From b71a7290a9f719a1ed93b5cc7f7dde9cc81739ec Mon Sep 17 00:00:00 2001 From: chenxun Date: Fri, 22 Oct 2021 14:04:53 +0800 Subject: [PATCH] python3.8.10 Signed-off-by: chenxun --- ohos.build | 15 + python/BUILD.gn | 889 + python/Modules/README | 2 + python/Modules/Setup | 368 + python/Modules/Setup.local | 1 + python/Modules/_abc.c | 832 + python/Modules/_asynciomodule.c | 3448 ++ python/Modules/_bisectmodule.c | 280 + python/Modules/_blake2/blake2b2s.py | 49 + python/Modules/_blake2/blake2b_impl.c | 437 + python/Modules/_blake2/blake2module.c | 105 + python/Modules/_blake2/blake2ns.h | 32 + python/Modules/_blake2/blake2s_impl.c | 437 + .../Modules/_blake2/clinic/blake2b_impl.c.h | 264 + .../Modules/_blake2/clinic/blake2s_impl.c.h | 264 + python/Modules/_blake2/impl/blake2-config.h | 71 + python/Modules/_blake2/impl/blake2-dispatch.c | 577 + python/Modules/_blake2/impl/blake2-impl.h | 162 + python/Modules/_blake2/impl/blake2-kat.h | 16467 +++++++++ python/Modules/_blake2/impl/blake2.h | 177 + .../Modules/_blake2/impl/blake2b-load-sse2.h | 68 + .../Modules/_blake2/impl/blake2b-load-sse41.h | 402 + python/Modules/_blake2/impl/blake2b-ref.c | 379 + python/Modules/_blake2/impl/blake2b-round.h | 160 + python/Modules/_blake2/impl/blake2b-test.c | 43 + python/Modules/_blake2/impl/blake2b.c | 436 + python/Modules/_blake2/impl/blake2bp-test.c | 44 + python/Modules/_blake2/impl/blake2bp.c | 274 + .../Modules/_blake2/impl/blake2s-load-sse2.h | 59 + .../Modules/_blake2/impl/blake2s-load-sse41.h | 229 + .../Modules/_blake2/impl/blake2s-load-xop.h | 189 + python/Modules/_blake2/impl/blake2s-ref.c | 368 + python/Modules/_blake2/impl/blake2s-round.h | 91 + python/Modules/_blake2/impl/blake2s-test.c | 43 + python/Modules/_blake2/impl/blake2s.c | 415 + python/Modules/_blake2/impl/blake2sp-test.c | 43 + python/Modules/_blake2/impl/blake2sp.c | 274 + python/Modules/_bz2module.c | 765 + python/Modules/_codecsmodule.c | 1058 + python/Modules/_collectionsmodule.c | 2577 ++ python/Modules/_contextvarsmodule.c | 78 + python/Modules/_cryptmodule.c | 71 + python/Modules/_csv.c | 1680 + python/Modules/_ctypes/_ctypes.c | 5873 ++++ python/Modules/_ctypes/_ctypes_test.c | 1080 + python/Modules/_ctypes/_ctypes_test.h | 1 + python/Modules/_ctypes/callbacks.c | 615 + python/Modules/_ctypes/callproc.c | 2020 ++ python/Modules/_ctypes/cfield.c | 1671 + python/Modules/_ctypes/ctypes.h | 381 + python/Modules/_ctypes/ctypes_dlfcn.h | 27 + python/Modules/_ctypes/darwin/LICENSE | 31 + python/Modules/_ctypes/darwin/README | 95 + python/Modules/_ctypes/darwin/README.ctypes | 11 + python/Modules/_ctypes/darwin/dlfcn.h | 84 + python/Modules/_ctypes/darwin/dlfcn_simple.c | 272 + python/Modules/_ctypes/libffi_osx/LICENSE | 20 + python/Modules/_ctypes/libffi_osx/README | 500 + .../Modules/_ctypes/libffi_osx/README.pyobjc | 5 + python/Modules/_ctypes/libffi_osx/ffi.c | 227 + .../Modules/_ctypes/libffi_osx/include/ffi.h | 355 + .../_ctypes/libffi_osx/include/ffi_common.h | 102 + .../_ctypes/libffi_osx/include/fficonfig.h | 150 + .../_ctypes/libffi_osx/include/ffitarget.h | 13 + .../libffi_osx/include/ppc-ffitarget.h | 104 + .../libffi_osx/include/x86-ffitarget.h | 88 + .../_ctypes/libffi_osx/powerpc/ppc-darwin.S | 365 + .../_ctypes/libffi_osx/powerpc/ppc-darwin.h | 85 + .../libffi_osx/powerpc/ppc-darwin_closure.S | 308 + .../libffi_osx/powerpc/ppc-ffi_darwin.c | 1776 + .../libffi_osx/powerpc/ppc64-darwin_closure.S | 418 + python/Modules/_ctypes/libffi_osx/types.c | 115 + .../Modules/_ctypes/libffi_osx/x86/darwin64.S | 417 + .../_ctypes/libffi_osx/x86/x86-darwin.S | 422 + .../_ctypes/libffi_osx/x86/x86-ffi64.c | 737 + .../_ctypes/libffi_osx/x86/x86-ffi_darwin.c | 438 + python/Modules/_ctypes/malloc_closure.c | 135 + python/Modules/_ctypes/stgdict.c | 900 + python/Modules/_curses_panel.c | 672 + python/Modules/_cursesmodule.c | 4656 +++ python/Modules/_datetimemodule.c | 6783 ++++ python/Modules/_dbmmodule.c | 521 + python/Modules/_decimal/README.txt | 46 + python/Modules/_decimal/_decimal.c | 5934 ++++ python/Modules/_decimal/docstrings.h | 884 + python/Modules/_decimal/libmpdec/README.txt | 90 + python/Modules/_decimal/libmpdec/basearith.c | 657 + python/Modules/_decimal/libmpdec/basearith.h | 222 + python/Modules/_decimal/libmpdec/bits.h | 192 + python/Modules/_decimal/libmpdec/constants.c | 132 + python/Modules/_decimal/libmpdec/constants.h | 90 + python/Modules/_decimal/libmpdec/context.c | 286 + python/Modules/_decimal/libmpdec/convolute.c | 174 + python/Modules/_decimal/libmpdec/convolute.h | 50 + python/Modules/_decimal/libmpdec/crt.c | 179 + python/Modules/_decimal/libmpdec/crt.h | 47 + python/Modules/_decimal/libmpdec/difradix2.c | 173 + python/Modules/_decimal/libmpdec/difradix2.h | 48 + python/Modules/_decimal/libmpdec/fnt.c | 81 + python/Modules/_decimal/libmpdec/fnt.h | 49 + python/Modules/_decimal/libmpdec/fourstep.c | 257 + python/Modules/_decimal/libmpdec/fourstep.h | 48 + python/Modules/_decimal/libmpdec/io.c | 1583 + python/Modules/_decimal/libmpdec/io.h | 59 + .../libmpdec/literature/REFERENCES.txt | 51 + .../_decimal/libmpdec/literature/bignum.txt | 83 + .../_decimal/libmpdec/literature/fnt.py | 208 + .../libmpdec/literature/matrix-transform.txt | 256 + .../libmpdec/literature/mulmod-64.txt | 127 + .../libmpdec/literature/mulmod-ppro.txt | 269 + .../_decimal/libmpdec/literature/six-step.txt | 63 + .../libmpdec/literature/umodarith.lisp | 692 + python/Modules/_decimal/libmpdec/memory.c | 297 + python/Modules/_decimal/libmpdec/mpalloc.h | 51 + python/Modules/_decimal/libmpdec/mpdecimal.c | 8417 +++++ python/Modules/_decimal/libmpdec/mpdecimal.h | 850 + .../Modules/_decimal/libmpdec/numbertheory.c | 132 + .../Modules/_decimal/libmpdec/numbertheory.h | 78 + python/Modules/_decimal/libmpdec/sixstep.c | 214 + python/Modules/_decimal/libmpdec/sixstep.h | 48 + python/Modules/_decimal/libmpdec/transpose.c | 276 + python/Modules/_decimal/libmpdec/transpose.h | 62 + python/Modules/_decimal/libmpdec/typearith.h | 669 + python/Modules/_decimal/libmpdec/umodarith.h | 650 + python/Modules/_decimal/libmpdec/vccompat.h | 57 + python/Modules/_decimal/libmpdec/vcdiv64.asm | 48 + python/Modules/_decimal/libmpdec/vcstdint.h | 232 + python/Modules/_decimal/tests/README.txt | 15 + python/Modules/_decimal/tests/bench.py | 132 + python/Modules/_decimal/tests/bignum.py | 42 + python/Modules/_decimal/tests/deccheck.py | 1100 + python/Modules/_decimal/tests/formathelper.py | 342 + python/Modules/_decimal/tests/randdec.py | 575 + python/Modules/_decimal/tests/randfloat.py | 250 + .../_decimal/tests/runall-memorydebugger.sh | 176 + python/Modules/_decimal/tests/runall.bat | 129 + python/Modules/_elementtree.c | 4520 +++ python/Modules/_functoolsmodule.c | 1430 + python/Modules/_gdbmmodule.c | 721 + python/Modules/_hashopenssl.c | 1152 + python/Modules/_heapqmodule.c | 721 + python/Modules/_io/_iomodule.c | 810 + python/Modules/_io/_iomodule.h | 186 + python/Modules/_io/bufferedio.c | 2725 ++ python/Modules/_io/bytesio.c | 1143 + python/Modules/_io/clinic/_iomodule.c.h | 326 + python/Modules/_io/clinic/bufferedio.c.h | 675 + python/Modules/_io/clinic/bytesio.c.h | 518 + python/Modules/_io/clinic/fileio.c.h | 450 + python/Modules/_io/clinic/iobase.c.h | 318 + python/Modules/_io/clinic/stringio.c.h | 351 + python/Modules/_io/clinic/textio.c.h | 704 + python/Modules/_io/clinic/winconsoleio.c.h | 389 + python/Modules/_io/fileio.c | 1238 + python/Modules/_io/iobase.c | 1083 + python/Modules/_io/stringio.c | 1044 + python/Modules/_io/textio.c | 3299 ++ python/Modules/_io/winconsoleio.c | 1169 + python/Modules/_json.c | 1943 ++ python/Modules/_localemodule.c | 796 + python/Modules/_lsprof.c | 838 + python/Modules/_lzmamodule.c | 1504 + python/Modules/_math.c | 266 + python/Modules/_math.h | 41 + .../_multiprocessing/clinic/posixshmem.c.h | 133 + .../_multiprocessing/multiprocessing.c | 219 + .../_multiprocessing/multiprocessing.h | 103 + python/Modules/_multiprocessing/posixshmem.c | 131 + python/Modules/_multiprocessing/semaphore.c | 689 + python/Modules/_opcode.c | 96 + python/Modules/_operator.c | 1789 + python/Modules/_pickle.c | 8062 +++++ python/Modules/_posixsubprocess.c | 813 + python/Modules/_queuemodule.c | 400 + python/Modules/_randommodule.c | 603 + python/Modules/_scproxy.c | 262 + python/Modules/_sha3/README.txt | 11 + python/Modules/_sha3/cleanup.py | 50 + python/Modules/_sha3/clinic/sha3module.c.h | 121 + python/Modules/_sha3/kcp/KeccakHash.c | 82 + python/Modules/_sha3/kcp/KeccakHash.h | 114 + .../Modules/_sha3/kcp/KeccakP-1600-64.macros | 2208 ++ .../_sha3/kcp/KeccakP-1600-SnP-opt32.h | 37 + .../_sha3/kcp/KeccakP-1600-SnP-opt64.h | 49 + python/Modules/_sha3/kcp/KeccakP-1600-SnP.h | 7 + .../_sha3/kcp/KeccakP-1600-inplace32BI.c | 1162 + .../_sha3/kcp/KeccakP-1600-opt64-config.h | 3 + python/Modules/_sha3/kcp/KeccakP-1600-opt64.c | 474 + .../_sha3/kcp/KeccakP-1600-unrolling.macros | 185 + python/Modules/_sha3/kcp/KeccakSponge.c | 92 + python/Modules/_sha3/kcp/KeccakSponge.h | 172 + python/Modules/_sha3/kcp/KeccakSponge.inc | 332 + python/Modules/_sha3/kcp/PlSnP-Fallback.inc | 257 + python/Modules/_sha3/kcp/SnP-Relaned.h | 134 + python/Modules/_sha3/kcp/align.h | 35 + python/Modules/_sha3/sha3module.c | 750 + python/Modules/_sqlite/cache.c | 360 + python/Modules/_sqlite/cache.h | 74 + python/Modules/_sqlite/connection.c | 1896 + python/Modules/_sqlite/connection.h | 127 + python/Modules/_sqlite/cursor.c | 980 + python/Modules/_sqlite/cursor.h | 70 + python/Modules/_sqlite/microprotocols.c | 160 + python/Modules/_sqlite/microprotocols.h | 52 + python/Modules/_sqlite/module.c | 474 + python/Modules/_sqlite/module.h | 53 + python/Modules/_sqlite/prepare_protocol.c | 83 + python/Modules/_sqlite/prepare_protocol.h | 42 + python/Modules/_sqlite/row.c | 278 + python/Modules/_sqlite/row.h | 40 + python/Modules/_sqlite/statement.c | 505 + python/Modules/_sqlite/statement.h | 60 + python/Modules/_sqlite/util.c | 146 + python/Modules/_sqlite/util.h | 49 + python/Modules/_sre.c | 2817 ++ python/Modules/_ssl.c | 6474 ++++ python/Modules/_ssl/debughelpers.c | 223 + python/Modules/_ssl_data.h | 6323 ++++ python/Modules/_ssl_data_111.h | 6525 ++++ python/Modules/_ssl_data_300.h | 8435 +++++ python/Modules/_stat.c | 610 + python/Modules/_statisticsmodule.c | 150 + python/Modules/_struct.c | 2399 ++ python/Modules/_testbuffer.c | 2894 ++ python/Modules/_testcapimodule.c | 6491 ++++ python/Modules/_testimportmultiple.c | 57 + python/Modules/_testinternalcapi.c | 88 + python/Modules/_testmultiphase.c | 680 + python/Modules/_threadmodule.c | 1583 + python/Modules/_tkinter.c | 3644 ++ python/Modules/_tracemalloc.c | 1770 + python/Modules/_uuidmodule.c | 75 + python/Modules/_weakref.c | 174 + python/Modules/_winapi.c | 2045 ++ python/Modules/_xxsubinterpretersmodule.c | 2558 ++ python/Modules/_xxtestfuzz/README.rst | 56 + python/Modules/_xxtestfuzz/_xxtestfuzz.c | 53 + .../dictionaries/fuzz_json_loads.dict | 40 + .../dictionaries/fuzz_sre_compile.dict | 219 + .../fuzz_csv_reader_corpus/test.csv | Bin 0 -> 118 bytes .../fuzz_json_loads_corpus/empty_array.json | 1 + .../fuzz_json_loads_corpus/empty_object.json | 1 + .../fuzz_json_loads_corpus/pass1.json | 58 + .../fuzz_json_loads_corpus/pass2.json | 1 + .../fuzz_json_loads_corpus/pass3.json | 6 + .../fuzz_json_loads_corpus/simple_array.json | 1 + .../fuzz_sre_compile_corpus/anchor_links | 1 + .../fuzz_sre_compile_corpus/characters | 1 + .../_xxtestfuzz/fuzz_sre_compile_corpus/isbn | 1 + .../fuzz_sre_compile_corpus/phone_number | 1 + python/Modules/_xxtestfuzz/fuzz_tests.txt | 7 + python/Modules/_xxtestfuzz/fuzzer.c | 426 + python/Modules/addrinfo.h | 168 + python/Modules/arraymodule.c | 3095 ++ python/Modules/atexitmodule.c | 354 + python/Modules/audioop.c | 1927 + python/Modules/binascii.c | 1668 + python/Modules/cjkcodecs/README | 79 + python/Modules/cjkcodecs/_codecs_cn.c | 470 + python/Modules/cjkcodecs/_codecs_hk.c | 191 + python/Modules/cjkcodecs/_codecs_iso2022.c | 1143 + python/Modules/cjkcodecs/_codecs_jp.c | 760 + python/Modules/cjkcodecs/_codecs_kr.c | 468 + python/Modules/cjkcodecs/_codecs_tw.c | 143 + python/Modules/cjkcodecs/alg_jisx0201.h | 65 + python/Modules/cjkcodecs/cjkcodecs.h | 419 + .../cjkcodecs/clinic/multibytecodec.c.h | 528 + python/Modules/cjkcodecs/emu_jisx0213_2000.h | 54 + python/Modules/cjkcodecs/mappings_cn.h | 4103 +++ python/Modules/cjkcodecs/mappings_hk.h | 2378 ++ .../cjkcodecs/mappings_jisx0213_pair.h | 59 + python/Modules/cjkcodecs/mappings_jp.h | 4765 +++ python/Modules/cjkcodecs/mappings_kr.h | 3251 ++ python/Modules/cjkcodecs/mappings_tw.h | 2633 ++ python/Modules/cjkcodecs/multibytecodec.c | 2103 ++ python/Modules/cjkcodecs/multibytecodec.h | 139 + python/Modules/clinic/_abc.c.h | 162 + python/Modules/clinic/_asynciomodule.c.h | 835 + python/Modules/clinic/_bz2module.c.h | 223 + python/Modules/clinic/_codecsmodule.c.h | 2925 ++ python/Modules/clinic/_collectionsmodule.c.h | 76 + python/Modules/clinic/_contextvarsmodule.c.h | 21 + python/Modules/clinic/_cryptmodule.c.h | 63 + python/Modules/clinic/_curses_panel.c.h | 338 + python/Modules/clinic/_cursesmodule.c.h | 4562 +++ python/Modules/clinic/_datetimemodule.c.h | 58 + python/Modules/clinic/_dbmmodule.c.h | 180 + python/Modules/clinic/_elementtree.c.h | 972 + python/Modules/clinic/_gdbmmodule.c.h | 301 + python/Modules/clinic/_hashopenssl.c.h | 626 + python/Modules/clinic/_heapqmodule.c.h | 172 + python/Modules/clinic/_lzmamodule.c.h | 337 + python/Modules/clinic/_opcode.c.h | 64 + python/Modules/clinic/_operator.c.h | 1494 + python/Modules/clinic/_pickle.c.h | 839 + python/Modules/clinic/_queuemodule.c.h | 253 + python/Modules/clinic/_randommodule.c.h | 117 + python/Modules/clinic/_sre.c.h | 1210 + python/Modules/clinic/_ssl.c.h | 1485 + python/Modules/clinic/_statisticsmodule.c.h | 68 + python/Modules/clinic/_struct.c.h | 389 + python/Modules/clinic/_tkinter.c.h | 915 + python/Modules/clinic/_tracemalloc.c.h | 200 + python/Modules/clinic/_weakref.c.h | 67 + python/Modules/clinic/_winapi.c.h | 1100 + python/Modules/clinic/arraymodule.c.h | 602 + python/Modules/clinic/audioop.c.h | 1472 + python/Modules/clinic/binascii.c.h | 804 + python/Modules/clinic/cmathmodule.c.h | 971 + python/Modules/clinic/fcntlmodule.c.h | 271 + python/Modules/clinic/gcmodule.c.h | 376 + python/Modules/clinic/grpmodule.c.h | 100 + python/Modules/clinic/itertoolsmodule.c.h | 645 + python/Modules/clinic/mathmodule.c.h | 811 + python/Modules/clinic/md5module.c.h | 104 + python/Modules/clinic/posixmodule.c.h | 8771 +++++ python/Modules/clinic/pwdmodule.c.h | 77 + python/Modules/clinic/pyexpat.c.h | 405 + python/Modules/clinic/resource.c.h | 181 + python/Modules/clinic/selectmodule.c.h | 1222 + python/Modules/clinic/sha1module.c.h | 104 + python/Modules/clinic/sha256module.c.h | 141 + python/Modules/clinic/sha512module.c.h | 141 + python/Modules/clinic/signalmodule.c.h | 661 + python/Modules/clinic/spwdmodule.c.h | 74 + python/Modules/clinic/symtablemodule.c.h | 51 + python/Modules/clinic/unicodedata.c.h | 562 + python/Modules/clinic/zlibmodule.c.h | 788 + python/Modules/cmathmodule.c | 1413 + python/Modules/config.c | 114 + python/Modules/config.c.in | 67 + python/Modules/errnomodule.c | 935 + python/Modules/expat/COPYING | 21 + python/Modules/expat/ascii.h | 120 + python/Modules/expat/asciitab.h | 64 + python/Modules/expat/expat.h | 1024 + python/Modules/expat/expat_config.h | 21 + python/Modules/expat/expat_external.h | 163 + python/Modules/expat/iasciitab.h | 65 + python/Modules/expat/internal.h | 123 + python/Modules/expat/latin1tab.h | 64 + python/Modules/expat/nametab.h | 136 + python/Modules/expat/pyexpatns.h | 125 + python/Modules/expat/siphash.h | 398 + python/Modules/expat/utf8tab.h | 64 + python/Modules/expat/winconfig.h | 56 + python/Modules/expat/xmlparse.c | 6893 ++++ python/Modules/expat/xmlrole.c | 1247 + python/Modules/expat/xmlrole.h | 139 + python/Modules/expat/xmltok.c | 1672 + python/Modules/expat/xmltok.h | 315 + python/Modules/expat/xmltok_impl.c | 1804 + python/Modules/expat/xmltok_impl.h | 73 + python/Modules/expat/xmltok_ns.c | 118 + python/Modules/faulthandler.c | 1417 + python/Modules/fcntlmodule.c | 681 + python/Modules/gc_weakref.txt | 219 + python/Modules/gcmodule.c | 2063 ++ python/Modules/getaddrinfo.c | 661 + python/Modules/getbuildinfo.c | 67 + python/Modules/getnameinfo.c | 235 + python/Modules/getpath.c | 1363 + python/Modules/grpmodule.c | 349 + python/Modules/hashlib.h | 59 + python/Modules/hashtable.c | 524 + python/Modules/hashtable.h | 211 + python/Modules/itertoolsmodule.c | 4790 +++ python/Modules/ld_so_aix | 195 + python/Modules/ld_so_aix.in | 195 + python/Modules/main.c | 748 + python/Modules/makesetup | 309 + python/Modules/makexp_aix | 81 + python/Modules/mathmodule.c | 3395 ++ python/Modules/md5module.c | 584 + python/Modules/mmapmodule.c | 1617 + python/Modules/nismodule.c | 469 + python/Modules/ossaudiodev.c | 1311 + python/Modules/overlapped.c | 1881 + python/Modules/parsermodule.c | 1221 + python/Modules/posixmodule.c | 14854 ++++++++ python/Modules/posixmodule.h | 34 + python/Modules/pwdmodule.c | 343 + python/Modules/pyexpat.c | 1936 + python/Modules/readline.c | 1387 + python/Modules/resource.c | 494 + python/Modules/rotatingtree.c | 121 + python/Modules/rotatingtree.h | 27 + python/Modules/selectmodule.c | 2693 ++ python/Modules/sha1module.c | 561 + python/Modules/sha256module.c | 729 + python/Modules/sha512module.c | 793 + python/Modules/signalmodule.c | 1865 + python/Modules/socketmodule.c | 8305 +++++ python/Modules/socketmodule.h | 302 + python/Modules/spwdmodule.c | 230 + python/Modules/sre.h | 94 + python/Modules/sre_constants.h | 97 + python/Modules/sre_lib.h | 1545 + python/Modules/symtablemodule.c | 126 + python/Modules/syslogmodule.c | 354 + python/Modules/termios.c | 972 + python/Modules/testcapi_long.h | 207 + python/Modules/timemodule.c | 1918 + python/Modules/tkappinit.c | 166 + python/Modules/tkinter.h | 27 + python/Modules/unicodedata.c | 1485 + python/Modules/unicodedata_db.h | 7664 ++++ python/Modules/unicodename_db.h | 29046 ++++++++++++++++ python/Modules/winreparse.h | 59 + python/Modules/xxlimited.c | 307 + python/Modules/xxmodule.c | 411 + python/Modules/xxsubtype.c | 314 + python/Modules/zlibmodule.c | 1461 + python/Objects/README | 1 + python/Objects/abstract.c | 2696 ++ python/Objects/accu.c | 115 + python/Objects/boolobject.c | 185 + python/Objects/bytearrayobject.c | 2467 ++ python/Objects/bytes_methods.c | 833 + python/Objects/bytesobject.c | 3489 ++ python/Objects/call.c | 1354 + python/Objects/capsule.c | 324 + python/Objects/cellobject.c | 199 + python/Objects/classobject.c | 674 + python/Objects/clinic/bytearrayobject.c.h | 1014 + python/Objects/clinic/bytesobject.c.h | 758 + python/Objects/clinic/codeobject.c.h | 256 + python/Objects/clinic/complexobject.c.h | 49 + python/Objects/clinic/descrobject.c.h | 118 + python/Objects/clinic/dictobject.c.h | 157 + python/Objects/clinic/enumobject.c.h | 80 + python/Objects/clinic/floatobject.c.h | 354 + python/Objects/clinic/funcobject.c.h | 78 + python/Objects/clinic/listobject.c.h | 370 + python/Objects/clinic/longobject.c.h | 316 + python/Objects/clinic/memoryobject.c.h | 74 + python/Objects/clinic/moduleobject.c.h | 51 + python/Objects/clinic/odictobject.c.h | 171 + python/Objects/clinic/structseq.c.h | 36 + python/Objects/clinic/tupleobject.c.h | 114 + python/Objects/clinic/typeobject.c.h | 251 + python/Objects/clinic/unicodeobject.c.h | 1235 + python/Objects/codeobject.c | 1092 + python/Objects/complexobject.c | 1137 + python/Objects/descrobject.c | 1792 + python/Objects/dict-common.h | 68 + python/Objects/dictnotes.txt | 149 + python/Objects/dictobject.c | 4708 +++ python/Objects/enumobject.c | 457 + python/Objects/exceptions.c | 3064 ++ python/Objects/fileobject.c | 589 + python/Objects/floatobject.c | 2604 ++ python/Objects/frameobject.c | 1013 + python/Objects/funcobject.c | 1057 + python/Objects/genobject.c | 2069 ++ python/Objects/interpreteridobject.c | 293 + python/Objects/iterobject.c | 292 + python/Objects/listobject.c | 3403 ++ python/Objects/listsort.txt | 763 + python/Objects/lnotab_notes.txt | 137 + python/Objects/longobject.c | 5863 ++++ python/Objects/memoryobject.c | 3201 ++ python/Objects/methodobject.c | 485 + python/Objects/moduleobject.c | 873 + python/Objects/namespaceobject.c | 263 + python/Objects/object.c | 2220 ++ python/Objects/obmalloc.c | 2722 ++ python/Objects/odictobject.c | 2304 ++ python/Objects/picklebufobject.c | 219 + python/Objects/rangeobject.c | 1193 + python/Objects/setobject.c | 2549 ++ python/Objects/sliceobject.c | 661 + python/Objects/stringlib/README.txt | 40 + python/Objects/stringlib/asciilib.h | 29 + .../Objects/stringlib/clinic/transmogrify.h.h | 277 + python/Objects/stringlib/codecs.h | 822 + python/Objects/stringlib/count.h | 27 + python/Objects/stringlib/ctype.h | 116 + python/Objects/stringlib/eq.h | 24 + python/Objects/stringlib/fastsearch.h | 283 + python/Objects/stringlib/find.h | 119 + python/Objects/stringlib/find_max_char.h | 134 + python/Objects/stringlib/join.h | 140 + python/Objects/stringlib/localeutil.h | 82 + python/Objects/stringlib/partition.h | 116 + python/Objects/stringlib/replace.h | 53 + python/Objects/stringlib/split.h | 390 + python/Objects/stringlib/stringdefs.h | 28 + python/Objects/stringlib/transmogrify.h | 743 + python/Objects/stringlib/ucs1lib.h | 30 + python/Objects/stringlib/ucs2lib.h | 29 + python/Objects/stringlib/ucs4lib.h | 29 + python/Objects/stringlib/undef.h | 11 + python/Objects/stringlib/unicode_format.h | 1291 + python/Objects/stringlib/unicodedefs.h | 32 + python/Objects/structseq.c | 512 + python/Objects/tupleobject.c | 1115 + python/Objects/typeobject.c | 8026 +++++ python/Objects/typeslots.inc | 81 + python/Objects/typeslots.py | 43 + python/Objects/unicodectype.c | 297 + python/Objects/unicodeobject.c | 15920 +++++++++ python/Objects/unicodetype_db.h | 6209 ++++ python/Objects/weakrefobject.c | 1023 + python/Parser/Python.asdl | 129 + python/Parser/acceler.c | 123 + python/Parser/asdl.py | 376 + python/Parser/asdl_c.py | 1348 + python/Parser/grammar1.c | 47 + python/Parser/listnode.c | 66 + python/Parser/myreadline.c | 416 + python/Parser/node.c | 188 + python/Parser/parser.c | 462 + python/Parser/parser.h | 49 + python/Parser/parsetok.c | 496 + python/Parser/pgen/__init__.py | 0 python/Parser/pgen/__main__.py | 35 + python/Parser/pgen/grammar.py | 144 + python/Parser/pgen/keywordgen.py | 60 + python/Parser/pgen/pgen.py | 406 + python/Parser/pgen/token.py | 42 + python/Parser/token.c | 243 + python/Parser/tokenizer.c | 1882 + python/Parser/tokenizer.h | 88 + python/Programs/README | 1 + python/Programs/_freeze_importlib.c | 167 + python/Programs/_testembed | Bin 0 -> 18220556 bytes python/Programs/_testembed.c | 1682 + python/Programs/python.c | 18 + python/Python/Python-ast.c | 9055 +++++ python/Python/README | 1 + python/Python/_warnings.c | 1382 + python/Python/asdl.c | 64 + python/Python/ast.c | 5991 ++++ python/Python/ast_opt.c | 766 + python/Python/ast_unparse.c | 955 + python/Python/bltinmodule.c | 2852 ++ python/Python/bootstrap_hash.c | 601 + python/Python/ceval.c | 5619 +++ python/Python/ceval_gil.h | 254 + python/Python/clinic/_warnings.c.h | 74 + python/Python/clinic/bltinmodule.c.h | 858 + python/Python/clinic/context.c.h | 180 + python/Python/clinic/import.c.h | 458 + python/Python/clinic/marshal.c.h | 168 + python/Python/clinic/sysmodule.c.h | 1091 + python/Python/clinic/traceback.c.h | 62 + python/Python/codecs.c | 1539 + python/Python/compile.c | 6052 ++++ python/Python/condvar.h | 309 + python/Python/context.c | 1307 + python/Python/dtoa.c | 2847 ++ python/Python/dup2.c | 31 + python/Python/dynamic_annotations.c | 154 + python/Python/dynload_aix.c | 190 + python/Python/dynload_dl.c | 23 + python/Python/dynload_hpux.c | 77 + python/Python/dynload_shlib.c | 133 + python/Python/dynload_stub.c | 9 + python/Python/dynload_win.c | 297 + python/Python/errors.c | 1613 + python/Python/fileutils.c | 2052 ++ python/Python/formatter_unicode.c | 1593 + python/Python/frozen.c | 50 + python/Python/frozenmain.c | 129 + python/Python/future.c | 158 + python/Python/getargs.c | 2859 ++ python/Python/getcompiler.c | 27 + python/Python/getcopyright.c | 23 + python/Python/getopt.c | 179 + python/Python/getplatform.c | 12 + python/Python/getversion.c | 15 + python/Python/graminit.c | 2701 ++ python/Python/hamt.c | 2997 ++ python/Python/import.c | 2468 ++ python/Python/importdl.c | 247 + python/Python/importdl.h | 27 + python/Python/importlib.h | 1789 + python/Python/importlib_external.h | 2826 ++ python/Python/importlib_zipimport.h | 1081 + python/Python/initconfig.c | 2674 ++ python/Python/makeopcodetargets.py | 55 + python/Python/marshal.c | 1843 + python/Python/modsupport.c | 683 + python/Python/mysnprintf.c | 104 + python/Python/mystrtoul.c | 291 + python/Python/opcode_targets.h | 258 + python/Python/pathconfig.c | 786 + python/Python/peephole.c | 538 + python/Python/preconfig.c | 967 + python/Python/pyarena.c | 210 + python/Python/pyctype.c | 214 + python/Python/pyfpe.c | 15 + python/Python/pyhash.c | 435 + python/Python/pylifecycle.c | 2407 ++ python/Python/pymath.c | 81 + python/Python/pystate.c | 1724 + python/Python/pystrcmp.c | 30 + python/Python/pystrhex.c | 133 + python/Python/pystrtod.c | 1308 + python/Python/pythonrun.c | 1816 + python/Python/pytime.c | 1114 + python/Python/strdup.c | 14 + python/Python/structmember.c | 292 + python/Python/symtable.c | 1956 ++ python/Python/sysmodule.c | 3337 ++ python/Python/thread.c | 228 + python/Python/thread_nt.h | 498 + python/Python/thread_pthread.h | 874 + python/Python/traceback.c | 923 + python/Python/wordcode_helpers.h | 44 + python/include/Python-ast.h | 715 + python/include/Python.h | 160 + python/include/abstract.h | 844 + python/include/asdl.h | 46 + python/include/ast.h | 37 + python/include/bitset.h | 23 + python/include/bltinmodule.h | 14 + python/include/boolobject.h | 34 + python/include/bytearrayobject.h | 62 + python/include/bytes_methods.h | 69 + python/include/bytesobject.h | 224 + python/include/cellobject.h | 29 + python/include/ceval.h | 231 + python/include/classobject.h | 59 + python/include/code.h | 180 + python/include/codecs.h | 240 + python/include/compile.h | 106 + python/include/complexobject.h | 69 + python/include/context.h | 84 + python/include/cpython/abstract.h | 319 + python/include/cpython/dictobject.h | 94 + python/include/cpython/fileobject.h | 24 + python/include/cpython/initconfig.h | 434 + python/include/cpython/interpreteridobject.h | 19 + python/include/cpython/object.h | 470 + python/include/cpython/objimpl.h | 113 + python/include/cpython/pyerrors.h | 188 + python/include/cpython/pylifecycle.h | 78 + python/include/cpython/pymem.h | 108 + python/include/cpython/pystate.h | 252 + python/include/cpython/sysmodule.h | 21 + python/include/cpython/traceback.h | 22 + python/include/cpython/tupleobject.h | 36 + python/include/cpython/unicodeobject.h | 1239 + python/include/datetime.h | 259 + python/include/descrobject.h | 108 + python/include/dictobject.h | 94 + python/include/dtoa.h | 19 + python/include/dynamic_annotations.h | 499 + python/include/enumobject.h | 17 + python/include/errcode.h | 38 + python/include/eval.h | 37 + python/include/fileobject.h | 49 + python/include/fileutils.h | 185 + python/include/floatobject.h | 130 + python/include/frameobject.h | 92 + python/include/funcobject.h | 104 + python/include/genobject.h | 109 + python/include/graminit.h | 94 + python/include/grammar.h | 77 + python/include/import.h | 149 + python/include/internal/pycore_accu.h | 39 + python/include/internal/pycore_atomic.h | 558 + python/include/internal/pycore_ceval.h | 37 + python/include/internal/pycore_code.h | 27 + python/include/internal/pycore_condvar.h | 95 + python/include/internal/pycore_context.h | 42 + python/include/internal/pycore_fileutils.h | 54 + python/include/internal/pycore_getopt.h | 22 + python/include/internal/pycore_gil.h | 50 + python/include/internal/pycore_hamt.h | 116 + python/include/internal/pycore_initconfig.h | 166 + python/include/internal/pycore_object.h | 81 + python/include/internal/pycore_pathconfig.h | 75 + python/include/internal/pycore_pyerrors.h | 62 + python/include/internal/pycore_pyhash.h | 10 + python/include/internal/pycore_pylifecycle.h | 118 + python/include/internal/pycore_pymem.h | 212 + python/include/internal/pycore_pystate.h | 326 + python/include/internal/pycore_traceback.h | 96 + python/include/internal/pycore_tupleobject.h | 19 + python/include/internal/pycore_warnings.h | 25 + python/include/interpreteridobject.h | 17 + python/include/intrcheck.h | 33 + python/include/iterobject.h | 25 + python/include/listobject.h | 81 + python/include/longintrepr.h | 99 + python/include/longobject.h | 242 + python/include/marshal.h | 28 + python/include/memoryobject.h | 72 + python/include/methodobject.h | 131 + python/include/modsupport.h | 248 + python/include/moduleobject.h | 90 + python/include/namespaceobject.h | 19 + python/include/node.h | 48 + python/include/object.h | 753 + python/include/objimpl.h | 284 + python/include/odictobject.h | 43 + python/include/opcode.h | 148 + python/include/osdefs.h | 51 + python/include/osmodule.h | 17 + python/include/parsetok.h | 110 + python/include/patchlevel.h | 35 + python/include/picklebufobject.h | 31 + python/include/py_curses.h | 100 + python/include/pyarena.h | 64 + python/include/pycapsule.h | 59 + python/include/pyctype.h | 39 + python/include/pydebug.h | 40 + python/include/pydtrace.d | 22 + python/include/pydtrace.h | 59 + python/include/pyerrors.h | 335 + python/include/pyexpat.h | 55 + python/include/pyfpe.h | 12 + python/include/pyhash.h | 145 + python/include/pylifecycle.h | 75 + python/include/pymacconfig.h | 102 + python/include/pymacro.h | 106 + python/include/pymath.h | 230 + python/include/pymem.h | 150 + python/include/pyport.h | 850 + python/include/pystate.h | 136 + python/include/pystrcmp.h | 23 + python/include/pystrhex.h | 22 + python/include/pystrtod.h | 45 + python/include/pythonrun.h | 210 + python/include/pythread.h | 161 + python/include/pytime.h | 246 + python/include/rangeobject.h | 27 + python/include/setobject.h | 108 + python/include/sliceobject.h | 65 + python/include/structmember.h | 74 + python/include/structseq.h | 49 + python/include/symtable.h | 123 + python/include/sysmodule.h | 41 + python/include/token.h | 92 + python/include/traceback.h | 28 + python/include/tracemalloc.h | 38 + python/include/tupleobject.h | 48 + python/include/typeslots.h | 85 + python/include/ucnhash.h | 36 + python/include/unicodeobject.h | 1044 + python/include/warnings.h | 67 + python/include/weakrefobject.h | 86 + python/pyconfig.h | 1665 + 746 files changed, 624590 insertions(+) create mode 100755 ohos.build create mode 100755 python/BUILD.gn create mode 100755 python/Modules/README create mode 100755 python/Modules/Setup create mode 100755 python/Modules/Setup.local create mode 100755 python/Modules/_abc.c create mode 100755 python/Modules/_asynciomodule.c create mode 100755 python/Modules/_bisectmodule.c create mode 100755 python/Modules/_blake2/blake2b2s.py create mode 100755 python/Modules/_blake2/blake2b_impl.c create mode 100755 python/Modules/_blake2/blake2module.c create mode 100755 python/Modules/_blake2/blake2ns.h create mode 100755 python/Modules/_blake2/blake2s_impl.c create mode 100755 python/Modules/_blake2/clinic/blake2b_impl.c.h create mode 100755 python/Modules/_blake2/clinic/blake2s_impl.c.h create mode 100755 python/Modules/_blake2/impl/blake2-config.h create mode 100755 python/Modules/_blake2/impl/blake2-dispatch.c create mode 100755 python/Modules/_blake2/impl/blake2-impl.h create mode 100755 python/Modules/_blake2/impl/blake2-kat.h create mode 100755 python/Modules/_blake2/impl/blake2.h create mode 100755 python/Modules/_blake2/impl/blake2b-load-sse2.h create mode 100755 python/Modules/_blake2/impl/blake2b-load-sse41.h create mode 100755 python/Modules/_blake2/impl/blake2b-ref.c create mode 100755 python/Modules/_blake2/impl/blake2b-round.h create mode 100755 python/Modules/_blake2/impl/blake2b-test.c create mode 100755 python/Modules/_blake2/impl/blake2b.c create mode 100755 python/Modules/_blake2/impl/blake2bp-test.c create mode 100755 python/Modules/_blake2/impl/blake2bp.c create mode 100755 python/Modules/_blake2/impl/blake2s-load-sse2.h create mode 100755 python/Modules/_blake2/impl/blake2s-load-sse41.h create mode 100755 python/Modules/_blake2/impl/blake2s-load-xop.h create mode 100755 python/Modules/_blake2/impl/blake2s-ref.c create mode 100755 python/Modules/_blake2/impl/blake2s-round.h create mode 100755 python/Modules/_blake2/impl/blake2s-test.c create mode 100755 python/Modules/_blake2/impl/blake2s.c create mode 100755 python/Modules/_blake2/impl/blake2sp-test.c create mode 100755 python/Modules/_blake2/impl/blake2sp.c create mode 100755 python/Modules/_bz2module.c create mode 100755 python/Modules/_codecsmodule.c create mode 100755 python/Modules/_collectionsmodule.c create mode 100755 python/Modules/_contextvarsmodule.c create mode 100755 python/Modules/_cryptmodule.c create mode 100755 python/Modules/_csv.c create mode 100755 python/Modules/_ctypes/_ctypes.c create mode 100755 python/Modules/_ctypes/_ctypes_test.c create mode 100755 python/Modules/_ctypes/_ctypes_test.h create mode 100755 python/Modules/_ctypes/callbacks.c create mode 100755 python/Modules/_ctypes/callproc.c create mode 100755 python/Modules/_ctypes/cfield.c create mode 100755 python/Modules/_ctypes/ctypes.h create mode 100755 python/Modules/_ctypes/ctypes_dlfcn.h create mode 100755 python/Modules/_ctypes/darwin/LICENSE create mode 100755 python/Modules/_ctypes/darwin/README create mode 100755 python/Modules/_ctypes/darwin/README.ctypes create mode 100755 python/Modules/_ctypes/darwin/dlfcn.h create mode 100755 python/Modules/_ctypes/darwin/dlfcn_simple.c create mode 100755 python/Modules/_ctypes/libffi_osx/LICENSE create mode 100755 python/Modules/_ctypes/libffi_osx/README create mode 100755 python/Modules/_ctypes/libffi_osx/README.pyobjc create mode 100755 python/Modules/_ctypes/libffi_osx/ffi.c create mode 100755 python/Modules/_ctypes/libffi_osx/include/ffi.h create mode 100755 python/Modules/_ctypes/libffi_osx/include/ffi_common.h create mode 100755 python/Modules/_ctypes/libffi_osx/include/fficonfig.h create mode 100755 python/Modules/_ctypes/libffi_osx/include/ffitarget.h create mode 100755 python/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h create mode 100755 python/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h create mode 100755 python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S create mode 100755 python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h create mode 100755 python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S create mode 100755 python/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c create mode 100755 python/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S create mode 100755 python/Modules/_ctypes/libffi_osx/types.c create mode 100755 python/Modules/_ctypes/libffi_osx/x86/darwin64.S create mode 100755 python/Modules/_ctypes/libffi_osx/x86/x86-darwin.S create mode 100755 python/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c create mode 100755 python/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c create mode 100755 python/Modules/_ctypes/malloc_closure.c create mode 100755 python/Modules/_ctypes/stgdict.c create mode 100755 python/Modules/_curses_panel.c create mode 100755 python/Modules/_cursesmodule.c create mode 100755 python/Modules/_datetimemodule.c create mode 100755 python/Modules/_dbmmodule.c create mode 100755 python/Modules/_decimal/README.txt create mode 100755 python/Modules/_decimal/_decimal.c create mode 100755 python/Modules/_decimal/docstrings.h create mode 100755 python/Modules/_decimal/libmpdec/README.txt create mode 100755 python/Modules/_decimal/libmpdec/basearith.c create mode 100755 python/Modules/_decimal/libmpdec/basearith.h create mode 100755 python/Modules/_decimal/libmpdec/bits.h create mode 100755 python/Modules/_decimal/libmpdec/constants.c create mode 100755 python/Modules/_decimal/libmpdec/constants.h create mode 100755 python/Modules/_decimal/libmpdec/context.c create mode 100755 python/Modules/_decimal/libmpdec/convolute.c create mode 100755 python/Modules/_decimal/libmpdec/convolute.h create mode 100755 python/Modules/_decimal/libmpdec/crt.c create mode 100755 python/Modules/_decimal/libmpdec/crt.h create mode 100755 python/Modules/_decimal/libmpdec/difradix2.c create mode 100755 python/Modules/_decimal/libmpdec/difradix2.h create mode 100755 python/Modules/_decimal/libmpdec/fnt.c create mode 100755 python/Modules/_decimal/libmpdec/fnt.h create mode 100755 python/Modules/_decimal/libmpdec/fourstep.c create mode 100755 python/Modules/_decimal/libmpdec/fourstep.h create mode 100755 python/Modules/_decimal/libmpdec/io.c create mode 100755 python/Modules/_decimal/libmpdec/io.h create mode 100755 python/Modules/_decimal/libmpdec/literature/REFERENCES.txt create mode 100755 python/Modules/_decimal/libmpdec/literature/bignum.txt create mode 100755 python/Modules/_decimal/libmpdec/literature/fnt.py create mode 100755 python/Modules/_decimal/libmpdec/literature/matrix-transform.txt create mode 100755 python/Modules/_decimal/libmpdec/literature/mulmod-64.txt create mode 100755 python/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt create mode 100755 python/Modules/_decimal/libmpdec/literature/six-step.txt create mode 100755 python/Modules/_decimal/libmpdec/literature/umodarith.lisp create mode 100755 python/Modules/_decimal/libmpdec/memory.c create mode 100755 python/Modules/_decimal/libmpdec/mpalloc.h create mode 100755 python/Modules/_decimal/libmpdec/mpdecimal.c create mode 100755 python/Modules/_decimal/libmpdec/mpdecimal.h create mode 100755 python/Modules/_decimal/libmpdec/numbertheory.c create mode 100755 python/Modules/_decimal/libmpdec/numbertheory.h create mode 100755 python/Modules/_decimal/libmpdec/sixstep.c create mode 100755 python/Modules/_decimal/libmpdec/sixstep.h create mode 100755 python/Modules/_decimal/libmpdec/transpose.c create mode 100755 python/Modules/_decimal/libmpdec/transpose.h create mode 100755 python/Modules/_decimal/libmpdec/typearith.h create mode 100755 python/Modules/_decimal/libmpdec/umodarith.h create mode 100755 python/Modules/_decimal/libmpdec/vccompat.h create mode 100755 python/Modules/_decimal/libmpdec/vcdiv64.asm create mode 100755 python/Modules/_decimal/libmpdec/vcstdint.h create mode 100755 python/Modules/_decimal/tests/README.txt create mode 100755 python/Modules/_decimal/tests/bench.py create mode 100755 python/Modules/_decimal/tests/bignum.py create mode 100755 python/Modules/_decimal/tests/deccheck.py create mode 100755 python/Modules/_decimal/tests/formathelper.py create mode 100755 python/Modules/_decimal/tests/randdec.py create mode 100755 python/Modules/_decimal/tests/randfloat.py create mode 100755 python/Modules/_decimal/tests/runall-memorydebugger.sh create mode 100755 python/Modules/_decimal/tests/runall.bat create mode 100755 python/Modules/_elementtree.c create mode 100755 python/Modules/_functoolsmodule.c create mode 100755 python/Modules/_gdbmmodule.c create mode 100755 python/Modules/_hashopenssl.c create mode 100755 python/Modules/_heapqmodule.c create mode 100755 python/Modules/_io/_iomodule.c create mode 100755 python/Modules/_io/_iomodule.h create mode 100755 python/Modules/_io/bufferedio.c create mode 100755 python/Modules/_io/bytesio.c create mode 100755 python/Modules/_io/clinic/_iomodule.c.h create mode 100755 python/Modules/_io/clinic/bufferedio.c.h create mode 100755 python/Modules/_io/clinic/bytesio.c.h create mode 100755 python/Modules/_io/clinic/fileio.c.h create mode 100755 python/Modules/_io/clinic/iobase.c.h create mode 100755 python/Modules/_io/clinic/stringio.c.h create mode 100755 python/Modules/_io/clinic/textio.c.h create mode 100755 python/Modules/_io/clinic/winconsoleio.c.h create mode 100755 python/Modules/_io/fileio.c create mode 100755 python/Modules/_io/iobase.c create mode 100755 python/Modules/_io/stringio.c create mode 100755 python/Modules/_io/textio.c create mode 100755 python/Modules/_io/winconsoleio.c create mode 100755 python/Modules/_json.c create mode 100755 python/Modules/_localemodule.c create mode 100755 python/Modules/_lsprof.c create mode 100755 python/Modules/_lzmamodule.c create mode 100755 python/Modules/_math.c create mode 100755 python/Modules/_math.h create mode 100755 python/Modules/_multiprocessing/clinic/posixshmem.c.h create mode 100755 python/Modules/_multiprocessing/multiprocessing.c create mode 100755 python/Modules/_multiprocessing/multiprocessing.h create mode 100755 python/Modules/_multiprocessing/posixshmem.c create mode 100755 python/Modules/_multiprocessing/semaphore.c create mode 100755 python/Modules/_opcode.c create mode 100755 python/Modules/_operator.c create mode 100755 python/Modules/_pickle.c create mode 100755 python/Modules/_posixsubprocess.c create mode 100755 python/Modules/_queuemodule.c create mode 100755 python/Modules/_randommodule.c create mode 100755 python/Modules/_scproxy.c create mode 100755 python/Modules/_sha3/README.txt create mode 100755 python/Modules/_sha3/cleanup.py create mode 100755 python/Modules/_sha3/clinic/sha3module.c.h create mode 100755 python/Modules/_sha3/kcp/KeccakHash.c create mode 100755 python/Modules/_sha3/kcp/KeccakHash.h create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-64.macros create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-SnP.h create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-opt64.c create mode 100755 python/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros create mode 100755 python/Modules/_sha3/kcp/KeccakSponge.c create mode 100755 python/Modules/_sha3/kcp/KeccakSponge.h create mode 100755 python/Modules/_sha3/kcp/KeccakSponge.inc create mode 100755 python/Modules/_sha3/kcp/PlSnP-Fallback.inc create mode 100755 python/Modules/_sha3/kcp/SnP-Relaned.h create mode 100755 python/Modules/_sha3/kcp/align.h create mode 100755 python/Modules/_sha3/sha3module.c create mode 100755 python/Modules/_sqlite/cache.c create mode 100755 python/Modules/_sqlite/cache.h create mode 100755 python/Modules/_sqlite/connection.c create mode 100755 python/Modules/_sqlite/connection.h create mode 100755 python/Modules/_sqlite/cursor.c create mode 100755 python/Modules/_sqlite/cursor.h create mode 100755 python/Modules/_sqlite/microprotocols.c create mode 100755 python/Modules/_sqlite/microprotocols.h create mode 100755 python/Modules/_sqlite/module.c create mode 100755 python/Modules/_sqlite/module.h create mode 100755 python/Modules/_sqlite/prepare_protocol.c create mode 100755 python/Modules/_sqlite/prepare_protocol.h create mode 100755 python/Modules/_sqlite/row.c create mode 100755 python/Modules/_sqlite/row.h create mode 100755 python/Modules/_sqlite/statement.c create mode 100755 python/Modules/_sqlite/statement.h create mode 100755 python/Modules/_sqlite/util.c create mode 100755 python/Modules/_sqlite/util.h create mode 100755 python/Modules/_sre.c create mode 100755 python/Modules/_ssl.c create mode 100755 python/Modules/_ssl/debughelpers.c create mode 100755 python/Modules/_ssl_data.h create mode 100755 python/Modules/_ssl_data_111.h create mode 100755 python/Modules/_ssl_data_300.h create mode 100755 python/Modules/_stat.c create mode 100755 python/Modules/_statisticsmodule.c create mode 100755 python/Modules/_struct.c create mode 100755 python/Modules/_testbuffer.c create mode 100755 python/Modules/_testcapimodule.c create mode 100755 python/Modules/_testimportmultiple.c create mode 100755 python/Modules/_testinternalcapi.c create mode 100755 python/Modules/_testmultiphase.c create mode 100755 python/Modules/_threadmodule.c create mode 100755 python/Modules/_tkinter.c create mode 100755 python/Modules/_tracemalloc.c create mode 100755 python/Modules/_uuidmodule.c create mode 100755 python/Modules/_weakref.c create mode 100755 python/Modules/_winapi.c create mode 100755 python/Modules/_xxsubinterpretersmodule.c create mode 100755 python/Modules/_xxtestfuzz/README.rst create mode 100755 python/Modules/_xxtestfuzz/_xxtestfuzz.c create mode 100755 python/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict create mode 100755 python/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict create mode 100755 python/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv create mode 100755 python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json create mode 100755 python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json create mode 100755 python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json create mode 100755 python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json create mode 100755 python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json create mode 100755 python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json create mode 100755 python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links create mode 100755 python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters create mode 100755 python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn create mode 100755 python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number create mode 100755 python/Modules/_xxtestfuzz/fuzz_tests.txt create mode 100755 python/Modules/_xxtestfuzz/fuzzer.c create mode 100755 python/Modules/addrinfo.h create mode 100755 python/Modules/arraymodule.c create mode 100755 python/Modules/atexitmodule.c create mode 100755 python/Modules/audioop.c create mode 100755 python/Modules/binascii.c create mode 100755 python/Modules/cjkcodecs/README create mode 100755 python/Modules/cjkcodecs/_codecs_cn.c create mode 100755 python/Modules/cjkcodecs/_codecs_hk.c create mode 100755 python/Modules/cjkcodecs/_codecs_iso2022.c create mode 100755 python/Modules/cjkcodecs/_codecs_jp.c create mode 100755 python/Modules/cjkcodecs/_codecs_kr.c create mode 100755 python/Modules/cjkcodecs/_codecs_tw.c create mode 100755 python/Modules/cjkcodecs/alg_jisx0201.h create mode 100755 python/Modules/cjkcodecs/cjkcodecs.h create mode 100755 python/Modules/cjkcodecs/clinic/multibytecodec.c.h create mode 100755 python/Modules/cjkcodecs/emu_jisx0213_2000.h create mode 100755 python/Modules/cjkcodecs/mappings_cn.h create mode 100755 python/Modules/cjkcodecs/mappings_hk.h create mode 100755 python/Modules/cjkcodecs/mappings_jisx0213_pair.h create mode 100755 python/Modules/cjkcodecs/mappings_jp.h create mode 100755 python/Modules/cjkcodecs/mappings_kr.h create mode 100755 python/Modules/cjkcodecs/mappings_tw.h create mode 100755 python/Modules/cjkcodecs/multibytecodec.c create mode 100755 python/Modules/cjkcodecs/multibytecodec.h create mode 100755 python/Modules/clinic/_abc.c.h create mode 100755 python/Modules/clinic/_asynciomodule.c.h create mode 100755 python/Modules/clinic/_bz2module.c.h create mode 100755 python/Modules/clinic/_codecsmodule.c.h create mode 100755 python/Modules/clinic/_collectionsmodule.c.h create mode 100755 python/Modules/clinic/_contextvarsmodule.c.h create mode 100755 python/Modules/clinic/_cryptmodule.c.h create mode 100755 python/Modules/clinic/_curses_panel.c.h create mode 100755 python/Modules/clinic/_cursesmodule.c.h create mode 100755 python/Modules/clinic/_datetimemodule.c.h create mode 100755 python/Modules/clinic/_dbmmodule.c.h create mode 100755 python/Modules/clinic/_elementtree.c.h create mode 100755 python/Modules/clinic/_gdbmmodule.c.h create mode 100755 python/Modules/clinic/_hashopenssl.c.h create mode 100755 python/Modules/clinic/_heapqmodule.c.h create mode 100755 python/Modules/clinic/_lzmamodule.c.h create mode 100755 python/Modules/clinic/_opcode.c.h create mode 100755 python/Modules/clinic/_operator.c.h create mode 100755 python/Modules/clinic/_pickle.c.h create mode 100755 python/Modules/clinic/_queuemodule.c.h create mode 100755 python/Modules/clinic/_randommodule.c.h create mode 100755 python/Modules/clinic/_sre.c.h create mode 100755 python/Modules/clinic/_ssl.c.h create mode 100755 python/Modules/clinic/_statisticsmodule.c.h create mode 100755 python/Modules/clinic/_struct.c.h create mode 100755 python/Modules/clinic/_tkinter.c.h create mode 100755 python/Modules/clinic/_tracemalloc.c.h create mode 100755 python/Modules/clinic/_weakref.c.h create mode 100755 python/Modules/clinic/_winapi.c.h create mode 100755 python/Modules/clinic/arraymodule.c.h create mode 100755 python/Modules/clinic/audioop.c.h create mode 100755 python/Modules/clinic/binascii.c.h create mode 100755 python/Modules/clinic/cmathmodule.c.h create mode 100755 python/Modules/clinic/fcntlmodule.c.h create mode 100755 python/Modules/clinic/gcmodule.c.h create mode 100755 python/Modules/clinic/grpmodule.c.h create mode 100755 python/Modules/clinic/itertoolsmodule.c.h create mode 100755 python/Modules/clinic/mathmodule.c.h create mode 100755 python/Modules/clinic/md5module.c.h create mode 100755 python/Modules/clinic/posixmodule.c.h create mode 100755 python/Modules/clinic/pwdmodule.c.h create mode 100755 python/Modules/clinic/pyexpat.c.h create mode 100755 python/Modules/clinic/resource.c.h create mode 100755 python/Modules/clinic/selectmodule.c.h create mode 100755 python/Modules/clinic/sha1module.c.h create mode 100755 python/Modules/clinic/sha256module.c.h create mode 100755 python/Modules/clinic/sha512module.c.h create mode 100755 python/Modules/clinic/signalmodule.c.h create mode 100755 python/Modules/clinic/spwdmodule.c.h create mode 100755 python/Modules/clinic/symtablemodule.c.h create mode 100755 python/Modules/clinic/unicodedata.c.h create mode 100755 python/Modules/clinic/zlibmodule.c.h create mode 100755 python/Modules/cmathmodule.c create mode 100755 python/Modules/config.c create mode 100755 python/Modules/config.c.in create mode 100755 python/Modules/errnomodule.c create mode 100755 python/Modules/expat/COPYING create mode 100755 python/Modules/expat/ascii.h create mode 100755 python/Modules/expat/asciitab.h create mode 100755 python/Modules/expat/expat.h create mode 100755 python/Modules/expat/expat_config.h create mode 100755 python/Modules/expat/expat_external.h create mode 100755 python/Modules/expat/iasciitab.h create mode 100755 python/Modules/expat/internal.h create mode 100755 python/Modules/expat/latin1tab.h create mode 100755 python/Modules/expat/nametab.h create mode 100755 python/Modules/expat/pyexpatns.h create mode 100755 python/Modules/expat/siphash.h create mode 100755 python/Modules/expat/utf8tab.h create mode 100755 python/Modules/expat/winconfig.h create mode 100755 python/Modules/expat/xmlparse.c create mode 100755 python/Modules/expat/xmlrole.c create mode 100755 python/Modules/expat/xmlrole.h create mode 100755 python/Modules/expat/xmltok.c create mode 100755 python/Modules/expat/xmltok.h create mode 100755 python/Modules/expat/xmltok_impl.c create mode 100755 python/Modules/expat/xmltok_impl.h create mode 100755 python/Modules/expat/xmltok_ns.c create mode 100755 python/Modules/faulthandler.c create mode 100755 python/Modules/fcntlmodule.c create mode 100755 python/Modules/gc_weakref.txt create mode 100755 python/Modules/gcmodule.c create mode 100755 python/Modules/getaddrinfo.c create mode 100755 python/Modules/getbuildinfo.c create mode 100755 python/Modules/getnameinfo.c create mode 100755 python/Modules/getpath.c create mode 100755 python/Modules/grpmodule.c create mode 100755 python/Modules/hashlib.h create mode 100755 python/Modules/hashtable.c create mode 100755 python/Modules/hashtable.h create mode 100755 python/Modules/itertoolsmodule.c create mode 100755 python/Modules/ld_so_aix create mode 100755 python/Modules/ld_so_aix.in create mode 100755 python/Modules/main.c create mode 100755 python/Modules/makesetup create mode 100755 python/Modules/makexp_aix create mode 100755 python/Modules/mathmodule.c create mode 100755 python/Modules/md5module.c create mode 100755 python/Modules/mmapmodule.c create mode 100755 python/Modules/nismodule.c create mode 100755 python/Modules/ossaudiodev.c create mode 100755 python/Modules/overlapped.c create mode 100755 python/Modules/parsermodule.c create mode 100755 python/Modules/posixmodule.c create mode 100755 python/Modules/posixmodule.h create mode 100755 python/Modules/pwdmodule.c create mode 100755 python/Modules/pyexpat.c create mode 100755 python/Modules/readline.c create mode 100755 python/Modules/resource.c create mode 100755 python/Modules/rotatingtree.c create mode 100755 python/Modules/rotatingtree.h create mode 100755 python/Modules/selectmodule.c create mode 100755 python/Modules/sha1module.c create mode 100755 python/Modules/sha256module.c create mode 100755 python/Modules/sha512module.c create mode 100755 python/Modules/signalmodule.c create mode 100755 python/Modules/socketmodule.c create mode 100755 python/Modules/socketmodule.h create mode 100755 python/Modules/spwdmodule.c create mode 100755 python/Modules/sre.h create mode 100755 python/Modules/sre_constants.h create mode 100755 python/Modules/sre_lib.h create mode 100755 python/Modules/symtablemodule.c create mode 100755 python/Modules/syslogmodule.c create mode 100755 python/Modules/termios.c create mode 100755 python/Modules/testcapi_long.h create mode 100755 python/Modules/timemodule.c create mode 100755 python/Modules/tkappinit.c create mode 100755 python/Modules/tkinter.h create mode 100755 python/Modules/unicodedata.c create mode 100755 python/Modules/unicodedata_db.h create mode 100755 python/Modules/unicodename_db.h create mode 100755 python/Modules/winreparse.h create mode 100755 python/Modules/xxlimited.c create mode 100755 python/Modules/xxmodule.c create mode 100755 python/Modules/xxsubtype.c create mode 100755 python/Modules/zlibmodule.c create mode 100755 python/Objects/README create mode 100755 python/Objects/abstract.c create mode 100755 python/Objects/accu.c create mode 100755 python/Objects/boolobject.c create mode 100755 python/Objects/bytearrayobject.c create mode 100755 python/Objects/bytes_methods.c create mode 100755 python/Objects/bytesobject.c create mode 100755 python/Objects/call.c create mode 100755 python/Objects/capsule.c create mode 100755 python/Objects/cellobject.c create mode 100755 python/Objects/classobject.c create mode 100755 python/Objects/clinic/bytearrayobject.c.h create mode 100755 python/Objects/clinic/bytesobject.c.h create mode 100755 python/Objects/clinic/codeobject.c.h create mode 100755 python/Objects/clinic/complexobject.c.h create mode 100755 python/Objects/clinic/descrobject.c.h create mode 100755 python/Objects/clinic/dictobject.c.h create mode 100755 python/Objects/clinic/enumobject.c.h create mode 100755 python/Objects/clinic/floatobject.c.h create mode 100755 python/Objects/clinic/funcobject.c.h create mode 100755 python/Objects/clinic/listobject.c.h create mode 100755 python/Objects/clinic/longobject.c.h create mode 100755 python/Objects/clinic/memoryobject.c.h create mode 100755 python/Objects/clinic/moduleobject.c.h create mode 100755 python/Objects/clinic/odictobject.c.h create mode 100755 python/Objects/clinic/structseq.c.h create mode 100755 python/Objects/clinic/tupleobject.c.h create mode 100755 python/Objects/clinic/typeobject.c.h create mode 100755 python/Objects/clinic/unicodeobject.c.h create mode 100755 python/Objects/codeobject.c create mode 100755 python/Objects/complexobject.c create mode 100755 python/Objects/descrobject.c create mode 100755 python/Objects/dict-common.h create mode 100755 python/Objects/dictnotes.txt create mode 100755 python/Objects/dictobject.c create mode 100755 python/Objects/enumobject.c create mode 100755 python/Objects/exceptions.c create mode 100755 python/Objects/fileobject.c create mode 100755 python/Objects/floatobject.c create mode 100755 python/Objects/frameobject.c create mode 100755 python/Objects/funcobject.c create mode 100755 python/Objects/genobject.c create mode 100755 python/Objects/interpreteridobject.c create mode 100755 python/Objects/iterobject.c create mode 100755 python/Objects/listobject.c create mode 100755 python/Objects/listsort.txt create mode 100755 python/Objects/lnotab_notes.txt create mode 100755 python/Objects/longobject.c create mode 100755 python/Objects/memoryobject.c create mode 100755 python/Objects/methodobject.c create mode 100755 python/Objects/moduleobject.c create mode 100755 python/Objects/namespaceobject.c create mode 100755 python/Objects/object.c create mode 100755 python/Objects/obmalloc.c create mode 100755 python/Objects/odictobject.c create mode 100755 python/Objects/picklebufobject.c create mode 100755 python/Objects/rangeobject.c create mode 100755 python/Objects/setobject.c create mode 100755 python/Objects/sliceobject.c create mode 100755 python/Objects/stringlib/README.txt create mode 100755 python/Objects/stringlib/asciilib.h create mode 100755 python/Objects/stringlib/clinic/transmogrify.h.h create mode 100755 python/Objects/stringlib/codecs.h create mode 100755 python/Objects/stringlib/count.h create mode 100755 python/Objects/stringlib/ctype.h create mode 100755 python/Objects/stringlib/eq.h create mode 100755 python/Objects/stringlib/fastsearch.h create mode 100755 python/Objects/stringlib/find.h create mode 100755 python/Objects/stringlib/find_max_char.h create mode 100755 python/Objects/stringlib/join.h create mode 100755 python/Objects/stringlib/localeutil.h create mode 100755 python/Objects/stringlib/partition.h create mode 100755 python/Objects/stringlib/replace.h create mode 100755 python/Objects/stringlib/split.h create mode 100755 python/Objects/stringlib/stringdefs.h create mode 100755 python/Objects/stringlib/transmogrify.h create mode 100755 python/Objects/stringlib/ucs1lib.h create mode 100755 python/Objects/stringlib/ucs2lib.h create mode 100755 python/Objects/stringlib/ucs4lib.h create mode 100755 python/Objects/stringlib/undef.h create mode 100755 python/Objects/stringlib/unicode_format.h create mode 100755 python/Objects/stringlib/unicodedefs.h create mode 100755 python/Objects/structseq.c create mode 100755 python/Objects/tupleobject.c create mode 100755 python/Objects/typeobject.c create mode 100755 python/Objects/typeslots.inc create mode 100755 python/Objects/typeslots.py create mode 100755 python/Objects/unicodectype.c create mode 100755 python/Objects/unicodeobject.c create mode 100755 python/Objects/unicodetype_db.h create mode 100755 python/Objects/weakrefobject.c create mode 100755 python/Parser/Python.asdl create mode 100755 python/Parser/acceler.c create mode 100755 python/Parser/asdl.py create mode 100755 python/Parser/asdl_c.py create mode 100755 python/Parser/grammar1.c create mode 100755 python/Parser/listnode.c create mode 100755 python/Parser/myreadline.c create mode 100755 python/Parser/node.c create mode 100755 python/Parser/parser.c create mode 100755 python/Parser/parser.h create mode 100755 python/Parser/parsetok.c create mode 100755 python/Parser/pgen/__init__.py create mode 100755 python/Parser/pgen/__main__.py create mode 100755 python/Parser/pgen/grammar.py create mode 100755 python/Parser/pgen/keywordgen.py create mode 100755 python/Parser/pgen/pgen.py create mode 100755 python/Parser/pgen/token.py create mode 100755 python/Parser/token.c create mode 100755 python/Parser/tokenizer.c create mode 100755 python/Parser/tokenizer.h create mode 100755 python/Programs/README create mode 100755 python/Programs/_freeze_importlib.c create mode 100755 python/Programs/_testembed create mode 100755 python/Programs/_testembed.c create mode 100755 python/Programs/python.c create mode 100755 python/Python/Python-ast.c create mode 100755 python/Python/README create mode 100755 python/Python/_warnings.c create mode 100755 python/Python/asdl.c create mode 100755 python/Python/ast.c create mode 100755 python/Python/ast_opt.c create mode 100755 python/Python/ast_unparse.c create mode 100755 python/Python/bltinmodule.c create mode 100755 python/Python/bootstrap_hash.c create mode 100755 python/Python/ceval.c create mode 100755 python/Python/ceval_gil.h create mode 100755 python/Python/clinic/_warnings.c.h create mode 100755 python/Python/clinic/bltinmodule.c.h create mode 100755 python/Python/clinic/context.c.h create mode 100755 python/Python/clinic/import.c.h create mode 100755 python/Python/clinic/marshal.c.h create mode 100755 python/Python/clinic/sysmodule.c.h create mode 100755 python/Python/clinic/traceback.c.h create mode 100755 python/Python/codecs.c create mode 100755 python/Python/compile.c create mode 100755 python/Python/condvar.h create mode 100755 python/Python/context.c create mode 100755 python/Python/dtoa.c create mode 100755 python/Python/dup2.c create mode 100755 python/Python/dynamic_annotations.c create mode 100755 python/Python/dynload_aix.c create mode 100755 python/Python/dynload_dl.c create mode 100755 python/Python/dynload_hpux.c create mode 100755 python/Python/dynload_shlib.c create mode 100755 python/Python/dynload_stub.c create mode 100755 python/Python/dynload_win.c create mode 100755 python/Python/errors.c create mode 100755 python/Python/fileutils.c create mode 100755 python/Python/formatter_unicode.c create mode 100755 python/Python/frozen.c create mode 100755 python/Python/frozenmain.c create mode 100755 python/Python/future.c create mode 100755 python/Python/getargs.c create mode 100755 python/Python/getcompiler.c create mode 100755 python/Python/getcopyright.c create mode 100755 python/Python/getopt.c create mode 100755 python/Python/getplatform.c create mode 100755 python/Python/getversion.c create mode 100755 python/Python/graminit.c create mode 100755 python/Python/hamt.c create mode 100755 python/Python/import.c create mode 100755 python/Python/importdl.c create mode 100755 python/Python/importdl.h create mode 100755 python/Python/importlib.h create mode 100755 python/Python/importlib_external.h create mode 100755 python/Python/importlib_zipimport.h create mode 100755 python/Python/initconfig.c create mode 100755 python/Python/makeopcodetargets.py create mode 100755 python/Python/marshal.c create mode 100755 python/Python/modsupport.c create mode 100755 python/Python/mysnprintf.c create mode 100755 python/Python/mystrtoul.c create mode 100755 python/Python/opcode_targets.h create mode 100755 python/Python/pathconfig.c create mode 100755 python/Python/peephole.c create mode 100755 python/Python/preconfig.c create mode 100755 python/Python/pyarena.c create mode 100755 python/Python/pyctype.c create mode 100755 python/Python/pyfpe.c create mode 100755 python/Python/pyhash.c create mode 100755 python/Python/pylifecycle.c create mode 100755 python/Python/pymath.c create mode 100755 python/Python/pystate.c create mode 100755 python/Python/pystrcmp.c create mode 100755 python/Python/pystrhex.c create mode 100755 python/Python/pystrtod.c create mode 100755 python/Python/pythonrun.c create mode 100755 python/Python/pytime.c create mode 100755 python/Python/strdup.c create mode 100755 python/Python/structmember.c create mode 100755 python/Python/symtable.c create mode 100755 python/Python/sysmodule.c create mode 100755 python/Python/thread.c create mode 100755 python/Python/thread_nt.h create mode 100755 python/Python/thread_pthread.h create mode 100755 python/Python/traceback.c create mode 100755 python/Python/wordcode_helpers.h create mode 100755 python/include/Python-ast.h create mode 100755 python/include/Python.h create mode 100755 python/include/abstract.h create mode 100755 python/include/asdl.h create mode 100755 python/include/ast.h create mode 100755 python/include/bitset.h create mode 100755 python/include/bltinmodule.h create mode 100755 python/include/boolobject.h create mode 100755 python/include/bytearrayobject.h create mode 100755 python/include/bytes_methods.h create mode 100755 python/include/bytesobject.h create mode 100755 python/include/cellobject.h create mode 100755 python/include/ceval.h create mode 100755 python/include/classobject.h create mode 100755 python/include/code.h create mode 100755 python/include/codecs.h create mode 100755 python/include/compile.h create mode 100755 python/include/complexobject.h create mode 100755 python/include/context.h create mode 100755 python/include/cpython/abstract.h create mode 100755 python/include/cpython/dictobject.h create mode 100755 python/include/cpython/fileobject.h create mode 100755 python/include/cpython/initconfig.h create mode 100755 python/include/cpython/interpreteridobject.h create mode 100755 python/include/cpython/object.h create mode 100755 python/include/cpython/objimpl.h create mode 100755 python/include/cpython/pyerrors.h create mode 100755 python/include/cpython/pylifecycle.h create mode 100755 python/include/cpython/pymem.h create mode 100755 python/include/cpython/pystate.h create mode 100755 python/include/cpython/sysmodule.h create mode 100755 python/include/cpython/traceback.h create mode 100755 python/include/cpython/tupleobject.h create mode 100755 python/include/cpython/unicodeobject.h create mode 100755 python/include/datetime.h create mode 100755 python/include/descrobject.h create mode 100755 python/include/dictobject.h create mode 100755 python/include/dtoa.h create mode 100755 python/include/dynamic_annotations.h create mode 100755 python/include/enumobject.h create mode 100755 python/include/errcode.h create mode 100755 python/include/eval.h create mode 100755 python/include/fileobject.h create mode 100755 python/include/fileutils.h create mode 100755 python/include/floatobject.h create mode 100755 python/include/frameobject.h create mode 100755 python/include/funcobject.h create mode 100755 python/include/genobject.h create mode 100755 python/include/graminit.h create mode 100755 python/include/grammar.h create mode 100755 python/include/import.h create mode 100755 python/include/internal/pycore_accu.h create mode 100755 python/include/internal/pycore_atomic.h create mode 100755 python/include/internal/pycore_ceval.h create mode 100755 python/include/internal/pycore_code.h create mode 100755 python/include/internal/pycore_condvar.h create mode 100755 python/include/internal/pycore_context.h create mode 100755 python/include/internal/pycore_fileutils.h create mode 100755 python/include/internal/pycore_getopt.h create mode 100755 python/include/internal/pycore_gil.h create mode 100755 python/include/internal/pycore_hamt.h create mode 100755 python/include/internal/pycore_initconfig.h create mode 100755 python/include/internal/pycore_object.h create mode 100755 python/include/internal/pycore_pathconfig.h create mode 100755 python/include/internal/pycore_pyerrors.h create mode 100755 python/include/internal/pycore_pyhash.h create mode 100755 python/include/internal/pycore_pylifecycle.h create mode 100755 python/include/internal/pycore_pymem.h create mode 100755 python/include/internal/pycore_pystate.h create mode 100755 python/include/internal/pycore_traceback.h create mode 100755 python/include/internal/pycore_tupleobject.h create mode 100755 python/include/internal/pycore_warnings.h create mode 100755 python/include/interpreteridobject.h create mode 100755 python/include/intrcheck.h create mode 100755 python/include/iterobject.h create mode 100755 python/include/listobject.h create mode 100755 python/include/longintrepr.h create mode 100755 python/include/longobject.h create mode 100755 python/include/marshal.h create mode 100755 python/include/memoryobject.h create mode 100755 python/include/methodobject.h create mode 100755 python/include/modsupport.h create mode 100755 python/include/moduleobject.h create mode 100755 python/include/namespaceobject.h create mode 100755 python/include/node.h create mode 100755 python/include/object.h create mode 100755 python/include/objimpl.h create mode 100755 python/include/odictobject.h create mode 100755 python/include/opcode.h create mode 100755 python/include/osdefs.h create mode 100755 python/include/osmodule.h create mode 100755 python/include/parsetok.h create mode 100755 python/include/patchlevel.h create mode 100755 python/include/picklebufobject.h create mode 100755 python/include/py_curses.h create mode 100755 python/include/pyarena.h create mode 100755 python/include/pycapsule.h create mode 100755 python/include/pyctype.h create mode 100755 python/include/pydebug.h create mode 100755 python/include/pydtrace.d create mode 100755 python/include/pydtrace.h create mode 100755 python/include/pyerrors.h create mode 100755 python/include/pyexpat.h create mode 100755 python/include/pyfpe.h create mode 100755 python/include/pyhash.h create mode 100755 python/include/pylifecycle.h create mode 100755 python/include/pymacconfig.h create mode 100755 python/include/pymacro.h create mode 100755 python/include/pymath.h create mode 100755 python/include/pymem.h create mode 100755 python/include/pyport.h create mode 100755 python/include/pystate.h create mode 100755 python/include/pystrcmp.h create mode 100755 python/include/pystrhex.h create mode 100755 python/include/pystrtod.h create mode 100755 python/include/pythonrun.h create mode 100755 python/include/pythread.h create mode 100755 python/include/pytime.h create mode 100755 python/include/rangeobject.h create mode 100755 python/include/setobject.h create mode 100755 python/include/sliceobject.h create mode 100755 python/include/structmember.h create mode 100755 python/include/structseq.h create mode 100755 python/include/symtable.h create mode 100755 python/include/sysmodule.h create mode 100755 python/include/token.h create mode 100755 python/include/traceback.h create mode 100755 python/include/tracemalloc.h create mode 100755 python/include/tupleobject.h create mode 100755 python/include/typeslots.h create mode 100755 python/include/ucnhash.h create mode 100755 python/include/unicodeobject.h create mode 100755 python/include/warnings.h create mode 100755 python/include/weakrefobject.h create mode 100755 python/pyconfig.h diff --git a/ohos.build b/ohos.build new file mode 100755 index 0000000..0f08130 --- /dev/null +++ b/ohos.build @@ -0,0 +1,15 @@ +{ + "subsystem": "communication", + "parts": { + "python_part": { + "variants": [ + "phone", + "wearable", + "ivi" + ], + "module_list": [ + "//foundation/communication/python_part/python:python_all" + ] + } + } +} diff --git a/python/BUILD.gn b/python/BUILD.gn new file mode 100755 index 0000000..0cf6a99 --- /dev/null +++ b/python/BUILD.gn @@ -0,0 +1,889 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("python_config") { + include_dirs = [ + "include", + "include/internal", + "Modules", + "Modules/expat", + ".", + "Modules/_decimal/libmpdec" + ] + + defines = [ + "CONFIG_32", + "SOABI=\"pythonlib\"", + "Py_BUILD_CORE", + "Py_BUILD_CORE_MODULE", + "PREFIX=\"/system\"", + "EXEC_PREFIX=\"/system\"", + "PYTHONPATH=\"/system\"", + "VERSION=\"3.8\"", + "VPATH=\"/system\"", + "NETMGR_LOG_TAG = \"NetConnManager\"", + ] +} + +ohos_shared_library("hipython") { + sources = [ +"Parser/acceler.c", +"Parser/grammar1.c", +"Parser/listnode.c", +"Parser/myreadline.c", +"Parser/node.c", +"Parser/parser.c", +"Parser/parsetok.c", +"Parser/token.c", +"Parser/tokenizer.c", + +"Modules/_datetimemodule.c", +"Modules/_stat.c", +"Modules/timemodule.c", + +"Modules/_io/bufferedio.c", +"Modules/_io/bytesio.c", +"Modules/_io/fileio.c", +"Modules/_io/iobase.c", +"Modules/_io/stringio.c", +"Modules/_io/textio.c", +"Modules/_io/winconsoleio.c", +"Modules/_io/_iomodule.c", + +"Modules/atexitmodule.c", +"Modules/config.c", +"Modules/errnomodule.c", +"Modules/faulthandler.c", +"Modules/gcmodule.c", +"Modules/getaddrinfo.c", +"Modules/getbuildinfo.c", +"Modules/getnameinfo.c", +"Modules/getpath.c", +"Modules/hashtable.c", +"Modules/itertoolsmodule.c", +"Modules/main.c", +"Modules/nismodule.c", +"Modules/overlapped.c", +"Modules/posixmodule.c", +"Modules/pwdmodule.c", +"Modules/readline.c", +"Modules/rotatingtree.c", +"Modules/signalmodule.c", +"Modules/symtablemodule.c", +"Modules/tkappinit.c", +"Modules/xxmodule.c", +"Modules/xxsubtype.c", +"Modules/zlibmodule.c", +"Modules/_abc.c", +"Modules/_bz2module.c", +"Modules/_codecsmodule.c", +"Modules/_collectionsmodule.c", +"Modules/_cursesmodule.c", +"Modules/_curses_panel.c", +"Modules/_dbmmodule.c", +"Modules/_functoolsmodule.c", +"Modules/_gdbmmodule.c", +"Modules/_hashopenssl.c", +"Modules/_localemodule.c", +"Modules/_lzmamodule.c", +"Modules/_math.c", +"Modules/_operator.c", +"Modules/_scproxy.c", +"Modules/_sre.c", +"Modules/_ssl.c", +"Modules/_threadmodule.c", +"Modules/_tkinter.c", +"Modules/_tracemalloc.c", +"Modules/_uuidmodule.c", +"Modules/_weakref.c", +"Modules/_winapi.c", + +"Objects/abstract.c", +"Objects/accu.c", +"Objects/boolobject.c", +"Objects/bytearrayobject.c", +"Objects/bytesobject.c", +"Objects/bytes_methods.c", +"Objects/call.c", +"Objects/capsule.c", +"Objects/cellobject.c", +"Objects/classobject.c", +"Objects/codeobject.c", +"Objects/complexobject.c", +"Objects/descrobject.c", +"Objects/dictobject.c", +"Objects/enumobject.c", +"Objects/exceptions.c", +"Objects/fileobject.c", +"Objects/floatobject.c", +"Objects/frameobject.c", +"Objects/funcobject.c", +"Objects/genobject.c", +"Objects/interpreteridobject.c", +"Objects/iterobject.c", +"Objects/listobject.c", +"Objects/longobject.c", +"Objects/memoryobject.c", +"Objects/methodobject.c", +"Objects/moduleobject.c", +"Objects/namespaceobject.c", +"Objects/object.c", +"Objects/obmalloc.c", +"Objects/odictobject.c", +"Objects/picklebufobject.c", +"Objects/rangeobject.c", +"Objects/setobject.c", +"Objects/sliceobject.c", +"Objects/structseq.c", +"Objects/tupleobject.c", +"Objects/typeobject.c", +"Objects/unicodectype.c", +"Objects/unicodeobject.c", +"Objects/weakrefobject.c", + +"Python/asdl.c", +"Python/ast.c", +"Python/ast_opt.c", +"Python/ast_unparse.c", +"Python/bltinmodule.c", +"Python/bootstrap_hash.c", +"Python/ceval.c", +"Python/codecs.c", +"Python/compile.c", +"Python/context.c", +"Python/dtoa.c", +"Python/dup2.c", +"Python/dynamic_annotations.c", +#"Python/dynload_aix.c", +# "Python/dynload_dl.c", +#"Python/dynload_hpux.c", +"Python/dynload_shlib.c", +# "Python/dynload_stub.c", +#"Python/dynload_win.c", +"Python/errors.c", +"Python/fileutils.c", +"Python/formatter_unicode.c", +"Python/frozen.c", +"Python/frozenmain.c", +"Python/future.c", +"Python/getargs.c", +"Python/getcompiler.c", +"Python/getcopyright.c", +"Python/getopt.c", +"Python/getplatform.c", +"Python/getversion.c", +"Python/graminit.c", +"Python/hamt.c", +"Python/import.c", +"Python/importdl.c", +"Python/initconfig.c", +"Python/marshal.c", +"Python/modsupport.c", +"Python/mysnprintf.c", +"Python/mystrtoul.c", +"Python/pathconfig.c", +"Python/peephole.c", +"Python/preconfig.c", +"Python/pyarena.c", +"Python/pyctype.c", +"Python/pyfpe.c", +"Python/pyhash.c", +"Python/pylifecycle.c", +"Python/pymath.c", +"Python/pystate.c", +"Python/pystrcmp.c", +"Python/pystrhex.c", +"Python/pystrtod.c", +"Python/Python-ast.c", +"Python/pythonrun.c", +"Python/pytime.c", +"Python/strdup.c", +"Python/structmember.c", +"Python/symtable.c", +"Python/sysmodule.c", +"Python/thread.c", +"Python/traceback.c", +"Python/_warnings.c", + ] + + configs=[":python_config"] + + deps = [ + # "//utils/native/base:utils", + # "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + # "//foundation/graphic/standard:libvsync_client", + # "//foundation/graphic/standard:libwmclient", + # "//foundation/graphic/standard:libwmservice", + "//third_party/zlib:libz", + ] + + # external_deps = [ + # "safwk:system_ability_fwk", + # "appexecfwk_standard:libeventhandler", + # "samgr_L2:samgr_proxy", + # "ipc:ipc_core", + # "aafwk_standard:want", + # "cellular_data:tel_cellular_data_api" + # ] + + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_asyncio") +{ + sources=["Modules/_asynciomodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_bisect") +{ + sources=["Modules/_bisectmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_blake2") +{ + sources=["Modules/_blake2/blake2module.c", + "Modules/_blake2/blake2b_impl.c", + "Modules/_blake2/blake2s_impl.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_codecs_cn") +{ + sources=["Modules/cjkcodecs/_codecs_cn.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_codecs_hk") +{ + sources=["Modules/cjkcodecs/_codecs_hk.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_codecs_iso2022") +{ + sources=["Modules/cjkcodecs/_codecs_iso2022.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_codecs_jp") +{ + sources=["Modules/cjkcodecs/_codecs_jp.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_codecs_kr") +{ + sources=["Modules/cjkcodecs/_codecs_kr.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_codecs_tw") +{ + sources=["Modules/cjkcodecs/_codecs_tw.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_contextvars") +{ + sources=["Modules/_contextvarsmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_crypt") +{ + sources=["Modules/_cryptmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_csv") +{ + sources=["Modules/_csv.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +# ohos_shared_library("module_ctypes") +# { +# sources=["Modules/_ctypes/_ctypes.c"] +# configs=[":python_config"] +# deps = ["//foundation/communication/python_part/python:hipython"] +# part_name = "python_part" +# subsystem_name = "communication" +# } + +# ohos_shared_library("module_ctypes_test") +# { +# sources=["Modules/_ctypes/_ctypes_test.c"] +# configs=[":python_config"] +# deps = ["//foundation/communication/python_part/python:hipython"] +# part_name = "python_part" +# subsystem_name = "communication" +# } + +ohos_shared_library("module_datetime") +{ + sources=["Modules/_datetimemodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +# ohos_shared_library("module_decimal") +# { +# sources=["Modules/_decimal/_decimal.c", +# "Modules/_decimal/libmpdec/basearith.c", +# "Modules/_decimal/libmpdec/constants.c", +# "Modules/_decimal/libmpdec/context.c", +# "Modules/_decimal/libmpdec/convolute.c", +# "Modules/_decimal/libmpdec/crt.c", +# "Modules/_decimal/libmpdec/difradix2.c", +# "Modules/_decimal/libmpdec/fnt.c", +# "Modules/_decimal/libmpdec/fourstep.c", +# "Modules/_decimal/libmpdec/io.c", +# "Modules/_decimal/libmpdec/memory.c", +# "Modules/_decimal/libmpdec/mpdecimal.c", +# "Modules/_decimal/libmpdec/numbertheory.c", +# "Modules/_decimal/libmpdec/sixstep.c", +# "Modules/_decimal/libmpdec/transpose.c"] +# configs=[":python_config"] +# deps = ["//foundation/communication/python_part/python:hipython"] +# part_name = "python_part" +# subsystem_name = "communication" +# } + +ohos_shared_library("module_elementtree") +{ + sources=["Modules/_elementtree.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_heapq") +{ + sources=["Modules/_heapqmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_json") +{ + sources=["Modules/_json.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_lsprof") +{ + sources=["Modules/_lsprof.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_md5") +{ + sources=["Modules/md5module.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_multibytecodec") +{ + sources=["Modules/cjkcodecs/multibytecodec.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_multiprocessing") +{ + sources=["Modules/_multiprocessing/multiprocessing.c", + "Modules/_multiprocessing/semaphore.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_opcode") +{ + sources=["Modules/_opcode.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_pickle") +{ + sources=["Modules/_pickle.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_posixshmem") +{ + sources=["Modules/_multiprocessing/posixshmem.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_posixsubprocess") +{ + sources=["Modules/_posixsubprocess.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_queue") +{ + sources=["Modules/_queuemodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_random") +{ + sources=["Modules/_randommodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_sha1") +{ + sources=["Modules/sha1module.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_sha256") +{ + sources=["Modules/sha256module.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_sha3") +{ + sources=["Modules/_sha3/sha3module.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_sha512") +{ + sources=["Modules/sha512module.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_socket") +{ + sources=["Modules/socketmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_statistics") +{ + sources=["Modules/_statisticsmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_struct") +{ + sources=["Modules/_struct.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_testbuffer") +{ + sources=["Modules/_testbuffer.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_testcapi") +{ + sources=["Modules/_testcapimodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_testimportmultiple") +{ + sources=["Modules/_testimportmultiple.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_testinternalcapi") +{ + sources=["Modules/_testinternalcapi.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_testmultiphase") +{ + sources=["Modules/_testmultiphase.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_xxsubinterpreters") +{ + sources=["Modules/_xxsubinterpretersmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("module_xxtestfuzz") +{ + sources=["Modules/_xxtestfuzz/_xxtestfuzz.c", + "Modules/_xxtestfuzz/fuzzer.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulearray") +{ + sources=["Modules/arraymodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("moduleaudioop") +{ + sources=["Modules/audioop.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulebinascii") +{ + sources=["Modules/binascii.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulecmath") +{ + sources=["Modules/cmathmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulefcntl") +{ + sources=["Modules/fcntlmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulegrp") +{ + sources=["Modules/grpmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulemath") +{ + sources=["Modules/mathmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulemmap") +{ + sources=["Modules/mmapmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("moduleossaudiodev") +{ + sources=["Modules/ossaudiodev.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("moduleparser") +{ + sources=["Modules/parsermodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulepyexpat") +{ + sources=["Modules/pyexpat.c", + "Modules/expat/xmlparse.c", + "Modules/expat/xmlrole.c", + "Modules/expat/xmltok.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("moduleresource") +{ + sources=["Modules/resource.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("moduleselect") +{ + sources=["Modules/selectmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulespwd") +{ + sources=["Modules/spwdmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulesyslog") +{ + sources=["Modules/syslogmodule.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("moduletermios") +{ + sources=["Modules/termios.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("moduleunicodedata") +{ + sources=["Modules/unicodedata.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_shared_library("modulexxlimited") +{ + sources=["Modules/xxlimited.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +ohos_executable("python") +{ + sources=["Programs/python.c"] + configs=[":python_config"] + deps = ["//foundation/communication/python_part/python:hipython"] + part_name = "python_part" + subsystem_name = "communication" +} + +group("python_all") { + deps = [ + ":python", + ":module_asyncio", + ":module_bisect", + ":module_blake2", + ":module_codecs_cn", + ":module_codecs_hk", + ":module_codecs_iso2022", + ":module_codecs_jp", + ":module_codecs_kr", + ":module_codecs_tw", + ":module_contextvars", + ":module_crypt", + ":module_csv", + # ":module_ctypes", + # ":module_ctypes_test", + ":module_datetime", + # ":module_decimal", + ":module_elementtree", + ":module_heapq", + ":module_json", + ":module_lsprof", + ":module_md5", + ":module_multibytecodec", + ":module_multiprocessing", + ":module_opcode", + ":module_pickle", + ":module_posixshmem", + ":module_posixsubprocess", + ":module_queue", + ":module_random", + ":module_sha1", + ":module_sha256", + ":module_sha3", + ":module_sha512", + ":module_socket", + ":module_statistics", + ":module_struct", + ":module_testbuffer", + ":module_testcapi", + ":module_testimportmultiple", + ":module_testinternalcapi", + ":module_testmultiphase", + ":module_xxsubinterpreters", + ":module_xxtestfuzz", + ":modulearray", + ":moduleaudioop", + ":modulebinascii", + ":modulecmath", + ":modulefcntl", + ":modulegrp", + ":modulemath", + ":modulemmap", + ":moduleossaudiodev", + ":moduleparser", + ":modulepyexpat", + ":moduleresource", + ":moduleselect", + ":modulespwd", + ":modulesyslog", + ":moduletermios", + ":moduleunicodedata", + ":modulexxlimited" + ] +} \ No newline at end of file diff --git a/python/Modules/README b/python/Modules/README new file mode 100755 index 0000000..9b79f53 --- /dev/null +++ b/python/Modules/README @@ -0,0 +1,2 @@ +Source files for standard library extension modules, +and former extension modules that are now builtin modules. diff --git a/python/Modules/Setup b/python/Modules/Setup new file mode 100755 index 0000000..983fa01 --- /dev/null +++ b/python/Modules/Setup @@ -0,0 +1,368 @@ +# -*- makefile -*- +# The file Setup is used by the makesetup script to construct the files +# Makefile and config.c, from Makefile.pre and config.c.in, +# respectively. Note that Makefile.pre is created from Makefile.pre.in +# by the toplevel configure script. + +# (VPATH notes: Setup and Makefile.pre are in the build directory, as +# are Makefile and config.c; the *.in files are in the source directory.) + +# Each line in this file describes one or more optional modules. +# Modules configured here will not be compiled by the setup.py script, +# so the file can be used to override setup.py's behavior. +# Tag lines containing just the word "*static*", "*shared*" or "*disabled*" +# (without the quotes but with the stars) are used to tag the following module +# descriptions. Tag lines may alternate throughout this file. Modules are +# built statically when they are preceded by a "*static*" tag line or when +# there is no tag line between the start of the file and the module +# description. Modules are built as a shared library when they are preceded by +# a "*shared*" tag line. Modules are not built at all, not by the Makefile, +# nor by the setup.py script, when they are preceded by a "*disabled*" tag +# line. + +# Lines have the following structure: +# +# ... [ ...] [ ...] [ ...] +# +# is anything ending in .c (.C, .cc, .c++ are C++ files) +# is anything starting with -I, -D, -U or -C +# is anything ending in .a or beginning with -l or -L +# is anything else but should be a valid Python +# identifier (letters, digits, underscores, beginning with non-digit) +# +# (As the makesetup script changes, it may recognize some other +# arguments as well, e.g. *.so and *.sl as libraries. See the big +# case statement in the makesetup script.) +# +# Lines can also have the form +# +# = +# +# which defines a Make variable definition inserted into Makefile.in +# +# The build process works like this: +# +# 1. Build all modules that are declared as static in Modules/Setup, +# combine them into libpythonxy.a, combine that into python. +# 2. Build all modules that are listed as shared in Modules/Setup. +# 3. Invoke setup.py. That builds all modules that +# a) are not builtin, and +# b) are not listed in Modules/Setup, and +# c) can be build on the target +# +# Therefore, modules declared to be shared will not be +# included in the config.c file, nor in the list of objects to be +# added to the library archive, and their linker options won't be +# added to the linker options. Rules to create their .o files and +# their shared libraries will still be added to the Makefile, and +# their names will be collected in the Make variable SHAREDMODS. This +# is used to build modules as shared libraries. (They can be +# installed using "make sharedinstall", which is implied by the +# toplevel "make install" target.) (For compatibility, +# *noconfig* has the same effect as *shared*.) +# +# NOTE: As a standard policy, as many modules as can be supported by a +# platform should be present. The distribution comes with all modules +# enabled that are supported by most platforms and don't require you +# to ftp sources from elsewhere. + + +# Some special rules to define PYTHONPATH. +# Edit the definitions below to indicate which options you are using. +# Don't add any whitespace or comments! + +# Directories where library files get installed. +# DESTLIB is for Python modules; MACHDESTLIB for shared libraries. +DESTLIB=$(LIBDEST) +MACHDESTLIB=$(BINLIBDEST) + +# NOTE: all the paths are now relative to the prefix that is computed +# at run time! + +# Standard path -- don't edit. +# No leading colon since this is the first entry. +# Empty since this is now just the runtime prefix. +DESTPATH= + +# Site specific path components -- should begin with : if non-empty +SITEPATH= + +# Standard path components for test modules +TESTPATH= + +COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH) +PYTHONPATH=$(COREPYTHONPATH) + + +# The modules listed here can't be built as shared libraries for +# various reasons; therefore they are listed here instead of in the +# normal order. + +# This only contains the minimal set of modules required to run the +# setup.py script in the root of the Python source tree. + +posix -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal posixmodule.c # posix (UNIX) system calls +errno errnomodule.c # posix (UNIX) errno values +pwd pwdmodule.c # this is needed to find out the user's home dir + # if $HOME is not set +_sre _sre.c # Fredrik Lundh's new regular expressions +_codecs _codecsmodule.c # access to the builtin codecs and codec registry +_weakref _weakref.c # weak references +_functools -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _functoolsmodule.c # Tools for working with functions and callable objects +_operator _operator.c # operator.add() and similar goodies +_collections _collectionsmodule.c # Container types +_abc _abc.c # Abstract base classes +itertools itertoolsmodule.c # Functions creating iterators for efficient looping +atexit atexitmodule.c # Register functions to be run at interpreter-shutdown +_signal -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal signalmodule.c +_stat _stat.c # stat.h interface +time -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal timemodule.c # -lm # time operations and variables +_thread -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _threadmodule.c # low-level threading interface + +# access to ISO C locale support +_locale -DPy_BUILD_CORE_BUILTIN _localemodule.c # -lintl + +# Standard I/O baseline +_io -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c + +# faulthandler module +faulthandler faulthandler.c + +# debug tool to trace memory blocks allocated by Python +# +# bpo-35053: The module must be builtin since _Py_NewReference() +# can call _PyTraceMalloc_NewReference(). +_tracemalloc _tracemalloc.c hashtable.c + +# The rest of the modules listed in this file are all commented out by +# default. Usually they can be detected and built as dynamically +# loaded modules by the new setup.py script added in Python 2.1. If +# you're on a platform that doesn't support dynamic loading, want to +# compile modules statically into the Python binary, or need to +# specify some odd set of compiler switches, you can uncomment the +# appropriate lines below. + +# ====================================================================== + +# The Python symtable module depends on .h files that setup.py doesn't track +_symtable symtablemodule.c + +# Uncommenting the following line tells makesetup that all following +# modules are to be built as shared libraries (see above for more +# detail; also note that *static* or *disabled* cancels this effect): + +#*shared* + +# GNU readline. Unlike previous Python incarnations, GNU readline is +# now incorporated in an optional module, configured in the Setup file +# instead of by a configure script switch. You may have to insert a +# -L option pointing to the directory where libreadline.* lives, +# and you may have to change -ltermcap to -ltermlib or perhaps remove +# it, depending on your system -- see the GNU readline instructions. +# It's okay for this to be a shared library, too. + +#readline readline.c -lreadline -ltermcap + + +# Modules that should always be present (non UNIX dependent): + +#array arraymodule.c # array objects +#cmath cmathmodule.c _math.c # -lm # complex math library functions +#math mathmodule.c _math.c # -lm # math library functions, e.g. sin() +#_contextvars _contextvarsmodule.c # Context Variables +#_struct _struct.c # binary structure packing/unpacking +#_weakref _weakref.c # basic weak reference support +#_testcapi _testcapimodule.c # Python C API test module +#_testinternalcapi _testinternalcapi.c -I$(srcdir)/Include/internal -DPy_BUILD_CORE_MODULE # Python internal C API test module +#_random _randommodule.c # Random number generator +#_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator +#_pickle _pickle.c # pickle accelerator +#_datetime _datetimemodule.c # datetime accelerator +#_bisect _bisectmodule.c # Bisection algorithms +#_heapq _heapqmodule.c # Heap queue algorithm +#_asyncio _asynciomodule.c # Fast asyncio Future +#_json -I$(srcdir)/Include/internal -DPy_BUILD_CORE_BUILTIN _json.c # _json speedups +#_statistics _statisticsmodule.c # statistics accelerator + +#unicodedata unicodedata.c # static Unicode character database + + +# Modules with some UNIX dependencies -- on by default: +# (If you have a really backward UNIX, select and socket may not be +# supported...) + +#fcntl fcntlmodule.c # fcntl(2) and ioctl(2) +#spwd spwdmodule.c # spwd(3) +#grp grpmodule.c # grp(3) +#select selectmodule.c # select(2); not on ancient System V + +# Memory-mapped files (also works on Win32). +#mmap mmapmodule.c + +# CSV file helper +#_csv _csv.c + +# Socket module helper for socket(2) +#_socket socketmodule.c + +# Socket module helper for SSL support; you must comment out the other +# socket line above, and possibly edit the SSL variable: +#SSL=/usr/local/ssl +#_ssl _ssl.c \ +# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ +# -L$(SSL)/lib -lssl -lcrypto + +# The crypt module is now disabled by default because it breaks builds +# on many systems (where -lcrypt is needed), e.g. Linux (I believe). + +#_crypt _cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems + + +# Some more UNIX dependent modules -- off by default, since these +# are not supported by all UNIX systems: + +#nis nismodule.c -lnsl # Sun yellow pages -- not everywhere +#termios termios.c # Steen Lumholt's termios module +#resource resource.c # Jeremy Hylton's rlimit interface + +#_posixsubprocess _posixsubprocess.c # POSIX subprocess module helper + +# Multimedia modules -- off by default. +# These don't work for 64-bit platforms!!! +# #993173 says audioop works on 64-bit platforms, though. +# These represent audio samples or images as strings: + +#audioop audioop.c # Operations on audio samples + + +# Note that the _md5 and _sha modules are normally only built if the +# system does not have the OpenSSL libs containing an optimized version. + +# The _md5 module implements the RSA Data Security, Inc. MD5 +# Message-Digest Algorithm, described in RFC 1321. + +#_md5 md5module.c + + +# The _sha module implements the SHA checksum algorithms. +# (NIST's Secure Hash Algorithms.) +#_sha1 sha1module.c +#_sha256 sha256module.c +#_sha512 sha512module.c +#_sha3 _sha3/sha3module.c + +# _blake module +#_blake2 _blake2/blake2module.c _blake2/blake2b_impl.c _blake2/blake2s_impl.c + +# The _tkinter module. +# +# The command for _tkinter is long and site specific. Please +# uncomment and/or edit those parts as indicated. If you don't have a +# specific extension (e.g. Tix or BLT), leave the corresponding line +# commented out. (Leave the trailing backslashes in! If you +# experience strange errors, you may want to join all uncommented +# lines and remove the backslashes -- the backslash interpretation is +# done by the shell's "read" command and it may not be implemented on +# every system. + +# *** Always uncomment this (leave the leading underscore in!): +# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ +# *** Uncomment and edit to reflect where your Tcl/Tk libraries are: +# -L/usr/local/lib \ +# *** Uncomment and edit to reflect where your Tcl/Tk headers are: +# -I/usr/local/include \ +# *** Uncomment and edit to reflect where your X11 header files are: +# -I/usr/X11R6/include \ +# *** Or uncomment this for Solaris: +# -I/usr/openwin/include \ +# *** Uncomment and edit for Tix extension only: +# -DWITH_TIX -ltix8.1.8.2 \ +# *** Uncomment and edit for BLT extension only: +# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \ +# *** Uncomment and edit for PIL (TkImaging) extension only: +# (See http://www.pythonware.com/products/pil/ for more info) +# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ +# *** Uncomment and edit for TOGL extension only: +# -DWITH_TOGL togl.c \ +# *** Uncomment and edit to reflect your Tcl/Tk versions: +# -ltk8.2 -ltcl8.2 \ +# *** Uncomment and edit to reflect where your X11 libraries are: +# -L/usr/X11R6/lib \ +# *** Or uncomment this for Solaris: +# -L/usr/openwin/lib \ +# *** Uncomment these for TOGL extension only: +# -lGL -lGLU -lXext -lXmu \ +# *** Uncomment for AIX: +# -lld \ +# *** Always uncomment this; X11 libraries to link with: +# -lX11 + +# Lance Ellinghaus's syslog module +#syslog syslogmodule.c # syslog daemon interface + + +# Curses support, requiring the System V version of curses, often +# provided by the ncurses library. e.g. on Linux, link with -lncurses +# instead of -lcurses). + +#_curses _cursesmodule.c -lcurses -ltermcap +# Wrapper for the panel library that's part of ncurses and SYSV curses. +#_curses_panel _curses_panel.c -lpanel -lncurses + + +# Modules that provide persistent dictionary-like semantics. You will +# probably want to arrange for at least one of them to be available on +# your machine, though none are defined by default because of library +# dependencies. The Python module dbm/__init__.py provides an +# implementation independent wrapper for these; dbm/dumb.py provides +# similar functionality (but slower of course) implemented in Python. + +#_dbm _dbmmodule.c # dbm(3) may require -lndbm or similar + +# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: + +#_gdbm _gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm + + +# Helper module for various ascii-encoders +#binascii binascii.c + +# Fred Drake's interface to the Python parser +#parser parsermodule.c + + +# Andrew Kuchling's zlib module. +# This require zlib 1.1.3 (or later). +# See http://www.gzip.org/zlib/ +#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz + +# Interface to the Expat XML parser +# More information on Expat can be found at www.libexpat.org. +# +#pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DXML_POOR_ENTROPY -DUSE_PYEXPAT_CAPI + +# Hye-Shik Chang's CJKCodecs + +# multibytecodec is required for all the other CJK codec modules +#_multibytecodec cjkcodecs/multibytecodec.c + +#_codecs_cn cjkcodecs/_codecs_cn.c +#_codecs_hk cjkcodecs/_codecs_hk.c +#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c +#_codecs_jp cjkcodecs/_codecs_jp.c +#_codecs_kr cjkcodecs/_codecs_kr.c +#_codecs_tw cjkcodecs/_codecs_tw.c + +# Example -- included for reference only: +# xx xxmodule.c + +# Another example -- the 'xxsubtype' module shows C-level subtyping in action +xxsubtype xxsubtype.c + +# Uncommenting the following line tells makesetup that all following modules +# are not built (see above for more detail). +# +#*disabled* +# +#_sqlite3 _tkinter _curses pyexpat +#_codecs_jp _codecs_kr _codecs_tw unicodedata diff --git a/python/Modules/Setup.local b/python/Modules/Setup.local new file mode 100755 index 0000000..ca2983e --- /dev/null +++ b/python/Modules/Setup.local @@ -0,0 +1 @@ +# Edit this file for local setup changes diff --git a/python/Modules/_abc.c b/python/Modules/_abc.c new file mode 100755 index 0000000..de938dd --- /dev/null +++ b/python/Modules/_abc.c @@ -0,0 +1,832 @@ +/* ABCMeta implementation */ + +#include "Python.h" +#include "structmember.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__); + +/* A global counter that is incremented each time a class is + registered as a virtual subclass of anything. It forces the + negative cache to be cleared before its next use. + Note: this counter is private. Use `abc.get_cache_token()` for + external code. */ +static unsigned long long abc_invalidation_counter = 0; + +/* 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 void +abc_data_dealloc(_abc_data *self) +{ + Py_XDECREF(self->_abc_registry); + Py_XDECREF(self->_abc_cache); + Py_XDECREF(self->_abc_negative_cache); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + _abc_data *self = (_abc_data *) type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + + self->_abc_registry = NULL; + self->_abc_cache = NULL; + self->_abc_negative_cache = NULL; + self->_abc_negative_cache_version = abc_invalidation_counter; + return (PyObject *) self; +} + +PyDoc_STRVAR(abc_data_doc, +"Internal state held by ABC machinery."); + +static PyTypeObject _abc_data_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_abc_data", /*tp_name*/ + sizeof(_abc_data), /*tp_basicsize*/ + .tp_dealloc = (destructor)abc_data_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_alloc = PyType_GenericAlloc, + .tp_new = abc_data_new, +}; + +static _abc_data * +_get_impl(PyObject *self) +{ + PyObject *impl = _PyObject_GetAttrId(self, &PyId__abc_impl); + if (impl == NULL) { + return NULL; + } + if (Py_TYPE(impl) != &_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]*/ +{ + _abc_data *impl = _get_impl(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]*/ +{ + _abc_data *impl = _get_impl(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]*/ +{ + _abc_data *impl = _get_impl(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]*/ +{ + PyObject *data; + if (compute_abstract_methods(self) < 0) { + return NULL; + } + + /* Set up inheritance registry. */ + data = abc_data_new(&_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; + } + _abc_data *impl = _get_impl(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 */ + 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; + _abc_data *impl = _get_impl(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->_abc_negative_cache_version == 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. */ + result = _PyObject_CallMethodIdObjArgs(self, &PyId___subclasscheck__, + subclass, NULL); + goto end; + } + result = _PyObject_CallMethodIdObjArgs(self, &PyId___subclasscheck__, + subclass, NULL); + if (result == NULL) { + goto end; + } + + switch (PyObject_IsTrue(result)) { + case -1: + Py_DECREF(result); + result = NULL; + break; + case 0: + Py_DECREF(result); + result = _PyObject_CallMethodIdObjArgs(self, &PyId___subclasscheck__, + subtype, NULL); + 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; + Py_ssize_t pos; + int incache; + _abc_data *impl = _get_impl(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; + } + + /* 2. Check negative cache; may have to invalidate. */ + if (impl->_abc_negative_cache_version < abc_invalidation_counter) { + /* Invalidate the negative cache. */ + if (impl->_abc_negative_cache != NULL && + PySet_Clear(impl->_abc_negative_cache) < 0) + { + goto end; + } + impl->_abc_negative_cache_version = 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. */ + ok = _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId___subclasshook__, + subclass, NULL); + 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]*/ +{ + return PyLong_FromUnsignedLongLong(abc_invalidation_counter); +} + +static struct PyMethodDef module_functions[] = { + _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 struct PyModuleDef _abcmodule = { + PyModuleDef_HEAD_INIT, + "_abc", + _abc__doc__, + -1, + module_functions, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__abc(void) +{ + if (PyType_Ready(&_abc_data_type) < 0) { + return NULL; + } + _abc_data_type.tp_doc = abc_data_doc; + + return PyModule_Create(&_abcmodule); +} diff --git a/python/Modules/_asynciomodule.c b/python/Modules/_asynciomodule.c new file mode 100755 index 0000000..4ed2af5 --- /dev/null +++ b/python/Modules/_asynciomodule.c @@ -0,0 +1,3448 @@ +#include "Python.h" +#include "structmember.h" + + +/*[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(_all_tasks_compat); +_Py_IDENTIFIER(call_soon); +_Py_IDENTIFIER(cancel); +_Py_IDENTIFIER(current_task); +_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; + +/* 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; \ + fut_state prefix##_state; \ + int prefix##_log_tb; \ + int prefix##_blocking; \ + PyObject *dict; \ + PyObject *prefix##_weakreflist; + +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; + + +#define Future_CheckExact(obj) (Py_TYPE(obj) == &FutureType) +#define Task_CheckExact(obj) (Py_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. + */ + PyObject *res = PyObject_CallFunctionObjArgs( + asyncio_iscoroutine_func, coro, 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_CallNoArg(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(); + if (ts->id == cached_running_holder_tsid && cached_running_holder != NULL) { + // Fast path, check the cache. + rl = cached_running_holder; // borrowed + } + else { + if (ts->dict == NULL) { + 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 + cached_running_holder_tsid = ts->id; + } + + assert(Py_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 *ts_dict = PyThreadState_GetDict(); // 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); + + cached_running_holder = (PyObject *)rl; + + /* safe to assume state is not NULL as the call to PyThreadState_GetDict() + above already checks if state is NULL */ + cached_running_holder_tsid = PyThreadState_Get()->id; + + 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_CallNoArg(asyncio_get_event_loop_policy); + if (policy == NULL) { + return NULL; + } + + loop = _PyObject_CallMethodId(policy, &PyId_get_event_loop, NULL); + 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); + + 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_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL); + 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_CallNoArg(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)) { + exc_val = _PyObject_CallNoArg(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 ((PyObject*)Py_TYPE(exc_val) == 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; +} + +static int +future_get_result(FutureObj *fut, PyObject **result) +{ + if (fut->fut_state == STATE_CANCELLED) { + PyErr_SetNone(asyncio_CancelledError); + 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) +{ + fut->fut_log_tb = 0; + + if (fut->fut_state != STATE_PENDING) { + Py_RETURN_FALSE; + } + fut->fut_state = STATE_CANCELLED; + + 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->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->dict); + 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) { + PyErr_SetNone(asyncio_CancelledError); + 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(fn, self->fut_callback0, 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( + fn, PyTuple_GET_ITEM(cb_tup, 0), 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(fn, PyTuple_GET_ITEM(item, 0), 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_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 + +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) +/*[clinic end generated code: output=e45b932ba8bd68a1 input=515709a127995109]*/ +{ + ENSURE_FUTURE_ALIVE(self) + return future_cancel(self); +} + +/*[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_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._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_CallFunctionObjArgs( + asyncio_future_repr_info_func, self, NULL); +} + +static PyObject * +FutureObj_repr(FutureObj *fut) +{ + _Py_IDENTIFIER(_repr_info); + + ENSURE_FUTURE_ALIVE(fut) + + PyObject *rinfo = _PyObject_CallMethodIdObjArgs((PyObject*)fut, + &PyId__repr_info, + NULL); + 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_CallFunctionObjArgs(func, context, NULL); + 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 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__REPR_INFO_METHODDEF + {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}, + +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_CallMethodIdObjArgs( + all_tasks, &PyId_add, task, NULL); + if (res == NULL) { + return -1; + } + Py_DECREF(res); + return 0; +} + + +static int +unregister_task(PyObject *task) +{ + _Py_IDENTIFIER(discard); + + PyObject *res = _PyObject_CallMethodIdObjArgs( + all_tasks, &PyId_discard, task, NULL); + 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; + } +} + +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] +@classmethod +_asyncio.Task.current_task + + loop: object = None + +Return the currently running task in an event loop or None. + +By default the current task for the current event loop is returned. + +None is returned when called not in the context of a Task. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop) +/*[clinic end generated code: output=99fbe7332c516e03 input=cd14770c5b79c7eb]*/ +{ + PyObject *ret; + PyObject *current_task_func; + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Task.current_task() is deprecated, " \ + "use asyncio.current_task() instead", + 1) < 0) { + return NULL; + } + + current_task_func = _PyObject_GetAttrId(asyncio_mod, &PyId_current_task); + if (current_task_func == NULL) { + return NULL; + } + + if (loop == Py_None) { + loop = get_event_loop(); + if (loop == NULL) { + Py_DECREF(current_task_func); + return NULL; + } + ret = PyObject_CallFunctionObjArgs(current_task_func, loop, NULL); + Py_DECREF(current_task_func); + Py_DECREF(loop); + return ret; + } + else { + ret = PyObject_CallFunctionObjArgs(current_task_func, loop, NULL); + Py_DECREF(current_task_func); + return ret; + } +} + +/*[clinic input] +@classmethod +_asyncio.Task.all_tasks + + loop: object = None + +Return a set of all tasks for an event loop. + +By default all tasks for the current event loop are returned. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop) +/*[clinic end generated code: output=11f9b20749ccca5d input=497f80bc9ce726b5]*/ +{ + PyObject *res; + PyObject *all_tasks_func; + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Task.all_tasks() is deprecated, " \ + "use asyncio.all_tasks() instead", + 1) < 0) { + return NULL; + } + + all_tasks_func = _PyObject_GetAttrId(asyncio_mod, &PyId__all_tasks_compat); + if (all_tasks_func == NULL) { + return NULL; + } + + res = PyObject_CallFunctionObjArgs(all_tasks_func, loop, NULL); + Py_DECREF(all_tasks_func); + return res; +} + +/*[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_CallFunctionObjArgs( + asyncio_task_repr_info_func, self, NULL); +} + +/*[clinic input] +_asyncio.Task.cancel + +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) +/*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/ +{ + 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_CallMethodId( + self->task_fut_waiter, &PyId_cancel, NULL); + 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_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]*/ +{ + Py_INCREF(self->task_coro); + return self->task_coro; +} + +/*[clinic input] +_asyncio.Task.get_name +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_get_name_impl(TaskObj *self) +/*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/ +{ + if (self->task_name) { + Py_INCREF(self->task_name); + return self->task_name; + } + + Py_RETURN_NONE; +} + +/*[clinic input] +_asyncio.Task.set_name + + value: object + / +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_set_name(TaskObj *self, PyObject *value) +/*[clinic end generated code: output=138a8d51e32057d6 input=a8359b6e65f8fd31]*/ +{ + if (!PyUnicode_CheckExact(value)) { + value = PyObject_Str(value); + if (value == NULL) { + return NULL; + } + } else { + Py_INCREF(value); + } + + Py_XSETREF(self->task_name, 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) { + PyObject *res = PyObject_CallFunctionObjArgs(func, context, NULL); + 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 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_CURRENT_TASK_METHODDEF + _ASYNCIO_TASK_ALL_TASKS_METHODDEF + _ASYNCIO_TASK_CANCEL_METHODDEF + _ASYNCIO_TASK_GET_STACK_METHODDEF + _ASYNCIO_TASK_PRINT_STACK_METHODDEF + _ASYNCIO_TASK__REPR_INFO_METHODDEF + _ASYNCIO_TASK_GET_NAME_METHODDEF + _ASYNCIO_TASK_SET_NAME_METHODDEF + _ASYNCIO_TASK_GET_CORO_METHODDEF + {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; + } + + PyObject *e = PyObject_CallFunctionObjArgs(et, msg, NULL); + 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 = _PyObject_CallNoArg(asyncio_CancelledError); + 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 { + result = _PyObject_CallMethodIdObjArgs(coro, &PyId_send, + Py_None, NULL); + } + } + else { + result = _PyObject_CallMethodIdObjArgs(coro, &PyId_throw, + exc, NULL); + 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; + res = future_cancel((FutureObj*)task); + } + 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 */ + PyErr_Clear(); + return future_cancel((FutureObj*)task); + } + + /* 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; + } + + if (!fut->fut_blocking) { + goto yield_insteadof_yf; + } + + fut->fut_blocking = 0; + + /* result.add_done_callback(task._wakeup) */ + wrapper = TaskWakeupMethWrapper_new(task); + if (wrapper == NULL) { + goto fail; + } + res = future_add_done_callback( + (FutureObj*)result, wrapper, task->task_context); + Py_DECREF(wrapper); + if (res == NULL) { + 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; + r = _PyObject_CallMethodId(result, &PyId_cancel, NULL); + 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 */ + if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) { + goto fail; + } + if (o != NULL && o != Py_None) { + /* `result` is a Future-compatible object */ + PyObject *wrapper; + PyObject *res; + + int blocking = PyObject_IsTrue(o); + 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; + } + 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); + if (add_cb == NULL) { + Py_DECREF(wrapper); + goto fail; + } + PyObject *stack[2]; + stack[0] = wrapper; + stack[1] = (PyObject *)task->task_context; + res = _PyObject_Vectorcall(add_cb, stack, 1, context_kwname); + Py_DECREF(add_cb); + Py_DECREF(wrapper); + if (res == NULL) { + 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; + r = _PyObject_CallMethodId(result, &PyId_cancel, NULL); + 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 */ + res = PyObject_IsInstance(result, (PyObject*)&PyGen_Type); + if (res < 0) { + 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 { + 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_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; + + asyncio_mod = PyImport_ImportModule("asyncio"); + if (asyncio_mod == NULL) { + goto fail; + } + if (module_initialized != 0) { + return 0; + } + else { + module_initialized = 1; + } + + 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") + + 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"); + all_tasks = _PyObject_CallNoArg(weak_set); + Py_CLEAR(weak_set); + if (all_tasks == NULL) { + goto fail; + } + + 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(&FutureType) < 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(&TaskType) < 0) { + return NULL; + } + if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) { + return NULL; + } + + PyObject *m = PyModule_Create(&_asynciomodule); + if (m == NULL) { + return NULL; + } + + Py_INCREF(&FutureType); + if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) { + Py_DECREF(&FutureType); + Py_DECREF(m); + return NULL; + } + + Py_INCREF(&TaskType); + if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) { + Py_DECREF(&TaskType); + Py_DECREF(m); + 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); + Py_DECREF(m); + return NULL; + } + + return m; +} diff --git a/python/Modules/_bisectmodule.c b/python/Modules/_bisectmodule.c new file mode 100755 index 0000000..461a11f --- /dev/null +++ b/python/Modules/_bisectmodule.c @@ -0,0 +1,280 @@ +/* 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" + +_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; +} + +static PyObject * +bisect_right(PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *list, *item; + Py_ssize_t lo = 0; + Py_ssize_t hi = -1; + Py_ssize_t index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; + + if (kw == NULL && PyTuple_GET_SIZE(args) == 2) { + list = PyTuple_GET_ITEM(args, 0); + item = PyTuple_GET_ITEM(args, 1); + } + else { + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_right", + keywords, &list, &item, &lo, &hi)) + return NULL; + } + index = internal_bisect_right(list, item, lo, hi); + if (index < 0) + return NULL; + return PyLong_FromSsize_t(index); +} + +PyDoc_STRVAR(bisect_right_doc, +"bisect_right(a, x[, lo[, hi]]) -> index\n\ +\n\ +Return the index where to insert item x in list a, assuming a is sorted.\n\ +\n\ +The return value i is such that all e in a[:i] have e <= x, and all e in\n\ +a[i:] have e > x. So if x already appears in the list, i points just\n\ +beyond the rightmost x already there\n\ +\n\ +Optional args lo (default 0) and hi (default len(a)) bound the\n\ +slice of a to be searched.\n"); + +static PyObject * +insort_right(PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *list, *item, *result; + Py_ssize_t lo = 0; + Py_ssize_t hi = -1; + Py_ssize_t index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; + + if (kw == NULL && PyTuple_GET_SIZE(args) == 2) { + list = PyTuple_GET_ITEM(args, 0); + item = PyTuple_GET_ITEM(args, 1); + } + else { + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_right", + keywords, &list, &item, &lo, &hi)) + return NULL; + } + index = internal_bisect_right(list, item, lo, hi); + if (index < 0) + return NULL; + if (PyList_CheckExact(list)) { + if (PyList_Insert(list, index, item) < 0) + return NULL; + } + else { + result = _PyObject_CallMethodId(list, &PyId_insert, "nO", index, item); + if (result == NULL) + return NULL; + Py_DECREF(result); + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(insort_right_doc, +"insort_right(a, x[, lo[, hi]])\n\ +\n\ +Insert item x in list a, and keep it sorted assuming a is sorted.\n\ +\n\ +If x is already in a, insert it to the right of the rightmost x.\n\ +\n\ +Optional args lo (default 0) and hi (default len(a)) bound the\n\ +slice of a to be searched.\n"); + +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; +} + +static PyObject * +bisect_left(PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *list, *item; + Py_ssize_t lo = 0; + Py_ssize_t hi = -1; + Py_ssize_t index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; + + if (kw == NULL && PyTuple_GET_SIZE(args) == 2) { + list = PyTuple_GET_ITEM(args, 0); + item = PyTuple_GET_ITEM(args, 1); + } + else { + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:bisect_left", + keywords, &list, &item, &lo, &hi)) + return NULL; + } + index = internal_bisect_left(list, item, lo, hi); + if (index < 0) + return NULL; + return PyLong_FromSsize_t(index); +} + +PyDoc_STRVAR(bisect_left_doc, +"bisect_left(a, x[, lo[, hi]]) -> index\n\ +\n\ +Return the index where to insert item x in list a, assuming a is sorted.\n\ +\n\ +The return value i is such that all e in a[:i] have e < x, and all e in\n\ +a[i:] have e >= x. So if x already appears in the list, i points just\n\ +before the leftmost x already there.\n\ +\n\ +Optional args lo (default 0) and hi (default len(a)) bound the\n\ +slice of a to be searched.\n"); + +static PyObject * +insort_left(PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *list, *item, *result; + Py_ssize_t lo = 0; + Py_ssize_t hi = -1; + Py_ssize_t index; + static char *keywords[] = {"a", "x", "lo", "hi", NULL}; + + if (kw == NULL && PyTuple_GET_SIZE(args) == 2) { + list = PyTuple_GET_ITEM(args, 0); + item = PyTuple_GET_ITEM(args, 1); + } else { + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|nn:insort_left", + keywords, &list, &item, &lo, &hi)) + return NULL; + } + index = internal_bisect_left(list, item, lo, hi); + if (index < 0) + return NULL; + if (PyList_CheckExact(list)) { + if (PyList_Insert(list, index, item) < 0) + return NULL; + } else { + result = _PyObject_CallMethodId(list, &PyId_insert, "nO", index, item); + if (result == NULL) + return NULL; + Py_DECREF(result); + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(insort_left_doc, +"insort_left(a, x[, lo[, hi]])\n\ +\n\ +Insert item x in list a, and keep it sorted assuming a is sorted.\n\ +\n\ +If x is already in a, insert it to the left of the leftmost x.\n\ +\n\ +Optional args lo (default 0) and hi (default len(a)) bound the\n\ +slice of a to be searched.\n"); + +static PyMethodDef bisect_methods[] = { + {"bisect_right", (PyCFunction)(void(*)(void))bisect_right, + METH_VARARGS|METH_KEYWORDS, bisect_right_doc}, + {"insort_right", (PyCFunction)(void(*)(void))insort_right, + METH_VARARGS|METH_KEYWORDS, insort_right_doc}, + {"bisect_left", (PyCFunction)(void(*)(void))bisect_left, + METH_VARARGS|METH_KEYWORDS, bisect_left_doc}, + {"insort_left", (PyCFunction)(void(*)(void))insort_left, + METH_VARARGS|METH_KEYWORDS, insort_left_doc}, + {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/python/Modules/_blake2/blake2b2s.py b/python/Modules/_blake2/blake2b2s.py new file mode 100755 index 0000000..01cf265 --- /dev/null +++ b/python/Modules/_blake2/blake2b2s.py @@ -0,0 +1,49 @@ +#!/usr/bin/python3 + +import os +import re + +HERE = os.path.dirname(os.path.abspath(__file__)) +BLAKE2 = os.path.join(HERE, 'impl') + +PUBLIC_SEARCH = re.compile(r'\ int (blake2[bs]p?[a-z_]*)\(') + + +def getfiles(): + for name in os.listdir(BLAKE2): + name = os.path.join(BLAKE2, name) + if os.path.isfile(name): + yield name + + +def find_public(): + public_funcs = set() + for name in getfiles(): + with open(name) as f: + for line in f: + # find public functions + mo = PUBLIC_SEARCH.search(line) + if mo: + public_funcs.add(mo.group(1)) + + for f in sorted(public_funcs): + print('#define {0:<18} PyBlake2_{0}'.format(f)) + + return public_funcs + + +def main(): + lines = [] + with open(os.path.join(HERE, 'blake2b_impl.c')) as f: + for line in f: + line = line.replace('blake2b', 'blake2s') + line = line.replace('BLAKE2b', 'BLAKE2s') + line = line.replace('BLAKE2B', 'BLAKE2S') + lines.append(line) + with open(os.path.join(HERE, 'blake2s_impl.c'), 'w') as f: + f.write(''.join(lines)) + # find_public() + + +if __name__ == '__main__': + main() diff --git a/python/Modules/_blake2/blake2b_impl.c b/python/Modules/_blake2/blake2b_impl.c new file mode 100755 index 0000000..edab31e --- /dev/null +++ b/python/Modules/_blake2/blake2b_impl.c @@ -0,0 +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 "pythread.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 + +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) +/*[clinic end generated code: output=65e732c66c2297a0 input=82be35a4e6a9daa2]*/ +{ + 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 */ + 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 */ + 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/python/Modules/_blake2/blake2module.c b/python/Modules/_blake2/blake2module.c new file mode 100755 index 0000000..e2a3d42 --- /dev/null +++ b/python/Modules/_blake2/blake2module.c @@ -0,0 +1,105 @@ +/* + * 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_TYPE(&PyBlake2_BLAKE2bType) = &PyType_Type; + if (PyType_Ready(&PyBlake2_BLAKE2bType) < 0) { + return NULL; + } + + Py_INCREF(&PyBlake2_BLAKE2bType); + PyModule_AddObject(m, "blake2b", (PyObject *)&PyBlake2_BLAKE2bType); + + 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_TYPE(&PyBlake2_BLAKE2sType) = &PyType_Type; + if (PyType_Ready(&PyBlake2_BLAKE2sType) < 0) { + return NULL; + } + + Py_INCREF(&PyBlake2_BLAKE2sType); + PyModule_AddObject(m, "blake2s", (PyObject *)&PyBlake2_BLAKE2sType); + + 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/python/Modules/_blake2/blake2ns.h b/python/Modules/_blake2/blake2ns.h new file mode 100755 index 0000000..53bce8e --- /dev/null +++ b/python/Modules/_blake2/blake2ns.h @@ -0,0 +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 */ diff --git a/python/Modules/_blake2/blake2s_impl.c b/python/Modules/_blake2/blake2s_impl.c new file mode 100755 index 0000000..ef2f7e1 --- /dev/null +++ b/python/Modules/_blake2/blake2s_impl.c @@ -0,0 +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 "pythread.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 + +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) +/*[clinic end generated code: output=b95806be0514dcf7 input=641c0509debf714d]*/ +{ + 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 */ + 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 */ + 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/python/Modules/_blake2/clinic/blake2b_impl.c.h b/python/Modules/_blake2/clinic/blake2b_impl.c.h new file mode 100755 index 0000000..cd329c0 --- /dev/null +++ b/python/Modules/_blake2/clinic/blake2b_impl.c.h @@ -0,0 +1,264 @@ +/*[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" +"--\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); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "blake2b", 0}; + PyObject *argsbuf[12]; + 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; + unsigned long leaf_size = 0; + unsigned long long node_offset = 0; + int node_depth = 0; + int inner_size = 0; + int last_node = 0; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + noptargs--; + data = fastargs[0]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + digest_size = _PyLong_AsInt(fastargs[1]); + if (digest_size == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[2]) { + if (PyObject_GetBuffer(fastargs[2], &key, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&key, 'C')) { + _PyArg_BadArgument("blake2b", "argument 'key'", "contiguous buffer", fastargs[2]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + if (PyObject_GetBuffer(fastargs[3], &salt, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&salt, 'C')) { + _PyArg_BadArgument("blake2b", "argument 'salt'", "contiguous buffer", fastargs[3]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[4]) { + if (PyObject_GetBuffer(fastargs[4], &person, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&person, 'C')) { + _PyArg_BadArgument("blake2b", "argument 'person'", "contiguous buffer", fastargs[4]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[5]) { + if (PyFloat_Check(fastargs[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fanout = _PyLong_AsInt(fastargs[5]); + if (fanout == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[6]) { + if (PyFloat_Check(fastargs[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + depth = _PyLong_AsInt(fastargs[6]); + if (depth == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[7]) { + if (!_PyLong_UnsignedLong_Converter(fastargs[7], &leaf_size)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[8]) { + if (!_PyLong_UnsignedLongLong_Converter(fastargs[8], &node_offset)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[9]) { + if (PyFloat_Check(fastargs[9])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + node_depth = _PyLong_AsInt(fastargs[9]); + if (node_depth == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[10]) { + if (PyFloat_Check(fastargs[10])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + inner_size = _PyLong_AsInt(fastargs[10]); + if (inner_size == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + last_node = PyObject_IsTrue(fastargs[11]); + if (last_node < 0) { + goto exit; + } +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); + +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=cbb625d7f60c288c input=a9049054013a1b77]*/ diff --git a/python/Modules/_blake2/clinic/blake2s_impl.c.h b/python/Modules/_blake2/clinic/blake2s_impl.c.h new file mode 100755 index 0000000..560bd68 --- /dev/null +++ b/python/Modules/_blake2/clinic/blake2s_impl.c.h @@ -0,0 +1,264 @@ +/*[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" +"--\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); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "blake2s", 0}; + PyObject *argsbuf[12]; + 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; + unsigned long leaf_size = 0; + unsigned long long node_offset = 0; + int node_depth = 0; + int inner_size = 0; + int last_node = 0; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + noptargs--; + data = fastargs[0]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + digest_size = _PyLong_AsInt(fastargs[1]); + if (digest_size == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[2]) { + if (PyObject_GetBuffer(fastargs[2], &key, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&key, 'C')) { + _PyArg_BadArgument("blake2s", "argument 'key'", "contiguous buffer", fastargs[2]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + if (PyObject_GetBuffer(fastargs[3], &salt, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&salt, 'C')) { + _PyArg_BadArgument("blake2s", "argument 'salt'", "contiguous buffer", fastargs[3]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[4]) { + if (PyObject_GetBuffer(fastargs[4], &person, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&person, 'C')) { + _PyArg_BadArgument("blake2s", "argument 'person'", "contiguous buffer", fastargs[4]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[5]) { + if (PyFloat_Check(fastargs[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fanout = _PyLong_AsInt(fastargs[5]); + if (fanout == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[6]) { + if (PyFloat_Check(fastargs[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + depth = _PyLong_AsInt(fastargs[6]); + if (depth == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[7]) { + if (!_PyLong_UnsignedLong_Converter(fastargs[7], &leaf_size)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[8]) { + if (!_PyLong_UnsignedLongLong_Converter(fastargs[8], &node_offset)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[9]) { + if (PyFloat_Check(fastargs[9])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + node_depth = _PyLong_AsInt(fastargs[9]); + if (node_depth == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[10]) { + if (PyFloat_Check(fastargs[10])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + inner_size = _PyLong_AsInt(fastargs[10]); + if (inner_size == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + last_node = PyObject_IsTrue(fastargs[11]); + if (last_node < 0) { + goto exit; + } +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); + +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=39af5a74c8805b36 input=a9049054013a1b77]*/ diff --git a/python/Modules/_blake2/impl/blake2-config.h b/python/Modules/_blake2/impl/blake2-config.h new file mode 100755 index 0000000..f5dd6fa --- /dev/null +++ b/python/Modules/_blake2/impl/blake2-config.h @@ -0,0 +1,71 @@ +/* + 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__ + +#if defined(__SSE2__) +#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 +#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 + diff --git a/python/Modules/_blake2/impl/blake2-dispatch.c b/python/Modules/_blake2/impl/blake2-dispatch.c new file mode 100755 index 0000000..96bb340 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2-dispatch.c @@ -0,0 +1,577 @@ +/* + 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 . +*/ +#include +#if defined(WIN32) +#include +#endif +#include "blake2.h" + +#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64) +#define HAVE_X86 +#endif + +typedef enum +{ + NONE = 0, +#if defined(HAVE_X86) + SSE2 = 1, + SSSE3 = 2, + SSE41 = 3, + AVX = 4, + XOP = 5, + /* AVX2 = 6, */ +#endif +} cpu_feature_t; + +static const char feature_names[][8] = +{ + "none", +#if defined(HAVE_X86) + "sse2", + "ssse3", + "sse41", + "avx", + "xop", + /* "avx2" */ +#endif +}; + +#if defined(HAVE_X86) + +#if defined(__GNUC__) +static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) +{ + __asm__ __volatile__( +#if defined(__i386__) /* This is needed for -fPIC to work on i386 */ + "movl %%ebx, %%esi\n\t" +#endif + "cpuid\n\t" +#if defined(__i386__) + "xchgl %%ebx, %%esi\n\t" + : "=a"( *eax ), "=S"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); +#else + : "=a"( *eax ), "=b"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); +#endif +} + +static inline uint64_t xgetbv(uint32_t xcr) +{ + uint32_t a, d; + __asm__ __volatile__( + "xgetbv" + : "=a"(a),"=d"(d) + : "c"(xcr) + ); + return ((uint64_t)d << 32) | a; +} + +#elif defined(_MSC_VER) +#include +static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) +{ + int regs[4]; + __cpuid( regs, *eax ); + *eax = regs[0]; + *ebx = regs[1]; + *ecx = regs[2]; + *edx = regs[3]; +} +#else +#error "Don't know how to call cpuid on this compiler!" +#endif + +#endif /* HAVE_X86 */ + +static inline cpu_feature_t get_cpu_features( void ) +{ +#if defined(HAVE_X86) + static volatile int initialized = 0; + static cpu_feature_t feature = NONE; // Safe default + uint32_t eax, ecx, edx, ebx; + + if( initialized ) + return feature; + + eax = 1; + cpuid( &eax, &ebx, &ecx, &edx ); + + if( 1 & ( edx >> 26 ) ) + feature = SSE2; + + if( 1 & ( ecx >> 9 ) ) + feature = SSSE3; + + if( 1 & ( ecx >> 19 ) ) + feature = SSE41; + +#if defined(WIN32) /* Work around the fact that Windows <7 does NOT support AVX... */ + if( IsProcessorFeaturePresent(17) ) /* Some environments don't know about PF_XSAVE_ENABLED */ +#endif + { + /* check for AVX and OSXSAVE bits */ + if( 1 & ( ecx >> 28 ) & (ecx >> 27) ) { +#if !defined(WIN32) /* Already checked for this in WIN32 */ + if( (xgetbv(0) & 6) == 6 ) /* XCR0 */ +#endif + feature = AVX; + } + + + eax = 0x80000001; + cpuid( &eax, &ebx, &ecx, &edx ); + + if( 1 & ( ecx >> 11 ) ) + feature = XOP; + } + + /* For future architectures */ + /* + eax = 7; ecx = 0; + cpuid(&eax, &ebx, &ecx, &edx); + + if(1&(ebx >> 5)) + feature = AVX2; + */ + /* fprintf( stderr, "Using %s engine\n", feature_names[feature] ); */ + initialized = 1; + return feature; +#else + return NONE; +#endif +} + + + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init_ref( blake2b_state *S, size_t outlen ); + int blake2b_init_key_ref( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_ref( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_ref( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_ref( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#if defined(HAVE_X86) + + int blake2b_init_sse2( blake2b_state *S, size_t outlen ); + int blake2b_init_key_sse2( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_sse2( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_sse2( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_sse2( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_ssse3( blake2b_state *S, size_t outlen ); + int blake2b_init_key_ssse3( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_ssse3( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_ssse3( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_ssse3( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_sse41( blake2b_state *S, size_t outlen ); + int blake2b_init_key_sse41( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_sse41( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_sse41( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_sse41( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_avx( blake2b_state *S, size_t outlen ); + int blake2b_init_key_avx( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_avx( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_avx( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_avx( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_xop( blake2b_state *S, size_t outlen ); + int blake2b_init_key_xop( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_xop( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_xop( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_xop( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#endif /* HAVE_X86 */ + + int blake2s_init_ref( blake2s_state *S, size_t outlen ); + int blake2s_init_key_ref( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_ref( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_ref( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_ref( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#if defined(HAVE_X86) + + int blake2s_init_sse2( blake2s_state *S, size_t outlen ); + int blake2s_init_key_sse2( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_sse2( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_sse2( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_sse2( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_ssse3( blake2s_state *S, size_t outlen ); + int blake2s_init_key_ssse3( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_ssse3( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_ssse3( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_ssse3( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_sse41( blake2s_state *S, size_t outlen ); + int blake2s_init_key_sse41( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_sse41( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_sse41( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_sse41( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_avx( blake2s_state *S, size_t outlen ); + int blake2s_init_key_avx( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_avx( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_avx( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_avx( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_xop( blake2s_state *S, size_t outlen ); + int blake2s_init_key_xop( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_xop( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_xop( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_xop( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#endif /* HAVE_X86 */ + +#if defined(__cplusplus) +} +#endif + +typedef int ( *blake2b_init_fn )( blake2b_state *, size_t ); +typedef int ( *blake2b_init_key_fn )( blake2b_state *, size_t, const void *, size_t ); +typedef int ( *blake2b_init_param_fn )( blake2b_state *, const blake2b_param * ); +typedef int ( *blake2b_update_fn )( blake2b_state *, const uint8_t *, size_t ); +typedef int ( *blake2b_final_fn )( blake2b_state *, uint8_t *, size_t ); +typedef int ( *blake2b_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); + +typedef int ( *blake2s_init_fn )( blake2s_state *, size_t ); +typedef int ( *blake2s_init_key_fn )( blake2s_state *, size_t, const void *, size_t ); +typedef int ( *blake2s_init_param_fn )( blake2s_state *, const blake2s_param * ); +typedef int ( *blake2s_update_fn )( blake2s_state *, const uint8_t *, size_t ); +typedef int ( *blake2s_final_fn )( blake2s_state *, uint8_t *, size_t ); +typedef int ( *blake2s_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); + +static const blake2b_init_fn blake2b_init_table[] = +{ + blake2b_init_ref, +#if defined(HAVE_X86) + blake2b_init_sse2, + blake2b_init_ssse3, + blake2b_init_sse41, + blake2b_init_avx, + blake2b_init_xop +#endif +}; + +static const blake2b_init_key_fn blake2b_init_key_table[] = +{ + blake2b_init_key_ref, +#if defined(HAVE_X86) + blake2b_init_key_sse2, + blake2b_init_key_ssse3, + blake2b_init_key_sse41, + blake2b_init_key_avx, + blake2b_init_key_xop +#endif +}; + +static const blake2b_init_param_fn blake2b_init_param_table[] = +{ + blake2b_init_param_ref, +#if defined(HAVE_X86) + blake2b_init_param_sse2, + blake2b_init_param_ssse3, + blake2b_init_param_sse41, + blake2b_init_param_avx, + blake2b_init_param_xop +#endif +}; + +static const blake2b_update_fn blake2b_update_table[] = +{ + blake2b_update_ref, +#if defined(HAVE_X86) + blake2b_update_sse2, + blake2b_update_ssse3, + blake2b_update_sse41, + blake2b_update_avx, + blake2b_update_xop +#endif +}; + +static const blake2b_final_fn blake2b_final_table[] = +{ + blake2b_final_ref, +#if defined(HAVE_X86) + blake2b_final_sse2, + blake2b_final_ssse3, + blake2b_final_sse41, + blake2b_final_avx, + blake2b_final_xop +#endif +}; + +static const blake2b_fn blake2b_table[] = +{ + blake2b_ref, +#if defined(HAVE_X86) + blake2b_sse2, + blake2b_ssse3, + blake2b_sse41, + blake2b_avx, + blake2b_xop +#endif +}; + +static const blake2s_init_fn blake2s_init_table[] = +{ + blake2s_init_ref, +#if defined(HAVE_X86) + blake2s_init_sse2, + blake2s_init_ssse3, + blake2s_init_sse41, + blake2s_init_avx, + blake2s_init_xop +#endif +}; + +static const blake2s_init_key_fn blake2s_init_key_table[] = +{ + blake2s_init_key_ref, +#if defined(HAVE_X86) + blake2s_init_key_sse2, + blake2s_init_key_ssse3, + blake2s_init_key_sse41, + blake2s_init_key_avx, + blake2s_init_key_xop +#endif +}; + +static const blake2s_init_param_fn blake2s_init_param_table[] = +{ + blake2s_init_param_ref, +#if defined(HAVE_X86) + blake2s_init_param_sse2, + blake2s_init_param_ssse3, + blake2s_init_param_sse41, + blake2s_init_param_avx, + blake2s_init_param_xop +#endif +}; + +static const blake2s_update_fn blake2s_update_table[] = +{ + blake2s_update_ref, +#if defined(HAVE_X86) + blake2s_update_sse2, + blake2s_update_ssse3, + blake2s_update_sse41, + blake2s_update_avx, + blake2s_update_xop +#endif +}; + +static const blake2s_final_fn blake2s_final_table[] = +{ + blake2s_final_ref, +#if defined(HAVE_X86) + blake2s_final_sse2, + blake2s_final_ssse3, + blake2s_final_sse41, + blake2s_final_avx, + blake2s_final_xop +#endif +}; + +static const blake2s_fn blake2s_table[] = +{ + blake2s_ref, +#if defined(HAVE_X86) + blake2s_sse2, + blake2s_ssse3, + blake2s_sse41, + blake2s_avx, + blake2s_xop +#endif +}; + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init_dispatch( blake2b_state *S, size_t outlen ); + int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_dispatch( blake2s_state *S, size_t outlen ); + int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + +static blake2b_init_fn blake2b_init_ptr = blake2b_init_dispatch; +static blake2b_init_key_fn blake2b_init_key_ptr = blake2b_init_key_dispatch; +static blake2b_init_param_fn blake2b_init_param_ptr = blake2b_init_param_dispatch; +static blake2b_update_fn blake2b_update_ptr = blake2b_update_dispatch; +static blake2b_final_fn blake2b_final_ptr = blake2b_final_dispatch; +static blake2b_fn blake2b_ptr = blake2b_dispatch; + +static blake2s_init_fn blake2s_init_ptr = blake2s_init_dispatch; +static blake2s_init_key_fn blake2s_init_key_ptr = blake2s_init_key_dispatch; +static blake2s_init_param_fn blake2s_init_param_ptr = blake2s_init_param_dispatch; +static blake2s_update_fn blake2s_update_ptr = blake2s_update_dispatch; +static blake2s_final_fn blake2s_final_ptr = blake2s_final_dispatch; +static blake2s_fn blake2s_ptr = blake2s_dispatch; + +int blake2b_init_dispatch( blake2b_state *S, size_t outlen ) +{ + blake2b_init_ptr = blake2b_init_table[get_cpu_features()]; + return blake2b_init_ptr( S, outlen ); +} + +int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2b_init_key_ptr = blake2b_init_key_table[get_cpu_features()]; + return blake2b_init_key_ptr( S, outlen, key, keylen ); +} + +int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ) +{ + blake2b_init_param_ptr = blake2b_init_param_table[get_cpu_features()]; + return blake2b_init_param_ptr( S, P ); +} + +int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ) +{ + blake2b_update_ptr = blake2b_update_table[get_cpu_features()]; + return blake2b_update_ptr( S, in, inlen ); +} + +int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ) +{ + blake2b_final_ptr = blake2b_final_table[get_cpu_features()]; + return blake2b_final_ptr( S, out, outlen ); +} + +int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + blake2b_ptr = blake2b_table[get_cpu_features()]; + return blake2b_ptr( out, in, key, outlen, inlen, keylen ); +} + +BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen ) +{ + return blake2b_init_ptr( S, outlen ); +} + +BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) +{ + return blake2b_init_key_ptr( S, outlen, key, keylen ); +} + +BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + return blake2b_init_param_ptr( S, P ); +} + +BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) +{ + return blake2b_update_ptr( S, in, inlen ); +} + +BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) +{ + return blake2b_final_ptr( S, out, outlen ); +} + +BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + return blake2b_ptr( out, in, key, outlen, inlen, keylen ); +} + +int blake2s_init_dispatch( blake2s_state *S, size_t outlen ) +{ + blake2s_init_ptr = blake2s_init_table[get_cpu_features()]; + return blake2s_init_ptr( S, outlen ); +} + +int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2s_init_key_ptr = blake2s_init_key_table[get_cpu_features()]; + return blake2s_init_key_ptr( S, outlen, key, keylen ); +} + +int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ) +{ + blake2s_init_param_ptr = blake2s_init_param_table[get_cpu_features()]; + return blake2s_init_param_ptr( S, P ); +} + +int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ) +{ + blake2s_update_ptr = blake2s_update_table[get_cpu_features()]; + return blake2s_update_ptr( S, in, inlen ); +} + +int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ) +{ + blake2s_final_ptr = blake2s_final_table[get_cpu_features()]; + return blake2s_final_ptr( S, out, outlen ); +} + +int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + blake2s_ptr = blake2s_table[get_cpu_features()]; + return blake2s_ptr( out, in, key, outlen, inlen, keylen ); +} + +BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen ) +{ + return blake2s_init_ptr( S, outlen ); +} + +BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) +{ + return blake2s_init_key_ptr( S, outlen, key, keylen ); +} + +BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + return blake2s_init_param_ptr( S, P ); +} + +BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) +{ + return blake2s_update_ptr( S, in, inlen ); +} + +BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) +{ + return blake2s_final_ptr( S, out, outlen ); +} + +BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + return blake2s_ptr( out, in, key, outlen, inlen, keylen ); +} + diff --git a/python/Modules/_blake2/impl/blake2-impl.h b/python/Modules/_blake2/impl/blake2-impl.h new file mode 100755 index 0000000..9d2fbb7 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2-impl.h @@ -0,0 +1,162 @@ +/* + 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_IMPL_H__ +#define __BLAKE2_IMPL_H__ + +#if defined(_WIN32) || defined(WIN32) +#include +#endif + +#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; + memcpy( &w, src, sizeof( w ) ); + 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 +} + +static inline uint64_t load64( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; + memcpy( &w, src, sizeof( w ) ); + 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 +} + +static inline void store32( void *dst, uint32_t w ) +{ +#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 +} + +static inline void store64( void *dst, uint64_t w ) +{ +#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 +} + +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; +} + +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; +} + +static inline uint32_t rotl32( const uint32_t w, const unsigned 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 ) ); +} + +static inline uint32_t rotr32( const uint32_t w, const unsigned 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() */ +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); +#else +// prioritize first the general C11 call +#if defined(HAVE_MEMSET_S) + memset_s(v, n, 0, n); +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(v, n); +#elif defined(HAVE_EXPLICIT_MEMSET) + explicit_memset(v, 0, n); +#else + memset(v, 0, n); + __asm__ __volatile__("" :: "r"(v) : "memory"); +#endif +#endif +} + +#endif + diff --git a/python/Modules/_blake2/impl/blake2-kat.h b/python/Modules/_blake2/impl/blake2-kat.h new file mode 100755 index 0000000..3d20727 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2-kat.h @@ -0,0 +1,16467 @@ +/* + 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_KAT_H__ +#define __BLAKE2_KAT_H__ + + +#include + +#define KAT_LENGTH 256 + + + +static const uint8_t blake2s_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0x69, 0x21, 0x7A, 0x30, 0x79, 0x90, 0x80, 0x94, + 0xE1, 0x11, 0x21, 0xD0, 0x42, 0x35, 0x4A, 0x7C, + 0x1F, 0x55, 0xB6, 0x48, 0x2C, 0xA1, 0xA5, 0x1E, + 0x1B, 0x25, 0x0D, 0xFD, 0x1E, 0xD0, 0xEE, 0xF9 + }, + { + 0xE3, 0x4D, 0x74, 0xDB, 0xAF, 0x4F, 0xF4, 0xC6, + 0xAB, 0xD8, 0x71, 0xCC, 0x22, 0x04, 0x51, 0xD2, + 0xEA, 0x26, 0x48, 0x84, 0x6C, 0x77, 0x57, 0xFB, + 0xAA, 0xC8, 0x2F, 0xE5, 0x1A, 0xD6, 0x4B, 0xEA + }, + { + 0xDD, 0xAD, 0x9A, 0xB1, 0x5D, 0xAC, 0x45, 0x49, + 0xBA, 0x42, 0xF4, 0x9D, 0x26, 0x24, 0x96, 0xBE, + 0xF6, 0xC0, 0xBA, 0xE1, 0xDD, 0x34, 0x2A, 0x88, + 0x08, 0xF8, 0xEA, 0x26, 0x7C, 0x6E, 0x21, 0x0C + }, + { + 0xE8, 0xF9, 0x1C, 0x6E, 0xF2, 0x32, 0xA0, 0x41, + 0x45, 0x2A, 0xB0, 0xE1, 0x49, 0x07, 0x0C, 0xDD, + 0x7D, 0xD1, 0x76, 0x9E, 0x75, 0xB3, 0xA5, 0x92, + 0x1B, 0xE3, 0x78, 0x76, 0xC4, 0x5C, 0x99, 0x00 + }, + { + 0x0C, 0xC7, 0x0E, 0x00, 0x34, 0x8B, 0x86, 0xBA, + 0x29, 0x44, 0xD0, 0xC3, 0x20, 0x38, 0xB2, 0x5C, + 0x55, 0x58, 0x4F, 0x90, 0xDF, 0x23, 0x04, 0xF5, + 0x5F, 0xA3, 0x32, 0xAF, 0x5F, 0xB0, 0x1E, 0x20 + }, + { + 0xEC, 0x19, 0x64, 0x19, 0x10, 0x87, 0xA4, 0xFE, + 0x9D, 0xF1, 0xC7, 0x95, 0x34, 0x2A, 0x02, 0xFF, + 0xC1, 0x91, 0xA5, 0xB2, 0x51, 0x76, 0x48, 0x56, + 0xAE, 0x5B, 0x8B, 0x57, 0x69, 0xF0, 0xC6, 0xCD + }, + { + 0xE1, 0xFA, 0x51, 0x61, 0x8D, 0x7D, 0xF4, 0xEB, + 0x70, 0xCF, 0x0D, 0x5A, 0x9E, 0x90, 0x6F, 0x80, + 0x6E, 0x9D, 0x19, 0xF7, 0xF4, 0xF0, 0x1E, 0x3B, + 0x62, 0x12, 0x88, 0xE4, 0x12, 0x04, 0x05, 0xD6 + }, + { + 0x59, 0x80, 0x01, 0xFA, 0xFB, 0xE8, 0xF9, 0x4E, + 0xC6, 0x6D, 0xC8, 0x27, 0xD0, 0x12, 0xCF, 0xCB, + 0xBA, 0x22, 0x28, 0x56, 0x9F, 0x44, 0x8E, 0x89, + 0xEA, 0x22, 0x08, 0xC8, 0xBF, 0x76, 0x92, 0x93 + }, + { + 0xC7, 0xE8, 0x87, 0xB5, 0x46, 0x62, 0x36, 0x35, + 0xE9, 0x3E, 0x04, 0x95, 0x59, 0x8F, 0x17, 0x26, + 0x82, 0x19, 0x96, 0xC2, 0x37, 0x77, 0x05, 0xB9, + 0x3A, 0x1F, 0x63, 0x6F, 0x87, 0x2B, 0xFA, 0x2D + }, + { + 0xC3, 0x15, 0xA4, 0x37, 0xDD, 0x28, 0x06, 0x2A, + 0x77, 0x0D, 0x48, 0x19, 0x67, 0x13, 0x6B, 0x1B, + 0x5E, 0xB8, 0x8B, 0x21, 0xEE, 0x53, 0xD0, 0x32, + 0x9C, 0x58, 0x97, 0x12, 0x6E, 0x9D, 0xB0, 0x2C + }, + { + 0xBB, 0x47, 0x3D, 0xED, 0xDC, 0x05, 0x5F, 0xEA, + 0x62, 0x28, 0xF2, 0x07, 0xDA, 0x57, 0x53, 0x47, + 0xBB, 0x00, 0x40, 0x4C, 0xD3, 0x49, 0xD3, 0x8C, + 0x18, 0x02, 0x63, 0x07, 0xA2, 0x24, 0xCB, 0xFF + }, + { + 0x68, 0x7E, 0x18, 0x73, 0xA8, 0x27, 0x75, 0x91, + 0xBB, 0x33, 0xD9, 0xAD, 0xF9, 0xA1, 0x39, 0x12, + 0xEF, 0xEF, 0xE5, 0x57, 0xCA, 0xFC, 0x39, 0xA7, + 0x95, 0x26, 0x23, 0xE4, 0x72, 0x55, 0xF1, 0x6D + }, + { + 0x1A, 0xC7, 0xBA, 0x75, 0x4D, 0x6E, 0x2F, 0x94, + 0xE0, 0xE8, 0x6C, 0x46, 0xBF, 0xB2, 0x62, 0xAB, + 0xBB, 0x74, 0xF4, 0x50, 0xEF, 0x45, 0x6D, 0x6B, + 0x4D, 0x97, 0xAA, 0x80, 0xCE, 0x6D, 0xA7, 0x67 + }, + { + 0x01, 0x2C, 0x97, 0x80, 0x96, 0x14, 0x81, 0x6B, + 0x5D, 0x94, 0x94, 0x47, 0x7D, 0x4B, 0x68, 0x7D, + 0x15, 0xB9, 0x6E, 0xB6, 0x9C, 0x0E, 0x80, 0x74, + 0xA8, 0x51, 0x6F, 0x31, 0x22, 0x4B, 0x5C, 0x98 + }, + { + 0x91, 0xFF, 0xD2, 0x6C, 0xFA, 0x4D, 0xA5, 0x13, + 0x4C, 0x7E, 0xA2, 0x62, 0xF7, 0x88, 0x9C, 0x32, + 0x9F, 0x61, 0xF6, 0xA6, 0x57, 0x22, 0x5C, 0xC2, + 0x12, 0xF4, 0x00, 0x56, 0xD9, 0x86, 0xB3, 0xF4 + }, + { + 0xD9, 0x7C, 0x82, 0x8D, 0x81, 0x82, 0xA7, 0x21, + 0x80, 0xA0, 0x6A, 0x78, 0x26, 0x83, 0x30, 0x67, + 0x3F, 0x7C, 0x4E, 0x06, 0x35, 0x94, 0x7C, 0x04, + 0xC0, 0x23, 0x23, 0xFD, 0x45, 0xC0, 0xA5, 0x2D + }, + { + 0xEF, 0xC0, 0x4C, 0xDC, 0x39, 0x1C, 0x7E, 0x91, + 0x19, 0xBD, 0x38, 0x66, 0x8A, 0x53, 0x4E, 0x65, + 0xFE, 0x31, 0x03, 0x6D, 0x6A, 0x62, 0x11, 0x2E, + 0x44, 0xEB, 0xEB, 0x11, 0xF9, 0xC5, 0x70, 0x80 + }, + { + 0x99, 0x2C, 0xF5, 0xC0, 0x53, 0x44, 0x2A, 0x5F, + 0xBC, 0x4F, 0xAF, 0x58, 0x3E, 0x04, 0xE5, 0x0B, + 0xB7, 0x0D, 0x2F, 0x39, 0xFB, 0xB6, 0xA5, 0x03, + 0xF8, 0x9E, 0x56, 0xA6, 0x3E, 0x18, 0x57, 0x8A + }, + { + 0x38, 0x64, 0x0E, 0x9F, 0x21, 0x98, 0x3E, 0x67, + 0xB5, 0x39, 0xCA, 0xCC, 0xAE, 0x5E, 0xCF, 0x61, + 0x5A, 0xE2, 0x76, 0x4F, 0x75, 0xA0, 0x9C, 0x9C, + 0x59, 0xB7, 0x64, 0x83, 0xC1, 0xFB, 0xC7, 0x35 + }, + { + 0x21, 0x3D, 0xD3, 0x4C, 0x7E, 0xFE, 0x4F, 0xB2, + 0x7A, 0x6B, 0x35, 0xF6, 0xB4, 0x00, 0x0D, 0x1F, + 0xE0, 0x32, 0x81, 0xAF, 0x3C, 0x72, 0x3E, 0x5C, + 0x9F, 0x94, 0x74, 0x7A, 0x5F, 0x31, 0xCD, 0x3B + }, + { + 0xEC, 0x24, 0x6E, 0xEE, 0xB9, 0xCE, 0xD3, 0xF7, + 0xAD, 0x33, 0xED, 0x28, 0x66, 0x0D, 0xD9, 0xBB, + 0x07, 0x32, 0x51, 0x3D, 0xB4, 0xE2, 0xFA, 0x27, + 0x8B, 0x60, 0xCD, 0xE3, 0x68, 0x2A, 0x4C, 0xCD + }, + { + 0xAC, 0x9B, 0x61, 0xD4, 0x46, 0x64, 0x8C, 0x30, + 0x05, 0xD7, 0x89, 0x2B, 0xF3, 0xA8, 0x71, 0x9F, + 0x4C, 0x81, 0x81, 0xCF, 0xDC, 0xBC, 0x2B, 0x79, + 0xFE, 0xF1, 0x0A, 0x27, 0x9B, 0x91, 0x10, 0x95 + }, + { + 0x7B, 0xF8, 0xB2, 0x29, 0x59, 0xE3, 0x4E, 0x3A, + 0x43, 0xF7, 0x07, 0x92, 0x23, 0xE8, 0x3A, 0x97, + 0x54, 0x61, 0x7D, 0x39, 0x1E, 0x21, 0x3D, 0xFD, + 0x80, 0x8E, 0x41, 0xB9, 0xBE, 0xAD, 0x4C, 0xE7 + }, + { + 0x68, 0xD4, 0xB5, 0xD4, 0xFA, 0x0E, 0x30, 0x2B, + 0x64, 0xCC, 0xC5, 0xAF, 0x79, 0x29, 0x13, 0xAC, + 0x4C, 0x88, 0xEC, 0x95, 0xC0, 0x7D, 0xDF, 0x40, + 0x69, 0x42, 0x56, 0xEB, 0x88, 0xCE, 0x9F, 0x3D + }, + { + 0xB2, 0xC2, 0x42, 0x0F, 0x05, 0xF9, 0xAB, 0xE3, + 0x63, 0x15, 0x91, 0x93, 0x36, 0xB3, 0x7E, 0x4E, + 0x0F, 0xA3, 0x3F, 0xF7, 0xE7, 0x6A, 0x49, 0x27, + 0x67, 0x00, 0x6F, 0xDB, 0x5D, 0x93, 0x54, 0x62 + }, + { + 0x13, 0x4F, 0x61, 0xBB, 0xD0, 0xBB, 0xB6, 0x9A, + 0xED, 0x53, 0x43, 0x90, 0x45, 0x51, 0xA3, 0xE6, + 0xC1, 0xAA, 0x7D, 0xCD, 0xD7, 0x7E, 0x90, 0x3E, + 0x70, 0x23, 0xEB, 0x7C, 0x60, 0x32, 0x0A, 0xA7 + }, + { + 0x46, 0x93, 0xF9, 0xBF, 0xF7, 0xD4, 0xF3, 0x98, + 0x6A, 0x7D, 0x17, 0x6E, 0x6E, 0x06, 0xF7, 0x2A, + 0xD1, 0x49, 0x0D, 0x80, 0x5C, 0x99, 0xE2, 0x53, + 0x47, 0xB8, 0xDE, 0x77, 0xB4, 0xDB, 0x6D, 0x9B + }, + { + 0x85, 0x3E, 0x26, 0xF7, 0x41, 0x95, 0x3B, 0x0F, + 0xD5, 0xBD, 0xB4, 0x24, 0xE8, 0xAB, 0x9E, 0x8B, + 0x37, 0x50, 0xEA, 0xA8, 0xEF, 0x61, 0xE4, 0x79, + 0x02, 0xC9, 0x1E, 0x55, 0x4E, 0x9C, 0x73, 0xB9 + }, + { + 0xF7, 0xDE, 0x53, 0x63, 0x61, 0xAB, 0xAA, 0x0E, + 0x15, 0x81, 0x56, 0xCF, 0x0E, 0xA4, 0xF6, 0x3A, + 0x99, 0xB5, 0xE4, 0x05, 0x4F, 0x8F, 0xA4, 0xC9, + 0xD4, 0x5F, 0x62, 0x85, 0xCA, 0xD5, 0x56, 0x94 + }, + { + 0x4C, 0x23, 0x06, 0x08, 0x86, 0x0A, 0x99, 0xAE, + 0x8D, 0x7B, 0xD5, 0xC2, 0xCC, 0x17, 0xFA, 0x52, + 0x09, 0x6B, 0x9A, 0x61, 0xBE, 0xDB, 0x17, 0xCB, + 0x76, 0x17, 0x86, 0x4A, 0xD2, 0x9C, 0xA7, 0xA6 + }, + { + 0xAE, 0xB9, 0x20, 0xEA, 0x87, 0x95, 0x2D, 0xAD, + 0xB1, 0xFB, 0x75, 0x92, 0x91, 0xE3, 0x38, 0x81, + 0x39, 0xA8, 0x72, 0x86, 0x50, 0x01, 0x88, 0x6E, + 0xD8, 0x47, 0x52, 0xE9, 0x3C, 0x25, 0x0C, 0x2A + }, + { + 0xAB, 0xA4, 0xAD, 0x9B, 0x48, 0x0B, 0x9D, 0xF3, + 0xD0, 0x8C, 0xA5, 0xE8, 0x7B, 0x0C, 0x24, 0x40, + 0xD4, 0xE4, 0xEA, 0x21, 0x22, 0x4C, 0x2E, 0xB4, + 0x2C, 0xBA, 0xE4, 0x69, 0xD0, 0x89, 0xB9, 0x31 + }, + { + 0x05, 0x82, 0x56, 0x07, 0xD7, 0xFD, 0xF2, 0xD8, + 0x2E, 0xF4, 0xC3, 0xC8, 0xC2, 0xAE, 0xA9, 0x61, + 0xAD, 0x98, 0xD6, 0x0E, 0xDF, 0xF7, 0xD0, 0x18, + 0x98, 0x3E, 0x21, 0x20, 0x4C, 0x0D, 0x93, 0xD1 + }, + { + 0xA7, 0x42, 0xF8, 0xB6, 0xAF, 0x82, 0xD8, 0xA6, + 0xCA, 0x23, 0x57, 0xC5, 0xF1, 0xCF, 0x91, 0xDE, + 0xFB, 0xD0, 0x66, 0x26, 0x7D, 0x75, 0xC0, 0x48, + 0xB3, 0x52, 0x36, 0x65, 0x85, 0x02, 0x59, 0x62 + }, + { + 0x2B, 0xCA, 0xC8, 0x95, 0x99, 0x00, 0x0B, 0x42, + 0xC9, 0x5A, 0xE2, 0x38, 0x35, 0xA7, 0x13, 0x70, + 0x4E, 0xD7, 0x97, 0x89, 0xC8, 0x4F, 0xEF, 0x14, + 0x9A, 0x87, 0x4F, 0xF7, 0x33, 0xF0, 0x17, 0xA2 + }, + { + 0xAC, 0x1E, 0xD0, 0x7D, 0x04, 0x8F, 0x10, 0x5A, + 0x9E, 0x5B, 0x7A, 0xB8, 0x5B, 0x09, 0xA4, 0x92, + 0xD5, 0xBA, 0xFF, 0x14, 0xB8, 0xBF, 0xB0, 0xE9, + 0xFD, 0x78, 0x94, 0x86, 0xEE, 0xA2, 0xB9, 0x74 + }, + { + 0xE4, 0x8D, 0x0E, 0xCF, 0xAF, 0x49, 0x7D, 0x5B, + 0x27, 0xC2, 0x5D, 0x99, 0xE1, 0x56, 0xCB, 0x05, + 0x79, 0xD4, 0x40, 0xD6, 0xE3, 0x1F, 0xB6, 0x24, + 0x73, 0x69, 0x6D, 0xBF, 0x95, 0xE0, 0x10, 0xE4 + }, + { + 0x12, 0xA9, 0x1F, 0xAD, 0xF8, 0xB2, 0x16, 0x44, + 0xFD, 0x0F, 0x93, 0x4F, 0x3C, 0x4A, 0x8F, 0x62, + 0xBA, 0x86, 0x2F, 0xFD, 0x20, 0xE8, 0xE9, 0x61, + 0x15, 0x4C, 0x15, 0xC1, 0x38, 0x84, 0xED, 0x3D + }, + { + 0x7C, 0xBE, 0xE9, 0x6E, 0x13, 0x98, 0x97, 0xDC, + 0x98, 0xFB, 0xEF, 0x3B, 0xE8, 0x1A, 0xD4, 0xD9, + 0x64, 0xD2, 0x35, 0xCB, 0x12, 0x14, 0x1F, 0xB6, + 0x67, 0x27, 0xE6, 0xE5, 0xDF, 0x73, 0xA8, 0x78 + }, + { + 0xEB, 0xF6, 0x6A, 0xBB, 0x59, 0x7A, 0xE5, 0x72, + 0xA7, 0x29, 0x7C, 0xB0, 0x87, 0x1E, 0x35, 0x5A, + 0xCC, 0xAF, 0xAD, 0x83, 0x77, 0xB8, 0xE7, 0x8B, + 0xF1, 0x64, 0xCE, 0x2A, 0x18, 0xDE, 0x4B, 0xAF + }, + { + 0x71, 0xB9, 0x33, 0xB0, 0x7E, 0x4F, 0xF7, 0x81, + 0x8C, 0xE0, 0x59, 0xD0, 0x08, 0x82, 0x9E, 0x45, + 0x3C, 0x6F, 0xF0, 0x2E, 0xC0, 0xA7, 0xDB, 0x39, + 0x3F, 0xC2, 0xD8, 0x70, 0xF3, 0x7A, 0x72, 0x86 + }, + { + 0x7C, 0xF7, 0xC5, 0x13, 0x31, 0x22, 0x0B, 0x8D, + 0x3E, 0xBA, 0xED, 0x9C, 0x29, 0x39, 0x8A, 0x16, + 0xD9, 0x81, 0x56, 0xE2, 0x61, 0x3C, 0xB0, 0x88, + 0xF2, 0xB0, 0xE0, 0x8A, 0x1B, 0xE4, 0xCF, 0x4F + }, + { + 0x3E, 0x41, 0xA1, 0x08, 0xE0, 0xF6, 0x4A, 0xD2, + 0x76, 0xB9, 0x79, 0xE1, 0xCE, 0x06, 0x82, 0x79, + 0xE1, 0x6F, 0x7B, 0xC7, 0xE4, 0xAA, 0x1D, 0x21, + 0x1E, 0x17, 0xB8, 0x11, 0x61, 0xDF, 0x16, 0x02 + }, + { + 0x88, 0x65, 0x02, 0xA8, 0x2A, 0xB4, 0x7B, 0xA8, + 0xD8, 0x67, 0x10, 0xAA, 0x9D, 0xE3, 0xD4, 0x6E, + 0xA6, 0x5C, 0x47, 0xAF, 0x6E, 0xE8, 0xDE, 0x45, + 0x0C, 0xCE, 0xB8, 0xB1, 0x1B, 0x04, 0x5F, 0x50 + }, + { + 0xC0, 0x21, 0xBC, 0x5F, 0x09, 0x54, 0xFE, 0xE9, + 0x4F, 0x46, 0xEA, 0x09, 0x48, 0x7E, 0x10, 0xA8, + 0x48, 0x40, 0xD0, 0x2F, 0x64, 0x81, 0x0B, 0xC0, + 0x8D, 0x9E, 0x55, 0x1F, 0x7D, 0x41, 0x68, 0x14 + }, + { + 0x20, 0x30, 0x51, 0x6E, 0x8A, 0x5F, 0xE1, 0x9A, + 0xE7, 0x9C, 0x33, 0x6F, 0xCE, 0x26, 0x38, 0x2A, + 0x74, 0x9D, 0x3F, 0xD0, 0xEC, 0x91, 0xE5, 0x37, + 0xD4, 0xBD, 0x23, 0x58, 0xC1, 0x2D, 0xFB, 0x22 + }, + { + 0x55, 0x66, 0x98, 0xDA, 0xC8, 0x31, 0x7F, 0xD3, + 0x6D, 0xFB, 0xDF, 0x25, 0xA7, 0x9C, 0xB1, 0x12, + 0xD5, 0x42, 0x58, 0x60, 0x60, 0x5C, 0xBA, 0xF5, + 0x07, 0xF2, 0x3B, 0xF7, 0xE9, 0xF4, 0x2A, 0xFE + }, + { + 0x2F, 0x86, 0x7B, 0xA6, 0x77, 0x73, 0xFD, 0xC3, + 0xE9, 0x2F, 0xCE, 0xD9, 0x9A, 0x64, 0x09, 0xAD, + 0x39, 0xD0, 0xB8, 0x80, 0xFD, 0xE8, 0xF1, 0x09, + 0xA8, 0x17, 0x30, 0xC4, 0x45, 0x1D, 0x01, 0x78 + }, + { + 0x17, 0x2E, 0xC2, 0x18, 0xF1, 0x19, 0xDF, 0xAE, + 0x98, 0x89, 0x6D, 0xFF, 0x29, 0xDD, 0x98, 0x76, + 0xC9, 0x4A, 0xF8, 0x74, 0x17, 0xF9, 0xAE, 0x4C, + 0x70, 0x14, 0xBB, 0x4E, 0x4B, 0x96, 0xAF, 0xC7 + }, + { + 0x3F, 0x85, 0x81, 0x4A, 0x18, 0x19, 0x5F, 0x87, + 0x9A, 0xA9, 0x62, 0xF9, 0x5D, 0x26, 0xBD, 0x82, + 0xA2, 0x78, 0xF2, 0xB8, 0x23, 0x20, 0x21, 0x8F, + 0x6B, 0x3B, 0xD6, 0xF7, 0xF6, 0x67, 0xA6, 0xD9 + }, + { + 0x1B, 0x61, 0x8F, 0xBA, 0xA5, 0x66, 0xB3, 0xD4, + 0x98, 0xC1, 0x2E, 0x98, 0x2C, 0x9E, 0xC5, 0x2E, + 0x4D, 0xA8, 0x5A, 0x8C, 0x54, 0xF3, 0x8F, 0x34, + 0xC0, 0x90, 0x39, 0x4F, 0x23, 0xC1, 0x84, 0xC1 + }, + { + 0x0C, 0x75, 0x8F, 0xB5, 0x69, 0x2F, 0xFD, 0x41, + 0xA3, 0x57, 0x5D, 0x0A, 0xF0, 0x0C, 0xC7, 0xFB, + 0xF2, 0xCB, 0xE5, 0x90, 0x5A, 0x58, 0x32, 0x3A, + 0x88, 0xAE, 0x42, 0x44, 0xF6, 0xE4, 0xC9, 0x93 + }, + { + 0xA9, 0x31, 0x36, 0x0C, 0xAD, 0x62, 0x8C, 0x7F, + 0x12, 0xA6, 0xC1, 0xC4, 0xB7, 0x53, 0xB0, 0xF4, + 0x06, 0x2A, 0xEF, 0x3C, 0xE6, 0x5A, 0x1A, 0xE3, + 0xF1, 0x93, 0x69, 0xDA, 0xDF, 0x3A, 0xE2, 0x3D + }, + { + 0xCB, 0xAC, 0x7D, 0x77, 0x3B, 0x1E, 0x3B, 0x3C, + 0x66, 0x91, 0xD7, 0xAB, 0xB7, 0xE9, 0xDF, 0x04, + 0x5C, 0x8B, 0xA1, 0x92, 0x68, 0xDE, 0xD1, 0x53, + 0x20, 0x7F, 0x5E, 0x80, 0x43, 0x52, 0xEC, 0x5D + }, + { + 0x23, 0xA1, 0x96, 0xD3, 0x80, 0x2E, 0xD3, 0xC1, + 0xB3, 0x84, 0x01, 0x9A, 0x82, 0x32, 0x58, 0x40, + 0xD3, 0x2F, 0x71, 0x95, 0x0C, 0x45, 0x80, 0xB0, + 0x34, 0x45, 0xE0, 0x89, 0x8E, 0x14, 0x05, 0x3C + }, + { + 0xF4, 0x49, 0x54, 0x70, 0xF2, 0x26, 0xC8, 0xC2, + 0x14, 0xBE, 0x08, 0xFD, 0xFA, 0xD4, 0xBC, 0x4A, + 0x2A, 0x9D, 0xBE, 0xA9, 0x13, 0x6A, 0x21, 0x0D, + 0xF0, 0xD4, 0xB6, 0x49, 0x29, 0xE6, 0xFC, 0x14 + }, + { + 0xE2, 0x90, 0xDD, 0x27, 0x0B, 0x46, 0x7F, 0x34, + 0xAB, 0x1C, 0x00, 0x2D, 0x34, 0x0F, 0xA0, 0x16, + 0x25, 0x7F, 0xF1, 0x9E, 0x58, 0x33, 0xFD, 0xBB, + 0xF2, 0xCB, 0x40, 0x1C, 0x3B, 0x28, 0x17, 0xDE + }, + { + 0x9F, 0xC7, 0xB5, 0xDE, 0xD3, 0xC1, 0x50, 0x42, + 0xB2, 0xA6, 0x58, 0x2D, 0xC3, 0x9B, 0xE0, 0x16, + 0xD2, 0x4A, 0x68, 0x2D, 0x5E, 0x61, 0xAD, 0x1E, + 0xFF, 0x9C, 0x63, 0x30, 0x98, 0x48, 0xF7, 0x06 + }, + { + 0x8C, 0xCA, 0x67, 0xA3, 0x6D, 0x17, 0xD5, 0xE6, + 0x34, 0x1C, 0xB5, 0x92, 0xFD, 0x7B, 0xEF, 0x99, + 0x26, 0xC9, 0xE3, 0xAA, 0x10, 0x27, 0xEA, 0x11, + 0xA7, 0xD8, 0xBD, 0x26, 0x0B, 0x57, 0x6E, 0x04 + }, + { + 0x40, 0x93, 0x92, 0xF5, 0x60, 0xF8, 0x68, 0x31, + 0xDA, 0x43, 0x73, 0xEE, 0x5E, 0x00, 0x74, 0x26, + 0x05, 0x95, 0xD7, 0xBC, 0x24, 0x18, 0x3B, 0x60, + 0xED, 0x70, 0x0D, 0x45, 0x83, 0xD3, 0xF6, 0xF0 + }, + { + 0x28, 0x02, 0x16, 0x5D, 0xE0, 0x90, 0x91, 0x55, + 0x46, 0xF3, 0x39, 0x8C, 0xD8, 0x49, 0x16, 0x4A, + 0x19, 0xF9, 0x2A, 0xDB, 0xC3, 0x61, 0xAD, 0xC9, + 0x9B, 0x0F, 0x20, 0xC8, 0xEA, 0x07, 0x10, 0x54 + }, + { + 0xAD, 0x83, 0x91, 0x68, 0xD9, 0xF8, 0xA4, 0xBE, + 0x95, 0xBA, 0x9E, 0xF9, 0xA6, 0x92, 0xF0, 0x72, + 0x56, 0xAE, 0x43, 0xFE, 0x6F, 0x98, 0x64, 0xE2, + 0x90, 0x69, 0x1B, 0x02, 0x56, 0xCE, 0x50, 0xA9 + }, + { + 0x75, 0xFD, 0xAA, 0x50, 0x38, 0xC2, 0x84, 0xB8, + 0x6D, 0x6E, 0x8A, 0xFF, 0xE8, 0xB2, 0x80, 0x7E, + 0x46, 0x7B, 0x86, 0x60, 0x0E, 0x79, 0xAF, 0x36, + 0x89, 0xFB, 0xC0, 0x63, 0x28, 0xCB, 0xF8, 0x94 + }, + { + 0xE5, 0x7C, 0xB7, 0x94, 0x87, 0xDD, 0x57, 0x90, + 0x24, 0x32, 0xB2, 0x50, 0x73, 0x38, 0x13, 0xBD, + 0x96, 0xA8, 0x4E, 0xFC, 0xE5, 0x9F, 0x65, 0x0F, + 0xAC, 0x26, 0xE6, 0x69, 0x6A, 0xEF, 0xAF, 0xC3 + }, + { + 0x56, 0xF3, 0x4E, 0x8B, 0x96, 0x55, 0x7E, 0x90, + 0xC1, 0xF2, 0x4B, 0x52, 0xD0, 0xC8, 0x9D, 0x51, + 0x08, 0x6A, 0xCF, 0x1B, 0x00, 0xF6, 0x34, 0xCF, + 0x1D, 0xDE, 0x92, 0x33, 0xB8, 0xEA, 0xAA, 0x3E + }, + { + 0x1B, 0x53, 0xEE, 0x94, 0xAA, 0xF3, 0x4E, 0x4B, + 0x15, 0x9D, 0x48, 0xDE, 0x35, 0x2C, 0x7F, 0x06, + 0x61, 0xD0, 0xA4, 0x0E, 0xDF, 0xF9, 0x5A, 0x0B, + 0x16, 0x39, 0xB4, 0x09, 0x0E, 0x97, 0x44, 0x72 + }, + { + 0x05, 0x70, 0x5E, 0x2A, 0x81, 0x75, 0x7C, 0x14, + 0xBD, 0x38, 0x3E, 0xA9, 0x8D, 0xDA, 0x54, 0x4E, + 0xB1, 0x0E, 0x6B, 0xC0, 0x7B, 0xAE, 0x43, 0x5E, + 0x25, 0x18, 0xDB, 0xE1, 0x33, 0x52, 0x53, 0x75 + }, + { + 0xD8, 0xB2, 0x86, 0x6E, 0x8A, 0x30, 0x9D, 0xB5, + 0x3E, 0x52, 0x9E, 0xC3, 0x29, 0x11, 0xD8, 0x2F, + 0x5C, 0xA1, 0x6C, 0xFF, 0x76, 0x21, 0x68, 0x91, + 0xA9, 0x67, 0x6A, 0xA3, 0x1A, 0xAA, 0x6C, 0x42 + }, + { + 0xF5, 0x04, 0x1C, 0x24, 0x12, 0x70, 0xEB, 0x04, + 0xC7, 0x1E, 0xC2, 0xC9, 0x5D, 0x4C, 0x38, 0xD8, + 0x03, 0xB1, 0x23, 0x7B, 0x0F, 0x29, 0xFD, 0x4D, + 0xB3, 0xEB, 0x39, 0x76, 0x69, 0xE8, 0x86, 0x99 + }, + { + 0x9A, 0x4C, 0xE0, 0x77, 0xC3, 0x49, 0x32, 0x2F, + 0x59, 0x5E, 0x0E, 0xE7, 0x9E, 0xD0, 0xDA, 0x5F, + 0xAB, 0x66, 0x75, 0x2C, 0xBF, 0xEF, 0x8F, 0x87, + 0xD0, 0xE9, 0xD0, 0x72, 0x3C, 0x75, 0x30, 0xDD + }, + { + 0x65, 0x7B, 0x09, 0xF3, 0xD0, 0xF5, 0x2B, 0x5B, + 0x8F, 0x2F, 0x97, 0x16, 0x3A, 0x0E, 0xDF, 0x0C, + 0x04, 0xF0, 0x75, 0x40, 0x8A, 0x07, 0xBB, 0xEB, + 0x3A, 0x41, 0x01, 0xA8, 0x91, 0x99, 0x0D, 0x62 + }, + { + 0x1E, 0x3F, 0x7B, 0xD5, 0xA5, 0x8F, 0xA5, 0x33, + 0x34, 0x4A, 0xA8, 0xED, 0x3A, 0xC1, 0x22, 0xBB, + 0x9E, 0x70, 0xD4, 0xEF, 0x50, 0xD0, 0x04, 0x53, + 0x08, 0x21, 0x94, 0x8F, 0x5F, 0xE6, 0x31, 0x5A + }, + { + 0x80, 0xDC, 0xCF, 0x3F, 0xD8, 0x3D, 0xFD, 0x0D, + 0x35, 0xAA, 0x28, 0x58, 0x59, 0x22, 0xAB, 0x89, + 0xD5, 0x31, 0x39, 0x97, 0x67, 0x3E, 0xAF, 0x90, + 0x5C, 0xEA, 0x9C, 0x0B, 0x22, 0x5C, 0x7B, 0x5F + }, + { + 0x8A, 0x0D, 0x0F, 0xBF, 0x63, 0x77, 0xD8, 0x3B, + 0xB0, 0x8B, 0x51, 0x4B, 0x4B, 0x1C, 0x43, 0xAC, + 0xC9, 0x5D, 0x75, 0x17, 0x14, 0xF8, 0x92, 0x56, + 0x45, 0xCB, 0x6B, 0xC8, 0x56, 0xCA, 0x15, 0x0A + }, + { + 0x9F, 0xA5, 0xB4, 0x87, 0x73, 0x8A, 0xD2, 0x84, + 0x4C, 0xC6, 0x34, 0x8A, 0x90, 0x19, 0x18, 0xF6, + 0x59, 0xA3, 0xB8, 0x9E, 0x9C, 0x0D, 0xFE, 0xEA, + 0xD3, 0x0D, 0xD9, 0x4B, 0xCF, 0x42, 0xEF, 0x8E + }, + { + 0x80, 0x83, 0x2C, 0x4A, 0x16, 0x77, 0xF5, 0xEA, + 0x25, 0x60, 0xF6, 0x68, 0xE9, 0x35, 0x4D, 0xD3, + 0x69, 0x97, 0xF0, 0x37, 0x28, 0xCF, 0xA5, 0x5E, + 0x1B, 0x38, 0x33, 0x7C, 0x0C, 0x9E, 0xF8, 0x18 + }, + { + 0xAB, 0x37, 0xDD, 0xB6, 0x83, 0x13, 0x7E, 0x74, + 0x08, 0x0D, 0x02, 0x6B, 0x59, 0x0B, 0x96, 0xAE, + 0x9B, 0xB4, 0x47, 0x72, 0x2F, 0x30, 0x5A, 0x5A, + 0xC5, 0x70, 0xEC, 0x1D, 0xF9, 0xB1, 0x74, 0x3C + }, + { + 0x3E, 0xE7, 0x35, 0xA6, 0x94, 0xC2, 0x55, 0x9B, + 0x69, 0x3A, 0xA6, 0x86, 0x29, 0x36, 0x1E, 0x15, + 0xD1, 0x22, 0x65, 0xAD, 0x6A, 0x3D, 0xED, 0xF4, + 0x88, 0xB0, 0xB0, 0x0F, 0xAC, 0x97, 0x54, 0xBA + }, + { + 0xD6, 0xFC, 0xD2, 0x32, 0x19, 0xB6, 0x47, 0xE4, + 0xCB, 0xD5, 0xEB, 0x2D, 0x0A, 0xD0, 0x1E, 0xC8, + 0x83, 0x8A, 0x4B, 0x29, 0x01, 0xFC, 0x32, 0x5C, + 0xC3, 0x70, 0x19, 0x81, 0xCA, 0x6C, 0x88, 0x8B + }, + { + 0x05, 0x20, 0xEC, 0x2F, 0x5B, 0xF7, 0xA7, 0x55, + 0xDA, 0xCB, 0x50, 0xC6, 0xBF, 0x23, 0x3E, 0x35, + 0x15, 0x43, 0x47, 0x63, 0xDB, 0x01, 0x39, 0xCC, + 0xD9, 0xFA, 0xEF, 0xBB, 0x82, 0x07, 0x61, 0x2D + }, + { + 0xAF, 0xF3, 0xB7, 0x5F, 0x3F, 0x58, 0x12, 0x64, + 0xD7, 0x66, 0x16, 0x62, 0xB9, 0x2F, 0x5A, 0xD3, + 0x7C, 0x1D, 0x32, 0xBD, 0x45, 0xFF, 0x81, 0xA4, + 0xED, 0x8A, 0xDC, 0x9E, 0xF3, 0x0D, 0xD9, 0x89 + }, + { + 0xD0, 0xDD, 0x65, 0x0B, 0xEF, 0xD3, 0xBA, 0x63, + 0xDC, 0x25, 0x10, 0x2C, 0x62, 0x7C, 0x92, 0x1B, + 0x9C, 0xBE, 0xB0, 0xB1, 0x30, 0x68, 0x69, 0x35, + 0xB5, 0xC9, 0x27, 0xCB, 0x7C, 0xCD, 0x5E, 0x3B + }, + { + 0xE1, 0x14, 0x98, 0x16, 0xB1, 0x0A, 0x85, 0x14, + 0xFB, 0x3E, 0x2C, 0xAB, 0x2C, 0x08, 0xBE, 0xE9, + 0xF7, 0x3C, 0xE7, 0x62, 0x21, 0x70, 0x12, 0x46, + 0xA5, 0x89, 0xBB, 0xB6, 0x73, 0x02, 0xD8, 0xA9 + }, + { + 0x7D, 0xA3, 0xF4, 0x41, 0xDE, 0x90, 0x54, 0x31, + 0x7E, 0x72, 0xB5, 0xDB, 0xF9, 0x79, 0xDA, 0x01, + 0xE6, 0xBC, 0xEE, 0xBB, 0x84, 0x78, 0xEA, 0xE6, + 0xA2, 0x28, 0x49, 0xD9, 0x02, 0x92, 0x63, 0x5C + }, + { + 0x12, 0x30, 0xB1, 0xFC, 0x8A, 0x7D, 0x92, 0x15, + 0xED, 0xC2, 0xD4, 0xA2, 0xDE, 0xCB, 0xDD, 0x0A, + 0x6E, 0x21, 0x6C, 0x92, 0x42, 0x78, 0xC9, 0x1F, + 0xC5, 0xD1, 0x0E, 0x7D, 0x60, 0x19, 0x2D, 0x94 + }, + { + 0x57, 0x50, 0xD7, 0x16, 0xB4, 0x80, 0x8F, 0x75, + 0x1F, 0xEB, 0xC3, 0x88, 0x06, 0xBA, 0x17, 0x0B, + 0xF6, 0xD5, 0x19, 0x9A, 0x78, 0x16, 0xBE, 0x51, + 0x4E, 0x3F, 0x93, 0x2F, 0xBE, 0x0C, 0xB8, 0x71 + }, + { + 0x6F, 0xC5, 0x9B, 0x2F, 0x10, 0xFE, 0xBA, 0x95, + 0x4A, 0xA6, 0x82, 0x0B, 0x3C, 0xA9, 0x87, 0xEE, + 0x81, 0xD5, 0xCC, 0x1D, 0xA3, 0xC6, 0x3C, 0xE8, + 0x27, 0x30, 0x1C, 0x56, 0x9D, 0xFB, 0x39, 0xCE + }, + { + 0xC7, 0xC3, 0xFE, 0x1E, 0xEB, 0xDC, 0x7B, 0x5A, + 0x93, 0x93, 0x26, 0xE8, 0xDD, 0xB8, 0x3E, 0x8B, + 0xF2, 0xB7, 0x80, 0xB6, 0x56, 0x78, 0xCB, 0x62, + 0xF2, 0x08, 0xB0, 0x40, 0xAB, 0xDD, 0x35, 0xE2 + }, + { + 0x0C, 0x75, 0xC1, 0xA1, 0x5C, 0xF3, 0x4A, 0x31, + 0x4E, 0xE4, 0x78, 0xF4, 0xA5, 0xCE, 0x0B, 0x8A, + 0x6B, 0x36, 0x52, 0x8E, 0xF7, 0xA8, 0x20, 0x69, + 0x6C, 0x3E, 0x42, 0x46, 0xC5, 0xA1, 0x58, 0x64 + }, + { + 0x21, 0x6D, 0xC1, 0x2A, 0x10, 0x85, 0x69, 0xA3, + 0xC7, 0xCD, 0xDE, 0x4A, 0xED, 0x43, 0xA6, 0xC3, + 0x30, 0x13, 0x9D, 0xDA, 0x3C, 0xCC, 0x4A, 0x10, + 0x89, 0x05, 0xDB, 0x38, 0x61, 0x89, 0x90, 0x50 + }, + { + 0xA5, 0x7B, 0xE6, 0xAE, 0x67, 0x56, 0xF2, 0x8B, + 0x02, 0xF5, 0x9D, 0xAD, 0xF7, 0xE0, 0xD7, 0xD8, + 0x80, 0x7F, 0x10, 0xFA, 0x15, 0xCE, 0xD1, 0xAD, + 0x35, 0x85, 0x52, 0x1A, 0x1D, 0x99, 0x5A, 0x89 + }, + { + 0x81, 0x6A, 0xEF, 0x87, 0x59, 0x53, 0x71, 0x6C, + 0xD7, 0xA5, 0x81, 0xF7, 0x32, 0xF5, 0x3D, 0xD4, + 0x35, 0xDA, 0xB6, 0x6D, 0x09, 0xC3, 0x61, 0xD2, + 0xD6, 0x59, 0x2D, 0xE1, 0x77, 0x55, 0xD8, 0xA8 + }, + { + 0x9A, 0x76, 0x89, 0x32, 0x26, 0x69, 0x3B, 0x6E, + 0xA9, 0x7E, 0x6A, 0x73, 0x8F, 0x9D, 0x10, 0xFB, + 0x3D, 0x0B, 0x43, 0xAE, 0x0E, 0x8B, 0x7D, 0x81, + 0x23, 0xEA, 0x76, 0xCE, 0x97, 0x98, 0x9C, 0x7E + }, + { + 0x8D, 0xAE, 0xDB, 0x9A, 0x27, 0x15, 0x29, 0xDB, + 0xB7, 0xDC, 0x3B, 0x60, 0x7F, 0xE5, 0xEB, 0x2D, + 0x32, 0x11, 0x77, 0x07, 0x58, 0xDD, 0x3B, 0x0A, + 0x35, 0x93, 0xD2, 0xD7, 0x95, 0x4E, 0x2D, 0x5B + }, + { + 0x16, 0xDB, 0xC0, 0xAA, 0x5D, 0xD2, 0xC7, 0x74, + 0xF5, 0x05, 0x10, 0x0F, 0x73, 0x37, 0x86, 0xD8, + 0xA1, 0x75, 0xFC, 0xBB, 0xB5, 0x9C, 0x43, 0xE1, + 0xFB, 0xFF, 0x3E, 0x1E, 0xAF, 0x31, 0xCB, 0x4A + }, + { + 0x86, 0x06, 0xCB, 0x89, 0x9C, 0x6A, 0xEA, 0xF5, + 0x1B, 0x9D, 0xB0, 0xFE, 0x49, 0x24, 0xA9, 0xFD, + 0x5D, 0xAB, 0xC1, 0x9F, 0x88, 0x26, 0xF2, 0xBC, + 0x1C, 0x1D, 0x7D, 0xA1, 0x4D, 0x2C, 0x2C, 0x99 + }, + { + 0x84, 0x79, 0x73, 0x1A, 0xED, 0xA5, 0x7B, 0xD3, + 0x7E, 0xAD, 0xB5, 0x1A, 0x50, 0x7E, 0x30, 0x7F, + 0x3B, 0xD9, 0x5E, 0x69, 0xDB, 0xCA, 0x94, 0xF3, + 0xBC, 0x21, 0x72, 0x60, 0x66, 0xAD, 0x6D, 0xFD + }, + { + 0x58, 0x47, 0x3A, 0x9E, 0xA8, 0x2E, 0xFA, 0x3F, + 0x3B, 0x3D, 0x8F, 0xC8, 0x3E, 0xD8, 0x86, 0x31, + 0x27, 0xB3, 0x3A, 0xE8, 0xDE, 0xAE, 0x63, 0x07, + 0x20, 0x1E, 0xDB, 0x6D, 0xDE, 0x61, 0xDE, 0x29 + }, + { + 0x9A, 0x92, 0x55, 0xD5, 0x3A, 0xF1, 0x16, 0xDE, + 0x8B, 0xA2, 0x7C, 0xE3, 0x5B, 0x4C, 0x7E, 0x15, + 0x64, 0x06, 0x57, 0xA0, 0xFC, 0xB8, 0x88, 0xC7, + 0x0D, 0x95, 0x43, 0x1D, 0xAC, 0xD8, 0xF8, 0x30 + }, + { + 0x9E, 0xB0, 0x5F, 0xFB, 0xA3, 0x9F, 0xD8, 0x59, + 0x6A, 0x45, 0x49, 0x3E, 0x18, 0xD2, 0x51, 0x0B, + 0xF3, 0xEF, 0x06, 0x5C, 0x51, 0xD6, 0xE1, 0x3A, + 0xBE, 0x66, 0xAA, 0x57, 0xE0, 0x5C, 0xFD, 0xB7 + }, + { + 0x81, 0xDC, 0xC3, 0xA5, 0x05, 0xEA, 0xCE, 0x3F, + 0x87, 0x9D, 0x8F, 0x70, 0x27, 0x76, 0x77, 0x0F, + 0x9D, 0xF5, 0x0E, 0x52, 0x1D, 0x14, 0x28, 0xA8, + 0x5D, 0xAF, 0x04, 0xF9, 0xAD, 0x21, 0x50, 0xE0 + }, + { + 0xE3, 0xE3, 0xC4, 0xAA, 0x3A, 0xCB, 0xBC, 0x85, + 0x33, 0x2A, 0xF9, 0xD5, 0x64, 0xBC, 0x24, 0x16, + 0x5E, 0x16, 0x87, 0xF6, 0xB1, 0xAD, 0xCB, 0xFA, + 0xE7, 0x7A, 0x8F, 0x03, 0xC7, 0x2A, 0xC2, 0x8C + }, + { + 0x67, 0x46, 0xC8, 0x0B, 0x4E, 0xB5, 0x6A, 0xEA, + 0x45, 0xE6, 0x4E, 0x72, 0x89, 0xBB, 0xA3, 0xED, + 0xBF, 0x45, 0xEC, 0xF8, 0x20, 0x64, 0x81, 0xFF, + 0x63, 0x02, 0x12, 0x29, 0x84, 0xCD, 0x52, 0x6A + }, + { + 0x2B, 0x62, 0x8E, 0x52, 0x76, 0x4D, 0x7D, 0x62, + 0xC0, 0x86, 0x8B, 0x21, 0x23, 0x57, 0xCD, 0xD1, + 0x2D, 0x91, 0x49, 0x82, 0x2F, 0x4E, 0x98, 0x45, + 0xD9, 0x18, 0xA0, 0x8D, 0x1A, 0xE9, 0x90, 0xC0 + }, + { + 0xE4, 0xBF, 0xE8, 0x0D, 0x58, 0xC9, 0x19, 0x94, + 0x61, 0x39, 0x09, 0xDC, 0x4B, 0x1A, 0x12, 0x49, + 0x68, 0x96, 0xC0, 0x04, 0xAF, 0x7B, 0x57, 0x01, + 0x48, 0x3D, 0xE4, 0x5D, 0x28, 0x23, 0xD7, 0x8E + }, + { + 0xEB, 0xB4, 0xBA, 0x15, 0x0C, 0xEF, 0x27, 0x34, + 0x34, 0x5B, 0x5D, 0x64, 0x1B, 0xBE, 0xD0, 0x3A, + 0x21, 0xEA, 0xFA, 0xE9, 0x33, 0xC9, 0x9E, 0x00, + 0x92, 0x12, 0xEF, 0x04, 0x57, 0x4A, 0x85, 0x30 + }, + { + 0x39, 0x66, 0xEC, 0x73, 0xB1, 0x54, 0xAC, 0xC6, + 0x97, 0xAC, 0x5C, 0xF5, 0xB2, 0x4B, 0x40, 0xBD, + 0xB0, 0xDB, 0x9E, 0x39, 0x88, 0x36, 0xD7, 0x6D, + 0x4B, 0x88, 0x0E, 0x3B, 0x2A, 0xF1, 0xAA, 0x27 + }, + { + 0xEF, 0x7E, 0x48, 0x31, 0xB3, 0xA8, 0x46, 0x36, + 0x51, 0x8D, 0x6E, 0x4B, 0xFC, 0xE6, 0x4A, 0x43, + 0xDB, 0x2A, 0x5D, 0xDA, 0x9C, 0xCA, 0x2B, 0x44, + 0xF3, 0x90, 0x33, 0xBD, 0xC4, 0x0D, 0x62, 0x43 + }, + { + 0x7A, 0xBF, 0x6A, 0xCF, 0x5C, 0x8E, 0x54, 0x9D, + 0xDB, 0xB1, 0x5A, 0xE8, 0xD8, 0xB3, 0x88, 0xC1, + 0xC1, 0x97, 0xE6, 0x98, 0x73, 0x7C, 0x97, 0x85, + 0x50, 0x1E, 0xD1, 0xF9, 0x49, 0x30, 0xB7, 0xD9 + }, + { + 0x88, 0x01, 0x8D, 0xED, 0x66, 0x81, 0x3F, 0x0C, + 0xA9, 0x5D, 0xEF, 0x47, 0x4C, 0x63, 0x06, 0x92, + 0x01, 0x99, 0x67, 0xB9, 0xE3, 0x68, 0x88, 0xDA, + 0xDD, 0x94, 0x12, 0x47, 0x19, 0xB6, 0x82, 0xF6 + }, + { + 0x39, 0x30, 0x87, 0x6B, 0x9F, 0xC7, 0x52, 0x90, + 0x36, 0xB0, 0x08, 0xB1, 0xB8, 0xBB, 0x99, 0x75, + 0x22, 0xA4, 0x41, 0x63, 0x5A, 0x0C, 0x25, 0xEC, + 0x02, 0xFB, 0x6D, 0x90, 0x26, 0xE5, 0x5A, 0x97 + }, + { + 0x0A, 0x40, 0x49, 0xD5, 0x7E, 0x83, 0x3B, 0x56, + 0x95, 0xFA, 0xC9, 0x3D, 0xD1, 0xFB, 0xEF, 0x31, + 0x66, 0xB4, 0x4B, 0x12, 0xAD, 0x11, 0x24, 0x86, + 0x62, 0x38, 0x3A, 0xE0, 0x51, 0xE1, 0x58, 0x27 + }, + { + 0x81, 0xDC, 0xC0, 0x67, 0x8B, 0xB6, 0xA7, 0x65, + 0xE4, 0x8C, 0x32, 0x09, 0x65, 0x4F, 0xE9, 0x00, + 0x89, 0xCE, 0x44, 0xFF, 0x56, 0x18, 0x47, 0x7E, + 0x39, 0xAB, 0x28, 0x64, 0x76, 0xDF, 0x05, 0x2B + }, + { + 0xE6, 0x9B, 0x3A, 0x36, 0xA4, 0x46, 0x19, 0x12, + 0xDC, 0x08, 0x34, 0x6B, 0x11, 0xDD, 0xCB, 0x9D, + 0xB7, 0x96, 0xF8, 0x85, 0xFD, 0x01, 0x93, 0x6E, + 0x66, 0x2F, 0xE2, 0x92, 0x97, 0xB0, 0x99, 0xA4 + }, + { + 0x5A, 0xC6, 0x50, 0x3B, 0x0D, 0x8D, 0xA6, 0x91, + 0x76, 0x46, 0xE6, 0xDC, 0xC8, 0x7E, 0xDC, 0x58, + 0xE9, 0x42, 0x45, 0x32, 0x4C, 0xC2, 0x04, 0xF4, + 0xDD, 0x4A, 0xF0, 0x15, 0x63, 0xAC, 0xD4, 0x27 + }, + { + 0xDF, 0x6D, 0xDA, 0x21, 0x35, 0x9A, 0x30, 0xBC, + 0x27, 0x17, 0x80, 0x97, 0x1C, 0x1A, 0xBD, 0x56, + 0xA6, 0xEF, 0x16, 0x7E, 0x48, 0x08, 0x87, 0x88, + 0x8E, 0x73, 0xA8, 0x6D, 0x3B, 0xF6, 0x05, 0xE9 + }, + { + 0xE8, 0xE6, 0xE4, 0x70, 0x71, 0xE7, 0xB7, 0xDF, + 0x25, 0x80, 0xF2, 0x25, 0xCF, 0xBB, 0xED, 0xF8, + 0x4C, 0xE6, 0x77, 0x46, 0x62, 0x66, 0x28, 0xD3, + 0x30, 0x97, 0xE4, 0xB7, 0xDC, 0x57, 0x11, 0x07 + }, + { + 0x53, 0xE4, 0x0E, 0xAD, 0x62, 0x05, 0x1E, 0x19, + 0xCB, 0x9B, 0xA8, 0x13, 0x3E, 0x3E, 0x5C, 0x1C, + 0xE0, 0x0D, 0xDC, 0xAD, 0x8A, 0xCF, 0x34, 0x2A, + 0x22, 0x43, 0x60, 0xB0, 0xAC, 0xC1, 0x47, 0x77 + }, + { + 0x9C, 0xCD, 0x53, 0xFE, 0x80, 0xBE, 0x78, 0x6A, + 0xA9, 0x84, 0x63, 0x84, 0x62, 0xFB, 0x28, 0xAF, + 0xDF, 0x12, 0x2B, 0x34, 0xD7, 0x8F, 0x46, 0x87, + 0xEC, 0x63, 0x2B, 0xB1, 0x9D, 0xE2, 0x37, 0x1A + }, + { + 0xCB, 0xD4, 0x80, 0x52, 0xC4, 0x8D, 0x78, 0x84, + 0x66, 0xA3, 0xE8, 0x11, 0x8C, 0x56, 0xC9, 0x7F, + 0xE1, 0x46, 0xE5, 0x54, 0x6F, 0xAA, 0xF9, 0x3E, + 0x2B, 0xC3, 0xC4, 0x7E, 0x45, 0x93, 0x97, 0x53 + }, + { + 0x25, 0x68, 0x83, 0xB1, 0x4E, 0x2A, 0xF4, 0x4D, + 0xAD, 0xB2, 0x8E, 0x1B, 0x34, 0xB2, 0xAC, 0x0F, + 0x0F, 0x4C, 0x91, 0xC3, 0x4E, 0xC9, 0x16, 0x9E, + 0x29, 0x03, 0x61, 0x58, 0xAC, 0xAA, 0x95, 0xB9 + }, + { + 0x44, 0x71, 0xB9, 0x1A, 0xB4, 0x2D, 0xB7, 0xC4, + 0xDD, 0x84, 0x90, 0xAB, 0x95, 0xA2, 0xEE, 0x8D, + 0x04, 0xE3, 0xEF, 0x5C, 0x3D, 0x6F, 0xC7, 0x1A, + 0xC7, 0x4B, 0x2B, 0x26, 0x91, 0x4D, 0x16, 0x41 + }, + { + 0xA5, 0xEB, 0x08, 0x03, 0x8F, 0x8F, 0x11, 0x55, + 0xED, 0x86, 0xE6, 0x31, 0x90, 0x6F, 0xC1, 0x30, + 0x95, 0xF6, 0xBB, 0xA4, 0x1D, 0xE5, 0xD4, 0xE7, + 0x95, 0x75, 0x8E, 0xC8, 0xC8, 0xDF, 0x8A, 0xF1 + }, + { + 0xDC, 0x1D, 0xB6, 0x4E, 0xD8, 0xB4, 0x8A, 0x91, + 0x0E, 0x06, 0x0A, 0x6B, 0x86, 0x63, 0x74, 0xC5, + 0x78, 0x78, 0x4E, 0x9A, 0xC4, 0x9A, 0xB2, 0x77, + 0x40, 0x92, 0xAC, 0x71, 0x50, 0x19, 0x34, 0xAC + }, + { + 0x28, 0x54, 0x13, 0xB2, 0xF2, 0xEE, 0x87, 0x3D, + 0x34, 0x31, 0x9E, 0xE0, 0xBB, 0xFB, 0xB9, 0x0F, + 0x32, 0xDA, 0x43, 0x4C, 0xC8, 0x7E, 0x3D, 0xB5, + 0xED, 0x12, 0x1B, 0xB3, 0x98, 0xED, 0x96, 0x4B + }, + { + 0x02, 0x16, 0xE0, 0xF8, 0x1F, 0x75, 0x0F, 0x26, + 0xF1, 0x99, 0x8B, 0xC3, 0x93, 0x4E, 0x3E, 0x12, + 0x4C, 0x99, 0x45, 0xE6, 0x85, 0xA6, 0x0B, 0x25, + 0xE8, 0xFB, 0xD9, 0x62, 0x5A, 0xB6, 0xB5, 0x99 + }, + { + 0x38, 0xC4, 0x10, 0xF5, 0xB9, 0xD4, 0x07, 0x20, + 0x50, 0x75, 0x5B, 0x31, 0xDC, 0xA8, 0x9F, 0xD5, + 0x39, 0x5C, 0x67, 0x85, 0xEE, 0xB3, 0xD7, 0x90, + 0xF3, 0x20, 0xFF, 0x94, 0x1C, 0x5A, 0x93, 0xBF + }, + { + 0xF1, 0x84, 0x17, 0xB3, 0x9D, 0x61, 0x7A, 0xB1, + 0xC1, 0x8F, 0xDF, 0x91, 0xEB, 0xD0, 0xFC, 0x6D, + 0x55, 0x16, 0xBB, 0x34, 0xCF, 0x39, 0x36, 0x40, + 0x37, 0xBC, 0xE8, 0x1F, 0xA0, 0x4C, 0xEC, 0xB1 + }, + { + 0x1F, 0xA8, 0x77, 0xDE, 0x67, 0x25, 0x9D, 0x19, + 0x86, 0x3A, 0x2A, 0x34, 0xBC, 0xC6, 0x96, 0x2A, + 0x2B, 0x25, 0xFC, 0xBF, 0x5C, 0xBE, 0xCD, 0x7E, + 0xDE, 0x8F, 0x1F, 0xA3, 0x66, 0x88, 0xA7, 0x96 + }, + { + 0x5B, 0xD1, 0x69, 0xE6, 0x7C, 0x82, 0xC2, 0xC2, + 0xE9, 0x8E, 0xF7, 0x00, 0x8B, 0xDF, 0x26, 0x1F, + 0x2D, 0xDF, 0x30, 0xB1, 0xC0, 0x0F, 0x9E, 0x7F, + 0x27, 0x5B, 0xB3, 0xE8, 0xA2, 0x8D, 0xC9, 0xA2 + }, + { + 0xC8, 0x0A, 0xBE, 0xEB, 0xB6, 0x69, 0xAD, 0x5D, + 0xEE, 0xB5, 0xF5, 0xEC, 0x8E, 0xA6, 0xB7, 0xA0, + 0x5D, 0xDF, 0x7D, 0x31, 0xEC, 0x4C, 0x0A, 0x2E, + 0xE2, 0x0B, 0x0B, 0x98, 0xCA, 0xEC, 0x67, 0x46 + }, + { + 0xE7, 0x6D, 0x3F, 0xBD, 0xA5, 0xBA, 0x37, 0x4E, + 0x6B, 0xF8, 0xE5, 0x0F, 0xAD, 0xC3, 0xBB, 0xB9, + 0xBA, 0x5C, 0x20, 0x6E, 0xBD, 0xEC, 0x89, 0xA3, + 0xA5, 0x4C, 0xF3, 0xDD, 0x84, 0xA0, 0x70, 0x16 + }, + { + 0x7B, 0xBA, 0x9D, 0xC5, 0xB5, 0xDB, 0x20, 0x71, + 0xD1, 0x77, 0x52, 0xB1, 0x04, 0x4C, 0x1E, 0xCE, + 0xD9, 0x6A, 0xAF, 0x2D, 0xD4, 0x6E, 0x9B, 0x43, + 0x37, 0x50, 0xE8, 0xEA, 0x0D, 0xCC, 0x18, 0x70 + }, + { + 0xF2, 0x9B, 0x1B, 0x1A, 0xB9, 0xBA, 0xB1, 0x63, + 0x01, 0x8E, 0xE3, 0xDA, 0x15, 0x23, 0x2C, 0xCA, + 0x78, 0xEC, 0x52, 0xDB, 0xC3, 0x4E, 0xDA, 0x5B, + 0x82, 0x2E, 0xC1, 0xD8, 0x0F, 0xC2, 0x1B, 0xD0 + }, + { + 0x9E, 0xE3, 0xE3, 0xE7, 0xE9, 0x00, 0xF1, 0xE1, + 0x1D, 0x30, 0x8C, 0x4B, 0x2B, 0x30, 0x76, 0xD2, + 0x72, 0xCF, 0x70, 0x12, 0x4F, 0x9F, 0x51, 0xE1, + 0xDA, 0x60, 0xF3, 0x78, 0x46, 0xCD, 0xD2, 0xF4 + }, + { + 0x70, 0xEA, 0x3B, 0x01, 0x76, 0x92, 0x7D, 0x90, + 0x96, 0xA1, 0x85, 0x08, 0xCD, 0x12, 0x3A, 0x29, + 0x03, 0x25, 0x92, 0x0A, 0x9D, 0x00, 0xA8, 0x9B, + 0x5D, 0xE0, 0x42, 0x73, 0xFB, 0xC7, 0x6B, 0x85 + }, + { + 0x67, 0xDE, 0x25, 0xC0, 0x2A, 0x4A, 0xAB, 0xA2, + 0x3B, 0xDC, 0x97, 0x3C, 0x8B, 0xB0, 0xB5, 0x79, + 0x6D, 0x47, 0xCC, 0x06, 0x59, 0xD4, 0x3D, 0xFF, + 0x1F, 0x97, 0xDE, 0x17, 0x49, 0x63, 0xB6, 0x8E + }, + { + 0xB2, 0x16, 0x8E, 0x4E, 0x0F, 0x18, 0xB0, 0xE6, + 0x41, 0x00, 0xB5, 0x17, 0xED, 0x95, 0x25, 0x7D, + 0x73, 0xF0, 0x62, 0x0D, 0xF8, 0x85, 0xC1, 0x3D, + 0x2E, 0xCF, 0x79, 0x36, 0x7B, 0x38, 0x4C, 0xEE + }, + { + 0x2E, 0x7D, 0xEC, 0x24, 0x28, 0x85, 0x3B, 0x2C, + 0x71, 0x76, 0x07, 0x45, 0x54, 0x1F, 0x7A, 0xFE, + 0x98, 0x25, 0xB5, 0xDD, 0x77, 0xDF, 0x06, 0x51, + 0x1D, 0x84, 0x41, 0xA9, 0x4B, 0xAC, 0xC9, 0x27 + }, + { + 0xCA, 0x9F, 0xFA, 0xC4, 0xC4, 0x3F, 0x0B, 0x48, + 0x46, 0x1D, 0xC5, 0xC2, 0x63, 0xBE, 0xA3, 0xF6, + 0xF0, 0x06, 0x11, 0xCE, 0xAC, 0xAB, 0xF6, 0xF8, + 0x95, 0xBA, 0x2B, 0x01, 0x01, 0xDB, 0xB6, 0x8D + }, + { + 0x74, 0x10, 0xD4, 0x2D, 0x8F, 0xD1, 0xD5, 0xE9, + 0xD2, 0xF5, 0x81, 0x5C, 0xB9, 0x34, 0x17, 0x99, + 0x88, 0x28, 0xEF, 0x3C, 0x42, 0x30, 0xBF, 0xBD, + 0x41, 0x2D, 0xF0, 0xA4, 0xA7, 0xA2, 0x50, 0x7A + }, + { + 0x50, 0x10, 0xF6, 0x84, 0x51, 0x6D, 0xCC, 0xD0, + 0xB6, 0xEE, 0x08, 0x52, 0xC2, 0x51, 0x2B, 0x4D, + 0xC0, 0x06, 0x6C, 0xF0, 0xD5, 0x6F, 0x35, 0x30, + 0x29, 0x78, 0xDB, 0x8A, 0xE3, 0x2C, 0x6A, 0x81 + }, + { + 0xAC, 0xAA, 0xB5, 0x85, 0xF7, 0xB7, 0x9B, 0x71, + 0x99, 0x35, 0xCE, 0xB8, 0x95, 0x23, 0xDD, 0xC5, + 0x48, 0x27, 0xF7, 0x5C, 0x56, 0x88, 0x38, 0x56, + 0x15, 0x4A, 0x56, 0xCD, 0xCD, 0x5E, 0xE9, 0x88 + }, + { + 0x66, 0x6D, 0xE5, 0xD1, 0x44, 0x0F, 0xEE, 0x73, + 0x31, 0xAA, 0xF0, 0x12, 0x3A, 0x62, 0xEF, 0x2D, + 0x8B, 0xA5, 0x74, 0x53, 0xA0, 0x76, 0x96, 0x35, + 0xAC, 0x6C, 0xD0, 0x1E, 0x63, 0x3F, 0x77, 0x12 + }, + { + 0xA6, 0xF9, 0x86, 0x58, 0xF6, 0xEA, 0xBA, 0xF9, + 0x02, 0xD8, 0xB3, 0x87, 0x1A, 0x4B, 0x10, 0x1D, + 0x16, 0x19, 0x6E, 0x8A, 0x4B, 0x24, 0x1E, 0x15, + 0x58, 0xFE, 0x29, 0x96, 0x6E, 0x10, 0x3E, 0x8D + }, + { + 0x89, 0x15, 0x46, 0xA8, 0xB2, 0x9F, 0x30, 0x47, + 0xDD, 0xCF, 0xE5, 0xB0, 0x0E, 0x45, 0xFD, 0x55, + 0x75, 0x63, 0x73, 0x10, 0x5E, 0xA8, 0x63, 0x7D, + 0xFC, 0xFF, 0x54, 0x7B, 0x6E, 0xA9, 0x53, 0x5F + }, + { + 0x18, 0xDF, 0xBC, 0x1A, 0xC5, 0xD2, 0x5B, 0x07, + 0x61, 0x13, 0x7D, 0xBD, 0x22, 0xC1, 0x7C, 0x82, + 0x9D, 0x0F, 0x0E, 0xF1, 0xD8, 0x23, 0x44, 0xE9, + 0xC8, 0x9C, 0x28, 0x66, 0x94, 0xDA, 0x24, 0xE8 + }, + { + 0xB5, 0x4B, 0x9B, 0x67, 0xF8, 0xFE, 0xD5, 0x4B, + 0xBF, 0x5A, 0x26, 0x66, 0xDB, 0xDF, 0x4B, 0x23, + 0xCF, 0xF1, 0xD1, 0xB6, 0xF4, 0xAF, 0xC9, 0x85, + 0xB2, 0xE6, 0xD3, 0x30, 0x5A, 0x9F, 0xF8, 0x0F + }, + { + 0x7D, 0xB4, 0x42, 0xE1, 0x32, 0xBA, 0x59, 0xBC, + 0x12, 0x89, 0xAA, 0x98, 0xB0, 0xD3, 0xE8, 0x06, + 0x00, 0x4F, 0x8E, 0xC1, 0x28, 0x11, 0xAF, 0x1E, + 0x2E, 0x33, 0xC6, 0x9B, 0xFD, 0xE7, 0x29, 0xE1 + }, + { + 0x25, 0x0F, 0x37, 0xCD, 0xC1, 0x5E, 0x81, 0x7D, + 0x2F, 0x16, 0x0D, 0x99, 0x56, 0xC7, 0x1F, 0xE3, + 0xEB, 0x5D, 0xB7, 0x45, 0x56, 0xE4, 0xAD, 0xF9, + 0xA4, 0xFF, 0xAF, 0xBA, 0x74, 0x01, 0x03, 0x96 + }, + { + 0x4A, 0xB8, 0xA3, 0xDD, 0x1D, 0xDF, 0x8A, 0xD4, + 0x3D, 0xAB, 0x13, 0xA2, 0x7F, 0x66, 0xA6, 0x54, + 0x4F, 0x29, 0x05, 0x97, 0xFA, 0x96, 0x04, 0x0E, + 0x0E, 0x1D, 0xB9, 0x26, 0x3A, 0xA4, 0x79, 0xF8 + }, + { + 0xEE, 0x61, 0x72, 0x7A, 0x07, 0x66, 0xDF, 0x93, + 0x9C, 0xCD, 0xC8, 0x60, 0x33, 0x40, 0x44, 0xC7, + 0x9A, 0x3C, 0x9B, 0x15, 0x62, 0x00, 0xBC, 0x3A, + 0xA3, 0x29, 0x73, 0x48, 0x3D, 0x83, 0x41, 0xAE + }, + { + 0x3F, 0x68, 0xC7, 0xEC, 0x63, 0xAC, 0x11, 0xEB, + 0xB9, 0x8F, 0x94, 0xB3, 0x39, 0xB0, 0x5C, 0x10, + 0x49, 0x84, 0xFD, 0xA5, 0x01, 0x03, 0x06, 0x01, + 0x44, 0xE5, 0xA2, 0xBF, 0xCC, 0xC9, 0xDA, 0x95 + }, + { + 0x05, 0x6F, 0x29, 0x81, 0x6B, 0x8A, 0xF8, 0xF5, + 0x66, 0x82, 0xBC, 0x4D, 0x7C, 0xF0, 0x94, 0x11, + 0x1D, 0xA7, 0x73, 0x3E, 0x72, 0x6C, 0xD1, 0x3D, + 0x6B, 0x3E, 0x8E, 0xA0, 0x3E, 0x92, 0xA0, 0xD5 + }, + { + 0xF5, 0xEC, 0x43, 0xA2, 0x8A, 0xCB, 0xEF, 0xF1, + 0xF3, 0x31, 0x8A, 0x5B, 0xCA, 0xC7, 0xC6, 0x6D, + 0xDB, 0x52, 0x30, 0xB7, 0x9D, 0xB2, 0xD1, 0x05, + 0xBC, 0xBE, 0x15, 0xF3, 0xC1, 0x14, 0x8D, 0x69 + }, + { + 0x2A, 0x69, 0x60, 0xAD, 0x1D, 0x8D, 0xD5, 0x47, + 0x55, 0x5C, 0xFB, 0xD5, 0xE4, 0x60, 0x0F, 0x1E, + 0xAA, 0x1C, 0x8E, 0xDA, 0x34, 0xDE, 0x03, 0x74, + 0xEC, 0x4A, 0x26, 0xEA, 0xAA, 0xA3, 0x3B, 0x4E + }, + { + 0xDC, 0xC1, 0xEA, 0x7B, 0xAA, 0xB9, 0x33, 0x84, + 0xF7, 0x6B, 0x79, 0x68, 0x66, 0x19, 0x97, 0x54, + 0x74, 0x2F, 0x7B, 0x96, 0xD6, 0xB4, 0xC1, 0x20, + 0x16, 0x5C, 0x04, 0xA6, 0xC4, 0xF5, 0xCE, 0x10 + }, + { + 0x13, 0xD5, 0xDF, 0x17, 0x92, 0x21, 0x37, 0x9C, + 0x6A, 0x78, 0xC0, 0x7C, 0x79, 0x3F, 0xF5, 0x34, + 0x87, 0xCA, 0xE6, 0xBF, 0x9F, 0xE8, 0x82, 0x54, + 0x1A, 0xB0, 0xE7, 0x35, 0xE3, 0xEA, 0xDA, 0x3B + }, + { + 0x8C, 0x59, 0xE4, 0x40, 0x76, 0x41, 0xA0, 0x1E, + 0x8F, 0xF9, 0x1F, 0x99, 0x80, 0xDC, 0x23, 0x6F, + 0x4E, 0xCD, 0x6F, 0xCF, 0x52, 0x58, 0x9A, 0x09, + 0x9A, 0x96, 0x16, 0x33, 0x96, 0x77, 0x14, 0xE1 + }, + { + 0x83, 0x3B, 0x1A, 0xC6, 0xA2, 0x51, 0xFD, 0x08, + 0xFD, 0x6D, 0x90, 0x8F, 0xEA, 0x2A, 0x4E, 0xE1, + 0xE0, 0x40, 0xBC, 0xA9, 0x3F, 0xC1, 0xA3, 0x8E, + 0xC3, 0x82, 0x0E, 0x0C, 0x10, 0xBD, 0x82, 0xEA + }, + { + 0xA2, 0x44, 0xF9, 0x27, 0xF3, 0xB4, 0x0B, 0x8F, + 0x6C, 0x39, 0x15, 0x70, 0xC7, 0x65, 0x41, 0x8F, + 0x2F, 0x6E, 0x70, 0x8E, 0xAC, 0x90, 0x06, 0xC5, + 0x1A, 0x7F, 0xEF, 0xF4, 0xAF, 0x3B, 0x2B, 0x9E + }, + { + 0x3D, 0x99, 0xED, 0x95, 0x50, 0xCF, 0x11, 0x96, + 0xE6, 0xC4, 0xD2, 0x0C, 0x25, 0x96, 0x20, 0xF8, + 0x58, 0xC3, 0xD7, 0x03, 0x37, 0x4C, 0x12, 0x8C, + 0xE7, 0xB5, 0x90, 0x31, 0x0C, 0x83, 0x04, 0x6D + }, + { + 0x2B, 0x35, 0xC4, 0x7D, 0x7B, 0x87, 0x76, 0x1F, + 0x0A, 0xE4, 0x3A, 0xC5, 0x6A, 0xC2, 0x7B, 0x9F, + 0x25, 0x83, 0x03, 0x67, 0xB5, 0x95, 0xBE, 0x8C, + 0x24, 0x0E, 0x94, 0x60, 0x0C, 0x6E, 0x33, 0x12 + }, + { + 0x5D, 0x11, 0xED, 0x37, 0xD2, 0x4D, 0xC7, 0x67, + 0x30, 0x5C, 0xB7, 0xE1, 0x46, 0x7D, 0x87, 0xC0, + 0x65, 0xAC, 0x4B, 0xC8, 0xA4, 0x26, 0xDE, 0x38, + 0x99, 0x1F, 0xF5, 0x9A, 0xA8, 0x73, 0x5D, 0x02 + }, + { + 0xB8, 0x36, 0x47, 0x8E, 0x1C, 0xA0, 0x64, 0x0D, + 0xCE, 0x6F, 0xD9, 0x10, 0xA5, 0x09, 0x62, 0x72, + 0xC8, 0x33, 0x09, 0x90, 0xCD, 0x97, 0x86, 0x4A, + 0xC2, 0xBF, 0x14, 0xEF, 0x6B, 0x23, 0x91, 0x4A + }, + { + 0x91, 0x00, 0xF9, 0x46, 0xD6, 0xCC, 0xDE, 0x3A, + 0x59, 0x7F, 0x90, 0xD3, 0x9F, 0xC1, 0x21, 0x5B, + 0xAD, 0xDC, 0x74, 0x13, 0x64, 0x3D, 0x85, 0xC2, + 0x1C, 0x3E, 0xEE, 0x5D, 0x2D, 0xD3, 0x28, 0x94 + }, + { + 0xDA, 0x70, 0xEE, 0xDD, 0x23, 0xE6, 0x63, 0xAA, + 0x1A, 0x74, 0xB9, 0x76, 0x69, 0x35, 0xB4, 0x79, + 0x22, 0x2A, 0x72, 0xAF, 0xBA, 0x5C, 0x79, 0x51, + 0x58, 0xDA, 0xD4, 0x1A, 0x3B, 0xD7, 0x7E, 0x40 + }, + { + 0xF0, 0x67, 0xED, 0x6A, 0x0D, 0xBD, 0x43, 0xAA, + 0x0A, 0x92, 0x54, 0xE6, 0x9F, 0xD6, 0x6B, 0xDD, + 0x8A, 0xCB, 0x87, 0xDE, 0x93, 0x6C, 0x25, 0x8C, + 0xFB, 0x02, 0x28, 0x5F, 0x2C, 0x11, 0xFA, 0x79 + }, + { + 0x71, 0x5C, 0x99, 0xC7, 0xD5, 0x75, 0x80, 0xCF, + 0x97, 0x53, 0xB4, 0xC1, 0xD7, 0x95, 0xE4, 0x5A, + 0x83, 0xFB, 0xB2, 0x28, 0xC0, 0xD3, 0x6F, 0xBE, + 0x20, 0xFA, 0xF3, 0x9B, 0xDD, 0x6D, 0x4E, 0x85 + }, + { + 0xE4, 0x57, 0xD6, 0xAD, 0x1E, 0x67, 0xCB, 0x9B, + 0xBD, 0x17, 0xCB, 0xD6, 0x98, 0xFA, 0x6D, 0x7D, + 0xAE, 0x0C, 0x9B, 0x7A, 0xD6, 0xCB, 0xD6, 0x53, + 0x96, 0x34, 0xE3, 0x2A, 0x71, 0x9C, 0x84, 0x92 + }, + { + 0xEC, 0xE3, 0xEA, 0x81, 0x03, 0xE0, 0x24, 0x83, + 0xC6, 0x4A, 0x70, 0xA4, 0xBD, 0xCE, 0xE8, 0xCE, + 0xB6, 0x27, 0x8F, 0x25, 0x33, 0xF3, 0xF4, 0x8D, + 0xBE, 0xED, 0xFB, 0xA9, 0x45, 0x31, 0xD4, 0xAE + }, + { + 0x38, 0x8A, 0xA5, 0xD3, 0x66, 0x7A, 0x97, 0xC6, + 0x8D, 0x3D, 0x56, 0xF8, 0xF3, 0xEE, 0x8D, 0x3D, + 0x36, 0x09, 0x1F, 0x17, 0xFE, 0x5D, 0x1B, 0x0D, + 0x5D, 0x84, 0xC9, 0x3B, 0x2F, 0xFE, 0x40, 0xBD + }, + { + 0x8B, 0x6B, 0x31, 0xB9, 0xAD, 0x7C, 0x3D, 0x5C, + 0xD8, 0x4B, 0xF9, 0x89, 0x47, 0xB9, 0xCD, 0xB5, + 0x9D, 0xF8, 0xA2, 0x5F, 0xF7, 0x38, 0x10, 0x10, + 0x13, 0xBE, 0x4F, 0xD6, 0x5E, 0x1D, 0xD1, 0xA3 + }, + { + 0x06, 0x62, 0x91, 0xF6, 0xBB, 0xD2, 0x5F, 0x3C, + 0x85, 0x3D, 0xB7, 0xD8, 0xB9, 0x5C, 0x9A, 0x1C, + 0xFB, 0x9B, 0xF1, 0xC1, 0xC9, 0x9F, 0xB9, 0x5A, + 0x9B, 0x78, 0x69, 0xD9, 0x0F, 0x1C, 0x29, 0x03 + }, + { + 0xA7, 0x07, 0xEF, 0xBC, 0xCD, 0xCE, 0xED, 0x42, + 0x96, 0x7A, 0x66, 0xF5, 0x53, 0x9B, 0x93, 0xED, + 0x75, 0x60, 0xD4, 0x67, 0x30, 0x40, 0x16, 0xC4, + 0x78, 0x0D, 0x77, 0x55, 0xA5, 0x65, 0xD4, 0xC4 + }, + { + 0x38, 0xC5, 0x3D, 0xFB, 0x70, 0xBE, 0x7E, 0x79, + 0x2B, 0x07, 0xA6, 0xA3, 0x5B, 0x8A, 0x6A, 0x0A, + 0xBA, 0x02, 0xC5, 0xC5, 0xF3, 0x8B, 0xAF, 0x5C, + 0x82, 0x3F, 0xDF, 0xD9, 0xE4, 0x2D, 0x65, 0x7E + }, + { + 0xF2, 0x91, 0x13, 0x86, 0x50, 0x1D, 0x9A, 0xB9, + 0xD7, 0x20, 0xCF, 0x8A, 0xD1, 0x05, 0x03, 0xD5, + 0x63, 0x4B, 0xF4, 0xB7, 0xD1, 0x2B, 0x56, 0xDF, + 0xB7, 0x4F, 0xEC, 0xC6, 0xE4, 0x09, 0x3F, 0x68 + }, + { + 0xC6, 0xF2, 0xBD, 0xD5, 0x2B, 0x81, 0xE6, 0xE4, + 0xF6, 0x59, 0x5A, 0xBD, 0x4D, 0x7F, 0xB3, 0x1F, + 0x65, 0x11, 0x69, 0xD0, 0x0F, 0xF3, 0x26, 0x92, + 0x6B, 0x34, 0x94, 0x7B, 0x28, 0xA8, 0x39, 0x59 + }, + { + 0x29, 0x3D, 0x94, 0xB1, 0x8C, 0x98, 0xBB, 0x32, + 0x23, 0x36, 0x6B, 0x8C, 0xE7, 0x4C, 0x28, 0xFB, + 0xDF, 0x28, 0xE1, 0xF8, 0x4A, 0x33, 0x50, 0xB0, + 0xEB, 0x2D, 0x18, 0x04, 0xA5, 0x77, 0x57, 0x9B + }, + { + 0x2C, 0x2F, 0xA5, 0xC0, 0xB5, 0x15, 0x33, 0x16, + 0x5B, 0xC3, 0x75, 0xC2, 0x2E, 0x27, 0x81, 0x76, + 0x82, 0x70, 0xA3, 0x83, 0x98, 0x5D, 0x13, 0xBD, + 0x6B, 0x67, 0xB6, 0xFD, 0x67, 0xF8, 0x89, 0xEB + }, + { + 0xCA, 0xA0, 0x9B, 0x82, 0xB7, 0x25, 0x62, 0xE4, + 0x3F, 0x4B, 0x22, 0x75, 0xC0, 0x91, 0x91, 0x8E, + 0x62, 0x4D, 0x91, 0x16, 0x61, 0xCC, 0x81, 0x1B, + 0xB5, 0xFA, 0xEC, 0x51, 0xF6, 0x08, 0x8E, 0xF7 + }, + { + 0x24, 0x76, 0x1E, 0x45, 0xE6, 0x74, 0x39, 0x53, + 0x79, 0xFB, 0x17, 0x72, 0x9C, 0x78, 0xCB, 0x93, + 0x9E, 0x6F, 0x74, 0xC5, 0xDF, 0xFB, 0x9C, 0x96, + 0x1F, 0x49, 0x59, 0x82, 0xC3, 0xED, 0x1F, 0xE3 + }, + { + 0x55, 0xB7, 0x0A, 0x82, 0x13, 0x1E, 0xC9, 0x48, + 0x88, 0xD7, 0xAB, 0x54, 0xA7, 0xC5, 0x15, 0x25, + 0x5C, 0x39, 0x38, 0xBB, 0x10, 0xBC, 0x78, 0x4D, + 0xC9, 0xB6, 0x7F, 0x07, 0x6E, 0x34, 0x1A, 0x73 + }, + { + 0x6A, 0xB9, 0x05, 0x7B, 0x97, 0x7E, 0xBC, 0x3C, + 0xA4, 0xD4, 0xCE, 0x74, 0x50, 0x6C, 0x25, 0xCC, + 0xCD, 0xC5, 0x66, 0x49, 0x7C, 0x45, 0x0B, 0x54, + 0x15, 0xA3, 0x94, 0x86, 0xF8, 0x65, 0x7A, 0x03 + }, + { + 0x24, 0x06, 0x6D, 0xEE, 0xE0, 0xEC, 0xEE, 0x15, + 0xA4, 0x5F, 0x0A, 0x32, 0x6D, 0x0F, 0x8D, 0xBC, + 0x79, 0x76, 0x1E, 0xBB, 0x93, 0xCF, 0x8C, 0x03, + 0x77, 0xAF, 0x44, 0x09, 0x78, 0xFC, 0xF9, 0x94 + }, + { + 0x20, 0x00, 0x0D, 0x3F, 0x66, 0xBA, 0x76, 0x86, + 0x0D, 0x5A, 0x95, 0x06, 0x88, 0xB9, 0xAA, 0x0D, + 0x76, 0xCF, 0xEA, 0x59, 0xB0, 0x05, 0xD8, 0x59, + 0x91, 0x4B, 0x1A, 0x46, 0x65, 0x3A, 0x93, 0x9B + }, + { + 0xB9, 0x2D, 0xAA, 0x79, 0x60, 0x3E, 0x3B, 0xDB, + 0xC3, 0xBF, 0xE0, 0xF4, 0x19, 0xE4, 0x09, 0xB2, + 0xEA, 0x10, 0xDC, 0x43, 0x5B, 0xEE, 0xFE, 0x29, + 0x59, 0xDA, 0x16, 0x89, 0x5D, 0x5D, 0xCA, 0x1C + }, + { + 0xE9, 0x47, 0x94, 0x87, 0x05, 0xB2, 0x06, 0xD5, + 0x72, 0xB0, 0xE8, 0xF6, 0x2F, 0x66, 0xA6, 0x55, + 0x1C, 0xBD, 0x6B, 0xC3, 0x05, 0xD2, 0x6C, 0xE7, + 0x53, 0x9A, 0x12, 0xF9, 0xAA, 0xDF, 0x75, 0x71 + }, + { + 0x3D, 0x67, 0xC1, 0xB3, 0xF9, 0xB2, 0x39, 0x10, + 0xE3, 0xD3, 0x5E, 0x6B, 0x0F, 0x2C, 0xCF, 0x44, + 0xA0, 0xB5, 0x40, 0xA4, 0x5C, 0x18, 0xBA, 0x3C, + 0x36, 0x26, 0x4D, 0xD4, 0x8E, 0x96, 0xAF, 0x6A + }, + { + 0xC7, 0x55, 0x8B, 0xAB, 0xDA, 0x04, 0xBC, 0xCB, + 0x76, 0x4D, 0x0B, 0xBF, 0x33, 0x58, 0x42, 0x51, + 0x41, 0x90, 0x2D, 0x22, 0x39, 0x1D, 0x9F, 0x8C, + 0x59, 0x15, 0x9F, 0xEC, 0x9E, 0x49, 0xB1, 0x51 + }, + { + 0x0B, 0x73, 0x2B, 0xB0, 0x35, 0x67, 0x5A, 0x50, + 0xFF, 0x58, 0xF2, 0xC2, 0x42, 0xE4, 0x71, 0x0A, + 0xEC, 0xE6, 0x46, 0x70, 0x07, 0x9C, 0x13, 0x04, + 0x4C, 0x79, 0xC9, 0xB7, 0x49, 0x1F, 0x70, 0x00 + }, + { + 0xD1, 0x20, 0xB5, 0xEF, 0x6D, 0x57, 0xEB, 0xF0, + 0x6E, 0xAF, 0x96, 0xBC, 0x93, 0x3C, 0x96, 0x7B, + 0x16, 0xCB, 0xE6, 0xE2, 0xBF, 0x00, 0x74, 0x1C, + 0x30, 0xAA, 0x1C, 0x54, 0xBA, 0x64, 0x80, 0x1F + }, + { + 0x58, 0xD2, 0x12, 0xAD, 0x6F, 0x58, 0xAE, 0xF0, + 0xF8, 0x01, 0x16, 0xB4, 0x41, 0xE5, 0x7F, 0x61, + 0x95, 0xBF, 0xEF, 0x26, 0xB6, 0x14, 0x63, 0xED, + 0xEC, 0x11, 0x83, 0xCD, 0xB0, 0x4F, 0xE7, 0x6D + }, + { + 0xB8, 0x83, 0x6F, 0x51, 0xD1, 0xE2, 0x9B, 0xDF, + 0xDB, 0xA3, 0x25, 0x56, 0x53, 0x60, 0x26, 0x8B, + 0x8F, 0xAD, 0x62, 0x74, 0x73, 0xED, 0xEC, 0xEF, + 0x7E, 0xAE, 0xFE, 0xE8, 0x37, 0xC7, 0x40, 0x03 + }, + { + 0xC5, 0x47, 0xA3, 0xC1, 0x24, 0xAE, 0x56, 0x85, + 0xFF, 0xA7, 0xB8, 0xED, 0xAF, 0x96, 0xEC, 0x86, + 0xF8, 0xB2, 0xD0, 0xD5, 0x0C, 0xEE, 0x8B, 0xE3, + 0xB1, 0xF0, 0xC7, 0x67, 0x63, 0x06, 0x9D, 0x9C + }, + { + 0x5D, 0x16, 0x8B, 0x76, 0x9A, 0x2F, 0x67, 0x85, + 0x3D, 0x62, 0x95, 0xF7, 0x56, 0x8B, 0xE4, 0x0B, + 0xB7, 0xA1, 0x6B, 0x8D, 0x65, 0xBA, 0x87, 0x63, + 0x5D, 0x19, 0x78, 0xD2, 0xAB, 0x11, 0xBA, 0x2A + }, + { + 0xA2, 0xF6, 0x75, 0xDC, 0x73, 0x02, 0x63, 0x8C, + 0xB6, 0x02, 0x01, 0x06, 0x4C, 0xA5, 0x50, 0x77, + 0x71, 0x4D, 0x71, 0xFE, 0x09, 0x6A, 0x31, 0x5F, + 0x2F, 0xE7, 0x40, 0x12, 0x77, 0xCA, 0xA5, 0xAF + }, + { + 0xC8, 0xAA, 0xB5, 0xCD, 0x01, 0x60, 0xAE, 0x78, + 0xCD, 0x2E, 0x8A, 0xC5, 0xFB, 0x0E, 0x09, 0x3C, + 0xDB, 0x5C, 0x4B, 0x60, 0x52, 0xA0, 0xA9, 0x7B, + 0xB0, 0x42, 0x16, 0x82, 0x6F, 0xA7, 0xA4, 0x37 + }, + { + 0xFF, 0x68, 0xCA, 0x40, 0x35, 0xBF, 0xEB, 0x43, + 0xFB, 0xF1, 0x45, 0xFD, 0xDD, 0x5E, 0x43, 0xF1, + 0xCE, 0xA5, 0x4F, 0x11, 0xF7, 0xBE, 0xE1, 0x30, + 0x58, 0xF0, 0x27, 0x32, 0x9A, 0x4A, 0x5F, 0xA4 + }, + { + 0x1D, 0x4E, 0x54, 0x87, 0xAE, 0x3C, 0x74, 0x0F, + 0x2B, 0xA6, 0xE5, 0x41, 0xAC, 0x91, 0xBC, 0x2B, + 0xFC, 0xD2, 0x99, 0x9C, 0x51, 0x8D, 0x80, 0x7B, + 0x42, 0x67, 0x48, 0x80, 0x3A, 0x35, 0x0F, 0xD4 + }, + { + 0x6D, 0x24, 0x4E, 0x1A, 0x06, 0xCE, 0x4E, 0xF5, + 0x78, 0xDD, 0x0F, 0x63, 0xAF, 0xF0, 0x93, 0x67, + 0x06, 0x73, 0x51, 0x19, 0xCA, 0x9C, 0x8D, 0x22, + 0xD8, 0x6C, 0x80, 0x14, 0x14, 0xAB, 0x97, 0x41 + }, + { + 0xDE, 0xCF, 0x73, 0x29, 0xDB, 0xCC, 0x82, 0x7B, + 0x8F, 0xC5, 0x24, 0xC9, 0x43, 0x1E, 0x89, 0x98, + 0x02, 0x9E, 0xCE, 0x12, 0xCE, 0x93, 0xB7, 0xB2, + 0xF3, 0xE7, 0x69, 0xA9, 0x41, 0xFB, 0x8C, 0xEA + }, + { + 0x2F, 0xAF, 0xCC, 0x0F, 0x2E, 0x63, 0xCB, 0xD0, + 0x77, 0x55, 0xBE, 0x7B, 0x75, 0xEC, 0xEA, 0x0A, + 0xDF, 0xF9, 0xAA, 0x5E, 0xDE, 0x2A, 0x52, 0xFD, + 0xAB, 0x4D, 0xFD, 0x03, 0x74, 0xCD, 0x48, 0x3F + }, + { + 0xAA, 0x85, 0x01, 0x0D, 0xD4, 0x6A, 0x54, 0x6B, + 0x53, 0x5E, 0xF4, 0xCF, 0x5F, 0x07, 0xD6, 0x51, + 0x61, 0xE8, 0x98, 0x28, 0xF3, 0xA7, 0x7D, 0xB7, + 0xB9, 0xB5, 0x6F, 0x0D, 0xF5, 0x9A, 0xAE, 0x45 + }, + { + 0x07, 0xE8, 0xE1, 0xEE, 0x73, 0x2C, 0xB0, 0xD3, + 0x56, 0xC9, 0xC0, 0xD1, 0x06, 0x9C, 0x89, 0xD1, + 0x7A, 0xDF, 0x6A, 0x9A, 0x33, 0x4F, 0x74, 0x5E, + 0xC7, 0x86, 0x73, 0x32, 0x54, 0x8C, 0xA8, 0xE9 + }, + { + 0x0E, 0x01, 0xE8, 0x1C, 0xAD, 0xA8, 0x16, 0x2B, + 0xFD, 0x5F, 0x8A, 0x8C, 0x81, 0x8A, 0x6C, 0x69, + 0xFE, 0xDF, 0x02, 0xCE, 0xB5, 0x20, 0x85, 0x23, + 0xCB, 0xE5, 0x31, 0x3B, 0x89, 0xCA, 0x10, 0x53 + }, + { + 0x6B, 0xB6, 0xC6, 0x47, 0x26, 0x55, 0x08, 0x43, + 0x99, 0x85, 0x2E, 0x00, 0x24, 0x9F, 0x8C, 0xB2, + 0x47, 0x89, 0x6D, 0x39, 0x2B, 0x02, 0xD7, 0x3B, + 0x7F, 0x0D, 0xD8, 0x18, 0xE1, 0xE2, 0x9B, 0x07 + }, + { + 0x42, 0xD4, 0x63, 0x6E, 0x20, 0x60, 0xF0, 0x8F, + 0x41, 0xC8, 0x82, 0xE7, 0x6B, 0x39, 0x6B, 0x11, + 0x2E, 0xF6, 0x27, 0xCC, 0x24, 0xC4, 0x3D, 0xD5, + 0xF8, 0x3A, 0x1D, 0x1A, 0x7E, 0xAD, 0x71, 0x1A + }, + { + 0x48, 0x58, 0xC9, 0xA1, 0x88, 0xB0, 0x23, 0x4F, + 0xB9, 0xA8, 0xD4, 0x7D, 0x0B, 0x41, 0x33, 0x65, + 0x0A, 0x03, 0x0B, 0xD0, 0x61, 0x1B, 0x87, 0xC3, + 0x89, 0x2E, 0x94, 0x95, 0x1F, 0x8D, 0xF8, 0x52 + }, + { + 0x3F, 0xAB, 0x3E, 0x36, 0x98, 0x8D, 0x44, 0x5A, + 0x51, 0xC8, 0x78, 0x3E, 0x53, 0x1B, 0xE3, 0xA0, + 0x2B, 0xE4, 0x0C, 0xD0, 0x47, 0x96, 0xCF, 0xB6, + 0x1D, 0x40, 0x34, 0x74, 0x42, 0xD3, 0xF7, 0x94 + }, + { + 0xEB, 0xAB, 0xC4, 0x96, 0x36, 0xBD, 0x43, 0x3D, + 0x2E, 0xC8, 0xF0, 0xE5, 0x18, 0x73, 0x2E, 0xF8, + 0xFA, 0x21, 0xD4, 0xD0, 0x71, 0xCC, 0x3B, 0xC4, + 0x6C, 0xD7, 0x9F, 0xA3, 0x8A, 0x28, 0xB8, 0x10 + }, + { + 0xA1, 0xD0, 0x34, 0x35, 0x23, 0xB8, 0x93, 0xFC, + 0xA8, 0x4F, 0x47, 0xFE, 0xB4, 0xA6, 0x4D, 0x35, + 0x0A, 0x17, 0xD8, 0xEE, 0xF5, 0x49, 0x7E, 0xCE, + 0x69, 0x7D, 0x02, 0xD7, 0x91, 0x78, 0xB5, 0x91 + }, + { + 0x26, 0x2E, 0xBF, 0xD9, 0x13, 0x0B, 0x7D, 0x28, + 0x76, 0x0D, 0x08, 0xEF, 0x8B, 0xFD, 0x3B, 0x86, + 0xCD, 0xD3, 0xB2, 0x11, 0x3D, 0x2C, 0xAE, 0xF7, + 0xEA, 0x95, 0x1A, 0x30, 0x3D, 0xFA, 0x38, 0x46 + }, + { + 0xF7, 0x61, 0x58, 0xED, 0xD5, 0x0A, 0x15, 0x4F, + 0xA7, 0x82, 0x03, 0xED, 0x23, 0x62, 0x93, 0x2F, + 0xCB, 0x82, 0x53, 0xAA, 0xE3, 0x78, 0x90, 0x3E, + 0xDE, 0xD1, 0xE0, 0x3F, 0x70, 0x21, 0xA2, 0x57 + }, + { + 0x26, 0x17, 0x8E, 0x95, 0x0A, 0xC7, 0x22, 0xF6, + 0x7A, 0xE5, 0x6E, 0x57, 0x1B, 0x28, 0x4C, 0x02, + 0x07, 0x68, 0x4A, 0x63, 0x34, 0xA1, 0x77, 0x48, + 0xA9, 0x4D, 0x26, 0x0B, 0xC5, 0xF5, 0x52, 0x74 + }, + { + 0xC3, 0x78, 0xD1, 0xE4, 0x93, 0xB4, 0x0E, 0xF1, + 0x1F, 0xE6, 0xA1, 0x5D, 0x9C, 0x27, 0x37, 0xA3, + 0x78, 0x09, 0x63, 0x4C, 0x5A, 0xBA, 0xD5, 0xB3, + 0x3D, 0x7E, 0x39, 0x3B, 0x4A, 0xE0, 0x5D, 0x03 + }, + { + 0x98, 0x4B, 0xD8, 0x37, 0x91, 0x01, 0xBE, 0x8F, + 0xD8, 0x06, 0x12, 0xD8, 0xEA, 0x29, 0x59, 0xA7, + 0x86, 0x5E, 0xC9, 0x71, 0x85, 0x23, 0x55, 0x01, + 0x07, 0xAE, 0x39, 0x38, 0xDF, 0x32, 0x01, 0x1B + }, + { + 0xC6, 0xF2, 0x5A, 0x81, 0x2A, 0x14, 0x48, 0x58, + 0xAC, 0x5C, 0xED, 0x37, 0xA9, 0x3A, 0x9F, 0x47, + 0x59, 0xBA, 0x0B, 0x1C, 0x0F, 0xDC, 0x43, 0x1D, + 0xCE, 0x35, 0xF9, 0xEC, 0x1F, 0x1F, 0x4A, 0x99 + }, + { + 0x92, 0x4C, 0x75, 0xC9, 0x44, 0x24, 0xFF, 0x75, + 0xE7, 0x4B, 0x8B, 0x4E, 0x94, 0x35, 0x89, 0x58, + 0xB0, 0x27, 0xB1, 0x71, 0xDF, 0x5E, 0x57, 0x89, + 0x9A, 0xD0, 0xD4, 0xDA, 0xC3, 0x73, 0x53, 0xB6 + }, + { + 0x0A, 0xF3, 0x58, 0x92, 0xA6, 0x3F, 0x45, 0x93, + 0x1F, 0x68, 0x46, 0xED, 0x19, 0x03, 0x61, 0xCD, + 0x07, 0x30, 0x89, 0xE0, 0x77, 0x16, 0x57, 0x14, + 0xB5, 0x0B, 0x81, 0xA2, 0xE3, 0xDD, 0x9B, 0xA1 + }, + { + 0xCC, 0x80, 0xCE, 0xFB, 0x26, 0xC3, 0xB2, 0xB0, + 0xDA, 0xEF, 0x23, 0x3E, 0x60, 0x6D, 0x5F, 0xFC, + 0x80, 0xFA, 0x17, 0x42, 0x7D, 0x18, 0xE3, 0x04, + 0x89, 0x67, 0x3E, 0x06, 0xEF, 0x4B, 0x87, 0xF7 + }, + { + 0xC2, 0xF8, 0xC8, 0x11, 0x74, 0x47, 0xF3, 0x97, + 0x8B, 0x08, 0x18, 0xDC, 0xF6, 0xF7, 0x01, 0x16, + 0xAC, 0x56, 0xFD, 0x18, 0x4D, 0xD1, 0x27, 0x84, + 0x94, 0xE1, 0x03, 0xFC, 0x6D, 0x74, 0xA8, 0x87 + }, + { + 0xBD, 0xEC, 0xF6, 0xBF, 0xC1, 0xBA, 0x0D, 0xF6, + 0xE8, 0x62, 0xC8, 0x31, 0x99, 0x22, 0x07, 0x79, + 0x6A, 0xCC, 0x79, 0x79, 0x68, 0x35, 0x88, 0x28, + 0xC0, 0x6E, 0x7A, 0x51, 0xE0, 0x90, 0x09, 0x8F + }, + { + 0x24, 0xD1, 0xA2, 0x6E, 0x3D, 0xAB, 0x02, 0xFE, + 0x45, 0x72, 0xD2, 0xAA, 0x7D, 0xBD, 0x3E, 0xC3, + 0x0F, 0x06, 0x93, 0xDB, 0x26, 0xF2, 0x73, 0xD0, + 0xAB, 0x2C, 0xB0, 0xC1, 0x3B, 0x5E, 0x64, 0x51 + }, + { + 0xEC, 0x56, 0xF5, 0x8B, 0x09, 0x29, 0x9A, 0x30, + 0x0B, 0x14, 0x05, 0x65, 0xD7, 0xD3, 0xE6, 0x87, + 0x82, 0xB6, 0xE2, 0xFB, 0xEB, 0x4B, 0x7E, 0xA9, + 0x7A, 0xC0, 0x57, 0x98, 0x90, 0x61, 0xDD, 0x3F + }, + { + 0x11, 0xA4, 0x37, 0xC1, 0xAB, 0xA3, 0xC1, 0x19, + 0xDD, 0xFA, 0xB3, 0x1B, 0x3E, 0x8C, 0x84, 0x1D, + 0xEE, 0xEB, 0x91, 0x3E, 0xF5, 0x7F, 0x7E, 0x48, + 0xF2, 0xC9, 0xCF, 0x5A, 0x28, 0xFA, 0x42, 0xBC + }, + { + 0x53, 0xC7, 0xE6, 0x11, 0x4B, 0x85, 0x0A, 0x2C, + 0xB4, 0x96, 0xC9, 0xB3, 0xC6, 0x9A, 0x62, 0x3E, + 0xAE, 0xA2, 0xCB, 0x1D, 0x33, 0xDD, 0x81, 0x7E, + 0x47, 0x65, 0xED, 0xAA, 0x68, 0x23, 0xC2, 0x28 + }, + { + 0x15, 0x4C, 0x3E, 0x96, 0xFE, 0xE5, 0xDB, 0x14, + 0xF8, 0x77, 0x3E, 0x18, 0xAF, 0x14, 0x85, 0x79, + 0x13, 0x50, 0x9D, 0xA9, 0x99, 0xB4, 0x6C, 0xDD, + 0x3D, 0x4C, 0x16, 0x97, 0x60, 0xC8, 0x3A, 0xD2 + }, + { + 0x40, 0xB9, 0x91, 0x6F, 0x09, 0x3E, 0x02, 0x7A, + 0x87, 0x86, 0x64, 0x18, 0x18, 0x92, 0x06, 0x20, + 0x47, 0x2F, 0xBC, 0xF6, 0x8F, 0x70, 0x1D, 0x1B, + 0x68, 0x06, 0x32, 0xE6, 0x99, 0x6B, 0xDE, 0xD3 + }, + { + 0x24, 0xC4, 0xCB, 0xBA, 0x07, 0x11, 0x98, 0x31, + 0xA7, 0x26, 0xB0, 0x53, 0x05, 0xD9, 0x6D, 0xA0, + 0x2F, 0xF8, 0xB1, 0x48, 0xF0, 0xDA, 0x44, 0x0F, + 0xE2, 0x33, 0xBC, 0xAA, 0x32, 0xC7, 0x2F, 0x6F + }, + { + 0x5D, 0x20, 0x15, 0x10, 0x25, 0x00, 0x20, 0xB7, + 0x83, 0x68, 0x96, 0x88, 0xAB, 0xBF, 0x8E, 0xCF, + 0x25, 0x94, 0xA9, 0x6A, 0x08, 0xF2, 0xBF, 0xEC, + 0x6C, 0xE0, 0x57, 0x44, 0x65, 0xDD, 0xED, 0x71 + }, + { + 0x04, 0x3B, 0x97, 0xE3, 0x36, 0xEE, 0x6F, 0xDB, + 0xBE, 0x2B, 0x50, 0xF2, 0x2A, 0xF8, 0x32, 0x75, + 0xA4, 0x08, 0x48, 0x05, 0xD2, 0xD5, 0x64, 0x59, + 0x62, 0x45, 0x4B, 0x6C, 0x9B, 0x80, 0x53, 0xA0 + }, + { + 0x56, 0x48, 0x35, 0xCB, 0xAE, 0xA7, 0x74, 0x94, + 0x85, 0x68, 0xBE, 0x36, 0xCF, 0x52, 0xFC, 0xDD, + 0x83, 0x93, 0x4E, 0xB0, 0xA2, 0x75, 0x12, 0xDB, + 0xE3, 0xE2, 0xDB, 0x47, 0xB9, 0xE6, 0x63, 0x5A + }, + { + 0xF2, 0x1C, 0x33, 0xF4, 0x7B, 0xDE, 0x40, 0xA2, + 0xA1, 0x01, 0xC9, 0xCD, 0xE8, 0x02, 0x7A, 0xAF, + 0x61, 0xA3, 0x13, 0x7D, 0xE2, 0x42, 0x2B, 0x30, + 0x03, 0x5A, 0x04, 0xC2, 0x70, 0x89, 0x41, 0x83 + }, + { + 0x9D, 0xB0, 0xEF, 0x74, 0xE6, 0x6C, 0xBB, 0x84, + 0x2E, 0xB0, 0xE0, 0x73, 0x43, 0xA0, 0x3C, 0x5C, + 0x56, 0x7E, 0x37, 0x2B, 0x3F, 0x23, 0xB9, 0x43, + 0xC7, 0x88, 0xA4, 0xF2, 0x50, 0xF6, 0x78, 0x91 + }, + { + 0xAB, 0x8D, 0x08, 0x65, 0x5F, 0xF1, 0xD3, 0xFE, + 0x87, 0x58, 0xD5, 0x62, 0x23, 0x5F, 0xD2, 0x3E, + 0x7C, 0xF9, 0xDC, 0xAA, 0xD6, 0x58, 0x87, 0x2A, + 0x49, 0xE5, 0xD3, 0x18, 0x3B, 0x6C, 0xCE, 0xBD + }, + { + 0x6F, 0x27, 0xF7, 0x7E, 0x7B, 0xCF, 0x46, 0xA1, + 0xE9, 0x63, 0xAD, 0xE0, 0x30, 0x97, 0x33, 0x54, + 0x30, 0x31, 0xDC, 0xCD, 0xD4, 0x7C, 0xAA, 0xC1, + 0x74, 0xD7, 0xD2, 0x7C, 0xE8, 0x07, 0x7E, 0x8B + }, + { + 0xE3, 0xCD, 0x54, 0xDA, 0x7E, 0x44, 0x4C, 0xAA, + 0x62, 0x07, 0x56, 0x95, 0x25, 0xA6, 0x70, 0xEB, + 0xAE, 0x12, 0x78, 0xDE, 0x4E, 0x3F, 0xE2, 0x68, + 0x4B, 0x3E, 0x33, 0xF5, 0xEF, 0x90, 0xCC, 0x1B + }, + { + 0xB2, 0xC3, 0xE3, 0x3A, 0x51, 0xD2, 0x2C, 0x4C, + 0x08, 0xFC, 0x09, 0x89, 0xC8, 0x73, 0xC9, 0xCC, + 0x41, 0x50, 0x57, 0x9B, 0x1E, 0x61, 0x63, 0xFA, + 0x69, 0x4A, 0xD5, 0x1D, 0x53, 0xD7, 0x12, 0xDC + }, + { + 0xBE, 0x7F, 0xDA, 0x98, 0x3E, 0x13, 0x18, 0x9B, + 0x4C, 0x77, 0xE0, 0xA8, 0x09, 0x20, 0xB6, 0xE0, + 0xE0, 0xEA, 0x80, 0xC3, 0xB8, 0x4D, 0xBE, 0x7E, + 0x71, 0x17, 0xD2, 0x53, 0xF4, 0x81, 0x12, 0xF4 + }, + { + 0xB6, 0x00, 0x8C, 0x28, 0xFA, 0xE0, 0x8A, 0xA4, + 0x27, 0xE5, 0xBD, 0x3A, 0xAD, 0x36, 0xF1, 0x00, + 0x21, 0xF1, 0x6C, 0x77, 0xCF, 0xEA, 0xBE, 0xD0, + 0x7F, 0x97, 0xCC, 0x7D, 0xC1, 0xF1, 0x28, 0x4A + }, + { + 0x6E, 0x4E, 0x67, 0x60, 0xC5, 0x38, 0xF2, 0xE9, + 0x7B, 0x3A, 0xDB, 0xFB, 0xBC, 0xDE, 0x57, 0xF8, + 0x96, 0x6B, 0x7E, 0xA8, 0xFC, 0xB5, 0xBF, 0x7E, + 0xFE, 0xC9, 0x13, 0xFD, 0x2A, 0x2B, 0x0C, 0x55 + }, + { + 0x4A, 0xE5, 0x1F, 0xD1, 0x83, 0x4A, 0xA5, 0xBD, + 0x9A, 0x6F, 0x7E, 0xC3, 0x9F, 0xC6, 0x63, 0x33, + 0x8D, 0xC5, 0xD2, 0xE2, 0x07, 0x61, 0x56, 0x6D, + 0x90, 0xCC, 0x68, 0xB1, 0xCB, 0x87, 0x5E, 0xD8 + }, + { + 0xB6, 0x73, 0xAA, 0xD7, 0x5A, 0xB1, 0xFD, 0xB5, + 0x40, 0x1A, 0xBF, 0xA1, 0xBF, 0x89, 0xF3, 0xAD, + 0xD2, 0xEB, 0xC4, 0x68, 0xDF, 0x36, 0x24, 0xA4, + 0x78, 0xF4, 0xFE, 0x85, 0x9D, 0x8D, 0x55, 0xE2 + }, + { + 0x13, 0xC9, 0x47, 0x1A, 0x98, 0x55, 0x91, 0x35, + 0x39, 0x83, 0x66, 0x60, 0x39, 0x8D, 0xA0, 0xF3, + 0xF9, 0x9A, 0xDA, 0x08, 0x47, 0x9C, 0x69, 0xD1, + 0xB7, 0xFC, 0xAA, 0x34, 0x61, 0xDD, 0x7E, 0x59 + }, + { + 0x2C, 0x11, 0xF4, 0xA7, 0xF9, 0x9A, 0x1D, 0x23, + 0xA5, 0x8B, 0xB6, 0x36, 0x35, 0x0F, 0xE8, 0x49, + 0xF2, 0x9C, 0xBA, 0xC1, 0xB2, 0xA1, 0x11, 0x2D, + 0x9F, 0x1E, 0xD5, 0xBC, 0x5B, 0x31, 0x3C, 0xCD + }, + { + 0xC7, 0xD3, 0xC0, 0x70, 0x6B, 0x11, 0xAE, 0x74, + 0x1C, 0x05, 0xA1, 0xEF, 0x15, 0x0D, 0xD6, 0x5B, + 0x54, 0x94, 0xD6, 0xD5, 0x4C, 0x9A, 0x86, 0xE2, + 0x61, 0x78, 0x54, 0xE6, 0xAE, 0xEE, 0xBB, 0xD9 + }, + { + 0x19, 0x4E, 0x10, 0xC9, 0x38, 0x93, 0xAF, 0xA0, + 0x64, 0xC3, 0xAC, 0x04, 0xC0, 0xDD, 0x80, 0x8D, + 0x79, 0x1C, 0x3D, 0x4B, 0x75, 0x56, 0xE8, 0x9D, + 0x8D, 0x9C, 0xB2, 0x25, 0xC4, 0xB3, 0x33, 0x39 + }, + { + 0x6F, 0xC4, 0x98, 0x8B, 0x8F, 0x78, 0x54, 0x6B, + 0x16, 0x88, 0x99, 0x18, 0x45, 0x90, 0x8F, 0x13, + 0x4B, 0x6A, 0x48, 0x2E, 0x69, 0x94, 0xB3, 0xD4, + 0x83, 0x17, 0xBF, 0x08, 0xDB, 0x29, 0x21, 0x85 + }, + { + 0x56, 0x65, 0xBE, 0xB8, 0xB0, 0x95, 0x55, 0x25, + 0x81, 0x3B, 0x59, 0x81, 0xCD, 0x14, 0x2E, 0xD4, + 0xD0, 0x3F, 0xBA, 0x38, 0xA6, 0xF3, 0xE5, 0xAD, + 0x26, 0x8E, 0x0C, 0xC2, 0x70, 0xD1, 0xCD, 0x11 + }, + { + 0xB8, 0x83, 0xD6, 0x8F, 0x5F, 0xE5, 0x19, 0x36, + 0x43, 0x1B, 0xA4, 0x25, 0x67, 0x38, 0x05, 0x3B, + 0x1D, 0x04, 0x26, 0xD4, 0xCB, 0x64, 0xB1, 0x6E, + 0x83, 0xBA, 0xDC, 0x5E, 0x9F, 0xBE, 0x3B, 0x81 + }, + { + 0x53, 0xE7, 0xB2, 0x7E, 0xA5, 0x9C, 0x2F, 0x6D, + 0xBB, 0x50, 0x76, 0x9E, 0x43, 0x55, 0x4D, 0xF3, + 0x5A, 0xF8, 0x9F, 0x48, 0x22, 0xD0, 0x46, 0x6B, + 0x00, 0x7D, 0xD6, 0xF6, 0xDE, 0xAF, 0xFF, 0x02 + }, + { + 0x1F, 0x1A, 0x02, 0x29, 0xD4, 0x64, 0x0F, 0x01, + 0x90, 0x15, 0x88, 0xD9, 0xDE, 0xC2, 0x2D, 0x13, + 0xFC, 0x3E, 0xB3, 0x4A, 0x61, 0xB3, 0x29, 0x38, + 0xEF, 0xBF, 0x53, 0x34, 0xB2, 0x80, 0x0A, 0xFA + }, + { + 0xC2, 0xB4, 0x05, 0xAF, 0xA0, 0xFA, 0x66, 0x68, + 0x85, 0x2A, 0xEE, 0x4D, 0x88, 0x04, 0x08, 0x53, + 0xFA, 0xB8, 0x00, 0xE7, 0x2B, 0x57, 0x58, 0x14, + 0x18, 0xE5, 0x50, 0x6F, 0x21, 0x4C, 0x7D, 0x1F + }, + { + 0xC0, 0x8A, 0xA1, 0xC2, 0x86, 0xD7, 0x09, 0xFD, + 0xC7, 0x47, 0x37, 0x44, 0x97, 0x71, 0x88, 0xC8, + 0x95, 0xBA, 0x01, 0x10, 0x14, 0x24, 0x7E, 0x4E, + 0xFA, 0x8D, 0x07, 0xE7, 0x8F, 0xEC, 0x69, 0x5C + }, + { + 0xF0, 0x3F, 0x57, 0x89, 0xD3, 0x33, 0x6B, 0x80, + 0xD0, 0x02, 0xD5, 0x9F, 0xDF, 0x91, 0x8B, 0xDB, + 0x77, 0x5B, 0x00, 0x95, 0x6E, 0xD5, 0x52, 0x8E, + 0x86, 0xAA, 0x99, 0x4A, 0xCB, 0x38, 0xFE, 0x2D + }, +}; + + + + +static const uint8_t blake2s_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0x48, 0xA8, 0x99, 0x7D, 0xA4, 0x07, 0x87, 0x6B, + 0x3D, 0x79, 0xC0, 0xD9, 0x23, 0x25, 0xAD, 0x3B, + 0x89, 0xCB, 0xB7, 0x54, 0xD8, 0x6A, 0xB7, 0x1A, + 0xEE, 0x04, 0x7A, 0xD3, 0x45, 0xFD, 0x2C, 0x49 + }, + { + 0x40, 0xD1, 0x5F, 0xEE, 0x7C, 0x32, 0x88, 0x30, + 0x16, 0x6A, 0xC3, 0xF9, 0x18, 0x65, 0x0F, 0x80, + 0x7E, 0x7E, 0x01, 0xE1, 0x77, 0x25, 0x8C, 0xDC, + 0x0A, 0x39, 0xB1, 0x1F, 0x59, 0x80, 0x66, 0xF1 + }, + { + 0x6B, 0xB7, 0x13, 0x00, 0x64, 0x4C, 0xD3, 0x99, + 0x1B, 0x26, 0xCC, 0xD4, 0xD2, 0x74, 0xAC, 0xD1, + 0xAD, 0xEA, 0xB8, 0xB1, 0xD7, 0x91, 0x45, 0x46, + 0xC1, 0x19, 0x8B, 0xBE, 0x9F, 0xC9, 0xD8, 0x03 + }, + { + 0x1D, 0x22, 0x0D, 0xBE, 0x2E, 0xE1, 0x34, 0x66, + 0x1F, 0xDF, 0x6D, 0x9E, 0x74, 0xB4, 0x17, 0x04, + 0x71, 0x05, 0x56, 0xF2, 0xF6, 0xE5, 0xA0, 0x91, + 0xB2, 0x27, 0x69, 0x74, 0x45, 0xDB, 0xEA, 0x6B + }, + { + 0xF6, 0xC3, 0xFB, 0xAD, 0xB4, 0xCC, 0x68, 0x7A, + 0x00, 0x64, 0xA5, 0xBE, 0x6E, 0x79, 0x1B, 0xEC, + 0x63, 0xB8, 0x68, 0xAD, 0x62, 0xFB, 0xA6, 0x1B, + 0x37, 0x57, 0xEF, 0x9C, 0xA5, 0x2E, 0x05, 0xB2 + }, + { + 0x49, 0xC1, 0xF2, 0x11, 0x88, 0xDF, 0xD7, 0x69, + 0xAE, 0xA0, 0xE9, 0x11, 0xDD, 0x6B, 0x41, 0xF1, + 0x4D, 0xAB, 0x10, 0x9D, 0x2B, 0x85, 0x97, 0x7A, + 0xA3, 0x08, 0x8B, 0x5C, 0x70, 0x7E, 0x85, 0x98 + }, + { + 0xFD, 0xD8, 0x99, 0x3D, 0xCD, 0x43, 0xF6, 0x96, + 0xD4, 0x4F, 0x3C, 0xEA, 0x0F, 0xF3, 0x53, 0x45, + 0x23, 0x4E, 0xC8, 0xEE, 0x08, 0x3E, 0xB3, 0xCA, + 0xDA, 0x01, 0x7C, 0x7F, 0x78, 0xC1, 0x71, 0x43 + }, + { + 0xE6, 0xC8, 0x12, 0x56, 0x37, 0x43, 0x8D, 0x09, + 0x05, 0xB7, 0x49, 0xF4, 0x65, 0x60, 0xAC, 0x89, + 0xFD, 0x47, 0x1C, 0xF8, 0x69, 0x2E, 0x28, 0xFA, + 0xB9, 0x82, 0xF7, 0x3F, 0x01, 0x9B, 0x83, 0xA9 + }, + { + 0x19, 0xFC, 0x8C, 0xA6, 0x97, 0x9D, 0x60, 0xE6, + 0xED, 0xD3, 0xB4, 0x54, 0x1E, 0x2F, 0x96, 0x7C, + 0xED, 0x74, 0x0D, 0xF6, 0xEC, 0x1E, 0xAE, 0xBB, + 0xFE, 0x81, 0x38, 0x32, 0xE9, 0x6B, 0x29, 0x74 + }, + { + 0xA6, 0xAD, 0x77, 0x7C, 0xE8, 0x81, 0xB5, 0x2B, + 0xB5, 0xA4, 0x42, 0x1A, 0xB6, 0xCD, 0xD2, 0xDF, + 0xBA, 0x13, 0xE9, 0x63, 0x65, 0x2D, 0x4D, 0x6D, + 0x12, 0x2A, 0xEE, 0x46, 0x54, 0x8C, 0x14, 0xA7 + }, + { + 0xF5, 0xC4, 0xB2, 0xBA, 0x1A, 0x00, 0x78, 0x1B, + 0x13, 0xAB, 0xA0, 0x42, 0x52, 0x42, 0xC6, 0x9C, + 0xB1, 0x55, 0x2F, 0x3F, 0x71, 0xA9, 0xA3, 0xBB, + 0x22, 0xB4, 0xA6, 0xB4, 0x27, 0x7B, 0x46, 0xDD + }, + { + 0xE3, 0x3C, 0x4C, 0x9B, 0xD0, 0xCC, 0x7E, 0x45, + 0xC8, 0x0E, 0x65, 0xC7, 0x7F, 0xA5, 0x99, 0x7F, + 0xEC, 0x70, 0x02, 0x73, 0x85, 0x41, 0x50, 0x9E, + 0x68, 0xA9, 0x42, 0x38, 0x91, 0xE8, 0x22, 0xA3 + }, + { + 0xFB, 0xA1, 0x61, 0x69, 0xB2, 0xC3, 0xEE, 0x10, + 0x5B, 0xE6, 0xE1, 0xE6, 0x50, 0xE5, 0xCB, 0xF4, + 0x07, 0x46, 0xB6, 0x75, 0x3D, 0x03, 0x6A, 0xB5, + 0x51, 0x79, 0x01, 0x4A, 0xD7, 0xEF, 0x66, 0x51 + }, + { + 0xF5, 0xC4, 0xBE, 0xC6, 0xD6, 0x2F, 0xC6, 0x08, + 0xBF, 0x41, 0xCC, 0x11, 0x5F, 0x16, 0xD6, 0x1C, + 0x7E, 0xFD, 0x3F, 0xF6, 0xC6, 0x56, 0x92, 0xBB, + 0xE0, 0xAF, 0xFF, 0xB1, 0xFE, 0xDE, 0x74, 0x75 + }, + { + 0xA4, 0x86, 0x2E, 0x76, 0xDB, 0x84, 0x7F, 0x05, + 0xBA, 0x17, 0xED, 0xE5, 0xDA, 0x4E, 0x7F, 0x91, + 0xB5, 0x92, 0x5C, 0xF1, 0xAD, 0x4B, 0xA1, 0x27, + 0x32, 0xC3, 0x99, 0x57, 0x42, 0xA5, 0xCD, 0x6E + }, + { + 0x65, 0xF4, 0xB8, 0x60, 0xCD, 0x15, 0xB3, 0x8E, + 0xF8, 0x14, 0xA1, 0xA8, 0x04, 0x31, 0x4A, 0x55, + 0xBE, 0x95, 0x3C, 0xAA, 0x65, 0xFD, 0x75, 0x8A, + 0xD9, 0x89, 0xFF, 0x34, 0xA4, 0x1C, 0x1E, 0xEA + }, + { + 0x19, 0xBA, 0x23, 0x4F, 0x0A, 0x4F, 0x38, 0x63, + 0x7D, 0x18, 0x39, 0xF9, 0xD9, 0xF7, 0x6A, 0xD9, + 0x1C, 0x85, 0x22, 0x30, 0x71, 0x43, 0xC9, 0x7D, + 0x5F, 0x93, 0xF6, 0x92, 0x74, 0xCE, 0xC9, 0xA7 + }, + { + 0x1A, 0x67, 0x18, 0x6C, 0xA4, 0xA5, 0xCB, 0x8E, + 0x65, 0xFC, 0xA0, 0xE2, 0xEC, 0xBC, 0x5D, 0xDC, + 0x14, 0xAE, 0x38, 0x1B, 0xB8, 0xBF, 0xFE, 0xB9, + 0xE0, 0xA1, 0x03, 0x44, 0x9E, 0x3E, 0xF0, 0x3C + }, + { + 0xAF, 0xBE, 0xA3, 0x17, 0xB5, 0xA2, 0xE8, 0x9C, + 0x0B, 0xD9, 0x0C, 0xCF, 0x5D, 0x7F, 0xD0, 0xED, + 0x57, 0xFE, 0x58, 0x5E, 0x4B, 0xE3, 0x27, 0x1B, + 0x0A, 0x6B, 0xF0, 0xF5, 0x78, 0x6B, 0x0F, 0x26 + }, + { + 0xF1, 0xB0, 0x15, 0x58, 0xCE, 0x54, 0x12, 0x62, + 0xF5, 0xEC, 0x34, 0x29, 0x9D, 0x6F, 0xB4, 0x09, + 0x00, 0x09, 0xE3, 0x43, 0x4B, 0xE2, 0xF4, 0x91, + 0x05, 0xCF, 0x46, 0xAF, 0x4D, 0x2D, 0x41, 0x24 + }, + { + 0x13, 0xA0, 0xA0, 0xC8, 0x63, 0x35, 0x63, 0x5E, + 0xAA, 0x74, 0xCA, 0x2D, 0x5D, 0x48, 0x8C, 0x79, + 0x7B, 0xBB, 0x4F, 0x47, 0xDC, 0x07, 0x10, 0x50, + 0x15, 0xED, 0x6A, 0x1F, 0x33, 0x09, 0xEF, 0xCE + }, + { + 0x15, 0x80, 0xAF, 0xEE, 0xBE, 0xBB, 0x34, 0x6F, + 0x94, 0xD5, 0x9F, 0xE6, 0x2D, 0xA0, 0xB7, 0x92, + 0x37, 0xEA, 0xD7, 0xB1, 0x49, 0x1F, 0x56, 0x67, + 0xA9, 0x0E, 0x45, 0xED, 0xF6, 0xCA, 0x8B, 0x03 + }, + { + 0x20, 0xBE, 0x1A, 0x87, 0x5B, 0x38, 0xC5, 0x73, + 0xDD, 0x7F, 0xAA, 0xA0, 0xDE, 0x48, 0x9D, 0x65, + 0x5C, 0x11, 0xEF, 0xB6, 0xA5, 0x52, 0x69, 0x8E, + 0x07, 0xA2, 0xD3, 0x31, 0xB5, 0xF6, 0x55, 0xC3 + }, + { + 0xBE, 0x1F, 0xE3, 0xC4, 0xC0, 0x40, 0x18, 0xC5, + 0x4C, 0x4A, 0x0F, 0x6B, 0x9A, 0x2E, 0xD3, 0xC5, + 0x3A, 0xBE, 0x3A, 0x9F, 0x76, 0xB4, 0xD2, 0x6D, + 0xE5, 0x6F, 0xC9, 0xAE, 0x95, 0x05, 0x9A, 0x99 + }, + { + 0xE3, 0xE3, 0xAC, 0xE5, 0x37, 0xEB, 0x3E, 0xDD, + 0x84, 0x63, 0xD9, 0xAD, 0x35, 0x82, 0xE1, 0x3C, + 0xF8, 0x65, 0x33, 0xFF, 0xDE, 0x43, 0xD6, 0x68, + 0xDD, 0x2E, 0x93, 0xBB, 0xDB, 0xD7, 0x19, 0x5A + }, + { + 0x11, 0x0C, 0x50, 0xC0, 0xBF, 0x2C, 0x6E, 0x7A, + 0xEB, 0x7E, 0x43, 0x5D, 0x92, 0xD1, 0x32, 0xAB, + 0x66, 0x55, 0x16, 0x8E, 0x78, 0xA2, 0xDE, 0xCD, + 0xEC, 0x33, 0x30, 0x77, 0x76, 0x84, 0xD9, 0xC1 + }, + { + 0xE9, 0xBA, 0x8F, 0x50, 0x5C, 0x9C, 0x80, 0xC0, + 0x86, 0x66, 0xA7, 0x01, 0xF3, 0x36, 0x7E, 0x6C, + 0xC6, 0x65, 0xF3, 0x4B, 0x22, 0xE7, 0x3C, 0x3C, + 0x04, 0x17, 0xEB, 0x1C, 0x22, 0x06, 0x08, 0x2F + }, + { + 0x26, 0xCD, 0x66, 0xFC, 0xA0, 0x23, 0x79, 0xC7, + 0x6D, 0xF1, 0x23, 0x17, 0x05, 0x2B, 0xCA, 0xFD, + 0x6C, 0xD8, 0xC3, 0xA7, 0xB8, 0x90, 0xD8, 0x05, + 0xF3, 0x6C, 0x49, 0x98, 0x97, 0x82, 0x43, 0x3A + }, + { + 0x21, 0x3F, 0x35, 0x96, 0xD6, 0xE3, 0xA5, 0xD0, + 0xE9, 0x93, 0x2C, 0xD2, 0x15, 0x91, 0x46, 0x01, + 0x5E, 0x2A, 0xBC, 0x94, 0x9F, 0x47, 0x29, 0xEE, + 0x26, 0x32, 0xFE, 0x1E, 0xDB, 0x78, 0xD3, 0x37 + }, + { + 0x10, 0x15, 0xD7, 0x01, 0x08, 0xE0, 0x3B, 0xE1, + 0xC7, 0x02, 0xFE, 0x97, 0x25, 0x36, 0x07, 0xD1, + 0x4A, 0xEE, 0x59, 0x1F, 0x24, 0x13, 0xEA, 0x67, + 0x87, 0x42, 0x7B, 0x64, 0x59, 0xFF, 0x21, 0x9A + }, + { + 0x3C, 0xA9, 0x89, 0xDE, 0x10, 0xCF, 0xE6, 0x09, + 0x90, 0x94, 0x72, 0xC8, 0xD3, 0x56, 0x10, 0x80, + 0x5B, 0x2F, 0x97, 0x77, 0x34, 0xCF, 0x65, 0x2C, + 0xC6, 0x4B, 0x3B, 0xFC, 0x88, 0x2D, 0x5D, 0x89 + }, + { + 0xB6, 0x15, 0x6F, 0x72, 0xD3, 0x80, 0xEE, 0x9E, + 0xA6, 0xAC, 0xD1, 0x90, 0x46, 0x4F, 0x23, 0x07, + 0xA5, 0xC1, 0x79, 0xEF, 0x01, 0xFD, 0x71, 0xF9, + 0x9F, 0x2D, 0x0F, 0x7A, 0x57, 0x36, 0x0A, 0xEA + }, + { + 0xC0, 0x3B, 0xC6, 0x42, 0xB2, 0x09, 0x59, 0xCB, + 0xE1, 0x33, 0xA0, 0x30, 0x3E, 0x0C, 0x1A, 0xBF, + 0xF3, 0xE3, 0x1E, 0xC8, 0xE1, 0xA3, 0x28, 0xEC, + 0x85, 0x65, 0xC3, 0x6D, 0xEC, 0xFF, 0x52, 0x65 + }, + { + 0x2C, 0x3E, 0x08, 0x17, 0x6F, 0x76, 0x0C, 0x62, + 0x64, 0xC3, 0xA2, 0xCD, 0x66, 0xFE, 0xC6, 0xC3, + 0xD7, 0x8D, 0xE4, 0x3F, 0xC1, 0x92, 0x45, 0x7B, + 0x2A, 0x4A, 0x66, 0x0A, 0x1E, 0x0E, 0xB2, 0x2B + }, + { + 0xF7, 0x38, 0xC0, 0x2F, 0x3C, 0x1B, 0x19, 0x0C, + 0x51, 0x2B, 0x1A, 0x32, 0xDE, 0xAB, 0xF3, 0x53, + 0x72, 0x8E, 0x0E, 0x9A, 0xB0, 0x34, 0x49, 0x0E, + 0x3C, 0x34, 0x09, 0x94, 0x6A, 0x97, 0xAE, 0xEC + }, + { + 0x8B, 0x18, 0x80, 0xDF, 0x30, 0x1C, 0xC9, 0x63, + 0x41, 0x88, 0x11, 0x08, 0x89, 0x64, 0x83, 0x92, + 0x87, 0xFF, 0x7F, 0xE3, 0x1C, 0x49, 0xEA, 0x6E, + 0xBD, 0x9E, 0x48, 0xBD, 0xEE, 0xE4, 0x97, 0xC5 + }, + { + 0x1E, 0x75, 0xCB, 0x21, 0xC6, 0x09, 0x89, 0x02, + 0x03, 0x75, 0xF1, 0xA7, 0xA2, 0x42, 0x83, 0x9F, + 0x0B, 0x0B, 0x68, 0x97, 0x3A, 0x4C, 0x2A, 0x05, + 0xCF, 0x75, 0x55, 0xED, 0x5A, 0xAE, 0xC4, 0xC1 + }, + { + 0x62, 0xBF, 0x8A, 0x9C, 0x32, 0xA5, 0xBC, 0xCF, + 0x29, 0x0B, 0x6C, 0x47, 0x4D, 0x75, 0xB2, 0xA2, + 0xA4, 0x09, 0x3F, 0x1A, 0x9E, 0x27, 0x13, 0x94, + 0x33, 0xA8, 0xF2, 0xB3, 0xBC, 0xE7, 0xB8, 0xD7 + }, + { + 0x16, 0x6C, 0x83, 0x50, 0xD3, 0x17, 0x3B, 0x5E, + 0x70, 0x2B, 0x78, 0x3D, 0xFD, 0x33, 0xC6, 0x6E, + 0xE0, 0x43, 0x27, 0x42, 0xE9, 0xB9, 0x2B, 0x99, + 0x7F, 0xD2, 0x3C, 0x60, 0xDC, 0x67, 0x56, 0xCA + }, + { + 0x04, 0x4A, 0x14, 0xD8, 0x22, 0xA9, 0x0C, 0xAC, + 0xF2, 0xF5, 0xA1, 0x01, 0x42, 0x8A, 0xDC, 0x8F, + 0x41, 0x09, 0x38, 0x6C, 0xCB, 0x15, 0x8B, 0xF9, + 0x05, 0xC8, 0x61, 0x8B, 0x8E, 0xE2, 0x4E, 0xC3 + }, + { + 0x38, 0x7D, 0x39, 0x7E, 0xA4, 0x3A, 0x99, 0x4B, + 0xE8, 0x4D, 0x2D, 0x54, 0x4A, 0xFB, 0xE4, 0x81, + 0xA2, 0x00, 0x0F, 0x55, 0x25, 0x26, 0x96, 0xBB, + 0xA2, 0xC5, 0x0C, 0x8E, 0xBD, 0x10, 0x13, 0x47 + }, + { + 0x56, 0xF8, 0xCC, 0xF1, 0xF8, 0x64, 0x09, 0xB4, + 0x6C, 0xE3, 0x61, 0x66, 0xAE, 0x91, 0x65, 0x13, + 0x84, 0x41, 0x57, 0x75, 0x89, 0xDB, 0x08, 0xCB, + 0xC5, 0xF6, 0x6C, 0xA2, 0x97, 0x43, 0xB9, 0xFD + }, + { + 0x97, 0x06, 0xC0, 0x92, 0xB0, 0x4D, 0x91, 0xF5, + 0x3D, 0xFF, 0x91, 0xFA, 0x37, 0xB7, 0x49, 0x3D, + 0x28, 0xB5, 0x76, 0xB5, 0xD7, 0x10, 0x46, 0x9D, + 0xF7, 0x94, 0x01, 0x66, 0x22, 0x36, 0xFC, 0x03 + }, + { + 0x87, 0x79, 0x68, 0x68, 0x6C, 0x06, 0x8C, 0xE2, + 0xF7, 0xE2, 0xAD, 0xCF, 0xF6, 0x8B, 0xF8, 0x74, + 0x8E, 0xDF, 0x3C, 0xF8, 0x62, 0xCF, 0xB4, 0xD3, + 0x94, 0x7A, 0x31, 0x06, 0x95, 0x80, 0x54, 0xE3 + }, + { + 0x88, 0x17, 0xE5, 0x71, 0x98, 0x79, 0xAC, 0xF7, + 0x02, 0x47, 0x87, 0xEC, 0xCD, 0xB2, 0x71, 0x03, + 0x55, 0x66, 0xCF, 0xA3, 0x33, 0xE0, 0x49, 0x40, + 0x7C, 0x01, 0x78, 0xCC, 0xC5, 0x7A, 0x5B, 0x9F + }, + { + 0x89, 0x38, 0x24, 0x9E, 0x4B, 0x50, 0xCA, 0xDA, + 0xCC, 0xDF, 0x5B, 0x18, 0x62, 0x13, 0x26, 0xCB, + 0xB1, 0x52, 0x53, 0xE3, 0x3A, 0x20, 0xF5, 0x63, + 0x6E, 0x99, 0x5D, 0x72, 0x47, 0x8D, 0xE4, 0x72 + }, + { + 0xF1, 0x64, 0xAB, 0xBA, 0x49, 0x63, 0xA4, 0x4D, + 0x10, 0x72, 0x57, 0xE3, 0x23, 0x2D, 0x90, 0xAC, + 0xA5, 0xE6, 0x6A, 0x14, 0x08, 0x24, 0x8C, 0x51, + 0x74, 0x1E, 0x99, 0x1D, 0xB5, 0x22, 0x77, 0x56 + }, + { + 0xD0, 0x55, 0x63, 0xE2, 0xB1, 0xCB, 0xA0, 0xC4, + 0xA2, 0xA1, 0xE8, 0xBD, 0xE3, 0xA1, 0xA0, 0xD9, + 0xF5, 0xB4, 0x0C, 0x85, 0xA0, 0x70, 0xD6, 0xF5, + 0xFB, 0x21, 0x06, 0x6E, 0xAD, 0x5D, 0x06, 0x01 + }, + { + 0x03, 0xFB, 0xB1, 0x63, 0x84, 0xF0, 0xA3, 0x86, + 0x6F, 0x4C, 0x31, 0x17, 0x87, 0x76, 0x66, 0xEF, + 0xBF, 0x12, 0x45, 0x97, 0x56, 0x4B, 0x29, 0x3D, + 0x4A, 0xAB, 0x0D, 0x26, 0x9F, 0xAB, 0xDD, 0xFA + }, + { + 0x5F, 0xA8, 0x48, 0x6A, 0xC0, 0xE5, 0x29, 0x64, + 0xD1, 0x88, 0x1B, 0xBE, 0x33, 0x8E, 0xB5, 0x4B, + 0xE2, 0xF7, 0x19, 0x54, 0x92, 0x24, 0x89, 0x20, + 0x57, 0xB4, 0xDA, 0x04, 0xBA, 0x8B, 0x34, 0x75 + }, + { + 0xCD, 0xFA, 0xBC, 0xEE, 0x46, 0x91, 0x11, 0x11, + 0x23, 0x6A, 0x31, 0x70, 0x8B, 0x25, 0x39, 0xD7, + 0x1F, 0xC2, 0x11, 0xD9, 0xB0, 0x9C, 0x0D, 0x85, + 0x30, 0xA1, 0x1E, 0x1D, 0xBF, 0x6E, 0xED, 0x01 + }, + { + 0x4F, 0x82, 0xDE, 0x03, 0xB9, 0x50, 0x47, 0x93, + 0xB8, 0x2A, 0x07, 0xA0, 0xBD, 0xCD, 0xFF, 0x31, + 0x4D, 0x75, 0x9E, 0x7B, 0x62, 0xD2, 0x6B, 0x78, + 0x49, 0x46, 0xB0, 0xD3, 0x6F, 0x91, 0x6F, 0x52 + }, + { + 0x25, 0x9E, 0xC7, 0xF1, 0x73, 0xBC, 0xC7, 0x6A, + 0x09, 0x94, 0xC9, 0x67, 0xB4, 0xF5, 0xF0, 0x24, + 0xC5, 0x60, 0x57, 0xFB, 0x79, 0xC9, 0x65, 0xC4, + 0xFA, 0xE4, 0x18, 0x75, 0xF0, 0x6A, 0x0E, 0x4C + }, + { + 0x19, 0x3C, 0xC8, 0xE7, 0xC3, 0xE0, 0x8B, 0xB3, + 0x0F, 0x54, 0x37, 0xAA, 0x27, 0xAD, 0xE1, 0xF1, + 0x42, 0x36, 0x9B, 0x24, 0x6A, 0x67, 0x5B, 0x23, + 0x83, 0xE6, 0xDA, 0x9B, 0x49, 0xA9, 0x80, 0x9E + }, + { + 0x5C, 0x10, 0x89, 0x6F, 0x0E, 0x28, 0x56, 0xB2, + 0xA2, 0xEE, 0xE0, 0xFE, 0x4A, 0x2C, 0x16, 0x33, + 0x56, 0x5D, 0x18, 0xF0, 0xE9, 0x3E, 0x1F, 0xAB, + 0x26, 0xC3, 0x73, 0xE8, 0xF8, 0x29, 0x65, 0x4D + }, + { + 0xF1, 0x60, 0x12, 0xD9, 0x3F, 0x28, 0x85, 0x1A, + 0x1E, 0xB9, 0x89, 0xF5, 0xD0, 0xB4, 0x3F, 0x3F, + 0x39, 0xCA, 0x73, 0xC9, 0xA6, 0x2D, 0x51, 0x81, + 0xBF, 0xF2, 0x37, 0x53, 0x6B, 0xD3, 0x48, 0xC3 + }, + { + 0x29, 0x66, 0xB3, 0xCF, 0xAE, 0x1E, 0x44, 0xEA, + 0x99, 0x6D, 0xC5, 0xD6, 0x86, 0xCF, 0x25, 0xFA, + 0x05, 0x3F, 0xB6, 0xF6, 0x72, 0x01, 0xB9, 0xE4, + 0x6E, 0xAD, 0xE8, 0x5D, 0x0A, 0xD6, 0xB8, 0x06 + }, + { + 0xDD, 0xB8, 0x78, 0x24, 0x85, 0xE9, 0x00, 0xBC, + 0x60, 0xBC, 0xF4, 0xC3, 0x3A, 0x6F, 0xD5, 0x85, + 0x68, 0x0C, 0xC6, 0x83, 0xD5, 0x16, 0xEF, 0xA0, + 0x3E, 0xB9, 0x98, 0x5F, 0xAD, 0x87, 0x15, 0xFB + }, + { + 0x4C, 0x4D, 0x6E, 0x71, 0xAE, 0xA0, 0x57, 0x86, + 0x41, 0x31, 0x48, 0xFC, 0x7A, 0x78, 0x6B, 0x0E, + 0xCA, 0xF5, 0x82, 0xCF, 0xF1, 0x20, 0x9F, 0x5A, + 0x80, 0x9F, 0xBA, 0x85, 0x04, 0xCE, 0x66, 0x2C + }, + { + 0xFB, 0x4C, 0x5E, 0x86, 0xD7, 0xB2, 0x22, 0x9B, + 0x99, 0xB8, 0xBA, 0x6D, 0x94, 0xC2, 0x47, 0xEF, + 0x96, 0x4A, 0xA3, 0xA2, 0xBA, 0xE8, 0xED, 0xC7, + 0x75, 0x69, 0xF2, 0x8D, 0xBB, 0xFF, 0x2D, 0x4E + }, + { + 0xE9, 0x4F, 0x52, 0x6D, 0xE9, 0x01, 0x96, 0x33, + 0xEC, 0xD5, 0x4A, 0xC6, 0x12, 0x0F, 0x23, 0x95, + 0x8D, 0x77, 0x18, 0xF1, 0xE7, 0x71, 0x7B, 0xF3, + 0x29, 0x21, 0x1A, 0x4F, 0xAE, 0xED, 0x4E, 0x6D + }, + { + 0xCB, 0xD6, 0x66, 0x0A, 0x10, 0xDB, 0x3F, 0x23, + 0xF7, 0xA0, 0x3D, 0x4B, 0x9D, 0x40, 0x44, 0xC7, + 0x93, 0x2B, 0x28, 0x01, 0xAC, 0x89, 0xD6, 0x0B, + 0xC9, 0xEB, 0x92, 0xD6, 0x5A, 0x46, 0xC2, 0xA0 + }, + { + 0x88, 0x18, 0xBB, 0xD3, 0xDB, 0x4D, 0xC1, 0x23, + 0xB2, 0x5C, 0xBB, 0xA5, 0xF5, 0x4C, 0x2B, 0xC4, + 0xB3, 0xFC, 0xF9, 0xBF, 0x7D, 0x7A, 0x77, 0x09, + 0xF4, 0xAE, 0x58, 0x8B, 0x26, 0x7C, 0x4E, 0xCE + }, + { + 0xC6, 0x53, 0x82, 0x51, 0x3F, 0x07, 0x46, 0x0D, + 0xA3, 0x98, 0x33, 0xCB, 0x66, 0x6C, 0x5E, 0xD8, + 0x2E, 0x61, 0xB9, 0xE9, 0x98, 0xF4, 0xB0, 0xC4, + 0x28, 0x7C, 0xEE, 0x56, 0xC3, 0xCC, 0x9B, 0xCD + }, + { + 0x89, 0x75, 0xB0, 0x57, 0x7F, 0xD3, 0x55, 0x66, + 0xD7, 0x50, 0xB3, 0x62, 0xB0, 0x89, 0x7A, 0x26, + 0xC3, 0x99, 0x13, 0x6D, 0xF0, 0x7B, 0xAB, 0xAB, + 0xBD, 0xE6, 0x20, 0x3F, 0xF2, 0x95, 0x4E, 0xD4 + }, + { + 0x21, 0xFE, 0x0C, 0xEB, 0x00, 0x52, 0xBE, 0x7F, + 0xB0, 0xF0, 0x04, 0x18, 0x7C, 0xAC, 0xD7, 0xDE, + 0x67, 0xFA, 0x6E, 0xB0, 0x93, 0x8D, 0x92, 0x76, + 0x77, 0xF2, 0x39, 0x8C, 0x13, 0x23, 0x17, 0xA8 + }, + { + 0x2E, 0xF7, 0x3F, 0x3C, 0x26, 0xF1, 0x2D, 0x93, + 0x88, 0x9F, 0x3C, 0x78, 0xB6, 0xA6, 0x6C, 0x1D, + 0x52, 0xB6, 0x49, 0xDC, 0x9E, 0x85, 0x6E, 0x2C, + 0x17, 0x2E, 0xA7, 0xC5, 0x8A, 0xC2, 0xB5, 0xE3 + }, + { + 0x38, 0x8A, 0x3C, 0xD5, 0x6D, 0x73, 0x86, 0x7A, + 0xBB, 0x5F, 0x84, 0x01, 0x49, 0x2B, 0x6E, 0x26, + 0x81, 0xEB, 0x69, 0x85, 0x1E, 0x76, 0x7F, 0xD8, + 0x42, 0x10, 0xA5, 0x60, 0x76, 0xFB, 0x3D, 0xD3 + }, + { + 0xAF, 0x53, 0x3E, 0x02, 0x2F, 0xC9, 0x43, 0x9E, + 0x4E, 0x3C, 0xB8, 0x38, 0xEC, 0xD1, 0x86, 0x92, + 0x23, 0x2A, 0xDF, 0x6F, 0xE9, 0x83, 0x95, 0x26, + 0xD3, 0xC3, 0xDD, 0x1B, 0x71, 0x91, 0x0B, 0x1A + }, + { + 0x75, 0x1C, 0x09, 0xD4, 0x1A, 0x93, 0x43, 0x88, + 0x2A, 0x81, 0xCD, 0x13, 0xEE, 0x40, 0x81, 0x8D, + 0x12, 0xEB, 0x44, 0xC6, 0xC7, 0xF4, 0x0D, 0xF1, + 0x6E, 0x4A, 0xEA, 0x8F, 0xAB, 0x91, 0x97, 0x2A + }, + { + 0x5B, 0x73, 0xDD, 0xB6, 0x8D, 0x9D, 0x2B, 0x0A, + 0xA2, 0x65, 0xA0, 0x79, 0x88, 0xD6, 0xB8, 0x8A, + 0xE9, 0xAA, 0xC5, 0x82, 0xAF, 0x83, 0x03, 0x2F, + 0x8A, 0x9B, 0x21, 0xA2, 0xE1, 0xB7, 0xBF, 0x18 + }, + { + 0x3D, 0xA2, 0x91, 0x26, 0xC7, 0xC5, 0xD7, 0xF4, + 0x3E, 0x64, 0x24, 0x2A, 0x79, 0xFE, 0xAA, 0x4E, + 0xF3, 0x45, 0x9C, 0xDE, 0xCC, 0xC8, 0x98, 0xED, + 0x59, 0xA9, 0x7F, 0x6E, 0xC9, 0x3B, 0x9D, 0xAB + }, + { + 0x56, 0x6D, 0xC9, 0x20, 0x29, 0x3D, 0xA5, 0xCB, + 0x4F, 0xE0, 0xAA, 0x8A, 0xBD, 0xA8, 0xBB, 0xF5, + 0x6F, 0x55, 0x23, 0x13, 0xBF, 0xF1, 0x90, 0x46, + 0x64, 0x1E, 0x36, 0x15, 0xC1, 0xE3, 0xED, 0x3F + }, + { + 0x41, 0x15, 0xBE, 0xA0, 0x2F, 0x73, 0xF9, 0x7F, + 0x62, 0x9E, 0x5C, 0x55, 0x90, 0x72, 0x0C, 0x01, + 0xE7, 0xE4, 0x49, 0xAE, 0x2A, 0x66, 0x97, 0xD4, + 0xD2, 0x78, 0x33, 0x21, 0x30, 0x36, 0x92, 0xF9 + }, + { + 0x4C, 0xE0, 0x8F, 0x47, 0x62, 0x46, 0x8A, 0x76, + 0x70, 0x01, 0x21, 0x64, 0x87, 0x8D, 0x68, 0x34, + 0x0C, 0x52, 0xA3, 0x5E, 0x66, 0xC1, 0x88, 0x4D, + 0x5C, 0x86, 0x48, 0x89, 0xAB, 0xC9, 0x66, 0x77 + }, + { + 0x81, 0xEA, 0x0B, 0x78, 0x04, 0x12, 0x4E, 0x0C, + 0x22, 0xEA, 0x5F, 0xC7, 0x11, 0x04, 0xA2, 0xAF, + 0xCB, 0x52, 0xA1, 0xFA, 0x81, 0x6F, 0x3E, 0xCB, + 0x7D, 0xCB, 0x5D, 0x9D, 0xEA, 0x17, 0x86, 0xD0 + }, + { + 0xFE, 0x36, 0x27, 0x33, 0xB0, 0x5F, 0x6B, 0xED, + 0xAF, 0x93, 0x79, 0xD7, 0xF7, 0x93, 0x6E, 0xDE, + 0x20, 0x9B, 0x1F, 0x83, 0x23, 0xC3, 0x92, 0x25, + 0x49, 0xD9, 0xE7, 0x36, 0x81, 0xB5, 0xDB, 0x7B + }, + { + 0xEF, 0xF3, 0x7D, 0x30, 0xDF, 0xD2, 0x03, 0x59, + 0xBE, 0x4E, 0x73, 0xFD, 0xF4, 0x0D, 0x27, 0x73, + 0x4B, 0x3D, 0xF9, 0x0A, 0x97, 0xA5, 0x5E, 0xD7, + 0x45, 0x29, 0x72, 0x94, 0xCA, 0x85, 0xD0, 0x9F + }, + { + 0x17, 0x2F, 0xFC, 0x67, 0x15, 0x3D, 0x12, 0xE0, + 0xCA, 0x76, 0xA8, 0xB6, 0xCD, 0x5D, 0x47, 0x31, + 0x88, 0x5B, 0x39, 0xCE, 0x0C, 0xAC, 0x93, 0xA8, + 0x97, 0x2A, 0x18, 0x00, 0x6C, 0x8B, 0x8B, 0xAF + }, + { + 0xC4, 0x79, 0x57, 0xF1, 0xCC, 0x88, 0xE8, 0x3E, + 0xF9, 0x44, 0x58, 0x39, 0x70, 0x9A, 0x48, 0x0A, + 0x03, 0x6B, 0xED, 0x5F, 0x88, 0xAC, 0x0F, 0xCC, + 0x8E, 0x1E, 0x70, 0x3F, 0xFA, 0xAC, 0x13, 0x2C + }, + { + 0x30, 0xF3, 0x54, 0x83, 0x70, 0xCF, 0xDC, 0xED, + 0xA5, 0xC3, 0x7B, 0x56, 0x9B, 0x61, 0x75, 0xE7, + 0x99, 0xEE, 0xF1, 0xA6, 0x2A, 0xAA, 0x94, 0x32, + 0x45, 0xAE, 0x76, 0x69, 0xC2, 0x27, 0xA7, 0xB5 + }, + { + 0xC9, 0x5D, 0xCB, 0x3C, 0xF1, 0xF2, 0x7D, 0x0E, + 0xEF, 0x2F, 0x25, 0xD2, 0x41, 0x38, 0x70, 0x90, + 0x4A, 0x87, 0x7C, 0x4A, 0x56, 0xC2, 0xDE, 0x1E, + 0x83, 0xE2, 0xBC, 0x2A, 0xE2, 0xE4, 0x68, 0x21 + }, + { + 0xD5, 0xD0, 0xB5, 0xD7, 0x05, 0x43, 0x4C, 0xD4, + 0x6B, 0x18, 0x57, 0x49, 0xF6, 0x6B, 0xFB, 0x58, + 0x36, 0xDC, 0xDF, 0x6E, 0xE5, 0x49, 0xA2, 0xB7, + 0xA4, 0xAE, 0xE7, 0xF5, 0x80, 0x07, 0xCA, 0xAF + }, + { + 0xBB, 0xC1, 0x24, 0xA7, 0x12, 0xF1, 0x5D, 0x07, + 0xC3, 0x00, 0xE0, 0x5B, 0x66, 0x83, 0x89, 0xA4, + 0x39, 0xC9, 0x17, 0x77, 0xF7, 0x21, 0xF8, 0x32, + 0x0C, 0x1C, 0x90, 0x78, 0x06, 0x6D, 0x2C, 0x7E + }, + { + 0xA4, 0x51, 0xB4, 0x8C, 0x35, 0xA6, 0xC7, 0x85, + 0x4C, 0xFA, 0xAE, 0x60, 0x26, 0x2E, 0x76, 0x99, + 0x08, 0x16, 0x38, 0x2A, 0xC0, 0x66, 0x7E, 0x5A, + 0x5C, 0x9E, 0x1B, 0x46, 0xC4, 0x34, 0x2D, 0xDF + }, + { + 0xB0, 0xD1, 0x50, 0xFB, 0x55, 0xE7, 0x78, 0xD0, + 0x11, 0x47, 0xF0, 0xB5, 0xD8, 0x9D, 0x99, 0xEC, + 0xB2, 0x0F, 0xF0, 0x7E, 0x5E, 0x67, 0x60, 0xD6, + 0xB6, 0x45, 0xEB, 0x5B, 0x65, 0x4C, 0x62, 0x2B + }, + { + 0x34, 0xF7, 0x37, 0xC0, 0xAB, 0x21, 0x99, 0x51, + 0xEE, 0xE8, 0x9A, 0x9F, 0x8D, 0xAC, 0x29, 0x9C, + 0x9D, 0x4C, 0x38, 0xF3, 0x3F, 0xA4, 0x94, 0xC5, + 0xC6, 0xEE, 0xFC, 0x92, 0xB6, 0xDB, 0x08, 0xBC + }, + { + 0x1A, 0x62, 0xCC, 0x3A, 0x00, 0x80, 0x0D, 0xCB, + 0xD9, 0x98, 0x91, 0x08, 0x0C, 0x1E, 0x09, 0x84, + 0x58, 0x19, 0x3A, 0x8C, 0xC9, 0xF9, 0x70, 0xEA, + 0x99, 0xFB, 0xEF, 0xF0, 0x03, 0x18, 0xC2, 0x89 + }, + { + 0xCF, 0xCE, 0x55, 0xEB, 0xAF, 0xC8, 0x40, 0xD7, + 0xAE, 0x48, 0x28, 0x1C, 0x7F, 0xD5, 0x7E, 0xC8, + 0xB4, 0x82, 0xD4, 0xB7, 0x04, 0x43, 0x74, 0x95, + 0x49, 0x5A, 0xC4, 0x14, 0xCF, 0x4A, 0x37, 0x4B + }, + { + 0x67, 0x46, 0xFA, 0xCF, 0x71, 0x14, 0x6D, 0x99, + 0x9D, 0xAB, 0xD0, 0x5D, 0x09, 0x3A, 0xE5, 0x86, + 0x64, 0x8D, 0x1E, 0xE2, 0x8E, 0x72, 0x61, 0x7B, + 0x99, 0xD0, 0xF0, 0x08, 0x6E, 0x1E, 0x45, 0xBF + }, + { + 0x57, 0x1C, 0xED, 0x28, 0x3B, 0x3F, 0x23, 0xB4, + 0xE7, 0x50, 0xBF, 0x12, 0xA2, 0xCA, 0xF1, 0x78, + 0x18, 0x47, 0xBD, 0x89, 0x0E, 0x43, 0x60, 0x3C, + 0xDC, 0x59, 0x76, 0x10, 0x2B, 0x7B, 0xB1, 0x1B + }, + { + 0xCF, 0xCB, 0x76, 0x5B, 0x04, 0x8E, 0x35, 0x02, + 0x2C, 0x5D, 0x08, 0x9D, 0x26, 0xE8, 0x5A, 0x36, + 0xB0, 0x05, 0xA2, 0xB8, 0x04, 0x93, 0xD0, 0x3A, + 0x14, 0x4E, 0x09, 0xF4, 0x09, 0xB6, 0xAF, 0xD1 + }, + { + 0x40, 0x50, 0xC7, 0xA2, 0x77, 0x05, 0xBB, 0x27, + 0xF4, 0x20, 0x89, 0xB2, 0x99, 0xF3, 0xCB, 0xE5, + 0x05, 0x4E, 0xAD, 0x68, 0x72, 0x7E, 0x8E, 0xF9, + 0x31, 0x8C, 0xE6, 0xF2, 0x5C, 0xD6, 0xF3, 0x1D + }, + { + 0x18, 0x40, 0x70, 0xBD, 0x5D, 0x26, 0x5F, 0xBD, + 0xC1, 0x42, 0xCD, 0x1C, 0x5C, 0xD0, 0xD7, 0xE4, + 0x14, 0xE7, 0x03, 0x69, 0xA2, 0x66, 0xD6, 0x27, + 0xC8, 0xFB, 0xA8, 0x4F, 0xA5, 0xE8, 0x4C, 0x34 + }, + { + 0x9E, 0xDD, 0xA9, 0xA4, 0x44, 0x39, 0x02, 0xA9, + 0x58, 0x8C, 0x0D, 0x0C, 0xCC, 0x62, 0xB9, 0x30, + 0x21, 0x84, 0x79, 0xA6, 0x84, 0x1E, 0x6F, 0xE7, + 0xD4, 0x30, 0x03, 0xF0, 0x4B, 0x1F, 0xD6, 0x43 + }, + { + 0xE4, 0x12, 0xFE, 0xEF, 0x79, 0x08, 0x32, 0x4A, + 0x6D, 0xA1, 0x84, 0x16, 0x29, 0xF3, 0x5D, 0x3D, + 0x35, 0x86, 0x42, 0x01, 0x93, 0x10, 0xEC, 0x57, + 0xC6, 0x14, 0x83, 0x6B, 0x63, 0xD3, 0x07, 0x63 + }, + { + 0x1A, 0x2B, 0x8E, 0xDF, 0xF3, 0xF9, 0xAC, 0xC1, + 0x55, 0x4F, 0xCB, 0xAE, 0x3C, 0xF1, 0xD6, 0x29, + 0x8C, 0x64, 0x62, 0xE2, 0x2E, 0x5E, 0xB0, 0x25, + 0x96, 0x84, 0xF8, 0x35, 0x01, 0x2B, 0xD1, 0x3F + }, + { + 0x28, 0x8C, 0x4A, 0xD9, 0xB9, 0x40, 0x97, 0x62, + 0xEA, 0x07, 0xC2, 0x4A, 0x41, 0xF0, 0x4F, 0x69, + 0xA7, 0xD7, 0x4B, 0xEE, 0x2D, 0x95, 0x43, 0x53, + 0x74, 0xBD, 0xE9, 0x46, 0xD7, 0x24, 0x1C, 0x7B + }, + { + 0x80, 0x56, 0x91, 0xBB, 0x28, 0x67, 0x48, 0xCF, + 0xB5, 0x91, 0xD3, 0xAE, 0xBE, 0x7E, 0x6F, 0x4E, + 0x4D, 0xC6, 0xE2, 0x80, 0x8C, 0x65, 0x14, 0x3C, + 0xC0, 0x04, 0xE4, 0xEB, 0x6F, 0xD0, 0x9D, 0x43 + }, + { + 0xD4, 0xAC, 0x8D, 0x3A, 0x0A, 0xFC, 0x6C, 0xFA, + 0x7B, 0x46, 0x0A, 0xE3, 0x00, 0x1B, 0xAE, 0xB3, + 0x6D, 0xAD, 0xB3, 0x7D, 0xA0, 0x7D, 0x2E, 0x8A, + 0xC9, 0x18, 0x22, 0xDF, 0x34, 0x8A, 0xED, 0x3D + }, + { + 0xC3, 0x76, 0x61, 0x70, 0x14, 0xD2, 0x01, 0x58, + 0xBC, 0xED, 0x3D, 0x3B, 0xA5, 0x52, 0xB6, 0xEC, + 0xCF, 0x84, 0xE6, 0x2A, 0xA3, 0xEB, 0x65, 0x0E, + 0x90, 0x02, 0x9C, 0x84, 0xD1, 0x3E, 0xEA, 0x69 + }, + { + 0xC4, 0x1F, 0x09, 0xF4, 0x3C, 0xEC, 0xAE, 0x72, + 0x93, 0xD6, 0x00, 0x7C, 0xA0, 0xA3, 0x57, 0x08, + 0x7D, 0x5A, 0xE5, 0x9B, 0xE5, 0x00, 0xC1, 0xCD, + 0x5B, 0x28, 0x9E, 0xE8, 0x10, 0xC7, 0xB0, 0x82 + }, + { + 0x03, 0xD1, 0xCE, 0xD1, 0xFB, 0xA5, 0xC3, 0x91, + 0x55, 0xC4, 0x4B, 0x77, 0x65, 0xCB, 0x76, 0x0C, + 0x78, 0x70, 0x8D, 0xCF, 0xC8, 0x0B, 0x0B, 0xD8, + 0xAD, 0xE3, 0xA5, 0x6D, 0xA8, 0x83, 0x0B, 0x29 + }, + { + 0x09, 0xBD, 0xE6, 0xF1, 0x52, 0x21, 0x8D, 0xC9, + 0x2C, 0x41, 0xD7, 0xF4, 0x53, 0x87, 0xE6, 0x3E, + 0x58, 0x69, 0xD8, 0x07, 0xEC, 0x70, 0xB8, 0x21, + 0x40, 0x5D, 0xBD, 0x88, 0x4B, 0x7F, 0xCF, 0x4B + }, + { + 0x71, 0xC9, 0x03, 0x6E, 0x18, 0x17, 0x9B, 0x90, + 0xB3, 0x7D, 0x39, 0xE9, 0xF0, 0x5E, 0xB8, 0x9C, + 0xC5, 0xFC, 0x34, 0x1F, 0xD7, 0xC4, 0x77, 0xD0, + 0xD7, 0x49, 0x32, 0x85, 0xFA, 0xCA, 0x08, 0xA4 + }, + { + 0x59, 0x16, 0x83, 0x3E, 0xBB, 0x05, 0xCD, 0x91, + 0x9C, 0xA7, 0xFE, 0x83, 0xB6, 0x92, 0xD3, 0x20, + 0x5B, 0xEF, 0x72, 0x39, 0x2B, 0x2C, 0xF6, 0xBB, + 0x0A, 0x6D, 0x43, 0xF9, 0x94, 0xF9, 0x5F, 0x11 + }, + { + 0xF6, 0x3A, 0xAB, 0x3E, 0xC6, 0x41, 0xB3, 0xB0, + 0x24, 0x96, 0x4C, 0x2B, 0x43, 0x7C, 0x04, 0xF6, + 0x04, 0x3C, 0x4C, 0x7E, 0x02, 0x79, 0x23, 0x99, + 0x95, 0x40, 0x19, 0x58, 0xF8, 0x6B, 0xBE, 0x54 + }, + { + 0xF1, 0x72, 0xB1, 0x80, 0xBF, 0xB0, 0x97, 0x40, + 0x49, 0x31, 0x20, 0xB6, 0x32, 0x6C, 0xBD, 0xC5, + 0x61, 0xE4, 0x77, 0xDE, 0xF9, 0xBB, 0xCF, 0xD2, + 0x8C, 0xC8, 0xC1, 0xC5, 0xE3, 0x37, 0x9A, 0x31 + }, + { + 0xCB, 0x9B, 0x89, 0xCC, 0x18, 0x38, 0x1D, 0xD9, + 0x14, 0x1A, 0xDE, 0x58, 0x86, 0x54, 0xD4, 0xE6, + 0xA2, 0x31, 0xD5, 0xBF, 0x49, 0xD4, 0xD5, 0x9A, + 0xC2, 0x7D, 0x86, 0x9C, 0xBE, 0x10, 0x0C, 0xF3 + }, + { + 0x7B, 0xD8, 0x81, 0x50, 0x46, 0xFD, 0xD8, 0x10, + 0xA9, 0x23, 0xE1, 0x98, 0x4A, 0xAE, 0xBD, 0xCD, + 0xF8, 0x4D, 0x87, 0xC8, 0x99, 0x2D, 0x68, 0xB5, + 0xEE, 0xB4, 0x60, 0xF9, 0x3E, 0xB3, 0xC8, 0xD7 + }, + { + 0x60, 0x7B, 0xE6, 0x68, 0x62, 0xFD, 0x08, 0xEE, + 0x5B, 0x19, 0xFA, 0xCA, 0xC0, 0x9D, 0xFD, 0xBC, + 0xD4, 0x0C, 0x31, 0x21, 0x01, 0xD6, 0x6E, 0x6E, + 0xBD, 0x2B, 0x84, 0x1F, 0x1B, 0x9A, 0x93, 0x25 + }, + { + 0x9F, 0xE0, 0x3B, 0xBE, 0x69, 0xAB, 0x18, 0x34, + 0xF5, 0x21, 0x9B, 0x0D, 0xA8, 0x8A, 0x08, 0xB3, + 0x0A, 0x66, 0xC5, 0x91, 0x3F, 0x01, 0x51, 0x96, + 0x3C, 0x36, 0x05, 0x60, 0xDB, 0x03, 0x87, 0xB3 + }, + { + 0x90, 0xA8, 0x35, 0x85, 0x71, 0x7B, 0x75, 0xF0, + 0xE9, 0xB7, 0x25, 0xE0, 0x55, 0xEE, 0xEE, 0xB9, + 0xE7, 0xA0, 0x28, 0xEA, 0x7E, 0x6C, 0xBC, 0x07, + 0xB2, 0x09, 0x17, 0xEC, 0x03, 0x63, 0xE3, 0x8C + }, + { + 0x33, 0x6E, 0xA0, 0x53, 0x0F, 0x4A, 0x74, 0x69, + 0x12, 0x6E, 0x02, 0x18, 0x58, 0x7E, 0xBB, 0xDE, + 0x33, 0x58, 0xA0, 0xB3, 0x1C, 0x29, 0xD2, 0x00, + 0xF7, 0xDC, 0x7E, 0xB1, 0x5C, 0x6A, 0xAD, 0xD8 + }, + { + 0xA7, 0x9E, 0x76, 0xDC, 0x0A, 0xBC, 0xA4, 0x39, + 0x6F, 0x07, 0x47, 0xCD, 0x7B, 0x74, 0x8D, 0xF9, + 0x13, 0x00, 0x76, 0x26, 0xB1, 0xD6, 0x59, 0xDA, + 0x0C, 0x1F, 0x78, 0xB9, 0x30, 0x3D, 0x01, 0xA3 + }, + { + 0x44, 0xE7, 0x8A, 0x77, 0x37, 0x56, 0xE0, 0x95, + 0x15, 0x19, 0x50, 0x4D, 0x70, 0x38, 0xD2, 0x8D, + 0x02, 0x13, 0xA3, 0x7E, 0x0C, 0xE3, 0x75, 0x37, + 0x17, 0x57, 0xBC, 0x99, 0x63, 0x11, 0xE3, 0xB8 + }, + { + 0x77, 0xAC, 0x01, 0x2A, 0x3F, 0x75, 0x4D, 0xCF, + 0xEA, 0xB5, 0xEB, 0x99, 0x6B, 0xE9, 0xCD, 0x2D, + 0x1F, 0x96, 0x11, 0x1B, 0x6E, 0x49, 0xF3, 0x99, + 0x4D, 0xF1, 0x81, 0xF2, 0x85, 0x69, 0xD8, 0x25 + }, + { + 0xCE, 0x5A, 0x10, 0xDB, 0x6F, 0xCC, 0xDA, 0xF1, + 0x40, 0xAA, 0xA4, 0xDE, 0xD6, 0x25, 0x0A, 0x9C, + 0x06, 0xE9, 0x22, 0x2B, 0xC9, 0xF9, 0xF3, 0x65, + 0x8A, 0x4A, 0xFF, 0x93, 0x5F, 0x2B, 0x9F, 0x3A + }, + { + 0xEC, 0xC2, 0x03, 0xA7, 0xFE, 0x2B, 0xE4, 0xAB, + 0xD5, 0x5B, 0xB5, 0x3E, 0x6E, 0x67, 0x35, 0x72, + 0xE0, 0x07, 0x8D, 0xA8, 0xCD, 0x37, 0x5E, 0xF4, + 0x30, 0xCC, 0x97, 0xF9, 0xF8, 0x00, 0x83, 0xAF + }, + { + 0x14, 0xA5, 0x18, 0x6D, 0xE9, 0xD7, 0xA1, 0x8B, + 0x04, 0x12, 0xB8, 0x56, 0x3E, 0x51, 0xCC, 0x54, + 0x33, 0x84, 0x0B, 0x4A, 0x12, 0x9A, 0x8F, 0xF9, + 0x63, 0xB3, 0x3A, 0x3C, 0x4A, 0xFE, 0x8E, 0xBB + }, + { + 0x13, 0xF8, 0xEF, 0x95, 0xCB, 0x86, 0xE6, 0xA6, + 0x38, 0x93, 0x1C, 0x8E, 0x10, 0x76, 0x73, 0xEB, + 0x76, 0xBA, 0x10, 0xD7, 0xC2, 0xCD, 0x70, 0xB9, + 0xD9, 0x92, 0x0B, 0xBE, 0xED, 0x92, 0x94, 0x09 + }, + { + 0x0B, 0x33, 0x8F, 0x4E, 0xE1, 0x2F, 0x2D, 0xFC, + 0xB7, 0x87, 0x13, 0x37, 0x79, 0x41, 0xE0, 0xB0, + 0x63, 0x21, 0x52, 0x58, 0x1D, 0x13, 0x32, 0x51, + 0x6E, 0x4A, 0x2C, 0xAB, 0x19, 0x42, 0xCC, 0xA4 + }, + { + 0xEA, 0xAB, 0x0E, 0xC3, 0x7B, 0x3B, 0x8A, 0xB7, + 0x96, 0xE9, 0xF5, 0x72, 0x38, 0xDE, 0x14, 0xA2, + 0x64, 0xA0, 0x76, 0xF3, 0x88, 0x7D, 0x86, 0xE2, + 0x9B, 0xB5, 0x90, 0x6D, 0xB5, 0xA0, 0x0E, 0x02 + }, + { + 0x23, 0xCB, 0x68, 0xB8, 0xC0, 0xE6, 0xDC, 0x26, + 0xDC, 0x27, 0x76, 0x6D, 0xDC, 0x0A, 0x13, 0xA9, + 0x94, 0x38, 0xFD, 0x55, 0x61, 0x7A, 0xA4, 0x09, + 0x5D, 0x8F, 0x96, 0x97, 0x20, 0xC8, 0x72, 0xDF + }, + { + 0x09, 0x1D, 0x8E, 0xE3, 0x0D, 0x6F, 0x29, 0x68, + 0xD4, 0x6B, 0x68, 0x7D, 0xD6, 0x52, 0x92, 0x66, + 0x57, 0x42, 0xDE, 0x0B, 0xB8, 0x3D, 0xCC, 0x00, + 0x04, 0xC7, 0x2C, 0xE1, 0x00, 0x07, 0xA5, 0x49 + }, + { + 0x7F, 0x50, 0x7A, 0xBC, 0x6D, 0x19, 0xBA, 0x00, + 0xC0, 0x65, 0xA8, 0x76, 0xEC, 0x56, 0x57, 0x86, + 0x88, 0x82, 0xD1, 0x8A, 0x22, 0x1B, 0xC4, 0x6C, + 0x7A, 0x69, 0x12, 0x54, 0x1F, 0x5B, 0xC7, 0xBA + }, + { + 0xA0, 0x60, 0x7C, 0x24, 0xE1, 0x4E, 0x8C, 0x22, + 0x3D, 0xB0, 0xD7, 0x0B, 0x4D, 0x30, 0xEE, 0x88, + 0x01, 0x4D, 0x60, 0x3F, 0x43, 0x7E, 0x9E, 0x02, + 0xAA, 0x7D, 0xAF, 0xA3, 0xCD, 0xFB, 0xAD, 0x94 + }, + { + 0xDD, 0xBF, 0xEA, 0x75, 0xCC, 0x46, 0x78, 0x82, + 0xEB, 0x34, 0x83, 0xCE, 0x5E, 0x2E, 0x75, 0x6A, + 0x4F, 0x47, 0x01, 0xB7, 0x6B, 0x44, 0x55, 0x19, + 0xE8, 0x9F, 0x22, 0xD6, 0x0F, 0xA8, 0x6E, 0x06 + }, + { + 0x0C, 0x31, 0x1F, 0x38, 0xC3, 0x5A, 0x4F, 0xB9, + 0x0D, 0x65, 0x1C, 0x28, 0x9D, 0x48, 0x68, 0x56, + 0xCD, 0x14, 0x13, 0xDF, 0x9B, 0x06, 0x77, 0xF5, + 0x3E, 0xCE, 0x2C, 0xD9, 0xE4, 0x77, 0xC6, 0x0A + }, + { + 0x46, 0xA7, 0x3A, 0x8D, 0xD3, 0xE7, 0x0F, 0x59, + 0xD3, 0x94, 0x2C, 0x01, 0xDF, 0x59, 0x9D, 0xEF, + 0x78, 0x3C, 0x9D, 0xA8, 0x2F, 0xD8, 0x32, 0x22, + 0xCD, 0x66, 0x2B, 0x53, 0xDC, 0xE7, 0xDB, 0xDF + }, + { + 0xAD, 0x03, 0x8F, 0xF9, 0xB1, 0x4D, 0xE8, 0x4A, + 0x80, 0x1E, 0x4E, 0x62, 0x1C, 0xE5, 0xDF, 0x02, + 0x9D, 0xD9, 0x35, 0x20, 0xD0, 0xC2, 0xFA, 0x38, + 0xBF, 0xF1, 0x76, 0xA8, 0xB1, 0xD1, 0x69, 0x8C + }, + { + 0xAB, 0x70, 0xC5, 0xDF, 0xBD, 0x1E, 0xA8, 0x17, + 0xFE, 0xD0, 0xCD, 0x06, 0x72, 0x93, 0xAB, 0xF3, + 0x19, 0xE5, 0xD7, 0x90, 0x1C, 0x21, 0x41, 0xD5, + 0xD9, 0x9B, 0x23, 0xF0, 0x3A, 0x38, 0xE7, 0x48 + }, + { + 0x1F, 0xFF, 0xDA, 0x67, 0x93, 0x2B, 0x73, 0xC8, + 0xEC, 0xAF, 0x00, 0x9A, 0x34, 0x91, 0xA0, 0x26, + 0x95, 0x3B, 0xAB, 0xFE, 0x1F, 0x66, 0x3B, 0x06, + 0x97, 0xC3, 0xC4, 0xAE, 0x8B, 0x2E, 0x7D, 0xCB + }, + { + 0xB0, 0xD2, 0xCC, 0x19, 0x47, 0x2D, 0xD5, 0x7F, + 0x2B, 0x17, 0xEF, 0xC0, 0x3C, 0x8D, 0x58, 0xC2, + 0x28, 0x3D, 0xBB, 0x19, 0xDA, 0x57, 0x2F, 0x77, + 0x55, 0x85, 0x5A, 0xA9, 0x79, 0x43, 0x17, 0xA0 + }, + { + 0xA0, 0xD1, 0x9A, 0x6E, 0xE3, 0x39, 0x79, 0xC3, + 0x25, 0x51, 0x0E, 0x27, 0x66, 0x22, 0xDF, 0x41, + 0xF7, 0x15, 0x83, 0xD0, 0x75, 0x01, 0xB8, 0x70, + 0x71, 0x12, 0x9A, 0x0A, 0xD9, 0x47, 0x32, 0xA5 + }, + { + 0x72, 0x46, 0x42, 0xA7, 0x03, 0x2D, 0x10, 0x62, + 0xB8, 0x9E, 0x52, 0xBE, 0xA3, 0x4B, 0x75, 0xDF, + 0x7D, 0x8F, 0xE7, 0x72, 0xD9, 0xFE, 0x3C, 0x93, + 0xDD, 0xF3, 0xC4, 0x54, 0x5A, 0xB5, 0xA9, 0x9B + }, + { + 0xAD, 0xE5, 0xEA, 0xA7, 0xE6, 0x1F, 0x67, 0x2D, + 0x58, 0x7E, 0xA0, 0x3D, 0xAE, 0x7D, 0x7B, 0x55, + 0x22, 0x9C, 0x01, 0xD0, 0x6B, 0xC0, 0xA5, 0x70, + 0x14, 0x36, 0xCB, 0xD1, 0x83, 0x66, 0xA6, 0x26 + }, + { + 0x01, 0x3B, 0x31, 0xEB, 0xD2, 0x28, 0xFC, 0xDD, + 0xA5, 0x1F, 0xAB, 0xB0, 0x3B, 0xB0, 0x2D, 0x60, + 0xAC, 0x20, 0xCA, 0x21, 0x5A, 0xAF, 0xA8, 0x3B, + 0xDD, 0x85, 0x5E, 0x37, 0x55, 0xA3, 0x5F, 0x0B + }, + { + 0x33, 0x2E, 0xD4, 0x0B, 0xB1, 0x0D, 0xDE, 0x3C, + 0x95, 0x4A, 0x75, 0xD7, 0xB8, 0x99, 0x9D, 0x4B, + 0x26, 0xA1, 0xC0, 0x63, 0xC1, 0xDC, 0x6E, 0x32, + 0xC1, 0xD9, 0x1B, 0xAB, 0x7B, 0xBB, 0x7D, 0x16 + }, + { + 0xC7, 0xA1, 0x97, 0xB3, 0xA0, 0x5B, 0x56, 0x6B, + 0xCC, 0x9F, 0xAC, 0xD2, 0x0E, 0x44, 0x1D, 0x6F, + 0x6C, 0x28, 0x60, 0xAC, 0x96, 0x51, 0xCD, 0x51, + 0xD6, 0xB9, 0xD2, 0xCD, 0xEE, 0xEA, 0x03, 0x90 + }, + { + 0xBD, 0x9C, 0xF6, 0x4E, 0xA8, 0x95, 0x3C, 0x03, + 0x71, 0x08, 0xE6, 0xF6, 0x54, 0x91, 0x4F, 0x39, + 0x58, 0xB6, 0x8E, 0x29, 0xC1, 0x67, 0x00, 0xDC, + 0x18, 0x4D, 0x94, 0xA2, 0x17, 0x08, 0xFF, 0x60 + }, + { + 0x88, 0x35, 0xB0, 0xAC, 0x02, 0x11, 0x51, 0xDF, + 0x71, 0x64, 0x74, 0xCE, 0x27, 0xCE, 0x4D, 0x3C, + 0x15, 0xF0, 0xB2, 0xDA, 0xB4, 0x80, 0x03, 0xCF, + 0x3F, 0x3E, 0xFD, 0x09, 0x45, 0x10, 0x6B, 0x9A + }, + { + 0x3B, 0xFE, 0xFA, 0x33, 0x01, 0xAA, 0x55, 0xC0, + 0x80, 0x19, 0x0C, 0xFF, 0xDA, 0x8E, 0xAE, 0x51, + 0xD9, 0xAF, 0x48, 0x8B, 0x4C, 0x1F, 0x24, 0xC3, + 0xD9, 0xA7, 0x52, 0x42, 0xFD, 0x8E, 0xA0, 0x1D + }, + { + 0x08, 0x28, 0x4D, 0x14, 0x99, 0x3C, 0xD4, 0x7D, + 0x53, 0xEB, 0xAE, 0xCF, 0x0D, 0xF0, 0x47, 0x8C, + 0xC1, 0x82, 0xC8, 0x9C, 0x00, 0xE1, 0x85, 0x9C, + 0x84, 0x85, 0x16, 0x86, 0xDD, 0xF2, 0xC1, 0xB7 + }, + { + 0x1E, 0xD7, 0xEF, 0x9F, 0x04, 0xC2, 0xAC, 0x8D, + 0xB6, 0xA8, 0x64, 0xDB, 0x13, 0x10, 0x87, 0xF2, + 0x70, 0x65, 0x09, 0x8E, 0x69, 0xC3, 0xFE, 0x78, + 0x71, 0x8D, 0x9B, 0x94, 0x7F, 0x4A, 0x39, 0xD0 + }, + { + 0xC1, 0x61, 0xF2, 0xDC, 0xD5, 0x7E, 0x9C, 0x14, + 0x39, 0xB3, 0x1A, 0x9D, 0xD4, 0x3D, 0x8F, 0x3D, + 0x7D, 0xD8, 0xF0, 0xEB, 0x7C, 0xFA, 0xC6, 0xFB, + 0x25, 0xA0, 0xF2, 0x8E, 0x30, 0x6F, 0x06, 0x61 + }, + { + 0xC0, 0x19, 0x69, 0xAD, 0x34, 0xC5, 0x2C, 0xAF, + 0x3D, 0xC4, 0xD8, 0x0D, 0x19, 0x73, 0x5C, 0x29, + 0x73, 0x1A, 0xC6, 0xE7, 0xA9, 0x20, 0x85, 0xAB, + 0x92, 0x50, 0xC4, 0x8D, 0xEA, 0x48, 0xA3, 0xFC + }, + { + 0x17, 0x20, 0xB3, 0x65, 0x56, 0x19, 0xD2, 0xA5, + 0x2B, 0x35, 0x21, 0xAE, 0x0E, 0x49, 0xE3, 0x45, + 0xCB, 0x33, 0x89, 0xEB, 0xD6, 0x20, 0x8A, 0xCA, + 0xF9, 0xF1, 0x3F, 0xDA, 0xCC, 0xA8, 0xBE, 0x49 + }, + { + 0x75, 0x62, 0x88, 0x36, 0x1C, 0x83, 0xE2, 0x4C, + 0x61, 0x7C, 0xF9, 0x5C, 0x90, 0x5B, 0x22, 0xD0, + 0x17, 0xCD, 0xC8, 0x6F, 0x0B, 0xF1, 0xD6, 0x58, + 0xF4, 0x75, 0x6C, 0x73, 0x79, 0x87, 0x3B, 0x7F + }, + { + 0xE7, 0xD0, 0xED, 0xA3, 0x45, 0x26, 0x93, 0xB7, + 0x52, 0xAB, 0xCD, 0xA1, 0xB5, 0x5E, 0x27, 0x6F, + 0x82, 0x69, 0x8F, 0x5F, 0x16, 0x05, 0x40, 0x3E, + 0xFF, 0x83, 0x0B, 0xEA, 0x00, 0x71, 0xA3, 0x94 + }, + { + 0x2C, 0x82, 0xEC, 0xAA, 0x6B, 0x84, 0x80, 0x3E, + 0x04, 0x4A, 0xF6, 0x31, 0x18, 0xAF, 0xE5, 0x44, + 0x68, 0x7C, 0xB6, 0xE6, 0xC7, 0xDF, 0x49, 0xED, + 0x76, 0x2D, 0xFD, 0x7C, 0x86, 0x93, 0xA1, 0xBC + }, + { + 0x61, 0x36, 0xCB, 0xF4, 0xB4, 0x41, 0x05, 0x6F, + 0xA1, 0xE2, 0x72, 0x24, 0x98, 0x12, 0x5D, 0x6D, + 0xED, 0x45, 0xE1, 0x7B, 0x52, 0x14, 0x39, 0x59, + 0xC7, 0xF4, 0xD4, 0xE3, 0x95, 0x21, 0x8A, 0xC2 + }, + { + 0x72, 0x1D, 0x32, 0x45, 0xAA, 0xFE, 0xF2, 0x7F, + 0x6A, 0x62, 0x4F, 0x47, 0x95, 0x4B, 0x6C, 0x25, + 0x50, 0x79, 0x52, 0x6F, 0xFA, 0x25, 0xE9, 0xFF, + 0x77, 0xE5, 0xDC, 0xFF, 0x47, 0x3B, 0x15, 0x97 + }, + { + 0x9D, 0xD2, 0xFB, 0xD8, 0xCE, 0xF1, 0x6C, 0x35, + 0x3C, 0x0A, 0xC2, 0x11, 0x91, 0xD5, 0x09, 0xEB, + 0x28, 0xDD, 0x9E, 0x3E, 0x0D, 0x8C, 0xEA, 0x5D, + 0x26, 0xCA, 0x83, 0x93, 0x93, 0x85, 0x1C, 0x3A + }, + { + 0xB2, 0x39, 0x4C, 0xEA, 0xCD, 0xEB, 0xF2, 0x1B, + 0xF9, 0xDF, 0x2C, 0xED, 0x98, 0xE5, 0x8F, 0x1C, + 0x3A, 0x4B, 0xBB, 0xFF, 0x66, 0x0D, 0xD9, 0x00, + 0xF6, 0x22, 0x02, 0xD6, 0x78, 0x5C, 0xC4, 0x6E + }, + { + 0x57, 0x08, 0x9F, 0x22, 0x27, 0x49, 0xAD, 0x78, + 0x71, 0x76, 0x5F, 0x06, 0x2B, 0x11, 0x4F, 0x43, + 0xBA, 0x20, 0xEC, 0x56, 0x42, 0x2A, 0x8B, 0x1E, + 0x3F, 0x87, 0x19, 0x2C, 0x0E, 0xA7, 0x18, 0xC6 + }, + { + 0xE4, 0x9A, 0x94, 0x59, 0x96, 0x1C, 0xD3, 0x3C, + 0xDF, 0x4A, 0xAE, 0x1B, 0x10, 0x78, 0xA5, 0xDE, + 0xA7, 0xC0, 0x40, 0xE0, 0xFE, 0xA3, 0x40, 0xC9, + 0x3A, 0x72, 0x48, 0x72, 0xFC, 0x4A, 0xF8, 0x06 + }, + { + 0xED, 0xE6, 0x7F, 0x72, 0x0E, 0xFF, 0xD2, 0xCA, + 0x9C, 0x88, 0x99, 0x41, 0x52, 0xD0, 0x20, 0x1D, + 0xEE, 0x6B, 0x0A, 0x2D, 0x2C, 0x07, 0x7A, 0xCA, + 0x6D, 0xAE, 0x29, 0xF7, 0x3F, 0x8B, 0x63, 0x09 + }, + { + 0xE0, 0xF4, 0x34, 0xBF, 0x22, 0xE3, 0x08, 0x80, + 0x39, 0xC2, 0x1F, 0x71, 0x9F, 0xFC, 0x67, 0xF0, + 0xF2, 0xCB, 0x5E, 0x98, 0xA7, 0xA0, 0x19, 0x4C, + 0x76, 0xE9, 0x6B, 0xF4, 0xE8, 0xE1, 0x7E, 0x61 + }, + { + 0x27, 0x7C, 0x04, 0xE2, 0x85, 0x34, 0x84, 0xA4, + 0xEB, 0xA9, 0x10, 0xAD, 0x33, 0x6D, 0x01, 0xB4, + 0x77, 0xB6, 0x7C, 0xC2, 0x00, 0xC5, 0x9F, 0x3C, + 0x8D, 0x77, 0xEE, 0xF8, 0x49, 0x4F, 0x29, 0xCD + }, + { + 0x15, 0x6D, 0x57, 0x47, 0xD0, 0xC9, 0x9C, 0x7F, + 0x27, 0x09, 0x7D, 0x7B, 0x7E, 0x00, 0x2B, 0x2E, + 0x18, 0x5C, 0xB7, 0x2D, 0x8D, 0xD7, 0xEB, 0x42, + 0x4A, 0x03, 0x21, 0x52, 0x81, 0x61, 0x21, 0x9F + }, + { + 0x20, 0xDD, 0xD1, 0xED, 0x9B, 0x1C, 0xA8, 0x03, + 0x94, 0x6D, 0x64, 0xA8, 0x3A, 0xE4, 0x65, 0x9D, + 0xA6, 0x7F, 0xBA, 0x7A, 0x1A, 0x3E, 0xDD, 0xB1, + 0xE1, 0x03, 0xC0, 0xF5, 0xE0, 0x3E, 0x3A, 0x2C + }, + { + 0xF0, 0xAF, 0x60, 0x4D, 0x3D, 0xAB, 0xBF, 0x9A, + 0x0F, 0x2A, 0x7D, 0x3D, 0xDA, 0x6B, 0xD3, 0x8B, + 0xBA, 0x72, 0xC6, 0xD0, 0x9B, 0xE4, 0x94, 0xFC, + 0xEF, 0x71, 0x3F, 0xF1, 0x01, 0x89, 0xB6, 0xE6 + }, + { + 0x98, 0x02, 0xBB, 0x87, 0xDE, 0xF4, 0xCC, 0x10, + 0xC4, 0xA5, 0xFD, 0x49, 0xAA, 0x58, 0xDF, 0xE2, + 0xF3, 0xFD, 0xDB, 0x46, 0xB4, 0x70, 0x88, 0x14, + 0xEA, 0xD8, 0x1D, 0x23, 0xBA, 0x95, 0x13, 0x9B + }, + { + 0x4F, 0x8C, 0xE1, 0xE5, 0x1D, 0x2F, 0xE7, 0xF2, + 0x40, 0x43, 0xA9, 0x04, 0xD8, 0x98, 0xEB, 0xFC, + 0x91, 0x97, 0x54, 0x18, 0x75, 0x34, 0x13, 0xAA, + 0x09, 0x9B, 0x79, 0x5E, 0xCB, 0x35, 0xCE, 0xDB + }, + { + 0xBD, 0xDC, 0x65, 0x14, 0xD7, 0xEE, 0x6A, 0xCE, + 0x0A, 0x4A, 0xC1, 0xD0, 0xE0, 0x68, 0x11, 0x22, + 0x88, 0xCB, 0xCF, 0x56, 0x04, 0x54, 0x64, 0x27, + 0x05, 0x63, 0x01, 0x77, 0xCB, 0xA6, 0x08, 0xBD + }, + { + 0xD6, 0x35, 0x99, 0x4F, 0x62, 0x91, 0x51, 0x7B, + 0x02, 0x81, 0xFF, 0xDD, 0x49, 0x6A, 0xFA, 0x86, + 0x27, 0x12, 0xE5, 0xB3, 0xC4, 0xE5, 0x2E, 0x4C, + 0xD5, 0xFD, 0xAE, 0x8C, 0x0E, 0x72, 0xFB, 0x08 + }, + { + 0x87, 0x8D, 0x9C, 0xA6, 0x00, 0xCF, 0x87, 0xE7, + 0x69, 0xCC, 0x30, 0x5C, 0x1B, 0x35, 0x25, 0x51, + 0x86, 0x61, 0x5A, 0x73, 0xA0, 0xDA, 0x61, 0x3B, + 0x5F, 0x1C, 0x98, 0xDB, 0xF8, 0x12, 0x83, 0xEA + }, + { + 0xA6, 0x4E, 0xBE, 0x5D, 0xC1, 0x85, 0xDE, 0x9F, + 0xDD, 0xE7, 0x60, 0x7B, 0x69, 0x98, 0x70, 0x2E, + 0xB2, 0x34, 0x56, 0x18, 0x49, 0x57, 0x30, 0x7D, + 0x2F, 0xA7, 0x2E, 0x87, 0xA4, 0x77, 0x02, 0xD6 + }, + { + 0xCE, 0x50, 0xEA, 0xB7, 0xB5, 0xEB, 0x52, 0xBD, + 0xC9, 0xAD, 0x8E, 0x5A, 0x48, 0x0A, 0xB7, 0x80, + 0xCA, 0x93, 0x20, 0xE4, 0x43, 0x60, 0xB1, 0xFE, + 0x37, 0xE0, 0x3F, 0x2F, 0x7A, 0xD7, 0xDE, 0x01 + }, + { + 0xEE, 0xDD, 0xB7, 0xC0, 0xDB, 0x6E, 0x30, 0xAB, + 0xE6, 0x6D, 0x79, 0xE3, 0x27, 0x51, 0x1E, 0x61, + 0xFC, 0xEB, 0xBC, 0x29, 0xF1, 0x59, 0xB4, 0x0A, + 0x86, 0xB0, 0x46, 0xEC, 0xF0, 0x51, 0x38, 0x23 + }, + { + 0x78, 0x7F, 0xC9, 0x34, 0x40, 0xC1, 0xEC, 0x96, + 0xB5, 0xAD, 0x01, 0xC1, 0x6C, 0xF7, 0x79, 0x16, + 0xA1, 0x40, 0x5F, 0x94, 0x26, 0x35, 0x6E, 0xC9, + 0x21, 0xD8, 0xDF, 0xF3, 0xEA, 0x63, 0xB7, 0xE0 + }, + { + 0x7F, 0x0D, 0x5E, 0xAB, 0x47, 0xEE, 0xFD, 0xA6, + 0x96, 0xC0, 0xBF, 0x0F, 0xBF, 0x86, 0xAB, 0x21, + 0x6F, 0xCE, 0x46, 0x1E, 0x93, 0x03, 0xAB, 0xA6, + 0xAC, 0x37, 0x41, 0x20, 0xE8, 0x90, 0xE8, 0xDF + }, + { + 0xB6, 0x80, 0x04, 0xB4, 0x2F, 0x14, 0xAD, 0x02, + 0x9F, 0x4C, 0x2E, 0x03, 0xB1, 0xD5, 0xEB, 0x76, + 0xD5, 0x71, 0x60, 0xE2, 0x64, 0x76, 0xD2, 0x11, + 0x31, 0xBE, 0xF2, 0x0A, 0xDA, 0x7D, 0x27, 0xF4 + }, + { + 0xB0, 0xC4, 0xEB, 0x18, 0xAE, 0x25, 0x0B, 0x51, + 0xA4, 0x13, 0x82, 0xEA, 0xD9, 0x2D, 0x0D, 0xC7, + 0x45, 0x5F, 0x93, 0x79, 0xFC, 0x98, 0x84, 0x42, + 0x8E, 0x47, 0x70, 0x60, 0x8D, 0xB0, 0xFA, 0xEC + }, + { + 0xF9, 0x2B, 0x7A, 0x87, 0x0C, 0x05, 0x9F, 0x4D, + 0x46, 0x46, 0x4C, 0x82, 0x4E, 0xC9, 0x63, 0x55, + 0x14, 0x0B, 0xDC, 0xE6, 0x81, 0x32, 0x2C, 0xC3, + 0xA9, 0x92, 0xFF, 0x10, 0x3E, 0x3F, 0xEA, 0x52 + }, + { + 0x53, 0x64, 0x31, 0x26, 0x14, 0x81, 0x33, 0x98, + 0xCC, 0x52, 0x5D, 0x4C, 0x4E, 0x14, 0x6E, 0xDE, + 0xB3, 0x71, 0x26, 0x5F, 0xBA, 0x19, 0x13, 0x3A, + 0x2C, 0x3D, 0x21, 0x59, 0x29, 0x8A, 0x17, 0x42 + }, + { + 0xF6, 0x62, 0x0E, 0x68, 0xD3, 0x7F, 0xB2, 0xAF, + 0x50, 0x00, 0xFC, 0x28, 0xE2, 0x3B, 0x83, 0x22, + 0x97, 0xEC, 0xD8, 0xBC, 0xE9, 0x9E, 0x8B, 0xE4, + 0xD0, 0x4E, 0x85, 0x30, 0x9E, 0x3D, 0x33, 0x74 + }, + { + 0x53, 0x16, 0xA2, 0x79, 0x69, 0xD7, 0xFE, 0x04, + 0xFF, 0x27, 0xB2, 0x83, 0x96, 0x1B, 0xFF, 0xC3, + 0xBF, 0x5D, 0xFB, 0x32, 0xFB, 0x6A, 0x89, 0xD1, + 0x01, 0xC6, 0xC3, 0xB1, 0x93, 0x7C, 0x28, 0x71 + }, + { + 0x81, 0xD1, 0x66, 0x4F, 0xDF, 0x3C, 0xB3, 0x3C, + 0x24, 0xEE, 0xBA, 0xC0, 0xBD, 0x64, 0x24, 0x4B, + 0x77, 0xC4, 0xAB, 0xEA, 0x90, 0xBB, 0xE8, 0xB5, + 0xEE, 0x0B, 0x2A, 0xAF, 0xCF, 0x2D, 0x6A, 0x53 + }, + { + 0x34, 0x57, 0x82, 0xF2, 0x95, 0xB0, 0x88, 0x03, + 0x52, 0xE9, 0x24, 0xA0, 0x46, 0x7B, 0x5F, 0xBC, + 0x3E, 0x8F, 0x3B, 0xFB, 0xC3, 0xC7, 0xE4, 0x8B, + 0x67, 0x09, 0x1F, 0xB5, 0xE8, 0x0A, 0x94, 0x42 + }, + { + 0x79, 0x41, 0x11, 0xEA, 0x6C, 0xD6, 0x5E, 0x31, + 0x1F, 0x74, 0xEE, 0x41, 0xD4, 0x76, 0xCB, 0x63, + 0x2C, 0xE1, 0xE4, 0xB0, 0x51, 0xDC, 0x1D, 0x9E, + 0x9D, 0x06, 0x1A, 0x19, 0xE1, 0xD0, 0xBB, 0x49 + }, + { + 0x2A, 0x85, 0xDA, 0xF6, 0x13, 0x88, 0x16, 0xB9, + 0x9B, 0xF8, 0xD0, 0x8B, 0xA2, 0x11, 0x4B, 0x7A, + 0xB0, 0x79, 0x75, 0xA7, 0x84, 0x20, 0xC1, 0xA3, + 0xB0, 0x6A, 0x77, 0x7C, 0x22, 0xDD, 0x8B, 0xCB + }, + { + 0x89, 0xB0, 0xD5, 0xF2, 0x89, 0xEC, 0x16, 0x40, + 0x1A, 0x06, 0x9A, 0x96, 0x0D, 0x0B, 0x09, 0x3E, + 0x62, 0x5D, 0xA3, 0xCF, 0x41, 0xEE, 0x29, 0xB5, + 0x9B, 0x93, 0x0C, 0x58, 0x20, 0x14, 0x54, 0x55 + }, + { + 0xD0, 0xFD, 0xCB, 0x54, 0x39, 0x43, 0xFC, 0x27, + 0xD2, 0x08, 0x64, 0xF5, 0x21, 0x81, 0x47, 0x1B, + 0x94, 0x2C, 0xC7, 0x7C, 0xA6, 0x75, 0xBC, 0xB3, + 0x0D, 0xF3, 0x1D, 0x35, 0x8E, 0xF7, 0xB1, 0xEB + }, + { + 0xB1, 0x7E, 0xA8, 0xD7, 0x70, 0x63, 0xC7, 0x09, + 0xD4, 0xDC, 0x6B, 0x87, 0x94, 0x13, 0xC3, 0x43, + 0xE3, 0x79, 0x0E, 0x9E, 0x62, 0xCA, 0x85, 0xB7, + 0x90, 0x0B, 0x08, 0x6F, 0x6B, 0x75, 0xC6, 0x72 + }, + { + 0xE7, 0x1A, 0x3E, 0x2C, 0x27, 0x4D, 0xB8, 0x42, + 0xD9, 0x21, 0x14, 0xF2, 0x17, 0xE2, 0xC0, 0xEA, + 0xC8, 0xB4, 0x50, 0x93, 0xFD, 0xFD, 0x9D, 0xF4, + 0xCA, 0x71, 0x62, 0x39, 0x48, 0x62, 0xD5, 0x01 + }, + { + 0xC0, 0x47, 0x67, 0x59, 0xAB, 0x7A, 0xA3, 0x33, + 0x23, 0x4F, 0x6B, 0x44, 0xF5, 0xFD, 0x85, 0x83, + 0x90, 0xEC, 0x23, 0x69, 0x4C, 0x62, 0x2C, 0xB9, + 0x86, 0xE7, 0x69, 0xC7, 0x8E, 0xDD, 0x73, 0x3E + }, + { + 0x9A, 0xB8, 0xEA, 0xBB, 0x14, 0x16, 0x43, 0x4D, + 0x85, 0x39, 0x13, 0x41, 0xD5, 0x69, 0x93, 0xC5, + 0x54, 0x58, 0x16, 0x7D, 0x44, 0x18, 0xB1, 0x9A, + 0x0F, 0x2A, 0xD8, 0xB7, 0x9A, 0x83, 0xA7, 0x5B + }, + { + 0x79, 0x92, 0xD0, 0xBB, 0xB1, 0x5E, 0x23, 0x82, + 0x6F, 0x44, 0x3E, 0x00, 0x50, 0x5D, 0x68, 0xD3, + 0xED, 0x73, 0x72, 0x99, 0x5A, 0x5C, 0x3E, 0x49, + 0x86, 0x54, 0x10, 0x2F, 0xBC, 0xD0, 0x96, 0x4E + }, + { + 0xC0, 0x21, 0xB3, 0x00, 0x85, 0x15, 0x14, 0x35, + 0xDF, 0x33, 0xB0, 0x07, 0xCC, 0xEC, 0xC6, 0x9D, + 0xF1, 0x26, 0x9F, 0x39, 0xBA, 0x25, 0x09, 0x2B, + 0xED, 0x59, 0xD9, 0x32, 0xAC, 0x0F, 0xDC, 0x28 + }, + { + 0x91, 0xA2, 0x5E, 0xC0, 0xEC, 0x0D, 0x9A, 0x56, + 0x7F, 0x89, 0xC4, 0xBF, 0xE1, 0xA6, 0x5A, 0x0E, + 0x43, 0x2D, 0x07, 0x06, 0x4B, 0x41, 0x90, 0xE2, + 0x7D, 0xFB, 0x81, 0x90, 0x1F, 0xD3, 0x13, 0x9B + }, + { + 0x59, 0x50, 0xD3, 0x9A, 0x23, 0xE1, 0x54, 0x5F, + 0x30, 0x12, 0x70, 0xAA, 0x1A, 0x12, 0xF2, 0xE6, + 0xC4, 0x53, 0x77, 0x6E, 0x4D, 0x63, 0x55, 0xDE, + 0x42, 0x5C, 0xC1, 0x53, 0xF9, 0x81, 0x88, 0x67 + }, + { + 0xD7, 0x9F, 0x14, 0x72, 0x0C, 0x61, 0x0A, 0xF1, + 0x79, 0xA3, 0x76, 0x5D, 0x4B, 0x7C, 0x09, 0x68, + 0xF9, 0x77, 0x96, 0x2D, 0xBF, 0x65, 0x5B, 0x52, + 0x12, 0x72, 0xB6, 0xF1, 0xE1, 0x94, 0x48, 0x8E + }, + { + 0xE9, 0x53, 0x1B, 0xFC, 0x8B, 0x02, 0x99, 0x5A, + 0xEA, 0xA7, 0x5B, 0xA2, 0x70, 0x31, 0xFA, 0xDB, + 0xCB, 0xF4, 0xA0, 0xDA, 0xB8, 0x96, 0x1D, 0x92, + 0x96, 0xCD, 0x7E, 0x84, 0xD2, 0x5D, 0x60, 0x06 + }, + { + 0x34, 0xE9, 0xC2, 0x6A, 0x01, 0xD7, 0xF1, 0x61, + 0x81, 0xB4, 0x54, 0xA9, 0xD1, 0x62, 0x3C, 0x23, + 0x3C, 0xB9, 0x9D, 0x31, 0xC6, 0x94, 0x65, 0x6E, + 0x94, 0x13, 0xAC, 0xA3, 0xE9, 0x18, 0x69, 0x2F + }, + { + 0xD9, 0xD7, 0x42, 0x2F, 0x43, 0x7B, 0xD4, 0x39, + 0xDD, 0xD4, 0xD8, 0x83, 0xDA, 0xE2, 0xA0, 0x83, + 0x50, 0x17, 0x34, 0x14, 0xBE, 0x78, 0x15, 0x51, + 0x33, 0xFF, 0xF1, 0x96, 0x4C, 0x3D, 0x79, 0x72 + }, + { + 0x4A, 0xEE, 0x0C, 0x7A, 0xAF, 0x07, 0x54, 0x14, + 0xFF, 0x17, 0x93, 0xEA, 0xD7, 0xEA, 0xCA, 0x60, + 0x17, 0x75, 0xC6, 0x15, 0xDB, 0xD6, 0x0B, 0x64, + 0x0B, 0x0A, 0x9F, 0x0C, 0xE5, 0x05, 0xD4, 0x35 + }, + { + 0x6B, 0xFD, 0xD1, 0x54, 0x59, 0xC8, 0x3B, 0x99, + 0xF0, 0x96, 0xBF, 0xB4, 0x9E, 0xE8, 0x7B, 0x06, + 0x3D, 0x69, 0xC1, 0x97, 0x4C, 0x69, 0x28, 0xAC, + 0xFC, 0xFB, 0x40, 0x99, 0xF8, 0xC4, 0xEF, 0x67 + }, + { + 0x9F, 0xD1, 0xC4, 0x08, 0xFD, 0x75, 0xC3, 0x36, + 0x19, 0x3A, 0x2A, 0x14, 0xD9, 0x4F, 0x6A, 0xF5, + 0xAD, 0xF0, 0x50, 0xB8, 0x03, 0x87, 0xB4, 0xB0, + 0x10, 0xFB, 0x29, 0xF4, 0xCC, 0x72, 0x70, 0x7C + }, + { + 0x13, 0xC8, 0x84, 0x80, 0xA5, 0xD0, 0x0D, 0x6C, + 0x8C, 0x7A, 0xD2, 0x11, 0x0D, 0x76, 0xA8, 0x2D, + 0x9B, 0x70, 0xF4, 0xFA, 0x66, 0x96, 0xD4, 0xE5, + 0xDD, 0x42, 0xA0, 0x66, 0xDC, 0xAF, 0x99, 0x20 + }, + { + 0x82, 0x0E, 0x72, 0x5E, 0xE2, 0x5F, 0xE8, 0xFD, + 0x3A, 0x8D, 0x5A, 0xBE, 0x4C, 0x46, 0xC3, 0xBA, + 0x88, 0x9D, 0xE6, 0xFA, 0x91, 0x91, 0xAA, 0x22, + 0xBA, 0x67, 0xD5, 0x70, 0x54, 0x21, 0x54, 0x2B + }, + { + 0x32, 0xD9, 0x3A, 0x0E, 0xB0, 0x2F, 0x42, 0xFB, + 0xBC, 0xAF, 0x2B, 0xAD, 0x00, 0x85, 0xB2, 0x82, + 0xE4, 0x60, 0x46, 0xA4, 0xDF, 0x7A, 0xD1, 0x06, + 0x57, 0xC9, 0xD6, 0x47, 0x63, 0x75, 0xB9, 0x3E + }, + { + 0xAD, 0xC5, 0x18, 0x79, 0x05, 0xB1, 0x66, 0x9C, + 0xD8, 0xEC, 0x9C, 0x72, 0x1E, 0x19, 0x53, 0x78, + 0x6B, 0x9D, 0x89, 0xA9, 0xBA, 0xE3, 0x07, 0x80, + 0xF1, 0xE1, 0xEA, 0xB2, 0x4A, 0x00, 0x52, 0x3C + }, + { + 0xE9, 0x07, 0x56, 0xFF, 0x7F, 0x9A, 0xD8, 0x10, + 0xB2, 0x39, 0xA1, 0x0C, 0xED, 0x2C, 0xF9, 0xB2, + 0x28, 0x43, 0x54, 0xC1, 0xF8, 0xC7, 0xE0, 0xAC, + 0xCC, 0x24, 0x61, 0xDC, 0x79, 0x6D, 0x6E, 0x89 + }, + { + 0x12, 0x51, 0xF7, 0x6E, 0x56, 0x97, 0x84, 0x81, + 0x87, 0x53, 0x59, 0x80, 0x1D, 0xB5, 0x89, 0xA0, + 0xB2, 0x2F, 0x86, 0xD8, 0xD6, 0x34, 0xDC, 0x04, + 0x50, 0x6F, 0x32, 0x2E, 0xD7, 0x8F, 0x17, 0xE8 + }, + { + 0x3A, 0xFA, 0x89, 0x9F, 0xD9, 0x80, 0xE7, 0x3E, + 0xCB, 0x7F, 0x4D, 0x8B, 0x8F, 0x29, 0x1D, 0xC9, + 0xAF, 0x79, 0x6B, 0xC6, 0x5D, 0x27, 0xF9, 0x74, + 0xC6, 0xF1, 0x93, 0xC9, 0x19, 0x1A, 0x09, 0xFD + }, + { + 0xAA, 0x30, 0x5B, 0xE2, 0x6E, 0x5D, 0xED, 0xDC, + 0x3C, 0x10, 0x10, 0xCB, 0xC2, 0x13, 0xF9, 0x5F, + 0x05, 0x1C, 0x78, 0x5C, 0x5B, 0x43, 0x1E, 0x6A, + 0x7C, 0xD0, 0x48, 0xF1, 0x61, 0x78, 0x75, 0x28 + }, + { + 0x8E, 0xA1, 0x88, 0x4F, 0xF3, 0x2E, 0x9D, 0x10, + 0xF0, 0x39, 0xB4, 0x07, 0xD0, 0xD4, 0x4E, 0x7E, + 0x67, 0x0A, 0xBD, 0x88, 0x4A, 0xEE, 0xE0, 0xFB, + 0x75, 0x7A, 0xE9, 0x4E, 0xAA, 0x97, 0x37, 0x3D + }, + { + 0xD4, 0x82, 0xB2, 0x15, 0x5D, 0x4D, 0xEC, 0x6B, + 0x47, 0x36, 0xA1, 0xF1, 0x61, 0x7B, 0x53, 0xAA, + 0xA3, 0x73, 0x10, 0x27, 0x7D, 0x3F, 0xEF, 0x0C, + 0x37, 0xAD, 0x41, 0x76, 0x8F, 0xC2, 0x35, 0xB4 + }, + { + 0x4D, 0x41, 0x39, 0x71, 0x38, 0x7E, 0x7A, 0x88, + 0x98, 0xA8, 0xDC, 0x2A, 0x27, 0x50, 0x07, 0x78, + 0x53, 0x9E, 0xA2, 0x14, 0xA2, 0xDF, 0xE9, 0xB3, + 0xD7, 0xE8, 0xEB, 0xDC, 0xE5, 0xCF, 0x3D, 0xB3 + }, + { + 0x69, 0x6E, 0x5D, 0x46, 0xE6, 0xC5, 0x7E, 0x87, + 0x96, 0xE4, 0x73, 0x5D, 0x08, 0x91, 0x6E, 0x0B, + 0x79, 0x29, 0xB3, 0xCF, 0x29, 0x8C, 0x29, 0x6D, + 0x22, 0xE9, 0xD3, 0x01, 0x96, 0x53, 0x37, 0x1C + }, + { + 0x1F, 0x56, 0x47, 0xC1, 0xD3, 0xB0, 0x88, 0x22, + 0x88, 0x85, 0x86, 0x5C, 0x89, 0x40, 0x90, 0x8B, + 0xF4, 0x0D, 0x1A, 0x82, 0x72, 0x82, 0x19, 0x73, + 0xB1, 0x60, 0x00, 0x8E, 0x7A, 0x3C, 0xE2, 0xEB + }, + { + 0xB6, 0xE7, 0x6C, 0x33, 0x0F, 0x02, 0x1A, 0x5B, + 0xDA, 0x65, 0x87, 0x50, 0x10, 0xB0, 0xED, 0xF0, + 0x91, 0x26, 0xC0, 0xF5, 0x10, 0xEA, 0x84, 0x90, + 0x48, 0x19, 0x20, 0x03, 0xAE, 0xF4, 0xC6, 0x1C + }, + { + 0x3C, 0xD9, 0x52, 0xA0, 0xBE, 0xAD, 0xA4, 0x1A, + 0xBB, 0x42, 0x4C, 0xE4, 0x7F, 0x94, 0xB4, 0x2B, + 0xE6, 0x4E, 0x1F, 0xFB, 0x0F, 0xD0, 0x78, 0x22, + 0x76, 0x80, 0x79, 0x46, 0xD0, 0xD0, 0xBC, 0x55 + }, + { + 0x98, 0xD9, 0x26, 0x77, 0x43, 0x9B, 0x41, 0xB7, + 0xBB, 0x51, 0x33, 0x12, 0xAF, 0xB9, 0x2B, 0xCC, + 0x8E, 0xE9, 0x68, 0xB2, 0xE3, 0xB2, 0x38, 0xCE, + 0xCB, 0x9B, 0x0F, 0x34, 0xC9, 0xBB, 0x63, 0xD0 + }, + { + 0xEC, 0xBC, 0xA2, 0xCF, 0x08, 0xAE, 0x57, 0xD5, + 0x17, 0xAD, 0x16, 0x15, 0x8A, 0x32, 0xBF, 0xA7, + 0xDC, 0x03, 0x82, 0xEA, 0xED, 0xA1, 0x28, 0xE9, + 0x18, 0x86, 0x73, 0x4C, 0x24, 0xA0, 0xB2, 0x9D + }, + { + 0x94, 0x2C, 0xC7, 0xC0, 0xB5, 0x2E, 0x2B, 0x16, + 0xA4, 0xB8, 0x9F, 0xA4, 0xFC, 0x7E, 0x0B, 0xF6, + 0x09, 0xE2, 0x9A, 0x08, 0xC1, 0xA8, 0x54, 0x34, + 0x52, 0xB7, 0x7C, 0x7B, 0xFD, 0x11, 0xBB, 0x28 + }, + { + 0x8A, 0x06, 0x5D, 0x8B, 0x61, 0xA0, 0xDF, 0xFB, + 0x17, 0x0D, 0x56, 0x27, 0x73, 0x5A, 0x76, 0xB0, + 0xE9, 0x50, 0x60, 0x37, 0x80, 0x8C, 0xBA, 0x16, + 0xC3, 0x45, 0x00, 0x7C, 0x9F, 0x79, 0xCF, 0x8F + }, + { + 0x1B, 0x9F, 0xA1, 0x97, 0x14, 0x65, 0x9C, 0x78, + 0xFF, 0x41, 0x38, 0x71, 0x84, 0x92, 0x15, 0x36, + 0x10, 0x29, 0xAC, 0x80, 0x2B, 0x1C, 0xBC, 0xD5, + 0x4E, 0x40, 0x8B, 0xD8, 0x72, 0x87, 0xF8, 0x1F + }, + { + 0x8D, 0xAB, 0x07, 0x1B, 0xCD, 0x6C, 0x72, 0x92, + 0xA9, 0xEF, 0x72, 0x7B, 0x4A, 0xE0, 0xD8, 0x67, + 0x13, 0x30, 0x1D, 0xA8, 0x61, 0x8D, 0x9A, 0x48, + 0xAD, 0xCE, 0x55, 0xF3, 0x03, 0xA8, 0x69, 0xA1 + }, + { + 0x82, 0x53, 0xE3, 0xE7, 0xC7, 0xB6, 0x84, 0xB9, + 0xCB, 0x2B, 0xEB, 0x01, 0x4C, 0xE3, 0x30, 0xFF, + 0x3D, 0x99, 0xD1, 0x7A, 0xBB, 0xDB, 0xAB, 0xE4, + 0xF4, 0xD6, 0x74, 0xDE, 0xD5, 0x3F, 0xFC, 0x6B + }, + { + 0xF1, 0x95, 0xF3, 0x21, 0xE9, 0xE3, 0xD6, 0xBD, + 0x7D, 0x07, 0x45, 0x04, 0xDD, 0x2A, 0xB0, 0xE6, + 0x24, 0x1F, 0x92, 0xE7, 0x84, 0xB1, 0xAA, 0x27, + 0x1F, 0xF6, 0x48, 0xB1, 0xCA, 0xB6, 0xD7, 0xF6 + }, + { + 0x27, 0xE4, 0xCC, 0x72, 0x09, 0x0F, 0x24, 0x12, + 0x66, 0x47, 0x6A, 0x7C, 0x09, 0x49, 0x5F, 0x2D, + 0xB1, 0x53, 0xD5, 0xBC, 0xBD, 0x76, 0x19, 0x03, + 0xEF, 0x79, 0x27, 0x5E, 0xC5, 0x6B, 0x2E, 0xD8 + }, + { + 0x89, 0x9C, 0x24, 0x05, 0x78, 0x8E, 0x25, 0xB9, + 0x9A, 0x18, 0x46, 0x35, 0x5E, 0x64, 0x6D, 0x77, + 0xCF, 0x40, 0x00, 0x83, 0x41, 0x5F, 0x7D, 0xC5, + 0xAF, 0xE6, 0x9D, 0x6E, 0x17, 0xC0, 0x00, 0x23 + }, + { + 0xA5, 0x9B, 0x78, 0xC4, 0x90, 0x57, 0x44, 0x07, + 0x6B, 0xFE, 0xE8, 0x94, 0xDE, 0x70, 0x7D, 0x4F, + 0x12, 0x0B, 0x5C, 0x68, 0x93, 0xEA, 0x04, 0x00, + 0x29, 0x7D, 0x0B, 0xB8, 0x34, 0x72, 0x76, 0x32 + }, + { + 0x59, 0xDC, 0x78, 0xB1, 0x05, 0x64, 0x97, 0x07, + 0xA2, 0xBB, 0x44, 0x19, 0xC4, 0x8F, 0x00, 0x54, + 0x00, 0xD3, 0x97, 0x3D, 0xE3, 0x73, 0x66, 0x10, + 0x23, 0x04, 0x35, 0xB1, 0x04, 0x24, 0xB2, 0x4F + }, + { + 0xC0, 0x14, 0x9D, 0x1D, 0x7E, 0x7A, 0x63, 0x53, + 0xA6, 0xD9, 0x06, 0xEF, 0xE7, 0x28, 0xF2, 0xF3, + 0x29, 0xFE, 0x14, 0xA4, 0x14, 0x9A, 0x3E, 0xA7, + 0x76, 0x09, 0xBC, 0x42, 0xB9, 0x75, 0xDD, 0xFA + }, + { + 0xA3, 0x2F, 0x24, 0x14, 0x74, 0xA6, 0xC1, 0x69, + 0x32, 0xE9, 0x24, 0x3B, 0xE0, 0xCF, 0x09, 0xBC, + 0xDC, 0x7E, 0x0C, 0xA0, 0xE7, 0xA6, 0xA1, 0xB9, + 0xB1, 0xA0, 0xF0, 0x1E, 0x41, 0x50, 0x23, 0x77 + }, + { + 0xB2, 0x39, 0xB2, 0xE4, 0xF8, 0x18, 0x41, 0x36, + 0x1C, 0x13, 0x39, 0xF6, 0x8E, 0x2C, 0x35, 0x9F, + 0x92, 0x9A, 0xF9, 0xAD, 0x9F, 0x34, 0xE0, 0x1A, + 0xAB, 0x46, 0x31, 0xAD, 0x6D, 0x55, 0x00, 0xB0 + }, + { + 0x85, 0xFB, 0x41, 0x9C, 0x70, 0x02, 0xA3, 0xE0, + 0xB4, 0xB6, 0xEA, 0x09, 0x3B, 0x4C, 0x1A, 0xC6, + 0x93, 0x66, 0x45, 0xB6, 0x5D, 0xAC, 0x5A, 0xC1, + 0x5A, 0x85, 0x28, 0xB7, 0xB9, 0x4C, 0x17, 0x54 + }, + { + 0x96, 0x19, 0x72, 0x06, 0x25, 0xF1, 0x90, 0xB9, + 0x3A, 0x3F, 0xAD, 0x18, 0x6A, 0xB3, 0x14, 0x18, + 0x96, 0x33, 0xC0, 0xD3, 0xA0, 0x1E, 0x6F, 0x9B, + 0xC8, 0xC4, 0xA8, 0xF8, 0x2F, 0x38, 0x3D, 0xBF + }, + { + 0x7D, 0x62, 0x0D, 0x90, 0xFE, 0x69, 0xFA, 0x46, + 0x9A, 0x65, 0x38, 0x38, 0x89, 0x70, 0xA1, 0xAA, + 0x09, 0xBB, 0x48, 0xA2, 0xD5, 0x9B, 0x34, 0x7B, + 0x97, 0xE8, 0xCE, 0x71, 0xF4, 0x8C, 0x7F, 0x46 + }, + { + 0x29, 0x43, 0x83, 0x56, 0x85, 0x96, 0xFB, 0x37, + 0xC7, 0x5B, 0xBA, 0xCD, 0x97, 0x9C, 0x5F, 0xF6, + 0xF2, 0x0A, 0x55, 0x6B, 0xF8, 0x87, 0x9C, 0xC7, + 0x29, 0x24, 0x85, 0x5D, 0xF9, 0xB8, 0x24, 0x0E + }, + { + 0x16, 0xB1, 0x8A, 0xB3, 0x14, 0x35, 0x9C, 0x2B, + 0x83, 0x3C, 0x1C, 0x69, 0x86, 0xD4, 0x8C, 0x55, + 0xA9, 0xFC, 0x97, 0xCD, 0xE9, 0xA3, 0xC1, 0xF1, + 0x0A, 0x31, 0x77, 0x14, 0x0F, 0x73, 0xF7, 0x38 + }, + { + 0x8C, 0xBB, 0xDD, 0x14, 0xBC, 0x33, 0xF0, 0x4C, + 0xF4, 0x58, 0x13, 0xE4, 0xA1, 0x53, 0xA2, 0x73, + 0xD3, 0x6A, 0xDA, 0xD5, 0xCE, 0x71, 0xF4, 0x99, + 0xEE, 0xB8, 0x7F, 0xB8, 0xAC, 0x63, 0xB7, 0x29 + }, + { + 0x69, 0xC9, 0xA4, 0x98, 0xDB, 0x17, 0x4E, 0xCA, + 0xEF, 0xCC, 0x5A, 0x3A, 0xC9, 0xFD, 0xED, 0xF0, + 0xF8, 0x13, 0xA5, 0xBE, 0xC7, 0x27, 0xF1, 0xE7, + 0x75, 0xBA, 0xBD, 0xEC, 0x77, 0x18, 0x81, 0x6E + }, + { + 0xB4, 0x62, 0xC3, 0xBE, 0x40, 0x44, 0x8F, 0x1D, + 0x4F, 0x80, 0x62, 0x62, 0x54, 0xE5, 0x35, 0xB0, + 0x8B, 0xC9, 0xCD, 0xCF, 0xF5, 0x99, 0xA7, 0x68, + 0x57, 0x8D, 0x4B, 0x28, 0x81, 0xA8, 0xE3, 0xF0 + }, + { + 0x55, 0x3E, 0x9D, 0x9C, 0x5F, 0x36, 0x0A, 0xC0, + 0xB7, 0x4A, 0x7D, 0x44, 0xE5, 0xA3, 0x91, 0xDA, + 0xD4, 0xCE, 0xD0, 0x3E, 0x0C, 0x24, 0x18, 0x3B, + 0x7E, 0x8E, 0xCA, 0xBD, 0xF1, 0x71, 0x5A, 0x64 + }, + { + 0x7A, 0x7C, 0x55, 0xA5, 0x6F, 0xA9, 0xAE, 0x51, + 0xE6, 0x55, 0xE0, 0x19, 0x75, 0xD8, 0xA6, 0xFF, + 0x4A, 0xE9, 0xE4, 0xB4, 0x86, 0xFC, 0xBE, 0x4E, + 0xAC, 0x04, 0x45, 0x88, 0xF2, 0x45, 0xEB, 0xEA + }, + { + 0x2A, 0xFD, 0xF3, 0xC8, 0x2A, 0xBC, 0x48, 0x67, + 0xF5, 0xDE, 0x11, 0x12, 0x86, 0xC2, 0xB3, 0xBE, + 0x7D, 0x6E, 0x48, 0x65, 0x7B, 0xA9, 0x23, 0xCF, + 0xBF, 0x10, 0x1A, 0x6D, 0xFC, 0xF9, 0xDB, 0x9A + }, + { + 0x41, 0x03, 0x7D, 0x2E, 0xDC, 0xDC, 0xE0, 0xC4, + 0x9B, 0x7F, 0xB4, 0xA6, 0xAA, 0x09, 0x99, 0xCA, + 0x66, 0x97, 0x6C, 0x74, 0x83, 0xAF, 0xE6, 0x31, + 0xD4, 0xED, 0xA2, 0x83, 0x14, 0x4F, 0x6D, 0xFC + }, + { + 0xC4, 0x46, 0x6F, 0x84, 0x97, 0xCA, 0x2E, 0xEB, + 0x45, 0x83, 0xA0, 0xB0, 0x8E, 0x9D, 0x9A, 0xC7, + 0x43, 0x95, 0x70, 0x9F, 0xDA, 0x10, 0x9D, 0x24, + 0xF2, 0xE4, 0x46, 0x21, 0x96, 0x77, 0x9C, 0x5D + }, + { + 0x75, 0xF6, 0x09, 0x33, 0x8A, 0xA6, 0x7D, 0x96, + 0x9A, 0x2A, 0xE2, 0xA2, 0x36, 0x2B, 0x2D, 0xA9, + 0xD7, 0x7C, 0x69, 0x5D, 0xFD, 0x1D, 0xF7, 0x22, + 0x4A, 0x69, 0x01, 0xDB, 0x93, 0x2C, 0x33, 0x64 + }, + { + 0x68, 0x60, 0x6C, 0xEB, 0x98, 0x9D, 0x54, 0x88, + 0xFC, 0x7C, 0xF6, 0x49, 0xF3, 0xD7, 0xC2, 0x72, + 0xEF, 0x05, 0x5D, 0xA1, 0xA9, 0x3F, 0xAE, 0xCD, + 0x55, 0xFE, 0x06, 0xF6, 0x96, 0x70, 0x98, 0xCA + }, + { + 0x44, 0x34, 0x6B, 0xDE, 0xB7, 0xE0, 0x52, 0xF6, + 0x25, 0x50, 0x48, 0xF0, 0xD9, 0xB4, 0x2C, 0x42, + 0x5B, 0xAB, 0x9C, 0x3D, 0xD2, 0x41, 0x68, 0x21, + 0x2C, 0x3E, 0xCF, 0x1E, 0xBF, 0x34, 0xE6, 0xAE + }, + { + 0x8E, 0x9C, 0xF6, 0xE1, 0xF3, 0x66, 0x47, 0x1F, + 0x2A, 0xC7, 0xD2, 0xEE, 0x9B, 0x5E, 0x62, 0x66, + 0xFD, 0xA7, 0x1F, 0x8F, 0x2E, 0x41, 0x09, 0xF2, + 0x23, 0x7E, 0xD5, 0xF8, 0x81, 0x3F, 0xC7, 0x18 + }, + { + 0x84, 0xBB, 0xEB, 0x84, 0x06, 0xD2, 0x50, 0x95, + 0x1F, 0x8C, 0x1B, 0x3E, 0x86, 0xA7, 0xC0, 0x10, + 0x08, 0x29, 0x21, 0x83, 0x3D, 0xFD, 0x95, 0x55, + 0xA2, 0xF9, 0x09, 0xB1, 0x08, 0x6E, 0xB4, 0xB8 + }, + { + 0xEE, 0x66, 0x6F, 0x3E, 0xEF, 0x0F, 0x7E, 0x2A, + 0x9C, 0x22, 0x29, 0x58, 0xC9, 0x7E, 0xAF, 0x35, + 0xF5, 0x1C, 0xED, 0x39, 0x3D, 0x71, 0x44, 0x85, + 0xAB, 0x09, 0xA0, 0x69, 0x34, 0x0F, 0xDF, 0x88 + }, + { + 0xC1, 0x53, 0xD3, 0x4A, 0x65, 0xC4, 0x7B, 0x4A, + 0x62, 0xC5, 0xCA, 0xCF, 0x24, 0x01, 0x09, 0x75, + 0xD0, 0x35, 0x6B, 0x2F, 0x32, 0xC8, 0xF5, 0xDA, + 0x53, 0x0D, 0x33, 0x88, 0x16, 0xAD, 0x5D, 0xE6 + }, + { + 0x9F, 0xC5, 0x45, 0x01, 0x09, 0xE1, 0xB7, 0x79, + 0xF6, 0xC7, 0xAE, 0x79, 0xD5, 0x6C, 0x27, 0x63, + 0x5C, 0x8D, 0xD4, 0x26, 0xC5, 0xA9, 0xD5, 0x4E, + 0x25, 0x78, 0xDB, 0x98, 0x9B, 0x8C, 0x3B, 0x4E + }, + { + 0xD1, 0x2B, 0xF3, 0x73, 0x2E, 0xF4, 0xAF, 0x5C, + 0x22, 0xFA, 0x90, 0x35, 0x6A, 0xF8, 0xFC, 0x50, + 0xFC, 0xB4, 0x0F, 0x8F, 0x2E, 0xA5, 0xC8, 0x59, + 0x47, 0x37, 0xA3, 0xB3, 0xD5, 0xAB, 0xDB, 0xD7 + }, + { + 0x11, 0x03, 0x0B, 0x92, 0x89, 0xBB, 0xA5, 0xAF, + 0x65, 0x26, 0x06, 0x72, 0xAB, 0x6F, 0xEE, 0x88, + 0xB8, 0x74, 0x20, 0xAC, 0xEF, 0x4A, 0x17, 0x89, + 0xA2, 0x07, 0x3B, 0x7E, 0xC2, 0xF2, 0xA0, 0x9E + }, + { + 0x69, 0xCB, 0x19, 0x2B, 0x84, 0x44, 0x00, 0x5C, + 0x8C, 0x0C, 0xEB, 0x12, 0xC8, 0x46, 0x86, 0x07, + 0x68, 0x18, 0x8C, 0xDA, 0x0A, 0xEC, 0x27, 0xA9, + 0xC8, 0xA5, 0x5C, 0xDE, 0xE2, 0x12, 0x36, 0x32 + }, + { + 0xDB, 0x44, 0x4C, 0x15, 0x59, 0x7B, 0x5F, 0x1A, + 0x03, 0xD1, 0xF9, 0xED, 0xD1, 0x6E, 0x4A, 0x9F, + 0x43, 0xA6, 0x67, 0xCC, 0x27, 0x51, 0x75, 0xDF, + 0xA2, 0xB7, 0x04, 0xE3, 0xBB, 0x1A, 0x9B, 0x83 + }, + { + 0x3F, 0xB7, 0x35, 0x06, 0x1A, 0xBC, 0x51, 0x9D, + 0xFE, 0x97, 0x9E, 0x54, 0xC1, 0xEE, 0x5B, 0xFA, + 0xD0, 0xA9, 0xD8, 0x58, 0xB3, 0x31, 0x5B, 0xAD, + 0x34, 0xBD, 0xE9, 0x99, 0xEF, 0xD7, 0x24, 0xDD + }, +}; + + + + +static const uint8_t blake2b_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03, + 0xC6, 0xC6, 0xFD, 0x85, 0x25, 0x52, 0xD2, 0x72, + 0x91, 0x2F, 0x47, 0x40, 0xE1, 0x58, 0x47, 0x61, + 0x8A, 0x86, 0xE2, 0x17, 0xF7, 0x1F, 0x54, 0x19, + 0xD2, 0x5E, 0x10, 0x31, 0xAF, 0xEE, 0x58, 0x53, + 0x13, 0x89, 0x64, 0x44, 0x93, 0x4E, 0xB0, 0x4B, + 0x90, 0x3A, 0x68, 0x5B, 0x14, 0x48, 0xB7, 0x55, + 0xD5, 0x6F, 0x70, 0x1A, 0xFE, 0x9B, 0xE2, 0xCE + }, + { + 0x2F, 0xA3, 0xF6, 0x86, 0xDF, 0x87, 0x69, 0x95, + 0x16, 0x7E, 0x7C, 0x2E, 0x5D, 0x74, 0xC4, 0xC7, + 0xB6, 0xE4, 0x8F, 0x80, 0x68, 0xFE, 0x0E, 0x44, + 0x20, 0x83, 0x44, 0xD4, 0x80, 0xF7, 0x90, 0x4C, + 0x36, 0x96, 0x3E, 0x44, 0x11, 0x5F, 0xE3, 0xEB, + 0x2A, 0x3A, 0xC8, 0x69, 0x4C, 0x28, 0xBC, 0xB4, + 0xF5, 0xA0, 0xF3, 0x27, 0x6F, 0x2E, 0x79, 0x48, + 0x7D, 0x82, 0x19, 0x05, 0x7A, 0x50, 0x6E, 0x4B + }, + { + 0x1C, 0x08, 0x79, 0x8D, 0xC6, 0x41, 0xAB, 0xA9, + 0xDE, 0xE4, 0x35, 0xE2, 0x25, 0x19, 0xA4, 0x72, + 0x9A, 0x09, 0xB2, 0xBF, 0xE0, 0xFF, 0x00, 0xEF, + 0x2D, 0xCD, 0x8E, 0xD6, 0xF8, 0xA0, 0x7D, 0x15, + 0xEA, 0xF4, 0xAE, 0xE5, 0x2B, 0xBF, 0x18, 0xAB, + 0x56, 0x08, 0xA6, 0x19, 0x0F, 0x70, 0xB9, 0x04, + 0x86, 0xC8, 0xA7, 0xD4, 0x87, 0x37, 0x10, 0xB1, + 0x11, 0x5D, 0x3D, 0xEB, 0xBB, 0x43, 0x27, 0xB5 + }, + { + 0x40, 0xA3, 0x74, 0x72, 0x73, 0x02, 0xD9, 0xA4, + 0x76, 0x9C, 0x17, 0xB5, 0xF4, 0x09, 0xFF, 0x32, + 0xF5, 0x8A, 0xA2, 0x4F, 0xF1, 0x22, 0xD7, 0x60, + 0x3E, 0x4F, 0xDA, 0x15, 0x09, 0xE9, 0x19, 0xD4, + 0x10, 0x7A, 0x52, 0xC5, 0x75, 0x70, 0xA6, 0xD9, + 0x4E, 0x50, 0x96, 0x7A, 0xEA, 0x57, 0x3B, 0x11, + 0xF8, 0x6F, 0x47, 0x3F, 0x53, 0x75, 0x65, 0xC6, + 0x6F, 0x70, 0x39, 0x83, 0x0A, 0x85, 0xD1, 0x86 + }, + { + 0x77, 0xDD, 0xF4, 0xB1, 0x44, 0x25, 0xEB, 0x3D, + 0x05, 0x3C, 0x1E, 0x84, 0xE3, 0x46, 0x9D, 0x92, + 0xC4, 0xCD, 0x91, 0x0E, 0xD2, 0x0F, 0x92, 0x03, + 0x5E, 0x0C, 0x99, 0xD8, 0xA7, 0xA8, 0x6C, 0xEC, + 0xAF, 0x69, 0xF9, 0x66, 0x3C, 0x20, 0xA7, 0xAA, + 0x23, 0x0B, 0xC8, 0x2F, 0x60, 0xD2, 0x2F, 0xB4, + 0xA0, 0x0B, 0x09, 0xD3, 0xEB, 0x8F, 0xC6, 0x5E, + 0xF5, 0x47, 0xFE, 0x63, 0xC8, 0xD3, 0xDD, 0xCE + }, + { + 0xCB, 0xAA, 0x0B, 0xA7, 0xD4, 0x82, 0xB1, 0xF3, + 0x01, 0x10, 0x9A, 0xE4, 0x10, 0x51, 0x99, 0x1A, + 0x32, 0x89, 0xBC, 0x11, 0x98, 0x00, 0x5A, 0xF2, + 0x26, 0xC5, 0xE4, 0xF1, 0x03, 0xB6, 0x65, 0x79, + 0xF4, 0x61, 0x36, 0x10, 0x44, 0xC8, 0xBA, 0x34, + 0x39, 0xFF, 0x12, 0xC5, 0x15, 0xFB, 0x29, 0xC5, + 0x21, 0x61, 0xB7, 0xEB, 0x9C, 0x28, 0x37, 0xB7, + 0x6A, 0x5D, 0xC3, 0x3F, 0x7C, 0xB2, 0xE2, 0xE8 + }, + { + 0xF9, 0x5D, 0x45, 0xCF, 0x69, 0xAF, 0x5C, 0x20, + 0x23, 0xBD, 0xB5, 0x05, 0x82, 0x1E, 0x62, 0xE8, + 0x5D, 0x7C, 0xAE, 0xDF, 0x7B, 0xED, 0xA1, 0x2C, + 0x02, 0x48, 0x77, 0x5B, 0x0C, 0x88, 0x20, 0x5E, + 0xEB, 0x35, 0xAF, 0x3A, 0x90, 0x81, 0x6F, 0x66, + 0x08, 0xCE, 0x7D, 0xD4, 0x4E, 0xC2, 0x8D, 0xB1, + 0x14, 0x06, 0x14, 0xE1, 0xDD, 0xEB, 0xF3, 0xAA, + 0x9C, 0xD1, 0x84, 0x3E, 0x0F, 0xAD, 0x2C, 0x36 + }, + { + 0x8F, 0x94, 0x5B, 0xA7, 0x00, 0xF2, 0x53, 0x0E, + 0x5C, 0x2A, 0x7D, 0xF7, 0xD5, 0xDC, 0xE0, 0xF8, + 0x3F, 0x9E, 0xFC, 0x78, 0xC0, 0x73, 0xFE, 0x71, + 0xAE, 0x1F, 0x88, 0x20, 0x4A, 0x4F, 0xD1, 0xCF, + 0x70, 0xA0, 0x73, 0xF5, 0xD1, 0xF9, 0x42, 0xED, + 0x62, 0x3A, 0xA1, 0x6E, 0x90, 0xA8, 0x71, 0x24, + 0x6C, 0x90, 0xC4, 0x5B, 0x62, 0x1B, 0x34, 0x01, + 0xA5, 0xDD, 0xBD, 0x9D, 0xF6, 0x26, 0x41, 0x65 + }, + { + 0xE9, 0x98, 0xE0, 0xDC, 0x03, 0xEC, 0x30, 0xEB, + 0x99, 0xBB, 0x6B, 0xFA, 0xAF, 0x66, 0x18, 0xAC, + 0xC6, 0x20, 0x32, 0x0D, 0x72, 0x20, 0xB3, 0xAF, + 0x2B, 0x23, 0xD1, 0x12, 0xD8, 0xE9, 0xCB, 0x12, + 0x62, 0xF3, 0xC0, 0xD6, 0x0D, 0x18, 0x3B, 0x1E, + 0xE7, 0xF0, 0x96, 0xD1, 0x2D, 0xAE, 0x42, 0xC9, + 0x58, 0x41, 0x86, 0x00, 0x21, 0x4D, 0x04, 0xF5, + 0xED, 0x6F, 0x5E, 0x71, 0x8B, 0xE3, 0x55, 0x66 + }, + { + 0x6A, 0x9A, 0x09, 0x0C, 0x61, 0xB3, 0x41, 0x0A, + 0xED, 0xE7, 0xEC, 0x91, 0x38, 0x14, 0x6C, 0xEB, + 0x2C, 0x69, 0x66, 0x2F, 0x46, 0x0C, 0x3D, 0xA5, + 0x3C, 0x65, 0x15, 0xC1, 0xEB, 0x31, 0xF4, 0x1C, + 0xA3, 0xD2, 0x80, 0xE5, 0x67, 0x88, 0x2F, 0x95, + 0xCF, 0x66, 0x4A, 0x94, 0x14, 0x7D, 0x78, 0xF4, + 0x2C, 0xFC, 0x71, 0x4A, 0x40, 0xD2, 0x2E, 0xF1, + 0x94, 0x70, 0xE0, 0x53, 0x49, 0x35, 0x08, 0xA2 + }, + { + 0x29, 0x10, 0x25, 0x11, 0xD7, 0x49, 0xDB, 0x3C, + 0xC9, 0xB4, 0xE3, 0x35, 0xFA, 0x1F, 0x5E, 0x8F, + 0xAC, 0xA8, 0x42, 0x1D, 0x55, 0x8F, 0x6A, 0x3F, + 0x33, 0x21, 0xD5, 0x0D, 0x04, 0x4A, 0x24, 0x8B, + 0xA5, 0x95, 0xCF, 0xC3, 0xEF, 0xD3, 0xD2, 0xAD, + 0xC9, 0x73, 0x34, 0xDA, 0x73, 0x24, 0x13, 0xF5, + 0xCB, 0xF4, 0x75, 0x1C, 0x36, 0x2B, 0xA1, 0xD5, + 0x38, 0x62, 0xAC, 0x1E, 0x8D, 0xAB, 0xEE, 0xE8 + }, + { + 0xC9, 0x7A, 0x47, 0x79, 0xD4, 0x7E, 0x6F, 0x77, + 0x72, 0x9B, 0x59, 0x17, 0xD0, 0x13, 0x8A, 0xBB, + 0x35, 0x98, 0x0A, 0xB6, 0x41, 0xBD, 0x73, 0xA8, + 0x85, 0x9E, 0xB1, 0xAC, 0x98, 0xC0, 0x53, 0x62, + 0xED, 0x7D, 0x60, 0x8F, 0x2E, 0x95, 0x87, 0xD6, + 0xBA, 0x9E, 0x27, 0x1D, 0x34, 0x31, 0x25, 0xD4, + 0x0D, 0x93, 0x3A, 0x8E, 0xD0, 0x4E, 0xC1, 0xFE, + 0x75, 0xEC, 0x40, 0x7C, 0x7A, 0x53, 0xC3, 0x4E + }, + { + 0x10, 0xF0, 0xDC, 0x91, 0xB9, 0xF8, 0x45, 0xFB, + 0x95, 0xFA, 0xD6, 0x86, 0x0E, 0x6C, 0xE1, 0xAD, + 0xFA, 0x00, 0x2C, 0x7F, 0xC3, 0x27, 0x11, 0x6D, + 0x44, 0xD0, 0x47, 0xCD, 0x7D, 0x58, 0x70, 0xD7, + 0x72, 0xBB, 0x12, 0xB5, 0xFA, 0xC0, 0x0E, 0x02, + 0xB0, 0x8A, 0xC2, 0xA0, 0x17, 0x4D, 0x04, 0x46, + 0xC3, 0x6A, 0xB3, 0x5F, 0x14, 0xCA, 0x31, 0x89, + 0x4C, 0xD6, 0x1C, 0x78, 0xC8, 0x49, 0xB4, 0x8A + }, + { + 0xDE, 0xA9, 0x10, 0x1C, 0xAC, 0x62, 0xB8, 0xF6, + 0xA3, 0xC6, 0x50, 0xF9, 0x0E, 0xEA, 0x5B, 0xFA, + 0xE2, 0x65, 0x3A, 0x4E, 0xAF, 0xD6, 0x3A, 0x6D, + 0x1F, 0x0F, 0x13, 0x2D, 0xB9, 0xE4, 0xF2, 0xB1, + 0xB6, 0x62, 0x43, 0x2E, 0xC8, 0x5B, 0x17, 0xBC, + 0xAC, 0x41, 0xE7, 0x75, 0x63, 0x78, 0x81, 0xF6, + 0xAA, 0xB3, 0x8D, 0xD6, 0x6D, 0xCB, 0xD0, 0x80, + 0xF0, 0x99, 0x0A, 0x7A, 0x6E, 0x98, 0x54, 0xFE + }, + { + 0x44, 0x1F, 0xFA, 0xA0, 0x8C, 0xD7, 0x9D, 0xFF, + 0x4A, 0xFC, 0x9B, 0x9E, 0x5B, 0x56, 0x20, 0xEE, + 0xC0, 0x86, 0x73, 0x0C, 0x25, 0xF6, 0x61, 0xB1, + 0xD6, 0xFB, 0xFB, 0xD1, 0xCE, 0xC3, 0x14, 0x8D, + 0xD7, 0x22, 0x58, 0xC6, 0x56, 0x41, 0xF2, 0xFC, + 0xA5, 0xEB, 0x15, 0x5F, 0xAD, 0xBC, 0xAB, 0xB1, + 0x3C, 0x6E, 0x21, 0xDC, 0x11, 0xFA, 0xF7, 0x2C, + 0x2A, 0x28, 0x1B, 0x7D, 0x56, 0x14, 0x5F, 0x19 + }, + { + 0x44, 0x4B, 0x24, 0x0F, 0xE3, 0xED, 0x86, 0xD0, + 0xE2, 0xEF, 0x4C, 0xE7, 0xD8, 0x51, 0xED, 0xDE, + 0x22, 0x15, 0x55, 0x82, 0xAA, 0x09, 0x14, 0x79, + 0x7B, 0x72, 0x6C, 0xD0, 0x58, 0xB6, 0xF4, 0x59, + 0x32, 0xE0, 0xE1, 0x29, 0x51, 0x68, 0x76, 0x52, + 0x7B, 0x1D, 0xD8, 0x8F, 0xC6, 0x6D, 0x71, 0x19, + 0xF4, 0xAB, 0x3B, 0xED, 0x93, 0xA6, 0x1A, 0x0E, + 0x2D, 0x2D, 0x2A, 0xEA, 0xC3, 0x36, 0xD9, 0x58 + }, + { + 0xBF, 0xBA, 0xBB, 0xEF, 0x45, 0x55, 0x4C, 0xCF, + 0xA0, 0xDC, 0x83, 0x75, 0x2A, 0x19, 0xCC, 0x35, + 0xD5, 0x92, 0x09, 0x56, 0xB3, 0x01, 0xD5, 0x58, + 0xD7, 0x72, 0x28, 0x2B, 0xC8, 0x67, 0x00, 0x91, + 0x68, 0xE9, 0xE9, 0x86, 0x06, 0xBB, 0x5B, 0xA7, + 0x3A, 0x38, 0x5D, 0xE5, 0x74, 0x92, 0x28, 0xC9, + 0x25, 0xA8, 0x50, 0x19, 0xB7, 0x1F, 0x72, 0xFE, + 0x29, 0xB3, 0xCD, 0x37, 0xCA, 0x52, 0xEF, 0xE6 + }, + { + 0x9C, 0x4D, 0x0C, 0x3E, 0x1C, 0xDB, 0xBF, 0x48, + 0x5B, 0xEC, 0x86, 0xF4, 0x1C, 0xEC, 0x7C, 0x98, + 0x37, 0x3F, 0x0E, 0x09, 0xF3, 0x92, 0x84, 0x9A, + 0xAA, 0x22, 0x9E, 0xBF, 0xBF, 0x39, 0x7B, 0x22, + 0x08, 0x55, 0x29, 0xCB, 0x7E, 0xF3, 0x9F, 0x9C, + 0x7C, 0x22, 0x22, 0xA5, 0x14, 0x18, 0x2B, 0x1E, + 0xFF, 0xAA, 0x17, 0x8C, 0xC3, 0x68, 0x7B, 0x1B, + 0x2B, 0x6C, 0xBC, 0xB6, 0xFD, 0xEB, 0x96, 0xF8 + }, + { + 0x47, 0x71, 0x76, 0xB3, 0xBF, 0xCB, 0xAD, 0xD7, + 0x65, 0x7C, 0x23, 0xC2, 0x46, 0x25, 0xE4, 0xD0, + 0xD6, 0x74, 0xD1, 0x86, 0x8F, 0x00, 0x60, 0x06, + 0x39, 0x8A, 0xF9, 0x7A, 0xA4, 0x18, 0x77, 0xC8, + 0xE7, 0x0D, 0x3D, 0x14, 0xC3, 0xBB, 0xC9, 0xBB, + 0xCD, 0xCE, 0xA8, 0x01, 0xBD, 0x0E, 0x15, 0x99, + 0xAF, 0x1F, 0x3E, 0xEC, 0x67, 0x40, 0x51, 0x70, + 0xF4, 0xE2, 0x6C, 0x96, 0x4A, 0x57, 0xA8, 0xB7 + }, + { + 0xA7, 0x8C, 0x49, 0x0E, 0xDA, 0x31, 0x73, 0xBB, + 0x3F, 0x10, 0xDE, 0xE5, 0x2F, 0x11, 0x0F, 0xB1, + 0xC0, 0x8E, 0x03, 0x02, 0x23, 0x0B, 0x85, 0xDD, + 0xD7, 0xC1, 0x12, 0x57, 0xD9, 0x2D, 0xE1, 0x48, + 0x78, 0x5E, 0xF0, 0x0C, 0x03, 0x9C, 0x0B, 0xB8, + 0xEB, 0x98, 0x08, 0xA3, 0x5B, 0x2D, 0x8C, 0x08, + 0x0F, 0x57, 0x28, 0x59, 0x71, 0x4C, 0x9D, 0x40, + 0x69, 0xC5, 0xBC, 0xAF, 0x09, 0x0E, 0x89, 0x8E + }, + { + 0x58, 0xD0, 0x23, 0x39, 0x7B, 0xEB, 0x5B, 0x41, + 0x45, 0xCB, 0x22, 0x55, 0xB0, 0x7D, 0x74, 0x29, + 0x0B, 0x36, 0xD9, 0xFD, 0x1E, 0x59, 0x4A, 0xFB, + 0xD8, 0xEE, 0xA4, 0x7C, 0x20, 0x5B, 0x2E, 0xFB, + 0xFE, 0x6F, 0x46, 0x19, 0x0F, 0xAF, 0x95, 0xAF, + 0x50, 0x4A, 0xB0, 0x72, 0xE3, 0x6F, 0x6C, 0x85, + 0xD7, 0x67, 0xA3, 0x21, 0xBF, 0xD7, 0xF2, 0x26, + 0x87, 0xA4, 0xAB, 0xBF, 0x49, 0x4A, 0x68, 0x9C + }, + { + 0x40, 0x01, 0xEC, 0x74, 0xD5, 0xA4, 0x6F, 0xD2, + 0x9C, 0x2C, 0x3C, 0xDB, 0xE5, 0xD1, 0xB9, 0xF2, + 0x0E, 0x51, 0xA9, 0x41, 0xBE, 0x98, 0xD2, 0xA4, + 0xE1, 0xE2, 0xFB, 0xF8, 0x66, 0xA6, 0x72, 0x12, + 0x1D, 0xB6, 0xF8, 0x1A, 0x51, 0x4C, 0xFD, 0x10, + 0xE7, 0x35, 0x8D, 0x57, 0x1B, 0xDB, 0xA4, 0x8E, + 0x4C, 0xE7, 0x08, 0xB9, 0xD1, 0x24, 0x89, 0x4B, + 0xC0, 0xB5, 0xED, 0x55, 0x49, 0x35, 0xF7, 0x3A + }, + { + 0xCC, 0xD1, 0xB2, 0x2D, 0xAB, 0x65, 0x11, 0x22, + 0x5D, 0x24, 0x01, 0xEA, 0x2D, 0x86, 0x25, 0xD2, + 0x06, 0xA1, 0x24, 0x73, 0xCC, 0x73, 0x2B, 0x61, + 0x5E, 0x56, 0x40, 0xCE, 0xFF, 0xF0, 0xA4, 0xAD, + 0xF9, 0x71, 0xB0, 0xE8, 0x27, 0xA6, 0x19, 0xE0, + 0xA8, 0x0F, 0x5D, 0xB9, 0xCC, 0xD0, 0x96, 0x23, + 0x29, 0x01, 0x0D, 0x07, 0xE3, 0x4A, 0x20, 0x64, + 0xE7, 0x31, 0xC5, 0x20, 0x81, 0x7B, 0x21, 0x83 + }, + { + 0xB4, 0xA0, 0xA9, 0xE3, 0x57, 0x4E, 0xDB, 0x9E, + 0x1E, 0x72, 0xAA, 0x31, 0xE3, 0x9C, 0xC5, 0xF3, + 0x0D, 0xBF, 0x94, 0x3F, 0x8C, 0xAB, 0xC4, 0x08, + 0x44, 0x96, 0x54, 0xA3, 0x91, 0x31, 0xE6, 0x6D, + 0x71, 0x8A, 0x18, 0x81, 0x91, 0x43, 0xE3, 0xEA, + 0x96, 0xB4, 0xA1, 0x89, 0x59, 0x88, 0xA1, 0xC0, + 0x05, 0x6C, 0xF2, 0xB6, 0xE0, 0x4F, 0x9A, 0xC1, + 0x9D, 0x65, 0x73, 0x83, 0xC2, 0x91, 0x0C, 0x44 + }, + { + 0x44, 0x7B, 0xEC, 0xAB, 0x16, 0x63, 0x06, 0x08, + 0xD3, 0x9F, 0x4F, 0x05, 0x8B, 0x16, 0xF7, 0xAF, + 0x95, 0xB8, 0x5A, 0x76, 0xAA, 0x0F, 0xA7, 0xCE, + 0xA2, 0xB8, 0x07, 0x55, 0xFB, 0x76, 0xE9, 0xC8, + 0x04, 0xF2, 0xCA, 0x78, 0xF0, 0x26, 0x43, 0xC9, + 0x15, 0xFB, 0xF2, 0xFC, 0xE5, 0xE1, 0x9D, 0xE8, + 0x60, 0x00, 0xDE, 0x03, 0xB1, 0x88, 0x61, 0x81, + 0x5A, 0x83, 0x12, 0x60, 0x71, 0xF8, 0xA3, 0x7B + }, + { + 0x54, 0xE6, 0xDA, 0xB9, 0x97, 0x73, 0x80, 0xA5, + 0x66, 0x58, 0x22, 0xDB, 0x93, 0x37, 0x4E, 0xDA, + 0x52, 0x8D, 0x9B, 0xEB, 0x62, 0x6F, 0x9B, 0x94, + 0x02, 0x70, 0x71, 0xCB, 0x26, 0x67, 0x5E, 0x11, + 0x2B, 0x4A, 0x7F, 0xEC, 0x94, 0x1E, 0xE6, 0x0A, + 0x81, 0xE4, 0xD2, 0xEA, 0x3F, 0xF7, 0xBC, 0x52, + 0xCF, 0xC4, 0x5D, 0xFB, 0xFE, 0x73, 0x5A, 0x1C, + 0x64, 0x6B, 0x2C, 0xF6, 0xD6, 0xA4, 0x9B, 0x62 + }, + { + 0x3E, 0xA6, 0x26, 0x25, 0x94, 0x9E, 0x36, 0x46, + 0x70, 0x4D, 0x7E, 0x3C, 0x90, 0x6F, 0x82, 0xF6, + 0xC0, 0x28, 0xF5, 0x40, 0xF5, 0xF7, 0x2A, 0x79, + 0x4B, 0x0C, 0x57, 0xBF, 0x97, 0xB7, 0x64, 0x9B, + 0xFE, 0xB9, 0x0B, 0x01, 0xD3, 0xCA, 0x3E, 0x82, + 0x9D, 0xE2, 0x1B, 0x38, 0x26, 0xE6, 0xF8, 0x70, + 0x14, 0xD3, 0xC7, 0x73, 0x50, 0xCB, 0x5A, 0x15, + 0xFF, 0x5D, 0x46, 0x8A, 0x81, 0xBE, 0xC1, 0x60 + }, + { + 0x21, 0x3C, 0xFE, 0x14, 0x5C, 0x54, 0xA3, 0x36, + 0x91, 0x56, 0x99, 0x80, 0xE5, 0x93, 0x8C, 0x88, + 0x83, 0xA4, 0x6D, 0x84, 0xD1, 0x49, 0xC8, 0xFF, + 0x1A, 0x67, 0xCD, 0x28, 0x7B, 0x4D, 0x49, 0xC6, + 0xDA, 0x69, 0xD3, 0xA0, 0x35, 0x44, 0x3D, 0xB0, + 0x85, 0x98, 0x3D, 0x0E, 0xFE, 0x63, 0x70, 0x6B, + 0xD5, 0xB6, 0xF1, 0x5A, 0x7D, 0xA4, 0x59, 0xE8, + 0xD5, 0x0A, 0x19, 0x09, 0x3D, 0xB5, 0x5E, 0x80 + }, + { + 0x57, 0x16, 0xC4, 0xA3, 0x8F, 0x38, 0xDB, 0x10, + 0x4E, 0x49, 0x4A, 0x0A, 0x27, 0xCB, 0xE8, 0x9A, + 0x26, 0xA6, 0xBB, 0x6F, 0x49, 0x9E, 0xC0, 0x1C, + 0x8C, 0x01, 0xAA, 0x7C, 0xB8, 0x84, 0x97, 0xE7, + 0x51, 0x48, 0xCD, 0x6E, 0xEE, 0x12, 0xA7, 0x16, + 0x8B, 0x6F, 0x78, 0xAB, 0x74, 0xE4, 0xBE, 0x74, + 0x92, 0x51, 0xA1, 0xA7, 0x4C, 0x38, 0xC8, 0x6D, + 0x61, 0x29, 0x17, 0x7E, 0x28, 0x89, 0xE0, 0xB6 + }, + { + 0x03, 0x04, 0x60, 0xA9, 0x8B, 0xDF, 0x9F, 0xF1, + 0x7C, 0xD9, 0x64, 0x04, 0xF2, 0x8F, 0xC3, 0x04, + 0xF2, 0xB7, 0xC0, 0x4E, 0xAA, 0xDE, 0x53, 0x67, + 0x7F, 0xD2, 0x8F, 0x78, 0x8C, 0xA2, 0x21, 0x86, + 0xB8, 0xBC, 0x80, 0xDD, 0x21, 0xD1, 0x7F, 0x85, + 0x49, 0xC7, 0x11, 0xAF, 0xF0, 0xE5, 0x14, 0xE1, + 0x9D, 0x4E, 0x15, 0xF5, 0x99, 0x02, 0x52, 0xA0, + 0x3E, 0x08, 0x2F, 0x28, 0xDC, 0x20, 0x52, 0xF6 + }, + { + 0x19, 0xE7, 0xF1, 0xCC, 0xEE, 0x88, 0xA1, 0x06, + 0x72, 0x33, 0x3E, 0x39, 0x0C, 0xF2, 0x20, 0x13, + 0xA8, 0xC7, 0x34, 0xC6, 0xCB, 0x9E, 0xAB, 0x41, + 0xF1, 0x7C, 0x3C, 0x80, 0x32, 0xA2, 0xE4, 0xAC, + 0xA0, 0x56, 0x9E, 0xA3, 0x6F, 0x08, 0x60, 0xC7, + 0xA1, 0xAF, 0x28, 0xFA, 0x47, 0x68, 0x40, 0xD6, + 0x60, 0x11, 0x16, 0x88, 0x59, 0x33, 0x4A, 0x9E, + 0x4E, 0xF9, 0xCC, 0x2E, 0x61, 0xA0, 0xE2, 0x9E + }, + { + 0x29, 0xF8, 0xB8, 0xC7, 0x8C, 0x80, 0xF2, 0xFC, + 0xB4, 0xBD, 0xF7, 0x82, 0x5E, 0xD9, 0x0A, 0x70, + 0xD6, 0x25, 0xFF, 0x78, 0x5D, 0x26, 0x26, 0x77, + 0xE2, 0x50, 0xC0, 0x4F, 0x37, 0x20, 0xC8, 0x88, + 0xD0, 0x3F, 0x80, 0x45, 0xE4, 0xED, 0xF3, 0xF5, + 0x28, 0x5B, 0xD3, 0x9D, 0x92, 0x8A, 0x10, 0xA7, + 0xD0, 0xA5, 0xDF, 0x00, 0xB8, 0x48, 0x4A, 0xC2, + 0x86, 0x81, 0x42, 0xA1, 0xE8, 0xBE, 0xA3, 0x51 + }, + { + 0x5C, 0x52, 0x92, 0x0A, 0x72, 0x63, 0xE3, 0x9D, + 0x57, 0x92, 0x0C, 0xA0, 0xCB, 0x75, 0x2A, 0xC6, + 0xD7, 0x9A, 0x04, 0xFE, 0xF8, 0xA7, 0xA2, 0x16, + 0xA1, 0xEC, 0xB7, 0x11, 0x5C, 0xE0, 0x6D, 0x89, + 0xFD, 0x7D, 0x73, 0x5B, 0xD6, 0xF4, 0x27, 0x25, + 0x55, 0xDB, 0xA2, 0x2C, 0x2D, 0x1C, 0x96, 0xE6, + 0x35, 0x23, 0x22, 0xC6, 0x2C, 0x56, 0x30, 0xFD, + 0xE0, 0xF4, 0x77, 0x7A, 0x76, 0xC3, 0xDE, 0x2C + }, + { + 0x83, 0xB0, 0x98, 0xF2, 0x62, 0x25, 0x1B, 0xF6, + 0x60, 0x06, 0x4A, 0x9D, 0x35, 0x11, 0xCE, 0x76, + 0x87, 0xA0, 0x9E, 0x6D, 0xFB, 0xB8, 0x78, 0x29, + 0x9C, 0x30, 0xE9, 0x3D, 0xFB, 0x43, 0xA9, 0x31, + 0x4D, 0xB9, 0xA6, 0x00, 0x33, 0x7D, 0xB2, 0x6E, + 0xBE, 0xED, 0xAF, 0x22, 0x56, 0xA9, 0x6D, 0xAB, + 0xE9, 0xB2, 0x9E, 0x75, 0x73, 0xAD, 0x11, 0xC3, + 0x52, 0x3D, 0x87, 0x4D, 0xDE, 0x5B, 0xE7, 0xED + }, + { + 0x94, 0x47, 0xD9, 0x8A, 0xA5, 0xC9, 0x33, 0x13, + 0x52, 0xF4, 0x3D, 0x3E, 0x56, 0xD0, 0xA9, 0xA9, + 0xF9, 0x58, 0x18, 0x65, 0x99, 0x8E, 0x28, 0x85, + 0xCC, 0x56, 0xDD, 0x0A, 0x0B, 0xD5, 0xA7, 0xB5, + 0x05, 0x95, 0xBD, 0x10, 0xF7, 0x52, 0x9B, 0xCD, + 0x31, 0xF3, 0x7D, 0xC1, 0x6A, 0x14, 0x65, 0xD5, + 0x94, 0x07, 0x96, 0x67, 0xDA, 0x2A, 0x3F, 0xCB, + 0x70, 0x40, 0x14, 0x98, 0x83, 0x7C, 0xED, 0xEB + }, + { + 0x86, 0x77, 0x32, 0xF2, 0xFE, 0xEB, 0x23, 0x89, + 0x30, 0x97, 0x56, 0x1A, 0xC7, 0x10, 0xA4, 0xBF, + 0xF4, 0x53, 0xBE, 0x9C, 0xFB, 0xED, 0xBA, 0x8B, + 0xA3, 0x24, 0xF9, 0xD3, 0x12, 0xA8, 0x2D, 0x73, + 0x2E, 0x1B, 0x83, 0xB8, 0x29, 0xFD, 0xCD, 0x17, + 0x7B, 0x88, 0x2C, 0xA0, 0xC1, 0xBF, 0x54, 0x4B, + 0x22, 0x3B, 0xE5, 0x29, 0x92, 0x4A, 0x24, 0x6A, + 0x63, 0xCF, 0x05, 0x9B, 0xFD, 0xC5, 0x0A, 0x1B + }, + { + 0xF1, 0x5A, 0xB2, 0x6D, 0x4C, 0xDF, 0xCF, 0x56, + 0xE1, 0x96, 0xBB, 0x6B, 0xA1, 0x70, 0xA8, 0xFC, + 0xCC, 0x41, 0x4D, 0xE9, 0x28, 0x5A, 0xFD, 0x98, + 0xA3, 0xD3, 0xCF, 0x2F, 0xB8, 0x8F, 0xCB, 0xC0, + 0xF1, 0x98, 0x32, 0xAC, 0x43, 0x3A, 0x5B, 0x2C, + 0xC2, 0x39, 0x2A, 0x4C, 0xE3, 0x43, 0x32, 0x98, + 0x7D, 0x8D, 0x2C, 0x2B, 0xEF, 0x6C, 0x34, 0x66, + 0x13, 0x8D, 0xB0, 0xC6, 0xE4, 0x2F, 0xA4, 0x7B + }, + { + 0x28, 0x13, 0x51, 0x6D, 0x68, 0xED, 0x4A, 0x08, + 0xB3, 0x9D, 0x64, 0x8A, 0xA6, 0xAA, 0xCD, 0x81, + 0xE9, 0xD6, 0x55, 0xEC, 0xD5, 0xF0, 0xC1, 0x35, + 0x56, 0xC6, 0x0F, 0xDF, 0x0D, 0x33, 0x3E, 0xA3, + 0x84, 0x64, 0xB3, 0x6C, 0x02, 0xBA, 0xCC, 0xD7, + 0x46, 0xE9, 0x57, 0x5E, 0x96, 0xC6, 0x30, 0x14, + 0xF0, 0x74, 0xAE, 0x34, 0xA0, 0xA2, 0x5B, 0x32, + 0x0F, 0x0F, 0xBE, 0xDD, 0x6A, 0xCF, 0x76, 0x65 + }, + { + 0xD3, 0x25, 0x9A, 0xFC, 0xA8, 0xA4, 0x89, 0x62, + 0xFA, 0x89, 0x2E, 0x14, 0x5A, 0xCF, 0x54, 0x7F, + 0x26, 0x92, 0x3A, 0xE8, 0xD4, 0x92, 0x4C, 0x8A, + 0x53, 0x15, 0x81, 0x52, 0x6B, 0x04, 0xB4, 0x4C, + 0x7A, 0xF8, 0x3C, 0x64, 0x3E, 0xF5, 0xA0, 0xBC, + 0x28, 0x2D, 0x36, 0xF3, 0xFB, 0x04, 0xC8, 0x4E, + 0x28, 0xB3, 0x51, 0xF4, 0x0C, 0x74, 0xB6, 0x9D, + 0xC7, 0x84, 0x0B, 0xC7, 0x17, 0xB6, 0xF1, 0x5F + }, + { + 0xF1, 0x4B, 0x06, 0x1A, 0xE3, 0x59, 0xFA, 0x31, + 0xB9, 0x89, 0xE3, 0x03, 0x32, 0xBF, 0xE8, 0xDE, + 0x8C, 0xC8, 0xCD, 0xB5, 0x68, 0xE1, 0x4B, 0xE2, + 0x14, 0xA2, 0x22, 0x3B, 0x84, 0xCA, 0xAB, 0x74, + 0x19, 0x54, 0x9E, 0xCF, 0xCC, 0x96, 0xCE, 0x2A, + 0xCE, 0xC1, 0x19, 0x48, 0x5D, 0x87, 0xD1, 0x57, + 0xD3, 0xA8, 0x73, 0x4F, 0xC4, 0x26, 0x59, 0x7D, + 0x64, 0xF3, 0x65, 0x70, 0xCE, 0xAF, 0x22, 0x4D + }, + { + 0x55, 0xE7, 0x0B, 0x01, 0xD1, 0xFB, 0xF8, 0xB2, + 0x3B, 0x57, 0xFB, 0x62, 0xE2, 0x6C, 0x2C, 0xE5, + 0x4F, 0x13, 0xF8, 0xFA, 0x24, 0x64, 0xE6, 0xEB, + 0x98, 0xD1, 0x6A, 0x61, 0x17, 0x02, 0x6D, 0x8B, + 0x90, 0x81, 0x90, 0x12, 0x49, 0x6D, 0x40, 0x71, + 0xEB, 0xE2, 0xE5, 0x95, 0x57, 0xEC, 0xE3, 0x51, + 0x9A, 0x7A, 0xA4, 0x58, 0x02, 0xF9, 0x61, 0x53, + 0x74, 0x87, 0x73, 0x32, 0xB7, 0x34, 0x90, 0xB3 + }, + { + 0x25, 0x26, 0x1E, 0xB2, 0x96, 0x97, 0x1D, 0x6E, + 0x4A, 0x71, 0xB2, 0x92, 0x8E, 0x64, 0x83, 0x9C, + 0x67, 0xD4, 0x22, 0x87, 0x2B, 0xF9, 0xF3, 0xC3, + 0x19, 0x93, 0x61, 0x52, 0x22, 0xDE, 0x9F, 0x8F, + 0x0B, 0x2C, 0x4B, 0xE8, 0x54, 0x85, 0x59, 0xB4, + 0xB3, 0x54, 0xE7, 0x36, 0x41, 0x6E, 0x32, 0x18, + 0xD4, 0xE8, 0xA1, 0xE2, 0x19, 0xA4, 0xA6, 0xD4, + 0x3E, 0x1A, 0x9A, 0x52, 0x1D, 0x0E, 0x75, 0xFC + }, + { + 0x08, 0x30, 0x7F, 0x34, 0x7C, 0x41, 0x29, 0x4E, + 0x34, 0xBB, 0x54, 0xCB, 0x42, 0xB1, 0x52, 0x2D, + 0x22, 0xF8, 0x24, 0xF7, 0xB6, 0xE5, 0xDB, 0x50, + 0xFD, 0xA0, 0x96, 0x79, 0x8E, 0x18, 0x1A, 0x8F, + 0x02, 0x6F, 0xA2, 0x7B, 0x4A, 0xE4, 0x5D, 0x52, + 0xA6, 0x2C, 0xAF, 0x9D, 0x51, 0x98, 0xE2, 0x4A, + 0x49, 0x13, 0xC6, 0x67, 0x17, 0x75, 0xB2, 0xD7, + 0x23, 0xC1, 0x23, 0x9B, 0xFB, 0xF0, 0x16, 0xD7 + }, + { + 0x1E, 0x5C, 0x62, 0xE7, 0xE9, 0xBF, 0xA1, 0xB1, + 0x18, 0x74, 0x7A, 0x2D, 0xE0, 0x8B, 0x3C, 0xA1, + 0x01, 0x12, 0xAF, 0x96, 0xA4, 0x6E, 0x4B, 0x22, + 0xC3, 0xFC, 0x06, 0xF9, 0xBF, 0xEE, 0x4E, 0xB5, + 0xC4, 0x9E, 0x05, 0x7A, 0x4A, 0x48, 0x86, 0x23, + 0x43, 0x24, 0x57, 0x25, 0x76, 0xBB, 0x9B, 0x5E, + 0xCF, 0xDE, 0x0D, 0x99, 0xB0, 0xDE, 0x4F, 0x98, + 0xEC, 0x16, 0xE4, 0xD1, 0xB8, 0x5F, 0xA9, 0x47 + }, + { + 0xC7, 0x4A, 0x77, 0x39, 0x5F, 0xB8, 0xBC, 0x12, + 0x64, 0x47, 0x45, 0x48, 0x38, 0xE5, 0x61, 0xE9, + 0x62, 0x85, 0x3D, 0xC7, 0xEB, 0x49, 0xA1, 0xE3, + 0xCB, 0x67, 0xC3, 0xD0, 0x85, 0x1F, 0x3E, 0x39, + 0x51, 0x7B, 0xE8, 0xC3, 0x50, 0xAC, 0x91, 0x09, + 0x03, 0xD4, 0x9C, 0xD2, 0xBF, 0xDF, 0x54, 0x5C, + 0x99, 0x31, 0x6D, 0x03, 0x46, 0x17, 0x0B, 0x73, + 0x9F, 0x0A, 0xDD, 0x5D, 0x53, 0x3C, 0x2C, 0xFC + }, + { + 0x0D, 0xD5, 0x7B, 0x42, 0x3C, 0xC0, 0x1E, 0xB2, + 0x86, 0x13, 0x91, 0xEB, 0x88, 0x6A, 0x0D, 0x17, + 0x07, 0x9B, 0x93, 0x3F, 0xC7, 0x6E, 0xB3, 0xFC, + 0x08, 0xA1, 0x9F, 0x8A, 0x74, 0x95, 0x2C, 0xB6, + 0x8F, 0x6B, 0xCD, 0xC6, 0x44, 0xF7, 0x73, 0x70, + 0x96, 0x6E, 0x4D, 0x13, 0xE8, 0x05, 0x60, 0xBC, + 0xF0, 0x82, 0xEF, 0x04, 0x79, 0xD4, 0x8F, 0xBB, + 0xAB, 0x4D, 0xF0, 0x3B, 0x53, 0xA4, 0xE1, 0x78 + }, + { + 0x4D, 0x8D, 0xC3, 0x92, 0x3E, 0xDC, 0xCD, 0xFC, + 0xE7, 0x00, 0x72, 0x39, 0x8B, 0x8A, 0x3D, 0xA5, + 0xC3, 0x1F, 0xCB, 0x3E, 0xE3, 0xB6, 0x45, 0xC8, + 0x5F, 0x71, 0x7C, 0xBA, 0xEB, 0x4B, 0x67, 0x3A, + 0x19, 0x39, 0x44, 0x25, 0xA5, 0x85, 0xBF, 0xB4, + 0x64, 0xD9, 0x2F, 0x15, 0x97, 0xD0, 0xB7, 0x54, + 0xD1, 0x63, 0xF9, 0x7C, 0xED, 0x34, 0x3B, 0x25, + 0xDB, 0x5A, 0x70, 0xEF, 0x48, 0xEB, 0xB3, 0x4F + }, + { + 0xF0, 0xA5, 0x05, 0x53, 0xE4, 0xDF, 0xB0, 0xC4, + 0xE3, 0xE3, 0xD3, 0xBA, 0x82, 0x03, 0x48, 0x57, + 0xE3, 0xB1, 0xE5, 0x09, 0x18, 0xF5, 0xB8, 0xA7, + 0xD6, 0x98, 0xE1, 0x0D, 0x24, 0x2B, 0x0F, 0xB5, + 0x44, 0xAF, 0x6C, 0x92, 0xD0, 0xC3, 0xAA, 0xF9, + 0x93, 0x22, 0x20, 0x41, 0x61, 0x17, 0xB4, 0xE7, + 0x8E, 0xCB, 0x8A, 0x8F, 0x43, 0x0E, 0x13, 0xB8, + 0x2A, 0x59, 0x15, 0x29, 0x0A, 0x58, 0x19, 0xC5 + }, + { + 0xB1, 0x55, 0x43, 0xF3, 0xF7, 0x36, 0x08, 0x66, + 0x27, 0xCC, 0x53, 0x65, 0xE7, 0xE8, 0x98, 0x8C, + 0x2E, 0xF1, 0x55, 0xC0, 0xFD, 0x4F, 0x42, 0x89, + 0x61, 0xB0, 0x0D, 0x15, 0x26, 0xF0, 0x4D, 0x6D, + 0x6A, 0x65, 0x8B, 0x4B, 0x8E, 0xD3, 0x2C, 0x5D, + 0x86, 0x21, 0xE7, 0xF4, 0xF8, 0xE8, 0xA9, 0x33, + 0xD9, 0xEC, 0xC9, 0xDD, 0x1B, 0x83, 0x33, 0xCB, + 0xE2, 0x8C, 0xFC, 0x37, 0xD9, 0x71, 0x9E, 0x1C + }, + { + 0x7B, 0x4F, 0xA1, 0x58, 0xE4, 0x15, 0xFE, 0xF0, + 0x23, 0x24, 0x72, 0x64, 0xCB, 0xBE, 0x15, 0xD1, + 0x6D, 0x91, 0xA4, 0x44, 0x24, 0xA8, 0xDB, 0x70, + 0x7E, 0xB1, 0xE2, 0x03, 0x3C, 0x30, 0xE9, 0xE1, + 0xE7, 0xC8, 0xC0, 0x86, 0x45, 0x95, 0xD2, 0xCB, + 0x8C, 0x58, 0x0E, 0xB4, 0x7E, 0x9D, 0x16, 0xAB, + 0xBD, 0x7E, 0x44, 0xE8, 0x24, 0xF7, 0xCE, 0xDB, + 0x7D, 0xEF, 0x57, 0x13, 0x0E, 0x52, 0xCF, 0xE9 + }, + { + 0x60, 0x42, 0x4F, 0xF2, 0x32, 0x34, 0xC3, 0x4D, + 0xC9, 0x68, 0x7A, 0xD5, 0x02, 0x86, 0x93, 0x72, + 0xCC, 0x31, 0xA5, 0x93, 0x80, 0x18, 0x6B, 0xC2, + 0x36, 0x1C, 0x83, 0x5D, 0x97, 0x2F, 0x49, 0x66, + 0x6E, 0xB1, 0xAC, 0x69, 0x62, 0x9D, 0xE6, 0x46, + 0xF0, 0x3F, 0x9B, 0x4D, 0xB9, 0xE2, 0xAC, 0xE0, + 0x93, 0xFB, 0xFD, 0xF8, 0xF2, 0x0A, 0xB5, 0xF9, + 0x85, 0x41, 0x97, 0x8B, 0xE8, 0xEF, 0x54, 0x9F + }, + { + 0x74, 0x06, 0x01, 0x8C, 0xE7, 0x04, 0xD8, 0x4F, + 0x5E, 0xB9, 0xC7, 0x9F, 0xEA, 0x97, 0xDA, 0x34, + 0x56, 0x99, 0x46, 0x8A, 0x35, 0x0E, 0xE0, 0xB2, + 0xD0, 0xF3, 0xA4, 0xBF, 0x20, 0x70, 0x30, 0x4E, + 0xA8, 0x62, 0xD7, 0x2A, 0x51, 0xC5, 0x7D, 0x30, + 0x64, 0x94, 0x72, 0x86, 0xF5, 0x31, 0xE0, 0xEA, + 0xF7, 0x56, 0x37, 0x02, 0x26, 0x2E, 0x6C, 0x72, + 0x4A, 0xBF, 0x5E, 0xD8, 0xC8, 0x39, 0x8D, 0x17 + }, + { + 0x14, 0xEF, 0x5C, 0x6D, 0x64, 0x7B, 0x3B, 0xD1, + 0xE6, 0xE3, 0x20, 0x06, 0xC2, 0x31, 0x19, 0x98, + 0x10, 0xDE, 0x5C, 0x4D, 0xC8, 0x8E, 0x70, 0x24, + 0x02, 0x73, 0xB0, 0xEA, 0x18, 0xE6, 0x51, 0xA3, + 0xEB, 0x4F, 0x5C, 0xA3, 0x11, 0x4B, 0x8A, 0x56, + 0x71, 0x69, 0x69, 0xC7, 0xCD, 0xA2, 0x7E, 0x0C, + 0x8D, 0xB8, 0x32, 0xAD, 0x5E, 0x89, 0xA2, 0xDC, + 0x6C, 0xB0, 0xAD, 0xBE, 0x7D, 0x93, 0xAB, 0xD1 + }, + { + 0x38, 0xCF, 0x6C, 0x24, 0xE3, 0xE0, 0x8B, 0xCF, + 0x1F, 0x6C, 0xF3, 0xD1, 0xB1, 0xF6, 0x5B, 0x90, + 0x52, 0x39, 0xA3, 0x11, 0x80, 0x33, 0x24, 0x9E, + 0x44, 0x81, 0x13, 0xEC, 0x63, 0x2E, 0xA6, 0xDC, + 0x34, 0x6F, 0xEE, 0xB2, 0x57, 0x1C, 0x38, 0xBD, + 0x9A, 0x73, 0x98, 0xB2, 0x22, 0x12, 0x80, 0x32, + 0x80, 0x02, 0xB2, 0x3E, 0x1A, 0x45, 0xAD, 0xAF, + 0xFE, 0x66, 0xD9, 0x3F, 0x65, 0x64, 0xEA, 0xA2 + }, + { + 0x6C, 0xD7, 0x20, 0x8A, 0x4B, 0xC7, 0xE7, 0xE5, + 0x62, 0x01, 0xBB, 0xBA, 0x02, 0xA0, 0xF4, 0x89, + 0xCD, 0x38, 0x4A, 0xBE, 0x40, 0xAF, 0xD4, 0x22, + 0x2F, 0x15, 0x8B, 0x3D, 0x98, 0x6E, 0xE7, 0x2A, + 0x54, 0xC5, 0x0F, 0xB6, 0x4F, 0xD4, 0xED, 0x25, + 0x30, 0xED, 0xA2, 0xC8, 0xAF, 0x29, 0x28, 0xA0, + 0xDA, 0x6D, 0x4F, 0x83, 0x0A, 0xE1, 0xC9, 0xDB, + 0x46, 0x9D, 0xFD, 0x97, 0x0F, 0x12, 0xA5, 0x6F + }, + { + 0x65, 0x98, 0x58, 0xF0, 0xB5, 0xC9, 0xED, 0xAB, + 0x5B, 0x94, 0xFD, 0x73, 0x2F, 0x6E, 0x6B, 0x17, + 0xC5, 0x1C, 0xC0, 0x96, 0x10, 0x4F, 0x09, 0xBE, + 0xB3, 0xAF, 0xC3, 0xAA, 0x46, 0x7C, 0x2E, 0xCF, + 0x88, 0x5C, 0x4C, 0x65, 0x41, 0xEF, 0xFA, 0x90, + 0x23, 0xD3, 0xB5, 0x73, 0x8A, 0xE5, 0xA1, 0x4D, + 0x86, 0x7E, 0x15, 0xDB, 0x06, 0xFE, 0x1F, 0x9D, + 0x11, 0x27, 0xB7, 0x7E, 0x1A, 0xAB, 0xB5, 0x16 + }, + { + 0x26, 0xCC, 0xA0, 0x12, 0x6F, 0x5D, 0x1A, 0x81, + 0x3C, 0x62, 0xE5, 0xC7, 0x10, 0x01, 0xC0, 0x46, + 0xF9, 0xC9, 0x20, 0x95, 0x70, 0x45, 0x50, 0xBE, + 0x58, 0x73, 0xA4, 0x95, 0xA9, 0x99, 0xAD, 0x01, + 0x0A, 0x4F, 0x79, 0x49, 0x1F, 0x24, 0xF2, 0x86, + 0x50, 0x0A, 0xDC, 0xE1, 0xA1, 0x37, 0xBC, 0x20, + 0x84, 0xE4, 0x94, 0x9F, 0x5B, 0x72, 0x94, 0xCE, + 0xFE, 0x51, 0xEC, 0xAF, 0xF8, 0xE9, 0x5C, 0xBA + }, + { + 0x41, 0x47, 0xC1, 0xF5, 0x51, 0x72, 0x78, 0x8C, + 0x55, 0x67, 0xC5, 0x61, 0xFE, 0xEF, 0x87, 0x6F, + 0x62, 0x1F, 0xFF, 0x1C, 0xE8, 0x77, 0x86, 0xB8, + 0x46, 0x76, 0x37, 0xE7, 0x0D, 0xFB, 0xCD, 0x0D, + 0xBD, 0xB6, 0x41, 0x5C, 0xB6, 0x00, 0x95, 0x4A, + 0xB9, 0xC0, 0x4C, 0x0E, 0x45, 0x7E, 0x62, 0x5B, + 0x40, 0x72, 0x22, 0xC0, 0xFE, 0x1A, 0xE2, 0x1B, + 0x21, 0x43, 0x68, 0x8A, 0xDA, 0x94, 0xDC, 0x58 + }, + { + 0x5B, 0x1B, 0xF1, 0x54, 0xC6, 0x2A, 0x8A, 0xF6, + 0xE9, 0x3D, 0x35, 0xF1, 0x8F, 0x7F, 0x90, 0xAB, + 0xB1, 0x6A, 0x6E, 0xF0, 0xE8, 0xD1, 0xAE, 0xCD, + 0x11, 0x8B, 0xF7, 0x01, 0x67, 0xBA, 0xB2, 0xAF, + 0x08, 0x93, 0x5C, 0x6F, 0xDC, 0x06, 0x63, 0xCE, + 0x74, 0x48, 0x2D, 0x17, 0xA8, 0xE5, 0x4B, 0x54, + 0x6D, 0x1C, 0x29, 0x66, 0x31, 0xC6, 0x5F, 0x3B, + 0x52, 0x2A, 0x51, 0x58, 0x39, 0xD4, 0x3D, 0x71 + }, + { + 0x9F, 0x60, 0x04, 0x19, 0xA4, 0xE8, 0xF4, 0xFB, + 0x83, 0x4C, 0x24, 0xB0, 0xF7, 0xFC, 0x13, 0xBF, + 0x4E, 0x27, 0x9D, 0x98, 0xE8, 0xA3, 0xC7, 0x65, + 0xEE, 0x93, 0x49, 0x17, 0x40, 0x3E, 0x3A, 0x66, + 0x09, 0x71, 0x82, 0xEA, 0x21, 0x45, 0x3C, 0xB6, + 0x3E, 0xBB, 0xE8, 0xB7, 0x3A, 0x9C, 0x21, 0x67, + 0x59, 0x64, 0x46, 0x43, 0x8C, 0x57, 0x62, 0x7F, + 0x33, 0x0B, 0xAD, 0xD4, 0xF5, 0x69, 0xF7, 0xD6 + }, + { + 0x45, 0x7E, 0xF6, 0x46, 0x6A, 0x89, 0x24, 0xFD, + 0x80, 0x11, 0xA3, 0x44, 0x71, 0xA5, 0xA1, 0xAC, + 0x8C, 0xCD, 0x9B, 0xD0, 0xD0, 0x7A, 0x97, 0x41, + 0x4A, 0xC9, 0x43, 0x02, 0x1C, 0xE4, 0xB9, 0xE4, + 0xB9, 0xC8, 0xDB, 0x0A, 0x28, 0xF0, 0x16, 0xED, + 0x43, 0xB1, 0x54, 0x24, 0x81, 0x99, 0x00, 0x22, + 0x14, 0x7B, 0x31, 0x3E, 0x19, 0x46, 0x71, 0x13, + 0x1E, 0x70, 0x8D, 0xD4, 0x3A, 0x3E, 0xD7, 0xDC + }, + { + 0x99, 0x97, 0xB2, 0x19, 0x4D, 0x9A, 0xF6, 0xDF, + 0xCB, 0x91, 0x43, 0xF4, 0x1C, 0x0E, 0xD8, 0x3D, + 0x3A, 0x3F, 0x43, 0x88, 0x36, 0x11, 0x03, 0xD3, + 0x8C, 0x2A, 0x49, 0xB2, 0x80, 0xA5, 0x81, 0x21, + 0x27, 0x15, 0xFD, 0x90, 0x8D, 0x41, 0xC6, 0x51, + 0xF5, 0xC7, 0x15, 0xCA, 0x38, 0xC0, 0xCE, 0x28, + 0x30, 0xA3, 0x7E, 0x00, 0xE5, 0x08, 0xCE, 0xD1, + 0xBC, 0xDC, 0x32, 0x0E, 0x5E, 0x4D, 0x1E, 0x2E + }, + { + 0x5C, 0x6B, 0xBF, 0x16, 0xBA, 0xA1, 0x80, 0xF9, + 0x86, 0xBD, 0x40, 0xA1, 0x28, 0x7E, 0xD4, 0xC5, + 0x49, 0x77, 0x0E, 0x72, 0x84, 0x85, 0x8F, 0xC4, + 0x7B, 0xC2, 0x1A, 0xB9, 0x5E, 0xBB, 0xF3, 0x37, + 0x4B, 0x4E, 0xE3, 0xFD, 0x9F, 0x2A, 0xF6, 0x0F, + 0x33, 0x95, 0x22, 0x1B, 0x2A, 0xCC, 0x76, 0xF2, + 0xD3, 0x4C, 0x13, 0x29, 0x54, 0x04, 0x9F, 0x8A, + 0x3A, 0x99, 0x6F, 0x1E, 0x32, 0xEC, 0x84, 0xE5 + }, + { + 0xD1, 0x0B, 0xF9, 0xA1, 0x5B, 0x1C, 0x9F, 0xC8, + 0xD4, 0x1F, 0x89, 0xBB, 0x14, 0x0B, 0xF0, 0xBE, + 0x08, 0xD2, 0xF3, 0x66, 0x61, 0x76, 0xD1, 0x3B, + 0xAA, 0xC4, 0xD3, 0x81, 0x35, 0x8A, 0xD0, 0x74, + 0xC9, 0xD4, 0x74, 0x8C, 0x30, 0x05, 0x20, 0xEB, + 0x02, 0x6D, 0xAE, 0xAE, 0xA7, 0xC5, 0xB1, 0x58, + 0x89, 0x2F, 0xDE, 0x4E, 0x8E, 0xC1, 0x7D, 0xC9, + 0x98, 0xDC, 0xD5, 0x07, 0xDF, 0x26, 0xEB, 0x63 + }, + { + 0x2F, 0xC6, 0xE6, 0x9F, 0xA2, 0x6A, 0x89, 0xA5, + 0xED, 0x26, 0x90, 0x92, 0xCB, 0x9B, 0x2A, 0x44, + 0x9A, 0x44, 0x09, 0xA7, 0xA4, 0x40, 0x11, 0xEE, + 0xCA, 0xD1, 0x3D, 0x7C, 0x4B, 0x04, 0x56, 0x60, + 0x2D, 0x40, 0x2F, 0xA5, 0x84, 0x4F, 0x1A, 0x7A, + 0x75, 0x81, 0x36, 0xCE, 0x3D, 0x5D, 0x8D, 0x0E, + 0x8B, 0x86, 0x92, 0x1F, 0xFF, 0xF4, 0xF6, 0x92, + 0xDD, 0x95, 0xBD, 0xC8, 0xE5, 0xFF, 0x00, 0x52 + }, + { + 0xFC, 0xBE, 0x8B, 0xE7, 0xDC, 0xB4, 0x9A, 0x32, + 0xDB, 0xDF, 0x23, 0x94, 0x59, 0xE2, 0x63, 0x08, + 0xB8, 0x4D, 0xFF, 0x1E, 0xA4, 0x80, 0xDF, 0x8D, + 0x10, 0x4E, 0xEF, 0xF3, 0x4B, 0x46, 0xFA, 0xE9, + 0x86, 0x27, 0xB4, 0x50, 0xC2, 0x26, 0x7D, 0x48, + 0xC0, 0x94, 0x6A, 0x69, 0x7C, 0x5B, 0x59, 0x53, + 0x14, 0x52, 0xAC, 0x04, 0x84, 0xF1, 0xC8, 0x4E, + 0x3A, 0x33, 0xD0, 0xC3, 0x39, 0xBB, 0x2E, 0x28 + }, + { + 0xA1, 0x90, 0x93, 0xA6, 0xE3, 0xBC, 0xF5, 0x95, + 0x2F, 0x85, 0x0F, 0x20, 0x30, 0xF6, 0x9B, 0x96, + 0x06, 0xF1, 0x47, 0xF9, 0x0B, 0x8B, 0xAE, 0xE3, + 0x36, 0x2D, 0xA7, 0x1D, 0x9F, 0x35, 0xB4, 0x4E, + 0xF9, 0xD8, 0xF0, 0xA7, 0x71, 0x2B, 0xA1, 0x87, + 0x7F, 0xDD, 0xCD, 0x2D, 0x8E, 0xA8, 0xF1, 0xE5, + 0xA7, 0x73, 0xD0, 0xB7, 0x45, 0xD4, 0x72, 0x56, + 0x05, 0x98, 0x3A, 0x2D, 0xE9, 0x01, 0xF8, 0x03 + }, + { + 0x3C, 0x20, 0x06, 0x42, 0x3F, 0x73, 0xE2, 0x68, + 0xFA, 0x59, 0xD2, 0x92, 0x03, 0x77, 0xEB, 0x29, + 0xA4, 0xF9, 0xA8, 0xB4, 0x62, 0xBE, 0x15, 0x98, + 0x3E, 0xE3, 0xB8, 0x5A, 0xE8, 0xA7, 0x8E, 0x99, + 0x26, 0x33, 0x58, 0x1A, 0x90, 0x99, 0x89, 0x3B, + 0x63, 0xDB, 0x30, 0x24, 0x1C, 0x34, 0xF6, 0x43, + 0x02, 0x7D, 0xC8, 0x78, 0x27, 0x9A, 0xF5, 0x85, + 0x0D, 0x7E, 0x2D, 0x4A, 0x26, 0x53, 0x07, 0x3A + }, + { + 0xD0, 0xF2, 0xF2, 0xE3, 0x78, 0x76, 0x53, 0xF7, + 0x7C, 0xCE, 0x2F, 0xA2, 0x48, 0x35, 0x78, 0x5B, + 0xBD, 0x0C, 0x43, 0x3F, 0xC7, 0x79, 0x46, 0x5A, + 0x11, 0x51, 0x49, 0x90, 0x5A, 0x9D, 0xD1, 0xCB, + 0x82, 0x7A, 0x62, 0x85, 0x06, 0xD4, 0x57, 0xFC, + 0xF1, 0x24, 0xA0, 0xC2, 0xAE, 0xF9, 0xCE, 0x2D, + 0x2A, 0x0A, 0x0F, 0x63, 0x54, 0x55, 0x70, 0xD8, + 0x66, 0x7F, 0xF9, 0xE2, 0xEB, 0xA0, 0x73, 0x34 + }, + { + 0x78, 0xA9, 0xFC, 0x04, 0x8E, 0x25, 0xC6, 0xDC, + 0xB5, 0xDE, 0x45, 0x66, 0x7D, 0xE8, 0xFF, 0xDD, + 0x3A, 0x93, 0x71, 0x11, 0x41, 0xD5, 0x94, 0xE9, + 0xFA, 0x62, 0xA9, 0x59, 0x47, 0x5D, 0xA6, 0x07, + 0x5E, 0xA8, 0xF0, 0x91, 0x6E, 0x84, 0xE4, 0x5A, + 0xD9, 0x11, 0xB7, 0x54, 0x67, 0x07, 0x7E, 0xE5, + 0x2D, 0x2C, 0x9A, 0xEB, 0xF4, 0xD5, 0x8F, 0x20, + 0xCE, 0x4A, 0x3A, 0x00, 0x45, 0x8B, 0x05, 0xD4 + }, + { + 0x45, 0x81, 0x3F, 0x44, 0x17, 0x69, 0xAB, 0x6E, + 0xD3, 0x7D, 0x34, 0x9F, 0xF6, 0xE7, 0x22, 0x67, + 0xD7, 0x6A, 0xE6, 0xBB, 0x3E, 0x3C, 0x61, 0x2E, + 0xC0, 0x5C, 0x6E, 0x02, 0xA1, 0x2A, 0xF5, 0xA3, + 0x7C, 0x91, 0x8B, 0x52, 0xBF, 0x74, 0x26, 0x7C, + 0x3F, 0x6A, 0x3F, 0x18, 0x3A, 0x80, 0x64, 0xFF, + 0x84, 0xC0, 0x7B, 0x19, 0x3D, 0x08, 0x06, 0x67, + 0x89, 0xA0, 0x1A, 0xCC, 0xDB, 0x6F, 0x93, 0x40 + }, + { + 0x95, 0x6D, 0xA1, 0xC6, 0x8D, 0x83, 0xA7, 0xB8, + 0x81, 0xE0, 0x1B, 0x9A, 0x96, 0x6C, 0x3C, 0x0B, + 0xF2, 0x7F, 0x68, 0x60, 0x6A, 0x8B, 0x71, 0xD4, + 0x57, 0xBD, 0x01, 0x6D, 0x4C, 0x41, 0xDD, 0x8A, + 0x38, 0x0C, 0x70, 0x9A, 0x29, 0x6C, 0xB4, 0xC6, + 0x54, 0x47, 0x92, 0x92, 0x0F, 0xD7, 0x88, 0x83, + 0x57, 0x71, 0xA0, 0x7D, 0x4A, 0x16, 0xFB, 0x52, + 0xED, 0x48, 0x05, 0x03, 0x31, 0xDC, 0x4C, 0x8B + }, + { + 0xDF, 0x18, 0x6C, 0x2D, 0xC0, 0x9C, 0xAA, 0x48, + 0xE1, 0x4E, 0x94, 0x2F, 0x75, 0xDE, 0x5A, 0xC1, + 0xB7, 0xA2, 0x1E, 0x4F, 0x9F, 0x07, 0x2A, 0x5B, + 0x37, 0x1E, 0x09, 0xE0, 0x73, 0x45, 0xB0, 0x74, + 0x0C, 0x76, 0x17, 0x7B, 0x01, 0x27, 0x88, 0x08, + 0xFE, 0xC0, 0x25, 0xED, 0xED, 0x98, 0x22, 0xC1, + 0x22, 0xAF, 0xD1, 0xC6, 0x3E, 0x6F, 0x0C, 0xE2, + 0xE3, 0x26, 0x31, 0x04, 0x10, 0x63, 0x14, 0x5C + }, + { + 0x87, 0x47, 0x56, 0x40, 0x96, 0x6A, 0x9F, 0xDC, + 0xD6, 0xD3, 0xA3, 0xB5, 0xA2, 0xCC, 0xA5, 0xC0, + 0x8F, 0x0D, 0x88, 0x2B, 0x10, 0x24, 0x3C, 0x0E, + 0xC1, 0xBF, 0x3C, 0x6B, 0x1C, 0x37, 0xF2, 0xCD, + 0x32, 0x12, 0xF1, 0x9A, 0x05, 0x78, 0x64, 0x47, + 0x7D, 0x5E, 0xAF, 0x8F, 0xAE, 0xD7, 0x3F, 0x29, + 0x37, 0xC7, 0x68, 0xA0, 0xAF, 0x41, 0x5E, 0x84, + 0xBB, 0xCE, 0x6B, 0xD7, 0xDE, 0x23, 0xB6, 0x60 + }, + { + 0xC3, 0xB5, 0x73, 0xBB, 0xE1, 0x09, 0x49, 0xA0, + 0xFB, 0xD4, 0xFF, 0x88, 0x4C, 0x44, 0x6F, 0x22, + 0x29, 0xB7, 0x69, 0x02, 0xF9, 0xDF, 0xDB, 0xB8, + 0xA0, 0x35, 0x3D, 0xA5, 0xC8, 0x3C, 0xA1, 0x4E, + 0x81, 0x51, 0xBB, 0xAA, 0xC8, 0x2F, 0xD1, 0x57, + 0x6A, 0x00, 0x9A, 0xDC, 0x6F, 0x19, 0x35, 0xCF, + 0x26, 0xED, 0xD4, 0xF1, 0xFB, 0x8D, 0xA4, 0x83, + 0xE6, 0xC5, 0xCD, 0x9D, 0x89, 0x23, 0xAD, 0xC3 + }, + { + 0xB0, 0x9D, 0x8D, 0x0B, 0xBA, 0x8A, 0x72, 0x86, + 0xE4, 0x35, 0x68, 0xF7, 0x90, 0x75, 0x50, 0xE4, + 0x20, 0x36, 0xD6, 0x74, 0xE3, 0xC8, 0xFC, 0x34, + 0xD8, 0xCA, 0x46, 0xF7, 0x71, 0xD6, 0x46, 0x6B, + 0x70, 0xFB, 0x60, 0x58, 0x75, 0xF6, 0xA8, 0x63, + 0xC8, 0x77, 0xD1, 0x2F, 0x07, 0x06, 0x3F, 0xDC, + 0x2E, 0x90, 0xCC, 0xD4, 0x59, 0xB1, 0x91, 0x0D, + 0xCD, 0x52, 0xD8, 0xF1, 0x0B, 0x2B, 0x0A, 0x15 + }, + { + 0xAF, 0x3A, 0x22, 0xBF, 0x75, 0xB2, 0x1A, 0xBF, + 0xB0, 0xAC, 0xD5, 0x44, 0x22, 0xBA, 0x1B, 0x73, + 0x00, 0xA9, 0x52, 0xEF, 0xF0, 0x2E, 0xBE, 0xB6, + 0x5B, 0x5C, 0x23, 0x44, 0x71, 0xA9, 0x8D, 0xF3, + 0x2F, 0x4F, 0x96, 0x43, 0xCE, 0x19, 0x04, 0x10, + 0x8A, 0x16, 0x87, 0x67, 0x92, 0x42, 0x80, 0xBD, + 0x76, 0xC8, 0x3F, 0x8C, 0x82, 0xD9, 0xA7, 0x9D, + 0x92, 0x59, 0xB1, 0x95, 0x36, 0x2A, 0x2A, 0x04 + }, + { + 0xBF, 0x4F, 0xF2, 0x22, 0x1B, 0x7E, 0x69, 0x57, + 0xA7, 0x24, 0xCD, 0x96, 0x4A, 0xA3, 0xD5, 0xD0, + 0xD9, 0x94, 0x1F, 0x54, 0x04, 0x13, 0x75, 0x2F, + 0x46, 0x99, 0xD8, 0x10, 0x1B, 0x3E, 0x53, 0x75, + 0x08, 0xBF, 0x09, 0xF8, 0x50, 0x8B, 0x31, 0x77, + 0x36, 0xFF, 0xD2, 0x65, 0xF2, 0x84, 0x7A, 0xA7, + 0xD8, 0x4B, 0xD2, 0xD9, 0x75, 0x69, 0xC4, 0x9D, + 0x63, 0x2A, 0xED, 0x99, 0x45, 0xE5, 0xFA, 0x5E + }, + { + 0x9C, 0x6B, 0x6B, 0x78, 0x19, 0x9B, 0x1B, 0xDA, + 0xCB, 0x43, 0x00, 0xE3, 0x14, 0x79, 0xFA, 0x62, + 0x2A, 0x6B, 0x5B, 0xC8, 0x0D, 0x46, 0x78, 0xA6, + 0x07, 0x8F, 0x88, 0xA8, 0x26, 0x8C, 0xD7, 0x20, + 0x6A, 0x27, 0x99, 0xE8, 0xD4, 0x62, 0x1A, 0x46, + 0x4E, 0xF6, 0xB4, 0x3D, 0xD8, 0xAD, 0xFF, 0xE9, + 0x7C, 0xAF, 0x22, 0x1B, 0x22, 0xB6, 0xB8, 0x77, + 0x8B, 0x14, 0x9A, 0x82, 0x2A, 0xEF, 0xBB, 0x09 + }, + { + 0x89, 0x06, 0x56, 0xF0, 0x9C, 0x99, 0xD2, 0x80, + 0xB5, 0xEC, 0xB3, 0x81, 0xF5, 0x64, 0x27, 0xB8, + 0x13, 0x75, 0x1B, 0xC6, 0x52, 0xC7, 0x82, 0x80, + 0x78, 0xB2, 0x3A, 0x4A, 0xF8, 0x3B, 0x4E, 0x3A, + 0x61, 0xFD, 0xBA, 0xC6, 0x1F, 0x89, 0xBE, 0xE8, + 0x4E, 0xA6, 0xBE, 0xE7, 0x60, 0xC0, 0x47, 0xF2, + 0x5C, 0x6B, 0x0A, 0x20, 0x1C, 0x69, 0xA3, 0x8F, + 0xD6, 0xFD, 0x97, 0x1A, 0xF1, 0x85, 0x88, 0xBB + }, + { + 0x31, 0xA0, 0x46, 0xF7, 0x88, 0x2F, 0xFE, 0x6F, + 0x83, 0xCE, 0x47, 0x2E, 0x9A, 0x07, 0x01, 0x83, + 0x2E, 0xC7, 0xB3, 0xF7, 0x6F, 0xBC, 0xFD, 0x1D, + 0xF6, 0x0F, 0xE3, 0xEA, 0x48, 0xFD, 0xE1, 0x65, + 0x12, 0x54, 0x24, 0x7C, 0x3F, 0xD9, 0x5E, 0x10, + 0x0F, 0x91, 0x72, 0x73, 0x1E, 0x17, 0xFD, 0x52, + 0x97, 0xC1, 0x1F, 0x4B, 0xB3, 0x28, 0x36, 0x3C, + 0xA3, 0x61, 0x62, 0x4A, 0x81, 0xAF, 0x79, 0x7C + }, + { + 0x27, 0xA6, 0x0B, 0x2D, 0x00, 0xE7, 0xA6, 0x71, + 0xD4, 0x7D, 0x0A, 0xEC, 0x2A, 0x68, 0x6A, 0x0A, + 0xC0, 0x4B, 0x52, 0xF4, 0x0A, 0xB6, 0x62, 0x90, + 0x28, 0xEB, 0x7D, 0x13, 0xF4, 0xBA, 0xA9, 0x9A, + 0xC0, 0xFE, 0x46, 0xEE, 0x6C, 0x81, 0x49, 0x44, + 0xF2, 0xF4, 0xB4, 0xD2, 0x0E, 0x93, 0x78, 0xE4, + 0x84, 0x7E, 0xA4, 0x4C, 0x13, 0x17, 0x80, 0x91, + 0xE2, 0x77, 0xB8, 0x7E, 0xA7, 0xA5, 0x57, 0x11 + }, + { + 0x8B, 0x5C, 0xCE, 0xF1, 0x94, 0x16, 0x2C, 0x1F, + 0x19, 0xD6, 0x8F, 0x91, 0xE0, 0xB0, 0x92, 0x8F, + 0x28, 0x9E, 0xC5, 0x28, 0x37, 0x20, 0x84, 0x0C, + 0x2F, 0x73, 0xD2, 0x53, 0x11, 0x12, 0x38, 0xDC, + 0xFE, 0x94, 0xAF, 0x2B, 0x59, 0xC2, 0xC1, 0xCA, + 0x25, 0x91, 0x90, 0x1A, 0x7B, 0xC0, 0x60, 0xE7, + 0x45, 0x9B, 0x6C, 0x47, 0xDF, 0x0F, 0x71, 0x70, + 0x1A, 0x35, 0xCC, 0x0A, 0xA8, 0x31, 0xB5, 0xB6 + }, + { + 0x57, 0xAB, 0x6C, 0x4B, 0x22, 0x29, 0xAE, 0xB3, + 0xB7, 0x04, 0x76, 0xD8, 0x03, 0xCD, 0x63, 0x81, + 0x2F, 0x10, 0x7C, 0xE6, 0xDA, 0x17, 0xFE, 0xD9, + 0xB1, 0x78, 0x75, 0xE8, 0xF8, 0x6C, 0x72, 0x4F, + 0x49, 0xE0, 0x24, 0xCB, 0xF3, 0xA1, 0xB8, 0xB1, + 0x19, 0xC5, 0x03, 0x57, 0x65, 0x2B, 0x81, 0x87, + 0x9D, 0x2A, 0xDE, 0x2D, 0x58, 0x8B, 0x9E, 0x4F, + 0x7C, 0xED, 0xBA, 0x0E, 0x46, 0x44, 0xC9, 0xEE + }, + { + 0x01, 0x90, 0xA8, 0xDA, 0xC3, 0x20, 0xA7, 0x39, + 0xF3, 0x22, 0xE1, 0x57, 0x31, 0xAA, 0x14, 0x0D, + 0xDA, 0xF5, 0xBE, 0xD2, 0x94, 0xD5, 0xC8, 0x2E, + 0x54, 0xFE, 0xF2, 0x9F, 0x21, 0x4E, 0x18, 0xAA, + 0xFA, 0xA8, 0x4F, 0x8B, 0xE9, 0x9A, 0xF6, 0x29, + 0x50, 0x26, 0x6B, 0x8F, 0x90, 0x1F, 0x15, 0xDD, + 0x4C, 0x5D, 0x35, 0x51, 0x6F, 0xC3, 0x5B, 0x4C, + 0xAB, 0x2E, 0x96, 0xE4, 0x69, 0x5B, 0xBE, 0x1C + }, + { + 0xD1, 0x4D, 0x7C, 0x4C, 0x41, 0x5E, 0xEB, 0x0E, + 0x10, 0xB1, 0x59, 0x22, 0x4B, 0xEA, 0x12, 0x7E, + 0xBD, 0x84, 0xF9, 0x59, 0x1C, 0x70, 0x2A, 0x33, + 0x0F, 0x5B, 0xB7, 0xBB, 0x7A, 0xA4, 0x4E, 0xA3, + 0x9D, 0xE6, 0xED, 0x01, 0xF1, 0x8D, 0xA7, 0xAD, + 0xF4, 0x0C, 0xFB, 0x97, 0xC5, 0xD1, 0x52, 0xC2, + 0x75, 0x28, 0x82, 0x4B, 0x21, 0xE2, 0x39, 0x52, + 0x6A, 0xF8, 0xF3, 0x6B, 0x21, 0x4E, 0x0C, 0xFB + }, + { + 0xBE, 0x28, 0xC4, 0xBE, 0x70, 0x69, 0x70, 0x48, + 0x8F, 0xAC, 0x7D, 0x29, 0xC3, 0xBD, 0x5C, 0x4E, + 0x98, 0x60, 0x85, 0xC4, 0xC3, 0x33, 0x2F, 0x1F, + 0x3F, 0xD3, 0x09, 0x73, 0xDB, 0x61, 0x41, 0x64, + 0xBA, 0x2F, 0x31, 0xA7, 0x88, 0x75, 0xFF, 0xDC, + 0x15, 0x03, 0x25, 0xC8, 0x83, 0x27, 0xA9, 0x44, + 0x3E, 0xD0, 0x4F, 0xDF, 0xE5, 0xBE, 0x93, 0x87, + 0x6D, 0x16, 0x28, 0x56, 0x0C, 0x76, 0x4A, 0x80 + }, + { + 0x03, 0x1D, 0xA1, 0x06, 0x9E, 0x3A, 0x2E, 0x9C, + 0x33, 0x82, 0xE4, 0x36, 0xFF, 0xD7, 0x9D, 0xF7, + 0x4B, 0x1C, 0xA6, 0xA8, 0xAD, 0xB2, 0xDE, 0xAB, + 0xE6, 0x76, 0xAB, 0x45, 0x99, 0x4C, 0xBC, 0x05, + 0x4F, 0x03, 0x7D, 0x2F, 0x0E, 0xAC, 0xE8, 0x58, + 0xD3, 0x2C, 0x14, 0xE2, 0xD1, 0xC8, 0xB4, 0x60, + 0x77, 0x30, 0x8E, 0x3B, 0xDC, 0x2C, 0x1B, 0x53, + 0x17, 0x2E, 0xCF, 0x7A, 0x8C, 0x14, 0xE3, 0x49 + }, + { + 0x46, 0x65, 0xCE, 0xF8, 0xBA, 0x4D, 0xB4, 0xD0, + 0xAC, 0xB1, 0x18, 0xF2, 0x98, 0x7F, 0x0B, 0xB0, + 0x9F, 0x8F, 0x86, 0xAA, 0x44, 0x5A, 0xA3, 0xD5, + 0xFC, 0x9A, 0x8B, 0x34, 0x68, 0x64, 0x78, 0x74, + 0x89, 0xE8, 0xFC, 0xEC, 0xC1, 0x25, 0xD1, 0x7E, + 0x9B, 0x56, 0xE1, 0x29, 0x88, 0xEA, 0xC5, 0xEC, + 0xC7, 0x28, 0x68, 0x83, 0xDB, 0x06, 0x61, 0xB8, + 0xFF, 0x05, 0xDA, 0x2A, 0xFF, 0xF3, 0x0F, 0xE4 + }, + { + 0x63, 0xB7, 0x03, 0x2E, 0x5F, 0x93, 0x0C, 0xC9, + 0x93, 0x95, 0x17, 0xF9, 0xE9, 0x86, 0x81, 0x6C, + 0xFB, 0xEC, 0x2B, 0xE5, 0x9B, 0x95, 0x68, 0xB1, + 0x3F, 0x2E, 0xAD, 0x05, 0xBA, 0xE7, 0x77, 0x7C, + 0xAB, 0x62, 0x0C, 0x66, 0x59, 0x40, 0x4F, 0x74, + 0x09, 0xE4, 0x19, 0x9A, 0x3B, 0xE5, 0xF7, 0x86, + 0x5A, 0xA7, 0xCB, 0xDF, 0x8C, 0x42, 0x53, 0xF7, + 0xE8, 0x21, 0x9B, 0x1B, 0xD5, 0xF4, 0x6F, 0xEA + }, + { + 0x9F, 0x09, 0xBF, 0x09, 0x3A, 0x2B, 0x0F, 0xF8, + 0xC2, 0x63, 0x4B, 0x49, 0xE3, 0x7F, 0x1B, 0x21, + 0x35, 0xB4, 0x47, 0xAA, 0x91, 0x44, 0xC9, 0x78, + 0x7D, 0xBF, 0xD9, 0x21, 0x29, 0x31, 0x6C, 0x99, + 0xE8, 0x8A, 0xAB, 0x8A, 0x21, 0xFD, 0xEF, 0x23, + 0x72, 0xD1, 0x18, 0x9A, 0xEC, 0x50, 0x0F, 0x95, + 0x77, 0x5F, 0x1F, 0x92, 0xBF, 0xB4, 0x55, 0x45, + 0xE4, 0x25, 0x9F, 0xB9, 0xB7, 0xB0, 0x2D, 0x14 + }, + { + 0xF9, 0xF8, 0x49, 0x3C, 0x68, 0x08, 0x88, 0x07, + 0xDF, 0x7F, 0x6A, 0x26, 0x93, 0xD6, 0x4E, 0xA5, + 0x9F, 0x03, 0xE9, 0xE0, 0x5A, 0x22, 0x3E, 0x68, + 0x52, 0x4C, 0xA3, 0x21, 0x95, 0xA4, 0x73, 0x4B, + 0x65, 0x4F, 0xCE, 0xA4, 0xD2, 0x73, 0x4C, 0x86, + 0x6C, 0xF9, 0x5C, 0x88, 0x9F, 0xB1, 0x0C, 0x49, + 0x15, 0x9B, 0xE2, 0xF5, 0x04, 0x3D, 0xC9, 0x8B, + 0xB5, 0x5E, 0x02, 0xEF, 0x7B, 0xDC, 0xB0, 0x82 + }, + { + 0x3C, 0x9A, 0x73, 0x59, 0xAB, 0x4F, 0xEB, 0xCE, + 0x07, 0xB2, 0x0A, 0xC4, 0x47, 0xB0, 0x6A, 0x24, + 0x0B, 0x7F, 0xE1, 0xDA, 0xE5, 0x43, 0x9C, 0x49, + 0xB6, 0x0B, 0x58, 0x19, 0xF7, 0x81, 0x2E, 0x4C, + 0x17, 0x24, 0x06, 0xC1, 0xAA, 0xC3, 0x16, 0x71, + 0x3C, 0xF0, 0xDD, 0xED, 0x10, 0x38, 0x07, 0x72, + 0x58, 0xE2, 0xEF, 0xF5, 0xB3, 0x39, 0x13, 0xD9, + 0xD9, 0x5C, 0xAE, 0xB4, 0xE6, 0xC6, 0xB9, 0x70 + }, + { + 0xAD, 0x6A, 0xAB, 0x80, 0x84, 0x51, 0x0E, 0x82, + 0x2C, 0xFC, 0xE8, 0x62, 0x5D, 0x62, 0xCF, 0x4D, + 0xE6, 0x55, 0xF4, 0x76, 0x38, 0x84, 0xC7, 0x1E, + 0x80, 0xBA, 0xB9, 0xAC, 0x9D, 0x53, 0x18, 0xDB, + 0xA4, 0xA6, 0x03, 0x3E, 0xD2, 0x90, 0x84, 0xE6, + 0x52, 0x16, 0xC0, 0x31, 0x60, 0x6C, 0xA1, 0x76, + 0x15, 0xDC, 0xFE, 0x3B, 0xA1, 0x1D, 0x26, 0x85, + 0x1A, 0xE0, 0x99, 0x9C, 0xA6, 0xE2, 0x32, 0xCF + }, + { + 0x15, 0x6E, 0x9E, 0x62, 0x61, 0x37, 0x4C, 0x9D, + 0xC8, 0x84, 0xF3, 0x6E, 0x70, 0xF0, 0xFE, 0x1A, + 0xB9, 0x29, 0x79, 0x97, 0xB8, 0x36, 0xFA, 0x7D, + 0x17, 0x0A, 0x9C, 0x9E, 0xBF, 0x57, 0x5B, 0x88, + 0x1E, 0x7B, 0xCE, 0xA4, 0x4D, 0x6C, 0x02, 0x48, + 0xD3, 0x55, 0x97, 0x90, 0x71, 0x54, 0x82, 0x89, + 0x55, 0xBE, 0x19, 0x13, 0x58, 0x52, 0xF9, 0x22, + 0x88, 0x15, 0xEC, 0xA0, 0x24, 0xA8, 0xAD, 0xFB + }, + { + 0x42, 0x15, 0x40, 0x76, 0x33, 0xF4, 0xCC, 0xA9, + 0xB6, 0x78, 0x8B, 0xE9, 0x3E, 0x6A, 0xA3, 0xD9, + 0x63, 0xC7, 0xD6, 0xCE, 0x4B, 0x14, 0x72, 0x47, + 0x09, 0x9F, 0x46, 0xA3, 0xAC, 0xB5, 0x00, 0xA3, + 0x00, 0x38, 0xCB, 0x3E, 0x78, 0x8C, 0x3D, 0x29, + 0xF1, 0x32, 0xAD, 0x84, 0x4E, 0x80, 0xE9, 0xE9, + 0x92, 0x51, 0xF6, 0xDB, 0x96, 0xAC, 0xD8, 0xA0, + 0x91, 0xCF, 0xC7, 0x70, 0xAF, 0x53, 0x84, 0x7B + }, + { + 0x1C, 0x07, 0x7E, 0x27, 0x9D, 0xE6, 0x54, 0x85, + 0x23, 0x50, 0x2B, 0x6D, 0xF8, 0x00, 0xFF, 0xDA, + 0xB5, 0xE2, 0xC3, 0xE9, 0x44, 0x2E, 0xB8, 0x38, + 0xF5, 0x8C, 0x29, 0x5F, 0x3B, 0x14, 0x7C, 0xEF, + 0x9D, 0x70, 0x1C, 0x41, 0xC3, 0x21, 0x28, 0x3F, + 0x00, 0xC7, 0x1A, 0xFF, 0xA0, 0x61, 0x93, 0x10, + 0x39, 0x91, 0x26, 0x29, 0x5B, 0x78, 0xDD, 0x4D, + 0x1A, 0x74, 0x57, 0x2E, 0xF9, 0xED, 0x51, 0x35 + }, + { + 0xF0, 0x7A, 0x55, 0x5F, 0x49, 0xFE, 0x48, 0x1C, + 0xF4, 0xCD, 0x0A, 0x87, 0xB7, 0x1B, 0x82, 0xE4, + 0xA9, 0x50, 0x64, 0xD0, 0x66, 0x77, 0xFD, 0xD9, + 0x0A, 0x0E, 0xB5, 0x98, 0x87, 0x7B, 0xA1, 0xC8, + 0x3D, 0x46, 0x77, 0xB3, 0x93, 0xC3, 0xA3, 0xB6, + 0x66, 0x1C, 0x42, 0x1F, 0x5B, 0x12, 0xCB, 0x99, + 0xD2, 0x03, 0x76, 0xBA, 0x72, 0x75, 0xC2, 0xF3, + 0xA8, 0xF5, 0xA9, 0xB7, 0x82, 0x17, 0x20, 0xDA + }, + { + 0xB5, 0x91, 0x1B, 0x38, 0x0D, 0x20, 0xC7, 0xB0, + 0x43, 0x23, 0xE4, 0x02, 0x6B, 0x38, 0xE2, 0x00, + 0xF5, 0x34, 0x25, 0x92, 0x33, 0xB5, 0x81, 0xE0, + 0x2C, 0x1E, 0x3E, 0x2D, 0x84, 0x38, 0xD6, 0xC6, + 0x6D, 0x5A, 0x4E, 0xB2, 0x01, 0xD5, 0xA8, 0xB7, + 0x50, 0x72, 0xC4, 0xEC, 0x29, 0x10, 0x63, 0x34, + 0xDA, 0x70, 0xBC, 0x79, 0x52, 0x1B, 0x0C, 0xED, + 0x2C, 0xFD, 0x53, 0x3F, 0x5F, 0xF8, 0x4F, 0x95 + }, + { + 0x01, 0xF0, 0x70, 0xA0, 0x9B, 0xAE, 0x91, 0x12, + 0x96, 0x36, 0x1F, 0x91, 0xAA, 0x0E, 0x8E, 0x0D, + 0x09, 0xA7, 0x72, 0x54, 0x78, 0x53, 0x6D, 0x9D, + 0x48, 0xC5, 0xFE, 0x1E, 0x5E, 0x7C, 0x3C, 0x5B, + 0x9B, 0x9D, 0x6E, 0xB0, 0x77, 0x96, 0xF6, 0xDA, + 0x57, 0xAE, 0x56, 0x2A, 0x7D, 0x70, 0xE8, 0x82, + 0xE3, 0x7A, 0xDF, 0xDE, 0x83, 0xF0, 0xC4, 0x33, + 0xC2, 0xCD, 0x36, 0x35, 0x36, 0xBB, 0x22, 0xC8 + }, + { + 0x6F, 0x79, 0x3E, 0xB4, 0x37, 0x4A, 0x48, 0xB0, + 0x77, 0x5A, 0xCA, 0xF9, 0xAD, 0xCF, 0x8E, 0x45, + 0xE5, 0x42, 0x70, 0xC9, 0x47, 0x5F, 0x00, 0x4A, + 0xD8, 0xD5, 0x97, 0x3E, 0x2A, 0xCA, 0x52, 0x74, + 0x7F, 0xF4, 0xED, 0x04, 0xAE, 0x96, 0x72, 0x75, + 0xB9, 0xF9, 0xEB, 0x0E, 0x1F, 0xF7, 0x5F, 0xB4, + 0xF7, 0x94, 0xFA, 0x8B, 0xE9, 0xAD, 0xD7, 0xA4, + 0x13, 0x04, 0x86, 0x8D, 0x10, 0x3F, 0xAB, 0x10 + }, + { + 0x96, 0x5F, 0x20, 0xF1, 0x39, 0x76, 0x5F, 0xCC, + 0x4C, 0xE4, 0xBA, 0x37, 0x94, 0x67, 0x58, 0x63, + 0xCA, 0xC2, 0x4D, 0xB4, 0x72, 0xCD, 0x2B, 0x79, + 0x9D, 0x03, 0x5B, 0xCE, 0x3D, 0xBE, 0xA5, 0x02, + 0xDA, 0x7B, 0x52, 0x48, 0x65, 0xF6, 0xB8, 0x11, + 0xD8, 0xC5, 0x82, 0x8D, 0x3A, 0x88, 0x96, 0x46, + 0xFE, 0x64, 0xA3, 0x80, 0xDA, 0x1A, 0xA7, 0xC7, + 0x04, 0x4E, 0x9F, 0x24, 0x5D, 0xCE, 0xD1, 0x28 + }, + { + 0xEC, 0x29, 0x5B, 0x57, 0x83, 0x60, 0x12, 0x44, + 0xC3, 0x0E, 0x46, 0x41, 0xE3, 0xB4, 0x5B, 0xE2, + 0x22, 0xC4, 0xDC, 0xE7, 0x7A, 0x58, 0x70, 0x0F, + 0x53, 0xBC, 0x8E, 0xC5, 0x2A, 0x94, 0x16, 0x90, + 0xB4, 0xD0, 0xB0, 0x87, 0xFB, 0x6F, 0xCB, 0x3F, + 0x39, 0x83, 0x2B, 0x9D, 0xE8, 0xF7, 0x5E, 0xC2, + 0x0B, 0xD4, 0x30, 0x79, 0x81, 0x17, 0x49, 0xCD, + 0xC9, 0x07, 0xED, 0xB9, 0x41, 0x57, 0xD1, 0x80 + }, + { + 0x61, 0xC7, 0x2F, 0x8C, 0xCC, 0x91, 0xDB, 0xB5, + 0x4C, 0xA6, 0x75, 0x0B, 0xC4, 0x89, 0x67, 0x2D, + 0xE0, 0x9F, 0xAE, 0xDB, 0x8F, 0xDD, 0x4F, 0x94, + 0xFF, 0x23, 0x20, 0x90, 0x9A, 0x30, 0x3F, 0x5D, + 0x5A, 0x98, 0x48, 0x1C, 0x0B, 0xC1, 0xA6, 0x25, + 0x41, 0x9F, 0xB4, 0xDE, 0xBF, 0xBF, 0x7F, 0x8A, + 0x53, 0xBB, 0x07, 0xEC, 0x3D, 0x98, 0x5E, 0x8E, + 0xA1, 0x1E, 0x72, 0xD5, 0x59, 0x94, 0x07, 0x80 + }, + { + 0xAF, 0xD8, 0x14, 0x5B, 0x25, 0x9E, 0xEF, 0xC8, + 0xD1, 0x26, 0x20, 0xC3, 0xC5, 0xB0, 0x3E, 0x1E, + 0xD8, 0xFD, 0x2C, 0xCE, 0xFE, 0x03, 0x65, 0x07, + 0x8C, 0x80, 0xFD, 0x42, 0xC1, 0x77, 0x0E, 0x28, + 0xB4, 0x49, 0x48, 0xF2, 0x7E, 0x65, 0xA1, 0x88, + 0x66, 0x90, 0x11, 0x0D, 0xB8, 0x14, 0x39, 0x7B, + 0x68, 0xE4, 0x3D, 0x80, 0xD1, 0xBA, 0x16, 0xDF, + 0xA3, 0x58, 0xE7, 0x39, 0xC8, 0x98, 0xCF, 0xA3 + }, + { + 0x55, 0x2F, 0xC7, 0x89, 0x3C, 0xF1, 0xCE, 0x93, + 0x3A, 0xDA, 0x35, 0xC0, 0xDA, 0x98, 0x84, 0x4E, + 0x41, 0x54, 0x5E, 0x24, 0x4C, 0x31, 0x57, 0xA1, + 0x42, 0x8D, 0x7B, 0x4C, 0x21, 0xF9, 0xCD, 0x7E, + 0x40, 0x71, 0xAE, 0xD7, 0x7B, 0x7C, 0xA9, 0xF1, + 0xC3, 0x8F, 0xBA, 0x32, 0x23, 0x74, 0x12, 0xEF, + 0x21, 0xA3, 0x42, 0x74, 0x2E, 0xC8, 0x32, 0x43, + 0x78, 0xF2, 0x1E, 0x50, 0x7F, 0xAF, 0xDD, 0x88 + }, + { + 0x46, 0x7A, 0x33, 0xFB, 0xAD, 0xF5, 0xEB, 0xC5, + 0x25, 0x96, 0xEF, 0x86, 0xAA, 0xAE, 0xFC, 0x6F, + 0xAB, 0xA8, 0xEE, 0x65, 0x1B, 0x1C, 0xE0, 0x4D, + 0xE3, 0x68, 0xA0, 0x3A, 0x5A, 0x90, 0x40, 0xEF, + 0x28, 0x35, 0xE0, 0x0A, 0xDB, 0x09, 0xAB, 0xB3, + 0xFB, 0xD2, 0xBC, 0xE8, 0x18, 0xA2, 0x41, 0x3D, + 0x0B, 0x02, 0x53, 0xB5, 0xBD, 0xA4, 0xFC, 0x5B, + 0x2F, 0x6F, 0x85, 0xF3, 0xFD, 0x5B, 0x55, 0xF2 + }, + { + 0x22, 0xEF, 0xF8, 0xE6, 0xDD, 0x52, 0x36, 0xF5, + 0xF5, 0x7D, 0x94, 0xED, 0xE8, 0x74, 0xD6, 0xC9, + 0x42, 0x8E, 0x8F, 0x5D, 0x56, 0x6F, 0x17, 0xCD, + 0x6D, 0x18, 0x48, 0xCD, 0x75, 0x2F, 0xE1, 0x3C, + 0x65, 0x5C, 0xB1, 0x0F, 0xBA, 0xAF, 0xF7, 0x68, + 0x72, 0xF2, 0xBF, 0x2D, 0xA9, 0x9E, 0x15, 0xDC, + 0x62, 0x40, 0x75, 0xE1, 0xEC, 0x2F, 0x58, 0xA3, + 0xF6, 0x40, 0x72, 0x12, 0x18, 0x38, 0x56, 0x9E + }, + { + 0x9C, 0xEC, 0x6B, 0xBF, 0x62, 0xC4, 0xBC, 0xE4, + 0x13, 0x8A, 0xBA, 0xE1, 0xCB, 0xEC, 0x8D, 0xAD, + 0x31, 0x95, 0x04, 0x44, 0xE9, 0x03, 0x21, 0xB1, + 0x34, 0x71, 0x96, 0x83, 0x4C, 0x11, 0x4B, 0x86, + 0x4A, 0xF3, 0xF3, 0xCC, 0x35, 0x08, 0xF8, 0x37, + 0x51, 0xFF, 0xB4, 0xED, 0xA7, 0xC8, 0x4D, 0x14, + 0x07, 0x34, 0xBB, 0x42, 0x63, 0xC3, 0x62, 0x5C, + 0x00, 0xF0, 0x4F, 0x4C, 0x80, 0x68, 0x98, 0x1B + }, + { + 0xA8, 0xB6, 0x0F, 0xA4, 0xFC, 0x24, 0x42, 0xF6, + 0xF1, 0x51, 0x4A, 0xD7, 0x40, 0x26, 0x26, 0x92, + 0x0C, 0xC7, 0xC2, 0xC9, 0xF7, 0x21, 0x24, 0xB8, + 0xCB, 0xA8, 0xEE, 0x2C, 0xB7, 0xC4, 0x58, 0x6F, + 0x65, 0x8A, 0x44, 0x10, 0xCF, 0xFC, 0xC0, 0xAB, + 0x88, 0x34, 0x39, 0x55, 0xE0, 0x94, 0xC6, 0xAF, + 0x0D, 0x20, 0xD0, 0xC7, 0x14, 0xFB, 0x0A, 0x98, + 0x8F, 0x54, 0x3F, 0x30, 0x0F, 0x58, 0xD3, 0x89 + }, + { + 0x82, 0x71, 0xCC, 0x45, 0xDF, 0xA5, 0xE4, 0x17, + 0x0E, 0x84, 0x7E, 0x86, 0x30, 0xB9, 0x52, 0xCF, + 0x9C, 0x2A, 0xA7, 0x77, 0xD0, 0x6F, 0x26, 0xA7, + 0x58, 0x5B, 0x83, 0x81, 0xF1, 0x88, 0xDA, 0xCC, + 0x73, 0x37, 0x39, 0x1C, 0xFC, 0xC9, 0x4B, 0x05, + 0x3D, 0xC4, 0xEC, 0x29, 0xCC, 0x17, 0xF0, 0x77, + 0x87, 0x04, 0x28, 0xF1, 0xAC, 0x23, 0xFD, 0xDD, + 0xA1, 0x65, 0xEF, 0x5A, 0x3F, 0x15, 0x5F, 0x39 + }, + { + 0xBF, 0x23, 0xC0, 0xC2, 0x5C, 0x80, 0x60, 0xE4, + 0xF6, 0x99, 0x5F, 0x16, 0x23, 0xA3, 0xBE, 0xBE, + 0xCA, 0xA9, 0x6E, 0x30, 0x86, 0x80, 0x00, 0x0A, + 0x8A, 0xA3, 0xCD, 0x56, 0xBB, 0x1A, 0x6D, 0xA0, + 0x99, 0xE1, 0x0D, 0x92, 0x31, 0xB3, 0x7F, 0x45, + 0x19, 0xB2, 0xEF, 0xD2, 0xC2, 0x4D, 0xE7, 0x2F, + 0x31, 0xA5, 0xF1, 0x95, 0x35, 0x24, 0x1B, 0x4A, + 0x59, 0xFA, 0x3C, 0x03, 0xCE, 0xB7, 0x90, 0xE7 + }, + { + 0x87, 0x7F, 0xD6, 0x52, 0xC0, 0x52, 0x81, 0x00, + 0x9C, 0x0A, 0x52, 0x50, 0xE7, 0xA3, 0xA6, 0x71, + 0xF8, 0xB1, 0x8C, 0x10, 0x88, 0x17, 0xFE, 0x4A, + 0x87, 0x4D, 0xE2, 0x2D, 0xA8, 0xE4, 0x5D, 0xB1, + 0x19, 0x58, 0xA6, 0x00, 0xC5, 0xF6, 0x2E, 0x67, + 0xD3, 0x6C, 0xBF, 0x84, 0x47, 0x4C, 0xF2, 0x44, + 0xA9, 0xC2, 0xB0, 0x3A, 0x9F, 0xB9, 0xDC, 0x71, + 0x1C, 0xD1, 0xA2, 0xCA, 0xB6, 0xF3, 0xFA, 0xE0 + }, + { + 0x29, 0xDF, 0x4D, 0x87, 0xEA, 0x44, 0x4B, 0xAF, + 0x5B, 0xCD, 0xF5, 0xF4, 0xE4, 0x15, 0x79, 0xE2, + 0x8A, 0x67, 0xDE, 0x84, 0x14, 0x9F, 0x06, 0xC0, + 0x3F, 0x11, 0x0E, 0xA8, 0x4F, 0x57, 0x2A, 0x9F, + 0x67, 0x6A, 0xDD, 0xD0, 0x4C, 0x48, 0x78, 0xF4, + 0x9C, 0x5C, 0x00, 0xAC, 0xCD, 0xA4, 0x41, 0xB1, + 0xA3, 0x87, 0xCA, 0xCE, 0xB2, 0xE9, 0x93, 0xBB, + 0x7A, 0x10, 0xCD, 0x8C, 0x2D, 0x67, 0x17, 0xE1 + }, + { + 0x71, 0x0D, 0xAC, 0xB1, 0x66, 0x84, 0x46, 0x39, + 0xCD, 0x7B, 0x63, 0x7C, 0x27, 0x42, 0x09, 0x42, + 0x4E, 0x24, 0x49, 0xDC, 0x35, 0xD7, 0x90, 0xBB, + 0xFA, 0x4F, 0x76, 0x17, 0x70, 0x54, 0xA3, 0x6B, + 0x3B, 0x76, 0xFA, 0xC0, 0xCA, 0x6E, 0x61, 0xDF, + 0x1E, 0x68, 0x70, 0x00, 0x67, 0x8A, 0xC0, 0x74, + 0x6D, 0xF7, 0x5D, 0x0A, 0x39, 0x54, 0x89, 0x76, + 0x81, 0xFD, 0x39, 0x3A, 0x15, 0x5A, 0x1B, 0xB4 + }, + { + 0xC1, 0xD5, 0xF9, 0x3B, 0x8D, 0xEA, 0x1F, 0x25, + 0x71, 0xBA, 0xBC, 0xCB, 0xC0, 0x17, 0x64, 0x54, + 0x1A, 0x0C, 0xDA, 0x87, 0xE4, 0x44, 0xD6, 0x73, + 0xC5, 0x09, 0x66, 0xCA, 0x55, 0x9C, 0x33, 0x35, + 0x4B, 0x3A, 0xCB, 0x26, 0xE5, 0xD5, 0x78, 0x1F, + 0xFB, 0x28, 0x84, 0x7A, 0x4B, 0x47, 0x54, 0xD7, + 0x70, 0x08, 0xC6, 0x2A, 0x83, 0x58, 0x35, 0xF5, + 0x00, 0xDE, 0xA7, 0xC3, 0xB5, 0x8B, 0xDA, 0xE2 + }, + { + 0xA4, 0x1E, 0x41, 0x27, 0x1C, 0xDA, 0xB8, 0xAF, + 0x4D, 0x72, 0xB1, 0x04, 0xBF, 0xB2, 0xAD, 0x04, + 0x1A, 0xC4, 0xDF, 0x14, 0x67, 0x7D, 0xA6, 0x71, + 0xD8, 0x56, 0x40, 0xC4, 0xB1, 0x87, 0xF5, 0x0C, + 0x2B, 0x66, 0x51, 0x3C, 0x46, 0x19, 0xFB, 0xD5, + 0xD5, 0xDC, 0x4F, 0xE6, 0x5D, 0xD3, 0x7B, 0x90, + 0x42, 0xE9, 0x84, 0x8D, 0xDA, 0x55, 0x6A, 0x50, + 0x4C, 0xAA, 0x2B, 0x1C, 0x6A, 0xFE, 0x47, 0x30 + }, + { + 0xE7, 0xBC, 0xBA, 0xCD, 0xC3, 0x79, 0xC4, 0x3D, + 0x81, 0xEB, 0xAD, 0xCB, 0x37, 0x78, 0x15, 0x52, + 0xFC, 0x1D, 0x75, 0x3E, 0x8C, 0xF3, 0x10, 0xD9, + 0x68, 0x39, 0x2D, 0x06, 0xC9, 0x1F, 0x1D, 0x64, + 0xCC, 0x9E, 0x90, 0xCE, 0x1D, 0x22, 0xC3, 0x2D, + 0x27, 0x7F, 0xC6, 0xCD, 0xA4, 0x33, 0xA4, 0xD4, + 0x42, 0xC7, 0x62, 0xE9, 0xEA, 0xCF, 0x2C, 0x25, + 0x9F, 0x32, 0xD6, 0x4C, 0xF9, 0xDA, 0x3A, 0x22 + }, + { + 0x51, 0x75, 0x5B, 0x4A, 0xC5, 0x45, 0x6B, 0x13, + 0x21, 0x8A, 0x19, 0xC5, 0xB9, 0x24, 0x2F, 0x57, + 0xC4, 0xA9, 0x81, 0xE4, 0xD4, 0xEC, 0xDC, 0xE0, + 0x9A, 0x31, 0x93, 0x36, 0x2B, 0x80, 0x8A, 0x57, + 0x93, 0x45, 0xD4, 0x88, 0x1C, 0x26, 0x07, 0xA5, + 0x65, 0x34, 0xDD, 0x7F, 0x21, 0x95, 0x6A, 0xFF, + 0x72, 0xC2, 0xF4, 0x17, 0x3A, 0x6E, 0x7B, 0x6C, + 0xC2, 0x21, 0x2B, 0xA0, 0xE3, 0xDA, 0xEE, 0x1F + }, + { + 0xDC, 0xC2, 0xC4, 0xBE, 0xB9, 0xC1, 0xF2, 0x60, + 0x7B, 0x78, 0x6C, 0x20, 0xC6, 0x31, 0x97, 0x23, + 0x47, 0x03, 0x4C, 0x1C, 0xC0, 0x2F, 0xCC, 0x7D, + 0x02, 0xFF, 0x01, 0x09, 0x9C, 0xFE, 0x1C, 0x69, + 0x89, 0x84, 0x0A, 0xC2, 0x13, 0x92, 0x36, 0x29, + 0x11, 0x3A, 0xA8, 0xBA, 0xD7, 0x13, 0xCC, 0xF0, + 0xFE, 0x4C, 0xE1, 0x32, 0x64, 0xFB, 0x32, 0xB8, + 0xB0, 0xFE, 0x37, 0x2D, 0xA3, 0x82, 0x54, 0x4A + }, + { + 0x3D, 0x55, 0x17, 0x6A, 0xCE, 0xA4, 0xA7, 0xE3, + 0xA6, 0x5F, 0xFA, 0x9F, 0xB1, 0x0A, 0x7A, 0x17, + 0x67, 0x19, 0x9C, 0xF0, 0x77, 0xCE, 0xE9, 0xF7, + 0x15, 0x32, 0xD6, 0x7C, 0xD7, 0xC7, 0x3C, 0x9F, + 0x93, 0xCF, 0xC3, 0x7C, 0xCD, 0xCC, 0x1F, 0xDE, + 0xF5, 0x0A, 0xAD, 0x46, 0xA5, 0x04, 0xA6, 0x50, + 0xD2, 0x98, 0xD5, 0x97, 0xA3, 0xA9, 0xFA, 0x95, + 0xC6, 0xC4, 0x0C, 0xB7, 0x1F, 0xA5, 0xE7, 0x25 + }, + { + 0xD0, 0x77, 0x13, 0xC0, 0x05, 0xDE, 0x96, 0xDD, + 0x21, 0xD2, 0xEB, 0x8B, 0xBE, 0xCA, 0x66, 0x74, + 0x6E, 0xA5, 0x1A, 0x31, 0xAE, 0x92, 0x2A, 0x3E, + 0x74, 0x86, 0x48, 0x89, 0x54, 0x0A, 0x48, 0xDB, + 0x27, 0xD7, 0xE4, 0xC9, 0x03, 0x11, 0x63, 0x8B, + 0x22, 0x4B, 0xF0, 0x20, 0x1B, 0x50, 0x18, 0x91, + 0x75, 0x48, 0x48, 0x11, 0x3C, 0x26, 0x61, 0x08, + 0xD0, 0xAD, 0xB1, 0x3D, 0xB7, 0x19, 0x09, 0xC7 + }, + { + 0x58, 0x98, 0x3C, 0x21, 0x43, 0x3D, 0x95, 0x0C, + 0xAA, 0x23, 0xE4, 0xBC, 0x18, 0x54, 0x3B, 0x8E, + 0x60, 0x1C, 0x20, 0x43, 0x18, 0x53, 0x21, 0x52, + 0xDA, 0xF5, 0xE1, 0x59, 0xA0, 0xCD, 0x14, 0x80, + 0x18, 0x3D, 0x29, 0x28, 0x5C, 0x05, 0xF1, 0x29, + 0xCB, 0x0C, 0xC3, 0x16, 0x46, 0x87, 0x92, 0x80, + 0x86, 0xFF, 0xE3, 0x80, 0x15, 0x8D, 0xF1, 0xD3, + 0x94, 0xC6, 0xAC, 0x0D, 0x42, 0x88, 0xBC, 0xA8 + }, + { + 0x81, 0x00, 0xA8, 0xDC, 0x52, 0x8D, 0x2B, 0x68, + 0x2A, 0xB4, 0x25, 0x08, 0x01, 0xBA, 0x33, 0xF0, + 0x2A, 0x3E, 0x94, 0xC5, 0x4D, 0xAC, 0x0A, 0xE1, + 0x48, 0x2A, 0xA2, 0x1F, 0x51, 0xEF, 0x3A, 0x82, + 0xF3, 0x80, 0x7E, 0x6F, 0xAC, 0xB0, 0xAE, 0xB0, + 0x59, 0x47, 0xBF, 0x7A, 0xA2, 0xAD, 0xCB, 0x03, + 0x43, 0x56, 0xF9, 0x0F, 0xA4, 0x56, 0x0E, 0xDE, + 0x02, 0x20, 0x1A, 0x37, 0xE4, 0x11, 0xEC, 0x1A + }, + { + 0x07, 0x02, 0x5F, 0x1B, 0xB6, 0xC7, 0x84, 0xF3, + 0xFE, 0x49, 0xDE, 0x5C, 0x14, 0xB9, 0x36, 0xA5, + 0xAC, 0xAC, 0xAC, 0xAA, 0xB3, 0x3F, 0x6A, 0xC4, + 0xD0, 0xE0, 0x0A, 0xB6, 0xA1, 0x24, 0x83, 0xD6, + 0xBE, 0xC0, 0x0B, 0x4F, 0xE6, 0x7C, 0x7C, 0xA5, + 0xCC, 0x50, 0x8C, 0x2A, 0x53, 0xEF, 0xB5, 0xBF, + 0xA5, 0x39, 0x87, 0x69, 0xD8, 0x43, 0xFF, 0x0D, + 0x9E, 0x8B, 0x14, 0xD3, 0x6A, 0x01, 0xA7, 0x7F + }, + { + 0xBA, 0x6A, 0xEF, 0xD9, 0x72, 0xB6, 0x18, 0x6E, + 0x02, 0x7A, 0x76, 0x27, 0x3A, 0x4A, 0x72, 0x33, + 0x21, 0xA3, 0xF5, 0x80, 0xCF, 0xA8, 0x94, 0xDA, + 0x5A, 0x9C, 0xE8, 0xE7, 0x21, 0xC8, 0x28, 0x55, + 0x2C, 0x64, 0xDA, 0xCE, 0xE3, 0xA7, 0xFD, 0x2D, + 0x74, 0x3B, 0x5C, 0x35, 0xAD, 0x0C, 0x8E, 0xFA, + 0x71, 0xF8, 0xCE, 0x99, 0xBF, 0x96, 0x33, 0x47, + 0x10, 0xE2, 0xC2, 0x34, 0x6E, 0x8F, 0x3C, 0x52 + }, + { + 0xE0, 0x72, 0x1E, 0x02, 0x51, 0x7A, 0xED, 0xFA, + 0x4E, 0x7E, 0x9B, 0xA5, 0x03, 0xE0, 0x25, 0xFD, + 0x46, 0xE7, 0x14, 0x56, 0x6D, 0xC8, 0x89, 0xA8, + 0x4C, 0xBF, 0xE5, 0x6A, 0x55, 0xDF, 0xBE, 0x2F, + 0xC4, 0x93, 0x8A, 0xC4, 0x12, 0x05, 0x88, 0x33, + 0x5D, 0xEA, 0xC8, 0xEF, 0x3F, 0xA2, 0x29, 0xAD, + 0xC9, 0x64, 0x7F, 0x54, 0xAD, 0x2E, 0x34, 0x72, + 0x23, 0x4F, 0x9B, 0x34, 0xEF, 0xC4, 0x65, 0x43 + }, + { + 0xB6, 0x29, 0x26, 0x69, 0xCC, 0xD3, 0x8D, 0x5F, + 0x01, 0xCA, 0xAE, 0x96, 0xBA, 0x27, 0x2C, 0x76, + 0xA8, 0x79, 0xA4, 0x57, 0x43, 0xAF, 0xA0, 0x72, + 0x5D, 0x83, 0xB9, 0xEB, 0xB2, 0x66, 0x65, 0xB7, + 0x31, 0xF1, 0x84, 0x8C, 0x52, 0xF1, 0x19, 0x72, + 0xB6, 0x64, 0x4F, 0x55, 0x4C, 0x06, 0x4F, 0xA9, + 0x07, 0x80, 0xDB, 0xBB, 0xF3, 0xA8, 0x9D, 0x4F, + 0xC3, 0x1F, 0x67, 0xDF, 0x3E, 0x58, 0x57, 0xEF + }, + { + 0x23, 0x19, 0xE3, 0x78, 0x9C, 0x47, 0xE2, 0xDA, + 0xA5, 0xFE, 0x80, 0x7F, 0x61, 0xBE, 0xC2, 0xA1, + 0xA6, 0x53, 0x7F, 0xA0, 0x3F, 0x19, 0xFF, 0x32, + 0xE8, 0x7E, 0xEC, 0xBF, 0xD6, 0x4B, 0x7E, 0x0E, + 0x8C, 0xCF, 0xF4, 0x39, 0xAC, 0x33, 0x3B, 0x04, + 0x0F, 0x19, 0xB0, 0xC4, 0xDD, 0xD1, 0x1A, 0x61, + 0xE2, 0x4A, 0xC1, 0xFE, 0x0F, 0x10, 0xA0, 0x39, + 0x80, 0x6C, 0x5D, 0xCC, 0x0D, 0xA3, 0xD1, 0x15 + }, + { + 0xF5, 0x97, 0x11, 0xD4, 0x4A, 0x03, 0x1D, 0x5F, + 0x97, 0xA9, 0x41, 0x3C, 0x06, 0x5D, 0x1E, 0x61, + 0x4C, 0x41, 0x7E, 0xDE, 0x99, 0x85, 0x90, 0x32, + 0x5F, 0x49, 0xBA, 0xD2, 0xFD, 0x44, 0x4D, 0x3E, + 0x44, 0x18, 0xBE, 0x19, 0xAE, 0xC4, 0xE1, 0x14, + 0x49, 0xAC, 0x1A, 0x57, 0x20, 0x78, 0x98, 0xBC, + 0x57, 0xD7, 0x6A, 0x1B, 0xCF, 0x35, 0x66, 0x29, + 0x2C, 0x20, 0xC6, 0x83, 0xA5, 0xC4, 0x64, 0x8F + }, + { + 0xDF, 0x0A, 0x9D, 0x0C, 0x21, 0x28, 0x43, 0xA6, + 0xA9, 0x34, 0xE3, 0x90, 0x2B, 0x2D, 0xD3, 0x0D, + 0x17, 0xFB, 0xA5, 0xF9, 0x69, 0xD2, 0x03, 0x0B, + 0x12, 0xA5, 0x46, 0xD8, 0xA6, 0xA4, 0x5E, 0x80, + 0xCF, 0x56, 0x35, 0xF0, 0x71, 0xF0, 0x45, 0x2E, + 0x9C, 0x91, 0x92, 0x75, 0xDA, 0x99, 0xBE, 0xD5, + 0x1E, 0xB1, 0x17, 0x3C, 0x1A, 0xF0, 0x51, 0x87, + 0x26, 0xB7, 0x5B, 0x0E, 0xC3, 0xBA, 0xE2, 0xB5 + }, + { + 0xA3, 0xEB, 0x6E, 0x6C, 0x7B, 0xF2, 0xFB, 0x8B, + 0x28, 0xBF, 0xE8, 0xB1, 0x5E, 0x15, 0xBB, 0x50, + 0x0F, 0x78, 0x1E, 0xCC, 0x86, 0xF7, 0x78, 0xC3, + 0xA4, 0xE6, 0x55, 0xFC, 0x58, 0x69, 0xBF, 0x28, + 0x46, 0xA2, 0x45, 0xD4, 0xE3, 0x3B, 0x7B, 0x14, + 0x43, 0x6A, 0x17, 0xE6, 0x3B, 0xE7, 0x9B, 0x36, + 0x65, 0x5C, 0x22, 0x6A, 0x50, 0xFF, 0xBC, 0x71, + 0x24, 0x20, 0x7B, 0x02, 0x02, 0x34, 0x2D, 0xB5 + }, + { + 0x56, 0xD4, 0xCB, 0xCD, 0x07, 0x05, 0x63, 0x42, + 0x6A, 0x01, 0x70, 0x69, 0x42, 0x5C, 0x2C, 0xD2, + 0xAE, 0x54, 0x06, 0x68, 0x28, 0x7A, 0x5F, 0xB9, + 0xDA, 0xC4, 0x32, 0xEB, 0x8A, 0xB1, 0xA3, 0x53, + 0xA3, 0x0F, 0x2F, 0xE1, 0xF4, 0x0D, 0x83, 0x33, + 0x3A, 0xFE, 0x69, 0x6A, 0x26, 0x77, 0x95, 0x40, + 0x8A, 0x92, 0xFE, 0x7D, 0xA0, 0x7A, 0x0C, 0x18, + 0x14, 0xCF, 0x77, 0xF3, 0x6E, 0x10, 0x5E, 0xE8 + }, + { + 0xE5, 0x9B, 0x99, 0x87, 0xD4, 0x28, 0xB3, 0xED, + 0xA3, 0x7D, 0x80, 0xAB, 0xDB, 0x16, 0xCD, 0x2B, + 0x0A, 0xEF, 0x67, 0x4C, 0x2B, 0x1D, 0xDA, 0x44, + 0x32, 0xEA, 0x91, 0xEE, 0x6C, 0x93, 0x5C, 0x68, + 0x4B, 0x48, 0xB4, 0x42, 0x8A, 0x8C, 0xC7, 0x40, + 0xE5, 0x79, 0xA3, 0x0D, 0xEF, 0xF3, 0x5A, 0x80, + 0x30, 0x13, 0x82, 0x0D, 0xD2, 0x3F, 0x14, 0xAE, + 0x1D, 0x84, 0x13, 0xB5, 0xC8, 0x67, 0x2A, 0xEC + }, + { + 0xCD, 0x9F, 0xCC, 0x99, 0xF9, 0x9D, 0x4C, 0xC1, + 0x6D, 0x03, 0x19, 0x00, 0xB2, 0xA7, 0x36, 0xE1, + 0x50, 0x8D, 0xB4, 0xB5, 0x86, 0x81, 0x4E, 0x63, + 0x45, 0x85, 0x7F, 0x35, 0x4A, 0x70, 0xCC, 0xEC, + 0xB1, 0xDF, 0x3B, 0x50, 0xA1, 0x9A, 0xDA, 0xF4, + 0x3C, 0x27, 0x8E, 0xFA, 0x42, 0x3F, 0xF4, 0xBB, + 0x6C, 0x52, 0x3E, 0xC7, 0xFD, 0x78, 0x59, 0xB9, + 0x7B, 0x16, 0x8A, 0x7E, 0xBF, 0xF8, 0x46, 0x7C + }, + { + 0x06, 0x02, 0x18, 0x5D, 0x8C, 0x3A, 0x78, 0x73, + 0x8B, 0x99, 0x16, 0x4B, 0x8B, 0xC6, 0xFF, 0xB2, + 0x1C, 0x7D, 0xEB, 0xEB, 0xBF, 0x80, 0x63, 0x72, + 0xE0, 0xDA, 0x44, 0xD1, 0x21, 0x54, 0x55, 0x97, + 0xB9, 0xC6, 0x62, 0xA2, 0x55, 0xDC, 0x31, 0x54, + 0x2C, 0xF9, 0x95, 0xEC, 0xBE, 0x6A, 0x50, 0xFB, + 0x5E, 0x6E, 0x0E, 0xE4, 0xEF, 0x24, 0x0F, 0xE5, + 0x57, 0xED, 0xED, 0x11, 0x88, 0x08, 0x7E, 0x86 + }, + { + 0xC0, 0x8A, 0xFA, 0x5B, 0x92, 0x7B, 0xF0, 0x80, + 0x97, 0xAF, 0xC5, 0xFF, 0xF9, 0xCA, 0x4E, 0x78, + 0x00, 0x12, 0x5C, 0x1F, 0x52, 0xF2, 0xAF, 0x35, + 0x53, 0xFA, 0x2B, 0x89, 0xE1, 0xE3, 0x01, 0x5C, + 0x4F, 0x87, 0xD5, 0xE0, 0xA4, 0x89, 0x56, 0xAD, + 0x31, 0x45, 0x0B, 0x08, 0x3D, 0xAD, 0x14, 0x7F, + 0xFB, 0x5E, 0xC0, 0x34, 0x34, 0xA2, 0x68, 0x30, + 0xCF, 0x37, 0xD1, 0x03, 0xAB, 0x50, 0xC5, 0xDA + }, + { + 0x36, 0xF1, 0xE1, 0xC1, 0x1D, 0x6E, 0xF6, 0xBC, + 0x3B, 0x53, 0x6D, 0x50, 0x5D, 0x54, 0x4A, 0x87, + 0x15, 0x22, 0xC5, 0xC2, 0xA2, 0x53, 0x06, 0x7E, + 0xC9, 0x93, 0x3B, 0x6E, 0xC2, 0x54, 0x64, 0xDA, + 0xF9, 0x85, 0x52, 0x5F, 0x5B, 0x95, 0x60, 0xA1, + 0x6D, 0x89, 0x02, 0x59, 0xAC, 0x1B, 0xB5, 0xCC, + 0x67, 0xC0, 0xC4, 0x69, 0xCD, 0xE1, 0x33, 0xDE, + 0xF0, 0x00, 0xEA, 0x1D, 0x68, 0x6F, 0x4F, 0x5D + }, + { + 0xBF, 0x2A, 0xB2, 0xE2, 0x47, 0x0F, 0x54, 0x38, + 0xC3, 0xB6, 0x89, 0xE6, 0x6E, 0x76, 0x86, 0xFF, + 0xFA, 0x0C, 0xB1, 0xE1, 0x79, 0x8A, 0xD3, 0xA8, + 0x6F, 0xF9, 0x90, 0x75, 0xBF, 0x61, 0x38, 0xE3, + 0x3D, 0x9C, 0x0C, 0xE5, 0x9A, 0xFB, 0x24, 0xAC, + 0x67, 0xA0, 0x2A, 0xF3, 0x44, 0x28, 0x19, 0x1A, + 0x9A, 0x0A, 0x60, 0x41, 0xC0, 0x74, 0x71, 0xB7, + 0xC3, 0xB1, 0xA7, 0x52, 0xD6, 0xFC, 0x0B, 0x8B + }, + { + 0xD4, 0x00, 0x60, 0x1F, 0x97, 0x28, 0xCC, 0xC4, + 0xC9, 0x23, 0x42, 0xD9, 0x78, 0x7D, 0x8D, 0x28, + 0xAB, 0x32, 0x3A, 0xF3, 0x75, 0xCA, 0x56, 0x24, + 0xB4, 0xBB, 0x91, 0xD1, 0x72, 0x71, 0xFB, 0xAE, + 0x86, 0x2E, 0x41, 0x3B, 0xE7, 0x3F, 0x1F, 0x68, + 0xE6, 0x15, 0xB8, 0xC5, 0xC3, 0x91, 0xBE, 0x0D, + 0xBD, 0x91, 0x44, 0x74, 0x6E, 0xB3, 0x39, 0xAD, + 0x54, 0x15, 0x47, 0xBA, 0x9C, 0x46, 0x8A, 0x17 + }, + { + 0x79, 0xFE, 0x2F, 0xE1, 0x57, 0xEB, 0x85, 0xA0, + 0x38, 0xAB, 0xB8, 0xEB, 0xBC, 0x64, 0x77, 0x31, + 0xD2, 0xC8, 0x3F, 0x51, 0xB0, 0xAC, 0x6E, 0xE1, + 0x4A, 0xA2, 0x84, 0xCB, 0x6A, 0x35, 0x49, 0xA4, + 0xDC, 0xCE, 0xB3, 0x00, 0x74, 0x0A, 0x82, 0x5F, + 0x52, 0xF5, 0xFB, 0x30, 0xB0, 0x3B, 0x8C, 0x4D, + 0x8B, 0x0F, 0x4A, 0xA6, 0x7A, 0x63, 0xF4, 0xA9, + 0x4E, 0x33, 0x03, 0xC4, 0xED, 0xA4, 0xC0, 0x2B + }, + { + 0x75, 0x35, 0x13, 0x13, 0xB5, 0x2A, 0x85, 0x29, + 0x29, 0x8D, 0x8C, 0x18, 0x6B, 0x17, 0x68, 0x66, + 0x6D, 0xCC, 0xA8, 0x59, 0x53, 0x17, 0xD7, 0xA4, + 0x81, 0x6E, 0xB8, 0x8C, 0x06, 0x20, 0x20, 0xC0, + 0xC8, 0xEF, 0xC5, 0x54, 0xBB, 0x34, 0x1B, 0x64, + 0x68, 0x8D, 0xB5, 0xCC, 0xAF, 0xC3, 0x5F, 0x3C, + 0x3C, 0xD0, 0x9D, 0x65, 0x64, 0xB3, 0x6D, 0x7B, + 0x04, 0xA2, 0x48, 0xE1, 0x46, 0x98, 0x0D, 0x4B + }, + { + 0xE3, 0x12, 0x8B, 0x1D, 0x31, 0x1D, 0x02, 0x17, + 0x9D, 0x7F, 0x25, 0xF9, 0x7A, 0x5A, 0x8B, 0xEE, + 0x2C, 0xC8, 0xC8, 0x63, 0x03, 0x64, 0x4F, 0xCD, + 0x66, 0x4E, 0x15, 0x7D, 0x1F, 0xEF, 0x00, 0xF2, + 0x3E, 0x46, 0xF9, 0xA5, 0xE8, 0xE5, 0xC8, 0x90, + 0xCE, 0x56, 0x5B, 0xB6, 0xAB, 0xD4, 0x30, 0x2C, + 0xE0, 0x64, 0x69, 0xD5, 0x2A, 0x5B, 0xD5, 0x3E, + 0x1C, 0x5A, 0x54, 0xD0, 0x46, 0x49, 0xDC, 0x03 + }, + { + 0xC2, 0x38, 0x2A, 0x72, 0xD2, 0xD3, 0xAC, 0xE9, + 0xD5, 0x93, 0x3D, 0x00, 0xB6, 0x08, 0x27, 0xED, + 0x38, 0x0C, 0xDA, 0x08, 0xD0, 0xBA, 0x5F, 0x6D, + 0xD4, 0x1E, 0x29, 0xEE, 0x6D, 0xBE, 0x8E, 0xCB, + 0x92, 0x35, 0xF0, 0x6B, 0xE9, 0x5D, 0x83, 0xB6, + 0x81, 0x6A, 0x2F, 0xB7, 0xA5, 0xAD, 0x47, 0x03, + 0x5E, 0x8A, 0x4B, 0x69, 0xA4, 0x88, 0x4B, 0x99, + 0xE4, 0xBE, 0xCE, 0x58, 0xCA, 0xB2, 0x5D, 0x44 + }, + { + 0x6B, 0x1C, 0x69, 0x46, 0x0B, 0xBD, 0x50, 0xAC, + 0x2E, 0xD6, 0xF3, 0x2E, 0x6E, 0x88, 0x7C, 0xFE, + 0xD4, 0x07, 0xD4, 0x7D, 0xCF, 0x0A, 0xAA, 0x60, + 0x38, 0x7F, 0xE3, 0x20, 0xD7, 0x80, 0xBD, 0x03, + 0xEA, 0xB6, 0xD7, 0xBA, 0xEB, 0x2A, 0x07, 0xD1, + 0x0C, 0xD5, 0x52, 0xA3, 0x00, 0x34, 0x13, 0x54, + 0xEA, 0x9A, 0x5F, 0x03, 0x18, 0x3A, 0x62, 0x3F, + 0x92, 0xA2, 0xD4, 0xD9, 0xF0, 0x09, 0x26, 0xAF + }, + { + 0x6C, 0xDA, 0x20, 0x6C, 0x80, 0xCD, 0xC9, 0xC4, + 0x4B, 0xA9, 0x90, 0xE0, 0x32, 0x8C, 0x31, 0x4F, + 0x81, 0x9B, 0x14, 0x2D, 0x00, 0x63, 0x04, 0x04, + 0xC4, 0x8C, 0x05, 0xDC, 0x76, 0xD1, 0xB0, 0x0C, + 0xE4, 0xD7, 0x2F, 0xC6, 0xA4, 0x8E, 0x14, 0x69, + 0xDD, 0xEF, 0x60, 0x94, 0x12, 0xC3, 0x64, 0x82, + 0x08, 0x54, 0x21, 0x4B, 0x48, 0x69, 0xAF, 0x09, + 0x0F, 0x00, 0xD3, 0xC1, 0xBA, 0x44, 0x3E, 0x1B + }, + { + 0x7F, 0xFC, 0x8C, 0x26, 0xFB, 0xD6, 0xA0, 0xF7, + 0xA6, 0x09, 0xE6, 0xE1, 0x93, 0x9F, 0x6A, 0x9E, + 0xDF, 0x1B, 0x0B, 0x06, 0x66, 0x41, 0xFB, 0x76, + 0xC4, 0xF9, 0x60, 0x2E, 0xD7, 0x48, 0xD1, 0x16, + 0x02, 0x49, 0x6B, 0x35, 0x35, 0x5B, 0x1A, 0xA2, + 0x55, 0x85, 0x0A, 0x50, 0x9D, 0x2F, 0x8E, 0xE1, + 0x8C, 0x8F, 0x3E, 0x1D, 0x7D, 0xCB, 0xC3, 0x7A, + 0x13, 0x65, 0x98, 0xF5, 0x6A, 0x59, 0xED, 0x17 + }, + { + 0x70, 0xDE, 0x1F, 0x08, 0xDD, 0x4E, 0x09, 0xD5, + 0xFC, 0x15, 0x1F, 0x17, 0xFC, 0x99, 0x1A, 0x23, + 0xAB, 0xFC, 0x05, 0x10, 0x42, 0x90, 0xD5, 0x04, + 0x68, 0x88, 0x2E, 0xFA, 0xF5, 0x82, 0xB6, 0xEC, + 0x2F, 0x14, 0xF5, 0x77, 0xC0, 0xD6, 0x8C, 0x3A, + 0xD0, 0x66, 0x26, 0x91, 0x6E, 0x3C, 0x86, 0xE6, + 0xDA, 0xAB, 0x6C, 0x53, 0xE5, 0x16, 0x3E, 0x82, + 0xB6, 0xBD, 0x0C, 0xE4, 0x9F, 0xC0, 0xD8, 0xDF + }, + { + 0x4F, 0x81, 0x93, 0x57, 0x56, 0xED, 0x35, 0xEE, + 0x20, 0x58, 0xEE, 0x0C, 0x6A, 0x61, 0x10, 0xD6, + 0xFA, 0xC5, 0xCB, 0x6A, 0x4F, 0x46, 0xAA, 0x94, + 0x11, 0x60, 0x3F, 0x99, 0x96, 0x58, 0x23, 0xB6, + 0xDA, 0x48, 0x38, 0x27, 0x6C, 0x5C, 0x06, 0xBC, + 0x78, 0x80, 0xE3, 0x76, 0xD9, 0x27, 0x58, 0x36, + 0x9E, 0xE7, 0x30, 0x5B, 0xCE, 0xC8, 0xD3, 0xCF, + 0xD2, 0x8C, 0xCA, 0xBB, 0x7B, 0x4F, 0x05, 0x79 + }, + { + 0xAB, 0xCB, 0x61, 0xCB, 0x36, 0x83, 0xD1, 0x8F, + 0x27, 0xAD, 0x52, 0x79, 0x08, 0xED, 0x2D, 0x32, + 0xA0, 0x42, 0x6C, 0xB7, 0xBB, 0x4B, 0xF1, 0x80, + 0x61, 0x90, 0x3A, 0x7D, 0xC4, 0x2E, 0x7E, 0x76, + 0xF9, 0x82, 0x38, 0x23, 0x04, 0xD1, 0x8A, 0xF8, + 0xC8, 0x0D, 0x91, 0xDD, 0x58, 0xDD, 0x47, 0xAF, + 0x76, 0xF8, 0xE2, 0xC3, 0x6E, 0x28, 0xAF, 0x24, + 0x76, 0xB4, 0xBC, 0xCF, 0x82, 0xE8, 0x9F, 0xDF + }, + { + 0x02, 0xD2, 0x61, 0xAD, 0x56, 0xA5, 0x26, 0x33, + 0x1B, 0x64, 0x3D, 0xD2, 0x18, 0x6D, 0xE9, 0xA8, + 0x2E, 0x72, 0xA5, 0x82, 0x23, 0xCD, 0x1E, 0x72, + 0x36, 0x86, 0xC5, 0x3D, 0x86, 0x9B, 0x83, 0xB9, + 0x46, 0x32, 0xB7, 0xB6, 0x47, 0xAB, 0x2A, 0xFC, + 0x0D, 0x52, 0x2E, 0x29, 0xDA, 0x3A, 0x56, 0x15, + 0xB7, 0x41, 0xD8, 0x28, 0x52, 0xE0, 0xDF, 0x41, + 0xB6, 0x60, 0x07, 0xDB, 0xCB, 0xA9, 0x05, 0x43 + }, + { + 0xC5, 0x83, 0x27, 0x41, 0xFA, 0x30, 0xC5, 0x43, + 0x68, 0x23, 0x01, 0x53, 0x83, 0xD2, 0x97, 0xFF, + 0x4C, 0x4A, 0x5D, 0x72, 0x76, 0xC3, 0xF9, 0x02, + 0x12, 0x20, 0x66, 0xE0, 0x4B, 0xE5, 0x43, 0x1B, + 0x1A, 0x85, 0xFA, 0xF7, 0x3B, 0x91, 0x84, 0x34, + 0xF9, 0x30, 0x09, 0x63, 0xD1, 0xDE, 0xA9, 0xE8, + 0xAC, 0x39, 0x24, 0xEF, 0x49, 0x02, 0x26, 0xED, + 0xEE, 0xA5, 0xF7, 0x43, 0xE4, 0x10, 0x66, 0x9F + }, + { + 0xCF, 0xAE, 0xAB, 0x26, 0x8C, 0xD0, 0x75, 0xA5, + 0xA6, 0xAE, 0xD5, 0x15, 0x02, 0x3A, 0x03, 0x2D, + 0x54, 0xF2, 0xF2, 0xFF, 0x73, 0x3C, 0xE0, 0xCB, + 0xC7, 0x8D, 0xB5, 0x1D, 0xB4, 0x50, 0x4D, 0x67, + 0x59, 0x23, 0xF8, 0x27, 0x46, 0xD6, 0x59, 0x46, + 0x06, 0xAD, 0x5D, 0x67, 0x73, 0x4B, 0x11, 0xA6, + 0x7C, 0xC6, 0xA4, 0x68, 0xC2, 0x03, 0x2E, 0x43, + 0xCA, 0x1A, 0x94, 0xC6, 0x27, 0x3A, 0x98, 0x5E + }, + { + 0x86, 0x08, 0x50, 0xF9, 0x2E, 0xB2, 0x68, 0x27, + 0x2B, 0x67, 0xD1, 0x33, 0x60, 0x9B, 0xD6, 0x4E, + 0x34, 0xF6, 0x1B, 0xF0, 0x3F, 0x4C, 0x17, 0x38, + 0x64, 0x5C, 0x17, 0xFE, 0xC8, 0x18, 0x46, 0x5D, + 0x7E, 0xCD, 0x2B, 0xE2, 0x90, 0x76, 0x41, 0x13, + 0x00, 0x25, 0xFD, 0xA7, 0x94, 0x70, 0xAB, 0x73, + 0x16, 0x46, 0xE7, 0xF6, 0x94, 0x40, 0xE8, 0x36, + 0x7E, 0xA7, 0x6A, 0xC4, 0xCE, 0xE8, 0xA1, 0xDF + }, + { + 0x84, 0xB1, 0x54, 0xED, 0x29, 0xBB, 0xED, 0xEF, + 0xA6, 0x48, 0x28, 0x68, 0x39, 0x04, 0x6F, 0x4B, + 0x5A, 0xA3, 0x44, 0x30, 0xE2, 0xD6, 0x7F, 0x74, + 0x96, 0xE4, 0xC3, 0x9F, 0x2C, 0x7E, 0xA7, 0x89, + 0x95, 0xF6, 0x9E, 0x12, 0x92, 0x20, 0x00, 0x16, + 0xF1, 0x6A, 0xC3, 0xB3, 0x77, 0x00, 0xE6, 0xC7, + 0xE7, 0x86, 0x1A, 0xFC, 0x39, 0x6B, 0x64, 0xA5, + 0x9A, 0x1D, 0xBF, 0x47, 0xA5, 0x5C, 0x4B, 0xBC + }, + { + 0xAE, 0xEE, 0xC2, 0x60, 0xA5, 0xD8, 0xEF, 0xF5, + 0xCC, 0xAB, 0x8B, 0x95, 0xDA, 0x43, 0x5A, 0x63, + 0xED, 0x7A, 0x21, 0xEA, 0x7F, 0xC7, 0x55, 0x94, + 0x13, 0xFD, 0x61, 0x7E, 0x33, 0x60, 0x9F, 0x8C, + 0x29, 0x0E, 0x64, 0xBB, 0xAC, 0xC5, 0x28, 0xF6, + 0xC0, 0x80, 0x26, 0x22, 0x88, 0xB0, 0xF0, 0xA3, + 0x21, 0x9B, 0xE2, 0x23, 0xC9, 0x91, 0xBE, 0xE9, + 0x2E, 0x72, 0x34, 0x95, 0x93, 0xE6, 0x76, 0x38 + }, + { + 0x8A, 0xD7, 0x8A, 0x9F, 0x26, 0x60, 0x1D, 0x12, + 0x7E, 0x8D, 0x2F, 0x2F, 0x97, 0x6E, 0x63, 0xD1, + 0x9A, 0x05, 0x4A, 0x17, 0xDC, 0xF5, 0x9E, 0x0F, + 0x01, 0x3A, 0xB5, 0x4A, 0x68, 0x87, 0xBB, 0xDF, + 0xFD, 0xE7, 0xAA, 0xAE, 0x11, 0x7E, 0x0F, 0xBF, + 0x32, 0x71, 0x01, 0x65, 0x95, 0xB9, 0xD9, 0xC7, + 0x12, 0xC0, 0x1B, 0x2C, 0x53, 0xE9, 0x65, 0x5A, + 0x38, 0x2B, 0xC4, 0x52, 0x2E, 0x61, 0x66, 0x45 + }, + { + 0x89, 0x34, 0x15, 0x9D, 0xAD, 0xE1, 0xAC, 0x74, + 0x14, 0x7D, 0xFA, 0x28, 0x2C, 0x75, 0x95, 0x4F, + 0xCE, 0xF4, 0x43, 0xEF, 0x25, 0xF8, 0x0D, 0xFE, + 0x9F, 0xB6, 0xEA, 0x63, 0x3B, 0x85, 0x45, 0x11, + 0x1D, 0x08, 0xB3, 0x4E, 0xF4, 0x3F, 0xFF, 0x17, + 0x02, 0x6C, 0x79, 0x64, 0xF5, 0xDE, 0xAC, 0x6D, + 0x2B, 0x3C, 0x29, 0xDA, 0xCF, 0x27, 0x47, 0xF0, + 0x22, 0xDF, 0x59, 0x67, 0xDF, 0xDC, 0x1A, 0x0A + }, + { + 0xCD, 0x36, 0xDD, 0x0B, 0x24, 0x06, 0x14, 0xCF, + 0x2F, 0xA2, 0xB9, 0xE9, 0x59, 0x67, 0x9D, 0xCD, + 0xD7, 0x2E, 0xC0, 0xCD, 0x58, 0xA4, 0x3D, 0xA3, + 0x79, 0x0A, 0x92, 0xF6, 0xCD, 0xEB, 0x9E, 0x1E, + 0x79, 0x5E, 0x47, 0x8A, 0x0A, 0x47, 0xD3, 0x71, + 0x10, 0x0D, 0x34, 0x0C, 0x5C, 0xED, 0xCD, 0xBB, + 0xC9, 0xE6, 0x8B, 0x3F, 0x46, 0x08, 0x18, 0xE5, + 0xBD, 0xFF, 0x7B, 0x4C, 0xDA, 0x4C, 0x27, 0x44 + }, + { + 0x00, 0xDF, 0x4E, 0x09, 0x9B, 0x80, 0x71, 0x37, + 0xA8, 0x59, 0x90, 0xF4, 0x9D, 0x3A, 0x94, 0x31, + 0x5E, 0x5A, 0x5F, 0x7F, 0x7A, 0x60, 0x76, 0xB3, + 0x03, 0xE9, 0x6B, 0x05, 0x6F, 0xB9, 0x38, 0x00, + 0x11, 0x1F, 0x47, 0x96, 0x28, 0xE2, 0xF8, 0xDB, + 0x59, 0xAE, 0xB6, 0xAC, 0x70, 0xC3, 0xB6, 0x1F, + 0x51, 0xF9, 0xB4, 0x6E, 0x80, 0xFF, 0xDE, 0xAE, + 0x25, 0xEB, 0xDD, 0xB4, 0xAF, 0x6C, 0xB4, 0xEE + }, + { + 0x2B, 0x9C, 0x95, 0x5E, 0x6C, 0xAE, 0xD4, 0xB7, + 0xC9, 0xE2, 0x46, 0xB8, 0x6F, 0x9A, 0x17, 0x26, + 0xE8, 0x10, 0xC5, 0x9D, 0x12, 0x6C, 0xEE, 0x66, + 0xED, 0x71, 0xBF, 0x01, 0x5B, 0x83, 0x55, 0x8A, + 0x4B, 0x6D, 0x84, 0xD1, 0x8D, 0xC3, 0xFF, 0x46, + 0x20, 0xC2, 0xFF, 0xB7, 0x22, 0x35, 0x9F, 0xDE, + 0xF8, 0x5B, 0xA0, 0xD4, 0xE2, 0xD2, 0x2E, 0xCB, + 0xE0, 0xED, 0x78, 0x4F, 0x99, 0xAF, 0xE5, 0x87 + }, + { + 0x18, 0x1D, 0xF0, 0xA2, 0x61, 0xA2, 0xF7, 0xD2, + 0x9E, 0xA5, 0xA1, 0x57, 0x72, 0x71, 0x51, 0x05, + 0xD4, 0x50, 0xA4, 0xB6, 0xC2, 0x36, 0xF6, 0x99, + 0xF4, 0x62, 0xD6, 0x0C, 0xA7, 0x64, 0x87, 0xFE, + 0xED, 0xFC, 0x9F, 0x5E, 0xB9, 0x2D, 0xF8, 0x38, + 0xE8, 0xFB, 0x5D, 0xC3, 0x69, 0x4E, 0x84, 0xC5, + 0xE0, 0xF4, 0xA1, 0x0B, 0x76, 0x1F, 0x50, 0x67, + 0x62, 0xBE, 0x05, 0x2C, 0x74, 0x5A, 0x6E, 0xE8 + }, + { + 0x21, 0xFB, 0x20, 0x34, 0x58, 0xBF, 0x3A, 0x7E, + 0x9A, 0x80, 0x43, 0x9F, 0x9A, 0x90, 0x28, 0x99, + 0xCD, 0x5D, 0xE0, 0x13, 0x9D, 0xFD, 0x56, 0xF7, + 0x11, 0x0C, 0x9D, 0xEC, 0x84, 0x37, 0xB2, 0x6B, + 0xDA, 0x63, 0xDE, 0x2F, 0x56, 0x59, 0x26, 0xD8, + 0x5E, 0xDB, 0x1D, 0x6C, 0x68, 0x25, 0x66, 0x97, + 0x43, 0xDD, 0x99, 0x92, 0x65, 0x3D, 0x13, 0x97, + 0x95, 0x44, 0xD5, 0xDC, 0x82, 0x28, 0xBF, 0xAA + }, + { + 0xEF, 0x02, 0x1F, 0x29, 0xC5, 0xFF, 0xB8, 0x30, + 0xE6, 0x4B, 0x9A, 0xA9, 0x05, 0x8D, 0xD6, 0x60, + 0xFD, 0x2F, 0xCB, 0x81, 0xC4, 0x97, 0xA7, 0xE6, + 0x98, 0xBC, 0xFB, 0xF5, 0x9D, 0xE5, 0xAD, 0x4A, + 0x86, 0xFF, 0x93, 0xC1, 0x0A, 0x4B, 0x9D, 0x1A, + 0xE5, 0x77, 0x47, 0x25, 0xF9, 0x07, 0x2D, 0xCD, + 0xE9, 0xE1, 0xF1, 0x99, 0xBA, 0xB9, 0x1F, 0x8B, + 0xFF, 0x92, 0x18, 0x64, 0xAA, 0x50, 0x2E, 0xEE + }, + { + 0xB3, 0xCF, 0xDA, 0x40, 0x52, 0x6B, 0x7F, 0x1D, + 0x37, 0x56, 0x9B, 0xDF, 0xCD, 0xF9, 0x11, 0xE5, + 0xA6, 0xEF, 0xE6, 0xB2, 0xEC, 0x90, 0xA0, 0x45, + 0x4C, 0x47, 0xB2, 0xC0, 0x46, 0xBF, 0x13, 0x0F, + 0xC3, 0xB3, 0x52, 0xB3, 0x4D, 0xF4, 0x81, 0x3D, + 0x48, 0xD3, 0x3A, 0xB8, 0xE2, 0x69, 0xB6, 0x9B, + 0x07, 0x56, 0x76, 0xCB, 0x6D, 0x00, 0xA8, 0xDC, + 0xF9, 0xE1, 0xF9, 0x67, 0xEC, 0x19, 0x1B, 0x2C + }, + { + 0xB4, 0xC6, 0xC3, 0xB2, 0x67, 0x07, 0x1E, 0xEF, + 0xB9, 0xC8, 0xC7, 0x2E, 0x0E, 0x2B, 0x94, 0x12, + 0x93, 0x64, 0x1F, 0x86, 0x73, 0xCB, 0x70, 0xC1, + 0xCC, 0x26, 0xAD, 0x1E, 0x73, 0xCF, 0x14, 0x17, + 0x55, 0x86, 0x0A, 0xD1, 0x9B, 0x34, 0xC2, 0xF3, + 0x4E, 0xD3, 0x5B, 0xB5, 0x2E, 0xC4, 0x50, 0x7C, + 0xC1, 0xFE, 0x59, 0x04, 0x77, 0x43, 0xA5, 0xF0, + 0xC6, 0xFE, 0xBD, 0xE6, 0x25, 0xE2, 0x60, 0x91 + }, + { + 0x57, 0xA3, 0x4F, 0x2B, 0xCC, 0xA6, 0x0D, 0x4B, + 0x85, 0x10, 0x3B, 0x83, 0x0C, 0x9D, 0x79, 0x52, + 0xA4, 0x16, 0xBE, 0x52, 0x63, 0xAE, 0x42, 0x9C, + 0x9E, 0x5E, 0x53, 0xFE, 0x85, 0x90, 0xA8, 0xF7, + 0x8E, 0xC6, 0x5A, 0x51, 0x10, 0x9E, 0xA8, 0x5D, + 0xCD, 0xF7, 0xB6, 0x22, 0x3F, 0x9F, 0x2B, 0x34, + 0x05, 0x39, 0xFA, 0xD8, 0x19, 0x23, 0xDB, 0xF8, + 0xED, 0xAB, 0xF9, 0x51, 0x29, 0xE4, 0xDF, 0xF6 + }, + { + 0x9C, 0xF4, 0x66, 0x62, 0xFC, 0xD6, 0x1A, 0x23, + 0x22, 0x77, 0xB6, 0x85, 0x66, 0x3B, 0x8B, 0x5D, + 0xA8, 0x32, 0xDF, 0xD9, 0xA3, 0xB8, 0xCC, 0xFE, + 0xEC, 0x99, 0x3E, 0xC6, 0xAC, 0x41, 0x5A, 0xD0, + 0x7E, 0x04, 0x8A, 0xDF, 0xE4, 0x14, 0xDF, 0x27, + 0x27, 0x70, 0xDB, 0xA8, 0x67, 0xDA, 0x5C, 0x12, + 0x24, 0xC6, 0xFD, 0x0A, 0xA0, 0xC2, 0x18, 0x7D, + 0x42, 0x6A, 0xC6, 0x47, 0xE9, 0x88, 0x73, 0x61 + }, + { + 0x5C, 0xE1, 0x04, 0x2A, 0xB4, 0xD5, 0x42, 0xC2, + 0xF9, 0xEE, 0x9D, 0x17, 0x26, 0x2A, 0xF8, 0x16, + 0x40, 0x98, 0x93, 0x5B, 0xEF, 0x17, 0x3D, 0x0E, + 0x18, 0x48, 0x9B, 0x04, 0x84, 0x17, 0x46, 0xCD, + 0x2F, 0x2D, 0xF8, 0x66, 0xBD, 0x7D, 0xA6, 0xE5, + 0xEF, 0x90, 0x24, 0xC6, 0x48, 0x02, 0x3E, 0xC7, + 0x23, 0xAB, 0x9C, 0x62, 0xFD, 0x80, 0x28, 0x57, + 0x39, 0xD8, 0x4F, 0x15, 0xD2, 0xAB, 0x51, 0x5A + }, + { + 0x84, 0x88, 0x39, 0x6B, 0xD4, 0xA8, 0x72, 0x9B, + 0x7A, 0x47, 0x31, 0x78, 0xF2, 0x32, 0xDA, 0xDF, + 0x3F, 0x0F, 0x8E, 0x22, 0x67, 0x8B, 0xA5, 0xA4, + 0x3E, 0x04, 0x1E, 0x72, 0xDA, 0x1E, 0x2C, 0xF8, + 0x21, 0x94, 0xC3, 0x07, 0x20, 0x7A, 0x54, 0xCB, + 0x81, 0x56, 0x29, 0x33, 0x39, 0xEA, 0xEC, 0x69, + 0x3F, 0xF6, 0x6B, 0xFC, 0xD5, 0xEF, 0xC6, 0x5E, + 0x95, 0xE4, 0xEC, 0xAF, 0x54, 0x53, 0x0A, 0xBD + }, + { + 0xF5, 0x98, 0xDA, 0x90, 0x1C, 0x38, 0x35, 0xBC, + 0xA5, 0x60, 0x77, 0x90, 0x37, 0xDF, 0xDE, 0x9F, + 0x0C, 0x51, 0xDC, 0x61, 0xC0, 0xB7, 0x60, 0xFC, + 0x15, 0x22, 0xD7, 0xB4, 0x70, 0xEE, 0x63, 0xF5, + 0xBD, 0xC6, 0x49, 0x84, 0x76, 0xE8, 0x60, 0x49, + 0xAD, 0x86, 0xE4, 0xE2, 0x1A, 0xF2, 0x85, 0x4A, + 0x98, 0x4C, 0xC9, 0x05, 0x42, 0x7D, 0x2F, 0x17, + 0xF6, 0x6B, 0x1F, 0x41, 0xC3, 0xDA, 0x6F, 0x61 + }, + { + 0x5F, 0x93, 0x26, 0x97, 0x98, 0xCF, 0x02, 0x13, + 0x21, 0x07, 0x33, 0x76, 0x60, 0xA8, 0xD7, 0xA1, + 0x77, 0x35, 0x4C, 0x02, 0x12, 0xEB, 0x93, 0xE5, + 0x55, 0xE7, 0xC3, 0x7A, 0x08, 0xAE, 0xF3, 0xD8, + 0xDC, 0xE0, 0x12, 0x17, 0x01, 0x1C, 0xD9, 0x65, + 0xC0, 0x4D, 0xD2, 0xC1, 0x05, 0xF2, 0xE2, 0xB6, + 0xCA, 0xE5, 0xE4, 0xE6, 0xBC, 0xAF, 0x09, 0xDF, + 0xBE, 0xE3, 0xE0, 0xA6, 0xA6, 0x35, 0x7C, 0x37 + }, + { + 0x0E, 0xCF, 0x58, 0x1D, 0x47, 0xBA, 0xC9, 0x23, + 0x09, 0x86, 0xFA, 0xAB, 0xD7, 0x0C, 0x2F, 0x5B, + 0x80, 0xE9, 0x10, 0x66, 0xF0, 0xEC, 0x55, 0xA8, + 0x42, 0x93, 0x78, 0x82, 0x28, 0x6D, 0x2C, 0xA0, + 0x07, 0xBB, 0x4E, 0x97, 0x3B, 0x0B, 0x09, 0x1D, + 0x52, 0x16, 0x7F, 0xF7, 0xC4, 0x00, 0x9C, 0x7A, + 0xB4, 0xAD, 0x38, 0xFF, 0xF1, 0xDC, 0xEA, 0xCD, + 0xB7, 0xBE, 0x81, 0xEF, 0x4A, 0x45, 0x29, 0x52 + }, + { + 0x5A, 0xEC, 0xA8, 0xAB, 0xE1, 0x52, 0x85, 0x82, + 0xB2, 0xA3, 0x07, 0xB4, 0x00, 0x95, 0x85, 0x49, + 0x8A, 0x3D, 0x46, 0x7C, 0xA6, 0x10, 0x1C, 0xB0, + 0xC5, 0x12, 0x6F, 0x99, 0x76, 0x05, 0x6E, 0x9F, + 0xFC, 0x12, 0x3C, 0xC2, 0x0C, 0x30, 0x2B, 0x2A, + 0x73, 0x7F, 0x49, 0x2C, 0x75, 0xD2, 0x1F, 0x01, + 0x51, 0x2C, 0x90, 0xCA, 0x05, 0x41, 0xDF, 0xA5, + 0x6E, 0x95, 0x0A, 0x32, 0x1D, 0xCB, 0x28, 0xD8 + }, + { + 0x73, 0x2F, 0xBF, 0x8F, 0x1C, 0xB2, 0xB8, 0x32, + 0x92, 0x63, 0xED, 0xE2, 0x78, 0x58, 0xFE, 0x46, + 0xF8, 0xD3, 0x35, 0x4D, 0x37, 0x6B, 0xCD, 0xA0, + 0x54, 0x8E, 0x7C, 0xE1, 0xFA, 0x9D, 0xD1, 0x1F, + 0x85, 0xEB, 0x66, 0x1F, 0xE9, 0x50, 0xB5, 0x43, + 0xAA, 0x63, 0x5C, 0xA4, 0xD3, 0xF0, 0x4E, 0xDE, + 0x5B, 0x32, 0xD6, 0xB6, 0x56, 0xE5, 0xCE, 0x1C, + 0x44, 0xD3, 0x5C, 0x4A, 0x6C, 0x56, 0xCF, 0xF8 + }, + { + 0xD5, 0xE9, 0x38, 0x73, 0x5D, 0x63, 0x78, 0x8C, + 0x80, 0x10, 0x0A, 0xEF, 0xD1, 0x86, 0x48, 0xD1, + 0x8C, 0xF2, 0x72, 0xF6, 0x9F, 0x20, 0xFF, 0x24, + 0xCF, 0xE2, 0x89, 0x5C, 0x08, 0x8A, 0xD0, 0x8B, + 0x01, 0x04, 0xDA, 0x16, 0x72, 0xA4, 0xEB, 0x26, + 0xFC, 0x52, 0x54, 0x5C, 0xC7, 0xD7, 0xA0, 0x1B, + 0x26, 0x6C, 0xF5, 0x46, 0xC4, 0x03, 0xC4, 0x5B, + 0xD1, 0x29, 0xEB, 0x41, 0xBD, 0xD9, 0x20, 0x0B + }, + { + 0x65, 0xA2, 0x45, 0xB4, 0x93, 0x52, 0xEE, 0x29, + 0x7D, 0x91, 0xAF, 0x8C, 0x8B, 0xE0, 0x05, 0x28, + 0xAC, 0x6E, 0x04, 0x6D, 0xD8, 0x3A, 0xC7, 0xBD, + 0x46, 0x5A, 0x98, 0x81, 0x6D, 0xD6, 0x8F, 0x3E, + 0x00, 0xE1, 0xAE, 0x8F, 0x89, 0x53, 0x27, 0xA7, + 0xE9, 0xA8, 0xC9, 0x32, 0x65, 0x98, 0x37, 0x9A, + 0x29, 0xC9, 0xFC, 0x91, 0xEC, 0x0C, 0x6E, 0xEF, + 0x08, 0xF3, 0xE2, 0xB2, 0x16, 0xC1, 0x10, 0x08 + }, + { + 0xC9, 0x56, 0x54, 0xB6, 0x30, 0x19, 0x13, 0x0A, + 0xB4, 0x5D, 0xD0, 0xFB, 0x49, 0x41, 0xB9, 0x8A, + 0xEB, 0x3A, 0xF2, 0xA1, 0x23, 0x91, 0x3E, 0xCA, + 0x2C, 0xE9, 0x9B, 0x3E, 0x97, 0x41, 0x0A, 0x7B, + 0xF8, 0x66, 0x1C, 0xC7, 0xFB, 0xAA, 0x2B, 0xC1, + 0xCF, 0x2B, 0x13, 0x11, 0x3B, 0x1E, 0xD4, 0x0A, + 0x01, 0x18, 0xB8, 0x8E, 0x5F, 0xFF, 0xC3, 0x54, + 0x27, 0x59, 0xEA, 0x00, 0x7E, 0xD4, 0xC5, 0x8D + }, + { + 0x1E, 0xB2, 0x62, 0xF3, 0x8F, 0xA4, 0x94, 0x43, + 0x1F, 0x01, 0x7D, 0xAD, 0x44, 0xC0, 0xDF, 0xB6, + 0x93, 0x24, 0xAC, 0x03, 0x2F, 0x04, 0xB6, 0x57, + 0xFC, 0x91, 0xA8, 0x86, 0x47, 0xBB, 0x74, 0x76, + 0x0F, 0x24, 0xE7, 0xC9, 0x56, 0x51, 0x4F, 0x0C, + 0xF0, 0x02, 0x99, 0x0B, 0x18, 0x2C, 0x16, 0x42, + 0xB9, 0xB2, 0x42, 0x6E, 0x96, 0xA6, 0x11, 0x87, + 0xE4, 0xE0, 0x12, 0xF0, 0x0E, 0x21, 0x7D, 0x84 + }, + { + 0x3B, 0x95, 0x5A, 0xEE, 0xBF, 0xA5, 0x15, 0x1A, + 0xC1, 0xAB, 0x8E, 0x3F, 0x5C, 0xC1, 0xE3, 0x76, + 0x70, 0x84, 0xC8, 0x42, 0xA5, 0x75, 0xD3, 0x62, + 0x69, 0x83, 0x6E, 0x97, 0x35, 0x3D, 0x41, 0x62, + 0x2B, 0x73, 0x1D, 0xDD, 0xCD, 0x5F, 0x26, 0x95, + 0x50, 0xA3, 0xA5, 0xB8, 0x7B, 0xE1, 0xE9, 0x03, + 0x26, 0x34, 0x0B, 0x6E, 0x0E, 0x62, 0x55, 0x58, + 0x15, 0xD9, 0x60, 0x05, 0x97, 0xAC, 0x6E, 0xF9 + }, + { + 0x68, 0x28, 0x9F, 0x66, 0x05, 0x47, 0x3B, 0xA0, + 0xE4, 0xF2, 0x41, 0xBA, 0xF7, 0x47, 0x7A, 0x98, + 0x85, 0x42, 0x6A, 0x85, 0x8F, 0x19, 0xEF, 0x2A, + 0x18, 0xB0, 0xD4, 0x0E, 0xF8, 0xE4, 0x12, 0x82, + 0xED, 0x55, 0x26, 0xB5, 0x19, 0x79, 0x9E, 0x27, + 0x0F, 0x13, 0x88, 0x13, 0x27, 0x91, 0x82, 0x78, + 0x75, 0x57, 0x11, 0x07, 0x1D, 0x85, 0x11, 0xFE, + 0x96, 0x3E, 0x3B, 0x56, 0x06, 0xAA, 0x37, 0x16 + }, + { + 0x80, 0xA3, 0x37, 0x87, 0x54, 0x26, 0x12, 0xC3, + 0x8F, 0x6B, 0xCD, 0x7C, 0xD8, 0x6C, 0xAB, 0x46, + 0x02, 0x27, 0x50, 0x9B, 0x1C, 0xBA, 0xD5, 0xEC, + 0x40, 0x8A, 0x91, 0x41, 0x3D, 0x51, 0x15, 0x5A, + 0x04, 0x76, 0xDA, 0xDB, 0xF3, 0xA2, 0x51, 0x8E, + 0x4A, 0x6E, 0x77, 0xCC, 0x34, 0x66, 0x22, 0xE3, + 0x47, 0xA4, 0x69, 0xBF, 0x8B, 0xAA, 0x5F, 0x04, + 0xEB, 0x2D, 0x98, 0x70, 0x53, 0x55, 0xD0, 0x63 + }, + { + 0x34, 0x62, 0x9B, 0xC6, 0xD8, 0x31, 0x39, 0x1C, + 0x4C, 0xDF, 0x8A, 0xF1, 0xB4, 0xB7, 0xB6, 0xB8, + 0xE8, 0xEE, 0x17, 0xCF, 0x98, 0xC7, 0x0E, 0x5D, + 0xD5, 0x86, 0xCD, 0x99, 0xF1, 0x4B, 0x11, 0xDF, + 0x94, 0x51, 0x66, 0x23, 0x6A, 0x95, 0x71, 0xE6, + 0xD5, 0x91, 0xBB, 0x83, 0xEE, 0x4D, 0x16, 0x4D, + 0x46, 0xF6, 0xB9, 0xD8, 0xEF, 0x86, 0xFF, 0x86, + 0x5A, 0x81, 0xBF, 0xB9, 0x1B, 0x00, 0x42, 0x4B + }, + { + 0x8B, 0x7C, 0xC3, 0x39, 0x16, 0x38, 0x63, 0xBB, + 0x43, 0x83, 0xE5, 0x42, 0xB0, 0xEF, 0x0E, 0x7C, + 0xF3, 0x6B, 0x84, 0xAD, 0x93, 0x2C, 0xDF, 0x5A, + 0x80, 0x41, 0x9E, 0xC9, 0xAD, 0x69, 0x2E, 0x7A, + 0x7E, 0x78, 0x4D, 0x2C, 0x7C, 0xB3, 0x79, 0x6A, + 0x18, 0xB8, 0xF8, 0x00, 0x03, 0x5F, 0x3A, 0xA0, + 0x6C, 0x82, 0x41, 0x00, 0x61, 0x11, 0x20, 0xA7, + 0xBD, 0xEB, 0x35, 0x61, 0x8C, 0xCB, 0x81, 0xB7 + }, + { + 0x4F, 0x08, 0x4E, 0x49, 0x39, 0xDD, 0x5A, 0x7F, + 0x5A, 0x65, 0x8F, 0xAD, 0x58, 0xA1, 0x8A, 0x15, + 0xC2, 0x5C, 0x32, 0xEC, 0x1C, 0x7F, 0xD5, 0xC5, + 0xC6, 0xC3, 0xE8, 0x92, 0xB3, 0x97, 0x1A, 0xEA, + 0xAC, 0x30, 0x83, 0x04, 0xEF, 0x17, 0xB1, 0xC4, + 0x72, 0x39, 0xEA, 0x4B, 0xB3, 0x98, 0xB3, 0xFD, + 0x6D, 0x45, 0x28, 0xD8, 0xDE, 0x8E, 0x76, 0x8A, + 0xE0, 0xF1, 0xA5, 0xA5, 0xC6, 0xB5, 0xC2, 0x97 + }, + { + 0x48, 0xF4, 0x07, 0xA1, 0xAF, 0x5B, 0x80, 0x09, + 0xB2, 0x05, 0x17, 0x42, 0xE8, 0xCF, 0x5C, 0xD5, + 0x65, 0x66, 0x69, 0xE7, 0xD7, 0x22, 0xEE, 0x8E, + 0x7B, 0xD2, 0x02, 0x06, 0x08, 0x49, 0x44, 0x21, + 0x68, 0xD8, 0xFA, 0xCC, 0x11, 0x7C, 0x01, 0x2B, + 0xFB, 0x7B, 0xF4, 0x49, 0xD9, 0x9B, 0xEF, 0xFF, + 0x6A, 0x34, 0xAE, 0xA2, 0x03, 0xF1, 0xD8, 0xD3, + 0x52, 0x72, 0x2B, 0xE5, 0x01, 0x4E, 0xC8, 0x18 + }, + { + 0xA6, 0xAA, 0x82, 0xCD, 0x1E, 0x42, 0x6F, 0x9A, + 0x73, 0xBF, 0xA3, 0x9A, 0x29, 0x03, 0x78, 0x76, + 0x11, 0x46, 0x55, 0xB8, 0xC2, 0x2D, 0x6D, 0x3F, + 0xF8, 0xB6, 0x38, 0xAE, 0x7D, 0xEA, 0x6B, 0x17, + 0x84, 0x3E, 0x09, 0xE5, 0x2E, 0xB6, 0x6F, 0xA1, + 0xE4, 0x75, 0xE4, 0xA8, 0xA3, 0xDE, 0x42, 0x9B, + 0x7D, 0x0F, 0x4A, 0x77, 0x6F, 0xCB, 0x8B, 0xDC, + 0x9B, 0x9F, 0xED, 0xE7, 0xD5, 0x2E, 0x81, 0x5F + }, + { + 0x58, 0x17, 0x02, 0x7D, 0x6B, 0xDD, 0x00, 0xC5, + 0xDD, 0x10, 0xAC, 0x59, 0x3C, 0xD5, 0x60, 0x37, + 0x22, 0x70, 0x77, 0x5A, 0x18, 0x52, 0x6D, 0x7E, + 0x6F, 0x13, 0x87, 0x2A, 0x2E, 0x20, 0xEA, 0xB6, + 0x64, 0x62, 0x5B, 0xE7, 0x16, 0x8A, 0xC4, 0xBD, + 0x7C, 0x9E, 0x0C, 0xE7, 0xFC, 0x40, 0x99, 0xE0, + 0xF4, 0x84, 0x42, 0xE2, 0xC7, 0x67, 0x19, 0x1C, + 0x6E, 0x12, 0x84, 0xE9, 0xB2, 0xCC, 0xEA, 0x8C + }, + { + 0x08, 0xE4, 0x10, 0x28, 0x34, 0x0A, 0x45, 0xC7, + 0x4E, 0x40, 0x52, 0xB3, 0xA8, 0xD6, 0x38, 0x9E, + 0x22, 0xE0, 0x43, 0xA1, 0xAD, 0xAB, 0x5E, 0x28, + 0xD9, 0x76, 0x19, 0x45, 0x0D, 0x72, 0x34, 0x69, + 0xB6, 0x20, 0xCA, 0xA5, 0x19, 0xB8, 0x1C, 0x14, + 0x52, 0x38, 0x54, 0xF6, 0x19, 0xFD, 0x30, 0x27, + 0xE3, 0x84, 0x7B, 0xD0, 0x32, 0x76, 0xE6, 0x06, + 0x04, 0xA8, 0x0D, 0xDB, 0x4D, 0xE8, 0x76, 0xD6 + }, + { + 0x13, 0x0B, 0x84, 0x20, 0x53, 0x7E, 0xB0, 0x7D, + 0x72, 0xAB, 0xDA, 0x07, 0xC8, 0x5A, 0xCB, 0xD8, + 0xB9, 0xA4, 0x4F, 0x16, 0x32, 0x1D, 0xD0, 0x42, + 0x21, 0x45, 0xF8, 0x09, 0x67, 0x3D, 0x30, 0xF2, + 0xB5, 0x32, 0x13, 0x26, 0xE2, 0xBF, 0xF3, 0x17, + 0xEF, 0x3F, 0xEF, 0x98, 0x3C, 0x51, 0xC4, 0xF8, + 0xAB, 0x24, 0xA3, 0x25, 0xD2, 0x98, 0xE3, 0x4A, + 0xFC, 0xE5, 0x69, 0xA8, 0x25, 0x55, 0x77, 0x4C + }, + { + 0xAC, 0x49, 0xB8, 0x44, 0xAF, 0xAA, 0x01, 0x2E, + 0x31, 0xC4, 0x74, 0xCA, 0x26, 0x36, 0x48, 0x84, + 0x4F, 0xD2, 0xF6, 0x30, 0x79, 0x92, 0xC2, 0xF7, + 0x52, 0xAC, 0xA0, 0x2C, 0x38, 0x28, 0x96, 0x51, + 0x75, 0x79, 0x4D, 0xEE, 0xE2, 0xD2, 0xEE, 0x95, + 0xC6, 0x1C, 0xD2, 0x84, 0xF6, 0xB5, 0xA2, 0xD7, + 0x5E, 0x2E, 0xF2, 0xB2, 0x9E, 0xE8, 0x14, 0x9E, + 0x77, 0xFB, 0x81, 0x44, 0x7B, 0x2F, 0xD0, 0x4B + }, + { + 0xB9, 0xD7, 0xCA, 0x81, 0xCC, 0x60, 0xBB, 0x95, + 0x78, 0xE4, 0x40, 0x24, 0xE5, 0xA0, 0xA0, 0xBE, + 0x80, 0xF2, 0x73, 0x36, 0xA6, 0xA9, 0xF4, 0xE5, + 0x3D, 0xF3, 0x99, 0x9C, 0xB1, 0x91, 0x28, 0x0B, + 0x09, 0x0E, 0x2A, 0xC2, 0xD2, 0x9C, 0x5B, 0xAA, + 0xD9, 0xD7, 0x14, 0x15, 0xBD, 0xC1, 0x29, 0xE6, + 0x9A, 0xA2, 0x66, 0x7A, 0xF6, 0xA7, 0xFD, 0x5E, + 0x18, 0x9F, 0xCC, 0xDC, 0xEE, 0x81, 0x73, 0x40 + }, + { + 0xA7, 0x55, 0xE1, 0x13, 0x38, 0x65, 0x72, 0xC7, + 0x5C, 0xED, 0x61, 0xD7, 0x19, 0x70, 0x60, 0x70, + 0xB9, 0x14, 0x60, 0x48, 0xE4, 0x2A, 0x9F, 0x8C, + 0xD3, 0x56, 0x67, 0xA0, 0x88, 0xB4, 0x2F, 0x08, + 0x80, 0x8A, 0xBD, 0xF7, 0x7E, 0x61, 0x8A, 0xBD, + 0x95, 0x9A, 0xFC, 0x75, 0x73, 0x79, 0xCA, 0x2C, + 0x00, 0xBC, 0xC1, 0xA4, 0x83, 0x90, 0xFA, 0x2B, + 0xFF, 0x61, 0x8B, 0x1E, 0x00, 0x78, 0xA6, 0x13 + }, + { + 0xA7, 0x3C, 0x7D, 0xEB, 0xED, 0x32, 0x6F, 0x1C, + 0x0D, 0xB0, 0x79, 0x5E, 0xE7, 0xD6, 0xE3, 0x94, + 0x68, 0x94, 0xB8, 0x26, 0xB1, 0xF8, 0x10, 0x1C, + 0x56, 0xC8, 0x23, 0xBA, 0x17, 0x16, 0x83, 0x12, + 0xE7, 0xF5, 0x3F, 0xC7, 0xDB, 0xE5, 0x2C, 0x3E, + 0x11, 0xE6, 0x98, 0x52, 0xC4, 0x04, 0x85, 0xE2, + 0xEF, 0x18, 0x24, 0x77, 0x86, 0x2E, 0xA6, 0xA3, + 0x4E, 0xC1, 0x36, 0xE2, 0xDF, 0xEE, 0xA6, 0xF4 + }, + { + 0x6C, 0xB8, 0xF9, 0xD5, 0x2C, 0x56, 0xD8, 0x2C, + 0xAC, 0x28, 0xF3, 0x9E, 0xA1, 0x59, 0x3E, 0x8B, + 0xB2, 0x50, 0x62, 0x93, 0xAC, 0x0D, 0x68, 0x37, + 0x6A, 0x17, 0x09, 0xB6, 0x2A, 0x46, 0xDF, 0x14, + 0xA4, 0xAE, 0x64, 0xB2, 0xD8, 0xFA, 0xB7, 0x67, + 0x33, 0xA1, 0xCE, 0xD2, 0xD5, 0x48, 0xE3, 0xF3, + 0xC6, 0xFC, 0xB4, 0x9D, 0x40, 0xC3, 0xD5, 0x80, + 0x8E, 0x44, 0x9C, 0xD8, 0x3D, 0x1C, 0x2A, 0xA2 + }, + { + 0x68, 0x3F, 0xA2, 0xB2, 0x36, 0x9A, 0x10, 0x16, + 0x2C, 0x1C, 0x1C, 0x7B, 0x24, 0xBC, 0x97, 0x0E, + 0xE6, 0x7D, 0xA2, 0x20, 0x56, 0x4F, 0x32, 0x20, + 0x3F, 0x62, 0x56, 0x96, 0xC0, 0x35, 0x2A, 0x0B, + 0x9A, 0xD9, 0x66, 0x24, 0x36, 0x2D, 0x95, 0x2D, + 0x84, 0x46, 0x3C, 0x11, 0x06, 0xA2, 0xDB, 0xA7, + 0xA0, 0x92, 0x59, 0x98, 0x84, 0xB3, 0x5A, 0x0B, + 0x89, 0xC8, 0xF1, 0xB6, 0xA9, 0xB5, 0xA6, 0x1E + }, + { + 0xAA, 0xD9, 0xAD, 0x44, 0x61, 0x01, 0x18, 0xB7, + 0x7D, 0x50, 0x8A, 0xEB, 0x1B, 0xBC, 0xD1, 0xC1, + 0xB7, 0xD0, 0x17, 0x13, 0x97, 0xFB, 0x51, 0x0A, + 0x40, 0x1B, 0xBC, 0x0E, 0xC3, 0x46, 0x23, 0x67, + 0x0D, 0x86, 0xA2, 0xDC, 0x3C, 0x8F, 0x3A, 0xB5, + 0xA2, 0x04, 0x4D, 0xF7, 0x30, 0x25, 0x67, 0x27, + 0x54, 0x5F, 0x08, 0x60, 0xCE, 0x21, 0xA1, 0xEA, + 0xC7, 0x17, 0xDF, 0xC4, 0x8F, 0x5D, 0x22, 0x8E + }, + { + 0xC4, 0x25, 0x78, 0xDE, 0x23, 0xB4, 0xC9, 0x87, + 0xD5, 0xE1, 0xAC, 0x4D, 0x68, 0x9E, 0xD5, 0xDE, + 0x4B, 0x04, 0x17, 0xF9, 0x70, 0x4B, 0xC6, 0xBC, + 0xE9, 0x69, 0xFA, 0x13, 0x47, 0x15, 0x85, 0xD6, + 0x2C, 0x2C, 0xB1, 0x21, 0x2A, 0x94, 0x4F, 0x39, + 0x7F, 0xC9, 0xCA, 0x2C, 0x37, 0x47, 0xC3, 0xBE, + 0xB6, 0x94, 0xEC, 0x4C, 0x5B, 0xE6, 0x88, 0x28, + 0xDD, 0xA5, 0x3E, 0xF4, 0x3F, 0xAE, 0xC6, 0xC0 + }, + { + 0x47, 0x0F, 0x00, 0x84, 0x1E, 0xE8, 0x24, 0x4E, + 0x63, 0xED, 0x2C, 0x7E, 0xA3, 0x0E, 0x2E, 0x41, + 0x98, 0x97, 0xC1, 0x97, 0x46, 0x2E, 0xCC, 0xCE, + 0xCF, 0x71, 0x3B, 0x42, 0xA5, 0x06, 0x5F, 0xFF, + 0x59, 0x14, 0xBC, 0x9B, 0x79, 0xAF, 0xFE, 0x8F, + 0x6B, 0x65, 0x78, 0x75, 0xE7, 0x89, 0xAE, 0x21, + 0x3B, 0xD9, 0x14, 0xCD, 0x35, 0xBD, 0x17, 0x4D, + 0x46, 0xE9, 0xD1, 0x8B, 0xD8, 0x43, 0x77, 0x3D + }, + { + 0x34, 0xFC, 0x42, 0x13, 0x73, 0x0F, 0x47, 0xA5, + 0xE9, 0xA3, 0x58, 0x0F, 0x64, 0x3E, 0x12, 0x94, + 0x5C, 0xFC, 0xB3, 0x1B, 0xF2, 0x06, 0xF6, 0xAD, + 0x45, 0x0C, 0xE5, 0x28, 0xDA, 0x3F, 0xA4, 0x32, + 0xE0, 0x05, 0xD6, 0xB0, 0xEC, 0xCE, 0x10, 0xDC, + 0xA7, 0xC5, 0x99, 0x5F, 0x6A, 0xAC, 0xC5, 0x15, + 0x0E, 0x1B, 0x00, 0x9E, 0x19, 0x75, 0x1E, 0x83, + 0x09, 0xF8, 0x85, 0x95, 0x31, 0x84, 0x43, 0x74 + }, + { + 0xFB, 0x3C, 0x1F, 0x0F, 0x56, 0xA5, 0x6F, 0x8E, + 0x31, 0x6F, 0xDF, 0x5D, 0x85, 0x3C, 0x8C, 0x87, + 0x2C, 0x39, 0x63, 0x5D, 0x08, 0x36, 0x34, 0xC3, + 0x90, 0x4F, 0xC3, 0xAC, 0x07, 0xD1, 0xB5, 0x78, + 0xE8, 0x5F, 0xF0, 0xE4, 0x80, 0xE9, 0x2D, 0x44, + 0xAD, 0xE3, 0x3B, 0x62, 0xE8, 0x93, 0xEE, 0x32, + 0x34, 0x3E, 0x79, 0xDD, 0xF6, 0xEF, 0x29, 0x2E, + 0x89, 0xB5, 0x82, 0xD3, 0x12, 0x50, 0x23, 0x14 + }, + { + 0xC7, 0xC9, 0x7F, 0xC6, 0x5D, 0xD2, 0xB9, 0xE3, + 0xD3, 0xD6, 0x07, 0xD3, 0x15, 0x98, 0xD3, 0xF8, + 0x42, 0x61, 0xE9, 0x91, 0x92, 0x51, 0xE9, 0xC8, + 0xE5, 0x7B, 0xB5, 0xF8, 0x29, 0x37, 0x7D, 0x5F, + 0x73, 0xEA, 0xBB, 0xED, 0x55, 0xC6, 0xC3, 0x81, + 0x18, 0x0F, 0x29, 0xAD, 0x02, 0xE5, 0xBE, 0x79, + 0x7F, 0xFE, 0xC7, 0xE5, 0x7B, 0xDE, 0xCB, 0xC5, + 0x0A, 0xD3, 0xD0, 0x62, 0xF0, 0x99, 0x3A, 0xB0 + }, + { + 0xA5, 0x7A, 0x49, 0xCD, 0xBE, 0x67, 0xAE, 0x7D, + 0x9F, 0x79, 0x7B, 0xB5, 0xCC, 0x7E, 0xFC, 0x2D, + 0xF0, 0x7F, 0x4E, 0x1B, 0x15, 0x95, 0x5F, 0x85, + 0xDA, 0xE7, 0x4B, 0x76, 0xE2, 0xEC, 0xB8, 0x5A, + 0xFB, 0x6C, 0xD9, 0xEE, 0xED, 0x88, 0x88, 0xD5, + 0xCA, 0x3E, 0xC5, 0xAB, 0x65, 0xD2, 0x7A, 0x7B, + 0x19, 0xE5, 0x78, 0x47, 0x57, 0x60, 0xA0, 0x45, + 0xAC, 0x3C, 0x92, 0xE1, 0x3A, 0x93, 0x8E, 0x77 + }, + { + 0xC7, 0x14, 0x3F, 0xCE, 0x96, 0x14, 0xA1, 0x7F, + 0xD6, 0x53, 0xAE, 0xB1, 0x40, 0x72, 0x6D, 0xC9, + 0xC3, 0xDB, 0xB1, 0xDE, 0x6C, 0xC5, 0x81, 0xB2, + 0x72, 0x68, 0x97, 0xEC, 0x24, 0xB7, 0xA5, 0x03, + 0x59, 0xAD, 0x49, 0x22, 0x43, 0xBE, 0x66, 0xD9, + 0xED, 0xD8, 0xC9, 0x33, 0xB5, 0xB8, 0x0E, 0x0B, + 0x91, 0xBB, 0x61, 0xEA, 0x98, 0x05, 0x60, 0x06, + 0x51, 0x69, 0x76, 0xFA, 0xE8, 0xD9, 0x9A, 0x35 + }, + { + 0x65, 0xBB, 0x58, 0xD0, 0x7F, 0x93, 0x7E, 0x2D, + 0x3C, 0x7E, 0x65, 0x38, 0x5F, 0x9C, 0x54, 0x73, + 0x0B, 0x70, 0x41, 0x05, 0xCC, 0xDB, 0x69, 0x1F, + 0x6E, 0x14, 0x6D, 0x4E, 0xE8, 0xF6, 0xC0, 0x86, + 0xF4, 0x95, 0x11, 0x03, 0x51, 0x10, 0xA9, 0xAD, + 0x60, 0x31, 0xFD, 0xCE, 0xB9, 0x43, 0xE0, 0xF9, + 0x61, 0x3B, 0xCB, 0x27, 0x6D, 0xD4, 0x0F, 0x06, + 0x24, 0xEF, 0x0F, 0x92, 0x4F, 0x80, 0x97, 0x83 + }, + { + 0xE5, 0x40, 0x27, 0x7F, 0x68, 0x3B, 0x11, 0x86, + 0xDD, 0x3B, 0x5B, 0x3F, 0x61, 0x43, 0x33, 0x96, + 0x58, 0x1A, 0x35, 0xFE, 0xB1, 0x20, 0x02, 0xBE, + 0x8C, 0x6A, 0x62, 0x31, 0xFC, 0x40, 0xFF, 0xA7, + 0x0F, 0x08, 0x08, 0x1B, 0xC5, 0x8B, 0x2D, 0x94, + 0xF7, 0x64, 0x95, 0x43, 0x61, 0x4A, 0x43, 0x5F, + 0xAA, 0x2D, 0x62, 0x11, 0x0E, 0x13, 0xDA, 0xBC, + 0x7B, 0x86, 0x62, 0x9B, 0x63, 0xAF, 0x9C, 0x24 + }, + { + 0x41, 0x85, 0x00, 0x87, 0x8C, 0x5F, 0xBC, 0xB5, + 0x84, 0xC4, 0x32, 0xF4, 0x28, 0x5E, 0x05, 0xE4, + 0x9F, 0x2E, 0x3E, 0x07, 0x53, 0x99, 0xA0, 0xDB, + 0xFC, 0xF8, 0x74, 0xEB, 0xF8, 0xC0, 0x3D, 0x02, + 0xBF, 0x16, 0xBC, 0x69, 0x89, 0xD1, 0x61, 0xC7, + 0x7C, 0xA0, 0x78, 0x6B, 0x05, 0x05, 0x3C, 0x6C, + 0x70, 0x94, 0x33, 0x71, 0x23, 0x19, 0x19, 0x21, + 0x28, 0x83, 0x5C, 0xF0, 0xB6, 0x60, 0x59, 0x5B + }, + { + 0x88, 0x90, 0x90, 0xDB, 0xB1, 0x94, 0x4B, 0xDC, + 0x94, 0x33, 0xEE, 0x5E, 0xF1, 0x01, 0x0C, 0x7A, + 0x4A, 0x24, 0xA8, 0xE7, 0x1E, 0xCE, 0xA8, 0xE1, + 0x2A, 0x31, 0x31, 0x8C, 0xE4, 0x9D, 0xCA, 0xB0, + 0xAC, 0xA5, 0xC3, 0x80, 0x23, 0x34, 0xAA, 0xB2, + 0xCC, 0x84, 0xB1, 0x4C, 0x6B, 0x93, 0x21, 0xFE, + 0x58, 0x6B, 0xF3, 0xF8, 0x76, 0xF1, 0x9C, 0xD4, + 0x06, 0xEB, 0x11, 0x27, 0xFB, 0x94, 0x48, 0x01 + }, + { + 0x53, 0xB6, 0xA2, 0x89, 0x10, 0xAA, 0x92, 0xE2, + 0x7E, 0x53, 0x6F, 0xB5, 0x49, 0xCF, 0x9B, 0x99, + 0x18, 0x79, 0x10, 0x60, 0x89, 0x8E, 0x0B, 0x9F, + 0xE1, 0x83, 0x57, 0x7F, 0xF4, 0x3B, 0x5E, 0x9C, + 0x76, 0x89, 0xC7, 0x45, 0xB3, 0x2E, 0x41, 0x22, + 0x69, 0x83, 0x7C, 0x31, 0xB8, 0x9E, 0x6C, 0xC1, + 0x2B, 0xF7, 0x6E, 0x13, 0xCA, 0xD3, 0x66, 0xB7, + 0x4E, 0xCE, 0x48, 0xBB, 0x85, 0xFD, 0x09, 0xE9 + }, + { + 0x7C, 0x09, 0x20, 0x80, 0xC6, 0xA8, 0x0D, 0x67, + 0x24, 0x09, 0xD0, 0x81, 0xD3, 0xD1, 0x77, 0x10, + 0x6B, 0xCD, 0x63, 0x56, 0x77, 0x85, 0x14, 0x07, + 0x19, 0x49, 0x09, 0x50, 0xAE, 0x07, 0xAE, 0x8F, + 0xCA, 0xAB, 0xBA, 0xAA, 0xB3, 0x30, 0xCF, 0xBC, + 0xF7, 0x37, 0x44, 0x82, 0xC2, 0x20, 0xAF, 0x2E, + 0xAD, 0xEE, 0xB7, 0x3D, 0xCB, 0xB3, 0x5E, 0xD8, + 0x23, 0x34, 0x4E, 0x14, 0x4E, 0x7D, 0x48, 0x99 + }, + { + 0x9C, 0xCD, 0xE5, 0x66, 0xD2, 0x40, 0x05, 0x09, + 0x18, 0x11, 0x11, 0xF3, 0x2D, 0xDE, 0x4C, 0xD6, + 0x32, 0x09, 0xFE, 0x59, 0xA3, 0x0C, 0x11, 0x45, + 0x46, 0xAD, 0x27, 0x76, 0xD8, 0x89, 0xA4, 0x1B, + 0xAD, 0x8F, 0xA1, 0xBB, 0x46, 0x8C, 0xB2, 0xF9, + 0xD4, 0x2C, 0xA9, 0x92, 0x8A, 0x77, 0x70, 0xFE, + 0xF8, 0xE8, 0xBA, 0x4D, 0x0C, 0x81, 0x2D, 0x9A, + 0x1E, 0x75, 0xC3, 0xD8, 0xD2, 0xCC, 0xD7, 0x5A + }, + { + 0x6E, 0x29, 0x3B, 0xF5, 0xD0, 0x3F, 0xE4, 0x39, + 0x77, 0xCF, 0xE3, 0xF5, 0x7C, 0xCD, 0xB3, 0xAE, + 0x28, 0x2A, 0x85, 0x45, 0x5D, 0xCA, 0x33, 0xF3, + 0x7F, 0x4B, 0x74, 0xF8, 0x39, 0x8C, 0xC6, 0x12, + 0x43, 0x3D, 0x75, 0x5C, 0xBE, 0xC4, 0x12, 0xF8, + 0xF8, 0x2A, 0x3B, 0xD3, 0xBC, 0x4A, 0x27, 0x8F, + 0x7E, 0xCD, 0x0D, 0xFA, 0x9B, 0xBD, 0xC4, 0x0B, + 0xE7, 0xA7, 0x87, 0xC8, 0xF1, 0x59, 0xB2, 0xDF + }, + { + 0xC5, 0x65, 0x46, 0xFB, 0x21, 0x78, 0x45, 0x6F, + 0x33, 0x61, 0x64, 0xC1, 0x8B, 0x90, 0xDE, 0xFF, + 0xC8, 0x3A, 0xE2, 0xB5, 0xA3, 0xAC, 0xA7, 0x7B, + 0x68, 0x84, 0xD3, 0x6D, 0x2C, 0x1D, 0xB3, 0x95, + 0x01, 0xB3, 0xE6, 0x5E, 0x36, 0xC7, 0x58, 0xC6, + 0x6E, 0x31, 0x88, 0x45, 0x1F, 0xDB, 0x35, 0x15, + 0xEE, 0x16, 0x2C, 0x00, 0x1F, 0x06, 0xC3, 0xE8, + 0xCB, 0x57, 0x3A, 0xDF, 0x30, 0xF7, 0xA1, 0x01 + }, + { + 0x6F, 0x82, 0xF8, 0x9F, 0x29, 0x9E, 0xBC, 0xA2, + 0xFE, 0x01, 0x4B, 0x59, 0xBF, 0xFE, 0x1A, 0xA8, + 0x4E, 0x88, 0xB1, 0x91, 0x5F, 0xE2, 0x56, 0xAF, + 0xB6, 0x46, 0xFD, 0x84, 0x48, 0xAF, 0x2B, 0x88, + 0x91, 0xA7, 0xFA, 0xB3, 0x7A, 0x4E, 0xA6, 0xF9, + 0xA5, 0x0E, 0x6C, 0x31, 0x70, 0x39, 0xD8, 0xCF, + 0x87, 0x8F, 0x4C, 0x8E, 0x1A, 0x0D, 0xD4, 0x64, + 0xF0, 0xB4, 0xD6, 0xFF, 0x1C, 0x7E, 0xA8, 0x53 + }, + { + 0x2B, 0x85, 0x99, 0xFF, 0x9C, 0x3D, 0x61, 0x98, + 0x63, 0x7A, 0xD5, 0x1E, 0x57, 0xD1, 0x99, 0x8B, + 0x0D, 0x75, 0x31, 0x3F, 0xE2, 0xDD, 0x61, 0xA5, + 0x33, 0xC9, 0x64, 0xA6, 0xDD, 0x96, 0x07, 0xC6, + 0xF7, 0x23, 0xE9, 0x45, 0x2C, 0xE4, 0x6E, 0x01, + 0x4B, 0x1C, 0x1D, 0x6D, 0xE7, 0x7B, 0xA5, 0xB8, + 0x8C, 0x91, 0x4D, 0x1C, 0x59, 0x7B, 0xF1, 0xEA, + 0xE1, 0x34, 0x74, 0xB4, 0x29, 0x0E, 0x89, 0xB2 + }, + { + 0x08, 0xBF, 0x34, 0x6D, 0x38, 0xE1, 0xDF, 0x06, + 0xC8, 0x26, 0x0E, 0xDB, 0x1D, 0xA7, 0x55, 0x79, + 0x27, 0x59, 0x48, 0xD5, 0xC0, 0xA0, 0xAA, 0x9E, + 0xD2, 0x88, 0x6F, 0x88, 0x56, 0xDE, 0x54, 0x17, + 0xA1, 0x56, 0x99, 0x87, 0x58, 0xF5, 0xB1, 0x7E, + 0x52, 0xF1, 0x01, 0xCA, 0x95, 0x7A, 0x71, 0x13, + 0x74, 0x73, 0xDF, 0xD1, 0x8D, 0x7D, 0x20, 0x9C, + 0x4C, 0x10, 0xD9, 0x23, 0x3C, 0x93, 0x69, 0x1D + }, + { + 0x6D, 0xF2, 0x15, 0x6D, 0x77, 0x31, 0x14, 0xD3, + 0x10, 0xB6, 0x3D, 0xB9, 0xEE, 0x53, 0x50, 0xD7, + 0x7E, 0x6B, 0xCF, 0x25, 0xB0, 0x5F, 0xCD, 0x91, + 0x0F, 0x9B, 0x31, 0xBC, 0x42, 0xBB, 0x13, 0xFE, + 0x82, 0x25, 0xEB, 0xCB, 0x2A, 0x23, 0xA6, 0x22, + 0x80, 0x77, 0x7B, 0x6B, 0xF7, 0x4E, 0x2C, 0xD0, + 0x91, 0x7C, 0x76, 0x40, 0xB4, 0x3D, 0xEF, 0xE4, + 0x68, 0xCD, 0x1E, 0x18, 0xC9, 0x43, 0xC6, 0x6A + }, + { + 0x7C, 0x70, 0x38, 0xBC, 0x13, 0xA9, 0x11, 0x51, + 0x82, 0x8A, 0x5B, 0xA8, 0x2B, 0x4A, 0x96, 0x04, + 0x0F, 0x25, 0x8A, 0x4D, 0xFB, 0x1B, 0x13, 0x73, + 0xF0, 0xD3, 0x59, 0x16, 0x8A, 0xFB, 0x05, 0x17, + 0xA2, 0x0B, 0x28, 0xA1, 0x2D, 0x36, 0x44, 0x04, + 0x6B, 0xE6, 0x6B, 0x8D, 0x08, 0xD8, 0xAE, 0x7F, + 0x6A, 0x92, 0x3E, 0xA1, 0xC0, 0x01, 0x87, 0xC6, + 0xD1, 0x1D, 0xC5, 0x02, 0xBA, 0xC7, 0x13, 0x05 + }, + { + 0xBC, 0xD1, 0xB3, 0x0D, 0x80, 0x8F, 0xB7, 0x39, + 0xB9, 0x87, 0xCB, 0xF1, 0x54, 0xBE, 0xA0, 0x0D, + 0xA9, 0xD4, 0x03, 0x80, 0xB8, 0x61, 0xD4, 0xC1, + 0xD6, 0x37, 0x71, 0x22, 0xDA, 0xDD, 0x61, 0xC0, + 0xE5, 0x90, 0x18, 0xB7, 0x19, 0x41, 0xCF, 0xB6, + 0x2E, 0x00, 0xDC, 0xD7, 0x0A, 0xEB, 0x9A, 0xBF, + 0x04, 0x73, 0xE8, 0x0F, 0x0A, 0x7E, 0xCA, 0x6B, + 0x6D, 0xEA, 0x24, 0x6A, 0xB2, 0x29, 0xDD, 0x2B + }, + { + 0x7E, 0xD4, 0x46, 0x8D, 0x96, 0x85, 0x30, 0xFE, + 0x7A, 0xB2, 0xC3, 0x35, 0x40, 0xB2, 0x6D, 0x8C, + 0x3B, 0xD3, 0xED, 0x44, 0xB3, 0x4F, 0xBE, 0x8C, + 0x2A, 0x9D, 0x7F, 0x80, 0x5B, 0x5A, 0xDA, 0x0E, + 0xA2, 0x52, 0xEE, 0xAD, 0xE4, 0xFC, 0xE9, 0x7F, + 0x89, 0x72, 0x8A, 0xD8, 0x5B, 0xC8, 0xBB, 0x24, + 0x30, 0xB1, 0xBE, 0xF2, 0xCD, 0xDD, 0x32, 0xC8, + 0x44, 0x6E, 0x59, 0xB8, 0xE8, 0xBA, 0x3C, 0x67 + }, + { + 0x6D, 0x30, 0xB7, 0xC6, 0xCE, 0x8A, 0x32, 0x36, + 0xC0, 0xCA, 0x2F, 0x8D, 0x72, 0x8B, 0x10, 0x88, + 0xCA, 0x06, 0x98, 0x3A, 0x80, 0x43, 0xE6, 0x21, + 0xD5, 0xDC, 0xF0, 0xC5, 0x37, 0xD1, 0x3B, 0x08, + 0x79, 0x1E, 0xDE, 0xB0, 0x1A, 0x3C, 0xF0, 0x94, + 0x3E, 0xC1, 0xC8, 0x90, 0xAB, 0x6E, 0x29, 0xB1, + 0x46, 0xA2, 0x36, 0xCD, 0x46, 0xBC, 0xB9, 0xD9, + 0x3B, 0xF5, 0x16, 0xFB, 0x67, 0xC6, 0x3F, 0xE5 + }, + { + 0x97, 0xFE, 0x03, 0xCE, 0xF3, 0x14, 0x38, 0x50, + 0x89, 0x11, 0xBD, 0xED, 0x97, 0x59, 0x80, 0xA6, + 0x60, 0x29, 0x30, 0x5D, 0xC5, 0xE3, 0xFA, 0x8A, + 0xD1, 0xB4, 0xFB, 0x22, 0xFC, 0xDF, 0x5A, 0x19, + 0xA7, 0x33, 0x32, 0x03, 0x27, 0xD8, 0xF7, 0x1C, + 0xCF, 0x49, 0x6C, 0xB3, 0xA4, 0x4A, 0x77, 0xAF, + 0x56, 0xE3, 0xDD, 0xE7, 0x3D, 0x3A, 0x5F, 0x17, + 0x68, 0x96, 0xCC, 0x57, 0xC9, 0xA5, 0xAD, 0x99 + }, + { + 0x78, 0x5A, 0x9D, 0x0F, 0xBD, 0x21, 0x13, 0x6D, + 0xBC, 0xE8, 0xFA, 0x7E, 0xAF, 0xD6, 0x3C, 0x9D, + 0xAD, 0x22, 0x00, 0x52, 0x97, 0x84, 0x16, 0xB3, + 0x1D, 0x97, 0x53, 0xEA, 0xA1, 0x49, 0x09, 0x78, + 0x47, 0xED, 0x9B, 0x30, 0xA6, 0x5C, 0x70, 0x50, + 0x7E, 0xFF, 0x01, 0x87, 0x91, 0x49, 0xED, 0x5C, + 0xF0, 0x47, 0x1D, 0x37, 0x79, 0x8E, 0xDC, 0x05, + 0xAB, 0xD5, 0x6A, 0xD4, 0xA2, 0xCC, 0xCB, 0x1D + }, + { + 0xAD, 0x40, 0x8D, 0x2A, 0xBD, 0xDF, 0xD3, 0x7B, + 0x3B, 0xF3, 0x47, 0x94, 0xC1, 0xA3, 0x37, 0x1D, + 0x92, 0x8E, 0xD7, 0xFC, 0x8D, 0x96, 0x62, 0x25, + 0x33, 0x35, 0x84, 0xC5, 0x66, 0x58, 0x17, 0x83, + 0x2A, 0x37, 0xC0, 0x7F, 0x0D, 0xC7, 0xCB, 0x5A, + 0xA8, 0x74, 0xCD, 0x7D, 0x20, 0xFE, 0x8F, 0xAB, + 0x8E, 0xAB, 0xCB, 0x9B, 0x33, 0xD2, 0xE0, 0x84, + 0x1F, 0x6E, 0x20, 0x09, 0x60, 0x89, 0x9D, 0x95 + }, + { + 0x97, 0x66, 0x8F, 0x74, 0x5B, 0x60, 0x32, 0xFC, + 0x81, 0x5D, 0x95, 0x79, 0x32, 0x27, 0x69, 0xDC, + 0xCD, 0x95, 0x01, 0xA5, 0x08, 0x00, 0x29, 0xB8, + 0xAE, 0x82, 0x6B, 0xEF, 0xB6, 0x74, 0x23, 0x31, + 0xBD, 0x9F, 0x76, 0xEF, 0xEB, 0x3E, 0x2B, 0x8E, + 0x81, 0xA9, 0x78, 0x6B, 0x28, 0x2F, 0x50, 0x68, + 0xA3, 0xA2, 0x42, 0x46, 0x97, 0xA7, 0x7C, 0x41, + 0x87, 0x6B, 0x7E, 0x75, 0x3F, 0x4C, 0x77, 0x67 + }, + { + 0x26, 0xBB, 0x98, 0x5F, 0x47, 0xE7, 0xFE, 0xE0, + 0xCF, 0xD2, 0x52, 0xD4, 0xEF, 0x96, 0xBE, 0xD4, + 0x2B, 0x9C, 0x37, 0x0C, 0x1C, 0x6A, 0x3E, 0x8C, + 0x9E, 0xB0, 0x4E, 0xF7, 0xF7, 0x81, 0x8B, 0x83, + 0x3A, 0x0D, 0x1F, 0x04, 0x3E, 0xBA, 0xFB, 0x91, + 0x1D, 0xC7, 0x79, 0xE0, 0x27, 0x40, 0xA0, 0x2A, + 0x44, 0xD3, 0xA1, 0xEA, 0x45, 0xED, 0x4A, 0xD5, + 0x5E, 0x68, 0x6C, 0x92, 0x7C, 0xAF, 0xE9, 0x7E + }, + { + 0x5B, 0xFE, 0x2B, 0x1D, 0xCF, 0x7F, 0xE9, 0xB9, + 0x50, 0x88, 0xAC, 0xED, 0xB5, 0x75, 0xC1, 0x90, + 0x16, 0xC7, 0x43, 0xB2, 0xE7, 0x63, 0xBF, 0x58, + 0x51, 0xAC, 0x40, 0x7C, 0x9E, 0xDA, 0x43, 0x71, + 0x5E, 0xDF, 0xA4, 0x8B, 0x48, 0x25, 0x49, 0x2C, + 0x51, 0x79, 0x59, 0x3F, 0xFF, 0x21, 0x35, 0x1B, + 0x76, 0xE8, 0xB7, 0xE0, 0x34, 0xE4, 0xC5, 0x3C, + 0x79, 0xF6, 0x1F, 0x29, 0xC4, 0x79, 0xBD, 0x08 + }, + { + 0xC7, 0x65, 0x09, 0xEF, 0x72, 0xF4, 0xA6, 0xF9, + 0xC9, 0xC4, 0x06, 0x18, 0xED, 0x52, 0xB2, 0x08, + 0x4F, 0x83, 0x50, 0x22, 0x32, 0xE0, 0xAC, 0x8B, + 0xDA, 0xF3, 0x26, 0x43, 0x68, 0xE4, 0xD0, 0x18, + 0x0F, 0x68, 0x54, 0xC4, 0xAB, 0xF4, 0xF6, 0x50, + 0x9C, 0x79, 0xCA, 0xAF, 0xC4, 0x4C, 0xF3, 0x19, + 0x4A, 0xFC, 0x57, 0xBD, 0x07, 0x7B, 0xD7, 0xB3, + 0xC9, 0xBD, 0xA3, 0xD4, 0xB8, 0x77, 0x58, 0x16 + }, + { + 0xD6, 0x6F, 0x2B, 0xEA, 0xB9, 0x90, 0xE3, 0x54, + 0xCC, 0xB9, 0x10, 0xE4, 0xE9, 0xC7, 0xAC, 0x61, + 0x8C, 0x7B, 0x63, 0xEF, 0x29, 0x2A, 0x96, 0xB5, + 0x52, 0x34, 0x1D, 0xE7, 0x8D, 0xC4, 0x6D, 0x3E, + 0xC8, 0xCF, 0xAB, 0xC6, 0x99, 0xB5, 0x0A, 0xF4, + 0x1F, 0xDA, 0x39, 0xCF, 0x1B, 0x01, 0x73, 0x66, + 0x09, 0x23, 0x51, 0x0A, 0xD6, 0x7F, 0xAE, 0xDE, + 0xF5, 0x20, 0x7C, 0xFF, 0xE8, 0x64, 0x1D, 0x20 + }, + { + 0x7D, 0x8F, 0x06, 0x72, 0x99, 0x2B, 0x79, 0xBE, + 0x3A, 0x36, 0x4D, 0x8E, 0x59, 0x04, 0xF4, 0xAB, + 0x71, 0x3B, 0xBC, 0x8A, 0xB0, 0x1B, 0x4F, 0x30, + 0x9A, 0xD8, 0xCC, 0xF2, 0x23, 0xCE, 0x10, 0x34, + 0xA8, 0x60, 0xDC, 0xB0, 0xB0, 0x05, 0x50, 0x61, + 0x2C, 0xC2, 0xFA, 0x17, 0xF2, 0x96, 0x9E, 0x18, + 0xF2, 0x2E, 0x14, 0x27, 0xD2, 0x54, 0xB4, 0xA8, + 0x2B, 0x3A, 0x03, 0xA3, 0xEB, 0x39, 0x4A, 0xDF + }, + { + 0xA5, 0x6D, 0x67, 0x25, 0xBF, 0xB3, 0xDE, 0x47, + 0xC1, 0x41, 0x4A, 0xDF, 0x25, 0xFC, 0x8F, 0x0F, + 0xC9, 0x84, 0x6F, 0x69, 0x87, 0x72, 0x2B, 0xC0, + 0x63, 0x66, 0xD5, 0xCA, 0x4E, 0x89, 0x72, 0x29, + 0x25, 0xEB, 0xBC, 0x88, 0x14, 0x18, 0x84, 0x40, + 0x75, 0x39, 0x7A, 0x0C, 0xA8, 0x98, 0x42, 0xC7, + 0xB9, 0xE9, 0xE0, 0x7E, 0x1D, 0x9D, 0x18, 0x3E, + 0xBE, 0xB3, 0x9E, 0x12, 0x0B, 0x48, 0x3B, 0xF7 + }, + { + 0xAF, 0x5E, 0x03, 0xD7, 0xFE, 0x60, 0xC6, 0x7E, + 0x10, 0x31, 0x33, 0x44, 0x43, 0x4E, 0x79, 0x48, + 0x5A, 0x03, 0xA7, 0x58, 0xD6, 0xDC, 0xE9, 0x85, + 0x57, 0x47, 0x45, 0x76, 0x3C, 0x1C, 0x5C, 0x77, + 0xD4, 0xFB, 0x3E, 0x6F, 0xB1, 0x22, 0x30, 0x36, + 0x83, 0x70, 0x99, 0x3B, 0xF9, 0x0F, 0xEE, 0xD0, + 0xC5, 0xD1, 0x60, 0x75, 0x24, 0x56, 0x2D, 0x7C, + 0x09, 0xC0, 0xC2, 0x10, 0xED, 0x39, 0x3D, 0x7C + }, + { + 0x7A, 0x20, 0x54, 0x0C, 0xC0, 0x7B, 0xF7, 0x2B, + 0x58, 0x24, 0x21, 0xFC, 0x34, 0x2E, 0x82, 0xF5, + 0x21, 0x34, 0xB6, 0x98, 0x41, 0xEC, 0x28, 0xED, + 0x18, 0x9E, 0x2E, 0xA6, 0xA2, 0x9D, 0xD2, 0xF8, + 0x2A, 0x64, 0x03, 0x52, 0xD2, 0x22, 0xB5, 0x2F, + 0x29, 0x11, 0xDC, 0x72, 0xA7, 0xDA, 0xB3, 0x1C, + 0xAA, 0xDD, 0x80, 0xC6, 0x11, 0x8F, 0x13, 0xC5, + 0x6B, 0x2A, 0x1E, 0x43, 0x73, 0xBE, 0x0E, 0xA3 + }, + { + 0x48, 0x6F, 0x02, 0xC6, 0x3E, 0x54, 0x67, 0xEA, + 0x1F, 0xDD, 0xE7, 0xE8, 0x2B, 0xFA, 0xCC, 0x2C, + 0x1B, 0xA5, 0xD6, 0x36, 0xD9, 0xF3, 0xD0, 0x8B, + 0x21, 0x0D, 0xA3, 0xF3, 0x72, 0xF7, 0x06, 0xEC, + 0x21, 0x8C, 0xC1, 0x7F, 0xF6, 0x0A, 0xEF, 0x70, + 0x3B, 0xBE, 0x0C, 0x15, 0xC3, 0x8A, 0xE5, 0x5D, + 0x28, 0x6A, 0x68, 0x4F, 0x86, 0x4C, 0x78, 0x21, + 0x1C, 0xCA, 0xB4, 0x17, 0x8C, 0x92, 0xAD, 0xBA + }, + { + 0x1C, 0x7A, 0x5C, 0x1D, 0xED, 0xCD, 0x04, 0xA9, + 0x21, 0x78, 0x8F, 0x7E, 0xB2, 0x33, 0x61, 0xCA, + 0x19, 0x53, 0xB0, 0x4B, 0x9C, 0x7A, 0xEC, 0x35, + 0xD6, 0x5E, 0xA3, 0xE4, 0x99, 0x6D, 0xB2, 0x6F, + 0x28, 0x12, 0x78, 0xEA, 0x4A, 0xE6, 0x66, 0xAD, + 0x81, 0x02, 0x7D, 0x98, 0xAF, 0x57, 0x26, 0x2C, + 0xDB, 0xFA, 0x4C, 0x08, 0x5F, 0x42, 0x10, 0x56, + 0x8C, 0x7E, 0x15, 0xEE, 0xC7, 0x80, 0x51, 0x14 + }, + { + 0x9C, 0xE3, 0xFA, 0x9A, 0x86, 0x0B, 0xDB, 0xD5, + 0x37, 0x8F, 0xD6, 0xD7, 0xB8, 0xB6, 0x71, 0xC6, + 0xCB, 0x76, 0x92, 0x91, 0x0C, 0xE8, 0xF9, 0xB6, + 0xCB, 0x41, 0x22, 0xCB, 0xCB, 0xE6, 0xAC, 0x06, + 0xCA, 0x04, 0x22, 0xCE, 0xF1, 0x22, 0x59, 0x35, + 0x05, 0x3B, 0x7D, 0x19, 0x3A, 0x81, 0xB9, 0xE9, + 0x72, 0xEB, 0x85, 0xA1, 0xD3, 0x07, 0x4F, 0x14, + 0xCB, 0xB5, 0xEC, 0x9F, 0x05, 0x73, 0x89, 0x2D + }, + { + 0xA9, 0x11, 0x87, 0xBE, 0x5C, 0x37, 0x1C, 0x42, + 0x65, 0xC1, 0x74, 0xFD, 0x46, 0x53, 0xB8, 0xAB, + 0x70, 0x85, 0x51, 0xF8, 0x3D, 0x1F, 0xEE, 0x1C, + 0xC1, 0x47, 0x95, 0x81, 0xBC, 0x00, 0x6D, 0x6F, + 0xB7, 0x8F, 0xCC, 0x9A, 0x5D, 0xEE, 0x1D, 0xB3, + 0x66, 0x6F, 0x50, 0x8F, 0x97, 0x80, 0xA3, 0x75, + 0x93, 0xEB, 0xCC, 0xCF, 0x5F, 0xBE, 0xD3, 0x96, + 0x67, 0xDC, 0x63, 0x61, 0xE9, 0x21, 0xF7, 0x79 + }, + { + 0x46, 0x25, 0x76, 0x7D, 0x7B, 0x1D, 0x3D, 0x3E, + 0xD2, 0xFB, 0xC6, 0x74, 0xAF, 0x14, 0xE0, 0x24, + 0x41, 0x52, 0xF2, 0xA4, 0x02, 0x1F, 0xCF, 0x33, + 0x11, 0x50, 0x5D, 0x89, 0xBD, 0x81, 0xE2, 0xF9, + 0xF9, 0xA5, 0x00, 0xC3, 0xB1, 0x99, 0x91, 0x4D, + 0xB4, 0x95, 0x00, 0xB3, 0xC9, 0x8D, 0x03, 0xEA, + 0x93, 0x28, 0x67, 0x51, 0xA6, 0x86, 0xA3, 0xB8, + 0x75, 0xDA, 0xAB, 0x0C, 0xCD, 0x63, 0xB4, 0x4F + }, + { + 0x43, 0xDF, 0xDF, 0xE1, 0xB0, 0x14, 0xFE, 0xD3, + 0xA2, 0xAC, 0xAB, 0xB7, 0xF3, 0xE9, 0xA1, 0x82, + 0xF2, 0xAA, 0x18, 0x01, 0x9D, 0x27, 0xE3, 0xE6, + 0xCD, 0xCF, 0x31, 0xA1, 0x5B, 0x42, 0x8E, 0x91, + 0xE7, 0xB0, 0x8C, 0xF5, 0xE5, 0xC3, 0x76, 0xFC, + 0xE2, 0xD8, 0xA2, 0x8F, 0xF8, 0x5A, 0xB0, 0xA0, + 0xA1, 0x65, 0x6E, 0xDB, 0x4A, 0x0A, 0x91, 0x53, + 0x26, 0x20, 0x09, 0x6D, 0x9A, 0x5A, 0x65, 0x2D + }, + { + 0x27, 0x9E, 0x32, 0x02, 0xBE, 0x39, 0x89, 0xBA, + 0x31, 0x12, 0x77, 0x25, 0x85, 0x17, 0x74, 0x87, + 0xE4, 0xFE, 0x3E, 0xE3, 0xEA, 0xB4, 0x9C, 0x2F, + 0x7F, 0xA7, 0xFE, 0x87, 0xCF, 0xE7, 0xB8, 0x0D, + 0x3E, 0x03, 0x55, 0xED, 0xFF, 0x6D, 0x03, 0x1E, + 0x6C, 0x96, 0xC7, 0x95, 0xDB, 0x1C, 0x6F, 0x04, + 0x18, 0x80, 0xEC, 0x38, 0x24, 0xDE, 0xFA, 0xCF, + 0x92, 0x63, 0x82, 0x0A, 0x8E, 0x73, 0x27, 0xDE + }, + { + 0xEA, 0x2D, 0x06, 0x6A, 0xC2, 0x29, 0xD4, 0xD4, + 0xB6, 0x16, 0xA8, 0xBE, 0xDE, 0xC7, 0x34, 0x32, + 0x52, 0x24, 0xE4, 0xB4, 0xE5, 0x8F, 0x1A, 0xE6, + 0xDA, 0xD7, 0xE4, 0x0C, 0x2D, 0xA2, 0x91, 0x96, + 0xC3, 0xB1, 0xEA, 0x95, 0x71, 0xDA, 0xCC, 0x81, + 0xE8, 0x73, 0x28, 0xCA, 0xA0, 0x21, 0x1E, 0x09, + 0x02, 0x7B, 0x05, 0x24, 0xAA, 0x3F, 0x4A, 0x84, + 0x99, 0x17, 0xB3, 0x58, 0x67, 0x47, 0xEB, 0xBB + }, + { + 0x49, 0xF0, 0x14, 0xF5, 0xC6, 0x18, 0x22, 0xC8, + 0x99, 0xAB, 0x5C, 0xAE, 0x51, 0xBE, 0x40, 0x44, + 0xA4, 0x49, 0x5E, 0x77, 0x7D, 0xEB, 0x7D, 0xA9, + 0xB6, 0xD8, 0x49, 0x0E, 0xFB, 0xB8, 0x75, 0x30, + 0xAD, 0xF2, 0x93, 0xDA, 0xF0, 0x79, 0xF9, 0x4C, + 0x33, 0xB7, 0x04, 0x4E, 0xF6, 0x2E, 0x2E, 0x5B, + 0xB3, 0xEB, 0x11, 0xE1, 0x73, 0x04, 0xF8, 0x45, + 0x3E, 0xE6, 0xCE, 0x24, 0xF0, 0x33, 0xDD, 0xB0 + }, + { + 0x92, 0x33, 0x49, 0x03, 0x44, 0xE5, 0xB0, 0xDC, + 0x59, 0x12, 0x67, 0x1B, 0x7A, 0xE5, 0x4C, 0xEE, + 0x77, 0x30, 0xDB, 0xE1, 0xF4, 0xC7, 0xD9, 0x2A, + 0x4D, 0x3E, 0x3A, 0xAB, 0x50, 0x57, 0x17, 0x08, + 0xDB, 0x51, 0xDC, 0xF9, 0xC2, 0x94, 0x45, 0x91, + 0xDB, 0x65, 0x1D, 0xB3, 0x2D, 0x22, 0x93, 0x5B, + 0x86, 0x94, 0x49, 0x69, 0xBE, 0x77, 0xD5, 0xB5, + 0xFE, 0xAE, 0x6C, 0x38, 0x40, 0xA8, 0xDB, 0x26 + }, + { + 0xB6, 0xE7, 0x5E, 0x6F, 0x4C, 0x7F, 0x45, 0x3B, + 0x74, 0x65, 0xD2, 0x5B, 0x5A, 0xC8, 0xC7, 0x19, + 0x69, 0x02, 0xEA, 0xA9, 0x53, 0x87, 0x52, 0x28, + 0xC8, 0x63, 0x4E, 0x16, 0xE2, 0xAE, 0x1F, 0x38, + 0xBC, 0x32, 0x75, 0x30, 0x43, 0x35, 0xF5, 0x98, + 0x9E, 0xCC, 0xC1, 0xE3, 0x41, 0x67, 0xD4, 0xE6, + 0x8D, 0x77, 0x19, 0x96, 0x8F, 0xBA, 0x8E, 0x2F, + 0xE6, 0x79, 0x47, 0xC3, 0x5C, 0x48, 0xE8, 0x06 + }, + { + 0xCC, 0x14, 0xCA, 0x66, 0x5A, 0xF1, 0x48, 0x3E, + 0xFB, 0xC3, 0xAF, 0x80, 0x08, 0x0E, 0x65, 0x0D, + 0x50, 0x46, 0xA3, 0x93, 0x2F, 0x4F, 0x51, 0xF3, + 0xFE, 0x90, 0xA0, 0x70, 0x5E, 0xC2, 0x51, 0x04, + 0xAD, 0xF0, 0x78, 0x39, 0x26, 0x5D, 0xC5, 0x1D, + 0x43, 0x40, 0x14, 0x11, 0x24, 0x6E, 0x47, 0x4F, + 0x0D, 0x5E, 0x56, 0x37, 0xAF, 0x94, 0x76, 0x72, + 0x83, 0xD5, 0x3E, 0x06, 0x17, 0xE9, 0x81, 0xF4 + }, + { + 0x23, 0x0A, 0x1C, 0x85, 0x7C, 0xB2, 0xE7, 0x85, + 0x2E, 0x41, 0xB6, 0x47, 0xE9, 0x0E, 0x45, 0x85, + 0xD2, 0xD8, 0x81, 0xE1, 0x73, 0x4D, 0xC3, 0x89, + 0x55, 0x35, 0x6E, 0x8D, 0xD7, 0xBF, 0xF3, 0x90, + 0x53, 0x09, 0x2C, 0x6B, 0x38, 0xE2, 0x36, 0xE1, + 0x89, 0x95, 0x25, 0x64, 0x70, 0x73, 0xDD, 0xDF, + 0x68, 0x95, 0xD6, 0x42, 0x06, 0x32, 0x5E, 0x76, + 0x47, 0xF2, 0x75, 0x56, 0x7B, 0x25, 0x59, 0x09 + }, + { + 0xCB, 0xB6, 0x53, 0x21, 0xAC, 0x43, 0x6E, 0x2F, + 0xFD, 0xAB, 0x29, 0x36, 0x35, 0x9C, 0xE4, 0x90, + 0x23, 0xF7, 0xDE, 0xE7, 0x61, 0x4E, 0xF2, 0x8D, + 0x17, 0x3C, 0x3D, 0x27, 0xC5, 0xD1, 0xBF, 0xFA, + 0x51, 0x55, 0x3D, 0x43, 0x3F, 0x8E, 0xE3, 0xC9, + 0xE4, 0x9C, 0x05, 0xA2, 0xB8, 0x83, 0xCC, 0xE9, + 0x54, 0xC9, 0xA8, 0x09, 0x3B, 0x80, 0x61, 0x2A, + 0x0C, 0xDD, 0x47, 0x32, 0xE0, 0x41, 0xF9, 0x95 + }, + { + 0x3E, 0x7E, 0x57, 0x00, 0x74, 0x33, 0x72, 0x75, + 0xEF, 0xB5, 0x13, 0x15, 0x58, 0x80, 0x34, 0xC3, + 0xCF, 0x0D, 0xDD, 0xCA, 0x20, 0xB4, 0x61, 0x2E, + 0x0B, 0xD5, 0xB8, 0x81, 0xE7, 0xE5, 0x47, 0x6D, + 0x31, 0x9C, 0xE4, 0xFE, 0x9F, 0x19, 0x18, 0x6E, + 0x4C, 0x08, 0x26, 0xF4, 0x4F, 0x13, 0x1E, 0xB0, + 0x48, 0xE6, 0x5B, 0xE2, 0x42, 0xB1, 0x17, 0x2C, + 0x63, 0xBA, 0xDB, 0x12, 0x3A, 0xB0, 0xCB, 0xE8 + }, + { + 0xD3, 0x2E, 0x9E, 0xC0, 0x2D, 0x38, 0xD4, 0xE1, + 0xB8, 0x24, 0x9D, 0xF8, 0xDC, 0xB0, 0x0C, 0x5B, + 0x9C, 0x68, 0xEB, 0x89, 0x22, 0x67, 0x2E, 0x35, + 0x05, 0x39, 0x3B, 0x6A, 0x21, 0x0B, 0xA5, 0x6F, + 0x94, 0x96, 0xE5, 0xEE, 0x04, 0x90, 0xEF, 0x38, + 0x7C, 0x3C, 0xDE, 0xC0, 0x61, 0xF0, 0x6B, 0xC0, + 0x38, 0x2D, 0x93, 0x04, 0xCA, 0xFB, 0xB8, 0xE0, + 0xCD, 0x33, 0xD5, 0x70, 0x29, 0xE6, 0x2D, 0xF2 + }, + { + 0x8C, 0x15, 0x12, 0x46, 0x60, 0x89, 0xF0, 0x5B, + 0x37, 0x75, 0xC2, 0x62, 0xB6, 0x2D, 0x22, 0xB8, + 0x38, 0x54, 0xA8, 0x32, 0x18, 0x13, 0x0B, 0x4E, + 0xC9, 0x1B, 0x3C, 0xCB, 0xD2, 0x93, 0xD2, 0xA5, + 0x43, 0x02, 0xCE, 0xCA, 0xAB, 0x9B, 0x10, 0x0C, + 0x68, 0xD1, 0xE6, 0xDD, 0xC8, 0xF0, 0x7C, 0xDD, + 0xBD, 0xFE, 0x6F, 0xDA, 0xAA, 0xF0, 0x99, 0xCC, + 0x09, 0xD6, 0xB7, 0x25, 0x87, 0x9C, 0x63, 0x69 + }, + { + 0x91, 0xA7, 0xF6, 0x1C, 0x97, 0xC2, 0x91, 0x1E, + 0x4C, 0x81, 0x2E, 0xF7, 0x1D, 0x78, 0x0A, 0xD8, + 0xFA, 0x78, 0x87, 0x94, 0x56, 0x1D, 0x08, 0x30, + 0x3F, 0xD1, 0xC1, 0xCB, 0x60, 0x8A, 0x46, 0xA1, + 0x25, 0x63, 0x08, 0x6E, 0xC5, 0xB3, 0x9D, 0x47, + 0x1A, 0xED, 0x94, 0xFB, 0x0F, 0x6C, 0x67, 0x8A, + 0x43, 0xB8, 0x79, 0x29, 0x32, 0xF9, 0x02, 0x8D, + 0x77, 0x2A, 0x22, 0x76, 0x8E, 0xA2, 0x3A, 0x9B + }, + { + 0x4F, 0x6B, 0xB2, 0x22, 0xA3, 0x95, 0xE8, 0xB1, + 0x8F, 0x6B, 0xA1, 0x55, 0x47, 0x7A, 0xED, 0x3F, + 0x07, 0x29, 0xAC, 0x9E, 0x83, 0xE1, 0x6D, 0x31, + 0xA2, 0xA8, 0xBC, 0x65, 0x54, 0x22, 0xB8, 0x37, + 0xC8, 0x91, 0xC6, 0x19, 0x9E, 0x6F, 0x0D, 0x75, + 0x79, 0x9E, 0x3B, 0x69, 0x15, 0x25, 0xC5, 0x81, + 0x95, 0x35, 0x17, 0xF2, 0x52, 0xC4, 0xB9, 0xE3, + 0xA2, 0x7A, 0x28, 0xFB, 0xAF, 0x49, 0x64, 0x4C + }, + { + 0x5D, 0x06, 0xC0, 0x7E, 0x7A, 0x64, 0x6C, 0x41, + 0x3A, 0x50, 0x1C, 0x3F, 0x4B, 0xB2, 0xFC, 0x38, + 0x12, 0x7D, 0xE7, 0x50, 0x9B, 0x70, 0x77, 0xC4, + 0xD9, 0xB5, 0x61, 0x32, 0x01, 0xC1, 0xAA, 0x02, + 0xFD, 0x5F, 0x79, 0xD2, 0x74, 0x59, 0x15, 0xDD, + 0x57, 0xFB, 0xCB, 0x4C, 0xE0, 0x86, 0x95, 0xF6, + 0xEF, 0xC0, 0xCB, 0x3D, 0x2D, 0x33, 0x0E, 0x19, + 0xB4, 0xB0, 0xE6, 0x00, 0x4E, 0xA6, 0x47, 0x1E + }, + { + 0xB9, 0x67, 0x56, 0xE5, 0x79, 0x09, 0x96, 0x8F, + 0x14, 0xB7, 0x96, 0xA5, 0xD3, 0x0F, 0x4C, 0x9D, + 0x67, 0x14, 0x72, 0xCF, 0x82, 0xC8, 0xCF, 0xB2, + 0xCA, 0xCA, 0x7A, 0xC7, 0xA4, 0x4C, 0xA0, 0xA1, + 0x4C, 0x98, 0x42, 0xD0, 0x0C, 0x82, 0xE3, 0x37, + 0x50, 0x2C, 0x94, 0xD5, 0x96, 0x0A, 0xCA, 0x4C, + 0x49, 0x2E, 0xA7, 0xB0, 0xDF, 0x91, 0x9D, 0xDF, + 0x1A, 0xAD, 0xA2, 0xA2, 0x75, 0xBB, 0x10, 0xD4 + }, + { + 0xFF, 0x0A, 0x01, 0x5E, 0x98, 0xDB, 0x9C, 0x99, + 0xF0, 0x39, 0x77, 0x71, 0x0A, 0xAC, 0x3E, 0x65, + 0x8C, 0x0D, 0x89, 0x6F, 0x6D, 0x71, 0xD6, 0x18, + 0xBA, 0x79, 0xDC, 0x6C, 0xF7, 0x2A, 0xC7, 0x5B, + 0x7C, 0x03, 0x8E, 0xB6, 0x86, 0x2D, 0xED, 0xE4, + 0x54, 0x3E, 0x14, 0x54, 0x13, 0xA6, 0x36, 0x8D, + 0x69, 0xF5, 0x72, 0x2C, 0x82, 0x7B, 0xA3, 0xEF, + 0x25, 0xB6, 0xAE, 0x64, 0x40, 0xD3, 0x92, 0x76 + }, + { + 0x5B, 0x21, 0xC5, 0xFD, 0x88, 0x68, 0x36, 0x76, + 0x12, 0x47, 0x4F, 0xA2, 0xE7, 0x0E, 0x9C, 0xFA, + 0x22, 0x01, 0xFF, 0xEE, 0xE8, 0xFA, 0xFA, 0xB5, + 0x79, 0x7A, 0xD5, 0x8F, 0xEF, 0xA1, 0x7C, 0x9B, + 0x5B, 0x10, 0x7D, 0xA4, 0xA3, 0xDB, 0x63, 0x20, + 0xBA, 0xAF, 0x2C, 0x86, 0x17, 0xD5, 0xA5, 0x1D, + 0xF9, 0x14, 0xAE, 0x88, 0xDA, 0x38, 0x67, 0xC2, + 0xD4, 0x1F, 0x0C, 0xC1, 0x4F, 0xA6, 0x79, 0x28 + }, +}; + + + + +static const uint8_t blake2b_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0x10, 0xEB, 0xB6, 0x77, 0x00, 0xB1, 0x86, 0x8E, + 0xFB, 0x44, 0x17, 0x98, 0x7A, 0xCF, 0x46, 0x90, + 0xAE, 0x9D, 0x97, 0x2F, 0xB7, 0xA5, 0x90, 0xC2, + 0xF0, 0x28, 0x71, 0x79, 0x9A, 0xAA, 0x47, 0x86, + 0xB5, 0xE9, 0x96, 0xE8, 0xF0, 0xF4, 0xEB, 0x98, + 0x1F, 0xC2, 0x14, 0xB0, 0x05, 0xF4, 0x2D, 0x2F, + 0xF4, 0x23, 0x34, 0x99, 0x39, 0x16, 0x53, 0xDF, + 0x7A, 0xEF, 0xCB, 0xC1, 0x3F, 0xC5, 0x15, 0x68 + }, + { + 0x96, 0x1F, 0x6D, 0xD1, 0xE4, 0xDD, 0x30, 0xF6, + 0x39, 0x01, 0x69, 0x0C, 0x51, 0x2E, 0x78, 0xE4, + 0xB4, 0x5E, 0x47, 0x42, 0xED, 0x19, 0x7C, 0x3C, + 0x5E, 0x45, 0xC5, 0x49, 0xFD, 0x25, 0xF2, 0xE4, + 0x18, 0x7B, 0x0B, 0xC9, 0xFE, 0x30, 0x49, 0x2B, + 0x16, 0xB0, 0xD0, 0xBC, 0x4E, 0xF9, 0xB0, 0xF3, + 0x4C, 0x70, 0x03, 0xFA, 0xC0, 0x9A, 0x5E, 0xF1, + 0x53, 0x2E, 0x69, 0x43, 0x02, 0x34, 0xCE, 0xBD + }, + { + 0xDA, 0x2C, 0xFB, 0xE2, 0xD8, 0x40, 0x9A, 0x0F, + 0x38, 0x02, 0x61, 0x13, 0x88, 0x4F, 0x84, 0xB5, + 0x01, 0x56, 0x37, 0x1A, 0xE3, 0x04, 0xC4, 0x43, + 0x01, 0x73, 0xD0, 0x8A, 0x99, 0xD9, 0xFB, 0x1B, + 0x98, 0x31, 0x64, 0xA3, 0x77, 0x07, 0x06, 0xD5, + 0x37, 0xF4, 0x9E, 0x0C, 0x91, 0x6D, 0x9F, 0x32, + 0xB9, 0x5C, 0xC3, 0x7A, 0x95, 0xB9, 0x9D, 0x85, + 0x74, 0x36, 0xF0, 0x23, 0x2C, 0x88, 0xA9, 0x65 + }, + { + 0x33, 0xD0, 0x82, 0x5D, 0xDD, 0xF7, 0xAD, 0xA9, + 0x9B, 0x0E, 0x7E, 0x30, 0x71, 0x04, 0xAD, 0x07, + 0xCA, 0x9C, 0xFD, 0x96, 0x92, 0x21, 0x4F, 0x15, + 0x61, 0x35, 0x63, 0x15, 0xE7, 0x84, 0xF3, 0xE5, + 0xA1, 0x7E, 0x36, 0x4A, 0xE9, 0xDB, 0xB1, 0x4C, + 0xB2, 0x03, 0x6D, 0xF9, 0x32, 0xB7, 0x7F, 0x4B, + 0x29, 0x27, 0x61, 0x36, 0x5F, 0xB3, 0x28, 0xDE, + 0x7A, 0xFD, 0xC6, 0xD8, 0x99, 0x8F, 0x5F, 0xC1 + }, + { + 0xBE, 0xAA, 0x5A, 0x3D, 0x08, 0xF3, 0x80, 0x71, + 0x43, 0xCF, 0x62, 0x1D, 0x95, 0xCD, 0x69, 0x05, + 0x14, 0xD0, 0xB4, 0x9E, 0xFF, 0xF9, 0xC9, 0x1D, + 0x24, 0xB5, 0x92, 0x41, 0xEC, 0x0E, 0xEF, 0xA5, + 0xF6, 0x01, 0x96, 0xD4, 0x07, 0x04, 0x8B, 0xBA, + 0x8D, 0x21, 0x46, 0x82, 0x8E, 0xBC, 0xB0, 0x48, + 0x8D, 0x88, 0x42, 0xFD, 0x56, 0xBB, 0x4F, 0x6D, + 0xF8, 0xE1, 0x9C, 0x4B, 0x4D, 0xAA, 0xB8, 0xAC + }, + { + 0x09, 0x80, 0x84, 0xB5, 0x1F, 0xD1, 0x3D, 0xEA, + 0xE5, 0xF4, 0x32, 0x0D, 0xE9, 0x4A, 0x68, 0x8E, + 0xE0, 0x7B, 0xAE, 0xA2, 0x80, 0x04, 0x86, 0x68, + 0x9A, 0x86, 0x36, 0x11, 0x7B, 0x46, 0xC1, 0xF4, + 0xC1, 0xF6, 0xAF, 0x7F, 0x74, 0xAE, 0x7C, 0x85, + 0x76, 0x00, 0x45, 0x6A, 0x58, 0xA3, 0xAF, 0x25, + 0x1D, 0xC4, 0x72, 0x3A, 0x64, 0xCC, 0x7C, 0x0A, + 0x5A, 0xB6, 0xD9, 0xCA, 0xC9, 0x1C, 0x20, 0xBB + }, + { + 0x60, 0x44, 0x54, 0x0D, 0x56, 0x08, 0x53, 0xEB, + 0x1C, 0x57, 0xDF, 0x00, 0x77, 0xDD, 0x38, 0x10, + 0x94, 0x78, 0x1C, 0xDB, 0x90, 0x73, 0xE5, 0xB1, + 0xB3, 0xD3, 0xF6, 0xC7, 0x82, 0x9E, 0x12, 0x06, + 0x6B, 0xBA, 0xCA, 0x96, 0xD9, 0x89, 0xA6, 0x90, + 0xDE, 0x72, 0xCA, 0x31, 0x33, 0xA8, 0x36, 0x52, + 0xBA, 0x28, 0x4A, 0x6D, 0x62, 0x94, 0x2B, 0x27, + 0x1F, 0xFA, 0x26, 0x20, 0xC9, 0xE7, 0x5B, 0x1F + }, + { + 0x7A, 0x8C, 0xFE, 0x9B, 0x90, 0xF7, 0x5F, 0x7E, + 0xCB, 0x3A, 0xCC, 0x05, 0x3A, 0xAE, 0xD6, 0x19, + 0x31, 0x12, 0xB6, 0xF6, 0xA4, 0xAE, 0xEB, 0x3F, + 0x65, 0xD3, 0xDE, 0x54, 0x19, 0x42, 0xDE, 0xB9, + 0xE2, 0x22, 0x81, 0x52, 0xA3, 0xC4, 0xBB, 0xBE, + 0x72, 0xFC, 0x3B, 0x12, 0x62, 0x95, 0x28, 0xCF, + 0xBB, 0x09, 0xFE, 0x63, 0x0F, 0x04, 0x74, 0x33, + 0x9F, 0x54, 0xAB, 0xF4, 0x53, 0xE2, 0xED, 0x52 + }, + { + 0x38, 0x0B, 0xEA, 0xF6, 0xEA, 0x7C, 0xC9, 0x36, + 0x5E, 0x27, 0x0E, 0xF0, 0xE6, 0xF3, 0xA6, 0x4F, + 0xB9, 0x02, 0xAC, 0xAE, 0x51, 0xDD, 0x55, 0x12, + 0xF8, 0x42, 0x59, 0xAD, 0x2C, 0x91, 0xF4, 0xBC, + 0x41, 0x08, 0xDB, 0x73, 0x19, 0x2A, 0x5B, 0xBF, + 0xB0, 0xCB, 0xCF, 0x71, 0xE4, 0x6C, 0x3E, 0x21, + 0xAE, 0xE1, 0xC5, 0xE8, 0x60, 0xDC, 0x96, 0xE8, + 0xEB, 0x0B, 0x7B, 0x84, 0x26, 0xE6, 0xAB, 0xE9 + }, + { + 0x60, 0xFE, 0x3C, 0x45, 0x35, 0xE1, 0xB5, 0x9D, + 0x9A, 0x61, 0xEA, 0x85, 0x00, 0xBF, 0xAC, 0x41, + 0xA6, 0x9D, 0xFF, 0xB1, 0xCE, 0xAD, 0xD9, 0xAC, + 0xA3, 0x23, 0xE9, 0xA6, 0x25, 0xB6, 0x4D, 0xA5, + 0x76, 0x3B, 0xAD, 0x72, 0x26, 0xDA, 0x02, 0xB9, + 0xC8, 0xC4, 0xF1, 0xA5, 0xDE, 0x14, 0x0A, 0xC5, + 0xA6, 0xC1, 0x12, 0x4E, 0x4F, 0x71, 0x8C, 0xE0, + 0xB2, 0x8E, 0xA4, 0x73, 0x93, 0xAA, 0x66, 0x37 + }, + { + 0x4F, 0xE1, 0x81, 0xF5, 0x4A, 0xD6, 0x3A, 0x29, + 0x83, 0xFE, 0xAA, 0xF7, 0x7D, 0x1E, 0x72, 0x35, + 0xC2, 0xBE, 0xB1, 0x7F, 0xA3, 0x28, 0xB6, 0xD9, + 0x50, 0x5B, 0xDA, 0x32, 0x7D, 0xF1, 0x9F, 0xC3, + 0x7F, 0x02, 0xC4, 0xB6, 0xF0, 0x36, 0x8C, 0xE2, + 0x31, 0x47, 0x31, 0x3A, 0x8E, 0x57, 0x38, 0xB5, + 0xFA, 0x2A, 0x95, 0xB2, 0x9D, 0xE1, 0xC7, 0xF8, + 0x26, 0x4E, 0xB7, 0x7B, 0x69, 0xF5, 0x85, 0xCD + }, + { + 0xF2, 0x28, 0x77, 0x3C, 0xE3, 0xF3, 0xA4, 0x2B, + 0x5F, 0x14, 0x4D, 0x63, 0x23, 0x7A, 0x72, 0xD9, + 0x96, 0x93, 0xAD, 0xB8, 0x83, 0x7D, 0x0E, 0x11, + 0x2A, 0x8A, 0x0F, 0x8F, 0xFF, 0xF2, 0xC3, 0x62, + 0x85, 0x7A, 0xC4, 0x9C, 0x11, 0xEC, 0x74, 0x0D, + 0x15, 0x00, 0x74, 0x9D, 0xAC, 0x9B, 0x1F, 0x45, + 0x48, 0x10, 0x8B, 0xF3, 0x15, 0x57, 0x94, 0xDC, + 0xC9, 0xE4, 0x08, 0x28, 0x49, 0xE2, 0xB8, 0x5B + }, + { + 0x96, 0x24, 0x52, 0xA8, 0x45, 0x5C, 0xC5, 0x6C, + 0x85, 0x11, 0x31, 0x7E, 0x3B, 0x1F, 0x3B, 0x2C, + 0x37, 0xDF, 0x75, 0xF5, 0x88, 0xE9, 0x43, 0x25, + 0xFD, 0xD7, 0x70, 0x70, 0x35, 0x9C, 0xF6, 0x3A, + 0x9A, 0xE6, 0xE9, 0x30, 0x93, 0x6F, 0xDF, 0x8E, + 0x1E, 0x08, 0xFF, 0xCA, 0x44, 0x0C, 0xFB, 0x72, + 0xC2, 0x8F, 0x06, 0xD8, 0x9A, 0x21, 0x51, 0xD1, + 0xC4, 0x6C, 0xD5, 0xB2, 0x68, 0xEF, 0x85, 0x63 + }, + { + 0x43, 0xD4, 0x4B, 0xFA, 0x18, 0x76, 0x8C, 0x59, + 0x89, 0x6B, 0xF7, 0xED, 0x17, 0x65, 0xCB, 0x2D, + 0x14, 0xAF, 0x8C, 0x26, 0x02, 0x66, 0x03, 0x90, + 0x99, 0xB2, 0x5A, 0x60, 0x3E, 0x4D, 0xDC, 0x50, + 0x39, 0xD6, 0xEF, 0x3A, 0x91, 0x84, 0x7D, 0x10, + 0x88, 0xD4, 0x01, 0xC0, 0xC7, 0xE8, 0x47, 0x78, + 0x1A, 0x8A, 0x59, 0x0D, 0x33, 0xA3, 0xC6, 0xCB, + 0x4D, 0xF0, 0xFA, 0xB1, 0xC2, 0xF2, 0x23, 0x55 + }, + { + 0xDC, 0xFF, 0xA9, 0xD5, 0x8C, 0x2A, 0x4C, 0xA2, + 0xCD, 0xBB, 0x0C, 0x7A, 0xA4, 0xC4, 0xC1, 0xD4, + 0x51, 0x65, 0x19, 0x00, 0x89, 0xF4, 0xE9, 0x83, + 0xBB, 0x1C, 0x2C, 0xAB, 0x4A, 0xAE, 0xFF, 0x1F, + 0xA2, 0xB5, 0xEE, 0x51, 0x6F, 0xEC, 0xD7, 0x80, + 0x54, 0x02, 0x40, 0xBF, 0x37, 0xE5, 0x6C, 0x8B, + 0xCC, 0xA7, 0xFA, 0xB9, 0x80, 0xE1, 0xE6, 0x1C, + 0x94, 0x00, 0xD8, 0xA9, 0xA5, 0xB1, 0x4A, 0xC6 + }, + { + 0x6F, 0xBF, 0x31, 0xB4, 0x5A, 0xB0, 0xC0, 0xB8, + 0xDA, 0xD1, 0xC0, 0xF5, 0xF4, 0x06, 0x13, 0x79, + 0x91, 0x2D, 0xDE, 0x5A, 0xA9, 0x22, 0x09, 0x9A, + 0x03, 0x0B, 0x72, 0x5C, 0x73, 0x34, 0x6C, 0x52, + 0x42, 0x91, 0xAD, 0xEF, 0x89, 0xD2, 0xF6, 0xFD, + 0x8D, 0xFC, 0xDA, 0x6D, 0x07, 0xDA, 0xD8, 0x11, + 0xA9, 0x31, 0x45, 0x36, 0xC2, 0x91, 0x5E, 0xD4, + 0x5D, 0xA3, 0x49, 0x47, 0xE8, 0x3D, 0xE3, 0x4E + }, + { + 0xA0, 0xC6, 0x5B, 0xDD, 0xDE, 0x8A, 0xDE, 0xF5, + 0x72, 0x82, 0xB0, 0x4B, 0x11, 0xE7, 0xBC, 0x8A, + 0xAB, 0x10, 0x5B, 0x99, 0x23, 0x1B, 0x75, 0x0C, + 0x02, 0x1F, 0x4A, 0x73, 0x5C, 0xB1, 0xBC, 0xFA, + 0xB8, 0x75, 0x53, 0xBB, 0xA3, 0xAB, 0xB0, 0xC3, + 0xE6, 0x4A, 0x0B, 0x69, 0x55, 0x28, 0x51, 0x85, + 0xA0, 0xBD, 0x35, 0xFB, 0x8C, 0xFD, 0xE5, 0x57, + 0x32, 0x9B, 0xEB, 0xB1, 0xF6, 0x29, 0xEE, 0x93 + }, + { + 0xF9, 0x9D, 0x81, 0x55, 0x50, 0x55, 0x8E, 0x81, + 0xEC, 0xA2, 0xF9, 0x67, 0x18, 0xAE, 0xD1, 0x0D, + 0x86, 0xF3, 0xF1, 0xCF, 0xB6, 0x75, 0xCC, 0xE0, + 0x6B, 0x0E, 0xFF, 0x02, 0xF6, 0x17, 0xC5, 0xA4, + 0x2C, 0x5A, 0xA7, 0x60, 0x27, 0x0F, 0x26, 0x79, + 0xDA, 0x26, 0x77, 0xC5, 0xAE, 0xB9, 0x4F, 0x11, + 0x42, 0x27, 0x7F, 0x21, 0xC7, 0xF7, 0x9F, 0x3C, + 0x4F, 0x0C, 0xCE, 0x4E, 0xD8, 0xEE, 0x62, 0xB1 + }, + { + 0x95, 0x39, 0x1D, 0xA8, 0xFC, 0x7B, 0x91, 0x7A, + 0x20, 0x44, 0xB3, 0xD6, 0xF5, 0x37, 0x4E, 0x1C, + 0xA0, 0x72, 0xB4, 0x14, 0x54, 0xD5, 0x72, 0xC7, + 0x35, 0x6C, 0x05, 0xFD, 0x4B, 0xC1, 0xE0, 0xF4, + 0x0B, 0x8B, 0xB8, 0xB4, 0xA9, 0xF6, 0xBC, 0xE9, + 0xBE, 0x2C, 0x46, 0x23, 0xC3, 0x99, 0xB0, 0xDC, + 0xA0, 0xDA, 0xB0, 0x5C, 0xB7, 0x28, 0x1B, 0x71, + 0xA2, 0x1B, 0x0E, 0xBC, 0xD9, 0xE5, 0x56, 0x70 + }, + { + 0x04, 0xB9, 0xCD, 0x3D, 0x20, 0xD2, 0x21, 0xC0, + 0x9A, 0xC8, 0x69, 0x13, 0xD3, 0xDC, 0x63, 0x04, + 0x19, 0x89, 0xA9, 0xA1, 0xE6, 0x94, 0xF1, 0xE6, + 0x39, 0xA3, 0xBA, 0x7E, 0x45, 0x18, 0x40, 0xF7, + 0x50, 0xC2, 0xFC, 0x19, 0x1D, 0x56, 0xAD, 0x61, + 0xF2, 0xE7, 0x93, 0x6B, 0xC0, 0xAC, 0x8E, 0x09, + 0x4B, 0x60, 0xCA, 0xEE, 0xD8, 0x78, 0xC1, 0x87, + 0x99, 0x04, 0x54, 0x02, 0xD6, 0x1C, 0xEA, 0xF9 + }, + { + 0xEC, 0x0E, 0x0E, 0xF7, 0x07, 0xE4, 0xED, 0x6C, + 0x0C, 0x66, 0xF9, 0xE0, 0x89, 0xE4, 0x95, 0x4B, + 0x05, 0x80, 0x30, 0xD2, 0xDD, 0x86, 0x39, 0x8F, + 0xE8, 0x40, 0x59, 0x63, 0x1F, 0x9E, 0xE5, 0x91, + 0xD9, 0xD7, 0x73, 0x75, 0x35, 0x51, 0x49, 0x17, + 0x8C, 0x0C, 0xF8, 0xF8, 0xE7, 0xC4, 0x9E, 0xD2, + 0xA5, 0xE4, 0xF9, 0x54, 0x88, 0xA2, 0x24, 0x70, + 0x67, 0xC2, 0x08, 0x51, 0x0F, 0xAD, 0xC4, 0x4C + }, + { + 0x9A, 0x37, 0xCC, 0xE2, 0x73, 0xB7, 0x9C, 0x09, + 0x91, 0x36, 0x77, 0x51, 0x0E, 0xAF, 0x76, 0x88, + 0xE8, 0x9B, 0x33, 0x14, 0xD3, 0x53, 0x2F, 0xD2, + 0x76, 0x4C, 0x39, 0xDE, 0x02, 0x2A, 0x29, 0x45, + 0xB5, 0x71, 0x0D, 0x13, 0x51, 0x7A, 0xF8, 0xDD, + 0xC0, 0x31, 0x66, 0x24, 0xE7, 0x3B, 0xEC, 0x1C, + 0xE6, 0x7D, 0xF1, 0x52, 0x28, 0x30, 0x20, 0x36, + 0xF3, 0x30, 0xAB, 0x0C, 0xB4, 0xD2, 0x18, 0xDD + }, + { + 0x4C, 0xF9, 0xBB, 0x8F, 0xB3, 0xD4, 0xDE, 0x8B, + 0x38, 0xB2, 0xF2, 0x62, 0xD3, 0xC4, 0x0F, 0x46, + 0xDF, 0xE7, 0x47, 0xE8, 0xFC, 0x0A, 0x41, 0x4C, + 0x19, 0x3D, 0x9F, 0xCF, 0x75, 0x31, 0x06, 0xCE, + 0x47, 0xA1, 0x8F, 0x17, 0x2F, 0x12, 0xE8, 0xA2, + 0xF1, 0xC2, 0x67, 0x26, 0x54, 0x53, 0x58, 0xE5, + 0xEE, 0x28, 0xC9, 0xE2, 0x21, 0x3A, 0x87, 0x87, + 0xAA, 0xFB, 0xC5, 0x16, 0xD2, 0x34, 0x31, 0x52 + }, + { + 0x64, 0xE0, 0xC6, 0x3A, 0xF9, 0xC8, 0x08, 0xFD, + 0x89, 0x31, 0x37, 0x12, 0x98, 0x67, 0xFD, 0x91, + 0x93, 0x9D, 0x53, 0xF2, 0xAF, 0x04, 0xBE, 0x4F, + 0xA2, 0x68, 0x00, 0x61, 0x00, 0x06, 0x9B, 0x2D, + 0x69, 0xDA, 0xA5, 0xC5, 0xD8, 0xED, 0x7F, 0xDD, + 0xCB, 0x2A, 0x70, 0xEE, 0xEC, 0xDF, 0x2B, 0x10, + 0x5D, 0xD4, 0x6A, 0x1E, 0x3B, 0x73, 0x11, 0x72, + 0x8F, 0x63, 0x9A, 0xB4, 0x89, 0x32, 0x6B, 0xC9 + }, + { + 0x5E, 0x9C, 0x93, 0x15, 0x8D, 0x65, 0x9B, 0x2D, + 0xEF, 0x06, 0xB0, 0xC3, 0xC7, 0x56, 0x50, 0x45, + 0x54, 0x26, 0x62, 0xD6, 0xEE, 0xE8, 0xA9, 0x6A, + 0x89, 0xB7, 0x8A, 0xDE, 0x09, 0xFE, 0x8B, 0x3D, + 0xCC, 0x09, 0x6D, 0x4F, 0xE4, 0x88, 0x15, 0xD8, + 0x8D, 0x8F, 0x82, 0x62, 0x01, 0x56, 0x60, 0x2A, + 0xF5, 0x41, 0x95, 0x5E, 0x1F, 0x6C, 0xA3, 0x0D, + 0xCE, 0x14, 0xE2, 0x54, 0xC3, 0x26, 0xB8, 0x8F + }, + { + 0x77, 0x75, 0xDF, 0xF8, 0x89, 0x45, 0x8D, 0xD1, + 0x1A, 0xEF, 0x41, 0x72, 0x76, 0x85, 0x3E, 0x21, + 0x33, 0x5E, 0xB8, 0x8E, 0x4D, 0xEC, 0x9C, 0xFB, + 0x4E, 0x9E, 0xDB, 0x49, 0x82, 0x00, 0x88, 0x55, + 0x1A, 0x2C, 0xA6, 0x03, 0x39, 0xF1, 0x20, 0x66, + 0x10, 0x11, 0x69, 0xF0, 0xDF, 0xE8, 0x4B, 0x09, + 0x8F, 0xDD, 0xB1, 0x48, 0xD9, 0xDA, 0x6B, 0x3D, + 0x61, 0x3D, 0xF2, 0x63, 0x88, 0x9A, 0xD6, 0x4B + }, + { + 0xF0, 0xD2, 0x80, 0x5A, 0xFB, 0xB9, 0x1F, 0x74, + 0x39, 0x51, 0x35, 0x1A, 0x6D, 0x02, 0x4F, 0x93, + 0x53, 0xA2, 0x3C, 0x7C, 0xE1, 0xFC, 0x2B, 0x05, + 0x1B, 0x3A, 0x8B, 0x96, 0x8C, 0x23, 0x3F, 0x46, + 0xF5, 0x0F, 0x80, 0x6E, 0xCB, 0x15, 0x68, 0xFF, + 0xAA, 0x0B, 0x60, 0x66, 0x1E, 0x33, 0x4B, 0x21, + 0xDD, 0xE0, 0x4F, 0x8F, 0xA1, 0x55, 0xAC, 0x74, + 0x0E, 0xEB, 0x42, 0xE2, 0x0B, 0x60, 0xD7, 0x64 + }, + { + 0x86, 0xA2, 0xAF, 0x31, 0x6E, 0x7D, 0x77, 0x54, + 0x20, 0x1B, 0x94, 0x2E, 0x27, 0x53, 0x64, 0xAC, + 0x12, 0xEA, 0x89, 0x62, 0xAB, 0x5B, 0xD8, 0xD7, + 0xFB, 0x27, 0x6D, 0xC5, 0xFB, 0xFF, 0xC8, 0xF9, + 0xA2, 0x8C, 0xAE, 0x4E, 0x48, 0x67, 0xDF, 0x67, + 0x80, 0xD9, 0xB7, 0x25, 0x24, 0x16, 0x09, 0x27, + 0xC8, 0x55, 0xDA, 0x5B, 0x60, 0x78, 0xE0, 0xB5, + 0x54, 0xAA, 0x91, 0xE3, 0x1C, 0xB9, 0xCA, 0x1D + }, + { + 0x10, 0xBD, 0xF0, 0xCA, 0xA0, 0x80, 0x27, 0x05, + 0xE7, 0x06, 0x36, 0x9B, 0xAF, 0x8A, 0x3F, 0x79, + 0xD7, 0x2C, 0x0A, 0x03, 0xA8, 0x06, 0x75, 0xA7, + 0xBB, 0xB0, 0x0B, 0xE3, 0xA4, 0x5E, 0x51, 0x64, + 0x24, 0xD1, 0xEE, 0x88, 0xEF, 0xB5, 0x6F, 0x6D, + 0x57, 0x77, 0x54, 0x5A, 0xE6, 0xE2, 0x77, 0x65, + 0xC3, 0xA8, 0xF5, 0xE4, 0x93, 0xFC, 0x30, 0x89, + 0x15, 0x63, 0x89, 0x33, 0xA1, 0xDF, 0xEE, 0x55 + }, + { + 0xB0, 0x17, 0x81, 0x09, 0x2B, 0x17, 0x48, 0x45, + 0x9E, 0x2E, 0x4E, 0xC1, 0x78, 0x69, 0x66, 0x27, + 0xBF, 0x4E, 0xBA, 0xFE, 0xBB, 0xA7, 0x74, 0xEC, + 0xF0, 0x18, 0xB7, 0x9A, 0x68, 0xAE, 0xB8, 0x49, + 0x17, 0xBF, 0x0B, 0x84, 0xBB, 0x79, 0xD1, 0x7B, + 0x74, 0x31, 0x51, 0x14, 0x4C, 0xD6, 0x6B, 0x7B, + 0x33, 0xA4, 0xB9, 0xE5, 0x2C, 0x76, 0xC4, 0xE1, + 0x12, 0x05, 0x0F, 0xF5, 0x38, 0x5B, 0x7F, 0x0B + }, + { + 0xC6, 0xDB, 0xC6, 0x1D, 0xEC, 0x6E, 0xAE, 0xAC, + 0x81, 0xE3, 0xD5, 0xF7, 0x55, 0x20, 0x3C, 0x8E, + 0x22, 0x05, 0x51, 0x53, 0x4A, 0x0B, 0x2F, 0xD1, + 0x05, 0xA9, 0x18, 0x89, 0x94, 0x5A, 0x63, 0x85, + 0x50, 0x20, 0x4F, 0x44, 0x09, 0x3D, 0xD9, 0x98, + 0xC0, 0x76, 0x20, 0x5D, 0xFF, 0xAD, 0x70, 0x3A, + 0x0E, 0x5C, 0xD3, 0xC7, 0xF4, 0x38, 0xA7, 0xE6, + 0x34, 0xCD, 0x59, 0xFE, 0xDE, 0xDB, 0x53, 0x9E + }, + { + 0xEB, 0xA5, 0x1A, 0xCF, 0xFB, 0x4C, 0xEA, 0x31, + 0xDB, 0x4B, 0x8D, 0x87, 0xE9, 0xBF, 0x7D, 0xD4, + 0x8F, 0xE9, 0x7B, 0x02, 0x53, 0xAE, 0x67, 0xAA, + 0x58, 0x0F, 0x9A, 0xC4, 0xA9, 0xD9, 0x41, 0xF2, + 0xBE, 0xA5, 0x18, 0xEE, 0x28, 0x68, 0x18, 0xCC, + 0x9F, 0x63, 0x3F, 0x2A, 0x3B, 0x9F, 0xB6, 0x8E, + 0x59, 0x4B, 0x48, 0xCD, 0xD6, 0xD5, 0x15, 0xBF, + 0x1D, 0x52, 0xBA, 0x6C, 0x85, 0xA2, 0x03, 0xA7 + }, + { + 0x86, 0x22, 0x1F, 0x3A, 0xDA, 0x52, 0x03, 0x7B, + 0x72, 0x22, 0x4F, 0x10, 0x5D, 0x79, 0x99, 0x23, + 0x1C, 0x5E, 0x55, 0x34, 0xD0, 0x3D, 0xA9, 0xD9, + 0xC0, 0xA1, 0x2A, 0xCB, 0x68, 0x46, 0x0C, 0xD3, + 0x75, 0xDA, 0xF8, 0xE2, 0x43, 0x86, 0x28, 0x6F, + 0x96, 0x68, 0xF7, 0x23, 0x26, 0xDB, 0xF9, 0x9B, + 0xA0, 0x94, 0x39, 0x24, 0x37, 0xD3, 0x98, 0xE9, + 0x5B, 0xB8, 0x16, 0x1D, 0x71, 0x7F, 0x89, 0x91 + }, + { + 0x55, 0x95, 0xE0, 0x5C, 0x13, 0xA7, 0xEC, 0x4D, + 0xC8, 0xF4, 0x1F, 0xB7, 0x0C, 0xB5, 0x0A, 0x71, + 0xBC, 0xE1, 0x7C, 0x02, 0x4F, 0xF6, 0xDE, 0x7A, + 0xF6, 0x18, 0xD0, 0xCC, 0x4E, 0x9C, 0x32, 0xD9, + 0x57, 0x0D, 0x6D, 0x3E, 0xA4, 0x5B, 0x86, 0x52, + 0x54, 0x91, 0x03, 0x0C, 0x0D, 0x8F, 0x2B, 0x18, + 0x36, 0xD5, 0x77, 0x8C, 0x1C, 0xE7, 0x35, 0xC1, + 0x77, 0x07, 0xDF, 0x36, 0x4D, 0x05, 0x43, 0x47 + }, + { + 0xCE, 0x0F, 0x4F, 0x6A, 0xCA, 0x89, 0x59, 0x0A, + 0x37, 0xFE, 0x03, 0x4D, 0xD7, 0x4D, 0xD5, 0xFA, + 0x65, 0xEB, 0x1C, 0xBD, 0x0A, 0x41, 0x50, 0x8A, + 0xAD, 0xDC, 0x09, 0x35, 0x1A, 0x3C, 0xEA, 0x6D, + 0x18, 0xCB, 0x21, 0x89, 0xC5, 0x4B, 0x70, 0x0C, + 0x00, 0x9F, 0x4C, 0xBF, 0x05, 0x21, 0xC7, 0xEA, + 0x01, 0xBE, 0x61, 0xC5, 0xAE, 0x09, 0xCB, 0x54, + 0xF2, 0x7B, 0xC1, 0xB4, 0x4D, 0x65, 0x8C, 0x82 + }, + { + 0x7E, 0xE8, 0x0B, 0x06, 0xA2, 0x15, 0xA3, 0xBC, + 0xA9, 0x70, 0xC7, 0x7C, 0xDA, 0x87, 0x61, 0x82, + 0x2B, 0xC1, 0x03, 0xD4, 0x4F, 0xA4, 0xB3, 0x3F, + 0x4D, 0x07, 0xDC, 0xB9, 0x97, 0xE3, 0x6D, 0x55, + 0x29, 0x8B, 0xCE, 0xAE, 0x12, 0x24, 0x1B, 0x3F, + 0xA0, 0x7F, 0xA6, 0x3B, 0xE5, 0x57, 0x60, 0x68, + 0xDA, 0x38, 0x7B, 0x8D, 0x58, 0x59, 0xAE, 0xAB, + 0x70, 0x13, 0x69, 0x84, 0x8B, 0x17, 0x6D, 0x42 + }, + { + 0x94, 0x0A, 0x84, 0xB6, 0xA8, 0x4D, 0x10, 0x9A, + 0xAB, 0x20, 0x8C, 0x02, 0x4C, 0x6C, 0xE9, 0x64, + 0x76, 0x76, 0xBA, 0x0A, 0xAA, 0x11, 0xF8, 0x6D, + 0xBB, 0x70, 0x18, 0xF9, 0xFD, 0x22, 0x20, 0xA6, + 0xD9, 0x01, 0xA9, 0x02, 0x7F, 0x9A, 0xBC, 0xF9, + 0x35, 0x37, 0x27, 0x27, 0xCB, 0xF0, 0x9E, 0xBD, + 0x61, 0xA2, 0xA2, 0xEE, 0xB8, 0x76, 0x53, 0xE8, + 0xEC, 0xAD, 0x1B, 0xAB, 0x85, 0xDC, 0x83, 0x27 + }, + { + 0x20, 0x20, 0xB7, 0x82, 0x64, 0xA8, 0x2D, 0x9F, + 0x41, 0x51, 0x14, 0x1A, 0xDB, 0xA8, 0xD4, 0x4B, + 0xF2, 0x0C, 0x5E, 0xC0, 0x62, 0xEE, 0xE9, 0xB5, + 0x95, 0xA1, 0x1F, 0x9E, 0x84, 0x90, 0x1B, 0xF1, + 0x48, 0xF2, 0x98, 0xE0, 0xC9, 0xF8, 0x77, 0x7D, + 0xCD, 0xBC, 0x7C, 0xC4, 0x67, 0x0A, 0xAC, 0x35, + 0x6C, 0xC2, 0xAD, 0x8C, 0xCB, 0x16, 0x29, 0xF1, + 0x6F, 0x6A, 0x76, 0xBC, 0xEF, 0xBE, 0xE7, 0x60 + }, + { + 0xD1, 0xB8, 0x97, 0xB0, 0xE0, 0x75, 0xBA, 0x68, + 0xAB, 0x57, 0x2A, 0xDF, 0x9D, 0x9C, 0x43, 0x66, + 0x63, 0xE4, 0x3E, 0xB3, 0xD8, 0xE6, 0x2D, 0x92, + 0xFC, 0x49, 0xC9, 0xBE, 0x21, 0x4E, 0x6F, 0x27, + 0x87, 0x3F, 0xE2, 0x15, 0xA6, 0x51, 0x70, 0xE6, + 0xBE, 0xA9, 0x02, 0x40, 0x8A, 0x25, 0xB4, 0x95, + 0x06, 0xF4, 0x7B, 0xAB, 0xD0, 0x7C, 0xEC, 0xF7, + 0x11, 0x3E, 0xC1, 0x0C, 0x5D, 0xD3, 0x12, 0x52 + }, + { + 0xB1, 0x4D, 0x0C, 0x62, 0xAB, 0xFA, 0x46, 0x9A, + 0x35, 0x71, 0x77, 0xE5, 0x94, 0xC1, 0x0C, 0x19, + 0x42, 0x43, 0xED, 0x20, 0x25, 0xAB, 0x8A, 0xA5, + 0xAD, 0x2F, 0xA4, 0x1A, 0xD3, 0x18, 0xE0, 0xFF, + 0x48, 0xCD, 0x5E, 0x60, 0xBE, 0xC0, 0x7B, 0x13, + 0x63, 0x4A, 0x71, 0x1D, 0x23, 0x26, 0xE4, 0x88, + 0xA9, 0x85, 0xF3, 0x1E, 0x31, 0x15, 0x33, 0x99, + 0xE7, 0x30, 0x88, 0xEF, 0xC8, 0x6A, 0x5C, 0x55 + }, + { + 0x41, 0x69, 0xC5, 0xCC, 0x80, 0x8D, 0x26, 0x97, + 0xDC, 0x2A, 0x82, 0x43, 0x0D, 0xC2, 0x3E, 0x3C, + 0xD3, 0x56, 0xDC, 0x70, 0xA9, 0x45, 0x66, 0x81, + 0x05, 0x02, 0xB8, 0xD6, 0x55, 0xB3, 0x9A, 0xBF, + 0x9E, 0x7F, 0x90, 0x2F, 0xE7, 0x17, 0xE0, 0x38, + 0x92, 0x19, 0x85, 0x9E, 0x19, 0x45, 0xDF, 0x1A, + 0xF6, 0xAD, 0xA4, 0x2E, 0x4C, 0xCD, 0xA5, 0x5A, + 0x19, 0x7B, 0x71, 0x00, 0xA3, 0x0C, 0x30, 0xA1 + }, + { + 0x25, 0x8A, 0x4E, 0xDB, 0x11, 0x3D, 0x66, 0xC8, + 0x39, 0xC8, 0xB1, 0xC9, 0x1F, 0x15, 0xF3, 0x5A, + 0xDE, 0x60, 0x9F, 0x11, 0xCD, 0x7F, 0x86, 0x81, + 0xA4, 0x04, 0x5B, 0x9F, 0xEF, 0x7B, 0x0B, 0x24, + 0xC8, 0x2C, 0xDA, 0x06, 0xA5, 0xF2, 0x06, 0x7B, + 0x36, 0x88, 0x25, 0xE3, 0x91, 0x4E, 0x53, 0xD6, + 0x94, 0x8E, 0xDE, 0x92, 0xEF, 0xD6, 0xE8, 0x38, + 0x7F, 0xA2, 0xE5, 0x37, 0x23, 0x9B, 0x5B, 0xEE + }, + { + 0x79, 0xD2, 0xD8, 0x69, 0x6D, 0x30, 0xF3, 0x0F, + 0xB3, 0x46, 0x57, 0x76, 0x11, 0x71, 0xA1, 0x1E, + 0x6C, 0x3F, 0x1E, 0x64, 0xCB, 0xE7, 0xBE, 0xBE, + 0xE1, 0x59, 0xCB, 0x95, 0xBF, 0xAF, 0x81, 0x2B, + 0x4F, 0x41, 0x1E, 0x2F, 0x26, 0xD9, 0xC4, 0x21, + 0xDC, 0x2C, 0x28, 0x4A, 0x33, 0x42, 0xD8, 0x23, + 0xEC, 0x29, 0x38, 0x49, 0xE4, 0x2D, 0x1E, 0x46, + 0xB0, 0xA4, 0xAC, 0x1E, 0x3C, 0x86, 0xAB, 0xAA + }, + { + 0x8B, 0x94, 0x36, 0x01, 0x0D, 0xC5, 0xDE, 0xE9, + 0x92, 0xAE, 0x38, 0xAE, 0xA9, 0x7F, 0x2C, 0xD6, + 0x3B, 0x94, 0x6D, 0x94, 0xFE, 0xDD, 0x2E, 0xC9, + 0x67, 0x1D, 0xCD, 0xE3, 0xBD, 0x4C, 0xE9, 0x56, + 0x4D, 0x55, 0x5C, 0x66, 0xC1, 0x5B, 0xB2, 0xB9, + 0x00, 0xDF, 0x72, 0xED, 0xB6, 0xB8, 0x91, 0xEB, + 0xCA, 0xDF, 0xEF, 0xF6, 0x3C, 0x9E, 0xA4, 0x03, + 0x6A, 0x99, 0x8B, 0xE7, 0x97, 0x39, 0x81, 0xE7 + }, + { + 0xC8, 0xF6, 0x8E, 0x69, 0x6E, 0xD2, 0x82, 0x42, + 0xBF, 0x99, 0x7F, 0x5B, 0x3B, 0x34, 0x95, 0x95, + 0x08, 0xE4, 0x2D, 0x61, 0x38, 0x10, 0xF1, 0xE2, + 0xA4, 0x35, 0xC9, 0x6E, 0xD2, 0xFF, 0x56, 0x0C, + 0x70, 0x22, 0xF3, 0x61, 0xA9, 0x23, 0x4B, 0x98, + 0x37, 0xFE, 0xEE, 0x90, 0xBF, 0x47, 0x92, 0x2E, + 0xE0, 0xFD, 0x5F, 0x8D, 0xDF, 0x82, 0x37, 0x18, + 0xD8, 0x6D, 0x1E, 0x16, 0xC6, 0x09, 0x00, 0x71 + }, + { + 0xB0, 0x2D, 0x3E, 0xEE, 0x48, 0x60, 0xD5, 0x86, + 0x8B, 0x2C, 0x39, 0xCE, 0x39, 0xBF, 0xE8, 0x10, + 0x11, 0x29, 0x05, 0x64, 0xDD, 0x67, 0x8C, 0x85, + 0xE8, 0x78, 0x3F, 0x29, 0x30, 0x2D, 0xFC, 0x13, + 0x99, 0xBA, 0x95, 0xB6, 0xB5, 0x3C, 0xD9, 0xEB, + 0xBF, 0x40, 0x0C, 0xCA, 0x1D, 0xB0, 0xAB, 0x67, + 0xE1, 0x9A, 0x32, 0x5F, 0x2D, 0x11, 0x58, 0x12, + 0xD2, 0x5D, 0x00, 0x97, 0x8A, 0xD1, 0xBC, 0xA4 + }, + { + 0x76, 0x93, 0xEA, 0x73, 0xAF, 0x3A, 0xC4, 0xDA, + 0xD2, 0x1C, 0xA0, 0xD8, 0xDA, 0x85, 0xB3, 0x11, + 0x8A, 0x7D, 0x1C, 0x60, 0x24, 0xCF, 0xAF, 0x55, + 0x76, 0x99, 0x86, 0x82, 0x17, 0xBC, 0x0C, 0x2F, + 0x44, 0xA1, 0x99, 0xBC, 0x6C, 0x0E, 0xDD, 0x51, + 0x97, 0x98, 0xBA, 0x05, 0xBD, 0x5B, 0x1B, 0x44, + 0x84, 0x34, 0x6A, 0x47, 0xC2, 0xCA, 0xDF, 0x6B, + 0xF3, 0x0B, 0x78, 0x5C, 0xC8, 0x8B, 0x2B, 0xAF + }, + { + 0xA0, 0xE5, 0xC1, 0xC0, 0x03, 0x1C, 0x02, 0xE4, + 0x8B, 0x7F, 0x09, 0xA5, 0xE8, 0x96, 0xEE, 0x9A, + 0xEF, 0x2F, 0x17, 0xFC, 0x9E, 0x18, 0xE9, 0x97, + 0xD7, 0xF6, 0xCA, 0xC7, 0xAE, 0x31, 0x64, 0x22, + 0xC2, 0xB1, 0xE7, 0x79, 0x84, 0xE5, 0xF3, 0xA7, + 0x3C, 0xB4, 0x5D, 0xEE, 0xD5, 0xD3, 0xF8, 0x46, + 0x00, 0x10, 0x5E, 0x6E, 0xE3, 0x8F, 0x2D, 0x09, + 0x0C, 0x7D, 0x04, 0x42, 0xEA, 0x34, 0xC4, 0x6D + }, + { + 0x41, 0xDA, 0xA6, 0xAD, 0xCF, 0xDB, 0x69, 0xF1, + 0x44, 0x0C, 0x37, 0xB5, 0x96, 0x44, 0x01, 0x65, + 0xC1, 0x5A, 0xDA, 0x59, 0x68, 0x13, 0xE2, 0xE2, + 0x2F, 0x06, 0x0F, 0xCD, 0x55, 0x1F, 0x24, 0xDE, + 0xE8, 0xE0, 0x4B, 0xA6, 0x89, 0x03, 0x87, 0x88, + 0x6C, 0xEE, 0xC4, 0xA7, 0xA0, 0xD7, 0xFC, 0x6B, + 0x44, 0x50, 0x63, 0x92, 0xEC, 0x38, 0x22, 0xC0, + 0xD8, 0xC1, 0xAC, 0xFC, 0x7D, 0x5A, 0xEB, 0xE8 + }, + { + 0x14, 0xD4, 0xD4, 0x0D, 0x59, 0x84, 0xD8, 0x4C, + 0x5C, 0xF7, 0x52, 0x3B, 0x77, 0x98, 0xB2, 0x54, + 0xE2, 0x75, 0xA3, 0xA8, 0xCC, 0x0A, 0x1B, 0xD0, + 0x6E, 0xBC, 0x0B, 0xEE, 0x72, 0x68, 0x56, 0xAC, + 0xC3, 0xCB, 0xF5, 0x16, 0xFF, 0x66, 0x7C, 0xDA, + 0x20, 0x58, 0xAD, 0x5C, 0x34, 0x12, 0x25, 0x44, + 0x60, 0xA8, 0x2C, 0x92, 0x18, 0x70, 0x41, 0x36, + 0x3C, 0xC7, 0x7A, 0x4D, 0xC2, 0x15, 0xE4, 0x87 + }, + { + 0xD0, 0xE7, 0xA1, 0xE2, 0xB9, 0xA4, 0x47, 0xFE, + 0xE8, 0x3E, 0x22, 0x77, 0xE9, 0xFF, 0x80, 0x10, + 0xC2, 0xF3, 0x75, 0xAE, 0x12, 0xFA, 0x7A, 0xAA, + 0x8C, 0xA5, 0xA6, 0x31, 0x78, 0x68, 0xA2, 0x6A, + 0x36, 0x7A, 0x0B, 0x69, 0xFB, 0xC1, 0xCF, 0x32, + 0xA5, 0x5D, 0x34, 0xEB, 0x37, 0x06, 0x63, 0x01, + 0x6F, 0x3D, 0x21, 0x10, 0x23, 0x0E, 0xBA, 0x75, + 0x40, 0x28, 0xA5, 0x6F, 0x54, 0xAC, 0xF5, 0x7C + }, + { + 0xE7, 0x71, 0xAA, 0x8D, 0xB5, 0xA3, 0xE0, 0x43, + 0xE8, 0x17, 0x8F, 0x39, 0xA0, 0x85, 0x7B, 0xA0, + 0x4A, 0x3F, 0x18, 0xE4, 0xAA, 0x05, 0x74, 0x3C, + 0xF8, 0xD2, 0x22, 0xB0, 0xB0, 0x95, 0x82, 0x53, + 0x50, 0xBA, 0x42, 0x2F, 0x63, 0x38, 0x2A, 0x23, + 0xD9, 0x2E, 0x41, 0x49, 0x07, 0x4E, 0x81, 0x6A, + 0x36, 0xC1, 0xCD, 0x28, 0x28, 0x4D, 0x14, 0x62, + 0x67, 0x94, 0x0B, 0x31, 0xF8, 0x81, 0x8E, 0xA2 + }, + { + 0xFE, 0xB4, 0xFD, 0x6F, 0x9E, 0x87, 0xA5, 0x6B, + 0xEF, 0x39, 0x8B, 0x32, 0x84, 0xD2, 0xBD, 0xA5, + 0xB5, 0xB0, 0xE1, 0x66, 0x58, 0x3A, 0x66, 0xB6, + 0x1E, 0x53, 0x84, 0x57, 0xFF, 0x05, 0x84, 0x87, + 0x2C, 0x21, 0xA3, 0x29, 0x62, 0xB9, 0x92, 0x8F, + 0xFA, 0xB5, 0x8D, 0xE4, 0xAF, 0x2E, 0xDD, 0x4E, + 0x15, 0xD8, 0xB3, 0x55, 0x70, 0x52, 0x32, 0x07, + 0xFF, 0x4E, 0x2A, 0x5A, 0xA7, 0x75, 0x4C, 0xAA + }, + { + 0x46, 0x2F, 0x17, 0xBF, 0x00, 0x5F, 0xB1, 0xC1, + 0xB9, 0xE6, 0x71, 0x77, 0x9F, 0x66, 0x52, 0x09, + 0xEC, 0x28, 0x73, 0xE3, 0xE4, 0x11, 0xF9, 0x8D, + 0xAB, 0xF2, 0x40, 0xA1, 0xD5, 0xEC, 0x3F, 0x95, + 0xCE, 0x67, 0x96, 0xB6, 0xFC, 0x23, 0xFE, 0x17, + 0x19, 0x03, 0xB5, 0x02, 0x02, 0x34, 0x67, 0xDE, + 0xC7, 0x27, 0x3F, 0xF7, 0x48, 0x79, 0xB9, 0x29, + 0x67, 0xA2, 0xA4, 0x3A, 0x5A, 0x18, 0x3D, 0x33 + }, + { + 0xD3, 0x33, 0x81, 0x93, 0xB6, 0x45, 0x53, 0xDB, + 0xD3, 0x8D, 0x14, 0x4B, 0xEA, 0x71, 0xC5, 0x91, + 0x5B, 0xB1, 0x10, 0xE2, 0xD8, 0x81, 0x80, 0xDB, + 0xC5, 0xDB, 0x36, 0x4F, 0xD6, 0x17, 0x1D, 0xF3, + 0x17, 0xFC, 0x72, 0x68, 0x83, 0x1B, 0x5A, 0xEF, + 0x75, 0xE4, 0x34, 0x2B, 0x2F, 0xAD, 0x87, 0x97, + 0xBA, 0x39, 0xED, 0xDC, 0xEF, 0x80, 0xE6, 0xEC, + 0x08, 0x15, 0x93, 0x50, 0xB1, 0xAD, 0x69, 0x6D + }, + { + 0xE1, 0x59, 0x0D, 0x58, 0x5A, 0x3D, 0x39, 0xF7, + 0xCB, 0x59, 0x9A, 0xBD, 0x47, 0x90, 0x70, 0x96, + 0x64, 0x09, 0xA6, 0x84, 0x6D, 0x43, 0x77, 0xAC, + 0xF4, 0x47, 0x1D, 0x06, 0x5D, 0x5D, 0xB9, 0x41, + 0x29, 0xCC, 0x9B, 0xE9, 0x25, 0x73, 0xB0, 0x5E, + 0xD2, 0x26, 0xBE, 0x1E, 0x9B, 0x7C, 0xB0, 0xCA, + 0xBE, 0x87, 0x91, 0x85, 0x89, 0xF8, 0x0D, 0xAD, + 0xD4, 0xEF, 0x5E, 0xF2, 0x5A, 0x93, 0xD2, 0x8E + }, + { + 0xF8, 0xF3, 0x72, 0x6A, 0xC5, 0xA2, 0x6C, 0xC8, + 0x01, 0x32, 0x49, 0x3A, 0x6F, 0xED, 0xCB, 0x0E, + 0x60, 0x76, 0x0C, 0x09, 0xCF, 0xC8, 0x4C, 0xAD, + 0x17, 0x81, 0x75, 0x98, 0x68, 0x19, 0x66, 0x5E, + 0x76, 0x84, 0x2D, 0x7B, 0x9F, 0xED, 0xF7, 0x6D, + 0xDD, 0xEB, 0xF5, 0xD3, 0xF5, 0x6F, 0xAA, 0xAD, + 0x44, 0x77, 0x58, 0x7A, 0xF2, 0x16, 0x06, 0xD3, + 0x96, 0xAE, 0x57, 0x0D, 0x8E, 0x71, 0x9A, 0xF2 + }, + { + 0x30, 0x18, 0x60, 0x55, 0xC0, 0x79, 0x49, 0x94, + 0x81, 0x83, 0xC8, 0x50, 0xE9, 0xA7, 0x56, 0xCC, + 0x09, 0x93, 0x7E, 0x24, 0x7D, 0x9D, 0x92, 0x8E, + 0x86, 0x9E, 0x20, 0xBA, 0xFC, 0x3C, 0xD9, 0x72, + 0x17, 0x19, 0xD3, 0x4E, 0x04, 0xA0, 0x89, 0x9B, + 0x92, 0xC7, 0x36, 0x08, 0x45, 0x50, 0x18, 0x68, + 0x86, 0xEF, 0xBA, 0x2E, 0x79, 0x0D, 0x8B, 0xE6, + 0xEB, 0xF0, 0x40, 0xB2, 0x09, 0xC4, 0x39, 0xA4 + }, + { + 0xF3, 0xC4, 0x27, 0x6C, 0xB8, 0x63, 0x63, 0x77, + 0x12, 0xC2, 0x41, 0xC4, 0x44, 0xC5, 0xCC, 0x1E, + 0x35, 0x54, 0xE0, 0xFD, 0xDB, 0x17, 0x4D, 0x03, + 0x58, 0x19, 0xDD, 0x83, 0xEB, 0x70, 0x0B, 0x4C, + 0xE8, 0x8D, 0xF3, 0xAB, 0x38, 0x41, 0xBA, 0x02, + 0x08, 0x5E, 0x1A, 0x99, 0xB4, 0xE1, 0x73, 0x10, + 0xC5, 0x34, 0x10, 0x75, 0xC0, 0x45, 0x8B, 0xA3, + 0x76, 0xC9, 0x5A, 0x68, 0x18, 0xFB, 0xB3, 0xE2 + }, + { + 0x0A, 0xA0, 0x07, 0xC4, 0xDD, 0x9D, 0x58, 0x32, + 0x39, 0x30, 0x40, 0xA1, 0x58, 0x3C, 0x93, 0x0B, + 0xCA, 0x7D, 0xC5, 0xE7, 0x7E, 0xA5, 0x3A, 0xDD, + 0x7E, 0x2B, 0x3F, 0x7C, 0x8E, 0x23, 0x13, 0x68, + 0x04, 0x35, 0x20, 0xD4, 0xA3, 0xEF, 0x53, 0xC9, + 0x69, 0xB6, 0xBB, 0xFD, 0x02, 0x59, 0x46, 0xF6, + 0x32, 0xBD, 0x7F, 0x76, 0x5D, 0x53, 0xC2, 0x10, + 0x03, 0xB8, 0xF9, 0x83, 0xF7, 0x5E, 0x2A, 0x6A + }, + { + 0x08, 0xE9, 0x46, 0x47, 0x20, 0x53, 0x3B, 0x23, + 0xA0, 0x4E, 0xC2, 0x4F, 0x7A, 0xE8, 0xC1, 0x03, + 0x14, 0x5F, 0x76, 0x53, 0x87, 0xD7, 0x38, 0x77, + 0x7D, 0x3D, 0x34, 0x34, 0x77, 0xFD, 0x1C, 0x58, + 0xDB, 0x05, 0x21, 0x42, 0xCA, 0xB7, 0x54, 0xEA, + 0x67, 0x43, 0x78, 0xE1, 0x87, 0x66, 0xC5, 0x35, + 0x42, 0xF7, 0x19, 0x70, 0x17, 0x1C, 0xC4, 0xF8, + 0x16, 0x94, 0x24, 0x6B, 0x71, 0x7D, 0x75, 0x64 + }, + { + 0xD3, 0x7F, 0xF7, 0xAD, 0x29, 0x79, 0x93, 0xE7, + 0xEC, 0x21, 0xE0, 0xF1, 0xB4, 0xB5, 0xAE, 0x71, + 0x9C, 0xDC, 0x83, 0xC5, 0xDB, 0x68, 0x75, 0x27, + 0xF2, 0x75, 0x16, 0xCB, 0xFF, 0xA8, 0x22, 0x88, + 0x8A, 0x68, 0x10, 0xEE, 0x5C, 0x1C, 0xA7, 0xBF, + 0xE3, 0x32, 0x11, 0x19, 0xBE, 0x1A, 0xB7, 0xBF, + 0xA0, 0xA5, 0x02, 0x67, 0x1C, 0x83, 0x29, 0x49, + 0x4D, 0xF7, 0xAD, 0x6F, 0x52, 0x2D, 0x44, 0x0F + }, + { + 0xDD, 0x90, 0x42, 0xF6, 0xE4, 0x64, 0xDC, 0xF8, + 0x6B, 0x12, 0x62, 0xF6, 0xAC, 0xCF, 0xAF, 0xBD, + 0x8C, 0xFD, 0x90, 0x2E, 0xD3, 0xED, 0x89, 0xAB, + 0xF7, 0x8F, 0xFA, 0x48, 0x2D, 0xBD, 0xEE, 0xB6, + 0x96, 0x98, 0x42, 0x39, 0x4C, 0x9A, 0x11, 0x68, + 0xAE, 0x3D, 0x48, 0x1A, 0x01, 0x78, 0x42, 0xF6, + 0x60, 0x00, 0x2D, 0x42, 0x44, 0x7C, 0x6B, 0x22, + 0xF7, 0xB7, 0x2F, 0x21, 0xAA, 0xE0, 0x21, 0xC9 + }, + { + 0xBD, 0x96, 0x5B, 0xF3, 0x1E, 0x87, 0xD7, 0x03, + 0x27, 0x53, 0x6F, 0x2A, 0x34, 0x1C, 0xEB, 0xC4, + 0x76, 0x8E, 0xCA, 0x27, 0x5F, 0xA0, 0x5E, 0xF9, + 0x8F, 0x7F, 0x1B, 0x71, 0xA0, 0x35, 0x12, 0x98, + 0xDE, 0x00, 0x6F, 0xBA, 0x73, 0xFE, 0x67, 0x33, + 0xED, 0x01, 0xD7, 0x58, 0x01, 0xB4, 0xA9, 0x28, + 0xE5, 0x42, 0x31, 0xB3, 0x8E, 0x38, 0xC5, 0x62, + 0xB2, 0xE3, 0x3E, 0xA1, 0x28, 0x49, 0x92, 0xFA + }, + { + 0x65, 0x67, 0x6D, 0x80, 0x06, 0x17, 0x97, 0x2F, + 0xBD, 0x87, 0xE4, 0xB9, 0x51, 0x4E, 0x1C, 0x67, + 0x40, 0x2B, 0x7A, 0x33, 0x10, 0x96, 0xD3, 0xBF, + 0xAC, 0x22, 0xF1, 0xAB, 0xB9, 0x53, 0x74, 0xAB, + 0xC9, 0x42, 0xF1, 0x6E, 0x9A, 0xB0, 0xEA, 0xD3, + 0x3B, 0x87, 0xC9, 0x19, 0x68, 0xA6, 0xE5, 0x09, + 0xE1, 0x19, 0xFF, 0x07, 0x78, 0x7B, 0x3E, 0xF4, + 0x83, 0xE1, 0xDC, 0xDC, 0xCF, 0x6E, 0x30, 0x22 + }, + { + 0x93, 0x9F, 0xA1, 0x89, 0x69, 0x9C, 0x5D, 0x2C, + 0x81, 0xDD, 0xD1, 0xFF, 0xC1, 0xFA, 0x20, 0x7C, + 0x97, 0x0B, 0x6A, 0x36, 0x85, 0xBB, 0x29, 0xCE, + 0x1D, 0x3E, 0x99, 0xD4, 0x2F, 0x2F, 0x74, 0x42, + 0xDA, 0x53, 0xE9, 0x5A, 0x72, 0x90, 0x73, 0x14, + 0xF4, 0x58, 0x83, 0x99, 0xA3, 0xFF, 0x5B, 0x0A, + 0x92, 0xBE, 0xB3, 0xF6, 0xBE, 0x26, 0x94, 0xF9, + 0xF8, 0x6E, 0xCF, 0x29, 0x52, 0xD5, 0xB4, 0x1C + }, + { + 0xC5, 0x16, 0x54, 0x17, 0x01, 0x86, 0x3F, 0x91, + 0x00, 0x5F, 0x31, 0x41, 0x08, 0xCE, 0xEC, 0xE3, + 0xC6, 0x43, 0xE0, 0x4F, 0xC8, 0xC4, 0x2F, 0xD2, + 0xFF, 0x55, 0x62, 0x20, 0xE6, 0x16, 0xAA, 0xA6, + 0xA4, 0x8A, 0xEB, 0x97, 0xA8, 0x4B, 0xAD, 0x74, + 0x78, 0x2E, 0x8D, 0xFF, 0x96, 0xA1, 0xA2, 0xFA, + 0x94, 0x93, 0x39, 0xD7, 0x22, 0xED, 0xCA, 0xA3, + 0x2B, 0x57, 0x06, 0x70, 0x41, 0xDF, 0x88, 0xCC + }, + { + 0x98, 0x7F, 0xD6, 0xE0, 0xD6, 0x85, 0x7C, 0x55, + 0x3E, 0xAE, 0xBB, 0x3D, 0x34, 0x97, 0x0A, 0x2C, + 0x2F, 0x6E, 0x89, 0xA3, 0x54, 0x8F, 0x49, 0x25, + 0x21, 0x72, 0x2B, 0x80, 0xA1, 0xC2, 0x1A, 0x15, + 0x38, 0x92, 0x34, 0x6D, 0x2C, 0xBA, 0x64, 0x44, + 0x21, 0x2D, 0x56, 0xDA, 0x9A, 0x26, 0xE3, 0x24, + 0xDC, 0xCB, 0xC0, 0xDC, 0xDE, 0x85, 0xD4, 0xD2, + 0xEE, 0x43, 0x99, 0xEE, 0xC5, 0xA6, 0x4E, 0x8F + }, + { + 0xAE, 0x56, 0xDE, 0xB1, 0xC2, 0x32, 0x8D, 0x9C, + 0x40, 0x17, 0x70, 0x6B, 0xCE, 0x6E, 0x99, 0xD4, + 0x13, 0x49, 0x05, 0x3B, 0xA9, 0xD3, 0x36, 0xD6, + 0x77, 0xC4, 0xC2, 0x7D, 0x9F, 0xD5, 0x0A, 0xE6, + 0xAE, 0xE1, 0x7E, 0x85, 0x31, 0x54, 0xE1, 0xF4, + 0xFE, 0x76, 0x72, 0x34, 0x6D, 0xA2, 0xEA, 0xA3, + 0x1E, 0xEA, 0x53, 0xFC, 0xF2, 0x4A, 0x22, 0x80, + 0x4F, 0x11, 0xD0, 0x3D, 0xA6, 0xAB, 0xFC, 0x2B + }, + { + 0x49, 0xD6, 0xA6, 0x08, 0xC9, 0xBD, 0xE4, 0x49, + 0x18, 0x70, 0x49, 0x85, 0x72, 0xAC, 0x31, 0xAA, + 0xC3, 0xFA, 0x40, 0x93, 0x8B, 0x38, 0xA7, 0x81, + 0x8F, 0x72, 0x38, 0x3E, 0xB0, 0x40, 0xAD, 0x39, + 0x53, 0x2B, 0xC0, 0x65, 0x71, 0xE1, 0x3D, 0x76, + 0x7E, 0x69, 0x45, 0xAB, 0x77, 0xC0, 0xBD, 0xC3, + 0xB0, 0x28, 0x42, 0x53, 0x34, 0x3F, 0x9F, 0x6C, + 0x12, 0x44, 0xEB, 0xF2, 0xFF, 0x0D, 0xF8, 0x66 + }, + { + 0xDA, 0x58, 0x2A, 0xD8, 0xC5, 0x37, 0x0B, 0x44, + 0x69, 0xAF, 0x86, 0x2A, 0xA6, 0x46, 0x7A, 0x22, + 0x93, 0xB2, 0xB2, 0x8B, 0xD8, 0x0A, 0xE0, 0xE9, + 0x1F, 0x42, 0x5A, 0xD3, 0xD4, 0x72, 0x49, 0xFD, + 0xF9, 0x88, 0x25, 0xCC, 0x86, 0xF1, 0x40, 0x28, + 0xC3, 0x30, 0x8C, 0x98, 0x04, 0xC7, 0x8B, 0xFE, + 0xEE, 0xEE, 0x46, 0x14, 0x44, 0xCE, 0x24, 0x36, + 0x87, 0xE1, 0xA5, 0x05, 0x22, 0x45, 0x6A, 0x1D + }, + { + 0xD5, 0x26, 0x6A, 0xA3, 0x33, 0x11, 0x94, 0xAE, + 0xF8, 0x52, 0xEE, 0xD8, 0x6D, 0x7B, 0x5B, 0x26, + 0x33, 0xA0, 0xAF, 0x1C, 0x73, 0x59, 0x06, 0xF2, + 0xE1, 0x32, 0x79, 0xF1, 0x49, 0x31, 0xA9, 0xFC, + 0x3B, 0x0E, 0xAC, 0x5C, 0xE9, 0x24, 0x52, 0x73, + 0xBD, 0x1A, 0xA9, 0x29, 0x05, 0xAB, 0xE1, 0x62, + 0x78, 0xEF, 0x7E, 0xFD, 0x47, 0x69, 0x47, 0x89, + 0xA7, 0x28, 0x3B, 0x77, 0xDA, 0x3C, 0x70, 0xF8 + }, + { + 0x29, 0x62, 0x73, 0x4C, 0x28, 0x25, 0x21, 0x86, + 0xA9, 0xA1, 0x11, 0x1C, 0x73, 0x2A, 0xD4, 0xDE, + 0x45, 0x06, 0xD4, 0xB4, 0x48, 0x09, 0x16, 0x30, + 0x3E, 0xB7, 0x99, 0x1D, 0x65, 0x9C, 0xCD, 0xA0, + 0x7A, 0x99, 0x11, 0x91, 0x4B, 0xC7, 0x5C, 0x41, + 0x8A, 0xB7, 0xA4, 0x54, 0x17, 0x57, 0xAD, 0x05, + 0x47, 0x96, 0xE2, 0x67, 0x97, 0xFE, 0xAF, 0x36, + 0xE9, 0xF6, 0xAD, 0x43, 0xF1, 0x4B, 0x35, 0xA4 + }, + { + 0xE8, 0xB7, 0x9E, 0xC5, 0xD0, 0x6E, 0x11, 0x1B, + 0xDF, 0xAF, 0xD7, 0x1E, 0x9F, 0x57, 0x60, 0xF0, + 0x0A, 0xC8, 0xAC, 0x5D, 0x8B, 0xF7, 0x68, 0xF9, + 0xFF, 0x6F, 0x08, 0xB8, 0xF0, 0x26, 0x09, 0x6B, + 0x1C, 0xC3, 0xA4, 0xC9, 0x73, 0x33, 0x30, 0x19, + 0xF1, 0xE3, 0x55, 0x3E, 0x77, 0xDA, 0x3F, 0x98, + 0xCB, 0x9F, 0x54, 0x2E, 0x0A, 0x90, 0xE5, 0xF8, + 0xA9, 0x40, 0xCC, 0x58, 0xE5, 0x98, 0x44, 0xB3 + }, + { + 0xDF, 0xB3, 0x20, 0xC4, 0x4F, 0x9D, 0x41, 0xD1, + 0xEF, 0xDC, 0xC0, 0x15, 0xF0, 0x8D, 0xD5, 0x53, + 0x9E, 0x52, 0x6E, 0x39, 0xC8, 0x7D, 0x50, 0x9A, + 0xE6, 0x81, 0x2A, 0x96, 0x9E, 0x54, 0x31, 0xBF, + 0x4F, 0xA7, 0xD9, 0x1F, 0xFD, 0x03, 0xB9, 0x81, + 0xE0, 0xD5, 0x44, 0xCF, 0x72, 0xD7, 0xB1, 0xC0, + 0x37, 0x4F, 0x88, 0x01, 0x48, 0x2E, 0x6D, 0xEA, + 0x2E, 0xF9, 0x03, 0x87, 0x7E, 0xBA, 0x67, 0x5E + }, + { + 0xD8, 0x86, 0x75, 0x11, 0x8F, 0xDB, 0x55, 0xA5, + 0xFB, 0x36, 0x5A, 0xC2, 0xAF, 0x1D, 0x21, 0x7B, + 0xF5, 0x26, 0xCE, 0x1E, 0xE9, 0xC9, 0x4B, 0x2F, + 0x00, 0x90, 0xB2, 0xC5, 0x8A, 0x06, 0xCA, 0x58, + 0x18, 0x7D, 0x7F, 0xE5, 0x7C, 0x7B, 0xED, 0x9D, + 0x26, 0xFC, 0xA0, 0x67, 0xB4, 0x11, 0x0E, 0xEF, + 0xCD, 0x9A, 0x0A, 0x34, 0x5D, 0xE8, 0x72, 0xAB, + 0xE2, 0x0D, 0xE3, 0x68, 0x00, 0x1B, 0x07, 0x45 + }, + { + 0xB8, 0x93, 0xF2, 0xFC, 0x41, 0xF7, 0xB0, 0xDD, + 0x6E, 0x2F, 0x6A, 0xA2, 0xE0, 0x37, 0x0C, 0x0C, + 0xFF, 0x7D, 0xF0, 0x9E, 0x3A, 0xCF, 0xCC, 0x0E, + 0x92, 0x0B, 0x6E, 0x6F, 0xAD, 0x0E, 0xF7, 0x47, + 0xC4, 0x06, 0x68, 0x41, 0x7D, 0x34, 0x2B, 0x80, + 0xD2, 0x35, 0x1E, 0x8C, 0x17, 0x5F, 0x20, 0x89, + 0x7A, 0x06, 0x2E, 0x97, 0x65, 0xE6, 0xC6, 0x7B, + 0x53, 0x9B, 0x6B, 0xA8, 0xB9, 0x17, 0x05, 0x45 + }, + { + 0x6C, 0x67, 0xEC, 0x56, 0x97, 0xAC, 0xCD, 0x23, + 0x5C, 0x59, 0xB4, 0x86, 0xD7, 0xB7, 0x0B, 0xAE, + 0xED, 0xCB, 0xD4, 0xAA, 0x64, 0xEB, 0xD4, 0xEE, + 0xF3, 0xC7, 0xEA, 0xC1, 0x89, 0x56, 0x1A, 0x72, + 0x62, 0x50, 0xAE, 0xC4, 0xD4, 0x8C, 0xAD, 0xCA, + 0xFB, 0xBE, 0x2C, 0xE3, 0xC1, 0x6C, 0xE2, 0xD6, + 0x91, 0xA8, 0xCC, 0xE0, 0x6E, 0x88, 0x79, 0x55, + 0x6D, 0x44, 0x83, 0xED, 0x71, 0x65, 0xC0, 0x63 + }, + { + 0xF1, 0xAA, 0x2B, 0x04, 0x4F, 0x8F, 0x0C, 0x63, + 0x8A, 0x3F, 0x36, 0x2E, 0x67, 0x7B, 0x5D, 0x89, + 0x1D, 0x6F, 0xD2, 0xAB, 0x07, 0x65, 0xF6, 0xEE, + 0x1E, 0x49, 0x87, 0xDE, 0x05, 0x7E, 0xAD, 0x35, + 0x78, 0x83, 0xD9, 0xB4, 0x05, 0xB9, 0xD6, 0x09, + 0xEE, 0xA1, 0xB8, 0x69, 0xD9, 0x7F, 0xB1, 0x6D, + 0x9B, 0x51, 0x01, 0x7C, 0x55, 0x3F, 0x3B, 0x93, + 0xC0, 0xA1, 0xE0, 0xF1, 0x29, 0x6F, 0xED, 0xCD + }, + { + 0xCB, 0xAA, 0x25, 0x95, 0x72, 0xD4, 0xAE, 0xBF, + 0xC1, 0x91, 0x7A, 0xCD, 0xDC, 0x58, 0x2B, 0x9F, + 0x8D, 0xFA, 0xA9, 0x28, 0xA1, 0x98, 0xCA, 0x7A, + 0xCD, 0x0F, 0x2A, 0xA7, 0x6A, 0x13, 0x4A, 0x90, + 0x25, 0x2E, 0x62, 0x98, 0xA6, 0x5B, 0x08, 0x18, + 0x6A, 0x35, 0x0D, 0x5B, 0x76, 0x26, 0x69, 0x9F, + 0x8C, 0xB7, 0x21, 0xA3, 0xEA, 0x59, 0x21, 0xB7, + 0x53, 0xAE, 0x3A, 0x2D, 0xCE, 0x24, 0xBA, 0x3A + }, + { + 0xFA, 0x15, 0x49, 0xC9, 0x79, 0x6C, 0xD4, 0xD3, + 0x03, 0xDC, 0xF4, 0x52, 0xC1, 0xFB, 0xD5, 0x74, + 0x4F, 0xD9, 0xB9, 0xB4, 0x70, 0x03, 0xD9, 0x20, + 0xB9, 0x2D, 0xE3, 0x48, 0x39, 0xD0, 0x7E, 0xF2, + 0xA2, 0x9D, 0xED, 0x68, 0xF6, 0xFC, 0x9E, 0x6C, + 0x45, 0xE0, 0x71, 0xA2, 0xE4, 0x8B, 0xD5, 0x0C, + 0x50, 0x84, 0xE9, 0x6B, 0x65, 0x7D, 0xD0, 0x40, + 0x40, 0x45, 0xA1, 0xDD, 0xEF, 0xE2, 0x82, 0xED + }, + { + 0x5C, 0xF2, 0xAC, 0x89, 0x7A, 0xB4, 0x44, 0xDC, + 0xB5, 0xC8, 0xD8, 0x7C, 0x49, 0x5D, 0xBD, 0xB3, + 0x4E, 0x18, 0x38, 0xB6, 0xB6, 0x29, 0x42, 0x7C, + 0xAA, 0x51, 0x70, 0x2A, 0xD0, 0xF9, 0x68, 0x85, + 0x25, 0xF1, 0x3B, 0xEC, 0x50, 0x3A, 0x3C, 0x3A, + 0x2C, 0x80, 0xA6, 0x5E, 0x0B, 0x57, 0x15, 0xE8, + 0xAF, 0xAB, 0x00, 0xFF, 0xA5, 0x6E, 0xC4, 0x55, + 0xA4, 0x9A, 0x1A, 0xD3, 0x0A, 0xA2, 0x4F, 0xCD + }, + { + 0x9A, 0xAF, 0x80, 0x20, 0x7B, 0xAC, 0xE1, 0x7B, + 0xB7, 0xAB, 0x14, 0x57, 0x57, 0xD5, 0x69, 0x6B, + 0xDE, 0x32, 0x40, 0x6E, 0xF2, 0x2B, 0x44, 0x29, + 0x2E, 0xF6, 0x5D, 0x45, 0x19, 0xC3, 0xBB, 0x2A, + 0xD4, 0x1A, 0x59, 0xB6, 0x2C, 0xC3, 0xE9, 0x4B, + 0x6F, 0xA9, 0x6D, 0x32, 0xA7, 0xFA, 0xAD, 0xAE, + 0x28, 0xAF, 0x7D, 0x35, 0x09, 0x72, 0x19, 0xAA, + 0x3F, 0xD8, 0xCD, 0xA3, 0x1E, 0x40, 0xC2, 0x75 + }, + { + 0xAF, 0x88, 0xB1, 0x63, 0x40, 0x2C, 0x86, 0x74, + 0x5C, 0xB6, 0x50, 0xC2, 0x98, 0x8F, 0xB9, 0x52, + 0x11, 0xB9, 0x4B, 0x03, 0xEF, 0x29, 0x0E, 0xED, + 0x96, 0x62, 0x03, 0x42, 0x41, 0xFD, 0x51, 0xCF, + 0x39, 0x8F, 0x80, 0x73, 0xE3, 0x69, 0x35, 0x4C, + 0x43, 0xEA, 0xE1, 0x05, 0x2F, 0x9B, 0x63, 0xB0, + 0x81, 0x91, 0xCA, 0xA1, 0x38, 0xAA, 0x54, 0xFE, + 0xA8, 0x89, 0xCC, 0x70, 0x24, 0x23, 0x68, 0x97 + }, + { + 0x48, 0xFA, 0x7D, 0x64, 0xE1, 0xCE, 0xEE, 0x27, + 0xB9, 0x86, 0x4D, 0xB5, 0xAD, 0xA4, 0xB5, 0x3D, + 0x00, 0xC9, 0xBC, 0x76, 0x26, 0x55, 0x58, 0x13, + 0xD3, 0xCD, 0x67, 0x30, 0xAB, 0x3C, 0xC0, 0x6F, + 0xF3, 0x42, 0xD7, 0x27, 0x90, 0x5E, 0x33, 0x17, + 0x1B, 0xDE, 0x6E, 0x84, 0x76, 0xE7, 0x7F, 0xB1, + 0x72, 0x08, 0x61, 0xE9, 0x4B, 0x73, 0xA2, 0xC5, + 0x38, 0xD2, 0x54, 0x74, 0x62, 0x85, 0xF4, 0x30 + }, + { + 0x0E, 0x6F, 0xD9, 0x7A, 0x85, 0xE9, 0x04, 0xF8, + 0x7B, 0xFE, 0x85, 0xBB, 0xEB, 0x34, 0xF6, 0x9E, + 0x1F, 0x18, 0x10, 0x5C, 0xF4, 0xED, 0x4F, 0x87, + 0xAE, 0xC3, 0x6C, 0x6E, 0x8B, 0x5F, 0x68, 0xBD, + 0x2A, 0x6F, 0x3D, 0xC8, 0xA9, 0xEC, 0xB2, 0xB6, + 0x1D, 0xB4, 0xEE, 0xDB, 0x6B, 0x2E, 0xA1, 0x0B, + 0xF9, 0xCB, 0x02, 0x51, 0xFB, 0x0F, 0x8B, 0x34, + 0x4A, 0xBF, 0x7F, 0x36, 0x6B, 0x6D, 0xE5, 0xAB + }, + { + 0x06, 0x62, 0x2D, 0xA5, 0x78, 0x71, 0x76, 0x28, + 0x7F, 0xDC, 0x8F, 0xED, 0x44, 0x0B, 0xAD, 0x18, + 0x7D, 0x83, 0x00, 0x99, 0xC9, 0x4E, 0x6D, 0x04, + 0xC8, 0xE9, 0xC9, 0x54, 0xCD, 0xA7, 0x0C, 0x8B, + 0xB9, 0xE1, 0xFC, 0x4A, 0x6D, 0x0B, 0xAA, 0x83, + 0x1B, 0x9B, 0x78, 0xEF, 0x66, 0x48, 0x68, 0x1A, + 0x48, 0x67, 0xA1, 0x1D, 0xA9, 0x3E, 0xE3, 0x6E, + 0x5E, 0x6A, 0x37, 0xD8, 0x7F, 0xC6, 0x3F, 0x6F + }, + { + 0x1D, 0xA6, 0x77, 0x2B, 0x58, 0xFA, 0xBF, 0x9C, + 0x61, 0xF6, 0x8D, 0x41, 0x2C, 0x82, 0xF1, 0x82, + 0xC0, 0x23, 0x6D, 0x7D, 0x57, 0x5E, 0xF0, 0xB5, + 0x8D, 0xD2, 0x24, 0x58, 0xD6, 0x43, 0xCD, 0x1D, + 0xFC, 0x93, 0xB0, 0x38, 0x71, 0xC3, 0x16, 0xD8, + 0x43, 0x0D, 0x31, 0x29, 0x95, 0xD4, 0x19, 0x7F, + 0x08, 0x74, 0xC9, 0x91, 0x72, 0xBA, 0x00, 0x4A, + 0x01, 0xEE, 0x29, 0x5A, 0xBA, 0xC2, 0x4E, 0x46 + }, + { + 0x3C, 0xD2, 0xD9, 0x32, 0x0B, 0x7B, 0x1D, 0x5F, + 0xB9, 0xAA, 0xB9, 0x51, 0xA7, 0x60, 0x23, 0xFA, + 0x66, 0x7B, 0xE1, 0x4A, 0x91, 0x24, 0xE3, 0x94, + 0x51, 0x39, 0x18, 0xA3, 0xF4, 0x40, 0x96, 0xAE, + 0x49, 0x04, 0xBA, 0x0F, 0xFC, 0x15, 0x0B, 0x63, + 0xBC, 0x7A, 0xB1, 0xEE, 0xB9, 0xA6, 0xE2, 0x57, + 0xE5, 0xC8, 0xF0, 0x00, 0xA7, 0x03, 0x94, 0xA5, + 0xAF, 0xD8, 0x42, 0x71, 0x5D, 0xE1, 0x5F, 0x29 + }, + { + 0x04, 0xCD, 0xC1, 0x4F, 0x74, 0x34, 0xE0, 0xB4, + 0xBE, 0x70, 0xCB, 0x41, 0xDB, 0x4C, 0x77, 0x9A, + 0x88, 0xEA, 0xEF, 0x6A, 0xCC, 0xEB, 0xCB, 0x41, + 0xF2, 0xD4, 0x2F, 0xFF, 0xE7, 0xF3, 0x2A, 0x8E, + 0x28, 0x1B, 0x5C, 0x10, 0x3A, 0x27, 0x02, 0x1D, + 0x0D, 0x08, 0x36, 0x22, 0x50, 0x75, 0x3C, 0xDF, + 0x70, 0x29, 0x21, 0x95, 0xA5, 0x3A, 0x48, 0x72, + 0x8C, 0xEB, 0x58, 0x44, 0xC2, 0xD9, 0x8B, 0xAB + }, + { + 0x90, 0x71, 0xB7, 0xA8, 0xA0, 0x75, 0xD0, 0x09, + 0x5B, 0x8F, 0xB3, 0xAE, 0x51, 0x13, 0x78, 0x57, + 0x35, 0xAB, 0x98, 0xE2, 0xB5, 0x2F, 0xAF, 0x91, + 0xD5, 0xB8, 0x9E, 0x44, 0xAA, 0xC5, 0xB5, 0xD4, + 0xEB, 0xBF, 0x91, 0x22, 0x3B, 0x0F, 0xF4, 0xC7, + 0x19, 0x05, 0xDA, 0x55, 0x34, 0x2E, 0x64, 0x65, + 0x5D, 0x6E, 0xF8, 0xC8, 0x9A, 0x47, 0x68, 0xC3, + 0xF9, 0x3A, 0x6D, 0xC0, 0x36, 0x6B, 0x5B, 0xC8 + }, + { + 0xEB, 0xB3, 0x02, 0x40, 0xDD, 0x96, 0xC7, 0xBC, + 0x8D, 0x0A, 0xBE, 0x49, 0xAA, 0x4E, 0xDC, 0xBB, + 0x4A, 0xFD, 0xC5, 0x1F, 0xF9, 0xAA, 0xF7, 0x20, + 0xD3, 0xF9, 0xE7, 0xFB, 0xB0, 0xF9, 0xC6, 0xD6, + 0x57, 0x13, 0x50, 0x50, 0x17, 0x69, 0xFC, 0x4E, + 0xBD, 0x0B, 0x21, 0x41, 0x24, 0x7F, 0xF4, 0x00, + 0xD4, 0xFD, 0x4B, 0xE4, 0x14, 0xED, 0xF3, 0x77, + 0x57, 0xBB, 0x90, 0xA3, 0x2A, 0xC5, 0xC6, 0x5A + }, + { + 0x85, 0x32, 0xC5, 0x8B, 0xF3, 0xC8, 0x01, 0x5D, + 0x9D, 0x1C, 0xBE, 0x00, 0xEE, 0xF1, 0xF5, 0x08, + 0x2F, 0x8F, 0x36, 0x32, 0xFB, 0xE9, 0xF1, 0xED, + 0x4F, 0x9D, 0xFB, 0x1F, 0xA7, 0x9E, 0x82, 0x83, + 0x06, 0x6D, 0x77, 0xC4, 0x4C, 0x4A, 0xF9, 0x43, + 0xD7, 0x6B, 0x30, 0x03, 0x64, 0xAE, 0xCB, 0xD0, + 0x64, 0x8C, 0x8A, 0x89, 0x39, 0xBD, 0x20, 0x41, + 0x23, 0xF4, 0xB5, 0x62, 0x60, 0x42, 0x2D, 0xEC + }, + { + 0xFE, 0x98, 0x46, 0xD6, 0x4F, 0x7C, 0x77, 0x08, + 0x69, 0x6F, 0x84, 0x0E, 0x2D, 0x76, 0xCB, 0x44, + 0x08, 0xB6, 0x59, 0x5C, 0x2F, 0x81, 0xEC, 0x6A, + 0x28, 0xA7, 0xF2, 0xF2, 0x0C, 0xB8, 0x8C, 0xFE, + 0x6A, 0xC0, 0xB9, 0xE9, 0xB8, 0x24, 0x4F, 0x08, + 0xBD, 0x70, 0x95, 0xC3, 0x50, 0xC1, 0xD0, 0x84, + 0x2F, 0x64, 0xFB, 0x01, 0xBB, 0x7F, 0x53, 0x2D, + 0xFC, 0xD4, 0x73, 0x71, 0xB0, 0xAE, 0xEB, 0x79 + }, + { + 0x28, 0xF1, 0x7E, 0xA6, 0xFB, 0x6C, 0x42, 0x09, + 0x2D, 0xC2, 0x64, 0x25, 0x7E, 0x29, 0x74, 0x63, + 0x21, 0xFB, 0x5B, 0xDA, 0xEA, 0x98, 0x73, 0xC2, + 0xA7, 0xFA, 0x9D, 0x8F, 0x53, 0x81, 0x8E, 0x89, + 0x9E, 0x16, 0x1B, 0xC7, 0x7D, 0xFE, 0x80, 0x90, + 0xAF, 0xD8, 0x2B, 0xF2, 0x26, 0x6C, 0x5C, 0x1B, + 0xC9, 0x30, 0xA8, 0xD1, 0x54, 0x76, 0x24, 0x43, + 0x9E, 0x66, 0x2E, 0xF6, 0x95, 0xF2, 0x6F, 0x24 + }, + { + 0xEC, 0x6B, 0x7D, 0x7F, 0x03, 0x0D, 0x48, 0x50, + 0xAC, 0xAE, 0x3C, 0xB6, 0x15, 0xC2, 0x1D, 0xD2, + 0x52, 0x06, 0xD6, 0x3E, 0x84, 0xD1, 0xDB, 0x8D, + 0x95, 0x73, 0x70, 0x73, 0x7B, 0xA0, 0xE9, 0x84, + 0x67, 0xEA, 0x0C, 0xE2, 0x74, 0xC6, 0x61, 0x99, + 0x90, 0x1E, 0xAE, 0xC1, 0x8A, 0x08, 0x52, 0x57, + 0x15, 0xF5, 0x3B, 0xFD, 0xB0, 0xAA, 0xCB, 0x61, + 0x3D, 0x34, 0x2E, 0xBD, 0xCE, 0xED, 0xDC, 0x3B + }, + { + 0xB4, 0x03, 0xD3, 0x69, 0x1C, 0x03, 0xB0, 0xD3, + 0x41, 0x8D, 0xF3, 0x27, 0xD5, 0x86, 0x0D, 0x34, + 0xBB, 0xFC, 0xC4, 0x51, 0x9B, 0xFB, 0xCE, 0x36, + 0xBF, 0x33, 0xB2, 0x08, 0x38, 0x5F, 0xAD, 0xB9, + 0x18, 0x6B, 0xC7, 0x8A, 0x76, 0xC4, 0x89, 0xD8, + 0x9F, 0xD5, 0x7E, 0x7D, 0xC7, 0x54, 0x12, 0xD2, + 0x3B, 0xCD, 0x1D, 0xAE, 0x84, 0x70, 0xCE, 0x92, + 0x74, 0x75, 0x4B, 0xB8, 0x58, 0x5B, 0x13, 0xC5 + }, + { + 0x31, 0xFC, 0x79, 0x73, 0x8B, 0x87, 0x72, 0xB3, + 0xF5, 0x5C, 0xD8, 0x17, 0x88, 0x13, 0xB3, 0xB5, + 0x2D, 0x0D, 0xB5, 0xA4, 0x19, 0xD3, 0x0B, 0xA9, + 0x49, 0x5C, 0x4B, 0x9D, 0xA0, 0x21, 0x9F, 0xAC, + 0x6D, 0xF8, 0xE7, 0xC2, 0x3A, 0x81, 0x15, 0x51, + 0xA6, 0x2B, 0x82, 0x7F, 0x25, 0x6E, 0xCD, 0xB8, + 0x12, 0x4A, 0xC8, 0xA6, 0x79, 0x2C, 0xCF, 0xEC, + 0xC3, 0xB3, 0x01, 0x27, 0x22, 0xE9, 0x44, 0x63 + }, + { + 0xBB, 0x20, 0x39, 0xEC, 0x28, 0x70, 0x91, 0xBC, + 0xC9, 0x64, 0x2F, 0xC9, 0x00, 0x49, 0xE7, 0x37, + 0x32, 0xE0, 0x2E, 0x57, 0x7E, 0x28, 0x62, 0xB3, + 0x22, 0x16, 0xAE, 0x9B, 0xED, 0xCD, 0x73, 0x0C, + 0x4C, 0x28, 0x4E, 0xF3, 0x96, 0x8C, 0x36, 0x8B, + 0x7D, 0x37, 0x58, 0x4F, 0x97, 0xBD, 0x4B, 0x4D, + 0xC6, 0xEF, 0x61, 0x27, 0xAC, 0xFE, 0x2E, 0x6A, + 0xE2, 0x50, 0x91, 0x24, 0xE6, 0x6C, 0x8A, 0xF4 + }, + { + 0xF5, 0x3D, 0x68, 0xD1, 0x3F, 0x45, 0xED, 0xFC, + 0xB9, 0xBD, 0x41, 0x5E, 0x28, 0x31, 0xE9, 0x38, + 0x35, 0x0D, 0x53, 0x80, 0xD3, 0x43, 0x22, 0x78, + 0xFC, 0x1C, 0x0C, 0x38, 0x1F, 0xCB, 0x7C, 0x65, + 0xC8, 0x2D, 0xAF, 0xE0, 0x51, 0xD8, 0xC8, 0xB0, + 0xD4, 0x4E, 0x09, 0x74, 0xA0, 0xE5, 0x9E, 0xC7, + 0xBF, 0x7E, 0xD0, 0x45, 0x9F, 0x86, 0xE9, 0x6F, + 0x32, 0x9F, 0xC7, 0x97, 0x52, 0x51, 0x0F, 0xD3 + }, + { + 0x8D, 0x56, 0x8C, 0x79, 0x84, 0xF0, 0xEC, 0xDF, + 0x76, 0x40, 0xFB, 0xC4, 0x83, 0xB5, 0xD8, 0xC9, + 0xF8, 0x66, 0x34, 0xF6, 0xF4, 0x32, 0x91, 0x84, + 0x1B, 0x30, 0x9A, 0x35, 0x0A, 0xB9, 0xC1, 0x13, + 0x7D, 0x24, 0x06, 0x6B, 0x09, 0xDA, 0x99, 0x44, + 0xBA, 0xC5, 0x4D, 0x5B, 0xB6, 0x58, 0x0D, 0x83, + 0x60, 0x47, 0xAA, 0xC7, 0x4A, 0xB7, 0x24, 0xB8, + 0x87, 0xEB, 0xF9, 0x3D, 0x4B, 0x32, 0xEC, 0xA9 + }, + { + 0xC0, 0xB6, 0x5C, 0xE5, 0xA9, 0x6F, 0xF7, 0x74, + 0xC4, 0x56, 0xCA, 0xC3, 0xB5, 0xF2, 0xC4, 0xCD, + 0x35, 0x9B, 0x4F, 0xF5, 0x3E, 0xF9, 0x3A, 0x3D, + 0xA0, 0x77, 0x8B, 0xE4, 0x90, 0x0D, 0x1E, 0x8D, + 0xA1, 0x60, 0x1E, 0x76, 0x9E, 0x8F, 0x1B, 0x02, + 0xD2, 0xA2, 0xF8, 0xC5, 0xB9, 0xFA, 0x10, 0xB4, + 0x4F, 0x1C, 0x18, 0x69, 0x85, 0x46, 0x8F, 0xEE, + 0xB0, 0x08, 0x73, 0x02, 0x83, 0xA6, 0x65, 0x7D + }, + { + 0x49, 0x00, 0xBB, 0xA6, 0xF5, 0xFB, 0x10, 0x3E, + 0xCE, 0x8E, 0xC9, 0x6A, 0xDA, 0x13, 0xA5, 0xC3, + 0xC8, 0x54, 0x88, 0xE0, 0x55, 0x51, 0xDA, 0x6B, + 0x6B, 0x33, 0xD9, 0x88, 0xE6, 0x11, 0xEC, 0x0F, + 0xE2, 0xE3, 0xC2, 0xAA, 0x48, 0xEA, 0x6A, 0xE8, + 0x98, 0x6A, 0x3A, 0x23, 0x1B, 0x22, 0x3C, 0x5D, + 0x27, 0xCE, 0xC2, 0xEA, 0xDD, 0xE9, 0x1C, 0xE0, + 0x79, 0x81, 0xEE, 0x65, 0x28, 0x62, 0xD1, 0xE4 + }, + { + 0xC7, 0xF5, 0xC3, 0x7C, 0x72, 0x85, 0xF9, 0x27, + 0xF7, 0x64, 0x43, 0x41, 0x4D, 0x43, 0x57, 0xFF, + 0x78, 0x96, 0x47, 0xD7, 0xA0, 0x05, 0xA5, 0xA7, + 0x87, 0xE0, 0x3C, 0x34, 0x6B, 0x57, 0xF4, 0x9F, + 0x21, 0xB6, 0x4F, 0xA9, 0xCF, 0x4B, 0x7E, 0x45, + 0x57, 0x3E, 0x23, 0x04, 0x90, 0x17, 0x56, 0x71, + 0x21, 0xA9, 0xC3, 0xD4, 0xB2, 0xB7, 0x3E, 0xC5, + 0xE9, 0x41, 0x35, 0x77, 0x52, 0x5D, 0xB4, 0x5A + }, + { + 0xEC, 0x70, 0x96, 0x33, 0x07, 0x36, 0xFD, 0xB2, + 0xD6, 0x4B, 0x56, 0x53, 0xE7, 0x47, 0x5D, 0xA7, + 0x46, 0xC2, 0x3A, 0x46, 0x13, 0xA8, 0x26, 0x87, + 0xA2, 0x80, 0x62, 0xD3, 0x23, 0x63, 0x64, 0x28, + 0x4A, 0xC0, 0x17, 0x20, 0xFF, 0xB4, 0x06, 0xCF, + 0xE2, 0x65, 0xC0, 0xDF, 0x62, 0x6A, 0x18, 0x8C, + 0x9E, 0x59, 0x63, 0xAC, 0xE5, 0xD3, 0xD5, 0xBB, + 0x36, 0x3E, 0x32, 0xC3, 0x8C, 0x21, 0x90, 0xA6 + }, + { + 0x82, 0xE7, 0x44, 0xC7, 0x5F, 0x46, 0x49, 0xEC, + 0x52, 0xB8, 0x07, 0x71, 0xA7, 0x7D, 0x47, 0x5A, + 0x3B, 0xC0, 0x91, 0x98, 0x95, 0x56, 0x96, 0x0E, + 0x27, 0x6A, 0x5F, 0x9E, 0xAD, 0x92, 0xA0, 0x3F, + 0x71, 0x87, 0x42, 0xCD, 0xCF, 0xEA, 0xEE, 0x5C, + 0xB8, 0x5C, 0x44, 0xAF, 0x19, 0x8A, 0xDC, 0x43, + 0xA4, 0xA4, 0x28, 0xF5, 0xF0, 0xC2, 0xDD, 0xB0, + 0xBE, 0x36, 0x05, 0x9F, 0x06, 0xD7, 0xDF, 0x73 + }, + { + 0x28, 0x34, 0xB7, 0xA7, 0x17, 0x0F, 0x1F, 0x5B, + 0x68, 0x55, 0x9A, 0xB7, 0x8C, 0x10, 0x50, 0xEC, + 0x21, 0xC9, 0x19, 0x74, 0x0B, 0x78, 0x4A, 0x90, + 0x72, 0xF6, 0xE5, 0xD6, 0x9F, 0x82, 0x8D, 0x70, + 0xC9, 0x19, 0xC5, 0x03, 0x9F, 0xB1, 0x48, 0xE3, + 0x9E, 0x2C, 0x8A, 0x52, 0x11, 0x83, 0x78, 0xB0, + 0x64, 0xCA, 0x8D, 0x50, 0x01, 0xCD, 0x10, 0xA5, + 0x47, 0x83, 0x87, 0xB9, 0x66, 0x71, 0x5E, 0xD6 + }, + { + 0x16, 0xB4, 0xAD, 0xA8, 0x83, 0xF7, 0x2F, 0x85, + 0x3B, 0xB7, 0xEF, 0x25, 0x3E, 0xFC, 0xAB, 0x0C, + 0x3E, 0x21, 0x61, 0x68, 0x7A, 0xD6, 0x15, 0x43, + 0xA0, 0xD2, 0x82, 0x4F, 0x91, 0xC1, 0xF8, 0x13, + 0x47, 0xD8, 0x6B, 0xE7, 0x09, 0xB1, 0x69, 0x96, + 0xE1, 0x7F, 0x2D, 0xD4, 0x86, 0x92, 0x7B, 0x02, + 0x88, 0xAD, 0x38, 0xD1, 0x30, 0x63, 0xC4, 0xA9, + 0x67, 0x2C, 0x39, 0x39, 0x7D, 0x37, 0x89, 0xB6 + }, + { + 0x78, 0xD0, 0x48, 0xF3, 0xA6, 0x9D, 0x8B, 0x54, + 0xAE, 0x0E, 0xD6, 0x3A, 0x57, 0x3A, 0xE3, 0x50, + 0xD8, 0x9F, 0x7C, 0x6C, 0xF1, 0xF3, 0x68, 0x89, + 0x30, 0xDE, 0x89, 0x9A, 0xFA, 0x03, 0x76, 0x97, + 0x62, 0x9B, 0x31, 0x4E, 0x5C, 0xD3, 0x03, 0xAA, + 0x62, 0xFE, 0xEA, 0x72, 0xA2, 0x5B, 0xF4, 0x2B, + 0x30, 0x4B, 0x6C, 0x6B, 0xCB, 0x27, 0xFA, 0xE2, + 0x1C, 0x16, 0xD9, 0x25, 0xE1, 0xFB, 0xDA, 0xC3 + }, + { + 0x0F, 0x74, 0x6A, 0x48, 0x74, 0x92, 0x87, 0xAD, + 0xA7, 0x7A, 0x82, 0x96, 0x1F, 0x05, 0xA4, 0xDA, + 0x4A, 0xBD, 0xB7, 0xD7, 0x7B, 0x12, 0x20, 0xF8, + 0x36, 0xD0, 0x9E, 0xC8, 0x14, 0x35, 0x9C, 0x0E, + 0xC0, 0x23, 0x9B, 0x8C, 0x7B, 0x9F, 0xF9, 0xE0, + 0x2F, 0x56, 0x9D, 0x1B, 0x30, 0x1E, 0xF6, 0x7C, + 0x46, 0x12, 0xD1, 0xDE, 0x4F, 0x73, 0x0F, 0x81, + 0xC1, 0x2C, 0x40, 0xCC, 0x06, 0x3C, 0x5C, 0xAA + }, + { + 0xF0, 0xFC, 0x85, 0x9D, 0x3B, 0xD1, 0x95, 0xFB, + 0xDC, 0x2D, 0x59, 0x1E, 0x4C, 0xDA, 0xC1, 0x51, + 0x79, 0xEC, 0x0F, 0x1D, 0xC8, 0x21, 0xC1, 0x1D, + 0xF1, 0xF0, 0xC1, 0xD2, 0x6E, 0x62, 0x60, 0xAA, + 0xA6, 0x5B, 0x79, 0xFA, 0xFA, 0xCA, 0xFD, 0x7D, + 0x3A, 0xD6, 0x1E, 0x60, 0x0F, 0x25, 0x09, 0x05, + 0xF5, 0x87, 0x8C, 0x87, 0x45, 0x28, 0x97, 0x64, + 0x7A, 0x35, 0xB9, 0x95, 0xBC, 0xAD, 0xC3, 0xA3 + }, + { + 0x26, 0x20, 0xF6, 0x87, 0xE8, 0x62, 0x5F, 0x6A, + 0x41, 0x24, 0x60, 0xB4, 0x2E, 0x2C, 0xEF, 0x67, + 0x63, 0x42, 0x08, 0xCE, 0x10, 0xA0, 0xCB, 0xD4, + 0xDF, 0xF7, 0x04, 0x4A, 0x41, 0xB7, 0x88, 0x00, + 0x77, 0xE9, 0xF8, 0xDC, 0x3B, 0x8D, 0x12, 0x16, + 0xD3, 0x37, 0x6A, 0x21, 0xE0, 0x15, 0xB5, 0x8F, + 0xB2, 0x79, 0xB5, 0x21, 0xD8, 0x3F, 0x93, 0x88, + 0xC7, 0x38, 0x2C, 0x85, 0x05, 0x59, 0x0B, 0x9B + }, + { + 0x22, 0x7E, 0x3A, 0xED, 0x8D, 0x2C, 0xB1, 0x0B, + 0x91, 0x8F, 0xCB, 0x04, 0xF9, 0xDE, 0x3E, 0x6D, + 0x0A, 0x57, 0xE0, 0x84, 0x76, 0xD9, 0x37, 0x59, + 0xCD, 0x7B, 0x2E, 0xD5, 0x4A, 0x1C, 0xBF, 0x02, + 0x39, 0xC5, 0x28, 0xFB, 0x04, 0xBB, 0xF2, 0x88, + 0x25, 0x3E, 0x60, 0x1D, 0x3B, 0xC3, 0x8B, 0x21, + 0x79, 0x4A, 0xFE, 0xF9, 0x0B, 0x17, 0x09, 0x4A, + 0x18, 0x2C, 0xAC, 0x55, 0x77, 0x45, 0xE7, 0x5F + }, + { + 0x1A, 0x92, 0x99, 0x01, 0xB0, 0x9C, 0x25, 0xF2, + 0x7D, 0x6B, 0x35, 0xBE, 0x7B, 0x2F, 0x1C, 0x47, + 0x45, 0x13, 0x1F, 0xDE, 0xBC, 0xA7, 0xF3, 0xE2, + 0x45, 0x19, 0x26, 0x72, 0x04, 0x34, 0xE0, 0xDB, + 0x6E, 0x74, 0xFD, 0x69, 0x3A, 0xD2, 0x9B, 0x77, + 0x7D, 0xC3, 0x35, 0x5C, 0x59, 0x2A, 0x36, 0x1C, + 0x48, 0x73, 0xB0, 0x11, 0x33, 0xA5, 0x7C, 0x2E, + 0x3B, 0x70, 0x75, 0xCB, 0xDB, 0x86, 0xF4, 0xFC + }, + { + 0x5F, 0xD7, 0x96, 0x8B, 0xC2, 0xFE, 0x34, 0xF2, + 0x20, 0xB5, 0xE3, 0xDC, 0x5A, 0xF9, 0x57, 0x17, + 0x42, 0xD7, 0x3B, 0x7D, 0x60, 0x81, 0x9F, 0x28, + 0x88, 0xB6, 0x29, 0x07, 0x2B, 0x96, 0xA9, 0xD8, + 0xAB, 0x2D, 0x91, 0xB8, 0x2D, 0x0A, 0x9A, 0xAB, + 0xA6, 0x1B, 0xBD, 0x39, 0x95, 0x81, 0x32, 0xFC, + 0xC4, 0x25, 0x70, 0x23, 0xD1, 0xEC, 0xA5, 0x91, + 0xB3, 0x05, 0x4E, 0x2D, 0xC8, 0x1C, 0x82, 0x00 + }, + { + 0xDF, 0xCC, 0xE8, 0xCF, 0x32, 0x87, 0x0C, 0xC6, + 0xA5, 0x03, 0xEA, 0xDA, 0xFC, 0x87, 0xFD, 0x6F, + 0x78, 0x91, 0x8B, 0x9B, 0x4D, 0x07, 0x37, 0xDB, + 0x68, 0x10, 0xBE, 0x99, 0x6B, 0x54, 0x97, 0xE7, + 0xE5, 0xCC, 0x80, 0xE3, 0x12, 0xF6, 0x1E, 0x71, + 0xFF, 0x3E, 0x96, 0x24, 0x43, 0x60, 0x73, 0x15, + 0x64, 0x03, 0xF7, 0x35, 0xF5, 0x6B, 0x0B, 0x01, + 0x84, 0x5C, 0x18, 0xF6, 0xCA, 0xF7, 0x72, 0xE6 + }, + { + 0x02, 0xF7, 0xEF, 0x3A, 0x9C, 0xE0, 0xFF, 0xF9, + 0x60, 0xF6, 0x70, 0x32, 0xB2, 0x96, 0xEF, 0xCA, + 0x30, 0x61, 0xF4, 0x93, 0x4D, 0x69, 0x07, 0x49, + 0xF2, 0xD0, 0x1C, 0x35, 0xC8, 0x1C, 0x14, 0xF3, + 0x9A, 0x67, 0xFA, 0x35, 0x0B, 0xC8, 0xA0, 0x35, + 0x9B, 0xF1, 0x72, 0x4B, 0xFF, 0xC3, 0xBC, 0xA6, + 0xD7, 0xC7, 0xBB, 0xA4, 0x79, 0x1F, 0xD5, 0x22, + 0xA3, 0xAD, 0x35, 0x3C, 0x02, 0xEC, 0x5A, 0xA8 + }, + { + 0x64, 0xBE, 0x5C, 0x6A, 0xBA, 0x65, 0xD5, 0x94, + 0x84, 0x4A, 0xE7, 0x8B, 0xB0, 0x22, 0xE5, 0xBE, + 0xBE, 0x12, 0x7F, 0xD6, 0xB6, 0xFF, 0xA5, 0xA1, + 0x37, 0x03, 0x85, 0x5A, 0xB6, 0x3B, 0x62, 0x4D, + 0xCD, 0x1A, 0x36, 0x3F, 0x99, 0x20, 0x3F, 0x63, + 0x2E, 0xC3, 0x86, 0xF3, 0xEA, 0x76, 0x7F, 0xC9, + 0x92, 0xE8, 0xED, 0x96, 0x86, 0x58, 0x6A, 0xA2, + 0x75, 0x55, 0xA8, 0x59, 0x9D, 0x5B, 0x80, 0x8F + }, + { + 0xF7, 0x85, 0x85, 0x50, 0x5C, 0x4E, 0xAA, 0x54, + 0xA8, 0xB5, 0xBE, 0x70, 0xA6, 0x1E, 0x73, 0x5E, + 0x0F, 0xF9, 0x7A, 0xF9, 0x44, 0xDD, 0xB3, 0x00, + 0x1E, 0x35, 0xD8, 0x6C, 0x4E, 0x21, 0x99, 0xD9, + 0x76, 0x10, 0x4B, 0x6A, 0xE3, 0x17, 0x50, 0xA3, + 0x6A, 0x72, 0x6E, 0xD2, 0x85, 0x06, 0x4F, 0x59, + 0x81, 0xB5, 0x03, 0x88, 0x9F, 0xEF, 0x82, 0x2F, + 0xCD, 0xC2, 0x89, 0x8D, 0xDD, 0xB7, 0x88, 0x9A + }, + { + 0xE4, 0xB5, 0x56, 0x60, 0x33, 0x86, 0x95, 0x72, + 0xED, 0xFD, 0x87, 0x47, 0x9A, 0x5B, 0xB7, 0x3C, + 0x80, 0xE8, 0x75, 0x9B, 0x91, 0x23, 0x28, 0x79, + 0xD9, 0x6B, 0x1D, 0xDA, 0x36, 0xC0, 0x12, 0x07, + 0x6E, 0xE5, 0xA2, 0xED, 0x7A, 0xE2, 0xDE, 0x63, + 0xEF, 0x84, 0x06, 0xA0, 0x6A, 0xEA, 0x82, 0xC1, + 0x88, 0x03, 0x1B, 0x56, 0x0B, 0xEA, 0xFB, 0x58, + 0x3F, 0xB3, 0xDE, 0x9E, 0x57, 0x95, 0x2A, 0x7E + }, + { + 0xE1, 0xB3, 0xE7, 0xED, 0x86, 0x7F, 0x6C, 0x94, + 0x84, 0xA2, 0xA9, 0x7F, 0x77, 0x15, 0xF2, 0x5E, + 0x25, 0x29, 0x4E, 0x99, 0x2E, 0x41, 0xF6, 0xA7, + 0xC1, 0x61, 0xFF, 0xC2, 0xAD, 0xC6, 0xDA, 0xAE, + 0xB7, 0x11, 0x31, 0x02, 0xD5, 0xE6, 0x09, 0x02, + 0x87, 0xFE, 0x6A, 0xD9, 0x4C, 0xE5, 0xD6, 0xB7, + 0x39, 0xC6, 0xCA, 0x24, 0x0B, 0x05, 0xC7, 0x6F, + 0xB7, 0x3F, 0x25, 0xDD, 0x02, 0x4B, 0xF9, 0x35 + }, + { + 0x85, 0xFD, 0x08, 0x5F, 0xDC, 0x12, 0xA0, 0x80, + 0x98, 0x3D, 0xF0, 0x7B, 0xD7, 0x01, 0x2B, 0x0D, + 0x40, 0x2A, 0x0F, 0x40, 0x43, 0xFC, 0xB2, 0x77, + 0x5A, 0xDF, 0x0B, 0xAD, 0x17, 0x4F, 0x9B, 0x08, + 0xD1, 0x67, 0x6E, 0x47, 0x69, 0x85, 0x78, 0x5C, + 0x0A, 0x5D, 0xCC, 0x41, 0xDB, 0xFF, 0x6D, 0x95, + 0xEF, 0x4D, 0x66, 0xA3, 0xFB, 0xDC, 0x4A, 0x74, + 0xB8, 0x2B, 0xA5, 0x2D, 0xA0, 0x51, 0x2B, 0x74 + }, + { + 0xAE, 0xD8, 0xFA, 0x76, 0x4B, 0x0F, 0xBF, 0xF8, + 0x21, 0xE0, 0x52, 0x33, 0xD2, 0xF7, 0xB0, 0x90, + 0x0E, 0xC4, 0x4D, 0x82, 0x6F, 0x95, 0xE9, 0x3C, + 0x34, 0x3C, 0x1B, 0xC3, 0xBA, 0x5A, 0x24, 0x37, + 0x4B, 0x1D, 0x61, 0x6E, 0x7E, 0x7A, 0xBA, 0x45, + 0x3A, 0x0A, 0xDA, 0x5E, 0x4F, 0xAB, 0x53, 0x82, + 0x40, 0x9E, 0x0D, 0x42, 0xCE, 0x9C, 0x2B, 0xC7, + 0xFB, 0x39, 0xA9, 0x9C, 0x34, 0x0C, 0x20, 0xF0 + }, + { + 0x7B, 0xA3, 0xB2, 0xE2, 0x97, 0x23, 0x35, 0x22, + 0xEE, 0xB3, 0x43, 0xBD, 0x3E, 0xBC, 0xFD, 0x83, + 0x5A, 0x04, 0x00, 0x77, 0x35, 0xE8, 0x7F, 0x0C, + 0xA3, 0x00, 0xCB, 0xEE, 0x6D, 0x41, 0x65, 0x65, + 0x16, 0x21, 0x71, 0x58, 0x1E, 0x40, 0x20, 0xFF, + 0x4C, 0xF1, 0x76, 0x45, 0x0F, 0x12, 0x91, 0xEA, + 0x22, 0x85, 0xCB, 0x9E, 0xBF, 0xFE, 0x4C, 0x56, + 0x66, 0x06, 0x27, 0x68, 0x51, 0x45, 0x05, 0x1C + }, + { + 0xDE, 0x74, 0x8B, 0xCF, 0x89, 0xEC, 0x88, 0x08, + 0x47, 0x21, 0xE1, 0x6B, 0x85, 0xF3, 0x0A, 0xDB, + 0x1A, 0x61, 0x34, 0xD6, 0x64, 0xB5, 0x84, 0x35, + 0x69, 0xBA, 0xBC, 0x5B, 0xBD, 0x1A, 0x15, 0xCA, + 0x9B, 0x61, 0x80, 0x3C, 0x90, 0x1A, 0x4F, 0xEF, + 0x32, 0x96, 0x5A, 0x17, 0x49, 0xC9, 0xF3, 0xA4, + 0xE2, 0x43, 0xE1, 0x73, 0x93, 0x9D, 0xC5, 0xA8, + 0xDC, 0x49, 0x5C, 0x67, 0x1A, 0xB5, 0x21, 0x45 + }, + { + 0xAA, 0xF4, 0xD2, 0xBD, 0xF2, 0x00, 0xA9, 0x19, + 0x70, 0x6D, 0x98, 0x42, 0xDC, 0xE1, 0x6C, 0x98, + 0x14, 0x0D, 0x34, 0xBC, 0x43, 0x3D, 0xF3, 0x20, + 0xAB, 0xA9, 0xBD, 0x42, 0x9E, 0x54, 0x9A, 0xA7, + 0xA3, 0x39, 0x76, 0x52, 0xA4, 0xD7, 0x68, 0x27, + 0x77, 0x86, 0xCF, 0x99, 0x3C, 0xDE, 0x23, 0x38, + 0x67, 0x3E, 0xD2, 0xE6, 0xB6, 0x6C, 0x96, 0x1F, + 0xEF, 0xB8, 0x2C, 0xD2, 0x0C, 0x93, 0x33, 0x8F + }, + { + 0xC4, 0x08, 0x21, 0x89, 0x68, 0xB7, 0x88, 0xBF, + 0x86, 0x4F, 0x09, 0x97, 0xE6, 0xBC, 0x4C, 0x3D, + 0xBA, 0x68, 0xB2, 0x76, 0xE2, 0x12, 0x5A, 0x48, + 0x43, 0x29, 0x60, 0x52, 0xFF, 0x93, 0xBF, 0x57, + 0x67, 0xB8, 0xCD, 0xCE, 0x71, 0x31, 0xF0, 0x87, + 0x64, 0x30, 0xC1, 0x16, 0x5F, 0xEC, 0x6C, 0x4F, + 0x47, 0xAD, 0xAA, 0x4F, 0xD8, 0xBC, 0xFA, 0xCE, + 0xF4, 0x63, 0xB5, 0xD3, 0xD0, 0xFA, 0x61, 0xA0 + }, + { + 0x76, 0xD2, 0xD8, 0x19, 0xC9, 0x2B, 0xCE, 0x55, + 0xFA, 0x8E, 0x09, 0x2A, 0xB1, 0xBF, 0x9B, 0x9E, + 0xAB, 0x23, 0x7A, 0x25, 0x26, 0x79, 0x86, 0xCA, + 0xCF, 0x2B, 0x8E, 0xE1, 0x4D, 0x21, 0x4D, 0x73, + 0x0D, 0xC9, 0xA5, 0xAA, 0x2D, 0x7B, 0x59, 0x6E, + 0x86, 0xA1, 0xFD, 0x8F, 0xA0, 0x80, 0x4C, 0x77, + 0x40, 0x2D, 0x2F, 0xCD, 0x45, 0x08, 0x36, 0x88, + 0xB2, 0x18, 0xB1, 0xCD, 0xFA, 0x0D, 0xCB, 0xCB + }, + { + 0x72, 0x06, 0x5E, 0xE4, 0xDD, 0x91, 0xC2, 0xD8, + 0x50, 0x9F, 0xA1, 0xFC, 0x28, 0xA3, 0x7C, 0x7F, + 0xC9, 0xFA, 0x7D, 0x5B, 0x3F, 0x8A, 0xD3, 0xD0, + 0xD7, 0xA2, 0x56, 0x26, 0xB5, 0x7B, 0x1B, 0x44, + 0x78, 0x8D, 0x4C, 0xAF, 0x80, 0x62, 0x90, 0x42, + 0x5F, 0x98, 0x90, 0xA3, 0xA2, 0xA3, 0x5A, 0x90, + 0x5A, 0xB4, 0xB3, 0x7A, 0xCF, 0xD0, 0xDA, 0x6E, + 0x45, 0x17, 0xB2, 0x52, 0x5C, 0x96, 0x51, 0xE4 + }, + { + 0x64, 0x47, 0x5D, 0xFE, 0x76, 0x00, 0xD7, 0x17, + 0x1B, 0xEA, 0x0B, 0x39, 0x4E, 0x27, 0xC9, 0xB0, + 0x0D, 0x8E, 0x74, 0xDD, 0x1E, 0x41, 0x6A, 0x79, + 0x47, 0x36, 0x82, 0xAD, 0x3D, 0xFD, 0xBB, 0x70, + 0x66, 0x31, 0x55, 0x80, 0x55, 0xCF, 0xC8, 0xA4, + 0x0E, 0x07, 0xBD, 0x01, 0x5A, 0x45, 0x40, 0xDC, + 0xDE, 0xA1, 0x58, 0x83, 0xCB, 0xBF, 0x31, 0x41, + 0x2D, 0xF1, 0xDE, 0x1C, 0xD4, 0x15, 0x2B, 0x91 + }, + { + 0x12, 0xCD, 0x16, 0x74, 0xA4, 0x48, 0x8A, 0x5D, + 0x7C, 0x2B, 0x31, 0x60, 0xD2, 0xE2, 0xC4, 0xB5, + 0x83, 0x71, 0xBE, 0xDA, 0xD7, 0x93, 0x41, 0x8D, + 0x6F, 0x19, 0xC6, 0xEE, 0x38, 0x5D, 0x70, 0xB3, + 0xE0, 0x67, 0x39, 0x36, 0x9D, 0x4D, 0xF9, 0x10, + 0xED, 0xB0, 0xB0, 0xA5, 0x4C, 0xBF, 0xF4, 0x3D, + 0x54, 0x54, 0x4C, 0xD3, 0x7A, 0xB3, 0xA0, 0x6C, + 0xFA, 0x0A, 0x3D, 0xDA, 0xC8, 0xB6, 0x6C, 0x89 + }, + { + 0x60, 0x75, 0x69, 0x66, 0x47, 0x9D, 0xED, 0xC6, + 0xDD, 0x4B, 0xCF, 0xF8, 0xEA, 0x7D, 0x1D, 0x4C, + 0xE4, 0xD4, 0xAF, 0x2E, 0x7B, 0x09, 0x7E, 0x32, + 0xE3, 0x76, 0x35, 0x18, 0x44, 0x11, 0x47, 0xCC, + 0x12, 0xB3, 0xC0, 0xEE, 0x6D, 0x2E, 0xCA, 0xBF, + 0x11, 0x98, 0xCE, 0xC9, 0x2E, 0x86, 0xA3, 0x61, + 0x6F, 0xBA, 0x4F, 0x4E, 0x87, 0x2F, 0x58, 0x25, + 0x33, 0x0A, 0xDB, 0xB4, 0xC1, 0xDE, 0xE4, 0x44 + }, + { + 0xA7, 0x80, 0x3B, 0xCB, 0x71, 0xBC, 0x1D, 0x0F, + 0x43, 0x83, 0xDD, 0xE1, 0xE0, 0x61, 0x2E, 0x04, + 0xF8, 0x72, 0xB7, 0x15, 0xAD, 0x30, 0x81, 0x5C, + 0x22, 0x49, 0xCF, 0x34, 0xAB, 0xB8, 0xB0, 0x24, + 0x91, 0x5C, 0xB2, 0xFC, 0x9F, 0x4E, 0x7C, 0xC4, + 0xC8, 0xCF, 0xD4, 0x5B, 0xE2, 0xD5, 0xA9, 0x1E, + 0xAB, 0x09, 0x41, 0xC7, 0xD2, 0x70, 0xE2, 0xDA, + 0x4C, 0xA4, 0xA9, 0xF7, 0xAC, 0x68, 0x66, 0x3A + }, + { + 0xB8, 0x4E, 0xF6, 0xA7, 0x22, 0x9A, 0x34, 0xA7, + 0x50, 0xD9, 0xA9, 0x8E, 0xE2, 0x52, 0x98, 0x71, + 0x81, 0x6B, 0x87, 0xFB, 0xE3, 0xBC, 0x45, 0xB4, + 0x5F, 0xA5, 0xAE, 0x82, 0xD5, 0x14, 0x15, 0x40, + 0x21, 0x11, 0x65, 0xC3, 0xC5, 0xD7, 0xA7, 0x47, + 0x6B, 0xA5, 0xA4, 0xAA, 0x06, 0xD6, 0x64, 0x76, + 0xF0, 0xD9, 0xDC, 0x49, 0xA3, 0xF1, 0xEE, 0x72, + 0xC3, 0xAC, 0xAB, 0xD4, 0x98, 0x96, 0x74, 0x14 + }, + { + 0xFA, 0xE4, 0xB6, 0xD8, 0xEF, 0xC3, 0xF8, 0xC8, + 0xE6, 0x4D, 0x00, 0x1D, 0xAB, 0xEC, 0x3A, 0x21, + 0xF5, 0x44, 0xE8, 0x27, 0x14, 0x74, 0x52, 0x51, + 0xB2, 0xB4, 0xB3, 0x93, 0xF2, 0xF4, 0x3E, 0x0D, + 0xA3, 0xD4, 0x03, 0xC6, 0x4D, 0xB9, 0x5A, 0x2C, + 0xB6, 0xE2, 0x3E, 0xBB, 0x7B, 0x9E, 0x94, 0xCD, + 0xD5, 0xDD, 0xAC, 0x54, 0xF0, 0x7C, 0x4A, 0x61, + 0xBD, 0x3C, 0xB1, 0x0A, 0xA6, 0xF9, 0x3B, 0x49 + }, + { + 0x34, 0xF7, 0x28, 0x66, 0x05, 0xA1, 0x22, 0x36, + 0x95, 0x40, 0x14, 0x1D, 0xED, 0x79, 0xB8, 0x95, + 0x72, 0x55, 0xDA, 0x2D, 0x41, 0x55, 0xAB, 0xBF, + 0x5A, 0x8D, 0xBB, 0x89, 0xC8, 0xEB, 0x7E, 0xDE, + 0x8E, 0xEE, 0xF1, 0xDA, 0xA4, 0x6D, 0xC2, 0x9D, + 0x75, 0x1D, 0x04, 0x5D, 0xC3, 0xB1, 0xD6, 0x58, + 0xBB, 0x64, 0xB8, 0x0F, 0xF8, 0x58, 0x9E, 0xDD, + 0xB3, 0x82, 0x4B, 0x13, 0xDA, 0x23, 0x5A, 0x6B + }, + { + 0x3B, 0x3B, 0x48, 0x43, 0x4B, 0xE2, 0x7B, 0x9E, + 0xAB, 0xAB, 0xBA, 0x43, 0xBF, 0x6B, 0x35, 0xF1, + 0x4B, 0x30, 0xF6, 0xA8, 0x8D, 0xC2, 0xE7, 0x50, + 0xC3, 0x58, 0x47, 0x0D, 0x6B, 0x3A, 0xA3, 0xC1, + 0x8E, 0x47, 0xDB, 0x40, 0x17, 0xFA, 0x55, 0x10, + 0x6D, 0x82, 0x52, 0xF0, 0x16, 0x37, 0x1A, 0x00, + 0xF5, 0xF8, 0xB0, 0x70, 0xB7, 0x4B, 0xA5, 0xF2, + 0x3C, 0xFF, 0xC5, 0x51, 0x1C, 0x9F, 0x09, 0xF0 + }, + { + 0xBA, 0x28, 0x9E, 0xBD, 0x65, 0x62, 0xC4, 0x8C, + 0x3E, 0x10, 0xA8, 0xAD, 0x6C, 0xE0, 0x2E, 0x73, + 0x43, 0x3D, 0x1E, 0x93, 0xD7, 0xC9, 0x27, 0x9D, + 0x4D, 0x60, 0xA7, 0xE8, 0x79, 0xEE, 0x11, 0xF4, + 0x41, 0xA0, 0x00, 0xF4, 0x8E, 0xD9, 0xF7, 0xC4, + 0xED, 0x87, 0xA4, 0x51, 0x36, 0xD7, 0xDC, 0xCD, + 0xCA, 0x48, 0x21, 0x09, 0xC7, 0x8A, 0x51, 0x06, + 0x2B, 0x3B, 0xA4, 0x04, 0x4A, 0xDA, 0x24, 0x69 + }, + { + 0x02, 0x29, 0x39, 0xE2, 0x38, 0x6C, 0x5A, 0x37, + 0x04, 0x98, 0x56, 0xC8, 0x50, 0xA2, 0xBB, 0x10, + 0xA1, 0x3D, 0xFE, 0xA4, 0x21, 0x2B, 0x4C, 0x73, + 0x2A, 0x88, 0x40, 0xA9, 0xFF, 0xA5, 0xFA, 0xF5, + 0x48, 0x75, 0xC5, 0x44, 0x88, 0x16, 0xB2, 0x78, + 0x5A, 0x00, 0x7D, 0xA8, 0xA8, 0xD2, 0xBC, 0x7D, + 0x71, 0xA5, 0x4E, 0x4E, 0x65, 0x71, 0xF1, 0x0B, + 0x60, 0x0C, 0xBD, 0xB2, 0x5D, 0x13, 0xED, 0xE3 + }, + { + 0xE6, 0xFE, 0xC1, 0x9D, 0x89, 0xCE, 0x87, 0x17, + 0xB1, 0xA0, 0x87, 0x02, 0x46, 0x70, 0xFE, 0x02, + 0x6F, 0x6C, 0x7C, 0xBD, 0xA1, 0x1C, 0xAE, 0xF9, + 0x59, 0xBB, 0x2D, 0x35, 0x1B, 0xF8, 0x56, 0xF8, + 0x05, 0x5D, 0x1C, 0x0E, 0xBD, 0xAA, 0xA9, 0xD1, + 0xB1, 0x78, 0x86, 0xFC, 0x2C, 0x56, 0x2B, 0x5E, + 0x99, 0x64, 0x2F, 0xC0, 0x64, 0x71, 0x0C, 0x0D, + 0x34, 0x88, 0xA0, 0x2B, 0x5E, 0xD7, 0xF6, 0xFD + }, + { + 0x94, 0xC9, 0x6F, 0x02, 0xA8, 0xF5, 0x76, 0xAC, + 0xA3, 0x2B, 0xA6, 0x1C, 0x2B, 0x20, 0x6F, 0x90, + 0x72, 0x85, 0xD9, 0x29, 0x9B, 0x83, 0xAC, 0x17, + 0x5C, 0x20, 0x9A, 0x8D, 0x43, 0xD5, 0x3B, 0xFE, + 0x68, 0x3D, 0xD1, 0xD8, 0x3E, 0x75, 0x49, 0xCB, + 0x90, 0x6C, 0x28, 0xF5, 0x9A, 0xB7, 0xC4, 0x6F, + 0x87, 0x51, 0x36, 0x6A, 0x28, 0xC3, 0x9D, 0xD5, + 0xFE, 0x26, 0x93, 0xC9, 0x01, 0x96, 0x66, 0xC8 + }, + { + 0x31, 0xA0, 0xCD, 0x21, 0x5E, 0xBD, 0x2C, 0xB6, + 0x1D, 0xE5, 0xB9, 0xED, 0xC9, 0x1E, 0x61, 0x95, + 0xE3, 0x1C, 0x59, 0xA5, 0x64, 0x8D, 0x5C, 0x9F, + 0x73, 0x7E, 0x12, 0x5B, 0x26, 0x05, 0x70, 0x8F, + 0x2E, 0x32, 0x5A, 0xB3, 0x38, 0x1C, 0x8D, 0xCE, + 0x1A, 0x3E, 0x95, 0x88, 0x86, 0xF1, 0xEC, 0xDC, + 0x60, 0x31, 0x8F, 0x88, 0x2C, 0xFE, 0x20, 0xA2, + 0x41, 0x91, 0x35, 0x2E, 0x61, 0x7B, 0x0F, 0x21 + }, + { + 0x91, 0xAB, 0x50, 0x4A, 0x52, 0x2D, 0xCE, 0x78, + 0x77, 0x9F, 0x4C, 0x6C, 0x6B, 0xA2, 0xE6, 0xB6, + 0xDB, 0x55, 0x65, 0xC7, 0x6D, 0x3E, 0x7E, 0x7C, + 0x92, 0x0C, 0xAF, 0x7F, 0x75, 0x7E, 0xF9, 0xDB, + 0x7C, 0x8F, 0xCF, 0x10, 0xE5, 0x7F, 0x03, 0x37, + 0x9E, 0xA9, 0xBF, 0x75, 0xEB, 0x59, 0x89, 0x5D, + 0x96, 0xE1, 0x49, 0x80, 0x0B, 0x6A, 0xAE, 0x01, + 0xDB, 0x77, 0x8B, 0xB9, 0x0A, 0xFB, 0xC9, 0x89 + }, + { + 0xD8, 0x5C, 0xAB, 0xC6, 0xBD, 0x5B, 0x1A, 0x01, + 0xA5, 0xAF, 0xD8, 0xC6, 0x73, 0x47, 0x40, 0xDA, + 0x9F, 0xD1, 0xC1, 0xAC, 0xC6, 0xDB, 0x29, 0xBF, + 0xC8, 0xA2, 0xE5, 0xB6, 0x68, 0xB0, 0x28, 0xB6, + 0xB3, 0x15, 0x4B, 0xFB, 0x87, 0x03, 0xFA, 0x31, + 0x80, 0x25, 0x1D, 0x58, 0x9A, 0xD3, 0x80, 0x40, + 0xCE, 0xB7, 0x07, 0xC4, 0xBA, 0xD1, 0xB5, 0x34, + 0x3C, 0xB4, 0x26, 0xB6, 0x1E, 0xAA, 0x49, 0xC1 + }, + { + 0xD6, 0x2E, 0xFB, 0xEC, 0x2C, 0xA9, 0xC1, 0xF8, + 0xBD, 0x66, 0xCE, 0x8B, 0x3F, 0x6A, 0x89, 0x8C, + 0xB3, 0xF7, 0x56, 0x6B, 0xA6, 0x56, 0x8C, 0x61, + 0x8A, 0xD1, 0xFE, 0xB2, 0xB6, 0x5B, 0x76, 0xC3, + 0xCE, 0x1D, 0xD2, 0x0F, 0x73, 0x95, 0x37, 0x2F, + 0xAF, 0x28, 0x42, 0x7F, 0x61, 0xC9, 0x27, 0x80, + 0x49, 0xCF, 0x01, 0x40, 0xDF, 0x43, 0x4F, 0x56, + 0x33, 0x04, 0x8C, 0x86, 0xB8, 0x1E, 0x03, 0x99 + }, + { + 0x7C, 0x8F, 0xDC, 0x61, 0x75, 0x43, 0x9E, 0x2C, + 0x3D, 0xB1, 0x5B, 0xAF, 0xA7, 0xFB, 0x06, 0x14, + 0x3A, 0x6A, 0x23, 0xBC, 0x90, 0xF4, 0x49, 0xE7, + 0x9D, 0xEE, 0xF7, 0x3C, 0x3D, 0x49, 0x2A, 0x67, + 0x17, 0x15, 0xC1, 0x93, 0xB6, 0xFE, 0xA9, 0xF0, + 0x36, 0x05, 0x0B, 0x94, 0x60, 0x69, 0x85, 0x6B, + 0x89, 0x7E, 0x08, 0xC0, 0x07, 0x68, 0xF5, 0xEE, + 0x5D, 0xDC, 0xF7, 0x0B, 0x7C, 0xD6, 0xD0, 0xE0 + }, + { + 0x58, 0x60, 0x2E, 0xE7, 0x46, 0x8E, 0x6B, 0xC9, + 0xDF, 0x21, 0xBD, 0x51, 0xB2, 0x3C, 0x00, 0x5F, + 0x72, 0xD6, 0xCB, 0x01, 0x3F, 0x0A, 0x1B, 0x48, + 0xCB, 0xEC, 0x5E, 0xCA, 0x29, 0x92, 0x99, 0xF9, + 0x7F, 0x09, 0xF5, 0x4A, 0x9A, 0x01, 0x48, 0x3E, + 0xAE, 0xB3, 0x15, 0xA6, 0x47, 0x8B, 0xAD, 0x37, + 0xBA, 0x47, 0xCA, 0x13, 0x47, 0xC7, 0xC8, 0xFC, + 0x9E, 0x66, 0x95, 0x59, 0x2C, 0x91, 0xD7, 0x23 + }, + { + 0x27, 0xF5, 0xB7, 0x9E, 0xD2, 0x56, 0xB0, 0x50, + 0x99, 0x3D, 0x79, 0x34, 0x96, 0xED, 0xF4, 0x80, + 0x7C, 0x1D, 0x85, 0xA7, 0xB0, 0xA6, 0x7C, 0x9C, + 0x4F, 0xA9, 0x98, 0x60, 0x75, 0x0B, 0x0A, 0xE6, + 0x69, 0x89, 0x67, 0x0A, 0x8F, 0xFD, 0x78, 0x56, + 0xD7, 0xCE, 0x41, 0x15, 0x99, 0xE5, 0x8C, 0x4D, + 0x77, 0xB2, 0x32, 0xA6, 0x2B, 0xEF, 0x64, 0xD1, + 0x52, 0x75, 0xBE, 0x46, 0xA6, 0x82, 0x35, 0xFF + }, + { + 0x39, 0x57, 0xA9, 0x76, 0xB9, 0xF1, 0x88, 0x7B, + 0xF0, 0x04, 0xA8, 0xDC, 0xA9, 0x42, 0xC9, 0x2D, + 0x2B, 0x37, 0xEA, 0x52, 0x60, 0x0F, 0x25, 0xE0, + 0xC9, 0xBC, 0x57, 0x07, 0xD0, 0x27, 0x9C, 0x00, + 0xC6, 0xE8, 0x5A, 0x83, 0x9B, 0x0D, 0x2D, 0x8E, + 0xB5, 0x9C, 0x51, 0xD9, 0x47, 0x88, 0xEB, 0xE6, + 0x24, 0x74, 0xA7, 0x91, 0xCA, 0xDF, 0x52, 0xCC, + 0xCF, 0x20, 0xF5, 0x07, 0x0B, 0x65, 0x73, 0xFC + }, + { + 0xEA, 0xA2, 0x37, 0x6D, 0x55, 0x38, 0x0B, 0xF7, + 0x72, 0xEC, 0xCA, 0x9C, 0xB0, 0xAA, 0x46, 0x68, + 0xC9, 0x5C, 0x70, 0x71, 0x62, 0xFA, 0x86, 0xD5, + 0x18, 0xC8, 0xCE, 0x0C, 0xA9, 0xBF, 0x73, 0x62, + 0xB9, 0xF2, 0xA0, 0xAD, 0xC3, 0xFF, 0x59, 0x92, + 0x2D, 0xF9, 0x21, 0xB9, 0x45, 0x67, 0xE8, 0x1E, + 0x45, 0x2F, 0x6C, 0x1A, 0x07, 0xFC, 0x81, 0x7C, + 0xEB, 0xE9, 0x96, 0x04, 0xB3, 0x50, 0x5D, 0x38 + }, + { + 0xC1, 0xE2, 0xC7, 0x8B, 0x6B, 0x27, 0x34, 0xE2, + 0x48, 0x0E, 0xC5, 0x50, 0x43, 0x4C, 0xB5, 0xD6, + 0x13, 0x11, 0x1A, 0xDC, 0xC2, 0x1D, 0x47, 0x55, + 0x45, 0xC3, 0xB1, 0xB7, 0xE6, 0xFF, 0x12, 0x44, + 0x44, 0x76, 0xE5, 0xC0, 0x55, 0x13, 0x2E, 0x22, + 0x29, 0xDC, 0x0F, 0x80, 0x70, 0x44, 0xBB, 0x91, + 0x9B, 0x1A, 0x56, 0x62, 0xDD, 0x38, 0xA9, 0xEE, + 0x65, 0xE2, 0x43, 0xA3, 0x91, 0x1A, 0xED, 0x1A + }, + { + 0x8A, 0xB4, 0x87, 0x13, 0x38, 0x9D, 0xD0, 0xFC, + 0xF9, 0xF9, 0x65, 0xD3, 0xCE, 0x66, 0xB1, 0xE5, + 0x59, 0xA1, 0xF8, 0xC5, 0x87, 0x41, 0xD6, 0x76, + 0x83, 0xCD, 0x97, 0x13, 0x54, 0xF4, 0x52, 0xE6, + 0x2D, 0x02, 0x07, 0xA6, 0x5E, 0x43, 0x6C, 0x5D, + 0x5D, 0x8F, 0x8E, 0xE7, 0x1C, 0x6A, 0xBF, 0xE5, + 0x0E, 0x66, 0x90, 0x04, 0xC3, 0x02, 0xB3, 0x1A, + 0x7E, 0xA8, 0x31, 0x1D, 0x4A, 0x91, 0x60, 0x51 + }, + { + 0x24, 0xCE, 0x0A, 0xDD, 0xAA, 0x4C, 0x65, 0x03, + 0x8B, 0xD1, 0xB1, 0xC0, 0xF1, 0x45, 0x2A, 0x0B, + 0x12, 0x87, 0x77, 0xAA, 0xBC, 0x94, 0xA2, 0x9D, + 0xF2, 0xFD, 0x6C, 0x7E, 0x2F, 0x85, 0xF8, 0xAB, + 0x9A, 0xC7, 0xEF, 0xF5, 0x16, 0xB0, 0xE0, 0xA8, + 0x25, 0xC8, 0x4A, 0x24, 0xCF, 0xE4, 0x92, 0xEA, + 0xAD, 0x0A, 0x63, 0x08, 0xE4, 0x6D, 0xD4, 0x2F, + 0xE8, 0x33, 0x3A, 0xB9, 0x71, 0xBB, 0x30, 0xCA + }, + { + 0x51, 0x54, 0xF9, 0x29, 0xEE, 0x03, 0x04, 0x5B, + 0x6B, 0x0C, 0x00, 0x04, 0xFA, 0x77, 0x8E, 0xDE, + 0xE1, 0xD1, 0x39, 0x89, 0x32, 0x67, 0xCC, 0x84, + 0x82, 0x5A, 0xD7, 0xB3, 0x6C, 0x63, 0xDE, 0x32, + 0x79, 0x8E, 0x4A, 0x16, 0x6D, 0x24, 0x68, 0x65, + 0x61, 0x35, 0x4F, 0x63, 0xB0, 0x07, 0x09, 0xA1, + 0x36, 0x4B, 0x3C, 0x24, 0x1D, 0xE3, 0xFE, 0xBF, + 0x07, 0x54, 0x04, 0x58, 0x97, 0x46, 0x7C, 0xD4 + }, + { + 0xE7, 0x4E, 0x90, 0x79, 0x20, 0xFD, 0x87, 0xBD, + 0x5A, 0xD6, 0x36, 0xDD, 0x11, 0x08, 0x5E, 0x50, + 0xEE, 0x70, 0x45, 0x9C, 0x44, 0x3E, 0x1C, 0xE5, + 0x80, 0x9A, 0xF2, 0xBC, 0x2E, 0xBA, 0x39, 0xF9, + 0xE6, 0xD7, 0x12, 0x8E, 0x0E, 0x37, 0x12, 0xC3, + 0x16, 0xDA, 0x06, 0xF4, 0x70, 0x5D, 0x78, 0xA4, + 0x83, 0x8E, 0x28, 0x12, 0x1D, 0x43, 0x44, 0xA2, + 0xC7, 0x9C, 0x5E, 0x0D, 0xB3, 0x07, 0xA6, 0x77 + }, + { + 0xBF, 0x91, 0xA2, 0x23, 0x34, 0xBA, 0xC2, 0x0F, + 0x3F, 0xD8, 0x06, 0x63, 0xB3, 0xCD, 0x06, 0xC4, + 0xE8, 0x80, 0x2F, 0x30, 0xE6, 0xB5, 0x9F, 0x90, + 0xD3, 0x03, 0x5C, 0xC9, 0x79, 0x8A, 0x21, 0x7E, + 0xD5, 0xA3, 0x1A, 0xBB, 0xDA, 0x7F, 0xA6, 0x84, + 0x28, 0x27, 0xBD, 0xF2, 0xA7, 0xA1, 0xC2, 0x1F, + 0x6F, 0xCF, 0xCC, 0xBB, 0x54, 0xC6, 0xC5, 0x29, + 0x26, 0xF3, 0x2D, 0xA8, 0x16, 0x26, 0x9B, 0xE1 + }, + { + 0xD9, 0xD5, 0xC7, 0x4B, 0xE5, 0x12, 0x1B, 0x0B, + 0xD7, 0x42, 0xF2, 0x6B, 0xFF, 0xB8, 0xC8, 0x9F, + 0x89, 0x17, 0x1F, 0x3F, 0x93, 0x49, 0x13, 0x49, + 0x2B, 0x09, 0x03, 0xC2, 0x71, 0xBB, 0xE2, 0xB3, + 0x39, 0x5E, 0xF2, 0x59, 0x66, 0x9B, 0xEF, 0x43, + 0xB5, 0x7F, 0x7F, 0xCC, 0x30, 0x27, 0xDB, 0x01, + 0x82, 0x3F, 0x6B, 0xAE, 0xE6, 0x6E, 0x4F, 0x9F, + 0xEA, 0xD4, 0xD6, 0x72, 0x6C, 0x74, 0x1F, 0xCE + }, + { + 0x50, 0xC8, 0xB8, 0xCF, 0x34, 0xCD, 0x87, 0x9F, + 0x80, 0xE2, 0xFA, 0xAB, 0x32, 0x30, 0xB0, 0xC0, + 0xE1, 0xCC, 0x3E, 0x9D, 0xCA, 0xDE, 0xB1, 0xB9, + 0xD9, 0x7A, 0xB9, 0x23, 0x41, 0x5D, 0xD9, 0xA1, + 0xFE, 0x38, 0xAD, 0xDD, 0x5C, 0x11, 0x75, 0x6C, + 0x67, 0x99, 0x0B, 0x25, 0x6E, 0x95, 0xAD, 0x6D, + 0x8F, 0x9F, 0xED, 0xCE, 0x10, 0xBF, 0x1C, 0x90, + 0x67, 0x9C, 0xDE, 0x0E, 0xCF, 0x1B, 0xE3, 0x47 + }, + { + 0x0A, 0x38, 0x6E, 0x7C, 0xD5, 0xDD, 0x9B, 0x77, + 0xA0, 0x35, 0xE0, 0x9F, 0xE6, 0xFE, 0xE2, 0xC8, + 0xCE, 0x61, 0xB5, 0x38, 0x3C, 0x87, 0xEA, 0x43, + 0x20, 0x50, 0x59, 0xC5, 0xE4, 0xCD, 0x4F, 0x44, + 0x08, 0x31, 0x9B, 0xB0, 0xA8, 0x23, 0x60, 0xF6, + 0xA5, 0x8E, 0x6C, 0x9C, 0xE3, 0xF4, 0x87, 0xC4, + 0x46, 0x06, 0x3B, 0xF8, 0x13, 0xBC, 0x6B, 0xA5, + 0x35, 0xE1, 0x7F, 0xC1, 0x82, 0x6C, 0xFC, 0x91 + }, + { + 0x1F, 0x14, 0x59, 0xCB, 0x6B, 0x61, 0xCB, 0xAC, + 0x5F, 0x0E, 0xFE, 0x8F, 0xC4, 0x87, 0x53, 0x8F, + 0x42, 0x54, 0x89, 0x87, 0xFC, 0xD5, 0x62, 0x21, + 0xCF, 0xA7, 0xBE, 0xB2, 0x25, 0x04, 0x76, 0x9E, + 0x79, 0x2C, 0x45, 0xAD, 0xFB, 0x1D, 0x6B, 0x3D, + 0x60, 0xD7, 0xB7, 0x49, 0xC8, 0xA7, 0x5B, 0x0B, + 0xDF, 0x14, 0xE8, 0xEA, 0x72, 0x1B, 0x95, 0xDC, + 0xA5, 0x38, 0xCA, 0x6E, 0x25, 0x71, 0x12, 0x09 + }, + { + 0xE5, 0x8B, 0x38, 0x36, 0xB7, 0xD8, 0xFE, 0xDB, + 0xB5, 0x0C, 0xA5, 0x72, 0x5C, 0x65, 0x71, 0xE7, + 0x4C, 0x07, 0x85, 0xE9, 0x78, 0x21, 0xDA, 0xB8, + 0xB6, 0x29, 0x8C, 0x10, 0xE4, 0xC0, 0x79, 0xD4, + 0xA6, 0xCD, 0xF2, 0x2F, 0x0F, 0xED, 0xB5, 0x50, + 0x32, 0x92, 0x5C, 0x16, 0x74, 0x81, 0x15, 0xF0, + 0x1A, 0x10, 0x5E, 0x77, 0xE0, 0x0C, 0xEE, 0x3D, + 0x07, 0x92, 0x4D, 0xC0, 0xD8, 0xF9, 0x06, 0x59 + }, + { + 0xB9, 0x29, 0xCC, 0x65, 0x05, 0xF0, 0x20, 0x15, + 0x86, 0x72, 0xDE, 0xDA, 0x56, 0xD0, 0xDB, 0x08, + 0x1A, 0x2E, 0xE3, 0x4C, 0x00, 0xC1, 0x10, 0x00, + 0x29, 0xBD, 0xF8, 0xEA, 0x98, 0x03, 0x4F, 0xA4, + 0xBF, 0x3E, 0x86, 0x55, 0xEC, 0x69, 0x7F, 0xE3, + 0x6F, 0x40, 0x55, 0x3C, 0x5B, 0xB4, 0x68, 0x01, + 0x64, 0x4A, 0x62, 0x7D, 0x33, 0x42, 0xF4, 0xFC, + 0x92, 0xB6, 0x1F, 0x03, 0x29, 0x0F, 0xB3, 0x81 + }, + { + 0x72, 0xD3, 0x53, 0x99, 0x4B, 0x49, 0xD3, 0xE0, + 0x31, 0x53, 0x92, 0x9A, 0x1E, 0x4D, 0x4F, 0x18, + 0x8E, 0xE5, 0x8A, 0xB9, 0xE7, 0x2E, 0xE8, 0xE5, + 0x12, 0xF2, 0x9B, 0xC7, 0x73, 0x91, 0x38, 0x19, + 0xCE, 0x05, 0x7D, 0xDD, 0x70, 0x02, 0xC0, 0x43, + 0x3E, 0xE0, 0xA1, 0x61, 0x14, 0xE3, 0xD1, 0x56, + 0xDD, 0x2C, 0x4A, 0x7E, 0x80, 0xEE, 0x53, 0x37, + 0x8B, 0x86, 0x70, 0xF2, 0x3E, 0x33, 0xEF, 0x56 + }, + { + 0xC7, 0x0E, 0xF9, 0xBF, 0xD7, 0x75, 0xD4, 0x08, + 0x17, 0x67, 0x37, 0xA0, 0x73, 0x6D, 0x68, 0x51, + 0x7C, 0xE1, 0xAA, 0xAD, 0x7E, 0x81, 0xA9, 0x3C, + 0x8C, 0x1E, 0xD9, 0x67, 0xEA, 0x21, 0x4F, 0x56, + 0xC8, 0xA3, 0x77, 0xB1, 0x76, 0x3E, 0x67, 0x66, + 0x15, 0xB6, 0x0F, 0x39, 0x88, 0x24, 0x1E, 0xAE, + 0x6E, 0xAB, 0x96, 0x85, 0xA5, 0x12, 0x49, 0x29, + 0xD2, 0x81, 0x88, 0xF2, 0x9E, 0xAB, 0x06, 0xF7 + }, + { + 0xC2, 0x30, 0xF0, 0x80, 0x26, 0x79, 0xCB, 0x33, + 0x82, 0x2E, 0xF8, 0xB3, 0xB2, 0x1B, 0xF7, 0xA9, + 0xA2, 0x89, 0x42, 0x09, 0x29, 0x01, 0xD7, 0xDA, + 0xC3, 0x76, 0x03, 0x00, 0x83, 0x10, 0x26, 0xCF, + 0x35, 0x4C, 0x92, 0x32, 0xDF, 0x3E, 0x08, 0x4D, + 0x99, 0x03, 0x13, 0x0C, 0x60, 0x1F, 0x63, 0xC1, + 0xF4, 0xA4, 0xA4, 0xB8, 0x10, 0x6E, 0x46, 0x8C, + 0xD4, 0x43, 0xBB, 0xE5, 0xA7, 0x34, 0xF4, 0x5F + }, + { + 0x6F, 0x43, 0x09, 0x4C, 0xAF, 0xB5, 0xEB, 0xF1, + 0xF7, 0xA4, 0x93, 0x7E, 0xC5, 0x0F, 0x56, 0xA4, + 0xC9, 0xDA, 0x30, 0x3C, 0xBB, 0x55, 0xAC, 0x1F, + 0x27, 0xF1, 0xF1, 0x97, 0x6C, 0xD9, 0x6B, 0xED, + 0xA9, 0x46, 0x4F, 0x0E, 0x7B, 0x9C, 0x54, 0x62, + 0x0B, 0x8A, 0x9F, 0xBA, 0x98, 0x31, 0x64, 0xB8, + 0xBE, 0x35, 0x78, 0x42, 0x5A, 0x02, 0x4F, 0x5F, + 0xE1, 0x99, 0xC3, 0x63, 0x56, 0xB8, 0x89, 0x72 + }, + { + 0x37, 0x45, 0x27, 0x3F, 0x4C, 0x38, 0x22, 0x5D, + 0xB2, 0x33, 0x73, 0x81, 0x87, 0x1A, 0x0C, 0x6A, + 0xAF, 0xD3, 0xAF, 0x9B, 0x01, 0x8C, 0x88, 0xAA, + 0x02, 0x02, 0x58, 0x50, 0xA5, 0xDC, 0x3A, 0x42, + 0xA1, 0xA3, 0xE0, 0x3E, 0x56, 0xCB, 0xF1, 0xB0, + 0x87, 0x6D, 0x63, 0xA4, 0x41, 0xF1, 0xD2, 0x85, + 0x6A, 0x39, 0xB8, 0x80, 0x1E, 0xB5, 0xAF, 0x32, + 0x52, 0x01, 0xC4, 0x15, 0xD6, 0x5E, 0x97, 0xFE + }, + { + 0xC5, 0x0C, 0x44, 0xCC, 0xA3, 0xEC, 0x3E, 0xDA, + 0xAE, 0x77, 0x9A, 0x7E, 0x17, 0x94, 0x50, 0xEB, + 0xDD, 0xA2, 0xF9, 0x70, 0x67, 0xC6, 0x90, 0xAA, + 0x6C, 0x5A, 0x4A, 0xC7, 0xC3, 0x01, 0x39, 0xBB, + 0x27, 0xC0, 0xDF, 0x4D, 0xB3, 0x22, 0x0E, 0x63, + 0xCB, 0x11, 0x0D, 0x64, 0xF3, 0x7F, 0xFE, 0x07, + 0x8D, 0xB7, 0x26, 0x53, 0xE2, 0xDA, 0xAC, 0xF9, + 0x3A, 0xE3, 0xF0, 0xA2, 0xD1, 0xA7, 0xEB, 0x2E + }, + { + 0x8A, 0xEF, 0x26, 0x3E, 0x38, 0x5C, 0xBC, 0x61, + 0xE1, 0x9B, 0x28, 0x91, 0x42, 0x43, 0x26, 0x2A, + 0xF5, 0xAF, 0xE8, 0x72, 0x6A, 0xF3, 0xCE, 0x39, + 0xA7, 0x9C, 0x27, 0x02, 0x8C, 0xF3, 0xEC, 0xD3, + 0xF8, 0xD2, 0xDF, 0xD9, 0xCF, 0xC9, 0xAD, 0x91, + 0xB5, 0x8F, 0x6F, 0x20, 0x77, 0x8F, 0xD5, 0xF0, + 0x28, 0x94, 0xA3, 0xD9, 0x1C, 0x7D, 0x57, 0xD1, + 0xE4, 0xB8, 0x66, 0xA7, 0xF3, 0x64, 0xB6, 0xBE + }, + { + 0x28, 0x69, 0x61, 0x41, 0xDE, 0x6E, 0x2D, 0x9B, + 0xCB, 0x32, 0x35, 0x57, 0x8A, 0x66, 0x16, 0x6C, + 0x14, 0x48, 0xD3, 0xE9, 0x05, 0xA1, 0xB4, 0x82, + 0xD4, 0x23, 0xBE, 0x4B, 0xC5, 0x36, 0x9B, 0xC8, + 0xC7, 0x4D, 0xAE, 0x0A, 0xCC, 0x9C, 0xC1, 0x23, + 0xE1, 0xD8, 0xDD, 0xCE, 0x9F, 0x97, 0x91, 0x7E, + 0x8C, 0x01, 0x9C, 0x55, 0x2D, 0xA3, 0x2D, 0x39, + 0xD2, 0x21, 0x9B, 0x9A, 0xBF, 0x0F, 0xA8, 0xC8 + }, + { + 0x2F, 0xB9, 0xEB, 0x20, 0x85, 0x83, 0x01, 0x81, + 0x90, 0x3A, 0x9D, 0xAF, 0xE3, 0xDB, 0x42, 0x8E, + 0xE1, 0x5B, 0xE7, 0x66, 0x22, 0x24, 0xEF, 0xD6, + 0x43, 0x37, 0x1F, 0xB2, 0x56, 0x46, 0xAE, 0xE7, + 0x16, 0xE5, 0x31, 0xEC, 0xA6, 0x9B, 0x2B, 0xDC, + 0x82, 0x33, 0xF1, 0xA8, 0x08, 0x1F, 0xA4, 0x3D, + 0xA1, 0x50, 0x03, 0x02, 0x97, 0x5A, 0x77, 0xF4, + 0x2F, 0xA5, 0x92, 0x13, 0x67, 0x10, 0xE9, 0xDC + }, + { + 0x66, 0xF9, 0xA7, 0x14, 0x3F, 0x7A, 0x33, 0x14, + 0xA6, 0x69, 0xBF, 0x2E, 0x24, 0xBB, 0xB3, 0x50, + 0x14, 0x26, 0x1D, 0x63, 0x9F, 0x49, 0x5B, 0x6C, + 0x9C, 0x1F, 0x10, 0x4F, 0xE8, 0xE3, 0x20, 0xAC, + 0xA6, 0x0D, 0x45, 0x50, 0xD6, 0x9D, 0x52, 0xED, + 0xBD, 0x5A, 0x3C, 0xDE, 0xB4, 0x01, 0x4A, 0xE6, + 0x5B, 0x1D, 0x87, 0xAA, 0x77, 0x0B, 0x69, 0xAE, + 0x5C, 0x15, 0xF4, 0x33, 0x0B, 0x0B, 0x0A, 0xD8 + }, + { + 0xF4, 0xC4, 0xDD, 0x1D, 0x59, 0x4C, 0x35, 0x65, + 0xE3, 0xE2, 0x5C, 0xA4, 0x3D, 0xAD, 0x82, 0xF6, + 0x2A, 0xBE, 0xA4, 0x83, 0x5E, 0xD4, 0xCD, 0x81, + 0x1B, 0xCD, 0x97, 0x5E, 0x46, 0x27, 0x98, 0x28, + 0xD4, 0x4D, 0x4C, 0x62, 0xC3, 0x67, 0x9F, 0x1B, + 0x7F, 0x7B, 0x9D, 0xD4, 0x57, 0x1D, 0x7B, 0x49, + 0x55, 0x73, 0x47, 0xB8, 0xC5, 0x46, 0x0C, 0xBD, + 0xC1, 0xBE, 0xF6, 0x90, 0xFB, 0x2A, 0x08, 0xC0 + }, + { + 0x8F, 0x1D, 0xC9, 0x64, 0x9C, 0x3A, 0x84, 0x55, + 0x1F, 0x8F, 0x6E, 0x91, 0xCA, 0xC6, 0x82, 0x42, + 0xA4, 0x3B, 0x1F, 0x8F, 0x32, 0x8E, 0xE9, 0x22, + 0x80, 0x25, 0x73, 0x87, 0xFA, 0x75, 0x59, 0xAA, + 0x6D, 0xB1, 0x2E, 0x4A, 0xEA, 0xDC, 0x2D, 0x26, + 0x09, 0x91, 0x78, 0x74, 0x9C, 0x68, 0x64, 0xB3, + 0x57, 0xF3, 0xF8, 0x3B, 0x2F, 0xB3, 0xEF, 0xA8, + 0xD2, 0xA8, 0xDB, 0x05, 0x6B, 0xED, 0x6B, 0xCC + }, + { + 0x31, 0x39, 0xC1, 0xA7, 0xF9, 0x7A, 0xFD, 0x16, + 0x75, 0xD4, 0x60, 0xEB, 0xBC, 0x07, 0xF2, 0x72, + 0x8A, 0xA1, 0x50, 0xDF, 0x84, 0x96, 0x24, 0x51, + 0x1E, 0xE0, 0x4B, 0x74, 0x3B, 0xA0, 0xA8, 0x33, + 0x09, 0x2F, 0x18, 0xC1, 0x2D, 0xC9, 0x1B, 0x4D, + 0xD2, 0x43, 0xF3, 0x33, 0x40, 0x2F, 0x59, 0xFE, + 0x28, 0xAB, 0xDB, 0xBB, 0xAE, 0x30, 0x1E, 0x7B, + 0x65, 0x9C, 0x7A, 0x26, 0xD5, 0xC0, 0xF9, 0x79 + }, + { + 0x06, 0xF9, 0x4A, 0x29, 0x96, 0x15, 0x8A, 0x81, + 0x9F, 0xE3, 0x4C, 0x40, 0xDE, 0x3C, 0xF0, 0x37, + 0x9F, 0xD9, 0xFB, 0x85, 0xB3, 0xE3, 0x63, 0xBA, + 0x39, 0x26, 0xA0, 0xE7, 0xD9, 0x60, 0xE3, 0xF4, + 0xC2, 0xE0, 0xC7, 0x0C, 0x7C, 0xE0, 0xCC, 0xB2, + 0xA6, 0x4F, 0xC2, 0x98, 0x69, 0xF6, 0xE7, 0xAB, + 0x12, 0xBD, 0x4D, 0x3F, 0x14, 0xFC, 0xE9, 0x43, + 0x27, 0x90, 0x27, 0xE7, 0x85, 0xFB, 0x5C, 0x29 + }, + { + 0xC2, 0x9C, 0x39, 0x9E, 0xF3, 0xEE, 0xE8, 0x96, + 0x1E, 0x87, 0x56, 0x5C, 0x1C, 0xE2, 0x63, 0x92, + 0x5F, 0xC3, 0xD0, 0xCE, 0x26, 0x7D, 0x13, 0xE4, + 0x8D, 0xD9, 0xE7, 0x32, 0xEE, 0x67, 0xB0, 0xF6, + 0x9F, 0xAD, 0x56, 0x40, 0x1B, 0x0F, 0x10, 0xFC, + 0xAA, 0xC1, 0x19, 0x20, 0x10, 0x46, 0xCC, 0xA2, + 0x8C, 0x5B, 0x14, 0xAB, 0xDE, 0xA3, 0x21, 0x2A, + 0xE6, 0x55, 0x62, 0xF7, 0xF1, 0x38, 0xDB, 0x3D + }, + { + 0x4C, 0xEC, 0x4C, 0x9D, 0xF5, 0x2E, 0xEF, 0x05, + 0xC3, 0xF6, 0xFA, 0xAA, 0x97, 0x91, 0xBC, 0x74, + 0x45, 0x93, 0x71, 0x83, 0x22, 0x4E, 0xCC, 0x37, + 0xA1, 0xE5, 0x8D, 0x01, 0x32, 0xD3, 0x56, 0x17, + 0x53, 0x1D, 0x7E, 0x79, 0x5F, 0x52, 0xAF, 0x7B, + 0x1E, 0xB9, 0xD1, 0x47, 0xDE, 0x12, 0x92, 0xD3, + 0x45, 0xFE, 0x34, 0x18, 0x23, 0xF8, 0xE6, 0xBC, + 0x1E, 0x5B, 0xAD, 0xCA, 0x5C, 0x65, 0x61, 0x08 + }, + { + 0x89, 0x8B, 0xFB, 0xAE, 0x93, 0xB3, 0xE1, 0x8D, + 0x00, 0x69, 0x7E, 0xAB, 0x7D, 0x97, 0x04, 0xFA, + 0x36, 0xEC, 0x33, 0x9D, 0x07, 0x61, 0x31, 0xCE, + 0xFD, 0xF3, 0x0E, 0xDB, 0xE8, 0xD9, 0xCC, 0x81, + 0xC3, 0xA8, 0x0B, 0x12, 0x96, 0x59, 0xB1, 0x63, + 0xA3, 0x23, 0xBA, 0xB9, 0x79, 0x3D, 0x4F, 0xEE, + 0xD9, 0x2D, 0x54, 0xDA, 0xE9, 0x66, 0xC7, 0x75, + 0x29, 0x76, 0x4A, 0x09, 0xBE, 0x88, 0xDB, 0x45 + }, + { + 0xEE, 0x9B, 0xD0, 0x46, 0x9D, 0x3A, 0xAF, 0x4F, + 0x14, 0x03, 0x5B, 0xE4, 0x8A, 0x2C, 0x3B, 0x84, + 0xD9, 0xB4, 0xB1, 0xFF, 0xF1, 0xD9, 0x45, 0xE1, + 0xF1, 0xC1, 0xD3, 0x89, 0x80, 0xA9, 0x51, 0xBE, + 0x19, 0x7B, 0x25, 0xFE, 0x22, 0xC7, 0x31, 0xF2, + 0x0A, 0xEA, 0xCC, 0x93, 0x0B, 0xA9, 0xC4, 0xA1, + 0xF4, 0x76, 0x22, 0x27, 0x61, 0x7A, 0xD3, 0x50, + 0xFD, 0xAB, 0xB4, 0xE8, 0x02, 0x73, 0xA0, 0xF4 + }, + { + 0x3D, 0x4D, 0x31, 0x13, 0x30, 0x05, 0x81, 0xCD, + 0x96, 0xAC, 0xBF, 0x09, 0x1C, 0x3D, 0x0F, 0x3C, + 0x31, 0x01, 0x38, 0xCD, 0x69, 0x79, 0xE6, 0x02, + 0x6C, 0xDE, 0x62, 0x3E, 0x2D, 0xD1, 0xB2, 0x4D, + 0x4A, 0x86, 0x38, 0xBE, 0xD1, 0x07, 0x33, 0x44, + 0x78, 0x3A, 0xD0, 0x64, 0x9C, 0xC6, 0x30, 0x5C, + 0xCE, 0xC0, 0x4B, 0xEB, 0x49, 0xF3, 0x1C, 0x63, + 0x30, 0x88, 0xA9, 0x9B, 0x65, 0x13, 0x02, 0x67 + }, + { + 0x95, 0xC0, 0x59, 0x1A, 0xD9, 0x1F, 0x92, 0x1A, + 0xC7, 0xBE, 0x6D, 0x9C, 0xE3, 0x7E, 0x06, 0x63, + 0xED, 0x80, 0x11, 0xC1, 0xCF, 0xD6, 0xD0, 0x16, + 0x2A, 0x55, 0x72, 0xE9, 0x43, 0x68, 0xBA, 0xC0, + 0x20, 0x24, 0x48, 0x5E, 0x6A, 0x39, 0x85, 0x4A, + 0xA4, 0x6F, 0xE3, 0x8E, 0x97, 0xD6, 0xC6, 0xB1, + 0x94, 0x7C, 0xD2, 0x72, 0xD8, 0x6B, 0x06, 0xBB, + 0x5B, 0x2F, 0x78, 0xB9, 0xB6, 0x8D, 0x55, 0x9D + }, + { + 0x22, 0x7B, 0x79, 0xDE, 0xD3, 0x68, 0x15, 0x3B, + 0xF4, 0x6C, 0x0A, 0x3C, 0xA9, 0x78, 0xBF, 0xDB, + 0xEF, 0x31, 0xF3, 0x02, 0x4A, 0x56, 0x65, 0x84, + 0x24, 0x68, 0x49, 0x0B, 0x0F, 0xF7, 0x48, 0xAE, + 0x04, 0xE7, 0x83, 0x2E, 0xD4, 0xC9, 0xF4, 0x9D, + 0xE9, 0xB1, 0x70, 0x67, 0x09, 0xD6, 0x23, 0xE5, + 0xC8, 0xC1, 0x5E, 0x3C, 0xAE, 0xCA, 0xE8, 0xD5, + 0xE4, 0x33, 0x43, 0x0F, 0xF7, 0x2F, 0x20, 0xEB + }, + { + 0x5D, 0x34, 0xF3, 0x95, 0x2F, 0x01, 0x05, 0xEE, + 0xF8, 0x8A, 0xE8, 0xB6, 0x4C, 0x6C, 0xE9, 0x5E, + 0xBF, 0xAD, 0xE0, 0xE0, 0x2C, 0x69, 0xB0, 0x87, + 0x62, 0xA8, 0x71, 0x2D, 0x2E, 0x49, 0x11, 0xAD, + 0x3F, 0x94, 0x1F, 0xC4, 0x03, 0x4D, 0xC9, 0xB2, + 0xE4, 0x79, 0xFD, 0xBC, 0xD2, 0x79, 0xB9, 0x02, + 0xFA, 0xF5, 0xD8, 0x38, 0xBB, 0x2E, 0x0C, 0x64, + 0x95, 0xD3, 0x72, 0xB5, 0xB7, 0x02, 0x98, 0x13 + }, + { + 0x7F, 0x93, 0x9B, 0xF8, 0x35, 0x3A, 0xBC, 0xE4, + 0x9E, 0x77, 0xF1, 0x4F, 0x37, 0x50, 0xAF, 0x20, + 0xB7, 0xB0, 0x39, 0x02, 0xE1, 0xA1, 0xE7, 0xFB, + 0x6A, 0xAF, 0x76, 0xD0, 0x25, 0x9C, 0xD4, 0x01, + 0xA8, 0x31, 0x90, 0xF1, 0x56, 0x40, 0xE7, 0x4F, + 0x3E, 0x6C, 0x5A, 0x90, 0xE8, 0x39, 0xC7, 0x82, + 0x1F, 0x64, 0x74, 0x75, 0x7F, 0x75, 0xC7, 0xBF, + 0x90, 0x02, 0x08, 0x4D, 0xDC, 0x7A, 0x62, 0xDC + }, + { + 0x06, 0x2B, 0x61, 0xA2, 0xF9, 0xA3, 0x3A, 0x71, + 0xD7, 0xD0, 0xA0, 0x61, 0x19, 0x64, 0x4C, 0x70, + 0xB0, 0x71, 0x6A, 0x50, 0x4D, 0xE7, 0xE5, 0xE1, + 0xBE, 0x49, 0xBD, 0x7B, 0x86, 0xE7, 0xED, 0x68, + 0x17, 0x71, 0x4F, 0x9F, 0x0F, 0xC3, 0x13, 0xD0, + 0x61, 0x29, 0x59, 0x7E, 0x9A, 0x22, 0x35, 0xEC, + 0x85, 0x21, 0xDE, 0x36, 0xF7, 0x29, 0x0A, 0x90, + 0xCC, 0xFC, 0x1F, 0xFA, 0x6D, 0x0A, 0xEE, 0x29 + }, + { + 0xF2, 0x9E, 0x01, 0xEE, 0xAE, 0x64, 0x31, 0x1E, + 0xB7, 0xF1, 0xC6, 0x42, 0x2F, 0x94, 0x6B, 0xF7, + 0xBE, 0xA3, 0x63, 0x79, 0x52, 0x3E, 0x7B, 0x2B, + 0xBA, 0xBA, 0x7D, 0x1D, 0x34, 0xA2, 0x2D, 0x5E, + 0xA5, 0xF1, 0xC5, 0xA0, 0x9D, 0x5C, 0xE1, 0xFE, + 0x68, 0x2C, 0xCE, 0xD9, 0xA4, 0x79, 0x8D, 0x1A, + 0x05, 0xB4, 0x6C, 0xD7, 0x2D, 0xFF, 0x5C, 0x1B, + 0x35, 0x54, 0x40, 0xB2, 0xA2, 0xD4, 0x76, 0xBC + }, + { + 0xEC, 0x38, 0xCD, 0x3B, 0xBA, 0xB3, 0xEF, 0x35, + 0xD7, 0xCB, 0x6D, 0x5C, 0x91, 0x42, 0x98, 0x35, + 0x1D, 0x8A, 0x9D, 0xC9, 0x7F, 0xCE, 0xE0, 0x51, + 0xA8, 0xA0, 0x2F, 0x58, 0xE3, 0xED, 0x61, 0x84, + 0xD0, 0xB7, 0x81, 0x0A, 0x56, 0x15, 0x41, 0x1A, + 0xB1, 0xB9, 0x52, 0x09, 0xC3, 0xC8, 0x10, 0x11, + 0x4F, 0xDE, 0xB2, 0x24, 0x52, 0x08, 0x4E, 0x77, + 0xF3, 0xF8, 0x47, 0xC6, 0xDB, 0xAA, 0xFE, 0x16 + }, + { + 0xC2, 0xAE, 0xF5, 0xE0, 0xCA, 0x43, 0xE8, 0x26, + 0x41, 0x56, 0x5B, 0x8C, 0xB9, 0x43, 0xAA, 0x8B, + 0xA5, 0x35, 0x50, 0xCA, 0xEF, 0x79, 0x3B, 0x65, + 0x32, 0xFA, 0xFA, 0xD9, 0x4B, 0x81, 0x60, 0x82, + 0xF0, 0x11, 0x3A, 0x3E, 0xA2, 0xF6, 0x36, 0x08, + 0xAB, 0x40, 0x43, 0x7E, 0xCC, 0x0F, 0x02, 0x29, + 0xCB, 0x8F, 0xA2, 0x24, 0xDC, 0xF1, 0xC4, 0x78, + 0xA6, 0x7D, 0x9B, 0x64, 0x16, 0x2B, 0x92, 0xD1 + }, + { + 0x15, 0xF5, 0x34, 0xEF, 0xFF, 0x71, 0x05, 0xCD, + 0x1C, 0x25, 0x4D, 0x07, 0x4E, 0x27, 0xD5, 0x89, + 0x8B, 0x89, 0x31, 0x3B, 0x7D, 0x36, 0x6D, 0xC2, + 0xD7, 0xD8, 0x71, 0x13, 0xFA, 0x7D, 0x53, 0xAA, + 0xE1, 0x3F, 0x6D, 0xBA, 0x48, 0x7A, 0xD8, 0x10, + 0x3D, 0x5E, 0x85, 0x4C, 0x91, 0xFD, 0xB6, 0xE1, + 0xE7, 0x4B, 0x2E, 0xF6, 0xD1, 0x43, 0x17, 0x69, + 0xC3, 0x07, 0x67, 0xDD, 0xE0, 0x67, 0xA3, 0x5C + }, + { + 0x89, 0xAC, 0xBC, 0xA0, 0xB1, 0x69, 0x89, 0x7A, + 0x0A, 0x27, 0x14, 0xC2, 0xDF, 0x8C, 0x95, 0xB5, + 0xB7, 0x9C, 0xB6, 0x93, 0x90, 0x14, 0x2B, 0x7D, + 0x60, 0x18, 0xBB, 0x3E, 0x30, 0x76, 0xB0, 0x99, + 0xB7, 0x9A, 0x96, 0x41, 0x52, 0xA9, 0xD9, 0x12, + 0xB1, 0xB8, 0x64, 0x12, 0xB7, 0xE3, 0x72, 0xE9, + 0xCE, 0xCA, 0xD7, 0xF2, 0x5D, 0x4C, 0xBA, 0xB8, + 0xA3, 0x17, 0xBE, 0x36, 0x49, 0x2A, 0x67, 0xD7 + }, + { + 0xE3, 0xC0, 0x73, 0x91, 0x90, 0xED, 0x84, 0x9C, + 0x9C, 0x96, 0x2F, 0xD9, 0xDB, 0xB5, 0x5E, 0x20, + 0x7E, 0x62, 0x4F, 0xCA, 0xC1, 0xEB, 0x41, 0x76, + 0x91, 0x51, 0x54, 0x99, 0xEE, 0xA8, 0xD8, 0x26, + 0x7B, 0x7E, 0x8F, 0x12, 0x87, 0xA6, 0x36, 0x33, + 0xAF, 0x50, 0x11, 0xFD, 0xE8, 0xC4, 0xDD, 0xF5, + 0x5B, 0xFD, 0xF7, 0x22, 0xED, 0xF8, 0x88, 0x31, + 0x41, 0x4F, 0x2C, 0xFA, 0xED, 0x59, 0xCB, 0x9A + }, + { + 0x8D, 0x6C, 0xF8, 0x7C, 0x08, 0x38, 0x0D, 0x2D, + 0x15, 0x06, 0xEE, 0xE4, 0x6F, 0xD4, 0x22, 0x2D, + 0x21, 0xD8, 0xC0, 0x4E, 0x58, 0x5F, 0xBF, 0xD0, + 0x82, 0x69, 0xC9, 0x8F, 0x70, 0x28, 0x33, 0xA1, + 0x56, 0x32, 0x6A, 0x07, 0x24, 0x65, 0x64, 0x00, + 0xEE, 0x09, 0x35, 0x1D, 0x57, 0xB4, 0x40, 0x17, + 0x5E, 0x2A, 0x5D, 0xE9, 0x3C, 0xC5, 0xF8, 0x0D, + 0xB6, 0xDA, 0xF8, 0x35, 0x76, 0xCF, 0x75, 0xFA + }, + { + 0xDA, 0x24, 0xBE, 0xDE, 0x38, 0x36, 0x66, 0xD5, + 0x63, 0xEE, 0xED, 0x37, 0xF6, 0x31, 0x9B, 0xAF, + 0x20, 0xD5, 0xC7, 0x5D, 0x16, 0x35, 0xA6, 0xBA, + 0x5E, 0xF4, 0xCF, 0xA1, 0xAC, 0x95, 0x48, 0x7E, + 0x96, 0xF8, 0xC0, 0x8A, 0xF6, 0x00, 0xAA, 0xB8, + 0x7C, 0x98, 0x6E, 0xBA, 0xD4, 0x9F, 0xC7, 0x0A, + 0x58, 0xB4, 0x89, 0x0B, 0x9C, 0x87, 0x6E, 0x09, + 0x10, 0x16, 0xDA, 0xF4, 0x9E, 0x1D, 0x32, 0x2E + }, + { + 0xF9, 0xD1, 0xD1, 0xB1, 0xE8, 0x7E, 0xA7, 0xAE, + 0x75, 0x3A, 0x02, 0x97, 0x50, 0xCC, 0x1C, 0xF3, + 0xD0, 0x15, 0x7D, 0x41, 0x80, 0x5E, 0x24, 0x5C, + 0x56, 0x17, 0xBB, 0x93, 0x4E, 0x73, 0x2F, 0x0A, + 0xE3, 0x18, 0x0B, 0x78, 0xE0, 0x5B, 0xFE, 0x76, + 0xC7, 0xC3, 0x05, 0x1E, 0x3E, 0x3A, 0xC7, 0x8B, + 0x9B, 0x50, 0xC0, 0x51, 0x42, 0x65, 0x7E, 0x1E, + 0x03, 0x21, 0x5D, 0x6E, 0xC7, 0xBF, 0xD0, 0xFC + }, + { + 0x11, 0xB7, 0xBC, 0x16, 0x68, 0x03, 0x20, 0x48, + 0xAA, 0x43, 0x34, 0x3D, 0xE4, 0x76, 0x39, 0x5E, + 0x81, 0x4B, 0xBB, 0xC2, 0x23, 0x67, 0x8D, 0xB9, + 0x51, 0xA1, 0xB0, 0x3A, 0x02, 0x1E, 0xFA, 0xC9, + 0x48, 0xCF, 0xBE, 0x21, 0x5F, 0x97, 0xFE, 0x9A, + 0x72, 0xA2, 0xF6, 0xBC, 0x03, 0x9E, 0x39, 0x56, + 0xBF, 0xA4, 0x17, 0xC1, 0xA9, 0xF1, 0x0D, 0x6D, + 0x7B, 0xA5, 0xD3, 0xD3, 0x2F, 0xF3, 0x23, 0xE5 + }, + { + 0xB8, 0xD9, 0x00, 0x0E, 0x4F, 0xC2, 0xB0, 0x66, + 0xED, 0xB9, 0x1A, 0xFE, 0xE8, 0xE7, 0xEB, 0x0F, + 0x24, 0xE3, 0xA2, 0x01, 0xDB, 0x8B, 0x67, 0x93, + 0xC0, 0x60, 0x85, 0x81, 0xE6, 0x28, 0xED, 0x0B, + 0xCC, 0x4E, 0x5A, 0xA6, 0x78, 0x79, 0x92, 0xA4, + 0xBC, 0xC4, 0x4E, 0x28, 0x80, 0x93, 0xE6, 0x3E, + 0xE8, 0x3A, 0xBD, 0x0B, 0xC3, 0xEC, 0x6D, 0x09, + 0x34, 0xA6, 0x74, 0xA4, 0xDA, 0x13, 0x83, 0x8A + }, + { + 0xCE, 0x32, 0x5E, 0x29, 0x4F, 0x9B, 0x67, 0x19, + 0xD6, 0xB6, 0x12, 0x78, 0x27, 0x6A, 0xE0, 0x6A, + 0x25, 0x64, 0xC0, 0x3B, 0xB0, 0xB7, 0x83, 0xFA, + 0xFE, 0x78, 0x5B, 0xDF, 0x89, 0xC7, 0xD5, 0xAC, + 0xD8, 0x3E, 0x78, 0x75, 0x6D, 0x30, 0x1B, 0x44, + 0x56, 0x99, 0x02, 0x4E, 0xAE, 0xB7, 0x7B, 0x54, + 0xD4, 0x77, 0x33, 0x6E, 0xC2, 0xA4, 0xF3, 0x32, + 0xF2, 0xB3, 0xF8, 0x87, 0x65, 0xDD, 0xB0, 0xC3 + }, + { + 0x29, 0xAC, 0xC3, 0x0E, 0x96, 0x03, 0xAE, 0x2F, + 0xCC, 0xF9, 0x0B, 0xF9, 0x7E, 0x6C, 0xC4, 0x63, + 0xEB, 0xE2, 0x8C, 0x1B, 0x2F, 0x9B, 0x4B, 0x76, + 0x5E, 0x70, 0x53, 0x7C, 0x25, 0xC7, 0x02, 0xA2, + 0x9D, 0xCB, 0xFB, 0xF1, 0x4C, 0x99, 0xC5, 0x43, + 0x45, 0xBA, 0x2B, 0x51, 0xF1, 0x7B, 0x77, 0xB5, + 0xF1, 0x5D, 0xB9, 0x2B, 0xBA, 0xD8, 0xFA, 0x95, + 0xC4, 0x71, 0xF5, 0xD0, 0x70, 0xA1, 0x37, 0xCC + }, + { + 0x33, 0x79, 0xCB, 0xAA, 0xE5, 0x62, 0xA8, 0x7B, + 0x4C, 0x04, 0x25, 0x55, 0x0F, 0xFD, 0xD6, 0xBF, + 0xE1, 0x20, 0x3F, 0x0D, 0x66, 0x6C, 0xC7, 0xEA, + 0x09, 0x5B, 0xE4, 0x07, 0xA5, 0xDF, 0xE6, 0x1E, + 0xE9, 0x14, 0x41, 0xCD, 0x51, 0x54, 0xB3, 0xE5, + 0x3B, 0x4F, 0x5F, 0xB3, 0x1A, 0xD4, 0xC7, 0xA9, + 0xAD, 0x5C, 0x7A, 0xF4, 0xAE, 0x67, 0x9A, 0xA5, + 0x1A, 0x54, 0x00, 0x3A, 0x54, 0xCA, 0x6B, 0x2D + }, + { + 0x30, 0x95, 0xA3, 0x49, 0xD2, 0x45, 0x70, 0x8C, + 0x7C, 0xF5, 0x50, 0x11, 0x87, 0x03, 0xD7, 0x30, + 0x2C, 0x27, 0xB6, 0x0A, 0xF5, 0xD4, 0xE6, 0x7F, + 0xC9, 0x78, 0xF8, 0xA4, 0xE6, 0x09, 0x53, 0xC7, + 0xA0, 0x4F, 0x92, 0xFC, 0xF4, 0x1A, 0xEE, 0x64, + 0x32, 0x1C, 0xCB, 0x70, 0x7A, 0x89, 0x58, 0x51, + 0x55, 0x2B, 0x1E, 0x37, 0xB0, 0x0B, 0xC5, 0xE6, + 0xB7, 0x2F, 0xA5, 0xBC, 0xEF, 0x9E, 0x3F, 0xFF + }, + { + 0x07, 0x26, 0x2D, 0x73, 0x8B, 0x09, 0x32, 0x1F, + 0x4D, 0xBC, 0xCE, 0xC4, 0xBB, 0x26, 0xF4, 0x8C, + 0xB0, 0xF0, 0xED, 0x24, 0x6C, 0xE0, 0xB3, 0x1B, + 0x9A, 0x6E, 0x7B, 0xC6, 0x83, 0x04, 0x9F, 0x1F, + 0x3E, 0x55, 0x45, 0xF2, 0x8C, 0xE9, 0x32, 0xDD, + 0x98, 0x5C, 0x5A, 0xB0, 0xF4, 0x3B, 0xD6, 0xDE, + 0x07, 0x70, 0x56, 0x0A, 0xF3, 0x29, 0x06, 0x5E, + 0xD2, 0xE4, 0x9D, 0x34, 0x62, 0x4C, 0x2C, 0xBB + }, + { + 0xB6, 0x40, 0x5E, 0xCA, 0x8E, 0xE3, 0x31, 0x6C, + 0x87, 0x06, 0x1C, 0xC6, 0xEC, 0x18, 0xDB, 0xA5, + 0x3E, 0x6C, 0x25, 0x0C, 0x63, 0xBA, 0x1F, 0x3B, + 0xAE, 0x9E, 0x55, 0xDD, 0x34, 0x98, 0x03, 0x6A, + 0xF0, 0x8C, 0xD2, 0x72, 0xAA, 0x24, 0xD7, 0x13, + 0xC6, 0x02, 0x0D, 0x77, 0xAB, 0x2F, 0x39, 0x19, + 0xAF, 0x1A, 0x32, 0xF3, 0x07, 0x42, 0x06, 0x18, + 0xAB, 0x97, 0xE7, 0x39, 0x53, 0x99, 0x4F, 0xB4 + }, + { + 0x7E, 0xE6, 0x82, 0xF6, 0x31, 0x48, 0xEE, 0x45, + 0xF6, 0xE5, 0x31, 0x5D, 0xA8, 0x1E, 0x5C, 0x6E, + 0x55, 0x7C, 0x2C, 0x34, 0x64, 0x1F, 0xC5, 0x09, + 0xC7, 0xA5, 0x70, 0x10, 0x88, 0xC3, 0x8A, 0x74, + 0x75, 0x61, 0x68, 0xE2, 0xCD, 0x8D, 0x35, 0x1E, + 0x88, 0xFD, 0x1A, 0x45, 0x1F, 0x36, 0x0A, 0x01, + 0xF5, 0xB2, 0x58, 0x0F, 0x9B, 0x5A, 0x2E, 0x8C, + 0xFC, 0x13, 0x8F, 0x3D, 0xD5, 0x9A, 0x3F, 0xFC + }, + { + 0x1D, 0x26, 0x3C, 0x17, 0x9D, 0x6B, 0x26, 0x8F, + 0x6F, 0xA0, 0x16, 0xF3, 0xA4, 0xF2, 0x9E, 0x94, + 0x38, 0x91, 0x12, 0x5E, 0xD8, 0x59, 0x3C, 0x81, + 0x25, 0x60, 0x59, 0xF5, 0xA7, 0xB4, 0x4A, 0xF2, + 0xDC, 0xB2, 0x03, 0x0D, 0x17, 0x5C, 0x00, 0xE6, + 0x2E, 0xCA, 0xF7, 0xEE, 0x96, 0x68, 0x2A, 0xA0, + 0x7A, 0xB2, 0x0A, 0x61, 0x10, 0x24, 0xA2, 0x85, + 0x32, 0xB1, 0xC2, 0x5B, 0x86, 0x65, 0x79, 0x02 + }, + { + 0x10, 0x6D, 0x13, 0x2C, 0xBD, 0xB4, 0xCD, 0x25, + 0x97, 0x81, 0x28, 0x46, 0xE2, 0xBC, 0x1B, 0xF7, + 0x32, 0xFE, 0xC5, 0xF0, 0xA5, 0xF6, 0x5D, 0xBB, + 0x39, 0xEC, 0x4E, 0x6D, 0xC6, 0x4A, 0xB2, 0xCE, + 0x6D, 0x24, 0x63, 0x0D, 0x0F, 0x15, 0xA8, 0x05, + 0xC3, 0x54, 0x00, 0x25, 0xD8, 0x4A, 0xFA, 0x98, + 0xE3, 0x67, 0x03, 0xC3, 0xDB, 0xEE, 0x71, 0x3E, + 0x72, 0xDD, 0xE8, 0x46, 0x5B, 0xC1, 0xBE, 0x7E + }, + { + 0x0E, 0x79, 0x96, 0x82, 0x26, 0x65, 0x06, 0x67, + 0xA8, 0xD8, 0x62, 0xEA, 0x8D, 0xA4, 0x89, 0x1A, + 0xF5, 0x6A, 0x4E, 0x3A, 0x8B, 0x6D, 0x17, 0x50, + 0xE3, 0x94, 0xF0, 0xDE, 0xA7, 0x6D, 0x64, 0x0D, + 0x85, 0x07, 0x7B, 0xCE, 0xC2, 0xCC, 0x86, 0x88, + 0x6E, 0x50, 0x67, 0x51, 0xB4, 0xF6, 0xA5, 0x83, + 0x8F, 0x7F, 0x0B, 0x5F, 0xEF, 0x76, 0x5D, 0x9D, + 0xC9, 0x0D, 0xCD, 0xCB, 0xAF, 0x07, 0x9F, 0x08 + }, + { + 0x52, 0x11, 0x56, 0xA8, 0x2A, 0xB0, 0xC4, 0xE5, + 0x66, 0xE5, 0x84, 0x4D, 0x5E, 0x31, 0xAD, 0x9A, + 0xAF, 0x14, 0x4B, 0xBD, 0x5A, 0x46, 0x4F, 0xDC, + 0xA3, 0x4D, 0xBD, 0x57, 0x17, 0xE8, 0xFF, 0x71, + 0x1D, 0x3F, 0xFE, 0xBB, 0xFA, 0x08, 0x5D, 0x67, + 0xFE, 0x99, 0x6A, 0x34, 0xF6, 0xD3, 0xE4, 0xE6, + 0x0B, 0x13, 0x96, 0xBF, 0x4B, 0x16, 0x10, 0xC2, + 0x63, 0xBD, 0xBB, 0x83, 0x4D, 0x56, 0x08, 0x16 + }, + { + 0x1A, 0xBA, 0x88, 0xBE, 0xFC, 0x55, 0xBC, 0x25, + 0xEF, 0xBC, 0xE0, 0x2D, 0xB8, 0xB9, 0x93, 0x3E, + 0x46, 0xF5, 0x76, 0x61, 0xBA, 0xEA, 0xBE, 0xB2, + 0x1C, 0xC2, 0x57, 0x4D, 0x2A, 0x51, 0x8A, 0x3C, + 0xBA, 0x5D, 0xC5, 0xA3, 0x8E, 0x49, 0x71, 0x34, + 0x40, 0xB2, 0x5F, 0x9C, 0x74, 0x4E, 0x75, 0xF6, + 0xB8, 0x5C, 0x9D, 0x8F, 0x46, 0x81, 0xF6, 0x76, + 0x16, 0x0F, 0x61, 0x05, 0x35, 0x7B, 0x84, 0x06 + }, + { + 0x5A, 0x99, 0x49, 0xFC, 0xB2, 0xC4, 0x73, 0xCD, + 0xA9, 0x68, 0xAC, 0x1B, 0x5D, 0x08, 0x56, 0x6D, + 0xC2, 0xD8, 0x16, 0xD9, 0x60, 0xF5, 0x7E, 0x63, + 0xB8, 0x98, 0xFA, 0x70, 0x1C, 0xF8, 0xEB, 0xD3, + 0xF5, 0x9B, 0x12, 0x4D, 0x95, 0xBF, 0xBB, 0xED, + 0xC5, 0xF1, 0xCF, 0x0E, 0x17, 0xD5, 0xEA, 0xED, + 0x0C, 0x02, 0xC5, 0x0B, 0x69, 0xD8, 0xA4, 0x02, + 0xCA, 0xBC, 0xCA, 0x44, 0x33, 0xB5, 0x1F, 0xD4 + }, + { + 0xB0, 0xCE, 0xAD, 0x09, 0x80, 0x7C, 0x67, 0x2A, + 0xF2, 0xEB, 0x2B, 0x0F, 0x06, 0xDD, 0xE4, 0x6C, + 0xF5, 0x37, 0x0E, 0x15, 0xA4, 0x09, 0x6B, 0x1A, + 0x7D, 0x7C, 0xBB, 0x36, 0xEC, 0x31, 0xC2, 0x05, + 0xFB, 0xEF, 0xCA, 0x00, 0xB7, 0xA4, 0x16, 0x2F, + 0xA8, 0x9F, 0xB4, 0xFB, 0x3E, 0xB7, 0x8D, 0x79, + 0x77, 0x0C, 0x23, 0xF4, 0x4E, 0x72, 0x06, 0x66, + 0x4C, 0xE3, 0xCD, 0x93, 0x1C, 0x29, 0x1E, 0x5D + }, + { + 0xBB, 0x66, 0x64, 0x93, 0x1E, 0xC9, 0x70, 0x44, + 0xE4, 0x5B, 0x2A, 0xE4, 0x20, 0xAE, 0x1C, 0x55, + 0x1A, 0x88, 0x74, 0xBC, 0x93, 0x7D, 0x08, 0xE9, + 0x69, 0x39, 0x9C, 0x39, 0x64, 0xEB, 0xDB, 0xA8, + 0x34, 0x6C, 0xDD, 0x5D, 0x09, 0xCA, 0xAF, 0xE4, + 0xC2, 0x8B, 0xA7, 0xEC, 0x78, 0x81, 0x91, 0xCE, + 0xCA, 0x65, 0xDD, 0xD6, 0xF9, 0x5F, 0x18, 0x58, + 0x3E, 0x04, 0x0D, 0x0F, 0x30, 0xD0, 0x36, 0x4D + }, + { + 0x65, 0xBC, 0x77, 0x0A, 0x5F, 0xAA, 0x37, 0x92, + 0x36, 0x98, 0x03, 0x68, 0x3E, 0x84, 0x4B, 0x0B, + 0xE7, 0xEE, 0x96, 0xF2, 0x9F, 0x6D, 0x6A, 0x35, + 0x56, 0x80, 0x06, 0xBD, 0x55, 0x90, 0xF9, 0xA4, + 0xEF, 0x63, 0x9B, 0x7A, 0x80, 0x61, 0xC7, 0xB0, + 0x42, 0x4B, 0x66, 0xB6, 0x0A, 0xC3, 0x4A, 0xF3, + 0x11, 0x99, 0x05, 0xF3, 0x3A, 0x9D, 0x8C, 0x3A, + 0xE1, 0x83, 0x82, 0xCA, 0x9B, 0x68, 0x99, 0x00 + }, + { + 0xEA, 0x9B, 0x4D, 0xCA, 0x33, 0x33, 0x36, 0xAA, + 0xF8, 0x39, 0xA4, 0x5C, 0x6E, 0xAA, 0x48, 0xB8, + 0xCB, 0x4C, 0x7D, 0xDA, 0xBF, 0xFE, 0xA4, 0xF6, + 0x43, 0xD6, 0x35, 0x7E, 0xA6, 0x62, 0x8A, 0x48, + 0x0A, 0x5B, 0x45, 0xF2, 0xB0, 0x52, 0xC1, 0xB0, + 0x7D, 0x1F, 0xED, 0xCA, 0x91, 0x8B, 0x6F, 0x11, + 0x39, 0xD8, 0x0F, 0x74, 0xC2, 0x45, 0x10, 0xDC, + 0xBA, 0xA4, 0xBE, 0x70, 0xEA, 0xCC, 0x1B, 0x06 + }, + { + 0xE6, 0x34, 0x2F, 0xB4, 0xA7, 0x80, 0xAD, 0x97, + 0x5D, 0x0E, 0x24, 0xBC, 0xE1, 0x49, 0x98, 0x9B, + 0x91, 0xD3, 0x60, 0x55, 0x7E, 0x87, 0x99, 0x4F, + 0x6B, 0x45, 0x7B, 0x89, 0x55, 0x75, 0xCC, 0x02, + 0xD0, 0xC1, 0x5B, 0xAD, 0x3C, 0xE7, 0x57, 0x7F, + 0x4C, 0x63, 0x92, 0x7F, 0xF1, 0x3F, 0x3E, 0x38, + 0x1F, 0xF7, 0xE7, 0x2B, 0xDB, 0xE7, 0x45, 0x32, + 0x48, 0x44, 0xA9, 0xD2, 0x7E, 0x3F, 0x1C, 0x01 + }, + { + 0x3E, 0x20, 0x9C, 0x9B, 0x33, 0xE8, 0xE4, 0x61, + 0x17, 0x8A, 0xB4, 0x6B, 0x1C, 0x64, 0xB4, 0x9A, + 0x07, 0xFB, 0x74, 0x5F, 0x1C, 0x8B, 0xC9, 0x5F, + 0xBF, 0xB9, 0x4C, 0x6B, 0x87, 0xC6, 0x95, 0x16, + 0x65, 0x1B, 0x26, 0x4E, 0xF9, 0x80, 0x93, 0x7F, + 0xAD, 0x41, 0x23, 0x8B, 0x91, 0xDD, 0xC0, 0x11, + 0xA5, 0xDD, 0x77, 0x7C, 0x7E, 0xFD, 0x44, 0x94, + 0xB4, 0xB6, 0xEC, 0xD3, 0xA9, 0xC2, 0x2A, 0xC0 + }, + { + 0xFD, 0x6A, 0x3D, 0x5B, 0x18, 0x75, 0xD8, 0x04, + 0x86, 0xD6, 0xE6, 0x96, 0x94, 0xA5, 0x6D, 0xBB, + 0x04, 0xA9, 0x9A, 0x4D, 0x05, 0x1F, 0x15, 0xDB, + 0x26, 0x89, 0x77, 0x6B, 0xA1, 0xC4, 0x88, 0x2E, + 0x6D, 0x46, 0x2A, 0x60, 0x3B, 0x70, 0x15, 0xDC, + 0x9F, 0x4B, 0x74, 0x50, 0xF0, 0x53, 0x94, 0x30, + 0x3B, 0x86, 0x52, 0xCF, 0xB4, 0x04, 0xA2, 0x66, + 0x96, 0x2C, 0x41, 0xBA, 0xE6, 0xE1, 0x8A, 0x94 + }, + { + 0x95, 0x1E, 0x27, 0x51, 0x7E, 0x6B, 0xAD, 0x9E, + 0x41, 0x95, 0xFC, 0x86, 0x71, 0xDE, 0xE3, 0xE7, + 0xE9, 0xBE, 0x69, 0xCE, 0xE1, 0x42, 0x2C, 0xB9, + 0xFE, 0xCF, 0xCE, 0x0D, 0xBA, 0x87, 0x5F, 0x7B, + 0x31, 0x0B, 0x93, 0xEE, 0x3A, 0x3D, 0x55, 0x8F, + 0x94, 0x1F, 0x63, 0x5F, 0x66, 0x8F, 0xF8, 0x32, + 0xD2, 0xC1, 0xD0, 0x33, 0xC5, 0xE2, 0xF0, 0x99, + 0x7E, 0x4C, 0x66, 0xF1, 0x47, 0x34, 0x4E, 0x02 + }, + { + 0x8E, 0xBA, 0x2F, 0x87, 0x4F, 0x1A, 0xE8, 0x40, + 0x41, 0x90, 0x3C, 0x7C, 0x42, 0x53, 0xC8, 0x22, + 0x92, 0x53, 0x0F, 0xC8, 0x50, 0x95, 0x50, 0xBF, + 0xDC, 0x34, 0xC9, 0x5C, 0x7E, 0x28, 0x89, 0xD5, + 0x65, 0x0B, 0x0A, 0xD8, 0xCB, 0x98, 0x8E, 0x5C, + 0x48, 0x94, 0xCB, 0x87, 0xFB, 0xFB, 0xB1, 0x96, + 0x12, 0xEA, 0x93, 0xCC, 0xC4, 0xC5, 0xCA, 0xD1, + 0x71, 0x58, 0xB9, 0x76, 0x34, 0x64, 0xB4, 0x92 + }, + { + 0x16, 0xF7, 0x12, 0xEA, 0xA1, 0xB7, 0xC6, 0x35, + 0x47, 0x19, 0xA8, 0xE7, 0xDB, 0xDF, 0xAF, 0x55, + 0xE4, 0x06, 0x3A, 0x4D, 0x27, 0x7D, 0x94, 0x75, + 0x50, 0x01, 0x9B, 0x38, 0xDF, 0xB5, 0x64, 0x83, + 0x09, 0x11, 0x05, 0x7D, 0x50, 0x50, 0x61, 0x36, + 0xE2, 0x39, 0x4C, 0x3B, 0x28, 0x94, 0x5C, 0xC9, + 0x64, 0x96, 0x7D, 0x54, 0xE3, 0x00, 0x0C, 0x21, + 0x81, 0x62, 0x6C, 0xFB, 0x9B, 0x73, 0xEF, 0xD2 + }, + { + 0xC3, 0x96, 0x39, 0xE7, 0xD5, 0xC7, 0xFB, 0x8C, + 0xDD, 0x0F, 0xD3, 0xE6, 0xA5, 0x20, 0x96, 0x03, + 0x94, 0x37, 0x12, 0x2F, 0x21, 0xC7, 0x8F, 0x16, + 0x79, 0xCE, 0xA9, 0xD7, 0x8A, 0x73, 0x4C, 0x56, + 0xEC, 0xBE, 0xB2, 0x86, 0x54, 0xB4, 0xF1, 0x8E, + 0x34, 0x2C, 0x33, 0x1F, 0x6F, 0x72, 0x29, 0xEC, + 0x4B, 0x4B, 0xC2, 0x81, 0xB2, 0xD8, 0x0A, 0x6E, + 0xB5, 0x00, 0x43, 0xF3, 0x17, 0x96, 0xC8, 0x8C + }, + { + 0x72, 0xD0, 0x81, 0xAF, 0x99, 0xF8, 0xA1, 0x73, + 0xDC, 0xC9, 0xA0, 0xAC, 0x4E, 0xB3, 0x55, 0x74, + 0x05, 0x63, 0x9A, 0x29, 0x08, 0x4B, 0x54, 0xA4, + 0x01, 0x72, 0x91, 0x2A, 0x2F, 0x8A, 0x39, 0x51, + 0x29, 0xD5, 0x53, 0x6F, 0x09, 0x18, 0xE9, 0x02, + 0xF9, 0xE8, 0xFA, 0x60, 0x00, 0x99, 0x5F, 0x41, + 0x68, 0xDD, 0xC5, 0xF8, 0x93, 0x01, 0x1B, 0xE6, + 0xA0, 0xDB, 0xC9, 0xB8, 0xA1, 0xA3, 0xF5, 0xBB + }, + { + 0xC1, 0x1A, 0xA8, 0x1E, 0x5E, 0xFD, 0x24, 0xD5, + 0xFC, 0x27, 0xEE, 0x58, 0x6C, 0xFD, 0x88, 0x47, + 0xFB, 0xB0, 0xE2, 0x76, 0x01, 0xCC, 0xEC, 0xE5, + 0xEC, 0xCA, 0x01, 0x98, 0xE3, 0xC7, 0x76, 0x53, + 0x93, 0xBB, 0x74, 0x45, 0x7C, 0x7E, 0x7A, 0x27, + 0xEB, 0x91, 0x70, 0x35, 0x0E, 0x1F, 0xB5, 0x38, + 0x57, 0x17, 0x75, 0x06, 0xBE, 0x3E, 0x76, 0x2C, + 0xC0, 0xF1, 0x4D, 0x8C, 0x3A, 0xFE, 0x90, 0x77 + }, + { + 0xC2, 0x8F, 0x21, 0x50, 0xB4, 0x52, 0xE6, 0xC0, + 0xC4, 0x24, 0xBC, 0xDE, 0x6F, 0x8D, 0x72, 0x00, + 0x7F, 0x93, 0x10, 0xFE, 0xD7, 0xF2, 0xF8, 0x7D, + 0xE0, 0xDB, 0xB6, 0x4F, 0x44, 0x79, 0xD6, 0xC1, + 0x44, 0x1B, 0xA6, 0x6F, 0x44, 0xB2, 0xAC, 0xCE, + 0xE6, 0x16, 0x09, 0x17, 0x7E, 0xD3, 0x40, 0x12, + 0x8B, 0x40, 0x7E, 0xCE, 0xC7, 0xC6, 0x4B, 0xBE, + 0x50, 0xD6, 0x3D, 0x22, 0xD8, 0x62, 0x77, 0x27 + }, + { + 0xF6, 0x3D, 0x88, 0x12, 0x28, 0x77, 0xEC, 0x30, + 0xB8, 0xC8, 0xB0, 0x0D, 0x22, 0xE8, 0x90, 0x00, + 0xA9, 0x66, 0x42, 0x61, 0x12, 0xBD, 0x44, 0x16, + 0x6E, 0x2F, 0x52, 0x5B, 0x76, 0x9C, 0xCB, 0xE9, + 0xB2, 0x86, 0xD4, 0x37, 0xA0, 0x12, 0x91, 0x30, + 0xDD, 0xE1, 0xA8, 0x6C, 0x43, 0xE0, 0x4B, 0xED, + 0xB5, 0x94, 0xE6, 0x71, 0xD9, 0x82, 0x83, 0xAF, + 0xE6, 0x4C, 0xE3, 0x31, 0xDE, 0x98, 0x28, 0xFD + }, + { + 0x34, 0x8B, 0x05, 0x32, 0x88, 0x0B, 0x88, 0xA6, + 0x61, 0x4A, 0x8D, 0x74, 0x08, 0xC3, 0xF9, 0x13, + 0x35, 0x7F, 0xBB, 0x60, 0xE9, 0x95, 0xC6, 0x02, + 0x05, 0xBE, 0x91, 0x39, 0xE7, 0x49, 0x98, 0xAE, + 0xDE, 0x7F, 0x45, 0x81, 0xE4, 0x2F, 0x6B, 0x52, + 0x69, 0x8F, 0x7F, 0xA1, 0x21, 0x97, 0x08, 0xC1, + 0x44, 0x98, 0x06, 0x7F, 0xD1, 0xE0, 0x95, 0x02, + 0xDE, 0x83, 0xA7, 0x7D, 0xD2, 0x81, 0x15, 0x0C + }, + { + 0x51, 0x33, 0xDC, 0x8B, 0xEF, 0x72, 0x53, 0x59, + 0xDF, 0xF5, 0x97, 0x92, 0xD8, 0x5E, 0xAF, 0x75, + 0xB7, 0xE1, 0xDC, 0xD1, 0x97, 0x8B, 0x01, 0xC3, + 0x5B, 0x1B, 0x85, 0xFC, 0xEB, 0xC6, 0x33, 0x88, + 0xAD, 0x99, 0xA1, 0x7B, 0x63, 0x46, 0xA2, 0x17, + 0xDC, 0x1A, 0x96, 0x22, 0xEB, 0xD1, 0x22, 0xEC, + 0xF6, 0x91, 0x3C, 0x4D, 0x31, 0xA6, 0xB5, 0x2A, + 0x69, 0x5B, 0x86, 0xAF, 0x00, 0xD7, 0x41, 0xA0 + }, + { + 0x27, 0x53, 0xC4, 0xC0, 0xE9, 0x8E, 0xCA, 0xD8, + 0x06, 0xE8, 0x87, 0x80, 0xEC, 0x27, 0xFC, 0xCD, + 0x0F, 0x5C, 0x1A, 0xB5, 0x47, 0xF9, 0xE4, 0xBF, + 0x16, 0x59, 0xD1, 0x92, 0xC2, 0x3A, 0xA2, 0xCC, + 0x97, 0x1B, 0x58, 0xB6, 0x80, 0x25, 0x80, 0xBA, + 0xEF, 0x8A, 0xDC, 0x3B, 0x77, 0x6E, 0xF7, 0x08, + 0x6B, 0x25, 0x45, 0xC2, 0x98, 0x7F, 0x34, 0x8E, + 0xE3, 0x71, 0x9C, 0xDE, 0xF2, 0x58, 0xC4, 0x03 + }, + { + 0xB1, 0x66, 0x35, 0x73, 0xCE, 0x4B, 0x9D, 0x8C, + 0xAE, 0xFC, 0x86, 0x50, 0x12, 0xF3, 0xE3, 0x97, + 0x14, 0xB9, 0x89, 0x8A, 0x5D, 0xA6, 0xCE, 0x17, + 0xC2, 0x5A, 0x6A, 0x47, 0x93, 0x1A, 0x9D, 0xDB, + 0x9B, 0xBE, 0x98, 0xAD, 0xAA, 0x55, 0x3B, 0xEE, + 0xD4, 0x36, 0xE8, 0x95, 0x78, 0x45, 0x54, 0x16, + 0xC2, 0xA5, 0x2A, 0x52, 0x5C, 0xF2, 0x86, 0x2B, + 0x8D, 0x1D, 0x49, 0xA2, 0x53, 0x1B, 0x73, 0x91 + }, + { + 0x64, 0xF5, 0x8B, 0xD6, 0xBF, 0xC8, 0x56, 0xF5, + 0xE8, 0x73, 0xB2, 0xA2, 0x95, 0x6E, 0xA0, 0xED, + 0xA0, 0xD6, 0xDB, 0x0D, 0xA3, 0x9C, 0x8C, 0x7F, + 0xC6, 0x7C, 0x9F, 0x9F, 0xEE, 0xFC, 0xFF, 0x30, + 0x72, 0xCD, 0xF9, 0xE6, 0xEA, 0x37, 0xF6, 0x9A, + 0x44, 0xF0, 0xC6, 0x1A, 0xA0, 0xDA, 0x36, 0x93, + 0xC2, 0xDB, 0x5B, 0x54, 0x96, 0x0C, 0x02, 0x81, + 0xA0, 0x88, 0x15, 0x1D, 0xB4, 0x2B, 0x11, 0xE8 + }, + { + 0x07, 0x64, 0xC7, 0xBE, 0x28, 0x12, 0x5D, 0x90, + 0x65, 0xC4, 0xB9, 0x8A, 0x69, 0xD6, 0x0A, 0xED, + 0xE7, 0x03, 0x54, 0x7C, 0x66, 0xA1, 0x2E, 0x17, + 0xE1, 0xC6, 0x18, 0x99, 0x41, 0x32, 0xF5, 0xEF, + 0x82, 0x48, 0x2C, 0x1E, 0x3F, 0xE3, 0x14, 0x6C, + 0xC6, 0x53, 0x76, 0xCC, 0x10, 0x9F, 0x01, 0x38, + 0xED, 0x9A, 0x80, 0xE4, 0x9F, 0x1F, 0x3C, 0x7D, + 0x61, 0x0D, 0x2F, 0x24, 0x32, 0xF2, 0x06, 0x05 + }, + { + 0xF7, 0x48, 0x78, 0x43, 0x98, 0xA2, 0xFF, 0x03, + 0xEB, 0xEB, 0x07, 0xE1, 0x55, 0xE6, 0x61, 0x16, + 0xA8, 0x39, 0x74, 0x1A, 0x33, 0x6E, 0x32, 0xDA, + 0x71, 0xEC, 0x69, 0x60, 0x01, 0xF0, 0xAD, 0x1B, + 0x25, 0xCD, 0x48, 0xC6, 0x9C, 0xFC, 0xA7, 0x26, + 0x5E, 0xCA, 0x1D, 0xD7, 0x19, 0x04, 0xA0, 0xCE, + 0x74, 0x8A, 0xC4, 0x12, 0x4F, 0x35, 0x71, 0x07, + 0x6D, 0xFA, 0x71, 0x16, 0xA9, 0xCF, 0x00, 0xE9 + }, + { + 0x3F, 0x0D, 0xBC, 0x01, 0x86, 0xBC, 0xEB, 0x6B, + 0x78, 0x5B, 0xA7, 0x8D, 0x2A, 0x2A, 0x01, 0x3C, + 0x91, 0x0B, 0xE1, 0x57, 0xBD, 0xAF, 0xFA, 0xE8, + 0x1B, 0xB6, 0x66, 0x3B, 0x1A, 0x73, 0x72, 0x2F, + 0x7F, 0x12, 0x28, 0x79, 0x5F, 0x3E, 0xCA, 0xDA, + 0x87, 0xCF, 0x6E, 0xF0, 0x07, 0x84, 0x74, 0xAF, + 0x73, 0xF3, 0x1E, 0xCA, 0x0C, 0xC2, 0x00, 0xED, + 0x97, 0x5B, 0x68, 0x93, 0xF7, 0x61, 0xCB, 0x6D + }, + { + 0xD4, 0x76, 0x2C, 0xD4, 0x59, 0x98, 0x76, 0xCA, + 0x75, 0xB2, 0xB8, 0xFE, 0x24, 0x99, 0x44, 0xDB, + 0xD2, 0x7A, 0xCE, 0x74, 0x1F, 0xDA, 0xB9, 0x36, + 0x16, 0xCB, 0xC6, 0xE4, 0x25, 0x46, 0x0F, 0xEB, + 0x51, 0xD4, 0xE7, 0xAD, 0xCC, 0x38, 0x18, 0x0E, + 0x7F, 0xC4, 0x7C, 0x89, 0x02, 0x4A, 0x7F, 0x56, + 0x19, 0x1A, 0xDB, 0x87, 0x8D, 0xFD, 0xE4, 0xEA, + 0xD6, 0x22, 0x23, 0xF5, 0xA2, 0x61, 0x0E, 0xFE + }, + { + 0xCD, 0x36, 0xB3, 0xD5, 0xB4, 0xC9, 0x1B, 0x90, + 0xFC, 0xBB, 0xA7, 0x95, 0x13, 0xCF, 0xEE, 0x19, + 0x07, 0xD8, 0x64, 0x5A, 0x16, 0x2A, 0xFD, 0x0C, + 0xD4, 0xCF, 0x41, 0x92, 0xD4, 0xA5, 0xF4, 0xC8, + 0x92, 0x18, 0x3A, 0x8E, 0xAC, 0xDB, 0x2B, 0x6B, + 0x6A, 0x9D, 0x9A, 0xA8, 0xC1, 0x1A, 0xC1, 0xB2, + 0x61, 0xB3, 0x80, 0xDB, 0xEE, 0x24, 0xCA, 0x46, + 0x8F, 0x1B, 0xFD, 0x04, 0x3C, 0x58, 0xEE, 0xFE + }, + { + 0x98, 0x59, 0x34, 0x52, 0x28, 0x16, 0x61, 0xA5, + 0x3C, 0x48, 0xA9, 0xD8, 0xCD, 0x79, 0x08, 0x26, + 0xC1, 0xA1, 0xCE, 0x56, 0x77, 0x38, 0x05, 0x3D, + 0x0B, 0xEE, 0x4A, 0x91, 0xA3, 0xD5, 0xBD, 0x92, + 0xEE, 0xFD, 0xBA, 0xBE, 0xBE, 0x32, 0x04, 0xF2, + 0x03, 0x1C, 0xA5, 0xF7, 0x81, 0xBD, 0xA9, 0x9E, + 0xF5, 0xD8, 0xAE, 0x56, 0xE5, 0xB0, 0x4A, 0x9E, + 0x1E, 0xCD, 0x21, 0xB0, 0xEB, 0x05, 0xD3, 0xE1 + }, + { + 0x77, 0x1F, 0x57, 0xDD, 0x27, 0x75, 0xCC, 0xDA, + 0xB5, 0x59, 0x21, 0xD3, 0xE8, 0xE3, 0x0C, 0xCF, + 0x48, 0x4D, 0x61, 0xFE, 0x1C, 0x1B, 0x9C, 0x2A, + 0xE8, 0x19, 0xD0, 0xFB, 0x2A, 0x12, 0xFA, 0xB9, + 0xBE, 0x70, 0xC4, 0xA7, 0xA1, 0x38, 0xDA, 0x84, + 0xE8, 0x28, 0x04, 0x35, 0xDA, 0xAD, 0xE5, 0xBB, + 0xE6, 0x6A, 0xF0, 0x83, 0x6A, 0x15, 0x4F, 0x81, + 0x7F, 0xB1, 0x7F, 0x33, 0x97, 0xE7, 0x25, 0xA3 + }, + { + 0xC6, 0x08, 0x97, 0xC6, 0xF8, 0x28, 0xE2, 0x1F, + 0x16, 0xFB, 0xB5, 0xF1, 0x5B, 0x32, 0x3F, 0x87, + 0xB6, 0xC8, 0x95, 0x5E, 0xAB, 0xF1, 0xD3, 0x80, + 0x61, 0xF7, 0x07, 0xF6, 0x08, 0xAB, 0xDD, 0x99, + 0x3F, 0xAC, 0x30, 0x70, 0x63, 0x3E, 0x28, 0x6C, + 0xF8, 0x33, 0x9C, 0xE2, 0x95, 0xDD, 0x35, 0x2D, + 0xF4, 0xB4, 0xB4, 0x0B, 0x2F, 0x29, 0xDA, 0x1D, + 0xD5, 0x0B, 0x3A, 0x05, 0xD0, 0x79, 0xE6, 0xBB + }, + { + 0x82, 0x10, 0xCD, 0x2C, 0x2D, 0x3B, 0x13, 0x5C, + 0x2C, 0xF0, 0x7F, 0xA0, 0xD1, 0x43, 0x3C, 0xD7, + 0x71, 0xF3, 0x25, 0xD0, 0x75, 0xC6, 0x46, 0x9D, + 0x9C, 0x7F, 0x1B, 0xA0, 0x94, 0x3C, 0xD4, 0xAB, + 0x09, 0x80, 0x8C, 0xAB, 0xF4, 0xAC, 0xB9, 0xCE, + 0x5B, 0xB8, 0x8B, 0x49, 0x89, 0x29, 0xB4, 0xB8, + 0x47, 0xF6, 0x81, 0xAD, 0x2C, 0x49, 0x0D, 0x04, + 0x2D, 0xB2, 0xAE, 0xC9, 0x42, 0x14, 0xB0, 0x6B + }, + { + 0x1D, 0x4E, 0xDF, 0xFF, 0xD8, 0xFD, 0x80, 0xF7, + 0xE4, 0x10, 0x78, 0x40, 0xFA, 0x3A, 0xA3, 0x1E, + 0x32, 0x59, 0x84, 0x91, 0xE4, 0xAF, 0x70, 0x13, + 0xC1, 0x97, 0xA6, 0x5B, 0x7F, 0x36, 0xDD, 0x3A, + 0xC4, 0xB4, 0x78, 0x45, 0x61, 0x11, 0xCD, 0x43, + 0x09, 0xD9, 0x24, 0x35, 0x10, 0x78, 0x2F, 0xA3, + 0x1B, 0x7C, 0x4C, 0x95, 0xFA, 0x95, 0x15, 0x20, + 0xD0, 0x20, 0xEB, 0x7E, 0x5C, 0x36, 0xE4, 0xEF + }, + { + 0xAF, 0x8E, 0x6E, 0x91, 0xFA, 0xB4, 0x6C, 0xE4, + 0x87, 0x3E, 0x1A, 0x50, 0xA8, 0xEF, 0x44, 0x8C, + 0xC2, 0x91, 0x21, 0xF7, 0xF7, 0x4D, 0xEE, 0xF3, + 0x4A, 0x71, 0xEF, 0x89, 0xCC, 0x00, 0xD9, 0x27, + 0x4B, 0xC6, 0xC2, 0x45, 0x4B, 0xBB, 0x32, 0x30, + 0xD8, 0xB2, 0xEC, 0x94, 0xC6, 0x2B, 0x1D, 0xEC, + 0x85, 0xF3, 0x59, 0x3B, 0xFA, 0x30, 0xEA, 0x6F, + 0x7A, 0x44, 0xD7, 0xC0, 0x94, 0x65, 0xA2, 0x53 + }, + { + 0x29, 0xFD, 0x38, 0x4E, 0xD4, 0x90, 0x6F, 0x2D, + 0x13, 0xAA, 0x9F, 0xE7, 0xAF, 0x90, 0x59, 0x90, + 0x93, 0x8B, 0xED, 0x80, 0x7F, 0x18, 0x32, 0x45, + 0x4A, 0x37, 0x2A, 0xB4, 0x12, 0xEE, 0xA1, 0xF5, + 0x62, 0x5A, 0x1F, 0xCC, 0x9A, 0xC8, 0x34, 0x3B, + 0x7C, 0x67, 0xC5, 0xAB, 0xA6, 0xE0, 0xB1, 0xCC, + 0x46, 0x44, 0x65, 0x49, 0x13, 0x69, 0x2C, 0x6B, + 0x39, 0xEB, 0x91, 0x87, 0xCE, 0xAC, 0xD3, 0xEC + }, + { + 0xA2, 0x68, 0xC7, 0x88, 0x5D, 0x98, 0x74, 0xA5, + 0x1C, 0x44, 0xDF, 0xFE, 0xD8, 0xEA, 0x53, 0xE9, + 0x4F, 0x78, 0x45, 0x6E, 0x0B, 0x2E, 0xD9, 0x9F, + 0xF5, 0xA3, 0x92, 0x47, 0x60, 0x81, 0x38, 0x26, + 0xD9, 0x60, 0xA1, 0x5E, 0xDB, 0xED, 0xBB, 0x5D, + 0xE5, 0x22, 0x6B, 0xA4, 0xB0, 0x74, 0xE7, 0x1B, + 0x05, 0xC5, 0x5B, 0x97, 0x56, 0xBB, 0x79, 0xE5, + 0x5C, 0x02, 0x75, 0x4C, 0x2C, 0x7B, 0x6C, 0x8A + }, + { + 0x0C, 0xF8, 0x54, 0x54, 0x88, 0xD5, 0x6A, 0x86, + 0x81, 0x7C, 0xD7, 0xEC, 0xB1, 0x0F, 0x71, 0x16, + 0xB7, 0xEA, 0x53, 0x0A, 0x45, 0xB6, 0xEA, 0x49, + 0x7B, 0x6C, 0x72, 0xC9, 0x97, 0xE0, 0x9E, 0x3D, + 0x0D, 0xA8, 0x69, 0x8F, 0x46, 0xBB, 0x00, 0x6F, + 0xC9, 0x77, 0xC2, 0xCD, 0x3D, 0x11, 0x77, 0x46, + 0x3A, 0xC9, 0x05, 0x7F, 0xDD, 0x16, 0x62, 0xC8, + 0x5D, 0x0C, 0x12, 0x64, 0x43, 0xC1, 0x04, 0x73 + }, + { + 0xB3, 0x96, 0x14, 0x26, 0x8F, 0xDD, 0x87, 0x81, + 0x51, 0x5E, 0x2C, 0xFE, 0xBF, 0x89, 0xB4, 0xD5, + 0x40, 0x2B, 0xAB, 0x10, 0xC2, 0x26, 0xE6, 0x34, + 0x4E, 0x6B, 0x9A, 0xE0, 0x00, 0xFB, 0x0D, 0x6C, + 0x79, 0xCB, 0x2F, 0x3E, 0xC8, 0x0E, 0x80, 0xEA, + 0xEB, 0x19, 0x80, 0xD2, 0xF8, 0x69, 0x89, 0x16, + 0xBD, 0x2E, 0x9F, 0x74, 0x72, 0x36, 0x65, 0x51, + 0x16, 0x64, 0x9C, 0xD3, 0xCA, 0x23, 0xA8, 0x37 + }, + { + 0x74, 0xBE, 0xF0, 0x92, 0xFC, 0x6F, 0x1E, 0x5D, + 0xBA, 0x36, 0x63, 0xA3, 0xFB, 0x00, 0x3B, 0x2A, + 0x5B, 0xA2, 0x57, 0x49, 0x65, 0x36, 0xD9, 0x9F, + 0x62, 0xB9, 0xD7, 0x3F, 0x8F, 0x9E, 0xB3, 0xCE, + 0x9F, 0xF3, 0xEE, 0xC7, 0x09, 0xEB, 0x88, 0x36, + 0x55, 0xEC, 0x9E, 0xB8, 0x96, 0xB9, 0x12, 0x8F, + 0x2A, 0xFC, 0x89, 0xCF, 0x7D, 0x1A, 0xB5, 0x8A, + 0x72, 0xF4, 0xA3, 0xBF, 0x03, 0x4D, 0x2B, 0x4A + }, + { + 0x3A, 0x98, 0x8D, 0x38, 0xD7, 0x56, 0x11, 0xF3, + 0xEF, 0x38, 0xB8, 0x77, 0x49, 0x80, 0xB3, 0x3E, + 0x57, 0x3B, 0x6C, 0x57, 0xBE, 0xE0, 0x46, 0x9B, + 0xA5, 0xEE, 0xD9, 0xB4, 0x4F, 0x29, 0x94, 0x5E, + 0x73, 0x47, 0x96, 0x7F, 0xBA, 0x2C, 0x16, 0x2E, + 0x1C, 0x3B, 0xE7, 0xF3, 0x10, 0xF2, 0xF7, 0x5E, + 0xE2, 0x38, 0x1E, 0x7B, 0xFD, 0x6B, 0x3F, 0x0B, + 0xAE, 0xA8, 0xD9, 0x5D, 0xFB, 0x1D, 0xAF, 0xB1 + }, + { + 0x58, 0xAE, 0xDF, 0xCE, 0x6F, 0x67, 0xDD, 0xC8, + 0x5A, 0x28, 0xC9, 0x92, 0xF1, 0xC0, 0xBD, 0x09, + 0x69, 0xF0, 0x41, 0xE6, 0x6F, 0x1E, 0xE8, 0x80, + 0x20, 0xA1, 0x25, 0xCB, 0xFC, 0xFE, 0xBC, 0xD6, + 0x17, 0x09, 0xC9, 0xC4, 0xEB, 0xA1, 0x92, 0xC1, + 0x5E, 0x69, 0xF0, 0x20, 0xD4, 0x62, 0x48, 0x60, + 0x19, 0xFA, 0x8D, 0xEA, 0x0C, 0xD7, 0xA4, 0x29, + 0x21, 0xA1, 0x9D, 0x2F, 0xE5, 0x46, 0xD4, 0x3D + }, + { + 0x93, 0x47, 0xBD, 0x29, 0x14, 0x73, 0xE6, 0xB4, + 0xE3, 0x68, 0x43, 0x7B, 0x8E, 0x56, 0x1E, 0x06, + 0x5F, 0x64, 0x9A, 0x6D, 0x8A, 0xDA, 0x47, 0x9A, + 0xD0, 0x9B, 0x19, 0x99, 0xA8, 0xF2, 0x6B, 0x91, + 0xCF, 0x61, 0x20, 0xFD, 0x3B, 0xFE, 0x01, 0x4E, + 0x83, 0xF2, 0x3A, 0xCF, 0xA4, 0xC0, 0xAD, 0x7B, + 0x37, 0x12, 0xB2, 0xC3, 0xC0, 0x73, 0x32, 0x70, + 0x66, 0x31, 0x12, 0xCC, 0xD9, 0x28, 0x5C, 0xD9 + }, + { + 0xB3, 0x21, 0x63, 0xE7, 0xC5, 0xDB, 0xB5, 0xF5, + 0x1F, 0xDC, 0x11, 0xD2, 0xEA, 0xC8, 0x75, 0xEF, + 0xBB, 0xCB, 0x7E, 0x76, 0x99, 0x09, 0x0A, 0x7E, + 0x7F, 0xF8, 0xA8, 0xD5, 0x07, 0x95, 0xAF, 0x5D, + 0x74, 0xD9, 0xFF, 0x98, 0x54, 0x3E, 0xF8, 0xCD, + 0xF8, 0x9A, 0xC1, 0x3D, 0x04, 0x85, 0x27, 0x87, + 0x56, 0xE0, 0xEF, 0x00, 0xC8, 0x17, 0x74, 0x56, + 0x61, 0xE1, 0xD5, 0x9F, 0xE3, 0x8E, 0x75, 0x37 + }, + { + 0x10, 0x85, 0xD7, 0x83, 0x07, 0xB1, 0xC4, 0xB0, + 0x08, 0xC5, 0x7A, 0x2E, 0x7E, 0x5B, 0x23, 0x46, + 0x58, 0xA0, 0xA8, 0x2E, 0x4F, 0xF1, 0xE4, 0xAA, + 0xAC, 0x72, 0xB3, 0x12, 0xFD, 0xA0, 0xFE, 0x27, + 0xD2, 0x33, 0xBC, 0x5B, 0x10, 0xE9, 0xCC, 0x17, + 0xFD, 0xC7, 0x69, 0x7B, 0x54, 0x0C, 0x7D, 0x95, + 0xEB, 0x21, 0x5A, 0x19, 0xA1, 0xA0, 0xE2, 0x0E, + 0x1A, 0xBF, 0xA1, 0x26, 0xEF, 0xD5, 0x68, 0xC7 + }, + { + 0x4E, 0x5C, 0x73, 0x4C, 0x7D, 0xDE, 0x01, 0x1D, + 0x83, 0xEA, 0xC2, 0xB7, 0x34, 0x7B, 0x37, 0x35, + 0x94, 0xF9, 0x2D, 0x70, 0x91, 0xB9, 0xCA, 0x34, + 0xCB, 0x9C, 0x6F, 0x39, 0xBD, 0xF5, 0xA8, 0xD2, + 0xF1, 0x34, 0x37, 0x9E, 0x16, 0xD8, 0x22, 0xF6, + 0x52, 0x21, 0x70, 0xCC, 0xF2, 0xDD, 0xD5, 0x5C, + 0x84, 0xB9, 0xE6, 0xC6, 0x4F, 0xC9, 0x27, 0xAC, + 0x4C, 0xF8, 0xDF, 0xB2, 0xA1, 0x77, 0x01, 0xF2 + }, + { + 0x69, 0x5D, 0x83, 0xBD, 0x99, 0x0A, 0x11, 0x17, + 0xB3, 0xD0, 0xCE, 0x06, 0xCC, 0x88, 0x80, 0x27, + 0xD1, 0x2A, 0x05, 0x4C, 0x26, 0x77, 0xFD, 0x82, + 0xF0, 0xD4, 0xFB, 0xFC, 0x93, 0x57, 0x55, 0x23, + 0xE7, 0x99, 0x1A, 0x5E, 0x35, 0xA3, 0x75, 0x2E, + 0x9B, 0x70, 0xCE, 0x62, 0x99, 0x2E, 0x26, 0x8A, + 0x87, 0x77, 0x44, 0xCD, 0xD4, 0x35, 0xF5, 0xF1, + 0x30, 0x86, 0x9C, 0x9A, 0x20, 0x74, 0xB3, 0x38 + }, + { + 0xA6, 0x21, 0x37, 0x43, 0x56, 0x8E, 0x3B, 0x31, + 0x58, 0xB9, 0x18, 0x43, 0x01, 0xF3, 0x69, 0x08, + 0x47, 0x55, 0x4C, 0x68, 0x45, 0x7C, 0xB4, 0x0F, + 0xC9, 0xA4, 0xB8, 0xCF, 0xD8, 0xD4, 0xA1, 0x18, + 0xC3, 0x01, 0xA0, 0x77, 0x37, 0xAE, 0xDA, 0x0F, + 0x92, 0x9C, 0x68, 0x91, 0x3C, 0x5F, 0x51, 0xC8, + 0x03, 0x94, 0xF5, 0x3B, 0xFF, 0x1C, 0x3E, 0x83, + 0xB2, 0xE4, 0x0C, 0xA9, 0x7E, 0xBA, 0x9E, 0x15 + }, + { + 0xD4, 0x44, 0xBF, 0xA2, 0x36, 0x2A, 0x96, 0xDF, + 0x21, 0x3D, 0x07, 0x0E, 0x33, 0xFA, 0x84, 0x1F, + 0x51, 0x33, 0x4E, 0x4E, 0x76, 0x86, 0x6B, 0x81, + 0x39, 0xE8, 0xAF, 0x3B, 0xB3, 0x39, 0x8B, 0xE2, + 0xDF, 0xAD, 0xDC, 0xBC, 0x56, 0xB9, 0x14, 0x6D, + 0xE9, 0xF6, 0x81, 0x18, 0xDC, 0x58, 0x29, 0xE7, + 0x4B, 0x0C, 0x28, 0xD7, 0x71, 0x19, 0x07, 0xB1, + 0x21, 0xF9, 0x16, 0x1C, 0xB9, 0x2B, 0x69, 0xA9 + }, + { + 0x14, 0x27, 0x09, 0xD6, 0x2E, 0x28, 0xFC, 0xCC, + 0xD0, 0xAF, 0x97, 0xFA, 0xD0, 0xF8, 0x46, 0x5B, + 0x97, 0x1E, 0x82, 0x20, 0x1D, 0xC5, 0x10, 0x70, + 0xFA, 0xA0, 0x37, 0x2A, 0xA4, 0x3E, 0x92, 0x48, + 0x4B, 0xE1, 0xC1, 0xE7, 0x3B, 0xA1, 0x09, 0x06, + 0xD5, 0xD1, 0x85, 0x3D, 0xB6, 0xA4, 0x10, 0x6E, + 0x0A, 0x7B, 0xF9, 0x80, 0x0D, 0x37, 0x3D, 0x6D, + 0xEE, 0x2D, 0x46, 0xD6, 0x2E, 0xF2, 0xA4, 0x61 + }, +}; + + + + +static const uint8_t blake2sp_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0xDD, 0x0E, 0x89, 0x17, 0x76, 0x93, 0x3F, 0x43, + 0xC7, 0xD0, 0x32, 0xB0, 0x8A, 0x91, 0x7E, 0x25, + 0x74, 0x1F, 0x8A, 0xA9, 0xA1, 0x2C, 0x12, 0xE1, + 0xCA, 0xC8, 0x80, 0x15, 0x00, 0xF2, 0xCA, 0x4F + }, + { + 0xA6, 0xB9, 0xEE, 0xCC, 0x25, 0x22, 0x7A, 0xD7, + 0x88, 0xC9, 0x9D, 0x3F, 0x23, 0x6D, 0xEB, 0xC8, + 0xDA, 0x40, 0x88, 0x49, 0xE9, 0xA5, 0x17, 0x89, + 0x78, 0x72, 0x7A, 0x81, 0x45, 0x7F, 0x72, 0x39 + }, + { + 0xDA, 0xCA, 0xDE, 0xCE, 0x7A, 0x8E, 0x6B, 0xF3, + 0xAB, 0xFE, 0x32, 0x4C, 0xA6, 0x95, 0x43, 0x69, + 0x84, 0xB8, 0x19, 0x5D, 0x29, 0xF6, 0xBB, 0xD8, + 0x96, 0xE4, 0x1E, 0x18, 0xE2, 0x1C, 0x91, 0x45 + }, + { + 0xED, 0x14, 0x41, 0x3B, 0x40, 0xDA, 0x68, 0x9F, + 0x1F, 0x7F, 0xED, 0x2B, 0x08, 0xDF, 0xF4, 0x5B, + 0x80, 0x92, 0xDB, 0x5E, 0xC2, 0xC3, 0x61, 0x0E, + 0x02, 0x72, 0x4D, 0x20, 0x2F, 0x42, 0x3C, 0x46 + }, + { + 0x9B, 0x8A, 0x52, 0x7B, 0x52, 0x72, 0x25, 0x0A, + 0x1E, 0xC3, 0x97, 0x38, 0x8F, 0x04, 0x09, 0x14, + 0x95, 0x48, 0x06, 0xE7, 0x94, 0xDB, 0x04, 0xB7, + 0x0A, 0x46, 0x11, 0xBC, 0x59, 0x58, 0x6A, 0x83 + }, + { + 0x2B, 0xB6, 0x33, 0x37, 0x29, 0x00, 0x0B, 0xE3, + 0xD5, 0xA2, 0x1B, 0x98, 0xF8, 0xE7, 0xEA, 0xD0, + 0x77, 0xF1, 0x51, 0xA5, 0x39, 0x39, 0x19, 0xEB, + 0x67, 0xC8, 0x76, 0xEE, 0x00, 0xBB, 0xBB, 0x04 + }, + { + 0x63, 0xC0, 0x14, 0x08, 0x15, 0x4A, 0xD1, 0x9D, + 0x7F, 0xB7, 0x39, 0xF3, 0x11, 0x78, 0x17, 0x80, + 0x46, 0x2C, 0xF2, 0xEE, 0xCC, 0xE6, 0x0F, 0x06, + 0x4E, 0x85, 0x34, 0x87, 0xC2, 0x72, 0xE3, 0xEB + }, + { + 0x3D, 0x05, 0x1A, 0x11, 0x76, 0x01, 0x9C, 0xA3, + 0x7B, 0xF3, 0x3D, 0x60, 0x42, 0x7F, 0x8D, 0x9D, + 0x1C, 0x3A, 0xBD, 0x59, 0x82, 0x97, 0xCF, 0xB4, + 0x23, 0x5F, 0x74, 0x7D, 0x7C, 0x7C, 0x7F, 0xEC + }, + { + 0x39, 0x1E, 0xA9, 0x12, 0xDF, 0x4D, 0x4D, 0x79, + 0xA4, 0x64, 0x6D, 0x9D, 0xA2, 0x54, 0x9A, 0x44, + 0x6D, 0x22, 0x40, 0xF6, 0x24, 0x15, 0xD0, 0x70, + 0xA2, 0xE0, 0x93, 0x99, 0x2B, 0x47, 0x1F, 0xBA + }, + { + 0x32, 0x46, 0x40, 0x44, 0x0E, 0xA5, 0xC3, 0x08, + 0x2D, 0xDC, 0x30, 0x9E, 0x78, 0x09, 0xD7, 0x41, + 0xD6, 0xCC, 0x1B, 0x2D, 0x49, 0x0F, 0xF8, 0xC0, + 0x52, 0x12, 0x8A, 0x6E, 0xEB, 0x40, 0x9D, 0x62 + }, + { + 0xAB, 0x85, 0x5E, 0x6F, 0xA3, 0x9A, 0x5E, 0x8F, + 0xC9, 0x0E, 0xAC, 0xB9, 0x99, 0xC7, 0xF7, 0x8A, + 0xE7, 0x1E, 0x59, 0xC3, 0xD9, 0x7D, 0x60, 0xAF, + 0xE5, 0x17, 0xD5, 0x87, 0x92, 0x3B, 0x77, 0x11 + }, + { + 0x2A, 0x39, 0xDA, 0x45, 0x86, 0xEF, 0xC4, 0x77, + 0x85, 0xA7, 0xA8, 0xDA, 0x85, 0x68, 0x3A, 0x51, + 0x72, 0x4C, 0xDE, 0xF5, 0x41, 0x3B, 0x35, 0x6D, + 0xC4, 0xFB, 0x50, 0x05, 0x13, 0xF8, 0xFA, 0x2E + }, + { + 0x8A, 0x00, 0x57, 0xC1, 0xF7, 0x8A, 0xD6, 0x21, + 0x45, 0x55, 0xC0, 0x67, 0x07, 0x33, 0xE2, 0x9A, + 0x4C, 0x7E, 0x95, 0x62, 0x27, 0x66, 0x0E, 0xFE, + 0xB1, 0xD7, 0xFC, 0x79, 0xF5, 0x8E, 0xC6, 0xF2 + }, + { + 0x07, 0x64, 0xB0, 0x01, 0x7F, 0x5B, 0xD9, 0x51, + 0xF0, 0x1D, 0x9F, 0xDF, 0x95, 0xC0, 0xCB, 0x41, + 0x38, 0x98, 0x5D, 0x84, 0x79, 0x9C, 0xD4, 0x29, + 0x84, 0xE2, 0x5B, 0x51, 0x28, 0x00, 0xE7, 0x3C + }, + { + 0xCC, 0x02, 0x49, 0x56, 0x93, 0xC8, 0xE1, 0x84, + 0xAD, 0x2E, 0xD0, 0x9D, 0x53, 0x3D, 0xC3, 0x3B, + 0x76, 0xA7, 0x78, 0x3D, 0x62, 0x07, 0xFC, 0xAC, + 0xCB, 0x64, 0xF3, 0xED, 0x2C, 0x6D, 0x66, 0xE0 + }, + { + 0xC0, 0xDF, 0x49, 0xC2, 0x06, 0xA3, 0x42, 0x88, + 0x14, 0x32, 0x16, 0x84, 0x7D, 0xF3, 0x34, 0xD4, + 0x56, 0x9D, 0xAD, 0x73, 0xC2, 0xB1, 0xFF, 0x62, + 0x84, 0x88, 0x4F, 0xD3, 0x89, 0x41, 0xFB, 0x95 + }, + { + 0xB9, 0x19, 0x45, 0x19, 0xE4, 0x97, 0x8A, 0x9D, + 0xC8, 0x93, 0xB2, 0x8B, 0xD8, 0x08, 0xCD, 0xFA, + 0xBB, 0x1B, 0xD5, 0x10, 0xD8, 0x62, 0xB3, 0x17, + 0x1F, 0xF6, 0xE0, 0x17, 0xA4, 0x1B, 0x80, 0x4C + }, + { + 0xBB, 0xA9, 0x27, 0xAC, 0xF1, 0x1B, 0xEB, 0xD3, + 0x62, 0xA3, 0xA3, 0xEB, 0x78, 0xC4, 0xBB, 0x65, + 0xE6, 0x02, 0xA8, 0x70, 0x9F, 0xCE, 0xF3, 0x8D, + 0xC6, 0xC8, 0xB7, 0xBD, 0xA6, 0x64, 0xC3, 0x2C + }, + { + 0xEC, 0xB4, 0x90, 0x0A, 0x63, 0x92, 0x4E, 0x72, + 0x0D, 0x40, 0xF2, 0xD2, 0xB1, 0x4D, 0x1B, 0xB3, + 0x9C, 0x37, 0x01, 0xAD, 0x73, 0x46, 0xBD, 0x0B, + 0x67, 0x23, 0x42, 0x70, 0xBF, 0xBE, 0x7E, 0x70 + }, + { + 0xF8, 0x31, 0x5A, 0x21, 0xB2, 0x5E, 0x6B, 0xA8, + 0xBF, 0x59, 0xB1, 0x7B, 0x05, 0x91, 0x3B, 0x8C, + 0xA4, 0x65, 0x9F, 0x1C, 0xD8, 0x38, 0xFC, 0xC7, + 0x73, 0xC9, 0xEB, 0x12, 0xE7, 0x00, 0x4E, 0x09 + }, + { + 0x4B, 0x77, 0xAF, 0x67, 0xA9, 0x23, 0x2B, 0xF1, + 0x18, 0x4E, 0x57, 0x81, 0x82, 0x94, 0x03, 0x1E, + 0x55, 0xF1, 0xF8, 0x53, 0xC9, 0x4D, 0xBA, 0xB5, + 0x57, 0x75, 0x47, 0x33, 0x0D, 0x65, 0xAA, 0x61 + }, + { + 0x76, 0x85, 0x68, 0x39, 0x0F, 0xD2, 0xB8, 0x70, + 0x94, 0x11, 0x4E, 0xD4, 0xCF, 0x72, 0x3E, 0xA3, + 0x20, 0xFE, 0x97, 0x7B, 0x53, 0x18, 0x03, 0x05, + 0xC3, 0x84, 0x33, 0x54, 0x79, 0xF0, 0xB5, 0x9B + }, + { + 0xA4, 0x31, 0xCB, 0x27, 0x0F, 0x3E, 0x2C, 0x9B, + 0x7A, 0x95, 0x93, 0xB1, 0x55, 0xCC, 0xEC, 0xFF, + 0x5B, 0x5C, 0x4A, 0x2D, 0xCD, 0x5D, 0x6B, 0xB1, + 0xC4, 0x85, 0xAA, 0x28, 0x69, 0x97, 0xF9, 0x15 + }, + { + 0xD6, 0x91, 0xFA, 0x6A, 0x79, 0x0B, 0x1A, 0x51, + 0x79, 0x80, 0x08, 0x7F, 0x50, 0xB0, 0x3D, 0xED, + 0x8C, 0x6E, 0xD4, 0x86, 0xD0, 0x84, 0x22, 0x1C, + 0x82, 0x7D, 0x9B, 0xD9, 0x22, 0xBE, 0xB8, 0xC0 + }, + { + 0x8F, 0x97, 0x8A, 0x49, 0x32, 0xF4, 0x45, 0x98, + 0x13, 0xE8, 0xFE, 0x15, 0x68, 0x6E, 0x4E, 0xFA, + 0x25, 0xC2, 0xC5, 0xFF, 0x5A, 0x3A, 0x4F, 0x8C, + 0x9B, 0x14, 0x96, 0x5D, 0x2F, 0x0B, 0xE4, 0x61 + }, + { + 0x1E, 0xFB, 0xD0, 0xC1, 0x31, 0x44, 0x91, 0x42, + 0xF2, 0x29, 0x5F, 0x2D, 0x42, 0x41, 0x1D, 0xFE, + 0x0F, 0x48, 0xD4, 0xAC, 0xAE, 0x76, 0x2D, 0x8D, + 0xF6, 0x7A, 0x57, 0x0B, 0xF7, 0xB1, 0xDC, 0xD5 + }, + { + 0xD5, 0x3B, 0xA9, 0x33, 0x46, 0x14, 0x3A, 0xB8, + 0xE0, 0xD3, 0xD1, 0xBF, 0x27, 0x27, 0x06, 0xD1, + 0x69, 0xE6, 0x6C, 0x69, 0xC7, 0xB8, 0xF4, 0xA5, + 0xE8, 0x2F, 0xEF, 0x44, 0x07, 0x02, 0xBC, 0xF2 + }, + { + 0xF7, 0x1A, 0x3E, 0xC0, 0x1A, 0xA3, 0x82, 0xEA, + 0x76, 0x99, 0x2B, 0x43, 0x0A, 0x7F, 0x42, 0xC7, + 0xAD, 0x2A, 0x86, 0xAE, 0xA9, 0xC1, 0x9E, 0x76, + 0xCD, 0x17, 0x32, 0xEC, 0x68, 0x30, 0xDE, 0x6F + }, + { + 0x80, 0xA6, 0xAB, 0x7B, 0x71, 0x04, 0x64, 0xF9, + 0x3E, 0x6C, 0xBA, 0x96, 0x86, 0x4A, 0xA6, 0x40, + 0x9B, 0xCA, 0xFC, 0x1B, 0xF4, 0xB3, 0x2A, 0x30, + 0x93, 0x72, 0xE8, 0x57, 0xE8, 0x04, 0x06, 0x8C + }, + { + 0xDB, 0xDE, 0x81, 0xE5, 0x1A, 0x52, 0x17, 0x4B, + 0x10, 0x14, 0x90, 0x1B, 0x53, 0xBE, 0xF8, 0x8D, + 0xE9, 0x3B, 0x29, 0xE2, 0x74, 0x34, 0x7E, 0x8E, + 0x9A, 0x7B, 0x03, 0x74, 0x56, 0x62, 0x9F, 0x35 + }, + { + 0x75, 0xF2, 0x74, 0x46, 0x6B, 0x1A, 0x2D, 0x0F, + 0xD8, 0x45, 0xBB, 0xB5, 0x7C, 0x38, 0xC9, 0x89, + 0x51, 0x6E, 0x15, 0x68, 0x32, 0x0A, 0xB5, 0x17, + 0xB1, 0x63, 0xEA, 0xF7, 0x09, 0x23, 0x4C, 0xC7 + }, + { + 0xAF, 0xE1, 0xA0, 0x59, 0x1C, 0x49, 0x1D, 0x41, + 0x6E, 0xB6, 0x4F, 0x62, 0x86, 0xF3, 0xBA, 0x29, + 0xD4, 0xC9, 0x99, 0x82, 0x14, 0xA3, 0x83, 0x1C, + 0x39, 0x01, 0x4A, 0xC0, 0x30, 0x55, 0x79, 0x45 + }, + { + 0x67, 0xFF, 0x6A, 0xCD, 0xBE, 0x8A, 0x99, 0xA1, + 0x66, 0xA5, 0xD9, 0xCF, 0x32, 0x13, 0x65, 0x06, + 0xB5, 0x48, 0xD6, 0xC9, 0x47, 0xC2, 0x4C, 0x69, + 0x9C, 0xEA, 0x3A, 0xFD, 0x92, 0xAD, 0xFA, 0xCA + }, + { + 0xBF, 0xB4, 0xD0, 0xC7, 0x11, 0x20, 0x75, 0x26, + 0x2C, 0x2D, 0xD2, 0x48, 0xF3, 0x34, 0xB2, 0xEF, + 0x15, 0x40, 0x08, 0x7E, 0xCC, 0x73, 0x82, 0xBC, + 0x2A, 0x27, 0x25, 0x75, 0xC5, 0x00, 0x9F, 0x70 + }, + { + 0x17, 0xC9, 0x4B, 0x9C, 0x53, 0x72, 0x43, 0xF2, + 0x33, 0x5B, 0x86, 0x39, 0x49, 0xB2, 0xB9, 0x1C, + 0x98, 0xA6, 0x95, 0x6D, 0x7C, 0x10, 0xAA, 0x98, + 0x99, 0x59, 0xA8, 0x0F, 0x91, 0x0C, 0x25, 0x22 + }, + { + 0xF6, 0x33, 0x8F, 0x43, 0x4D, 0x31, 0x94, 0x10, + 0x19, 0x6D, 0x95, 0x19, 0xAB, 0xCA, 0xEF, 0xF7, + 0xD5, 0x54, 0x39, 0xFD, 0x2A, 0xA5, 0xBA, 0xBF, + 0x7A, 0x7E, 0x79, 0x13, 0xB2, 0x94, 0xED, 0x4D + }, + { + 0x08, 0xEF, 0x7D, 0x65, 0xF9, 0xBB, 0xF3, 0xDA, + 0x1F, 0x78, 0x84, 0xAE, 0x9B, 0x75, 0x90, 0x1F, + 0xD8, 0x52, 0x95, 0x66, 0x2A, 0x6E, 0xA7, 0x1D, + 0xE0, 0x8B, 0xEE, 0x38, 0x34, 0x57, 0x62, 0x78 + }, + { + 0x16, 0x47, 0xEC, 0xC2, 0xBA, 0x13, 0xF8, 0xB9, + 0x3B, 0x2F, 0xBC, 0xDC, 0x4E, 0x8F, 0x1D, 0xFA, + 0x47, 0xFE, 0x3B, 0xE1, 0x2A, 0xAA, 0x0E, 0x45, + 0x9B, 0x0E, 0x5A, 0x87, 0xF3, 0xA6, 0x9B, 0xB0 + }, + { + 0xFF, 0x92, 0x7A, 0x71, 0x78, 0x81, 0xF6, 0xFD, + 0x8E, 0xD8, 0xBF, 0x5D, 0x5E, 0x35, 0xBD, 0x80, + 0x16, 0x15, 0x73, 0xE5, 0x82, 0x94, 0x04, 0xC3, + 0x2D, 0x2A, 0x27, 0x6A, 0x01, 0xF4, 0xB9, 0x06 + }, + { + 0xC8, 0xCA, 0xF1, 0x36, 0xFF, 0x20, 0x9C, 0x82, + 0xE0, 0x24, 0x0C, 0x1E, 0x62, 0xA3, 0xBC, 0x7E, + 0x9C, 0xAC, 0x87, 0x3B, 0x01, 0x1C, 0xF7, 0xC5, + 0xE6, 0x7E, 0xC1, 0x87, 0xA5, 0xFB, 0xCD, 0x96 + }, + { + 0xD9, 0xAC, 0xC7, 0x3E, 0x3F, 0x42, 0x1E, 0x18, + 0x83, 0xB5, 0xED, 0x53, 0xD8, 0x2A, 0x9A, 0xEC, + 0x8F, 0x5D, 0xC9, 0x80, 0xC4, 0x2B, 0xCA, 0xEB, + 0x0E, 0x7D, 0x89, 0x76, 0xA3, 0x38, 0xEF, 0x51 + }, + { + 0x9F, 0x17, 0x3F, 0xCF, 0x08, 0xA5, 0x36, 0x21, + 0x93, 0xF3, 0x52, 0xC8, 0x25, 0x6A, 0xE5, 0x34, + 0xAE, 0x9C, 0xE7, 0xBF, 0xA4, 0xBC, 0x09, 0xFA, + 0xC9, 0x00, 0x98, 0xF9, 0x8A, 0x71, 0x62, 0x94 + }, + { + 0x0A, 0x72, 0x45, 0x79, 0xDC, 0x80, 0xBC, 0x0C, + 0x90, 0x04, 0xE5, 0x1B, 0xE7, 0xEF, 0xF3, 0xAF, + 0xA5, 0x30, 0x75, 0xAB, 0x4A, 0x32, 0x55, 0x77, + 0x33, 0x58, 0x6E, 0x82, 0x0F, 0xD3, 0x64, 0x23 + }, + { + 0x38, 0xF7, 0xC3, 0x40, 0xF4, 0xB1, 0x59, 0xB1, + 0xE5, 0x94, 0xF6, 0xEB, 0x83, 0x28, 0x49, 0x17, + 0xB7, 0xAA, 0x19, 0xC7, 0x4F, 0x57, 0x11, 0x7A, + 0x4E, 0x08, 0xCF, 0x7C, 0x4E, 0x32, 0xA2, 0x3C + }, + { + 0x1C, 0x67, 0x4B, 0xE2, 0x57, 0xE9, 0xB3, 0x31, + 0x34, 0xD4, 0x16, 0x8F, 0x15, 0x2F, 0x8B, 0x63, + 0xDF, 0xD7, 0x80, 0xC9, 0x7D, 0xC4, 0xDC, 0x37, + 0xAC, 0x26, 0xCC, 0x0A, 0xEF, 0xB7, 0x9C, 0x1A + }, + { + 0x2F, 0x0C, 0x59, 0x76, 0x16, 0xD5, 0x75, 0x17, + 0x14, 0xA5, 0xFB, 0x4E, 0xBF, 0x3C, 0x48, 0x1A, + 0x96, 0xC3, 0xAD, 0x14, 0x5E, 0xBD, 0xE0, 0x65, + 0x09, 0xF3, 0xA2, 0xE5, 0xF2, 0xC1, 0x3F, 0xC8 + }, + { + 0xFD, 0xDC, 0x69, 0xE0, 0xC9, 0x83, 0xCD, 0x82, + 0x83, 0xED, 0x81, 0x88, 0xBE, 0xC4, 0xE5, 0xF4, + 0x1D, 0xEA, 0x3D, 0x01, 0xB9, 0xE7, 0x4C, 0x4B, + 0xAF, 0x73, 0x41, 0xD8, 0xB4, 0xBF, 0x55, 0x3D + }, + { + 0x24, 0xD0, 0x83, 0xCB, 0xA0, 0x38, 0xC8, 0x7E, + 0x9A, 0xCB, 0x86, 0x81, 0x82, 0x02, 0x08, 0xB7, + 0x5C, 0xB3, 0x29, 0x3A, 0x96, 0xC9, 0xEF, 0xA7, + 0x5D, 0x2C, 0x63, 0xF1, 0x6B, 0x85, 0xFE, 0x1E + }, + { + 0x7F, 0x6A, 0x64, 0x9C, 0xCA, 0x89, 0xB2, 0x53, + 0xFF, 0xBD, 0x20, 0xC0, 0x16, 0x98, 0x01, 0x00, + 0xA8, 0x7C, 0x16, 0x81, 0x09, 0x62, 0x8F, 0xCC, + 0x66, 0x52, 0x5D, 0x8B, 0xAA, 0xFE, 0x50, 0x5F + }, + { + 0x6D, 0xA3, 0x73, 0xB4, 0xC1, 0x87, 0x92, 0xB3, + 0x20, 0x9A, 0xDD, 0x15, 0xA5, 0x07, 0x4A, 0x1D, + 0x70, 0xC1, 0x0B, 0xB3, 0x94, 0x80, 0xCA, 0x3F, + 0xE5, 0xC4, 0x39, 0xD9, 0x5F, 0xC2, 0x86, 0xCA + }, + { + 0x27, 0x0A, 0xFF, 0xA6, 0x42, 0x6F, 0x1A, 0x51, + 0x5C, 0x9B, 0x76, 0xDF, 0xC2, 0x7D, 0x18, 0x1F, + 0xC2, 0xFD, 0x57, 0xD0, 0x82, 0xA3, 0xBA, 0x2C, + 0x1E, 0xEF, 0x07, 0x15, 0x33, 0xA6, 0xDF, 0xB7 + }, + { + 0xC2, 0x2E, 0x15, 0xCF, 0xC5, 0xA3, 0xD1, 0x4B, + 0x64, 0xD1, 0x31, 0xF3, 0x5F, 0xB3, 0x5D, 0xD5, + 0xE6, 0xC5, 0x7D, 0xC4, 0xAF, 0xC5, 0x52, 0x27, + 0x75, 0x01, 0xEC, 0xA7, 0x64, 0xDA, 0x74, 0xBF + }, + { + 0xAD, 0x68, 0x3E, 0x96, 0xB8, 0xAC, 0x65, 0x8C, + 0x4F, 0x3F, 0x10, 0xAD, 0x22, 0xD9, 0x9B, 0x07, + 0xCB, 0x5E, 0xF9, 0xE3, 0x1C, 0xBE, 0x11, 0xE7, + 0xF7, 0xDC, 0x29, 0xF2, 0xAE, 0xE5, 0x02, 0x4C + }, + { + 0x78, 0xD3, 0xCE, 0xDA, 0x1C, 0xE0, 0x52, 0x93, + 0xF4, 0x30, 0xF6, 0x16, 0x7B, 0x33, 0xC9, 0x9F, + 0x0B, 0x1D, 0x6D, 0xAD, 0xE5, 0x21, 0x43, 0xC2, + 0x92, 0x55, 0x77, 0xC0, 0xBA, 0x82, 0x53, 0xEB + }, + { + 0xE0, 0x06, 0x45, 0x63, 0x44, 0xF9, 0x0F, 0x50, + 0x1C, 0x25, 0x81, 0x3F, 0x9B, 0xE2, 0xA3, 0xF4, + 0x0B, 0x98, 0x74, 0xFA, 0x05, 0x63, 0x98, 0x1C, + 0xD4, 0x56, 0xEE, 0x8D, 0x44, 0x80, 0x7C, 0x93 + }, + { + 0x39, 0x08, 0xE8, 0xD5, 0x47, 0xC0, 0xAF, 0xB1, + 0x13, 0x49, 0x49, 0x46, 0x63, 0x04, 0xA1, 0x45, + 0x02, 0x7E, 0x6B, 0xB7, 0xA7, 0x4D, 0xD1, 0xC1, + 0x62, 0xCD, 0xF0, 0xBC, 0xF7, 0x72, 0x37, 0xE8 + }, + { + 0x1B, 0x6C, 0x87, 0xA3, 0x48, 0x38, 0xC7, 0xCD, + 0x5F, 0xD0, 0x89, 0x14, 0x22, 0x4E, 0x90, 0xC2, + 0x2A, 0xBF, 0x5A, 0x97, 0xB1, 0x06, 0x46, 0xD9, + 0x8C, 0x49, 0x16, 0xD3, 0xA8, 0x93, 0x9E, 0x62 + }, + { + 0xB0, 0xD3, 0x8F, 0x82, 0xF2, 0x48, 0x91, 0x69, + 0x52, 0xB3, 0x16, 0xB6, 0xD3, 0x6D, 0x9E, 0x02, + 0x2D, 0xF6, 0xEE, 0xCC, 0x26, 0xC7, 0x62, 0xA6, + 0x55, 0xCF, 0x5F, 0x0A, 0xE6, 0x49, 0xE2, 0xBD + }, + { + 0x8D, 0x66, 0xFC, 0x9C, 0xED, 0xA5, 0xED, 0xDF, + 0xB1, 0xE0, 0x4D, 0x09, 0x6C, 0xA7, 0x0E, 0xF5, + 0x06, 0x50, 0xFB, 0x87, 0xCC, 0x6A, 0x9F, 0xFB, + 0xB3, 0xD2, 0x0B, 0xCE, 0x7B, 0x5A, 0x60, 0x74 + }, + { + 0x06, 0x43, 0x54, 0xE8, 0xE1, 0x1C, 0xF7, 0x13, + 0xB2, 0xC7, 0x2B, 0xA6, 0x7A, 0xC7, 0xD7, 0x6E, + 0x41, 0xBA, 0x61, 0xDB, 0x9C, 0x2D, 0xEA, 0x52, + 0x2E, 0x0B, 0xDA, 0x17, 0xCB, 0xA5, 0xE3, 0x92 + }, + { + 0xC8, 0xEF, 0x5F, 0x49, 0x8B, 0xD1, 0xBC, 0x70, + 0x7F, 0xBC, 0x7B, 0x5C, 0xBC, 0x2D, 0xFF, 0x04, + 0x93, 0x14, 0x4A, 0xC5, 0x27, 0x86, 0xDB, 0x3C, + 0x79, 0x3E, 0xF4, 0xAE, 0x8A, 0x83, 0x88, 0x47 + }, + { + 0x8A, 0x23, 0x97, 0xDF, 0x31, 0xE7, 0xF0, 0xCC, + 0x29, 0x0D, 0xA9, 0xA8, 0xBB, 0xE4, 0xF5, 0xF7, + 0xA3, 0xA1, 0x37, 0x50, 0x73, 0x0D, 0xB6, 0x2D, + 0xC2, 0x54, 0x0F, 0xDB, 0xD6, 0x18, 0x85, 0x89 + }, + { + 0xF1, 0x2D, 0x0B, 0x13, 0xC6, 0xAD, 0xFB, 0x3B, + 0xE5, 0x0A, 0x51, 0xEB, 0x6B, 0xAF, 0x65, 0xAB, + 0xFB, 0x17, 0x00, 0xBA, 0xA8, 0x7E, 0x52, 0x7D, + 0xBE, 0x3E, 0x67, 0x5A, 0x7A, 0x99, 0x46, 0x61 + }, + { + 0x10, 0x24, 0xC9, 0x40, 0xBE, 0x73, 0x41, 0x44, + 0x9B, 0x50, 0x10, 0x52, 0x2B, 0x50, 0x9F, 0x65, + 0xBB, 0xDC, 0x12, 0x87, 0xB4, 0x55, 0xC2, 0xBB, + 0x7F, 0x72, 0xB2, 0xC9, 0x2F, 0xD0, 0xD1, 0x89 + }, + { + 0x52, 0x60, 0x3B, 0x6C, 0xBF, 0xAD, 0x49, 0x66, + 0xCB, 0x04, 0x4C, 0xB2, 0x67, 0x56, 0x83, 0x85, + 0xCF, 0x35, 0xF2, 0x1E, 0x6C, 0x45, 0xCF, 0x30, + 0xAE, 0xD1, 0x98, 0x32, 0xCB, 0x51, 0xE9, 0xF5 + }, + { + 0xFF, 0xF2, 0x4D, 0x3C, 0xC7, 0x29, 0xD3, 0x95, + 0xDA, 0xF9, 0x78, 0xB0, 0x15, 0x73, 0x06, 0xCB, + 0x49, 0x57, 0x97, 0xE6, 0xC8, 0xDC, 0xA1, 0x73, + 0x1D, 0x2F, 0x6F, 0x81, 0xB8, 0x49, 0xBA, 0xAE + }, + { + 0x41, 0xEE, 0xE9, 0x0D, 0x47, 0xEC, 0x27, 0x72, + 0xCD, 0x35, 0x2D, 0xFD, 0x67, 0xE0, 0x60, 0x5F, + 0xBD, 0xFC, 0x5F, 0xD6, 0xD8, 0x26, 0x45, 0x1E, + 0x3D, 0x06, 0x4D, 0x38, 0x28, 0xBD, 0x3B, 0xAE + }, + { + 0x30, 0x0B, 0x6B, 0x36, 0xE5, 0x9F, 0x85, 0x1D, + 0xDD, 0xC2, 0x9B, 0xFA, 0x93, 0x08, 0x25, 0x20, + 0xCD, 0x77, 0xC5, 0x1E, 0x00, 0x7E, 0x00, 0xD2, + 0xD7, 0x8B, 0x26, 0xF4, 0xAF, 0x96, 0x15, 0x32 + }, + { + 0x9E, 0xF3, 0x03, 0x14, 0x83, 0x4E, 0x40, 0x1C, + 0x87, 0x1A, 0x20, 0x04, 0xE3, 0x8D, 0x5C, 0xE3, + 0x2E, 0xD2, 0x8E, 0x11, 0x37, 0xF1, 0x97, 0x0F, + 0x4F, 0x43, 0x78, 0xC7, 0x37, 0x06, 0x76, 0x3D + }, + { + 0x3F, 0xBD, 0xCD, 0xE7, 0xB6, 0x43, 0x04, 0x02, + 0x5E, 0xC0, 0x58, 0x26, 0x09, 0x03, 0x1E, 0xC2, + 0x66, 0xD5, 0x0F, 0x56, 0x83, 0x5A, 0xE0, 0xCB, + 0x72, 0xD8, 0xCD, 0xB4, 0xCF, 0xAF, 0x44, 0x19 + }, + { + 0xE9, 0x0E, 0xAD, 0x3B, 0x98, 0x2B, 0x43, 0x5B, + 0x66, 0x36, 0x6A, 0x49, 0x6C, 0x3F, 0x8A, 0xE6, + 0x5B, 0x17, 0x61, 0x37, 0x00, 0xF5, 0x47, 0x67, + 0x3F, 0x62, 0x15, 0x35, 0x41, 0x91, 0x28, 0x64 + }, + { + 0xAB, 0xE3, 0x54, 0x7B, 0x33, 0x6D, 0x6E, 0x24, + 0x0D, 0x7F, 0xE6, 0x82, 0xD7, 0x4B, 0x9C, 0xC7, + 0xE8, 0xD7, 0xF9, 0xB5, 0x66, 0x48, 0x58, 0xB9, + 0x4D, 0xF5, 0x9E, 0x9F, 0xC3, 0x30, 0xD9, 0xE5 + }, + { + 0xB2, 0x99, 0x64, 0x20, 0x95, 0xB8, 0x28, 0x6C, + 0x52, 0x1C, 0xDB, 0x21, 0xED, 0x0F, 0xE0, 0x57, + 0x27, 0x80, 0x21, 0xBB, 0x40, 0x38, 0xEB, 0x5A, + 0x3D, 0x79, 0x54, 0x2F, 0x5D, 0x75, 0x1F, 0x54 + }, + { + 0xE4, 0xD7, 0x58, 0x35, 0x9F, 0x08, 0x67, 0x93, + 0xA8, 0x37, 0x54, 0xAC, 0xA6, 0x96, 0x8C, 0x3E, + 0x9F, 0xD9, 0x4B, 0x40, 0x49, 0x7F, 0x2E, 0xC2, + 0x24, 0xA2, 0x91, 0x60, 0x63, 0xA2, 0x14, 0xA3 + }, + { + 0x59, 0xA3, 0x04, 0xFC, 0x03, 0xAB, 0x75, 0xD5, + 0x57, 0xDB, 0x04, 0xEB, 0xD0, 0x2D, 0xD4, 0xC6, + 0xB8, 0x10, 0xA1, 0x38, 0xBB, 0xFE, 0xEA, 0x5D, + 0xFC, 0xEE, 0xAA, 0x2B, 0x75, 0xB0, 0x64, 0x91 + }, + { + 0x39, 0x95, 0x10, 0x22, 0x15, 0xF5, 0xFE, 0x92, + 0x10, 0xEB, 0x30, 0xD9, 0x52, 0xD8, 0xC9, 0x19, + 0x58, 0x9E, 0x71, 0x45, 0xFC, 0xD4, 0x95, 0xEA, + 0x78, 0xD0, 0x2B, 0x9C, 0x14, 0x8F, 0xAF, 0x09 + }, + { + 0x47, 0x2E, 0xE7, 0x11, 0x56, 0x35, 0x06, 0xA5, + 0xF0, 0x08, 0x3F, 0xE8, 0x2B, 0x08, 0xB9, 0x92, + 0x3C, 0xF6, 0xC8, 0x40, 0x4D, 0x0C, 0xBA, 0xCB, + 0xF8, 0x48, 0x64, 0xF6, 0x48, 0x54, 0x2A, 0xC0 + }, + { + 0x68, 0xFD, 0xB8, 0x2A, 0xDA, 0xE7, 0x9B, 0xEF, + 0x59, 0x0A, 0xBA, 0x62, 0xD7, 0xAC, 0x55, 0x32, + 0x12, 0x06, 0x1C, 0x36, 0xE3, 0x6F, 0x12, 0xC0, + 0xEF, 0xA2, 0x9A, 0x17, 0x62, 0xDE, 0x3B, 0x6A + }, + { + 0x75, 0x85, 0xC0, 0x77, 0x33, 0x83, 0xF1, 0x74, + 0xFD, 0x66, 0x65, 0x49, 0xA8, 0x35, 0x2B, 0x30, + 0x5B, 0xF6, 0x85, 0x5B, 0xC9, 0x8B, 0xEA, 0x28, + 0xC3, 0x91, 0xB3, 0xC0, 0x34, 0xDA, 0x5A, 0x5A + }, + { + 0xAC, 0xC5, 0x75, 0xFE, 0x2C, 0xD7, 0xBA, 0x2A, + 0x31, 0xFC, 0x7D, 0x67, 0x0A, 0x92, 0x34, 0xAF, + 0x68, 0x50, 0x33, 0x86, 0xE9, 0x59, 0x07, 0x3D, + 0x16, 0xA8, 0x1B, 0x33, 0xB9, 0x22, 0xB5, 0x0E + }, + { + 0x9E, 0xC7, 0xD2, 0x99, 0x59, 0x43, 0xD3, 0x9D, + 0x6B, 0x97, 0x14, 0x93, 0xB8, 0x97, 0xA0, 0xEE, + 0x2D, 0x33, 0x92, 0xA7, 0x2D, 0xB8, 0x75, 0xC2, + 0x40, 0x5D, 0x35, 0x71, 0x78, 0xFB, 0x69, 0x11 + }, + { + 0x2D, 0x7E, 0xF1, 0x94, 0x01, 0x42, 0x5A, 0xBA, + 0x45, 0x0E, 0x82, 0xD3, 0x6D, 0x0F, 0xE7, 0xB2, + 0x08, 0x5E, 0xA0, 0xAF, 0x60, 0x45, 0xA5, 0x99, + 0x4C, 0xF4, 0x31, 0xEA, 0x59, 0x93, 0x9C, 0xC9 + }, + { + 0xF3, 0x2F, 0xD8, 0x55, 0xF0, 0x11, 0xC7, 0x18, + 0x02, 0x7F, 0x2E, 0xBE, 0x37, 0x7D, 0x69, 0x39, + 0xF1, 0x23, 0x70, 0xCA, 0xFF, 0x15, 0x1C, 0x1E, + 0x5A, 0xCE, 0x43, 0x8D, 0x70, 0x3C, 0x6D, 0x9F + }, + { + 0xB2, 0xBD, 0x83, 0xD2, 0x31, 0x0D, 0x3D, 0x7B, + 0x1D, 0x2D, 0x5A, 0xAF, 0x43, 0x59, 0xFA, 0xE2, + 0x86, 0x12, 0x96, 0x27, 0x19, 0xFD, 0xDE, 0x4D, + 0xDA, 0xF6, 0x9E, 0x78, 0x20, 0xF3, 0x3F, 0x61 + }, + { + 0x1A, 0x7A, 0x9D, 0x0F, 0x44, 0xDD, 0xFA, 0x7F, + 0xC2, 0xF4, 0x77, 0x0C, 0xAD, 0x74, 0x22, 0xFA, + 0x6C, 0x4E, 0x37, 0xE6, 0xCB, 0x03, 0x6D, 0x89, + 0x9E, 0x10, 0x27, 0x50, 0xE5, 0x94, 0xFF, 0xCD + }, + { + 0xDC, 0x69, 0xF6, 0x14, 0x1C, 0x8E, 0x10, 0x3F, + 0xF6, 0x1F, 0x62, 0x98, 0xA2, 0xC4, 0x4F, 0x52, + 0xD1, 0x47, 0x36, 0x6D, 0xDB, 0xD9, 0xC7, 0x9C, + 0xC3, 0x08, 0xFE, 0x84, 0x33, 0x6A, 0x95, 0x64 + }, + { + 0xE3, 0x4E, 0xD4, 0x17, 0xB0, 0x79, 0x1D, 0x9A, + 0x77, 0xEE, 0x1E, 0x50, 0xCC, 0x2C, 0x20, 0x7E, + 0x54, 0x0C, 0x77, 0x14, 0x04, 0x21, 0xC4, 0x6C, + 0xE0, 0x86, 0x28, 0x78, 0xAA, 0xEB, 0x27, 0x09 + }, + { + 0x21, 0x74, 0x42, 0x5C, 0x8C, 0xCA, 0xE3, 0x98, + 0xC4, 0xFF, 0x06, 0xF8, 0x48, 0x99, 0x1C, 0x5E, + 0x9B, 0xC0, 0xF3, 0x46, 0x11, 0x11, 0x70, 0x6F, + 0xB9, 0x5D, 0x0B, 0xE1, 0xC6, 0x8E, 0x47, 0x60 + }, + { + 0x18, 0x94, 0x58, 0x2A, 0x8A, 0x25, 0xFE, 0x8F, + 0x84, 0x7A, 0x4A, 0x03, 0x25, 0x74, 0xB7, 0x7B, + 0x8B, 0x36, 0xBF, 0x19, 0x99, 0x75, 0x26, 0xBB, + 0x4B, 0xC8, 0x5F, 0x38, 0x24, 0x53, 0x7F, 0xEB + }, + { + 0x17, 0xED, 0x18, 0x8A, 0xE3, 0xC9, 0x53, 0xD6, + 0x55, 0x44, 0x59, 0x83, 0xB8, 0x32, 0x5B, 0xAF, + 0xFF, 0x32, 0xE2, 0x22, 0xB2, 0xDF, 0xEB, 0x16, + 0xE8, 0x61, 0x7A, 0xBF, 0x86, 0xEE, 0x7C, 0xC5 + }, + { + 0xF1, 0x48, 0x9A, 0xD1, 0xC3, 0x54, 0xCD, 0xE9, + 0x78, 0x92, 0x37, 0xEA, 0x6D, 0xBF, 0x67, 0xFC, + 0x1E, 0x44, 0xD1, 0xAC, 0xC8, 0xDC, 0x66, 0xAD, + 0x83, 0x87, 0x27, 0xF4, 0x7D, 0x9A, 0x91, 0xFE + }, + { + 0x36, 0x7F, 0x22, 0x16, 0x5B, 0x8B, 0x66, 0xE9, + 0x7F, 0x66, 0x70, 0xF3, 0x4E, 0xBA, 0x27, 0x49, + 0xD2, 0x64, 0x3B, 0x21, 0xBE, 0xAD, 0xAD, 0xFE, + 0xFE, 0xA2, 0x57, 0x4B, 0x7C, 0x9B, 0x21, 0x96 + }, + { + 0x3D, 0x8D, 0xFE, 0xA1, 0x7E, 0xEA, 0x5D, 0x64, + 0x5A, 0xC1, 0xD4, 0x1A, 0x5B, 0x59, 0x22, 0x6C, + 0x48, 0x6C, 0x36, 0xBD, 0x77, 0xED, 0x44, 0xBB, + 0x34, 0x91, 0x70, 0xD0, 0x80, 0xE3, 0x0E, 0x68 + }, + { + 0x41, 0x15, 0xF8, 0x9E, 0x0B, 0x3B, 0x5C, 0x8F, + 0x61, 0x22, 0xC0, 0x25, 0x00, 0x17, 0x1D, 0xCF, + 0xFB, 0xCE, 0xA4, 0x66, 0x2A, 0x8C, 0x5F, 0x8C, + 0x1C, 0x01, 0xA9, 0xCA, 0x7B, 0x10, 0x27, 0xBB + }, + { + 0xED, 0x6E, 0x91, 0x0B, 0x96, 0x02, 0x55, 0xD7, + 0xD7, 0x92, 0xEB, 0xE6, 0x7F, 0x26, 0x0A, 0x14, + 0x3C, 0xFA, 0xC1, 0x05, 0x1D, 0xFC, 0x05, 0x90, + 0x25, 0xEE, 0x0C, 0x1B, 0xFC, 0xBC, 0x56, 0x81 + }, + { + 0x55, 0x8F, 0xA8, 0xAF, 0xA1, 0x2B, 0xBE, 0xE5, + 0x4A, 0xF7, 0x8F, 0x6B, 0x74, 0x45, 0xF9, 0x96, + 0x65, 0xD4, 0xE3, 0x56, 0xBC, 0x07, 0xD3, 0xEF, + 0xFD, 0x8F, 0xD6, 0x5A, 0xB9, 0xC7, 0x47, 0x16 + }, + { + 0x5B, 0x60, 0x12, 0x76, 0x20, 0x53, 0xB8, 0x73, + 0x4A, 0xF0, 0xE5, 0x55, 0xE6, 0xA2, 0xBB, 0x4F, + 0xD4, 0x84, 0x0A, 0xF3, 0xB0, 0x4F, 0xCF, 0x63, + 0x50, 0xA2, 0xB8, 0xA5, 0x1B, 0x67, 0x96, 0xAD + }, + { + 0xAB, 0x7A, 0xCC, 0xA5, 0xD7, 0x77, 0x10, 0xBA, + 0xD3, 0x7B, 0xA0, 0xFF, 0x4C, 0xEA, 0xE2, 0x7E, + 0x84, 0x71, 0x79, 0xF7, 0xFD, 0x7A, 0xEC, 0x88, + 0x69, 0xC6, 0x49, 0xB3, 0x3F, 0x8D, 0x25, 0x77 + }, + { + 0xFF, 0x77, 0x30, 0xB4, 0x74, 0xEC, 0x21, 0x45, + 0xA9, 0x2D, 0xD1, 0xCF, 0xFE, 0x45, 0xC3, 0x42, + 0xC6, 0xFD, 0x6B, 0xAC, 0x58, 0x0F, 0xF9, 0x5A, + 0x75, 0xED, 0xA3, 0xBF, 0x90, 0xEB, 0x4F, 0x01 + }, + { + 0xD1, 0x0F, 0x06, 0x1D, 0x5B, 0x9C, 0xB4, 0x4E, + 0xE0, 0x78, 0xA9, 0x6B, 0x33, 0x18, 0x57, 0x9E, + 0x5E, 0xF5, 0x0A, 0xEF, 0x3E, 0xD9, 0x6E, 0x4F, + 0x62, 0x14, 0x9B, 0x2E, 0x9F, 0x7C, 0x66, 0x0C + }, + { + 0x67, 0xD2, 0x2B, 0x8E, 0xDF, 0x20, 0x01, 0xD8, + 0x64, 0x22, 0x13, 0x6A, 0xC6, 0x51, 0x6C, 0xF3, + 0x9F, 0x7F, 0xC6, 0xA7, 0x02, 0x98, 0x92, 0xFD, + 0x75, 0xC9, 0x87, 0x90, 0x96, 0x4A, 0x72, 0x0B + }, + { + 0x7A, 0x5E, 0xC5, 0xBA, 0x76, 0x25, 0x9B, 0x07, + 0xB4, 0xDA, 0x03, 0xF3, 0x81, 0xFE, 0x7B, 0xEA, + 0x48, 0x65, 0xC8, 0x6C, 0x42, 0x4A, 0xBA, 0xA0, + 0xDD, 0x1E, 0xCF, 0x74, 0xF8, 0x7D, 0x2A, 0xC0 + }, + { + 0xE0, 0xFF, 0x60, 0xD6, 0x90, 0x29, 0xE6, 0xBD, + 0x1C, 0x15, 0x95, 0x3E, 0x91, 0x50, 0x9C, 0x0C, + 0x59, 0xED, 0x5D, 0xA5, 0x00, 0x01, 0x99, 0xF2, + 0x16, 0xD2, 0x9F, 0x96, 0x07, 0x9C, 0x2F, 0xEF + }, + { + 0xFC, 0x13, 0xEA, 0xD8, 0x41, 0x01, 0x8F, 0x59, + 0x90, 0x3B, 0x40, 0xF2, 0x02, 0x0C, 0x66, 0x38, + 0xA6, 0x6A, 0x54, 0xC3, 0xA3, 0x38, 0x41, 0x4D, + 0x97, 0xA5, 0xC3, 0x94, 0xF3, 0x26, 0x6F, 0x33 + }, + { + 0x0C, 0x2F, 0x62, 0xB8, 0x98, 0xFB, 0x2F, 0x63, + 0x61, 0x7E, 0x78, 0x73, 0x45, 0x26, 0x3C, 0xB9, + 0xCF, 0x60, 0x65, 0x4B, 0x55, 0x3B, 0x20, 0x3E, + 0xE4, 0x9D, 0xCB, 0xB8, 0xF2, 0xA6, 0xAF, 0xAC + }, + { + 0xD7, 0xD6, 0xCB, 0x55, 0x2A, 0xEB, 0x36, 0xEB, + 0x96, 0xB1, 0xD5, 0xE0, 0x52, 0xF8, 0xD9, 0x21, + 0xC3, 0x24, 0x5A, 0x97, 0x0D, 0x0B, 0xC8, 0x41, + 0x0C, 0xD6, 0x5E, 0xA1, 0x04, 0xC8, 0xE7, 0x79 + }, + { + 0xB7, 0x14, 0x1F, 0x30, 0x5E, 0xFD, 0xFE, 0xE5, + 0x56, 0xBD, 0x13, 0xE0, 0x40, 0x0D, 0x1E, 0x8C, + 0xFD, 0x65, 0x48, 0xBF, 0x81, 0xEE, 0x5D, 0x15, + 0x32, 0x7E, 0x49, 0x95, 0xCA, 0x8A, 0xD6, 0xFD + }, + { + 0xB6, 0xB6, 0x38, 0xD2, 0x2B, 0x7A, 0x12, 0x82, + 0x53, 0x74, 0xF7, 0x03, 0x48, 0xD7, 0x44, 0x8D, + 0x4E, 0x7D, 0x90, 0x8C, 0xF6, 0xE7, 0xBB, 0xEF, + 0x8C, 0x93, 0xEF, 0x67, 0x9B, 0x2A, 0x54, 0x78 + }, + { + 0x0D, 0xF4, 0x58, 0x56, 0x41, 0xFA, 0x09, 0xF6, + 0xCB, 0xA4, 0xCC, 0x16, 0x5A, 0x10, 0xAD, 0xDE, + 0x34, 0xF8, 0x0D, 0x42, 0x5A, 0x70, 0xDB, 0x67, + 0xE2, 0xFD, 0x23, 0x7B, 0x62, 0x7F, 0x43, 0x8A + }, + { + 0x10, 0x6B, 0x2B, 0x35, 0x4D, 0x95, 0xAC, 0xEC, + 0xD0, 0xD9, 0x58, 0x8F, 0xBC, 0x23, 0x1F, 0x8B, + 0xEA, 0x2E, 0x94, 0xEA, 0x66, 0x2D, 0xDD, 0x3F, + 0x13, 0x9E, 0x1B, 0x67, 0x87, 0x46, 0x1E, 0xED + }, + { + 0xAE, 0x5C, 0x69, 0xEE, 0xFE, 0x90, 0x89, 0xB2, + 0x9C, 0x6C, 0x1A, 0x23, 0x70, 0xD2, 0x05, 0x52, + 0xBA, 0x40, 0xC3, 0xD5, 0xE3, 0x71, 0x3C, 0x12, + 0xDE, 0xFC, 0xAE, 0x99, 0x7F, 0x43, 0x3E, 0xCD + }, + { + 0x1A, 0xAE, 0xF5, 0x5D, 0x4F, 0xA8, 0x92, 0xB6, + 0x35, 0xFB, 0x2A, 0x7A, 0x25, 0xF9, 0xA8, 0xE0, + 0x3B, 0x9F, 0xFB, 0x08, 0x2A, 0xE9, 0xC0, 0x7C, + 0x20, 0x42, 0xA0, 0x49, 0xC6, 0x51, 0x5E, 0x45 + }, + { + 0x29, 0x7D, 0xAA, 0xC4, 0xD5, 0x4D, 0xC4, 0x1C, + 0x83, 0xE3, 0x23, 0x94, 0x59, 0x9F, 0x17, 0x1C, + 0xDA, 0xA9, 0xDD, 0xB7, 0x17, 0x26, 0xDA, 0x4E, + 0xCE, 0x3C, 0xCF, 0x95, 0xC1, 0x1F, 0x56, 0xDF + }, + { + 0x2C, 0x45, 0xAC, 0xF4, 0x91, 0xEC, 0x2F, 0x4B, + 0x7E, 0x30, 0x9E, 0x7E, 0xDD, 0x81, 0x5B, 0xE5, + 0xA5, 0x4C, 0x44, 0x58, 0xD1, 0xA5, 0x7C, 0x4F, + 0x9B, 0x76, 0x3B, 0x0C, 0x67, 0x18, 0xD4, 0x3E + }, + { + 0x2F, 0x92, 0xF9, 0x01, 0x70, 0xD3, 0xAE, 0x95, + 0xAB, 0xFA, 0xC3, 0xA6, 0x98, 0x9A, 0x2A, 0x60, + 0xCB, 0x28, 0xB8, 0x58, 0x78, 0x2B, 0xE7, 0xEA, + 0x17, 0x9B, 0x48, 0xA7, 0x27, 0x6D, 0xD8, 0x60 + }, + { + 0xB4, 0x01, 0xE8, 0x4B, 0x15, 0xAC, 0xC4, 0x70, + 0x93, 0x6D, 0x6E, 0x37, 0xF7, 0x88, 0x83, 0x33, + 0x09, 0x27, 0x31, 0x13, 0x3B, 0x25, 0x1B, 0xEA, + 0x22, 0x16, 0x58, 0xCA, 0x19, 0xA7, 0x56, 0x69 + }, + { + 0xF8, 0xB3, 0x40, 0xD2, 0xB9, 0xB3, 0x3D, 0x43, + 0xA0, 0xA6, 0x6F, 0x34, 0x97, 0x82, 0x0A, 0xFA, + 0xAE, 0xE4, 0x34, 0xC4, 0xE3, 0xC0, 0xC1, 0x7E, + 0x89, 0x8B, 0x83, 0x01, 0xC5, 0x7A, 0x26, 0xBD + }, + { + 0x56, 0x6D, 0xA2, 0x83, 0x99, 0x03, 0x89, 0x13, + 0x8A, 0xA6, 0xF2, 0xAA, 0xA3, 0xB9, 0xE4, 0x0C, + 0xBF, 0x90, 0x84, 0x0E, 0xC7, 0x62, 0xBD, 0x96, + 0xB7, 0xE3, 0x3A, 0x31, 0x13, 0xB1, 0x01, 0x08 + }, + { + 0x34, 0x06, 0x72, 0xB7, 0x04, 0x67, 0x60, 0x42, + 0xC9, 0xBF, 0x3F, 0x33, 0x7B, 0xA7, 0x9F, 0x11, + 0x33, 0x6A, 0xEB, 0xB5, 0xEC, 0x5D, 0x31, 0xDF, + 0x54, 0xEB, 0x6A, 0xD3, 0xB0, 0x43, 0x04, 0x42 + }, + { + 0x50, 0x50, 0xB7, 0x3B, 0x93, 0x16, 0xEE, 0xA2, + 0xF1, 0x49, 0xBF, 0xFD, 0x22, 0xAE, 0xE3, 0x84, + 0xDC, 0x54, 0x03, 0xB1, 0x8E, 0x16, 0xFA, 0x88, + 0x82, 0x5E, 0x18, 0x16, 0x09, 0x49, 0x6F, 0xD2 + }, + { + 0x13, 0x65, 0xCC, 0x6F, 0xB9, 0x26, 0x0E, 0x86, + 0x88, 0x9B, 0x3A, 0xFB, 0xD1, 0xC8, 0xBC, 0x12, + 0x92, 0x31, 0x97, 0x71, 0x5D, 0xB2, 0x66, 0xCC, + 0x7A, 0x01, 0xCA, 0x57, 0x15, 0x9F, 0x75, 0x96 + }, + { + 0x29, 0x46, 0x6F, 0x51, 0xC0, 0x11, 0xFD, 0x10, + 0x18, 0x14, 0x94, 0xA9, 0x37, 0x9B, 0x61, 0x59, + 0xB8, 0x08, 0xAE, 0x0F, 0xCB, 0x01, 0x61, 0xF8, + 0xF0, 0x79, 0x09, 0xFF, 0x04, 0x1B, 0x19, 0x65 + }, + { + 0x65, 0x91, 0xA3, 0xC3, 0xC7, 0x67, 0xB3, 0x8D, + 0x80, 0x5E, 0xD3, 0xF7, 0xEB, 0x67, 0x63, 0xE8, + 0xB3, 0xD2, 0xD6, 0x42, 0xE7, 0x30, 0x77, 0x45, + 0xCD, 0x34, 0x18, 0xEF, 0xF6, 0x9A, 0x19, 0xED + }, + { + 0x1D, 0x84, 0xB0, 0x4B, 0x13, 0x38, 0xB0, 0xD2, + 0xE3, 0xC9, 0x8F, 0x7A, 0xEA, 0x3E, 0x98, 0xEF, + 0xFC, 0x53, 0x0A, 0x50, 0x44, 0xB9, 0x3B, 0x96, + 0xC6, 0x7E, 0xE3, 0x79, 0xD6, 0x2E, 0x81, 0x5F + }, + { + 0x6F, 0xA2, 0x95, 0x27, 0x25, 0x32, 0xE9, 0x83, + 0xE1, 0x66, 0xB1, 0x2E, 0x49, 0x99, 0xC0, 0x52, + 0xF8, 0x9D, 0x9F, 0x30, 0xAE, 0x14, 0x81, 0xF3, + 0xD6, 0x0E, 0xAE, 0x85, 0xF8, 0xEE, 0x17, 0x8A + }, + { + 0x4E, 0xD8, 0xCA, 0xA9, 0x8E, 0xC3, 0x9F, 0x6A, + 0x62, 0x9F, 0x9A, 0x65, 0x4A, 0x44, 0x7E, 0x7E, + 0x3E, 0x4F, 0xAE, 0xEC, 0xF3, 0x4D, 0xCF, 0x65, + 0x8D, 0x2D, 0x4B, 0x98, 0xB7, 0xA2, 0xEC, 0x1A + }, + { + 0xCF, 0xAB, 0x82, 0x99, 0xA0, 0xDA, 0x0C, 0x2A, + 0x7E, 0x8F, 0xF5, 0x4D, 0x0A, 0x67, 0x6D, 0x14, + 0x1A, 0xB2, 0x6B, 0xC0, 0x01, 0x2E, 0x5F, 0x66, + 0x8E, 0x85, 0xD8, 0x14, 0xBC, 0x98, 0x88, 0xB0 + }, + { + 0xA6, 0x26, 0x54, 0x3C, 0x27, 0x1F, 0xCC, 0xC3, + 0xE4, 0x45, 0x0B, 0x48, 0xD6, 0x6B, 0xC9, 0xCB, + 0xDE, 0xB2, 0x5E, 0x5D, 0x07, 0x7A, 0x62, 0x13, + 0xCD, 0x90, 0xCB, 0xBD, 0x0F, 0xD2, 0x20, 0x76 + }, + { + 0x05, 0xCF, 0x3A, 0x90, 0x04, 0x91, 0x16, 0xDC, + 0x60, 0xEF, 0xC3, 0x15, 0x36, 0xAA, 0xA3, 0xD1, + 0x67, 0x76, 0x29, 0x94, 0x89, 0x28, 0x76, 0xDC, + 0xB7, 0xEF, 0x3F, 0xBE, 0xCD, 0x74, 0x49, 0xC0 + }, + { + 0xCC, 0xD6, 0x1C, 0x92, 0x6C, 0xC1, 0xE5, 0xE9, + 0x12, 0x8C, 0x02, 0x1C, 0x0C, 0x6E, 0x92, 0xAE, + 0xFC, 0x4F, 0xFB, 0xDE, 0x39, 0x4D, 0xD6, 0xF3, + 0xB7, 0xD8, 0x7A, 0x8C, 0xED, 0x89, 0x60, 0x14 + }, + { + 0x3F, 0xFA, 0x4F, 0x6D, 0xAF, 0xA5, 0x7F, 0x1C, + 0x50, 0xF1, 0xAF, 0xA4, 0xF8, 0x12, 0x92, 0xAE, + 0x71, 0xA0, 0x6F, 0xE4, 0xF8, 0xFF, 0x46, 0xC5, + 0x1D, 0x32, 0xFF, 0x26, 0x13, 0x48, 0x9F, 0x2B + }, + { + 0x19, 0xD3, 0x92, 0x1C, 0xFC, 0x0F, 0x1A, 0x2B, + 0xB8, 0x13, 0xB3, 0xDF, 0xA9, 0x6D, 0xF9, 0x0E, + 0x2C, 0x6B, 0x87, 0xD7, 0x8E, 0x92, 0x38, 0xF8, + 0x5B, 0xBC, 0x77, 0xAE, 0x9A, 0x73, 0xF9, 0x8F + }, + { + 0xF5, 0xC9, 0x16, 0xFF, 0x2B, 0xAD, 0xDE, 0x3E, + 0x29, 0xA5, 0xF9, 0x40, 0x23, 0x3E, 0xA3, 0x40, + 0x07, 0xD8, 0xF1, 0x82, 0xA4, 0x8A, 0x80, 0x8B, + 0x46, 0xBB, 0x80, 0x58, 0x00, 0x3F, 0x19, 0x03 + }, + { + 0x6B, 0xA0, 0x7A, 0x1A, 0xF7, 0x58, 0xE6, 0x82, + 0xD3, 0xE0, 0x9A, 0xDD, 0x2D, 0x3D, 0xCD, 0xF3, + 0x5D, 0x95, 0x53, 0xF6, 0x79, 0x98, 0x54, 0xA2, + 0x7E, 0x53, 0x60, 0x63, 0xC5, 0x7F, 0x81, 0xA5 + }, + { + 0xB7, 0x83, 0x78, 0xFB, 0x44, 0x6C, 0x54, 0x4B, + 0x04, 0xD4, 0xA1, 0x52, 0xAC, 0x49, 0x57, 0x31, + 0x61, 0xB3, 0xDD, 0xEB, 0xF6, 0x93, 0x86, 0x77, + 0x0A, 0x55, 0xA7, 0xD4, 0x7B, 0x88, 0x0E, 0x5D + }, + { + 0xB5, 0x19, 0x53, 0x8F, 0xE1, 0x62, 0x6F, 0x0C, + 0x59, 0x59, 0x45, 0xAD, 0xA5, 0x8A, 0x34, 0x4F, + 0xAA, 0xC0, 0x06, 0x17, 0x61, 0xCC, 0x9D, 0x4A, + 0x84, 0x14, 0x19, 0xBD, 0x32, 0xEE, 0xC0, 0xD9 + }, + { + 0x96, 0xE4, 0x88, 0xB0, 0x27, 0x89, 0x64, 0x13, + 0xF4, 0x03, 0x4B, 0x03, 0x54, 0xF4, 0x84, 0x84, + 0xF6, 0xCF, 0xC1, 0x0F, 0x8E, 0xC5, 0x7B, 0x02, + 0x6F, 0xD2, 0x1A, 0x3B, 0x88, 0x36, 0x1A, 0x74 + }, + { + 0x77, 0x0C, 0x8A, 0x5F, 0x47, 0xBF, 0xD7, 0x69, + 0xCE, 0xD3, 0x5A, 0x71, 0xAF, 0xC3, 0xCA, 0x1F, + 0xF4, 0xC1, 0xF1, 0xE7, 0xCC, 0x3D, 0x23, 0x56, + 0xDE, 0x94, 0x50, 0x04, 0x36, 0x8D, 0x81, 0x45 + }, + { + 0x6D, 0xF9, 0xD8, 0xD0, 0xD3, 0xA8, 0xD9, 0x8C, + 0x83, 0x50, 0xD7, 0x16, 0x2B, 0xD1, 0x55, 0x79, + 0xD5, 0x70, 0x7A, 0xDD, 0x76, 0x11, 0xA0, 0x0E, + 0xEB, 0x6C, 0xA5, 0x74, 0x3E, 0xD7, 0x8C, 0xB7 + }, + { + 0x4F, 0x0F, 0xE8, 0xFC, 0x17, 0x90, 0x15, 0x91, + 0xCF, 0x34, 0x87, 0x30, 0xE1, 0x87, 0xDE, 0x52, + 0x3D, 0x6D, 0x75, 0x68, 0xC1, 0xFB, 0xD8, 0x24, + 0x85, 0x91, 0x39, 0x85, 0xEB, 0x67, 0x97, 0x1C + }, + { + 0x0E, 0xF3, 0xBB, 0x35, 0xCF, 0x37, 0x2B, 0xD9, + 0x4E, 0x3F, 0x80, 0xEE, 0xCE, 0xBD, 0x50, 0xEF, + 0x0D, 0x03, 0x08, 0xE0, 0x1E, 0x0E, 0xD6, 0xDE, + 0x0F, 0x5A, 0x8A, 0x8C, 0x81, 0x8A, 0x00, 0x74 + }, + { + 0xC0, 0x38, 0xD3, 0xE8, 0x09, 0xA5, 0xE3, 0xA5, + 0x8D, 0xB2, 0xF9, 0x1C, 0x15, 0xAE, 0x12, 0x43, + 0x95, 0x78, 0xF7, 0x54, 0x85, 0xCD, 0x84, 0xF5, + 0x56, 0xC6, 0x97, 0x1E, 0x8E, 0x25, 0x06, 0x20 + }, + { + 0xCE, 0x39, 0x9A, 0x0F, 0x08, 0x27, 0x7D, 0x8D, + 0x48, 0x16, 0x09, 0x50, 0x60, 0xEB, 0xBF, 0x33, + 0xDA, 0x01, 0x6F, 0xB4, 0x3A, 0x6C, 0x35, 0x6D, + 0x5A, 0x3F, 0xE4, 0xBB, 0x57, 0x4C, 0x5E, 0x7B + }, + { + 0x86, 0x9F, 0x7E, 0x31, 0x6B, 0x19, 0x4F, 0x95, + 0x31, 0xBC, 0xAF, 0x33, 0xF7, 0x91, 0x3F, 0x1B, + 0x9C, 0xFC, 0x6B, 0xB5, 0xDC, 0xF8, 0x6B, 0x69, + 0x2B, 0xF8, 0xCA, 0xB2, 0x9B, 0x8A, 0xA9, 0x6F + }, + { + 0x32, 0x7D, 0xFA, 0x46, 0x44, 0x59, 0xD9, 0xE4, + 0x8F, 0x5E, 0x55, 0xC7, 0xF5, 0xBA, 0xA6, 0x8F, + 0xC4, 0xA2, 0x5A, 0xD6, 0x22, 0xBC, 0x7B, 0xF0, + 0x1A, 0xCA, 0x82, 0xFD, 0x5E, 0x72, 0x31, 0x4C + }, + { + 0xE0, 0x0D, 0xAD, 0x31, 0x51, 0xB9, 0x08, 0x5E, + 0xAE, 0x78, 0x69, 0x84, 0xFE, 0x20, 0x73, 0x52, + 0x32, 0xB7, 0xFF, 0x7F, 0x1B, 0x1D, 0xB7, 0x96, + 0x1F, 0xD0, 0xD0, 0xE0, 0xF6, 0x05, 0xDB, 0x9A + }, + { + 0x07, 0x6F, 0x64, 0x45, 0x20, 0xD0, 0xB4, 0x73, + 0x2D, 0x6C, 0x53, 0x1C, 0x93, 0x49, 0x08, 0x90, + 0x26, 0x93, 0x6D, 0x99, 0x82, 0x04, 0x61, 0xDA, + 0x87, 0x74, 0x9A, 0x52, 0x0F, 0xBE, 0x90, 0xCE + }, + { + 0xB4, 0x41, 0x4C, 0xA1, 0x37, 0x3B, 0xE4, 0x6F, + 0x15, 0xCE, 0xA6, 0xB1, 0x25, 0x5A, 0x7D, 0x18, + 0x86, 0xC6, 0xFD, 0xB0, 0x8E, 0xD5, 0xAF, 0x96, + 0x57, 0xD5, 0xAA, 0xC3, 0x17, 0xDE, 0x3A, 0x29 + }, + { + 0x8D, 0x1A, 0xB0, 0x26, 0x3D, 0xAB, 0x7B, 0x86, + 0xEC, 0xEE, 0x21, 0x91, 0x62, 0xD9, 0x99, 0xA0, + 0x12, 0x45, 0x57, 0x22, 0x69, 0xDE, 0x31, 0x10, + 0x0E, 0x5D, 0x88, 0xFC, 0x1B, 0x1E, 0xAA, 0x69 + }, + { + 0xB4, 0x8D, 0x1C, 0x1F, 0x83, 0x92, 0x4A, 0x02, + 0xA2, 0x3E, 0x5E, 0x0F, 0x97, 0x1E, 0x16, 0xE8, + 0x7F, 0xC4, 0x88, 0x48, 0x53, 0x83, 0x34, 0x85, + 0x19, 0x1A, 0x2B, 0x60, 0x72, 0x2F, 0xE2, 0x69 + }, + { + 0xF2, 0xED, 0xD5, 0xF7, 0x50, 0xA2, 0x0A, 0x54, + 0x1D, 0x3F, 0x6B, 0xD5, 0xDF, 0x80, 0x83, 0x8F, + 0x11, 0x82, 0x5B, 0x25, 0xA9, 0x8F, 0x3D, 0xA5, + 0xE1, 0x52, 0x3B, 0xFF, 0x81, 0x3B, 0xB5, 0x60 + }, + { + 0x07, 0x16, 0x60, 0x04, 0xEF, 0x88, 0xE1, 0x61, + 0x4E, 0xBD, 0xC8, 0x87, 0xDF, 0xC7, 0xDA, 0x42, + 0xEB, 0xCD, 0xA0, 0x2D, 0x92, 0xC1, 0x2F, 0x18, + 0xD1, 0x18, 0x6C, 0xE3, 0xC9, 0x87, 0x10, 0xE4 + }, + { + 0x69, 0xF8, 0x3A, 0xA1, 0x01, 0xD6, 0x9B, 0x8F, + 0x12, 0x20, 0xDC, 0x1C, 0x53, 0x8D, 0x89, 0x34, + 0x45, 0x84, 0x20, 0xBE, 0x33, 0x5F, 0xEB, 0x46, + 0xFF, 0xC4, 0x7A, 0x2C, 0x8E, 0x2E, 0x6A, 0x8A + }, + { + 0xE1, 0x46, 0x9F, 0x16, 0xC6, 0xFC, 0xA1, 0x51, + 0x19, 0xA2, 0x72, 0xE5, 0x85, 0xC7, 0xF5, 0x04, + 0x21, 0xBC, 0x8A, 0x41, 0x4C, 0x86, 0x4F, 0xC7, + 0x6B, 0x01, 0x04, 0x8D, 0x4C, 0x6F, 0xC5, 0xD2 + }, + { + 0x67, 0x63, 0x34, 0x3A, 0x1C, 0x80, 0xF1, 0x92, + 0x83, 0xA8, 0x0A, 0xF8, 0x54, 0xE7, 0xE9, 0x06, + 0x5C, 0x2A, 0x83, 0x49, 0xEF, 0x11, 0xF1, 0x1B, + 0xFB, 0x76, 0xBA, 0x9F, 0x97, 0x04, 0x85, 0x39 + }, + { + 0x1A, 0xE3, 0xA0, 0xB8, 0xB2, 0xC7, 0x88, 0x5B, + 0xA3, 0x18, 0xAD, 0x6F, 0xD4, 0x49, 0xFC, 0x4D, + 0x7F, 0x84, 0x04, 0xB5, 0x9C, 0xF3, 0x27, 0x5F, + 0xCD, 0xEA, 0x13, 0x56, 0x34, 0x25, 0x77, 0x2D + }, + { + 0x3A, 0x71, 0x18, 0x4C, 0xBE, 0x8E, 0xB5, 0x8E, + 0x68, 0x12, 0xBA, 0x7A, 0x7A, 0x1D, 0xCA, 0x0C, + 0xA2, 0x8E, 0xEC, 0x63, 0x78, 0x2F, 0x2E, 0x6E, + 0x3C, 0x0B, 0x87, 0x07, 0x3F, 0x53, 0x3F, 0xFD + }, + { + 0x18, 0x4C, 0xCF, 0x2A, 0x52, 0xF3, 0x88, 0xC9, + 0xF8, 0x97, 0xA8, 0x57, 0xFE, 0x7C, 0xCE, 0xC2, + 0x95, 0x99, 0x11, 0xA8, 0xD1, 0xE0, 0x9E, 0xE8, + 0x80, 0x4D, 0x8D, 0x5D, 0x50, 0x8D, 0xD9, 0x18 + }, + { + 0xA6, 0x6D, 0x40, 0x9A, 0xF7, 0xAF, 0xD7, 0x5B, + 0xE8, 0x31, 0xDD, 0x49, 0x8C, 0x19, 0x6E, 0xF1, + 0x2C, 0x73, 0xC3, 0x11, 0x29, 0xEC, 0x02, 0xD5, + 0xF1, 0x2A, 0xB0, 0x2A, 0x2C, 0x63, 0xA2, 0x5E + }, + { + 0x58, 0xB3, 0x74, 0x97, 0xFC, 0xF0, 0xBE, 0x0E, + 0x0C, 0xF1, 0x73, 0x40, 0x45, 0xC2, 0x95, 0xB2, + 0x86, 0xC7, 0x6A, 0x7C, 0x04, 0x8E, 0x87, 0xC5, + 0x40, 0x28, 0xED, 0x36, 0x91, 0x5B, 0x5D, 0xF3 + }, + { + 0x2C, 0x73, 0x33, 0x54, 0x0A, 0x83, 0x2D, 0x64, + 0x45, 0x6E, 0x43, 0x05, 0x8C, 0x50, 0xD9, 0x3C, + 0x93, 0x2A, 0xD9, 0xB1, 0x8B, 0x3F, 0xC3, 0xA0, + 0x59, 0x92, 0x07, 0xCD, 0xA3, 0xB3, 0xC7, 0xA6 + }, + { + 0x3D, 0xC0, 0x62, 0xFF, 0xB5, 0x7D, 0x83, 0x5F, + 0xE3, 0xAA, 0x40, 0x94, 0x66, 0x82, 0x2F, 0x91, + 0x86, 0x91, 0x84, 0x23, 0x94, 0x75, 0x05, 0x16, + 0x5F, 0xDC, 0xDF, 0xB7, 0x30, 0x6F, 0x72, 0x59 + }, + { + 0x89, 0x20, 0x48, 0x44, 0xAC, 0xB9, 0x2F, 0x35, + 0x3B, 0xFC, 0x89, 0xA3, 0xCE, 0x8A, 0x98, 0x17, + 0x21, 0x9C, 0x10, 0x13, 0x85, 0xC5, 0x93, 0xCF, + 0x60, 0xE0, 0xBE, 0xFA, 0x96, 0x38, 0xE1, 0x4E + }, + { + 0x78, 0x2B, 0xA9, 0x02, 0xE9, 0x12, 0x32, 0x94, + 0x1C, 0x78, 0xC4, 0x9C, 0xD9, 0x77, 0x1A, 0x5D, + 0x99, 0x92, 0xF9, 0xB0, 0x7D, 0x9C, 0x0A, 0x2D, + 0xF8, 0x2D, 0x38, 0x5D, 0x15, 0xC4, 0x2B, 0xB3 + }, + { + 0x0D, 0xC3, 0xFF, 0x7D, 0xF0, 0xDF, 0xC0, 0x23, + 0x76, 0x3D, 0x76, 0x34, 0xE1, 0x8D, 0xA2, 0x73, + 0x93, 0xFC, 0x9F, 0xDB, 0x1C, 0x15, 0x46, 0x46, + 0x86, 0x10, 0x75, 0xF0, 0xA8, 0x7D, 0x0E, 0x90 + }, + { + 0xB9, 0x5C, 0x65, 0xFB, 0x6F, 0x25, 0x4E, 0xDB, + 0xDE, 0x8C, 0x03, 0x7D, 0x5C, 0x8B, 0x20, 0x39, + 0x34, 0x0F, 0x4A, 0xC2, 0xB0, 0x23, 0xA6, 0xAA, + 0x28, 0xA8, 0xFC, 0xD2, 0xD2, 0x68, 0x9C, 0xF4 + }, + { + 0x87, 0xE8, 0xF5, 0x15, 0x72, 0xA5, 0xD6, 0xA2, + 0x39, 0xF8, 0x5B, 0xC5, 0x3E, 0x11, 0x74, 0xE1, + 0x5B, 0xE1, 0x2F, 0xCD, 0xF1, 0x51, 0xA0, 0xB9, + 0xA2, 0xB4, 0x36, 0x40, 0xCA, 0xF7, 0x4C, 0x1D + }, + { + 0x2A, 0x6F, 0x3E, 0x46, 0x2C, 0x40, 0x5C, 0x35, + 0x4F, 0xE8, 0x0F, 0xCC, 0xCE, 0xD1, 0xC9, 0xBE, + 0x44, 0x32, 0x5D, 0x29, 0xE0, 0x7D, 0xA3, 0x09, + 0x60, 0xB6, 0x25, 0xA7, 0x6E, 0xA4, 0x2F, 0x83 + }, + { + 0x20, 0xB4, 0x6C, 0x8F, 0xBF, 0xCA, 0x97, 0x45, + 0x32, 0x62, 0x46, 0x0F, 0x84, 0x98, 0xA7, 0xE2, + 0xAF, 0x15, 0xAC, 0x79, 0xB5, 0x9D, 0xDF, 0xB0, + 0x27, 0xBB, 0x52, 0xF2, 0xD6, 0x8E, 0x8F, 0x51 + }, + { + 0x31, 0xB0, 0x76, 0x3C, 0xB9, 0xBA, 0x92, 0x40, + 0x3D, 0xCA, 0x1A, 0xBD, 0xD7, 0x34, 0x2D, 0x7D, + 0xE9, 0x4C, 0x58, 0x1E, 0x76, 0xF7, 0xC9, 0xA6, + 0x1E, 0x51, 0x59, 0x28, 0xE1, 0x0B, 0x4E, 0x77 + }, + { + 0xE1, 0x91, 0xE1, 0x17, 0x06, 0x3C, 0xFA, 0xC9, + 0x64, 0x2C, 0xD9, 0x3C, 0xB4, 0x2B, 0x39, 0xED, + 0xDD, 0x9E, 0x4A, 0xB6, 0x5F, 0x1D, 0x03, 0x97, + 0xE3, 0xE1, 0x7D, 0xD0, 0x4C, 0xAB, 0x11, 0x80 + }, + { + 0x22, 0x5A, 0x20, 0x21, 0x07, 0xA7, 0x47, 0x03, + 0xE0, 0x41, 0xC6, 0xCC, 0xA4, 0xEA, 0xCF, 0x4F, + 0x21, 0xEE, 0xA6, 0xF2, 0x2A, 0x14, 0x6D, 0x8D, + 0xA2, 0xAB, 0x8C, 0xF6, 0x19, 0x72, 0x29, 0xA5 + }, + { + 0xEF, 0xC4, 0x83, 0x6B, 0xE4, 0xAC, 0x3E, 0x97, + 0x91, 0xD2, 0xEC, 0x62, 0x22, 0x6E, 0x7D, 0xF6, + 0x41, 0x18, 0xF4, 0x56, 0x5C, 0x19, 0xE6, 0xC9, + 0xE8, 0x40, 0x63, 0xF5, 0x66, 0x1C, 0x7B, 0x2F + }, + { + 0x3A, 0x76, 0xB0, 0x15, 0x2C, 0x0E, 0x1D, 0x1F, + 0xD7, 0xAC, 0x9D, 0x91, 0xA2, 0x8A, 0x18, 0xE1, + 0xA4, 0xC0, 0x60, 0x80, 0xF2, 0xB7, 0xEC, 0xEF, + 0xB6, 0xEF, 0xFE, 0x28, 0xB8, 0xCF, 0xC7, 0x65 + }, + { + 0x0D, 0x46, 0xAD, 0x03, 0x90, 0x70, 0x11, 0x58, + 0x28, 0xF9, 0x4E, 0xB6, 0xB7, 0x29, 0x63, 0xE6, + 0x0A, 0x7D, 0x2D, 0xB7, 0xCA, 0x89, 0x91, 0xD2, + 0x25, 0xC3, 0x87, 0x7B, 0x14, 0x9B, 0x0A, 0x8A + }, + { + 0xE4, 0x4C, 0xFC, 0x42, 0x11, 0x8F, 0x09, 0x6B, + 0xFC, 0x51, 0x52, 0x1C, 0xB1, 0x8D, 0x5D, 0x65, + 0x25, 0x58, 0x6B, 0x98, 0x9F, 0x4E, 0xE2, 0xB8, + 0x28, 0xC5, 0x19, 0x9F, 0xEA, 0xB9, 0x4B, 0x82 + }, + { + 0x6D, 0x4B, 0xD2, 0xE0, 0x73, 0xEC, 0x49, 0x66, + 0x84, 0x7F, 0x5C, 0xBE, 0x88, 0xDD, 0xFA, 0xBA, + 0x2B, 0xE4, 0xCA, 0xF2, 0xF3, 0x33, 0x55, 0x2B, + 0x85, 0x53, 0xDA, 0x53, 0x34, 0x87, 0xC2, 0x5B + }, + { + 0xBB, 0xC4, 0x6D, 0xB4, 0x37, 0xD1, 0x07, 0xC9, + 0x67, 0xCA, 0x6D, 0x91, 0x45, 0x5B, 0xBD, 0xFE, + 0x05, 0x21, 0x18, 0xAB, 0xD1, 0xD0, 0x69, 0xF0, + 0x43, 0x59, 0x48, 0x7E, 0x13, 0xAE, 0xA0, 0xE1 + }, + { + 0xB9, 0x74, 0xC1, 0x4D, 0xB7, 0xD3, 0x17, 0x4D, + 0xD0, 0x60, 0x84, 0xBB, 0x30, 0x31, 0x08, 0xB2, + 0xF0, 0xDA, 0xF5, 0x0E, 0xCC, 0xC3, 0x29, 0x35, + 0x43, 0x79, 0x5C, 0x96, 0x36, 0xC6, 0x24, 0x82 + }, + { + 0x0E, 0xEE, 0x23, 0x5B, 0x06, 0x93, 0x6A, 0xED, + 0x71, 0x73, 0xC8, 0xC1, 0x9A, 0xA7, 0xC2, 0x17, + 0xB9, 0xEE, 0xDA, 0xEB, 0x1A, 0x88, 0xF3, 0x05, + 0x52, 0xE9, 0x22, 0x51, 0x45, 0x14, 0x9E, 0x82 + }, + { + 0x36, 0xD0, 0x89, 0xE0, 0x25, 0xB5, 0x68, 0x69, + 0x37, 0x74, 0x28, 0x25, 0xE6, 0xEE, 0x3D, 0x83, + 0xE7, 0xD7, 0xA5, 0x0C, 0x82, 0x3C, 0x82, 0x88, + 0x34, 0x60, 0xF3, 0x85, 0x14, 0x7D, 0xC1, 0x7B + }, + { + 0x77, 0xEE, 0x4F, 0xFC, 0x9F, 0x5D, 0xD6, 0x05, + 0x47, 0x0D, 0xC0, 0xE7, 0x4D, 0x6B, 0x17, 0xC5, + 0x13, 0x0D, 0x8B, 0x73, 0x91, 0x3F, 0x36, 0xD5, + 0xF8, 0x78, 0x7E, 0x61, 0x9A, 0x94, 0x7C, 0xA0 + }, + { + 0x0F, 0xE6, 0xC2, 0xAB, 0x75, 0x42, 0x33, 0x36, + 0x0D, 0x68, 0xB9, 0xAC, 0x80, 0xCD, 0x61, 0x18, + 0x4B, 0xFA, 0xA7, 0xD3, 0x56, 0x29, 0x41, 0x80, + 0x02, 0x5F, 0xE4, 0x06, 0x39, 0xC7, 0x6C, 0x36 + }, + { + 0x99, 0x60, 0x88, 0xC7, 0x94, 0x56, 0xEC, 0xDD, + 0xA1, 0xFB, 0xC0, 0x2E, 0xE1, 0xBA, 0x42, 0xD9, + 0x1D, 0x85, 0x8C, 0x31, 0x0A, 0x5A, 0x8B, 0x46, + 0x74, 0xFE, 0x6A, 0x7C, 0x14, 0x44, 0x14, 0xA1 + }, + { + 0x9E, 0x33, 0x8A, 0xED, 0x0B, 0xC7, 0x1C, 0x0C, + 0x97, 0xF1, 0x98, 0x55, 0xBF, 0x49, 0x17, 0x4F, + 0x70, 0xA9, 0xD7, 0x70, 0x14, 0x87, 0x36, 0x63, + 0x21, 0x34, 0x27, 0x50, 0x2B, 0xD8, 0x5D, 0x9F + }, + { + 0x4A, 0x84, 0x3D, 0x26, 0xAD, 0xEC, 0x52, 0x0E, + 0x4B, 0x5D, 0xBF, 0x01, 0x45, 0xCC, 0x4F, 0x50, + 0x24, 0xFA, 0xFC, 0xDC, 0x20, 0x25, 0x82, 0x4A, + 0x8C, 0x64, 0x65, 0x06, 0x17, 0x68, 0x7E, 0xE7 + }, + { + 0xC9, 0x16, 0x78, 0xC4, 0xA6, 0x4E, 0x2F, 0xA4, + 0xB7, 0x4D, 0xE6, 0x1A, 0xD0, 0xC0, 0x6F, 0xF0, + 0x6B, 0x5D, 0x67, 0x2F, 0xA7, 0xC6, 0x87, 0x7A, + 0x40, 0x14, 0xCE, 0x9E, 0x91, 0xBE, 0x38, 0xD7 + }, + { + 0xFF, 0x77, 0x77, 0x40, 0x5D, 0x32, 0x7A, 0xDB, + 0x58, 0x30, 0x1C, 0x71, 0x1E, 0xCD, 0xC2, 0xBC, + 0xE1, 0xBF, 0xA8, 0x29, 0xFF, 0xC9, 0xB1, 0x17, + 0xF2, 0x1A, 0x2B, 0x19, 0x8D, 0x0D, 0x68, 0x84 + }, + { + 0x0A, 0x8D, 0xDA, 0xF1, 0x72, 0x8C, 0x5C, 0xD9, + 0x3A, 0x25, 0x5D, 0x56, 0x23, 0xC3, 0xDA, 0xDA, + 0x2D, 0x3D, 0x05, 0x71, 0xBF, 0x14, 0x38, 0xAD, + 0xC8, 0xC9, 0x64, 0xA9, 0xAA, 0xD1, 0x18, 0xCB + }, + { + 0xC1, 0x33, 0xAB, 0xBD, 0x0D, 0x2D, 0x80, 0x8A, + 0x67, 0xB6, 0x74, 0x5B, 0x4B, 0x36, 0x50, 0xB4, + 0xA6, 0x4D, 0xC2, 0x76, 0xCF, 0x98, 0xE3, 0x03, + 0x57, 0xB6, 0xAB, 0xD5, 0xC1, 0xD2, 0x2A, 0x9B + }, + { + 0xC5, 0x9E, 0xE5, 0xC1, 0x96, 0xBA, 0x3C, 0xFE, + 0xF9, 0x40, 0x87, 0x79, 0x82, 0x07, 0xBD, 0xCE, + 0xF1, 0x39, 0xCE, 0x2C, 0xF7, 0x8D, 0xCE, 0xD6, + 0x19, 0x8F, 0x0F, 0xA3, 0xA4, 0x09, 0x13, 0x1C + }, + { + 0xC7, 0xFD, 0xAD, 0xE5, 0x9C, 0x46, 0x99, 0x38, + 0x5E, 0xBA, 0x59, 0xE7, 0x56, 0xC2, 0xB1, 0x71, + 0xB0, 0x23, 0xDE, 0xAE, 0x08, 0x2E, 0x5A, 0x6E, + 0x3B, 0xFB, 0xDC, 0x10, 0x73, 0xA3, 0x20, 0x03 + }, + { + 0x97, 0x53, 0x27, 0xC5, 0xF4, 0xDE, 0xC6, 0x41, + 0x4B, 0x6E, 0x00, 0xCB, 0x04, 0x23, 0x37, 0xB8, + 0xD2, 0xA6, 0x56, 0x46, 0x37, 0xA7, 0x44, 0x2A, + 0xEC, 0x7B, 0xE8, 0xF8, 0xC8, 0x9A, 0x2F, 0x1C + }, + { + 0xA2, 0xF7, 0x24, 0x6D, 0xF4, 0xA2, 0x4E, 0xFB, + 0xAC, 0xD3, 0xFD, 0x60, 0x68, 0x3A, 0xBC, 0x86, + 0x8B, 0xEF, 0x25, 0x32, 0x70, 0x52, 0xCF, 0x2F, + 0x1D, 0x93, 0xEC, 0xE4, 0xFF, 0xCD, 0x73, 0xC6 + }, + { + 0x49, 0x7F, 0xB2, 0xAC, 0xAC, 0xF1, 0x23, 0xF3, + 0x59, 0x5E, 0x40, 0xFC, 0x51, 0xA7, 0xBD, 0x24, + 0x45, 0x8B, 0xBC, 0xBA, 0x4A, 0x29, 0x40, 0xA5, + 0xCB, 0x03, 0xD6, 0x08, 0xFB, 0xDF, 0x28, 0x25 + }, + { + 0x0E, 0x97, 0xD2, 0x27, 0x93, 0xCE, 0x6F, 0x28, + 0x3D, 0x5C, 0x74, 0x0D, 0x30, 0x8A, 0x27, 0xAD, + 0x7C, 0x3B, 0x0D, 0x9A, 0xFC, 0xD3, 0xD9, 0xE9, + 0xB9, 0xCA, 0xC5, 0x6B, 0x10, 0x29, 0x0C, 0x8F + }, + { + 0x66, 0x30, 0xB3, 0x56, 0x18, 0xE7, 0x00, 0xD9, + 0x10, 0x68, 0x38, 0x93, 0x79, 0x5E, 0xF7, 0x0B, + 0xF0, 0x7E, 0xB1, 0x56, 0xF5, 0x5F, 0xFE, 0x3B, + 0x69, 0xAD, 0x88, 0xA4, 0xB8, 0xB0, 0xBF, 0xA1 + }, + { + 0x02, 0xF7, 0x42, 0xC6, 0xE9, 0x52, 0x78, 0x12, + 0x1A, 0x05, 0xE4, 0x42, 0x05, 0x44, 0x4F, 0xC5, + 0xEA, 0x6A, 0xF5, 0xE7, 0x41, 0xC5, 0x35, 0xBC, + 0x2C, 0xBC, 0x3B, 0x23, 0x5A, 0x2E, 0xA2, 0xB0 + }, + { + 0x46, 0x22, 0xF3, 0x6E, 0xB8, 0x98, 0x38, 0x3F, + 0x60, 0xD5, 0xBE, 0xD8, 0x09, 0xAC, 0x5C, 0x47, + 0x45, 0xC5, 0xD6, 0xAB, 0x84, 0xBC, 0xAD, 0xF7, + 0x9C, 0xF2, 0xA9, 0x6D, 0x4E, 0xC8, 0x88, 0x18 + }, + { + 0xCC, 0xD1, 0x1F, 0xAA, 0xA0, 0x58, 0x1E, 0xC3, + 0x2C, 0x3A, 0x40, 0x3F, 0x92, 0xEF, 0x43, 0xD5, + 0xDC, 0xF1, 0x95, 0xC1, 0xA1, 0x01, 0xDB, 0xFD, + 0x49, 0x5D, 0xBB, 0x4D, 0xCE, 0x80, 0x69, 0xE0 + }, + { + 0x06, 0x02, 0x4D, 0x6B, 0x07, 0xE0, 0x00, 0xBC, + 0xE6, 0x13, 0x47, 0x0A, 0x28, 0x80, 0x51, 0x9B, + 0x8B, 0xE4, 0xA3, 0x6B, 0xF3, 0x3C, 0x99, 0xC9, + 0x17, 0x89, 0x3E, 0xC7, 0x5D, 0xD9, 0x0F, 0xE3 + }, + { + 0xD9, 0x3A, 0xF9, 0x47, 0xB1, 0x46, 0x3A, 0x81, + 0x7D, 0xB4, 0x41, 0xA4, 0x74, 0x58, 0x8D, 0x6F, + 0x99, 0x6D, 0x24, 0x39, 0x83, 0xE8, 0x3C, 0x7E, + 0xEE, 0x90, 0xE1, 0xEF, 0xA4, 0x40, 0xD9, 0xBA + }, + { + 0x94, 0x89, 0x89, 0x45, 0xA7, 0xDB, 0x25, 0x9E, + 0x1B, 0x2E, 0x7C, 0xBE, 0xA4, 0x8A, 0xA0, 0xC6, + 0xD6, 0x57, 0x0D, 0x18, 0x17, 0x9F, 0x06, 0x18, + 0x47, 0x1C, 0x88, 0xF3, 0xEC, 0x3B, 0x0F, 0xC3 + }, + { + 0x4C, 0x2D, 0x93, 0x52, 0x56, 0x39, 0x2A, 0xA2, + 0xBE, 0x6E, 0x10, 0x78, 0xC0, 0x59, 0x38, 0x15, + 0xAB, 0xEF, 0x46, 0x9D, 0xE9, 0x69, 0xB5, 0x7B, + 0x88, 0x1B, 0x93, 0xAF, 0x55, 0x84, 0x65, 0xFA + }, + { + 0xAA, 0xC7, 0xBE, 0x16, 0xE5, 0x2F, 0x79, 0x0E, + 0x4F, 0xF7, 0x0B, 0x24, 0x01, 0x5C, 0xB1, 0x1B, + 0x40, 0x61, 0x6E, 0x94, 0xDB, 0x13, 0x88, 0x2B, + 0x41, 0xD3, 0xDD, 0x8C, 0x8C, 0x19, 0x52, 0xB7 + }, + { + 0x04, 0x34, 0xB4, 0x7C, 0x0E, 0xE7, 0xE6, 0xF5, + 0x39, 0x06, 0x79, 0x9A, 0x43, 0x20, 0x9D, 0x3F, + 0xC3, 0x7D, 0x3F, 0xD1, 0xF7, 0x45, 0x55, 0xDE, + 0x67, 0xAB, 0xAC, 0xB9, 0x51, 0xB0, 0x06, 0xF4 + }, + { + 0x04, 0x42, 0xFB, 0xDD, 0x5B, 0x58, 0x49, 0x6E, + 0xC7, 0x81, 0x59, 0xCC, 0xAA, 0x88, 0x7C, 0x88, + 0xA8, 0x61, 0xFC, 0xCA, 0x70, 0xE7, 0xAB, 0xC9, + 0x76, 0xF2, 0x4C, 0x11, 0x58, 0x8B, 0xE6, 0xEE + }, + { + 0xA7, 0x3E, 0x68, 0xBB, 0x18, 0xB0, 0x07, 0x64, + 0x8E, 0x76, 0xB5, 0x52, 0x8D, 0x1E, 0x50, 0xE7, + 0xFA, 0x65, 0x4D, 0xA3, 0x97, 0x0E, 0xC3, 0x49, + 0xBF, 0x59, 0x1A, 0x30, 0xD9, 0x32, 0xC8, 0xF6 + }, + { + 0x84, 0x9C, 0xF8, 0x73, 0x16, 0x2B, 0xA7, 0x2C, + 0x4B, 0x80, 0x08, 0xE6, 0x8F, 0x93, 0x2F, 0xB3, + 0xA0, 0x15, 0xA7, 0x4F, 0xCF, 0x95, 0x71, 0x98, + 0xD5, 0x6A, 0x0D, 0xC4, 0x62, 0x5A, 0x74, 0xF5 + }, + { + 0xA6, 0xDE, 0xC6, 0xFC, 0x89, 0x49, 0x34, 0x9C, + 0x4E, 0x9A, 0x9C, 0x62, 0x36, 0x87, 0xFB, 0xA4, + 0xC9, 0xB2, 0x75, 0xBD, 0xB2, 0x30, 0x50, 0x9B, + 0x72, 0xE3, 0xD6, 0x71, 0x19, 0x14, 0xE2, 0xD8 + }, + { + 0x58, 0xAF, 0xC2, 0xB2, 0x4A, 0x19, 0xFD, 0xBF, + 0x76, 0xA0, 0x9B, 0x70, 0xB1, 0xE3, 0xB7, 0x7F, + 0xCB, 0xD4, 0x06, 0x50, 0x01, 0xD9, 0x63, 0x66, + 0x40, 0xEB, 0x5A, 0x26, 0x28, 0xF4, 0x42, 0xCC + }, + { + 0x47, 0x3A, 0x43, 0xAA, 0x1D, 0x6A, 0x02, 0x87, + 0x67, 0x43, 0x2A, 0x83, 0x0A, 0xD1, 0x22, 0x1E, + 0x02, 0x9C, 0x58, 0x9A, 0xF9, 0xFD, 0x4D, 0x68, + 0xD5, 0x6C, 0x4F, 0xB8, 0x20, 0x25, 0x93, 0x52 + }, + { + 0xA0, 0xAE, 0xB4, 0xA5, 0xAD, 0x89, 0x9A, 0xF2, + 0xE2, 0x91, 0xB2, 0xE7, 0x9D, 0xBB, 0x6B, 0x0B, + 0xF5, 0x6B, 0x58, 0x44, 0x67, 0x6B, 0x95, 0x5D, + 0x94, 0x5B, 0x6C, 0x4A, 0xE1, 0xC0, 0x1E, 0xED + }, + { + 0xCF, 0xC3, 0x02, 0x9A, 0x9E, 0xEB, 0x15, 0x22, + 0x22, 0xD9, 0x66, 0x53, 0x49, 0x2E, 0x46, 0xCA, + 0x64, 0xCA, 0x4F, 0x0D, 0x64, 0x68, 0x30, 0x28, + 0xD3, 0xAE, 0xE5, 0xA4, 0x9C, 0xB4, 0x71, 0x63 + }, + { + 0x74, 0x67, 0xCF, 0x77, 0x61, 0xCD, 0x9F, 0x55, + 0x61, 0x8D, 0x30, 0xC9, 0xD8, 0xC5, 0xB4, 0x1E, + 0x47, 0x01, 0x51, 0x0C, 0x7D, 0x16, 0xAB, 0x4E, + 0x5D, 0x89, 0xA5, 0xD7, 0x71, 0x46, 0xB0, 0x92 + }, + { + 0xC0, 0x16, 0xD8, 0x42, 0x4E, 0x53, 0x1E, 0xFC, + 0x57, 0x37, 0xC0, 0x3F, 0xC9, 0x0A, 0x5E, 0xFC, + 0x9F, 0x90, 0x22, 0xE4, 0xD5, 0xBA, 0x3B, 0x06, + 0x95, 0xF7, 0xAE, 0x53, 0x82, 0x60, 0xC2, 0xEE + }, + { + 0x5D, 0x38, 0x11, 0x89, 0xE6, 0x00, 0x0F, 0xC1, + 0x17, 0xC7, 0x1F, 0x59, 0xF7, 0x86, 0xFB, 0x4B, + 0x79, 0xFD, 0xD4, 0xEC, 0x5D, 0x4C, 0xD3, 0x0A, + 0xAC, 0x21, 0x57, 0xF7, 0x5D, 0xEA, 0xD7, 0x78 + }, + { + 0x7C, 0x9C, 0xDD, 0x15, 0xC4, 0xC9, 0xAB, 0xCA, + 0xCB, 0xFE, 0x6F, 0x66, 0x4A, 0x7F, 0x5F, 0x8B, + 0x2E, 0x25, 0x91, 0x83, 0x29, 0x1A, 0xE5, 0xCC, + 0x91, 0x30, 0xA0, 0xB2, 0x41, 0xE5, 0x73, 0x7F + }, + { + 0xB8, 0x81, 0x31, 0x72, 0xF5, 0x21, 0x8A, 0xC3, + 0xEB, 0x68, 0x7B, 0xC4, 0xAF, 0xAF, 0xF8, 0x3F, + 0xBC, 0xA4, 0xE9, 0xC1, 0xA4, 0x62, 0x96, 0x33, + 0x01, 0xDD, 0x44, 0x59, 0x85, 0x01, 0x50, 0xA2 + }, + { + 0xE3, 0xD1, 0x30, 0xE3, 0x6A, 0x02, 0x8E, 0xA8, + 0x0C, 0x57, 0xA2, 0xAA, 0x48, 0x19, 0xFD, 0x34, + 0xE4, 0xDB, 0xBE, 0xB1, 0x4A, 0x49, 0x58, 0x94, + 0xB1, 0x5A, 0x87, 0x87, 0xDB, 0x1A, 0x9F, 0x9C + }, + { + 0xFF, 0xF1, 0xB4, 0x40, 0x0F, 0x48, 0x9E, 0x07, + 0xD2, 0x23, 0x51, 0xC1, 0xF0, 0x95, 0x65, 0xE2, + 0x65, 0xB6, 0x8A, 0xD2, 0x9F, 0x63, 0x29, 0x87, + 0x9E, 0x6B, 0x5F, 0x7F, 0x6B, 0x41, 0x93, 0x50 + }, + { + 0x55, 0x9E, 0xD5, 0xBB, 0x3E, 0x5F, 0x39, 0x85, + 0xFB, 0x57, 0x82, 0x28, 0xBF, 0x8C, 0x0F, 0x0B, + 0x17, 0x3F, 0x8D, 0x11, 0x53, 0xFA, 0xEB, 0x9F, + 0xEC, 0x75, 0x6F, 0xFD, 0x18, 0xA8, 0x72, 0x38 + }, + { + 0x88, 0x13, 0x12, 0x53, 0x01, 0x4D, 0x23, 0xC5, + 0xE3, 0x8E, 0x78, 0xBD, 0xA1, 0x94, 0x55, 0xD8, + 0xA0, 0x23, 0xBD, 0x7A, 0x7E, 0x72, 0x74, 0x57, + 0xA1, 0x52, 0xA8, 0x1D, 0x0B, 0x17, 0x18, 0xA7 + }, + { + 0xF4, 0xD3, 0xFA, 0xE7, 0xCD, 0xE6, 0xBB, 0x66, + 0x71, 0x5A, 0x19, 0x8F, 0xA4, 0x8D, 0x21, 0x0C, + 0x10, 0xF8, 0xDF, 0x32, 0x04, 0xAE, 0x5E, 0x33, + 0xA6, 0x02, 0x46, 0x7F, 0x1B, 0x62, 0x26, 0x85 + }, + { + 0xE6, 0x2B, 0x62, 0x2A, 0xC8, 0xA2, 0x13, 0x66, + 0xBF, 0x2D, 0xED, 0x30, 0xF4, 0x08, 0x2A, 0x53, + 0xE7, 0x7A, 0x9A, 0xA6, 0x96, 0xB1, 0xF3, 0xEE, + 0x8C, 0xFE, 0x99, 0xC5, 0x93, 0x12, 0xD9, 0xC7 + }, + { + 0x3D, 0x39, 0xFF, 0xA8, 0x55, 0x12, 0xC3, 0xC8, + 0x89, 0x0D, 0x4B, 0xDF, 0x31, 0x88, 0x9C, 0xA6, + 0x6E, 0x5C, 0xEC, 0xB6, 0x3C, 0xFE, 0xED, 0x57, + 0xB9, 0x26, 0x37, 0x08, 0xE7, 0x4C, 0x55, 0x0B + }, + { + 0xB1, 0x70, 0x3B, 0x8A, 0x00, 0xE2, 0x61, 0x24, + 0x97, 0xD1, 0x1C, 0x64, 0x9D, 0x15, 0x0A, 0x6C, + 0x96, 0x3B, 0xF4, 0xFD, 0x38, 0xFE, 0xB1, 0xC3, + 0x81, 0xFE, 0x0D, 0x9B, 0x04, 0xC0, 0x2B, 0x22 + }, + { + 0x12, 0xFB, 0xAD, 0x9D, 0x37, 0x82, 0x81, 0x2D, + 0x71, 0x17, 0x9A, 0x50, 0xFB, 0xD9, 0xB4, 0x56, + 0x6C, 0x7B, 0x06, 0xF5, 0xD7, 0x7C, 0x6F, 0x32, + 0x97, 0x17, 0xFB, 0x4A, 0xE2, 0xC5, 0xB4, 0xEC + }, + { + 0x76, 0x8B, 0x65, 0x9A, 0x82, 0x4B, 0x43, 0xF9, + 0xCA, 0x56, 0x60, 0xB9, 0xDD, 0xF0, 0x5F, 0x8B, + 0xA2, 0xBC, 0x49, 0x93, 0x86, 0x6B, 0x7C, 0x9B, + 0xE6, 0x87, 0x91, 0xF5, 0xB2, 0x46, 0x44, 0xB3 + }, + { + 0xC0, 0x20, 0x4E, 0x23, 0xCA, 0x86, 0xBE, 0x20, + 0x5E, 0xED, 0x0C, 0xC3, 0xDD, 0x72, 0x25, 0xCE, + 0x5F, 0xFE, 0x1E, 0xE1, 0x2D, 0xAC, 0xB9, 0x3C, + 0x5D, 0x06, 0x29, 0xB7, 0x69, 0x9C, 0xD7, 0x33 + }, + { + 0xF4, 0x32, 0x96, 0x96, 0x1F, 0x8E, 0xAE, 0xCC, + 0xD8, 0x54, 0x41, 0x3D, 0xC5, 0xAD, 0xDA, 0x62, + 0x39, 0x3A, 0x34, 0x46, 0x27, 0xE8, 0x6C, 0x06, + 0x6E, 0x79, 0x07, 0x55, 0x00, 0x40, 0x74, 0x4F + }, + { + 0x82, 0xF4, 0x46, 0x9E, 0x80, 0x78, 0x90, 0x21, + 0xC6, 0x1D, 0xB7, 0xE3, 0x2F, 0x36, 0xAC, 0xBE, + 0x59, 0x1A, 0x64, 0xF2, 0x60, 0x59, 0x26, 0x57, + 0x70, 0xAE, 0x65, 0x8D, 0x62, 0xBD, 0xE7, 0xEF + }, + { + 0x2A, 0x85, 0x67, 0x1A, 0x55, 0xC8, 0x9F, 0xA1, + 0x56, 0xE2, 0x96, 0xF7, 0x5D, 0xF1, 0xC7, 0xDB, + 0xAB, 0x17, 0x8E, 0xBB, 0xA6, 0x52, 0x04, 0xA7, + 0xE8, 0x17, 0x8C, 0x91, 0x6A, 0xD0, 0x87, 0xF8 + }, + { + 0x33, 0xE2, 0x45, 0x00, 0x28, 0x08, 0xF6, 0x93, + 0x4B, 0x9B, 0xE3, 0xA6, 0xFA, 0x8E, 0x86, 0x70, + 0xC9, 0x0B, 0xAA, 0x62, 0x57, 0x17, 0xB9, 0x20, + 0x1E, 0xB9, 0xB9, 0xDD, 0x91, 0x2F, 0x5C, 0xE2 + }, + { + 0x58, 0xEE, 0x5E, 0x79, 0x91, 0x84, 0xAD, 0x9D, + 0xA9, 0xA1, 0x7C, 0x5B, 0x46, 0xA4, 0x81, 0x0E, + 0x28, 0xBD, 0xD0, 0x8C, 0x35, 0x81, 0x63, 0x4C, + 0x83, 0x50, 0x30, 0x53, 0x9B, 0x79, 0x54, 0x4D + }, + { + 0x26, 0xD8, 0xFA, 0x08, 0xDB, 0x30, 0x8E, 0xDF, + 0x2F, 0x96, 0xF8, 0x2A, 0xF6, 0xB6, 0x0C, 0x17, + 0xD8, 0xF1, 0xFF, 0x85, 0x8C, 0x52, 0xF2, 0xD0, + 0xF3, 0x83, 0x10, 0x78, 0x12, 0x75, 0x26, 0xA3 + }, + { + 0x25, 0xA5, 0x8D, 0xF4, 0x03, 0x92, 0x47, 0xA2, + 0x2F, 0x68, 0xFF, 0x2B, 0x71, 0x76, 0x6B, 0x7B, + 0x56, 0x00, 0xDD, 0xF4, 0x01, 0xD9, 0x9F, 0xF2, + 0xC1, 0x95, 0x5A, 0xE7, 0xBB, 0x43, 0xE5, 0x6A + }, + { + 0xBE, 0x43, 0xE8, 0x68, 0x61, 0x60, 0xE9, 0x07, + 0xBA, 0x54, 0x7D, 0x5A, 0x87, 0x9D, 0x10, 0xF7, + 0x88, 0xAF, 0xC8, 0x42, 0xB8, 0xEB, 0xB9, 0xF3, + 0xF7, 0x88, 0x53, 0x25, 0x15, 0x91, 0x2A, 0xE4 + }, + { + 0xAA, 0x4A, 0xCB, 0x95, 0xD8, 0x79, 0x19, 0x2A, + 0x69, 0x08, 0xE8, 0x8A, 0xE3, 0xD6, 0x58, 0x9F, + 0x4E, 0x3E, 0xB3, 0xD4, 0xE0, 0x3A, 0x80, 0x6C, + 0xCD, 0xB9, 0xB5, 0xD6, 0xA9, 0x58, 0x6F, 0xDF + }, + { + 0x84, 0x66, 0xD5, 0xE4, 0x4C, 0xE9, 0x5B, 0x4F, + 0xA1, 0x79, 0x99, 0x24, 0x44, 0xB8, 0xC2, 0x48, + 0x5B, 0x88, 0x64, 0x48, 0xA6, 0xDC, 0xCF, 0xCF, + 0x0B, 0xC3, 0x0B, 0xC5, 0xF0, 0xF5, 0x6B, 0x01 + }, + { + 0x00, 0x56, 0xD7, 0xE0, 0xAC, 0x33, 0x35, 0x57, + 0x83, 0x65, 0x9B, 0x38, 0xEC, 0x8B, 0xEC, 0xCB, + 0xF7, 0x83, 0x93, 0x99, 0x67, 0xFE, 0x37, 0xAE, + 0xAC, 0xF3, 0x69, 0xDD, 0xB6, 0x70, 0xAD, 0xA0 + }, + { + 0x90, 0x4F, 0x42, 0xF3, 0x45, 0x53, 0x0A, 0xC8, + 0xA3, 0x52, 0xD0, 0x9B, 0x68, 0x72, 0xC5, 0xBC, + 0xA3, 0x66, 0x1A, 0xBC, 0xA6, 0xCA, 0x64, 0xC8, + 0x09, 0x9F, 0x2F, 0xB6, 0x86, 0x7C, 0x30, 0xFE + }, + { + 0xA8, 0xC3, 0xBF, 0x46, 0xF0, 0xB8, 0x8B, 0xBD, + 0x16, 0xFD, 0xA4, 0xA8, 0xB5, 0xCA, 0x81, 0xF5, + 0x24, 0x35, 0x20, 0xC3, 0x85, 0xD3, 0x8C, 0x0B, + 0x4D, 0x23, 0x52, 0xAB, 0x34, 0xEA, 0x35, 0xE6 + }, + { + 0x8D, 0x33, 0x17, 0xFC, 0x60, 0x6E, 0x56, 0x6D, + 0x30, 0x2E, 0xDA, 0xB5, 0x5E, 0x80, 0x16, 0x11, + 0xD8, 0xC1, 0x3F, 0x4A, 0x9A, 0x19, 0xD1, 0x85, + 0x97, 0x8D, 0xEF, 0x72, 0x83, 0x9C, 0xDA, 0xA3 + }, + { + 0x97, 0x38, 0x80, 0x11, 0xF5, 0x7A, 0x49, 0x86, + 0x90, 0xEC, 0x79, 0x88, 0xEF, 0xF9, 0x03, 0xFF, + 0x9B, 0x23, 0x58, 0xF5, 0xB6, 0x1B, 0xAA, 0x20, + 0xF7, 0x32, 0x90, 0xD6, 0x29, 0x6C, 0x1C, 0x0B + }, + { + 0xCF, 0xB8, 0x0C, 0xAB, 0x89, 0x90, 0x95, 0x08, + 0x09, 0x12, 0x3F, 0xBF, 0x85, 0xE9, 0x76, 0x45, + 0x47, 0x08, 0xE0, 0xAF, 0xED, 0x69, 0x8E, 0x33, + 0x52, 0xA3, 0x16, 0x35, 0x90, 0x9D, 0xB3, 0xE5 + }, + { + 0x0D, 0xAA, 0xCA, 0x55, 0x13, 0x2A, 0x23, 0x5B, + 0x83, 0x1A, 0x5E, 0xFF, 0x4E, 0xA4, 0x67, 0xCD, + 0x10, 0xAF, 0x44, 0x20, 0x08, 0x47, 0x73, 0x5A, + 0x1F, 0xFD, 0x51, 0xFA, 0x37, 0xEA, 0xA2, 0xA2 + }, + { + 0x69, 0xB2, 0x14, 0x97, 0xEB, 0xB8, 0x24, 0xBA, + 0x66, 0x53, 0x68, 0x18, 0x88, 0x25, 0xE6, 0xF6, + 0xF1, 0x4C, 0xF2, 0xC3, 0xF7, 0xB5, 0x53, 0x0B, + 0xB3, 0x4F, 0xA6, 0x58, 0xEE, 0xD9, 0xA7, 0x39 + }, + { + 0xB9, 0xA1, 0x9F, 0x50, 0x9B, 0xE0, 0x3F, 0xBC, + 0x40, 0xE2, 0x43, 0xA5, 0x8A, 0x3D, 0xED, 0x11, + 0xF0, 0xD5, 0x1F, 0x80, 0xE3, 0xE2, 0x9A, 0x50, + 0x56, 0x44, 0xCC, 0x05, 0x74, 0x38, 0x14, 0xEC + }, + { + 0xC4, 0xBC, 0xB2, 0x00, 0x25, 0x55, 0xD5, 0x44, + 0xFD, 0x0B, 0x02, 0x77, 0x06, 0x23, 0x89, 0x1E, + 0x70, 0xEE, 0xEC, 0x77, 0x44, 0x86, 0x5D, 0xD6, + 0x45, 0x5A, 0xD6, 0x65, 0xCC, 0x82, 0xE8, 0x61 + }, + { + 0x91, 0x2D, 0x24, 0xDC, 0x3D, 0x69, 0x23, 0xA4, + 0x83, 0xC2, 0x63, 0xEB, 0xA8, 0x1B, 0x7A, 0x87, + 0x97, 0xF2, 0x3C, 0xBF, 0x2F, 0x78, 0xB5, 0x1E, + 0x22, 0x26, 0x63, 0x9F, 0x84, 0xA5, 0x90, 0x47 + }, + { + 0x56, 0x82, 0x7A, 0x18, 0x88, 0x3A, 0xFD, 0xF9, + 0xCE, 0xEC, 0x56, 0x2B, 0x20, 0x66, 0xD8, 0xAC, + 0xB2, 0xC1, 0x95, 0x05, 0xEC, 0xE6, 0xF7, 0xA8, + 0x3E, 0x9F, 0x33, 0x46, 0xCB, 0xB8, 0x28, 0xC9 + }, + { + 0x25, 0x1D, 0x8D, 0x09, 0xFC, 0x48, 0xDD, 0x1D, + 0x6A, 0xF8, 0xFF, 0xDF, 0x39, 0x50, 0x91, 0xA4, + 0x6E, 0x05, 0xB8, 0xB7, 0xC5, 0xEC, 0x0C, 0x79, + 0xB6, 0x8A, 0x89, 0x04, 0xC8, 0x27, 0xBD, 0xEA + }, + { + 0xC2, 0xD1, 0x4D, 0x69, 0xFD, 0x0B, 0xBD, 0x1C, + 0x0F, 0xE8, 0xC8, 0x45, 0xD5, 0xFD, 0x6A, 0x8F, + 0x74, 0x01, 0x51, 0xB1, 0xD8, 0xEB, 0x4D, 0x26, + 0x36, 0x4B, 0xB0, 0x2D, 0xAE, 0x0C, 0x13, 0xBC + }, + { + 0x2E, 0x5F, 0xE2, 0x1F, 0x8F, 0x1B, 0x63, 0x97, + 0xA3, 0x8A, 0x60, 0x3D, 0x60, 0xB6, 0xF5, 0x3C, + 0x3B, 0x5D, 0xB2, 0x0A, 0xA5, 0x6C, 0x6D, 0x44, + 0xBE, 0xBD, 0x48, 0x28, 0xCE, 0x28, 0xF9, 0x0F + }, + { + 0x25, 0x05, 0x9F, 0x10, 0x60, 0x5E, 0x67, 0xAD, + 0xFE, 0x68, 0x13, 0x50, 0x66, 0x6E, 0x15, 0xAE, + 0x97, 0x6A, 0x5A, 0x57, 0x1C, 0x13, 0xCF, 0x5B, + 0xC8, 0x05, 0x3F, 0x43, 0x0E, 0x12, 0x0A, 0x52 + }, +}; + + + + +static const uint8_t blake2sp_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0x71, 0x5C, 0xB1, 0x38, 0x95, 0xAE, 0xB6, 0x78, + 0xF6, 0x12, 0x41, 0x60, 0xBF, 0xF2, 0x14, 0x65, + 0xB3, 0x0F, 0x4F, 0x68, 0x74, 0x19, 0x3F, 0xC8, + 0x51, 0xB4, 0x62, 0x10, 0x43, 0xF0, 0x9C, 0xC6 + }, + { + 0x40, 0x57, 0x8F, 0xFA, 0x52, 0xBF, 0x51, 0xAE, + 0x18, 0x66, 0xF4, 0x28, 0x4D, 0x3A, 0x15, 0x7F, + 0xC1, 0xBC, 0xD3, 0x6A, 0xC1, 0x3C, 0xBD, 0xCB, + 0x03, 0x77, 0xE4, 0xD0, 0xCD, 0x0B, 0x66, 0x03 + }, + { + 0x67, 0xE3, 0x09, 0x75, 0x45, 0xBA, 0xD7, 0xE8, + 0x52, 0xD7, 0x4D, 0x4E, 0xB5, 0x48, 0xEC, 0xA7, + 0xC2, 0x19, 0xC2, 0x02, 0xA7, 0xD0, 0x88, 0xDB, + 0x0E, 0xFE, 0xAC, 0x0E, 0xAC, 0x30, 0x42, 0x49 + }, + { + 0x8D, 0xBC, 0xC0, 0x58, 0x9A, 0x3D, 0x17, 0x29, + 0x6A, 0x7A, 0x58, 0xE2, 0xF1, 0xEF, 0xF0, 0xE2, + 0xAA, 0x42, 0x10, 0xB5, 0x8D, 0x1F, 0x88, 0xB8, + 0x6D, 0x7B, 0xA5, 0xF2, 0x9D, 0xD3, 0xB5, 0x83 + }, + { + 0xA9, 0xA9, 0x65, 0x2C, 0x8C, 0x67, 0x75, 0x94, + 0xC8, 0x72, 0x12, 0xD8, 0x9D, 0x5A, 0x75, 0xFB, + 0x31, 0xEF, 0x4F, 0x47, 0xC6, 0x58, 0x2C, 0xDE, + 0x5F, 0x1E, 0xF6, 0x6B, 0xD4, 0x94, 0x53, 0x3A + }, + { + 0x05, 0xA7, 0x18, 0x0E, 0x59, 0x50, 0x54, 0x73, + 0x99, 0x48, 0xC5, 0xE3, 0x38, 0xC9, 0x5F, 0xE0, + 0xB7, 0xFC, 0x61, 0xAC, 0x58, 0xA7, 0x35, 0x74, + 0x74, 0x56, 0x33, 0xBB, 0xC1, 0xF7, 0x70, 0x31 + }, + { + 0x81, 0x4D, 0xE8, 0x31, 0x53, 0xB8, 0xD7, 0x5D, + 0xFA, 0xDE, 0x29, 0xFD, 0x39, 0xAC, 0x72, 0xDD, + 0x09, 0xCA, 0x0F, 0x9B, 0xC8, 0xB7, 0xAB, 0x6A, + 0x06, 0xBA, 0xEE, 0x7D, 0xD0, 0xF9, 0xF0, 0x83 + }, + { + 0xDF, 0xD4, 0x19, 0x44, 0x91, 0x29, 0xFF, 0x60, + 0x4F, 0x0A, 0x14, 0x8B, 0x4C, 0x7D, 0x68, 0xF1, + 0x17, 0x4F, 0x7D, 0x0F, 0x8C, 0x8D, 0x2C, 0xE7, + 0x7F, 0x44, 0x8F, 0xD3, 0x41, 0x9C, 0x6F, 0xB0 + }, + { + 0xB9, 0xED, 0x22, 0xE7, 0xDD, 0x8D, 0xD1, 0x4E, + 0xE8, 0xC9, 0x5B, 0x20, 0xE7, 0x63, 0x2E, 0x85, + 0x53, 0xA2, 0x68, 0xD9, 0xFF, 0x86, 0x33, 0xED, + 0x3C, 0x21, 0xD1, 0xB8, 0xC9, 0xA7, 0x0B, 0xE1 + }, + { + 0x95, 0xF0, 0x31, 0x67, 0x1A, 0x4E, 0x3C, 0x54, + 0x44, 0x1C, 0xEE, 0x9D, 0xBE, 0xF4, 0xB7, 0xAC, + 0xA4, 0x46, 0x18, 0xA3, 0xA3, 0x33, 0xAD, 0x74, + 0x06, 0xD1, 0x97, 0xAC, 0x5B, 0xA0, 0x79, 0x1A + }, + { + 0xE2, 0x92, 0x5B, 0x9D, 0x5C, 0xA0, 0xFF, 0x62, + 0x88, 0xC5, 0xEA, 0x1A, 0xF2, 0xD2, 0x2B, 0x0A, + 0x6B, 0x79, 0xE2, 0xDA, 0xE0, 0x8B, 0xFD, 0x36, + 0xC3, 0xBE, 0x10, 0xBB, 0x8D, 0x71, 0xD8, 0x39 + }, + { + 0x16, 0x24, 0x9C, 0x74, 0x4E, 0x49, 0x51, 0x45, + 0x1D, 0x4C, 0x89, 0x4F, 0xB5, 0x9A, 0x3E, 0xCB, + 0x3F, 0xBF, 0xB7, 0xA4, 0x5F, 0x96, 0xF8, 0x5D, + 0x15, 0x80, 0xAC, 0x0B, 0x84, 0x2D, 0x96, 0xDA + }, + { + 0x43, 0x2B, 0xC9, 0x1C, 0x52, 0xAC, 0xEB, 0x9D, + 0xAE, 0xD8, 0x83, 0x28, 0x81, 0x64, 0x86, 0x50, + 0xC1, 0xB8, 0x1D, 0x11, 0x7A, 0xBD, 0x68, 0xE0, + 0x84, 0x51, 0x50, 0x8A, 0x63, 0xBE, 0x00, 0x81 + }, + { + 0xCD, 0xE8, 0x20, 0x2B, 0xCF, 0xA3, 0xF3, 0xE9, + 0x5D, 0x79, 0xBA, 0xCC, 0x16, 0x5D, 0x52, 0x70, + 0x0E, 0xF7, 0x1D, 0x87, 0x4A, 0x3C, 0x63, 0x7E, + 0x63, 0x4F, 0x64, 0x44, 0x73, 0x72, 0x0D, 0x6B + }, + { + 0x16, 0x21, 0x62, 0x1F, 0x5C, 0x3E, 0xE4, 0x46, + 0x89, 0x9D, 0x3C, 0x8A, 0xAE, 0x49, 0x17, 0xB1, + 0xE6, 0xDB, 0x4A, 0x0E, 0xD0, 0x42, 0x31, 0x5F, + 0xB2, 0xC1, 0x74, 0x82, 0x5E, 0x0A, 0x18, 0x19 + }, + { + 0x33, 0x6E, 0x8E, 0xBC, 0x71, 0xE2, 0x09, 0x5C, + 0x27, 0xF8, 0x64, 0xA3, 0x12, 0x1E, 0xFD, 0x0F, + 0xAA, 0x7A, 0x41, 0x28, 0x57, 0x25, 0xA5, 0x92, + 0xF6, 0x1B, 0xED, 0xED, 0x9D, 0xDE, 0x86, 0xED + }, + { + 0x07, 0x9B, 0xE0, 0x41, 0x0E, 0x78, 0x9B, 0x36, + 0xEE, 0x7F, 0x55, 0xC1, 0x9F, 0xAA, 0xC6, 0x91, + 0x65, 0x6E, 0xB0, 0x52, 0x1F, 0x42, 0x94, 0x9B, + 0x84, 0xEE, 0x29, 0xFE, 0x2A, 0x0E, 0x7F, 0x36 + }, + { + 0x17, 0x27, 0x0C, 0x4F, 0x34, 0x88, 0x08, 0x2D, + 0x9F, 0xF9, 0x93, 0x7E, 0xAB, 0x3C, 0xA9, 0x9C, + 0x97, 0xC5, 0xB4, 0x59, 0x61, 0x47, 0x37, 0x2D, + 0xD4, 0xE9, 0x8A, 0xCF, 0x13, 0xDB, 0x28, 0x10 + }, + { + 0x18, 0x3C, 0x38, 0x75, 0x4D, 0x03, 0x41, 0xCE, + 0x07, 0xC1, 0x7A, 0x6C, 0xB6, 0xC2, 0xFD, 0x8B, + 0xBC, 0xC1, 0x40, 0x4F, 0xDD, 0x01, 0x41, 0x99, + 0xC7, 0x8B, 0xE1, 0xA9, 0x75, 0x59, 0xA9, 0x28 + }, + { + 0x6E, 0x52, 0xD7, 0x28, 0xA4, 0x05, 0xA6, 0xE1, + 0xF8, 0x75, 0x87, 0xBB, 0xC2, 0xAC, 0x91, 0xC5, + 0xC0, 0x9B, 0x2D, 0x82, 0x8A, 0xC8, 0x1E, 0x5C, + 0x4A, 0x81, 0xD0, 0x3D, 0xD4, 0xAA, 0x8D, 0x5C + }, + { + 0xF4, 0xE0, 0x8E, 0x05, 0x9B, 0x74, 0x14, 0x4B, + 0xF9, 0x48, 0x14, 0x6D, 0x14, 0xA2, 0xC8, 0x1E, + 0x46, 0xDC, 0x15, 0xFF, 0x26, 0xEB, 0x52, 0x34, + 0x4C, 0xDD, 0x47, 0x4A, 0xBE, 0xA1, 0x4B, 0xC0 + }, + { + 0x0F, 0x2E, 0x0A, 0x10, 0x0E, 0xD8, 0xA1, 0x17, + 0x85, 0x96, 0x2A, 0xD4, 0x59, 0x6A, 0xF9, 0x55, + 0xE3, 0x0B, 0x9A, 0xEF, 0x93, 0x0A, 0x24, 0x8D, + 0xA9, 0x32, 0x2B, 0x70, 0x2D, 0x4B, 0x68, 0x72 + }, + { + 0x51, 0x90, 0xFC, 0xC7, 0x32, 0xF4, 0x04, 0xAA, + 0xD4, 0x36, 0x4A, 0xC7, 0x96, 0x0C, 0xFD, 0x5B, + 0x4E, 0x34, 0x86, 0x29, 0xC3, 0x72, 0xEE, 0xB3, + 0x25, 0xB5, 0xC6, 0xC7, 0xCB, 0xCE, 0x59, 0xAB + }, + { + 0xC0, 0xC4, 0xCB, 0x86, 0xEA, 0x25, 0xEA, 0x95, + 0x7E, 0xEC, 0x5B, 0x22, 0xD2, 0x55, 0x0A, 0x16, + 0x49, 0xE6, 0xDF, 0xFA, 0x31, 0x6B, 0xB8, 0xF4, + 0xC9, 0x1B, 0x8F, 0xF7, 0xA2, 0x4B, 0x25, 0x31 + }, + { + 0x2C, 0x9E, 0xDA, 0x13, 0x5A, 0x30, 0xAE, 0xCA, + 0xF3, 0xAC, 0xB3, 0xD2, 0x3A, 0x30, 0x35, 0xFB, + 0xAB, 0xBA, 0x98, 0x33, 0x31, 0x65, 0xD8, 0x7F, + 0xCB, 0xF8, 0xFE, 0x10, 0x33, 0x6E, 0xCF, 0x20 + }, + { + 0x3C, 0xD6, 0x69, 0xE8, 0xD5, 0x62, 0x62, 0xA2, + 0x37, 0x13, 0x67, 0x22, 0x4D, 0xAE, 0x6D, 0x75, + 0x9E, 0xE1, 0x52, 0xC3, 0x15, 0x33, 0xB2, 0x63, + 0xFA, 0x2E, 0x64, 0x92, 0x08, 0x77, 0xB2, 0xA7 + }, + { + 0x18, 0xA9, 0xA0, 0xC2, 0xD0, 0xEA, 0x6C, 0x3B, + 0xB3, 0x32, 0x83, 0x0F, 0x89, 0x18, 0xB0, 0x68, + 0x4F, 0x5D, 0x39, 0x94, 0xDF, 0x48, 0x67, 0x46, + 0x2D, 0xD0, 0x6E, 0xF0, 0x86, 0x24, 0x24, 0xCC + }, + { + 0x73, 0x90, 0xEA, 0x41, 0x04, 0xA9, 0xF4, 0xEE, + 0xA9, 0x0F, 0x81, 0xE2, 0x6A, 0x12, 0x9D, 0xCF, + 0x9F, 0x4A, 0xF3, 0x83, 0x52, 0xD9, 0xCB, 0x6A, + 0x81, 0x2C, 0xC8, 0x05, 0x69, 0x09, 0x05, 0x0E + }, + { + 0xE4, 0x9E, 0x01, 0x14, 0xC6, 0x29, 0xB4, 0x94, + 0xB1, 0x1E, 0xA9, 0x8E, 0xCD, 0x40, 0x32, 0x73, + 0x1F, 0x15, 0x3B, 0x46, 0x50, 0xAC, 0xAC, 0xD7, + 0xE0, 0xF6, 0xE7, 0xDE, 0x3D, 0xF0, 0x19, 0x77 + }, + { + 0x27, 0xC5, 0x70, 0x2B, 0xE1, 0x04, 0xB3, 0xA9, + 0x4F, 0xC4, 0x34, 0x23, 0xAE, 0xEE, 0x83, 0xAC, + 0x3C, 0xA7, 0x3B, 0x7F, 0x87, 0x83, 0x9A, 0x6B, + 0x2E, 0x29, 0x60, 0x79, 0x03, 0xB7, 0xF2, 0x87 + }, + { + 0x81, 0xD2, 0xE1, 0x2E, 0xB2, 0xF4, 0x27, 0x60, + 0xC6, 0xE3, 0xBA, 0xA7, 0x8F, 0x84, 0x07, 0x3A, + 0xE6, 0xF5, 0x61, 0x60, 0x70, 0xFE, 0x25, 0xBE, + 0xDE, 0x7C, 0x7C, 0x82, 0x48, 0xAB, 0x1F, 0xBA + }, + { + 0xFA, 0xB2, 0x35, 0xD5, 0x93, 0x48, 0xAB, 0x8C, + 0xE4, 0x9B, 0xEC, 0x77, 0xC0, 0xF1, 0x93, 0x28, + 0xFD, 0x04, 0x5D, 0xFD, 0x60, 0x8A, 0x53, 0x03, + 0x36, 0xDF, 0x4F, 0x94, 0xE1, 0x72, 0xA5, 0xC8 + }, + { + 0x8A, 0xAA, 0x8D, 0x80, 0x5C, 0x58, 0x88, 0x1F, + 0xF3, 0x79, 0xFB, 0xD4, 0x2C, 0x6B, 0xF6, 0xF1, + 0x4C, 0x6C, 0x73, 0xDF, 0x80, 0x71, 0xB3, 0xB2, + 0x28, 0x98, 0x11, 0x09, 0xCC, 0xC0, 0x15, 0xF9 + }, + { + 0x91, 0xFD, 0xD2, 0x62, 0x20, 0x39, 0x16, 0x39, + 0x47, 0x40, 0x95, 0x2B, 0xCE, 0x72, 0xB6, 0x4B, + 0xAB, 0xB6, 0xF7, 0x21, 0x34, 0x4D, 0xEE, 0x82, + 0x50, 0xBF, 0x0E, 0x46, 0xF1, 0xBA, 0x18, 0x8F + }, + { + 0xF7, 0xE5, 0x7B, 0x8F, 0x85, 0xF4, 0x7D, 0x59, + 0x03, 0xAD, 0x4C, 0xCB, 0x8A, 0xF6, 0x2A, 0x3E, + 0x85, 0x8A, 0xAB, 0x2B, 0x8C, 0xC2, 0x26, 0x49, + 0x4F, 0x7B, 0x00, 0xBE, 0xDB, 0xF5, 0xB0, 0xD0 + }, + { + 0xF7, 0x6F, 0x21, 0xAD, 0xDA, 0xE9, 0x6A, 0x96, + 0x46, 0xFC, 0x06, 0xF9, 0xBF, 0x52, 0xAE, 0x08, + 0x48, 0xF1, 0x8C, 0x35, 0x26, 0xB1, 0x29, 0xE1, + 0x5B, 0x2C, 0x35, 0x5E, 0x2E, 0x79, 0xE5, 0xDA + }, + { + 0x8A, 0xEB, 0x1C, 0x79, 0x5F, 0x34, 0x90, 0x01, + 0x5E, 0xF4, 0xCD, 0x61, 0xA2, 0x80, 0x7B, 0x23, + 0x0E, 0xFD, 0xC8, 0x46, 0x01, 0x73, 0xDA, 0xD0, + 0x26, 0xA4, 0xA0, 0xFC, 0xC2, 0xFB, 0xF2, 0x2A + }, + { + 0xC5, 0x64, 0xFF, 0xC6, 0x23, 0x07, 0x77, 0x65, + 0xBB, 0x97, 0x87, 0x58, 0x56, 0x54, 0xCE, 0x74, + 0x5D, 0xBD, 0x10, 0x8C, 0xEF, 0x24, 0x8A, 0xB0, + 0x0A, 0xD1, 0xA2, 0x64, 0x7D, 0x99, 0x03, 0x87 + }, + { + 0xFE, 0x89, 0x42, 0xA3, 0xE5, 0xF5, 0xE8, 0xCD, + 0x70, 0x51, 0x04, 0xF8, 0x82, 0x10, 0x72, 0x6E, + 0x53, 0xDD, 0x7E, 0xB3, 0xF9, 0xA2, 0x02, 0xBF, + 0x93, 0x14, 0xB3, 0xB9, 0x06, 0x5E, 0xB7, 0x12 + }, + { + 0xDC, 0x29, 0x53, 0x59, 0xD4, 0x36, 0xEE, 0xA7, + 0x80, 0x84, 0xE7, 0xB0, 0x77, 0xFE, 0x09, 0xB1, + 0x9C, 0x5B, 0xF3, 0xD2, 0xA7, 0x96, 0xDA, 0xB0, + 0x19, 0xE4, 0x20, 0x05, 0x99, 0xFD, 0x82, 0x02 + }, + { + 0x70, 0xB3, 0xF7, 0x2F, 0x74, 0x90, 0x32, 0xE2, + 0x5E, 0x38, 0x3B, 0x96, 0x43, 0x78, 0xEA, 0x1C, + 0x54, 0x3E, 0x9C, 0x15, 0xDE, 0x3A, 0x27, 0xD8, + 0x6D, 0x2A, 0x9D, 0x22, 0x31, 0xEF, 0xF4, 0x8A + }, + { + 0x79, 0x82, 0xB5, 0x4C, 0x08, 0xDB, 0x2B, 0xFB, + 0x6F, 0x45, 0xF3, 0x5B, 0xC3, 0x23, 0xBC, 0x09, + 0x37, 0x79, 0xB6, 0xBB, 0x0E, 0x3E, 0xEA, 0x3E, + 0x8C, 0x98, 0xB1, 0xDE, 0x99, 0xD3, 0xC5, 0x5E + }, + { + 0x75, 0xE4, 0x16, 0x22, 0x57, 0x01, 0x4B, 0xED, + 0xCC, 0x05, 0xC2, 0x94, 0x4D, 0xCE, 0x0D, 0xF0, + 0xC3, 0x5E, 0xBA, 0x13, 0x19, 0x54, 0x06, 0x4F, + 0x6E, 0x4E, 0x09, 0x5F, 0xD0, 0x84, 0x45, 0xEE + }, + { + 0x4A, 0x12, 0x9E, 0xA6, 0xCD, 0xBA, 0xBC, 0x2D, + 0x39, 0x24, 0x79, 0x37, 0x2F, 0x97, 0x5B, 0x9C, + 0xF5, 0xA1, 0xB7, 0xDE, 0xB6, 0x9A, 0x32, 0x66, + 0xF0, 0x3E, 0xBC, 0x6D, 0x11, 0x13, 0x93, 0xC4 + }, + { + 0x8F, 0xED, 0x70, 0xF2, 0x79, 0x55, 0xDC, 0x8A, + 0xD9, 0xF1, 0xB7, 0xB3, 0xF6, 0xF5, 0xDF, 0xBD, + 0x96, 0x2A, 0x33, 0x59, 0x2B, 0x42, 0xDE, 0x85, + 0x6D, 0x42, 0x1E, 0x29, 0x12, 0xBA, 0xB8, 0x6B + }, + { + 0xE2, 0xF2, 0x06, 0x60, 0x37, 0x6F, 0x2B, 0x18, + 0x39, 0x66, 0x7C, 0xBF, 0xE5, 0xE1, 0x6E, 0xF0, + 0x75, 0xAC, 0x39, 0x43, 0x64, 0x4F, 0x35, 0x32, + 0x28, 0x2F, 0x8B, 0xB0, 0x72, 0x3B, 0x99, 0x86 + }, + { + 0xAB, 0xF8, 0x4C, 0x91, 0x3A, 0x83, 0xDF, 0x98, + 0xC7, 0x00, 0x29, 0x81, 0x9C, 0x06, 0x5F, 0x6D, + 0x6D, 0xE4, 0xF6, 0xD4, 0x3A, 0xBF, 0x60, 0x0D, + 0xAD, 0xE0, 0x35, 0xB2, 0x3B, 0xED, 0x7B, 0xAA + }, + { + 0x45, 0x9C, 0x15, 0xD4, 0x85, 0x6C, 0x7E, 0xCF, + 0x82, 0x62, 0x03, 0x51, 0xC3, 0xC1, 0xC7, 0x6C, + 0x40, 0x3F, 0x3E, 0x97, 0x07, 0x74, 0x13, 0x87, + 0xE2, 0x99, 0x07, 0x3F, 0xB1, 0x70, 0x4B, 0x2B + }, + { + 0x9A, 0xB9, 0x12, 0xED, 0xA0, 0x76, 0x8A, 0xBD, + 0xF8, 0x26, 0xB6, 0xE0, 0x5D, 0x0D, 0x73, 0x58, + 0x39, 0xE6, 0xA5, 0xF0, 0x2E, 0x04, 0xC4, 0xCC, + 0x75, 0x65, 0x0B, 0x2C, 0x8C, 0xAB, 0x67, 0x49 + }, + { + 0x47, 0x40, 0xEB, 0xEC, 0xAC, 0x90, 0x03, 0x1B, + 0xB7, 0xE6, 0x8E, 0x51, 0xC5, 0x53, 0x91, 0xAF, + 0xB1, 0x89, 0xB3, 0x17, 0xF2, 0xDE, 0x55, 0x87, + 0x66, 0xF7, 0x8F, 0x5C, 0xB7, 0x1F, 0x81, 0xB6 + }, + { + 0x3C, 0xC4, 0x7F, 0x0E, 0xF6, 0x48, 0x21, 0x58, + 0x7C, 0x93, 0x7C, 0xDD, 0xBA, 0x85, 0xC9, 0x93, + 0xD3, 0xCE, 0x2D, 0xD0, 0xCE, 0xD4, 0x0D, 0x3B, + 0xE3, 0x3C, 0xB7, 0xDC, 0x7E, 0xDA, 0xBC, 0xF1 + }, + { + 0x9F, 0x47, 0x6A, 0x22, 0xDB, 0x54, 0xD6, 0xBB, + 0x9B, 0xEF, 0xDB, 0x26, 0x0C, 0x66, 0x57, 0x8A, + 0xE1, 0xD8, 0xA5, 0xF8, 0x7D, 0x3D, 0x8C, 0x01, + 0x7F, 0xDB, 0x74, 0x75, 0x08, 0x0F, 0xA8, 0xE1 + }, + { + 0x8B, 0x68, 0xC6, 0xFB, 0x07, 0x06, 0xA7, 0x95, + 0xF3, 0xA8, 0x39, 0xD6, 0xFE, 0x25, 0xFD, 0x4A, + 0xA7, 0xF9, 0x2E, 0x66, 0x4F, 0x76, 0x2D, 0x61, + 0x53, 0x81, 0xBC, 0x85, 0x9A, 0xFA, 0x29, 0x2C + }, + { + 0xF6, 0x40, 0xD2, 0x25, 0xA6, 0xBC, 0xD2, 0xFC, + 0x8A, 0xCC, 0xAF, 0xBE, 0xD5, 0xA8, 0x4B, 0x5B, + 0xBB, 0x5D, 0x8A, 0xE5, 0xDB, 0x06, 0xA1, 0x0B, + 0x6D, 0x9D, 0x93, 0x16, 0x0B, 0x39, 0x2E, 0xE0 + }, + { + 0x70, 0x48, 0x60, 0xA7, 0xF5, 0xBA, 0x68, 0xDB, + 0x27, 0x03, 0x1C, 0x15, 0xF2, 0x25, 0x50, 0x0D, + 0x69, 0x2A, 0xB2, 0x47, 0x53, 0x42, 0x81, 0xC4, + 0xF6, 0x84, 0xF6, 0xC6, 0xC8, 0xCD, 0x88, 0xC7 + }, + { + 0xC1, 0xA7, 0x5B, 0xDD, 0xA1, 0x2B, 0x8B, 0x2A, + 0xB1, 0xB9, 0x24, 0x84, 0x38, 0x58, 0x18, 0x3A, + 0x09, 0xD2, 0x02, 0x42, 0x1F, 0xDB, 0xCD, 0xF0, + 0xE6, 0x3E, 0xAE, 0x46, 0xF3, 0x7D, 0x91, 0xED + }, + { + 0x9A, 0x8C, 0xAB, 0x7A, 0x5F, 0x2E, 0x57, 0x62, + 0x21, 0xA6, 0xA8, 0x5E, 0x5F, 0xDD, 0xEE, 0x75, + 0x67, 0x8E, 0x06, 0x53, 0x24, 0xA6, 0x1D, 0xB0, + 0x3A, 0x39, 0x26, 0x1D, 0xDF, 0x75, 0xE3, 0xF4 + }, + { + 0x05, 0xC2, 0xB2, 0x6B, 0x03, 0xCE, 0x6C, 0xA5, + 0x87, 0x1B, 0xE0, 0xDE, 0x84, 0xEE, 0x27, 0x86, + 0xA7, 0x9B, 0xCD, 0x9F, 0x30, 0x03, 0x3E, 0x81, + 0x9B, 0x4A, 0x87, 0xCC, 0xA2, 0x7A, 0xFC, 0x6A + }, + { + 0xB0, 0xB0, 0x99, 0x3C, 0x6D, 0x0C, 0x6E, 0xD5, + 0xC3, 0x59, 0x04, 0x80, 0xF8, 0x65, 0xF4, 0x67, + 0xF4, 0x33, 0x1A, 0x58, 0xDD, 0x8E, 0x47, 0xBD, + 0x98, 0xEB, 0xBC, 0xDB, 0x8E, 0xB4, 0xF9, 0x4D + }, + { + 0xE5, 0x7C, 0x10, 0x3C, 0xF7, 0xB6, 0xBB, 0xEB, + 0x8A, 0x0D, 0xC8, 0xF0, 0x48, 0x62, 0x5C, 0x3F, + 0x4C, 0xE4, 0xF1, 0xA5, 0xAD, 0x4D, 0x07, 0x9C, + 0x11, 0x87, 0xBF, 0xE9, 0xEE, 0x3B, 0x8A, 0x5F + }, + { + 0xF1, 0x00, 0x23, 0xE1, 0x5F, 0x3B, 0x72, 0xB7, + 0x38, 0xAD, 0x61, 0xAE, 0x65, 0xAB, 0x9A, 0x07, + 0xE7, 0x77, 0x4E, 0x2D, 0x7A, 0xB0, 0x2D, 0xBA, + 0x4E, 0x0C, 0xAF, 0x56, 0x02, 0xC8, 0x01, 0x78 + }, + { + 0x9A, 0x8F, 0xB3, 0xB5, 0x38, 0xC1, 0xD6, 0xC4, + 0x50, 0x51, 0xFA, 0x9E, 0xD9, 0xB0, 0x7D, 0x3E, + 0x89, 0xB4, 0x43, 0x03, 0x30, 0x01, 0x4A, 0x1E, + 0xFA, 0x28, 0x23, 0xC0, 0x82, 0x3C, 0xF2, 0x37 + }, + { + 0x30, 0x75, 0xC5, 0xBC, 0x7C, 0x3A, 0xD7, 0xE3, + 0x92, 0x01, 0x01, 0xBC, 0x68, 0x99, 0xC5, 0x8E, + 0xA7, 0x01, 0x67, 0xA7, 0x77, 0x2C, 0xA2, 0x8E, + 0x38, 0xE2, 0xC1, 0xB0, 0xD3, 0x25, 0xE5, 0xA0 + }, + { + 0xE8, 0x55, 0x94, 0x70, 0x0E, 0x39, 0x22, 0xA1, + 0xE8, 0xE4, 0x1E, 0xB8, 0xB0, 0x64, 0xE7, 0xAC, + 0x6D, 0x94, 0x9D, 0x13, 0xB5, 0xA3, 0x45, 0x23, + 0xE5, 0xA6, 0xBE, 0xAC, 0x03, 0xC8, 0xAB, 0x29 + }, + { + 0x1D, 0x37, 0x01, 0xA5, 0x66, 0x1B, 0xD3, 0x1A, + 0xB2, 0x05, 0x62, 0xBD, 0x07, 0xB7, 0x4D, 0xD1, + 0x9A, 0xC8, 0xF3, 0x52, 0x4B, 0x73, 0xCE, 0x7B, + 0xC9, 0x96, 0xB7, 0x88, 0xAF, 0xD2, 0xF3, 0x17 + }, + { + 0x87, 0x4E, 0x19, 0x38, 0x03, 0x3D, 0x7D, 0x38, + 0x35, 0x97, 0xA2, 0xA6, 0x5F, 0x58, 0xB5, 0x54, + 0xE4, 0x11, 0x06, 0xF6, 0xD1, 0xD5, 0x0E, 0x9B, + 0xA0, 0xEB, 0x68, 0x5F, 0x6B, 0x6D, 0xA0, 0x71 + }, + { + 0x93, 0xF2, 0xF3, 0xD6, 0x9B, 0x2D, 0x36, 0x52, + 0x95, 0x56, 0xEC, 0xCA, 0xF9, 0xF9, 0x9A, 0xDB, + 0xE8, 0x95, 0xE1, 0x57, 0x22, 0x31, 0xE6, 0x49, + 0xB5, 0x05, 0x84, 0xB5, 0xD7, 0xD0, 0x8A, 0xF8 + }, + { + 0x06, 0xE0, 0x6D, 0x61, 0x0F, 0x2E, 0xEB, 0xBA, + 0x36, 0x76, 0x82, 0x3E, 0x77, 0x44, 0xD7, 0x51, + 0xAF, 0xF7, 0x30, 0x76, 0xED, 0x65, 0xF3, 0xCF, + 0xF5, 0xE7, 0x2F, 0xD2, 0x27, 0x99, 0x9C, 0x77 + }, + { + 0x8D, 0xF7, 0x57, 0xB3, 0xA1, 0xE0, 0xF4, 0x80, + 0xFA, 0x76, 0xC7, 0xF3, 0x58, 0xED, 0x03, 0x98, + 0xBE, 0x3F, 0x2A, 0x8F, 0x7B, 0x90, 0xEA, 0x8C, + 0x80, 0x75, 0x99, 0xDE, 0xDA, 0x1D, 0x05, 0x34 + }, + { + 0xEE, 0xC9, 0xC5, 0xC6, 0x3C, 0xC5, 0x16, 0x9D, + 0x96, 0x7B, 0xB1, 0x62, 0x4E, 0x9E, 0xE5, 0xCE, + 0xD9, 0x28, 0x97, 0x73, 0x6E, 0xFB, 0xD1, 0x57, + 0x54, 0x8D, 0x82, 0xE8, 0x7C, 0xC7, 0x2F, 0x25 + }, + { + 0xCC, 0x2B, 0x58, 0x32, 0xAD, 0x27, 0x2C, 0xC5, + 0x5C, 0x10, 0xD4, 0xF8, 0xC7, 0xF8, 0xBB, 0x38, + 0xE6, 0xE4, 0xEB, 0x92, 0x2F, 0x93, 0x86, 0x83, + 0x0F, 0x90, 0xB1, 0xE3, 0xDA, 0x39, 0x37, 0xD5 + }, + { + 0x36, 0x89, 0x85, 0xD5, 0x38, 0x7C, 0x0B, 0xFC, + 0x92, 0x8A, 0xC2, 0x54, 0xFA, 0x6D, 0x16, 0x67, + 0x3E, 0x70, 0x94, 0x75, 0x66, 0x96, 0x1B, 0x5F, + 0xB3, 0x32, 0x5A, 0x58, 0x8A, 0xB3, 0x17, 0x3A + }, + { + 0xF1, 0xE4, 0x42, 0xAF, 0xB8, 0x72, 0x15, 0x1F, + 0x81, 0x34, 0x95, 0x6C, 0x54, 0x8A, 0xE3, 0x24, + 0x0D, 0x07, 0xE6, 0xE3, 0x38, 0xD4, 0xA7, 0xA6, + 0xAF, 0x8D, 0xA4, 0x11, 0x9A, 0xB0, 0xE2, 0xB0 + }, + { + 0xB0, 0x12, 0xC7, 0x54, 0x6A, 0x39, 0xC4, 0x0C, + 0xAD, 0xEC, 0xE4, 0xE0, 0x4E, 0x7F, 0x33, 0xC5, + 0x93, 0xAD, 0x18, 0x2E, 0xBC, 0x5A, 0x46, 0xD2, + 0xDB, 0xF4, 0xAD, 0x1A, 0x92, 0xF5, 0x9E, 0x7B + }, + { + 0x6C, 0x60, 0x97, 0xCD, 0x20, 0x33, 0x09, 0x6B, + 0x4D, 0xF3, 0x17, 0xDE, 0x8A, 0x90, 0x8B, 0x7D, + 0x0C, 0x72, 0x94, 0x39, 0x0C, 0x5A, 0x39, 0x9C, + 0x30, 0x1B, 0xF2, 0xA2, 0x65, 0x2E, 0x82, 0x62 + }, + { + 0xBA, 0x83, 0xFE, 0xB5, 0x10, 0xB4, 0x9A, 0xDE, + 0x4F, 0xAE, 0xFB, 0xE9, 0x42, 0x78, 0x1E, 0xAF, + 0xD4, 0x1A, 0xD5, 0xD4, 0x36, 0x88, 0x85, 0x31, + 0xB6, 0x88, 0x59, 0xF2, 0x2C, 0x2D, 0x16, 0x4A + }, + { + 0x5A, 0x06, 0x9E, 0x43, 0x92, 0x19, 0x5A, 0xC9, + 0xD2, 0x84, 0xA4, 0x7F, 0x3B, 0xD8, 0x54, 0xAF, + 0x8F, 0xD0, 0xD7, 0xFD, 0xC3, 0x48, 0x3D, 0x2C, + 0x5F, 0x34, 0x24, 0xCC, 0xFD, 0xA1, 0x5C, 0x8E + }, + { + 0x7E, 0x88, 0xD6, 0x4B, 0xBB, 0xE2, 0x02, 0x4F, + 0x44, 0x54, 0xBA, 0x13, 0x98, 0xB3, 0xD8, 0x65, + 0x2D, 0xCE, 0xC8, 0x20, 0xB1, 0x4C, 0x3B, 0x0A, + 0xBF, 0xBF, 0x0F, 0x4F, 0x33, 0x06, 0xBB, 0x5E + }, + { + 0xF8, 0x74, 0x2F, 0xF4, 0x6D, 0xFD, 0xF3, 0xEC, + 0x82, 0x64, 0xF9, 0x94, 0x5B, 0x20, 0x41, 0x94, + 0x62, 0xF0, 0x69, 0xE8, 0x33, 0xC5, 0x94, 0xEC, + 0x80, 0xFF, 0xAC, 0x5E, 0x7E, 0x51, 0x34, 0xF9 + }, + { + 0xD3, 0xE0, 0xB7, 0x38, 0xD2, 0xE9, 0x2F, 0x3C, + 0x47, 0xC7, 0x94, 0x66, 0x66, 0x09, 0xC0, 0xF5, + 0x50, 0x4F, 0x67, 0xEC, 0x4E, 0x76, 0x0E, 0xEE, + 0xCC, 0xF8, 0x64, 0x4E, 0x68, 0x33, 0x34, 0x11 + }, + { + 0x0C, 0x90, 0xCE, 0x10, 0xED, 0xF0, 0xCE, 0x1D, + 0x47, 0xEE, 0xB5, 0x0B, 0x5B, 0x7A, 0xFF, 0x8E, + 0xE8, 0xA4, 0x3B, 0x64, 0xA8, 0x89, 0xC1, 0xC6, + 0xC6, 0xB8, 0xE3, 0x1A, 0x3C, 0xFC, 0x45, 0xEE + }, + { + 0x83, 0x91, 0x7A, 0xC1, 0xCD, 0xAD, 0xE8, 0xF0, + 0xE3, 0xBF, 0x42, 0x6F, 0xEA, 0xC1, 0x38, 0x8B, + 0x3F, 0xCB, 0xE3, 0xE1, 0xBF, 0x98, 0x79, 0x8C, + 0x81, 0x58, 0xBF, 0x75, 0x8E, 0x8D, 0x5D, 0x4E + }, + { + 0xDC, 0x8E, 0xB0, 0xC0, 0x13, 0xFA, 0x9D, 0x06, + 0x4E, 0xE3, 0x76, 0x23, 0x36, 0x9F, 0xB3, 0x94, + 0xAF, 0x97, 0x4B, 0x1A, 0xAC, 0x82, 0x40, 0x5B, + 0x88, 0x97, 0x6C, 0xD8, 0xFC, 0xA1, 0x25, 0x30 + }, + { + 0x9A, 0xF4, 0xFC, 0x92, 0xEA, 0x8D, 0x6B, 0x5F, + 0xE7, 0x99, 0x0E, 0x3A, 0x02, 0x70, 0x1E, 0xC2, + 0x2B, 0x2D, 0xFD, 0x71, 0x00, 0xB9, 0x0D, 0x05, + 0x51, 0x86, 0x94, 0x17, 0x95, 0x5E, 0x44, 0xC8 + }, + { + 0xC7, 0x22, 0xCE, 0xC1, 0x31, 0xBA, 0xA1, 0x63, + 0xF4, 0x7E, 0x4B, 0x33, 0x9E, 0x1F, 0xB9, 0xB4, + 0xAC, 0xA2, 0x48, 0xC4, 0x75, 0x93, 0x45, 0xEA, + 0xDB, 0xD6, 0xC6, 0xA7, 0xDD, 0xB5, 0x04, 0x77 + }, + { + 0x18, 0x37, 0xB1, 0x20, 0xD4, 0xE4, 0x04, 0x6C, + 0x6D, 0xE8, 0xCC, 0xAF, 0x09, 0xF1, 0xCA, 0xF3, + 0x02, 0xAD, 0x56, 0x23, 0x4E, 0x6B, 0x42, 0x2C, + 0xE9, 0x0A, 0x61, 0xBF, 0x06, 0xAE, 0xE4, 0x3D + }, + { + 0x87, 0xAC, 0x9D, 0x0F, 0x8A, 0x0B, 0x11, 0xBF, + 0xED, 0xD6, 0x99, 0x1A, 0x6D, 0xAF, 0x34, 0xC8, + 0xAA, 0x5D, 0x7E, 0x8A, 0xE1, 0xB9, 0xDF, 0x4A, + 0xF7, 0x38, 0x00, 0x5F, 0xE7, 0x8C, 0xE9, 0x3C + }, + { + 0xE2, 0x1F, 0xB6, 0x68, 0xEB, 0xB8, 0xBF, 0x2D, + 0x82, 0x08, 0x6D, 0xED, 0xCB, 0x3A, 0x53, 0x71, + 0xC2, 0xC4, 0x6F, 0xA1, 0xAC, 0x11, 0xD2, 0xE2, + 0xC5, 0x66, 0xD1, 0x4A, 0xD3, 0xC3, 0x65, 0x3F + }, + { + 0x5A, 0x9A, 0x69, 0x81, 0x5E, 0x4D, 0x3E, 0xB7, + 0x72, 0xED, 0x90, 0x8F, 0xE6, 0x58, 0xCE, 0x50, + 0x87, 0x31, 0x0E, 0xC1, 0xD5, 0x0C, 0xB9, 0x4F, + 0x56, 0x28, 0x33, 0x9A, 0x61, 0xDC, 0xD9, 0xEE + }, + { + 0xAA, 0xC2, 0x85, 0xF1, 0x20, 0x8F, 0x70, 0xA6, + 0x47, 0x97, 0xD0, 0xA9, 0x40, 0x0D, 0xA6, 0x46, + 0x53, 0x30, 0x18, 0x38, 0xFE, 0xF6, 0x69, 0x0B, + 0x87, 0xCD, 0xA9, 0x15, 0x9E, 0xE0, 0x7E, 0xF4 + }, + { + 0x05, 0x64, 0x3C, 0x1C, 0x6F, 0x26, 0x59, 0x25, + 0xA6, 0x50, 0x93, 0xF9, 0xDE, 0x8A, 0x19, 0x1C, + 0x4F, 0x6F, 0xD1, 0x41, 0x8F, 0xBF, 0x66, 0xBE, + 0x80, 0x59, 0xA9, 0x1B, 0xA8, 0xDC, 0xDA, 0x61 + }, + { + 0x1C, 0x6C, 0xDE, 0x5B, 0x78, 0x10, 0x3C, 0x9E, + 0x6F, 0x04, 0x6D, 0xFE, 0x30, 0xF5, 0x12, 0x1C, + 0xF9, 0xD4, 0x03, 0x9E, 0xFE, 0x22, 0x25, 0x40, + 0xA4, 0x1B, 0xBC, 0x06, 0xE4, 0x69, 0xFE, 0xB6 + }, + { + 0xB4, 0x9B, 0xB4, 0x6D, 0x1B, 0x19, 0x3B, 0x04, + 0x5E, 0x74, 0x12, 0x05, 0x9F, 0xE7, 0x2D, 0x55, + 0x25, 0x52, 0xA8, 0xFB, 0x6C, 0x36, 0x41, 0x07, + 0x23, 0xDC, 0x7D, 0x05, 0xFC, 0xCE, 0xDE, 0xD3 + }, + { + 0xB6, 0x12, 0xD3, 0xD2, 0x1F, 0xC4, 0xDE, 0x3C, + 0x79, 0x1A, 0xF7, 0x35, 0xE5, 0x9F, 0xB7, 0x17, + 0xD8, 0x39, 0x72, 0x3B, 0x42, 0x50, 0x8E, 0x9E, + 0xBF, 0x78, 0x06, 0xD9, 0x3E, 0x9C, 0x83, 0x7F + }, + { + 0x7C, 0x33, 0x90, 0xA3, 0xE5, 0xCB, 0x27, 0xD1, + 0x86, 0x8B, 0xA4, 0x55, 0xCF, 0xEB, 0x32, 0x22, + 0xFD, 0xE2, 0x7B, 0xCD, 0xA4, 0xBF, 0x24, 0x8E, + 0x3D, 0x29, 0xCF, 0x1F, 0x34, 0x32, 0x9F, 0x25 + }, + { + 0xBD, 0x42, 0xEE, 0xA7, 0xB3, 0x54, 0x86, 0xCD, + 0xD0, 0x90, 0x7C, 0xB4, 0x71, 0x2E, 0xDE, 0x2F, + 0x4D, 0xEE, 0xCC, 0xBC, 0xA1, 0x91, 0x60, 0x38, + 0x65, 0xA1, 0xCC, 0x80, 0x9F, 0x12, 0xB4, 0x46 + }, + { + 0xD1, 0xDD, 0x62, 0x01, 0x74, 0x0C, 0xFA, 0xAD, + 0x53, 0xCE, 0xCC, 0xB7, 0x56, 0xB1, 0x10, 0xF3, + 0xD5, 0x0F, 0x81, 0x7B, 0x43, 0xD7, 0x55, 0x95, + 0x57, 0xE5, 0x7A, 0xAD, 0x14, 0x3A, 0x85, 0xD9 + }, + { + 0x58, 0x29, 0x64, 0x3C, 0x1B, 0x10, 0xE1, 0xC8, + 0xCC, 0xF2, 0x0C, 0x9B, 0x4A, 0xF8, 0x21, 0xEA, + 0x05, 0x2D, 0x7F, 0x0F, 0x7C, 0x22, 0xF7, 0x38, + 0x0B, 0xBB, 0xCF, 0xAF, 0xB9, 0x77, 0xE2, 0x1F + }, + { + 0xFC, 0x4C, 0xF2, 0xA7, 0xFB, 0xE0, 0xB1, 0xE8, + 0xAE, 0xFB, 0xE4, 0xB4, 0xB7, 0x9E, 0xD8, 0x4E, + 0xC9, 0x7B, 0x03, 0x4F, 0x51, 0xB4, 0xE9, 0x7F, + 0x76, 0x0B, 0x20, 0x63, 0x97, 0x65, 0xB9, 0x33 + }, + { + 0x4D, 0x7C, 0x3B, 0x34, 0x38, 0xA0, 0xBD, 0xA2, + 0x8E, 0x7A, 0x96, 0xE4, 0x20, 0x27, 0xD8, 0x13, + 0xE8, 0x8A, 0xE6, 0x28, 0x85, 0x49, 0x98, 0x33, + 0xD3, 0xC5, 0xF6, 0x35, 0x9E, 0xF7, 0xED, 0xBC + }, + { + 0x34, 0xCB, 0xD3, 0x20, 0x68, 0xEF, 0x7E, 0x82, + 0x09, 0x9E, 0x58, 0x0B, 0xF9, 0xE2, 0x64, 0x23, + 0xE9, 0x81, 0xE3, 0x1B, 0x1B, 0xBC, 0xE6, 0x1A, + 0xEA, 0xB1, 0x4C, 0x32, 0xA2, 0x73, 0xE4, 0xCB + }, + { + 0xA0, 0x5D, 0xDA, 0x7D, 0x0D, 0xA9, 0xE0, 0x94, + 0xAE, 0x22, 0x53, 0x3F, 0x79, 0xE7, 0xDC, 0xCD, + 0x26, 0xB1, 0x75, 0x7C, 0xEF, 0xB9, 0x5B, 0xCF, + 0x62, 0xC4, 0xFF, 0x9C, 0x26, 0x92, 0xE1, 0xC0 + }, + { + 0x22, 0x4C, 0xCF, 0xFA, 0x7C, 0xCA, 0x4C, 0xE3, + 0x4A, 0xFD, 0x47, 0xF6, 0x2A, 0xDE, 0x53, 0xC5, + 0xE8, 0x48, 0x9B, 0x04, 0xAC, 0x9C, 0x41, 0xF7, + 0xFA, 0xD0, 0xC8, 0xED, 0xEB, 0x89, 0xE9, 0x41 + }, + { + 0x6B, 0xC6, 0x07, 0x64, 0x83, 0xAA, 0x11, 0xC0, + 0x7F, 0xBA, 0x55, 0xC0, 0xF9, 0xA1, 0xB5, 0xDA, + 0x87, 0xEC, 0xBF, 0xFE, 0xA7, 0x55, 0x98, 0xCC, + 0x31, 0x8A, 0x51, 0x4C, 0xEC, 0x7B, 0x3B, 0x6A + }, + { + 0x9A, 0x03, 0x60, 0xE2, 0x3A, 0x22, 0xF4, 0xF7, + 0x6C, 0x0E, 0x95, 0x28, 0xDA, 0xFD, 0x12, 0x9B, + 0xB4, 0x67, 0x5F, 0xB8, 0x8D, 0x44, 0xEA, 0xF8, + 0x57, 0x77, 0x30, 0x0C, 0xEC, 0x9B, 0xCC, 0x79 + }, + { + 0x79, 0x01, 0x99, 0xB4, 0xCA, 0x90, 0xDE, 0xDC, + 0xCF, 0xE3, 0x24, 0x74, 0xE8, 0x5B, 0x17, 0x4F, + 0x06, 0x9E, 0x35, 0x42, 0xBE, 0x31, 0x04, 0xC1, + 0x12, 0x5C, 0x2F, 0xDB, 0xD6, 0x9D, 0x32, 0xC7 + }, + { + 0x55, 0x83, 0x99, 0x25, 0x83, 0x4C, 0xA3, 0xE8, + 0x25, 0xE9, 0x92, 0x41, 0x87, 0x4D, 0x16, 0xD6, + 0xC2, 0x62, 0x36, 0x29, 0xC4, 0xC2, 0xAD, 0xDD, + 0xF0, 0xDB, 0xA0, 0x1E, 0x6C, 0xE8, 0xA0, 0xDC + }, + { + 0x61, 0x5F, 0xF8, 0x46, 0xD9, 0x93, 0x00, 0x7D, + 0x38, 0xDE, 0x1A, 0xEC, 0xB3, 0x17, 0x82, 0x89, + 0xDE, 0xD0, 0x9E, 0x6B, 0xB5, 0xCB, 0xD6, 0x0F, + 0x69, 0xC6, 0xAA, 0x36, 0x38, 0x30, 0x20, 0xF7 + }, + { + 0xF0, 0xE4, 0x0B, 0x4E, 0xD4, 0x0D, 0x34, 0x85, + 0x1E, 0x72, 0xB4, 0xEE, 0x4D, 0x00, 0xEA, 0x6A, + 0x40, 0xEA, 0x1C, 0x1B, 0xF9, 0xE5, 0xC2, 0x69, + 0x71, 0x0C, 0x9D, 0x51, 0xCB, 0xB8, 0xA3, 0xC9 + }, + { + 0x0B, 0x07, 0xB2, 0x33, 0x3B, 0x08, 0xD0, 0x8C, + 0x11, 0xCA, 0x34, 0xAB, 0x44, 0x9B, 0x71, 0xD2, + 0x9A, 0x0F, 0x43, 0xE1, 0xF7, 0x78, 0xE0, 0x73, + 0xE7, 0x90, 0x06, 0xCC, 0xB7, 0x30, 0xED, 0x62 + }, + { + 0xD1, 0xF4, 0xC2, 0x9D, 0x9F, 0x23, 0xEA, 0x35, + 0xEC, 0x40, 0x35, 0xB3, 0x77, 0xD5, 0x06, 0x53, + 0x8E, 0x72, 0x8B, 0xC7, 0x39, 0xC1, 0x45, 0x96, + 0x80, 0xCF, 0x1C, 0xC6, 0x94, 0x24, 0x92, 0x4D + }, + { + 0x12, 0x79, 0xCF, 0x6F, 0x66, 0x9F, 0x92, 0xF6, + 0xBF, 0xC2, 0x5D, 0x60, 0x5B, 0x94, 0x40, 0xC7, + 0xDC, 0xCB, 0xD2, 0x5D, 0xF2, 0x8D, 0xC7, 0x35, + 0x3A, 0xBC, 0x1C, 0x05, 0x30, 0x40, 0x5D, 0xC4 + }, + { + 0x1F, 0xA0, 0xAF, 0x00, 0x77, 0x5D, 0xC2, 0xCE, + 0x76, 0x50, 0x6D, 0x32, 0x80, 0xF4, 0x72, 0xD2, + 0xF6, 0xFF, 0x97, 0xA2, 0x15, 0x1F, 0xAA, 0x82, + 0x79, 0x42, 0xFE, 0xA4, 0x4A, 0xD0, 0xBA, 0x1F + }, + { + 0x3E, 0x1A, 0xD5, 0x4A, 0x5F, 0x83, 0x5B, 0x98, + 0x3B, 0xD2, 0xAA, 0xB0, 0xED, 0x2A, 0x4C, 0x0B, + 0xDD, 0x72, 0x16, 0x20, 0x9C, 0x36, 0xA7, 0x9E, + 0x9E, 0x2A, 0xAB, 0xB9, 0x9F, 0xAF, 0x35, 0x12 + }, + { + 0xC6, 0xED, 0x39, 0xE2, 0xD8, 0xB6, 0x36, 0xEC, + 0xCB, 0xA2, 0x45, 0xEF, 0x4E, 0x88, 0x64, 0xF4, + 0xCD, 0x94, 0x6B, 0xE2, 0x16, 0xB9, 0xBE, 0x48, + 0x30, 0x3E, 0x08, 0xB9, 0x2D, 0xD0, 0x94, 0x34 + }, + { + 0xE2, 0x47, 0x36, 0xC1, 0x3E, 0xCB, 0x9F, 0x36, + 0xA0, 0xD8, 0x29, 0xD4, 0x79, 0x8D, 0x76, 0x99, + 0xC1, 0x4C, 0xC6, 0x5B, 0x6D, 0xC4, 0x4E, 0xD6, + 0xF1, 0x0C, 0xD4, 0x85, 0x3D, 0x6E, 0x07, 0x57 + }, + { + 0x38, 0x9B, 0xE8, 0x80, 0x52, 0xA3, 0x81, 0x27, + 0x2C, 0x6D, 0xF7, 0x41, 0xA8, 0x8A, 0xD3, 0x49, + 0xB7, 0x12, 0x71, 0x84, 0x35, 0x48, 0x0A, 0x81, + 0x90, 0xB7, 0x04, 0x77, 0x1D, 0x2D, 0xE6, 0x37 + }, + { + 0x88, 0x9F, 0x2D, 0x57, 0x8A, 0x5D, 0xAE, 0xFD, + 0x34, 0x1C, 0x21, 0x09, 0x84, 0xE1, 0x26, 0xD1, + 0xD9, 0x6D, 0xA2, 0xDE, 0xE3, 0xC8, 0x1F, 0x7A, + 0x60, 0x80, 0xBF, 0x84, 0x56, 0x9B, 0x31, 0x14 + }, + { + 0xE9, 0x36, 0x09, 0x5B, 0x9B, 0x98, 0x2F, 0xFC, + 0x85, 0x6D, 0x2F, 0x52, 0x76, 0xA4, 0xE5, 0x29, + 0xEC, 0x73, 0x95, 0xDA, 0x31, 0x6D, 0x62, 0x87, + 0x02, 0xFB, 0x28, 0x1A, 0xDA, 0x6F, 0x38, 0x99 + }, + { + 0xEF, 0x89, 0xCE, 0x1D, 0x6F, 0x8B, 0x48, 0xEA, + 0x5C, 0xD6, 0xAE, 0xAB, 0x6A, 0x83, 0xD0, 0xCC, + 0x98, 0xC9, 0xA3, 0xA2, 0x07, 0xA1, 0x08, 0x57, + 0x32, 0xF0, 0x47, 0xD9, 0x40, 0x38, 0xC2, 0x88 + }, + { + 0xF9, 0x25, 0x01, 0x6D, 0x79, 0xF2, 0xAC, 0xA8, + 0xC4, 0x9E, 0xDF, 0xCD, 0x66, 0x21, 0xD5, 0xBE, + 0x3C, 0x8C, 0xEC, 0x61, 0xBD, 0x58, 0x71, 0xD8, + 0xC1, 0xD3, 0xA5, 0x65, 0xF3, 0x5E, 0x0C, 0x9F + }, + { + 0x63, 0xE8, 0x63, 0x4B, 0x75, 0x7A, 0x38, 0xF9, + 0x2B, 0x92, 0xFD, 0x23, 0x89, 0x3B, 0xA2, 0x99, + 0x85, 0x3A, 0x86, 0x13, 0x67, 0x9F, 0xDF, 0x7E, + 0x05, 0x11, 0x09, 0x5C, 0x0F, 0x04, 0x7B, 0xCA + }, + { + 0xCF, 0x2C, 0xCA, 0x07, 0x72, 0xB7, 0x05, 0xEB, + 0x57, 0xD2, 0x89, 0x43, 0xF8, 0x3D, 0x35, 0x3F, + 0xE2, 0x91, 0xE5, 0xB3, 0x77, 0x78, 0x0B, 0x37, + 0x4C, 0x8B, 0xA4, 0x66, 0x58, 0x30, 0xBE, 0x87 + }, + { + 0x46, 0xDF, 0x5B, 0x87, 0xC8, 0x0E, 0x7E, 0x40, + 0x74, 0xAE, 0xE6, 0x85, 0x59, 0x42, 0x47, 0x42, + 0x84, 0x5B, 0x9B, 0x35, 0x0F, 0x51, 0xBA, 0x55, + 0xB0, 0x74, 0xBB, 0xAE, 0x4C, 0x62, 0x6A, 0xAB + }, + { + 0x65, 0x8A, 0xA4, 0xF9, 0xD2, 0xBC, 0xBD, 0x4F, + 0x7F, 0x8E, 0xB6, 0x3E, 0x68, 0xF5, 0x36, 0x7E, + 0xDB, 0xC5, 0x00, 0xA0, 0xB1, 0xFB, 0xB4, 0x1E, + 0x9D, 0xF1, 0x41, 0xBC, 0xBA, 0x8F, 0xCD, 0x53 + }, + { + 0xEE, 0x80, 0x55, 0x50, 0x08, 0xA7, 0x16, 0x55, + 0xE0, 0x81, 0x09, 0x2B, 0xBA, 0x6F, 0x67, 0x0E, + 0xD9, 0x8A, 0xF9, 0xA0, 0x9F, 0xB5, 0xAF, 0xB9, + 0x4C, 0xBC, 0x5C, 0x75, 0x48, 0x14, 0xDB, 0x4F + }, + { + 0x2C, 0x5F, 0x9D, 0x04, 0x82, 0x20, 0xB0, 0x41, + 0xB6, 0xD4, 0x52, 0x4B, 0x44, 0x90, 0xCF, 0x8C, + 0x66, 0xFC, 0xB8, 0xE1, 0x4B, 0x0D, 0x64, 0x88, + 0x7A, 0xA1, 0xE4, 0x76, 0x1A, 0x60, 0x2B, 0x39 + }, + { + 0x44, 0xCB, 0x63, 0x11, 0xD0, 0x75, 0x0B, 0x7E, + 0x33, 0xF7, 0x33, 0x3A, 0xA7, 0x8A, 0xAC, 0xA9, + 0xC3, 0x4A, 0xD5, 0xF7, 0x9C, 0x1B, 0x15, 0x91, + 0xEC, 0x33, 0x95, 0x1E, 0x69, 0xC4, 0xC4, 0x61 + }, + { + 0x0C, 0x6C, 0xE3, 0x2A, 0x3E, 0xA0, 0x56, 0x12, + 0xC5, 0xF8, 0x09, 0x0F, 0x6A, 0x7E, 0x87, 0xF5, + 0xAB, 0x30, 0xE4, 0x1B, 0x70, 0x7D, 0xCB, 0xE5, + 0x41, 0x55, 0x62, 0x0A, 0xD7, 0x70, 0xA3, 0x40 + }, + { + 0xC6, 0x59, 0x38, 0xDD, 0x3A, 0x05, 0x3C, 0x72, + 0x9C, 0xF5, 0xB7, 0xC8, 0x9F, 0x39, 0x0B, 0xFE, + 0xBB, 0x51, 0x12, 0x76, 0x6B, 0xB0, 0x0A, 0xA5, + 0xFA, 0x31, 0x64, 0xDF, 0xDF, 0x3B, 0x56, 0x47 + }, + { + 0x7D, 0xE7, 0xF0, 0xD5, 0x9A, 0x90, 0x39, 0xAF, + 0xF3, 0xAA, 0xF3, 0x2C, 0x3E, 0xE5, 0x2E, 0x79, + 0x17, 0x53, 0x57, 0x29, 0x06, 0x21, 0x68, 0xD2, + 0x49, 0x0B, 0x6B, 0x6C, 0xE2, 0x44, 0xB3, 0x80 + }, + { + 0x89, 0x58, 0x98, 0xF5, 0x3A, 0x8F, 0x39, 0xE4, + 0x24, 0x10, 0xDA, 0x77, 0xB6, 0xC4, 0x81, 0x5B, + 0x0B, 0xB2, 0x39, 0x5E, 0x39, 0x22, 0xF5, 0xBE, + 0xD0, 0xE1, 0xFB, 0xF2, 0xA4, 0xC6, 0xDF, 0xEB + }, + { + 0xC9, 0x05, 0xA8, 0x49, 0x84, 0x34, 0x8A, 0x64, + 0xDB, 0x1F, 0x54, 0x20, 0x83, 0x74, 0x8A, 0xD9, + 0x0A, 0x4B, 0xAD, 0x98, 0x33, 0xCB, 0x6D, 0xA3, + 0x87, 0x29, 0x34, 0x31, 0xF1, 0x9E, 0x7C, 0x9C + }, + { + 0xED, 0x37, 0xD1, 0xA4, 0xD0, 0x6C, 0x90, 0xD1, + 0x95, 0x78, 0x48, 0x66, 0x7E, 0x95, 0x48, 0xFE, + 0xBB, 0x5D, 0x42, 0x3E, 0xAB, 0x4F, 0x56, 0x78, + 0x5C, 0xC4, 0xB5, 0x41, 0x6B, 0x78, 0x00, 0x08 + }, + { + 0x0B, 0xC6, 0x5D, 0x99, 0x97, 0xFB, 0x73, 0x4A, + 0x56, 0x1F, 0xB1, 0xE9, 0xF8, 0xC0, 0x95, 0x8A, + 0x02, 0xC7, 0xA4, 0xDB, 0xD0, 0x96, 0xEB, 0xEF, + 0x1A, 0x17, 0x51, 0xAE, 0xD9, 0x59, 0xEE, 0xD7 + }, + { + 0x7C, 0x5F, 0x43, 0x2E, 0xB8, 0xB7, 0x35, 0x2A, + 0x94, 0x94, 0xDE, 0xA4, 0xD5, 0x3C, 0x21, 0x38, + 0x70, 0x31, 0xCE, 0x70, 0xE8, 0x5D, 0x94, 0x08, + 0xFC, 0x6F, 0x8C, 0xD9, 0x8A, 0x6A, 0xAA, 0x1E + }, + { + 0xB8, 0xBF, 0x8E, 0x2C, 0x34, 0xE0, 0x33, 0x98, + 0x36, 0x39, 0x90, 0x9E, 0xAA, 0x37, 0x64, 0x0D, + 0x87, 0x7B, 0x04, 0x8F, 0xE2, 0x99, 0xB4, 0x70, + 0xAF, 0x2D, 0x0B, 0xA8, 0x2A, 0x5F, 0x14, 0xC0 + }, + { + 0x88, 0xA9, 0xDD, 0x13, 0xD5, 0xDA, 0xDB, 0xDE, + 0xE6, 0xBF, 0xF7, 0xEE, 0x1E, 0xF8, 0xC7, 0x1C, + 0xC1, 0x93, 0xAA, 0x4B, 0xF3, 0xE8, 0x4F, 0x8F, + 0xE8, 0x0C, 0xB0, 0x75, 0x68, 0x3C, 0x07, 0x79 + }, + { + 0x9A, 0xED, 0xB8, 0x87, 0x6D, 0xD2, 0x1C, 0x8C, + 0x84, 0xD2, 0xE7, 0x02, 0xA1, 0x36, 0x25, 0x98, + 0x04, 0x62, 0xF6, 0x8B, 0xF0, 0xA1, 0xB7, 0x25, + 0x4A, 0xD8, 0x06, 0xC3, 0x84, 0x03, 0xC9, 0xDE + }, + { + 0xD0, 0x97, 0x57, 0x3D, 0xF2, 0xD6, 0xB2, 0x48, + 0x9A, 0x47, 0x94, 0x84, 0x86, 0x98, 0x00, 0xA1, + 0xF8, 0x33, 0xEA, 0x16, 0x9E, 0xFF, 0x32, 0xAE, + 0x3C, 0xE6, 0x3A, 0x20, 0x79, 0x54, 0x8D, 0x78 + }, + { + 0xD1, 0x8F, 0x27, 0xA3, 0xE5, 0x55, 0xD7, 0xF9, + 0x1A, 0x00, 0x7C, 0x67, 0xAC, 0xEE, 0xDE, 0x39, + 0x1F, 0x75, 0xA6, 0x1F, 0xA4, 0x2A, 0x0B, 0x45, + 0x66, 0xEB, 0x58, 0x2C, 0xA0, 0x5E, 0xBC, 0xE7 + }, + { + 0xDF, 0x1D, 0xAA, 0x90, 0xB1, 0x70, 0x23, 0x13, + 0xE6, 0xA5, 0x90, 0x1C, 0x7A, 0xFC, 0x5E, 0xD9, + 0x65, 0x77, 0x17, 0xA7, 0x15, 0xFA, 0x53, 0xA4, + 0x18, 0x9E, 0xC1, 0xE5, 0xDF, 0x29, 0x3A, 0x68 + }, + { + 0x04, 0xE3, 0xA4, 0x96, 0xB6, 0x69, 0x96, 0xC6, + 0x6E, 0x32, 0x91, 0x9E, 0xD1, 0xF9, 0x4C, 0x36, + 0xEE, 0xBB, 0xF2, 0x40, 0x63, 0x3A, 0x2F, 0x73, + 0x98, 0x45, 0xF0, 0x29, 0x5D, 0x34, 0xAF, 0xBA + }, + { + 0x8C, 0x45, 0xD8, 0x8C, 0x4E, 0x9C, 0x9D, 0x0C, + 0x8C, 0x67, 0x7F, 0xE4, 0x8F, 0xA5, 0x44, 0x9B, + 0xA3, 0x01, 0x78, 0xD4, 0x0A, 0xF0, 0xF0, 0x21, + 0x79, 0x21, 0xC6, 0x2E, 0x4B, 0x60, 0xCD, 0xD3 + }, + { + 0xE1, 0x49, 0xA6, 0xB1, 0x3B, 0xDE, 0xDE, 0xA2, + 0xEE, 0xEE, 0x00, 0x9C, 0xE9, 0x44, 0x5E, 0x8D, + 0xCF, 0x76, 0xB7, 0x6E, 0x55, 0xA5, 0x01, 0xD8, + 0xF5, 0xB4, 0x3F, 0xF8, 0x96, 0x79, 0x6A, 0xD1 + }, + { + 0xA8, 0x37, 0xC4, 0xC7, 0xC6, 0xF5, 0xCF, 0xB9, + 0x9E, 0x10, 0x85, 0xFD, 0x43, 0x28, 0x7A, 0x41, + 0x05, 0xCB, 0x28, 0xB7, 0x6F, 0xC3, 0x8B, 0x60, + 0x55, 0xC5, 0xDC, 0xFF, 0x78, 0xB8, 0x25, 0x65 + }, + { + 0x42, 0x41, 0x1F, 0x28, 0x78, 0x0B, 0x4F, 0x16, + 0x38, 0x54, 0x0B, 0x87, 0x05, 0x21, 0xEC, 0x45, + 0xBC, 0xEB, 0x1E, 0x0C, 0x71, 0x31, 0xF7, 0xE1, + 0xC4, 0x67, 0x2E, 0x43, 0x6C, 0x88, 0xC8, 0xE9 + }, + { + 0x34, 0xB4, 0xE8, 0x76, 0x76, 0x94, 0x71, 0xDF, + 0x55, 0x2E, 0x55, 0x22, 0xCE, 0xA7, 0x84, 0xFA, + 0x53, 0xAC, 0x61, 0xBE, 0xDE, 0x8C, 0xFE, 0x29, + 0x14, 0x09, 0xE6, 0x8B, 0x69, 0xE8, 0x77, 0x6F + }, + { + 0x8F, 0x31, 0xD6, 0x37, 0xA9, 0x1D, 0xBD, 0x0E, + 0xCB, 0x0B, 0xA0, 0xE6, 0x94, 0xBE, 0xC1, 0x44, + 0x76, 0x58, 0xCE, 0x6C, 0x27, 0xEA, 0x9B, 0x95, + 0xFF, 0x36, 0x70, 0x1C, 0xAF, 0x36, 0xF0, 0x01 + }, + { + 0xB5, 0xC8, 0x95, 0xEB, 0x07, 0x1E, 0x3D, 0x38, + 0x52, 0x8D, 0x47, 0x5D, 0x3B, 0xB0, 0xBA, 0x88, + 0xB7, 0x17, 0x95, 0xE4, 0x0A, 0x98, 0x2E, 0x2A, + 0xC2, 0xD8, 0x44, 0x22, 0xA0, 0xF2, 0x68, 0x5D + }, + { + 0xE9, 0x06, 0x25, 0x7C, 0x41, 0x9D, 0x94, 0x1E, + 0xD2, 0xB8, 0xA9, 0xC1, 0x27, 0x81, 0xDB, 0x97, + 0x59, 0xA3, 0xFC, 0xF3, 0xDC, 0x7C, 0xDB, 0x03, + 0x15, 0x99, 0xE1, 0x08, 0x6B, 0x67, 0x2F, 0x10 + }, + { + 0x98, 0xAD, 0x24, 0x39, 0x7C, 0x6E, 0xAE, 0x4C, + 0xF7, 0x3E, 0xA8, 0xBB, 0xEF, 0x5A, 0x0B, 0x74, + 0xD2, 0x1A, 0xD1, 0x5F, 0x33, 0x92, 0x0F, 0x44, + 0x07, 0x0A, 0x98, 0xBD, 0xF5, 0x3D, 0x0B, 0x3A + }, + { + 0xDD, 0x51, 0x0C, 0xA5, 0x5B, 0x11, 0x70, 0xF9, + 0xCE, 0xFD, 0xBB, 0x16, 0xFC, 0x14, 0x52, 0x62, + 0xAA, 0x36, 0x3A, 0x87, 0x0A, 0x01, 0xE1, 0xBC, + 0x4F, 0xBE, 0x40, 0x23, 0x4B, 0x4B, 0x6F, 0x2F + }, + { + 0xF2, 0xD8, 0xD9, 0x31, 0xB9, 0x2E, 0x1C, 0xB6, + 0x98, 0xE5, 0x6E, 0xD0, 0x28, 0x19, 0xEA, 0x11, + 0xD2, 0x66, 0x19, 0xB8, 0x3A, 0x62, 0x09, 0xAD, + 0x67, 0x22, 0x53, 0x68, 0xFE, 0x11, 0x95, 0x71 + }, + { + 0xE4, 0x63, 0x70, 0x55, 0xDB, 0x91, 0xF9, 0x43, + 0x7C, 0xF4, 0x60, 0xEF, 0x40, 0xB5, 0x14, 0x5F, + 0x69, 0x98, 0x26, 0x6A, 0x5E, 0x74, 0xE9, 0x6A, + 0x00, 0x78, 0x2C, 0x62, 0xCF, 0x30, 0xCF, 0x1C + }, + { + 0x35, 0x63, 0x53, 0x0A, 0x89, 0xD3, 0x2B, 0x75, + 0xF7, 0x8D, 0x83, 0xE9, 0x87, 0x2A, 0xD4, 0xC5, + 0x75, 0xF5, 0x20, 0x39, 0x9D, 0x65, 0x03, 0x5D, + 0xED, 0x99, 0xE5, 0xEE, 0xC5, 0x80, 0x71, 0x50 + }, + { + 0x8E, 0x79, 0xF9, 0x2C, 0x86, 0x5B, 0xEB, 0x3E, + 0x1C, 0xDB, 0xF0, 0x8F, 0x75, 0x4A, 0x26, 0x06, + 0xE8, 0x53, 0x49, 0x05, 0x3D, 0x66, 0xD6, 0x16, + 0x02, 0x4A, 0x81, 0x3F, 0xCA, 0x54, 0x1A, 0x4D + }, + { + 0x86, 0x42, 0x26, 0xF2, 0x83, 0x9C, 0x76, 0xB1, + 0xD5, 0xF7, 0xC1, 0x3D, 0x98, 0xC2, 0xA5, 0x15, + 0x8C, 0x2A, 0xBB, 0x71, 0xD9, 0xD8, 0xF0, 0xFA, + 0x1F, 0x7C, 0x3F, 0x74, 0x68, 0x00, 0x16, 0x03 + }, + { + 0xD3, 0xE3, 0xF5, 0xB8, 0xCE, 0xEB, 0xB1, 0x11, + 0x84, 0x80, 0x35, 0x35, 0x90, 0x0B, 0x6E, 0xED, + 0xDA, 0x60, 0x6E, 0xEB, 0x36, 0x97, 0x51, 0xA7, + 0xCD, 0xA3, 0x6C, 0xA3, 0x02, 0x29, 0xFB, 0x02 + }, + { + 0x8C, 0x7D, 0x6B, 0x98, 0x72, 0x69, 0x16, 0x90, + 0x31, 0xF7, 0x1F, 0xD7, 0xE4, 0xC4, 0x45, 0x01, + 0x2D, 0x3E, 0x6A, 0x3C, 0x88, 0x09, 0xF6, 0x47, + 0x9B, 0xD6, 0x67, 0xCF, 0x31, 0x1E, 0x27, 0x6E + }, + { + 0xB9, 0x04, 0xB5, 0x71, 0x1B, 0xF1, 0x9E, 0x85, + 0x32, 0xF7, 0xAD, 0x64, 0x27, 0x41, 0x0A, 0x62, + 0xA1, 0xF7, 0x7F, 0x77, 0xB9, 0xB6, 0xD7, 0x1D, + 0x2F, 0xC4, 0x3B, 0xC9, 0x0F, 0x73, 0x23, 0x5A + }, + { + 0x45, 0x36, 0x63, 0x43, 0x15, 0xC8, 0x67, 0x28, + 0xF5, 0xAB, 0x74, 0x49, 0xEB, 0x2D, 0x04, 0x02, + 0x0E, 0x9E, 0xAE, 0x8D, 0xD6, 0x79, 0x55, 0x00, + 0xE9, 0xEC, 0x9A, 0x00, 0x66, 0x38, 0x6E, 0x69 + }, + { + 0xFD, 0x5E, 0x49, 0xFE, 0xD4, 0x9D, 0xC4, 0x4B, + 0xDE, 0x89, 0xF4, 0x60, 0xA9, 0x50, 0x19, 0x1E, + 0xBB, 0x06, 0x7C, 0x69, 0x8A, 0x3F, 0x21, 0xEA, + 0x14, 0x30, 0x8C, 0x74, 0x13, 0xB9, 0x16, 0x81 + }, + { + 0x31, 0xF0, 0x1D, 0x03, 0x0B, 0x9B, 0x22, 0xD0, + 0x0A, 0x0F, 0x71, 0xED, 0x2C, 0xEB, 0x5D, 0x2D, + 0xC8, 0x1A, 0xF2, 0xC2, 0x4B, 0xF5, 0x67, 0x0F, + 0xDE, 0x19, 0xA6, 0x85, 0xE8, 0xD1, 0x39, 0x2E + }, + { + 0x5F, 0x84, 0xD9, 0xDE, 0x28, 0x4B, 0x1E, 0x4F, + 0x67, 0x8E, 0x31, 0xAB, 0x6A, 0x76, 0xF5, 0x66, + 0x1B, 0x5A, 0xEA, 0xA7, 0x68, 0x53, 0x93, 0x84, + 0xAA, 0x38, 0xF9, 0xE4, 0x9C, 0xCE, 0x6E, 0x6E + }, + { + 0xB2, 0x07, 0x9E, 0x59, 0x97, 0xA4, 0xEA, 0xD3, + 0xA7, 0x1F, 0xEF, 0xC0, 0x2F, 0x90, 0xA7, 0x48, + 0x3A, 0x10, 0xFD, 0x2E, 0x6F, 0x31, 0xBD, 0xA9, + 0xD2, 0x08, 0x44, 0x85, 0xCC, 0x01, 0x6B, 0xBD + }, + { + 0xE0, 0xF8, 0x4D, 0x7F, 0x52, 0x5B, 0x6F, 0xED, + 0x79, 0x1F, 0x77, 0x28, 0x9A, 0xE5, 0x8F, 0x7D, + 0x50, 0xA2, 0x94, 0x32, 0xD4, 0x2C, 0x25, 0xC1, + 0xE8, 0x39, 0x29, 0xB8, 0x38, 0x89, 0x1D, 0x79 + }, + { + 0x70, 0x46, 0x96, 0x90, 0x95, 0x6D, 0x79, 0x18, + 0xAC, 0xE7, 0xBA, 0x5F, 0x41, 0x30, 0x2D, 0xA1, + 0x38, 0xC9, 0xB5, 0x6E, 0xCD, 0x41, 0x55, 0x44, + 0xFA, 0xCE, 0x8D, 0x99, 0x8C, 0x21, 0xAB, 0xEB + }, + { + 0x45, 0xC9, 0x1A, 0x62, 0x24, 0x9B, 0x39, 0xCD, + 0xA9, 0x4E, 0x50, 0x82, 0x95, 0xBE, 0xC7, 0x66, + 0x71, 0x19, 0x44, 0x77, 0x65, 0xEF, 0x80, 0xEF, + 0xA8, 0x2D, 0x1E, 0x92, 0xD5, 0x70, 0x67, 0xD8 + }, + { + 0x1D, 0x9E, 0x00, 0x73, 0xEE, 0xD0, 0x73, 0x15, + 0x54, 0xC3, 0xBE, 0xAA, 0x47, 0x46, 0x0D, 0x51, + 0x1A, 0xD2, 0x61, 0xDD, 0x4D, 0x4A, 0x3B, 0xED, + 0x9D, 0x8D, 0x20, 0x2F, 0x22, 0xF2, 0x15, 0x89 + }, + { + 0x40, 0x82, 0x62, 0x73, 0x6D, 0x8A, 0xEC, 0x0B, + 0x84, 0x7D, 0xBA, 0x25, 0x02, 0x58, 0x60, 0x8A, + 0x43, 0x45, 0xA6, 0x3A, 0x1E, 0xB1, 0x95, 0xE5, + 0xC7, 0xAE, 0x2E, 0xE8, 0x74, 0xC3, 0x4D, 0xA8 + }, + { + 0x23, 0xD2, 0xB7, 0x04, 0x39, 0x46, 0x99, 0x49, + 0x98, 0x23, 0x90, 0x53, 0x8D, 0x7E, 0x5A, 0xDE, + 0x9F, 0x18, 0xC8, 0xE3, 0xBB, 0xF6, 0x60, 0x5A, + 0xFC, 0xF4, 0x9B, 0x00, 0xC0, 0x61, 0xE8, 0x37 + }, + { + 0x23, 0x2F, 0xB1, 0x87, 0xD2, 0x71, 0xBE, 0xA9, + 0x12, 0xEF, 0xD4, 0x07, 0xFF, 0xE0, 0x80, 0x56, + 0xD6, 0xA4, 0x2E, 0x53, 0x21, 0xEC, 0x79, 0x2D, + 0xF3, 0xD5, 0x84, 0xA9, 0x4F, 0x63, 0x0A, 0xB2 + }, + { + 0x13, 0x8E, 0x19, 0x44, 0xE4, 0xB5, 0x4D, 0xE8, + 0x68, 0x1D, 0x7E, 0x48, 0xC4, 0xF0, 0x81, 0x48, + 0xE4, 0x0A, 0x56, 0x7E, 0x5C, 0xAD, 0x94, 0x6A, + 0x6A, 0xF4, 0xE8, 0xD5, 0xD2, 0x6F, 0x75, 0xC7 + }, + { + 0x80, 0xC1, 0x51, 0x32, 0x5F, 0xBF, 0xC6, 0x78, + 0xB7, 0xBE, 0x4E, 0x40, 0xB3, 0x0F, 0x29, 0xFE, + 0x31, 0xCD, 0xBE, 0x1C, 0x84, 0x12, 0x6E, 0x00, + 0x6D, 0xF3, 0xC1, 0x85, 0x24, 0xBD, 0x2D, 0x6C + }, + { + 0xA6, 0x42, 0x26, 0x73, 0x01, 0x66, 0x9D, 0xF2, + 0x61, 0xB8, 0x39, 0xF8, 0x73, 0x65, 0x76, 0x29, + 0x05, 0xFF, 0x32, 0x0A, 0x0A, 0x2F, 0xC4, 0xBD, + 0xC4, 0x8E, 0x5A, 0x8E, 0x15, 0xD1, 0x32, 0x33 + }, + { + 0x0F, 0x8B, 0x10, 0x99, 0x38, 0x60, 0x93, 0x7A, + 0x74, 0xCC, 0x2D, 0xE4, 0x0A, 0x27, 0x31, 0xDD, + 0x99, 0x54, 0xB6, 0x54, 0xBB, 0x94, 0xC3, 0x4E, + 0x87, 0x66, 0x52, 0xE9, 0x8D, 0x4B, 0xBD, 0x16 + }, + { + 0xE6, 0x34, 0xA5, 0x85, 0x12, 0x49, 0x32, 0x73, + 0x26, 0x0F, 0x10, 0xD4, 0x49, 0x53, 0xCD, 0x99, + 0x8E, 0x34, 0xCB, 0x82, 0x81, 0xC4, 0x1B, 0xF4, + 0x2E, 0x0A, 0xE2, 0xF2, 0x5C, 0xBD, 0x1F, 0x75 + }, + { + 0xBD, 0xE6, 0xAF, 0x9B, 0xAF, 0x3C, 0x07, 0xE9, + 0x54, 0x23, 0xCA, 0xB5, 0x04, 0xDE, 0xE7, 0x0E, + 0xDC, 0xC3, 0x31, 0x8B, 0x22, 0xDD, 0x1E, 0xB6, + 0xFD, 0x85, 0xBE, 0x44, 0x7A, 0xC9, 0xF2, 0x09 + }, + { + 0x91, 0x4B, 0x37, 0xAB, 0x5B, 0x8C, 0xFD, 0xE6, + 0xA4, 0x80, 0x46, 0x6A, 0x0D, 0x82, 0x43, 0x2C, + 0x7D, 0x76, 0x32, 0x8E, 0x9A, 0x88, 0xEF, 0x5B, + 0x4F, 0x52, 0x42, 0x9F, 0x7A, 0x3F, 0xFC, 0x7D + }, + { + 0x55, 0xBE, 0x66, 0xE9, 0xA5, 0xAA, 0x67, 0x1A, + 0x23, 0x88, 0x2E, 0xF3, 0xE7, 0xD9, 0xD3, 0x6E, + 0xA9, 0x54, 0x87, 0xDC, 0x71, 0xB7, 0x25, 0xA5, + 0xAD, 0x4B, 0x79, 0x8A, 0x87, 0x91, 0x43, 0xD0 + }, + { + 0x3F, 0xD0, 0x45, 0x89, 0x4B, 0x83, 0x6E, 0x44, + 0xE9, 0xCA, 0x75, 0xFB, 0xE3, 0xEA, 0xDC, 0x48, + 0x6C, 0xBB, 0xD0, 0xD8, 0xCE, 0xE1, 0xB3, 0xCF, + 0x14, 0xF7, 0x6E, 0x7F, 0x1E, 0x77, 0xAE, 0xF3 + }, + { + 0xCE, 0x60, 0x34, 0x3D, 0xC4, 0x87, 0x4B, 0x66, + 0x04, 0xE1, 0xFB, 0x23, 0x1E, 0x37, 0xEC, 0x1E, + 0xEC, 0x3F, 0x06, 0x56, 0x6E, 0x42, 0x8A, 0xE7, + 0x64, 0xEF, 0xFF, 0xA2, 0x30, 0xAD, 0xD4, 0x85 + }, + { + 0xE3, 0x8C, 0x9D, 0xF0, 0x24, 0xDE, 0x21, 0x53, + 0xD2, 0x26, 0x73, 0x8A, 0x0E, 0x5B, 0xA9, 0xB8, + 0xC6, 0x78, 0x4D, 0xAC, 0xA6, 0x5C, 0x22, 0xA7, + 0x62, 0x8E, 0xB5, 0x8E, 0xA0, 0xD4, 0x95, 0xA7 + }, + { + 0x8D, 0xFE, 0xC0, 0xD4, 0xF3, 0x65, 0x8A, 0x20, + 0xA0, 0xBA, 0xD6, 0x6F, 0x21, 0x60, 0x83, 0x2B, + 0x16, 0x4E, 0x70, 0x0A, 0x21, 0xEC, 0x5A, 0x01, + 0x65, 0xC3, 0x67, 0x72, 0xB2, 0x08, 0x61, 0x11 + }, + { + 0x44, 0x01, 0xB5, 0x0E, 0x09, 0x86, 0x5F, 0x42, + 0x38, 0x24, 0x3B, 0x82, 0x25, 0xCA, 0x40, 0xA0, + 0x8D, 0xBB, 0x46, 0x85, 0xF5, 0xF8, 0x62, 0xFB, + 0xDD, 0x72, 0x98, 0x04, 0x31, 0xA8, 0x5D, 0x3F + }, + { + 0x86, 0x68, 0x94, 0x27, 0x88, 0xC4, 0xCE, 0x8A, + 0x33, 0x19, 0x0F, 0xFC, 0xFA, 0xD1, 0xC6, 0x78, + 0xC4, 0xFA, 0x41, 0xE9, 0x94, 0x17, 0x09, 0x4E, + 0x24, 0x0F, 0x4A, 0x43, 0xF3, 0x87, 0xA3, 0xB6 + }, + { + 0xA7, 0x28, 0x8D, 0x5E, 0x09, 0x80, 0x9B, 0x69, + 0x69, 0x84, 0xEC, 0xD5, 0x32, 0x6C, 0xDD, 0x84, + 0xFB, 0xE3, 0x5F, 0xCF, 0x67, 0x23, 0x5D, 0x81, + 0x1C, 0x82, 0x00, 0x25, 0x36, 0xA3, 0xC5, 0xE1 + }, + { + 0x8E, 0x92, 0x5C, 0x3C, 0x14, 0x6B, 0xAC, 0xF3, + 0x35, 0x1E, 0xC5, 0x32, 0x41, 0xAC, 0xE5, 0xF7, + 0x3E, 0x8F, 0xC9, 0xBD, 0x8C, 0x61, 0xCA, 0xD9, + 0x7F, 0xD7, 0x72, 0xB0, 0x7E, 0x1B, 0x83, 0x73 + }, + { + 0xC7, 0xEB, 0x9E, 0x6D, 0xED, 0x2F, 0x99, 0x3D, + 0x48, 0xB0, 0x17, 0x0D, 0xA2, 0x7C, 0x5B, 0x75, + 0x3B, 0x12, 0x17, 0x6B, 0xE1, 0x26, 0xC7, 0xBA, + 0x2D, 0x6A, 0xF8, 0x5F, 0x85, 0x93, 0xB7, 0x52 + }, + { + 0xCA, 0x27, 0xF1, 0x6F, 0x94, 0xE4, 0xEC, 0x0E, + 0x62, 0x8E, 0x7F, 0x8A, 0xEF, 0xC6, 0x65, 0x7B, + 0xED, 0xC9, 0x37, 0x42, 0x96, 0x59, 0x40, 0xAE, + 0x78, 0x6A, 0x73, 0xB5, 0xFD, 0x59, 0x3B, 0x97 + }, + { + 0x8C, 0x21, 0xE6, 0x56, 0x8B, 0xC6, 0xDC, 0x00, + 0xE3, 0xD6, 0xEB, 0xC0, 0x9E, 0xA9, 0xC2, 0xCE, + 0x00, 0x6C, 0xD3, 0x11, 0xD3, 0xB3, 0xE9, 0xCC, + 0x9D, 0x8D, 0xDB, 0xFB, 0x3C, 0x5A, 0x77, 0x76 + }, + { + 0x52, 0x56, 0x66, 0x96, 0x8B, 0x3B, 0x7D, 0x00, + 0x7B, 0xB9, 0x26, 0xB6, 0xEF, 0xDC, 0x7E, 0x21, + 0x2A, 0x31, 0x15, 0x4C, 0x9A, 0xE1, 0x8D, 0x43, + 0xEE, 0x0E, 0xB7, 0xE6, 0xB1, 0xA9, 0x38, 0xD3 + }, + { + 0xE0, 0x9A, 0x4F, 0xA5, 0xC2, 0x8B, 0xDC, 0xD7, + 0xC8, 0x39, 0x84, 0x0E, 0x0A, 0x38, 0x3E, 0x4F, + 0x7A, 0x10, 0x2D, 0x0B, 0x1B, 0xC8, 0x49, 0xC9, + 0x49, 0x62, 0x7C, 0x41, 0x00, 0xC1, 0x7D, 0xD3 + }, + { + 0xC1, 0x9F, 0x3E, 0x29, 0x5D, 0xB2, 0xFC, 0x0E, + 0x74, 0x81, 0xC4, 0xF1, 0x6A, 0xF0, 0x11, 0x55, + 0xDD, 0xB0, 0xD7, 0xD1, 0x38, 0x3D, 0x4A, 0x1F, + 0xF1, 0x69, 0x9D, 0xB7, 0x11, 0x77, 0x34, 0x0C + }, + { + 0x76, 0x9E, 0x67, 0x8C, 0x0A, 0x09, 0x09, 0xA2, + 0x02, 0x1C, 0x4D, 0xC2, 0x6B, 0x1A, 0x3C, 0x9B, + 0xC5, 0x57, 0xAD, 0xB2, 0x1A, 0x50, 0x83, 0x4C, + 0xDC, 0x5C, 0x92, 0x93, 0xF7, 0x53, 0x65, 0xF8 + }, + { + 0xB6, 0x48, 0x74, 0xAD, 0xAB, 0x6B, 0xCB, 0x85, + 0xB9, 0x4B, 0xD9, 0xA6, 0xC5, 0x65, 0xD0, 0xD2, + 0xBC, 0x35, 0x44, 0x5D, 0x75, 0x28, 0xBC, 0x85, + 0xB4, 0x1F, 0xDC, 0x79, 0xDC, 0x76, 0xE3, 0x4F + }, + { + 0xFA, 0xF2, 0x50, 0xDE, 0x15, 0x82, 0x0F, 0x7F, + 0xC6, 0x10, 0xDD, 0x53, 0xEE, 0xAE, 0x44, 0x60, + 0x1C, 0x3E, 0xFF, 0xA3, 0xAC, 0xCD, 0x08, 0x8E, + 0xB6, 0x69, 0x05, 0xBB, 0x26, 0x53, 0xBE, 0x8C + }, + { + 0x1E, 0x20, 0x38, 0x73, 0x9B, 0x2C, 0x01, 0x8B, + 0x0E, 0x9E, 0x0E, 0x1E, 0x52, 0x2F, 0xD9, 0x65, + 0x12, 0x87, 0xEE, 0x6E, 0x36, 0x65, 0x91, 0x9B, + 0x24, 0xC2, 0x12, 0x4F, 0x0C, 0x1A, 0x3F, 0x3A + }, + { + 0x5F, 0xEC, 0x3A, 0xA0, 0x08, 0x61, 0xDE, 0x1A, + 0xC5, 0xDA, 0xB3, 0xC1, 0x37, 0x06, 0x5D, 0x1E, + 0x01, 0xBB, 0x03, 0xF6, 0x9D, 0xCC, 0x7D, 0x1C, + 0xF7, 0xCA, 0x4F, 0x43, 0x56, 0xAE, 0xC9, 0xA3 + }, + { + 0x44, 0x51, 0xFE, 0x6B, 0xBE, 0xF3, 0x93, 0x43, + 0x91, 0x92, 0x44, 0xC5, 0x1D, 0xAE, 0x1E, 0xA9, + 0xA9, 0x54, 0xCF, 0x2C, 0x09, 0x66, 0xAB, 0x04, + 0x5B, 0x15, 0x52, 0x1E, 0xCF, 0x35, 0x00, 0x81 + }, + { + 0x8C, 0x62, 0x2F, 0xA2, 0x16, 0x0E, 0x8E, 0x99, + 0x18, 0x13, 0xF1, 0x80, 0xBF, 0xEC, 0x0B, 0x43, + 0x1C, 0x6D, 0xBF, 0xA2, 0x95, 0x6D, 0x91, 0x75, + 0x81, 0x6A, 0x23, 0xC3, 0x82, 0xC4, 0xF2, 0x00 + }, + { + 0x81, 0x7D, 0x5C, 0x8F, 0x92, 0xE7, 0xB5, 0xCA, + 0x57, 0xF5, 0xE1, 0x63, 0x90, 0x16, 0xAD, 0x57, + 0x60, 0xE4, 0x46, 0xD6, 0xE9, 0xCA, 0xA7, 0x49, + 0x84, 0x14, 0xAC, 0xE8, 0x22, 0x80, 0xB5, 0xCD + }, + { + 0xA6, 0xA1, 0xAD, 0x58, 0xCE, 0xE5, 0x4E, 0x69, + 0xCB, 0xBC, 0xAA, 0x87, 0xDF, 0x07, 0xA6, 0x70, + 0x7E, 0xB2, 0x24, 0x73, 0x9C, 0x21, 0x76, 0x13, + 0x46, 0x0A, 0xB4, 0x54, 0xB4, 0x59, 0xCA, 0x9C + }, + { + 0x63, 0xB8, 0x47, 0x27, 0x52, 0x26, 0x60, 0x5B, + 0xE6, 0x76, 0x81, 0x25, 0x8F, 0x7D, 0x00, 0xBB, + 0xB3, 0x07, 0xC6, 0x6F, 0x19, 0x59, 0xBF, 0x2E, + 0x46, 0x7A, 0x41, 0xAE, 0xE7, 0x14, 0xE5, 0x5C + }, + { + 0xFE, 0x52, 0xEB, 0xE5, 0xCF, 0xCF, 0xE6, 0xA2, + 0x29, 0x7B, 0x53, 0x9F, 0xA3, 0xDA, 0xDB, 0xD6, + 0xEB, 0xD2, 0x01, 0xAA, 0x2C, 0xA1, 0x35, 0x63, + 0xE3, 0xD7, 0xF1, 0x4D, 0x15, 0xAB, 0xFF, 0x63 + }, + { + 0xB7, 0xBE, 0xF9, 0xFA, 0x5A, 0x3D, 0x10, 0x42, + 0x62, 0x46, 0xB5, 0xF6, 0x58, 0xC0, 0x8F, 0xDF, + 0x80, 0x66, 0xEA, 0xA3, 0xE5, 0x5A, 0x2F, 0x7D, + 0xA1, 0x59, 0x1E, 0x05, 0xC8, 0x7D, 0xF8, 0xC7 + }, + { + 0xDE, 0xD1, 0xD6, 0xCA, 0xA9, 0xF8, 0xF3, 0xBD, + 0xA9, 0x2C, 0xEA, 0x7F, 0x65, 0x49, 0xB1, 0xFB, + 0x86, 0xA2, 0x21, 0x14, 0x78, 0xC4, 0xEC, 0x28, + 0x9B, 0x83, 0x7E, 0xFC, 0x2B, 0x5C, 0x27, 0xD7 + }, + { + 0x9F, 0x30, 0x00, 0x8A, 0x2E, 0xB0, 0x50, 0xF1, + 0x8E, 0x56, 0xA7, 0x6B, 0xE9, 0x20, 0x91, 0xB2, + 0xFD, 0xC1, 0x64, 0xD5, 0x6E, 0x32, 0xC8, 0x7D, + 0xD6, 0x4C, 0x9E, 0x3A, 0x61, 0x10, 0x41, 0xB1 + }, + { + 0x01, 0x0B, 0x6A, 0x3B, 0x11, 0x86, 0x00, 0x88, + 0xF0, 0xAB, 0xC8, 0x0A, 0x89, 0x72, 0xCB, 0xBC, + 0x32, 0x9D, 0x52, 0x75, 0x34, 0x29, 0x50, 0xEB, + 0x9A, 0x04, 0x5A, 0xFD, 0xC8, 0xBB, 0xED, 0x24 + }, + { + 0x0C, 0xD2, 0x10, 0xAA, 0xC1, 0x1F, 0x1C, 0x1C, + 0xED, 0x49, 0x7F, 0x67, 0x3E, 0x53, 0xDB, 0x68, + 0xC3, 0xEC, 0x36, 0x07, 0xF0, 0xC5, 0x78, 0x7D, + 0xDC, 0x60, 0xA3, 0x55, 0xDF, 0xE5, 0x6C, 0x25 + }, + { + 0x0E, 0x56, 0xFD, 0x01, 0xDA, 0x3B, 0x4F, 0x8B, + 0xE2, 0xC9, 0x90, 0x55, 0x2A, 0xAC, 0x8D, 0x1E, + 0x8D, 0xA2, 0x09, 0xBC, 0xF4, 0xAA, 0xD4, 0xFF, + 0xB5, 0x42, 0x7F, 0xD6, 0x31, 0x72, 0x46, 0x3E + }, + { + 0xD6, 0xD5, 0xCD, 0xB1, 0x14, 0x40, 0xE3, 0x4A, + 0xCA, 0x3A, 0x2F, 0xCF, 0x30, 0xF5, 0x9E, 0x08, + 0xB1, 0x1A, 0x2A, 0x3D, 0xE5, 0x39, 0xE3, 0xE6, + 0x51, 0x3E, 0xD7, 0x8A, 0x4F, 0xEE, 0x51, 0x3B + }, + { + 0xAA, 0x35, 0xAC, 0x90, 0x68, 0x06, 0x70, 0xC7, + 0x32, 0xED, 0x1E, 0xF3, 0x7E, 0x8C, 0xBA, 0xAE, + 0x49, 0xA4, 0xD8, 0x8E, 0xCF, 0x4D, 0xF2, 0xB6, + 0x89, 0xA0, 0xF1, 0x01, 0xB7, 0x56, 0xAE, 0x47 + }, + { + 0x27, 0x8E, 0x56, 0x12, 0x88, 0x72, 0x26, 0x30, + 0xE2, 0x6A, 0x5F, 0xC9, 0x54, 0xBF, 0x2D, 0xCD, + 0x6A, 0x65, 0x81, 0x67, 0x39, 0xAB, 0xEE, 0x7B, + 0xE1, 0x43, 0x07, 0xA9, 0x61, 0x74, 0xE5, 0xB0 + }, + { + 0xAB, 0x4B, 0x2C, 0xA1, 0xA2, 0xB3, 0x49, 0x98, + 0x15, 0x24, 0xB6, 0x15, 0x54, 0x62, 0xF0, 0xFF, + 0x10, 0x60, 0xBF, 0x9B, 0xFA, 0x07, 0xFB, 0x9E, + 0xC6, 0x9C, 0xA4, 0x71, 0x64, 0x5B, 0x6A, 0x18 + }, + { + 0x18, 0xA9, 0xBB, 0xEC, 0x3C, 0x8E, 0x1F, 0x8E, + 0xE9, 0x57, 0x12, 0x97, 0xA9, 0x34, 0x36, 0xDE, + 0x42, 0x7C, 0xD2, 0x70, 0xEC, 0x69, 0xDF, 0xE8, + 0x88, 0xDB, 0x7D, 0xBF, 0x10, 0xB6, 0x49, 0x93 + }, + { + 0xBA, 0xFC, 0x7E, 0x43, 0xD2, 0x65, 0xA1, 0x73, + 0x02, 0x1A, 0x9D, 0x9E, 0x58, 0x3D, 0x60, 0xED, + 0x42, 0xA8, 0x03, 0xFA, 0xCD, 0x6B, 0x83, 0x60, + 0xDE, 0x1F, 0x91, 0x68, 0x35, 0x38, 0x9B, 0xF0 + }, + { + 0xA5, 0xB6, 0x7B, 0xE9, 0x50, 0xFB, 0xC2, 0xF0, + 0xDD, 0x32, 0x3A, 0x79, 0xA1, 0x9E, 0x3E, 0xD1, + 0xF4, 0xAE, 0x4B, 0xA7, 0x89, 0x4F, 0x93, 0x0E, + 0xA5, 0xEF, 0x73, 0x4D, 0xE7, 0xDB, 0x83, 0xAE + }, + { + 0xBF, 0x1E, 0x65, 0xF3, 0xCD, 0x84, 0x98, 0x88, + 0x4D, 0x9D, 0x5C, 0x19, 0xEB, 0xF7, 0xB9, 0x16, + 0x06, 0x76, 0x37, 0x60, 0x4E, 0x26, 0xDB, 0xE2, + 0xB7, 0x28, 0x8E, 0xCB, 0x11, 0x42, 0x60, 0x68 + }, + { + 0xC3, 0x34, 0x2C, 0xF9, 0xCB, 0xBF, 0x29, 0xD4, + 0x06, 0xD7, 0x89, 0x5D, 0xD4, 0xD9, 0x54, 0x8D, + 0x4A, 0xC7, 0x8B, 0x4D, 0x00, 0xE9, 0xB6, 0x3E, + 0x20, 0x3E, 0x5E, 0x19, 0xE9, 0x97, 0x46, 0x20 + }, + { + 0x1C, 0x0B, 0xE6, 0x02, 0x77, 0x43, 0x4B, 0x0E, + 0x00, 0x4B, 0x7B, 0x38, 0x8A, 0x37, 0x55, 0x9F, + 0x84, 0xB3, 0x0C, 0x6C, 0xF8, 0x60, 0x0F, 0x52, + 0x8B, 0xFC, 0xD3, 0x3C, 0xAF, 0x52, 0xCB, 0x1E + }, + { + 0x73, 0x95, 0x45, 0x30, 0xD0, 0x3F, 0x10, 0xBE, + 0xF5, 0x2A, 0xD5, 0xBC, 0x7F, 0xB4, 0xC0, 0x76, + 0xF8, 0x3F, 0x63, 0x31, 0xC8, 0xBD, 0x1E, 0xEE, + 0xC3, 0x88, 0x7F, 0x4A, 0xA2, 0x06, 0x92, 0x40 + }, + { + 0x69, 0xC1, 0x1E, 0xE0, 0x49, 0x44, 0xDE, 0xA9, + 0x85, 0xAC, 0x9F, 0x13, 0x96, 0x0E, 0x73, 0x98, + 0x0E, 0x1B, 0xB0, 0xE3, 0x09, 0xF4, 0x38, 0x4A, + 0x16, 0x76, 0xF8, 0xEF, 0xAB, 0x38, 0x42, 0x88 + }, + { + 0x36, 0xFB, 0x8F, 0xDE, 0x0E, 0xC2, 0x8C, 0xE8, + 0x53, 0xFB, 0x71, 0x75, 0xC1, 0xB7, 0x9D, 0xA3, + 0xB5, 0xE8, 0xC3, 0x91, 0x86, 0xE7, 0x8A, 0xAE, + 0xCE, 0x54, 0x64, 0xDB, 0xD9, 0xFE, 0x2A, 0xA2 + }, + { + 0x6B, 0xB2, 0xA0, 0x9D, 0xFC, 0xAF, 0x96, 0x96, + 0x2D, 0xE0, 0x0C, 0x8A, 0x08, 0x2D, 0x6D, 0xF9, + 0x32, 0x2B, 0x49, 0x66, 0xAE, 0x8D, 0x2E, 0xCF, + 0x73, 0x24, 0x11, 0xA7, 0x6A, 0x1A, 0x0E, 0xE6 + }, + { + 0x74, 0x12, 0xE7, 0xDD, 0x1B, 0xF1, 0xAA, 0x93, + 0x97, 0x41, 0x1B, 0xBA, 0x4D, 0x3E, 0x02, 0x76, + 0xD2, 0xE7, 0xA1, 0xA2, 0x9A, 0x24, 0x77, 0x15, + 0x7A, 0xD6, 0x03, 0x60, 0xD3, 0x3D, 0x4E, 0x76 + }, + { + 0xDD, 0xDE, 0xAF, 0xCF, 0xC7, 0x23, 0x21, 0xC8, + 0x49, 0xFB, 0x25, 0x94, 0x7A, 0xB4, 0x2C, 0x1A, + 0xF2, 0xA5, 0xE4, 0x3F, 0xEF, 0x68, 0x1B, 0xE4, + 0x2C, 0x7E, 0xAF, 0x36, 0x60, 0x08, 0x0A, 0xD3 + }, + { + 0x9D, 0xEF, 0xEB, 0xAD, 0xBD, 0xCB, 0x0A, 0x0E, + 0x7F, 0xF9, 0x92, 0xF9, 0x47, 0xCE, 0xD3, 0xD0, + 0xA4, 0xC8, 0x99, 0xE6, 0x4F, 0xE7, 0x73, 0x60, + 0xE8, 0x1E, 0x1F, 0x0E, 0x97, 0xF8, 0xC1, 0xA2 + }, + { + 0x84, 0x4C, 0x59, 0xFB, 0xE6, 0x47, 0x6F, 0xD1, + 0x89, 0x23, 0x99, 0x54, 0xF1, 0x7E, 0x36, 0xE1, + 0xF6, 0x9E, 0x24, 0xAA, 0xED, 0x5D, 0x5C, 0x8B, + 0x84, 0x05, 0xEF, 0x2A, 0x83, 0x0C, 0xC2, 0xA0 + }, + { + 0xFF, 0x3F, 0xAF, 0xB6, 0x77, 0x86, 0xE0, 0x1A, + 0x0C, 0x38, 0xEA, 0xDF, 0x99, 0xC4, 0xCA, 0xE8, + 0x02, 0x9D, 0xA8, 0xCF, 0x29, 0x87, 0x5F, 0xC4, + 0x19, 0xBF, 0x68, 0x00, 0x09, 0xB3, 0xBD, 0xB3 + }, + { + 0xCA, 0x67, 0x60, 0xF3, 0x45, 0x67, 0x8F, 0x30, + 0xA2, 0x8D, 0x62, 0x82, 0x94, 0x27, 0x2A, 0x19, + 0xE3, 0x07, 0x2E, 0xBC, 0x61, 0xB1, 0x9F, 0xF1, + 0x3B, 0x31, 0x89, 0x73, 0xE9, 0x7C, 0x27, 0x38 + }, + { + 0xC0, 0x8E, 0x1A, 0x90, 0x47, 0xC5, 0x05, 0x26, + 0x4A, 0x16, 0x44, 0x7C, 0x9E, 0xD9, 0x81, 0xA7, + 0x19, 0xD3, 0x81, 0xF2, 0x8E, 0x60, 0x5F, 0xD7, + 0xCA, 0xA9, 0xE8, 0xBD, 0xBB, 0x42, 0x99, 0x6A + }, + { + 0xF1, 0x73, 0xBA, 0x9D, 0x45, 0x84, 0xCD, 0x12, + 0x60, 0x50, 0xC6, 0x9F, 0xC2, 0x19, 0xA9, 0x19, + 0x0A, 0x0B, 0xF0, 0xAE, 0xCE, 0xCB, 0xE6, 0x11, + 0xBE, 0xED, 0x19, 0x3D, 0xA6, 0xCA, 0x4D, 0xE7 + }, + { + 0xB1, 0x84, 0x87, 0x65, 0x20, 0xDE, 0xD8, 0xBD, + 0x7D, 0xE2, 0x5E, 0xAE, 0xFB, 0xD3, 0xE0, 0x36, + 0x88, 0xC3, 0xBE, 0x39, 0xC1, 0x9F, 0xB7, 0x3E, + 0x1F, 0x0E, 0xCC, 0xAC, 0x7C, 0xC0, 0xF0, 0x14 + }, + { + 0x90, 0x25, 0xDB, 0x07, 0x58, 0xBD, 0xFB, 0x48, + 0xF0, 0x66, 0x7E, 0xBD, 0x7E, 0x12, 0x02, 0x46, + 0x59, 0x8F, 0xED, 0x01, 0xC2, 0x58, 0x76, 0x4F, + 0xA0, 0xFA, 0xE3, 0x34, 0xA2, 0xA0, 0x0A, 0x97 + }, + { + 0xE8, 0x3D, 0x80, 0x86, 0xFA, 0xBC, 0x46, 0x0D, + 0x5E, 0xFC, 0x45, 0x9F, 0x95, 0xA2, 0x68, 0xF5, + 0xDC, 0x4A, 0xC2, 0x84, 0x09, 0x3C, 0x24, 0x7C, + 0xA6, 0xEC, 0x84, 0x1A, 0xD6, 0x18, 0x3F, 0xE1 + }, + { + 0xCC, 0x9D, 0xF4, 0x1D, 0x35, 0xAA, 0x75, 0x92, + 0x8C, 0x18, 0x5F, 0x73, 0x93, 0x66, 0x61, 0x10, + 0xB8, 0x0F, 0x09, 0x86, 0xA2, 0x21, 0xC3, 0x70, + 0xF4, 0x5C, 0x2E, 0xB9, 0x01, 0x6C, 0x9A, 0x3B + }, + { + 0x92, 0xF9, 0xA5, 0x94, 0x95, 0x45, 0x90, 0xFA, + 0x81, 0x98, 0x17, 0xE5, 0xD1, 0xC2, 0x8A, 0xAB, + 0x2B, 0x1C, 0xC5, 0x04, 0xD8, 0x6D, 0xBA, 0x44, + 0x36, 0x76, 0xBD, 0xF8, 0x66, 0x79, 0x68, 0x11 + }, + { + 0x72, 0x95, 0x62, 0xA1, 0xE0, 0x7B, 0x0E, 0x26, + 0x05, 0x49, 0x48, 0x09, 0xBD, 0x48, 0x0F, 0x15, + 0x37, 0xCE, 0xA1, 0x0D, 0xCA, 0xD4, 0x3E, 0xF9, + 0xF6, 0x8C, 0x66, 0xE8, 0x25, 0xDC, 0x46, 0xB1 + }, + { + 0x26, 0xF1, 0x60, 0xAB, 0x96, 0xF5, 0x58, 0x20, + 0x45, 0x14, 0x6E, 0xAF, 0xF2, 0xE2, 0xA8, 0xD4, + 0xDA, 0xB2, 0x98, 0xB4, 0xC5, 0x7E, 0x11, 0x7C, + 0xDF, 0xC5, 0xD0, 0x25, 0xC9, 0x2A, 0x22, 0x68 + }, + { + 0x87, 0xEB, 0xE7, 0x21, 0x38, 0x38, 0x73, 0xD2, + 0x47, 0xF8, 0x61, 0x82, 0xE3, 0xF5, 0x99, 0xA7, + 0x63, 0x4F, 0xCA, 0xEC, 0x5E, 0x07, 0xB1, 0xE8, + 0x3E, 0xBB, 0x79, 0x62, 0x5B, 0xA3, 0x54, 0xE6 + }, + { + 0xE0, 0x8D, 0x38, 0x9F, 0x75, 0x69, 0x4A, 0xDC, + 0x99, 0x6C, 0x22, 0xF5, 0x5D, 0x4F, 0x85, 0x9F, + 0xFD, 0x0C, 0x13, 0x19, 0xFF, 0x9C, 0xED, 0xF7, + 0x8C, 0x31, 0xBE, 0x84, 0xB6, 0xF2, 0x1A, 0xBC + }, + { + 0x13, 0x63, 0xE2, 0x29, 0x13, 0xC6, 0xE1, 0x8E, + 0x7A, 0xA6, 0x5B, 0x83, 0xE7, 0x51, 0xC8, 0xA2, + 0xC6, 0x1B, 0x0F, 0x30, 0x71, 0x55, 0x86, 0x5A, + 0x57, 0xDB, 0xA5, 0x69, 0xA9, 0x9C, 0x7B, 0x0E + }, + { + 0x88, 0x78, 0x08, 0x8E, 0xB2, 0xD1, 0xF6, 0xD0, + 0xBB, 0x48, 0x1B, 0x4B, 0xB1, 0x87, 0xDA, 0x04, + 0xBC, 0xD8, 0xC2, 0xC6, 0x39, 0xF0, 0x05, 0xB0, + 0x80, 0x54, 0xCC, 0x41, 0x75, 0x39, 0x05, 0xFB + }, + { + 0x04, 0x18, 0xD6, 0x0D, 0x05, 0xB4, 0xE1, 0x24, + 0x64, 0x6E, 0xE5, 0x0E, 0x77, 0x49, 0xA1, 0xD2, + 0x09, 0x45, 0x7B, 0xC5, 0x43, 0xE3, 0xCC, 0x11, + 0x30, 0x27, 0x4A, 0xEA, 0x0F, 0x7B, 0xF3, 0xC1 + }, + { + 0x7A, 0x39, 0x7E, 0x50, 0x3F, 0x29, 0x3B, 0xC4, + 0x2D, 0x5F, 0x7E, 0xF5, 0xEC, 0x37, 0x87, 0x24, + 0x60, 0xA4, 0xF5, 0xB5, 0xCC, 0xDE, 0x77, 0xFB, + 0x4D, 0x47, 0xAC, 0x06, 0x81, 0xE5, 0xA0, 0x49 + }, + { + 0x5C, 0x0D, 0x29, 0x83, 0xE7, 0x2A, 0x6D, 0xD4, + 0xE6, 0x52, 0xD7, 0x23, 0xC1, 0xDF, 0xC1, 0x2B, + 0x41, 0x4C, 0x87, 0x3D, 0x4A, 0xB4, 0xA0, 0xA1, + 0x50, 0x40, 0x8E, 0xB3, 0x43, 0x47, 0xE9, 0x95 + }, + { + 0x56, 0x23, 0x36, 0x54, 0x53, 0xC0, 0x49, 0x89, + 0xC7, 0xCF, 0x33, 0x63, 0x5E, 0x0F, 0xC4, 0xCD, + 0xDD, 0x68, 0x6F, 0xC9, 0x5A, 0x33, 0xDF, 0xED, + 0xCF, 0x33, 0x35, 0x79, 0x4C, 0x7D, 0xC3, 0x44 + }, + { + 0x11, 0xF6, 0xDA, 0xD1, 0x88, 0x02, 0x8F, 0xDF, + 0x13, 0x78, 0xA2, 0x56, 0xE4, 0x57, 0x0E, 0x90, + 0x63, 0x10, 0x7B, 0x8F, 0x79, 0xDC, 0x66, 0x3F, + 0xA5, 0x55, 0x6F, 0x56, 0xFD, 0x44, 0xA0, 0xF0 + }, + { + 0x0E, 0xD8, 0x16, 0x17, 0x97, 0xEC, 0xEE, 0x88, + 0x1E, 0x7D, 0x0E, 0x3F, 0x4C, 0x5F, 0xB8, 0x39, + 0xC8, 0x4E, 0xB7, 0xA9, 0x24, 0x26, 0x57, 0xCC, + 0x48, 0x30, 0x68, 0x07, 0xB3, 0x2B, 0xEF, 0xDE + }, + { + 0x73, 0x66, 0x67, 0xC9, 0x36, 0x4C, 0xE1, 0x2D, + 0xB8, 0xF6, 0xB1, 0x43, 0xC6, 0xC1, 0x78, 0xCD, + 0xEF, 0x1E, 0x14, 0x45, 0xBC, 0x5A, 0x2F, 0x26, + 0x34, 0xF0, 0x8E, 0x99, 0x32, 0x27, 0x3C, 0xAA + }, + { + 0xE1, 0x5F, 0x36, 0x8B, 0x44, 0x06, 0xC1, 0xF6, + 0x55, 0x57, 0xC8, 0x35, 0x5C, 0xBE, 0x69, 0x4B, + 0x63, 0x3E, 0x26, 0xF1, 0x55, 0xF5, 0x2B, 0x7D, + 0xA9, 0x4C, 0xFB, 0x23, 0xFD, 0x4A, 0x5D, 0x96 + }, + { + 0x43, 0x7A, 0xB2, 0xD7, 0x4F, 0x50, 0xCA, 0x86, + 0xCC, 0x3D, 0xE9, 0xBE, 0x70, 0xE4, 0x55, 0x48, + 0x25, 0xE3, 0x3D, 0x82, 0x4B, 0x3A, 0x49, 0x23, + 0x62, 0xE2, 0xE9, 0xD6, 0x11, 0xBC, 0x57, 0x9D + }, + { + 0x2B, 0x91, 0x58, 0xC7, 0x22, 0x89, 0x8E, 0x52, + 0x6D, 0x2C, 0xDD, 0x3F, 0xC0, 0x88, 0xE9, 0xFF, + 0xA7, 0x9A, 0x9B, 0x73, 0xB7, 0xD2, 0xD2, 0x4B, + 0xC4, 0x78, 0xE2, 0x1C, 0xDB, 0x3B, 0x67, 0x63 + }, + { + 0x0C, 0x8A, 0x36, 0x59, 0x7D, 0x74, 0x61, 0xC6, + 0x3A, 0x94, 0x73, 0x28, 0x21, 0xC9, 0x41, 0x85, + 0x6C, 0x66, 0x83, 0x76, 0x60, 0x6C, 0x86, 0xA5, + 0x2D, 0xE0, 0xEE, 0x41, 0x04, 0xC6, 0x15, 0xDB + }, +}; + + + + +static const uint8_t blake2bp_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0xB5, 0xEF, 0x81, 0x1A, 0x80, 0x38, 0xF7, 0x0B, + 0x62, 0x8F, 0xA8, 0xB2, 0x94, 0xDA, 0xAE, 0x74, + 0x92, 0xB1, 0xEB, 0xE3, 0x43, 0xA8, 0x0E, 0xAA, + 0xBB, 0xF1, 0xF6, 0xAE, 0x66, 0x4D, 0xD6, 0x7B, + 0x9D, 0x90, 0xB0, 0x12, 0x07, 0x91, 0xEA, 0xB8, + 0x1D, 0xC9, 0x69, 0x85, 0xF2, 0x88, 0x49, 0xF6, + 0xA3, 0x05, 0x18, 0x6A, 0x85, 0x50, 0x1B, 0x40, + 0x51, 0x14, 0xBF, 0xA6, 0x78, 0xDF, 0x93, 0x80 + }, + { + 0xA1, 0x39, 0x28, 0x0E, 0x72, 0x75, 0x7B, 0x72, + 0x3E, 0x64, 0x73, 0xD5, 0xBE, 0x59, 0xF3, 0x6E, + 0x9D, 0x50, 0xFC, 0x5C, 0xD7, 0xD4, 0x58, 0x5C, + 0xBC, 0x09, 0x80, 0x48, 0x95, 0xA3, 0x6C, 0x52, + 0x12, 0x42, 0xFB, 0x27, 0x89, 0xF8, 0x5C, 0xB9, + 0xE3, 0x54, 0x91, 0xF3, 0x1D, 0x4A, 0x69, 0x52, + 0xF9, 0xD8, 0xE0, 0x97, 0xAE, 0xF9, 0x4F, 0xA1, + 0xCA, 0x0B, 0x12, 0x52, 0x57, 0x21, 0xF0, 0x3D + }, + { + 0xEF, 0x8C, 0xDA, 0x96, 0x35, 0xD5, 0x06, 0x3A, + 0xF8, 0x11, 0x15, 0xDA, 0x3C, 0x52, 0x32, 0x5A, + 0x86, 0xE8, 0x40, 0x74, 0xF9, 0xF7, 0x24, 0xB7, + 0xCB, 0xD0, 0xB0, 0x85, 0x6F, 0xF0, 0x01, 0x77, + 0xCD, 0xD2, 0x83, 0xC2, 0x98, 0x32, 0x6C, 0xD0, + 0x91, 0x77, 0x54, 0xC5, 0x24, 0x1F, 0x14, 0x80, + 0xFB, 0x50, 0x9C, 0xF2, 0xD2, 0xC4, 0x49, 0x81, + 0x80, 0x77, 0xAE, 0x35, 0xFC, 0x33, 0x07, 0x37 + }, + { + 0x8C, 0xF9, 0x33, 0xA2, 0xD3, 0x61, 0xA3, 0xE6, + 0xA1, 0x36, 0xDB, 0xE4, 0xA0, 0x1E, 0x79, 0x03, + 0x79, 0x7A, 0xD6, 0xCE, 0x76, 0x6E, 0x2B, 0x91, + 0xB9, 0xB4, 0xA4, 0x03, 0x51, 0x27, 0xD6, 0x5F, + 0x4B, 0xE8, 0x65, 0x50, 0x11, 0x94, 0x18, 0xE2, + 0x2D, 0xA0, 0x0F, 0xD0, 0x6B, 0xF2, 0xB2, 0x75, + 0x96, 0xB3, 0x7F, 0x06, 0xBE, 0x0A, 0x15, 0x4A, + 0xAF, 0x7E, 0xCA, 0x54, 0xC4, 0x52, 0x0B, 0x97 + }, + { + 0x24, 0xDC, 0x1E, 0x6D, 0xC4, 0xE5, 0x1A, 0x3A, + 0x3C, 0x8D, 0xA6, 0x7A, 0xAC, 0xB4, 0xC5, 0x41, + 0xE4, 0x18, 0x18, 0xD1, 0x80, 0xE5, 0xBB, 0x69, + 0x75, 0x3D, 0xBB, 0xFF, 0x2F, 0x44, 0xD0, 0xE7, + 0xDA, 0x83, 0x03, 0x86, 0xBF, 0xC8, 0x3B, 0x27, + 0xA5, 0x9D, 0xBB, 0x62, 0xB9, 0x64, 0xFC, 0x8E, + 0xA6, 0xCB, 0xDF, 0x30, 0x49, 0xBF, 0xF8, 0x1F, + 0x24, 0xF3, 0x48, 0xDB, 0x4E, 0xFD, 0x0D, 0x07 + }, + { + 0xBC, 0x23, 0xF5, 0xAB, 0xDF, 0xFD, 0x6A, 0x32, + 0xA5, 0xD4, 0x08, 0x11, 0x26, 0x2E, 0xD4, 0x47, + 0x9E, 0xF7, 0x0B, 0x42, 0x33, 0xCA, 0x20, 0x5B, + 0xC5, 0xB9, 0xBF, 0x85, 0x96, 0x73, 0x19, 0x82, + 0xD0, 0x41, 0x69, 0xA9, 0x04, 0xDD, 0x43, 0xB0, + 0xE0, 0xF9, 0x48, 0x99, 0xF7, 0x33, 0x02, 0x2D, + 0x24, 0xD8, 0x4F, 0xAD, 0x0A, 0x99, 0x16, 0x00, + 0xF1, 0x97, 0x9B, 0x27, 0x2A, 0xD6, 0x20, 0x73 + }, + { + 0xEF, 0x10, 0x7F, 0xCD, 0x0D, 0x92, 0xD8, 0x4E, + 0xF5, 0xEF, 0x94, 0x63, 0xE6, 0xE9, 0x62, 0x41, + 0x25, 0x45, 0x29, 0xD2, 0xB9, 0x7F, 0xDB, 0xE5, + 0x64, 0x19, 0x07, 0x0A, 0xDB, 0xC7, 0xD5, 0x70, + 0x6F, 0xEB, 0x8F, 0x44, 0x95, 0x79, 0x81, 0x9E, + 0xD4, 0xBE, 0x61, 0x97, 0x85, 0xFF, 0xFA, 0xAF, + 0x0D, 0x97, 0x89, 0xCF, 0xE7, 0x26, 0x24, 0x9A, + 0xB0, 0x8C, 0x94, 0x68, 0xCB, 0x5F, 0xDE, 0x22 + }, + { + 0x23, 0x1F, 0xBF, 0xB7, 0xA1, 0xDD, 0xC5, 0xB7, + 0x49, 0x33, 0xA2, 0x85, 0xA4, 0x22, 0x4C, 0x04, + 0x9C, 0xBA, 0x14, 0x85, 0xCE, 0x35, 0x64, 0x0D, + 0x9C, 0x51, 0x6E, 0xD7, 0x8E, 0xAA, 0x22, 0x6D, + 0x36, 0xF6, 0x5B, 0x25, 0x89, 0xB8, 0x26, 0xC4, + 0x59, 0xFA, 0x6A, 0x91, 0xC4, 0x26, 0xFD, 0x2A, + 0x8A, 0xB4, 0x61, 0xC9, 0x76, 0x7E, 0x7B, 0xDD, + 0x99, 0x6B, 0xEF, 0x5A, 0x78, 0xF4, 0x81, 0xB7 + }, + { + 0x3A, 0x83, 0x1F, 0x2D, 0xA9, 0x69, 0xB9, 0xB7, + 0x36, 0x0E, 0x74, 0xEE, 0x53, 0xB5, 0x18, 0x98, + 0x0A, 0x5E, 0xBC, 0xDF, 0xD4, 0xEE, 0x23, 0xED, + 0x80, 0x5C, 0x26, 0x39, 0x4D, 0x18, 0x24, 0x20, + 0x8D, 0x7E, 0x8F, 0x63, 0x27, 0xD4, 0xEC, 0x87, + 0x97, 0x9C, 0xE4, 0xAF, 0x8A, 0xB0, 0x97, 0xD6, + 0x9E, 0x26, 0x1C, 0xA3, 0x2D, 0xB0, 0xEE, 0xFD, + 0xBC, 0x18, 0xD1, 0x63, 0x77, 0xA6, 0xBD, 0x20 + }, + { + 0x83, 0x49, 0xA2, 0x0F, 0xDD, 0xBA, 0xE1, 0xD8, + 0x47, 0x2B, 0x67, 0xF0, 0x34, 0x7A, 0xA0, 0xFD, + 0x40, 0x4D, 0x65, 0xC6, 0xFA, 0x14, 0x72, 0xB3, + 0x10, 0x39, 0x0D, 0x75, 0x65, 0xBA, 0x6B, 0xC1, + 0x02, 0x60, 0xD3, 0xDC, 0xE6, 0xA1, 0x4F, 0x4D, + 0xD9, 0xB8, 0xB3, 0xE0, 0xA0, 0xC4, 0x7F, 0x6D, + 0xB7, 0xE7, 0x10, 0x0A, 0x7A, 0x9B, 0x64, 0xA8, + 0x44, 0xF0, 0x10, 0x64, 0xD0, 0x79, 0x05, 0xC5 + }, + { + 0x23, 0x9A, 0xE3, 0xD6, 0x85, 0x9C, 0x7C, 0x97, + 0x2A, 0x5D, 0xC8, 0xB9, 0xC5, 0x5A, 0xEB, 0x93, + 0x85, 0x90, 0xCF, 0xB8, 0x55, 0x2A, 0xA3, 0x05, + 0xA6, 0xF6, 0xF3, 0x1F, 0xFA, 0x95, 0xA8, 0x40, + 0xF4, 0xEC, 0x36, 0xF6, 0xFB, 0x8F, 0x83, 0xB6, + 0x9C, 0x1D, 0xA9, 0x81, 0xFC, 0x9B, 0xA1, 0x63, + 0x60, 0xDB, 0x0F, 0x4F, 0x7C, 0x68, 0xEB, 0x54, + 0x3E, 0xD5, 0x8B, 0x28, 0x75, 0x6A, 0x1E, 0x0D + }, + { + 0x7C, 0x56, 0x73, 0x28, 0x63, 0x08, 0x40, 0x8F, + 0xBC, 0x62, 0x24, 0x0E, 0x07, 0x47, 0x28, 0xB2, + 0x7A, 0x57, 0x5C, 0xAD, 0x2A, 0x15, 0x6E, 0x00, + 0xB5, 0xC0, 0x8B, 0x21, 0x8D, 0x88, 0x87, 0x79, + 0x1E, 0x47, 0xBF, 0x10, 0xB0, 0xBC, 0x61, 0xA5, + 0x82, 0x54, 0x5A, 0x24, 0x69, 0x63, 0x9C, 0xE6, + 0x28, 0xC4, 0x0F, 0x20, 0xEA, 0x8B, 0x84, 0x9C, + 0xD0, 0x05, 0x44, 0x5F, 0x29, 0xA0, 0x8C, 0xCE + }, + { + 0xDD, 0x07, 0x7E, 0x76, 0x9E, 0x0D, 0xEF, 0x78, + 0xDD, 0x7A, 0xAD, 0xD5, 0x7D, 0x58, 0x42, 0x1B, + 0xDA, 0x3A, 0x1A, 0x4E, 0x69, 0x72, 0x05, 0x9F, + 0x8E, 0x64, 0x9C, 0xD6, 0xBC, 0xA4, 0x4A, 0x13, + 0xAB, 0x71, 0xEB, 0x53, 0x5D, 0x24, 0x49, 0x22, + 0x94, 0x84, 0x65, 0xD7, 0x3B, 0xD6, 0x4E, 0xFB, + 0x09, 0x10, 0x46, 0x94, 0x90, 0x66, 0x65, 0x36, + 0x03, 0x57, 0x5A, 0x2E, 0x89, 0x1E, 0xBD, 0x54 + }, + { + 0xB3, 0x6C, 0xEF, 0x28, 0x53, 0x2B, 0x40, 0xD8, + 0x17, 0x86, 0x28, 0xF0, 0xFA, 0xB5, 0xE5, 0xB4, + 0xA1, 0xDE, 0xC0, 0xC0, 0xE9, 0x11, 0xD7, 0x27, + 0xBF, 0x09, 0x49, 0x0F, 0x5E, 0x8D, 0x9F, 0xAC, + 0x57, 0x21, 0x3F, 0xD2, 0xA2, 0xD1, 0x2E, 0xD3, + 0xD7, 0x7A, 0x41, 0xF5, 0xE2, 0xFE, 0xCC, 0x40, + 0xE4, 0xEE, 0xCA, 0x16, 0x12, 0xF5, 0x1C, 0x45, + 0x23, 0x31, 0xAE, 0x93, 0x96, 0x62, 0x35, 0xBC + }, + { + 0xDE, 0x73, 0x7D, 0xBC, 0x61, 0x2E, 0xBD, 0x31, + 0xBC, 0x49, 0xA2, 0xD7, 0xC6, 0x44, 0xD4, 0xB1, + 0x37, 0x81, 0x74, 0x19, 0x42, 0x1C, 0x32, 0xF4, + 0xE7, 0x51, 0x14, 0xD8, 0x99, 0xE3, 0x13, 0x1D, + 0x45, 0xCA, 0x54, 0x51, 0x24, 0x8F, 0x24, 0x16, + 0x9F, 0xBF, 0x17, 0xEE, 0x60, 0xA9, 0xB7, 0x07, + 0x98, 0xA4, 0xB9, 0x37, 0xCE, 0xA6, 0x27, 0x95, + 0x28, 0x96, 0x39, 0xD1, 0x8F, 0xCD, 0x89, 0xE4 + }, + { + 0xB4, 0xC1, 0xBB, 0xCB, 0xBC, 0xCD, 0xFC, 0xE4, + 0xD2, 0xBE, 0x9D, 0xCD, 0xB9, 0x83, 0xC1, 0xB0, + 0x20, 0xC5, 0xF7, 0x20, 0xDA, 0x5B, 0xEC, 0xF4, + 0xCB, 0x2A, 0x9A, 0x3D, 0x1B, 0x8D, 0x23, 0xCE, + 0xA7, 0xA9, 0xF5, 0xFD, 0x70, 0xD3, 0x74, 0x0E, + 0xCD, 0x67, 0xCE, 0x7D, 0x1E, 0x9C, 0x5E, 0x31, + 0xA3, 0x30, 0x2D, 0xF6, 0x6A, 0x9B, 0x5D, 0x54, + 0x30, 0x44, 0x90, 0xFB, 0xE1, 0xC4, 0xA8, 0xB9 + }, + { + 0xB1, 0xD6, 0x5E, 0x70, 0xC6, 0x9B, 0xA7, 0xE3, + 0xA7, 0x28, 0xE8, 0xB6, 0x44, 0x94, 0x93, 0xF2, + 0x37, 0x51, 0x0B, 0x23, 0xB6, 0xE7, 0x7D, 0x95, + 0x84, 0xD0, 0x5F, 0xF4, 0xD3, 0xF0, 0x87, 0x80, + 0x92, 0x9D, 0x74, 0xFA, 0x5B, 0xED, 0x9B, 0x75, + 0xD4, 0xD6, 0xD1, 0xCA, 0x91, 0xAB, 0x8D, 0x26, + 0x37, 0xDC, 0x2E, 0x79, 0xBA, 0x0F, 0xE0, 0x59, + 0x4A, 0xCD, 0x68, 0xFB, 0x3C, 0xC6, 0x60, 0xB9 + }, + { + 0xDA, 0x79, 0xF7, 0x29, 0xEA, 0xB9, 0x8C, 0x04, + 0xF3, 0x7F, 0xCC, 0x85, 0x4B, 0x69, 0xA8, 0x4E, + 0x46, 0x7D, 0xEA, 0x1E, 0x77, 0x82, 0xE7, 0xAF, + 0x02, 0xCB, 0x44, 0xA4, 0x9D, 0x21, 0x0D, 0x25, + 0x23, 0x68, 0x3D, 0x42, 0x0A, 0xC1, 0xDE, 0xC8, + 0xAD, 0x1F, 0xB4, 0x0E, 0x65, 0xAB, 0x3F, 0xE2, + 0x51, 0xA8, 0x51, 0xE2, 0x83, 0xD8, 0x58, 0x38, + 0x08, 0x42, 0x61, 0x30, 0x1E, 0xCD, 0x08, 0x9B + }, + { + 0x71, 0x40, 0x40, 0x40, 0x39, 0x21, 0xAE, 0x55, + 0x48, 0xA2, 0x03, 0x39, 0xD6, 0x9E, 0x09, 0x3F, + 0x60, 0x9A, 0xA9, 0x9C, 0x22, 0xDB, 0x72, 0x59, + 0x1D, 0x1E, 0xF4, 0xFC, 0xB0, 0xAF, 0x01, 0x61, + 0x73, 0xE5, 0x77, 0xD8, 0xC1, 0xA3, 0x06, 0x3B, + 0x44, 0x3A, 0x0E, 0x48, 0xF3, 0x13, 0xCF, 0x2E, + 0x0F, 0x9B, 0x0C, 0x2E, 0xF9, 0x6A, 0x96, 0xC4, + 0x24, 0x32, 0x2C, 0xCC, 0x0C, 0xD5, 0x30, 0x4C + }, + { + 0x8B, 0x2E, 0x8C, 0x3F, 0x0E, 0x3C, 0x31, 0x9B, + 0xA6, 0x7E, 0x86, 0x01, 0x4B, 0xDA, 0x68, 0x3E, + 0x53, 0x57, 0xA0, 0x40, 0x37, 0xB4, 0x56, 0x32, + 0x86, 0xAC, 0x89, 0xCD, 0xDB, 0x7E, 0xE0, 0x4C, + 0xF6, 0x67, 0x5F, 0x9A, 0xB6, 0x1F, 0xC8, 0x33, + 0x2D, 0x21, 0x8D, 0x2B, 0xCA, 0x97, 0x15, 0xE7, + 0xDB, 0xE5, 0x83, 0x72, 0xD1, 0xEE, 0xBF, 0x6B, + 0xC2, 0x94, 0x84, 0x71, 0xCF, 0xCE, 0xBB, 0x77 + }, + { + 0x32, 0xEE, 0x95, 0x49, 0xD4, 0xE3, 0x2F, 0x4B, + 0xE9, 0xC5, 0x00, 0xBD, 0x85, 0x43, 0xAF, 0xD0, + 0xB6, 0x97, 0x82, 0xD0, 0xB3, 0xFF, 0x7E, 0xD4, + 0x7A, 0x88, 0x1A, 0x0E, 0x49, 0x1F, 0x37, 0x65, + 0x0A, 0x21, 0xB2, 0x6C, 0x3F, 0x5D, 0x0A, 0x64, + 0xE0, 0x90, 0x58, 0xB3, 0x00, 0x4A, 0x23, 0x68, + 0xB9, 0x50, 0xE4, 0x72, 0x30, 0xC2, 0x29, 0x66, + 0xD3, 0xF7, 0x9D, 0xA7, 0xBA, 0xA0, 0xB8, 0x7F + }, + { + 0xCA, 0xE7, 0xF2, 0x92, 0x71, 0x37, 0x82, 0xC4, + 0x71, 0xFE, 0x31, 0x78, 0xA9, 0x42, 0x0C, 0xD4, + 0xC1, 0x1F, 0xCD, 0x3F, 0x6D, 0xBE, 0x5D, 0x15, + 0xC8, 0x4A, 0xB7, 0x35, 0x3C, 0x73, 0x9E, 0xF0, + 0x64, 0x16, 0x39, 0xA2, 0xF9, 0x2A, 0xED, 0x31, + 0xC5, 0x6A, 0x20, 0x21, 0xCC, 0x5E, 0x58, 0xCB, + 0xEA, 0xD3, 0x74, 0xE2, 0xDC, 0x8A, 0x0D, 0xBC, + 0xE5, 0x45, 0x0F, 0xE7, 0xA0, 0x18, 0xCF, 0xA4 + }, + { + 0xF1, 0x7F, 0xEF, 0xAE, 0xAE, 0x7D, 0x40, 0xCD, + 0x88, 0x5D, 0xAC, 0x0B, 0xC3, 0x50, 0xC0, 0x27, + 0x36, 0x68, 0xEA, 0x02, 0x22, 0xDF, 0x5C, 0x75, + 0x69, 0x4F, 0x5C, 0xB3, 0xA3, 0x21, 0x51, 0x9F, + 0x6E, 0x0E, 0xC4, 0x3B, 0xA0, 0xC8, 0x59, 0x3D, + 0xC7, 0x34, 0x13, 0x41, 0xE5, 0x19, 0x48, 0x8F, + 0x20, 0xAB, 0xD5, 0xB8, 0x12, 0x4D, 0xFA, 0xCE, + 0xA5, 0xCD, 0xE0, 0x96, 0x5B, 0x69, 0x70, 0xF9 + }, + { + 0xE2, 0xCF, 0x86, 0xDD, 0xC8, 0x42, 0x4E, 0xE5, + 0x47, 0xEB, 0x72, 0x45, 0xB7, 0x32, 0x5E, 0x02, + 0xF2, 0xE3, 0xAC, 0x01, 0x3C, 0x8D, 0x38, 0x6B, + 0x3D, 0x2E, 0x09, 0x20, 0x8A, 0x9B, 0xCC, 0x0B, + 0x44, 0xC4, 0xC4, 0x38, 0xEA, 0xAF, 0x52, 0xD2, + 0x07, 0x7E, 0x91, 0x77, 0xEB, 0x8E, 0xE1, 0xD5, + 0x90, 0x75, 0xB5, 0x25, 0x92, 0x20, 0x20, 0x62, + 0x22, 0x93, 0x54, 0xBF, 0x23, 0xC9, 0x62, 0x39 + }, + { + 0x38, 0xF2, 0x6A, 0x11, 0x02, 0xCB, 0x16, 0x2D, + 0x35, 0x1F, 0x84, 0x3B, 0x3C, 0x49, 0xF6, 0xFF, + 0x85, 0x44, 0x16, 0x33, 0xB6, 0x70, 0x4A, 0x28, + 0x6A, 0xF8, 0x1C, 0xCB, 0xAE, 0x5A, 0x67, 0xD3, + 0x01, 0x5C, 0xC0, 0xEF, 0xAF, 0xB7, 0x05, 0x7D, + 0xC2, 0xB2, 0x8D, 0x67, 0x66, 0xE8, 0x2A, 0x06, + 0x8A, 0x4C, 0x0B, 0x52, 0x4B, 0x66, 0xD0, 0xA6, + 0x32, 0x77, 0x5D, 0x93, 0x06, 0x15, 0x75, 0xF9 + }, + { + 0xA2, 0xC4, 0x30, 0x2D, 0xAC, 0xA7, 0xA7, 0xC6, + 0x32, 0xF6, 0x76, 0x30, 0x4E, 0x62, 0x75, 0xC1, + 0xC1, 0xF0, 0xDB, 0xFE, 0x38, 0xDC, 0x57, 0x1C, + 0xB2, 0x3E, 0x1F, 0x7B, 0xA5, 0xDC, 0x18, 0x18, + 0x0F, 0xC4, 0x8A, 0x01, 0x5F, 0x92, 0x7C, 0x89, + 0x96, 0x7C, 0x1E, 0x10, 0x4E, 0x66, 0xF5, 0xEA, + 0x5B, 0x2D, 0xD3, 0x1D, 0x78, 0x1C, 0x38, 0x49, + 0xBF, 0xC6, 0x49, 0x22, 0x0C, 0x38, 0x5C, 0x82 + }, + { + 0xC1, 0x9C, 0x6B, 0x3F, 0xB5, 0x35, 0x2B, 0xB3, + 0x94, 0xC2, 0x68, 0x46, 0x52, 0x3C, 0x25, 0xE8, + 0x26, 0x5D, 0x50, 0x5F, 0x50, 0x1F, 0x96, 0x03, + 0xA4, 0xF8, 0xBD, 0x55, 0x38, 0x6C, 0xF4, 0xCC, + 0x9F, 0x4D, 0x71, 0xF3, 0x8F, 0xF4, 0x45, 0xF4, + 0xEF, 0xC8, 0x30, 0x98, 0xD4, 0x79, 0x69, 0x33, + 0x4E, 0x79, 0xA2, 0xBC, 0xB4, 0x02, 0x6B, 0xC6, + 0x3B, 0x79, 0x59, 0xDE, 0xDB, 0x62, 0xB7, 0xBD + }, + { + 0x1F, 0x4A, 0xB9, 0x84, 0x0A, 0x1C, 0xFA, 0x8F, + 0xE6, 0xC5, 0x62, 0x2D, 0x9B, 0x53, 0x8B, 0xEC, + 0xB8, 0x80, 0x7A, 0x87, 0x78, 0xB6, 0x9D, 0x93, + 0x05, 0xF9, 0x08, 0x57, 0x65, 0x73, 0xB2, 0x0C, + 0xA3, 0x70, 0x4E, 0x89, 0x12, 0x97, 0x26, 0xD5, + 0x02, 0xE1, 0x98, 0x58, 0x8D, 0x07, 0x26, 0x68, + 0xBF, 0x03, 0x63, 0x0B, 0x5B, 0x5A, 0x92, 0x32, + 0xFF, 0x39, 0x25, 0x27, 0x24, 0x9D, 0xF9, 0x9B + }, + { + 0xFE, 0x03, 0x17, 0x7B, 0x58, 0xB4, 0x88, 0x83, + 0xA8, 0x6D, 0x42, 0x68, 0x33, 0x4B, 0x95, 0x91, + 0xD9, 0xFB, 0xD8, 0xBF, 0x7C, 0xC2, 0xAA, 0xCC, + 0x50, 0x25, 0xEF, 0x47, 0x6B, 0x45, 0x33, 0xBA, + 0x7B, 0xD7, 0x81, 0xDF, 0x01, 0x11, 0x47, 0xB3, + 0xCF, 0x51, 0x1D, 0x8B, 0x3D, 0xCD, 0x8C, 0x78, + 0x0D, 0x30, 0xD7, 0xDA, 0x71, 0x8C, 0x22, 0x44, + 0x23, 0x19, 0x81, 0x7B, 0xE3, 0x18, 0x6B, 0xC5 + }, + { + 0xF4, 0xC3, 0xB0, 0x59, 0x10, 0x5B, 0x6A, 0xA5, + 0xFE, 0x78, 0x84, 0x3A, 0x07, 0xD9, 0x4F, 0x71, + 0x20, 0x62, 0xCB, 0x5A, 0x4D, 0xD6, 0x05, 0x9F, + 0x97, 0x90, 0x4D, 0x0C, 0x57, 0x97, 0x3B, 0xA8, + 0xDF, 0x71, 0xD1, 0x5A, 0x51, 0x1A, 0x06, 0x68, + 0x64, 0xFE, 0x45, 0x5E, 0xDC, 0x9E, 0x5F, 0x16, + 0x52, 0x4C, 0xEC, 0x7E, 0xE2, 0x48, 0xEE, 0x3E, + 0xC9, 0x29, 0x06, 0x3B, 0xD1, 0x07, 0x98, 0xDA + }, + { + 0x57, 0xA1, 0x6F, 0x96, 0x4B, 0x18, 0x1B, 0x12, + 0x03, 0xA5, 0x80, 0x3B, 0x73, 0x81, 0x7D, 0x77, + 0x44, 0x83, 0x82, 0x6C, 0xEA, 0x11, 0x3B, 0x9C, + 0xCF, 0xCF, 0x0E, 0xB8, 0x7C, 0xB2, 0x30, 0x64, + 0x28, 0x49, 0x62, 0xD8, 0x47, 0xBB, 0x1F, 0xAE, + 0x8C, 0xBF, 0x5C, 0xC6, 0x3B, 0x3C, 0xEA, 0xA1, + 0x24, 0x1E, 0xA4, 0x2C, 0x63, 0xF8, 0x98, 0x01, + 0x1F, 0xC4, 0xDB, 0xCA, 0xE6, 0xF5, 0xE8, 0xC5 + }, + { + 0x79, 0x52, 0xFC, 0x83, 0xAC, 0xF1, 0x3A, 0x95, + 0xCA, 0x9C, 0x27, 0xA2, 0x15, 0x6D, 0x9C, 0x1B, + 0x63, 0x00, 0xB0, 0xEF, 0x79, 0x0F, 0x57, 0x2B, + 0xC3, 0x94, 0xC6, 0x77, 0xF7, 0xC1, 0x46, 0x29, + 0xEB, 0xD8, 0xE7, 0xD5, 0xD7, 0xC7, 0xF1, 0xA5, + 0xEB, 0xBD, 0xC3, 0x90, 0xCC, 0x08, 0xCD, 0x58, + 0xC2, 0x00, 0x89, 0x00, 0xCB, 0x55, 0xEB, 0x05, + 0xE4, 0x44, 0xA6, 0x8C, 0x3B, 0x39, 0x3E, 0x60 + }, + { + 0x2C, 0x22, 0x40, 0xD6, 0xB5, 0x41, 0xF4, 0x29, + 0x4F, 0xF9, 0x76, 0x79, 0x1D, 0x35, 0xE6, 0xA2, + 0xD4, 0x92, 0xF5, 0x7A, 0x91, 0x5F, 0xBA, 0xC5, + 0x83, 0x26, 0x60, 0xC1, 0x0E, 0x9C, 0x96, 0x46, + 0x5C, 0x7B, 0xD5, 0xFC, 0xA7, 0x51, 0xBF, 0x68, + 0xE2, 0x67, 0x3A, 0x63, 0x8E, 0x3A, 0xF7, 0x35, + 0xB0, 0x20, 0x91, 0xD7, 0x5D, 0x1A, 0x7F, 0x89, + 0xE3, 0xF7, 0x61, 0xC5, 0xDF, 0x82, 0x1A, 0x6B + }, + { + 0x59, 0xDC, 0x84, 0x6D, 0x34, 0x05, 0xCC, 0xD8, + 0x06, 0xF8, 0xFA, 0x20, 0xC8, 0x96, 0x9E, 0xF6, + 0x8A, 0x43, 0x85, 0xEF, 0x6C, 0x27, 0x4E, 0xEE, + 0x6D, 0xC0, 0x69, 0x2C, 0x3E, 0xCF, 0xB1, 0xA8, + 0x34, 0xCE, 0x64, 0x43, 0x76, 0xC5, 0x2B, 0x80, + 0x42, 0x1B, 0xAE, 0x94, 0xD6, 0xC7, 0xFD, 0xCC, + 0xA5, 0xA8, 0xF1, 0x85, 0x9C, 0x45, 0xA1, 0x0C, + 0x4E, 0xB2, 0x74, 0x82, 0x6F, 0x1F, 0x08, 0x9F + }, + { + 0xB7, 0x52, 0x96, 0x27, 0x07, 0xA1, 0x7B, 0x66, + 0x4F, 0xAE, 0xB3, 0x13, 0xE2, 0xB9, 0x52, 0xDC, + 0x03, 0xE7, 0x4A, 0x7E, 0x94, 0x47, 0x09, 0x8A, + 0xA6, 0xD4, 0xEA, 0x5B, 0xD2, 0x87, 0xD0, 0x7A, + 0x12, 0x25, 0xEC, 0xED, 0xA9, 0x81, 0x15, 0x70, + 0x58, 0x0A, 0x51, 0x2B, 0x2B, 0x20, 0xB3, 0xFC, + 0xFC, 0xA7, 0x0B, 0x44, 0xF6, 0x45, 0x4E, 0xF3, + 0xC3, 0x52, 0x4C, 0xCA, 0x6B, 0x69, 0x47, 0x5B + }, + { + 0xDA, 0x0D, 0x8E, 0x54, 0x61, 0xF8, 0x10, 0x24, + 0xEF, 0xFE, 0xED, 0x5D, 0x70, 0x76, 0xA0, 0x4F, + 0xED, 0xED, 0xAC, 0x57, 0xE7, 0xC9, 0x8A, 0x59, + 0x45, 0xBF, 0xDE, 0x66, 0x75, 0x58, 0x18, 0x85, + 0x1B, 0xE1, 0x13, 0x6B, 0x71, 0xF4, 0x33, 0xA5, + 0x6B, 0xDA, 0x18, 0x41, 0xAE, 0x71, 0x39, 0x2C, + 0x4B, 0x82, 0x90, 0x82, 0x63, 0x59, 0xF5, 0x87, + 0x22, 0x3C, 0x3E, 0xF7, 0x37, 0xFF, 0x73, 0x2A + }, + { + 0xED, 0xB8, 0x6A, 0x23, 0x7C, 0x6F, 0x13, 0x7D, + 0xFB, 0xB3, 0x47, 0x01, 0x1E, 0xDB, 0x4C, 0x6E, + 0x86, 0x1F, 0x4D, 0x58, 0x14, 0x60, 0x85, 0x46, + 0x34, 0x41, 0x04, 0x2F, 0xA3, 0x63, 0x16, 0xF1, + 0xFA, 0xF8, 0x87, 0x11, 0xBB, 0x0F, 0x18, 0x11, + 0xDF, 0xBB, 0xBF, 0xA7, 0xB5, 0x1F, 0x9C, 0xE2, + 0xD4, 0x96, 0x05, 0x24, 0x3E, 0xD0, 0x16, 0xCB, + 0xAD, 0x68, 0x85, 0xEA, 0xE2, 0x03, 0x67, 0x4F + }, + { + 0xE6, 0xD8, 0xE0, 0xFB, 0xAA, 0x29, 0xDB, 0xEB, + 0x60, 0xF3, 0xC7, 0xF9, 0x85, 0xBA, 0xD7, 0x54, + 0xD7, 0x21, 0xAA, 0xC6, 0x3D, 0xA6, 0xF4, 0x49, + 0x0C, 0x9D, 0x7E, 0xA2, 0x31, 0xD2, 0x62, 0x2F, + 0xDF, 0xDE, 0xF1, 0x48, 0xD0, 0xCA, 0x44, 0x2B, + 0x8D, 0x59, 0xCF, 0x3E, 0x4F, 0x98, 0x35, 0xCB, + 0xC2, 0x40, 0xAF, 0x40, 0xFB, 0xA6, 0x3A, 0x2E, + 0xA5, 0xA2, 0x35, 0xD4, 0x6E, 0xEA, 0x6E, 0xAC + }, + { + 0xD4, 0xE4, 0x63, 0xC4, 0x88, 0x29, 0x87, 0xEB, + 0x44, 0xA5, 0xED, 0x0C, 0x82, 0x1D, 0x68, 0xB0, + 0xFE, 0xF9, 0x9D, 0x6F, 0x53, 0xA5, 0x7B, 0xF3, + 0x19, 0xBD, 0xAC, 0x25, 0xAC, 0x38, 0xEB, 0x0B, + 0x23, 0xE1, 0x13, 0x8C, 0x00, 0x12, 0xF5, 0xF3, + 0x83, 0x46, 0xA1, 0xDE, 0x9D, 0x4A, 0x99, 0x2A, + 0x64, 0xB9, 0x42, 0x83, 0x4A, 0x85, 0x6E, 0xFB, + 0xAA, 0x06, 0x20, 0xBD, 0xA2, 0x9F, 0x6A, 0x86 + }, + { + 0x42, 0xD8, 0x10, 0xD0, 0x1C, 0x2D, 0xA2, 0x47, + 0x35, 0xF0, 0x4A, 0x5E, 0x90, 0x13, 0x38, 0xFD, + 0xFC, 0x2D, 0xE1, 0x71, 0x5F, 0xF6, 0x64, 0x3A, + 0x37, 0x2F, 0x88, 0x0E, 0x6C, 0x5C, 0x6C, 0x13, + 0xD2, 0xB3, 0xAD, 0x70, 0x77, 0x46, 0x9D, 0x64, + 0x33, 0x54, 0x05, 0x4D, 0x32, 0xDD, 0x80, 0x49, + 0xEA, 0x63, 0x73, 0x2B, 0x57, 0x45, 0xBD, 0xB2, + 0x3B, 0xE2, 0xB5, 0x8E, 0x48, 0xC1, 0x01, 0x3A + }, + { + 0xCF, 0xBF, 0x54, 0x30, 0x07, 0x6F, 0x82, 0x5A, + 0x3B, 0xBB, 0x88, 0xC1, 0xBC, 0x0A, 0xEF, 0x61, + 0x25, 0x9E, 0x8F, 0x4D, 0x5F, 0xA3, 0x3C, 0x39, + 0x82, 0x50, 0x62, 0xF1, 0x5D, 0x19, 0xFD, 0x4A, + 0x01, 0x82, 0xCD, 0x97, 0x36, 0xD2, 0xAE, 0xC9, + 0x74, 0x9C, 0xCF, 0x83, 0x18, 0x6C, 0x35, 0x74, + 0xAB, 0x94, 0x42, 0x65, 0x40, 0x66, 0x0A, 0x9D, + 0xB8, 0xC3, 0xAA, 0xBB, 0xCB, 0xDD, 0x9D, 0x0F + }, + { + 0x6C, 0x24, 0x34, 0xA1, 0xAF, 0xA1, 0x57, 0xAC, + 0xCC, 0x34, 0xA5, 0xC4, 0x87, 0x2D, 0xFF, 0x69, + 0xFE, 0x7F, 0x31, 0x96, 0xCB, 0x1A, 0x75, 0x0C, + 0x54, 0x1D, 0x8B, 0x73, 0x92, 0x28, 0x88, 0xBA, + 0xBE, 0x89, 0xB1, 0xC3, 0x82, 0x02, 0x21, 0x86, + 0x20, 0xD8, 0x8D, 0x77, 0xDA, 0xD9, 0xDF, 0xBA, + 0xB3, 0xFB, 0xF7, 0x40, 0xB2, 0xD1, 0xD8, 0xF3, + 0x7E, 0xAD, 0x25, 0x8E, 0x2E, 0xF1, 0x06, 0x52 + }, + { + 0x48, 0xB7, 0x26, 0x8A, 0xA4, 0x34, 0x2F, 0xAB, + 0x02, 0x1D, 0x14, 0x72, 0xE9, 0x25, 0x7F, 0x76, + 0x58, 0x5C, 0xC5, 0x68, 0x10, 0xC8, 0xF2, 0xA6, + 0xE1, 0xD4, 0xA8, 0x94, 0x6B, 0x77, 0x71, 0x42, + 0xD4, 0x4A, 0xE5, 0x13, 0xA8, 0x80, 0x9F, 0x2D, + 0x6D, 0xC7, 0x26, 0x30, 0x5F, 0x79, 0x44, 0x60, + 0x4D, 0x95, 0x2D, 0x4A, 0x9F, 0x08, 0x5C, 0x5C, + 0x10, 0x50, 0xBA, 0xFD, 0xD2, 0x1D, 0x1E, 0x60 + }, + { + 0xCE, 0xCF, 0xCE, 0x4B, 0x12, 0xC6, 0xCF, 0x53, + 0xD1, 0xB1, 0xB2, 0xD4, 0x18, 0xA4, 0x93, 0xE3, + 0xF4, 0x29, 0x17, 0x03, 0x21, 0xE8, 0x1A, 0xA2, + 0x52, 0x63, 0xAA, 0xA7, 0x15, 0xD5, 0xCA, 0x38, + 0x9F, 0x65, 0xC3, 0xAC, 0xF9, 0x9B, 0x18, 0x0E, + 0x44, 0x6B, 0x50, 0xE6, 0x01, 0xFC, 0xBF, 0x44, + 0x61, 0xD0, 0x42, 0x6A, 0x85, 0x92, 0xA0, 0x77, + 0x42, 0x20, 0x18, 0x57, 0x12, 0x5F, 0x71, 0xEE + }, + { + 0x38, 0x5A, 0x75, 0x22, 0x42, 0xEB, 0x9E, 0xD5, + 0x6B, 0x07, 0x4B, 0x70, 0x2C, 0x91, 0xE7, 0x5A, + 0xEC, 0x0B, 0xE9, 0x06, 0x4B, 0xD9, 0xCF, 0x88, + 0x03, 0x04, 0xC2, 0x13, 0x27, 0x0C, 0xB2, 0xEA, + 0xE8, 0xE2, 0x1D, 0x9A, 0xE8, 0xC6, 0x08, 0x15, + 0x19, 0xF7, 0x5D, 0xFA, 0xBB, 0x00, 0x3B, 0x24, + 0x32, 0xB0, 0x47, 0x55, 0xB8, 0xC3, 0x2C, 0x97, + 0xAC, 0x29, 0x14, 0xE8, 0xBF, 0x45, 0xB2, 0x34 + }, + { + 0xD8, 0x9A, 0x12, 0x4A, 0x9B, 0x95, 0x8B, 0xA2, + 0x3D, 0x09, 0x20, 0x7A, 0xCF, 0xA6, 0x2A, 0x33, + 0xB8, 0x70, 0x89, 0xB2, 0x86, 0xE8, 0x43, 0x8B, + 0xDC, 0x01, 0xE2, 0x33, 0xAB, 0x2A, 0x86, 0x30, + 0xA1, 0xEE, 0xB6, 0xB2, 0xB9, 0xBA, 0x6B, 0x7D, + 0x21, 0x00, 0x10, 0x77, 0x33, 0xDE, 0xAF, 0x4C, + 0x20, 0x47, 0x8C, 0x26, 0xF2, 0x49, 0xC6, 0x89, + 0xC5, 0x26, 0x84, 0x73, 0xE2, 0xE9, 0xFA, 0x60 + }, + { + 0x43, 0xDE, 0x10, 0x92, 0xFF, 0x9F, 0xF5, 0x28, + 0x20, 0x6C, 0x6F, 0xCF, 0x81, 0x32, 0x2E, 0xAD, + 0x3D, 0x22, 0xEA, 0xA4, 0xC8, 0x54, 0x52, 0x15, + 0x77, 0xDF, 0x33, 0x62, 0x47, 0x49, 0x5C, 0xE1, + 0x72, 0xFC, 0x87, 0x39, 0x95, 0x30, 0x0B, 0x21, + 0xB9, 0x46, 0x10, 0xC9, 0xD2, 0xF6, 0x33, 0xB5, + 0x33, 0xBD, 0xE4, 0x56, 0x8C, 0xA0, 0x9C, 0x38, + 0x0E, 0x84, 0x68, 0xFE, 0x6A, 0xD8, 0xD8, 0x1D + }, + { + 0x86, 0x8B, 0x60, 0x11, 0x99, 0xEF, 0x00, 0x0B, + 0x70, 0x5C, 0xD6, 0x4D, 0x39, 0x30, 0x26, 0x2A, + 0x5A, 0xB9, 0x10, 0xE3, 0x4E, 0x2D, 0x78, 0xE8, + 0x58, 0x7B, 0x4E, 0x01, 0x0D, 0x37, 0x6D, 0xD4, + 0xA0, 0x0D, 0xE4, 0x48, 0x67, 0xD0, 0xE9, 0x33, + 0xEE, 0x39, 0xA1, 0xFA, 0x91, 0x47, 0xD4, 0x99, + 0xD1, 0x84, 0xF3, 0xA9, 0xCF, 0x35, 0x4F, 0x2D, + 0x3C, 0x51, 0x14, 0x6F, 0xF7, 0x15, 0x2D, 0x68 + }, + { + 0x15, 0x17, 0xF8, 0xF0, 0x44, 0x2F, 0x0D, 0x50, + 0xBB, 0xC0, 0xAA, 0xB6, 0x84, 0x6F, 0xDC, 0xE3, + 0xB7, 0x0F, 0xAE, 0xA4, 0xBB, 0x51, 0x13, 0xAC, + 0xB2, 0x3A, 0xBE, 0x10, 0x1D, 0x99, 0xA4, 0x0A, + 0x1B, 0x76, 0xC1, 0xE8, 0xDC, 0x2E, 0xA1, 0x93, + 0x62, 0x94, 0x82, 0x3A, 0xD8, 0x35, 0x4C, 0x11, + 0xE2, 0xE9, 0x6C, 0x67, 0x12, 0xBE, 0x4C, 0xF7, + 0x7C, 0x58, 0x3F, 0xD0, 0x6B, 0x5E, 0x5C, 0x55 + }, + { + 0xAF, 0x4C, 0x6C, 0x67, 0xC5, 0xCA, 0x38, 0x38, + 0x73, 0x48, 0xCA, 0x3E, 0xC2, 0xBE, 0xD7, 0xFB, + 0xA8, 0xC2, 0xB3, 0xD2, 0x2D, 0xE1, 0x48, 0xD0, + 0x8A, 0x61, 0x8C, 0x29, 0x70, 0x23, 0xFB, 0x7B, + 0x6D, 0x2C, 0x15, 0x3D, 0x5E, 0xFC, 0xD1, 0x68, + 0x89, 0x99, 0x91, 0x0B, 0x20, 0xE1, 0xEA, 0xC7, + 0xC1, 0x00, 0xA2, 0xC5, 0xA6, 0xC1, 0xAC, 0xF5, + 0xE9, 0x8F, 0x14, 0x3B, 0x41, 0xDC, 0x8A, 0x12 + }, + { + 0xA2, 0xAD, 0x94, 0x24, 0x3B, 0x8E, 0xEA, 0x68, + 0xF5, 0xFA, 0xDD, 0x69, 0x08, 0xAD, 0xB0, 0xDA, + 0xCD, 0xAA, 0x6A, 0x6D, 0x24, 0xC2, 0x50, 0xD3, + 0x39, 0x40, 0x3D, 0xBA, 0x82, 0x31, 0xBD, 0x51, + 0xE8, 0x87, 0xCB, 0x5B, 0x1B, 0x7B, 0xDE, 0x27, + 0x74, 0xC6, 0xB0, 0x8A, 0xCC, 0xE0, 0xF7, 0x49, + 0x56, 0x48, 0xDA, 0x3B, 0xEB, 0xC7, 0xB1, 0xC2, + 0x82, 0x15, 0x08, 0xC4, 0xD3, 0x82, 0xF7, 0x30 + }, + { + 0x28, 0xF8, 0x8C, 0xDB, 0xE9, 0x03, 0xAD, 0x63, + 0xA0, 0x23, 0x31, 0xDE, 0x1A, 0x32, 0xAF, 0x6D, + 0xBB, 0xA8, 0x2D, 0x7F, 0xC0, 0x79, 0x87, 0x02, + 0x72, 0x49, 0x33, 0xDA, 0x77, 0x38, 0x07, 0xBC, + 0x80, 0x42, 0x78, 0x13, 0x47, 0x81, 0xF1, 0x26, + 0x23, 0x32, 0x20, 0xE3, 0x07, 0x92, 0x81, 0x31, + 0xB2, 0x47, 0x10, 0xB4, 0x67, 0x4E, 0xD7, 0x05, + 0x11, 0x2F, 0x95, 0xD1, 0xAA, 0x37, 0xA2, 0xDC + }, + { + 0x5B, 0xB2, 0x92, 0x65, 0xE2, 0x46, 0xB8, 0x84, + 0xFF, 0x40, 0x91, 0x4F, 0xFA, 0x93, 0xD9, 0xA1, + 0x2E, 0xDC, 0x19, 0xEE, 0xE9, 0xCC, 0x8A, 0x83, + 0x63, 0x1D, 0x68, 0xBD, 0x46, 0xAA, 0xD3, 0x35, + 0x4B, 0xA6, 0x67, 0x4B, 0x91, 0x3F, 0x4F, 0x82, + 0x3E, 0x79, 0x1F, 0x0C, 0xB1, 0x9E, 0xA6, 0xA6, + 0x7C, 0x6E, 0x32, 0xE9, 0xBE, 0x0D, 0x0F, 0xF5, + 0x76, 0x0F, 0x16, 0xDD, 0x75, 0xA8, 0x7B, 0x5D + }, + { + 0xBF, 0x3C, 0x06, 0xDC, 0x6D, 0x94, 0xE3, 0x85, + 0x9A, 0x4D, 0xAA, 0x50, 0xEC, 0xA1, 0xAF, 0x53, + 0x57, 0xE3, 0x45, 0x79, 0xE5, 0x99, 0xF8, 0x20, + 0x49, 0xE1, 0xCC, 0xA7, 0xA7, 0xD4, 0xF3, 0x3F, + 0xEA, 0x44, 0x3B, 0x44, 0x69, 0x1B, 0xD4, 0x36, + 0x88, 0xF5, 0x55, 0x05, 0x31, 0xCF, 0x22, 0xB7, + 0x12, 0x77, 0x89, 0x0B, 0xFF, 0xAE, 0x1E, 0xCE, + 0x78, 0x3F, 0x56, 0x63, 0xA1, 0xC4, 0xD7, 0x1A + }, + { + 0xC9, 0x0D, 0xF5, 0x32, 0xF2, 0xF1, 0x49, 0x3A, + 0x11, 0x55, 0xBE, 0x8C, 0x2A, 0x44, 0x00, 0x92, + 0x20, 0x49, 0x97, 0x4E, 0x7D, 0x4F, 0x4B, 0x54, + 0xF8, 0x20, 0xC2, 0x26, 0x9D, 0x3B, 0x16, 0x1B, + 0x6E, 0x88, 0xEB, 0x77, 0x6B, 0x85, 0x9B, 0x89, + 0xB8, 0x56, 0x7F, 0xBC, 0x55, 0x0C, 0x4F, 0x54, + 0xAA, 0xD2, 0x7A, 0x16, 0x10, 0x65, 0x6D, 0x62, + 0x5C, 0x32, 0x7F, 0x66, 0x5D, 0xCA, 0x70, 0x7C + }, + { + 0x3D, 0x39, 0xEE, 0xCC, 0x9E, 0x90, 0x42, 0x36, + 0xDC, 0x85, 0x7B, 0xA4, 0x9D, 0x55, 0xD3, 0xBA, + 0xD7, 0x65, 0x72, 0xA9, 0x1A, 0x75, 0x95, 0x03, + 0x37, 0x6B, 0x77, 0x08, 0xD6, 0x2D, 0x5A, 0x78, + 0x5C, 0x23, 0x06, 0x80, 0x59, 0xCF, 0x68, 0x89, + 0x7F, 0x23, 0xEE, 0xC5, 0x07, 0x21, 0x9B, 0x0A, + 0x02, 0xED, 0xA2, 0xD8, 0xBC, 0x94, 0xFA, 0x69, + 0x89, 0xA5, 0x14, 0x82, 0x22, 0x03, 0xC8, 0xD1 + }, + { + 0xE0, 0x8C, 0x54, 0xD9, 0x98, 0xF9, 0x2B, 0x7A, + 0x54, 0xA2, 0x4C, 0xA6, 0xAE, 0xB1, 0x53, 0xA6, + 0x4F, 0x9C, 0x9F, 0x1F, 0xC3, 0x36, 0x58, 0xB3, + 0xED, 0xAC, 0x2C, 0x4B, 0xB5, 0x26, 0x31, 0x58, + 0xDA, 0xDF, 0x00, 0xD3, 0x51, 0x9A, 0x11, 0x9A, + 0x56, 0x14, 0xC7, 0xF3, 0x79, 0x40, 0xE5, 0x5D, + 0x13, 0xCC, 0xE4, 0x66, 0xCB, 0x71, 0xA4, 0x07, + 0xC3, 0x9F, 0xC5, 0x1E, 0x1E, 0xFE, 0x18, 0xDA + }, + { + 0x74, 0x76, 0x76, 0x07, 0x04, 0x1D, 0xD4, 0xB7, + 0xC5, 0x6B, 0x18, 0x9E, 0xE8, 0xF2, 0x77, 0x31, + 0xA5, 0x16, 0x72, 0x23, 0xEB, 0x7A, 0xF9, 0xB9, + 0x39, 0xE1, 0x18, 0xF8, 0x7D, 0x80, 0xB4, 0x9E, + 0xA8, 0xD0, 0xD0, 0x1F, 0x74, 0xF3, 0x98, 0xB1, + 0x72, 0xA8, 0xAD, 0x0D, 0xBF, 0x99, 0x41, 0x4F, + 0x08, 0xD2, 0xB7, 0xD8, 0xD7, 0x52, 0x16, 0xA1, + 0x82, 0x25, 0x27, 0x3D, 0x8D, 0x7F, 0xD0, 0x5D + }, + { + 0xFE, 0xE8, 0x9A, 0x92, 0xCC, 0xF9, 0xF1, 0xEB, + 0x08, 0x4A, 0xAB, 0xA9, 0x54, 0x97, 0xEF, 0x0F, + 0x30, 0x13, 0x4C, 0x19, 0x1C, 0xF9, 0x0A, 0x49, + 0xD2, 0x2C, 0x7D, 0x2F, 0x66, 0x14, 0x99, 0x3C, + 0xBE, 0x1A, 0x4B, 0x65, 0x13, 0xED, 0xC1, 0x53, + 0x86, 0x8A, 0x3D, 0x56, 0x2B, 0x5B, 0x02, 0x26, + 0xBA, 0x8E, 0x1B, 0x0D, 0xCB, 0x69, 0xED, 0x45, + 0xAF, 0x47, 0xCE, 0x4F, 0x86, 0xBA, 0x47, 0x4A + }, + { + 0xCD, 0xAE, 0x94, 0xB6, 0xD1, 0xD8, 0x35, 0xF6, + 0xC7, 0x4C, 0x76, 0xEC, 0x3A, 0x2D, 0xB6, 0x5B, + 0xBD, 0xFA, 0xE1, 0x9D, 0x7B, 0x05, 0x0D, 0xC9, + 0x5D, 0x65, 0x87, 0x33, 0xB8, 0xB2, 0x2C, 0x6F, + 0x9E, 0x0B, 0x63, 0xCC, 0x90, 0x5A, 0x29, 0xEA, + 0x88, 0x78, 0xCA, 0x39, 0x45, 0x56, 0xB3, 0x67, + 0x3C, 0x62, 0x79, 0x15, 0x46, 0xA9, 0xA1, 0xF0, + 0xD1, 0x56, 0x5F, 0xAD, 0xC5, 0x35, 0x36, 0xC1 + }, + { + 0xC7, 0x22, 0x8B, 0x6F, 0x00, 0x00, 0x17, 0xD2, + 0xBE, 0x4B, 0xF2, 0xAE, 0x48, 0xAD, 0xDB, 0x78, + 0x5E, 0x27, 0x35, 0xBF, 0x3C, 0x61, 0x4D, 0x3C, + 0x34, 0x23, 0x1F, 0x1D, 0x0C, 0x88, 0x7D, 0x3A, + 0x8E, 0x88, 0x88, 0x0B, 0x67, 0xAD, 0x3B, 0x2F, + 0x65, 0x23, 0xDD, 0x67, 0x19, 0x34, 0x2C, 0xD4, + 0xF0, 0x59, 0x35, 0xD2, 0xE5, 0x26, 0x7F, 0x36, + 0x80, 0xE7, 0x73, 0xBD, 0x5E, 0xAD, 0xFE, 0x1D + }, + { + 0x12, 0x27, 0x44, 0xFE, 0x3F, 0xFF, 0x9A, 0x05, + 0x5F, 0x0F, 0x3B, 0xDE, 0x01, 0xEB, 0x2F, 0x44, + 0x6B, 0x0C, 0xDA, 0xF3, 0xAE, 0xD7, 0x2C, 0xAA, + 0x29, 0x40, 0x74, 0x19, 0x20, 0x12, 0x0A, 0x96, + 0x4F, 0xCF, 0xF8, 0x70, 0x99, 0xB0, 0x8E, 0xF3, + 0x34, 0x96, 0xE3, 0x99, 0x03, 0x2A, 0x82, 0xDA, + 0xAD, 0x4F, 0xED, 0x30, 0x31, 0x17, 0x2F, 0x77, + 0x47, 0x92, 0x58, 0xFA, 0x39, 0xDB, 0x92, 0xFD + }, + { + 0x1F, 0xB4, 0xE3, 0x67, 0xEA, 0xB6, 0x42, 0xB7, + 0x2E, 0x43, 0xAD, 0x4A, 0xBD, 0xFC, 0xAD, 0x74, + 0x62, 0x0C, 0x3F, 0x6C, 0x63, 0xA8, 0x91, 0x31, + 0x28, 0xD2, 0x22, 0x6E, 0xB1, 0x92, 0xF9, 0x99, + 0x2E, 0xB9, 0xC8, 0xF7, 0x6A, 0xE2, 0x06, 0xD3, + 0xF5, 0xDE, 0xC7, 0x26, 0xA5, 0xA6, 0x86, 0xB4, + 0xAE, 0x37, 0xB5, 0x57, 0xAB, 0x57, 0xF9, 0x56, + 0x48, 0x53, 0x34, 0xF7, 0x3D, 0xCE, 0x02, 0xE0 + }, + { + 0x04, 0x25, 0xCA, 0xAA, 0x92, 0x3B, 0x47, 0xB3, + 0x50, 0x45, 0xEB, 0x50, 0x82, 0x9C, 0x04, 0x8B, + 0xC8, 0x90, 0x44, 0x4A, 0xFE, 0xEF, 0xC0, 0xAF, + 0xC9, 0xD1, 0x87, 0x7B, 0x82, 0x1E, 0x04, 0x3C, + 0x9C, 0x7B, 0x9D, 0x6D, 0xC3, 0x3F, 0xBB, 0xDF, + 0xA5, 0x37, 0xC1, 0xEC, 0xE3, 0x11, 0x96, 0x5B, + 0x2F, 0xEE, 0x89, 0x82, 0xBC, 0x46, 0xA2, 0xA7, + 0x50, 0xBF, 0xC7, 0x1D, 0x79, 0xDB, 0xEA, 0x04 + }, + { + 0x6B, 0x9D, 0x86, 0xF1, 0x5C, 0x09, 0x0A, 0x00, + 0xFC, 0x3D, 0x90, 0x7F, 0x90, 0x6C, 0x5E, 0xB7, + 0x92, 0x65, 0xE5, 0x8B, 0x88, 0xEB, 0x64, 0x29, + 0x4B, 0x4C, 0xC4, 0xE2, 0xB8, 0x9B, 0x1A, 0x7C, + 0x5E, 0xE3, 0x12, 0x7E, 0xD2, 0x1B, 0x45, 0x68, + 0x62, 0xDE, 0x6B, 0x2A, 0xBD, 0xA5, 0x9E, 0xAA, + 0xCF, 0x2D, 0xCB, 0xE9, 0x22, 0xCA, 0x75, 0x5E, + 0x40, 0x73, 0x5B, 0xE8, 0x1D, 0x9C, 0x88, 0xA5 + }, + { + 0x14, 0x6A, 0x18, 0x7A, 0x99, 0xE8, 0xA2, 0xD2, + 0x33, 0xE0, 0xEB, 0x37, 0x3D, 0x43, 0x7B, 0x02, + 0xBF, 0xA8, 0xD6, 0x51, 0x5B, 0x3C, 0xA1, 0xDE, + 0x48, 0xA6, 0xB6, 0xAC, 0xF7, 0x43, 0x7E, 0xB7, + 0xE7, 0xAC, 0x3F, 0x2D, 0x19, 0xEF, 0x3B, 0xB9, + 0xB8, 0x33, 0xCC, 0x57, 0x61, 0xDB, 0xA2, 0x2D, + 0x1A, 0xD0, 0x60, 0xBE, 0x76, 0xCD, 0xCB, 0x81, + 0x2D, 0x64, 0xD5, 0x78, 0xE9, 0x89, 0xA5, 0xA4 + }, + { + 0x25, 0x75, 0x4C, 0xA6, 0x66, 0x9C, 0x48, 0x70, + 0x84, 0x03, 0x88, 0xEA, 0x64, 0xE9, 0x5B, 0xD2, + 0xE0, 0x81, 0x0D, 0x36, 0x3C, 0x4C, 0xF6, 0xA1, + 0x6E, 0xA1, 0xBD, 0x06, 0x68, 0x6A, 0x93, 0xC8, + 0xA1, 0x25, 0xF2, 0x30, 0x22, 0x9D, 0x94, 0x84, + 0x85, 0xE1, 0xA8, 0x2D, 0xE4, 0x82, 0x00, 0x35, + 0x8F, 0x3E, 0x02, 0xB5, 0x05, 0xDA, 0xBC, 0x4F, + 0x13, 0x9C, 0x03, 0x79, 0xDC, 0x2B, 0x30, 0x80 + }, + { + 0x0E, 0x26, 0xCB, 0xC7, 0x8D, 0xC7, 0x54, 0xEC, + 0xA0, 0x6C, 0xF8, 0xCB, 0x31, 0xFC, 0xBA, 0xBB, + 0x18, 0x88, 0x92, 0xC1, 0x04, 0x50, 0x89, 0x05, + 0x49, 0xB2, 0xD4, 0x03, 0xA2, 0xA3, 0xC4, 0x57, + 0x70, 0x01, 0xF7, 0x4A, 0x76, 0xBD, 0x38, 0x99, + 0x0D, 0x75, 0x5B, 0xAE, 0x05, 0x26, 0x64, 0x83, + 0x29, 0xF6, 0x35, 0x45, 0xED, 0x16, 0x99, 0x5C, + 0xB1, 0xE6, 0x34, 0x3F, 0x18, 0x9F, 0x8E, 0x6F + }, + { + 0x58, 0xE7, 0x98, 0x0B, 0x8B, 0x1A, 0x0B, 0x88, + 0xDA, 0x9D, 0xA8, 0x64, 0x0F, 0x2B, 0x96, 0xE3, + 0xE0, 0x48, 0x36, 0x61, 0x30, 0xC2, 0x66, 0x21, + 0x7D, 0xDC, 0x79, 0x53, 0x50, 0x8F, 0x4A, 0x40, + 0xD1, 0x67, 0x4D, 0xAB, 0xD3, 0x92, 0x89, 0xE3, + 0xF1, 0x0C, 0x61, 0x19, 0x68, 0xCC, 0xD1, 0xE9, + 0xCC, 0xC1, 0x8C, 0xAD, 0xC7, 0x77, 0x4A, 0x99, + 0x7D, 0xD1, 0xFA, 0x94, 0xE8, 0x35, 0x47, 0x07 + }, + { + 0x69, 0x6F, 0xB8, 0x47, 0x63, 0xE0, 0x23, 0x58, + 0x4B, 0x35, 0x90, 0x7A, 0x8B, 0x8A, 0xAA, 0x9E, + 0x0E, 0x78, 0x6F, 0x2C, 0xA5, 0x91, 0x45, 0x41, + 0x91, 0x58, 0x48, 0xFB, 0x6D, 0xDA, 0xB8, 0xD3, + 0xD2, 0xEA, 0xB6, 0x00, 0xC1, 0x38, 0xCE, 0x67, + 0x17, 0xB0, 0xC7, 0x02, 0x59, 0xD3, 0x19, 0x3E, + 0xA1, 0x56, 0x95, 0xC8, 0x50, 0x53, 0x7F, 0x2C, + 0x70, 0x6C, 0xA4, 0xAF, 0x15, 0x8E, 0x95, 0x7E + }, + { + 0x23, 0xDE, 0x6E, 0x73, 0x07, 0x9C, 0x8C, 0x20, + 0x47, 0xA7, 0x84, 0x6A, 0x83, 0xCC, 0xAC, 0xAB, + 0xD3, 0x71, 0x16, 0x3B, 0x7B, 0x6D, 0x54, 0xEB, + 0x03, 0x2B, 0xC4, 0x9B, 0x66, 0x97, 0x42, 0xBE, + 0x71, 0x7B, 0x99, 0xDA, 0x12, 0xC6, 0x46, 0xAD, + 0x52, 0x57, 0x06, 0xF2, 0x22, 0xE1, 0xDF, 0x4A, + 0x91, 0xDD, 0x0C, 0xC6, 0x4D, 0xF1, 0x82, 0xDA, + 0x00, 0x73, 0x1D, 0x43, 0x9C, 0x46, 0xF8, 0xD2 + }, + { + 0xBB, 0x74, 0xF3, 0x6A, 0x9D, 0xB6, 0x96, 0xC9, + 0x33, 0x35, 0xE6, 0xC4, 0x6A, 0xAB, 0x58, 0xDB, + 0x10, 0xCB, 0x07, 0xEA, 0x4F, 0x1B, 0x71, 0x93, + 0x63, 0x05, 0x22, 0x83, 0x90, 0x95, 0x94, 0x78, + 0xF8, 0x73, 0x4E, 0x21, 0x54, 0x90, 0xE9, 0xAE, + 0x2A, 0x3E, 0xC8, 0xF7, 0xF7, 0x67, 0x33, 0xAE, + 0x3F, 0x8B, 0x9A, 0x3F, 0xD7, 0xC4, 0x06, 0xC6, + 0xCA, 0xC7, 0x09, 0x97, 0x5C, 0x40, 0xF8, 0x56 + }, + { + 0xEC, 0x63, 0x04, 0xD3, 0x8E, 0x23, 0x2C, 0x09, + 0x6A, 0xB5, 0x86, 0xCA, 0xDF, 0x27, 0x02, 0x6D, + 0xC5, 0xE5, 0x32, 0x17, 0xD0, 0xE8, 0xB0, 0xC6, + 0x0A, 0xDA, 0xAE, 0x22, 0xF4, 0xE8, 0xC2, 0x2D, + 0x30, 0xBC, 0x51, 0x77, 0xF1, 0xC8, 0x3A, 0xCD, + 0x92, 0x5E, 0x02, 0xA2, 0xDA, 0x89, 0x59, 0x5F, + 0xC1, 0x06, 0x09, 0x0E, 0x2E, 0x53, 0xED, 0xB3, + 0x1C, 0xDB, 0x76, 0xFF, 0x37, 0xEB, 0x61, 0x80 + }, + { + 0x92, 0xF9, 0xFC, 0x6B, 0xC5, 0x9A, 0x54, 0x3F, + 0x0D, 0xC9, 0xA1, 0x79, 0x8F, 0xB1, 0xE5, 0xD5, + 0x23, 0x47, 0x4E, 0x48, 0xFF, 0x3E, 0x29, 0x49, + 0x7F, 0x72, 0x80, 0xD1, 0xC4, 0x08, 0xC8, 0x66, + 0x33, 0x48, 0xFE, 0x2A, 0xF7, 0x8F, 0x6C, 0x4E, + 0x5E, 0xF5, 0xC0, 0xA0, 0x17, 0xF3, 0xD3, 0xF2, + 0x15, 0xEC, 0xDD, 0x7A, 0x40, 0x0A, 0xC5, 0x77, + 0x3B, 0x9E, 0x25, 0x60, 0x68, 0x84, 0x5A, 0x92 + }, + { + 0x4A, 0x25, 0xB5, 0x62, 0xF2, 0xFA, 0x01, 0xDD, + 0xEE, 0x7E, 0xA2, 0xE9, 0xFB, 0xF5, 0x2F, 0x8C, + 0x75, 0x6D, 0x28, 0xDB, 0x4A, 0x8B, 0xF7, 0x0E, + 0x74, 0x0E, 0x90, 0x27, 0x42, 0x6E, 0x51, 0x63, + 0x9D, 0xF8, 0x78, 0x8D, 0x13, 0x38, 0x56, 0x85, + 0x8D, 0x01, 0xFD, 0xDB, 0xDD, 0x5B, 0x98, 0x79, + 0x44, 0xC3, 0x00, 0xDC, 0x7F, 0x82, 0x41, 0xFB, + 0xCE, 0xFA, 0x4F, 0x12, 0x94, 0x8A, 0xFE, 0xAE + }, + { + 0x34, 0x21, 0x2D, 0xD9, 0xF0, 0x65, 0x1F, 0x81, + 0x80, 0x9A, 0x14, 0xED, 0xBC, 0xF7, 0xF3, 0xAC, + 0xDE, 0xDE, 0x78, 0x72, 0xC7, 0xA4, 0x84, 0x7B, + 0xEA, 0x9F, 0x7A, 0xB7, 0x59, 0x73, 0x82, 0x47, + 0x7A, 0x4C, 0xB8, 0x47, 0x9A, 0x27, 0x63, 0x21, + 0x23, 0x5E, 0x90, 0x21, 0x57, 0x94, 0x46, 0xA4, + 0x38, 0x8A, 0x99, 0xE5, 0x60, 0xA3, 0x90, 0x7A, + 0xEE, 0xF2, 0xB4, 0x38, 0xFE, 0x6B, 0x90, 0xC4 + }, + { + 0xD6, 0x2C, 0xF7, 0xAB, 0xBC, 0x7D, 0x7B, 0xCD, + 0x5B, 0xEB, 0x1E, 0xE4, 0x8C, 0x43, 0xB8, 0x04, + 0xFD, 0x0D, 0xB4, 0x55, 0xE7, 0xF4, 0xFE, 0xBB, + 0xCF, 0xF1, 0x4B, 0x05, 0xBE, 0x90, 0x47, 0xE2, + 0x7E, 0x51, 0x8D, 0x6D, 0x3A, 0x6A, 0xDA, 0x4D, + 0x58, 0x63, 0xB7, 0xEC, 0x7F, 0x84, 0x92, 0x45, + 0x89, 0x40, 0xAC, 0x6B, 0xDD, 0xB5, 0x06, 0x59, + 0x2C, 0xCB, 0xC8, 0x96, 0xAF, 0xBB, 0x77, 0xA3 + }, + { + 0x33, 0xA3, 0xA2, 0x63, 0x6F, 0x91, 0x98, 0xD3, + 0x7A, 0x5F, 0xF1, 0xBF, 0xF9, 0xEB, 0x10, 0x02, + 0x4B, 0x28, 0x46, 0x80, 0x39, 0xF4, 0x91, 0x40, + 0x2D, 0x39, 0xB7, 0x08, 0xC5, 0x5D, 0x27, 0xE5, + 0xE8, 0xDF, 0x5E, 0x3E, 0x19, 0x49, 0x95, 0x82, + 0x35, 0xCA, 0xD9, 0x80, 0x74, 0x20, 0x96, 0xF2, + 0x77, 0x9A, 0x1D, 0x71, 0xDA, 0xD5, 0x8F, 0xAF, + 0xA3, 0xCD, 0x02, 0xCB, 0x5E, 0xAA, 0x98, 0xC5 + }, + { + 0xB7, 0xA3, 0x89, 0x90, 0xE6, 0xF4, 0x56, 0x4A, + 0xA3, 0xD9, 0x3A, 0x79, 0x37, 0x10, 0x0C, 0x29, + 0xF9, 0x40, 0xAF, 0xF7, 0xCB, 0x20, 0x86, 0x5A, + 0x1C, 0x21, 0x89, 0x81, 0xA5, 0x42, 0x04, 0x86, + 0x08, 0x17, 0x81, 0xF8, 0xD5, 0x0C, 0x86, 0x62, + 0x5C, 0xC5, 0xD7, 0x6D, 0x0F, 0x5C, 0xCC, 0x4E, + 0xB6, 0x5D, 0x43, 0x66, 0x09, 0x62, 0x4F, 0x21, + 0xD0, 0x53, 0x39, 0xAB, 0x0C, 0xF7, 0x9F, 0x4C + }, + { + 0x9D, 0x66, 0x5A, 0x3F, 0xDD, 0x10, 0x45, 0x9E, + 0x77, 0xF0, 0x3A, 0xC8, 0xC0, 0xE2, 0x39, 0x01, + 0x94, 0x89, 0x69, 0x3C, 0xC9, 0x31, 0x5A, 0xA3, + 0xFF, 0x11, 0x29, 0x11, 0xD2, 0xAC, 0xF0, 0xB7, + 0xD2, 0x76, 0xAC, 0x76, 0x9B, 0xED, 0xFD, 0x85, + 0x2D, 0x28, 0x89, 0xDD, 0x12, 0xDB, 0x91, 0x39, + 0x8B, 0x01, 0xC4, 0xF4, 0xA5, 0xDA, 0x27, 0x80, + 0xB1, 0xDE, 0xFE, 0x0D, 0x95, 0xB6, 0x32, 0x70 + }, + { + 0x70, 0xFB, 0x9E, 0xFD, 0x5B, 0xCA, 0x7F, 0x19, + 0xB6, 0xE3, 0x1D, 0x64, 0x0D, 0xCF, 0x88, 0xD7, + 0x7E, 0x76, 0x8A, 0xE2, 0x27, 0xEC, 0xB3, 0xFD, + 0x6B, 0x47, 0x13, 0x78, 0x94, 0xF5, 0x49, 0xBF, + 0x1C, 0xF0, 0x6E, 0x5D, 0xB4, 0x54, 0x60, 0x44, + 0xDD, 0x9F, 0x46, 0x5C, 0x9C, 0x85, 0xF7, 0x28, + 0x4F, 0xE5, 0x4D, 0x2B, 0x71, 0x52, 0x69, 0x9B, + 0xE4, 0xBD, 0x55, 0x5A, 0x90, 0x9A, 0x88, 0xA9 + }, + { + 0x7A, 0xFD, 0xB0, 0x19, 0x30, 0x87, 0xE0, 0xC9, + 0xF8, 0xB4, 0xDD, 0x8B, 0x48, 0xD9, 0xF2, 0x0A, + 0xCE, 0x27, 0x13, 0xAF, 0xC7, 0x1B, 0xCC, 0x93, + 0x82, 0xB5, 0x42, 0x90, 0xAE, 0xBF, 0xFE, 0xB2, + 0xD1, 0x38, 0xF4, 0xDC, 0xF0, 0x28, 0xF9, 0xC4, + 0x3C, 0xC1, 0x80, 0x89, 0x84, 0x77, 0xA3, 0x9E, + 0x3F, 0x53, 0xA8, 0xD1, 0xBF, 0x67, 0xCE, 0xB6, + 0x08, 0x26, 0x1F, 0xAE, 0x6D, 0xDB, 0x1A, 0xBC + }, + { + 0x05, 0x99, 0x0D, 0x7D, 0x7D, 0xF1, 0xD4, 0x84, + 0xF5, 0xB1, 0xCA, 0xE9, 0xEE, 0x5D, 0xFC, 0xB4, + 0x3F, 0x2C, 0xBE, 0x18, 0x6C, 0x1A, 0x5B, 0x18, + 0x1A, 0x37, 0x31, 0xD4, 0xB1, 0x54, 0x8E, 0xBF, + 0xF5, 0xBF, 0x61, 0xCB, 0x0F, 0x6D, 0x9F, 0xC2, + 0x30, 0xF2, 0x5E, 0x86, 0x78, 0xB7, 0x99, 0xE0, + 0xE8, 0x30, 0x26, 0xA0, 0x86, 0x6B, 0xF0, 0xAC, + 0xAB, 0x08, 0x9E, 0x10, 0x2E, 0x67, 0xAB, 0x6B + }, + { + 0x1A, 0xF7, 0xA5, 0xCE, 0x58, 0x7C, 0x8D, 0x87, + 0xC7, 0xB7, 0x9F, 0xA3, 0xE7, 0x23, 0xD7, 0x4C, + 0xE0, 0x26, 0xB5, 0x28, 0x67, 0x52, 0xFD, 0x0C, + 0x37, 0x42, 0xC6, 0xF0, 0x41, 0x8E, 0xD7, 0x85, + 0x99, 0x0D, 0x21, 0xF2, 0x8D, 0xA8, 0x39, 0xCE, + 0x82, 0x12, 0xED, 0x55, 0x0C, 0x37, 0x3E, 0x6D, + 0x3A, 0x75, 0xD5, 0x5C, 0x31, 0x77, 0x04, 0x41, + 0xEE, 0xAF, 0xF2, 0xD5, 0x0F, 0x6E, 0x61, 0xB6 + }, + { + 0xDD, 0xEE, 0x0C, 0x76, 0xC9, 0xBD, 0xD3, 0x2D, + 0x70, 0x49, 0x35, 0x4C, 0xFC, 0x85, 0xDC, 0x68, + 0x67, 0xE2, 0x49, 0x2E, 0x47, 0xFE, 0xB0, 0x8E, + 0x39, 0x83, 0xD0, 0xB6, 0x78, 0x84, 0x5D, 0x7E, + 0xC6, 0xC9, 0x79, 0x3C, 0x33, 0x26, 0xBF, 0xDC, + 0x1E, 0x11, 0x32, 0x76, 0xD1, 0x77, 0xFE, 0x38, + 0x82, 0x52, 0x04, 0xDD, 0x00, 0x07, 0x39, 0x89, + 0xC0, 0x81, 0xCC, 0x3B, 0x71, 0xC6, 0x8D, 0x5F + }, + { + 0xDE, 0x07, 0x06, 0x48, 0xB3, 0x7C, 0x47, 0xDC, + 0x9F, 0x2F, 0x6D, 0x2A, 0xB2, 0x07, 0x73, 0xCD, + 0x82, 0xFA, 0x57, 0x25, 0xA6, 0x90, 0x0E, 0xB7, + 0x1C, 0xDD, 0xB0, 0xC9, 0xF3, 0x9B, 0x31, 0xDF, + 0x6D, 0x07, 0x73, 0x24, 0x6E, 0x8E, 0xF9, 0x03, + 0x49, 0x67, 0x75, 0x2D, 0xB7, 0xED, 0x22, 0x73, + 0x3F, 0x43, 0x79, 0x94, 0x8D, 0xC3, 0x96, 0xDC, + 0x35, 0xAD, 0xBB, 0xE9, 0xF6, 0x53, 0x77, 0x40 + }, + { + 0xA6, 0x45, 0x6F, 0xBC, 0xFF, 0x9E, 0x3D, 0x5B, + 0x11, 0x6A, 0x0E, 0x33, 0x1A, 0x1F, 0x97, 0x4F, + 0x07, 0x0E, 0x95, 0x56, 0x09, 0x78, 0x1F, 0xA5, + 0x99, 0xD6, 0x08, 0xA3, 0x1D, 0xA7, 0x6A, 0xD8, + 0xAB, 0xFE, 0x34, 0x66, 0x17, 0xC2, 0x57, 0x86, + 0x51, 0x3B, 0x2C, 0x44, 0xBF, 0xE2, 0xCB, 0x45, + 0x7C, 0x43, 0xFA, 0x6F, 0x45, 0x36, 0x1C, 0xA9, + 0xC6, 0x34, 0x13, 0x11, 0xB7, 0xDD, 0xFB, 0xD5 + }, + { + 0x5C, 0x95, 0xD3, 0x82, 0x02, 0x18, 0x91, 0x04, + 0x8B, 0x5E, 0xC8, 0x1C, 0xC8, 0x8E, 0x66, 0xB1, + 0xB4, 0xD8, 0x0A, 0x00, 0xB5, 0xEE, 0x66, 0xB3, + 0xC0, 0x30, 0x77, 0x49, 0xE6, 0xF2, 0x4D, 0x17, + 0x0D, 0x23, 0xFA, 0xCC, 0x8E, 0xB2, 0x53, 0xB3, + 0x56, 0x2B, 0xF8, 0xA4, 0x5C, 0x37, 0x99, 0x0C, + 0xD2, 0xD3, 0xE4, 0x43, 0xB1, 0x8C, 0x68, 0xBB, + 0xCC, 0x6C, 0x83, 0x1D, 0xFD, 0xE2, 0xF8, 0xE5 + }, + { + 0xE3, 0x74, 0x00, 0xDB, 0xD9, 0x21, 0x0F, 0x31, + 0x37, 0xAC, 0xAF, 0x49, 0x24, 0x2F, 0xA1, 0x23, + 0xA0, 0x52, 0x95, 0x8A, 0x4C, 0x0D, 0x98, 0x90, + 0x62, 0x47, 0xD5, 0x35, 0xA3, 0x51, 0xFD, 0x52, + 0x29, 0x6E, 0x70, 0x10, 0x32, 0x5B, 0xDA, 0x84, + 0x1F, 0xA2, 0xAA, 0xB4, 0x47, 0x63, 0x76, 0x3C, + 0x55, 0x04, 0xD7, 0xB3, 0x0C, 0x6D, 0x79, 0xFC, + 0x1D, 0xC8, 0xCF, 0x10, 0x24, 0x46, 0x6D, 0xB0 + }, + { + 0x52, 0x73, 0xA3, 0xA1, 0x3C, 0xF0, 0xEC, 0x72, + 0x00, 0x44, 0x2C, 0xBD, 0x7B, 0x37, 0x44, 0x66, + 0xA7, 0x19, 0x0D, 0xDC, 0xA1, 0x31, 0xD9, 0x63, + 0xF8, 0xF8, 0x39, 0x65, 0xAE, 0xD3, 0xDD, 0x86, + 0xE9, 0xD4, 0x5A, 0xB4, 0x89, 0xB9, 0xC5, 0x62, + 0x47, 0xC9, 0xF2, 0xAA, 0x69, 0xFD, 0x7E, 0x31, + 0x87, 0xB8, 0xFA, 0x0D, 0xAC, 0x77, 0xC4, 0x7C, + 0xB2, 0x95, 0xBA, 0x62, 0x96, 0x78, 0x43, 0x94 + }, + { + 0x2A, 0xDB, 0x93, 0x49, 0xA9, 0xEC, 0x37, 0xFF, + 0x49, 0x62, 0xF4, 0x21, 0x7E, 0x80, 0xEB, 0xDC, + 0xD3, 0x60, 0x96, 0x7B, 0x51, 0x3D, 0x12, 0x02, + 0xD9, 0x98, 0x28, 0x31, 0x15, 0x5D, 0x2F, 0x43, + 0xEB, 0x9A, 0xDD, 0x63, 0xB5, 0xEC, 0x10, 0xD3, + 0xD0, 0x43, 0x0D, 0xC9, 0xCF, 0x76, 0x48, 0x11, + 0x7F, 0xC6, 0x0B, 0xAB, 0xBF, 0x8E, 0xBF, 0x19, + 0xFA, 0xCE, 0xE5, 0x50, 0x45, 0x5B, 0x60, 0xC9 + }, + { + 0xAC, 0xAA, 0xDA, 0x3E, 0x47, 0x37, 0xC6, 0x63, + 0xEB, 0xF0, 0x3C, 0x02, 0x49, 0xCC, 0xA6, 0xF3, + 0x17, 0x9A, 0x03, 0x84, 0xEA, 0x2A, 0xB1, 0x35, + 0xD4, 0xD7, 0xA2, 0xBB, 0x8A, 0x2F, 0x40, 0x53, + 0x9C, 0xDC, 0xE8, 0xA3, 0x76, 0x0F, 0xD1, 0x3D, + 0xEE, 0xEC, 0xD1, 0x60, 0x61, 0x7F, 0x72, 0xDE, + 0x63, 0x75, 0x4E, 0x21, 0x57, 0xCA, 0xDC, 0xF0, + 0x67, 0x32, 0x9C, 0x2A, 0x51, 0x98, 0xF8, 0xE0 + }, + { + 0xEF, 0x15, 0xE6, 0xDB, 0x96, 0xE6, 0xD0, 0xC1, + 0x8C, 0x70, 0xAD, 0xC3, 0xCD, 0xB3, 0x2B, 0x28, + 0x67, 0x74, 0x02, 0xE8, 0xEA, 0x44, 0x11, 0xEA, + 0x2F, 0x34, 0x68, 0xED, 0x93, 0x82, 0xE1, 0x9B, + 0xFE, 0xCA, 0xF5, 0xAC, 0xB8, 0x28, 0xA5, 0x2B, + 0xE1, 0x6B, 0x98, 0x1E, 0x48, 0x7E, 0x5B, 0xB4, + 0xA1, 0x43, 0x08, 0x65, 0x35, 0x8E, 0x97, 0x9F, + 0xB1, 0x07, 0x1F, 0xB9, 0x51, 0x14, 0xFF, 0xDD + }, + { + 0x05, 0x7E, 0xAB, 0x8F, 0xA6, 0x1C, 0x23, 0x09, + 0x67, 0xD9, 0x5D, 0xFB, 0x75, 0x45, 0x57, 0x0E, + 0x34, 0x1A, 0xE3, 0xC6, 0x73, 0x7C, 0x7D, 0xB2, + 0xA2, 0x27, 0xD9, 0x0F, 0xF3, 0x15, 0xD0, 0x98, + 0xD4, 0x76, 0xF7, 0x15, 0x77, 0x9E, 0x67, 0x72, + 0xB4, 0xED, 0x37, 0x54, 0x82, 0x66, 0xE6, 0x59, + 0x8C, 0x6F, 0x09, 0x69, 0x13, 0xC2, 0xFD, 0xD8, + 0xD6, 0xE4, 0x4F, 0xE2, 0xB5, 0x4D, 0x97, 0x80 + }, + { + 0xED, 0xE6, 0x8D, 0x1B, 0x13, 0xE7, 0xEF, 0x78, + 0xD9, 0xC4, 0xEE, 0x10, 0xEC, 0xEB, 0x1D, 0x2A, + 0xEE, 0xC3, 0xB8, 0x15, 0x7F, 0xDB, 0x91, 0x41, + 0x8C, 0x22, 0x19, 0xF6, 0x41, 0x49, 0x74, 0x70, + 0x17, 0xAC, 0xA7, 0xD4, 0x65, 0xB8, 0xB4, 0x7F, + 0xFA, 0x53, 0x64, 0x4B, 0x8B, 0xC6, 0xDA, 0x12, + 0xDD, 0x45, 0xD1, 0x05, 0x5E, 0x47, 0xB4, 0xD8, + 0x39, 0x0E, 0xB2, 0xBD, 0x60, 0x2B, 0xA0, 0x30 + }, + { + 0x27, 0xF8, 0x56, 0xE6, 0x3E, 0xB9, 0x4D, 0x08, + 0xFB, 0xBE, 0x50, 0x22, 0xB0, 0xED, 0xDB, 0xC7, + 0xD8, 0xDB, 0x86, 0x5E, 0xF4, 0xFE, 0xC2, 0x05, + 0x86, 0xDF, 0x3D, 0xD9, 0x02, 0xA0, 0x5B, 0x26, + 0x35, 0x9E, 0x26, 0x7C, 0x78, 0x8D, 0x7C, 0x88, + 0x03, 0x2E, 0x76, 0x6B, 0x11, 0x87, 0x40, 0x20, + 0x0F, 0x49, 0xCB, 0x4D, 0x6E, 0xDB, 0x15, 0x61, + 0xB2, 0xDE, 0x7D, 0xC6, 0x5E, 0xE6, 0x42, 0x3B + }, + { + 0xE9, 0xE9, 0x8D, 0x6D, 0xE0, 0xEF, 0x53, 0xFD, + 0x24, 0x27, 0x66, 0x1E, 0x1A, 0xCF, 0x10, 0x3D, + 0x4C, 0xAA, 0x4D, 0xC6, 0x10, 0x03, 0x62, 0x09, + 0xEC, 0x99, 0x74, 0x19, 0xC1, 0x20, 0x63, 0x1C, + 0x2C, 0x09, 0x4A, 0x8E, 0xE7, 0x82, 0x2D, 0x43, + 0xF8, 0x77, 0x80, 0x11, 0xC6, 0x03, 0x11, 0x1F, + 0x26, 0x28, 0xF8, 0x97, 0xC9, 0xB4, 0x31, 0x31, + 0x54, 0x77, 0x75, 0x6B, 0x03, 0x2E, 0x1F, 0x8D + }, + { + 0x52, 0xEB, 0x1E, 0x6C, 0x8A, 0x54, 0x49, 0x2C, + 0xA7, 0x60, 0xB5, 0x6C, 0xA8, 0x7D, 0xA3, 0xE1, + 0xA9, 0xA6, 0xD8, 0xA4, 0x21, 0x92, 0x19, 0x35, + 0x1D, 0x18, 0x71, 0x5A, 0x9A, 0x2C, 0x26, 0x70, + 0x8B, 0xB7, 0x12, 0xCD, 0xAC, 0x04, 0x34, 0x48, + 0x2E, 0x55, 0x1C, 0xB0, 0x9E, 0x3F, 0x16, 0x33, + 0x8D, 0xE2, 0x9B, 0xE2, 0xC6, 0x67, 0x40, 0xC3, + 0x44, 0xDF, 0x54, 0x88, 0xC5, 0xC2, 0xBB, 0x26 + }, + { + 0x47, 0x3F, 0xA6, 0xC5, 0x1A, 0x48, 0x10, 0x5F, + 0x72, 0x1C, 0x5C, 0xB8, 0xDB, 0xA6, 0x1C, 0x64, + 0xA1, 0xE3, 0xDD, 0xCC, 0xC3, 0x25, 0x0E, 0x68, + 0x22, 0x62, 0xF2, 0x12, 0xC0, 0x1A, 0xB4, 0x87, + 0x4A, 0xFF, 0x68, 0x8F, 0xEA, 0x96, 0x37, 0x73, + 0x9E, 0x2A, 0x25, 0xD2, 0xEE, 0x88, 0xDB, 0xDC, + 0xC4, 0xF0, 0x4D, 0x01, 0x47, 0x9B, 0x30, 0x17, + 0x17, 0x53, 0x3A, 0x64, 0x32, 0xB8, 0x50, 0xCD + }, + { + 0x6B, 0x76, 0x60, 0xD4, 0x10, 0xEA, 0xE5, 0xF3, + 0x5A, 0xD0, 0xAE, 0x85, 0xE6, 0x3D, 0xA4, 0x53, + 0xEB, 0xB0, 0x57, 0xE4, 0x3F, 0x42, 0xE8, 0x42, + 0xCB, 0xF6, 0x25, 0x0D, 0xA6, 0x78, 0x66, 0xB4, + 0x24, 0x0D, 0x57, 0xC8, 0x3B, 0x77, 0x1B, 0x0F, + 0x70, 0x66, 0x3E, 0x17, 0xFB, 0xD9, 0x08, 0x7F, + 0x76, 0xB4, 0xCE, 0x6B, 0xCD, 0x0B, 0x50, 0x2E, + 0x33, 0x74, 0xB1, 0x50, 0x9B, 0xBA, 0x55, 0xA8 + }, + { + 0xA4, 0xD0, 0x8A, 0xCA, 0x7A, 0x9E, 0xA6, 0x43, + 0x99, 0x99, 0xEA, 0x21, 0xE4, 0xCF, 0xE9, 0x86, + 0x9B, 0xB9, 0x0E, 0x3A, 0x01, 0x48, 0x71, 0xAD, + 0x88, 0xED, 0x3A, 0x97, 0xAA, 0x89, 0x15, 0x95, + 0x1C, 0x3F, 0xD0, 0xB3, 0x93, 0x3A, 0x50, 0x85, + 0x88, 0x93, 0x8A, 0xF7, 0x54, 0x49, 0x44, 0xEF, + 0x43, 0xC4, 0x40, 0xAA, 0x8F, 0xF1, 0xE5, 0xA8, + 0x18, 0xA4, 0x66, 0x43, 0x5D, 0xE7, 0x0F, 0xA8 + }, + { + 0x85, 0xE0, 0xE9, 0xB5, 0x0D, 0x2D, 0xB0, 0x22, + 0xC2, 0x39, 0xD7, 0x23, 0x2A, 0xE4, 0x7C, 0x02, + 0x59, 0x22, 0xE4, 0xF0, 0x7E, 0x2A, 0xFC, 0x65, + 0x6C, 0xDC, 0x55, 0x53, 0xA2, 0x7D, 0x95, 0xBF, + 0xA5, 0x8A, 0x57, 0x4D, 0x4E, 0xC3, 0xA9, 0x73, + 0x28, 0x1A, 0x8F, 0x4E, 0x46, 0xA7, 0x1A, 0xB0, + 0x34, 0x1C, 0x25, 0x77, 0x28, 0x74, 0x63, 0xE2, + 0x51, 0x04, 0x4D, 0xB2, 0x39, 0x8D, 0x55, 0xE2 + }, + { + 0x81, 0xA0, 0xD0, 0x24, 0x42, 0x90, 0x51, 0x91, + 0x16, 0x33, 0x70, 0xAE, 0x29, 0xC7, 0xF8, 0x9C, + 0x0F, 0x48, 0xBC, 0x1A, 0x1E, 0xB2, 0x94, 0x70, + 0x47, 0xDA, 0x1C, 0x62, 0x2B, 0x86, 0x77, 0xE9, + 0xEA, 0x9B, 0xEC, 0xED, 0x55, 0xD3, 0x3A, 0xDB, + 0x15, 0x53, 0xBD, 0x58, 0x4A, 0xD2, 0xF8, 0x6A, + 0x62, 0x07, 0xE8, 0x4E, 0x40, 0xE4, 0x60, 0x7E, + 0x11, 0x65, 0x0E, 0xE2, 0x87, 0x9F, 0x4E, 0x0B + }, + { + 0x87, 0x79, 0x0D, 0xF6, 0xCF, 0x73, 0x94, 0x45, + 0x1B, 0xCC, 0x73, 0x0E, 0x53, 0xFC, 0x57, 0xBE, + 0x56, 0x45, 0x22, 0x77, 0x1E, 0x14, 0x43, 0x2A, + 0x80, 0xAB, 0x0B, 0x06, 0xB7, 0xB1, 0xD2, 0x09, + 0xAD, 0x69, 0x89, 0x95, 0x12, 0x53, 0x85, 0xDB, + 0x8B, 0x3C, 0x09, 0x59, 0xB8, 0xA5, 0x33, 0x9E, + 0xDA, 0x0A, 0xE6, 0x78, 0x59, 0xD8, 0x47, 0xF4, + 0x4C, 0x81, 0x59, 0x72, 0x72, 0xCB, 0xF1, 0x95 + }, + { + 0xCC, 0x06, 0x4E, 0xA8, 0x53, 0xDC, 0x01, 0x52, + 0xCC, 0x03, 0xFE, 0xB5, 0xFB, 0x5D, 0xE7, 0x8B, + 0x9B, 0x88, 0xE9, 0x61, 0x55, 0xD5, 0x35, 0x8B, + 0xCE, 0x84, 0xA5, 0x4C, 0x0E, 0x0C, 0x42, 0xFB, + 0xDA, 0x09, 0x2F, 0x22, 0xD0, 0x56, 0xDF, 0x99, + 0x93, 0x26, 0x2E, 0x2B, 0xA4, 0x4A, 0x5B, 0x2D, + 0x53, 0xC3, 0x75, 0x9D, 0x09, 0x45, 0xFE, 0xBA, + 0xA6, 0xFD, 0x51, 0xB8, 0xFF, 0x38, 0xD8, 0x39 + }, + { + 0x7E, 0x51, 0x7F, 0xC3, 0x83, 0xEE, 0x8C, 0x9F, + 0x0A, 0x01, 0x68, 0x1D, 0x39, 0xE7, 0x3B, 0xEB, + 0xA5, 0x96, 0x95, 0x95, 0xCE, 0x77, 0x92, 0x7F, + 0x91, 0x69, 0x1F, 0x33, 0xBB, 0x3E, 0x13, 0x07, + 0xEE, 0x03, 0x61, 0x6C, 0x27, 0xE6, 0x79, 0x51, + 0x86, 0xF6, 0x94, 0x0F, 0xED, 0xD9, 0xD5, 0xC7, + 0xF2, 0x1B, 0x6D, 0x2A, 0xAF, 0x70, 0x29, 0x9C, + 0xDD, 0x83, 0x51, 0x25, 0x05, 0x0A, 0x8B, 0x3C + }, + { + 0x84, 0x5F, 0xCF, 0xA6, 0x7F, 0x6E, 0x06, 0x55, + 0x10, 0xD2, 0x62, 0xF1, 0xDD, 0x69, 0x39, 0xEA, + 0x4C, 0x0A, 0x4A, 0x59, 0xC8, 0xEE, 0x39, 0x77, + 0xDB, 0x70, 0x05, 0xE1, 0xAE, 0xE4, 0x20, 0xBD, + 0x3F, 0x38, 0x26, 0xEC, 0xFE, 0x59, 0x01, 0x5B, + 0x4D, 0xFA, 0x0B, 0xD5, 0xBB, 0xF8, 0xD8, 0xA4, + 0x34, 0x48, 0x5D, 0xC1, 0x1C, 0xB9, 0xCC, 0x85, + 0x97, 0xCB, 0x8C, 0x95, 0x66, 0x11, 0x5F, 0x31 + }, + { + 0x17, 0xCF, 0x2C, 0x23, 0x21, 0x5B, 0xCD, 0xFC, + 0x24, 0x3D, 0x8A, 0x94, 0x5F, 0x3C, 0x5C, 0x25, + 0x1D, 0x27, 0x18, 0xA3, 0xF7, 0x5F, 0xED, 0x6F, + 0x33, 0x20, 0xBC, 0xC6, 0xFD, 0x92, 0x73, 0x86, + 0xD5, 0x6F, 0x87, 0x19, 0xCC, 0xA0, 0x2E, 0xC5, + 0xE9, 0x9C, 0xDA, 0xC4, 0xEA, 0x10, 0x95, 0xB4, + 0x65, 0xBA, 0x9A, 0x29, 0x8B, 0x1D, 0x23, 0x8E, + 0x38, 0xB3, 0xFA, 0x15, 0xE8, 0xB1, 0x4E, 0xE4 + }, + { + 0xD7, 0x89, 0xCE, 0xC7, 0xD7, 0x52, 0x0F, 0x10, + 0xE8, 0xB8, 0xB6, 0xC8, 0x40, 0x95, 0x89, 0xDF, + 0x57, 0xB8, 0x56, 0xB8, 0x24, 0x55, 0x68, 0xF6, + 0x4E, 0x2D, 0x21, 0x83, 0xE3, 0x59, 0xA7, 0x84, + 0xC8, 0xD2, 0x6C, 0xF9, 0xB7, 0x20, 0xF5, 0xDF, + 0x56, 0x7B, 0x01, 0xF3, 0xF4, 0x8D, 0xE6, 0x4D, + 0x4F, 0x0D, 0xB1, 0x56, 0xBE, 0x52, 0x5D, 0x7C, + 0x7A, 0x66, 0x5A, 0xAD, 0xC5, 0x91, 0xF0, 0xB6 + }, + { + 0xB5, 0xE2, 0x46, 0xA9, 0x02, 0x77, 0x10, 0xC0, + 0xB0, 0x55, 0xC7, 0x1F, 0x11, 0x67, 0xE0, 0xEE, + 0x36, 0xEB, 0xC4, 0x32, 0xCF, 0x5D, 0x14, 0x27, + 0x75, 0xA7, 0xAE, 0xCC, 0xCE, 0xA7, 0x83, 0x25, + 0xED, 0x8C, 0x12, 0xF5, 0x0F, 0xBE, 0x64, 0x8A, + 0xDD, 0xF0, 0x59, 0xB8, 0xC0, 0x2A, 0x61, 0x49, + 0x2F, 0x83, 0x57, 0xBE, 0xE1, 0x42, 0xE7, 0xF7, + 0xDE, 0x04, 0x33, 0x78, 0xDB, 0xCF, 0x2D, 0x33 + }, + { + 0xB5, 0x23, 0xFD, 0x77, 0xAB, 0x9E, 0xEE, 0x42, + 0x48, 0x72, 0xBC, 0x2E, 0x83, 0xFC, 0x0A, 0x77, + 0xFF, 0x8A, 0x90, 0xC9, 0xA0, 0xCE, 0x9E, 0x8C, + 0x87, 0x68, 0x0A, 0x0F, 0x62, 0x86, 0x33, 0x1F, + 0x15, 0xC9, 0x3A, 0x2A, 0xFE, 0xCF, 0x75, 0x66, + 0x65, 0x3F, 0x24, 0xD9, 0x30, 0xC3, 0x23, 0x19, + 0x2D, 0x30, 0x43, 0xB9, 0x05, 0x72, 0x1C, 0xBD, + 0xB6, 0x31, 0x11, 0xCA, 0x42, 0xF2, 0x8F, 0x4E + }, + { + 0x43, 0x59, 0xA4, 0x58, 0x76, 0xBF, 0x6A, 0xCC, + 0x0A, 0xEC, 0xE7, 0xB9, 0xB4, 0xB4, 0xA8, 0x38, + 0xB9, 0xDB, 0xA5, 0x77, 0x6A, 0x3B, 0x14, 0xDA, + 0x2F, 0xBA, 0x91, 0x02, 0xE7, 0x8B, 0xF6, 0x48, + 0xFF, 0xB4, 0xD8, 0x67, 0xBA, 0xE8, 0x5F, 0xD9, + 0xB7, 0x13, 0x12, 0xDC, 0x46, 0x02, 0xD0, 0xD4, + 0x9C, 0x90, 0x7B, 0xB9, 0x28, 0x9B, 0x22, 0x95, + 0x96, 0x1E, 0x54, 0x13, 0x81, 0x23, 0xF5, 0x4A + }, + { + 0xD3, 0xF2, 0xC8, 0xE7, 0x4F, 0x34, 0x3A, 0x4E, + 0x71, 0x90, 0xD4, 0x75, 0xCF, 0x9A, 0xF7, 0x54, + 0xEE, 0xD5, 0x57, 0x72, 0x62, 0xB3, 0x5B, 0xD9, + 0xA9, 0xC4, 0x2B, 0x58, 0xCE, 0x88, 0x26, 0x2E, + 0x31, 0x14, 0x91, 0x7F, 0xB9, 0xE6, 0x83, 0xC6, + 0x2D, 0x9F, 0x89, 0x47, 0xB5, 0x8A, 0x29, 0x4D, + 0xA5, 0x06, 0xFB, 0x86, 0xB3, 0xED, 0xF2, 0x5C, + 0xB9, 0xE2, 0xD2, 0xDF, 0x61, 0x1C, 0xD4, 0x48 + }, + { + 0x41, 0xB8, 0x90, 0xF8, 0xE8, 0x45, 0x0D, 0xAD, + 0xB6, 0x95, 0x9A, 0xCC, 0xBA, 0x19, 0x49, 0x17, + 0xE0, 0x2F, 0x30, 0x67, 0x82, 0x1D, 0x4E, 0x99, + 0x5A, 0x37, 0xAC, 0x18, 0xBA, 0x3E, 0x47, 0xC7, + 0x50, 0x6E, 0x7A, 0x3D, 0xD1, 0xE1, 0x12, 0xE6, + 0xEC, 0x41, 0xBE, 0xF5, 0x30, 0x85, 0x11, 0x20, + 0x89, 0x4A, 0x7B, 0x34, 0xB3, 0xDB, 0xCD, 0xAE, + 0x40, 0x73, 0x27, 0xF0, 0xC5, 0x73, 0x6E, 0xDF + }, + { + 0x19, 0xD7, 0x14, 0x4F, 0x0C, 0x85, 0x1E, 0xB8, + 0xB0, 0x53, 0xA3, 0xA4, 0x35, 0x86, 0x52, 0x6D, + 0xC5, 0xC7, 0x73, 0xE4, 0x97, 0x97, 0x51, 0x64, + 0xD1, 0x11, 0x51, 0x36, 0x43, 0x68, 0xDF, 0x24, + 0xBC, 0x44, 0xD5, 0x36, 0x07, 0x23, 0x04, 0xD7, + 0x06, 0x31, 0xA8, 0x40, 0xB6, 0x36, 0xB9, 0x66, + 0xFD, 0x02, 0x8F, 0x61, 0x06, 0x2B, 0xFC, 0x52, + 0x85, 0x67, 0x01, 0x53, 0xA6, 0x36, 0x3A, 0x0A + }, + { + 0xC2, 0x18, 0x4C, 0x1A, 0x81, 0xE9, 0x83, 0xBE, + 0x2C, 0x96, 0xE4, 0xCF, 0xD6, 0x5A, 0xFB, 0xDA, + 0x1A, 0xC6, 0xEF, 0x35, 0x26, 0x6E, 0xE4, 0xB3, + 0xAB, 0x1F, 0xB0, 0x3A, 0xBA, 0xDD, 0xFD, 0xD4, + 0x03, 0xFF, 0xFC, 0xAF, 0xB4, 0xAD, 0xE0, 0xE9, + 0x2D, 0xA3, 0x82, 0xDA, 0x8C, 0x40, 0x22, 0x2E, + 0x10, 0xE9, 0xFD, 0xE8, 0x56, 0xC5, 0x1B, 0xDA, + 0xCD, 0xE7, 0x41, 0xA6, 0x49, 0xF7, 0x33, 0x5D + }, + { + 0x48, 0x8C, 0x0D, 0x65, 0x2E, 0x42, 0xFD, 0x78, + 0xAB, 0x3A, 0x2D, 0xC2, 0x8C, 0xF3, 0xEB, 0x35, + 0xFC, 0xDD, 0xC8, 0xDE, 0xF7, 0xEA, 0xD4, 0x81, + 0x7B, 0xFF, 0xB6, 0x4C, 0x1A, 0xE0, 0xF2, 0x08, + 0xF7, 0x8C, 0xF4, 0x09, 0x76, 0xF7, 0xE2, 0xA2, + 0xCB, 0x2D, 0xD3, 0x0F, 0x1C, 0x99, 0x13, 0x02, + 0x08, 0xCE, 0xB6, 0x92, 0xC6, 0x68, 0x80, 0xD9, + 0x52, 0x8C, 0xD6, 0xD3, 0x8A, 0xD2, 0x9D, 0xB2 + }, + { + 0x51, 0x5B, 0x65, 0xBF, 0x65, 0x68, 0x83, 0x99, + 0x57, 0x5F, 0x0E, 0x06, 0x77, 0xBB, 0x6A, 0x91, + 0x9B, 0x66, 0x33, 0x55, 0x46, 0xD6, 0xCA, 0xE3, + 0x36, 0xF5, 0xC6, 0xFE, 0xAE, 0x5E, 0x2B, 0xF7, + 0x45, 0xE3, 0xA7, 0xB1, 0x3C, 0x32, 0x05, 0xDD, + 0x8B, 0x5B, 0x92, 0xCF, 0x05, 0x3B, 0xE9, 0x69, + 0xDF, 0x71, 0x20, 0xFC, 0xEF, 0x77, 0xE3, 0x89, + 0x5F, 0x56, 0x0F, 0xD2, 0x32, 0xFB, 0x89, 0x50 + }, + { + 0x3F, 0xDB, 0xC7, 0xD6, 0x9F, 0x4B, 0x53, 0xC2, + 0x25, 0x66, 0x3D, 0xA3, 0x0D, 0x80, 0xF7, 0x2E, + 0x54, 0x28, 0x10, 0x44, 0xA2, 0x2B, 0x98, 0x82, + 0xC6, 0x63, 0x8F, 0x55, 0x26, 0x83, 0x4B, 0xD3, + 0x16, 0x01, 0xCA, 0x5E, 0xB2, 0xCC, 0xA4, 0xF5, + 0xFF, 0xCF, 0x67, 0x5D, 0xCB, 0xCF, 0xCA, 0x60, + 0xC8, 0xA3, 0x61, 0x2D, 0x1A, 0xA9, 0xDA, 0xB6, + 0x93, 0xB2, 0x35, 0x60, 0x69, 0x60, 0x3A, 0x0E + }, + { + 0x4F, 0xF6, 0xC3, 0x1A, 0x8F, 0xC0, 0x01, 0xAC, + 0x3B, 0x7A, 0xE0, 0x20, 0xC5, 0xF7, 0xC4, 0x5E, + 0xFB, 0x62, 0x71, 0xA2, 0xD7, 0xCC, 0xAB, 0x87, + 0x13, 0xE5, 0x48, 0xB7, 0x29, 0xF0, 0xFF, 0xF9, + 0xC8, 0x2F, 0xD4, 0xDB, 0x5C, 0xF6, 0x56, 0x43, + 0xD4, 0x07, 0x6A, 0x3F, 0xB1, 0x7B, 0x3E, 0x89, + 0x3C, 0x30, 0x2D, 0xC7, 0x5B, 0x61, 0x22, 0xFF, + 0x86, 0x81, 0xD0, 0x37, 0x12, 0x0E, 0x27, 0x6A + }, + { + 0x43, 0xDF, 0xF2, 0x60, 0xDF, 0xEF, 0x1C, 0xB2, + 0xD6, 0x16, 0x00, 0xE2, 0x40, 0xAA, 0xD6, 0xB7, + 0x20, 0xE5, 0xF4, 0xF8, 0x30, 0x86, 0xE2, 0x6A, + 0x49, 0xA0, 0xCE, 0x3E, 0x0C, 0xA4, 0x4B, 0x9A, + 0x60, 0xFC, 0xF4, 0x6A, 0x8C, 0x3F, 0x1B, 0xB1, + 0xA6, 0xF5, 0x76, 0x2B, 0x66, 0x51, 0x3F, 0xE3, + 0xF7, 0xC5, 0xB0, 0xBC, 0x15, 0x0C, 0x08, 0x49, + 0x1A, 0xCB, 0xC4, 0x36, 0x1C, 0xAB, 0xCF, 0xDF + }, + { + 0xB4, 0xDE, 0xA9, 0x4C, 0x9D, 0x36, 0x75, 0xBE, + 0x05, 0x12, 0xEF, 0xDE, 0xA8, 0x16, 0x38, 0x70, + 0xFE, 0x34, 0x25, 0xDC, 0xD7, 0x61, 0xF3, 0x63, + 0xC4, 0x3A, 0x0C, 0xA5, 0x71, 0x6B, 0x76, 0x54, + 0x06, 0x63, 0xFB, 0x2B, 0xE4, 0x9E, 0x2D, 0xB1, + 0x06, 0x48, 0x5C, 0x9C, 0xDD, 0x3C, 0x16, 0x48, + 0x98, 0xA9, 0x54, 0xB5, 0x87, 0x48, 0xC4, 0x2F, + 0xEA, 0x16, 0xA4, 0x0F, 0xC4, 0x53, 0xD2, 0x10 + }, + { + 0xE5, 0x27, 0x7B, 0x6F, 0x93, 0xEA, 0x1D, 0xE3, + 0xE2, 0xD9, 0xFC, 0xD8, 0xC6, 0x79, 0x79, 0x3C, + 0x6C, 0xCB, 0x8A, 0x3B, 0xE2, 0x6E, 0x8E, 0x31, + 0x14, 0xF3, 0x5D, 0xA4, 0xF2, 0xAC, 0x01, 0x4F, + 0x55, 0xC2, 0xF1, 0x5E, 0x09, 0xE9, 0x4A, 0xA0, + 0x71, 0x29, 0x81, 0x67, 0xA2, 0xFB, 0x9B, 0xE3, + 0x11, 0x70, 0x1F, 0xFB, 0xA9, 0xD3, 0xEE, 0xFF, + 0x8F, 0xFC, 0x79, 0x93, 0xA3, 0xCE, 0xCE, 0x18 + }, + { + 0xF0, 0x95, 0xA7, 0xC6, 0xE2, 0xB9, 0x16, 0x64, + 0x73, 0x4F, 0x3E, 0x23, 0xF1, 0x8E, 0xB2, 0xBA, + 0x9B, 0x00, 0xE7, 0x1F, 0xBF, 0xCB, 0x99, 0x31, + 0xC0, 0xA6, 0x14, 0x79, 0x2A, 0x9D, 0x86, 0x75, + 0x62, 0x2A, 0x87, 0x4C, 0x1B, 0xF5, 0x24, 0x1A, + 0x2A, 0x87, 0x41, 0xED, 0x1C, 0x89, 0x3B, 0xDF, + 0xA8, 0xE2, 0x8C, 0x2E, 0x20, 0xBB, 0x1C, 0x58, + 0xEB, 0x4D, 0xE7, 0xD8, 0x01, 0x11, 0x6C, 0x78 + }, + { + 0xDF, 0xA1, 0xFD, 0x80, 0x3A, 0x1D, 0x4A, 0x3E, + 0x66, 0x1D, 0xF0, 0x1F, 0x49, 0x43, 0xEA, 0x66, + 0x26, 0x0A, 0x18, 0xFE, 0xCE, 0x13, 0x4D, 0x62, + 0xF9, 0x7D, 0xAC, 0xDB, 0x8B, 0x3B, 0xF9, 0xC8, + 0x00, 0xAF, 0xE5, 0x79, 0xCF, 0xD1, 0x3F, 0xC0, + 0x14, 0x8B, 0xDE, 0xFB, 0xFF, 0x4E, 0x76, 0x83, + 0x56, 0x1C, 0x06, 0xA6, 0xF7, 0x22, 0x5E, 0x47, + 0x81, 0x99, 0x3B, 0x4F, 0x4F, 0x2B, 0xCB, 0xFA + }, + { + 0x2B, 0x86, 0xCE, 0xB2, 0x70, 0xF6, 0x90, 0x8D, + 0x8B, 0x16, 0x00, 0x75, 0xEA, 0x7F, 0x57, 0x16, + 0x3A, 0xF5, 0xD5, 0xC6, 0xF8, 0xAA, 0xC5, 0x20, + 0x40, 0xCC, 0x68, 0x7C, 0x17, 0xAB, 0xF3, 0xC7, + 0x78, 0xC1, 0x39, 0x06, 0xE0, 0xE6, 0xF2, 0x9A, + 0x6A, 0xB1, 0x23, 0xDE, 0xEB, 0xCE, 0x39, 0x1F, + 0x90, 0x7D, 0x75, 0xD3, 0xA2, 0xCE, 0xFA, 0x0E, + 0xFC, 0xB8, 0x80, 0xA0, 0xE7, 0x0D, 0x71, 0x96 + }, + { + 0x32, 0x46, 0x6B, 0xCB, 0xDE, 0xD5, 0x38, 0xE5, + 0x68, 0x79, 0x54, 0x30, 0x35, 0x25, 0x36, 0xFE, + 0xB9, 0x19, 0xBF, 0x4D, 0x97, 0xCC, 0x44, 0xAB, + 0x1D, 0x80, 0x50, 0x40, 0xF4, 0xBC, 0x4C, 0x2E, + 0x79, 0x52, 0x72, 0x10, 0x18, 0x95, 0x8B, 0x4E, + 0xE7, 0x83, 0x03, 0x59, 0x0E, 0xF6, 0xAC, 0x45, + 0x0D, 0xF9, 0x2E, 0xC7, 0x7F, 0x47, 0x70, 0x54, + 0xBF, 0xF8, 0x67, 0xB8, 0x89, 0x71, 0xD4, 0x21 + }, + { + 0xEA, 0x64, 0xB0, 0x03, 0xA1, 0x35, 0x76, 0x61, + 0x21, 0xCF, 0xBC, 0xCB, 0xDC, 0x08, 0xDC, 0xA2, + 0x40, 0x29, 0x26, 0xBE, 0x78, 0xCE, 0xA3, 0xD0, + 0xA7, 0x25, 0x3D, 0x9E, 0xC9, 0xE6, 0x3B, 0x8A, + 0xCD, 0xD9, 0x94, 0x55, 0x99, 0x17, 0xE0, 0xE0, + 0x3B, 0x5E, 0x15, 0x5F, 0x94, 0x4D, 0x71, 0x98, + 0xD9, 0x92, 0x45, 0xA7, 0x94, 0xCE, 0x19, 0xC9, + 0xB4, 0xDF, 0x4D, 0xA4, 0xA3, 0x39, 0x93, 0x34 + }, + { + 0x05, 0xAD, 0x0F, 0x27, 0x1F, 0xAF, 0x7E, 0x36, + 0x13, 0x20, 0x51, 0x84, 0x52, 0x81, 0x3F, 0xF9, + 0xFB, 0x99, 0x76, 0xAC, 0x37, 0x80, 0x50, 0xB6, + 0xEE, 0xFB, 0x05, 0xF7, 0x86, 0x7B, 0x57, 0x7B, + 0x8F, 0x14, 0x47, 0x57, 0x94, 0xCF, 0xF6, 0x1B, + 0x2B, 0xC0, 0x62, 0xD3, 0x46, 0xA7, 0xC6, 0x5C, + 0x6E, 0x00, 0x67, 0xC6, 0x0A, 0x37, 0x4A, 0xF7, + 0x94, 0x0F, 0x10, 0xAA, 0x44, 0x9D, 0x5F, 0xB9 + }, + { + 0xB5, 0x45, 0x88, 0x02, 0x94, 0xAF, 0xA1, 0x53, + 0xF8, 0xB9, 0xF4, 0x9C, 0x73, 0xD9, 0x52, 0xB5, + 0xD1, 0x22, 0x8F, 0x1A, 0x1A, 0xB5, 0xEB, 0xCB, + 0x05, 0xFF, 0x79, 0xE5, 0x60, 0xC0, 0x30, 0xF7, + 0x50, 0x0F, 0xE2, 0x56, 0xA4, 0x0B, 0x6A, 0x0E, + 0x6C, 0xB3, 0xD4, 0x2A, 0xCD, 0x4B, 0x98, 0x59, + 0x5C, 0x5B, 0x51, 0xEA, 0xEC, 0x5A, 0xD6, 0x9C, + 0xD4, 0x0F, 0x1F, 0xC1, 0x6D, 0x2D, 0x5F, 0x50 + }, + { + 0xBB, 0xFB, 0x94, 0x77, 0xEC, 0x6A, 0x9F, 0x0C, + 0x25, 0x40, 0x5A, 0xCD, 0x8A, 0x30, 0xD5, 0xDD, + 0x7C, 0x73, 0x57, 0x1F, 0x1D, 0x1A, 0x6E, 0x8C, + 0xE7, 0x2F, 0x8B, 0x9C, 0x94, 0x1C, 0xF7, 0x79, + 0xB7, 0x64, 0x03, 0xAC, 0x7F, 0x04, 0x50, 0x05, + 0x25, 0x84, 0x39, 0x0A, 0x14, 0xEA, 0xA3, 0x7C, + 0x20, 0xB5, 0xBD, 0xB0, 0x38, 0x10, 0x54, 0xA9, + 0xA4, 0x95, 0x34, 0xF8, 0x14, 0x66, 0xBA, 0x9D + }, + { + 0xC8, 0x28, 0x7E, 0x93, 0x3D, 0x95, 0x04, 0xBF, + 0xFD, 0x7B, 0xE2, 0xAC, 0x02, 0x2B, 0x32, 0xF3, + 0xF4, 0x6D, 0x87, 0xA7, 0xA0, 0xE7, 0x9B, 0xB2, + 0xA1, 0xCB, 0xAA, 0xCC, 0x2E, 0x84, 0xCD, 0x70, + 0x84, 0x5D, 0x0D, 0x42, 0x78, 0x48, 0xA6, 0xD7, + 0x88, 0xD3, 0x96, 0x22, 0xE1, 0x0F, 0x43, 0x42, + 0x23, 0x7E, 0xEF, 0xA6, 0xD3, 0xC0, 0x12, 0xDA, + 0xE9, 0x6C, 0xC8, 0xA6, 0x50, 0xCC, 0x2E, 0x30 + }, + { + 0xC4, 0x59, 0x6F, 0xCB, 0x0A, 0x28, 0xD2, 0x4A, + 0xAD, 0x70, 0xCF, 0x18, 0x53, 0xEC, 0x29, 0xDA, + 0xC0, 0xFB, 0x20, 0x2D, 0x8E, 0xC1, 0x40, 0xDA, + 0x30, 0x00, 0x88, 0xBB, 0x85, 0xB9, 0x2C, 0x30, + 0x29, 0x19, 0x46, 0xAD, 0x30, 0x7C, 0x09, 0x6E, + 0x3B, 0x28, 0x66, 0x33, 0x5C, 0x93, 0x17, 0xAF, + 0xE2, 0x8C, 0xAD, 0xAB, 0x5D, 0x62, 0xC3, 0x54, + 0x32, 0x9C, 0x98, 0xD9, 0x93, 0xC5, 0xBE, 0x1C + }, + { + 0xE8, 0x8C, 0x38, 0xE6, 0x7E, 0x8D, 0x19, 0x83, + 0x58, 0x08, 0x85, 0x46, 0x70, 0x77, 0x9E, 0xCA, + 0x60, 0xBA, 0xD8, 0x54, 0xC5, 0x77, 0x87, 0x90, + 0xA0, 0x72, 0x54, 0xA3, 0x0A, 0x14, 0xAE, 0x82, + 0xB6, 0x1B, 0xB1, 0x69, 0x11, 0xFE, 0x57, 0x77, + 0x1D, 0x19, 0xE9, 0xB7, 0xF5, 0x02, 0x3C, 0x0D, + 0x4E, 0x8A, 0x8D, 0x37, 0x2E, 0x3D, 0x85, 0xE4, + 0x3B, 0x03, 0xE5, 0xE0, 0x0E, 0x6E, 0xBA, 0x4B + }, + { + 0x2D, 0x66, 0x3E, 0x03, 0xE6, 0xF3, 0x55, 0x2C, + 0xCD, 0xFB, 0xA4, 0x96, 0xA1, 0x4C, 0xC6, 0x22, + 0x4C, 0xEB, 0x1E, 0xB6, 0x1A, 0xA2, 0x65, 0xE6, + 0xA7, 0xD4, 0xA2, 0x6E, 0x54, 0x10, 0x61, 0x04, + 0xA9, 0x6E, 0x33, 0x09, 0x59, 0xF9, 0x71, 0x3B, + 0x34, 0x87, 0xC1, 0xB9, 0x49, 0x7C, 0xCF, 0x82, + 0x61, 0x1D, 0xBF, 0xA3, 0x4F, 0xF1, 0x1D, 0x31, + 0x33, 0xB5, 0xB5, 0xD1, 0xF1, 0xE4, 0xF8, 0xD0 + }, + { + 0x70, 0x7D, 0x6A, 0x58, 0x42, 0x1B, 0x8F, 0x7E, + 0x44, 0xFF, 0x1F, 0x83, 0x62, 0xBC, 0x70, 0x0F, + 0x71, 0xEF, 0x7C, 0x39, 0x35, 0xE0, 0x76, 0x4B, + 0xD1, 0x4D, 0x39, 0x0C, 0x1C, 0x72, 0x79, 0x2A, + 0xF9, 0xC2, 0xC0, 0x2F, 0xB7, 0x2A, 0x2B, 0x9D, + 0x9A, 0x07, 0x29, 0xCB, 0x3E, 0x99, 0x62, 0x6C, + 0xF0, 0x34, 0xDF, 0x54, 0xB5, 0x06, 0xB5, 0xB1, + 0x64, 0x64, 0xF4, 0x75, 0x86, 0x4F, 0x25, 0x90 + }, + { + 0x9D, 0x88, 0xF8, 0xBA, 0xA4, 0xEB, 0x0F, 0x9A, + 0xB2, 0x29, 0x2E, 0x49, 0x82, 0xAC, 0x80, 0x44, + 0x53, 0x58, 0x22, 0x7D, 0x7F, 0x9C, 0xE7, 0xA4, + 0xA6, 0x29, 0xF1, 0x80, 0xF7, 0x14, 0x1E, 0x08, + 0xFE, 0x63, 0x55, 0xC6, 0x45, 0x21, 0xA6, 0x9B, + 0xA2, 0xBF, 0xBD, 0x1C, 0x4A, 0x3E, 0xA0, 0x48, + 0xD0, 0xBC, 0x8A, 0xB3, 0x70, 0x1F, 0x30, 0xEA, + 0x83, 0xFB, 0xE0, 0x24, 0x74, 0xD8, 0x92, 0xBF + }, + { + 0x65, 0xEA, 0x4D, 0xB0, 0x4A, 0x75, 0x81, 0xC1, + 0x81, 0x94, 0xA8, 0x92, 0x1A, 0xFD, 0xFA, 0x4F, + 0x8D, 0x9A, 0xF6, 0x29, 0xDE, 0xD2, 0x77, 0x2C, + 0x65, 0x8E, 0x08, 0x48, 0x5F, 0x67, 0xAD, 0x2C, + 0xE2, 0x1A, 0x98, 0xCD, 0x29, 0x3F, 0xF2, 0x8D, + 0x4D, 0xFC, 0xDF, 0x65, 0x8C, 0xDC, 0x7A, 0xE6, + 0x70, 0x27, 0x84, 0x8E, 0x71, 0xCC, 0xC1, 0x15, + 0xA3, 0xFF, 0xBA, 0xC4, 0xFA, 0x61, 0xBB, 0x73 + }, + { + 0x0B, 0x4A, 0x68, 0x92, 0x9E, 0x7F, 0x15, 0xCA, + 0x91, 0xBB, 0x44, 0x39, 0xF2, 0x40, 0x37, 0x02, + 0x03, 0x4C, 0xD4, 0x74, 0x8E, 0x46, 0x92, 0x7A, + 0xBA, 0x95, 0xCB, 0xEF, 0x80, 0x04, 0x8B, 0x25, + 0xA6, 0x75, 0x97, 0x0F, 0xAC, 0x33, 0xC8, 0x74, + 0xAB, 0xD3, 0xD8, 0x3A, 0xA0, 0xF3, 0x7B, 0xE2, + 0x30, 0x83, 0x10, 0xE8, 0xDD, 0x79, 0x4F, 0x81, + 0x92, 0x93, 0x0E, 0xD5, 0x6E, 0x70, 0xA8, 0xE4 + }, + { + 0xC1, 0xC5, 0xD8, 0xAC, 0xFE, 0x3F, 0xDE, 0x67, + 0x4E, 0xDD, 0x36, 0x20, 0x15, 0x7A, 0x8B, 0x6B, + 0x4C, 0x8E, 0x67, 0xC6, 0xA7, 0xA9, 0x72, 0x67, + 0x41, 0xD9, 0xC3, 0x05, 0xE2, 0xA5, 0x2A, 0x87, + 0x97, 0xFD, 0xA0, 0xB2, 0xF1, 0x3A, 0xC7, 0x87, + 0x34, 0xDB, 0x2F, 0x4F, 0xC8, 0x3E, 0xF3, 0x24, + 0x14, 0xD9, 0x31, 0xEB, 0xAE, 0xAE, 0xCD, 0x82, + 0x6D, 0x7C, 0x2B, 0xE2, 0x03, 0xBD, 0xC2, 0xD1 + }, + { + 0x2D, 0xAD, 0xC8, 0xC9, 0xF7, 0x42, 0x5A, 0x01, + 0x14, 0x49, 0x12, 0x87, 0xBD, 0xC6, 0x8E, 0xAE, + 0x4F, 0xB6, 0x19, 0x4D, 0x1A, 0x10, 0x9D, 0xB9, + 0xB6, 0xE8, 0xA2, 0xAC, 0x94, 0xD4, 0xE4, 0x40, + 0x90, 0x99, 0x85, 0xC4, 0x29, 0x1F, 0xE8, 0x9F, + 0xD8, 0x28, 0x1F, 0x8F, 0xCE, 0xF6, 0xF6, 0xBC, + 0x32, 0x55, 0x0E, 0x53, 0xCB, 0x7A, 0x49, 0x42, + 0x89, 0x81, 0xE8, 0xD5, 0x3C, 0xF5, 0xA2, 0x12 + }, + { + 0xE5, 0x55, 0xF2, 0xA5, 0x8A, 0xCA, 0xC5, 0x50, + 0x3F, 0x9E, 0x2D, 0x97, 0xB2, 0x46, 0x87, 0x2B, + 0x4C, 0xA7, 0x8B, 0xD5, 0x6D, 0x47, 0xB7, 0x65, + 0xF0, 0x52, 0xAA, 0xB3, 0xDC, 0x77, 0xDB, 0xE9, + 0x93, 0x93, 0x6F, 0x22, 0x52, 0xF0, 0xAB, 0x2E, + 0x01, 0xFB, 0x08, 0x74, 0x72, 0xCC, 0xB5, 0xA1, + 0x21, 0xDD, 0xFF, 0xDE, 0x53, 0x1D, 0x3D, 0xC4, + 0x02, 0x2A, 0x7D, 0x19, 0x56, 0xCE, 0x0E, 0x20 + }, + { + 0x9B, 0x4E, 0xAE, 0x12, 0x95, 0x00, 0x0A, 0xEA, + 0x79, 0x83, 0xEC, 0x3B, 0xCB, 0x48, 0x57, 0xCC, + 0x71, 0x25, 0xFD, 0x73, 0x06, 0x78, 0x7C, 0x63, + 0x13, 0x24, 0x73, 0xCF, 0xE8, 0xF4, 0xEB, 0x45, + 0x31, 0x8A, 0x60, 0xDA, 0xAD, 0x64, 0x6D, 0x63, + 0xA2, 0x7C, 0x4B, 0x9D, 0x1F, 0x50, 0x73, 0x70, + 0x0A, 0x30, 0x57, 0xDE, 0x22, 0xA7, 0xFD, 0xF0, + 0x9A, 0x87, 0xAA, 0xC6, 0x6E, 0xBE, 0x47, 0x58 + }, + { + 0x96, 0x64, 0xAC, 0xC2, 0xDC, 0x72, 0x98, 0xB9, + 0x86, 0x8D, 0xB4, 0x95, 0xEE, 0xBC, 0x6B, 0x59, + 0x65, 0x7D, 0x13, 0x9A, 0x6A, 0xF0, 0x60, 0xA7, + 0x2F, 0xB6, 0x91, 0x24, 0xBD, 0xD3, 0xA6, 0x59, + 0x18, 0x88, 0xF0, 0x35, 0x4F, 0x70, 0x2B, 0x1B, + 0x88, 0x86, 0x84, 0x41, 0x10, 0x58, 0xA3, 0x75, + 0x9F, 0x7F, 0xD3, 0x7F, 0x06, 0xEA, 0xFB, 0x3B, + 0x58, 0xEC, 0xF2, 0x6F, 0x45, 0x53, 0xBE, 0x27 + }, + { + 0xFC, 0x16, 0xE0, 0x92, 0x5A, 0x35, 0xAA, 0xD4, + 0x7A, 0xD6, 0x95, 0x54, 0xB2, 0x57, 0x96, 0xFC, + 0xF9, 0x26, 0x0C, 0xB5, 0x0E, 0x6C, 0xC3, 0x74, + 0x75, 0x35, 0x55, 0x9E, 0x99, 0xC8, 0x58, 0x81, + 0xC7, 0x58, 0x89, 0xAC, 0x79, 0x3A, 0xB7, 0x8B, + 0x88, 0xB0, 0x5F, 0xB1, 0x60, 0x89, 0x56, 0x55, + 0xE4, 0xD6, 0x63, 0xA2, 0xA0, 0x9B, 0xA9, 0xFA, + 0x61, 0x4A, 0x10, 0xC2, 0x29, 0x47, 0x21, 0x0D + }, + { + 0x22, 0x5E, 0x73, 0x41, 0xF8, 0x57, 0x52, 0x4F, + 0x78, 0x90, 0x37, 0x6C, 0x50, 0xE6, 0x35, 0x4B, + 0x16, 0xC1, 0xCD, 0xFB, 0xF5, 0x8F, 0xE5, 0xF3, + 0xA4, 0x03, 0x94, 0x93, 0xB5, 0xDD, 0x40, 0x8D, + 0x79, 0xD4, 0x8C, 0x56, 0xE1, 0xF8, 0x9B, 0x68, + 0x7F, 0xBE, 0x33, 0x62, 0xA7, 0x7F, 0xA7, 0x5A, + 0x54, 0x37, 0x4B, 0x7A, 0x48, 0x5E, 0x91, 0xB1, + 0x89, 0xAF, 0x2E, 0x2F, 0x74, 0x9E, 0x2A, 0xDB + }, + { + 0xA0, 0x7A, 0x4C, 0x02, 0x3A, 0xC7, 0x04, 0xCE, + 0x7C, 0x09, 0xDD, 0x6C, 0x92, 0xC6, 0xF1, 0x84, + 0xF5, 0x3E, 0x8D, 0xD9, 0x6F, 0xE3, 0xBE, 0x9E, + 0x93, 0xC3, 0x9C, 0x53, 0x44, 0x85, 0xB6, 0x4B, + 0x39, 0xD5, 0xBE, 0x7F, 0x7B, 0x71, 0x70, 0x60, + 0x4D, 0xE7, 0x7C, 0xE5, 0xA4, 0x37, 0xA9, 0x8E, + 0x71, 0x2C, 0xC4, 0x4F, 0x19, 0xE2, 0x1D, 0x41, + 0xF0, 0xE6, 0xE3, 0xEC, 0x1E, 0x00, 0xAC, 0x55 + }, + { + 0x62, 0x85, 0x84, 0x63, 0x58, 0x2D, 0x22, 0xE6, + 0x8E, 0x52, 0x27, 0xBF, 0xBA, 0xB5, 0x40, 0x04, + 0x8F, 0x65, 0xED, 0xD6, 0xA6, 0x75, 0x5F, 0x6F, + 0xAB, 0x53, 0xC0, 0x25, 0xB6, 0x63, 0xCA, 0x37, + 0x7A, 0x0E, 0xD5, 0xEF, 0xD6, 0xAF, 0x16, 0x6C, + 0xA5, 0x5A, 0x9C, 0x73, 0x3F, 0xCA, 0x80, 0x5A, + 0xC4, 0xE4, 0x09, 0xCA, 0x56, 0x17, 0x7A, 0xA7, + 0x49, 0x40, 0xDB, 0x9F, 0x40, 0xC3, 0xB9, 0xFF + }, + { + 0xA1, 0xAC, 0x53, 0x9D, 0x1A, 0xBB, 0xC2, 0xB0, + 0x96, 0xFF, 0xAB, 0x81, 0x3B, 0x64, 0x45, 0x7F, + 0xE6, 0xEB, 0x3B, 0x50, 0xFC, 0xD8, 0x89, 0x53, + 0xD0, 0xCD, 0x9F, 0x65, 0x02, 0xF6, 0x89, 0x62, + 0x0A, 0xD4, 0x42, 0xB5, 0x51, 0x70, 0x90, 0xB5, + 0x0C, 0xFF, 0xB9, 0x58, 0x86, 0x6D, 0x7C, 0x16, + 0x1D, 0x8A, 0x7D, 0x75, 0x60, 0xC8, 0x93, 0xE1, + 0xDE, 0xF6, 0xAE, 0xC4, 0x37, 0xAD, 0x6D, 0x06 + }, + { + 0xB5, 0x86, 0xB7, 0x5D, 0xA7, 0x0F, 0x6C, 0xC0, + 0x62, 0x7E, 0xF3, 0xCF, 0x12, 0x37, 0xC9, 0x4B, + 0x12, 0xD0, 0xF7, 0x4D, 0xCB, 0xA2, 0x6A, 0x9E, + 0x7C, 0x7B, 0xC6, 0xC2, 0x1A, 0x33, 0x53, 0x37, + 0xBF, 0x9F, 0x5B, 0x83, 0x0C, 0x63, 0x24, 0xAF, + 0xA6, 0xEF, 0x64, 0x9E, 0x95, 0xAF, 0x87, 0x90, + 0x87, 0x52, 0x34, 0xC6, 0xE6, 0x61, 0xD3, 0xF5, + 0xE9, 0x8C, 0xA0, 0x12, 0xAE, 0x81, 0x48, 0x8A + }, + { + 0x56, 0x68, 0xA2, 0x98, 0x21, 0x37, 0xCB, 0xC6, + 0x22, 0xEF, 0x8D, 0x06, 0xCF, 0x4E, 0x86, 0x16, + 0x8C, 0xDD, 0x4A, 0x89, 0x9C, 0xD4, 0x46, 0x2A, + 0xF6, 0xC3, 0xD4, 0x15, 0x42, 0x61, 0x56, 0xA5, + 0xD8, 0xDD, 0x67, 0xC9, 0x60, 0x4F, 0x31, 0xB5, + 0x7D, 0x6C, 0x9D, 0x59, 0x72, 0x50, 0x45, 0x7E, + 0x4A, 0xB5, 0x2A, 0x58, 0x11, 0x55, 0x42, 0xAC, + 0xF2, 0x7F, 0x92, 0x59, 0x30, 0xF6, 0xA1, 0x12 + }, + { + 0xF2, 0xB1, 0xBD, 0x16, 0xD8, 0x8E, 0x37, 0xF3, + 0xA5, 0x18, 0xD1, 0x93, 0xED, 0x06, 0x1A, 0x1D, + 0xF7, 0xB4, 0x43, 0xA1, 0x8C, 0xE9, 0xF8, 0x44, + 0x45, 0xEF, 0x86, 0xEF, 0xFB, 0xDF, 0xF1, 0x60, + 0x55, 0x02, 0x3C, 0xD4, 0xE7, 0x8D, 0x03, 0x4D, + 0xE4, 0x03, 0x2A, 0x77, 0xDD, 0xC1, 0xD3, 0x43, + 0x52, 0xFE, 0x61, 0x7F, 0x82, 0x56, 0x24, 0x45, + 0x9B, 0xC3, 0x26, 0x9F, 0x70, 0x4F, 0x34, 0x5B + }, + { + 0xF0, 0x85, 0xF3, 0xD8, 0xBD, 0x13, 0x8E, 0x05, + 0x69, 0x24, 0x3F, 0x74, 0x52, 0x3E, 0x87, 0xFF, + 0x37, 0x6F, 0x04, 0xEA, 0xBD, 0x5A, 0x2F, 0x6E, + 0x53, 0xDF, 0x38, 0x99, 0x00, 0x0E, 0x2E, 0x94, + 0xAF, 0x0D, 0x2B, 0xC7, 0x1C, 0x3F, 0x71, 0x10, + 0x25, 0xC5, 0x38, 0xA6, 0xC8, 0xB1, 0x0B, 0x09, + 0x04, 0xDF, 0xC3, 0x46, 0xAD, 0xAD, 0x7E, 0xF3, + 0x6B, 0x1A, 0xE8, 0x8A, 0x6C, 0xFE, 0xAB, 0xBD + }, + { + 0x82, 0x91, 0xA4, 0xAF, 0xD2, 0xE4, 0xB7, 0x16, + 0x61, 0x77, 0x3A, 0x46, 0xB3, 0xD4, 0x45, 0x5A, + 0x8D, 0x33, 0xA7, 0x26, 0xD9, 0xD3, 0x87, 0x30, + 0x83, 0xAB, 0x33, 0x70, 0x20, 0xC2, 0x7B, 0x4D, + 0xD6, 0x43, 0xE2, 0x8C, 0x2F, 0xE4, 0x7A, 0xB2, + 0xFB, 0xF5, 0xD1, 0x40, 0x81, 0xA3, 0xFC, 0x1C, + 0x83, 0x9B, 0x12, 0xEA, 0x31, 0xD1, 0x3C, 0xF4, + 0x9E, 0xEE, 0x97, 0xEF, 0x2E, 0xD7, 0xFA, 0x3E + }, + { + 0xB1, 0x26, 0xAE, 0x46, 0xA7, 0xA4, 0x59, 0x5E, + 0x31, 0x60, 0x7E, 0xF8, 0x07, 0xA5, 0x60, 0x1F, + 0x4E, 0xCD, 0x9E, 0x7D, 0x66, 0xC8, 0x2D, 0xAE, + 0xB9, 0x71, 0x5F, 0x8D, 0xA1, 0xC1, 0x7D, 0x7D, + 0x71, 0xC3, 0xE6, 0x82, 0x50, 0xC9, 0xDC, 0x01, + 0xAC, 0x40, 0xA3, 0x6D, 0x2E, 0x63, 0x8B, 0xEF, + 0x3D, 0x7B, 0xC7, 0x0E, 0xA2, 0xD0, 0xE3, 0x31, + 0xE3, 0xD3, 0x3E, 0x17, 0x04, 0xEB, 0xA9, 0x2D + }, + { + 0x63, 0xB1, 0x4D, 0x8E, 0xD2, 0x47, 0x9C, 0xAA, + 0x17, 0xC3, 0xE4, 0xCF, 0x20, 0x3B, 0x23, 0x3A, + 0x7E, 0x37, 0x3E, 0xDB, 0x0C, 0x2F, 0x19, 0x71, + 0x29, 0xA9, 0xA3, 0x6C, 0x5B, 0x3E, 0x1F, 0x38, + 0x38, 0xF2, 0xE8, 0x2A, 0xC2, 0xC2, 0xAD, 0x9D, + 0x52, 0xB3, 0x35, 0x79, 0x0B, 0xFF, 0x57, 0x73, + 0x04, 0xA3, 0x78, 0xE3, 0x8E, 0xB6, 0xBB, 0x41, + 0x62, 0x03, 0x0C, 0xE2, 0xA8, 0xBA, 0x29, 0x3C + }, + { + 0x34, 0x42, 0x2A, 0x32, 0x29, 0x66, 0x99, 0x28, + 0xC4, 0x90, 0xF5, 0x7B, 0x8E, 0x76, 0x88, 0x52, + 0xE5, 0xB7, 0xC0, 0x0D, 0xCA, 0xD6, 0x0B, 0x01, + 0x2A, 0x5D, 0xB3, 0x9A, 0x2D, 0x59, 0x7C, 0x3D, + 0x0A, 0x63, 0xBE, 0x6A, 0x26, 0x3E, 0xA5, 0x36, + 0x08, 0xB7, 0x06, 0x92, 0xD7, 0x8E, 0x1B, 0x42, + 0x7E, 0xAC, 0xEC, 0x01, 0xF4, 0xBE, 0xE0, 0xBD, + 0xBB, 0x8F, 0x08, 0x81, 0x48, 0x8E, 0xFC, 0x28 + }, + { + 0xE2, 0x6B, 0x7E, 0xD6, 0xB9, 0x07, 0xB5, 0x4C, + 0xA2, 0x65, 0x67, 0xF1, 0x1E, 0xE5, 0xBB, 0x6D, + 0x73, 0x9A, 0x00, 0x08, 0xA5, 0x34, 0x37, 0xAD, + 0x75, 0x90, 0xA3, 0x13, 0x4C, 0xEB, 0x95, 0x19, + 0x6E, 0x49, 0xB3, 0x44, 0x3F, 0x32, 0x49, 0x22, + 0x51, 0x75, 0x23, 0xC0, 0xCD, 0x5A, 0x00, 0xD7, + 0x7E, 0x4C, 0x4D, 0xE7, 0xA0, 0xDE, 0x96, 0x8A, + 0x84, 0xFB, 0x1B, 0x3B, 0xE7, 0xB3, 0xB9, 0x63 + }, + { + 0x26, 0x01, 0x97, 0xCA, 0xFB, 0xF4, 0x56, 0xB4, + 0x11, 0xFA, 0x26, 0xD3, 0x83, 0xD6, 0x4D, 0x61, + 0xE8, 0x1E, 0x5E, 0x52, 0xF8, 0x4C, 0xD9, 0xD5, + 0x73, 0x86, 0xC7, 0x76, 0x23, 0x0C, 0x65, 0xA2, + 0x68, 0x1C, 0xD2, 0xFD, 0xFD, 0x28, 0x67, 0x9F, + 0x67, 0xFE, 0x1B, 0xD7, 0x46, 0x9C, 0xF7, 0x26, + 0x95, 0x85, 0xFC, 0xCB, 0xAE, 0xCC, 0x22, 0xF5, + 0x03, 0xD6, 0xE3, 0xFC, 0x39, 0x30, 0x14, 0x36 + }, + { + 0xCB, 0xD5, 0xAB, 0xE3, 0x7B, 0xCC, 0x4F, 0x9A, + 0x12, 0x70, 0xAD, 0xD0, 0xA5, 0x27, 0x0F, 0x42, + 0x83, 0x9C, 0x7D, 0x24, 0x93, 0x20, 0xD1, 0xF1, + 0xD8, 0x85, 0x53, 0xD0, 0x5F, 0xAF, 0x9A, 0x26, + 0x79, 0xF4, 0x9B, 0x49, 0xC9, 0xE2, 0x0C, 0x1C, + 0x85, 0xC6, 0x29, 0xAA, 0x0F, 0x09, 0x0C, 0xAE, + 0x8F, 0x6E, 0x32, 0xC6, 0xCA, 0xD7, 0x17, 0x21, + 0xFD, 0x06, 0x23, 0xE4, 0xED, 0x25, 0xB2, 0x56 + }, + { + 0x78, 0x0E, 0x31, 0x4F, 0xD6, 0x97, 0xD2, 0xA9, + 0x7D, 0x22, 0x1A, 0x22, 0xC3, 0x90, 0x11, 0xE2, + 0x50, 0x69, 0x16, 0x3C, 0xD0, 0x8F, 0x00, 0x70, + 0xD0, 0x67, 0xE8, 0xCD, 0xB0, 0xBC, 0x86, 0x73, + 0xFD, 0xB0, 0xEC, 0x4F, 0x46, 0xE3, 0x1D, 0x74, + 0x8C, 0xD3, 0xBB, 0x3D, 0x61, 0xB9, 0x01, 0x0A, + 0x66, 0x12, 0xF3, 0x41, 0xD4, 0x71, 0xD9, 0xC5, + 0xA2, 0xDE, 0x6B, 0x6D, 0xD5, 0x38, 0xA6, 0xB5 + }, + { + 0x40, 0x8F, 0x16, 0xCE, 0x86, 0xF8, 0x01, 0xD0, + 0x8B, 0xD0, 0x51, 0x36, 0x4B, 0x3E, 0xCD, 0x9A, + 0x39, 0x45, 0x71, 0x58, 0x88, 0xDF, 0x46, 0x63, + 0x21, 0x9A, 0x19, 0x0B, 0x35, 0x04, 0xE4, 0x61, + 0x8E, 0x7B, 0xF5, 0x51, 0x71, 0x17, 0x8B, 0x04, + 0x00, 0xFB, 0xEB, 0xFA, 0xA0, 0x1F, 0x6E, 0xEA, + 0xB5, 0x4F, 0xF5, 0xE3, 0x1E, 0x6D, 0x7A, 0x55, + 0xB8, 0x4A, 0xDB, 0x9E, 0x03, 0xDF, 0x48, 0x36 + }, + { + 0x0B, 0xF9, 0x88, 0x69, 0xEC, 0x05, 0x80, 0x19, + 0x9C, 0xA3, 0x70, 0x8E, 0xC9, 0xC4, 0x2C, 0x37, + 0x6C, 0x5C, 0x36, 0xE0, 0xFB, 0x74, 0x92, 0x42, + 0x57, 0x23, 0x98, 0xA0, 0xDA, 0x57, 0xF9, 0x8D, + 0x1C, 0x4C, 0xD2, 0x96, 0x3B, 0x37, 0xC3, 0xC6, + 0x5A, 0x10, 0xF1, 0x06, 0xB5, 0x6D, 0xCB, 0x96, + 0xDC, 0xDD, 0x32, 0x57, 0x96, 0x29, 0x7A, 0xDB, + 0xF6, 0xEE, 0x62, 0x70, 0xED, 0xD4, 0x59, 0x2A + }, + { + 0x05, 0x2C, 0x32, 0x98, 0x43, 0x87, 0xB1, 0x93, + 0x0D, 0x3A, 0x96, 0xBE, 0x72, 0x36, 0x85, 0x35, + 0x44, 0x4F, 0x13, 0x07, 0x57, 0xBF, 0x87, 0xE0, + 0x76, 0x2D, 0x8B, 0x1C, 0x4F, 0x65, 0x70, 0xF4, + 0xDC, 0x67, 0x4C, 0x4E, 0x6F, 0x5E, 0x21, 0xAB, + 0xD0, 0xB3, 0x5E, 0x1C, 0xA1, 0x9D, 0xB8, 0x40, + 0x68, 0x8D, 0x1B, 0x6E, 0x9E, 0xC9, 0x1F, 0x37, + 0x30, 0xE8, 0xB2, 0x88, 0x0E, 0xC2, 0xC3, 0xDF + }, + { + 0x4B, 0xB7, 0x14, 0x09, 0xC1, 0x5A, 0x0D, 0x39, + 0x32, 0xC5, 0x99, 0xEF, 0x0F, 0xF3, 0xEF, 0xF5, + 0xC7, 0x60, 0x2D, 0x70, 0x00, 0xCD, 0xA9, 0x74, + 0x08, 0x2C, 0x4A, 0x46, 0x82, 0x24, 0x9A, 0x19, + 0xD4, 0x3A, 0x5C, 0x14, 0xE0, 0xAE, 0xEF, 0x89, + 0x78, 0x21, 0x05, 0x63, 0x80, 0xAF, 0xF2, 0x75, + 0x20, 0x1D, 0x74, 0x59, 0x14, 0x84, 0x96, 0xEA, + 0xE9, 0x42, 0x0E, 0x71, 0x82, 0x88, 0xB4, 0x14 + }, + { + 0x47, 0x95, 0xB2, 0x51, 0xCC, 0x7B, 0x35, 0xE6, + 0x96, 0x92, 0xDB, 0x7F, 0xB4, 0x0E, 0xFD, 0x34, + 0xF2, 0x94, 0xF5, 0x1A, 0xEC, 0x15, 0xD6, 0xC8, + 0x67, 0x3E, 0x59, 0xF2, 0x04, 0xBE, 0xCF, 0x4C, + 0xF9, 0xDF, 0x84, 0x95, 0x23, 0xF1, 0xDB, 0x73, + 0xBE, 0x2A, 0x66, 0xC8, 0x39, 0xD8, 0x01, 0x97, + 0x4D, 0x43, 0x3B, 0x47, 0x80, 0x67, 0x01, 0xA1, + 0x63, 0xA7, 0x94, 0xB2, 0x6A, 0x84, 0x6B, 0x06 + }, + { + 0xDD, 0x50, 0xF9, 0x65, 0xB6, 0x0B, 0xAF, 0x16, + 0x8F, 0x5E, 0xA0, 0x5A, 0xC2, 0x0B, 0x8A, 0x78, + 0xF4, 0x47, 0x5C, 0x18, 0x61, 0x0B, 0x9D, 0x9F, + 0xC2, 0xB7, 0xC3, 0xAD, 0x5C, 0x6F, 0x97, 0xA4, + 0xCF, 0x5E, 0xA4, 0x8E, 0xE4, 0x0A, 0x3C, 0xA2, + 0x29, 0x3C, 0xC4, 0x21, 0x40, 0x82, 0xCF, 0x0F, + 0x8E, 0xC8, 0x95, 0x55, 0x32, 0x69, 0xE1, 0x4D, + 0xA9, 0xBD, 0x1A, 0x19, 0x65, 0x62, 0xCA, 0x59 + }, + { + 0xE0, 0xB5, 0x4B, 0x61, 0x7F, 0x44, 0x92, 0x2C, + 0x7F, 0x61, 0xC6, 0xA5, 0x4C, 0x98, 0xC6, 0x1E, + 0x93, 0x2D, 0xED, 0x1F, 0xA9, 0x34, 0x02, 0x66, + 0xEE, 0xA2, 0x5F, 0x01, 0xE8, 0x18, 0x0D, 0x1D, + 0xDC, 0x6A, 0xD8, 0xDD, 0x6A, 0x0B, 0x8F, 0xAB, + 0x8C, 0x73, 0xAE, 0xBB, 0x97, 0x73, 0x17, 0x1B, + 0xBA, 0x04, 0xA7, 0x81, 0xB1, 0x13, 0x14, 0xD5, + 0xA3, 0x0A, 0x9D, 0x1C, 0x28, 0x12, 0xCA, 0x7C + }, + { + 0x2D, 0xC4, 0xAD, 0x06, 0x89, 0xA4, 0x46, 0x0B, + 0x5B, 0x39, 0x9E, 0x91, 0x1B, 0xDB, 0x41, 0x58, + 0x6A, 0xC8, 0xAD, 0x36, 0x7B, 0x7A, 0xA3, 0x9E, + 0x3E, 0xAE, 0xC8, 0x89, 0x9A, 0x2D, 0x3C, 0xE3, + 0x8E, 0x34, 0xAB, 0x46, 0x08, 0x23, 0x4D, 0x75, + 0xEB, 0x67, 0x37, 0xFE, 0x21, 0x58, 0x24, 0xC2, + 0xA9, 0x78, 0x83, 0x59, 0x6F, 0x6F, 0x18, 0xDD, + 0xEB, 0xBF, 0x16, 0x27, 0xDE, 0xD9, 0x1D, 0x84 + }, + { + 0xF5, 0x6A, 0x11, 0xCB, 0xBF, 0x8A, 0x99, 0x7E, + 0x14, 0x77, 0xEC, 0x76, 0xE5, 0x3C, 0x89, 0x4B, + 0x14, 0x8D, 0x69, 0x25, 0xA4, 0x33, 0x6F, 0x0C, + 0xB7, 0xAA, 0xB9, 0xD8, 0x02, 0xAC, 0x9B, 0x45, + 0x36, 0xF4, 0x80, 0x10, 0x1F, 0x3F, 0x9A, 0x77, + 0xEE, 0xCD, 0xCB, 0xAE, 0x7A, 0xA6, 0xEA, 0x44, + 0x7A, 0x85, 0xDA, 0x90, 0xB5, 0x01, 0xF7, 0xDB, + 0x2E, 0xF8, 0xDD, 0xF5, 0xDE, 0x17, 0x33, 0x63 + }, + { + 0x6E, 0x17, 0x1D, 0x19, 0x6D, 0x0F, 0xC8, 0x2F, + 0xB4, 0x73, 0xE2, 0x9D, 0xA8, 0xF4, 0x0F, 0x37, + 0xEE, 0x97, 0x41, 0xAC, 0x3E, 0xAF, 0x17, 0x5D, + 0xD4, 0x9F, 0xDB, 0x56, 0x53, 0x0D, 0xB5, 0x98, + 0x98, 0xBA, 0xF3, 0xCE, 0xE7, 0x2E, 0xEF, 0x5E, + 0x77, 0x27, 0x6C, 0xAD, 0xAB, 0xCD, 0x75, 0x2C, + 0xA3, 0xA1, 0xB8, 0x64, 0xC1, 0x0A, 0xD2, 0x8D, + 0x27, 0xEA, 0xAD, 0x86, 0xE3, 0xF2, 0x1D, 0x33 + }, + { + 0x95, 0x20, 0x12, 0x33, 0x0D, 0x92, 0xBB, 0x9C, + 0x18, 0x92, 0xF2, 0x5B, 0x7B, 0x5A, 0xA0, 0xFE, + 0xD3, 0xC0, 0x39, 0x8A, 0x17, 0x08, 0x50, 0x9A, + 0x66, 0x14, 0x74, 0xA3, 0xF5, 0xE5, 0x11, 0xD0, + 0x9F, 0x21, 0xC3, 0x00, 0x08, 0x00, 0x2F, 0x10, + 0x42, 0xD8, 0x3D, 0x2F, 0x7B, 0x11, 0x33, 0x6B, + 0x8C, 0x2F, 0xE1, 0xD9, 0x79, 0xC1, 0xE3, 0x86, + 0xE0, 0x20, 0x97, 0x48, 0x9B, 0x2D, 0xFC, 0xF5 + }, + { + 0x2D, 0xCE, 0x47, 0xC3, 0x3A, 0x7E, 0x7F, 0x21, + 0x5D, 0x34, 0xA5, 0x47, 0x1B, 0xCD, 0x11, 0x10, + 0x60, 0x6C, 0x77, 0x13, 0x8F, 0x19, 0xD4, 0x17, + 0x41, 0xED, 0x5D, 0x1B, 0x89, 0xE8, 0xF7, 0xC7, + 0x74, 0xEE, 0xC4, 0xBB, 0xC1, 0x02, 0x76, 0x6E, + 0xA1, 0x53, 0x2F, 0x2E, 0x43, 0x13, 0x4A, 0xD3, + 0x66, 0xBD, 0xCC, 0x27, 0xD1, 0xA0, 0xCC, 0x95, + 0x9E, 0x16, 0x48, 0x65, 0x9E, 0x44, 0xCB, 0xBE + }, + { + 0x7F, 0x06, 0x59, 0x59, 0x7E, 0x7A, 0xD1, 0x22, + 0xD1, 0xC9, 0xED, 0x91, 0x93, 0x0B, 0x07, 0xDE, + 0x40, 0xE2, 0x55, 0x20, 0x1A, 0x33, 0xEB, 0x2B, + 0x31, 0x81, 0x37, 0x6E, 0x36, 0x8D, 0xF7, 0x76, + 0x4C, 0x0C, 0x14, 0xBF, 0x79, 0x9F, 0x16, 0x1B, + 0x9B, 0x00, 0x79, 0x57, 0x8B, 0x47, 0x09, 0x71, + 0x3E, 0x24, 0xE4, 0x2F, 0xE7, 0xDD, 0x71, 0xB5, + 0x09, 0x43, 0xF4, 0x40, 0xE2, 0x3C, 0xD1, 0xBE + }, + { + 0x1E, 0x66, 0xF7, 0xB3, 0x58, 0x80, 0x5D, 0xDD, + 0xFF, 0xC5, 0x82, 0x68, 0x3E, 0x0B, 0xAD, 0x81, + 0x8C, 0x87, 0x34, 0x03, 0xD4, 0xBA, 0x15, 0x06, + 0xB9, 0x2F, 0xB3, 0x20, 0xCA, 0x8C, 0xF9, 0xCE, + 0xE8, 0x15, 0x47, 0x15, 0xD6, 0xDB, 0x6F, 0x04, + 0x09, 0x3D, 0x4B, 0x3F, 0xD8, 0xA6, 0xFC, 0x8E, + 0x7E, 0xDD, 0xEA, 0xF2, 0x79, 0x5B, 0x3D, 0x22, + 0xDE, 0x7C, 0x75, 0xEC, 0xFF, 0x6F, 0x92, 0xAF + }, + { + 0x1F, 0x60, 0xC1, 0x8D, 0xB1, 0x68, 0xD9, 0x0D, + 0x2B, 0x46, 0x60, 0xE7, 0x58, 0xA3, 0xCD, 0x28, + 0x02, 0x3D, 0x4C, 0x0B, 0x84, 0x8B, 0x5E, 0x33, + 0xEA, 0x5C, 0xC1, 0x56, 0x29, 0xFD, 0x35, 0x2E, + 0xAC, 0xB1, 0x4F, 0x05, 0xFD, 0xEC, 0x07, 0xAC, + 0x23, 0xDA, 0x92, 0x04, 0x74, 0x5F, 0xA9, 0x73, + 0xC3, 0x29, 0x55, 0x13, 0x5F, 0x8E, 0xC7, 0x41, + 0x0A, 0x1C, 0xB5, 0x3B, 0xC7, 0x58, 0x06, 0x84 + }, + { + 0xB9, 0xDF, 0x57, 0xB3, 0x45, 0xEE, 0x6F, 0x87, + 0x0E, 0xE0, 0xE6, 0x3C, 0x55, 0x8B, 0x81, 0xC1, + 0xBC, 0x38, 0x42, 0x97, 0x6F, 0xD3, 0xCF, 0xB1, + 0xB5, 0x3B, 0x76, 0x6B, 0xF4, 0x36, 0xD1, 0xD1, + 0x75, 0xF4, 0xD4, 0xC5, 0xF1, 0xBD, 0x8D, 0x7A, + 0xF6, 0x5B, 0x5D, 0x18, 0xA7, 0x2F, 0x95, 0x71, + 0xF2, 0x34, 0x70, 0x19, 0x32, 0xAF, 0xB7, 0xC3, + 0xC9, 0x4A, 0x8C, 0x8F, 0xA0, 0x23, 0xDB, 0x4F + }, + { + 0xD8, 0xC8, 0x24, 0x95, 0xA2, 0xB5, 0xF6, 0x64, + 0x51, 0xF8, 0xC5, 0xB2, 0xE8, 0xA1, 0x73, 0x33, + 0xC2, 0xBE, 0x32, 0x20, 0xCE, 0x06, 0xA8, 0x14, + 0xC2, 0xCE, 0xA9, 0x5C, 0xC8, 0x65, 0x92, 0xAA, + 0x02, 0x15, 0xBF, 0x29, 0x46, 0x14, 0xA3, 0x28, + 0xCF, 0x07, 0x22, 0x2B, 0x73, 0xF9, 0x3F, 0x24, + 0x2A, 0x94, 0x8B, 0xCA, 0xE9, 0x56, 0x5F, 0xC9, + 0x70, 0x57, 0xB5, 0x2E, 0x02, 0x80, 0xEB, 0x82 + }, + { + 0x81, 0x34, 0xCE, 0x66, 0xD9, 0x5C, 0x40, 0x88, + 0xA5, 0x66, 0xD4, 0xE4, 0x35, 0x99, 0x06, 0x9A, + 0xD0, 0x45, 0x53, 0xB0, 0xFE, 0xA3, 0xD7, 0x48, + 0x19, 0xA6, 0xFD, 0x76, 0x6F, 0x43, 0x67, 0x42, + 0xF6, 0xB6, 0xEC, 0xC8, 0x27, 0x93, 0x98, 0x60, + 0x9F, 0x60, 0xB4, 0xE4, 0xBB, 0x44, 0xFD, 0x72, + 0xCD, 0xFB, 0xFF, 0x18, 0xD8, 0x03, 0x8A, 0xA7, + 0x12, 0x30, 0x83, 0x8B, 0x12, 0x6B, 0xC3, 0x00 + }, + { + 0x3D, 0xA8, 0x9F, 0x5C, 0x52, 0xB0, 0x52, 0xE0, + 0x42, 0xE5, 0x11, 0x7B, 0x96, 0x80, 0x6E, 0xDB, + 0x1C, 0x55, 0x22, 0x7E, 0x85, 0x14, 0xB3, 0x9E, + 0x8B, 0x22, 0xBE, 0xA4, 0xC9, 0x53, 0x30, 0x80, + 0xA4, 0xD7, 0xA9, 0x24, 0x92, 0xB7, 0x51, 0x76, + 0x9B, 0x0E, 0x11, 0x9E, 0xF4, 0xDB, 0x2B, 0xB8, + 0x8D, 0x5C, 0x1E, 0x75, 0xB4, 0x03, 0x10, 0x74, + 0xD7, 0xF2, 0x1A, 0x78, 0x01, 0x4A, 0x1F, 0x96 + }, + { + 0x9B, 0xDC, 0xB4, 0x69, 0xC2, 0x66, 0x5D, 0xD8, + 0x46, 0x83, 0xE5, 0x81, 0x01, 0xFD, 0xAE, 0x5C, + 0x88, 0x29, 0x2A, 0x4E, 0x05, 0xC4, 0x00, 0xCA, + 0x08, 0x26, 0xDA, 0x79, 0x38, 0x2B, 0x8A, 0x28, + 0x26, 0xFF, 0x24, 0xFC, 0xD5, 0x56, 0xC9, 0xD5, + 0xB5, 0xAA, 0x89, 0x2F, 0x02, 0xB1, 0x67, 0x04, + 0x77, 0x27, 0x9B, 0xD7, 0x5F, 0x1B, 0x2B, 0x7B, + 0x67, 0x5E, 0xFA, 0xC3, 0x80, 0x60, 0x70, 0x36 + }, + { + 0x6C, 0x77, 0x85, 0x7B, 0x38, 0x53, 0x3E, 0x41, + 0x4A, 0xF7, 0x38, 0x7C, 0x98, 0x56, 0x8D, 0x71, + 0xC8, 0xF0, 0xE3, 0x5E, 0x22, 0xB0, 0x2E, 0x2A, + 0x1C, 0x0D, 0xC6, 0xD5, 0x7E, 0x37, 0xD8, 0x68, + 0x72, 0x5A, 0xD8, 0x23, 0x58, 0x6A, 0x0B, 0xEE, + 0xF3, 0x98, 0x89, 0xCC, 0x31, 0xF1, 0xF7, 0xFA, + 0xD0, 0x96, 0x0A, 0x12, 0x5E, 0x29, 0xDF, 0xEA, + 0x74, 0x55, 0x12, 0xD1, 0x79, 0xE5, 0xF5, 0x89 + }, + { + 0x88, 0xC9, 0x83, 0x3A, 0x6D, 0x44, 0xFC, 0x25, + 0xBB, 0x64, 0xF3, 0xE9, 0x8E, 0x83, 0x8F, 0xB4, + 0xFF, 0x56, 0x48, 0x96, 0xDC, 0xD3, 0x58, 0x3A, + 0x8B, 0x57, 0xC9, 0x46, 0x6E, 0x74, 0x0C, 0x62, + 0x8B, 0x2D, 0x26, 0xEA, 0x14, 0x7C, 0xB3, 0x11, + 0x10, 0xFB, 0xAD, 0xCF, 0x9D, 0x01, 0x08, 0xAC, + 0xCE, 0xBE, 0x04, 0x31, 0x7D, 0x19, 0xFC, 0x03, + 0x66, 0xDE, 0x0C, 0x28, 0xA1, 0xA4, 0x5E, 0x2A + }, + { + 0x0A, 0xAB, 0xB3, 0xA1, 0x78, 0x46, 0x4A, 0x01, + 0x47, 0x64, 0x5F, 0x05, 0x71, 0x2A, 0x0A, 0x15, + 0x55, 0xC5, 0xB9, 0xA3, 0xE9, 0x99, 0xAB, 0x25, + 0x5A, 0xCA, 0x35, 0xC5, 0x03, 0x81, 0xF4, 0x90, + 0x55, 0x1A, 0x40, 0x89, 0x31, 0xAA, 0x6B, 0xE9, + 0xA4, 0xEF, 0x49, 0x7A, 0x16, 0x5B, 0x36, 0x66, + 0x3B, 0x1E, 0x1F, 0x05, 0x13, 0x48, 0x02, 0xB1, + 0x78, 0xB7, 0xC7, 0x04, 0x68, 0xCB, 0x98, 0xE8 + }, + { + 0x58, 0x50, 0xD8, 0x93, 0x70, 0x6B, 0x3B, 0xC2, + 0xDB, 0xBA, 0x9C, 0xFA, 0xB0, 0x28, 0xBE, 0xD8, + 0x19, 0xA2, 0x83, 0x11, 0xD2, 0xD6, 0xF0, 0xCD, + 0x8E, 0x27, 0x2E, 0xE6, 0x77, 0xBC, 0x87, 0x8A, + 0x0C, 0xED, 0x6C, 0x0D, 0xEA, 0x9E, 0x5C, 0xC9, + 0x4B, 0x2B, 0x4F, 0x59, 0x1A, 0x40, 0xEC, 0x9F, + 0xB1, 0x82, 0x22, 0xD6, 0xDE, 0xAC, 0xE1, 0xF9, + 0xC0, 0x83, 0xDC, 0x05, 0xDE, 0x11, 0x7A, 0x53 + }, + { + 0xBE, 0xE6, 0x96, 0xA4, 0x76, 0x4F, 0x94, 0x25, + 0xD9, 0x1B, 0x14, 0x17, 0x38, 0x62, 0x5A, 0x04, + 0x47, 0xA8, 0x22, 0xBB, 0xA7, 0xA8, 0x47, 0x78, + 0xCC, 0x3A, 0x77, 0xA3, 0x86, 0xCB, 0x18, 0x24, + 0x87, 0xDB, 0x51, 0x3B, 0xB8, 0xF3, 0x6F, 0xC2, + 0xF7, 0xE6, 0xD2, 0x89, 0x6E, 0x44, 0x56, 0xA5, + 0x23, 0x46, 0xC4, 0x94, 0x8E, 0x3E, 0xC6, 0x34, + 0xCB, 0xF1, 0x8F, 0x39, 0xC4, 0x46, 0xCB, 0xAB + }, + { + 0x3D, 0x9F, 0x75, 0xD3, 0xE5, 0x0D, 0x9B, 0xA3, + 0xBC, 0xAC, 0x4A, 0x4E, 0x11, 0x6B, 0x9B, 0x30, + 0x8D, 0xC6, 0x45, 0x99, 0xA3, 0x86, 0x4A, 0x9D, + 0xAF, 0xD7, 0x5C, 0xB7, 0x1F, 0x2D, 0xE3, 0x10, + 0x9F, 0x79, 0x56, 0xA7, 0xD2, 0xDD, 0x37, 0x4F, + 0x84, 0x06, 0xD7, 0x7F, 0x79, 0x63, 0x11, 0xE3, + 0xD3, 0x00, 0x89, 0xE5, 0x4D, 0xD6, 0xCE, 0x8A, + 0xBB, 0x02, 0xA8, 0x5A, 0x85, 0xAE, 0x92, 0xE4 + }, + { + 0xEF, 0x39, 0x51, 0x47, 0x5A, 0x16, 0xDF, 0x64, + 0x98, 0x32, 0x24, 0x04, 0x65, 0x30, 0xDC, 0x7C, + 0xB0, 0x53, 0xD2, 0x93, 0x94, 0x75, 0x39, 0x11, + 0xC4, 0x94, 0x99, 0x50, 0xF2, 0x3E, 0x8A, 0x92, + 0xC7, 0x09, 0xF4, 0x63, 0x69, 0xB2, 0x3A, 0x0D, + 0x70, 0x3A, 0x6F, 0x36, 0x49, 0x0F, 0x75, 0xBE, + 0x1E, 0x3E, 0x81, 0x29, 0xA8, 0x29, 0xF3, 0xDC, + 0xD7, 0x2D, 0x0E, 0x55, 0x49, 0x7B, 0x81, 0x33 + }, + { + 0xD4, 0x19, 0x7D, 0x2A, 0x68, 0x5B, 0xCA, 0x6B, + 0xFB, 0xDD, 0x0E, 0x3D, 0x84, 0xC7, 0x48, 0x01, + 0x35, 0x48, 0xBC, 0x84, 0x9F, 0xE6, 0x49, 0xDA, + 0xE7, 0xC4, 0xA2, 0x77, 0xFC, 0xBD, 0x8F, 0x81, + 0x8A, 0x9E, 0xDF, 0xA6, 0xCA, 0x14, 0xD7, 0xFE, + 0xEA, 0x72, 0x6B, 0x23, 0xB4, 0xA3, 0x3A, 0xA8, + 0xA3, 0xF5, 0xA6, 0x61, 0x67, 0x21, 0x5C, 0x61, + 0x48, 0xC0, 0x6B, 0x94, 0xCD, 0x8B, 0xFE, 0x37 + }, + { + 0x7A, 0x24, 0x40, 0x33, 0x35, 0xB8, 0x64, 0x10, + 0xD8, 0xD6, 0x93, 0xF1, 0x63, 0xD6, 0x19, 0x8A, + 0x68, 0x0F, 0x7E, 0x3A, 0xC0, 0x25, 0xEC, 0x44, + 0x74, 0x24, 0x9B, 0x01, 0x16, 0x77, 0xFE, 0x1C, + 0x86, 0x6A, 0xAF, 0x45, 0x3D, 0xB0, 0xE8, 0xF6, + 0x54, 0x33, 0x51, 0x50, 0x86, 0x3A, 0xCE, 0x57, + 0x66, 0x50, 0x80, 0x31, 0x91, 0x27, 0x8E, 0x9D, + 0x4B, 0x54, 0x7A, 0x43, 0x4C, 0x56, 0x54, 0xE2 + }, + { + 0xAF, 0x07, 0xC6, 0x7D, 0x58, 0x74, 0x3A, 0xEB, + 0x18, 0x50, 0xEB, 0x53, 0xB2, 0xDA, 0x78, 0xEC, + 0xF7, 0x09, 0x58, 0x18, 0x32, 0x5B, 0xEB, 0x86, + 0x6F, 0xF3, 0x13, 0xE3, 0x94, 0xC0, 0x07, 0xE0, + 0xC0, 0xB5, 0xA1, 0xCD, 0x7A, 0xE6, 0xBB, 0x37, + 0xCD, 0x27, 0x81, 0xB5, 0x2D, 0x15, 0x4D, 0x18, + 0x86, 0x5D, 0x5E, 0x37, 0xDB, 0xAA, 0x5F, 0x96, + 0x73, 0x9B, 0xF7, 0x69, 0x59, 0x96, 0xAE, 0x30 + }, + { + 0x28, 0xB3, 0xC2, 0x60, 0xFA, 0x7F, 0x23, 0xB9, + 0xCC, 0xAD, 0xD6, 0x15, 0xA1, 0x14, 0x69, 0x49, + 0x8A, 0xDB, 0x18, 0xD7, 0xA9, 0xF6, 0x84, 0xFD, + 0xE4, 0x35, 0xC0, 0x65, 0x33, 0xF5, 0xF5, 0x08, + 0xB2, 0x9B, 0x5E, 0xCD, 0x0E, 0xCD, 0x57, 0x36, + 0x9F, 0x22, 0xF1, 0xC5, 0x4E, 0x61, 0xBE, 0x6C, + 0xD1, 0x04, 0xC8, 0xF7, 0xD3, 0xE1, 0x84, 0x7A, + 0xAD, 0x67, 0x07, 0x3A, 0x47, 0x86, 0xE1, 0xDB + }, + { + 0xD6, 0x43, 0x23, 0x33, 0x25, 0x23, 0x9E, 0x2E, + 0xBD, 0x41, 0x1F, 0x0E, 0x00, 0x23, 0x30, 0x56, + 0x2E, 0xB1, 0xBB, 0x08, 0xE6, 0x88, 0x24, 0xB7, + 0x1B, 0x98, 0x19, 0x9C, 0x76, 0xD5, 0x31, 0x58, + 0xD9, 0x1D, 0xDD, 0x6F, 0x4F, 0x82, 0x61, 0xEC, + 0x1D, 0x72, 0xFC, 0x77, 0xC2, 0xCC, 0x23, 0x7E, + 0xDA, 0x15, 0xF0, 0x25, 0x7C, 0xF0, 0x7B, 0x84, + 0xCF, 0x1F, 0xBD, 0x1D, 0xBA, 0xFA, 0x1D, 0xFC + }, + { + 0x3D, 0x7B, 0x44, 0xCC, 0x82, 0xEF, 0xCA, 0xFC, + 0xAB, 0xA6, 0xB1, 0x91, 0x05, 0x48, 0x95, 0x8C, + 0x18, 0x0A, 0x0E, 0x8D, 0x84, 0xBC, 0x66, 0x3E, + 0x8E, 0xF9, 0x53, 0x3B, 0xD8, 0x0C, 0x4B, 0xBA, + 0xAA, 0x25, 0x5B, 0x19, 0x81, 0xF7, 0x56, 0xEB, + 0x10, 0x79, 0xAD, 0x0F, 0x34, 0x71, 0xA1, 0xFC, + 0x9D, 0x7A, 0x43, 0x23, 0x39, 0x30, 0x3A, 0x57, + 0x81, 0xA3, 0x45, 0x35, 0x30, 0x9E, 0x5A, 0x24 + }, + { + 0xEB, 0x08, 0x12, 0xC9, 0x67, 0x06, 0x46, 0xD5, + 0x63, 0x19, 0x8B, 0x11, 0x7A, 0xAF, 0xC5, 0x6F, + 0xA1, 0xB6, 0x56, 0x0F, 0x88, 0xB5, 0x75, 0x4E, + 0xBF, 0xC3, 0x1B, 0x35, 0x52, 0x16, 0xD8, 0xD7, + 0x4D, 0x34, 0x1E, 0x35, 0xB2, 0x43, 0xBC, 0x93, + 0x8C, 0xF5, 0x46, 0xAF, 0x1F, 0x73, 0xC1, 0xB0, + 0x04, 0x55, 0xDC, 0x06, 0xB2, 0xC6, 0xC5, 0x35, + 0x27, 0x9E, 0x87, 0x67, 0x49, 0x8F, 0x14, 0xE6 + }, + { + 0x7B, 0xBA, 0x7D, 0x73, 0x04, 0x02, 0x1C, 0x75, + 0xB5, 0xD6, 0xCE, 0x66, 0xB4, 0xEF, 0xA5, 0x50, + 0x19, 0xD9, 0x42, 0xD2, 0x08, 0xAF, 0xAC, 0x82, + 0x11, 0xAA, 0x7E, 0x5E, 0x11, 0x1E, 0x27, 0x69, + 0x76, 0x70, 0xE4, 0xEC, 0x91, 0xBA, 0x30, 0x8E, + 0xBD, 0xFB, 0x19, 0x15, 0x4C, 0x3B, 0xAD, 0x05, + 0x26, 0xA6, 0x25, 0x41, 0xAE, 0x5D, 0x43, 0xD0, + 0xF5, 0x47, 0xB9, 0xD9, 0x8E, 0x07, 0x36, 0x60 + }, + { + 0xA8, 0xE2, 0xA9, 0x46, 0x8D, 0xA3, 0xE3, 0x54, + 0x3A, 0x23, 0xA5, 0x78, 0x78, 0x0E, 0x25, 0x62, + 0xC7, 0xCE, 0x57, 0xFD, 0x11, 0x20, 0xE1, 0xC0, + 0x24, 0xD7, 0xEA, 0x32, 0x90, 0x31, 0x70, 0x46, + 0x61, 0x6E, 0x14, 0xCD, 0x0F, 0x15, 0xA8, 0x6B, + 0x99, 0x39, 0x54, 0x9B, 0x14, 0x76, 0x11, 0xB6, + 0xA5, 0x5D, 0x85, 0xAB, 0xC2, 0x5F, 0x63, 0x95, + 0x46, 0xB8, 0x9D, 0xD2, 0x3D, 0x39, 0xA9, 0x85 + }, + { + 0xCE, 0x87, 0x4C, 0xD6, 0xE1, 0x95, 0x8B, 0x9D, + 0x7F, 0x11, 0xFF, 0x44, 0xAB, 0x08, 0x32, 0xE8, + 0x48, 0x70, 0x2C, 0x8F, 0x26, 0x65, 0x6B, 0xA1, + 0x0B, 0xF5, 0x72, 0x0A, 0x7C, 0xAA, 0x1F, 0x59, + 0x08, 0xC9, 0x9A, 0x96, 0x03, 0xA9, 0x8B, 0x41, + 0x6C, 0x57, 0x22, 0x8C, 0x81, 0x9C, 0xEA, 0xF8, + 0x27, 0x01, 0x3B, 0x2E, 0x6D, 0x6B, 0x2D, 0xAE, + 0x59, 0xDF, 0xF1, 0x04, 0xB9, 0x02, 0xC3, 0x1B + }, + { + 0x30, 0xFF, 0xFE, 0x37, 0x21, 0x8D, 0xB1, 0x94, + 0xB2, 0x32, 0x73, 0x49, 0x8F, 0x45, 0x44, 0xD3, + 0x84, 0x14, 0xBE, 0xE4, 0x1B, 0x17, 0x55, 0xA0, + 0xC6, 0xC2, 0xDB, 0xCB, 0x41, 0x19, 0x42, 0xD5, + 0xEC, 0xB9, 0xD4, 0x52, 0x3F, 0xB4, 0x79, 0x4B, + 0xA3, 0x6E, 0x57, 0x9A, 0xF2, 0xF8, 0xDD, 0x85, + 0x19, 0x99, 0x23, 0x31, 0x83, 0xFA, 0xB2, 0x7B, + 0x47, 0xAD, 0xD8, 0x7D, 0xF3, 0x59, 0x14, 0xBB + }, + { + 0xCE, 0xF4, 0x43, 0x1D, 0xCE, 0x9F, 0xF5, 0x5A, + 0x00, 0x30, 0x0E, 0xC8, 0x64, 0x9E, 0x27, 0x58, + 0x36, 0x18, 0x22, 0x43, 0x69, 0xF6, 0x0A, 0x5C, + 0x89, 0x6B, 0x2A, 0x31, 0x10, 0xB0, 0x32, 0xB8, + 0x7C, 0x9E, 0xE4, 0xF2, 0x6C, 0x5F, 0x0B, 0xDB, + 0x50, 0x3E, 0xA7, 0x44, 0x7A, 0x5D, 0xB3, 0xF7, + 0x07, 0xFE, 0x34, 0x10, 0xDA, 0xCD, 0xD7, 0x57, + 0x22, 0x19, 0xBD, 0xEA, 0x8E, 0x17, 0xDC, 0x04 + }, + { + 0x8F, 0xF0, 0xBC, 0xB7, 0x5F, 0x00, 0x61, 0xB5, + 0xF9, 0x09, 0x29, 0x8F, 0x56, 0x9E, 0x45, 0xC7, + 0x5E, 0xD2, 0xD6, 0x4A, 0x81, 0x89, 0xCE, 0xBD, + 0x4E, 0x02, 0x56, 0x6E, 0x1A, 0x1B, 0x8B, 0xE5, + 0x3A, 0x78, 0x32, 0x28, 0x55, 0x8E, 0x28, 0xB5, + 0xF8, 0x7C, 0xCC, 0x2F, 0x42, 0x8F, 0x7F, 0x87, + 0x97, 0x44, 0xB5, 0x25, 0xB2, 0x49, 0x62, 0xB3, + 0x60, 0x4B, 0x12, 0x0F, 0x06, 0x77, 0x9F, 0x2E + }, + { + 0x7F, 0x8D, 0xDF, 0xFB, 0x4D, 0xC1, 0x51, 0x91, + 0xDE, 0x3D, 0xDB, 0xE4, 0xA0, 0xF8, 0x8B, 0x7A, + 0xB0, 0x2D, 0x48, 0xE2, 0x5C, 0xFC, 0x1F, 0xE9, + 0x1D, 0xA5, 0x57, 0xE8, 0x85, 0xD0, 0x12, 0xB8, + 0xF6, 0x55, 0x26, 0xC5, 0xB7, 0xB1, 0x01, 0x3F, + 0xC8, 0x16, 0x58, 0x50, 0x43, 0xA3, 0x45, 0x60, + 0x5A, 0x39, 0xD8, 0xDA, 0xD7, 0x0D, 0x8A, 0x64, + 0x48, 0x51, 0x32, 0x50, 0xAA, 0xC4, 0xF3, 0xD5 + }, + { + 0xB1, 0xFE, 0x8C, 0x68, 0xAE, 0xF6, 0xB4, 0xD4, + 0xB2, 0x33, 0x54, 0xEB, 0x8C, 0x1D, 0x8F, 0x5A, + 0x56, 0xE3, 0x2E, 0x76, 0xB9, 0x6A, 0xC8, 0x44, + 0x3B, 0x2A, 0xB8, 0x35, 0xE4, 0xC8, 0xB6, 0x74, + 0xB3, 0x3E, 0x4C, 0x6C, 0x6D, 0xC1, 0x21, 0xD7, + 0xC2, 0xD3, 0x4B, 0x59, 0xB3, 0x7A, 0x56, 0x8A, + 0x1C, 0x98, 0xD5, 0x00, 0x32, 0x4E, 0x53, 0x08, + 0x87, 0x85, 0xB6, 0xB0, 0x80, 0x63, 0x47, 0xD1 + }, + { + 0x8E, 0x87, 0x34, 0xFC, 0xF9, 0x25, 0x9E, 0xE3, + 0x7F, 0xE9, 0xC6, 0xCD, 0xA2, 0x82, 0xC2, 0xD5, + 0xEB, 0x83, 0xD0, 0xCF, 0x43, 0x9C, 0x86, 0x19, + 0xD4, 0xB0, 0x42, 0xFF, 0x69, 0x96, 0x6B, 0x03, + 0x56, 0x5B, 0xE4, 0xDF, 0x96, 0x39, 0x3F, 0xE6, + 0xBF, 0x35, 0xAF, 0xA1, 0x6E, 0x02, 0x73, 0xB6, + 0xD3, 0x39, 0xC0, 0x09, 0x95, 0xBF, 0x6F, 0x60, + 0xA7, 0x14, 0xEF, 0x18, 0x0E, 0xBB, 0x93, 0x15 + }, + { + 0xAE, 0x15, 0x6D, 0x43, 0xA7, 0x2C, 0x04, 0x29, + 0x42, 0x59, 0x58, 0x78, 0xA7, 0x83, 0x07, 0x97, + 0x60, 0xF5, 0x21, 0xED, 0xB8, 0xB2, 0xC3, 0xD4, + 0x1A, 0x56, 0x6B, 0x7C, 0xF7, 0x4A, 0x4A, 0x08, + 0xEA, 0x0F, 0x11, 0x9D, 0x24, 0x0A, 0x62, 0xEC, + 0x73, 0xB9, 0x50, 0x97, 0x88, 0xFA, 0x3A, 0xED, + 0xF1, 0x20, 0xEE, 0x88, 0xCB, 0x95, 0x1B, 0x69, + 0x3F, 0x8F, 0x7C, 0xAF, 0x8C, 0xBA, 0x37, 0x7F + }, + { + 0x93, 0x30, 0xAA, 0xCA, 0x8C, 0x08, 0x84, 0x46, + 0x58, 0xC2, 0x95, 0x06, 0xB1, 0xC3, 0x42, 0x72, + 0xE2, 0xB3, 0xC7, 0xB4, 0xE7, 0x5E, 0x6F, 0xE9, + 0x9A, 0x01, 0x07, 0xEC, 0x5D, 0xA4, 0x53, 0x0F, + 0xB1, 0xC8, 0x8C, 0xAA, 0x66, 0xDD, 0x9C, 0x47, + 0x1E, 0x01, 0xCA, 0x21, 0xA1, 0x3A, 0x5D, 0x6F, + 0x82, 0x15, 0xDE, 0xD3, 0x14, 0x7E, 0x94, 0xDE, + 0x20, 0x88, 0x57, 0x1F, 0xD1, 0xBF, 0x23, 0xB6 + }, + { + 0xC1, 0x29, 0xF2, 0x2C, 0x50, 0xF5, 0x99, 0x72, + 0x32, 0xE2, 0xB9, 0xF9, 0x3D, 0xFA, 0xA0, 0x0A, + 0xD8, 0xA5, 0x34, 0x29, 0xF9, 0xD1, 0x5B, 0x98, + 0x42, 0xE3, 0xAE, 0x08, 0xD8, 0x49, 0xEB, 0xDD, + 0x45, 0x23, 0x8C, 0x85, 0xF9, 0x2C, 0x6F, 0x91, + 0x7E, 0x0F, 0x8F, 0x6F, 0x94, 0xE2, 0x34, 0xBE, + 0x07, 0x61, 0x68, 0xE0, 0xDF, 0x43, 0xD0, 0x28, + 0x45, 0x52, 0x79, 0xA6, 0xFF, 0x65, 0xDC, 0x84 + }, + { + 0x0E, 0x2B, 0x4B, 0xC2, 0xF6, 0xA7, 0x5B, 0xE4, + 0xB7, 0xC9, 0xD4, 0xB5, 0x3D, 0x10, 0x4D, 0xA0, + 0x65, 0x85, 0x8D, 0x38, 0x7B, 0x34, 0x0B, 0xC1, + 0x63, 0x4F, 0x3A, 0x83, 0x32, 0xD5, 0x4C, 0xAA, + 0x94, 0x30, 0x24, 0xB2, 0x13, 0xDC, 0x8D, 0x4F, + 0x21, 0x9E, 0xC8, 0xE1, 0xDE, 0xCA, 0xC7, 0xD5, + 0xC6, 0xAE, 0x69, 0xC9, 0xEF, 0xD8, 0x81, 0x49, + 0x36, 0x78, 0x38, 0x20, 0x5D, 0x0D, 0xC7, 0xC0 + }, + { + 0x83, 0xB5, 0x43, 0x85, 0x3B, 0x81, 0x42, 0xA8, + 0x3B, 0xEF, 0xF0, 0x73, 0x5F, 0x20, 0x18, 0x91, + 0xE7, 0xFF, 0xC6, 0x7D, 0xBD, 0xCD, 0x21, 0xA4, + 0x22, 0xBB, 0x33, 0x6D, 0xE3, 0x29, 0x72, 0xAE, + 0x03, 0x92, 0x64, 0x6F, 0x68, 0x27, 0xD8, 0x0C, + 0xDA, 0x65, 0x4F, 0xD3, 0xA0, 0x77, 0x4C, 0xD2, + 0xF9, 0x95, 0x51, 0x7C, 0xF0, 0x64, 0xC6, 0x17, + 0xF2, 0x1A, 0x54, 0x27, 0x5F, 0xE5, 0x0C, 0x8D + }, + { + 0x09, 0xBE, 0x15, 0xEB, 0x6A, 0x5C, 0x22, 0x6F, + 0x6D, 0x95, 0x08, 0xCB, 0xA4, 0xA2, 0x51, 0x9F, + 0xBA, 0x17, 0x2A, 0xF8, 0x37, 0x58, 0x27, 0xD7, + 0x54, 0xA7, 0xA1, 0xBC, 0x19, 0x25, 0xD1, 0x3F, + 0x5E, 0x63, 0x43, 0xF3, 0xE1, 0x4D, 0x08, 0xA0, + 0x6E, 0x8D, 0x37, 0xF8, 0xEC, 0x56, 0xFB, 0x43, + 0x8E, 0x62, 0x36, 0x66, 0xB6, 0xFB, 0x0E, 0x23, + 0xFB, 0x50, 0x47, 0x7D, 0x41, 0x1B, 0x0C, 0x3A + }, + { + 0xC3, 0x57, 0x97, 0xE9, 0x83, 0x2D, 0x3E, 0x23, + 0x23, 0x33, 0x5B, 0x8C, 0x19, 0xC5, 0xFA, 0x74, + 0x91, 0x60, 0x2D, 0xBF, 0x6B, 0xEA, 0x77, 0xFA, + 0xEE, 0xC9, 0x51, 0x0B, 0xC2, 0xE8, 0x91, 0xC8, + 0xC3, 0x46, 0x21, 0x99, 0xF6, 0x04, 0x18, 0xD2, + 0xE0, 0xAB, 0xFF, 0xE3, 0x1B, 0x61, 0x3B, 0xB9, + 0x80, 0xEA, 0x32, 0xB7, 0x6C, 0x82, 0x43, 0x8D, + 0x02, 0x5F, 0x67, 0x8C, 0xAF, 0x48, 0x24, 0xA4 + }, + { + 0xCF, 0xC0, 0x57, 0xFD, 0xA7, 0x8A, 0x50, 0x31, + 0x8F, 0x49, 0x78, 0xFF, 0xFF, 0xAF, 0x77, 0x17, + 0x98, 0xE1, 0x2C, 0x3E, 0xA8, 0xC7, 0x98, 0x19, + 0x5B, 0xC5, 0xB4, 0xE6, 0x89, 0x1E, 0x61, 0xAA, + 0x25, 0xF7, 0xAF, 0x4A, 0xA7, 0x28, 0x6A, 0xC8, + 0x50, 0x76, 0x62, 0xC9, 0x07, 0xED, 0x91, 0x3E, + 0xDA, 0x65, 0x8F, 0x63, 0xFC, 0x47, 0x99, 0x7C, + 0x59, 0xB8, 0x59, 0x70, 0xF8, 0x78, 0xCA, 0x18 + }, + { + 0xD8, 0xEB, 0xE0, 0xE6, 0x38, 0xFC, 0x53, 0x5B, + 0x52, 0xCB, 0x0A, 0xFC, 0xE0, 0xF8, 0x2D, 0xDE, + 0x28, 0x57, 0x01, 0xAF, 0xF3, 0x29, 0xA5, 0x4B, + 0xA0, 0x6D, 0xFD, 0x3D, 0x1B, 0x4B, 0x31, 0xF9, + 0xF4, 0xB2, 0x4D, 0x9D, 0x68, 0x36, 0xF1, 0x22, + 0x3D, 0x6D, 0xE6, 0x6B, 0xAE, 0x78, 0x88, 0xFE, + 0xBC, 0x20, 0x40, 0xCF, 0xE9, 0x30, 0xE6, 0x9C, + 0xED, 0x59, 0xDA, 0x6D, 0xA8, 0xA0, 0xA6, 0xA6 + }, + { + 0x16, 0xB8, 0xC5, 0x5C, 0xF2, 0xF1, 0x35, 0xA4, + 0x32, 0x59, 0x0D, 0x2D, 0x4C, 0xFA, 0x38, 0x59, + 0x2F, 0x59, 0x35, 0xF8, 0xE7, 0x1C, 0xE0, 0x8A, + 0x02, 0x06, 0xA0, 0xE5, 0xAB, 0xEA, 0x90, 0xB2, + 0xE1, 0x07, 0xEB, 0x86, 0xB9, 0x18, 0x82, 0x3B, + 0xDD, 0x3B, 0xD2, 0x66, 0x07, 0x22, 0xC8, 0xDB, + 0xFA, 0x66, 0xAB, 0xB9, 0xF8, 0x63, 0x8E, 0x46, + 0x34, 0x02, 0xF6, 0x57, 0xA1, 0x68, 0x64, 0x0A + }, + { + 0x6A, 0x6E, 0x89, 0x38, 0x4F, 0x53, 0x5F, 0x02, + 0x17, 0x6C, 0x48, 0xA9, 0x93, 0xD3, 0x68, 0x7B, + 0x38, 0x9B, 0xFC, 0x03, 0x05, 0x0C, 0x77, 0x70, + 0x86, 0x35, 0x5C, 0x1A, 0x55, 0x59, 0x77, 0x42, + 0xF0, 0xB7, 0x48, 0x34, 0xA7, 0x1D, 0x05, 0x2A, + 0xE8, 0xA8, 0x3D, 0xC3, 0x4A, 0x8F, 0xD7, 0xBA, + 0x5A, 0xA6, 0x9D, 0xBD, 0x61, 0x2A, 0x4C, 0x22, + 0xDF, 0x4F, 0x74, 0xE2, 0x52, 0x8F, 0xB7, 0xA3 + }, + { + 0x1E, 0x40, 0x38, 0xCF, 0xA5, 0x0D, 0x8B, 0x13, + 0xEF, 0x68, 0xBE, 0xC3, 0xB0, 0xFF, 0xD5, 0x62, + 0xA0, 0x7A, 0xD6, 0x34, 0xB5, 0x82, 0x82, 0x57, + 0xDB, 0xA8, 0x73, 0x04, 0xF8, 0x23, 0xA9, 0x00, + 0x49, 0x2A, 0x31, 0x37, 0x19, 0x8B, 0x60, 0x5C, + 0xC7, 0xF7, 0x7C, 0x33, 0xB8, 0xCA, 0x3D, 0x94, + 0x0F, 0xD9, 0xB3, 0x38, 0xCF, 0x6B, 0x7B, 0x36, + 0xE7, 0xD9, 0xD9, 0x27, 0x20, 0x97, 0x93, 0xD0 + }, + { + 0x5B, 0xA6, 0xCD, 0x98, 0x8F, 0xF9, 0xA4, 0x81, + 0x91, 0x42, 0x21, 0x7E, 0xD6, 0x5D, 0x43, 0x7B, + 0x41, 0x3B, 0xA5, 0x02, 0x6B, 0x55, 0x4D, 0x8D, + 0x94, 0xEA, 0x27, 0x02, 0xC0, 0x96, 0xD1, 0x01, + 0x47, 0x75, 0xDB, 0xA2, 0xCA, 0xE9, 0x6F, 0x1E, + 0x2E, 0x72, 0x29, 0xC3, 0x78, 0xF2, 0x0B, 0x03, + 0x89, 0xE1, 0x19, 0x54, 0x7F, 0xDD, 0x35, 0x22, + 0x4A, 0x61, 0x7F, 0xCD, 0xCD, 0x0C, 0xB3, 0xAF + }, + { + 0x2D, 0x20, 0x96, 0x12, 0x30, 0xE2, 0x50, 0xF8, + 0x1D, 0xDC, 0xD2, 0xD2, 0xAB, 0x3E, 0xF0, 0xDA, + 0xCF, 0x96, 0x85, 0x1E, 0xBA, 0xE5, 0x96, 0x34, + 0x47, 0x19, 0x2C, 0xDB, 0x89, 0xE4, 0x8E, 0x84, + 0xF3, 0x96, 0xEC, 0x9A, 0x09, 0x25, 0x27, 0x84, + 0xE1, 0x73, 0xAD, 0xA5, 0x2A, 0x9C, 0x81, 0xAC, + 0xDA, 0xB3, 0xD8, 0xD6, 0x83, 0x80, 0x24, 0x7A, + 0xE9, 0x75, 0x23, 0x9B, 0x01, 0x7D, 0xC1, 0xCE + }, + { + 0x35, 0x38, 0x3E, 0xA7, 0x76, 0x2B, 0x55, 0x31, + 0x0A, 0x7D, 0x57, 0xFB, 0xD5, 0xA5, 0x49, 0x97, + 0x57, 0x9B, 0x0B, 0xA3, 0x9A, 0x4E, 0xB8, 0x87, + 0x94, 0x2B, 0xD1, 0x4F, 0xD8, 0x48, 0x31, 0x88, + 0xE5, 0x00, 0x48, 0x83, 0x8D, 0x6C, 0x02, 0xDC, + 0x75, 0x89, 0x59, 0xA9, 0xF7, 0x4D, 0x83, 0x37, + 0x27, 0x43, 0xE8, 0x64, 0xC6, 0x01, 0xED, 0x70, + 0x40, 0xA9, 0xE8, 0x71, 0x52, 0xD4, 0xCF, 0xFB + }, + { + 0x0B, 0x22, 0x3B, 0x6A, 0x1C, 0x2D, 0x3A, 0xB3, + 0xF9, 0x07, 0x7A, 0x31, 0x7B, 0x7F, 0xE3, 0x2F, + 0x6F, 0x95, 0x7B, 0x7B, 0x17, 0x41, 0xF2, 0x71, + 0x77, 0x71, 0x83, 0x4D, 0x37, 0x96, 0xA1, 0x9B, + 0xA3, 0x62, 0x73, 0xC9, 0xEE, 0xD6, 0x4C, 0x07, + 0xFA, 0x4E, 0x9A, 0xF7, 0xA9, 0x8A, 0xCE, 0x9C, + 0x78, 0x9A, 0x79, 0xA5, 0xA0, 0xF9, 0x4D, 0x04, + 0x05, 0xAA, 0xF0, 0x4A, 0xF3, 0x1E, 0xD7, 0x97 + }, + { + 0x5A, 0x00, 0x7F, 0x58, 0x95, 0x52, 0x4A, 0x5E, + 0x80, 0x37, 0x03, 0x6E, 0x0F, 0x26, 0x39, 0xFD, + 0xA8, 0xC5, 0xC1, 0x51, 0x2D, 0x76, 0xE9, 0xD1, + 0x9B, 0x3D, 0xD2, 0xD5, 0xBA, 0x43, 0xF5, 0x07, + 0x97, 0x41, 0xA4, 0x58, 0x31, 0x3C, 0x5E, 0x02, + 0x40, 0x0C, 0xE0, 0x2C, 0xB6, 0x56, 0x80, 0xBE, + 0x28, 0x2E, 0xAC, 0xD9, 0xA2, 0x54, 0xEF, 0x1C, + 0xDD, 0xEE, 0xBD, 0xCE, 0xE8, 0x5D, 0x41, 0x87 + }, + { + 0xBE, 0x4D, 0xD1, 0xCC, 0xBD, 0xE1, 0x67, 0x00, + 0x04, 0xD0, 0xEF, 0xAB, 0x65, 0x43, 0xE9, 0x1C, + 0x4E, 0x46, 0x64, 0xE5, 0xA2, 0xA8, 0x8B, 0xAC, + 0x6D, 0xD2, 0x7D, 0x27, 0x64, 0x8D, 0x30, 0x2A, + 0x06, 0x5B, 0xE6, 0x07, 0x8B, 0x22, 0xE4, 0xC4, + 0xAB, 0x4F, 0x7F, 0x7C, 0xBF, 0xAF, 0xC1, 0xAD, + 0x86, 0xEC, 0x2A, 0x50, 0x4F, 0xE5, 0x85, 0x17, + 0x66, 0xF7, 0xA3, 0x24, 0x47, 0x57, 0xCB, 0x6F + }, + { + 0x0F, 0xB4, 0x48, 0x3F, 0x96, 0x59, 0x29, 0x6C, + 0xB9, 0x24, 0x5B, 0x57, 0x79, 0x2A, 0x1E, 0x6A, + 0x99, 0xF2, 0x87, 0x90, 0x07, 0x72, 0x87, 0x96, + 0x8A, 0xB3, 0xEF, 0x35, 0x89, 0xE6, 0x90, 0x24, + 0x06, 0xF1, 0xF3, 0x9D, 0xCC, 0xE0, 0x06, 0x1D, + 0xEA, 0x94, 0x0F, 0xC8, 0xC1, 0xC4, 0x9F, 0x4B, + 0x54, 0x5E, 0xED, 0x59, 0xE9, 0x6D, 0xDA, 0xE9, + 0x6A, 0x6C, 0x35, 0xB5, 0x59, 0x3C, 0x29, 0x77 + }, + { + 0x41, 0xD1, 0xFA, 0xDC, 0x60, 0xA4, 0x6C, 0x9A, + 0xD0, 0x12, 0x0A, 0x3F, 0x54, 0xD0, 0x05, 0xF5, + 0xA1, 0x07, 0x5E, 0x2F, 0x71, 0xEE, 0x0D, 0xA6, + 0x18, 0xBA, 0xC1, 0x46, 0x1E, 0xFA, 0xE9, 0x69, + 0xEC, 0xCD, 0x7A, 0xA5, 0x75, 0xC4, 0xCD, 0xAE, + 0x97, 0x1D, 0xED, 0x13, 0xAE, 0x13, 0xC5, 0x06, + 0x87, 0x2C, 0xEC, 0xB5, 0xB2, 0x08, 0xFA, 0x72, + 0xA9, 0x48, 0x40, 0x02, 0x3E, 0xDB, 0x3E, 0xFE + }, + { + 0x2F, 0x7F, 0xDC, 0x1D, 0xA4, 0x4B, 0x6E, 0x5D, + 0x2D, 0xEC, 0xDE, 0x82, 0x1A, 0xAF, 0x4B, 0x49, + 0x16, 0x8C, 0x02, 0xE8, 0xD5, 0xF2, 0x5D, 0x5C, + 0x69, 0x98, 0x71, 0x08, 0x3A, 0xEB, 0xD9, 0x28, + 0xB7, 0x4D, 0xC2, 0x2D, 0xCB, 0xED, 0xFA, 0xBA, + 0x93, 0x16, 0xAE, 0xFC, 0xA8, 0x48, 0xD1, 0x5F, + 0x05, 0x17, 0x32, 0x99, 0x03, 0xD3, 0x4B, 0x83, + 0x70, 0xDD, 0xF9, 0xBD, 0x58, 0xC6, 0xD0, 0xCD + }, + { + 0x88, 0x55, 0x8A, 0x46, 0x4E, 0xE1, 0xA8, 0x80, + 0x3B, 0x23, 0x95, 0xAF, 0x6A, 0x64, 0x90, 0x84, + 0x2B, 0x5C, 0xD4, 0x3D, 0x41, 0xF6, 0xC0, 0x7C, + 0xD6, 0xC5, 0xF8, 0x5F, 0x82, 0xF5, 0x84, 0x32, + 0xA0, 0xB1, 0x62, 0xB4, 0x38, 0xBF, 0x0C, 0xB7, + 0x08, 0x2A, 0x76, 0x73, 0xE2, 0x87, 0xD6, 0xB9, + 0x0F, 0x8D, 0x0D, 0xC8, 0xAA, 0x5C, 0xEB, 0xA3, + 0x6B, 0xFA, 0x77, 0xB1, 0x5B, 0xA0, 0x69, 0x16 + }, + { + 0xEC, 0xC1, 0x49, 0x91, 0x7B, 0x26, 0x63, 0x98, + 0xB6, 0xF3, 0x29, 0x7E, 0x96, 0x96, 0x73, 0xB1, + 0x4E, 0xAE, 0x69, 0xCE, 0x43, 0x67, 0x1F, 0xD3, + 0xC6, 0xC2, 0x15, 0xC7, 0xCF, 0x42, 0xDE, 0xA1, + 0x02, 0xFC, 0x6B, 0xD9, 0x0C, 0x87, 0xDB, 0xD4, + 0x29, 0x02, 0x51, 0x12, 0x9C, 0xC1, 0x9B, 0x38, + 0xCC, 0xF0, 0x0C, 0xBD, 0xB1, 0x6D, 0xD8, 0xDE, + 0x51, 0x58, 0x60, 0x1A, 0x41, 0x6B, 0x1F, 0x00 + }, + { + 0xED, 0x30, 0x12, 0xF8, 0x9D, 0x71, 0xED, 0x13, + 0xBB, 0x82, 0x72, 0xEC, 0xDC, 0x3D, 0x0F, 0x51, + 0xE1, 0x4A, 0x37, 0xC1, 0xEF, 0x77, 0x57, 0x77, + 0x7A, 0xDA, 0x67, 0x12, 0x78, 0x4B, 0xE1, 0x6E, + 0xCF, 0xD3, 0xE6, 0x40, 0x58, 0x30, 0xF5, 0x1D, + 0xB3, 0x3D, 0xCB, 0x85, 0x52, 0x92, 0x93, 0xE2, + 0x3E, 0x47, 0x3A, 0xBF, 0x8C, 0x5C, 0x76, 0x55, + 0xD0, 0xC4, 0xF1, 0x52, 0xD0, 0x48, 0xBA, 0xB2 + }, + { + 0x09, 0x7A, 0x81, 0x19, 0x1E, 0x10, 0x05, 0x67, + 0x6D, 0x6E, 0x22, 0xA9, 0x63, 0x48, 0xFA, 0x4A, + 0x7C, 0x95, 0x61, 0xFD, 0x4D, 0x22, 0x8E, 0xB2, + 0x5F, 0x29, 0x47, 0x56, 0xBB, 0x87, 0xA2, 0xBA, + 0x88, 0x47, 0x5B, 0x03, 0x6F, 0x79, 0xFE, 0x37, + 0x3D, 0x75, 0x40, 0x87, 0x05, 0x52, 0x00, 0x1D, + 0x54, 0x79, 0x5F, 0x25, 0x92, 0x39, 0xBE, 0x6D, + 0x32, 0xC4, 0x87, 0xD1, 0x94, 0x4F, 0x1F, 0xE7 + }, + { + 0x3F, 0xC7, 0x98, 0xE4, 0x69, 0xD3, 0x90, 0x86, + 0xBA, 0x0B, 0xB4, 0x06, 0x3E, 0x80, 0x5F, 0xDF, + 0xB2, 0x20, 0x8D, 0xE4, 0x99, 0x18, 0x41, 0x73, + 0xF9, 0xA2, 0x36, 0x4D, 0x56, 0xBC, 0xD5, 0x63, + 0xED, 0x61, 0x9B, 0xB6, 0x87, 0x32, 0x24, 0x25, + 0x01, 0x4A, 0x1A, 0xAD, 0x3B, 0xCF, 0x50, 0xD2, + 0x2D, 0x83, 0xA9, 0x9D, 0x09, 0x73, 0x0A, 0x92, + 0xEC, 0x65, 0x46, 0xB3, 0xFC, 0x40, 0xA2, 0xC6 + }, + { + 0x69, 0x12, 0xB4, 0xB3, 0x41, 0xC7, 0xDD, 0x70, + 0x68, 0x37, 0x38, 0xBA, 0x0E, 0x7D, 0xEB, 0xBA, + 0xBF, 0xCA, 0x5F, 0x4F, 0xB0, 0x76, 0x0C, 0x84, + 0x97, 0x76, 0xE9, 0x20, 0x75, 0x0B, 0xF1, 0x37, + 0x89, 0xA6, 0x99, 0x97, 0x96, 0x23, 0x4E, 0x9E, + 0x24, 0x07, 0x15, 0xB2, 0x67, 0x67, 0x78, 0x2B, + 0x85, 0xA6, 0x4D, 0x68, 0x0C, 0x6D, 0x4C, 0xD4, + 0x26, 0xAD, 0x72, 0xB2, 0xFC, 0xE0, 0x81, 0xE8 + }, + { + 0xCE, 0xCD, 0x14, 0x01, 0x50, 0x15, 0x7D, 0xC9, + 0x06, 0xC0, 0xFF, 0x7F, 0x87, 0xC0, 0x08, 0x8F, + 0x31, 0x64, 0x80, 0x78, 0x3B, 0x4F, 0xE0, 0xA5, + 0x94, 0x45, 0x10, 0xC6, 0x4A, 0x87, 0xE3, 0xED, + 0x06, 0x67, 0x97, 0xA2, 0x7C, 0xE9, 0xD0, 0xF2, + 0x84, 0xDC, 0xA5, 0x18, 0x44, 0x18, 0x08, 0xAC, + 0x18, 0x29, 0x0A, 0xFD, 0xC0, 0x31, 0x29, 0x4B, + 0x31, 0xAA, 0x8B, 0x4A, 0x9F, 0xCD, 0x78, 0xF8 + }, + { + 0x2A, 0x2B, 0xED, 0x5D, 0x6A, 0xC0, 0x89, 0x28, + 0x11, 0xA4, 0x09, 0xD9, 0xF1, 0xFF, 0x63, 0x03, + 0xCC, 0xF9, 0x55, 0x44, 0x57, 0x46, 0x99, 0xCD, + 0xA7, 0xF7, 0x35, 0x03, 0x01, 0xF6, 0xD0, 0xC4, + 0xE8, 0x6E, 0x63, 0x5C, 0x80, 0x87, 0x56, 0x66, + 0xE2, 0xBB, 0x39, 0x07, 0x51, 0x0D, 0x0E, 0x72, + 0x12, 0x0F, 0x04, 0x86, 0x5E, 0xDC, 0x4C, 0x6C, + 0xEE, 0xCB, 0x44, 0x62, 0xD6, 0xAF, 0x60, 0xFB + }, + { + 0x03, 0x85, 0xAE, 0x9B, 0x73, 0x5D, 0xC5, 0x9F, + 0x30, 0x4D, 0x41, 0x4C, 0xA0, 0x43, 0x74, 0x9A, + 0xB5, 0x1A, 0xB6, 0x65, 0xEE, 0x01, 0xBE, 0x5E, + 0x52, 0xDC, 0xF7, 0x25, 0xEE, 0x7D, 0xFE, 0xFE, + 0xA6, 0xAD, 0x73, 0xF3, 0x35, 0xEE, 0xCF, 0x2A, + 0x51, 0x02, 0xE8, 0x88, 0x07, 0xFD, 0xC7, 0x5A, + 0xE6, 0xDC, 0x49, 0x0D, 0x7B, 0x8B, 0x5F, 0x11, + 0x63, 0x03, 0xEF, 0x60, 0xA5, 0xF1, 0x7C, 0x06 + }, + { + 0x0C, 0xA3, 0xFF, 0x03, 0x89, 0x65, 0xC0, 0x3B, + 0xC6, 0x5B, 0xBE, 0x2D, 0x86, 0x6C, 0xE9, 0xE0, + 0xE4, 0xE7, 0xD0, 0x3D, 0xC7, 0xF8, 0x6B, 0xA5, + 0x65, 0x0F, 0x82, 0xDD, 0xB3, 0xA9, 0xAA, 0x84, + 0x6B, 0x2B, 0x1F, 0x55, 0x3B, 0xD8, 0x9F, 0xB4, + 0xF9, 0xB6, 0x2E, 0x3C, 0x7F, 0xAF, 0x9E, 0xC3, + 0x10, 0x9F, 0xA9, 0x0E, 0xE5, 0x6C, 0x24, 0x63, + 0xE6, 0xEF, 0xD1, 0xAB, 0xAD, 0x8E, 0x28, 0xE6 + }, + { + 0x6D, 0xFD, 0x4F, 0x22, 0x18, 0x4E, 0xD0, 0x91, + 0xFD, 0x5A, 0xBA, 0x03, 0x9F, 0xCD, 0x3D, 0xB9, + 0x22, 0xF5, 0xE5, 0x9B, 0xF8, 0x38, 0xC0, 0x37, + 0x35, 0x7F, 0xAD, 0x93, 0x4B, 0x45, 0x10, 0x60, + 0x3F, 0x43, 0xA7, 0x31, 0x9F, 0xFF, 0xA6, 0x23, + 0x86, 0xF8, 0x78, 0x8F, 0xDF, 0x9D, 0xED, 0x40, + 0xC6, 0x66, 0xB4, 0xBD, 0xCA, 0x86, 0xD9, 0x32, + 0x8F, 0xE5, 0x5A, 0xD8, 0x6B, 0x37, 0x2F, 0xC8 + }, + { + 0xA3, 0x18, 0x97, 0x61, 0x02, 0x74, 0x7D, 0x80, + 0x0F, 0x58, 0x4D, 0xF6, 0x5B, 0xFB, 0x44, 0x3B, + 0x85, 0x6F, 0x00, 0x9E, 0x74, 0xF7, 0x29, 0x46, + 0xD0, 0x07, 0x6C, 0xED, 0xAC, 0x04, 0x37, 0x6F, + 0xAB, 0x97, 0x34, 0x53, 0xAD, 0xAD, 0xC3, 0x10, + 0xF7, 0x20, 0x81, 0xCB, 0xBA, 0x96, 0x26, 0x4F, + 0xFE, 0x2B, 0x21, 0xA3, 0xB1, 0x8B, 0xE9, 0xD8, + 0x8C, 0x42, 0x46, 0xCB, 0xA6, 0xD3, 0x09, 0x01 + }, + { + 0xB5, 0xE6, 0xE4, 0xFC, 0xA0, 0xCF, 0x98, 0x48, + 0xA0, 0x05, 0x89, 0xC6, 0x54, 0x57, 0xDB, 0x68, + 0xB3, 0x25, 0x3A, 0x6E, 0x17, 0x78, 0x85, 0x41, + 0x47, 0x2E, 0x1F, 0xB9, 0x48, 0x17, 0xF8, 0x04, + 0x05, 0x4D, 0x07, 0xA5, 0xD3, 0x2D, 0xFA, 0x0C, + 0xDB, 0x6F, 0xB4, 0x4E, 0xED, 0x50, 0xD2, 0x0E, + 0x5F, 0x22, 0x64, 0x36, 0x11, 0x32, 0xFA, 0x5F, + 0xCF, 0xD6, 0xE1, 0xB3, 0x67, 0xC1, 0xBE, 0x28 + }, + { + 0x2E, 0xA4, 0x57, 0x38, 0x29, 0x25, 0xE0, 0x3C, + 0xF8, 0x11, 0x10, 0x05, 0x0E, 0x63, 0x6A, 0xD6, + 0x78, 0xE0, 0xAA, 0x3C, 0xBC, 0x69, 0x00, 0xBD, + 0xEF, 0x27, 0x8A, 0xAA, 0x18, 0xF2, 0x35, 0xE2, + 0x51, 0x60, 0xA2, 0x0E, 0x23, 0xFE, 0x0E, 0x62, + 0xA8, 0x51, 0x1B, 0x5D, 0xD0, 0x59, 0x2F, 0x79, + 0xCB, 0xC8, 0xEB, 0x7D, 0xEA, 0x64, 0xAC, 0x86, + 0x67, 0x49, 0x43, 0x45, 0xC6, 0x89, 0x2D, 0xD4 + }, + { + 0x96, 0xB3, 0x49, 0x8B, 0xCC, 0xD7, 0x8B, 0x5A, + 0x40, 0x1B, 0x27, 0x38, 0x78, 0x7D, 0x28, 0xA9, + 0x8A, 0x0E, 0xDF, 0xDC, 0x7C, 0x0B, 0x5F, 0xF9, + 0x43, 0xCF, 0xE1, 0xB1, 0x4E, 0x9C, 0xF5, 0xD9, + 0xED, 0x43, 0x10, 0x7D, 0xFB, 0xDD, 0x9E, 0x97, + 0x28, 0xD5, 0xFD, 0xD6, 0xF7, 0x1F, 0xBC, 0x77, + 0x0E, 0xAD, 0xDC, 0x4F, 0x2E, 0x40, 0x9A, 0xBE, + 0x71, 0x92, 0x7B, 0xAE, 0x1F, 0x8F, 0x73, 0xD1 + }, + { + 0xCE, 0x1B, 0xFB, 0x9A, 0xFE, 0xD2, 0x8A, 0xF4, + 0xDC, 0x75, 0x35, 0xAD, 0xEF, 0x71, 0xB8, 0xF1, + 0xB8, 0x0A, 0x8D, 0x72, 0x94, 0xB4, 0x11, 0xFD, + 0x1E, 0xD3, 0x93, 0xCF, 0x23, 0x2D, 0x3A, 0x5C, + 0x5D, 0xF2, 0x3D, 0xBB, 0x1D, 0xB2, 0x6D, 0xDD, + 0xF6, 0xF7, 0x45, 0xF8, 0xBC, 0x24, 0xC3, 0x78, + 0x1F, 0x2D, 0xBB, 0xC8, 0x18, 0xA0, 0x0A, 0xE1, + 0xFB, 0x9D, 0x64, 0x63, 0xE9, 0x5F, 0x29, 0x86 + }, + { + 0xE6, 0x4D, 0x37, 0x35, 0x6B, 0x29, 0x6B, 0x36, + 0x93, 0x0E, 0xAB, 0xE4, 0x54, 0xDB, 0x11, 0xB2, + 0x09, 0x7B, 0x0C, 0x04, 0x0B, 0xED, 0x57, 0x98, + 0x87, 0x8D, 0x38, 0xA8, 0xC4, 0xD1, 0xC6, 0xF3, + 0x26, 0x1F, 0x36, 0xBF, 0xF7, 0x64, 0xE3, 0xB4, + 0xD6, 0x06, 0xB3, 0x17, 0xE5, 0xFF, 0x50, 0x04, + 0x18, 0x45, 0x92, 0xB0, 0xB7, 0xDD, 0xFB, 0x8C, + 0x2F, 0xD8, 0x35, 0x23, 0x26, 0xCD, 0xDD, 0xB1 + }, + { + 0x85, 0xE6, 0xFE, 0x54, 0xE1, 0xE7, 0x60, 0x46, + 0xAF, 0x68, 0xF5, 0xC6, 0x04, 0x4C, 0x1E, 0x3F, + 0xFF, 0x3B, 0xFC, 0xA0, 0xBA, 0xEC, 0xAE, 0xF6, + 0xA1, 0xDF, 0x90, 0x35, 0x0D, 0xF2, 0xB0, 0xBE, + 0xC6, 0xA4, 0x20, 0xEE, 0x8F, 0x49, 0xAD, 0x44, + 0x64, 0xEC, 0x4C, 0x1E, 0x7D, 0x71, 0xF6, 0x67, + 0x61, 0x4A, 0xCE, 0xBD, 0xAD, 0xA3, 0xDF, 0x32, + 0x07, 0x79, 0x07, 0x83, 0x23, 0xF6, 0xA8, 0xAF + }, + { + 0xB1, 0x2F, 0xF1, 0xEB, 0x3B, 0xAB, 0x32, 0x0D, + 0x78, 0x55, 0xB5, 0x49, 0xD7, 0x2B, 0x72, 0x47, + 0x59, 0x91, 0x68, 0x11, 0xCB, 0xCF, 0x3E, 0x1A, + 0x12, 0x82, 0x3F, 0x98, 0xB6, 0x4A, 0xB5, 0xC4, + 0x59, 0x41, 0x61, 0x0F, 0x6B, 0x47, 0x1E, 0x35, + 0xFF, 0x79, 0x28, 0x29, 0xDD, 0x5A, 0xDE, 0x51, + 0x79, 0x12, 0x57, 0x38, 0xF3, 0xF2, 0x37, 0x28, + 0x63, 0x0F, 0x1E, 0xEC, 0x57, 0x77, 0x5A, 0x19 + }, + { + 0xB4, 0xDB, 0xE7, 0x2A, 0x1E, 0x21, 0x69, 0x7A, + 0x47, 0x44, 0xBE, 0x65, 0x00, 0x0C, 0xB1, 0xBA, + 0xD3, 0x7C, 0xE2, 0x14, 0x16, 0xEE, 0x6F, 0xCE, + 0xA8, 0x4E, 0xBA, 0xF1, 0x2A, 0x59, 0xC1, 0x1D, + 0x7C, 0x08, 0x0D, 0xF9, 0x2F, 0xB2, 0xAA, 0x8F, + 0x1C, 0x4E, 0xE8, 0xE2, 0xA2, 0x2D, 0x30, 0xBE, + 0x49, 0x85, 0x82, 0xD7, 0xC5, 0xFB, 0xBA, 0x16, + 0x5A, 0x47, 0x26, 0x89, 0xAF, 0xF6, 0x01, 0xB6 + }, + { + 0x34, 0x82, 0x18, 0xBE, 0x4D, 0xE0, 0x8D, 0xFB, + 0x24, 0x5B, 0xF2, 0x52, 0x86, 0xE3, 0x66, 0x18, + 0x63, 0x1D, 0x3B, 0xDB, 0x58, 0x27, 0xD9, 0xF7, + 0x4F, 0xA0, 0x43, 0x01, 0x66, 0x11, 0x31, 0xA4, + 0xD5, 0x5C, 0x76, 0x09, 0xB1, 0xA6, 0xA0, 0x3B, + 0x85, 0x3F, 0x07, 0x33, 0xE0, 0xAE, 0xC0, 0x26, + 0x16, 0xA0, 0xA4, 0x0E, 0x84, 0x91, 0xF4, 0x94, + 0xD7, 0x6C, 0x15, 0x43, 0xCF, 0xC6, 0x82, 0x14 + }, + { + 0x42, 0x87, 0xE1, 0x9B, 0xAB, 0x1D, 0x4F, 0x75, + 0xE1, 0xD1, 0x97, 0xCB, 0xB4, 0x3F, 0x11, 0x33, + 0x13, 0x07, 0xF2, 0xF7, 0x5B, 0x8D, 0x0D, 0x50, + 0x27, 0x8E, 0xEC, 0x54, 0x09, 0x99, 0xA0, 0x09, + 0xC0, 0x33, 0x73, 0x52, 0x96, 0x07, 0xFD, 0xA6, + 0x05, 0xAA, 0x0F, 0x07, 0x39, 0xE2, 0x0B, 0xD1, + 0xFD, 0xAA, 0x27, 0xD7, 0xC0, 0xCD, 0xC8, 0x28, + 0x4D, 0x98, 0xE6, 0xC7, 0x55, 0xA7, 0x56, 0x2E + }, + { + 0x08, 0x56, 0x0C, 0x99, 0x88, 0xC8, 0xCE, 0x5A, + 0x88, 0x76, 0xA6, 0x00, 0xB6, 0xE5, 0x12, 0xB4, + 0xE2, 0x43, 0xA4, 0xA4, 0x30, 0x0A, 0xD5, 0xAB, + 0x2F, 0xF0, 0x63, 0x7C, 0xC5, 0x6A, 0x04, 0x41, + 0x64, 0x5B, 0x3D, 0xEB, 0x16, 0x84, 0x06, 0x4E, + 0xA4, 0x3B, 0xAE, 0x1C, 0xB6, 0x2D, 0x3B, 0xC4, + 0x15, 0x37, 0xFE, 0x8D, 0x7D, 0xEC, 0xA7, 0x17, + 0x29, 0x37, 0x77, 0x6B, 0xBE, 0xD7, 0x93, 0xA9 + }, + { + 0xB5, 0x36, 0x16, 0x23, 0x94, 0x77, 0x6F, 0xA7, + 0xDD, 0x5E, 0x9F, 0xDD, 0x01, 0x53, 0x0F, 0xDA, + 0x52, 0xBE, 0x1D, 0x39, 0xBD, 0x60, 0x9B, 0x3F, + 0x3B, 0xD0, 0x47, 0x6B, 0x81, 0x60, 0xAA, 0x18, + 0xAB, 0x2D, 0x37, 0xD2, 0x99, 0x16, 0x28, 0xBE, + 0x2F, 0xCC, 0x12, 0x56, 0xCD, 0x48, 0x55, 0x25, + 0xD1, 0xFA, 0x35, 0x6B, 0x04, 0xD3, 0x0E, 0x4A, + 0x0F, 0x9F, 0xFF, 0xC9, 0x93, 0x5C, 0xF4, 0x32 + }, + { + 0x02, 0xAB, 0xC9, 0x71, 0x75, 0xED, 0xB4, 0x7A, + 0x4C, 0xB4, 0xBD, 0x38, 0xD8, 0x2F, 0x86, 0xAA, + 0x09, 0x9C, 0x8B, 0x8F, 0xA8, 0xAB, 0x3F, 0xE1, + 0xCE, 0x10, 0x5A, 0x22, 0xBD, 0x61, 0x65, 0x78, + 0xC6, 0xDD, 0x15, 0x15, 0xDF, 0xB0, 0x39, 0x7E, + 0x1D, 0x9D, 0x06, 0x71, 0x91, 0x6D, 0xE4, 0xB5, + 0x22, 0xE7, 0x4E, 0x63, 0x75, 0x23, 0x68, 0x93, + 0xC8, 0xFD, 0xA6, 0xD2, 0x36, 0xBC, 0x8D, 0xA1 + }, + { + 0x21, 0xE1, 0xEB, 0x73, 0x12, 0x76, 0xA8, 0x35, + 0xA6, 0xDD, 0xEA, 0x71, 0x78, 0xB2, 0x3E, 0xBC, + 0x9A, 0xEC, 0xAA, 0xBC, 0x7C, 0xCD, 0x70, 0x65, + 0x87, 0xD7, 0x1B, 0x85, 0x44, 0x97, 0x93, 0xB0, + 0x7E, 0x7B, 0x17, 0x9A, 0x3D, 0xA7, 0xA5, 0x71, + 0x98, 0x29, 0x97, 0xE8, 0xF5, 0xA6, 0x7F, 0x8C, + 0x93, 0xDA, 0xF1, 0x1A, 0xAA, 0x23, 0xF0, 0x7E, + 0x4D, 0xF7, 0xA1, 0x31, 0x05, 0xA5, 0x42, 0x09 + }, + { + 0x1C, 0xC5, 0x37, 0xD3, 0xE5, 0x0E, 0xD9, 0xFD, + 0xCD, 0xC4, 0xF3, 0xCC, 0xB4, 0x81, 0x93, 0x75, + 0x41, 0x53, 0x04, 0xD8, 0xE5, 0xA6, 0xC0, 0x58, + 0x05, 0xB6, 0xB5, 0xD9, 0xE1, 0xFC, 0x18, 0x25, + 0x68, 0x64, 0xF1, 0x0C, 0xD8, 0x12, 0xF8, 0x48, + 0x01, 0xB8, 0x61, 0x6A, 0x92, 0xB4, 0x07, 0x95, + 0xA1, 0x55, 0x93, 0x24, 0x64, 0xF6, 0x2D, 0xBF, + 0x6E, 0xBD, 0x2F, 0x9A, 0xC3, 0xEE, 0x28, 0x16 + }, + { + 0x6F, 0x6C, 0xD2, 0x60, 0x05, 0xC8, 0xA5, 0x61, + 0xCF, 0xF5, 0x1E, 0x30, 0x1D, 0x1A, 0x06, 0x8F, + 0xC2, 0x8B, 0x9B, 0x65, 0x0D, 0xDD, 0x27, 0xAE, + 0x97, 0xB5, 0x22, 0xDA, 0xE9, 0x63, 0x91, 0x34, + 0xD5, 0xA1, 0x50, 0x58, 0x7B, 0x0A, 0x90, 0x1F, + 0x3B, 0x9A, 0xAB, 0xC7, 0xE3, 0x97, 0x84, 0x98, + 0x4C, 0xC5, 0x85, 0x23, 0x5D, 0x8E, 0x17, 0xCE, + 0x9E, 0x3B, 0x42, 0x10, 0x5B, 0xF9, 0x03, 0x4C + }, + { + 0x69, 0xC1, 0x7C, 0x28, 0x64, 0xC3, 0x37, 0x9F, + 0xAF, 0xB7, 0x14, 0xC0, 0x47, 0x5E, 0x00, 0xCF, + 0x7C, 0x9B, 0x37, 0x7D, 0x57, 0xA8, 0xBC, 0x96, + 0x98, 0xB4, 0xD3, 0x4A, 0x54, 0x85, 0x41, 0x76, + 0xA2, 0xF8, 0xD1, 0x5A, 0xFB, 0x54, 0x77, 0x56, + 0x04, 0x78, 0x73, 0x90, 0xD6, 0x00, 0x74, 0xCD, + 0x4B, 0xCA, 0x69, 0x02, 0xEA, 0x23, 0xD3, 0xAE, + 0x1A, 0xC0, 0x83, 0x40, 0x9F, 0xE3, 0x8A, 0x4D + }, + { + 0x86, 0x69, 0xB0, 0xAD, 0x35, 0x82, 0x9E, 0xDC, + 0x2A, 0x8A, 0x09, 0x85, 0x2B, 0x0E, 0xE9, 0xB3, + 0x90, 0x3B, 0xF6, 0xC1, 0xF8, 0x2F, 0x90, 0xA3, + 0xF0, 0xED, 0x95, 0x24, 0x19, 0x2F, 0x10, 0x91, + 0xFD, 0x64, 0x84, 0xE0, 0x4C, 0x3F, 0xEA, 0x8B, + 0x02, 0x2F, 0x4A, 0x89, 0x50, 0xDB, 0x17, 0xD4, + 0x73, 0x41, 0x45, 0xC0, 0xCE, 0xC5, 0xDC, 0x38, + 0x74, 0x55, 0xC1, 0x26, 0x90, 0x3F, 0x77, 0x66 + }, + { + 0x3F, 0x35, 0xC4, 0x5D, 0x24, 0xFC, 0xFB, 0x4A, + 0xCC, 0xA6, 0x51, 0x07, 0x6C, 0x08, 0x00, 0x0E, + 0x27, 0x9E, 0xBB, 0xFF, 0x37, 0xA1, 0x33, 0x3C, + 0xE1, 0x9F, 0xD5, 0x77, 0x20, 0x2D, 0xBD, 0x24, + 0xB5, 0x8C, 0x51, 0x4E, 0x36, 0xDD, 0x9B, 0xA6, + 0x4A, 0xF4, 0xD7, 0x8E, 0xEA, 0x4E, 0x2D, 0xD1, + 0x3B, 0xC1, 0x8D, 0x79, 0x88, 0x87, 0xDD, 0x97, + 0x13, 0x76, 0xBC, 0xAE, 0x00, 0x87, 0xE1, 0x7E + }, +}; + + + + +static const uint8_t blake2bp_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0x9D, 0x94, 0x61, 0x07, 0x3E, 0x4E, 0xB6, 0x40, + 0xA2, 0x55, 0x35, 0x7B, 0x83, 0x9F, 0x39, 0x4B, + 0x83, 0x8C, 0x6F, 0xF5, 0x7C, 0x9B, 0x68, 0x6A, + 0x3F, 0x76, 0x10, 0x7C, 0x10, 0x66, 0x72, 0x8F, + 0x3C, 0x99, 0x56, 0xBD, 0x78, 0x5C, 0xBC, 0x3B, + 0xF7, 0x9D, 0xC2, 0xAB, 0x57, 0x8C, 0x5A, 0x0C, + 0x06, 0x3B, 0x9D, 0x9C, 0x40, 0x58, 0x48, 0xDE, + 0x1D, 0xBE, 0x82, 0x1C, 0xD0, 0x5C, 0x94, 0x0A + }, + { + 0xFF, 0x8E, 0x90, 0xA3, 0x7B, 0x94, 0x62, 0x39, + 0x32, 0xC5, 0x9F, 0x75, 0x59, 0xF2, 0x60, 0x35, + 0x02, 0x9C, 0x37, 0x67, 0x32, 0xCB, 0x14, 0xD4, + 0x16, 0x02, 0x00, 0x1C, 0xBB, 0x73, 0xAD, 0xB7, + 0x92, 0x93, 0xA2, 0xDB, 0xDA, 0x5F, 0x60, 0x70, + 0x30, 0x25, 0x14, 0x4D, 0x15, 0x8E, 0x27, 0x35, + 0x52, 0x95, 0x96, 0x25, 0x1C, 0x73, 0xC0, 0x34, + 0x5C, 0xA6, 0xFC, 0xCB, 0x1F, 0xB1, 0xE9, 0x7E + }, + { + 0xD6, 0x22, 0x0C, 0xA1, 0x95, 0xA0, 0xF3, 0x56, + 0xA4, 0x79, 0x5E, 0x07, 0x1C, 0xEE, 0x1F, 0x54, + 0x12, 0xEC, 0xD9, 0x5D, 0x8A, 0x5E, 0x01, 0xD7, + 0xC2, 0xB8, 0x67, 0x50, 0xCA, 0x53, 0xD7, 0xF6, + 0x4C, 0x29, 0xCB, 0xB3, 0xD2, 0x89, 0xC6, 0xF4, + 0xEC, 0xC6, 0xC0, 0x1E, 0x3C, 0xA9, 0x33, 0x89, + 0x71, 0x17, 0x03, 0x88, 0xE3, 0xE4, 0x02, 0x28, + 0x47, 0x90, 0x06, 0xD1, 0xBB, 0xEB, 0xAD, 0x51 + }, + { + 0x30, 0x30, 0x2C, 0x3F, 0xC9, 0x99, 0x06, 0x5D, + 0x10, 0xDC, 0x98, 0x2C, 0x8F, 0xEE, 0xF4, 0x1B, + 0xBB, 0x66, 0x42, 0x71, 0x8F, 0x62, 0x4A, 0xF6, + 0xE3, 0xEA, 0xBE, 0xA0, 0x83, 0xE7, 0xFE, 0x78, + 0x53, 0x40, 0xDB, 0x4B, 0x08, 0x97, 0xEF, 0xFF, + 0x39, 0xCE, 0xE1, 0xDC, 0x1E, 0xB7, 0x37, 0xCD, + 0x1E, 0xEA, 0x0F, 0xE7, 0x53, 0x84, 0x98, 0x4E, + 0x7D, 0x8F, 0x44, 0x6F, 0xAA, 0x68, 0x3B, 0x80 + }, + { + 0x32, 0xF3, 0x98, 0xA6, 0x0C, 0x1E, 0x53, 0xF1, + 0xF8, 0x1D, 0x6D, 0x8D, 0xA2, 0xEC, 0x11, 0x75, + 0x42, 0x2D, 0x6B, 0x2C, 0xFA, 0x0C, 0x0E, 0x66, + 0xD8, 0xC4, 0xE7, 0x30, 0xB2, 0x96, 0xA4, 0xB5, + 0x3E, 0x39, 0x2E, 0x39, 0x85, 0x98, 0x22, 0xA1, + 0x45, 0xAE, 0x5F, 0x1A, 0x24, 0xC2, 0x7F, 0x55, + 0x33, 0x9E, 0x2B, 0x4B, 0x44, 0x58, 0xE8, 0xC5, + 0xEB, 0x19, 0xAA, 0x14, 0x20, 0x64, 0x27, 0xAA + }, + { + 0x23, 0x6D, 0xB9, 0x33, 0xF1, 0x8A, 0x9D, 0xBD, + 0x4E, 0x50, 0xB7, 0x29, 0x53, 0x90, 0x65, 0xBD, + 0xA4, 0x20, 0xDF, 0x97, 0xAC, 0x78, 0x0B, 0xE4, + 0x3F, 0x59, 0x10, 0x3C, 0x47, 0x2E, 0x0B, 0xCC, + 0xA6, 0xD4, 0x97, 0x38, 0x97, 0x86, 0xAF, 0x22, + 0xBA, 0x94, 0x30, 0xB7, 0x4D, 0x6F, 0x74, 0xB1, + 0x3F, 0x6F, 0x94, 0x9E, 0x25, 0x6A, 0x14, 0x0A, + 0xA3, 0x4B, 0x47, 0x70, 0x0B, 0x10, 0x03, 0x43 + }, + { + 0x23, 0x8C, 0x9D, 0x08, 0x02, 0x85, 0xE3, 0x54, + 0x35, 0xCB, 0x53, 0x15, 0x5D, 0x9F, 0x79, 0x2C, + 0xA1, 0xBB, 0x27, 0xDE, 0x4F, 0x9B, 0x6C, 0x87, + 0x26, 0xE1, 0x1C, 0x02, 0x8E, 0x7B, 0x87, 0x87, + 0x33, 0x54, 0x91, 0x12, 0xA3, 0x28, 0xB5, 0x0E, + 0x8C, 0xD8, 0xBA, 0x27, 0x87, 0x21, 0x7E, 0x46, + 0xB8, 0x16, 0x8D, 0x57, 0x11, 0x3D, 0xD4, 0x04, + 0xD9, 0x14, 0xE2, 0x9A, 0x6A, 0x54, 0x70, 0xE6 + }, + { + 0x9A, 0x02, 0x1E, 0xBD, 0x50, 0x4A, 0x97, 0x59, + 0x6D, 0x0E, 0x85, 0x04, 0x8A, 0xE1, 0xDA, 0x89, + 0x99, 0xE3, 0xA0, 0x47, 0x01, 0x6F, 0x17, 0xC6, + 0xC5, 0x55, 0x6C, 0x27, 0x31, 0xE9, 0xB1, 0x39, + 0x26, 0x1F, 0x84, 0x3F, 0xAD, 0x6B, 0xD4, 0x3F, + 0x7C, 0x7C, 0x58, 0x7F, 0x69, 0x8D, 0x69, 0xB6, + 0x82, 0xE5, 0x68, 0xB4, 0x42, 0xAC, 0x45, 0x88, + 0x98, 0x57, 0xB7, 0x69, 0x07, 0x34, 0xCD, 0xBB + }, + { + 0x3A, 0xBA, 0x07, 0xAE, 0x98, 0x0E, 0x33, 0x86, + 0x37, 0x47, 0x9D, 0xCA, 0x1E, 0x35, 0x28, 0x00, + 0xF4, 0x58, 0x8E, 0x62, 0xD8, 0x23, 0x36, 0x5A, + 0xA6, 0x9C, 0x5B, 0x25, 0xFC, 0xE1, 0x29, 0x68, + 0xD2, 0x6C, 0x9B, 0xDB, 0xEE, 0x9A, 0x32, 0xBF, + 0xFD, 0x42, 0xE6, 0xB2, 0x2C, 0x81, 0x38, 0xA6, + 0x1C, 0x1F, 0xCE, 0x49, 0xFF, 0xBC, 0x19, 0x0E, + 0x1E, 0x15, 0x16, 0x01, 0x53, 0xCC, 0xB6, 0xB4 + }, + { + 0x77, 0x4C, 0xDF, 0x9A, 0xBB, 0x50, 0x81, 0xFE, + 0x07, 0xEB, 0x57, 0x25, 0xE6, 0x06, 0x9B, 0x8D, + 0x6C, 0x7E, 0x60, 0x04, 0xA2, 0x4D, 0x70, 0xF7, + 0xDF, 0xAB, 0xFC, 0x03, 0x82, 0x5B, 0xBC, 0x3B, + 0x30, 0xE6, 0x20, 0xB6, 0x04, 0x1F, 0x3C, 0xC2, + 0x89, 0x6B, 0x14, 0xAB, 0x66, 0x0A, 0xF7, 0x2E, + 0x24, 0x95, 0x10, 0xAC, 0x2F, 0xE8, 0x10, 0xCC, + 0x77, 0x63, 0xA2, 0xE5, 0xC3, 0xFC, 0xA7, 0xFC + }, + { + 0x9E, 0x08, 0x9F, 0x51, 0x65, 0x7B, 0x29, 0xC2, + 0x66, 0x8E, 0x28, 0x50, 0x52, 0x4E, 0x53, 0xAE, + 0xAA, 0xA7, 0x30, 0x6F, 0x2A, 0xD5, 0xA2, 0x32, + 0xB5, 0xF0, 0x7F, 0x68, 0x8D, 0x8A, 0xB2, 0xB4, + 0x25, 0xDF, 0x7E, 0xA5, 0xBD, 0x3E, 0x9F, 0xFD, + 0x61, 0x68, 0x38, 0x90, 0x15, 0x1D, 0x78, 0xBB, + 0x94, 0x03, 0x11, 0x85, 0xAC, 0xA4, 0x81, 0xE2, + 0x14, 0x0F, 0xE3, 0x79, 0x85, 0x36, 0x76, 0x43 + }, + { + 0xB3, 0x5B, 0xD5, 0x4E, 0x4F, 0x81, 0x69, 0x6B, + 0x4F, 0x22, 0x31, 0x6A, 0x1E, 0x33, 0x7D, 0x98, + 0xD1, 0xC6, 0xB0, 0x61, 0x10, 0x99, 0x87, 0x63, + 0xB5, 0x91, 0x33, 0x35, 0x92, 0x3A, 0x40, 0x76, + 0xCB, 0x80, 0xD6, 0xD8, 0xA5, 0x18, 0x62, 0x91, + 0x13, 0x47, 0x7B, 0x30, 0xA1, 0x32, 0xA6, 0xB2, + 0x7F, 0xC1, 0xEE, 0x79, 0xF6, 0xB2, 0xE0, 0xD3, + 0x5D, 0x5B, 0xC2, 0x97, 0x27, 0x46, 0x3D, 0xB5 + }, + { + 0x12, 0x39, 0x30, 0xD5, 0xA4, 0xB7, 0x3B, 0x49, + 0x1F, 0x50, 0xE5, 0x6E, 0x2B, 0x73, 0x97, 0xA4, + 0x3D, 0x2E, 0x47, 0x87, 0x23, 0x76, 0x02, 0xB6, + 0x6F, 0xE0, 0xA8, 0x47, 0xBD, 0x13, 0xCB, 0xE8, + 0xB3, 0x7D, 0xC7, 0x03, 0xD7, 0xB2, 0xB4, 0xEA, + 0xA8, 0xBF, 0xB9, 0xA5, 0x8A, 0x7D, 0x71, 0x9C, + 0x90, 0x8F, 0x19, 0x66, 0xA2, 0xF1, 0x9F, 0xE6, + 0xEB, 0x1A, 0x78, 0x96, 0x2A, 0xFA, 0x5B, 0xF9 + }, + { + 0x08, 0x9C, 0xBC, 0x7E, 0xE1, 0xB1, 0x2C, 0x0C, + 0xC9, 0xC8, 0x3F, 0xF6, 0x66, 0xFE, 0xC8, 0x02, + 0x6B, 0xB7, 0x1B, 0x90, 0x84, 0x97, 0x9B, 0x0E, + 0xA8, 0xB7, 0x23, 0xBB, 0xBE, 0x8B, 0x00, 0xD4, + 0x10, 0x08, 0xB6, 0x04, 0x99, 0xF2, 0x4F, 0x24, + 0x1B, 0x63, 0x28, 0x1F, 0xE5, 0xB4, 0xD8, 0x89, + 0x66, 0x30, 0x9C, 0x0D, 0x7E, 0x64, 0x66, 0x91, + 0x05, 0xE5, 0x1E, 0x69, 0xD7, 0xAF, 0x8C, 0xE5 + }, + { + 0x6B, 0x3C, 0x67, 0x89, 0x47, 0xF6, 0x12, 0x52, + 0x65, 0x7C, 0x35, 0x49, 0x78, 0xC1, 0x01, 0xB2, + 0xFD, 0xD2, 0x72, 0x9E, 0xC3, 0x49, 0x27, 0xDD, + 0x5E, 0xFF, 0x0A, 0x7C, 0x0A, 0x86, 0x58, 0x26, + 0xE8, 0x33, 0xC3, 0x63, 0x23, 0x21, 0x31, 0xB1, + 0x05, 0x93, 0xBE, 0x1C, 0xCF, 0x6B, 0xA5, 0x4E, + 0xCC, 0x14, 0x31, 0x2F, 0x45, 0xBF, 0xFC, 0x24, + 0x04, 0x62, 0x9F, 0xF8, 0x02, 0x67, 0xF0, 0x94 + }, + { + 0xAA, 0x0C, 0x23, 0xEA, 0x1C, 0x6F, 0xE2, 0xE9, + 0x0A, 0x77, 0x18, 0xEF, 0x4A, 0xA4, 0x75, 0x1F, + 0xF6, 0xBE, 0xB9, 0xD4, 0x61, 0x63, 0x59, 0x5B, + 0x5D, 0x4F, 0xB8, 0x96, 0x00, 0x52, 0x5C, 0x5B, + 0x6C, 0xF1, 0x9E, 0xCD, 0xB2, 0x47, 0x78, 0x72, + 0xA7, 0xA1, 0x2D, 0x40, 0xE5, 0x06, 0x36, 0x08, + 0xE5, 0xF0, 0x00, 0x8E, 0x79, 0x72, 0xA9, 0xC0, + 0x1A, 0x4B, 0xE2, 0xAF, 0xE9, 0x53, 0x2F, 0x9C + }, + { + 0x63, 0x34, 0x7A, 0xB4, 0xCB, 0xB6, 0xF2, 0x89, + 0x52, 0x99, 0x2C, 0x07, 0x9D, 0x18, 0xD4, 0x20, + 0x01, 0xB7, 0xF3, 0xA9, 0xD0, 0xFD, 0x90, 0xB0, + 0xA4, 0x77, 0x1F, 0x69, 0x72, 0xF0, 0xC5, 0x32, + 0x89, 0xC8, 0xAE, 0xE1, 0x43, 0x29, 0x4B, 0x50, + 0xC6, 0x34, 0x12, 0x58, 0x5C, 0xDC, 0xE4, 0xFF, + 0x7B, 0xED, 0x11, 0x2C, 0xD0, 0x3C, 0x9B, 0x1D, + 0xF3, 0xDE, 0xF0, 0xCC, 0x32, 0x0D, 0x6B, 0x70 + }, + { + 0x23, 0x96, 0xC0, 0xCB, 0x9E, 0xDA, 0xAC, 0xA9, + 0xD8, 0xB1, 0x04, 0x65, 0x2C, 0xB7, 0xF1, 0x25, + 0xF1, 0x93, 0x55, 0x1A, 0xE5, 0xD7, 0xBC, 0x94, + 0x63, 0x30, 0x7C, 0x9E, 0x69, 0xCA, 0x7D, 0xA2, + 0x3A, 0x9F, 0xBC, 0xBC, 0xB8, 0x66, 0x69, 0xD5, + 0xBA, 0x63, 0x43, 0x85, 0x93, 0xE1, 0x32, 0xF9, + 0x92, 0xB5, 0x7C, 0x00, 0x17, 0xC8, 0x6D, 0xDB, + 0x9B, 0x47, 0x28, 0x6E, 0xF5, 0xB6, 0x87, 0x18 + }, + { + 0xA9, 0x4B, 0x80, 0x22, 0x57, 0xFD, 0x03, 0x1E, + 0xE6, 0x0F, 0x1B, 0xE1, 0x84, 0x38, 0x3A, 0x76, + 0x32, 0x85, 0x39, 0xF9, 0xD8, 0x06, 0x08, 0x72, + 0xEF, 0x35, 0x73, 0xBE, 0xB6, 0xF2, 0x73, 0x68, + 0x08, 0x95, 0x90, 0xED, 0xBB, 0x21, 0xF4, 0xD8, + 0xF1, 0x81, 0xBA, 0x66, 0x20, 0x75, 0xF9, 0x19, + 0x05, 0x97, 0x4B, 0xEE, 0xEF, 0x1F, 0xC5, 0xCB, + 0x9B, 0xCF, 0xB2, 0x8A, 0xAE, 0x1E, 0x4D, 0xE3 + }, + { + 0x52, 0xC7, 0xD3, 0x39, 0x9A, 0x03, 0x80, 0x04, + 0xBE, 0xA5, 0x2D, 0x3E, 0xA9, 0xE9, 0x1E, 0x25, + 0x44, 0xC8, 0x65, 0x2A, 0xB8, 0xF5, 0x28, 0x5C, + 0x9D, 0x32, 0x18, 0x63, 0x7A, 0x6D, 0x9F, 0xCA, + 0xF0, 0xD9, 0x65, 0xB3, 0x58, 0x8E, 0xE6, 0xD7, + 0x3F, 0xA5, 0x99, 0xDE, 0xCA, 0x1F, 0x41, 0xDE, + 0xD8, 0x02, 0x5B, 0xF7, 0x76, 0x8E, 0x0E, 0x20, + 0x0E, 0x8C, 0xD3, 0xFF, 0x86, 0x8C, 0x38, 0x00 + }, + { + 0xB6, 0x29, 0xF5, 0x71, 0x62, 0x87, 0x6A, 0xDB, + 0x8F, 0xA9, 0x57, 0x2E, 0xBA, 0x4E, 0x1E, 0xCD, + 0x75, 0xA6, 0x56, 0x73, 0x08, 0xDE, 0x90, 0xDB, + 0xB8, 0xFF, 0xDE, 0x77, 0xDE, 0x82, 0x13, 0xA4, + 0xD7, 0xF7, 0xCB, 0x85, 0xAE, 0x1B, 0x71, 0xE6, + 0x45, 0x7B, 0xC4, 0xE8, 0x9C, 0x0D, 0x9D, 0xE2, + 0x41, 0xB6, 0xB9, 0xF3, 0x74, 0xB7, 0x34, 0x19, + 0x4D, 0xB2, 0xB2, 0x67, 0x02, 0xD7, 0xCB, 0x7C + }, + { + 0x72, 0x28, 0x46, 0xDD, 0xAC, 0xAA, 0x94, 0xFD, + 0xE6, 0x63, 0x2A, 0x2D, 0xC7, 0xDC, 0x70, 0x8B, + 0xDF, 0x98, 0x31, 0x1C, 0x9F, 0xB6, 0x3C, 0x61, + 0xE5, 0x25, 0xFD, 0x4B, 0x0D, 0x87, 0xB6, 0x38, + 0x8B, 0x5A, 0xF7, 0x04, 0x20, 0x18, 0xDD, 0xCA, + 0x06, 0x5E, 0x8A, 0x55, 0xBB, 0xFD, 0x68, 0xEE, + 0x61, 0xFC, 0xD3, 0xC6, 0x87, 0x8F, 0x5B, 0x09, + 0xBC, 0xC2, 0x7B, 0xED, 0x61, 0xDD, 0x93, 0xED + }, + { + 0x1C, 0xED, 0x6A, 0x0C, 0x78, 0x9D, 0xDB, 0x29, + 0x56, 0x78, 0xAD, 0x43, 0xA3, 0x22, 0xD8, 0x96, + 0x61, 0x7F, 0xDE, 0x27, 0x5F, 0x13, 0x8C, 0xCC, + 0xFB, 0x13, 0x26, 0xCD, 0x3F, 0x76, 0x09, 0xC2, + 0xAA, 0xA5, 0xEC, 0x10, 0x26, 0x97, 0x17, 0x3E, + 0x12, 0x1A, 0xE1, 0x63, 0x02, 0x4F, 0x42, 0x8C, + 0x98, 0x28, 0x35, 0xB4, 0xFA, 0x6D, 0xA6, 0xD6, + 0x78, 0xAE, 0xB9, 0xEE, 0x10, 0x6A, 0x3F, 0x6C + }, + { + 0xE8, 0x69, 0x14, 0x8C, 0x05, 0x45, 0xB3, 0x58, + 0x0E, 0x39, 0x5A, 0xFD, 0xC7, 0x45, 0xCD, 0x24, + 0x3B, 0x6B, 0x5F, 0xE3, 0xB6, 0x7E, 0x29, 0x43, + 0xF6, 0xF8, 0xD9, 0xF2, 0x4F, 0xFA, 0x40, 0xE8, + 0x81, 0x75, 0x6E, 0x1C, 0x18, 0xD9, 0x2F, 0x3E, + 0xBE, 0x84, 0x55, 0x9B, 0x57, 0xE2, 0xEE, 0x3A, + 0x65, 0xD9, 0xEC, 0xE0, 0x49, 0x72, 0xB3, 0x5D, + 0x4C, 0x4E, 0xBE, 0x78, 0x6C, 0x88, 0xDA, 0x62 + }, + { + 0xDA, 0xDA, 0x15, 0x5E, 0x55, 0x42, 0x32, 0xB1, + 0x6E, 0xCA, 0xD9, 0x31, 0xCB, 0x42, 0xE3, 0x25, + 0xB5, 0x86, 0xDB, 0xF1, 0xCB, 0xD0, 0xCE, 0x38, + 0x14, 0x45, 0x16, 0x6B, 0xD1, 0xBF, 0xA3, 0x32, + 0x49, 0x85, 0xE7, 0x7C, 0x6F, 0x0D, 0x51, 0x2A, + 0x02, 0x6E, 0x09, 0xD4, 0x86, 0x1C, 0x3B, 0xB8, + 0x52, 0x9D, 0x72, 0x02, 0xEA, 0xC1, 0xC0, 0x44, + 0x27, 0x44, 0xD3, 0x7C, 0x7F, 0x5A, 0xB8, 0xAF + }, + { + 0x2D, 0x14, 0x8C, 0x8E, 0x8F, 0x76, 0xFA, 0xAC, + 0x6F, 0x7F, 0x01, 0xF2, 0x03, 0x9E, 0xA0, 0x2A, + 0x42, 0xD9, 0x32, 0x57, 0x94, 0xC2, 0xC7, 0xA0, + 0x0F, 0x83, 0xF4, 0xA7, 0x79, 0x8A, 0xFB, 0xA9, + 0x93, 0xFF, 0x94, 0x91, 0x1E, 0x09, 0x8B, 0x00, + 0x1A, 0x0B, 0xDF, 0xF4, 0xC8, 0x5A, 0x2A, 0x61, + 0x31, 0xE0, 0xCF, 0xE7, 0x0F, 0x1D, 0x2E, 0x07, + 0xAF, 0x02, 0x09, 0xDA, 0x77, 0x96, 0x09, 0x1F + }, + { + 0x99, 0x98, 0x3A, 0x75, 0x9C, 0xCF, 0x9C, 0xAC, + 0xAE, 0x70, 0x2D, 0xCB, 0xFC, 0xDF, 0x72, 0x04, + 0xDD, 0xF0, 0x33, 0x4B, 0xC6, 0x5D, 0xAD, 0x84, + 0x6F, 0x83, 0x1F, 0x9F, 0x9D, 0x8A, 0x45, 0x3F, + 0x0D, 0x24, 0x93, 0x5C, 0x4C, 0x65, 0x7F, 0xFF, + 0x2E, 0xBB, 0xDB, 0xAF, 0x7B, 0xCE, 0x6A, 0xAC, + 0xDB, 0xB8, 0x87, 0x6F, 0x16, 0x04, 0x59, 0xB1, + 0xA4, 0xAA, 0xC9, 0x56, 0x97, 0xE0, 0x0D, 0x98 + }, + { + 0x7E, 0x4A, 0x02, 0x12, 0x6D, 0x75, 0x52, 0xF4, + 0xC9, 0xB9, 0x4D, 0x80, 0xE3, 0xCF, 0x7B, 0x89, + 0x7E, 0x09, 0x84, 0xE4, 0x06, 0xF0, 0x78, 0x13, + 0x5C, 0xF4, 0x56, 0xC0, 0xD5, 0x1E, 0x13, 0x91, + 0xFF, 0x18, 0xA8, 0x8F, 0x93, 0x12, 0x2C, 0x83, + 0x2C, 0xAC, 0x7D, 0x79, 0x6A, 0x6B, 0x42, 0x51, + 0x9B, 0x1D, 0xB4, 0xEA, 0xD8, 0xF4, 0x98, 0x40, + 0xCE, 0xB5, 0x52, 0x33, 0x6B, 0x29, 0xDE, 0x44 + }, + { + 0xD7, 0xE1, 0x6F, 0xD1, 0x59, 0x65, 0x8A, 0xD7, + 0xEE, 0x25, 0x1E, 0x51, 0x7D, 0xCE, 0x5A, 0x29, + 0xF4, 0x6F, 0xD4, 0xB8, 0xD3, 0x19, 0xDB, 0x80, + 0x5F, 0xC2, 0x5A, 0xA6, 0x20, 0x35, 0x0F, 0xF4, + 0x23, 0xAD, 0x8D, 0x05, 0x37, 0xCD, 0x20, 0x69, + 0x43, 0x2E, 0xBF, 0xF2, 0x92, 0x36, 0xF8, 0xC2, + 0xA8, 0xA0, 0x4D, 0x04, 0xB3, 0xB4, 0x8C, 0x59, + 0xA3, 0x55, 0xFC, 0xC6, 0x2D, 0x27, 0xF8, 0xEE + }, + { + 0x0D, 0x45, 0x17, 0xD4, 0xF1, 0xD0, 0x47, 0x30, + 0xC6, 0x91, 0x69, 0x18, 0xA0, 0x4C, 0x9E, 0x90, + 0xCC, 0xA3, 0xAC, 0x1C, 0x63, 0xD6, 0x45, 0x97, + 0x8A, 0x7F, 0x07, 0x03, 0x9F, 0x92, 0x20, 0x64, + 0x7C, 0x25, 0xC0, 0x4E, 0x85, 0xF6, 0xE2, 0x28, + 0x6D, 0x2E, 0x35, 0x46, 0x0D, 0x0B, 0x2C, 0x1E, + 0x25, 0xAF, 0x9D, 0x35, 0x37, 0xEF, 0x33, 0xFD, + 0x7F, 0xE5, 0x1E, 0x2B, 0xA8, 0x76, 0x4B, 0x36 + }, + { + 0x56, 0xB7, 0x2E, 0x51, 0x37, 0xC6, 0x89, 0xB2, + 0x73, 0x66, 0xFB, 0x22, 0xC7, 0xC6, 0x75, 0x44, + 0xF6, 0xBC, 0xE5, 0x76, 0x19, 0x41, 0x31, 0xC5, + 0xBF, 0xAB, 0x1C, 0xF9, 0x3C, 0x2B, 0x51, 0xAA, + 0xA3, 0x03, 0x36, 0x8A, 0xA8, 0x44, 0xD5, 0x8D, + 0xF0, 0xEE, 0x5D, 0x4E, 0x31, 0x9F, 0xCD, 0x8E, + 0xFF, 0xC6, 0x02, 0xCE, 0xE4, 0x35, 0x1B, 0xD2, + 0xF5, 0x51, 0x43, 0x0B, 0x92, 0x11, 0xE7, 0x3C + }, + { + 0xF3, 0x35, 0xCC, 0x22, 0xFF, 0xEA, 0x5A, 0xA5, + 0x9C, 0xDF, 0xC8, 0xF5, 0x02, 0x89, 0xCC, 0x92, + 0x31, 0x9B, 0x8B, 0x14, 0x40, 0x8D, 0x7A, 0x5A, + 0xA1, 0x23, 0x2A, 0xE2, 0x3A, 0xA1, 0xEA, 0x7F, + 0x77, 0x48, 0xCF, 0xEF, 0x03, 0x20, 0x10, 0xF8, + 0x62, 0x6D, 0x93, 0x18, 0xED, 0xBA, 0x98, 0xD4, + 0x16, 0x62, 0x03, 0x35, 0xC9, 0x01, 0xED, 0x02, + 0xEA, 0xBD, 0x27, 0x6A, 0x1B, 0x82, 0x9C, 0x9D + }, + { + 0xA9, 0x9A, 0x3D, 0x10, 0xF9, 0x5B, 0x44, 0x2F, + 0xFF, 0xF7, 0xC4, 0x18, 0xFA, 0x94, 0x9D, 0x48, + 0x30, 0x86, 0x9B, 0x0E, 0x60, 0xEC, 0x8B, 0x97, + 0x2C, 0x30, 0xA3, 0x16, 0x9C, 0x27, 0xBE, 0xB5, + 0xCF, 0x33, 0x05, 0x94, 0xF0, 0x14, 0xB6, 0x6B, + 0x22, 0x00, 0xA7, 0xF0, 0x86, 0xD2, 0xC2, 0xF3, + 0xF9, 0xFD, 0x85, 0x32, 0xA5, 0x71, 0x88, 0x76, + 0xDF, 0xCA, 0x66, 0x1B, 0xA0, 0xF7, 0xB3, 0x6D + }, + { + 0x15, 0x8E, 0x25, 0x70, 0xD0, 0x84, 0xA4, 0x86, + 0x9D, 0x96, 0x93, 0x43, 0xC0, 0x10, 0x86, 0x07, + 0x17, 0xFF, 0x74, 0x11, 0x61, 0x88, 0x17, 0x5F, + 0x2E, 0xD7, 0x4C, 0xD5, 0x78, 0xFA, 0x0D, 0x80, + 0x91, 0xB0, 0x3F, 0xAD, 0x0C, 0x65, 0xCF, 0x59, + 0xAB, 0x91, 0xDD, 0x73, 0xB3, 0x7F, 0xE3, 0xF5, + 0x8A, 0x58, 0xE7, 0xB4, 0x47, 0x9C, 0x87, 0x5A, + 0xCD, 0x63, 0xEC, 0x52, 0x58, 0x12, 0x35, 0x3F + }, + { + 0x7C, 0x49, 0x50, 0x1C, 0x58, 0x08, 0xB1, 0x5C, + 0x0D, 0x31, 0xBD, 0xD5, 0xBB, 0x56, 0x31, 0xD5, + 0x3A, 0xE0, 0x0D, 0xF4, 0x31, 0x02, 0x5F, 0xEA, + 0x51, 0xEB, 0x47, 0x62, 0x54, 0x4E, 0xFD, 0xEE, + 0x97, 0x8A, 0x83, 0x50, 0x8D, 0xEA, 0x6B, 0xFD, + 0x3B, 0x93, 0x1A, 0x0E, 0x95, 0x83, 0xCC, 0xFC, + 0x04, 0x9E, 0xA8, 0x46, 0x44, 0x70, 0x5D, 0x31, + 0x9F, 0xDC, 0x5C, 0x16, 0x3B, 0xF4, 0x82, 0x24 + }, + { + 0xFE, 0xF4, 0x36, 0xB3, 0x5F, 0x71, 0x7D, 0x59, + 0xAC, 0xA1, 0x7E, 0x9B, 0xF5, 0xFF, 0xDA, 0x28, + 0xF5, 0xF4, 0x01, 0x94, 0x3E, 0xFE, 0x93, 0xEB, + 0x58, 0x0F, 0xFB, 0x98, 0xF1, 0x3B, 0xEA, 0x80, + 0x94, 0x69, 0xA3, 0x44, 0xE7, 0x82, 0xA4, 0x43, + 0xC6, 0x4E, 0xB2, 0x5A, 0xD0, 0x9D, 0x8D, 0xE2, + 0x05, 0xFE, 0xE7, 0xD5, 0x63, 0x96, 0x86, 0xA1, + 0x9E, 0x7C, 0x42, 0xB4, 0x0F, 0x70, 0x6A, 0x08 + }, + { + 0x4D, 0x47, 0xA6, 0x7A, 0x5F, 0x8E, 0x17, 0xB7, + 0x22, 0xDF, 0x98, 0x58, 0xAE, 0xB6, 0x7B, 0x99, + 0x56, 0xB4, 0x59, 0x62, 0xEC, 0x35, 0x3D, 0xC2, + 0xE2, 0x7F, 0x0F, 0x50, 0x1C, 0x39, 0x8E, 0x34, + 0x39, 0x7B, 0xEB, 0xE0, 0x2B, 0x54, 0x92, 0x7E, + 0x2D, 0x31, 0xF1, 0x2E, 0xCF, 0x55, 0xE8, 0x82, + 0x69, 0xFA, 0xB5, 0x37, 0x0E, 0x7F, 0xA5, 0x70, + 0x35, 0x26, 0x6F, 0x89, 0xD5, 0xC2, 0x64, 0x41 + }, + { + 0x1B, 0x58, 0xDC, 0x7A, 0xAC, 0x36, 0x3B, 0x00, + 0x44, 0x6E, 0xA8, 0x03, 0xBC, 0xD7, 0x49, 0xC3, + 0xF5, 0xCA, 0xBE, 0xAA, 0xF2, 0x23, 0x99, 0x4C, + 0x0C, 0x3E, 0xCC, 0x1B, 0x28, 0x47, 0x73, 0x44, + 0xD7, 0xBF, 0x97, 0xC0, 0x8A, 0x95, 0x9D, 0x1A, + 0xC2, 0x06, 0x0B, 0x47, 0x27, 0x89, 0x86, 0x92, + 0x91, 0x88, 0xAD, 0x73, 0xDE, 0x67, 0x07, 0x8B, + 0xA6, 0x80, 0x96, 0x3B, 0x9D, 0x3B, 0x12, 0xA4 + }, + { + 0x3C, 0x52, 0x2C, 0x84, 0x3E, 0x69, 0x74, 0xEC, + 0x75, 0x0D, 0xF2, 0x20, 0xD4, 0x1A, 0x00, 0x4A, + 0xC2, 0xAD, 0xF0, 0x94, 0x56, 0xFA, 0x78, 0x7F, + 0x7C, 0x65, 0x43, 0xAB, 0x17, 0x97, 0x9C, 0x77, + 0x7B, 0x3E, 0x79, 0xD1, 0x78, 0x7D, 0xA5, 0xA8, + 0x3F, 0x17, 0x8D, 0xA9, 0xF0, 0x4C, 0xF6, 0xF5, + 0xB2, 0x55, 0xDD, 0xCB, 0x18, 0x74, 0x84, 0x1B, + 0xBF, 0x70, 0x16, 0xE6, 0x13, 0x2B, 0x99, 0x8A + }, + { + 0x5A, 0x4F, 0xEB, 0x8F, 0x70, 0x75, 0xB4, 0xDC, + 0x9C, 0xA1, 0x6C, 0x6F, 0x05, 0xCD, 0x6B, 0x70, + 0x27, 0x48, 0x5F, 0xFE, 0xD9, 0x15, 0x7D, 0x82, + 0x4D, 0x9D, 0x1A, 0x17, 0x20, 0xEE, 0xEE, 0xEA, + 0x3F, 0x6C, 0x12, 0x5F, 0xDA, 0x4B, 0xA4, 0x40, + 0x9D, 0x79, 0x80, 0x49, 0xFD, 0x18, 0x82, 0xC6, + 0x90, 0x28, 0x8F, 0x33, 0x54, 0x7A, 0x3D, 0x8D, + 0x62, 0x60, 0xB6, 0x54, 0x54, 0x88, 0x53, 0xD7 + }, + { + 0xBC, 0xAA, 0x79, 0x36, 0x32, 0x56, 0x9E, 0x2F, + 0x84, 0x17, 0xCC, 0x60, 0x32, 0x53, 0x53, 0x5B, + 0xD7, 0xD8, 0x5F, 0x38, 0x53, 0x19, 0x92, 0x59, + 0x1E, 0x56, 0xC1, 0xA4, 0xB6, 0xF5, 0x8E, 0xE7, + 0xF8, 0x18, 0xFA, 0xE0, 0x27, 0x88, 0x8A, 0x86, + 0x28, 0x43, 0x05, 0x10, 0x1E, 0xC0, 0x46, 0x61, + 0xF5, 0x99, 0x53, 0x47, 0xA4, 0x67, 0xED, 0x8B, + 0x92, 0x79, 0xF1, 0xAC, 0xC2, 0xB4, 0xBB, 0x1F + }, + { + 0x34, 0xAF, 0x91, 0xCC, 0x22, 0xA6, 0x9B, 0xCB, + 0x55, 0xDD, 0xBF, 0x7F, 0x0F, 0x43, 0xEC, 0x56, + 0x48, 0x40, 0x43, 0x32, 0x13, 0xEA, 0x55, 0xD9, + 0xF8, 0x1A, 0xC4, 0x75, 0x20, 0x8D, 0x74, 0x85, + 0x1D, 0xB7, 0x0F, 0xE4, 0x96, 0xAF, 0x9D, 0xA1, + 0xD3, 0x93, 0xEC, 0xF8, 0x78, 0x69, 0x5D, 0xD3, + 0x3F, 0xD5, 0x43, 0x49, 0xA6, 0xF8, 0x24, 0xAE, + 0xED, 0x18, 0x3C, 0xB1, 0xB0, 0x8C, 0x54, 0x85 + }, + { + 0xB8, 0xB7, 0xAD, 0x2E, 0xA2, 0xB6, 0xFA, 0x06, + 0xD0, 0x0B, 0xCD, 0x59, 0x9C, 0x99, 0x71, 0xC5, + 0xB4, 0xE1, 0x65, 0x58, 0xE1, 0x52, 0x12, 0xC9, + 0xBF, 0xD3, 0x73, 0xE4, 0xBC, 0x79, 0x17, 0x05, + 0x26, 0x01, 0xFF, 0xDB, 0x68, 0x01, 0xBE, 0x80, + 0xBA, 0x50, 0x9D, 0xB8, 0x2A, 0x0B, 0x71, 0x95, + 0x92, 0x91, 0x33, 0xAD, 0x53, 0x99, 0x56, 0x06, + 0x52, 0x33, 0xF4, 0x9D, 0x07, 0x1C, 0x84, 0xE4 + }, + { + 0xDC, 0xEE, 0x9C, 0x45, 0xBC, 0x5D, 0x1F, 0xE6, + 0x30, 0xB1, 0x8B, 0x06, 0x3C, 0xE8, 0x2C, 0x38, + 0x57, 0xE3, 0x0D, 0x20, 0xC6, 0x4B, 0x5C, 0xC2, + 0x58, 0x84, 0x94, 0x3E, 0x7A, 0xE9, 0x4E, 0xDF, + 0xF8, 0x50, 0xEB, 0x0E, 0x82, 0x44, 0x02, 0x3D, + 0x3D, 0x07, 0xA8, 0xA0, 0x07, 0x06, 0xF0, 0x58, + 0x2C, 0xC1, 0x02, 0xB6, 0x6C, 0x6D, 0xDA, 0x86, + 0xE8, 0xF2, 0xDF, 0x32, 0x56, 0x59, 0x88, 0x6F + }, + { + 0x04, 0xF6, 0xE8, 0x22, 0xF1, 0x7C, 0xC7, 0xA5, + 0x94, 0x6D, 0xF8, 0x0D, 0x95, 0x8A, 0xEF, 0x06, + 0x5D, 0x87, 0x49, 0x16, 0xE1, 0x03, 0xA6, 0x83, + 0x0C, 0x6E, 0x46, 0xB6, 0x05, 0x59, 0x18, 0x18, + 0x0D, 0x14, 0x52, 0x29, 0x3C, 0x58, 0xA9, 0x74, + 0x9C, 0xBC, 0x8F, 0x0A, 0xC4, 0x08, 0xA9, 0xCA, + 0x89, 0x57, 0x61, 0xCF, 0xC4, 0x51, 0x16, 0x46, + 0x41, 0xA1, 0x79, 0xFB, 0x5C, 0xD8, 0xFE, 0xBC + }, + { + 0x51, 0x1F, 0xDB, 0x7C, 0x88, 0x26, 0x85, 0x35, + 0xE9, 0x7E, 0x4E, 0xD8, 0x92, 0xF3, 0xC0, 0x65, + 0x83, 0x2B, 0x26, 0x59, 0x14, 0xFC, 0x61, 0x07, + 0xA1, 0xD2, 0x7D, 0xBB, 0x7D, 0x51, 0xC3, 0x7E, + 0x95, 0x98, 0x15, 0x06, 0xC1, 0x14, 0x72, 0x44, + 0xD5, 0xBA, 0xE9, 0x0E, 0xE9, 0x0D, 0x08, 0x49, + 0x84, 0xBA, 0xA7, 0x58, 0x7F, 0x41, 0xFF, 0x6F, + 0x4B, 0xA7, 0x22, 0xC8, 0xB9, 0x2A, 0xEB, 0x99 + }, + { + 0x2B, 0xA2, 0xBD, 0x17, 0xE9, 0x26, 0x27, 0x5B, + 0x06, 0x83, 0xB2, 0x36, 0xBF, 0xE3, 0x76, 0x30, + 0x26, 0x6E, 0x37, 0xF4, 0x18, 0x2F, 0x53, 0xA9, + 0x82, 0x34, 0xE9, 0x15, 0xAB, 0x64, 0xC9, 0x59, + 0x96, 0xC6, 0xCB, 0x7A, 0xE8, 0x80, 0xC3, 0xDF, + 0xCB, 0x47, 0xD0, 0x5A, 0xAD, 0xD2, 0x1A, 0xBF, + 0x8E, 0x40, 0xB7, 0x3F, 0x40, 0xF3, 0x98, 0xDC, + 0x5B, 0x02, 0x14, 0x14, 0x57, 0x45, 0x6A, 0x09 + }, + { + 0x9B, 0x66, 0x8D, 0x9B, 0x44, 0x47, 0xE3, 0x76, + 0xF6, 0xC6, 0xCF, 0xA6, 0x8D, 0xBC, 0x79, 0x19, + 0x83, 0x81, 0xAB, 0x60, 0x5F, 0x55, 0xD5, 0xA7, + 0xEF, 0x68, 0x3B, 0xCE, 0xD4, 0x6F, 0x9A, 0xFD, + 0x36, 0x85, 0x41, 0x1A, 0x66, 0xE2, 0x34, 0x6F, + 0x96, 0x07, 0x77, 0xD0, 0xC9, 0x22, 0x71, 0x24, + 0x30, 0xE0, 0x18, 0xBF, 0xAE, 0x86, 0x53, 0x01, + 0x7E, 0xA2, 0x0E, 0xCD, 0x5F, 0x1F, 0x95, 0x6C + }, + { + 0x56, 0x81, 0x02, 0x4F, 0x53, 0x85, 0x88, 0xA0, + 0x1B, 0x2C, 0x83, 0x94, 0xCA, 0xE8, 0x73, 0xC6, + 0xD8, 0x5D, 0x6A, 0xA0, 0x6E, 0xDD, 0xB3, 0xA5, + 0x02, 0x09, 0x6F, 0xC0, 0x82, 0xBB, 0x89, 0xCB, + 0x24, 0x15, 0x31, 0xB3, 0x15, 0x75, 0x0D, 0x31, + 0xBB, 0x0B, 0x63, 0x01, 0x28, 0xD1, 0x9D, 0x11, + 0x39, 0x2B, 0xCF, 0x4B, 0x34, 0x78, 0xD5, 0x23, + 0xD7, 0xD2, 0x13, 0xE4, 0x75, 0x0F, 0x55, 0x92 + }, + { + 0x2A, 0xA9, 0x1B, 0xA6, 0xDE, 0x60, 0x17, 0xF1, + 0x93, 0x0F, 0xC7, 0xD9, 0x6D, 0xCC, 0xD6, 0x70, + 0x74, 0x8B, 0x7E, 0xB1, 0xD0, 0x94, 0xDF, 0xB4, + 0xB3, 0xB1, 0x47, 0x8A, 0x61, 0x2E, 0xBF, 0x03, + 0xDD, 0xD7, 0x21, 0x27, 0x9A, 0x26, 0x6D, 0xE3, + 0x88, 0x45, 0xE6, 0x12, 0xC9, 0x30, 0x98, 0xC2, + 0xEF, 0xFF, 0x34, 0xFE, 0x50, 0x06, 0x17, 0x20, + 0x5B, 0x1D, 0xE2, 0xFE, 0xA1, 0xD8, 0x02, 0x46 + }, + { + 0x82, 0x4D, 0x89, 0xC0, 0x63, 0x7C, 0xE1, 0x78, + 0xB6, 0x30, 0x68, 0x4C, 0x72, 0x9E, 0x26, 0x65, + 0x3F, 0x34, 0xEA, 0xC7, 0xE9, 0x04, 0x12, 0xE9, + 0x63, 0xD3, 0xF1, 0x9D, 0x64, 0x51, 0xE8, 0x25, + 0x85, 0x21, 0x67, 0xC4, 0x8D, 0xF7, 0xCC, 0x55, + 0xB2, 0x57, 0xB2, 0x50, 0xA7, 0x0C, 0x7B, 0xCC, + 0xFA, 0x9A, 0xA1, 0x5C, 0x18, 0x8A, 0xC4, 0x63, + 0x7A, 0x52, 0x22, 0x89, 0xC0, 0x87, 0x6A, 0xD4 + }, + { + 0x87, 0xE4, 0xAE, 0x11, 0xDA, 0x1A, 0x2C, 0xA8, + 0x82, 0x2A, 0xE3, 0x30, 0xDC, 0x97, 0xAB, 0x2E, + 0x47, 0xFF, 0x62, 0x32, 0x30, 0x93, 0xC2, 0xB7, + 0xA6, 0xC0, 0xE2, 0xC1, 0x68, 0x21, 0xCD, 0x7C, + 0xEC, 0x92, 0x18, 0x4D, 0xF4, 0xBB, 0x6E, 0x2B, + 0x62, 0x6A, 0x44, 0x78, 0x03, 0x90, 0x63, 0xAF, + 0xEE, 0xB0, 0xD2, 0x87, 0xF2, 0x42, 0x19, 0x20, + 0x78, 0x98, 0xCC, 0xE7, 0xAD, 0xE0, 0x63, 0x9C + }, + { + 0xDD, 0x7F, 0x2F, 0x44, 0xA4, 0x02, 0xA0, 0x1E, + 0x82, 0x16, 0xB1, 0x03, 0xA4, 0xE7, 0x23, 0x5C, + 0x28, 0x30, 0x31, 0x9D, 0x56, 0xAF, 0x63, 0x9F, + 0x23, 0xC4, 0x8C, 0x27, 0x59, 0xAB, 0xA6, 0xEB, + 0x5E, 0xEE, 0xE3, 0x8C, 0x29, 0x8E, 0xBE, 0x41, + 0x98, 0x26, 0x7A, 0x00, 0xEB, 0x2A, 0x08, 0xD9, + 0x3A, 0x50, 0x37, 0x03, 0x17, 0x1C, 0x77, 0x33, + 0x38, 0x62, 0x10, 0x10, 0x55, 0xBD, 0x7A, 0xD2 + }, + { + 0x4C, 0xB8, 0x46, 0x59, 0x61, 0x93, 0xF7, 0xF2, + 0x78, 0xAA, 0xAA, 0xC5, 0xCC, 0xFF, 0xD5, 0x35, + 0x7A, 0xB0, 0xD1, 0x24, 0x5F, 0x69, 0x79, 0xD1, + 0x41, 0xA4, 0x71, 0xBD, 0xAB, 0x55, 0xE2, 0x38, + 0xB1, 0xAE, 0xD6, 0x7B, 0x73, 0x39, 0x95, 0x04, + 0xB9, 0x7D, 0xF1, 0xA2, 0x5E, 0xB6, 0xFE, 0x27, + 0x2B, 0x5C, 0xD4, 0x96, 0xA7, 0xC8, 0xA0, 0x60, + 0x92, 0x6E, 0x74, 0x04, 0xFD, 0xA0, 0x79, 0x0D + }, + { + 0x6F, 0x44, 0xEC, 0xDA, 0xE1, 0x4E, 0x3B, 0x81, + 0xA1, 0x91, 0x22, 0x03, 0x01, 0x5F, 0x59, 0x18, + 0xEA, 0xC6, 0xFB, 0xF4, 0x96, 0x60, 0x10, 0xF4, + 0x9D, 0x2B, 0xC2, 0xBC, 0xEF, 0xE7, 0xB1, 0xDF, + 0xEC, 0x5C, 0x83, 0x5D, 0x7D, 0x87, 0xA4, 0x43, + 0x71, 0xF1, 0x5A, 0x6C, 0x08, 0x42, 0x52, 0xB9, + 0x34, 0x65, 0x26, 0x42, 0x72, 0xA4, 0x10, 0xD5, + 0x0F, 0x89, 0xA1, 0x17, 0xF3, 0x1A, 0xF4, 0x63 + }, + { + 0x1F, 0x70, 0x5F, 0x6E, 0x9F, 0x07, 0x0D, 0x87, + 0xFD, 0xE8, 0xE2, 0x77, 0x46, 0x74, 0xFA, 0x9B, + 0xF1, 0x20, 0xD2, 0x88, 0xEB, 0x0B, 0xE7, 0xAA, + 0x12, 0x8D, 0xFB, 0x5D, 0x10, 0x11, 0xCE, 0x1F, + 0xDA, 0x99, 0xB2, 0x55, 0x22, 0x66, 0x65, 0xD8, + 0x3F, 0x63, 0x4E, 0x8F, 0xCA, 0xBD, 0xA9, 0xA2, + 0x3C, 0x03, 0x51, 0x5E, 0x9C, 0xFE, 0xCE, 0x6E, + 0x94, 0xA8, 0xEC, 0x92, 0xE4, 0xED, 0xEC, 0xB7 + }, + { + 0x2D, 0x96, 0xC5, 0xB0, 0x15, 0x74, 0x72, 0x2B, + 0x81, 0x7F, 0xEB, 0x48, 0x6C, 0x5F, 0xC9, 0x8F, + 0x5F, 0x84, 0x61, 0xF4, 0xCE, 0xE9, 0x90, 0x5A, + 0xF2, 0x06, 0xD4, 0x72, 0x33, 0x86, 0xD1, 0xC4, + 0xC7, 0xCA, 0xC5, 0x84, 0x00, 0x28, 0xD7, 0xAF, + 0xED, 0x0E, 0x38, 0xAD, 0x13, 0x96, 0x28, 0xEB, + 0x6A, 0xF9, 0x2B, 0x4B, 0x88, 0xEB, 0xF0, 0x9B, + 0x1F, 0xA0, 0x47, 0xFB, 0xE1, 0x0B, 0xC3, 0x1D + }, + { + 0x65, 0xDA, 0x78, 0x0A, 0x0A, 0x37, 0x47, 0x9D, + 0xD8, 0xF4, 0xD6, 0x55, 0x64, 0xF9, 0xA7, 0x08, + 0x9E, 0x42, 0x07, 0xEB, 0x16, 0xAC, 0xA3, 0xF6, + 0x55, 0x31, 0xCF, 0xEE, 0x76, 0x25, 0xBA, 0x13, + 0x80, 0xA4, 0x97, 0xB6, 0x24, 0x72, 0xFC, 0x7E, + 0x00, 0x07, 0xA6, 0xB0, 0x35, 0x61, 0x04, 0x16, + 0xA5, 0xF8, 0x2C, 0x10, 0x82, 0xFA, 0x06, 0x5C, + 0x46, 0xDD, 0xEE, 0x49, 0x40, 0xD1, 0xFC, 0x46 + }, + { + 0x1C, 0x09, 0xA3, 0xB3, 0x80, 0xB8, 0xA7, 0xFC, + 0x33, 0x3F, 0xD2, 0x71, 0x4D, 0xF7, 0x12, 0x9B, + 0x44, 0xA4, 0x67, 0x68, 0xBA, 0xCF, 0x0A, 0x67, + 0xA3, 0x8A, 0x47, 0xB3, 0xAB, 0x31, 0xF5, 0x1B, + 0x05, 0x33, 0xC2, 0xAA, 0x2B, 0x4B, 0x7B, 0xBB, + 0x6A, 0xE5, 0xED, 0xF3, 0xDC, 0xB0, 0xEC, 0xC1, + 0xA2, 0x83, 0xE8, 0x43, 0xF2, 0x90, 0x7B, 0x34, + 0x1F, 0x17, 0x9A, 0xFD, 0x8B, 0x67, 0xDA, 0x90 + }, + { + 0x67, 0x88, 0x8B, 0x83, 0xFA, 0xAF, 0xBB, 0x62, + 0x29, 0x34, 0xB8, 0xD5, 0x59, 0x63, 0xE1, 0x86, + 0x15, 0x3E, 0x59, 0x51, 0x88, 0x7C, 0x7F, 0x4A, + 0x76, 0x35, 0xC7, 0x98, 0xD9, 0xA5, 0x82, 0x94, + 0xBE, 0x26, 0xA3, 0xC5, 0x49, 0xC9, 0xFD, 0x59, + 0x86, 0xAB, 0xD1, 0x9F, 0x40, 0x1E, 0xE2, 0x4E, + 0xDA, 0x36, 0x02, 0x04, 0x2A, 0xD3, 0x83, 0x35, + 0x7A, 0x31, 0x7D, 0x38, 0x07, 0x3B, 0x38, 0xCE + }, + { + 0xB4, 0xF7, 0x99, 0x63, 0xCA, 0x31, 0xBB, 0x62, + 0x26, 0x5D, 0xD9, 0x29, 0xAF, 0x7D, 0x51, 0x27, + 0x2F, 0xA6, 0x63, 0x1D, 0xE7, 0xFA, 0x35, 0xF7, + 0xA6, 0xB0, 0x3F, 0x9F, 0xCF, 0xDB, 0x8E, 0x3B, + 0x5B, 0xAC, 0xE3, 0x35, 0x91, 0xB7, 0xEC, 0x2C, + 0xFA, 0xB4, 0x9C, 0x91, 0xA6, 0xDB, 0x1F, 0xF8, + 0xF6, 0x78, 0x6D, 0x08, 0xF4, 0x4E, 0x80, 0x62, + 0xD2, 0xFF, 0x69, 0x6A, 0x7D, 0x98, 0x41, 0x42 + }, + { + 0x40, 0x84, 0x83, 0x69, 0x7B, 0xB6, 0xF9, 0xD0, + 0x11, 0xA1, 0xF2, 0x9A, 0x23, 0xC2, 0x78, 0xA8, + 0x1D, 0x37, 0x57, 0x8D, 0xCC, 0xCF, 0x42, 0x3B, + 0xDF, 0x48, 0x93, 0x37, 0xF1, 0x82, 0xEA, 0xB7, + 0x9A, 0x50, 0xB0, 0x5F, 0x3D, 0x2C, 0xCC, 0x49, + 0x13, 0x37, 0xC7, 0xE4, 0x1F, 0x30, 0x79, 0x3B, + 0xD2, 0x7D, 0x76, 0x61, 0xC2, 0xE3, 0x04, 0xC9, + 0x46, 0xA5, 0xA4, 0x01, 0xAF, 0x8D, 0x94, 0x6F + }, + { + 0xEE, 0xB5, 0xAD, 0xE1, 0xAB, 0x97, 0xE7, 0x15, + 0x43, 0x43, 0xA4, 0x6E, 0xB4, 0xCD, 0xD2, 0xA7, + 0x73, 0xF3, 0x63, 0x01, 0xED, 0xC6, 0xA1, 0xBC, + 0x1D, 0xD6, 0x48, 0x0E, 0x08, 0xF5, 0x87, 0x65, + 0xCB, 0x93, 0x87, 0x82, 0x92, 0x3B, 0xC0, 0x1F, + 0x8E, 0x0C, 0x61, 0xC6, 0xBE, 0x0D, 0xD1, 0xAB, + 0x4C, 0x18, 0xCB, 0x15, 0xED, 0x52, 0x10, 0x11, + 0x24, 0x05, 0xF1, 0xEA, 0x8F, 0x2E, 0x8C, 0x4E + }, + { + 0x71, 0x4A, 0xD1, 0x85, 0xF1, 0xEE, 0xC4, 0x3F, + 0x46, 0xB6, 0x7E, 0x99, 0x2D, 0x2D, 0x38, 0xBC, + 0x31, 0x49, 0xE3, 0x7D, 0xA7, 0xB4, 0x47, 0x48, + 0xD4, 0xD1, 0x4C, 0x16, 0x1E, 0x08, 0x78, 0x02, + 0x04, 0x42, 0x14, 0x95, 0x79, 0xA8, 0x65, 0xD8, + 0x04, 0xB0, 0x49, 0xCD, 0x01, 0x55, 0xBA, 0x98, + 0x33, 0x78, 0x75, 0x7A, 0x13, 0x88, 0x30, 0x1B, + 0xDC, 0x0F, 0xAE, 0x2C, 0xEA, 0xEA, 0x07, 0xDD + }, + { + 0x22, 0xB8, 0x24, 0x9E, 0xAF, 0x72, 0x29, 0x64, + 0xCE, 0x42, 0x4F, 0x71, 0xA7, 0x4D, 0x03, 0x8F, + 0xF9, 0xB6, 0x15, 0xFB, 0xA5, 0xC7, 0xC2, 0x2C, + 0xB6, 0x27, 0x97, 0xF5, 0x39, 0x82, 0x24, 0xC3, + 0xF0, 0x72, 0xEB, 0xC1, 0xDA, 0xCB, 0xA3, 0x2F, + 0xC6, 0xF6, 0x63, 0x60, 0xB3, 0xE1, 0x65, 0x8D, + 0x0F, 0xA0, 0xDA, 0x1E, 0xD1, 0xC1, 0xDA, 0x66, + 0x2A, 0x20, 0x37, 0xDA, 0x82, 0x3A, 0x33, 0x83 + }, + { + 0xB8, 0xE9, 0x03, 0xE6, 0x91, 0xB9, 0x92, 0x78, + 0x25, 0x28, 0xF8, 0xDB, 0x96, 0x4D, 0x08, 0xE3, + 0xBA, 0xAF, 0xBD, 0x08, 0xBA, 0x60, 0xC7, 0x2A, + 0xEC, 0x0C, 0x28, 0xEC, 0x6B, 0xFE, 0xCA, 0x4B, + 0x2E, 0xC4, 0xC4, 0x6F, 0x22, 0xBF, 0x62, 0x1A, + 0x5D, 0x74, 0xF7, 0x5C, 0x0D, 0x29, 0x69, 0x3E, + 0x56, 0xC5, 0xC5, 0x84, 0xF4, 0x39, 0x9E, 0x94, + 0x2F, 0x3B, 0xD8, 0xD3, 0x86, 0x13, 0xE6, 0x39 + }, + { + 0xD5, 0xB4, 0x66, 0xFF, 0x1F, 0xD6, 0x8C, 0xFA, + 0x8E, 0xDF, 0x0B, 0x68, 0x02, 0x44, 0x8F, 0x30, + 0x2D, 0xCC, 0xDA, 0xF5, 0x66, 0x28, 0x78, 0x6B, + 0x9D, 0xA0, 0xF6, 0x62, 0xFD, 0xA6, 0x90, 0x26, + 0x6B, 0xD4, 0x0A, 0xB6, 0xF0, 0xBE, 0xC0, 0x43, + 0xF1, 0x01, 0x28, 0xB3, 0x3D, 0x05, 0xDB, 0x82, + 0xD4, 0xAB, 0x26, 0x8A, 0x4F, 0x91, 0xAC, 0x42, + 0x86, 0x79, 0x5F, 0xC0, 0xF7, 0xCB, 0x48, 0x5C + }, + { + 0x0A, 0x1E, 0x8C, 0x0A, 0x8C, 0x48, 0xB8, 0x4B, + 0x71, 0xBA, 0x0F, 0xE5, 0x6F, 0xA0, 0x56, 0x09, + 0x8C, 0xA6, 0x92, 0xE9, 0x2F, 0x27, 0x6E, 0x85, + 0xB3, 0x38, 0x26, 0xCD, 0x78, 0x75, 0xFC, 0xF8, + 0x83, 0x85, 0x13, 0x1B, 0x43, 0xDF, 0x74, 0x53, + 0x2E, 0xAA, 0x86, 0xCF, 0x17, 0x1F, 0x50, 0x76, + 0xE6, 0xD1, 0x7B, 0x1C, 0x75, 0xFB, 0xA1, 0xDB, + 0x00, 0x1B, 0x6E, 0x66, 0x97, 0x7C, 0xB8, 0xD7 + }, + { + 0x65, 0xAA, 0x17, 0x99, 0x14, 0x36, 0x93, 0xAB, + 0xD9, 0xCB, 0x21, 0x8D, 0x9B, 0x5E, 0xC6, 0x0C, + 0x0E, 0xDD, 0xB0, 0x67, 0xE6, 0xA3, 0x2F, 0x76, + 0x79, 0x60, 0x10, 0xAC, 0xB1, 0x1A, 0xD0, 0x13, + 0x6C, 0xE4, 0x9F, 0x97, 0x6E, 0x74, 0xF8, 0x95, + 0x04, 0x2F, 0x7C, 0xBF, 0x13, 0xFB, 0x73, 0xD1, + 0x9D, 0xC8, 0x89, 0xD7, 0xE9, 0x03, 0x46, 0x9D, + 0xEB, 0x33, 0x73, 0x1F, 0x24, 0x06, 0xB6, 0x63 + }, + { + 0xDE, 0xB7, 0x12, 0xB9, 0xCC, 0x64, 0xF5, 0x88, + 0x14, 0x86, 0x0B, 0x51, 0xFA, 0x89, 0xAD, 0x8A, + 0x92, 0x6A, 0x69, 0x08, 0xC7, 0x96, 0xDE, 0x55, + 0x7F, 0x90, 0xCF, 0xAD, 0xB0, 0xC6, 0x2C, 0x07, + 0x87, 0x2F, 0x33, 0xFE, 0x18, 0x4E, 0x5E, 0x21, + 0x2A, 0x3C, 0x5C, 0x37, 0x31, 0x74, 0x18, 0x44, + 0x6E, 0xFD, 0x95, 0x61, 0x3F, 0x61, 0x8A, 0x35, + 0xF7, 0xD2, 0x78, 0x9E, 0xFE, 0x0D, 0x96, 0x60 + }, + { + 0xB4, 0x2F, 0x4A, 0x40, 0xB3, 0xC8, 0x8B, 0xCE, + 0xCF, 0xE3, 0x28, 0xC8, 0x46, 0xBF, 0x06, 0x48, + 0xA1, 0x69, 0x90, 0xCA, 0x53, 0x91, 0x95, 0xC0, + 0xC1, 0xDC, 0x8D, 0x70, 0x30, 0x80, 0x67, 0x68, + 0x5A, 0xF6, 0x77, 0xAD, 0x65, 0xAC, 0x0C, 0x7A, + 0x9B, 0xCF, 0xA8, 0xF7, 0xAC, 0xC0, 0xAA, 0xCF, + 0x45, 0xCA, 0x18, 0xAC, 0x83, 0x1F, 0xED, 0x64, + 0x4E, 0xC3, 0xD9, 0x28, 0x31, 0x01, 0xFF, 0xEF + }, + { + 0xED, 0xCF, 0x6C, 0x81, 0xCC, 0xF1, 0x6E, 0x11, + 0xDD, 0xF7, 0x19, 0xA3, 0x3D, 0xD0, 0xE5, 0x34, + 0x9C, 0xAB, 0xAC, 0x5C, 0xFA, 0xE5, 0x97, 0x00, + 0x98, 0x40, 0xE1, 0xC3, 0x93, 0x62, 0xC0, 0xF1, + 0x19, 0x82, 0xFE, 0x2C, 0x27, 0x65, 0x85, 0x9A, + 0x94, 0x26, 0x2D, 0xA2, 0x8D, 0xD3, 0x37, 0x3D, + 0x52, 0x26, 0x93, 0x89, 0x75, 0x11, 0xEB, 0xA5, + 0xE0, 0x7B, 0x8B, 0xC6, 0xB6, 0x06, 0x4D, 0xC0 + }, + { + 0x46, 0xB9, 0x62, 0xD2, 0x28, 0x36, 0x94, 0xD2, + 0x79, 0x75, 0xDC, 0xBF, 0x32, 0x56, 0x4C, 0x9B, + 0x04, 0x03, 0x2B, 0x30, 0xA9, 0x3E, 0x05, 0x8F, + 0xB7, 0x7B, 0x2B, 0x71, 0x8B, 0x4A, 0xD5, 0xFB, + 0x78, 0x9A, 0xB7, 0xD7, 0xAA, 0x90, 0x85, 0x2D, + 0xA2, 0xBF, 0xB6, 0xB3, 0x93, 0xB0, 0x9F, 0x98, + 0xE8, 0x69, 0xB1, 0x6E, 0x41, 0x0E, 0x7D, 0xE2, + 0x30, 0xB1, 0x79, 0xF6, 0x2E, 0xB5, 0x74, 0x71 + }, + { + 0x29, 0x03, 0x6C, 0x3F, 0x53, 0x82, 0xE3, 0x5D, + 0xE7, 0xA6, 0x9F, 0xA7, 0xA6, 0x3E, 0xC7, 0xBD, + 0xCB, 0xC4, 0xE0, 0xCC, 0x5A, 0x7B, 0x64, 0x14, + 0xCF, 0x44, 0xBF, 0x9A, 0x83, 0x83, 0xEF, 0xB5, + 0x97, 0x23, 0x50, 0x6F, 0x0D, 0x51, 0xAD, 0x50, + 0xAC, 0x1E, 0xAC, 0xF7, 0x04, 0x30, 0x8E, 0x8A, + 0xEC, 0xB9, 0x66, 0xF6, 0xAC, 0x94, 0x1D, 0xB1, + 0xCD, 0xE4, 0xB5, 0x9E, 0x84, 0xC1, 0xEB, 0xBA + }, + { + 0x17, 0x3F, 0x8A, 0xB8, 0x93, 0x3E, 0xB0, 0x7C, + 0xC5, 0xFD, 0x6E, 0x4B, 0xCE, 0xBA, 0xE1, 0xFF, + 0x35, 0xC7, 0x87, 0x9B, 0x93, 0x8A, 0x5A, 0x15, + 0x79, 0xEA, 0x02, 0xF3, 0x83, 0x32, 0x48, 0x86, + 0xC7, 0x0E, 0xD9, 0x10, 0x9D, 0xE1, 0x69, 0x0B, + 0x8E, 0xE8, 0x01, 0xBC, 0x95, 0x9B, 0x21, 0xD3, + 0x81, 0x17, 0xEB, 0xB8, 0x4A, 0xB5, 0x6F, 0x88, + 0xF8, 0xA3, 0x72, 0x62, 0x00, 0x2D, 0xD9, 0x8E + }, + { + 0xC6, 0xAF, 0xA6, 0xA1, 0x91, 0x93, 0x1F, 0xD4, + 0x5C, 0x3B, 0xAD, 0xBA, 0x72, 0x6E, 0x68, 0xA9, + 0xBC, 0x73, 0x88, 0xC8, 0xCF, 0x37, 0xAD, 0xEC, + 0x7C, 0x64, 0x56, 0x1C, 0xF4, 0x81, 0xFD, 0x25, + 0x9A, 0x64, 0x6C, 0x8B, 0xD8, 0x43, 0xE7, 0x70, + 0x9E, 0x11, 0xE6, 0x4D, 0xCF, 0xD5, 0xDF, 0xFF, + 0xED, 0x79, 0x23, 0x5C, 0x68, 0x9B, 0x42, 0x00, + 0xFE, 0x7A, 0xC8, 0xDF, 0xDA, 0xDD, 0xEC, 0xE0 + }, + { + 0xA6, 0xDC, 0xCD, 0x8C, 0x19, 0x26, 0x64, 0x88, + 0xBF, 0x77, 0xB9, 0xF2, 0x4B, 0x91, 0x43, 0xDE, + 0xF1, 0xFE, 0xD6, 0x1D, 0x0C, 0x60, 0xB5, 0x00, + 0x0A, 0x52, 0x3F, 0x45, 0x0D, 0xA2, 0x3D, 0x74, + 0xE4, 0xE3, 0xF6, 0xEF, 0x04, 0x09, 0x0D, 0x10, + 0x66, 0xB6, 0xAC, 0xE8, 0x5A, 0xBC, 0x0F, 0x03, + 0x01, 0x73, 0xF5, 0x28, 0x17, 0x72, 0x7C, 0x4E, + 0x40, 0x43, 0x2D, 0xD3, 0x4C, 0x6E, 0xF9, 0xF0 + }, + { + 0xAA, 0xF8, 0x90, 0x8D, 0x54, 0x6E, 0x4F, 0x1E, + 0x31, 0x4C, 0x00, 0xE9, 0xD2, 0xE8, 0x85, 0x5C, + 0xB2, 0x56, 0x44, 0x5A, 0xAE, 0x3E, 0xCA, 0x44, + 0x23, 0x83, 0x22, 0xAE, 0xC7, 0x40, 0x34, 0xA1, + 0x45, 0x8A, 0x29, 0x36, 0x75, 0xDA, 0xD9, 0x49, + 0x40, 0x8D, 0xE5, 0x55, 0x4F, 0x22, 0xD7, 0x34, + 0x54, 0xF3, 0xF0, 0x70, 0x9C, 0xBC, 0xCC, 0x85, + 0xCB, 0x05, 0x3A, 0x6F, 0x50, 0x38, 0x91, 0xA1 + }, + { + 0x52, 0x5F, 0x4A, 0xAB, 0x9C, 0x32, 0x7D, 0x2A, + 0x6A, 0x3C, 0x9D, 0xF8, 0x1F, 0xB7, 0xBE, 0x97, + 0xEE, 0x03, 0xE3, 0xF7, 0xCE, 0x33, 0x21, 0x1C, + 0x47, 0x78, 0x8A, 0xCD, 0x13, 0x46, 0x40, 0xDD, + 0x90, 0xAD, 0x74, 0x99, 0x2D, 0x3D, 0xD6, 0xAC, + 0x80, 0x63, 0x50, 0xF3, 0xBA, 0xBC, 0x7F, 0xE1, + 0x98, 0xA6, 0x1D, 0xB3, 0x2D, 0x4A, 0xD1, 0xD6, + 0x56, 0x9A, 0xE8, 0x41, 0x31, 0x04, 0xDE, 0xA4 + }, + { + 0x2D, 0xAC, 0xCD, 0x88, 0x71, 0x9D, 0x0A, 0x00, + 0xB5, 0x2C, 0x6E, 0xB7, 0x9E, 0x1C, 0xA8, 0xB4, + 0xA1, 0xB4, 0xB4, 0x4F, 0xFA, 0x20, 0x88, 0x9F, + 0x23, 0x63, 0xEF, 0x5C, 0x0D, 0x73, 0x7F, 0x1F, + 0x81, 0xF5, 0x0D, 0xA1, 0xCA, 0xAC, 0x23, 0x1D, + 0x6F, 0xCB, 0x48, 0x89, 0x5E, 0x72, 0x99, 0xB7, + 0x7A, 0xF8, 0x1F, 0x0A, 0xA4, 0xA7, 0x61, 0x8A, + 0xD2, 0x4B, 0x7A, 0xAF, 0xC8, 0xE3, 0xA2, 0xBE + }, + { + 0x7D, 0x28, 0x6F, 0x1F, 0x72, 0x1E, 0xC2, 0xD2, + 0x11, 0x5E, 0xF4, 0xCC, 0xD8, 0x28, 0x58, 0xA4, + 0xD5, 0x12, 0x21, 0x13, 0x55, 0xD4, 0xFC, 0x58, + 0xE5, 0x34, 0xBF, 0xA5, 0x9C, 0x2E, 0x1B, 0xF5, + 0x52, 0xA9, 0x6D, 0xC4, 0xB3, 0xE4, 0x6B, 0x01, + 0x28, 0x65, 0xDA, 0x88, 0x13, 0x4C, 0xF0, 0x4E, + 0x73, 0x1B, 0x19, 0x30, 0x75, 0x9E, 0x15, 0x8F, + 0xF6, 0x20, 0xB6, 0xEC, 0x5A, 0xAF, 0xD0, 0x12 + }, + { + 0x21, 0x82, 0x6B, 0x95, 0x29, 0xC4, 0xBC, 0x51, + 0x91, 0x47, 0xF5, 0xF9, 0xFE, 0x6D, 0xB8, 0x78, + 0x34, 0x52, 0x15, 0xE5, 0x09, 0x4F, 0x4E, 0x99, + 0xB1, 0x31, 0xED, 0x54, 0xE2, 0x49, 0x53, 0xCE, + 0xE9, 0xAD, 0xB7, 0x18, 0xD1, 0x74, 0x3E, 0x6C, + 0x27, 0xFC, 0x94, 0x51, 0x6A, 0x99, 0x22, 0xFB, + 0x97, 0x5A, 0x78, 0x16, 0xB8, 0xAA, 0xB0, 0x21, + 0x12, 0x60, 0x8C, 0x03, 0x2B, 0xF1, 0x38, 0xE3 + }, + { + 0xC1, 0x68, 0x9C, 0x69, 0x8A, 0xB0, 0x65, 0xF6, + 0x2E, 0xEE, 0x65, 0xDD, 0xCA, 0x67, 0x6B, 0xAA, + 0x45, 0xB5, 0x2F, 0x30, 0x8A, 0xFA, 0x80, 0x4A, + 0xB4, 0xAA, 0x6A, 0xB8, 0x4B, 0x7A, 0xC1, 0xAA, + 0x1D, 0xFF, 0x07, 0x17, 0x56, 0x10, 0xB1, 0x2A, + 0xE1, 0x1F, 0x27, 0xB7, 0xC4, 0x30, 0xAF, 0xD5, + 0x75, 0x56, 0xBD, 0x18, 0x1D, 0x02, 0x83, 0x2C, + 0xD8, 0xD0, 0xA5, 0xFD, 0xC3, 0x02, 0x01, 0x24 + }, + { + 0xA1, 0xA6, 0x28, 0x17, 0x47, 0xE3, 0x4D, 0x3E, + 0xDE, 0x5E, 0x93, 0x34, 0x01, 0x74, 0x7C, 0xA7, + 0xF7, 0x66, 0x28, 0xB6, 0x14, 0xC8, 0xA3, 0x94, + 0xF5, 0x02, 0x56, 0x2B, 0xFE, 0xE0, 0xB9, 0x94, + 0xEC, 0xB6, 0x5F, 0xBF, 0xE1, 0xFF, 0x70, 0x67, + 0xDC, 0xB0, 0x1D, 0x02, 0xA9, 0x2B, 0xA4, 0x62, + 0x20, 0x75, 0x87, 0xCE, 0xF7, 0xDC, 0x2C, 0xFD, + 0xB4, 0x58, 0x48, 0x48, 0xAD, 0x55, 0x91, 0x4A + }, + { + 0x00, 0x70, 0xA0, 0x19, 0x0A, 0xA6, 0x96, 0x57, + 0x2D, 0x85, 0x3F, 0x1D, 0x24, 0xAB, 0x63, 0x08, + 0x48, 0xAC, 0x56, 0xAD, 0x5C, 0x2E, 0xBF, 0xCF, + 0xDE, 0x27, 0xD1, 0x11, 0xCD, 0x55, 0x93, 0x9C, + 0x1E, 0x4D, 0x07, 0x87, 0x2D, 0xDE, 0x7C, 0xE7, + 0x8B, 0x53, 0x4B, 0x53, 0x0F, 0x0A, 0x39, 0x6E, + 0x86, 0xAF, 0x9D, 0x57, 0x53, 0x54, 0xB5, 0xD7, + 0xE3, 0x4A, 0xCD, 0xE1, 0x8C, 0xC7, 0x67, 0xAE + }, + { + 0x51, 0xB9, 0xB5, 0xED, 0x19, 0x3F, 0xD4, 0xB1, + 0xA3, 0xA9, 0x2B, 0x46, 0xBD, 0x4B, 0xD1, 0xF6, + 0xEC, 0x6B, 0x38, 0xA6, 0x0F, 0x2D, 0x02, 0x61, + 0xD7, 0x2A, 0xBF, 0xD1, 0x64, 0x36, 0x12, 0x8D, + 0xCB, 0xF2, 0x2C, 0x25, 0xE3, 0xE3, 0xC4, 0x3F, + 0xE4, 0xD2, 0x9D, 0xB9, 0x12, 0x4D, 0x03, 0x33, + 0x30, 0x18, 0x45, 0x92, 0xD2, 0x0C, 0x5B, 0x08, + 0x2C, 0x23, 0x20, 0x64, 0x54, 0xCB, 0x3D, 0xD7 + }, + { + 0x57, 0x8F, 0x24, 0x27, 0x46, 0x91, 0x4E, 0x36, + 0xD0, 0xD9, 0xD4, 0x80, 0x96, 0x89, 0x57, 0x12, + 0x16, 0xA4, 0x3E, 0x47, 0x33, 0x32, 0x39, 0x51, + 0x62, 0x0F, 0x5E, 0xE7, 0x8C, 0xCF, 0xEE, 0x91, + 0x9B, 0xF5, 0x5F, 0x28, 0x7B, 0x45, 0xA7, 0x3D, + 0x44, 0x85, 0xAC, 0x74, 0x22, 0x87, 0x92, 0x39, + 0x65, 0x3B, 0x05, 0x91, 0xC3, 0x6C, 0x86, 0x69, + 0x41, 0xF8, 0xAF, 0xFE, 0x4A, 0xE5, 0x6E, 0x9E + }, + { + 0x94, 0x71, 0x30, 0xEF, 0x0B, 0x94, 0x8E, 0xE0, + 0x45, 0x81, 0xAB, 0xA3, 0xE2, 0xCC, 0x4C, 0xEF, + 0xC3, 0x8C, 0xCE, 0xDC, 0x86, 0x17, 0x92, 0xB7, + 0xB5, 0xDC, 0xD9, 0xD9, 0x36, 0x1C, 0x72, 0x4A, + 0x12, 0x20, 0x03, 0xBF, 0x79, 0x6C, 0xE0, 0x97, + 0x98, 0x00, 0xAD, 0xAB, 0xC7, 0x45, 0x6F, 0x17, + 0x3A, 0xE5, 0x26, 0x93, 0x15, 0xAF, 0xC0, 0x1B, + 0x60, 0x6D, 0xB2, 0x9C, 0x75, 0x50, 0xE8, 0xCA + }, + { + 0xC8, 0x52, 0xE6, 0x77, 0xF7, 0x7B, 0x14, 0xB5, + 0x85, 0xBD, 0x10, 0x2A, 0x0F, 0x14, 0x42, 0x43, + 0x05, 0x9D, 0xAB, 0xEC, 0x7C, 0xB0, 0x1F, 0xFA, + 0x61, 0xDF, 0x19, 0xFC, 0xE8, 0xAB, 0x43, 0x6B, + 0xF5, 0xE2, 0xD5, 0xC7, 0x9A, 0xA2, 0xD7, 0xB6, + 0x77, 0xF6, 0xC3, 0x75, 0xE9, 0x34, 0x3D, 0x34, + 0x2E, 0x4F, 0xF4, 0xE3, 0xAB, 0x00, 0x1B, 0xC7, + 0x98, 0x8C, 0x3C, 0x7A, 0x83, 0xCC, 0xB6, 0x9F + }, + { + 0x01, 0x19, 0x75, 0x26, 0x91, 0x7A, 0xC2, 0xC7, + 0xBC, 0x53, 0x95, 0x19, 0xE6, 0x8B, 0xB2, 0x79, + 0x81, 0x35, 0xF6, 0x03, 0x3E, 0xD5, 0x8F, 0x5C, + 0x45, 0x1E, 0x0C, 0xE9, 0x46, 0xAF, 0xF0, 0xF9, + 0x8D, 0xFD, 0xD1, 0x51, 0x01, 0x73, 0x1A, 0xC1, + 0x66, 0x12, 0x6E, 0xAF, 0xB5, 0xE7, 0xCB, 0xE2, + 0xE2, 0x72, 0xEE, 0x23, 0x3F, 0x34, 0xE5, 0xF3, + 0xF8, 0xEA, 0x3D, 0x2D, 0x12, 0x24, 0x82, 0xFB + }, + { + 0x05, 0x9C, 0x90, 0x85, 0x89, 0x5E, 0xB7, 0x18, + 0x30, 0x4E, 0x2D, 0xDA, 0x78, 0x68, 0x6B, 0xD9, + 0x57, 0x49, 0x81, 0x5A, 0x5E, 0xE9, 0x02, 0x51, + 0x0B, 0x00, 0x9A, 0xF6, 0x92, 0x48, 0xB6, 0xA7, + 0xA7, 0x2F, 0xF8, 0xA6, 0x28, 0xD8, 0x17, 0x73, + 0xE1, 0x1D, 0x5A, 0x1E, 0x7F, 0x69, 0x7A, 0x44, + 0x9B, 0x7A, 0x1E, 0x27, 0x12, 0xD5, 0xCF, 0xAE, + 0x7A, 0xB2, 0x65, 0x07, 0xD1, 0x11, 0x29, 0x18 + }, + { + 0x29, 0x52, 0x43, 0xBD, 0x75, 0x8C, 0xF2, 0x1C, + 0x80, 0x31, 0x25, 0xFC, 0xF3, 0x21, 0xDE, 0x5F, + 0x97, 0x98, 0x7C, 0x8D, 0xB3, 0xBB, 0x3C, 0xB5, + 0x1F, 0xF9, 0x7C, 0x4C, 0xDA, 0xC9, 0xD3, 0xBF, + 0x0A, 0x67, 0xCE, 0xE7, 0xED, 0x35, 0x0A, 0x41, + 0xFD, 0xE6, 0xAB, 0xCC, 0x25, 0x4F, 0xBC, 0x9F, + 0x8E, 0x6B, 0x3E, 0x3C, 0xCE, 0xCB, 0xD0, 0xE4, + 0xA6, 0x40, 0xA2, 0x0F, 0x36, 0x2B, 0xA3, 0xA0 + }, + { + 0xDD, 0x82, 0x32, 0xD2, 0x41, 0x2C, 0xCE, 0xEC, + 0xB5, 0x12, 0x31, 0x91, 0xF6, 0xE9, 0x22, 0x1E, + 0x85, 0x1E, 0xCC, 0xE0, 0xFA, 0xEB, 0xF0, 0x50, + 0x5F, 0x2A, 0xEE, 0xFF, 0x8A, 0x8C, 0x92, 0xD4, + 0x1D, 0xAC, 0xF1, 0x77, 0xBD, 0xAE, 0x27, 0x76, + 0x3E, 0xA4, 0xA8, 0x62, 0x05, 0xEF, 0x76, 0x34, + 0xF7, 0xA6, 0x87, 0xCC, 0x44, 0xBB, 0xBB, 0xDE, + 0xEE, 0x5E, 0x11, 0xE6, 0x5F, 0x9F, 0xBD, 0x69 + }, + { + 0xB0, 0x46, 0xB6, 0x83, 0x71, 0x6D, 0x31, 0xC9, + 0x14, 0xC7, 0x0B, 0x10, 0xF7, 0x64, 0x6D, 0xA3, + 0x1E, 0xFA, 0xB2, 0x23, 0x63, 0x47, 0x45, 0x9C, + 0xF8, 0xFA, 0x2C, 0x09, 0x12, 0x34, 0x31, 0xF7, + 0x28, 0x07, 0xF1, 0x1D, 0x86, 0x7C, 0x37, 0x70, + 0xB1, 0xF0, 0x61, 0xD5, 0x6C, 0xA0, 0xE5, 0xB1, + 0xE8, 0x8A, 0x6B, 0x44, 0xA3, 0x3C, 0xF9, 0x3E, + 0x18, 0xBC, 0xC9, 0xCE, 0xBB, 0xA5, 0xAD, 0xE7 + }, + { + 0x20, 0xE5, 0xA2, 0x55, 0x05, 0x8B, 0xE5, 0x1E, + 0x1A, 0x62, 0x9B, 0x4E, 0xBF, 0x81, 0xE5, 0xCB, + 0xE0, 0x78, 0x1C, 0xB6, 0x7C, 0xA4, 0xE5, 0x7B, + 0xA8, 0x6B, 0x30, 0x88, 0x96, 0xBC, 0xE7, 0x38, + 0x20, 0xEB, 0x08, 0x43, 0x1C, 0xE8, 0xC9, 0xBC, + 0x58, 0x10, 0xCC, 0x8D, 0x8B, 0x9C, 0x9D, 0x6F, + 0xCF, 0x83, 0x4E, 0x42, 0xEA, 0x33, 0xEF, 0x73, + 0xCE, 0xC4, 0x7D, 0x71, 0x3B, 0x6D, 0x8D, 0xFD + }, + { + 0x1E, 0x48, 0x04, 0xF9, 0xC0, 0xB1, 0xE8, 0x2B, + 0x9E, 0xD3, 0x63, 0xBD, 0xE4, 0x47, 0x28, 0xAC, + 0xF7, 0xD0, 0x90, 0xA1, 0xBF, 0xE2, 0xDD, 0xF8, + 0x81, 0x9D, 0x65, 0x92, 0xEF, 0x45, 0x3B, 0x83, + 0x5B, 0xD2, 0xEF, 0xE8, 0xB0, 0x20, 0x6E, 0x29, + 0x25, 0x5B, 0x07, 0xFB, 0x90, 0xC7, 0xD3, 0x0D, + 0x2C, 0x11, 0x48, 0x00, 0xB8, 0x6C, 0xB0, 0xE3, + 0xE0, 0x7D, 0x38, 0x7E, 0x98, 0xCE, 0x95, 0x37 + }, + { + 0x41, 0xC9, 0x53, 0xD8, 0xD2, 0x2A, 0x86, 0xC3, + 0x63, 0x4D, 0xF4, 0x22, 0xB6, 0xDE, 0x4A, 0x4F, + 0x14, 0x96, 0x66, 0xBE, 0x8C, 0x4F, 0x58, 0x1B, + 0x26, 0x23, 0xEE, 0x65, 0xC3, 0x92, 0xA5, 0xC3, + 0x28, 0x36, 0x63, 0x9E, 0xF5, 0x6B, 0x93, 0x68, + 0x62, 0x20, 0xF4, 0x5C, 0xE6, 0x5B, 0x4F, 0xA8, + 0x58, 0x9C, 0x91, 0x25, 0x64, 0x17, 0x90, 0xB6, + 0x92, 0x5F, 0xAA, 0xD9, 0x48, 0xB8, 0xBE, 0x04 + }, + { + 0x8B, 0xFC, 0xA4, 0xC8, 0xDF, 0xE3, 0xFD, 0xE4, + 0x25, 0x7B, 0x75, 0xC3, 0xDB, 0x01, 0x86, 0x2E, + 0xD3, 0x11, 0x67, 0xDE, 0x66, 0xC2, 0xE0, 0x3A, + 0x25, 0x56, 0xC4, 0xF4, 0x6C, 0x9D, 0xFF, 0xC1, + 0xAC, 0x45, 0xF7, 0xBC, 0x59, 0xA6, 0x7A, 0xB9, + 0x36, 0x24, 0xBE, 0xB8, 0x6D, 0xDD, 0x0D, 0x02, + 0x60, 0x3F, 0x0D, 0xCD, 0x03, 0x64, 0xF0, 0xF8, + 0x08, 0x81, 0x9B, 0xE9, 0x6C, 0xD8, 0xD3, 0xB6 + }, + { + 0xF6, 0xBF, 0x59, 0xD8, 0xD4, 0x5A, 0x55, 0x71, + 0x11, 0xA2, 0x36, 0xCB, 0xBA, 0x52, 0x61, 0x9A, + 0xE3, 0xDF, 0xCC, 0x43, 0x16, 0x94, 0x38, 0x43, + 0xAF, 0xD1, 0x28, 0x1B, 0x28, 0x21, 0x4A, 0x4A, + 0x5E, 0x85, 0x1E, 0xF8, 0xC5, 0x4F, 0x50, 0x5E, + 0x3C, 0x4B, 0x60, 0x0E, 0xFF, 0xBE, 0xBB, 0x3E, + 0xAC, 0x17, 0x08, 0x7F, 0x22, 0x27, 0x58, 0x12, + 0x63, 0xF1, 0x7D, 0x7E, 0x5F, 0x68, 0xEA, 0x83 + }, + { + 0x1B, 0xC9, 0xED, 0xE4, 0xD4, 0x1A, 0x4D, 0xF6, + 0xE8, 0xE6, 0xF4, 0x7C, 0x2F, 0x4A, 0xD8, 0x73, + 0x37, 0xB6, 0x9B, 0x19, 0xF7, 0x10, 0xF7, 0x66, + 0xE1, 0xFA, 0xF5, 0xAA, 0x05, 0xA4, 0x3B, 0x66, + 0x45, 0x39, 0x6E, 0x7F, 0xBE, 0xF4, 0x3B, 0xB7, + 0x79, 0x5D, 0x39, 0x40, 0x7B, 0x58, 0x15, 0xB9, + 0x2E, 0xCC, 0x23, 0xA6, 0xC1, 0x24, 0x14, 0x21, + 0x15, 0x3A, 0x55, 0xD5, 0x1F, 0x12, 0xBF, 0xD8 + }, + { + 0x76, 0xB3, 0x8B, 0x36, 0x31, 0x55, 0x5D, 0xBC, + 0xFB, 0x21, 0x21, 0x8F, 0xF9, 0xE4, 0x12, 0xA2, + 0x29, 0x88, 0x9E, 0xF2, 0xCE, 0x8A, 0xD7, 0x05, + 0xE9, 0x0F, 0x96, 0xAA, 0xBB, 0xD5, 0xBE, 0x7E, + 0x53, 0x29, 0xA4, 0x26, 0x53, 0x4C, 0x81, 0x5A, + 0x56, 0x53, 0x77, 0x13, 0x18, 0x72, 0x66, 0x41, + 0x42, 0x4E, 0x3B, 0x88, 0x29, 0x2F, 0xB1, 0xD8, + 0x95, 0x44, 0x40, 0x6A, 0xDE, 0x9B, 0xCC, 0xB5 + }, + { + 0xE5, 0x3F, 0x60, 0x07, 0x40, 0x22, 0x4E, 0x4D, + 0x10, 0xD3, 0x1D, 0x24, 0x38, 0x00, 0x31, 0x43, + 0xAF, 0xDB, 0x43, 0x6E, 0xB1, 0x79, 0x1B, 0x15, + 0x0D, 0xE3, 0x56, 0x76, 0xF0, 0xE3, 0x2F, 0x80, + 0xB0, 0xB6, 0x5F, 0x0A, 0xCF, 0x48, 0x1A, 0x5F, + 0xBF, 0x95, 0x96, 0xC0, 0xCB, 0x0A, 0x27, 0xC7, + 0xAF, 0xC1, 0x1D, 0x1E, 0x2C, 0x4D, 0x54, 0x02, + 0x47, 0x5E, 0x4F, 0xFC, 0xC1, 0xCD, 0xA8, 0x11 + }, + { + 0x62, 0x06, 0xB9, 0x1F, 0xC0, 0xB6, 0xF1, 0x21, + 0x1E, 0x9F, 0xDE, 0xCD, 0xC9, 0xD5, 0x1A, 0x6F, + 0x1E, 0xEE, 0x65, 0x54, 0xB1, 0x38, 0xAD, 0xCD, + 0x4A, 0x82, 0x3D, 0xF0, 0x0D, 0xDE, 0xF6, 0x75, + 0x9A, 0x9B, 0xFD, 0x7A, 0x4E, 0x98, 0x1E, 0x04, + 0x52, 0x36, 0x83, 0x8F, 0x4A, 0xF6, 0x93, 0xF6, + 0x93, 0x77, 0x93, 0x14, 0x84, 0xB3, 0xE8, 0x1E, + 0x3E, 0x3B, 0xC2, 0xCB, 0x7E, 0xF7, 0x9F, 0xE9 + }, + { + 0x76, 0xFD, 0x02, 0xDA, 0xDD, 0x96, 0x3B, 0xC0, + 0x35, 0x39, 0x91, 0x46, 0xCE, 0x42, 0x98, 0x8C, + 0xC0, 0x99, 0xD3, 0xCF, 0x4D, 0x32, 0xDF, 0x5C, + 0x0B, 0xBF, 0x64, 0x10, 0x12, 0x46, 0xB1, 0xC7, + 0x08, 0xD1, 0x67, 0xE2, 0x95, 0x95, 0xD1, 0x1D, + 0x09, 0xB3, 0xF6, 0x34, 0x86, 0xB4, 0x05, 0x26, + 0xAC, 0x1D, 0xFE, 0x31, 0xBC, 0x22, 0xDE, 0xC7, + 0x0B, 0x74, 0x5E, 0x90, 0xE2, 0xEA, 0xAF, 0x5A + }, + { + 0xF0, 0xA1, 0xFB, 0xE3, 0x11, 0x63, 0xE4, 0x21, + 0x01, 0x50, 0x72, 0x18, 0x3D, 0x68, 0xEE, 0x51, + 0x91, 0xA9, 0x9C, 0xFD, 0xA1, 0x69, 0xBA, 0x5A, + 0x19, 0x54, 0xC9, 0xF3, 0x10, 0x7D, 0x4E, 0xCA, + 0x06, 0x3E, 0x13, 0x7A, 0x71, 0x14, 0xD3, 0x97, + 0xC9, 0xDB, 0x67, 0x2B, 0x9F, 0x47, 0x8D, 0x41, + 0xC3, 0x4E, 0x99, 0x1B, 0x06, 0x69, 0xA9, 0x51, + 0x53, 0x92, 0x90, 0xC8, 0xED, 0x65, 0xE4, 0x6A + }, + { + 0x13, 0xC7, 0x2A, 0x6A, 0xA5, 0x71, 0xB1, 0x43, + 0xDC, 0xCF, 0x45, 0xAD, 0xCD, 0x98, 0xEA, 0xE6, + 0x99, 0xA1, 0x54, 0xB1, 0x10, 0xF2, 0x5E, 0x7E, + 0x9E, 0x82, 0xB7, 0x65, 0xB9, 0xA0, 0x89, 0x23, + 0x68, 0x8E, 0x8E, 0x0F, 0xF3, 0x11, 0xA6, 0x8A, + 0x77, 0x1E, 0x14, 0x50, 0x96, 0xD6, 0x07, 0x76, + 0xC6, 0xD6, 0xEE, 0x70, 0xAD, 0x6F, 0x69, 0xFA, + 0x2B, 0x76, 0x77, 0x63, 0x40, 0x55, 0xA0, 0x0E + }, + { + 0x0E, 0x06, 0x2B, 0xFE, 0x81, 0x8E, 0xE1, 0x0F, + 0x33, 0x48, 0x1D, 0xEA, 0x43, 0x02, 0x8B, 0x2C, + 0xFB, 0xB4, 0x9E, 0xC9, 0x5E, 0x0F, 0x75, 0xA9, + 0xE1, 0x6D, 0x40, 0x4B, 0xC5, 0x19, 0xB9, 0xAD, + 0x50, 0xB4, 0xA7, 0x33, 0x69, 0x2C, 0xA5, 0x4E, + 0xFB, 0x68, 0x04, 0x69, 0xED, 0x83, 0xDD, 0xEF, + 0xBD, 0xDD, 0xB1, 0x39, 0x04, 0x2E, 0x0E, 0x1C, + 0x09, 0xC3, 0xEB, 0x79, 0x03, 0xFA, 0x08, 0xDF + }, + { + 0x45, 0x3B, 0xE4, 0xAA, 0xB9, 0xF4, 0x23, 0xB3, + 0x36, 0x52, 0xA0, 0xB5, 0xD0, 0x2A, 0x9A, 0xF8, + 0x55, 0xDD, 0x0D, 0x42, 0xDD, 0x83, 0x11, 0x0B, + 0xA3, 0xBC, 0x4B, 0x39, 0x94, 0xEA, 0x3F, 0x88, + 0x5A, 0x71, 0x30, 0x89, 0x75, 0x08, 0x9B, 0x49, + 0x03, 0xE2, 0xE4, 0xD6, 0xBA, 0x6D, 0xC2, 0xE8, + 0x40, 0x31, 0xFF, 0xE9, 0xC8, 0x56, 0x39, 0x75, + 0xC8, 0x61, 0x6A, 0xCA, 0x07, 0x42, 0xE8, 0x29 + }, + { + 0x53, 0x61, 0xE3, 0xE8, 0x93, 0xDD, 0x36, 0x0B, + 0xCB, 0xF5, 0x1C, 0x79, 0x3E, 0xC0, 0x92, 0xA6, + 0xB0, 0x52, 0x05, 0x4F, 0x5F, 0x00, 0x0B, 0x9F, + 0xCE, 0x50, 0x7B, 0x66, 0x45, 0xF8, 0xD4, 0x70, + 0x13, 0xA8, 0x70, 0x6A, 0x58, 0xD4, 0xB1, 0x06, + 0x29, 0xCC, 0x82, 0xB8, 0xD2, 0xD7, 0x96, 0xFD, + 0xD3, 0x7B, 0x60, 0x8A, 0x58, 0x79, 0x52, 0xD6, + 0x55, 0x3E, 0x01, 0xD1, 0xAF, 0x0E, 0x04, 0xB8 + }, + { + 0x74, 0xB5, 0x67, 0x39, 0xF0, 0x1F, 0x82, 0x09, + 0xA4, 0x04, 0x44, 0xDF, 0x4C, 0xCD, 0xEE, 0xEA, + 0x8F, 0x97, 0xE8, 0xE7, 0x6E, 0xFA, 0x3C, 0x04, + 0x33, 0x7F, 0x69, 0x94, 0x5C, 0x4D, 0x44, 0xC0, + 0x85, 0xF1, 0xF4, 0x78, 0x96, 0x96, 0x36, 0x1E, + 0x3C, 0x97, 0x77, 0x4A, 0x93, 0x5F, 0x86, 0x0D, + 0x67, 0x46, 0x86, 0xDC, 0xBA, 0x3D, 0x45, 0xEC, + 0xD8, 0x63, 0x9A, 0x64, 0xAE, 0xA0, 0x62, 0x1B + }, + { + 0xB4, 0xD3, 0x15, 0x87, 0xB9, 0x2B, 0x53, 0x61, + 0xCD, 0xC2, 0xD3, 0xC4, 0x10, 0x86, 0xC1, 0x55, + 0x3E, 0x7B, 0x55, 0xA1, 0xF6, 0x1E, 0x94, 0xD2, + 0xBC, 0x30, 0xBC, 0x25, 0x1D, 0xAF, 0x8A, 0x5E, + 0xBF, 0xC5, 0x07, 0x09, 0xCC, 0x04, 0xCB, 0xAF, + 0x4B, 0x3B, 0x4D, 0xA2, 0xD2, 0x6B, 0x81, 0x23, + 0x8F, 0xBA, 0x71, 0x8F, 0xA9, 0x17, 0x59, 0xB8, + 0x0B, 0xD3, 0x10, 0x3A, 0xEC, 0x11, 0xE0, 0x6F + }, + { + 0xAA, 0xF6, 0x12, 0x7F, 0x00, 0xA0, 0x3D, 0x96, + 0x40, 0x6B, 0x9F, 0xB4, 0xAC, 0x70, 0x16, 0x0D, + 0xB5, 0x22, 0x42, 0x9B, 0x5C, 0xD9, 0x4E, 0x7F, + 0xA0, 0x30, 0x3A, 0x74, 0x94, 0x78, 0xFE, 0x31, + 0x89, 0xC8, 0xEA, 0x23, 0x93, 0x0A, 0x66, 0x25, + 0x2A, 0x80, 0x26, 0x74, 0xDC, 0xAF, 0x77, 0x00, + 0x46, 0x82, 0x0D, 0xD9, 0x64, 0xC6, 0x6F, 0x0F, + 0x54, 0x75, 0x1A, 0x72, 0xF9, 0x7D, 0x9C, 0x35 + }, + { + 0x2C, 0x30, 0xD4, 0x8D, 0xF9, 0x98, 0x4E, 0x02, + 0xF7, 0x5A, 0x94, 0x54, 0x92, 0x17, 0x18, 0x4D, + 0xD0, 0x2A, 0xAD, 0x3B, 0x57, 0x68, 0x3D, 0x09, + 0xB5, 0xA8, 0xC2, 0xEF, 0x53, 0xA9, 0x6A, 0xFB, + 0x73, 0xFE, 0xB6, 0xF9, 0x14, 0xE2, 0xD8, 0x15, + 0xBB, 0x3B, 0x08, 0x65, 0x43, 0x32, 0xFC, 0xFE, + 0x79, 0xF8, 0x0E, 0xC5, 0xF0, 0x51, 0xDA, 0x10, + 0xD7, 0x21, 0x41, 0x3D, 0xDD, 0xE8, 0xFA, 0x60 + }, + { + 0x92, 0xE2, 0xC5, 0xF7, 0x5D, 0x0C, 0xEA, 0xFC, + 0x81, 0x8F, 0xA7, 0x93, 0x59, 0x39, 0xE4, 0x8B, + 0x91, 0x59, 0x41, 0xEF, 0x73, 0x4D, 0x75, 0x27, + 0x0E, 0xB3, 0x21, 0xBA, 0x20, 0x80, 0xEF, 0x6D, + 0x25, 0x5E, 0x90, 0xEF, 0x96, 0xC6, 0x4C, 0xFF, + 0x1D, 0x8C, 0x18, 0xF3, 0x3C, 0x2E, 0xAB, 0x10, + 0x7F, 0xEF, 0x53, 0xE0, 0xD8, 0xBB, 0x16, 0x05, + 0x16, 0x80, 0x74, 0x80, 0xFC, 0xBA, 0x53, 0x73 + }, + { + 0x6E, 0x03, 0xA9, 0x1E, 0x20, 0x44, 0x46, 0x27, + 0xE3, 0xD2, 0xE2, 0x22, 0x26, 0xCF, 0x47, 0x00, + 0x26, 0x69, 0x44, 0x34, 0xED, 0x64, 0x79, 0x82, + 0x8C, 0xB6, 0xDC, 0x8F, 0x27, 0x96, 0x0A, 0xEE, + 0xE2, 0xF4, 0xAB, 0x87, 0x2A, 0x5C, 0xA2, 0xF7, + 0xF6, 0x52, 0xF7, 0xDC, 0x77, 0xD5, 0xF9, 0x6D, + 0x85, 0x82, 0x8B, 0x8F, 0x9C, 0x2D, 0x6C, 0x23, + 0x9E, 0x79, 0x77, 0x24, 0xA1, 0x31, 0x31, 0xB1 + }, + { + 0xBA, 0x43, 0x2D, 0xB0, 0xA3, 0x31, 0xBB, 0x8C, + 0x39, 0xB1, 0x7B, 0xEE, 0x34, 0x46, 0x2B, 0x26, + 0xDD, 0xB7, 0xAD, 0x91, 0xB6, 0xC7, 0x5A, 0xEC, + 0x27, 0x65, 0xFB, 0xAE, 0x3A, 0x0E, 0x60, 0xEC, + 0x54, 0x6D, 0x45, 0xF8, 0xE5, 0x84, 0x37, 0xB9, + 0xD7, 0x7C, 0x3D, 0x2E, 0x8D, 0x7C, 0xE0, 0x69, + 0x73, 0x15, 0x66, 0x51, 0xD4, 0x08, 0x22, 0x2A, + 0xA2, 0x90, 0xCB, 0x58, 0xCA, 0xBC, 0x0A, 0xE5 + }, + { + 0x83, 0xA0, 0x1E, 0x23, 0xAB, 0x27, 0x7B, 0x1F, + 0xC2, 0x8C, 0xD8, 0xBB, 0x8D, 0xA7, 0xE9, 0x4C, + 0x70, 0xF1, 0xDE, 0xE3, 0x2D, 0x19, 0x55, 0xCE, + 0xE2, 0x50, 0xEE, 0x58, 0x41, 0x9A, 0x1F, 0xEE, + 0x10, 0xA8, 0x99, 0x17, 0x97, 0xCE, 0x3D, 0x20, + 0x93, 0x80, 0xCA, 0x9F, 0x98, 0x93, 0x39, 0xE2, + 0xD8, 0xA8, 0x1C, 0x67, 0xD7, 0x37, 0xD8, 0x28, + 0x8C, 0x7F, 0xAE, 0x46, 0x02, 0x83, 0x4A, 0x8B + }, + { + 0x0E, 0xA3, 0x21, 0x72, 0xCC, 0x19, 0x1D, 0xFC, + 0x13, 0x1C, 0xD8, 0x8A, 0xA0, 0x3F, 0xF4, 0x18, + 0x5C, 0x0B, 0xFA, 0x7B, 0x19, 0x11, 0x12, 0x19, + 0xEE, 0xCB, 0x45, 0xB0, 0xFF, 0x60, 0x4D, 0x3E, + 0xDB, 0x00, 0x55, 0x0A, 0xBB, 0xA1, 0x11, 0x52, + 0x2B, 0x77, 0xAE, 0x61, 0xC9, 0xA8, 0xD6, 0xE9, + 0x4F, 0xCA, 0x9D, 0x96, 0xC3, 0x8D, 0x6B, 0x7C, + 0xCE, 0x27, 0x52, 0xF0, 0xD0, 0xC3, 0x7E, 0x78 + }, + { + 0x54, 0xAD, 0xD6, 0x55, 0x2B, 0x08, 0x85, 0x8B, + 0x23, 0xD6, 0x64, 0x5F, 0x6C, 0xE7, 0x9E, 0x92, + 0xF3, 0x8B, 0x66, 0xAE, 0x91, 0x86, 0x77, 0xE6, + 0xD9, 0x1F, 0x71, 0x87, 0xC4, 0x16, 0x05, 0x24, + 0xDF, 0xA8, 0xD0, 0x1F, 0x00, 0xEA, 0x93, 0xDD, + 0x29, 0x9F, 0x3C, 0xC4, 0x09, 0x01, 0xBD, 0x33, + 0x27, 0xA0, 0xF1, 0x8C, 0xCD, 0x7B, 0x6B, 0x8E, + 0x4E, 0x47, 0xCD, 0x28, 0xCF, 0x83, 0x8F, 0xAB + }, + { + 0xEF, 0x84, 0x74, 0x6D, 0xC2, 0x01, 0x56, 0xB6, + 0x6B, 0xA5, 0xC7, 0x8A, 0x50, 0x83, 0x0A, 0xBD, + 0x2A, 0xEF, 0x90, 0xE6, 0x67, 0xB9, 0x7E, 0xB5, + 0x22, 0x91, 0xBC, 0x86, 0x9D, 0x8A, 0xA2, 0x45, + 0x59, 0xA1, 0x42, 0xC6, 0x8F, 0xEA, 0x2E, 0xF3, + 0x2A, 0xF2, 0x2D, 0xFC, 0xEA, 0x4C, 0x90, 0xB3, + 0xD4, 0x90, 0x8C, 0xC9, 0xEA, 0x5C, 0xFC, 0x4E, + 0x91, 0xBF, 0x11, 0xCE, 0x6A, 0x7E, 0x57, 0x61 + }, + { + 0x5A, 0x1B, 0xF3, 0x81, 0xA0, 0x41, 0x19, 0xF9, + 0x42, 0xE4, 0x63, 0xAB, 0xA2, 0xB1, 0x64, 0x38, + 0x82, 0x46, 0x8A, 0xEC, 0xC1, 0xB1, 0xAA, 0x1E, + 0x7B, 0xCA, 0xAB, 0x3B, 0x47, 0x8F, 0xC5, 0xF0, + 0x56, 0xF1, 0x0D, 0xA9, 0x03, 0x7D, 0x40, 0xFA, + 0x7F, 0x55, 0x70, 0x8E, 0x10, 0x3B, 0xDA, 0x96, + 0x5E, 0x92, 0x0C, 0xF6, 0x7C, 0xE3, 0xAD, 0xF7, + 0xE2, 0x00, 0xE8, 0x61, 0x01, 0x4D, 0xEC, 0xC6 + }, + { + 0xAC, 0xF7, 0x8A, 0xA3, 0x28, 0x45, 0x96, 0xF3, + 0x30, 0xB7, 0xE8, 0x47, 0x51, 0xB9, 0x4C, 0x31, + 0x4C, 0xD8, 0x36, 0x36, 0x27, 0xBA, 0x99, 0x78, + 0x81, 0x30, 0x85, 0x78, 0x87, 0x37, 0x59, 0x89, + 0x5D, 0x13, 0xDF, 0xFF, 0xA5, 0xE5, 0x74, 0x50, + 0x13, 0x61, 0xF0, 0x43, 0xC7, 0x4F, 0x57, 0xD2, + 0xD0, 0xF1, 0x5C, 0x7A, 0x41, 0xC7, 0xC4, 0x5E, + 0x3C, 0x09, 0xAD, 0x89, 0xD6, 0x99, 0xA9, 0x77 + }, + { + 0x18, 0xB3, 0xE9, 0x04, 0x38, 0x44, 0xD4, 0xF3, + 0xA2, 0xD0, 0x21, 0xF5, 0x4C, 0x38, 0xFA, 0xCC, + 0x36, 0x4F, 0x84, 0xBA, 0x10, 0x58, 0xF2, 0x10, + 0x09, 0xFC, 0x37, 0x1D, 0x2E, 0x4F, 0x38, 0xC7, + 0x27, 0x51, 0x8A, 0xAB, 0xA6, 0xA2, 0x9E, 0x0F, + 0xDA, 0xE6, 0xE7, 0x60, 0xA4, 0xF1, 0xA6, 0xD7, + 0x58, 0xEB, 0xE4, 0x2C, 0x2A, 0xFC, 0x9D, 0x2C, + 0xDC, 0x6D, 0xD5, 0x80, 0x77, 0x8C, 0x4B, 0x32 + }, + { + 0x18, 0x96, 0xB2, 0x31, 0x70, 0x33, 0xCF, 0x31, + 0x04, 0x68, 0x73, 0xD8, 0x7F, 0x26, 0xE6, 0xA4, + 0x2A, 0x9D, 0x77, 0x0B, 0xBA, 0xF6, 0xE0, 0x62, + 0xDF, 0x11, 0xF9, 0xB4, 0xA0, 0xEA, 0xB2, 0x75, + 0xAA, 0xB1, 0x2C, 0xAA, 0xC2, 0xD3, 0xF5, 0x29, + 0xEB, 0x20, 0xD0, 0x70, 0xFD, 0x84, 0x4D, 0x86, + 0xD0, 0xA5, 0x71, 0xCD, 0xF6, 0x28, 0x5F, 0x80, + 0xE2, 0x30, 0x8B, 0xB8, 0x2C, 0x6C, 0x5B, 0x3B + }, + { + 0x8C, 0x3D, 0xC4, 0x01, 0x94, 0xAA, 0x02, 0x1F, + 0x3C, 0x4A, 0x1F, 0x9A, 0x05, 0x5E, 0x4D, 0x41, + 0x9E, 0xB3, 0xA2, 0x6D, 0x4C, 0x2F, 0x1A, 0x8C, + 0x7E, 0x18, 0x8B, 0x73, 0x48, 0x13, 0x40, 0x80, + 0xB6, 0x3F, 0x6E, 0x57, 0x0A, 0xD1, 0x1C, 0x28, + 0x78, 0x66, 0x53, 0x55, 0x41, 0x9C, 0x10, 0x20, + 0xDE, 0x4B, 0x65, 0x5E, 0x7A, 0x6C, 0x2C, 0xCD, + 0xE9, 0x07, 0x2C, 0xD4, 0x27, 0xFE, 0x8C, 0x4E + }, + { + 0x70, 0xAE, 0x04, 0x30, 0xD5, 0x45, 0xEC, 0x42, + 0x7F, 0x85, 0x41, 0x21, 0x1D, 0x4F, 0xE0, 0x42, + 0xB9, 0x82, 0x3A, 0xCE, 0xC0, 0x4B, 0x15, 0xC9, + 0x0B, 0x7F, 0x4B, 0x8B, 0xDD, 0x3D, 0xC7, 0x85, + 0x19, 0x90, 0xF3, 0x70, 0xE7, 0x14, 0x16, 0x75, + 0x10, 0x66, 0x49, 0xD3, 0x91, 0x51, 0x09, 0x03, + 0x18, 0x23, 0x1E, 0x4D, 0xED, 0x51, 0x22, 0x5D, + 0x9A, 0x6F, 0xA6, 0xC4, 0x24, 0x69, 0x5D, 0xE2 + }, + { + 0x07, 0x33, 0x6C, 0x42, 0xBD, 0x51, 0x49, 0x0E, + 0xF8, 0x4D, 0xFB, 0xDF, 0xAB, 0x74, 0x66, 0xF6, + 0xB6, 0x39, 0x99, 0xA5, 0xC0, 0x88, 0x72, 0xDF, + 0xED, 0xA0, 0x20, 0x6F, 0xDA, 0x80, 0xB9, 0xA6, + 0x2D, 0xE7, 0x28, 0xE3, 0xE3, 0xC3, 0xFD, 0x6B, + 0x7D, 0x21, 0xA4, 0x38, 0xAA, 0xD1, 0xB8, 0xDD, + 0x22, 0x38, 0x63, 0xC0, 0xD2, 0x6A, 0xCA, 0x27, + 0x79, 0x01, 0x74, 0xD9, 0xD4, 0x42, 0xA6, 0x4C + }, + { + 0x79, 0x26, 0x70, 0x88, 0x59, 0xE6, 0xE2, 0xAB, + 0x68, 0xF6, 0x04, 0xDA, 0x69, 0xA9, 0xFB, 0x50, + 0x87, 0xBB, 0x33, 0xF4, 0xE8, 0xD8, 0x95, 0x73, + 0x0E, 0x30, 0x1A, 0xB2, 0xD7, 0xDF, 0x74, 0x8B, + 0x67, 0xDF, 0x0B, 0x6B, 0x86, 0x22, 0xE5, 0x2D, + 0xD5, 0x7D, 0x8D, 0x3A, 0xD8, 0x7D, 0x58, 0x20, + 0xD4, 0xEC, 0xFD, 0x24, 0x17, 0x8B, 0x2D, 0x2B, + 0x78, 0xD6, 0x4F, 0x4F, 0xBD, 0x38, 0x75, 0x82 + }, + { + 0x92, 0x80, 0xF4, 0xD1, 0x15, 0x70, 0x32, 0xAB, + 0x31, 0x5C, 0x10, 0x0D, 0x63, 0x62, 0x83, 0xFB, + 0xF4, 0xFB, 0xA2, 0xFB, 0xAD, 0x0F, 0x8B, 0xC0, + 0x20, 0x72, 0x1D, 0x76, 0xBC, 0x1C, 0x89, 0x73, + 0xCE, 0xD2, 0x88, 0x71, 0xCC, 0x90, 0x7D, 0xAB, + 0x60, 0xE5, 0x97, 0x56, 0x98, 0x7B, 0x0E, 0x0F, + 0x86, 0x7F, 0xA2, 0xFE, 0x9D, 0x90, 0x41, 0xF2, + 0xC9, 0x61, 0x80, 0x74, 0xE4, 0x4F, 0xE5, 0xE9 + }, + { + 0x55, 0x30, 0xC2, 0xD5, 0x9F, 0x14, 0x48, 0x72, + 0xE9, 0x87, 0xE4, 0xE2, 0x58, 0xA7, 0xD8, 0xC3, + 0x8C, 0xE8, 0x44, 0xE2, 0xCC, 0x2E, 0xED, 0x94, + 0x0F, 0xFC, 0x68, 0x3B, 0x49, 0x88, 0x15, 0xE5, + 0x3A, 0xDB, 0x1F, 0xAA, 0xF5, 0x68, 0x94, 0x61, + 0x22, 0x80, 0x5A, 0xC3, 0xB8, 0xE2, 0xFE, 0xD4, + 0x35, 0xFE, 0xD6, 0x16, 0x2E, 0x76, 0xF5, 0x64, + 0xE5, 0x86, 0xBA, 0x46, 0x44, 0x24, 0xE8, 0x85 + }, + { + 0xDA, 0x85, 0x0A, 0x2F, 0x54, 0xE9, 0x44, 0x89, + 0x17, 0xD0, 0xDC, 0xAA, 0x63, 0x93, 0x7B, 0x95, + 0xA4, 0xDA, 0x1E, 0xAC, 0x8A, 0xF4, 0xDD, 0xF2, + 0x11, 0x3E, 0x5C, 0x8B, 0x0D, 0x4D, 0xB2, 0x66, + 0x9A, 0xF3, 0xC2, 0xAC, 0xB0, 0x80, 0x3D, 0x05, + 0x32, 0x3F, 0x3E, 0xC5, 0x5A, 0xBD, 0x33, 0xBD, + 0xF9, 0xB2, 0xBE, 0x89, 0x0E, 0xE7, 0x9E, 0x7F, + 0x3F, 0xCE, 0x4E, 0x19, 0x86, 0x96, 0xA7, 0xA3 + }, + { + 0xF1, 0x60, 0x95, 0xDD, 0x9F, 0x1E, 0xEB, 0x77, + 0xD5, 0xB9, 0x2F, 0x4B, 0x1F, 0xAC, 0x3A, 0x2C, + 0x5D, 0xA6, 0xAE, 0x5D, 0x0A, 0xB3, 0xF2, 0x54, + 0xE2, 0xA7, 0xFE, 0x52, 0x67, 0x24, 0x11, 0xD0, + 0x1C, 0xFA, 0x6A, 0xC0, 0x5B, 0xF3, 0x9E, 0xF6, + 0x5F, 0x4B, 0x22, 0x26, 0x4B, 0x41, 0xC3, 0xF3, + 0x63, 0x56, 0x3A, 0xBF, 0x0E, 0x92, 0x42, 0x90, + 0xC1, 0xC6, 0x80, 0xB1, 0x8A, 0xA6, 0x5B, 0x44 + }, + { + 0x76, 0xD0, 0x0A, 0x09, 0xC5, 0xBD, 0xD3, 0x9E, + 0xD3, 0x28, 0x71, 0x72, 0x2C, 0xFA, 0x00, 0x47, + 0x67, 0x4B, 0xEC, 0x8D, 0x35, 0x17, 0x5A, 0xF9, + 0x0D, 0x7A, 0xE9, 0x10, 0x74, 0x40, 0xA2, 0xA0, + 0x63, 0x88, 0x56, 0xD8, 0x38, 0x4C, 0x81, 0x7D, + 0x77, 0x2A, 0x4A, 0x59, 0x7A, 0x89, 0x55, 0x49, + 0xC8, 0x48, 0x66, 0x37, 0x56, 0x31, 0xCB, 0xA0, + 0x42, 0xF0, 0xEF, 0x6F, 0xFE, 0xB8, 0x9D, 0x44 + }, + { + 0xA6, 0x51, 0x13, 0x7B, 0x2C, 0x47, 0xFB, 0x79, + 0x51, 0xE7, 0xBD, 0xA7, 0x15, 0x43, 0xA6, 0xEB, + 0xC6, 0x24, 0x2A, 0xCA, 0xB4, 0x34, 0x7D, 0x38, + 0x8B, 0xE8, 0x35, 0x0F, 0x0C, 0x3F, 0xA3, 0xDF, + 0x8D, 0x95, 0x2C, 0x7C, 0x8A, 0x3D, 0xAF, 0x01, + 0xE0, 0x6C, 0x1D, 0xA6, 0x94, 0x96, 0xBB, 0xA8, + 0xDE, 0x62, 0xD8, 0x6B, 0x50, 0x93, 0x25, 0x6F, + 0x77, 0xA1, 0x87, 0xB5, 0x3D, 0xB0, 0x39, 0x88 + }, + { + 0xF3, 0x2F, 0x15, 0x0C, 0x2D, 0x67, 0xC0, 0xC4, + 0x37, 0x40, 0x1B, 0x70, 0xF6, 0x0B, 0x38, 0xF0, + 0xA3, 0xA4, 0x70, 0x59, 0x03, 0x3E, 0x75, 0x05, + 0xE6, 0x9A, 0x1D, 0x30, 0x12, 0x96, 0x03, 0x0B, + 0xC9, 0xB2, 0x95, 0x19, 0xC7, 0xF8, 0xB7, 0xD5, + 0x9A, 0x71, 0xFA, 0xB9, 0x05, 0x57, 0xDC, 0x3D, + 0xC8, 0x23, 0xFA, 0xC9, 0x5B, 0x9E, 0x85, 0xE6, + 0x52, 0x52, 0x8C, 0xBF, 0xB0, 0x1B, 0x11, 0x78 + }, + { + 0x27, 0x02, 0x56, 0x61, 0x36, 0xC4, 0x92, 0xF4, + 0x10, 0x89, 0xB0, 0x60, 0x10, 0x84, 0x60, 0xFA, + 0x30, 0x22, 0xC9, 0xC2, 0x5D, 0x34, 0x3B, 0xCB, + 0xD8, 0xAF, 0x2A, 0xF1, 0x9C, 0x17, 0xEF, 0x4C, + 0xA9, 0xF2, 0x22, 0x4F, 0xE7, 0xC4, 0x70, 0x0A, + 0x10, 0x19, 0x8E, 0xE5, 0x24, 0x8F, 0x30, 0x0B, + 0x54, 0x8E, 0xBF, 0x5C, 0x8E, 0x71, 0x16, 0x32, + 0x0C, 0xC8, 0x93, 0xFF, 0x7E, 0x23, 0x1F, 0xFB + }, + { + 0xFF, 0xE6, 0x87, 0x9F, 0x46, 0xB6, 0x29, 0x2B, + 0x21, 0x96, 0x97, 0x2E, 0x3F, 0xDF, 0x4F, 0xE9, + 0xEA, 0x4A, 0x81, 0x6D, 0x18, 0x07, 0xA3, 0x1C, + 0xAE, 0xAD, 0x6A, 0xAC, 0x5F, 0x06, 0x3C, 0x8F, + 0xE8, 0x77, 0x79, 0x75, 0x59, 0xA7, 0x59, 0xA0, + 0x0F, 0x8B, 0xA8, 0xF6, 0x68, 0xD8, 0x96, 0x8F, + 0xB3, 0x1D, 0x8A, 0x3B, 0x84, 0x57, 0x35, 0x90, + 0x2C, 0x5E, 0x42, 0xE2, 0x89, 0xEE, 0x0B, 0x62 + }, + { + 0x14, 0x48, 0x84, 0x28, 0x68, 0x22, 0xC2, 0x51, + 0x2D, 0x61, 0xB0, 0x46, 0xE6, 0x74, 0xD8, 0x6B, + 0x26, 0x4E, 0x9C, 0xC6, 0x89, 0x3E, 0xFF, 0x36, + 0x73, 0x11, 0x24, 0xF5, 0x9D, 0x1A, 0x82, 0x00, + 0x1E, 0x63, 0xF3, 0xE8, 0x05, 0x1C, 0xFE, 0x52, + 0xE7, 0x59, 0x7E, 0x28, 0x73, 0x8E, 0x3C, 0x3A, + 0x70, 0xF1, 0xBE, 0xD9, 0x68, 0x0E, 0x2C, 0x0E, + 0xF3, 0x72, 0x8B, 0x10, 0xA5, 0x6E, 0xD9, 0x87 + }, + { + 0x17, 0xC3, 0xF1, 0x46, 0xEE, 0x8D, 0xEC, 0x3B, + 0xAF, 0xCB, 0x51, 0xC0, 0xDA, 0x37, 0xF1, 0x78, + 0x71, 0xF2, 0x34, 0xC4, 0xA0, 0xFB, 0x7F, 0xA6, + 0xD0, 0x70, 0x7A, 0x54, 0x3E, 0x3C, 0xBF, 0x3A, + 0xDB, 0x81, 0xE3, 0x0C, 0x1E, 0x0A, 0xE9, 0xE1, + 0xAC, 0xE7, 0x22, 0x3B, 0xDA, 0x99, 0xBD, 0x59, + 0x19, 0xA3, 0xCF, 0xCC, 0x92, 0xC6, 0xA7, 0x55, + 0xE4, 0x56, 0xF0, 0x93, 0x82, 0x3B, 0xD3, 0x3E + }, + { + 0x1B, 0x83, 0x7A, 0xF2, 0x33, 0xA8, 0xA6, 0x8B, + 0xE7, 0x09, 0x52, 0xF7, 0x83, 0xC4, 0x96, 0x1A, + 0x81, 0x52, 0xD1, 0xE0, 0xB0, 0xFA, 0x32, 0x5F, + 0xF0, 0x86, 0xEA, 0x5B, 0x5F, 0x13, 0x12, 0xB8, + 0x9C, 0x42, 0xE0, 0x1B, 0x8C, 0x3A, 0x47, 0x7C, + 0xB5, 0x40, 0xC0, 0x6B, 0x2F, 0x37, 0xEE, 0x0E, + 0x39, 0x24, 0xD7, 0x45, 0xB4, 0xFF, 0x5C, 0x6A, + 0xF7, 0xD6, 0x1E, 0x0E, 0x37, 0xAC, 0x19, 0x31 + }, + { + 0x78, 0x97, 0x88, 0x0C, 0x1E, 0xB0, 0x0F, 0xD2, + 0x56, 0x7A, 0xE8, 0xA5, 0x9E, 0x64, 0x82, 0xAF, + 0xE1, 0x73, 0x49, 0xCF, 0x93, 0x92, 0x4A, 0x91, + 0x5F, 0x8C, 0x59, 0x26, 0x93, 0xD4, 0x52, 0x07, + 0x55, 0x19, 0x68, 0x9D, 0xFC, 0xD2, 0x93, 0xE3, + 0x76, 0x89, 0x7B, 0x3B, 0x0E, 0x03, 0x6F, 0x11, + 0x4F, 0xE8, 0x1E, 0xBC, 0xB3, 0x15, 0x36, 0x71, + 0xBD, 0x23, 0xBC, 0x2B, 0xED, 0x46, 0xF9, 0xC2 + }, + { + 0xCA, 0x7B, 0x6C, 0x77, 0x5D, 0x20, 0x1E, 0x5B, + 0x5A, 0x77, 0x22, 0x61, 0xDE, 0x52, 0x8E, 0x47, + 0x5F, 0x4B, 0xDE, 0x51, 0x76, 0x60, 0x52, 0x9F, + 0x41, 0xBE, 0xEB, 0x15, 0x78, 0xB2, 0x4B, 0xCB, + 0x94, 0xB9, 0x41, 0x0F, 0x9B, 0xF3, 0x36, 0xC1, + 0x09, 0xF9, 0xD4, 0x70, 0x93, 0xA1, 0x0B, 0xA6, + 0xDE, 0xBE, 0x50, 0x43, 0x80, 0xD9, 0xD1, 0x50, + 0x73, 0xBD, 0xD1, 0x11, 0xC8, 0xD1, 0x29, 0xFA + }, + { + 0x57, 0x18, 0xE0, 0xD4, 0x5D, 0xEB, 0xC3, 0x00, + 0x2D, 0x52, 0xB2, 0x2C, 0x52, 0x73, 0x29, 0xAE, + 0x5E, 0xBF, 0x27, 0xE8, 0xFA, 0x9C, 0x8F, 0xEA, + 0xB4, 0x6C, 0x40, 0xBC, 0x64, 0x22, 0xCA, 0x03, + 0x35, 0x30, 0x4C, 0xF9, 0xE7, 0xF1, 0x41, 0xDE, + 0x7F, 0xA6, 0xAD, 0xB6, 0x78, 0x9B, 0xDB, 0xF3, + 0x8D, 0x14, 0xDA, 0xBA, 0x3E, 0x62, 0x97, 0xD2, + 0x5B, 0xF1, 0x7D, 0xE1, 0x70, 0xD6, 0xE3, 0xC8 + }, + { + 0x48, 0xD0, 0xED, 0x24, 0x9F, 0x90, 0x28, 0x41, + 0x99, 0x7C, 0x25, 0x5D, 0xAF, 0x99, 0x08, 0x9C, + 0x9A, 0x31, 0x24, 0x69, 0x8B, 0x16, 0x4A, 0x30, + 0x28, 0x33, 0x0F, 0xDD, 0x4C, 0xEE, 0x41, 0xE1, + 0x68, 0x3F, 0xA4, 0xD9, 0xDC, 0x66, 0xB2, 0xA7, + 0x9C, 0x8A, 0xA4, 0xC8, 0x28, 0x4E, 0x27, 0xBE, + 0xE2, 0xA4, 0x28, 0xA6, 0x71, 0x9D, 0x6E, 0xC6, + 0x55, 0xED, 0x76, 0x9D, 0xCB, 0x62, 0x4E, 0x24 + }, + { + 0x79, 0x4E, 0x0B, 0x64, 0xAC, 0xE1, 0xFE, 0x5A, + 0xE3, 0x79, 0x93, 0x70, 0x68, 0xD8, 0x2D, 0xF0, + 0x48, 0x68, 0x61, 0x6C, 0xAE, 0x0C, 0x17, 0xD3, + 0x05, 0x72, 0xC2, 0x02, 0x4E, 0x77, 0x48, 0x94, + 0xE0, 0x66, 0x8C, 0x47, 0x2D, 0x62, 0x3C, 0x90, + 0x3C, 0xC5, 0x88, 0x5F, 0x17, 0x84, 0x94, 0x51, + 0x10, 0x32, 0x9E, 0xB4, 0x98, 0xA8, 0x95, 0xA9, + 0xE5, 0x9A, 0x75, 0xE5, 0x27, 0x15, 0x8A, 0x5C + }, + { + 0x21, 0x79, 0xAA, 0x82, 0x0E, 0x03, 0xFA, 0x33, + 0xD9, 0xBD, 0xE5, 0x56, 0x8C, 0x26, 0x2E, 0x2D, + 0x34, 0x17, 0xA4, 0x02, 0xE0, 0x7A, 0x59, 0x1F, + 0x9D, 0x55, 0x70, 0x68, 0x2D, 0xB5, 0xF9, 0xBB, + 0xA4, 0xBB, 0x9D, 0x5A, 0x82, 0xEE, 0x5E, 0xFD, + 0xB4, 0xF6, 0x5B, 0xBB, 0xFE, 0xEE, 0x2F, 0x4A, + 0xB9, 0xE4, 0x6C, 0xF2, 0xCE, 0x7E, 0x3B, 0x05, + 0x43, 0x27, 0xA7, 0x18, 0xD3, 0xF1, 0x08, 0x06 + }, + { + 0xB0, 0xA4, 0x8C, 0x6A, 0xDA, 0x54, 0x87, 0x25, + 0x79, 0x9B, 0x59, 0x86, 0xBA, 0xB4, 0x32, 0x69, + 0x79, 0x60, 0x92, 0x24, 0xD8, 0x97, 0x18, 0x4B, + 0x89, 0x97, 0x10, 0x4E, 0x0C, 0x6A, 0x24, 0xB3, + 0xAB, 0xE5, 0x62, 0x16, 0x54, 0x22, 0xA4, 0x5D, + 0x8A, 0xC8, 0x19, 0xB9, 0x9D, 0x37, 0x56, 0xEB, + 0xBB, 0x64, 0xF8, 0x43, 0xE3, 0xE0, 0x93, 0x4D, + 0xEC, 0x48, 0x7A, 0xED, 0x12, 0x13, 0x72, 0x79 + }, + { + 0x84, 0x8D, 0x7F, 0x2E, 0xAD, 0x41, 0x29, 0x1D, + 0x05, 0x38, 0x68, 0x0C, 0x64, 0x9D, 0x07, 0x89, + 0x7E, 0x45, 0xC7, 0x0A, 0x0A, 0xA4, 0xF9, 0x35, + 0x3F, 0x82, 0xC3, 0xF6, 0xFB, 0xB8, 0xE8, 0x48, + 0x9C, 0x75, 0x3E, 0x90, 0xDB, 0xE8, 0x89, 0x00, + 0x41, 0xA1, 0xAE, 0xEF, 0x84, 0xCD, 0x31, 0x36, + 0x43, 0x4F, 0x53, 0x0E, 0x9D, 0xD9, 0xC2, 0x3F, + 0xA5, 0x4F, 0xE1, 0x24, 0xEA, 0xFB, 0x72, 0xAD + }, + { + 0x0E, 0xD1, 0x46, 0x26, 0xEE, 0x6D, 0x0C, 0x8E, + 0xD3, 0xF0, 0xC2, 0x00, 0xC1, 0x29, 0x85, 0x0F, + 0xFF, 0x76, 0x31, 0x8F, 0xFF, 0xA1, 0xDD, 0xD7, + 0xDD, 0x56, 0x3A, 0x01, 0xB7, 0x77, 0x97, 0x06, + 0x86, 0x2B, 0x23, 0x99, 0x59, 0xB6, 0x15, 0xAE, + 0x2E, 0xBE, 0x27, 0xC4, 0x50, 0x37, 0xE6, 0xFF, + 0xAF, 0x99, 0x14, 0xDA, 0x8F, 0xF2, 0x77, 0x2B, + 0xA5, 0xEE, 0x08, 0x11, 0xCD, 0x9E, 0xD5, 0x32 + }, + { + 0x52, 0x03, 0xC0, 0x76, 0x38, 0xC4, 0xB6, 0x5F, + 0x78, 0x43, 0x1E, 0x8B, 0x02, 0xE2, 0x0F, 0x6D, + 0x68, 0x3F, 0x19, 0xFA, 0x8F, 0x83, 0xB5, 0x13, + 0x4C, 0xD0, 0xF4, 0xE4, 0x68, 0xC9, 0x7E, 0xAC, + 0xB5, 0x26, 0x7C, 0x7D, 0x3E, 0xAB, 0x58, 0x3C, + 0xCA, 0xAC, 0xD0, 0xDB, 0xA4, 0xD5, 0x8A, 0xCE, + 0x52, 0x19, 0x3A, 0x51, 0x78, 0xA7, 0xB1, 0x2D, + 0x27, 0x95, 0xF5, 0xFD, 0xE8, 0xA3, 0x7B, 0xB9 + }, + { + 0x48, 0xBE, 0x43, 0xD5, 0xE0, 0x04, 0x36, 0x88, + 0xDF, 0x35, 0x32, 0xF7, 0x12, 0x1A, 0xFF, 0xFA, + 0x16, 0x7D, 0xAB, 0xE4, 0xA4, 0x84, 0xFB, 0x75, + 0xA0, 0x3A, 0xF3, 0x04, 0xA5, 0xC6, 0xF8, 0x25, + 0xF3, 0x6C, 0xEC, 0xCB, 0xBB, 0xC0, 0x75, 0xEE, + 0xF3, 0x20, 0xC4, 0xCD, 0x8D, 0x7E, 0xF8, 0xCB, + 0x49, 0xE6, 0xDD, 0x59, 0x73, 0x37, 0x9E, 0xEC, + 0x4C, 0x23, 0x3C, 0x45, 0x43, 0xD1, 0x32, 0xCE + }, + { + 0xB5, 0x46, 0x4E, 0x6A, 0xBA, 0xF5, 0xD3, 0xD4, + 0x08, 0x3D, 0x1D, 0x7D, 0x2A, 0x8B, 0x0B, 0xAB, + 0x78, 0xB6, 0x17, 0x09, 0x50, 0x0B, 0xBF, 0x77, + 0x82, 0x3F, 0x60, 0x2D, 0x57, 0xD5, 0x13, 0xCA, + 0x9E, 0x9F, 0xFF, 0x65, 0xEF, 0xAA, 0x89, 0x9C, + 0xFE, 0x7B, 0xF8, 0x8A, 0x01, 0x88, 0x82, 0x9C, + 0x24, 0xE4, 0x98, 0xAD, 0x00, 0x23, 0x5A, 0xBE, + 0x8E, 0xEF, 0xA7, 0x19, 0xFA, 0x6A, 0xE6, 0xF6 + }, + { + 0xAF, 0xE5, 0xE5, 0xE8, 0x3F, 0x19, 0xAD, 0xAD, + 0x9E, 0x95, 0x90, 0x3E, 0xA9, 0xB2, 0x98, 0x10, + 0x7D, 0x37, 0xDD, 0x38, 0x63, 0x2C, 0x95, 0x90, + 0xBB, 0xFF, 0xC6, 0x24, 0xD4, 0xDE, 0x95, 0x8C, + 0xB6, 0xB6, 0x1A, 0xF0, 0x80, 0xF0, 0x37, 0xAD, + 0x17, 0xD0, 0x35, 0xB6, 0xBF, 0x58, 0xF7, 0x80, + 0xFA, 0xDF, 0x70, 0xF3, 0xC9, 0x59, 0x66, 0x8A, + 0x1B, 0x47, 0x21, 0x98, 0xA5, 0x9A, 0x8A, 0x00 + }, + { + 0xEF, 0xA2, 0xC7, 0xC8, 0x02, 0xE2, 0x10, 0xD2, + 0xD8, 0x0F, 0xB3, 0x50, 0xB3, 0xC2, 0xCB, 0x31, + 0x56, 0x13, 0x18, 0x11, 0xE7, 0x18, 0xEE, 0xE5, + 0xC9, 0xC6, 0x64, 0x0F, 0x87, 0x68, 0x2A, 0x55, + 0x81, 0x2B, 0x10, 0xF4, 0x03, 0x10, 0xBA, 0xA7, + 0xB8, 0x2B, 0x27, 0x3E, 0xF3, 0xAC, 0xC5, 0x5F, + 0xED, 0xE0, 0xB5, 0xF1, 0x94, 0x9D, 0xE4, 0x29, + 0x3D, 0x91, 0xB5, 0x89, 0xA2, 0x17, 0x5F, 0xF7 + }, + { + 0xD6, 0xC6, 0x2A, 0x61, 0x82, 0x71, 0xF3, 0xBC, + 0xBE, 0x00, 0x79, 0x24, 0xA0, 0xC9, 0x81, 0x2F, + 0x83, 0x17, 0x44, 0x5F, 0xB6, 0xFB, 0x19, 0xEB, + 0x58, 0x9A, 0x62, 0x9F, 0x51, 0x2F, 0xB3, 0x8A, + 0x0B, 0x4E, 0x24, 0x7D, 0xEA, 0x88, 0xC5, 0x6A, + 0x1B, 0xAF, 0x17, 0x88, 0x33, 0x65, 0xB4, 0x36, + 0xF2, 0x84, 0x46, 0xFF, 0x66, 0xEA, 0x43, 0x18, + 0x0B, 0xD0, 0x1E, 0xB5, 0xA6, 0x50, 0x9B, 0xD5 + }, + { + 0x0B, 0x41, 0x16, 0x6B, 0xE6, 0x2F, 0x65, 0xE1, + 0x93, 0xB3, 0xB8, 0x65, 0xE6, 0xC4, 0x7A, 0xAD, + 0x26, 0x0A, 0xF5, 0xFC, 0xEE, 0xC9, 0xAB, 0x44, + 0xAB, 0xAA, 0x46, 0x0A, 0x0C, 0x02, 0x46, 0xB6, + 0xC6, 0x9B, 0x67, 0xD7, 0x1D, 0x3A, 0xDF, 0xEC, + 0x60, 0xDC, 0x8E, 0x77, 0x37, 0x2F, 0x09, 0x49, + 0x52, 0x34, 0x4F, 0xE1, 0x0C, 0x0D, 0x59, 0xEF, + 0xEC, 0x0E, 0x11, 0xC4, 0xA5, 0x16, 0x93, 0x6D + }, + { + 0x79, 0xD5, 0xF9, 0xFF, 0xC0, 0x5E, 0xCF, 0x33, + 0x7D, 0xE9, 0xF1, 0xE0, 0xF1, 0xD8, 0x9B, 0x30, + 0xAC, 0xFE, 0xBB, 0xB8, 0x8A, 0x69, 0x35, 0x86, + 0x78, 0x18, 0xCD, 0x8D, 0x45, 0xDA, 0x3D, 0x25, + 0x18, 0xDE, 0x61, 0xA7, 0xFE, 0x28, 0x75, 0x1B, + 0x61, 0x8F, 0x7A, 0x87, 0x5E, 0x11, 0x89, 0x8F, + 0xFF, 0x74, 0x15, 0x7A, 0xB9, 0x06, 0x81, 0xBD, + 0x53, 0xFA, 0x69, 0x62, 0x67, 0x1E, 0xD9, 0x9D + }, + { + 0xBE, 0xA9, 0x83, 0xD7, 0x6F, 0x24, 0xB1, 0xEE, + 0xDE, 0x1D, 0x06, 0x71, 0x48, 0x05, 0x76, 0x8F, + 0xAA, 0xAD, 0x47, 0x08, 0xC9, 0xA4, 0xFF, 0x9C, + 0xD2, 0x42, 0x2F, 0x70, 0x6B, 0x6F, 0x0C, 0x30, + 0x6D, 0x8B, 0x67, 0xF3, 0x40, 0x89, 0xC6, 0x5E, + 0xD3, 0x88, 0x0C, 0x75, 0xF6, 0x7B, 0xBC, 0x4D, + 0x89, 0xAD, 0x87, 0x12, 0x0A, 0x77, 0xD0, 0xFF, + 0xE4, 0x36, 0xFB, 0x7B, 0x58, 0xB2, 0xCA, 0x41 + }, + { + 0x46, 0x6F, 0xD9, 0x15, 0xEF, 0xD9, 0x50, 0xBC, + 0x96, 0x65, 0x78, 0xCD, 0x92, 0xC6, 0x85, 0x92, + 0x9D, 0x7B, 0x51, 0xA6, 0x3D, 0xB1, 0x42, 0xC7, + 0xB9, 0xA9, 0x3D, 0x16, 0x52, 0x04, 0x95, 0x31, + 0x9B, 0x87, 0xF6, 0x58, 0xE6, 0xAF, 0xDA, 0x1B, + 0x42, 0x77, 0x3E, 0x2D, 0x49, 0xDA, 0x81, 0x45, + 0x94, 0xA5, 0x54, 0x90, 0x89, 0xEF, 0xB1, 0xF3, + 0xAB, 0x5F, 0x15, 0x90, 0xCA, 0x0A, 0x02, 0xAF + }, + { + 0xF6, 0x46, 0x11, 0x13, 0x7A, 0xD2, 0x95, 0x46, + 0x70, 0xEA, 0xEC, 0xD6, 0x26, 0xD2, 0x12, 0xCF, + 0xC5, 0xB9, 0xF6, 0xBB, 0x41, 0xAA, 0xEB, 0xB1, + 0xD7, 0x1E, 0x89, 0x79, 0x2E, 0xB1, 0x31, 0x7A, + 0xED, 0xC6, 0x38, 0x13, 0xFE, 0x63, 0xDE, 0x40, + 0x17, 0x98, 0xDF, 0x75, 0x6C, 0xA1, 0xF2, 0x20, + 0x35, 0xA0, 0xFA, 0xBD, 0x37, 0xFB, 0x11, 0x03, + 0x43, 0x7F, 0x89, 0x1E, 0xAD, 0x5E, 0x64, 0x29 + }, + { + 0x32, 0xE1, 0xF9, 0x38, 0xA2, 0x7F, 0xAA, 0xD8, + 0xAC, 0x4A, 0x13, 0xFD, 0x4F, 0x6A, 0x8B, 0xF3, + 0xDA, 0xBE, 0x4B, 0xC7, 0x2A, 0xF1, 0x1C, 0x8F, + 0x0E, 0x1A, 0x06, 0x56, 0x7E, 0xD7, 0x04, 0xB8, + 0xE7, 0x8E, 0x11, 0x40, 0xA0, 0xC7, 0x72, 0x4E, + 0x3E, 0xFB, 0x70, 0xD2, 0x38, 0x07, 0xCF, 0x38, + 0xE6, 0x27, 0xE3, 0x26, 0xAF, 0xC1, 0x64, 0xCD, + 0xED, 0x52, 0xB4, 0x41, 0x39, 0xFF, 0xB3, 0xF3 + }, + { + 0x48, 0x33, 0xAC, 0x92, 0xE3, 0x02, 0xAC, 0x2B, + 0x67, 0xB0, 0x2B, 0x88, 0x27, 0x14, 0x3B, 0xAD, + 0xA1, 0x5C, 0xED, 0x22, 0x0E, 0x1D, 0x1F, 0x5B, + 0x71, 0x12, 0x0C, 0x51, 0xEE, 0x54, 0xC1, 0x9D, + 0x30, 0x1F, 0x29, 0x60, 0xBD, 0xB5, 0xA2, 0xCE, + 0x27, 0xD4, 0x41, 0xD1, 0x4A, 0xF0, 0x80, 0xCB, + 0x01, 0x0A, 0x8A, 0x23, 0xEE, 0xFF, 0x58, 0x11, + 0xDF, 0xA4, 0x4D, 0x1D, 0x7B, 0x35, 0x8B, 0x48 + }, + { + 0x9A, 0x03, 0x88, 0xCE, 0xE1, 0xAD, 0x01, 0x46, + 0x17, 0x7C, 0x48, 0xB5, 0xA0, 0x8A, 0x2D, 0xB3, + 0xC4, 0x89, 0xE8, 0x4C, 0xE2, 0xAB, 0xA8, 0xC6, + 0x45, 0x11, 0x2A, 0x02, 0x1E, 0x41, 0x1C, 0xF8, + 0x29, 0x12, 0x7F, 0xA2, 0xF1, 0xD1, 0xAE, 0x1B, + 0xAF, 0x3A, 0x33, 0xEA, 0x53, 0x09, 0x84, 0x77, + 0xA7, 0xD1, 0x2B, 0xA7, 0x48, 0xD2, 0xAF, 0x24, + 0xD1, 0x66, 0x02, 0xE9, 0x19, 0x07, 0x76, 0x23 + }, + { + 0xE3, 0xDF, 0x00, 0x74, 0xA9, 0x37, 0x35, 0x13, + 0x0D, 0x99, 0x22, 0xD2, 0xBE, 0x91, 0x6F, 0x35, + 0x34, 0x3D, 0x98, 0x8C, 0xE5, 0x9D, 0x76, 0x97, + 0x15, 0xA9, 0x83, 0xB4, 0xBA, 0x80, 0x7C, 0xE1, + 0xEE, 0x70, 0xA3, 0x13, 0xE5, 0x92, 0x31, 0x58, + 0x4F, 0x55, 0x6E, 0xBB, 0xA1, 0xB9, 0x0B, 0x1B, + 0xB6, 0xA6, 0xC5, 0x81, 0xA4, 0xB4, 0x7C, 0x3F, + 0xF5, 0x21, 0x89, 0x65, 0x2A, 0xAB, 0x36, 0xF5 + }, + { + 0x91, 0x91, 0xCF, 0x46, 0x1B, 0x69, 0x59, 0xBE, + 0xC9, 0x3E, 0xAE, 0x7F, 0xB1, 0xC6, 0xE3, 0x70, + 0x73, 0xD1, 0xA6, 0x15, 0x27, 0xAD, 0x75, 0xD1, + 0x0B, 0x7F, 0x89, 0x49, 0xD9, 0xB8, 0xAF, 0x70, + 0xA2, 0x3A, 0xD1, 0x31, 0x2E, 0xD5, 0x1F, 0x70, + 0xF0, 0xE9, 0xDF, 0x60, 0x1D, 0xDA, 0xE2, 0x38, + 0x90, 0x6C, 0x0F, 0xE3, 0xF7, 0x66, 0xB1, 0x4F, + 0x11, 0x3B, 0x26, 0xBC, 0x85, 0x42, 0xD1, 0xD2 + }, + { + 0x2A, 0x8B, 0xAD, 0xE2, 0x72, 0xEE, 0x7A, 0xC6, + 0x43, 0xC5, 0xE3, 0x71, 0x47, 0xFA, 0xAC, 0x92, + 0xC3, 0x97, 0x0B, 0xD3, 0x86, 0x2F, 0x53, 0x1E, + 0x5D, 0xCE, 0xA5, 0xCE, 0xAC, 0xD1, 0x83, 0x74, + 0x53, 0xAA, 0x49, 0x8D, 0x78, 0x5B, 0x4D, 0x1F, + 0x89, 0xE1, 0xB2, 0xA7, 0x39, 0xCA, 0x4A, 0x38, + 0x49, 0x87, 0x30, 0x27, 0x46, 0xB4, 0xF1, 0x13, + 0x42, 0x43, 0x02, 0xC4, 0xA1, 0xE0, 0xF9, 0xDF + }, + { + 0x32, 0x3E, 0x67, 0x93, 0xC7, 0xDD, 0x9B, 0x4D, + 0x7B, 0xB7, 0xFB, 0xF2, 0x15, 0x31, 0xD3, 0x7F, + 0x72, 0x64, 0x53, 0x2C, 0x58, 0xF1, 0x22, 0x55, + 0x48, 0xD0, 0x6E, 0x69, 0x40, 0xC6, 0x3E, 0x91, + 0x27, 0x09, 0x90, 0xE7, 0xF5, 0x64, 0x32, 0x03, + 0xC9, 0x87, 0x64, 0x7E, 0x5C, 0xF6, 0x61, 0x03, + 0xE7, 0x9B, 0x71, 0x4C, 0x58, 0x1B, 0xD8, 0x77, + 0x2E, 0x19, 0xD0, 0xF0, 0x05, 0xDC, 0x86, 0x33 + }, + { + 0xF9, 0x22, 0x07, 0x6D, 0x29, 0x5D, 0x23, 0xE2, + 0x98, 0x58, 0x30, 0xAA, 0xD2, 0xF2, 0x3F, 0x65, + 0x2F, 0x7F, 0x4D, 0xB4, 0x2C, 0x11, 0x9E, 0xD2, + 0x20, 0xA5, 0x45, 0x14, 0x88, 0xA4, 0x53, 0xF5, + 0x9F, 0xA8, 0xA2, 0xDE, 0x23, 0x03, 0x00, 0x0D, + 0x6B, 0xFD, 0x8C, 0x48, 0x23, 0xA8, 0x5F, 0xAD, + 0xB4, 0xFB, 0x8E, 0x7E, 0xAC, 0x12, 0x2B, 0xF0, + 0x12, 0x47, 0xD7, 0x6F, 0x65, 0x24, 0x7D, 0x45 + }, + { + 0xDC, 0x40, 0x00, 0x95, 0x60, 0x95, 0x92, 0x91, + 0x55, 0x8E, 0xBE, 0x07, 0x20, 0x64, 0xCE, 0x67, + 0x12, 0xC9, 0x21, 0xB5, 0x40, 0x9B, 0x44, 0xE0, + 0x4F, 0x9A, 0x56, 0x5E, 0xEA, 0xDD, 0x39, 0xA7, + 0x71, 0x6E, 0x21, 0xB4, 0x6D, 0xD8, 0x61, 0x65, + 0x17, 0xA2, 0x1A, 0x0C, 0x03, 0x41, 0x9E, 0x94, + 0xDB, 0x82, 0x0A, 0x35, 0x3F, 0x15, 0x2D, 0x10, + 0x83, 0x84, 0xBE, 0x94, 0x70, 0x09, 0x3F, 0x89 + }, + { + 0x7F, 0xA4, 0xBE, 0x91, 0xCA, 0x52, 0x07, 0xFF, + 0x08, 0x7D, 0xE9, 0x2F, 0x1D, 0xB0, 0x9B, 0xF7, + 0x1A, 0x67, 0x87, 0x8B, 0xED, 0x19, 0x3A, 0x5C, + 0x2C, 0xC4, 0xE3, 0x53, 0x23, 0xB8, 0xDF, 0x99, + 0xA2, 0x6E, 0xCB, 0x98, 0x88, 0xD7, 0xB3, 0x4A, + 0x73, 0x9D, 0x64, 0x1A, 0x0E, 0xCD, 0x0A, 0x66, + 0x47, 0xA6, 0xA0, 0x64, 0x26, 0xF3, 0xCC, 0x1F, + 0xEF, 0xDF, 0x90, 0x69, 0x92, 0x2F, 0xAE, 0x4C + }, + { + 0xBA, 0xD3, 0xCD, 0x75, 0x90, 0x5D, 0x7B, 0xFD, + 0xA3, 0x32, 0x2B, 0x44, 0xA7, 0xD3, 0x58, 0x87, + 0x14, 0xD3, 0x33, 0xEE, 0x86, 0x85, 0x5A, 0x87, + 0x27, 0x47, 0xE7, 0x04, 0xF6, 0x11, 0x94, 0x84, + 0xBD, 0xB7, 0xD0, 0x77, 0xFA, 0x08, 0xED, 0xC4, + 0xA7, 0x9D, 0xE0, 0xF4, 0x3F, 0xCA, 0x8D, 0x43, + 0x6E, 0x8A, 0x10, 0x08, 0x57, 0xF5, 0x9B, 0xC7, + 0xB0, 0x55, 0xB9, 0x87, 0xF9, 0x7A, 0xC6, 0xB9 + }, + { + 0xB7, 0xDE, 0xE8, 0xE8, 0x33, 0x9D, 0xB2, 0x97, + 0xFD, 0xAA, 0x3C, 0xA5, 0xC1, 0xDC, 0x19, 0x88, + 0xD9, 0x7F, 0x5F, 0xB6, 0x20, 0x8C, 0x64, 0xDE, + 0xA9, 0x5E, 0x1C, 0x78, 0xF3, 0x37, 0xCE, 0x20, + 0xA2, 0xB4, 0xDF, 0x17, 0xA7, 0xB8, 0x23, 0x6A, + 0x90, 0xD6, 0x28, 0x67, 0x33, 0x16, 0x35, 0x72, + 0xC8, 0x67, 0xD9, 0x3D, 0xE8, 0x9E, 0xF6, 0x2F, + 0xA0, 0x5D, 0xAB, 0x70, 0x7E, 0xC3, 0xA7, 0x70 + }, + { + 0xA0, 0xF7, 0xE9, 0x3C, 0xF3, 0x25, 0x02, 0xB9, + 0xFD, 0x79, 0xEC, 0x20, 0x54, 0x62, 0x07, 0xF3, + 0x31, 0xC5, 0x29, 0x9E, 0xCE, 0xF3, 0x50, 0xD6, + 0x6E, 0xA8, 0x55, 0xC8, 0x7F, 0xBD, 0xDF, 0x18, + 0xE6, 0x91, 0xC2, 0x0D, 0x04, 0x5A, 0x30, 0x8F, + 0x83, 0xF6, 0xCB, 0x8F, 0xCA, 0x69, 0xD7, 0xE2, + 0xB3, 0x9B, 0x34, 0xD2, 0xF8, 0x77, 0x27, 0x6C, + 0x19, 0x6B, 0xF5, 0x14, 0xBA, 0xC6, 0x02, 0x70 + }, + { + 0x6F, 0x50, 0x93, 0xCF, 0xC8, 0x83, 0x00, 0xBF, + 0x68, 0x8E, 0x88, 0x4B, 0x4C, 0x5E, 0xC2, 0xC3, + 0x1A, 0x8C, 0xC2, 0x8D, 0x63, 0x31, 0xAD, 0x7C, + 0xA7, 0x1D, 0x97, 0x60, 0x21, 0x64, 0x82, 0x05, + 0x28, 0x15, 0xD4, 0x4F, 0xC6, 0x9E, 0x18, 0xA8, + 0xDC, 0x8B, 0xD7, 0x1B, 0x31, 0xF2, 0xB5, 0x89, + 0xA7, 0xC0, 0x78, 0x0B, 0x61, 0x99, 0x38, 0x5F, + 0x8D, 0xAE, 0x6C, 0x9B, 0x79, 0x74, 0xC4, 0xCB + }, + { + 0x3C, 0xFF, 0x46, 0xAC, 0x35, 0x46, 0xF6, 0x5A, + 0xD7, 0xA7, 0x20, 0x87, 0x1A, 0xFA, 0x20, 0xA9, + 0x21, 0x6D, 0xDA, 0x5C, 0x45, 0x18, 0x81, 0x56, + 0xA5, 0xBB, 0xED, 0xF2, 0x15, 0x46, 0xD4, 0xBB, + 0x39, 0x40, 0xB2, 0x1A, 0x41, 0xA3, 0x94, 0x03, + 0xE3, 0xCF, 0xD5, 0xE7, 0xA0, 0xE7, 0x90, 0x4D, + 0xA9, 0x5F, 0x4D, 0x8E, 0x0C, 0x5B, 0xF5, 0xB7, + 0x0E, 0xB0, 0x29, 0x55, 0x6E, 0xFD, 0x49, 0x7E + }, + { + 0xAF, 0x66, 0x8A, 0x80, 0x5E, 0x6D, 0x70, 0x4B, + 0x1E, 0x58, 0x1F, 0x1E, 0x8E, 0x3C, 0x00, 0xCF, + 0x4C, 0xF3, 0xE5, 0x46, 0x14, 0x7C, 0x40, 0x6D, + 0x17, 0xCA, 0x97, 0x4D, 0x19, 0xA0, 0x14, 0xC7, + 0x8B, 0x44, 0xE7, 0x2D, 0xDE, 0xEB, 0x65, 0x26, + 0x07, 0xE8, 0x6D, 0x69, 0x02, 0x59, 0xDC, 0xAB, + 0x0D, 0xDA, 0x81, 0xC7, 0x7C, 0x7E, 0xE2, 0x72, + 0x1E, 0x82, 0xBB, 0xB1, 0x39, 0x43, 0x07, 0x1D + }, + { + 0x79, 0xDD, 0xEB, 0x5C, 0x54, 0xDE, 0xD1, 0xE4, + 0x48, 0x40, 0x71, 0xC4, 0x6B, 0xB4, 0x28, 0x02, + 0xD2, 0x3B, 0x3A, 0x08, 0xC1, 0x23, 0x11, 0xBE, + 0x36, 0x3C, 0x7C, 0x7A, 0x02, 0x5A, 0x17, 0x64, + 0xC8, 0xD8, 0x50, 0x69, 0xFD, 0xA8, 0xD5, 0x17, + 0x77, 0x7D, 0x8D, 0xD8, 0x09, 0xE3, 0xD4, 0xA9, + 0x56, 0x04, 0x1A, 0x70, 0x79, 0xF9, 0x16, 0x7B, + 0x0F, 0xE9, 0x71, 0x2E, 0x5F, 0x12, 0x29, 0xF5 + }, + { + 0x99, 0x8E, 0x82, 0xF4, 0x26, 0x3D, 0x53, 0xAE, + 0xDA, 0xC9, 0x39, 0xEB, 0xB6, 0xEB, 0x8B, 0x19, + 0x69, 0x74, 0x6C, 0xB8, 0x15, 0xBD, 0x72, 0x1F, + 0x17, 0xA4, 0x8B, 0xEE, 0x9E, 0xCF, 0xF2, 0xFE, + 0x59, 0x8C, 0x53, 0x9C, 0x41, 0x9A, 0x60, 0xE0, + 0xD5, 0xA0, 0x4F, 0x1C, 0xB5, 0x23, 0xA2, 0xFD, + 0x05, 0x38, 0xBB, 0x17, 0x8E, 0x44, 0x75, 0x8D, + 0x31, 0x59, 0xAB, 0x9E, 0x02, 0x84, 0x01, 0xA3 + }, + { + 0x33, 0x96, 0xCF, 0xD5, 0xCD, 0xE1, 0x4A, 0xEC, + 0x1A, 0xAE, 0xD3, 0xE1, 0x22, 0x52, 0xCF, 0xD6, + 0xE3, 0x42, 0xED, 0x25, 0x5E, 0x8E, 0x9E, 0x1B, + 0xE1, 0x0F, 0x1F, 0x27, 0x38, 0x77, 0xF3, 0x63, + 0x33, 0x81, 0xE3, 0xC9, 0x61, 0xE6, 0x7E, 0xC4, + 0x1E, 0x8F, 0x9E, 0x16, 0x11, 0x0F, 0xC0, 0x3D, + 0xDE, 0x88, 0xBF, 0xC0, 0x96, 0xFC, 0x15, 0x14, + 0x46, 0x1D, 0x70, 0xD0, 0xBE, 0xCE, 0x0A, 0xF6 + }, + { + 0x77, 0x7D, 0x9D, 0xC5, 0x5A, 0x2F, 0x57, 0xA4, + 0x6E, 0xA0, 0x6A, 0x2F, 0x4C, 0xB9, 0x76, 0x0D, + 0x00, 0xD7, 0xA8, 0x62, 0xD0, 0xA2, 0xAA, 0x19, + 0x46, 0x7B, 0x57, 0x0F, 0x7C, 0x7D, 0x5E, 0xA7, + 0x62, 0x9A, 0x95, 0xEB, 0x20, 0x0E, 0x1F, 0x9D, + 0xB0, 0x66, 0x10, 0xCF, 0x8E, 0x30, 0xD5, 0xE6, + 0xAD, 0x0A, 0x7B, 0x63, 0x29, 0x77, 0xFC, 0x21, + 0xBB, 0x17, 0x89, 0x67, 0xF3, 0xB0, 0xE0, 0x9B + }, + { + 0x32, 0xEE, 0x35, 0x7F, 0xC9, 0x16, 0x36, 0xA8, + 0x55, 0xBA, 0x01, 0xA0, 0xB8, 0xDA, 0x6F, 0x35, + 0x53, 0xB1, 0xD5, 0x20, 0xAD, 0xCF, 0xE8, 0xFE, + 0x9D, 0xEB, 0xCC, 0xB2, 0x6C, 0x5C, 0x4C, 0xE8, + 0x50, 0x5B, 0xB1, 0xEF, 0xB5, 0xED, 0x5B, 0xAA, + 0x4C, 0x52, 0x45, 0xB5, 0x0D, 0x74, 0x46, 0x3F, + 0x07, 0x67, 0xB2, 0xC7, 0x83, 0xC4, 0x7A, 0x93, + 0xB0, 0xFD, 0xA6, 0x68, 0x95, 0x69, 0x3C, 0xE6 + }, + { + 0x34, 0x0C, 0x0A, 0x7C, 0xE4, 0x96, 0xFE, 0xBD, + 0xA1, 0x3F, 0xA2, 0x40, 0x7A, 0x21, 0xDC, 0x19, + 0x83, 0x9B, 0xED, 0xAE, 0x1A, 0x08, 0x6A, 0xD0, + 0xFE, 0xD3, 0x91, 0x7D, 0xF9, 0xBF, 0x40, 0x94, + 0x4A, 0x78, 0x7F, 0x64, 0x1E, 0x90, 0xDD, 0xBA, + 0xE0, 0x3A, 0x93, 0x37, 0x72, 0x3E, 0x51, 0x66, + 0x8F, 0xB8, 0x93, 0x77, 0x2C, 0x0F, 0xBD, 0xB3, + 0xEB, 0x7E, 0xF7, 0x90, 0xDF, 0xCB, 0xB9, 0xAB + }, + { + 0xD8, 0x6A, 0x5B, 0xAA, 0x33, 0x65, 0xAB, 0xD8, + 0xF4, 0x42, 0xCD, 0x6E, 0xBB, 0x93, 0x11, 0x38, + 0x19, 0xF0, 0xB4, 0x60, 0x61, 0xE1, 0x34, 0x04, + 0xEF, 0xAA, 0x1A, 0x58, 0xE1, 0xFF, 0x27, 0x2A, + 0xD4, 0xBF, 0xD3, 0x08, 0x15, 0xAD, 0xD8, 0x8A, + 0xD9, 0x8F, 0xCE, 0x9A, 0xF0, 0x18, 0x37, 0x4C, + 0xA6, 0x0D, 0x89, 0x79, 0x0F, 0x71, 0xA6, 0x07, + 0x5F, 0x3D, 0x68, 0xD3, 0x20, 0x21, 0xA9, 0xEB + }, + { + 0xA6, 0x7E, 0x6E, 0xC6, 0x57, 0xC9, 0x5E, 0xAB, + 0x3C, 0x3C, 0x32, 0xE4, 0x1F, 0xBF, 0x39, 0xCF, + 0x20, 0x33, 0xAB, 0x4B, 0xE2, 0xE2, 0xB8, 0x21, + 0x10, 0x4A, 0xDB, 0xE6, 0x9D, 0x16, 0xE9, 0x48, + 0xDC, 0xE4, 0xC4, 0xC6, 0xA3, 0xCF, 0x22, 0x76, + 0x90, 0x1F, 0x7D, 0x4F, 0xFD, 0x69, 0x65, 0x46, + 0x49, 0x88, 0x2C, 0x01, 0x4D, 0x2C, 0x10, 0xA1, + 0x30, 0x2B, 0x79, 0xC6, 0x15, 0x69, 0xCD, 0x36 + }, + { + 0x55, 0xCE, 0x19, 0x2A, 0xE4, 0xB3, 0xEA, 0xF8, + 0x55, 0x59, 0x0E, 0x2D, 0x44, 0xE6, 0x25, 0xD9, + 0xBA, 0x14, 0x6E, 0xB7, 0x50, 0x48, 0xE6, 0xB5, + 0x6E, 0x02, 0x50, 0x31, 0xEF, 0xBA, 0x0B, 0xDA, + 0x8A, 0xAA, 0xFA, 0x04, 0x70, 0xB7, 0xAC, 0x3D, + 0x40, 0x6E, 0x5A, 0xBA, 0x3E, 0x83, 0x2F, 0x27, + 0xA5, 0x07, 0x24, 0x6D, 0x1B, 0x5F, 0x33, 0xDE, + 0xA1, 0xF7, 0x24, 0xE2, 0xB8, 0x1B, 0x0C, 0x98 + }, + { + 0xB3, 0xA2, 0x0C, 0x1F, 0xB0, 0xB4, 0xF0, 0xD3, + 0x77, 0x26, 0xC2, 0x3B, 0x58, 0x77, 0xDD, 0x8E, + 0x72, 0xF6, 0x98, 0x86, 0xE0, 0x9A, 0x8C, 0x68, + 0xCF, 0xC3, 0x01, 0xD2, 0xA3, 0xF2, 0xF9, 0x5C, + 0xEF, 0xCF, 0xAB, 0xB8, 0x88, 0x99, 0x03, 0xC7, + 0x32, 0xF4, 0xE8, 0x14, 0x32, 0xD3, 0xF6, 0x78, + 0xCC, 0xDF, 0xC3, 0x98, 0xAC, 0xD8, 0xA2, 0xF0, + 0x66, 0x41, 0x10, 0x04, 0x50, 0xD8, 0x9F, 0x32 + }, + { + 0xF7, 0x27, 0x2D, 0x93, 0xC7, 0x01, 0x2D, 0x38, + 0xB2, 0x7F, 0x0C, 0x9A, 0xE2, 0x01, 0x79, 0x58, + 0xBB, 0xA6, 0x66, 0xA9, 0xDE, 0x1E, 0x88, 0x12, + 0xE9, 0x74, 0x37, 0xAE, 0xB2, 0xE0, 0x3C, 0x99, + 0x94, 0x38, 0xF0, 0xBE, 0x33, 0x3D, 0x09, 0xAD, + 0xDB, 0xCF, 0xAA, 0xC7, 0xAA, 0x73, 0xF7, 0xB6, + 0xCC, 0xEC, 0x67, 0xDC, 0x07, 0x79, 0x98, 0xDE, + 0xDB, 0x8C, 0x13, 0x32, 0xBA, 0xC0, 0xFB, 0xA8 + }, + { + 0x1F, 0xE7, 0xB3, 0xDE, 0x34, 0xC0, 0x47, 0x9C, + 0xA8, 0x40, 0x5F, 0x3C, 0xBC, 0xD2, 0xDB, 0x64, + 0xBB, 0x18, 0xDB, 0xB2, 0x91, 0xA5, 0xFE, 0xAA, + 0x16, 0xC5, 0x22, 0x8C, 0x93, 0xEE, 0x21, 0xC7, + 0x11, 0xD6, 0x8A, 0x01, 0x0C, 0x2A, 0xE8, 0x80, + 0x05, 0xEB, 0xAC, 0x95, 0x9E, 0x3A, 0x32, 0x24, + 0x52, 0xF8, 0x62, 0xDD, 0xE9, 0x4B, 0xB9, 0x41, + 0x81, 0x3E, 0x52, 0x4D, 0x23, 0x47, 0xFE, 0xEE + }, + { + 0x4E, 0xE1, 0xD3, 0x88, 0x05, 0xC3, 0x22, 0x84, + 0xEC, 0xEB, 0xE9, 0x2E, 0x3D, 0xF6, 0xCD, 0x98, + 0xC7, 0xD6, 0x68, 0x0E, 0xAB, 0x0D, 0x68, 0x66, + 0x4F, 0x96, 0x70, 0x6C, 0x45, 0x63, 0x3B, 0x1E, + 0x26, 0x82, 0x22, 0xAA, 0x5A, 0x52, 0x79, 0xEF, + 0x01, 0xFC, 0x28, 0x54, 0x32, 0xAB, 0xEE, 0xD7, + 0x4B, 0xA3, 0xDF, 0x18, 0x9F, 0x50, 0xA9, 0x89, + 0xD5, 0x8E, 0x71, 0x30, 0x62, 0x2D, 0xAA, 0x59 + }, + { + 0x0E, 0x14, 0x05, 0x87, 0x1C, 0x87, 0xA5, 0xEA, + 0x40, 0x83, 0x42, 0xF3, 0x9D, 0x34, 0x94, 0xF9, + 0x39, 0xF7, 0x3C, 0x22, 0x60, 0xC2, 0xA4, 0x3A, + 0x5C, 0x9F, 0x1B, 0x57, 0x33, 0x0C, 0xCA, 0x40, + 0x93, 0xFC, 0x1F, 0x42, 0xF9, 0x6D, 0x83, 0x00, + 0x56, 0x77, 0x03, 0x7D, 0xB5, 0x1A, 0xEF, 0x26, + 0xF0, 0x54, 0x38, 0x05, 0x7A, 0xE7, 0x9E, 0xD1, + 0x44, 0x64, 0xFD, 0x8E, 0x57, 0xD1, 0x55, 0x86 + }, + { + 0x17, 0xC5, 0xCA, 0xB4, 0x09, 0x10, 0x73, 0x62, + 0x1B, 0x5C, 0x24, 0xC3, 0x36, 0x31, 0x6D, 0x0C, + 0xF6, 0x49, 0xBA, 0x1E, 0xFF, 0xEB, 0xFC, 0x87, + 0xE0, 0x43, 0x9C, 0xDF, 0x57, 0x88, 0x87, 0xB2, + 0x21, 0x65, 0x6D, 0x33, 0x9A, 0x6F, 0xD1, 0x98, + 0xAB, 0xAE, 0xE6, 0x7E, 0xA1, 0x88, 0xDD, 0x66, + 0x56, 0x78, 0x23, 0xFC, 0x22, 0x0C, 0x52, 0xB5, + 0x74, 0x90, 0x25, 0x14, 0x69, 0xD2, 0x5D, 0x8C + }, + { + 0x57, 0xDC, 0x27, 0x97, 0xD1, 0x42, 0x68, 0x1C, + 0x94, 0xFE, 0x48, 0x86, 0x26, 0x98, 0x6E, 0xD4, + 0xB2, 0x67, 0x03, 0xCB, 0xF6, 0xBF, 0xE5, 0x93, + 0x91, 0x64, 0x36, 0x57, 0x06, 0x5B, 0x2D, 0x46, + 0xE4, 0xB1, 0xDD, 0xB3, 0xAA, 0x83, 0x2C, 0x9B, + 0xD4, 0x49, 0x75, 0x5A, 0xC8, 0xB1, 0xBF, 0x93, + 0x68, 0x97, 0xFB, 0xC6, 0xAD, 0xE3, 0x78, 0xF2, + 0xBD, 0x64, 0x93, 0xE4, 0x86, 0xF4, 0x20, 0x29 + }, + { + 0x44, 0x12, 0xDD, 0x6B, 0xED, 0x6D, 0xB2, 0xA8, + 0x03, 0xC2, 0xE0, 0xDF, 0x8F, 0x58, 0x29, 0xE7, + 0xA4, 0xB0, 0x41, 0x78, 0x89, 0x51, 0x0D, 0xF7, + 0xDF, 0xEE, 0x49, 0x57, 0x4A, 0x71, 0xEC, 0x0D, + 0x9E, 0x0D, 0x46, 0x06, 0x50, 0x17, 0xC7, 0x2D, + 0xD9, 0x74, 0x39, 0x33, 0xCA, 0x83, 0x9A, 0x76, + 0x8D, 0xD1, 0x5A, 0xB0, 0xB7, 0xC1, 0x4C, 0x62, + 0x6A, 0x35, 0x41, 0x09, 0x69, 0x01, 0x96, 0xAE + }, + { + 0xD0, 0xEB, 0xC7, 0x71, 0x03, 0x1B, 0x7C, 0x16, + 0x00, 0x21, 0xC9, 0xB6, 0xFB, 0xB2, 0xB6, 0x70, + 0xE3, 0xB4, 0x02, 0x70, 0x02, 0x69, 0x07, 0xA3, + 0x91, 0x63, 0xDB, 0x18, 0x73, 0xEC, 0xC3, 0xB8, + 0x00, 0x11, 0x1D, 0xD7, 0xBF, 0x13, 0x8F, 0x83, + 0xA6, 0x10, 0xDC, 0x04, 0x6D, 0xA2, 0x68, 0xB7, + 0x2B, 0x8C, 0x90, 0x86, 0x92, 0x23, 0x77, 0xDB, + 0xED, 0x73, 0x94, 0x82, 0x43, 0xCA, 0x1E, 0x14 + }, + { + 0x10, 0xC4, 0xBA, 0x31, 0x55, 0x91, 0x69, 0x8D, + 0xFB, 0x91, 0xA5, 0x73, 0x37, 0x63, 0x18, 0x84, + 0xB4, 0x73, 0x8D, 0x9F, 0x59, 0x80, 0x78, 0x51, + 0xA6, 0x79, 0x84, 0x0C, 0xC2, 0x87, 0xAC, 0xE3, + 0x01, 0x1C, 0xCD, 0xC8, 0xF4, 0xA4, 0x85, 0xBB, + 0x19, 0x73, 0x40, 0x4E, 0xF9, 0xEE, 0x9B, 0x9C, + 0xF1, 0xEA, 0xDB, 0xC5, 0x40, 0x74, 0xC6, 0xD1, + 0x13, 0xDE, 0x8F, 0xC9, 0x1D, 0x07, 0x97, 0xEB + }, + { + 0x14, 0x64, 0x34, 0x7B, 0xE3, 0x2C, 0x79, 0x59, + 0x17, 0x2B, 0x74, 0x72, 0xD1, 0x1F, 0xE0, 0x78, + 0x44, 0xA5, 0x2E, 0x2D, 0x3B, 0x2D, 0x05, 0x8C, + 0xC6, 0xBC, 0xC0, 0xA8, 0xA2, 0x75, 0xD6, 0xB8, + 0x2B, 0x2D, 0x62, 0x63, 0x75, 0x5E, 0xAF, 0x2A, + 0x65, 0x88, 0xB6, 0xA1, 0xEB, 0x79, 0x9A, 0xF8, + 0x3A, 0x4C, 0xE7, 0x53, 0xF8, 0xC7, 0x5A, 0x22, + 0x84, 0xD0, 0x28, 0x5B, 0xAB, 0x5F, 0x7C, 0x1C + }, + { + 0xF4, 0x09, 0x23, 0x1E, 0xD1, 0x87, 0xF5, 0xC4, + 0xE8, 0x33, 0xFA, 0x9E, 0x30, 0x42, 0xAC, 0xA6, + 0xC8, 0x58, 0xB0, 0x8B, 0x49, 0x6B, 0x25, 0x31, + 0xF8, 0x4F, 0xD5, 0xCE, 0xA9, 0x3E, 0xCD, 0x06, + 0xDA, 0xFE, 0x0A, 0x10, 0xC3, 0xFF, 0x23, 0x76, + 0xC7, 0x4D, 0xC8, 0x0D, 0xA0, 0x7D, 0xA0, 0x18, + 0x64, 0xFB, 0xF2, 0x68, 0x59, 0x60, 0xB5, 0x40, + 0xB3, 0xA2, 0xE9, 0x42, 0xCB, 0x8D, 0x90, 0x9F + }, + { + 0x39, 0x51, 0x32, 0xC5, 0x80, 0xC3, 0x55, 0xB5, + 0xB0, 0xE2, 0x35, 0x33, 0x6C, 0x8D, 0xC1, 0x08, + 0x5E, 0x59, 0x59, 0x64, 0x04, 0x3D, 0x38, 0x9E, + 0x08, 0x1E, 0xFE, 0x48, 0x5B, 0xA4, 0xC6, 0x37, + 0x72, 0xDB, 0x8D, 0x7E, 0x0F, 0x18, 0x6C, 0x50, + 0x98, 0x2E, 0x12, 0x23, 0xEA, 0x78, 0x5A, 0xDC, + 0x74, 0x0B, 0x0C, 0xF2, 0x18, 0x70, 0x74, 0x58, + 0xB8, 0xB8, 0x03, 0x40, 0x42, 0xF9, 0x23, 0xC2 + }, + { + 0xF9, 0x2A, 0xBA, 0xCA, 0x21, 0x32, 0x29, 0x66, + 0x06, 0x49, 0xEF, 0x2D, 0x8F, 0x88, 0x11, 0x5B, + 0x5B, 0xED, 0x8A, 0xB5, 0xB9, 0xBC, 0xA9, 0xA1, + 0xB4, 0xC5, 0x24, 0x57, 0x03, 0x53, 0x10, 0xC4, + 0x1A, 0x6B, 0xEA, 0x2B, 0x23, 0xB7, 0x91, 0x8B, + 0x5B, 0x8B, 0xF3, 0x8B, 0x52, 0xEA, 0xC6, 0xFF, + 0x3B, 0x62, 0x13, 0xA5, 0x22, 0xF3, 0x81, 0xBE, + 0x7F, 0xF0, 0x90, 0x6D, 0xBA, 0x7B, 0xD0, 0x0C + }, + { + 0xCB, 0xAD, 0xE7, 0xAD, 0x3B, 0x5D, 0xEE, 0x0F, + 0xF1, 0xA4, 0x6B, 0x08, 0x2C, 0xF4, 0xE1, 0xE1, + 0xDC, 0x21, 0x62, 0x0D, 0xD2, 0xCC, 0x0E, 0xDC, + 0x2C, 0x70, 0x7A, 0x21, 0x62, 0xD2, 0x14, 0x99, + 0x69, 0xAB, 0xBB, 0x29, 0xC5, 0x72, 0x0B, 0x04, + 0xBD, 0x15, 0x68, 0xA9, 0x55, 0x61, 0x95, 0xE6, + 0x7F, 0x24, 0x32, 0x2D, 0xD9, 0xAA, 0x4E, 0x83, + 0x65, 0x19, 0x1A, 0xA5, 0xB6, 0xC4, 0x45, 0x79 + }, + { + 0xF5, 0x1B, 0x4A, 0xE4, 0xD4, 0xC5, 0x4A, 0x29, + 0xCF, 0x71, 0x35, 0xA8, 0xFE, 0x1E, 0xAB, 0xD5, + 0xE1, 0xBC, 0xBF, 0x82, 0x08, 0x96, 0x96, 0x7D, + 0xC4, 0x1E, 0x38, 0x49, 0xDA, 0xC2, 0x25, 0x07, + 0x69, 0x42, 0x10, 0xCA, 0x11, 0xC4, 0xEB, 0xF1, + 0xC2, 0x9A, 0x8D, 0x4F, 0x71, 0xB3, 0x0F, 0x76, + 0xC9, 0xB6, 0x01, 0x0A, 0xD9, 0x5B, 0xDF, 0xB0, + 0xDE, 0x83, 0x79, 0x25, 0xF0, 0x61, 0x25, 0x97 + }, + { + 0xCE, 0x38, 0x72, 0x11, 0x5D, 0x83, 0x3B, 0x34, + 0x56, 0xCA, 0x94, 0x2E, 0x6E, 0x38, 0x5F, 0x28, + 0xA9, 0x03, 0xBE, 0xAB, 0xFB, 0x75, 0x3F, 0x8A, + 0xFC, 0xCC, 0x12, 0xF2, 0x58, 0x2C, 0xE1, 0xF3, + 0x62, 0x12, 0xBD, 0x05, 0xE0, 0x5A, 0x46, 0xFC, + 0x88, 0xD3, 0x19, 0x50, 0xB4, 0x91, 0x1A, 0xE5, + 0xDC, 0xD8, 0xFF, 0x7A, 0x0B, 0x50, 0x47, 0x4C, + 0xB4, 0x88, 0xCC, 0xF2, 0xA8, 0x9C, 0xD0, 0xEB + }, + { + 0x9B, 0xB7, 0x4C, 0xBD, 0x47, 0xA6, 0x24, 0xCB, + 0xEA, 0xFC, 0xC1, 0x6D, 0x46, 0x29, 0x47, 0xBB, + 0xEA, 0x13, 0x70, 0xB8, 0x5C, 0x96, 0x1A, 0x40, + 0x7D, 0xF9, 0x86, 0x3E, 0x54, 0xE6, 0xD9, 0xE6, + 0xA8, 0xD2, 0xEF, 0x0C, 0x64, 0x97, 0x20, 0x5E, + 0x5E, 0xB7, 0xC3, 0xE5, 0x9E, 0x69, 0x8D, 0x99, + 0x24, 0x63, 0xCA, 0x9D, 0xD4, 0xCF, 0x28, 0xCF, + 0x9A, 0x2D, 0x4E, 0x30, 0xC1, 0x33, 0xE8, 0x55 + }, + { + 0x72, 0x96, 0x33, 0x82, 0x0B, 0xF0, 0x13, 0xD9, + 0xD2, 0xBD, 0x37, 0x3C, 0xCA, 0xC7, 0xBC, 0x9F, + 0x37, 0x16, 0xF6, 0x9E, 0x16, 0xA4, 0x4E, 0x94, + 0x9C, 0x7A, 0x9A, 0x93, 0xDC, 0xA1, 0x26, 0xBB, + 0x1A, 0xA5, 0x4E, 0x5E, 0x70, 0x40, 0x70, 0x7F, + 0x02, 0x87, 0x6A, 0xFD, 0x02, 0x0A, 0xF4, 0x72, + 0x63, 0x9D, 0x49, 0xF5, 0x42, 0x0D, 0x29, 0x4C, + 0x3A, 0xA3, 0x1D, 0x06, 0x7E, 0x3E, 0x85, 0x75 + }, + { + 0x06, 0x86, 0x1D, 0xB3, 0x07, 0xC6, 0x78, 0x08, + 0x6E, 0x8B, 0x2A, 0xEC, 0xDF, 0x18, 0x29, 0xD2, + 0x88, 0x3D, 0x28, 0xB7, 0x31, 0xAB, 0xD0, 0xF1, + 0xE7, 0x2F, 0x1C, 0xED, 0x6C, 0x7A, 0xD4, 0x17, + 0x2E, 0xCA, 0x63, 0x22, 0xA8, 0x3F, 0xB6, 0xA6, + 0x5A, 0xFA, 0x37, 0xE9, 0x4A, 0x3E, 0x2B, 0xA2, + 0x05, 0xB8, 0x7B, 0xF3, 0x82, 0xD9, 0x15, 0x88, + 0x49, 0x7A, 0x46, 0x50, 0x88, 0x3B, 0xD8, 0x75 + }, + { + 0x35, 0x6E, 0xCE, 0xAF, 0x17, 0x02, 0xB3, 0x70, + 0xF4, 0xAA, 0xB8, 0xEA, 0x82, 0x84, 0x86, 0xF3, + 0x30, 0x13, 0xF7, 0x44, 0xB3, 0x9E, 0x7E, 0xA2, + 0x6C, 0x69, 0x18, 0xD6, 0x0E, 0x1A, 0xBC, 0xF4, + 0x4F, 0xB1, 0x6E, 0xDC, 0xA7, 0x72, 0x0A, 0xCF, + 0xC6, 0xA7, 0x01, 0xBF, 0x1E, 0x2C, 0x35, 0xDD, + 0xBD, 0x69, 0x5A, 0x8D, 0x40, 0x8E, 0x8C, 0x96, + 0x32, 0xE8, 0xCD, 0x27, 0x23, 0x0C, 0xAD, 0x8D + }, + { + 0x48, 0x9A, 0x39, 0xD0, 0xFC, 0x3C, 0xDE, 0xAF, + 0x42, 0x89, 0x2E, 0xD8, 0x03, 0x85, 0xC1, 0x1C, + 0xE2, 0x93, 0xC9, 0x32, 0x21, 0x5B, 0xB2, 0x31, + 0x88, 0x69, 0x2A, 0x86, 0xE6, 0x1B, 0xCA, 0xD9, + 0x2C, 0x2A, 0x1D, 0x11, 0x42, 0x60, 0x1B, 0x1B, + 0xDF, 0x09, 0x82, 0xD1, 0xCD, 0x1E, 0x05, 0xC0, + 0x52, 0xDE, 0x81, 0x9E, 0x64, 0xF2, 0x47, 0xDB, + 0x35, 0x91, 0x5D, 0xD1, 0xDB, 0x79, 0xA3, 0xB5 + }, + { + 0xC0, 0x2F, 0x46, 0x4B, 0x4D, 0xD1, 0x81, 0x17, + 0xE3, 0x0A, 0x8D, 0xB8, 0xEF, 0x1D, 0xA0, 0x67, + 0x13, 0x4B, 0x60, 0x4E, 0xFA, 0x19, 0x51, 0x76, + 0x7E, 0xE6, 0x32, 0xDC, 0x02, 0x4D, 0x64, 0xC0, + 0x0F, 0x24, 0x49, 0xF0, 0x42, 0xDB, 0x3A, 0xEA, + 0x01, 0x74, 0xEB, 0xCD, 0xBB, 0x4F, 0xF5, 0x9D, + 0xAE, 0x75, 0x4F, 0x72, 0x39, 0x46, 0xF1, 0xB9, + 0x0A, 0x77, 0xFD, 0x95, 0x23, 0x69, 0x0B, 0x7B + }, + { + 0xFB, 0x31, 0xE6, 0xDD, 0xB8, 0x6D, 0xBF, 0xF3, + 0x72, 0x64, 0x6D, 0x1E, 0x3A, 0x3F, 0x31, 0xDD, + 0x61, 0x15, 0x9F, 0xC3, 0x93, 0x65, 0x8C, 0x2E, + 0xE9, 0x57, 0x10, 0x3B, 0xF2, 0x11, 0x6B, 0xDE, + 0xF8, 0x2C, 0x33, 0xE8, 0x69, 0xF3, 0xC8, 0x3A, + 0xC3, 0xC2, 0xF6, 0x38, 0x0C, 0xF6, 0x92, 0xF7, + 0xB1, 0xDC, 0xBA, 0xE0, 0xBB, 0x22, 0x7A, 0xD3, + 0x47, 0xE7, 0x54, 0x13, 0x74, 0x66, 0xC6, 0x9F + }, + { + 0x00, 0x60, 0x62, 0xAB, 0xE1, 0x6C, 0x2F, 0xE7, + 0x9A, 0xF8, 0x80, 0x85, 0xE0, 0xB5, 0x82, 0xB1, + 0x06, 0xE7, 0xF7, 0x9F, 0x01, 0xA4, 0x39, 0x46, + 0xC7, 0x8B, 0x19, 0xF9, 0xBD, 0xD7, 0x25, 0x99, + 0x76, 0x36, 0xA3, 0x32, 0xEB, 0x9A, 0x3A, 0xAA, + 0x6D, 0xE0, 0xD4, 0xA8, 0xE9, 0xE2, 0x8E, 0x8C, + 0x77, 0x87, 0x74, 0x22, 0x4C, 0x66, 0x5B, 0xF7, + 0xBC, 0x36, 0x44, 0xFC, 0xE4, 0x11, 0x22, 0x8C + }, + { + 0xD4, 0x4A, 0x6D, 0xB3, 0xDE, 0x9F, 0xD4, 0xE4, + 0xA7, 0xEF, 0x15, 0x5A, 0x01, 0xBC, 0xCB, 0x91, + 0xC1, 0xBC, 0xF1, 0xCB, 0x53, 0x22, 0x56, 0x89, + 0xA7, 0x7A, 0x0D, 0x23, 0xB4, 0xD3, 0x9A, 0x89, + 0xA1, 0x89, 0xF2, 0x89, 0x80, 0xF9, 0x1C, 0x56, + 0xEA, 0xC5, 0x87, 0x9E, 0xAE, 0x93, 0x3C, 0xED, + 0x7F, 0x26, 0x7E, 0x2F, 0x70, 0x40, 0xEB, 0x38, + 0x0F, 0xDB, 0xBF, 0x34, 0xA6, 0xB7, 0xB6, 0x15 + }, + { + 0x5A, 0xFB, 0xFE, 0xA1, 0xDE, 0xDA, 0x5A, 0xEA, + 0xB9, 0x2E, 0x4D, 0x0C, 0x31, 0xD1, 0x6A, 0x9A, + 0x86, 0xBF, 0x7C, 0x75, 0x23, 0x27, 0x4A, 0x05, + 0xC5, 0x05, 0x29, 0xF5, 0xC1, 0x39, 0xDB, 0x10, + 0x93, 0x3A, 0x52, 0xC6, 0x22, 0x9C, 0xD3, 0x11, + 0x08, 0xF0, 0x83, 0xFB, 0x0C, 0x85, 0xCF, 0x52, + 0x83, 0x1B, 0x5A, 0x05, 0xF2, 0x55, 0x0A, 0x77, + 0xB5, 0x70, 0x3C, 0xC6, 0x68, 0x91, 0x2D, 0xBC + }, + { + 0xD1, 0x7F, 0xCA, 0xD4, 0xE0, 0xD8, 0xBD, 0xE2, + 0xED, 0xFD, 0xA1, 0x68, 0xBA, 0x47, 0x10, 0x4B, + 0xBC, 0xA4, 0xD2, 0x6D, 0xA2, 0xD3, 0x1A, 0x07, + 0x0B, 0x0F, 0xBA, 0x0B, 0x26, 0xEE, 0xDD, 0x95, + 0xEE, 0xC1, 0xFC, 0x34, 0xD7, 0x6C, 0xD4, 0xA1, + 0xCB, 0x15, 0xF2, 0x62, 0x16, 0x88, 0xA9, 0xCC, + 0x0E, 0x96, 0x35, 0x8D, 0xE9, 0x93, 0x22, 0x2B, + 0xB3, 0xE3, 0xCD, 0x0B, 0xFD, 0xCB, 0x74, 0x6C + }, + { + 0xBD, 0x6A, 0x59, 0x21, 0x63, 0x37, 0xB4, 0x5D, + 0x6B, 0x71, 0xAE, 0xAC, 0x01, 0x36, 0x6B, 0xFE, + 0x96, 0x60, 0xE0, 0xFB, 0xC2, 0x95, 0x9A, 0xDB, + 0xB6, 0x8D, 0x52, 0x6C, 0x43, 0xD4, 0x8F, 0xFF, + 0xFE, 0x2F, 0xFC, 0x43, 0x05, 0x88, 0xE7, 0x8E, + 0x66, 0x54, 0x6A, 0x3C, 0x70, 0x9B, 0x0A, 0xCE, + 0xA1, 0x7C, 0xBC, 0x5A, 0x21, 0x8C, 0x53, 0xCD, + 0x47, 0xAA, 0x48, 0x71, 0xC1, 0xDD, 0x98, 0x4A + }, + { + 0x83, 0xEA, 0x5A, 0xE1, 0x89, 0x11, 0x45, 0xC4, + 0x1A, 0x7C, 0x6C, 0x87, 0xFE, 0x92, 0x24, 0x87, + 0xF5, 0xD2, 0x82, 0x93, 0x35, 0x69, 0xB7, 0xAE, + 0x0E, 0x34, 0x56, 0x53, 0x38, 0x1E, 0xDE, 0x6D, + 0x4B, 0x16, 0xE1, 0x44, 0xD1, 0xC3, 0xE8, 0xF0, + 0x60, 0x5D, 0xAA, 0x0D, 0xB5, 0x96, 0x5A, 0x7B, + 0x79, 0xD9, 0x1A, 0x8A, 0xFE, 0x11, 0xF1, 0xE0, + 0xBC, 0x54, 0x9A, 0xC0, 0x74, 0xA0, 0x1A, 0xB7 + }, + { + 0x37, 0x50, 0x50, 0xCF, 0x2E, 0x43, 0x0D, 0x0E, + 0x29, 0x87, 0x58, 0x35, 0x20, 0x8E, 0x89, 0x06, + 0xD7, 0x05, 0x2E, 0x47, 0x29, 0x2C, 0x5A, 0x38, + 0xA6, 0x30, 0x82, 0x87, 0x3D, 0x31, 0xD5, 0x83, + 0x13, 0x5C, 0x07, 0xA2, 0x0C, 0x52, 0xD9, 0x5B, + 0x2D, 0x5D, 0xC3, 0xEA, 0xDE, 0x6B, 0xE1, 0x43, + 0xCA, 0x34, 0x38, 0xF4, 0x4D, 0x02, 0x0A, 0xAE, + 0x16, 0x0E, 0xD7, 0x7A, 0xB9, 0x88, 0x4F, 0x7D + }, + { + 0x30, 0x28, 0xB0, 0xE8, 0x24, 0x95, 0x7F, 0xF3, + 0xB3, 0x05, 0xE9, 0x7F, 0xF5, 0x92, 0xAA, 0x8E, + 0xF2, 0x9B, 0x3B, 0xEC, 0x1D, 0xC4, 0x7B, 0x76, + 0x13, 0x3D, 0x10, 0x3F, 0xFE, 0x38, 0x71, 0xBF, + 0x05, 0x12, 0xA2, 0x31, 0xAF, 0xCB, 0x1D, 0xF8, + 0x65, 0x97, 0xEC, 0x5E, 0x46, 0xE9, 0x23, 0xC8, + 0xB9, 0x85, 0xC2, 0x85, 0x08, 0x57, 0xC6, 0x40, + 0x01, 0xB2, 0xC5, 0x51, 0xEA, 0x83, 0x3D, 0x0E + }, + { + 0x08, 0x7C, 0xCB, 0x1E, 0x5B, 0xD1, 0x72, 0x22, + 0xB8, 0xAF, 0x20, 0x6D, 0xD6, 0x39, 0x08, 0xF8, + 0x91, 0x72, 0x97, 0x62, 0x1A, 0x8C, 0xB9, 0x33, + 0x0A, 0xE0, 0xBA, 0x4A, 0xF3, 0xE9, 0xD6, 0x0C, + 0x98, 0xFC, 0xF1, 0xEF, 0xFC, 0xEC, 0x20, 0x13, + 0x6B, 0x4F, 0x91, 0x88, 0x12, 0x6D, 0xFA, 0x04, + 0x4E, 0x1C, 0x1C, 0xCD, 0xA3, 0xCE, 0xD8, 0x73, + 0x73, 0xD9, 0x37, 0x9C, 0xCB, 0xED, 0xBD, 0xB3 + }, + { + 0x7F, 0x17, 0x06, 0x24, 0x98, 0xBF, 0xA2, 0xBB, + 0x58, 0x56, 0xCD, 0x0A, 0x62, 0xC5, 0x68, 0xC5, + 0xC6, 0xB8, 0x97, 0x43, 0x24, 0x74, 0xEF, 0xB2, + 0xE6, 0xA2, 0xEE, 0x18, 0xCA, 0xFF, 0xD2, 0x1E, + 0x1E, 0xF3, 0x0D, 0x06, 0x47, 0x23, 0x85, 0x0F, + 0x79, 0x90, 0xD2, 0x1B, 0xA3, 0x4E, 0x8F, 0x2B, + 0x3B, 0xB0, 0x67, 0x02, 0x3A, 0x77, 0x27, 0x82, + 0x15, 0x8A, 0x27, 0xC6, 0xC4, 0x67, 0xC9, 0x28 + }, + { + 0x6B, 0xA9, 0x86, 0xA9, 0x42, 0x49, 0x7F, 0xD3, + 0x84, 0x62, 0x97, 0x2F, 0x50, 0xA6, 0x19, 0x68, + 0xC0, 0x65, 0x2D, 0xAC, 0x56, 0xCE, 0x9B, 0x9A, + 0xC1, 0xBC, 0x06, 0x1A, 0xB6, 0x34, 0xFE, 0x5A, + 0x77, 0xAC, 0xD0, 0x27, 0x5F, 0x83, 0x96, 0xE3, + 0xC0, 0xBE, 0xF0, 0x12, 0xAE, 0x93, 0xB7, 0x27, + 0x58, 0xB8, 0xD7, 0x67, 0x9C, 0x87, 0xE8, 0x47, + 0xE6, 0x30, 0x17, 0xB5, 0x5A, 0x69, 0xC5, 0xC6 + }, + { + 0x96, 0x7C, 0x81, 0xF5, 0x61, 0x95, 0x18, 0x33, + 0xFA, 0x56, 0x6F, 0x6B, 0x36, 0x07, 0x7E, 0xAD, + 0xB2, 0xA6, 0x15, 0xCC, 0x15, 0xF0, 0xED, 0xBB, + 0xAE, 0x4F, 0x84, 0x4D, 0xDC, 0x8E, 0x9C, 0x1F, + 0xB8, 0x3D, 0x31, 0xA9, 0x3F, 0xCB, 0x17, 0x74, + 0xD7, 0x40, 0xD6, 0x92, 0x08, 0xCA, 0x59, 0x30, + 0xBC, 0xFA, 0xC4, 0xA1, 0xF9, 0x44, 0x46, 0x9F, + 0xEF, 0xD1, 0x9B, 0x6E, 0x93, 0x75, 0xE0, 0xB5 + }, + { + 0xE8, 0xAE, 0xF1, 0x78, 0xE6, 0xDA, 0x3E, 0xF5, + 0xCA, 0xED, 0x65, 0x30, 0xF7, 0xEB, 0x25, 0x60, + 0x82, 0x56, 0xC2, 0x37, 0x7C, 0x4C, 0xF9, 0x6B, + 0x0C, 0xFD, 0x0D, 0x76, 0xEE, 0xB4, 0xBB, 0x86, + 0xEE, 0xFF, 0x7B, 0x7D, 0xF1, 0x58, 0x5C, 0x8D, + 0x7A, 0x20, 0xC0, 0x63, 0x3A, 0x67, 0x90, 0x7F, + 0x6D, 0x28, 0x67, 0xC3, 0x26, 0x4A, 0x91, 0xC0, + 0x51, 0xAB, 0xAE, 0x6E, 0xEA, 0x5A, 0x91, 0xD8 + }, + { + 0x64, 0x81, 0xDC, 0xC8, 0x15, 0x7A, 0xE6, 0x28, + 0xB5, 0xCD, 0x52, 0x6B, 0xAC, 0x8F, 0x93, 0x31, + 0x56, 0xDE, 0xDA, 0xC9, 0x56, 0xA2, 0xB2, 0x2A, + 0x97, 0x4B, 0xF5, 0xF7, 0xEC, 0x2D, 0xB5, 0x80, + 0x6F, 0x53, 0xDD, 0x0E, 0x2D, 0xD5, 0x3D, 0xB8, + 0x7C, 0xD8, 0xF5, 0x8A, 0x58, 0x6F, 0x9B, 0x3C, + 0x5C, 0x52, 0x23, 0x31, 0xA3, 0x11, 0x74, 0xC4, + 0xE7, 0xB9, 0xB6, 0xF7, 0xF0, 0x57, 0xC2, 0x8F + }, + { + 0xA7, 0x1E, 0xA4, 0x5C, 0xE6, 0x61, 0x6A, 0x3D, + 0x2F, 0x0A, 0x59, 0x2D, 0x5D, 0x02, 0x86, 0x93, + 0x2D, 0xA6, 0x3C, 0x6D, 0xB1, 0x1D, 0x59, 0xC6, + 0x69, 0x1C, 0x35, 0xA5, 0x6F, 0x7E, 0xE4, 0xF8, + 0x0B, 0x6F, 0xC3, 0x40, 0xB4, 0xDB, 0xC1, 0x84, + 0x4C, 0x50, 0x40, 0xE6, 0x68, 0xD2, 0x89, 0x2F, + 0x4A, 0x4A, 0xE8, 0x53, 0x3F, 0x1B, 0x67, 0x71, + 0xBC, 0xFC, 0xE7, 0xC3, 0xA2, 0x3E, 0x0D, 0x97 + }, + { + 0x96, 0x93, 0x44, 0x87, 0x70, 0xFE, 0xAE, 0x42, + 0x17, 0x26, 0xEB, 0x20, 0x3B, 0x01, 0xC7, 0x08, + 0x23, 0xD5, 0xF4, 0x4C, 0xC5, 0x21, 0x3E, 0x6A, + 0x68, 0x28, 0x47, 0x29, 0xBD, 0x11, 0x7D, 0x9B, + 0xD1, 0x8F, 0xEC, 0x4A, 0x0A, 0x82, 0x4A, 0x24, + 0x08, 0x0F, 0x29, 0x8B, 0xAC, 0xD2, 0x96, 0xD7, + 0xB4, 0x97, 0x83, 0x8F, 0xBD, 0x7B, 0x0D, 0x57, + 0x5C, 0x52, 0x49, 0x2B, 0x3E, 0x6F, 0x92, 0x6B + }, + { + 0x37, 0xA1, 0x50, 0x66, 0xF2, 0xB9, 0xF9, 0x4C, + 0x24, 0x61, 0x1B, 0xC4, 0x53, 0xED, 0x02, 0x74, + 0x07, 0x8D, 0x1F, 0x70, 0xB2, 0xD3, 0x4C, 0x8B, + 0x96, 0x36, 0x08, 0x48, 0x9D, 0xCB, 0xE8, 0xDF, + 0x44, 0x8E, 0xDD, 0x9C, 0x73, 0x36, 0x2B, 0xB2, + 0xB6, 0x6B, 0xEE, 0xF6, 0x1F, 0xCE, 0x60, 0x10, + 0x6F, 0x70, 0x19, 0xED, 0x37, 0x3C, 0x69, 0x22, + 0x59, 0xD9, 0x55, 0x6A, 0x94, 0x0B, 0x1A, 0x06 + }, + { + 0xBD, 0x44, 0xE7, 0x39, 0xE1, 0xF9, 0xDB, 0x1C, + 0x6B, 0xAF, 0x42, 0xCA, 0x4A, 0x12, 0xAC, 0x09, + 0x9B, 0x96, 0xF6, 0xB3, 0x6C, 0x4B, 0xCB, 0x1B, + 0x72, 0xEE, 0xFF, 0x08, 0xA6, 0x49, 0x68, 0x35, + 0xEC, 0x65, 0x15, 0x0B, 0xE8, 0xFE, 0x16, 0xCB, + 0xE3, 0x27, 0x07, 0xE3, 0x47, 0x54, 0x7D, 0xC5, + 0xA5, 0x83, 0xD2, 0x65, 0x74, 0x6F, 0xA5, 0x95, + 0xC5, 0xE7, 0x73, 0x0F, 0xCF, 0x24, 0x58, 0x1E + }, + { + 0xFA, 0xB2, 0x03, 0x8E, 0x94, 0x98, 0xA1, 0xC3, + 0x9E, 0x05, 0x78, 0xA0, 0xA5, 0xEA, 0x6B, 0x44, + 0xF3, 0xC1, 0xB4, 0x1A, 0xE5, 0x67, 0xF9, 0x91, + 0x4A, 0x95, 0xB1, 0x31, 0xC4, 0x8D, 0x12, 0x1E, + 0xCA, 0xCE, 0xA8, 0x95, 0xA0, 0x9B, 0x1D, 0x4E, + 0x04, 0x42, 0xBE, 0xC9, 0xC5, 0x0C, 0x50, 0xE0, + 0x0A, 0x9F, 0xAF, 0xEF, 0xFA, 0xE0, 0x70, 0x88, + 0x4C, 0x26, 0x25, 0xA8, 0xB1, 0xA2, 0x17, 0x26 + }, + { + 0x05, 0xA1, 0xB7, 0x6B, 0x2F, 0xD5, 0x62, 0x11, + 0xE0, 0xF2, 0xD7, 0x5A, 0x25, 0x16, 0x54, 0xA7, + 0x72, 0xF5, 0x5E, 0x18, 0xCA, 0x02, 0x2A, 0xF5, + 0x2C, 0xB3, 0x30, 0x19, 0x1E, 0x98, 0xA3, 0xB8, + 0xEB, 0x87, 0xE5, 0x11, 0x7B, 0xAE, 0x58, 0x04, + 0x4D, 0x94, 0x4C, 0x1F, 0x18, 0x85, 0x45, 0x12, + 0x25, 0x41, 0x77, 0x35, 0xFC, 0x72, 0xF7, 0x39, + 0x36, 0x69, 0x3C, 0xFF, 0x45, 0x46, 0x9F, 0x8C + }, + { + 0x2A, 0x30, 0xC9, 0x6B, 0xDA, 0xC7, 0x8A, 0x39, + 0x94, 0xEE, 0xCA, 0xA5, 0xA5, 0x3F, 0x82, 0x7F, + 0x58, 0xE1, 0x32, 0x31, 0xA0, 0xD1, 0x13, 0x08, + 0x6C, 0x06, 0xB1, 0xBD, 0xAB, 0xDA, 0x38, 0xD0, + 0x8F, 0x1A, 0xE2, 0x7D, 0xE2, 0x5F, 0xD2, 0x2E, + 0xEA, 0x70, 0xC0, 0x5F, 0x01, 0x32, 0xBF, 0x7A, + 0x50, 0x1C, 0x82, 0xAE, 0x62, 0x15, 0xBF, 0xEF, + 0x3C, 0x01, 0x63, 0x98, 0xBA, 0xF2, 0xCB, 0x62 + }, + { + 0x48, 0xDB, 0x53, 0x76, 0x5B, 0x82, 0xBD, 0x6F, + 0x25, 0x33, 0xEA, 0xE1, 0x7F, 0x67, 0x69, 0xD7, + 0xA4, 0xE3, 0xB2, 0x43, 0x74, 0x60, 0x1C, 0xDD, + 0x8E, 0xC0, 0xCA, 0x3A, 0xAB, 0x30, 0x93, 0xFD, + 0x2B, 0x99, 0x24, 0x38, 0x46, 0x0B, 0xAF, 0x8D, + 0xA5, 0x8F, 0xB9, 0xA8, 0x9B, 0x2C, 0x58, 0xF9, + 0x68, 0xE6, 0x36, 0x17, 0xCB, 0xEB, 0x18, 0x44, + 0xB0, 0x2D, 0x6A, 0x27, 0xC5, 0xB4, 0xAD, 0x41 + }, + { + 0x5C, 0x8B, 0x2E, 0x0E, 0x1B, 0x5C, 0x8F, 0x45, + 0x7D, 0x7F, 0x7B, 0xD9, 0xF0, 0x5A, 0x97, 0xE5, + 0x8D, 0xDA, 0x1D, 0x28, 0xDB, 0x9F, 0x34, 0xD1, + 0xCE, 0x73, 0x25, 0x28, 0xF9, 0x68, 0xBE, 0xDD, + 0x9E, 0x1C, 0xC9, 0x35, 0x2D, 0x0A, 0x5D, 0xF6, + 0x67, 0x29, 0x28, 0xBD, 0xD3, 0xEA, 0x6F, 0x5C, + 0xB0, 0x60, 0x77, 0xCF, 0x3A, 0xD3, 0xA7, 0x6E, + 0x29, 0xB2, 0x2E, 0x82, 0xBA, 0xC6, 0x7B, 0x61 + }, + { + 0x5B, 0x73, 0x91, 0xAA, 0x52, 0xF2, 0x76, 0xFA, + 0xB9, 0xC1, 0x38, 0x77, 0xF1, 0x22, 0x32, 0x70, + 0x84, 0x97, 0xFC, 0x02, 0x8F, 0xAA, 0x17, 0x32, + 0xA5, 0xDB, 0x07, 0x9E, 0x7F, 0xE0, 0x73, 0xED, + 0x0C, 0xC9, 0x52, 0x9C, 0xFC, 0x86, 0x3A, 0x4E, + 0xCB, 0xA4, 0xDC, 0x2F, 0x1E, 0xA9, 0xF6, 0xBD, + 0x69, 0x04, 0xF3, 0xA0, 0xC1, 0x07, 0x19, 0x3C, + 0x5E, 0x71, 0x1C, 0xB9, 0x11, 0xF3, 0x80, 0x25 + }, + { + 0x1D, 0x5A, 0xF7, 0x0F, 0x09, 0xA5, 0xFC, 0x69, + 0x16, 0xEF, 0x59, 0xA3, 0x8A, 0x86, 0x92, 0x6D, + 0xCA, 0xAE, 0x39, 0xA8, 0x95, 0x4D, 0x73, 0xFC, + 0x80, 0xA3, 0x50, 0x75, 0x1A, 0xDD, 0xA3, 0x8C, + 0x9D, 0x59, 0x75, 0x06, 0xDC, 0x05, 0xE1, 0xED, + 0x37, 0xBD, 0x2D, 0xB1, 0x59, 0x0F, 0x99, 0xAA, + 0x29, 0x6A, 0xEA, 0x13, 0xAB, 0x84, 0x43, 0xD5, + 0xA9, 0x23, 0x47, 0xFB, 0x85, 0xFC, 0x81, 0x6D + }, + { + 0x80, 0xE3, 0x70, 0x92, 0x97, 0xD4, 0x41, 0x14, + 0xB9, 0xFB, 0xDF, 0x55, 0x67, 0xF0, 0x5F, 0x33, + 0x00, 0x94, 0xCF, 0x09, 0xF4, 0xC0, 0xEF, 0xCF, + 0xAC, 0x05, 0x09, 0x5C, 0x36, 0x08, 0x10, 0x77, + 0x30, 0xC1, 0xAA, 0x07, 0xFF, 0x23, 0x00, 0x25, + 0x62, 0xC7, 0xE8, 0x41, 0xA9, 0xF5, 0x66, 0x24, + 0xFF, 0xE2, 0xAB, 0xEC, 0x61, 0x1E, 0xB9, 0xE7, + 0x3E, 0x1C, 0xCB, 0xD8, 0xF6, 0x2B, 0x11, 0x49 + }, + { + 0xF9, 0x94, 0x5C, 0x19, 0x06, 0x77, 0x84, 0x61, + 0x94, 0x13, 0x2B, 0x49, 0x6E, 0xC6, 0x01, 0x2C, + 0x08, 0x75, 0x0E, 0x02, 0x5F, 0xD5, 0x52, 0xED, + 0x32, 0x4D, 0x3A, 0x49, 0xD8, 0x63, 0x66, 0xC0, + 0x3D, 0xCC, 0xDE, 0x8D, 0x5B, 0x5A, 0xC9, 0xA4, + 0xBC, 0xB7, 0x19, 0x5E, 0x63, 0xBC, 0xAA, 0x93, + 0x9E, 0x8E, 0xDA, 0x18, 0xF1, 0x16, 0x94, 0xB6, + 0xFA, 0x69, 0x37, 0x39, 0x3B, 0xFF, 0xDB, 0xF4 + }, + { + 0x8D, 0x8F, 0x2E, 0xD9, 0xAE, 0x39, 0x80, 0x9A, + 0xAC, 0xAD, 0x2F, 0xCE, 0xDB, 0xD2, 0xDC, 0xA7, + 0x30, 0xC7, 0x83, 0xE6, 0x2F, 0xF7, 0x0B, 0x8D, + 0x3C, 0x53, 0x62, 0xF0, 0x73, 0xF8, 0x34, 0x67, + 0x19, 0x7D, 0x37, 0x56, 0xB4, 0x45, 0x19, 0x5F, + 0xE7, 0x52, 0x11, 0x73, 0x64, 0xD9, 0x2C, 0xF4, + 0x2C, 0x02, 0x6E, 0x40, 0x9D, 0x5F, 0xF7, 0xA9, + 0x53, 0x3E, 0xAB, 0x78, 0xF1, 0x75, 0x4A, 0x2D + }, + { + 0x3A, 0xC9, 0x9A, 0xC5, 0x3A, 0xC4, 0x9A, 0x56, + 0xFA, 0xA1, 0x86, 0x46, 0xB8, 0xE0, 0x8A, 0x2D, + 0x35, 0xBE, 0x80, 0xDF, 0x3E, 0xFB, 0xBB, 0xA6, + 0xBD, 0xA4, 0xAE, 0x90, 0x2B, 0x8D, 0x3E, 0x17, + 0x0A, 0x7B, 0xE8, 0x60, 0x5C, 0x34, 0xA4, 0xDC, + 0x9A, 0x73, 0x62, 0xB1, 0xC2, 0x01, 0xD7, 0x02, + 0x39, 0x1B, 0xD7, 0xD5, 0x20, 0x7F, 0x95, 0xFA, + 0x39, 0x0C, 0xE3, 0x3C, 0x43, 0x14, 0xD4, 0x11 + }, + { + 0xE4, 0x69, 0x4B, 0xDB, 0x31, 0x01, 0x6F, 0x25, + 0x53, 0x2C, 0x04, 0x3C, 0x5C, 0x63, 0x08, 0xCC, + 0x61, 0x9B, 0x0F, 0x87, 0x16, 0xF0, 0xC2, 0x9E, + 0xEB, 0x9F, 0x34, 0x0F, 0x47, 0xB0, 0x7B, 0x4A, + 0x4C, 0xE0, 0x98, 0x4C, 0x47, 0x24, 0xB1, 0x2A, + 0xB3, 0xD3, 0x2A, 0xF5, 0x16, 0xAD, 0xA2, 0x64, + 0x4C, 0xA6, 0x55, 0x8C, 0x1C, 0xB5, 0x81, 0x5C, + 0x12, 0x12, 0xA9, 0xB5, 0xFA, 0x83, 0x44, 0x12 + }, + { + 0xC6, 0x3C, 0x70, 0x3E, 0x62, 0x10, 0x8A, 0xA0, + 0xED, 0xC6, 0x83, 0xF3, 0x67, 0x8A, 0x00, 0x78, + 0x8F, 0xB1, 0x00, 0xC0, 0x96, 0x0B, 0x4E, 0x98, + 0xB7, 0x6A, 0x48, 0xE4, 0xE5, 0x92, 0x3D, 0x34, + 0x13, 0x44, 0x8D, 0xB8, 0x87, 0x5E, 0x3B, 0xCE, + 0xA7, 0xB6, 0xB8, 0x5D, 0x9E, 0x3E, 0xEA, 0xB7, + 0x2C, 0xD1, 0x50, 0x96, 0xFB, 0xBB, 0x2C, 0xC4, + 0x27, 0x03, 0x17, 0xFC, 0x34, 0xD4, 0x04, 0x71 + }, + { + 0x90, 0x80, 0xB7, 0xE8, 0x41, 0xEF, 0x51, 0x9C, + 0x54, 0x17, 0xE6, 0x90, 0xAA, 0xF4, 0x32, 0x79, + 0x07, 0xA8, 0x3D, 0xBC, 0xB7, 0x38, 0xD0, 0xF7, + 0x30, 0x8B, 0x1D, 0x61, 0x1D, 0xEF, 0x16, 0x9A, + 0x4F, 0x47, 0x42, 0x3E, 0x69, 0x0F, 0x27, 0xA7, + 0xE2, 0x74, 0x1A, 0xE7, 0x86, 0x5D, 0xA2, 0x3C, + 0x5D, 0x3F, 0x13, 0xC3, 0x16, 0x06, 0x3C, 0x7A, + 0xA1, 0xA9, 0x58, 0xE5, 0xBE, 0x83, 0x8F, 0x04 + }, + { + 0x29, 0x8D, 0xF6, 0x46, 0x91, 0x5F, 0x04, 0xD6, + 0x65, 0xE9, 0x67, 0x5E, 0x6A, 0x10, 0x31, 0x87, + 0x0D, 0x28, 0xEB, 0x7A, 0x04, 0x05, 0x66, 0x3E, + 0xAC, 0x3B, 0x10, 0xD1, 0xB4, 0xFA, 0x2E, 0x86, + 0x8E, 0x63, 0x73, 0xA5, 0x86, 0xCD, 0x73, 0xE0, + 0x6D, 0x8E, 0x7A, 0xD7, 0x71, 0xB4, 0xFB, 0x0A, + 0x8B, 0x4F, 0xC2, 0xDC, 0x6C, 0xE0, 0x9C, 0x64, + 0x2E, 0xE8, 0x99, 0x26, 0xFD, 0xC6, 0x52, 0x60 + }, + { + 0x4F, 0x2D, 0xE9, 0xC4, 0xF4, 0x34, 0x8B, 0xDB, + 0x32, 0x3A, 0x66, 0x83, 0x72, 0xE7, 0x71, 0x42, + 0x99, 0xC7, 0x76, 0xF9, 0x60, 0x2F, 0x3A, 0xF8, + 0xFB, 0x77, 0x46, 0xF1, 0x76, 0x86, 0x8D, 0xF3, + 0x54, 0x2B, 0x2F, 0xA6, 0x9E, 0xAE, 0x38, 0xB6, + 0xA2, 0x6A, 0x06, 0xCA, 0x89, 0x42, 0xF8, 0x82, + 0x78, 0xC6, 0x4E, 0x3D, 0x01, 0x7F, 0xEE, 0x67, + 0xA9, 0x4E, 0xA0, 0x23, 0xB2, 0xB5, 0xBE, 0x5F + }, + { + 0x40, 0x18, 0xC5, 0xEE, 0x90, 0x93, 0xA6, 0x81, + 0x11, 0x2F, 0x4C, 0xE1, 0x93, 0xA1, 0xD6, 0x5E, + 0x05, 0x48, 0x72, 0x5F, 0x96, 0xAE, 0x31, 0x53, + 0x87, 0xCD, 0x76, 0x5C, 0x2B, 0x9C, 0x30, 0x68, + 0xAE, 0x4C, 0xBE, 0x5C, 0xD5, 0x40, 0x2C, 0x11, + 0xC5, 0x5A, 0x9D, 0x78, 0x5F, 0xFD, 0xFC, 0x2B, + 0xDE, 0x6E, 0x7A, 0xCF, 0x19, 0x61, 0x74, 0x75, + 0xDA, 0xE0, 0xEB, 0x01, 0x44, 0x56, 0xCE, 0x45 + }, + { + 0x6F, 0xCE, 0x66, 0x75, 0xE8, 0x6D, 0x7E, 0x85, + 0x70, 0x4C, 0x96, 0xC2, 0x95, 0x70, 0x3C, 0xD9, + 0x54, 0x98, 0x59, 0x0E, 0x50, 0x76, 0x4D, 0x23, + 0xD7, 0xA7, 0xA3, 0xA3, 0x22, 0x68, 0xA0, 0xB3, + 0xC9, 0x91, 0xE8, 0xF7, 0x84, 0x87, 0x69, 0x9A, + 0x55, 0x4B, 0x58, 0x1E, 0x33, 0x9C, 0x09, 0xAE, + 0xC9, 0x82, 0xE0, 0xBA, 0xA4, 0x31, 0x87, 0x93, + 0x62, 0x06, 0x35, 0xE1, 0xE2, 0xC8, 0xD9, 0xF2 + }, + { + 0xEB, 0xA9, 0x37, 0x85, 0x91, 0x97, 0xC7, 0xFD, + 0x41, 0x2D, 0xBC, 0x9A, 0xFC, 0x0D, 0x67, 0xCC, + 0x19, 0x81, 0x60, 0xB5, 0xA9, 0xCC, 0xEE, 0x87, + 0xC4, 0x1A, 0x86, 0x64, 0x85, 0x9F, 0x3E, 0xFD, + 0x96, 0x13, 0x66, 0xA8, 0x09, 0xC7, 0xC6, 0xBC, + 0x6F, 0xA8, 0x44, 0x92, 0x68, 0x14, 0xE0, 0xB4, + 0xEF, 0xA3, 0x7E, 0xDE, 0x2C, 0x88, 0x44, 0x26, + 0x8D, 0x7F, 0x35, 0x56, 0xE4, 0x46, 0x58, 0x1D + }, + { + 0x83, 0xF4, 0x33, 0xE4, 0xF1, 0xC5, 0x07, 0x97, + 0x49, 0x3C, 0x58, 0xC2, 0x64, 0xCF, 0xFA, 0x70, + 0xC4, 0xA7, 0xA2, 0x4C, 0x33, 0x4D, 0xBA, 0xA3, + 0xC5, 0x74, 0x89, 0xD9, 0x70, 0xD4, 0x9D, 0x69, + 0x49, 0xFE, 0x45, 0xB7, 0x04, 0xF2, 0x65, 0xEF, + 0xD2, 0xAE, 0xE1, 0xAC, 0x1B, 0x46, 0xF4, 0xAA, + 0x3E, 0x4F, 0xAD, 0x68, 0xB3, 0x79, 0x61, 0xD2, + 0xC7, 0x28, 0x0A, 0xE1, 0x96, 0x72, 0xC8, 0x50 + }, + { + 0xB5, 0x57, 0xEC, 0xE1, 0x22, 0x72, 0x49, 0x3D, + 0xC2, 0x7E, 0x88, 0xA0, 0x5A, 0xDC, 0xD8, 0x61, + 0x87, 0x5A, 0x0C, 0xD0, 0x0B, 0xD6, 0x8A, 0xDC, + 0x3A, 0x30, 0x1D, 0x26, 0x3A, 0x9C, 0xD9, 0x93, + 0xA9, 0x6A, 0xE1, 0x4C, 0xFC, 0xDD, 0xCB, 0x99, + 0x7C, 0xC9, 0x86, 0x23, 0x93, 0x50, 0x50, 0xEA, + 0x43, 0x55, 0x2A, 0x34, 0x11, 0x07, 0x18, 0x7D, + 0xE7, 0x5C, 0x4E, 0xDE, 0xD7, 0xC7, 0x86, 0xBD + }, + { + 0x95, 0x89, 0xC0, 0x81, 0x3B, 0x73, 0x93, 0xDB, + 0xAA, 0xAF, 0xE4, 0x7A, 0xF5, 0xB4, 0x08, 0xB2, + 0x3C, 0x8A, 0x8C, 0x8B, 0xAC, 0x62, 0x55, 0x4B, + 0x8F, 0xA1, 0x32, 0xA3, 0x58, 0xCE, 0x30, 0x83, + 0xB1, 0xD4, 0xE3, 0x97, 0x07, 0xCD, 0x54, 0xA5, + 0x5F, 0x67, 0x3D, 0x48, 0x11, 0x6E, 0xB1, 0xF9, + 0xED, 0x8D, 0xE9, 0xC9, 0x43, 0xCD, 0x2D, 0xE4, + 0x60, 0xA6, 0x8B, 0xDD, 0xF7, 0x1E, 0x98, 0x03 + }, + { + 0xAE, 0x4C, 0xCF, 0x27, 0xAB, 0x00, 0xA4, 0x0C, + 0x36, 0x37, 0xD3, 0xD2, 0xCE, 0x51, 0xA8, 0x3E, + 0xFB, 0xA6, 0x2D, 0x4A, 0x6F, 0xDA, 0xD6, 0x95, + 0x06, 0x3F, 0xBC, 0x60, 0xA2, 0xD8, 0x2E, 0xC5, + 0xA5, 0x4A, 0xCB, 0xE0, 0x9B, 0xA9, 0x38, 0x8F, + 0x49, 0xAA, 0xC2, 0x7C, 0x99, 0x2D, 0x84, 0x63, + 0x20, 0x36, 0xE1, 0xBD, 0xD4, 0xC5, 0x29, 0xBB, + 0xF1, 0x85, 0x1E, 0xAE, 0x0C, 0x6E, 0xA9, 0x02 + }, + { + 0xA3, 0x94, 0x4B, 0x2C, 0x31, 0xCB, 0x49, 0x40, + 0x80, 0xB7, 0xEE, 0x1D, 0xB0, 0x81, 0x68, 0x53, + 0xE4, 0x25, 0xB5, 0x4C, 0x48, 0xD6, 0x31, 0x44, + 0x7E, 0xA5, 0x2C, 0x1D, 0x29, 0x52, 0x07, 0x9B, + 0xD8, 0x8F, 0xAB, 0x9E, 0xD0, 0xB7, 0xD8, 0xC0, + 0xBA, 0xAF, 0x0C, 0x4E, 0xCA, 0x19, 0x10, 0xDB, + 0x6F, 0x98, 0x53, 0x4F, 0x0D, 0x42, 0xE5, 0xEB, + 0xB6, 0xC0, 0xA7, 0x5E, 0xF0, 0xD8, 0xB2, 0xC0 + }, + { + 0xCF, 0xA1, 0xA2, 0x24, 0x68, 0x5A, 0x5F, 0xB2, + 0x01, 0x04, 0x58, 0x20, 0x1C, 0xEB, 0x0C, 0xDA, + 0x21, 0xC8, 0x2B, 0x16, 0x02, 0xDC, 0x41, 0x35, + 0x85, 0xFB, 0xCE, 0x80, 0x97, 0x6F, 0x06, 0x1C, + 0x23, 0x5B, 0x13, 0x67, 0x71, 0x24, 0x98, 0x14, + 0x4A, 0xC1, 0x6A, 0x98, 0x54, 0xF6, 0xFB, 0x32, + 0x3C, 0xBE, 0xB6, 0x23, 0x69, 0xCF, 0x9B, 0x75, + 0x2B, 0x92, 0x52, 0xA2, 0xA7, 0xAC, 0xE1, 0xFD + }, + { + 0xFA, 0x62, 0xC6, 0xCF, 0xC8, 0xF0, 0x79, 0xE5, + 0x8F, 0x3D, 0x3F, 0xEF, 0xD7, 0xC2, 0x24, 0xE7, + 0x1E, 0xBC, 0x69, 0xA9, 0x5B, 0x18, 0x35, 0xCC, + 0xC3, 0x2F, 0x35, 0x07, 0x77, 0x05, 0x11, 0x02, + 0x61, 0x54, 0x92, 0xD6, 0x7F, 0xB6, 0xDE, 0x62, + 0xCF, 0x2A, 0xD5, 0xB1, 0x84, 0x67, 0xFE, 0x87, + 0x15, 0x74, 0x88, 0x82, 0xDB, 0x89, 0xFF, 0x86, + 0xEF, 0xDF, 0x2F, 0x96, 0xF8, 0x13, 0x5E, 0xD2 + }, + { + 0xCC, 0x63, 0x3F, 0xD4, 0xEA, 0x6A, 0xC4, 0x08, + 0xC3, 0x87, 0x57, 0x56, 0xB9, 0x01, 0x28, 0x8A, + 0x1D, 0xE1, 0x91, 0x89, 0x28, 0x32, 0xBE, 0x2E, + 0x90, 0x26, 0xDC, 0x65, 0xC2, 0xFF, 0x00, 0x00, + 0x9F, 0x14, 0x36, 0xDD, 0xFF, 0x42, 0x06, 0x26, + 0x0A, 0x3D, 0x66, 0xEF, 0x61, 0x92, 0x14, 0x3E, + 0x57, 0x2F, 0x1E, 0x4B, 0xB8, 0xE5, 0xA7, 0x4B, + 0x12, 0x05, 0x5E, 0x42, 0x41, 0x1C, 0x18, 0xBC + }, + { + 0x44, 0xD2, 0xBF, 0x7F, 0x36, 0x96, 0xB8, 0x93, + 0x3F, 0x25, 0x5B, 0x9B, 0xE1, 0xA4, 0xA6, 0xAE, + 0x33, 0x16, 0xC2, 0x5D, 0x03, 0x95, 0xF5, 0x90, + 0xB9, 0xB9, 0x89, 0x8F, 0x12, 0x7E, 0x40, 0xD3, + 0xF4, 0x12, 0x4D, 0x7B, 0xDB, 0xC8, 0x72, 0x5F, + 0x00, 0xB0, 0xD2, 0x81, 0x50, 0xFF, 0x05, 0xB4, + 0xA7, 0x9E, 0x5E, 0x04, 0xE3, 0x4A, 0x47, 0xE9, + 0x08, 0x7B, 0x3F, 0x79, 0xD4, 0x13, 0xAB, 0x7F + }, + { + 0x96, 0xFB, 0xCB, 0xB6, 0x0B, 0xD3, 0x13, 0xB8, + 0x84, 0x50, 0x33, 0xE5, 0xBC, 0x05, 0x8A, 0x38, + 0x02, 0x74, 0x38, 0x57, 0x2D, 0x7E, 0x79, 0x57, + 0xF3, 0x68, 0x4F, 0x62, 0x68, 0xAA, 0xDD, 0x3A, + 0xD0, 0x8D, 0x21, 0x76, 0x7E, 0xD6, 0x87, 0x86, + 0x85, 0x33, 0x1B, 0xA9, 0x85, 0x71, 0x48, 0x7E, + 0x12, 0x47, 0x0A, 0xAD, 0x66, 0x93, 0x26, 0x71, + 0x6E, 0x46, 0x66, 0x7F, 0x69, 0xF8, 0xD7, 0xE8 + }, +}; + + + + +#endif + + + diff --git a/python/Modules/_blake2/impl/blake2.h b/python/Modules/_blake2/impl/blake2.h new file mode 100755 index 0000000..a08d82e --- /dev/null +++ b/python/Modules/_blake2/impl/blake2.h @@ -0,0 +1,177 @@ +/* + 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_H__ +#define __BLAKE2_H__ + +#include +#include + +#if defined(_WIN32) || defined(__CYGWIN__) + #define BLAKE2_DLL_IMPORT __declspec(dllimport) + #define BLAKE2_DLL_EXPORT __declspec(dllexport) + #define BLAKE2_DLL_PRIVATE +#elif __GNUC__ >= 4 + #define BLAKE2_DLL_IMPORT __attribute__ ((visibility ("default"))) + #define BLAKE2_DLL_EXPORT __attribute__ ((visibility ("default"))) + #define BLAKE2_DLL_PRIVATE __attribute__ ((visibility ("hidden"))) +#else + #define BLAKE2_DLL_IMPORT + #define BLAKE2_DLL_EXPORT + #define BLAKE2_DLL_PRIVATE +#endif + +#if defined(BLAKE2_DLL) + #if defined(BLAKE2_DLL_EXPORTS) // defined if we are building the DLL + #define BLAKE2_API BLAKE2_DLL_EXPORT + #else + #define BLAKE2_API BLAKE2_DLL_IMPORT + #endif + #define BLAKE2_PRIVATE BLAKE2_DLL_PRIVATE // must only be used by hidden logic +#else + #define BLAKE2_API + #define BLAKE2_PRIVATE +#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 + }; + +#pragma pack(push, 1) + typedef struct __blake2s_param + { + uint8_t digest_length; // 1 + uint8_t key_length; // 2 + uint8_t fanout; // 3 + uint8_t depth; // 4 + uint32_t leaf_length; // 8 + uint8_t node_offset[6];// 14 + uint8_t node_depth; // 15 + uint8_t inner_length; // 16 + // uint8_t reserved[0]; + uint8_t salt[BLAKE2S_SALTBYTES]; // 24 + 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]; + uint32_t buflen; + uint8_t outlen; + uint8_t last_node; + } blake2s_state; + + typedef struct __blake2b_param + { + uint8_t digest_length; // 1 + uint8_t key_length; // 2 + uint8_t fanout; // 3 + uint8_t depth; // 4 + uint32_t leaf_length; // 8 + uint64_t node_offset; // 16 + uint8_t node_depth; // 17 + uint8_t inner_length; // 18 + uint8_t reserved[14]; // 32 + uint8_t salt[BLAKE2B_SALTBYTES]; // 48 + 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]; + 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 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]; + uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; + uint32_t buflen; + uint8_t outlen; + } 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 + diff --git a/python/Modules/_blake2/impl/blake2b-load-sse2.h b/python/Modules/_blake2/impl/blake2b-load-sse2.h new file mode 100755 index 0000000..1ba153c --- /dev/null +++ b/python/Modules/_blake2/impl/blake2b-load-sse2.h @@ -0,0 +1,68 @@ +/* + 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 __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/python/Modules/_blake2/impl/blake2b-load-sse41.h b/python/Modules/_blake2/impl/blake2b-load-sse41.h new file mode 100755 index 0000000..f6c1bc8 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2b-load-sse41.h @@ -0,0 +1,402 @@ +/* + 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 __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/python/Modules/_blake2/impl/blake2b-ref.c b/python/Modules/_blake2/impl/blake2b-ref.c new file mode 100755 index 0000000..e58c436 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2b-ref.c @@ -0,0 +1,379 @@ +/* + BLAKE2 reference source code package - reference 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 . +*/ + +#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; +} + +static inline int blake2b_clear_lastnode( blake2b_state *S ) +{ + S->f[1] = 0ULL; + 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 ); + + S->f[0] = ~0ULL; + return 0; +} + +static inline int blake2b_clear_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_clear_lastnode( S ); + + S->f[0] = 0ULL; + 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; +} + + + +// 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; +} + +static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) +{ + 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; +} + +static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) +{ + 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; +} + +static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) +{ + 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; +} + +static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) +{ + 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; +} + +static inline int blake2b_init0( blake2b_state *S ) +{ + memset( S, 0, sizeof( blake2b_state ) ); + + for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + + return 0; +} + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init( blake2b_state *S, size_t outlen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + +/* 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 */ + for( size_t i = 0; i < 8; ++i ) + S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + + S->outlen = P->digest_length; + return 0; +} + + + +int blake2b_init( blake2b_state *S, size_t outlen ) +{ + 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 ); +} + + +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; + + 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]; + 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; +} + + +int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) +{ + while( inlen > 0 ) + { + uint32_t left = S->buflen; + uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + + if( inlen > fill ) + { + memcpy( S->buf + left, in, fill ); // Fill buffer + 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; + } + 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; +} + +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; + 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; +} + +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; + } + + if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0 ) return -1; + return blake2b_final( S, out, outlen ); +} + + diff --git a/python/Modules/_blake2/impl/blake2b-round.h b/python/Modules/_blake2/impl/blake2b-round.h new file mode 100755 index 0000000..cebc225 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2b-round.h @@ -0,0 +1,160 @@ +/* + 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 __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 + +#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 + diff --git a/python/Modules/_blake2/impl/blake2b-test.c b/python/Modules/_blake2/impl/blake2b-test.c new file mode 100755 index 0000000..9310a27 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2b-test.c @@ -0,0 +1,43 @@ +/* + 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 . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + + if( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/python/Modules/_blake2/impl/blake2b.c b/python/Modules/_blake2/impl/blake2b.c new file mode 100755 index 0000000..c1068e8 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2b.c @@ -0,0 +1,436 @@ +/* + 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 . +*/ + +#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 +// 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 ) +{ + return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 ); +} +#endif +#endif + +#if defined(HAVE_SSSE3) +#include +#endif +#if defined(HAVE_SSE4_1) +#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 */ +static inline int blake2b_set_lastnode( blake2b_state *S ) +{ + S->f[1] = ~0ULL; + return 0; +} + +static inline int blake2b_clear_lastnode( blake2b_state *S ) +{ + S->f[1] = 0ULL; + return 0; +} + +static inline int blake2b_set_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_set_lastnode( S ); + + S->f[0] = ~0ULL; + return 0; +} + +static inline int blake2b_clear_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_clear_lastnode( S ); + + S->f[0] = 0ULL; + 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; +} + + +// 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; +} + +static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) +{ + 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; +} + +static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) +{ + 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; +} + +static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) +{ + 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; +} + +static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) +{ + 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; +} + +static inline int blake2b_init0( blake2b_state *S ) +{ + memset( S, 0, sizeof( blake2b_state ) ); + + for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + + return 0; +} + + + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init( blake2b_state *S, size_t outlen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + +/* 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 ) ); + + 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 */ + +int blake2b_init( blake2b_state *S, size_t outlen ) +{ + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + const blake2b_param P = + { + ( uint8_t ) outlen, + 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 ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; + + 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; +} + +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 +#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; +} + + +int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) +{ + while( inlen > 0 ) + { + uint32_t left = S->buflen; + uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + + if( inlen > fill ) + { + memcpy( S->buf + left, in, fill ); // Fill buffer + 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; + } + 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; +} + + +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; + 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; +} + + +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; + } + + 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 diff --git a/python/Modules/_blake2/impl/blake2bp-test.c b/python/Modules/_blake2/impl/blake2bp-test.c new file mode 100755 index 0000000..849666c --- /dev/null +++ b/python/Modules/_blake2/impl/blake2bp-test.c @@ -0,0 +1,44 @@ +/* + 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 . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" + +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + + if( blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/python/Modules/_blake2/impl/blake2bp.c b/python/Modules/_blake2/impl/blake2bp.c new file mode 100755 index 0000000..4522161 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2bp.c @@ -0,0 +1,274 @@ +/* + 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 . +*/ + +#include +#include +#include +#include + +#if defined(_OPENMP) +#include +#endif + +#include "blake2.h" +#include "blake2-impl.h" + +#define PARALLELISM_DEGREE 4 + +static int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) +{ + blake2b_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + store32(&P->leaf_length, 0); + store64(&P->node_offset, offset); + P->node_depth = 0; + P->inner_length = BLAKE2B_OUTBYTES; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2b_init_param( S, P ); + S->outlen = P->inner_length; + return 0; +} + +static int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen ) +{ + blake2b_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + store32(&P->leaf_length, 0); + store64(&P->node_offset, 0); + P->node_depth = 1; + P->inner_length = BLAKE2B_OUTBYTES; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2b_init_param( S, P ); + S->outlen = P->digest_length; + return 0; +} + + +int blake2bp_init( blake2bp_state *S, size_t outlen ) +{ + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2bp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + return 0; +} + +int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) +{ + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2bp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + + +int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen ) +{ + size_t left = S->buflen; + size_t fill = sizeof( S->buf ) - left; + + if( left && inlen >= fill ) + { + memcpy( S->buf + left, in, fill ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); + + in += fill; + inlen -= fill; + left = 0; + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S) +#else + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2B_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) + { + blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + } + } + + in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); + inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + + if( inlen > 0 ) + memcpy( S->buf + left, in, inlen ); + + S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; + return 0; +} + + + +int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; + + if(S->outlen != outlen) return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + { + if( S->buflen > i * BLAKE2B_BLOCKBYTES ) + { + size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; + + if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; + + blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); + } + + blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); + } + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); + + return blake2b_final( S->R, out, outlen ); +} + +int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; + blake2b_state S[PARALLELISM_DEGREE][1]; + blake2b_state FS[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; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2bp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node + + if( keylen > 0 ) + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S,hash) +#else + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2B_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) + { + blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + } + + if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) + { + const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; + const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; + blake2b_update( S[id__], in__, len ); + } + + blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); + } + + if( blake2bp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + FS->last_node = 1; // Mark as last node + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); + + return blake2b_final( FS, out, outlen ); +} + + + diff --git a/python/Modules/_blake2/impl/blake2s-load-sse2.h b/python/Modules/_blake2/impl/blake2s-load-sse2.h new file mode 100755 index 0000000..b24483c --- /dev/null +++ b/python/Modules/_blake2/impl/blake2s-load-sse2.h @@ -0,0 +1,59 @@ +/* + 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 __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/python/Modules/_blake2/impl/blake2s-load-sse41.h b/python/Modules/_blake2/impl/blake2s-load-sse41.h new file mode 100755 index 0000000..3ac12eb --- /dev/null +++ b/python/Modules/_blake2/impl/blake2s-load-sse41.h @@ -0,0 +1,229 @@ +/* + 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 __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/python/Modules/_blake2/impl/blake2s-load-xop.h b/python/Modules/_blake2/impl/blake2s-load-xop.h new file mode 100755 index 0000000..ac591a7 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2s-load-xop.h @@ -0,0 +1,189 @@ +/* + 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 __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 */ +/*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), + _mm_cmpgt_epi8(sel, sixteen)); // (>=16) = 0xff : 00 + 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 + diff --git a/python/Modules/_blake2/impl/blake2s-ref.c b/python/Modules/_blake2/impl/blake2s-ref.c new file mode 100755 index 0000000..ab86cc1 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2s-ref.c @@ -0,0 +1,368 @@ +/* + BLAKE2 reference source code package - reference 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 . +*/ + +#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; +} + +static inline int blake2s_clear_lastnode( blake2s_state *S ) +{ + S->f[1] = 0U; + 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 ); + + S->f[0] = ~0U; + return 0; +} + +static inline int blake2s_clear_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_clear_lastnode( S ); + + S->f[0] = 0U; + 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; +} + +// 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; +} + +static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) +{ + 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; +} + +static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) +{ + 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; +} + +static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) +{ + 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; +} + +static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) +{ + 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; +} + +static inline int blake2s_init0( blake2s_state *S ) +{ + memset( S, 0, sizeof( blake2s_state ) ); + + for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + + return 0; +} + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2s_init( blake2s_state *S, size_t outlen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + +/* 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 */ + for( size_t i = 0; i < 8; ++i ) + S->h[i] ^= load32( &p[i] ); + + S->outlen = P->digest_length; + 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; + + 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; + // 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 ); +} + +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; + + 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; + // 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]; + + for( size_t i = 0; i < 16; ++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 ); + + 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; +} + + +int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) +{ + while( inlen > 0 ) + { + uint32_t left = S->buflen; + uint32_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 ); + 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 += ( uint32_t ) inlen; // Be lazy, do not compress + 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; + 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; +} + +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; + } + + if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1; + return blake2s_final( S, out, outlen ); +} + diff --git a/python/Modules/_blake2/impl/blake2s-round.h b/python/Modules/_blake2/impl/blake2s-round.h new file mode 100755 index 0000000..1e2f2b7 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2s-round.h @@ -0,0 +1,91 @@ +/* + 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 __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" +#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); \ + +#endif + diff --git a/python/Modules/_blake2/impl/blake2s-test.c b/python/Modules/_blake2/impl/blake2s-test.c new file mode 100755 index 0000000..5c3f1f1 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2s-test.c @@ -0,0 +1,43 @@ +/* + 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 . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + + if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/python/Modules/_blake2/impl/blake2s.c b/python/Modules/_blake2/impl/blake2s.c new file mode 100755 index 0000000..4751468 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2s.c @@ -0,0 +1,415 @@ +/* + 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 . +*/ + +#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 +// 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 ) +{ + return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 ); +} +#endif +#endif + + +#if defined(HAVE_SSSE3) +#include +#endif +#if defined(HAVE_SSE4_1) +#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 */ +static inline int blake2s_set_lastnode( blake2s_state *S ) +{ + S->f[1] = ~0U; + return 0; +} + +static inline int blake2s_clear_lastnode( blake2s_state *S ) +{ + S->f[1] = 0U; + return 0; +} + +static inline int blake2s_set_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_set_lastnode( S ); + + S->f[0] = ~0U; + return 0; +} + +static inline int blake2s_clear_lastblock( blake2s_state *S ) +{ + if( S->last_node ) blake2s_clear_lastnode( S ); + + S->f[0] = 0U; + 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; +} + + +// 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; +} + +static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) +{ + 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; +} + +static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) +{ + 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; +} + +static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) +{ + 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; +} + +static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) +{ + 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; +} + +static inline int blake2s_init0( blake2s_state *S ) +{ + memset( S, 0, sizeof( blake2s_state ) ); + + for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + + return 0; +} + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2s_init( blake2s_state *S, size_t outlen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + + +/* 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 ) ); + + 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 */ +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 ); +} + + +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; +} + + +static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) +{ + __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 +#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; +} + + +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 ) + { + memcpy( S->buf + left, in, fill ); // Fill buffer + 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 += inlen; // Be lazy, do not compress + 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; + 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( 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; +} + +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; + } + + 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 ) +{ + return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, (size_t)inlen, 0 ); +} +#endif + diff --git a/python/Modules/_blake2/impl/blake2sp-test.c b/python/Modules/_blake2/impl/blake2sp-test.c new file mode 100755 index 0000000..621e350 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2sp-test.c @@ -0,0 +1,43 @@ +/* + 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 . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" + +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + if( blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/python/Modules/_blake2/impl/blake2sp.c b/python/Modules/_blake2/impl/blake2sp.c new file mode 100755 index 0000000..2f32bf3 --- /dev/null +++ b/python/Modules/_blake2/impl/blake2sp.c @@ -0,0 +1,274 @@ +/* + 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 . +*/ + +#include +#include +#include + +#if defined(_OPENMP) +#include +#endif + +#include "blake2.h" +#include "blake2-impl.h" + +#define PARALLELISM_DEGREE 8 + +static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) +{ + blake2s_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + P->leaf_length = 0; + store48( P->node_offset, offset ); + P->node_depth = 0; + P->inner_length = BLAKE2S_OUTBYTES; + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2s_init_param( S, P ); + S->outlen = P->inner_length; + return 0; +} + +static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen ) +{ + blake2s_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + P->leaf_length = 0; + store48( P->node_offset, 0ULL ); + P->node_depth = 1; + P->inner_length = BLAKE2S_OUTBYTES; + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2s_init_param( S, P ); + S->outlen = P->digest_length; + return 0; +} + + +int blake2sp_init( blake2sp_state *S, size_t outlen ) +{ + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2sp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + return 0; +} + +int blake2sp_init_key( blake2sp_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; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2sp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + + +int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen ) +{ + size_t left = S->buflen; + size_t fill = sizeof( S->buf ) - left; + + if( left && inlen >= fill ) + { + memcpy( S->buf + left, in, fill ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); + + in += fill; + inlen -= fill; + left = 0; + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S) +#else + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2S_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) + { + blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + } + } + + in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); + inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + + if( inlen > 0 ) + memcpy( S->buf + left, in, inlen ); + + S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; + return 0; +} + + +int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; + + if(S->outlen != outlen) return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + { + if( S->buflen > i * BLAKE2S_BLOCKBYTES ) + { + size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; + + if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; + + blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); + } + + blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); + } + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); + + blake2s_final( S->R, out, outlen ); + return 0; +} + + +int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; + blake2s_state S[PARALLELISM_DEGREE][1]; + blake2s_state FS[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; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2sp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node + + if( keylen > 0 ) + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S,hash) +#else + + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2S_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) + { + blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + } + + if( inlen__ > id__ * BLAKE2S_BLOCKBYTES ) + { + const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES; + const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; + blake2s_update( S[id__], in__, len ); + } + + blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES ); + } + + if( blake2sp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + FS->last_node = 1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); + + return blake2s_final( FS, out, outlen ); +} + + + + diff --git a/python/Modules/_bz2module.c b/python/Modules/_bz2module.c new file mode 100755 index 0000000..b8a10ba --- /dev/null +++ b/python/Modules/_bz2module.c @@ -0,0 +1,765 @@ +// /* _bz2 - Low-level Python interface to libbzip2. */ + +// #define PY_SSIZE_T_CLEAN + +// #include "Python.h" +// #include "structmember.h" + +// #include "pythread.h" + +// #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_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_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 */ +// _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 struct PyModuleDef _bz2module = { +// PyModuleDef_HEAD_INIT, +// "_bz2", +// NULL, +// -1, +// NULL, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit__bz2(void) +// { +// PyObject *m; + +// if (PyType_Ready(&BZ2Compressor_Type) < 0) +// return NULL; +// if (PyType_Ready(&BZ2Decompressor_Type) < 0) +// return NULL; + +// m = PyModule_Create(&_bz2module); +// if (m == NULL) +// return NULL; + +// Py_INCREF(&BZ2Compressor_Type); +// PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Compressor_Type); + +// Py_INCREF(&BZ2Decompressor_Type); +// PyModule_AddObject(m, "BZ2Decompressor", +// (PyObject *)&BZ2Decompressor_Type); + +// return m; +// } diff --git a/python/Modules/_codecsmodule.c b/python/Modules/_codecsmodule.c new file mode 100755 index 0000000..a8ffb69 --- /dev/null +++ b/python/Modules/_codecsmodule.c @@ -0,0 +1,1058 @@ +/* ------------------------------------------------------------------------ + + _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}) + 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 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') + errors: str(accept={str, NoneType}) = None + / +[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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}) + errors: str(accept={str, NoneType}) = None + / +[clinic start generated code]*/ + +static PyObject * +_codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=3ca3c917176b82ab input=8328081a3a569bd6]*/ +{ + PyObject *decoded = PyUnicode_DecodeUnicodeEscape(data->buf, data->len, + errors); + return codec_tuple(decoded, data->len); +} + +/*[clinic input] +_codecs.raw_unicode_escape_decode + data: Py_buffer(accept={str, buffer}) + errors: str(accept={str, NoneType}) = None + / +[clinic start generated code]*/ + +static PyObject * +_codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=c98eeb56028070a6 input=d2f5159ce3b3392f]*/ +{ + PyObject *decoded = PyUnicode_DecodeRawUnicodeEscape(data->buf, data->len, + errors); + return codec_tuple(decoded, data->len); +} + +/*[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 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 + 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 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 + 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 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 + 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) +/*[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 + 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) +/*[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 + 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) +/*[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}) + 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 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 + 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 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 + 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 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 + 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) +/*[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 + 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 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 + 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 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 + 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) +/*[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 + 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 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 + 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 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 + 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 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 + 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 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 + 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 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 + errors: str(accept={str, NoneType}) = None + / +[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 + 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 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 + errors: str(accept={str, NoneType}) = None + / +[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 + errors: str(accept={str, NoneType}) = None + / +[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 + 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 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 */ +}; + +static struct PyModuleDef codecsmodule = { + PyModuleDef_HEAD_INIT, + "_codecs", + NULL, + -1, + _codecs_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__codecs(void) +{ + return PyModule_Create(&codecsmodule); +} diff --git a/python/Modules/_collectionsmodule.c b/python/Modules/_collectionsmodule.c new file mode 100755 index 0000000..cc2b90e --- /dev/null +++ b/python/Modules/_collectionsmodule.c @@ -0,0 +1,2577 @@ +#include "Python.h" +#include "structmember.h" + +#ifdef STDC_HEADERS +#include +#else +#include /* For size_t */ +#endif + +/*[clinic input] +module _collections +class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a8ece4ccad7e30ac]*/ + +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); + Py_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--; + Py_SIZE(deque)--; + 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_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; + } + Py_SIZE(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; + } + Py_SIZE(deque)++; + 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) { + 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 * +deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored)) +{ + PyObject *result; + dequeobject *old_deque = (dequeobject *)deque; + if (Py_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) + result = PyObject_CallFunctionObjArgs((PyObject *)(Py_TYPE(deque)), + deque, NULL); + 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", + other->ob_type->tp_name); + } + 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); + Py_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_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) { + 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; + } + } + 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; + + 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]; + 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}, + {"__copy__", deque_copy, + 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}, + {"index", (PyCFunction)(void(*)(void))deque_index, + 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}, + {"rotate", (PyCFunction)(void(*)(void))deque_rotate, + METH_FASTCALL, rotate_doc}, + {"__sizeof__", (PyCFunction)deque_sizeof, + METH_NOARGS, sizeof_doc}, + {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_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 * +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 * +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 */ + 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, /* 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); + + 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 */ + 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, /* 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 = PyEval_CallObject(factory, NULL); + if (value == NULL) + return value; + if (PyObject_SetItem((PyObject *)dd, key, value) < 0) { + Py_DECREF(value); + return NULL; + } + return value; +} + +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(). + */ + + if (dd->default_factory == NULL) + return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), Py_None, dd, NULL); + return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), + dd->default_factory, dd, NULL); +} + +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; + items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, NULL); + 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}, + {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 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[, ...]) --> 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 */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)defdict_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 */ + 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 + / + +Count elements in the iterable, updating the mapping +[clinic start generated code]*/ + +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__); + 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; +} + +/* Helper function for namedtuple() ************************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t index; + PyObject* doc; +} _tuplegetterobject; + +/*[clinic input] +@classmethod +_tuplegetter.__new__ as tuplegetter_new + + index: Py_ssize_t + doc: object + / +[clinic start generated code]*/ + +static PyObject * +tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc) +/*[clinic end generated code: output=014be444ad80263f input=87c576a5bdbc0bbb]*/ +{ + _tuplegetterobject* self; + self = (_tuplegetterobject *)type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + self->index = index; + Py_INCREF(doc); + self->doc = doc; + return (PyObject *)self; +} + +static PyObject * +tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + Py_ssize_t index = ((_tuplegetterobject*)self)->index; + PyObject *result; + + if (obj == NULL) { + Py_INCREF(self); + return self; + } + if (!PyTuple_Check(obj)) { + if (obj == Py_None) { + Py_INCREF(self); + return self; + } + PyErr_Format(PyExc_TypeError, + "descriptor for index '%zd' for tuple subclasses " + "doesn't apply to '%s' object", + index, + obj->ob_type->tp_name); + return NULL; + } + + if (!valid_index(index, PyTuple_GET_SIZE(obj))) { + PyErr_SetString(PyExc_IndexError, "tuple index out of range"); + return NULL; + } + + result = PyTuple_GET_ITEM(obj, index); + Py_INCREF(result); + return result; +} + +static int +tuplegetter_descr_set(PyObject *self, PyObject *obj, PyObject *value) +{ + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, "can't delete attribute"); + } else { + PyErr_SetString(PyExc_AttributeError, "can't set attribute"); + } + return -1; +} + +static int +tuplegetter_traverse(PyObject *self, visitproc visit, void *arg) +{ + _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self; + Py_VISIT(tuplegetter->doc); + return 0; +} + +static int +tuplegetter_clear(PyObject *self) +{ + _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self; + Py_CLEAR(tuplegetter->doc); + return 0; +} + +static void +tuplegetter_dealloc(_tuplegetterobject *self) +{ + PyObject_GC_UnTrack(self); + tuplegetter_clear((PyObject*)self); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject* +tuplegetter_reduce(_tuplegetterobject *self, PyObject *Py_UNUSED(ignored)) +{ + return Py_BuildValue("(O(nO))", (PyObject*) Py_TYPE(self), self->index, self->doc); +} + + +static PyMemberDef tuplegetter_members[] = { + {"__doc__", T_OBJECT, offsetof(_tuplegetterobject, doc), 0}, + {0} +}; + +static PyMethodDef tuplegetter_methods[] = { + {"__reduce__", (PyCFunction)tuplegetter_reduce, METH_NOARGS, NULL}, + {NULL}, +}; + +static PyTypeObject tuplegetter_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_collections._tuplegetter", /* tp_name */ + sizeof(_tuplegetterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)tuplegetter_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)tuplegetter_traverse, /* tp_traverse */ + (inquiry)tuplegetter_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + tuplegetter_methods, /* tp_methods */ + tuplegetter_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + tuplegetter_descr_get, /* tp_descr_get */ + tuplegetter_descr_set, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + tuplegetter_new, /* tp_new */ + 0, +}; + + +/* module level code ********************************************************/ + +PyDoc_STRVAR(module_doc, +"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 module_functions[] = { + _COLLECTIONS__COUNT_ELEMENTS_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static struct PyModuleDef _collectionsmodule = { + PyModuleDef_HEAD_INIT, + "_collections", + module_doc, + -1, + module_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__collections(void) +{ + PyObject *m; + + m = PyModule_Create(&_collectionsmodule); + if (m == NULL) + return NULL; + + if (PyType_Ready(&deque_type) < 0) + return NULL; + Py_INCREF(&deque_type); + PyModule_AddObject(m, "deque", (PyObject *)&deque_type); + + defdict_type.tp_base = &PyDict_Type; + if (PyType_Ready(&defdict_type) < 0) + return NULL; + Py_INCREF(&defdict_type); + PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type); + + Py_INCREF(&PyODict_Type); + PyModule_AddObject(m, "OrderedDict", (PyObject *)&PyODict_Type); + + if (PyType_Ready(&dequeiter_type) < 0) + return NULL; + Py_INCREF(&dequeiter_type); + PyModule_AddObject(m, "_deque_iterator", (PyObject *)&dequeiter_type); + + if (PyType_Ready(&dequereviter_type) < 0) + return NULL; + Py_INCREF(&dequereviter_type); + PyModule_AddObject(m, "_deque_reverse_iterator", (PyObject *)&dequereviter_type); + + if (PyType_Ready(&tuplegetter_type) < 0) + return NULL; + Py_INCREF(&tuplegetter_type); + PyModule_AddObject(m, "_tuplegetter", (PyObject *)&tuplegetter_type); + + return m; +} diff --git a/python/Modules/_contextvarsmodule.c b/python/Modules/_contextvarsmodule.c new file mode 100755 index 0000000..1abcdbf --- /dev/null +++ b/python/Modules/_contextvarsmodule.c @@ -0,0 +1,78 @@ +#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 struct PyModuleDef _contextvarsmodule = { + PyModuleDef_HEAD_INIT, /* m_base */ + "_contextvars", /* m_name */ + module_doc, /* m_doc */ + -1, /* m_size */ + _contextvars_methods, /* m_methods */ + NULL, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC +PyInit__contextvars(void) +{ + PyObject *m = PyModule_Create(&_contextvarsmodule); + if (m == NULL) { + return NULL; + } + + Py_INCREF(&PyContext_Type); + if (PyModule_AddObject(m, "Context", + (PyObject *)&PyContext_Type) < 0) + { + Py_DECREF(&PyContext_Type); + Py_DECREF(m); + return NULL; + } + + Py_INCREF(&PyContextVar_Type); + if (PyModule_AddObject(m, "ContextVar", + (PyObject *)&PyContextVar_Type) < 0) + { + Py_DECREF(&PyContextVar_Type); + Py_DECREF(m); + return NULL; + } + + Py_INCREF(&PyContextToken_Type); + if (PyModule_AddObject(m, "Token", + (PyObject *)&PyContextToken_Type) < 0) + { + Py_DECREF(&PyContextToken_Type); + Py_DECREF(m); + return NULL; + } + + return m; +} diff --git a/python/Modules/_cryptmodule.c b/python/Modules/_cryptmodule.c new file mode 100755 index 0000000..5d03f45 --- /dev/null +++ b/python/Modules/_cryptmodule.c @@ -0,0 +1,71 @@ +/* cryptmodule.c - by Steve Majewski + */ + +#include "Python.h" + +#include + +/* Module crypt */ + +/*[clinic input] +module crypt +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c6252cf4f2f2ae81]*/ + +#include "clinic/_cryptmodule.c.h" + +/*[clinic input] +crypt.crypt + + word: str + salt: str + / + +Hash a *word* with the given *salt* and return the hashed password. + +*word* will usually be a user's password. *salt* (either a random 2 or 16 +character string, possibly prefixed with $digit$ to indicate the method) +will be used to perturb the encryption algorithm and produce distinct +results for a given *word*. + +[clinic start generated code]*/ + +static PyObject * +crypt_crypt_impl(PyObject *module, const char *word, const char *salt) +/*[clinic end generated code: output=0512284a03d2803c input=0e8edec9c364352b]*/ +{ + char *crypt_result; +#ifdef HAVE_CRYPT_R + struct crypt_data data; + memset(&data, 0, sizeof(data)); + crypt_result = crypt_r(word, salt, &data); +#else + crypt_result = crypt(word, salt); +#endif + return Py_BuildValue("s", crypt_result); +} + + +static PyMethodDef crypt_methods[] = { + CRYPT_CRYPT_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef cryptmodule = { + PyModuleDef_HEAD_INIT, + "_crypt", + NULL, + -1, + crypt_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__crypt(void) +{ + return PyModule_Create(&cryptmodule); +} diff --git a/python/Modules/_csv.c b/python/Modules/_csv.c new file mode 100755 index 0000000..069ec96 --- /dev/null +++ b/python/Modules/_csv.c @@ -0,0 +1,1680 @@ +/* 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" +#include + + +typedef struct { + PyObject *error_obj; /* CSV exception */ + PyObject *dialects; /* Dialect registry */ + long field_limit; /* max parsed field size */ +} _csvstate; + +#define _csvstate(o) ((_csvstate *)PyModule_GetState(o)) + +static int +_csv_clear(PyObject *m) +{ + Py_CLEAR(_csvstate(m)->error_obj); + Py_CLEAR(_csvstate(m)->dialects); + return 0; +} + +static int +_csv_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(_csvstate(m)->error_obj); + Py_VISIT(_csvstate(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 + + 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 */ + 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; + +#define ReaderObject_Check(v) (Py_TYPE(v) == &Reader_Type) + +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; + + 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 +_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; + *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 +_set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) +{ + if (src == NULL) + *target = dflt; + else { + *target = '\0'; + if (src != Py_None) { + Py_ssize_t len; + if (!PyUnicode_Check(src)) { + PyErr_Format(PyExc_TypeError, + "\"%s\" must be string, not %.200s", name, + src->ob_type->tp_name); + return -1; + } + len = PyUnicode_GetLength(src); + 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 > 0) + *target = PyUnicode_READ_CHAR(src, 0); + } + } + return 0; +} + +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[] = { + { "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) { +#define DIALECT_GETATTR(v, n) \ + if (v == NULL) \ + v = PyObject_GetAttrString(dialect, n) + 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"); + PyErr_Clear(); + } + + /* 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, "escapechar", &self->escapechar, escapechar, 0); + DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n"); + DIASET(_set_char, "quotechar", &self->quotechar, quotechar, '"'); + 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 */ + 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 */ + (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_FastCallDict(type, &dialect_inst, 1, kwargs); + } + else { + return _PyObject_FastCallDict(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; + 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?)", + lineobj->ob_type->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, + "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*/ + 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*/ + (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, 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; + 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; + 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); + if (iter == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Format(_csvstate_global->error_obj, + "iterable expected, not %.200s", + Py_TYPE(seq)->tp_name); + } + 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. + */ + if (!join_append_lineterminator(self)) { + return NULL; + } + + line = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, + (void *) self->rec, self->rec_len); + if (line == NULL) { + return NULL; + } + result = PyObject_CallFunctionObjArgs(self->write, line, NULL); + 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); + Py_VISIT(self->write); + 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*/ + 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*/ + (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; + } + 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) +{ + 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" +" * quotechar - specifies a one-character string to use as the\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" +" * 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" +" * 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[] = { + { "reader", (PyCFunction)(void(*)(void))csv_reader, + 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}, + { "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(&Dialect_Type) < 0) + return NULL; + + 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 */ + _csvstate(module)->field_limit = 128 * 1024; + /* Do I still need to add this var to the Module Dict? */ + + /* Add _dialects dictionary */ + _csvstate(module)->dialects = PyDict_New(); + if (_csvstate(module)->dialects == NULL) + return NULL; + Py_INCREF(_csvstate(module)->dialects); + if (PyModule_AddObject(module, "_dialects", _csvstate(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; + } + + /* Add the Dialect type */ + Py_INCREF(&Dialect_Type); + if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type)) + return NULL; + + /* Add the CSV exception object to the module. */ + _csvstate(module)->error_obj = PyErr_NewException("_csv.Error", NULL, NULL); + if (_csvstate(module)->error_obj == NULL) + return NULL; + Py_INCREF(_csvstate(module)->error_obj); + PyModule_AddObject(module, "Error", _csvstate(module)->error_obj); + return module; +} diff --git a/python/Modules/_ctypes/_ctypes.c b/python/Modules/_ctypes/_ctypes.c new file mode 100755 index 0000000..b10b867 --- /dev/null +++ b/python/Modules/_ctypes/_ctypes.c @@ -0,0 +1,5873 @@ +/* + 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" + +#include +#ifdef MS_WIN32 +#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 */ + 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 */ + _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; +} + +/* StructParamObject and StructParam_Type are used in _ctypes_callproc() + for argument.keep to call PyMem_Free(ptr) on Py_DECREF(argument). + + StructUnionType_paramfunc() creates such object when a ctypes Structure is + passed by copy to a C function. */ +typedef struct { + PyObject_HEAD + void *ptr; +} StructParamObject; + + +static void +StructParam_dealloc(PyObject *myself) +{ + StructParamObject *self = (StructParamObject *)myself; + PyMem_Free(self->ptr); + Py_TYPE(self)->tp_free(myself); +} + + +static PyTypeObject StructParam_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "_ctypes.StructParam_Type", + .tp_basicsize = sizeof(StructParamObject), + .tp_dealloc = StructParam_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + + +/* + 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; + void *ptr; + + if ((size_t)self->b_size > sizeof(void*)) { + ptr = PyMem_Malloc(self->b_size); + if (ptr == NULL) { + return NULL; + } + memcpy(ptr, self->b_ptr, self->b_size); + + /* Create a Python object which calls PyMem_Free(ptr) in + its deallocator. The object will be destroyed + at _ctypes_callproc() cleanup. */ + obj = (&StructParam_Type)->tp_alloc(&StructParam_Type, 0); + if (obj == NULL) { + PyMem_Free(ptr); + return NULL; + } + + StructParamObject *struct_param = (StructParamObject *)obj; + struct_param->ptr = ptr; + } else { + ptr = self->b_ptr; + obj = (PyObject *)self; + Py_INCREF(obj); + } + + parg = PyCArgObject_new(); + if (parg == NULL) { + Py_DECREF(obj); + 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->value.p = ptr; + 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; + _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 */ + if (_PyDict_GetItemIdWithError(result->tp_dict, &PyId__abstract_)) + 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; + } + 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; + + fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); + if (fields) { + if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) { + Py_DECREF(result); + return NULL; + } + return (PyObject *)result; + } + else if (PyErr_Occurred()) { + Py_DECREF(result); + 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"); + 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; + } + + 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; + } + + 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) +{ + _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; + } + 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_CallObject( + (PyObject *)&PyCStgDict_Type, NULL); + 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)) +{ + 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_CallObject( + (PyObject *)&PyCStgDict_Type, NULL); + 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_CallObject( + (PyObject *)&PyCStgDict_Type, NULL); + 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_CallObject( + (PyObject *)&PyCStgDict_Type, NULL); + 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_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL); + 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; + + 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 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 */ + 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)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; + } + + 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_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"); + 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, 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_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) +{ + 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 (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. +*/ + PyEval_InitThreads(); + 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_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); + + Py_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); + + Py_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); + + Py_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); + + Py_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); + + Py_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; + + 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: +*/ diff --git a/python/Modules/_ctypes/_ctypes_test.c b/python/Modules/_ctypes/_ctypes_test.c new file mode 100755 index 0000000..3392208 --- /dev/null +++ b/python/Modules/_ctypes/_ctypes_test.c @@ -0,0 +1,1080 @@ +#include + +#ifdef MS_WIN32 +#include +#endif + +#if defined(MS_WIN32) || defined(__CYGWIN__) +#define EXPORT(x) __declspec(dllexport) x +#else +#define EXPORT(x) x +#endif + +/* some functions handy for testing */ + +EXPORT(int) +_testfunc_cbk_reg_int(int a, int b, int c, int d, int e, + int (*func)(int, int, int, int, int)) +{ + return func(a*a, b*b, c*c, d*d, e*e); +} + +EXPORT(double) +_testfunc_cbk_reg_double(double a, double b, double c, double d, double e, + double (*func)(double, double, double, double, double)) +{ + return func(a*a, b*b, c*c, d*d, e*e); +} + +/* + * This structure should be the same as in test_callbacks.py and the + * method test_callback_large_struct. See issues 17310 and 20160: the + * structure must be larger than 8 bytes long. + */ + +typedef struct { + unsigned long first; + unsigned long second; + unsigned long third; +} Test; + +EXPORT(void) +_testfunc_cbk_large_struct(Test in, void (*func)(Test)) +{ + func(in); +} + +/* + * See issue 29565. Update a structure passed by value; + * the caller should not see any change. + */ + +EXPORT(void) +_testfunc_large_struct_update_value(Test in) +{ + ((volatile Test *)&in)->first = 0x0badf00d; + ((volatile Test *)&in)->second = 0x0badf00d; + ((volatile Test *)&in)->third = 0x0badf00d; +} + +typedef struct { + unsigned int first; + unsigned int second; +} TestReg; + + +EXPORT(TestReg) last_tfrsuv_arg = {0}; + + +EXPORT(void) +_testfunc_reg_struct_update_value(TestReg in) +{ + last_tfrsuv_arg = in; + ((volatile TestReg *)&in)->first = 0x0badf00d; + ((volatile TestReg *)&in)->second = 0x0badf00d; +} + +/* + * See bpo-22273. Structs containing arrays should work on Linux 64-bit. + */ + +typedef struct { + unsigned char data[16]; +} Test2; + +EXPORT(int) +_testfunc_array_in_struct1(Test2 in) +{ + int result = 0; + + for (unsigned i = 0; i < 16; i++) + result += in.data[i]; + /* As the structure is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(in.data, 0, sizeof(in.data)); + return result; +} + +typedef struct { + double data[2]; +} Test3; + +typedef struct { + float data[2]; + float more_data[2]; +} Test3B; + +EXPORT(double) +_testfunc_array_in_struct2(Test3 in) +{ + double result = 0; + + for (unsigned i = 0; i < 2; i++) + result += in.data[i]; + /* As the structure is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(in.data, 0, sizeof(in.data)); + return result; +} + +EXPORT(double) +_testfunc_array_in_struct2a(Test3B in) +{ + double result = 0; + + for (unsigned i = 0; i < 2; i++) + result += in.data[i]; + for (unsigned i = 0; i < 2; i++) + result += in.more_data[i]; + /* As the structure is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(in.data, 0, sizeof(in.data)); + return result; +} + +typedef union { + long a_long; + struct { + int an_int; + int another_int; + } a_struct; +} Test4; + +typedef struct { + int an_int; + struct { + int an_int; + Test4 a_union; + } nested; + int another_int; +} Test5; + +EXPORT(long) +_testfunc_union_by_value1(Test4 in) { + long result = in.a_long + in.a_struct.an_int + in.a_struct.another_int; + + /* As the union/struct are passed by value, changes to them shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_union_by_value2(Test5 in) { + long result = in.an_int + in.nested.an_int; + + /* As the union/struct are passed by value, changes to them shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_union_by_reference1(Test4 *in) { + long result = in->a_long; + + memset(in, 0, sizeof(Test4)); + return result; +} + +EXPORT(long) +_testfunc_union_by_reference2(Test4 *in) { + long result = in->a_struct.an_int + in->a_struct.another_int; + + memset(in, 0, sizeof(Test4)); + return result; +} + +EXPORT(long) +_testfunc_union_by_reference3(Test5 *in) { + long result = in->an_int + in->nested.an_int + in->another_int; + + memset(in, 0, sizeof(Test5)); + return result; +} + +typedef struct { + signed int A: 1, B:2, C:3, D:2; +} Test6; + +EXPORT(long) +_testfunc_bitfield_by_value1(Test6 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_bitfield_by_reference1(Test6 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test6)); + return result; +} + +typedef struct { + unsigned int A: 1, B:2, C:3, D:2; +} Test7; + +EXPORT(long) +_testfunc_bitfield_by_reference2(Test7 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test7)); + return result; +} + +typedef union { + signed int A: 1, B:2, C:3, D:2; +} Test8; + +EXPORT(long) +_testfunc_bitfield_by_value2(Test8 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(void)testfunc_array(int values[4]) +{ + printf("testfunc_array %d %d %d %d\n", + values[0], + values[1], + values[2], + values[3]); +} + +EXPORT(long double)testfunc_Ddd(double a, double b) +{ + long double result = (long double)(a * b); + printf("testfunc_Ddd(%p, %p)\n", (void *)&a, (void *)&b); + printf("testfunc_Ddd(%g, %g)\n", a, b); + return result; +} + +EXPORT(long double)testfunc_DDD(long double a, long double b) +{ + long double result = a * b; + printf("testfunc_DDD(%p, %p)\n", (void *)&a, (void *)&b); + printf("testfunc_DDD(%Lg, %Lg)\n", a, b); + return result; +} + +EXPORT(int)testfunc_iii(int a, int b) +{ + int result = a * b; + printf("testfunc_iii(%p, %p)\n", (void *)&a, (void *)&b); + return result; +} + +EXPORT(int)myprintf(char *fmt, ...) +{ + int result; + va_list argptr; + va_start(argptr, fmt); + result = vprintf(fmt, argptr); + va_end(argptr); + return result; +} + +EXPORT(char *)my_strtok(char *token, const char *delim) +{ + return strtok(token, delim); +} + +EXPORT(char *)my_strchr(const char *s, int c) +{ + return strchr(s, c); +} + + +EXPORT(double) my_sqrt(double a) +{ + return sqrt(a); +} + +EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*)) +{ + qsort(base, num, width, compare); +} + +EXPORT(int *) _testfunc_ai8(int a[8]) +{ + return a; +} + +EXPORT(void) _testfunc_v(int a, int b, int *presult) +{ + *presult = a + b; +} + +EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d) +{ +/* printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ + return (int)(b + h + i + l + f + d); +} + +EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d) +{ +/* printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ + return (float)(b + h + i + l + f + d); +} + +EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d) +{ +/* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ + return (double)(b + h + i + l + f + d); +} + +EXPORT(long double) _testfunc_D_bhilfD(signed char b, short h, int i, long l, float f, long double d) +{ +/* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ + return (long double)(b + h + i + l + f + d); +} + +EXPORT(char *) _testfunc_p_p(void *s) +{ + return (char *)s; +} + +EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv) +{ + return argv[(*argcp)-1]; +} + +EXPORT(void *) get_strchr(void) +{ + return (void *)strchr; +} + +EXPORT(char *) my_strdup(char *src) +{ + char *dst = (char *)malloc(strlen(src)+1); + if (!dst) + return NULL; + strcpy(dst, src); + return dst; +} + +EXPORT(void)my_free(void *ptr) +{ + free(ptr); +} + +#ifdef HAVE_WCHAR_H +EXPORT(wchar_t *) my_wcsdup(wchar_t *src) +{ + size_t len = wcslen(src); + wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t)); + if (ptr == NULL) + return NULL; + memcpy(ptr, src, (len+1) * sizeof(wchar_t)); + return ptr; +} + +EXPORT(size_t) my_wcslen(wchar_t *src) +{ + return wcslen(src); +} +#endif + +#ifndef MS_WIN32 +# ifndef __stdcall +# define __stdcall /* */ +# endif +#endif + +typedef struct { + int (*c)(int, int); + int (__stdcall *s)(int, int); +} FUNCS; + +EXPORT(int) _testfunc_callfuncp(FUNCS *fp) +{ + fp->c(1, 2); + fp->s(3, 4); + return 0; +} + +EXPORT(int) _testfunc_deref_pointer(int *pi) +{ + return *pi; +} + +#ifdef MS_WIN32 +EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk) +{ + piunk->lpVtbl->AddRef(piunk); + return piunk->lpVtbl->Release(piunk); +} +#endif + +EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *)) +{ + int table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + return (*func)(table); +} + +EXPORT(long long) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f, + double d, long long q) +{ + return (long long)(b + h + i + l + f + d + q); +} + +EXPORT(long long) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d) +{ + return (long long)(b + h + i + l + f + d); +} + +EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int)) +{ + int sum = 0; + while (value != 0) { + sum += func(value); + value /= 2; + } + return sum; +} + +EXPORT(long long) _testfunc_callback_q_qf(long long value, + long long (*func)(long long)) +{ + long long sum = 0; + + while (value != 0) { + sum += func(value); + value /= 2; + } + return sum; +} + +typedef struct { + char *name; + char *value; +} SPAM; + +typedef struct { + char *name; + int num_spams; + SPAM *spams; +} EGG; + +SPAM my_spams[2] = { + { "name1", "value1" }, + { "name2", "value2" }, +}; + +EGG my_eggs[1] = { + { "first egg", 1, my_spams } +}; + +EXPORT(int) getSPAMANDEGGS(EGG **eggs) +{ + *eggs = my_eggs; + return 1; +} + +typedef struct tagpoint { + int x; + int y; +} point; + +EXPORT(int) _testfunc_byval(point in, point *pout) +{ + if (pout) { + pout->x = in.x; + pout->y = in.y; + } + return in.x + in.y; +} + +EXPORT (int) an_integer = 42; + +EXPORT(int) get_an_integer(void) +{ + return an_integer; +} + +EXPORT(double) +integrate(double a, double b, double (*f)(double), long nstep) +{ + double x, sum=0.0, dx=(b-a)/(double)nstep; + for(x=a+0.5*dx; (b-x)*(x-a)>0.0; x+=dx) + sum += f(x); + return sum/(double)nstep; +} + +typedef struct { + void (*initialize)(void *(*)(int), void(*)(void *)); +} xxx_library; + +static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *)) +{ + void *ptr; + + printf("_xxx_init got %p %p\n", (void *)Xalloc, (void *)Xfree); + printf("calling\n"); + ptr = Xalloc(32); + Xfree(ptr); + printf("calls done, ptr was %p\n", ptr); +} + +xxx_library _xxx_lib = { + _xxx_init +}; + +EXPORT(xxx_library) *library_get(void) +{ + return &_xxx_lib; +} + +#ifdef MS_WIN32 +/* See Don Box (german), pp 79ff. */ +EXPORT(void) GetString(BSTR *pbstr) +{ + *pbstr = SysAllocString(L"Goodbye!"); +} +#endif + +/* + * Some do-nothing functions, for speed tests + */ +PyObject *py_func_si(PyObject *self, PyObject *args) +{ + char *name; + int i; + if (!PyArg_ParseTuple(args, "si", &name, &i)) + return NULL; + Py_RETURN_NONE; +} + +EXPORT(void) _py_func_si(char *s, int i) +{ +} + +PyObject *py_func(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; +} + +EXPORT(void) _py_func(void) +{ +} + +EXPORT(long long) last_tf_arg_s = 0; +EXPORT(unsigned long long) last_tf_arg_u = 0; + +struct BITS { + signed int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9; +/* + * The test case needs/uses "signed short" bitfields, but the + * IBM XLC compiler does not support this + */ +#ifndef __xlc__ +#define SIGNED_SHORT_BITFIELDS + short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7; +#endif +}; + +EXPORT(void) set_bitfields(struct BITS *bits, char name, int value) +{ + switch (name) { + case 'A': bits->A = value; break; + case 'B': bits->B = value; break; + case 'C': bits->C = value; break; + case 'D': bits->D = value; break; + case 'E': bits->E = value; break; + case 'F': bits->F = value; break; + case 'G': bits->G = value; break; + case 'H': bits->H = value; break; + case 'I': bits->I = value; break; +#ifdef SIGNED_SHORT_BITFIELDS + case 'M': bits->M = value; break; + case 'N': bits->N = value; break; + case 'O': bits->O = value; break; + case 'P': bits->P = value; break; + case 'Q': bits->Q = value; break; + case 'R': bits->R = value; break; + case 'S': bits->S = value; break; +#endif + } +} + +EXPORT(int) unpack_bitfields(struct BITS *bits, char name) +{ + switch (name) { + case 'A': return bits->A; + case 'B': return bits->B; + case 'C': return bits->C; + case 'D': return bits->D; + case 'E': return bits->E; + case 'F': return bits->F; + case 'G': return bits->G; + case 'H': return bits->H; + case 'I': return bits->I; + +#ifdef SIGNED_SHORT_BITFIELDS + case 'M': return bits->M; + case 'N': return bits->N; + case 'O': return bits->O; + case 'P': return bits->P; + case 'Q': return bits->Q; + case 'R': return bits->R; + case 'S': return bits->S; +#endif + } + return 999; +} + +static PyMethodDef module_methods[] = { +/* {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS}, + {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS}, +*/ + {"func_si", py_func_si, METH_VARARGS}, + {"func", py_func, METH_NOARGS}, + { NULL, NULL, 0, NULL}, +}; + +#define S last_tf_arg_s = (long long)c +#define U last_tf_arg_u = (unsigned long long)c + +EXPORT(signed char) tf_b(signed char c) { S; return c/3; } +EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; } +EXPORT(short) tf_h(short c) { S; return c/3; } +EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; } +EXPORT(int) tf_i(int c) { S; return c/3; } +EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; } +EXPORT(long) tf_l(long c) { S; return c/3; } +EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; } +EXPORT(long long) tf_q(long long c) { S; return c/3; } +EXPORT(unsigned long long) tf_Q(unsigned long long c) { U; return c/3; } +EXPORT(float) tf_f(float c) { S; return c/3; } +EXPORT(double) tf_d(double c) { S; return c/3; } +EXPORT(long double) tf_D(long double c) { S; return c/3; } + +#ifdef MS_WIN32 +EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; } +EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; } +EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; } +EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; } +EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; } +EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; } +EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; } +EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; } +EXPORT(long long) __stdcall s_tf_q(long long c) { S; return c/3; } +EXPORT(unsigned long long) __stdcall s_tf_Q(unsigned long long c) { U; return c/3; } +EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; } +EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; } +EXPORT(long double) __stdcall s_tf_D(long double c) { S; return c/3; } +#endif +/*******/ + +EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; } +EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; } +EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; } +EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; } +EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; } +EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; } +EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; } +EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; } +EXPORT(long long) tf_bq(signed char x, long long c) { S; return c/3; } +EXPORT(unsigned long long) tf_bQ(signed char x, unsigned long long c) { U; return c/3; } +EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; } +EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; } +EXPORT(long double) tf_bD(signed char x, long double c) { S; return c/3; } +EXPORT(void) tv_i(int c) { S; return; } + +#ifdef MS_WIN32 +EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; } +EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; } +EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; } +EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; } +EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; } +EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; } +EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; } +EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; } +EXPORT(long long) __stdcall s_tf_bq(signed char x, long long c) { S; return c/3; } +EXPORT(unsigned long long) __stdcall s_tf_bQ(signed char x, unsigned long long c) { U; return c/3; } +EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; } +EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; } +EXPORT(long double) __stdcall s_tf_bD(signed char x, long double c) { S; return c/3; } +EXPORT(void) __stdcall s_tv_i(int c) { S; return; } +#endif + +/********/ + +#ifndef MS_WIN32 + +typedef struct { + long x; + long y; +} POINT; + +typedef struct { + long left; + long top; + long right; + long bottom; +} RECT; + +#endif + +EXPORT(int) PointInRect(RECT *prc, POINT pt) +{ + if (pt.x < prc->left) + return 0; + if (pt.x > prc->right) + return 0; + if (pt.y < prc->top) + return 0; + if (pt.y > prc->bottom) + return 0; + return 1; +} + +EXPORT(long left = 10); +EXPORT(long top = 20); +EXPORT(long right = 30); +EXPORT(long bottom = 40); + +EXPORT(RECT) ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr, + RECT *er, POINT fp, RECT gr) +{ + /*Check input */ + if (ar.left + br->left + dr.left + er->left + gr.left != left * 5) + { + ar.left = 100; + return ar; + } + if (ar.right + br->right + dr.right + er->right + gr.right != right * 5) + { + ar.right = 100; + return ar; + } + if (cp.x != fp.x) + { + ar.left = -100; + } + if (cp.y != fp.y) + { + ar.left = -200; + } + switch(i) + { + case 0: + return ar; + break; + case 1: + return dr; + break; + case 2: + return gr; + break; + + } + return ar; +} + +typedef struct { + short x; + short y; +} S2H; + +EXPORT(S2H) ret_2h_func(S2H inp) +{ + inp.x *= 2; + inp.y *= 3; + return inp; +} + +typedef struct { + int a, b, c, d, e, f, g, h; +} S8I; + +EXPORT(S8I) ret_8i_func(S8I inp) +{ + inp.a *= 2; + inp.b *= 3; + inp.c *= 4; + inp.d *= 5; + inp.e *= 6; + inp.f *= 7; + inp.g *= 8; + inp.h *= 9; + return inp; +} + +EXPORT(int) GetRectangle(int flag, RECT *prect) +{ + if (flag == 0) + return 0; + prect->left = (int)flag; + prect->top = (int)flag + 1; + prect->right = (int)flag + 2; + prect->bottom = (int)flag + 3; + return 1; +} + +EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj) +{ + *pi += a; + *pj += b; +} + +#ifdef MS_WIN32 + +typedef struct { + char f1; +} Size1; + +typedef struct { + char f1; + char f2; +} Size2; + +typedef struct { + char f1; + char f2; + char f3; +} Size3; + +typedef struct { + char f1; + char f2; + char f3; + char f4; +} Size4; + +typedef struct { + char f1; + char f2; + char f3; + char f4; + char f5; +} Size5; + +typedef struct { + char f1; + char f2; + char f3; + char f4; + char f5; + char f6; +} Size6; + +typedef struct { + char f1; + char f2; + char f3; + char f4; + char f5; + char f6; + char f7; +} Size7; + +typedef struct { + char f1; + char f2; + char f3; + char f4; + char f5; + char f6; + char f7; + char f8; +} Size8; + +typedef struct { + char f1; + char f2; + char f3; + char f4; + char f5; + char f6; + char f7; + char f8; + char f9; +} Size9; + +typedef struct { + char f1; + char f2; + char f3; + char f4; + char f5; + char f6; + char f7; + char f8; + char f9; + char f10; +} Size10; + +EXPORT(Size1) TestSize1() { + Size1 f; + f.f1 = 'a'; + return f; +} + +EXPORT(Size2) TestSize2() { + Size2 f; + f.f1 = 'a'; + f.f2 = 'b'; + return f; +} + +EXPORT(Size3) TestSize3() { + Size3 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + return f; +} + +EXPORT(Size4) TestSize4() { + Size4 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + f.f4 = 'd'; + return f; +} + +EXPORT(Size5) TestSize5() { + Size5 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + f.f4 = 'd'; + f.f5 = 'e'; + return f; +} + +EXPORT(Size6) TestSize6() { + Size6 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + f.f4 = 'd'; + f.f5 = 'e'; + f.f6 = 'f'; + return f; +} + +EXPORT(Size7) TestSize7() { + Size7 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + f.f4 = 'd'; + f.f5 = 'e'; + f.f6 = 'f'; + f.f7 = 'g'; + return f; +} + +EXPORT(Size8) TestSize8() { + Size8 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + f.f4 = 'd'; + f.f5 = 'e'; + f.f6 = 'f'; + f.f7 = 'g'; + f.f8 = 'h'; + return f; +} + +EXPORT(Size9) TestSize9() { + Size9 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + f.f4 = 'd'; + f.f5 = 'e'; + f.f6 = 'f'; + f.f7 = 'g'; + f.f8 = 'h'; + f.f9 = 'i'; + return f; +} + +EXPORT(Size10) TestSize10() { + Size10 f; + f.f1 = 'a'; + f.f2 = 'b'; + f.f3 = 'c'; + f.f4 = 'd'; + f.f5 = 'e'; + f.f6 = 'f'; + f.f7 = 'g'; + f.f8 = 'h'; + f.f9 = 'i'; + f.f10 = 'j'; + return f; +} + +#endif + +#ifdef MS_WIN32 +EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); } +EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); } +#endif + +#ifdef MS_WIN32 +/* Should port this */ +#include +#include + +EXPORT (HRESULT) KeepObject(IUnknown *punk) +{ + static IUnknown *pobj; + if (punk) + punk->lpVtbl->AddRef(punk); + if (pobj) + pobj->lpVtbl->Release(pobj); + pobj = punk; + return S_OK; +} + +#endif + + +static struct PyModuleDef _ctypes_testmodule = { + PyModuleDef_HEAD_INIT, + "_ctypes_test", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__ctypes_test(void) +{ + return PyModule_Create(&_ctypes_testmodule); +} diff --git a/python/Modules/_ctypes/_ctypes_test.h b/python/Modules/_ctypes/_ctypes_test.h new file mode 100755 index 0000000..060d4d6 --- /dev/null +++ b/python/Modules/_ctypes/_ctypes_test.h @@ -0,0 +1 @@ +extern int _testfunc_i_bhilfd(char b, short h, int i, long l, float f, double d); diff --git a/python/Modules/_ctypes/callbacks.c b/python/Modules/_ctypes/callbacks.c new file mode 100755 index 0000000..b826ee3 --- /dev/null +++ b/python/Modules/_ctypes/callbacks.c @@ -0,0 +1,615 @@ +#include "Python.h" +#include "frameobject.h" + +#include + +#include +#ifdef MS_WIN32 +#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 */ + 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 */ + "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); + 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; + _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; + } + + 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) { + 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) { + PrintError("create argument %zd:\n", i); + 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"); + 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); + 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); + + if (restype != &ffi_type_void && result) { + assert(setfunc); + +#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; + } +#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) { + /* Could not convert callback result. */ + _PyErr_WriteUnraisableMsg("on converting result " + "of ctypes callback function", + callable); + } + else if (keep == Py_None) { + /* Nothing to keep */ + Py_DECREF(keep); + } + 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)); + + 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 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 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, *) +# else +# define HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME 1 +# endif + if (HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME) { + result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn, + p, + p->pcl_exec); + } else +#endif + { +#if USING_APPLE_OS_LIBFFI && defined(__arm64__) + PyErr_Format(PyExc_NotImplementedError, "ffi_prep_closure_loc() is missing"); + goto error; +#else +#ifdef MACOSX + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p); + +#ifdef MACOSX + #pragma clang diagnostic pop +#endif + +#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()) { + Py_Initialize(); + PyEval_InitThreads(); + } +} + +/******************************************************************/ + +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/python/Modules/_ctypes/callproc.c b/python/Modules/_ctypes/callproc.c new file mode 100755 index 0000000..e326cd8 --- /dev/null +++ b/python/Modules/_ctypes/callproc.c @@ -0,0 +1,2020 @@ +/* + * 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" + +#include + +#ifdef MS_WIN32 +#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. + + 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; + } + 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); + } + else if (!PyErr_Occurred()) { + void *space = PyMem_Malloc(sizeof(int) * 2); + if (space == NULL) + return NULL; + memset(space, 0, sizeof(int) * 2); + 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; + + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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; + 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) +{ + 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': + return PyUnicode_FromFormat("", + self->tag, self->value.b); + case 'h': + case 'H': + return PyUnicode_FromFormat("", + self->tag, self->value.h); + case 'i': + case 'I': + return PyUnicode_FromFormat("", + self->tag, self->value.i); + case 'l': + case 'L': + return PyUnicode_FromFormat("", + self->tag, self->value.l); + + case 'q': + case 'Q': + return PyUnicode_FromFormat("", + 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) { + return NULL; + } + PyObject *result = PyUnicode_FromFormat("", self->tag, f); + Py_DECREF(f); + return result; + } + case 'c': + if (is_literal_char((unsigned char)self->value.c)) { + return PyUnicode_FromFormat("", + 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': + return PyUnicode_FromFormat("", + 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 { + 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 */ + 0, /* tp_vectorcall_offset */ + 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 + + { + _Py_IDENTIFIER(_as_parameter_); + 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; + } +} + +#if defined(MS_WIN32) && !defined(_WIN32_WCE) +/* +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 +*/ +int can_return_struct_as_int(size_t s) +{ + 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 +} +#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, + 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; +#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; +#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) && !defined(_M_ARM) + 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, *) +# elif HAVE_FFI_PREP_CIF_VAR +# define HAVE_FFI_PREP_CIF_VAR_RUNTIME true +# else +# define HAVE_FFI_PREP_CIF_VAR_RUNTIME false +# endif + + /* Even on Apple-arm64 the calling convention for variadic functions conincides + * with the standard calling convention in the case that the function called + * only with its fixed arguments. Thus, we do not need a special flag to be + * set on variadic functions. We treat a function as variadic if it is called + * with a nonzero number of variadic arguments */ + bool is_variadic = (argtypecount != 0 && argcount > argtypecount); + (void) is_variadic; + +#if defined(__APPLE__) && defined(__arm64__) + if (is_variadic) { + if (HAVE_FFI_PREP_CIF_VAR_RUNTIME) { + } else { + 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) { + if (FFI_OK != ffi_prep_cif_var(&cif, + cc, + argtypecount, + argcount, + restype, + atypes)) { + PyErr_SetString(PyExc_RuntimeError, + "ffi_prep_cif_var failed"); + return -1; + } + } else { + if (FFI_OK != ffi_prep_cif(&cif, + cc, + argcount, + restype, + atypes)) { + PyErr_SetString(PyExc_RuntimeError, + "ffi_prep_cif failed"); + return -1; + } + } + } else +#endif + + { + if (FFI_OK != ffi_prep_cif(&cif, + cc, + argcount, + restype, + atypes)) { + PyErr_SetString(PyExc_RuntimeError, + "ffi_prep_cif failed"); + return -1; + } + } + + 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_CallFunctionObjArgs(checker, retval, NULL); + 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`, + * to avoid allocating a massive buffer on the stack. + */ +#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 + + if (argcount > CTYPES_MAX_ARGCOUNT) + { + PyErr_Format(PyExc_ArgError, "too many arguments (%zi), maximum is %i", + argcount, CTYPES_MAX_ARGCOUNT); + 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); + v = PyObject_CallFunctionObjArgs(converter, arg, 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) { + _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1); + 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, + 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)) + { + 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\ +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; + int load_flags = 0; + HMODULE hMod; + DWORD err; + + if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags)) + return NULL; + + name = _PyUnicode_AsUnicode(nameobj); + if (!name) + return NULL; + + if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) { + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + /* bpo-36085: Limit DLL search directories to avoid pre-loading + * attacks and enable use of the AddDllDirectory function. + */ + hMod = LoadLibraryExW(name, NULL, (DWORD)load_flags); + err = hMod ? 0 : GetLastError(); + Py_END_ALLOW_THREADS + + if (err == ERROR_MOD_NOT_FOUND) { + PyErr_Format(PyExc_FileNotFoundError, + ("Could not find module '%.500S' (or one of its " + "dependencies). Try using the full path with " + "constructor syntax."), + nameobj); + return NULL; + } 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; + BOOL result; + DWORD err; + if (!PyArg_ParseTuple(args, "O&:FreeLibrary", &_parse_voidp, &hMod)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + result = FreeLibrary((HMODULE)hMod); + err = result ? 0 : GetLastError(); + Py_END_ALLOW_THREADS + + 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 + +#ifdef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH +static PyObject *py_dyld_shared_cache_contains_path(PyObject *self, PyObject *args) +{ + PyObject *name, *name2; + char *name_str; + + if (__builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)) { + int r; + + if (!PyArg_ParseTuple(args, "O", &name)) + return NULL; + + if (name == Py_None) + Py_RETURN_FALSE; + + if (PyUnicode_FSConverter(name, &name2) == 0) + return NULL; + name_str = PyBytes_AS_STRING(name2); + + r = _dyld_shared_cache_contains_path(name_str); + Py_DECREF(name2); + + if (r) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + + } else { + PyErr_SetString(PyExc_NotImplementedError, "_dyld_shared_cache_contains_path symbol is missing"); + return NULL; + } + + } +#endif + +static PyObject *py_dl_open(PyObject *self, PyObject *args) +{ + PyObject *name, *name2; + 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; + name_str = PyBytes_AS_STRING(name2); + } 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; + 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; + 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; + 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) +{ + if (!CDataObject_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "invalid type"); + return NULL; + } + if (PySys_Audit("ctypes.addressof", "(O)", obj) < 0) { + 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; + if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) { + 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. */ + void *ptr = PyMem_Malloc(size); + if (ptr == NULL) + return PyErr_NoMemory(); + memset(ptr, 0, size); + 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_CallMethodIdObjArgs(typ, &PyId___new__, typ, NULL); + 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; + } + 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; + + typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); + if (typ) { + return PyObject_CallFunctionObjArgs(typ, arg, NULL); + } + else if (PyErr_Occurred()) { + return NULL; + } + typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); + if (typ == NULL) + return NULL; + result = PyObject_CallFunctionObjArgs(typ, arg, NULL); + 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 HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH + {"_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: +*/ diff --git a/python/Modules/_ctypes/cfield.c b/python/Modules/_ctypes/cfield.c new file mode 100755 index 0000000..0b12a44 --- /dev/null +++ b/python/Modules/_ctypes/cfield.c @@ -0,0 +1,1671 @@ +#include "Python.h" + +#include +#ifdef MS_WIN32 +#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 desriptor 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 + + self = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type, + NULL); + 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); + self->ob_type->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 */ + 0, /* tp_vectorcall_offset */ + 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) + +/* byte swapping macros */ +#define SWAP_2(v) \ + ( ( (v >> 8) & 0x00FF) | \ + ( (v << 8) & 0xFF00) ) + +#define SWAP_4(v) \ + ( ( (v & 0x000000FF) << 24 ) | \ + ( (v & 0x0000FF00) << 8 ) | \ + ( (v & 0x00FF0000) >> 8 ) | \ + ( ((v >> 24) & 0xFF)) ) + +#ifdef _MSC_VER +#define SWAP_8(v) \ + ( ( (v & 0x00000000000000FFL) << 56 ) | \ + ( (v & 0x000000000000FF00L) << 40 ) | \ + ( (v & 0x0000000000FF0000L) << 24 ) | \ + ( (v & 0x00000000FF000000L) << 8 ) | \ + ( (v & 0x000000FF00000000L) >> 8 ) | \ + ( (v & 0x0000FF0000000000L) >> 24 ) | \ + ( (v & 0x00FF000000000000L) >> 40 ) | \ + ( ((v >> 56) & 0xFF)) ) +#else +#define SWAP_8(v) \ + ( ( (v & 0x00000000000000FFLL) << 56 ) | \ + ( (v & 0x000000000000FF00LL) << 40 ) | \ + ( (v & 0x0000000000FF0000LL) << 24 ) | \ + ( (v & 0x00000000FF000000LL) << 8 ) | \ + ( (v & 0x000000FF00000000LL) >> 8 ) | \ + ( (v & 0x0000FF0000000000LL) >> 24 ) | \ + ( (v & 0x00FF000000000000LL) >> 40 ) | \ + ( ((v >> 56) & 0xFF)) ) +#endif + +#define SWAP_INT SWAP_4 + +#if SIZEOF_LONG == 4 +# define SWAP_LONG SWAP_4 +#elif SIZEOF_LONG == 8 +# define SWAP_LONG SWAP_8 +#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; + if (get_long(value, &val) < 0) + return NULL; + memcpy(&field, ptr, sizeof(field)); + field = SWAP_2(field); + field = SET(short, field, val, size); + field = SWAP_2(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)); + val = SWAP_2(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; + if (get_ulong(value, &val) < 0) + return NULL; + memcpy(&field, ptr, sizeof(field)); + field = SWAP_2(field); + field = SET(unsigned short, field, val, size); + field = SWAP_2(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)); + val = SWAP_2(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; + if (get_long(value, &val) < 0) + 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); +} + +#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; + if (get_ulong(value, &val) < 0) + 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; + if (get_long(value, &val) < 0) + 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; + if (get_ulong(value, &val) < 0) + 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; + if (get_longlong(value, &val) < 0) + return NULL; + memcpy(&field, ptr, sizeof(field)); + field = SWAP_8(field); + field = SET(long long, field, val, size); + field = SWAP_8(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)); + val = SWAP_8(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; + if (get_ulonglong(value, &val) < 0) + return NULL; + memcpy(&field, ptr, sizeof(field)); + field = SWAP_8(field); + field = SET(unsigned long long, field, val, size); + field = SWAP_8(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)); + val = SWAP_8(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)) + { + 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", + value->ob_type->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", + value->ob_type->tp_name); + return NULL; + } + + Py_ssize_t size = PyUnicode_AsWideChar(value, NULL, 0); + if (size < 0) { + 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) +{ + char *data; + Py_ssize_t size; + + if(!PyBytes_Check(value)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %s found", + value->ob_type->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)) { + *(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", + value->ob_type->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; + 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", + value->ob_type->tp_name); + 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", + value->ob_type->tp_name); + 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; + } + if ((unsigned) wsize != wsize) { + PyErr_SetString(PyExc_ValueError, "String too long for BSTR"); + PyMem_Free(wvalue); + 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}, +#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; +} + +typedef struct { char c; char x; } s_char; +typedef struct { char c; short x; } s_short; +typedef struct { char c; int x; } s_int; +typedef struct { char c; long x; } s_long; +typedef struct { char c; float x; } s_float; +typedef struct { char c; double x; } s_double; +typedef struct { char c; long double x; } s_long_double; +typedef struct { char c; char *x; } s_char_p; +typedef struct { char c; void *x; } s_void_p; + +/* +#define CHAR_ALIGN (sizeof(s_char) - sizeof(char)) +#define SHORT_ALIGN (sizeof(s_short) - sizeof(short)) +#define LONG_ALIGN (sizeof(s_long) - sizeof(long)) +*/ +#define INT_ALIGN (sizeof(s_int) - sizeof(int)) +#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float)) +#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double)) +#define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double)) + +/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */ +#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*)) + +/* +#ifdef HAVE_USABLE_WCHAR_T +typedef struct { char c; wchar_t x; } s_wchar; +typedef struct { char c; wchar_t *x; } s_wchar_p; + +#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t)) +#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*)) +#endif +*/ + +typedef struct { char c; long long x; } s_long_long; +#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) + +/* from ffi.h: +typedef struct _ffi_type +{ + size_t size; + unsigned short alignment; + unsigned short type; + struct _ffi_type **elements; +} ffi_type; +*/ + +/* align and size are bogus for void, but they must not be zero */ +ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID }; + +ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 }; +ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 }; + +ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 }; +ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 }; + +ffi_type ffi_type_uint32 = { 4, INT_ALIGN, FFI_TYPE_UINT32 }; +ffi_type ffi_type_sint32 = { 4, INT_ALIGN, FFI_TYPE_SINT32 }; + +ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 }; +ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 }; + +ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT }; +ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE }; + +#ifdef ffi_type_longdouble +#undef ffi_type_longdouble +#endif + /* This is already defined on OSX */ +ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN, + FFI_TYPE_LONGDOUBLE }; + +ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; + +/*---------------- EOF ----------------*/ diff --git a/python/Modules/_ctypes/ctypes.h b/python/Modules/_ctypes/ctypes.h new file mode 100755 index 0000000..0bed85e --- /dev/null +++ b/python/Modules/_ctypes/ctypes.h @@ -0,0 +1,381 @@ +#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) ((v)->ob_type == &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; +#define PyCStgDict_CheckExact(v) ((v)->ob_type == &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 CDataObject_CheckExact(v) ((v)->ob_type == &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 PyCSimpleTypeObject_CheckExact(v) ((v)->ob_type == &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 */ + + /* pep3118 fields, pointers neeed 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 +#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 PyCArg_CheckExact(v) ((v)->ob_type == &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 + +#if USING_MALLOC_CLOSURE_DOT_C +void Py_ffi_closure_free(void *p); +void *Py_ffi_closure_alloc(size_t size, void** codeloc); +#else +#define Py_ffi_closure_free ffi_closure_free +#define Py_ffi_closure_alloc ffi_closure_alloc +#endif + +/* + Local Variables: + compile-command: "python setup.py -q build install --home ~" + End: +*/ diff --git a/python/Modules/_ctypes/ctypes_dlfcn.h b/python/Modules/_ctypes/ctypes_dlfcn.h new file mode 100755 index 0000000..54cdde9 --- /dev/null +++ b/python/Modules/_ctypes/ctypes_dlfcn.h @@ -0,0 +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_ */ diff --git a/python/Modules/_ctypes/darwin/LICENSE b/python/Modules/_ctypes/darwin/LICENSE new file mode 100755 index 0000000..786fb50 --- /dev/null +++ b/python/Modules/_ctypes/darwin/LICENSE @@ -0,0 +1,31 @@ +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. + + diff --git a/python/Modules/_ctypes/darwin/README b/python/Modules/_ctypes/darwin/README new file mode 100755 index 0000000..4d63f3d --- /dev/null +++ b/python/Modules/_ctypes/darwin/README @@ -0,0 +1,95 @@ +dlcompat for Darwin +========================= + +This is dlcompat, a small library that emulates the dlopen() +interface on top of Darwin's dyld API. + +dlcompat allows loading a ".dylib" library (as long as the RTLD_LOCAL +flag isn't passed to dlopen()). It can be configured to yield a warning +when trying to close it (dynamic libraries cannot currently be unloaded). + +It automatically searches for modules in several directories when no +absolute path is specified and the module is not found in the current +directory. + +The paths searched are those specified in the environment variables +LD_LIBRARY_PATH and DYLD_LIBRARY_PATH plus /lib, /usr/local/lib and +/usr/lib or the path specified in the environment variable +DYLD_FALLBACK_LIBRARY_PATH. + +In the default install the behavior of dlsym is to automatically prepend +an underscore to passed in symbol names, this allows easier porting of +applications which were written specifically for ELF based lifeforms. + +Installation +-------------- +Type: + ./configure + make + sudo make install + +This will compile the source file, generate both a static and shared +library called libdl and install it into /usr/local/lib. The header +file dlfcn.h will be installed in /usr/local/include. + +If you want to place the files somewhere else, run + + make clean + ./configure --prefix= + make + sudo make install + +where is the hierarchy you want to install into, e.g. /usr +for /usr/lib and /usr/include (_NOT_ recommended!). + +To enable debugging output (useful for me), run + + make clean + ./configure --enable-debug + make + sudo make install + +If you want old dlcompat style behavior of not prepending the underscore +on calls to dlsym then type: + + make clean + ./configure --enable-fink + make + sudo make install + +Usage +------- +Software that uses GNU autoconf will likely check for a library called +libdl, that's why I named it that way. For software that doesn't find +the library on its own, you must add a '-ldl' to the appropriate +Makefile (or environment) variable, usually LIBS. + +If you installed dlcompat into a directory other than /usr/local/lib, +you must tell the compiler where to find it. Add '-L/lib' to +LDFLAGS (or CFLAGS) and '-I/include' to CPPFLAGS (or CFLAGS). + +Notes +----- +If you are writing new software and plan to have Mac OX X compatibility you +should look at the dyld api's in /usr/include/mach-o/dyld.h, rather than +using dlcompat, using the native api's is the supported method of loading +dynamically on Mac OS X, if you want an small example, look at dlfcn_simple.c, +which should help get you started. + +Also note that the functions in dlcompat are not thread safe, and while it is not +POSIX spec compliant, it is about as close to compliance as it is going to get though. + +You can always get the latest version from opendarwin cvs: + + cvs -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od login + cvs -z3 -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od \ + co -d dlcompat proj/dlcompat + + +It is hoped that this library will be useful, and as bug free as possible, if you find +any bugs please let us know about them so they can be fixed. + +Please send bug reports to Peter O'Gorman + +Thanks. + diff --git a/python/Modules/_ctypes/darwin/README.ctypes b/python/Modules/_ctypes/darwin/README.ctypes new file mode 100755 index 0000000..8520b01 --- /dev/null +++ b/python/Modules/_ctypes/darwin/README.ctypes @@ -0,0 +1,11 @@ +The files in this directory are taken from +http://www.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/proj/dlcompat/ + +The LICENSE in this directory applies to these files. + +Thomas Heller, Jan 2003 + +These files have been modified so they fall back to the system +dlfcn calls if available in libSystem. + +Bob Ippolito, Feb 2006 diff --git a/python/Modules/_ctypes/darwin/dlfcn.h b/python/Modules/_ctypes/darwin/dlfcn.h new file mode 100755 index 0000000..a2afc3e --- /dev/null +++ b/python/Modules/_ctypes/darwin/dlfcn.h @@ -0,0 +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_ */ diff --git a/python/Modules/_ctypes/darwin/dlfcn_simple.c b/python/Modules/_ctypes/darwin/dlfcn_simple.c new file mode 100755 index 0000000..2b293bb --- /dev/null +++ b/python/Modules/_ctypes/darwin/dlfcn_simple.c @@ -0,0 +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 */ diff --git a/python/Modules/_ctypes/libffi_osx/LICENSE b/python/Modules/_ctypes/libffi_osx/LICENSE new file mode 100755 index 0000000..f591795 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/LICENSE @@ -0,0 +1,20 @@ +libffi - Copyright (c) 1996-2003 Red Hat, Inc. + +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 CYGNUS SOLUTIONS 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. diff --git a/python/Modules/_ctypes/libffi_osx/README b/python/Modules/_ctypes/libffi_osx/README new file mode 100755 index 0000000..69e46cb --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/README @@ -0,0 +1,500 @@ +This directory contains the libffi package, which is not part of GCC but +shipped with GCC as convenience. + +Status +====== + +libffi-2.00 has not been released yet! This is a development snapshot! + +libffi-1.20 was released on October 5, 1998. Check the libffi web +page for updates: . + + +What is libffi? +=============== + +Compilers for high level languages generate code that follow certain +conventions. These conventions are necessary, in part, for separate +compilation to work. One such convention is the "calling +convention". The "calling convention" is essentially a set of +assumptions made by the compiler about where function arguments will +be found on entry to a function. A "calling convention" also specifies +where the return value for a function is found. + +Some programs may not know at the time of compilation what arguments +are to be passed to a function. For instance, an interpreter may be +told at run-time about the number and types of arguments used to call +a given function. Libffi can be used in such programs to provide a +bridge from the interpreter program to compiled code. + +The libffi library provides a portable, high level programming +interface to various calling conventions. This allows a programmer to +call any function specified by a call interface description at run +time. + +Ffi stands for Foreign Function Interface. A foreign function +interface is the popular name for the interface that allows code +written in one language to call code written in another language. The +libffi library really only provides the lowest, machine dependent +layer of a fully featured foreign function interface. A layer must +exist above libffi that handles type conversions for values passed +between the two languages. + + +Supported Platforms and Prerequisites +===================================== + +Libffi has been ported to: + + SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9) + + Irix 5.3 & 6.2 (System V/o32 & n32) + + Intel x86 - Linux (System V ABI) + + Alpha - Linux and OSF/1 + + m68k - Linux (System V ABI) + + PowerPC - Linux (System V ABI, Darwin, AIX) + + ARM - Linux (System V ABI) + +Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are +that other versions will work. Libffi has also been built and tested +with the SGI compiler tools. + +On PowerPC, the tests failed (see the note below). + +You must use GNU make to build libffi. SGI's make will not work. +Sun's probably won't either. + +If you port libffi to another platform, please let me know! I assume +that some will be easy (x86 NetBSD), and others will be more difficult +(HP). + + +Installing libffi +================= + +[Note: before actually performing any of these installation steps, + you may wish to read the "Platform Specific Notes" below.] + +First you must configure the distribution for your particular +system. Go to the directory you wish to build libffi in and run the +"configure" program found in the root directory of the libffi source +distribution. + +You may want to tell configure where to install the libffi library and +header files. To do that, use the --prefix configure switch. Libffi +will install under /usr/local by default. + +If you want to enable extra run-time debugging checks use the the +--enable-debug configure switch. This is useful when your program dies +mysteriously while using libffi. + +Another useful configure switch is --enable-purify-safety. Using this +will add some extra code which will suppress certain warnings when you +are using Purify with libffi. Only use this switch when using +Purify, as it will slow down the library. + +Configure has many other options. Use "configure --help" to see them all. + +Once configure has finished, type "make". Note that you must be using +GNU make. SGI's make will not work. Sun's probably won't either. +You can ftp GNU make from prep.ai.mit.edu:/pub/gnu. + +To ensure that libffi is working as advertised, type "make test". + +To install the library and header files, type "make install". + + +Using libffi +============ + + The Basics + ---------- + +Libffi assumes that you have a pointer to the function you wish to +call and that you know the number and types of arguments to pass it, +as well as the return type of the function. + +The first thing you must do is create an ffi_cif object that matches +the signature of the function you wish to call. The cif in ffi_cif +stands for Call InterFace. To prepare a call interface object, use the +following function: + +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, + unsigned int nargs, + ffi_type *rtype, ffi_type **atypes); + + CIF is a pointer to the call interface object you wish + to initialize. + + ABI is an enum that specifies the calling convention + to use for the call. FFI_DEFAULT_ABI defaults + to the system's native calling convention. Other + ABI's may be used with care. They are system + specific. + + NARGS is the number of arguments this function accepts. + libffi does not yet support vararg functions. + + RTYPE is a pointer to an ffi_type structure that represents + the return type of the function. Ffi_type objects + describe the types of values. libffi provides + ffi_type objects for many of the native C types: + signed int, unsigned int, signed char, unsigned char, + etc. There is also a pointer ffi_type object and + a void ffi_type. Use &ffi_type_void for functions that + don't return values. + + ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long. + If NARGS is 0, this is ignored. + + +ffi_prep_cif will return a status code that you are responsible +for checking. It will be one of the following: + + FFI_OK - All is good. + + FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif + came across is bad. + + +Before making the call, the VALUES vector should be initialized +with pointers to the appropriate argument values. + +To call the the function using the initialized ffi_cif, use the +ffi_call function: + +void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); + + CIF is a pointer to the ffi_cif initialized specifically + for this function. + + FN is a pointer to the function you want to call. + + RVALUE is a pointer to a chunk of memory that is to hold the + result of the function call. Currently, it must be + at least one word in size (except for the n32 version + under Irix 6.x, which must be a pointer to an 8 byte + aligned value (a long long). It must also be at least + word aligned (depending on the return type, and the + system's alignment requirements). If RTYPE is + &ffi_type_void, this is ignored. If RVALUE is NULL, + the return value is discarded. + + AVALUES is a vector of void* that point to the memory locations + holding the argument values for a call. + If NARGS is 0, this is ignored. + + +If you are expecting a return value from FN it will have been stored +at RVALUE. + + + + An Example + ---------- + +Here is a trivial example that calls puts() a few times. + + #include + #include + + int main() + { + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + char *s; + int rc; + + /* Initialize the argument info vectors */ + args[0] = &ffi_type_uint; + values[0] = &s; + + /* Initialize the cif */ + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uint, args) == FFI_OK) + { + s = "Hello World!"; + ffi_call(&cif, puts, &rc, values); + /* rc now holds the result of the call to puts */ + + /* values holds a pointer to the function's arg, so to + call puts() again all we need to do is change the + value of s */ + s = "This is cool!"; + ffi_call(&cif, puts, &rc, values); + } + + return 0; + } + + + + Aggregate Types + --------------- + +Although libffi has no special support for unions or bit-fields, it is +perfectly happy passing structures back and forth. You must first +describe the structure to libffi by creating a new ffi_type object +for it. Here is the definition of ffi_type: + + typedef struct _ffi_type + { + unsigned size; + short alignment; + short type; + struct _ffi_type **elements; + } ffi_type; + +All structures must have type set to FFI_TYPE_STRUCT. You may set +size and alignment to 0. These will be calculated and reset to the +appropriate values by ffi_prep_cif(). + +elements is a NULL terminated array of pointers to ffi_type objects +that describe the type of the structure elements. These may, in turn, +be structure elements. + +The following example initializes a ffi_type object representing the +tm struct from Linux's time.h: + + struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + /* Those are for future use. */ + long int __tm_gmtoff__; + __const char *__tm_zone__; + }; + + { + ffi_type tm_type; + ffi_type *tm_type_elements[12]; + int i; + + tm_type.size = tm_type.alignment = 0; + tm_type.elements = &tm_type_elements; + + for (i = 0; i < 9; i++) + tm_type_elements[i] = &ffi_type_sint; + + tm_type_elements[9] = &ffi_type_slong; + tm_type_elements[10] = &ffi_type_pointer; + tm_type_elements[11] = NULL; + + /* tm_type can now be used to represent tm argument types and + return types for ffi_prep_cif() */ + } + + + +Platform Specific Notes +======================= + + Intel x86 + --------- + +There are no known problems with the x86 port. + + Sun SPARC - SunOS 4.1.3 & Solaris 2.x + ------------------------------------- + +You must use GNU Make to build libffi on Sun platforms. + + MIPS - Irix 5.3 & 6.x + --------------------- + +Irix 6.2 and better supports three different calling conventions: o32, +n32 and n64. Currently, libffi only supports both o32 and n32 under +Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be +configured for whichever calling convention it was built for. + +By default, the configure script will try to build libffi with the GNU +development tools. To build libffi with the SGI development tools, set +the environment variable CC to either "cc -32" or "cc -n32" before +running configure under Irix 6.x (depending on whether you want an o32 +or n32 library), or just "cc" for Irix 5.3. + +With the n32 calling convention, when returning structures smaller +than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned. +Here's one way of forcing this: + + double struct_storage[2]; + my_small_struct *s = (my_small_struct *) struct_storage; + /* Use s for RVALUE */ + +If you don't do this you are liable to get spurious bus errors. + +"long long" values are not supported yet. + +You must use GNU Make to build libffi on SGI platforms. + + ARM - System V ABI + ------------------ + +The ARM port was performed on a NetWinder running ARM Linux ELF +(2.0.31) and gcc 2.8.1. + + + + PowerPC System V ABI + -------------------- + +There are two `System V ABI's which libffi implements for PowerPC. +They differ only in how small structures are returned from functions. + +In the FFI_SYSV version, structures that are 8 bytes or smaller are +returned in registers. This is what GCC does when it is configured +for solaris, and is what the System V ABI I have (dated September +1995) says. + +In the FFI_GCC_SYSV version, all structures are returned the same way: +by passing a pointer as the first argument to the function. This is +what GCC does when it is configured for linux or a generic sysv +target. + +EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a +inconsistency with the SysV ABI: When a procedure is called with many +floating-point arguments, some of them get put on the stack. They are +all supposed to be stored in double-precision format, even if they are +only single-precision, but EGCS stores single-precision arguments as +single-precision anyway. This causes one test to fail (the `many +arguments' test). + + +What's With The Cryptic Comments? +================================= + +You might notice a number of cryptic comments in the code, delimited +by /*@ and @*/. These are annotations read by the program LCLint, a +tool for statically checking C programs. You can read all about it at +. + + +History +======= + +1.20 Oct-5-98 + Raffaele Sena produces ARM port. + +1.19 Oct-5-98 + Fixed x86 long double and long long return support. + m68k bug fixes from Andreas Schwab. + Patch for DU assembler compatibility for the Alpha from Richard + Henderson. + +1.18 Apr-17-98 + Bug fixes and MIPS configuration changes. + +1.17 Feb-24-98 + Bug fixes and m68k port from Andreas Schwab. PowerPC port from + Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes. + +1.16 Feb-11-98 + Richard Henderson produces Alpha port. + +1.15 Dec-4-97 + Fixed an n32 ABI bug. New libtool, auto* support. + +1.14 May-13-97 + libtool is now used to generate shared and static libraries. + Fixed a minor portability problem reported by Russ McManus + . + +1.13 Dec-2-96 + Added --enable-purify-safety to keep Purify from complaining + about certain low level code. + Sparc fix for calling functions with < 6 args. + Linux x86 a.out fix. + +1.12 Nov-22-96 + Added missing ffi_type_void, needed for supporting void return + types. Fixed test case for non MIPS machines. Cygnus Support + is now Cygnus Solutions. + +1.11 Oct-30-96 + Added notes about GNU make. + +1.10 Oct-29-96 + Added configuration fix for non GNU compilers. + +1.09 Oct-29-96 + Added --enable-debug configure switch. Clean-ups based on LCLint + feedback. ffi_mips.h is always installed. Many configuration + fixes. Fixed ffitest.c for sparc builds. + +1.08 Oct-15-96 + Fixed n32 problem. Many clean-ups. + +1.07 Oct-14-96 + Gordon Irlam rewrites v8.S again. Bug fixes. + +1.06 Oct-14-96 + Gordon Irlam improved the sparc port. + +1.05 Oct-14-96 + Interface changes based on feedback. + +1.04 Oct-11-96 + Sparc port complete (modulo struct passing bug). + +1.03 Oct-10-96 + Passing struct args, and returning struct values works for + all architectures/calling conventions. Expanded tests. + +1.02 Oct-9-96 + Added SGI n32 support. Fixed bugs in both o32 and Linux support. + Added "make test". + +1.01 Oct-8-96 + Fixed float passing bug in mips version. Restructured some + of the code. Builds cleanly with SGI tools. + +1.00 Oct-7-96 + First release. No public announcement. + + +Authors & Credits +================= + +libffi was written by Anthony Green . + +Portions of libffi were derived from Gianni Mariani's free gencall +library for Silicon Graphics machines. + +The closure mechanism was designed and implemented by Kresten Krab +Thorup. + +The Sparc port was derived from code contributed by the fine folks at +Visible Decisions Inc . Further enhancements were +made by Gordon Irlam at Cygnus Solutions . + +The Alpha port was written by Richard Henderson at Cygnus Solutions. + +Andreas Schwab ported libffi to m68k Linux and provided a number of +bug fixes. + +Geoffrey Keating ported libffi to the PowerPC. + +Raffaele Sena ported libffi to the ARM. + +Jesper Skov and Andrew Haley both did more than their fair share of +stepping through the code and tracking down bugs. + +Thanks also to Tom Tromey for bug fixes and configuration help. + +Thanks to Jim Blandy, who provided some useful feedback on the libffi +interface. + +If you have a problem, or have found a bug, please send a note to +green@cygnus.com. diff --git a/python/Modules/_ctypes/libffi_osx/README.pyobjc b/python/Modules/_ctypes/libffi_osx/README.pyobjc new file mode 100755 index 0000000..405d85f --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/README.pyobjc @@ -0,0 +1,5 @@ +This directory contains a slightly modified version of libffi, extracted from +the GCC source-tree. + +The only modifications are those that are necessary to compile libffi using +the Apple provided compiler and outside of the GCC source tree. diff --git a/python/Modules/_ctypes/libffi_osx/ffi.c b/python/Modules/_ctypes/libffi_osx/ffi.c new file mode 100755 index 0000000..1776b79 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/ffi.c @@ -0,0 +1,227 @@ +/* ----------------------------------------------------------------------- + prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + 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 CYGNUS SOLUTIONS 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. + ----------------------------------------------------------------------- */ + +#include +#include + +#include +#include + +/* Round up to FFI_SIZEOF_ARG. */ +#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) + +/* Perform machine independent initialization of aggregate type + specifications. */ + +static ffi_status +initialize_aggregate( +/*@out@*/ ffi_type* arg) +{ +/*@-usedef@*/ + ffi_type** ptr; + + if (arg == NULL || arg->elements == NULL || + arg->size != 0 || arg->alignment != 0) + return FFI_BAD_TYPEDEF; + + ptr = &(arg->elements[0]); + + while ((*ptr) != NULL) + { + if (((*ptr)->size == 0) && (initialize_aggregate(*ptr) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type */ + FFI_ASSERT_VALID_TYPE(*ptr); + +#ifdef POWERPC_DARWIN + int curalign = (*ptr)->alignment; + + if (ptr != &(arg->elements[0])) + { + if (curalign > 4 && curalign != 16) + curalign = 4; + } + + arg->size = ALIGN(arg->size, curalign); + arg->size += (*ptr)->size; + arg->alignment = (arg->alignment > curalign) ? + arg->alignment : curalign; +#else + arg->size = ALIGN(arg->size, (*ptr)->alignment); + arg->size += (*ptr)->size; + arg->alignment = (arg->alignment > (*ptr)->alignment) ? + arg->alignment : (*ptr)->alignment; +#endif + + ptr++; + } + + /* Structure size includes tail padding. This is important for + structures that fit in one register on ABIs like the PowerPC64 + Linux ABI that right justify small structs in a register. + It's also needed for nested structure layout, for example + struct A { long a; char b; }; struct B { struct A x; char y; }; + should find y at an offset of 2*sizeof(long) and result in a + total size of 3*sizeof(long). */ + arg->size = ALIGN(arg->size, arg->alignment); + + if (arg->size == 0) + return FFI_BAD_TYPEDEF; + + return FFI_OK; + +/*@=usedef@*/ +} + +#ifndef __CRIS__ +/* The CRIS ABI specifies structure elements to have byte + alignment only, so it completely overrides this functions, + which assumes "natural" alignment and padding. */ + +/* Perform machine independent ffi_cif preparation, then call + machine dependent routine. */ + +#if defined(X86_DARWIN) && !defined __x86_64__ + +static inline bool +struct_on_stack( + int size) +{ + if (size > 8) + return true; + + /* This is not what the ABI says, but is what is really implemented */ + switch (size) + { + case 1: + case 2: + case 4: + case 8: + return false; + + default: + return true; + } +} + +#endif // defined(X86_DARWIN) && !defined __x86_64__ + +// Arguments' ffi_type->alignment must be nonzero. +ffi_status +ffi_prep_cif( +/*@out@*/ /*@partial@*/ ffi_cif* cif, + ffi_abi abi, + unsigned int nargs, +/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype, +/*@dependent@*/ ffi_type** atypes) +{ + unsigned int bytes = 0; + unsigned int i; + ffi_type** ptr; + + if (cif == NULL) + return FFI_BAD_TYPEDEF; + + if (abi <= FFI_FIRST_ABI || abi > FFI_DEFAULT_ABI) + return FFI_BAD_ABI; + + cif->abi = abi; + cif->arg_types = atypes; + cif->nargs = nargs; + cif->rtype = rtype; + cif->flags = 0; + + /* Initialize the return type if necessary */ + /*@-usedef@*/ + if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) + return FFI_BAD_TYPEDEF; + /*@=usedef@*/ + + /* Perform a sanity check on the return type */ + FFI_ASSERT_VALID_TYPE(cif->rtype); + + /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ +#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA + /* Make space for the return structure pointer */ + if (cif->rtype->type == FFI_TYPE_STRUCT +#ifdef SPARC + && (cif->abi != FFI_V9 || cif->rtype->size > 32) +#endif +#ifdef X86_DARWIN + && (struct_on_stack(cif->rtype->size)) +#endif + ) + bytes = STACK_ARG_SIZE(sizeof(void*)); +#endif + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + /* Initialize any uninitialized aggregate type definitions */ + if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + if ((*ptr)->alignment == 0) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type, do this + check after the initialization. */ + FFI_ASSERT_VALID_TYPE(*ptr); + +#if defined(X86_DARWIN) + { + int align = (*ptr)->alignment; + + if (align > 4) + align = 4; + + if ((align - 1) & bytes) + bytes = ALIGN(bytes, align); + + bytes += STACK_ARG_SIZE((*ptr)->size); + } +#elif !defined __x86_64__ && !defined S390 && !defined PA +#ifdef SPARC + if (((*ptr)->type == FFI_TYPE_STRUCT + && ((*ptr)->size > 16 || cif->abi != FFI_V9)) + || ((*ptr)->type == FFI_TYPE_LONGDOUBLE + && cif->abi != FFI_V9)) + bytes += sizeof(void*); + else +#endif + { + /* Add any padding if necessary */ + if (((*ptr)->alignment - 1) & bytes) + bytes = ALIGN(bytes, (*ptr)->alignment); + + bytes += STACK_ARG_SIZE((*ptr)->size); + } +#endif + } + + cif->bytes = bytes; + + /* Perform machine dependent cif processing */ + return ffi_prep_cif_machdep(cif); +} +#endif /* not __CRIS__ */ diff --git a/python/Modules/_ctypes/libffi_osx/include/ffi.h b/python/Modules/_ctypes/libffi_osx/include/ffi.h new file mode 100755 index 0000000..c104a5c --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/include/ffi.h @@ -0,0 +1,355 @@ +/* -----------------------------------------------------------------*-C-*- + libffi PyOBJC - Copyright (c) 1996-2003 Red Hat, Inc. + + 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 CYGNUS SOLUTIONS 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. + + ----------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------- + The basic API is described in the README file. + + The raw API is designed to bypass some of the argument packing + and unpacking on architectures for which it can be avoided. + + The closure API allows interpreted functions to be packaged up + inside a C function pointer, so that they can be called as C functions, + with no understanding on the client side that they are interpreted. + It can also be used in other cases in which it is necessary to package + up a user specified parameter and a function pointer as a single + function pointer. + + The closure API must be implemented in order to get its functionality, + e.g. for use by gij. Routines are provided to emulate the raw API + if the underlying platform doesn't allow faster implementation. + + More details on the raw and closure API can be found in: + + http://gcc.gnu.org/ml/java/1999-q3/msg00138.html + + and + + http://gcc.gnu.org/ml/java/1999-q3/msg00174.html + -------------------------------------------------------------------- */ + +#ifndef LIBFFI_H +#define LIBFFI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Specify which architecture libffi is configured for. */ +#ifdef MACOSX +# if defined(__i386__) || defined(__x86_64__) +# define X86_DARWIN +# elif defined(__ppc__) || defined(__ppc64__) +# define POWERPC_DARWIN +# else +# error "Unsupported MacOS X CPU type" +# endif +#else +#error "Unsupported OS type" +#endif + +/* ---- System configuration information --------------------------------- */ + +#include "ffitarget.h" +#include "fficonfig.h" + +#ifndef LIBFFI_ASM + +#include +#include + +/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). + But we can find it either under the correct ANSI name, or under GNU + C's internal name. */ +#ifdef LONG_LONG_MAX +# define FFI_LONG_LONG_MAX LONG_LONG_MAX +#else +# ifdef LLONG_MAX +# define FFI_LONG_LONG_MAX LLONG_MAX +# else +# ifdef __GNUC__ +# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ +# endif +# endif +#endif + +#if SCHAR_MAX == 127 +# define ffi_type_uchar ffi_type_uint8 +# define ffi_type_schar ffi_type_sint8 +#else +#error "char size not supported" +#endif + +#if SHRT_MAX == 32767 +# define ffi_type_ushort ffi_type_uint16 +# define ffi_type_sshort ffi_type_sint16 +#elif SHRT_MAX == 2147483647 +# define ffi_type_ushort ffi_type_uint32 +# define ffi_type_sshort ffi_type_sint32 +#else +#error "short size not supported" +#endif + +#if INT_MAX == 32767 +# define ffi_type_uint ffi_type_uint16 +# define ffi_type_sint ffi_type_sint16 +#elif INT_MAX == 2147483647 +# define ffi_type_uint ffi_type_uint32 +# define ffi_type_sint ffi_type_sint32 +#elif INT_MAX == 9223372036854775807 +# define ffi_type_uint ffi_type_uint64 +# define ffi_type_sint ffi_type_sint64 +#else +#error "int size not supported" +#endif + +#define ffi_type_ulong ffi_type_uint64 +#define ffi_type_slong ffi_type_sint64 + +#if LONG_MAX == 2147483647 +# if FFI_LONG_LONG_MAX != 9223372036854775807 +# error "no 64-bit data type supported" +# endif +#elif LONG_MAX != 9223372036854775807 +#error "long size not supported" +#endif + +/* The closure code assumes that this works on pointers, i.e. a size_t + can hold a pointer. */ + +typedef struct _ffi_type { + size_t size; + unsigned short alignment; + unsigned short type; +/*@null@*/ struct _ffi_type** elements; +} ffi_type; + +/* These are defined in types.c */ +extern ffi_type ffi_type_void; +extern ffi_type ffi_type_uint8; +extern ffi_type ffi_type_sint8; +extern ffi_type ffi_type_uint16; +extern ffi_type ffi_type_sint16; +extern ffi_type ffi_type_uint32; +extern ffi_type ffi_type_sint32; +extern ffi_type ffi_type_uint64; +extern ffi_type ffi_type_sint64; +extern ffi_type ffi_type_float; +extern ffi_type ffi_type_double; +extern ffi_type ffi_type_longdouble; +extern ffi_type ffi_type_pointer; + +typedef enum ffi_status { + FFI_OK = 0, + FFI_BAD_TYPEDEF, + FFI_BAD_ABI +} ffi_status; + +typedef unsigned FFI_TYPE; + +typedef struct ffi_cif { + ffi_abi abi; + unsigned nargs; +/*@dependent@*/ ffi_type** arg_types; +/*@dependent@*/ ffi_type* rtype; + unsigned bytes; + unsigned flags; +#ifdef FFI_EXTRA_CIF_FIELDS + FFI_EXTRA_CIF_FIELDS; +#endif +} ffi_cif; + +/* ---- Definitions for the raw API -------------------------------------- */ + +#ifndef FFI_SIZEOF_ARG +# if LONG_MAX == 2147483647 +# define FFI_SIZEOF_ARG 4 +# elif LONG_MAX == 9223372036854775807 +# define FFI_SIZEOF_ARG 8 +# endif +#endif + +typedef union { + ffi_sarg sint; + ffi_arg uint; + float flt; + char data[FFI_SIZEOF_ARG]; + void* ptr; +} ffi_raw; + +void +ffi_raw_call( +/*@dependent@*/ ffi_cif* cif, + void (*fn)(void), +/*@out@*/ void* rvalue, +/*@dependent@*/ ffi_raw* avalue); + +void +ffi_ptrarray_to_raw( + ffi_cif* cif, + void** args, + ffi_raw* raw); + +void +ffi_raw_to_ptrarray( + ffi_cif* cif, + ffi_raw* raw, + void** args); + +size_t +ffi_raw_size( + ffi_cif* cif); + +/* This is analogous to the raw API, except it uses Java parameter + packing, even on 64-bit machines. I.e. on 64-bit machines + longs and doubles are followed by an empty 64-bit word. */ +void +ffi_java_raw_call( +/*@dependent@*/ ffi_cif* cif, + void (*fn)(void), +/*@out@*/ void* rvalue, +/*@dependent@*/ ffi_raw* avalue); + +void +ffi_java_ptrarray_to_raw( + ffi_cif* cif, + void** args, + ffi_raw* raw); + +void +ffi_java_raw_to_ptrarray( + ffi_cif* cif, + ffi_raw* raw, + void** args); + +size_t +ffi_java_raw_size( + ffi_cif* cif); + +/* ---- Definitions for closures ----------------------------------------- */ + +#if FFI_CLOSURES + +typedef struct ffi_closure { + char tramp[FFI_TRAMPOLINE_SIZE]; + ffi_cif* cif; + void (*fun)(ffi_cif*,void*,void**,void*); + void* user_data; +} ffi_closure; + +ffi_status +ffi_prep_closure( + ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void* user_data); + +void ffi_closure_free(void *); +void *ffi_closure_alloc (size_t size, void **code); + +typedef struct ffi_raw_closure { + char tramp[FFI_TRAMPOLINE_SIZE]; + ffi_cif* cif; + +#if !FFI_NATIVE_RAW_API + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + void (*translate_args)(ffi_cif*,void*,void**,void*); + void* this_closure; +#endif + + void (*fun)(ffi_cif*,void*,ffi_raw*,void*); + void* user_data; +} ffi_raw_closure; + +ffi_status +ffi_prep_raw_closure( + ffi_raw_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void* user_data); + +ffi_status +ffi_prep_java_raw_closure( + ffi_raw_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void* user_data); + +#endif // FFI_CLOSURES + +/* ---- Public interface definition -------------------------------------- */ + +ffi_status +ffi_prep_cif( +/*@out@*/ /*@partial@*/ ffi_cif* cif, + ffi_abi abi, + unsigned int nargs, +/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype, +/*@dependent@*/ ffi_type** atypes); + +void +ffi_call( +/*@dependent@*/ ffi_cif* cif, + void (*fn)(void), +/*@out@*/ void* rvalue, +/*@dependent@*/ void** avalue); + +/* Useful for eliminating compiler warnings */ +#define FFI_FN(f) ((void (*)(void))f) + +#endif // #ifndef LIBFFI_ASM +/* ---- Definitions shared with assembly code ---------------------------- */ + +/* If these change, update src/mips/ffitarget.h. */ +#define FFI_TYPE_VOID 0 +#define FFI_TYPE_INT 1 +#define FFI_TYPE_FLOAT 2 +#define FFI_TYPE_DOUBLE 3 + +#ifdef HAVE_LONG_DOUBLE +# define FFI_TYPE_LONGDOUBLE 4 +#else +# define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE +#endif + +#define FFI_TYPE_UINT8 5 +#define FFI_TYPE_SINT8 6 +#define FFI_TYPE_UINT16 7 +#define FFI_TYPE_SINT16 8 +#define FFI_TYPE_UINT32 9 +#define FFI_TYPE_SINT32 10 +#define FFI_TYPE_UINT64 11 +#define FFI_TYPE_SINT64 12 +#define FFI_TYPE_STRUCT 13 +#define FFI_TYPE_POINTER 14 + +/* This should always refer to the last type code (for sanity checks) */ +#define FFI_TYPE_LAST FFI_TYPE_POINTER + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef LIBFFI_H diff --git a/python/Modules/_ctypes/libffi_osx/include/ffi_common.h b/python/Modules/_ctypes/libffi_osx/include/ffi_common.h new file mode 100755 index 0000000..685a358 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/include/ffi_common.h @@ -0,0 +1,102 @@ +/* ----------------------------------------------------------------------- + ffi_common.h - Copyright (c) 1996 Red Hat, Inc. + + Common internal definitions and macros. Only necessary for building + libffi. + ----------------------------------------------------------------------- */ + +#ifndef FFI_COMMON_H +#define FFI_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fficonfig.h" + +/* Do not move this. Some versions of AIX are very picky about where + this is positioned. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX +# pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char* alloca(); +# endif +# endif +# endif +#endif + +/* Check for the existence of memcpy. */ +#if STDC_HEADERS +# include +#else +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy((s), (d), (n)) +# endif +#endif + +/*#if defined(FFI_DEBUG) +#include +#endif*/ + +#ifdef FFI_DEBUG +#include + +/*@exits@*/ void +ffi_assert( +/*@temp@*/ char* expr, +/*@temp@*/ char* file, + int line); +void +ffi_stop_here(void); +void +ffi_type_test( +/*@temp@*/ /*@out@*/ ffi_type* a, +/*@temp@*/ char* file, + int line); + +# define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) +# define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) +# define FFI_ASSERT_VALID_TYPE(x) ffi_type_test(x, __FILE__, __LINE__) +#else +# define FFI_ASSERT(x) +# define FFI_ASSERT_AT(x, f, l) +# define FFI_ASSERT_VALID_TYPE(x) +#endif // #ifdef FFI_DEBUG + +#define ALIGN(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1)) + +/* Perform machine dependent cif processing */ +ffi_status +ffi_prep_cif_machdep( + ffi_cif* cif); + +/* Extended cif, used in callback from assembly routine */ +typedef struct extended_cif { +/*@dependent@*/ ffi_cif* cif; +/*@dependent@*/ void* rvalue; +/*@dependent@*/ void** avalue; +} extended_cif; + +/* Terse sized type definitions. */ +typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); +typedef signed int SINT8 __attribute__((__mode__(__QI__))); +typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); +typedef signed int SINT16 __attribute__((__mode__(__HI__))); +typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); +typedef signed int SINT32 __attribute__((__mode__(__SI__))); +typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); +typedef signed int SINT64 __attribute__((__mode__(__DI__))); +typedef float FLOAT32; + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef FFI_COMMON_H \ No newline at end of file diff --git a/python/Modules/_ctypes/libffi_osx/include/fficonfig.h b/python/Modules/_ctypes/libffi_osx/include/fficonfig.h new file mode 100755 index 0000000..2172490 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/include/fficonfig.h @@ -0,0 +1,150 @@ +/* Manually created fficonfig.h for Darwin on PowerPC or Intel + + This file is manually generated to do away with the need for autoconf and + therefore make it easier to cross-compile and build fat binaries. + + NOTE: This file was added by PyObjC. +*/ + +#ifndef MACOSX +#error "This file is only supported on Mac OS X" +#endif + +#if defined(__i386__) +# define BYTEORDER 1234 +# undef HOST_WORDS_BIG_ENDIAN +# undef WORDS_BIGENDIAN +# define SIZEOF_DOUBLE 8 +# define HAVE_LONG_DOUBLE 1 +# define SIZEOF_LONG_DOUBLE 16 + +#elif defined(__x86_64__) +# define BYTEORDER 1234 +# undef HOST_WORDS_BIG_ENDIAN +# undef WORDS_BIGENDIAN +# define SIZEOF_DOUBLE 8 +# define HAVE_LONG_DOUBLE 1 +# define SIZEOF_LONG_DOUBLE 16 + +#elif defined(__ppc__) +# define BYTEORDER 4321 +# define HOST_WORDS_BIG_ENDIAN 1 +# define WORDS_BIGENDIAN 1 +# define SIZEOF_DOUBLE 8 +# if __GNUC__ >= 4 +# define HAVE_LONG_DOUBLE 1 +# define SIZEOF_LONG_DOUBLE 16 +# else +# undef HAVE_LONG_DOUBLE +# define SIZEOF_LONG_DOUBLE 8 +# endif + +#elif defined(__ppc64__) +# define BYTEORDER 4321 +# define HOST_WORDS_BIG_ENDIAN 1 +# define WORDS_BIGENDIAN 1 +# define SIZEOF_DOUBLE 8 +# define HAVE_LONG_DOUBLE 1 +# define SIZEOF_LONG_DOUBLE 16 + +#else +#error "Unknown CPU type" +#endif + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Define to the flags needed for the .section .eh_frame directive. */ +#define EH_FRAME_FLAGS "aw" + +/* Define this if you want extra debugging. */ +/* #undef FFI_DEBUG */ + +/* Define this is you do not want support for the raw API. */ +#define FFI_NO_RAW_API 1 + +/* Define this if you do not want support for aggregate types. */ +/* #undef FFI_NO_STRUCTS */ + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if your assembler supports .register. */ +/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ + +/* Define if your assembler and linker support unaligned PC relative relocs. */ +/* #undef HAVE_AS_SPARC_UA_PCREL */ + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define if mmap with MAP_ANON(YMOUS) works. */ +#define HAVE_MMAP_ANON 1 + +/* Define if mmap of /dev/zero works. */ +/* #undef HAVE_MMAP_DEV_ZERO */ + +/* Define if read-only mmap of a plain file works. */ +#define HAVE_MMAP_FILE 1 + +/* Define if .eh_frame sections should be read-only. */ +/* #undef HAVE_RO_EH_FRAME */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "libffi" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "http://gcc.gnu.org/bugs.html" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libffi" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libffi 2.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libffi" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.1" + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define this if you are using Purify and want to suppress spurious messages. */ +/* #undef USING_PURIFY */ + +/* Version number of package */ +#define VERSION "2.1-pyobjc" + +#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE +# ifdef LIBFFI_ASM +# define FFI_HIDDEN(name) .hidden name +# else +# define FFI_HIDDEN __attribute__((visibility ("hidden"))) +# endif +#else +# ifdef LIBFFI_ASM +# define FFI_HIDDEN(name) +# else +# define FFI_HIDDEN +# endif +#endif \ No newline at end of file diff --git a/python/Modules/_ctypes/libffi_osx/include/ffitarget.h b/python/Modules/_ctypes/libffi_osx/include/ffitarget.h new file mode 100755 index 0000000..faaa30d --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/include/ffitarget.h @@ -0,0 +1,13 @@ +/* Dispatch to the right ffitarget file. This file is PyObjC specific; in a + normal build, the build environment copies the file to the right location or + sets up the right include flags. We want to do neither because that would + make building fat binaries harder. +*/ + +#if defined(__i386__) || defined(__x86_64__) +#include "x86-ffitarget.h" +#elif defined(__ppc__) || defined(__ppc64__) +#include "ppc-ffitarget.h" +#else +#error "Unsupported CPU type" +#endif \ No newline at end of file diff --git a/python/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h b/python/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h new file mode 100755 index 0000000..2318421 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h @@ -0,0 +1,104 @@ +/* -----------------------------------------------------------------*-C-*- + ppc-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for PowerPC. + + 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 CYGNUS SOLUTIONS 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 LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +/* ---- System specific configurations ----------------------------------- */ + +#if (defined(POWERPC) && defined(__powerpc64__)) || \ + (defined(POWERPC_DARWIN) && defined(__ppc64__)) +#define POWERPC64 +#endif + +#ifndef LIBFFI_ASM + +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + +#ifdef POWERPC + FFI_SYSV, + FFI_GCC_SYSV, + FFI_LINUX64, +# ifdef POWERPC64 + FFI_DEFAULT_ABI = FFI_LINUX64, +# else + FFI_DEFAULT_ABI = FFI_GCC_SYSV, +# endif +#endif + +#ifdef POWERPC_AIX + FFI_AIX, + FFI_DARWIN, + FFI_DEFAULT_ABI = FFI_AIX, +#endif + +#ifdef POWERPC_DARWIN + FFI_AIX, + FFI_DARWIN, + FFI_DEFAULT_ABI = FFI_DARWIN, +#endif + +#ifdef POWERPC_FREEBSD + FFI_SYSV, + FFI_GCC_SYSV, + FFI_LINUX64, + FFI_DEFAULT_ABI = FFI_SYSV, +#endif + + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; + +#endif // #ifndef LIBFFI_ASM + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 + +/* Needed for FFI_SYSV small structure returns. */ +#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST) + +#if defined(POWERPC64) /*|| defined(POWERPC_AIX)*/ +# define FFI_TRAMPOLINE_SIZE 48 +#elif defined(POWERPC_AIX) +# define FFI_TRAMPOLINE_SIZE 24 +#else +# define FFI_TRAMPOLINE_SIZE 40 +#endif + +#ifndef LIBFFI_ASM +# if defined(POWERPC_DARWIN) || defined(POWERPC_AIX) +typedef struct ffi_aix_trampoline_struct { + void* code_pointer; /* Pointer to ffi_closure_ASM */ + void* toc; /* TOC */ + void* static_chain; /* Pointer to closure */ +} ffi_aix_trampoline_struct; +# endif +#endif // #ifndef LIBFFI_ASM + +#endif // #ifndef LIBFFI_TARGET_H \ No newline at end of file diff --git a/python/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h b/python/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h new file mode 100755 index 0000000..55c2b6c --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h @@ -0,0 +1,88 @@ +/* -----------------------------------------------------------------*-C-*- + x86-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for x86 and x86-64. + + 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 CYGNUS SOLUTIONS 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 LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +/* ---- System specific configurations ----------------------------------- */ + +#if defined(X86_64) && defined(__i386__) +# undef X86_64 +# define X86 +#endif + +#if defined(__x86_64__) +# ifndef X86_64 +# define X86_64 +# endif +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM + +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + + /* ---- Intel x86 Win32 ---------- */ +#ifdef X86_WIN32 + FFI_SYSV, + FFI_STDCALL, + /* TODO: Add fastcall support for the sake of completeness */ + FFI_DEFAULT_ABI = FFI_SYSV, +#endif + + /* ---- Intel x86 and AMD x86-64 - */ +#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) + FFI_SYSV, + FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ +# ifdef __i386__ + FFI_DEFAULT_ABI = FFI_SYSV, +# else + FFI_DEFAULT_ABI = FFI_UNIX64, +# endif +#endif + + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; + +#endif // #ifndef LIBFFI_ASM + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 + +#if defined(X86_64) || (defined(__x86_64__) && defined(X86_DARWIN)) +# define FFI_TRAMPOLINE_SIZE 24 +# define FFI_NATIVE_RAW_API 0 +#else +# define FFI_TRAMPOLINE_SIZE 10 +# define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ +#endif + +#endif // #ifndef LIBFFI_TARGET_H \ No newline at end of file diff --git a/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S new file mode 100755 index 0000000..f143dbd --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S @@ -0,0 +1,365 @@ +#if defined(__ppc__) || defined(__ppc64__) + +/* ----------------------------------------------------------------------- + ppc-darwin.S - Copyright (c) 2000 John Hornkvist + Copyright (c) 2004 Free Software Foundation, Inc. + + PowerPC Assembly glue. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM + +#include +#include +#include +#include + +.text + .align 2 +.globl _ffi_prep_args + +.text + .align 2 +.globl _ffi_call_DARWIN + +.text + .align 2 +_ffi_call_DARWIN: +LFB0: + mr r12,r8 /* We only need r12 until the call, + so it doesn't have to be saved. */ + +LFB1: + /* Save the old stack pointer as AP. */ + mr r8,r1 + +LCFI0: +#if defined(__ppc64__) + /* Allocate the stack space we need. + r4 (size of input data) + 48 bytes (linkage area) + 40 bytes (saved registers) + 8 bytes (extra FPR) + r4 + 96 bytes total + */ + + addi r4,r4,-96 // Add our overhead. + li r0,-32 // Align to 32 bytes. + and r4,r4,r0 +#endif + stgux r1,r1,r4 // Grow the stack. + mflr r9 + + /* Save registers we use. */ +#if defined(__ppc64__) + std r27,-40(r8) +#endif + stg r28,MODE_CHOICE(-16,-32)(r8) + stg r29,MODE_CHOICE(-12,-24)(r8) + stg r30,MODE_CHOICE(-8,-16)(r8) + stg r31,MODE_CHOICE(-4,-8)(r8) + stg r9,SF_RETURN(r8) /* return address */ +#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */ + stg r2,MODE_CHOICE(20,40)(r1) +#endif + +LCFI1: +#if defined(__ppc64__) + mr r27,r3 // our extended_cif +#endif + /* Save arguments over call. */ + mr r31,r5 /* flags, */ + mr r30,r6 /* rvalue, */ + mr r29,r7 /* function address, */ + mr r28,r8 /* our AP. */ + +LCFI2: + /* Call ffi_prep_args. */ + mr r4,r1 + li r9,0 + mtctr r12 /* r12 holds address of _ffi_prep_args. */ + bctrl +#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */ + lg r2,MODE_CHOICE(20,40)(r1) +#endif + + /* Now do the call. + Set up cr1 with bits 4-7 of the flags. */ + mtcrf 0x40,r31 + + /* Load all those argument registers. + We have set up a nice stack frame, just load it into registers. */ + lg r3,SF_ARG1(r1) + lg r4,SF_ARG2(r1) + lg r5,SF_ARG3(r1) + lg r6,SF_ARG4(r1) + nop + lg r7,SF_ARG5(r1) + lg r8,SF_ARG6(r1) + lg r9,SF_ARG7(r1) + lg r10,SF_ARG8(r1) + + /* Load all the FP registers. */ + bf 6,L2 /* No floats to load. */ +#if defined(__ppc64__) + lfd f1,MODE_CHOICE(-16,-40)-(14*8)(r28) + lfd f2,MODE_CHOICE(-16,-40)-(13*8)(r28) + lfd f3,MODE_CHOICE(-16,-40)-(12*8)(r28) + lfd f4,MODE_CHOICE(-16,-40)-(11*8)(r28) + nop + lfd f5,MODE_CHOICE(-16,-40)-(10*8)(r28) + lfd f6,MODE_CHOICE(-16,-40)-(9*8)(r28) + lfd f7,MODE_CHOICE(-16,-40)-(8*8)(r28) + lfd f8,MODE_CHOICE(-16,-40)-(7*8)(r28) + nop + lfd f9,MODE_CHOICE(-16,-40)-(6*8)(r28) + lfd f10,MODE_CHOICE(-16,-40)-(5*8)(r28) + lfd f11,MODE_CHOICE(-16,-40)-(4*8)(r28) + lfd f12,MODE_CHOICE(-16,-40)-(3*8)(r28) + nop + lfd f13,MODE_CHOICE(-16,-40)-(2*8)(r28) + lfd f14,MODE_CHOICE(-16,-40)-(1*8)(r28) +#elif defined(__ppc__) + lfd f1,MODE_CHOICE(-16,-40)-(13*8)(r28) + lfd f2,MODE_CHOICE(-16,-40)-(12*8)(r28) + lfd f3,MODE_CHOICE(-16,-40)-(11*8)(r28) + lfd f4,MODE_CHOICE(-16,-40)-(10*8)(r28) + nop + lfd f5,MODE_CHOICE(-16,-40)-(9*8)(r28) + lfd f6,MODE_CHOICE(-16,-40)-(8*8)(r28) + lfd f7,MODE_CHOICE(-16,-40)-(7*8)(r28) + lfd f8,MODE_CHOICE(-16,-40)-(6*8)(r28) + nop + lfd f9,MODE_CHOICE(-16,-40)-(5*8)(r28) + lfd f10,MODE_CHOICE(-16,-40)-(4*8)(r28) + lfd f11,MODE_CHOICE(-16,-40)-(3*8)(r28) + lfd f12,MODE_CHOICE(-16,-40)-(2*8)(r28) + nop + lfd f13,MODE_CHOICE(-16,-40)-(1*8)(r28) +#else +#error undefined architecture +#endif + +L2: + mr r12,r29 // Put the target address in r12 as specified. + mtctr r12 // Get the address to call into CTR. + nop + nop + bctrl // Make the call. + + // Deal with the return value. +#if defined(__ppc64__) + mtcrf 0x3,r31 // flags in cr6 and cr7 + bt 27,L(st_return_value) +#elif defined(__ppc__) + mtcrf 0x1,r31 // flags in cr7 +#else +#error undefined architecture +#endif + + bt 30,L(done_return_value) + bt 29,L(fp_return_value) + stg r3,0(r30) +#if defined(__ppc__) + bf 28,L(done_return_value) // Store the second long if necessary. + stg r4,4(r30) +#endif + // Fall through + +L(done_return_value): + lg r1,0(r1) // Restore stack pointer. + // Restore the registers we used. + lg r9,SF_RETURN(r1) // return address + lg r31,MODE_CHOICE(-4,-8)(r1) + mtlr r9 + lg r30,MODE_CHOICE(-8,-16)(r1) + lg r29,MODE_CHOICE(-12,-24)(r1) + lg r28,MODE_CHOICE(-16,-32)(r1) +#if defined(__ppc64__) + ld r27,-40(r1) +#endif + blr + +#if defined(__ppc64__) +L(st_return_value): + // Grow the stack enough to fit the registers. Leave room for 8 args + // to trample the 1st 8 slots in param area. + stgu r1,-SF_ROUND(280)(r1) // 64 + 104 + 48 + 64 + + // Store GPRs + std r3,SF_ARG9(r1) + std r4,SF_ARG10(r1) + std r5,SF_ARG11(r1) + std r6,SF_ARG12(r1) + nop + std r7,SF_ARG13(r1) + std r8,SF_ARG14(r1) + std r9,SF_ARG15(r1) + std r10,SF_ARG16(r1) + + // Store FPRs + nop + bf 26,L(call_struct_to_ram_form) + stfd f1,SF_ARG17(r1) + stfd f2,SF_ARG18(r1) + stfd f3,SF_ARG19(r1) + stfd f4,SF_ARG20(r1) + nop + stfd f5,SF_ARG21(r1) + stfd f6,SF_ARG22(r1) + stfd f7,SF_ARG23(r1) + stfd f8,SF_ARG24(r1) + nop + stfd f9,SF_ARG25(r1) + stfd f10,SF_ARG26(r1) + stfd f11,SF_ARG27(r1) + stfd f12,SF_ARG28(r1) + nop + stfd f13,SF_ARG29(r1) + +L(call_struct_to_ram_form): + ld r3,0(r27) // extended_cif->cif* + ld r3,16(r3) // ffi_cif->rtype* + addi r4,r1,SF_ARG9 // stored GPRs + addi r6,r1,SF_ARG17 // stored FPRs + li r5,0 // GPR size ptr (NULL) + li r7,0 // FPR size ptr (NULL) + li r8,0 // FPR count ptr (NULL) + li r10,0 // struct offset (NULL) + mr r9,r30 // return area + bl Lffi64_struct_to_ram_form$stub + lg r1,0(r1) // Restore stack pointer. + b L(done_return_value) +#endif + +L(fp_return_value): + /* Do we have long double to store? */ + bf 31,L(fd_return_value) + stfd f1,0(r30) + stfd f2,8(r30) + b L(done_return_value) + +L(fd_return_value): + /* Do we have double to store? */ + bf 28,L(float_return_value) + stfd f1,0(r30) + b L(done_return_value) + +L(float_return_value): + /* We only have a float to store. */ + stfs f1,0(r30) + b L(done_return_value) + +LFE1: +/* END(_ffi_call_DARWIN) */ + +/* Provide a null definition of _ffi_call_AIX. */ +.text + .align 2 +.globl _ffi_call_AIX +.text + .align 2 +_ffi_call_AIX: + blr +/* END(_ffi_call_AIX) */ + +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 ; Length of Common Information Entry +LSCIE1: + .long 0x0 ; CIE Identifier Tag + .byte 0x1 ; CIE Version + .ascii "zR\0" ; CIE Augmentation + .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor + .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor + .byte 0x41 ; CIE RA Column + .byte 0x1 ; uleb128 0x1; Augmentation size + .byte 0x10 ; FDE Encoding (pcrel) + .byte 0xc ; DW_CFA_def_cfa + .byte 0x1 ; uleb128 0x1 + .byte 0x0 ; uleb128 0x0 + .align LOG2_GPR_BYTES +LECIE1: +.globl _ffi_call_DARWIN.eh +_ffi_call_DARWIN.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 ; FDE Length + +LASFDE1: + .long LASFDE1-EH_frame1 ; FDE CIE offset + .g_long LFB0-. ; FDE initial location + .set L$set$3,LFE1-LFB0 + .g_long L$set$3 ; FDE address range + .byte 0x0 ; uleb128 0x0; Augmentation size + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$4,LCFI0-LFB1 + .long L$set$4 + .byte 0xd ; DW_CFA_def_cfa_register + .byte 0x08 ; uleb128 0x08 + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$5,LCFI1-LCFI0 + .long L$set$5 + .byte 0x11 ; DW_CFA_offset_extended_sf + .byte 0x41 ; uleb128 0x41 + .byte 0x7e ; sleb128 -2 + .byte 0x9f ; DW_CFA_offset, column 0x1f + .byte 0x1 ; uleb128 0x1 + .byte 0x9e ; DW_CFA_offset, column 0x1e + .byte 0x2 ; uleb128 0x2 + .byte 0x9d ; DW_CFA_offset, column 0x1d + .byte 0x3 ; uleb128 0x3 + .byte 0x9c ; DW_CFA_offset, column 0x1c + .byte 0x4 ; uleb128 0x4 + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$6,LCFI2-LCFI1 + .long L$set$6 + .byte 0xd ; DW_CFA_def_cfa_register + .byte 0x1c ; uleb128 0x1c + .align LOG2_GPR_BYTES +LEFDE1: + +#if defined(__ppc64__) +.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align LOG2_GPR_BYTES + +Lffi64_struct_to_ram_form$stub: + .indirect_symbol _ffi64_struct_to_ram_form + mflr r0 + bcl 20,31,LO$ffi64_struct_to_ram_form + +LO$ffi64_struct_to_ram_form: + mflr r11 + addis r11,r11,ha16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form) + mtlr r0 + lgu r12,lo16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form)(r11) + mtctr r12 + bctr + +.lazy_symbol_pointer +L_ffi64_struct_to_ram_form$lazy_ptr: + .indirect_symbol _ffi64_struct_to_ram_form + .g_long dyld_stub_binding_helper + +#endif // __ppc64__ +#endif // __ppc__ || __ppc64__ diff --git a/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h new file mode 100755 index 0000000..cf4bd50 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h @@ -0,0 +1,85 @@ +/* ----------------------------------------------------------------------- + ppc-darwin.h - Copyright (c) 2002, 2003, 2004, Free Software Foundation, + Inc. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + +#define L(x) x + +#define SF_ARG9 MODE_CHOICE(56,112) +#define SF_ARG10 MODE_CHOICE(60,120) +#define SF_ARG11 MODE_CHOICE(64,128) +#define SF_ARG12 MODE_CHOICE(68,136) +#define SF_ARG13 MODE_CHOICE(72,144) +#define SF_ARG14 MODE_CHOICE(76,152) +#define SF_ARG15 MODE_CHOICE(80,160) +#define SF_ARG16 MODE_CHOICE(84,168) +#define SF_ARG17 MODE_CHOICE(88,176) +#define SF_ARG18 MODE_CHOICE(92,184) +#define SF_ARG19 MODE_CHOICE(96,192) +#define SF_ARG20 MODE_CHOICE(100,200) +#define SF_ARG21 MODE_CHOICE(104,208) +#define SF_ARG22 MODE_CHOICE(108,216) +#define SF_ARG23 MODE_CHOICE(112,224) +#define SF_ARG24 MODE_CHOICE(116,232) +#define SF_ARG25 MODE_CHOICE(120,240) +#define SF_ARG26 MODE_CHOICE(124,248) +#define SF_ARG27 MODE_CHOICE(128,256) +#define SF_ARG28 MODE_CHOICE(132,264) +#define SF_ARG29 MODE_CHOICE(136,272) + +#define ASM_NEEDS_REGISTERS 4 +#define NUM_GPR_ARG_REGISTERS 8 +#define NUM_FPR_ARG_REGISTERS 13 + +#define FFI_TYPE_1_BYTE(x) ((x) == FFI_TYPE_UINT8 || (x) == FFI_TYPE_SINT8) +#define FFI_TYPE_2_BYTE(x) ((x) == FFI_TYPE_UINT16 || (x) == FFI_TYPE_SINT16) +#define FFI_TYPE_4_BYTE(x) \ + ((x) == FFI_TYPE_UINT32 || (x) == FFI_TYPE_SINT32 ||\ + (x) == FFI_TYPE_INT || (x) == FFI_TYPE_FLOAT) + +#if !defined(LIBFFI_ASM) + +enum { + FLAG_RETURNS_NOTHING = 1 << (31 - 30), // cr7 + FLAG_RETURNS_FP = 1 << (31 - 29), + FLAG_RETURNS_64BITS = 1 << (31 - 28), + FLAG_RETURNS_128BITS = 1 << (31 - 31), + + FLAG_RETURNS_STRUCT = 1 << (31 - 27), // cr6 + FLAG_STRUCT_CONTAINS_FP = 1 << (31 - 26), + + FLAG_ARG_NEEDS_COPY = 1 << (31 - 7), + FLAG_FP_ARGUMENTS = 1 << (31 - 6), // cr1.eq; specified by ABI + FLAG_4_GPR_ARGUMENTS = 1 << (31 - 5), + FLAG_RETVAL_REFERENCE = 1 << (31 - 4) +}; + +#if defined(__ppc64__) +void ffi64_struct_to_ram_form(const ffi_type*, const char*, unsigned int*, + const char*, unsigned int*, unsigned int*, char*, unsigned int*); +void ffi64_struct_to_reg_form(const ffi_type*, const char*, unsigned int*, + unsigned int*, char*, unsigned int*, char*, unsigned int*); +bool ffi64_stret_needs_ptr(const ffi_type* inType, + unsigned short*, unsigned short*); +#endif + +#endif // !defined(LIBFFI_ASM) \ No newline at end of file diff --git a/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S new file mode 100755 index 0000000..c3d30c2 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S @@ -0,0 +1,308 @@ +#if defined(__ppc__) + +/* ----------------------------------------------------------------------- + ppc-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation, + Inc. based on ppc_closure.S + + PowerPC Assembly glue. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM + +#include +#include // for FFI_TRAMPOLINE_SIZE +#include +#include + + .file "ppc-darwin_closure.S" +.text + .align LOG2_GPR_BYTES + .globl _ffi_closure_ASM + +.text + .align LOG2_GPR_BYTES + +_ffi_closure_ASM: +LFB1: + mflr r0 // Save return address + stg r0,SF_RETURN(r1) + +LCFI0: + /* 24/48 bytes (Linkage Area) + 32/64 bytes (outgoing parameter area, always reserved) + 104 bytes (13*8 from FPR) + 16/32 bytes (result) + 176/232 total bytes */ + + /* skip over caller save area and keep stack aligned to 16/32. */ + stgu r1,-SF_ROUND(176)(r1) + +LCFI1: + /* We want to build up an area for the parameters passed + in registers. (both floating point and integer) */ + + /* 176/256 bytes (callee stack frame aligned to 16/32) + 24/48 bytes (caller linkage area) + 200/304 (start of caller parameter area aligned to 4/8) + */ + + /* Save GPRs 3 - 10 (aligned to 4/8) + in the parents outgoing area. */ + stg r3,200(r1) + stg r4,204(r1) + stg r5,208(r1) + stg r6,212(r1) + stg r7,216(r1) + stg r8,220(r1) + stg r9,224(r1) + stg r10,228(r1) + + /* Save FPRs 1 - 13. (aligned to 8) */ + stfd f1,56(r1) + stfd f2,64(r1) + stfd f3,72(r1) + stfd f4,80(r1) + stfd f5,88(r1) + stfd f6,96(r1) + stfd f7,104(r1) + stfd f8,112(r1) + stfd f9,120(r1) + stfd f10,128(r1) + stfd f11,136(r1) + stfd f12,144(r1) + stfd f13,152(r1) + + // Set up registers for the routine that actually does the work. + mr r3,r11 // context pointer from the trampoline + addi r4,r1,160 // result storage + addi r5,r1,200 // saved GPRs + addi r6,r1,56 // saved FPRs + bl Lffi_closure_helper_DARWIN$stub + + /* Now r3 contains the return type. Use it to look up in a table + so we know how to deal with each type. */ + addi r5,r1,160 // Copy result storage pointer. + bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR. + mflr r4 // Move to r4. + slwi r3,r3,4 // Multiply return type by 16. + add r3,r3,r4 // Add contents of table to table address. + mtctr r3 + bctr + +LFE1: +/* Each of the ret_typeX code fragments has to be exactly 16 bytes long + (4 instructions). For cache effectiveness we align to a 16 byte boundary + first. */ + .align 4 + nop + nop + nop + +Lget_ret_type0_addr: + blrl + +/* case FFI_TYPE_VOID */ +Lret_type0: + b Lfinish + nop + nop + nop + +/* case FFI_TYPE_INT */ +Lret_type1: + lwz r3,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_FLOAT */ +Lret_type2: + lfs f1,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_DOUBLE */ +Lret_type3: + lfd f1,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_LONGDOUBLE */ +Lret_type4: + lfd f1,0(r5) + lfd f2,8(r5) + b Lfinish + nop + +/* case FFI_TYPE_UINT8 */ +Lret_type5: + lbz r3,3(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_SINT8 */ +Lret_type6: + lbz r3,3(r5) + extsb r3,r3 + b Lfinish + nop + +/* case FFI_TYPE_UINT16 */ +Lret_type7: + lhz r3,2(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_SINT16 */ +Lret_type8: + lha r3,2(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_UINT32 */ +Lret_type9: // same as Lret_type1 + lwz r3,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_SINT32 */ +Lret_type10: // same as Lret_type1 + lwz r3,0(r5) + b Lfinish + nop + nop + +/* case FFI_TYPE_UINT64 */ +Lret_type11: + lwz r3,0(r5) + lwz r4,4(r5) + b Lfinish + nop + +/* case FFI_TYPE_SINT64 */ +Lret_type12: // same as Lret_type11 + lwz r3,0(r5) + lwz r4,4(r5) + b Lfinish + nop + +/* case FFI_TYPE_STRUCT */ +Lret_type13: + b Lfinish + nop + nop + nop + +/* End 16-byte aligned cases */ +/* case FFI_TYPE_POINTER */ +// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types +// are added in future, the following code will need to be updated and +// padded to 16 bytes. +Lret_type14: + lg r3,0(r5) + // fall through + +/* case done */ +Lfinish: + addi r1,r1,SF_ROUND(176) // Restore stack pointer. + lg r0,SF_RETURN(r1) // Restore return address. + mtlr r0 // Restore link register. + blr + +/* END(ffi_closure_ASM) */ + +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 ; Length of Common Information Entry +LSCIE1: + .long 0x0 ; CIE Identifier Tag + .byte 0x1 ; CIE Version + .ascii "zR\0" ; CIE Augmentation + .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor + .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor + .byte 0x41 ; CIE RA Column + .byte 0x1 ; uleb128 0x1; Augmentation size + .byte 0x10 ; FDE Encoding (pcrel) + .byte 0xc ; DW_CFA_def_cfa + .byte 0x1 ; uleb128 0x1 + .byte 0x0 ; uleb128 0x0 + .align LOG2_GPR_BYTES +LECIE1: +.globl _ffi_closure_ASM.eh +_ffi_closure_ASM.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 ; FDE Length + +LASFDE1: + .long LASFDE1-EH_frame1 ; FDE CIE offset + .g_long LFB1-. ; FDE initial location + .set L$set$3,LFE1-LFB1 + .g_long L$set$3 ; FDE address range + .byte 0x0 ; uleb128 0x0; Augmentation size + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$3,LCFI1-LCFI0 + .long L$set$3 + .byte 0xe ; DW_CFA_def_cfa_offset + .byte 176,1 ; uleb128 176 + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$4,LCFI0-LFB1 + .long L$set$4 + .byte 0x11 ; DW_CFA_offset_extended_sf + .byte 0x41 ; uleb128 0x41 + .byte 0x7e ; sleb128 -2 + .align LOG2_GPR_BYTES + +LEFDE1: +.data + .align LOG2_GPR_BYTES +LDFCM0: +.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align LOG2_GPR_BYTES + +Lffi_closure_helper_DARWIN$stub: + .indirect_symbol _ffi_closure_helper_DARWIN + mflr r0 + bcl 20,31,LO$ffi_closure_helper_DARWIN + +LO$ffi_closure_helper_DARWIN: + mflr r11 + addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) + mtlr r0 + lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) + mtctr r12 + bctr + +.lazy_symbol_pointer +L_ffi_closure_helper_DARWIN$lazy_ptr: + .indirect_symbol _ffi_closure_helper_DARWIN + .g_long dyld_stub_binding_helper + + +#endif // __ppc__ diff --git a/python/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c new file mode 100755 index 0000000..8953d5f --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c @@ -0,0 +1,1776 @@ +#if defined(__ppc__) || defined(__ppc64__) + +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + Darwin ABI support (c) 2001 John Hornkvist + AIX ABI support (c) 2002 Free Software Foundation, Inc. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + +#include +#include + +#include +#include +#include +#include +#include + +#if 0 +#if defined(POWERPC_DARWIN) +#include // for sys_icache_invalidate() +#endif + +#else + +#pragma weak sys_icache_invalidate +extern void sys_icache_invalidate(void *start, size_t len); + +#endif + + +extern void ffi_closure_ASM(void); + +// The layout of a function descriptor. A C function pointer really +// points to one of these. +typedef struct aix_fd_struct { + void* code_pointer; + void* toc; +} aix_fd; + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments. + + The stack layout we want looks like this: + + | Return address from ffi_call_DARWIN | higher addresses + |--------------------------------------------| + | Previous backchain pointer 4/8 | stack pointer here + |--------------------------------------------|-\ <<< on entry to + | Saved r28-r31 (4/8)*4 | | ffi_call_DARWIN + |--------------------------------------------| | + | Parameters (at least 8*(4/8)=32/64) | | (176) +112 - +288 + |--------------------------------------------| | + | Space for GPR2 4/8 | | + |--------------------------------------------| | stack | + | Reserved (4/8)*2 | | grows | + |--------------------------------------------| | down V + | Space for callee's LR 4/8 | | + |--------------------------------------------| | lower addresses + | Saved CR 4/8 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 4/8 | | during + |--------------------------------------------|-/ <<< ffi_call_DARWIN + + Note: ppc64 CR is saved in the low word of a long on the stack. +*/ + +/*@-exportheader@*/ +void +ffi_prep_args( + extended_cif* inEcif, + unsigned *const stack) +/*@=exportheader@*/ +{ + /* Copy the ecif to a local var so we can trample the arg. + BC note: test this with GP later for possible problems... */ + volatile extended_cif* ecif = inEcif; + + const unsigned bytes = ecif->cif->bytes; + const unsigned flags = ecif->cif->flags; + + /* Cast the stack arg from int* to long*. sizeof(long) == 4 in 32-bit mode + and 8 in 64-bit mode. */ + unsigned long *const longStack = (unsigned long *const)stack; + + /* 'stacktop' points at the previous backchain pointer. */ +#if defined(__ppc64__) + // In ppc-darwin.s, an extra 96 bytes is reserved for the linkage area, + // saved registers, and an extra FPR. + unsigned long *const stacktop = + (unsigned long *)(unsigned long)((char*)longStack + bytes + 96); +#elif defined(__ppc__) + unsigned long *const stacktop = longStack + (bytes / sizeof(long)); +#else +#error undefined architecture +#endif + + /* 'fpr_base' points at the space for fpr1, and grows upwards as + we use FPR registers. */ + double* fpr_base = (double*)(stacktop - ASM_NEEDS_REGISTERS) - + NUM_FPR_ARG_REGISTERS; + +#if defined(__ppc64__) + // 64-bit saves an extra register, and uses an extra FPR. Knock fpr_base + // down a couple pegs. + fpr_base -= 2; +#endif + + unsigned int fparg_count = 0; + + /* 'next_arg' grows up as we put parameters in it. */ + unsigned long* next_arg = longStack + 6; /* 6 reserved positions. */ + + int i; + double double_tmp; + void** p_argv = ecif->avalue; + unsigned long gprvalue; + ffi_type** ptr = ecif->cif->arg_types; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT(stack == SF_ROUND(stack)); + FFI_ASSERT(stacktop == SF_ROUND(stacktop)); + FFI_ASSERT(bytes == SF_ROUND(bytes)); + + /* Deal with return values that are actually pass-by-reference. + Rule: + Return values are referenced by r3, so r4 is the first parameter. */ + + if (flags & FLAG_RETVAL_REFERENCE) + *next_arg++ = (unsigned long)(char*)ecif->rvalue; + + /* Now for the arguments. */ + for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++) + { + switch ((*ptr)->type) + { + /* If a floating-point parameter appears before all of the general- + purpose registers are filled, the corresponding GPRs that match + the size of the floating-point parameter are shadowed for the + benefit of vararg and pre-ANSI functions. */ + case FFI_TYPE_FLOAT: + double_tmp = *(float*)*p_argv; + + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = double_tmp; + + *(double*)next_arg = double_tmp; + + next_arg++; + fparg_count++; + FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + + break; + + case FFI_TYPE_DOUBLE: + double_tmp = *(double*)*p_argv; + + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *fpr_base++ = double_tmp; + + *(double*)next_arg = double_tmp; + + next_arg += MODE_CHOICE(2,1); + fparg_count++; + FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: +#if defined(__ppc64__) + if (fparg_count < NUM_FPR_ARG_REGISTERS) + *(long double*)fpr_base = *(long double*)*p_argv; +#elif defined(__ppc__) + if (fparg_count < NUM_FPR_ARG_REGISTERS - 1) + *(long double*)fpr_base = *(long double*)*p_argv; + else if (fparg_count == NUM_FPR_ARG_REGISTERS - 1) + *(double*)fpr_base = *(double*)*p_argv; +#else +#error undefined architecture +#endif + + *(long double*)next_arg = *(long double*)*p_argv; + fparg_count += 2; + fpr_base += 2; + next_arg += MODE_CHOICE(4,2); + FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + + break; +#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: +#if defined(__ppc64__) + gprvalue = *(long long*)*p_argv; + goto putgpr; +#elif defined(__ppc__) + *(long long*)next_arg = *(long long*)*p_argv; + next_arg += 2; + break; +#else +#error undefined architecture +#endif + + case FFI_TYPE_POINTER: + gprvalue = *(unsigned long*)*p_argv; + goto putgpr; + + case FFI_TYPE_UINT8: + gprvalue = *(unsigned char*)*p_argv; + goto putgpr; + + case FFI_TYPE_SINT8: + gprvalue = *(signed char*)*p_argv; + goto putgpr; + + case FFI_TYPE_UINT16: + gprvalue = *(unsigned short*)*p_argv; + goto putgpr; + + case FFI_TYPE_SINT16: + gprvalue = *(signed short*)*p_argv; + goto putgpr; + + case FFI_TYPE_STRUCT: + { +#if defined(__ppc64__) + unsigned int gprSize = 0; + unsigned int fprSize = 0; + + ffi64_struct_to_reg_form(*ptr, (char*)*p_argv, NULL, &fparg_count, + (char*)next_arg, &gprSize, (char*)fpr_base, &fprSize); + next_arg += gprSize / sizeof(long); + fpr_base += fprSize / sizeof(double); + +#elif defined(__ppc__) + char* dest_cpy = (char*)next_arg; + + /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, + SI 4 bytes) are aligned as if they were those modes. + Structures with 3 byte in size are padded upwards. */ + unsigned size_al = (*ptr)->size; + + /* If the first member of the struct is a double, then align + the struct to double-word. */ + if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) + size_al = ALIGN((*ptr)->size, 8); + + if (ecif->cif->abi == FFI_DARWIN) + { + if (size_al < 3) + dest_cpy += 4 - size_al; + } + + memcpy((char*)dest_cpy, (char*)*p_argv, size_al); + next_arg += (size_al + 3) / 4; +#else +#error undefined architecture +#endif + break; + } + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + gprvalue = *(unsigned*)*p_argv; + +putgpr: + *next_arg++ = gprvalue; + break; + + default: + break; + } + } + + /* Check that we didn't overrun the stack... */ + //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); + //FFI_ASSERT((unsigned *)fpr_base + // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); + //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); +} + +#if defined(__ppc64__) + +bool +ffi64_struct_contains_fp( + const ffi_type* inType) +{ + bool containsFP = false; + unsigned int i; + + for (i = 0; inType->elements[i] != NULL && !containsFP; i++) + { + if (inType->elements[i]->type == FFI_TYPE_FLOAT || + inType->elements[i]->type == FFI_TYPE_DOUBLE || + inType->elements[i]->type == FFI_TYPE_LONGDOUBLE) + containsFP = true; + else if (inType->elements[i]->type == FFI_TYPE_STRUCT) + containsFP = ffi64_struct_contains_fp(inType->elements[i]); + } + + return containsFP; +} + +#endif // defined(__ppc64__) + +/* Perform machine dependent cif processing. */ +ffi_status +ffi_prep_cif_machdep( + ffi_cif* cif) +{ + /* All this is for the DARWIN ABI. */ + int i; + ffi_type** ptr; + int intarg_count = 0; + int fparg_count = 0; + unsigned int flags = 0; + unsigned int size_al = 0; + + /* All the machine-independent calculation of cif->bytes will be wrong. + Redo the calculation for DARWIN. */ + + /* Space for the frame pointer, callee's LR, CR, etc, and for + the asm's temp regs. */ + unsigned int bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long); + + /* Return value handling. The rules are as follows: + - 32-bit (or less) integer values are returned in gpr3; + - Structures of size <= 4 bytes also returned in gpr3; + - 64-bit integer values and structures between 5 and 8 bytes are + returned in gpr3 and gpr4; + - Single/double FP values are returned in fpr1; + - Long double FP (if not equivalent to double) values are returned in + fpr1 and fpr2; + - Larger structures values are allocated space and a pointer is passed + as the first argument. */ + switch (cif->rtype->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + flags |= FLAG_RETURNS_128BITS; + flags |= FLAG_RETURNS_FP; + break; +#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; + break; + +#if defined(__ppc64__) + case FFI_TYPE_POINTER: +#endif + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: + { +#if defined(__ppc64__) + + if (ffi64_stret_needs_ptr(cif->rtype, NULL, NULL)) + { + flags |= FLAG_RETVAL_REFERENCE; + flags |= FLAG_RETURNS_NOTHING; + intarg_count++; + } + else + { + flags |= FLAG_RETURNS_STRUCT; + + if (ffi64_struct_contains_fp(cif->rtype)) + flags |= FLAG_STRUCT_CONTAINS_FP; + } + +#elif defined(__ppc__) + + flags |= FLAG_RETVAL_REFERENCE; + flags |= FLAG_RETURNS_NOTHING; + intarg_count++; + +#else +#error undefined architecture +#endif + break; + } + + case FFI_TYPE_VOID: + flags |= FLAG_RETURNS_NOTHING; + break; + + default: + /* Returns 32-bit integer, or similar. Nothing to do here. */ + break; + } + + /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the + first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest + goes on the stack. Structures are passed as a pointer to a copy of + the structure. Stuff on the stack needs to keep proper alignment. */ + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + switch ((*ptr)->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + fparg_count++; + /* If this FP arg is going on the stack, it must be + 8-byte-aligned. */ + if (fparg_count > NUM_FPR_ARG_REGISTERS + && intarg_count % 2 != 0) + intarg_count++; + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + fparg_count += 2; + /* If this FP arg is going on the stack, it must be + 8-byte-aligned. */ + + if ( +#if defined(__ppc64__) + fparg_count > NUM_FPR_ARG_REGISTERS + 1 +#elif defined(__ppc__) + fparg_count > NUM_FPR_ARG_REGISTERS +#else +#error undefined architecture +#endif + && intarg_count % 2 != 0) + intarg_count++; + + intarg_count += 2; + break; +#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + /* 'long long' arguments are passed as two words, but + either both words must fit in registers or both go + on the stack. If they go on the stack, they must + be 8-byte-aligned. */ + if (intarg_count == NUM_GPR_ARG_REGISTERS - 1 + || (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0)) + intarg_count++; + + intarg_count += MODE_CHOICE(2,1); + + break; + + case FFI_TYPE_STRUCT: + size_al = (*ptr)->size; + /* If the first member of the struct is a double, then align + the struct to double-word. */ + if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) + size_al = ALIGN((*ptr)->size, 8); + +#if defined(__ppc64__) + // Look for FP struct members. + unsigned int j; + + for (j = 0; (*ptr)->elements[j] != NULL; j++) + { + if ((*ptr)->elements[j]->type == FFI_TYPE_FLOAT || + (*ptr)->elements[j]->type == FFI_TYPE_DOUBLE) + { + fparg_count++; + + if (fparg_count > NUM_FPR_ARG_REGISTERS) + intarg_count++; + } + else if ((*ptr)->elements[j]->type == FFI_TYPE_LONGDOUBLE) + { + fparg_count += 2; + + if (fparg_count > NUM_FPR_ARG_REGISTERS + 1) + intarg_count += 2; + } + else + intarg_count++; + } +#elif defined(__ppc__) + intarg_count += (size_al + 3) / 4; +#else +#error undefined architecture +#endif + + break; + + default: + /* Everything else is passed as a 4/8-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + break; + } + } + + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + { + flags |= FLAG_FP_ARGUMENTS; +#if defined(__ppc64__) + bytes += (NUM_FPR_ARG_REGISTERS + 1) * sizeof(double); +#elif defined(__ppc__) + bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); +#else +#error undefined architecture +#endif + } + + /* Stack space. */ +#if defined(__ppc64__) + if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS) + bytes += (intarg_count + fparg_count) * sizeof(long); +#elif defined(__ppc__) + if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS) + bytes += (intarg_count + 2 * fparg_count) * sizeof(long); +#else +#error undefined architecture +#endif + else + bytes += NUM_GPR_ARG_REGISTERS * sizeof(long); + + /* The stack space allocated needs to be a multiple of 16/32 bytes. */ + bytes = SF_ROUND(bytes); + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +/*@-declundef@*/ +/*@-exportheader@*/ +extern void +ffi_call_AIX( +/*@out@*/ extended_cif*, + unsigned, + unsigned, +/*@out@*/ unsigned*, + void (*fn)(void), + void (*fn2)(extended_cif*, unsigned *const)); + +extern void +ffi_call_DARWIN( +/*@out@*/ extended_cif*, + unsigned long, + unsigned, +/*@out@*/ unsigned*, + void (*fn)(void), + void (*fn2)(extended_cif*, unsigned *const)); +/*@=declundef@*/ +/*@=exportheader@*/ + +void +ffi_call( +/*@dependent@*/ ffi_cif* cif, + void (*fn)(void), +/*@out@*/ void* rvalue, +/*@dependent@*/ void** avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return + value address then we need to make one. */ + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + /*@-sysunrecog@*/ + ecif.rvalue = alloca(cif->rtype->size); + /*@=sysunrecog@*/ + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_AIX: + /*@-usedef@*/ + ffi_call_AIX(&ecif, -cif->bytes, + cif->flags, ecif.rvalue, fn, ffi_prep_args); + /*@=usedef@*/ + break; + + case FFI_DARWIN: + /*@-usedef@*/ + ffi_call_DARWIN(&ecif, -(long)cif->bytes, + cif->flags, ecif.rvalue, fn, ffi_prep_args); + /*@=usedef@*/ + break; + + default: + FFI_ASSERT(0); + break; + } +} + +/* here I'd like to add the stack frame layout we use in darwin_closure.S + and aix_clsoure.S + + SP previous -> +---------------------------------------+ <--- child frame + | back chain to caller 4 | + +---------------------------------------+ 4 + | saved CR 4 | + +---------------------------------------+ 8 + | saved LR 4 | + +---------------------------------------+ 12 + | reserved for compilers 4 | + +---------------------------------------+ 16 + | reserved for binders 4 | + +---------------------------------------+ 20 + | saved TOC pointer 4 | + +---------------------------------------+ 24 + | always reserved 8*4=32 (previous GPRs)| + | according to the linkage convention | + | from AIX | + +---------------------------------------+ 56 + | our FPR area 13*8=104 | + | f1 | + | . | + | f13 | + +---------------------------------------+ 160 + | result area 8 | + +---------------------------------------+ 168 + | alignement to the next multiple of 16 | +SP current --> +---------------------------------------+ 176 <- parent frame + | back chain to caller 4 | + +---------------------------------------+ 180 + | saved CR 4 | + +---------------------------------------+ 184 + | saved LR 4 | + +---------------------------------------+ 188 + | reserved for compilers 4 | + +---------------------------------------+ 192 + | reserved for binders 4 | + +---------------------------------------+ 196 + | saved TOC pointer 4 | + +---------------------------------------+ 200 + | always reserved 8*4=32 we store our | + | GPRs here | + | r3 | + | . | + | r10 | + +---------------------------------------+ 232 + | overflow part | + +---------------------------------------+ xxx + | ???? | + +---------------------------------------+ xxx +*/ + +#if !defined(POWERPC_DARWIN) + +#define MIN_LINE_SIZE 32 + +static void +flush_icache( + char* addr) +{ +#ifndef _AIX + __asm__ volatile ( + "dcbf 0,%0\n" + "sync\n" + "icbi 0,%0\n" + "sync\n" + "isync" + : : "r" (addr) : "memory"); +#endif +} + +static void +flush_range( + char* addr, + int size) +{ + int i; + + for (i = 0; i < size; i += MIN_LINE_SIZE) + flush_icache(addr + i); + + flush_icache(addr + size - 1); +} + +#endif // !defined(POWERPC_DARWIN) + +ffi_status +ffi_prep_closure( + ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void* user_data) +{ + switch (cif->abi) + { + case FFI_DARWIN: + { + FFI_ASSERT (cif->abi == FFI_DARWIN); + + unsigned int* tramp = (unsigned int*)&closure->tramp[0]; + +#if defined(__ppc64__) + tramp[0] = 0x7c0802a6; // mflr r0 + tramp[1] = 0x429f0005; // bcl 20,31,+0x8 + tramp[2] = 0x7d6802a6; // mflr r11 + tramp[3] = 0x7c0803a6; // mtlr r0 + tramp[4] = 0xe98b0018; // ld r12,24(r11) + tramp[5] = 0x7d8903a6; // mtctr r12 + tramp[6] = 0xe96b0020; // ld r11,32(r11) + tramp[7] = 0x4e800420; // bctr + *(unsigned long*)&tramp[8] = (unsigned long)ffi_closure_ASM; + *(unsigned long*)&tramp[10] = (unsigned long)closure; +#elif defined(__ppc__) + tramp[0] = 0x7c0802a6; // mflr r0 + tramp[1] = 0x429f0005; // bcl 20,31,+0x8 + tramp[2] = 0x7d6802a6; // mflr r11 + tramp[3] = 0x7c0803a6; // mtlr r0 + tramp[4] = 0x818b0018; // lwz r12,24(r11) + tramp[5] = 0x7d8903a6; // mtctr r12 + tramp[6] = 0x816b001c; // lwz r11,28(r11) + tramp[7] = 0x4e800420; // bctr + tramp[8] = (unsigned long)ffi_closure_ASM; + tramp[9] = (unsigned long)closure; +#else +#error undefined architecture +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + // Flush the icache. Only necessary on Darwin. +#if defined(POWERPC_DARWIN) + sys_icache_invalidate(closure->tramp, FFI_TRAMPOLINE_SIZE); +#else + flush_range(closure->tramp, FFI_TRAMPOLINE_SIZE); +#endif + + break; + } + + case FFI_AIX: + { + FFI_ASSERT (cif->abi == FFI_AIX); + + ffi_aix_trampoline_struct* tramp_aix = + (ffi_aix_trampoline_struct*)(closure->tramp); + aix_fd* fd = (aix_fd*)(void*)ffi_closure_ASM; + + tramp_aix->code_pointer = fd->code_pointer; + tramp_aix->toc = fd->toc; + tramp_aix->static_chain = closure; + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + break; + } + + default: + return FFI_BAD_ABI; + } + + return FFI_OK; +} + +#if defined(__ppc__) + typedef double ldbits[2]; + + typedef union + { + ldbits lb; + long double ld; + } ldu; +#endif + +typedef union +{ + float f; + double d; +} ffi_dblfl; + +/* The trampoline invokes ffi_closure_ASM, and on entry, r11 holds the + address of the closure. After storing the registers that could possibly + contain parameters to be passed into the stack frame and setting up space + for a return value, ffi_closure_ASM invokes the following helper function + to do most of the work. */ +int +ffi_closure_helper_DARWIN( + ffi_closure* closure, + void* rvalue, + unsigned long* pgr, + ffi_dblfl* pfr) +{ + /* rvalue is the pointer to space for return value in closure assembly + pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM + pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */ + +#if defined(__ppc__) + ldu temp_ld; +#endif + + double temp; + unsigned int i; + unsigned int nf = 0; /* number of FPRs already used. */ + unsigned int ng = 0; /* number of GPRs already used. */ + ffi_cif* cif = closure->cif; + long avn = cif->nargs; + void** avalue = alloca(cif->nargs * sizeof(void*)); + ffi_type** arg_types = cif->arg_types; + + /* Copy the caller's structure return value address so that the closure + returns the data directly to the caller. */ +#if defined(__ppc64__) + if (cif->rtype->type == FFI_TYPE_STRUCT && + ffi64_stret_needs_ptr(cif->rtype, NULL, NULL)) +#elif defined(__ppc__) + if (cif->rtype->type == FFI_TYPE_STRUCT) +#else +#error undefined architecture +#endif + { + rvalue = (void*)*pgr; + pgr++; + ng++; + } + + /* Grab the addresses of the arguments from the stack frame. */ + for (i = 0; i < avn; i++) + { + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: + avalue[i] = (char*)pgr + MODE_CHOICE(3,7); + ng++; + pgr++; + break; + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: + avalue[i] = (char*)pgr + MODE_CHOICE(2,6); + ng++; + pgr++; + break; + +#if defined(__ppc__) + case FFI_TYPE_POINTER: +#endif + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + avalue[i] = (char*)pgr + MODE_CHOICE(0,4); + ng++; + pgr++; + + break; + + case FFI_TYPE_STRUCT: + if (cif->abi == FFI_DARWIN) + { +#if defined(__ppc64__) + unsigned int gprSize = 0; + unsigned int fprSize = 0; + unsigned int savedFPRSize = fprSize; + + avalue[i] = alloca(arg_types[i]->size); + ffi64_struct_to_ram_form(arg_types[i], (const char*)pgr, + &gprSize, (const char*)pfr, &fprSize, &nf, avalue[i], NULL); + + ng += gprSize / sizeof(long); + pgr += gprSize / sizeof(long); + pfr += (fprSize - savedFPRSize) / sizeof(double); + +#elif defined(__ppc__) + /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, + SI 4 bytes) are aligned as if they were those modes. */ + unsigned int size_al = size_al = arg_types[i]->size; + + /* If the first member of the struct is a double, then align + the struct to double-word. */ + if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE) + size_al = ALIGN(arg_types[i]->size, 8); + + if (size_al < 3) + avalue[i] = (void*)pgr + MODE_CHOICE(4,8) - size_al; + else + avalue[i] = (void*)pgr; + + ng += (size_al + 3) / sizeof(long); + pgr += (size_al + 3) / sizeof(long); +#else +#error undefined architecture +#endif + } + + break; + +#if defined(__ppc64__) + case FFI_TYPE_POINTER: +#endif + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + /* Long long ints are passed in 1 or 2 GPRs. */ + avalue[i] = pgr; + ng += MODE_CHOICE(2,1); + pgr += MODE_CHOICE(2,1); + + break; + + case FFI_TYPE_FLOAT: + /* A float value consumes a GPR. + There are 13 64-bit floating point registers. */ + if (nf < NUM_FPR_ARG_REGISTERS) + { + temp = pfr->d; + pfr->f = (float)temp; + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pgr; + + nf++; + ng++; + pgr++; + break; + + case FFI_TYPE_DOUBLE: + /* A double value consumes one or two GPRs. + There are 13 64bit floating point registers. */ + if (nf < NUM_FPR_ARG_REGISTERS) + { + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pgr; + + nf++; + ng += MODE_CHOICE(2,1); + pgr += MODE_CHOICE(2,1); + + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + + case FFI_TYPE_LONGDOUBLE: +#if defined(__ppc64__) + if (nf < NUM_FPR_ARG_REGISTERS) + { + avalue[i] = pfr; + pfr += 2; + } +#elif defined(__ppc__) + /* A long double value consumes 2/4 GPRs and 2 FPRs. + There are 13 64bit floating point registers. */ + if (nf < NUM_FPR_ARG_REGISTERS - 1) + { + avalue[i] = pfr; + pfr += 2; + } + /* Here we have the situation where one part of the long double + is stored in fpr13 and the other part is already on the stack. + We use a union to pass the long double to avalue[i]. */ + else if (nf == NUM_FPR_ARG_REGISTERS - 1) + { + memcpy (&temp_ld.lb[0], pfr, sizeof(temp_ld.lb[0])); + memcpy (&temp_ld.lb[1], pgr + 2, sizeof(temp_ld.lb[1])); + avalue[i] = &temp_ld.ld; + } +#else +#error undefined architecture +#endif + else + avalue[i] = pgr; + + nf += 2; + ng += MODE_CHOICE(4,2); + pgr += MODE_CHOICE(4,2); + + break; + +#endif /* FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE */ + + default: + FFI_ASSERT(0); + break; + } + } + + (closure->fun)(cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_ASM to perform return type promotions. */ + return cif->rtype->type; +} + +#if defined(__ppc64__) + +/* ffi64_struct_to_ram_form + + Rebuild a struct's natural layout from buffers of concatenated registers. + Return the number of registers used. + inGPRs[0-7] == r3, inFPRs[0-7] == f1 ... +*/ +void +ffi64_struct_to_ram_form( + const ffi_type* inType, + const char* inGPRs, + unsigned int* ioGPRMarker, + const char* inFPRs, + unsigned int* ioFPRMarker, + unsigned int* ioFPRsUsed, + char* outStruct, // caller-allocated + unsigned int* ioStructMarker) +{ + unsigned int srcGMarker = 0; + unsigned int srcFMarker = 0; + unsigned int savedFMarker = 0; + unsigned int fprsUsed = 0; + unsigned int savedFPRsUsed = 0; + unsigned int destMarker = 0; + + static unsigned int recurseCount = 0; + + if (ioGPRMarker) + srcGMarker = *ioGPRMarker; + + if (ioFPRMarker) + { + srcFMarker = *ioFPRMarker; + savedFMarker = srcFMarker; + } + + if (ioFPRsUsed) + { + fprsUsed = *ioFPRsUsed; + savedFPRsUsed = fprsUsed; + } + + if (ioStructMarker) + destMarker = *ioStructMarker; + + size_t i; + + switch (inType->size) + { + case 1: case 2: case 4: + srcGMarker += 8 - inType->size; + break; + + default: + break; + } + + for (i = 0; inType->elements[i] != NULL; i++) + { + switch (inType->elements[i]->type) + { + case FFI_TYPE_FLOAT: + srcFMarker = ALIGN(srcFMarker, 4); + srcGMarker = ALIGN(srcGMarker, 4); + destMarker = ALIGN(destMarker, 4); + + if (fprsUsed < NUM_FPR_ARG_REGISTERS) + { + *(float*)&outStruct[destMarker] = + (float)*(double*)&inFPRs[srcFMarker]; + srcFMarker += 8; + fprsUsed++; + } + else + *(float*)&outStruct[destMarker] = + (float)*(double*)&inGPRs[srcGMarker]; + + srcGMarker += 4; + destMarker += 4; + + // Skip to next GPR if next element won't fit and we're + // not already at a register boundary. + if (inType->elements[i + 1] != NULL && (destMarker % 8)) + { + if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && + (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || + (ALIGN(srcGMarker, 8) - srcGMarker) < 2) && + (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || + (ALIGN(srcGMarker, 8) - srcGMarker) < 4)) + srcGMarker = ALIGN(srcGMarker, 8); + } + + break; + + case FFI_TYPE_DOUBLE: + srcFMarker = ALIGN(srcFMarker, 8); + destMarker = ALIGN(destMarker, 8); + + if (fprsUsed < NUM_FPR_ARG_REGISTERS) + { + *(double*)&outStruct[destMarker] = + *(double*)&inFPRs[srcFMarker]; + srcFMarker += 8; + fprsUsed++; + } + else + *(double*)&outStruct[destMarker] = + *(double*)&inGPRs[srcGMarker]; + + destMarker += 8; + + // Skip next GPR + srcGMarker += 8; + srcGMarker = ALIGN(srcGMarker, 8); + + break; + + case FFI_TYPE_LONGDOUBLE: + destMarker = ALIGN(destMarker, 16); + + if (fprsUsed < NUM_FPR_ARG_REGISTERS) + { + srcFMarker = ALIGN(srcFMarker, 8); + srcGMarker = ALIGN(srcGMarker, 8); + *(long double*)&outStruct[destMarker] = + *(long double*)&inFPRs[srcFMarker]; + srcFMarker += 16; + fprsUsed += 2; + } + else + { + srcFMarker = ALIGN(srcFMarker, 16); + srcGMarker = ALIGN(srcGMarker, 16); + *(long double*)&outStruct[destMarker] = + *(long double*)&inGPRs[srcGMarker]; + } + + destMarker += 16; + + // Skip next 2 GPRs + srcGMarker += 16; + srcGMarker = ALIGN(srcGMarker, 8); + + break; + + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + { + if (inType->alignment == 1) // chars only + { + if (inType->size == 1) + outStruct[destMarker++] = inGPRs[srcGMarker++]; + else if (inType->size == 2) + { + outStruct[destMarker++] = inGPRs[srcGMarker++]; + outStruct[destMarker++] = inGPRs[srcGMarker++]; + i++; + } + else + { + memcpy(&outStruct[destMarker], + &inGPRs[srcGMarker], inType->size); + srcGMarker += inType->size; + destMarker += inType->size; + i += inType->size - 1; + } + } + else // chars and other stuff + { + outStruct[destMarker++] = inGPRs[srcGMarker++]; + + // Skip to next GPR if next element won't fit and we're + // not already at a register boundary. + if (inType->elements[i + 1] != NULL && (srcGMarker % 8)) + { + if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && + (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || + (ALIGN(srcGMarker, 8) - srcGMarker) < 2) && + (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || + (ALIGN(srcGMarker, 8) - srcGMarker) < 4)) + srcGMarker = ALIGN(srcGMarker, inType->alignment); // was 8 + } + } + + break; + } + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + srcGMarker = ALIGN(srcGMarker, 2); + destMarker = ALIGN(destMarker, 2); + + *(short*)&outStruct[destMarker] = + *(short*)&inGPRs[srcGMarker]; + srcGMarker += 2; + destMarker += 2; + + break; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + srcGMarker = ALIGN(srcGMarker, 4); + destMarker = ALIGN(destMarker, 4); + + *(int*)&outStruct[destMarker] = + *(int*)&inGPRs[srcGMarker]; + srcGMarker += 4; + destMarker += 4; + + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + srcGMarker = ALIGN(srcGMarker, 8); + destMarker = ALIGN(destMarker, 8); + + *(long long*)&outStruct[destMarker] = + *(long long*)&inGPRs[srcGMarker]; + srcGMarker += 8; + destMarker += 8; + + break; + + case FFI_TYPE_STRUCT: + recurseCount++; + ffi64_struct_to_ram_form(inType->elements[i], inGPRs, + &srcGMarker, inFPRs, &srcFMarker, &fprsUsed, + outStruct, &destMarker); + recurseCount--; + break; + + default: + FFI_ASSERT(0); // unknown element type + break; + } + } + + srcGMarker = ALIGN(srcGMarker, inType->alignment); + + // Take care of the special case for 16-byte structs, but not for + // nested structs. + if (recurseCount == 0 && srcGMarker == 16) + { + *(long double*)&outStruct[0] = *(long double*)&inGPRs[0]; + srcFMarker = savedFMarker; + fprsUsed = savedFPRsUsed; + } + + if (ioGPRMarker) + *ioGPRMarker = ALIGN(srcGMarker, 8); + + if (ioFPRMarker) + *ioFPRMarker = srcFMarker; + + if (ioFPRsUsed) + *ioFPRsUsed = fprsUsed; + + if (ioStructMarker) + *ioStructMarker = ALIGN(destMarker, 8); +} + +/* ffi64_struct_to_reg_form + + Copy a struct's elements into buffers that can be sliced into registers. + Return the sizes of the output buffers in bytes. Pass NULL buffer pointers + to calculate size only. + outGPRs[0-7] == r3, outFPRs[0-7] == f1 ... +*/ +void +ffi64_struct_to_reg_form( + const ffi_type* inType, + const char* inStruct, + unsigned int* ioStructMarker, + unsigned int* ioFPRsUsed, + char* outGPRs, // caller-allocated + unsigned int* ioGPRSize, + char* outFPRs, // caller-allocated + unsigned int* ioFPRSize) +{ + size_t i; + unsigned int srcMarker = 0; + unsigned int destGMarker = 0; + unsigned int destFMarker = 0; + unsigned int savedFMarker = 0; + unsigned int fprsUsed = 0; + unsigned int savedFPRsUsed = 0; + + static unsigned int recurseCount = 0; + + if (ioStructMarker) + srcMarker = *ioStructMarker; + + if (ioFPRsUsed) + { + fprsUsed = *ioFPRsUsed; + savedFPRsUsed = fprsUsed; + } + + if (ioGPRSize) + destGMarker = *ioGPRSize; + + if (ioFPRSize) + { + destFMarker = *ioFPRSize; + savedFMarker = destFMarker; + } + + switch (inType->size) + { + case 1: case 2: case 4: + destGMarker += 8 - inType->size; + break; + + default: + break; + } + + for (i = 0; inType->elements[i] != NULL; i++) + { + switch (inType->elements[i]->type) + { + // Shadow floating-point types in GPRs for vararg and pre-ANSI + // functions. + case FFI_TYPE_FLOAT: + // Nudge markers to next 4/8-byte boundary + srcMarker = ALIGN(srcMarker, 4); + destGMarker = ALIGN(destGMarker, 4); + destFMarker = ALIGN(destFMarker, 8); + + if (fprsUsed < NUM_FPR_ARG_REGISTERS) + { + if (outFPRs != NULL && inStruct != NULL) + *(double*)&outFPRs[destFMarker] = + (double)*(float*)&inStruct[srcMarker]; + + destFMarker += 8; + fprsUsed++; + } + + if (outGPRs != NULL && inStruct != NULL) + *(double*)&outGPRs[destGMarker] = + (double)*(float*)&inStruct[srcMarker]; + + srcMarker += 4; + destGMarker += 4; + + // Skip to next GPR if next element won't fit and we're + // not already at a register boundary. + if (inType->elements[i + 1] != NULL && (srcMarker % 8)) + { + if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && + (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || + (ALIGN(destGMarker, 8) - destGMarker) < 2) && + (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || + (ALIGN(destGMarker, 8) - destGMarker) < 4)) + destGMarker = ALIGN(destGMarker, 8); + } + + break; + + case FFI_TYPE_DOUBLE: + srcMarker = ALIGN(srcMarker, 8); + destFMarker = ALIGN(destFMarker, 8); + + if (fprsUsed < NUM_FPR_ARG_REGISTERS) + { + if (outFPRs != NULL && inStruct != NULL) + *(double*)&outFPRs[destFMarker] = + *(double*)&inStruct[srcMarker]; + + destFMarker += 8; + fprsUsed++; + } + + if (outGPRs != NULL && inStruct != NULL) + *(double*)&outGPRs[destGMarker] = + *(double*)&inStruct[srcMarker]; + + srcMarker += 8; + + // Skip next GPR + destGMarker += 8; + destGMarker = ALIGN(destGMarker, 8); + + break; + + case FFI_TYPE_LONGDOUBLE: + srcMarker = ALIGN(srcMarker, 16); + + if (fprsUsed < NUM_FPR_ARG_REGISTERS) + { + destFMarker = ALIGN(destFMarker, 8); + destGMarker = ALIGN(destGMarker, 8); + + if (outFPRs != NULL && inStruct != NULL) + *(long double*)&outFPRs[destFMarker] = + *(long double*)&inStruct[srcMarker]; + + if (outGPRs != NULL && inStruct != NULL) + *(long double*)&outGPRs[destGMarker] = + *(long double*)&inStruct[srcMarker]; + + destFMarker += 16; + fprsUsed += 2; + } + else + { + destGMarker = ALIGN(destGMarker, 16); + + if (outGPRs != NULL && inStruct != NULL) + *(long double*)&outGPRs[destGMarker] = + *(long double*)&inStruct[srcMarker]; + } + + srcMarker += 16; + destGMarker += 16; // Skip next 2 GPRs + destGMarker = ALIGN(destGMarker, 8); // was 16 + + break; + + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + if (inType->alignment == 1) // bytes only + { + if (inType->size == 1) + { + if (outGPRs != NULL && inStruct != NULL) + outGPRs[destGMarker] = inStruct[srcMarker]; + + srcMarker++; + destGMarker++; + } + else if (inType->size == 2) + { + if (outGPRs != NULL && inStruct != NULL) + { + outGPRs[destGMarker] = inStruct[srcMarker]; + outGPRs[destGMarker + 1] = inStruct[srcMarker + 1]; + } + + srcMarker += 2; + destGMarker += 2; + + i++; + } + else + { + if (outGPRs != NULL && inStruct != NULL) + { + // Avoid memcpy for small chunks. + if (inType->size <= sizeof(long)) + *(long*)&outGPRs[destGMarker] = + *(long*)&inStruct[srcMarker]; + else + memcpy(&outGPRs[destGMarker], + &inStruct[srcMarker], inType->size); + } + + srcMarker += inType->size; + destGMarker += inType->size; + i += inType->size - 1; + } + } + else // bytes and other stuff + { + if (outGPRs != NULL && inStruct != NULL) + outGPRs[destGMarker] = inStruct[srcMarker]; + + srcMarker++; + destGMarker++; + + // Skip to next GPR if next element won't fit and we're + // not already at a register boundary. + if (inType->elements[i + 1] != NULL && (destGMarker % 8)) + { + if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && + (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || + (ALIGN(destGMarker, 8) - destGMarker) < 2) && + (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || + (ALIGN(destGMarker, 8) - destGMarker) < 4)) + destGMarker = ALIGN(destGMarker, inType->alignment); // was 8 + } + } + + break; + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + srcMarker = ALIGN(srcMarker, 2); + destGMarker = ALIGN(destGMarker, 2); + + if (outGPRs != NULL && inStruct != NULL) + *(short*)&outGPRs[destGMarker] = + *(short*)&inStruct[srcMarker]; + + srcMarker += 2; + destGMarker += 2; + + if (inType->elements[i + 1] == NULL) + destGMarker = ALIGN(destGMarker, inType->alignment); + + break; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + srcMarker = ALIGN(srcMarker, 4); + destGMarker = ALIGN(destGMarker, 4); + + if (outGPRs != NULL && inStruct != NULL) + *(int*)&outGPRs[destGMarker] = + *(int*)&inStruct[srcMarker]; + + srcMarker += 4; + destGMarker += 4; + + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + srcMarker = ALIGN(srcMarker, 8); + destGMarker = ALIGN(destGMarker, 8); + + if (outGPRs != NULL && inStruct != NULL) + *(long long*)&outGPRs[destGMarker] = + *(long long*)&inStruct[srcMarker]; + + srcMarker += 8; + destGMarker += 8; + + if (inType->elements[i + 1] == NULL) + destGMarker = ALIGN(destGMarker, inType->alignment); + + break; + + case FFI_TYPE_STRUCT: + recurseCount++; + ffi64_struct_to_reg_form(inType->elements[i], + inStruct, &srcMarker, &fprsUsed, outGPRs, + &destGMarker, outFPRs, &destFMarker); + recurseCount--; + break; + + default: + FFI_ASSERT(0); + break; + } + } + + destGMarker = ALIGN(destGMarker, inType->alignment); + + // Take care of the special case for 16-byte structs, but not for + // nested structs. + if (recurseCount == 0 && destGMarker == 16) + { + if (outGPRs != NULL && inStruct != NULL) + *(long double*)&outGPRs[0] = *(long double*)&inStruct[0]; + + destFMarker = savedFMarker; + fprsUsed = savedFPRsUsed; + } + + if (ioStructMarker) + *ioStructMarker = ALIGN(srcMarker, 8); + + if (ioFPRsUsed) + *ioFPRsUsed = fprsUsed; + + if (ioGPRSize) + *ioGPRSize = ALIGN(destGMarker, 8); + + if (ioFPRSize) + *ioFPRSize = ALIGN(destFMarker, 8); +} + +/* ffi64_stret_needs_ptr + + Determine whether a returned struct needs a pointer in r3 or can fit + in registers. +*/ + +bool +ffi64_stret_needs_ptr( + const ffi_type* inType, + unsigned short* ioGPRCount, + unsigned short* ioFPRCount) +{ + // Obvious case first- struct is larger than combined FPR size. + if (inType->size > 14 * 8) + return true; + + // Now the struct can physically fit in registers, determine if it + // also fits logically. + bool needsPtr = false; + unsigned short gprsUsed = 0; + unsigned short fprsUsed = 0; + size_t i; + + if (ioGPRCount) + gprsUsed = *ioGPRCount; + + if (ioFPRCount) + fprsUsed = *ioFPRCount; + + for (i = 0; inType->elements[i] != NULL && !needsPtr; i++) + { + switch (inType->elements[i]->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + gprsUsed++; + fprsUsed++; + + if (fprsUsed > 13) + needsPtr = true; + + break; + + case FFI_TYPE_LONGDOUBLE: + gprsUsed += 2; + fprsUsed += 2; + + if (fprsUsed > 14) + needsPtr = true; + + break; + + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + { + gprsUsed++; + + if (gprsUsed > 8) + { + needsPtr = true; + break; + } + + if (inType->elements[i + 1] == NULL) // last byte in the struct + break; + + // Count possible contiguous bytes ahead, up to 8. + unsigned short j; + + for (j = 1; j < 8; j++) + { + if (inType->elements[i + j] == NULL || + !FFI_TYPE_1_BYTE(inType->elements[i + j]->type)) + break; + } + + i += j - 1; // allow for i++ before the test condition + + break; + } + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + gprsUsed++; + + if (gprsUsed > 8) + needsPtr = true; + + break; + + case FFI_TYPE_STRUCT: + needsPtr = ffi64_stret_needs_ptr( + inType->elements[i], &gprsUsed, &fprsUsed); + + break; + + default: + FFI_ASSERT(0); + break; + } + } + + if (ioGPRCount) + *ioGPRCount = gprsUsed; + + if (ioFPRCount) + *ioFPRCount = fprsUsed; + + return needsPtr; +} + +/* ffi64_data_size + + Calculate the size in bytes of an ffi type. +*/ + +unsigned int +ffi64_data_size( + const ffi_type* inType) +{ + unsigned int size = 0; + + switch (inType->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + size = 1; + break; + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + size = 2; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_FLOAT: + size = 4; + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_DOUBLE: + size = 8; + break; + + case FFI_TYPE_LONGDOUBLE: + size = 16; + break; + + case FFI_TYPE_STRUCT: + ffi64_struct_to_reg_form( + inType, NULL, NULL, NULL, NULL, &size, NULL, NULL); + break; + + case FFI_TYPE_VOID: + break; + + default: + FFI_ASSERT(0); + break; + } + + return size; +} + +#endif /* defined(__ppc64__) */ +#endif /* __ppc__ || __ppc64__ */ diff --git a/python/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S b/python/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S new file mode 100755 index 0000000..7162fa1 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S @@ -0,0 +1,418 @@ +#if defined(__ppc64__) + +/* ----------------------------------------------------------------------- + ppc64-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation, + Inc. based on ppc_closure.S + + PowerPC Assembly glue. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM + +#include +#include // for FFI_TRAMPOLINE_SIZE +#include +#include + + .file "ppc64-darwin_closure.S" +.text + .align LOG2_GPR_BYTES + .globl _ffi_closure_ASM + +.text + .align LOG2_GPR_BYTES + +_ffi_closure_ASM: +LFB1: + mflr r0 + stg r0,SF_RETURN(r1) // save return address + + // Save GPRs 3 - 10 (aligned to 8) in the parents outgoing area. + stg r3,SF_ARG1(r1) + stg r4,SF_ARG2(r1) + stg r5,SF_ARG3(r1) + stg r6,SF_ARG4(r1) + stg r7,SF_ARG5(r1) + stg r8,SF_ARG6(r1) + stg r9,SF_ARG7(r1) + stg r10,SF_ARG8(r1) + +LCFI0: +/* 48 bytes (Linkage Area) + 64 bytes (outgoing parameter area, always reserved) + 112 bytes (14*8 for incoming FPR) + ? bytes (result) + 112 bytes (14*8 for outgoing FPR) + 16 bytes (2 saved registers) + 352 + ? total bytes +*/ + + std r31,-8(r1) // Save registers we use. + std r30,-16(r1) + mr r30,r1 // Save the old SP. + mr r31,r11 // Save the ffi_closure around ffi64_data_size. + + // Calculate the space we need. + stdu r1,-SF_MINSIZE(r1) + ld r3,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif* + ld r3,16(r3) // ffi_cif->rtype* + bl Lffi64_data_size$stub + ld r1,0(r1) + + addi r3,r3,352 // Add our overhead. + neg r3,r3 + li r0,-32 // Align to 32 bytes. + and r3,r3,r0 + stdux r1,r1,r3 // Grow the stack. + + mr r11,r31 // Copy the ffi_closure back. + +LCFI1: + // We want to build up an area for the parameters passed + // in registers. (both floating point and integer) + +/* 320 bytes (callee stack frame aligned to 32) + 48 bytes (caller linkage area) + 368 (start of caller parameter area aligned to 8) +*/ + + // Save FPRs 1 - 14. (aligned to 8) + stfd f1,112(r1) + stfd f2,120(r1) + stfd f3,128(r1) + stfd f4,136(r1) + stfd f5,144(r1) + stfd f6,152(r1) + stfd f7,160(r1) + stfd f8,168(r1) + stfd f9,176(r1) + stfd f10,184(r1) + stfd f11,192(r1) + stfd f12,200(r1) + stfd f13,208(r1) + stfd f14,216(r1) + + // Set up registers for the routine that actually does the work. + mr r3,r11 // context pointer from the trampoline + addi r4,r1,224 // result storage + addi r5,r30,SF_ARG1 // saved GPRs + addi r6,r1,112 // saved FPRs + bl Lffi_closure_helper_DARWIN$stub + + // Look the proper starting point in table + // by using return type as an offset. + addi r5,r1,224 // Get pointer to results area. + bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR. + mflr r4 // Move to r4. + slwi r3,r3,4 // Now multiply return type by 16. + add r3,r3,r4 // Add contents of table to table address. + mtctr r3 + bctr + +LFE1: + // Each of the ret_typeX code fragments has to be exactly 16 bytes long + // (4 instructions). For cache effectiveness we align to a 16 byte + // boundary first. + .align 4 + nop + nop + nop + +Lget_ret_type0_addr: + blrl + +// case FFI_TYPE_VOID +Lret_type0: + b Lfinish + nop + nop + nop + +// case FFI_TYPE_INT +Lret_type1: + lwz r3,4(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_FLOAT +Lret_type2: + lfs f1,0(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_DOUBLE +Lret_type3: + lfd f1,0(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_LONGDOUBLE +Lret_type4: + lfd f1,0(r5) + lfd f2,8(r5) + b Lfinish + nop + +// case FFI_TYPE_UINT8 +Lret_type5: + lbz r3,7(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_SINT8 +Lret_type6: + lbz r3,7(r5) + extsb r3,r3 + b Lfinish + nop + +// case FFI_TYPE_UINT16 +Lret_type7: + lhz r3,6(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_SINT16 +Lret_type8: + lha r3,6(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_UINT32 +Lret_type9: // same as Lret_type1 + lwz r3,4(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_SINT32 +Lret_type10: // same as Lret_type1 + lwz r3,4(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_UINT64 +Lret_type11: + ld r3,0(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_SINT64 +Lret_type12: // same as Lret_type11 + ld r3,0(r5) + b Lfinish + nop + nop + +// case FFI_TYPE_STRUCT +Lret_type13: + b Lret_struct + nop + nop + nop + +// ** End 16-byte aligned cases ** +// case FFI_TYPE_POINTER +// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types +// are added in future, the following code will need to be updated and +// padded to 16 bytes. +Lret_type14: + lg r3,0(r5) + b Lfinish + +// copy struct into registers +Lret_struct: + ld r31,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif* + ld r3,16(r31) // ffi_cif->rtype* + ld r31,24(r31) // ffi_cif->flags + mr r4,r5 // copy struct* to 2nd arg + addi r7,r1,SF_ARG9 // GPR return area + addi r9,r30,-16-(14*8) // FPR return area + li r5,0 // struct offset ptr (NULL) + li r6,0 // FPR used count ptr (NULL) + li r8,0 // GPR return area size ptr (NULL) + li r10,0 // FPR return area size ptr (NULL) + bl Lffi64_struct_to_reg_form$stub + + // Load GPRs + ld r3,SF_ARG9(r1) + ld r4,SF_ARG10(r1) + ld r5,SF_ARG11(r1) + ld r6,SF_ARG12(r1) + nop + ld r7,SF_ARG13(r1) + ld r8,SF_ARG14(r1) + ld r9,SF_ARG15(r1) + ld r10,SF_ARG16(r1) + nop + + // Load FPRs + mtcrf 0x2,r31 + bf 26,Lfinish + lfd f1,-16-(14*8)(r30) + lfd f2,-16-(13*8)(r30) + lfd f3,-16-(12*8)(r30) + lfd f4,-16-(11*8)(r30) + nop + lfd f5,-16-(10*8)(r30) + lfd f6,-16-(9*8)(r30) + lfd f7,-16-(8*8)(r30) + lfd f8,-16-(7*8)(r30) + nop + lfd f9,-16-(6*8)(r30) + lfd f10,-16-(5*8)(r30) + lfd f11,-16-(4*8)(r30) + lfd f12,-16-(3*8)(r30) + nop + lfd f13,-16-(2*8)(r30) + lfd f14,-16-(1*8)(r30) + // Fall through + +// case done +Lfinish: + lg r1,0(r1) // Restore stack pointer. + ld r31,-8(r1) // Restore registers we used. + ld r30,-16(r1) + lg r0,SF_RETURN(r1) // Get return address. + mtlr r0 // Reset link register. + blr + +// END(ffi_closure_ASM) + +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 ; Length of Common Information Entry +LSCIE1: + .long 0x0 ; CIE Identifier Tag + .byte 0x1 ; CIE Version + .ascii "zR\0" ; CIE Augmentation + .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor + .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor + .byte 0x41 ; CIE RA Column + .byte 0x1 ; uleb128 0x1; Augmentation size + .byte 0x10 ; FDE Encoding (pcrel) + .byte 0xc ; DW_CFA_def_cfa + .byte 0x1 ; uleb128 0x1 + .byte 0x0 ; uleb128 0x0 + .align LOG2_GPR_BYTES +LECIE1: +.globl _ffi_closure_ASM.eh +_ffi_closure_ASM.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 ; FDE Length + +LASFDE1: + .long LASFDE1-EH_frame1 ; FDE CIE offset + .g_long LFB1-. ; FDE initial location + .set L$set$3,LFE1-LFB1 + .g_long L$set$3 ; FDE address range + .byte 0x0 ; uleb128 0x0; Augmentation size + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$3,LCFI1-LCFI0 + .long L$set$3 + .byte 0xe ; DW_CFA_def_cfa_offset + .byte 176,1 ; uleb128 176 + .byte 0x4 ; DW_CFA_advance_loc4 + .set L$set$4,LCFI0-LFB1 + .long L$set$4 + .byte 0x11 ; DW_CFA_offset_extended_sf + .byte 0x41 ; uleb128 0x41 + .byte 0x7e ; sleb128 -2 + .align LOG2_GPR_BYTES + +LEFDE1: +.data + .align LOG2_GPR_BYTES +LDFCM0: +.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align LOG2_GPR_BYTES + +Lffi_closure_helper_DARWIN$stub: + .indirect_symbol _ffi_closure_helper_DARWIN + mflr r0 + bcl 20,31,LO$ffi_closure_helper_DARWIN + +LO$ffi_closure_helper_DARWIN: + mflr r11 + addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) + mtlr r0 + lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) + mtctr r12 + bctr + +.lazy_symbol_pointer +L_ffi_closure_helper_DARWIN$lazy_ptr: + .indirect_symbol _ffi_closure_helper_DARWIN + .g_long dyld_stub_binding_helper + +.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align LOG2_GPR_BYTES + +Lffi64_struct_to_reg_form$stub: + .indirect_symbol _ffi64_struct_to_reg_form + mflr r0 + bcl 20,31,LO$ffi64_struct_to_reg_form + +LO$ffi64_struct_to_reg_form: + mflr r11 + addis r11,r11,ha16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form) + mtlr r0 + lgu r12,lo16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form)(r11) + mtctr r12 + bctr + +.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 + .align LOG2_GPR_BYTES + +Lffi64_data_size$stub: + .indirect_symbol _ffi64_data_size + mflr r0 + bcl 20,31,LO$ffi64_data_size + +LO$ffi64_data_size: + mflr r11 + addis r11,r11,ha16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size) + mtlr r0 + lgu r12,lo16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size)(r11) + mtctr r12 + bctr + +.lazy_symbol_pointer +L_ffi64_struct_to_reg_form$lazy_ptr: + .indirect_symbol _ffi64_struct_to_reg_form + .g_long dyld_stub_binding_helper + +L_ffi64_data_size$lazy_ptr: + .indirect_symbol _ffi64_data_size + .g_long dyld_stub_binding_helper + +#endif // __ppc64__ diff --git a/python/Modules/_ctypes/libffi_osx/types.c b/python/Modules/_ctypes/libffi_osx/types.c new file mode 100755 index 0000000..44806ae --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/types.c @@ -0,0 +1,115 @@ +/* ----------------------------------------------------------------------- + types.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + Predefined ffi_types needed by libffi. + + 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 CYGNUS SOLUTIONS 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. + ----------------------------------------------------------------------- */ + +#include +#include + +/* Type definitions */ +#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) \ + ffi_type ffi_type_##n = { s, a, t, NULL } +#define FFI_AGGREGATE_TYPEDEF(n, e) \ + ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } + +FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); +FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); +FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); +FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); +FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); +FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); +FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); + +/* Size and alignment are fake here. They must not be 0. */ +FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); + +#if defined ALPHA || defined SPARC64 || defined X86_64 || \ + defined S390X || defined IA64 || defined POWERPC64 +FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); +#else +FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); +#endif + +#if defined X86 || defined ARM || defined M68K || defined(X86_DARWIN) + +# ifdef X86_64 + FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); + FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); +# else + FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); + FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); +# endif + +#elif defined(POWERPC_DARWIN) +FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); +#elif defined SH +FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); +#else +FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); +#endif + +#if defined X86 || defined X86_WIN32 || defined M68K || defined(X86_DARWIN) + +# if defined X86_WIN32 || defined X86_64 + FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +# else + FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); +# endif + +# ifdef X86_DARWIN + FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); +# else + FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); +# endif + +#elif defined ARM || defined SH || defined POWERPC_AIX +FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); +#elif defined POWERPC_DARWIN +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); + +# if __GNUC__ >= 4 + FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); +# else + FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); +# endif + +#elif defined SPARC +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); + +# ifdef SPARC64 + FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); +# else + FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); +# endif + +#elif defined X86_64 || defined POWERPC64 +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); +#else +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); +#endif \ No newline at end of file diff --git a/python/Modules/_ctypes/libffi_osx/x86/darwin64.S b/python/Modules/_ctypes/libffi_osx/x86/darwin64.S new file mode 100755 index 0000000..1286d33 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/x86/darwin64.S @@ -0,0 +1,417 @@ +/* ----------------------------------------------------------------------- + darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc. + derived from unix64.S + + x86-64 Foreign Function Interface for Darwin. + + 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 AUTHOR 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. + ----------------------------------------------------------------------- */ + +#ifdef __x86_64__ +#define LIBFFI_ASM +#include +#include + + .file "darwin64.S" +.text + +/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, + void *raddr, void (*fnaddr)()); + + Bit o trickiness here -- ARGS+BYTES is the base of the stack frame + for this function. This has been allocated by ffi_call. We also + deallocate some of the stack that has been alloca'd. */ + + .align 3 + .globl _ffi_call_unix64 + +_ffi_call_unix64: +LUW0: + movq (%rsp), %r10 /* Load return address. */ + movq %rdi, %r12 /* Save a copy of the register area. */ + leaq (%rdi, %rsi), %rax /* Find local stack base. */ + movq %rdx, (%rax) /* Save flags. */ + movq %rcx, 8(%rax) /* Save raddr. */ + movq %rbp, 16(%rax) /* Save old frame pointer. */ + movq %r10, 24(%rax) /* Relocate return address. */ + movq %rax, %rbp /* Finalize local stack frame. */ +LUW1: + /* movq %rdi, %r10 // Save a copy of the register area. */ + movq %r12, %r10 + movq %r8, %r11 /* Save a copy of the target fn. */ + movl %r9d, %eax /* Set number of SSE registers. */ + + /* Load up all argument registers. */ + movq (%r10), %rdi + movq 8(%r10), %rsi + movq 16(%r10), %rdx + movq 24(%r10), %rcx + movq 32(%r10), %r8 + movq 40(%r10), %r9 + testl %eax, %eax + jnz Lload_sse +Lret_from_load_sse: + + /* Deallocate the reg arg area. */ + leaq 176(%r10), %rsp + + /* Call the user function. */ + call *%r11 + + /* Deallocate stack arg area; local stack frame in redzone. */ + leaq 24(%rbp), %rsp + + movq 0(%rbp), %rcx /* Reload flags. */ + movq 8(%rbp), %rdi /* Reload raddr. */ + movq 16(%rbp), %rbp /* Reload old frame pointer. */ +LUW2: + + /* The first byte of the flags contains the FFI_TYPE. */ + movzbl %cl, %r10d + leaq Lstore_table(%rip), %r11 + movslq (%r11, %r10, 4), %r10 + addq %r11, %r10 + jmp *%r10 + +Lstore_table: + .long Lst_void-Lstore_table /* FFI_TYPE_VOID */ + .long Lst_sint32-Lstore_table /* FFI_TYPE_INT */ + .long Lst_float-Lstore_table /* FFI_TYPE_FLOAT */ + .long Lst_double-Lstore_table /* FFI_TYPE_DOUBLE */ + .long Lst_ldouble-Lstore_table /* FFI_TYPE_LONGDOUBLE */ + .long Lst_uint8-Lstore_table /* FFI_TYPE_UINT8 */ + .long Lst_sint8-Lstore_table /* FFI_TYPE_SINT8 */ + .long Lst_uint16-Lstore_table /* FFI_TYPE_UINT16 */ + .long Lst_sint16-Lstore_table /* FFI_TYPE_SINT16 */ + .long Lst_uint32-Lstore_table /* FFI_TYPE_UINT32 */ + .long Lst_sint32-Lstore_table /* FFI_TYPE_SINT32 */ + .long Lst_int64-Lstore_table /* FFI_TYPE_UINT64 */ + .long Lst_int64-Lstore_table /* FFI_TYPE_SINT64 */ + .long Lst_struct-Lstore_table /* FFI_TYPE_STRUCT */ + .long Lst_int64-Lstore_table /* FFI_TYPE_POINTER */ + + .text + .align 3 +Lst_void: + ret + .align 3 +Lst_uint8: + movzbq %al, %rax + movq %rax, (%rdi) + ret + .align 3 +Lst_sint8: + movsbq %al, %rax + movq %rax, (%rdi) + ret + .align 3 +Lst_uint16: + movzwq %ax, %rax + movq %rax, (%rdi) + .align 3 +Lst_sint16: + movswq %ax, %rax + movq %rax, (%rdi) + ret + .align 3 +Lst_uint32: + movl %eax, %eax + movq %rax, (%rdi) + .align 3 +Lst_sint32: + cltq + movq %rax, (%rdi) + ret + .align 3 +Lst_int64: + movq %rax, (%rdi) + ret + .align 3 +Lst_float: + movss %xmm0, (%rdi) + ret + .align 3 +Lst_double: + movsd %xmm0, (%rdi) + ret +Lst_ldouble: + fstpt (%rdi) + ret + .align 3 +Lst_struct: + leaq -20(%rsp), %rsi /* Scratch area in redzone. */ + + /* We have to locate the values now, and since we don't want to + write too much data into the user's return value, we spill the + value to a 16 byte scratch area first. Bits 8, 9, and 10 + control where the values are located. Only one of the three + bits will be set; see ffi_prep_cif_machdep for the pattern. */ + movd %xmm0, %r10 + movd %xmm1, %r11 + testl $0x100, %ecx + cmovnz %rax, %rdx + cmovnz %r10, %rax + testl $0x200, %ecx + cmovnz %r10, %rdx + testl $0x400, %ecx + cmovnz %r10, %rax + cmovnz %r11, %rdx + movq %rax, (%rsi) + movq %rdx, 8(%rsi) + + /* Bits 12-31 contain the true size of the structure. Copy from + the scratch area to the true destination. */ + shrl $12, %ecx + rep movsb + ret + + /* Many times we can avoid loading any SSE registers at all. + It's not worth an indirect jump to load the exact set of + SSE registers needed; zero or all is a good compromise. */ + .align 3 +LUW3: +Lload_sse: + movdqa 48(%r10), %xmm0 + movdqa 64(%r10), %xmm1 + movdqa 80(%r10), %xmm2 + movdqa 96(%r10), %xmm3 + movdqa 112(%r10), %xmm4 + movdqa 128(%r10), %xmm5 + movdqa 144(%r10), %xmm6 + movdqa 160(%r10), %xmm7 + jmp Lret_from_load_sse + +LUW4: + .align 3 + .globl _ffi_closure_unix64 + +_ffi_closure_unix64: +LUW5: + /* The carry flag is set by the trampoline iff SSE registers + are used. Don't clobber it before the branch instruction. */ + leaq -200(%rsp), %rsp +LUW6: + movq %rdi, (%rsp) + movq %rsi, 8(%rsp) + movq %rdx, 16(%rsp) + movq %rcx, 24(%rsp) + movq %r8, 32(%rsp) + movq %r9, 40(%rsp) + jc Lsave_sse +Lret_from_save_sse: + + movq %r10, %rdi + leaq 176(%rsp), %rsi + movq %rsp, %rdx + leaq 208(%rsp), %rcx + call _ffi_closure_unix64_inner + + /* Deallocate stack frame early; return value is now in redzone. */ + addq $200, %rsp +LUW7: + + /* The first byte of the return value contains the FFI_TYPE. */ + movzbl %al, %r10d + leaq Lload_table(%rip), %r11 + movslq (%r11, %r10, 4), %r10 + addq %r11, %r10 + jmp *%r10 + +Lload_table: + .long Lld_void-Lload_table /* FFI_TYPE_VOID */ + .long Lld_int32-Lload_table /* FFI_TYPE_INT */ + .long Lld_float-Lload_table /* FFI_TYPE_FLOAT */ + .long Lld_double-Lload_table /* FFI_TYPE_DOUBLE */ + .long Lld_ldouble-Lload_table /* FFI_TYPE_LONGDOUBLE */ + .long Lld_int8-Lload_table /* FFI_TYPE_UINT8 */ + .long Lld_int8-Lload_table /* FFI_TYPE_SINT8 */ + .long Lld_int16-Lload_table /* FFI_TYPE_UINT16 */ + .long Lld_int16-Lload_table /* FFI_TYPE_SINT16 */ + .long Lld_int32-Lload_table /* FFI_TYPE_UINT32 */ + .long Lld_int32-Lload_table /* FFI_TYPE_SINT32 */ + .long Lld_int64-Lload_table /* FFI_TYPE_UINT64 */ + .long Lld_int64-Lload_table /* FFI_TYPE_SINT64 */ + .long Lld_struct-Lload_table /* FFI_TYPE_STRUCT */ + .long Lld_int64-Lload_table /* FFI_TYPE_POINTER */ + + .text + .align 3 +Lld_void: + ret + .align 3 +Lld_int8: + movzbl -24(%rsp), %eax + ret + .align 3 +Lld_int16: + movzwl -24(%rsp), %eax + ret + .align 3 +Lld_int32: + movl -24(%rsp), %eax + ret + .align 3 +Lld_int64: + movq -24(%rsp), %rax + ret + .align 3 +Lld_float: + movss -24(%rsp), %xmm0 + ret + .align 3 +Lld_double: + movsd -24(%rsp), %xmm0 + ret + .align 3 +Lld_ldouble: + fldt -24(%rsp) + ret + .align 3 +Lld_struct: + /* There are four possibilities here, %rax/%rdx, %xmm0/%rax, + %rax/%xmm0, %xmm0/%xmm1. We collapse two by always loading + both rdx and xmm1 with the second word. For the remaining, + bit 8 set means xmm0 gets the second word, and bit 9 means + that rax gets the second word. */ + movq -24(%rsp), %rcx + movq -16(%rsp), %rdx + movq -16(%rsp), %xmm1 + testl $0x100, %eax + cmovnz %rdx, %rcx + movd %rcx, %xmm0 + testl $0x200, %eax + movq -24(%rsp), %rax + cmovnz %rdx, %rax + ret + + /* See the comment above Lload_sse; the same logic applies here. */ + .align 3 +LUW8: +Lsave_sse: + movdqa %xmm0, 48(%rsp) + movdqa %xmm1, 64(%rsp) + movdqa %xmm2, 80(%rsp) + movdqa %xmm3, 96(%rsp) + movdqa %xmm4, 112(%rsp) + movdqa %xmm5, 128(%rsp) + movdqa %xmm6, 144(%rsp) + movdqa %xmm7, 160(%rsp) + jmp Lret_from_save_sse + +LUW9: +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 /* CIE Length */ + .long L$set$0 +LSCIE1: + .long 0x0 /* CIE Identifier Tag */ + .byte 0x1 /* CIE Version */ + .ascii "zR\0" /* CIE Augmentation */ + .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */ + .byte 0x78 /* sleb128 -8; CIE Data Alignment Factor */ + .byte 0x10 /* CIE RA Column */ + .byte 0x1 /* uleb128 0x1; Augmentation size */ + .byte 0x10 /* FDE Encoding (pcrel sdata4) */ + .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */ + .byte 0x7 /* uleb128 0x7 */ + .byte 0x8 /* uleb128 0x8 */ + .byte 0x90 /* DW_CFA_offset, column 0x10 */ + .byte 0x1 + .align 3 +LECIE1: + .globl _ffi_call_unix64.eh +_ffi_call_unix64.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 /* FDE Length */ + .long L$set$1 +LASFDE1: + .long LASFDE1-EH_frame1 /* FDE CIE offset */ + .quad LUW0-. /* FDE initial location */ + .set L$set$2,LUW4-LUW0 /* FDE address range */ + .quad L$set$2 + .byte 0x0 /* Augmentation size */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .set L$set$3,LUW1-LUW0 + .long L$set$3 + + /* New stack frame based off rbp. This is an itty bit of unwind + trickery in that the CFA *has* changed. There is no easy way + to describe it correctly on entry to the function. Fortunately, + it doesn't matter too much since at all points we can correctly + unwind back to ffi_call. Note that the location to which we + moved the return address is (the new) CFA-8, so from the + perspective of the unwind info, it hasn't moved. */ + .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */ + .byte 0x6 + .byte 0x20 + .byte 0x80+6 /* DW_CFA_offset, %rbp offset 2*-8 */ + .byte 0x2 + .byte 0xa /* DW_CFA_remember_state */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .set L$set$4,LUW2-LUW1 + .long L$set$4 + .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */ + .byte 0x7 + .byte 0x8 + .byte 0xc0+6 /* DW_CFA_restore, %rbp */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .set L$set$5,LUW3-LUW2 + .long L$set$5 + .byte 0xb /* DW_CFA_restore_state */ + + .align 3 +LEFDE1: + .globl _ffi_closure_unix64.eh +_ffi_closure_unix64.eh: +LSFDE3: + .set L$set$6,LEFDE3-LASFDE3 /* FDE Length */ + .long L$set$6 +LASFDE3: + .long LASFDE3-EH_frame1 /* FDE CIE offset */ + .quad LUW5-. /* FDE initial location */ + .set L$set$7,LUW9-LUW5 /* FDE address range */ + .quad L$set$7 + .byte 0x0 /* Augmentation size */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .set L$set$8,LUW6-LUW5 + .long L$set$8 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 208,1 /* uleb128 208 */ + .byte 0xa /* DW_CFA_remember_state */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .set L$set$9,LUW7-LUW6 + .long L$set$9 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x8 + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .set L$set$10,LUW8-LUW7 + .long L$set$10 + .byte 0xb /* DW_CFA_restore_state */ + + .align 3 +LEFDE3: + .subsections_via_symbols + +#endif /* __x86_64__ */ diff --git a/python/Modules/_ctypes/libffi_osx/x86/x86-darwin.S b/python/Modules/_ctypes/libffi_osx/x86/x86-darwin.S new file mode 100755 index 0000000..925a841 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/x86/x86-darwin.S @@ -0,0 +1,422 @@ +#ifdef __i386__ +/* ----------------------------------------------------------------------- + darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc. + + X86 Foreign Function Interface + + 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 CYGNUS SOLUTIONS 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. + ----------------------------------------------------------------------- */ + +/* + * This file is based on sysv.S and then hacked up by Ronald who hasn't done + * assembly programming in 8 years. + */ + +#ifndef __x86_64__ + +#define LIBFFI_ASM +#include +#include + +#ifdef PyObjC_STRICT_DEBUGGING + /* XXX: Debugging of stack alignment, to be removed */ +#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0 +#else +#define ASSERT_STACK_ALIGNED +#endif + +.text + +.globl _ffi_prep_args + + .align 4 +.globl _ffi_call_SYSV + +_ffi_call_SYSV: +LFB1: + pushl %ebp +LCFI0: + movl %esp,%ebp +LCFI1: + subl $8,%esp + /* Make room for all of the new args. */ + movl 16(%ebp),%ecx + subl %ecx,%esp + + movl %esp,%eax + + /* Place all of the ffi_prep_args in position */ + subl $8,%esp + pushl 12(%ebp) + pushl %eax + call *8(%ebp) + + /* Return stack to previous state and call the function */ + addl $16,%esp + + call *28(%ebp) + + /* Remove the space we pushed for the args */ + movl 16(%ebp),%ecx + addl %ecx,%esp + + /* Load %ecx with the return type code */ + movl 20(%ebp),%ecx + + /* If the return value pointer is NULL, assume no return value. */ + cmpl $0,24(%ebp) + jne Lretint + + /* Even if there is no space for the return value, we are + obliged to handle floating-point values. */ + cmpl $FFI_TYPE_FLOAT,%ecx + jne Lnoretval + fstp %st(0) + + jmp Lepilogue + +Lretint: + cmpl $FFI_TYPE_INT,%ecx + jne Lretfloat + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + jmp Lepilogue + +Lretfloat: + cmpl $FFI_TYPE_FLOAT,%ecx + jne Lretdouble + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + fstps (%ecx) + jmp Lepilogue + +Lretdouble: + cmpl $FFI_TYPE_DOUBLE,%ecx + jne Lretlongdouble + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + fstpl (%ecx) + jmp Lepilogue + +Lretlongdouble: + cmpl $FFI_TYPE_LONGDOUBLE,%ecx + jne Lretint64 + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + fstpt (%ecx) + jmp Lepilogue + +Lretint64: + cmpl $FFI_TYPE_SINT64,%ecx + jne Lretstruct1b + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + movl %edx,4(%ecx) + jmp Lepilogue + +Lretstruct1b: + cmpl $FFI_TYPE_SINT8,%ecx + jne Lretstruct2b + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + movb %al,0(%ecx) + jmp Lepilogue + +Lretstruct2b: + cmpl $FFI_TYPE_SINT16,%ecx + jne Lretstruct + /* Load %ecx with the pointer to storage for the return value */ + movl 24(%ebp),%ecx + movw %ax,0(%ecx) + jmp Lepilogue + +Lretstruct: + cmpl $FFI_TYPE_STRUCT,%ecx + jne Lnoretval + /* Nothing to do! */ + addl $4,%esp + popl %ebp + ret + +Lnoretval: +Lepilogue: + addl $8,%esp + movl %ebp,%esp + popl %ebp + ret +LFE1: +.ffi_call_SYSV_end: + + .align 4 +FFI_HIDDEN (ffi_closure_SYSV) +.globl _ffi_closure_SYSV + +_ffi_closure_SYSV: +LFB2: + pushl %ebp +LCFI2: + movl %esp, %ebp +LCFI3: + subl $56, %esp + leal -40(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 8(%ebp), %edx + movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ + leal -12(%ebp), %edx + movl %edx, (%esp) /* &resp */ + movl %ebx, 8(%esp) +LCFI7: + call L_ffi_closure_SYSV_inner$stub + movl 8(%esp), %ebx + movl -12(%ebp), %ecx + cmpl $FFI_TYPE_INT, %eax + je Lcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je Lcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je Lcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je Lcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je Lcls_retllong + cmpl $FFI_TYPE_UINT8, %eax + je Lcls_retstruct1 + cmpl $FFI_TYPE_SINT8, %eax + je Lcls_retstruct1 + cmpl $FFI_TYPE_UINT16, %eax + je Lcls_retstruct2 + cmpl $FFI_TYPE_SINT16, %eax + je Lcls_retstruct2 + cmpl $FFI_TYPE_STRUCT, %eax + je Lcls_retstruct +Lcls_epilogue: + movl %ebp, %esp + popl %ebp + ret +Lcls_retint: + movl (%ecx), %eax + jmp Lcls_epilogue +Lcls_retfloat: + flds (%ecx) + jmp Lcls_epilogue +Lcls_retdouble: + fldl (%ecx) + jmp Lcls_epilogue +Lcls_retldouble: + fldt (%ecx) + jmp Lcls_epilogue +Lcls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp Lcls_epilogue +Lcls_retstruct1: + movsbl (%ecx), %eax + jmp Lcls_epilogue +Lcls_retstruct2: + movswl (%ecx), %eax + jmp Lcls_epilogue +Lcls_retstruct: + lea -8(%ebp),%esp + movl %ebp, %esp + popl %ebp + ret $4 +LFE2: + +#if !FFI_NO_RAW_API + +#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) +#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) +#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) +#define CIF_FLAGS_OFFSET 20 + + .align 4 +FFI_HIDDEN (ffi_closure_raw_SYSV) +.globl _ffi_closure_raw_SYSV + +_ffi_closure_raw_SYSV: +LFB3: + pushl %ebp +LCFI4: + movl %esp, %ebp +LCFI5: + pushl %esi +LCFI6: + subl $36, %esp + movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ + movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ + movl %edx, 12(%esp) /* user_data */ + leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ + movl %edx, 8(%esp) /* raw_args */ + leal -24(%ebp), %edx + movl %edx, 4(%esp) /* &res */ + movl %esi, (%esp) /* cif */ + call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ + movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ + cmpl $FFI_TYPE_INT, %eax + je Lrcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je Lrcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je Lrcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je Lrcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je Lrcls_retllong +Lrcls_epilogue: + addl $36, %esp + popl %esi + popl %ebp + ret +Lrcls_retint: + movl -24(%ebp), %eax + jmp Lrcls_epilogue +Lrcls_retfloat: + flds -24(%ebp) + jmp Lrcls_epilogue +Lrcls_retdouble: + fldl -24(%ebp) + jmp Lrcls_epilogue +Lrcls_retldouble: + fldt -24(%ebp) + jmp Lrcls_epilogue +Lrcls_retllong: + movl -24(%ebp), %eax + movl -20(%ebp), %edx + jmp Lrcls_epilogue +LFE3: +#endif + +.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 +L_ffi_closure_SYSV_inner$stub: + .indirect_symbol _ffi_closure_SYSV_inner + hlt ; hlt ; hlt ; hlt ; hlt + + +.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 +LSCIE1: + .long 0x0 + .byte 0x1 + .ascii "zR\0" + .byte 0x1 + .byte 0x7c + .byte 0x8 + .byte 0x1 + .byte 0x10 + .byte 0xc + .byte 0x5 + .byte 0x4 + .byte 0x88 + .byte 0x1 + .align 2 +LECIE1: +.globl _ffi_call_SYSV.eh +_ffi_call_SYSV.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 +LASFDE1: + .long LASFDE1-EH_frame1 + .long LFB1-. + .set L$set$2,LFE1-LFB1 + .long L$set$2 + .byte 0x0 + .byte 0x4 + .set L$set$3,LCFI0-LFB1 + .long L$set$3 + .byte 0xe + .byte 0x8 + .byte 0x84 + .byte 0x2 + .byte 0x4 + .set L$set$4,LCFI1-LCFI0 + .long L$set$4 + .byte 0xd + .byte 0x4 + .align 2 +LEFDE1: +.globl _ffi_closure_SYSV.eh +_ffi_closure_SYSV.eh: +LSFDE2: + .set L$set$5,LEFDE2-LASFDE2 + .long L$set$5 +LASFDE2: + .long LASFDE2-EH_frame1 + .long LFB2-. + .set L$set$6,LFE2-LFB2 + .long L$set$6 + .byte 0x0 + .byte 0x4 + .set L$set$7,LCFI2-LFB2 + .long L$set$7 + .byte 0xe + .byte 0x8 + .byte 0x84 + .byte 0x2 + .byte 0x4 + .set L$set$8,LCFI3-LCFI2 + .long L$set$8 + .byte 0xd + .byte 0x4 + .align 2 +LEFDE2: + +#if !FFI_NO_RAW_API + +.globl _ffi_closure_raw_SYSV.eh +_ffi_closure_raw_SYSV.eh: +LSFDE3: + .set L$set$10,LEFDE3-LASFDE3 + .long L$set$10 +LASFDE3: + .long LASFDE3-EH_frame1 + .long LFB3-. + .set L$set$11,LFE3-LFB3 + .long L$set$11 + .byte 0x0 + .byte 0x4 + .set L$set$12,LCFI4-LFB3 + .long L$set$12 + .byte 0xe + .byte 0x8 + .byte 0x84 + .byte 0x2 + .byte 0x4 + .set L$set$13,LCFI5-LCFI4 + .long L$set$13 + .byte 0xd + .byte 0x4 + .byte 0x4 + .set L$set$14,LCFI6-LCFI5 + .long L$set$14 + .byte 0x85 + .byte 0x3 + .align 2 +LEFDE3: + +#endif + +#endif /* ifndef __x86_64__ */ + +#endif /* defined __i386__ */ diff --git a/python/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c b/python/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c new file mode 100755 index 0000000..f2610c1 --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c @@ -0,0 +1,737 @@ +#ifdef __x86_64__ + +/* ----------------------------------------------------------------------- + x86-ffi64.c - Copyright (c) 2002 Bo Thorsen + + x86-64 Foreign Function Interface + + 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 CYGNUS SOLUTIONS 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. + ----------------------------------------------------------------------- */ + +#include +#include + +#include +#include + +#define MAX_GPR_REGS 6 +#define MAX_SSE_REGS 8 + +typedef struct RegisterArgs { + /* Registers for argument passing. */ + UINT64 gpr[MAX_GPR_REGS]; + __int128_t sse[MAX_SSE_REGS]; +} RegisterArgs; + +extern void +ffi_call_unix64( + void* args, + unsigned long bytes, + unsigned flags, + void* raddr, + void (*fnaddr)(void), + unsigned ssecount); + +/* All reference to register classes here is identical to the code in + gcc/config/i386/i386.c. Do *not* change one without the other. */ + +/* Register class used for passing given 64bit part of the argument. + These represent classes as documented by the PS ABI, with the exception + of SSESF, SSEDF classes, that are basically SSE class, just gcc will + use SF or DFmode move instead of DImode to avoid reformating penalties. + + Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves + whenever possible (upper half does contain padding). */ +enum x86_64_reg_class +{ + X86_64_NO_CLASS, + X86_64_INTEGER_CLASS, + X86_64_INTEGERSI_CLASS, + X86_64_SSE_CLASS, + X86_64_SSESF_CLASS, + X86_64_SSEDF_CLASS, + X86_64_SSEUP_CLASS, + X86_64_X87_CLASS, + X86_64_X87UP_CLASS, + X86_64_COMPLEX_X87_CLASS, + X86_64_MEMORY_CLASS +}; + +#define MAX_CLASSES 4 +#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS) + +/* x86-64 register passing implementation. See x86-64 ABI for details. Goal + of this code is to classify each 8bytes of incoming argument by the register + class and assign registers accordingly. */ + +/* Return the union class of CLASS1 and CLASS2. + See the x86-64 PS ABI for details. */ +static enum x86_64_reg_class +merge_classes( + enum x86_64_reg_class class1, + enum x86_64_reg_class class2) +{ + /* Rule #1: If both classes are equal, this is the resulting class. */ + if (class1 == class2) + return class1; + + /* Rule #2: If one of the classes is NO_CLASS, the resulting class is + the other class. */ + if (class1 == X86_64_NO_CLASS) + return class2; + + if (class2 == X86_64_NO_CLASS) + return class1; + + /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */ + if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS) + return X86_64_MEMORY_CLASS; + + /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */ + if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS) + || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS)) + return X86_64_INTEGERSI_CLASS; + + if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS + || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS) + return X86_64_INTEGER_CLASS; + + /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class, + MEMORY is used. */ + if (class1 == X86_64_X87_CLASS + || class1 == X86_64_X87UP_CLASS + || class1 == X86_64_COMPLEX_X87_CLASS + || class2 == X86_64_X87_CLASS + || class2 == X86_64_X87UP_CLASS + || class2 == X86_64_COMPLEX_X87_CLASS) + return X86_64_MEMORY_CLASS; + + /* Rule #6: Otherwise class SSE is used. */ + return X86_64_SSE_CLASS; +} + +/* Classify the argument of type TYPE and mode MODE. + CLASSES will be filled by the register class used to pass each word + of the operand. The number of words is returned. In case the parameter + should be passed in memory, 0 is returned. As a special case for zero + sized containers, classes[0] will be NO_CLASS and 1 is returned. + + See the x86-64 PS ABI for details. */ + +static int +classify_argument( + ffi_type* type, + enum x86_64_reg_class classes[], + size_t byte_offset) +{ + switch (type->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: +#if 0 + if (byte_offset + type->size <= 4) + classes[0] = X86_64_INTEGERSI_CLASS; + else + classes[0] = X86_64_INTEGER_CLASS; + + return 1; +#else + { + int size = byte_offset + type->size; + + if (size <= 4) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 8) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 12) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 16) + { + classes[0] = classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else + FFI_ASSERT (0); + } +#endif + + case FFI_TYPE_FLOAT: + if (byte_offset == 0) + classes[0] = X86_64_SSESF_CLASS; + else + classes[0] = X86_64_SSE_CLASS; + + return 1; + + case FFI_TYPE_DOUBLE: + classes[0] = X86_64_SSEDF_CLASS; + return 1; + + case FFI_TYPE_LONGDOUBLE: + classes[0] = X86_64_X87_CLASS; + classes[1] = X86_64_X87UP_CLASS; + return 2; + + case FFI_TYPE_STRUCT: + { + ffi_type** ptr; + int i; + enum x86_64_reg_class subclasses[MAX_CLASSES]; + const int UNITS_PER_WORD = 8; + int words = + (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + + /* If the struct is larger than 16 bytes, pass it on the stack. */ + if (type->size > 16) + return 0; + + for (i = 0; i < words; i++) + classes[i] = X86_64_NO_CLASS; + + /* Merge the fields of structure. */ + for (ptr = type->elements; *ptr != NULL; ptr++) + { + int num, pos; + + byte_offset = ALIGN(byte_offset, (*ptr)->alignment); + + num = classify_argument(*ptr, subclasses, byte_offset % 8); + + if (num == 0) + return 0; + + pos = byte_offset / 8; + + for (i = 0; i < num; i++) + { + classes[i + pos] = + merge_classes(subclasses[i], classes[i + pos]); + } + + byte_offset += (*ptr)->size; + } + + if (words > 2) + { + /* When size > 16 bytes, if the first one isn't + X86_64_SSE_CLASS or any other ones aren't + X86_64_SSEUP_CLASS, everything should be passed in + memory. */ + if (classes[0] != X86_64_SSE_CLASS) + return 0; + + for (i = 1; i < words; i++) + if (classes[i] != X86_64_SSEUP_CLASS) + return 0; + } + + + /* Final merger cleanup. */ + for (i = 0; i < words; i++) + { + /* If one class is MEMORY, everything should be passed in + memory. */ + if (classes[i] == X86_64_MEMORY_CLASS) + return 0; + + /* The X86_64_SSEUP_CLASS should be always preceded by + X86_64_SSE_CLASS. */ + if (classes[i] == X86_64_SSEUP_CLASS + && classes[i - 1] != X86_64_SSE_CLASS + && classes[i - 1] != X86_64_SSEUP_CLASS) + { + FFI_ASSERT(i != 0); + classes[i] = X86_64_SSE_CLASS; + } + + /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ + if (classes[i] == X86_64_X87UP_CLASS + && classes[i - 1] != X86_64_X87_CLASS) + { + FFI_ASSERT(i != 0); + classes[i] = X86_64_SSE_CLASS; + } + } + + return words; + } + + default: + FFI_ASSERT(0); + } + + return 0; /* Never reached. */ +} + +/* Examine the argument and return set number of register required in each + class. Return zero if parameter should be passed in memory, otherwise + the number of registers. */ +static int +examine_argument( + ffi_type* type, + enum x86_64_reg_class classes[MAX_CLASSES], + _Bool in_return, + int* pngpr, + int* pnsse) +{ + int n = classify_argument(type, classes, 0); + int ngpr = 0; + int nsse = 0; + int i; + + if (n == 0) + return 0; + + for (i = 0; i < n; ++i) + { + switch (classes[i]) + { + case X86_64_INTEGER_CLASS: + case X86_64_INTEGERSI_CLASS: + ngpr++; + break; + + case X86_64_SSE_CLASS: + case X86_64_SSESF_CLASS: + case X86_64_SSEDF_CLASS: + nsse++; + break; + + case X86_64_NO_CLASS: + case X86_64_SSEUP_CLASS: + break; + + case X86_64_X87_CLASS: + case X86_64_X87UP_CLASS: + case X86_64_COMPLEX_X87_CLASS: + return in_return != 0; + + default: + abort(); + } + } + + *pngpr = ngpr; + *pnsse = nsse; + + return n; +} + +/* Perform machine dependent cif processing. */ +ffi_status +ffi_prep_cif_machdep( + ffi_cif* cif) +{ + int gprcount = 0; + int ssecount = 0; + int flags = cif->rtype->type; + int i, avn, n, ngpr, nsse; + enum x86_64_reg_class classes[MAX_CLASSES]; + size_t bytes; + + if (flags != FFI_TYPE_VOID) + { + n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); + + if (n == 0) + { + /* The return value is passed in memory. A pointer to that + memory is the first argument. Allocate a register for it. */ + gprcount++; + + /* We don't have to do anything in asm for the return. */ + flags = FFI_TYPE_VOID; + } + else if (flags == FFI_TYPE_STRUCT) + { + /* Mark which registers the result appears in. */ + _Bool sse0 = SSE_CLASS_P(classes[0]); + _Bool sse1 = n == 2 && SSE_CLASS_P(classes[1]); + + if (sse0 && !sse1) + flags |= 1 << 8; + else if (!sse0 && sse1) + flags |= 1 << 9; + else if (sse0 && sse1) + flags |= 1 << 10; + + /* Mark the true size of the structure. */ + flags |= cif->rtype->size << 12; + } + } + + /* Go over all arguments and determine the way they should be passed. + If it's in a register and there is space for it, let that be so. If + not, add it's size to the stack byte count. */ + for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++) + { + if (examine_argument(cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = cif->arg_types[i]->alignment; + + if (align < 8) + align = 8; + + bytes = ALIGN(bytes, align); + bytes += cif->arg_types[i]->size; + } + else + { + gprcount += ngpr; + ssecount += nsse; + } + } + + if (ssecount) + flags |= 1 << 11; + + cif->flags = flags; + cif->bytes = bytes; + cif->bytes = ALIGN(bytes,8); + + return FFI_OK; +} + +void +ffi_call( + ffi_cif* cif, + void (*fn)(void), + void* rvalue, + void** avalue) +{ + enum x86_64_reg_class classes[MAX_CLASSES]; + char* stack; + char* argp; + ffi_type** arg_types; + int gprcount, ssecount, ngpr, nsse, i, avn; + _Bool ret_in_memory; + RegisterArgs* reg_args; + + /* Can't call 32-bit mode from 64-bit mode. */ + FFI_ASSERT(cif->abi == FFI_UNIX64); + + /* If the return value is a struct and we don't have a return value + address then we need to make one. Note the setting of flags to + VOID above in ffi_prep_cif_machdep. */ + ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT + && (cif->flags & 0xff) == FFI_TYPE_VOID); + + if (rvalue == NULL && ret_in_memory) + rvalue = alloca (cif->rtype->size); + + /* Allocate the space for the arguments, plus 4 words of temp space. */ + stack = alloca(sizeof(RegisterArgs) + cif->bytes + 4 * 8); + reg_args = (RegisterArgs*)stack; + argp = stack + sizeof(RegisterArgs); + + gprcount = ssecount = 0; + + /* If the return value is passed in memory, add the pointer as the + first integer argument. */ + if (ret_in_memory) + reg_args->gpr[gprcount++] = (long) rvalue; + + avn = cif->nargs; + arg_types = cif->arg_types; + + for (i = 0; i < avn; ++i) + { + size_t size = arg_types[i]->size; + int n; + + n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); + + if (n == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = arg_types[i]->alignment; + + /* Stack arguments are *always* at least 8 byte aligned. */ + if (align < 8) + align = 8; + + /* Pass this argument in memory. */ + argp = (void *) ALIGN (argp, align); + memcpy (argp, avalue[i], size); + argp += size; + } + else + { /* The argument is passed entirely in registers. */ + char *a = (char *) avalue[i]; + int j; + + for (j = 0; j < n; j++, a += 8, size -= 8) + { + switch (classes[j]) + { + case X86_64_INTEGER_CLASS: + case X86_64_INTEGERSI_CLASS: + reg_args->gpr[gprcount] = 0; + switch (arg_types[i]->type) { + case FFI_TYPE_SINT8: + { + int8_t shortval = *(int8_t*)a; + int64_t actval = (int64_t)shortval; + reg_args->gpr[gprcount] = actval; + /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ + break; + } + + case FFI_TYPE_SINT16: + { + int16_t shortval = *(int16_t*)a; + int64_t actval = (int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + case FFI_TYPE_SINT32: + { + int32_t shortval = *(int32_t*)a; + int64_t actval = (int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + case FFI_TYPE_UINT8: + { + u_int8_t shortval = *(u_int8_t*)a; + u_int64_t actval = (u_int64_t)shortval; + /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ + reg_args->gpr[gprcount] = actval; + break; + } + + case FFI_TYPE_UINT16: + { + u_int16_t shortval = *(u_int16_t*)a; + u_int64_t actval = (u_int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + case FFI_TYPE_UINT32: + { + u_int32_t shortval = *(u_int32_t*)a; + u_int64_t actval = (u_int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + default: + //memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); + reg_args->gpr[gprcount] = *(int64_t*)a; + } + gprcount++; + break; + + case X86_64_SSE_CLASS: + case X86_64_SSEDF_CLASS: + reg_args->sse[ssecount++] = *(UINT64 *) a; + break; + + case X86_64_SSESF_CLASS: + reg_args->sse[ssecount++] = *(UINT32 *) a; + break; + + default: + abort(); + } + } + } + } + + ffi_call_unix64 (stack, cif->bytes + sizeof(RegisterArgs), + cif->flags, rvalue, fn, ssecount); +} + +extern void ffi_closure_unix64(void); + +ffi_status +ffi_prep_closure( + ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void* user_data) +{ + volatile unsigned short* tramp; + + if (cif->abi != FFI_UNIX64) + return FFI_BAD_ABI; + + tramp = (volatile unsigned short*)&closure->tramp[0]; + + tramp[0] = 0xbb49; /* mov , %r11 */ + *(void* volatile*)&tramp[1] = ffi_closure_unix64; + tramp[5] = 0xba49; /* mov , %r10 */ + *(void* volatile*)&tramp[6] = closure; + + /* Set the carry bit if the function uses any sse registers. + This is clc or stc, together with the first byte of the jmp. */ + tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8; + tramp[11] = 0xe3ff; /* jmp *%r11 */ + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-prototypes" +int +ffi_closure_unix64_inner( + ffi_closure* closure, + void* rvalue, + RegisterArgs* reg_args, + char* argp) +#pragma clang diagnostic pop +{ + ffi_cif* cif = closure->cif; + void** avalue = alloca(cif->nargs * sizeof(void *)); + ffi_type** arg_types; + long i, avn; + int gprcount = 0; + int ssecount = 0; + int ngpr, nsse; + int ret; + + ret = cif->rtype->type; + + if (ret != FFI_TYPE_VOID) + { + enum x86_64_reg_class classes[MAX_CLASSES]; + int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); + + if (n == 0) + { + /* The return value goes in memory. Arrange for the closure + return value to go directly back to the original caller. */ + rvalue = (void *) reg_args->gpr[gprcount++]; + + /* We don't have to do anything in asm for the return. */ + ret = FFI_TYPE_VOID; + } + else if (ret == FFI_TYPE_STRUCT && n == 2) + { + /* Mark which register the second word of the structure goes in. */ + _Bool sse0 = SSE_CLASS_P (classes[0]); + _Bool sse1 = SSE_CLASS_P (classes[1]); + + if (!sse0 && sse1) + ret |= 1 << 8; + else if (sse0 && !sse1) + ret |= 1 << 9; + } + } + + avn = cif->nargs; + arg_types = cif->arg_types; + + for (i = 0; i < avn; ++i) + { + enum x86_64_reg_class classes[MAX_CLASSES]; + int n; + + n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); + + if (n == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = arg_types[i]->alignment; + + /* Stack arguments are *always* at least 8 byte aligned. */ + if (align < 8) + align = 8; + + /* Pass this argument in memory. */ + argp = (void *) ALIGN (argp, align); + avalue[i] = argp; + argp += arg_types[i]->size; + } + +#if !defined(X86_DARWIN) + /* If the argument is in a single register, or two consecutive + registers, then we can use that address directly. */ + else if (n == 1 || (n == 2 && + SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1]))) + { + // The argument is in a single register. + if (SSE_CLASS_P (classes[0])) + { + avalue[i] = ®_args->sse[ssecount]; + ssecount += n; + } + else + { + avalue[i] = ®_args->gpr[gprcount]; + gprcount += n; + } + } +#endif + + /* Otherwise, allocate space to make them consecutive. */ + else + { + char *a = alloca (16); + int j; + + avalue[i] = a; + + for (j = 0; j < n; j++, a += 8) + { + if (SSE_CLASS_P (classes[j])) + memcpy (a, ®_args->sse[ssecount++], 8); + else + memcpy (a, ®_args->gpr[gprcount++], 8); + } + } + } + + /* Invoke the closure. */ + closure->fun (cif, rvalue, avalue, closure->user_data); + + /* Tell assembly how to perform return type promotions. */ + return ret; +} + +#endif /* __x86_64__ */ diff --git a/python/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c b/python/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c new file mode 100755 index 0000000..706ea0f --- /dev/null +++ b/python/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c @@ -0,0 +1,438 @@ +#ifdef __i386__ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. + Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2002 Bo Thorsen + Copyright (c) 2002 Roger Sayle + + x86 Foreign Function Interface + + 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 CYGNUS SOLUTIONS 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. + ----------------------------------------------------------------------- */ + +#include +#include + +#include + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void ffi_prep_args(char *stack, extended_cif *ecif); + +void ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + + if (ecif->cif->flags == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += 4; + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(int) - 1) & (unsigned) argp) + argp = (char *) ALIGN(argp, sizeof(int)); + + z = (*p_arg)->size; + if (z < sizeof(int)) + { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_SINT32: + *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); + break; + + case FFI_TYPE_UINT32: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + } + else + { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + } + + return; +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: +#ifdef X86 + case FFI_TYPE_STRUCT: + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: +#endif + + case FFI_TYPE_SINT64: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_UINT64: + cif->flags = FFI_TYPE_SINT64; + break; + +#ifndef X86 + case FFI_TYPE_STRUCT: + if (cif->rtype->size == 1) + { + cif->flags = FFI_TYPE_SINT8; /* same as char size */ + } + else if (cif->rtype->size == 2) + { + cif->flags = FFI_TYPE_SINT16; /* same as short size */ + } + else if (cif->rtype->size == 4) + { + cif->flags = FFI_TYPE_INT; /* same as int type */ + } + else if (cif->rtype->size == 8) + { + cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ + } + else + { + cif->flags = FFI_TYPE_STRUCT; + } + break; +#endif + + default: + cif->flags = FFI_TYPE_INT; + break; + } + +#ifdef X86_DARWIN + cif->bytes = (cif->bytes + 15) & ~0xF; +#endif + + return FFI_OK; +} + +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)()); + +#ifdef X86_WIN32 +extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)()); + +#endif /* X86_WIN32 */ + +void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->flags == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); + break; +#ifdef X86_WIN32 + case FFI_STDCALL: + ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; +#endif /* X86_WIN32 */ + default: + FFI_ASSERT(0); + break; + } +} + + +/** private members **/ + +static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, + void** args, ffi_cif* cif); +void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) +__attribute__ ((regparm(1))); +unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *) +__attribute__ ((regparm(1))); +void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) +__attribute__ ((regparm(1))); + +/* This function is jumped to by the trampoline */ + +unsigned int FFI_HIDDEN +ffi_closure_SYSV_inner (closure, respp, args) +ffi_closure *closure; +void **respp; +void *args; +{ + // our various things... + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); + + /* this call will initialize ARG_AREA, such that each + * element in that array points to the corresponding + * value on the stack; and if the function returns + * a structure, it will re-set RESP to point to the + * structure return address. */ + + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); + + (closure->fun) (cif, *respp, arg_area, closure->user_data); + + return cif->flags; +} + +static void +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, + ffi_cif *cif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + + if ( cif->flags == FFI_TYPE_STRUCT ) { + *rvalue = *(void **) argp; + argp += 4; + } + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(int) - 1) & (unsigned) argp) { + argp = (char *) ALIGN(argp, sizeof(int)); + } + + z = (*p_arg)->size; + + /* because we're little endian, this is what it turns into. */ + + *p_argv = (void*) argp; + + p_argv++; + argp += z; + } + + return; +} + +/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ + +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ +({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ +unsigned int __fun = (unsigned int)(FUN); \ +unsigned int __ctx = (unsigned int)(CTX); \ +unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \ +*(unsigned char*) &__tramp[0] = 0xb8; \ +*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ +*(unsigned char *) &__tramp[5] = 0xe9; \ +*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ +}) + + +/* the cif must already be prep'ed */ +ffi_status +ffi_prep_closure (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data) +{ + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ + &ffi_closure_SYSV, \ + (void*)closure); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + +/* ------- Native raw API support -------------------------------- */ + +#if !FFI_NO_RAW_API + +ffi_status +ffi_prep_raw_closure_loc (ffi_raw_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc) +{ + int i; + + FFI_ASSERT (cif->abi == FFI_SYSV); + + // we currently don't support certain kinds of arguments for raw + // closures. This should be implemented by a separate assembly language + // routine, since it would require argument processing, something we + // don't do now for performance. + + for (i = cif->nargs-1; i >= 0; i--) + { + FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); + FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); + } + + + FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, + codeloc); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + +static void +ffi_prep_args_raw(char *stack, extended_cif *ecif) +{ + memcpy (stack, ecif->avalue, ecif->cif->bytes); +} + +/* we borrow this routine from libffi (it must be changed, though, to + * actually call the function passed in the first argument. as of + * libffi-1.20, this is not the case.) + */ + +extern void +ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, + unsigned, unsigned *, void (*fn)()); + +#ifdef X86_WIN32 +extern void +ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned, + unsigned, unsigned *, void (*fn)()); +#endif /* X86_WIN32 */ + +void +ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue) +{ + extended_cif ecif; + void **avalue = (void **)fake_avalue; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; +#ifdef X86_WIN32 + case FFI_STDCALL: + ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; +#endif /* X86_WIN32 */ + default: + FFI_ASSERT(0); + break; + } +} + +#endif +#endif // __i386__ diff --git a/python/Modules/_ctypes/malloc_closure.c b/python/Modules/_ctypes/malloc_closure.c new file mode 100755 index 0000000..788bae6 --- /dev/null +++ b/python/Modules/_ctypes/malloc_closure.c @@ -0,0 +1,135 @@ +#include +#include +#ifdef MS_WIN32 +#include +#else +#include +#include +# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif +#endif +#include "ctypes.h" + +/* BLOCKSIZE can be adjusted. Larger blocksize will take a larger memory + overhead, but allocate less blocks from the system. It may be that some + systems have a limit of how many mmap'd blocks can be open. +*/ + +#define BLOCKSIZE _pagesize + +/* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */ + +/******************************************************************/ + +typedef union _tagITEM { + ffi_closure closure; + union _tagITEM *next; +} ITEM; + +static ITEM *free_list; +static int _pagesize; + +static void more_core(void) +{ + ITEM *item; + int count, i; + +/* determine the pagesize */ +#ifdef MS_WIN32 + if (!_pagesize) { + SYSTEM_INFO systeminfo; + GetSystemInfo(&systeminfo); + _pagesize = systeminfo.dwPageSize; + } +#else + if (!_pagesize) { +#ifdef _SC_PAGESIZE + _pagesize = sysconf(_SC_PAGESIZE); +#else + _pagesize = getpagesize(); +#endif + } +#endif + + /* calculate the number of nodes to allocate */ + count = BLOCKSIZE / sizeof(ITEM); + + /* allocate a memory block */ +#ifdef MS_WIN32 + item = (ITEM *)VirtualAlloc(NULL, + count * sizeof(ITEM), + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + if (item == NULL) + return; +#else + item = (ITEM *)mmap(NULL, + count * sizeof(ITEM), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, + 0); + if (item == (void *)MAP_FAILED) + return; +#endif + +#ifdef MALLOC_CLOSURE_DEBUG + printf("block at %p allocated (%d bytes), %d ITEMs\n", + item, count * (int)sizeof(ITEM), count); +#endif + /* put them into the free list */ + for (i = 0; i < count; ++i) { + item->next = free_list; + free_list = item; + ++item; + } +} + +/******************************************************************/ + +/* put the item back into the free list */ +void Py_ffi_closure_free(void *p) +{ +#if HAVE_FFI_CLOSURE_ALLOC +#if USING_APPLE_OS_LIBFFI + if (__builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)) { +#endif + ffi_closure_free(p); + return; +#if USING_APPLE_OS_LIBFFI + } +#endif +#endif + ITEM *item = (ITEM *)p; + item->next = free_list; + free_list = item; +} + +/* return one item from the free list, allocating more if needed */ +void *Py_ffi_closure_alloc(size_t size, void** codeloc) +{ +#if HAVE_FFI_CLOSURE_ALLOC +#if USING_APPLE_OS_LIBFFI + if (__builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)) { +#endif + return ffi_closure_alloc(size, codeloc); +#if USING_APPLE_OS_LIBFFI + } +#endif +#endif + ITEM *item; + if (!free_list) + more_core(); + if (!free_list) + return NULL; + item = free_list; + free_list = item->next; +#ifdef _M_ARM + // set Thumb bit so that blx is called correctly + *codeloc = (ITEM*)((uintptr_t)item | 1); +#else + *codeloc = (void *)item; +#endif + return (void *)item; +} diff --git a/python/Modules/_ctypes/stgdict.c b/python/Modules/_ctypes/stgdict.c new file mode 100755 index 0000000..1d45ade --- /dev/null +++ b/python/Modules/_ctypes/stgdict.c @@ -0,0 +1,900 @@ +#include "Python.h" +#include +#ifdef MS_WIN32 +#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_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) +{ + PyTypeObject *type = self->ob_type; + 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_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; + } + assert(Py_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) +{ + _Py_IDENTIFIER(_anonymous_); + 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 (Py_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) +{ + _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; + PyObject *tmp; + int isPacked; + int pack; + 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 + 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; + + if (_PyObject_LookupAttrId(type, &PyId__swappedbytes_, &tmp) < 0) { + return -1; + } + if (tmp) { + Py_DECREF(tmp); + big_endian = !PY_BIG_ENDIAN; + } + else { + big_endian = PY_BIG_ENDIAN; + } + + if (_PyObject_LookupAttrId(type, + &PyId__use_broken_old_ctypes_structure_semantics_, &tmp) < 0) + { + return -1; + } + if (tmp) { + Py_DECREF(tmp); + use_broken_old_ctypes_semantics = 1; + } + else { + use_broken_old_ctypes_semantics = 0; + } + + if (_PyObject_LookupAttrId(type, &PyId__pack_, &tmp) < 0) { + return -1; + } + if (tmp) { + isPacked = 1; + pack = _PyLong_AsInt(tmp); + Py_DECREF(tmp); + if (pack < 0) { + if (!PyErr_Occurred() || + PyErr_ExceptionMatches(PyExc_TypeError) || + PyErr_ExceptionMatches(PyExc_OverflowError)) + { + PyErr_SetString(PyExc_ValueError, + "_pack_ must be a non-negative integer"); + } + return -1; + } + } + else { + isPacked = 0; + pack = 0; + } + + len = PySequence_Size(fields); + 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); + if (basedict) { + stgdict->flags |= (basedict->flags & + (TYPEFLAG_HASUNION | TYPEFLAG_HASBITFIELD)); + } + 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 (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; + stgdict->flags |= dict->flags & (TYPEFLAG_HASUNION | TYPEFLAG_HASBITFIELD); + 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? */ + +#define MAX_STRUCT_SIZE 16 + + if (arrays_seen && (size <= MAX_STRUCT_SIZE)) { + /* + * See bpo-22273. Arrays are normally treated as pointers, which is + * fine when an array name is being passed as parameter, but not when + * passing structures by value that contain arrays. On 64-bit Linux, + * small structures passed by value are passed in registers, and in + * order to do this, libffi needs to know the true type of the array + * members of structs. Treating them as pointers breaks things. + * + * By small structures, we mean ones that are 16 bytes or less. In that + * case, there can't be more than 16 elements after unrolling arrays, + * as we (will) disallow bitfields. So we can collect the true ffi_type + * values in a fixed-size local array on the stack and, if any arrays + * were seen, replace the ffi_type_pointer.elements with a more + * accurate set, to allow libffi to marshal them into registers + * correctly. It means one more loop over the fields, but if we got + * here, the structure is small, so there aren't too many of those. + * + * Although the passing in registers is specific to 64-bit Linux, the + * array-in-struct vs. pointer problem is general. But we restrict the + * type transformation to small structs nonetheless. + * + * Note that although a union may be small in terms of memory usage, it + * could contain many overlapping declarations of arrays, e.g. + * + * union { + * unsigned int_8 foo [16]; + * unsigned uint_8 bar [16]; + * unsigned int_16 baz[8]; + * unsigned uint_16 bozz[8]; + * unsigned int_32 fizz[4]; + * unsigned uint_32 buzz[4]; + * } + * + * which is still only 16 bytes in size. We need to convert this into + * the following equivalent for libffi: + * + * union { + * struct { int_8 e1; int_8 e2; ... int_8 e_16; } f1; + * struct { uint_8 e1; uint_8 e2; ... uint_8 e_16; } f2; + * struct { int_16 e1; int_16 e2; ... int_16 e_8; } f3; + * struct { uint_16 e1; uint_16 e2; ... uint_16 e_8; } f4; + * struct { int_32 e1; int_32 e2; ... int_32 e_4; } f5; + * struct { uint_32 e1; uint_32 e2; ... uint_32 e_4; } f6; + * } + * + * So the struct/union needs setting up as follows: all non-array + * elements copied across as is, and all array elements replaced with + * an equivalent struct which has as many fields as the array has + * elements, plus one NULL pointer. + */ + + Py_ssize_t num_ffi_type_pointers = 0; /* for the dummy fields */ + Py_ssize_t num_ffi_types = 0; /* for the dummy structures */ + size_t alloc_size; /* total bytes to allocate */ + void *type_block; /* to hold all the type information needed */ + ffi_type **element_types; /* of this struct/union */ + ffi_type **dummy_types; /* of the dummy struct elements */ + ffi_type *structs; /* point to struct aliases of arrays */ + Py_ssize_t element_index; /* index into element_types for this */ + Py_ssize_t dummy_index = 0; /* index into dummy field pointers */ + Py_ssize_t struct_index = 0; /* index into dummy structs */ + + /* first pass to see how much memory to allocate */ + for (i = 0; i < len; ++i) { + PyObject *name, *desc; + PyObject *pair = PySequence_GetItem(fields, i); + StgDictObject *dict; + int bitsize = 0; + + if (pair == NULL) { + return -1; + } + if (!PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) { + PyErr_SetString(PyExc_TypeError, + "'_fields_' must be a sequence of (name, C type) pairs"); + Py_DECREF(pair); + return -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; + } + if (!PyCArrayTypeObject_Check(desc)) { + /* Not an array. Just need an ffi_type pointer. */ + num_ffi_type_pointers++; + } + else { + /* It's an array. */ + Py_ssize_t length = dict->length; + StgDictObject *edict; + + edict = PyType_stgdict(dict->proto); + if (edict == NULL) { + Py_DECREF(pair); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + /* + * We need one extra ffi_type to hold the struct, and one + * ffi_type pointer per array element + one for a NULL to + * mark the end. + */ + num_ffi_types++; + num_ffi_type_pointers += length + 1; + } + Py_DECREF(pair); + } + + /* + * At this point, we know we need storage for some ffi_types and some + * ffi_type pointers. We'll allocate these in one block. + * There are three sub-blocks of information: the ffi_type pointers to + * this structure/union's elements, the ffi_type_pointers to the + * dummy fields standing in for array elements, and the + * ffi_types representing the dummy structures. + */ + alloc_size = (ffi_ofs + 1 + len + num_ffi_type_pointers) * sizeof(ffi_type *) + + num_ffi_types * sizeof(ffi_type); + type_block = PyMem_Malloc(alloc_size); + + if (type_block == NULL) { + PyErr_NoMemory(); + return -1; + } + /* + * the first block takes up ffi_ofs + len + 1 which is the pointers * + * for this struct/union. The second block takes up + * num_ffi_type_pointers, so the sum of these is ffi_ofs + len + 1 + + * num_ffi_type_pointers as allocated above. The last bit is the + * num_ffi_types structs. + */ + element_types = (ffi_type **) type_block; + dummy_types = &element_types[ffi_ofs + len + 1]; + structs = (ffi_type *) &dummy_types[num_ffi_type_pointers]; + + if (num_ffi_types > 0) { + memset(structs, 0, num_ffi_types * sizeof(ffi_type)); + } + if (ffi_ofs && (basedict != NULL)) { + memcpy(element_types, + basedict->ffi_type_pointer.elements, + ffi_ofs * sizeof(ffi_type *)); + } + element_index = ffi_ofs; + + /* second pass to actually set the type pointers */ + for (i = 0; i < len; ++i) { + PyObject *name, *desc; + PyObject *pair = PySequence_GetItem(fields, i); + StgDictObject *dict; + int bitsize = 0; + + if (pair == NULL) { + PyMem_Free(type_block); + return -1; + } + /* In theory, we made this call in the first pass, so it *shouldn't* + * fail. However, you never know, and the code above might change + * later - keeping the check in here is a tad defensive but it + * will affect program size only slightly and performance hardly at + * all. + */ + if (!PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) { + PyErr_SetString(PyExc_TypeError, + "'_fields_' must be a sequence of (name, C type) pairs"); + Py_DECREF(pair); + PyMem_Free(type_block); + return -1; + } + dict = PyType_stgdict(desc); + /* Possibly this check could be avoided, but see above comment. */ + if (dict == NULL) { + Py_DECREF(pair); + PyMem_Free(type_block); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + assert(element_index < (ffi_ofs + len)); /* will be used below */ + if (!PyCArrayTypeObject_Check(desc)) { + /* Not an array. Just copy over the element ffi_type. */ + element_types[element_index++] = &dict->ffi_type_pointer; + } + else { + Py_ssize_t length = dict->length; + StgDictObject *edict; + + edict = PyType_stgdict(dict->proto); + if (edict == NULL) { + Py_DECREF(pair); + PyMem_Free(type_block); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + element_types[element_index++] = &structs[struct_index]; + structs[struct_index].size = length * edict->ffi_type_pointer.size; + structs[struct_index].alignment = edict->ffi_type_pointer.alignment; + structs[struct_index].type = FFI_TYPE_STRUCT; + structs[struct_index].elements = &dummy_types[dummy_index]; + ++struct_index; + /* Copy over the element's type, length times. */ + while (length > 0) { + assert(dummy_index < (num_ffi_type_pointers)); + dummy_types[dummy_index++] = &edict->ffi_type_pointer; + length--; + } + assert(dummy_index < (num_ffi_type_pointers)); + dummy_types[dummy_index++] = NULL; + } + Py_DECREF(pair); + } + + element_types[element_index] = NULL; + /* + * Replace the old elements with the new, taking into account + * base class elements where necessary. + */ + assert(stgdict->ffi_type_pointer.elements); + PyMem_Free(stgdict->ffi_type_pointer.elements); + 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); +} diff --git a/python/Modules/_curses_panel.c b/python/Modules/_curses_panel.c new file mode 100755 index 0000000..0c17e48 --- /dev/null +++ b/python/Modules/_curses_panel.c @@ -0,0 +1,672 @@ +// /* +// * Interface to the ncurses panel library +// * +// * Original version by Thomas Gellekum +// */ + +// /* Release Number */ + +// static const char PyCursesVersion[] = "2.1"; + +// /* Includes */ + +// #include "Python.h" + +// #include "py_curses.h" + +// #include + +// typedef struct { +// PyObject *PyCursesError; +// PyObject *PyCursesPanel_Type; +// } _curses_panelstate; + +// #define _curses_panelstate(o) ((_curses_panelstate *)PyModule_GetState(o)) + +// static int +// _curses_panel_clear(PyObject *m) +// { +// Py_CLEAR(_curses_panelstate(m)->PyCursesError); +// return 0; +// } + +// static int +// _curses_panel_traverse(PyObject *m, visitproc visit, void *arg) +// { +// Py_VISIT(_curses_panelstate(m)->PyCursesError); +// return 0; +// } + +// static void +// _curses_panel_free(void *m) +// { +// _curses_panel_clear((PyObject *) m); +// } + +// static struct PyModuleDef _curses_panelmodule; + +// #define _curses_panelstate_global \ +// ((_curses_panelstate *) PyModule_GetState(PyState_FindModule(&_curses_panelmodule))) + +// /* Utility Functions */ + +// /* +// * Check the return code from a curses function and return None +// * or raise an exception as appropriate. +// */ + +// static PyObject * +// PyCursesCheckERR(int code, const char *fname) +// { +// if (code != ERR) { +// Py_RETURN_NONE; +// } else { +// if (fname == NULL) { +// PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_ERR); +// } else { +// PyErr_Format(_curses_panelstate_global->PyCursesError, "%s() returned ERR", fname); +// } +// return NULL; +// } +// } + +// /***************************************************************************** +// The Panel Object +// ******************************************************************************/ + +// /* Definition of the panel object and panel type */ + +// typedef struct { +// PyObject_HEAD +// PANEL *pan; +// PyCursesWindowObject *wo; /* for reference counts */ +// } PyCursesPanelObject; + +// #define PyCursesPanel_Check(v) \ +// (Py_TYPE(v) == _curses_panelstate_global->PyCursesPanel_Type) + +// /* Some helper functions. The problem is that there's always a window +// associated with a panel. To ensure that Python's GC doesn't pull +// this window from under our feet we need to keep track of references +// to the corresponding window object within Python. We can't use +// dupwin(oldwin) to keep a copy of the curses WINDOW because the +// contents of oldwin is copied only once; code like + +// win = newwin(...) +// pan = win.panel() +// win.addstr(some_string) +// pan.window().addstr(other_string) + +// will fail. */ + +// /* We keep a linked list of PyCursesPanelObjects, lop. A list should +// suffice, I don't expect more than a handful or at most a few +// dozens of panel objects within a typical program. */ +// typedef struct _list_of_panels { +// PyCursesPanelObject *po; +// struct _list_of_panels *next; +// } list_of_panels; + +// /* list anchor */ +// static list_of_panels *lop; + +// /* Insert a new panel object into lop */ +// static int +// insert_lop(PyCursesPanelObject *po) +// { +// list_of_panels *new; + +// if ((new = (list_of_panels *)PyMem_Malloc(sizeof(list_of_panels))) == NULL) { +// PyErr_NoMemory(); +// return -1; +// } +// new->po = po; +// new->next = lop; +// lop = new; +// return 0; +// } + +// /* Remove the panel object from lop */ +// static void +// remove_lop(PyCursesPanelObject *po) +// { +// list_of_panels *temp, *n; + +// temp = lop; +// if (temp->po == po) { +// lop = temp->next; +// PyMem_Free(temp); +// return; +// } +// while (temp->next == NULL || temp->next->po != po) { +// if (temp->next == NULL) { +// PyErr_SetString(PyExc_RuntimeError, +// "remove_lop: can't find Panel Object"); +// return; +// } +// temp = temp->next; +// } +// n = temp->next->next; +// PyMem_Free(temp->next); +// temp->next = n; +// return; +// } + +// /* Return the panel object that corresponds to pan */ +// static PyCursesPanelObject * +// find_po(PANEL *pan) +// { +// list_of_panels *temp; +// for (temp = lop; temp->po->pan != pan; temp = temp->next) +// if (temp->next == NULL) return NULL; /* not found!? */ +// return temp->po; +// } + +// /*[clinic input] +// module _curses_panel +// class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type" +// [clinic start generated code]*/ +// /*[clinic end generated code: output=da39a3ee5e6b4b0d input=2f4ef263ca850a31]*/ + +// #include "clinic/_curses_panel.c.h" + +// /* ------------- PANEL routines --------------- */ + +// /*[clinic input] +// _curses_panel.panel.bottom + +// Push the panel to the bottom of the stack. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_bottom_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=7aa7d14d7e1d1ce6 input=b6c920c071b61e2e]*/ +// { +// return PyCursesCheckERR(bottom_panel(self->pan), "bottom"); +// } + +// /*[clinic input] +// _curses_panel.panel.hide + +// Hide the panel. + +// This does not delete the object, it just makes the window on screen invisible. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_hide_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=a7bbbd523e1eab49 input=f6ab884e99386118]*/ +// { +// return PyCursesCheckERR(hide_panel(self->pan), "hide"); +// } + +// /*[clinic input] +// _curses_panel.panel.show + +// Display the panel (which might have been hidden). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_show_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=6b4553ab45c97769 input=57b167bbefaa3755]*/ +// { +// return PyCursesCheckERR(show_panel(self->pan), "show"); +// } + +// /*[clinic input] +// _curses_panel.panel.top + +// Push panel to the top of the stack. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_top_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=0f5f2f8cdd2d1777 input=be33975ec3ca0e9a]*/ +// { +// return PyCursesCheckERR(top_panel(self->pan), "top"); +// } + +// /* Allocation and deallocation of Panel Objects */ + +// static PyObject * +// PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo) +// { +// PyCursesPanelObject *po; + +// po = PyObject_NEW(PyCursesPanelObject, +// (PyTypeObject *)(_curses_panelstate_global)->PyCursesPanel_Type); +// if (po == NULL) return NULL; +// po->pan = pan; +// if (insert_lop(po) < 0) { +// po->wo = NULL; +// Py_DECREF(po); +// return NULL; +// } +// po->wo = wo; +// Py_INCREF(wo); +// return (PyObject *)po; +// } + +// static void +// PyCursesPanel_Dealloc(PyCursesPanelObject *po) +// { +// PyObject *tp, *obj; + +// tp = (PyObject *) Py_TYPE(po); +// obj = (PyObject *) panel_userptr(po->pan); +// if (obj) { +// (void)set_panel_userptr(po->pan, NULL); +// Py_DECREF(obj); +// } +// (void)del_panel(po->pan); +// if (po->wo != NULL) { +// Py_DECREF(po->wo); +// remove_lop(po); +// } +// PyObject_DEL(po); +// Py_DECREF(tp); +// } + +// /* panel_above(NULL) returns the bottom panel in the stack. To get +// this behaviour we use curses.panel.bottom_panel(). */ +// /*[clinic input] +// _curses_panel.panel.above + +// Return the panel above the current panel. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_above_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=70ac06d25fd3b4da input=c059994022976788]*/ +// { +// PANEL *pan; +// PyCursesPanelObject *po; + +// pan = panel_above(self->pan); + +// if (pan == NULL) { /* valid output, it means the calling panel +// is on top of the stack */ +// Py_RETURN_NONE; +// } +// po = find_po(pan); +// if (po == NULL) { +// PyErr_SetString(PyExc_RuntimeError, +// "panel_above: can't find Panel Object"); +// return NULL; +// } +// Py_INCREF(po); +// return (PyObject *)po; +// } + +// /* panel_below(NULL) returns the top panel in the stack. To get +// this behaviour we use curses.panel.top_panel(). */ +// /*[clinic input] +// _curses_panel.panel.below + +// Return the panel below the current panel. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_below_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=282861122e06e3de input=cc08f61936d297c6]*/ +// { +// PANEL *pan; +// PyCursesPanelObject *po; + +// pan = panel_below(self->pan); + +// if (pan == NULL) { /* valid output, it means the calling panel +// is on the bottom of the stack */ +// Py_RETURN_NONE; +// } +// po = find_po(pan); +// if (po == NULL) { +// PyErr_SetString(PyExc_RuntimeError, +// "panel_below: can't find Panel Object"); +// return NULL; +// } +// Py_INCREF(po); +// return (PyObject *)po; +// } + +// /*[clinic input] +// _curses_panel.panel.hidden + +// Return True if the panel is hidden (not visible), False otherwise. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_hidden_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=66eebd1ab4501a71 input=453d4b4fce25e21a]*/ +// { +// if (panel_hidden(self->pan)) +// Py_RETURN_TRUE; +// else +// Py_RETURN_FALSE; +// } + +// /*[clinic input] +// _curses_panel.panel.move + +// y: int +// x: int +// / + +// Move the panel to the screen coordinates (y, x). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x) +// /*[clinic end generated code: output=d867535a89777415 input=e0b36b78acc03fba]*/ +// { +// return PyCursesCheckERR(move_panel(self->pan, y, x), "move_panel"); +// } + +// /*[clinic input] +// _curses_panel.panel.window + +// Return the window object associated with the panel. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_window_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=5f05940d4106b4cb input=6067353d2c307901]*/ +// { +// Py_INCREF(self->wo); +// return (PyObject *)self->wo; +// } + +// /*[clinic input] +// _curses_panel.panel.replace + +// win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") +// / + +// Change the window associated with the panel to the window win. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_replace_impl(PyCursesPanelObject *self, +// PyCursesWindowObject *win) +// /*[clinic end generated code: output=2253a95f7b287255 input=4b1c4283987d9dfa]*/ +// { +// PyCursesPanelObject *po; +// int rtn; + +// po = find_po(self->pan); +// if (po == NULL) { +// PyErr_SetString(PyExc_RuntimeError, +// "replace_panel: can't find Panel Object"); +// return NULL; +// } + +// rtn = replace_panel(self->pan, win->win); +// if (rtn == ERR) { +// PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); +// return NULL; +// } +// Py_INCREF(win); +// Py_SETREF(po->wo, win); +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _curses_panel.panel.set_userptr + +// obj: object +// / + +// Set the panel's user pointer to obj. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyObject *obj) +// /*[clinic end generated code: output=6fb145b3af88cf4a input=d2c6a9dbefabbf39]*/ +// { +// PyObject *oldobj; +// int rc; +// PyCursesInitialised; +// Py_INCREF(obj); +// oldobj = (PyObject *) panel_userptr(self->pan); +// rc = set_panel_userptr(self->pan, (void*)obj); +// if (rc == ERR) { +// /* In case of an ncurses error, decref the new object again */ +// Py_DECREF(obj); +// } +// else { +// Py_XDECREF(oldobj); +// } +// return PyCursesCheckERR(rc, "set_panel_userptr"); +// } + +// /*[clinic input] +// _curses_panel.panel.userptr + +// Return the user pointer for the panel. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_panel_userptr_impl(PyCursesPanelObject *self) +// /*[clinic end generated code: output=e849c307b5dc9237 input=f78b7a47aef0fd50]*/ +// { +// PyObject *obj; +// PyCursesInitialised; +// obj = (PyObject *) panel_userptr(self->pan); +// if (obj == NULL) { +// PyErr_SetString(_curses_panelstate_global->PyCursesError, "no userptr set"); +// return NULL; +// } + +// Py_INCREF(obj); +// return obj; +// } + + +// /* Module interface */ + +// static PyMethodDef PyCursesPanel_Methods[] = { +// _CURSES_PANEL_PANEL_ABOVE_METHODDEF +// _CURSES_PANEL_PANEL_BELOW_METHODDEF +// _CURSES_PANEL_PANEL_BOTTOM_METHODDEF +// _CURSES_PANEL_PANEL_HIDDEN_METHODDEF +// _CURSES_PANEL_PANEL_HIDE_METHODDEF +// _CURSES_PANEL_PANEL_MOVE_METHODDEF +// _CURSES_PANEL_PANEL_REPLACE_METHODDEF +// _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF +// _CURSES_PANEL_PANEL_SHOW_METHODDEF +// _CURSES_PANEL_PANEL_TOP_METHODDEF +// _CURSES_PANEL_PANEL_USERPTR_METHODDEF +// _CURSES_PANEL_PANEL_WINDOW_METHODDEF +// {NULL, NULL} /* sentinel */ +// }; + +// /* -------------------------------------------------------*/ + +// static PyType_Slot PyCursesPanel_Type_slots[] = { +// {Py_tp_dealloc, PyCursesPanel_Dealloc}, +// {Py_tp_methods, PyCursesPanel_Methods}, +// {0, 0}, +// }; + +// static PyType_Spec PyCursesPanel_Type_spec = { +// "_curses_panel.panel", +// sizeof(PyCursesPanelObject), +// 0, +// Py_TPFLAGS_DEFAULT, +// PyCursesPanel_Type_slots +// }; + +// /* Wrapper for panel_above(NULL). This function returns the bottom +// panel of the stack, so it's renamed to bottom_panel(). +// panel.above() *requires* a panel object in the first place which +// may be undesirable. */ +// /*[clinic input] +// _curses_panel.bottom_panel + +// Return the bottom panel in the panel stack. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_bottom_panel_impl(PyObject *module) +// /*[clinic end generated code: output=3aba9f985f4c2bd0 input=634c2a8078b3d7e4]*/ +// { +// PANEL *pan; +// PyCursesPanelObject *po; + +// PyCursesInitialised; + +// pan = panel_above(NULL); + +// if (pan == NULL) { /* valid output, it means +// there's no panel at all */ +// Py_RETURN_NONE; +// } +// po = find_po(pan); +// if (po == NULL) { +// PyErr_SetString(PyExc_RuntimeError, +// "panel_above: can't find Panel Object"); +// return NULL; +// } +// Py_INCREF(po); +// return (PyObject *)po; +// } + +// /*[clinic input] +// _curses_panel.new_panel + +// win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") +// / + +// Return a panel object, associating it with the given window win. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win) +// /*[clinic end generated code: output=45e948e0176a9bd2 input=74d4754e0ebe4800]*/ +// { +// PANEL *pan = new_panel(win->win); +// if (pan == NULL) { +// PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_NULL); +// return NULL; +// } +// return (PyObject *)PyCursesPanel_New(pan, win); +// } + + +// /* Wrapper for panel_below(NULL). This function returns the top panel +// of the stack, so it's renamed to top_panel(). panel.below() +// *requires* a panel object in the first place which may be +// undesirable. */ +// /*[clinic input] +// _curses_panel.top_panel + +// Return the top panel in the panel stack. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_top_panel_impl(PyObject *module) +// /*[clinic end generated code: output=86704988bea8508e input=e62d6278dba39e79]*/ +// { +// PANEL *pan; +// PyCursesPanelObject *po; + +// PyCursesInitialised; + +// pan = panel_below(NULL); + +// if (pan == NULL) { /* valid output, it means +// there's no panel at all */ +// Py_RETURN_NONE; +// } +// po = find_po(pan); +// if (po == NULL) { +// PyErr_SetString(PyExc_RuntimeError, +// "panel_below: can't find Panel Object"); +// return NULL; +// } +// Py_INCREF(po); +// return (PyObject *)po; +// } + +// /*[clinic input] +// _curses_panel.update_panels + +// Updates the virtual screen after changes in the panel stack. + +// This does not call curses.doupdate(), so you'll have to do this yourself. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_panel_update_panels_impl(PyObject *module) +// /*[clinic end generated code: output=2f3b4c2e03d90ded input=5299624c9a708621]*/ +// { +// PyCursesInitialised; +// update_panels(); +// Py_RETURN_NONE; +// } + + +// /* List of functions defined in the module */ + +// static PyMethodDef PyCurses_methods[] = { +// _CURSES_PANEL_BOTTOM_PANEL_METHODDEF +// _CURSES_PANEL_NEW_PANEL_METHODDEF +// _CURSES_PANEL_TOP_PANEL_METHODDEF +// _CURSES_PANEL_UPDATE_PANELS_METHODDEF +// {NULL, NULL} /* sentinel */ +// }; + +// /* Initialization function for the module */ + + +// static struct PyModuleDef _curses_panelmodule = { +// PyModuleDef_HEAD_INIT, +// "_curses_panel", +// NULL, +// sizeof(_curses_panelstate), +// PyCurses_methods, +// NULL, +// _curses_panel_traverse, +// _curses_panel_clear, +// _curses_panel_free +// }; + +// PyMODINIT_FUNC +// PyInit__curses_panel(void) +// { +// PyObject *m, *d, *v; + +// /* Create the module and add the functions */ +// m = PyModule_Create(&_curses_panelmodule); +// if (m == NULL) +// goto fail; +// d = PyModule_GetDict(m); + +// /* Initialize object type */ +// v = PyType_FromSpec(&PyCursesPanel_Type_spec); +// if (v == NULL) +// goto fail; +// ((PyTypeObject *)v)->tp_new = NULL; +// _curses_panelstate(m)->PyCursesPanel_Type = v; + +// import_curses(); +// if (PyErr_Occurred()) +// goto fail; + +// /* For exception _curses_panel.error */ +// _curses_panelstate(m)->PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL); +// PyDict_SetItemString(d, "error", _curses_panelstate(m)->PyCursesError); + +// /* Make the version available */ +// v = PyUnicode_FromString(PyCursesVersion); +// PyDict_SetItemString(d, "version", v); +// PyDict_SetItemString(d, "__version__", v); +// Py_DECREF(v); + +// Py_INCREF(_curses_panelstate(m)->PyCursesPanel_Type); +// PyModule_AddObject(m, "panel", (PyObject *)_curses_panelstate(m)->PyCursesPanel_Type); +// return m; +// fail: +// Py_XDECREF(m); +// return NULL; +// } diff --git a/python/Modules/_cursesmodule.c b/python/Modules/_cursesmodule.c new file mode 100755 index 0000000..ea1d5a7 --- /dev/null +++ b/python/Modules/_cursesmodule.c @@ -0,0 +1,4656 @@ +// /* +// * This is a curses module for Python. +// * +// * Based on prior work by Lance Ellinghaus and Oliver Andrich +// * Version 1.2 of this module: Copyright 1994 by Lance Ellinghouse, +// * Cathedral City, California Republic, United States of America. +// * +// * Version 1.5b1, heavily extended for ncurses by Oliver Andrich: +// * Copyright 1996,1997 by Oliver Andrich, Koblenz, Germany. +// * +// * Tidied for Python 1.6, and currently maintained by . +// * +// * Permission is hereby granted, free of charge, to any person obtaining +// * a copy of this source file to use, copy, modify, merge, or publish it +// * subject to the following conditions: +// * +// * The above copyright notice and this permission notice shall be included +// * in all copies or in any new file that contains a substantial portion of +// * this file. +// * +// * THE AUTHOR MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF +// * THE SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT +// * EXPRESS OR IMPLIED WARRANTY. THE AUTHOR DISCLAIMS ALL WARRANTIES +// * WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES +// * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// * NON-INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE +// * AUTHOR BE LIABLE TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, +// * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +// * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, STRICT LIABILITY OR +// * ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// * PERFORMANCE OF THIS SOFTWARE. +// */ + +// /* + +// A number of SysV or ncurses functions don't have wrappers yet; if you +// need a given function, add it and send a patch. See +// http://www.python.org/dev/patches/ for instructions on how to submit +// patches to Python. + +// Here's a list of currently unsupported functions: + +// addchnstr addchstr color_set define_key +// del_curterm delscreen dupwin inchnstr inchstr innstr keyok +// mcprint mvaddchnstr mvaddchstr mvcur mvinchnstr +// mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr +// mvwinchnstr mvwinchstr mvwinnstr newterm +// restartterm ripoffline scr_dump +// scr_init scr_restore scr_set scrl set_curterm set_term setterm +// tgetent tgetflag tgetnum tgetstr tgoto timeout tputs +// vidattr vidputs waddchnstr waddchstr +// wcolor_set winchnstr winchstr winnstr wmouse_trafo wscrl + +// Low-priority: +// slk_attr slk_attr_off slk_attr_on slk_attr_set slk_attroff +// slk_attron slk_attrset slk_clear slk_color slk_init slk_label +// slk_noutrefresh slk_refresh slk_restore slk_set slk_touch + +// Menu extension (ncurses and probably SYSV): +// current_item free_item free_menu item_count item_description +// item_index item_init item_name item_opts item_opts_off +// item_opts_on item_term item_userptr item_value item_visible +// menu_back menu_driver menu_fore menu_format menu_grey +// menu_init menu_items menu_mark menu_opts menu_opts_off +// menu_opts_on menu_pad menu_pattern menu_request_by_name +// menu_request_name menu_spacing menu_sub menu_term menu_userptr +// menu_win new_item new_menu pos_menu_cursor post_menu +// scale_menu set_current_item set_item_init set_item_opts +// set_item_term set_item_userptr set_item_value set_menu_back +// set_menu_fore set_menu_format set_menu_grey set_menu_init +// set_menu_items set_menu_mark set_menu_opts set_menu_pad +// set_menu_pattern set_menu_spacing set_menu_sub set_menu_term +// set_menu_userptr set_menu_win set_top_row top_row unpost_menu + +// Form extension (ncurses and probably SYSV): +// current_field data_ahead data_behind dup_field +// dynamic_fieldinfo field_arg field_back field_buffer +// field_count field_fore field_index field_info field_init +// field_just field_opts field_opts_off field_opts_on field_pad +// field_status field_term field_type field_userptr form_driver +// form_fields form_init form_opts form_opts_off form_opts_on +// form_page form_request_by_name form_request_name form_sub +// form_term form_userptr form_win free_field free_form +// link_field link_fieldtype move_field new_field new_form +// new_page pos_form_cursor post_form scale_form +// set_current_field set_field_back set_field_buffer +// set_field_fore set_field_init set_field_just set_field_opts +// set_field_pad set_field_status set_field_term set_field_type +// set_field_userptr set_fieldtype_arg set_fieldtype_choice +// set_form_fields set_form_init set_form_opts set_form_page +// set_form_sub set_form_term set_form_userptr set_form_win +// set_max_field set_new_page unpost_form + + +// */ + +// /* Release Number */ + +// static const char PyCursesVersion[] = "2.2"; + +// /* Includes */ + +// #define PY_SSIZE_T_CLEAN + +// #include "Python.h" + + +// #ifdef __hpux +// #define STRICT_SYSV_CURSES +// #endif + +// #define CURSES_MODULE +// #include "py_curses.h" + +// #if defined(HAVE_TERM_H) || defined(__sgi) +// /* For termname, longname, putp, tigetflag, tigetnum, tigetstr, tparm +// which are not declared in SysV curses and for setupterm. */ +// #include +// /* Including #defines many common symbols. */ +// #undef lines +// #undef columns +// #endif + +// #ifdef HAVE_LANGINFO_H +// #include +// #endif + +// #if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5)) +// #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ +// typedef chtype attr_t; /* No attr_t type is available */ +// #endif + +// #if defined(_AIX) +// #define STRICT_SYSV_CURSES +// #endif + +// /*[clinic input] +// module _curses +// class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" +// [clinic start generated code]*/ +// /*[clinic end generated code: output=da39a3ee5e6b4b0d input=43265c372c2887d6]*/ + +// /* Definition of exception curses.error */ + +// static PyObject *PyCursesError; + +// /* Tells whether setupterm() has been called to initialise terminfo. */ +// static int initialised_setupterm = FALSE; + +// /* Tells whether initscr() has been called to initialise curses. */ +// static int initialised = FALSE; + +// /* Tells whether start_color() has been called to initialise color usage. */ +// static int initialisedcolors = FALSE; + +// static char *screen_encoding = NULL; + +// /* Utility Macros */ +// #define PyCursesSetupTermCalled \ +// if (initialised_setupterm != TRUE) { \ +// PyErr_SetString(PyCursesError, \ +// "must call (at least) setupterm() first"); \ +// return 0; } + +// #define PyCursesInitialised \ +// if (initialised != TRUE) { \ +// PyErr_SetString(PyCursesError, \ +// "must call initscr() first"); \ +// return 0; } + +// #define PyCursesInitialisedColor \ +// if (initialisedcolors != TRUE) { \ +// PyErr_SetString(PyCursesError, \ +// "must call start_color() first"); \ +// return 0; } + +// /* Utility Functions */ + +// /* +// * Check the return code from a curses function and return None +// * or raise an exception as appropriate. These are exported using the +// * capsule API. +// */ + +// static PyObject * +// PyCursesCheckERR(int code, const char *fname) +// { +// if (code != ERR) { +// Py_RETURN_NONE; +// } else { +// if (fname == NULL) { +// PyErr_SetString(PyCursesError, catchall_ERR); +// } else { +// PyErr_Format(PyCursesError, "%s() returned ERR", fname); +// } +// return NULL; +// } +// } + +// /* Convert an object to a byte (an integer of type chtype): + +// - int +// - bytes of length 1 +// - str of length 1 + +// Return 1 on success, 0 on error (invalid type or integer overflow). */ +// static int +// PyCurses_ConvertToChtype(PyCursesWindowObject *win, PyObject *obj, chtype *ch) +// { +// long value; +// if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) { +// value = (unsigned char)PyBytes_AsString(obj)[0]; +// } +// else if (PyUnicode_Check(obj)) { +// if (PyUnicode_GetLength(obj) != 1) { +// PyErr_Format(PyExc_TypeError, +// "expect bytes or str of length 1, or int, " +// "got a str of length %zi", +// PyUnicode_GET_LENGTH(obj)); +// return 0; +// } +// value = PyUnicode_READ_CHAR(obj, 0); +// if (128 < value) { +// PyObject *bytes; +// const char *encoding; +// if (win) +// encoding = win->encoding; +// else +// encoding = screen_encoding; +// bytes = PyUnicode_AsEncodedString(obj, encoding, NULL); +// if (bytes == NULL) +// return 0; +// if (PyBytes_GET_SIZE(bytes) == 1) +// value = (unsigned char)PyBytes_AS_STRING(bytes)[0]; +// else +// value = -1; +// Py_DECREF(bytes); +// if (value < 0) +// goto overflow; +// } +// } +// else if (PyLong_CheckExact(obj)) { +// int long_overflow; +// value = PyLong_AsLongAndOverflow(obj, &long_overflow); +// if (long_overflow) +// goto overflow; +// } +// else { +// PyErr_Format(PyExc_TypeError, +// "expect bytes or str of length 1, or int, got %s", +// Py_TYPE(obj)->tp_name); +// return 0; +// } +// *ch = (chtype)value; +// if ((long)*ch != value) +// goto overflow; +// return 1; + +// overflow: +// PyErr_SetString(PyExc_OverflowError, +// "byte doesn't fit in chtype"); +// return 0; +// } + +// /* Convert an object to a byte (chtype) or a character (cchar_t): + +// - int +// - bytes of length 1 +// - str of length 1 + +// Return: + +// - 2 if obj is a character (written into *wch) +// - 1 if obj is a byte (written into *ch) +// - 0 on error: raise an exception */ +// static int +// PyCurses_ConvertToCchar_t(PyCursesWindowObject *win, PyObject *obj, +// chtype *ch +// #ifdef HAVE_NCURSESW +// , wchar_t *wch +// #endif +// ) +// { +// long value; +// #ifdef HAVE_NCURSESW +// wchar_t buffer[2]; +// #endif + +// if (PyUnicode_Check(obj)) { +// #ifdef HAVE_NCURSESW +// if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) { +// PyErr_Format(PyExc_TypeError, +// "expect bytes or str of length 1, or int, " +// "got a str of length %zi", +// PyUnicode_GET_LENGTH(obj)); +// return 0; +// } +// *wch = buffer[0]; +// return 2; +// #else +// return PyCurses_ConvertToChtype(win, obj, ch); +// #endif +// } +// else if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) { +// value = (unsigned char)PyBytes_AsString(obj)[0]; +// } +// else if (PyLong_CheckExact(obj)) { +// int overflow; +// value = PyLong_AsLongAndOverflow(obj, &overflow); +// if (overflow) { +// PyErr_SetString(PyExc_OverflowError, +// "int doesn't fit in long"); +// return 0; +// } +// } +// else { +// PyErr_Format(PyExc_TypeError, +// "expect bytes or str of length 1, or int, got %s", +// Py_TYPE(obj)->tp_name); +// return 0; +// } + +// *ch = (chtype)value; +// if ((long)*ch != value) { +// PyErr_Format(PyExc_OverflowError, +// "byte doesn't fit in chtype"); +// return 0; +// } +// return 1; +// } + +// /* Convert an object to a byte string (char*) or a wide character string +// (wchar_t*). Return: + +// - 2 if obj is a character string (written into *wch) +// - 1 if obj is a byte string (written into *bytes) +// - 0 on error: raise an exception */ +// static int +// PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, +// PyObject **bytes, wchar_t **wstr) +// { +// char *str; +// if (PyUnicode_Check(obj)) { +// #ifdef HAVE_NCURSESW +// assert (wstr != NULL); + +// *wstr = PyUnicode_AsWideCharString(obj, NULL); +// if (*wstr == NULL) +// return 0; +// return 2; +// #else +// assert (wstr == NULL); +// *bytes = PyUnicode_AsEncodedString(obj, win->encoding, NULL); +// if (*bytes == NULL) +// return 0; +// /* check for embedded null bytes */ +// if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { +// return 0; +// } +// return 1; +// #endif +// } +// else if (PyBytes_Check(obj)) { +// Py_INCREF(obj); +// *bytes = obj; +// /* check for embedded null bytes */ +// if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { +// Py_DECREF(obj); +// return 0; +// } +// return 1; +// } + +// PyErr_Format(PyExc_TypeError, "expect bytes or str, got %s", +// Py_TYPE(obj)->tp_name); +// return 0; +// } + +// /* Function versions of the 3 functions for testing whether curses has been +// initialised or not. */ + +// static int func_PyCursesSetupTermCalled(void) +// { +// PyCursesSetupTermCalled; +// return 1; +// } + +// static int func_PyCursesInitialised(void) +// { +// PyCursesInitialised; +// return 1; +// } + +// static int func_PyCursesInitialisedColor(void) +// { +// PyCursesInitialisedColor; +// return 1; +// } + +// /***************************************************************************** +// The Window Object +// ******************************************************************************/ + +// /* Definition of the window type */ + +// PyTypeObject PyCursesWindow_Type; + +// /* Function prototype macros for Window object + +// X - function name +// TYPE - parameter Type +// ERGSTR - format string for construction of the return value +// PARSESTR - format string for argument parsing +// */ + +// #define Window_NoArgNoReturnFunction(X) \ +// static PyObject *PyCursesWindow_ ## X \ +// (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ +// { return PyCursesCheckERR(X(self->win), # X); } + +// #define Window_NoArgTrueFalseFunction(X) \ +// static PyObject * PyCursesWindow_ ## X \ +// (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ +// { \ +// return PyBool_FromLong(X(self->win)); } + +// #define Window_NoArgNoReturnVoidFunction(X) \ +// static PyObject * PyCursesWindow_ ## X \ +// (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ +// { \ +// X(self->win); Py_RETURN_NONE; } + +// #define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR) \ +// static PyObject * PyCursesWindow_ ## X \ +// (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \ +// { \ +// TYPE arg1, arg2; \ +// X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); } + +// #define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR) \ +// static PyObject * PyCursesWindow_ ## X \ +// (PyCursesWindowObject *self, PyObject *args) \ +// { \ +// TYPE arg1; \ +// if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL; \ +// X(self->win,arg1); Py_RETURN_NONE; } + +// #define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR) \ +// static PyObject * PyCursesWindow_ ## X \ +// (PyCursesWindowObject *self, PyObject *args) \ +// { \ +// TYPE arg1; \ +// if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL; \ +// return PyCursesCheckERR(X(self->win, arg1), # X); } + +// #define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ +// static PyObject * PyCursesWindow_ ## X \ +// (PyCursesWindowObject *self, PyObject *args) \ +// { \ +// TYPE arg1, arg2; \ +// if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \ +// return PyCursesCheckERR(X(self->win, arg1, arg2), # X); } + +// /* ------------- WINDOW routines --------------- */ + +// Window_NoArgNoReturnFunction(untouchwin) +// Window_NoArgNoReturnFunction(touchwin) +// Window_NoArgNoReturnFunction(redrawwin) +// Window_NoArgNoReturnFunction(winsertln) +// Window_NoArgNoReturnFunction(werase) +// Window_NoArgNoReturnFunction(wdeleteln) + +// Window_NoArgTrueFalseFunction(is_wintouched) + +// Window_NoArgNoReturnVoidFunction(wsyncup) +// Window_NoArgNoReturnVoidFunction(wsyncdown) +// Window_NoArgNoReturnVoidFunction(wstandend) +// Window_NoArgNoReturnVoidFunction(wstandout) +// Window_NoArgNoReturnVoidFunction(wcursyncup) +// Window_NoArgNoReturnVoidFunction(wclrtoeol) +// Window_NoArgNoReturnVoidFunction(wclrtobot) +// Window_NoArgNoReturnVoidFunction(wclear) + +// Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)") +// #ifdef HAVE_CURSES_IMMEDOK +// Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)") +// #endif +// Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay") + +// Window_NoArg2TupleReturnFunction(getyx, int, "ii") +// Window_NoArg2TupleReturnFunction(getbegyx, int, "ii") +// Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii") +// Window_NoArg2TupleReturnFunction(getparyx, int, "ii") + +// Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)") +// Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)") +// Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)") +// Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)") +// Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)") +// Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)") +// Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)") +// Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines") +// #ifdef HAVE_CURSES_SYNCOK +// Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)") +// #endif + +// Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x") +// Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x") +// Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x") +// #ifndef STRICT_SYSV_CURSES +// Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns") +// #endif + +// /* Allocation and deallocation of Window Objects */ + +// static PyObject * +// PyCursesWindow_New(WINDOW *win, const char *encoding) +// { +// PyCursesWindowObject *wo; + +// if (encoding == NULL) { +// #if defined(MS_WINDOWS) +// char *buffer[100]; +// UINT cp; +// cp = GetConsoleOutputCP(); +// if (cp != 0) { +// PyOS_snprintf(buffer, sizeof(buffer), "cp%u", cp); +// encoding = buffer; +// } +// #elif defined(CODESET) +// const char *codeset = nl_langinfo(CODESET); +// if (codeset != NULL && codeset[0] != 0) +// encoding = codeset; +// #endif +// if (encoding == NULL) +// encoding = "utf-8"; +// } + +// wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type); +// if (wo == NULL) return NULL; +// wo->win = win; +// wo->encoding = _PyMem_Strdup(encoding); +// if (wo->encoding == NULL) { +// Py_DECREF(wo); +// PyErr_NoMemory(); +// return NULL; +// } +// return (PyObject *)wo; +// } + +// static void +// PyCursesWindow_Dealloc(PyCursesWindowObject *wo) +// { +// if (wo->win != stdscr) delwin(wo->win); +// if (wo->encoding != NULL) +// PyMem_Free(wo->encoding); +// PyObject_DEL(wo); +// } + +// /* Addch, Addstr, Addnstr */ + +// /*[clinic input] +// _curses.window.addch + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] + +// ch: object +// Character to add. + +// [ +// attr: long(c_default="A_NORMAL") = _curses.A_NORMAL +// Attributes for the character. +// ] +// / + +// Paint the character. + +// Paint character ch at (y, x) with attributes attr, +// overwriting any character previously painted at that location. +// By default, the character position and attributes are the +// current settings for the window object. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *ch, int group_right_1, +// long attr) +// /*[clinic end generated code: output=00f4c37af3378f45 input=95ce131578458196]*/ +// { +// int coordinates_group = group_left_1; +// int rtn; +// int type; +// chtype cch = 0; +// #ifdef HAVE_NCURSESW +// wchar_t wstr[2]; +// cchar_t wcval; +// #endif +// const char *funcname; + +// #ifdef HAVE_NCURSESW +// type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr); +// if (type == 2) { +// funcname = "add_wch"; +// wstr[1] = L'\0'; +// setcchar(&wcval, wstr, attr, PAIR_NUMBER(attr), NULL); +// if (coordinates_group) +// rtn = mvwadd_wch(self->win,y,x, &wcval); +// else { +// rtn = wadd_wch(self->win, &wcval); +// } +// } +// else +// #else +// type = PyCurses_ConvertToCchar_t(self, ch, &cch); +// #endif +// if (type == 1) { +// funcname = "addch"; +// if (coordinates_group) +// rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr); +// else { +// rtn = waddch(self->win, cch | (attr_t) attr); +// } +// } +// else { +// return NULL; +// } +// return PyCursesCheckERR(rtn, funcname); +// } + +// /*[clinic input] +// _curses.window.addstr + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] + +// str: object +// String to add. + +// [ +// attr: long +// Attributes for characters. +// ] +// / + +// Paint the string. + +// Paint the string str at (y, x) with attributes attr, +// overwriting anything previously on the display. +// By default, the character position and attributes are the +// current settings for the window object. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *str, int group_right_1, +// long attr) +// /*[clinic end generated code: output=65a928ea85ff3115 input=ff6cbb91448a22a3]*/ +// { +// int rtn; +// int strtype; +// PyObject *bytesobj = NULL; +// #ifdef HAVE_NCURSESW +// wchar_t *wstr = NULL; +// #endif +// attr_t attr_old = A_NORMAL; +// int use_xy = group_left_1, use_attr = group_right_1; +// const char *funcname; + +// #ifdef HAVE_NCURSESW +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); +// #else +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); +// #endif +// if (strtype == 0) { +// return NULL; +// } +// if (use_attr) { +// attr_old = getattrs(self->win); +// (void)wattrset(self->win,attr); +// } +// #ifdef HAVE_NCURSESW +// if (strtype == 2) { +// funcname = "addwstr"; +// if (use_xy) +// rtn = mvwaddwstr(self->win,y,x,wstr); +// else +// rtn = waddwstr(self->win,wstr); +// PyMem_Free(wstr); +// } +// else +// #endif +// { +// char *str = PyBytes_AS_STRING(bytesobj); +// funcname = "addstr"; +// if (use_xy) +// rtn = mvwaddstr(self->win,y,x,str); +// else +// rtn = waddstr(self->win,str); +// Py_DECREF(bytesobj); +// } +// if (use_attr) +// (void)wattrset(self->win,attr_old); +// return PyCursesCheckERR(rtn, funcname); +// } + +// /*[clinic input] +// _curses.window.addnstr + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] + +// str: object +// String to add. + +// n: int +// Maximal number of characters. + +// [ +// attr: long +// Attributes for characters. +// ] +// / + +// Paint at most n characters of the string. + +// Paint at most n characters of the string str at (y, x) with +// attributes attr, overwriting anything previously on the display. +// By default, the character position and attributes are the +// current settings for the window object. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *str, int n, +// int group_right_1, long attr) +// /*[clinic end generated code: output=6d21cee2ce6876d9 input=72718415c2744a2a]*/ +// { +// int rtn; +// int strtype; +// PyObject *bytesobj = NULL; +// #ifdef HAVE_NCURSESW +// wchar_t *wstr = NULL; +// #endif +// attr_t attr_old = A_NORMAL; +// int use_xy = group_left_1, use_attr = group_right_1; +// const char *funcname; + +// #ifdef HAVE_NCURSESW +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); +// #else +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); +// #endif +// if (strtype == 0) +// return NULL; + +// if (use_attr) { +// attr_old = getattrs(self->win); +// (void)wattrset(self->win,attr); +// } +// #ifdef HAVE_NCURSESW +// if (strtype == 2) { +// funcname = "addnwstr"; +// if (use_xy) +// rtn = mvwaddnwstr(self->win,y,x,wstr,n); +// else +// rtn = waddnwstr(self->win,wstr,n); +// PyMem_Free(wstr); +// } +// else +// #endif +// { +// char *str = PyBytes_AS_STRING(bytesobj); +// funcname = "addnstr"; +// if (use_xy) +// rtn = mvwaddnstr(self->win,y,x,str,n); +// else +// rtn = waddnstr(self->win,str,n); +// Py_DECREF(bytesobj); +// } +// if (use_attr) +// (void)wattrset(self->win,attr_old); +// return PyCursesCheckERR(rtn, funcname); +// } + +// /*[clinic input] +// _curses.window.bkgd + +// ch: object +// Background character. +// attr: long(c_default="A_NORMAL") = _curses.A_NORMAL +// Background attributes. +// / + +// Set the background property of the window. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr) +// /*[clinic end generated code: output=058290afb2cf4034 input=634015bcb339283d]*/ +// { +// chtype bkgd; + +// if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) +// return NULL; + +// return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd"); +// } + +// /*[clinic input] +// _curses.window.attroff + +// attr: long +// / + +// Remove attribute attr from the "background" set. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_attroff_impl(PyCursesWindowObject *self, long attr) +// /*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/ +// { +// return PyCursesCheckERR(wattroff(self->win, (attr_t)attr), "attroff"); +// } + +// /*[clinic input] +// _curses.window.attron + +// attr: long +// / + +// Add attribute attr from the "background" set. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_attron_impl(PyCursesWindowObject *self, long attr) +// /*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/ +// { +// return PyCursesCheckERR(wattron(self->win, (attr_t)attr), "attron"); +// } + +// /*[clinic input] +// _curses.window.attrset + +// attr: long +// / + +// Set the "background" set of attributes. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_attrset_impl(PyCursesWindowObject *self, long attr) +// /*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/ +// { +// return PyCursesCheckERR(wattrset(self->win, (attr_t)attr), "attrset"); +// } + +// /*[clinic input] +// _curses.window.bkgdset + +// ch: object +// Background character. +// attr: long(c_default="A_NORMAL") = _curses.A_NORMAL +// Background attributes. +// / + +// Set the window's background. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, +// long attr) +// /*[clinic end generated code: output=8cb994fc4d7e2496 input=e09c682425c9e45b]*/ +// { +// chtype bkgd; + +// if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) +// return NULL; + +// wbkgdset(self->win, bkgd | attr); +// return PyCursesCheckERR(0, "bkgdset"); +// } + +// /*[clinic input] +// _curses.window.border + +// ls: object(c_default="NULL") = _curses.ACS_VLINE +// Left side. +// rs: object(c_default="NULL") = _curses.ACS_VLINE +// Right side. +// ts: object(c_default="NULL") = _curses.ACS_HLINE +// Top side. +// bs: object(c_default="NULL") = _curses.ACS_HLINE +// Bottom side. +// tl: object(c_default="NULL") = _curses.ACS_ULCORNER +// Upper-left corner. +// tr: object(c_default="NULL") = _curses.ACS_URCORNER +// Upper-right corner. +// bl: object(c_default="NULL") = _curses.ACS_LLCORNER +// Bottom-left corner. +// br: object(c_default="NULL") = _curses.ACS_LRCORNER +// Bottom-right corner. +// / + +// Draw a border around the edges of the window. + +// Each parameter specifies the character to use for a specific part of the +// border. The characters can be specified as integers or as one-character +// strings. A 0 value for any parameter will cause the default character to be +// used for that parameter. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, +// PyObject *rs, PyObject *ts, PyObject *bs, +// PyObject *tl, PyObject *tr, PyObject *bl, +// PyObject *br) +// /*[clinic end generated code: output=670ef38d3d7c2aa3 input=e015f735d67a240b]*/ +// { +// chtype ch[8]; +// int i; + +// /* Clear the array of parameters */ +// for(i=0; i<8; i++) +// ch[i] = 0; + +// #define CONVERTTOCHTYPE(obj, i) \ +// if ((obj) != NULL && !PyCurses_ConvertToChtype(self, (obj), &ch[(i)])) \ +// return NULL; + +// CONVERTTOCHTYPE(ls, 0); +// CONVERTTOCHTYPE(rs, 1); +// CONVERTTOCHTYPE(ts, 2); +// CONVERTTOCHTYPE(bs, 3); +// CONVERTTOCHTYPE(tl, 4); +// CONVERTTOCHTYPE(tr, 5); +// CONVERTTOCHTYPE(bl, 6); +// CONVERTTOCHTYPE(br, 7); + +// #undef CONVERTTOCHTYPE + +// wborder(self->win, +// ch[0], ch[1], ch[2], ch[3], +// ch[4], ch[5], ch[6], ch[7]); +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _curses.window.box + +// [ +// verch: object(c_default="_PyLong_Zero") = 0 +// Left and right side. +// horch: object(c_default="_PyLong_Zero") = 0 +// Top and bottom side. +// ] +// / + +// Draw a border around the edges of the window. + +// Similar to border(), but both ls and rs are verch and both ts and bs are +// horch. The default corner characters are always used by this function. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, +// PyObject *verch, PyObject *horch) +// /*[clinic end generated code: output=f3fcb038bb287192 input=465a121741c1efdf]*/ +// { +// chtype ch1 = 0, ch2 = 0; +// if (group_right_1) { +// if (!PyCurses_ConvertToChtype(self, verch, &ch1)) { +// return NULL; +// } +// if (!PyCurses_ConvertToChtype(self, horch, &ch2)) { +// return NULL; +// } +// } +// box(self->win,ch1,ch2); +// Py_RETURN_NONE; +// } + +// #if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION) +// #define py_mvwdelch mvwdelch +// #else +// int py_mvwdelch(WINDOW *w, int y, int x) +// { +// mvwdelch(w,y,x); +// /* On HP/UX, mvwdelch already returns. On other systems, +// we may well run into this return statement. */ +// return 0; +// } +// #endif + +// #if defined(HAVE_CURSES_IS_PAD) +// #define py_is_pad(win) is_pad(win) +// #elif defined(WINDOW_HAS_FLAGS) +// #define py_is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE) +// #endif + +// /* chgat, added by Fabian Kreutz */ +// #ifdef HAVE_CURSES_WCHGAT +// /*[-clinic input] +// _curses.window.chgat + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] + +// n: int = -1 +// Number of characters. + +// attr: long +// Attributes for characters. +// / + +// Set the attributes of characters. + +// Set the attributes of num characters at the current cursor position, or at +// position (y, x) if supplied. If no value of num is given or num = -1, the +// attribute will be set on all the characters to the end of the line. This +// function does not move the cursor. The changed line will be touched using +// the touchline() method so that the contents will be redisplayed by the next +// window refresh. +// [-clinic start generated code]*/ +// static PyObject * +// PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) +// { +// int rtn; +// int x, y; +// int num = -1; +// short color; +// attr_t attr = A_NORMAL; +// long lattr; +// int use_xy = FALSE; + +// switch (PyTuple_Size(args)) { +// case 1: +// if (!PyArg_ParseTuple(args,"l;attr", &lattr)) +// return NULL; +// attr = lattr; +// break; +// case 2: +// if (!PyArg_ParseTuple(args,"il;n,attr", &num, &lattr)) +// return NULL; +// attr = lattr; +// break; +// case 3: +// if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &lattr)) +// return NULL; +// attr = lattr; +// use_xy = TRUE; +// break; +// case 4: +// if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &lattr)) +// return NULL; +// attr = lattr; +// use_xy = TRUE; +// break; +// default: +// PyErr_SetString(PyExc_TypeError, "chgat requires 1 to 4 arguments"); +// return NULL; +// } + +// color = (short)((attr >> 8) & 0xff); +// attr = attr - (color << 8); + +// if (use_xy) { +// rtn = mvwchgat(self->win,y,x,num,attr,color,NULL); +// touchline(self->win,y,1); +// } else { +// getyx(self->win,y,x); +// rtn = wchgat(self->win,num,attr,color,NULL); +// touchline(self->win,y,1); +// } +// return PyCursesCheckERR(rtn, "chgat"); +// } +// #endif + +// /*[clinic input] +// _curses.window.delch + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] +// / + +// Delete any character at (y, x). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, +// int y, int x) +// /*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/ +// { +// if (!group_right_1) { +// return PyCursesCheckERR(wdelch(self->win), "wdelch"); +// } +// else { +// return PyCursesCheckERR(py_mvwdelch(self->win, y, x), "mvwdelch"); +// } +// } + +// /*[clinic input] +// _curses.window.derwin + +// [ +// nlines: int = 0 +// Height. +// ncols: int = 0 +// Width. +// ] +// begin_y: int +// Top side y-coordinate. +// begin_x: int +// Left side x-coordinate. +// / + +// Create a sub-window (window-relative coordinates). + +// derwin() is the same as calling subwin(), except that begin_y and begin_x +// are relative to the origin of the window, rather than relative to the entire +// screen. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, +// int nlines, int ncols, int begin_y, int begin_x) +// /*[clinic end generated code: output=7924b112d9f70d6e input=966d9481f7f5022e]*/ +// { +// WINDOW *win; + +// win = derwin(self->win,nlines,ncols,begin_y,begin_x); + +// if (win == NULL) { +// PyErr_SetString(PyCursesError, catchall_NULL); +// return NULL; +// } + +// return (PyObject *)PyCursesWindow_New(win, NULL); +// } + +// /*[clinic input] +// _curses.window.echochar + +// ch: object +// Character to add. + +// attr: long(c_default="A_NORMAL") = _curses.A_NORMAL +// Attributes for the character. +// / + +// Add character ch with attribute attr, and refresh. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, +// long attr) +// /*[clinic end generated code: output=13e7dd875d4b9642 input=e7f34b964e92b156]*/ +// { +// chtype ch_; + +// if (!PyCurses_ConvertToChtype(self, ch, &ch_)) +// return NULL; + +// #ifdef py_is_pad +// if (py_is_pad(self->win)) { +// return PyCursesCheckERR(pechochar(self->win, ch_ | (attr_t)attr), +// "echochar"); +// } +// else +// #endif +// return PyCursesCheckERR(wechochar(self->win, ch_ | (attr_t)attr), +// "echochar"); +// } + +// #ifdef NCURSES_MOUSE_VERSION +// /*[clinic input] +// _curses.window.enclose -> long + +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// / + +// Return True if the screen-relative coordinates are enclosed by the window. +// [clinic start generated code]*/ + +// static long +// _curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x) +// /*[clinic end generated code: output=5251c961cbe3df63 input=dfe1d9d4d05d8642]*/ +// { +// return wenclose(self->win, y, x); +// } +// #endif + +// /*[clinic input] +// _curses.window.getbkgd -> long + +// Return the window's current background character/attribute pair. +// [clinic start generated code]*/ + +// static long +// _curses_window_getbkgd_impl(PyCursesWindowObject *self) +// /*[clinic end generated code: output=c52b25dc16b215c3 input=a69db882fa35426c]*/ +// { +// return (long) getbkgd(self->win); +// } + +// /*[clinic input] +// _curses.window.getch -> int + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] +// / + +// Get a character code from terminal keyboard. + +// The integer returned does not have to be in ASCII range: function keys, +// keypad keys and so on return numbers higher than 256. In no-delay mode, -1 +// is returned if there is no input, else getch() waits until a key is pressed. +// [clinic start generated code]*/ + +// static int +// _curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1, +// int y, int x) +// /*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/ +// { +// int rtn; + +// Py_BEGIN_ALLOW_THREADS +// if (!group_right_1) { +// rtn = wgetch(self->win); +// } +// else { +// rtn = mvwgetch(self->win, y, x); +// } +// Py_END_ALLOW_THREADS + +// return rtn; +// } + +// /*[clinic input] +// _curses.window.getkey + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] +// / + +// Get a character (string) from terminal keyboard. + +// Returning a string instead of an integer, as getch() does. Function keys, +// keypad keys and other special keys return a multibyte string containing the +// key name. In no-delay mode, an exception is raised if there is no input. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, +// int y, int x) +// /*[clinic end generated code: output=8490a182db46b10f input=be2dee34f5cf57f8]*/ +// { +// int rtn; + +// Py_BEGIN_ALLOW_THREADS +// if (!group_right_1) { +// rtn = wgetch(self->win); +// } +// else { +// rtn = mvwgetch(self->win, y, x); +// } +// Py_END_ALLOW_THREADS + +// if (rtn == ERR) { +// /* getch() returns ERR in nodelay mode */ +// PyErr_CheckSignals(); +// if (!PyErr_Occurred()) +// PyErr_SetString(PyCursesError, "no input"); +// return NULL; +// } else if (rtn <= 255) { +// #ifdef NCURSES_VERSION_MAJOR +// #if NCURSES_VERSION_MAJOR*100+NCURSES_VERSION_MINOR <= 507 +// /* Work around a bug in ncurses 5.7 and earlier */ +// if (rtn < 0) { +// rtn += 256; +// } +// #endif +// #endif +// return PyUnicode_FromOrdinal(rtn); +// } else { +// const char *knp = keyname(rtn); +// return PyUnicode_FromString((knp == NULL) ? "" : knp); +// } +// } + +// #ifdef HAVE_NCURSESW +// /*[clinic input] +// _curses.window.get_wch + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] +// / + +// Get a wide character from terminal keyboard. + +// Return a character for most keys, or an integer for function keys, +// keypad keys, and other special keys. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, +// int y, int x) +// /*[clinic end generated code: output=9f4f86e91fe50ef3 input=dd7e5367fb49dc48]*/ +// { +// int ct; +// wint_t rtn; + +// Py_BEGIN_ALLOW_THREADS +// if (!group_right_1) { +// ct = wget_wch(self->win ,&rtn); +// } +// else { +// ct = mvwget_wch(self->win, y, x, &rtn); +// } +// Py_END_ALLOW_THREADS + +// if (ct == ERR) { +// if (PyErr_CheckSignals()) +// return NULL; + +// /* get_wch() returns ERR in nodelay mode */ +// PyErr_SetString(PyCursesError, "no input"); +// return NULL; +// } +// if (ct == KEY_CODE_YES) +// return PyLong_FromLong(rtn); +// else +// return PyUnicode_FromOrdinal(rtn); +// } +// #endif + +// /*[-clinic input] +// _curses.window.getstr + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] +// n: int = 1023 +// Maximal number of characters. +// / + +// Read a string from the user, with primitive line editing capacity. +// [-clinic start generated code]*/ + +// static PyObject * +// PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args) +// { +// int x, y, n; +// char rtn[1024]; /* This should be big enough.. I hope */ +// int rtn2; + +// switch (PyTuple_Size(args)) { +// case 0: +// Py_BEGIN_ALLOW_THREADS +// rtn2 = wgetnstr(self->win,rtn, 1023); +// Py_END_ALLOW_THREADS +// break; +// case 1: +// if (!PyArg_ParseTuple(args,"i;n", &n)) +// return NULL; +// if (n < 0) { +// PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); +// return NULL; +// } +// Py_BEGIN_ALLOW_THREADS +// rtn2 = wgetnstr(self->win, rtn, Py_MIN(n, 1023)); +// Py_END_ALLOW_THREADS +// break; +// case 2: +// if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) +// return NULL; +// Py_BEGIN_ALLOW_THREADS +// #ifdef STRICT_SYSV_CURSES +// rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023); +// #else +// rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023); +// #endif +// Py_END_ALLOW_THREADS +// break; +// case 3: +// if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n)) +// return NULL; +// if (n < 0) { +// PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); +// return NULL; +// } +// #ifdef STRICT_SYSV_CURSES +// Py_BEGIN_ALLOW_THREADS +// rtn2 = wmove(self->win,y,x)==ERR ? ERR : +// wgetnstr(self->win, rtn, Py_MIN(n, 1023)); +// Py_END_ALLOW_THREADS +// #else +// Py_BEGIN_ALLOW_THREADS +// rtn2 = mvwgetnstr(self->win, y, x, rtn, Py_MIN(n, 1023)); +// Py_END_ALLOW_THREADS +// #endif +// break; +// default: +// PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments"); +// return NULL; +// } +// if (rtn2 == ERR) +// rtn[0] = 0; +// return PyBytes_FromString(rtn); +// } + +// /*[clinic input] +// _curses.window.hline + +// [ +// y: int +// Starting Y-coordinate. +// x: int +// Starting X-coordinate. +// ] + +// ch: object +// Character to draw. +// n: int +// Line length. + +// [ +// attr: long(c_default="A_NORMAL") = _curses.A_NORMAL +// Attributes for the characters. +// ] +// / + +// Display a horizontal line. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *ch, int n, +// int group_right_1, long attr) +// /*[clinic end generated code: output=c00d489d61fc9eef input=81a4dea47268163e]*/ +// { +// chtype ch_; + +// if (!PyCurses_ConvertToChtype(self, ch, &ch_)) +// return NULL; +// if (group_left_1) { +// if (wmove(self->win, y, x) == ERR) { +// return PyCursesCheckERR(ERR, "wmove"); +// } +// } +// return PyCursesCheckERR(whline(self->win, ch_ | (attr_t)attr, n), "hline"); +// } + +// /*[clinic input] +// _curses.window.insch + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] + +// ch: object +// Character to insert. + +// [ +// attr: long(c_default="A_NORMAL") = _curses.A_NORMAL +// Attributes for the character. +// ] +// / + +// Insert a character before the current or specified position. + +// All characters to the right of the cursor are shifted one position right, with +// the rightmost characters on the line being lost. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *ch, int group_right_1, +// long attr) +// /*[clinic end generated code: output=ade8cfe3a3bf3e34 input=336342756ee19812]*/ +// { +// int rtn; +// chtype ch_ = 0; + +// if (!PyCurses_ConvertToChtype(self, ch, &ch_)) +// return NULL; + +// if (!group_left_1) { +// rtn = winsch(self->win, ch_ | (attr_t)attr); +// } +// else { +// rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr); +// } + +// return PyCursesCheckERR(rtn, "insch"); +// } + +// /*[clinic input] +// _curses.window.inch -> unsigned_long + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] +// / + +// Return the character at the given position in the window. + +// The bottom 8 bits are the character proper, and upper bits are the attributes. +// [clinic start generated code]*/ + +// static unsigned long +// _curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1, +// int y, int x) +// /*[clinic end generated code: output=6c4719fe978fe86a input=fac23ee11e3b3a66]*/ +// { +// unsigned long rtn; + +// if (!group_right_1) { +// rtn = winch(self->win); +// } +// else { +// rtn = mvwinch(self->win, y, x); +// } + +// return rtn; +// } + +// /*[-clinic input] +// _curses.window.instr + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] +// n: int = 1023 +// Maximal number of characters. +// / + +// Return a string of characters, extracted from the window. + +// Return a string of characters, extracted from the window starting at the +// current cursor position, or at y, x if specified. Attributes are stripped +// from the characters. If n is specified, instr() returns a string at most +// n characters long (exclusive of the trailing NUL). +// [-clinic start generated code]*/ +// static PyObject * +// PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args) +// { +// int x, y, n; +// char rtn[1024]; /* This should be big enough.. I hope */ +// int rtn2; + +// switch (PyTuple_Size(args)) { +// case 0: +// rtn2 = winnstr(self->win,rtn, 1023); +// break; +// case 1: +// if (!PyArg_ParseTuple(args,"i;n", &n)) +// return NULL; +// if (n < 0) { +// PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); +// return NULL; +// } +// rtn2 = winnstr(self->win, rtn, Py_MIN(n, 1023)); +// break; +// case 2: +// if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) +// return NULL; +// rtn2 = mvwinnstr(self->win,y,x,rtn,1023); +// break; +// case 3: +// if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n)) +// return NULL; +// if (n < 0) { +// PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); +// return NULL; +// } +// rtn2 = mvwinnstr(self->win, y, x, rtn, Py_MIN(n,1023)); +// break; +// default: +// PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments"); +// return NULL; +// } +// if (rtn2 == ERR) +// rtn[0] = 0; +// return PyBytes_FromString(rtn); +// } + +// /*[clinic input] +// _curses.window.insstr + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] + +// str: object +// String to insert. + +// [ +// attr: long +// Attributes for characters. +// ] +// / + +// Insert the string before the current or specified position. + +// Insert a character string (as many characters as will fit on the line) +// before the character under the cursor. All characters to the right of +// the cursor are shifted right, with the rightmost characters on the line +// being lost. The cursor position does not change (after moving to y, x, +// if specified). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *str, int group_right_1, +// long attr) +// /*[clinic end generated code: output=c259a5265ad0b777 input=6827cddc6340a7f3]*/ +// { +// int rtn; +// int strtype; +// PyObject *bytesobj = NULL; +// #ifdef HAVE_NCURSESW +// wchar_t *wstr = NULL; +// #endif +// attr_t attr_old = A_NORMAL; +// int use_xy = group_left_1, use_attr = group_right_1; +// const char *funcname; + +// #ifdef HAVE_NCURSESW +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); +// #else +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); +// #endif +// if (strtype == 0) +// return NULL; + +// if (use_attr) { +// attr_old = getattrs(self->win); +// (void)wattrset(self->win, (attr_t)attr); +// } +// #ifdef HAVE_NCURSESW +// if (strtype == 2) { +// funcname = "inswstr"; +// if (use_xy) +// rtn = mvwins_wstr(self->win,y,x,wstr); +// else +// rtn = wins_wstr(self->win,wstr); +// PyMem_Free(wstr); +// } +// else +// #endif +// { +// char *str = PyBytes_AS_STRING(bytesobj); +// funcname = "insstr"; +// if (use_xy) +// rtn = mvwinsstr(self->win,y,x,str); +// else +// rtn = winsstr(self->win,str); +// Py_DECREF(bytesobj); +// } +// if (use_attr) +// (void)wattrset(self->win,attr_old); +// return PyCursesCheckERR(rtn, funcname); +// } + +// /*[clinic input] +// _curses.window.insnstr + +// [ +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// ] + +// str: object +// String to insert. + +// n: int +// Maximal number of characters. + +// [ +// attr: long +// Attributes for characters. +// ] +// / + +// Insert at most n characters of the string. + +// Insert a character string (as many characters as will fit on the line) +// before the character under the cursor, up to n characters. If n is zero +// or negative, the entire string is inserted. All characters to the right +// of the cursor are shifted right, with the rightmost characters on the line +// being lost. The cursor position does not change (after moving to y, x, if +// specified). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *str, int n, +// int group_right_1, long attr) +// /*[clinic end generated code: output=971a32ea6328ec8b input=70fa0cd543901a4c]*/ +// { +// int rtn; +// int strtype; +// PyObject *bytesobj = NULL; +// #ifdef HAVE_NCURSESW +// wchar_t *wstr = NULL; +// #endif +// attr_t attr_old = A_NORMAL; +// int use_xy = group_left_1, use_attr = group_right_1; +// const char *funcname; + +// #ifdef HAVE_NCURSESW +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); +// #else +// strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); +// #endif +// if (strtype == 0) +// return NULL; + +// if (use_attr) { +// attr_old = getattrs(self->win); +// (void)wattrset(self->win, (attr_t)attr); +// } +// #ifdef HAVE_NCURSESW +// if (strtype == 2) { +// funcname = "insn_wstr"; +// if (use_xy) +// rtn = mvwins_nwstr(self->win,y,x,wstr,n); +// else +// rtn = wins_nwstr(self->win,wstr,n); +// PyMem_Free(wstr); +// } +// else +// #endif +// { +// char *str = PyBytes_AS_STRING(bytesobj); +// funcname = "insnstr"; +// if (use_xy) +// rtn = mvwinsnstr(self->win,y,x,str,n); +// else +// rtn = winsnstr(self->win,str,n); +// Py_DECREF(bytesobj); +// } +// if (use_attr) +// (void)wattrset(self->win,attr_old); +// return PyCursesCheckERR(rtn, funcname); +// } + +// /*[clinic input] +// _curses.window.is_linetouched + +// line: int +// Line number. +// / + +// Return True if the specified line was modified, otherwise return False. + +// Raise a curses.error exception if line is not valid for the given window. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line) +// /*[clinic end generated code: output=ad4a4edfee2db08c input=a7be0c189f243914]*/ +// { +// int erg; +// erg = is_linetouched(self->win, line); +// if (erg == ERR) { +// PyErr_SetString(PyExc_TypeError, +// "is_linetouched: line number outside of boundaries"); +// return NULL; +// } +// return PyBool_FromLong(erg); +// } + +// #ifdef py_is_pad +// /*[clinic input] +// _curses.window.noutrefresh + +// [ +// pminrow: int +// pmincol: int +// sminrow: int +// smincol: int +// smaxrow: int +// smaxcol: int +// ] +// / + +// Mark for refresh but wait. + +// This function updates the data structure representing the desired state of the +// window, but does not force an update of the physical screen. To accomplish +// that, call doupdate(). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_noutrefresh_impl(PyCursesWindowObject *self, +// int group_right_1, int pminrow, int pmincol, +// int sminrow, int smincol, int smaxrow, +// int smaxcol) +// /*[clinic end generated code: output=809a1f3c6a03e23e input=3e56898388cd739e]*/ +// #else +// /*[clinic input] +// _curses.window.noutrefresh + +// Mark for refresh but wait. + +// This function updates the data structure representing the desired state of the +// window, but does not force an update of the physical screen. To accomplish +// that, call doupdate(). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_noutrefresh_impl(PyCursesWindowObject *self) +// /*[clinic end generated code: output=6ef6dec666643fee input=876902e3fa431dbd]*/ +// #endif +// { +// int rtn; + +// #ifdef py_is_pad +// if (py_is_pad(self->win)) { +// if (!group_right_1) { +// PyErr_SetString(PyCursesError, +// "noutrefresh() called for a pad " +// "requires 6 arguments"); +// return NULL; +// } +// Py_BEGIN_ALLOW_THREADS +// rtn = pnoutrefresh(self->win, pminrow, pmincol, +// sminrow, smincol, smaxrow, smaxcol); +// Py_END_ALLOW_THREADS +// return PyCursesCheckERR(rtn, "pnoutrefresh"); +// } +// if (group_right_1) { +// PyErr_SetString(PyExc_TypeError, +// "noutrefresh() takes no arguments (6 given)"); +// return NULL; +// } +// #endif +// Py_BEGIN_ALLOW_THREADS +// rtn = wnoutrefresh(self->win); +// Py_END_ALLOW_THREADS +// return PyCursesCheckERR(rtn, "wnoutrefresh"); +// } + +// /*[clinic input] +// _curses.window.overlay + +// destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + +// [ +// sminrow: int +// smincol: int +// dminrow: int +// dmincol: int +// dmaxrow: int +// dmaxcol: int +// ] +// / + +// Overlay the window on top of destwin. + +// The windows need not be the same size, only the overlapping region is copied. +// This copy is non-destructive, which means that the current background +// character does not overwrite the old contents of destwin. + +// To get fine-grained control over the copied region, the second form of +// overlay() can be used. sminrow and smincol are the upper-left coordinates +// of the source window, and the other variables mark a rectangle in the +// destination window. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_overlay_impl(PyCursesWindowObject *self, +// PyCursesWindowObject *destwin, int group_right_1, +// int sminrow, int smincol, int dminrow, +// int dmincol, int dmaxrow, int dmaxcol) +// /*[clinic end generated code: output=82bb2c4cb443ca58 input=7edd23ad22cc1984]*/ +// { +// int rtn; + +// if (group_right_1) { +// rtn = copywin(self->win, destwin->win, sminrow, smincol, +// dminrow, dmincol, dmaxrow, dmaxcol, TRUE); +// return PyCursesCheckERR(rtn, "copywin"); +// } +// else { +// rtn = overlay(self->win, destwin->win); +// return PyCursesCheckERR(rtn, "overlay"); +// } +// } + +// /*[clinic input] +// _curses.window.overwrite + +// destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + +// [ +// sminrow: int +// smincol: int +// dminrow: int +// dmincol: int +// dmaxrow: int +// dmaxcol: int +// ] +// / + +// Overwrite the window on top of destwin. + +// The windows need not be the same size, in which case only the overlapping +// region is copied. This copy is destructive, which means that the current +// background character overwrites the old contents of destwin. + +// To get fine-grained control over the copied region, the second form of +// overwrite() can be used. sminrow and smincol are the upper-left coordinates +// of the source window, the other variables mark a rectangle in the destination +// window. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_overwrite_impl(PyCursesWindowObject *self, +// PyCursesWindowObject *destwin, +// int group_right_1, int sminrow, int smincol, +// int dminrow, int dmincol, int dmaxrow, +// int dmaxcol) +// /*[clinic end generated code: output=12ae007d1681be28 input=ea5de1b35cd948e0]*/ +// { +// int rtn; + +// if (group_right_1) { +// rtn = copywin(self->win, destwin->win, sminrow, smincol, +// dminrow, dmincol, dmaxrow, dmaxcol, FALSE); +// return PyCursesCheckERR(rtn, "copywin"); +// } +// else { +// rtn = overwrite(self->win, destwin->win); +// return PyCursesCheckERR(rtn, "overwrite"); +// } +// } + +// /*[clinic input] +// _curses.window.putwin + +// file: object +// / + +// Write all data associated with the window into the provided file object. + +// This information can be later retrieved using the getwin() function. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_putwin(PyCursesWindowObject *self, PyObject *file) +// /*[clinic end generated code: output=3a25e2a5e7a040ac input=0608648e09c8ea0a]*/ +// { +// /* We have to simulate this by writing to a temporary FILE*, +// then reading back, then writing to the argument file. */ +// FILE *fp; +// PyObject *res = NULL; + +// fp = tmpfile(); +// if (fp == NULL) +// return PyErr_SetFromErrno(PyExc_OSError); +// if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) +// goto exit; +// res = PyCursesCheckERR(putwin(self->win, fp), "putwin"); +// if (res == NULL) +// goto exit; +// fseek(fp, 0, 0); +// while (1) { +// char buf[BUFSIZ]; +// Py_ssize_t n = fread(buf, 1, BUFSIZ, fp); +// _Py_IDENTIFIER(write); + +// if (n <= 0) +// break; +// Py_DECREF(res); +// res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n); +// if (res == NULL) +// break; +// } + +// exit: +// fclose(fp); +// return res; +// } + +// /*[clinic input] +// _curses.window.redrawln + +// beg: int +// Starting line number. +// num: int +// The number of lines. +// / + +// Mark the specified lines corrupted. + +// They should be completely redrawn on the next refresh() call. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num) +// /*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/ +// { +// return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln"); +// } + +// /*[clinic input] +// _curses.window.refresh + +// [ +// pminrow: int +// pmincol: int +// sminrow: int +// smincol: int +// smaxrow: int +// smaxcol: int +// ] +// / + +// Update the display immediately. + +// Synchronize actual screen with previous drawing/deleting methods. +// The 6 optional arguments can only be specified when the window is a pad +// created with newpad(). The additional parameters are needed to indicate +// what part of the pad and screen are involved. pminrow and pmincol specify +// the upper left-hand corner of the rectangle to be displayed in the pad. +// sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to +// be displayed on the screen. The lower right-hand corner of the rectangle to +// be displayed in the pad is calculated from the screen coordinates, since the +// rectangles must be the same size. Both rectangles must be entirely contained +// within their respective structures. Negative values of pminrow, pmincol, +// sminrow, or smincol are treated as if they were zero. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, +// int pminrow, int pmincol, int sminrow, +// int smincol, int smaxrow, int smaxcol) +// /*[clinic end generated code: output=42199543115e6e63 input=95e01cb5ffc635d0]*/ +// { +// int rtn; + +// #ifdef py_is_pad +// if (py_is_pad(self->win)) { +// if (!group_right_1) { +// PyErr_SetString(PyCursesError, +// "refresh() for a pad requires 6 arguments"); +// return NULL; +// } +// Py_BEGIN_ALLOW_THREADS +// rtn = prefresh(self->win, pminrow, pmincol, +// sminrow, smincol, smaxrow, smaxcol); +// Py_END_ALLOW_THREADS +// return PyCursesCheckERR(rtn, "prefresh"); +// } +// #endif +// if (group_right_1) { +// PyErr_SetString(PyExc_TypeError, +// "refresh() takes no arguments (6 given)"); +// return NULL; +// } +// Py_BEGIN_ALLOW_THREADS +// rtn = wrefresh(self->win); +// Py_END_ALLOW_THREADS +// return PyCursesCheckERR(rtn, "prefresh"); +// } + +// /*[clinic input] +// _curses.window.setscrreg + +// top: int +// First line number. +// bottom: int +// Last line number. +// / + +// Define a software scrolling region. + +// All scrolling actions will take place in this region. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, +// int bottom) +// /*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/ +// { +// return PyCursesCheckERR(wsetscrreg(self->win, top, bottom), "wsetscrreg"); +// } + +// /*[clinic input] +// _curses.window.subwin + +// [ +// nlines: int = 0 +// Height. +// ncols: int = 0 +// Width. +// ] +// begin_y: int +// Top side y-coordinate. +// begin_x: int +// Left side x-coordinate. +// / + +// Create a sub-window (screen-relative coordinates). + +// By default, the sub-window will extend from the specified position to the +// lower right corner of the window. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, +// int nlines, int ncols, int begin_y, int begin_x) +// /*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/ +// { +// WINDOW *win; + +// /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ +// #ifdef py_is_pad +// if (py_is_pad(self->win)) { +// win = subpad(self->win, nlines, ncols, begin_y, begin_x); +// } +// else +// #endif +// win = subwin(self->win, nlines, ncols, begin_y, begin_x); + +// if (win == NULL) { +// PyErr_SetString(PyCursesError, catchall_NULL); +// return NULL; +// } + +// return (PyObject *)PyCursesWindow_New(win, self->encoding); +// } + +// /*[clinic input] +// _curses.window.scroll + +// [ +// lines: int = 1 +// Number of lines to scroll. +// ] +// / + +// Scroll the screen or scrolling region. + +// Scroll upward if the argument is positive and downward if it is negative. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, +// int lines) +// /*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/ +// { +// if (!group_right_1) { +// return PyCursesCheckERR(scroll(self->win), "scroll"); +// } +// else { +// return PyCursesCheckERR(wscrl(self->win, lines), "scroll"); +// } +// } + +// /*[clinic input] +// _curses.window.touchline + +// start: int +// count: int +// [ +// changed: bool(accept={int}) = True +// ] +// / + +// Pretend count lines have been changed, starting with line start. + +// If changed is supplied, it specifies whether the affected lines are marked +// as having been changed (changed=True) or unchanged (changed=False). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_touchline_impl(PyCursesWindowObject *self, int start, +// int count, int group_right_1, int changed) +// /*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/ +// { +// if (!group_right_1) { +// return PyCursesCheckERR(touchline(self->win, start, count), "touchline"); +// } +// else { +// return PyCursesCheckERR(wtouchln(self->win, start, count, changed), "touchline"); +// } +// } + +// /*[clinic input] +// _curses.window.vline + +// [ +// y: int +// Starting Y-coordinate. +// x: int +// Starting X-coordinate. +// ] + +// ch: object +// Character to draw. +// n: int +// Line length. + +// [ +// attr: long(c_default="A_NORMAL") = _curses.A_NORMAL +// Attributes for the character. +// ] +// / + +// Display a vertical line. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, +// int y, int x, PyObject *ch, int n, +// int group_right_1, long attr) +// /*[clinic end generated code: output=287ad1cc8982217f input=a6f2dc86a4648b32]*/ +// { +// chtype ch_; + +// if (!PyCurses_ConvertToChtype(self, ch, &ch_)) +// return NULL; +// if (group_left_1) { +// if (wmove(self->win, y, x) == ERR) +// return PyCursesCheckERR(ERR, "wmove"); +// } +// return PyCursesCheckERR(wvline(self->win, ch_ | (attr_t)attr, n), "vline"); +// } + +// static PyObject * +// PyCursesWindow_get_encoding(PyCursesWindowObject *self, void *closure) +// { +// return PyUnicode_FromString(self->encoding); +// } + +// static int +// PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value, void *Py_UNUSED(ignored)) +// { +// PyObject *ascii; +// char *encoding; + +// /* It is illegal to del win.encoding */ +// if (value == NULL) { +// PyErr_SetString(PyExc_TypeError, +// "encoding may not be deleted"); +// return -1; +// } + +// if (!PyUnicode_Check(value)) { +// PyErr_SetString(PyExc_TypeError, +// "setting encoding to a non-string"); +// return -1; +// } +// ascii = PyUnicode_AsASCIIString(value); +// if (ascii == NULL) +// return -1; +// encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii)); +// Py_DECREF(ascii); +// if (encoding == NULL) { +// PyErr_NoMemory(); +// return -1; +// } +// PyMem_Free(self->encoding); +// self->encoding = encoding; +// return 0; +// } + +// #include "clinic/_cursesmodule.c.h" + +// static PyMethodDef PyCursesWindow_Methods[] = { +// _CURSES_WINDOW_ADDCH_METHODDEF +// _CURSES_WINDOW_ADDNSTR_METHODDEF +// _CURSES_WINDOW_ADDSTR_METHODDEF +// _CURSES_WINDOW_ATTROFF_METHODDEF +// _CURSES_WINDOW_ATTRON_METHODDEF +// _CURSES_WINDOW_ATTRSET_METHODDEF +// _CURSES_WINDOW_BKGD_METHODDEF +// #ifdef HAVE_CURSES_WCHGAT +// {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS}, +// #endif +// _CURSES_WINDOW_BKGDSET_METHODDEF +// _CURSES_WINDOW_BORDER_METHODDEF +// _CURSES_WINDOW_BOX_METHODDEF +// {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS}, +// {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS}, +// {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS}, +// {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS}, +// {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS}, +// _CURSES_WINDOW_DELCH_METHODDEF +// {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS}, +// _CURSES_WINDOW_DERWIN_METHODDEF +// _CURSES_WINDOW_ECHOCHAR_METHODDEF +// _CURSES_WINDOW_ENCLOSE_METHODDEF +// {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS}, +// {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS}, +// _CURSES_WINDOW_GETBKGD_METHODDEF +// _CURSES_WINDOW_GETCH_METHODDEF +// _CURSES_WINDOW_GETKEY_METHODDEF +// _CURSES_WINDOW_GET_WCH_METHODDEF +// {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS}, +// {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS}, +// {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS}, +// {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS}, +// _CURSES_WINDOW_HLINE_METHODDEF +// {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS}, +// {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS}, +// #ifdef HAVE_CURSES_IMMEDOK +// {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS}, +// #endif +// _CURSES_WINDOW_INCH_METHODDEF +// _CURSES_WINDOW_INSCH_METHODDEF +// {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS}, +// {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS}, +// _CURSES_WINDOW_INSNSTR_METHODDEF +// _CURSES_WINDOW_INSSTR_METHODDEF +// {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS}, +// _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF +// {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS}, +// {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS}, +// {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS}, +// {"move", (PyCFunction)PyCursesWindow_wmove, METH_VARARGS}, +// {"mvderwin", (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS}, +// {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS}, +// {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS}, +// {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS}, +// _CURSES_WINDOW_NOUTREFRESH_METHODDEF +// _CURSES_WINDOW_OVERLAY_METHODDEF +// _CURSES_WINDOW_OVERWRITE_METHODDEF +// _CURSES_WINDOW_PUTWIN_METHODDEF +// _CURSES_WINDOW_REDRAWLN_METHODDEF +// {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS}, +// _CURSES_WINDOW_REFRESH_METHODDEF +// #ifndef STRICT_SYSV_CURSES +// {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS}, +// #endif +// _CURSES_WINDOW_SCROLL_METHODDEF +// {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS}, +// _CURSES_WINDOW_SETSCRREG_METHODDEF +// {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS}, +// {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS}, +// {"subpad", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__}, +// _CURSES_WINDOW_SUBWIN_METHODDEF +// {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS}, +// #ifdef HAVE_CURSES_SYNCOK +// {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS}, +// #endif +// {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS}, +// {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS}, +// _CURSES_WINDOW_TOUCHLINE_METHODDEF +// {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS}, +// {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS}, +// _CURSES_WINDOW_VLINE_METHODDEF +// {NULL, NULL} /* sentinel */ +// }; + +// static PyGetSetDef PyCursesWindow_getsets[] = { +// {"encoding", +// (getter)PyCursesWindow_get_encoding, +// (setter)PyCursesWindow_set_encoding, +// "the typecode character used to create the array"}, +// {NULL, NULL, NULL, NULL } /* sentinel */ +// }; + +// /* -------------------------------------------------------*/ + +// PyTypeObject PyCursesWindow_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "_curses.window", /*tp_name*/ +// sizeof(PyCursesWindowObject), /*tp_basicsize*/ +// 0, /*tp_itemsize*/ +// /* methods */ +// (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/ +// 0, /*tp_vectorcall_offset*/ +// (getattrfunc)0, /*tp_getattr*/ +// (setattrfunc)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*/ +// PyCursesWindow_Methods, /*tp_methods*/ +// 0, /* tp_members */ +// PyCursesWindow_getsets, /* tp_getset */ +// }; + +// /* Function Prototype Macros - They are ugly but very, very useful. ;-) + +// X - function name +// TYPE - parameter Type +// ERGSTR - format string for construction of the return value +// PARSESTR - format string for argument parsing +// */ + +// #define NoArgNoReturnFunctionBody(X) \ +// { \ +// PyCursesInitialised \ +// return PyCursesCheckERR(X(), # X); } + +// #define NoArgOrFlagNoReturnFunctionBody(X, flag) \ +// { \ +// PyCursesInitialised \ +// if (flag) \ +// return PyCursesCheckERR(X(), # X); \ +// else \ +// return PyCursesCheckERR(no ## X(), # X); \ +// } + +// #define NoArgReturnIntFunctionBody(X) \ +// { \ +// PyCursesInitialised \ +// return PyLong_FromLong((long) X()); } + + +// #define NoArgReturnStringFunctionBody(X) \ +// { \ +// PyCursesInitialised \ +// return PyBytes_FromString(X()); } + +// #define NoArgTrueFalseFunctionBody(X) \ +// { \ +// PyCursesInitialised \ +// return PyBool_FromLong(X()); } + +// #define NoArgNoReturnVoidFunctionBody(X) \ +// { \ +// PyCursesInitialised \ +// X(); \ +// Py_RETURN_NONE; } + +// /********************************************************************* +// Global Functions +// **********************************************************************/ + +// #ifdef HAVE_CURSES_FILTER +// /*[clinic input] +// _curses.filter + +// [clinic start generated code]*/ + +// static PyObject * +// _curses_filter_impl(PyObject *module) +// /*[clinic end generated code: output=fb5b8a3642eb70b5 input=668c75a6992d3624]*/ +// { +// /* not checking for PyCursesInitialised here since filter() must +// be called before initscr() */ +// filter(); +// Py_RETURN_NONE; +// } +// #endif + +// /*[clinic input] +// _curses.baudrate + +// Return the output speed of the terminal in bits per second. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_baudrate_impl(PyObject *module) +// /*[clinic end generated code: output=3c63c6c401d7d9c0 input=921f022ed04a0fd9]*/ +// NoArgReturnIntFunctionBody(baudrate) + +// /*[clinic input] +// _curses.beep + +// Emit a short attention sound. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_beep_impl(PyObject *module) +// /*[clinic end generated code: output=425274962abe49a2 input=a35698ca7d0162bc]*/ +// NoArgNoReturnFunctionBody(beep) + +// /*[clinic input] +// _curses.can_change_color + +// Return True if the programmer can change the colors displayed by the terminal. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_can_change_color_impl(PyObject *module) +// /*[clinic end generated code: output=359df8c3c77d8bf1 input=d7718884de0092f2]*/ +// NoArgTrueFalseFunctionBody(can_change_color) + +// /*[clinic input] +// _curses.cbreak + +// flag: bool(accept={int}) = True +// If false, the effect is the same as calling nocbreak(). +// / + +// Enter cbreak mode. + +// In cbreak mode (sometimes called "rare" mode) normal tty line buffering is +// turned off and characters are available to be read one by one. However, +// unlike raw mode, special characters (interrupt, quit, suspend, and flow +// control) retain their effects on the tty driver and calling program. +// Calling first raw() then cbreak() leaves the terminal in cbreak mode. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_cbreak_impl(PyObject *module, int flag) +// /*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/ +// NoArgOrFlagNoReturnFunctionBody(cbreak, flag) + +// /*[clinic input] +// _curses.color_content + +// color_number: short +// The number of the color (0 - (COLORS-1)). +// / + +// Return the red, green, and blue (RGB) components of the specified color. + +// A 3-tuple is returned, containing the R, G, B values for the given color, +// which will be between 0 (no component) and 1000 (maximum amount of component). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_color_content_impl(PyObject *module, short color_number) +// /*[clinic end generated code: output=cb15cf3120d4bfc1 input=630f6737514db6ad]*/ +// { +// short r,g,b; + +// PyCursesInitialised; +// PyCursesInitialisedColor; + +// if (color_content(color_number, &r, &g, &b) == ERR) { +// if (color_number >= COLORS) { +// PyErr_SetString(PyCursesError, +// "Argument 1 was out of range. Check value of COLORS."); +// } +// else { +// PyErr_SetString(PyCursesError, "color_content() returned ERR"); +// } +// return NULL; +// } + +// return Py_BuildValue("(iii)", r, g, b); +// } + +// /*[clinic input] +// _curses.color_pair + +// pair_number: short +// The number of the color pair. +// / + +// Return the attribute value for displaying text in the specified color. + +// This attribute value can be combined with A_STANDOUT, A_REVERSE, and the +// other A_* attributes. pair_number() is the counterpart to this function. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_color_pair_impl(PyObject *module, short pair_number) +// /*[clinic end generated code: output=ce609d238b70dc11 input=8dd0d5da94cb15b5]*/ +// { +// PyCursesInitialised; +// PyCursesInitialisedColor; + +// return PyLong_FromLong(COLOR_PAIR(pair_number)); +// } + +// /*[clinic input] +// _curses.curs_set + +// visibility: int +// 0 for invisible, 1 for normal visible, or 2 for very visible. +// / + +// Set the cursor state. + +// If the terminal supports the visibility requested, the previous cursor +// state is returned; otherwise, an exception is raised. On many terminals, +// the "visible" mode is an underline cursor and the "very visible" mode is +// a block cursor. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_curs_set_impl(PyObject *module, int visibility) +// /*[clinic end generated code: output=ee8e62483b1d6cd4 input=81a7924a65d29504]*/ +// { +// int erg; + +// PyCursesInitialised; + +// erg = curs_set(visibility); +// if (erg == ERR) return PyCursesCheckERR(erg, "curs_set"); + +// return PyLong_FromLong((long) erg); +// } + +// /*[clinic input] +// _curses.def_prog_mode + +// Save the current terminal mode as the "program" mode. + +// The "program" mode is the mode when the running program is using curses. + +// Subsequent calls to reset_prog_mode() will restore this mode. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_def_prog_mode_impl(PyObject *module) +// /*[clinic end generated code: output=05d5a351fff874aa input=768b9cace620dda5]*/ +// NoArgNoReturnFunctionBody(def_prog_mode) + +// /*[clinic input] +// _curses.def_shell_mode + +// Save the current terminal mode as the "shell" mode. + +// The "shell" mode is the mode when the running program is not using curses. + +// Subsequent calls to reset_shell_mode() will restore this mode. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_def_shell_mode_impl(PyObject *module) +// /*[clinic end generated code: output=d6e42f5c768f860f input=5ead21f6f0baa894]*/ +// NoArgNoReturnFunctionBody(def_shell_mode) + +// /*[clinic input] +// _curses.delay_output + +// ms: int +// Duration in milliseconds. +// / + +// Insert a pause in output. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_delay_output_impl(PyObject *module, int ms) +// /*[clinic end generated code: output=b6613a67f17fa4f4 input=5316457f5f59196c]*/ +// { +// PyCursesInitialised; + +// return PyCursesCheckERR(delay_output(ms), "delay_output"); +// } + +// /*[clinic input] +// _curses.doupdate + +// Update the physical screen to match the virtual screen. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_doupdate_impl(PyObject *module) +// /*[clinic end generated code: output=f34536975a75680c input=8da80914432a6489]*/ +// NoArgNoReturnFunctionBody(doupdate) + +// /*[clinic input] +// _curses.echo + +// flag: bool(accept={int}) = True +// If false, the effect is the same as calling noecho(). +// / + +// Enter echo mode. + +// In echo mode, each character input is echoed to the screen as it is entered. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_echo_impl(PyObject *module, int flag) +// /*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/ +// NoArgOrFlagNoReturnFunctionBody(echo, flag) + +// /*[clinic input] +// _curses.endwin + +// De-initialize the library, and return terminal to normal status. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_endwin_impl(PyObject *module) +// /*[clinic end generated code: output=c0150cd96d2f4128 input=e172cfa43062f3fa]*/ +// NoArgNoReturnFunctionBody(endwin) + +// /*[clinic input] +// _curses.erasechar + +// Return the user's current erase character. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_erasechar_impl(PyObject *module) +// /*[clinic end generated code: output=3df305dc6b926b3f input=628c136c3c5758d3]*/ +// { +// char ch; + +// PyCursesInitialised; + +// ch = erasechar(); + +// return PyBytes_FromStringAndSize(&ch, 1); +// } + +// /*[clinic input] +// _curses.flash + +// Flash the screen. + +// That is, change it to reverse-video and then change it back in a short interval. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_flash_impl(PyObject *module) +// /*[clinic end generated code: output=488b8a0ebd9ea9b8 input=02fdfb06c8fc3171]*/ +// NoArgNoReturnFunctionBody(flash) + +// /*[clinic input] +// _curses.flushinp + +// Flush all input buffers. + +// This throws away any typeahead that has been typed by the user and has not +// yet been processed by the program. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_flushinp_impl(PyObject *module) +// /*[clinic end generated code: output=7e7a1fc1473960f5 input=59d042e705cef5ec]*/ +// NoArgNoReturnVoidFunctionBody(flushinp) + +// #ifdef getsyx +// /*[clinic input] +// _curses.getsyx + +// Return the current coordinates of the virtual screen cursor. + +// Return a (y, x) tuple. If leaveok is currently true, return (-1, -1). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_getsyx_impl(PyObject *module) +// /*[clinic end generated code: output=c8e6c3f42349a038 input=9e1f862f3b4f7cba]*/ +// { +// int x = 0; +// int y = 0; + +// PyCursesInitialised; + +// getsyx(y, x); + +// return Py_BuildValue("(ii)", y, x); +// } +// #endif + +// #ifdef NCURSES_MOUSE_VERSION +// /*[clinic input] +// _curses.getmouse + +// Retrieve the queued mouse event. + +// After getch() returns KEY_MOUSE to signal a mouse event, this function +// returns a 5-tuple (id, x, y, z, bstate). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_getmouse_impl(PyObject *module) +// /*[clinic end generated code: output=ccf4242546b9cfa8 input=5b756ee6f5b481b1]*/ +// { +// int rtn; +// MEVENT event; + +// PyCursesInitialised; + +// rtn = getmouse( &event ); +// if (rtn == ERR) { +// PyErr_SetString(PyCursesError, "getmouse() returned ERR"); +// return NULL; +// } +// return Py_BuildValue("(hiiik)", +// (short)event.id, +// (int)event.x, (int)event.y, (int)event.z, +// (unsigned long) event.bstate); +// } + +// /*[clinic input] +// _curses.ungetmouse + +// id: short +// x: int +// y: int +// z: int +// bstate: unsigned_long(bitwise=True) +// / + +// Push a KEY_MOUSE event onto the input queue. + +// The following getmouse() will return the given state data. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, +// unsigned long bstate) +// /*[clinic end generated code: output=3430c9b0fc5c4341 input=fd650b2ca5a01e8f]*/ +// { +// MEVENT event; + +// PyCursesInitialised; + +// event.id = id; +// event.x = x; +// event.y = y; +// event.z = z; +// event.bstate = bstate; +// return PyCursesCheckERR(ungetmouse(&event), "ungetmouse"); +// } +// #endif + +// /*[clinic input] +// _curses.getwin + +// file: object +// / + +// Read window related data stored in the file by an earlier putwin() call. + +// The routine then creates and initializes a new window using that data, +// returning the new window object. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_getwin(PyObject *module, PyObject *file) +// /*[clinic end generated code: output=a79e0df3379af756 input=f713d2bba0e4c929]*/ +// { +// FILE *fp; +// PyObject *data; +// size_t datalen; +// WINDOW *win; +// _Py_IDENTIFIER(read); +// PyObject *res = NULL; + +// PyCursesInitialised; + +// fp = tmpfile(); +// if (fp == NULL) +// return PyErr_SetFromErrno(PyExc_OSError); + +// if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) +// goto error; + +// data = _PyObject_CallMethodId(file, &PyId_read, NULL); +// if (data == NULL) +// goto error; +// if (!PyBytes_Check(data)) { +// PyErr_Format(PyExc_TypeError, +// "f.read() returned %.100s instead of bytes", +// data->ob_type->tp_name); +// Py_DECREF(data); +// goto error; +// } +// datalen = PyBytes_GET_SIZE(data); +// if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) { +// Py_DECREF(data); +// PyErr_SetFromErrno(PyExc_OSError); +// goto error; +// } +// Py_DECREF(data); + +// fseek(fp, 0, 0); +// win = getwin(fp); +// if (win == NULL) { +// PyErr_SetString(PyCursesError, catchall_NULL); +// goto error; +// } +// res = PyCursesWindow_New(win, NULL); + +// error: +// fclose(fp); +// return res; +// } + +// /*[clinic input] +// _curses.halfdelay + +// tenths: byte +// Maximal blocking delay in tenths of seconds (1 - 255). +// / + +// Enter half-delay mode. + +// Use nocbreak() to leave half-delay mode. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_halfdelay_impl(PyObject *module, unsigned char tenths) +// /*[clinic end generated code: output=e92cdf0ef33c0663 input=e42dce7259c15100]*/ +// { +// PyCursesInitialised; + +// return PyCursesCheckERR(halfdelay(tenths), "halfdelay"); +// } + +// /*[clinic input] +// _curses.has_colors + +// Return True if the terminal can display colors; otherwise, return False. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_has_colors_impl(PyObject *module) +// /*[clinic end generated code: output=db5667483139e3e2 input=b2ec41b739d896c6]*/ +// NoArgTrueFalseFunctionBody(has_colors) + +// /*[clinic input] +// _curses.has_ic + +// Return True if the terminal has insert- and delete-character capabilities. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_has_ic_impl(PyObject *module) +// /*[clinic end generated code: output=6be24da9cb1268fe input=9bc2d3a797cc7324]*/ +// NoArgTrueFalseFunctionBody(has_ic) + +// /*[clinic input] +// _curses.has_il + +// Return True if the terminal has insert- and delete-line capabilities. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_has_il_impl(PyObject *module) +// /*[clinic end generated code: output=d45bd7788ff9f5f4 input=cd939d5607ee5427]*/ +// NoArgTrueFalseFunctionBody(has_il) + +// #ifdef HAVE_CURSES_HAS_KEY +// /*[clinic input] +// _curses.has_key + +// key: int +// Key number. +// / + +// Return True if the current terminal type recognizes a key with that value. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_has_key_impl(PyObject *module, int key) +// /*[clinic end generated code: output=19ad48319414d0b1 input=78bd44acf1a4997c]*/ +// { +// PyCursesInitialised; + +// return PyBool_FromLong(has_key(key)); +// } +// #endif + +// /*[clinic input] +// _curses.init_color + +// color_number: short +// The number of the color to be changed (0 - (COLORS-1)). +// r: short +// Red component (0 - 1000). +// g: short +// Green component (0 - 1000). +// b: short +// Blue component (0 - 1000). +// / + +// Change the definition of a color. + +// When init_color() is used, all occurrences of that color on the screen +// immediately change to the new definition. This function is a no-op on +// most terminals; it is active only if can_change_color() returns true. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_init_color_impl(PyObject *module, short color_number, short r, +// short g, short b) +// /*[clinic end generated code: output=280236f5efe9776a input=128601b5dc76d548]*/ +// { +// PyCursesInitialised; +// PyCursesInitialisedColor; + +// return PyCursesCheckERR(init_color(color_number, r, g, b), "init_color"); +// } + +// /*[clinic input] +// _curses.init_pair + +// pair_number: short +// The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)). +// fg: short +// Foreground color number (-1 - (COLORS-1)). +// bg: short +// Background color number (-1 - (COLORS-1)). +// / + +// Change the definition of a color-pair. + +// If the color-pair was previously initialized, the screen is refreshed and +// all occurrences of that color-pair are changed to the new definition. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_init_pair_impl(PyObject *module, short pair_number, short fg, +// short bg) +// /*[clinic end generated code: output=9c2ce39c22f376b6 input=12c320ec14396ea2]*/ +// { +// PyCursesInitialised; +// PyCursesInitialisedColor; + +// return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair"); +// } + +// static PyObject *ModDict; + +// /*[clinic input] +// _curses.initscr + +// Initialize the library. + +// Return a WindowObject which represents the whole screen. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_initscr_impl(PyObject *module) +// /*[clinic end generated code: output=619fb68443810b7b input=514f4bce1821f6b5]*/ +// { +// WINDOW *win; +// PyCursesWindowObject *winobj; + +// if (initialised) { +// wrefresh(stdscr); +// return (PyObject *)PyCursesWindow_New(stdscr, NULL); +// } + +// win = initscr(); + +// if (win == NULL) { +// PyErr_SetString(PyCursesError, catchall_NULL); +// return NULL; +// } + +// initialised = initialised_setupterm = TRUE; + +// /* This was moved from initcurses() because it core dumped on SGI, +// where they're not defined until you've called initscr() */ +// #define SetDictInt(string,ch) \ +// do { \ +// PyObject *o = PyLong_FromLong((long) (ch)); \ +// if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \ +// Py_DECREF(o); \ +// } \ +// } while (0) + +// /* Here are some graphic symbols you can use */ +// SetDictInt("ACS_ULCORNER", (ACS_ULCORNER)); +// SetDictInt("ACS_LLCORNER", (ACS_LLCORNER)); +// SetDictInt("ACS_URCORNER", (ACS_URCORNER)); +// SetDictInt("ACS_LRCORNER", (ACS_LRCORNER)); +// SetDictInt("ACS_LTEE", (ACS_LTEE)); +// SetDictInt("ACS_RTEE", (ACS_RTEE)); +// SetDictInt("ACS_BTEE", (ACS_BTEE)); +// SetDictInt("ACS_TTEE", (ACS_TTEE)); +// SetDictInt("ACS_HLINE", (ACS_HLINE)); +// SetDictInt("ACS_VLINE", (ACS_VLINE)); +// SetDictInt("ACS_PLUS", (ACS_PLUS)); +// #if !defined(__hpux) || defined(HAVE_NCURSES_H) +// /* On HP/UX 11, these are of type cchar_t, which is not an +// integral type. If this is a problem on more platforms, a +// configure test should be added to determine whether ACS_S1 +// is of integral type. */ +// SetDictInt("ACS_S1", (ACS_S1)); +// SetDictInt("ACS_S9", (ACS_S9)); +// SetDictInt("ACS_DIAMOND", (ACS_DIAMOND)); +// SetDictInt("ACS_CKBOARD", (ACS_CKBOARD)); +// SetDictInt("ACS_DEGREE", (ACS_DEGREE)); +// SetDictInt("ACS_PLMINUS", (ACS_PLMINUS)); +// SetDictInt("ACS_BULLET", (ACS_BULLET)); +// SetDictInt("ACS_LARROW", (ACS_LARROW)); +// SetDictInt("ACS_RARROW", (ACS_RARROW)); +// SetDictInt("ACS_DARROW", (ACS_DARROW)); +// SetDictInt("ACS_UARROW", (ACS_UARROW)); +// SetDictInt("ACS_BOARD", (ACS_BOARD)); +// SetDictInt("ACS_LANTERN", (ACS_LANTERN)); +// SetDictInt("ACS_BLOCK", (ACS_BLOCK)); +// #endif +// SetDictInt("ACS_BSSB", (ACS_ULCORNER)); +// SetDictInt("ACS_SSBB", (ACS_LLCORNER)); +// SetDictInt("ACS_BBSS", (ACS_URCORNER)); +// SetDictInt("ACS_SBBS", (ACS_LRCORNER)); +// SetDictInt("ACS_SBSS", (ACS_RTEE)); +// SetDictInt("ACS_SSSB", (ACS_LTEE)); +// SetDictInt("ACS_SSBS", (ACS_BTEE)); +// SetDictInt("ACS_BSSS", (ACS_TTEE)); +// SetDictInt("ACS_BSBS", (ACS_HLINE)); +// SetDictInt("ACS_SBSB", (ACS_VLINE)); +// SetDictInt("ACS_SSSS", (ACS_PLUS)); + +// /* The following are never available with strict SYSV curses */ +// #ifdef ACS_S3 +// SetDictInt("ACS_S3", (ACS_S3)); +// #endif +// #ifdef ACS_S7 +// SetDictInt("ACS_S7", (ACS_S7)); +// #endif +// #ifdef ACS_LEQUAL +// SetDictInt("ACS_LEQUAL", (ACS_LEQUAL)); +// #endif +// #ifdef ACS_GEQUAL +// SetDictInt("ACS_GEQUAL", (ACS_GEQUAL)); +// #endif +// #ifdef ACS_PI +// SetDictInt("ACS_PI", (ACS_PI)); +// #endif +// #ifdef ACS_NEQUAL +// SetDictInt("ACS_NEQUAL", (ACS_NEQUAL)); +// #endif +// #ifdef ACS_STERLING +// SetDictInt("ACS_STERLING", (ACS_STERLING)); +// #endif + +// SetDictInt("LINES", LINES); +// SetDictInt("COLS", COLS); + +// winobj = (PyCursesWindowObject *)PyCursesWindow_New(win, NULL); +// screen_encoding = winobj->encoding; +// return (PyObject *)winobj; +// } + +// /*[clinic input] +// _curses.setupterm + +// term: str(accept={str, NoneType}) = None +// Terminal name. +// If omitted, the value of the TERM environment variable will be used. +// fd: int = -1 +// File descriptor to which any initialization sequences will be sent. +// If not supplied, the file descriptor for sys.stdout will be used. + +// Initialize the terminal. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_setupterm_impl(PyObject *module, const char *term, int fd) +// /*[clinic end generated code: output=4584e587350f2848 input=4511472766af0c12]*/ +// { +// int err; + +// if (fd == -1) { +// PyObject* sys_stdout; + +// sys_stdout = PySys_GetObject("stdout"); + +// if (sys_stdout == NULL || sys_stdout == Py_None) { +// PyErr_SetString( +// PyCursesError, +// "lost sys.stdout"); +// return NULL; +// } + +// fd = PyObject_AsFileDescriptor(sys_stdout); + +// if (fd == -1) { +// return NULL; +// } +// } + +// if (!initialised_setupterm && setupterm((char *)term, fd, &err) == ERR) { +// const char* s = "setupterm: unknown error"; + +// if (err == 0) { +// s = "setupterm: could not find terminal"; +// } else if (err == -1) { +// s = "setupterm: could not find terminfo database"; +// } + +// PyErr_SetString(PyCursesError,s); +// return NULL; +// } + +// initialised_setupterm = TRUE; + +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _curses.intrflush + +// flag: bool(accept={int}) +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _curses_intrflush_impl(PyObject *module, int flag) +// /*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/ +// { +// PyCursesInitialised; + +// return PyCursesCheckERR(intrflush(NULL, flag), "intrflush"); +// } + +// /*[clinic input] +// _curses.isendwin + +// Return True if endwin() has been called. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_isendwin_impl(PyObject *module) +// /*[clinic end generated code: output=d73179e4a7e1eb8c input=6cdb01a7ebf71397]*/ +// NoArgTrueFalseFunctionBody(isendwin) + +// #ifdef HAVE_CURSES_IS_TERM_RESIZED +// /*[clinic input] +// _curses.is_term_resized + +// nlines: int +// Height. +// ncols: int +// Width. +// / + +// Return True if resize_term() would modify the window structure, False otherwise. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_is_term_resized_impl(PyObject *module, int nlines, int ncols) +// /*[clinic end generated code: output=aafe04afe50f1288 input=ca9c0bd0fb8ab444]*/ +// { +// PyCursesInitialised; + +// return PyBool_FromLong(is_term_resized(nlines, ncols)); +// } +// #endif /* HAVE_CURSES_IS_TERM_RESIZED */ + +// /*[clinic input] +// _curses.keyname + +// key: int +// Key number. +// / + +// Return the name of specified key. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_keyname_impl(PyObject *module, int key) +// /*[clinic end generated code: output=fa2675ab3f4e056b input=ee4b1d0f243a2a2b]*/ +// { +// const char *knp; + +// PyCursesInitialised; + +// if (key < 0) { +// PyErr_SetString(PyExc_ValueError, "invalid key number"); +// return NULL; +// } +// knp = keyname(key); + +// return PyBytes_FromString((knp == NULL) ? "" : knp); +// } + +// /*[clinic input] +// _curses.killchar + +// Return the user's current line kill character. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_killchar_impl(PyObject *module) +// /*[clinic end generated code: output=31c3a45b2c528269 input=1ff171c38df5ccad]*/ +// { +// char ch; + +// ch = killchar(); + +// return PyBytes_FromStringAndSize(&ch, 1); +// } + +// /*[clinic input] +// _curses.longname + +// Return the terminfo long name field describing the current terminal. + +// The maximum length of a verbose description is 128 characters. It is defined +// only after the call to initscr(). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_longname_impl(PyObject *module) +// /*[clinic end generated code: output=fdf30433727ef568 input=84c3f20201b1098e]*/ +// NoArgReturnStringFunctionBody(longname) + +// /*[clinic input] +// _curses.meta + +// yes: bool(accept={int}) +// / + +// Enable/disable meta keys. + +// If yes is True, allow 8-bit characters to be input. If yes is False, +// allow only 7-bit characters. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_meta_impl(PyObject *module, int yes) +// /*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/ +// { +// PyCursesInitialised; + +// return PyCursesCheckERR(meta(stdscr, yes), "meta"); +// } + +// #ifdef NCURSES_MOUSE_VERSION +// /*[clinic input] +// _curses.mouseinterval + +// interval: int +// Time in milliseconds. +// / + +// Set and retrieve the maximum time between press and release in a click. + +// Set the maximum time that can elapse between press and release events in +// order for them to be recognized as a click, and return the previous interval +// value. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_mouseinterval_impl(PyObject *module, int interval) +// /*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/ +// { +// PyCursesInitialised; + +// return PyCursesCheckERR(mouseinterval(interval), "mouseinterval"); +// } + +// /*[clinic input] +// _curses.mousemask + +// newmask: unsigned_long(bitwise=True) +// / + +// Set the mouse events to be reported, and return a tuple (availmask, oldmask). + +// Return a tuple (availmask, oldmask). availmask indicates which of the +// specified mouse events can be reported; on complete failure it returns 0. +// oldmask is the previous value of the given window's mouse event mask. +// If this function is never called, no mouse events are ever reported. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_mousemask_impl(PyObject *module, unsigned long newmask) +// /*[clinic end generated code: output=9406cf1b8a36e485 input=bdf76b7568a3c541]*/ +// { +// mmask_t oldmask, availmask; + +// PyCursesInitialised; +// availmask = mousemask((mmask_t)newmask, &oldmask); +// return Py_BuildValue("(kk)", +// (unsigned long)availmask, (unsigned long)oldmask); +// } +// #endif + +// /*[clinic input] +// _curses.napms + +// ms: int +// Duration in milliseconds. +// / + +// Sleep for specified time. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_napms_impl(PyObject *module, int ms) +// /*[clinic end generated code: output=a40a1da2e39ea438 input=20cd3af2b6900f56]*/ +// { +// PyCursesInitialised; + +// return Py_BuildValue("i", napms(ms)); +// } + + +// /*[clinic input] +// _curses.newpad + +// nlines: int +// Height. +// ncols: int +// Width. +// / + +// Create and return a pointer to a new pad data structure. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_newpad_impl(PyObject *module, int nlines, int ncols) +// /*[clinic end generated code: output=de52a56eb1098ec9 input=93f1272f240d8894]*/ +// { +// WINDOW *win; + +// PyCursesInitialised; + +// win = newpad(nlines, ncols); + +// if (win == NULL) { +// PyErr_SetString(PyCursesError, catchall_NULL); +// return NULL; +// } + +// return (PyObject *)PyCursesWindow_New(win, NULL); +// } + +// /*[clinic input] +// _curses.newwin + +// nlines: int +// Height. +// ncols: int +// Width. +// [ +// begin_y: int = 0 +// Top side y-coordinate. +// begin_x: int = 0 +// Left side x-coordinate. +// ] +// / + +// Return a new window. + +// By default, the window will extend from the specified position to the lower +// right corner of the screen. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_newwin_impl(PyObject *module, int nlines, int ncols, +// int group_right_1, int begin_y, int begin_x) +// /*[clinic end generated code: output=c1e0a8dc8ac2826c input=29312c15a72a003d]*/ +// { +// WINDOW *win; + +// PyCursesInitialised; + +// win = newwin(nlines,ncols,begin_y,begin_x); +// if (win == NULL) { +// PyErr_SetString(PyCursesError, catchall_NULL); +// return NULL; +// } + +// return (PyObject *)PyCursesWindow_New(win, NULL); +// } + +// /*[clinic input] +// _curses.nl + +// flag: bool(accept={int}) = True +// If false, the effect is the same as calling nonl(). +// / + +// Enter newline mode. + +// This mode translates the return key into newline on input, and translates +// newline into return and line-feed on output. Newline mode is initially on. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_nl_impl(PyObject *module, int flag) +// /*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/ +// NoArgOrFlagNoReturnFunctionBody(nl, flag) + +// /*[clinic input] +// _curses.nocbreak + +// Leave cbreak mode. + +// Return to normal "cooked" mode with line buffering. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_nocbreak_impl(PyObject *module) +// /*[clinic end generated code: output=eabf3833a4fbf620 input=e4b65f7d734af400]*/ +// NoArgNoReturnFunctionBody(nocbreak) + +// /*[clinic input] +// _curses.noecho + +// Leave echo mode. + +// Echoing of input characters is turned off. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_noecho_impl(PyObject *module) +// /*[clinic end generated code: output=cc95ab45bc98f41b input=76714df529e614c3]*/ +// NoArgNoReturnFunctionBody(noecho) + +// /*[clinic input] +// _curses.nonl + +// Leave newline mode. + +// Disable translation of return into newline on input, and disable low-level +// translation of newline into newline/return on output. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_nonl_impl(PyObject *module) +// /*[clinic end generated code: output=99e917e9715770c6 input=9d37dd122d3022fc]*/ +// NoArgNoReturnFunctionBody(nonl) + +// /*[clinic input] +// _curses.noqiflush + +// Disable queue flushing. + +// When queue flushing is disabled, normal flush of input and output queues +// associated with the INTR, QUIT and SUSP characters will not be done. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_noqiflush_impl(PyObject *module) +// /*[clinic end generated code: output=8b95a4229bbf0877 input=ba3e6b2e3e54c4df]*/ +// NoArgNoReturnVoidFunctionBody(noqiflush) + +// /*[clinic input] +// _curses.noraw + +// Leave raw mode. + +// Return to normal "cooked" mode with line buffering. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_noraw_impl(PyObject *module) +// /*[clinic end generated code: output=39894e5524c430cc input=6ec86692096dffb5]*/ +// NoArgNoReturnFunctionBody(noraw) + +// /*[clinic input] +// _curses.pair_content + +// pair_number: short +// The number of the color pair (1 - (COLOR_PAIRS-1)). +// / + +// Return a tuple (fg, bg) containing the colors for the requested color pair. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_pair_content_impl(PyObject *module, short pair_number) +// /*[clinic end generated code: output=5a72aa1a28bbacf3 input=f4d7fec5643b976b]*/ +// { +// short f, b; + +// PyCursesInitialised; +// PyCursesInitialisedColor; + +// if (pair_content(pair_number, &f, &b) == ERR) { +// if (pair_number >= COLOR_PAIRS) { +// PyErr_SetString(PyCursesError, +// "Argument 1 was out of range. (0..COLOR_PAIRS-1)"); +// } +// else { +// PyErr_SetString(PyCursesError, "pair_content() returned ERR"); +// } +// return NULL; +// } + +// return Py_BuildValue("(ii)", f, b); +// } + +// /*[clinic input] +// _curses.pair_number + +// attr: int +// / + +// Return the number of the color-pair set by the specified attribute value. + +// color_pair() is the counterpart to this function. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_pair_number_impl(PyObject *module, int attr) +// /*[clinic end generated code: output=85bce7d65c0aa3f4 input=d478548e33f5e61a]*/ +// { +// PyCursesInitialised; +// PyCursesInitialisedColor; + +// return PyLong_FromLong(PAIR_NUMBER(attr)); +// } + +// /*[clinic input] +// _curses.putp + +// string: str(accept={robuffer}) +// / + +// Emit the value of a specified terminfo capability for the current terminal. + +// Note that the output of putp() always goes to standard output. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_putp_impl(PyObject *module, const char *string) +// /*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/ +// { +// return PyCursesCheckERR(putp(string), "putp"); +// } + +// /*[clinic input] +// _curses.qiflush + +// flag: bool(accept={int}) = True +// If false, the effect is the same as calling noqiflush(). +// / + +// Enable queue flushing. + +// If queue flushing is enabled, all output in the display driver queue +// will be flushed when the INTR, QUIT and SUSP characters are read. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_qiflush_impl(PyObject *module, int flag) +// /*[clinic end generated code: output=9167e862f760ea30 input=e9e4a389946a0dbc]*/ +// { +// PyCursesInitialised; + +// if (flag) { +// qiflush(); +// } +// else { +// noqiflush(); +// } +// Py_RETURN_NONE; +// } + +// /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES +// * and _curses.COLS */ +// #if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM) +// static int +// update_lines_cols(void) +// { +// PyObject *o; +// PyObject *m = PyImport_ImportModuleNoBlock("curses"); +// _Py_IDENTIFIER(LINES); +// _Py_IDENTIFIER(COLS); + +// if (!m) +// return 0; + +// o = PyLong_FromLong(LINES); +// if (!o) { +// Py_DECREF(m); +// return 0; +// } +// if (_PyObject_SetAttrId(m, &PyId_LINES, o)) { +// Py_DECREF(m); +// Py_DECREF(o); +// return 0; +// } +// /* PyId_LINES.object will be initialized here. */ +// if (PyDict_SetItem(ModDict, PyId_LINES.object, o)) { +// Py_DECREF(m); +// Py_DECREF(o); +// return 0; +// } +// Py_DECREF(o); +// o = PyLong_FromLong(COLS); +// if (!o) { +// Py_DECREF(m); +// return 0; +// } +// if (_PyObject_SetAttrId(m, &PyId_COLS, o)) { +// Py_DECREF(m); +// Py_DECREF(o); +// return 0; +// } +// if (PyDict_SetItem(ModDict, PyId_COLS.object, o)) { +// Py_DECREF(m); +// Py_DECREF(o); +// return 0; +// } +// Py_DECREF(o); +// Py_DECREF(m); +// return 1; +// } + +// /*[clinic input] +// _curses.update_lines_cols + +// [clinic start generated code]*/ + +// static PyObject * +// _curses_update_lines_cols_impl(PyObject *module) +// /*[clinic end generated code: output=423f2b1e63ed0f75 input=5f065ab7a28a5d90]*/ +// { +// if (!update_lines_cols()) { +// return NULL; +// } +// Py_RETURN_NONE; +// } + +// #endif + +// /*[clinic input] +// _curses.raw + +// flag: bool(accept={int}) = True +// If false, the effect is the same as calling noraw(). +// / + +// Enter raw mode. + +// In raw mode, normal line buffering and processing of interrupt, quit, +// suspend, and flow control keys are turned off; characters are presented to +// curses input functions one by one. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_raw_impl(PyObject *module, int flag) +// /*[clinic end generated code: output=a750e4b342be015b input=e36d8db27832b848]*/ +// NoArgOrFlagNoReturnFunctionBody(raw, flag) + +// /*[clinic input] +// _curses.reset_prog_mode + +// Restore the terminal to "program" mode, as previously saved by def_prog_mode(). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_reset_prog_mode_impl(PyObject *module) +// /*[clinic end generated code: output=15eb765abf0b6575 input=3d82bea2b3243471]*/ +// NoArgNoReturnFunctionBody(reset_prog_mode) + +// /*[clinic input] +// _curses.reset_shell_mode + +// Restore the terminal to "shell" mode, as previously saved by def_shell_mode(). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_reset_shell_mode_impl(PyObject *module) +// /*[clinic end generated code: output=0238de2962090d33 input=1c738fa64bd1a24f]*/ +// NoArgNoReturnFunctionBody(reset_shell_mode) + +// /*[clinic input] +// _curses.resetty + +// Restore terminal mode. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_resetty_impl(PyObject *module) +// /*[clinic end generated code: output=ff4b448e80a7cd63 input=940493de03624bb0]*/ +// NoArgNoReturnFunctionBody(resetty) + +// #ifdef HAVE_CURSES_RESIZETERM +// /*[clinic input] +// _curses.resizeterm + +// nlines: int +// Height. +// ncols: int +// Width. +// / + +// Resize the standard and current windows to the specified dimensions. + +// Adjusts other bookkeeping data used by the curses library that record the +// window dimensions (in particular the SIGWINCH handler). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_resizeterm_impl(PyObject *module, int nlines, int ncols) +// /*[clinic end generated code: output=56d6bcc5194ad055 input=0fca02ebad5ffa82]*/ +// { +// PyObject *result; + +// PyCursesInitialised; + +// result = PyCursesCheckERR(resizeterm(nlines, ncols), "resizeterm"); +// if (!result) +// return NULL; +// if (!update_lines_cols()) { +// Py_DECREF(result); +// return NULL; +// } +// return result; +// } + +// #endif + +// #ifdef HAVE_CURSES_RESIZE_TERM +// /*[clinic input] +// _curses.resize_term + +// nlines: int +// Height. +// ncols: int +// Width. +// / + +// Backend function used by resizeterm(), performing most of the work. + +// When resizing the windows, resize_term() blank-fills the areas that are +// extended. The calling application should fill in these areas with appropriate +// data. The resize_term() function attempts to resize all windows. However, +// due to the calling convention of pads, it is not possible to resize these +// without additional interaction with the application. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_resize_term_impl(PyObject *module, int nlines, int ncols) +// /*[clinic end generated code: output=9e26d8b9ea311ed2 input=2197edd05b049ed4]*/ +// { +// PyObject *result; + +// PyCursesInitialised; + +// result = PyCursesCheckERR(resize_term(nlines, ncols), "resize_term"); +// if (!result) +// return NULL; +// if (!update_lines_cols()) { +// Py_DECREF(result); +// return NULL; +// } +// return result; +// } +// #endif /* HAVE_CURSES_RESIZE_TERM */ + +// /*[clinic input] +// _curses.savetty + +// Save terminal mode. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_savetty_impl(PyObject *module) +// /*[clinic end generated code: output=6babc49f12b42199 input=fce6b2b7d2200102]*/ +// NoArgNoReturnFunctionBody(savetty) + +// #ifdef getsyx +// /*[clinic input] +// _curses.setsyx + +// y: int +// Y-coordinate. +// x: int +// X-coordinate. +// / + +// Set the virtual screen cursor. + +// If y and x are both -1, then leaveok is set. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_setsyx_impl(PyObject *module, int y, int x) +// /*[clinic end generated code: output=23dcf753511a2464 input=fa7f2b208e10a557]*/ +// { +// PyCursesInitialised; + +// setsyx(y,x); + +// Py_RETURN_NONE; +// } +// #endif + +// /*[clinic input] +// _curses.start_color + +// Initializes eight basic colors and global variables COLORS and COLOR_PAIRS. + +// Must be called if the programmer wants to use colors, and before any other +// color manipulation routine is called. It is good practice to call this +// routine right after initscr(). + +// It also restores the colors on the terminal to the values they had when the +// terminal was just turned on. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_start_color_impl(PyObject *module) +// /*[clinic end generated code: output=8b772b41d8090ede input=0ca0ecb2b77e1a12]*/ +// { +// int code; +// PyObject *c, *cp; + +// PyCursesInitialised; + +// code = start_color(); +// if (code != ERR) { +// initialisedcolors = TRUE; +// c = PyLong_FromLong((long) COLORS); +// if (c == NULL) +// return NULL; +// if (PyDict_SetItemString(ModDict, "COLORS", c) < 0) { +// Py_DECREF(c); +// return NULL; +// } +// Py_DECREF(c); +// cp = PyLong_FromLong((long) COLOR_PAIRS); +// if (cp == NULL) +// return NULL; +// if (PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp) < 0) { +// Py_DECREF(cp); +// return NULL; +// } +// Py_DECREF(cp); +// Py_RETURN_NONE; +// } else { +// PyErr_SetString(PyCursesError, "start_color() returned ERR"); +// return NULL; +// } +// } + +// /*[clinic input] +// _curses.termattrs + +// Return a logical OR of all video attributes supported by the terminal. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_termattrs_impl(PyObject *module) +// /*[clinic end generated code: output=b06f437fce1b6fc4 input=0559882a04f84d1d]*/ +// NoArgReturnIntFunctionBody(termattrs) + +// /*[clinic input] +// _curses.termname + +// Return the value of the environment variable TERM, truncated to 14 characters. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_termname_impl(PyObject *module) +// /*[clinic end generated code: output=96375577ebbd67fd input=33c08d000944f33f]*/ +// NoArgReturnStringFunctionBody(termname) + +// /*[clinic input] +// _curses.tigetflag + +// capname: str +// The terminfo capability name. +// / + +// Return the value of the Boolean capability. + +// The value -1 is returned if capname is not a Boolean capability, or 0 if +// it is canceled or absent from the terminal description. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_tigetflag_impl(PyObject *module, const char *capname) +// /*[clinic end generated code: output=8853c0e55542195b input=b0787af9e3e9a6ce]*/ +// { +// PyCursesSetupTermCalled; + +// return PyLong_FromLong( (long) tigetflag( (char *)capname ) ); +// } + +// /*[clinic input] +// _curses.tigetnum + +// capname: str +// The terminfo capability name. +// / + +// Return the value of the numeric capability. + +// The value -2 is returned if capname is not a numeric capability, or -1 if +// it is canceled or absent from the terminal description. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_tigetnum_impl(PyObject *module, const char *capname) +// /*[clinic end generated code: output=46f8b0a1b5dff42f input=5cdf2f410b109720]*/ +// { +// PyCursesSetupTermCalled; + +// return PyLong_FromLong( (long) tigetnum( (char *)capname ) ); +// } + +// /*[clinic input] +// _curses.tigetstr + +// capname: str +// The terminfo capability name. +// / + +// Return the value of the string capability. + +// None is returned if capname is not a string capability, or is canceled or +// absent from the terminal description. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_tigetstr_impl(PyObject *module, const char *capname) +// /*[clinic end generated code: output=f22b576ad60248f3 input=36644df25c73c0a7]*/ +// { +// PyCursesSetupTermCalled; + +// capname = tigetstr( (char *)capname ); +// if (capname == NULL || capname == (char*) -1) { +// Py_RETURN_NONE; +// } +// return PyBytes_FromString( capname ); +// } + +// /*[clinic input] +// _curses.tparm + +// str: str(accept={robuffer}) +// Parameterized byte string obtained from the terminfo database. +// i1: int = 0 +// i2: int = 0 +// i3: int = 0 +// i4: int = 0 +// i5: int = 0 +// i6: int = 0 +// i7: int = 0 +// i8: int = 0 +// i9: int = 0 +// / + +// Instantiate the specified byte string with the supplied parameters. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, +// int i4, int i5, int i6, int i7, int i8, int i9) +// /*[clinic end generated code: output=599f62b615c667ff input=5e30b15786f032aa]*/ +// { +// char* result = NULL; + +// PyCursesSetupTermCalled; + +// result = tparm((char *)str,i1,i2,i3,i4,i5,i6,i7,i8,i9); +// if (!result) { +// PyErr_SetString(PyCursesError, "tparm() returned NULL"); +// return NULL; +// } + +// return PyBytes_FromString(result); +// } + +// #ifdef HAVE_CURSES_TYPEAHEAD +// /*[clinic input] +// _curses.typeahead + +// fd: int +// File descriptor. +// / + +// Specify that the file descriptor fd be used for typeahead checking. + +// If fd is -1, then no typeahead checking is done. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_typeahead_impl(PyObject *module, int fd) +// /*[clinic end generated code: output=084bb649d7066583 input=f2968d8e1805051b]*/ +// { +// PyCursesInitialised; + +// return PyCursesCheckERR(typeahead( fd ), "typeahead"); +// } +// #endif + +// /*[clinic input] +// _curses.unctrl + +// ch: object +// / + +// Return a string which is a printable representation of the character ch. + +// Control characters are displayed as a caret followed by the character, +// for example as ^C. Printing characters are left as they are. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_unctrl(PyObject *module, PyObject *ch) +// /*[clinic end generated code: output=8e07fafc430c9434 input=cd1e35e16cd1ace4]*/ +// { +// chtype ch_; + +// PyCursesInitialised; + +// if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) +// return NULL; + +// return PyBytes_FromString(unctrl(ch_)); +// } + +// /*[clinic input] +// _curses.ungetch + +// ch: object +// / + +// Push ch so the next getch() will return it. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_ungetch(PyObject *module, PyObject *ch) +// /*[clinic end generated code: output=9b19d8268376d887 input=6681e6ae4c42e5eb]*/ +// { +// chtype ch_; + +// PyCursesInitialised; + +// if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) +// return NULL; + +// return PyCursesCheckERR(ungetch(ch_), "ungetch"); +// } + +// #ifdef HAVE_NCURSESW +// /* Convert an object to a character (wchar_t): + +// - int +// - str of length 1 + +// Return 1 on success, 0 on error. */ +// static int +// PyCurses_ConvertToWchar_t(PyObject *obj, +// wchar_t *wch) +// { +// if (PyUnicode_Check(obj)) { +// wchar_t buffer[2]; +// if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) { +// PyErr_Format(PyExc_TypeError, +// "expect str of length 1 or int, " +// "got a str of length %zi", +// PyUnicode_GET_LENGTH(obj)); +// return 0; +// } +// *wch = buffer[0]; +// return 2; +// } +// else if (PyLong_CheckExact(obj)) { +// long value; +// int overflow; +// value = PyLong_AsLongAndOverflow(obj, &overflow); +// if (overflow) { +// PyErr_SetString(PyExc_OverflowError, +// "int doesn't fit in long"); +// return 0; +// } +// *wch = (wchar_t)value; +// if ((long)*wch != value) { +// PyErr_Format(PyExc_OverflowError, +// "character doesn't fit in wchar_t"); +// return 0; +// } +// return 1; +// } +// else { +// PyErr_Format(PyExc_TypeError, +// "expect str of length 1 or int, got %s", +// Py_TYPE(obj)->tp_name); +// return 0; +// } +// } + +// /*[clinic input] +// _curses.unget_wch + +// ch: object +// / + +// Push ch so the next get_wch() will return it. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_unget_wch(PyObject *module, PyObject *ch) +// /*[clinic end generated code: output=1974c9fb01d37863 input=0d56dc65a46feebb]*/ +// { +// wchar_t wch; + +// PyCursesInitialised; + +// if (!PyCurses_ConvertToWchar_t(ch, &wch)) +// return NULL; +// return PyCursesCheckERR(unget_wch(wch), "unget_wch"); +// } +// #endif + +// #ifdef HAVE_CURSES_USE_ENV +// /*[clinic input] +// _curses.use_env + +// flag: bool(accept={int}) +// / + +// Use environment variables LINES and COLUMNS. + +// If used, this function should be called before initscr() or newterm() are +// called. + +// When flag is False, the values of lines and columns specified in the terminfo +// database will be used, even if environment variables LINES and COLUMNS (used +// by default) are set, or if curses is running in a window (in which case +// default behavior would be to use the window size if LINES and COLUMNS are +// not set). +// [clinic start generated code]*/ + +// static PyObject * +// _curses_use_env_impl(PyObject *module, int flag) +// /*[clinic end generated code: output=b2c445e435c0b164 input=1778eb1e9151ea37]*/ +// { +// use_env(flag); +// Py_RETURN_NONE; +// } +// #endif + +// #ifndef STRICT_SYSV_CURSES +// /*[clinic input] +// _curses.use_default_colors + +// Allow use of default values for colors on terminals supporting this feature. + +// Use this to support transparency in your application. The default color +// is assigned to the color number -1. +// [clinic start generated code]*/ + +// static PyObject * +// _curses_use_default_colors_impl(PyObject *module) +// /*[clinic end generated code: output=a3b81ff71dd901be input=656844367470e8fc]*/ +// { +// int code; + +// PyCursesInitialised; +// PyCursesInitialisedColor; + +// code = use_default_colors(); +// if (code != ERR) { +// Py_RETURN_NONE; +// } else { +// PyErr_SetString(PyCursesError, "use_default_colors() returned ERR"); +// return NULL; +// } +// } +// #endif /* STRICT_SYSV_CURSES */ + + +// #ifdef NCURSES_VERSION + +// PyDoc_STRVAR(ncurses_version__doc__, +// "curses.ncurses_version\n\ +// \n\ +// Ncurses version information as a named tuple."); + +// static PyTypeObject NcursesVersionType; + +// static PyStructSequence_Field ncurses_version_fields[] = { +// {"major", "Major release number"}, +// {"minor", "Minor release number"}, +// {"patch", "Patch release number"}, +// {0} +// }; + +// static PyStructSequence_Desc ncurses_version_desc = { +// "curses.ncurses_version", /* name */ +// ncurses_version__doc__, /* doc */ +// ncurses_version_fields, /* fields */ +// 3 +// }; + +// static PyObject * +// make_ncurses_version(void) +// { +// PyObject *ncurses_version; +// int pos = 0; + +// ncurses_version = PyStructSequence_New(&NcursesVersionType); +// if (ncurses_version == NULL) { +// return NULL; +// } + +// #define SetIntItem(flag) \ +// PyStructSequence_SET_ITEM(ncurses_version, pos++, PyLong_FromLong(flag)); \ +// if (PyErr_Occurred()) { \ +// Py_CLEAR(ncurses_version); \ +// return NULL; \ +// } + +// SetIntItem(NCURSES_VERSION_MAJOR) +// SetIntItem(NCURSES_VERSION_MINOR) +// SetIntItem(NCURSES_VERSION_PATCH) +// #undef SetIntItem + +// return ncurses_version; +// } + +// #endif /* NCURSES_VERSION */ + + +// /* List of functions defined in the module */ + +// static PyMethodDef PyCurses_methods[] = { +// _CURSES_BAUDRATE_METHODDEF +// _CURSES_BEEP_METHODDEF +// _CURSES_CAN_CHANGE_COLOR_METHODDEF +// _CURSES_CBREAK_METHODDEF +// _CURSES_COLOR_CONTENT_METHODDEF +// _CURSES_COLOR_PAIR_METHODDEF +// _CURSES_CURS_SET_METHODDEF +// _CURSES_DEF_PROG_MODE_METHODDEF +// _CURSES_DEF_SHELL_MODE_METHODDEF +// _CURSES_DELAY_OUTPUT_METHODDEF +// _CURSES_DOUPDATE_METHODDEF +// _CURSES_ECHO_METHODDEF +// _CURSES_ENDWIN_METHODDEF +// _CURSES_ERASECHAR_METHODDEF +// _CURSES_FILTER_METHODDEF +// _CURSES_FLASH_METHODDEF +// _CURSES_FLUSHINP_METHODDEF +// _CURSES_GETMOUSE_METHODDEF +// _CURSES_UNGETMOUSE_METHODDEF +// _CURSES_GETSYX_METHODDEF +// _CURSES_GETWIN_METHODDEF +// _CURSES_HAS_COLORS_METHODDEF +// _CURSES_HAS_IC_METHODDEF +// _CURSES_HAS_IL_METHODDEF +// _CURSES_HAS_KEY_METHODDEF +// _CURSES_HALFDELAY_METHODDEF +// _CURSES_INIT_COLOR_METHODDEF +// _CURSES_INIT_PAIR_METHODDEF +// _CURSES_INITSCR_METHODDEF +// _CURSES_INTRFLUSH_METHODDEF +// _CURSES_ISENDWIN_METHODDEF +// _CURSES_IS_TERM_RESIZED_METHODDEF +// _CURSES_KEYNAME_METHODDEF +// _CURSES_KILLCHAR_METHODDEF +// _CURSES_LONGNAME_METHODDEF +// _CURSES_META_METHODDEF +// _CURSES_MOUSEINTERVAL_METHODDEF +// _CURSES_MOUSEMASK_METHODDEF +// _CURSES_NAPMS_METHODDEF +// _CURSES_NEWPAD_METHODDEF +// _CURSES_NEWWIN_METHODDEF +// _CURSES_NL_METHODDEF +// _CURSES_NOCBREAK_METHODDEF +// _CURSES_NOECHO_METHODDEF +// _CURSES_NONL_METHODDEF +// _CURSES_NOQIFLUSH_METHODDEF +// _CURSES_NORAW_METHODDEF +// _CURSES_PAIR_CONTENT_METHODDEF +// _CURSES_PAIR_NUMBER_METHODDEF +// _CURSES_PUTP_METHODDEF +// _CURSES_QIFLUSH_METHODDEF +// _CURSES_RAW_METHODDEF +// _CURSES_RESET_PROG_MODE_METHODDEF +// _CURSES_RESET_SHELL_MODE_METHODDEF +// _CURSES_RESETTY_METHODDEF +// _CURSES_RESIZETERM_METHODDEF +// _CURSES_RESIZE_TERM_METHODDEF +// _CURSES_SAVETTY_METHODDEF +// _CURSES_SETSYX_METHODDEF +// _CURSES_SETUPTERM_METHODDEF +// _CURSES_START_COLOR_METHODDEF +// _CURSES_TERMATTRS_METHODDEF +// _CURSES_TERMNAME_METHODDEF +// _CURSES_TIGETFLAG_METHODDEF +// _CURSES_TIGETNUM_METHODDEF +// _CURSES_TIGETSTR_METHODDEF +// _CURSES_TPARM_METHODDEF +// _CURSES_TYPEAHEAD_METHODDEF +// _CURSES_UNCTRL_METHODDEF +// _CURSES_UNGETCH_METHODDEF +// _CURSES_UPDATE_LINES_COLS_METHODDEF +// _CURSES_UNGET_WCH_METHODDEF +// _CURSES_USE_ENV_METHODDEF +// _CURSES_USE_DEFAULT_COLORS_METHODDEF +// {NULL, NULL} /* sentinel */ +// }; + +// /* Initialization function for the module */ + + +// static struct PyModuleDef _cursesmodule = { +// PyModuleDef_HEAD_INIT, +// "_curses", +// NULL, +// -1, +// PyCurses_methods, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit__curses(void) +// { +// PyObject *m, *d, *v, *c_api_object; +// static void *PyCurses_API[PyCurses_API_pointers]; + +// /* Initialize object type */ +// if (PyType_Ready(&PyCursesWindow_Type) < 0) +// return NULL; + +// /* Initialize the C API pointer array */ +// PyCurses_API[0] = (void *)&PyCursesWindow_Type; +// PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled; +// PyCurses_API[2] = (void *)func_PyCursesInitialised; +// PyCurses_API[3] = (void *)func_PyCursesInitialisedColor; + +// /* Create the module and add the functions */ +// m = PyModule_Create(&_cursesmodule); +// if (m == NULL) +// return NULL; + +// /* Add some symbolic constants to the module */ +// d = PyModule_GetDict(m); +// if (d == NULL) +// return NULL; +// ModDict = d; /* For PyCurses_InitScr to use later */ + +// /* Add a capsule for the C API */ +// c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME, NULL); +// PyDict_SetItemString(d, "_C_API", c_api_object); +// Py_DECREF(c_api_object); + +// /* For exception curses.error */ +// PyCursesError = PyErr_NewException("_curses.error", NULL, NULL); +// PyDict_SetItemString(d, "error", PyCursesError); + +// /* Make the version available */ +// v = PyBytes_FromString(PyCursesVersion); +// PyDict_SetItemString(d, "version", v); +// PyDict_SetItemString(d, "__version__", v); +// Py_DECREF(v); + +// #ifdef NCURSES_VERSION +// /* ncurses_version */ +// if (NcursesVersionType.tp_name == NULL) { +// if (PyStructSequence_InitType2(&NcursesVersionType, +// &ncurses_version_desc) < 0) +// return NULL; +// } +// v = make_ncurses_version(); +// if (v == NULL) { +// return NULL; +// } +// PyDict_SetItemString(d, "ncurses_version", v); +// Py_DECREF(v); + +// /* prevent user from creating new instances */ +// NcursesVersionType.tp_init = NULL; +// NcursesVersionType.tp_new = NULL; +// if (PyDict_DelItemString(NcursesVersionType.tp_dict, "__new__") < 0 && +// PyErr_ExceptionMatches(PyExc_KeyError)) +// { +// PyErr_Clear(); +// } +// #endif /* NCURSES_VERSION */ + +// SetDictInt("ERR", ERR); +// SetDictInt("OK", OK); + +// /* Here are some attributes you can add to chars to print */ + +// SetDictInt("A_ATTRIBUTES", A_ATTRIBUTES); +// SetDictInt("A_NORMAL", A_NORMAL); +// SetDictInt("A_STANDOUT", A_STANDOUT); +// SetDictInt("A_UNDERLINE", A_UNDERLINE); +// SetDictInt("A_REVERSE", A_REVERSE); +// SetDictInt("A_BLINK", A_BLINK); +// SetDictInt("A_DIM", A_DIM); +// SetDictInt("A_BOLD", A_BOLD); +// SetDictInt("A_ALTCHARSET", A_ALTCHARSET); +// SetDictInt("A_INVIS", A_INVIS); +// SetDictInt("A_PROTECT", A_PROTECT); +// SetDictInt("A_CHARTEXT", A_CHARTEXT); +// SetDictInt("A_COLOR", A_COLOR); + +// /* The following are never available with strict SYSV curses */ +// #ifdef A_HORIZONTAL +// SetDictInt("A_HORIZONTAL", A_HORIZONTAL); +// #endif +// #ifdef A_LEFT +// SetDictInt("A_LEFT", A_LEFT); +// #endif +// #ifdef A_LOW +// SetDictInt("A_LOW", A_LOW); +// #endif +// #ifdef A_RIGHT +// SetDictInt("A_RIGHT", A_RIGHT); +// #endif +// #ifdef A_TOP +// SetDictInt("A_TOP", A_TOP); +// #endif +// #ifdef A_VERTICAL +// SetDictInt("A_VERTICAL", A_VERTICAL); +// #endif + +// /* ncurses extension */ +// #ifdef A_ITALIC +// SetDictInt("A_ITALIC", A_ITALIC); +// #endif + +// SetDictInt("COLOR_BLACK", COLOR_BLACK); +// SetDictInt("COLOR_RED", COLOR_RED); +// SetDictInt("COLOR_GREEN", COLOR_GREEN); +// SetDictInt("COLOR_YELLOW", COLOR_YELLOW); +// SetDictInt("COLOR_BLUE", COLOR_BLUE); +// SetDictInt("COLOR_MAGENTA", COLOR_MAGENTA); +// SetDictInt("COLOR_CYAN", COLOR_CYAN); +// SetDictInt("COLOR_WHITE", COLOR_WHITE); + +// #ifdef NCURSES_MOUSE_VERSION +// /* Mouse-related constants */ +// SetDictInt("BUTTON1_PRESSED", BUTTON1_PRESSED); +// SetDictInt("BUTTON1_RELEASED", BUTTON1_RELEASED); +// SetDictInt("BUTTON1_CLICKED", BUTTON1_CLICKED); +// SetDictInt("BUTTON1_DOUBLE_CLICKED", BUTTON1_DOUBLE_CLICKED); +// SetDictInt("BUTTON1_TRIPLE_CLICKED", BUTTON1_TRIPLE_CLICKED); + +// SetDictInt("BUTTON2_PRESSED", BUTTON2_PRESSED); +// SetDictInt("BUTTON2_RELEASED", BUTTON2_RELEASED); +// SetDictInt("BUTTON2_CLICKED", BUTTON2_CLICKED); +// SetDictInt("BUTTON2_DOUBLE_CLICKED", BUTTON2_DOUBLE_CLICKED); +// SetDictInt("BUTTON2_TRIPLE_CLICKED", BUTTON2_TRIPLE_CLICKED); + +// SetDictInt("BUTTON3_PRESSED", BUTTON3_PRESSED); +// SetDictInt("BUTTON3_RELEASED", BUTTON3_RELEASED); +// SetDictInt("BUTTON3_CLICKED", BUTTON3_CLICKED); +// SetDictInt("BUTTON3_DOUBLE_CLICKED", BUTTON3_DOUBLE_CLICKED); +// SetDictInt("BUTTON3_TRIPLE_CLICKED", BUTTON3_TRIPLE_CLICKED); + +// SetDictInt("BUTTON4_PRESSED", BUTTON4_PRESSED); +// SetDictInt("BUTTON4_RELEASED", BUTTON4_RELEASED); +// SetDictInt("BUTTON4_CLICKED", BUTTON4_CLICKED); +// SetDictInt("BUTTON4_DOUBLE_CLICKED", BUTTON4_DOUBLE_CLICKED); +// SetDictInt("BUTTON4_TRIPLE_CLICKED", BUTTON4_TRIPLE_CLICKED); + +// SetDictInt("BUTTON_SHIFT", BUTTON_SHIFT); +// SetDictInt("BUTTON_CTRL", BUTTON_CTRL); +// SetDictInt("BUTTON_ALT", BUTTON_ALT); + +// SetDictInt("ALL_MOUSE_EVENTS", ALL_MOUSE_EVENTS); +// SetDictInt("REPORT_MOUSE_POSITION", REPORT_MOUSE_POSITION); +// #endif +// /* Now set everything up for KEY_ variables */ +// { +// int key; +// char *key_n; +// char *key_n2; +// for (key=KEY_MIN;key < KEY_MAX; key++) { +// key_n = (char *)keyname(key); +// if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0) +// continue; +// if (strncmp(key_n,"KEY_F(",6)==0) { +// char *p1, *p2; +// key_n2 = PyMem_Malloc(strlen(key_n)+1); +// if (!key_n2) { +// PyErr_NoMemory(); +// break; +// } +// p1 = key_n; +// p2 = key_n2; +// while (*p1) { +// if (*p1 != '(' && *p1 != ')') { +// *p2 = *p1; +// p2++; +// } +// p1++; +// } +// *p2 = (char)0; +// } else +// key_n2 = key_n; +// SetDictInt(key_n2,key); +// if (key_n2 != key_n) +// PyMem_Free(key_n2); +// } +// SetDictInt("KEY_MIN", KEY_MIN); +// SetDictInt("KEY_MAX", KEY_MAX); +// } + +// Py_INCREF(&PyCursesWindow_Type); +// PyModule_AddObject(m, "window", (PyObject *)&PyCursesWindow_Type); +// return m; +// } diff --git a/python/Modules/_datetimemodule.c b/python/Modules/_datetimemodule.c new file mode 100755 index 0000000..d428210 --- /dev/null +++ b/python/Modules/_datetimemodule.c @@ -0,0 +1,6783 @@ +/* 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 "datetime.h" +#include "structmember.h" + +#include + +#ifdef MS_WINDOWS +# include /* struct timeval */ +#endif + +#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) +#define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) +#define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) +#define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) +#define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) +#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType) + +#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType) + +/*[clinic input] +module datetime +class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" +class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=25138ad6a696b785]*/ + +#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_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_CallMethodIdObjArgs(tzinfo, &PyId_tzname, + tzinfoarg, NULL); + + 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_CallMethodId(time, &PyId_time, NULL); + 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_CallMethodIdObjArgs(time, &PyId_struct_time, + args, NULL); + 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)", + result->ob_type->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_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL); + 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; + + whole_us = round(leftover_us); + 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_CallMethodIdObjArgs(cls, &PyId_fromtimestamp, + time, NULL); + 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_CallMethodId((PyObject *)self, &PyId_isoformat, NULL); +} + + +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_CallMethodId((PyObject *)self, &PyId_timetuple, NULL); + 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_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime, + format, NULL); +} + +/* 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); +} + +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; + } + return Py_BuildValue("iii", year, week + 1, day + 1); +} + +/* 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 3-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_CallNoArg(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_CallNoArg(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 */ + &PyDateTime_TZInfoType, /* tp_base */ + 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_CallMethodId((PyObject *)self, &PyId_isoformat, NULL); +} + +static PyObject * +time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw) +{ + char buf[100]; + char *timespec = NULL; + static char *keywords[] = {"timespec", NULL}; + PyObject *result; + int us = TIME_GET_MICROSECOND(self); + static 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 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_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL); + 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()).")}, + + {"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().")}, + + {"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" + "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).")}, + + {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS, + 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 */ + 0, /* tp_vectorcall_offset */ + 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 */ + &PyDateTime_DateType, /* tp_base */ + 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; + + if (PyType_Ready(&PyDateTime_DateType) < 0) + return NULL; + if (PyType_Ready(&PyDateTime_DateTimeType) < 0) + return NULL; + if (PyType_Ready(&PyDateTime_DeltaType) < 0) + return NULL; + if (PyType_Ready(&PyDateTime_TimeType) < 0) + return NULL; + if (PyType_Ready(&PyDateTime_TZInfoType) < 0) + return NULL; + if (PyType_Ready(&PyDateTime_TimeZoneType) < 0) + return NULL; + + /* 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); + + Py_INCREF(&PyDateTime_DateType); + PyModule_AddObject(m, "date", (PyObject *) &PyDateTime_DateType); + + Py_INCREF(&PyDateTime_DateTimeType); + PyModule_AddObject(m, "datetime", + (PyObject *)&PyDateTime_DateTimeType); + + Py_INCREF(&PyDateTime_TimeType); + PyModule_AddObject(m, "time", (PyObject *) &PyDateTime_TimeType); + + Py_INCREF(&PyDateTime_DeltaType); + PyModule_AddObject(m, "timedelta", (PyObject *) &PyDateTime_DeltaType); + + Py_INCREF(&PyDateTime_TZInfoType); + PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); + + Py_INCREF(&PyDateTime_TimeZoneType); + PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType); + + 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/python/Modules/_dbmmodule.c b/python/Modules/_dbmmodule.c new file mode 100755 index 0000000..d46c3c6 --- /dev/null +++ b/python/Modules/_dbmmodule.c @@ -0,0 +1,521 @@ + +// /* DBM module using dictionary interface */ + + +// #define PY_SSIZE_T_CLEAN +// #include "Python.h" + +// #include +// #include +// #include + +// /* Some Linux systems install gdbm/ndbm.h, but not ndbm.h. This supports +// * whichever configure was able to locate. +// */ +// #if defined(HAVE_NDBM_H) +// #include +// static const char which_dbm[] = "GNU gdbm"; /* EMX port of GDBM */ +// #elif defined(HAVE_GDBM_NDBM_H) +// #include +// static const char which_dbm[] = "GNU gdbm"; +// #elif defined(HAVE_GDBM_DASH_NDBM_H) +// #include +// static const char which_dbm[] = "GNU gdbm"; +// #elif defined(HAVE_BERKDB_H) +// #include +// static const char which_dbm[] = "Berkeley DB"; +// #else +// #error "No ndbm.h available!" +// #endif + +// /*[clinic input] +// module _dbm +// class _dbm.dbm "dbmobject *" "&Dbmtype" +// [clinic start generated code]*/ +// /*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b1aa8756d16150e]*/ + +// typedef struct { +// PyObject_HEAD +// int flags; +// int di_size; /* -1 means recompute */ +// DBM *di_dbm; +// } dbmobject; + +// #include "clinic/_dbmmodule.c.h" + +// static PyTypeObject Dbmtype; + +// #define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype) +// #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \ +// { PyErr_SetString(DbmError, "DBM object has already been closed"); \ +// return NULL; } + +// static PyObject *DbmError; + +// static PyObject * +// newdbmobject(const char *file, int flags, int mode) +// { +// dbmobject *dp; + +// dp = PyObject_New(dbmobject, &Dbmtype); +// if (dp == NULL) +// return NULL; +// dp->di_size = -1; +// dp->flags = flags; +// /* See issue #19296 */ +// if ( (dp->di_dbm = dbm_open((char *)file, flags, mode)) == 0 ) { +// PyErr_SetFromErrnoWithFilename(DbmError, file); +// Py_DECREF(dp); +// return NULL; +// } +// return (PyObject *)dp; +// } + +// /* Methods */ + +// static void +// dbm_dealloc(dbmobject *dp) +// { +// if ( dp->di_dbm ) +// dbm_close(dp->di_dbm); +// PyObject_Del(dp); +// } + +// static Py_ssize_t +// dbm_length(dbmobject *dp) +// { +// if (dp->di_dbm == NULL) { +// PyErr_SetString(DbmError, "DBM object has already been closed"); +// return -1; +// } +// if ( dp->di_size < 0 ) { +// datum key; +// int size; + +// size = 0; +// for ( key=dbm_firstkey(dp->di_dbm); key.dptr; +// key = dbm_nextkey(dp->di_dbm)) +// size++; +// dp->di_size = size; +// } +// return dp->di_size; +// } + +// static PyObject * +// dbm_subscript(dbmobject *dp, PyObject *key) +// { +// datum drec, krec; +// Py_ssize_t tmp_size; + +// if (!PyArg_Parse(key, "s#", &krec.dptr, &tmp_size) ) +// return NULL; + +// krec.dsize = tmp_size; +// check_dbmobject_open(dp); +// drec = dbm_fetch(dp->di_dbm, krec); +// if ( drec.dptr == 0 ) { +// PyErr_SetObject(PyExc_KeyError, key); +// return NULL; +// } +// if ( dbm_error(dp->di_dbm) ) { +// dbm_clearerr(dp->di_dbm); +// PyErr_SetString(DbmError, ""); +// return NULL; +// } +// return PyBytes_FromStringAndSize(drec.dptr, drec.dsize); +// } + +// static int +// dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w) +// { +// datum krec, drec; +// Py_ssize_t tmp_size; + +// if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) { +// PyErr_SetString(PyExc_TypeError, +// "dbm mappings have bytes or string keys only"); +// return -1; +// } +// krec.dsize = tmp_size; +// if (dp->di_dbm == NULL) { +// PyErr_SetString(DbmError, "DBM object has already been closed"); +// return -1; +// } +// dp->di_size = -1; +// if (w == NULL) { +// if ( dbm_delete(dp->di_dbm, krec) < 0 ) { +// dbm_clearerr(dp->di_dbm); +// /* we might get a failure for reasons like file corrupted, +// but we are not able to distinguish it */ +// if (dp->flags & O_RDWR) { +// PyErr_SetObject(PyExc_KeyError, v); +// } +// else { +// PyErr_SetString(DbmError, "cannot delete item from database"); +// } +// return -1; +// } +// } else { +// if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) { +// PyErr_SetString(PyExc_TypeError, +// "dbm mappings have bytes or string elements only"); +// return -1; +// } +// drec.dsize = tmp_size; +// if ( dbm_store(dp->di_dbm, krec, drec, DBM_REPLACE) < 0 ) { +// dbm_clearerr(dp->di_dbm); +// PyErr_SetString(DbmError, +// "cannot add item to database"); +// return -1; +// } +// } +// if ( dbm_error(dp->di_dbm) ) { +// dbm_clearerr(dp->di_dbm); +// PyErr_SetString(DbmError, ""); +// return -1; +// } +// return 0; +// } + +// static PyMappingMethods dbm_as_mapping = { +// (lenfunc)dbm_length, /*mp_length*/ +// (binaryfunc)dbm_subscript, /*mp_subscript*/ +// (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/ +// }; + +// /*[clinic input] +// _dbm.dbm.close + +// Close the database. +// [clinic start generated code]*/ + +// static PyObject * +// _dbm_dbm_close_impl(dbmobject *self) +// /*[clinic end generated code: output=c8dc5b6709600b86 input=046db72377d51be8]*/ +// { +// if (self->di_dbm) +// dbm_close(self->di_dbm); +// self->di_dbm = NULL; +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _dbm.dbm.keys + +// Return a list of all keys in the database. +// [clinic start generated code]*/ + +// static PyObject * +// _dbm_dbm_keys_impl(dbmobject *self) +// /*[clinic end generated code: output=434549f7c121b33c input=d210ba778cd9c68a]*/ +// { +// PyObject *v, *item; +// datum key; +// int err; + +// check_dbmobject_open(self); +// v = PyList_New(0); +// if (v == NULL) +// return NULL; +// for (key = dbm_firstkey(self->di_dbm); key.dptr; +// key = dbm_nextkey(self->di_dbm)) { +// item = PyBytes_FromStringAndSize(key.dptr, key.dsize); +// if (item == NULL) { +// Py_DECREF(v); +// return NULL; +// } +// err = PyList_Append(v, item); +// Py_DECREF(item); +// if (err != 0) { +// Py_DECREF(v); +// return NULL; +// } +// } +// return v; +// } + +// static int +// dbm_contains(PyObject *self, PyObject *arg) +// { +// dbmobject *dp = (dbmobject *)self; +// datum key, val; +// Py_ssize_t size; + +// if ((dp)->di_dbm == NULL) { +// PyErr_SetString(DbmError, +// "DBM object has already been closed"); +// return -1; +// } +// if (PyUnicode_Check(arg)) { +// key.dptr = (char *)PyUnicode_AsUTF8AndSize(arg, &size); +// key.dsize = size; +// if (key.dptr == NULL) +// return -1; +// } +// else if (!PyBytes_Check(arg)) { +// PyErr_Format(PyExc_TypeError, +// "dbm key must be bytes or string, not %.100s", +// arg->ob_type->tp_name); +// return -1; +// } +// else { +// key.dptr = PyBytes_AS_STRING(arg); +// key.dsize = PyBytes_GET_SIZE(arg); +// } +// val = dbm_fetch(dp->di_dbm, key); +// return val.dptr != NULL; +// } + +// static PySequenceMethods dbm_as_sequence = { +// 0, /* sq_length */ +// 0, /* sq_concat */ +// 0, /* sq_repeat */ +// 0, /* sq_item */ +// 0, /* sq_slice */ +// 0, /* sq_ass_item */ +// 0, /* sq_ass_slice */ +// dbm_contains, /* sq_contains */ +// 0, /* sq_inplace_concat */ +// 0, /* sq_inplace_repeat */ +// }; + +// /*[clinic input] +// _dbm.dbm.get + +// key: str(accept={str, robuffer}, zeroes=True) +// default: object = None +// / + +// Return the value for key if present, otherwise default. +// [clinic start generated code]*/ + +// static PyObject * +// _dbm_dbm_get_impl(dbmobject *self, const char *key, +// Py_ssize_clean_t key_length, PyObject *default_value) +// /*[clinic end generated code: output=b44f95eba8203d93 input=b788eba0ffad2e91]*/ +// /*[clinic end generated code: output=4f5c0e523eaf1251 input=9402c0af8582dc69]*/ +// { +// datum dbm_key, val; + +// dbm_key.dptr = (char *)key; +// dbm_key.dsize = key_length; +// check_dbmobject_open(self); +// val = dbm_fetch(self->di_dbm, dbm_key); +// if (val.dptr != NULL) +// return PyBytes_FromStringAndSize(val.dptr, val.dsize); + +// Py_INCREF(default_value); +// return default_value; +// } + +// /*[clinic input] +// _dbm.dbm.setdefault +// key: str(accept={str, robuffer}, zeroes=True) +// default: object(c_default="NULL") = b'' +// / + +// Return the value for key if present, otherwise default. + +// If key is not in the database, it is inserted with default as the value. +// [clinic start generated code]*/ + +// static PyObject * +// _dbm_dbm_setdefault_impl(dbmobject *self, const char *key, +// Py_ssize_clean_t key_length, +// PyObject *default_value) +// /*[clinic end generated code: output=52545886cf272161 input=bf40c48edaca01d6]*/ +// { +// datum dbm_key, val; +// Py_ssize_t tmp_size; + +// dbm_key.dptr = (char *)key; +// dbm_key.dsize = key_length; +// check_dbmobject_open(self); +// val = dbm_fetch(self->di_dbm, dbm_key); +// if (val.dptr != NULL) +// return PyBytes_FromStringAndSize(val.dptr, val.dsize); +// if (default_value == NULL) { +// default_value = PyBytes_FromStringAndSize(NULL, 0); +// if (default_value == NULL) +// return NULL; +// val.dptr = NULL; +// val.dsize = 0; +// } +// else { +// if ( !PyArg_Parse(default_value, "s#", &val.dptr, &tmp_size) ) { +// PyErr_SetString(PyExc_TypeError, +// "dbm mappings have bytes or string elements only"); +// return NULL; +// } +// val.dsize = tmp_size; +// Py_INCREF(default_value); +// } +// if (dbm_store(self->di_dbm, dbm_key, val, DBM_INSERT) < 0) { +// dbm_clearerr(self->di_dbm); +// PyErr_SetString(DbmError, "cannot add item to database"); +// Py_DECREF(default_value); +// return NULL; +// } +// return default_value; +// } + +// static PyObject * +// dbm__enter__(PyObject *self, PyObject *args) +// { +// Py_INCREF(self); +// return self; +// } + +// static PyObject * +// dbm__exit__(PyObject *self, PyObject *args) +// { +// _Py_IDENTIFIER(close); +// return _PyObject_CallMethodId(self, &PyId_close, NULL); +// } + + +// static PyMethodDef dbm_methods[] = { +// _DBM_DBM_CLOSE_METHODDEF +// _DBM_DBM_KEYS_METHODDEF +// _DBM_DBM_GET_METHODDEF +// _DBM_DBM_SETDEFAULT_METHODDEF +// {"__enter__", dbm__enter__, METH_NOARGS, NULL}, +// {"__exit__", dbm__exit__, METH_VARARGS, NULL}, +// {NULL, NULL} /* sentinel */ +// }; + +// static PyTypeObject Dbmtype = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "_dbm.dbm", +// sizeof(dbmobject), +// 0, +// (destructor)dbm_dealloc, /*tp_dealloc*/ +// 0, /*tp_vectorcall_offset*/ +// 0, /*tp_getattr*/ +// 0, /*tp_setattr*/ +// 0, /*tp_as_async*/ +// 0, /*tp_repr*/ +// 0, /*tp_as_number*/ +// &dbm_as_sequence, /*tp_as_sequence*/ +// &dbm_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*/ +// 0, /*tp_doc*/ +// 0, /*tp_traverse*/ +// 0, /*tp_clear*/ +// 0, /*tp_richcompare*/ +// 0, /*tp_weaklistoffset*/ +// 0, /*tp_iter*/ +// 0, /*tp_iternext*/ +// dbm_methods, /*tp_methods*/ +// }; + +// /* ----------------------------------------------------------------- */ + +// /*[clinic input] + +// _dbm.open as dbmopen + +// filename: unicode +// The filename to open. + +// flags: str="r" +// How to open the file. "r" for reading, "w" for writing, etc. + +// mode: int(py_default="0o666") = 0o666 +// If creating a new file, the mode bits for the new file +// (e.g. os.O_RDWR). + +// / + +// Return a database object. + +// [clinic start generated code]*/ + +// static PyObject * +// dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, +// int mode) +// /*[clinic end generated code: output=9527750f5df90764 input=376a9d903a50df59]*/ +// { +// int iflags; + +// if ( strcmp(flags, "r") == 0 ) +// iflags = O_RDONLY; +// else if ( strcmp(flags, "w") == 0 ) +// iflags = O_RDWR; +// else if ( strcmp(flags, "rw") == 0 ) /* B/W compat */ +// iflags = O_RDWR|O_CREAT; +// else if ( strcmp(flags, "c") == 0 ) +// iflags = O_RDWR|O_CREAT; +// else if ( strcmp(flags, "n") == 0 ) +// iflags = O_RDWR|O_CREAT|O_TRUNC; +// else { +// PyErr_SetString(DbmError, +// "arg 2 to open should be 'r', 'w', 'c', or 'n'"); +// return NULL; +// } + +// PyObject *filenamebytes = PyUnicode_EncodeFSDefault(filename); +// if (filenamebytes == NULL) { +// return NULL; +// } +// const char *name = PyBytes_AS_STRING(filenamebytes); +// if (strlen(name) != (size_t)PyBytes_GET_SIZE(filenamebytes)) { +// Py_DECREF(filenamebytes); +// PyErr_SetString(PyExc_ValueError, "embedded null character"); +// return NULL; +// } +// PyObject *self = newdbmobject(name, iflags, mode); +// Py_DECREF(filenamebytes); +// return self; +// } + +// static PyMethodDef dbmmodule_methods[] = { +// DBMOPEN_METHODDEF +// { 0, 0 }, +// }; + + +// static struct PyModuleDef _dbmmodule = { +// PyModuleDef_HEAD_INIT, +// "_dbm", +// NULL, +// -1, +// dbmmodule_methods, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit__dbm(void) { +// PyObject *m, *d, *s; + +// if (PyType_Ready(&Dbmtype) < 0) +// return NULL; +// m = PyModule_Create(&_dbmmodule); +// if (m == NULL) +// return NULL; +// d = PyModule_GetDict(m); +// if (DbmError == NULL) +// DbmError = PyErr_NewException("_dbm.error", +// PyExc_OSError, NULL); +// s = PyUnicode_FromString(which_dbm); +// if (s != NULL) { +// PyDict_SetItemString(d, "library", s); +// Py_DECREF(s); +// } +// if (DbmError != NULL) +// PyDict_SetItemString(d, "error", DbmError); +// if (PyErr_Occurred()) { +// Py_DECREF(m); +// m = NULL; +// } +// return m; +// } diff --git a/python/Modules/_decimal/README.txt b/python/Modules/_decimal/README.txt new file mode 100755 index 0000000..7eae0f8 --- /dev/null +++ b/python/Modules/_decimal/README.txt @@ -0,0 +1,46 @@ + + +About +===== + +_decimal.c is a wrapper for the libmpdec library. libmpdec is a fast C +library for correctly-rounded arbitrary precision decimal floating point +arithmetic. It is a complete implementation of Mike Cowlishaw/IBM's +General Decimal Arithmetic Specification. + + +Build process for the module +============================ + +As usual, the build process for _decimal.so is driven by setup.py in the top +level directory. setup.py autodetects the following build configurations: + + 1) x64 - 64-bit Python, x86_64 processor (AMD, Intel) + + 2) uint128 - 64-bit Python, compiler provides __uint128_t (gcc) + + 3) ansi64 - 64-bit Python, ANSI C + + 4) ppro - 32-bit Python, x86 CPU, PentiumPro or later + + 5) ansi32 - 32-bit Python, ANSI C + + 6) ansi-legacy - 32-bit Python, compiler without uint64_t + + 7) universal - Mac OS only (multi-arch) + + +It is possible to override autodetection by exporting: + + PYTHON_DECIMAL_WITH_MACHINE=value, where value is one of the above options. + + +NOTE +==== + +decimal.so is not built from a static libmpdec.a since doing so led to +failures on AIX (user report) and Windows (mixing static and dynamic CRTs +causes locale problems and more). + + + diff --git a/python/Modules/_decimal/_decimal.c b/python/Modules/_decimal/_decimal.c new file mode 100755 index 0000000..eb1f1a0 --- /dev/null +++ b/python/Modules/_decimal/_decimal.c @@ -0,0 +1,5934 @@ +/* + * 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 "pythread.h" +#include "structmember.h" +#include "complexobject.h" +#include "mpdecimal.h" + +#include + +#include "docstrings.h" + + +#if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02040100 + #error "libmpdec version >= 2.4.1 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 + +#ifndef UNUSED +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) + #define UNUSED __attribute__((unused)) +#else + #define UNUSED +#endif +#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; +#define PyDec_CheckExact(v) (Py_TYPE(v) == &PyDec_Type) +#define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type) +#define PyDecSignalDict_Check(v) (Py_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; +} + + +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Key for thread state dictionary */ +static PyObject *tls_context_key = NULL; +/* Invariant: NULL or the most recently accessed thread local context */ +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; + } + } + + 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| + Py_TPFLAGS_HAVE_GC, /* 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, 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; + 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", + v->ob_type->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", + v->ob_type->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", + v->ob_type->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_SIZE(pylong) = i; + if (mpd_isnegative(x) && !mpd_iszero(x)) { + Py_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 */ + 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 */ + 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}, + { "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)); + +#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); + 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 */ +#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 */ +} + + diff --git a/python/Modules/_decimal/docstrings.h b/python/Modules/_decimal/docstrings.h new file mode 100755 index 0000000..f7fd6e7 --- /dev/null +++ b/python/Modules/_decimal/docstrings.h @@ -0,0 +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 */ + + + diff --git a/python/Modules/_decimal/libmpdec/README.txt b/python/Modules/_decimal/libmpdec/README.txt new file mode 100755 index 0000000..96b7223 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/README.txt @@ -0,0 +1,90 @@ + + +libmpdec +======== + +libmpdec is a fast C/C++ library for correctly-rounded arbitrary precision +decimal floating point arithmetic. It is a complete implementation of +Mike Cowlishaw/IBM's General Decimal Arithmetic Specification. + + +Files required for the Python _decimal module +============================================= + + Core files for small and medium precision arithmetic + ---------------------------------------------------- + + basearith.{c,h} -> Core arithmetic in base 10**9 or 10**19. + bits.h -> Portable detection of least/most significant one-bit. + constants.{c,h} -> Constants that are used in multiple files. + context.c -> Context functions. + io.{c,h} -> Conversions between mpd_t and ASCII strings, + mpd_t formatting (allows UTF-8 fill character). + memory.{c,h} -> Allocation handlers with overflow detection + and functions for switching between static + and dynamic mpd_t. + mpdecimal.{c,h} -> All (quiet) functions of the specification. + typearith.h -> Fast primitives for double word multiplication, + division etc. + + Visual Studio only: + ~~~~~~~~~~~~~~~~~~~ + vccompat.h -> snprintf <==> sprintf_s and similar things. + vcstdint.h -> stdint.h (included in VS 2010 but not in VS 2008). + vcdiv64.asm -> Double word division used in typearith.h. VS 2008 does + not allow inline asm for x64. Also, it does not provide + an intrinsic for double word division. + + Files for bignum arithmetic: + ---------------------------- + + The following files implement the Fast Number Theoretic Transform + used for multiplying coefficients with more than 1024 words (see + mpdecimal.c: _mpd_fntmul()). + + umodarith.h -> Fast low level routines for unsigned modular arithmetic. + numbertheory.{c,h} -> Routines for setting up the Number Theoretic Transform. + difradix2.{c,h} -> Decimation in frequency transform, used as the + "base case" by the following three files: + + fnt.{c,h} -> Transform arrays up to 4096 words. + sixstep.{c,h} -> Transform larger arrays of length 2**n. + fourstep.{c,h} -> Transform larger arrays of length 3 * 2**n. + + convolute.{c,h} -> Fast convolution using one of the three transform + functions. + transpose.{c,h} -> Transpositions needed for the sixstep algorithm. + crt.{c,h} -> Chinese Remainder Theorem: use information from three + transforms modulo three different primes to get the + final result. + + +Pointers to literature, proofs and more +======================================= + + literature/ + ----------- + + REFERENCES.txt -> List of relevant papers. + bignum.txt -> Explanation of the Fast Number Theoretic Transform (FNT). + fnt.py -> Verify constants used in the FNT; Python demo for the + O(N**2) discrete transform. + + matrix-transform.txt -> Proof for the Matrix Fourier Transform used in + fourstep.c. + six-step.txt -> Show that the algorithm used in sixstep.c is + a variant of the Matrix Fourier Transform. + mulmod-64.txt -> Proof for the mulmod64 algorithm from + umodarith.h. + mulmod-ppro.txt -> Proof for the x87 FPU modular multiplication + from umodarith.h. + umodarith.lisp -> ACL2 proofs for many functions from umodarith.h. + + +Library Author +============== + + Stefan Krah + + + diff --git a/python/Modules/_decimal/libmpdec/basearith.c b/python/Modules/_decimal/libmpdec/basearith.c new file mode 100755 index 0000000..dfe1523 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/basearith.c @@ -0,0 +1,657 @@ +/* + * Copyright (c) 2008-2016 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 +#include +#include +#include "constants.h" +#include "typearith.h" +#include "basearith.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--) { + + /* 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/python/Modules/_decimal/libmpdec/basearith.h b/python/Modules/_decimal/libmpdec/basearith.h new file mode 100755 index 0000000..976358a --- /dev/null +++ b/python/Modules/_decimal/libmpdec/basearith.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef BASEARITH_H +#define BASEARITH_H + + +#include "mpdecimal.h" +#include +#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 /* BASEARITH_H */ + + + diff --git a/python/Modules/_decimal/libmpdec/bits.h b/python/Modules/_decimal/libmpdec/bits.h new file mode 100755 index 0000000..b5eaa24 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/bits.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef BITS_H +#define BITS_H + + +#include "mpdecimal.h" +#include + + +/* 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 /* BITS_H */ + + + diff --git a/python/Modules/_decimal/libmpdec/constants.c b/python/Modules/_decimal/libmpdec/constants.c new file mode 100755 index 0000000..2c2d5ea --- /dev/null +++ b/python/Modules/_decimal/libmpdec/constants.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2008-2016 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 "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/python/Modules/_decimal/libmpdec/constants.h b/python/Modules/_decimal/libmpdec/constants.h new file mode 100755 index 0000000..c0febfc --- /dev/null +++ b/python/Modules/_decimal/libmpdec/constants.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef CONSTANTS_H +#define CONSTANTS_H + + +#include "mpdecimal.h" + + +/* 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 /* CONSTANTS_H */ + + + diff --git a/python/Modules/_decimal/libmpdec/context.c b/python/Modules/_decimal/libmpdec/context.c new file mode 100755 index 0000000..24c7b89 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/context.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2008-2016 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 +#include + + +void +mpd_dflt_traphandler(mpd_context_t *ctx UNUSED) +{ + 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/python/Modules/_decimal/libmpdec/convolute.c b/python/Modules/_decimal/libmpdec/convolute.c new file mode 100755 index 0000000..4c62e8b --- /dev/null +++ b/python/Modules/_decimal/libmpdec/convolute.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2008-2016 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" +#include "constants.h" +#include "fnt.h" +#include "fourstep.h" +#include "numbertheory.h" +#include "sixstep.h" +#include "umodarith.h" +#include "convolute.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/python/Modules/_decimal/libmpdec/convolute.h b/python/Modules/_decimal/libmpdec/convolute.h new file mode 100755 index 0000000..f30a177 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/convolute.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef CONVOLUTE_H +#define CONVOLUTE_H + + +#include "mpdecimal.h" +#include + + +/* 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 diff --git a/python/Modules/_decimal/libmpdec/crt.c b/python/Modules/_decimal/libmpdec/crt.c new file mode 100755 index 0000000..4a1e80a --- /dev/null +++ b/python/Modules/_decimal/libmpdec/crt.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2008-2016 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 +#include "numbertheory.h" +#include "umodarith.h" +#include "crt.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); +} + + diff --git a/python/Modules/_decimal/libmpdec/crt.h b/python/Modules/_decimal/libmpdec/crt.h new file mode 100755 index 0000000..f61e772 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/crt.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef CRT_H +#define CRT_H + + +#include "mpdecimal.h" +#include + + +/* 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 diff --git a/python/Modules/_decimal/libmpdec/difradix2.c b/python/Modules/_decimal/libmpdec/difradix2.c new file mode 100755 index 0000000..06e5ab5 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/difradix2.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2008-2016 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 +#include "bits.h" +#include "numbertheory.h" +#include "umodarith.h" +#include "difradix2.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/python/Modules/_decimal/libmpdec/difradix2.h b/python/Modules/_decimal/libmpdec/difradix2.h new file mode 100755 index 0000000..5e22bcf --- /dev/null +++ b/python/Modules/_decimal/libmpdec/difradix2.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef DIF_RADIX2_H +#define DIF_RADIX2_H + + +#include "mpdecimal.h" +#include +#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 diff --git a/python/Modules/_decimal/libmpdec/fnt.c b/python/Modules/_decimal/libmpdec/fnt.c new file mode 100755 index 0000000..7e924c8 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/fnt.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008-2016 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 +#include +#include "bits.h" +#include "difradix2.h" +#include "numbertheory.h" +#include "fnt.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/python/Modules/_decimal/libmpdec/fnt.h b/python/Modules/_decimal/libmpdec/fnt.h new file mode 100755 index 0000000..fa2154a --- /dev/null +++ b/python/Modules/_decimal/libmpdec/fnt.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef FNT_H +#define FNT_H + + +#include "mpdecimal.h" +#include + + +/* 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 + diff --git a/python/Modules/_decimal/libmpdec/fourstep.c b/python/Modules/_decimal/libmpdec/fourstep.c new file mode 100755 index 0000000..21d3e74 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/fourstep.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2008-2016 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 "numbertheory.h" +#include "sixstep.h" +#include "transpose.h" +#include "umodarith.h" +#include "fourstep.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= 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, 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 + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +int four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); +int inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + +#endif diff --git a/python/Modules/_decimal/libmpdec/io.c b/python/Modules/_decimal/libmpdec/io.c new file mode 100755 index 0000000..f45e558 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/io.c @@ -0,0 +1,1583 @@ +/* + * Copyright (c) 2008-2016 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 +#include +#include +#include +#include +#include +#include +#include "bits.h" +#include "constants.h" +#include "typearith.h" +#include "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 (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); +} + +/* 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)) { + type = 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; + } + 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/python/Modules/_decimal/libmpdec/io.h b/python/Modules/_decimal/libmpdec/io.h new file mode 100755 index 0000000..de5486a --- /dev/null +++ b/python/Modules/_decimal/libmpdec/io.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef IO_H +#define IO_H + + +#include +#include "mpdecimal.h" + + +#if SIZE_MAX == MPD_SIZE_MAX + #define mpd_strtossize _mpd_strtossize +#else +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 diff --git a/python/Modules/_decimal/libmpdec/literature/REFERENCES.txt b/python/Modules/_decimal/libmpdec/literature/REFERENCES.txt new file mode 100755 index 0000000..9ed5782 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/REFERENCES.txt @@ -0,0 +1,51 @@ + + +This document contains links to the literature used in the process of +creating the library. The list is probably not complete. + + +Mike Cowlishaw: General Decimal Arithmetic Specification +http://speleotrove.com/decimal/decarith.html + + +Jean-Michel Muller: On the definition of ulp (x) +lara.inist.fr/bitstream/2332/518/1/LIP-RR2005-09.pdf + + +T. E. Hull, A. Abrham: Properly rounded variable precision square root +http://portal.acm.org/citation.cfm?id=214413 + + +T. E. Hull, A. Abrham: Variable precision exponential function +http://portal.acm.org/citation.cfm?id=6498 + + +Roman E. Maeder: Storage allocation for the Karatsuba integer multiplication +algorithm. http://www.springerlink.com/content/w15058mj6v59t565/ + + +J. M. Pollard: The fast Fourier transform in a finite field +http://www.ams.org/journals/mcom/1971-25-114/S0025-5718-1971-0301966-0/home.html + + +David H. Bailey: FFTs in External or Hierarchical Memory +http://crd.lbl.gov/~dhbailey/dhbpapers/ + + +W. Morven Gentleman: Matrix Multiplication and Fast Fourier Transforms +http://www.alcatel-lucent.com/bstj/vol47-1968/articles/bstj47-6-1099.pdf + + +Mikko Tommila: Apfloat documentation +http://www.apfloat.org/apfloat/2.41/apfloat.pdf + + +Joerg Arndt: "Matters Computational" +http://www.jjj.de/fxt/ + + +Karl Hasselstrom: Fast Division of Large Integers +www.treskal.com/kalle/exjobb/original-report.pdf + + + diff --git a/python/Modules/_decimal/libmpdec/literature/bignum.txt b/python/Modules/_decimal/libmpdec/literature/bignum.txt new file mode 100755 index 0000000..f34ff67 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/bignum.txt @@ -0,0 +1,83 @@ + + +Bignum support (Fast Number Theoretic Transform or FNT): +======================================================== + +Bignum arithmetic in libmpdec uses the scheme for fast convolution +of integer sequences from: + +J. M. Pollard: The fast Fourier transform in a finite field +http://www.ams.org/journals/mcom/1971-25-114/S0025-5718-1971-0301966-0/home.html + + +The transform in a finite field can be used for convolution in the same +way as the Fourier Transform. The main advantages of the Number Theoretic +Transform are that it is both exact and very memory efficient. + + +Convolution in pseudo-code: +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + fnt_convolute(a, b): + x = fnt(a) # forward transform of a + y = fnt(b) # forward transform of b + z = pairwise multiply x[i] and y[i] + result = inv_fnt(z) # backward transform of z. + + +Extending the maximum transform length (Chinese Remainder Theorem): +------------------------------------------------------------------- + +The maximum transform length is quite limited when using a single +prime field. However, it is possible to use multiple primes and +recover the result using the Chinese Remainder Theorem. + + +Multiplication in pseudo-code: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + _mpd_fntmul(u, v): + c1 = fnt_convolute(u, v, P1) # convolute modulo prime1 + c2 = fnt_convolute(u, v, P2) # convolute modulo prime2 + c3 = fnt_convolute(u, v, P3) # convolute modulo prime3 + result = crt3(c1, c2, c3) # Chinese Remainder Theorem + + +Optimized transform functions: +------------------------------ + +There are three different fnt() functions: + + std_fnt: "standard" decimation in frequency transform for array lengths + of 2**n. Performs well up to 1024 words. + + sixstep: Cache-friendly algorithm for array lengths of 2**n. Outperforms + std_fnt for large arrays. + + fourstep: Algorithm for array lengths of 3 * 2**n. Also cache friendly + in large parts. + + +List of bignum-only files: +-------------------------- + +Functions from these files are only used in _mpd_fntmul(). + + umodarith.h -> fast low level routines for unsigned modular arithmetic + numbertheory.c -> routines for setting up the FNT + difradix2.c -> decimation in frequency transform, used as the + "base case" by the following three files: + + fnt.c -> standard transform for smaller arrays + sixstep.c -> transform large arrays of length 2**n + fourstep.c -> transform arrays of length 3 * 2**n + + convolute.c -> do the actual fast convolution, using one of + the three transform functions. + transpose.c -> transpositions needed for the sixstep algorithm. + crt.c -> Chinese Remainder Theorem: use information from three + transforms modulo three different primes to get the + final result. + + + diff --git a/python/Modules/_decimal/libmpdec/literature/fnt.py b/python/Modules/_decimal/libmpdec/literature/fnt.py new file mode 100755 index 0000000..6363536 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/fnt.py @@ -0,0 +1,208 @@ +# +# Copyright (c) 2008-2016 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. +# + + +###################################################################### +# This file lists and checks some of the constants and limits used # +# in libmpdec's Number Theoretic Transform. At the end of the file # +# there is an example function for the plain DFT transform. # +###################################################################### + + +# +# Number theoretic transforms are done in subfields of F(p). P[i] +# are the primes, D[i] = P[i] - 1 are highly composite and w[i] +# are the respective primitive roots of F(p). +# +# The strategy is to convolute two coefficients modulo all three +# primes, then use the Chinese Remainder Theorem on the three +# result arrays to recover the result in the usual base RADIX +# form. +# + +# ====================================================================== +# Primitive roots +# ====================================================================== + +# +# Verify primitive roots: +# +# For a prime field, r is a primitive root if and only if for all prime +# factors f of p-1, r**((p-1)/f) =/= 1 (mod p). +# +def prod(F, E): + """Check that the factorization of P-1 is correct. F is the list of + factors of P-1, E lists the number of occurrences of each factor.""" + x = 1 + for y, z in zip(F, E): + x *= y**z + return x + +def is_primitive_root(r, p, factors, exponents): + """Check if r is a primitive root of F(p).""" + if p != prod(factors, exponents) + 1: + return False + for f in factors: + q, control = divmod(p-1, f) + if control != 0: + return False + if pow(r, q, p) == 1: + return False + return True + + +# ================================================================= +# Constants and limits for the 64-bit version +# ================================================================= + +RADIX = 10**19 + +# Primes P1, P2 and P3: +P = [2**64-2**32+1, 2**64-2**34+1, 2**64-2**40+1] + +# P-1, highly composite. The transform length d is variable and +# must divide D = P-1. Since all D are divisible by 3 * 2**32, +# transform lengths can be 2**n or 3 * 2**n (where n <= 32). +D = [2**32 * 3 * (5 * 17 * 257 * 65537), + 2**34 * 3**2 * (7 * 11 * 31 * 151 * 331), + 2**40 * 3**2 * (5 * 7 * 13 * 17 * 241)] + +# Prime factors of P-1 and their exponents: +F = [(2,3,5,17,257,65537), (2,3,7,11,31,151,331), (2,3,5,7,13,17,241)] +E = [(32,1,1,1,1,1), (34,2,1,1,1,1,1), (40,2,1,1,1,1,1)] + +# Maximum transform length for 2**n. Above that only 3 * 2**31 +# or 3 * 2**32 are possible. +MPD_MAXTRANSFORM_2N = 2**32 + + +# Limits in the terminology of Pollard's paper: +m2 = (MPD_MAXTRANSFORM_2N * 3) // 2 # Maximum length of the smaller array. +M1 = M2 = RADIX-1 # Maximum value per single word. +L = m2 * M1 * M2 +P[0] * P[1] * P[2] > 2 * L + + +# Primitive roots of F(P1), F(P2) and F(P3): +w = [7, 10, 19] + +# The primitive roots are correct: +for i in range(3): + if not is_primitive_root(w[i], P[i], F[i], E[i]): + print("FAIL") + + +# ================================================================= +# Constants and limits for the 32-bit version +# ================================================================= + +RADIX = 10**9 + +# Primes P1, P2 and P3: +P = [2113929217, 2013265921, 1811939329] + +# P-1, highly composite. All D = P-1 are divisible by 3 * 2**25, +# allowing for transform lengths up to 3 * 2**25 words. +D = [2**25 * 3**2 * 7, + 2**27 * 3 * 5, + 2**26 * 3**3] + +# Prime factors of P-1 and their exponents: +F = [(2,3,7), (2,3,5), (2,3)] +E = [(25,2,1), (27,1,1), (26,3)] + +# Maximum transform length for 2**n. Above that only 3 * 2**24 or +# 3 * 2**25 are possible. +MPD_MAXTRANSFORM_2N = 2**25 + + +# Limits in the terminology of Pollard's paper: +m2 = (MPD_MAXTRANSFORM_2N * 3) // 2 # Maximum length of the smaller array. +M1 = M2 = RADIX-1 # Maximum value per single word. +L = m2 * M1 * M2 +P[0] * P[1] * P[2] > 2 * L + + +# Primitive roots of F(P1), F(P2) and F(P3): +w = [5, 31, 13] + +# The primitive roots are correct: +for i in range(3): + if not is_primitive_root(w[i], P[i], F[i], E[i]): + print("FAIL") + + +# ====================================================================== +# Example transform using a single prime +# ====================================================================== + +def ntt(lst, dir): + """Perform a transform on the elements of lst. len(lst) must + be 2**n or 3 * 2**n, where n <= 25. This is the slow DFT.""" + p = 2113929217 # prime + d = len(lst) # transform length + d_prime = pow(d, (p-2), p) # inverse of d + xi = (p-1)//d + w = 5 # primitive root of F(p) + r = pow(w, xi, p) # primitive root of the subfield + r_prime = pow(w, (p-1-xi), p) # inverse of r + if dir == 1: # forward transform + a = lst # input array + A = [0] * d # transformed values + for i in range(d): + s = 0 + for j in range(d): + s += a[j] * pow(r, i*j, p) + A[i] = s % p + return A + elif dir == -1: # backward transform + A = lst # input array + a = [0] * d # transformed values + for j in range(d): + s = 0 + for i in range(d): + s += A[i] * pow(r_prime, i*j, p) + a[j] = (d_prime * s) % p + return a + +def ntt_convolute(a, b): + """convolute arrays a and b.""" + assert(len(a) == len(b)) + x = ntt(a, 1) + y = ntt(b, 1) + for i in range(len(a)): + y[i] = y[i] * x[i] + r = ntt(y, -1) + return r + + +# Example: Two arrays representing 21 and 81 in little-endian: +a = [1, 2, 0, 0] +b = [1, 8, 0, 0] + +assert(ntt_convolute(a, b) == [1, 10, 16, 0]) +assert(21 * 81 == (1*10**0 + 10*10**1 + 16*10**2 + 0*10**3)) diff --git a/python/Modules/_decimal/libmpdec/literature/matrix-transform.txt b/python/Modules/_decimal/libmpdec/literature/matrix-transform.txt new file mode 100755 index 0000000..701d85d --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/matrix-transform.txt @@ -0,0 +1,256 @@ + + +(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) + + +The Matrix Fourier Transform: +============================= + +In libmpdec, the Matrix Fourier Transform [1] is called four-step transform +after a variant that appears in [2]. The algorithm requires that the input +array can be viewed as an R*C matrix. + +All operations are done modulo p. For readability, the proofs drop all +instances of (mod p). + + +Algorithm four-step (forward transform): +---------------------------------------- + + a := input array + d := len(a) = R * C + p := prime + w := primitive root of unity of the prime field + r := w**((p-1)/d) + A := output array + + 1) Apply a length R FNT to each column. + + 2) Multiply each matrix element (addressed by j*C+m) by r**(j*m). + + 3) Apply a length C FNT to each row. + + 4) Transpose the matrix. + + +Proof (forward transform): +-------------------------- + + The algorithm can be derived starting from the regular definition of + the finite-field transform of length d: + + d-1 + ,---- + \ + A[k] = | a[l] * r**(k * l) + / + `---- + l = 0 + + + The sum can be rearranged into the sum of the sums of columns: + + C-1 R-1 + ,---- ,---- + \ \ + = | | a[i * C + j] * r**(k * (i * C + j)) + / / + `---- `---- + j = 0 i = 0 + + + Extracting a constant from the inner sum: + + C-1 R-1 + ,---- ,---- + \ \ + = | r**k*j * | a[i * C + j] * r**(k * i * C) + / / + `---- `---- + j = 0 i = 0 + + + Without any loss of generality, let k = n * R + m, + where n < C and m < R: + + C-1 R-1 + ,---- ,---- + \ \ + A[n*R+m] = | r**(R*n*j) * r**(m*j) * | a[i*C+j] * r**(R*C*n*i) * r**(C*m*i) + / / + `---- `---- + j = 0 i = 0 + + + Since r = w ** ((p-1) / (R*C)): + + a) r**(R*C*n*i) = w**((p-1)*n*i) = 1 + + b) r**(C*m*i) = w**((p-1) / R) ** (m*i) = r_R ** (m*i) + + c) r**(R*n*j) = w**((p-1) / C) ** (n*j) = r_C ** (n*j) + + r_R := root of the subfield of length R. + r_C := root of the subfield of length C. + + + C-1 R-1 + ,---- ,---- + \ \ + A[n*R+m] = | r_C**(n*j) * [ r**(m*j) * | a[i*C+j] * r_R**(m*i) ] + / ^ / + `---- | `---- 1) transform the columns + j = 0 | i = 0 + ^ | + | `-- 2) multiply + | + `-- 3) transform the rows + + + Note that the entire RHS is a function of n and m and that the results + for each pair (n, m) are stored in Fortran order. + + Let the term in square brackets be f(m, j). Step 1) and 2) precalculate + the term for all (m, j). After that, the original matrix is now a lookup + table with the mth element in the jth column at location m * C + j. + + Let the complete RHS be g(m, n). Step 3) does an in-place transform of + length n on all rows. After that, the original matrix is now a lookup + table with the mth element in the nth column at location m * C + n. + + But each (m, n) pair should be written to location n * R + m. Therefore, + step 4) transposes the result of step 3). + + + +Algorithm four-step (inverse transform): +---------------------------------------- + + A := input array + d := len(A) = R * C + p := prime + d' := d**(p-2) # inverse of d + w := primitive root of unity of the prime field + r := w**((p-1)/d) # root of the subfield + r' := w**((p-1) - (p-1)/d) # inverse of r + a := output array + + 0) View the matrix as a C*R matrix. + + 1) Transpose the matrix, producing an R*C matrix. + + 2) Apply a length C FNT to each row. + + 3) Multiply each matrix element (addressed by i*C+n) by r**(i*n). + + 4) Apply a length R FNT to each column. + + +Proof (inverse transform): +-------------------------- + + The algorithm can be derived starting from the regular definition of + the finite-field inverse transform of length d: + + d-1 + ,---- + \ + a[k] = d' * | A[l] * r' ** (k * l) + / + `---- + l = 0 + + + The sum can be rearranged into the sum of the sums of columns. Note + that at this stage we still have a C*R matrix, so C denotes the number + of rows: + + R-1 C-1 + ,---- ,---- + \ \ + = d' * | | a[j * R + i] * r' ** (k * (j * R + i)) + / / + `---- `---- + i = 0 j = 0 + + + Extracting a constant from the inner sum: + + R-1 C-1 + ,---- ,---- + \ \ + = d' * | r' ** (k*i) * | a[j * R + i] * r' ** (k * j * R) + / / + `---- `---- + i = 0 j = 0 + + + Without any loss of generality, let k = m * C + n, + where m < R and n < C: + + R-1 C-1 + ,---- ,---- + \ \ + A[m*C+n] = d' * | r' ** (C*m*i) * r' ** (n*i) * | a[j*R+i] * r' ** (R*C*m*j) * r' ** (R*n*j) + / / + `---- `---- + i = 0 j = 0 + + + Since r' = w**((p-1) - (p-1)/d) and d = R*C: + + a) r' ** (R*C*m*j) = w**((p-1)*R*C*m*j - (p-1)*m*j) = 1 + + b) r' ** (C*m*i) = w**((p-1)*C - (p-1)/R) ** (m*i) = r_R' ** (m*i) + + c) r' ** (R*n*j) = r_C' ** (n*j) + + d) d' = d**(p-2) = (R*C) ** (p-2) = R**(p-2) * C**(p-2) = R' * C' + + r_R' := inverse of the root of the subfield of length R. + r_C' := inverse of the root of the subfield of length C. + R' := inverse of R + C' := inverse of C + + + R-1 C-1 + ,---- ,---- 2) transform the rows of a^T + \ \ + A[m*C+n] = R' * | r_R' ** (m*i) * [ r' ** (n*i) * C' * | a[j*R+i] * r_C' ** (n*j) ] + / ^ / ^ + `---- | `---- | + i = 0 | j = 0 | + ^ | `-- 1) Transpose input matrix + | `-- 3) multiply to address elements by + | i * C + j + `-- 3) transform the columns + + + + Note that the entire RHS is a function of m and n and that the results + for each pair (m, n) are stored in C order. + + Let the term in square brackets be f(n, i). Without step 1), the sum + would perform a length C transform on the columns of the input matrix. + This is a) inefficient and b) the results are needed in C order, so + step 1) exchanges rows and columns. + + Step 2) and 3) precalculate f(n, i) for all (n, i). After that, the + original matrix is now a lookup table with the ith element in the nth + column at location i * C + n. + + Let the complete RHS be g(m, n). Step 4) does an in-place transform of + length m on all columns. After that, the original matrix is now a lookup + table with the mth element in the nth column at location m * C + n, + which means that all A[k] = A[m * C + n] are in the correct order. + + +-- + + [1] Joerg Arndt: "Matters Computational" + http://www.jjj.de/fxt/ + [2] David H. Bailey: FFTs in External or Hierarchical Memory + http://crd.lbl.gov/~dhbailey/dhbpapers/ + + + diff --git a/python/Modules/_decimal/libmpdec/literature/mulmod-64.txt b/python/Modules/_decimal/libmpdec/literature/mulmod-64.txt new file mode 100755 index 0000000..029b8de --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/mulmod-64.txt @@ -0,0 +1,127 @@ + + +(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) + + +========================================================================== + Calculate (a * b) % p using special primes +========================================================================== + +A description of the algorithm can be found in the apfloat manual by +Tommila [1]. + + +Definitions: +------------ + +In the whole document, "==" stands for "is congruent with". + +Result of a * b in terms of high/low words: + + (1) hi * 2**64 + lo = a * b + +Special primes: + + (2) p = 2**64 - z + 1, where z = 2**n + +Single step modular reduction: + + (3) R(hi, lo) = hi * z - hi + lo + + +Strategy: +--------- + + a) Set (hi, lo) to the result of a * b. + + b) Set (hi', lo') to the result of R(hi, lo). + + 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. + + +The reduction step b) preserves congruence: +------------------------------------------- + + hi * 2**64 + lo == hi * z - hi + lo (mod p) + + Proof: + ~~~~~~ + + hi * 2**64 + lo = (2**64 - z + 1) * hi + z * hi - hi + lo + + = p * hi + z * hi - hi + lo + + == z * hi - hi + lo (mod p) + + +Maximum numbers of step b): +--------------------------- + +# To avoid unnecessary formalism, define: + +def R(hi, lo, z): + return divmod(hi * z - hi + lo, 2**64) + +# For simplicity, assume hi=2**64-1, lo=2**64-1 after the +# initial multiplication a * b. This is of course impossible +# but certainly covers all cases. + +# Then, for p1: +hi=2**64-1; lo=2**64-1; z=2**32 +p1 = 2**64 - z + 1 + +hi, lo = R(hi, lo, z) # First reduction +hi, lo = R(hi, lo, z) # Second reduction +hi * 2**64 + lo < 2 * p1 # True + +# For p2: +hi=2**64-1; lo=2**64-1; z=2**34 +p2 = 2**64 - z + 1 + +hi, lo = R(hi, lo, z) # First reduction +hi, lo = R(hi, lo, z) # Second reduction +hi, lo = R(hi, lo, z) # Third reduction +hi * 2**64 + lo < 2 * p2 # True + +# For p3: +hi=2**64-1; lo=2**64-1; z=2**40 +p3 = 2**64 - z + 1 + +hi, lo = R(hi, lo, z) # First reduction +hi, lo = R(hi, lo, z) # Second reduction +hi, lo = R(hi, lo, z) # Third reduction +hi * 2**64 + lo < 2 * p3 # True + + +Step d) preserves congruence and yields a result < p: +----------------------------------------------------- + + Case hi = 0: + + Case lo < p: trivial. + + Case lo >= p: + + lo == lo - p (mod p) # result is congruent + + p <= lo < 2*p -> 0 <= lo - p < p # result is in the correct range + + Case hi = 1: + + p < 2**64 /\ 2**64 + lo < 2*p -> lo < p # lo is always less than p + + 2**64 + lo == 2**64 + (lo - p) (mod p) # result is congruent + + = lo - p # exactly the same value as the previous RHS + # in uint64_t arithmetic. + + p < 2**64 + lo < 2*p -> 0 < 2**64 + (lo - p) < p # correct range + + + +[1] http://www.apfloat.org/apfloat/2.40/apfloat.pdf + + + diff --git a/python/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt b/python/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt new file mode 100755 index 0000000..4d17a92 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt @@ -0,0 +1,269 @@ + + +(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) + + +======================================================================== + Calculate (a * b) % p using the 80-bit x87 FPU +======================================================================== + +A description of the algorithm can be found in the apfloat manual by +Tommila [1]. + +The proof follows an argument made by Granlund/Montgomery in [2]. + + +Definitions and assumptions: +---------------------------- + +The 80-bit extended precision format uses 64 bits for the significand: + + (1) F = 64 + +The modulus is prime and less than 2**31: + + (2) 2 <= p < 2**31 + +The factors are less than p: + + (3) 0 <= a < p + (4) 0 <= b < p + +The product a * b is less than 2**62 and is thus exact in 64 bits: + + (5) n = a * b + +The product can be represented in terms of quotient and remainder: + + (6) n = q * p + r + +Using (3), (4) and the fact that p is prime, the remainder is always +greater than zero: + + (7) 0 <= q < p /\ 1 <= r < p + + +Strategy: +--------- + +Precalculate the 80-bit long double inverse of p, with a maximum +relative error of 2**(1-F): + + (8) pinv = (long double)1.0 / p + +Calculate an estimate for q = floor(n/p). The multiplication has another +maximum relative error of 2**(1-F): + + (9) qest = n * pinv + +If we can show that q < qest < q+1, then trunc(qest) = q. It is then +easy to recover the remainder r. The complete algorithm is: + + a) Set the control word to 64-bit precision and truncation mode. + + b) n = a * b # Calculate exact product. + + c) qest = n * pinv # Calculate estimate for the quotient. + + d) q = (qest+2**63)-2**63 # Truncate qest to the exact quotient. + + f) r = n - q * p # Calculate remainder. + + +Proof for q < qest < q+1: +------------------------- + +Using the cumulative error, the error bounds for qest are: + + n n * (1 + 2**(1-F))**2 + (9) --------------------- <= qest <= --------------------- + p * (1 + 2**(1-F))**2 p + + + Lemma 1: + -------- + n q * p + r + (10) q < --------------------- = --------------------- + p * (1 + 2**(1-F))**2 p * (1 + 2**(1-F))**2 + + + Proof: + ~~~~~~ + + (I) q * p * (1 + 2**(1-F))**2 < q * p + r + + (II) q * p * 2**(2-F) + q * p * 2**(2-2*F) < r + + Using (1) and (7), it is sufficient to show that: + + (III) q * p * 2**(-62) + q * p * 2**(-126) < 1 <= r + + (III) can easily be verified by substituting the largest possible + values p = 2**31-1 and q = 2**31-2. + + The critical cases occur when r = 1, n = m * p + 1. These cases + can be exhaustively verified with a test program. + + + Lemma 2: + -------- + + n * (1 + 2**(1-F))**2 (q * p + r) * (1 + 2**(1-F))**2 + (11) --------------------- = ------------------------------- < q + 1 + p p + + Proof: + ~~~~~~ + + (I) (q * p + r) + (q * p + r) * 2**(2-F) + (q * p + r) * 2**(2-2*F) < q * p + p + + (II) (q * p + r) * 2**(2-F) + (q * p + r) * 2**(2-2*F) < p - r + + Using (1) and (7), it is sufficient to show that: + + (III) (q * p + r) * 2**(-62) + (q * p + r) * 2**(-126) < 1 <= p - r + + (III) can easily be verified by substituting the largest possible + values p = 2**31-1, q = 2**31-2 and r = 2**31-2. + + The critical cases occur when r = (p - 1), n = m * p - 1. These cases + can be exhaustively verified with a test program. + + +[1] http://www.apfloat.org/apfloat/2.40/apfloat.pdf +[2] http://gmplib.org/~tege/divcnst-pldi94.pdf + [Section 7: "Use of floating point"] + + + +(* Coq proof for (10) and (11) *) + +Require Import ZArith. +Require Import QArith. +Require Import Qpower. +Require Import Qabs. +Require Import Psatz. + +Open Scope Q_scope. + + +Ltac qreduce T := + rewrite <- (Qred_correct (T)); simpl (Qred (T)). + +Theorem Qlt_move_right : + forall x y z:Q, x + z < y <-> x < y - z. +Proof. + intros. + split. + intros. + psatzl Q. + intros. + psatzl Q. +Qed. + +Theorem Qlt_mult_by_z : + forall x y z:Q, 0 < z -> (x < y <-> x * z < y * z). +Proof. + intros. + split. + intros. + apply Qmult_lt_compat_r. trivial. trivial. + intros. + rewrite <- (Qdiv_mult_l x z). rewrite <- (Qdiv_mult_l y z). + apply Qmult_lt_compat_r. + apply Qlt_shift_inv_l. + trivial. psatzl Q. trivial. psatzl Q. psatzl Q. +Qed. + +Theorem Qle_mult_quad : + forall (a b c d:Q), + 0 <= a -> a <= c -> + 0 <= b -> b <= d -> + a * b <= c * d. + intros. + psatz Q. +Qed. + + +Theorem q_lt_qest: + forall (p q r:Q), + (0 < p) -> (p <= (2#1)^31 - 1) -> + (0 <= q) -> (q <= p - 1) -> + (1 <= r) -> (r <= p - 1) -> + q < (q * p + r) / (p * (1 + (2#1)^(-63))^2). +Proof. + intros. + rewrite Qlt_mult_by_z with (z := (p * (1 + (2#1)^(-63))^2)). + + unfold Qdiv. + rewrite <- Qmult_assoc. + rewrite (Qmult_comm (/ (p * (1 + (2 # 1) ^ (-63)) ^ 2)) (p * (1 + (2 # 1) ^ (-63)) ^ 2)). + rewrite Qmult_inv_r. + rewrite Qmult_1_r. + + assert (q * (p * (1 + (2 # 1) ^ (-63)) ^ 2) == q * p + (q * p) * ((2 # 1) ^ (-62) + (2 # 1) ^ (-126))). + qreduce ((1 + (2 # 1) ^ (-63)) ^ 2). + qreduce ((2 # 1) ^ (-62) + (2 # 1) ^ (-126)). + ring_simplify. + reflexivity. + rewrite H5. + + rewrite Qplus_comm. + rewrite Qlt_move_right. + ring_simplify (q * p + r - q * p). + qreduce ((2 # 1) ^ (-62) + (2 # 1) ^ (-126)). + + apply Qlt_le_trans with (y := 1). + rewrite Qlt_mult_by_z with (z := 85070591730234615865843651857942052864 # 18446744073709551617). + ring_simplify. + + apply Qle_lt_trans with (y := ((2 # 1) ^ 31 - (2#1)) * ((2 # 1) ^ 31 - 1)). + apply Qle_mult_quad. + assumption. psatzl Q. psatzl Q. psatzl Q. psatzl Q. psatzl Q. assumption. psatzl Q. psatzl Q. +Qed. + +Theorem qest_lt_qplus1: + forall (p q r:Q), + (0 < p) -> (p <= (2#1)^31 - 1) -> + (0 <= q) -> (q <= p - 1) -> + (1 <= r) -> (r <= p - 1) -> + ((q * p + r) * (1 + (2#1)^(-63))^2) / p < q + 1. +Proof. + intros. + rewrite Qlt_mult_by_z with (z := p). + + unfold Qdiv. + rewrite <- Qmult_assoc. + rewrite (Qmult_comm (/ p) p). + rewrite Qmult_inv_r. + rewrite Qmult_1_r. + + assert ((q * p + r) * (1 + (2 # 1) ^ (-63)) ^ 2 == q * p + r + (q * p + r) * ((2 # 1) ^ (-62) + (2 # 1) ^ (-126))). + qreduce ((1 + (2 # 1) ^ (-63)) ^ 2). + qreduce ((2 # 1) ^ (-62) + (2 # 1) ^ (-126)). + ring_simplify. reflexivity. + rewrite H5. + + rewrite <- Qplus_assoc. rewrite <- Qplus_comm. rewrite Qlt_move_right. + ring_simplify ((q + 1) * p - q * p). + + rewrite <- Qplus_comm. rewrite Qlt_move_right. + + apply Qlt_le_trans with (y := 1). + qreduce ((2 # 1) ^ (-62) + (2 # 1) ^ (-126)). + + rewrite Qlt_mult_by_z with (z := 85070591730234615865843651857942052864 # 18446744073709551617). + ring_simplify. + + ring_simplify in H0. + apply Qle_lt_trans with (y := (2147483646 # 1) * (2147483647 # 1) + (2147483646 # 1)). + + apply Qplus_le_compat. + apply Qle_mult_quad. + assumption. psatzl Q. auto with qarith. assumption. psatzl Q. + auto with qarith. auto with qarith. + psatzl Q. psatzl Q. assumption. +Qed. + + + diff --git a/python/Modules/_decimal/libmpdec/literature/six-step.txt b/python/Modules/_decimal/libmpdec/literature/six-step.txt new file mode 100755 index 0000000..8e45f48 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/six-step.txt @@ -0,0 +1,63 @@ + + +(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) + + +The Six Step Transform: +======================= + +In libmpdec, the six-step transform is the Matrix Fourier Transform (See +matrix-transform.txt) in disguise. It is called six-step transform after +a variant that appears in [1]. The algorithm requires that the input +array can be viewed as an R*C matrix. + + +Algorithm six-step (forward transform): +--------------------------------------- + + 1a) Transpose the matrix. + + 1b) Apply a length R FNT to each row. + + 1c) Transpose the matrix. + + 2) Multiply each matrix element (addressed by j*C+m) by r**(j*m). + + 3) Apply a length C FNT to each row. + + 4) Transpose the matrix. + +Note that steps 1a) - 1c) are exactly equivalent to step 1) of the Matrix +Fourier Transform. For large R, it is faster to transpose twice and do +a transform on the rows than to perform a column transpose directly. + + + +Algorithm six-step (inverse transform): +--------------------------------------- + + 0) View the matrix as a C*R matrix. + + 1) Transpose the matrix, producing an R*C matrix. + + 2) Apply a length C FNT to each row. + + 3) Multiply each matrix element (addressed by i*C+n) by r**(i*n). + + 4a) Transpose the matrix. + + 4b) Apply a length R FNT to each row. + + 4c) Transpose the matrix. + +Again, steps 4a) - 4c) are equivalent to step 4) of the Matrix Fourier +Transform. + + + +-- + + [1] David H. Bailey: FFTs in External or Hierarchical Memory + http://crd.lbl.gov/~dhbailey/dhbpapers/ + + diff --git a/python/Modules/_decimal/libmpdec/literature/umodarith.lisp b/python/Modules/_decimal/libmpdec/literature/umodarith.lisp new file mode 100755 index 0000000..99d71c3 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/literature/umodarith.lisp @@ -0,0 +1,692 @@ +; +; Copyright (c) 2008-2016 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. +; + + +(in-package "ACL2") + +(include-book "arithmetic/top-with-meta" :dir :system) +(include-book "arithmetic-2/floor-mod/floor-mod" :dir :system) + + +;; ===================================================================== +;; Proofs for several functions in umodarith.h +;; ===================================================================== + + + +;; ===================================================================== +;; Helper theorems +;; ===================================================================== + +(defthm elim-mod-m= s m) (mod (- s m) base) s))) + s)) + +(defthmd addmod-correct + (implies (and (< 0 m) (< m base) + (< a m) (<= b m) + (natp m) (natp base) + (natp a) (natp b)) + (equal (addmod a b m base) + (mod (+ a b) m))) + :hints (("Goal" :cases ((<= base (+ a b)))) + ("Subgoal 2.1'" :use ((:instance elim-mod-m= a m) (- a m) a)) + (b (if (>= b m) (- b m) b)) + (d (mod (- a b) base)) + (d (if (< a b) (mod (+ d m) base) d))) + d)) + +; a < 2*m, b < 2*m +(defun ext-submod-2 (a b m base) + (let* ((a (mod a m)) + (b (mod b m)) + (d (mod (- a b) base)) + (d (if (< a b) (mod (+ d m) base) d))) + d)) + +(defthmd ext-submod-ext-submod-2-equal + (implies (and (< 0 m) (< m base) + (< a (* 2 m)) (< b (* 2 m)) + (natp m) (natp base) + (natp a) (natp b)) + (equal (ext-submod a b m base) + (ext-submod-2 a b m base)))) + +(defthmd ext-submod-2-correct + (implies (and (< 0 m) (< m base) + (< a (* 2 m)) (< b (* 2 m)) + (natp m) (natp base) + (natp a) (natp b)) + (equal (ext-submod-2 a b m base) + (mod (- a b) m)))) + + +;; ========================================================================= +;; dw-reduce is correct +;; ========================================================================= + +(defun dw-reduce (hi lo m base) + (let* ((r1 (mod hi m)) + (r2 (mod (+ (* r1 base) lo) m))) + r2)) + +(defthmd dw-reduce-correct + (implies (and (< 0 m) (< m base) + (< hi base) (< lo base) + (natp m) (natp base) + (natp hi) (natp lo)) + (equal (dw-reduce hi lo m base) + (mod (+ (* hi base) lo) m)))) + +(defthmd <=-multiply-both-sides-by-z + (implies (and (rationalp x) (rationalp y) + (< 0 z) (rationalp z)) + (equal (<= x y) + (<= (* z x) (* z y))))) + +(defthmd dw-reduce-aux1 + (implies (and (< 0 m) (< m base) + (natp m) (natp base) + (< lo base) (natp lo) + (< x m) (natp x)) + (< (+ lo (* base x)) (* base m))) + :hints (("Goal" :cases ((<= (+ x 1) m))) + ("Subgoal 1''" :cases ((<= (* base (+ x 1)) (* base m)))) + ("subgoal 1.2" :use ((:instance <=-multiply-both-sides-by-z + (x (+ 1 x)) + (y m) + (z base)))))) + +(defthm dw-reduce-aux2 + (implies (and (< x (* base m)) + (< 0 m) (< m base) + (natp m) (natp base) (natp x)) + (< (floor x m) base))) + +;; This is the necessary condition for using _mpd_div_words(). +(defthmd dw-reduce-second-quotient-fits-in-single-word + (implies (and (< 0 m) (< m base) + (< hi base) (< lo base) + (natp m) (natp base) + (natp hi) (natp lo) + (equal r1 (mod hi m))) + (< (floor (+ (* r1 base) lo) m) + base)) + :hints (("Goal" :cases ((< r1 m))) + ("Subgoal 1''" :cases ((< (+ lo (* base (mod hi m))) (* base m)))) + ("Subgoal 1.2" :use ((:instance dw-reduce-aux1 + (x (mod hi m))))))) + + +;; ========================================================================= +;; dw-submod is correct +;; ========================================================================= + +(defun dw-submod (a hi lo m base) + (let* ((r (dw-reduce hi lo m base)) + (d (mod (- a r) base)) + (d (if (< a r) (mod (+ d m) base) d))) + d)) + +(defthmd dw-submod-aux1 + (implies (and (natp a) (< 0 m) (natp m) + (natp x) (equal r (mod x m))) + (equal (mod (- a x) m) + (mod (- a r) m)))) + +(defthmd dw-submod-correct + (implies (and (< 0 m) (< m base) + (natp a) (< a m) + (< hi base) (< lo base) + (natp m) (natp base) + (natp hi) (natp lo)) + (equal (dw-submod a hi lo m base) + (mod (- a (+ (* base hi) lo)) m))) + :hints (("Goal" :in-theory (disable dw-reduce) + :use ((:instance dw-submod-aux1 + (x (+ lo (* base hi))) + (r (dw-reduce hi lo m base))) + (:instance dw-reduce-correct))))) + + +;; ========================================================================= +;; ANSI C arithmetic for uint64_t +;; ========================================================================= + +(defun add (a b) + (mod (+ a b) + (expt 2 64))) + +(defun sub (a b) + (mod (- a b) + (expt 2 64))) + +(defun << (w n) + (mod (* w (expt 2 n)) + (expt 2 64))) + +(defun >> (w n) + (floor w (expt 2 n))) + +;; join upper and lower half of a double word, yielding a 128 bit number +(defun join (hi lo) + (+ (* (expt 2 64) hi) lo)) + + +;; ============================================================================= +;; Fast modular reduction +;; ============================================================================= + +;; These are the three primes used in the Number Theoretic Transform. +;; A fast modular reduction scheme exists for all of them. +(defmacro p1 () + (+ (expt 2 64) (- (expt 2 32)) 1)) + +(defmacro p2 () + (+ (expt 2 64) (- (expt 2 34)) 1)) + +(defmacro p3 () + (+ (expt 2 64) (- (expt 2 40)) 1)) + + +;; reduce the double word number hi*2**64 + lo (mod p1) +(defun simple-mod-reduce-p1 (hi lo) + (+ (* (expt 2 32) hi) (- hi) lo)) + +;; reduce the double word number hi*2**64 + lo (mod p2) +(defun simple-mod-reduce-p2 (hi lo) + (+ (* (expt 2 34) hi) (- hi) lo)) + +;; reduce the double word number hi*2**64 + lo (mod p3) +(defun simple-mod-reduce-p3 (hi lo) + (+ (* (expt 2 40) hi) (- hi) lo)) + + +; ---------------------------------------------------------- +; The modular reductions given above are correct +; ---------------------------------------------------------- + +(defthmd congruence-p1-aux + (equal (* (expt 2 64) hi) + (+ (* (p1) hi) + (* (expt 2 32) hi) + (- hi)))) + +(defthmd congruence-p2-aux + (equal (* (expt 2 64) hi) + (+ (* (p2) hi) + (* (expt 2 34) hi) + (- hi)))) + +(defthmd congruence-p3-aux + (equal (* (expt 2 64) hi) + (+ (* (p3) hi) + (* (expt 2 40) hi) + (- hi)))) + +(defthmd mod-augment + (implies (and (rationalp x) + (rationalp y) + (rationalp m)) + (equal (mod (+ x y) m) + (mod (+ x (mod y m)) m)))) + +(defthmd simple-mod-reduce-p1-congruent + (implies (and (integerp hi) + (integerp lo)) + (equal (mod (simple-mod-reduce-p1 hi lo) (p1)) + (mod (join hi lo) (p1)))) + :hints (("Goal''" :use ((:instance congruence-p1-aux) + (:instance mod-augment + (m (p1)) + (x (+ (- hi) lo (* (expt 2 32) hi))) + (y (* (p1) hi))))))) + +(defthmd simple-mod-reduce-p2-congruent + (implies (and (integerp hi) + (integerp lo)) + (equal (mod (simple-mod-reduce-p2 hi lo) (p2)) + (mod (join hi lo) (p2)))) + :hints (("Goal''" :use ((:instance congruence-p2-aux) + (:instance mod-augment + (m (p2)) + (x (+ (- hi) lo (* (expt 2 34) hi))) + (y (* (p2) hi))))))) + +(defthmd simple-mod-reduce-p3-congruent + (implies (and (integerp hi) + (integerp lo)) + (equal (mod (simple-mod-reduce-p3 hi lo) (p3)) + (mod (join hi lo) (p3)))) + :hints (("Goal''" :use ((:instance congruence-p3-aux) + (:instance mod-augment + (m (p3)) + (x (+ (- hi) lo (* (expt 2 40) hi))) + (y (* (p3) hi))))))) + + +; --------------------------------------------------------------------- +; We need a number less than 2*p, so that we can use the trick from +; elim-mod-m> hi 32)) + (x (sub lo x)) + (hi (if (> x lo) (+ hi -1) hi)) + (y (<< y 32)) + (lo (add y x)) + (hi (if (< lo y) (+ hi 1) hi))) + (+ (* hi (expt 2 64)) lo))) + +(defun mod-reduce-p2 (hi lo) + (let* ((y hi) + (x y) + (hi (>> hi 30)) + (x (sub lo x)) + (hi (if (> x lo) (+ hi -1) hi)) + (y (<< y 34)) + (lo (add y x)) + (hi (if (< lo y) (+ hi 1) hi))) + (+ (* hi (expt 2 64)) lo))) + +(defun mod-reduce-p3 (hi lo) + (let* ((y hi) + (x y) + (hi (>> hi 24)) + (x (sub lo x)) + (hi (if (> x lo) (+ hi -1) hi)) + (y (<< y 40)) + (lo (add y x)) + (hi (if (< lo y) (+ hi 1) hi))) + (+ (* hi (expt 2 64)) lo))) + + +; ------------------------------------------------------------------------- +; The compiler friendly versions are equal to the simple versions +; ------------------------------------------------------------------------- + +(defthm mod-reduce-aux1 + (implies (and (<= 0 a) (natp a) (natp m) + (< (- m) b) (<= b 0) + (integerp b) + (< (mod (+ b a) m) + (mod a m))) + (equal (mod (+ b a) m) + (+ b (mod a m)))) + :hints (("Subgoal 2" :use ((:instance modaux-1b + (x (+ a b))))))) + +(defthm mod-reduce-aux2 + (implies (and (<= 0 a) (natp a) (natp m) + (< b m) (natp b) + (< (mod (+ b a) m) + (mod a m))) + (equal (+ m (mod (+ b a) m)) + (+ b (mod a m))))) + + +(defthm mod-reduce-aux3 + (implies (and (< 0 a) (natp a) (natp m) + (< (- m) b) (< b 0) + (integerp b) + (<= (mod a m) + (mod (+ b a) m))) + (equal (+ (- m) (mod (+ b a) m)) + (+ b (mod a m)))) + :hints (("Subgoal 1.2'" :use ((:instance modaux-1b + (x b)))) + ("Subgoal 1''" :use ((:instance modaux-2d + (x I)))))) + + +(defthm mod-reduce-aux4 + (implies (and (< 0 a) (natp a) (natp m) + (< b m) (natp b) + (<= (mod a m) + (mod (+ b a) m))) + (equal (mod (+ b a) m) + (+ b (mod a m))))) + + +(defthm mod-reduce-p1==simple-mod-reduce-p1 + (implies (and (< hi (expt 2 64)) + (< lo (expt 2 64)) + (natp hi) (natp lo)) + (equal (mod-reduce-p1 hi lo) + (simple-mod-reduce-p1 hi lo))) + :hints (("Goal" :in-theory (disable expt) + :cases ((< 0 hi))) + ("Subgoal 1.2.2'" :use ((:instance mod-reduce-aux1 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 32) hi))))) + ("Subgoal 1.2.1'" :use ((:instance mod-reduce-aux3 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 32) hi))))) + ("Subgoal 1.1.2'" :use ((:instance mod-reduce-aux2 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 32) hi))))) + ("Subgoal 1.1.1'" :use ((:instance mod-reduce-aux4 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 32) hi))))))) + + +(defthm mod-reduce-p2==simple-mod-reduce-p2 + (implies (and (< hi (expt 2 64)) + (< lo (expt 2 64)) + (natp hi) (natp lo)) + (equal (mod-reduce-p2 hi lo) + (simple-mod-reduce-p2 hi lo))) + :hints (("Goal" :cases ((< 0 hi))) + ("Subgoal 1.2.2'" :use ((:instance mod-reduce-aux1 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 34) hi))))) + ("Subgoal 1.2.1'" :use ((:instance mod-reduce-aux3 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 34) hi))))) + ("Subgoal 1.1.2'" :use ((:instance mod-reduce-aux2 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 34) hi))))) + ("Subgoal 1.1.1'" :use ((:instance mod-reduce-aux4 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 34) hi))))))) + + +(defthm mod-reduce-p3==simple-mod-reduce-p3 + (implies (and (< hi (expt 2 64)) + (< lo (expt 2 64)) + (natp hi) (natp lo)) + (equal (mod-reduce-p3 hi lo) + (simple-mod-reduce-p3 hi lo))) + :hints (("Goal" :cases ((< 0 hi))) + ("Subgoal 1.2.2'" :use ((:instance mod-reduce-aux1 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 40) hi))))) + ("Subgoal 1.2.1'" :use ((:instance mod-reduce-aux3 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 40) hi))))) + ("Subgoal 1.1.2'" :use ((:instance mod-reduce-aux2 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 40) hi))))) + ("Subgoal 1.1.1'" :use ((:instance mod-reduce-aux4 + (m (expt 2 64)) + (b (+ (- HI) LO)) + (a (* (expt 2 40) hi))))))) + + + diff --git a/python/Modules/_decimal/libmpdec/memory.c b/python/Modules/_decimal/libmpdec/memory.c new file mode 100755 index 0000000..a854e09 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/memory.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2008-2016 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 +#include "typearith.h" +#include "mpalloc.h" + + +#if defined(_MSC_VER) + #pragma warning(disable : 4232) +#endif + + +/* Guaranteed minimum allocation for a coefficient. May be changed once + at program start using mpd_setminalloc(). */ +mpd_ssize_t MPD_MINALLOC = MPD_MINALLOC_MIN; + +/* Custom allocation and free functions */ +void *(* mpd_mallocfunc)(size_t size) = malloc; +void *(* mpd_reallocfunc)(void *ptr, size_t size) = realloc; +void *(* mpd_callocfunc)(size_t nmemb, size_t size) = calloc; +void (* mpd_free)(void *ptr) = free; + + +/* emulate calloc if it is not available */ +void * +mpd_callocfunc_em(size_t nmemb, size_t size) +{ + void *ptr; + size_t req; + mpd_size_t overflow; + +#if MPD_SIZE_MAX < SIZE_MAX + /* full_coverage test only */ + if (nmemb > MPD_SIZE_MAX || size > MPD_SIZE_MAX) { + return NULL; + } +#endif + + req = mul_size_t_overflow((mpd_size_t)nmemb, (mpd_size_t)size, + &overflow); + if (overflow) { + return NULL; + } + + ptr = mpd_mallocfunc(req); + if (ptr == NULL) { + return NULL; + } + /* used on uint32_t or uint64_t */ + memset(ptr, 0, req); + + return ptr; +} + + +/* malloc with overflow checking */ +void * +mpd_alloc(mpd_size_t nmemb, mpd_size_t size) +{ + mpd_size_t req, overflow; + + req = mul_size_t_overflow(nmemb, size, &overflow); + if (overflow) { + return NULL; + } + + return mpd_mallocfunc(req); +} + +/* calloc with overflow checking */ +void * +mpd_calloc(mpd_size_t nmemb, mpd_size_t size) +{ + mpd_size_t overflow; + + (void)mul_size_t_overflow(nmemb, size, &overflow); + if (overflow) { + return NULL; + } + + return mpd_callocfunc(nmemb, size); +} + +/* realloc with overflow checking */ +void * +mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err) +{ + void *new; + mpd_size_t req, overflow; + + req = mul_size_t_overflow(nmemb, size, &overflow); + if (overflow) { + *err = 1; + return ptr; + } + + new = mpd_reallocfunc(ptr, req); + if (new == NULL) { + *err = 1; + return ptr; + } + + return new; +} + +/* struct hack malloc with overflow checking */ +void * +mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size) +{ + mpd_size_t req, overflow; + + req = mul_size_t_overflow(nmemb, size, &overflow); + if (overflow) { + return NULL; + } + + req = add_size_t_overflow(req, struct_size, &overflow); + if (overflow) { + return NULL; + } + + return mpd_mallocfunc(req); +} + + +/* Allocate a new decimal with a coefficient of length 'nwords'. In case + of an error the return value is NULL. */ +mpd_t * +mpd_qnew_size(mpd_ssize_t nwords) +{ + mpd_t *result; + + nwords = (nwords < MPD_MINALLOC) ? MPD_MINALLOC : nwords; + + result = mpd_alloc(1, sizeof *result); + if (result == NULL) { + return NULL; + } + + result->data = mpd_alloc(nwords, sizeof *result->data); + if (result->data == NULL) { + mpd_free(result); + return NULL; + } + + result->flags = 0; + result->exp = 0; + result->digits = 0; + result->len = 0; + result->alloc = nwords; + + return result; +} + +/* Allocate a new decimal with a coefficient of length MPD_MINALLOC. + In case of an error the return value is NULL. */ +mpd_t * +mpd_qnew(void) +{ + return mpd_qnew_size(MPD_MINALLOC); +} + +/* Allocate new decimal. Caller can check for NULL or MPD_Malloc_error. + Raises on error. */ +mpd_t * +mpd_new(mpd_context_t *ctx) +{ + mpd_t *result; + + result = mpd_qnew(); + if (result == NULL) { + mpd_addstatus_raise(ctx, MPD_Malloc_error); + } + return result; +} + +/* + * Input: 'result' is a static mpd_t with a static coefficient. + * Assumption: 'nwords' >= result->alloc. + * + * Resize the static coefficient to a larger dynamic one and copy the + * existing data. If successful, the value of 'result' is unchanged. + * Otherwise, set 'result' to NaN and update 'status' with MPD_Malloc_error. + */ +int +mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) +{ + mpd_uint_t *p = result->data; + + assert(nwords >= result->alloc); + + result->data = mpd_alloc(nwords, sizeof *result->data); + if (result->data == NULL) { + result->data = p; + mpd_set_qnan(result); + mpd_set_positive(result); + result->exp = result->digits = result->len = 0; + *status |= MPD_Malloc_error; + return 0; + } + + memcpy(result->data, p, result->alloc * (sizeof *result->data)); + result->alloc = nwords; + mpd_set_dynamic_data(result); + return 1; +} + +/* + * Input: 'result' is a static mpd_t with a static coefficient. + * + * Convert the coefficient to a dynamic one that is initialized to zero. If + * malloc fails, set 'result' to NaN and update 'status' with MPD_Malloc_error. + */ +int +mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) +{ + mpd_uint_t *p = result->data; + + result->data = mpd_calloc(nwords, sizeof *result->data); + if (result->data == NULL) { + result->data = p; + mpd_set_qnan(result); + mpd_set_positive(result); + result->exp = result->digits = result->len = 0; + *status |= MPD_Malloc_error; + return 0; + } + + result->alloc = nwords; + mpd_set_dynamic_data(result); + + return 1; +} + +/* + * Input: 'result' is a static or a dynamic mpd_t with a dynamic coefficient. + * Resize the coefficient to length 'nwords': + * Case nwords > result->alloc: + * If realloc is successful: + * 'result' has a larger coefficient but the same value. Return 1. + * Otherwise: + * Set 'result' to NaN, update status with MPD_Malloc_error and return 0. + * Case nwords < result->alloc: + * If realloc is successful: + * 'result' has a smaller coefficient. result->len is undefined. Return 1. + * Otherwise (unlikely): + * 'result' is unchanged. Reuse the now oversized coefficient. Return 1. + */ +int +mpd_realloc_dyn(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) +{ + uint8_t err = 0; + + result->data = mpd_realloc(result->data, nwords, sizeof *result->data, &err); + if (!err) { + result->alloc = nwords; + } + else if (nwords > result->alloc) { + mpd_set_qnan(result); + mpd_set_positive(result); + result->exp = result->digits = result->len = 0; + *status |= MPD_Malloc_error; + return 0; + } + + return 1; +} + + diff --git a/python/Modules/_decimal/libmpdec/mpalloc.h b/python/Modules/_decimal/libmpdec/mpalloc.h new file mode 100755 index 0000000..efd7119 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/mpalloc.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef MPALLOC_H +#define MPALLOC_H + + +#include "mpdecimal.h" + + +/* 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); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + +#endif + + + diff --git a/python/Modules/_decimal/libmpdec/mpdecimal.c b/python/Modules/_decimal/libmpdec/mpdecimal.c new file mode 100755 index 0000000..bfa8bb3 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/mpdecimal.c @@ -0,0 +1,8417 @@ +/* + * Copyright (c) 2008-2016 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 +#include +#include +#include +#include "basearith.h" +#include "bits.h" +#include "convolute.h" +#include "crt.h" +#include "mpalloc.h" +#include "typearith.h" +#include "umodarith.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(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' */ +ALWAYS_INLINE 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_iscanonical(const mpd_t *dec UNUSED) +{ + 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 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_sign(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 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 +} +#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) +{ + mpd_uint_t u; + int isneg; + + u = mpd_qabs_uint(a, status); + if (*status&MPD_Invalid_operation) { + 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) +{ + uint64_t x = mpd_qget_uint(a, status); + + if (*status&MPD_Invalid_operation) { + 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) +{ + int64_t x = mpd_qget_ssize(a, status); + + if (*status&MPD_Invalid_operation) { + 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) +{ + return _c32_qget_u64(1, a, status); +} + +/* quietly get an int64_t from a decimal */ +int64_t +mpd_qget_i64(const mpd_t *a, uint32_t *status) +{ + return _c32_qget_i64(a, status); +} +#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; +} + +/* + * 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_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status); +} + +/* 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) { + 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)) { + workctx.prec += 1; + mpd_qdiv(&tbase, &one, base, &workctx, status); + if (*status&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; + + 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) +{ + (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; + 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; + 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 */ +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; +} + + +/******************************************************************************/ +/* 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; + + 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; + } +#endif + + x = (double)digits / log10(base); + return (x > SIZE_MAX-1) ? 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; + + assert(srclen > 0); + assert(base >= 2); + +#if SIZE_MAX == UINT64_MAX + if (srclen > (1ULL<<53)) { + return MPD_SSIZE_MAX; + } +#endif + + x = (double)srclen * (log10(base)/MPD_RDIGITS); + return (x >= MPD_MAXIMPORT) ? 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); +} + + + diff --git a/python/Modules/_decimal/libmpdec/mpdecimal.h b/python/Modules/_decimal/libmpdec/mpdecimal.h new file mode 100755 index 0000000..3e9c818 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/mpdecimal.h @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef MPDECIMAL_H +#define MPDECIMAL_H + + +#ifdef __cplusplus +extern "C" { + #ifndef __STDC_LIMIT_MACROS + #define __STDC_LIMIT_MACROS + #define MPD_CLEAR_STDC_LIMIT_MACROS + #endif +#endif + + +#ifndef _MSC_VER + #include "pyconfig.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER + #include "vccompat.h" + #ifndef UNUSED + #define UNUSED + #endif + #define MPD_PRAGMA(x) + #define MPD_HIDE_SYMBOLS_START + #define MPD_HIDE_SYMBOLS_END + #define EXTINLINE extern inline +#else + #ifndef __GNUC_STDC_INLINE__ + #define __GNUC_STDC_INLINE__ 1 + #endif + #if defined(__GNUC__) && !defined(__INTEL_COMPILER) + #define UNUSED __attribute__((unused)) + #else + #define UNUSED + #endif + #if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \ + defined(__GNUC__) && __GNUC__ >= 4 && !defined(__INTEL_COMPILER) + #define MPD_PRAGMA(x) _Pragma(x) + #define MPD_HIDE_SYMBOLS_START "GCC visibility push(hidden)" + #define MPD_HIDE_SYMBOLS_END "GCC visibility pop" + #else + #define MPD_PRAGMA(x) + #define MPD_HIDE_SYMBOLS_START + #define MPD_HIDE_SYMBOLS_END + #endif + #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 4 +#define MPD_MICRO_VERSION 2 + +#define MPD_VERSION "2.4.2" + +#define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ + (MPD_MINOR_VERSION << 16) | \ + (MPD_MICRO_VERSION << 8)) + +const char *mpd_version(void); + + +/******************************************************************************/ +/* Configuration */ +/******************************************************************************/ + +#if defined(UNIVERSAL) + #if defined(CONFIG_64) || defined(CONFIG_32) + #error "cannot use CONFIG_64 or CONFIG_32 with UNIVERSAL." + #endif + #if defined(__ppc__) + #define CONFIG_32 + #define ANSI + #elif defined(__ppc64__) + #define CONFIG_64 + #define ANSI + #elif defined(__i386__) + #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); + +/* 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); +#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); +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 UNUSED); +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 + #ifdef MPD_CLEAR_STDC_LIMIT_MACROS + #undef MPD_CLEAR_STDC_LIMIT_MACROS + #undef __STDC_LIMIT_MACROS + #endif +} /* END extern "C" */ +#endif + + +#endif /* MPDECIMAL_H */ + + + diff --git a/python/Modules/_decimal/libmpdec/numbertheory.c b/python/Modules/_decimal/libmpdec/numbertheory.c new file mode 100755 index 0000000..4e03547 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/numbertheory.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2008-2016 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 +#include "bits.h" +#include "umodarith.h" +#include "numbertheory.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/python/Modules/_decimal/libmpdec/numbertheory.h b/python/Modules/_decimal/libmpdec/numbertheory.h new file mode 100755 index 0000000..e94c157 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/numbertheory.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef NUMBER_THEORY_H +#define NUMBER_THEORY_H + + +#include "constants.h" +#include "mpdecimal.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 + + diff --git a/python/Modules/_decimal/libmpdec/sixstep.c b/python/Modules/_decimal/libmpdec/sixstep.c new file mode 100755 index 0000000..92d513e --- /dev/null +++ b/python/Modules/_decimal/libmpdec/sixstep.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2008-2016 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 +#include +#include "bits.h" +#include "difradix2.h" +#include "numbertheory.h" +#include "transpose.h" +#include "umodarith.h" +#include "sixstep.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/python/Modules/_decimal/libmpdec/sixstep.h b/python/Modules/_decimal/libmpdec/sixstep.h new file mode 100755 index 0000000..4a8b015 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/sixstep.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef SIX_STEP_H +#define SIX_STEP_H + + +#include "mpdecimal.h" +#include + + +/* 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 diff --git a/python/Modules/_decimal/libmpdec/transpose.c b/python/Modules/_decimal/libmpdec/transpose.c new file mode 100755 index 0000000..55d6d89 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/transpose.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2008-2016 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 +#include +#include +#include +#include "bits.h" +#include "constants.h" +#include "typearith.h" +#include "transpose.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/python/Modules/_decimal/libmpdec/transpose.h b/python/Modules/_decimal/libmpdec/transpose.h new file mode 100755 index 0000000..e1cd1fa --- /dev/null +++ b/python/Modules/_decimal/libmpdec/transpose.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef TRANSPOSE_H +#define TRANSPOSE_H + + +#include "mpdecimal.h" +#include + + +/* 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 diff --git a/python/Modules/_decimal/libmpdec/typearith.h b/python/Modules/_decimal/libmpdec/typearith.h new file mode 100755 index 0000000..405237d --- /dev/null +++ b/python/Modules/_decimal/libmpdec/typearith.h @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef TYPEARITH_H +#define TYPEARITH_H + + +#include "mpdecimal.h" + + +/*****************************************************************************/ +/* 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 /* TYPEARITH_H */ + + + diff --git a/python/Modules/_decimal/libmpdec/umodarith.h b/python/Modules/_decimal/libmpdec/umodarith.h new file mode 100755 index 0000000..68d1518 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/umodarith.h @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef UMODARITH_H +#define UMODARITH_H + + +#include "constants.h" +#include "mpdecimal.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 /* UMODARITH_H */ + + + diff --git a/python/Modules/_decimal/libmpdec/vccompat.h b/python/Modules/_decimal/libmpdec/vccompat.h new file mode 100755 index 0000000..dd131d8 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/vccompat.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2008-2016 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. + */ + + +#ifndef VCCOMPAT_H +#define VCCOMPAT_H + + +/* Visual C fixes: no stdint.h, no snprintf ... */ +#ifdef _MSC_VER + #undef inline + #define inline __inline + #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 /* VCCOMPAT_H */ + + + diff --git a/python/Modules/_decimal/libmpdec/vcdiv64.asm b/python/Modules/_decimal/libmpdec/vcdiv64.asm new file mode 100755 index 0000000..6b66456 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/vcdiv64.asm @@ -0,0 +1,48 @@ +; +; Copyright (c) 2008-2016 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. +; + + +PUBLIC _mpd_div_words +_TEXT SEGMENT +q$ = 8 +r$ = 16 +hi$ = 24 +lo$ = 32 +d$ = 40 +_mpd_div_words PROC + mov r10, rdx + mov rdx, r8 + mov rax, r9 + div QWORD PTR d$[rsp] + mov QWORD PTR [r10], rdx + mov QWORD PTR [rcx], rax + ret 0 +_mpd_div_words ENDP +_TEXT ENDS +END + + diff --git a/python/Modules/_decimal/libmpdec/vcstdint.h b/python/Modules/_decimal/libmpdec/vcstdint.h new file mode 100755 index 0000000..17dcad4 --- /dev/null +++ b/python/Modules/_decimal/libmpdec/vcstdint.h @@ -0,0 +1,232 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// 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 name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if (_MSC_VER < 1300) && defined(__cplusplus) + extern "C++" { +#endif +# include +#if (_MSC_VER < 1300) && defined(__cplusplus) + } +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/python/Modules/_decimal/tests/README.txt b/python/Modules/_decimal/tests/README.txt new file mode 100755 index 0000000..97b6ff6 --- /dev/null +++ b/python/Modules/_decimal/tests/README.txt @@ -0,0 +1,15 @@ + + +This directory contains extended tests and a benchmark against decimal.py: + + bench.py -> Benchmark for small and large precisions. + Usage: ../../../python bench.py + + formathelper.py -> + randdec.py -> Generate test cases for deccheck.py. + randfloat.py -> + + deccheck.py -> Run extended tests. + Usage: ../../../python deccheck.py [--short|--medium|--long|--all] + + diff --git a/python/Modules/_decimal/tests/bench.py b/python/Modules/_decimal/tests/bench.py new file mode 100755 index 0000000..3726db1 --- /dev/null +++ b/python/Modules/_decimal/tests/bench.py @@ -0,0 +1,132 @@ +# +# Copyright (C) 2001-2012 Python Software Foundation. All Rights Reserved. +# Modified and extended by Stefan Krah. +# + +# Usage: ../../../python bench.py + + +import time +try: + from test.support import import_fresh_module +except ImportError: + from test.test_support import import_fresh_module + +C = import_fresh_module('decimal', fresh=['_decimal']) +P = import_fresh_module('decimal', blocked=['_decimal']) + +# +# NOTE: This is the pi function from the decimal documentation, modified +# for benchmarking purposes. Since floats do not have a context, the higher +# intermediate precision from the original is NOT used, so the modified +# algorithm only gives an approximation to the correctly rounded result. +# For serious use, refer to the documentation or the appropriate literature. +# +def pi_float(): + """native float""" + lasts, t, s, n, na, d, da = 0, 3.0, 3, 1, 0, 0, 24 + while s != lasts: + lasts = s + n, na = n+na, na+8 + d, da = d+da, da+32 + t = (t * n) / d + s += t + return s + +def pi_cdecimal(): + """cdecimal""" + D = C.Decimal + lasts, t, s, n, na, d, da = D(0), D(3), D(3), D(1), D(0), D(0), D(24) + while s != lasts: + lasts = s + n, na = n+na, na+8 + d, da = d+da, da+32 + t = (t * n) / d + s += t + return s + +def pi_decimal(): + """decimal""" + D = P.Decimal + lasts, t, s, n, na, d, da = D(0), D(3), D(3), D(1), D(0), D(0), D(24) + while s != lasts: + lasts = s + n, na = n+na, na+8 + d, da = d+da, da+32 + t = (t * n) / d + s += t + return s + +def factorial(n, m): + if (n > m): + return factorial(m, n) + elif m == 0: + return 1 + elif n == m: + return n + else: + return factorial(n, (n+m)//2) * factorial((n+m)//2 + 1, m) + + +print("\n# ======================================================================") +print("# Calculating pi, 10000 iterations") +print("# ======================================================================\n") + +to_benchmark = [pi_float, pi_decimal] +if C is not None: + to_benchmark.insert(1, pi_cdecimal) + +for prec in [9, 19]: + print("\nPrecision: %d decimal digits\n" % prec) + for func in to_benchmark: + start = time.time() + if C is not None: + C.getcontext().prec = prec + P.getcontext().prec = prec + for i in range(10000): + x = func() + print("%s:" % func.__name__.replace("pi_", "")) + print("result: %s" % str(x)) + print("time: %fs\n" % (time.time()-start)) + + +print("\n# ======================================================================") +print("# Factorial") +print("# ======================================================================\n") + +if C is not None: + c = C.getcontext() + c.prec = C.MAX_PREC + c.Emax = C.MAX_EMAX + c.Emin = C.MIN_EMIN + +for n in [100000, 1000000]: + + print("n = %d\n" % n) + + if C is not None: + # C version of decimal + start_calc = time.time() + x = factorial(C.Decimal(n), 0) + end_calc = time.time() + start_conv = time.time() + sx = str(x) + end_conv = time.time() + print("cdecimal:") + print("calculation time: %fs" % (end_calc-start_calc)) + print("conversion time: %fs\n" % (end_conv-start_conv)) + + # Python integers + start_calc = time.time() + y = factorial(n, 0) + end_calc = time.time() + start_conv = time.time() + sy = str(y) + end_conv = time.time() + + print("int:") + print("calculation time: %fs" % (end_calc-start_calc)) + print("conversion time: %fs\n\n" % (end_conv-start_conv)) + + if C is not None: + assert(sx == sy) diff --git a/python/Modules/_decimal/tests/bignum.py b/python/Modules/_decimal/tests/bignum.py new file mode 100755 index 0000000..a67e161 --- /dev/null +++ b/python/Modules/_decimal/tests/bignum.py @@ -0,0 +1,42 @@ +# +# These tests require gmpy and test the limits of the 32-bit build. The +# limits of the 64-bit build are so large that they cannot be tested +# on accessible hardware. +# + +import sys +from decimal import * +from gmpy import mpz + + +_PyHASH_MODULUS = sys.hash_info.modulus +# hash values to use for positive and negative infinities, and nans +_PyHASH_INF = sys.hash_info.inf +_PyHASH_NAN = sys.hash_info.nan + +# _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS +_PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS) + +def xhash(coeff, exp): + sign = 1 + if coeff < 0: + sign = -1 + coeff = -coeff + if exp >= 0: + exp_hash = pow(10, exp, _PyHASH_MODULUS) + else: + exp_hash = pow(_PyHASH_10INV, -exp, _PyHASH_MODULUS) + hash_ = coeff * exp_hash % _PyHASH_MODULUS + ans = hash_ if sign == 1 else -hash_ + return -2 if ans == -1 else ans + + +x = mpz(10) ** 425000000 - 1 +coeff = int(x) + +d = Decimal('9' * 425000000 + 'e-849999999') + +h1 = xhash(coeff, -849999999) +h2 = hash(d) + +assert h2 == h1 diff --git a/python/Modules/_decimal/tests/deccheck.py b/python/Modules/_decimal/tests/deccheck.py new file mode 100755 index 0000000..f907531 --- /dev/null +++ b/python/Modules/_decimal/tests/deccheck.py @@ -0,0 +1,1100 @@ +# +# 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. +# + +# +# Usage: python deccheck.py [--short|--medium|--long|--all] +# + +import sys, random +from copy import copy +from collections import defaultdict +from test.support import import_fresh_module +from randdec import randfloat, all_unary, all_binary, all_ternary +from randdec import unary_optarg, binary_optarg, ternary_optarg +from formathelper import rand_format, rand_locale +from _pydecimal import _dec_from_triple + +C = import_fresh_module('decimal', fresh=['_decimal']) +P = import_fresh_module('decimal', blocked=['_decimal']) +EXIT_STATUS = 0 + + +# Contains all categories of Decimal methods. +Functions = { + # Plain unary: + 'unary': ( + '__abs__', '__bool__', '__ceil__', '__complex__', '__copy__', + '__floor__', '__float__', '__hash__', '__int__', '__neg__', + '__pos__', '__reduce__', '__repr__', '__str__', '__trunc__', + 'adjusted', 'as_integer_ratio', 'as_tuple', 'canonical', 'conjugate', + 'copy_abs', 'copy_negate', 'is_canonical', 'is_finite', 'is_infinite', + 'is_nan', 'is_qnan', 'is_signed', 'is_snan', 'is_zero', 'radix' + ), + # Unary with optional context: + 'unary_ctx': ( + 'exp', 'is_normal', 'is_subnormal', 'ln', 'log10', 'logb', + 'logical_invert', 'next_minus', 'next_plus', 'normalize', + 'number_class', 'sqrt', 'to_eng_string' + ), + # Unary with optional rounding mode and context: + 'unary_rnd_ctx': ('to_integral', 'to_integral_exact', 'to_integral_value'), + # Plain binary: + 'binary': ( + '__add__', '__divmod__', '__eq__', '__floordiv__', '__ge__', '__gt__', + '__le__', '__lt__', '__mod__', '__mul__', '__ne__', '__pow__', + '__radd__', '__rdivmod__', '__rfloordiv__', '__rmod__', '__rmul__', + '__rpow__', '__rsub__', '__rtruediv__', '__sub__', '__truediv__', + 'compare_total', 'compare_total_mag', 'copy_sign', 'quantize', + 'same_quantum' + ), + # Binary with optional context: + 'binary_ctx': ( + 'compare', 'compare_signal', 'logical_and', 'logical_or', 'logical_xor', + 'max', 'max_mag', 'min', 'min_mag', 'next_toward', 'remainder_near', + 'rotate', 'scaleb', 'shift' + ), + # Plain ternary: + 'ternary': ('__pow__',), + # Ternary with optional context: + 'ternary_ctx': ('fma',), + # Special: + 'special': ('__format__', '__reduce_ex__', '__round__', 'from_float', + 'quantize'), + # Properties: + 'property': ('real', 'imag') +} + +# Contains all categories of Context methods. The n-ary classification +# applies to the number of Decimal arguments. +ContextFunctions = { + # Plain nullary: + 'nullary': ('context.__hash__', 'context.__reduce__', 'context.radix'), + # Plain unary: + 'unary': ('context.abs', 'context.canonical', 'context.copy_abs', + 'context.copy_decimal', 'context.copy_negate', + 'context.create_decimal', 'context.exp', 'context.is_canonical', + 'context.is_finite', 'context.is_infinite', 'context.is_nan', + 'context.is_normal', 'context.is_qnan', 'context.is_signed', + 'context.is_snan', 'context.is_subnormal', 'context.is_zero', + 'context.ln', 'context.log10', 'context.logb', + 'context.logical_invert', 'context.minus', 'context.next_minus', + 'context.next_plus', 'context.normalize', 'context.number_class', + 'context.plus', 'context.sqrt', 'context.to_eng_string', + 'context.to_integral', 'context.to_integral_exact', + 'context.to_integral_value', 'context.to_sci_string' + ), + # Plain binary: + 'binary': ('context.add', 'context.compare', 'context.compare_signal', + 'context.compare_total', 'context.compare_total_mag', + 'context.copy_sign', 'context.divide', 'context.divide_int', + 'context.divmod', 'context.logical_and', 'context.logical_or', + 'context.logical_xor', 'context.max', 'context.max_mag', + 'context.min', 'context.min_mag', 'context.multiply', + 'context.next_toward', 'context.power', 'context.quantize', + 'context.remainder', 'context.remainder_near', 'context.rotate', + 'context.same_quantum', 'context.scaleb', 'context.shift', + 'context.subtract' + ), + # Plain ternary: + 'ternary': ('context.fma', 'context.power'), + # Special: + 'special': ('context.__reduce_ex__', 'context.create_decimal_from_float') +} + +# Functions that require a restricted exponent range for reasonable runtimes. +UnaryRestricted = [ + '__ceil__', '__floor__', '__int__', '__trunc__', + 'as_integer_ratio', 'to_integral', 'to_integral_value' +] + +BinaryRestricted = ['__round__'] + +TernaryRestricted = ['__pow__', 'context.power'] + + +# ====================================================================== +# Unified Context +# ====================================================================== + +# Translate symbols. +CondMap = { + C.Clamped: P.Clamped, + C.ConversionSyntax: P.ConversionSyntax, + C.DivisionByZero: P.DivisionByZero, + C.DivisionImpossible: P.InvalidOperation, + C.DivisionUndefined: P.DivisionUndefined, + C.Inexact: P.Inexact, + C.InvalidContext: P.InvalidContext, + C.InvalidOperation: P.InvalidOperation, + C.Overflow: P.Overflow, + C.Rounded: P.Rounded, + C.Subnormal: P.Subnormal, + C.Underflow: P.Underflow, + C.FloatOperation: P.FloatOperation, +} + +RoundModes = [C.ROUND_UP, C.ROUND_DOWN, C.ROUND_CEILING, C.ROUND_FLOOR, + C.ROUND_HALF_UP, C.ROUND_HALF_DOWN, C.ROUND_HALF_EVEN, + C.ROUND_05UP] + + +class Context(object): + """Provides a convenient way of syncing the C and P contexts""" + + __slots__ = ['c', 'p'] + + def __init__(self, c_ctx=None, p_ctx=None): + """Initialization is from the C context""" + self.c = C.getcontext() if c_ctx is None else c_ctx + self.p = P.getcontext() if p_ctx is None else p_ctx + self.p.prec = self.c.prec + self.p.Emin = self.c.Emin + self.p.Emax = self.c.Emax + self.p.rounding = self.c.rounding + self.p.capitals = self.c.capitals + self.settraps([sig for sig in self.c.traps if self.c.traps[sig]]) + self.setstatus([sig for sig in self.c.flags if self.c.flags[sig]]) + self.p.clamp = self.c.clamp + + def __str__(self): + return str(self.c) + '\n' + str(self.p) + + def getprec(self): + assert(self.c.prec == self.p.prec) + return self.c.prec + + def setprec(self, val): + self.c.prec = val + self.p.prec = val + + def getemin(self): + assert(self.c.Emin == self.p.Emin) + return self.c.Emin + + def setemin(self, val): + self.c.Emin = val + self.p.Emin = val + + def getemax(self): + assert(self.c.Emax == self.p.Emax) + return self.c.Emax + + def setemax(self, val): + self.c.Emax = val + self.p.Emax = val + + def getround(self): + assert(self.c.rounding == self.p.rounding) + return self.c.rounding + + def setround(self, val): + self.c.rounding = val + self.p.rounding = val + + def getcapitals(self): + assert(self.c.capitals == self.p.capitals) + return self.c.capitals + + def setcapitals(self, val): + self.c.capitals = val + self.p.capitals = val + + def getclamp(self): + assert(self.c.clamp == self.p.clamp) + return self.c.clamp + + def setclamp(self, val): + self.c.clamp = val + self.p.clamp = val + + prec = property(getprec, setprec) + Emin = property(getemin, setemin) + Emax = property(getemax, setemax) + rounding = property(getround, setround) + clamp = property(getclamp, setclamp) + capitals = property(getcapitals, setcapitals) + + def clear_traps(self): + self.c.clear_traps() + for trap in self.p.traps: + self.p.traps[trap] = False + + def clear_status(self): + self.c.clear_flags() + self.p.clear_flags() + + def settraps(self, lst): + """lst: C signal list""" + self.clear_traps() + for signal in lst: + self.c.traps[signal] = True + self.p.traps[CondMap[signal]] = True + + def setstatus(self, lst): + """lst: C signal list""" + self.clear_status() + for signal in lst: + self.c.flags[signal] = True + self.p.flags[CondMap[signal]] = True + + def assert_eq_status(self): + """assert equality of C and P status""" + for signal in self.c.flags: + if self.c.flags[signal] == (not self.p.flags[CondMap[signal]]): + return False + return True + + +# We don't want exceptions so that we can compare the status flags. +context = Context() +context.Emin = C.MIN_EMIN +context.Emax = C.MAX_EMAX +context.clear_traps() + +# When creating decimals, _decimal is ultimately limited by the maximum +# context values. We emulate this restriction for decimal.py. +maxcontext = P.Context( + prec=C.MAX_PREC, + Emin=C.MIN_EMIN, + Emax=C.MAX_EMAX, + rounding=P.ROUND_HALF_UP, + capitals=1 +) +maxcontext.clamp = 0 + +def RestrictedDecimal(value): + maxcontext.traps = copy(context.p.traps) + maxcontext.clear_flags() + if isinstance(value, str): + value = value.strip() + dec = maxcontext.create_decimal(value) + if maxcontext.flags[P.Inexact] or \ + maxcontext.flags[P.Rounded] or \ + maxcontext.flags[P.Clamped] or \ + maxcontext.flags[P.InvalidOperation]: + return context.p._raise_error(P.InvalidOperation) + if maxcontext.flags[P.FloatOperation]: + context.p.flags[P.FloatOperation] = True + return dec + + +# ====================================================================== +# TestSet: Organize data and events during a single test case +# ====================================================================== + +class RestrictedList(list): + """List that can only be modified by appending items.""" + def __getattribute__(self, name): + if name != 'append': + raise AttributeError("unsupported operation") + return list.__getattribute__(self, name) + def unsupported(self, *_): + raise AttributeError("unsupported operation") + __add__ = __delattr__ = __delitem__ = __iadd__ = __imul__ = unsupported + __mul__ = __reversed__ = __rmul__ = __setattr__ = __setitem__ = unsupported + +class TestSet(object): + """A TestSet contains the original input operands, converted operands, + Python exceptions that occurred either during conversion or during + execution of the actual function, and the final results. + + For safety, most attributes are lists that only support the append + operation. + + If a function name is prefixed with 'context.', the corresponding + context method is called. + """ + def __init__(self, funcname, operands): + if funcname.startswith("context."): + self.funcname = funcname.replace("context.", "") + self.contextfunc = True + else: + self.funcname = funcname + self.contextfunc = False + self.op = operands # raw operand tuple + self.context = context # context used for the operation + self.cop = RestrictedList() # converted C.Decimal operands + self.cex = RestrictedList() # Python exceptions for C.Decimal + self.cresults = RestrictedList() # C.Decimal results + self.pop = RestrictedList() # converted P.Decimal operands + self.pex = RestrictedList() # Python exceptions for P.Decimal + self.presults = RestrictedList() # P.Decimal results + + +# ====================================================================== +# SkipHandler: skip known discrepancies +# ====================================================================== + +class SkipHandler: + """Handle known discrepancies between decimal.py and _decimal.so. + These are either ULP differences in the power function or + extremely minor issues.""" + + def __init__(self): + self.ulpdiff = 0 + self.powmod_zeros = 0 + self.maxctx = P.Context(Emax=10**18, Emin=-10**18) + + def default(self, t): + return False + __ge__ = __gt__ = __le__ = __lt__ = __ne__ = __eq__ = default + __reduce__ = __format__ = __repr__ = __str__ = default + + def harrison_ulp(self, dec): + """ftp://ftp.inria.fr/INRIA/publication/publi-pdf/RR/RR-5504.pdf""" + a = dec.next_plus() + b = dec.next_minus() + return abs(a - b) + + def standard_ulp(self, dec, prec): + return _dec_from_triple(0, '1', dec._exp+len(dec._int)-prec) + + def rounding_direction(self, x, mode): + """Determine the effective direction of the rounding when + the exact result x is rounded according to mode. + Return -1 for downwards, 0 for undirected, 1 for upwards, + 2 for ROUND_05UP.""" + cmp = 1 if x.compare_total(P.Decimal("+0")) >= 0 else -1 + + if mode in (P.ROUND_HALF_EVEN, P.ROUND_HALF_UP, P.ROUND_HALF_DOWN): + return 0 + elif mode == P.ROUND_CEILING: + return 1 + elif mode == P.ROUND_FLOOR: + return -1 + elif mode == P.ROUND_UP: + return cmp + elif mode == P.ROUND_DOWN: + return -cmp + elif mode == P.ROUND_05UP: + return 2 + else: + raise ValueError("Unexpected rounding mode: %s" % mode) + + def check_ulpdiff(self, exact, rounded): + # current precision + p = context.p.prec + + # Convert infinities to the largest representable number + 1. + x = exact + if exact.is_infinite(): + x = _dec_from_triple(exact._sign, '10', context.p.Emax) + y = rounded + if rounded.is_infinite(): + y = _dec_from_triple(rounded._sign, '10', context.p.Emax) + + # err = (rounded - exact) / ulp(rounded) + self.maxctx.prec = p * 2 + t = self.maxctx.subtract(y, x) + if context.c.flags[C.Clamped] or \ + context.c.flags[C.Underflow]: + # The standard ulp does not work in Underflow territory. + ulp = self.harrison_ulp(y) + else: + ulp = self.standard_ulp(y, p) + # Error in ulps. + err = self.maxctx.divide(t, ulp) + + dir = self.rounding_direction(x, context.p.rounding) + if dir == 0: + if P.Decimal("-0.6") < err < P.Decimal("0.6"): + return True + elif dir == 1: # directed, upwards + if P.Decimal("-0.1") < err < P.Decimal("1.1"): + return True + elif dir == -1: # directed, downwards + if P.Decimal("-1.1") < err < P.Decimal("0.1"): + return True + else: # ROUND_05UP + if P.Decimal("-1.1") < err < P.Decimal("1.1"): + return True + + print("ulp: %s error: %s exact: %s c_rounded: %s" + % (ulp, err, exact, rounded)) + return False + + def bin_resolve_ulp(self, t): + """Check if results of _decimal's power function are within the + allowed ulp ranges.""" + # NaNs are beyond repair. + if t.rc.is_nan() or t.rp.is_nan(): + return False + + # "exact" result, double precision, half_even + self.maxctx.prec = context.p.prec * 2 + + op1, op2 = t.pop[0], t.pop[1] + if t.contextfunc: + exact = getattr(self.maxctx, t.funcname)(op1, op2) + else: + exact = getattr(op1, t.funcname)(op2, context=self.maxctx) + + # _decimal's rounded result + rounded = P.Decimal(t.cresults[0]) + + self.ulpdiff += 1 + return self.check_ulpdiff(exact, rounded) + + ############################ Correct rounding ############################# + def resolve_underflow(self, t): + """In extremely rare cases where the infinite precision result is just + below etiny, cdecimal does not set Subnormal/Underflow. Example: + + setcontext(Context(prec=21, rounding=ROUND_UP, Emin=-55, Emax=85)) + Decimal("1.00000000000000000000000000000000000000000000000" + "0000000100000000000000000000000000000000000000000" + "0000000000000025").ln() + """ + if t.cresults != t.presults: + return False # Results must be identical. + if context.c.flags[C.Rounded] and \ + context.c.flags[C.Inexact] and \ + context.p.flags[P.Rounded] and \ + context.p.flags[P.Inexact]: + return True # Subnormal/Underflow may be missing. + return False + + def exp(self, t): + """Resolve Underflow or ULP difference.""" + return self.resolve_underflow(t) + + def log10(self, t): + """Resolve Underflow or ULP difference.""" + return self.resolve_underflow(t) + + def ln(self, t): + """Resolve Underflow or ULP difference.""" + return self.resolve_underflow(t) + + def __pow__(self, t): + """Always calls the resolve function. C.Decimal does not have correct + rounding for the power function.""" + if context.c.flags[C.Rounded] and \ + context.c.flags[C.Inexact] and \ + context.p.flags[P.Rounded] and \ + context.p.flags[P.Inexact]: + return self.bin_resolve_ulp(t) + else: + return False + power = __rpow__ = __pow__ + + ############################## Technicalities ############################# + def __float__(self, t): + """NaN comparison in the verify() function obviously gives an + incorrect answer: nan == nan -> False""" + if t.cop[0].is_nan() and t.pop[0].is_nan(): + return True + return False + __complex__ = __float__ + + def __radd__(self, t): + """decimal.py gives precedence to the first NaN; this is + not important, as __radd__ will not be called for + two decimal arguments.""" + if t.rc.is_nan() and t.rp.is_nan(): + return True + return False + __rmul__ = __radd__ + + ################################ Various ################################## + def __round__(self, t): + """Exception: Decimal('1').__round__(-100000000000000000000000000) + Should it really be InvalidOperation?""" + if t.rc is None and t.rp.is_nan(): + return True + return False + +shandler = SkipHandler() +def skip_error(t): + return getattr(shandler, t.funcname, shandler.default)(t) + + +# ====================================================================== +# Handling verification errors +# ====================================================================== + +class VerifyError(Exception): + """Verification failed.""" + pass + +def function_as_string(t): + if t.contextfunc: + cargs = t.cop + pargs = t.pop + cfunc = "c_func: %s(" % t.funcname + pfunc = "p_func: %s(" % t.funcname + else: + cself, cargs = t.cop[0], t.cop[1:] + pself, pargs = t.pop[0], t.pop[1:] + cfunc = "c_func: %s.%s(" % (repr(cself), t.funcname) + pfunc = "p_func: %s.%s(" % (repr(pself), t.funcname) + + err = cfunc + for arg in cargs: + err += "%s, " % repr(arg) + err = err.rstrip(", ") + err += ")\n" + + err += pfunc + for arg in pargs: + err += "%s, " % repr(arg) + err = err.rstrip(", ") + err += ")" + + return err + +def raise_error(t): + global EXIT_STATUS + + if skip_error(t): + return + EXIT_STATUS = 1 + + err = "Error in %s:\n\n" % t.funcname + err += "input operands: %s\n\n" % (t.op,) + err += function_as_string(t) + err += "\n\nc_result: %s\np_result: %s\n\n" % (t.cresults, t.presults) + err += "c_exceptions: %s\np_exceptions: %s\n\n" % (t.cex, t.pex) + err += "%s\n\n" % str(t.context) + + raise VerifyError(err) + + +# ====================================================================== +# Main testing functions +# +# The procedure is always (t is the TestSet): +# +# convert(t) -> Initialize the TestSet as necessary. +# +# Return 0 for early abortion (e.g. if a TypeError +# occurs during conversion, there is nothing to test). +# +# Return 1 for continuing with the test case. +# +# callfuncs(t) -> Call the relevant function for each implementation +# and record the results in the TestSet. +# +# verify(t) -> Verify the results. If verification fails, details +# are printed to stdout. +# ====================================================================== + +def convert(t, convstr=True): + """ t is the testset. At this stage the testset contains a tuple of + operands t.op of various types. For decimal methods the first + operand (self) is always converted to Decimal. If 'convstr' is + true, string operands are converted as well. + + Context operands are of type deccheck.Context, rounding mode + operands are given as a tuple (C.rounding, P.rounding). + + Other types (float, int, etc.) are left unchanged. + """ + for i, op in enumerate(t.op): + + context.clear_status() + + if op in RoundModes: + t.cop.append(op) + t.pop.append(op) + + elif not t.contextfunc and i == 0 or \ + convstr and isinstance(op, str): + try: + c = C.Decimal(op) + cex = None + except (TypeError, ValueError, OverflowError) as e: + c = None + cex = e.__class__ + + try: + p = RestrictedDecimal(op) + pex = None + except (TypeError, ValueError, OverflowError) as e: + p = None + pex = e.__class__ + + t.cop.append(c) + t.cex.append(cex) + t.pop.append(p) + t.pex.append(pex) + + if cex is pex: + if str(c) != str(p) or not context.assert_eq_status(): + raise_error(t) + if cex and pex: + # nothing to test + return 0 + else: + raise_error(t) + + elif isinstance(op, Context): + t.context = op + t.cop.append(op.c) + t.pop.append(op.p) + + else: + t.cop.append(op) + t.pop.append(op) + + return 1 + +def callfuncs(t): + """ t is the testset. At this stage the testset contains operand lists + t.cop and t.pop for the C and Python versions of decimal. + For Decimal methods, the first operands are of type C.Decimal and + P.Decimal respectively. The remaining operands can have various types. + For Context methods, all operands can have any type. + + t.rc and t.rp are the results of the operation. + """ + context.clear_status() + + try: + if t.contextfunc: + cargs = t.cop + t.rc = getattr(context.c, t.funcname)(*cargs) + else: + cself = t.cop[0] + cargs = t.cop[1:] + t.rc = getattr(cself, t.funcname)(*cargs) + t.cex.append(None) + except (TypeError, ValueError, OverflowError, MemoryError) as e: + t.rc = None + t.cex.append(e.__class__) + + try: + if t.contextfunc: + pargs = t.pop + t.rp = getattr(context.p, t.funcname)(*pargs) + else: + pself = t.pop[0] + pargs = t.pop[1:] + t.rp = getattr(pself, t.funcname)(*pargs) + t.pex.append(None) + except (TypeError, ValueError, OverflowError, MemoryError) as e: + t.rp = None + t.pex.append(e.__class__) + +def verify(t, stat): + """ t is the testset. At this stage the testset contains the following + tuples: + + t.op: original operands + t.cop: C.Decimal operands (see convert for details) + t.pop: P.Decimal operands (see convert for details) + t.rc: C result + t.rp: Python result + + t.rc and t.rp can have various types. + """ + t.cresults.append(str(t.rc)) + t.presults.append(str(t.rp)) + if isinstance(t.rc, C.Decimal) and isinstance(t.rp, P.Decimal): + # General case: both results are Decimals. + t.cresults.append(t.rc.to_eng_string()) + t.cresults.append(t.rc.as_tuple()) + t.cresults.append(str(t.rc.imag)) + t.cresults.append(str(t.rc.real)) + t.presults.append(t.rp.to_eng_string()) + t.presults.append(t.rp.as_tuple()) + t.presults.append(str(t.rp.imag)) + t.presults.append(str(t.rp.real)) + + nc = t.rc.number_class().lstrip('+-s') + stat[nc] += 1 + else: + # Results from e.g. __divmod__ can only be compared as strings. + if not isinstance(t.rc, tuple) and not isinstance(t.rp, tuple): + if t.rc != t.rp: + raise_error(t) + stat[type(t.rc).__name__] += 1 + + # The return value lists must be equal. + if t.cresults != t.presults: + raise_error(t) + # The Python exception lists (TypeError, etc.) must be equal. + if t.cex != t.pex: + raise_error(t) + # The context flags must be equal. + if not t.context.assert_eq_status(): + raise_error(t) + + +# ====================================================================== +# Main test loops +# +# test_method(method, testspecs, testfunc) -> +# +# Loop through various context settings. The degree of +# thoroughness is determined by 'testspec'. For each +# setting, call 'testfunc'. Generally, 'testfunc' itself +# a loop, iterating through many test cases generated +# by the functions in randdec.py. +# +# test_n-ary(method, prec, exp_range, restricted_range, itr, stat) -> +# +# 'test_unary', 'test_binary' and 'test_ternary' are the +# main test functions passed to 'test_method'. They deal +# with the regular cases. The thoroughness of testing is +# determined by 'itr'. +# +# 'prec', 'exp_range' and 'restricted_range' are passed +# to the test-generating functions and limit the generated +# values. In some cases, for reasonable run times a +# maximum exponent of 9999 is required. +# +# The 'stat' parameter is passed down to the 'verify' +# function, which records statistics for the result values. +# ====================================================================== + +def log(fmt, args=None): + if args: + sys.stdout.write(''.join((fmt, '\n')) % args) + else: + sys.stdout.write(''.join((str(fmt), '\n'))) + sys.stdout.flush() + +def test_method(method, testspecs, testfunc): + """Iterate a test function through many context settings.""" + log("testing %s ...", method) + stat = defaultdict(int) + for spec in testspecs: + if 'samples' in spec: + spec['prec'] = sorted(random.sample(range(1, 101), + spec['samples'])) + for prec in spec['prec']: + context.prec = prec + for expts in spec['expts']: + emin, emax = expts + if emin == 'rand': + context.Emin = random.randrange(-1000, 0) + context.Emax = random.randrange(prec, 1000) + else: + context.Emin, context.Emax = emin, emax + if prec > context.Emax: continue + log(" prec: %d emin: %d emax: %d", + (context.prec, context.Emin, context.Emax)) + restr_range = 9999 if context.Emax > 9999 else context.Emax+99 + for rounding in RoundModes: + context.rounding = rounding + context.capitals = random.randrange(2) + if spec['clamp'] == 'rand': + context.clamp = random.randrange(2) + else: + context.clamp = spec['clamp'] + exprange = context.c.Emax + testfunc(method, prec, exprange, restr_range, + spec['iter'], stat) + log(" result types: %s" % sorted([t for t in stat.items()])) + +def test_unary(method, prec, exp_range, restricted_range, itr, stat): + """Iterate a unary function through many test cases.""" + if method in UnaryRestricted: + exp_range = restricted_range + for op in all_unary(prec, exp_range, itr): + t = TestSet(method, op) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + + if not method.startswith('__'): + for op in unary_optarg(prec, exp_range, itr): + t = TestSet(method, op) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + +def test_binary(method, prec, exp_range, restricted_range, itr, stat): + """Iterate a binary function through many test cases.""" + if method in BinaryRestricted: + exp_range = restricted_range + for op in all_binary(prec, exp_range, itr): + t = TestSet(method, op) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + + if not method.startswith('__'): + for op in binary_optarg(prec, exp_range, itr): + t = TestSet(method, op) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + +def test_ternary(method, prec, exp_range, restricted_range, itr, stat): + """Iterate a ternary function through many test cases.""" + if method in TernaryRestricted: + exp_range = restricted_range + for op in all_ternary(prec, exp_range, itr): + t = TestSet(method, op) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + + if not method.startswith('__'): + for op in ternary_optarg(prec, exp_range, itr): + t = TestSet(method, op) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + +def test_format(method, prec, exp_range, restricted_range, itr, stat): + """Iterate the __format__ method through many test cases.""" + for op in all_unary(prec, exp_range, itr): + fmt1 = rand_format(chr(random.randrange(0, 128)), 'EeGgn') + fmt2 = rand_locale() + for fmt in (fmt1, fmt2): + fmtop = (op[0], fmt) + t = TestSet(method, fmtop) + try: + if not convert(t, convstr=False): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + for op in all_unary(prec, 9999, itr): + fmt1 = rand_format(chr(random.randrange(0, 128)), 'Ff%') + fmt2 = rand_locale() + for fmt in (fmt1, fmt2): + fmtop = (op[0], fmt) + t = TestSet(method, fmtop) + try: + if not convert(t, convstr=False): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + +def test_round(method, prec, exprange, restricted_range, itr, stat): + """Iterate the __round__ method through many test cases.""" + for op in all_unary(prec, 9999, itr): + n = random.randrange(10) + roundop = (op[0], n) + t = TestSet(method, roundop) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + +def test_from_float(method, prec, exprange, restricted_range, itr, stat): + """Iterate the __float__ method through many test cases.""" + for rounding in RoundModes: + context.rounding = rounding + for i in range(1000): + f = randfloat() + op = (f,) if method.startswith("context.") else ("sNaN", f) + t = TestSet(method, op) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + +def randcontext(exprange): + c = Context(C.Context(), P.Context()) + c.Emax = random.randrange(1, exprange+1) + c.Emin = random.randrange(-exprange, 0) + maxprec = 100 if c.Emax >= 100 else c.Emax + c.prec = random.randrange(1, maxprec+1) + c.clamp = random.randrange(2) + c.clear_traps() + return c + +def test_quantize_api(method, prec, exprange, restricted_range, itr, stat): + """Iterate the 'quantize' method through many test cases, using + the optional arguments.""" + for op in all_binary(prec, restricted_range, itr): + for rounding in RoundModes: + c = randcontext(exprange) + quantizeop = (op[0], op[1], rounding, c) + t = TestSet(method, quantizeop) + try: + if not convert(t): + continue + callfuncs(t) + verify(t, stat) + except VerifyError as err: + log(err) + + +def check_untested(funcdict, c_cls, p_cls): + """Determine untested, C-only and Python-only attributes. + Uncomment print lines for debugging.""" + c_attr = set(dir(c_cls)) + p_attr = set(dir(p_cls)) + intersect = c_attr & p_attr + + funcdict['c_only'] = tuple(sorted(c_attr-intersect)) + funcdict['p_only'] = tuple(sorted(p_attr-intersect)) + + tested = set() + for lst in funcdict.values(): + for v in lst: + v = v.replace("context.", "") if c_cls == C.Context else v + tested.add(v) + + funcdict['untested'] = tuple(sorted(intersect-tested)) + + #for key in ('untested', 'c_only', 'p_only'): + # s = 'Context' if c_cls == C.Context else 'Decimal' + # print("\n%s %s:\n%s" % (s, key, funcdict[key])) + + +if __name__ == '__main__': + + import time + + randseed = int(time.time()) + random.seed(randseed) + + # Set up the testspecs list. A testspec is simply a dictionary + # that determines the amount of different contexts that 'test_method' + # will generate. + base_expts = [(C.MIN_EMIN, C.MAX_EMAX)] + if C.MAX_EMAX == 999999999999999999: + base_expts.append((-999999999, 999999999)) + + # Basic contexts. + base = { + 'expts': base_expts, + 'prec': [], + 'clamp': 'rand', + 'iter': None, + 'samples': None, + } + # Contexts with small values for prec, emin, emax. + small = { + 'prec': [1, 2, 3, 4, 5], + 'expts': [(-1, 1), (-2, 2), (-3, 3), (-4, 4), (-5, 5)], + 'clamp': 'rand', + 'iter': None + } + # IEEE interchange format. + ieee = [ + # DECIMAL32 + {'prec': [7], 'expts': [(-95, 96)], 'clamp': 1, 'iter': None}, + # DECIMAL64 + {'prec': [16], 'expts': [(-383, 384)], 'clamp': 1, 'iter': None}, + # DECIMAL128 + {'prec': [34], 'expts': [(-6143, 6144)], 'clamp': 1, 'iter': None} + ] + + if '--medium' in sys.argv: + base['expts'].append(('rand', 'rand')) + # 5 random precisions + base['samples'] = 5 + testspecs = [small] + ieee + [base] + if '--long' in sys.argv: + base['expts'].append(('rand', 'rand')) + # 10 random precisions + base['samples'] = 10 + testspecs = [small] + ieee + [base] + elif '--all' in sys.argv: + base['expts'].append(('rand', 'rand')) + # All precisions in [1, 100] + base['samples'] = 100 + testspecs = [small] + ieee + [base] + else: # --short + rand_ieee = random.choice(ieee) + base['iter'] = small['iter'] = rand_ieee['iter'] = 1 + # 1 random precision and exponent pair + base['samples'] = 1 + base['expts'] = [random.choice(base_expts)] + # 1 random precision and exponent pair + prec = random.randrange(1, 6) + small['prec'] = [prec] + small['expts'] = [(-prec, prec)] + testspecs = [small, rand_ieee, base] + + check_untested(Functions, C.Decimal, P.Decimal) + check_untested(ContextFunctions, C.Context, P.Context) + + + log("\n\nRandom seed: %d\n\n", randseed) + + # Decimal methods: + for method in Functions['unary'] + Functions['unary_ctx'] + \ + Functions['unary_rnd_ctx']: + test_method(method, testspecs, test_unary) + + for method in Functions['binary'] + Functions['binary_ctx']: + test_method(method, testspecs, test_binary) + + for method in Functions['ternary'] + Functions['ternary_ctx']: + test_method(method, testspecs, test_ternary) + + test_method('__format__', testspecs, test_format) + test_method('__round__', testspecs, test_round) + test_method('from_float', testspecs, test_from_float) + test_method('quantize', testspecs, test_quantize_api) + + # Context methods: + for method in ContextFunctions['unary']: + test_method(method, testspecs, test_unary) + + for method in ContextFunctions['binary']: + test_method(method, testspecs, test_binary) + + for method in ContextFunctions['ternary']: + test_method(method, testspecs, test_ternary) + + test_method('context.create_decimal_from_float', testspecs, test_from_float) + + + sys.exit(EXIT_STATUS) diff --git a/python/Modules/_decimal/tests/formathelper.py b/python/Modules/_decimal/tests/formathelper.py new file mode 100755 index 0000000..19b2aad --- /dev/null +++ b/python/Modules/_decimal/tests/formathelper.py @@ -0,0 +1,342 @@ +# +# 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. +# + + +# Generate PEP-3101 format strings. + + +import os, sys, locale, random +import platform, subprocess +from test.support import import_fresh_module +from distutils.spawn import find_executable + +C = import_fresh_module('decimal', fresh=['_decimal']) +P = import_fresh_module('decimal', blocked=['_decimal']) + + +windows_lang_strings = [ + "chinese", "chinese-simplified", "chinese-traditional", "czech", "danish", + "dutch", "belgian", "english", "australian", "canadian", "english-nz", + "english-uk", "english-us", "finnish", "french", "french-belgian", + "french-canadian", "french-swiss", "german", "german-austrian", + "german-swiss", "greek", "hungarian", "icelandic", "italian", "italian-swiss", + "japanese", "korean", "norwegian", "norwegian-bokmal", "norwegian-nynorsk", + "polish", "portuguese", "portuguese-brazil", "russian", "slovak", "spanish", + "spanish-mexican", "spanish-modern", "swedish", "turkish", +] + +preferred_encoding = { + 'cs_CZ': 'ISO8859-2', + 'cs_CZ.iso88592': 'ISO8859-2', + 'czech': 'ISO8859-2', + 'eesti': 'ISO8859-1', + 'estonian': 'ISO8859-1', + 'et_EE': 'ISO8859-15', + 'et_EE.ISO-8859-15': 'ISO8859-15', + 'et_EE.iso885915': 'ISO8859-15', + 'et_EE.iso88591': 'ISO8859-1', + 'fi_FI.iso88591': 'ISO8859-1', + 'fi_FI': 'ISO8859-15', + 'fi_FI@euro': 'ISO8859-15', + 'fi_FI.iso885915@euro': 'ISO8859-15', + 'finnish': 'ISO8859-1', + 'lv_LV': 'ISO8859-13', + 'lv_LV.iso885913': 'ISO8859-13', + 'nb_NO': 'ISO8859-1', + 'nb_NO.iso88591': 'ISO8859-1', + 'bokmal': 'ISO8859-1', + 'nn_NO': 'ISO8859-1', + 'nn_NO.iso88591': 'ISO8859-1', + 'no_NO': 'ISO8859-1', + 'norwegian': 'ISO8859-1', + 'nynorsk': 'ISO8859-1', + 'ru_RU': 'ISO8859-5', + 'ru_RU.iso88595': 'ISO8859-5', + 'russian': 'ISO8859-5', + 'ru_RU.KOI8-R': 'KOI8-R', + 'ru_RU.koi8r': 'KOI8-R', + 'ru_RU.CP1251': 'CP1251', + 'ru_RU.cp1251': 'CP1251', + 'sk_SK': 'ISO8859-2', + 'sk_SK.iso88592': 'ISO8859-2', + 'slovak': 'ISO8859-2', + 'sv_FI': 'ISO8859-1', + 'sv_FI.iso88591': 'ISO8859-1', + 'sv_FI@euro': 'ISO8859-15', + 'sv_FI.iso885915@euro': 'ISO8859-15', + 'uk_UA': 'KOI8-U', + 'uk_UA.koi8u': 'KOI8-U' +} + +integers = [ + "", + "1", + "12", + "123", + "1234", + "12345", + "123456", + "1234567", + "12345678", + "123456789", + "1234567890", + "12345678901", + "123456789012", + "1234567890123", + "12345678901234", + "123456789012345", + "1234567890123456", + "12345678901234567", + "123456789012345678", + "1234567890123456789", + "12345678901234567890", + "123456789012345678901", + "1234567890123456789012", +] + +numbers = [ + "0", "-0", "+0", + "0.0", "-0.0", "+0.0", + "0e0", "-0e0", "+0e0", + ".0", "-.0", + ".1", "-.1", + "1.1", "-1.1", + "1e1", "-1e1" +] + +# Get the list of available locales. +if platform.system() == 'Windows': + locale_list = windows_lang_strings +else: + locale_list = ['C'] + if os.path.isfile("/var/lib/locales/supported.d/local"): + # On Ubuntu, `locale -a` gives the wrong case for some locales, + # so we get the correct names directly: + with open("/var/lib/locales/supported.d/local") as f: + locale_list = [loc.split()[0] for loc in f.readlines() \ + if not loc.startswith('#')] + elif find_executable('locale'): + locale_list = subprocess.Popen(["locale", "-a"], + stdout=subprocess.PIPE).communicate()[0] + try: + locale_list = locale_list.decode() + except UnicodeDecodeError: + # Some distributions insist on using latin-1 characters + # in their locale names. + locale_list = locale_list.decode('latin-1') + locale_list = locale_list.split('\n') +try: + locale_list.remove('') +except ValueError: + pass + +# Debian +if os.path.isfile("/etc/locale.alias"): + with open("/etc/locale.alias") as f: + while 1: + try: + line = f.readline() + except UnicodeDecodeError: + continue + if line == "": + break + if line.startswith('#'): + continue + x = line.split() + if len(x) == 2: + if x[0] in locale_list: + locale_list.remove(x[0]) + +# FreeBSD +if platform.system() == 'FreeBSD': + # http://www.freebsd.org/cgi/query-pr.cgi?pr=142173 + # en_GB.US-ASCII has 163 as the currency symbol. + for loc in ['it_CH.ISO8859-1', 'it_CH.ISO8859-15', 'it_CH.UTF-8', + 'it_IT.ISO8859-1', 'it_IT.ISO8859-15', 'it_IT.UTF-8', + 'sl_SI.ISO8859-2', 'sl_SI.UTF-8', + 'en_GB.US-ASCII']: + try: + locale_list.remove(loc) + except ValueError: + pass + +# Print a testcase in the format of the IBM tests (for runtest.c): +def get_preferred_encoding(): + loc = locale.setlocale(locale.LC_CTYPE) + if loc in preferred_encoding: + return preferred_encoding[loc] + else: + return locale.getpreferredencoding() + +def printit(testno, s, fmt, encoding=None): + if not encoding: + encoding = get_preferred_encoding() + try: + result = format(P.Decimal(s), fmt) + fmt = str(fmt.encode(encoding))[2:-1] + result = str(result.encode(encoding))[2:-1] + if "'" in result: + sys.stdout.write("xfmt%d format %s '%s' -> \"%s\"\n" + % (testno, s, fmt, result)) + else: + sys.stdout.write("xfmt%d format %s '%s' -> '%s'\n" + % (testno, s, fmt, result)) + except Exception as err: + sys.stderr.write("%s %s %s\n" % (err, s, fmt)) + + +# Check if an integer can be converted to a valid fill character. +def check_fillchar(i): + try: + c = chr(i) + c.encode('utf-8').decode() + format(P.Decimal(0), c + '<19g') + return c + except: + return None + +# Generate all unicode characters that are accepted as +# fill characters by decimal.py. +def all_fillchars(): + for i in range(0, 0x110002): + c = check_fillchar(i) + if c: yield c + +# Return random fill character. +def rand_fillchar(): + while 1: + i = random.randrange(0, 0x110002) + c = check_fillchar(i) + if c: return c + +# Generate random format strings +# [[fill]align][sign][#][0][width][.precision][type] +def rand_format(fill, typespec='EeGgFfn%'): + active = sorted(random.sample(range(7), random.randrange(8))) + have_align = 0 + s = '' + for elem in active: + if elem == 0: # fill+align + s += fill + s += random.choice('<>=^') + have_align = 1 + elif elem == 1: # sign + s += random.choice('+- ') + elif elem == 2 and not have_align: # zeropad + s += '0' + elif elem == 3: # width + s += str(random.randrange(1, 100)) + elif elem == 4: # thousands separator + s += ',' + elif elem == 5: # prec + s += '.' + s += str(random.randrange(100)) + elif elem == 6: + if 4 in active: c = typespec.replace('n', '') + else: c = typespec + s += random.choice(c) + return s + +# Partially brute force all possible format strings containing a thousands +# separator. Fall back to random where the runtime would become excessive. +# [[fill]align][sign][#][0][width][,][.precision][type] +def all_format_sep(): + for align in ('', '<', '>', '=', '^'): + for fill in ('', 'x'): + if align == '': fill = '' + for sign in ('', '+', '-', ' '): + for zeropad in ('', '0'): + if align != '': zeropad = '' + for width in ['']+[str(y) for y in range(1, 15)]+['101']: + for prec in ['']+['.'+str(y) for y in range(15)]: + # for type in ('', 'E', 'e', 'G', 'g', 'F', 'f', '%'): + type = random.choice(('', 'E', 'e', 'G', 'g', 'F', 'f', '%')) + yield ''.join((fill, align, sign, zeropad, width, ',', prec, type)) + +# Partially brute force all possible format strings with an 'n' specifier. +# [[fill]align][sign][#][0][width][,][.precision][type] +def all_format_loc(): + for align in ('', '<', '>', '=', '^'): + for fill in ('', 'x'): + if align == '': fill = '' + for sign in ('', '+', '-', ' '): + for zeropad in ('', '0'): + if align != '': zeropad = '' + for width in ['']+[str(y) for y in range(1, 20)]+['101']: + for prec in ['']+['.'+str(y) for y in range(1, 20)]: + yield ''.join((fill, align, sign, zeropad, width, prec, 'n')) + +# Generate random format strings with a unicode fill character +# [[fill]align][sign][#][0][width][,][.precision][type] +def randfill(fill): + active = sorted(random.sample(range(5), random.randrange(6))) + s = '' + s += str(fill) + s += random.choice('<>=^') + for elem in active: + if elem == 0: # sign + s += random.choice('+- ') + elif elem == 1: # width + s += str(random.randrange(1, 100)) + elif elem == 2: # thousands separator + s += ',' + elif elem == 3: # prec + s += '.' + s += str(random.randrange(100)) + elif elem == 4: + if 2 in active: c = 'EeGgFf%' + else: c = 'EeGgFfn%' + s += random.choice(c) + return s + +# Generate random format strings with random locale setting +# [[fill]align][sign][#][0][width][,][.precision][type] +def rand_locale(): + try: + loc = random.choice(locale_list) + locale.setlocale(locale.LC_ALL, loc) + except locale.Error as err: + pass + active = sorted(random.sample(range(5), random.randrange(6))) + s = '' + have_align = 0 + for elem in active: + if elem == 0: # fill+align + s += chr(random.randrange(32, 128)) + s += random.choice('<>=^') + have_align = 1 + elif elem == 1: # sign + s += random.choice('+- ') + elif elem == 2 and not have_align: # zeropad + s += '0' + elif elem == 3: # width + s += str(random.randrange(1, 100)) + elif elem == 4: # prec + s += '.' + s += str(random.randrange(100)) + s += 'n' + return s diff --git a/python/Modules/_decimal/tests/randdec.py b/python/Modules/_decimal/tests/randdec.py new file mode 100755 index 0000000..d667f79 --- /dev/null +++ b/python/Modules/_decimal/tests/randdec.py @@ -0,0 +1,575 @@ +# +# 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. +# + + +# Generate test cases for deccheck.py. + + +# +# Grammar from http://speleotrove.com/decimal/daconvs.html +# +# sign ::= '+' | '-' +# digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | +# '8' | '9' +# indicator ::= 'e' | 'E' +# digits ::= digit [digit]... +# decimal-part ::= digits '.' [digits] | ['.'] digits +# exponent-part ::= indicator [sign] digits +# infinity ::= 'Infinity' | 'Inf' +# nan ::= 'NaN' [digits] | 'sNaN' [digits] +# numeric-value ::= decimal-part [exponent-part] | infinity +# numeric-string ::= [sign] numeric-value | [sign] nan +# + + +from random import randrange, sample +from fractions import Fraction +from randfloat import un_randfloat, bin_randfloat, tern_randfloat + + +def sign(): + if randrange(2): + if randrange(2): return '+' + return '' + return '-' + +def indicator(): + return "eE"[randrange(2)] + +def digits(maxprec): + if maxprec == 0: return '' + return str(randrange(10**maxprec)) + +def dot(): + if randrange(2): return '.' + return '' + +def decimal_part(maxprec): + if randrange(100) > 60: # integers + return digits(maxprec) + if randrange(2): + intlen = randrange(1, maxprec+1) + fraclen = maxprec-intlen + intpart = digits(intlen) + fracpart = digits(fraclen) + return ''.join((intpart, '.', fracpart)) + else: + return ''.join((dot(), digits(maxprec))) + +def expdigits(maxexp): + return str(randrange(maxexp)) + +def exponent_part(maxexp): + return ''.join((indicator(), sign(), expdigits(maxexp))) + +def infinity(): + if randrange(2): return 'Infinity' + return 'Inf' + +def nan(): + d = '' + if randrange(2): + d = digits(randrange(99)) + if randrange(2): + return ''.join(('NaN', d)) + else: + return ''.join(('sNaN', d)) + +def numeric_value(maxprec, maxexp): + if randrange(100) > 90: + return infinity() + exp_part = '' + if randrange(100) > 60: + exp_part = exponent_part(maxexp) + return ''.join((decimal_part(maxprec), exp_part)) + +def numeric_string(maxprec, maxexp): + if randrange(100) > 95: + return ''.join((sign(), nan())) + else: + return ''.join((sign(), numeric_value(maxprec, maxexp))) + +def randdec(maxprec, maxexp): + return numeric_string(maxprec, maxexp) + +def rand_adjexp(maxprec, maxadjexp): + d = digits(maxprec) + maxexp = maxadjexp-len(d)+1 + if maxexp == 0: maxexp = 1 + exp = str(randrange(maxexp-2*(abs(maxexp)), maxexp)) + return ''.join((sign(), d, 'E', exp)) + + +def ndigits(n): + if n < 1: return 0 + return randrange(10**(n-1), 10**n) + +def randtuple(maxprec, maxexp): + n = randrange(100) + sign = randrange(2) + coeff = ndigits(maxprec) + if n >= 95: + coeff = () + exp = 'F' + elif n >= 85: + coeff = tuple(map(int, str(ndigits(maxprec)))) + exp = "nN"[randrange(2)] + else: + coeff = tuple(map(int, str(ndigits(maxprec)))) + exp = randrange(-maxexp, maxexp) + return (sign, coeff, exp) + +def from_triple(sign, coeff, exp): + return ''.join((str(sign*coeff), indicator(), str(exp))) + + +# Close to 10**n +def un_close_to_pow10(prec, maxexp, itr=None): + if itr is None: + lst = range(prec+30) + else: + lst = sample(range(prec+30), itr) + nines = [10**n - 1 for n in lst] + pow10 = [10**n for n in lst] + for coeff in nines: + yield coeff + yield -coeff + yield from_triple(1, coeff, randrange(2*maxexp)) + yield from_triple(-1, coeff, randrange(2*maxexp)) + for coeff in pow10: + yield coeff + yield -coeff + +# Close to 10**n +def bin_close_to_pow10(prec, maxexp, itr=None): + if itr is None: + lst = range(prec+30) + else: + lst = sample(range(prec+30), itr) + nines = [10**n - 1 for n in lst] + pow10 = [10**n for n in lst] + for coeff in nines: + yield coeff, 1 + yield -coeff, -1 + yield 1, coeff + yield -1, -coeff + yield from_triple(1, coeff, randrange(2*maxexp)), 1 + yield from_triple(-1, coeff, randrange(2*maxexp)), -1 + yield 1, from_triple(1, coeff, -randrange(2*maxexp)) + yield -1, from_triple(-1, coeff, -randrange(2*maxexp)) + for coeff in pow10: + yield coeff, -1 + yield -coeff, 1 + yield 1, -coeff + yield -coeff, 1 + +# Close to 1: +def close_to_one_greater(prec, emax, emin): + rprec = 10**prec + return ''.join(("1.", '0'*randrange(prec), + str(randrange(rprec)))) + +def close_to_one_less(prec, emax, emin): + rprec = 10**prec + return ''.join(("0.9", '9'*randrange(prec), + str(randrange(rprec)))) + +# Close to 0: +def close_to_zero_greater(prec, emax, emin): + rprec = 10**prec + return ''.join(("0.", '0'*randrange(prec), + str(randrange(rprec)))) + +def close_to_zero_less(prec, emax, emin): + rprec = 10**prec + return ''.join(("-0.", '0'*randrange(prec), + str(randrange(rprec)))) + +# Close to emax: +def close_to_emax_less(prec, emax, emin): + rprec = 10**prec + return ''.join(("9.", '9'*randrange(prec), + str(randrange(rprec)), "E", str(emax))) + +def close_to_emax_greater(prec, emax, emin): + rprec = 10**prec + return ''.join(("1.", '0'*randrange(prec), + str(randrange(rprec)), "E", str(emax+1))) + +# Close to emin: +def close_to_emin_greater(prec, emax, emin): + rprec = 10**prec + return ''.join(("1.", '0'*randrange(prec), + str(randrange(rprec)), "E", str(emin))) + +def close_to_emin_less(prec, emax, emin): + rprec = 10**prec + return ''.join(("9.", '9'*randrange(prec), + str(randrange(rprec)), "E", str(emin-1))) + +# Close to etiny: +def close_to_etiny_greater(prec, emax, emin): + rprec = 10**prec + etiny = emin - (prec - 1) + return ''.join(("1.", '0'*randrange(prec), + str(randrange(rprec)), "E", str(etiny))) + +def close_to_etiny_less(prec, emax, emin): + rprec = 10**prec + etiny = emin - (prec - 1) + return ''.join(("9.", '9'*randrange(prec), + str(randrange(rprec)), "E", str(etiny-1))) + + +def close_to_min_etiny_greater(prec, max_prec, min_emin): + rprec = 10**prec + etiny = min_emin - (max_prec - 1) + return ''.join(("1.", '0'*randrange(prec), + str(randrange(rprec)), "E", str(etiny))) + +def close_to_min_etiny_less(prec, max_prec, min_emin): + rprec = 10**prec + etiny = min_emin - (max_prec - 1) + return ''.join(("9.", '9'*randrange(prec), + str(randrange(rprec)), "E", str(etiny-1))) + + +close_funcs = [ + close_to_one_greater, close_to_one_less, close_to_zero_greater, + close_to_zero_less, close_to_emax_less, close_to_emax_greater, + close_to_emin_greater, close_to_emin_less, close_to_etiny_greater, + close_to_etiny_less, close_to_min_etiny_greater, close_to_min_etiny_less +] + + +def un_close_numbers(prec, emax, emin, itr=None): + if itr is None: + itr = 1000 + for _ in range(itr): + for func in close_funcs: + yield func(prec, emax, emin) + +def bin_close_numbers(prec, emax, emin, itr=None): + if itr is None: + itr = 1000 + for _ in range(itr): + for func1 in close_funcs: + for func2 in close_funcs: + yield func1(prec, emax, emin), func2(prec, emax, emin) + for func in close_funcs: + yield randdec(prec, emax), func(prec, emax, emin) + yield func(prec, emax, emin), randdec(prec, emax) + +def tern_close_numbers(prec, emax, emin, itr): + if itr is None: + itr = 1000 + for _ in range(itr): + for func1 in close_funcs: + for func2 in close_funcs: + for func3 in close_funcs: + yield (func1(prec, emax, emin), func2(prec, emax, emin), + func3(prec, emax, emin)) + for func in close_funcs: + yield (randdec(prec, emax), func(prec, emax, emin), + func(prec, emax, emin)) + yield (func(prec, emax, emin), randdec(prec, emax), + func(prec, emax, emin)) + yield (func(prec, emax, emin), func(prec, emax, emin), + randdec(prec, emax)) + for func in close_funcs: + yield (randdec(prec, emax), randdec(prec, emax), + func(prec, emax, emin)) + yield (randdec(prec, emax), func(prec, emax, emin), + randdec(prec, emax)) + yield (func(prec, emax, emin), randdec(prec, emax), + randdec(prec, emax)) + + +# If itr == None, test all digit lengths up to prec + 30 +def un_incr_digits(prec, maxexp, itr): + if itr is None: + lst = range(prec+30) + else: + lst = sample(range(prec+30), itr) + for m in lst: + yield from_triple(1, ndigits(m), 0) + yield from_triple(-1, ndigits(m), 0) + yield from_triple(1, ndigits(m), randrange(maxexp)) + yield from_triple(-1, ndigits(m), randrange(maxexp)) + +# If itr == None, test all digit lengths up to prec + 30 +# Also output decimals im tuple form. +def un_incr_digits_tuple(prec, maxexp, itr): + if itr is None: + lst = range(prec+30) + else: + lst = sample(range(prec+30), itr) + for m in lst: + yield from_triple(1, ndigits(m), 0) + yield from_triple(-1, ndigits(m), 0) + yield from_triple(1, ndigits(m), randrange(maxexp)) + yield from_triple(-1, ndigits(m), randrange(maxexp)) + # test from tuple + yield (0, tuple(map(int, str(ndigits(m)))), 0) + yield (1, tuple(map(int, str(ndigits(m)))), 0) + yield (0, tuple(map(int, str(ndigits(m)))), randrange(maxexp)) + yield (1, tuple(map(int, str(ndigits(m)))), randrange(maxexp)) + +# If itr == None, test all combinations of digit lengths up to prec + 30 +def bin_incr_digits(prec, maxexp, itr): + if itr is None: + lst1 = range(prec+30) + lst2 = range(prec+30) + else: + lst1 = sample(range(prec+30), itr) + lst2 = sample(range(prec+30), itr) + for m in lst1: + x = from_triple(1, ndigits(m), 0) + yield x, x + x = from_triple(-1, ndigits(m), 0) + yield x, x + x = from_triple(1, ndigits(m), randrange(maxexp)) + yield x, x + x = from_triple(-1, ndigits(m), randrange(maxexp)) + yield x, x + for m in lst1: + for n in lst2: + x = from_triple(1, ndigits(m), 0) + y = from_triple(1, ndigits(n), 0) + yield x, y + x = from_triple(-1, ndigits(m), 0) + y = from_triple(1, ndigits(n), 0) + yield x, y + x = from_triple(1, ndigits(m), 0) + y = from_triple(-1, ndigits(n), 0) + yield x, y + x = from_triple(-1, ndigits(m), 0) + y = from_triple(-1, ndigits(n), 0) + yield x, y + x = from_triple(1, ndigits(m), randrange(maxexp)) + y = from_triple(1, ndigits(n), randrange(maxexp)) + yield x, y + x = from_triple(-1, ndigits(m), randrange(maxexp)) + y = from_triple(1, ndigits(n), randrange(maxexp)) + yield x, y + x = from_triple(1, ndigits(m), randrange(maxexp)) + y = from_triple(-1, ndigits(n), randrange(maxexp)) + yield x, y + x = from_triple(-1, ndigits(m), randrange(maxexp)) + y = from_triple(-1, ndigits(n), randrange(maxexp)) + yield x, y + + +def randsign(): + return (1, -1)[randrange(2)] + +# If itr == None, test all combinations of digit lengths up to prec + 30 +def tern_incr_digits(prec, maxexp, itr): + if itr is None: + lst1 = range(prec+30) + lst2 = range(prec+30) + lst3 = range(prec+30) + else: + lst1 = sample(range(prec+30), itr) + lst2 = sample(range(prec+30), itr) + lst3 = sample(range(prec+30), itr) + for m in lst1: + for n in lst2: + for p in lst3: + x = from_triple(randsign(), ndigits(m), 0) + y = from_triple(randsign(), ndigits(n), 0) + z = from_triple(randsign(), ndigits(p), 0) + yield x, y, z + + +# Tests for the 'logical' functions +def bindigits(prec): + z = 0 + for i in range(prec): + z += randrange(2) * 10**i + return z + +def logical_un_incr_digits(prec, itr): + if itr is None: + lst = range(prec+30) + else: + lst = sample(range(prec+30), itr) + for m in lst: + yield from_triple(1, bindigits(m), 0) + +def logical_bin_incr_digits(prec, itr): + if itr is None: + lst1 = range(prec+30) + lst2 = range(prec+30) + else: + lst1 = sample(range(prec+30), itr) + lst2 = sample(range(prec+30), itr) + for m in lst1: + x = from_triple(1, bindigits(m), 0) + yield x, x + for m in lst1: + for n in lst2: + x = from_triple(1, bindigits(m), 0) + y = from_triple(1, bindigits(n), 0) + yield x, y + + +def randint(): + p = randrange(1, 100) + return ndigits(p) * (1,-1)[randrange(2)] + +def randfloat(): + p = randrange(1, 100) + s = numeric_value(p, 383) + try: + f = float(numeric_value(p, 383)) + except ValueError: + f = 0.0 + return f + +def randcomplex(): + real = randfloat() + if randrange(100) > 30: + imag = 0.0 + else: + imag = randfloat() + return complex(real, imag) + +def randfraction(): + num = randint() + denom = randint() + if denom == 0: + denom = 1 + return Fraction(num, denom) + +number_funcs = [randint, randfloat, randcomplex, randfraction] + +def un_random_mixed_op(itr=None): + if itr is None: + itr = 1000 + for _ in range(itr): + for func in number_funcs: + yield func() + # Test garbage input + for x in (['x'], ('y',), {'z'}, {1:'z'}): + yield x + +def bin_random_mixed_op(prec, emax, emin, itr=None): + if itr is None: + itr = 1000 + for _ in range(itr): + for func in number_funcs: + yield randdec(prec, emax), func() + yield func(), randdec(prec, emax) + for number in number_funcs: + for dec in close_funcs: + yield dec(prec, emax, emin), number() + # Test garbage input + for x in (['x'], ('y',), {'z'}, {1:'z'}): + for y in (['x'], ('y',), {'z'}, {1:'z'}): + yield x, y + +def tern_random_mixed_op(prec, emax, emin, itr): + if itr is None: + itr = 1000 + for _ in range(itr): + for func in number_funcs: + yield randdec(prec, emax), randdec(prec, emax), func() + yield randdec(prec, emax), func(), func() + yield func(), func(), func() + # Test garbage input + for x in (['x'], ('y',), {'z'}, {1:'z'}): + for y in (['x'], ('y',), {'z'}, {1:'z'}): + for z in (['x'], ('y',), {'z'}, {1:'z'}): + yield x, y, z + +def all_unary(prec, exp_range, itr): + for a in un_close_to_pow10(prec, exp_range, itr): + yield (a,) + for a in un_close_numbers(prec, exp_range, -exp_range, itr): + yield (a,) + for a in un_incr_digits_tuple(prec, exp_range, itr): + yield (a,) + for a in un_randfloat(): + yield (a,) + for a in un_random_mixed_op(itr): + yield (a,) + for a in logical_un_incr_digits(prec, itr): + yield (a,) + for _ in range(100): + yield (randdec(prec, exp_range),) + for _ in range(100): + yield (randtuple(prec, exp_range),) + +def unary_optarg(prec, exp_range, itr): + for _ in range(100): + yield randdec(prec, exp_range), None + yield randdec(prec, exp_range), None, None + +def all_binary(prec, exp_range, itr): + for a, b in bin_close_to_pow10(prec, exp_range, itr): + yield a, b + for a, b in bin_close_numbers(prec, exp_range, -exp_range, itr): + yield a, b + for a, b in bin_incr_digits(prec, exp_range, itr): + yield a, b + for a, b in bin_randfloat(): + yield a, b + for a, b in bin_random_mixed_op(prec, exp_range, -exp_range, itr): + yield a, b + for a, b in logical_bin_incr_digits(prec, itr): + yield a, b + for _ in range(100): + yield randdec(prec, exp_range), randdec(prec, exp_range) + +def binary_optarg(prec, exp_range, itr): + for _ in range(100): + yield randdec(prec, exp_range), randdec(prec, exp_range), None + yield randdec(prec, exp_range), randdec(prec, exp_range), None, None + +def all_ternary(prec, exp_range, itr): + for a, b, c in tern_close_numbers(prec, exp_range, -exp_range, itr): + yield a, b, c + for a, b, c in tern_incr_digits(prec, exp_range, itr): + yield a, b, c + for a, b, c in tern_randfloat(): + yield a, b, c + for a, b, c in tern_random_mixed_op(prec, exp_range, -exp_range, itr): + yield a, b, c + for _ in range(100): + a = randdec(prec, 2*exp_range) + b = randdec(prec, 2*exp_range) + c = randdec(prec, 2*exp_range) + yield a, b, c + +def ternary_optarg(prec, exp_range, itr): + for _ in range(100): + a = randdec(prec, 2*exp_range) + b = randdec(prec, 2*exp_range) + c = randdec(prec, 2*exp_range) + yield a, b, c, None + yield a, b, c, None, None diff --git a/python/Modules/_decimal/tests/randfloat.py b/python/Modules/_decimal/tests/randfloat.py new file mode 100755 index 0000000..1687303 --- /dev/null +++ b/python/Modules/_decimal/tests/randfloat.py @@ -0,0 +1,250 @@ +# Copyright (c) 2010 Python Software Foundation. All Rights Reserved. +# Adapted from Python's Lib/test/test_strtod.py (by Mark Dickinson) + +# More test cases for deccheck.py. + +import random + +TEST_SIZE = 2 + + +def test_short_halfway_cases(): + # exact halfway cases with a small number of significant digits + for k in 0, 5, 10, 15, 20: + # upper = smallest integer >= 2**54/5**k + upper = -(-2**54//5**k) + # lower = smallest odd number >= 2**53/5**k + lower = -(-2**53//5**k) + if lower % 2 == 0: + lower += 1 + for i in range(10 * TEST_SIZE): + # Select a random odd n in [2**53/5**k, + # 2**54/5**k). Then n * 10**k gives a halfway case + # with small number of significant digits. + n, e = random.randrange(lower, upper, 2), k + + # Remove any additional powers of 5. + while n % 5 == 0: + n, e = n // 5, e + 1 + assert n % 10 in (1, 3, 7, 9) + + # Try numbers of the form n * 2**p2 * 10**e, p2 >= 0, + # until n * 2**p2 has more than 20 significant digits. + digits, exponent = n, e + while digits < 10**20: + s = '{}e{}'.format(digits, exponent) + yield s + # Same again, but with extra trailing zeros. + s = '{}e{}'.format(digits * 10**40, exponent - 40) + yield s + digits *= 2 + + # Try numbers of the form n * 5**p2 * 10**(e - p5), p5 + # >= 0, with n * 5**p5 < 10**20. + digits, exponent = n, e + while digits < 10**20: + s = '{}e{}'.format(digits, exponent) + yield s + # Same again, but with extra trailing zeros. + s = '{}e{}'.format(digits * 10**40, exponent - 40) + yield s + digits *= 5 + exponent -= 1 + +def test_halfway_cases(): + # test halfway cases for the round-half-to-even rule + for i in range(1000): + for j in range(TEST_SIZE): + # bit pattern for a random finite positive (or +0.0) float + bits = random.randrange(2047*2**52) + + # convert bit pattern to a number of the form m * 2**e + e, m = divmod(bits, 2**52) + if e: + m, e = m + 2**52, e - 1 + e -= 1074 + + # add 0.5 ulps + m, e = 2*m + 1, e - 1 + + # convert to a decimal string + if e >= 0: + digits = m << e + exponent = 0 + else: + # m * 2**e = (m * 5**-e) * 10**e + digits = m * 5**-e + exponent = e + s = '{}e{}'.format(digits, exponent) + yield s + +def test_boundaries(): + # boundaries expressed as triples (n, e, u), where + # n*10**e is an approximation to the boundary value and + # u*10**e is 1ulp + boundaries = [ + (10000000000000000000, -19, 1110), # a power of 2 boundary (1.0) + (17976931348623159077, 289, 1995), # overflow boundary (2.**1024) + (22250738585072013831, -327, 4941), # normal/subnormal (2.**-1022) + (0, -327, 4941), # zero + ] + for n, e, u in boundaries: + for j in range(1000): + for i in range(TEST_SIZE): + digits = n + random.randrange(-3*u, 3*u) + exponent = e + s = '{}e{}'.format(digits, exponent) + yield s + n *= 10 + u *= 10 + e -= 1 + +def test_underflow_boundary(): + # test values close to 2**-1075, the underflow boundary; similar + # to boundary_tests, except that the random error doesn't scale + # with n + for exponent in range(-400, -320): + base = 10**-exponent // 2**1075 + for j in range(TEST_SIZE): + digits = base + random.randrange(-1000, 1000) + s = '{}e{}'.format(digits, exponent) + yield s + +def test_bigcomp(): + for ndigs in 5, 10, 14, 15, 16, 17, 18, 19, 20, 40, 41, 50: + dig10 = 10**ndigs + for i in range(100 * TEST_SIZE): + digits = random.randrange(dig10) + exponent = random.randrange(-400, 400) + s = '{}e{}'.format(digits, exponent) + yield s + +def test_parsing(): + # make '0' more likely to be chosen than other digits + digits = '000000123456789' + signs = ('+', '-', '') + + # put together random short valid strings + # \d*[.\d*]?e + for i in range(1000): + for j in range(TEST_SIZE): + s = random.choice(signs) + intpart_len = random.randrange(5) + s += ''.join(random.choice(digits) for _ in range(intpart_len)) + if random.choice([True, False]): + s += '.' + fracpart_len = random.randrange(5) + s += ''.join(random.choice(digits) + for _ in range(fracpart_len)) + else: + fracpart_len = 0 + if random.choice([True, False]): + s += random.choice(['e', 'E']) + s += random.choice(signs) + exponent_len = random.randrange(1, 4) + s += ''.join(random.choice(digits) + for _ in range(exponent_len)) + + if intpart_len + fracpart_len: + yield s + +test_particular = [ + # squares + '1.00000000100000000025', + '1.0000000000000000000000000100000000000000000000000' #... + '00025', + '1.0000000000000000000000000000000000000000000010000' #... + '0000000000000000000000000000000000000000025', + '1.0000000000000000000000000000000000000000000000000' #... + '000001000000000000000000000000000000000000000000000' #... + '000000000025', + '0.99999999900000000025', + '0.9999999999999999999999999999999999999999999999999' #... + '999000000000000000000000000000000000000000000000000' #... + '000025', + '0.9999999999999999999999999999999999999999999999999' #... + '999999999999999999999999999999999999999999999999999' #... + '999999999999999999999999999999999999999990000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '0000000000000000000000000000025', + + '1.0000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '100000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000001', + '1.0000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '500000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000005', + '1.0000000000000000000000000000000000000000000000000' #... + '000000000100000000000000000000000000000000000000000' #... + '000000000000000000250000000000000002000000000000000' #... + '000000000000000000000000000000000000000000010000000' #... + '000000000000000000000000000000000000000000000000000' #... + '0000000000000000001', + '1.0000000000000000000000000000000000000000000000000' #... + '000000000100000000000000000000000000000000000000000' #... + '000000000000000000249999999999999999999999999999999' #... + '999999999999979999999999999999999999999999999999999' #... + '999999999999999999999900000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '00000000000000000000000001', + + '0.9999999999999999999999999999999999999999999999999' #... + '999999999900000000000000000000000000000000000000000' #... + '000000000000000000249999999999999998000000000000000' #... + '000000000000000000000000000000000000000000010000000' #... + '000000000000000000000000000000000000000000000000000' #... + '0000000000000000001', + '0.9999999999999999999999999999999999999999999999999' #... + '999999999900000000000000000000000000000000000000000' #... + '000000000000000000250000001999999999999999999999999' #... + '999999999999999999999999999999999990000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '1', + + # tough cases for ln etc. + '1.000000000000000000000000000000000000000000000000' #... + '00000000000000000000000000000000000000000000000000' #... + '00100000000000000000000000000000000000000000000000' #... + '00000000000000000000000000000000000000000000000000' #... + '0001', + '0.999999999999999999999999999999999999999999999999' #... + '99999999999999999999999999999999999999999999999999' #... + '99899999999999999999999999999999999999999999999999' #... + '99999999999999999999999999999999999999999999999999' #... + '99999999999999999999999999999999999999999999999999' #... + '9999' + ] + + +TESTCASES = [ + [x for x in test_short_halfway_cases()], + [x for x in test_halfway_cases()], + [x for x in test_boundaries()], + [x for x in test_underflow_boundary()], + [x for x in test_bigcomp()], + [x for x in test_parsing()], + test_particular +] + +def un_randfloat(): + for i in range(1000): + l = random.choice(TESTCASES[:6]) + yield random.choice(l) + for v in test_particular: + yield v + +def bin_randfloat(): + for i in range(1000): + l1 = random.choice(TESTCASES) + l2 = random.choice(TESTCASES) + yield random.choice(l1), random.choice(l2) + +def tern_randfloat(): + for i in range(1000): + l1 = random.choice(TESTCASES) + l2 = random.choice(TESTCASES) + l3 = random.choice(TESTCASES) + yield random.choice(l1), random.choice(l2), random.choice(l3) diff --git a/python/Modules/_decimal/tests/runall-memorydebugger.sh b/python/Modules/_decimal/tests/runall-memorydebugger.sh new file mode 100755 index 0000000..7f3e527 --- /dev/null +++ b/python/Modules/_decimal/tests/runall-memorydebugger.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +# +# Purpose: test with and without contextvar, all machine configurations, pydebug, +# refleaks, release build and release build with valgrind. +# +# Synopsis: ./runall-memorydebugger.sh [--all-configs64 | --all-configs32] +# +# Requirements: valgrind +# + +# Set additional CFLAGS and LDFLAGS for ./configure +ADD_CFLAGS= +ADD_LDFLAGS= + + +CONFIGS_64="x64 uint128 ansi64 universal" +CONFIGS_32="ppro ansi32 ansi-legacy universal" + +VALGRIND="valgrind --tool=memcheck --leak-resolution=high \ + --suppressions=Misc/valgrind-python.supp" + +# Get args +case $@ in + *--all-configs64*) + CONFIGS=$CONFIGS_64 + ;; + *--all-configs32*) + CONFIGS=$CONFIGS_32 + ;; + *) + CONFIGS="auto" + ;; +esac + +# gmake required +GMAKE=`which gmake` +if [ X"$GMAKE" = X"" ]; then + GMAKE=make +fi + +# Pretty print configurations +print_config () +{ + len=`echo $@ | wc -c` + margin="#%"`expr \( 74 - $len \) / 2`"s" + + echo "" + echo "# ========================================================================" + printf $margin "" + echo $@ + echo "# ========================================================================" + echo "" +} + + +cd .. + +# test_decimal: refleak, regular and Valgrind tests +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do + + unset PYTHON_DECIMAL_WITH_MACHINE + libmpdec_config=$config + if [ X"$config" != X"auto" ]; then + PYTHON_DECIMAL_WITH_MACHINE=$config + export PYTHON_DECIMAL_WITH_MACHINE + else + libmpdec_config="" + fi + + ############ refleak tests ########### + print_config "refleak tests: config=$config" $args + printf "\nbuilding python ...\n\n" + + cd ../../ + $GMAKE distclean > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 + $GMAKE | grep _decimal + + printf "\n\n# ======================== refleak tests ===========================\n\n" + ./python -m test -uall -R 3:3 test_decimal + + + ############ regular tests ########### + print_config "regular tests: config=$config" $args + printf "\nbuilding python ...\n\n" + + $GMAKE distclean > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 + $GMAKE | grep _decimal + + printf "\n\n# ======================== regular tests ===========================\n\n" + ./python -m test -uall test_decimal + + + ########### valgrind tests ########### + valgrind=$VALGRIND + case "$config" in + # Valgrind has no support for 80 bit long double arithmetic. + ppro) valgrind= ;; + auto) case `uname -m` in + i386|i486|i586|i686) valgrind= ;; + esac + esac + + print_config "valgrind tests: config=$config" $args + printf "\nbuilding python ...\n\n" + $GMAKE distclean > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 + $GMAKE | grep _decimal + + printf "\n\n# ======================== valgrind tests ===========================\n\n" + $valgrind ./python -m test -uall test_decimal + + cd Modules/_decimal + done +done + +# deccheck +cd ../../ +for args in "--without-decimal-contextvar" ""; do + for config in $CONFIGS; do + + unset PYTHON_DECIMAL_WITH_MACHINE + if [ X"$config" != X"auto" ]; then + PYTHON_DECIMAL_WITH_MACHINE=$config + export PYTHON_DECIMAL_WITH_MACHINE + fi + + ############ debug ############ + print_config "deccheck: config=$config --with-pydebug" $args + printf "\nbuilding python ...\n\n" + + $GMAKE distclean > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --with-pydebug $args > /dev/null 2>&1 + $GMAKE | grep _decimal + + printf "\n\n# ========================== debug ===========================\n\n" + ./python Modules/_decimal/tests/deccheck.py + + ########### regular ########### + print_config "deccheck: config=$config" $args + printf "\nbuilding python ...\n\n" + + $GMAKE distclean > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" $args > /dev/null 2>&1 + $GMAKE | grep _decimal + + printf "\n\n# ======================== regular ===========================\n\n" + ./python Modules/_decimal/tests/deccheck.py + + ########### valgrind ########### + valgrind=$VALGRIND + case "$config" in + # Valgrind has no support for 80 bit long double arithmetic. + ppro) valgrind= ;; + auto) case `uname -m` in + i386|i486|i586|i686) valgrind= ;; + esac + esac + + print_config "valgrind deccheck: config=$config" $args + printf "\nbuilding python ...\n\n" + + $GMAKE distclean > /dev/null 2>&1 + ./configure CFLAGS="$ADD_CFLAGS" LDFLAGS="$ADD_LDFLAGS" --without-pymalloc $args > /dev/null 2>&1 + $GMAKE | grep _decimal + + printf "\n\n# ======================== valgrind ==========================\n\n" + $valgrind ./python Modules/_decimal/tests/deccheck.py + done +done + + + diff --git a/python/Modules/_decimal/tests/runall.bat b/python/Modules/_decimal/tests/runall.bat new file mode 100755 index 0000000..f278ef3 --- /dev/null +++ b/python/Modules/_decimal/tests/runall.bat @@ -0,0 +1,129 @@ +@ECHO OFF + +rem Test all machine configurations, pydebug, refleaks, release build. + +cd ..\..\..\ + + +echo. +echo # ====================================================================== +echo # Building Python (Debug^|x64) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Debug -p x64 + +echo. +echo # ====================================================================== +echo # platform=Debug^|x64 +echo # ====================================================================== +echo. + +echo # ==================== refleak tests ======================= +echo. +call python.bat -m test -uall -R 3:3 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +echo. +echo # ====================================================================== +echo # Building Python (Release^|x64) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p x64 + +echo. +echo # ====================================================================== +echo # platform=Release^|x64 +echo # ====================================================================== +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +echo. +echo # ====================================================================== +echo # Building Python (Debug^|Win32) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call Tools\buildbot\build.bat -c Debug -p Win32 + +echo. +echo # ====================================================================== +echo # platform=Debug^|Win32 +echo # ====================================================================== +echo. + +echo # ==================== refleak tests ======================= +echo. +call python.bat -m test -uall -R 3:3 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +echo. +echo # ====================================================================== +echo # Building Python (Release^|Win32) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p Win32 + +echo. +echo # ====================================================================== +echo # platform=Release^|Win32 +echo # ====================================================================== +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. diff --git a/python/Modules/_elementtree.c b/python/Modules/_elementtree.c new file mode 100755 index 0000000..a96e3f4 --- /dev/null +++ b/python/Modules/_elementtree.c @@ -0,0 +1,4520 @@ +/*-------------------------------------------------------------------- + * Licensed to PSF under a Contributor Agreement. + * See http://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" +#include "structmember.h" + +/* -------------------------------------------------------------------- */ +/* 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. + */ +#define ET_STATE(mod) ((elementtreestate *) PyModule_GetState(mod)) + +/* 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 = ET_STATE(m); + 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) +{ + elementtreestate *st = ET_STATE(m); + 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 { + + /* attributes (a dictionary object), or None 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; + + +#define Element_CheckExact(op) (Py_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; + } + + if (!attrib) + attrib = Py_None; + + Py_INCREF(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; + + Py_DECREF(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); + + if (attrib != Py_None && !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; + } + 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; + } + } + 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; +} + +LOCAL(void) +raise_type_error(PyObject *element) +{ + PyErr_Format(PyExc_TypeError, + "expected an Element, not \"%.200s\"", + Py_TYPE(element)->tp_name); +} + +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 (res == Py_None) { + /* create missing dictionary */ + res = PyDict_New(); + if (!res) + return NULL; + Py_DECREF(Py_None); + self->extra->attrib = res; + } + + 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 */ + Py_INCREF(Py_None); + attrib = Py_None; + } + + elem = create_new_element(tag, attrib); + Py_DECREF(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 : Py_None); + 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) { + attrib = deepcopy(self->extra->attrib, memo); + if (!attrib) { + Py_DECREF(tag); + return NULL; + } + } else { + Py_INCREF(Py_None); + attrib = Py_None; + } + + element = (ElementObject*) create_new_element(tag, attrib); + + Py_DECREF(tag); + Py_DECREF(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 != Py_None) { + 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 == Py_None); + self->extra->attrib = oldextra->attrib; + oldextra->attrib = Py_None; + } + + /* 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. */ + if (attrib) { + Py_INCREF(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); + 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)) { + char *p = PyBytes_AS_STRING(tag); + const Py_ssize_t len = PyBytes_GET_SIZE(tag); + if (len >= 3 && p[0] == '{' && ( + p[1] == '}' || (p[1] == '*' && p[2] == '}'))) { + /* 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]*/ +{ + PyObject* value; + + if (!self->extra || self->extra->attrib == Py_None) + value = default_value; + else { + value = PyDict_GetItemWithError(self->extra->attrib, key); + if (!value) { + if (PyErr_Occurred()) { + return NULL; + } + value = default_value; + } + } + + Py_INCREF(value); + return value; +} + +/*[clinic input] +_elementtree.Element.getchildren + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_getchildren_impl(ElementObject *self) +/*[clinic end generated code: output=e50ffe118637b14f input=0f754dfded150d5f]*/ +{ + Py_ssize_t i; + PyObject* list; + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "This method will be removed in future versions. " + "Use 'list(elem)' or iteration over elem instead.", + 1) < 0) { + return NULL; + } + + if (!self->extra) + return PyList_New(0); + + list = PyList_New(self->extra->length); + if (!list) + return NULL; + + for (i = 0; i < self->extra->length; i++) { + PyObject* item = self->extra->children[i]; + Py_INCREF(item); + PyList_SET_ITEM(list, i, item); + } + + return list; +} + + +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.getiterator + + tag: object = None + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_getiterator_impl(ElementObject *self, PyObject *tag) +/*[clinic end generated code: output=cb69ff4a3742dfa1 input=500da1a03f7b9e28]*/ +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "This method will be removed in future versions. " + "Use 'tree.iter()' or 'list(tree.iter())' instead.", + 1) < 0) { + return NULL; + } + return _elementtree_Element_iter_impl(self, tag); +} + + +/*[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 == Py_None) + 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 == Py_None) + 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 + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, + PyObject *attrib) +/*[clinic end generated code: output=4109832d5bb789ef input=9480d1d2e3e68235]*/ +{ + 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 + ); + 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)) { + raise_type_error(element); + Py_DECREF(seq); + return -1; + } + } + + 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 (!self->extra) { + if (create_extra(self, NULL) < 0) + return -1; + } + Py_INCREF(value); + Py_SETREF(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; + } + + 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 */ + 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)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; + + PyObject_GC_Track(it); + + 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; + + 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 *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; + PyObject *comment_event_obj; + PyObject *pi_event_obj; + + char insert_comments; + char insert_pis; +} TreeBuilderObject; + +#define TreeBuilder_CheckExact(op) (Py_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; + 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->comment_event_obj = t->pi_event_obj = NULL; + t->insert_comments = t->insert_pis = 0; + } + 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, + 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); + } else { + Py_CLEAR(self->element_factory); + } + + if (comment_factory == Py_None) { + elementtreestate *st = ET_STATE_GLOBAL; + comment_factory = st->comment_factory; + } + if (comment_factory) { + Py_INCREF(comment_factory); + Py_XSETREF(self->comment_factory, comment_factory); + self->insert_comments = insert_comments; + } else { + Py_CLEAR(self->comment_factory); + self->insert_comments = 0; + } + + if (pi_factory == Py_None) { + elementtreestate *st = ET_STATE_GLOBAL; + pi_factory = st->pi_factory; + } + if (pi_factory) { + Py_INCREF(pi_factory); + Py_XSETREF(self->pi_factory, pi_factory); + self->insert_pis = insert_pis; + } else { + Py_CLEAR(self->pi_factory); + self->insert_pis = 0; + } + + 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->last_for_tail); + 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_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->last_for_tail); + 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 */ + +/*[clinic input] +_elementtree._set_factories + + comment_factory: object + pi_factory: object + / + +Change the factories used to create comments and processing instructions. + +For internal use only. +[clinic start generated code]*/ + +static PyObject * +_elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, + PyObject *pi_factory) +/*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/ +{ + elementtreestate *st = ET_STATE_GLOBAL; + PyObject *old; + + if (!PyCallable_Check(comment_factory) && comment_factory != Py_None) { + PyErr_Format(PyExc_TypeError, "Comment factory must be callable, not %.100s", + Py_TYPE(comment_factory)->tp_name); + return NULL; + } + if (!PyCallable_Check(pi_factory) && pi_factory != Py_None) { + PyErr_Format(PyExc_TypeError, "PI factory must be callable, not %.100s", + Py_TYPE(pi_factory)->tp_name); + return NULL; + } + + old = PyTuple_Pack(2, + st->comment_factory ? st->comment_factory : Py_None, + st->pi_factory ? st->pi_factory : Py_None); + + if (comment_factory == Py_None) { + Py_CLEAR(st->comment_factory); + } else { + Py_INCREF(comment_factory); + Py_XSETREF(st->comment_factory, comment_factory); + } + if (pi_factory == Py_None) { + Py_CLEAR(st->pi_factory); + } else { + Py_INCREF(pi_factory); + Py_XSETREF(st->pi_factory, pi_factory); + } + + return old; +} + +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)) { + PyObject *dest_obj = JOIN_OBJ(*dest); + if (dest_obj == Py_None) { + *dest = JOIN_SET(*data, PyList_CheckExact(*data)); + *data = NULL; + Py_DECREF(dest_obj); + return 0; + } + else if (JOIN_GET(*dest)) { + if (PyList_SetSlice(dest_obj, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, *data) < 0) { + return -1; + } + Py_CLEAR(*data); + return 0; + } + } + + /* Fallback for the non-Element / non-trivial cases. */ + { + int r; + PyObject* joined; + PyObject* previous = _PyObject_GetAttrId(element, name); + if (!previous) + return -1; + joined = list_join(*data); + if (!joined) { + Py_DECREF(previous); + return -1; + } + if (previous != Py_None) { + PyObject *tmp = PyNumber_Add(previous, joined); + Py_DECREF(joined); + Py_DECREF(previous); + if (!tmp) + return -1; + joined = tmp; + } else { + 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_CallMethodIdObjArgs(element, &PyId_append, child, NULL); + 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_FastCall(self->events_append, &event, 1); + 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 == Py_None) { + 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; +} + +LOCAL(PyObject*) +treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) +{ + PyObject* comment; + PyObject* this; + + if (treebuilder_flush_data(self) < 0) { + return NULL; + } + + if (self->comment_factory) { + comment = _PyObject_FastCall(self->comment_factory, &text, 1); + if (!comment) + return NULL; + + this = self->this; + if (self->insert_comments && this != Py_None) { + if (treebuilder_add_subelement(this, comment) < 0) + goto error; + Py_INCREF(comment); + Py_XSETREF(self->last_for_tail, comment); + } + } else { + Py_INCREF(text); + comment = text; + } + + if (self->events_append && self->comment_event_obj) { + if (treebuilder_append_event(self, self->comment_event_obj, comment) < 0) + goto error; + } + + return comment; + + error: + Py_DECREF(comment); + return NULL; +} + +LOCAL(PyObject*) +treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text) +{ + PyObject* pi; + PyObject* this; + PyObject* stack[2] = {target, text}; + + if (treebuilder_flush_data(self) < 0) { + return NULL; + } + + if (self->pi_factory) { + pi = _PyObject_FastCall(self->pi_factory, stack, 2); + if (!pi) { + return NULL; + } + + this = self->this; + if (self->insert_pis && this != Py_None) { + if (treebuilder_add_subelement(this, pi) < 0) + goto error; + Py_INCREF(pi); + Py_XSETREF(self->last_for_tail, pi); + } + } else { + pi = PyTuple_Pack(2, target, text); + if (!pi) { + return NULL; + } + } + + if (self->events_append && self->pi_event_obj) { + if (treebuilder_append_event(self, self->pi_event_obj, pi) < 0) + goto error; + } + + return pi; + + error: + Py_DECREF(pi); + return NULL; +} + +LOCAL(PyObject*) +treebuilder_handle_start_ns(TreeBuilderObject* self, PyObject* prefix, PyObject* uri) +{ + PyObject* parcel; + + if (self->events_append && self->start_ns_event_obj) { + parcel = PyTuple_Pack(2, prefix, uri); + if (!parcel) { + return NULL; + } + + if (treebuilder_append_event(self, self->start_ns_event_obj, parcel) < 0) { + Py_DECREF(parcel); + return NULL; + } + Py_DECREF(parcel); + } + + Py_RETURN_NONE; +} + +LOCAL(PyObject*) +treebuilder_handle_end_ns(TreeBuilderObject* self, PyObject* prefix) +{ + if (self->events_append && self->end_ns_event_obj) { + if (treebuilder_append_event(self, self->end_ns_event_obj, prefix) < 0) { + return NULL; + } + } + + 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); +} + +/*[clinic input] +_elementtree.TreeBuilder.comment + + text: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_comment(TreeBuilderObject *self, PyObject *text) +/*[clinic end generated code: output=22835be41deeaa27 input=47e7ebc48ed01dfa]*/ +{ + return treebuilder_handle_comment(self, text); +} + +/*[clinic input] +_elementtree.TreeBuilder.pi + + target: object + text: object = None + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target, + PyObject *text) +/*[clinic end generated code: output=21eb95ec9d04d1d9 input=349342bd79c35570]*/ +{ + 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 + attrs: object = None + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, + PyObject *attrs) +/*[clinic end generated code: output=e7e9dc2861349411 input=95fc1758dd042c65]*/ +{ + 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; + + value = PyDict_GetItemWithError(self->names, key); + + 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; + + error = _PyObject_FastCall(st->parseerror_obj, &errmsg, 1); + 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) + res = _PyObject_FastCall(self->handle_data, &value, 1); + 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 { + Py_INCREF(Py_None); + attrib = Py_None; + } + + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut */ + res = treebuilder_handle_start((TreeBuilderObject*) self->target, + tag, attrib); + } + else if (self->handle_start) { + if (attrib == Py_None) { + Py_DECREF(attrib); + 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_DECREF(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) + res = _PyObject_FastCall(self->handle_data, &data, 1); + 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_FastCall(self->handle_end, &tag, 1); + 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 (!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) + return; + uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict"); + if (!uri) { + Py_DECREF(prefix); + return; + } + + res = treebuilder_handle_start_ns(target, prefix, uri); + Py_DECREF(uri); + Py_DECREF(prefix); + } + } else if (self->handle_start_ns) { + prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); + if (!prefix) + return; + uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict"); + if (!uri) { + Py_DECREF(prefix); + return; + } + + stack[0] = prefix; + stack[1] = uri; + res = _PyObject_FastCall(self->handle_start_ns, stack, 2); + Py_DECREF(uri); + Py_DECREF(prefix); + } + + Py_XDECREF(res); +} + +static void +expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) +{ + PyObject *res = NULL; + PyObject* prefix; + + 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; + + if (target->events_append && target->end_ns_event_obj) { + res = treebuilder_handle_end_ns(target, Py_None); + } + } else if (self->handle_end_ns) { + prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); + if (!prefix) + return; + + res = _PyObject_FastCall(self->handle_end_ns, &prefix, 1); + Py_DECREF(prefix); + } + + Py_XDECREF(res); +} + +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"); + if (!comment) + return; /* parser will look for errors */ + + res = treebuilder_handle_comment(target, comment); + Py_XDECREF(res); + Py_DECREF(comment); + } else if (self->handle_comment) { + comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); + if (!comment) + return; + + res = _PyObject_FastCall(self->handle_comment, &comment, 1); + 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) +{ + _Py_IDENTIFIER(doctype); + 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); + 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) +{ + PyObject* pi_target; + PyObject* data; + PyObject* res; + PyObject* stack[2]; + + if (PyErr_Occurred()) + return; + + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut */ + TreeBuilderObject *target = (TreeBuilderObject*) self->target; + + if ((target->events_append && target->pi_event_obj) || target->insert_pis) { + pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); + if (!pi_target) + goto error; + data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); + if (!data) + goto error; + res = treebuilder_handle_pi(target, pi_target, 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) + goto error; + data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); + if (!data) + goto error; + + stack[0] = pi_target; + 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; +} + +/*[clinic input] +_elementtree.XMLParser.__init__ + + * + target: object = NULL + encoding: str(accept={str, NoneType}) = None + +[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->handle_start_ns = PyObject_GetAttrString(target, "start_ns"); + if (ignore_attribute_error(self->handle_start_ns)) { + return -1; + } + self->handle_end_ns = PyObject_GetAttrString(target, "end_ns"); + 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); + 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); + 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_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_LOCAL_INLINE(int) +_check_xmlparser(XMLParserObject* self) +{ + if (self->target == NULL) { + PyErr_SetString(PyExc_ValueError, + "XMLParser.__init__() wasn't called"); + return 0; + } + 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; + + 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); + return _PyObject_CallNoArg(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 */ + + 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 (!_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; + + 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); + 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 + ); + } else if (strcmp(event_name, "comment") == 0) { + Py_XSETREF(target->comment_event_obj, event_name_obj); + EXPAT(SetCommentHandler)( + self->parser, + (XML_CommentHandler) expat_comment_handler + ); + } else if (strcmp(event_name, "pi") == 0) { + Py_XSETREF(target->pi_event_obj, event_name_obj); + EXPAT(SetProcessingInstructionHandler)( + 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; +} + +static PyMemberDef xmlparser_members[] = { + {"entity", T_OBJECT, offsetof(XMLParserObject, entity), READONLY, NULL}, + {"target", T_OBJECT, offsetof(XMLParserObject, target), READONLY, NULL}, + {NULL} +}; + +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_GETITERATOR_METHODDEF + _ELEMENTTREE_ELEMENT_GETCHILDREN_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_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 + _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 */ + 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)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_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)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[] = { + {"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; + st = ET_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); + PyModule_AddObject(m, "ParseError", st->parseerror_obj); + + Py_INCREF((PyObject *)&Element_Type); + PyModule_AddObject(m, "Element", (PyObject *)&Element_Type); + + Py_INCREF((PyObject *)&TreeBuilder_Type); + PyModule_AddObject(m, "TreeBuilder", (PyObject *)&TreeBuilder_Type); + + Py_INCREF((PyObject *)&XMLParser_Type); + PyModule_AddObject(m, "XMLParser", (PyObject *)&XMLParser_Type); + + return m; +} diff --git a/python/Modules/_functoolsmodule.c b/python/Modules/_functoolsmodule.c new file mode 100755 index 0000000..148d051 --- /dev/null +++ b/python/Modules/_functoolsmodule.c @@ -0,0 +1,1430 @@ +#include "Python.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" +#include "structmember.h" +#include "pycore_object.h" // _PyObject_GC_TRACK + +/* _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; + PyObject *weakreflist; /* List of weak references */ + int use_fastcall; +} partialobject; + +static PyTypeObject partial_type; + +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_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; + } + + pto->use_fastcall = (_PyVectorcall_Function(func) != NULL); + + 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); +} + +static PyObject * +partial_fastcall(partialobject *pto, PyObject **args, Py_ssize_t nargs, + PyObject *kwargs) +{ + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject *ret; + PyObject **stack, **stack_buf = NULL; + Py_ssize_t nargs2, pto_nargs; + + pto_nargs = PyTuple_GET_SIZE(pto->args); + nargs2 = pto_nargs + nargs; + + if (pto_nargs == 0) { + stack = args; + } + else if (nargs == 0) { + stack = _PyTuple_ITEMS(pto->args); + } + else { + if (nargs2 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { + stack = small_stack; + } + else { + stack_buf = PyMem_Malloc(nargs2 * sizeof(PyObject *)); + if (stack_buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + stack = stack_buf; + } + + /* use borrowed references */ + memcpy(stack, + _PyTuple_ITEMS(pto->args), + pto_nargs * sizeof(PyObject*)); + memcpy(&stack[pto_nargs], + args, + nargs * sizeof(PyObject*)); + } + + ret = _PyObject_FastCallDict(pto->fn, stack, nargs2, kwargs); + PyMem_Free(stack_buf); + return ret; +} + +static PyObject * +partial_call_impl(partialobject *pto, PyObject *args, PyObject *kwargs) +{ + PyObject *ret, *args2; + + /* Note: tupleconcat() is optimized for empty tuples */ + args2 = PySequence_Concat(pto->args, args); + if (args2 == NULL) { + return NULL; + } + assert(PyTuple_Check(args2)); + + ret = PyObject_Call(pto->fn, args2, kwargs); + Py_DECREF(args2); + return ret; +} + +static PyObject * +partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) +{ + PyObject *kwargs2, *res; + + assert (PyCallable_Check(pto->fn)); + assert (PyTuple_Check(pto->args)); + assert (PyDict_Check(pto->kw)); + + 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 (pto->use_fastcall) { + res = partial_fastcall(pto, + _PyTuple_ITEMS(args), + PyTuple_GET_SIZE(args), + kwargs2); + } + else { + res = partial_call_impl(pto, args, kwargs2); + } + 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); + pto->use_fastcall = (_PyVectorcall_Function(fn) != NULL); + Py_SETREF(pto->fn, fn); + Py_SETREF(pto->args, fnargs); + Py_SETREF(pto->kw, kw); + Py_XSETREF(pto->dict, dict); + Py_RETURN_NONE; +} + +static PyMethodDef partial_methods[] = { + {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS}, + {"__setstate__", (PyCFunction)partial_setstate, METH_O}, + {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 */ + 0, /* tp_vectorcall_offset */ + 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 | + Py_TPFLAGS_BASETYPE, /* 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 */ + 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 */ + (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_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; + + if (args->ob_refcnt > 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 { + /* Update the args tuple in-place */ + assert(args->ob_refcnt == 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; + } + // 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 */ + 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 */ +}; + + +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; +} 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 */ + 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; + 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); + + 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_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 */ + 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 */ + 0, /* 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 ********************************************************/ + +PyDoc_STRVAR(module_doc, +"Tools that operate on functions."); + +static PyMethodDef module_methods[] = { + {"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 +module_free(void *m) +{ + Py_CLEAR(kwd_mark); +} + +static struct PyModuleDef _functoolsmodule = { + PyModuleDef_HEAD_INIT, + "_functools", + module_doc, + -1, + module_methods, + NULL, + NULL, + NULL, + module_free, +}; + +PyMODINIT_FUNC +PyInit__functools(void) +{ + int i; + PyObject *m; + const char *name; + PyTypeObject *typelist[] = { + &partial_type, + &lru_cache_type, + NULL + }; + + m = PyModule_Create(&_functoolsmodule); + if (m == NULL) + return NULL; + + kwd_mark = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); + if (!kwd_mark) { + Py_DECREF(m); + return NULL; + } + + for (i=0 ; typelist[i] != NULL ; i++) { + if (PyType_Ready(typelist[i]) < 0) { + Py_DECREF(m); + return NULL; + } + name = _PyType_Name(typelist[i]); + Py_INCREF(typelist[i]); + PyModule_AddObject(m, name, (PyObject *)typelist[i]); + } + return m; +} diff --git a/python/Modules/_gdbmmodule.c b/python/Modules/_gdbmmodule.c new file mode 100755 index 0000000..34e205f --- /dev/null +++ b/python/Modules/_gdbmmodule.c @@ -0,0 +1,721 @@ + +// /* DBM module using dictionary interface */ +// /* Author: Anthony Baxter, after dbmmodule.c */ +// /* Doc strings: Mitch Chapman */ + +// #define PY_SSIZE_T_CLEAN +// #include "Python.h" + +// #include +// #include +// #include +// #include "gdbm.h" + +// #if defined(WIN32) && !defined(__CYGWIN__) +// #include "gdbmerrno.h" +// extern const char * gdbm_strerror(gdbm_error); +// #endif + +// /*[clinic input] +// module _gdbm +// class _gdbm.gdbm "dbmobject *" "&Dbmtype" +// [clinic start generated code]*/ +// /*[clinic end generated code: output=da39a3ee5e6b4b0d input=113927c6170729b2]*/ + +// PyDoc_STRVAR(gdbmmodule__doc__, +// "This module provides an interface to the GNU DBM (GDBM) library.\n\ +// \n\ +// This module is quite similar to the dbm module, but uses GDBM instead to\n\ +// provide some additional functionality. Please note that the file formats\n\ +// created by GDBM and dbm are incompatible.\n\ +// \n\ +// GDBM objects behave like mappings (dictionaries), except that keys and\n\ +// values are always immutable bytes-like objects or strings. Printing\n\ +// a GDBM object doesn't print the keys and values, and the items() and\n\ +// values() methods are not supported."); + +// typedef struct { +// PyObject_HEAD +// int di_size; /* -1 means recompute */ +// GDBM_FILE di_dbm; +// } dbmobject; + +// static PyTypeObject Dbmtype; + +// #include "clinic/_gdbmmodule.c.h" + +// #define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype) +// #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \ +// { PyErr_SetString(DbmError, "GDBM object has already been closed"); \ +// return NULL; } + + + +// static PyObject *DbmError; + +// PyDoc_STRVAR(gdbm_object__doc__, +// "This object represents a GDBM database.\n\ +// GDBM objects behave like mappings (dictionaries), except that keys and\n\ +// values are always immutable bytes-like objects or strings. Printing\n\ +// a GDBM object doesn't print the keys and values, and the items() and\n\ +// values() methods are not supported.\n\ +// \n\ +// GDBM objects also support additional operations such as firstkey,\n\ +// nextkey, reorganize, and sync."); + +// static PyObject * +// newdbmobject(const char *file, int flags, int mode) +// { +// dbmobject *dp; + +// dp = PyObject_New(dbmobject, &Dbmtype); +// if (dp == NULL) +// return NULL; +// dp->di_size = -1; +// errno = 0; +// if ((dp->di_dbm = gdbm_open((char *)file, 0, flags, mode, NULL)) == 0) { +// if (errno != 0) +// PyErr_SetFromErrnoWithFilename(DbmError, file); +// else +// PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); +// Py_DECREF(dp); +// return NULL; +// } +// return (PyObject *)dp; +// } + +// /* Methods */ + +// static void +// dbm_dealloc(dbmobject *dp) +// { +// if (dp->di_dbm) +// gdbm_close(dp->di_dbm); +// PyObject_Del(dp); +// } + +// static Py_ssize_t +// dbm_length(dbmobject *dp) +// { +// if (dp->di_dbm == NULL) { +// PyErr_SetString(DbmError, "GDBM object has already been closed"); +// return -1; +// } +// if (dp->di_size < 0) { +// datum key,okey; +// int size; +// okey.dsize=0; +// okey.dptr=NULL; + +// size = 0; +// for (key=gdbm_firstkey(dp->di_dbm); key.dptr; +// key = gdbm_nextkey(dp->di_dbm,okey)) { +// size++; +// if(okey.dsize) free(okey.dptr); +// okey=key; +// } +// dp->di_size = size; +// } +// return dp->di_size; +// } + +// // Wrapper function for PyArg_Parse(o, "s#", &d.dptr, &d.size). +// // This function is needed to support PY_SSIZE_T_CLEAN. +// // Return 1 on success, same to PyArg_Parse(). +// static int +// parse_datum(PyObject *o, datum *d, const char *failmsg) +// { +// Py_ssize_t size; +// if (!PyArg_Parse(o, "s#", &d->dptr, &size)) { +// if (failmsg != NULL) { +// PyErr_SetString(PyExc_TypeError, failmsg); +// } +// return 0; +// } +// if (INT_MAX < size) { +// PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); +// return 0; +// } +// d->dsize = size; +// return 1; +// } + +// static PyObject * +// dbm_subscript(dbmobject *dp, PyObject *key) +// { +// PyObject *v; +// datum drec, krec; + +// if (!parse_datum(key, &krec, NULL)) { +// return NULL; +// } +// if (dp->di_dbm == NULL) { +// PyErr_SetString(DbmError, +// "GDBM object has already been closed"); +// return NULL; +// } +// drec = gdbm_fetch(dp->di_dbm, krec); +// if (drec.dptr == 0) { +// PyErr_SetObject(PyExc_KeyError, key); +// return NULL; +// } +// v = PyBytes_FromStringAndSize(drec.dptr, drec.dsize); +// free(drec.dptr); +// return v; +// } + +// /*[clinic input] +// _gdbm.gdbm.get + +// key: object +// default: object = None +// / + +// Get the value for key, or default if not present. +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_get_impl(dbmobject *self, PyObject *key, PyObject *default_value) +// /*[clinic end generated code: output=19b7c585ad4f554a input=a9c20423f34c17b6]*/ +// { +// PyObject *res; + +// res = dbm_subscript(self, key); +// if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { +// PyErr_Clear(); +// Py_INCREF(default_value); +// return default_value; +// } +// return res; +// } + +// static int +// dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w) +// { +// datum krec, drec; +// const char *failmsg = "gdbm mappings have bytes or string indices only"; + +// if (!parse_datum(v, &krec, failmsg)) { +// return -1; +// } +// if (dp->di_dbm == NULL) { +// PyErr_SetString(DbmError, +// "GDBM object has already been closed"); +// return -1; +// } +// dp->di_size = -1; +// if (w == NULL) { +// if (gdbm_delete(dp->di_dbm, krec) < 0) { +// if (gdbm_errno == GDBM_ITEM_NOT_FOUND) { +// PyErr_SetObject(PyExc_KeyError, v); +// } +// else { +// PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); +// } +// return -1; +// } +// } +// else { +// if (!parse_datum(w, &drec, failmsg)) { +// return -1; +// } +// errno = 0; +// if (gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0) { +// if (errno != 0) +// PyErr_SetFromErrno(DbmError); +// else +// PyErr_SetString(DbmError, +// gdbm_strerror(gdbm_errno)); +// return -1; +// } +// } +// return 0; +// } + +// /*[clinic input] +// _gdbm.gdbm.setdefault + +// key: object +// default: object = None +// / + +// Get value for key, or set it to default and return default if not present. +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_setdefault_impl(dbmobject *self, PyObject *key, +// PyObject *default_value) +// /*[clinic end generated code: output=88760ee520329012 input=0db46b69e9680171]*/ +// { +// PyObject *res; + +// res = dbm_subscript(self, key); +// if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { +// PyErr_Clear(); +// if (dbm_ass_sub(self, key, default_value) < 0) +// return NULL; +// return dbm_subscript(self, key); +// } +// return res; +// } + +// static PyMappingMethods dbm_as_mapping = { +// (lenfunc)dbm_length, /*mp_length*/ +// (binaryfunc)dbm_subscript, /*mp_subscript*/ +// (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/ +// }; + +// /*[clinic input] +// _gdbm.gdbm.close + +// Close the database. +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_close_impl(dbmobject *self) +// /*[clinic end generated code: output=23512a594598b563 input=0a203447379b45fd]*/ +// { +// if (self->di_dbm) +// gdbm_close(self->di_dbm); +// self->di_dbm = NULL; +// Py_RETURN_NONE; +// } + +// /* XXX Should return a set or a set view */ +// /*[clinic input] +// _gdbm.gdbm.keys + +// Get a list of all keys in the database. +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_keys_impl(dbmobject *self) +// /*[clinic end generated code: output=cb4b1776c3645dcc input=1832ee0a3132cfaf]*/ +// { +// PyObject *v, *item; +// datum key, nextkey; +// int err; + +// if (self == NULL || !is_dbmobject(self)) { +// PyErr_BadInternalCall(); +// return NULL; +// } +// check_dbmobject_open(self); + +// v = PyList_New(0); +// if (v == NULL) +// return NULL; + +// key = gdbm_firstkey(self->di_dbm); +// while (key.dptr) { +// item = PyBytes_FromStringAndSize(key.dptr, key.dsize); +// if (item == NULL) { +// free(key.dptr); +// Py_DECREF(v); +// return NULL; +// } +// err = PyList_Append(v, item); +// Py_DECREF(item); +// if (err != 0) { +// free(key.dptr); +// Py_DECREF(v); +// return NULL; +// } +// nextkey = gdbm_nextkey(self->di_dbm, key); +// free(key.dptr); +// key = nextkey; +// } +// return v; +// } + +// static int +// dbm_contains(PyObject *self, PyObject *arg) +// { +// dbmobject *dp = (dbmobject *)self; +// datum key; +// Py_ssize_t size; + +// if ((dp)->di_dbm == NULL) { +// PyErr_SetString(DbmError, +// "GDBM object has already been closed"); +// return -1; +// } +// if (PyUnicode_Check(arg)) { +// key.dptr = (char *)PyUnicode_AsUTF8AndSize(arg, &size); +// key.dsize = size; +// if (key.dptr == NULL) +// return -1; +// } +// else if (!PyBytes_Check(arg)) { +// PyErr_Format(PyExc_TypeError, +// "gdbm key must be bytes or string, not %.100s", +// arg->ob_type->tp_name); +// return -1; +// } +// else { +// key.dptr = PyBytes_AS_STRING(arg); +// key.dsize = PyBytes_GET_SIZE(arg); +// } +// return gdbm_exists(dp->di_dbm, key); +// } + +// static PySequenceMethods dbm_as_sequence = { +// 0, /* sq_length */ +// 0, /* sq_concat */ +// 0, /* sq_repeat */ +// 0, /* sq_item */ +// 0, /* sq_slice */ +// 0, /* sq_ass_item */ +// 0, /* sq_ass_slice */ +// dbm_contains, /* sq_contains */ +// 0, /* sq_inplace_concat */ +// 0, /* sq_inplace_repeat */ +// }; + +// /*[clinic input] +// _gdbm.gdbm.firstkey + +// Return the starting key for the traversal. + +// It's possible to loop over every key in the database using this method +// and the nextkey() method. The traversal is ordered by GDBM's internal +// hash values, and won't be sorted by the key values. +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_firstkey_impl(dbmobject *self) +// /*[clinic end generated code: output=9ff85628d84b65d2 input=0dbd6a335d69bba0]*/ +// { +// PyObject *v; +// datum key; + +// check_dbmobject_open(self); +// key = gdbm_firstkey(self->di_dbm); +// if (key.dptr) { +// v = PyBytes_FromStringAndSize(key.dptr, key.dsize); +// free(key.dptr); +// return v; +// } +// else { +// Py_RETURN_NONE; +// } +// } + +// /*[clinic input] +// _gdbm.gdbm.nextkey + +// key: str(accept={str, robuffer}, zeroes=True) +// / + +// Returns the key that follows key in the traversal. + +// The following code prints every key in the database db, without having +// to create a list in memory that contains them all: + +// k = db.firstkey() +// while k != None: +// print(k) +// k = db.nextkey(k) +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_nextkey_impl(dbmobject *self, const char *key, +// Py_ssize_clean_t key_length) +// /*[clinic end generated code: output=192ab892de6eb2f6 input=1f1606943614e36f]*/ +// { +// PyObject *v; +// datum dbm_key, nextkey; + +// dbm_key.dptr = (char *)key; +// dbm_key.dsize = key_length; +// check_dbmobject_open(self); +// nextkey = gdbm_nextkey(self->di_dbm, dbm_key); +// if (nextkey.dptr) { +// v = PyBytes_FromStringAndSize(nextkey.dptr, nextkey.dsize); +// free(nextkey.dptr); +// return v; +// } +// else { +// Py_RETURN_NONE; +// } +// } + +// /*[clinic input] +// _gdbm.gdbm.reorganize + +// Reorganize the database. + +// If you have carried out a lot of deletions and would like to shrink +// the space used by the GDBM file, this routine will reorganize the +// database. GDBM will not shorten the length of a database file except +// by using this reorganization; otherwise, deleted file space will be +// kept and reused as new (key,value) pairs are added. +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_reorganize_impl(dbmobject *self) +// /*[clinic end generated code: output=38d9624df92e961d input=f6bea85bcfd40dd2]*/ +// { +// check_dbmobject_open(self); +// errno = 0; +// if (gdbm_reorganize(self->di_dbm) < 0) { +// if (errno != 0) +// PyErr_SetFromErrno(DbmError); +// else +// PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); +// return NULL; +// } +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _gdbm.gdbm.sync + +// Flush the database to the disk file. + +// When the database has been opened in fast mode, this method forces +// any unwritten data to be written to the disk. +// [clinic start generated code]*/ + +// static PyObject * +// _gdbm_gdbm_sync_impl(dbmobject *self) +// /*[clinic end generated code: output=488b15f47028f125 input=2a47d2c9e153ab8a]*/ +// { +// check_dbmobject_open(self); +// gdbm_sync(self->di_dbm); +// Py_RETURN_NONE; +// } + +// static PyObject * +// dbm__enter__(PyObject *self, PyObject *args) +// { +// Py_INCREF(self); +// return self; +// } + +// static PyObject * +// dbm__exit__(PyObject *self, PyObject *args) +// { +// _Py_IDENTIFIER(close); +// return _PyObject_CallMethodId(self, &PyId_close, NULL); +// } + +// static PyMethodDef dbm_methods[] = { +// _GDBM_GDBM_CLOSE_METHODDEF +// _GDBM_GDBM_KEYS_METHODDEF +// _GDBM_GDBM_FIRSTKEY_METHODDEF +// _GDBM_GDBM_NEXTKEY_METHODDEF +// _GDBM_GDBM_REORGANIZE_METHODDEF +// _GDBM_GDBM_SYNC_METHODDEF +// _GDBM_GDBM_GET_METHODDEF +// _GDBM_GDBM_SETDEFAULT_METHODDEF +// {"__enter__", dbm__enter__, METH_NOARGS, NULL}, +// {"__exit__", dbm__exit__, METH_VARARGS, NULL}, +// {NULL, NULL} /* sentinel */ +// }; + +// static PyTypeObject Dbmtype = { +// PyVarObject_HEAD_INIT(0, 0) +// "_gdbm.gdbm", +// sizeof(dbmobject), +// 0, +// (destructor)dbm_dealloc, /*tp_dealloc*/ +// 0, /*tp_vectorcall_offset*/ +// 0, /*tp_getattr*/ +// 0, /*tp_setattr*/ +// 0, /*tp_as_async*/ +// 0, /*tp_repr*/ +// 0, /*tp_as_number*/ +// &dbm_as_sequence, /*tp_as_sequence*/ +// &dbm_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_xxx4*/ +// gdbm_object__doc__, /*tp_doc*/ +// 0, /*tp_traverse*/ +// 0, /*tp_clear*/ +// 0, /*tp_richcompare*/ +// 0, /*tp_weaklistoffset*/ +// 0, /*tp_iter*/ +// 0, /*tp_iternext*/ +// dbm_methods, /*tp_methods*/ +// }; + +// /* ----------------------------------------------------------------- */ + +// /*[clinic input] +// _gdbm.open as dbmopen +// filename: unicode +// flags: str="r" +// mode: int(py_default="0o666") = 0o666 +// / + +// Open a dbm database and return a dbm object. + +// The filename argument is the name of the database file. + +// The optional flags argument can be 'r' (to open an existing database +// for reading only -- default), 'w' (to open an existing database for +// reading and writing), 'c' (which creates the database if it doesn't +// exist), or 'n' (which always creates a new empty database). + +// Some versions of gdbm support additional flags which must be +// appended to one of the flags described above. The module constant +// 'open_flags' is a string of valid additional flags. The 'f' flag +// opens the database in fast mode; altered data will not automatically +// be written to the disk after every change. This results in faster +// writes to the database, but may result in an inconsistent database +// if the program crashes while the database is still open. Use the +// sync() method to force any unwritten data to be written to the disk. +// The 's' flag causes all database operations to be synchronized to +// disk. The 'u' flag disables locking of the database file. + +// The optional mode argument is the Unix mode of the file, used only +// when the database has to be created. It defaults to octal 0o666. +// [clinic start generated code]*/ + +// static PyObject * +// dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, +// int mode) +// /*[clinic end generated code: output=9527750f5df90764 input=3be0b0875974b928]*/ +// { +// int iflags; + +// switch (flags[0]) { +// case 'r': +// iflags = GDBM_READER; +// break; +// case 'w': +// iflags = GDBM_WRITER; +// break; +// case 'c': +// iflags = GDBM_WRCREAT; +// break; +// case 'n': +// iflags = GDBM_NEWDB; +// break; +// default: +// PyErr_SetString(DbmError, +// "First flag must be one of 'r', 'w', 'c' or 'n'"); +// return NULL; +// } +// for (flags++; *flags != '\0'; flags++) { +// char buf[40]; +// switch (*flags) { +// #ifdef GDBM_FAST +// case 'f': +// iflags |= GDBM_FAST; +// break; +// #endif +// #ifdef GDBM_SYNC +// case 's': +// iflags |= GDBM_SYNC; +// break; +// #endif +// #ifdef GDBM_NOLOCK +// case 'u': +// iflags |= GDBM_NOLOCK; +// break; +// #endif +// default: +// PyOS_snprintf(buf, sizeof(buf), "Flag '%c' is not supported.", +// *flags); +// PyErr_SetString(DbmError, buf); +// return NULL; +// } +// } + +// PyObject *filenamebytes = PyUnicode_EncodeFSDefault(filename); +// if (filenamebytes == NULL) { +// return NULL; +// } +// const char *name = PyBytes_AS_STRING(filenamebytes); +// if (strlen(name) != (size_t)PyBytes_GET_SIZE(filenamebytes)) { +// Py_DECREF(filenamebytes); +// PyErr_SetString(PyExc_ValueError, "embedded null character"); +// return NULL; +// } +// PyObject *self = newdbmobject(name, iflags, mode); +// Py_DECREF(filenamebytes); +// return self; +// } + +// static const char dbmmodule_open_flags[] = "rwcn" +// #ifdef GDBM_FAST +// "f" +// #endif +// #ifdef GDBM_SYNC +// "s" +// #endif +// #ifdef GDBM_NOLOCK +// "u" +// #endif +// ; + +// static PyMethodDef dbmmodule_methods[] = { +// DBMOPEN_METHODDEF +// { 0, 0 }, +// }; + + +// static struct PyModuleDef _gdbmmodule = { +// PyModuleDef_HEAD_INIT, +// "_gdbm", +// gdbmmodule__doc__, +// -1, +// dbmmodule_methods, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit__gdbm(void) { +// PyObject *m; + +// if (PyType_Ready(&Dbmtype) < 0) +// return NULL; +// m = PyModule_Create(&_gdbmmodule); +// if (m == NULL) { +// return NULL; +// } + +// DbmError = PyErr_NewException("_gdbm.error", PyExc_OSError, NULL); +// if (DbmError == NULL) { +// goto error; +// } +// Py_INCREF(DbmError); +// if (PyModule_AddObject(m, "error", DbmError) < 0) { +// Py_DECREF(DbmError); +// goto error; +// } + +// if (PyModule_AddStringConstant(m, "open_flags", +// dbmmodule_open_flags) < 0) { +// goto error; +// } + +// #if defined(GDBM_VERSION_MAJOR) && defined(GDBM_VERSION_MINOR) && \ +// defined(GDBM_VERSION_PATCH) +// PyObject *obj = Py_BuildValue("iii", GDBM_VERSION_MAJOR, +// GDBM_VERSION_MINOR, GDBM_VERSION_PATCH); +// if (obj == NULL) { +// goto error; +// } +// if (PyModule_AddObject(m, "_GDBM_VERSION", obj) < 0) { +// Py_DECREF(obj); +// goto error; +// } +// #endif + +// return m; + +// error: +// Py_DECREF(m); +// return NULL; +// } diff --git a/python/Modules/_hashopenssl.c b/python/Modules/_hashopenssl.c new file mode 100755 index 0000000..8c71096 --- /dev/null +++ b/python/Modules/_hashopenssl.c @@ -0,0 +1,1152 @@ +// /* 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 +// #define OPENSSL_API_COMPAT 0x10101000L +// #endif +// #define OPENSSL_NO_DEPRECATED 1 + +// #define PY_SSIZE_T_CLEAN + +// #include "Python.h" +// #include "structmember.h" +// #include "hashlib.h" +// #include "pystrhex.h" + + +// /* EVP is the preferred interface to hashing in OpenSSL */ +// #include +// #include +// /* We use the object interface to discover what hashes OpenSSL supports. */ +// #include +// #include + +// #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 + +// #define MUNCH_SIZE INT_MAX + +// #ifdef NID_sha3_224 +// #define PY_OPENSSL_HAS_SHA3 1 +// #endif + +// #if defined(EVP_MD_FLAG_XOF) && defined(NID_shake128) +// #define PY_OPENSSL_HAS_SHAKE 1 +// #endif + +// #if defined(NID_blake2b512) && !defined(OPENSSL_NO_BLAKE2) +// #define PY_OPENSSL_HAS_BLAKE2 1 +// #endif + +// typedef struct { +// PyObject_HEAD +// EVP_MD_CTX *ctx; /* OpenSSL message digest context */ +// PyThread_type_lock lock; /* OpenSSL context lock */ +// } EVPobject; + + +// static PyTypeObject EVPtype; + +// #include "clinic/_hashopenssl.c.h" +// /*[clinic input] +// module _hashlib +// class _hashlib.HASH "EVPobject *" "&EVPtype" +// [clinic start generated code]*/ +// /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a881a5092eecad28]*/ + + +// /* LCOV_EXCL_START */ +// static PyObject * +// _setException(PyObject *exc) +// { +// unsigned long errcode; +// const char *lib, *func, *reason; + +// errcode = ERR_peek_last_error(); +// if (!errcode) { +// PyErr_SetString(exc, "unknown reasons"); +// return NULL; +// } +// 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 */ + +// static PyObject* +// py_digest_name(const EVP_MD *md) +// { +// int nid = EVP_MD_nid(md); +// const char *name = NULL; + +// /* Hard-coded names for well-known hashing algorithms. +// * OpenSSL uses slightly different names algorithms like SHA3. +// */ +// switch (nid) { +// case NID_md5: +// name = "md5"; +// break; +// case NID_sha1: +// name = "sha1"; +// break; +// case NID_sha224: +// name ="sha224"; +// break; +// case NID_sha256: +// name ="sha256"; +// break; +// case NID_sha384: +// name ="sha384"; +// break; +// case NID_sha512: +// name ="sha512"; +// break; +// #ifdef NID_sha512_224 +// case NID_sha512_224: +// name ="sha512_224"; +// break; +// case NID_sha512_256: +// name ="sha512_256"; +// break; +// #endif +// #ifdef PY_OPENSSL_HAS_SHA3 +// case NID_sha3_224: +// name ="sha3_224"; +// break; +// case NID_sha3_256: +// name ="sha3_256"; +// break; +// case NID_sha3_384: +// name ="sha3_384"; +// break; +// case NID_sha3_512: +// name ="sha3_512"; +// break; +// #endif +// #ifdef PY_OPENSSL_HAS_SHAKE +// case NID_shake128: +// name ="shake_128"; +// break; +// case NID_shake256: +// name ="shake_256"; +// break; +// #endif +// #ifdef PY_OPENSSL_HAS_BLAKE2 +// case NID_blake2s256: +// name ="blake2s"; +// break; +// case NID_blake2b512: +// name ="blake2b"; +// break; +// #endif +// default: +// /* Ignore aliased names and only use long, lowercase name. The aliases +// * pollute the list and OpenSSL appears to have its own definition of +// * alias as the resulting list still contains duplicate and alternate +// * names for several algorithms. +// */ +// name = OBJ_nid2ln(nid); +// if (name == NULL) +// name = OBJ_nid2sn(nid); +// break; +// } + +// return PyUnicode_FromString(name); +// } + +// static const EVP_MD* +// py_digest_by_name(const char *name) +// { +// const EVP_MD *digest = EVP_get_digestbyname(name); + +// /* OpenSSL uses dash instead of underscore in names of some algorithms +// * like SHA3 and SHAKE. Detect different spellings. */ +// if (digest == NULL) { +// if (0) {} +// #ifdef NID_sha512_224 +// else if (!strcmp(name, "sha512_224") || !strcmp(name, "SHA512_224")) { +// digest = EVP_sha512_224(); +// } +// else if (!strcmp(name, "sha512_256") || !strcmp(name, "SHA512_256")) { +// digest = EVP_sha512_256(); +// } +// #endif +// #ifdef PY_OPENSSL_HAS_SHA3 +// /* could be sha3_ or shake_, Python never defined upper case */ +// else if (!strcmp(name, "sha3_224")) { +// digest = EVP_sha3_224(); +// } +// else if (!strcmp(name, "sha3_256")) { +// digest = EVP_sha3_256(); +// } +// else if (!strcmp(name, "sha3_384")) { +// digest = EVP_sha3_384(); +// } +// else if (!strcmp(name, "sha3_512")) { +// digest = EVP_sha3_512(); +// } +// #endif +// #ifdef PY_OPENSSL_HAS_SHAKE +// else if (!strcmp(name, "shake_128")) { +// digest = EVP_shake128(); +// } +// else if (!strcmp(name, "shake_256")) { +// digest = EVP_shake256(); +// } +// #endif +// #ifdef PY_OPENSSL_HAS_BLAKE2 +// else if (!strcmp(name, "blake2s256")) { +// digest = EVP_blake2s256(); +// } +// else if (!strcmp(name, "blake2b512")) { +// digest = EVP_blake2b512(); +// } +// #endif +// } + +// return digest; +// } + +// static EVPobject * +// newEVPobject(void) +// { +// EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype); +// 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)) { +// _setException(PyExc_ValueError); +// return -1; +// } +// len -= process; +// cp += process; +// } +// return 0; +// } + +// /* Internal methods for a hash object */ + +// static void +// EVP_dealloc(EVPobject *self) +// { +// if (self->lock != NULL) +// PyThread_free_lock(self->lock); +// EVP_MD_CTX_free(self->ctx); +// PyObject_Del(self); +// } + +// 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 * +// EVP_copy_impl(EVPobject *self) +// /*[clinic end generated code: output=b370c21cdb8ca0b4 input=31455b6a3e638069]*/ +// { +// EVPobject *newobj; + +// if ( (newobj = newEVPobject())==NULL) +// return NULL; + +// if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { +// Py_DECREF(newobj); +// return _setException(PyExc_ValueError); +// } +// 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 * +// 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)) { +// return _setException(PyExc_ValueError); +// } +// digest_size = EVP_MD_CTX_size(temp_ctx); +// if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { +// _setException(PyExc_ValueError); +// 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 * +// 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)) { +// return _setException(PyExc_ValueError); +// } +// digest_size = EVP_MD_CTX_size(temp_ctx); +// if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { +// _setException(PyExc_ValueError); +// 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 * +// 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); +// result = EVP_hash(self, view.buf, view.len); +// PyThread_release_lock(self->lock); +// Py_END_ALLOW_THREADS +// } else { +// result = EVP_hash(self, view.buf, view.len); +// } + +// PyBuffer_Release(&view); + +// if (result == -1) +// return NULL; +// 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); +// } + +// 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}, +// {"name", +// (getter)EVP_get_name, NULL, +// NULL, +// PyDoc_STR("algorithm name.")}, +// {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 HASH object @ %p>", name_obj, self); +// Py_DECREF(name_obj); +// return repr; +// } + +// PyDoc_STRVAR(hashtype_doc, +// "HASH(name, string=b\'\')\n" +// "--\n" +// "\n" +// "A hash is an object used to calculate a checksum of a string of information.\n" +// "\n" +// "Methods:\n" +// "\n" +// "update() -- updates the current digest with an additional string\n" +// "digest() -- return the current digest value\n" +// "hexdigest() -- return the current digest as a string of hexadecimal digits\n" +// "copy() -- return a copy of the current hash object\n" +// "\n" +// "Attributes:\n" +// "\n" +// "name -- the hash algorithm being used by this object\n" +// "digest_size -- number of bytes in this hashes output"); + +// static PyTypeObject EVPtype = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "_hashlib.HASH", /*tp_name*/ +// sizeof(EVPobject), /*tp_basicsize*/ +// 0, /*tp_itemsize*/ +// /* methods */ +// (destructor)EVP_dealloc, /*tp_dealloc*/ +// 0, /*tp_vectorcall_offset*/ +// 0, /*tp_getattr*/ +// 0, /*tp_setattr*/ +// 0, /*tp_as_async*/ +// (reprfunc)EVP_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*/ +// hashtype_doc, /*tp_doc*/ +// 0, /*tp_traverse*/ +// 0, /*tp_clear*/ +// 0, /*tp_richcompare*/ +// 0, /*tp_weaklistoffset*/ +// 0, /*tp_iter*/ +// 0, /*tp_iternext*/ +// EVP_methods, /* tp_methods */ +// NULL, /* tp_members */ +// EVP_getseters, /* tp_getset */ +// 0, /* tp_base */ +// 0, /* tp_dict */ +// 0, /* tp_descr_get */ +// 0, /* tp_descr_set */ +// 0, /* tp_dictoffset */ +// }; + +// \ +// static PyObject * +// EVPnew(const EVP_MD *digest, +// const unsigned char *cp, Py_ssize_t len) +// { +// int result = 0; +// EVPobject *self; + +// if (!digest) { +// PyErr_SetString(PyExc_ValueError, "unsupported hash type"); +// return NULL; +// } + +// if ((self = newEVPobject()) == NULL) +// return NULL; + +// if (!EVP_DigestInit_ex(self->ctx, digest, NULL)) { +// _setException(PyExc_ValueError); +// Py_DECREF(self); +// return NULL; +// } + +// if (cp && len) { +// if (len >= HASHLIB_GIL_MINSIZE) { +// Py_BEGIN_ALLOW_THREADS +// result = EVP_hash(self, cp, len); +// Py_END_ALLOW_THREADS +// } else { +// result = EVP_hash(self, cp, len); +// } +// if (result == -1) { +// Py_DECREF(self); +// return NULL; +// } +// } + +// 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'' + +// Return a new hash object using the named algorithm. + +// An optional string argument may be provided and will be +// automatically hashed. + +// The MD5 and SHA1 algorithms are always supported. +// [clinic start generated code]*/ + +// static PyObject * +// EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj) +// /*[clinic end generated code: output=9e7cf664e04b0226 input=7eb79bf30058bd02]*/ +// { +// Py_buffer view = { 0 }; +// PyObject *ret_obj; +// char *name; +// const EVP_MD *digest; + +// if (!PyArg_Parse(name_obj, "s", &name)) { +// PyErr_SetString(PyExc_TypeError, "name must be a string"); +// return NULL; +// } + +// if (data_obj) +// GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); + +// digest = py_digest_by_name(name); + +// ret_obj = EVPnew(digest, (unsigned char*)view.buf, view.len); + +// if (data_obj) +// PyBuffer_Release(&view); +// return ret_obj; +// } + +// static PyObject* +// EVP_fast_new(PyObject *module, PyObject *data_obj, const EVP_MD *digest) +// { +// Py_buffer view = { 0 }; +// PyObject *ret_obj; + +// if (data_obj) +// GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); + +// ret_obj = EVPnew(digest, (unsigned char*)view.buf, view.len); + +// if (data_obj) +// PyBuffer_Release(&view); + +// return ret_obj; +// } + +// /*[clinic input] +// _hashlib.openssl_md5 + +// string as data_obj: object(py_default="b''") = NULL + +// Returns a md5 hash object; optionally initialized with a string + +// [clinic start generated code]*/ + +// static PyObject * +// _hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj) +// /*[clinic end generated code: output=6caae75b73e22c3f input=52010d3869e1b1a7]*/ +// { +// return EVP_fast_new(module, data_obj, EVP_md5()); +// } + + +// /*[clinic input] +// _hashlib.openssl_sha1 + +// string as data_obj: object(py_default="b''") = NULL + +// Returns a sha1 hash object; optionally initialized with a string + +// [clinic start generated code]*/ + +// static PyObject * +// _hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj) +// /*[clinic end generated code: output=07606d8f75153e61 input=16807d30e4aa8ae9]*/ +// { +// return EVP_fast_new(module, data_obj, EVP_sha1()); +// } + + +// /*[clinic input] +// _hashlib.openssl_sha224 + +// string as data_obj: object(py_default="b''") = NULL + +// Returns a sha224 hash object; optionally initialized with a string + +// [clinic start generated code]*/ + +// static PyObject * +// _hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj) +// /*[clinic end generated code: output=55e848761bcef0c9 input=5dbc2f1d84eb459b]*/ +// { +// return EVP_fast_new(module, data_obj, EVP_sha224()); +// } + + +// /*[clinic input] +// _hashlib.openssl_sha256 + +// string as data_obj: object(py_default="b''") = NULL + +// Returns a sha256 hash object; optionally initialized with a string + +// [clinic start generated code]*/ + +// static PyObject * +// _hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj) +// /*[clinic end generated code: output=05851d7cce34ac65 input=a68a5d21cda5a80f]*/ +// { +// return EVP_fast_new(module, data_obj, EVP_sha256()); +// } + + +// /*[clinic input] +// _hashlib.openssl_sha384 + +// string as data_obj: object(py_default="b''") = NULL + +// Returns a sha384 hash object; optionally initialized with a string + +// [clinic start generated code]*/ + +// static PyObject * +// _hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj) +// /*[clinic end generated code: output=5101a4704a932c2f input=6bdfa006622b64ea]*/ +// { +// return EVP_fast_new(module, data_obj, EVP_sha384()); +// } + + +// /*[clinic input] +// _hashlib.openssl_sha512 + +// string as data_obj: object(py_default="b''") = NULL + +// Returns a sha512 hash object; optionally initialized with a string + +// [clinic start generated code]*/ + +// static PyObject * +// _hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj) +// /*[clinic end generated code: output=20c8e63ee560a5cb input=ece50182ad4b76a6]*/ +// { +// return EVP_fast_new(module, data_obj, EVP_sha512()); +// } + + +// /*[clinic input] +// _hashlib.pbkdf2_hmac as pbkdf2_hmac + +// hash_name: str +// password: Py_buffer +// salt: Py_buffer +// iterations: long +// dklen as dklen_obj: object = None + +// Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as pseudorandom function. +// [clinic start generated code]*/ + +// static PyObject * +// pbkdf2_hmac_impl(PyObject *module, const char *hash_name, +// Py_buffer *password, Py_buffer *salt, long iterations, +// PyObject *dklen_obj) +// /*[clinic end generated code: output=144b76005416599b input=ed3ab0d2d28b5d5c]*/ +// { +// PyObject *key_obj = NULL; +// char *key; +// long dklen; +// int retval; +// const EVP_MD *digest; + +// digest = EVP_get_digestbyname(hash_name); +// 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; +// } + +// 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 +// 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); +// _setException(PyExc_ValueError); +// goto end; +// } + +// end: +// 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) { +// /* sorry, can't do much better */ +// PyErr_SetString(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); +// _setException(PyExc_ValueError); +// return NULL; +// } +// return key_obj; +// } +// #endif + +// /* Fast HMAC for hmac.digest() +// */ + +// /*[clinic input] +// _hashlib.hmac_digest + +// key: Py_buffer +// msg: Py_buffer +// digest: str + +// Single-shot HMAC. +// [clinic start generated code]*/ + +// static PyObject * +// _hashlib_hmac_digest_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, +// const char *digest) +// /*[clinic end generated code: output=75630e684cdd8762 input=562d2f4249511bd3]*/ +// { +// unsigned char md[EVP_MAX_MD_SIZE] = {0}; +// unsigned int md_len = 0; +// unsigned char *result; +// const EVP_MD *evp; + +// evp = EVP_get_digestbyname(digest); +// if (evp == NULL) { +// PyErr_SetString(PyExc_ValueError, "unsupported hash type"); +// 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; +// } + +// 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 + +// if (result == NULL) { +// _setException(PyExc_ValueError); +// return NULL; +// } +// return PyBytes_FromStringAndSize((const char*)md, md_len); +// } + +// /* 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); +// if (md == NULL) +// 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. */ +// static PyObject* +// generate_hash_name_list(void) +// { +// _InternalNameMapperState state; +// state.set = PyFrozenSet_New(NULL); +// if (state.set == NULL) +// return NULL; +// state.error = 0; + +// EVP_MD_do_all(&_openssl_hash_name_mapper, &state); + +// if (state.error) { +// Py_DECREF(state.set); +// return NULL; +// } +// return state.set; +// } + +// /* List of functions exported by this module */ + +// static struct PyMethodDef EVP_functions[] = { +// EVP_NEW_METHODDEF +// PBKDF2_HMAC_METHODDEF +// _HASHLIB_SCRYPT_METHODDEF +// _HASHLIB_HMAC_DIGEST_METHODDEF +// _HASHLIB_OPENSSL_MD5_METHODDEF +// _HASHLIB_OPENSSL_SHA1_METHODDEF +// _HASHLIB_OPENSSL_SHA224_METHODDEF +// _HASHLIB_OPENSSL_SHA256_METHODDEF +// _HASHLIB_OPENSSL_SHA384_METHODDEF +// _HASHLIB_OPENSSL_SHA512_METHODDEF +// {NULL, NULL} /* Sentinel */ +// }; + + +// /* Initialize this module. */ + + +// static struct PyModuleDef _hashlibmodule = { +// PyModuleDef_HEAD_INIT, +// "_hashlib", +// NULL, +// -1, +// EVP_functions, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit__hashlib(void) +// { +// PyObject *m, *openssl_md_meth_names; + +// #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 + +// /* TODO build EVP_functions openssl_* entries dynamically based +// * on what hashes are supported rather than listing many +// * but having some be unsupported. Only init appropriate +// * constants. */ + +// Py_TYPE(&EVPtype) = &PyType_Type; +// if (PyType_Ready(&EVPtype) < 0) +// return NULL; + +// m = PyModule_Create(&_hashlibmodule); +// if (m == NULL) +// return NULL; + +// openssl_md_meth_names = generate_hash_name_list(); +// if (openssl_md_meth_names == NULL) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddObject(m, "openssl_md_meth_names", openssl_md_meth_names)) { +// Py_DECREF(m); +// return NULL; +// } + +// Py_INCREF((PyObject *)&EVPtype); +// PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype); + +// return m; +// } diff --git a/python/Modules/_heapqmodule.c b/python/Modules/_heapqmodule.c new file mode 100755 index 0000000..6bc18b5 --- /dev/null +++ b/python/Modules/_heapqmodule.c @@ -0,0 +1,721 @@ +/* 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] +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]; + Py_INCREF(newitem); + Py_INCREF(parent); + 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) { + PyObject* a = arr[childpos]; + PyObject* b = arr[childpos + 1]; + Py_INCREF(a); + Py_INCREF(b); + 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); +} + +/*[clinic input] +_heapq.heappush + + heap: object + item: object + / + +Push item onto heap, maintaining the heap invariant. +[clinic start generated code]*/ + +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; +} + +/*[clinic input] +_heapq.heappop + + heap: object + / + +Pop the smallest item off the heap, maintaining the heap invariant. +[clinic start generated code]*/ + +static PyObject * +_heapq_heappop(PyObject *module, PyObject *heap) +/*[clinic end generated code: output=e1bbbc9866bce179 input=9bd36317b806033d]*/ +{ + 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; +} + + +/*[clinic input] +_heapq.heapreplace + + heap: object + item: object + / + +Pop and return the current smallest value, and add the new item. + +This is more efficient than heappop() followed by heappush(), and can be +more appropriate when using a fixed-size heap. Note that the value +returned may be larger than item! That constrains reasonable uses of +this routine unless written as part of a conditional replacement: + + if item > heap[0]: + item = heapreplace(heap, item) +[clinic start generated code]*/ + +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 + / + +Push item on the heap, then pop and return the smallest item from the heap. + +The combined action runs more efficiently than heappush() followed by +a separate call to heappop(). +[clinic start generated code]*/ + +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; + } + + 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; +} + +/*[clinic input] +_heapq.heapify + + heap: object + / + +Transform list into a heap, in-place, in O(len(heap)) time. +[clinic start generated code]*/ + +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]; + Py_INCREF(parent); + Py_INCREF(newitem); + 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) { + PyObject* a = arr[childpos + 1]; + PyObject* b = arr[childpos]; + Py_INCREF(a); + Py_INCREF(b); + 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); +} + + +/*[clinic input] +_heapq._heappop_max + + heap: object + / + +Maxheap variant of heappop. +[clinic start generated code]*/ + +static PyObject * +_heapq__heappop_max(PyObject *module, PyObject *heap) +/*[clinic end generated code: output=acd30acf6384b13c input=62ede3ba9117f541]*/ +{ + return heappop_internal(heap, siftup_max); +} + +/*[clinic input] +_heapq._heapreplace_max + + heap: object + item: object + / + +Maxheap variant of heapreplace. +[clinic start generated code]*/ + +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 * +_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[] = { + _HEAPQ_HEAPPUSH_METHODDEF + _HEAPQ_HEAPPUSHPOP_METHODDEF + _HEAPQ_HEAPPOP_METHODDEF + _HEAPQ_HEAPREPLACE_METHODDEF + _HEAPQ_HEAPIFY_METHODDEF + _HEAPQ__HEAPPOP_MAX_METHODDEF + _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"); + + +static struct PyModuleDef _heapqmodule = { + PyModuleDef_HEAD_INIT, + "_heapq", + module_doc, + -1, + heapq_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__heapq(void) +{ + PyObject *m, *about; + + m = PyModule_Create(&_heapqmodule); + if (m == NULL) + return NULL; + about = PyUnicode_DecodeUTF8(__about__, strlen(__about__), NULL); + PyModule_AddObject(m, "__about__", about); + return m; +} + diff --git a/python/Modules/_io/_iomodule.c b/python/Modules/_io/_iomodule.c new file mode 100755 index 0000000..49ed2cb --- /dev/null +++ b/python/Modules/_io/_iomodule.c @@ -0,0 +1,810 @@ +/* + 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 "pycore_pystate.h" /* _PyInterpreterState_GET_UNSAFE() */ +#include "structmember.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) +/*[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; + 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, + "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; + } + + if (binary && buffering == 1) { + if (PyErr_WarnEx(PyExc_RuntimeWarning, + "line buffering (buffering=1) isn't supported in " + "binary mode, the default buffer size will be used", + 1) < 0) { + goto error; + } + } + + /* Create the Raw file stream */ + { + PyObject *RawIO_class = (PyObject *)&PyFileIO_Type; +#ifdef MS_WINDOWS + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') { + RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type; + encoding = "utf-8"; + } +#endif + raw = PyObject_CallFunction(RawIO_class, + "OsiO", path_or_fd, rawmode, closefd, 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 (buffering < 0) { + PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL); + 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, + "Osssi", + buffer, + encoding, errors, newline, + line_buffering); + 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_CallMethodId(result, &PyId_close, 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 + + path : unicode + +Opens the provided file with the intent to import the contents. + +This may perform extra validation beyond open(), but is otherwise interchangeable +with calling open(path, 'rb'). + +[clinic start generated code]*/ + +static PyObject * +_io_open_code_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=2fe4ecbd6f3d6844 input=f5c18e23f4b2ed9f]*/ +{ + 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", + item->ob_type->tp_name); + } + + finish: + Py_DECREF(value); + return result; +} + + +_PyIO_State * +_PyIO_get_module_state(void) +{ + PyObject *mod = PyState_FindModule(&_PyIO_Module); + _PyIO_State *state; + if (mod == NULL || (state = IO_MOD_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) { + _PyIO_State *state = IO_MOD_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) { + _PyIO_State *state = IO_MOD_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 + _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; + state = IO_MOD_STATE(m); + state->initialized = 0; + +#define ADD_TYPE(type, name) \ + if (PyType_Ready(type) < 0) \ + goto fail; \ + Py_INCREF(type); \ + if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ + Py_DECREF(type); \ + 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, "_IOBase"); + ADD_TYPE(&PyRawIOBase_Type, "_RawIOBase"); + ADD_TYPE(&PyBufferedIOBase_Type, "_BufferedIOBase"); + ADD_TYPE(&PyTextIOBase_Type, "_TextIOBase"); + + /* Implementation of concrete IO objects. */ + /* FileIO */ + PyFileIO_Type.tp_base = &PyRawIOBase_Type; + ADD_TYPE(&PyFileIO_Type, "FileIO"); + + /* BytesIO */ + PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; + ADD_TYPE(&PyBytesIO_Type, "BytesIO"); + if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0) + goto fail; + + /* StringIO */ + PyStringIO_Type.tp_base = &PyTextIOBase_Type; + ADD_TYPE(&PyStringIO_Type, "StringIO"); + +#ifdef MS_WINDOWS + /* WindowsConsoleIO */ + PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; + ADD_TYPE(&PyWindowsConsoleIO_Type, "_WindowsConsoleIO"); +#endif + + /* BufferedReader */ + PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; + ADD_TYPE(&PyBufferedReader_Type, "BufferedReader"); + + /* BufferedWriter */ + PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type; + ADD_TYPE(&PyBufferedWriter_Type, "BufferedWriter"); + + /* BufferedRWPair */ + PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type; + ADD_TYPE(&PyBufferedRWPair_Type, "BufferedRWPair"); + + /* BufferedRandom */ + PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; + ADD_TYPE(&PyBufferedRandom_Type, "BufferedRandom"); + + /* TextIOWrapper */ + PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; + ADD_TYPE(&PyTextIOWrapper_Type, "TextIOWrapper"); + + /* IncrementalNewlineDecoder */ + ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder"); + + /* 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/python/Modules/_io/_iomodule.h b/python/Modules/_io/_iomodule.h new file mode 100755 index 0000000..4d318ac --- /dev/null +++ b/python/Modules/_io/_iomodule.h @@ -0,0 +1,186 @@ +/* + * Declarations shared between the different parts of the io module + */ + +/* 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 PyTypeObject _PyBytesIOBuffer_Type; diff --git a/python/Modules/_io/bufferedio.c b/python/Modules/_io/bufferedio.c new file mode 100755 index 0000000..ad7a8c9 --- /dev/null +++ b/python/Modules/_io/bufferedio.c @@ -0,0 +1,2725 @@ +/* + 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 "pycore_pystate.h" +#include "structmember.h" +#include "pythread.h" +#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 *msgobj = PyUnicode_FromFormat( + "could not acquire lock for %A at interpreter " + "shutdown, possibly due to daemon threads", + (PyObject *) self); + const char *msg = PyUnicode_AsUTF8(msgobj); + Py_FatalError(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)) { \ + 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 * +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; + r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn, + source, NULL); + 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_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL); +} + +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_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + if (!ENTER_BUFFERED(self)) + return NULL; + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); + else + Py_DECREF(res); + + res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL); + + if (self->buffer) { + PyMem_Free(self->buffer); + self->buffer = NULL; + } + + if (exc != NULL) { + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(res); + } + +end: + LEAVE_BUFFERED(self) + return res; +} + +/* detach */ + +static PyObject * +buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *raw, *res; + CHECK_INITIALIZED(self) + res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + 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) + return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL); +} + +static PyObject * +buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + CHECK_INITIALIZED(self) + return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL); +} + +static PyObject * +buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + CHECK_INITIALIZED(self) + return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL); +} + +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) + return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL); +} + +static PyObject * +buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + CHECK_INITIALIZED(self) + return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL); +} + +/* 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_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL); + 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 * +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) + 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 = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL); + 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_CallMethodObjArgs((PyObject *)self, + _PyIO_str_readline, NULL); + 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; + } + /* 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); + + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type && + Py_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 { + res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL); + } 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_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); + 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_TYPE(self) == &PyBufferedWriter_Type && + Py_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; + res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL); + 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 * +bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored)) +{ + return _forward_call(self->reader, &PyId_readable, NULL); +} + +static PyObject * +bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored)) +{ + return _forward_call(self->writer, &PyId_writable, NULL); +} + +static PyObject * +bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored)) +{ + 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); + ret = _forward_call(self->reader, &PyId_close, NULL); + 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); + + 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; + + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type && + Py_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*/ + 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, /*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*/ + 0, /*tp_vectorcall_offset*/ + 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 + | 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*/ + 0, /*tp_vectorcall_offset*/ + 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 + | 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*/ + 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 */ + _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_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 + | 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 */ +}; diff --git a/python/Modules/_io/bytesio.c b/python/Modules/_io/bytesio.c new file mode 100755 index 0000000..3cf6402 --- /dev/null +++ b/python/Modules/_io/bytesio.c @@ -0,0 +1,1143 @@ +#include "Python.h" +#include "pycore_object.h" +#include "structmember.h" /* for 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. +*/ + +#define CHECK_CLOSED(self) \ + if ((self)->buf == NULL) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on closed file."); \ + return NULL; \ + } + +#define CHECK_EXPORTS(self) \ + if ((self)->exports > 0) { \ + PyErr_SetString(PyExc_BufferError, \ + "Existing exports of data: object cannot be re-sized"); \ + 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. */ +static Py_ssize_t +write_bytes(bytesio *self, const char *bytes, Py_ssize_t len) +{ + size_t endpos; + assert(self->buf != NULL); + assert(self->pos >= 0); + assert(len >= 0); + + endpos = (size_t)self->pos + len; + if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) { + if (resize_buffer(self, endpos) < 0) + return -1; + } + else if (SHARED_BUF(self)) { + if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0) + return -1; + } + + 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, bytes, 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; + } + + 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) +{ + 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; + 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]*/ +{ + Py_ssize_t n = 0; + Py_buffer buf; + + CHECK_CLOSED(self); + CHECK_EXPORTS(self); + + if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0) + return NULL; + + if (buf.len != 0) + n = write_bytes(self, buf.buf, buf.len); + + PyBuffer_Release(&buf); + 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; + PyObject *ret; + + CHECK_CLOSED(self); + + it = PyObject_GetIter(lines); + if (it == NULL) + return NULL; + + while ((item = PyIter_Next(it)) != NULL) { + ret = _io_BytesIO_write(self, item); + Py_DECREF(item); + if (ret == NULL) { + Py_DECREF(it); + return NULL; + } + Py_DECREF(ret); + } + 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 + 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)); + if (self->buf && !SHARED_BUF(self)) { + Py_ssize_t s = _PySys_GetSizeOf(self->buf); + if (s == -1) { + return NULL; + } + 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*/ + 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*/ + _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, +}; + +PyTypeObject _PyBytesIOBuffer_Type = { + 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_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*/ +}; diff --git a/python/Modules/_io/clinic/_iomodule.c.h b/python/Modules/_io/clinic/_iomodule.c.h new file mode 100755 index 0000000..1a9651d --- /dev/null +++ b/python/Modules/_io/clinic/_iomodule.c.h @@ -0,0 +1,326 @@ +/*[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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 8, 0, argsbuf); + if (!args) { + goto exit; + } + file = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("open", "argument 'mode'", "str", args[1]); + goto exit; + } + Py_ssize_t mode_length; + mode = PyUnicode_AsUTF8AndSize(args[1], &mode_length); + if (mode == NULL) { + goto exit; + } + if (strlen(mode) != (size_t)mode_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + 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; + } + buffering = _PyLong_AsInt(args[2]); + if (buffering == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[3]) { + if (args[3] == Py_None) { + encoding = NULL; + } + else if (PyUnicode_Check(args[3])) { + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[3], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("open", "argument 'encoding'", "str or None", args[3]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[4]) { + if (args[4] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[4])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[4], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("open", "argument 'errors'", "str or None", args[4]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[5]) { + if (args[5] == Py_None) { + newline = NULL; + } + else if (PyUnicode_Check(args[5])) { + Py_ssize_t newline_length; + newline = PyUnicode_AsUTF8AndSize(args[5], &newline_length); + if (newline == NULL) { + goto exit; + } + if (strlen(newline) != (size_t)newline_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("open", "argument 'newline'", "str or None", args[5]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[6]) { + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + closefd = _PyLong_AsInt(args[6]); + if (closefd == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + opener = args[7]; +skip_optional_pos: + 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" +"--\n" +"\n" +"Opens the provided file with the intent to import the contents.\n" +"\n" +"This may perform extra validation beyond open(), but is otherwise interchangeable\n" +"with calling open(path, \'rb\')."); + +#define _IO_OPEN_CODE_METHODDEF \ + {"open_code", (PyCFunction)(void(*)(void))_io_open_code, METH_FASTCALL|METH_KEYWORDS, _io_open_code__doc__}, + +static PyObject * +_io_open_code_impl(PyObject *module, PyObject *path); + +static PyObject * +_io_open_code(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, "open_code", 0}; + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("open_code", "argument 'path'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + path = args[0]; + return_value = _io_open_code_impl(module, path); + +exit: + return return_value; +} +/*[clinic end generated code: output=3df6bc6d91697545 input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/clinic/bufferedio.c.h b/python/Modules/_io/clinic/bufferedio.c.h new file mode 100755 index 0000000..72841fc --- /dev/null +++ b/python/Modules/_io/clinic/bufferedio.c.h @@ -0,0 +1,675 @@ +/*[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; + } + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + PyErr_Clear(); + _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("peek", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &n)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("read1", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + PyErr_Clear(); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + PyErr_Clear(); + _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { + goto exit; + } + targetobj = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + whence = _PyLong_AsInt(args[1]); + if (whence == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { + 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}; + 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + raw = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(fastargs[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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}; + 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + raw = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(fastargs[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { + 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; + + if ((Py_TYPE(self) == &PyBufferedRWPair_Type) && + !_PyArg_NoKeywords("BufferedRWPair", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("BufferedRWPair", PyTuple_GET_SIZE(args), 2, 3)) { + goto exit; + } + reader = PyTuple_GET_ITEM(args, 0); + writer = PyTuple_GET_ITEM(args, 1); + if (PyTuple_GET_SIZE(args) < 3) { + goto skip_optional; + } + if (PyFloat_Check(PyTuple_GET_ITEM(args, 2))) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(PyTuple_GET_ITEM(args, 2)); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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}; + 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + raw = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(fastargs[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + buffer_size = ival; + } +skip_optional_pos: + return_value = _io_BufferedRandom___init___impl((buffered *)self, raw, buffer_size); + +exit: + return return_value; +} +/*[clinic end generated code: output=7246104f6c7d3167 input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/clinic/bytesio.c.h b/python/Modules/_io/clinic/bytesio.c.h new file mode 100755 index 0000000..83cd490 --- /dev/null +++ b/python/Modules/_io/clinic/bytesio.c.h @@ -0,0 +1,518 @@ +/*[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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("read1", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readlines", nargs, 0, 1)) { + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + PyErr_Clear(); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + whence = _PyLong_AsInt(args[1]); + if (whence == -1 && PyErr_Occurred()) { + 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}; + 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { + 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; +} +/*[clinic end generated code: output=4ec2506def9c8eb9 input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/clinic/fileio.c.h b/python/Modules/_io/clinic/fileio.c.h new file mode 100755 index 0000000..53e7067 --- /dev/null +++ b/python/Modules/_io/clinic/fileio.c.h @@ -0,0 +1,450 @@ +/*[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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 4, 0, argsbuf); + if (!fastargs) { + goto exit; + } + nameobj = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[1]) { + if (!PyUnicode_Check(fastargs[1])) { + _PyArg_BadArgument("FileIO", "argument 'mode'", "str", fastargs[1]); + goto exit; + } + Py_ssize_t mode_length; + mode = PyUnicode_AsUTF8AndSize(fastargs[1], &mode_length); + if (mode == NULL) { + goto exit; + } + if (strlen(mode) != (size_t)mode_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + if (PyFloat_Check(fastargs[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + closefd = _PyLong_AsInt(fastargs[2]); + if (closefd == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + PyErr_Clear(); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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}; + + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { + goto exit; + } + pos = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + whence = _PyLong_AsInt(args[1]); + if (whence == -1 && PyErr_Occurred()) { + 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 \ + {"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; + PyObject *posobj = Py_None; + + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { + 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) */ +/*[clinic end generated code: output=e7682d0a3264d284 input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/clinic/iobase.c.h b/python/Modules/_io/clinic/iobase.c.h new file mode 100755 index 0000000..ddaff7b --- /dev/null +++ b/python/Modules/_io/clinic/iobase.c.h @@ -0,0 +1,318 @@ +/*[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; + + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &limit)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readlines", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &hint)) { + 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" +"\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 \ + {"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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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); +} +/*[clinic end generated code: output=61b6ea7153ef9940 input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/clinic/stringio.c.h b/python/Modules/_io/clinic/stringio.c.h new file mode 100755 index 0000000..77a720c --- /dev/null +++ b/python/Modules/_io/clinic/stringio.c.h @@ -0,0 +1,351 @@ +/*[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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + whence = _PyLong_AsInt(args[1]); + if (whence == -1 && PyErr_Occurred()) { + 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}; + 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + value = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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); +} +/*[clinic end generated code: output=7aad5ab2e64a25b8 input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/clinic/textio.c.h b/python/Modules/_io/clinic/textio.c.h new file mode 100755 index 0000000..b8b5075 --- /dev/null +++ b/python/Modules/_io/clinic/textio.c.h @@ -0,0 +1,704 @@ +/*[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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 3, 0, argsbuf); + if (!fastargs) { + goto exit; + } + decoder = fastargs[0]; + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + translate = _PyLong_AsInt(fastargs[1]); + if (translate == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + input = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[1]); + if (final == -1 && PyErr_Occurred()) { + 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}; + 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 6, 0, argsbuf); + if (!fastargs) { + goto exit; + } + buffer = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[1]) { + if (fastargs[1] == Py_None) { + encoding = NULL; + } + else if (PyUnicode_Check(fastargs[1])) { + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("TextIOWrapper", "argument 'encoding'", "str or None", fastargs[1]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + errors = fastargs[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[3]) { + if (fastargs[3] == Py_None) { + newline = NULL; + } + else if (PyUnicode_Check(fastargs[3])) { + Py_ssize_t newline_length; + newline = PyUnicode_AsUTF8AndSize(fastargs[3], &newline_length); + if (newline == NULL) { + goto exit; + } + if (strlen(newline) != (size_t)newline_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("TextIOWrapper", "argument 'newline'", "str or None", fastargs[3]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[4]) { + if (PyFloat_Check(fastargs[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + line_buffering = _PyLong_AsInt(fastargs[4]); + if (line_buffering == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(fastargs[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + write_through = _PyLong_AsInt(fastargs[5]); + if (write_through == -1 && PyErr_Occurred()) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[0]) { + encoding = args[0]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[1]) { + errors = args[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + newline_obj = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + line_buffering_obj = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("write", "argument", "str", arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &n)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { + goto exit; + } + cookieObj = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + whence = _PyLong_AsInt(args[1]); + if (whence == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { + 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); +} +/*[clinic end generated code: output=b1bae4f4cdf6019e input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/clinic/winconsoleio.c.h b/python/Modules/_io/clinic/winconsoleio.c.h new file mode 100755 index 0000000..3e501a5 --- /dev/null +++ b/python/Modules/_io/clinic/winconsoleio.c.h @@ -0,0 +1,389 @@ +/*[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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 4, 0, argsbuf); + if (!fastargs) { + goto exit; + } + nameobj = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[1]) { + if (!PyUnicode_Check(fastargs[1])) { + _PyArg_BadArgument("_WindowsConsoleIO", "argument 'mode'", "str", fastargs[1]); + goto exit; + } + Py_ssize_t mode_length; + mode = PyUnicode_AsUTF8AndSize(fastargs[1], &mode_length); + if (mode == NULL) { + goto exit; + } + if (strlen(mode) != (size_t)mode_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + if (PyFloat_Check(fastargs[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + closefd = _PyLong_AsInt(fastargs[2]); + if (closefd == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + PyErr_Clear(); + _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { + 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}; + + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { + 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) */ +/*[clinic end generated code: output=f5b8860a658a001a input=a9049054013a1b77]*/ diff --git a/python/Modules/_io/fileio.c b/python/Modules/_io/fileio.c new file mode 100755 index 0000000..482d08f --- /dev/null +++ b/python/Modules/_io/fileio.c @@ -0,0 +1,1238 @@ +/* Author: Daniel Stutzbach */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "pycore_object.h" +#include "structmember.h" +#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 */ +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); + res = _PyObject_CallMethodIdObjArgs((PyObject*)&PyRawIOBase_Type, + &PyId_close, self, NULL); + 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; + } + widename = PyUnicode_AsUnicode(stringobj); + 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()). */ + 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 */ + 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 * +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); + } + + if (res < 0) { + if (suppress_pipe_error && errno == ESPIPE) { + res = 0; + } else { + 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(); + + 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(); + + return portable_lseek(self, NULL, 1, false); +} + +#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) +/*[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"); + + if (posobj == Py_None) { + /* 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 */ + 0, /* tp_vectorcall_offset */ + 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 + | 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 */ + 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 */ + 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 */ +}; diff --git a/python/Modules/_io/iobase.c b/python/Modules/_io/iobase.c new file mode 100755 index 0000000..fab4509 --- /dev/null +++ b/python/Modules/_io/iobase.c @@ -0,0 +1,1083 @@ +/* + 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 "structmember.h" +#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_CallMethodObjArgs(self, _PyIO_str_flush, NULL); + + 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_CallMethodObjArgs((PyObject *) self, _PyIO_str_close, + NULL); + /* 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 + const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + if (config->dev_mode) { + PyErr_WriteUnraisable(self); + } + else { + PyErr_Clear(); + } +#else + PyErr_WriteUnraisable(self); +#endif + } + else { + 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) +{ + PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL); + 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_CallMethodObjArgs(self, _PyIO_str_readable, NULL); + 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_CallMethodObjArgs(self, _PyIO_str_writable, NULL); + 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_CallMethodObjArgs(self, _PyIO_str_close, 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_CallFunctionObjArgs(peek, _PyLong_One, NULL); + 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_CallMethodObjArgs(self, _PyIO_str_readline, NULL); + + 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 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*/ + 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*/ + 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_CallMethodId(self, &PyId_readall, NULL); + } + + /* 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_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*/ + 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/python/Modules/_io/stringio.c b/python/Modules/_io/stringio.c new file mode 100755 index 0000000..8b5fa7a --- /dev/null +++ b/python/Modules/_io/stringio.c @@ -0,0 +1,1044 @@ +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "structmember.h" +#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); + + if (Py_TYPE(self) == &PyStringIO_Type) { + /* Skip method call overhead for speed */ + line = _stringio_readline(self, -1); + } + else { + /* XXX is subclassing StringIO really supported? */ + line = PyObject_CallMethodObjArgs((PyObject *)self, + _PyIO_str_readline, NULL); + 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_CallFunction( + (PyObject *)&PyIncrementalNewlineDecoder_Type, + "Oi", Py_None, (int) self->readtranslate); + 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 + 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*/ + 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*/ + _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/python/Modules/_io/textio.c b/python/Modules/_io/textio.c new file mode 100755 index 0000000..642c614 --- /dev/null +++ b/python/Modules/_io/textio.c @@ -0,0 +1,3299 @@ +/* + 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_object.h" +#include "structmember.h" +#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[] = { + {"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*/ + 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, /*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); + PyUnicode_WRITE(kind, PyUnicode_DATA(modified), 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. */ + { + 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); + 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) { + PyObject *state = PyObject_CallMethodObjArgs(self->decoder, + _PyIO_str_getstate, NULL); + 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_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); + 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)); +} + +// Return true when encoding can be skipped when text is ascii. +static inline int +is_asciicompat_encoding(encodefunc_t f) +{ + return f == (encodefunc_t) ascii_encode + || f == (encodefunc_t) latin1_encode + || 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} +}; + +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_CallMethodId(self->buffer, &PyId_readable, NULL); + 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_CallFunction( + (PyObject *)&PyIncrementalNewlineDecoder_Type, + "Oi", self->decoder, (int)self->readtranslate); + 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_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_CallMethodId(self->buffer, &PyId_writable, NULL); + 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_CallMethodObjArgs( + self->buffer, _PyIO_str_tell, NULL); + 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_CallMethodObjArgs( + self->encoder, _PyIO_str_setstate, _PyLong_Zero, NULL); + if (res == NULL) { + return -1; + } + Py_DECREF(res); + } + + return 0; +} + +/*[clinic input] +_io.TextIOWrapper.__init__ + buffer: object + encoding: str(accept={str, NoneType}) = 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) +/*[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", + errors->ob_type->tp_name); + 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; + fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL); + /* 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_CallMethodIdObjArgs( + locale_module, &PyId_getpreferredencoding, Py_False, NULL); + 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_TYPE(buffer) == &PyBufferedReader_Type || + Py_TYPE(buffer) == &PyBufferedWriter_Type || + Py_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 (Py_TYPE(raw) == &PyFileIO_Type) + self->raw = raw; + else + Py_DECREF(raw); + } + } + + res = _PyObject_CallMethodId(buffer, &PyId_seekable, 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_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + 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_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); + res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + 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; + + if (PyBytes_Check(pending)) { + b = pending; + Py_INCREF(b); + } + else if (PyUnicode_Check(pending)) { + assert(PyUnicode_IS_ASCII(pending)); + assert(PyUnicode_GET_LENGTH(pending) == self->pending_bytes_count); + b = PyBytes_FromStringAndSize( + PyUnicode_DATA(pending), PyUnicode_GET_LENGTH(pending)); + if (b == NULL) { + return -1; + } + } + else { + assert(PyList_Check(pending)); + b = PyBytes_FromStringAndSize(NULL, self->pending_bytes_count); + if (b == NULL) { + return -1; + } + + char *buf = PyBytes_AsString(b); + Py_ssize_t pos = 0; + + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pending); i++) { + PyObject *obj = PyList_GET_ITEM(pending, i); + char *src; + Py_ssize_t len; + if (PyUnicode_Check(obj)) { + assert(PyUnicode_IS_ASCII(obj)); + src = PyUnicode_DATA(obj); + len = PyUnicode_GET_LENGTH(obj); + } + else { + assert(PyBytes_Check(obj)); + if (PyBytes_AsStringAndSize(obj, &src, &len) < 0) { + Py_DECREF(b); + return -1; + } + } + memcpy(buf + pos, src, len); + pos += len; + } + assert(pos == self->pending_bytes_count); + } + + self->pending_bytes_count = 0; + self->pending_bytes = NULL; + Py_DECREF(pending); + + PyObject *ret; + do { + ret = PyObject_CallMethodObjArgs(self->buffer, + _PyIO_str_write, b, NULL); + } 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 (PyUnicode_IS_ASCII(text) && + // See bpo-43260 + PyUnicode_GET_LENGTH(text) <= self->chunk_size && + is_asciicompat_encoding(self->encodefunc)) { + b = text; + Py_INCREF(b); + } + else { + b = (*self->encodefunc)((PyObject *) self, text); + } + self->encoding_start_of_stream = 0; + } + else { + b = PyObject_CallMethodObjArgs(self->encoder, + _PyIO_str_encode, text, NULL); + } + + 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_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL); + if (ret == NULL) + return NULL; + Py_DECREF(ret); + } + + textiowrapper_set_decoded_chars(self, NULL); + Py_CLEAR(self->snapshot); + + if (self->decoder) { + ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL); + 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_CallMethodObjArgs(self->decoder, + _PyIO_str_getstate, NULL); + 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_CallMethodObjArgs(self->buffer, + (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read), + chunk_size, NULL); + 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_CallMethodId(self->buffer, &PyId_read, NULL); + PyObject *decoded; + if (bytes == NULL) + goto fail; + + if (Py_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); + 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) { + 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_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); + 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_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL); + self->encoding_start_of_stream = 1; + } + else { + res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate, + _PyLong_Zero, NULL); + 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); + cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL); + 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; + } + + res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); + if (res == NULL) + goto fail; + Py_DECREF(res); + + textiowrapper_set_decoded_chars(self, NULL); + Py_CLEAR(self->snapshot); + if (self->decoder) { + res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL); + 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, + "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; + } + + res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + 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_CallMethodObjArgs(self->buffer, + _PyIO_str_seek, posobj, NULL); + 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_CallMethodId(self->decoder, &PyId_decode, + "Oi", input_chunk, (int)cookie.need_eof); + + 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; + 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; + res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); + if (res == NULL) + goto fail; + Py_DECREF(res); + + posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL); + 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_CallMethodObjArgs(self->decoder, + _PyIO_str_getstate, NULL); + if (saved_state == NULL) + goto fail; + +#define DECODER_GETSTATE() do { \ + PyObject *dec_buffer; \ + PyObject *_state = PyObject_CallMethodObjArgs(self->decoder, \ + _PyIO_str_getstate, NULL); \ + 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, "yi", "", /* final = */ 1); + 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_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL); + 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_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL); + _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_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL); + if (res == NULL) + return NULL; + Py_DECREF(res); + + return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL); +} + +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; + } + /* 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; + } + 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); + return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL); +} + +/*[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_CallMethodId(self->buffer, &PyId_seekable, NULL); +} + +/*[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_CallMethodId(self->buffer, &PyId_readable, NULL); +} + +/*[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_CallMethodId(self->buffer, &PyId_writable, NULL); +} + +/*[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_CallMethodId(self->buffer, &PyId_isatty, 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_CallMethodId(self->buffer, &PyId_flush, NULL); +} + +/*[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_CallMethodIdObjArgs(self->buffer, + &PyId__dealloc_warn, + self, NULL); + if (res) + Py_DECREF(res); + else + PyErr_Clear(); + } + res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); + else + Py_DECREF(res); + + res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL); + 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_TYPE(self) == &PyTextIOWrapper_Type) { + /* Skip method call overhead for speed */ + line = _textiowrapper_readline(self, -1); + } + else { + line = PyObject_CallMethodObjArgs((PyObject *)self, + _PyIO_str_readline, NULL); + 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_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_vectorcall_offset*/ + 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 + | 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 */ +}; diff --git a/python/Modules/_io/winconsoleio.c b/python/Modules/_io/winconsoleio.c new file mode 100755 index 0000000..ea5d24f --- /dev/null +++ b/python/Modules/_io/winconsoleio.c @@ -0,0 +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" +#include "pycore_object.h" + +#ifdef MS_WINDOWS + +#include "structmember.h" +#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_CallMethodIdObjArgs((PyObject*)&PyRawIOBase_Type, + &PyId_close, self, NULL); + 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, + "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 */ + 0, /* tp_vectorcall_offset */ + 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 + | 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 */ +}; + +PyObject * _PyWindowsConsoleIO_Type = (PyObject*)&PyWindowsConsoleIO_Type; + +#endif /* MS_WINDOWS */ diff --git a/python/Modules/_json.c b/python/Modules/_json.c new file mode 100755 index 0000000..43a6ab3 --- /dev/null +++ b/python/Modules/_json.c @@ -0,0 +1,1943 @@ +// /* JSON accelerator C extensor: _json module. +// * +// * 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" +// #include "structmember.h" +// #include "pycore_accu.h" + +// #ifdef __GNUC__ +// #define UNUSED __attribute__((__unused__)) +// #else +// #define UNUSED +// #endif + +// #define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType) +// #define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType) +// #define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType) +// #define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType) + +// static PyTypeObject PyScannerType; +// static PyTypeObject PyEncoderType; + +// 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} +// }; + +// static PyObject * +// join_list_unicode(PyObject *lst) +// { +// /* return u''.join(lst) */ +// static PyObject *sep = NULL; +// if (sep == NULL) { +// sep = PyUnicode_FromStringAndSize("", 0); +// if (sep == NULL) +// return NULL; +// } +// return PyUnicode_Join(sep, lst); +// } + +// /* Forward decls */ + +// static PyObject * +// ascii_escape_unicode(PyObject *pystr); +// static PyObject * +// py_encode_basestring_ascii(PyObject* self UNUSED, 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 +// scanner_clear(PyObject *self); +// static PyObject * +// encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +// static void +// encoder_dealloc(PyObject *self); +// static int +// encoder_clear(PyObject *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; +// void *input; +// unsigned char *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; +// 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; +// } + +// #define APPEND_OLD_CHUNK \ +// if (chunk != NULL) { \ +// if (chunks == NULL) { \ +// chunks = PyList_New(0); \ +// if (chunks == NULL) { \ +// goto bail; \ +// } \ +// } \ +// if (PyList_Append(chunks, chunk)) { \ +// Py_CLEAR(chunk); \ +// goto bail; \ +// } \ +// Py_CLEAR(chunk); \ +// } + +// 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; +// PyObject *chunks = NULL; +// PyObject *chunk = NULL; + +// if (PyUnicode_READY(pystr) == -1) +// return 0; + +// 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 = 0; +// for (next = end; next < len; next++) { +// c = PyUnicode_READ(kind, buf, next); +// if (c == '"' || c == '\\') { +// break; +// } +// else if (c <= 0x1f && strict) { +// raise_errmsg("Invalid control character at", pystr, next); +// goto bail; +// } +// } +// if (!(c == '"' || c == '\\')) { +// raise_errmsg("Unterminated string starting at", pystr, begin); +// goto bail; +// } +// /* Pick up this chunk if it's not zero length */ +// if (next != end) { +// APPEND_OLD_CHUNK +// chunk = PyUnicode_FromKindAndData( +// kind, +// (char*)buf + kind * end, +// next - end); +// if (chunk == NULL) { +// 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; +// } +// } +// APPEND_OLD_CHUNK +// chunk = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, &c, 1); +// if (chunk == NULL) { +// goto bail; +// } +// } + +// if (chunks == NULL) { +// if (chunk != NULL) +// rval = chunk; +// else +// rval = PyUnicode_FromStringAndSize("", 0); +// } +// else { +// APPEND_OLD_CHUNK +// rval = join_list_unicode(chunks); +// if (rval == NULL) { +// goto bail; +// } +// Py_CLEAR(chunks); +// } + +// *next_end_ptr = end; +// return rval; +// bail: +// *next_end_ptr = -1; +// Py_XDECREF(chunks); +// Py_XDECREF(chunk); +// 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* self UNUSED, 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 * +// py_encode_basestring_ascii(PyObject* self UNUSED, 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 * +// py_encode_basestring(PyObject* self UNUSED, 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) +// { +// /* bpo-31095: UnTrack is needed before calling any callbacks */ +// PyObject_GC_UnTrack(self); +// scanner_clear(self); +// Py_TYPE(self)->tp_free(self); +// } + +// static int +// scanner_traverse(PyObject *self, visitproc visit, void *arg) +// { +// PyScannerObject *s; +// assert(PyScanner_Check(self)); +// s = (PyScannerObject *)self; +// Py_VISIT(s->object_hook); +// Py_VISIT(s->object_pairs_hook); +// Py_VISIT(s->parse_float); +// Py_VISIT(s->parse_int); +// Py_VISIT(s->parse_constant); +// return 0; +// } + +// static int +// scanner_clear(PyObject *self) +// { +// PyScannerObject *s; +// assert(PyScanner_Check(self)); +// s = (PyScannerObject *)self; +// Py_CLEAR(s->object_hook); +// Py_CLEAR(s->object_pairs_hook); +// Py_CLEAR(s->parse_float); +// Py_CLEAR(s->parse_int); +// Py_CLEAR(s->parse_constant); +// Py_CLEAR(s->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) +// */ +// 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; +// memokey = PyDict_GetItemWithError(s->memo, key); +// if (memokey != NULL) { +// Py_INCREF(memokey); +// Py_DECREF(key); +// key = memokey; +// } +// else if (PyErr_Occurred()) { +// goto bail; +// } +// else { +// if (PyDict_SetItem(s->memo, key, key) < 0) +// goto bail; +// } +// 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_CallFunctionObjArgs(s->object_pairs_hook, rval, NULL); +// Py_DECREF(rval); +// return val; +// } + +// /* if object_hook is not None: rval = object_hook(rval) */ +// if (s->object_hook != Py_None) { +// val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL); +// 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 +// */ +// 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) */ +// rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL); +// 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 +// */ +// 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; +// rval = PyObject_CallFunctionObjArgs(custom_func, numstr, NULL); +// } +// 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; +// 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 * +// scanner_call(PyObject *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}; +// PyScannerObject *s; +// assert(PyScanner_Check(self)); +// s = (PyScannerObject *)self; +// if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx)) +// return NULL; + +// if (PyUnicode_Check(pystr)) { +// rval = scan_once_unicode(s, pystr, idx, &next_idx); +// } +// else { +// PyErr_Format(PyExc_TypeError, +// "first argument must be a string, not %.80s", +// Py_TYPE(pystr)->tp_name); +// return NULL; +// } +// PyDict_Clear(s->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"); + +// static +// PyTypeObject PyScannerType = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "_json.Scanner", /* tp_name */ +// sizeof(PyScannerObject), /* tp_basicsize */ +// 0, /* tp_itemsize */ +// scanner_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 */ +// scanner_call, /* tp_call */ +// 0, /* tp_str */ +// 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */ +// 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */ +// 0, /* tp_as_buffer */ +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ +// scanner_doc, /* tp_doc */ +// scanner_traverse, /* tp_traverse */ +// scanner_clear, /* tp_clear */ +// 0, /* tp_richcompare */ +// 0, /* tp_weaklistoffset */ +// 0, /* tp_iter */ +// 0, /* tp_iternext */ +// 0, /* tp_methods */ +// scanner_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,/* PyType_GenericAlloc, */ /* tp_alloc */ +// scanner_new, /* tp_new */ +// 0,/* PyObject_GC_Del, */ /* tp_free */ +// }; + +// 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(PyObject *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; +// PyEncoderObject *s; +// _PyAccu acc; + +// assert(PyEncoder_Check(self)); +// s = (PyEncoderObject *)self; +// if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist, +// &obj, &indent_level)) +// return NULL; +// if (_PyAccu_Init(&acc)) +// return NULL; +// if (encoder_listencode_obj(s, &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); +// } +// encoded = PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); +// 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; +// } +// } +// newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL); +// 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, " +// "not %.100s", key->ob_type->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) +// { +// /* bpo-31095: UnTrack is needed before calling any callbacks */ +// PyObject_GC_UnTrack(self); +// encoder_clear(self); +// Py_TYPE(self)->tp_free(self); +// } + +// static int +// encoder_traverse(PyObject *self, visitproc visit, void *arg) +// { +// PyEncoderObject *s; +// assert(PyEncoder_Check(self)); +// s = (PyEncoderObject *)self; +// Py_VISIT(s->markers); +// Py_VISIT(s->defaultfn); +// Py_VISIT(s->encoder); +// Py_VISIT(s->indent); +// Py_VISIT(s->key_separator); +// Py_VISIT(s->item_separator); +// return 0; +// } + +// static int +// encoder_clear(PyObject *self) +// { +// /* Deallocate Encoder */ +// PyEncoderObject *s; +// assert(PyEncoder_Check(self)); +// s = (PyEncoderObject *)self; +// Py_CLEAR(s->markers); +// Py_CLEAR(s->defaultfn); +// Py_CLEAR(s->encoder); +// Py_CLEAR(s->indent); +// Py_CLEAR(s->key_separator); +// Py_CLEAR(s->item_separator); +// return 0; +// } + +// PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable"); + +// static +// PyTypeObject PyEncoderType = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "_json.Encoder", /* tp_name */ +// sizeof(PyEncoderObject), /* tp_basicsize */ +// 0, /* tp_itemsize */ +// encoder_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 */ +// encoder_call, /* tp_call */ +// 0, /* tp_str */ +// 0, /* tp_getattro */ +// 0, /* tp_setattro */ +// 0, /* tp_as_buffer */ +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ +// encoder_doc, /* tp_doc */ +// encoder_traverse, /* tp_traverse */ +// encoder_clear, /* tp_clear */ +// 0, /* tp_richcompare */ +// 0, /* tp_weaklistoffset */ +// 0, /* tp_iter */ +// 0, /* tp_iternext */ +// 0, /* tp_methods */ +// encoder_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 */ +// encoder_new, /* tp_new */ +// 0, /* tp_free */ +// }; + +// 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 struct PyModuleDef jsonmodule = { +// PyModuleDef_HEAD_INIT, +// "_json", +// module_doc, +// -1, +// speedups_methods, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit__json(void) +// { +// PyObject *m = PyModule_Create(&jsonmodule); +// if (!m) +// return NULL; +// if (PyType_Ready(&PyScannerType) < 0) +// goto fail; +// if (PyType_Ready(&PyEncoderType) < 0) +// goto fail; +// Py_INCREF((PyObject*)&PyScannerType); +// if (PyModule_AddObject(m, "make_scanner", (PyObject*)&PyScannerType) < 0) { +// Py_DECREF((PyObject*)&PyScannerType); +// goto fail; +// } +// Py_INCREF((PyObject*)&PyEncoderType); +// if (PyModule_AddObject(m, "make_encoder", (PyObject*)&PyEncoderType) < 0) { +// Py_DECREF((PyObject*)&PyEncoderType); +// goto fail; +// } +// return m; +// fail: +// Py_DECREF(m); +// return NULL; +// } diff --git a/python/Modules/_localemodule.c b/python/Modules/_localemodule.c new file mode 100755 index 0000000..d54f709 --- /dev/null +++ b/python/Modules/_localemodule.c @@ -0,0 +1,796 @@ +/*********************************************************** +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."); + +static PyObject *Error; + +/* 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(Error, "invalid locale category"); + return NULL; + } +#endif + + if (locale) { + /* set locale */ + result = setlocale(category, locale); + if (!result) { + /* operation failed, no setting was changed */ + PyErr_SetString(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) { + PyErr_SetString(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) +{ +#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); + } + } + +#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; \ + 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 +#undef GET_LOCALE_STRING + + 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* +PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored)) +{ + 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 */ + 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) + +#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 { \ + x = GET_LOCALE_STRING(s); \ + 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 */ + if (locale_decode_monetary(result, lc) < 0) { + 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 */ + 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); + + x = copy_grouping(lc->grouping); + 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* +PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored)) +{ + char encoding[20]; + 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* +PyIntl_bindtextdomain(PyObject* self,PyObject*args) +{ + char *domain, *dirname, *current_dirname; + PyObject *dirname_obj, *dirname_bytes = NULL, *result; + if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) + return 0; + if (!strlen(domain)) { + PyErr_SetString(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__}, + {"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) + {"_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} +}; + + +static struct PyModuleDef _localemodule = { + PyModuleDef_HEAD_INIT, + "_locale", + locale__doc__, + -1, + PyLocale_Methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__locale(void) +{ + PyObject *m; +#ifdef HAVE_LANGINFO_H + int i; +#endif + + m = PyModule_Create(&_localemodule); + if (m == NULL) + return NULL; + + PyModule_AddIntMacro(m, LC_CTYPE); + PyModule_AddIntMacro(m, LC_TIME); + PyModule_AddIntMacro(m, LC_COLLATE); + PyModule_AddIntMacro(m, LC_MONETARY); + +#ifdef LC_MESSAGES + PyModule_AddIntMacro(m, LC_MESSAGES); +#endif /* LC_MESSAGES */ + + PyModule_AddIntMacro(m, LC_NUMERIC); + PyModule_AddIntMacro(m, LC_ALL); + PyModule_AddIntMacro(m, CHAR_MAX); + + Error = PyErr_NewException("locale.Error", NULL, NULL); + if (Error == NULL) { + Py_DECREF(m); + return NULL; + } + PyModule_AddObject(m, "Error", Error); + +#ifdef HAVE_LANGINFO_H + for (i = 0; langinfo_constants[i].name; i++) { + PyModule_AddIntConstant(m, langinfo_constants[i].name, + langinfo_constants[i].value); + } +#endif + + if (PyErr_Occurred()) { + Py_DECREF(m); + return NULL; + } + return m; +} + +/* +Local variables: +c-basic-offset: 4 +indent-tabs-mode: nil +End: +*/ diff --git a/python/Modules/_lsprof.c b/python/Modules/_lsprof.c new file mode 100755 index 0000000..c5a6f44 --- /dev/null +++ b/python/Modules/_lsprof.c @@ -0,0 +1,838 @@ +#include "Python.h" +#include "frameobject.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 */ + _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 { + _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) +#define PyProfiler_CheckExact(op) (Py_TYPE(op) == &PyProfiler_Type) + +/*** External Timers ***/ + +static _PyTime_t CallExternalTimer(ProfilerObject *pObj) +{ + PyObject *o = _PyObject_CallNoArg(pObj->externalTimer); + 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() */ + err = _PyTime_FromNanosecondsObject(&result, o); + } + 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 */ + err = _PyTime_FromSecondsObject(&result, o, _PyTime_ROUND_FLOOR); + } + Py_DECREF(o); + if (err < 0) { + PyErr_WriteUnraisable(pObj->externalTimer); + return 0; + } + return result; +} + +static inline _PyTime_t +call_timer(ProfilerObject *pObj) +{ + if (pObj->externalTimer != NULL) { + return CallExternalTimer(pObj); + } + else { + 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; + } + self->t0 = call_timer(pObj); +} + +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: + ptrace_enter_call(self, (void *)frame->f_code, + (PyObject *)frame->f_code); + break; + + /* the 'frame' of a called function is about to finish + (either normally or with an exception) */ + case PyTrace_RETURN: + ptrace_leave_call(self, (void *)frame->f_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; + if (pending_exception(pObj)) + 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; + if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) + return NULL; + PyEval_SetProfile(profiler_callback, (PyObject*)self); + 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; + PyEval_SetProfile(NULL, NULL); + 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) +{ + if (op->flags & POF_ENABLED) + PyEval_SetProfile(NULL, NULL); + 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 */ + 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, /* 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/python/Modules/_lzmamodule.c b/python/Modules/_lzmamodule.c new file mode 100755 index 0000000..27e9a91 --- /dev/null +++ b/python/Modules/_lzmamodule.c @@ -0,0 +1,1504 @@ +// /* _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" +// #include "pythread.h" + +// #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_Malloc(sizeof *options); +// if (options == NULL) +// return PyErr_NoMemory(); +// memset(options, 0, sizeof *options); + +// 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_Malloc(sizeof *options); +// if (options == NULL) +// return PyErr_NoMemory(); +// memset(options, 0, sizeof *options); +// 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_Malloc(sizeof *options); +// if (options == NULL) +// return PyErr_NoMemory(); +// memset(options, 0, sizeof *options); +// 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 (PyType_Ready(&Compressor_type) == -1) +// return NULL; +// Py_INCREF(&Compressor_type); +// if (PyModule_AddObject(m, "LZMACompressor", +// (PyObject *)&Compressor_type) == -1) +// return NULL; + +// if (PyType_Ready(&Decompressor_type) == -1) +// return NULL; +// Py_INCREF(&Decompressor_type); +// if (PyModule_AddObject(m, "LZMADecompressor", +// (PyObject *)&Decompressor_type) == -1) +// return NULL; + +// return m; +// } diff --git a/python/Modules/_math.c b/python/Modules/_math.c new file mode 100755 index 0000000..02d8f1c --- /dev/null +++ b/python/Modules/_math.c @@ -0,0 +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, + * := 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 */ +} + diff --git a/python/Modules/_math.h b/python/Modules/_math.h new file mode 100755 index 0000000..398b7e8 --- /dev/null +++ b/python/Modules/_math.h @@ -0,0 +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 diff --git a/python/Modules/_multiprocessing/clinic/posixshmem.c.h b/python/Modules/_multiprocessing/clinic/posixshmem.c.h new file mode 100755 index 0000000..a99f0d2 --- /dev/null +++ b/python/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -0,0 +1,133 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(HAVE_SHM_OPEN) + +PyDoc_STRVAR(_posixshmem_shm_open__doc__, +"shm_open($module, /, path, flags, mode=511)\n" +"--\n" +"\n" +"Open a shared memory object. Returns a file descriptor (integer)."); + +#define _POSIXSHMEM_SHM_OPEN_METHODDEF \ + {"shm_open", (PyCFunction)(void(*)(void))_posixshmem_shm_open, METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_open__doc__}, + +static int +_posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags, + int mode); + +static PyObject * +_posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "flags", "mode", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "shm_open", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *path; + int flags; + int mode = 511; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("shm_open", "argument 'path'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + path = args[0]; + 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 (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; + } +skip_optional_pos: + _return_value = _posixshmem_shm_open_impl(module, path, flags, mode); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SHM_OPEN) */ + +#if defined(HAVE_SHM_UNLINK) + +PyDoc_STRVAR(_posixshmem_shm_unlink__doc__, +"shm_unlink($module, /, path)\n" +"--\n" +"\n" +"Remove a shared memory object (similar to unlink()).\n" +"\n" +"Remove a shared memory object name, and, once all processes have unmapped\n" +"the object, de-allocates and destroys the contents of the associated memory\n" +"region."); + +#define _POSIXSHMEM_SHM_UNLINK_METHODDEF \ + {"shm_unlink", (PyCFunction)(void(*)(void))_posixshmem_shm_unlink, METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_unlink__doc__}, + +static PyObject * +_posixshmem_shm_unlink_impl(PyObject *module, PyObject *path); + +static PyObject * +_posixshmem_shm_unlink(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, "shm_unlink", 0}; + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("shm_unlink", "argument 'path'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + path = args[0]; + return_value = _posixshmem_shm_unlink_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SHM_UNLINK) */ + +#ifndef _POSIXSHMEM_SHM_OPEN_METHODDEF + #define _POSIXSHMEM_SHM_OPEN_METHODDEF +#endif /* !defined(_POSIXSHMEM_SHM_OPEN_METHODDEF) */ + +#ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF + #define _POSIXSHMEM_SHM_UNLINK_METHODDEF +#endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ +/*[clinic end generated code: output=9132861c61d8c2d8 input=a9049054013a1b77]*/ diff --git a/python/Modules/_multiprocessing/multiprocessing.c b/python/Modules/_multiprocessing/multiprocessing.c new file mode 100755 index 0000000..806e638 --- /dev/null +++ b/python/Modules/_multiprocessing/multiprocessing.c @@ -0,0 +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; +} diff --git a/python/Modules/_multiprocessing/multiprocessing.h b/python/Modules/_multiprocessing/multiprocessing.h new file mode 100755 index 0000000..512bc17 --- /dev/null +++ b/python/Modules/_multiprocessing/multiprocessing.h @@ -0,0 +1,103 @@ +#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 +# define HANDLE int +# define SOCKET int +# define BOOL int +# define UINT32 uint32_t +# define INT32 int32_t +# define TRUE 1 +# define FALSE 0 +# define INVALID_HANDLE_VALUE (-1) +#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 +# define F_DWORD "k" +# define T_DWORD T_ULONG +#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/python/Modules/_multiprocessing/posixshmem.c b/python/Modules/_multiprocessing/posixshmem.c new file mode 100755 index 0000000..2049dbb --- /dev/null +++ b/python/Modules/_multiprocessing/posixshmem.c @@ -0,0 +1,131 @@ +/* +posixshmem - A Python extension that provides shm_open() and shm_unlink() +*/ + +#define PY_SSIZE_T_CLEAN + +#include +#include "structmember.h" + +// for shm_open() and shm_unlink() +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +/*[clinic input] +module _posixshmem +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a416734e49164bf8]*/ + +/* + * + * Module-level functions & meta stuff + * + */ + +#ifdef HAVE_SHM_OPEN +/*[clinic input] +_posixshmem.shm_open -> int + path: unicode + flags: int + mode: int = 0o777 + +# "shm_open(path, flags, mode=0o777)\n\n\ + +Open a shared memory object. Returns a file descriptor (integer). + +[clinic start generated code]*/ + +static int +_posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags, + int mode) +/*[clinic end generated code: output=8d110171a4fa20df input=e83b58fa802fac25]*/ +{ + int fd; + int async_err = 0; + const char *name = PyUnicode_AsUTF8(path); + if (name == NULL) { + return -1; + } + do { + Py_BEGIN_ALLOW_THREADS + fd = shm_open(name, flags, mode); + Py_END_ALLOW_THREADS + } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (fd < 0) { + if (!async_err) + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); + return -1; + } + + return fd; +} +#endif /* HAVE_SHM_OPEN */ + +#ifdef HAVE_SHM_UNLINK +/*[clinic input] +_posixshmem.shm_unlink + path: unicode + +Remove a shared memory object (similar to unlink()). + +Remove a shared memory object name, and, once all processes have unmapped +the object, de-allocates and destroys the contents of the associated memory +region. + +[clinic start generated code]*/ + +static PyObject * +_posixshmem_shm_unlink_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=42f8b23d134b9ff5 input=8dc0f87143e3b300]*/ +{ + int rv; + int async_err = 0; + const char *name = PyUnicode_AsUTF8(path); + if (name == NULL) { + return NULL; + } + do { + Py_BEGIN_ALLOW_THREADS + rv = shm_unlink(name); + Py_END_ALLOW_THREADS + } while (rv < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (rv < 0) { + if (!async_err) + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); + return NULL; + } + + Py_RETURN_NONE; +} +#endif /* HAVE_SHM_UNLINK */ + +#include "clinic/posixshmem.c.h" + +static PyMethodDef module_methods[ ] = { + _POSIXSHMEM_SHM_OPEN_METHODDEF + _POSIXSHMEM_SHM_UNLINK_METHODDEF + {NULL} /* Sentinel */ +}; + + +static struct PyModuleDef this_module = { + PyModuleDef_HEAD_INIT, // m_base + "_posixshmem", // m_name + "POSIX shared memory module", // m_doc + -1, // m_size (space allocated for module globals) + module_methods, // m_methods +}; + +/* Module init function */ +PyMODINIT_FUNC +PyInit__posixshmem(void) { + PyObject *module; + module = PyModule_Create(&this_module); + if (!module) { + return NULL; + } + return module; +} diff --git a/python/Modules/_multiprocessing/semaphore.c b/python/Modules/_multiprocessing/semaphore.c new file mode 100755 index 0000000..4be2dea --- /dev/null +++ b/python/Modules/_multiprocessing/semaphore.c @@ -0,0 +1,689 @@ +/* + * 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; + double timeout; + PyObject *timeout_obj = Py_None; + struct timespec deadline = {0}; + struct timeval now; + long sec, nsec; + + 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; + } + + if (timeout_obj != Py_None) { + timeout = PyFloat_AsDouble(timeout_obj); + if (PyErr_Occurred()) + return NULL; + if (timeout < 0.0) + timeout = 0.0; + + if (gettimeofday(&now, NULL) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + sec = (long) timeout; + 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 + if (timeout_obj == Py_None) { + 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 * +semlock_ismine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + /* 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 * +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 * +semlock_afterfork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) +{ + 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"}, + {"__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, + /* 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 */ 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/python/Modules/_opcode.c b/python/Modules/_opcode.c new file mode 100755 index 0000000..42a8732 --- /dev/null +++ b/python/Modules/_opcode.c @@ -0,0 +1,96 @@ +#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 +_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 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 (jump == Py_None) { + jump_int = -1; + } + else if (jump == Py_True) { + jump_int = 1; + } + else if (jump == Py_False) { + jump_int = 0; + } + else { + PyErr_SetString(PyExc_ValueError, + "stack_effect: jump must be False, True or None"); + 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); +} diff --git a/python/Modules/_operator.c b/python/Modules/_operator.c new file mode 100755 index 0000000..a816548 --- /dev/null +++ b/python/Modules/_operator.c @@ -0,0 +1,1789 @@ + +#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 times b occurs in a. +[clinic start generated code]*/ + +static Py_ssize_t +_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=9e1623197daf3382 input=0c3a2656add252db]*/ +{ + 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); +} + +/*[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; + 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; + ig->index = -1; + if (PyLong_CheckExact(item)) { + index = PyLong_AsSsize_t(item); + if (index < 0) { + /* If we get here, then either the index conversion failed + * due to being out of range, or the index was a negative + * integer. Either way, we clear any possible exception + * and fall back to the slow path, where ig->index is -1. + */ + PyErr_Clear(); + } + else { + 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; + + assert(PyTuple_CheckExact(args)); + if (!_PyArg_NoKeywords("itemgetter", kw)) + return NULL; + if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1)) + return NULL; + + obj = PyTuple_GET_ITEM(args, 0); + if (nitems == 1) { + if (ig->index >= 0 + && PyTuple_CheckExact(obj) + && ig->index < PyTuple_GET_SIZE(obj)) + { + result = PyTuple_GET_ITEM(obj, ig->index); + 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 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 */ + 0, /* tp_vectorcall_offset */ + 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; + 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; + if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1)) + 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 * +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 */ + 0, /* tp_vectorcall_offset */ + 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; + if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1)) + 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 * +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; + constructor = _PyObject_FastCallDict(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 */ + 0, /* tp_vectorcall_offset */ + 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 */ +}; + + +/* Initialization function for the module (*must* be called PyInit__operator) */ + + +static struct PyModuleDef operatormodule = { + PyModuleDef_HEAD_INIT, + "_operator", + operator_doc, + -1, + operator_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__operator(void) +{ + PyObject *m; + + /* Create the module and add the functions */ + m = PyModule_Create(&operatormodule); + if (m == NULL) + return NULL; + + if (PyType_Ready(&itemgetter_type) < 0) + return NULL; + Py_INCREF(&itemgetter_type); + PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type); + + if (PyType_Ready(&attrgetter_type) < 0) + return NULL; + Py_INCREF(&attrgetter_type); + PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type); + + if (PyType_Ready(&methodcaller_type) < 0) + return NULL; + Py_INCREF(&methodcaller_type); + PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type); + return m; +} diff --git a/python/Modules/_pickle.c b/python/Modules/_pickle.c new file mode 100755 index 0000000..42ce62f --- /dev/null +++ b/python/Modules/_pickle.c @@ -0,0 +1,8062 @@ +/* pickle accelerator C extensor: _pickle module. + * + * 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" +#include "structmember.h" + +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 { + 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', + FLOAT = 'F', + INT = 'I', + 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', + 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); +} + +/* 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_CallFunctionObjArgs(func, obj, NULL); + 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_CallFunctionObjArgs(func, obj, NULL); + } +} + +/*************************************************************************/ + +/* 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_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_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; + } + 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; + 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_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_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_CallNoArg(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", + obj->ob_type->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_CallFunctionObjArgs(self->write, payload, NULL); + 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_CallFunctionObjArgs(self->buffer_callback, + obj, NULL); + 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; + 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_CallMethodId(obj, &PyId_items, NULL); + 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_CallFunctionObjArgs(self->reducer_override, + obj, NULL); + 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_CallNoArg(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 wont 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_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_CallMethodIdObjArgs(cls, &PyId___new__, cls, NULL); + } + 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_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()) + PyErr_SetObject(PyExc_KeyError, key); + 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) { + PyErr_SetObject(PyExc_KeyError, key); + 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) { + PyErr_SetObject(PyExc_KeyError, key); + 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_SIZE(self->stack) = x; + Py_DECREF(append_func); + return -1; + } + Py_DECREF(result); + } + Py_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(); + /* Currupt 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_SIZE(self->stack) = mark; + return -1; + } + Py_DECREF(result); + } + Py_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; + } + + /* 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; + + 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_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_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 + protocol: object = None + * + 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 +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. 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, + 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; + + 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 + protocol: object = None + * + 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 +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. + +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, + 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; + + 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' + 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, + 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; + + 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 + * + 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, + const char *encoding, const char *errors, + PyObject *buffers) +/*[clinic end generated code: output=82ac1e6b588e6d02 input=9c2ab6a0960185ea]*/ +{ + 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); + 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(&Unpickler_Type) < 0) + return NULL; + if (PyType_Ready(&Pickler_Type) < 0) + return NULL; + 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 */ + Py_INCREF(&Pickler_Type); + if (PyModule_AddObject(m, "Pickler", (PyObject *)&Pickler_Type) < 0) + return NULL; + Py_INCREF(&Unpickler_Type); + if (PyModule_AddObject(m, "Unpickler", (PyObject *)&Unpickler_Type) < 0) + return NULL; + Py_INCREF(&PyPickleBuffer_Type); + if (PyModule_AddObject(m, "PickleBuffer", + (PyObject *)&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; +} diff --git a/python/Modules/_posixsubprocess.c b/python/Modules/_posixsubprocess.c new file mode 100755 index 0000000..05c051c --- /dev/null +++ b/python/Modules/_posixsubprocess.c @@ -0,0 +1,813 @@ +/* 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) && defined(__FreeBSD__) +#include +#endif +#ifdef HAVE_SYS_SYSCALL_H +#include +#endif +#if defined(HAVE_SYS_RESOURCE_H) +#include +#endif +#ifdef HAVE_DIRENT_H +#include +#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 POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0) + + +/* 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; + _Py_IDENTIFIER(enable); + PyObject *exctype, *val, *tb; + + if (need_to_reenable_gc) { + PyErr_Fetch(&exctype, &val, &tb); + result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL); + 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 + * 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) { + for (fd_num = start_fd; fd_num < end_fd; ++fd_num) { + close(fd_num); + } + } +} + + +#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, + 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 (restore_signals) + _Py_RestoreSignals(); + +#ifdef HAVE_SETSID + if (call_setsid) + POSIX_CALL(setsid()); +#endif + + 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; + int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite; + int errpipe_read, errpipe_write, close_fds, restore_signals; + int call_setsid; + PyObject *cwd_obj, *cwd_obj2; + 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; + int need_after_fork = 0; + int saved_errno = 0; + + if (!PyArg_ParseTuple( + args, "OOpO!OOiiiiiiiiiiO: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, + &restore_signals, &call_setsid, &preexec_fn)) + return NULL; + + if ((preexec_fn != Py_None) && + (_PyInterpreterState_Get() != PyInterpreterState_Main())) { + PyErr_SetString(PyExc_RuntimeError, + "preexec_fn not supported within subinterpreters"); + 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; + } + + /* We need to call gc.disable() when we'll be calling preexec_fn */ + if (preexec_fn != Py_None) { + PyObject *result; + _Py_IDENTIFIER(isenabled); + _Py_IDENTIFIER(disable); + + gc_module = PyImport_ImportModule("gc"); + if (gc_module == NULL) + return NULL; + result = _PyObject_CallMethodId(gc_module, &PyId_isenabled, 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_CallMethodId(gc_module, &PyId_disable, 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; + cwd_obj2 = NULL; + } + + /* 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, + 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_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: + if (envp) + _Py_FreeCharPArray(envp); + if (argv) + _Py_FreeCharPArray(argv); + if (exec_array) + _Py_FreeCharPArray(exec_array); + 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, cwd, env,\n\ + p2cread, p2cwrite, c2pread, c2pwrite,\n\ + errread, errwrite, errpipe_read, errpipe_write,\n\ + restore_signals, call_setsid, 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\ +The preexec_fn, if supplied, will be called immediately before 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 */ +}; + + +static struct PyModuleDef _posixsubprocessmodule = { + PyModuleDef_HEAD_INIT, + "_posixsubprocess", + module_doc, + -1, /* No memory is needed. */ + module_methods, +}; + +PyMODINIT_FUNC +PyInit__posixsubprocess(void) +{ + return PyModule_Create(&_posixsubprocessmodule); +} diff --git a/python/Modules/_queuemodule.c b/python/Modules/_queuemodule.c new file mode 100755 index 0000000..e033da5 --- /dev/null +++ b/python/Modules/_queuemodule.c @@ -0,0 +1,400 @@ +#include "Python.h" +#include "structmember.h" /* offsetof */ +#include "pythread.h" + +/*[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 + {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_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; + + if (PyType_Ready(&PySimpleQueueType) < 0) + return NULL; + Py_INCREF(&PySimpleQueueType); + if (PyModule_AddObject(m, "SimpleQueue", (PyObject *)&PySimpleQueueType) < 0) + return NULL; + + return m; +} diff --git a/python/Modules/_randommodule.c b/python/Modules/_randommodule.c new file mode 100755 index 0000000..4e9ac40 --- /dev/null +++ b/python/Modules/_randommodule.c @@ -0,0 +1,603 @@ +/* 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_int32() 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" +#include /* for seeding to current time */ +#ifdef HAVE_PROCESS_H +# include /* needed for 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 { + PyObject_HEAD + int index; + uint32_t state[N]; +} RandomObject; + +static PyTypeObject Random_Type; + +#define RandomObject_Check(v) (Py_TYPE(v) == &Random_Type) + +#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 +genrand_int32(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. + */ + +/*[clinic input] +_random.Random.random + + self: self(type="RandomObject *") + +random() -> x in the interval [0, 1). +[clinic start generated code]*/ + +static PyObject * +_random_Random_random_impl(RandomObject *self) +/*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/ +{ + uint32_t a=genrand_int32(self)>>5, b=genrand_int32(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) +{ + PY_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(); + key[0] = (PY_UINT32_T)(now & 0xffffffffU); + key[1] = (PY_UINT32_T)(now >> 32); + + key[2] = (PY_UINT32_T)getpid(); + + now = _PyTime_GetMonotonicClock(); + key[3] = (PY_UINT32_T)(now & 0xffffffffU); + key[4] = (PY_UINT32_T)(now >> 32); + + 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; + + 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. + */ + if (PyLong_Check(arg)) { + /* Calling int.__abs__() prevents calling arg.__abs__(), which might + return an invalid value. See issue #31478. */ + n = PyLong_Type.tp_as_number->nb_absolute(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; +} + +/*[clinic input] +_random.Random.seed + + self: self(type="RandomObject *") + n: object = None + / + +seed([n]) -> None. + +Defaults to use urandom and falls back to a combination +of the current time and the process identifier. +[clinic start generated code]*/ + +static PyObject * +_random_Random_seed_impl(RandomObject *self, PyObject *n) +/*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/ +{ + return random_seed(self, n); +} + +/*[clinic input] +_random.Random.getstate + + self: self(type="RandomObject *") + +getstate() -> tuple containing the current state. +[clinic start generated code]*/ + +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; +} + + +/*[clinic input] +_random.Random.setstate + + self: self(type="RandomObject *") + state: object + / + +setstate(state) -> None. Restores generator state. +[clinic start generated code]*/ + +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; +} + +/*[clinic input] + +_random.Random.getrandbits + + self: self(type="RandomObject *") + k: int + / + +getrandbits(k) -> x. Generates an int with k random bits. +[clinic start generated code]*/ + +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; + + if (k <= 0) { + PyErr_SetString(PyExc_ValueError, + "number of bits must be greater than zero"); + return NULL; + } + + if (k <= 32) /* Fast path */ + return PyLong_FromUnsignedLong(genrand_int32(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 + { + r = genrand_int32(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 (type == &Random_Type && !_PyArg_NoKeywords("Random", kwds)) + return NULL; + + self = (RandomObject *)type->tp_alloc(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[] = { + _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."); + +static PyTypeObject Random_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_random.Random", /*tp_name*/ + sizeof(RandomObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + 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*/ + random_doc, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + random_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*/ + random_new, /*tp_new*/ + PyObject_Free, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +PyDoc_STRVAR(module_doc, +"Module implements the Mersenne Twister random number generator."); + + +static struct PyModuleDef _randommodule = { + PyModuleDef_HEAD_INIT, + "_random", + module_doc, + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__random(void) +{ + PyObject *m; + + if (PyType_Ready(&Random_Type) < 0) + return NULL; + m = PyModule_Create(&_randommodule); + if (m == NULL) + return NULL; + Py_INCREF(&Random_Type); + PyModule_AddObject(m, "Random", (PyObject *)&Random_Type); + return m; +} diff --git a/python/Modules/_scproxy.c b/python/Modules/_scproxy.c new file mode 100755 index 0000000..9b6b2d6 --- /dev/null +++ b/python/Modules/_scproxy.c @@ -0,0 +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* +// 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* +// 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", +// get_proxy_settings, +// 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 + diff --git a/python/Modules/_sha3/README.txt b/python/Modules/_sha3/README.txt new file mode 100755 index 0000000..e34b1d1 --- /dev/null +++ b/python/Modules/_sha3/README.txt @@ -0,0 +1,11 @@ +Keccak Code Package +=================== + +The files in kcp are taken from the Keccak Code Package. They have been +slightly to be C89 compatible. The architecture specific header file +KeccakP-1600-SnP.h ha been renamed to KeccakP-1600-SnP-opt32.h or +KeccakP-1600-SnP-opt64.h. + +The 64bit files were generated with generic64lc/libkeccak.a.pack target, the +32bit files with generic32lc/libkeccak.a.pack. + diff --git a/python/Modules/_sha3/cleanup.py b/python/Modules/_sha3/cleanup.py new file mode 100755 index 0000000..4f53681 --- /dev/null +++ b/python/Modules/_sha3/cleanup.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# Copyright (C) 2012 Christian Heimes (christian@python.org) +# Licensed to PSF under a Contributor Agreement. +# +# cleanup Keccak sources + +import os +import re + +CPP1 = re.compile("^//(.*)") +CPP2 = re.compile(r"\ //(.*)") + +STATICS = ("void ", "int ", "HashReturn ", + "const UINT64 ", "UINT16 ", " int prefix##") + +HERE = os.path.dirname(os.path.abspath(__file__)) +KECCAK = os.path.join(HERE, "kcp") + +def getfiles(): + for name in os.listdir(KECCAK): + name = os.path.join(KECCAK, name) + if os.path.isfile(name): + yield name + +def cleanup(f): + buf = [] + for line in f: + # mark all functions and global data as static + #if line.startswith(STATICS): + # buf.append("static " + line) + # continue + # remove UINT64 typedef, we have our own + if line.startswith("typedef unsigned long long int"): + buf.append("/* %s */\n" % line.strip()) + continue + ## remove #include "brg_endian.h" + if "brg_endian.h" in line: + buf.append("/* %s */\n" % line.strip()) + continue + # transform C++ comments into ANSI C comments + line = CPP1.sub(r"/*\1 */\n", line) + line = CPP2.sub(r" /*\1 */\n", line) + buf.append(line) + return "".join(buf) + +for name in getfiles(): + with open(name) as f: + res = cleanup(f) + with open(name, "w") as f: + f.write(res) diff --git a/python/Modules/_sha3/clinic/sha3module.c.h b/python/Modules/_sha3/clinic/sha3module.c.h new file mode 100755 index 0000000..554442d --- /dev/null +++ b/python/Modules/_sha3/clinic/sha3module.c.h @@ -0,0 +1,121 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +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); + +static PyObject * +_sha3_shake_128_digest(SHA3object *self, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned long length; + + if (!_PyLong_UnsignedLong_Converter(arg, &length)) { + goto exit; + } + return_value = _sha3_shake_128_digest_impl(self, length); + +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__}, + +static PyObject * +_sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length); + +static PyObject * +_sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned long length; + + if (!_PyLong_UnsignedLong_Converter(arg, &length)) { + goto exit; + } + return_value = _sha3_shake_128_hexdigest_impl(self, length); + +exit: + return return_value; +} +/*[clinic end generated code: output=5b3e99b9a96471e8 input=a9049054013a1b77]*/ diff --git a/python/Modules/_sha3/kcp/KeccakHash.c b/python/Modules/_sha3/kcp/KeccakHash.c new file mode 100755 index 0000000..e09fb43 --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakHash.c @@ -0,0 +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); +} diff --git a/python/Modules/_sha3/kcp/KeccakHash.h b/python/Modules/_sha3/kcp/KeccakHash.h new file mode 100755 index 0000000..bbd3dc6 --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakHash.h @@ -0,0 +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 diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-64.macros b/python/Modules/_sha3/kcp/KeccakP-1600-64.macros new file mode 100755 index 0000000..1f11fe3 --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-64.macros @@ -0,0 +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) \ + } \ + } \ + } diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h b/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h new file mode 100755 index 0000000..6cf765e --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h @@ -0,0 +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 diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h b/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h new file mode 100755 index 0000000..889a31a --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h @@ -0,0 +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 diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-SnP.h b/python/Modules/_sha3/kcp/KeccakP-1600-SnP.h new file mode 100755 index 0000000..0b23f09 --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-SnP.h @@ -0,0 +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 diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c b/python/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c new file mode 100755 index 0000000..a2f9ffe --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c @@ -0,0 +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); +} diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h b/python/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h new file mode 100755 index 0000000..9501c64 --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h @@ -0,0 +1,3 @@ +#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled" +#define KeccakP1600_fullUnrolling +#define KeccakP1600_useLaneComplementing diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-opt64.c b/python/Modules/_sha3/kcp/KeccakP-1600-opt64.c new file mode 100755 index 0000000..c90010d --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-opt64.c @@ -0,0 +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; +} diff --git a/python/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros b/python/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros new file mode 100755 index 0000000..405ce29 --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros @@ -0,0 +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 diff --git a/python/Modules/_sha3/kcp/KeccakSponge.c b/python/Modules/_sha3/kcp/KeccakSponge.c new file mode 100755 index 0000000..afdb731 --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakSponge.c @@ -0,0 +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" +#endif + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #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" + + #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" + + #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/python/Modules/_sha3/kcp/KeccakSponge.h b/python/Modules/_sha3/kcp/KeccakSponge.h new file mode 100755 index 0000000..0f4badc --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakSponge.h @@ -0,0 +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" + KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth200) +#endif + +#ifndef KeccakP400_excluded + #include "KeccakP-400-SnP.h" + KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth400) +#endif + +#ifndef KeccakP800_excluded + #include "KeccakP-800-SnP.h" + 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/python/Modules/_sha3/kcp/KeccakSponge.inc b/python/Modules/_sha3/kcp/KeccakSponge.inc new file mode 100755 index 0000000..e10739d --- /dev/null +++ b/python/Modules/_sha3/kcp/KeccakSponge.inc @@ -0,0 +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 diff --git a/python/Modules/_sha3/kcp/PlSnP-Fallback.inc b/python/Modules/_sha3/kcp/PlSnP-Fallback.inc new file mode 100755 index 0000000..3a9119a --- /dev/null +++ b/python/Modules/_sha3/kcp/PlSnP-Fallback.inc @@ -0,0 +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 diff --git a/python/Modules/_sha3/kcp/align.h b/python/Modules/_sha3/kcp/align.h new file mode 100755 index 0000000..6650fe8 --- /dev/null +++ b/python/Modules/_sha3/kcp/align.h @@ -0,0 +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 diff --git a/python/Modules/_sha3/sha3module.c b/python/Modules/_sha3/sha3module.c new file mode 100755 index 0000000..c1fb618 --- /dev/null +++ b/python/Modules/_sha3/sha3module.c @@ -0,0 +1,750 @@ +/* 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 && defined(PY_UINT64_T) + /* 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 && defined(PY_UINT64_T) + /* 64bit platforms with unsigned int64 */ + typedef PY_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 + +/* 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; +} + + +static PyObject * +py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + SHA3object *self = NULL; + Py_buffer buf = {NULL, NULL}; + HashReturn res; + PyObject *data = NULL; + + if (!_PyArg_NoKeywords(_PyType_Name(type), kwargs)) { + return NULL; + } + if (!PyArg_UnpackTuple(args, _PyType_Name(type), 0, 1, &data)) { + return NULL; + } + + 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_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__, +"sha3_224([data]) -> SHA3 object\n\ +\n\ +Return a new SHA3 hash object with a hashbit length of 28 bytes."); + +PyDoc_STRVAR(sha3_256__doc__, +"sha3_256([data]) -> SHA3 object\n\ +\n\ +Return a new SHA3 hash object with a hashbit length of 32 bytes."); + +PyDoc_STRVAR(sha3_384__doc__, +"sha3_384([data]) -> SHA3 object\n\ +\n\ +Return a new SHA3 hash object with a hashbit length of 48 bytes."); + +PyDoc_STRVAR(sha3_512__doc__, +"sha3_512([data]) -> 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__, +"keccak_224([data]) -> Keccak object\n\ +\n\ +Return a new Keccak hash object with a hashbit length of 28 bytes."); + +PyDoc_STRVAR(keccak_256__doc__, +"keccak_256([data]) -> Keccak object\n\ +\n\ +Return a new Keccak hash object with a hashbit length of 32 bytes."); + +PyDoc_STRVAR(keccak_384__doc__, +"keccak_384([data]) -> Keccak object\n\ +\n\ +Return a new Keccak hash object with a hashbit length of 48 bytes."); + +PyDoc_STRVAR(keccak_512__doc__, +"keccak_512([data]) -> 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 * +_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 + + length: unsigned_long + / + +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 + + length: unsigned_long + / + +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__, +"shake_128([data]) -> SHAKE object\n\ +\n\ +Return a new SHAKE hash object."); + +PyDoc_STRVAR(shake_256__doc__, +"shake_256([data]) -> 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 { \ + Py_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; +} diff --git a/python/Modules/_sqlite/cache.c b/python/Modules/_sqlite/cache.c new file mode 100755 index 0000000..4d41804 --- /dev/null +++ b/python/Modules/_sqlite/cache.c @@ -0,0 +1,360 @@ +/* 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* args) +{ + PyObject* key = args; + 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; + } + } + 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); + } + } + + 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_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_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, /* 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/python/Modules/_sqlite/cache.h b/python/Modules/_sqlite/cache.h new file mode 100755 index 0000000..5290109 --- /dev/null +++ b/python/Modules/_sqlite/cache.h @@ -0,0 +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 +#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 diff --git a/python/Modules/_sqlite/connection.c b/python/Modules/_sqlite/connection.c new file mode 100755 index 0000000..d1d5f9f --- /dev/null +++ b/python/Modules/_sqlite/connection.c @@ -0,0 +1,1896 @@ +/* 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" +#include "connection.h" +#include "statement.h" +#include "cursor.h" +#include "prepare_protocol.h" +#include "util.h" + +#include "pythread.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 + }; + + 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; + } + + if (PySys_Audit("sqlite3.connect", "O", database_obj) < 0) { + return -1; + } + + database = PyBytes_AsString(database_obj); + + self->initialized = 1; + + 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 (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; + + 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; + + 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; + } + + cursor = PyObject_CallFunctionObjArgs(factory, (PyObject *)self, 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; + } + + 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)) { + const char *str = PyUnicode_AsUTF8(py_val); + if (str == NULL) + return -1; + sqlite3_result_text(context, str, -1, 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; + const char* val_str; + 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 = _pysqlite_long_from_int64(sqlite3_value_int64(cur_value)); + break; + case SQLITE_FLOAT: + cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value)); + break; + case SQLITE_TEXT: + val_str = (const char*)sqlite3_value_text(cur_value); + cur_py_value = PyUnicode_FromString(val_str); + /* TODO: have a way to show errors here */ + if (!cur_py_value) { + PyErr_Clear(); + Py_INCREF(Py_None); + cur_py_value = Py_None; + } + 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) { + Py_DECREF(args); + return NULL; + } + + PyTuple_SetItem(args, i, cur_py_value); + + } + + return args; +} + +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_CallMethodId(*aggregate_instance, &PyId_finalize, NULL); + + 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) +{ + static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; + + 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 (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|$p", kwlist, + &name, &narg, &func, &deterministic)) + { + return NULL; + } + + if (deterministic) { +#if SQLITE_VERSION_NUMBER < 3008003 + PyErr_SetString(pysqlite_NotSupportedError, + "deterministic=True requires SQLite 3.8.3 or higher"); + 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_CallFunctionObjArgs((PyObject*)user_arg, py_statement, NULL); + 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) +{ + 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) { + PyObject *res = pysqlite_connection_commit(self, NULL); + if (!res) { + return -1; + } + Py_DECREF(res); + + 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_CallMethodIdObjArgs( + (PyObject *)&PyUnicode_Type, &PyId_upper, + isolation_level, 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, "O", &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; + + cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, NULL); + 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_CallMethodId((PyObject*)self, &PyId_cursor, NULL); + 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_CallMethodId((PyObject*)self, &PyId_cursor, NULL); + 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; + } + + pyfn_iterdump = _PyDict_GetItemIdWithError(module_dict, &PyId__iterdump); + if (!pyfn_iterdump) { + if (!PyErr_Occurred()) { + PyErr_SetString(pysqlite_OperationalError, + "Failed to obtain _iterdump() reference"); + } + goto finally; + } + + args = PyTuple_New(1); + if (!args) { + goto finally; + } + Py_INCREF(self); + PyTuple_SetItem(args, 0, (PyObject*)self); + retval = PyObject_CallObject(pyfn_iterdump, args); + +finally: + Py_XDECREF(args); + 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}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, + &pysqlite_ConnectionType, &target, + &pages, &progress, &name, &sleep_obj)) { + return NULL; + } + + if (sleep_obj != NULL) { + _PyTime_t sleep_secs; + if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj, + _PyTime_ROUND_TIMEOUT)) { + return NULL; + } + _PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs, + _PyTime_ROUND_TIMEOUT); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "sleep is too large"); + return NULL; + } + sleep_ms = (int)ms; + } + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + 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 + 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; + 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; + } + + uppercase_name = _PyObject_CallMethodIdObjArgs((PyObject *)&PyUnicode_Type, + &PyId_upper, name, NULL); + 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) { + PyDict_DelItem(self->collations, uppercase_name); + _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; + const char* method_name; + PyObject* result; + + if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &exc_tb)) { + return NULL; + } + + if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) { + method_name = "commit"; + } else { + method_name = "rollback"; + } + + result = PyObject_CallMethod((PyObject*)self, method_name, NULL); + if (!result) { + 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.")}, + {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS, + 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.")}, + {"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 + {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS, + 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 + {"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 */ + 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 */ + (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/python/Modules/_sqlite/connection.h b/python/Modules/_sqlite/connection.h new file mode 100755 index 0000000..206085e --- /dev/null +++ b/python/Modules/_sqlite/connection.h @@ -0,0 +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 +#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; + + /* 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 diff --git a/python/Modules/_sqlite/cursor.c b/python/Modules/_sqlite/cursor.c new file mode 100755 index 0000000..8cfa6e5 --- /dev/null +++ b/python/Modules/_sqlite/cursor.c @@ -0,0 +1,980 @@ +/* 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); +} + +static PyObject * +_pysqlite_get_converter(const char *keystr, Py_ssize_t keylen) +{ + PyObject *key; + PyObject *upcase_key; + PyObject *retval; + _Py_IDENTIFIER(upper); + + key = PyUnicode_FromStringAndSize(keystr, keylen); + if (!key) { + return NULL; + } + upcase_key = _PyObject_CallMethodId(key, &PyId_upper, NULL); + Py_DECREF(key); + if (!upcase_key) { + return NULL; + } + + retval = PyDict_GetItemWithError(_pysqlite_converters, upcase_key); + 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)); + 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) { + const char *type_start = NULL; + 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) { + 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; +} + +static PyObject * +_pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname) +{ + const char* pos; + Py_ssize_t len; + + if (!colname) { + Py_RETURN_NONE; + } + + if (self->connection->detect_types & PARSE_COLNAMES) { + for (pos = colname; *pos; pos++) { + if (*pos == '[') { + if ((pos != colname) && (*(pos-1) == ' ')) { + 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. + */ +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; + 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->connection->detect_types + && self->row_cast_map != NULL + && i < PyList_GET_SIZE(self->row_cast_map)) + { + 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; + converted = PyObject_CallFunction(converter, "O", 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) { + converted = _pysqlite_long_from_int64(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); + 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); + error_msg = PyUnicode_Decode(buf, strlen(buf), "ascii", "replace"); + if (!error_msg) { + 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); + converted = PyBytes_FromStringAndSize( + 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); +} + +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* 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() */ + if (!PyArg_ParseTuple(args, "OO", &operation, &second_argument)) { + goto error; + } + + if (!PyUnicode_Check(operation)) { + PyErr_SetString(PyExc_ValueError, "operation parameter must be str"); + 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, "O|O", &operation, &second_argument)) { + goto error; + } + + if (!PyUnicode_Check(operation)) { + PyErr_SetString(PyExc_ValueError, "operation parameter must be str"); + 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; + } + column_name = _pysqlite_build_column_name(self, + sqlite3_column_name(self->statement->st, i)); + if (!column_name) { + Py_DECREF(descriptor); + 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_DECREF(self->lastrowid); + Py_BEGIN_ALLOW_THREADS + lastrowid = sqlite3_last_insert_rowid(self->connection->db); + Py_END_ALLOW_THREADS + self->lastrowid = _pysqlite_long_from_int64(lastrowid); + } + + 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; + PyObject* script_str = NULL; + 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: + Py_XDECREF(script_str); + + 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, 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; + } + + /* just make sure we enter the loop */ + row = Py_None; + + while (row) { + row = pysqlite_cursor_iternext(self); + if (row) { + PyList_Append(list, row); + Py_DECREF(row); + } else { + break; + } + + 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; + } + + /* just make sure we enter the loop */ + row = (PyObject*)Py_None; + + while (row) { + row = pysqlite_cursor_iternext(self); + if (row) { + PyList_Append(list, row); + 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.")}, + {"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 */ + 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, /* 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); +} diff --git a/python/Modules/_sqlite/cursor.h b/python/Modules/_sqlite/cursor.h new file mode 100755 index 0000000..4a20e75 --- /dev/null +++ b/python/Modules/_sqlite/cursor.h @@ -0,0 +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 +#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 diff --git a/python/Modules/_sqlite/microprotocols.c b/python/Modules/_sqlite/microprotocols.c new file mode 100755 index 0000000..c23b09f --- /dev/null +++ b/python/Modules/_sqlite/microprotocols.c @@ -0,0 +1,160 @@ +/* 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 + +#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 */ + key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto); + if (!key) { + return NULL; + } + adapter = PyDict_GetItemWithError(psyco_adapters, key); + Py_DECREF(key); + if (adapter) { + Py_INCREF(adapter); + adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL); + Py_DECREF(adapter); + 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; + } + if (adapter) { + adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL); + 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 */ + if (_PyObject_LookupAttrId(obj, &PyId___conform__, &adapter) < 0) { + return NULL; + } + if (adapter) { + adapted = PyObject_CallFunctionObjArgs(adapter, proto, NULL); + 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); +} diff --git a/python/Modules/_sqlite/microprotocols.h b/python/Modules/_sqlite/microprotocols.h new file mode 100755 index 0000000..5418c2b --- /dev/null +++ b/python/Modules/_sqlite/microprotocols.h @@ -0,0 +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 + +#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) */ diff --git a/python/Modules/_sqlite/module.c b/python/Modules/_sqlite/module.c new file mode 100755 index 0000000..d3ce283 --- /dev/null +++ b/python/Modules/_sqlite/module.c @@ -0,0 +1,474 @@ +/* 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) +{ + static char *kwlist[] = {"statement", NULL, 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) +{ + static char *kwlist[] = {"do_enable", NULL, 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 */ + name = _PyObject_CallMethodId(orig_name, &PyId_upper, NULL); + 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}, + {"complete_statement", (PyCFunction)(void(*)(void))module_complete, + 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 +}; + +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; + } + + Py_INCREF(&pysqlite_ConnectionType); + PyModule_AddObject(module, "Connection", (PyObject*) &pysqlite_ConnectionType); + Py_INCREF(&pysqlite_CursorType); + PyModule_AddObject(module, "Cursor", (PyObject*) &pysqlite_CursorType); + Py_INCREF(&pysqlite_PrepareProtocolType); + PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &pysqlite_PrepareProtocolType); + Py_INCREF(&pysqlite_RowType); + PyModule_AddObject(module, "Row", (PyObject*) &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; +} diff --git a/python/Modules/_sqlite/module.h b/python/Modules/_sqlite/module.h new file mode 100755 index 0000000..3185ec9 --- /dev/null +++ b/python/Modules/_sqlite/module.h @@ -0,0 +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 +#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 diff --git a/python/Modules/_sqlite/prepare_protocol.c b/python/Modules/_sqlite/prepare_protocol.c new file mode 100755 index 0000000..181c7ed --- /dev/null +++ b/python/Modules/_sqlite/prepare_protocol.c @@ -0,0 +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 */ + 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 */ + 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_TYPE(&pysqlite_PrepareProtocolType)= &PyType_Type; + return PyType_Ready(&pysqlite_PrepareProtocolType); +} diff --git a/python/Modules/_sqlite/prepare_protocol.h b/python/Modules/_sqlite/prepare_protocol.h new file mode 100755 index 0000000..3998a55 --- /dev/null +++ b/python/Modules/_sqlite/prepare_protocol.h @@ -0,0 +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 +#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 diff --git a/python/Modules/_sqlite/row.c b/python/Modules/_sqlite/row.c new file mode 100755 index 0000000..4b47108 --- /dev/null +++ b/python/Modules/_sqlite/row.c @@ -0,0 +1,278 @@ +/* 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) +{ + int eq = PyObject_RichCompareBool(left, right, Py_EQ); + if (eq) { /* equal or error */ + return eq; + } + if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) { + return 0; + } + if (!PyUnicode_IS_ASCII(left) || !PyUnicode_IS_ASCII(right)) { + return 0; + } + + Py_ssize_t len = PyUnicode_GET_LENGTH(left); + if (PyUnicode_GET_LENGTH(right) != len) { + return 0; + } + const Py_UCS1 *p1 = PyUnicode_1BYTE_DATA(left); + const Py_UCS1 *p2 = PyUnicode_1BYTE_DATA(right); + for (; len; len--, p1++, p2++) { + if (Py_TOLOWER(*p1) != Py_TOLOWER(*p2)) { + return 0; + } + } + 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); + int eq = equal_ignore_case(idx, obj); + if (eq < 0) { + 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); +} + +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; + + if (PyObject_TypeCheck(_other, &pysqlite_RowType)) { + 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 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 */ + 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 */ + (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/python/Modules/_sqlite/row.h b/python/Modules/_sqlite/row.h new file mode 100755 index 0000000..4ad506f --- /dev/null +++ b/python/Modules/_sqlite/row.h @@ -0,0 +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 +#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 diff --git a/python/Modules/_sqlite/statement.c b/python/Modules/_sqlite/statement.c new file mode 100755 index 0000000..70fd95f --- /dev/null +++ b/python/Modules/_sqlite/statement.c @@ -0,0 +1,505 @@ +/* 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; + + 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); + Py_INCREF(current_param); + } 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 { + 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++) { + 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) */ + binding_name_obj = PyUnicode_FromString(binding_name); + if (!binding_name_obj) { + return; + } + if (PyDict_CheckExact(parameters)) { + current_param = PyDict_GetItemWithError(parameters, binding_name_obj); + Py_XINCREF(current_param); + } else { + current_param = PyObject_GetItem(parameters, binding_name_obj); + } + Py_DECREF(binding_name_obj); + 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 { + 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 */ + 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 */ + 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/python/Modules/_sqlite/statement.h b/python/Modules/_sqlite/statement.h new file mode 100755 index 0000000..5002f02 --- /dev/null +++ b/python/Modules/_sqlite/statement.h @@ -0,0 +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 +#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 diff --git a/python/Modules/_sqlite/util.c b/python/Modules/_sqlite/util.c new file mode 100755 index 0000000..3fa671d --- /dev/null +++ b/python/Modules/_sqlite/util.c @@ -0,0 +1,146 @@ +/* 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 + +PyObject * +_pysqlite_long_from_int64(sqlite_int64 value) +{ +# if SIZEOF_LONG_LONG < 8 + if (value > PY_LLONG_MAX || value < PY_LLONG_MIN) { + return _PyLong_FromByteArray(&value, sizeof(value), + IS_LITTLE_ENDIAN, 1 /* signed */); + } +# endif +# if SIZEOF_LONG < SIZEOF_LONG_LONG + if (value > LONG_MAX || value < LONG_MIN) + return PyLong_FromLongLong(value); +# endif + return PyLong_FromLong(Py_SAFE_DOWNCAST(value, sqlite_int64, long)); +} + +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/python/Modules/_sqlite/util.h b/python/Modules/_sqlite/util.h new file mode 100755 index 0000000..6261911 --- /dev/null +++ b/python/Modules/_sqlite/util.h @@ -0,0 +1,49 @@ +/* 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); + +PyObject * _pysqlite_long_from_int64(sqlite_int64 value); +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/python/Modules/_sre.c b/python/Modules/_sre.c new file mode 100755 index 0000000..d4fe588 --- /dev/null +++ b/python/Modules/_sre.c @@ -0,0 +1,2817 @@ +/* + * 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; reenable 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" /* offsetof */ + +#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 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; + void* ptr; + + memset(state, 0, sizeof(SRE_STATE)); + + state->mark = PyMem_New(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: + PyMem_Del(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); + PyMem_Del(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; + 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; + 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); + b = charsize; + 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_CallFunctionObjArgs(filter, match, NULL); + 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_NEW_VAR(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; + 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)) { + 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()) { + PyErr_SetString(PyExc_IndexError, "no such group"); + } + return -1; + } + + return i; +} + +static PyObject* +match_getslice(MatchObject* self, PyObject* index, PyObject* def) +{ + Py_ssize_t i = match_getindex(self, index); + + if (i < 0) { + return NULL; + } + + 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); + + 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); + + 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); + + 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] */ + match = PyObject_NEW_VAR(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 */ + 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 (Py_TYPE(lefto) != &Pattern_Type || Py_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 + {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_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 + {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_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 */ + 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 */ + 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/python/Modules/_ssl.c b/python/Modules/_ssl.c new file mode 100755 index 0000000..7c6927b --- /dev/null +++ b/python/Modules/_ssl.c @@ -0,0 +1,6474 @@ +// /* 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 +// #define OPENSSL_API_COMPAT 0x10101000L +// #endif +// #define OPENSSL_NO_DEPRECATED 1 + +// #define PY_SSIZE_T_CLEAN + +// #include "Python.h" + +// #include "pythread.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 + +// /* 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) */ +// #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 + +// /* 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. +// */ +// #ifndef OPENSSL_NO_TLS1_METHOD +// extern const SSL_METHOD *TLSv1_method(void); +// #endif +// #ifndef OPENSSL_NO_TLS1_1_METHOD +// extern const SSL_METHOD *TLSv1_1_method(void); +// #endif +// #ifndef OPENSSL_NO_TLS1_2_METHOD +// 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 + +// #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 +// #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 +// 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 */ +// /* 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. +// */ +// 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 *); +// #define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type) +// #define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type) +// #define PySSLSession_Check(v) (Py_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) + +// #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 */ +// {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; +// reason_obj = PyDict_GetItemWithError(err_codes_to_names, key); +// Py_DECREF(key); +// if (reason_obj == NULL && PyErr_Occurred()) { +// goto fail; +// } +// key = PyLong_FromLong(lib); +// if (key == NULL) +// goto fail; +// lib_obj = PyDict_GetItemWithError(lib_codes_to_names, 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; + +// 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); +// } + +// static int +// PySSL_ChainExceptions(PySSLSocket *sslsock) { +// if (sslsock->exc_type == NULL) +// return 0; + +// _PyErr_ChainExceptions(sslsock->exc_type, sslsock->exc_value, sslsock->exc_tb); +// sslsock->exc_type = NULL; +// sslsock->exc_value = NULL; +// sslsock->exc_tb = NULL; +// 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); +// } +// 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; +// } +// 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); +// } +// } 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 (PySSL_ChainExceptions(self) < 0) +// return NULL; +// 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); +// 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; + +// 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 +// */ +// t = PyTuple_New(2); +// if (t == NULL) +// goto fail; + +// v = PyUnicode_FromString("IP Address"); +// if (v == NULL) { +// Py_DECREF(t); +// goto fail; +// } +// PyTuple_SET_ITEM(t, 0, v); + +// if (name->d.ip->length == 4) { +// unsigned char *p = name->d.ip->data; +// v = PyUnicode_FromFormat( +// "%d.%d.%d.%d", +// p[0], p[1], p[2], p[3] +// ); +// } else if (name->d.ip->length == 16) { +// /* PyUnicode_FromFormat() does not support %X */ +// unsigned char *p = name->d.ip->data; +// len = sprintf( +// buf, +// "%X:%X:%X:%X:%X:%X:%X:%X", +// p[0] << 8 | p[1], +// p[2] << 8 | p[3], +// p[4] << 8 | p[5], +// p[6] << 8 | p[7], +// p[8] << 8 | p[9], +// p[10] << 8 | p[11], +// p[12] << 8 | p[13], +// p[14] << 8 | p[15] +// ); +// v = PyUnicode_FromStringAndSize(buf, len); +// } else { +// v = PyUnicode_FromString(""); +// } + +// 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; +// } + +// 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, 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; +// } + +// /* validata 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) { +// ok = 0; +// 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) +// { +// 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) +// { +// /* this function collects the system certificate stores listed in +// * system_stores into a collection certificate store for being +// * enumerated. The store must be readable to be added to the +// * store collection. +// */ + +// HCERTSTORE hCollectionStore = NULL, hSystemStore = NULL; +// static DWORD system_stores[] = { +// CERT_SYSTEM_STORE_LOCAL_MACHINE, +// CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, +// CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, +// CERT_SYSTEM_STORE_CURRENT_USER, +// CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, +// CERT_SYSTEM_STORE_SERVICES, +// CERT_SYSTEM_STORE_USERS}; +// size_t i, storesAdded; +// BOOL result; + +// hCollectionStore = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, +// (HCRYPTPROV)NULL, 0, NULL); +// if (!hCollectionStore) { +// return NULL; +// } +// storesAdded = 0; +// for (i = 0; i < sizeof(system_stores) / sizeof(DWORD); i++) { +// hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, +// (HCRYPTPROV)NULL, +// CERT_STORE_READONLY_FLAG | +// system_stores[i], store_name); +// if (hSystemStore) { +// result = CertAddStoreToCollection(hCollectionStore, hSystemStore, +// CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); +// if (result) { +// ++storesAdded; +// } +// CertCloseStore(hSystemStore, 0); /* flag must be 0 */ +// } +// } +// if (storesAdded == 0) { +// CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG); +// return NULL; +// } + +// 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]*/ +// { +// HCERTSTORE hCollectionStore = 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; +// } +// hCollectionStore = ssl_collect_certificates(store_name); +// if (hCollectionStore == NULL) { +// 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; +// 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); + +// /* 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()); +// } + +// /* convert set to list */ +// if (result == NULL) { +// return NULL; +// } else { +// PyObject *lst = PySequence_List(result); +// 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]*/ +// { +// HCERTSTORE hCollectionStore = NULL; +// PCCRL_CONTEXT pCrlCtx = NULL; +// PyObject *crl = NULL, *enc = NULL, *tup = NULL; +// PyObject *result = NULL; + +// result = PySet_New(NULL); +// if (result == NULL) { +// return NULL; +// } +// hCollectionStore = ssl_collect_certificates(store_name); +// if (hCollectionStore == NULL) { +// 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; + +// 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); + +// /* 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()); +// } +// /* convert set to list */ +// if (result == NULL) { +// return NULL; +// } else { +// PyObject *lst = PySequence_List(result); +// 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; +// } +// #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 +// #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); + +// #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. +// */ +// 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 = 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; +// } diff --git a/python/Modules/_ssl/debughelpers.c b/python/Modules/_ssl/debughelpers.c new file mode 100755 index 0000000..af56f9d --- /dev/null +++ b/python/Modules/_ssl/debughelpers.c @@ -0,0 +1,223 @@ +/* Debug helpers */ + +#ifndef SSL3_MT_CHANGE_CIPHER_SPEC +/* Dummy message type for handling CCS like a normal handshake message + * not defined in OpenSSL 1.0.2 + */ +#define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 +#endif + +static void +_PySSL_msg_callback(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) +{ + const char *cbuf = (const char *)buf; + PyGILState_STATE threadstate; + PyObject *res = NULL; + PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ + PyObject *ssl_socket = NULL; /* ssl.SSLSocket or ssl.SSLObject */ + int msg_type; + + threadstate = PyGILState_Ensure(); + + ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); + assert(PySSLSocket_Check(ssl_obj)); + if (ssl_obj->ctx->msg_cb == NULL) { + PyGILState_Release(threadstate); + return; + } + + if (ssl_obj->owner) + ssl_socket = PyWeakref_GetObject(ssl_obj->owner); + else if (ssl_obj->Socket) + ssl_socket = PyWeakref_GetObject(ssl_obj->Socket); + else + ssl_socket = (PyObject *)ssl_obj; + Py_INCREF(ssl_socket); + + /* assume that OpenSSL verifies all payload and buf len is of sufficient + length */ + switch(content_type) { + case SSL3_RT_CHANGE_CIPHER_SPEC: + msg_type = SSL3_MT_CHANGE_CIPHER_SPEC; + break; + case SSL3_RT_ALERT: + /* byte 0: level */ + /* byte 1: alert type */ + msg_type = (int)cbuf[1]; + break; + case SSL3_RT_HANDSHAKE: + msg_type = (int)cbuf[0]; + break; +#ifdef SSL3_RT_HEADER + case SSL3_RT_HEADER: + /* frame header encodes version in bytes 1..2 */ + version = cbuf[1] << 8 | cbuf[2]; + msg_type = (int)cbuf[0]; + break; +#endif +#ifdef SSL3_RT_INNER_CONTENT_TYPE + case SSL3_RT_INNER_CONTENT_TYPE: + msg_type = (int)cbuf[0]; + break; +#endif + default: + /* never SSL3_RT_APPLICATION_DATA */ + msg_type = -1; + break; + } + + res = PyObject_CallFunction( + ssl_obj->ctx->msg_cb, "Osiiiy#", + ssl_socket, write_p ? "write" : "read", + version, content_type, msg_type, + buf, len + ); + if (res == NULL) { + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + } else { + Py_DECREF(res); + } + Py_XDECREF(ssl_socket); + + PyGILState_Release(threadstate); +} + + +static PyObject * +_PySSLContext_get_msg_callback(PySSLContext *self, void *c) { + if (self->msg_cb != NULL) { + Py_INCREF(self->msg_cb); + return self->msg_cb; + } else { + Py_RETURN_NONE; + } +} + +static int +_PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) { + Py_CLEAR(self->msg_cb); + if (arg == Py_None) { + SSL_CTX_set_msg_callback(self->ctx, NULL); + } + else { + if (!PyCallable_Check(arg)) { + SSL_CTX_set_msg_callback(self->ctx, NULL); + PyErr_SetString(PyExc_TypeError, + "not a callable object"); + return -1; + } + Py_INCREF(arg); + self->msg_cb = arg; + SSL_CTX_set_msg_callback(self->ctx, _PySSL_msg_callback); + } + return 0; +} + +#ifdef HAVE_OPENSSL_KEYLOG + +static void +_PySSL_keylog_callback(const SSL *ssl, const char *line) +{ + PyGILState_STATE threadstate; + PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ + int res, e; + static PyThread_type_lock *lock = NULL; + + threadstate = PyGILState_Ensure(); + + ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); + assert(PySSLSocket_Check(ssl_obj)); + if (ssl_obj->ctx->keylog_bio == NULL) { + return; + } + + /* Allocate a static lock to synchronize writes to keylog file. + * The lock is neither released on exit nor on fork(). The lock is + * also shared between all SSLContexts although contexts may write to + * their own files. IMHO that's good enough for a non-performance + * critical debug helper. + */ + if (lock == NULL) { + lock = PyThread_allocate_lock(); + if (lock == NULL) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, + &ssl_obj->exc_tb); + return; + } + } + + PySSL_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(lock, 1); + res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line); + e = errno; + (void)BIO_flush(ssl_obj->ctx->keylog_bio); + PyThread_release_lock(lock); + PySSL_END_ALLOW_THREADS + + if (res == -1) { + errno = e; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, + ssl_obj->ctx->keylog_filename); + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + } + PyGILState_Release(threadstate); +} + +static PyObject * +_PySSLContext_get_keylog_filename(PySSLContext *self, void *c) { + if (self->keylog_filename != NULL) { + Py_INCREF(self->keylog_filename); + return self->keylog_filename; + } else { + Py_RETURN_NONE; + } +} + +static int +_PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { + FILE *fp; + /* Reset variables and callback first */ + SSL_CTX_set_keylog_callback(self->ctx, NULL); + Py_CLEAR(self->keylog_filename); + if (self->keylog_bio != NULL) { + BIO *bio = self->keylog_bio; + self->keylog_bio = NULL; + PySSL_BEGIN_ALLOW_THREADS + BIO_free_all(bio); + PySSL_END_ALLOW_THREADS + } + + if (arg == Py_None) { + /* None disables the callback */ + return 0; + } + + /* _Py_fopen_obj() also checks that arg is of proper type. */ + fp = _Py_fopen_obj(arg, "a" PY_STDIOTEXTMODE); + if (fp == NULL) + return -1; + + self->keylog_bio = BIO_new_fp(fp, BIO_CLOSE | BIO_FP_TEXT); + if (self->keylog_bio == NULL) { + PyErr_SetString(PySSLErrorObject, + "Can't malloc memory for keylog file"); + return -1; + } + Py_INCREF(arg); + self->keylog_filename = arg; + + /* Write a header for seekable, empty files (this excludes pipes). */ + PySSL_BEGIN_ALLOW_THREADS + if (BIO_tell(self->keylog_bio) == 0) { + BIO_puts(self->keylog_bio, + "# TLS secrets log file, generated by OpenSSL / Python\n"); + (void)BIO_flush(self->keylog_bio); + } + PySSL_END_ALLOW_THREADS + SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback); + return 0; +} + +#endif diff --git a/python/Modules/_ssl_data.h b/python/Modules/_ssl_data.h new file mode 100755 index 0000000..8f2994f --- /dev/null +++ b/python/Modules/_ssl_data.h @@ -0,0 +1,6323 @@ +/* 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[] = { +#ifdef ERR_LIB_ASN1 + {"ASN1", ERR_LIB_ASN1}, +#endif +#ifdef ERR_LIB_ASYNC + {"ASYNC", ERR_LIB_ASYNC}, +#endif +#ifdef ERR_LIB_BIO + {"BIO", ERR_LIB_BIO}, +#endif +#ifdef ERR_LIB_BN + {"BN", ERR_LIB_BN}, +#endif +#ifdef ERR_LIB_CMS + {"CMS", ERR_LIB_CMS}, +#endif +#ifdef ERR_LIB_COMP + {"COMP", ERR_LIB_COMP}, +#endif +#ifdef ERR_LIB_CONF + {"CONF", ERR_LIB_CONF}, +#endif +#ifdef ERR_LIB_CRYPTO + {"CRYPTO", ERR_LIB_CRYPTO}, +#endif +#ifdef ERR_LIB_CT + {"CT", ERR_LIB_CT}, +#endif +#ifdef ERR_LIB_DH + {"DH", ERR_LIB_DH}, +#endif +#ifdef ERR_LIB_DSA + {"DSA", ERR_LIB_DSA}, +#endif +#ifdef ERR_LIB_EC + {"EC", ERR_LIB_EC}, +#endif +#ifdef ERR_LIB_ENGINE + {"ENGINE", ERR_LIB_ENGINE}, +#endif +#ifdef ERR_LIB_EVP + {"EVP", ERR_LIB_EVP}, +#endif +#ifdef ERR_LIB_KDF + {"KDF", ERR_LIB_KDF}, +#endif +#ifdef ERR_LIB_OCSP + {"OCSP", ERR_LIB_OCSP}, +#endif +#ifdef ERR_LIB_PEM + {"PEM", ERR_LIB_PEM}, +#endif +#ifdef ERR_LIB_PKCS12 + {"PKCS12", ERR_LIB_PKCS12}, +#endif +#ifdef ERR_LIB_PKCS7 + {"PKCS7", ERR_LIB_PKCS7}, +#endif +#ifdef ERR_LIB_RAND + {"RAND", ERR_LIB_RAND}, +#endif +#ifdef ERR_LIB_RSA + {"RSA", ERR_LIB_RSA}, +#endif +#ifdef ERR_LIB_SSL + {"SSL", ERR_LIB_SSL}, +#endif +#ifdef ERR_LIB_TS + {"TS", ERR_LIB_TS}, +#endif +#ifdef ERR_LIB_UI + {"UI", ERR_LIB_UI}, +#endif +#ifdef 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[] = { + #ifdef ASN1_R_ADDING_OBJECT + {"ADDING_OBJECT", ERR_LIB_ASN1, ASN1_R_ADDING_OBJECT}, + #else + {"ADDING_OBJECT", 13, 171}, + #endif + #ifdef ASN1_R_ASN1_PARSE_ERROR + {"ASN1_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_PARSE_ERROR}, + #else + {"ASN1_PARSE_ERROR", 13, 203}, + #endif + #ifdef ASN1_R_ASN1_SIG_PARSE_ERROR + {"ASN1_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR}, + #else + {"ASN1_SIG_PARSE_ERROR", 13, 204}, + #endif + #ifdef ASN1_R_AUX_ERROR + {"AUX_ERROR", ERR_LIB_ASN1, ASN1_R_AUX_ERROR}, + #else + {"AUX_ERROR", 13, 100}, + #endif + #ifdef ASN1_R_BAD_OBJECT_HEADER + {"BAD_OBJECT_HEADER", ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER}, + #else + {"BAD_OBJECT_HEADER", 13, 102}, + #endif + #ifdef ASN1_R_BMPSTRING_IS_WRONG_LENGTH + {"BMPSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH}, + #else + {"BMPSTRING_IS_WRONG_LENGTH", 13, 214}, + #endif + #ifdef ASN1_R_BN_LIB + {"BN_LIB", ERR_LIB_ASN1, ASN1_R_BN_LIB}, + #else + {"BN_LIB", 13, 105}, + #endif + #ifdef ASN1_R_BOOLEAN_IS_WRONG_LENGTH + {"BOOLEAN_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH}, + #else + {"BOOLEAN_IS_WRONG_LENGTH", 13, 106}, + #endif + #ifdef ASN1_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_ASN1, ASN1_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 13, 107}, + #endif + #ifdef ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 13, 108}, + #endif + #ifdef ASN1_R_CONTEXT_NOT_INITIALISED + {"CONTEXT_NOT_INITIALISED", ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED}, + #else + {"CONTEXT_NOT_INITIALISED", 13, 217}, + #endif + #ifdef ASN1_R_DATA_IS_WRONG + {"DATA_IS_WRONG", ERR_LIB_ASN1, ASN1_R_DATA_IS_WRONG}, + #else + {"DATA_IS_WRONG", 13, 109}, + #endif + #ifdef ASN1_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 13, 110}, + #endif + #ifdef ASN1_R_DEPTH_EXCEEDED + {"DEPTH_EXCEEDED", ERR_LIB_ASN1, ASN1_R_DEPTH_EXCEEDED}, + #else + {"DEPTH_EXCEEDED", 13, 174}, + #endif + #ifdef ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED}, + #else + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", 13, 198}, + #endif + #ifdef ASN1_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_ASN1, ASN1_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 13, 112}, + #endif + #ifdef ASN1_R_ERROR_GETTING_TIME + {"ERROR_GETTING_TIME", ERR_LIB_ASN1, ASN1_R_ERROR_GETTING_TIME}, + #else + {"ERROR_GETTING_TIME", 13, 173}, + #endif + #ifdef ASN1_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_ASN1, ASN1_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 13, 172}, + #endif + #ifdef ASN1_R_ERROR_SETTING_CIPHER_PARAMS + {"ERROR_SETTING_CIPHER_PARAMS", ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS}, + #else + {"ERROR_SETTING_CIPHER_PARAMS", 13, 114}, + #endif + #ifdef ASN1_R_EXPECTING_AN_INTEGER + {"EXPECTING_AN_INTEGER", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_INTEGER}, + #else + {"EXPECTING_AN_INTEGER", 13, 115}, + #endif + #ifdef ASN1_R_EXPECTING_AN_OBJECT + {"EXPECTING_AN_OBJECT", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_OBJECT}, + #else + {"EXPECTING_AN_OBJECT", 13, 116}, + #endif + #ifdef ASN1_R_EXPLICIT_LENGTH_MISMATCH + {"EXPLICIT_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH}, + #else + {"EXPLICIT_LENGTH_MISMATCH", 13, 119}, + #endif + #ifdef ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED + {"EXPLICIT_TAG_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED}, + #else + {"EXPLICIT_TAG_NOT_CONSTRUCTED", 13, 120}, + #endif + #ifdef ASN1_R_FIELD_MISSING + {"FIELD_MISSING", ERR_LIB_ASN1, ASN1_R_FIELD_MISSING}, + #else + {"FIELD_MISSING", 13, 121}, + #endif + #ifdef ASN1_R_FIRST_NUM_TOO_LARGE + {"FIRST_NUM_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_FIRST_NUM_TOO_LARGE}, + #else + {"FIRST_NUM_TOO_LARGE", 13, 122}, + #endif + #ifdef ASN1_R_HEADER_TOO_LONG + {"HEADER_TOO_LONG", ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}, + #else + {"HEADER_TOO_LONG", 13, 123}, + #endif + #ifdef ASN1_R_ILLEGAL_BITSTRING_FORMAT + {"ILLEGAL_BITSTRING_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT}, + #else + {"ILLEGAL_BITSTRING_FORMAT", 13, 175}, + #endif + #ifdef ASN1_R_ILLEGAL_BOOLEAN + {"ILLEGAL_BOOLEAN", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BOOLEAN}, + #else + {"ILLEGAL_BOOLEAN", 13, 176}, + #endif + #ifdef ASN1_R_ILLEGAL_CHARACTERS + {"ILLEGAL_CHARACTERS", ERR_LIB_ASN1, ASN1_R_ILLEGAL_CHARACTERS}, + #else + {"ILLEGAL_CHARACTERS", 13, 124}, + #endif + #ifdef ASN1_R_ILLEGAL_FORMAT + {"ILLEGAL_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_FORMAT}, + #else + {"ILLEGAL_FORMAT", 13, 177}, + #endif + #ifdef ASN1_R_ILLEGAL_HEX + {"ILLEGAL_HEX", ERR_LIB_ASN1, ASN1_R_ILLEGAL_HEX}, + #else + {"ILLEGAL_HEX", 13, 178}, + #endif + #ifdef ASN1_R_ILLEGAL_IMPLICIT_TAG + {"ILLEGAL_IMPLICIT_TAG", ERR_LIB_ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG}, + #else + {"ILLEGAL_IMPLICIT_TAG", 13, 179}, + #endif + #ifdef ASN1_R_ILLEGAL_INTEGER + {"ILLEGAL_INTEGER", ERR_LIB_ASN1, ASN1_R_ILLEGAL_INTEGER}, + #else + {"ILLEGAL_INTEGER", 13, 180}, + #endif + #ifdef ASN1_R_ILLEGAL_NEGATIVE_VALUE + {"ILLEGAL_NEGATIVE_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE}, + #else + {"ILLEGAL_NEGATIVE_VALUE", 13, 226}, + #endif + #ifdef ASN1_R_ILLEGAL_NESTED_TAGGING + {"ILLEGAL_NESTED_TAGGING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING}, + #else + {"ILLEGAL_NESTED_TAGGING", 13, 181}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL + {"ILLEGAL_NULL", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL}, + #else + {"ILLEGAL_NULL", 13, 125}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL_VALUE + {"ILLEGAL_NULL_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL_VALUE}, + #else + {"ILLEGAL_NULL_VALUE", 13, 182}, + #endif + #ifdef ASN1_R_ILLEGAL_OBJECT + {"ILLEGAL_OBJECT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT}, + #else + {"ILLEGAL_OBJECT", 13, 183}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONAL_ANY + {"ILLEGAL_OPTIONAL_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY}, + #else + {"ILLEGAL_OPTIONAL_ANY", 13, 126}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE}, + #else + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", 13, 170}, + #endif + #ifdef ASN1_R_ILLEGAL_PADDING + {"ILLEGAL_PADDING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_PADDING}, + #else + {"ILLEGAL_PADDING", 13, 221}, + #endif + #ifdef ASN1_R_ILLEGAL_TAGGED_ANY + {"ILLEGAL_TAGGED_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TAGGED_ANY}, + #else + {"ILLEGAL_TAGGED_ANY", 13, 127}, + #endif + #ifdef ASN1_R_ILLEGAL_TIME_VALUE + {"ILLEGAL_TIME_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TIME_VALUE}, + #else + {"ILLEGAL_TIME_VALUE", 13, 184}, + #endif + #ifdef ASN1_R_ILLEGAL_ZERO_CONTENT + {"ILLEGAL_ZERO_CONTENT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT}, + #else + {"ILLEGAL_ZERO_CONTENT", 13, 222}, + #endif + #ifdef ASN1_R_INTEGER_NOT_ASCII_FORMAT + {"INTEGER_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT}, + #else + {"INTEGER_NOT_ASCII_FORMAT", 13, 185}, + #endif + #ifdef ASN1_R_INTEGER_TOO_LARGE_FOR_LONG + {"INTEGER_TOO_LARGE_FOR_LONG", ERR_LIB_ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG}, + #else + {"INTEGER_TOO_LARGE_FOR_LONG", 13, 128}, + #endif + #ifdef ASN1_R_INVALID_BIT_STRING_BITS_LEFT + {"INVALID_BIT_STRING_BITS_LEFT", ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}, + #else + {"INVALID_BIT_STRING_BITS_LEFT", 13, 220}, + #endif + #ifdef ASN1_R_INVALID_BMPSTRING_LENGTH + {"INVALID_BMPSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH}, + #else + {"INVALID_BMPSTRING_LENGTH", 13, 129}, + #endif + #ifdef ASN1_R_INVALID_DIGIT + {"INVALID_DIGIT", ERR_LIB_ASN1, ASN1_R_INVALID_DIGIT}, + #else + {"INVALID_DIGIT", 13, 130}, + #endif + #ifdef ASN1_R_INVALID_MIME_TYPE + {"INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_INVALID_MIME_TYPE}, + #else + {"INVALID_MIME_TYPE", 13, 205}, + #endif + #ifdef ASN1_R_INVALID_MODIFIER + {"INVALID_MODIFIER", ERR_LIB_ASN1, ASN1_R_INVALID_MODIFIER}, + #else + {"INVALID_MODIFIER", 13, 186}, + #endif + #ifdef ASN1_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 13, 187}, + #endif + #ifdef ASN1_R_INVALID_OBJECT_ENCODING + {"INVALID_OBJECT_ENCODING", ERR_LIB_ASN1, ASN1_R_INVALID_OBJECT_ENCODING}, + #else + {"INVALID_OBJECT_ENCODING", 13, 216}, + #endif + #ifdef ASN1_R_INVALID_SCRYPT_PARAMETERS + {"INVALID_SCRYPT_PARAMETERS", ERR_LIB_ASN1, ASN1_R_INVALID_SCRYPT_PARAMETERS}, + #else + {"INVALID_SCRYPT_PARAMETERS", 13, 227}, + #endif + #ifdef ASN1_R_INVALID_SEPARATOR + {"INVALID_SEPARATOR", ERR_LIB_ASN1, ASN1_R_INVALID_SEPARATOR}, + #else + {"INVALID_SEPARATOR", 13, 131}, + #endif + #ifdef ASN1_R_INVALID_STRING_TABLE_VALUE + {"INVALID_STRING_TABLE_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE}, + #else + {"INVALID_STRING_TABLE_VALUE", 13, 218}, + #endif + #ifdef ASN1_R_INVALID_UNIVERSALSTRING_LENGTH + {"INVALID_UNIVERSALSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH}, + #else + {"INVALID_UNIVERSALSTRING_LENGTH", 13, 133}, + #endif + #ifdef ASN1_R_INVALID_UTF8STRING + {"INVALID_UTF8STRING", ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING}, + #else + {"INVALID_UTF8STRING", 13, 134}, + #endif + #ifdef ASN1_R_INVALID_VALUE + {"INVALID_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_VALUE}, + #else + {"INVALID_VALUE", 13, 219}, + #endif + #ifdef ASN1_R_LIST_ERROR + {"LIST_ERROR", ERR_LIB_ASN1, ASN1_R_LIST_ERROR}, + #else + {"LIST_ERROR", 13, 188}, + #endif + #ifdef ASN1_R_MIME_NO_CONTENT_TYPE + {"MIME_NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_MIME_NO_CONTENT_TYPE}, + #else + {"MIME_NO_CONTENT_TYPE", 13, 206}, + #endif + #ifdef ASN1_R_MIME_PARSE_ERROR + {"MIME_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_PARSE_ERROR}, + #else + {"MIME_PARSE_ERROR", 13, 207}, + #endif + #ifdef ASN1_R_MIME_SIG_PARSE_ERROR + {"MIME_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR}, + #else + {"MIME_SIG_PARSE_ERROR", 13, 208}, + #endif + #ifdef ASN1_R_MISSING_EOC + {"MISSING_EOC", ERR_LIB_ASN1, ASN1_R_MISSING_EOC}, + #else + {"MISSING_EOC", 13, 137}, + #endif + #ifdef ASN1_R_MISSING_SECOND_NUMBER + {"MISSING_SECOND_NUMBER", ERR_LIB_ASN1, ASN1_R_MISSING_SECOND_NUMBER}, + #else + {"MISSING_SECOND_NUMBER", 13, 138}, + #endif + #ifdef ASN1_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 13, 189}, + #endif + #ifdef ASN1_R_MSTRING_NOT_UNIVERSAL + {"MSTRING_NOT_UNIVERSAL", ERR_LIB_ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL}, + #else + {"MSTRING_NOT_UNIVERSAL", 13, 139}, + #endif + #ifdef ASN1_R_MSTRING_WRONG_TAG + {"MSTRING_WRONG_TAG", ERR_LIB_ASN1, ASN1_R_MSTRING_WRONG_TAG}, + #else + {"MSTRING_WRONG_TAG", 13, 140}, + #endif + #ifdef ASN1_R_NESTED_ASN1_STRING + {"NESTED_ASN1_STRING", ERR_LIB_ASN1, ASN1_R_NESTED_ASN1_STRING}, + #else + {"NESTED_ASN1_STRING", 13, 197}, + #endif + #ifdef ASN1_R_NESTED_TOO_DEEP + {"NESTED_TOO_DEEP", ERR_LIB_ASN1, ASN1_R_NESTED_TOO_DEEP}, + #else + {"NESTED_TOO_DEEP", 13, 201}, + #endif + #ifdef ASN1_R_NON_HEX_CHARACTERS + {"NON_HEX_CHARACTERS", ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS}, + #else + {"NON_HEX_CHARACTERS", 13, 141}, + #endif + #ifdef ASN1_R_NOT_ASCII_FORMAT + {"NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_NOT_ASCII_FORMAT}, + #else + {"NOT_ASCII_FORMAT", 13, 190}, + #endif + #ifdef ASN1_R_NOT_ENOUGH_DATA + {"NOT_ENOUGH_DATA", ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA}, + #else + {"NOT_ENOUGH_DATA", 13, 142}, + #endif + #ifdef ASN1_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 13, 209}, + #endif + #ifdef ASN1_R_NO_MATCHING_CHOICE_TYPE + {"NO_MATCHING_CHOICE_TYPE", ERR_LIB_ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE}, + #else + {"NO_MATCHING_CHOICE_TYPE", 13, 143}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BODY_FAILURE + {"NO_MULTIPART_BODY_FAILURE", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE}, + #else + {"NO_MULTIPART_BODY_FAILURE", 13, 210}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BOUNDARY + {"NO_MULTIPART_BOUNDARY", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY}, + #else + {"NO_MULTIPART_BOUNDARY", 13, 211}, + #endif + #ifdef ASN1_R_NO_SIG_CONTENT_TYPE + {"NO_SIG_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE}, + #else + {"NO_SIG_CONTENT_TYPE", 13, 212}, + #endif + #ifdef ASN1_R_NULL_IS_WRONG_LENGTH + {"NULL_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_NULL_IS_WRONG_LENGTH}, + #else + {"NULL_IS_WRONG_LENGTH", 13, 144}, + #endif + #ifdef ASN1_R_OBJECT_NOT_ASCII_FORMAT + {"OBJECT_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT}, + #else + {"OBJECT_NOT_ASCII_FORMAT", 13, 191}, + #endif + #ifdef ASN1_R_ODD_NUMBER_OF_CHARS + {"ODD_NUMBER_OF_CHARS", ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS}, + #else + {"ODD_NUMBER_OF_CHARS", 13, 145}, + #endif + #ifdef ASN1_R_SECOND_NUMBER_TOO_LARGE + {"SECOND_NUMBER_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE}, + #else + {"SECOND_NUMBER_TOO_LARGE", 13, 147}, + #endif + #ifdef ASN1_R_SEQUENCE_LENGTH_MISMATCH + {"SEQUENCE_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH}, + #else + {"SEQUENCE_LENGTH_MISMATCH", 13, 148}, + #endif + #ifdef ASN1_R_SEQUENCE_NOT_CONSTRUCTED + {"SEQUENCE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED}, + #else + {"SEQUENCE_NOT_CONSTRUCTED", 13, 149}, + #endif + #ifdef ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG + {"SEQUENCE_OR_SET_NEEDS_CONFIG", ERR_LIB_ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG}, + #else + {"SEQUENCE_OR_SET_NEEDS_CONFIG", 13, 192}, + #endif + #ifdef ASN1_R_SHORT_LINE + {"SHORT_LINE", ERR_LIB_ASN1, ASN1_R_SHORT_LINE}, + #else + {"SHORT_LINE", 13, 150}, + #endif + #ifdef ASN1_R_SIG_INVALID_MIME_TYPE + {"SIG_INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE}, + #else + {"SIG_INVALID_MIME_TYPE", 13, 213}, + #endif + #ifdef ASN1_R_STREAMING_NOT_SUPPORTED + {"STREAMING_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED}, + #else + {"STREAMING_NOT_SUPPORTED", 13, 202}, + #endif + #ifdef ASN1_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 13, 151}, + #endif + #ifdef ASN1_R_STRING_TOO_SHORT + {"STRING_TOO_SHORT", ERR_LIB_ASN1, ASN1_R_STRING_TOO_SHORT}, + #else + {"STRING_TOO_SHORT", 13, 152}, + #endif + #ifdef ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_ASN1, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 13, 154}, + #endif + #ifdef ASN1_R_TIME_NOT_ASCII_FORMAT + {"TIME_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT}, + #else + {"TIME_NOT_ASCII_FORMAT", 13, 193}, + #endif + #ifdef ASN1_R_TOO_LARGE + {"TOO_LARGE", ERR_LIB_ASN1, ASN1_R_TOO_LARGE}, + #else + {"TOO_LARGE", 13, 223}, + #endif + #ifdef ASN1_R_TOO_LONG + {"TOO_LONG", ERR_LIB_ASN1, ASN1_R_TOO_LONG}, + #else + {"TOO_LONG", 13, 155}, + #endif + #ifdef ASN1_R_TOO_SMALL + {"TOO_SMALL", ERR_LIB_ASN1, ASN1_R_TOO_SMALL}, + #else + {"TOO_SMALL", 13, 224}, + #endif + #ifdef ASN1_R_TYPE_NOT_CONSTRUCTED + {"TYPE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED}, + #else + {"TYPE_NOT_CONSTRUCTED", 13, 156}, + #endif + #ifdef ASN1_R_TYPE_NOT_PRIMITIVE + {"TYPE_NOT_PRIMITIVE", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_PRIMITIVE}, + #else + {"TYPE_NOT_PRIMITIVE", 13, 195}, + #endif + #ifdef ASN1_R_UNEXPECTED_EOC + {"UNEXPECTED_EOC", ERR_LIB_ASN1, ASN1_R_UNEXPECTED_EOC}, + #else + {"UNEXPECTED_EOC", 13, 159}, + #endif + #ifdef ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH + {"UNIVERSALSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH}, + #else + {"UNIVERSALSTRING_IS_WRONG_LENGTH", 13, 215}, + #endif + #ifdef ASN1_R_UNKNOWN_FORMAT + {"UNKNOWN_FORMAT", ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT}, + #else + {"UNKNOWN_FORMAT", 13, 160}, + #endif + #ifdef ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", 13, 161}, + #endif + #ifdef ASN1_R_UNKNOWN_OBJECT_TYPE + {"UNKNOWN_OBJECT_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_OBJECT_TYPE}, + #else + {"UNKNOWN_OBJECT_TYPE", 13, 162}, + #endif + #ifdef ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE + {"UNKNOWN_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE}, + #else + {"UNKNOWN_PUBLIC_KEY_TYPE", 13, 163}, + #endif + #ifdef ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM + {"UNKNOWN_SIGNATURE_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM}, + #else + {"UNKNOWN_SIGNATURE_ALGORITHM", 13, 199}, + #endif + #ifdef ASN1_R_UNKNOWN_TAG + {"UNKNOWN_TAG", ERR_LIB_ASN1, ASN1_R_UNKNOWN_TAG}, + #else + {"UNKNOWN_TAG", 13, 194}, + #endif + #ifdef ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE}, + #else + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", 13, 164}, + #endif + #ifdef ASN1_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 13, 228}, + #endif + #ifdef ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE + {"UNSUPPORTED_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE}, + #else + {"UNSUPPORTED_PUBLIC_KEY_TYPE", 13, 167}, + #endif + #ifdef ASN1_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 13, 196}, + #endif + #ifdef ASN1_R_WRONG_INTEGER_TYPE + {"WRONG_INTEGER_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_INTEGER_TYPE}, + #else + {"WRONG_INTEGER_TYPE", 13, 225}, + #endif + #ifdef ASN1_R_WRONG_PUBLIC_KEY_TYPE + {"WRONG_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE}, + #else + {"WRONG_PUBLIC_KEY_TYPE", 13, 200}, + #endif + #ifdef ASN1_R_WRONG_TAG + {"WRONG_TAG", ERR_LIB_ASN1, ASN1_R_WRONG_TAG}, + #else + {"WRONG_TAG", 13, 168}, + #endif + #ifdef ASYNC_R_FAILED_TO_SET_POOL + {"FAILED_TO_SET_POOL", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SET_POOL}, + #else + {"FAILED_TO_SET_POOL", 51, 101}, + #endif + #ifdef ASYNC_R_FAILED_TO_SWAP_CONTEXT + {"FAILED_TO_SWAP_CONTEXT", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT}, + #else + {"FAILED_TO_SWAP_CONTEXT", 51, 102}, + #endif + #ifdef ASYNC_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ASYNC, ASYNC_R_INIT_FAILED}, + #else + {"INIT_FAILED", 51, 105}, + #endif + #ifdef ASYNC_R_INVALID_POOL_SIZE + {"INVALID_POOL_SIZE", ERR_LIB_ASYNC, ASYNC_R_INVALID_POOL_SIZE}, + #else + {"INVALID_POOL_SIZE", 51, 103}, + #endif + #ifdef BIO_R_ACCEPT_ERROR + {"ACCEPT_ERROR", ERR_LIB_BIO, BIO_R_ACCEPT_ERROR}, + #else + {"ACCEPT_ERROR", 32, 100}, + #endif + #ifdef BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET + {"ADDRINFO_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET}, + #else + {"ADDRINFO_ADDR_IS_NOT_AF_INET", 32, 141}, + #endif + #ifdef BIO_R_AMBIGUOUS_HOST_OR_SERVICE + {"AMBIGUOUS_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_AMBIGUOUS_HOST_OR_SERVICE}, + #else + {"AMBIGUOUS_HOST_OR_SERVICE", 32, 129}, + #endif + #ifdef BIO_R_BAD_FOPEN_MODE + {"BAD_FOPEN_MODE", ERR_LIB_BIO, BIO_R_BAD_FOPEN_MODE}, + #else + {"BAD_FOPEN_MODE", 32, 101}, + #endif + #ifdef BIO_R_BROKEN_PIPE + {"BROKEN_PIPE", ERR_LIB_BIO, BIO_R_BROKEN_PIPE}, + #else + {"BROKEN_PIPE", 32, 124}, + #endif + #ifdef BIO_R_CONNECT_ERROR + {"CONNECT_ERROR", ERR_LIB_BIO, BIO_R_CONNECT_ERROR}, + #else + {"CONNECT_ERROR", 32, 103}, + #endif + #ifdef BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET}, + #else + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", 32, 107}, + #endif + #ifdef BIO_R_GETSOCKNAME_ERROR + {"GETSOCKNAME_ERROR", ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR}, + #else + {"GETSOCKNAME_ERROR", 32, 132}, + #endif + #ifdef BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS + {"GETSOCKNAME_TRUNCATED_ADDRESS", ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS}, + #else + {"GETSOCKNAME_TRUNCATED_ADDRESS", 32, 133}, + #endif + #ifdef BIO_R_GETTING_SOCKTYPE + {"GETTING_SOCKTYPE", ERR_LIB_BIO, BIO_R_GETTING_SOCKTYPE}, + #else + {"GETTING_SOCKTYPE", 32, 134}, + #endif + #ifdef BIO_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 32, 125}, + #endif + #ifdef BIO_R_INVALID_SOCKET + {"INVALID_SOCKET", ERR_LIB_BIO, BIO_R_INVALID_SOCKET}, + #else + {"INVALID_SOCKET", 32, 135}, + #endif + #ifdef BIO_R_IN_USE + {"IN_USE", ERR_LIB_BIO, BIO_R_IN_USE}, + #else + {"IN_USE", 32, 123}, + #endif + #ifdef BIO_R_LENGTH_TOO_LONG + {"LENGTH_TOO_LONG", ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG}, + #else + {"LENGTH_TOO_LONG", 32, 102}, + #endif + #ifdef BIO_R_LISTEN_V6_ONLY + {"LISTEN_V6_ONLY", ERR_LIB_BIO, BIO_R_LISTEN_V6_ONLY}, + #else + {"LISTEN_V6_ONLY", 32, 136}, + #endif + #ifdef BIO_R_LOOKUP_RETURNED_NOTHING + {"LOOKUP_RETURNED_NOTHING", ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING}, + #else + {"LOOKUP_RETURNED_NOTHING", 32, 142}, + #endif + #ifdef BIO_R_MALFORMED_HOST_OR_SERVICE + {"MALFORMED_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE}, + #else + {"MALFORMED_HOST_OR_SERVICE", 32, 130}, + #endif + #ifdef BIO_R_NBIO_CONNECT_ERROR + {"NBIO_CONNECT_ERROR", ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR}, + #else + {"NBIO_CONNECT_ERROR", 32, 110}, + #endif + #ifdef BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED}, + #else + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", 32, 143}, + #endif + #ifdef BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED}, + #else + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", 32, 144}, + #endif + #ifdef BIO_R_NO_PORT_DEFINED + {"NO_PORT_DEFINED", ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED}, + #else + {"NO_PORT_DEFINED", 32, 113}, + #endif + #ifdef BIO_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_BIO, BIO_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 32, 128}, + #endif + #ifdef BIO_R_NULL_PARAMETER + {"NULL_PARAMETER", ERR_LIB_BIO, BIO_R_NULL_PARAMETER}, + #else + {"NULL_PARAMETER", 32, 115}, + #endif + #ifdef BIO_R_UNABLE_TO_BIND_SOCKET + {"UNABLE_TO_BIND_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_BIND_SOCKET}, + #else + {"UNABLE_TO_BIND_SOCKET", 32, 117}, + #endif + #ifdef BIO_R_UNABLE_TO_CREATE_SOCKET + {"UNABLE_TO_CREATE_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET}, + #else + {"UNABLE_TO_CREATE_SOCKET", 32, 118}, + #endif + #ifdef BIO_R_UNABLE_TO_KEEPALIVE + {"UNABLE_TO_KEEPALIVE", ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE}, + #else + {"UNABLE_TO_KEEPALIVE", 32, 137}, + #endif + #ifdef BIO_R_UNABLE_TO_LISTEN_SOCKET + {"UNABLE_TO_LISTEN_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_LISTEN_SOCKET}, + #else + {"UNABLE_TO_LISTEN_SOCKET", 32, 119}, + #endif + #ifdef BIO_R_UNABLE_TO_NODELAY + {"UNABLE_TO_NODELAY", ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY}, + #else + {"UNABLE_TO_NODELAY", 32, 138}, + #endif + #ifdef BIO_R_UNABLE_TO_REUSEADDR + {"UNABLE_TO_REUSEADDR", ERR_LIB_BIO, BIO_R_UNABLE_TO_REUSEADDR}, + #else + {"UNABLE_TO_REUSEADDR", 32, 139}, + #endif + #ifdef BIO_R_UNAVAILABLE_IP_FAMILY + {"UNAVAILABLE_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY}, + #else + {"UNAVAILABLE_IP_FAMILY", 32, 145}, + #endif + #ifdef BIO_R_UNINITIALIZED + {"UNINITIALIZED", ERR_LIB_BIO, BIO_R_UNINITIALIZED}, + #else + {"UNINITIALIZED", 32, 120}, + #endif + #ifdef BIO_R_UNKNOWN_INFO_TYPE + {"UNKNOWN_INFO_TYPE", ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE}, + #else + {"UNKNOWN_INFO_TYPE", 32, 140}, + #endif + #ifdef BIO_R_UNSUPPORTED_IP_FAMILY + {"UNSUPPORTED_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY}, + #else + {"UNSUPPORTED_IP_FAMILY", 32, 146}, + #endif + #ifdef BIO_R_UNSUPPORTED_METHOD + {"UNSUPPORTED_METHOD", ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD}, + #else + {"UNSUPPORTED_METHOD", 32, 121}, + #endif + #ifdef BIO_R_UNSUPPORTED_PROTOCOL_FAMILY + {"UNSUPPORTED_PROTOCOL_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY}, + #else + {"UNSUPPORTED_PROTOCOL_FAMILY", 32, 131}, + #endif + #ifdef BIO_R_WRITE_TO_READ_ONLY_BIO + {"WRITE_TO_READ_ONLY_BIO", ERR_LIB_BIO, BIO_R_WRITE_TO_READ_ONLY_BIO}, + #else + {"WRITE_TO_READ_ONLY_BIO", 32, 126}, + #endif + #ifdef BIO_R_WSASTARTUP + {"WSASTARTUP", ERR_LIB_BIO, BIO_R_WSASTARTUP}, + #else + {"WSASTARTUP", 32, 122}, + #endif + #ifdef BN_R_ARG2_LT_ARG3 + {"ARG2_LT_ARG3", ERR_LIB_BN, BN_R_ARG2_LT_ARG3}, + #else + {"ARG2_LT_ARG3", 3, 100}, + #endif + #ifdef BN_R_BAD_RECIPROCAL + {"BAD_RECIPROCAL", ERR_LIB_BN, BN_R_BAD_RECIPROCAL}, + #else + {"BAD_RECIPROCAL", 3, 101}, + #endif + #ifdef BN_R_BIGNUM_TOO_LONG + {"BIGNUM_TOO_LONG", ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG}, + #else + {"BIGNUM_TOO_LONG", 3, 114}, + #endif + #ifdef BN_R_BITS_TOO_SMALL + {"BITS_TOO_SMALL", ERR_LIB_BN, BN_R_BITS_TOO_SMALL}, + #else + {"BITS_TOO_SMALL", 3, 118}, + #endif + #ifdef BN_R_CALLED_WITH_EVEN_MODULUS + {"CALLED_WITH_EVEN_MODULUS", ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS}, + #else + {"CALLED_WITH_EVEN_MODULUS", 3, 102}, + #endif + #ifdef BN_R_DIV_BY_ZERO + {"DIV_BY_ZERO", ERR_LIB_BN, BN_R_DIV_BY_ZERO}, + #else + {"DIV_BY_ZERO", 3, 103}, + #endif + #ifdef BN_R_ENCODING_ERROR + {"ENCODING_ERROR", ERR_LIB_BN, BN_R_ENCODING_ERROR}, + #else + {"ENCODING_ERROR", 3, 104}, + #endif + #ifdef BN_R_EXPAND_ON_STATIC_BIGNUM_DATA + {"EXPAND_ON_STATIC_BIGNUM_DATA", ERR_LIB_BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA}, + #else + {"EXPAND_ON_STATIC_BIGNUM_DATA", 3, 105}, + #endif + #ifdef BN_R_INPUT_NOT_REDUCED + {"INPUT_NOT_REDUCED", ERR_LIB_BN, BN_R_INPUT_NOT_REDUCED}, + #else + {"INPUT_NOT_REDUCED", 3, 110}, + #endif + #ifdef BN_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_BN, BN_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 3, 106}, + #endif + #ifdef BN_R_INVALID_RANGE + {"INVALID_RANGE", ERR_LIB_BN, BN_R_INVALID_RANGE}, + #else + {"INVALID_RANGE", 3, 115}, + #endif + #ifdef BN_R_INVALID_SHIFT + {"INVALID_SHIFT", ERR_LIB_BN, BN_R_INVALID_SHIFT}, + #else + {"INVALID_SHIFT", 3, 119}, + #endif + #ifdef BN_R_NOT_A_SQUARE + {"NOT_A_SQUARE", ERR_LIB_BN, BN_R_NOT_A_SQUARE}, + #else + {"NOT_A_SQUARE", 3, 111}, + #endif + #ifdef BN_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_BN, BN_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 3, 107}, + #endif + #ifdef BN_R_NO_INVERSE + {"NO_INVERSE", ERR_LIB_BN, BN_R_NO_INVERSE}, + #else + {"NO_INVERSE", 3, 108}, + #endif + #ifdef BN_R_NO_SOLUTION + {"NO_SOLUTION", ERR_LIB_BN, BN_R_NO_SOLUTION}, + #else + {"NO_SOLUTION", 3, 116}, + #endif + #ifdef BN_R_PRIVATE_KEY_TOO_LARGE + {"PRIVATE_KEY_TOO_LARGE", ERR_LIB_BN, BN_R_PRIVATE_KEY_TOO_LARGE}, + #else + {"PRIVATE_KEY_TOO_LARGE", 3, 117}, + #endif + #ifdef BN_R_P_IS_NOT_PRIME + {"P_IS_NOT_PRIME", ERR_LIB_BN, BN_R_P_IS_NOT_PRIME}, + #else + {"P_IS_NOT_PRIME", 3, 112}, + #endif + #ifdef BN_R_TOO_MANY_ITERATIONS + {"TOO_MANY_ITERATIONS", ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS}, + #else + {"TOO_MANY_ITERATIONS", 3, 113}, + #endif + #ifdef BN_R_TOO_MANY_TEMPORARY_VARIABLES + {"TOO_MANY_TEMPORARY_VARIABLES", ERR_LIB_BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES}, + #else + {"TOO_MANY_TEMPORARY_VARIABLES", 3, 109}, + #endif + #ifdef CMS_R_ADD_SIGNER_ERROR + {"ADD_SIGNER_ERROR", ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR}, + #else + {"ADD_SIGNER_ERROR", 46, 99}, + #endif + #ifdef CMS_R_ATTRIBUTE_ERROR + {"ATTRIBUTE_ERROR", ERR_LIB_CMS, CMS_R_ATTRIBUTE_ERROR}, + #else + {"ATTRIBUTE_ERROR", 46, 161}, + #endif + #ifdef CMS_R_CERTIFICATE_ALREADY_PRESENT + {"CERTIFICATE_ALREADY_PRESENT", ERR_LIB_CMS, CMS_R_CERTIFICATE_ALREADY_PRESENT}, + #else + {"CERTIFICATE_ALREADY_PRESENT", 46, 175}, + #endif + #ifdef CMS_R_CERTIFICATE_HAS_NO_KEYID + {"CERTIFICATE_HAS_NO_KEYID", ERR_LIB_CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID}, + #else + {"CERTIFICATE_HAS_NO_KEYID", 46, 160}, + #endif + #ifdef CMS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 46, 100}, + #endif + #ifdef CMS_R_CIPHER_INITIALISATION_ERROR + {"CIPHER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_INITIALISATION_ERROR}, + #else + {"CIPHER_INITIALISATION_ERROR", 46, 101}, + #endif + #ifdef CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR + {"CIPHER_PARAMETER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR}, + #else + {"CIPHER_PARAMETER_INITIALISATION_ERROR", 46, 102}, + #endif + #ifdef CMS_R_CMS_DATAFINAL_ERROR + {"CMS_DATAFINAL_ERROR", ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR}, + #else + {"CMS_DATAFINAL_ERROR", 46, 103}, + #endif + #ifdef CMS_R_CMS_LIB + {"CMS_LIB", ERR_LIB_CMS, CMS_R_CMS_LIB}, + #else + {"CMS_LIB", 46, 104}, + #endif + #ifdef CMS_R_CONTENTIDENTIFIER_MISMATCH + {"CONTENTIDENTIFIER_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENTIDENTIFIER_MISMATCH}, + #else + {"CONTENTIDENTIFIER_MISMATCH", 46, 170}, + #endif + #ifdef CMS_R_CONTENT_NOT_FOUND + {"CONTENT_NOT_FOUND", ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND}, + #else + {"CONTENT_NOT_FOUND", 46, 105}, + #endif + #ifdef CMS_R_CONTENT_TYPE_MISMATCH + {"CONTENT_TYPE_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_MISMATCH}, + #else + {"CONTENT_TYPE_MISMATCH", 46, 171}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA}, + #else + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", 46, 106}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA}, + #else + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", 46, 107}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA + {"CONTENT_TYPE_NOT_SIGNED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA}, + #else + {"CONTENT_TYPE_NOT_SIGNED_DATA", 46, 108}, + #endif + #ifdef CMS_R_CONTENT_VERIFY_ERROR + {"CONTENT_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR}, + #else + {"CONTENT_VERIFY_ERROR", 46, 109}, + #endif + #ifdef CMS_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_CMS, CMS_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 46, 110}, + #endif + #ifdef CMS_R_CTRL_FAILURE + {"CTRL_FAILURE", ERR_LIB_CMS, CMS_R_CTRL_FAILURE}, + #else + {"CTRL_FAILURE", 46, 111}, + #endif + #ifdef CMS_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_CMS, CMS_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 46, 112}, + #endif + #ifdef CMS_R_ERROR_GETTING_PUBLIC_KEY + {"ERROR_GETTING_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_ERROR_GETTING_PUBLIC_KEY}, + #else + {"ERROR_GETTING_PUBLIC_KEY", 46, 113}, + #endif + #ifdef CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE}, + #else + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", 46, 114}, + #endif + #ifdef CMS_R_ERROR_SETTING_KEY + {"ERROR_SETTING_KEY", ERR_LIB_CMS, CMS_R_ERROR_SETTING_KEY}, + #else + {"ERROR_SETTING_KEY", 46, 115}, + #endif + #ifdef CMS_R_ERROR_SETTING_RECIPIENTINFO + {"ERROR_SETTING_RECIPIENTINFO", ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO}, + #else + {"ERROR_SETTING_RECIPIENTINFO", 46, 116}, + #endif + #ifdef CMS_R_INVALID_ENCRYPTED_KEY_LENGTH + {"INVALID_ENCRYPTED_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH}, + #else + {"INVALID_ENCRYPTED_KEY_LENGTH", 46, 117}, + #endif + #ifdef CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER + {"INVALID_KEY_ENCRYPTION_PARAMETER", ERR_LIB_CMS, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER}, + #else + {"INVALID_KEY_ENCRYPTION_PARAMETER", 46, 176}, + #endif + #ifdef CMS_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 46, 118}, + #endif + #ifdef CMS_R_MD_BIO_INIT_ERROR + {"MD_BIO_INIT_ERROR", ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR}, + #else + {"MD_BIO_INIT_ERROR", 46, 119}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", 46, 120}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_WRONG_LENGTH + {"MESSAGEDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_WRONG_LENGTH", 46, 121}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_ERROR + {"MSGSIGDIGEST_ERROR", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR}, + #else + {"MSGSIGDIGEST_ERROR", 46, 172}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE + {"MSGSIGDIGEST_VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE}, + #else + {"MSGSIGDIGEST_VERIFICATION_FAILURE", 46, 162}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_WRONG_LENGTH + {"MSGSIGDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_WRONG_LENGTH}, + #else + {"MSGSIGDIGEST_WRONG_LENGTH", 46, 163}, + #endif + #ifdef CMS_R_NEED_ONE_SIGNER + {"NEED_ONE_SIGNER", ERR_LIB_CMS, CMS_R_NEED_ONE_SIGNER}, + #else + {"NEED_ONE_SIGNER", 46, 164}, + #endif + #ifdef CMS_R_NOT_A_SIGNED_RECEIPT + {"NOT_A_SIGNED_RECEIPT", ERR_LIB_CMS, CMS_R_NOT_A_SIGNED_RECEIPT}, + #else + {"NOT_A_SIGNED_RECEIPT", 46, 165}, + #endif + #ifdef CMS_R_NOT_ENCRYPTED_DATA + {"NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_NOT_ENCRYPTED_DATA}, + #else + {"NOT_ENCRYPTED_DATA", 46, 122}, + #endif + #ifdef CMS_R_NOT_KEK + {"NOT_KEK", ERR_LIB_CMS, CMS_R_NOT_KEK}, + #else + {"NOT_KEK", 46, 123}, + #endif + #ifdef CMS_R_NOT_KEY_AGREEMENT + {"NOT_KEY_AGREEMENT", ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT}, + #else + {"NOT_KEY_AGREEMENT", 46, 181}, + #endif + #ifdef CMS_R_NOT_KEY_TRANSPORT + {"NOT_KEY_TRANSPORT", ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT}, + #else + {"NOT_KEY_TRANSPORT", 46, 124}, + #endif + #ifdef CMS_R_NOT_PWRI + {"NOT_PWRI", ERR_LIB_CMS, CMS_R_NOT_PWRI}, + #else + {"NOT_PWRI", 46, 177}, + #endif + #ifdef CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 46, 125}, + #endif + #ifdef CMS_R_NO_CIPHER + {"NO_CIPHER", ERR_LIB_CMS, CMS_R_NO_CIPHER}, + #else + {"NO_CIPHER", 46, 126}, + #endif + #ifdef CMS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_CMS, CMS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 46, 127}, + #endif + #ifdef CMS_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 46, 173}, + #endif + #ifdef CMS_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 46, 128}, + #endif + #ifdef CMS_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_CMS, CMS_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 46, 129}, + #endif + #ifdef CMS_R_NO_KEY + {"NO_KEY", ERR_LIB_CMS, CMS_R_NO_KEY}, + #else + {"NO_KEY", 46, 130}, + #endif + #ifdef CMS_R_NO_KEY_OR_CERT + {"NO_KEY_OR_CERT", ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT}, + #else + {"NO_KEY_OR_CERT", 46, 174}, + #endif + #ifdef CMS_R_NO_MATCHING_DIGEST + {"NO_MATCHING_DIGEST", ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST}, + #else + {"NO_MATCHING_DIGEST", 46, 131}, + #endif + #ifdef CMS_R_NO_MATCHING_RECIPIENT + {"NO_MATCHING_RECIPIENT", ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT}, + #else + {"NO_MATCHING_RECIPIENT", 46, 132}, + #endif + #ifdef CMS_R_NO_MATCHING_SIGNATURE + {"NO_MATCHING_SIGNATURE", ERR_LIB_CMS, CMS_R_NO_MATCHING_SIGNATURE}, + #else + {"NO_MATCHING_SIGNATURE", 46, 166}, + #endif + #ifdef CMS_R_NO_MSGSIGDIGEST + {"NO_MSGSIGDIGEST", ERR_LIB_CMS, CMS_R_NO_MSGSIGDIGEST}, + #else + {"NO_MSGSIGDIGEST", 46, 167}, + #endif + #ifdef CMS_R_NO_PASSWORD + {"NO_PASSWORD", ERR_LIB_CMS, CMS_R_NO_PASSWORD}, + #else + {"NO_PASSWORD", 46, 178}, + #endif + #ifdef CMS_R_NO_PRIVATE_KEY + {"NO_PRIVATE_KEY", ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY}, + #else + {"NO_PRIVATE_KEY", 46, 133}, + #endif + #ifdef CMS_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 46, 134}, + #endif + #ifdef CMS_R_NO_RECEIPT_REQUEST + {"NO_RECEIPT_REQUEST", ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST}, + #else + {"NO_RECEIPT_REQUEST", 46, 168}, + #endif + #ifdef CMS_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_CMS, CMS_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 46, 135}, + #endif + #ifdef CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_CMS, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 46, 136}, + #endif + #ifdef CMS_R_RECEIPT_DECODE_ERROR + {"RECEIPT_DECODE_ERROR", ERR_LIB_CMS, CMS_R_RECEIPT_DECODE_ERROR}, + #else + {"RECEIPT_DECODE_ERROR", 46, 169}, + #endif + #ifdef CMS_R_RECIPIENT_ERROR + {"RECIPIENT_ERROR", ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR}, + #else + {"RECIPIENT_ERROR", 46, 137}, + #endif + #ifdef CMS_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 46, 138}, + #endif + #ifdef CMS_R_SIGNFINAL_ERROR + {"SIGNFINAL_ERROR", ERR_LIB_CMS, CMS_R_SIGNFINAL_ERROR}, + #else + {"SIGNFINAL_ERROR", 46, 139}, + #endif + #ifdef CMS_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 46, 140}, + #endif + #ifdef CMS_R_STORE_INIT_ERROR + {"STORE_INIT_ERROR", ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR}, + #else + {"STORE_INIT_ERROR", 46, 141}, + #endif + #ifdef CMS_R_TYPE_NOT_COMPRESSED_DATA + {"TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA}, + #else + {"TYPE_NOT_COMPRESSED_DATA", 46, 142}, + #endif + #ifdef CMS_R_TYPE_NOT_DATA + {"TYPE_NOT_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA}, + #else + {"TYPE_NOT_DATA", 46, 143}, + #endif + #ifdef CMS_R_TYPE_NOT_DIGESTED_DATA + {"TYPE_NOT_DIGESTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA}, + #else + {"TYPE_NOT_DIGESTED_DATA", 46, 144}, + #endif + #ifdef CMS_R_TYPE_NOT_ENCRYPTED_DATA + {"TYPE_NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA}, + #else + {"TYPE_NOT_ENCRYPTED_DATA", 46, 145}, + #endif + #ifdef CMS_R_TYPE_NOT_ENVELOPED_DATA + {"TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA}, + #else + {"TYPE_NOT_ENVELOPED_DATA", 46, 146}, + #endif + #ifdef CMS_R_UNABLE_TO_FINALIZE_CONTEXT + {"UNABLE_TO_FINALIZE_CONTEXT", ERR_LIB_CMS, CMS_R_UNABLE_TO_FINALIZE_CONTEXT}, + #else + {"UNABLE_TO_FINALIZE_CONTEXT", 46, 147}, + #endif + #ifdef CMS_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 46, 148}, + #endif + #ifdef CMS_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 46, 149}, + #endif + #ifdef CMS_R_UNKNOWN_ID + {"UNKNOWN_ID", ERR_LIB_CMS, CMS_R_UNKNOWN_ID}, + #else + {"UNKNOWN_ID", 46, 150}, + #endif + #ifdef CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM + {"UNSUPPORTED_COMPRESSION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM}, + #else + {"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151}, + #endif + #ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 46, 152}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEK_ALGORITHM + {"UNSUPPORTED_KEK_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEK_ALGORITHM}, + #else + {"UNSUPPORTED_KEK_ALGORITHM", 46, 153}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM}, + #else + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", 46, 179}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + {"UNSUPPORTED_RECIPIENTINFO_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE}, + #else + {"UNSUPPORTED_RECIPIENTINFO_TYPE", 46, 155}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENT_TYPE + {"UNSUPPORTED_RECIPIENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENT_TYPE}, + #else + {"UNSUPPORTED_RECIPIENT_TYPE", 46, 154}, + #endif + #ifdef CMS_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 46, 156}, + #endif + #ifdef CMS_R_UNWRAP_ERROR + {"UNWRAP_ERROR", ERR_LIB_CMS, CMS_R_UNWRAP_ERROR}, + #else + {"UNWRAP_ERROR", 46, 157}, + #endif + #ifdef CMS_R_UNWRAP_FAILURE + {"UNWRAP_FAILURE", ERR_LIB_CMS, CMS_R_UNWRAP_FAILURE}, + #else + {"UNWRAP_FAILURE", 46, 180}, + #endif + #ifdef CMS_R_VERIFICATION_FAILURE + {"VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE}, + #else + {"VERIFICATION_FAILURE", 46, 158}, + #endif + #ifdef CMS_R_WRAP_ERROR + {"WRAP_ERROR", ERR_LIB_CMS, CMS_R_WRAP_ERROR}, + #else + {"WRAP_ERROR", 46, 159}, + #endif + #ifdef COMP_R_ZLIB_DEFLATE_ERROR + {"ZLIB_DEFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR}, + #else + {"ZLIB_DEFLATE_ERROR", 41, 99}, + #endif + #ifdef COMP_R_ZLIB_INFLATE_ERROR + {"ZLIB_INFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR}, + #else + {"ZLIB_INFLATE_ERROR", 41, 100}, + #endif + #ifdef COMP_R_ZLIB_NOT_SUPPORTED + {"ZLIB_NOT_SUPPORTED", ERR_LIB_COMP, COMP_R_ZLIB_NOT_SUPPORTED}, + #else + {"ZLIB_NOT_SUPPORTED", 41, 101}, + #endif + #ifdef CONF_R_ERROR_LOADING_DSO + {"ERROR_LOADING_DSO", ERR_LIB_CONF, CONF_R_ERROR_LOADING_DSO}, + #else + {"ERROR_LOADING_DSO", 14, 110}, + #endif + #ifdef CONF_R_LIST_CANNOT_BE_NULL + {"LIST_CANNOT_BE_NULL", ERR_LIB_CONF, CONF_R_LIST_CANNOT_BE_NULL}, + #else + {"LIST_CANNOT_BE_NULL", 14, 115}, + #endif + #ifdef CONF_R_MISSING_CLOSE_SQUARE_BRACKET + {"MISSING_CLOSE_SQUARE_BRACKET", ERR_LIB_CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET}, + #else + {"MISSING_CLOSE_SQUARE_BRACKET", 14, 100}, + #endif + #ifdef CONF_R_MISSING_EQUAL_SIGN + {"MISSING_EQUAL_SIGN", ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN}, + #else + {"MISSING_EQUAL_SIGN", 14, 101}, + #endif + #ifdef CONF_R_MISSING_INIT_FUNCTION + {"MISSING_INIT_FUNCTION", ERR_LIB_CONF, CONF_R_MISSING_INIT_FUNCTION}, + #else + {"MISSING_INIT_FUNCTION", 14, 112}, + #endif + #ifdef CONF_R_MODULE_INITIALIZATION_ERROR + {"MODULE_INITIALIZATION_ERROR", ERR_LIB_CONF, CONF_R_MODULE_INITIALIZATION_ERROR}, + #else + {"MODULE_INITIALIZATION_ERROR", 14, 109}, + #endif + #ifdef CONF_R_NO_CLOSE_BRACE + {"NO_CLOSE_BRACE", ERR_LIB_CONF, CONF_R_NO_CLOSE_BRACE}, + #else + {"NO_CLOSE_BRACE", 14, 102}, + #endif + #ifdef CONF_R_NO_CONF + {"NO_CONF", ERR_LIB_CONF, CONF_R_NO_CONF}, + #else + {"NO_CONF", 14, 105}, + #endif + #ifdef CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", ERR_LIB_CONF, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE}, + #else + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", 14, 106}, + #endif + #ifdef CONF_R_NO_SECTION + {"NO_SECTION", ERR_LIB_CONF, CONF_R_NO_SECTION}, + #else + {"NO_SECTION", 14, 107}, + #endif + #ifdef CONF_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_CONF, CONF_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 14, 114}, + #endif + #ifdef CONF_R_NO_VALUE + {"NO_VALUE", ERR_LIB_CONF, CONF_R_NO_VALUE}, + #else + {"NO_VALUE", 14, 108}, + #endif + #ifdef CONF_R_NUMBER_TOO_LARGE + {"NUMBER_TOO_LARGE", ERR_LIB_CONF, CONF_R_NUMBER_TOO_LARGE}, + #else + {"NUMBER_TOO_LARGE", 14, 121}, + #endif + #ifdef CONF_R_RECURSIVE_DIRECTORY_INCLUDE + {"RECURSIVE_DIRECTORY_INCLUDE", ERR_LIB_CONF, CONF_R_RECURSIVE_DIRECTORY_INCLUDE}, + #else + {"RECURSIVE_DIRECTORY_INCLUDE", 14, 111}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 14, 117}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #else + {"SSL_COMMAND_SECTION_NOT_FOUND", 14, 118}, + #endif + #ifdef CONF_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 14, 119}, + #endif + #ifdef CONF_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_SECTION_NOT_FOUND}, + #else + {"SSL_SECTION_NOT_FOUND", 14, 120}, + #endif + #ifdef CONF_R_UNABLE_TO_CREATE_NEW_SECTION + {"UNABLE_TO_CREATE_NEW_SECTION", ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION}, + #else + {"UNABLE_TO_CREATE_NEW_SECTION", 14, 103}, + #endif + #ifdef CONF_R_UNKNOWN_MODULE_NAME + {"UNKNOWN_MODULE_NAME", ERR_LIB_CONF, CONF_R_UNKNOWN_MODULE_NAME}, + #else + {"UNKNOWN_MODULE_NAME", 14, 113}, + #endif + #ifdef CONF_R_VARIABLE_EXPANSION_TOO_LONG + {"VARIABLE_EXPANSION_TOO_LONG", ERR_LIB_CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG}, + #else + {"VARIABLE_EXPANSION_TOO_LONG", 14, 116}, + #endif + #ifdef CONF_R_VARIABLE_HAS_NO_VALUE + {"VARIABLE_HAS_NO_VALUE", ERR_LIB_CONF, CONF_R_VARIABLE_HAS_NO_VALUE}, + #else + {"VARIABLE_HAS_NO_VALUE", 14, 104}, + #endif + #ifdef CRYPTO_R_FIPS_MODE_NOT_SUPPORTED + {"FIPS_MODE_NOT_SUPPORTED", ERR_LIB_CRYPTO, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED}, + #else + {"FIPS_MODE_NOT_SUPPORTED", 15, 101}, + #endif + #ifdef CRYPTO_R_ILLEGAL_HEX_DIGIT + {"ILLEGAL_HEX_DIGIT", ERR_LIB_CRYPTO, CRYPTO_R_ILLEGAL_HEX_DIGIT}, + #else + {"ILLEGAL_HEX_DIGIT", 15, 102}, + #endif + #ifdef CRYPTO_R_ODD_NUMBER_OF_DIGITS + {"ODD_NUMBER_OF_DIGITS", ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS}, + #else + {"ODD_NUMBER_OF_DIGITS", 15, 103}, + #endif + #ifdef CT_R_BASE64_DECODE_ERROR + {"BASE64_DECODE_ERROR", ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR}, + #else + {"BASE64_DECODE_ERROR", 50, 108}, + #endif + #ifdef CT_R_INVALID_LOG_ID_LENGTH + {"INVALID_LOG_ID_LENGTH", ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH}, + #else + {"INVALID_LOG_ID_LENGTH", 50, 100}, + #endif + #ifdef CT_R_LOG_CONF_INVALID + {"LOG_CONF_INVALID", ERR_LIB_CT, CT_R_LOG_CONF_INVALID}, + #else + {"LOG_CONF_INVALID", 50, 109}, + #endif + #ifdef CT_R_LOG_CONF_INVALID_KEY + {"LOG_CONF_INVALID_KEY", ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY}, + #else + {"LOG_CONF_INVALID_KEY", 50, 110}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_DESCRIPTION + {"LOG_CONF_MISSING_DESCRIPTION", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_DESCRIPTION}, + #else + {"LOG_CONF_MISSING_DESCRIPTION", 50, 111}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_KEY + {"LOG_CONF_MISSING_KEY", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_KEY}, + #else + {"LOG_CONF_MISSING_KEY", 50, 112}, + #endif + #ifdef CT_R_LOG_KEY_INVALID + {"LOG_KEY_INVALID", ERR_LIB_CT, CT_R_LOG_KEY_INVALID}, + #else + {"LOG_KEY_INVALID", 50, 113}, + #endif + #ifdef CT_R_SCT_FUTURE_TIMESTAMP + {"SCT_FUTURE_TIMESTAMP", ERR_LIB_CT, CT_R_SCT_FUTURE_TIMESTAMP}, + #else + {"SCT_FUTURE_TIMESTAMP", 50, 116}, + #endif + #ifdef CT_R_SCT_INVALID + {"SCT_INVALID", ERR_LIB_CT, CT_R_SCT_INVALID}, + #else + {"SCT_INVALID", 50, 104}, + #endif + #ifdef CT_R_SCT_INVALID_SIGNATURE + {"SCT_INVALID_SIGNATURE", ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE}, + #else + {"SCT_INVALID_SIGNATURE", 50, 107}, + #endif + #ifdef CT_R_SCT_LIST_INVALID + {"SCT_LIST_INVALID", ERR_LIB_CT, CT_R_SCT_LIST_INVALID}, + #else + {"SCT_LIST_INVALID", 50, 105}, + #endif + #ifdef CT_R_SCT_LOG_ID_MISMATCH + {"SCT_LOG_ID_MISMATCH", ERR_LIB_CT, CT_R_SCT_LOG_ID_MISMATCH}, + #else + {"SCT_LOG_ID_MISMATCH", 50, 114}, + #endif + #ifdef CT_R_SCT_NOT_SET + {"SCT_NOT_SET", ERR_LIB_CT, CT_R_SCT_NOT_SET}, + #else + {"SCT_NOT_SET", 50, 106}, + #endif + #ifdef CT_R_SCT_UNSUPPORTED_VERSION + {"SCT_UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_SCT_UNSUPPORTED_VERSION}, + #else + {"SCT_UNSUPPORTED_VERSION", 50, 115}, + #endif + #ifdef CT_R_UNRECOGNIZED_SIGNATURE_NID + {"UNRECOGNIZED_SIGNATURE_NID", ERR_LIB_CT, CT_R_UNRECOGNIZED_SIGNATURE_NID}, + #else + {"UNRECOGNIZED_SIGNATURE_NID", 50, 101}, + #endif + #ifdef CT_R_UNSUPPORTED_ENTRY_TYPE + {"UNSUPPORTED_ENTRY_TYPE", ERR_LIB_CT, CT_R_UNSUPPORTED_ENTRY_TYPE}, + #else + {"UNSUPPORTED_ENTRY_TYPE", 50, 102}, + #endif + #ifdef CT_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 50, 103}, + #endif + #ifdef DH_R_BAD_GENERATOR + {"BAD_GENERATOR", ERR_LIB_DH, DH_R_BAD_GENERATOR}, + #else + {"BAD_GENERATOR", 5, 101}, + #endif + #ifdef DH_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DH, DH_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 5, 109}, + #endif + #ifdef DH_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DH, DH_R_BN_ERROR}, + #else + {"BN_ERROR", 5, 106}, + #endif + #ifdef DH_R_CHECK_INVALID_J_VALUE + {"CHECK_INVALID_J_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_J_VALUE}, + #else + {"CHECK_INVALID_J_VALUE", 5, 115}, + #endif + #ifdef DH_R_CHECK_INVALID_Q_VALUE + {"CHECK_INVALID_Q_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_Q_VALUE}, + #else + {"CHECK_INVALID_Q_VALUE", 5, 116}, + #endif + #ifdef DH_R_CHECK_PUBKEY_INVALID + {"CHECK_PUBKEY_INVALID", ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID}, + #else + {"CHECK_PUBKEY_INVALID", 5, 122}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_LARGE + {"CHECK_PUBKEY_TOO_LARGE", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_LARGE}, + #else + {"CHECK_PUBKEY_TOO_LARGE", 5, 123}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_SMALL + {"CHECK_PUBKEY_TOO_SMALL", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_SMALL}, + #else + {"CHECK_PUBKEY_TOO_SMALL", 5, 124}, + #endif + #ifdef DH_R_CHECK_P_NOT_PRIME + {"CHECK_P_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME}, + #else + {"CHECK_P_NOT_PRIME", 5, 117}, + #endif + #ifdef DH_R_CHECK_P_NOT_SAFE_PRIME + {"CHECK_P_NOT_SAFE_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_SAFE_PRIME}, + #else + {"CHECK_P_NOT_SAFE_PRIME", 5, 118}, + #endif + #ifdef DH_R_CHECK_Q_NOT_PRIME + {"CHECK_Q_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_Q_NOT_PRIME}, + #else + {"CHECK_Q_NOT_PRIME", 5, 119}, + #endif + #ifdef DH_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DH, DH_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 5, 104}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NAME + {"INVALID_PARAMETER_NAME", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME}, + #else + {"INVALID_PARAMETER_NAME", 5, 110}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NID + {"INVALID_PARAMETER_NID", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID}, + #else + {"INVALID_PARAMETER_NID", 5, 114}, + #endif + #ifdef DH_R_INVALID_PUBKEY + {"INVALID_PUBKEY", ERR_LIB_DH, DH_R_INVALID_PUBKEY}, + #else + {"INVALID_PUBKEY", 5, 102}, + #endif + #ifdef DH_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_DH, DH_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 5, 112}, + #endif + #ifdef DH_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_DH, DH_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 5, 108}, + #endif + #ifdef DH_R_MISSING_PUBKEY + {"MISSING_PUBKEY", ERR_LIB_DH, DH_R_MISSING_PUBKEY}, + #else + {"MISSING_PUBKEY", 5, 125}, + #endif + #ifdef DH_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 5, 103}, + #endif + #ifdef DH_R_NOT_SUITABLE_GENERATOR + {"NOT_SUITABLE_GENERATOR", ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR}, + #else + {"NOT_SUITABLE_GENERATOR", 5, 120}, + #endif + #ifdef DH_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DH, DH_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 5, 107}, + #endif + #ifdef DH_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_DH, DH_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 5, 100}, + #endif + #ifdef DH_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DH, DH_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 5, 105}, + #endif + #ifdef DH_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_DH, DH_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 5, 111}, + #endif + #ifdef DH_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_DH, DH_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 5, 113}, + #endif + #ifdef DH_R_UNABLE_TO_CHECK_GENERATOR + {"UNABLE_TO_CHECK_GENERATOR", ERR_LIB_DH, DH_R_UNABLE_TO_CHECK_GENERATOR}, + #else + {"UNABLE_TO_CHECK_GENERATOR", 5, 121}, + #endif + #ifdef DSA_R_BAD_Q_VALUE + {"BAD_Q_VALUE", ERR_LIB_DSA, DSA_R_BAD_Q_VALUE}, + #else + {"BAD_Q_VALUE", 10, 102}, + #endif + #ifdef DSA_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DSA, DSA_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 10, 108}, + #endif + #ifdef DSA_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DSA, DSA_R_BN_ERROR}, + #else + {"BN_ERROR", 10, 109}, + #endif + #ifdef DSA_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DSA, DSA_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 10, 104}, + #endif + #ifdef DSA_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 10, 106}, + #endif + #ifdef DSA_R_INVALID_PARAMETERS + {"INVALID_PARAMETERS", ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS}, + #else + {"INVALID_PARAMETERS", 10, 112}, + #endif + #ifdef DSA_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 10, 101}, + #endif + #ifdef DSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_DSA, DSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 10, 111}, + #endif + #ifdef DSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 10, 103}, + #endif + #ifdef DSA_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 10, 107}, + #endif + #ifdef DSA_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 10, 105}, + #endif + #ifdef DSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_DSA, DSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 10, 113}, + #endif + #ifdef DSA_R_SEED_LEN_SMALL + {"SEED_LEN_SMALL", ERR_LIB_DSA, DSA_R_SEED_LEN_SMALL}, + #else + {"SEED_LEN_SMALL", 10, 110}, + #endif + #ifdef EC_R_ASN1_ERROR + {"ASN1_ERROR", ERR_LIB_EC, EC_R_ASN1_ERROR}, + #else + {"ASN1_ERROR", 16, 115}, + #endif + #ifdef EC_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_EC, EC_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 16, 156}, + #endif + #ifdef EC_R_BIGNUM_OUT_OF_RANGE + {"BIGNUM_OUT_OF_RANGE", ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE}, + #else + {"BIGNUM_OUT_OF_RANGE", 16, 144}, + #endif + #ifdef EC_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 16, 100}, + #endif + #ifdef EC_R_CANNOT_INVERT + {"CANNOT_INVERT", ERR_LIB_EC, EC_R_CANNOT_INVERT}, + #else + {"CANNOT_INVERT", 16, 165}, + #endif + #ifdef EC_R_COORDINATES_OUT_OF_RANGE + {"COORDINATES_OUT_OF_RANGE", ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE}, + #else + {"COORDINATES_OUT_OF_RANGE", 16, 146}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_ECDH + {"CURVE_DOES_NOT_SUPPORT_ECDH", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH}, + #else + {"CURVE_DOES_NOT_SUPPORT_ECDH", 16, 160}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING + {"CURVE_DOES_NOT_SUPPORT_SIGNING", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING}, + #else + {"CURVE_DOES_NOT_SUPPORT_SIGNING", 16, 159}, + #endif + #ifdef EC_R_D2I_ECPKPARAMETERS_FAILURE + {"D2I_ECPKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_D2I_ECPKPARAMETERS_FAILURE}, + #else + {"D2I_ECPKPARAMETERS_FAILURE", 16, 117}, + #endif + #ifdef EC_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EC, EC_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 16, 142}, + #endif + #ifdef EC_R_DISCRIMINANT_IS_ZERO + {"DISCRIMINANT_IS_ZERO", ERR_LIB_EC, EC_R_DISCRIMINANT_IS_ZERO}, + #else + {"DISCRIMINANT_IS_ZERO", 16, 118}, + #endif + #ifdef EC_R_EC_GROUP_NEW_BY_NAME_FAILURE + {"EC_GROUP_NEW_BY_NAME_FAILURE", ERR_LIB_EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE}, + #else + {"EC_GROUP_NEW_BY_NAME_FAILURE", 16, 119}, + #endif + #ifdef EC_R_FIELD_TOO_LARGE + {"FIELD_TOO_LARGE", ERR_LIB_EC, EC_R_FIELD_TOO_LARGE}, + #else + {"FIELD_TOO_LARGE", 16, 143}, + #endif + #ifdef EC_R_GF2M_NOT_SUPPORTED + {"GF2M_NOT_SUPPORTED", ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED}, + #else + {"GF2M_NOT_SUPPORTED", 16, 147}, + #endif + #ifdef EC_R_GROUP2PKPARAMETERS_FAILURE + {"GROUP2PKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_GROUP2PKPARAMETERS_FAILURE}, + #else + {"GROUP2PKPARAMETERS_FAILURE", 16, 120}, + #endif + #ifdef EC_R_I2D_ECPKPARAMETERS_FAILURE + {"I2D_ECPKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_I2D_ECPKPARAMETERS_FAILURE}, + #else + {"I2D_ECPKPARAMETERS_FAILURE", 16, 121}, + #endif + #ifdef EC_R_INCOMPATIBLE_OBJECTS + {"INCOMPATIBLE_OBJECTS", ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS}, + #else + {"INCOMPATIBLE_OBJECTS", 16, 101}, + #endif + #ifdef EC_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_EC, EC_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 16, 112}, + #endif + #ifdef EC_R_INVALID_COMPRESSED_POINT + {"INVALID_COMPRESSED_POINT", ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT}, + #else + {"INVALID_COMPRESSED_POINT", 16, 110}, + #endif + #ifdef EC_R_INVALID_COMPRESSION_BIT + {"INVALID_COMPRESSION_BIT", ERR_LIB_EC, EC_R_INVALID_COMPRESSION_BIT}, + #else + {"INVALID_COMPRESSION_BIT", 16, 109}, + #endif + #ifdef EC_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_EC, EC_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 16, 141}, + #endif + #ifdef EC_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EC, EC_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 16, 151}, + #endif + #ifdef EC_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 16, 138}, + #endif + #ifdef EC_R_INVALID_ENCODING + {"INVALID_ENCODING", ERR_LIB_EC, EC_R_INVALID_ENCODING}, + #else + {"INVALID_ENCODING", 16, 102}, + #endif + #ifdef EC_R_INVALID_FIELD + {"INVALID_FIELD", ERR_LIB_EC, EC_R_INVALID_FIELD}, + #else + {"INVALID_FIELD", 16, 103}, + #endif + #ifdef EC_R_INVALID_FORM + {"INVALID_FORM", ERR_LIB_EC, EC_R_INVALID_FORM}, + #else + {"INVALID_FORM", 16, 104}, + #endif + #ifdef EC_R_INVALID_GROUP_ORDER + {"INVALID_GROUP_ORDER", ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER}, + #else + {"INVALID_GROUP_ORDER", 16, 122}, + #endif + #ifdef EC_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EC, EC_R_INVALID_KEY}, + #else + {"INVALID_KEY", 16, 116}, + #endif + #ifdef EC_R_INVALID_OUTPUT_LENGTH + {"INVALID_OUTPUT_LENGTH", ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH}, + #else + {"INVALID_OUTPUT_LENGTH", 16, 161}, + #endif + #ifdef EC_R_INVALID_PEER_KEY + {"INVALID_PEER_KEY", ERR_LIB_EC, EC_R_INVALID_PEER_KEY}, + #else + {"INVALID_PEER_KEY", 16, 133}, + #endif + #ifdef EC_R_INVALID_PENTANOMIAL_BASIS + {"INVALID_PENTANOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_PENTANOMIAL_BASIS}, + #else + {"INVALID_PENTANOMIAL_BASIS", 16, 132}, + #endif + #ifdef EC_R_INVALID_PRIVATE_KEY + {"INVALID_PRIVATE_KEY", ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY}, + #else + {"INVALID_PRIVATE_KEY", 16, 123}, + #endif + #ifdef EC_R_INVALID_TRINOMIAL_BASIS + {"INVALID_TRINOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_TRINOMIAL_BASIS}, + #else + {"INVALID_TRINOMIAL_BASIS", 16, 137}, + #endif + #ifdef EC_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_EC, EC_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 16, 148}, + #endif + #ifdef EC_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_EC, EC_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 16, 140}, + #endif + #ifdef EC_R_LADDER_POST_FAILURE + {"LADDER_POST_FAILURE", ERR_LIB_EC, EC_R_LADDER_POST_FAILURE}, + #else + {"LADDER_POST_FAILURE", 16, 136}, + #endif + #ifdef EC_R_LADDER_PRE_FAILURE + {"LADDER_PRE_FAILURE", ERR_LIB_EC, EC_R_LADDER_PRE_FAILURE}, + #else + {"LADDER_PRE_FAILURE", 16, 153}, + #endif + #ifdef EC_R_LADDER_STEP_FAILURE + {"LADDER_STEP_FAILURE", ERR_LIB_EC, EC_R_LADDER_STEP_FAILURE}, + #else + {"LADDER_STEP_FAILURE", 16, 162}, + #endif + #ifdef EC_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EC, EC_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 16, 124}, + #endif + #ifdef EC_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 16, 125}, + #endif + #ifdef EC_R_NEED_NEW_SETUP_VALUES + {"NEED_NEW_SETUP_VALUES", ERR_LIB_EC, EC_R_NEED_NEW_SETUP_VALUES}, + #else + {"NEED_NEW_SETUP_VALUES", 16, 157}, + #endif + #ifdef EC_R_NOT_A_NIST_PRIME + {"NOT_A_NIST_PRIME", ERR_LIB_EC, EC_R_NOT_A_NIST_PRIME}, + #else + {"NOT_A_NIST_PRIME", 16, 135}, + #endif + #ifdef EC_R_NOT_IMPLEMENTED + {"NOT_IMPLEMENTED", ERR_LIB_EC, EC_R_NOT_IMPLEMENTED}, + #else + {"NOT_IMPLEMENTED", 16, 126}, + #endif + #ifdef EC_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_EC, EC_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 16, 111}, + #endif + #ifdef EC_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_EC, EC_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 16, 139}, + #endif + #ifdef EC_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_EC, EC_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 16, 154}, + #endif + #ifdef EC_R_OPERATION_NOT_SUPPORTED + {"OPERATION_NOT_SUPPORTED", ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED}, + #else + {"OPERATION_NOT_SUPPORTED", 16, 152}, + #endif + #ifdef EC_R_PASSED_NULL_PARAMETER + {"PASSED_NULL_PARAMETER", ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER}, + #else + {"PASSED_NULL_PARAMETER", 16, 134}, + #endif + #ifdef EC_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_EC, EC_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 16, 149}, + #endif + #ifdef EC_R_PKPARAMETERS2GROUP_FAILURE + {"PKPARAMETERS2GROUP_FAILURE", ERR_LIB_EC, EC_R_PKPARAMETERS2GROUP_FAILURE}, + #else + {"PKPARAMETERS2GROUP_FAILURE", 16, 127}, + #endif + #ifdef EC_R_POINT_ARITHMETIC_FAILURE + {"POINT_ARITHMETIC_FAILURE", ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE}, + #else + {"POINT_ARITHMETIC_FAILURE", 16, 155}, + #endif + #ifdef EC_R_POINT_AT_INFINITY + {"POINT_AT_INFINITY", ERR_LIB_EC, EC_R_POINT_AT_INFINITY}, + #else + {"POINT_AT_INFINITY", 16, 106}, + #endif + #ifdef EC_R_POINT_COORDINATES_BLIND_FAILURE + {"POINT_COORDINATES_BLIND_FAILURE", ERR_LIB_EC, EC_R_POINT_COORDINATES_BLIND_FAILURE}, + #else + {"POINT_COORDINATES_BLIND_FAILURE", 16, 163}, + #endif + #ifdef EC_R_POINT_IS_NOT_ON_CURVE + {"POINT_IS_NOT_ON_CURVE", ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE}, + #else + {"POINT_IS_NOT_ON_CURVE", 16, 107}, + #endif + #ifdef EC_R_RANDOM_NUMBER_GENERATION_FAILED + {"RANDOM_NUMBER_GENERATION_FAILED", ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED}, + #else + {"RANDOM_NUMBER_GENERATION_FAILED", 16, 158}, + #endif + #ifdef EC_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_EC, EC_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 16, 150}, + #endif + #ifdef EC_R_SLOT_FULL + {"SLOT_FULL", ERR_LIB_EC, EC_R_SLOT_FULL}, + #else + {"SLOT_FULL", 16, 108}, + #endif + #ifdef EC_R_UNDEFINED_GENERATOR + {"UNDEFINED_GENERATOR", ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR}, + #else + {"UNDEFINED_GENERATOR", 16, 113}, + #endif + #ifdef EC_R_UNDEFINED_ORDER + {"UNDEFINED_ORDER", ERR_LIB_EC, EC_R_UNDEFINED_ORDER}, + #else + {"UNDEFINED_ORDER", 16, 128}, + #endif + #ifdef EC_R_UNKNOWN_COFACTOR + {"UNKNOWN_COFACTOR", ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR}, + #else + {"UNKNOWN_COFACTOR", 16, 164}, + #endif + #ifdef EC_R_UNKNOWN_GROUP + {"UNKNOWN_GROUP", ERR_LIB_EC, EC_R_UNKNOWN_GROUP}, + #else + {"UNKNOWN_GROUP", 16, 129}, + #endif + #ifdef EC_R_UNKNOWN_ORDER + {"UNKNOWN_ORDER", ERR_LIB_EC, EC_R_UNKNOWN_ORDER}, + #else + {"UNKNOWN_ORDER", 16, 114}, + #endif + #ifdef EC_R_UNSUPPORTED_FIELD + {"UNSUPPORTED_FIELD", ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD}, + #else + {"UNSUPPORTED_FIELD", 16, 131}, + #endif + #ifdef EC_R_WRONG_CURVE_PARAMETERS + {"WRONG_CURVE_PARAMETERS", ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS}, + #else + {"WRONG_CURVE_PARAMETERS", 16, 145}, + #endif + #ifdef EC_R_WRONG_ORDER + {"WRONG_ORDER", ERR_LIB_EC, EC_R_WRONG_ORDER}, + #else + {"WRONG_ORDER", 16, 130}, + #endif + #ifdef ENGINE_R_ALREADY_LOADED + {"ALREADY_LOADED", ERR_LIB_ENGINE, ENGINE_R_ALREADY_LOADED}, + #else + {"ALREADY_LOADED", 38, 100}, + #endif + #ifdef ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER + {"ARGUMENT_IS_NOT_A_NUMBER", ERR_LIB_ENGINE, ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER}, + #else + {"ARGUMENT_IS_NOT_A_NUMBER", 38, 133}, + #endif + #ifdef ENGINE_R_CMD_NOT_EXECUTABLE + {"CMD_NOT_EXECUTABLE", ERR_LIB_ENGINE, ENGINE_R_CMD_NOT_EXECUTABLE}, + #else + {"CMD_NOT_EXECUTABLE", 38, 134}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_INPUT + {"COMMAND_TAKES_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_INPUT}, + #else + {"COMMAND_TAKES_INPUT", 38, 135}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_NO_INPUT + {"COMMAND_TAKES_NO_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_NO_INPUT}, + #else + {"COMMAND_TAKES_NO_INPUT", 38, 136}, + #endif + #ifdef ENGINE_R_CONFLICTING_ENGINE_ID + {"CONFLICTING_ENGINE_ID", ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID}, + #else + {"CONFLICTING_ENGINE_ID", 38, 103}, + #endif + #ifdef ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED + {"CTRL_COMMAND_NOT_IMPLEMENTED", ERR_LIB_ENGINE, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED}, + #else + {"CTRL_COMMAND_NOT_IMPLEMENTED", 38, 119}, + #endif + #ifdef ENGINE_R_DSO_FAILURE + {"DSO_FAILURE", ERR_LIB_ENGINE, ENGINE_R_DSO_FAILURE}, + #else + {"DSO_FAILURE", 38, 104}, + #endif + #ifdef ENGINE_R_DSO_NOT_FOUND + {"DSO_NOT_FOUND", ERR_LIB_ENGINE, ENGINE_R_DSO_NOT_FOUND}, + #else + {"DSO_NOT_FOUND", 38, 132}, + #endif + #ifdef ENGINE_R_ENGINES_SECTION_ERROR + {"ENGINES_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINES_SECTION_ERROR}, + #else + {"ENGINES_SECTION_ERROR", 38, 148}, + #endif + #ifdef ENGINE_R_ENGINE_CONFIGURATION_ERROR + {"ENGINE_CONFIGURATION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR}, + #else + {"ENGINE_CONFIGURATION_ERROR", 38, 102}, + #endif + #ifdef ENGINE_R_ENGINE_IS_NOT_IN_LIST + {"ENGINE_IS_NOT_IN_LIST", ERR_LIB_ENGINE, ENGINE_R_ENGINE_IS_NOT_IN_LIST}, + #else + {"ENGINE_IS_NOT_IN_LIST", 38, 105}, + #endif + #ifdef ENGINE_R_ENGINE_SECTION_ERROR + {"ENGINE_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_SECTION_ERROR}, + #else + {"ENGINE_SECTION_ERROR", 38, 149}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PRIVATE_KEY + {"FAILED_LOADING_PRIVATE_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PRIVATE_KEY}, + #else + {"FAILED_LOADING_PRIVATE_KEY", 38, 128}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PUBLIC_KEY + {"FAILED_LOADING_PUBLIC_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PUBLIC_KEY}, + #else + {"FAILED_LOADING_PUBLIC_KEY", 38, 129}, + #endif + #ifdef ENGINE_R_FINISH_FAILED + {"FINISH_FAILED", ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED}, + #else + {"FINISH_FAILED", 38, 106}, + #endif + #ifdef ENGINE_R_ID_OR_NAME_MISSING + {"ID_OR_NAME_MISSING", ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING}, + #else + {"ID_OR_NAME_MISSING", 38, 108}, + #endif + #ifdef ENGINE_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ENGINE, ENGINE_R_INIT_FAILED}, + #else + {"INIT_FAILED", 38, 109}, + #endif + #ifdef ENGINE_R_INTERNAL_LIST_ERROR + {"INTERNAL_LIST_ERROR", ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR}, + #else + {"INTERNAL_LIST_ERROR", 38, 110}, + #endif + #ifdef ENGINE_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_ENGINE, ENGINE_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 38, 143}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NAME + {"INVALID_CMD_NAME", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NAME}, + #else + {"INVALID_CMD_NAME", 38, 137}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NUMBER + {"INVALID_CMD_NUMBER", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NUMBER}, + #else + {"INVALID_CMD_NUMBER", 38, 138}, + #endif + #ifdef ENGINE_R_INVALID_INIT_VALUE + {"INVALID_INIT_VALUE", ERR_LIB_ENGINE, ENGINE_R_INVALID_INIT_VALUE}, + #else + {"INVALID_INIT_VALUE", 38, 151}, + #endif + #ifdef ENGINE_R_INVALID_STRING + {"INVALID_STRING", ERR_LIB_ENGINE, ENGINE_R_INVALID_STRING}, + #else + {"INVALID_STRING", 38, 150}, + #endif + #ifdef ENGINE_R_NOT_INITIALISED + {"NOT_INITIALISED", ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED}, + #else + {"NOT_INITIALISED", 38, 117}, + #endif + #ifdef ENGINE_R_NOT_LOADED + {"NOT_LOADED", ERR_LIB_ENGINE, ENGINE_R_NOT_LOADED}, + #else + {"NOT_LOADED", 38, 112}, + #endif + #ifdef ENGINE_R_NO_CONTROL_FUNCTION + {"NO_CONTROL_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_CONTROL_FUNCTION}, + #else + {"NO_CONTROL_FUNCTION", 38, 120}, + #endif + #ifdef ENGINE_R_NO_INDEX + {"NO_INDEX", ERR_LIB_ENGINE, ENGINE_R_NO_INDEX}, + #else + {"NO_INDEX", 38, 144}, + #endif + #ifdef ENGINE_R_NO_LOAD_FUNCTION + {"NO_LOAD_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION}, + #else + {"NO_LOAD_FUNCTION", 38, 125}, + #endif + #ifdef ENGINE_R_NO_REFERENCE + {"NO_REFERENCE", ERR_LIB_ENGINE, ENGINE_R_NO_REFERENCE}, + #else + {"NO_REFERENCE", 38, 130}, + #endif + #ifdef ENGINE_R_NO_SUCH_ENGINE + {"NO_SUCH_ENGINE", ERR_LIB_ENGINE, ENGINE_R_NO_SUCH_ENGINE}, + #else + {"NO_SUCH_ENGINE", 38, 116}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_CIPHER + {"UNIMPLEMENTED_CIPHER", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_CIPHER}, + #else + {"UNIMPLEMENTED_CIPHER", 38, 146}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_DIGEST + {"UNIMPLEMENTED_DIGEST", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_DIGEST}, + #else + {"UNIMPLEMENTED_DIGEST", 38, 147}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD}, + #else + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", 38, 101}, + #endif + #ifdef ENGINE_R_VERSION_INCOMPATIBILITY + {"VERSION_INCOMPATIBILITY", ERR_LIB_ENGINE, ENGINE_R_VERSION_INCOMPATIBILITY}, + #else + {"VERSION_INCOMPATIBILITY", 38, 145}, + #endif + #ifdef EVP_R_AES_KEY_SETUP_FAILED + {"AES_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_AES_KEY_SETUP_FAILED}, + #else + {"AES_KEY_SETUP_FAILED", 6, 143}, + #endif + #ifdef EVP_R_ARIA_KEY_SETUP_FAILED + {"ARIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED}, + #else + {"ARIA_KEY_SETUP_FAILED", 6, 176}, + #endif + #ifdef EVP_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_EVP, EVP_R_BAD_DECRYPT}, + #else + {"BAD_DECRYPT", 6, 100}, + #endif + #ifdef EVP_R_BAD_KEY_LENGTH + {"BAD_KEY_LENGTH", ERR_LIB_EVP, EVP_R_BAD_KEY_LENGTH}, + #else + {"BAD_KEY_LENGTH", 6, 195}, + #endif + #ifdef EVP_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 6, 155}, + #endif + #ifdef EVP_R_CAMELLIA_KEY_SETUP_FAILED + {"CAMELLIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED}, + #else + {"CAMELLIA_KEY_SETUP_FAILED", 6, 157}, + #endif + #ifdef EVP_R_CIPHER_PARAMETER_ERROR + {"CIPHER_PARAMETER_ERROR", ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR}, + #else + {"CIPHER_PARAMETER_ERROR", 6, 122}, + #endif + #ifdef EVP_R_COMMAND_NOT_SUPPORTED + {"COMMAND_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED}, + #else + {"COMMAND_NOT_SUPPORTED", 6, 147}, + #endif + #ifdef EVP_R_COPY_ERROR + {"COPY_ERROR", ERR_LIB_EVP, EVP_R_COPY_ERROR}, + #else + {"COPY_ERROR", 6, 173}, + #endif + #ifdef EVP_R_CTRL_NOT_IMPLEMENTED + {"CTRL_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED}, + #else + {"CTRL_NOT_IMPLEMENTED", 6, 132}, + #endif + #ifdef EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED + {"CTRL_OPERATION_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED}, + #else + {"CTRL_OPERATION_NOT_IMPLEMENTED", 6, 133}, + #endif + #ifdef EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH}, + #else + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", 6, 138}, + #endif + #ifdef EVP_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EVP, EVP_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 6, 114}, + #endif + #ifdef EVP_R_DIFFERENT_KEY_TYPES + {"DIFFERENT_KEY_TYPES", ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES}, + #else + {"DIFFERENT_KEY_TYPES", 6, 101}, + #endif + #ifdef EVP_R_DIFFERENT_PARAMETERS + {"DIFFERENT_PARAMETERS", ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS}, + #else + {"DIFFERENT_PARAMETERS", 6, 153}, + #endif + #ifdef EVP_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_EVP, EVP_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 6, 165}, + #endif + #ifdef EVP_R_ERROR_SETTING_FIPS_MODE + {"ERROR_SETTING_FIPS_MODE", ERR_LIB_EVP, EVP_R_ERROR_SETTING_FIPS_MODE}, + #else + {"ERROR_SETTING_FIPS_MODE", 6, 166}, + #endif + #ifdef EVP_R_EXPECTING_AN_HMAC_KEY + {"EXPECTING_AN_HMAC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY}, + #else + {"EXPECTING_AN_HMAC_KEY", 6, 174}, + #endif + #ifdef EVP_R_EXPECTING_AN_RSA_KEY + {"EXPECTING_AN_RSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_RSA_KEY}, + #else + {"EXPECTING_AN_RSA_KEY", 6, 127}, + #endif + #ifdef EVP_R_EXPECTING_A_DH_KEY + {"EXPECTING_A_DH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY}, + #else + {"EXPECTING_A_DH_KEY", 6, 128}, + #endif + #ifdef EVP_R_EXPECTING_A_DSA_KEY + {"EXPECTING_A_DSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY}, + #else + {"EXPECTING_A_DSA_KEY", 6, 129}, + #endif + #ifdef EVP_R_EXPECTING_A_EC_KEY + {"EXPECTING_A_EC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_EC_KEY}, + #else + {"EXPECTING_A_EC_KEY", 6, 142}, + #endif + #ifdef EVP_R_EXPECTING_A_POLY1305_KEY + {"EXPECTING_A_POLY1305_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY}, + #else + {"EXPECTING_A_POLY1305_KEY", 6, 164}, + #endif + #ifdef EVP_R_EXPECTING_A_SIPHASH_KEY + {"EXPECTING_A_SIPHASH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY}, + #else + {"EXPECTING_A_SIPHASH_KEY", 6, 175}, + #endif + #ifdef EVP_R_FIPS_MODE_NOT_SUPPORTED + {"FIPS_MODE_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_FIPS_MODE_NOT_SUPPORTED}, + #else + {"FIPS_MODE_NOT_SUPPORTED", 6, 167}, + #endif + #ifdef EVP_R_GET_RAW_KEY_FAILED + {"GET_RAW_KEY_FAILED", ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED}, + #else + {"GET_RAW_KEY_FAILED", 6, 182}, + #endif + #ifdef EVP_R_ILLEGAL_SCRYPT_PARAMETERS + {"ILLEGAL_SCRYPT_PARAMETERS", ERR_LIB_EVP, EVP_R_ILLEGAL_SCRYPT_PARAMETERS}, + #else + {"ILLEGAL_SCRYPT_PARAMETERS", 6, 171}, + #endif + #ifdef EVP_R_INITIALIZATION_ERROR + {"INITIALIZATION_ERROR", ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR}, + #else + {"INITIALIZATION_ERROR", 6, 134}, + #endif + #ifdef EVP_R_INPUT_NOT_INITIALIZED + {"INPUT_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_INPUT_NOT_INITIALIZED}, + #else + {"INPUT_NOT_INITIALIZED", 6, 111}, + #endif + #ifdef EVP_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EVP, EVP_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 6, 152}, + #endif + #ifdef EVP_R_INVALID_FIPS_MODE + {"INVALID_FIPS_MODE", ERR_LIB_EVP, EVP_R_INVALID_FIPS_MODE}, + #else + {"INVALID_FIPS_MODE", 6, 168}, + #endif + #ifdef EVP_R_INVALID_IV_LENGTH + {"INVALID_IV_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH}, + #else + {"INVALID_IV_LENGTH", 6, 194}, + #endif + #ifdef EVP_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EVP, EVP_R_INVALID_KEY}, + #else + {"INVALID_KEY", 6, 163}, + #endif + #ifdef EVP_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 6, 130}, + #endif + #ifdef EVP_R_INVALID_OPERATION + {"INVALID_OPERATION", ERR_LIB_EVP, EVP_R_INVALID_OPERATION}, + #else + {"INVALID_OPERATION", 6, 148}, + #endif + #ifdef EVP_R_KEYGEN_FAILURE + {"KEYGEN_FAILURE", ERR_LIB_EVP, EVP_R_KEYGEN_FAILURE}, + #else + {"KEYGEN_FAILURE", 6, 120}, + #endif + #ifdef EVP_R_KEY_SETUP_FAILED + {"KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED}, + #else + {"KEY_SETUP_FAILED", 6, 180}, + #endif + #ifdef EVP_R_MEMORY_LIMIT_EXCEEDED + {"MEMORY_LIMIT_EXCEEDED", ERR_LIB_EVP, EVP_R_MEMORY_LIMIT_EXCEEDED}, + #else + {"MEMORY_LIMIT_EXCEEDED", 6, 172}, + #endif + #ifdef EVP_R_MESSAGE_DIGEST_IS_NULL + {"MESSAGE_DIGEST_IS_NULL", ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL}, + #else + {"MESSAGE_DIGEST_IS_NULL", 6, 159}, + #endif + #ifdef EVP_R_METHOD_NOT_SUPPORTED + {"METHOD_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_METHOD_NOT_SUPPORTED}, + #else + {"METHOD_NOT_SUPPORTED", 6, 144}, + #endif + #ifdef EVP_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 6, 103}, + #endif + #ifdef EVP_R_NOT_XOF_OR_INVALID_LENGTH + {"NOT_XOF_OR_INVALID_LENGTH", ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH}, + #else + {"NOT_XOF_OR_INVALID_LENGTH", 6, 178}, + #endif + #ifdef EVP_R_NO_CIPHER_SET + {"NO_CIPHER_SET", ERR_LIB_EVP, EVP_R_NO_CIPHER_SET}, + #else + {"NO_CIPHER_SET", 6, 131}, + #endif + #ifdef EVP_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 6, 158}, + #endif + #ifdef EVP_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_EVP, EVP_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 6, 139}, + #endif + #ifdef EVP_R_NO_KEY_SET + {"NO_KEY_SET", ERR_LIB_EVP, EVP_R_NO_KEY_SET}, + #else + {"NO_KEY_SET", 6, 154}, + #endif + #ifdef EVP_R_NO_OPERATION_SET + {"NO_OPERATION_SET", ERR_LIB_EVP, EVP_R_NO_OPERATION_SET}, + #else + {"NO_OPERATION_SET", 6, 149}, + #endif + #ifdef EVP_R_ONLY_ONESHOT_SUPPORTED + {"ONLY_ONESHOT_SUPPORTED", ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED}, + #else + {"ONLY_ONESHOT_SUPPORTED", 6, 177}, + #endif + #ifdef EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 6, 150}, + #endif + #ifdef EVP_R_OPERATON_NOT_INITIALIZED + {"OPERATON_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED}, + #else + {"OPERATON_NOT_INITIALIZED", 6, 151}, + #endif + #ifdef EVP_R_PARTIALLY_OVERLAPPING + {"PARTIALLY_OVERLAPPING", ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING}, + #else + {"PARTIALLY_OVERLAPPING", 6, 162}, + #endif + #ifdef EVP_R_PBKDF2_ERROR + {"PBKDF2_ERROR", ERR_LIB_EVP, EVP_R_PBKDF2_ERROR}, + #else + {"PBKDF2_ERROR", 6, 181}, + #endif + #ifdef EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", ERR_LIB_EVP, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED}, + #else + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", 6, 179}, + #endif + #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR + {"PRIVATE_KEY_DECODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_DECODE_ERROR}, + #else + {"PRIVATE_KEY_DECODE_ERROR", 6, 145}, + #endif + #ifdef EVP_R_PRIVATE_KEY_ENCODE_ERROR + {"PRIVATE_KEY_ENCODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_ENCODE_ERROR}, + #else + {"PRIVATE_KEY_ENCODE_ERROR", 6, 146}, + #endif + #ifdef EVP_R_PUBLIC_KEY_NOT_RSA + {"PUBLIC_KEY_NOT_RSA", ERR_LIB_EVP, EVP_R_PUBLIC_KEY_NOT_RSA}, + #else + {"PUBLIC_KEY_NOT_RSA", 6, 106}, + #endif + #ifdef EVP_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_EVP, EVP_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 6, 160}, + #endif + #ifdef EVP_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_EVP, EVP_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 6, 161}, + #endif + #ifdef EVP_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_EVP, EVP_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 6, 169}, + #endif + #ifdef EVP_R_UNKNOWN_PBE_ALGORITHM + {"UNKNOWN_PBE_ALGORITHM", ERR_LIB_EVP, EVP_R_UNKNOWN_PBE_ALGORITHM}, + #else + {"UNKNOWN_PBE_ALGORITHM", 6, 121}, + #endif + #ifdef EVP_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 6, 156}, + #endif + #ifdef EVP_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 6, 107}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEYLENGTH + {"UNSUPPORTED_KEYLENGTH", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH}, + #else + {"UNSUPPORTED_KEYLENGTH", 6, 123}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION}, + #else + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", 6, 124}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_SIZE + {"UNSUPPORTED_KEY_SIZE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE}, + #else + {"UNSUPPORTED_KEY_SIZE", 6, 108}, + #endif + #ifdef EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS + {"UNSUPPORTED_NUMBER_OF_ROUNDS", ERR_LIB_EVP, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS}, + #else + {"UNSUPPORTED_NUMBER_OF_ROUNDS", 6, 135}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRF + {"UNSUPPORTED_PRF", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF}, + #else + {"UNSUPPORTED_PRF", 6, 125}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM}, + #else + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", 6, 118}, + #endif + #ifdef EVP_R_UNSUPPORTED_SALT_TYPE + {"UNSUPPORTED_SALT_TYPE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_SALT_TYPE}, + #else + {"UNSUPPORTED_SALT_TYPE", 6, 126}, + #endif + #ifdef EVP_R_WRAP_MODE_NOT_ALLOWED + {"WRAP_MODE_NOT_ALLOWED", ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED}, + #else + {"WRAP_MODE_NOT_ALLOWED", 6, 170}, + #endif + #ifdef EVP_R_WRONG_FINAL_BLOCK_LENGTH + {"WRONG_FINAL_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_WRONG_FINAL_BLOCK_LENGTH}, + #else + {"WRONG_FINAL_BLOCK_LENGTH", 6, 109}, + #endif + #ifdef EVP_R_XTS_DUPLICATED_KEYS + {"XTS_DUPLICATED_KEYS", ERR_LIB_EVP, EVP_R_XTS_DUPLICATED_KEYS}, + #else + {"XTS_DUPLICATED_KEYS", 6, 183}, + #endif + #ifdef KDF_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_KDF, KDF_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 52, 100}, + #endif + #ifdef KDF_R_MISSING_ITERATION_COUNT + {"MISSING_ITERATION_COUNT", ERR_LIB_KDF, KDF_R_MISSING_ITERATION_COUNT}, + #else + {"MISSING_ITERATION_COUNT", 52, 109}, + #endif + #ifdef KDF_R_MISSING_KEY + {"MISSING_KEY", ERR_LIB_KDF, KDF_R_MISSING_KEY}, + #else + {"MISSING_KEY", 52, 104}, + #endif + #ifdef KDF_R_MISSING_MESSAGE_DIGEST + {"MISSING_MESSAGE_DIGEST", ERR_LIB_KDF, KDF_R_MISSING_MESSAGE_DIGEST}, + #else + {"MISSING_MESSAGE_DIGEST", 52, 105}, + #endif + #ifdef KDF_R_MISSING_PARAMETER + {"MISSING_PARAMETER", ERR_LIB_KDF, KDF_R_MISSING_PARAMETER}, + #else + {"MISSING_PARAMETER", 52, 101}, + #endif + #ifdef KDF_R_MISSING_PASS + {"MISSING_PASS", ERR_LIB_KDF, KDF_R_MISSING_PASS}, + #else + {"MISSING_PASS", 52, 110}, + #endif + #ifdef KDF_R_MISSING_SALT + {"MISSING_SALT", ERR_LIB_KDF, KDF_R_MISSING_SALT}, + #else + {"MISSING_SALT", 52, 111}, + #endif + #ifdef KDF_R_MISSING_SECRET + {"MISSING_SECRET", ERR_LIB_KDF, KDF_R_MISSING_SECRET}, + #else + {"MISSING_SECRET", 52, 107}, + #endif + #ifdef KDF_R_MISSING_SEED + {"MISSING_SEED", ERR_LIB_KDF, KDF_R_MISSING_SEED}, + #else + {"MISSING_SEED", 52, 106}, + #endif + #ifdef KDF_R_UNKNOWN_PARAMETER_TYPE + {"UNKNOWN_PARAMETER_TYPE", ERR_LIB_KDF, KDF_R_UNKNOWN_PARAMETER_TYPE}, + #else + {"UNKNOWN_PARAMETER_TYPE", 52, 103}, + #endif + #ifdef KDF_R_VALUE_ERROR + {"VALUE_ERROR", ERR_LIB_KDF, KDF_R_VALUE_ERROR}, + #else + {"VALUE_ERROR", 52, 108}, + #endif + #ifdef KDF_R_VALUE_MISSING + {"VALUE_MISSING", ERR_LIB_KDF, KDF_R_VALUE_MISSING}, + #else + {"VALUE_MISSING", 52, 102}, + #endif + #ifdef OCSP_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 39, 101}, + #endif + #ifdef OCSP_R_DIGEST_ERR + {"DIGEST_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_ERR}, + #else + {"DIGEST_ERR", 39, 102}, + #endif + #ifdef OCSP_R_ERROR_IN_NEXTUPDATE_FIELD + {"ERROR_IN_NEXTUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD}, + #else + {"ERROR_IN_NEXTUPDATE_FIELD", 39, 122}, + #endif + #ifdef OCSP_R_ERROR_IN_THISUPDATE_FIELD + {"ERROR_IN_THISUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD}, + #else + {"ERROR_IN_THISUPDATE_FIELD", 39, 123}, + #endif + #ifdef OCSP_R_ERROR_PARSING_URL + {"ERROR_PARSING_URL", ERR_LIB_OCSP, OCSP_R_ERROR_PARSING_URL}, + #else + {"ERROR_PARSING_URL", 39, 121}, + #endif + #ifdef OCSP_R_MISSING_OCSPSIGNING_USAGE + {"MISSING_OCSPSIGNING_USAGE", ERR_LIB_OCSP, OCSP_R_MISSING_OCSPSIGNING_USAGE}, + #else + {"MISSING_OCSPSIGNING_USAGE", 39, 103}, + #endif + #ifdef OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE + {"NEXTUPDATE_BEFORE_THISUPDATE", ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE}, + #else + {"NEXTUPDATE_BEFORE_THISUPDATE", 39, 124}, + #endif + #ifdef OCSP_R_NOT_BASIC_RESPONSE + {"NOT_BASIC_RESPONSE", ERR_LIB_OCSP, OCSP_R_NOT_BASIC_RESPONSE}, + #else + {"NOT_BASIC_RESPONSE", 39, 104}, + #endif + #ifdef OCSP_R_NO_CERTIFICATES_IN_CHAIN + {"NO_CERTIFICATES_IN_CHAIN", ERR_LIB_OCSP, OCSP_R_NO_CERTIFICATES_IN_CHAIN}, + #else + {"NO_CERTIFICATES_IN_CHAIN", 39, 105}, + #endif + #ifdef OCSP_R_NO_RESPONSE_DATA + {"NO_RESPONSE_DATA", ERR_LIB_OCSP, OCSP_R_NO_RESPONSE_DATA}, + #else + {"NO_RESPONSE_DATA", 39, 108}, + #endif + #ifdef OCSP_R_NO_REVOKED_TIME + {"NO_REVOKED_TIME", ERR_LIB_OCSP, OCSP_R_NO_REVOKED_TIME}, + #else + {"NO_REVOKED_TIME", 39, 109}, + #endif + #ifdef OCSP_R_NO_SIGNER_KEY + {"NO_SIGNER_KEY", ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY}, + #else + {"NO_SIGNER_KEY", 39, 130}, + #endif + #ifdef OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_OCSP, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 39, 110}, + #endif + #ifdef OCSP_R_REQUEST_NOT_SIGNED + {"REQUEST_NOT_SIGNED", ERR_LIB_OCSP, OCSP_R_REQUEST_NOT_SIGNED}, + #else + {"REQUEST_NOT_SIGNED", 39, 128}, + #endif + #ifdef OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", ERR_LIB_OCSP, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA}, + #else + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", 39, 111}, + #endif + #ifdef OCSP_R_ROOT_CA_NOT_TRUSTED + {"ROOT_CA_NOT_TRUSTED", ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED}, + #else + {"ROOT_CA_NOT_TRUSTED", 39, 112}, + #endif + #ifdef OCSP_R_SERVER_RESPONSE_ERROR + {"SERVER_RESPONSE_ERROR", ERR_LIB_OCSP, OCSP_R_SERVER_RESPONSE_ERROR}, + #else + {"SERVER_RESPONSE_ERROR", 39, 114}, + #endif + #ifdef OCSP_R_SERVER_RESPONSE_PARSE_ERROR + {"SERVER_RESPONSE_PARSE_ERROR", ERR_LIB_OCSP, OCSP_R_SERVER_RESPONSE_PARSE_ERROR}, + #else + {"SERVER_RESPONSE_PARSE_ERROR", 39, 115}, + #endif + #ifdef OCSP_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 39, 117}, + #endif + #ifdef OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 39, 118}, + #endif + #ifdef OCSP_R_STATUS_EXPIRED + {"STATUS_EXPIRED", ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED}, + #else + {"STATUS_EXPIRED", 39, 125}, + #endif + #ifdef OCSP_R_STATUS_NOT_YET_VALID + {"STATUS_NOT_YET_VALID", ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID}, + #else + {"STATUS_NOT_YET_VALID", 39, 126}, + #endif + #ifdef OCSP_R_STATUS_TOO_OLD + {"STATUS_TOO_OLD", ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD}, + #else + {"STATUS_TOO_OLD", 39, 127}, + #endif + #ifdef OCSP_R_UNKNOWN_MESSAGE_DIGEST + {"UNKNOWN_MESSAGE_DIGEST", ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST}, + #else + {"UNKNOWN_MESSAGE_DIGEST", 39, 119}, + #endif + #ifdef OCSP_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_OCSP, OCSP_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 39, 120}, + #endif + #ifdef OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE + {"UNSUPPORTED_REQUESTORNAME_TYPE", ERR_LIB_OCSP, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE}, + #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 + {"BAD_BASE64_DECODE", 9, 100}, + #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 + {"BAD_END_LINE", 9, 102}, + #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 + {"BAD_MAGIC_NUMBER", 9, 116}, + #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 + {"BAD_VERSION_NUMBER", 9, 117}, + #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 + {"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 + {"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 + {"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 + {"EXPECTING_PUBLIC_KEY_BLOB", 9, 120}, + #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 + {"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 + {"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 + {"KEYBLOB_TOO_SHORT", 9, 123}, + #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 + {"NOT_DEK_INFO", 9, 105}, + #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 + {"NOT_PROC_TYPE", 9, 107}, + #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 + {"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 + {"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 + {"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 + {"PVK_TOO_SHORT", 9, 125}, + #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 + {"SHORT_HEADER", 9, 112}, + #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 + {"UNSUPPORTED_CIPHER", 9, 113}, + #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 + {"UNSUPPORTED_KEY_COMPONENTS", 9, 126}, + #endif + #ifdef PKCS12_R_CANT_PACK_STRUCTURE + {"CANT_PACK_STRUCTURE", ERR_LIB_PKCS12, PKCS12_R_CANT_PACK_STRUCTURE}, + #else + {"CANT_PACK_STRUCTURE", 35, 100}, + #endif + #ifdef PKCS12_R_CONTENT_TYPE_NOT_DATA + {"CONTENT_TYPE_NOT_DATA", ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA}, + #else + {"CONTENT_TYPE_NOT_DATA", 35, 121}, + #endif + #ifdef PKCS12_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 35, 101}, + #endif + #ifdef PKCS12_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 35, 102}, + #endif + #ifdef PKCS12_R_ENCRYPT_ERROR + {"ENCRYPT_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR}, + #else + {"ENCRYPT_ERROR", 35, 103}, + #endif + #ifdef PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", ERR_LIB_PKCS12, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE}, + #else + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", 35, 120}, + #endif + #ifdef PKCS12_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 35, 104}, + #endif + #ifdef PKCS12_R_INVALID_NULL_PKCS12_POINTER + {"INVALID_NULL_PKCS12_POINTER", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER}, + #else + {"INVALID_NULL_PKCS12_POINTER", 35, 105}, + #endif + #ifdef PKCS12_R_IV_GEN_ERROR + {"IV_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_IV_GEN_ERROR}, + #else + {"IV_GEN_ERROR", 35, 106}, + #endif + #ifdef PKCS12_R_KEY_GEN_ERROR + {"KEY_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR}, + #else + {"KEY_GEN_ERROR", 35, 107}, + #endif + #ifdef PKCS12_R_MAC_ABSENT + {"MAC_ABSENT", ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT}, + #else + {"MAC_ABSENT", 35, 108}, + #endif + #ifdef PKCS12_R_MAC_GENERATION_ERROR + {"MAC_GENERATION_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR}, + #else + {"MAC_GENERATION_ERROR", 35, 109}, + #endif + #ifdef PKCS12_R_MAC_SETUP_ERROR + {"MAC_SETUP_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR}, + #else + {"MAC_SETUP_ERROR", 35, 110}, + #endif + #ifdef PKCS12_R_MAC_STRING_SET_ERROR + {"MAC_STRING_SET_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR}, + #else + {"MAC_STRING_SET_ERROR", 35, 111}, + #endif + #ifdef PKCS12_R_MAC_VERIFY_FAILURE + {"MAC_VERIFY_FAILURE", ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE}, + #else + {"MAC_VERIFY_FAILURE", 35, 113}, + #endif + #ifdef PKCS12_R_PARSE_ERROR + {"PARSE_ERROR", ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR}, + #else + {"PARSE_ERROR", 35, 114}, + #endif + #ifdef PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR + {"PKCS12_ALGOR_CIPHERINIT_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR}, + #else + {"PKCS12_ALGOR_CIPHERINIT_ERROR", 35, 115}, + #endif + #ifdef PKCS12_R_PKCS12_CIPHERFINAL_ERROR + {"PKCS12_CIPHERFINAL_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR}, + #else + {"PKCS12_CIPHERFINAL_ERROR", 35, 116}, + #endif + #ifdef PKCS12_R_PKCS12_PBE_CRYPT_ERROR + {"PKCS12_PBE_CRYPT_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_PBE_CRYPT_ERROR}, + #else + {"PKCS12_PBE_CRYPT_ERROR", 35, 117}, + #endif + #ifdef PKCS12_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 35, 118}, + #endif + #ifdef PKCS12_R_UNSUPPORTED_PKCS12_MODE + {"UNSUPPORTED_PKCS12_MODE", ERR_LIB_PKCS12, PKCS12_R_UNSUPPORTED_PKCS12_MODE}, + #else + {"UNSUPPORTED_PKCS12_MODE", 35, 119}, + #endif + #ifdef PKCS7_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_PKCS7, PKCS7_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 33, 117}, + #endif + #ifdef PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 33, 144}, + #endif + #ifdef PKCS7_R_CIPHER_NOT_INITIALIZED + {"CIPHER_NOT_INITIALIZED", ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED}, + #else + {"CIPHER_NOT_INITIALIZED", 33, 116}, + #endif + #ifdef PKCS7_R_CONTENT_AND_DATA_PRESENT + {"CONTENT_AND_DATA_PRESENT", ERR_LIB_PKCS7, PKCS7_R_CONTENT_AND_DATA_PRESENT}, + #else + {"CONTENT_AND_DATA_PRESENT", 33, 118}, + #endif + #ifdef PKCS7_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_PKCS7, PKCS7_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 33, 152}, + #endif + #ifdef PKCS7_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_PKCS7, PKCS7_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 33, 119}, + #endif + #ifdef PKCS7_R_DIGEST_FAILURE + {"DIGEST_FAILURE", ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE}, + #else + {"DIGEST_FAILURE", 33, 101}, + #endif + #ifdef PKCS7_R_ENCRYPTION_CTRL_FAILURE + {"ENCRYPTION_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE}, + #else + {"ENCRYPTION_CTRL_FAILURE", 33, 149}, + #endif + #ifdef PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 150}, + #endif + #ifdef PKCS7_R_ERROR_ADDING_RECIPIENT + {"ERROR_ADDING_RECIPIENT", ERR_LIB_PKCS7, PKCS7_R_ERROR_ADDING_RECIPIENT}, + #else + {"ERROR_ADDING_RECIPIENT", 33, 120}, + #endif + #ifdef PKCS7_R_ERROR_SETTING_CIPHER + {"ERROR_SETTING_CIPHER", ERR_LIB_PKCS7, PKCS7_R_ERROR_SETTING_CIPHER}, + #else + {"ERROR_SETTING_CIPHER", 33, 121}, + #endif + #ifdef PKCS7_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 33, 143}, + #endif + #ifdef PKCS7_R_INVALID_SIGNED_DATA_TYPE + {"INVALID_SIGNED_DATA_TYPE", ERR_LIB_PKCS7, PKCS7_R_INVALID_SIGNED_DATA_TYPE}, + #else + {"INVALID_SIGNED_DATA_TYPE", 33, 155}, + #endif + #ifdef PKCS7_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT}, + #else + {"NO_CONTENT", 33, 122}, + #endif + #ifdef PKCS7_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 33, 151}, + #endif + #ifdef PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND + {"NO_MATCHING_DIGEST_TYPE_FOUND", ERR_LIB_PKCS7, PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND}, + #else + {"NO_MATCHING_DIGEST_TYPE_FOUND", 33, 154}, + #endif + #ifdef PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE + {"NO_RECIPIENT_MATCHES_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE}, + #else + {"NO_RECIPIENT_MATCHES_CERTIFICATE", 33, 115}, + #endif + #ifdef PKCS7_R_NO_SIGNATURES_ON_DATA + {"NO_SIGNATURES_ON_DATA", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNATURES_ON_DATA}, + #else + {"NO_SIGNATURES_ON_DATA", 33, 123}, + #endif + #ifdef PKCS7_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 33, 142}, + #endif + #ifdef PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", ERR_LIB_PKCS7, PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE}, + #else + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", 33, 104}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 33, 124}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNER_ERROR + {"PKCS7_ADD_SIGNER_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNER_ERROR}, + #else + {"PKCS7_ADD_SIGNER_ERROR", 33, 153}, + #endif + #ifdef PKCS7_R_PKCS7_DATASIGN + {"PKCS7_DATASIGN", ERR_LIB_PKCS7, PKCS7_R_PKCS7_DATASIGN}, + #else + {"PKCS7_DATASIGN", 33, 145}, + #endif + #ifdef PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 33, 127}, + #endif + #ifdef PKCS7_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 33, 105}, + #endif + #ifdef PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_PKCS7, PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 33, 128}, + #endif + #ifdef PKCS7_R_SIGNING_CTRL_FAILURE + {"SIGNING_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE}, + #else + {"SIGNING_CTRL_FAILURE", 33, 147}, + #endif + #ifdef PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 148}, + #endif + #ifdef PKCS7_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_PKCS7, PKCS7_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 33, 129}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_CERTIFICATE + {"UNABLE_TO_FIND_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE}, + #else + {"UNABLE_TO_FIND_CERTIFICATE", 33, 106}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MEM_BIO + {"UNABLE_TO_FIND_MEM_BIO", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MEM_BIO}, + #else + {"UNABLE_TO_FIND_MEM_BIO", 33, 107}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST + {"UNABLE_TO_FIND_MESSAGE_DIGEST", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST}, + #else + {"UNABLE_TO_FIND_MESSAGE_DIGEST", 33, 108}, + #endif + #ifdef PKCS7_R_UNKNOWN_DIGEST_TYPE + {"UNKNOWN_DIGEST_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE}, + #else + {"UNKNOWN_DIGEST_TYPE", 33, 109}, + #endif + #ifdef PKCS7_R_UNKNOWN_OPERATION + {"UNKNOWN_OPERATION", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION}, + #else + {"UNKNOWN_OPERATION", 33, 110}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CIPHER_TYPE + {"UNSUPPORTED_CIPHER_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE}, + #else + {"UNSUPPORTED_CIPHER_TYPE", 33, 111}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 33, 112}, + #endif + #ifdef PKCS7_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 33, 113}, + #endif + #ifdef PKCS7_R_WRONG_PKCS7_TYPE + {"WRONG_PKCS7_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE}, + #else + {"WRONG_PKCS7_TYPE", 33, 114}, + #endif + #ifdef RAND_R_ADDITIONAL_INPUT_TOO_LONG + {"ADDITIONAL_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ADDITIONAL_INPUT_TOO_LONG}, + #else + {"ADDITIONAL_INPUT_TOO_LONG", 36, 102}, + #endif + #ifdef RAND_R_ALREADY_INSTANTIATED + {"ALREADY_INSTANTIATED", ERR_LIB_RAND, RAND_R_ALREADY_INSTANTIATED}, + #else + {"ALREADY_INSTANTIATED", 36, 103}, + #endif + #ifdef RAND_R_ARGUMENT_OUT_OF_RANGE + {"ARGUMENT_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE}, + #else + {"ARGUMENT_OUT_OF_RANGE", 36, 105}, + #endif + #ifdef RAND_R_CANNOT_OPEN_FILE + {"CANNOT_OPEN_FILE", ERR_LIB_RAND, RAND_R_CANNOT_OPEN_FILE}, + #else + {"CANNOT_OPEN_FILE", 36, 121}, + #endif + #ifdef RAND_R_DRBG_ALREADY_INITIALIZED + {"DRBG_ALREADY_INITIALIZED", ERR_LIB_RAND, RAND_R_DRBG_ALREADY_INITIALIZED}, + #else + {"DRBG_ALREADY_INITIALIZED", 36, 129}, + #endif + #ifdef RAND_R_DRBG_NOT_INITIALISED + {"DRBG_NOT_INITIALISED", ERR_LIB_RAND, RAND_R_DRBG_NOT_INITIALISED}, + #else + {"DRBG_NOT_INITIALISED", 36, 104}, + #endif + #ifdef RAND_R_ENTROPY_INPUT_TOO_LONG + {"ENTROPY_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG}, + #else + {"ENTROPY_INPUT_TOO_LONG", 36, 106}, + #endif + #ifdef RAND_R_ENTROPY_OUT_OF_RANGE + {"ENTROPY_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ENTROPY_OUT_OF_RANGE}, + #else + {"ENTROPY_OUT_OF_RANGE", 36, 124}, + #endif + #ifdef RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED + {"ERROR_ENTROPY_POOL_WAS_IGNORED", ERR_LIB_RAND, RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED}, + #else + {"ERROR_ENTROPY_POOL_WAS_IGNORED", 36, 127}, + #endif + #ifdef RAND_R_ERROR_INITIALISING_DRBG + {"ERROR_INITIALISING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INITIALISING_DRBG}, + #else + {"ERROR_INITIALISING_DRBG", 36, 107}, + #endif + #ifdef RAND_R_ERROR_INSTANTIATING_DRBG + {"ERROR_INSTANTIATING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG}, + #else + {"ERROR_INSTANTIATING_DRBG", 36, 108}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT}, + #else + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", 36, 109}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ENTROPY + {"ERROR_RETRIEVING_ENTROPY", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY}, + #else + {"ERROR_RETRIEVING_ENTROPY", 36, 110}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_NONCE + {"ERROR_RETRIEVING_NONCE", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_NONCE}, + #else + {"ERROR_RETRIEVING_NONCE", 36, 111}, + #endif + #ifdef RAND_R_FAILED_TO_CREATE_LOCK + {"FAILED_TO_CREATE_LOCK", ERR_LIB_RAND, RAND_R_FAILED_TO_CREATE_LOCK}, + #else + {"FAILED_TO_CREATE_LOCK", 36, 126}, + #endif + #ifdef RAND_R_FUNC_NOT_IMPLEMENTED + {"FUNC_NOT_IMPLEMENTED", ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED}, + #else + {"FUNC_NOT_IMPLEMENTED", 36, 101}, + #endif + #ifdef RAND_R_FWRITE_ERROR + {"FWRITE_ERROR", ERR_LIB_RAND, RAND_R_FWRITE_ERROR}, + #else + {"FWRITE_ERROR", 36, 123}, + #endif + #ifdef RAND_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_RAND, RAND_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 36, 112}, + #endif + #ifdef RAND_R_INTERNAL_ERROR + {"INTERNAL_ERROR", ERR_LIB_RAND, RAND_R_INTERNAL_ERROR}, + #else + {"INTERNAL_ERROR", 36, 113}, + #endif + #ifdef RAND_R_IN_ERROR_STATE + {"IN_ERROR_STATE", ERR_LIB_RAND, RAND_R_IN_ERROR_STATE}, + #else + {"IN_ERROR_STATE", 36, 114}, + #endif + #ifdef RAND_R_NOT_A_REGULAR_FILE + {"NOT_A_REGULAR_FILE", ERR_LIB_RAND, RAND_R_NOT_A_REGULAR_FILE}, + #else + {"NOT_A_REGULAR_FILE", 36, 122}, + #endif + #ifdef RAND_R_NOT_INSTANTIATED + {"NOT_INSTANTIATED", ERR_LIB_RAND, RAND_R_NOT_INSTANTIATED}, + #else + {"NOT_INSTANTIATED", 36, 115}, + #endif + #ifdef RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED + {"NO_DRBG_IMPLEMENTATION_SELECTED", ERR_LIB_RAND, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED}, + #else + {"NO_DRBG_IMPLEMENTATION_SELECTED", 36, 128}, + #endif + #ifdef RAND_R_PARENT_LOCKING_NOT_ENABLED + {"PARENT_LOCKING_NOT_ENABLED", ERR_LIB_RAND, RAND_R_PARENT_LOCKING_NOT_ENABLED}, + #else + {"PARENT_LOCKING_NOT_ENABLED", 36, 130}, + #endif + #ifdef RAND_R_PARENT_STRENGTH_TOO_WEAK + {"PARENT_STRENGTH_TOO_WEAK", ERR_LIB_RAND, RAND_R_PARENT_STRENGTH_TOO_WEAK}, + #else + {"PARENT_STRENGTH_TOO_WEAK", 36, 131}, + #endif + #ifdef RAND_R_PERSONALISATION_STRING_TOO_LONG + {"PERSONALISATION_STRING_TOO_LONG", ERR_LIB_RAND, RAND_R_PERSONALISATION_STRING_TOO_LONG}, + #else + {"PERSONALISATION_STRING_TOO_LONG", 36, 116}, + #endif + #ifdef RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", ERR_LIB_RAND, RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED}, + #else + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", 36, 133}, + #endif + #ifdef RAND_R_PRNG_NOT_SEEDED + {"PRNG_NOT_SEEDED", ERR_LIB_RAND, RAND_R_PRNG_NOT_SEEDED}, + #else + {"PRNG_NOT_SEEDED", 36, 100}, + #endif + #ifdef RAND_R_RANDOM_POOL_OVERFLOW + {"RANDOM_POOL_OVERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW}, + #else + {"RANDOM_POOL_OVERFLOW", 36, 125}, + #endif + #ifdef RAND_R_RANDOM_POOL_UNDERFLOW + {"RANDOM_POOL_UNDERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_UNDERFLOW}, + #else + {"RANDOM_POOL_UNDERFLOW", 36, 134}, + #endif + #ifdef RAND_R_REQUEST_TOO_LARGE_FOR_DRBG + {"REQUEST_TOO_LARGE_FOR_DRBG", ERR_LIB_RAND, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG}, + #else + {"REQUEST_TOO_LARGE_FOR_DRBG", 36, 117}, + #endif + #ifdef RAND_R_RESEED_ERROR + {"RESEED_ERROR", ERR_LIB_RAND, RAND_R_RESEED_ERROR}, + #else + {"RESEED_ERROR", 36, 118}, + #endif + #ifdef RAND_R_SELFTEST_FAILURE + {"SELFTEST_FAILURE", ERR_LIB_RAND, RAND_R_SELFTEST_FAILURE}, + #else + {"SELFTEST_FAILURE", 36, 119}, + #endif + #ifdef RAND_R_TOO_LITTLE_NONCE_REQUESTED + {"TOO_LITTLE_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_LITTLE_NONCE_REQUESTED}, + #else + {"TOO_LITTLE_NONCE_REQUESTED", 36, 135}, + #endif + #ifdef RAND_R_TOO_MUCH_NONCE_REQUESTED + {"TOO_MUCH_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_MUCH_NONCE_REQUESTED}, + #else + {"TOO_MUCH_NONCE_REQUESTED", 36, 136}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_FLAGS + {"UNSUPPORTED_DRBG_FLAGS", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_FLAGS}, + #else + {"UNSUPPORTED_DRBG_FLAGS", 36, 132}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_TYPE + {"UNSUPPORTED_DRBG_TYPE", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_TYPE}, + #else + {"UNSUPPORTED_DRBG_TYPE", 36, 120}, + #endif + #ifdef RSA_R_ALGORITHM_MISMATCH + {"ALGORITHM_MISMATCH", ERR_LIB_RSA, RSA_R_ALGORITHM_MISMATCH}, + #else + {"ALGORITHM_MISMATCH", 4, 100}, + #endif + #ifdef RSA_R_BAD_E_VALUE + {"BAD_E_VALUE", ERR_LIB_RSA, RSA_R_BAD_E_VALUE}, + #else + {"BAD_E_VALUE", 4, 101}, + #endif + #ifdef RSA_R_BAD_FIXED_HEADER_DECRYPT + {"BAD_FIXED_HEADER_DECRYPT", ERR_LIB_RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT}, + #else + {"BAD_FIXED_HEADER_DECRYPT", 4, 102}, + #endif + #ifdef RSA_R_BAD_PAD_BYTE_COUNT + {"BAD_PAD_BYTE_COUNT", ERR_LIB_RSA, RSA_R_BAD_PAD_BYTE_COUNT}, + #else + {"BAD_PAD_BYTE_COUNT", 4, 103}, + #endif + #ifdef RSA_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_RSA, RSA_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 4, 104}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_01 + {"BLOCK_TYPE_IS_NOT_01", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_01}, + #else + {"BLOCK_TYPE_IS_NOT_01", 4, 106}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_02 + {"BLOCK_TYPE_IS_NOT_02", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_02}, + #else + {"BLOCK_TYPE_IS_NOT_02", 4, 107}, + #endif + #ifdef RSA_R_DATA_GREATER_THAN_MOD_LEN + {"DATA_GREATER_THAN_MOD_LEN", ERR_LIB_RSA, RSA_R_DATA_GREATER_THAN_MOD_LEN}, + #else + {"DATA_GREATER_THAN_MOD_LEN", 4, 108}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE + {"DATA_TOO_LARGE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE}, + #else + {"DATA_TOO_LARGE", 4, 109}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE + {"DATA_TOO_LARGE_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE}, + #else + {"DATA_TOO_LARGE_FOR_KEY_SIZE", 4, 110}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_MODULUS + {"DATA_TOO_LARGE_FOR_MODULUS", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS}, + #else + {"DATA_TOO_LARGE_FOR_MODULUS", 4, 132}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL + {"DATA_TOO_SMALL", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL}, + #else + {"DATA_TOO_SMALL", 4, 111}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE + {"DATA_TOO_SMALL_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE}, + #else + {"DATA_TOO_SMALL_FOR_KEY_SIZE", 4, 122}, + #endif + #ifdef RSA_R_DIGEST_DOES_NOT_MATCH + {"DIGEST_DOES_NOT_MATCH", ERR_LIB_RSA, RSA_R_DIGEST_DOES_NOT_MATCH}, + #else + {"DIGEST_DOES_NOT_MATCH", 4, 158}, + #endif + #ifdef RSA_R_DIGEST_NOT_ALLOWED + {"DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED}, + #else + {"DIGEST_NOT_ALLOWED", 4, 145}, + #endif + #ifdef RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY + {"DIGEST_TOO_BIG_FOR_RSA_KEY", ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY}, + #else + {"DIGEST_TOO_BIG_FOR_RSA_KEY", 4, 112}, + #endif + #ifdef RSA_R_DMP1_NOT_CONGRUENT_TO_D + {"DMP1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMP1_NOT_CONGRUENT_TO_D}, + #else + {"DMP1_NOT_CONGRUENT_TO_D", 4, 124}, + #endif + #ifdef RSA_R_DMQ1_NOT_CONGRUENT_TO_D + {"DMQ1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMQ1_NOT_CONGRUENT_TO_D}, + #else + {"DMQ1_NOT_CONGRUENT_TO_D", 4, 125}, + #endif + #ifdef RSA_R_D_E_NOT_CONGRUENT_TO_1 + {"D_E_NOT_CONGRUENT_TO_1", ERR_LIB_RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1}, + #else + {"D_E_NOT_CONGRUENT_TO_1", 4, 123}, + #endif + #ifdef RSA_R_FIRST_OCTET_INVALID + {"FIRST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_FIRST_OCTET_INVALID}, + #else + {"FIRST_OCTET_INVALID", 4, 133}, + #endif + #ifdef RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE}, + #else + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", 4, 144}, + #endif + #ifdef RSA_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 4, 157}, + #endif + #ifdef RSA_R_INVALID_DIGEST_LENGTH + {"INVALID_DIGEST_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH}, + #else + {"INVALID_DIGEST_LENGTH", 4, 143}, + #endif + #ifdef RSA_R_INVALID_HEADER + {"INVALID_HEADER", ERR_LIB_RSA, RSA_R_INVALID_HEADER}, + #else + {"INVALID_HEADER", 4, 137}, + #endif + #ifdef RSA_R_INVALID_LABEL + {"INVALID_LABEL", ERR_LIB_RSA, RSA_R_INVALID_LABEL}, + #else + {"INVALID_LABEL", 4, 160}, + #endif + #ifdef RSA_R_INVALID_MESSAGE_LENGTH + {"INVALID_MESSAGE_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH}, + #else + {"INVALID_MESSAGE_LENGTH", 4, 131}, + #endif + #ifdef RSA_R_INVALID_MGF1_MD + {"INVALID_MGF1_MD", ERR_LIB_RSA, RSA_R_INVALID_MGF1_MD}, + #else + {"INVALID_MGF1_MD", 4, 156}, + #endif + #ifdef RSA_R_INVALID_MULTI_PRIME_KEY + {"INVALID_MULTI_PRIME_KEY", ERR_LIB_RSA, RSA_R_INVALID_MULTI_PRIME_KEY}, + #else + {"INVALID_MULTI_PRIME_KEY", 4, 167}, + #endif + #ifdef RSA_R_INVALID_OAEP_PARAMETERS + {"INVALID_OAEP_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_OAEP_PARAMETERS}, + #else + {"INVALID_OAEP_PARAMETERS", 4, 161}, + #endif + #ifdef RSA_R_INVALID_PADDING + {"INVALID_PADDING", ERR_LIB_RSA, RSA_R_INVALID_PADDING}, + #else + {"INVALID_PADDING", 4, 138}, + #endif + #ifdef RSA_R_INVALID_PADDING_MODE + {"INVALID_PADDING_MODE", ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE}, + #else + {"INVALID_PADDING_MODE", 4, 141}, + #endif + #ifdef RSA_R_INVALID_PSS_PARAMETERS + {"INVALID_PSS_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS}, + #else + {"INVALID_PSS_PARAMETERS", 4, 149}, + #endif + #ifdef RSA_R_INVALID_PSS_SALTLEN + {"INVALID_PSS_SALTLEN", ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN}, + #else + {"INVALID_PSS_SALTLEN", 4, 146}, + #endif + #ifdef RSA_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 4, 150}, + #endif + #ifdef RSA_R_INVALID_TRAILER + {"INVALID_TRAILER", ERR_LIB_RSA, RSA_R_INVALID_TRAILER}, + #else + {"INVALID_TRAILER", 4, 139}, + #endif + #ifdef RSA_R_INVALID_X931_DIGEST + {"INVALID_X931_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_X931_DIGEST}, + #else + {"INVALID_X931_DIGEST", 4, 142}, + #endif + #ifdef RSA_R_IQMP_NOT_INVERSE_OF_Q + {"IQMP_NOT_INVERSE_OF_Q", ERR_LIB_RSA, RSA_R_IQMP_NOT_INVERSE_OF_Q}, + #else + {"IQMP_NOT_INVERSE_OF_Q", 4, 126}, + #endif + #ifdef RSA_R_KEY_PRIME_NUM_INVALID + {"KEY_PRIME_NUM_INVALID", ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID}, + #else + {"KEY_PRIME_NUM_INVALID", 4, 165}, + #endif + #ifdef RSA_R_KEY_SIZE_TOO_SMALL + {"KEY_SIZE_TOO_SMALL", ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL}, + #else + {"KEY_SIZE_TOO_SMALL", 4, 120}, + #endif + #ifdef RSA_R_LAST_OCTET_INVALID + {"LAST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_LAST_OCTET_INVALID}, + #else + {"LAST_OCTET_INVALID", 4, 134}, + #endif + #ifdef RSA_R_MGF1_DIGEST_NOT_ALLOWED + {"MGF1_DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED}, + #else + {"MGF1_DIGEST_NOT_ALLOWED", 4, 152}, + #endif + #ifdef RSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_RSA, RSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 4, 179}, + #endif + #ifdef RSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 4, 105}, + #endif + #ifdef RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", ERR_LIB_RSA, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R}, + #else + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", 4, 168}, + #endif + #ifdef RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D}, + #else + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", 4, 169}, + #endif + #ifdef RSA_R_MP_R_NOT_PRIME + {"MP_R_NOT_PRIME", ERR_LIB_RSA, RSA_R_MP_R_NOT_PRIME}, + #else + {"MP_R_NOT_PRIME", 4, 170}, + #endif + #ifdef RSA_R_NO_PUBLIC_EXPONENT + {"NO_PUBLIC_EXPONENT", ERR_LIB_RSA, RSA_R_NO_PUBLIC_EXPONENT}, + #else + {"NO_PUBLIC_EXPONENT", 4, 140}, + #endif + #ifdef RSA_R_NULL_BEFORE_BLOCK_MISSING + {"NULL_BEFORE_BLOCK_MISSING", ERR_LIB_RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING}, + #else + {"NULL_BEFORE_BLOCK_MISSING", 4, 113}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES}, + #else + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", 4, 172}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_P_Q + {"N_DOES_NOT_EQUAL_P_Q", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_P_Q}, + #else + {"N_DOES_NOT_EQUAL_P_Q", 4, 127}, + #endif + #ifdef RSA_R_OAEP_DECODING_ERROR + {"OAEP_DECODING_ERROR", ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR}, + #else + {"OAEP_DECODING_ERROR", 4, 121}, + #endif + #ifdef RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_RSA, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 4, 148}, + #endif + #ifdef RSA_R_PADDING_CHECK_FAILED + {"PADDING_CHECK_FAILED", ERR_LIB_RSA, RSA_R_PADDING_CHECK_FAILED}, + #else + {"PADDING_CHECK_FAILED", 4, 114}, + #endif + #ifdef RSA_R_PKCS_DECODING_ERROR + {"PKCS_DECODING_ERROR", ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR}, + #else + {"PKCS_DECODING_ERROR", 4, 159}, + #endif + #ifdef RSA_R_PSS_SALTLEN_TOO_SMALL + {"PSS_SALTLEN_TOO_SMALL", ERR_LIB_RSA, RSA_R_PSS_SALTLEN_TOO_SMALL}, + #else + {"PSS_SALTLEN_TOO_SMALL", 4, 164}, + #endif + #ifdef RSA_R_P_NOT_PRIME + {"P_NOT_PRIME", ERR_LIB_RSA, RSA_R_P_NOT_PRIME}, + #else + {"P_NOT_PRIME", 4, 128}, + #endif + #ifdef RSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_RSA, RSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 4, 129}, + #endif + #ifdef RSA_R_RSA_OPERATIONS_NOT_SUPPORTED + {"RSA_OPERATIONS_NOT_SUPPORTED", ERR_LIB_RSA, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED}, + #else + {"RSA_OPERATIONS_NOT_SUPPORTED", 4, 130}, + #endif + #ifdef RSA_R_SLEN_CHECK_FAILED + {"SLEN_CHECK_FAILED", ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED}, + #else + {"SLEN_CHECK_FAILED", 4, 136}, + #endif + #ifdef RSA_R_SLEN_RECOVERY_FAILED + {"SLEN_RECOVERY_FAILED", ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED}, + #else + {"SLEN_RECOVERY_FAILED", 4, 135}, + #endif + #ifdef RSA_R_SSLV3_ROLLBACK_ATTACK + {"SSLV3_ROLLBACK_ATTACK", ERR_LIB_RSA, RSA_R_SSLV3_ROLLBACK_ATTACK}, + #else + {"SSLV3_ROLLBACK_ATTACK", 4, 115}, + #endif + #ifdef RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_RSA, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 4, 116}, + #endif + #ifdef RSA_R_UNKNOWN_ALGORITHM_TYPE + {"UNKNOWN_ALGORITHM_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE}, + #else + {"UNKNOWN_ALGORITHM_TYPE", 4, 117}, + #endif + #ifdef RSA_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 4, 166}, + #endif + #ifdef RSA_R_UNKNOWN_MASK_DIGEST + {"UNKNOWN_MASK_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_MASK_DIGEST}, + #else + {"UNKNOWN_MASK_DIGEST", 4, 151}, + #endif + #ifdef RSA_R_UNKNOWN_PADDING_TYPE + {"UNKNOWN_PADDING_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE}, + #else + {"UNKNOWN_PADDING_TYPE", 4, 118}, + #endif + #ifdef RSA_R_UNSUPPORTED_ENCRYPTION_TYPE + {"UNSUPPORTED_ENCRYPTION_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE}, + #else + {"UNSUPPORTED_ENCRYPTION_TYPE", 4, 162}, + #endif + #ifdef RSA_R_UNSUPPORTED_LABEL_SOURCE + {"UNSUPPORTED_LABEL_SOURCE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_LABEL_SOURCE}, + #else + {"UNSUPPORTED_LABEL_SOURCE", 4, 163}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_ALGORITHM + {"UNSUPPORTED_MASK_ALGORITHM", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_ALGORITHM}, + #else + {"UNSUPPORTED_MASK_ALGORITHM", 4, 153}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_PARAMETER + {"UNSUPPORTED_MASK_PARAMETER", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_PARAMETER}, + #else + {"UNSUPPORTED_MASK_PARAMETER", 4, 154}, + #endif + #ifdef RSA_R_UNSUPPORTED_SIGNATURE_TYPE + {"UNSUPPORTED_SIGNATURE_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE}, + #else + {"UNSUPPORTED_SIGNATURE_TYPE", 4, 155}, + #endif + #ifdef RSA_R_VALUE_MISSING + {"VALUE_MISSING", ERR_LIB_RSA, RSA_R_VALUE_MISSING}, + #else + {"VALUE_MISSING", 4, 147}, + #endif + #ifdef RSA_R_WRONG_SIGNATURE_LENGTH + {"WRONG_SIGNATURE_LENGTH", ERR_LIB_RSA, RSA_R_WRONG_SIGNATURE_LENGTH}, + #else + {"WRONG_SIGNATURE_LENGTH", 4, 119}, + #endif + #ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY + {"APPLICATION_DATA_AFTER_CLOSE_NOTIFY", ERR_LIB_SSL, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY}, + #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 + {"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 + {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", 20, 272}, + #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 + {"AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE", 20, 143}, + #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 + {"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 + {"BAD_CHANGE_CIPHER_SPEC", 20, 103}, + #endif + #ifdef SSL_R_BAD_CIPHER + {"BAD_CIPHER", ERR_LIB_SSL, SSL_R_BAD_CIPHER}, + #else + {"BAD_CIPHER", 20, 186}, + #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 + {"BAD_DATA_RETURNED_BY_CALLBACK", 20, 106}, + #endif + #ifdef SSL_R_BAD_DECOMPRESSION + {"BAD_DECOMPRESSION", ERR_LIB_SSL, SSL_R_BAD_DECOMPRESSION}, + #else + {"BAD_DECOMPRESSION", 20, 107}, + #endif + #ifdef SSL_R_BAD_DH_VALUE + {"BAD_DH_VALUE", ERR_LIB_SSL, SSL_R_BAD_DH_VALUE}, + #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 + {"BAD_DIGEST_LENGTH", 20, 111}, + #endif + #ifdef SSL_R_BAD_EARLY_DATA + {"BAD_EARLY_DATA", ERR_LIB_SSL, SSL_R_BAD_EARLY_DATA}, + #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 + {"BAD_ECC_CERT", 20, 304}, + #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 + {"BAD_ECPOINT", 20, 306}, + #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 + {"BAD_HANDSHAKE_LENGTH", 20, 332}, + #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 + {"BAD_HELLO_REQUEST", 20, 105}, + #endif + #ifdef SSL_R_BAD_HRR_VERSION + {"BAD_HRR_VERSION", ERR_LIB_SSL, SSL_R_BAD_HRR_VERSION}, + #else + {"BAD_HRR_VERSION", 20, 263}, + #endif + #ifdef SSL_R_BAD_KEY_SHARE + {"BAD_KEY_SHARE", ERR_LIB_SSL, SSL_R_BAD_KEY_SHARE}, + #else + {"BAD_KEY_SHARE", 20, 108}, + #endif + #ifdef SSL_R_BAD_KEY_UPDATE + {"BAD_KEY_UPDATE", ERR_LIB_SSL, SSL_R_BAD_KEY_UPDATE}, + #else + {"BAD_KEY_UPDATE", 20, 122}, + #endif + #ifdef SSL_R_BAD_LEGACY_VERSION + {"BAD_LEGACY_VERSION", ERR_LIB_SSL, SSL_R_BAD_LEGACY_VERSION}, + #else + {"BAD_LEGACY_VERSION", 20, 292}, + #endif + #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 + {"BAD_MAC_LENGTH", 20, 333}, + #endif + #ifdef SSL_R_BAD_PACKET + {"BAD_PACKET", ERR_LIB_SSL, SSL_R_BAD_PACKET}, + #else + {"BAD_PACKET", 20, 240}, + #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 + {"BAD_PROTOCOL_VERSION_NUMBER", 20, 116}, + #endif + #ifdef SSL_R_BAD_PSK + {"BAD_PSK", ERR_LIB_SSL, SSL_R_BAD_PSK}, + #else + {"BAD_PSK", 20, 219}, + #endif + #ifdef SSL_R_BAD_PSK_IDENTITY + {"BAD_PSK_IDENTITY", ERR_LIB_SSL, SSL_R_BAD_PSK_IDENTITY}, + #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 + {"BAD_PSK_IDENTITY_HINT_LENGTH", 20, 316}, + #endif + #ifdef SSL_R_BAD_RECORD_TYPE + {"BAD_RECORD_TYPE", ERR_LIB_SSL, SSL_R_BAD_RECORD_TYPE}, + #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 + {"BAD_RSA_ENCRYPT", 20, 119}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"BAD_SSL_FILETYPE", 20, 124}, + #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 + {"BAD_WRITE_RETRY", 20, 127}, + #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 + {"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 + {"BLOCK_CIPHER_PAD_IS_WRONG", 20, 129}, + #endif + #ifdef SSL_R_BN_LIB + {"BN_LIB", ERR_LIB_SSL, SSL_R_BN_LIB}, + #else + {"BN_LIB", 20, 130}, + #endif + #ifdef SSL_R_CALLBACK_FAILED + {"CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_CALLBACK_FAILED}, + #else + {"CALLBACK_FAILED", 20, 234}, + #endif + #ifdef SSL_R_CANNOT_CHANGE_CIPHER + {"CANNOT_CHANGE_CIPHER", ERR_LIB_SSL, SSL_R_CANNOT_CHANGE_CIPHER}, + #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 + {"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 + {"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 + {"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 + {"CCS_RECEIVED_EARLY", 20, 133}, + #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 + {"CERT_CB_ERROR", 20, 377}, + #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 + #ifdef SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED + {"CIPHERSUITE_DIGEST_HAS_CHANGED", ERR_LIB_SSL, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED}, + #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 + {"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 + {"CIPHER_OR_HASH_UNAVAILABLE", 20, 138}, + #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 + {"COMPRESSED_LENGTH_TOO_LONG", 20, 140}, + #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 + {"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 + {"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 + {"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 + {"CONNECTION_TYPE_NOT_SET", 20, 144}, + #endif + #ifdef SSL_R_CONTEXT_NOT_DANE_ENABLED + {"CONTEXT_NOT_DANE_ENABLED", ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED}, + #else + {"CONTEXT_NOT_DANE_ENABLED", 20, 167}, + #endif + #ifdef SSL_R_COOKIE_GEN_CALLBACK_FAILURE + {"COOKIE_GEN_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_COOKIE_GEN_CALLBACK_FAILURE}, + #else + {"COOKIE_GEN_CALLBACK_FAILURE", 20, 400}, + #endif + #ifdef SSL_R_COOKIE_MISMATCH + {"COOKIE_MISMATCH", ERR_LIB_SSL, SSL_R_COOKIE_MISMATCH}, + #else + {"COOKIE_MISMATCH", 20, 308}, + #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 + {"CUSTOM_EXT_HANDLER_ALREADY_INSTALLED", 20, 206}, + #endif + #ifdef SSL_R_DANE_ALREADY_ENABLED + {"DANE_ALREADY_ENABLED", ERR_LIB_SSL, SSL_R_DANE_ALREADY_ENABLED}, + #else + {"DANE_ALREADY_ENABLED", 20, 172}, + #endif + #ifdef SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", ERR_LIB_SSL, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL}, + #else + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", 20, 173}, + #endif + #ifdef SSL_R_DANE_NOT_ENABLED + {"DANE_NOT_ENABLED", ERR_LIB_SSL, SSL_R_DANE_NOT_ENABLED}, + #else + {"DANE_NOT_ENABLED", 20, 175}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE + {"DANE_TLSA_BAD_CERTIFICATE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE", 20, 180}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", 20, 184}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DATA_LENGTH + {"DANE_TLSA_BAD_DATA_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DATA_LENGTH}, + #else + {"DANE_TLSA_BAD_DATA_LENGTH", 20, 189}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH + {"DANE_TLSA_BAD_DIGEST_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH}, + #else + {"DANE_TLSA_BAD_DIGEST_LENGTH", 20, 192}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_MATCHING_TYPE + {"DANE_TLSA_BAD_MATCHING_TYPE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE}, + #else + {"DANE_TLSA_BAD_MATCHING_TYPE", 20, 200}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_PUBLIC_KEY + {"DANE_TLSA_BAD_PUBLIC_KEY", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY}, + #else + {"DANE_TLSA_BAD_PUBLIC_KEY", 20, 201}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_SELECTOR + {"DANE_TLSA_BAD_SELECTOR", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_SELECTOR}, + #else + {"DANE_TLSA_BAD_SELECTOR", 20, 202}, + #endif + #ifdef SSL_R_DANE_TLSA_NULL_DATA + {"DANE_TLSA_NULL_DATA", ERR_LIB_SSL, SSL_R_DANE_TLSA_NULL_DATA}, + #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 + {"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 + {"DATA_LENGTH_TOO_LONG", 20, 146}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"ERROR_IN_RECEIVED_CIPHER_LIST", 20, 151}, + #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 + {"ERROR_SETTING_TLSA_BASE_DOMAIN", 20, 204}, + #endif + #ifdef SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE + {"EXCEEDS_MAX_FRAGMENT_SIZE", ERR_LIB_SSL, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE}, + #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 + {"EXCESSIVE_MESSAGE_SIZE", 20, 152}, + #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 + {"EXTRA_DATA_IN_MESSAGE", 20, 153}, + #endif + #ifdef SSL_R_EXT_LENGTH_MISMATCH + {"EXT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_EXT_LENGTH_MISMATCH}, + #else + {"EXT_LENGTH_MISMATCH", 20, 163}, + #endif + #ifdef SSL_R_FAILED_TO_INIT_ASYNC + {"FAILED_TO_INIT_ASYNC", ERR_LIB_SSL, SSL_R_FAILED_TO_INIT_ASYNC}, + #else + {"FAILED_TO_INIT_ASYNC", 20, 405}, + #endif + #ifdef SSL_R_FRAGMENTED_CLIENT_HELLO + {"FRAGMENTED_CLIENT_HELLO", ERR_LIB_SSL, SSL_R_FRAGMENTED_CLIENT_HELLO}, + #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 + {"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 + {"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 + {"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 + {"HTTPS_PROXY_REQUEST", 20, 155}, + #endif + #ifdef SSL_R_HTTP_REQUEST + {"HTTP_REQUEST", ERR_LIB_SSL, SSL_R_HTTP_REQUEST}, + #else + {"HTTP_REQUEST", 20, 156}, + #endif + #ifdef SSL_R_ILLEGAL_POINT_COMPRESSION + {"ILLEGAL_POINT_COMPRESSION", ERR_LIB_SSL, SSL_R_ILLEGAL_POINT_COMPRESSION}, + #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 + {"ILLEGAL_SUITEB_DIGEST", 20, 380}, + #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 + {"INCONSISTENT_COMPRESSION", 20, 340}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_ALPN + {"INCONSISTENT_EARLY_DATA_ALPN", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_ALPN}, + #else + {"INCONSISTENT_EARLY_DATA_ALPN", 20, 222}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_SNI + {"INCONSISTENT_EARLY_DATA_SNI", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_SNI}, + #else + {"INCONSISTENT_EARLY_DATA_SNI", 20, 231}, + #endif + #ifdef SSL_R_INCONSISTENT_EXTMS + {"INCONSISTENT_EXTMS", ERR_LIB_SSL, SSL_R_INCONSISTENT_EXTMS}, + #else + {"INCONSISTENT_EXTMS", 20, 104}, + #endif + #ifdef SSL_R_INSUFFICIENT_SECURITY + {"INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_INSUFFICIENT_SECURITY}, + #else + {"INSUFFICIENT_SECURITY", 20, 241}, + #endif + #ifdef SSL_R_INVALID_ALERT + {"INVALID_ALERT", ERR_LIB_SSL, SSL_R_INVALID_ALERT}, + #else + {"INVALID_ALERT", 20, 205}, + #endif + #ifdef SSL_R_INVALID_CCS_MESSAGE + {"INVALID_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_INVALID_CCS_MESSAGE}, + #else + {"INVALID_CCS_MESSAGE", 20, 260}, + #endif + #ifdef SSL_R_INVALID_CERTIFICATE_OR_ALG + {"INVALID_CERTIFICATE_OR_ALG", ERR_LIB_SSL, SSL_R_INVALID_CERTIFICATE_OR_ALG}, + #else + {"INVALID_CERTIFICATE_OR_ALG", 20, 238}, + #endif + #ifdef SSL_R_INVALID_COMMAND + {"INVALID_COMMAND", ERR_LIB_SSL, SSL_R_INVALID_COMMAND}, + #else + {"INVALID_COMMAND", 20, 280}, + #endif + #ifdef SSL_R_INVALID_COMPRESSION_ALGORITHM + {"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_INVALID_COMPRESSION_ALGORITHM}, + #else + {"INVALID_COMPRESSION_ALGORITHM", 20, 341}, + #endif + #ifdef SSL_R_INVALID_CONFIG + {"INVALID_CONFIG", ERR_LIB_SSL, SSL_R_INVALID_CONFIG}, + #else + {"INVALID_CONFIG", 20, 283}, + #endif + #ifdef SSL_R_INVALID_CONFIGURATION_NAME + {"INVALID_CONFIGURATION_NAME", ERR_LIB_SSL, SSL_R_INVALID_CONFIGURATION_NAME}, + #else + {"INVALID_CONFIGURATION_NAME", 20, 113}, + #endif + #ifdef SSL_R_INVALID_CONTEXT + {"INVALID_CONTEXT", ERR_LIB_SSL, SSL_R_INVALID_CONTEXT}, + #else + {"INVALID_CONTEXT", 20, 282}, + #endif + #ifdef SSL_R_INVALID_CT_VALIDATION_TYPE + {"INVALID_CT_VALIDATION_TYPE", ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE}, + #else + {"INVALID_CT_VALIDATION_TYPE", 20, 212}, + #endif + #ifdef SSL_R_INVALID_KEY_UPDATE_TYPE + {"INVALID_KEY_UPDATE_TYPE", ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE}, + #else + {"INVALID_KEY_UPDATE_TYPE", 20, 120}, + #endif + #ifdef SSL_R_INVALID_MAX_EARLY_DATA + {"INVALID_MAX_EARLY_DATA", ERR_LIB_SSL, SSL_R_INVALID_MAX_EARLY_DATA}, + #else + {"INVALID_MAX_EARLY_DATA", 20, 174}, + #endif + #ifdef SSL_R_INVALID_NULL_CMD_NAME + {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME}, + #else + {"INVALID_NULL_CMD_NAME", 20, 385}, + #endif + #ifdef SSL_R_INVALID_SEQUENCE_NUMBER + {"INVALID_SEQUENCE_NUMBER", ERR_LIB_SSL, SSL_R_INVALID_SEQUENCE_NUMBER}, + #else + {"INVALID_SEQUENCE_NUMBER", 20, 402}, + #endif + #ifdef SSL_R_INVALID_SERVERINFO_DATA + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA}, + #else + {"INVALID_SERVERINFO_DATA", 20, 388}, + #endif + #ifdef SSL_R_INVALID_SESSION_ID + {"INVALID_SESSION_ID", ERR_LIB_SSL, SSL_R_INVALID_SESSION_ID}, + #else + {"INVALID_SESSION_ID", 20, 999}, + #endif + #ifdef SSL_R_INVALID_SRP_USERNAME + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME}, + #else + {"INVALID_SRP_USERNAME", 20, 357}, + #endif + #ifdef SSL_R_INVALID_STATUS_RESPONSE + {"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE}, + #else + {"INVALID_STATUS_RESPONSE", 20, 328}, + #endif + #ifdef SSL_R_INVALID_TICKET_KEYS_LENGTH + {"INVALID_TICKET_KEYS_LENGTH", ERR_LIB_SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH}, + #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 + {"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 + {"KRB5_S_TKT_SKEW", 20, 295}, + #endif + #ifdef SSL_R_LENGTH_MISMATCH + {"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH}, + #else + {"LENGTH_MISMATCH", 20, 159}, + #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 + {"LENGTH_TOO_SHORT", 20, 160}, + #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 + {"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 + {"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 + {"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 + {"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 + {"MISSING_ECDSA_SIGNING_CERT", 20, 381}, + #endif + #ifdef SSL_R_MISSING_FATAL + {"MISSING_FATAL", ERR_LIB_SSL, SSL_R_MISSING_FATAL}, + #else + {"MISSING_FATAL", 20, 256}, + #endif + #ifdef SSL_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 20, 290}, + #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 + {"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 + {"MISSING_RSA_SIGNING_CERT", 20, 170}, + #endif + #ifdef SSL_R_MISSING_SIGALGS_EXTENSION + {"MISSING_SIGALGS_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_SIGALGS_EXTENSION}, + #else + {"MISSING_SIGALGS_EXTENSION", 20, 112}, + #endif + #ifdef SSL_R_MISSING_SIGNING_CERT + {"MISSING_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_SIGNING_CERT}, + #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 + {"MISSING_SRP_PARAM", 20, 358}, + #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 + {"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 + {"MISSING_TMP_ECDH_KEY", 20, 311}, + #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 + {"MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA", 20, 293}, + #endif + #ifdef SSL_R_MULTIPLE_SGC_RESTARTS + {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, SSL_R_MULTIPLE_SGC_RESTARTS}, + #else + {"MULTIPLE_SGC_RESTARTS", 20, 346}, + #endif + #ifdef SSL_R_NOT_ON_RECORD_BOUNDARY + {"NOT_ON_RECORD_BOUNDARY", ERR_LIB_SSL, SSL_R_NOT_ON_RECORD_BOUNDARY}, + #else + {"NOT_ON_RECORD_BOUNDARY", 20, 182}, + #endif + #ifdef SSL_R_NOT_REPLACING_CERTIFICATE + {"NOT_REPLACING_CERTIFICATE", ERR_LIB_SSL, SSL_R_NOT_REPLACING_CERTIFICATE}, + #else + {"NOT_REPLACING_CERTIFICATE", 20, 289}, + #endif + #ifdef SSL_R_NOT_SERVER + {"NOT_SERVER", ERR_LIB_SSL, SSL_R_NOT_SERVER}, + #else + {"NOT_SERVER", 20, 284}, + #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 + {"NO_CERTIFICATES_RETURNED", 20, 176}, + #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 + {"NO_CERTIFICATE_SET", 20, 179}, + #endif + #ifdef SSL_R_NO_CHANGE_FOLLOWING_HRR + {"NO_CHANGE_FOLLOWING_HRR", ERR_LIB_SSL, SSL_R_NO_CHANGE_FOLLOWING_HRR}, + #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 + {"NO_CIPHERS_AVAILABLE", 20, 181}, + #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 + {"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 + {"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 + {"NO_COMPRESSION_SPECIFIED", 20, 187}, + #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 + {"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 + {"NO_METHOD_SPECIFIED", 20, 188}, + #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 + {"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 + {"NO_PROTOCOLS_AVAILABLE", 20, 191}, + #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 + {"NO_REQUIRED_DIGEST", 20, 324}, + #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 + #ifdef SSL_R_NO_SHARED_GROUPS + {"NO_SHARED_GROUPS", ERR_LIB_SSL, SSL_R_NO_SHARED_GROUPS}, + #else + {"NO_SHARED_GROUPS", 20, 410}, + #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 + {"NO_SRTP_PROFILES", 20, 359}, + #endif + #ifdef SSL_R_NO_SUITABLE_KEY_SHARE + {"NO_SUITABLE_KEY_SHARE", ERR_LIB_SSL, SSL_R_NO_SUITABLE_KEY_SHARE}, + #else + {"NO_SUITABLE_KEY_SHARE", 20, 101}, + #endif + #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM + {"NO_SUITABLE_SIGNATURE_ALGORITHM", ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM}, + #else + {"NO_SUITABLE_SIGNATURE_ALGORITHM", 20, 118}, + #endif + #ifdef SSL_R_NO_VALID_SCTS + {"NO_VALID_SCTS", ERR_LIB_SSL, SSL_R_NO_VALID_SCTS}, + #else + {"NO_VALID_SCTS", 20, 216}, + #endif + #ifdef SSL_R_NO_VERIFY_COOKIE_CALLBACK + {"NO_VERIFY_COOKIE_CALLBACK", ERR_LIB_SSL, SSL_R_NO_VERIFY_COOKIE_CALLBACK}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"OPAQUE_PRF_INPUT_TOO_LONG", 20, 327}, + #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 + {"PACKET_LENGTH_TOO_LONG", 20, 198}, + #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 + {"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 + {"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 + {"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 + {"PEM_NAME_TOO_SHORT", 20, 392}, + #endif + #ifdef SSL_R_PIPELINE_FAILURE + {"PIPELINE_FAILURE", ERR_LIB_SSL, SSL_R_PIPELINE_FAILURE}, + #else + {"PIPELINE_FAILURE", 20, 406}, + #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 + {"POST_HANDSHAKE_AUTH_ENCODING_ERR", 20, 278}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"READ_TIMEOUT_EXPIRED", 20, 312}, + #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 + {"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 + {"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 + {"RENEGOTIATION_ENCODING_ERR", 20, 336}, + #endif + #ifdef SSL_R_RENEGOTIATION_MISMATCH + {"RENEGOTIATION_MISMATCH", ERR_LIB_SSL, SSL_R_RENEGOTIATION_MISMATCH}, + #else + {"RENEGOTIATION_MISMATCH", 20, 337}, + #endif + #ifdef SSL_R_REQUEST_PENDING + {"REQUEST_PENDING", ERR_LIB_SSL, SSL_R_REQUEST_PENDING}, + #else + {"REQUEST_PENDING", 20, 285}, + #endif + #ifdef SSL_R_REQUEST_SENT + {"REQUEST_SENT", ERR_LIB_SSL, SSL_R_REQUEST_SENT}, + #else + {"REQUEST_SENT", 20, 286}, + #endif + #ifdef SSL_R_REQUIRED_CIPHER_MISSING + {"REQUIRED_CIPHER_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_CIPHER_MISSING}, + #else + {"REQUIRED_CIPHER_MISSING", 20, 215}, + #endif + #ifdef SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING + {"REQUIRED_COMPRESSION_ALGORITHM_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING}, + #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 + {"SCSV_RECEIVED_WHEN_RENEGOTIATING", 20, 345}, + #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 + {"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 + {"SESSION_ID_CONTEXT_UNINITIALIZED", 20, 277}, + #endif + #ifdef SSL_R_SHUTDOWN_WHILE_IN_INIT + {"SHUTDOWN_WHILE_IN_INIT", ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"SSL3_EXT_INVALID_ECPOINTFORMAT", 20, 321}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", 20, 1043}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 20, 117}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #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 + {"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 + {"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 + {"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 + {"SSL_NEGATIVE_LENGTH", 20, 372}, + #endif + #ifdef SSL_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 20, 126}, + #endif + #ifdef SSL_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_SECTION_NOT_FOUND}, + #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 + {"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 + {"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 + {"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 + {"SSL_SESSION_ID_HAS_BAD_LENGTH", 20, 303}, + #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 + {"SSL_SESSION_ID_TOO_LONG", 20, 408}, + #endif + #ifdef SSL_R_SSL_SESSION_VERSION_MISMATCH + {"SSL_SESSION_VERSION_MISMATCH", ERR_LIB_SSL, SSL_R_SSL_SESSION_VERSION_MISMATCH}, + #else + {"SSL_SESSION_VERSION_MISMATCH", 20, 210}, + #endif + #ifdef SSL_R_STILL_IN_INIT + {"STILL_IN_INIT", ERR_LIB_SSL, SSL_R_STILL_IN_INIT}, + #else + {"STILL_IN_INIT", 20, 121}, + #endif + #ifdef SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED}, + #else + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", 20, 1116}, + #endif + #ifdef SSL_R_TLSV13_ALERT_MISSING_EXTENSION + {"TLSV13_ALERT_MISSING_EXTENSION", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_MISSING_EXTENSION}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"TLSV1_CERTIFICATE_UNOBTAINABLE", 20, 1111}, + #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 + {"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 + {"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 + {"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 + {"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 + {"TLS_INVALID_ECPOINTFORMAT_LIST", 20, 157}, + #endif + #ifdef SSL_R_TOO_MANY_KEY_UPDATES + {"TOO_MANY_KEY_UPDATES", ERR_LIB_SSL, SSL_R_TOO_MANY_KEY_UPDATES}, + #else + {"TOO_MANY_KEY_UPDATES", 20, 132}, + #endif + #ifdef SSL_R_TOO_MANY_WARN_ALERTS + {"TOO_MANY_WARN_ALERTS", ERR_LIB_SSL, SSL_R_TOO_MANY_WARN_ALERTS}, + #else + {"TOO_MANY_WARN_ALERTS", 20, 409}, + #endif + #ifdef SSL_R_TOO_MUCH_EARLY_DATA + {"TOO_MUCH_EARLY_DATA", ERR_LIB_SSL, SSL_R_TOO_MUCH_EARLY_DATA}, + #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 + {"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 + {"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 + {"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 + {"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 + {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", 20, 243}, + #endif + #ifdef SSL_R_UNEXPECTED_CCS_MESSAGE + {"UNEXPECTED_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_CCS_MESSAGE}, + #else + {"UNEXPECTED_CCS_MESSAGE", 20, 262}, + #endif + #ifdef SSL_R_UNEXPECTED_END_OF_EARLY_DATA + {"UNEXPECTED_END_OF_EARLY_DATA", ERR_LIB_SSL, SSL_R_UNEXPECTED_END_OF_EARLY_DATA}, + #else + {"UNEXPECTED_END_OF_EARLY_DATA", 20, 178}, + #endif + #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 + {"UNEXPECTED_RECORD", 20, 245}, + #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 + {"UNKNOWN_ALERT_TYPE", 20, 246}, + #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 + {"UNKNOWN_CIPHER_RETURNED", 20, 248}, + #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 + {"UNKNOWN_CMD_NAME", 20, 386}, + #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 + {"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 + {"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 + {"UNKNOWN_PKEY_TYPE", 20, 251}, + #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 + {"UNKNOWN_SSL_VERSION", 20, 254}, + #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 + {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", 20, 338}, + #endif + #ifdef SSL_R_UNSOLICITED_EXTENSION + {"UNSOLICITED_EXTENSION", ERR_LIB_SSL, SSL_R_UNSOLICITED_EXTENSION}, + #else + {"UNSOLICITED_EXTENSION", 20, 217}, + #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 + {"UNSUPPORTED_DIGEST_TYPE", 20, 326}, + #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 + {"UNSUPPORTED_PROTOCOL", 20, 258}, + #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 + {"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 + {"USE_SRTP_NOT_NEGOTIATED", 20, 369}, + #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 + {"VERSION_TOO_LOW", 20, 396}, + #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 + {"WRONG_CIPHER_RETURNED", 20, 261}, + #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 + {"WRONG_SIGNATURE_LENGTH", 20, 264}, + #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 + {"WRONG_SIGNATURE_TYPE", 20, 370}, + #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 + {"WRONG_VERSION_NUMBER", 20, 267}, + #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 + {"X509_VERIFICATION_SETUP_PROBLEMS", 20, 269}, + #endif + #ifdef TS_R_BAD_PKCS7_TYPE + {"BAD_PKCS7_TYPE", ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE}, + #else + {"BAD_PKCS7_TYPE", 47, 132}, + #endif + #ifdef TS_R_BAD_TYPE + {"BAD_TYPE", ERR_LIB_TS, TS_R_BAD_TYPE}, + #else + {"BAD_TYPE", 47, 133}, + #endif + #ifdef TS_R_CANNOT_LOAD_CERT + {"CANNOT_LOAD_CERT", ERR_LIB_TS, TS_R_CANNOT_LOAD_CERT}, + #else + {"CANNOT_LOAD_CERT", 47, 137}, + #endif + #ifdef TS_R_CANNOT_LOAD_KEY + {"CANNOT_LOAD_KEY", ERR_LIB_TS, TS_R_CANNOT_LOAD_KEY}, + #else + {"CANNOT_LOAD_KEY", 47, 138}, + #endif + #ifdef TS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_TS, TS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 47, 100}, + #endif + #ifdef TS_R_COULD_NOT_SET_ENGINE + {"COULD_NOT_SET_ENGINE", ERR_LIB_TS, TS_R_COULD_NOT_SET_ENGINE}, + #else + {"COULD_NOT_SET_ENGINE", 47, 127}, + #endif + #ifdef TS_R_COULD_NOT_SET_TIME + {"COULD_NOT_SET_TIME", ERR_LIB_TS, TS_R_COULD_NOT_SET_TIME}, + #else + {"COULD_NOT_SET_TIME", 47, 115}, + #endif + #ifdef TS_R_DETACHED_CONTENT + {"DETACHED_CONTENT", ERR_LIB_TS, TS_R_DETACHED_CONTENT}, + #else + {"DETACHED_CONTENT", 47, 134}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_ERROR + {"ESS_ADD_SIGNING_CERT_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_ERROR", 47, 116}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR + {"ESS_ADD_SIGNING_CERT_V2_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_V2_ERROR", 47, 139}, + #endif + #ifdef TS_R_ESS_SIGNING_CERTIFICATE_ERROR + {"ESS_SIGNING_CERTIFICATE_ERROR", ERR_LIB_TS, TS_R_ESS_SIGNING_CERTIFICATE_ERROR}, + #else + {"ESS_SIGNING_CERTIFICATE_ERROR", 47, 101}, + #endif + #ifdef TS_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_TS, TS_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 47, 102}, + #endif + #ifdef TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE}, + #else + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", 47, 117}, + #endif + #ifdef TS_R_MESSAGE_IMPRINT_MISMATCH + {"MESSAGE_IMPRINT_MISMATCH", ERR_LIB_TS, TS_R_MESSAGE_IMPRINT_MISMATCH}, + #else + {"MESSAGE_IMPRINT_MISMATCH", 47, 103}, + #endif + #ifdef TS_R_NONCE_MISMATCH + {"NONCE_MISMATCH", ERR_LIB_TS, TS_R_NONCE_MISMATCH}, + #else + {"NONCE_MISMATCH", 47, 104}, + #endif + #ifdef TS_R_NONCE_NOT_RETURNED + {"NONCE_NOT_RETURNED", ERR_LIB_TS, TS_R_NONCE_NOT_RETURNED}, + #else + {"NONCE_NOT_RETURNED", 47, 105}, + #endif + #ifdef TS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_TS, TS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 47, 106}, + #endif + #ifdef TS_R_NO_TIME_STAMP_TOKEN + {"NO_TIME_STAMP_TOKEN", ERR_LIB_TS, TS_R_NO_TIME_STAMP_TOKEN}, + #else + {"NO_TIME_STAMP_TOKEN", 47, 107}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 47, 118}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR + {"PKCS7_ADD_SIGNED_ATTR_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR}, + #else + {"PKCS7_ADD_SIGNED_ATTR_ERROR", 47, 119}, + #endif + #ifdef TS_R_PKCS7_TO_TS_TST_INFO_FAILED + {"PKCS7_TO_TS_TST_INFO_FAILED", ERR_LIB_TS, TS_R_PKCS7_TO_TS_TST_INFO_FAILED}, + #else + {"PKCS7_TO_TS_TST_INFO_FAILED", 47, 129}, + #endif + #ifdef TS_R_POLICY_MISMATCH + {"POLICY_MISMATCH", ERR_LIB_TS, TS_R_POLICY_MISMATCH}, + #else + {"POLICY_MISMATCH", 47, 108}, + #endif + #ifdef TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 47, 120}, + #endif + #ifdef TS_R_RESPONSE_SETUP_ERROR + {"RESPONSE_SETUP_ERROR", ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR}, + #else + {"RESPONSE_SETUP_ERROR", 47, 121}, + #endif + #ifdef TS_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_TS, TS_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 47, 109}, + #endif + #ifdef TS_R_THERE_MUST_BE_ONE_SIGNER + {"THERE_MUST_BE_ONE_SIGNER", ERR_LIB_TS, TS_R_THERE_MUST_BE_ONE_SIGNER}, + #else + {"THERE_MUST_BE_ONE_SIGNER", 47, 110}, + #endif + #ifdef TS_R_TIME_SYSCALL_ERROR + {"TIME_SYSCALL_ERROR", ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR}, + #else + {"TIME_SYSCALL_ERROR", 47, 122}, + #endif + #ifdef TS_R_TOKEN_NOT_PRESENT + {"TOKEN_NOT_PRESENT", ERR_LIB_TS, TS_R_TOKEN_NOT_PRESENT}, + #else + {"TOKEN_NOT_PRESENT", 47, 130}, + #endif + #ifdef TS_R_TOKEN_PRESENT + {"TOKEN_PRESENT", ERR_LIB_TS, TS_R_TOKEN_PRESENT}, + #else + {"TOKEN_PRESENT", 47, 131}, + #endif + #ifdef TS_R_TSA_NAME_MISMATCH + {"TSA_NAME_MISMATCH", ERR_LIB_TS, TS_R_TSA_NAME_MISMATCH}, + #else + {"TSA_NAME_MISMATCH", 47, 111}, + #endif + #ifdef TS_R_TSA_UNTRUSTED + {"TSA_UNTRUSTED", ERR_LIB_TS, TS_R_TSA_UNTRUSTED}, + #else + {"TSA_UNTRUSTED", 47, 112}, + #endif + #ifdef TS_R_TST_INFO_SETUP_ERROR + {"TST_INFO_SETUP_ERROR", ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR}, + #else + {"TST_INFO_SETUP_ERROR", 47, 123}, + #endif + #ifdef TS_R_TS_DATASIGN + {"TS_DATASIGN", ERR_LIB_TS, TS_R_TS_DATASIGN}, + #else + {"TS_DATASIGN", 47, 124}, + #endif + #ifdef TS_R_UNACCEPTABLE_POLICY + {"UNACCEPTABLE_POLICY", ERR_LIB_TS, TS_R_UNACCEPTABLE_POLICY}, + #else + {"UNACCEPTABLE_POLICY", 47, 125}, + #endif + #ifdef TS_R_UNSUPPORTED_MD_ALGORITHM + {"UNSUPPORTED_MD_ALGORITHM", ERR_LIB_TS, TS_R_UNSUPPORTED_MD_ALGORITHM}, + #else + {"UNSUPPORTED_MD_ALGORITHM", 47, 126}, + #endif + #ifdef TS_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_TS, TS_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 47, 113}, + #endif + #ifdef TS_R_VAR_BAD_VALUE + {"VAR_BAD_VALUE", ERR_LIB_TS, TS_R_VAR_BAD_VALUE}, + #else + {"VAR_BAD_VALUE", 47, 135}, + #endif + #ifdef TS_R_VAR_LOOKUP_FAILURE + {"VAR_LOOKUP_FAILURE", ERR_LIB_TS, TS_R_VAR_LOOKUP_FAILURE}, + #else + {"VAR_LOOKUP_FAILURE", 47, 136}, + #endif + #ifdef TS_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_TS, TS_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 47, 114}, + #endif + #ifdef UI_R_COMMON_OK_AND_CANCEL_CHARACTERS + {"COMMON_OK_AND_CANCEL_CHARACTERS", ERR_LIB_UI, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS}, + #else + {"COMMON_OK_AND_CANCEL_CHARACTERS", 40, 104}, + #endif + #ifdef UI_R_INDEX_TOO_LARGE + {"INDEX_TOO_LARGE", ERR_LIB_UI, UI_R_INDEX_TOO_LARGE}, + #else + {"INDEX_TOO_LARGE", 40, 102}, + #endif + #ifdef UI_R_INDEX_TOO_SMALL + {"INDEX_TOO_SMALL", ERR_LIB_UI, UI_R_INDEX_TOO_SMALL}, + #else + {"INDEX_TOO_SMALL", 40, 103}, + #endif + #ifdef UI_R_NO_RESULT_BUFFER + {"NO_RESULT_BUFFER", ERR_LIB_UI, UI_R_NO_RESULT_BUFFER}, + #else + {"NO_RESULT_BUFFER", 40, 105}, + #endif + #ifdef UI_R_PROCESSING_ERROR + {"PROCESSING_ERROR", ERR_LIB_UI, UI_R_PROCESSING_ERROR}, + #else + {"PROCESSING_ERROR", 40, 107}, + #endif + #ifdef UI_R_RESULT_TOO_LARGE + {"RESULT_TOO_LARGE", ERR_LIB_UI, UI_R_RESULT_TOO_LARGE}, + #else + {"RESULT_TOO_LARGE", 40, 100}, + #endif + #ifdef UI_R_RESULT_TOO_SMALL + {"RESULT_TOO_SMALL", ERR_LIB_UI, UI_R_RESULT_TOO_SMALL}, + #else + {"RESULT_TOO_SMALL", 40, 101}, + #endif + #ifdef UI_R_SYSASSIGN_ERROR + {"SYSASSIGN_ERROR", ERR_LIB_UI, UI_R_SYSASSIGN_ERROR}, + #else + {"SYSASSIGN_ERROR", 40, 109}, + #endif + #ifdef UI_R_SYSDASSGN_ERROR + {"SYSDASSGN_ERROR", ERR_LIB_UI, UI_R_SYSDASSGN_ERROR}, + #else + {"SYSDASSGN_ERROR", 40, 110}, + #endif + #ifdef UI_R_SYSQIOW_ERROR + {"SYSQIOW_ERROR", ERR_LIB_UI, UI_R_SYSQIOW_ERROR}, + #else + {"SYSQIOW_ERROR", 40, 111}, + #endif + #ifdef UI_R_UNKNOWN_CONTROL_COMMAND + {"UNKNOWN_CONTROL_COMMAND", ERR_LIB_UI, UI_R_UNKNOWN_CONTROL_COMMAND}, + #else + {"UNKNOWN_CONTROL_COMMAND", 40, 106}, + #endif + #ifdef UI_R_UNKNOWN_TTYGET_ERRNO_VALUE + {"UNKNOWN_TTYGET_ERRNO_VALUE", ERR_LIB_UI, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE}, + #else + {"UNKNOWN_TTYGET_ERRNO_VALUE", 40, 108}, + #endif + #ifdef UI_R_USER_DATA_DUPLICATION_UNSUPPORTED + {"USER_DATA_DUPLICATION_UNSUPPORTED", ERR_LIB_UI, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED}, + #else + {"USER_DATA_DUPLICATION_UNSUPPORTED", 40, 112}, + #endif + #ifdef X509V3_R_BAD_IP_ADDRESS + {"BAD_IP_ADDRESS", ERR_LIB_X509V3, X509V3_R_BAD_IP_ADDRESS}, + #else + {"BAD_IP_ADDRESS", 34, 118}, + #endif + #ifdef X509V3_R_BAD_OBJECT + {"BAD_OBJECT", ERR_LIB_X509V3, X509V3_R_BAD_OBJECT}, + #else + {"BAD_OBJECT", 34, 119}, + #endif + #ifdef X509V3_R_BN_DEC2BN_ERROR + {"BN_DEC2BN_ERROR", ERR_LIB_X509V3, X509V3_R_BN_DEC2BN_ERROR}, + #else + {"BN_DEC2BN_ERROR", 34, 100}, + #endif + #ifdef X509V3_R_BN_TO_ASN1_INTEGER_ERROR + {"BN_TO_ASN1_INTEGER_ERROR", ERR_LIB_X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR}, + #else + {"BN_TO_ASN1_INTEGER_ERROR", 34, 101}, + #endif + #ifdef X509V3_R_DIRNAME_ERROR + {"DIRNAME_ERROR", ERR_LIB_X509V3, X509V3_R_DIRNAME_ERROR}, + #else + {"DIRNAME_ERROR", 34, 149}, + #endif + #ifdef X509V3_R_DISTPOINT_ALREADY_SET + {"DISTPOINT_ALREADY_SET", ERR_LIB_X509V3, X509V3_R_DISTPOINT_ALREADY_SET}, + #else + {"DISTPOINT_ALREADY_SET", 34, 160}, + #endif + #ifdef X509V3_R_DUPLICATE_ZONE_ID + {"DUPLICATE_ZONE_ID", ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID}, + #else + {"DUPLICATE_ZONE_ID", 34, 133}, + #endif + #ifdef X509V3_R_ERROR_CONVERTING_ZONE + {"ERROR_CONVERTING_ZONE", ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE}, + #else + {"ERROR_CONVERTING_ZONE", 34, 131}, + #endif + #ifdef X509V3_R_ERROR_CREATING_EXTENSION + {"ERROR_CREATING_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_CREATING_EXTENSION}, + #else + {"ERROR_CREATING_EXTENSION", 34, 144}, + #endif + #ifdef X509V3_R_ERROR_IN_EXTENSION + {"ERROR_IN_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION}, + #else + {"ERROR_IN_EXTENSION", 34, 128}, + #endif + #ifdef X509V3_R_EXPECTED_A_SECTION_NAME + {"EXPECTED_A_SECTION_NAME", ERR_LIB_X509V3, X509V3_R_EXPECTED_A_SECTION_NAME}, + #else + {"EXPECTED_A_SECTION_NAME", 34, 137}, + #endif + #ifdef X509V3_R_EXTENSION_EXISTS + {"EXTENSION_EXISTS", ERR_LIB_X509V3, X509V3_R_EXTENSION_EXISTS}, + #else + {"EXTENSION_EXISTS", 34, 145}, + #endif + #ifdef X509V3_R_EXTENSION_NAME_ERROR + {"EXTENSION_NAME_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR}, + #else + {"EXTENSION_NAME_ERROR", 34, 115}, + #endif + #ifdef X509V3_R_EXTENSION_NOT_FOUND + {"EXTENSION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND}, + #else + {"EXTENSION_NOT_FOUND", 34, 102}, + #endif + #ifdef X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED + {"EXTENSION_SETTING_NOT_SUPPORTED", ERR_LIB_X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED}, + #else + {"EXTENSION_SETTING_NOT_SUPPORTED", 34, 103}, + #endif + #ifdef X509V3_R_EXTENSION_VALUE_ERROR + {"EXTENSION_VALUE_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR}, + #else + {"EXTENSION_VALUE_ERROR", 34, 116}, + #endif + #ifdef X509V3_R_ILLEGAL_EMPTY_EXTENSION + {"ILLEGAL_EMPTY_EXTENSION", ERR_LIB_X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION}, + #else + {"ILLEGAL_EMPTY_EXTENSION", 34, 151}, + #endif + #ifdef X509V3_R_INCORRECT_POLICY_SYNTAX_TAG + {"INCORRECT_POLICY_SYNTAX_TAG", ERR_LIB_X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG}, + #else + {"INCORRECT_POLICY_SYNTAX_TAG", 34, 152}, + #endif + #ifdef X509V3_R_INVALID_ASNUMBER + {"INVALID_ASNUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_ASNUMBER}, + #else + {"INVALID_ASNUMBER", 34, 162}, + #endif + #ifdef X509V3_R_INVALID_ASRANGE + {"INVALID_ASRANGE", ERR_LIB_X509V3, X509V3_R_INVALID_ASRANGE}, + #else + {"INVALID_ASRANGE", 34, 163}, + #endif + #ifdef X509V3_R_INVALID_BOOLEAN_STRING + {"INVALID_BOOLEAN_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_BOOLEAN_STRING}, + #else + {"INVALID_BOOLEAN_STRING", 34, 104}, + #endif + #ifdef X509V3_R_INVALID_EXTENSION_STRING + {"INVALID_EXTENSION_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_EXTENSION_STRING}, + #else + {"INVALID_EXTENSION_STRING", 34, 105}, + #endif + #ifdef X509V3_R_INVALID_INHERITANCE + {"INVALID_INHERITANCE", ERR_LIB_X509V3, X509V3_R_INVALID_INHERITANCE}, + #else + {"INVALID_INHERITANCE", 34, 165}, + #endif + #ifdef X509V3_R_INVALID_IPADDRESS + {"INVALID_IPADDRESS", ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS}, + #else + {"INVALID_IPADDRESS", 34, 166}, + #endif + #ifdef X509V3_R_INVALID_MULTIPLE_RDNS + {"INVALID_MULTIPLE_RDNS", ERR_LIB_X509V3, X509V3_R_INVALID_MULTIPLE_RDNS}, + #else + {"INVALID_MULTIPLE_RDNS", 34, 161}, + #endif + #ifdef X509V3_R_INVALID_NAME + {"INVALID_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_NAME}, + #else + {"INVALID_NAME", 34, 106}, + #endif + #ifdef X509V3_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 34, 107}, + #endif + #ifdef X509V3_R_INVALID_NULL_NAME + {"INVALID_NULL_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_NAME}, + #else + {"INVALID_NULL_NAME", 34, 108}, + #endif + #ifdef X509V3_R_INVALID_NULL_VALUE + {"INVALID_NULL_VALUE", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_VALUE}, + #else + {"INVALID_NULL_VALUE", 34, 109}, + #endif + #ifdef X509V3_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 34, 140}, + #endif + #ifdef X509V3_R_INVALID_NUMBERS + {"INVALID_NUMBERS", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBERS}, + #else + {"INVALID_NUMBERS", 34, 141}, + #endif + #ifdef X509V3_R_INVALID_OBJECT_IDENTIFIER + {"INVALID_OBJECT_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER}, + #else + {"INVALID_OBJECT_IDENTIFIER", 34, 110}, + #endif + #ifdef X509V3_R_INVALID_OPTION + {"INVALID_OPTION", ERR_LIB_X509V3, X509V3_R_INVALID_OPTION}, + #else + {"INVALID_OPTION", 34, 138}, + #endif + #ifdef X509V3_R_INVALID_POLICY_IDENTIFIER + {"INVALID_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER}, + #else + {"INVALID_POLICY_IDENTIFIER", 34, 134}, + #endif + #ifdef X509V3_R_INVALID_PROXY_POLICY_SETTING + {"INVALID_PROXY_POLICY_SETTING", ERR_LIB_X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING}, + #else + {"INVALID_PROXY_POLICY_SETTING", 34, 153}, + #endif + #ifdef X509V3_R_INVALID_PURPOSE + {"INVALID_PURPOSE", ERR_LIB_X509V3, X509V3_R_INVALID_PURPOSE}, + #else + {"INVALID_PURPOSE", 34, 146}, + #endif + #ifdef X509V3_R_INVALID_SAFI + {"INVALID_SAFI", ERR_LIB_X509V3, X509V3_R_INVALID_SAFI}, + #else + {"INVALID_SAFI", 34, 164}, + #endif + #ifdef X509V3_R_INVALID_SECTION + {"INVALID_SECTION", ERR_LIB_X509V3, X509V3_R_INVALID_SECTION}, + #else + {"INVALID_SECTION", 34, 135}, + #endif + #ifdef X509V3_R_INVALID_SYNTAX + {"INVALID_SYNTAX", ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX}, + #else + {"INVALID_SYNTAX", 34, 143}, + #endif + #ifdef X509V3_R_ISSUER_DECODE_ERROR + {"ISSUER_DECODE_ERROR", ERR_LIB_X509V3, X509V3_R_ISSUER_DECODE_ERROR}, + #else + {"ISSUER_DECODE_ERROR", 34, 126}, + #endif + #ifdef X509V3_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_X509V3, X509V3_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 34, 124}, + #endif + #ifdef X509V3_R_NEED_ORGANIZATION_AND_NUMBERS + {"NEED_ORGANIZATION_AND_NUMBERS", ERR_LIB_X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS}, + #else + {"NEED_ORGANIZATION_AND_NUMBERS", 34, 142}, + #endif + #ifdef X509V3_R_NO_CONFIG_DATABASE + {"NO_CONFIG_DATABASE", ERR_LIB_X509V3, X509V3_R_NO_CONFIG_DATABASE}, + #else + {"NO_CONFIG_DATABASE", 34, 136}, + #endif + #ifdef X509V3_R_NO_ISSUER_CERTIFICATE + {"NO_ISSUER_CERTIFICATE", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE}, + #else + {"NO_ISSUER_CERTIFICATE", 34, 121}, + #endif + #ifdef X509V3_R_NO_ISSUER_DETAILS + {"NO_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_DETAILS}, + #else + {"NO_ISSUER_DETAILS", 34, 127}, + #endif + #ifdef X509V3_R_NO_POLICY_IDENTIFIER + {"NO_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_NO_POLICY_IDENTIFIER}, + #else + {"NO_POLICY_IDENTIFIER", 34, 139}, + #endif + #ifdef X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", ERR_LIB_X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED}, + #else + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", 34, 154}, + #endif + #ifdef X509V3_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 34, 114}, + #endif + #ifdef X509V3_R_NO_SUBJECT_DETAILS + {"NO_SUBJECT_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS}, + #else + {"NO_SUBJECT_DETAILS", 34, 125}, + #endif + #ifdef X509V3_R_OPERATION_NOT_DEFINED + {"OPERATION_NOT_DEFINED", ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED}, + #else + {"OPERATION_NOT_DEFINED", 34, 148}, + #endif + #ifdef X509V3_R_OTHERNAME_ERROR + {"OTHERNAME_ERROR", ERR_LIB_X509V3, X509V3_R_OTHERNAME_ERROR}, + #else + {"OTHERNAME_ERROR", 34, 147}, + #endif + #ifdef X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED + {"POLICY_LANGUAGE_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED}, + #else + {"POLICY_LANGUAGE_ALREADY_DEFINED", 34, 155}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH + {"POLICY_PATH_LENGTH", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH}, + #else + {"POLICY_PATH_LENGTH", 34, 156}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED}, + #else + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", 34, 157}, + #endif + #ifdef X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", ERR_LIB_X509V3, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY}, + #else + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", 34, 159}, + #endif + #ifdef X509V3_R_SECTION_NOT_FOUND + {"SECTION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND}, + #else + {"SECTION_NOT_FOUND", 34, 150}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS + {"UNABLE_TO_GET_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS}, + #else + {"UNABLE_TO_GET_ISSUER_DETAILS", 34, 122}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_KEYID + {"UNABLE_TO_GET_ISSUER_KEYID", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID}, + #else + {"UNABLE_TO_GET_ISSUER_KEYID", 34, 123}, + #endif + #ifdef X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT + {"UNKNOWN_BIT_STRING_ARGUMENT", ERR_LIB_X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT}, + #else + {"UNKNOWN_BIT_STRING_ARGUMENT", 34, 111}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION + {"UNKNOWN_EXTENSION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION}, + #else + {"UNKNOWN_EXTENSION", 34, 129}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION_NAME + {"UNKNOWN_EXTENSION_NAME", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME}, + #else + {"UNKNOWN_EXTENSION_NAME", 34, 130}, + #endif + #ifdef X509V3_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 34, 120}, + #endif + #ifdef X509V3_R_UNSUPPORTED_OPTION + {"UNSUPPORTED_OPTION", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_OPTION}, + #else + {"UNSUPPORTED_OPTION", 34, 117}, + #endif + #ifdef X509V3_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 34, 167}, + #endif + #ifdef X509V3_R_USER_TOO_LONG + {"USER_TOO_LONG", ERR_LIB_X509V3, X509V3_R_USER_TOO_LONG}, + #else + {"USER_TOO_LONG", 34, 132}, + #endif + #ifdef X509_R_AKID_MISMATCH + {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, + #else + {"AKID_MISMATCH", 11, 110}, + #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 + {"BAD_X509_FILETYPE", 11, 100}, + #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 + {"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 + {"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 + {"CRL_ALREADY_DELTA", 11, 127}, + #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 + {"ERR_ASN1_LIB", 11, 102}, + #endif + #ifdef X509_R_IDP_MISMATCH + {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, + #else + {"IDP_MISMATCH", 11, 128}, + #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 + {"INVALID_DIRECTORY", 11, 113}, + #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 + {"INVALID_TRUST", 11, 123}, + #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 + {"KEY_TYPE_MISMATCH", 11, 115}, + #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 + {"LOADING_CERT_DIR", 11, 103}, + #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 + {"METHOD_NOT_SUPPORTED", 11, 124}, + #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 + {"NEWER_CRL_NOT_NEWER", 11, 132}, + #endif + #ifdef X509_R_NO_CERTIFICATE_FOUND + {"NO_CERTIFICATE_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND}, + #else + {"NO_CERTIFICATE_FOUND", 11, 135}, + #endif + #ifdef X509_R_NO_CERTIFICATE_OR_CRL_FOUND + {"NO_CERTIFICATE_OR_CRL_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND}, + #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 + {"NO_CERT_SET_FOR_US_TO_VERIFY", 11, 105}, + #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 + {"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 + {"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 + {"PUBLIC_KEY_ENCODE_ERROR", 11, 126}, + #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 + {"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 + {"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 + {"UNKNOWN_KEY_TYPE", 11, 117}, + #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 + {"UNKNOWN_PURPOSE_ID", 11, 121}, + #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 + {"UNSUPPORTED_ALGORITHM", 11, 111}, + #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 + {"WRONG_TYPE", 11, 122}, + #endif + { NULL } +}; diff --git a/python/Modules/_ssl_data_111.h b/python/Modules/_ssl_data_111.h new file mode 100755 index 0000000..85a2f7e --- /dev/null +++ b/python/Modules/_ssl_data_111.h @@ -0,0 +1,6525 @@ +/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2021-04-09T09:36:21.493286 */ +static struct py_ssl_library_code library_codes[] = { +#ifdef ERR_LIB_ASN1 + {"ASN1", ERR_LIB_ASN1}, +#endif +#ifdef ERR_LIB_ASYNC + {"ASYNC", ERR_LIB_ASYNC}, +#endif +#ifdef ERR_LIB_BIO + {"BIO", ERR_LIB_BIO}, +#endif +#ifdef ERR_LIB_BN + {"BN", ERR_LIB_BN}, +#endif +#ifdef ERR_LIB_BUF + {"BUF", ERR_LIB_BUF}, +#endif +#ifdef ERR_LIB_CMS + {"CMS", ERR_LIB_CMS}, +#endif +#ifdef ERR_LIB_COMP + {"COMP", ERR_LIB_COMP}, +#endif +#ifdef ERR_LIB_CONF + {"CONF", ERR_LIB_CONF}, +#endif +#ifdef ERR_LIB_CRYPTO + {"CRYPTO", ERR_LIB_CRYPTO}, +#endif +#ifdef ERR_LIB_CT + {"CT", ERR_LIB_CT}, +#endif +#ifdef ERR_LIB_DH + {"DH", ERR_LIB_DH}, +#endif +#ifdef ERR_LIB_DSA + {"DSA", ERR_LIB_DSA}, +#endif +#ifdef ERR_LIB_DSO + {"DSO", ERR_LIB_DSO}, +#endif +#ifdef ERR_LIB_EC + {"EC", ERR_LIB_EC}, +#endif +#ifdef ERR_LIB_ECDH + {"ECDH", ERR_LIB_ECDH}, +#endif +#ifdef ERR_LIB_ECDSA + {"ECDSA", ERR_LIB_ECDSA}, +#endif +#ifdef ERR_LIB_ENGINE + {"ENGINE", ERR_LIB_ENGINE}, +#endif +#ifdef ERR_LIB_EVP + {"EVP", ERR_LIB_EVP}, +#endif +#ifdef ERR_LIB_FIPS + {"FIPS", ERR_LIB_FIPS}, +#endif +#ifdef ERR_LIB_HMAC + {"HMAC", ERR_LIB_HMAC}, +#endif +#ifdef ERR_LIB_JPAKE + {"JPAKE", ERR_LIB_JPAKE}, +#endif +#ifdef ERR_LIB_KDF + {"KDF", ERR_LIB_KDF}, +#endif +#ifdef ERR_LIB_METH + {"METH", ERR_LIB_METH}, +#endif +#ifdef ERR_LIB_NONE + {"NONE", ERR_LIB_NONE}, +#endif +#ifdef ERR_LIB_OBJ + {"OBJ", ERR_LIB_OBJ}, +#endif +#ifdef ERR_LIB_OCSP + {"OCSP", ERR_LIB_OCSP}, +#endif +#ifdef ERR_LIB_OSSL_STORE + {"OSSL_STORE", ERR_LIB_OSSL_STORE}, +#endif +#ifdef ERR_LIB_PEM + {"PEM", ERR_LIB_PEM}, +#endif +#ifdef ERR_LIB_PKCS12 + {"PKCS12", ERR_LIB_PKCS12}, +#endif +#ifdef ERR_LIB_PKCS7 + {"PKCS7", ERR_LIB_PKCS7}, +#endif +#ifdef ERR_LIB_PROXY + {"PROXY", ERR_LIB_PROXY}, +#endif +#ifdef ERR_LIB_RAND + {"RAND", ERR_LIB_RAND}, +#endif +#ifdef ERR_LIB_RSA + {"RSA", ERR_LIB_RSA}, +#endif +#ifdef ERR_LIB_RSAREF + {"RSAREF", ERR_LIB_RSAREF}, +#endif +#ifdef ERR_LIB_SM2 + {"SM2", ERR_LIB_SM2}, +#endif +#ifdef ERR_LIB_SSL + {"SSL", ERR_LIB_SSL}, +#endif +#ifdef ERR_LIB_SSL2 + {"SSL2", ERR_LIB_SSL2}, +#endif +#ifdef ERR_LIB_SSL23 + {"SSL23", ERR_LIB_SSL23}, +#endif +#ifdef ERR_LIB_SSL3 + {"SSL3", ERR_LIB_SSL3}, +#endif +#ifdef ERR_LIB_SYS + {"SYS", ERR_LIB_SYS}, +#endif +#ifdef ERR_LIB_TS + {"TS", ERR_LIB_TS}, +#endif +#ifdef ERR_LIB_UI + {"UI", ERR_LIB_UI}, +#endif +#ifdef ERR_LIB_USER + {"USER", ERR_LIB_USER}, +#endif +#ifdef 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[] = { + #ifdef ASN1_R_ADDING_OBJECT + {"ADDING_OBJECT", ERR_LIB_ASN1, ASN1_R_ADDING_OBJECT}, + #else + {"ADDING_OBJECT", 13, 171}, + #endif + #ifdef ASN1_R_ASN1_PARSE_ERROR + {"ASN1_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_PARSE_ERROR}, + #else + {"ASN1_PARSE_ERROR", 13, 203}, + #endif + #ifdef ASN1_R_ASN1_SIG_PARSE_ERROR + {"ASN1_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR}, + #else + {"ASN1_SIG_PARSE_ERROR", 13, 204}, + #endif + #ifdef ASN1_R_AUX_ERROR + {"AUX_ERROR", ERR_LIB_ASN1, ASN1_R_AUX_ERROR}, + #else + {"AUX_ERROR", 13, 100}, + #endif + #ifdef ASN1_R_BAD_OBJECT_HEADER + {"BAD_OBJECT_HEADER", ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER}, + #else + {"BAD_OBJECT_HEADER", 13, 102}, + #endif + #ifdef ASN1_R_BAD_TEMPLATE + {"BAD_TEMPLATE", ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE}, + #else + {"BAD_TEMPLATE", 13, 230}, + #endif + #ifdef ASN1_R_BMPSTRING_IS_WRONG_LENGTH + {"BMPSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH}, + #else + {"BMPSTRING_IS_WRONG_LENGTH", 13, 214}, + #endif + #ifdef ASN1_R_BN_LIB + {"BN_LIB", ERR_LIB_ASN1, ASN1_R_BN_LIB}, + #else + {"BN_LIB", 13, 105}, + #endif + #ifdef ASN1_R_BOOLEAN_IS_WRONG_LENGTH + {"BOOLEAN_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH}, + #else + {"BOOLEAN_IS_WRONG_LENGTH", 13, 106}, + #endif + #ifdef ASN1_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_ASN1, ASN1_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 13, 107}, + #endif + #ifdef ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 13, 108}, + #endif + #ifdef ASN1_R_CONTEXT_NOT_INITIALISED + {"CONTEXT_NOT_INITIALISED", ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED}, + #else + {"CONTEXT_NOT_INITIALISED", 13, 217}, + #endif + #ifdef ASN1_R_DATA_IS_WRONG + {"DATA_IS_WRONG", ERR_LIB_ASN1, ASN1_R_DATA_IS_WRONG}, + #else + {"DATA_IS_WRONG", 13, 109}, + #endif + #ifdef ASN1_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 13, 110}, + #endif + #ifdef ASN1_R_DEPTH_EXCEEDED + {"DEPTH_EXCEEDED", ERR_LIB_ASN1, ASN1_R_DEPTH_EXCEEDED}, + #else + {"DEPTH_EXCEEDED", 13, 174}, + #endif + #ifdef ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED}, + #else + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", 13, 198}, + #endif + #ifdef ASN1_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_ASN1, ASN1_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 13, 112}, + #endif + #ifdef ASN1_R_ERROR_GETTING_TIME + {"ERROR_GETTING_TIME", ERR_LIB_ASN1, ASN1_R_ERROR_GETTING_TIME}, + #else + {"ERROR_GETTING_TIME", 13, 173}, + #endif + #ifdef ASN1_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_ASN1, ASN1_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 13, 172}, + #endif + #ifdef ASN1_R_ERROR_SETTING_CIPHER_PARAMS + {"ERROR_SETTING_CIPHER_PARAMS", ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS}, + #else + {"ERROR_SETTING_CIPHER_PARAMS", 13, 114}, + #endif + #ifdef ASN1_R_EXPECTING_AN_INTEGER + {"EXPECTING_AN_INTEGER", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_INTEGER}, + #else + {"EXPECTING_AN_INTEGER", 13, 115}, + #endif + #ifdef ASN1_R_EXPECTING_AN_OBJECT + {"EXPECTING_AN_OBJECT", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_OBJECT}, + #else + {"EXPECTING_AN_OBJECT", 13, 116}, + #endif + #ifdef ASN1_R_EXPLICIT_LENGTH_MISMATCH + {"EXPLICIT_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH}, + #else + {"EXPLICIT_LENGTH_MISMATCH", 13, 119}, + #endif + #ifdef ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED + {"EXPLICIT_TAG_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED}, + #else + {"EXPLICIT_TAG_NOT_CONSTRUCTED", 13, 120}, + #endif + #ifdef ASN1_R_FIELD_MISSING + {"FIELD_MISSING", ERR_LIB_ASN1, ASN1_R_FIELD_MISSING}, + #else + {"FIELD_MISSING", 13, 121}, + #endif + #ifdef ASN1_R_FIRST_NUM_TOO_LARGE + {"FIRST_NUM_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_FIRST_NUM_TOO_LARGE}, + #else + {"FIRST_NUM_TOO_LARGE", 13, 122}, + #endif + #ifdef ASN1_R_HEADER_TOO_LONG + {"HEADER_TOO_LONG", ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}, + #else + {"HEADER_TOO_LONG", 13, 123}, + #endif + #ifdef ASN1_R_ILLEGAL_BITSTRING_FORMAT + {"ILLEGAL_BITSTRING_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT}, + #else + {"ILLEGAL_BITSTRING_FORMAT", 13, 175}, + #endif + #ifdef ASN1_R_ILLEGAL_BOOLEAN + {"ILLEGAL_BOOLEAN", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BOOLEAN}, + #else + {"ILLEGAL_BOOLEAN", 13, 176}, + #endif + #ifdef ASN1_R_ILLEGAL_CHARACTERS + {"ILLEGAL_CHARACTERS", ERR_LIB_ASN1, ASN1_R_ILLEGAL_CHARACTERS}, + #else + {"ILLEGAL_CHARACTERS", 13, 124}, + #endif + #ifdef ASN1_R_ILLEGAL_FORMAT + {"ILLEGAL_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_FORMAT}, + #else + {"ILLEGAL_FORMAT", 13, 177}, + #endif + #ifdef ASN1_R_ILLEGAL_HEX + {"ILLEGAL_HEX", ERR_LIB_ASN1, ASN1_R_ILLEGAL_HEX}, + #else + {"ILLEGAL_HEX", 13, 178}, + #endif + #ifdef ASN1_R_ILLEGAL_IMPLICIT_TAG + {"ILLEGAL_IMPLICIT_TAG", ERR_LIB_ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG}, + #else + {"ILLEGAL_IMPLICIT_TAG", 13, 179}, + #endif + #ifdef ASN1_R_ILLEGAL_INTEGER + {"ILLEGAL_INTEGER", ERR_LIB_ASN1, ASN1_R_ILLEGAL_INTEGER}, + #else + {"ILLEGAL_INTEGER", 13, 180}, + #endif + #ifdef ASN1_R_ILLEGAL_NEGATIVE_VALUE + {"ILLEGAL_NEGATIVE_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE}, + #else + {"ILLEGAL_NEGATIVE_VALUE", 13, 226}, + #endif + #ifdef ASN1_R_ILLEGAL_NESTED_TAGGING + {"ILLEGAL_NESTED_TAGGING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING}, + #else + {"ILLEGAL_NESTED_TAGGING", 13, 181}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL + {"ILLEGAL_NULL", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL}, + #else + {"ILLEGAL_NULL", 13, 125}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL_VALUE + {"ILLEGAL_NULL_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL_VALUE}, + #else + {"ILLEGAL_NULL_VALUE", 13, 182}, + #endif + #ifdef ASN1_R_ILLEGAL_OBJECT + {"ILLEGAL_OBJECT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT}, + #else + {"ILLEGAL_OBJECT", 13, 183}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONAL_ANY + {"ILLEGAL_OPTIONAL_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY}, + #else + {"ILLEGAL_OPTIONAL_ANY", 13, 126}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE}, + #else + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", 13, 170}, + #endif + #ifdef ASN1_R_ILLEGAL_PADDING + {"ILLEGAL_PADDING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_PADDING}, + #else + {"ILLEGAL_PADDING", 13, 221}, + #endif + #ifdef ASN1_R_ILLEGAL_TAGGED_ANY + {"ILLEGAL_TAGGED_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TAGGED_ANY}, + #else + {"ILLEGAL_TAGGED_ANY", 13, 127}, + #endif + #ifdef ASN1_R_ILLEGAL_TIME_VALUE + {"ILLEGAL_TIME_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TIME_VALUE}, + #else + {"ILLEGAL_TIME_VALUE", 13, 184}, + #endif + #ifdef ASN1_R_ILLEGAL_ZERO_CONTENT + {"ILLEGAL_ZERO_CONTENT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT}, + #else + {"ILLEGAL_ZERO_CONTENT", 13, 222}, + #endif + #ifdef ASN1_R_INTEGER_NOT_ASCII_FORMAT + {"INTEGER_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT}, + #else + {"INTEGER_NOT_ASCII_FORMAT", 13, 185}, + #endif + #ifdef ASN1_R_INTEGER_TOO_LARGE_FOR_LONG + {"INTEGER_TOO_LARGE_FOR_LONG", ERR_LIB_ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG}, + #else + {"INTEGER_TOO_LARGE_FOR_LONG", 13, 128}, + #endif + #ifdef ASN1_R_INVALID_BIT_STRING_BITS_LEFT + {"INVALID_BIT_STRING_BITS_LEFT", ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}, + #else + {"INVALID_BIT_STRING_BITS_LEFT", 13, 220}, + #endif + #ifdef ASN1_R_INVALID_BMPSTRING_LENGTH + {"INVALID_BMPSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH}, + #else + {"INVALID_BMPSTRING_LENGTH", 13, 129}, + #endif + #ifdef ASN1_R_INVALID_DIGIT + {"INVALID_DIGIT", ERR_LIB_ASN1, ASN1_R_INVALID_DIGIT}, + #else + {"INVALID_DIGIT", 13, 130}, + #endif + #ifdef ASN1_R_INVALID_MIME_TYPE + {"INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_INVALID_MIME_TYPE}, + #else + {"INVALID_MIME_TYPE", 13, 205}, + #endif + #ifdef ASN1_R_INVALID_MODIFIER + {"INVALID_MODIFIER", ERR_LIB_ASN1, ASN1_R_INVALID_MODIFIER}, + #else + {"INVALID_MODIFIER", 13, 186}, + #endif + #ifdef ASN1_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 13, 187}, + #endif + #ifdef ASN1_R_INVALID_OBJECT_ENCODING + {"INVALID_OBJECT_ENCODING", ERR_LIB_ASN1, ASN1_R_INVALID_OBJECT_ENCODING}, + #else + {"INVALID_OBJECT_ENCODING", 13, 216}, + #endif + #ifdef ASN1_R_INVALID_SCRYPT_PARAMETERS + {"INVALID_SCRYPT_PARAMETERS", ERR_LIB_ASN1, ASN1_R_INVALID_SCRYPT_PARAMETERS}, + #else + {"INVALID_SCRYPT_PARAMETERS", 13, 227}, + #endif + #ifdef ASN1_R_INVALID_SEPARATOR + {"INVALID_SEPARATOR", ERR_LIB_ASN1, ASN1_R_INVALID_SEPARATOR}, + #else + {"INVALID_SEPARATOR", 13, 131}, + #endif + #ifdef ASN1_R_INVALID_STRING_TABLE_VALUE + {"INVALID_STRING_TABLE_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE}, + #else + {"INVALID_STRING_TABLE_VALUE", 13, 218}, + #endif + #ifdef ASN1_R_INVALID_UNIVERSALSTRING_LENGTH + {"INVALID_UNIVERSALSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH}, + #else + {"INVALID_UNIVERSALSTRING_LENGTH", 13, 133}, + #endif + #ifdef ASN1_R_INVALID_UTF8STRING + {"INVALID_UTF8STRING", ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING}, + #else + {"INVALID_UTF8STRING", 13, 134}, + #endif + #ifdef ASN1_R_INVALID_VALUE + {"INVALID_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_VALUE}, + #else + {"INVALID_VALUE", 13, 219}, + #endif + #ifdef ASN1_R_LIST_ERROR + {"LIST_ERROR", ERR_LIB_ASN1, ASN1_R_LIST_ERROR}, + #else + {"LIST_ERROR", 13, 188}, + #endif + #ifdef ASN1_R_MIME_NO_CONTENT_TYPE + {"MIME_NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_MIME_NO_CONTENT_TYPE}, + #else + {"MIME_NO_CONTENT_TYPE", 13, 206}, + #endif + #ifdef ASN1_R_MIME_PARSE_ERROR + {"MIME_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_PARSE_ERROR}, + #else + {"MIME_PARSE_ERROR", 13, 207}, + #endif + #ifdef ASN1_R_MIME_SIG_PARSE_ERROR + {"MIME_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR}, + #else + {"MIME_SIG_PARSE_ERROR", 13, 208}, + #endif + #ifdef ASN1_R_MISSING_EOC + {"MISSING_EOC", ERR_LIB_ASN1, ASN1_R_MISSING_EOC}, + #else + {"MISSING_EOC", 13, 137}, + #endif + #ifdef ASN1_R_MISSING_SECOND_NUMBER + {"MISSING_SECOND_NUMBER", ERR_LIB_ASN1, ASN1_R_MISSING_SECOND_NUMBER}, + #else + {"MISSING_SECOND_NUMBER", 13, 138}, + #endif + #ifdef ASN1_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 13, 189}, + #endif + #ifdef ASN1_R_MSTRING_NOT_UNIVERSAL + {"MSTRING_NOT_UNIVERSAL", ERR_LIB_ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL}, + #else + {"MSTRING_NOT_UNIVERSAL", 13, 139}, + #endif + #ifdef ASN1_R_MSTRING_WRONG_TAG + {"MSTRING_WRONG_TAG", ERR_LIB_ASN1, ASN1_R_MSTRING_WRONG_TAG}, + #else + {"MSTRING_WRONG_TAG", 13, 140}, + #endif + #ifdef ASN1_R_NESTED_ASN1_STRING + {"NESTED_ASN1_STRING", ERR_LIB_ASN1, ASN1_R_NESTED_ASN1_STRING}, + #else + {"NESTED_ASN1_STRING", 13, 197}, + #endif + #ifdef ASN1_R_NESTED_TOO_DEEP + {"NESTED_TOO_DEEP", ERR_LIB_ASN1, ASN1_R_NESTED_TOO_DEEP}, + #else + {"NESTED_TOO_DEEP", 13, 201}, + #endif + #ifdef ASN1_R_NON_HEX_CHARACTERS + {"NON_HEX_CHARACTERS", ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS}, + #else + {"NON_HEX_CHARACTERS", 13, 141}, + #endif + #ifdef ASN1_R_NOT_ASCII_FORMAT + {"NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_NOT_ASCII_FORMAT}, + #else + {"NOT_ASCII_FORMAT", 13, 190}, + #endif + #ifdef ASN1_R_NOT_ENOUGH_DATA + {"NOT_ENOUGH_DATA", ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA}, + #else + {"NOT_ENOUGH_DATA", 13, 142}, + #endif + #ifdef ASN1_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 13, 209}, + #endif + #ifdef ASN1_R_NO_MATCHING_CHOICE_TYPE + {"NO_MATCHING_CHOICE_TYPE", ERR_LIB_ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE}, + #else + {"NO_MATCHING_CHOICE_TYPE", 13, 143}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BODY_FAILURE + {"NO_MULTIPART_BODY_FAILURE", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE}, + #else + {"NO_MULTIPART_BODY_FAILURE", 13, 210}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BOUNDARY + {"NO_MULTIPART_BOUNDARY", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY}, + #else + {"NO_MULTIPART_BOUNDARY", 13, 211}, + #endif + #ifdef ASN1_R_NO_SIG_CONTENT_TYPE + {"NO_SIG_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE}, + #else + {"NO_SIG_CONTENT_TYPE", 13, 212}, + #endif + #ifdef ASN1_R_NULL_IS_WRONG_LENGTH + {"NULL_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_NULL_IS_WRONG_LENGTH}, + #else + {"NULL_IS_WRONG_LENGTH", 13, 144}, + #endif + #ifdef ASN1_R_OBJECT_NOT_ASCII_FORMAT + {"OBJECT_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT}, + #else + {"OBJECT_NOT_ASCII_FORMAT", 13, 191}, + #endif + #ifdef ASN1_R_ODD_NUMBER_OF_CHARS + {"ODD_NUMBER_OF_CHARS", ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS}, + #else + {"ODD_NUMBER_OF_CHARS", 13, 145}, + #endif + #ifdef ASN1_R_SECOND_NUMBER_TOO_LARGE + {"SECOND_NUMBER_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE}, + #else + {"SECOND_NUMBER_TOO_LARGE", 13, 147}, + #endif + #ifdef ASN1_R_SEQUENCE_LENGTH_MISMATCH + {"SEQUENCE_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH}, + #else + {"SEQUENCE_LENGTH_MISMATCH", 13, 148}, + #endif + #ifdef ASN1_R_SEQUENCE_NOT_CONSTRUCTED + {"SEQUENCE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED}, + #else + {"SEQUENCE_NOT_CONSTRUCTED", 13, 149}, + #endif + #ifdef ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG + {"SEQUENCE_OR_SET_NEEDS_CONFIG", ERR_LIB_ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG}, + #else + {"SEQUENCE_OR_SET_NEEDS_CONFIG", 13, 192}, + #endif + #ifdef ASN1_R_SHORT_LINE + {"SHORT_LINE", ERR_LIB_ASN1, ASN1_R_SHORT_LINE}, + #else + {"SHORT_LINE", 13, 150}, + #endif + #ifdef ASN1_R_SIG_INVALID_MIME_TYPE + {"SIG_INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE}, + #else + {"SIG_INVALID_MIME_TYPE", 13, 213}, + #endif + #ifdef ASN1_R_STREAMING_NOT_SUPPORTED + {"STREAMING_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED}, + #else + {"STREAMING_NOT_SUPPORTED", 13, 202}, + #endif + #ifdef ASN1_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 13, 151}, + #endif + #ifdef ASN1_R_STRING_TOO_SHORT + {"STRING_TOO_SHORT", ERR_LIB_ASN1, ASN1_R_STRING_TOO_SHORT}, + #else + {"STRING_TOO_SHORT", 13, 152}, + #endif + #ifdef ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_ASN1, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 13, 154}, + #endif + #ifdef ASN1_R_TIME_NOT_ASCII_FORMAT + {"TIME_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT}, + #else + {"TIME_NOT_ASCII_FORMAT", 13, 193}, + #endif + #ifdef ASN1_R_TOO_LARGE + {"TOO_LARGE", ERR_LIB_ASN1, ASN1_R_TOO_LARGE}, + #else + {"TOO_LARGE", 13, 223}, + #endif + #ifdef ASN1_R_TOO_LONG + {"TOO_LONG", ERR_LIB_ASN1, ASN1_R_TOO_LONG}, + #else + {"TOO_LONG", 13, 155}, + #endif + #ifdef ASN1_R_TOO_SMALL + {"TOO_SMALL", ERR_LIB_ASN1, ASN1_R_TOO_SMALL}, + #else + {"TOO_SMALL", 13, 224}, + #endif + #ifdef ASN1_R_TYPE_NOT_CONSTRUCTED + {"TYPE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED}, + #else + {"TYPE_NOT_CONSTRUCTED", 13, 156}, + #endif + #ifdef ASN1_R_TYPE_NOT_PRIMITIVE + {"TYPE_NOT_PRIMITIVE", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_PRIMITIVE}, + #else + {"TYPE_NOT_PRIMITIVE", 13, 195}, + #endif + #ifdef ASN1_R_UNEXPECTED_EOC + {"UNEXPECTED_EOC", ERR_LIB_ASN1, ASN1_R_UNEXPECTED_EOC}, + #else + {"UNEXPECTED_EOC", 13, 159}, + #endif + #ifdef ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH + {"UNIVERSALSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH}, + #else + {"UNIVERSALSTRING_IS_WRONG_LENGTH", 13, 215}, + #endif + #ifdef ASN1_R_UNKNOWN_FORMAT + {"UNKNOWN_FORMAT", ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT}, + #else + {"UNKNOWN_FORMAT", 13, 160}, + #endif + #ifdef ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", 13, 161}, + #endif + #ifdef ASN1_R_UNKNOWN_OBJECT_TYPE + {"UNKNOWN_OBJECT_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_OBJECT_TYPE}, + #else + {"UNKNOWN_OBJECT_TYPE", 13, 162}, + #endif + #ifdef ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE + {"UNKNOWN_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE}, + #else + {"UNKNOWN_PUBLIC_KEY_TYPE", 13, 163}, + #endif + #ifdef ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM + {"UNKNOWN_SIGNATURE_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM}, + #else + {"UNKNOWN_SIGNATURE_ALGORITHM", 13, 199}, + #endif + #ifdef ASN1_R_UNKNOWN_TAG + {"UNKNOWN_TAG", ERR_LIB_ASN1, ASN1_R_UNKNOWN_TAG}, + #else + {"UNKNOWN_TAG", 13, 194}, + #endif + #ifdef ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE}, + #else + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", 13, 164}, + #endif + #ifdef ASN1_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 13, 228}, + #endif + #ifdef ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE + {"UNSUPPORTED_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE}, + #else + {"UNSUPPORTED_PUBLIC_KEY_TYPE", 13, 167}, + #endif + #ifdef ASN1_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 13, 196}, + #endif + #ifdef ASN1_R_WRONG_INTEGER_TYPE + {"WRONG_INTEGER_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_INTEGER_TYPE}, + #else + {"WRONG_INTEGER_TYPE", 13, 225}, + #endif + #ifdef ASN1_R_WRONG_PUBLIC_KEY_TYPE + {"WRONG_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE}, + #else + {"WRONG_PUBLIC_KEY_TYPE", 13, 200}, + #endif + #ifdef ASN1_R_WRONG_TAG + {"WRONG_TAG", ERR_LIB_ASN1, ASN1_R_WRONG_TAG}, + #else + {"WRONG_TAG", 13, 168}, + #endif + #ifdef ASYNC_R_FAILED_TO_SET_POOL + {"FAILED_TO_SET_POOL", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SET_POOL}, + #else + {"FAILED_TO_SET_POOL", 51, 101}, + #endif + #ifdef ASYNC_R_FAILED_TO_SWAP_CONTEXT + {"FAILED_TO_SWAP_CONTEXT", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT}, + #else + {"FAILED_TO_SWAP_CONTEXT", 51, 102}, + #endif + #ifdef ASYNC_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ASYNC, ASYNC_R_INIT_FAILED}, + #else + {"INIT_FAILED", 51, 105}, + #endif + #ifdef ASYNC_R_INVALID_POOL_SIZE + {"INVALID_POOL_SIZE", ERR_LIB_ASYNC, ASYNC_R_INVALID_POOL_SIZE}, + #else + {"INVALID_POOL_SIZE", 51, 103}, + #endif + #ifdef BIO_R_ACCEPT_ERROR + {"ACCEPT_ERROR", ERR_LIB_BIO, BIO_R_ACCEPT_ERROR}, + #else + {"ACCEPT_ERROR", 32, 100}, + #endif + #ifdef BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET + {"ADDRINFO_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET}, + #else + {"ADDRINFO_ADDR_IS_NOT_AF_INET", 32, 141}, + #endif + #ifdef BIO_R_AMBIGUOUS_HOST_OR_SERVICE + {"AMBIGUOUS_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_AMBIGUOUS_HOST_OR_SERVICE}, + #else + {"AMBIGUOUS_HOST_OR_SERVICE", 32, 129}, + #endif + #ifdef BIO_R_BAD_FOPEN_MODE + {"BAD_FOPEN_MODE", ERR_LIB_BIO, BIO_R_BAD_FOPEN_MODE}, + #else + {"BAD_FOPEN_MODE", 32, 101}, + #endif + #ifdef BIO_R_BROKEN_PIPE + {"BROKEN_PIPE", ERR_LIB_BIO, BIO_R_BROKEN_PIPE}, + #else + {"BROKEN_PIPE", 32, 124}, + #endif + #ifdef BIO_R_CONNECT_ERROR + {"CONNECT_ERROR", ERR_LIB_BIO, BIO_R_CONNECT_ERROR}, + #else + {"CONNECT_ERROR", 32, 103}, + #endif + #ifdef BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET}, + #else + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", 32, 107}, + #endif + #ifdef BIO_R_GETSOCKNAME_ERROR + {"GETSOCKNAME_ERROR", ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR}, + #else + {"GETSOCKNAME_ERROR", 32, 132}, + #endif + #ifdef BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS + {"GETSOCKNAME_TRUNCATED_ADDRESS", ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS}, + #else + {"GETSOCKNAME_TRUNCATED_ADDRESS", 32, 133}, + #endif + #ifdef BIO_R_GETTING_SOCKTYPE + {"GETTING_SOCKTYPE", ERR_LIB_BIO, BIO_R_GETTING_SOCKTYPE}, + #else + {"GETTING_SOCKTYPE", 32, 134}, + #endif + #ifdef BIO_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 32, 125}, + #endif + #ifdef BIO_R_INVALID_SOCKET + {"INVALID_SOCKET", ERR_LIB_BIO, BIO_R_INVALID_SOCKET}, + #else + {"INVALID_SOCKET", 32, 135}, + #endif + #ifdef BIO_R_IN_USE + {"IN_USE", ERR_LIB_BIO, BIO_R_IN_USE}, + #else + {"IN_USE", 32, 123}, + #endif + #ifdef BIO_R_LENGTH_TOO_LONG + {"LENGTH_TOO_LONG", ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG}, + #else + {"LENGTH_TOO_LONG", 32, 102}, + #endif + #ifdef BIO_R_LISTEN_V6_ONLY + {"LISTEN_V6_ONLY", ERR_LIB_BIO, BIO_R_LISTEN_V6_ONLY}, + #else + {"LISTEN_V6_ONLY", 32, 136}, + #endif + #ifdef BIO_R_LOOKUP_RETURNED_NOTHING + {"LOOKUP_RETURNED_NOTHING", ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING}, + #else + {"LOOKUP_RETURNED_NOTHING", 32, 142}, + #endif + #ifdef BIO_R_MALFORMED_HOST_OR_SERVICE + {"MALFORMED_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE}, + #else + {"MALFORMED_HOST_OR_SERVICE", 32, 130}, + #endif + #ifdef BIO_R_NBIO_CONNECT_ERROR + {"NBIO_CONNECT_ERROR", ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR}, + #else + {"NBIO_CONNECT_ERROR", 32, 110}, + #endif + #ifdef BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED}, + #else + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", 32, 143}, + #endif + #ifdef BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED}, + #else + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", 32, 144}, + #endif + #ifdef BIO_R_NO_PORT_DEFINED + {"NO_PORT_DEFINED", ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED}, + #else + {"NO_PORT_DEFINED", 32, 113}, + #endif + #ifdef BIO_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_BIO, BIO_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 32, 128}, + #endif + #ifdef BIO_R_NULL_PARAMETER + {"NULL_PARAMETER", ERR_LIB_BIO, BIO_R_NULL_PARAMETER}, + #else + {"NULL_PARAMETER", 32, 115}, + #endif + #ifdef BIO_R_UNABLE_TO_BIND_SOCKET + {"UNABLE_TO_BIND_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_BIND_SOCKET}, + #else + {"UNABLE_TO_BIND_SOCKET", 32, 117}, + #endif + #ifdef BIO_R_UNABLE_TO_CREATE_SOCKET + {"UNABLE_TO_CREATE_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET}, + #else + {"UNABLE_TO_CREATE_SOCKET", 32, 118}, + #endif + #ifdef BIO_R_UNABLE_TO_KEEPALIVE + {"UNABLE_TO_KEEPALIVE", ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE}, + #else + {"UNABLE_TO_KEEPALIVE", 32, 137}, + #endif + #ifdef BIO_R_UNABLE_TO_LISTEN_SOCKET + {"UNABLE_TO_LISTEN_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_LISTEN_SOCKET}, + #else + {"UNABLE_TO_LISTEN_SOCKET", 32, 119}, + #endif + #ifdef BIO_R_UNABLE_TO_NODELAY + {"UNABLE_TO_NODELAY", ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY}, + #else + {"UNABLE_TO_NODELAY", 32, 138}, + #endif + #ifdef BIO_R_UNABLE_TO_REUSEADDR + {"UNABLE_TO_REUSEADDR", ERR_LIB_BIO, BIO_R_UNABLE_TO_REUSEADDR}, + #else + {"UNABLE_TO_REUSEADDR", 32, 139}, + #endif + #ifdef BIO_R_UNAVAILABLE_IP_FAMILY + {"UNAVAILABLE_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY}, + #else + {"UNAVAILABLE_IP_FAMILY", 32, 145}, + #endif + #ifdef BIO_R_UNINITIALIZED + {"UNINITIALIZED", ERR_LIB_BIO, BIO_R_UNINITIALIZED}, + #else + {"UNINITIALIZED", 32, 120}, + #endif + #ifdef BIO_R_UNKNOWN_INFO_TYPE + {"UNKNOWN_INFO_TYPE", ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE}, + #else + {"UNKNOWN_INFO_TYPE", 32, 140}, + #endif + #ifdef BIO_R_UNSUPPORTED_IP_FAMILY + {"UNSUPPORTED_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY}, + #else + {"UNSUPPORTED_IP_FAMILY", 32, 146}, + #endif + #ifdef BIO_R_UNSUPPORTED_METHOD + {"UNSUPPORTED_METHOD", ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD}, + #else + {"UNSUPPORTED_METHOD", 32, 121}, + #endif + #ifdef BIO_R_UNSUPPORTED_PROTOCOL_FAMILY + {"UNSUPPORTED_PROTOCOL_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY}, + #else + {"UNSUPPORTED_PROTOCOL_FAMILY", 32, 131}, + #endif + #ifdef BIO_R_WRITE_TO_READ_ONLY_BIO + {"WRITE_TO_READ_ONLY_BIO", ERR_LIB_BIO, BIO_R_WRITE_TO_READ_ONLY_BIO}, + #else + {"WRITE_TO_READ_ONLY_BIO", 32, 126}, + #endif + #ifdef BIO_R_WSASTARTUP + {"WSASTARTUP", ERR_LIB_BIO, BIO_R_WSASTARTUP}, + #else + {"WSASTARTUP", 32, 122}, + #endif + #ifdef BN_R_ARG2_LT_ARG3 + {"ARG2_LT_ARG3", ERR_LIB_BN, BN_R_ARG2_LT_ARG3}, + #else + {"ARG2_LT_ARG3", 3, 100}, + #endif + #ifdef BN_R_BAD_RECIPROCAL + {"BAD_RECIPROCAL", ERR_LIB_BN, BN_R_BAD_RECIPROCAL}, + #else + {"BAD_RECIPROCAL", 3, 101}, + #endif + #ifdef BN_R_BIGNUM_TOO_LONG + {"BIGNUM_TOO_LONG", ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG}, + #else + {"BIGNUM_TOO_LONG", 3, 114}, + #endif + #ifdef BN_R_BITS_TOO_SMALL + {"BITS_TOO_SMALL", ERR_LIB_BN, BN_R_BITS_TOO_SMALL}, + #else + {"BITS_TOO_SMALL", 3, 118}, + #endif + #ifdef BN_R_CALLED_WITH_EVEN_MODULUS + {"CALLED_WITH_EVEN_MODULUS", ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS}, + #else + {"CALLED_WITH_EVEN_MODULUS", 3, 102}, + #endif + #ifdef BN_R_DIV_BY_ZERO + {"DIV_BY_ZERO", ERR_LIB_BN, BN_R_DIV_BY_ZERO}, + #else + {"DIV_BY_ZERO", 3, 103}, + #endif + #ifdef BN_R_ENCODING_ERROR + {"ENCODING_ERROR", ERR_LIB_BN, BN_R_ENCODING_ERROR}, + #else + {"ENCODING_ERROR", 3, 104}, + #endif + #ifdef BN_R_EXPAND_ON_STATIC_BIGNUM_DATA + {"EXPAND_ON_STATIC_BIGNUM_DATA", ERR_LIB_BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA}, + #else + {"EXPAND_ON_STATIC_BIGNUM_DATA", 3, 105}, + #endif + #ifdef BN_R_INPUT_NOT_REDUCED + {"INPUT_NOT_REDUCED", ERR_LIB_BN, BN_R_INPUT_NOT_REDUCED}, + #else + {"INPUT_NOT_REDUCED", 3, 110}, + #endif + #ifdef BN_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_BN, BN_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 3, 106}, + #endif + #ifdef BN_R_INVALID_RANGE + {"INVALID_RANGE", ERR_LIB_BN, BN_R_INVALID_RANGE}, + #else + {"INVALID_RANGE", 3, 115}, + #endif + #ifdef BN_R_INVALID_SHIFT + {"INVALID_SHIFT", ERR_LIB_BN, BN_R_INVALID_SHIFT}, + #else + {"INVALID_SHIFT", 3, 119}, + #endif + #ifdef BN_R_NOT_A_SQUARE + {"NOT_A_SQUARE", ERR_LIB_BN, BN_R_NOT_A_SQUARE}, + #else + {"NOT_A_SQUARE", 3, 111}, + #endif + #ifdef BN_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_BN, BN_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 3, 107}, + #endif + #ifdef BN_R_NO_INVERSE + {"NO_INVERSE", ERR_LIB_BN, BN_R_NO_INVERSE}, + #else + {"NO_INVERSE", 3, 108}, + #endif + #ifdef BN_R_NO_SOLUTION + {"NO_SOLUTION", ERR_LIB_BN, BN_R_NO_SOLUTION}, + #else + {"NO_SOLUTION", 3, 116}, + #endif + #ifdef BN_R_PRIVATE_KEY_TOO_LARGE + {"PRIVATE_KEY_TOO_LARGE", ERR_LIB_BN, BN_R_PRIVATE_KEY_TOO_LARGE}, + #else + {"PRIVATE_KEY_TOO_LARGE", 3, 117}, + #endif + #ifdef BN_R_P_IS_NOT_PRIME + {"P_IS_NOT_PRIME", ERR_LIB_BN, BN_R_P_IS_NOT_PRIME}, + #else + {"P_IS_NOT_PRIME", 3, 112}, + #endif + #ifdef BN_R_TOO_MANY_ITERATIONS + {"TOO_MANY_ITERATIONS", ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS}, + #else + {"TOO_MANY_ITERATIONS", 3, 113}, + #endif + #ifdef BN_R_TOO_MANY_TEMPORARY_VARIABLES + {"TOO_MANY_TEMPORARY_VARIABLES", ERR_LIB_BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES}, + #else + {"TOO_MANY_TEMPORARY_VARIABLES", 3, 109}, + #endif + #ifdef CMS_R_ADD_SIGNER_ERROR + {"ADD_SIGNER_ERROR", ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR}, + #else + {"ADD_SIGNER_ERROR", 46, 99}, + #endif + #ifdef CMS_R_ATTRIBUTE_ERROR + {"ATTRIBUTE_ERROR", ERR_LIB_CMS, CMS_R_ATTRIBUTE_ERROR}, + #else + {"ATTRIBUTE_ERROR", 46, 161}, + #endif + #ifdef CMS_R_CERTIFICATE_ALREADY_PRESENT + {"CERTIFICATE_ALREADY_PRESENT", ERR_LIB_CMS, CMS_R_CERTIFICATE_ALREADY_PRESENT}, + #else + {"CERTIFICATE_ALREADY_PRESENT", 46, 175}, + #endif + #ifdef CMS_R_CERTIFICATE_HAS_NO_KEYID + {"CERTIFICATE_HAS_NO_KEYID", ERR_LIB_CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID}, + #else + {"CERTIFICATE_HAS_NO_KEYID", 46, 160}, + #endif + #ifdef CMS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 46, 100}, + #endif + #ifdef CMS_R_CIPHER_INITIALISATION_ERROR + {"CIPHER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_INITIALISATION_ERROR}, + #else + {"CIPHER_INITIALISATION_ERROR", 46, 101}, + #endif + #ifdef CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR + {"CIPHER_PARAMETER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR}, + #else + {"CIPHER_PARAMETER_INITIALISATION_ERROR", 46, 102}, + #endif + #ifdef CMS_R_CMS_DATAFINAL_ERROR + {"CMS_DATAFINAL_ERROR", ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR}, + #else + {"CMS_DATAFINAL_ERROR", 46, 103}, + #endif + #ifdef CMS_R_CMS_LIB + {"CMS_LIB", ERR_LIB_CMS, CMS_R_CMS_LIB}, + #else + {"CMS_LIB", 46, 104}, + #endif + #ifdef CMS_R_CONTENTIDENTIFIER_MISMATCH + {"CONTENTIDENTIFIER_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENTIDENTIFIER_MISMATCH}, + #else + {"CONTENTIDENTIFIER_MISMATCH", 46, 170}, + #endif + #ifdef CMS_R_CONTENT_NOT_FOUND + {"CONTENT_NOT_FOUND", ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND}, + #else + {"CONTENT_NOT_FOUND", 46, 105}, + #endif + #ifdef CMS_R_CONTENT_TYPE_MISMATCH + {"CONTENT_TYPE_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_MISMATCH}, + #else + {"CONTENT_TYPE_MISMATCH", 46, 171}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA}, + #else + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", 46, 106}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA}, + #else + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", 46, 107}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA + {"CONTENT_TYPE_NOT_SIGNED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA}, + #else + {"CONTENT_TYPE_NOT_SIGNED_DATA", 46, 108}, + #endif + #ifdef CMS_R_CONTENT_VERIFY_ERROR + {"CONTENT_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR}, + #else + {"CONTENT_VERIFY_ERROR", 46, 109}, + #endif + #ifdef CMS_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_CMS, CMS_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 46, 110}, + #endif + #ifdef CMS_R_CTRL_FAILURE + {"CTRL_FAILURE", ERR_LIB_CMS, CMS_R_CTRL_FAILURE}, + #else + {"CTRL_FAILURE", 46, 111}, + #endif + #ifdef CMS_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_CMS, CMS_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 46, 112}, + #endif + #ifdef CMS_R_ERROR_GETTING_PUBLIC_KEY + {"ERROR_GETTING_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_ERROR_GETTING_PUBLIC_KEY}, + #else + {"ERROR_GETTING_PUBLIC_KEY", 46, 113}, + #endif + #ifdef CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE}, + #else + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", 46, 114}, + #endif + #ifdef CMS_R_ERROR_SETTING_KEY + {"ERROR_SETTING_KEY", ERR_LIB_CMS, CMS_R_ERROR_SETTING_KEY}, + #else + {"ERROR_SETTING_KEY", 46, 115}, + #endif + #ifdef CMS_R_ERROR_SETTING_RECIPIENTINFO + {"ERROR_SETTING_RECIPIENTINFO", ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO}, + #else + {"ERROR_SETTING_RECIPIENTINFO", 46, 116}, + #endif + #ifdef CMS_R_INVALID_ENCRYPTED_KEY_LENGTH + {"INVALID_ENCRYPTED_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH}, + #else + {"INVALID_ENCRYPTED_KEY_LENGTH", 46, 117}, + #endif + #ifdef CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER + {"INVALID_KEY_ENCRYPTION_PARAMETER", ERR_LIB_CMS, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER}, + #else + {"INVALID_KEY_ENCRYPTION_PARAMETER", 46, 176}, + #endif + #ifdef CMS_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 46, 118}, + #endif + #ifdef CMS_R_MD_BIO_INIT_ERROR + {"MD_BIO_INIT_ERROR", ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR}, + #else + {"MD_BIO_INIT_ERROR", 46, 119}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", 46, 120}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_WRONG_LENGTH + {"MESSAGEDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_WRONG_LENGTH", 46, 121}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_ERROR + {"MSGSIGDIGEST_ERROR", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR}, + #else + {"MSGSIGDIGEST_ERROR", 46, 172}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE + {"MSGSIGDIGEST_VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE}, + #else + {"MSGSIGDIGEST_VERIFICATION_FAILURE", 46, 162}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_WRONG_LENGTH + {"MSGSIGDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_WRONG_LENGTH}, + #else + {"MSGSIGDIGEST_WRONG_LENGTH", 46, 163}, + #endif + #ifdef CMS_R_NEED_ONE_SIGNER + {"NEED_ONE_SIGNER", ERR_LIB_CMS, CMS_R_NEED_ONE_SIGNER}, + #else + {"NEED_ONE_SIGNER", 46, 164}, + #endif + #ifdef CMS_R_NOT_A_SIGNED_RECEIPT + {"NOT_A_SIGNED_RECEIPT", ERR_LIB_CMS, CMS_R_NOT_A_SIGNED_RECEIPT}, + #else + {"NOT_A_SIGNED_RECEIPT", 46, 165}, + #endif + #ifdef CMS_R_NOT_ENCRYPTED_DATA + {"NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_NOT_ENCRYPTED_DATA}, + #else + {"NOT_ENCRYPTED_DATA", 46, 122}, + #endif + #ifdef CMS_R_NOT_KEK + {"NOT_KEK", ERR_LIB_CMS, CMS_R_NOT_KEK}, + #else + {"NOT_KEK", 46, 123}, + #endif + #ifdef CMS_R_NOT_KEY_AGREEMENT + {"NOT_KEY_AGREEMENT", ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT}, + #else + {"NOT_KEY_AGREEMENT", 46, 181}, + #endif + #ifdef CMS_R_NOT_KEY_TRANSPORT + {"NOT_KEY_TRANSPORT", ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT}, + #else + {"NOT_KEY_TRANSPORT", 46, 124}, + #endif + #ifdef CMS_R_NOT_PWRI + {"NOT_PWRI", ERR_LIB_CMS, CMS_R_NOT_PWRI}, + #else + {"NOT_PWRI", 46, 177}, + #endif + #ifdef CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 46, 125}, + #endif + #ifdef CMS_R_NO_CIPHER + {"NO_CIPHER", ERR_LIB_CMS, CMS_R_NO_CIPHER}, + #else + {"NO_CIPHER", 46, 126}, + #endif + #ifdef CMS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_CMS, CMS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 46, 127}, + #endif + #ifdef CMS_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 46, 173}, + #endif + #ifdef CMS_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 46, 128}, + #endif + #ifdef CMS_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_CMS, CMS_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 46, 129}, + #endif + #ifdef CMS_R_NO_KEY + {"NO_KEY", ERR_LIB_CMS, CMS_R_NO_KEY}, + #else + {"NO_KEY", 46, 130}, + #endif + #ifdef CMS_R_NO_KEY_OR_CERT + {"NO_KEY_OR_CERT", ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT}, + #else + {"NO_KEY_OR_CERT", 46, 174}, + #endif + #ifdef CMS_R_NO_MATCHING_DIGEST + {"NO_MATCHING_DIGEST", ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST}, + #else + {"NO_MATCHING_DIGEST", 46, 131}, + #endif + #ifdef CMS_R_NO_MATCHING_RECIPIENT + {"NO_MATCHING_RECIPIENT", ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT}, + #else + {"NO_MATCHING_RECIPIENT", 46, 132}, + #endif + #ifdef CMS_R_NO_MATCHING_SIGNATURE + {"NO_MATCHING_SIGNATURE", ERR_LIB_CMS, CMS_R_NO_MATCHING_SIGNATURE}, + #else + {"NO_MATCHING_SIGNATURE", 46, 166}, + #endif + #ifdef CMS_R_NO_MSGSIGDIGEST + {"NO_MSGSIGDIGEST", ERR_LIB_CMS, CMS_R_NO_MSGSIGDIGEST}, + #else + {"NO_MSGSIGDIGEST", 46, 167}, + #endif + #ifdef CMS_R_NO_PASSWORD + {"NO_PASSWORD", ERR_LIB_CMS, CMS_R_NO_PASSWORD}, + #else + {"NO_PASSWORD", 46, 178}, + #endif + #ifdef CMS_R_NO_PRIVATE_KEY + {"NO_PRIVATE_KEY", ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY}, + #else + {"NO_PRIVATE_KEY", 46, 133}, + #endif + #ifdef CMS_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 46, 134}, + #endif + #ifdef CMS_R_NO_RECEIPT_REQUEST + {"NO_RECEIPT_REQUEST", ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST}, + #else + {"NO_RECEIPT_REQUEST", 46, 168}, + #endif + #ifdef CMS_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_CMS, CMS_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 46, 135}, + #endif + #ifdef CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_CMS, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 46, 136}, + #endif + #ifdef CMS_R_RECEIPT_DECODE_ERROR + {"RECEIPT_DECODE_ERROR", ERR_LIB_CMS, CMS_R_RECEIPT_DECODE_ERROR}, + #else + {"RECEIPT_DECODE_ERROR", 46, 169}, + #endif + #ifdef CMS_R_RECIPIENT_ERROR + {"RECIPIENT_ERROR", ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR}, + #else + {"RECIPIENT_ERROR", 46, 137}, + #endif + #ifdef CMS_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 46, 138}, + #endif + #ifdef CMS_R_SIGNFINAL_ERROR + {"SIGNFINAL_ERROR", ERR_LIB_CMS, CMS_R_SIGNFINAL_ERROR}, + #else + {"SIGNFINAL_ERROR", 46, 139}, + #endif + #ifdef CMS_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 46, 140}, + #endif + #ifdef CMS_R_STORE_INIT_ERROR + {"STORE_INIT_ERROR", ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR}, + #else + {"STORE_INIT_ERROR", 46, 141}, + #endif + #ifdef CMS_R_TYPE_NOT_COMPRESSED_DATA + {"TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA}, + #else + {"TYPE_NOT_COMPRESSED_DATA", 46, 142}, + #endif + #ifdef CMS_R_TYPE_NOT_DATA + {"TYPE_NOT_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA}, + #else + {"TYPE_NOT_DATA", 46, 143}, + #endif + #ifdef CMS_R_TYPE_NOT_DIGESTED_DATA + {"TYPE_NOT_DIGESTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA}, + #else + {"TYPE_NOT_DIGESTED_DATA", 46, 144}, + #endif + #ifdef CMS_R_TYPE_NOT_ENCRYPTED_DATA + {"TYPE_NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA}, + #else + {"TYPE_NOT_ENCRYPTED_DATA", 46, 145}, + #endif + #ifdef CMS_R_TYPE_NOT_ENVELOPED_DATA + {"TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA}, + #else + {"TYPE_NOT_ENVELOPED_DATA", 46, 146}, + #endif + #ifdef CMS_R_UNABLE_TO_FINALIZE_CONTEXT + {"UNABLE_TO_FINALIZE_CONTEXT", ERR_LIB_CMS, CMS_R_UNABLE_TO_FINALIZE_CONTEXT}, + #else + {"UNABLE_TO_FINALIZE_CONTEXT", 46, 147}, + #endif + #ifdef CMS_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 46, 148}, + #endif + #ifdef CMS_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 46, 149}, + #endif + #ifdef CMS_R_UNKNOWN_ID + {"UNKNOWN_ID", ERR_LIB_CMS, CMS_R_UNKNOWN_ID}, + #else + {"UNKNOWN_ID", 46, 150}, + #endif + #ifdef CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM + {"UNSUPPORTED_COMPRESSION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM}, + #else + {"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151}, + #endif + #ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 46, 152}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEK_ALGORITHM + {"UNSUPPORTED_KEK_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEK_ALGORITHM}, + #else + {"UNSUPPORTED_KEK_ALGORITHM", 46, 153}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM}, + #else + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", 46, 179}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + {"UNSUPPORTED_RECIPIENTINFO_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE}, + #else + {"UNSUPPORTED_RECIPIENTINFO_TYPE", 46, 155}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENT_TYPE + {"UNSUPPORTED_RECIPIENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENT_TYPE}, + #else + {"UNSUPPORTED_RECIPIENT_TYPE", 46, 154}, + #endif + #ifdef CMS_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 46, 156}, + #endif + #ifdef CMS_R_UNWRAP_ERROR + {"UNWRAP_ERROR", ERR_LIB_CMS, CMS_R_UNWRAP_ERROR}, + #else + {"UNWRAP_ERROR", 46, 157}, + #endif + #ifdef CMS_R_UNWRAP_FAILURE + {"UNWRAP_FAILURE", ERR_LIB_CMS, CMS_R_UNWRAP_FAILURE}, + #else + {"UNWRAP_FAILURE", 46, 180}, + #endif + #ifdef CMS_R_VERIFICATION_FAILURE + {"VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE}, + #else + {"VERIFICATION_FAILURE", 46, 158}, + #endif + #ifdef CMS_R_WRAP_ERROR + {"WRAP_ERROR", ERR_LIB_CMS, CMS_R_WRAP_ERROR}, + #else + {"WRAP_ERROR", 46, 159}, + #endif + #ifdef COMP_R_ZLIB_DEFLATE_ERROR + {"ZLIB_DEFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR}, + #else + {"ZLIB_DEFLATE_ERROR", 41, 99}, + #endif + #ifdef COMP_R_ZLIB_INFLATE_ERROR + {"ZLIB_INFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR}, + #else + {"ZLIB_INFLATE_ERROR", 41, 100}, + #endif + #ifdef COMP_R_ZLIB_NOT_SUPPORTED + {"ZLIB_NOT_SUPPORTED", ERR_LIB_COMP, COMP_R_ZLIB_NOT_SUPPORTED}, + #else + {"ZLIB_NOT_SUPPORTED", 41, 101}, + #endif + #ifdef CONF_R_ERROR_LOADING_DSO + {"ERROR_LOADING_DSO", ERR_LIB_CONF, CONF_R_ERROR_LOADING_DSO}, + #else + {"ERROR_LOADING_DSO", 14, 110}, + #endif + #ifdef CONF_R_LIST_CANNOT_BE_NULL + {"LIST_CANNOT_BE_NULL", ERR_LIB_CONF, CONF_R_LIST_CANNOT_BE_NULL}, + #else + {"LIST_CANNOT_BE_NULL", 14, 115}, + #endif + #ifdef CONF_R_MISSING_CLOSE_SQUARE_BRACKET + {"MISSING_CLOSE_SQUARE_BRACKET", ERR_LIB_CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET}, + #else + {"MISSING_CLOSE_SQUARE_BRACKET", 14, 100}, + #endif + #ifdef CONF_R_MISSING_EQUAL_SIGN + {"MISSING_EQUAL_SIGN", ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN}, + #else + {"MISSING_EQUAL_SIGN", 14, 101}, + #endif + #ifdef CONF_R_MISSING_INIT_FUNCTION + {"MISSING_INIT_FUNCTION", ERR_LIB_CONF, CONF_R_MISSING_INIT_FUNCTION}, + #else + {"MISSING_INIT_FUNCTION", 14, 112}, + #endif + #ifdef CONF_R_MODULE_INITIALIZATION_ERROR + {"MODULE_INITIALIZATION_ERROR", ERR_LIB_CONF, CONF_R_MODULE_INITIALIZATION_ERROR}, + #else + {"MODULE_INITIALIZATION_ERROR", 14, 109}, + #endif + #ifdef CONF_R_NO_CLOSE_BRACE + {"NO_CLOSE_BRACE", ERR_LIB_CONF, CONF_R_NO_CLOSE_BRACE}, + #else + {"NO_CLOSE_BRACE", 14, 102}, + #endif + #ifdef CONF_R_NO_CONF + {"NO_CONF", ERR_LIB_CONF, CONF_R_NO_CONF}, + #else + {"NO_CONF", 14, 105}, + #endif + #ifdef CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", ERR_LIB_CONF, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE}, + #else + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", 14, 106}, + #endif + #ifdef CONF_R_NO_SECTION + {"NO_SECTION", ERR_LIB_CONF, CONF_R_NO_SECTION}, + #else + {"NO_SECTION", 14, 107}, + #endif + #ifdef CONF_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_CONF, CONF_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 14, 114}, + #endif + #ifdef CONF_R_NO_VALUE + {"NO_VALUE", ERR_LIB_CONF, CONF_R_NO_VALUE}, + #else + {"NO_VALUE", 14, 108}, + #endif + #ifdef CONF_R_NUMBER_TOO_LARGE + {"NUMBER_TOO_LARGE", ERR_LIB_CONF, CONF_R_NUMBER_TOO_LARGE}, + #else + {"NUMBER_TOO_LARGE", 14, 121}, + #endif + #ifdef CONF_R_RECURSIVE_DIRECTORY_INCLUDE + {"RECURSIVE_DIRECTORY_INCLUDE", ERR_LIB_CONF, CONF_R_RECURSIVE_DIRECTORY_INCLUDE}, + #else + {"RECURSIVE_DIRECTORY_INCLUDE", 14, 111}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 14, 117}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #else + {"SSL_COMMAND_SECTION_NOT_FOUND", 14, 118}, + #endif + #ifdef CONF_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 14, 119}, + #endif + #ifdef CONF_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_SECTION_NOT_FOUND}, + #else + {"SSL_SECTION_NOT_FOUND", 14, 120}, + #endif + #ifdef CONF_R_UNABLE_TO_CREATE_NEW_SECTION + {"UNABLE_TO_CREATE_NEW_SECTION", ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION}, + #else + {"UNABLE_TO_CREATE_NEW_SECTION", 14, 103}, + #endif + #ifdef CONF_R_UNKNOWN_MODULE_NAME + {"UNKNOWN_MODULE_NAME", ERR_LIB_CONF, CONF_R_UNKNOWN_MODULE_NAME}, + #else + {"UNKNOWN_MODULE_NAME", 14, 113}, + #endif + #ifdef CONF_R_VARIABLE_EXPANSION_TOO_LONG + {"VARIABLE_EXPANSION_TOO_LONG", ERR_LIB_CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG}, + #else + {"VARIABLE_EXPANSION_TOO_LONG", 14, 116}, + #endif + #ifdef CONF_R_VARIABLE_HAS_NO_VALUE + {"VARIABLE_HAS_NO_VALUE", ERR_LIB_CONF, CONF_R_VARIABLE_HAS_NO_VALUE}, + #else + {"VARIABLE_HAS_NO_VALUE", 14, 104}, + #endif + #ifdef CRYPTO_R_FIPS_MODE_NOT_SUPPORTED + {"FIPS_MODE_NOT_SUPPORTED", ERR_LIB_CRYPTO, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED}, + #else + {"FIPS_MODE_NOT_SUPPORTED", 15, 101}, + #endif + #ifdef CRYPTO_R_ILLEGAL_HEX_DIGIT + {"ILLEGAL_HEX_DIGIT", ERR_LIB_CRYPTO, CRYPTO_R_ILLEGAL_HEX_DIGIT}, + #else + {"ILLEGAL_HEX_DIGIT", 15, 102}, + #endif + #ifdef CRYPTO_R_ODD_NUMBER_OF_DIGITS + {"ODD_NUMBER_OF_DIGITS", ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS}, + #else + {"ODD_NUMBER_OF_DIGITS", 15, 103}, + #endif + #ifdef CT_R_BASE64_DECODE_ERROR + {"BASE64_DECODE_ERROR", ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR}, + #else + {"BASE64_DECODE_ERROR", 50, 108}, + #endif + #ifdef CT_R_INVALID_LOG_ID_LENGTH + {"INVALID_LOG_ID_LENGTH", ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH}, + #else + {"INVALID_LOG_ID_LENGTH", 50, 100}, + #endif + #ifdef CT_R_LOG_CONF_INVALID + {"LOG_CONF_INVALID", ERR_LIB_CT, CT_R_LOG_CONF_INVALID}, + #else + {"LOG_CONF_INVALID", 50, 109}, + #endif + #ifdef CT_R_LOG_CONF_INVALID_KEY + {"LOG_CONF_INVALID_KEY", ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY}, + #else + {"LOG_CONF_INVALID_KEY", 50, 110}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_DESCRIPTION + {"LOG_CONF_MISSING_DESCRIPTION", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_DESCRIPTION}, + #else + {"LOG_CONF_MISSING_DESCRIPTION", 50, 111}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_KEY + {"LOG_CONF_MISSING_KEY", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_KEY}, + #else + {"LOG_CONF_MISSING_KEY", 50, 112}, + #endif + #ifdef CT_R_LOG_KEY_INVALID + {"LOG_KEY_INVALID", ERR_LIB_CT, CT_R_LOG_KEY_INVALID}, + #else + {"LOG_KEY_INVALID", 50, 113}, + #endif + #ifdef CT_R_SCT_FUTURE_TIMESTAMP + {"SCT_FUTURE_TIMESTAMP", ERR_LIB_CT, CT_R_SCT_FUTURE_TIMESTAMP}, + #else + {"SCT_FUTURE_TIMESTAMP", 50, 116}, + #endif + #ifdef CT_R_SCT_INVALID + {"SCT_INVALID", ERR_LIB_CT, CT_R_SCT_INVALID}, + #else + {"SCT_INVALID", 50, 104}, + #endif + #ifdef CT_R_SCT_INVALID_SIGNATURE + {"SCT_INVALID_SIGNATURE", ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE}, + #else + {"SCT_INVALID_SIGNATURE", 50, 107}, + #endif + #ifdef CT_R_SCT_LIST_INVALID + {"SCT_LIST_INVALID", ERR_LIB_CT, CT_R_SCT_LIST_INVALID}, + #else + {"SCT_LIST_INVALID", 50, 105}, + #endif + #ifdef CT_R_SCT_LOG_ID_MISMATCH + {"SCT_LOG_ID_MISMATCH", ERR_LIB_CT, CT_R_SCT_LOG_ID_MISMATCH}, + #else + {"SCT_LOG_ID_MISMATCH", 50, 114}, + #endif + #ifdef CT_R_SCT_NOT_SET + {"SCT_NOT_SET", ERR_LIB_CT, CT_R_SCT_NOT_SET}, + #else + {"SCT_NOT_SET", 50, 106}, + #endif + #ifdef CT_R_SCT_UNSUPPORTED_VERSION + {"SCT_UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_SCT_UNSUPPORTED_VERSION}, + #else + {"SCT_UNSUPPORTED_VERSION", 50, 115}, + #endif + #ifdef CT_R_UNRECOGNIZED_SIGNATURE_NID + {"UNRECOGNIZED_SIGNATURE_NID", ERR_LIB_CT, CT_R_UNRECOGNIZED_SIGNATURE_NID}, + #else + {"UNRECOGNIZED_SIGNATURE_NID", 50, 101}, + #endif + #ifdef CT_R_UNSUPPORTED_ENTRY_TYPE + {"UNSUPPORTED_ENTRY_TYPE", ERR_LIB_CT, CT_R_UNSUPPORTED_ENTRY_TYPE}, + #else + {"UNSUPPORTED_ENTRY_TYPE", 50, 102}, + #endif + #ifdef CT_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 50, 103}, + #endif + #ifdef DH_R_BAD_GENERATOR + {"BAD_GENERATOR", ERR_LIB_DH, DH_R_BAD_GENERATOR}, + #else + {"BAD_GENERATOR", 5, 101}, + #endif + #ifdef DH_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DH, DH_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 5, 109}, + #endif + #ifdef DH_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DH, DH_R_BN_ERROR}, + #else + {"BN_ERROR", 5, 106}, + #endif + #ifdef DH_R_CHECK_INVALID_J_VALUE + {"CHECK_INVALID_J_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_J_VALUE}, + #else + {"CHECK_INVALID_J_VALUE", 5, 115}, + #endif + #ifdef DH_R_CHECK_INVALID_Q_VALUE + {"CHECK_INVALID_Q_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_Q_VALUE}, + #else + {"CHECK_INVALID_Q_VALUE", 5, 116}, + #endif + #ifdef DH_R_CHECK_PUBKEY_INVALID + {"CHECK_PUBKEY_INVALID", ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID}, + #else + {"CHECK_PUBKEY_INVALID", 5, 122}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_LARGE + {"CHECK_PUBKEY_TOO_LARGE", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_LARGE}, + #else + {"CHECK_PUBKEY_TOO_LARGE", 5, 123}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_SMALL + {"CHECK_PUBKEY_TOO_SMALL", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_SMALL}, + #else + {"CHECK_PUBKEY_TOO_SMALL", 5, 124}, + #endif + #ifdef DH_R_CHECK_P_NOT_PRIME + {"CHECK_P_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME}, + #else + {"CHECK_P_NOT_PRIME", 5, 117}, + #endif + #ifdef DH_R_CHECK_P_NOT_SAFE_PRIME + {"CHECK_P_NOT_SAFE_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_SAFE_PRIME}, + #else + {"CHECK_P_NOT_SAFE_PRIME", 5, 118}, + #endif + #ifdef DH_R_CHECK_Q_NOT_PRIME + {"CHECK_Q_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_Q_NOT_PRIME}, + #else + {"CHECK_Q_NOT_PRIME", 5, 119}, + #endif + #ifdef DH_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DH, DH_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 5, 104}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NAME + {"INVALID_PARAMETER_NAME", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME}, + #else + {"INVALID_PARAMETER_NAME", 5, 110}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NID + {"INVALID_PARAMETER_NID", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID}, + #else + {"INVALID_PARAMETER_NID", 5, 114}, + #endif + #ifdef DH_R_INVALID_PUBKEY + {"INVALID_PUBKEY", ERR_LIB_DH, DH_R_INVALID_PUBKEY}, + #else + {"INVALID_PUBKEY", 5, 102}, + #endif + #ifdef DH_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_DH, DH_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 5, 112}, + #endif + #ifdef DH_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_DH, DH_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 5, 108}, + #endif + #ifdef DH_R_MISSING_PUBKEY + {"MISSING_PUBKEY", ERR_LIB_DH, DH_R_MISSING_PUBKEY}, + #else + {"MISSING_PUBKEY", 5, 125}, + #endif + #ifdef DH_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 5, 103}, + #endif + #ifdef DH_R_NOT_SUITABLE_GENERATOR + {"NOT_SUITABLE_GENERATOR", ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR}, + #else + {"NOT_SUITABLE_GENERATOR", 5, 120}, + #endif + #ifdef DH_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DH, DH_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 5, 107}, + #endif + #ifdef DH_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_DH, DH_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 5, 100}, + #endif + #ifdef DH_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DH, DH_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 5, 105}, + #endif + #ifdef DH_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_DH, DH_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 5, 111}, + #endif + #ifdef DH_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_DH, DH_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 5, 113}, + #endif + #ifdef DH_R_UNABLE_TO_CHECK_GENERATOR + {"UNABLE_TO_CHECK_GENERATOR", ERR_LIB_DH, DH_R_UNABLE_TO_CHECK_GENERATOR}, + #else + {"UNABLE_TO_CHECK_GENERATOR", 5, 121}, + #endif + #ifdef DSA_R_BAD_Q_VALUE + {"BAD_Q_VALUE", ERR_LIB_DSA, DSA_R_BAD_Q_VALUE}, + #else + {"BAD_Q_VALUE", 10, 102}, + #endif + #ifdef DSA_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DSA, DSA_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 10, 108}, + #endif + #ifdef DSA_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DSA, DSA_R_BN_ERROR}, + #else + {"BN_ERROR", 10, 109}, + #endif + #ifdef DSA_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DSA, DSA_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 10, 104}, + #endif + #ifdef DSA_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 10, 106}, + #endif + #ifdef DSA_R_INVALID_PARAMETERS + {"INVALID_PARAMETERS", ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS}, + #else + {"INVALID_PARAMETERS", 10, 112}, + #endif + #ifdef DSA_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 10, 101}, + #endif + #ifdef DSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_DSA, DSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 10, 111}, + #endif + #ifdef DSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 10, 103}, + #endif + #ifdef DSA_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 10, 107}, + #endif + #ifdef DSA_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 10, 105}, + #endif + #ifdef DSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_DSA, DSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 10, 113}, + #endif + #ifdef DSA_R_SEED_LEN_SMALL + {"SEED_LEN_SMALL", ERR_LIB_DSA, DSA_R_SEED_LEN_SMALL}, + #else + {"SEED_LEN_SMALL", 10, 110}, + #endif + #ifdef DSO_R_CTRL_FAILED + {"CTRL_FAILED", ERR_LIB_DSO, DSO_R_CTRL_FAILED}, + #else + {"CTRL_FAILED", 37, 100}, + #endif + #ifdef DSO_R_DSO_ALREADY_LOADED + {"DSO_ALREADY_LOADED", ERR_LIB_DSO, DSO_R_DSO_ALREADY_LOADED}, + #else + {"DSO_ALREADY_LOADED", 37, 110}, + #endif + #ifdef DSO_R_EMPTY_FILE_STRUCTURE + {"EMPTY_FILE_STRUCTURE", ERR_LIB_DSO, DSO_R_EMPTY_FILE_STRUCTURE}, + #else + {"EMPTY_FILE_STRUCTURE", 37, 113}, + #endif + #ifdef DSO_R_FAILURE + {"FAILURE", ERR_LIB_DSO, DSO_R_FAILURE}, + #else + {"FAILURE", 37, 114}, + #endif + #ifdef DSO_R_FILENAME_TOO_BIG + {"FILENAME_TOO_BIG", ERR_LIB_DSO, DSO_R_FILENAME_TOO_BIG}, + #else + {"FILENAME_TOO_BIG", 37, 101}, + #endif + #ifdef DSO_R_FINISH_FAILED + {"FINISH_FAILED", ERR_LIB_DSO, DSO_R_FINISH_FAILED}, + #else + {"FINISH_FAILED", 37, 102}, + #endif + #ifdef DSO_R_INCORRECT_FILE_SYNTAX + {"INCORRECT_FILE_SYNTAX", ERR_LIB_DSO, DSO_R_INCORRECT_FILE_SYNTAX}, + #else + {"INCORRECT_FILE_SYNTAX", 37, 115}, + #endif + #ifdef DSO_R_LOAD_FAILED + {"LOAD_FAILED", ERR_LIB_DSO, DSO_R_LOAD_FAILED}, + #else + {"LOAD_FAILED", 37, 103}, + #endif + #ifdef DSO_R_NAME_TRANSLATION_FAILED + {"NAME_TRANSLATION_FAILED", ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED}, + #else + {"NAME_TRANSLATION_FAILED", 37, 109}, + #endif + #ifdef DSO_R_NO_FILENAME + {"NO_FILENAME", ERR_LIB_DSO, DSO_R_NO_FILENAME}, + #else + {"NO_FILENAME", 37, 111}, + #endif + #ifdef DSO_R_NULL_HANDLE + {"NULL_HANDLE", ERR_LIB_DSO, DSO_R_NULL_HANDLE}, + #else + {"NULL_HANDLE", 37, 104}, + #endif + #ifdef DSO_R_SET_FILENAME_FAILED + {"SET_FILENAME_FAILED", ERR_LIB_DSO, DSO_R_SET_FILENAME_FAILED}, + #else + {"SET_FILENAME_FAILED", 37, 112}, + #endif + #ifdef DSO_R_STACK_ERROR + {"STACK_ERROR", ERR_LIB_DSO, DSO_R_STACK_ERROR}, + #else + {"STACK_ERROR", 37, 105}, + #endif + #ifdef DSO_R_SYM_FAILURE + {"SYM_FAILURE", ERR_LIB_DSO, DSO_R_SYM_FAILURE}, + #else + {"SYM_FAILURE", 37, 106}, + #endif + #ifdef DSO_R_UNLOAD_FAILED + {"UNLOAD_FAILED", ERR_LIB_DSO, DSO_R_UNLOAD_FAILED}, + #else + {"UNLOAD_FAILED", 37, 107}, + #endif + #ifdef DSO_R_UNSUPPORTED + {"UNSUPPORTED", ERR_LIB_DSO, DSO_R_UNSUPPORTED}, + #else + {"UNSUPPORTED", 37, 108}, + #endif + #ifdef EC_R_ASN1_ERROR + {"ASN1_ERROR", ERR_LIB_EC, EC_R_ASN1_ERROR}, + #else + {"ASN1_ERROR", 16, 115}, + #endif + #ifdef EC_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_EC, EC_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 16, 156}, + #endif + #ifdef EC_R_BIGNUM_OUT_OF_RANGE + {"BIGNUM_OUT_OF_RANGE", ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE}, + #else + {"BIGNUM_OUT_OF_RANGE", 16, 144}, + #endif + #ifdef EC_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 16, 100}, + #endif + #ifdef EC_R_CANNOT_INVERT + {"CANNOT_INVERT", ERR_LIB_EC, EC_R_CANNOT_INVERT}, + #else + {"CANNOT_INVERT", 16, 165}, + #endif + #ifdef EC_R_COORDINATES_OUT_OF_RANGE + {"COORDINATES_OUT_OF_RANGE", ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE}, + #else + {"COORDINATES_OUT_OF_RANGE", 16, 146}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_ECDH + {"CURVE_DOES_NOT_SUPPORT_ECDH", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH}, + #else + {"CURVE_DOES_NOT_SUPPORT_ECDH", 16, 160}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING + {"CURVE_DOES_NOT_SUPPORT_SIGNING", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING}, + #else + {"CURVE_DOES_NOT_SUPPORT_SIGNING", 16, 159}, + #endif + #ifdef EC_R_D2I_ECPKPARAMETERS_FAILURE + {"D2I_ECPKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_D2I_ECPKPARAMETERS_FAILURE}, + #else + {"D2I_ECPKPARAMETERS_FAILURE", 16, 117}, + #endif + #ifdef EC_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EC, EC_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 16, 142}, + #endif + #ifdef EC_R_DISCRIMINANT_IS_ZERO + {"DISCRIMINANT_IS_ZERO", ERR_LIB_EC, EC_R_DISCRIMINANT_IS_ZERO}, + #else + {"DISCRIMINANT_IS_ZERO", 16, 118}, + #endif + #ifdef EC_R_EC_GROUP_NEW_BY_NAME_FAILURE + {"EC_GROUP_NEW_BY_NAME_FAILURE", ERR_LIB_EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE}, + #else + {"EC_GROUP_NEW_BY_NAME_FAILURE", 16, 119}, + #endif + #ifdef EC_R_FIELD_TOO_LARGE + {"FIELD_TOO_LARGE", ERR_LIB_EC, EC_R_FIELD_TOO_LARGE}, + #else + {"FIELD_TOO_LARGE", 16, 143}, + #endif + #ifdef EC_R_GF2M_NOT_SUPPORTED + {"GF2M_NOT_SUPPORTED", ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED}, + #else + {"GF2M_NOT_SUPPORTED", 16, 147}, + #endif + #ifdef EC_R_GROUP2PKPARAMETERS_FAILURE + {"GROUP2PKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_GROUP2PKPARAMETERS_FAILURE}, + #else + {"GROUP2PKPARAMETERS_FAILURE", 16, 120}, + #endif + #ifdef EC_R_I2D_ECPKPARAMETERS_FAILURE + {"I2D_ECPKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_I2D_ECPKPARAMETERS_FAILURE}, + #else + {"I2D_ECPKPARAMETERS_FAILURE", 16, 121}, + #endif + #ifdef EC_R_INCOMPATIBLE_OBJECTS + {"INCOMPATIBLE_OBJECTS", ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS}, + #else + {"INCOMPATIBLE_OBJECTS", 16, 101}, + #endif + #ifdef EC_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_EC, EC_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 16, 112}, + #endif + #ifdef EC_R_INVALID_COMPRESSED_POINT + {"INVALID_COMPRESSED_POINT", ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT}, + #else + {"INVALID_COMPRESSED_POINT", 16, 110}, + #endif + #ifdef EC_R_INVALID_COMPRESSION_BIT + {"INVALID_COMPRESSION_BIT", ERR_LIB_EC, EC_R_INVALID_COMPRESSION_BIT}, + #else + {"INVALID_COMPRESSION_BIT", 16, 109}, + #endif + #ifdef EC_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_EC, EC_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 16, 141}, + #endif + #ifdef EC_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EC, EC_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 16, 151}, + #endif + #ifdef EC_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 16, 138}, + #endif + #ifdef EC_R_INVALID_ENCODING + {"INVALID_ENCODING", ERR_LIB_EC, EC_R_INVALID_ENCODING}, + #else + {"INVALID_ENCODING", 16, 102}, + #endif + #ifdef EC_R_INVALID_FIELD + {"INVALID_FIELD", ERR_LIB_EC, EC_R_INVALID_FIELD}, + #else + {"INVALID_FIELD", 16, 103}, + #endif + #ifdef EC_R_INVALID_FORM + {"INVALID_FORM", ERR_LIB_EC, EC_R_INVALID_FORM}, + #else + {"INVALID_FORM", 16, 104}, + #endif + #ifdef EC_R_INVALID_GROUP_ORDER + {"INVALID_GROUP_ORDER", ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER}, + #else + {"INVALID_GROUP_ORDER", 16, 122}, + #endif + #ifdef EC_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EC, EC_R_INVALID_KEY}, + #else + {"INVALID_KEY", 16, 116}, + #endif + #ifdef EC_R_INVALID_OUTPUT_LENGTH + {"INVALID_OUTPUT_LENGTH", ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH}, + #else + {"INVALID_OUTPUT_LENGTH", 16, 161}, + #endif + #ifdef EC_R_INVALID_PEER_KEY + {"INVALID_PEER_KEY", ERR_LIB_EC, EC_R_INVALID_PEER_KEY}, + #else + {"INVALID_PEER_KEY", 16, 133}, + #endif + #ifdef EC_R_INVALID_PENTANOMIAL_BASIS + {"INVALID_PENTANOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_PENTANOMIAL_BASIS}, + #else + {"INVALID_PENTANOMIAL_BASIS", 16, 132}, + #endif + #ifdef EC_R_INVALID_PRIVATE_KEY + {"INVALID_PRIVATE_KEY", ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY}, + #else + {"INVALID_PRIVATE_KEY", 16, 123}, + #endif + #ifdef EC_R_INVALID_TRINOMIAL_BASIS + {"INVALID_TRINOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_TRINOMIAL_BASIS}, + #else + {"INVALID_TRINOMIAL_BASIS", 16, 137}, + #endif + #ifdef EC_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_EC, EC_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 16, 148}, + #endif + #ifdef EC_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_EC, EC_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 16, 140}, + #endif + #ifdef EC_R_LADDER_POST_FAILURE + {"LADDER_POST_FAILURE", ERR_LIB_EC, EC_R_LADDER_POST_FAILURE}, + #else + {"LADDER_POST_FAILURE", 16, 136}, + #endif + #ifdef EC_R_LADDER_PRE_FAILURE + {"LADDER_PRE_FAILURE", ERR_LIB_EC, EC_R_LADDER_PRE_FAILURE}, + #else + {"LADDER_PRE_FAILURE", 16, 153}, + #endif + #ifdef EC_R_LADDER_STEP_FAILURE + {"LADDER_STEP_FAILURE", ERR_LIB_EC, EC_R_LADDER_STEP_FAILURE}, + #else + {"LADDER_STEP_FAILURE", 16, 162}, + #endif + #ifdef EC_R_MISSING_OID + {"MISSING_OID", ERR_LIB_EC, EC_R_MISSING_OID}, + #else + {"MISSING_OID", 16, 167}, + #endif + #ifdef EC_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EC, EC_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 16, 124}, + #endif + #ifdef EC_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 16, 125}, + #endif + #ifdef EC_R_NEED_NEW_SETUP_VALUES + {"NEED_NEW_SETUP_VALUES", ERR_LIB_EC, EC_R_NEED_NEW_SETUP_VALUES}, + #else + {"NEED_NEW_SETUP_VALUES", 16, 157}, + #endif + #ifdef EC_R_NOT_A_NIST_PRIME + {"NOT_A_NIST_PRIME", ERR_LIB_EC, EC_R_NOT_A_NIST_PRIME}, + #else + {"NOT_A_NIST_PRIME", 16, 135}, + #endif + #ifdef EC_R_NOT_IMPLEMENTED + {"NOT_IMPLEMENTED", ERR_LIB_EC, EC_R_NOT_IMPLEMENTED}, + #else + {"NOT_IMPLEMENTED", 16, 126}, + #endif + #ifdef EC_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_EC, EC_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 16, 111}, + #endif + #ifdef EC_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_EC, EC_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 16, 139}, + #endif + #ifdef EC_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_EC, EC_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 16, 154}, + #endif + #ifdef EC_R_OPERATION_NOT_SUPPORTED + {"OPERATION_NOT_SUPPORTED", ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED}, + #else + {"OPERATION_NOT_SUPPORTED", 16, 152}, + #endif + #ifdef EC_R_PASSED_NULL_PARAMETER + {"PASSED_NULL_PARAMETER", ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER}, + #else + {"PASSED_NULL_PARAMETER", 16, 134}, + #endif + #ifdef EC_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_EC, EC_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 16, 149}, + #endif + #ifdef EC_R_PKPARAMETERS2GROUP_FAILURE + {"PKPARAMETERS2GROUP_FAILURE", ERR_LIB_EC, EC_R_PKPARAMETERS2GROUP_FAILURE}, + #else + {"PKPARAMETERS2GROUP_FAILURE", 16, 127}, + #endif + #ifdef EC_R_POINT_ARITHMETIC_FAILURE + {"POINT_ARITHMETIC_FAILURE", ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE}, + #else + {"POINT_ARITHMETIC_FAILURE", 16, 155}, + #endif + #ifdef EC_R_POINT_AT_INFINITY + {"POINT_AT_INFINITY", ERR_LIB_EC, EC_R_POINT_AT_INFINITY}, + #else + {"POINT_AT_INFINITY", 16, 106}, + #endif + #ifdef EC_R_POINT_COORDINATES_BLIND_FAILURE + {"POINT_COORDINATES_BLIND_FAILURE", ERR_LIB_EC, EC_R_POINT_COORDINATES_BLIND_FAILURE}, + #else + {"POINT_COORDINATES_BLIND_FAILURE", 16, 163}, + #endif + #ifdef EC_R_POINT_IS_NOT_ON_CURVE + {"POINT_IS_NOT_ON_CURVE", ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE}, + #else + {"POINT_IS_NOT_ON_CURVE", 16, 107}, + #endif + #ifdef EC_R_RANDOM_NUMBER_GENERATION_FAILED + {"RANDOM_NUMBER_GENERATION_FAILED", ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED}, + #else + {"RANDOM_NUMBER_GENERATION_FAILED", 16, 158}, + #endif + #ifdef EC_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_EC, EC_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 16, 150}, + #endif + #ifdef EC_R_SLOT_FULL + {"SLOT_FULL", ERR_LIB_EC, EC_R_SLOT_FULL}, + #else + {"SLOT_FULL", 16, 108}, + #endif + #ifdef EC_R_UNDEFINED_GENERATOR + {"UNDEFINED_GENERATOR", ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR}, + #else + {"UNDEFINED_GENERATOR", 16, 113}, + #endif + #ifdef EC_R_UNDEFINED_ORDER + {"UNDEFINED_ORDER", ERR_LIB_EC, EC_R_UNDEFINED_ORDER}, + #else + {"UNDEFINED_ORDER", 16, 128}, + #endif + #ifdef EC_R_UNKNOWN_COFACTOR + {"UNKNOWN_COFACTOR", ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR}, + #else + {"UNKNOWN_COFACTOR", 16, 164}, + #endif + #ifdef EC_R_UNKNOWN_GROUP + {"UNKNOWN_GROUP", ERR_LIB_EC, EC_R_UNKNOWN_GROUP}, + #else + {"UNKNOWN_GROUP", 16, 129}, + #endif + #ifdef EC_R_UNKNOWN_ORDER + {"UNKNOWN_ORDER", ERR_LIB_EC, EC_R_UNKNOWN_ORDER}, + #else + {"UNKNOWN_ORDER", 16, 114}, + #endif + #ifdef EC_R_UNSUPPORTED_FIELD + {"UNSUPPORTED_FIELD", ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD}, + #else + {"UNSUPPORTED_FIELD", 16, 131}, + #endif + #ifdef EC_R_WRONG_CURVE_PARAMETERS + {"WRONG_CURVE_PARAMETERS", ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS}, + #else + {"WRONG_CURVE_PARAMETERS", 16, 145}, + #endif + #ifdef EC_R_WRONG_ORDER + {"WRONG_ORDER", ERR_LIB_EC, EC_R_WRONG_ORDER}, + #else + {"WRONG_ORDER", 16, 130}, + #endif + #ifdef ENGINE_R_ALREADY_LOADED + {"ALREADY_LOADED", ERR_LIB_ENGINE, ENGINE_R_ALREADY_LOADED}, + #else + {"ALREADY_LOADED", 38, 100}, + #endif + #ifdef ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER + {"ARGUMENT_IS_NOT_A_NUMBER", ERR_LIB_ENGINE, ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER}, + #else + {"ARGUMENT_IS_NOT_A_NUMBER", 38, 133}, + #endif + #ifdef ENGINE_R_CMD_NOT_EXECUTABLE + {"CMD_NOT_EXECUTABLE", ERR_LIB_ENGINE, ENGINE_R_CMD_NOT_EXECUTABLE}, + #else + {"CMD_NOT_EXECUTABLE", 38, 134}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_INPUT + {"COMMAND_TAKES_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_INPUT}, + #else + {"COMMAND_TAKES_INPUT", 38, 135}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_NO_INPUT + {"COMMAND_TAKES_NO_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_NO_INPUT}, + #else + {"COMMAND_TAKES_NO_INPUT", 38, 136}, + #endif + #ifdef ENGINE_R_CONFLICTING_ENGINE_ID + {"CONFLICTING_ENGINE_ID", ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID}, + #else + {"CONFLICTING_ENGINE_ID", 38, 103}, + #endif + #ifdef ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED + {"CTRL_COMMAND_NOT_IMPLEMENTED", ERR_LIB_ENGINE, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED}, + #else + {"CTRL_COMMAND_NOT_IMPLEMENTED", 38, 119}, + #endif + #ifdef ENGINE_R_DSO_FAILURE + {"DSO_FAILURE", ERR_LIB_ENGINE, ENGINE_R_DSO_FAILURE}, + #else + {"DSO_FAILURE", 38, 104}, + #endif + #ifdef ENGINE_R_DSO_NOT_FOUND + {"DSO_NOT_FOUND", ERR_LIB_ENGINE, ENGINE_R_DSO_NOT_FOUND}, + #else + {"DSO_NOT_FOUND", 38, 132}, + #endif + #ifdef ENGINE_R_ENGINES_SECTION_ERROR + {"ENGINES_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINES_SECTION_ERROR}, + #else + {"ENGINES_SECTION_ERROR", 38, 148}, + #endif + #ifdef ENGINE_R_ENGINE_CONFIGURATION_ERROR + {"ENGINE_CONFIGURATION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR}, + #else + {"ENGINE_CONFIGURATION_ERROR", 38, 102}, + #endif + #ifdef ENGINE_R_ENGINE_IS_NOT_IN_LIST + {"ENGINE_IS_NOT_IN_LIST", ERR_LIB_ENGINE, ENGINE_R_ENGINE_IS_NOT_IN_LIST}, + #else + {"ENGINE_IS_NOT_IN_LIST", 38, 105}, + #endif + #ifdef ENGINE_R_ENGINE_SECTION_ERROR + {"ENGINE_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_SECTION_ERROR}, + #else + {"ENGINE_SECTION_ERROR", 38, 149}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PRIVATE_KEY + {"FAILED_LOADING_PRIVATE_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PRIVATE_KEY}, + #else + {"FAILED_LOADING_PRIVATE_KEY", 38, 128}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PUBLIC_KEY + {"FAILED_LOADING_PUBLIC_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PUBLIC_KEY}, + #else + {"FAILED_LOADING_PUBLIC_KEY", 38, 129}, + #endif + #ifdef ENGINE_R_FINISH_FAILED + {"FINISH_FAILED", ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED}, + #else + {"FINISH_FAILED", 38, 106}, + #endif + #ifdef ENGINE_R_ID_OR_NAME_MISSING + {"ID_OR_NAME_MISSING", ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING}, + #else + {"ID_OR_NAME_MISSING", 38, 108}, + #endif + #ifdef ENGINE_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ENGINE, ENGINE_R_INIT_FAILED}, + #else + {"INIT_FAILED", 38, 109}, + #endif + #ifdef ENGINE_R_INTERNAL_LIST_ERROR + {"INTERNAL_LIST_ERROR", ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR}, + #else + {"INTERNAL_LIST_ERROR", 38, 110}, + #endif + #ifdef ENGINE_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_ENGINE, ENGINE_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 38, 143}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NAME + {"INVALID_CMD_NAME", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NAME}, + #else + {"INVALID_CMD_NAME", 38, 137}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NUMBER + {"INVALID_CMD_NUMBER", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NUMBER}, + #else + {"INVALID_CMD_NUMBER", 38, 138}, + #endif + #ifdef ENGINE_R_INVALID_INIT_VALUE + {"INVALID_INIT_VALUE", ERR_LIB_ENGINE, ENGINE_R_INVALID_INIT_VALUE}, + #else + {"INVALID_INIT_VALUE", 38, 151}, + #endif + #ifdef ENGINE_R_INVALID_STRING + {"INVALID_STRING", ERR_LIB_ENGINE, ENGINE_R_INVALID_STRING}, + #else + {"INVALID_STRING", 38, 150}, + #endif + #ifdef ENGINE_R_NOT_INITIALISED + {"NOT_INITIALISED", ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED}, + #else + {"NOT_INITIALISED", 38, 117}, + #endif + #ifdef ENGINE_R_NOT_LOADED + {"NOT_LOADED", ERR_LIB_ENGINE, ENGINE_R_NOT_LOADED}, + #else + {"NOT_LOADED", 38, 112}, + #endif + #ifdef ENGINE_R_NO_CONTROL_FUNCTION + {"NO_CONTROL_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_CONTROL_FUNCTION}, + #else + {"NO_CONTROL_FUNCTION", 38, 120}, + #endif + #ifdef ENGINE_R_NO_INDEX + {"NO_INDEX", ERR_LIB_ENGINE, ENGINE_R_NO_INDEX}, + #else + {"NO_INDEX", 38, 144}, + #endif + #ifdef ENGINE_R_NO_LOAD_FUNCTION + {"NO_LOAD_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION}, + #else + {"NO_LOAD_FUNCTION", 38, 125}, + #endif + #ifdef ENGINE_R_NO_REFERENCE + {"NO_REFERENCE", ERR_LIB_ENGINE, ENGINE_R_NO_REFERENCE}, + #else + {"NO_REFERENCE", 38, 130}, + #endif + #ifdef ENGINE_R_NO_SUCH_ENGINE + {"NO_SUCH_ENGINE", ERR_LIB_ENGINE, ENGINE_R_NO_SUCH_ENGINE}, + #else + {"NO_SUCH_ENGINE", 38, 116}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_CIPHER + {"UNIMPLEMENTED_CIPHER", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_CIPHER}, + #else + {"UNIMPLEMENTED_CIPHER", 38, 146}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_DIGEST + {"UNIMPLEMENTED_DIGEST", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_DIGEST}, + #else + {"UNIMPLEMENTED_DIGEST", 38, 147}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD}, + #else + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", 38, 101}, + #endif + #ifdef ENGINE_R_VERSION_INCOMPATIBILITY + {"VERSION_INCOMPATIBILITY", ERR_LIB_ENGINE, ENGINE_R_VERSION_INCOMPATIBILITY}, + #else + {"VERSION_INCOMPATIBILITY", 38, 145}, + #endif + #ifdef EVP_R_AES_KEY_SETUP_FAILED + {"AES_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_AES_KEY_SETUP_FAILED}, + #else + {"AES_KEY_SETUP_FAILED", 6, 143}, + #endif + #ifdef EVP_R_ARIA_KEY_SETUP_FAILED + {"ARIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED}, + #else + {"ARIA_KEY_SETUP_FAILED", 6, 176}, + #endif + #ifdef EVP_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_EVP, EVP_R_BAD_DECRYPT}, + #else + {"BAD_DECRYPT", 6, 100}, + #endif + #ifdef EVP_R_BAD_KEY_LENGTH + {"BAD_KEY_LENGTH", ERR_LIB_EVP, EVP_R_BAD_KEY_LENGTH}, + #else + {"BAD_KEY_LENGTH", 6, 195}, + #endif + #ifdef EVP_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 6, 155}, + #endif + #ifdef EVP_R_CAMELLIA_KEY_SETUP_FAILED + {"CAMELLIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED}, + #else + {"CAMELLIA_KEY_SETUP_FAILED", 6, 157}, + #endif + #ifdef EVP_R_CIPHER_PARAMETER_ERROR + {"CIPHER_PARAMETER_ERROR", ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR}, + #else + {"CIPHER_PARAMETER_ERROR", 6, 122}, + #endif + #ifdef EVP_R_COMMAND_NOT_SUPPORTED + {"COMMAND_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED}, + #else + {"COMMAND_NOT_SUPPORTED", 6, 147}, + #endif + #ifdef EVP_R_COPY_ERROR + {"COPY_ERROR", ERR_LIB_EVP, EVP_R_COPY_ERROR}, + #else + {"COPY_ERROR", 6, 173}, + #endif + #ifdef EVP_R_CTRL_NOT_IMPLEMENTED + {"CTRL_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED}, + #else + {"CTRL_NOT_IMPLEMENTED", 6, 132}, + #endif + #ifdef EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED + {"CTRL_OPERATION_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED}, + #else + {"CTRL_OPERATION_NOT_IMPLEMENTED", 6, 133}, + #endif + #ifdef EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH}, + #else + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", 6, 138}, + #endif + #ifdef EVP_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EVP, EVP_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 6, 114}, + #endif + #ifdef EVP_R_DIFFERENT_KEY_TYPES + {"DIFFERENT_KEY_TYPES", ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES}, + #else + {"DIFFERENT_KEY_TYPES", 6, 101}, + #endif + #ifdef EVP_R_DIFFERENT_PARAMETERS + {"DIFFERENT_PARAMETERS", ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS}, + #else + {"DIFFERENT_PARAMETERS", 6, 153}, + #endif + #ifdef EVP_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_EVP, EVP_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 6, 165}, + #endif + #ifdef EVP_R_ERROR_SETTING_FIPS_MODE + {"ERROR_SETTING_FIPS_MODE", ERR_LIB_EVP, EVP_R_ERROR_SETTING_FIPS_MODE}, + #else + {"ERROR_SETTING_FIPS_MODE", 6, 166}, + #endif + #ifdef EVP_R_EXPECTING_AN_HMAC_KEY + {"EXPECTING_AN_HMAC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY}, + #else + {"EXPECTING_AN_HMAC_KEY", 6, 174}, + #endif + #ifdef EVP_R_EXPECTING_AN_RSA_KEY + {"EXPECTING_AN_RSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_RSA_KEY}, + #else + {"EXPECTING_AN_RSA_KEY", 6, 127}, + #endif + #ifdef EVP_R_EXPECTING_A_DH_KEY + {"EXPECTING_A_DH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY}, + #else + {"EXPECTING_A_DH_KEY", 6, 128}, + #endif + #ifdef EVP_R_EXPECTING_A_DSA_KEY + {"EXPECTING_A_DSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY}, + #else + {"EXPECTING_A_DSA_KEY", 6, 129}, + #endif + #ifdef EVP_R_EXPECTING_A_EC_KEY + {"EXPECTING_A_EC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_EC_KEY}, + #else + {"EXPECTING_A_EC_KEY", 6, 142}, + #endif + #ifdef EVP_R_EXPECTING_A_POLY1305_KEY + {"EXPECTING_A_POLY1305_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY}, + #else + {"EXPECTING_A_POLY1305_KEY", 6, 164}, + #endif + #ifdef EVP_R_EXPECTING_A_SIPHASH_KEY + {"EXPECTING_A_SIPHASH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY}, + #else + {"EXPECTING_A_SIPHASH_KEY", 6, 175}, + #endif + #ifdef EVP_R_FIPS_MODE_NOT_SUPPORTED + {"FIPS_MODE_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_FIPS_MODE_NOT_SUPPORTED}, + #else + {"FIPS_MODE_NOT_SUPPORTED", 6, 167}, + #endif + #ifdef EVP_R_GET_RAW_KEY_FAILED + {"GET_RAW_KEY_FAILED", ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED}, + #else + {"GET_RAW_KEY_FAILED", 6, 182}, + #endif + #ifdef EVP_R_ILLEGAL_SCRYPT_PARAMETERS + {"ILLEGAL_SCRYPT_PARAMETERS", ERR_LIB_EVP, EVP_R_ILLEGAL_SCRYPT_PARAMETERS}, + #else + {"ILLEGAL_SCRYPT_PARAMETERS", 6, 171}, + #endif + #ifdef EVP_R_INITIALIZATION_ERROR + {"INITIALIZATION_ERROR", ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR}, + #else + {"INITIALIZATION_ERROR", 6, 134}, + #endif + #ifdef EVP_R_INPUT_NOT_INITIALIZED + {"INPUT_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_INPUT_NOT_INITIALIZED}, + #else + {"INPUT_NOT_INITIALIZED", 6, 111}, + #endif + #ifdef EVP_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EVP, EVP_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 6, 152}, + #endif + #ifdef EVP_R_INVALID_FIPS_MODE + {"INVALID_FIPS_MODE", ERR_LIB_EVP, EVP_R_INVALID_FIPS_MODE}, + #else + {"INVALID_FIPS_MODE", 6, 168}, + #endif + #ifdef EVP_R_INVALID_IV_LENGTH + {"INVALID_IV_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH}, + #else + {"INVALID_IV_LENGTH", 6, 194}, + #endif + #ifdef EVP_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EVP, EVP_R_INVALID_KEY}, + #else + {"INVALID_KEY", 6, 163}, + #endif + #ifdef EVP_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 6, 130}, + #endif + #ifdef EVP_R_INVALID_OPERATION + {"INVALID_OPERATION", ERR_LIB_EVP, EVP_R_INVALID_OPERATION}, + #else + {"INVALID_OPERATION", 6, 148}, + #endif + #ifdef EVP_R_KEYGEN_FAILURE + {"KEYGEN_FAILURE", ERR_LIB_EVP, EVP_R_KEYGEN_FAILURE}, + #else + {"KEYGEN_FAILURE", 6, 120}, + #endif + #ifdef EVP_R_KEY_SETUP_FAILED + {"KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED}, + #else + {"KEY_SETUP_FAILED", 6, 180}, + #endif + #ifdef EVP_R_MEMORY_LIMIT_EXCEEDED + {"MEMORY_LIMIT_EXCEEDED", ERR_LIB_EVP, EVP_R_MEMORY_LIMIT_EXCEEDED}, + #else + {"MEMORY_LIMIT_EXCEEDED", 6, 172}, + #endif + #ifdef EVP_R_MESSAGE_DIGEST_IS_NULL + {"MESSAGE_DIGEST_IS_NULL", ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL}, + #else + {"MESSAGE_DIGEST_IS_NULL", 6, 159}, + #endif + #ifdef EVP_R_METHOD_NOT_SUPPORTED + {"METHOD_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_METHOD_NOT_SUPPORTED}, + #else + {"METHOD_NOT_SUPPORTED", 6, 144}, + #endif + #ifdef EVP_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 6, 103}, + #endif + #ifdef EVP_R_NOT_XOF_OR_INVALID_LENGTH + {"NOT_XOF_OR_INVALID_LENGTH", ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH}, + #else + {"NOT_XOF_OR_INVALID_LENGTH", 6, 178}, + #endif + #ifdef EVP_R_NO_CIPHER_SET + {"NO_CIPHER_SET", ERR_LIB_EVP, EVP_R_NO_CIPHER_SET}, + #else + {"NO_CIPHER_SET", 6, 131}, + #endif + #ifdef EVP_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 6, 158}, + #endif + #ifdef EVP_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_EVP, EVP_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 6, 139}, + #endif + #ifdef EVP_R_NO_KEY_SET + {"NO_KEY_SET", ERR_LIB_EVP, EVP_R_NO_KEY_SET}, + #else + {"NO_KEY_SET", 6, 154}, + #endif + #ifdef EVP_R_NO_OPERATION_SET + {"NO_OPERATION_SET", ERR_LIB_EVP, EVP_R_NO_OPERATION_SET}, + #else + {"NO_OPERATION_SET", 6, 149}, + #endif + #ifdef EVP_R_ONLY_ONESHOT_SUPPORTED + {"ONLY_ONESHOT_SUPPORTED", ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED}, + #else + {"ONLY_ONESHOT_SUPPORTED", 6, 177}, + #endif + #ifdef EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 6, 150}, + #endif + #ifdef EVP_R_OPERATON_NOT_INITIALIZED + {"OPERATON_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED}, + #else + {"OPERATON_NOT_INITIALIZED", 6, 151}, + #endif + #ifdef EVP_R_OUTPUT_WOULD_OVERFLOW + {"OUTPUT_WOULD_OVERFLOW", ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW}, + #else + {"OUTPUT_WOULD_OVERFLOW", 6, 184}, + #endif + #ifdef EVP_R_PARTIALLY_OVERLAPPING + {"PARTIALLY_OVERLAPPING", ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING}, + #else + {"PARTIALLY_OVERLAPPING", 6, 162}, + #endif + #ifdef EVP_R_PBKDF2_ERROR + {"PBKDF2_ERROR", ERR_LIB_EVP, EVP_R_PBKDF2_ERROR}, + #else + {"PBKDF2_ERROR", 6, 181}, + #endif + #ifdef EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", ERR_LIB_EVP, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED}, + #else + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", 6, 179}, + #endif + #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR + {"PRIVATE_KEY_DECODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_DECODE_ERROR}, + #else + {"PRIVATE_KEY_DECODE_ERROR", 6, 145}, + #endif + #ifdef EVP_R_PRIVATE_KEY_ENCODE_ERROR + {"PRIVATE_KEY_ENCODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_ENCODE_ERROR}, + #else + {"PRIVATE_KEY_ENCODE_ERROR", 6, 146}, + #endif + #ifdef EVP_R_PUBLIC_KEY_NOT_RSA + {"PUBLIC_KEY_NOT_RSA", ERR_LIB_EVP, EVP_R_PUBLIC_KEY_NOT_RSA}, + #else + {"PUBLIC_KEY_NOT_RSA", 6, 106}, + #endif + #ifdef EVP_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_EVP, EVP_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 6, 160}, + #endif + #ifdef EVP_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_EVP, EVP_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 6, 161}, + #endif + #ifdef EVP_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_EVP, EVP_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 6, 169}, + #endif + #ifdef EVP_R_UNKNOWN_PBE_ALGORITHM + {"UNKNOWN_PBE_ALGORITHM", ERR_LIB_EVP, EVP_R_UNKNOWN_PBE_ALGORITHM}, + #else + {"UNKNOWN_PBE_ALGORITHM", 6, 121}, + #endif + #ifdef EVP_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 6, 156}, + #endif + #ifdef EVP_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 6, 107}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEYLENGTH + {"UNSUPPORTED_KEYLENGTH", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH}, + #else + {"UNSUPPORTED_KEYLENGTH", 6, 123}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION}, + #else + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", 6, 124}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_SIZE + {"UNSUPPORTED_KEY_SIZE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE}, + #else + {"UNSUPPORTED_KEY_SIZE", 6, 108}, + #endif + #ifdef EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS + {"UNSUPPORTED_NUMBER_OF_ROUNDS", ERR_LIB_EVP, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS}, + #else + {"UNSUPPORTED_NUMBER_OF_ROUNDS", 6, 135}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRF + {"UNSUPPORTED_PRF", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF}, + #else + {"UNSUPPORTED_PRF", 6, 125}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM}, + #else + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", 6, 118}, + #endif + #ifdef EVP_R_UNSUPPORTED_SALT_TYPE + {"UNSUPPORTED_SALT_TYPE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_SALT_TYPE}, + #else + {"UNSUPPORTED_SALT_TYPE", 6, 126}, + #endif + #ifdef EVP_R_WRAP_MODE_NOT_ALLOWED + {"WRAP_MODE_NOT_ALLOWED", ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED}, + #else + {"WRAP_MODE_NOT_ALLOWED", 6, 170}, + #endif + #ifdef EVP_R_WRONG_FINAL_BLOCK_LENGTH + {"WRONG_FINAL_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_WRONG_FINAL_BLOCK_LENGTH}, + #else + {"WRONG_FINAL_BLOCK_LENGTH", 6, 109}, + #endif + #ifdef EVP_R_XTS_DUPLICATED_KEYS + {"XTS_DUPLICATED_KEYS", ERR_LIB_EVP, EVP_R_XTS_DUPLICATED_KEYS}, + #else + {"XTS_DUPLICATED_KEYS", 6, 183}, + #endif + #ifdef KDF_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_KDF, KDF_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 52, 100}, + #endif + #ifdef KDF_R_MISSING_ITERATION_COUNT + {"MISSING_ITERATION_COUNT", ERR_LIB_KDF, KDF_R_MISSING_ITERATION_COUNT}, + #else + {"MISSING_ITERATION_COUNT", 52, 109}, + #endif + #ifdef KDF_R_MISSING_KEY + {"MISSING_KEY", ERR_LIB_KDF, KDF_R_MISSING_KEY}, + #else + {"MISSING_KEY", 52, 104}, + #endif + #ifdef KDF_R_MISSING_MESSAGE_DIGEST + {"MISSING_MESSAGE_DIGEST", ERR_LIB_KDF, KDF_R_MISSING_MESSAGE_DIGEST}, + #else + {"MISSING_MESSAGE_DIGEST", 52, 105}, + #endif + #ifdef KDF_R_MISSING_PARAMETER + {"MISSING_PARAMETER", ERR_LIB_KDF, KDF_R_MISSING_PARAMETER}, + #else + {"MISSING_PARAMETER", 52, 101}, + #endif + #ifdef KDF_R_MISSING_PASS + {"MISSING_PASS", ERR_LIB_KDF, KDF_R_MISSING_PASS}, + #else + {"MISSING_PASS", 52, 110}, + #endif + #ifdef KDF_R_MISSING_SALT + {"MISSING_SALT", ERR_LIB_KDF, KDF_R_MISSING_SALT}, + #else + {"MISSING_SALT", 52, 111}, + #endif + #ifdef KDF_R_MISSING_SECRET + {"MISSING_SECRET", ERR_LIB_KDF, KDF_R_MISSING_SECRET}, + #else + {"MISSING_SECRET", 52, 107}, + #endif + #ifdef KDF_R_MISSING_SEED + {"MISSING_SEED", ERR_LIB_KDF, KDF_R_MISSING_SEED}, + #else + {"MISSING_SEED", 52, 106}, + #endif + #ifdef KDF_R_UNKNOWN_PARAMETER_TYPE + {"UNKNOWN_PARAMETER_TYPE", ERR_LIB_KDF, KDF_R_UNKNOWN_PARAMETER_TYPE}, + #else + {"UNKNOWN_PARAMETER_TYPE", 52, 103}, + #endif + #ifdef KDF_R_VALUE_ERROR + {"VALUE_ERROR", ERR_LIB_KDF, KDF_R_VALUE_ERROR}, + #else + {"VALUE_ERROR", 52, 108}, + #endif + #ifdef KDF_R_VALUE_MISSING + {"VALUE_MISSING", ERR_LIB_KDF, KDF_R_VALUE_MISSING}, + #else + {"VALUE_MISSING", 52, 102}, + #endif + #ifdef OBJ_R_OID_EXISTS + {"OID_EXISTS", ERR_LIB_OBJ, OBJ_R_OID_EXISTS}, + #else + {"OID_EXISTS", 8, 102}, + #endif + #ifdef OBJ_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 8, 101}, + #endif + #ifdef OCSP_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 39, 101}, + #endif + #ifdef OCSP_R_DIGEST_ERR + {"DIGEST_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_ERR}, + #else + {"DIGEST_ERR", 39, 102}, + #endif + #ifdef OCSP_R_ERROR_IN_NEXTUPDATE_FIELD + {"ERROR_IN_NEXTUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD}, + #else + {"ERROR_IN_NEXTUPDATE_FIELD", 39, 122}, + #endif + #ifdef OCSP_R_ERROR_IN_THISUPDATE_FIELD + {"ERROR_IN_THISUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD}, + #else + {"ERROR_IN_THISUPDATE_FIELD", 39, 123}, + #endif + #ifdef OCSP_R_ERROR_PARSING_URL + {"ERROR_PARSING_URL", ERR_LIB_OCSP, OCSP_R_ERROR_PARSING_URL}, + #else + {"ERROR_PARSING_URL", 39, 121}, + #endif + #ifdef OCSP_R_MISSING_OCSPSIGNING_USAGE + {"MISSING_OCSPSIGNING_USAGE", ERR_LIB_OCSP, OCSP_R_MISSING_OCSPSIGNING_USAGE}, + #else + {"MISSING_OCSPSIGNING_USAGE", 39, 103}, + #endif + #ifdef OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE + {"NEXTUPDATE_BEFORE_THISUPDATE", ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE}, + #else + {"NEXTUPDATE_BEFORE_THISUPDATE", 39, 124}, + #endif + #ifdef OCSP_R_NOT_BASIC_RESPONSE + {"NOT_BASIC_RESPONSE", ERR_LIB_OCSP, OCSP_R_NOT_BASIC_RESPONSE}, + #else + {"NOT_BASIC_RESPONSE", 39, 104}, + #endif + #ifdef OCSP_R_NO_CERTIFICATES_IN_CHAIN + {"NO_CERTIFICATES_IN_CHAIN", ERR_LIB_OCSP, OCSP_R_NO_CERTIFICATES_IN_CHAIN}, + #else + {"NO_CERTIFICATES_IN_CHAIN", 39, 105}, + #endif + #ifdef OCSP_R_NO_RESPONSE_DATA + {"NO_RESPONSE_DATA", ERR_LIB_OCSP, OCSP_R_NO_RESPONSE_DATA}, + #else + {"NO_RESPONSE_DATA", 39, 108}, + #endif + #ifdef OCSP_R_NO_REVOKED_TIME + {"NO_REVOKED_TIME", ERR_LIB_OCSP, OCSP_R_NO_REVOKED_TIME}, + #else + {"NO_REVOKED_TIME", 39, 109}, + #endif + #ifdef OCSP_R_NO_SIGNER_KEY + {"NO_SIGNER_KEY", ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY}, + #else + {"NO_SIGNER_KEY", 39, 130}, + #endif + #ifdef OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_OCSP, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 39, 110}, + #endif + #ifdef OCSP_R_REQUEST_NOT_SIGNED + {"REQUEST_NOT_SIGNED", ERR_LIB_OCSP, OCSP_R_REQUEST_NOT_SIGNED}, + #else + {"REQUEST_NOT_SIGNED", 39, 128}, + #endif + #ifdef OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", ERR_LIB_OCSP, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA}, + #else + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", 39, 111}, + #endif + #ifdef OCSP_R_ROOT_CA_NOT_TRUSTED + {"ROOT_CA_NOT_TRUSTED", ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED}, + #else + {"ROOT_CA_NOT_TRUSTED", 39, 112}, + #endif + #ifdef OCSP_R_SERVER_RESPONSE_ERROR + {"SERVER_RESPONSE_ERROR", ERR_LIB_OCSP, OCSP_R_SERVER_RESPONSE_ERROR}, + #else + {"SERVER_RESPONSE_ERROR", 39, 114}, + #endif + #ifdef OCSP_R_SERVER_RESPONSE_PARSE_ERROR + {"SERVER_RESPONSE_PARSE_ERROR", ERR_LIB_OCSP, OCSP_R_SERVER_RESPONSE_PARSE_ERROR}, + #else + {"SERVER_RESPONSE_PARSE_ERROR", 39, 115}, + #endif + #ifdef OCSP_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 39, 117}, + #endif + #ifdef OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 39, 118}, + #endif + #ifdef OCSP_R_STATUS_EXPIRED + {"STATUS_EXPIRED", ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED}, + #else + {"STATUS_EXPIRED", 39, 125}, + #endif + #ifdef OCSP_R_STATUS_NOT_YET_VALID + {"STATUS_NOT_YET_VALID", ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID}, + #else + {"STATUS_NOT_YET_VALID", 39, 126}, + #endif + #ifdef OCSP_R_STATUS_TOO_OLD + {"STATUS_TOO_OLD", ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD}, + #else + {"STATUS_TOO_OLD", 39, 127}, + #endif + #ifdef OCSP_R_UNKNOWN_MESSAGE_DIGEST + {"UNKNOWN_MESSAGE_DIGEST", ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST}, + #else + {"UNKNOWN_MESSAGE_DIGEST", 39, 119}, + #endif + #ifdef OCSP_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_OCSP, OCSP_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 39, 120}, + #endif + #ifdef OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE + {"UNSUPPORTED_REQUESTORNAME_TYPE", ERR_LIB_OCSP, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE}, + #else + {"UNSUPPORTED_REQUESTORNAME_TYPE", 39, 129}, + #endif + #ifdef OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE + {"AMBIGUOUS_CONTENT_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE}, + #else + {"AMBIGUOUS_CONTENT_TYPE", 44, 107}, + #endif + #ifdef OSSL_STORE_R_BAD_PASSWORD_READ + {"BAD_PASSWORD_READ", ERR_LIB_OSSL_STORE, OSSL_STORE_R_BAD_PASSWORD_READ}, + #else + {"BAD_PASSWORD_READ", 44, 115}, + #endif + #ifdef OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC + {"ERROR_VERIFYING_PKCS12_MAC", ERR_LIB_OSSL_STORE, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC}, + #else + {"ERROR_VERIFYING_PKCS12_MAC", 44, 113}, + #endif + #ifdef OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST + {"FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST", ERR_LIB_OSSL_STORE, OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST}, + #else + {"FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST", 44, 121}, + #endif + #ifdef OSSL_STORE_R_INVALID_SCHEME + {"INVALID_SCHEME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME}, + #else + {"INVALID_SCHEME", 44, 106}, + #endif + #ifdef OSSL_STORE_R_IS_NOT_A + {"IS_NOT_A", ERR_LIB_OSSL_STORE, OSSL_STORE_R_IS_NOT_A}, + #else + {"IS_NOT_A", 44, 112}, + #endif + #ifdef OSSL_STORE_R_LOADER_INCOMPLETE + {"LOADER_INCOMPLETE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE}, + #else + {"LOADER_INCOMPLETE", 44, 116}, + #endif + #ifdef OSSL_STORE_R_LOADING_STARTED + {"LOADING_STARTED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED}, + #else + {"LOADING_STARTED", 44, 117}, + #endif + #ifdef OSSL_STORE_R_NOT_A_CERTIFICATE + {"NOT_A_CERTIFICATE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE}, + #else + {"NOT_A_CERTIFICATE", 44, 100}, + #endif + #ifdef OSSL_STORE_R_NOT_A_CRL + {"NOT_A_CRL", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL}, + #else + {"NOT_A_CRL", 44, 101}, + #endif + #ifdef OSSL_STORE_R_NOT_A_KEY + {"NOT_A_KEY", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_KEY}, + #else + {"NOT_A_KEY", 44, 102}, + #endif + #ifdef OSSL_STORE_R_NOT_A_NAME + {"NOT_A_NAME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME}, + #else + {"NOT_A_NAME", 44, 103}, + #endif + #ifdef OSSL_STORE_R_NOT_PARAMETERS + {"NOT_PARAMETERS", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS}, + #else + {"NOT_PARAMETERS", 44, 104}, + #endif + #ifdef OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR + {"PASSPHRASE_CALLBACK_ERROR", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR}, + #else + {"PASSPHRASE_CALLBACK_ERROR", 44, 114}, + #endif + #ifdef OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE + {"PATH_MUST_BE_ABSOLUTE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE}, + #else + {"PATH_MUST_BE_ABSOLUTE", 44, 108}, + #endif + #ifdef OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", ERR_LIB_OSSL_STORE, OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES}, + #else + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", 44, 119}, + #endif + #ifdef OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED + {"UI_PROCESS_INTERRUPTED_OR_CANCELLED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED}, + #else + {"UI_PROCESS_INTERRUPTED_OR_CANCELLED", 44, 109}, + #endif + #ifdef OSSL_STORE_R_UNREGISTERED_SCHEME + {"UNREGISTERED_SCHEME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNREGISTERED_SCHEME}, + #else + {"UNREGISTERED_SCHEME", 44, 105}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 44, 110}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_OPERATION + {"UNSUPPORTED_OPERATION", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION}, + #else + {"UNSUPPORTED_OPERATION", 44, 118}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE + {"UNSUPPORTED_SEARCH_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE}, + #else + {"UNSUPPORTED_SEARCH_TYPE", 44, 120}, + #endif + #ifdef OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED + {"URI_AUTHORITY_UNSUPPORTED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED}, + #else + {"URI_AUTHORITY_UNSUPPORTED", 44, 111}, + #endif + #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 + {"BAD_DECRYPT", 9, 101}, + #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 + {"BAD_IV_CHARS", 9, 103}, + #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 + {"BAD_PASSWORD_READ", 9, 104}, + #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 + {"BIO_WRITE_FAILURE", 9, 118}, + #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 + {"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 + {"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 + {"EXPECTING_PUBLIC_KEY_BLOB", 9, 120}, + #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 + {"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 + {"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 + {"KEYBLOB_TOO_SHORT", 9, 123}, + #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 + {"NOT_DEK_INFO", 9, 105}, + #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 + {"NOT_PROC_TYPE", 9, 107}, + #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 + {"PROBLEMS_GETTING_PASSWORD", 9, 109}, + #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 + {"PVK_TOO_SHORT", 9, 125}, + #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 + {"SHORT_HEADER", 9, 112}, + #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 + {"UNSUPPORTED_CIPHER", 9, 113}, + #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 + {"UNSUPPORTED_KEY_COMPONENTS", 9, 126}, + #endif + #ifdef PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE + {"UNSUPPORTED_PUBLIC_KEY_TYPE", ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE}, + #else + {"UNSUPPORTED_PUBLIC_KEY_TYPE", 9, 110}, + #endif + #ifdef PKCS12_R_CANT_PACK_STRUCTURE + {"CANT_PACK_STRUCTURE", ERR_LIB_PKCS12, PKCS12_R_CANT_PACK_STRUCTURE}, + #else + {"CANT_PACK_STRUCTURE", 35, 100}, + #endif + #ifdef PKCS12_R_CONTENT_TYPE_NOT_DATA + {"CONTENT_TYPE_NOT_DATA", ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA}, + #else + {"CONTENT_TYPE_NOT_DATA", 35, 121}, + #endif + #ifdef PKCS12_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 35, 101}, + #endif + #ifdef PKCS12_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 35, 102}, + #endif + #ifdef PKCS12_R_ENCRYPT_ERROR + {"ENCRYPT_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR}, + #else + {"ENCRYPT_ERROR", 35, 103}, + #endif + #ifdef PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", ERR_LIB_PKCS12, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE}, + #else + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", 35, 120}, + #endif + #ifdef PKCS12_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 35, 104}, + #endif + #ifdef PKCS12_R_INVALID_NULL_PKCS12_POINTER + {"INVALID_NULL_PKCS12_POINTER", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER}, + #else + {"INVALID_NULL_PKCS12_POINTER", 35, 105}, + #endif + #ifdef PKCS12_R_IV_GEN_ERROR + {"IV_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_IV_GEN_ERROR}, + #else + {"IV_GEN_ERROR", 35, 106}, + #endif + #ifdef PKCS12_R_KEY_GEN_ERROR + {"KEY_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR}, + #else + {"KEY_GEN_ERROR", 35, 107}, + #endif + #ifdef PKCS12_R_MAC_ABSENT + {"MAC_ABSENT", ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT}, + #else + {"MAC_ABSENT", 35, 108}, + #endif + #ifdef PKCS12_R_MAC_GENERATION_ERROR + {"MAC_GENERATION_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR}, + #else + {"MAC_GENERATION_ERROR", 35, 109}, + #endif + #ifdef PKCS12_R_MAC_SETUP_ERROR + {"MAC_SETUP_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR}, + #else + {"MAC_SETUP_ERROR", 35, 110}, + #endif + #ifdef PKCS12_R_MAC_STRING_SET_ERROR + {"MAC_STRING_SET_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR}, + #else + {"MAC_STRING_SET_ERROR", 35, 111}, + #endif + #ifdef PKCS12_R_MAC_VERIFY_FAILURE + {"MAC_VERIFY_FAILURE", ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE}, + #else + {"MAC_VERIFY_FAILURE", 35, 113}, + #endif + #ifdef PKCS12_R_PARSE_ERROR + {"PARSE_ERROR", ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR}, + #else + {"PARSE_ERROR", 35, 114}, + #endif + #ifdef PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR + {"PKCS12_ALGOR_CIPHERINIT_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR}, + #else + {"PKCS12_ALGOR_CIPHERINIT_ERROR", 35, 115}, + #endif + #ifdef PKCS12_R_PKCS12_CIPHERFINAL_ERROR + {"PKCS12_CIPHERFINAL_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR}, + #else + {"PKCS12_CIPHERFINAL_ERROR", 35, 116}, + #endif + #ifdef PKCS12_R_PKCS12_PBE_CRYPT_ERROR + {"PKCS12_PBE_CRYPT_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_PBE_CRYPT_ERROR}, + #else + {"PKCS12_PBE_CRYPT_ERROR", 35, 117}, + #endif + #ifdef PKCS12_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 35, 118}, + #endif + #ifdef PKCS12_R_UNSUPPORTED_PKCS12_MODE + {"UNSUPPORTED_PKCS12_MODE", ERR_LIB_PKCS12, PKCS12_R_UNSUPPORTED_PKCS12_MODE}, + #else + {"UNSUPPORTED_PKCS12_MODE", 35, 119}, + #endif + #ifdef PKCS7_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_PKCS7, PKCS7_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 33, 117}, + #endif + #ifdef PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 33, 144}, + #endif + #ifdef PKCS7_R_CIPHER_NOT_INITIALIZED + {"CIPHER_NOT_INITIALIZED", ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED}, + #else + {"CIPHER_NOT_INITIALIZED", 33, 116}, + #endif + #ifdef PKCS7_R_CONTENT_AND_DATA_PRESENT + {"CONTENT_AND_DATA_PRESENT", ERR_LIB_PKCS7, PKCS7_R_CONTENT_AND_DATA_PRESENT}, + #else + {"CONTENT_AND_DATA_PRESENT", 33, 118}, + #endif + #ifdef PKCS7_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_PKCS7, PKCS7_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 33, 152}, + #endif + #ifdef PKCS7_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_PKCS7, PKCS7_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 33, 119}, + #endif + #ifdef PKCS7_R_DIGEST_FAILURE + {"DIGEST_FAILURE", ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE}, + #else + {"DIGEST_FAILURE", 33, 101}, + #endif + #ifdef PKCS7_R_ENCRYPTION_CTRL_FAILURE + {"ENCRYPTION_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE}, + #else + {"ENCRYPTION_CTRL_FAILURE", 33, 149}, + #endif + #ifdef PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 150}, + #endif + #ifdef PKCS7_R_ERROR_ADDING_RECIPIENT + {"ERROR_ADDING_RECIPIENT", ERR_LIB_PKCS7, PKCS7_R_ERROR_ADDING_RECIPIENT}, + #else + {"ERROR_ADDING_RECIPIENT", 33, 120}, + #endif + #ifdef PKCS7_R_ERROR_SETTING_CIPHER + {"ERROR_SETTING_CIPHER", ERR_LIB_PKCS7, PKCS7_R_ERROR_SETTING_CIPHER}, + #else + {"ERROR_SETTING_CIPHER", 33, 121}, + #endif + #ifdef PKCS7_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 33, 143}, + #endif + #ifdef PKCS7_R_INVALID_SIGNED_DATA_TYPE + {"INVALID_SIGNED_DATA_TYPE", ERR_LIB_PKCS7, PKCS7_R_INVALID_SIGNED_DATA_TYPE}, + #else + {"INVALID_SIGNED_DATA_TYPE", 33, 155}, + #endif + #ifdef PKCS7_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT}, + #else + {"NO_CONTENT", 33, 122}, + #endif + #ifdef PKCS7_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 33, 151}, + #endif + #ifdef PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND + {"NO_MATCHING_DIGEST_TYPE_FOUND", ERR_LIB_PKCS7, PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND}, + #else + {"NO_MATCHING_DIGEST_TYPE_FOUND", 33, 154}, + #endif + #ifdef PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE + {"NO_RECIPIENT_MATCHES_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE}, + #else + {"NO_RECIPIENT_MATCHES_CERTIFICATE", 33, 115}, + #endif + #ifdef PKCS7_R_NO_SIGNATURES_ON_DATA + {"NO_SIGNATURES_ON_DATA", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNATURES_ON_DATA}, + #else + {"NO_SIGNATURES_ON_DATA", 33, 123}, + #endif + #ifdef PKCS7_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 33, 142}, + #endif + #ifdef PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", ERR_LIB_PKCS7, PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE}, + #else + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", 33, 104}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 33, 124}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNER_ERROR + {"PKCS7_ADD_SIGNER_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNER_ERROR}, + #else + {"PKCS7_ADD_SIGNER_ERROR", 33, 153}, + #endif + #ifdef PKCS7_R_PKCS7_DATASIGN + {"PKCS7_DATASIGN", ERR_LIB_PKCS7, PKCS7_R_PKCS7_DATASIGN}, + #else + {"PKCS7_DATASIGN", 33, 145}, + #endif + #ifdef PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 33, 127}, + #endif + #ifdef PKCS7_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 33, 105}, + #endif + #ifdef PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_PKCS7, PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 33, 128}, + #endif + #ifdef PKCS7_R_SIGNING_CTRL_FAILURE + {"SIGNING_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE}, + #else + {"SIGNING_CTRL_FAILURE", 33, 147}, + #endif + #ifdef PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 148}, + #endif + #ifdef PKCS7_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_PKCS7, PKCS7_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 33, 129}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_CERTIFICATE + {"UNABLE_TO_FIND_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE}, + #else + {"UNABLE_TO_FIND_CERTIFICATE", 33, 106}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MEM_BIO + {"UNABLE_TO_FIND_MEM_BIO", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MEM_BIO}, + #else + {"UNABLE_TO_FIND_MEM_BIO", 33, 107}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST + {"UNABLE_TO_FIND_MESSAGE_DIGEST", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST}, + #else + {"UNABLE_TO_FIND_MESSAGE_DIGEST", 33, 108}, + #endif + #ifdef PKCS7_R_UNKNOWN_DIGEST_TYPE + {"UNKNOWN_DIGEST_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE}, + #else + {"UNKNOWN_DIGEST_TYPE", 33, 109}, + #endif + #ifdef PKCS7_R_UNKNOWN_OPERATION + {"UNKNOWN_OPERATION", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION}, + #else + {"UNKNOWN_OPERATION", 33, 110}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CIPHER_TYPE + {"UNSUPPORTED_CIPHER_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE}, + #else + {"UNSUPPORTED_CIPHER_TYPE", 33, 111}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 33, 112}, + #endif + #ifdef PKCS7_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 33, 113}, + #endif + #ifdef PKCS7_R_WRONG_PKCS7_TYPE + {"WRONG_PKCS7_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE}, + #else + {"WRONG_PKCS7_TYPE", 33, 114}, + #endif + #ifdef RAND_R_ADDITIONAL_INPUT_TOO_LONG + {"ADDITIONAL_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ADDITIONAL_INPUT_TOO_LONG}, + #else + {"ADDITIONAL_INPUT_TOO_LONG", 36, 102}, + #endif + #ifdef RAND_R_ALREADY_INSTANTIATED + {"ALREADY_INSTANTIATED", ERR_LIB_RAND, RAND_R_ALREADY_INSTANTIATED}, + #else + {"ALREADY_INSTANTIATED", 36, 103}, + #endif + #ifdef RAND_R_ARGUMENT_OUT_OF_RANGE + {"ARGUMENT_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE}, + #else + {"ARGUMENT_OUT_OF_RANGE", 36, 105}, + #endif + #ifdef RAND_R_CANNOT_OPEN_FILE + {"CANNOT_OPEN_FILE", ERR_LIB_RAND, RAND_R_CANNOT_OPEN_FILE}, + #else + {"CANNOT_OPEN_FILE", 36, 121}, + #endif + #ifdef RAND_R_DRBG_ALREADY_INITIALIZED + {"DRBG_ALREADY_INITIALIZED", ERR_LIB_RAND, RAND_R_DRBG_ALREADY_INITIALIZED}, + #else + {"DRBG_ALREADY_INITIALIZED", 36, 129}, + #endif + #ifdef RAND_R_DRBG_NOT_INITIALISED + {"DRBG_NOT_INITIALISED", ERR_LIB_RAND, RAND_R_DRBG_NOT_INITIALISED}, + #else + {"DRBG_NOT_INITIALISED", 36, 104}, + #endif + #ifdef RAND_R_ENTROPY_INPUT_TOO_LONG + {"ENTROPY_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG}, + #else + {"ENTROPY_INPUT_TOO_LONG", 36, 106}, + #endif + #ifdef RAND_R_ENTROPY_OUT_OF_RANGE + {"ENTROPY_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ENTROPY_OUT_OF_RANGE}, + #else + {"ENTROPY_OUT_OF_RANGE", 36, 124}, + #endif + #ifdef RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED + {"ERROR_ENTROPY_POOL_WAS_IGNORED", ERR_LIB_RAND, RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED}, + #else + {"ERROR_ENTROPY_POOL_WAS_IGNORED", 36, 127}, + #endif + #ifdef RAND_R_ERROR_INITIALISING_DRBG + {"ERROR_INITIALISING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INITIALISING_DRBG}, + #else + {"ERROR_INITIALISING_DRBG", 36, 107}, + #endif + #ifdef RAND_R_ERROR_INSTANTIATING_DRBG + {"ERROR_INSTANTIATING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG}, + #else + {"ERROR_INSTANTIATING_DRBG", 36, 108}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT}, + #else + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", 36, 109}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ENTROPY + {"ERROR_RETRIEVING_ENTROPY", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY}, + #else + {"ERROR_RETRIEVING_ENTROPY", 36, 110}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_NONCE + {"ERROR_RETRIEVING_NONCE", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_NONCE}, + #else + {"ERROR_RETRIEVING_NONCE", 36, 111}, + #endif + #ifdef RAND_R_FAILED_TO_CREATE_LOCK + {"FAILED_TO_CREATE_LOCK", ERR_LIB_RAND, RAND_R_FAILED_TO_CREATE_LOCK}, + #else + {"FAILED_TO_CREATE_LOCK", 36, 126}, + #endif + #ifdef RAND_R_FUNC_NOT_IMPLEMENTED + {"FUNC_NOT_IMPLEMENTED", ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED}, + #else + {"FUNC_NOT_IMPLEMENTED", 36, 101}, + #endif + #ifdef RAND_R_FWRITE_ERROR + {"FWRITE_ERROR", ERR_LIB_RAND, RAND_R_FWRITE_ERROR}, + #else + {"FWRITE_ERROR", 36, 123}, + #endif + #ifdef RAND_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_RAND, RAND_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 36, 112}, + #endif + #ifdef RAND_R_INTERNAL_ERROR + {"INTERNAL_ERROR", ERR_LIB_RAND, RAND_R_INTERNAL_ERROR}, + #else + {"INTERNAL_ERROR", 36, 113}, + #endif + #ifdef RAND_R_IN_ERROR_STATE + {"IN_ERROR_STATE", ERR_LIB_RAND, RAND_R_IN_ERROR_STATE}, + #else + {"IN_ERROR_STATE", 36, 114}, + #endif + #ifdef RAND_R_NOT_A_REGULAR_FILE + {"NOT_A_REGULAR_FILE", ERR_LIB_RAND, RAND_R_NOT_A_REGULAR_FILE}, + #else + {"NOT_A_REGULAR_FILE", 36, 122}, + #endif + #ifdef RAND_R_NOT_INSTANTIATED + {"NOT_INSTANTIATED", ERR_LIB_RAND, RAND_R_NOT_INSTANTIATED}, + #else + {"NOT_INSTANTIATED", 36, 115}, + #endif + #ifdef RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED + {"NO_DRBG_IMPLEMENTATION_SELECTED", ERR_LIB_RAND, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED}, + #else + {"NO_DRBG_IMPLEMENTATION_SELECTED", 36, 128}, + #endif + #ifdef RAND_R_PARENT_LOCKING_NOT_ENABLED + {"PARENT_LOCKING_NOT_ENABLED", ERR_LIB_RAND, RAND_R_PARENT_LOCKING_NOT_ENABLED}, + #else + {"PARENT_LOCKING_NOT_ENABLED", 36, 130}, + #endif + #ifdef RAND_R_PARENT_STRENGTH_TOO_WEAK + {"PARENT_STRENGTH_TOO_WEAK", ERR_LIB_RAND, RAND_R_PARENT_STRENGTH_TOO_WEAK}, + #else + {"PARENT_STRENGTH_TOO_WEAK", 36, 131}, + #endif + #ifdef RAND_R_PERSONALISATION_STRING_TOO_LONG + {"PERSONALISATION_STRING_TOO_LONG", ERR_LIB_RAND, RAND_R_PERSONALISATION_STRING_TOO_LONG}, + #else + {"PERSONALISATION_STRING_TOO_LONG", 36, 116}, + #endif + #ifdef RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", ERR_LIB_RAND, RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED}, + #else + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", 36, 133}, + #endif + #ifdef RAND_R_PRNG_NOT_SEEDED + {"PRNG_NOT_SEEDED", ERR_LIB_RAND, RAND_R_PRNG_NOT_SEEDED}, + #else + {"PRNG_NOT_SEEDED", 36, 100}, + #endif + #ifdef RAND_R_RANDOM_POOL_OVERFLOW + {"RANDOM_POOL_OVERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW}, + #else + {"RANDOM_POOL_OVERFLOW", 36, 125}, + #endif + #ifdef RAND_R_RANDOM_POOL_UNDERFLOW + {"RANDOM_POOL_UNDERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_UNDERFLOW}, + #else + {"RANDOM_POOL_UNDERFLOW", 36, 134}, + #endif + #ifdef RAND_R_REQUEST_TOO_LARGE_FOR_DRBG + {"REQUEST_TOO_LARGE_FOR_DRBG", ERR_LIB_RAND, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG}, + #else + {"REQUEST_TOO_LARGE_FOR_DRBG", 36, 117}, + #endif + #ifdef RAND_R_RESEED_ERROR + {"RESEED_ERROR", ERR_LIB_RAND, RAND_R_RESEED_ERROR}, + #else + {"RESEED_ERROR", 36, 118}, + #endif + #ifdef RAND_R_SELFTEST_FAILURE + {"SELFTEST_FAILURE", ERR_LIB_RAND, RAND_R_SELFTEST_FAILURE}, + #else + {"SELFTEST_FAILURE", 36, 119}, + #endif + #ifdef RAND_R_TOO_LITTLE_NONCE_REQUESTED + {"TOO_LITTLE_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_LITTLE_NONCE_REQUESTED}, + #else + {"TOO_LITTLE_NONCE_REQUESTED", 36, 135}, + #endif + #ifdef RAND_R_TOO_MUCH_NONCE_REQUESTED + {"TOO_MUCH_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_MUCH_NONCE_REQUESTED}, + #else + {"TOO_MUCH_NONCE_REQUESTED", 36, 136}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_FLAGS + {"UNSUPPORTED_DRBG_FLAGS", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_FLAGS}, + #else + {"UNSUPPORTED_DRBG_FLAGS", 36, 132}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_TYPE + {"UNSUPPORTED_DRBG_TYPE", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_TYPE}, + #else + {"UNSUPPORTED_DRBG_TYPE", 36, 120}, + #endif + #ifdef RSA_R_ALGORITHM_MISMATCH + {"ALGORITHM_MISMATCH", ERR_LIB_RSA, RSA_R_ALGORITHM_MISMATCH}, + #else + {"ALGORITHM_MISMATCH", 4, 100}, + #endif + #ifdef RSA_R_BAD_E_VALUE + {"BAD_E_VALUE", ERR_LIB_RSA, RSA_R_BAD_E_VALUE}, + #else + {"BAD_E_VALUE", 4, 101}, + #endif + #ifdef RSA_R_BAD_FIXED_HEADER_DECRYPT + {"BAD_FIXED_HEADER_DECRYPT", ERR_LIB_RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT}, + #else + {"BAD_FIXED_HEADER_DECRYPT", 4, 102}, + #endif + #ifdef RSA_R_BAD_PAD_BYTE_COUNT + {"BAD_PAD_BYTE_COUNT", ERR_LIB_RSA, RSA_R_BAD_PAD_BYTE_COUNT}, + #else + {"BAD_PAD_BYTE_COUNT", 4, 103}, + #endif + #ifdef RSA_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_RSA, RSA_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 4, 104}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_01 + {"BLOCK_TYPE_IS_NOT_01", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_01}, + #else + {"BLOCK_TYPE_IS_NOT_01", 4, 106}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_02 + {"BLOCK_TYPE_IS_NOT_02", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_02}, + #else + {"BLOCK_TYPE_IS_NOT_02", 4, 107}, + #endif + #ifdef RSA_R_DATA_GREATER_THAN_MOD_LEN + {"DATA_GREATER_THAN_MOD_LEN", ERR_LIB_RSA, RSA_R_DATA_GREATER_THAN_MOD_LEN}, + #else + {"DATA_GREATER_THAN_MOD_LEN", 4, 108}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE + {"DATA_TOO_LARGE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE}, + #else + {"DATA_TOO_LARGE", 4, 109}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE + {"DATA_TOO_LARGE_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE}, + #else + {"DATA_TOO_LARGE_FOR_KEY_SIZE", 4, 110}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_MODULUS + {"DATA_TOO_LARGE_FOR_MODULUS", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS}, + #else + {"DATA_TOO_LARGE_FOR_MODULUS", 4, 132}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL + {"DATA_TOO_SMALL", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL}, + #else + {"DATA_TOO_SMALL", 4, 111}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE + {"DATA_TOO_SMALL_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE}, + #else + {"DATA_TOO_SMALL_FOR_KEY_SIZE", 4, 122}, + #endif + #ifdef RSA_R_DIGEST_DOES_NOT_MATCH + {"DIGEST_DOES_NOT_MATCH", ERR_LIB_RSA, RSA_R_DIGEST_DOES_NOT_MATCH}, + #else + {"DIGEST_DOES_NOT_MATCH", 4, 158}, + #endif + #ifdef RSA_R_DIGEST_NOT_ALLOWED + {"DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED}, + #else + {"DIGEST_NOT_ALLOWED", 4, 145}, + #endif + #ifdef RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY + {"DIGEST_TOO_BIG_FOR_RSA_KEY", ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY}, + #else + {"DIGEST_TOO_BIG_FOR_RSA_KEY", 4, 112}, + #endif + #ifdef RSA_R_DMP1_NOT_CONGRUENT_TO_D + {"DMP1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMP1_NOT_CONGRUENT_TO_D}, + #else + {"DMP1_NOT_CONGRUENT_TO_D", 4, 124}, + #endif + #ifdef RSA_R_DMQ1_NOT_CONGRUENT_TO_D + {"DMQ1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMQ1_NOT_CONGRUENT_TO_D}, + #else + {"DMQ1_NOT_CONGRUENT_TO_D", 4, 125}, + #endif + #ifdef RSA_R_D_E_NOT_CONGRUENT_TO_1 + {"D_E_NOT_CONGRUENT_TO_1", ERR_LIB_RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1}, + #else + {"D_E_NOT_CONGRUENT_TO_1", 4, 123}, + #endif + #ifdef RSA_R_FIRST_OCTET_INVALID + {"FIRST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_FIRST_OCTET_INVALID}, + #else + {"FIRST_OCTET_INVALID", 4, 133}, + #endif + #ifdef RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE}, + #else + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", 4, 144}, + #endif + #ifdef RSA_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 4, 157}, + #endif + #ifdef RSA_R_INVALID_DIGEST_LENGTH + {"INVALID_DIGEST_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH}, + #else + {"INVALID_DIGEST_LENGTH", 4, 143}, + #endif + #ifdef RSA_R_INVALID_HEADER + {"INVALID_HEADER", ERR_LIB_RSA, RSA_R_INVALID_HEADER}, + #else + {"INVALID_HEADER", 4, 137}, + #endif + #ifdef RSA_R_INVALID_LABEL + {"INVALID_LABEL", ERR_LIB_RSA, RSA_R_INVALID_LABEL}, + #else + {"INVALID_LABEL", 4, 160}, + #endif + #ifdef RSA_R_INVALID_MESSAGE_LENGTH + {"INVALID_MESSAGE_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH}, + #else + {"INVALID_MESSAGE_LENGTH", 4, 131}, + #endif + #ifdef RSA_R_INVALID_MGF1_MD + {"INVALID_MGF1_MD", ERR_LIB_RSA, RSA_R_INVALID_MGF1_MD}, + #else + {"INVALID_MGF1_MD", 4, 156}, + #endif + #ifdef RSA_R_INVALID_MULTI_PRIME_KEY + {"INVALID_MULTI_PRIME_KEY", ERR_LIB_RSA, RSA_R_INVALID_MULTI_PRIME_KEY}, + #else + {"INVALID_MULTI_PRIME_KEY", 4, 167}, + #endif + #ifdef RSA_R_INVALID_OAEP_PARAMETERS + {"INVALID_OAEP_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_OAEP_PARAMETERS}, + #else + {"INVALID_OAEP_PARAMETERS", 4, 161}, + #endif + #ifdef RSA_R_INVALID_PADDING + {"INVALID_PADDING", ERR_LIB_RSA, RSA_R_INVALID_PADDING}, + #else + {"INVALID_PADDING", 4, 138}, + #endif + #ifdef RSA_R_INVALID_PADDING_MODE + {"INVALID_PADDING_MODE", ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE}, + #else + {"INVALID_PADDING_MODE", 4, 141}, + #endif + #ifdef RSA_R_INVALID_PSS_PARAMETERS + {"INVALID_PSS_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS}, + #else + {"INVALID_PSS_PARAMETERS", 4, 149}, + #endif + #ifdef RSA_R_INVALID_PSS_SALTLEN + {"INVALID_PSS_SALTLEN", ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN}, + #else + {"INVALID_PSS_SALTLEN", 4, 146}, + #endif + #ifdef RSA_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 4, 150}, + #endif + #ifdef RSA_R_INVALID_TRAILER + {"INVALID_TRAILER", ERR_LIB_RSA, RSA_R_INVALID_TRAILER}, + #else + {"INVALID_TRAILER", 4, 139}, + #endif + #ifdef RSA_R_INVALID_X931_DIGEST + {"INVALID_X931_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_X931_DIGEST}, + #else + {"INVALID_X931_DIGEST", 4, 142}, + #endif + #ifdef RSA_R_IQMP_NOT_INVERSE_OF_Q + {"IQMP_NOT_INVERSE_OF_Q", ERR_LIB_RSA, RSA_R_IQMP_NOT_INVERSE_OF_Q}, + #else + {"IQMP_NOT_INVERSE_OF_Q", 4, 126}, + #endif + #ifdef RSA_R_KEY_PRIME_NUM_INVALID + {"KEY_PRIME_NUM_INVALID", ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID}, + #else + {"KEY_PRIME_NUM_INVALID", 4, 165}, + #endif + #ifdef RSA_R_KEY_SIZE_TOO_SMALL + {"KEY_SIZE_TOO_SMALL", ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL}, + #else + {"KEY_SIZE_TOO_SMALL", 4, 120}, + #endif + #ifdef RSA_R_LAST_OCTET_INVALID + {"LAST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_LAST_OCTET_INVALID}, + #else + {"LAST_OCTET_INVALID", 4, 134}, + #endif + #ifdef RSA_R_MGF1_DIGEST_NOT_ALLOWED + {"MGF1_DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED}, + #else + {"MGF1_DIGEST_NOT_ALLOWED", 4, 152}, + #endif + #ifdef RSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_RSA, RSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 4, 179}, + #endif + #ifdef RSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 4, 105}, + #endif + #ifdef RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", ERR_LIB_RSA, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R}, + #else + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", 4, 168}, + #endif + #ifdef RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D}, + #else + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", 4, 169}, + #endif + #ifdef RSA_R_MP_R_NOT_PRIME + {"MP_R_NOT_PRIME", ERR_LIB_RSA, RSA_R_MP_R_NOT_PRIME}, + #else + {"MP_R_NOT_PRIME", 4, 170}, + #endif + #ifdef RSA_R_NO_PUBLIC_EXPONENT + {"NO_PUBLIC_EXPONENT", ERR_LIB_RSA, RSA_R_NO_PUBLIC_EXPONENT}, + #else + {"NO_PUBLIC_EXPONENT", 4, 140}, + #endif + #ifdef RSA_R_NULL_BEFORE_BLOCK_MISSING + {"NULL_BEFORE_BLOCK_MISSING", ERR_LIB_RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING}, + #else + {"NULL_BEFORE_BLOCK_MISSING", 4, 113}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES}, + #else + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", 4, 172}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_P_Q + {"N_DOES_NOT_EQUAL_P_Q", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_P_Q}, + #else + {"N_DOES_NOT_EQUAL_P_Q", 4, 127}, + #endif + #ifdef RSA_R_OAEP_DECODING_ERROR + {"OAEP_DECODING_ERROR", ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR}, + #else + {"OAEP_DECODING_ERROR", 4, 121}, + #endif + #ifdef RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_RSA, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 4, 148}, + #endif + #ifdef RSA_R_PADDING_CHECK_FAILED + {"PADDING_CHECK_FAILED", ERR_LIB_RSA, RSA_R_PADDING_CHECK_FAILED}, + #else + {"PADDING_CHECK_FAILED", 4, 114}, + #endif + #ifdef RSA_R_PKCS_DECODING_ERROR + {"PKCS_DECODING_ERROR", ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR}, + #else + {"PKCS_DECODING_ERROR", 4, 159}, + #endif + #ifdef RSA_R_PSS_SALTLEN_TOO_SMALL + {"PSS_SALTLEN_TOO_SMALL", ERR_LIB_RSA, RSA_R_PSS_SALTLEN_TOO_SMALL}, + #else + {"PSS_SALTLEN_TOO_SMALL", 4, 164}, + #endif + #ifdef RSA_R_P_NOT_PRIME + {"P_NOT_PRIME", ERR_LIB_RSA, RSA_R_P_NOT_PRIME}, + #else + {"P_NOT_PRIME", 4, 128}, + #endif + #ifdef RSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_RSA, RSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 4, 129}, + #endif + #ifdef RSA_R_RSA_OPERATIONS_NOT_SUPPORTED + {"RSA_OPERATIONS_NOT_SUPPORTED", ERR_LIB_RSA, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED}, + #else + {"RSA_OPERATIONS_NOT_SUPPORTED", 4, 130}, + #endif + #ifdef RSA_R_SLEN_CHECK_FAILED + {"SLEN_CHECK_FAILED", ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED}, + #else + {"SLEN_CHECK_FAILED", 4, 136}, + #endif + #ifdef RSA_R_SLEN_RECOVERY_FAILED + {"SLEN_RECOVERY_FAILED", ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED}, + #else + {"SLEN_RECOVERY_FAILED", 4, 135}, + #endif + #ifdef RSA_R_SSLV3_ROLLBACK_ATTACK + {"SSLV3_ROLLBACK_ATTACK", ERR_LIB_RSA, RSA_R_SSLV3_ROLLBACK_ATTACK}, + #else + {"SSLV3_ROLLBACK_ATTACK", 4, 115}, + #endif + #ifdef RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_RSA, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 4, 116}, + #endif + #ifdef RSA_R_UNKNOWN_ALGORITHM_TYPE + {"UNKNOWN_ALGORITHM_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE}, + #else + {"UNKNOWN_ALGORITHM_TYPE", 4, 117}, + #endif + #ifdef RSA_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 4, 166}, + #endif + #ifdef RSA_R_UNKNOWN_MASK_DIGEST + {"UNKNOWN_MASK_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_MASK_DIGEST}, + #else + {"UNKNOWN_MASK_DIGEST", 4, 151}, + #endif + #ifdef RSA_R_UNKNOWN_PADDING_TYPE + {"UNKNOWN_PADDING_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE}, + #else + {"UNKNOWN_PADDING_TYPE", 4, 118}, + #endif + #ifdef RSA_R_UNSUPPORTED_ENCRYPTION_TYPE + {"UNSUPPORTED_ENCRYPTION_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE}, + #else + {"UNSUPPORTED_ENCRYPTION_TYPE", 4, 162}, + #endif + #ifdef RSA_R_UNSUPPORTED_LABEL_SOURCE + {"UNSUPPORTED_LABEL_SOURCE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_LABEL_SOURCE}, + #else + {"UNSUPPORTED_LABEL_SOURCE", 4, 163}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_ALGORITHM + {"UNSUPPORTED_MASK_ALGORITHM", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_ALGORITHM}, + #else + {"UNSUPPORTED_MASK_ALGORITHM", 4, 153}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_PARAMETER + {"UNSUPPORTED_MASK_PARAMETER", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_PARAMETER}, + #else + {"UNSUPPORTED_MASK_PARAMETER", 4, 154}, + #endif + #ifdef RSA_R_UNSUPPORTED_SIGNATURE_TYPE + {"UNSUPPORTED_SIGNATURE_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE}, + #else + {"UNSUPPORTED_SIGNATURE_TYPE", 4, 155}, + #endif + #ifdef RSA_R_VALUE_MISSING + {"VALUE_MISSING", ERR_LIB_RSA, RSA_R_VALUE_MISSING}, + #else + {"VALUE_MISSING", 4, 147}, + #endif + #ifdef RSA_R_WRONG_SIGNATURE_LENGTH + {"WRONG_SIGNATURE_LENGTH", ERR_LIB_RSA, RSA_R_WRONG_SIGNATURE_LENGTH}, + #else + {"WRONG_SIGNATURE_LENGTH", 4, 119}, + #endif + #ifdef SM2_R_ASN1_ERROR + {"ASN1_ERROR", ERR_LIB_SM2, SM2_R_ASN1_ERROR}, + #else + {"ASN1_ERROR", 53, 100}, + #endif + #ifdef SM2_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_SM2, SM2_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 53, 101}, + #endif + #ifdef SM2_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_SM2, SM2_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 53, 107}, + #endif + #ifdef SM2_R_DIST_ID_TOO_LARGE + {"DIST_ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_DIST_ID_TOO_LARGE}, + #else + {"DIST_ID_TOO_LARGE", 53, 110}, + #endif + #ifdef SM2_R_ID_NOT_SET + {"ID_NOT_SET", ERR_LIB_SM2, SM2_R_ID_NOT_SET}, + #else + {"ID_NOT_SET", 53, 112}, + #endif + #ifdef SM2_R_ID_TOO_LARGE + {"ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_ID_TOO_LARGE}, + #else + {"ID_TOO_LARGE", 53, 111}, + #endif + #ifdef SM2_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_SM2, SM2_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 53, 108}, + #endif + #ifdef SM2_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_SM2, SM2_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 53, 102}, + #endif + #ifdef SM2_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_SM2, SM2_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 53, 103}, + #endif + #ifdef SM2_R_INVALID_ENCODING + {"INVALID_ENCODING", ERR_LIB_SM2, SM2_R_INVALID_ENCODING}, + #else + {"INVALID_ENCODING", 53, 104}, + #endif + #ifdef SM2_R_INVALID_FIELD + {"INVALID_FIELD", ERR_LIB_SM2, SM2_R_INVALID_FIELD}, + #else + {"INVALID_FIELD", 53, 105}, + #endif + #ifdef SM2_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_SM2, SM2_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 53, 109}, + #endif + #ifdef SM2_R_USER_ID_TOO_LARGE + {"USER_ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_USER_ID_TOO_LARGE}, + #else + {"USER_ID_TOO_LARGE", 53, 106}, + #endif + #ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY + {"APPLICATION_DATA_AFTER_CLOSE_NOTIFY", ERR_LIB_SSL, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY}, + #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 + {"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 + {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", 20, 272}, + #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 + {"AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE", 20, 143}, + #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 + {"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 + {"BAD_CHANGE_CIPHER_SPEC", 20, 103}, + #endif + #ifdef SSL_R_BAD_CIPHER + {"BAD_CIPHER", ERR_LIB_SSL, SSL_R_BAD_CIPHER}, + #else + {"BAD_CIPHER", 20, 186}, + #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 + {"BAD_DATA_RETURNED_BY_CALLBACK", 20, 106}, + #endif + #ifdef SSL_R_BAD_DECOMPRESSION + {"BAD_DECOMPRESSION", ERR_LIB_SSL, SSL_R_BAD_DECOMPRESSION}, + #else + {"BAD_DECOMPRESSION", 20, 107}, + #endif + #ifdef SSL_R_BAD_DH_VALUE + {"BAD_DH_VALUE", ERR_LIB_SSL, SSL_R_BAD_DH_VALUE}, + #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 + {"BAD_DIGEST_LENGTH", 20, 111}, + #endif + #ifdef SSL_R_BAD_EARLY_DATA + {"BAD_EARLY_DATA", ERR_LIB_SSL, SSL_R_BAD_EARLY_DATA}, + #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 + {"BAD_ECC_CERT", 20, 304}, + #endif + #ifdef SSL_R_BAD_ECPOINT + {"BAD_ECPOINT", ERR_LIB_SSL, SSL_R_BAD_ECPOINT}, + #else + {"BAD_ECPOINT", 20, 306}, + #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 + {"BAD_HANDSHAKE_LENGTH", 20, 332}, + #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 + {"BAD_HELLO_REQUEST", 20, 105}, + #endif + #ifdef SSL_R_BAD_HRR_VERSION + {"BAD_HRR_VERSION", ERR_LIB_SSL, SSL_R_BAD_HRR_VERSION}, + #else + {"BAD_HRR_VERSION", 20, 263}, + #endif + #ifdef SSL_R_BAD_KEY_SHARE + {"BAD_KEY_SHARE", ERR_LIB_SSL, SSL_R_BAD_KEY_SHARE}, + #else + {"BAD_KEY_SHARE", 20, 108}, + #endif + #ifdef SSL_R_BAD_KEY_UPDATE + {"BAD_KEY_UPDATE", ERR_LIB_SSL, SSL_R_BAD_KEY_UPDATE}, + #else + {"BAD_KEY_UPDATE", 20, 122}, + #endif + #ifdef SSL_R_BAD_LEGACY_VERSION + {"BAD_LEGACY_VERSION", ERR_LIB_SSL, SSL_R_BAD_LEGACY_VERSION}, + #else + {"BAD_LEGACY_VERSION", 20, 292}, + #endif + #ifdef SSL_R_BAD_LENGTH + {"BAD_LENGTH", ERR_LIB_SSL, SSL_R_BAD_LENGTH}, + #else + {"BAD_LENGTH", 20, 271}, + #endif + #ifdef SSL_R_BAD_PACKET + {"BAD_PACKET", ERR_LIB_SSL, SSL_R_BAD_PACKET}, + #else + {"BAD_PACKET", 20, 240}, + #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 + {"BAD_PROTOCOL_VERSION_NUMBER", 20, 116}, + #endif + #ifdef SSL_R_BAD_PSK + {"BAD_PSK", ERR_LIB_SSL, SSL_R_BAD_PSK}, + #else + {"BAD_PSK", 20, 219}, + #endif + #ifdef SSL_R_BAD_PSK_IDENTITY + {"BAD_PSK_IDENTITY", ERR_LIB_SSL, SSL_R_BAD_PSK_IDENTITY}, + #else + {"BAD_PSK_IDENTITY", 20, 114}, + #endif + #ifdef SSL_R_BAD_RECORD_TYPE + {"BAD_RECORD_TYPE", ERR_LIB_SSL, SSL_R_BAD_RECORD_TYPE}, + #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 + {"BAD_RSA_ENCRYPT", 20, 119}, + #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 + {"BAD_SRP_A_LENGTH", 20, 347}, + #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_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 + {"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 + {"BAD_SSL_FILETYPE", 20, 124}, + #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 + {"BAD_WRITE_RETRY", 20, 127}, + #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 + {"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 + {"BLOCK_CIPHER_PAD_IS_WRONG", 20, 129}, + #endif + #ifdef SSL_R_BN_LIB + {"BN_LIB", ERR_LIB_SSL, SSL_R_BN_LIB}, + #else + {"BN_LIB", 20, 130}, + #endif + #ifdef SSL_R_CALLBACK_FAILED + {"CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_CALLBACK_FAILED}, + #else + {"CALLBACK_FAILED", 20, 234}, + #endif + #ifdef SSL_R_CANNOT_CHANGE_CIPHER + {"CANNOT_CHANGE_CIPHER", ERR_LIB_SSL, SSL_R_CANNOT_CHANGE_CIPHER}, + #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 + {"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 + {"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 + {"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 + {"CCS_RECEIVED_EARLY", 20, 133}, + #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 + {"CERT_CB_ERROR", 20, 377}, + #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 + #ifdef SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED + {"CIPHERSUITE_DIGEST_HAS_CHANGED", ERR_LIB_SSL, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED}, + #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 + {"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 + {"CIPHER_OR_HASH_UNAVAILABLE", 20, 138}, + #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 + {"COMPRESSED_LENGTH_TOO_LONG", 20, 140}, + #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 + {"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 + {"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 + {"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 + {"CONNECTION_TYPE_NOT_SET", 20, 144}, + #endif + #ifdef SSL_R_CONTEXT_NOT_DANE_ENABLED + {"CONTEXT_NOT_DANE_ENABLED", ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED}, + #else + {"CONTEXT_NOT_DANE_ENABLED", 20, 167}, + #endif + #ifdef SSL_R_COOKIE_GEN_CALLBACK_FAILURE + {"COOKIE_GEN_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_COOKIE_GEN_CALLBACK_FAILURE}, + #else + {"COOKIE_GEN_CALLBACK_FAILURE", 20, 400}, + #endif + #ifdef SSL_R_COOKIE_MISMATCH + {"COOKIE_MISMATCH", ERR_LIB_SSL, SSL_R_COOKIE_MISMATCH}, + #else + {"COOKIE_MISMATCH", 20, 308}, + #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 + {"CUSTOM_EXT_HANDLER_ALREADY_INSTALLED", 20, 206}, + #endif + #ifdef SSL_R_DANE_ALREADY_ENABLED + {"DANE_ALREADY_ENABLED", ERR_LIB_SSL, SSL_R_DANE_ALREADY_ENABLED}, + #else + {"DANE_ALREADY_ENABLED", 20, 172}, + #endif + #ifdef SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", ERR_LIB_SSL, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL}, + #else + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", 20, 173}, + #endif + #ifdef SSL_R_DANE_NOT_ENABLED + {"DANE_NOT_ENABLED", ERR_LIB_SSL, SSL_R_DANE_NOT_ENABLED}, + #else + {"DANE_NOT_ENABLED", 20, 175}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE + {"DANE_TLSA_BAD_CERTIFICATE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE", 20, 180}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", 20, 184}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DATA_LENGTH + {"DANE_TLSA_BAD_DATA_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DATA_LENGTH}, + #else + {"DANE_TLSA_BAD_DATA_LENGTH", 20, 189}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH + {"DANE_TLSA_BAD_DIGEST_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH}, + #else + {"DANE_TLSA_BAD_DIGEST_LENGTH", 20, 192}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_MATCHING_TYPE + {"DANE_TLSA_BAD_MATCHING_TYPE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE}, + #else + {"DANE_TLSA_BAD_MATCHING_TYPE", 20, 200}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_PUBLIC_KEY + {"DANE_TLSA_BAD_PUBLIC_KEY", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY}, + #else + {"DANE_TLSA_BAD_PUBLIC_KEY", 20, 201}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_SELECTOR + {"DANE_TLSA_BAD_SELECTOR", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_SELECTOR}, + #else + {"DANE_TLSA_BAD_SELECTOR", 20, 202}, + #endif + #ifdef SSL_R_DANE_TLSA_NULL_DATA + {"DANE_TLSA_NULL_DATA", ERR_LIB_SSL, SSL_R_DANE_TLSA_NULL_DATA}, + #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 + {"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 + {"DATA_LENGTH_TOO_LONG", 20, 146}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"DUPLICATE_COMPRESSION_ID", 20, 309}, + #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_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_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 + {"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 + {"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 + {"ERROR_IN_RECEIVED_CIPHER_LIST", 20, 151}, + #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 + {"ERROR_SETTING_TLSA_BASE_DOMAIN", 20, 204}, + #endif + #ifdef SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE + {"EXCEEDS_MAX_FRAGMENT_SIZE", ERR_LIB_SSL, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE}, + #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 + {"EXCESSIVE_MESSAGE_SIZE", 20, 152}, + #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 + {"EXTRA_DATA_IN_MESSAGE", 20, 153}, + #endif + #ifdef SSL_R_EXT_LENGTH_MISMATCH + {"EXT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_EXT_LENGTH_MISMATCH}, + #else + {"EXT_LENGTH_MISMATCH", 20, 163}, + #endif + #ifdef SSL_R_FAILED_TO_INIT_ASYNC + {"FAILED_TO_INIT_ASYNC", ERR_LIB_SSL, SSL_R_FAILED_TO_INIT_ASYNC}, + #else + {"FAILED_TO_INIT_ASYNC", 20, 405}, + #endif + #ifdef SSL_R_FRAGMENTED_CLIENT_HELLO + {"FRAGMENTED_CLIENT_HELLO", ERR_LIB_SSL, SSL_R_FRAGMENTED_CLIENT_HELLO}, + #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 + {"GOT_A_FIN_BEFORE_A_CCS", 20, 154}, + #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 + {"HTTP_REQUEST", 20, 156}, + #endif + #ifdef SSL_R_ILLEGAL_POINT_COMPRESSION + {"ILLEGAL_POINT_COMPRESSION", ERR_LIB_SSL, SSL_R_ILLEGAL_POINT_COMPRESSION}, + #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 + {"ILLEGAL_SUITEB_DIGEST", 20, 380}, + #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 + {"INCONSISTENT_COMPRESSION", 20, 340}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_ALPN + {"INCONSISTENT_EARLY_DATA_ALPN", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_ALPN}, + #else + {"INCONSISTENT_EARLY_DATA_ALPN", 20, 222}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_SNI + {"INCONSISTENT_EARLY_DATA_SNI", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_SNI}, + #else + {"INCONSISTENT_EARLY_DATA_SNI", 20, 231}, + #endif + #ifdef SSL_R_INCONSISTENT_EXTMS + {"INCONSISTENT_EXTMS", ERR_LIB_SSL, SSL_R_INCONSISTENT_EXTMS}, + #else + {"INCONSISTENT_EXTMS", 20, 104}, + #endif + #ifdef SSL_R_INSUFFICIENT_SECURITY + {"INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_INSUFFICIENT_SECURITY}, + #else + {"INSUFFICIENT_SECURITY", 20, 241}, + #endif + #ifdef SSL_R_INVALID_ALERT + {"INVALID_ALERT", ERR_LIB_SSL, SSL_R_INVALID_ALERT}, + #else + {"INVALID_ALERT", 20, 205}, + #endif + #ifdef SSL_R_INVALID_CCS_MESSAGE + {"INVALID_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_INVALID_CCS_MESSAGE}, + #else + {"INVALID_CCS_MESSAGE", 20, 260}, + #endif + #ifdef SSL_R_INVALID_CERTIFICATE_OR_ALG + {"INVALID_CERTIFICATE_OR_ALG", ERR_LIB_SSL, SSL_R_INVALID_CERTIFICATE_OR_ALG}, + #else + {"INVALID_CERTIFICATE_OR_ALG", 20, 238}, + #endif + #ifdef SSL_R_INVALID_COMMAND + {"INVALID_COMMAND", ERR_LIB_SSL, SSL_R_INVALID_COMMAND}, + #else + {"INVALID_COMMAND", 20, 280}, + #endif + #ifdef SSL_R_INVALID_COMPRESSION_ALGORITHM + {"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_INVALID_COMPRESSION_ALGORITHM}, + #else + {"INVALID_COMPRESSION_ALGORITHM", 20, 341}, + #endif + #ifdef SSL_R_INVALID_CONFIG + {"INVALID_CONFIG", ERR_LIB_SSL, SSL_R_INVALID_CONFIG}, + #else + {"INVALID_CONFIG", 20, 283}, + #endif + #ifdef SSL_R_INVALID_CONFIGURATION_NAME + {"INVALID_CONFIGURATION_NAME", ERR_LIB_SSL, SSL_R_INVALID_CONFIGURATION_NAME}, + #else + {"INVALID_CONFIGURATION_NAME", 20, 113}, + #endif + #ifdef SSL_R_INVALID_CONTEXT + {"INVALID_CONTEXT", ERR_LIB_SSL, SSL_R_INVALID_CONTEXT}, + #else + {"INVALID_CONTEXT", 20, 282}, + #endif + #ifdef SSL_R_INVALID_CT_VALIDATION_TYPE + {"INVALID_CT_VALIDATION_TYPE", ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE}, + #else + {"INVALID_CT_VALIDATION_TYPE", 20, 212}, + #endif + #ifdef SSL_R_INVALID_KEY_UPDATE_TYPE + {"INVALID_KEY_UPDATE_TYPE", ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE}, + #else + {"INVALID_KEY_UPDATE_TYPE", 20, 120}, + #endif + #ifdef SSL_R_INVALID_MAX_EARLY_DATA + {"INVALID_MAX_EARLY_DATA", ERR_LIB_SSL, SSL_R_INVALID_MAX_EARLY_DATA}, + #else + {"INVALID_MAX_EARLY_DATA", 20, 174}, + #endif + #ifdef SSL_R_INVALID_NULL_CMD_NAME + {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME}, + #else + {"INVALID_NULL_CMD_NAME", 20, 385}, + #endif + #ifdef SSL_R_INVALID_SEQUENCE_NUMBER + {"INVALID_SEQUENCE_NUMBER", ERR_LIB_SSL, SSL_R_INVALID_SEQUENCE_NUMBER}, + #else + {"INVALID_SEQUENCE_NUMBER", 20, 402}, + #endif + #ifdef SSL_R_INVALID_SERVERINFO_DATA + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA}, + #else + {"INVALID_SERVERINFO_DATA", 20, 388}, + #endif + #ifdef SSL_R_INVALID_SESSION_ID + {"INVALID_SESSION_ID", ERR_LIB_SSL, SSL_R_INVALID_SESSION_ID}, + #else + {"INVALID_SESSION_ID", 20, 999}, + #endif + #ifdef SSL_R_INVALID_SRP_USERNAME + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME}, + #else + {"INVALID_SRP_USERNAME", 20, 357}, + #endif + #ifdef SSL_R_INVALID_STATUS_RESPONSE + {"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE}, + #else + {"INVALID_STATUS_RESPONSE", 20, 328}, + #endif + #ifdef SSL_R_INVALID_TICKET_KEYS_LENGTH + {"INVALID_TICKET_KEYS_LENGTH", ERR_LIB_SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH}, + #else + {"INVALID_TICKET_KEYS_LENGTH", 20, 325}, + #endif + #ifdef SSL_R_LENGTH_MISMATCH + {"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH}, + #else + {"LENGTH_MISMATCH", 20, 159}, + #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 + {"LENGTH_TOO_SHORT", 20, 160}, + #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 + {"LIBRARY_HAS_NO_CIPHERS", 20, 161}, + #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_ECDSA_SIGNING_CERT + {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDSA_SIGNING_CERT}, + #else + {"MISSING_ECDSA_SIGNING_CERT", 20, 381}, + #endif + #ifdef SSL_R_MISSING_FATAL + {"MISSING_FATAL", ERR_LIB_SSL, SSL_R_MISSING_FATAL}, + #else + {"MISSING_FATAL", 20, 256}, + #endif + #ifdef SSL_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 20, 290}, + #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 + {"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 + {"MISSING_RSA_SIGNING_CERT", 20, 170}, + #endif + #ifdef SSL_R_MISSING_SIGALGS_EXTENSION + {"MISSING_SIGALGS_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_SIGALGS_EXTENSION}, + #else + {"MISSING_SIGALGS_EXTENSION", 20, 112}, + #endif + #ifdef SSL_R_MISSING_SIGNING_CERT + {"MISSING_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_SIGNING_CERT}, + #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 + {"MISSING_SRP_PARAM", 20, 358}, + #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 + {"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 + {"MISSING_TMP_ECDH_KEY", 20, 311}, + #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 + {"MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA", 20, 293}, + #endif + #ifdef SSL_R_NOT_ON_RECORD_BOUNDARY + {"NOT_ON_RECORD_BOUNDARY", ERR_LIB_SSL, SSL_R_NOT_ON_RECORD_BOUNDARY}, + #else + {"NOT_ON_RECORD_BOUNDARY", 20, 182}, + #endif + #ifdef SSL_R_NOT_REPLACING_CERTIFICATE + {"NOT_REPLACING_CERTIFICATE", ERR_LIB_SSL, SSL_R_NOT_REPLACING_CERTIFICATE}, + #else + {"NOT_REPLACING_CERTIFICATE", 20, 289}, + #endif + #ifdef SSL_R_NOT_SERVER + {"NOT_SERVER", ERR_LIB_SSL, SSL_R_NOT_SERVER}, + #else + {"NOT_SERVER", 20, 284}, + #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 + {"NO_CERTIFICATES_RETURNED", 20, 176}, + #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 + {"NO_CERTIFICATE_SET", 20, 179}, + #endif + #ifdef SSL_R_NO_CHANGE_FOLLOWING_HRR + {"NO_CHANGE_FOLLOWING_HRR", ERR_LIB_SSL, SSL_R_NO_CHANGE_FOLLOWING_HRR}, + #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 + {"NO_CIPHERS_AVAILABLE", 20, 181}, + #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 + {"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 + {"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 + {"NO_COMPRESSION_SPECIFIED", 20, 187}, + #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 + {"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 + {"NO_METHOD_SPECIFIED", 20, 188}, + #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 + {"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 + {"NO_PROTOCOLS_AVAILABLE", 20, 191}, + #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 + {"NO_REQUIRED_DIGEST", 20, 324}, + #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 + #ifdef SSL_R_NO_SHARED_GROUPS + {"NO_SHARED_GROUPS", ERR_LIB_SSL, SSL_R_NO_SHARED_GROUPS}, + #else + {"NO_SHARED_GROUPS", 20, 410}, + #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 + {"NO_SRTP_PROFILES", 20, 359}, + #endif + #ifdef SSL_R_NO_SUITABLE_KEY_SHARE + {"NO_SUITABLE_KEY_SHARE", ERR_LIB_SSL, SSL_R_NO_SUITABLE_KEY_SHARE}, + #else + {"NO_SUITABLE_KEY_SHARE", 20, 101}, + #endif + #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM + {"NO_SUITABLE_SIGNATURE_ALGORITHM", ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM}, + #else + {"NO_SUITABLE_SIGNATURE_ALGORITHM", 20, 118}, + #endif + #ifdef SSL_R_NO_VALID_SCTS + {"NO_VALID_SCTS", ERR_LIB_SSL, SSL_R_NO_VALID_SCTS}, + #else + {"NO_VALID_SCTS", 20, 216}, + #endif + #ifdef SSL_R_NO_VERIFY_COOKIE_CALLBACK + {"NO_VERIFY_COOKIE_CALLBACK", ERR_LIB_SSL, SSL_R_NO_VERIFY_COOKIE_CALLBACK}, + #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 + {"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 + {"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 + {"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 + {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", 20, 344}, + #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 + {"PACKET_LENGTH_TOO_LONG", 20, 198}, + #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 + {"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 + {"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 + {"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 + {"PEM_NAME_TOO_SHORT", 20, 392}, + #endif + #ifdef SSL_R_PIPELINE_FAILURE + {"PIPELINE_FAILURE", ERR_LIB_SSL, SSL_R_PIPELINE_FAILURE}, + #else + {"PIPELINE_FAILURE", 20, 406}, + #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 + {"POST_HANDSHAKE_AUTH_ENCODING_ERR", 20, 278}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"READ_TIMEOUT_EXPIRED", 20, 312}, + #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 + {"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 + {"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 + {"RENEGOTIATION_ENCODING_ERR", 20, 336}, + #endif + #ifdef SSL_R_RENEGOTIATION_MISMATCH + {"RENEGOTIATION_MISMATCH", ERR_LIB_SSL, SSL_R_RENEGOTIATION_MISMATCH}, + #else + {"RENEGOTIATION_MISMATCH", 20, 337}, + #endif + #ifdef SSL_R_REQUEST_PENDING + {"REQUEST_PENDING", ERR_LIB_SSL, SSL_R_REQUEST_PENDING}, + #else + {"REQUEST_PENDING", 20, 285}, + #endif + #ifdef SSL_R_REQUEST_SENT + {"REQUEST_SENT", ERR_LIB_SSL, SSL_R_REQUEST_SENT}, + #else + {"REQUEST_SENT", 20, 286}, + #endif + #ifdef SSL_R_REQUIRED_CIPHER_MISSING + {"REQUIRED_CIPHER_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_CIPHER_MISSING}, + #else + {"REQUIRED_CIPHER_MISSING", 20, 215}, + #endif + #ifdef SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING + {"REQUIRED_COMPRESSION_ALGORITHM_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING}, + #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 + {"SCSV_RECEIVED_WHEN_RENEGOTIATING", 20, 345}, + #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 + {"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 + {"SESSION_ID_CONTEXT_UNINITIALIZED", 20, 277}, + #endif + #ifdef SSL_R_SHUTDOWN_WHILE_IN_INIT + {"SHUTDOWN_WHILE_IN_INIT", ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"SRTP_UNKNOWN_PROTECTION_PROFILE", 20, 364}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", 20, 1043}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 20, 117}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #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 + {"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 + {"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 + {"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 + {"SSL_NEGATIVE_LENGTH", 20, 372}, + #endif + #ifdef SSL_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 20, 126}, + #endif + #ifdef SSL_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_SECTION_NOT_FOUND}, + #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 + {"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 + {"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 + {"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 + {"SSL_SESSION_ID_HAS_BAD_LENGTH", 20, 303}, + #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 + {"SSL_SESSION_ID_TOO_LONG", 20, 408}, + #endif + #ifdef SSL_R_SSL_SESSION_VERSION_MISMATCH + {"SSL_SESSION_VERSION_MISMATCH", ERR_LIB_SSL, SSL_R_SSL_SESSION_VERSION_MISMATCH}, + #else + {"SSL_SESSION_VERSION_MISMATCH", 20, 210}, + #endif + #ifdef SSL_R_STILL_IN_INIT + {"STILL_IN_INIT", ERR_LIB_SSL, SSL_R_STILL_IN_INIT}, + #else + {"STILL_IN_INIT", 20, 121}, + #endif + #ifdef SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED}, + #else + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", 20, 1116}, + #endif + #ifdef SSL_R_TLSV13_ALERT_MISSING_EXTENSION + {"TLSV13_ALERT_MISSING_EXTENSION", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_MISSING_EXTENSION}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"TLSV1_CERTIFICATE_UNOBTAINABLE", 20, 1111}, + #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 + {"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 + {"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 + {"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 + {"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 + {"TLS_INVALID_ECPOINTFORMAT_LIST", 20, 157}, + #endif + #ifdef SSL_R_TOO_MANY_KEY_UPDATES + {"TOO_MANY_KEY_UPDATES", ERR_LIB_SSL, SSL_R_TOO_MANY_KEY_UPDATES}, + #else + {"TOO_MANY_KEY_UPDATES", 20, 132}, + #endif + #ifdef SSL_R_TOO_MANY_WARN_ALERTS + {"TOO_MANY_WARN_ALERTS", ERR_LIB_SSL, SSL_R_TOO_MANY_WARN_ALERTS}, + #else + {"TOO_MANY_WARN_ALERTS", 20, 409}, + #endif + #ifdef SSL_R_TOO_MUCH_EARLY_DATA + {"TOO_MUCH_EARLY_DATA", ERR_LIB_SSL, SSL_R_TOO_MUCH_EARLY_DATA}, + #else + {"TOO_MUCH_EARLY_DATA", 20, 164}, + #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 + {"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 + {"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 + {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", 20, 243}, + #endif + #ifdef SSL_R_UNEXPECTED_CCS_MESSAGE + {"UNEXPECTED_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_CCS_MESSAGE}, + #else + {"UNEXPECTED_CCS_MESSAGE", 20, 262}, + #endif + #ifdef SSL_R_UNEXPECTED_END_OF_EARLY_DATA + {"UNEXPECTED_END_OF_EARLY_DATA", ERR_LIB_SSL, SSL_R_UNEXPECTED_END_OF_EARLY_DATA}, + #else + {"UNEXPECTED_END_OF_EARLY_DATA", 20, 178}, + #endif + #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 + {"UNEXPECTED_RECORD", 20, 245}, + #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 + {"UNKNOWN_ALERT_TYPE", 20, 246}, + #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 + {"UNKNOWN_CIPHER_RETURNED", 20, 248}, + #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 + {"UNKNOWN_CMD_NAME", 20, 386}, + #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 + {"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 + {"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 + {"UNKNOWN_PKEY_TYPE", 20, 251}, + #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 + {"UNKNOWN_SSL_VERSION", 20, 254}, + #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 + {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", 20, 338}, + #endif + #ifdef SSL_R_UNSOLICITED_EXTENSION + {"UNSOLICITED_EXTENSION", ERR_LIB_SSL, SSL_R_UNSOLICITED_EXTENSION}, + #else + {"UNSOLICITED_EXTENSION", 20, 217}, + #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_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 + {"UNSUPPORTED_PROTOCOL", 20, 258}, + #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 + {"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 + {"USE_SRTP_NOT_NEGOTIATED", 20, 369}, + #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 + {"VERSION_TOO_LOW", 20, 396}, + #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 + {"WRONG_CIPHER_RETURNED", 20, 261}, + #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 + {"WRONG_SIGNATURE_LENGTH", 20, 264}, + #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 + {"WRONG_SIGNATURE_TYPE", 20, 370}, + #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 + {"WRONG_VERSION_NUMBER", 20, 267}, + #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 + {"X509_VERIFICATION_SETUP_PROBLEMS", 20, 269}, + #endif + #ifdef TS_R_BAD_PKCS7_TYPE + {"BAD_PKCS7_TYPE", ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE}, + #else + {"BAD_PKCS7_TYPE", 47, 132}, + #endif + #ifdef TS_R_BAD_TYPE + {"BAD_TYPE", ERR_LIB_TS, TS_R_BAD_TYPE}, + #else + {"BAD_TYPE", 47, 133}, + #endif + #ifdef TS_R_CANNOT_LOAD_CERT + {"CANNOT_LOAD_CERT", ERR_LIB_TS, TS_R_CANNOT_LOAD_CERT}, + #else + {"CANNOT_LOAD_CERT", 47, 137}, + #endif + #ifdef TS_R_CANNOT_LOAD_KEY + {"CANNOT_LOAD_KEY", ERR_LIB_TS, TS_R_CANNOT_LOAD_KEY}, + #else + {"CANNOT_LOAD_KEY", 47, 138}, + #endif + #ifdef TS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_TS, TS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 47, 100}, + #endif + #ifdef TS_R_COULD_NOT_SET_ENGINE + {"COULD_NOT_SET_ENGINE", ERR_LIB_TS, TS_R_COULD_NOT_SET_ENGINE}, + #else + {"COULD_NOT_SET_ENGINE", 47, 127}, + #endif + #ifdef TS_R_COULD_NOT_SET_TIME + {"COULD_NOT_SET_TIME", ERR_LIB_TS, TS_R_COULD_NOT_SET_TIME}, + #else + {"COULD_NOT_SET_TIME", 47, 115}, + #endif + #ifdef TS_R_DETACHED_CONTENT + {"DETACHED_CONTENT", ERR_LIB_TS, TS_R_DETACHED_CONTENT}, + #else + {"DETACHED_CONTENT", 47, 134}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_ERROR + {"ESS_ADD_SIGNING_CERT_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_ERROR", 47, 116}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR + {"ESS_ADD_SIGNING_CERT_V2_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_V2_ERROR", 47, 139}, + #endif + #ifdef TS_R_ESS_SIGNING_CERTIFICATE_ERROR + {"ESS_SIGNING_CERTIFICATE_ERROR", ERR_LIB_TS, TS_R_ESS_SIGNING_CERTIFICATE_ERROR}, + #else + {"ESS_SIGNING_CERTIFICATE_ERROR", 47, 101}, + #endif + #ifdef TS_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_TS, TS_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 47, 102}, + #endif + #ifdef TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE}, + #else + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", 47, 117}, + #endif + #ifdef TS_R_MESSAGE_IMPRINT_MISMATCH + {"MESSAGE_IMPRINT_MISMATCH", ERR_LIB_TS, TS_R_MESSAGE_IMPRINT_MISMATCH}, + #else + {"MESSAGE_IMPRINT_MISMATCH", 47, 103}, + #endif + #ifdef TS_R_NONCE_MISMATCH + {"NONCE_MISMATCH", ERR_LIB_TS, TS_R_NONCE_MISMATCH}, + #else + {"NONCE_MISMATCH", 47, 104}, + #endif + #ifdef TS_R_NONCE_NOT_RETURNED + {"NONCE_NOT_RETURNED", ERR_LIB_TS, TS_R_NONCE_NOT_RETURNED}, + #else + {"NONCE_NOT_RETURNED", 47, 105}, + #endif + #ifdef TS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_TS, TS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 47, 106}, + #endif + #ifdef TS_R_NO_TIME_STAMP_TOKEN + {"NO_TIME_STAMP_TOKEN", ERR_LIB_TS, TS_R_NO_TIME_STAMP_TOKEN}, + #else + {"NO_TIME_STAMP_TOKEN", 47, 107}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 47, 118}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR + {"PKCS7_ADD_SIGNED_ATTR_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR}, + #else + {"PKCS7_ADD_SIGNED_ATTR_ERROR", 47, 119}, + #endif + #ifdef TS_R_PKCS7_TO_TS_TST_INFO_FAILED + {"PKCS7_TO_TS_TST_INFO_FAILED", ERR_LIB_TS, TS_R_PKCS7_TO_TS_TST_INFO_FAILED}, + #else + {"PKCS7_TO_TS_TST_INFO_FAILED", 47, 129}, + #endif + #ifdef TS_R_POLICY_MISMATCH + {"POLICY_MISMATCH", ERR_LIB_TS, TS_R_POLICY_MISMATCH}, + #else + {"POLICY_MISMATCH", 47, 108}, + #endif + #ifdef TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 47, 120}, + #endif + #ifdef TS_R_RESPONSE_SETUP_ERROR + {"RESPONSE_SETUP_ERROR", ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR}, + #else + {"RESPONSE_SETUP_ERROR", 47, 121}, + #endif + #ifdef TS_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_TS, TS_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 47, 109}, + #endif + #ifdef TS_R_THERE_MUST_BE_ONE_SIGNER + {"THERE_MUST_BE_ONE_SIGNER", ERR_LIB_TS, TS_R_THERE_MUST_BE_ONE_SIGNER}, + #else + {"THERE_MUST_BE_ONE_SIGNER", 47, 110}, + #endif + #ifdef TS_R_TIME_SYSCALL_ERROR + {"TIME_SYSCALL_ERROR", ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR}, + #else + {"TIME_SYSCALL_ERROR", 47, 122}, + #endif + #ifdef TS_R_TOKEN_NOT_PRESENT + {"TOKEN_NOT_PRESENT", ERR_LIB_TS, TS_R_TOKEN_NOT_PRESENT}, + #else + {"TOKEN_NOT_PRESENT", 47, 130}, + #endif + #ifdef TS_R_TOKEN_PRESENT + {"TOKEN_PRESENT", ERR_LIB_TS, TS_R_TOKEN_PRESENT}, + #else + {"TOKEN_PRESENT", 47, 131}, + #endif + #ifdef TS_R_TSA_NAME_MISMATCH + {"TSA_NAME_MISMATCH", ERR_LIB_TS, TS_R_TSA_NAME_MISMATCH}, + #else + {"TSA_NAME_MISMATCH", 47, 111}, + #endif + #ifdef TS_R_TSA_UNTRUSTED + {"TSA_UNTRUSTED", ERR_LIB_TS, TS_R_TSA_UNTRUSTED}, + #else + {"TSA_UNTRUSTED", 47, 112}, + #endif + #ifdef TS_R_TST_INFO_SETUP_ERROR + {"TST_INFO_SETUP_ERROR", ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR}, + #else + {"TST_INFO_SETUP_ERROR", 47, 123}, + #endif + #ifdef TS_R_TS_DATASIGN + {"TS_DATASIGN", ERR_LIB_TS, TS_R_TS_DATASIGN}, + #else + {"TS_DATASIGN", 47, 124}, + #endif + #ifdef TS_R_UNACCEPTABLE_POLICY + {"UNACCEPTABLE_POLICY", ERR_LIB_TS, TS_R_UNACCEPTABLE_POLICY}, + #else + {"UNACCEPTABLE_POLICY", 47, 125}, + #endif + #ifdef TS_R_UNSUPPORTED_MD_ALGORITHM + {"UNSUPPORTED_MD_ALGORITHM", ERR_LIB_TS, TS_R_UNSUPPORTED_MD_ALGORITHM}, + #else + {"UNSUPPORTED_MD_ALGORITHM", 47, 126}, + #endif + #ifdef TS_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_TS, TS_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 47, 113}, + #endif + #ifdef TS_R_VAR_BAD_VALUE + {"VAR_BAD_VALUE", ERR_LIB_TS, TS_R_VAR_BAD_VALUE}, + #else + {"VAR_BAD_VALUE", 47, 135}, + #endif + #ifdef TS_R_VAR_LOOKUP_FAILURE + {"VAR_LOOKUP_FAILURE", ERR_LIB_TS, TS_R_VAR_LOOKUP_FAILURE}, + #else + {"VAR_LOOKUP_FAILURE", 47, 136}, + #endif + #ifdef TS_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_TS, TS_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 47, 114}, + #endif + #ifdef UI_R_COMMON_OK_AND_CANCEL_CHARACTERS + {"COMMON_OK_AND_CANCEL_CHARACTERS", ERR_LIB_UI, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS}, + #else + {"COMMON_OK_AND_CANCEL_CHARACTERS", 40, 104}, + #endif + #ifdef UI_R_INDEX_TOO_LARGE + {"INDEX_TOO_LARGE", ERR_LIB_UI, UI_R_INDEX_TOO_LARGE}, + #else + {"INDEX_TOO_LARGE", 40, 102}, + #endif + #ifdef UI_R_INDEX_TOO_SMALL + {"INDEX_TOO_SMALL", ERR_LIB_UI, UI_R_INDEX_TOO_SMALL}, + #else + {"INDEX_TOO_SMALL", 40, 103}, + #endif + #ifdef UI_R_NO_RESULT_BUFFER + {"NO_RESULT_BUFFER", ERR_LIB_UI, UI_R_NO_RESULT_BUFFER}, + #else + {"NO_RESULT_BUFFER", 40, 105}, + #endif + #ifdef UI_R_PROCESSING_ERROR + {"PROCESSING_ERROR", ERR_LIB_UI, UI_R_PROCESSING_ERROR}, + #else + {"PROCESSING_ERROR", 40, 107}, + #endif + #ifdef UI_R_RESULT_TOO_LARGE + {"RESULT_TOO_LARGE", ERR_LIB_UI, UI_R_RESULT_TOO_LARGE}, + #else + {"RESULT_TOO_LARGE", 40, 100}, + #endif + #ifdef UI_R_RESULT_TOO_SMALL + {"RESULT_TOO_SMALL", ERR_LIB_UI, UI_R_RESULT_TOO_SMALL}, + #else + {"RESULT_TOO_SMALL", 40, 101}, + #endif + #ifdef UI_R_SYSASSIGN_ERROR + {"SYSASSIGN_ERROR", ERR_LIB_UI, UI_R_SYSASSIGN_ERROR}, + #else + {"SYSASSIGN_ERROR", 40, 109}, + #endif + #ifdef UI_R_SYSDASSGN_ERROR + {"SYSDASSGN_ERROR", ERR_LIB_UI, UI_R_SYSDASSGN_ERROR}, + #else + {"SYSDASSGN_ERROR", 40, 110}, + #endif + #ifdef UI_R_SYSQIOW_ERROR + {"SYSQIOW_ERROR", ERR_LIB_UI, UI_R_SYSQIOW_ERROR}, + #else + {"SYSQIOW_ERROR", 40, 111}, + #endif + #ifdef UI_R_UNKNOWN_CONTROL_COMMAND + {"UNKNOWN_CONTROL_COMMAND", ERR_LIB_UI, UI_R_UNKNOWN_CONTROL_COMMAND}, + #else + {"UNKNOWN_CONTROL_COMMAND", 40, 106}, + #endif + #ifdef UI_R_UNKNOWN_TTYGET_ERRNO_VALUE + {"UNKNOWN_TTYGET_ERRNO_VALUE", ERR_LIB_UI, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE}, + #else + {"UNKNOWN_TTYGET_ERRNO_VALUE", 40, 108}, + #endif + #ifdef UI_R_USER_DATA_DUPLICATION_UNSUPPORTED + {"USER_DATA_DUPLICATION_UNSUPPORTED", ERR_LIB_UI, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED}, + #else + {"USER_DATA_DUPLICATION_UNSUPPORTED", 40, 112}, + #endif + #ifdef X509V3_R_BAD_IP_ADDRESS + {"BAD_IP_ADDRESS", ERR_LIB_X509V3, X509V3_R_BAD_IP_ADDRESS}, + #else + {"BAD_IP_ADDRESS", 34, 118}, + #endif + #ifdef X509V3_R_BAD_OBJECT + {"BAD_OBJECT", ERR_LIB_X509V3, X509V3_R_BAD_OBJECT}, + #else + {"BAD_OBJECT", 34, 119}, + #endif + #ifdef X509V3_R_BN_DEC2BN_ERROR + {"BN_DEC2BN_ERROR", ERR_LIB_X509V3, X509V3_R_BN_DEC2BN_ERROR}, + #else + {"BN_DEC2BN_ERROR", 34, 100}, + #endif + #ifdef X509V3_R_BN_TO_ASN1_INTEGER_ERROR + {"BN_TO_ASN1_INTEGER_ERROR", ERR_LIB_X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR}, + #else + {"BN_TO_ASN1_INTEGER_ERROR", 34, 101}, + #endif + #ifdef X509V3_R_DIRNAME_ERROR + {"DIRNAME_ERROR", ERR_LIB_X509V3, X509V3_R_DIRNAME_ERROR}, + #else + {"DIRNAME_ERROR", 34, 149}, + #endif + #ifdef X509V3_R_DISTPOINT_ALREADY_SET + {"DISTPOINT_ALREADY_SET", ERR_LIB_X509V3, X509V3_R_DISTPOINT_ALREADY_SET}, + #else + {"DISTPOINT_ALREADY_SET", 34, 160}, + #endif + #ifdef X509V3_R_DUPLICATE_ZONE_ID + {"DUPLICATE_ZONE_ID", ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID}, + #else + {"DUPLICATE_ZONE_ID", 34, 133}, + #endif + #ifdef X509V3_R_ERROR_CONVERTING_ZONE + {"ERROR_CONVERTING_ZONE", ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE}, + #else + {"ERROR_CONVERTING_ZONE", 34, 131}, + #endif + #ifdef X509V3_R_ERROR_CREATING_EXTENSION + {"ERROR_CREATING_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_CREATING_EXTENSION}, + #else + {"ERROR_CREATING_EXTENSION", 34, 144}, + #endif + #ifdef X509V3_R_ERROR_IN_EXTENSION + {"ERROR_IN_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION}, + #else + {"ERROR_IN_EXTENSION", 34, 128}, + #endif + #ifdef X509V3_R_EXPECTED_A_SECTION_NAME + {"EXPECTED_A_SECTION_NAME", ERR_LIB_X509V3, X509V3_R_EXPECTED_A_SECTION_NAME}, + #else + {"EXPECTED_A_SECTION_NAME", 34, 137}, + #endif + #ifdef X509V3_R_EXTENSION_EXISTS + {"EXTENSION_EXISTS", ERR_LIB_X509V3, X509V3_R_EXTENSION_EXISTS}, + #else + {"EXTENSION_EXISTS", 34, 145}, + #endif + #ifdef X509V3_R_EXTENSION_NAME_ERROR + {"EXTENSION_NAME_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR}, + #else + {"EXTENSION_NAME_ERROR", 34, 115}, + #endif + #ifdef X509V3_R_EXTENSION_NOT_FOUND + {"EXTENSION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND}, + #else + {"EXTENSION_NOT_FOUND", 34, 102}, + #endif + #ifdef X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED + {"EXTENSION_SETTING_NOT_SUPPORTED", ERR_LIB_X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED}, + #else + {"EXTENSION_SETTING_NOT_SUPPORTED", 34, 103}, + #endif + #ifdef X509V3_R_EXTENSION_VALUE_ERROR + {"EXTENSION_VALUE_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR}, + #else + {"EXTENSION_VALUE_ERROR", 34, 116}, + #endif + #ifdef X509V3_R_ILLEGAL_EMPTY_EXTENSION + {"ILLEGAL_EMPTY_EXTENSION", ERR_LIB_X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION}, + #else + {"ILLEGAL_EMPTY_EXTENSION", 34, 151}, + #endif + #ifdef X509V3_R_INCORRECT_POLICY_SYNTAX_TAG + {"INCORRECT_POLICY_SYNTAX_TAG", ERR_LIB_X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG}, + #else + {"INCORRECT_POLICY_SYNTAX_TAG", 34, 152}, + #endif + #ifdef X509V3_R_INVALID_ASNUMBER + {"INVALID_ASNUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_ASNUMBER}, + #else + {"INVALID_ASNUMBER", 34, 162}, + #endif + #ifdef X509V3_R_INVALID_ASRANGE + {"INVALID_ASRANGE", ERR_LIB_X509V3, X509V3_R_INVALID_ASRANGE}, + #else + {"INVALID_ASRANGE", 34, 163}, + #endif + #ifdef X509V3_R_INVALID_BOOLEAN_STRING + {"INVALID_BOOLEAN_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_BOOLEAN_STRING}, + #else + {"INVALID_BOOLEAN_STRING", 34, 104}, + #endif + #ifdef X509V3_R_INVALID_EXTENSION_STRING + {"INVALID_EXTENSION_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_EXTENSION_STRING}, + #else + {"INVALID_EXTENSION_STRING", 34, 105}, + #endif + #ifdef X509V3_R_INVALID_INHERITANCE + {"INVALID_INHERITANCE", ERR_LIB_X509V3, X509V3_R_INVALID_INHERITANCE}, + #else + {"INVALID_INHERITANCE", 34, 165}, + #endif + #ifdef X509V3_R_INVALID_IPADDRESS + {"INVALID_IPADDRESS", ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS}, + #else + {"INVALID_IPADDRESS", 34, 166}, + #endif + #ifdef X509V3_R_INVALID_MULTIPLE_RDNS + {"INVALID_MULTIPLE_RDNS", ERR_LIB_X509V3, X509V3_R_INVALID_MULTIPLE_RDNS}, + #else + {"INVALID_MULTIPLE_RDNS", 34, 161}, + #endif + #ifdef X509V3_R_INVALID_NAME + {"INVALID_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_NAME}, + #else + {"INVALID_NAME", 34, 106}, + #endif + #ifdef X509V3_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 34, 107}, + #endif + #ifdef X509V3_R_INVALID_NULL_NAME + {"INVALID_NULL_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_NAME}, + #else + {"INVALID_NULL_NAME", 34, 108}, + #endif + #ifdef X509V3_R_INVALID_NULL_VALUE + {"INVALID_NULL_VALUE", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_VALUE}, + #else + {"INVALID_NULL_VALUE", 34, 109}, + #endif + #ifdef X509V3_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 34, 140}, + #endif + #ifdef X509V3_R_INVALID_NUMBERS + {"INVALID_NUMBERS", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBERS}, + #else + {"INVALID_NUMBERS", 34, 141}, + #endif + #ifdef X509V3_R_INVALID_OBJECT_IDENTIFIER + {"INVALID_OBJECT_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER}, + #else + {"INVALID_OBJECT_IDENTIFIER", 34, 110}, + #endif + #ifdef X509V3_R_INVALID_OPTION + {"INVALID_OPTION", ERR_LIB_X509V3, X509V3_R_INVALID_OPTION}, + #else + {"INVALID_OPTION", 34, 138}, + #endif + #ifdef X509V3_R_INVALID_POLICY_IDENTIFIER + {"INVALID_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER}, + #else + {"INVALID_POLICY_IDENTIFIER", 34, 134}, + #endif + #ifdef X509V3_R_INVALID_PROXY_POLICY_SETTING + {"INVALID_PROXY_POLICY_SETTING", ERR_LIB_X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING}, + #else + {"INVALID_PROXY_POLICY_SETTING", 34, 153}, + #endif + #ifdef X509V3_R_INVALID_PURPOSE + {"INVALID_PURPOSE", ERR_LIB_X509V3, X509V3_R_INVALID_PURPOSE}, + #else + {"INVALID_PURPOSE", 34, 146}, + #endif + #ifdef X509V3_R_INVALID_SAFI + {"INVALID_SAFI", ERR_LIB_X509V3, X509V3_R_INVALID_SAFI}, + #else + {"INVALID_SAFI", 34, 164}, + #endif + #ifdef X509V3_R_INVALID_SECTION + {"INVALID_SECTION", ERR_LIB_X509V3, X509V3_R_INVALID_SECTION}, + #else + {"INVALID_SECTION", 34, 135}, + #endif + #ifdef X509V3_R_INVALID_SYNTAX + {"INVALID_SYNTAX", ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX}, + #else + {"INVALID_SYNTAX", 34, 143}, + #endif + #ifdef X509V3_R_ISSUER_DECODE_ERROR + {"ISSUER_DECODE_ERROR", ERR_LIB_X509V3, X509V3_R_ISSUER_DECODE_ERROR}, + #else + {"ISSUER_DECODE_ERROR", 34, 126}, + #endif + #ifdef X509V3_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_X509V3, X509V3_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 34, 124}, + #endif + #ifdef X509V3_R_NEED_ORGANIZATION_AND_NUMBERS + {"NEED_ORGANIZATION_AND_NUMBERS", ERR_LIB_X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS}, + #else + {"NEED_ORGANIZATION_AND_NUMBERS", 34, 142}, + #endif + #ifdef X509V3_R_NO_CONFIG_DATABASE + {"NO_CONFIG_DATABASE", ERR_LIB_X509V3, X509V3_R_NO_CONFIG_DATABASE}, + #else + {"NO_CONFIG_DATABASE", 34, 136}, + #endif + #ifdef X509V3_R_NO_ISSUER_CERTIFICATE + {"NO_ISSUER_CERTIFICATE", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE}, + #else + {"NO_ISSUER_CERTIFICATE", 34, 121}, + #endif + #ifdef X509V3_R_NO_ISSUER_DETAILS + {"NO_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_DETAILS}, + #else + {"NO_ISSUER_DETAILS", 34, 127}, + #endif + #ifdef X509V3_R_NO_POLICY_IDENTIFIER + {"NO_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_NO_POLICY_IDENTIFIER}, + #else + {"NO_POLICY_IDENTIFIER", 34, 139}, + #endif + #ifdef X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", ERR_LIB_X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED}, + #else + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", 34, 154}, + #endif + #ifdef X509V3_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 34, 114}, + #endif + #ifdef X509V3_R_NO_SUBJECT_DETAILS + {"NO_SUBJECT_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS}, + #else + {"NO_SUBJECT_DETAILS", 34, 125}, + #endif + #ifdef X509V3_R_OPERATION_NOT_DEFINED + {"OPERATION_NOT_DEFINED", ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED}, + #else + {"OPERATION_NOT_DEFINED", 34, 148}, + #endif + #ifdef X509V3_R_OTHERNAME_ERROR + {"OTHERNAME_ERROR", ERR_LIB_X509V3, X509V3_R_OTHERNAME_ERROR}, + #else + {"OTHERNAME_ERROR", 34, 147}, + #endif + #ifdef X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED + {"POLICY_LANGUAGE_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED}, + #else + {"POLICY_LANGUAGE_ALREADY_DEFINED", 34, 155}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH + {"POLICY_PATH_LENGTH", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH}, + #else + {"POLICY_PATH_LENGTH", 34, 156}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED}, + #else + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", 34, 157}, + #endif + #ifdef X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", ERR_LIB_X509V3, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY}, + #else + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", 34, 159}, + #endif + #ifdef X509V3_R_SECTION_NOT_FOUND + {"SECTION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND}, + #else + {"SECTION_NOT_FOUND", 34, 150}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS + {"UNABLE_TO_GET_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS}, + #else + {"UNABLE_TO_GET_ISSUER_DETAILS", 34, 122}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_KEYID + {"UNABLE_TO_GET_ISSUER_KEYID", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID}, + #else + {"UNABLE_TO_GET_ISSUER_KEYID", 34, 123}, + #endif + #ifdef X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT + {"UNKNOWN_BIT_STRING_ARGUMENT", ERR_LIB_X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT}, + #else + {"UNKNOWN_BIT_STRING_ARGUMENT", 34, 111}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION + {"UNKNOWN_EXTENSION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION}, + #else + {"UNKNOWN_EXTENSION", 34, 129}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION_NAME + {"UNKNOWN_EXTENSION_NAME", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME}, + #else + {"UNKNOWN_EXTENSION_NAME", 34, 130}, + #endif + #ifdef X509V3_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 34, 120}, + #endif + #ifdef X509V3_R_UNSUPPORTED_OPTION + {"UNSUPPORTED_OPTION", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_OPTION}, + #else + {"UNSUPPORTED_OPTION", 34, 117}, + #endif + #ifdef X509V3_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 34, 167}, + #endif + #ifdef X509V3_R_USER_TOO_LONG + {"USER_TOO_LONG", ERR_LIB_X509V3, X509V3_R_USER_TOO_LONG}, + #else + {"USER_TOO_LONG", 34, 132}, + #endif + #ifdef X509_R_AKID_MISMATCH + {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, + #else + {"AKID_MISMATCH", 11, 110}, + #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 + {"BAD_X509_FILETYPE", 11, 100}, + #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 + {"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 + {"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 + {"CRL_ALREADY_DELTA", 11, 127}, + #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_IDP_MISMATCH + {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, + #else + {"IDP_MISMATCH", 11, 128}, + #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 + {"INVALID_DIRECTORY", 11, 113}, + #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 + {"INVALID_TRUST", 11, 123}, + #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 + {"KEY_TYPE_MISMATCH", 11, 115}, + #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 + {"LOADING_CERT_DIR", 11, 103}, + #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 + {"METHOD_NOT_SUPPORTED", 11, 124}, + #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 + {"NEWER_CRL_NOT_NEWER", 11, 132}, + #endif + #ifdef X509_R_NO_CERTIFICATE_FOUND + {"NO_CERTIFICATE_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND}, + #else + {"NO_CERTIFICATE_FOUND", 11, 135}, + #endif + #ifdef X509_R_NO_CERTIFICATE_OR_CRL_FOUND + {"NO_CERTIFICATE_OR_CRL_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND}, + #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 + {"NO_CERT_SET_FOR_US_TO_VERIFY", 11, 105}, + #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 + {"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 + {"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 + {"PUBLIC_KEY_ENCODE_ERROR", 11, 126}, + #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 + {"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 + {"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 + {"UNKNOWN_KEY_TYPE", 11, 117}, + #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 + {"UNKNOWN_PURPOSE_ID", 11, 121}, + #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 + {"UNSUPPORTED_ALGORITHM", 11, 111}, + #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 + {"WRONG_TYPE", 11, 122}, + #endif + { NULL } +}; + diff --git a/python/Modules/_ssl_data_300.h b/python/Modules/_ssl_data_300.h new file mode 100755 index 0000000..6be8b24 --- /dev/null +++ b/python/Modules/_ssl_data_300.h @@ -0,0 +1,8435 @@ +/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2021-04-09T09:44:43.288448 */ +static struct py_ssl_library_code library_codes[] = { +#ifdef ERR_LIB_ASN1 + {"ASN1", ERR_LIB_ASN1}, +#endif +#ifdef ERR_LIB_ASYNC + {"ASYNC", ERR_LIB_ASYNC}, +#endif +#ifdef ERR_LIB_BIO + {"BIO", ERR_LIB_BIO}, +#endif +#ifdef ERR_LIB_BN + {"BN", ERR_LIB_BN}, +#endif +#ifdef ERR_LIB_BUF + {"BUF", ERR_LIB_BUF}, +#endif +#ifdef ERR_LIB_CMP + {"CMP", ERR_LIB_CMP}, +#endif +#ifdef ERR_LIB_CMS + {"CMS", ERR_LIB_CMS}, +#endif +#ifdef ERR_LIB_COMP + {"COMP", ERR_LIB_COMP}, +#endif +#ifdef ERR_LIB_CONF + {"CONF", ERR_LIB_CONF}, +#endif +#ifdef ERR_LIB_CRMF + {"CRMF", ERR_LIB_CRMF}, +#endif +#ifdef ERR_LIB_CRYPTO + {"CRYPTO", ERR_LIB_CRYPTO}, +#endif +#ifdef ERR_LIB_CT + {"CT", ERR_LIB_CT}, +#endif +#ifdef ERR_LIB_DH + {"DH", ERR_LIB_DH}, +#endif +#ifdef ERR_LIB_DSA + {"DSA", ERR_LIB_DSA}, +#endif +#ifdef ERR_LIB_DSO + {"DSO", ERR_LIB_DSO}, +#endif +#ifdef ERR_LIB_EC + {"EC", ERR_LIB_EC}, +#endif +#ifdef ERR_LIB_ECDH + {"ECDH", ERR_LIB_ECDH}, +#endif +#ifdef ERR_LIB_ECDSA + {"ECDSA", ERR_LIB_ECDSA}, +#endif +#ifdef ERR_LIB_ENGINE + {"ENGINE", ERR_LIB_ENGINE}, +#endif +#ifdef ERR_LIB_ESS + {"ESS", ERR_LIB_ESS}, +#endif +#ifdef ERR_LIB_EVP + {"EVP", ERR_LIB_EVP}, +#endif +#ifdef ERR_LIB_FIPS + {"FIPS", ERR_LIB_FIPS}, +#endif +#ifdef ERR_LIB_HMAC + {"HMAC", ERR_LIB_HMAC}, +#endif +#ifdef ERR_LIB_HTTP + {"HTTP", ERR_LIB_HTTP}, +#endif +#ifdef ERR_LIB_JPAKE + {"JPAKE", ERR_LIB_JPAKE}, +#endif +#ifdef ERR_LIB_KDF + {"KDF", ERR_LIB_KDF}, +#endif +#ifdef ERR_LIB_MASK + {"MASK", ERR_LIB_MASK}, +#endif +#ifdef ERR_LIB_METH + {"METH", ERR_LIB_METH}, +#endif +#ifdef ERR_LIB_NONE + {"NONE", ERR_LIB_NONE}, +#endif +#ifdef ERR_LIB_OBJ + {"OBJ", ERR_LIB_OBJ}, +#endif +#ifdef ERR_LIB_OCSP + {"OCSP", ERR_LIB_OCSP}, +#endif +#ifdef ERR_LIB_OFFSET + {"OFFSET", ERR_LIB_OFFSET}, +#endif +#ifdef ERR_LIB_OSSL_DECODER + {"OSSL_DECODER", ERR_LIB_OSSL_DECODER}, +#endif +#ifdef ERR_LIB_OSSL_ENCODER + {"OSSL_ENCODER", ERR_LIB_OSSL_ENCODER}, +#endif +#ifdef ERR_LIB_OSSL_STORE + {"OSSL_STORE", ERR_LIB_OSSL_STORE}, +#endif +#ifdef ERR_LIB_PEM + {"PEM", ERR_LIB_PEM}, +#endif +#ifdef ERR_LIB_PKCS12 + {"PKCS12", ERR_LIB_PKCS12}, +#endif +#ifdef ERR_LIB_PKCS7 + {"PKCS7", ERR_LIB_PKCS7}, +#endif +#ifdef ERR_LIB_PROP + {"PROP", ERR_LIB_PROP}, +#endif +#ifdef ERR_LIB_PROV + {"PROV", ERR_LIB_PROV}, +#endif +#ifdef ERR_LIB_PROXY + {"PROXY", ERR_LIB_PROXY}, +#endif +#ifdef ERR_LIB_RAND + {"RAND", ERR_LIB_RAND}, +#endif +#ifdef ERR_LIB_RSA + {"RSA", ERR_LIB_RSA}, +#endif +#ifdef ERR_LIB_RSAREF + {"RSAREF", ERR_LIB_RSAREF}, +#endif +#ifdef ERR_LIB_SM2 + {"SM2", ERR_LIB_SM2}, +#endif +#ifdef ERR_LIB_SSL + {"SSL", ERR_LIB_SSL}, +#endif +#ifdef ERR_LIB_SSL2 + {"SSL2", ERR_LIB_SSL2}, +#endif +#ifdef ERR_LIB_SSL23 + {"SSL23", ERR_LIB_SSL23}, +#endif +#ifdef ERR_LIB_SSL3 + {"SSL3", ERR_LIB_SSL3}, +#endif +#ifdef ERR_LIB_SYS + {"SYS", ERR_LIB_SYS}, +#endif +#ifdef ERR_LIB_TS + {"TS", ERR_LIB_TS}, +#endif +#ifdef ERR_LIB_UI + {"UI", ERR_LIB_UI}, +#endif +#ifdef ERR_LIB_USER + {"USER", ERR_LIB_USER}, +#endif +#ifdef 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[] = { + #ifdef ASN1_R_ADDING_OBJECT + {"ADDING_OBJECT", ERR_LIB_ASN1, ASN1_R_ADDING_OBJECT}, + #else + {"ADDING_OBJECT", 13, 171}, + #endif + #ifdef ASN1_R_ASN1_PARSE_ERROR + {"ASN1_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_PARSE_ERROR}, + #else + {"ASN1_PARSE_ERROR", 13, 203}, + #endif + #ifdef ASN1_R_ASN1_SIG_PARSE_ERROR + {"ASN1_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR}, + #else + {"ASN1_SIG_PARSE_ERROR", 13, 204}, + #endif + #ifdef ASN1_R_AUX_ERROR + {"AUX_ERROR", ERR_LIB_ASN1, ASN1_R_AUX_ERROR}, + #else + {"AUX_ERROR", 13, 100}, + #endif + #ifdef ASN1_R_BAD_OBJECT_HEADER + {"BAD_OBJECT_HEADER", ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER}, + #else + {"BAD_OBJECT_HEADER", 13, 102}, + #endif + #ifdef ASN1_R_BAD_TEMPLATE + {"BAD_TEMPLATE", ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE}, + #else + {"BAD_TEMPLATE", 13, 230}, + #endif + #ifdef ASN1_R_BMPSTRING_IS_WRONG_LENGTH + {"BMPSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH}, + #else + {"BMPSTRING_IS_WRONG_LENGTH", 13, 214}, + #endif + #ifdef ASN1_R_BN_LIB + {"BN_LIB", ERR_LIB_ASN1, ASN1_R_BN_LIB}, + #else + {"BN_LIB", 13, 105}, + #endif + #ifdef ASN1_R_BOOLEAN_IS_WRONG_LENGTH + {"BOOLEAN_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH}, + #else + {"BOOLEAN_IS_WRONG_LENGTH", 13, 106}, + #endif + #ifdef ASN1_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_ASN1, ASN1_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 13, 107}, + #endif + #ifdef ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 13, 108}, + #endif + #ifdef ASN1_R_CONTEXT_NOT_INITIALISED + {"CONTEXT_NOT_INITIALISED", ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED}, + #else + {"CONTEXT_NOT_INITIALISED", 13, 217}, + #endif + #ifdef ASN1_R_DATA_IS_WRONG + {"DATA_IS_WRONG", ERR_LIB_ASN1, ASN1_R_DATA_IS_WRONG}, + #else + {"DATA_IS_WRONG", 13, 109}, + #endif + #ifdef ASN1_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 13, 110}, + #endif + #ifdef ASN1_R_DEPTH_EXCEEDED + {"DEPTH_EXCEEDED", ERR_LIB_ASN1, ASN1_R_DEPTH_EXCEEDED}, + #else + {"DEPTH_EXCEEDED", 13, 174}, + #endif + #ifdef ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED}, + #else + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", 13, 198}, + #endif + #ifdef ASN1_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_ASN1, ASN1_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 13, 112}, + #endif + #ifdef ASN1_R_ERROR_GETTING_TIME + {"ERROR_GETTING_TIME", ERR_LIB_ASN1, ASN1_R_ERROR_GETTING_TIME}, + #else + {"ERROR_GETTING_TIME", 13, 173}, + #endif + #ifdef ASN1_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_ASN1, ASN1_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 13, 172}, + #endif + #ifdef ASN1_R_ERROR_SETTING_CIPHER_PARAMS + {"ERROR_SETTING_CIPHER_PARAMS", ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS}, + #else + {"ERROR_SETTING_CIPHER_PARAMS", 13, 114}, + #endif + #ifdef ASN1_R_EXPECTING_AN_INTEGER + {"EXPECTING_AN_INTEGER", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_INTEGER}, + #else + {"EXPECTING_AN_INTEGER", 13, 115}, + #endif + #ifdef ASN1_R_EXPECTING_AN_OBJECT + {"EXPECTING_AN_OBJECT", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_OBJECT}, + #else + {"EXPECTING_AN_OBJECT", 13, 116}, + #endif + #ifdef ASN1_R_EXPLICIT_LENGTH_MISMATCH + {"EXPLICIT_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH}, + #else + {"EXPLICIT_LENGTH_MISMATCH", 13, 119}, + #endif + #ifdef ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED + {"EXPLICIT_TAG_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED}, + #else + {"EXPLICIT_TAG_NOT_CONSTRUCTED", 13, 120}, + #endif + #ifdef ASN1_R_FIELD_MISSING + {"FIELD_MISSING", ERR_LIB_ASN1, ASN1_R_FIELD_MISSING}, + #else + {"FIELD_MISSING", 13, 121}, + #endif + #ifdef ASN1_R_FIRST_NUM_TOO_LARGE + {"FIRST_NUM_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_FIRST_NUM_TOO_LARGE}, + #else + {"FIRST_NUM_TOO_LARGE", 13, 122}, + #endif + #ifdef ASN1_R_HEADER_TOO_LONG + {"HEADER_TOO_LONG", ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}, + #else + {"HEADER_TOO_LONG", 13, 123}, + #endif + #ifdef ASN1_R_ILLEGAL_BITSTRING_FORMAT + {"ILLEGAL_BITSTRING_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT}, + #else + {"ILLEGAL_BITSTRING_FORMAT", 13, 175}, + #endif + #ifdef ASN1_R_ILLEGAL_BOOLEAN + {"ILLEGAL_BOOLEAN", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BOOLEAN}, + #else + {"ILLEGAL_BOOLEAN", 13, 176}, + #endif + #ifdef ASN1_R_ILLEGAL_CHARACTERS + {"ILLEGAL_CHARACTERS", ERR_LIB_ASN1, ASN1_R_ILLEGAL_CHARACTERS}, + #else + {"ILLEGAL_CHARACTERS", 13, 124}, + #endif + #ifdef ASN1_R_ILLEGAL_FORMAT + {"ILLEGAL_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_FORMAT}, + #else + {"ILLEGAL_FORMAT", 13, 177}, + #endif + #ifdef ASN1_R_ILLEGAL_HEX + {"ILLEGAL_HEX", ERR_LIB_ASN1, ASN1_R_ILLEGAL_HEX}, + #else + {"ILLEGAL_HEX", 13, 178}, + #endif + #ifdef ASN1_R_ILLEGAL_IMPLICIT_TAG + {"ILLEGAL_IMPLICIT_TAG", ERR_LIB_ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG}, + #else + {"ILLEGAL_IMPLICIT_TAG", 13, 179}, + #endif + #ifdef ASN1_R_ILLEGAL_INTEGER + {"ILLEGAL_INTEGER", ERR_LIB_ASN1, ASN1_R_ILLEGAL_INTEGER}, + #else + {"ILLEGAL_INTEGER", 13, 180}, + #endif + #ifdef ASN1_R_ILLEGAL_NEGATIVE_VALUE + {"ILLEGAL_NEGATIVE_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE}, + #else + {"ILLEGAL_NEGATIVE_VALUE", 13, 226}, + #endif + #ifdef ASN1_R_ILLEGAL_NESTED_TAGGING + {"ILLEGAL_NESTED_TAGGING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING}, + #else + {"ILLEGAL_NESTED_TAGGING", 13, 181}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL + {"ILLEGAL_NULL", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL}, + #else + {"ILLEGAL_NULL", 13, 125}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL_VALUE + {"ILLEGAL_NULL_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL_VALUE}, + #else + {"ILLEGAL_NULL_VALUE", 13, 182}, + #endif + #ifdef ASN1_R_ILLEGAL_OBJECT + {"ILLEGAL_OBJECT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT}, + #else + {"ILLEGAL_OBJECT", 13, 183}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONAL_ANY + {"ILLEGAL_OPTIONAL_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY}, + #else + {"ILLEGAL_OPTIONAL_ANY", 13, 126}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE}, + #else + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", 13, 170}, + #endif + #ifdef ASN1_R_ILLEGAL_PADDING + {"ILLEGAL_PADDING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_PADDING}, + #else + {"ILLEGAL_PADDING", 13, 221}, + #endif + #ifdef ASN1_R_ILLEGAL_TAGGED_ANY + {"ILLEGAL_TAGGED_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TAGGED_ANY}, + #else + {"ILLEGAL_TAGGED_ANY", 13, 127}, + #endif + #ifdef ASN1_R_ILLEGAL_TIME_VALUE + {"ILLEGAL_TIME_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TIME_VALUE}, + #else + {"ILLEGAL_TIME_VALUE", 13, 184}, + #endif + #ifdef ASN1_R_ILLEGAL_ZERO_CONTENT + {"ILLEGAL_ZERO_CONTENT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT}, + #else + {"ILLEGAL_ZERO_CONTENT", 13, 222}, + #endif + #ifdef ASN1_R_INTEGER_NOT_ASCII_FORMAT + {"INTEGER_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT}, + #else + {"INTEGER_NOT_ASCII_FORMAT", 13, 185}, + #endif + #ifdef ASN1_R_INTEGER_TOO_LARGE_FOR_LONG + {"INTEGER_TOO_LARGE_FOR_LONG", ERR_LIB_ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG}, + #else + {"INTEGER_TOO_LARGE_FOR_LONG", 13, 128}, + #endif + #ifdef ASN1_R_INVALID_BIT_STRING_BITS_LEFT + {"INVALID_BIT_STRING_BITS_LEFT", ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}, + #else + {"INVALID_BIT_STRING_BITS_LEFT", 13, 220}, + #endif + #ifdef ASN1_R_INVALID_BMPSTRING_LENGTH + {"INVALID_BMPSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH}, + #else + {"INVALID_BMPSTRING_LENGTH", 13, 129}, + #endif + #ifdef ASN1_R_INVALID_DIGIT + {"INVALID_DIGIT", ERR_LIB_ASN1, ASN1_R_INVALID_DIGIT}, + #else + {"INVALID_DIGIT", 13, 130}, + #endif + #ifdef ASN1_R_INVALID_MIME_TYPE + {"INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_INVALID_MIME_TYPE}, + #else + {"INVALID_MIME_TYPE", 13, 205}, + #endif + #ifdef ASN1_R_INVALID_MODIFIER + {"INVALID_MODIFIER", ERR_LIB_ASN1, ASN1_R_INVALID_MODIFIER}, + #else + {"INVALID_MODIFIER", 13, 186}, + #endif + #ifdef ASN1_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 13, 187}, + #endif + #ifdef ASN1_R_INVALID_OBJECT_ENCODING + {"INVALID_OBJECT_ENCODING", ERR_LIB_ASN1, ASN1_R_INVALID_OBJECT_ENCODING}, + #else + {"INVALID_OBJECT_ENCODING", 13, 216}, + #endif + #ifdef ASN1_R_INVALID_SCRYPT_PARAMETERS + {"INVALID_SCRYPT_PARAMETERS", ERR_LIB_ASN1, ASN1_R_INVALID_SCRYPT_PARAMETERS}, + #else + {"INVALID_SCRYPT_PARAMETERS", 13, 227}, + #endif + #ifdef ASN1_R_INVALID_SEPARATOR + {"INVALID_SEPARATOR", ERR_LIB_ASN1, ASN1_R_INVALID_SEPARATOR}, + #else + {"INVALID_SEPARATOR", 13, 131}, + #endif + #ifdef ASN1_R_INVALID_STRING_TABLE_VALUE + {"INVALID_STRING_TABLE_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE}, + #else + {"INVALID_STRING_TABLE_VALUE", 13, 218}, + #endif + #ifdef ASN1_R_INVALID_UNIVERSALSTRING_LENGTH + {"INVALID_UNIVERSALSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH}, + #else + {"INVALID_UNIVERSALSTRING_LENGTH", 13, 133}, + #endif + #ifdef ASN1_R_INVALID_UTF8STRING + {"INVALID_UTF8STRING", ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING}, + #else + {"INVALID_UTF8STRING", 13, 134}, + #endif + #ifdef ASN1_R_INVALID_VALUE + {"INVALID_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_VALUE}, + #else + {"INVALID_VALUE", 13, 219}, + #endif + #ifdef ASN1_R_LENGTH_TOO_LONG + {"LENGTH_TOO_LONG", ERR_LIB_ASN1, ASN1_R_LENGTH_TOO_LONG}, + #else + {"LENGTH_TOO_LONG", 13, 231}, + #endif + #ifdef ASN1_R_LIST_ERROR + {"LIST_ERROR", ERR_LIB_ASN1, ASN1_R_LIST_ERROR}, + #else + {"LIST_ERROR", 13, 188}, + #endif + #ifdef ASN1_R_MIME_NO_CONTENT_TYPE + {"MIME_NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_MIME_NO_CONTENT_TYPE}, + #else + {"MIME_NO_CONTENT_TYPE", 13, 206}, + #endif + #ifdef ASN1_R_MIME_PARSE_ERROR + {"MIME_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_PARSE_ERROR}, + #else + {"MIME_PARSE_ERROR", 13, 207}, + #endif + #ifdef ASN1_R_MIME_SIG_PARSE_ERROR + {"MIME_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR}, + #else + {"MIME_SIG_PARSE_ERROR", 13, 208}, + #endif + #ifdef ASN1_R_MISSING_EOC + {"MISSING_EOC", ERR_LIB_ASN1, ASN1_R_MISSING_EOC}, + #else + {"MISSING_EOC", 13, 137}, + #endif + #ifdef ASN1_R_MISSING_SECOND_NUMBER + {"MISSING_SECOND_NUMBER", ERR_LIB_ASN1, ASN1_R_MISSING_SECOND_NUMBER}, + #else + {"MISSING_SECOND_NUMBER", 13, 138}, + #endif + #ifdef ASN1_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 13, 189}, + #endif + #ifdef ASN1_R_MSTRING_NOT_UNIVERSAL + {"MSTRING_NOT_UNIVERSAL", ERR_LIB_ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL}, + #else + {"MSTRING_NOT_UNIVERSAL", 13, 139}, + #endif + #ifdef ASN1_R_MSTRING_WRONG_TAG + {"MSTRING_WRONG_TAG", ERR_LIB_ASN1, ASN1_R_MSTRING_WRONG_TAG}, + #else + {"MSTRING_WRONG_TAG", 13, 140}, + #endif + #ifdef ASN1_R_NESTED_ASN1_STRING + {"NESTED_ASN1_STRING", ERR_LIB_ASN1, ASN1_R_NESTED_ASN1_STRING}, + #else + {"NESTED_ASN1_STRING", 13, 197}, + #endif + #ifdef ASN1_R_NESTED_TOO_DEEP + {"NESTED_TOO_DEEP", ERR_LIB_ASN1, ASN1_R_NESTED_TOO_DEEP}, + #else + {"NESTED_TOO_DEEP", 13, 201}, + #endif + #ifdef ASN1_R_NON_HEX_CHARACTERS + {"NON_HEX_CHARACTERS", ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS}, + #else + {"NON_HEX_CHARACTERS", 13, 141}, + #endif + #ifdef ASN1_R_NOT_ASCII_FORMAT + {"NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_NOT_ASCII_FORMAT}, + #else + {"NOT_ASCII_FORMAT", 13, 190}, + #endif + #ifdef ASN1_R_NOT_ENOUGH_DATA + {"NOT_ENOUGH_DATA", ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA}, + #else + {"NOT_ENOUGH_DATA", 13, 142}, + #endif + #ifdef ASN1_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 13, 209}, + #endif + #ifdef ASN1_R_NO_MATCHING_CHOICE_TYPE + {"NO_MATCHING_CHOICE_TYPE", ERR_LIB_ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE}, + #else + {"NO_MATCHING_CHOICE_TYPE", 13, 143}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BODY_FAILURE + {"NO_MULTIPART_BODY_FAILURE", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE}, + #else + {"NO_MULTIPART_BODY_FAILURE", 13, 210}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BOUNDARY + {"NO_MULTIPART_BOUNDARY", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY}, + #else + {"NO_MULTIPART_BOUNDARY", 13, 211}, + #endif + #ifdef ASN1_R_NO_SIG_CONTENT_TYPE + {"NO_SIG_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE}, + #else + {"NO_SIG_CONTENT_TYPE", 13, 212}, + #endif + #ifdef ASN1_R_NULL_IS_WRONG_LENGTH + {"NULL_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_NULL_IS_WRONG_LENGTH}, + #else + {"NULL_IS_WRONG_LENGTH", 13, 144}, + #endif + #ifdef ASN1_R_OBJECT_NOT_ASCII_FORMAT + {"OBJECT_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT}, + #else + {"OBJECT_NOT_ASCII_FORMAT", 13, 191}, + #endif + #ifdef ASN1_R_ODD_NUMBER_OF_CHARS + {"ODD_NUMBER_OF_CHARS", ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS}, + #else + {"ODD_NUMBER_OF_CHARS", 13, 145}, + #endif + #ifdef ASN1_R_SECOND_NUMBER_TOO_LARGE + {"SECOND_NUMBER_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE}, + #else + {"SECOND_NUMBER_TOO_LARGE", 13, 147}, + #endif + #ifdef ASN1_R_SEQUENCE_LENGTH_MISMATCH + {"SEQUENCE_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH}, + #else + {"SEQUENCE_LENGTH_MISMATCH", 13, 148}, + #endif + #ifdef ASN1_R_SEQUENCE_NOT_CONSTRUCTED + {"SEQUENCE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED}, + #else + {"SEQUENCE_NOT_CONSTRUCTED", 13, 149}, + #endif + #ifdef ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG + {"SEQUENCE_OR_SET_NEEDS_CONFIG", ERR_LIB_ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG}, + #else + {"SEQUENCE_OR_SET_NEEDS_CONFIG", 13, 192}, + #endif + #ifdef ASN1_R_SHORT_LINE + {"SHORT_LINE", ERR_LIB_ASN1, ASN1_R_SHORT_LINE}, + #else + {"SHORT_LINE", 13, 150}, + #endif + #ifdef ASN1_R_SIG_INVALID_MIME_TYPE + {"SIG_INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE}, + #else + {"SIG_INVALID_MIME_TYPE", 13, 213}, + #endif + #ifdef ASN1_R_STREAMING_NOT_SUPPORTED + {"STREAMING_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED}, + #else + {"STREAMING_NOT_SUPPORTED", 13, 202}, + #endif + #ifdef ASN1_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 13, 151}, + #endif + #ifdef ASN1_R_STRING_TOO_SHORT + {"STRING_TOO_SHORT", ERR_LIB_ASN1, ASN1_R_STRING_TOO_SHORT}, + #else + {"STRING_TOO_SHORT", 13, 152}, + #endif + #ifdef ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_ASN1, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 13, 154}, + #endif + #ifdef ASN1_R_TIME_NOT_ASCII_FORMAT + {"TIME_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT}, + #else + {"TIME_NOT_ASCII_FORMAT", 13, 193}, + #endif + #ifdef ASN1_R_TOO_LARGE + {"TOO_LARGE", ERR_LIB_ASN1, ASN1_R_TOO_LARGE}, + #else + {"TOO_LARGE", 13, 223}, + #endif + #ifdef ASN1_R_TOO_LONG + {"TOO_LONG", ERR_LIB_ASN1, ASN1_R_TOO_LONG}, + #else + {"TOO_LONG", 13, 155}, + #endif + #ifdef ASN1_R_TOO_SMALL + {"TOO_SMALL", ERR_LIB_ASN1, ASN1_R_TOO_SMALL}, + #else + {"TOO_SMALL", 13, 224}, + #endif + #ifdef ASN1_R_TYPE_NOT_CONSTRUCTED + {"TYPE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED}, + #else + {"TYPE_NOT_CONSTRUCTED", 13, 156}, + #endif + #ifdef ASN1_R_TYPE_NOT_PRIMITIVE + {"TYPE_NOT_PRIMITIVE", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_PRIMITIVE}, + #else + {"TYPE_NOT_PRIMITIVE", 13, 195}, + #endif + #ifdef ASN1_R_UNEXPECTED_EOC + {"UNEXPECTED_EOC", ERR_LIB_ASN1, ASN1_R_UNEXPECTED_EOC}, + #else + {"UNEXPECTED_EOC", 13, 159}, + #endif + #ifdef ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH + {"UNIVERSALSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH}, + #else + {"UNIVERSALSTRING_IS_WRONG_LENGTH", 13, 215}, + #endif + #ifdef ASN1_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_ASN1, ASN1_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 13, 229}, + #endif + #ifdef ASN1_R_UNKNOWN_FORMAT + {"UNKNOWN_FORMAT", ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT}, + #else + {"UNKNOWN_FORMAT", 13, 160}, + #endif + #ifdef ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", 13, 161}, + #endif + #ifdef ASN1_R_UNKNOWN_OBJECT_TYPE + {"UNKNOWN_OBJECT_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_OBJECT_TYPE}, + #else + {"UNKNOWN_OBJECT_TYPE", 13, 162}, + #endif + #ifdef ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE + {"UNKNOWN_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE}, + #else + {"UNKNOWN_PUBLIC_KEY_TYPE", 13, 163}, + #endif + #ifdef ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM + {"UNKNOWN_SIGNATURE_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM}, + #else + {"UNKNOWN_SIGNATURE_ALGORITHM", 13, 199}, + #endif + #ifdef ASN1_R_UNKNOWN_TAG + {"UNKNOWN_TAG", ERR_LIB_ASN1, ASN1_R_UNKNOWN_TAG}, + #else + {"UNKNOWN_TAG", 13, 194}, + #endif + #ifdef ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE}, + #else + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", 13, 164}, + #endif + #ifdef ASN1_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 13, 228}, + #endif + #ifdef ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE + {"UNSUPPORTED_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE}, + #else + {"UNSUPPORTED_PUBLIC_KEY_TYPE", 13, 167}, + #endif + #ifdef ASN1_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 13, 196}, + #endif + #ifdef ASN1_R_WRONG_INTEGER_TYPE + {"WRONG_INTEGER_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_INTEGER_TYPE}, + #else + {"WRONG_INTEGER_TYPE", 13, 225}, + #endif + #ifdef ASN1_R_WRONG_PUBLIC_KEY_TYPE + {"WRONG_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE}, + #else + {"WRONG_PUBLIC_KEY_TYPE", 13, 200}, + #endif + #ifdef ASN1_R_WRONG_TAG + {"WRONG_TAG", ERR_LIB_ASN1, ASN1_R_WRONG_TAG}, + #else + {"WRONG_TAG", 13, 168}, + #endif + #ifdef ASYNC_R_FAILED_TO_SET_POOL + {"FAILED_TO_SET_POOL", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SET_POOL}, + #else + {"FAILED_TO_SET_POOL", 51, 101}, + #endif + #ifdef ASYNC_R_FAILED_TO_SWAP_CONTEXT + {"FAILED_TO_SWAP_CONTEXT", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT}, + #else + {"FAILED_TO_SWAP_CONTEXT", 51, 102}, + #endif + #ifdef ASYNC_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ASYNC, ASYNC_R_INIT_FAILED}, + #else + {"INIT_FAILED", 51, 105}, + #endif + #ifdef ASYNC_R_INVALID_POOL_SIZE + {"INVALID_POOL_SIZE", ERR_LIB_ASYNC, ASYNC_R_INVALID_POOL_SIZE}, + #else + {"INVALID_POOL_SIZE", 51, 103}, + #endif + #ifdef BIO_R_ACCEPT_ERROR + {"ACCEPT_ERROR", ERR_LIB_BIO, BIO_R_ACCEPT_ERROR}, + #else + {"ACCEPT_ERROR", 32, 100}, + #endif + #ifdef BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET + {"ADDRINFO_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET}, + #else + {"ADDRINFO_ADDR_IS_NOT_AF_INET", 32, 141}, + #endif + #ifdef BIO_R_AMBIGUOUS_HOST_OR_SERVICE + {"AMBIGUOUS_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_AMBIGUOUS_HOST_OR_SERVICE}, + #else + {"AMBIGUOUS_HOST_OR_SERVICE", 32, 129}, + #endif + #ifdef BIO_R_BAD_FOPEN_MODE + {"BAD_FOPEN_MODE", ERR_LIB_BIO, BIO_R_BAD_FOPEN_MODE}, + #else + {"BAD_FOPEN_MODE", 32, 101}, + #endif + #ifdef BIO_R_BROKEN_PIPE + {"BROKEN_PIPE", ERR_LIB_BIO, BIO_R_BROKEN_PIPE}, + #else + {"BROKEN_PIPE", 32, 124}, + #endif + #ifdef BIO_R_CONNECT_ERROR + {"CONNECT_ERROR", ERR_LIB_BIO, BIO_R_CONNECT_ERROR}, + #else + {"CONNECT_ERROR", 32, 103}, + #endif + #ifdef BIO_R_CONNECT_TIMEOUT + {"CONNECT_TIMEOUT", ERR_LIB_BIO, BIO_R_CONNECT_TIMEOUT}, + #else + {"CONNECT_TIMEOUT", 32, 147}, + #endif + #ifdef BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET}, + #else + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", 32, 107}, + #endif + #ifdef BIO_R_GETSOCKNAME_ERROR + {"GETSOCKNAME_ERROR", ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR}, + #else + {"GETSOCKNAME_ERROR", 32, 132}, + #endif + #ifdef BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS + {"GETSOCKNAME_TRUNCATED_ADDRESS", ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS}, + #else + {"GETSOCKNAME_TRUNCATED_ADDRESS", 32, 133}, + #endif + #ifdef BIO_R_GETTING_SOCKTYPE + {"GETTING_SOCKTYPE", ERR_LIB_BIO, BIO_R_GETTING_SOCKTYPE}, + #else + {"GETTING_SOCKTYPE", 32, 134}, + #endif + #ifdef BIO_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 32, 125}, + #endif + #ifdef BIO_R_INVALID_SOCKET + {"INVALID_SOCKET", ERR_LIB_BIO, BIO_R_INVALID_SOCKET}, + #else + {"INVALID_SOCKET", 32, 135}, + #endif + #ifdef BIO_R_IN_USE + {"IN_USE", ERR_LIB_BIO, BIO_R_IN_USE}, + #else + {"IN_USE", 32, 123}, + #endif + #ifdef BIO_R_LENGTH_TOO_LONG + {"LENGTH_TOO_LONG", ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG}, + #else + {"LENGTH_TOO_LONG", 32, 102}, + #endif + #ifdef BIO_R_LISTEN_V6_ONLY + {"LISTEN_V6_ONLY", ERR_LIB_BIO, BIO_R_LISTEN_V6_ONLY}, + #else + {"LISTEN_V6_ONLY", 32, 136}, + #endif + #ifdef BIO_R_LOOKUP_RETURNED_NOTHING + {"LOOKUP_RETURNED_NOTHING", ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING}, + #else + {"LOOKUP_RETURNED_NOTHING", 32, 142}, + #endif + #ifdef BIO_R_MALFORMED_HOST_OR_SERVICE + {"MALFORMED_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE}, + #else + {"MALFORMED_HOST_OR_SERVICE", 32, 130}, + #endif + #ifdef BIO_R_NBIO_CONNECT_ERROR + {"NBIO_CONNECT_ERROR", ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR}, + #else + {"NBIO_CONNECT_ERROR", 32, 110}, + #endif + #ifdef BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED}, + #else + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", 32, 143}, + #endif + #ifdef BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED}, + #else + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", 32, 144}, + #endif + #ifdef BIO_R_NO_PORT_DEFINED + {"NO_PORT_DEFINED", ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED}, + #else + {"NO_PORT_DEFINED", 32, 113}, + #endif + #ifdef BIO_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_BIO, BIO_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 32, 128}, + #endif + #ifdef BIO_R_TRANSFER_ERROR + {"TRANSFER_ERROR", ERR_LIB_BIO, BIO_R_TRANSFER_ERROR}, + #else + {"TRANSFER_ERROR", 32, 104}, + #endif + #ifdef BIO_R_TRANSFER_TIMEOUT + {"TRANSFER_TIMEOUT", ERR_LIB_BIO, BIO_R_TRANSFER_TIMEOUT}, + #else + {"TRANSFER_TIMEOUT", 32, 105}, + #endif + #ifdef BIO_R_UNABLE_TO_BIND_SOCKET + {"UNABLE_TO_BIND_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_BIND_SOCKET}, + #else + {"UNABLE_TO_BIND_SOCKET", 32, 117}, + #endif + #ifdef BIO_R_UNABLE_TO_CREATE_SOCKET + {"UNABLE_TO_CREATE_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET}, + #else + {"UNABLE_TO_CREATE_SOCKET", 32, 118}, + #endif + #ifdef BIO_R_UNABLE_TO_KEEPALIVE + {"UNABLE_TO_KEEPALIVE", ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE}, + #else + {"UNABLE_TO_KEEPALIVE", 32, 137}, + #endif + #ifdef BIO_R_UNABLE_TO_LISTEN_SOCKET + {"UNABLE_TO_LISTEN_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_LISTEN_SOCKET}, + #else + {"UNABLE_TO_LISTEN_SOCKET", 32, 119}, + #endif + #ifdef BIO_R_UNABLE_TO_NODELAY + {"UNABLE_TO_NODELAY", ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY}, + #else + {"UNABLE_TO_NODELAY", 32, 138}, + #endif + #ifdef BIO_R_UNABLE_TO_REUSEADDR + {"UNABLE_TO_REUSEADDR", ERR_LIB_BIO, BIO_R_UNABLE_TO_REUSEADDR}, + #else + {"UNABLE_TO_REUSEADDR", 32, 139}, + #endif + #ifdef BIO_R_UNAVAILABLE_IP_FAMILY + {"UNAVAILABLE_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY}, + #else + {"UNAVAILABLE_IP_FAMILY", 32, 145}, + #endif + #ifdef BIO_R_UNINITIALIZED + {"UNINITIALIZED", ERR_LIB_BIO, BIO_R_UNINITIALIZED}, + #else + {"UNINITIALIZED", 32, 120}, + #endif + #ifdef BIO_R_UNKNOWN_INFO_TYPE + {"UNKNOWN_INFO_TYPE", ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE}, + #else + {"UNKNOWN_INFO_TYPE", 32, 140}, + #endif + #ifdef BIO_R_UNSUPPORTED_IP_FAMILY + {"UNSUPPORTED_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY}, + #else + {"UNSUPPORTED_IP_FAMILY", 32, 146}, + #endif + #ifdef BIO_R_UNSUPPORTED_METHOD + {"UNSUPPORTED_METHOD", ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD}, + #else + {"UNSUPPORTED_METHOD", 32, 121}, + #endif + #ifdef BIO_R_UNSUPPORTED_PROTOCOL_FAMILY + {"UNSUPPORTED_PROTOCOL_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY}, + #else + {"UNSUPPORTED_PROTOCOL_FAMILY", 32, 131}, + #endif + #ifdef BIO_R_WRITE_TO_READ_ONLY_BIO + {"WRITE_TO_READ_ONLY_BIO", ERR_LIB_BIO, BIO_R_WRITE_TO_READ_ONLY_BIO}, + #else + {"WRITE_TO_READ_ONLY_BIO", 32, 126}, + #endif + #ifdef BIO_R_WSASTARTUP + {"WSASTARTUP", ERR_LIB_BIO, BIO_R_WSASTARTUP}, + #else + {"WSASTARTUP", 32, 122}, + #endif + #ifdef BN_R_ARG2_LT_ARG3 + {"ARG2_LT_ARG3", ERR_LIB_BN, BN_R_ARG2_LT_ARG3}, + #else + {"ARG2_LT_ARG3", 3, 100}, + #endif + #ifdef BN_R_BAD_RECIPROCAL + {"BAD_RECIPROCAL", ERR_LIB_BN, BN_R_BAD_RECIPROCAL}, + #else + {"BAD_RECIPROCAL", 3, 101}, + #endif + #ifdef BN_R_BIGNUM_TOO_LONG + {"BIGNUM_TOO_LONG", ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG}, + #else + {"BIGNUM_TOO_LONG", 3, 114}, + #endif + #ifdef BN_R_BITS_TOO_SMALL + {"BITS_TOO_SMALL", ERR_LIB_BN, BN_R_BITS_TOO_SMALL}, + #else + {"BITS_TOO_SMALL", 3, 118}, + #endif + #ifdef BN_R_CALLED_WITH_EVEN_MODULUS + {"CALLED_WITH_EVEN_MODULUS", ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS}, + #else + {"CALLED_WITH_EVEN_MODULUS", 3, 102}, + #endif + #ifdef BN_R_DIV_BY_ZERO + {"DIV_BY_ZERO", ERR_LIB_BN, BN_R_DIV_BY_ZERO}, + #else + {"DIV_BY_ZERO", 3, 103}, + #endif + #ifdef BN_R_ENCODING_ERROR + {"ENCODING_ERROR", ERR_LIB_BN, BN_R_ENCODING_ERROR}, + #else + {"ENCODING_ERROR", 3, 104}, + #endif + #ifdef BN_R_EXPAND_ON_STATIC_BIGNUM_DATA + {"EXPAND_ON_STATIC_BIGNUM_DATA", ERR_LIB_BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA}, + #else + {"EXPAND_ON_STATIC_BIGNUM_DATA", 3, 105}, + #endif + #ifdef BN_R_INPUT_NOT_REDUCED + {"INPUT_NOT_REDUCED", ERR_LIB_BN, BN_R_INPUT_NOT_REDUCED}, + #else + {"INPUT_NOT_REDUCED", 3, 110}, + #endif + #ifdef BN_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_BN, BN_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 3, 106}, + #endif + #ifdef BN_R_INVALID_RANGE + {"INVALID_RANGE", ERR_LIB_BN, BN_R_INVALID_RANGE}, + #else + {"INVALID_RANGE", 3, 115}, + #endif + #ifdef BN_R_INVALID_SHIFT + {"INVALID_SHIFT", ERR_LIB_BN, BN_R_INVALID_SHIFT}, + #else + {"INVALID_SHIFT", 3, 119}, + #endif + #ifdef BN_R_NOT_A_SQUARE + {"NOT_A_SQUARE", ERR_LIB_BN, BN_R_NOT_A_SQUARE}, + #else + {"NOT_A_SQUARE", 3, 111}, + #endif + #ifdef BN_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_BN, BN_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 3, 107}, + #endif + #ifdef BN_R_NO_INVERSE + {"NO_INVERSE", ERR_LIB_BN, BN_R_NO_INVERSE}, + #else + {"NO_INVERSE", 3, 108}, + #endif + #ifdef BN_R_NO_SOLUTION + {"NO_SOLUTION", ERR_LIB_BN, BN_R_NO_SOLUTION}, + #else + {"NO_SOLUTION", 3, 116}, + #endif + #ifdef BN_R_NO_SUITABLE_DIGEST + {"NO_SUITABLE_DIGEST", ERR_LIB_BN, BN_R_NO_SUITABLE_DIGEST}, + #else + {"NO_SUITABLE_DIGEST", 3, 120}, + #endif + #ifdef BN_R_PRIVATE_KEY_TOO_LARGE + {"PRIVATE_KEY_TOO_LARGE", ERR_LIB_BN, BN_R_PRIVATE_KEY_TOO_LARGE}, + #else + {"PRIVATE_KEY_TOO_LARGE", 3, 117}, + #endif + #ifdef BN_R_P_IS_NOT_PRIME + {"P_IS_NOT_PRIME", ERR_LIB_BN, BN_R_P_IS_NOT_PRIME}, + #else + {"P_IS_NOT_PRIME", 3, 112}, + #endif + #ifdef BN_R_TOO_MANY_ITERATIONS + {"TOO_MANY_ITERATIONS", ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS}, + #else + {"TOO_MANY_ITERATIONS", 3, 113}, + #endif + #ifdef BN_R_TOO_MANY_TEMPORARY_VARIABLES + {"TOO_MANY_TEMPORARY_VARIABLES", ERR_LIB_BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES}, + #else + {"TOO_MANY_TEMPORARY_VARIABLES", 3, 109}, + #endif + #ifdef CMP_R_ALGORITHM_NOT_SUPPORTED + {"ALGORITHM_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_ALGORITHM_NOT_SUPPORTED}, + #else + {"ALGORITHM_NOT_SUPPORTED", 58, 139}, + #endif + #ifdef CMP_R_BAD_CHECKAFTER_IN_POLLREP + {"BAD_CHECKAFTER_IN_POLLREP", ERR_LIB_CMP, CMP_R_BAD_CHECKAFTER_IN_POLLREP}, + #else + {"BAD_CHECKAFTER_IN_POLLREP", 58, 167}, + #endif + #ifdef CMP_R_BAD_REQUEST_ID + {"BAD_REQUEST_ID", ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID}, + #else + {"BAD_REQUEST_ID", 58, 108}, + #endif + #ifdef CMP_R_CERTHASH_UNMATCHED + {"CERTHASH_UNMATCHED", ERR_LIB_CMP, CMP_R_CERTHASH_UNMATCHED}, + #else + {"CERTHASH_UNMATCHED", 58, 156}, + #endif + #ifdef CMP_R_CERTID_NOT_FOUND + {"CERTID_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTID_NOT_FOUND}, + #else + {"CERTID_NOT_FOUND", 58, 109}, + #endif + #ifdef CMP_R_CERTIFICATE_NOT_ACCEPTED + {"CERTIFICATE_NOT_ACCEPTED", ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_ACCEPTED}, + #else + {"CERTIFICATE_NOT_ACCEPTED", 58, 169}, + #endif + #ifdef CMP_R_CERTIFICATE_NOT_FOUND + {"CERTIFICATE_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND}, + #else + {"CERTIFICATE_NOT_FOUND", 58, 112}, + #endif + #ifdef CMP_R_CERTREQMSG_NOT_FOUND + {"CERTREQMSG_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND}, + #else + {"CERTREQMSG_NOT_FOUND", 58, 157}, + #endif + #ifdef CMP_R_CERTRESPONSE_NOT_FOUND + {"CERTRESPONSE_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND}, + #else + {"CERTRESPONSE_NOT_FOUND", 58, 113}, + #endif + #ifdef CMP_R_CERT_AND_KEY_DO_NOT_MATCH + {"CERT_AND_KEY_DO_NOT_MATCH", ERR_LIB_CMP, CMP_R_CERT_AND_KEY_DO_NOT_MATCH}, + #else + {"CERT_AND_KEY_DO_NOT_MATCH", 58, 114}, + #endif + #ifdef CMP_R_CHECKAFTER_OUT_OF_RANGE + {"CHECKAFTER_OUT_OF_RANGE", ERR_LIB_CMP, CMP_R_CHECKAFTER_OUT_OF_RANGE}, + #else + {"CHECKAFTER_OUT_OF_RANGE", 58, 181}, + #endif + #ifdef CMP_R_ENCOUNTERED_KEYUPDATEWARNING + {"ENCOUNTERED_KEYUPDATEWARNING", ERR_LIB_CMP, CMP_R_ENCOUNTERED_KEYUPDATEWARNING}, + #else + {"ENCOUNTERED_KEYUPDATEWARNING", 58, 176}, + #endif + #ifdef CMP_R_ENCOUNTERED_WAITING + {"ENCOUNTERED_WAITING", ERR_LIB_CMP, CMP_R_ENCOUNTERED_WAITING}, + #else + {"ENCOUNTERED_WAITING", 58, 162}, + #endif + #ifdef CMP_R_ERROR_CALCULATING_PROTECTION + {"ERROR_CALCULATING_PROTECTION", ERR_LIB_CMP, CMP_R_ERROR_CALCULATING_PROTECTION}, + #else + {"ERROR_CALCULATING_PROTECTION", 58, 115}, + #endif + #ifdef CMP_R_ERROR_CREATING_CERTCONF + {"ERROR_CREATING_CERTCONF", ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTCONF}, + #else + {"ERROR_CREATING_CERTCONF", 58, 116}, + #endif + #ifdef CMP_R_ERROR_CREATING_CERTREP + {"ERROR_CREATING_CERTREP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP}, + #else + {"ERROR_CREATING_CERTREP", 58, 117}, + #endif + #ifdef CMP_R_ERROR_CREATING_CERTREQ + {"ERROR_CREATING_CERTREQ", ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREQ}, + #else + {"ERROR_CREATING_CERTREQ", 58, 163}, + #endif + #ifdef CMP_R_ERROR_CREATING_ERROR + {"ERROR_CREATING_ERROR", ERR_LIB_CMP, CMP_R_ERROR_CREATING_ERROR}, + #else + {"ERROR_CREATING_ERROR", 58, 118}, + #endif + #ifdef CMP_R_ERROR_CREATING_GENM + {"ERROR_CREATING_GENM", ERR_LIB_CMP, CMP_R_ERROR_CREATING_GENM}, + #else + {"ERROR_CREATING_GENM", 58, 119}, + #endif + #ifdef CMP_R_ERROR_CREATING_GENP + {"ERROR_CREATING_GENP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_GENP}, + #else + {"ERROR_CREATING_GENP", 58, 120}, + #endif + #ifdef CMP_R_ERROR_CREATING_PKICONF + {"ERROR_CREATING_PKICONF", ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF}, + #else + {"ERROR_CREATING_PKICONF", 58, 122}, + #endif + #ifdef CMP_R_ERROR_CREATING_POLLREP + {"ERROR_CREATING_POLLREP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP}, + #else + {"ERROR_CREATING_POLLREP", 58, 123}, + #endif + #ifdef CMP_R_ERROR_CREATING_POLLREQ + {"ERROR_CREATING_POLLREQ", ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREQ}, + #else + {"ERROR_CREATING_POLLREQ", 58, 124}, + #endif + #ifdef CMP_R_ERROR_CREATING_RP + {"ERROR_CREATING_RP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_RP}, + #else + {"ERROR_CREATING_RP", 58, 125}, + #endif + #ifdef CMP_R_ERROR_CREATING_RR + {"ERROR_CREATING_RR", ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR}, + #else + {"ERROR_CREATING_RR", 58, 126}, + #endif + #ifdef CMP_R_ERROR_PARSING_PKISTATUS + {"ERROR_PARSING_PKISTATUS", ERR_LIB_CMP, CMP_R_ERROR_PARSING_PKISTATUS}, + #else + {"ERROR_PARSING_PKISTATUS", 58, 107}, + #endif + #ifdef CMP_R_ERROR_PROCESSING_MESSAGE + {"ERROR_PROCESSING_MESSAGE", ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE}, + #else + {"ERROR_PROCESSING_MESSAGE", 58, 158}, + #endif + #ifdef CMP_R_ERROR_PROTECTING_MESSAGE + {"ERROR_PROTECTING_MESSAGE", ERR_LIB_CMP, CMP_R_ERROR_PROTECTING_MESSAGE}, + #else + {"ERROR_PROTECTING_MESSAGE", 58, 127}, + #endif + #ifdef CMP_R_ERROR_SETTING_CERTHASH + {"ERROR_SETTING_CERTHASH", ERR_LIB_CMP, CMP_R_ERROR_SETTING_CERTHASH}, + #else + {"ERROR_SETTING_CERTHASH", 58, 128}, + #endif + #ifdef CMP_R_ERROR_UNEXPECTED_CERTCONF + {"ERROR_UNEXPECTED_CERTCONF", ERR_LIB_CMP, CMP_R_ERROR_UNEXPECTED_CERTCONF}, + #else + {"ERROR_UNEXPECTED_CERTCONF", 58, 160}, + #endif + #ifdef CMP_R_ERROR_VALIDATING_PROTECTION + {"ERROR_VALIDATING_PROTECTION", ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION}, + #else + {"ERROR_VALIDATING_PROTECTION", 58, 140}, + #endif + #ifdef CMP_R_ERROR_VALIDATING_SIGNATURE + {"ERROR_VALIDATING_SIGNATURE", ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_SIGNATURE}, + #else + {"ERROR_VALIDATING_SIGNATURE", 58, 171}, + #endif + #ifdef CMP_R_FAILED_BUILDING_OWN_CHAIN + {"FAILED_BUILDING_OWN_CHAIN", ERR_LIB_CMP, CMP_R_FAILED_BUILDING_OWN_CHAIN}, + #else + {"FAILED_BUILDING_OWN_CHAIN", 58, 164}, + #endif + #ifdef CMP_R_FAILED_EXTRACTING_PUBKEY + {"FAILED_EXTRACTING_PUBKEY", ERR_LIB_CMP, CMP_R_FAILED_EXTRACTING_PUBKEY}, + #else + {"FAILED_EXTRACTING_PUBKEY", 58, 141}, + #endif + #ifdef CMP_R_FAILURE_OBTAINING_RANDOM + {"FAILURE_OBTAINING_RANDOM", ERR_LIB_CMP, CMP_R_FAILURE_OBTAINING_RANDOM}, + #else + {"FAILURE_OBTAINING_RANDOM", 58, 110}, + #endif + #ifdef CMP_R_FAIL_INFO_OUT_OF_RANGE + {"FAIL_INFO_OUT_OF_RANGE", ERR_LIB_CMP, CMP_R_FAIL_INFO_OUT_OF_RANGE}, + #else + {"FAIL_INFO_OUT_OF_RANGE", 58, 129}, + #endif + #ifdef CMP_R_INVALID_ARGS + {"INVALID_ARGS", ERR_LIB_CMP, CMP_R_INVALID_ARGS}, + #else + {"INVALID_ARGS", 58, 100}, + #endif + #ifdef CMP_R_INVALID_OPTION + {"INVALID_OPTION", ERR_LIB_CMP, CMP_R_INVALID_OPTION}, + #else + {"INVALID_OPTION", 58, 174}, + #endif + #ifdef CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION + {"MISSING_KEY_INPUT_FOR_CREATING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION}, + #else + {"MISSING_KEY_INPUT_FOR_CREATING_PROTECTION", 58, 130}, + #endif + #ifdef CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE + {"MISSING_KEY_USAGE_DIGITALSIGNATURE", ERR_LIB_CMP, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE}, + #else + {"MISSING_KEY_USAGE_DIGITALSIGNATURE", 58, 142}, + #endif + #ifdef CMP_R_MISSING_P10CSR + {"MISSING_P10CSR", ERR_LIB_CMP, CMP_R_MISSING_P10CSR}, + #else + {"MISSING_P10CSR", 58, 121}, + #endif + #ifdef CMP_R_MISSING_PBM_SECRET + {"MISSING_PBM_SECRET", ERR_LIB_CMP, CMP_R_MISSING_PBM_SECRET}, + #else + {"MISSING_PBM_SECRET", 58, 166}, + #endif + #ifdef CMP_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 58, 131}, + #endif + #ifdef CMP_R_MISSING_PROTECTION + {"MISSING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_PROTECTION}, + #else + {"MISSING_PROTECTION", 58, 143}, + #endif + #ifdef CMP_R_MISSING_REFERENCE_CERT + {"MISSING_REFERENCE_CERT", ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT}, + #else + {"MISSING_REFERENCE_CERT", 58, 168}, + #endif + #ifdef CMP_R_MISSING_SENDER_IDENTIFICATION + {"MISSING_SENDER_IDENTIFICATION", ERR_LIB_CMP, CMP_R_MISSING_SENDER_IDENTIFICATION}, + #else + {"MISSING_SENDER_IDENTIFICATION", 58, 111}, + #endif + #ifdef CMP_R_MISSING_TRUST_STORE + {"MISSING_TRUST_STORE", ERR_LIB_CMP, CMP_R_MISSING_TRUST_STORE}, + #else + {"MISSING_TRUST_STORE", 58, 144}, + #endif + #ifdef CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED + {"MULTIPLE_REQUESTS_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED}, + #else + {"MULTIPLE_REQUESTS_NOT_SUPPORTED", 58, 161}, + #endif + #ifdef CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED + {"MULTIPLE_RESPONSES_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED}, + #else + {"MULTIPLE_RESPONSES_NOT_SUPPORTED", 58, 170}, + #endif + #ifdef CMP_R_MULTIPLE_SAN_SOURCES + {"MULTIPLE_SAN_SOURCES", ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES}, + #else + {"MULTIPLE_SAN_SOURCES", 58, 102}, + #endif + #ifdef CMP_R_NO_STDIO + {"NO_STDIO", ERR_LIB_CMP, CMP_R_NO_STDIO}, + #else + {"NO_STDIO", 58, 194}, + #endif + #ifdef CMP_R_NO_SUITABLE_SENDER_CERT + {"NO_SUITABLE_SENDER_CERT", ERR_LIB_CMP, CMP_R_NO_SUITABLE_SENDER_CERT}, + #else + {"NO_SUITABLE_SENDER_CERT", 58, 145}, + #endif + #ifdef CMP_R_NULL_ARGUMENT + {"NULL_ARGUMENT", ERR_LIB_CMP, CMP_R_NULL_ARGUMENT}, + #else + {"NULL_ARGUMENT", 58, 103}, + #endif + #ifdef CMP_R_PKIBODY_ERROR + {"PKIBODY_ERROR", ERR_LIB_CMP, CMP_R_PKIBODY_ERROR}, + #else + {"PKIBODY_ERROR", 58, 146}, + #endif + #ifdef CMP_R_PKISTATUSINFO_NOT_FOUND + {"PKISTATUSINFO_NOT_FOUND", ERR_LIB_CMP, CMP_R_PKISTATUSINFO_NOT_FOUND}, + #else + {"PKISTATUSINFO_NOT_FOUND", 58, 132}, + #endif + #ifdef CMP_R_POLLING_FAILED + {"POLLING_FAILED", ERR_LIB_CMP, CMP_R_POLLING_FAILED}, + #else + {"POLLING_FAILED", 58, 172}, + #endif + #ifdef CMP_R_POTENTIALLY_INVALID_CERTIFICATE + {"POTENTIALLY_INVALID_CERTIFICATE", ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE}, + #else + {"POTENTIALLY_INVALID_CERTIFICATE", 58, 147}, + #endif + #ifdef CMP_R_RECEIVED_ERROR + {"RECEIVED_ERROR", ERR_LIB_CMP, CMP_R_RECEIVED_ERROR}, + #else + {"RECEIVED_ERROR", 58, 180}, + #endif + #ifdef CMP_R_RECIPNONCE_UNMATCHED + {"RECIPNONCE_UNMATCHED", ERR_LIB_CMP, CMP_R_RECIPNONCE_UNMATCHED}, + #else + {"RECIPNONCE_UNMATCHED", 58, 148}, + #endif + #ifdef CMP_R_REQUEST_NOT_ACCEPTED + {"REQUEST_NOT_ACCEPTED", ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED}, + #else + {"REQUEST_NOT_ACCEPTED", 58, 149}, + #endif + #ifdef CMP_R_REQUEST_REJECTED_BY_SERVER + {"REQUEST_REJECTED_BY_SERVER", ERR_LIB_CMP, CMP_R_REQUEST_REJECTED_BY_SERVER}, + #else + {"REQUEST_REJECTED_BY_SERVER", 58, 182}, + #endif + #ifdef CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED + {"SENDER_GENERALNAME_TYPE_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED}, + #else + {"SENDER_GENERALNAME_TYPE_NOT_SUPPORTED", 58, 150}, + #endif + #ifdef CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG + {"SRVCERT_DOES_NOT_VALIDATE_MSG", ERR_LIB_CMP, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG}, + #else + {"SRVCERT_DOES_NOT_VALIDATE_MSG", 58, 151}, + #endif + #ifdef CMP_R_TOTAL_TIMEOUT + {"TOTAL_TIMEOUT", ERR_LIB_CMP, CMP_R_TOTAL_TIMEOUT}, + #else + {"TOTAL_TIMEOUT", 58, 184}, + #endif + #ifdef CMP_R_TRANSACTIONID_UNMATCHED + {"TRANSACTIONID_UNMATCHED", ERR_LIB_CMP, CMP_R_TRANSACTIONID_UNMATCHED}, + #else + {"TRANSACTIONID_UNMATCHED", 58, 152}, + #endif + #ifdef CMP_R_TRANSFER_ERROR + {"TRANSFER_ERROR", ERR_LIB_CMP, CMP_R_TRANSFER_ERROR}, + #else + {"TRANSFER_ERROR", 58, 159}, + #endif + #ifdef CMP_R_UNEXPECTED_PKIBODY + {"UNEXPECTED_PKIBODY", ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY}, + #else + {"UNEXPECTED_PKIBODY", 58, 133}, + #endif + #ifdef CMP_R_UNEXPECTED_PKISTATUS + {"UNEXPECTED_PKISTATUS", ERR_LIB_CMP, CMP_R_UNEXPECTED_PKISTATUS}, + #else + {"UNEXPECTED_PKISTATUS", 58, 185}, + #endif + #ifdef CMP_R_UNEXPECTED_PVNO + {"UNEXPECTED_PVNO", ERR_LIB_CMP, CMP_R_UNEXPECTED_PVNO}, + #else + {"UNEXPECTED_PVNO", 58, 153}, + #endif + #ifdef CMP_R_UNKNOWN_ALGORITHM_ID + {"UNKNOWN_ALGORITHM_ID", ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID}, + #else + {"UNKNOWN_ALGORITHM_ID", 58, 134}, + #endif + #ifdef CMP_R_UNKNOWN_CERT_TYPE + {"UNKNOWN_CERT_TYPE", ERR_LIB_CMP, CMP_R_UNKNOWN_CERT_TYPE}, + #else + {"UNKNOWN_CERT_TYPE", 58, 135}, + #endif + #ifdef CMP_R_UNKNOWN_PKISTATUS + {"UNKNOWN_PKISTATUS", ERR_LIB_CMP, CMP_R_UNKNOWN_PKISTATUS}, + #else + {"UNKNOWN_PKISTATUS", 58, 186}, + #endif + #ifdef CMP_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_CMP, CMP_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 58, 136}, + #endif + #ifdef CMP_R_UNSUPPORTED_KEY_TYPE + {"UNSUPPORTED_KEY_TYPE", ERR_LIB_CMP, CMP_R_UNSUPPORTED_KEY_TYPE}, + #else + {"UNSUPPORTED_KEY_TYPE", 58, 137}, + #endif + #ifdef CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC + {"UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC", ERR_LIB_CMP, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC}, + #else + {"UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC", 58, 154}, + #endif + #ifdef CMP_R_VALUE_TOO_LARGE + {"VALUE_TOO_LARGE", ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE}, + #else + {"VALUE_TOO_LARGE", 58, 175}, + #endif + #ifdef CMP_R_VALUE_TOO_SMALL + {"VALUE_TOO_SMALL", ERR_LIB_CMP, CMP_R_VALUE_TOO_SMALL}, + #else + {"VALUE_TOO_SMALL", 58, 177}, + #endif + #ifdef CMP_R_WRONG_ALGORITHM_OID + {"WRONG_ALGORITHM_OID", ERR_LIB_CMP, CMP_R_WRONG_ALGORITHM_OID}, + #else + {"WRONG_ALGORITHM_OID", 58, 138}, + #endif + #ifdef CMP_R_WRONG_CERTID_IN_RP + {"WRONG_CERTID_IN_RP", ERR_LIB_CMP, CMP_R_WRONG_CERTID_IN_RP}, + #else + {"WRONG_CERTID_IN_RP", 58, 187}, + #endif + #ifdef CMP_R_WRONG_PBM_VALUE + {"WRONG_PBM_VALUE", ERR_LIB_CMP, CMP_R_WRONG_PBM_VALUE}, + #else + {"WRONG_PBM_VALUE", 58, 155}, + #endif + #ifdef CMP_R_WRONG_RP_COMPONENT_COUNT + {"WRONG_RP_COMPONENT_COUNT", ERR_LIB_CMP, CMP_R_WRONG_RP_COMPONENT_COUNT}, + #else + {"WRONG_RP_COMPONENT_COUNT", 58, 188}, + #endif + #ifdef CMP_R_WRONG_SERIAL_IN_RP + {"WRONG_SERIAL_IN_RP", ERR_LIB_CMP, CMP_R_WRONG_SERIAL_IN_RP}, + #else + {"WRONG_SERIAL_IN_RP", 58, 173}, + #endif + #ifdef CMS_R_ADD_SIGNER_ERROR + {"ADD_SIGNER_ERROR", ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR}, + #else + {"ADD_SIGNER_ERROR", 46, 99}, + #endif + #ifdef CMS_R_ATTRIBUTE_ERROR + {"ATTRIBUTE_ERROR", ERR_LIB_CMS, CMS_R_ATTRIBUTE_ERROR}, + #else + {"ATTRIBUTE_ERROR", 46, 161}, + #endif + #ifdef CMS_R_CERTIFICATE_ALREADY_PRESENT + {"CERTIFICATE_ALREADY_PRESENT", ERR_LIB_CMS, CMS_R_CERTIFICATE_ALREADY_PRESENT}, + #else + {"CERTIFICATE_ALREADY_PRESENT", 46, 175}, + #endif + #ifdef CMS_R_CERTIFICATE_HAS_NO_KEYID + {"CERTIFICATE_HAS_NO_KEYID", ERR_LIB_CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID}, + #else + {"CERTIFICATE_HAS_NO_KEYID", 46, 160}, + #endif + #ifdef CMS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 46, 100}, + #endif + #ifdef CMS_R_CIPHER_AEAD_SET_TAG_ERROR + {"CIPHER_AEAD_SET_TAG_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_AEAD_SET_TAG_ERROR}, + #else + {"CIPHER_AEAD_SET_TAG_ERROR", 46, 184}, + #endif + #ifdef CMS_R_CIPHER_GET_TAG + {"CIPHER_GET_TAG", ERR_LIB_CMS, CMS_R_CIPHER_GET_TAG}, + #else + {"CIPHER_GET_TAG", 46, 185}, + #endif + #ifdef CMS_R_CIPHER_INITIALISATION_ERROR + {"CIPHER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_INITIALISATION_ERROR}, + #else + {"CIPHER_INITIALISATION_ERROR", 46, 101}, + #endif + #ifdef CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR + {"CIPHER_PARAMETER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR}, + #else + {"CIPHER_PARAMETER_INITIALISATION_ERROR", 46, 102}, + #endif + #ifdef CMS_R_CMS_DATAFINAL_ERROR + {"CMS_DATAFINAL_ERROR", ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR}, + #else + {"CMS_DATAFINAL_ERROR", 46, 103}, + #endif + #ifdef CMS_R_CMS_LIB + {"CMS_LIB", ERR_LIB_CMS, CMS_R_CMS_LIB}, + #else + {"CMS_LIB", 46, 104}, + #endif + #ifdef CMS_R_CONTENTIDENTIFIER_MISMATCH + {"CONTENTIDENTIFIER_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENTIDENTIFIER_MISMATCH}, + #else + {"CONTENTIDENTIFIER_MISMATCH", 46, 170}, + #endif + #ifdef CMS_R_CONTENT_NOT_FOUND + {"CONTENT_NOT_FOUND", ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND}, + #else + {"CONTENT_NOT_FOUND", 46, 105}, + #endif + #ifdef CMS_R_CONTENT_TYPE_MISMATCH + {"CONTENT_TYPE_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_MISMATCH}, + #else + {"CONTENT_TYPE_MISMATCH", 46, 171}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA}, + #else + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", 46, 106}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA}, + #else + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", 46, 107}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA + {"CONTENT_TYPE_NOT_SIGNED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA}, + #else + {"CONTENT_TYPE_NOT_SIGNED_DATA", 46, 108}, + #endif + #ifdef CMS_R_CONTENT_VERIFY_ERROR + {"CONTENT_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR}, + #else + {"CONTENT_VERIFY_ERROR", 46, 109}, + #endif + #ifdef CMS_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_CMS, CMS_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 46, 110}, + #endif + #ifdef CMS_R_CTRL_FAILURE + {"CTRL_FAILURE", ERR_LIB_CMS, CMS_R_CTRL_FAILURE}, + #else + {"CTRL_FAILURE", 46, 111}, + #endif + #ifdef CMS_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_CMS, CMS_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 46, 187}, + #endif + #ifdef CMS_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_CMS, CMS_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 46, 112}, + #endif + #ifdef CMS_R_ERROR_GETTING_PUBLIC_KEY + {"ERROR_GETTING_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_ERROR_GETTING_PUBLIC_KEY}, + #else + {"ERROR_GETTING_PUBLIC_KEY", 46, 113}, + #endif + #ifdef CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE}, + #else + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", 46, 114}, + #endif + #ifdef CMS_R_ERROR_SETTING_KEY + {"ERROR_SETTING_KEY", ERR_LIB_CMS, CMS_R_ERROR_SETTING_KEY}, + #else + {"ERROR_SETTING_KEY", 46, 115}, + #endif + #ifdef CMS_R_ERROR_SETTING_RECIPIENTINFO + {"ERROR_SETTING_RECIPIENTINFO", ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO}, + #else + {"ERROR_SETTING_RECIPIENTINFO", 46, 116}, + #endif + #ifdef CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR + {"ESS_SIGNING_CERTID_MISMATCH_ERROR", ERR_LIB_CMS, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR}, + #else + {"ESS_SIGNING_CERTID_MISMATCH_ERROR", 46, 183}, + #endif + #ifdef CMS_R_INVALID_ENCRYPTED_KEY_LENGTH + {"INVALID_ENCRYPTED_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH}, + #else + {"INVALID_ENCRYPTED_KEY_LENGTH", 46, 117}, + #endif + #ifdef CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER + {"INVALID_KEY_ENCRYPTION_PARAMETER", ERR_LIB_CMS, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER}, + #else + {"INVALID_KEY_ENCRYPTION_PARAMETER", 46, 176}, + #endif + #ifdef CMS_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 46, 118}, + #endif + #ifdef CMS_R_INVALID_LABEL + {"INVALID_LABEL", ERR_LIB_CMS, CMS_R_INVALID_LABEL}, + #else + {"INVALID_LABEL", 46, 190}, + #endif + #ifdef CMS_R_INVALID_OAEP_PARAMETERS + {"INVALID_OAEP_PARAMETERS", ERR_LIB_CMS, CMS_R_INVALID_OAEP_PARAMETERS}, + #else + {"INVALID_OAEP_PARAMETERS", 46, 191}, + #endif + #ifdef CMS_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 46, 186}, + #endif + #ifdef CMS_R_MD_BIO_INIT_ERROR + {"MD_BIO_INIT_ERROR", ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR}, + #else + {"MD_BIO_INIT_ERROR", 46, 119}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", 46, 120}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_WRONG_LENGTH + {"MESSAGEDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_WRONG_LENGTH", 46, 121}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_ERROR + {"MSGSIGDIGEST_ERROR", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR}, + #else + {"MSGSIGDIGEST_ERROR", 46, 172}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE + {"MSGSIGDIGEST_VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE}, + #else + {"MSGSIGDIGEST_VERIFICATION_FAILURE", 46, 162}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_WRONG_LENGTH + {"MSGSIGDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_WRONG_LENGTH}, + #else + {"MSGSIGDIGEST_WRONG_LENGTH", 46, 163}, + #endif + #ifdef CMS_R_NEED_ONE_SIGNER + {"NEED_ONE_SIGNER", ERR_LIB_CMS, CMS_R_NEED_ONE_SIGNER}, + #else + {"NEED_ONE_SIGNER", 46, 164}, + #endif + #ifdef CMS_R_NOT_A_SIGNED_RECEIPT + {"NOT_A_SIGNED_RECEIPT", ERR_LIB_CMS, CMS_R_NOT_A_SIGNED_RECEIPT}, + #else + {"NOT_A_SIGNED_RECEIPT", 46, 165}, + #endif + #ifdef CMS_R_NOT_ENCRYPTED_DATA + {"NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_NOT_ENCRYPTED_DATA}, + #else + {"NOT_ENCRYPTED_DATA", 46, 122}, + #endif + #ifdef CMS_R_NOT_KEK + {"NOT_KEK", ERR_LIB_CMS, CMS_R_NOT_KEK}, + #else + {"NOT_KEK", 46, 123}, + #endif + #ifdef CMS_R_NOT_KEY_AGREEMENT + {"NOT_KEY_AGREEMENT", ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT}, + #else + {"NOT_KEY_AGREEMENT", 46, 181}, + #endif + #ifdef CMS_R_NOT_KEY_TRANSPORT + {"NOT_KEY_TRANSPORT", ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT}, + #else + {"NOT_KEY_TRANSPORT", 46, 124}, + #endif + #ifdef CMS_R_NOT_PWRI + {"NOT_PWRI", ERR_LIB_CMS, CMS_R_NOT_PWRI}, + #else + {"NOT_PWRI", 46, 177}, + #endif + #ifdef CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 46, 125}, + #endif + #ifdef CMS_R_NO_CIPHER + {"NO_CIPHER", ERR_LIB_CMS, CMS_R_NO_CIPHER}, + #else + {"NO_CIPHER", 46, 126}, + #endif + #ifdef CMS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_CMS, CMS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 46, 127}, + #endif + #ifdef CMS_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 46, 173}, + #endif + #ifdef CMS_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 46, 128}, + #endif + #ifdef CMS_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_CMS, CMS_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 46, 129}, + #endif + #ifdef CMS_R_NO_KEY + {"NO_KEY", ERR_LIB_CMS, CMS_R_NO_KEY}, + #else + {"NO_KEY", 46, 130}, + #endif + #ifdef CMS_R_NO_KEY_OR_CERT + {"NO_KEY_OR_CERT", ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT}, + #else + {"NO_KEY_OR_CERT", 46, 174}, + #endif + #ifdef CMS_R_NO_MATCHING_DIGEST + {"NO_MATCHING_DIGEST", ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST}, + #else + {"NO_MATCHING_DIGEST", 46, 131}, + #endif + #ifdef CMS_R_NO_MATCHING_RECIPIENT + {"NO_MATCHING_RECIPIENT", ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT}, + #else + {"NO_MATCHING_RECIPIENT", 46, 132}, + #endif + #ifdef CMS_R_NO_MATCHING_SIGNATURE + {"NO_MATCHING_SIGNATURE", ERR_LIB_CMS, CMS_R_NO_MATCHING_SIGNATURE}, + #else + {"NO_MATCHING_SIGNATURE", 46, 166}, + #endif + #ifdef CMS_R_NO_MSGSIGDIGEST + {"NO_MSGSIGDIGEST", ERR_LIB_CMS, CMS_R_NO_MSGSIGDIGEST}, + #else + {"NO_MSGSIGDIGEST", 46, 167}, + #endif + #ifdef CMS_R_NO_PASSWORD + {"NO_PASSWORD", ERR_LIB_CMS, CMS_R_NO_PASSWORD}, + #else + {"NO_PASSWORD", 46, 178}, + #endif + #ifdef CMS_R_NO_PRIVATE_KEY + {"NO_PRIVATE_KEY", ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY}, + #else + {"NO_PRIVATE_KEY", 46, 133}, + #endif + #ifdef CMS_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 46, 134}, + #endif + #ifdef CMS_R_NO_RECEIPT_REQUEST + {"NO_RECEIPT_REQUEST", ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST}, + #else + {"NO_RECEIPT_REQUEST", 46, 168}, + #endif + #ifdef CMS_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_CMS, CMS_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 46, 135}, + #endif + #ifdef CMS_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_CMS, CMS_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 46, 188}, + #endif + #ifdef CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_CMS, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 46, 136}, + #endif + #ifdef CMS_R_RECEIPT_DECODE_ERROR + {"RECEIPT_DECODE_ERROR", ERR_LIB_CMS, CMS_R_RECEIPT_DECODE_ERROR}, + #else + {"RECEIPT_DECODE_ERROR", 46, 169}, + #endif + #ifdef CMS_R_RECIPIENT_ERROR + {"RECIPIENT_ERROR", ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR}, + #else + {"RECIPIENT_ERROR", 46, 137}, + #endif + #ifdef CMS_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_CMS, CMS_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 46, 189}, + #endif + #ifdef CMS_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 46, 138}, + #endif + #ifdef CMS_R_SIGNFINAL_ERROR + {"SIGNFINAL_ERROR", ERR_LIB_CMS, CMS_R_SIGNFINAL_ERROR}, + #else + {"SIGNFINAL_ERROR", 46, 139}, + #endif + #ifdef CMS_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 46, 140}, + #endif + #ifdef CMS_R_STORE_INIT_ERROR + {"STORE_INIT_ERROR", ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR}, + #else + {"STORE_INIT_ERROR", 46, 141}, + #endif + #ifdef CMS_R_TYPE_NOT_COMPRESSED_DATA + {"TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA}, + #else + {"TYPE_NOT_COMPRESSED_DATA", 46, 142}, + #endif + #ifdef CMS_R_TYPE_NOT_DATA + {"TYPE_NOT_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA}, + #else + {"TYPE_NOT_DATA", 46, 143}, + #endif + #ifdef CMS_R_TYPE_NOT_DIGESTED_DATA + {"TYPE_NOT_DIGESTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA}, + #else + {"TYPE_NOT_DIGESTED_DATA", 46, 144}, + #endif + #ifdef CMS_R_TYPE_NOT_ENCRYPTED_DATA + {"TYPE_NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA}, + #else + {"TYPE_NOT_ENCRYPTED_DATA", 46, 145}, + #endif + #ifdef CMS_R_TYPE_NOT_ENVELOPED_DATA + {"TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA}, + #else + {"TYPE_NOT_ENVELOPED_DATA", 46, 146}, + #endif + #ifdef CMS_R_UNABLE_TO_FINALIZE_CONTEXT + {"UNABLE_TO_FINALIZE_CONTEXT", ERR_LIB_CMS, CMS_R_UNABLE_TO_FINALIZE_CONTEXT}, + #else + {"UNABLE_TO_FINALIZE_CONTEXT", 46, 147}, + #endif + #ifdef CMS_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 46, 148}, + #endif + #ifdef CMS_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 46, 149}, + #endif + #ifdef CMS_R_UNKNOWN_ID + {"UNKNOWN_ID", ERR_LIB_CMS, CMS_R_UNKNOWN_ID}, + #else + {"UNKNOWN_ID", 46, 150}, + #endif + #ifdef CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM + {"UNSUPPORTED_COMPRESSION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM}, + #else + {"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151}, + #endif + #ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 46, 152}, + #endif + #ifdef CMS_R_UNSUPPORTED_ENCRYPTION_TYPE + {"UNSUPPORTED_ENCRYPTION_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE}, + #else + {"UNSUPPORTED_ENCRYPTION_TYPE", 46, 192}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEK_ALGORITHM + {"UNSUPPORTED_KEK_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEK_ALGORITHM}, + #else + {"UNSUPPORTED_KEK_ALGORITHM", 46, 153}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM}, + #else + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", 46, 179}, + #endif + #ifdef CMS_R_UNSUPPORTED_LABEL_SOURCE + {"UNSUPPORTED_LABEL_SOURCE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_LABEL_SOURCE}, + #else + {"UNSUPPORTED_LABEL_SOURCE", 46, 193}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + {"UNSUPPORTED_RECIPIENTINFO_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE}, + #else + {"UNSUPPORTED_RECIPIENTINFO_TYPE", 46, 155}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENT_TYPE + {"UNSUPPORTED_RECIPIENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENT_TYPE}, + #else + {"UNSUPPORTED_RECIPIENT_TYPE", 46, 154}, + #endif + #ifdef CMS_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 46, 156}, + #endif + #ifdef CMS_R_UNWRAP_ERROR + {"UNWRAP_ERROR", ERR_LIB_CMS, CMS_R_UNWRAP_ERROR}, + #else + {"UNWRAP_ERROR", 46, 157}, + #endif + #ifdef CMS_R_UNWRAP_FAILURE + {"UNWRAP_FAILURE", ERR_LIB_CMS, CMS_R_UNWRAP_FAILURE}, + #else + {"UNWRAP_FAILURE", 46, 180}, + #endif + #ifdef CMS_R_VERIFICATION_FAILURE + {"VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE}, + #else + {"VERIFICATION_FAILURE", 46, 158}, + #endif + #ifdef CMS_R_WRAP_ERROR + {"WRAP_ERROR", ERR_LIB_CMS, CMS_R_WRAP_ERROR}, + #else + {"WRAP_ERROR", 46, 159}, + #endif + #ifdef COMP_R_ZLIB_DEFLATE_ERROR + {"ZLIB_DEFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR}, + #else + {"ZLIB_DEFLATE_ERROR", 41, 99}, + #endif + #ifdef COMP_R_ZLIB_INFLATE_ERROR + {"ZLIB_INFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR}, + #else + {"ZLIB_INFLATE_ERROR", 41, 100}, + #endif + #ifdef COMP_R_ZLIB_NOT_SUPPORTED + {"ZLIB_NOT_SUPPORTED", ERR_LIB_COMP, COMP_R_ZLIB_NOT_SUPPORTED}, + #else + {"ZLIB_NOT_SUPPORTED", 41, 101}, + #endif + #ifdef CONF_R_ERROR_LOADING_DSO + {"ERROR_LOADING_DSO", ERR_LIB_CONF, CONF_R_ERROR_LOADING_DSO}, + #else + {"ERROR_LOADING_DSO", 14, 110}, + #endif + #ifdef CONF_R_INVALID_PRAGMA + {"INVALID_PRAGMA", ERR_LIB_CONF, CONF_R_INVALID_PRAGMA}, + #else + {"INVALID_PRAGMA", 14, 122}, + #endif + #ifdef CONF_R_LIST_CANNOT_BE_NULL + {"LIST_CANNOT_BE_NULL", ERR_LIB_CONF, CONF_R_LIST_CANNOT_BE_NULL}, + #else + {"LIST_CANNOT_BE_NULL", 14, 115}, + #endif + #ifdef CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION + {"MANDATORY_BRACES_IN_VARIABLE_EXPANSION", ERR_LIB_CONF, CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION}, + #else + {"MANDATORY_BRACES_IN_VARIABLE_EXPANSION", 14, 123}, + #endif + #ifdef CONF_R_MISSING_CLOSE_SQUARE_BRACKET + {"MISSING_CLOSE_SQUARE_BRACKET", ERR_LIB_CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET}, + #else + {"MISSING_CLOSE_SQUARE_BRACKET", 14, 100}, + #endif + #ifdef CONF_R_MISSING_EQUAL_SIGN + {"MISSING_EQUAL_SIGN", ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN}, + #else + {"MISSING_EQUAL_SIGN", 14, 101}, + #endif + #ifdef CONF_R_MISSING_INIT_FUNCTION + {"MISSING_INIT_FUNCTION", ERR_LIB_CONF, CONF_R_MISSING_INIT_FUNCTION}, + #else + {"MISSING_INIT_FUNCTION", 14, 112}, + #endif + #ifdef CONF_R_MODULE_INITIALIZATION_ERROR + {"MODULE_INITIALIZATION_ERROR", ERR_LIB_CONF, CONF_R_MODULE_INITIALIZATION_ERROR}, + #else + {"MODULE_INITIALIZATION_ERROR", 14, 109}, + #endif + #ifdef CONF_R_NO_CLOSE_BRACE + {"NO_CLOSE_BRACE", ERR_LIB_CONF, CONF_R_NO_CLOSE_BRACE}, + #else + {"NO_CLOSE_BRACE", 14, 102}, + #endif + #ifdef CONF_R_NO_CONF + {"NO_CONF", ERR_LIB_CONF, CONF_R_NO_CONF}, + #else + {"NO_CONF", 14, 105}, + #endif + #ifdef CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", ERR_LIB_CONF, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE}, + #else + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", 14, 106}, + #endif + #ifdef CONF_R_NO_SECTION + {"NO_SECTION", ERR_LIB_CONF, CONF_R_NO_SECTION}, + #else + {"NO_SECTION", 14, 107}, + #endif + #ifdef CONF_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_CONF, CONF_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 14, 114}, + #endif + #ifdef CONF_R_NO_VALUE + {"NO_VALUE", ERR_LIB_CONF, CONF_R_NO_VALUE}, + #else + {"NO_VALUE", 14, 108}, + #endif + #ifdef CONF_R_NUMBER_TOO_LARGE + {"NUMBER_TOO_LARGE", ERR_LIB_CONF, CONF_R_NUMBER_TOO_LARGE}, + #else + {"NUMBER_TOO_LARGE", 14, 121}, + #endif + #ifdef CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION + {"OPENSSL_CONF_REFERENCES_MISSING_SECTION", ERR_LIB_CONF, CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION}, + #else + {"OPENSSL_CONF_REFERENCES_MISSING_SECTION", 14, 124}, + #endif + #ifdef CONF_R_RECURSIVE_DIRECTORY_INCLUDE + {"RECURSIVE_DIRECTORY_INCLUDE", ERR_LIB_CONF, CONF_R_RECURSIVE_DIRECTORY_INCLUDE}, + #else + {"RECURSIVE_DIRECTORY_INCLUDE", 14, 111}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 14, 117}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #else + {"SSL_COMMAND_SECTION_NOT_FOUND", 14, 118}, + #endif + #ifdef CONF_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 14, 119}, + #endif + #ifdef CONF_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_SECTION_NOT_FOUND}, + #else + {"SSL_SECTION_NOT_FOUND", 14, 120}, + #endif + #ifdef CONF_R_UNABLE_TO_CREATE_NEW_SECTION + {"UNABLE_TO_CREATE_NEW_SECTION", ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION}, + #else + {"UNABLE_TO_CREATE_NEW_SECTION", 14, 103}, + #endif + #ifdef CONF_R_UNKNOWN_MODULE_NAME + {"UNKNOWN_MODULE_NAME", ERR_LIB_CONF, CONF_R_UNKNOWN_MODULE_NAME}, + #else + {"UNKNOWN_MODULE_NAME", 14, 113}, + #endif + #ifdef CONF_R_VARIABLE_EXPANSION_TOO_LONG + {"VARIABLE_EXPANSION_TOO_LONG", ERR_LIB_CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG}, + #else + {"VARIABLE_EXPANSION_TOO_LONG", 14, 116}, + #endif + #ifdef CONF_R_VARIABLE_HAS_NO_VALUE + {"VARIABLE_HAS_NO_VALUE", ERR_LIB_CONF, CONF_R_VARIABLE_HAS_NO_VALUE}, + #else + {"VARIABLE_HAS_NO_VALUE", 14, 104}, + #endif + #ifdef CRMF_R_BAD_PBM_ITERATIONCOUNT + {"BAD_PBM_ITERATIONCOUNT", ERR_LIB_CRMF, CRMF_R_BAD_PBM_ITERATIONCOUNT}, + #else + {"BAD_PBM_ITERATIONCOUNT", 56, 100}, + #endif + #ifdef CRMF_R_CRMFERROR + {"CRMFERROR", ERR_LIB_CRMF, CRMF_R_CRMFERROR}, + #else + {"CRMFERROR", 56, 102}, + #endif + #ifdef CRMF_R_ERROR + {"ERROR", ERR_LIB_CRMF, CRMF_R_ERROR}, + #else + {"ERROR", 56, 103}, + #endif + #ifdef CRMF_R_ERROR_DECODING_CERTIFICATE + {"ERROR_DECODING_CERTIFICATE", ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_CERTIFICATE}, + #else + {"ERROR_DECODING_CERTIFICATE", 56, 104}, + #endif + #ifdef CRMF_R_ERROR_DECRYPTING_CERTIFICATE + {"ERROR_DECRYPTING_CERTIFICATE", ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_CERTIFICATE}, + #else + {"ERROR_DECRYPTING_CERTIFICATE", 56, 105}, + #endif + #ifdef CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY + {"ERROR_DECRYPTING_SYMMETRIC_KEY", ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY}, + #else + {"ERROR_DECRYPTING_SYMMETRIC_KEY", 56, 106}, + #endif + #ifdef CRMF_R_FAILURE_OBTAINING_RANDOM + {"FAILURE_OBTAINING_RANDOM", ERR_LIB_CRMF, CRMF_R_FAILURE_OBTAINING_RANDOM}, + #else + {"FAILURE_OBTAINING_RANDOM", 56, 107}, + #endif + #ifdef CRMF_R_ITERATIONCOUNT_BELOW_100 + {"ITERATIONCOUNT_BELOW_100", ERR_LIB_CRMF, CRMF_R_ITERATIONCOUNT_BELOW_100}, + #else + {"ITERATIONCOUNT_BELOW_100", 56, 108}, + #endif + #ifdef CRMF_R_MALFORMED_IV + {"MALFORMED_IV", ERR_LIB_CRMF, CRMF_R_MALFORMED_IV}, + #else + {"MALFORMED_IV", 56, 101}, + #endif + #ifdef CRMF_R_NULL_ARGUMENT + {"NULL_ARGUMENT", ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT}, + #else + {"NULL_ARGUMENT", 56, 109}, + #endif + #ifdef CRMF_R_POPOSKINPUT_NOT_SUPPORTED + {"POPOSKINPUT_NOT_SUPPORTED", ERR_LIB_CRMF, CRMF_R_POPOSKINPUT_NOT_SUPPORTED}, + #else + {"POPOSKINPUT_NOT_SUPPORTED", 56, 113}, + #endif + #ifdef CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY + {"POPO_INCONSISTENT_PUBLIC_KEY", ERR_LIB_CRMF, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY}, + #else + {"POPO_INCONSISTENT_PUBLIC_KEY", 56, 117}, + #endif + #ifdef CRMF_R_POPO_MISSING + {"POPO_MISSING", ERR_LIB_CRMF, CRMF_R_POPO_MISSING}, + #else + {"POPO_MISSING", 56, 121}, + #endif + #ifdef CRMF_R_POPO_MISSING_PUBLIC_KEY + {"POPO_MISSING_PUBLIC_KEY", ERR_LIB_CRMF, CRMF_R_POPO_MISSING_PUBLIC_KEY}, + #else + {"POPO_MISSING_PUBLIC_KEY", 56, 118}, + #endif + #ifdef CRMF_R_POPO_MISSING_SUBJECT + {"POPO_MISSING_SUBJECT", ERR_LIB_CRMF, CRMF_R_POPO_MISSING_SUBJECT}, + #else + {"POPO_MISSING_SUBJECT", 56, 119}, + #endif + #ifdef CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED + {"POPO_RAVERIFIED_NOT_ACCEPTED", ERR_LIB_CRMF, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED}, + #else + {"POPO_RAVERIFIED_NOT_ACCEPTED", 56, 120}, + #endif + #ifdef CRMF_R_SETTING_MAC_ALGOR_FAILURE + {"SETTING_MAC_ALGOR_FAILURE", ERR_LIB_CRMF, CRMF_R_SETTING_MAC_ALGOR_FAILURE}, + #else + {"SETTING_MAC_ALGOR_FAILURE", 56, 110}, + #endif + #ifdef CRMF_R_SETTING_OWF_ALGOR_FAILURE + {"SETTING_OWF_ALGOR_FAILURE", ERR_LIB_CRMF, CRMF_R_SETTING_OWF_ALGOR_FAILURE}, + #else + {"SETTING_OWF_ALGOR_FAILURE", 56, 111}, + #endif + #ifdef CRMF_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 56, 112}, + #endif + #ifdef CRMF_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 56, 114}, + #endif + #ifdef CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO + {"UNSUPPORTED_METHOD_FOR_CREATING_POPO", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO}, + #else + {"UNSUPPORTED_METHOD_FOR_CREATING_POPO", 56, 115}, + #endif + #ifdef CRMF_R_UNSUPPORTED_POPO_METHOD + {"UNSUPPORTED_POPO_METHOD", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_POPO_METHOD}, + #else + {"UNSUPPORTED_POPO_METHOD", 56, 116}, + #endif + #ifdef CRYPTO_R_BAD_ALGORITHM_NAME + {"BAD_ALGORITHM_NAME", ERR_LIB_CRYPTO, CRYPTO_R_BAD_ALGORITHM_NAME}, + #else + {"BAD_ALGORITHM_NAME", 15, 117}, + #endif + #ifdef CRYPTO_R_CONFLICTING_NAMES + {"CONFLICTING_NAMES", ERR_LIB_CRYPTO, CRYPTO_R_CONFLICTING_NAMES}, + #else + {"CONFLICTING_NAMES", 15, 118}, + #endif + #ifdef CRYPTO_R_FIPS_MODE_NOT_SUPPORTED + {"FIPS_MODE_NOT_SUPPORTED", ERR_LIB_CRYPTO, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED}, + #else + {"FIPS_MODE_NOT_SUPPORTED", 15, 101}, + #endif + #ifdef CRYPTO_R_HEX_STRING_TOO_SHORT + {"HEX_STRING_TOO_SHORT", ERR_LIB_CRYPTO, CRYPTO_R_HEX_STRING_TOO_SHORT}, + #else + {"HEX_STRING_TOO_SHORT", 15, 121}, + #endif + #ifdef CRYPTO_R_ILLEGAL_HEX_DIGIT + {"ILLEGAL_HEX_DIGIT", ERR_LIB_CRYPTO, CRYPTO_R_ILLEGAL_HEX_DIGIT}, + #else + {"ILLEGAL_HEX_DIGIT", 15, 102}, + #endif + #ifdef CRYPTO_R_INSUFFICIENT_DATA_SPACE + {"INSUFFICIENT_DATA_SPACE", ERR_LIB_CRYPTO, CRYPTO_R_INSUFFICIENT_DATA_SPACE}, + #else + {"INSUFFICIENT_DATA_SPACE", 15, 106}, + #endif + #ifdef CRYPTO_R_INSUFFICIENT_PARAM_SIZE + {"INSUFFICIENT_PARAM_SIZE", ERR_LIB_CRYPTO, CRYPTO_R_INSUFFICIENT_PARAM_SIZE}, + #else + {"INSUFFICIENT_PARAM_SIZE", 15, 107}, + #endif + #ifdef CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE + {"INSUFFICIENT_SECURE_DATA_SPACE", ERR_LIB_CRYPTO, CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE}, + #else + {"INSUFFICIENT_SECURE_DATA_SPACE", 15, 108}, + #endif + #ifdef CRYPTO_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 15, 109}, + #endif + #ifdef CRYPTO_R_INVALID_OSSL_PARAM_TYPE + {"INVALID_OSSL_PARAM_TYPE", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_OSSL_PARAM_TYPE}, + #else + {"INVALID_OSSL_PARAM_TYPE", 15, 110}, + #endif + #ifdef CRYPTO_R_ODD_NUMBER_OF_DIGITS + {"ODD_NUMBER_OF_DIGITS", ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS}, + #else + {"ODD_NUMBER_OF_DIGITS", 15, 103}, + #endif + #ifdef CRYPTO_R_PROVIDER_ALREADY_EXISTS + {"PROVIDER_ALREADY_EXISTS", ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_ALREADY_EXISTS}, + #else + {"PROVIDER_ALREADY_EXISTS", 15, 104}, + #endif + #ifdef CRYPTO_R_PROVIDER_SECTION_ERROR + {"PROVIDER_SECTION_ERROR", ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR}, + #else + {"PROVIDER_SECTION_ERROR", 15, 105}, + #endif + #ifdef CRYPTO_R_RANDOM_SECTION_ERROR + {"RANDOM_SECTION_ERROR", ERR_LIB_CRYPTO, CRYPTO_R_RANDOM_SECTION_ERROR}, + #else + {"RANDOM_SECTION_ERROR", 15, 119}, + #endif + #ifdef CRYPTO_R_SECURE_MALLOC_FAILURE + {"SECURE_MALLOC_FAILURE", ERR_LIB_CRYPTO, CRYPTO_R_SECURE_MALLOC_FAILURE}, + #else + {"SECURE_MALLOC_FAILURE", 15, 111}, + #endif + #ifdef CRYPTO_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 15, 112}, + #endif + #ifdef CRYPTO_R_TOO_MANY_BYTES + {"TOO_MANY_BYTES", ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES}, + #else + {"TOO_MANY_BYTES", 15, 113}, + #endif + #ifdef CRYPTO_R_TOO_MANY_RECORDS + {"TOO_MANY_RECORDS", ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS}, + #else + {"TOO_MANY_RECORDS", 15, 114}, + #endif + #ifdef CRYPTO_R_TOO_SMALL_BUFFER + {"TOO_SMALL_BUFFER", ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER}, + #else + {"TOO_SMALL_BUFFER", 15, 116}, + #endif + #ifdef CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION + {"UNKNOWN_NAME_IN_RANDOM_SECTION", ERR_LIB_CRYPTO, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION}, + #else + {"UNKNOWN_NAME_IN_RANDOM_SECTION", 15, 120}, + #endif + #ifdef CRYPTO_R_ZERO_LENGTH_NUMBER + {"ZERO_LENGTH_NUMBER", ERR_LIB_CRYPTO, CRYPTO_R_ZERO_LENGTH_NUMBER}, + #else + {"ZERO_LENGTH_NUMBER", 15, 115}, + #endif + #ifdef CT_R_BASE64_DECODE_ERROR + {"BASE64_DECODE_ERROR", ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR}, + #else + {"BASE64_DECODE_ERROR", 50, 108}, + #endif + #ifdef CT_R_INVALID_LOG_ID_LENGTH + {"INVALID_LOG_ID_LENGTH", ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH}, + #else + {"INVALID_LOG_ID_LENGTH", 50, 100}, + #endif + #ifdef CT_R_LOG_CONF_INVALID + {"LOG_CONF_INVALID", ERR_LIB_CT, CT_R_LOG_CONF_INVALID}, + #else + {"LOG_CONF_INVALID", 50, 109}, + #endif + #ifdef CT_R_LOG_CONF_INVALID_KEY + {"LOG_CONF_INVALID_KEY", ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY}, + #else + {"LOG_CONF_INVALID_KEY", 50, 110}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_DESCRIPTION + {"LOG_CONF_MISSING_DESCRIPTION", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_DESCRIPTION}, + #else + {"LOG_CONF_MISSING_DESCRIPTION", 50, 111}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_KEY + {"LOG_CONF_MISSING_KEY", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_KEY}, + #else + {"LOG_CONF_MISSING_KEY", 50, 112}, + #endif + #ifdef CT_R_LOG_KEY_INVALID + {"LOG_KEY_INVALID", ERR_LIB_CT, CT_R_LOG_KEY_INVALID}, + #else + {"LOG_KEY_INVALID", 50, 113}, + #endif + #ifdef CT_R_SCT_FUTURE_TIMESTAMP + {"SCT_FUTURE_TIMESTAMP", ERR_LIB_CT, CT_R_SCT_FUTURE_TIMESTAMP}, + #else + {"SCT_FUTURE_TIMESTAMP", 50, 116}, + #endif + #ifdef CT_R_SCT_INVALID + {"SCT_INVALID", ERR_LIB_CT, CT_R_SCT_INVALID}, + #else + {"SCT_INVALID", 50, 104}, + #endif + #ifdef CT_R_SCT_INVALID_SIGNATURE + {"SCT_INVALID_SIGNATURE", ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE}, + #else + {"SCT_INVALID_SIGNATURE", 50, 107}, + #endif + #ifdef CT_R_SCT_LIST_INVALID + {"SCT_LIST_INVALID", ERR_LIB_CT, CT_R_SCT_LIST_INVALID}, + #else + {"SCT_LIST_INVALID", 50, 105}, + #endif + #ifdef CT_R_SCT_LOG_ID_MISMATCH + {"SCT_LOG_ID_MISMATCH", ERR_LIB_CT, CT_R_SCT_LOG_ID_MISMATCH}, + #else + {"SCT_LOG_ID_MISMATCH", 50, 114}, + #endif + #ifdef CT_R_SCT_NOT_SET + {"SCT_NOT_SET", ERR_LIB_CT, CT_R_SCT_NOT_SET}, + #else + {"SCT_NOT_SET", 50, 106}, + #endif + #ifdef CT_R_SCT_UNSUPPORTED_VERSION + {"SCT_UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_SCT_UNSUPPORTED_VERSION}, + #else + {"SCT_UNSUPPORTED_VERSION", 50, 115}, + #endif + #ifdef CT_R_UNRECOGNIZED_SIGNATURE_NID + {"UNRECOGNIZED_SIGNATURE_NID", ERR_LIB_CT, CT_R_UNRECOGNIZED_SIGNATURE_NID}, + #else + {"UNRECOGNIZED_SIGNATURE_NID", 50, 101}, + #endif + #ifdef CT_R_UNSUPPORTED_ENTRY_TYPE + {"UNSUPPORTED_ENTRY_TYPE", ERR_LIB_CT, CT_R_UNSUPPORTED_ENTRY_TYPE}, + #else + {"UNSUPPORTED_ENTRY_TYPE", 50, 102}, + #endif + #ifdef CT_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 50, 103}, + #endif + #ifdef DH_R_BAD_FFC_PARAMETERS + {"BAD_FFC_PARAMETERS", ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS}, + #else + {"BAD_FFC_PARAMETERS", 5, 127}, + #endif + #ifdef DH_R_BAD_GENERATOR + {"BAD_GENERATOR", ERR_LIB_DH, DH_R_BAD_GENERATOR}, + #else + {"BAD_GENERATOR", 5, 101}, + #endif + #ifdef DH_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DH, DH_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 5, 109}, + #endif + #ifdef DH_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DH, DH_R_BN_ERROR}, + #else + {"BN_ERROR", 5, 106}, + #endif + #ifdef DH_R_CHECK_INVALID_J_VALUE + {"CHECK_INVALID_J_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_J_VALUE}, + #else + {"CHECK_INVALID_J_VALUE", 5, 115}, + #endif + #ifdef DH_R_CHECK_INVALID_Q_VALUE + {"CHECK_INVALID_Q_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_Q_VALUE}, + #else + {"CHECK_INVALID_Q_VALUE", 5, 116}, + #endif + #ifdef DH_R_CHECK_PUBKEY_INVALID + {"CHECK_PUBKEY_INVALID", ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID}, + #else + {"CHECK_PUBKEY_INVALID", 5, 122}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_LARGE + {"CHECK_PUBKEY_TOO_LARGE", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_LARGE}, + #else + {"CHECK_PUBKEY_TOO_LARGE", 5, 123}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_SMALL + {"CHECK_PUBKEY_TOO_SMALL", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_SMALL}, + #else + {"CHECK_PUBKEY_TOO_SMALL", 5, 124}, + #endif + #ifdef DH_R_CHECK_P_NOT_PRIME + {"CHECK_P_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME}, + #else + {"CHECK_P_NOT_PRIME", 5, 117}, + #endif + #ifdef DH_R_CHECK_P_NOT_SAFE_PRIME + {"CHECK_P_NOT_SAFE_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_SAFE_PRIME}, + #else + {"CHECK_P_NOT_SAFE_PRIME", 5, 118}, + #endif + #ifdef DH_R_CHECK_Q_NOT_PRIME + {"CHECK_Q_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_Q_NOT_PRIME}, + #else + {"CHECK_Q_NOT_PRIME", 5, 119}, + #endif + #ifdef DH_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DH, DH_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 5, 104}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NAME + {"INVALID_PARAMETER_NAME", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME}, + #else + {"INVALID_PARAMETER_NAME", 5, 110}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NID + {"INVALID_PARAMETER_NID", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID}, + #else + {"INVALID_PARAMETER_NID", 5, 114}, + #endif + #ifdef DH_R_INVALID_PUBKEY + {"INVALID_PUBKEY", ERR_LIB_DH, DH_R_INVALID_PUBKEY}, + #else + {"INVALID_PUBKEY", 5, 102}, + #endif + #ifdef DH_R_INVALID_SECRET + {"INVALID_SECRET", ERR_LIB_DH, DH_R_INVALID_SECRET}, + #else + {"INVALID_SECRET", 5, 128}, + #endif + #ifdef DH_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_DH, DH_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 5, 112}, + #endif + #ifdef DH_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_DH, DH_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 5, 108}, + #endif + #ifdef DH_R_MISSING_PUBKEY + {"MISSING_PUBKEY", ERR_LIB_DH, DH_R_MISSING_PUBKEY}, + #else + {"MISSING_PUBKEY", 5, 125}, + #endif + #ifdef DH_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 5, 103}, + #endif + #ifdef DH_R_MODULUS_TOO_SMALL + {"MODULUS_TOO_SMALL", ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL}, + #else + {"MODULUS_TOO_SMALL", 5, 126}, + #endif + #ifdef DH_R_NOT_SUITABLE_GENERATOR + {"NOT_SUITABLE_GENERATOR", ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR}, + #else + {"NOT_SUITABLE_GENERATOR", 5, 120}, + #endif + #ifdef DH_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DH, DH_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 5, 107}, + #endif + #ifdef DH_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_DH, DH_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 5, 100}, + #endif + #ifdef DH_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DH, DH_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 5, 105}, + #endif + #ifdef DH_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_DH, DH_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 5, 111}, + #endif + #ifdef DH_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_DH, DH_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 5, 113}, + #endif + #ifdef DH_R_UNABLE_TO_CHECK_GENERATOR + {"UNABLE_TO_CHECK_GENERATOR", ERR_LIB_DH, DH_R_UNABLE_TO_CHECK_GENERATOR}, + #else + {"UNABLE_TO_CHECK_GENERATOR", 5, 121}, + #endif + #ifdef DSA_R_BAD_FFC_PARAMETERS + {"BAD_FFC_PARAMETERS", ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS}, + #else + {"BAD_FFC_PARAMETERS", 10, 114}, + #endif + #ifdef DSA_R_BAD_Q_VALUE + {"BAD_Q_VALUE", ERR_LIB_DSA, DSA_R_BAD_Q_VALUE}, + #else + {"BAD_Q_VALUE", 10, 102}, + #endif + #ifdef DSA_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DSA, DSA_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 10, 108}, + #endif + #ifdef DSA_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DSA, DSA_R_BN_ERROR}, + #else + {"BN_ERROR", 10, 109}, + #endif + #ifdef DSA_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DSA, DSA_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 10, 104}, + #endif + #ifdef DSA_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 10, 106}, + #endif + #ifdef DSA_R_INVALID_PARAMETERS + {"INVALID_PARAMETERS", ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS}, + #else + {"INVALID_PARAMETERS", 10, 112}, + #endif + #ifdef DSA_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 10, 101}, + #endif + #ifdef DSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_DSA, DSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 10, 111}, + #endif + #ifdef DSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 10, 103}, + #endif + #ifdef DSA_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 10, 107}, + #endif + #ifdef DSA_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 10, 105}, + #endif + #ifdef DSA_R_P_NOT_PRIME + {"P_NOT_PRIME", ERR_LIB_DSA, DSA_R_P_NOT_PRIME}, + #else + {"P_NOT_PRIME", 10, 115}, + #endif + #ifdef DSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_DSA, DSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 10, 113}, + #endif + #ifdef DSA_R_SEED_LEN_SMALL + {"SEED_LEN_SMALL", ERR_LIB_DSA, DSA_R_SEED_LEN_SMALL}, + #else + {"SEED_LEN_SMALL", 10, 110}, + #endif + #ifdef DSO_R_CTRL_FAILED + {"CTRL_FAILED", ERR_LIB_DSO, DSO_R_CTRL_FAILED}, + #else + {"CTRL_FAILED", 37, 100}, + #endif + #ifdef DSO_R_DSO_ALREADY_LOADED + {"DSO_ALREADY_LOADED", ERR_LIB_DSO, DSO_R_DSO_ALREADY_LOADED}, + #else + {"DSO_ALREADY_LOADED", 37, 110}, + #endif + #ifdef DSO_R_EMPTY_FILE_STRUCTURE + {"EMPTY_FILE_STRUCTURE", ERR_LIB_DSO, DSO_R_EMPTY_FILE_STRUCTURE}, + #else + {"EMPTY_FILE_STRUCTURE", 37, 113}, + #endif + #ifdef DSO_R_FAILURE + {"FAILURE", ERR_LIB_DSO, DSO_R_FAILURE}, + #else + {"FAILURE", 37, 114}, + #endif + #ifdef DSO_R_FILENAME_TOO_BIG + {"FILENAME_TOO_BIG", ERR_LIB_DSO, DSO_R_FILENAME_TOO_BIG}, + #else + {"FILENAME_TOO_BIG", 37, 101}, + #endif + #ifdef DSO_R_FINISH_FAILED + {"FINISH_FAILED", ERR_LIB_DSO, DSO_R_FINISH_FAILED}, + #else + {"FINISH_FAILED", 37, 102}, + #endif + #ifdef DSO_R_INCORRECT_FILE_SYNTAX + {"INCORRECT_FILE_SYNTAX", ERR_LIB_DSO, DSO_R_INCORRECT_FILE_SYNTAX}, + #else + {"INCORRECT_FILE_SYNTAX", 37, 115}, + #endif + #ifdef DSO_R_LOAD_FAILED + {"LOAD_FAILED", ERR_LIB_DSO, DSO_R_LOAD_FAILED}, + #else + {"LOAD_FAILED", 37, 103}, + #endif + #ifdef DSO_R_NAME_TRANSLATION_FAILED + {"NAME_TRANSLATION_FAILED", ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED}, + #else + {"NAME_TRANSLATION_FAILED", 37, 109}, + #endif + #ifdef DSO_R_NO_FILENAME + {"NO_FILENAME", ERR_LIB_DSO, DSO_R_NO_FILENAME}, + #else + {"NO_FILENAME", 37, 111}, + #endif + #ifdef DSO_R_NULL_HANDLE + {"NULL_HANDLE", ERR_LIB_DSO, DSO_R_NULL_HANDLE}, + #else + {"NULL_HANDLE", 37, 104}, + #endif + #ifdef DSO_R_SET_FILENAME_FAILED + {"SET_FILENAME_FAILED", ERR_LIB_DSO, DSO_R_SET_FILENAME_FAILED}, + #else + {"SET_FILENAME_FAILED", 37, 112}, + #endif + #ifdef DSO_R_STACK_ERROR + {"STACK_ERROR", ERR_LIB_DSO, DSO_R_STACK_ERROR}, + #else + {"STACK_ERROR", 37, 105}, + #endif + #ifdef DSO_R_SYM_FAILURE + {"SYM_FAILURE", ERR_LIB_DSO, DSO_R_SYM_FAILURE}, + #else + {"SYM_FAILURE", 37, 106}, + #endif + #ifdef DSO_R_UNLOAD_FAILED + {"UNLOAD_FAILED", ERR_LIB_DSO, DSO_R_UNLOAD_FAILED}, + #else + {"UNLOAD_FAILED", 37, 107}, + #endif + #ifdef DSO_R_UNSUPPORTED + {"UNSUPPORTED", ERR_LIB_DSO, DSO_R_UNSUPPORTED}, + #else + {"UNSUPPORTED", 37, 108}, + #endif + #ifdef EC_R_ASN1_ERROR + {"ASN1_ERROR", ERR_LIB_EC, EC_R_ASN1_ERROR}, + #else + {"ASN1_ERROR", 16, 115}, + #endif + #ifdef EC_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_EC, EC_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 16, 156}, + #endif + #ifdef EC_R_BIGNUM_OUT_OF_RANGE + {"BIGNUM_OUT_OF_RANGE", ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE}, + #else + {"BIGNUM_OUT_OF_RANGE", 16, 144}, + #endif + #ifdef EC_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 16, 100}, + #endif + #ifdef EC_R_CANNOT_INVERT + {"CANNOT_INVERT", ERR_LIB_EC, EC_R_CANNOT_INVERT}, + #else + {"CANNOT_INVERT", 16, 165}, + #endif + #ifdef EC_R_COORDINATES_OUT_OF_RANGE + {"COORDINATES_OUT_OF_RANGE", ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE}, + #else + {"COORDINATES_OUT_OF_RANGE", 16, 146}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_ECDH + {"CURVE_DOES_NOT_SUPPORT_ECDH", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH}, + #else + {"CURVE_DOES_NOT_SUPPORT_ECDH", 16, 160}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA + {"CURVE_DOES_NOT_SUPPORT_ECDSA", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA}, + #else + {"CURVE_DOES_NOT_SUPPORT_ECDSA", 16, 170}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING + {"CURVE_DOES_NOT_SUPPORT_SIGNING", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING}, + #else + {"CURVE_DOES_NOT_SUPPORT_SIGNING", 16, 159}, + #endif + #ifdef EC_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EC, EC_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 16, 142}, + #endif + #ifdef EC_R_DISCRIMINANT_IS_ZERO + {"DISCRIMINANT_IS_ZERO", ERR_LIB_EC, EC_R_DISCRIMINANT_IS_ZERO}, + #else + {"DISCRIMINANT_IS_ZERO", 16, 118}, + #endif + #ifdef EC_R_EC_GROUP_NEW_BY_NAME_FAILURE + {"EC_GROUP_NEW_BY_NAME_FAILURE", ERR_LIB_EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE}, + #else + {"EC_GROUP_NEW_BY_NAME_FAILURE", 16, 119}, + #endif + #ifdef EC_R_FAILED_MAKING_PUBLIC_KEY + {"FAILED_MAKING_PUBLIC_KEY", ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY}, + #else + {"FAILED_MAKING_PUBLIC_KEY", 16, 166}, + #endif + #ifdef EC_R_FIELD_TOO_LARGE + {"FIELD_TOO_LARGE", ERR_LIB_EC, EC_R_FIELD_TOO_LARGE}, + #else + {"FIELD_TOO_LARGE", 16, 143}, + #endif + #ifdef EC_R_GF2M_NOT_SUPPORTED + {"GF2M_NOT_SUPPORTED", ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED}, + #else + {"GF2M_NOT_SUPPORTED", 16, 147}, + #endif + #ifdef EC_R_GROUP2PKPARAMETERS_FAILURE + {"GROUP2PKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_GROUP2PKPARAMETERS_FAILURE}, + #else + {"GROUP2PKPARAMETERS_FAILURE", 16, 120}, + #endif + #ifdef EC_R_I2D_ECPKPARAMETERS_FAILURE + {"I2D_ECPKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_I2D_ECPKPARAMETERS_FAILURE}, + #else + {"I2D_ECPKPARAMETERS_FAILURE", 16, 121}, + #endif + #ifdef EC_R_INCOMPATIBLE_OBJECTS + {"INCOMPATIBLE_OBJECTS", ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS}, + #else + {"INCOMPATIBLE_OBJECTS", 16, 101}, + #endif + #ifdef EC_R_INVALID_A + {"INVALID_A", ERR_LIB_EC, EC_R_INVALID_A}, + #else + {"INVALID_A", 16, 168}, + #endif + #ifdef EC_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_EC, EC_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 16, 112}, + #endif + #ifdef EC_R_INVALID_B + {"INVALID_B", ERR_LIB_EC, EC_R_INVALID_B}, + #else + {"INVALID_B", 16, 169}, + #endif + #ifdef EC_R_INVALID_COFACTOR + {"INVALID_COFACTOR", ERR_LIB_EC, EC_R_INVALID_COFACTOR}, + #else + {"INVALID_COFACTOR", 16, 171}, + #endif + #ifdef EC_R_INVALID_COMPRESSED_POINT + {"INVALID_COMPRESSED_POINT", ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT}, + #else + {"INVALID_COMPRESSED_POINT", 16, 110}, + #endif + #ifdef EC_R_INVALID_COMPRESSION_BIT + {"INVALID_COMPRESSION_BIT", ERR_LIB_EC, EC_R_INVALID_COMPRESSION_BIT}, + #else + {"INVALID_COMPRESSION_BIT", 16, 109}, + #endif + #ifdef EC_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_EC, EC_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 16, 141}, + #endif + #ifdef EC_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EC, EC_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 16, 151}, + #endif + #ifdef EC_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 16, 138}, + #endif + #ifdef EC_R_INVALID_ENCODING + {"INVALID_ENCODING", ERR_LIB_EC, EC_R_INVALID_ENCODING}, + #else + {"INVALID_ENCODING", 16, 102}, + #endif + #ifdef EC_R_INVALID_FIELD + {"INVALID_FIELD", ERR_LIB_EC, EC_R_INVALID_FIELD}, + #else + {"INVALID_FIELD", 16, 103}, + #endif + #ifdef EC_R_INVALID_FORM + {"INVALID_FORM", ERR_LIB_EC, EC_R_INVALID_FORM}, + #else + {"INVALID_FORM", 16, 104}, + #endif + #ifdef EC_R_INVALID_GENERATOR + {"INVALID_GENERATOR", ERR_LIB_EC, EC_R_INVALID_GENERATOR}, + #else + {"INVALID_GENERATOR", 16, 173}, + #endif + #ifdef EC_R_INVALID_GROUP_ORDER + {"INVALID_GROUP_ORDER", ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER}, + #else + {"INVALID_GROUP_ORDER", 16, 122}, + #endif + #ifdef EC_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EC, EC_R_INVALID_KEY}, + #else + {"INVALID_KEY", 16, 116}, + #endif + #ifdef EC_R_INVALID_NAMED_GROUP_CONVERSION + {"INVALID_NAMED_GROUP_CONVERSION", ERR_LIB_EC, EC_R_INVALID_NAMED_GROUP_CONVERSION}, + #else + {"INVALID_NAMED_GROUP_CONVERSION", 16, 174}, + #endif + #ifdef EC_R_INVALID_OUTPUT_LENGTH + {"INVALID_OUTPUT_LENGTH", ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH}, + #else + {"INVALID_OUTPUT_LENGTH", 16, 161}, + #endif + #ifdef EC_R_INVALID_P + {"INVALID_P", ERR_LIB_EC, EC_R_INVALID_P}, + #else + {"INVALID_P", 16, 172}, + #endif + #ifdef EC_R_INVALID_PEER_KEY + {"INVALID_PEER_KEY", ERR_LIB_EC, EC_R_INVALID_PEER_KEY}, + #else + {"INVALID_PEER_KEY", 16, 133}, + #endif + #ifdef EC_R_INVALID_PENTANOMIAL_BASIS + {"INVALID_PENTANOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_PENTANOMIAL_BASIS}, + #else + {"INVALID_PENTANOMIAL_BASIS", 16, 132}, + #endif + #ifdef EC_R_INVALID_PRIVATE_KEY + {"INVALID_PRIVATE_KEY", ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY}, + #else + {"INVALID_PRIVATE_KEY", 16, 123}, + #endif + #ifdef EC_R_INVALID_SEED + {"INVALID_SEED", ERR_LIB_EC, EC_R_INVALID_SEED}, + #else + {"INVALID_SEED", 16, 175}, + #endif + #ifdef EC_R_INVALID_TRINOMIAL_BASIS + {"INVALID_TRINOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_TRINOMIAL_BASIS}, + #else + {"INVALID_TRINOMIAL_BASIS", 16, 137}, + #endif + #ifdef EC_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_EC, EC_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 16, 148}, + #endif + #ifdef EC_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_EC, EC_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 16, 140}, + #endif + #ifdef EC_R_LADDER_POST_FAILURE + {"LADDER_POST_FAILURE", ERR_LIB_EC, EC_R_LADDER_POST_FAILURE}, + #else + {"LADDER_POST_FAILURE", 16, 136}, + #endif + #ifdef EC_R_LADDER_PRE_FAILURE + {"LADDER_PRE_FAILURE", ERR_LIB_EC, EC_R_LADDER_PRE_FAILURE}, + #else + {"LADDER_PRE_FAILURE", 16, 153}, + #endif + #ifdef EC_R_LADDER_STEP_FAILURE + {"LADDER_STEP_FAILURE", ERR_LIB_EC, EC_R_LADDER_STEP_FAILURE}, + #else + {"LADDER_STEP_FAILURE", 16, 162}, + #endif + #ifdef EC_R_MISSING_OID + {"MISSING_OID", ERR_LIB_EC, EC_R_MISSING_OID}, + #else + {"MISSING_OID", 16, 167}, + #endif + #ifdef EC_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EC, EC_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 16, 124}, + #endif + #ifdef EC_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 16, 125}, + #endif + #ifdef EC_R_NEED_NEW_SETUP_VALUES + {"NEED_NEW_SETUP_VALUES", ERR_LIB_EC, EC_R_NEED_NEW_SETUP_VALUES}, + #else + {"NEED_NEW_SETUP_VALUES", 16, 157}, + #endif + #ifdef EC_R_NOT_A_NIST_PRIME + {"NOT_A_NIST_PRIME", ERR_LIB_EC, EC_R_NOT_A_NIST_PRIME}, + #else + {"NOT_A_NIST_PRIME", 16, 135}, + #endif + #ifdef EC_R_NOT_IMPLEMENTED + {"NOT_IMPLEMENTED", ERR_LIB_EC, EC_R_NOT_IMPLEMENTED}, + #else + {"NOT_IMPLEMENTED", 16, 126}, + #endif + #ifdef EC_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_EC, EC_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 16, 111}, + #endif + #ifdef EC_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_EC, EC_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 16, 139}, + #endif + #ifdef EC_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_EC, EC_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 16, 154}, + #endif + #ifdef EC_R_OPERATION_NOT_SUPPORTED + {"OPERATION_NOT_SUPPORTED", ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED}, + #else + {"OPERATION_NOT_SUPPORTED", 16, 152}, + #endif + #ifdef EC_R_PASSED_NULL_PARAMETER + {"PASSED_NULL_PARAMETER", ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER}, + #else + {"PASSED_NULL_PARAMETER", 16, 134}, + #endif + #ifdef EC_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_EC, EC_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 16, 149}, + #endif + #ifdef EC_R_POINT_ARITHMETIC_FAILURE + {"POINT_ARITHMETIC_FAILURE", ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE}, + #else + {"POINT_ARITHMETIC_FAILURE", 16, 155}, + #endif + #ifdef EC_R_POINT_AT_INFINITY + {"POINT_AT_INFINITY", ERR_LIB_EC, EC_R_POINT_AT_INFINITY}, + #else + {"POINT_AT_INFINITY", 16, 106}, + #endif + #ifdef EC_R_POINT_COORDINATES_BLIND_FAILURE + {"POINT_COORDINATES_BLIND_FAILURE", ERR_LIB_EC, EC_R_POINT_COORDINATES_BLIND_FAILURE}, + #else + {"POINT_COORDINATES_BLIND_FAILURE", 16, 163}, + #endif + #ifdef EC_R_POINT_IS_NOT_ON_CURVE + {"POINT_IS_NOT_ON_CURVE", ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE}, + #else + {"POINT_IS_NOT_ON_CURVE", 16, 107}, + #endif + #ifdef EC_R_RANDOM_NUMBER_GENERATION_FAILED + {"RANDOM_NUMBER_GENERATION_FAILED", ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED}, + #else + {"RANDOM_NUMBER_GENERATION_FAILED", 16, 158}, + #endif + #ifdef EC_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_EC, EC_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 16, 150}, + #endif + #ifdef EC_R_SLOT_FULL + {"SLOT_FULL", ERR_LIB_EC, EC_R_SLOT_FULL}, + #else + {"SLOT_FULL", 16, 108}, + #endif + #ifdef EC_R_UNDEFINED_GENERATOR + {"UNDEFINED_GENERATOR", ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR}, + #else + {"UNDEFINED_GENERATOR", 16, 113}, + #endif + #ifdef EC_R_UNDEFINED_ORDER + {"UNDEFINED_ORDER", ERR_LIB_EC, EC_R_UNDEFINED_ORDER}, + #else + {"UNDEFINED_ORDER", 16, 128}, + #endif + #ifdef EC_R_UNKNOWN_COFACTOR + {"UNKNOWN_COFACTOR", ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR}, + #else + {"UNKNOWN_COFACTOR", 16, 164}, + #endif + #ifdef EC_R_UNKNOWN_GROUP + {"UNKNOWN_GROUP", ERR_LIB_EC, EC_R_UNKNOWN_GROUP}, + #else + {"UNKNOWN_GROUP", 16, 129}, + #endif + #ifdef EC_R_UNKNOWN_ORDER + {"UNKNOWN_ORDER", ERR_LIB_EC, EC_R_UNKNOWN_ORDER}, + #else + {"UNKNOWN_ORDER", 16, 114}, + #endif + #ifdef EC_R_UNSUPPORTED_FIELD + {"UNSUPPORTED_FIELD", ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD}, + #else + {"UNSUPPORTED_FIELD", 16, 131}, + #endif + #ifdef EC_R_WRONG_CURVE_PARAMETERS + {"WRONG_CURVE_PARAMETERS", ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS}, + #else + {"WRONG_CURVE_PARAMETERS", 16, 145}, + #endif + #ifdef EC_R_WRONG_ORDER + {"WRONG_ORDER", ERR_LIB_EC, EC_R_WRONG_ORDER}, + #else + {"WRONG_ORDER", 16, 130}, + #endif + #ifdef ENGINE_R_ALREADY_LOADED + {"ALREADY_LOADED", ERR_LIB_ENGINE, ENGINE_R_ALREADY_LOADED}, + #else + {"ALREADY_LOADED", 38, 100}, + #endif + #ifdef ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER + {"ARGUMENT_IS_NOT_A_NUMBER", ERR_LIB_ENGINE, ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER}, + #else + {"ARGUMENT_IS_NOT_A_NUMBER", 38, 133}, + #endif + #ifdef ENGINE_R_CMD_NOT_EXECUTABLE + {"CMD_NOT_EXECUTABLE", ERR_LIB_ENGINE, ENGINE_R_CMD_NOT_EXECUTABLE}, + #else + {"CMD_NOT_EXECUTABLE", 38, 134}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_INPUT + {"COMMAND_TAKES_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_INPUT}, + #else + {"COMMAND_TAKES_INPUT", 38, 135}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_NO_INPUT + {"COMMAND_TAKES_NO_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_NO_INPUT}, + #else + {"COMMAND_TAKES_NO_INPUT", 38, 136}, + #endif + #ifdef ENGINE_R_CONFLICTING_ENGINE_ID + {"CONFLICTING_ENGINE_ID", ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID}, + #else + {"CONFLICTING_ENGINE_ID", 38, 103}, + #endif + #ifdef ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED + {"CTRL_COMMAND_NOT_IMPLEMENTED", ERR_LIB_ENGINE, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED}, + #else + {"CTRL_COMMAND_NOT_IMPLEMENTED", 38, 119}, + #endif + #ifdef ENGINE_R_DSO_FAILURE + {"DSO_FAILURE", ERR_LIB_ENGINE, ENGINE_R_DSO_FAILURE}, + #else + {"DSO_FAILURE", 38, 104}, + #endif + #ifdef ENGINE_R_DSO_NOT_FOUND + {"DSO_NOT_FOUND", ERR_LIB_ENGINE, ENGINE_R_DSO_NOT_FOUND}, + #else + {"DSO_NOT_FOUND", 38, 132}, + #endif + #ifdef ENGINE_R_ENGINES_SECTION_ERROR + {"ENGINES_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINES_SECTION_ERROR}, + #else + {"ENGINES_SECTION_ERROR", 38, 148}, + #endif + #ifdef ENGINE_R_ENGINE_CONFIGURATION_ERROR + {"ENGINE_CONFIGURATION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR}, + #else + {"ENGINE_CONFIGURATION_ERROR", 38, 102}, + #endif + #ifdef ENGINE_R_ENGINE_IS_NOT_IN_LIST + {"ENGINE_IS_NOT_IN_LIST", ERR_LIB_ENGINE, ENGINE_R_ENGINE_IS_NOT_IN_LIST}, + #else + {"ENGINE_IS_NOT_IN_LIST", 38, 105}, + #endif + #ifdef ENGINE_R_ENGINE_SECTION_ERROR + {"ENGINE_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_SECTION_ERROR}, + #else + {"ENGINE_SECTION_ERROR", 38, 149}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PRIVATE_KEY + {"FAILED_LOADING_PRIVATE_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PRIVATE_KEY}, + #else + {"FAILED_LOADING_PRIVATE_KEY", 38, 128}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PUBLIC_KEY + {"FAILED_LOADING_PUBLIC_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PUBLIC_KEY}, + #else + {"FAILED_LOADING_PUBLIC_KEY", 38, 129}, + #endif + #ifdef ENGINE_R_FINISH_FAILED + {"FINISH_FAILED", ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED}, + #else + {"FINISH_FAILED", 38, 106}, + #endif + #ifdef ENGINE_R_ID_OR_NAME_MISSING + {"ID_OR_NAME_MISSING", ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING}, + #else + {"ID_OR_NAME_MISSING", 38, 108}, + #endif + #ifdef ENGINE_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ENGINE, ENGINE_R_INIT_FAILED}, + #else + {"INIT_FAILED", 38, 109}, + #endif + #ifdef ENGINE_R_INTERNAL_LIST_ERROR + {"INTERNAL_LIST_ERROR", ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR}, + #else + {"INTERNAL_LIST_ERROR", 38, 110}, + #endif + #ifdef ENGINE_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_ENGINE, ENGINE_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 38, 143}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NAME + {"INVALID_CMD_NAME", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NAME}, + #else + {"INVALID_CMD_NAME", 38, 137}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NUMBER + {"INVALID_CMD_NUMBER", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NUMBER}, + #else + {"INVALID_CMD_NUMBER", 38, 138}, + #endif + #ifdef ENGINE_R_INVALID_INIT_VALUE + {"INVALID_INIT_VALUE", ERR_LIB_ENGINE, ENGINE_R_INVALID_INIT_VALUE}, + #else + {"INVALID_INIT_VALUE", 38, 151}, + #endif + #ifdef ENGINE_R_INVALID_STRING + {"INVALID_STRING", ERR_LIB_ENGINE, ENGINE_R_INVALID_STRING}, + #else + {"INVALID_STRING", 38, 150}, + #endif + #ifdef ENGINE_R_NOT_INITIALISED + {"NOT_INITIALISED", ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED}, + #else + {"NOT_INITIALISED", 38, 117}, + #endif + #ifdef ENGINE_R_NOT_LOADED + {"NOT_LOADED", ERR_LIB_ENGINE, ENGINE_R_NOT_LOADED}, + #else + {"NOT_LOADED", 38, 112}, + #endif + #ifdef ENGINE_R_NO_CONTROL_FUNCTION + {"NO_CONTROL_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_CONTROL_FUNCTION}, + #else + {"NO_CONTROL_FUNCTION", 38, 120}, + #endif + #ifdef ENGINE_R_NO_INDEX + {"NO_INDEX", ERR_LIB_ENGINE, ENGINE_R_NO_INDEX}, + #else + {"NO_INDEX", 38, 144}, + #endif + #ifdef ENGINE_R_NO_LOAD_FUNCTION + {"NO_LOAD_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION}, + #else + {"NO_LOAD_FUNCTION", 38, 125}, + #endif + #ifdef ENGINE_R_NO_REFERENCE + {"NO_REFERENCE", ERR_LIB_ENGINE, ENGINE_R_NO_REFERENCE}, + #else + {"NO_REFERENCE", 38, 130}, + #endif + #ifdef ENGINE_R_NO_SUCH_ENGINE + {"NO_SUCH_ENGINE", ERR_LIB_ENGINE, ENGINE_R_NO_SUCH_ENGINE}, + #else + {"NO_SUCH_ENGINE", 38, 116}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_CIPHER + {"UNIMPLEMENTED_CIPHER", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_CIPHER}, + #else + {"UNIMPLEMENTED_CIPHER", 38, 146}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_DIGEST + {"UNIMPLEMENTED_DIGEST", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_DIGEST}, + #else + {"UNIMPLEMENTED_DIGEST", 38, 147}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD}, + #else + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", 38, 101}, + #endif + #ifdef ENGINE_R_VERSION_INCOMPATIBILITY + {"VERSION_INCOMPATIBILITY", ERR_LIB_ENGINE, ENGINE_R_VERSION_INCOMPATIBILITY}, + #else + {"VERSION_INCOMPATIBILITY", 38, 145}, + #endif + #ifdef ESS_R_EMPTY_ESS_CERT_ID_LIST + {"EMPTY_ESS_CERT_ID_LIST", ERR_LIB_ESS, ESS_R_EMPTY_ESS_CERT_ID_LIST}, + #else + {"EMPTY_ESS_CERT_ID_LIST", 54, 107}, + #endif + #ifdef ESS_R_ESS_CERT_DIGEST_ERROR + {"ESS_CERT_DIGEST_ERROR", ERR_LIB_ESS, ESS_R_ESS_CERT_DIGEST_ERROR}, + #else + {"ESS_CERT_DIGEST_ERROR", 54, 103}, + #endif + #ifdef ESS_R_ESS_CERT_ID_NOT_FOUND + {"ESS_CERT_ID_NOT_FOUND", ERR_LIB_ESS, ESS_R_ESS_CERT_ID_NOT_FOUND}, + #else + {"ESS_CERT_ID_NOT_FOUND", 54, 104}, + #endif + #ifdef ESS_R_ESS_CERT_ID_WRONG_ORDER + {"ESS_CERT_ID_WRONG_ORDER", ERR_LIB_ESS, ESS_R_ESS_CERT_ID_WRONG_ORDER}, + #else + {"ESS_CERT_ID_WRONG_ORDER", 54, 105}, + #endif + #ifdef ESS_R_ESS_DIGEST_ALG_UNKNOWN + {"ESS_DIGEST_ALG_UNKNOWN", ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN}, + #else + {"ESS_DIGEST_ALG_UNKNOWN", 54, 106}, + #endif + #ifdef ESS_R_ESS_SIGNING_CERTIFICATE_ERROR + {"ESS_SIGNING_CERTIFICATE_ERROR", ERR_LIB_ESS, ESS_R_ESS_SIGNING_CERTIFICATE_ERROR}, + #else + {"ESS_SIGNING_CERTIFICATE_ERROR", 54, 102}, + #endif + #ifdef ESS_R_ESS_SIGNING_CERT_ADD_ERROR + {"ESS_SIGNING_CERT_ADD_ERROR", ERR_LIB_ESS, ESS_R_ESS_SIGNING_CERT_ADD_ERROR}, + #else + {"ESS_SIGNING_CERT_ADD_ERROR", 54, 100}, + #endif + #ifdef ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR + {"ESS_SIGNING_CERT_V2_ADD_ERROR", ERR_LIB_ESS, ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR}, + #else + {"ESS_SIGNING_CERT_V2_ADD_ERROR", 54, 101}, + #endif + #ifdef ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE + {"MISSING_SIGNING_CERTIFICATE_ATTRIBUTE", ERR_LIB_ESS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE}, + #else + {"MISSING_SIGNING_CERTIFICATE_ATTRIBUTE", 54, 108}, + #endif + #ifdef EVP_R_AES_KEY_SETUP_FAILED + {"AES_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_AES_KEY_SETUP_FAILED}, + #else + {"AES_KEY_SETUP_FAILED", 6, 143}, + #endif + #ifdef EVP_R_ARIA_KEY_SETUP_FAILED + {"ARIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED}, + #else + {"ARIA_KEY_SETUP_FAILED", 6, 176}, + #endif + #ifdef EVP_R_BAD_ALGORITHM_NAME + {"BAD_ALGORITHM_NAME", ERR_LIB_EVP, EVP_R_BAD_ALGORITHM_NAME}, + #else + {"BAD_ALGORITHM_NAME", 6, 200}, + #endif + #ifdef EVP_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_EVP, EVP_R_BAD_DECRYPT}, + #else + {"BAD_DECRYPT", 6, 100}, + #endif + #ifdef EVP_R_BAD_KEY_LENGTH + {"BAD_KEY_LENGTH", ERR_LIB_EVP, EVP_R_BAD_KEY_LENGTH}, + #else + {"BAD_KEY_LENGTH", 6, 195}, + #endif + #ifdef EVP_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 6, 155}, + #endif + #ifdef EVP_R_CACHE_CONSTANTS_FAILED + {"CACHE_CONSTANTS_FAILED", ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED}, + #else + {"CACHE_CONSTANTS_FAILED", 6, 225}, + #endif + #ifdef EVP_R_CAMELLIA_KEY_SETUP_FAILED + {"CAMELLIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED}, + #else + {"CAMELLIA_KEY_SETUP_FAILED", 6, 157}, + #endif + #ifdef EVP_R_CANNOT_GET_PARAMETERS + {"CANNOT_GET_PARAMETERS", ERR_LIB_EVP, EVP_R_CANNOT_GET_PARAMETERS}, + #else + {"CANNOT_GET_PARAMETERS", 6, 197}, + #endif + #ifdef EVP_R_CANNOT_SET_PARAMETERS + {"CANNOT_SET_PARAMETERS", ERR_LIB_EVP, EVP_R_CANNOT_SET_PARAMETERS}, + #else + {"CANNOT_SET_PARAMETERS", 6, 198}, + #endif + #ifdef EVP_R_CIPHER_NOT_GCM_MODE + {"CIPHER_NOT_GCM_MODE", ERR_LIB_EVP, EVP_R_CIPHER_NOT_GCM_MODE}, + #else + {"CIPHER_NOT_GCM_MODE", 6, 184}, + #endif + #ifdef EVP_R_CIPHER_PARAMETER_ERROR + {"CIPHER_PARAMETER_ERROR", ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR}, + #else + {"CIPHER_PARAMETER_ERROR", 6, 122}, + #endif + #ifdef EVP_R_COMMAND_NOT_SUPPORTED + {"COMMAND_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED}, + #else + {"COMMAND_NOT_SUPPORTED", 6, 147}, + #endif + #ifdef EVP_R_CONFLICTING_ALGORITHM_NAME + {"CONFLICTING_ALGORITHM_NAME", ERR_LIB_EVP, EVP_R_CONFLICTING_ALGORITHM_NAME}, + #else + {"CONFLICTING_ALGORITHM_NAME", 6, 201}, + #endif + #ifdef EVP_R_COPY_ERROR + {"COPY_ERROR", ERR_LIB_EVP, EVP_R_COPY_ERROR}, + #else + {"COPY_ERROR", 6, 173}, + #endif + #ifdef EVP_R_CTRL_NOT_IMPLEMENTED + {"CTRL_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED}, + #else + {"CTRL_NOT_IMPLEMENTED", 6, 132}, + #endif + #ifdef EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED + {"CTRL_OPERATION_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED}, + #else + {"CTRL_OPERATION_NOT_IMPLEMENTED", 6, 133}, + #endif + #ifdef EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH}, + #else + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", 6, 138}, + #endif + #ifdef EVP_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EVP, EVP_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 6, 114}, + #endif + #ifdef EVP_R_DEFAULT_QUERY_PARSE_ERROR + {"DEFAULT_QUERY_PARSE_ERROR", ERR_LIB_EVP, EVP_R_DEFAULT_QUERY_PARSE_ERROR}, + #else + {"DEFAULT_QUERY_PARSE_ERROR", 6, 210}, + #endif + #ifdef EVP_R_DIFFERENT_KEY_TYPES + {"DIFFERENT_KEY_TYPES", ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES}, + #else + {"DIFFERENT_KEY_TYPES", 6, 101}, + #endif + #ifdef EVP_R_DIFFERENT_PARAMETERS + {"DIFFERENT_PARAMETERS", ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS}, + #else + {"DIFFERENT_PARAMETERS", 6, 153}, + #endif + #ifdef EVP_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_EVP, EVP_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 6, 165}, + #endif + #ifdef EVP_R_ERROR_SETTING_FIPS_MODE + {"ERROR_SETTING_FIPS_MODE", ERR_LIB_EVP, EVP_R_ERROR_SETTING_FIPS_MODE}, + #else + {"ERROR_SETTING_FIPS_MODE", 6, 166}, + #endif + #ifdef EVP_R_EXPECTING_AN_HMAC_KEY + {"EXPECTING_AN_HMAC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY}, + #else + {"EXPECTING_AN_HMAC_KEY", 6, 174}, + #endif + #ifdef EVP_R_EXPECTING_AN_RSA_KEY + {"EXPECTING_AN_RSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_RSA_KEY}, + #else + {"EXPECTING_AN_RSA_KEY", 6, 127}, + #endif + #ifdef EVP_R_EXPECTING_A_DH_KEY + {"EXPECTING_A_DH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY}, + #else + {"EXPECTING_A_DH_KEY", 6, 128}, + #endif + #ifdef EVP_R_EXPECTING_A_DSA_KEY + {"EXPECTING_A_DSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY}, + #else + {"EXPECTING_A_DSA_KEY", 6, 129}, + #endif + #ifdef EVP_R_EXPECTING_A_ECX_KEY + {"EXPECTING_A_ECX_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_ECX_KEY}, + #else + {"EXPECTING_A_ECX_KEY", 6, 219}, + #endif + #ifdef EVP_R_EXPECTING_A_EC_KEY + {"EXPECTING_A_EC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_EC_KEY}, + #else + {"EXPECTING_A_EC_KEY", 6, 142}, + #endif + #ifdef EVP_R_EXPECTING_A_POLY1305_KEY + {"EXPECTING_A_POLY1305_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY}, + #else + {"EXPECTING_A_POLY1305_KEY", 6, 164}, + #endif + #ifdef EVP_R_EXPECTING_A_SIPHASH_KEY + {"EXPECTING_A_SIPHASH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY}, + #else + {"EXPECTING_A_SIPHASH_KEY", 6, 175}, + #endif + #ifdef EVP_R_FINAL_ERROR + {"FINAL_ERROR", ERR_LIB_EVP, EVP_R_FINAL_ERROR}, + #else + {"FINAL_ERROR", 6, 188}, + #endif + #ifdef EVP_R_FIPS_MODE_NOT_SUPPORTED + {"FIPS_MODE_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_FIPS_MODE_NOT_SUPPORTED}, + #else + {"FIPS_MODE_NOT_SUPPORTED", 6, 167}, + #endif + #ifdef EVP_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_EVP, EVP_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 6, 214}, + #endif + #ifdef EVP_R_GET_RAW_KEY_FAILED + {"GET_RAW_KEY_FAILED", ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED}, + #else + {"GET_RAW_KEY_FAILED", 6, 182}, + #endif + #ifdef EVP_R_ILLEGAL_SCRYPT_PARAMETERS + {"ILLEGAL_SCRYPT_PARAMETERS", ERR_LIB_EVP, EVP_R_ILLEGAL_SCRYPT_PARAMETERS}, + #else + {"ILLEGAL_SCRYPT_PARAMETERS", 6, 171}, + #endif + #ifdef EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS + {"INACCESSIBLE_DOMAIN_PARAMETERS", ERR_LIB_EVP, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS}, + #else + {"INACCESSIBLE_DOMAIN_PARAMETERS", 6, 204}, + #endif + #ifdef EVP_R_INACCESSIBLE_KEY + {"INACCESSIBLE_KEY", ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY}, + #else + {"INACCESSIBLE_KEY", 6, 203}, + #endif + #ifdef EVP_R_INITIALIZATION_ERROR + {"INITIALIZATION_ERROR", ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR}, + #else + {"INITIALIZATION_ERROR", 6, 134}, + #endif + #ifdef EVP_R_INPUT_NOT_INITIALIZED + {"INPUT_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_INPUT_NOT_INITIALIZED}, + #else + {"INPUT_NOT_INITIALIZED", 6, 111}, + #endif + #ifdef EVP_R_INVALID_CUSTOM_LENGTH + {"INVALID_CUSTOM_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_CUSTOM_LENGTH}, + #else + {"INVALID_CUSTOM_LENGTH", 6, 185}, + #endif + #ifdef EVP_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EVP, EVP_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 6, 152}, + #endif + #ifdef EVP_R_INVALID_FIPS_MODE + {"INVALID_FIPS_MODE", ERR_LIB_EVP, EVP_R_INVALID_FIPS_MODE}, + #else + {"INVALID_FIPS_MODE", 6, 168}, + #endif + #ifdef EVP_R_INVALID_IV_LENGTH + {"INVALID_IV_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH}, + #else + {"INVALID_IV_LENGTH", 6, 194}, + #endif + #ifdef EVP_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EVP, EVP_R_INVALID_KEY}, + #else + {"INVALID_KEY", 6, 163}, + #endif + #ifdef EVP_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 6, 130}, + #endif + #ifdef EVP_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 6, 221}, + #endif + #ifdef EVP_R_INVALID_NULL_ALGORITHM + {"INVALID_NULL_ALGORITHM", ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM}, + #else + {"INVALID_NULL_ALGORITHM", 6, 218}, + #endif + #ifdef EVP_R_INVALID_OPERATION + {"INVALID_OPERATION", ERR_LIB_EVP, EVP_R_INVALID_OPERATION}, + #else + {"INVALID_OPERATION", 6, 148}, + #endif + #ifdef EVP_R_INVALID_PROVIDER_FUNCTIONS + {"INVALID_PROVIDER_FUNCTIONS", ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS}, + #else + {"INVALID_PROVIDER_FUNCTIONS", 6, 193}, + #endif + #ifdef EVP_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 6, 186}, + #endif + #ifdef EVP_R_INVALID_SECRET_LENGTH + {"INVALID_SECRET_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH}, + #else + {"INVALID_SECRET_LENGTH", 6, 223}, + #endif + #ifdef EVP_R_INVALID_SEED_LENGTH + {"INVALID_SEED_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_SEED_LENGTH}, + #else + {"INVALID_SEED_LENGTH", 6, 220}, + #endif + #ifdef EVP_R_INVALID_VALUE + {"INVALID_VALUE", ERR_LIB_EVP, EVP_R_INVALID_VALUE}, + #else + {"INVALID_VALUE", 6, 222}, + #endif + #ifdef EVP_R_KEYMGMT_EXPORT_FAILURE + {"KEYMGMT_EXPORT_FAILURE", ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE}, + #else + {"KEYMGMT_EXPORT_FAILURE", 6, 205}, + #endif + #ifdef EVP_R_KEY_SETUP_FAILED + {"KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED}, + #else + {"KEY_SETUP_FAILED", 6, 180}, + #endif + #ifdef EVP_R_LOCKING_NOT_SUPPORTED + {"LOCKING_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_LOCKING_NOT_SUPPORTED}, + #else + {"LOCKING_NOT_SUPPORTED", 6, 213}, + #endif + #ifdef EVP_R_MEMORY_LIMIT_EXCEEDED + {"MEMORY_LIMIT_EXCEEDED", ERR_LIB_EVP, EVP_R_MEMORY_LIMIT_EXCEEDED}, + #else + {"MEMORY_LIMIT_EXCEEDED", 6, 172}, + #endif + #ifdef EVP_R_MESSAGE_DIGEST_IS_NULL + {"MESSAGE_DIGEST_IS_NULL", ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL}, + #else + {"MESSAGE_DIGEST_IS_NULL", 6, 159}, + #endif + #ifdef EVP_R_METHOD_NOT_SUPPORTED + {"METHOD_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_METHOD_NOT_SUPPORTED}, + #else + {"METHOD_NOT_SUPPORTED", 6, 144}, + #endif + #ifdef EVP_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 6, 103}, + #endif + #ifdef EVP_R_NOT_ABLE_TO_COPY_CTX + {"NOT_ABLE_TO_COPY_CTX", ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX}, + #else + {"NOT_ABLE_TO_COPY_CTX", 6, 190}, + #endif + #ifdef EVP_R_NOT_XOF_OR_INVALID_LENGTH + {"NOT_XOF_OR_INVALID_LENGTH", ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH}, + #else + {"NOT_XOF_OR_INVALID_LENGTH", 6, 178}, + #endif + #ifdef EVP_R_NO_CIPHER_SET + {"NO_CIPHER_SET", ERR_LIB_EVP, EVP_R_NO_CIPHER_SET}, + #else + {"NO_CIPHER_SET", 6, 131}, + #endif + #ifdef EVP_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 6, 158}, + #endif + #ifdef EVP_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_EVP, EVP_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 6, 139}, + #endif + #ifdef EVP_R_NO_IMPORT_FUNCTION + {"NO_IMPORT_FUNCTION", ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION}, + #else + {"NO_IMPORT_FUNCTION", 6, 206}, + #endif + #ifdef EVP_R_NO_KEYMGMT_AVAILABLE + {"NO_KEYMGMT_AVAILABLE", ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE}, + #else + {"NO_KEYMGMT_AVAILABLE", 6, 199}, + #endif + #ifdef EVP_R_NO_KEYMGMT_PRESENT + {"NO_KEYMGMT_PRESENT", ERR_LIB_EVP, EVP_R_NO_KEYMGMT_PRESENT}, + #else + {"NO_KEYMGMT_PRESENT", 6, 196}, + #endif + #ifdef EVP_R_NO_KEY_SET + {"NO_KEY_SET", ERR_LIB_EVP, EVP_R_NO_KEY_SET}, + #else + {"NO_KEY_SET", 6, 154}, + #endif + #ifdef EVP_R_NO_OPERATION_SET + {"NO_OPERATION_SET", ERR_LIB_EVP, EVP_R_NO_OPERATION_SET}, + #else + {"NO_OPERATION_SET", 6, 149}, + #endif + #ifdef EVP_R_NULL_MAC_PKEY_CTX + {"NULL_MAC_PKEY_CTX", ERR_LIB_EVP, EVP_R_NULL_MAC_PKEY_CTX}, + #else + {"NULL_MAC_PKEY_CTX", 6, 208}, + #endif + #ifdef EVP_R_ONLY_ONESHOT_SUPPORTED + {"ONLY_ONESHOT_SUPPORTED", ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED}, + #else + {"ONLY_ONESHOT_SUPPORTED", 6, 177}, + #endif + #ifdef EVP_R_OPERATION_NOT_INITIALIZED + {"OPERATION_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED}, + #else + {"OPERATION_NOT_INITIALIZED", 6, 151}, + #endif + #ifdef EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 6, 150}, + #endif + #ifdef EVP_R_OUTPUT_WOULD_OVERFLOW + {"OUTPUT_WOULD_OVERFLOW", ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW}, + #else + {"OUTPUT_WOULD_OVERFLOW", 6, 202}, + #endif + #ifdef EVP_R_PARAMETER_TOO_LARGE + {"PARAMETER_TOO_LARGE", ERR_LIB_EVP, EVP_R_PARAMETER_TOO_LARGE}, + #else + {"PARAMETER_TOO_LARGE", 6, 187}, + #endif + #ifdef EVP_R_PARTIALLY_OVERLAPPING + {"PARTIALLY_OVERLAPPING", ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING}, + #else + {"PARTIALLY_OVERLAPPING", 6, 162}, + #endif + #ifdef EVP_R_PBKDF2_ERROR + {"PBKDF2_ERROR", ERR_LIB_EVP, EVP_R_PBKDF2_ERROR}, + #else + {"PBKDF2_ERROR", 6, 181}, + #endif + #ifdef EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", ERR_LIB_EVP, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED}, + #else + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", 6, 179}, + #endif + #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR + {"PRIVATE_KEY_DECODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_DECODE_ERROR}, + #else + {"PRIVATE_KEY_DECODE_ERROR", 6, 145}, + #endif + #ifdef EVP_R_PRIVATE_KEY_ENCODE_ERROR + {"PRIVATE_KEY_ENCODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_ENCODE_ERROR}, + #else + {"PRIVATE_KEY_ENCODE_ERROR", 6, 146}, + #endif + #ifdef EVP_R_PUBLIC_KEY_NOT_RSA + {"PUBLIC_KEY_NOT_RSA", ERR_LIB_EVP, EVP_R_PUBLIC_KEY_NOT_RSA}, + #else + {"PUBLIC_KEY_NOT_RSA", 6, 106}, + #endif + #ifdef EVP_R_SET_DEFAULT_PROPERTY_FAILURE + {"SET_DEFAULT_PROPERTY_FAILURE", ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE}, + #else + {"SET_DEFAULT_PROPERTY_FAILURE", 6, 209}, + #endif + #ifdef EVP_R_TOO_MANY_RECORDS + {"TOO_MANY_RECORDS", ERR_LIB_EVP, EVP_R_TOO_MANY_RECORDS}, + #else + {"TOO_MANY_RECORDS", 6, 183}, + #endif + #ifdef EVP_R_UNABLE_TO_ENABLE_LOCKING + {"UNABLE_TO_ENABLE_LOCKING", ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING}, + #else + {"UNABLE_TO_ENABLE_LOCKING", 6, 212}, + #endif + #ifdef EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE + {"UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE", ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE}, + #else + {"UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE", 6, 215}, + #endif + #ifdef EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH + {"UNABLE_TO_GET_RANDOM_STRENGTH", ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH}, + #else + {"UNABLE_TO_GET_RANDOM_STRENGTH", 6, 216}, + #endif + #ifdef EVP_R_UNABLE_TO_LOCK_CONTEXT + {"UNABLE_TO_LOCK_CONTEXT", ERR_LIB_EVP, EVP_R_UNABLE_TO_LOCK_CONTEXT}, + #else + {"UNABLE_TO_LOCK_CONTEXT", 6, 211}, + #endif + #ifdef EVP_R_UNABLE_TO_SET_CALLBACKS + {"UNABLE_TO_SET_CALLBACKS", ERR_LIB_EVP, EVP_R_UNABLE_TO_SET_CALLBACKS}, + #else + {"UNABLE_TO_SET_CALLBACKS", 6, 217}, + #endif + #ifdef EVP_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_EVP, EVP_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 6, 160}, + #endif + #ifdef EVP_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_EVP, EVP_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 6, 161}, + #endif + #ifdef EVP_R_UNKNOWN_KEY_TYPE + {"UNKNOWN_KEY_TYPE", ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE}, + #else + {"UNKNOWN_KEY_TYPE", 6, 207}, + #endif + #ifdef EVP_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_EVP, EVP_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 6, 169}, + #endif + #ifdef EVP_R_UNKNOWN_PBE_ALGORITHM + {"UNKNOWN_PBE_ALGORITHM", ERR_LIB_EVP, EVP_R_UNKNOWN_PBE_ALGORITHM}, + #else + {"UNKNOWN_PBE_ALGORITHM", 6, 121}, + #endif + #ifdef EVP_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 6, 156}, + #endif + #ifdef EVP_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 6, 107}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEYLENGTH + {"UNSUPPORTED_KEYLENGTH", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH}, + #else + {"UNSUPPORTED_KEYLENGTH", 6, 123}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION}, + #else + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", 6, 124}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_SIZE + {"UNSUPPORTED_KEY_SIZE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE}, + #else + {"UNSUPPORTED_KEY_SIZE", 6, 108}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_TYPE + {"UNSUPPORTED_KEY_TYPE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE}, + #else + {"UNSUPPORTED_KEY_TYPE", 6, 224}, + #endif + #ifdef EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS + {"UNSUPPORTED_NUMBER_OF_ROUNDS", ERR_LIB_EVP, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS}, + #else + {"UNSUPPORTED_NUMBER_OF_ROUNDS", 6, 135}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRF + {"UNSUPPORTED_PRF", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF}, + #else + {"UNSUPPORTED_PRF", 6, 125}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM}, + #else + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", 6, 118}, + #endif + #ifdef EVP_R_UNSUPPORTED_SALT_TYPE + {"UNSUPPORTED_SALT_TYPE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_SALT_TYPE}, + #else + {"UNSUPPORTED_SALT_TYPE", 6, 126}, + #endif + #ifdef EVP_R_UPDATE_ERROR + {"UPDATE_ERROR", ERR_LIB_EVP, EVP_R_UPDATE_ERROR}, + #else + {"UPDATE_ERROR", 6, 189}, + #endif + #ifdef EVP_R_WRAP_MODE_NOT_ALLOWED + {"WRAP_MODE_NOT_ALLOWED", ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED}, + #else + {"WRAP_MODE_NOT_ALLOWED", 6, 170}, + #endif + #ifdef EVP_R_WRONG_FINAL_BLOCK_LENGTH + {"WRONG_FINAL_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_WRONG_FINAL_BLOCK_LENGTH}, + #else + {"WRONG_FINAL_BLOCK_LENGTH", 6, 109}, + #endif + #ifdef EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE + {"XTS_DATA_UNIT_IS_TOO_LARGE", ERR_LIB_EVP, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE}, + #else + {"XTS_DATA_UNIT_IS_TOO_LARGE", 6, 191}, + #endif + #ifdef EVP_R_XTS_DUPLICATED_KEYS + {"XTS_DUPLICATED_KEYS", ERR_LIB_EVP, EVP_R_XTS_DUPLICATED_KEYS}, + #else + {"XTS_DUPLICATED_KEYS", 6, 192}, + #endif + #ifdef HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN + {"ASN1_LEN_EXCEEDS_MAX_RESP_LEN", ERR_LIB_HTTP, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN}, + #else + {"ASN1_LEN_EXCEEDS_MAX_RESP_LEN", 61, 108}, + #endif + #ifdef HTTP_R_CONNECT_FAILURE + {"CONNECT_FAILURE", ERR_LIB_HTTP, HTTP_R_CONNECT_FAILURE}, + #else + {"CONNECT_FAILURE", 61, 100}, + #endif + #ifdef HTTP_R_ERROR_PARSING_ASN1_LENGTH + {"ERROR_PARSING_ASN1_LENGTH", ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_ASN1_LENGTH}, + #else + {"ERROR_PARSING_ASN1_LENGTH", 61, 109}, + #endif + #ifdef HTTP_R_ERROR_PARSING_CONTENT_LENGTH + {"ERROR_PARSING_CONTENT_LENGTH", ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_CONTENT_LENGTH}, + #else + {"ERROR_PARSING_CONTENT_LENGTH", 61, 119}, + #endif + #ifdef HTTP_R_ERROR_PARSING_URL + {"ERROR_PARSING_URL", ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_URL}, + #else + {"ERROR_PARSING_URL", 61, 101}, + #endif + #ifdef HTTP_R_ERROR_RECEIVING + {"ERROR_RECEIVING", ERR_LIB_HTTP, HTTP_R_ERROR_RECEIVING}, + #else + {"ERROR_RECEIVING", 61, 103}, + #endif + #ifdef HTTP_R_ERROR_SENDING + {"ERROR_SENDING", ERR_LIB_HTTP, HTTP_R_ERROR_SENDING}, + #else + {"ERROR_SENDING", 61, 102}, + #endif + #ifdef HTTP_R_FAILED_READING_DATA + {"FAILED_READING_DATA", ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA}, + #else + {"FAILED_READING_DATA", 61, 128}, + #endif + #ifdef HTTP_R_INCONSISTENT_CONTENT_LENGTH + {"INCONSISTENT_CONTENT_LENGTH", ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH}, + #else + {"INCONSISTENT_CONTENT_LENGTH", 61, 120}, + #endif + #ifdef HTTP_R_INVALID_PORT_NUMBER + {"INVALID_PORT_NUMBER", ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER}, + #else + {"INVALID_PORT_NUMBER", 61, 123}, + #endif + #ifdef HTTP_R_INVALID_URL_PATH + {"INVALID_URL_PATH", ERR_LIB_HTTP, HTTP_R_INVALID_URL_PATH}, + #else + {"INVALID_URL_PATH", 61, 125}, + #endif + #ifdef HTTP_R_INVALID_URL_SCHEME + {"INVALID_URL_SCHEME", ERR_LIB_HTTP, HTTP_R_INVALID_URL_SCHEME}, + #else + {"INVALID_URL_SCHEME", 61, 124}, + #endif + #ifdef HTTP_R_MAX_RESP_LEN_EXCEEDED + {"MAX_RESP_LEN_EXCEEDED", ERR_LIB_HTTP, HTTP_R_MAX_RESP_LEN_EXCEEDED}, + #else + {"MAX_RESP_LEN_EXCEEDED", 61, 117}, + #endif + #ifdef HTTP_R_MISSING_ASN1_ENCODING + {"MISSING_ASN1_ENCODING", ERR_LIB_HTTP, HTTP_R_MISSING_ASN1_ENCODING}, + #else + {"MISSING_ASN1_ENCODING", 61, 110}, + #endif + #ifdef HTTP_R_MISSING_CONTENT_TYPE + {"MISSING_CONTENT_TYPE", ERR_LIB_HTTP, HTTP_R_MISSING_CONTENT_TYPE}, + #else + {"MISSING_CONTENT_TYPE", 61, 121}, + #endif + #ifdef HTTP_R_MISSING_REDIRECT_LOCATION + {"MISSING_REDIRECT_LOCATION", ERR_LIB_HTTP, HTTP_R_MISSING_REDIRECT_LOCATION}, + #else + {"MISSING_REDIRECT_LOCATION", 61, 111}, + #endif + #ifdef HTTP_R_RECEIVED_ERROR + {"RECEIVED_ERROR", ERR_LIB_HTTP, HTTP_R_RECEIVED_ERROR}, + #else + {"RECEIVED_ERROR", 61, 105}, + #endif + #ifdef HTTP_R_RECEIVED_WRONG_HTTP_VERSION + {"RECEIVED_WRONG_HTTP_VERSION", ERR_LIB_HTTP, HTTP_R_RECEIVED_WRONG_HTTP_VERSION}, + #else + {"RECEIVED_WRONG_HTTP_VERSION", 61, 106}, + #endif + #ifdef HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP + {"REDIRECTION_FROM_HTTPS_TO_HTTP", ERR_LIB_HTTP, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP}, + #else + {"REDIRECTION_FROM_HTTPS_TO_HTTP", 61, 112}, + #endif + #ifdef HTTP_R_REDIRECTION_NOT_ENABLED + {"REDIRECTION_NOT_ENABLED", ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED}, + #else + {"REDIRECTION_NOT_ENABLED", 61, 116}, + #endif + #ifdef HTTP_R_RESPONSE_LINE_TOO_LONG + {"RESPONSE_LINE_TOO_LONG", ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG}, + #else + {"RESPONSE_LINE_TOO_LONG", 61, 113}, + #endif + #ifdef HTTP_R_RESPONSE_PARSE_ERROR + {"RESPONSE_PARSE_ERROR", ERR_LIB_HTTP, HTTP_R_RESPONSE_PARSE_ERROR}, + #else + {"RESPONSE_PARSE_ERROR", 61, 104}, + #endif + #ifdef HTTP_R_SOCK_NOT_SUPPORTED + {"SOCK_NOT_SUPPORTED", ERR_LIB_HTTP, HTTP_R_SOCK_NOT_SUPPORTED}, + #else + {"SOCK_NOT_SUPPORTED", 61, 122}, + #endif + #ifdef HTTP_R_STATUS_CODE_UNSUPPORTED + {"STATUS_CODE_UNSUPPORTED", ERR_LIB_HTTP, HTTP_R_STATUS_CODE_UNSUPPORTED}, + #else + {"STATUS_CODE_UNSUPPORTED", 61, 114}, + #endif + #ifdef HTTP_R_TLS_NOT_ENABLED + {"TLS_NOT_ENABLED", ERR_LIB_HTTP, HTTP_R_TLS_NOT_ENABLED}, + #else + {"TLS_NOT_ENABLED", 61, 107}, + #endif + #ifdef HTTP_R_TOO_MANY_REDIRECTIONS + {"TOO_MANY_REDIRECTIONS", ERR_LIB_HTTP, HTTP_R_TOO_MANY_REDIRECTIONS}, + #else + {"TOO_MANY_REDIRECTIONS", 61, 115}, + #endif + #ifdef HTTP_R_UNEXPECTED_CONTENT_TYPE + {"UNEXPECTED_CONTENT_TYPE", ERR_LIB_HTTP, HTTP_R_UNEXPECTED_CONTENT_TYPE}, + #else + {"UNEXPECTED_CONTENT_TYPE", 61, 118}, + #endif + #ifdef OBJ_R_OID_EXISTS + {"OID_EXISTS", ERR_LIB_OBJ, OBJ_R_OID_EXISTS}, + #else + {"OID_EXISTS", 8, 102}, + #endif + #ifdef OBJ_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 8, 101}, + #endif + #ifdef OBJ_R_UNKNOWN_OBJECT_NAME + {"UNKNOWN_OBJECT_NAME", ERR_LIB_OBJ, OBJ_R_UNKNOWN_OBJECT_NAME}, + #else + {"UNKNOWN_OBJECT_NAME", 8, 103}, + #endif + #ifdef OCSP_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 39, 101}, + #endif + #ifdef OCSP_R_DIGEST_ERR + {"DIGEST_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_ERR}, + #else + {"DIGEST_ERR", 39, 102}, + #endif + #ifdef OCSP_R_DIGEST_NAME_ERR + {"DIGEST_NAME_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_NAME_ERR}, + #else + {"DIGEST_NAME_ERR", 39, 106}, + #endif + #ifdef OCSP_R_DIGEST_SIZE_ERR + {"DIGEST_SIZE_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_SIZE_ERR}, + #else + {"DIGEST_SIZE_ERR", 39, 107}, + #endif + #ifdef OCSP_R_ERROR_IN_NEXTUPDATE_FIELD + {"ERROR_IN_NEXTUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD}, + #else + {"ERROR_IN_NEXTUPDATE_FIELD", 39, 122}, + #endif + #ifdef OCSP_R_ERROR_IN_THISUPDATE_FIELD + {"ERROR_IN_THISUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD}, + #else + {"ERROR_IN_THISUPDATE_FIELD", 39, 123}, + #endif + #ifdef OCSP_R_MISSING_OCSPSIGNING_USAGE + {"MISSING_OCSPSIGNING_USAGE", ERR_LIB_OCSP, OCSP_R_MISSING_OCSPSIGNING_USAGE}, + #else + {"MISSING_OCSPSIGNING_USAGE", 39, 103}, + #endif + #ifdef OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE + {"NEXTUPDATE_BEFORE_THISUPDATE", ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE}, + #else + {"NEXTUPDATE_BEFORE_THISUPDATE", 39, 124}, + #endif + #ifdef OCSP_R_NOT_BASIC_RESPONSE + {"NOT_BASIC_RESPONSE", ERR_LIB_OCSP, OCSP_R_NOT_BASIC_RESPONSE}, + #else + {"NOT_BASIC_RESPONSE", 39, 104}, + #endif + #ifdef OCSP_R_NO_CERTIFICATES_IN_CHAIN + {"NO_CERTIFICATES_IN_CHAIN", ERR_LIB_OCSP, OCSP_R_NO_CERTIFICATES_IN_CHAIN}, + #else + {"NO_CERTIFICATES_IN_CHAIN", 39, 105}, + #endif + #ifdef OCSP_R_NO_RESPONSE_DATA + {"NO_RESPONSE_DATA", ERR_LIB_OCSP, OCSP_R_NO_RESPONSE_DATA}, + #else + {"NO_RESPONSE_DATA", 39, 108}, + #endif + #ifdef OCSP_R_NO_REVOKED_TIME + {"NO_REVOKED_TIME", ERR_LIB_OCSP, OCSP_R_NO_REVOKED_TIME}, + #else + {"NO_REVOKED_TIME", 39, 109}, + #endif + #ifdef OCSP_R_NO_SIGNER_KEY + {"NO_SIGNER_KEY", ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY}, + #else + {"NO_SIGNER_KEY", 39, 130}, + #endif + #ifdef OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_OCSP, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 39, 110}, + #endif + #ifdef OCSP_R_REQUEST_NOT_SIGNED + {"REQUEST_NOT_SIGNED", ERR_LIB_OCSP, OCSP_R_REQUEST_NOT_SIGNED}, + #else + {"REQUEST_NOT_SIGNED", 39, 128}, + #endif + #ifdef OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", ERR_LIB_OCSP, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA}, + #else + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", 39, 111}, + #endif + #ifdef OCSP_R_ROOT_CA_NOT_TRUSTED + {"ROOT_CA_NOT_TRUSTED", ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED}, + #else + {"ROOT_CA_NOT_TRUSTED", 39, 112}, + #endif + #ifdef OCSP_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 39, 117}, + #endif + #ifdef OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 39, 118}, + #endif + #ifdef OCSP_R_STATUS_EXPIRED + {"STATUS_EXPIRED", ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED}, + #else + {"STATUS_EXPIRED", 39, 125}, + #endif + #ifdef OCSP_R_STATUS_NOT_YET_VALID + {"STATUS_NOT_YET_VALID", ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID}, + #else + {"STATUS_NOT_YET_VALID", 39, 126}, + #endif + #ifdef OCSP_R_STATUS_TOO_OLD + {"STATUS_TOO_OLD", ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD}, + #else + {"STATUS_TOO_OLD", 39, 127}, + #endif + #ifdef OCSP_R_UNKNOWN_MESSAGE_DIGEST + {"UNKNOWN_MESSAGE_DIGEST", ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST}, + #else + {"UNKNOWN_MESSAGE_DIGEST", 39, 119}, + #endif + #ifdef OCSP_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_OCSP, OCSP_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 39, 120}, + #endif + #ifdef OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE + {"UNSUPPORTED_REQUESTORNAME_TYPE", ERR_LIB_OCSP, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE}, + #else + {"UNSUPPORTED_REQUESTORNAME_TYPE", 39, 129}, + #endif + #ifdef OSSL_DECODER_R_MISSING_GET_PARAMS + {"MISSING_GET_PARAMS", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_MISSING_GET_PARAMS}, + #else + {"MISSING_GET_PARAMS", 60, 100}, + #endif + #ifdef OSSL_ENCODER_R_ENCODER_NOT_FOUND + {"ENCODER_NOT_FOUND", ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_ENCODER_NOT_FOUND}, + #else + {"ENCODER_NOT_FOUND", 59, 101}, + #endif + #ifdef OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY + {"INCORRECT_PROPERTY_QUERY", ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY}, + #else + {"INCORRECT_PROPERTY_QUERY", 59, 100}, + #endif + #ifdef OSSL_ENCODER_R_MISSING_GET_PARAMS + {"MISSING_GET_PARAMS", ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_MISSING_GET_PARAMS}, + #else + {"MISSING_GET_PARAMS", 59, 102}, + #endif + #ifdef OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE + {"AMBIGUOUS_CONTENT_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE}, + #else + {"AMBIGUOUS_CONTENT_TYPE", 44, 107}, + #endif + #ifdef OSSL_STORE_R_BAD_PASSWORD_READ + {"BAD_PASSWORD_READ", ERR_LIB_OSSL_STORE, OSSL_STORE_R_BAD_PASSWORD_READ}, + #else + {"BAD_PASSWORD_READ", 44, 115}, + #endif + #ifdef OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC + {"ERROR_VERIFYING_PKCS12_MAC", ERR_LIB_OSSL_STORE, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC}, + #else + {"ERROR_VERIFYING_PKCS12_MAC", 44, 113}, + #endif + #ifdef OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST + {"FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST", ERR_LIB_OSSL_STORE, OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST}, + #else + {"FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST", 44, 121}, + #endif + #ifdef OSSL_STORE_R_INVALID_SCHEME + {"INVALID_SCHEME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME}, + #else + {"INVALID_SCHEME", 44, 106}, + #endif + #ifdef OSSL_STORE_R_IS_NOT_A + {"IS_NOT_A", ERR_LIB_OSSL_STORE, OSSL_STORE_R_IS_NOT_A}, + #else + {"IS_NOT_A", 44, 112}, + #endif + #ifdef OSSL_STORE_R_LOADER_INCOMPLETE + {"LOADER_INCOMPLETE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE}, + #else + {"LOADER_INCOMPLETE", 44, 116}, + #endif + #ifdef OSSL_STORE_R_LOADING_STARTED + {"LOADING_STARTED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED}, + #else + {"LOADING_STARTED", 44, 117}, + #endif + #ifdef OSSL_STORE_R_NOT_A_CERTIFICATE + {"NOT_A_CERTIFICATE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE}, + #else + {"NOT_A_CERTIFICATE", 44, 100}, + #endif + #ifdef OSSL_STORE_R_NOT_A_CRL + {"NOT_A_CRL", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL}, + #else + {"NOT_A_CRL", 44, 101}, + #endif + #ifdef OSSL_STORE_R_NOT_A_NAME + {"NOT_A_NAME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME}, + #else + {"NOT_A_NAME", 44, 103}, + #endif + #ifdef OSSL_STORE_R_NOT_A_PRIVATE_KEY + {"NOT_A_PRIVATE_KEY", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY}, + #else + {"NOT_A_PRIVATE_KEY", 44, 102}, + #endif + #ifdef OSSL_STORE_R_NOT_A_PUBLIC_KEY + {"NOT_A_PUBLIC_KEY", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PUBLIC_KEY}, + #else + {"NOT_A_PUBLIC_KEY", 44, 122}, + #endif + #ifdef OSSL_STORE_R_NOT_PARAMETERS + {"NOT_PARAMETERS", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS}, + #else + {"NOT_PARAMETERS", 44, 104}, + #endif + #ifdef OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR + {"PASSPHRASE_CALLBACK_ERROR", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR}, + #else + {"PASSPHRASE_CALLBACK_ERROR", 44, 114}, + #endif + #ifdef OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE + {"PATH_MUST_BE_ABSOLUTE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE}, + #else + {"PATH_MUST_BE_ABSOLUTE", 44, 108}, + #endif + #ifdef OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", ERR_LIB_OSSL_STORE, OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES}, + #else + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", 44, 119}, + #endif + #ifdef OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED + {"UI_PROCESS_INTERRUPTED_OR_CANCELLED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED}, + #else + {"UI_PROCESS_INTERRUPTED_OR_CANCELLED", 44, 109}, + #endif + #ifdef OSSL_STORE_R_UNREGISTERED_SCHEME + {"UNREGISTERED_SCHEME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNREGISTERED_SCHEME}, + #else + {"UNREGISTERED_SCHEME", 44, 105}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 44, 110}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_OPERATION + {"UNSUPPORTED_OPERATION", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION}, + #else + {"UNSUPPORTED_OPERATION", 44, 118}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE + {"UNSUPPORTED_SEARCH_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE}, + #else + {"UNSUPPORTED_SEARCH_TYPE", 44, 120}, + #endif + #ifdef OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED + {"URI_AUTHORITY_UNSUPPORTED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED}, + #else + {"URI_AUTHORITY_UNSUPPORTED", 44, 111}, + #endif + #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 + {"BAD_DECRYPT", 9, 101}, + #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 + {"BAD_IV_CHARS", 9, 103}, + #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 + {"BAD_PASSWORD_READ", 9, 104}, + #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 + {"BIO_WRITE_FAILURE", 9, 118}, + #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 + {"ERROR_CONVERTING_PRIVATE_KEY", 9, 115}, + #endif + #ifdef PEM_R_EXPECTING_DSS_KEY_BLOB + {"EXPECTING_DSS_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_DSS_KEY_BLOB}, + #else + {"EXPECTING_DSS_KEY_BLOB", 9, 131}, + #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 + {"EXPECTING_PUBLIC_KEY_BLOB", 9, 120}, + #endif + #ifdef PEM_R_EXPECTING_RSA_KEY_BLOB + {"EXPECTING_RSA_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_RSA_KEY_BLOB}, + #else + {"EXPECTING_RSA_KEY_BLOB", 9, 132}, + #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 + {"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 + {"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 + {"KEYBLOB_TOO_SHORT", 9, 123}, + #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 + {"NOT_DEK_INFO", 9, 105}, + #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 + {"NOT_PROC_TYPE", 9, 107}, + #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 + {"PROBLEMS_GETTING_PASSWORD", 9, 109}, + #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 + {"PVK_TOO_SHORT", 9, 125}, + #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 + {"SHORT_HEADER", 9, 112}, + #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 + {"UNSUPPORTED_CIPHER", 9, 113}, + #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 + {"UNSUPPORTED_KEY_COMPONENTS", 9, 126}, + #endif + #ifdef PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE + {"UNSUPPORTED_PUBLIC_KEY_TYPE", ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE}, + #else + {"UNSUPPORTED_PUBLIC_KEY_TYPE", 9, 110}, + #endif + #ifdef PKCS12_R_CANT_PACK_STRUCTURE + {"CANT_PACK_STRUCTURE", ERR_LIB_PKCS12, PKCS12_R_CANT_PACK_STRUCTURE}, + #else + {"CANT_PACK_STRUCTURE", 35, 100}, + #endif + #ifdef PKCS12_R_CONTENT_TYPE_NOT_DATA + {"CONTENT_TYPE_NOT_DATA", ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA}, + #else + {"CONTENT_TYPE_NOT_DATA", 35, 121}, + #endif + #ifdef PKCS12_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 35, 101}, + #endif + #ifdef PKCS12_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 35, 102}, + #endif + #ifdef PKCS12_R_ENCRYPT_ERROR + {"ENCRYPT_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR}, + #else + {"ENCRYPT_ERROR", 35, 103}, + #endif + #ifdef PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", ERR_LIB_PKCS12, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE}, + #else + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", 35, 120}, + #endif + #ifdef PKCS12_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 35, 104}, + #endif + #ifdef PKCS12_R_INVALID_NULL_PKCS12_POINTER + {"INVALID_NULL_PKCS12_POINTER", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER}, + #else + {"INVALID_NULL_PKCS12_POINTER", 35, 105}, + #endif + #ifdef PKCS12_R_INVALID_TYPE + {"INVALID_TYPE", ERR_LIB_PKCS12, PKCS12_R_INVALID_TYPE}, + #else + {"INVALID_TYPE", 35, 112}, + #endif + #ifdef PKCS12_R_IV_GEN_ERROR + {"IV_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_IV_GEN_ERROR}, + #else + {"IV_GEN_ERROR", 35, 106}, + #endif + #ifdef PKCS12_R_KEY_GEN_ERROR + {"KEY_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR}, + #else + {"KEY_GEN_ERROR", 35, 107}, + #endif + #ifdef PKCS12_R_MAC_ABSENT + {"MAC_ABSENT", ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT}, + #else + {"MAC_ABSENT", 35, 108}, + #endif + #ifdef PKCS12_R_MAC_GENERATION_ERROR + {"MAC_GENERATION_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR}, + #else + {"MAC_GENERATION_ERROR", 35, 109}, + #endif + #ifdef PKCS12_R_MAC_SETUP_ERROR + {"MAC_SETUP_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR}, + #else + {"MAC_SETUP_ERROR", 35, 110}, + #endif + #ifdef PKCS12_R_MAC_STRING_SET_ERROR + {"MAC_STRING_SET_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR}, + #else + {"MAC_STRING_SET_ERROR", 35, 111}, + #endif + #ifdef PKCS12_R_MAC_VERIFY_FAILURE + {"MAC_VERIFY_FAILURE", ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE}, + #else + {"MAC_VERIFY_FAILURE", 35, 113}, + #endif + #ifdef PKCS12_R_PARSE_ERROR + {"PARSE_ERROR", ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR}, + #else + {"PARSE_ERROR", 35, 114}, + #endif + #ifdef PKCS12_R_PKCS12_CIPHERFINAL_ERROR + {"PKCS12_CIPHERFINAL_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR}, + #else + {"PKCS12_CIPHERFINAL_ERROR", 35, 116}, + #endif + #ifdef PKCS12_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 35, 118}, + #endif + #ifdef PKCS12_R_UNSUPPORTED_PKCS12_MODE + {"UNSUPPORTED_PKCS12_MODE", ERR_LIB_PKCS12, PKCS12_R_UNSUPPORTED_PKCS12_MODE}, + #else + {"UNSUPPORTED_PKCS12_MODE", 35, 119}, + #endif + #ifdef PKCS7_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_PKCS7, PKCS7_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 33, 117}, + #endif + #ifdef PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 33, 144}, + #endif + #ifdef PKCS7_R_CIPHER_NOT_INITIALIZED + {"CIPHER_NOT_INITIALIZED", ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED}, + #else + {"CIPHER_NOT_INITIALIZED", 33, 116}, + #endif + #ifdef PKCS7_R_CONTENT_AND_DATA_PRESENT + {"CONTENT_AND_DATA_PRESENT", ERR_LIB_PKCS7, PKCS7_R_CONTENT_AND_DATA_PRESENT}, + #else + {"CONTENT_AND_DATA_PRESENT", 33, 118}, + #endif + #ifdef PKCS7_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_PKCS7, PKCS7_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 33, 152}, + #endif + #ifdef PKCS7_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_PKCS7, PKCS7_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 33, 119}, + #endif + #ifdef PKCS7_R_DIGEST_FAILURE + {"DIGEST_FAILURE", ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE}, + #else + {"DIGEST_FAILURE", 33, 101}, + #endif + #ifdef PKCS7_R_ENCRYPTION_CTRL_FAILURE + {"ENCRYPTION_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE}, + #else + {"ENCRYPTION_CTRL_FAILURE", 33, 149}, + #endif + #ifdef PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 150}, + #endif + #ifdef PKCS7_R_ERROR_ADDING_RECIPIENT + {"ERROR_ADDING_RECIPIENT", ERR_LIB_PKCS7, PKCS7_R_ERROR_ADDING_RECIPIENT}, + #else + {"ERROR_ADDING_RECIPIENT", 33, 120}, + #endif + #ifdef PKCS7_R_ERROR_SETTING_CIPHER + {"ERROR_SETTING_CIPHER", ERR_LIB_PKCS7, PKCS7_R_ERROR_SETTING_CIPHER}, + #else + {"ERROR_SETTING_CIPHER", 33, 121}, + #endif + #ifdef PKCS7_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 33, 143}, + #endif + #ifdef PKCS7_R_INVALID_SIGNED_DATA_TYPE + {"INVALID_SIGNED_DATA_TYPE", ERR_LIB_PKCS7, PKCS7_R_INVALID_SIGNED_DATA_TYPE}, + #else + {"INVALID_SIGNED_DATA_TYPE", 33, 155}, + #endif + #ifdef PKCS7_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT}, + #else + {"NO_CONTENT", 33, 122}, + #endif + #ifdef PKCS7_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 33, 151}, + #endif + #ifdef PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND + {"NO_MATCHING_DIGEST_TYPE_FOUND", ERR_LIB_PKCS7, PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND}, + #else + {"NO_MATCHING_DIGEST_TYPE_FOUND", 33, 154}, + #endif + #ifdef PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE + {"NO_RECIPIENT_MATCHES_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE}, + #else + {"NO_RECIPIENT_MATCHES_CERTIFICATE", 33, 115}, + #endif + #ifdef PKCS7_R_NO_SIGNATURES_ON_DATA + {"NO_SIGNATURES_ON_DATA", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNATURES_ON_DATA}, + #else + {"NO_SIGNATURES_ON_DATA", 33, 123}, + #endif + #ifdef PKCS7_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 33, 142}, + #endif + #ifdef PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", ERR_LIB_PKCS7, PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE}, + #else + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", 33, 104}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 33, 124}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNER_ERROR + {"PKCS7_ADD_SIGNER_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNER_ERROR}, + #else + {"PKCS7_ADD_SIGNER_ERROR", 33, 153}, + #endif + #ifdef PKCS7_R_PKCS7_DATASIGN + {"PKCS7_DATASIGN", ERR_LIB_PKCS7, PKCS7_R_PKCS7_DATASIGN}, + #else + {"PKCS7_DATASIGN", 33, 145}, + #endif + #ifdef PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 33, 127}, + #endif + #ifdef PKCS7_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 33, 105}, + #endif + #ifdef PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_PKCS7, PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 33, 128}, + #endif + #ifdef PKCS7_R_SIGNING_CTRL_FAILURE + {"SIGNING_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE}, + #else + {"SIGNING_CTRL_FAILURE", 33, 147}, + #endif + #ifdef PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 148}, + #endif + #ifdef PKCS7_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_PKCS7, PKCS7_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 33, 129}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_CERTIFICATE + {"UNABLE_TO_FIND_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE}, + #else + {"UNABLE_TO_FIND_CERTIFICATE", 33, 106}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MEM_BIO + {"UNABLE_TO_FIND_MEM_BIO", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MEM_BIO}, + #else + {"UNABLE_TO_FIND_MEM_BIO", 33, 107}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST + {"UNABLE_TO_FIND_MESSAGE_DIGEST", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST}, + #else + {"UNABLE_TO_FIND_MESSAGE_DIGEST", 33, 108}, + #endif + #ifdef PKCS7_R_UNKNOWN_DIGEST_TYPE + {"UNKNOWN_DIGEST_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE}, + #else + {"UNKNOWN_DIGEST_TYPE", 33, 109}, + #endif + #ifdef PKCS7_R_UNKNOWN_OPERATION + {"UNKNOWN_OPERATION", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION}, + #else + {"UNKNOWN_OPERATION", 33, 110}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CIPHER_TYPE + {"UNSUPPORTED_CIPHER_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE}, + #else + {"UNSUPPORTED_CIPHER_TYPE", 33, 111}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 33, 112}, + #endif + #ifdef PKCS7_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 33, 113}, + #endif + #ifdef PKCS7_R_WRONG_PKCS7_TYPE + {"WRONG_PKCS7_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE}, + #else + {"WRONG_PKCS7_TYPE", 33, 114}, + #endif + #ifdef PROP_R_NAME_TOO_LONG + {"NAME_TOO_LONG", ERR_LIB_PROP, PROP_R_NAME_TOO_LONG}, + #else + {"NAME_TOO_LONG", 55, 100}, + #endif + #ifdef PROP_R_NOT_AN_ASCII_CHARACTER + {"NOT_AN_ASCII_CHARACTER", ERR_LIB_PROP, PROP_R_NOT_AN_ASCII_CHARACTER}, + #else + {"NOT_AN_ASCII_CHARACTER", 55, 101}, + #endif + #ifdef PROP_R_NOT_AN_HEXADECIMAL_DIGIT + {"NOT_AN_HEXADECIMAL_DIGIT", ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT}, + #else + {"NOT_AN_HEXADECIMAL_DIGIT", 55, 102}, + #endif + #ifdef PROP_R_NOT_AN_IDENTIFIER + {"NOT_AN_IDENTIFIER", ERR_LIB_PROP, PROP_R_NOT_AN_IDENTIFIER}, + #else + {"NOT_AN_IDENTIFIER", 55, 103}, + #endif + #ifdef PROP_R_NOT_AN_OCTAL_DIGIT + {"NOT_AN_OCTAL_DIGIT", ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT}, + #else + {"NOT_AN_OCTAL_DIGIT", 55, 104}, + #endif + #ifdef PROP_R_NOT_A_DECIMAL_DIGIT + {"NOT_A_DECIMAL_DIGIT", ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT}, + #else + {"NOT_A_DECIMAL_DIGIT", 55, 105}, + #endif + #ifdef PROP_R_NO_MATCHING_STRING_DELIMITER + {"NO_MATCHING_STRING_DELIMITER", ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMITER}, + #else + {"NO_MATCHING_STRING_DELIMITER", 55, 106}, + #endif + #ifdef PROP_R_NO_VALUE + {"NO_VALUE", ERR_LIB_PROP, PROP_R_NO_VALUE}, + #else + {"NO_VALUE", 55, 107}, + #endif + #ifdef PROP_R_PARSE_FAILED + {"PARSE_FAILED", ERR_LIB_PROP, PROP_R_PARSE_FAILED}, + #else + {"PARSE_FAILED", 55, 108}, + #endif + #ifdef PROP_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_PROP, PROP_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 55, 109}, + #endif + #ifdef PROP_R_TRAILING_CHARACTERS + {"TRAILING_CHARACTERS", ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS}, + #else + {"TRAILING_CHARACTERS", 55, 110}, + #endif + #ifdef PROV_R_ADDITIONAL_INPUT_TOO_LONG + {"ADDITIONAL_INPUT_TOO_LONG", ERR_LIB_PROV, PROV_R_ADDITIONAL_INPUT_TOO_LONG}, + #else + {"ADDITIONAL_INPUT_TOO_LONG", 57, 184}, + #endif + #ifdef PROV_R_ALGORITHM_MISMATCH + {"ALGORITHM_MISMATCH", ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH}, + #else + {"ALGORITHM_MISMATCH", 57, 173}, + #endif + #ifdef PROV_R_ALREADY_INSTANTIATED + {"ALREADY_INSTANTIATED", ERR_LIB_PROV, PROV_R_ALREADY_INSTANTIATED}, + #else + {"ALREADY_INSTANTIATED", 57, 185}, + #endif + #ifdef PROV_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_PROV, PROV_R_BAD_DECRYPT}, + #else + {"BAD_DECRYPT", 57, 100}, + #endif + #ifdef PROV_R_BAD_ENCODING + {"BAD_ENCODING", ERR_LIB_PROV, PROV_R_BAD_ENCODING}, + #else + {"BAD_ENCODING", 57, 141}, + #endif + #ifdef PROV_R_BAD_LENGTH + {"BAD_LENGTH", ERR_LIB_PROV, PROV_R_BAD_LENGTH}, + #else + {"BAD_LENGTH", 57, 142}, + #endif + #ifdef PROV_R_BAD_TLS_CLIENT_VERSION + {"BAD_TLS_CLIENT_VERSION", ERR_LIB_PROV, PROV_R_BAD_TLS_CLIENT_VERSION}, + #else + {"BAD_TLS_CLIENT_VERSION", 57, 161}, + #endif + #ifdef PROV_R_BN_ERROR + {"BN_ERROR", ERR_LIB_PROV, PROV_R_BN_ERROR}, + #else + {"BN_ERROR", 57, 160}, + #endif + #ifdef PROV_R_CIPHER_OPERATION_FAILED + {"CIPHER_OPERATION_FAILED", ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED}, + #else + {"CIPHER_OPERATION_FAILED", 57, 102}, + #endif + #ifdef PROV_R_DERIVATION_FUNCTION_INIT_FAILED + {"DERIVATION_FUNCTION_INIT_FAILED", ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED}, + #else + {"DERIVATION_FUNCTION_INIT_FAILED", 57, 205}, + #endif + #ifdef PROV_R_DIGEST_NOT_ALLOWED + {"DIGEST_NOT_ALLOWED", ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED}, + #else + {"DIGEST_NOT_ALLOWED", 57, 174}, + #endif + #ifdef PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK + {"ENTROPY_SOURCE_STRENGTH_TOO_WEAK", ERR_LIB_PROV, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK}, + #else + {"ENTROPY_SOURCE_STRENGTH_TOO_WEAK", 57, 186}, + #endif + #ifdef PROV_R_ERROR_INSTANTIATING_DRBG + {"ERROR_INSTANTIATING_DRBG", ERR_LIB_PROV, PROV_R_ERROR_INSTANTIATING_DRBG}, + #else + {"ERROR_INSTANTIATING_DRBG", 57, 188}, + #endif + #ifdef PROV_R_ERROR_RETRIEVING_ENTROPY + {"ERROR_RETRIEVING_ENTROPY", ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_ENTROPY}, + #else + {"ERROR_RETRIEVING_ENTROPY", 57, 189}, + #endif + #ifdef PROV_R_ERROR_RETRIEVING_NONCE + {"ERROR_RETRIEVING_NONCE", ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE}, + #else + {"ERROR_RETRIEVING_NONCE", 57, 190}, + #endif + #ifdef PROV_R_FAILED_DURING_DERIVATION + {"FAILED_DURING_DERIVATION", ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION}, + #else + {"FAILED_DURING_DERIVATION", 57, 164}, + #endif + #ifdef PROV_R_FAILED_TO_CREATE_LOCK + {"FAILED_TO_CREATE_LOCK", ERR_LIB_PROV, PROV_R_FAILED_TO_CREATE_LOCK}, + #else + {"FAILED_TO_CREATE_LOCK", 57, 180}, + #endif + #ifdef PROV_R_FAILED_TO_DECRYPT + {"FAILED_TO_DECRYPT", ERR_LIB_PROV, PROV_R_FAILED_TO_DECRYPT}, + #else + {"FAILED_TO_DECRYPT", 57, 162}, + #endif + #ifdef PROV_R_FAILED_TO_GENERATE_KEY + {"FAILED_TO_GENERATE_KEY", ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY}, + #else + {"FAILED_TO_GENERATE_KEY", 57, 121}, + #endif + #ifdef PROV_R_FAILED_TO_GET_PARAMETER + {"FAILED_TO_GET_PARAMETER", ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER}, + #else + {"FAILED_TO_GET_PARAMETER", 57, 103}, + #endif + #ifdef PROV_R_FAILED_TO_SET_PARAMETER + {"FAILED_TO_SET_PARAMETER", ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER}, + #else + {"FAILED_TO_SET_PARAMETER", 57, 104}, + #endif + #ifdef PROV_R_FAILED_TO_SIGN + {"FAILED_TO_SIGN", ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN}, + #else + {"FAILED_TO_SIGN", 57, 175}, + #endif + #ifdef PROV_R_FIPS_MODULE_CONDITIONAL_ERROR + {"FIPS_MODULE_CONDITIONAL_ERROR", ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR}, + #else + {"FIPS_MODULE_CONDITIONAL_ERROR", 57, 227}, + #endif + #ifdef PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE + {"FIPS_MODULE_ENTERING_ERROR_STATE", ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE}, + #else + {"FIPS_MODULE_ENTERING_ERROR_STATE", 57, 224}, + #endif + #ifdef PROV_R_FIPS_MODULE_IN_ERROR_STATE + {"FIPS_MODULE_IN_ERROR_STATE", ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE}, + #else + {"FIPS_MODULE_IN_ERROR_STATE", 57, 225}, + #endif + #ifdef PROV_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_PROV, PROV_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 57, 191}, + #endif + #ifdef PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", ERR_LIB_PROV, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE}, + #else + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", 57, 165}, + #endif + #ifdef PROV_R_INDICATOR_INTEGRITY_FAILURE + {"INDICATOR_INTEGRITY_FAILURE", ERR_LIB_PROV, PROV_R_INDICATOR_INTEGRITY_FAILURE}, + #else + {"INDICATOR_INTEGRITY_FAILURE", 57, 210}, + #endif + #ifdef PROV_R_INSUFFICIENT_DRBG_STRENGTH + {"INSUFFICIENT_DRBG_STRENGTH", ERR_LIB_PROV, PROV_R_INSUFFICIENT_DRBG_STRENGTH}, + #else + {"INSUFFICIENT_DRBG_STRENGTH", 57, 181}, + #endif + #ifdef PROV_R_INVALID_AAD + {"INVALID_AAD", ERR_LIB_PROV, PROV_R_INVALID_AAD}, + #else + {"INVALID_AAD", 57, 108}, + #endif + #ifdef PROV_R_INVALID_CONFIG_DATA + {"INVALID_CONFIG_DATA", ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA}, + #else + {"INVALID_CONFIG_DATA", 57, 211}, + #endif + #ifdef PROV_R_INVALID_CONSTANT_LENGTH + {"INVALID_CONSTANT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_CONSTANT_LENGTH}, + #else + {"INVALID_CONSTANT_LENGTH", 57, 157}, + #endif + #ifdef PROV_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_PROV, PROV_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 57, 176}, + #endif + #ifdef PROV_R_INVALID_CUSTOM_LENGTH + {"INVALID_CUSTOM_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH}, + #else + {"INVALID_CUSTOM_LENGTH", 57, 111}, + #endif + #ifdef PROV_R_INVALID_DATA + {"INVALID_DATA", ERR_LIB_PROV, PROV_R_INVALID_DATA}, + #else + {"INVALID_DATA", 57, 115}, + #endif + #ifdef PROV_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_PROV, PROV_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 57, 122}, + #endif + #ifdef PROV_R_INVALID_DIGEST_LENGTH + {"INVALID_DIGEST_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH}, + #else + {"INVALID_DIGEST_LENGTH", 57, 166}, + #endif + #ifdef PROV_R_INVALID_DIGEST_SIZE + {"INVALID_DIGEST_SIZE", ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE}, + #else + {"INVALID_DIGEST_SIZE", 57, 218}, + #endif + #ifdef PROV_R_INVALID_ITERATION_COUNT + {"INVALID_ITERATION_COUNT", ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT}, + #else + {"INVALID_ITERATION_COUNT", 57, 123}, + #endif + #ifdef PROV_R_INVALID_IV_LENGTH + {"INVALID_IV_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH}, + #else + {"INVALID_IV_LENGTH", 57, 109}, + #endif + #ifdef PROV_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_PROV, PROV_R_INVALID_KEY}, + #else + {"INVALID_KEY", 57, 158}, + #endif + #ifdef PROV_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 57, 105}, + #endif + #ifdef PROV_R_INVALID_MAC + {"INVALID_MAC", ERR_LIB_PROV, PROV_R_INVALID_MAC}, + #else + {"INVALID_MAC", 57, 151}, + #endif + #ifdef PROV_R_INVALID_MGF1_MD + {"INVALID_MGF1_MD", ERR_LIB_PROV, PROV_R_INVALID_MGF1_MD}, + #else + {"INVALID_MGF1_MD", 57, 167}, + #endif + #ifdef PROV_R_INVALID_MODE + {"INVALID_MODE", ERR_LIB_PROV, PROV_R_INVALID_MODE}, + #else + {"INVALID_MODE", 57, 125}, + #endif + #ifdef PROV_R_INVALID_PADDING_MODE + {"INVALID_PADDING_MODE", ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE}, + #else + {"INVALID_PADDING_MODE", 57, 168}, + #endif + #ifdef PROV_R_INVALID_PUBINFO + {"INVALID_PUBINFO", ERR_LIB_PROV, PROV_R_INVALID_PUBINFO}, + #else + {"INVALID_PUBINFO", 57, 198}, + #endif + #ifdef PROV_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 57, 112}, + #endif + #ifdef PROV_R_INVALID_SEED_LENGTH + {"INVALID_SEED_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH}, + #else + {"INVALID_SEED_LENGTH", 57, 154}, + #endif + #ifdef PROV_R_INVALID_SIGNATURE_SIZE + {"INVALID_SIGNATURE_SIZE", ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE}, + #else + {"INVALID_SIGNATURE_SIZE", 57, 179}, + #endif + #ifdef PROV_R_INVALID_STATE + {"INVALID_STATE", ERR_LIB_PROV, PROV_R_INVALID_STATE}, + #else + {"INVALID_STATE", 57, 212}, + #endif + #ifdef PROV_R_INVALID_TAG + {"INVALID_TAG", ERR_LIB_PROV, PROV_R_INVALID_TAG}, + #else + {"INVALID_TAG", 57, 110}, + #endif + #ifdef PROV_R_INVALID_TAG_LENGTH + {"INVALID_TAG_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH}, + #else + {"INVALID_TAG_LENGTH", 57, 118}, + #endif + #ifdef PROV_R_INVALID_UKM_LENGTH + {"INVALID_UKM_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_UKM_LENGTH}, + #else + {"INVALID_UKM_LENGTH", 57, 200}, + #endif + #ifdef PROV_R_INVALID_X931_DIGEST + {"INVALID_X931_DIGEST", ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST}, + #else + {"INVALID_X931_DIGEST", 57, 170}, + #endif + #ifdef PROV_R_IN_ERROR_STATE + {"IN_ERROR_STATE", ERR_LIB_PROV, PROV_R_IN_ERROR_STATE}, + #else + {"IN_ERROR_STATE", 57, 192}, + #endif + #ifdef PROV_R_KEY_SETUP_FAILED + {"KEY_SETUP_FAILED", ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED}, + #else + {"KEY_SETUP_FAILED", 57, 101}, + #endif + #ifdef PROV_R_KEY_SIZE_TOO_SMALL + {"KEY_SIZE_TOO_SMALL", ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL}, + #else + {"KEY_SIZE_TOO_SMALL", 57, 171}, + #endif + #ifdef PROV_R_MISSING_CEK_ALG + {"MISSING_CEK_ALG", ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG}, + #else + {"MISSING_CEK_ALG", 57, 144}, + #endif + #ifdef PROV_R_MISSING_CIPHER + {"MISSING_CIPHER", ERR_LIB_PROV, PROV_R_MISSING_CIPHER}, + #else + {"MISSING_CIPHER", 57, 155}, + #endif + #ifdef PROV_R_MISSING_CONFIG_DATA + {"MISSING_CONFIG_DATA", ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA}, + #else + {"MISSING_CONFIG_DATA", 57, 213}, + #endif + #ifdef PROV_R_MISSING_CONSTANT + {"MISSING_CONSTANT", ERR_LIB_PROV, PROV_R_MISSING_CONSTANT}, + #else + {"MISSING_CONSTANT", 57, 156}, + #endif + #ifdef PROV_R_MISSING_KEY + {"MISSING_KEY", ERR_LIB_PROV, PROV_R_MISSING_KEY}, + #else + {"MISSING_KEY", 57, 128}, + #endif + #ifdef PROV_R_MISSING_MAC + {"MISSING_MAC", ERR_LIB_PROV, PROV_R_MISSING_MAC}, + #else + {"MISSING_MAC", 57, 150}, + #endif + #ifdef PROV_R_MISSING_MESSAGE_DIGEST + {"MISSING_MESSAGE_DIGEST", ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST}, + #else + {"MISSING_MESSAGE_DIGEST", 57, 129}, + #endif + #ifdef PROV_R_MISSING_OID + {"MISSING_OID", ERR_LIB_PROV, PROV_R_MISSING_OID}, + #else + {"MISSING_OID", 57, 209}, + #endif + #ifdef PROV_R_MISSING_PASS + {"MISSING_PASS", ERR_LIB_PROV, PROV_R_MISSING_PASS}, + #else + {"MISSING_PASS", 57, 130}, + #endif + #ifdef PROV_R_MISSING_SALT + {"MISSING_SALT", ERR_LIB_PROV, PROV_R_MISSING_SALT}, + #else + {"MISSING_SALT", 57, 131}, + #endif + #ifdef PROV_R_MISSING_SECRET + {"MISSING_SECRET", ERR_LIB_PROV, PROV_R_MISSING_SECRET}, + #else + {"MISSING_SECRET", 57, 132}, + #endif + #ifdef PROV_R_MISSING_SEED + {"MISSING_SEED", ERR_LIB_PROV, PROV_R_MISSING_SEED}, + #else + {"MISSING_SEED", 57, 140}, + #endif + #ifdef PROV_R_MISSING_SESSION_ID + {"MISSING_SESSION_ID", ERR_LIB_PROV, PROV_R_MISSING_SESSION_ID}, + #else + {"MISSING_SESSION_ID", 57, 133}, + #endif + #ifdef PROV_R_MISSING_TYPE + {"MISSING_TYPE", ERR_LIB_PROV, PROV_R_MISSING_TYPE}, + #else + {"MISSING_TYPE", 57, 134}, + #endif + #ifdef PROV_R_MISSING_XCGHASH + {"MISSING_XCGHASH", ERR_LIB_PROV, PROV_R_MISSING_XCGHASH}, + #else + {"MISSING_XCGHASH", 57, 135}, + #endif + #ifdef PROV_R_MODULE_INTEGRITY_FAILURE + {"MODULE_INTEGRITY_FAILURE", ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE}, + #else + {"MODULE_INTEGRITY_FAILURE", 57, 214}, + #endif + #ifdef PROV_R_NOT_A_PRIVATE_KEY + {"NOT_A_PRIVATE_KEY", ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY}, + #else + {"NOT_A_PRIVATE_KEY", 57, 221}, + #endif + #ifdef PROV_R_NOT_A_PUBLIC_KEY + {"NOT_A_PUBLIC_KEY", ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY}, + #else + {"NOT_A_PUBLIC_KEY", 57, 220}, + #endif + #ifdef PROV_R_NOT_INSTANTIATED + {"NOT_INSTANTIATED", ERR_LIB_PROV, PROV_R_NOT_INSTANTIATED}, + #else + {"NOT_INSTANTIATED", 57, 193}, + #endif + #ifdef PROV_R_NOT_PARAMETERS + {"NOT_PARAMETERS", ERR_LIB_PROV, PROV_R_NOT_PARAMETERS}, + #else + {"NOT_PARAMETERS", 57, 226}, + #endif + #ifdef PROV_R_NOT_SUPPORTED + {"NOT_SUPPORTED", ERR_LIB_PROV, PROV_R_NOT_SUPPORTED}, + #else + {"NOT_SUPPORTED", 57, 136}, + #endif + #ifdef PROV_R_NOT_XOF_OR_INVALID_LENGTH + {"NOT_XOF_OR_INVALID_LENGTH", ERR_LIB_PROV, PROV_R_NOT_XOF_OR_INVALID_LENGTH}, + #else + {"NOT_XOF_OR_INVALID_LENGTH", 57, 113}, + #endif + #ifdef PROV_R_NO_KEY_SET + {"NO_KEY_SET", ERR_LIB_PROV, PROV_R_NO_KEY_SET}, + #else + {"NO_KEY_SET", 57, 114}, + #endif + #ifdef PROV_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 57, 177}, + #endif + #ifdef PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_PROV, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 57, 178}, + #endif + #ifdef PROV_R_OUTPUT_BUFFER_TOO_SMALL + {"OUTPUT_BUFFER_TOO_SMALL", ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL}, + #else + {"OUTPUT_BUFFER_TOO_SMALL", 57, 106}, + #endif + #ifdef PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS + {"PARENT_CANNOT_GENERATE_RANDOM_NUMBERS", ERR_LIB_PROV, PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS}, + #else + {"PARENT_CANNOT_GENERATE_RANDOM_NUMBERS", 57, 228}, + #endif + #ifdef PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED + {"PARENT_CANNOT_SUPPLY_ENTROPY_SEED", ERR_LIB_PROV, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED}, + #else + {"PARENT_CANNOT_SUPPLY_ENTROPY_SEED", 57, 187}, + #endif + #ifdef PROV_R_PARENT_LOCKING_NOT_ENABLED + {"PARENT_LOCKING_NOT_ENABLED", ERR_LIB_PROV, PROV_R_PARENT_LOCKING_NOT_ENABLED}, + #else + {"PARENT_LOCKING_NOT_ENABLED", 57, 182}, + #endif + #ifdef PROV_R_PARENT_STRENGTH_TOO_WEAK + {"PARENT_STRENGTH_TOO_WEAK", ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK}, + #else + {"PARENT_STRENGTH_TOO_WEAK", 57, 194}, + #endif + #ifdef PROV_R_PATH_MUST_BE_ABSOLUTE + {"PATH_MUST_BE_ABSOLUTE", ERR_LIB_PROV, PROV_R_PATH_MUST_BE_ABSOLUTE}, + #else + {"PATH_MUST_BE_ABSOLUTE", 57, 219}, + #endif + #ifdef PROV_R_PERSONALISATION_STRING_TOO_LONG + {"PERSONALISATION_STRING_TOO_LONG", ERR_LIB_PROV, PROV_R_PERSONALISATION_STRING_TOO_LONG}, + #else + {"PERSONALISATION_STRING_TOO_LONG", 57, 195}, + #endif + #ifdef PROV_R_PSS_SALTLEN_TOO_SMALL + {"PSS_SALTLEN_TOO_SMALL", ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL}, + #else + {"PSS_SALTLEN_TOO_SMALL", 57, 172}, + #endif + #ifdef PROV_R_REQUEST_TOO_LARGE_FOR_DRBG + {"REQUEST_TOO_LARGE_FOR_DRBG", ERR_LIB_PROV, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG}, + #else + {"REQUEST_TOO_LARGE_FOR_DRBG", 57, 196}, + #endif + #ifdef PROV_R_REQUIRE_CTR_MODE_CIPHER + {"REQUIRE_CTR_MODE_CIPHER", ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER}, + #else + {"REQUIRE_CTR_MODE_CIPHER", 57, 206}, + #endif + #ifdef PROV_R_RESEED_ERROR + {"RESEED_ERROR", ERR_LIB_PROV, PROV_R_RESEED_ERROR}, + #else + {"RESEED_ERROR", 57, 197}, + #endif + #ifdef PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", ERR_LIB_PROV, PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES}, + #else + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", 57, 222}, + #endif + #ifdef PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT + {"SEED_SOURCES_MUST_NOT_HAVE_A_PARENT", ERR_LIB_PROV, PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT}, + #else + {"SEED_SOURCES_MUST_NOT_HAVE_A_PARENT", 57, 229}, + #endif + #ifdef PROV_R_SELF_TEST_KAT_FAILURE + {"SELF_TEST_KAT_FAILURE", ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE}, + #else + {"SELF_TEST_KAT_FAILURE", 57, 215}, + #endif + #ifdef PROV_R_SELF_TEST_POST_FAILURE + {"SELF_TEST_POST_FAILURE", ERR_LIB_PROV, PROV_R_SELF_TEST_POST_FAILURE}, + #else + {"SELF_TEST_POST_FAILURE", 57, 216}, + #endif + #ifdef PROV_R_TAG_NOT_NEEDED + {"TAG_NOT_NEEDED", ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED}, + #else + {"TAG_NOT_NEEDED", 57, 120}, + #endif + #ifdef PROV_R_TAG_NOT_SET + {"TAG_NOT_SET", ERR_LIB_PROV, PROV_R_TAG_NOT_SET}, + #else + {"TAG_NOT_SET", 57, 119}, + #endif + #ifdef PROV_R_TOO_MANY_RECORDS + {"TOO_MANY_RECORDS", ERR_LIB_PROV, PROV_R_TOO_MANY_RECORDS}, + #else + {"TOO_MANY_RECORDS", 57, 126}, + #endif + #ifdef PROV_R_UNABLE_TO_FIND_CIPHERS + {"UNABLE_TO_FIND_CIPHERS", ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS}, + #else + {"UNABLE_TO_FIND_CIPHERS", 57, 207}, + #endif + #ifdef PROV_R_UNABLE_TO_GET_PARENT_STRENGTH + {"UNABLE_TO_GET_PARENT_STRENGTH", ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH}, + #else + {"UNABLE_TO_GET_PARENT_STRENGTH", 57, 199}, + #endif + #ifdef PROV_R_UNABLE_TO_GET_PASSPHRASE + {"UNABLE_TO_GET_PASSPHRASE", ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE}, + #else + {"UNABLE_TO_GET_PASSPHRASE", 57, 159}, + #endif + #ifdef PROV_R_UNABLE_TO_INITIALISE_CIPHERS + {"UNABLE_TO_INITIALISE_CIPHERS", ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS}, + #else + {"UNABLE_TO_INITIALISE_CIPHERS", 57, 208}, + #endif + #ifdef PROV_R_UNABLE_TO_LOAD_SHA256 + {"UNABLE_TO_LOAD_SHA256", ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256}, + #else + {"UNABLE_TO_LOAD_SHA256", 57, 147}, + #endif + #ifdef PROV_R_UNABLE_TO_LOCK_PARENT + {"UNABLE_TO_LOCK_PARENT", ERR_LIB_PROV, PROV_R_UNABLE_TO_LOCK_PARENT}, + #else + {"UNABLE_TO_LOCK_PARENT", 57, 201}, + #endif + #ifdef PROV_R_UNABLE_TO_RESEED + {"UNABLE_TO_RESEED", ERR_LIB_PROV, PROV_R_UNABLE_TO_RESEED}, + #else + {"UNABLE_TO_RESEED", 57, 204}, + #endif + #ifdef PROV_R_UNSUPPORTED_CEK_ALG + {"UNSUPPORTED_CEK_ALG", ERR_LIB_PROV, PROV_R_UNSUPPORTED_CEK_ALG}, + #else + {"UNSUPPORTED_CEK_ALG", 57, 145}, + #endif + #ifdef PROV_R_UNSUPPORTED_KEY_SIZE + {"UNSUPPORTED_KEY_SIZE", ERR_LIB_PROV, PROV_R_UNSUPPORTED_KEY_SIZE}, + #else + {"UNSUPPORTED_KEY_SIZE", 57, 153}, + #endif + #ifdef PROV_R_UNSUPPORTED_MAC_TYPE + {"UNSUPPORTED_MAC_TYPE", ERR_LIB_PROV, PROV_R_UNSUPPORTED_MAC_TYPE}, + #else + {"UNSUPPORTED_MAC_TYPE", 57, 137}, + #endif + #ifdef PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS + {"UNSUPPORTED_NUMBER_OF_ROUNDS", ERR_LIB_PROV, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS}, + #else + {"UNSUPPORTED_NUMBER_OF_ROUNDS", 57, 152}, + #endif + #ifdef PROV_R_URI_AUTHORITY_UNSUPPORTED + {"URI_AUTHORITY_UNSUPPORTED", ERR_LIB_PROV, PROV_R_URI_AUTHORITY_UNSUPPORTED}, + #else + {"URI_AUTHORITY_UNSUPPORTED", 57, 223}, + #endif + #ifdef PROV_R_VALUE_ERROR + {"VALUE_ERROR", ERR_LIB_PROV, PROV_R_VALUE_ERROR}, + #else + {"VALUE_ERROR", 57, 138}, + #endif + #ifdef PROV_R_WRONG_FINAL_BLOCK_LENGTH + {"WRONG_FINAL_BLOCK_LENGTH", ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH}, + #else + {"WRONG_FINAL_BLOCK_LENGTH", 57, 107}, + #endif + #ifdef PROV_R_WRONG_OUTPUT_BUFFER_SIZE + {"WRONG_OUTPUT_BUFFER_SIZE", ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE}, + #else + {"WRONG_OUTPUT_BUFFER_SIZE", 57, 139}, + #endif + #ifdef PROV_R_XOF_DIGESTS_NOT_ALLOWED + {"XOF_DIGESTS_NOT_ALLOWED", ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED}, + #else + {"XOF_DIGESTS_NOT_ALLOWED", 57, 183}, + #endif + #ifdef PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE + {"XTS_DATA_UNIT_IS_TOO_LARGE", ERR_LIB_PROV, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE}, + #else + {"XTS_DATA_UNIT_IS_TOO_LARGE", 57, 148}, + #endif + #ifdef PROV_R_XTS_DUPLICATED_KEYS + {"XTS_DUPLICATED_KEYS", ERR_LIB_PROV, PROV_R_XTS_DUPLICATED_KEYS}, + #else + {"XTS_DUPLICATED_KEYS", 57, 149}, + #endif + #ifdef RAND_R_ADDITIONAL_INPUT_TOO_LONG + {"ADDITIONAL_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ADDITIONAL_INPUT_TOO_LONG}, + #else + {"ADDITIONAL_INPUT_TOO_LONG", 36, 102}, + #endif + #ifdef RAND_R_ALREADY_INSTANTIATED + {"ALREADY_INSTANTIATED", ERR_LIB_RAND, RAND_R_ALREADY_INSTANTIATED}, + #else + {"ALREADY_INSTANTIATED", 36, 103}, + #endif + #ifdef RAND_R_ARGUMENT_OUT_OF_RANGE + {"ARGUMENT_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE}, + #else + {"ARGUMENT_OUT_OF_RANGE", 36, 105}, + #endif + #ifdef RAND_R_CANNOT_OPEN_FILE + {"CANNOT_OPEN_FILE", ERR_LIB_RAND, RAND_R_CANNOT_OPEN_FILE}, + #else + {"CANNOT_OPEN_FILE", 36, 121}, + #endif + #ifdef RAND_R_DERIVATION_FUNCTION_MANDATORY_FOR_FIPS + {"DERIVATION_FUNCTION_MANDATORY_FOR_FIPS", ERR_LIB_RAND, RAND_R_DERIVATION_FUNCTION_MANDATORY_FOR_FIPS}, + #else + {"DERIVATION_FUNCTION_MANDATORY_FOR_FIPS", 36, 137}, + #endif + #ifdef RAND_R_DRBG_ALREADY_INITIALIZED + {"DRBG_ALREADY_INITIALIZED", ERR_LIB_RAND, RAND_R_DRBG_ALREADY_INITIALIZED}, + #else + {"DRBG_ALREADY_INITIALIZED", 36, 129}, + #endif + #ifdef RAND_R_DRBG_NOT_INITIALISED + {"DRBG_NOT_INITIALISED", ERR_LIB_RAND, RAND_R_DRBG_NOT_INITIALISED}, + #else + {"DRBG_NOT_INITIALISED", 36, 104}, + #endif + #ifdef RAND_R_ENTROPY_INPUT_TOO_LONG + {"ENTROPY_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG}, + #else + {"ENTROPY_INPUT_TOO_LONG", 36, 106}, + #endif + #ifdef RAND_R_ENTROPY_OUT_OF_RANGE + {"ENTROPY_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ENTROPY_OUT_OF_RANGE}, + #else + {"ENTROPY_OUT_OF_RANGE", 36, 124}, + #endif + #ifdef RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED + {"ERROR_ENTROPY_POOL_WAS_IGNORED", ERR_LIB_RAND, RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED}, + #else + {"ERROR_ENTROPY_POOL_WAS_IGNORED", 36, 127}, + #endif + #ifdef RAND_R_ERROR_INITIALISING_DRBG + {"ERROR_INITIALISING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INITIALISING_DRBG}, + #else + {"ERROR_INITIALISING_DRBG", 36, 107}, + #endif + #ifdef RAND_R_ERROR_INSTANTIATING_DRBG + {"ERROR_INSTANTIATING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG}, + #else + {"ERROR_INSTANTIATING_DRBG", 36, 108}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT}, + #else + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", 36, 109}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ENTROPY + {"ERROR_RETRIEVING_ENTROPY", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY}, + #else + {"ERROR_RETRIEVING_ENTROPY", 36, 110}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_NONCE + {"ERROR_RETRIEVING_NONCE", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_NONCE}, + #else + {"ERROR_RETRIEVING_NONCE", 36, 111}, + #endif + #ifdef RAND_R_FAILED_TO_CREATE_LOCK + {"FAILED_TO_CREATE_LOCK", ERR_LIB_RAND, RAND_R_FAILED_TO_CREATE_LOCK}, + #else + {"FAILED_TO_CREATE_LOCK", 36, 126}, + #endif + #ifdef RAND_R_FUNC_NOT_IMPLEMENTED + {"FUNC_NOT_IMPLEMENTED", ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED}, + #else + {"FUNC_NOT_IMPLEMENTED", 36, 101}, + #endif + #ifdef RAND_R_FWRITE_ERROR + {"FWRITE_ERROR", ERR_LIB_RAND, RAND_R_FWRITE_ERROR}, + #else + {"FWRITE_ERROR", 36, 123}, + #endif + #ifdef RAND_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_RAND, RAND_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 36, 112}, + #endif + #ifdef RAND_R_INSUFFICIENT_DRBG_STRENGTH + {"INSUFFICIENT_DRBG_STRENGTH", ERR_LIB_RAND, RAND_R_INSUFFICIENT_DRBG_STRENGTH}, + #else + {"INSUFFICIENT_DRBG_STRENGTH", 36, 139}, + #endif + #ifdef RAND_R_INTERNAL_ERROR + {"INTERNAL_ERROR", ERR_LIB_RAND, RAND_R_INTERNAL_ERROR}, + #else + {"INTERNAL_ERROR", 36, 113}, + #endif + #ifdef RAND_R_IN_ERROR_STATE + {"IN_ERROR_STATE", ERR_LIB_RAND, RAND_R_IN_ERROR_STATE}, + #else + {"IN_ERROR_STATE", 36, 114}, + #endif + #ifdef RAND_R_NOT_A_REGULAR_FILE + {"NOT_A_REGULAR_FILE", ERR_LIB_RAND, RAND_R_NOT_A_REGULAR_FILE}, + #else + {"NOT_A_REGULAR_FILE", 36, 122}, + #endif + #ifdef RAND_R_NOT_INSTANTIATED + {"NOT_INSTANTIATED", ERR_LIB_RAND, RAND_R_NOT_INSTANTIATED}, + #else + {"NOT_INSTANTIATED", 36, 115}, + #endif + #ifdef RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED + {"NO_DRBG_IMPLEMENTATION_SELECTED", ERR_LIB_RAND, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED}, + #else + {"NO_DRBG_IMPLEMENTATION_SELECTED", 36, 128}, + #endif + #ifdef RAND_R_PARENT_LOCKING_NOT_ENABLED + {"PARENT_LOCKING_NOT_ENABLED", ERR_LIB_RAND, RAND_R_PARENT_LOCKING_NOT_ENABLED}, + #else + {"PARENT_LOCKING_NOT_ENABLED", 36, 130}, + #endif + #ifdef RAND_R_PARENT_STRENGTH_TOO_WEAK + {"PARENT_STRENGTH_TOO_WEAK", ERR_LIB_RAND, RAND_R_PARENT_STRENGTH_TOO_WEAK}, + #else + {"PARENT_STRENGTH_TOO_WEAK", 36, 131}, + #endif + #ifdef RAND_R_PERSONALISATION_STRING_TOO_LONG + {"PERSONALISATION_STRING_TOO_LONG", ERR_LIB_RAND, RAND_R_PERSONALISATION_STRING_TOO_LONG}, + #else + {"PERSONALISATION_STRING_TOO_LONG", 36, 116}, + #endif + #ifdef RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", ERR_LIB_RAND, RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED}, + #else + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", 36, 133}, + #endif + #ifdef RAND_R_PRNG_NOT_SEEDED + {"PRNG_NOT_SEEDED", ERR_LIB_RAND, RAND_R_PRNG_NOT_SEEDED}, + #else + {"PRNG_NOT_SEEDED", 36, 100}, + #endif + #ifdef RAND_R_RANDOM_POOL_OVERFLOW + {"RANDOM_POOL_OVERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW}, + #else + {"RANDOM_POOL_OVERFLOW", 36, 125}, + #endif + #ifdef RAND_R_RANDOM_POOL_UNDERFLOW + {"RANDOM_POOL_UNDERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_UNDERFLOW}, + #else + {"RANDOM_POOL_UNDERFLOW", 36, 134}, + #endif + #ifdef RAND_R_REQUEST_TOO_LARGE_FOR_DRBG + {"REQUEST_TOO_LARGE_FOR_DRBG", ERR_LIB_RAND, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG}, + #else + {"REQUEST_TOO_LARGE_FOR_DRBG", 36, 117}, + #endif + #ifdef RAND_R_RESEED_ERROR + {"RESEED_ERROR", ERR_LIB_RAND, RAND_R_RESEED_ERROR}, + #else + {"RESEED_ERROR", 36, 118}, + #endif + #ifdef RAND_R_SELFTEST_FAILURE + {"SELFTEST_FAILURE", ERR_LIB_RAND, RAND_R_SELFTEST_FAILURE}, + #else + {"SELFTEST_FAILURE", 36, 119}, + #endif + #ifdef RAND_R_TOO_LITTLE_NONCE_REQUESTED + {"TOO_LITTLE_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_LITTLE_NONCE_REQUESTED}, + #else + {"TOO_LITTLE_NONCE_REQUESTED", 36, 135}, + #endif + #ifdef RAND_R_TOO_MUCH_NONCE_REQUESTED + {"TOO_MUCH_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_MUCH_NONCE_REQUESTED}, + #else + {"TOO_MUCH_NONCE_REQUESTED", 36, 136}, + #endif + #ifdef RAND_R_UNABLE_TO_CREATE_DRBG + {"UNABLE_TO_CREATE_DRBG", ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG}, + #else + {"UNABLE_TO_CREATE_DRBG", 36, 143}, + #endif + #ifdef RAND_R_UNABLE_TO_FETCH_DRBG + {"UNABLE_TO_FETCH_DRBG", ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG}, + #else + {"UNABLE_TO_FETCH_DRBG", 36, 144}, + #endif + #ifdef RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER + {"UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER", ERR_LIB_RAND, RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER}, + #else + {"UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER", 36, 141}, + #endif + #ifdef RAND_R_UNABLE_TO_GET_PARENT_STRENGTH + {"UNABLE_TO_GET_PARENT_STRENGTH", ERR_LIB_RAND, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH}, + #else + {"UNABLE_TO_GET_PARENT_STRENGTH", 36, 138}, + #endif + #ifdef RAND_R_UNABLE_TO_LOCK_PARENT + {"UNABLE_TO_LOCK_PARENT", ERR_LIB_RAND, RAND_R_UNABLE_TO_LOCK_PARENT}, + #else + {"UNABLE_TO_LOCK_PARENT", 36, 140}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_FLAGS + {"UNSUPPORTED_DRBG_FLAGS", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_FLAGS}, + #else + {"UNSUPPORTED_DRBG_FLAGS", 36, 132}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_TYPE + {"UNSUPPORTED_DRBG_TYPE", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_TYPE}, + #else + {"UNSUPPORTED_DRBG_TYPE", 36, 120}, + #endif + #ifdef RSA_R_ALGORITHM_MISMATCH + {"ALGORITHM_MISMATCH", ERR_LIB_RSA, RSA_R_ALGORITHM_MISMATCH}, + #else + {"ALGORITHM_MISMATCH", 4, 100}, + #endif + #ifdef RSA_R_BAD_E_VALUE + {"BAD_E_VALUE", ERR_LIB_RSA, RSA_R_BAD_E_VALUE}, + #else + {"BAD_E_VALUE", 4, 101}, + #endif + #ifdef RSA_R_BAD_FIXED_HEADER_DECRYPT + {"BAD_FIXED_HEADER_DECRYPT", ERR_LIB_RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT}, + #else + {"BAD_FIXED_HEADER_DECRYPT", 4, 102}, + #endif + #ifdef RSA_R_BAD_PAD_BYTE_COUNT + {"BAD_PAD_BYTE_COUNT", ERR_LIB_RSA, RSA_R_BAD_PAD_BYTE_COUNT}, + #else + {"BAD_PAD_BYTE_COUNT", 4, 103}, + #endif + #ifdef RSA_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_RSA, RSA_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 4, 104}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_01 + {"BLOCK_TYPE_IS_NOT_01", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_01}, + #else + {"BLOCK_TYPE_IS_NOT_01", 4, 106}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_02 + {"BLOCK_TYPE_IS_NOT_02", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_02}, + #else + {"BLOCK_TYPE_IS_NOT_02", 4, 107}, + #endif + #ifdef RSA_R_DATA_GREATER_THAN_MOD_LEN + {"DATA_GREATER_THAN_MOD_LEN", ERR_LIB_RSA, RSA_R_DATA_GREATER_THAN_MOD_LEN}, + #else + {"DATA_GREATER_THAN_MOD_LEN", 4, 108}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE + {"DATA_TOO_LARGE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE}, + #else + {"DATA_TOO_LARGE", 4, 109}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE + {"DATA_TOO_LARGE_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE}, + #else + {"DATA_TOO_LARGE_FOR_KEY_SIZE", 4, 110}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_MODULUS + {"DATA_TOO_LARGE_FOR_MODULUS", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS}, + #else + {"DATA_TOO_LARGE_FOR_MODULUS", 4, 132}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL + {"DATA_TOO_SMALL", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL}, + #else + {"DATA_TOO_SMALL", 4, 111}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE + {"DATA_TOO_SMALL_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE}, + #else + {"DATA_TOO_SMALL_FOR_KEY_SIZE", 4, 122}, + #endif + #ifdef RSA_R_DIGEST_DOES_NOT_MATCH + {"DIGEST_DOES_NOT_MATCH", ERR_LIB_RSA, RSA_R_DIGEST_DOES_NOT_MATCH}, + #else + {"DIGEST_DOES_NOT_MATCH", 4, 158}, + #endif + #ifdef RSA_R_DIGEST_NOT_ALLOWED + {"DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED}, + #else + {"DIGEST_NOT_ALLOWED", 4, 145}, + #endif + #ifdef RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY + {"DIGEST_TOO_BIG_FOR_RSA_KEY", ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY}, + #else + {"DIGEST_TOO_BIG_FOR_RSA_KEY", 4, 112}, + #endif + #ifdef RSA_R_DMP1_NOT_CONGRUENT_TO_D + {"DMP1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMP1_NOT_CONGRUENT_TO_D}, + #else + {"DMP1_NOT_CONGRUENT_TO_D", 4, 124}, + #endif + #ifdef RSA_R_DMQ1_NOT_CONGRUENT_TO_D + {"DMQ1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMQ1_NOT_CONGRUENT_TO_D}, + #else + {"DMQ1_NOT_CONGRUENT_TO_D", 4, 125}, + #endif + #ifdef RSA_R_D_E_NOT_CONGRUENT_TO_1 + {"D_E_NOT_CONGRUENT_TO_1", ERR_LIB_RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1}, + #else + {"D_E_NOT_CONGRUENT_TO_1", 4, 123}, + #endif + #ifdef RSA_R_FIRST_OCTET_INVALID + {"FIRST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_FIRST_OCTET_INVALID}, + #else + {"FIRST_OCTET_INVALID", 4, 133}, + #endif + #ifdef RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE}, + #else + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", 4, 144}, + #endif + #ifdef RSA_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 4, 157}, + #endif + #ifdef RSA_R_INVALID_DIGEST_LENGTH + {"INVALID_DIGEST_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH}, + #else + {"INVALID_DIGEST_LENGTH", 4, 143}, + #endif + #ifdef RSA_R_INVALID_HEADER + {"INVALID_HEADER", ERR_LIB_RSA, RSA_R_INVALID_HEADER}, + #else + {"INVALID_HEADER", 4, 137}, + #endif + #ifdef RSA_R_INVALID_KEYPAIR + {"INVALID_KEYPAIR", ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR}, + #else + {"INVALID_KEYPAIR", 4, 171}, + #endif + #ifdef RSA_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 4, 173}, + #endif + #ifdef RSA_R_INVALID_LABEL + {"INVALID_LABEL", ERR_LIB_RSA, RSA_R_INVALID_LABEL}, + #else + {"INVALID_LABEL", 4, 160}, + #endif + #ifdef RSA_R_INVALID_MESSAGE_LENGTH + {"INVALID_MESSAGE_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH}, + #else + {"INVALID_MESSAGE_LENGTH", 4, 131}, + #endif + #ifdef RSA_R_INVALID_MGF1_MD + {"INVALID_MGF1_MD", ERR_LIB_RSA, RSA_R_INVALID_MGF1_MD}, + #else + {"INVALID_MGF1_MD", 4, 156}, + #endif + #ifdef RSA_R_INVALID_MODULUS + {"INVALID_MODULUS", ERR_LIB_RSA, RSA_R_INVALID_MODULUS}, + #else + {"INVALID_MODULUS", 4, 174}, + #endif + #ifdef RSA_R_INVALID_MULTI_PRIME_KEY + {"INVALID_MULTI_PRIME_KEY", ERR_LIB_RSA, RSA_R_INVALID_MULTI_PRIME_KEY}, + #else + {"INVALID_MULTI_PRIME_KEY", 4, 167}, + #endif + #ifdef RSA_R_INVALID_OAEP_PARAMETERS + {"INVALID_OAEP_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_OAEP_PARAMETERS}, + #else + {"INVALID_OAEP_PARAMETERS", 4, 161}, + #endif + #ifdef RSA_R_INVALID_PADDING + {"INVALID_PADDING", ERR_LIB_RSA, RSA_R_INVALID_PADDING}, + #else + {"INVALID_PADDING", 4, 138}, + #endif + #ifdef RSA_R_INVALID_PADDING_MODE + {"INVALID_PADDING_MODE", ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE}, + #else + {"INVALID_PADDING_MODE", 4, 141}, + #endif + #ifdef RSA_R_INVALID_PSS_PARAMETERS + {"INVALID_PSS_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS}, + #else + {"INVALID_PSS_PARAMETERS", 4, 149}, + #endif + #ifdef RSA_R_INVALID_PSS_SALTLEN + {"INVALID_PSS_SALTLEN", ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN}, + #else + {"INVALID_PSS_SALTLEN", 4, 146}, + #endif + #ifdef RSA_R_INVALID_REQUEST + {"INVALID_REQUEST", ERR_LIB_RSA, RSA_R_INVALID_REQUEST}, + #else + {"INVALID_REQUEST", 4, 175}, + #endif + #ifdef RSA_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 4, 150}, + #endif + #ifdef RSA_R_INVALID_STRENGTH + {"INVALID_STRENGTH", ERR_LIB_RSA, RSA_R_INVALID_STRENGTH}, + #else + {"INVALID_STRENGTH", 4, 176}, + #endif + #ifdef RSA_R_INVALID_TRAILER + {"INVALID_TRAILER", ERR_LIB_RSA, RSA_R_INVALID_TRAILER}, + #else + {"INVALID_TRAILER", 4, 139}, + #endif + #ifdef RSA_R_INVALID_X931_DIGEST + {"INVALID_X931_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_X931_DIGEST}, + #else + {"INVALID_X931_DIGEST", 4, 142}, + #endif + #ifdef RSA_R_IQMP_NOT_INVERSE_OF_Q + {"IQMP_NOT_INVERSE_OF_Q", ERR_LIB_RSA, RSA_R_IQMP_NOT_INVERSE_OF_Q}, + #else + {"IQMP_NOT_INVERSE_OF_Q", 4, 126}, + #endif + #ifdef RSA_R_KEY_PRIME_NUM_INVALID + {"KEY_PRIME_NUM_INVALID", ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID}, + #else + {"KEY_PRIME_NUM_INVALID", 4, 165}, + #endif + #ifdef RSA_R_KEY_SIZE_TOO_SMALL + {"KEY_SIZE_TOO_SMALL", ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL}, + #else + {"KEY_SIZE_TOO_SMALL", 4, 120}, + #endif + #ifdef RSA_R_LAST_OCTET_INVALID + {"LAST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_LAST_OCTET_INVALID}, + #else + {"LAST_OCTET_INVALID", 4, 134}, + #endif + #ifdef RSA_R_MGF1_DIGEST_NOT_ALLOWED + {"MGF1_DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED}, + #else + {"MGF1_DIGEST_NOT_ALLOWED", 4, 152}, + #endif + #ifdef RSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_RSA, RSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 4, 179}, + #endif + #ifdef RSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 4, 105}, + #endif + #ifdef RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", ERR_LIB_RSA, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R}, + #else + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", 4, 168}, + #endif + #ifdef RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D}, + #else + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", 4, 169}, + #endif + #ifdef RSA_R_MP_R_NOT_PRIME + {"MP_R_NOT_PRIME", ERR_LIB_RSA, RSA_R_MP_R_NOT_PRIME}, + #else + {"MP_R_NOT_PRIME", 4, 170}, + #endif + #ifdef RSA_R_NO_PUBLIC_EXPONENT + {"NO_PUBLIC_EXPONENT", ERR_LIB_RSA, RSA_R_NO_PUBLIC_EXPONENT}, + #else + {"NO_PUBLIC_EXPONENT", 4, 140}, + #endif + #ifdef RSA_R_NULL_BEFORE_BLOCK_MISSING + {"NULL_BEFORE_BLOCK_MISSING", ERR_LIB_RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING}, + #else + {"NULL_BEFORE_BLOCK_MISSING", 4, 113}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES}, + #else + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", 4, 172}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_P_Q + {"N_DOES_NOT_EQUAL_P_Q", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_P_Q}, + #else + {"N_DOES_NOT_EQUAL_P_Q", 4, 127}, + #endif + #ifdef RSA_R_OAEP_DECODING_ERROR + {"OAEP_DECODING_ERROR", ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR}, + #else + {"OAEP_DECODING_ERROR", 4, 121}, + #endif + #ifdef RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_RSA, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 4, 148}, + #endif + #ifdef RSA_R_PADDING_CHECK_FAILED + {"PADDING_CHECK_FAILED", ERR_LIB_RSA, RSA_R_PADDING_CHECK_FAILED}, + #else + {"PADDING_CHECK_FAILED", 4, 114}, + #endif + #ifdef RSA_R_PAIRWISE_TEST_FAILURE + {"PAIRWISE_TEST_FAILURE", ERR_LIB_RSA, RSA_R_PAIRWISE_TEST_FAILURE}, + #else + {"PAIRWISE_TEST_FAILURE", 4, 177}, + #endif + #ifdef RSA_R_PKCS_DECODING_ERROR + {"PKCS_DECODING_ERROR", ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR}, + #else + {"PKCS_DECODING_ERROR", 4, 159}, + #endif + #ifdef RSA_R_PSS_SALTLEN_TOO_SMALL + {"PSS_SALTLEN_TOO_SMALL", ERR_LIB_RSA, RSA_R_PSS_SALTLEN_TOO_SMALL}, + #else + {"PSS_SALTLEN_TOO_SMALL", 4, 164}, + #endif + #ifdef RSA_R_PUB_EXPONENT_OUT_OF_RANGE + {"PUB_EXPONENT_OUT_OF_RANGE", ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE}, + #else + {"PUB_EXPONENT_OUT_OF_RANGE", 4, 178}, + #endif + #ifdef RSA_R_P_NOT_PRIME + {"P_NOT_PRIME", ERR_LIB_RSA, RSA_R_P_NOT_PRIME}, + #else + {"P_NOT_PRIME", 4, 128}, + #endif + #ifdef RSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_RSA, RSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 4, 129}, + #endif + #ifdef RSA_R_RSA_OPERATIONS_NOT_SUPPORTED + {"RSA_OPERATIONS_NOT_SUPPORTED", ERR_LIB_RSA, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED}, + #else + {"RSA_OPERATIONS_NOT_SUPPORTED", 4, 130}, + #endif + #ifdef RSA_R_SLEN_CHECK_FAILED + {"SLEN_CHECK_FAILED", ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED}, + #else + {"SLEN_CHECK_FAILED", 4, 136}, + #endif + #ifdef RSA_R_SLEN_RECOVERY_FAILED + {"SLEN_RECOVERY_FAILED", ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED}, + #else + {"SLEN_RECOVERY_FAILED", 4, 135}, + #endif + #ifdef RSA_R_SSLV3_ROLLBACK_ATTACK + {"SSLV3_ROLLBACK_ATTACK", ERR_LIB_RSA, RSA_R_SSLV3_ROLLBACK_ATTACK}, + #else + {"SSLV3_ROLLBACK_ATTACK", 4, 115}, + #endif + #ifdef RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_RSA, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 4, 116}, + #endif + #ifdef RSA_R_UNKNOWN_ALGORITHM_TYPE + {"UNKNOWN_ALGORITHM_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE}, + #else + {"UNKNOWN_ALGORITHM_TYPE", 4, 117}, + #endif + #ifdef RSA_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 4, 166}, + #endif + #ifdef RSA_R_UNKNOWN_MASK_DIGEST + {"UNKNOWN_MASK_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_MASK_DIGEST}, + #else + {"UNKNOWN_MASK_DIGEST", 4, 151}, + #endif + #ifdef RSA_R_UNKNOWN_PADDING_TYPE + {"UNKNOWN_PADDING_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE}, + #else + {"UNKNOWN_PADDING_TYPE", 4, 118}, + #endif + #ifdef RSA_R_UNSUPPORTED_ENCRYPTION_TYPE + {"UNSUPPORTED_ENCRYPTION_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE}, + #else + {"UNSUPPORTED_ENCRYPTION_TYPE", 4, 162}, + #endif + #ifdef RSA_R_UNSUPPORTED_LABEL_SOURCE + {"UNSUPPORTED_LABEL_SOURCE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_LABEL_SOURCE}, + #else + {"UNSUPPORTED_LABEL_SOURCE", 4, 163}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_ALGORITHM + {"UNSUPPORTED_MASK_ALGORITHM", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_ALGORITHM}, + #else + {"UNSUPPORTED_MASK_ALGORITHM", 4, 153}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_PARAMETER + {"UNSUPPORTED_MASK_PARAMETER", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_PARAMETER}, + #else + {"UNSUPPORTED_MASK_PARAMETER", 4, 154}, + #endif + #ifdef RSA_R_UNSUPPORTED_SIGNATURE_TYPE + {"UNSUPPORTED_SIGNATURE_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE}, + #else + {"UNSUPPORTED_SIGNATURE_TYPE", 4, 155}, + #endif + #ifdef RSA_R_VALUE_MISSING + {"VALUE_MISSING", ERR_LIB_RSA, RSA_R_VALUE_MISSING}, + #else + {"VALUE_MISSING", 4, 147}, + #endif + #ifdef RSA_R_WRONG_SIGNATURE_LENGTH + {"WRONG_SIGNATURE_LENGTH", ERR_LIB_RSA, RSA_R_WRONG_SIGNATURE_LENGTH}, + #else + {"WRONG_SIGNATURE_LENGTH", 4, 119}, + #endif + #ifdef SM2_R_ASN1_ERROR + {"ASN1_ERROR", ERR_LIB_SM2, SM2_R_ASN1_ERROR}, + #else + {"ASN1_ERROR", 53, 100}, + #endif + #ifdef SM2_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_SM2, SM2_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 53, 101}, + #endif + #ifdef SM2_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_SM2, SM2_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 53, 107}, + #endif + #ifdef SM2_R_DIST_ID_TOO_LARGE + {"DIST_ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_DIST_ID_TOO_LARGE}, + #else + {"DIST_ID_TOO_LARGE", 53, 110}, + #endif + #ifdef SM2_R_ID_NOT_SET + {"ID_NOT_SET", ERR_LIB_SM2, SM2_R_ID_NOT_SET}, + #else + {"ID_NOT_SET", 53, 112}, + #endif + #ifdef SM2_R_ID_TOO_LARGE + {"ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_ID_TOO_LARGE}, + #else + {"ID_TOO_LARGE", 53, 111}, + #endif + #ifdef SM2_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_SM2, SM2_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 53, 108}, + #endif + #ifdef SM2_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_SM2, SM2_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 53, 102}, + #endif + #ifdef SM2_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_SM2, SM2_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 53, 103}, + #endif + #ifdef SM2_R_INVALID_ENCODING + {"INVALID_ENCODING", ERR_LIB_SM2, SM2_R_INVALID_ENCODING}, + #else + {"INVALID_ENCODING", 53, 104}, + #endif + #ifdef SM2_R_INVALID_FIELD + {"INVALID_FIELD", ERR_LIB_SM2, SM2_R_INVALID_FIELD}, + #else + {"INVALID_FIELD", 53, 105}, + #endif + #ifdef SM2_R_INVALID_PRIVATE_KEY + {"INVALID_PRIVATE_KEY", ERR_LIB_SM2, SM2_R_INVALID_PRIVATE_KEY}, + #else + {"INVALID_PRIVATE_KEY", 53, 113}, + #endif + #ifdef SM2_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_SM2, SM2_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 53, 109}, + #endif + #ifdef SM2_R_USER_ID_TOO_LARGE + {"USER_ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_USER_ID_TOO_LARGE}, + #else + {"USER_ID_TOO_LARGE", 53, 106}, + #endif + #ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY + {"APPLICATION_DATA_AFTER_CLOSE_NOTIFY", ERR_LIB_SSL, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY}, + #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 + {"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 + {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", 20, 272}, + #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 + {"AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE", 20, 143}, + #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 + {"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 + {"BAD_CHANGE_CIPHER_SPEC", 20, 103}, + #endif + #ifdef SSL_R_BAD_CIPHER + {"BAD_CIPHER", ERR_LIB_SSL, SSL_R_BAD_CIPHER}, + #else + {"BAD_CIPHER", 20, 186}, + #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 + {"BAD_DATA_RETURNED_BY_CALLBACK", 20, 106}, + #endif + #ifdef SSL_R_BAD_DECOMPRESSION + {"BAD_DECOMPRESSION", ERR_LIB_SSL, SSL_R_BAD_DECOMPRESSION}, + #else + {"BAD_DECOMPRESSION", 20, 107}, + #endif + #ifdef SSL_R_BAD_DH_VALUE + {"BAD_DH_VALUE", ERR_LIB_SSL, SSL_R_BAD_DH_VALUE}, + #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 + {"BAD_DIGEST_LENGTH", 20, 111}, + #endif + #ifdef SSL_R_BAD_EARLY_DATA + {"BAD_EARLY_DATA", ERR_LIB_SSL, SSL_R_BAD_EARLY_DATA}, + #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 + {"BAD_ECC_CERT", 20, 304}, + #endif + #ifdef SSL_R_BAD_ECPOINT + {"BAD_ECPOINT", ERR_LIB_SSL, SSL_R_BAD_ECPOINT}, + #else + {"BAD_ECPOINT", 20, 306}, + #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 + {"BAD_HANDSHAKE_LENGTH", 20, 332}, + #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 + {"BAD_HELLO_REQUEST", 20, 105}, + #endif + #ifdef SSL_R_BAD_HRR_VERSION + {"BAD_HRR_VERSION", ERR_LIB_SSL, SSL_R_BAD_HRR_VERSION}, + #else + {"BAD_HRR_VERSION", 20, 263}, + #endif + #ifdef SSL_R_BAD_KEY_SHARE + {"BAD_KEY_SHARE", ERR_LIB_SSL, SSL_R_BAD_KEY_SHARE}, + #else + {"BAD_KEY_SHARE", 20, 108}, + #endif + #ifdef SSL_R_BAD_KEY_UPDATE + {"BAD_KEY_UPDATE", ERR_LIB_SSL, SSL_R_BAD_KEY_UPDATE}, + #else + {"BAD_KEY_UPDATE", 20, 122}, + #endif + #ifdef SSL_R_BAD_LEGACY_VERSION + {"BAD_LEGACY_VERSION", ERR_LIB_SSL, SSL_R_BAD_LEGACY_VERSION}, + #else + {"BAD_LEGACY_VERSION", 20, 292}, + #endif + #ifdef SSL_R_BAD_LENGTH + {"BAD_LENGTH", ERR_LIB_SSL, SSL_R_BAD_LENGTH}, + #else + {"BAD_LENGTH", 20, 271}, + #endif + #ifdef SSL_R_BAD_PACKET + {"BAD_PACKET", ERR_LIB_SSL, SSL_R_BAD_PACKET}, + #else + {"BAD_PACKET", 20, 240}, + #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 + {"BAD_PROTOCOL_VERSION_NUMBER", 20, 116}, + #endif + #ifdef SSL_R_BAD_PSK + {"BAD_PSK", ERR_LIB_SSL, SSL_R_BAD_PSK}, + #else + {"BAD_PSK", 20, 219}, + #endif + #ifdef SSL_R_BAD_PSK_IDENTITY + {"BAD_PSK_IDENTITY", ERR_LIB_SSL, SSL_R_BAD_PSK_IDENTITY}, + #else + {"BAD_PSK_IDENTITY", 20, 114}, + #endif + #ifdef SSL_R_BAD_RECORD_TYPE + {"BAD_RECORD_TYPE", ERR_LIB_SSL, SSL_R_BAD_RECORD_TYPE}, + #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 + {"BAD_RSA_ENCRYPT", 20, 119}, + #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 + {"BAD_SRP_A_LENGTH", 20, 347}, + #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_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 + {"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 + {"BAD_SSL_FILETYPE", 20, 124}, + #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 + {"BAD_WRITE_RETRY", 20, 127}, + #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 + {"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 + {"BLOCK_CIPHER_PAD_IS_WRONG", 20, 129}, + #endif + #ifdef SSL_R_BN_LIB + {"BN_LIB", ERR_LIB_SSL, SSL_R_BN_LIB}, + #else + {"BN_LIB", 20, 130}, + #endif + #ifdef SSL_R_CALLBACK_FAILED + {"CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_CALLBACK_FAILED}, + #else + {"CALLBACK_FAILED", 20, 234}, + #endif + #ifdef SSL_R_CANNOT_CHANGE_CIPHER + {"CANNOT_CHANGE_CIPHER", ERR_LIB_SSL, SSL_R_CANNOT_CHANGE_CIPHER}, + #else + {"CANNOT_CHANGE_CIPHER", 20, 109}, + #endif + #ifdef SSL_R_CANNOT_GET_GROUP_NAME + {"CANNOT_GET_GROUP_NAME", ERR_LIB_SSL, SSL_R_CANNOT_GET_GROUP_NAME}, + #else + {"CANNOT_GET_GROUP_NAME", 20, 299}, + #endif + #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 + {"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 + {"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 + {"CCS_RECEIVED_EARLY", 20, 133}, + #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 + {"CERT_CB_ERROR", 20, 377}, + #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 + #ifdef SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED + {"CIPHERSUITE_DIGEST_HAS_CHANGED", ERR_LIB_SSL, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED}, + #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 + {"CIPHER_CODE_WRONG_LENGTH", 20, 137}, + #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 + {"COMPRESSED_LENGTH_TOO_LONG", 20, 140}, + #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 + {"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 + {"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 + {"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 + {"CONNECTION_TYPE_NOT_SET", 20, 144}, + #endif + #ifdef SSL_R_CONTEXT_NOT_DANE_ENABLED + {"CONTEXT_NOT_DANE_ENABLED", ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED}, + #else + {"CONTEXT_NOT_DANE_ENABLED", 20, 167}, + #endif + #ifdef SSL_R_COOKIE_GEN_CALLBACK_FAILURE + {"COOKIE_GEN_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_COOKIE_GEN_CALLBACK_FAILURE}, + #else + {"COOKIE_GEN_CALLBACK_FAILURE", 20, 400}, + #endif + #ifdef SSL_R_COOKIE_MISMATCH + {"COOKIE_MISMATCH", ERR_LIB_SSL, SSL_R_COOKIE_MISMATCH}, + #else + {"COOKIE_MISMATCH", 20, 308}, + #endif + #ifdef SSL_R_COPY_PARAMETERS_FAILED + {"COPY_PARAMETERS_FAILED", ERR_LIB_SSL, SSL_R_COPY_PARAMETERS_FAILED}, + #else + {"COPY_PARAMETERS_FAILED", 20, 296}, + #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 + {"CUSTOM_EXT_HANDLER_ALREADY_INSTALLED", 20, 206}, + #endif + #ifdef SSL_R_DANE_ALREADY_ENABLED + {"DANE_ALREADY_ENABLED", ERR_LIB_SSL, SSL_R_DANE_ALREADY_ENABLED}, + #else + {"DANE_ALREADY_ENABLED", 20, 172}, + #endif + #ifdef SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", ERR_LIB_SSL, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL}, + #else + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", 20, 173}, + #endif + #ifdef SSL_R_DANE_NOT_ENABLED + {"DANE_NOT_ENABLED", ERR_LIB_SSL, SSL_R_DANE_NOT_ENABLED}, + #else + {"DANE_NOT_ENABLED", 20, 175}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE + {"DANE_TLSA_BAD_CERTIFICATE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE", 20, 180}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", 20, 184}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DATA_LENGTH + {"DANE_TLSA_BAD_DATA_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DATA_LENGTH}, + #else + {"DANE_TLSA_BAD_DATA_LENGTH", 20, 189}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH + {"DANE_TLSA_BAD_DIGEST_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH}, + #else + {"DANE_TLSA_BAD_DIGEST_LENGTH", 20, 192}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_MATCHING_TYPE + {"DANE_TLSA_BAD_MATCHING_TYPE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE}, + #else + {"DANE_TLSA_BAD_MATCHING_TYPE", 20, 200}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_PUBLIC_KEY + {"DANE_TLSA_BAD_PUBLIC_KEY", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY}, + #else + {"DANE_TLSA_BAD_PUBLIC_KEY", 20, 201}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_SELECTOR + {"DANE_TLSA_BAD_SELECTOR", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_SELECTOR}, + #else + {"DANE_TLSA_BAD_SELECTOR", 20, 202}, + #endif + #ifdef SSL_R_DANE_TLSA_NULL_DATA + {"DANE_TLSA_NULL_DATA", ERR_LIB_SSL, SSL_R_DANE_TLSA_NULL_DATA}, + #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 + {"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 + {"DATA_LENGTH_TOO_LONG", 20, 146}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"DUPLICATE_COMPRESSION_ID", 20, 309}, + #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_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_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 + {"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 + {"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 + {"ERROR_IN_RECEIVED_CIPHER_LIST", 20, 151}, + #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 + {"ERROR_SETTING_TLSA_BASE_DOMAIN", 20, 204}, + #endif + #ifdef SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE + {"EXCEEDS_MAX_FRAGMENT_SIZE", ERR_LIB_SSL, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE}, + #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 + {"EXCESSIVE_MESSAGE_SIZE", 20, 152}, + #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 + {"EXTRA_DATA_IN_MESSAGE", 20, 153}, + #endif + #ifdef SSL_R_EXT_LENGTH_MISMATCH + {"EXT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_EXT_LENGTH_MISMATCH}, + #else + {"EXT_LENGTH_MISMATCH", 20, 163}, + #endif + #ifdef SSL_R_FAILED_TO_INIT_ASYNC + {"FAILED_TO_INIT_ASYNC", ERR_LIB_SSL, SSL_R_FAILED_TO_INIT_ASYNC}, + #else + {"FAILED_TO_INIT_ASYNC", 20, 405}, + #endif + #ifdef SSL_R_FRAGMENTED_CLIENT_HELLO + {"FRAGMENTED_CLIENT_HELLO", ERR_LIB_SSL, SSL_R_FRAGMENTED_CLIENT_HELLO}, + #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 + {"GOT_A_FIN_BEFORE_A_CCS", 20, 154}, + #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 + {"HTTP_REQUEST", 20, 156}, + #endif + #ifdef SSL_R_ILLEGAL_POINT_COMPRESSION + {"ILLEGAL_POINT_COMPRESSION", ERR_LIB_SSL, SSL_R_ILLEGAL_POINT_COMPRESSION}, + #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 + {"ILLEGAL_SUITEB_DIGEST", 20, 380}, + #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 + {"INCONSISTENT_COMPRESSION", 20, 340}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_ALPN + {"INCONSISTENT_EARLY_DATA_ALPN", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_ALPN}, + #else + {"INCONSISTENT_EARLY_DATA_ALPN", 20, 222}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_SNI + {"INCONSISTENT_EARLY_DATA_SNI", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_SNI}, + #else + {"INCONSISTENT_EARLY_DATA_SNI", 20, 231}, + #endif + #ifdef SSL_R_INCONSISTENT_EXTMS + {"INCONSISTENT_EXTMS", ERR_LIB_SSL, SSL_R_INCONSISTENT_EXTMS}, + #else + {"INCONSISTENT_EXTMS", 20, 104}, + #endif + #ifdef SSL_R_INSUFFICIENT_SECURITY + {"INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_INSUFFICIENT_SECURITY}, + #else + {"INSUFFICIENT_SECURITY", 20, 241}, + #endif + #ifdef SSL_R_INVALID_ALERT + {"INVALID_ALERT", ERR_LIB_SSL, SSL_R_INVALID_ALERT}, + #else + {"INVALID_ALERT", 20, 205}, + #endif + #ifdef SSL_R_INVALID_CCS_MESSAGE + {"INVALID_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_INVALID_CCS_MESSAGE}, + #else + {"INVALID_CCS_MESSAGE", 20, 260}, + #endif + #ifdef SSL_R_INVALID_CERTIFICATE_OR_ALG + {"INVALID_CERTIFICATE_OR_ALG", ERR_LIB_SSL, SSL_R_INVALID_CERTIFICATE_OR_ALG}, + #else + {"INVALID_CERTIFICATE_OR_ALG", 20, 238}, + #endif + #ifdef SSL_R_INVALID_COMMAND + {"INVALID_COMMAND", ERR_LIB_SSL, SSL_R_INVALID_COMMAND}, + #else + {"INVALID_COMMAND", 20, 280}, + #endif + #ifdef SSL_R_INVALID_COMPRESSION_ALGORITHM + {"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_INVALID_COMPRESSION_ALGORITHM}, + #else + {"INVALID_COMPRESSION_ALGORITHM", 20, 341}, + #endif + #ifdef SSL_R_INVALID_CONFIG + {"INVALID_CONFIG", ERR_LIB_SSL, SSL_R_INVALID_CONFIG}, + #else + {"INVALID_CONFIG", 20, 283}, + #endif + #ifdef SSL_R_INVALID_CONFIGURATION_NAME + {"INVALID_CONFIGURATION_NAME", ERR_LIB_SSL, SSL_R_INVALID_CONFIGURATION_NAME}, + #else + {"INVALID_CONFIGURATION_NAME", 20, 113}, + #endif + #ifdef SSL_R_INVALID_CONTEXT + {"INVALID_CONTEXT", ERR_LIB_SSL, SSL_R_INVALID_CONTEXT}, + #else + {"INVALID_CONTEXT", 20, 282}, + #endif + #ifdef SSL_R_INVALID_CT_VALIDATION_TYPE + {"INVALID_CT_VALIDATION_TYPE", ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE}, + #else + {"INVALID_CT_VALIDATION_TYPE", 20, 212}, + #endif + #ifdef SSL_R_INVALID_KEY_UPDATE_TYPE + {"INVALID_KEY_UPDATE_TYPE", ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE}, + #else + {"INVALID_KEY_UPDATE_TYPE", 20, 120}, + #endif + #ifdef SSL_R_INVALID_MAX_EARLY_DATA + {"INVALID_MAX_EARLY_DATA", ERR_LIB_SSL, SSL_R_INVALID_MAX_EARLY_DATA}, + #else + {"INVALID_MAX_EARLY_DATA", 20, 174}, + #endif + #ifdef SSL_R_INVALID_NULL_CMD_NAME + {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME}, + #else + {"INVALID_NULL_CMD_NAME", 20, 385}, + #endif + #ifdef SSL_R_INVALID_SEQUENCE_NUMBER + {"INVALID_SEQUENCE_NUMBER", ERR_LIB_SSL, SSL_R_INVALID_SEQUENCE_NUMBER}, + #else + {"INVALID_SEQUENCE_NUMBER", 20, 402}, + #endif + #ifdef SSL_R_INVALID_SERVERINFO_DATA + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA}, + #else + {"INVALID_SERVERINFO_DATA", 20, 388}, + #endif + #ifdef SSL_R_INVALID_SESSION_ID + {"INVALID_SESSION_ID", ERR_LIB_SSL, SSL_R_INVALID_SESSION_ID}, + #else + {"INVALID_SESSION_ID", 20, 999}, + #endif + #ifdef SSL_R_INVALID_SRP_USERNAME + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME}, + #else + {"INVALID_SRP_USERNAME", 20, 357}, + #endif + #ifdef SSL_R_INVALID_STATUS_RESPONSE + {"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE}, + #else + {"INVALID_STATUS_RESPONSE", 20, 328}, + #endif + #ifdef SSL_R_INVALID_TICKET_KEYS_LENGTH + {"INVALID_TICKET_KEYS_LENGTH", ERR_LIB_SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH}, + #else + {"INVALID_TICKET_KEYS_LENGTH", 20, 325}, + #endif + #ifdef SSL_R_LENGTH_MISMATCH + {"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH}, + #else + {"LENGTH_MISMATCH", 20, 159}, + #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 + {"LENGTH_TOO_SHORT", 20, 160}, + #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 + {"LIBRARY_HAS_NO_CIPHERS", 20, 161}, + #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_ECDSA_SIGNING_CERT + {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDSA_SIGNING_CERT}, + #else + {"MISSING_ECDSA_SIGNING_CERT", 20, 381}, + #endif + #ifdef SSL_R_MISSING_FATAL + {"MISSING_FATAL", ERR_LIB_SSL, SSL_R_MISSING_FATAL}, + #else + {"MISSING_FATAL", 20, 256}, + #endif + #ifdef SSL_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 20, 290}, + #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 + {"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 + {"MISSING_RSA_SIGNING_CERT", 20, 170}, + #endif + #ifdef SSL_R_MISSING_SIGALGS_EXTENSION + {"MISSING_SIGALGS_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_SIGALGS_EXTENSION}, + #else + {"MISSING_SIGALGS_EXTENSION", 20, 112}, + #endif + #ifdef SSL_R_MISSING_SIGNING_CERT + {"MISSING_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_SIGNING_CERT}, + #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 + {"MISSING_SRP_PARAM", 20, 358}, + #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 + {"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 + {"MISSING_TMP_ECDH_KEY", 20, 311}, + #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 + {"MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA", 20, 293}, + #endif + #ifdef SSL_R_NOT_ON_RECORD_BOUNDARY + {"NOT_ON_RECORD_BOUNDARY", ERR_LIB_SSL, SSL_R_NOT_ON_RECORD_BOUNDARY}, + #else + {"NOT_ON_RECORD_BOUNDARY", 20, 182}, + #endif + #ifdef SSL_R_NOT_REPLACING_CERTIFICATE + {"NOT_REPLACING_CERTIFICATE", ERR_LIB_SSL, SSL_R_NOT_REPLACING_CERTIFICATE}, + #else + {"NOT_REPLACING_CERTIFICATE", 20, 289}, + #endif + #ifdef SSL_R_NOT_SERVER + {"NOT_SERVER", ERR_LIB_SSL, SSL_R_NOT_SERVER}, + #else + {"NOT_SERVER", 20, 284}, + #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 + {"NO_CERTIFICATES_RETURNED", 20, 176}, + #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 + {"NO_CERTIFICATE_SET", 20, 179}, + #endif + #ifdef SSL_R_NO_CHANGE_FOLLOWING_HRR + {"NO_CHANGE_FOLLOWING_HRR", ERR_LIB_SSL, SSL_R_NO_CHANGE_FOLLOWING_HRR}, + #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 + {"NO_CIPHERS_AVAILABLE", 20, 181}, + #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 + {"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 + {"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 + {"NO_COMPRESSION_SPECIFIED", 20, 187}, + #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 + {"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 + {"NO_METHOD_SPECIFIED", 20, 188}, + #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 + {"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 + {"NO_PROTOCOLS_AVAILABLE", 20, 191}, + #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 + {"NO_REQUIRED_DIGEST", 20, 324}, + #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 + #ifdef SSL_R_NO_SHARED_GROUPS + {"NO_SHARED_GROUPS", ERR_LIB_SSL, SSL_R_NO_SHARED_GROUPS}, + #else + {"NO_SHARED_GROUPS", 20, 410}, + #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 + {"NO_SRTP_PROFILES", 20, 359}, + #endif + #ifdef SSL_R_NO_SUITABLE_DIGEST_ALGORITHM + {"NO_SUITABLE_DIGEST_ALGORITHM", ERR_LIB_SSL, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM}, + #else + {"NO_SUITABLE_DIGEST_ALGORITHM", 20, 297}, + #endif + #ifdef SSL_R_NO_SUITABLE_GROUPS + {"NO_SUITABLE_GROUPS", ERR_LIB_SSL, SSL_R_NO_SUITABLE_GROUPS}, + #else + {"NO_SUITABLE_GROUPS", 20, 295}, + #endif + #ifdef SSL_R_NO_SUITABLE_KEY_SHARE + {"NO_SUITABLE_KEY_SHARE", ERR_LIB_SSL, SSL_R_NO_SUITABLE_KEY_SHARE}, + #else + {"NO_SUITABLE_KEY_SHARE", 20, 101}, + #endif + #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM + {"NO_SUITABLE_SIGNATURE_ALGORITHM", ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM}, + #else + {"NO_SUITABLE_SIGNATURE_ALGORITHM", 20, 118}, + #endif + #ifdef SSL_R_NO_VALID_SCTS + {"NO_VALID_SCTS", ERR_LIB_SSL, SSL_R_NO_VALID_SCTS}, + #else + {"NO_VALID_SCTS", 20, 216}, + #endif + #ifdef SSL_R_NO_VERIFY_COOKIE_CALLBACK + {"NO_VERIFY_COOKIE_CALLBACK", ERR_LIB_SSL, SSL_R_NO_VERIFY_COOKIE_CALLBACK}, + #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 + {"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 + {"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 + {"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 + {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", 20, 344}, + #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 + {"PACKET_LENGTH_TOO_LONG", 20, 198}, + #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 + {"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 + {"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 + {"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 + {"PEM_NAME_TOO_SHORT", 20, 392}, + #endif + #ifdef SSL_R_PIPELINE_FAILURE + {"PIPELINE_FAILURE", ERR_LIB_SSL, SSL_R_PIPELINE_FAILURE}, + #else + {"PIPELINE_FAILURE", 20, 406}, + #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 + {"POST_HANDSHAKE_AUTH_ENCODING_ERR", 20, 278}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"READ_TIMEOUT_EXPIRED", 20, 312}, + #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 + {"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 + {"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 + {"RENEGOTIATION_ENCODING_ERR", 20, 336}, + #endif + #ifdef SSL_R_RENEGOTIATION_MISMATCH + {"RENEGOTIATION_MISMATCH", ERR_LIB_SSL, SSL_R_RENEGOTIATION_MISMATCH}, + #else + {"RENEGOTIATION_MISMATCH", 20, 337}, + #endif + #ifdef SSL_R_REQUEST_PENDING + {"REQUEST_PENDING", ERR_LIB_SSL, SSL_R_REQUEST_PENDING}, + #else + {"REQUEST_PENDING", 20, 285}, + #endif + #ifdef SSL_R_REQUEST_SENT + {"REQUEST_SENT", ERR_LIB_SSL, SSL_R_REQUEST_SENT}, + #else + {"REQUEST_SENT", 20, 286}, + #endif + #ifdef SSL_R_REQUIRED_CIPHER_MISSING + {"REQUIRED_CIPHER_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_CIPHER_MISSING}, + #else + {"REQUIRED_CIPHER_MISSING", 20, 215}, + #endif + #ifdef SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING + {"REQUIRED_COMPRESSION_ALGORITHM_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING}, + #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 + {"SCSV_RECEIVED_WHEN_RENEGOTIATING", 20, 345}, + #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 + {"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 + {"SESSION_ID_CONTEXT_UNINITIALIZED", 20, 277}, + #endif + #ifdef SSL_R_SHUTDOWN_WHILE_IN_INIT + {"SHUTDOWN_WHILE_IN_INIT", ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"SRTP_UNKNOWN_PROTECTION_PROFILE", 20, 364}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", 20, 1043}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 20, 117}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #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 + {"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 + {"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 + {"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 + {"SSL_NEGATIVE_LENGTH", 20, 372}, + #endif + #ifdef SSL_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 20, 126}, + #endif + #ifdef SSL_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_SECTION_NOT_FOUND}, + #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 + {"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 + {"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 + {"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 + {"SSL_SESSION_ID_HAS_BAD_LENGTH", 20, 303}, + #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 + {"SSL_SESSION_ID_TOO_LONG", 20, 408}, + #endif + #ifdef SSL_R_SSL_SESSION_VERSION_MISMATCH + {"SSL_SESSION_VERSION_MISMATCH", ERR_LIB_SSL, SSL_R_SSL_SESSION_VERSION_MISMATCH}, + #else + {"SSL_SESSION_VERSION_MISMATCH", 20, 210}, + #endif + #ifdef SSL_R_STILL_IN_INIT + {"STILL_IN_INIT", ERR_LIB_SSL, SSL_R_STILL_IN_INIT}, + #else + {"STILL_IN_INIT", 20, 121}, + #endif + #ifdef SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED}, + #else + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", 20, 1116}, + #endif + #ifdef SSL_R_TLSV13_ALERT_MISSING_EXTENSION + {"TLSV13_ALERT_MISSING_EXTENSION", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_MISSING_EXTENSION}, + #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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"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 + {"TLSV1_CERTIFICATE_UNOBTAINABLE", 20, 1111}, + #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 + {"TLSV1_UNSUPPORTED_EXTENSION", 20, 1110}, + #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 + {"TLS_INVALID_ECPOINTFORMAT_LIST", 20, 157}, + #endif + #ifdef SSL_R_TOO_MANY_KEY_UPDATES + {"TOO_MANY_KEY_UPDATES", ERR_LIB_SSL, SSL_R_TOO_MANY_KEY_UPDATES}, + #else + {"TOO_MANY_KEY_UPDATES", 20, 132}, + #endif + #ifdef SSL_R_TOO_MANY_WARN_ALERTS + {"TOO_MANY_WARN_ALERTS", ERR_LIB_SSL, SSL_R_TOO_MANY_WARN_ALERTS}, + #else + {"TOO_MANY_WARN_ALERTS", 20, 409}, + #endif + #ifdef SSL_R_TOO_MUCH_EARLY_DATA + {"TOO_MUCH_EARLY_DATA", ERR_LIB_SSL, SSL_R_TOO_MUCH_EARLY_DATA}, + #else + {"TOO_MUCH_EARLY_DATA", 20, 164}, + #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 + {"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 + {"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 + {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", 20, 243}, + #endif + #ifdef SSL_R_UNEXPECTED_CCS_MESSAGE + {"UNEXPECTED_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_CCS_MESSAGE}, + #else + {"UNEXPECTED_CCS_MESSAGE", 20, 262}, + #endif + #ifdef SSL_R_UNEXPECTED_END_OF_EARLY_DATA + {"UNEXPECTED_END_OF_EARLY_DATA", ERR_LIB_SSL, SSL_R_UNEXPECTED_END_OF_EARLY_DATA}, + #else + {"UNEXPECTED_END_OF_EARLY_DATA", 20, 178}, + #endif + #ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING + {"UNEXPECTED_EOF_WHILE_READING", ERR_LIB_SSL, SSL_R_UNEXPECTED_EOF_WHILE_READING}, + #else + {"UNEXPECTED_EOF_WHILE_READING", 20, 294}, + #endif + #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 + {"UNEXPECTED_RECORD", 20, 245}, + #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 + {"UNKNOWN_ALERT_TYPE", 20, 246}, + #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 + {"UNKNOWN_CIPHER_RETURNED", 20, 248}, + #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 + {"UNKNOWN_CMD_NAME", 20, 386}, + #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 + {"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 + {"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 + {"UNKNOWN_PKEY_TYPE", 20, 251}, + #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 + {"UNKNOWN_SSL_VERSION", 20, 254}, + #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 + {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", 20, 338}, + #endif + #ifdef SSL_R_UNSOLICITED_EXTENSION + {"UNSOLICITED_EXTENSION", ERR_LIB_SSL, SSL_R_UNSOLICITED_EXTENSION}, + #else + {"UNSOLICITED_EXTENSION", 20, 217}, + #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_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 + {"UNSUPPORTED_PROTOCOL", 20, 258}, + #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 + {"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 + {"USE_SRTP_NOT_NEGOTIATED", 20, 369}, + #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 + {"VERSION_TOO_LOW", 20, 396}, + #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 + {"WRONG_CIPHER_RETURNED", 20, 261}, + #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 + {"WRONG_SIGNATURE_LENGTH", 20, 264}, + #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 + {"WRONG_SIGNATURE_TYPE", 20, 370}, + #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 + {"WRONG_VERSION_NUMBER", 20, 267}, + #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 + {"X509_VERIFICATION_SETUP_PROBLEMS", 20, 269}, + #endif + #ifdef TS_R_BAD_PKCS7_TYPE + {"BAD_PKCS7_TYPE", ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE}, + #else + {"BAD_PKCS7_TYPE", 47, 132}, + #endif + #ifdef TS_R_BAD_TYPE + {"BAD_TYPE", ERR_LIB_TS, TS_R_BAD_TYPE}, + #else + {"BAD_TYPE", 47, 133}, + #endif + #ifdef TS_R_CANNOT_LOAD_CERT + {"CANNOT_LOAD_CERT", ERR_LIB_TS, TS_R_CANNOT_LOAD_CERT}, + #else + {"CANNOT_LOAD_CERT", 47, 137}, + #endif + #ifdef TS_R_CANNOT_LOAD_KEY + {"CANNOT_LOAD_KEY", ERR_LIB_TS, TS_R_CANNOT_LOAD_KEY}, + #else + {"CANNOT_LOAD_KEY", 47, 138}, + #endif + #ifdef TS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_TS, TS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 47, 100}, + #endif + #ifdef TS_R_COULD_NOT_SET_ENGINE + {"COULD_NOT_SET_ENGINE", ERR_LIB_TS, TS_R_COULD_NOT_SET_ENGINE}, + #else + {"COULD_NOT_SET_ENGINE", 47, 127}, + #endif + #ifdef TS_R_COULD_NOT_SET_TIME + {"COULD_NOT_SET_TIME", ERR_LIB_TS, TS_R_COULD_NOT_SET_TIME}, + #else + {"COULD_NOT_SET_TIME", 47, 115}, + #endif + #ifdef TS_R_DETACHED_CONTENT + {"DETACHED_CONTENT", ERR_LIB_TS, TS_R_DETACHED_CONTENT}, + #else + {"DETACHED_CONTENT", 47, 134}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_ERROR + {"ESS_ADD_SIGNING_CERT_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_ERROR", 47, 116}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR + {"ESS_ADD_SIGNING_CERT_V2_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_V2_ERROR", 47, 139}, + #endif + #ifdef TS_R_ESS_SIGNING_CERTIFICATE_ERROR + {"ESS_SIGNING_CERTIFICATE_ERROR", ERR_LIB_TS, TS_R_ESS_SIGNING_CERTIFICATE_ERROR}, + #else + {"ESS_SIGNING_CERTIFICATE_ERROR", 47, 101}, + #endif + #ifdef TS_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_TS, TS_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 47, 102}, + #endif + #ifdef TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE}, + #else + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", 47, 117}, + #endif + #ifdef TS_R_MESSAGE_IMPRINT_MISMATCH + {"MESSAGE_IMPRINT_MISMATCH", ERR_LIB_TS, TS_R_MESSAGE_IMPRINT_MISMATCH}, + #else + {"MESSAGE_IMPRINT_MISMATCH", 47, 103}, + #endif + #ifdef TS_R_NONCE_MISMATCH + {"NONCE_MISMATCH", ERR_LIB_TS, TS_R_NONCE_MISMATCH}, + #else + {"NONCE_MISMATCH", 47, 104}, + #endif + #ifdef TS_R_NONCE_NOT_RETURNED + {"NONCE_NOT_RETURNED", ERR_LIB_TS, TS_R_NONCE_NOT_RETURNED}, + #else + {"NONCE_NOT_RETURNED", 47, 105}, + #endif + #ifdef TS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_TS, TS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 47, 106}, + #endif + #ifdef TS_R_NO_TIME_STAMP_TOKEN + {"NO_TIME_STAMP_TOKEN", ERR_LIB_TS, TS_R_NO_TIME_STAMP_TOKEN}, + #else + {"NO_TIME_STAMP_TOKEN", 47, 107}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 47, 118}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR + {"PKCS7_ADD_SIGNED_ATTR_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR}, + #else + {"PKCS7_ADD_SIGNED_ATTR_ERROR", 47, 119}, + #endif + #ifdef TS_R_PKCS7_TO_TS_TST_INFO_FAILED + {"PKCS7_TO_TS_TST_INFO_FAILED", ERR_LIB_TS, TS_R_PKCS7_TO_TS_TST_INFO_FAILED}, + #else + {"PKCS7_TO_TS_TST_INFO_FAILED", 47, 129}, + #endif + #ifdef TS_R_POLICY_MISMATCH + {"POLICY_MISMATCH", ERR_LIB_TS, TS_R_POLICY_MISMATCH}, + #else + {"POLICY_MISMATCH", 47, 108}, + #endif + #ifdef TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 47, 120}, + #endif + #ifdef TS_R_RESPONSE_SETUP_ERROR + {"RESPONSE_SETUP_ERROR", ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR}, + #else + {"RESPONSE_SETUP_ERROR", 47, 121}, + #endif + #ifdef TS_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_TS, TS_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 47, 109}, + #endif + #ifdef TS_R_THERE_MUST_BE_ONE_SIGNER + {"THERE_MUST_BE_ONE_SIGNER", ERR_LIB_TS, TS_R_THERE_MUST_BE_ONE_SIGNER}, + #else + {"THERE_MUST_BE_ONE_SIGNER", 47, 110}, + #endif + #ifdef TS_R_TIME_SYSCALL_ERROR + {"TIME_SYSCALL_ERROR", ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR}, + #else + {"TIME_SYSCALL_ERROR", 47, 122}, + #endif + #ifdef TS_R_TOKEN_NOT_PRESENT + {"TOKEN_NOT_PRESENT", ERR_LIB_TS, TS_R_TOKEN_NOT_PRESENT}, + #else + {"TOKEN_NOT_PRESENT", 47, 130}, + #endif + #ifdef TS_R_TOKEN_PRESENT + {"TOKEN_PRESENT", ERR_LIB_TS, TS_R_TOKEN_PRESENT}, + #else + {"TOKEN_PRESENT", 47, 131}, + #endif + #ifdef TS_R_TSA_NAME_MISMATCH + {"TSA_NAME_MISMATCH", ERR_LIB_TS, TS_R_TSA_NAME_MISMATCH}, + #else + {"TSA_NAME_MISMATCH", 47, 111}, + #endif + #ifdef TS_R_TSA_UNTRUSTED + {"TSA_UNTRUSTED", ERR_LIB_TS, TS_R_TSA_UNTRUSTED}, + #else + {"TSA_UNTRUSTED", 47, 112}, + #endif + #ifdef TS_R_TST_INFO_SETUP_ERROR + {"TST_INFO_SETUP_ERROR", ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR}, + #else + {"TST_INFO_SETUP_ERROR", 47, 123}, + #endif + #ifdef TS_R_TS_DATASIGN + {"TS_DATASIGN", ERR_LIB_TS, TS_R_TS_DATASIGN}, + #else + {"TS_DATASIGN", 47, 124}, + #endif + #ifdef TS_R_UNACCEPTABLE_POLICY + {"UNACCEPTABLE_POLICY", ERR_LIB_TS, TS_R_UNACCEPTABLE_POLICY}, + #else + {"UNACCEPTABLE_POLICY", 47, 125}, + #endif + #ifdef TS_R_UNSUPPORTED_MD_ALGORITHM + {"UNSUPPORTED_MD_ALGORITHM", ERR_LIB_TS, TS_R_UNSUPPORTED_MD_ALGORITHM}, + #else + {"UNSUPPORTED_MD_ALGORITHM", 47, 126}, + #endif + #ifdef TS_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_TS, TS_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 47, 113}, + #endif + #ifdef TS_R_VAR_BAD_VALUE + {"VAR_BAD_VALUE", ERR_LIB_TS, TS_R_VAR_BAD_VALUE}, + #else + {"VAR_BAD_VALUE", 47, 135}, + #endif + #ifdef TS_R_VAR_LOOKUP_FAILURE + {"VAR_LOOKUP_FAILURE", ERR_LIB_TS, TS_R_VAR_LOOKUP_FAILURE}, + #else + {"VAR_LOOKUP_FAILURE", 47, 136}, + #endif + #ifdef TS_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_TS, TS_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 47, 114}, + #endif + #ifdef UI_R_COMMON_OK_AND_CANCEL_CHARACTERS + {"COMMON_OK_AND_CANCEL_CHARACTERS", ERR_LIB_UI, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS}, + #else + {"COMMON_OK_AND_CANCEL_CHARACTERS", 40, 104}, + #endif + #ifdef UI_R_INDEX_TOO_LARGE + {"INDEX_TOO_LARGE", ERR_LIB_UI, UI_R_INDEX_TOO_LARGE}, + #else + {"INDEX_TOO_LARGE", 40, 102}, + #endif + #ifdef UI_R_INDEX_TOO_SMALL + {"INDEX_TOO_SMALL", ERR_LIB_UI, UI_R_INDEX_TOO_SMALL}, + #else + {"INDEX_TOO_SMALL", 40, 103}, + #endif + #ifdef UI_R_NO_RESULT_BUFFER + {"NO_RESULT_BUFFER", ERR_LIB_UI, UI_R_NO_RESULT_BUFFER}, + #else + {"NO_RESULT_BUFFER", 40, 105}, + #endif + #ifdef UI_R_PROCESSING_ERROR + {"PROCESSING_ERROR", ERR_LIB_UI, UI_R_PROCESSING_ERROR}, + #else + {"PROCESSING_ERROR", 40, 107}, + #endif + #ifdef UI_R_RESULT_TOO_LARGE + {"RESULT_TOO_LARGE", ERR_LIB_UI, UI_R_RESULT_TOO_LARGE}, + #else + {"RESULT_TOO_LARGE", 40, 100}, + #endif + #ifdef UI_R_RESULT_TOO_SMALL + {"RESULT_TOO_SMALL", ERR_LIB_UI, UI_R_RESULT_TOO_SMALL}, + #else + {"RESULT_TOO_SMALL", 40, 101}, + #endif + #ifdef UI_R_SYSASSIGN_ERROR + {"SYSASSIGN_ERROR", ERR_LIB_UI, UI_R_SYSASSIGN_ERROR}, + #else + {"SYSASSIGN_ERROR", 40, 109}, + #endif + #ifdef UI_R_SYSDASSGN_ERROR + {"SYSDASSGN_ERROR", ERR_LIB_UI, UI_R_SYSDASSGN_ERROR}, + #else + {"SYSDASSGN_ERROR", 40, 110}, + #endif + #ifdef UI_R_SYSQIOW_ERROR + {"SYSQIOW_ERROR", ERR_LIB_UI, UI_R_SYSQIOW_ERROR}, + #else + {"SYSQIOW_ERROR", 40, 111}, + #endif + #ifdef UI_R_UNKNOWN_CONTROL_COMMAND + {"UNKNOWN_CONTROL_COMMAND", ERR_LIB_UI, UI_R_UNKNOWN_CONTROL_COMMAND}, + #else + {"UNKNOWN_CONTROL_COMMAND", 40, 106}, + #endif + #ifdef UI_R_UNKNOWN_TTYGET_ERRNO_VALUE + {"UNKNOWN_TTYGET_ERRNO_VALUE", ERR_LIB_UI, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE}, + #else + {"UNKNOWN_TTYGET_ERRNO_VALUE", 40, 108}, + #endif + #ifdef UI_R_USER_DATA_DUPLICATION_UNSUPPORTED + {"USER_DATA_DUPLICATION_UNSUPPORTED", ERR_LIB_UI, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED}, + #else + {"USER_DATA_DUPLICATION_UNSUPPORTED", 40, 112}, + #endif + #ifdef X509V3_R_BAD_IP_ADDRESS + {"BAD_IP_ADDRESS", ERR_LIB_X509V3, X509V3_R_BAD_IP_ADDRESS}, + #else + {"BAD_IP_ADDRESS", 34, 118}, + #endif + #ifdef X509V3_R_BAD_OBJECT + {"BAD_OBJECT", ERR_LIB_X509V3, X509V3_R_BAD_OBJECT}, + #else + {"BAD_OBJECT", 34, 119}, + #endif + #ifdef X509V3_R_BN_DEC2BN_ERROR + {"BN_DEC2BN_ERROR", ERR_LIB_X509V3, X509V3_R_BN_DEC2BN_ERROR}, + #else + {"BN_DEC2BN_ERROR", 34, 100}, + #endif + #ifdef X509V3_R_BN_TO_ASN1_INTEGER_ERROR + {"BN_TO_ASN1_INTEGER_ERROR", ERR_LIB_X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR}, + #else + {"BN_TO_ASN1_INTEGER_ERROR", 34, 101}, + #endif + #ifdef X509V3_R_DIRNAME_ERROR + {"DIRNAME_ERROR", ERR_LIB_X509V3, X509V3_R_DIRNAME_ERROR}, + #else + {"DIRNAME_ERROR", 34, 149}, + #endif + #ifdef X509V3_R_DISTPOINT_ALREADY_SET + {"DISTPOINT_ALREADY_SET", ERR_LIB_X509V3, X509V3_R_DISTPOINT_ALREADY_SET}, + #else + {"DISTPOINT_ALREADY_SET", 34, 160}, + #endif + #ifdef X509V3_R_DUPLICATE_ZONE_ID + {"DUPLICATE_ZONE_ID", ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID}, + #else + {"DUPLICATE_ZONE_ID", 34, 133}, + #endif + #ifdef X509V3_R_EMPTY_KEY_USAGE + {"EMPTY_KEY_USAGE", ERR_LIB_X509V3, X509V3_R_EMPTY_KEY_USAGE}, + #else + {"EMPTY_KEY_USAGE", 34, 169}, + #endif + #ifdef X509V3_R_ERROR_CONVERTING_ZONE + {"ERROR_CONVERTING_ZONE", ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE}, + #else + {"ERROR_CONVERTING_ZONE", 34, 131}, + #endif + #ifdef X509V3_R_ERROR_CREATING_EXTENSION + {"ERROR_CREATING_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_CREATING_EXTENSION}, + #else + {"ERROR_CREATING_EXTENSION", 34, 144}, + #endif + #ifdef X509V3_R_ERROR_IN_EXTENSION + {"ERROR_IN_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION}, + #else + {"ERROR_IN_EXTENSION", 34, 128}, + #endif + #ifdef X509V3_R_EXPECTED_A_SECTION_NAME + {"EXPECTED_A_SECTION_NAME", ERR_LIB_X509V3, X509V3_R_EXPECTED_A_SECTION_NAME}, + #else + {"EXPECTED_A_SECTION_NAME", 34, 137}, + #endif + #ifdef X509V3_R_EXTENSION_EXISTS + {"EXTENSION_EXISTS", ERR_LIB_X509V3, X509V3_R_EXTENSION_EXISTS}, + #else + {"EXTENSION_EXISTS", 34, 145}, + #endif + #ifdef X509V3_R_EXTENSION_NAME_ERROR + {"EXTENSION_NAME_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR}, + #else + {"EXTENSION_NAME_ERROR", 34, 115}, + #endif + #ifdef X509V3_R_EXTENSION_NOT_FOUND + {"EXTENSION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND}, + #else + {"EXTENSION_NOT_FOUND", 34, 102}, + #endif + #ifdef X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED + {"EXTENSION_SETTING_NOT_SUPPORTED", ERR_LIB_X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED}, + #else + {"EXTENSION_SETTING_NOT_SUPPORTED", 34, 103}, + #endif + #ifdef X509V3_R_EXTENSION_VALUE_ERROR + {"EXTENSION_VALUE_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR}, + #else + {"EXTENSION_VALUE_ERROR", 34, 116}, + #endif + #ifdef X509V3_R_ILLEGAL_EMPTY_EXTENSION + {"ILLEGAL_EMPTY_EXTENSION", ERR_LIB_X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION}, + #else + {"ILLEGAL_EMPTY_EXTENSION", 34, 151}, + #endif + #ifdef X509V3_R_INCORRECT_POLICY_SYNTAX_TAG + {"INCORRECT_POLICY_SYNTAX_TAG", ERR_LIB_X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG}, + #else + {"INCORRECT_POLICY_SYNTAX_TAG", 34, 152}, + #endif + #ifdef X509V3_R_INVALID_ASNUMBER + {"INVALID_ASNUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_ASNUMBER}, + #else + {"INVALID_ASNUMBER", 34, 162}, + #endif + #ifdef X509V3_R_INVALID_ASRANGE + {"INVALID_ASRANGE", ERR_LIB_X509V3, X509V3_R_INVALID_ASRANGE}, + #else + {"INVALID_ASRANGE", 34, 163}, + #endif + #ifdef X509V3_R_INVALID_BOOLEAN_STRING + {"INVALID_BOOLEAN_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_BOOLEAN_STRING}, + #else + {"INVALID_BOOLEAN_STRING", 34, 104}, + #endif + #ifdef X509V3_R_INVALID_CERTIFICATE + {"INVALID_CERTIFICATE", ERR_LIB_X509V3, X509V3_R_INVALID_CERTIFICATE}, + #else + {"INVALID_CERTIFICATE", 34, 158}, + #endif + #ifdef X509V3_R_INVALID_EMPTY_NAME + {"INVALID_EMPTY_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_EMPTY_NAME}, + #else + {"INVALID_EMPTY_NAME", 34, 108}, + #endif + #ifdef X509V3_R_INVALID_EXTENSION_STRING + {"INVALID_EXTENSION_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_EXTENSION_STRING}, + #else + {"INVALID_EXTENSION_STRING", 34, 105}, + #endif + #ifdef X509V3_R_INVALID_INHERITANCE + {"INVALID_INHERITANCE", ERR_LIB_X509V3, X509V3_R_INVALID_INHERITANCE}, + #else + {"INVALID_INHERITANCE", 34, 165}, + #endif + #ifdef X509V3_R_INVALID_IPADDRESS + {"INVALID_IPADDRESS", ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS}, + #else + {"INVALID_IPADDRESS", 34, 166}, + #endif + #ifdef X509V3_R_INVALID_MULTIPLE_RDNS + {"INVALID_MULTIPLE_RDNS", ERR_LIB_X509V3, X509V3_R_INVALID_MULTIPLE_RDNS}, + #else + {"INVALID_MULTIPLE_RDNS", 34, 161}, + #endif + #ifdef X509V3_R_INVALID_NAME + {"INVALID_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_NAME}, + #else + {"INVALID_NAME", 34, 106}, + #endif + #ifdef X509V3_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 34, 107}, + #endif + #ifdef X509V3_R_INVALID_NULL_VALUE + {"INVALID_NULL_VALUE", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_VALUE}, + #else + {"INVALID_NULL_VALUE", 34, 109}, + #endif + #ifdef X509V3_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 34, 140}, + #endif + #ifdef X509V3_R_INVALID_NUMBERS + {"INVALID_NUMBERS", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBERS}, + #else + {"INVALID_NUMBERS", 34, 141}, + #endif + #ifdef X509V3_R_INVALID_OBJECT_IDENTIFIER + {"INVALID_OBJECT_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER}, + #else + {"INVALID_OBJECT_IDENTIFIER", 34, 110}, + #endif + #ifdef X509V3_R_INVALID_OPTION + {"INVALID_OPTION", ERR_LIB_X509V3, X509V3_R_INVALID_OPTION}, + #else + {"INVALID_OPTION", 34, 138}, + #endif + #ifdef X509V3_R_INVALID_POLICY_IDENTIFIER + {"INVALID_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER}, + #else + {"INVALID_POLICY_IDENTIFIER", 34, 134}, + #endif + #ifdef X509V3_R_INVALID_PROXY_POLICY_SETTING + {"INVALID_PROXY_POLICY_SETTING", ERR_LIB_X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING}, + #else + {"INVALID_PROXY_POLICY_SETTING", 34, 153}, + #endif + #ifdef X509V3_R_INVALID_PURPOSE + {"INVALID_PURPOSE", ERR_LIB_X509V3, X509V3_R_INVALID_PURPOSE}, + #else + {"INVALID_PURPOSE", 34, 146}, + #endif + #ifdef X509V3_R_INVALID_SAFI + {"INVALID_SAFI", ERR_LIB_X509V3, X509V3_R_INVALID_SAFI}, + #else + {"INVALID_SAFI", 34, 164}, + #endif + #ifdef X509V3_R_INVALID_SECTION + {"INVALID_SECTION", ERR_LIB_X509V3, X509V3_R_INVALID_SECTION}, + #else + {"INVALID_SECTION", 34, 135}, + #endif + #ifdef X509V3_R_INVALID_SYNTAX + {"INVALID_SYNTAX", ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX}, + #else + {"INVALID_SYNTAX", 34, 143}, + #endif + #ifdef X509V3_R_ISSUER_DECODE_ERROR + {"ISSUER_DECODE_ERROR", ERR_LIB_X509V3, X509V3_R_ISSUER_DECODE_ERROR}, + #else + {"ISSUER_DECODE_ERROR", 34, 126}, + #endif + #ifdef X509V3_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_X509V3, X509V3_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 34, 124}, + #endif + #ifdef X509V3_R_NEED_ORGANIZATION_AND_NUMBERS + {"NEED_ORGANIZATION_AND_NUMBERS", ERR_LIB_X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS}, + #else + {"NEED_ORGANIZATION_AND_NUMBERS", 34, 142}, + #endif + #ifdef X509V3_R_NEGATIVE_PATHLEN + {"NEGATIVE_PATHLEN", ERR_LIB_X509V3, X509V3_R_NEGATIVE_PATHLEN}, + #else + {"NEGATIVE_PATHLEN", 34, 168}, + #endif + #ifdef X509V3_R_NO_CONFIG_DATABASE + {"NO_CONFIG_DATABASE", ERR_LIB_X509V3, X509V3_R_NO_CONFIG_DATABASE}, + #else + {"NO_CONFIG_DATABASE", 34, 136}, + #endif + #ifdef X509V3_R_NO_ISSUER_CERTIFICATE + {"NO_ISSUER_CERTIFICATE", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE}, + #else + {"NO_ISSUER_CERTIFICATE", 34, 121}, + #endif + #ifdef X509V3_R_NO_ISSUER_DETAILS + {"NO_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_DETAILS}, + #else + {"NO_ISSUER_DETAILS", 34, 127}, + #endif + #ifdef X509V3_R_NO_POLICY_IDENTIFIER + {"NO_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_NO_POLICY_IDENTIFIER}, + #else + {"NO_POLICY_IDENTIFIER", 34, 139}, + #endif + #ifdef X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", ERR_LIB_X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED}, + #else + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", 34, 154}, + #endif + #ifdef X509V3_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 34, 114}, + #endif + #ifdef X509V3_R_NO_SUBJECT_DETAILS + {"NO_SUBJECT_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS}, + #else + {"NO_SUBJECT_DETAILS", 34, 125}, + #endif + #ifdef X509V3_R_OPERATION_NOT_DEFINED + {"OPERATION_NOT_DEFINED", ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED}, + #else + {"OPERATION_NOT_DEFINED", 34, 148}, + #endif + #ifdef X509V3_R_OTHERNAME_ERROR + {"OTHERNAME_ERROR", ERR_LIB_X509V3, X509V3_R_OTHERNAME_ERROR}, + #else + {"OTHERNAME_ERROR", 34, 147}, + #endif + #ifdef X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED + {"POLICY_LANGUAGE_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED}, + #else + {"POLICY_LANGUAGE_ALREADY_DEFINED", 34, 155}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH + {"POLICY_PATH_LENGTH", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH}, + #else + {"POLICY_PATH_LENGTH", 34, 156}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED}, + #else + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", 34, 157}, + #endif + #ifdef X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", ERR_LIB_X509V3, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY}, + #else + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", 34, 159}, + #endif + #ifdef X509V3_R_SECTION_NOT_FOUND + {"SECTION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND}, + #else + {"SECTION_NOT_FOUND", 34, 150}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS + {"UNABLE_TO_GET_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS}, + #else + {"UNABLE_TO_GET_ISSUER_DETAILS", 34, 122}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_KEYID + {"UNABLE_TO_GET_ISSUER_KEYID", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID}, + #else + {"UNABLE_TO_GET_ISSUER_KEYID", 34, 123}, + #endif + #ifdef X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT + {"UNKNOWN_BIT_STRING_ARGUMENT", ERR_LIB_X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT}, + #else + {"UNKNOWN_BIT_STRING_ARGUMENT", 34, 111}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION + {"UNKNOWN_EXTENSION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION}, + #else + {"UNKNOWN_EXTENSION", 34, 129}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION_NAME + {"UNKNOWN_EXTENSION_NAME", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME}, + #else + {"UNKNOWN_EXTENSION_NAME", 34, 130}, + #endif + #ifdef X509V3_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 34, 120}, + #endif + #ifdef X509V3_R_UNSUPPORTED_OPTION + {"UNSUPPORTED_OPTION", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_OPTION}, + #else + {"UNSUPPORTED_OPTION", 34, 117}, + #endif + #ifdef X509V3_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 34, 167}, + #endif + #ifdef X509V3_R_USER_TOO_LONG + {"USER_TOO_LONG", ERR_LIB_X509V3, X509V3_R_USER_TOO_LONG}, + #else + {"USER_TOO_LONG", 34, 132}, + #endif + #ifdef X509_R_AKID_MISMATCH + {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, + #else + {"AKID_MISMATCH", 11, 110}, + #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 + {"BAD_X509_FILETYPE", 11, 100}, + #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 + {"CANT_CHECK_DH_KEY", 11, 114}, + #endif + #ifdef X509_R_CERTIFICATE_VERIFICATION_FAILED + {"CERTIFICATE_VERIFICATION_FAILED", ERR_LIB_X509, X509_R_CERTIFICATE_VERIFICATION_FAILED}, + #else + {"CERTIFICATE_VERIFICATION_FAILED", 11, 139}, + #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 + {"CRL_ALREADY_DELTA", 11, 127}, + #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_ERROR_GETTING_MD_BY_NID + {"ERROR_GETTING_MD_BY_NID", ERR_LIB_X509, X509_R_ERROR_GETTING_MD_BY_NID}, + #else + {"ERROR_GETTING_MD_BY_NID", 11, 141}, + #endif + #ifdef X509_R_ERROR_USING_SIGINF_SET + {"ERROR_USING_SIGINF_SET", ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET}, + #else + {"ERROR_USING_SIGINF_SET", 11, 142}, + #endif + #ifdef X509_R_IDP_MISMATCH + {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, + #else + {"IDP_MISMATCH", 11, 128}, + #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 + {"INVALID_DIRECTORY", 11, 113}, + #endif + #ifdef X509_R_INVALID_DISTPOINT + {"INVALID_DISTPOINT", ERR_LIB_X509, X509_R_INVALID_DISTPOINT}, + #else + {"INVALID_DISTPOINT", 11, 143}, + #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 + {"INVALID_TRUST", 11, 123}, + #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 + {"KEY_TYPE_MISMATCH", 11, 115}, + #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 + {"LOADING_CERT_DIR", 11, 103}, + #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 + {"METHOD_NOT_SUPPORTED", 11, 124}, + #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 + {"NEWER_CRL_NOT_NEWER", 11, 132}, + #endif + #ifdef X509_R_NO_CERTIFICATE_FOUND + {"NO_CERTIFICATE_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND}, + #else + {"NO_CERTIFICATE_FOUND", 11, 135}, + #endif + #ifdef X509_R_NO_CERTIFICATE_OR_CRL_FOUND + {"NO_CERTIFICATE_OR_CRL_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND}, + #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 + {"NO_CERT_SET_FOR_US_TO_VERIFY", 11, 105}, + #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 + {"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 + {"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 + {"PUBLIC_KEY_ENCODE_ERROR", 11, 126}, + #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 + {"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 + {"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 + {"UNKNOWN_KEY_TYPE", 11, 117}, + #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 + {"UNKNOWN_PURPOSE_ID", 11, 121}, + #endif + #ifdef X509_R_UNKNOWN_SIGID_ALGS + {"UNKNOWN_SIGID_ALGS", ERR_LIB_X509, X509_R_UNKNOWN_SIGID_ALGS}, + #else + {"UNKNOWN_SIGID_ALGS", 11, 144}, + #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 + {"UNSUPPORTED_ALGORITHM", 11, 111}, + #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 + {"WRONG_TYPE", 11, 122}, + #endif + { NULL } +}; + diff --git a/python/Modules/_stat.c b/python/Modules/_stat.c new file mode 100755 index 0000000..7a799af --- /dev/null +++ b/python/Modules/_stat.c @@ -0,0 +1,610 @@ +/* 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\ +"); + + +static struct PyModuleDef statmodule = { + PyModuleDef_HEAD_INIT, + "_stat", + module_doc, + -1, + stat_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__stat(void) +{ + PyObject *m; + m = PyModule_Create(&statmodule); + if (m == NULL) + return NULL; + + if (PyModule_AddIntMacro(m, S_IFDIR)) return NULL; + if (PyModule_AddIntMacro(m, S_IFCHR)) return NULL; + if (PyModule_AddIntMacro(m, S_IFBLK)) return NULL; + if (PyModule_AddIntMacro(m, S_IFREG)) return NULL; + if (PyModule_AddIntMacro(m, S_IFIFO)) return NULL; + if (PyModule_AddIntMacro(m, S_IFLNK)) return NULL; + if (PyModule_AddIntMacro(m, S_IFSOCK)) return NULL; + if (PyModule_AddIntMacro(m, S_IFDOOR)) return NULL; + if (PyModule_AddIntMacro(m, S_IFPORT)) return NULL; + if (PyModule_AddIntMacro(m, S_IFWHT)) return NULL; + + if (PyModule_AddIntMacro(m, S_ISUID)) return NULL; + if (PyModule_AddIntMacro(m, S_ISGID)) return NULL; + if (PyModule_AddIntMacro(m, S_ISVTX)) return NULL; + if (PyModule_AddIntMacro(m, S_ENFMT)) return NULL; + + if (PyModule_AddIntMacro(m, S_IREAD)) return NULL; + if (PyModule_AddIntMacro(m, S_IWRITE)) return NULL; + if (PyModule_AddIntMacro(m, S_IEXEC)) return NULL; + + if (PyModule_AddIntMacro(m, S_IRWXU)) return NULL; + if (PyModule_AddIntMacro(m, S_IRUSR)) return NULL; + if (PyModule_AddIntMacro(m, S_IWUSR)) return NULL; + if (PyModule_AddIntMacro(m, S_IXUSR)) return NULL; + + if (PyModule_AddIntMacro(m, S_IRWXG)) return NULL; + if (PyModule_AddIntMacro(m, S_IRGRP)) return NULL; + if (PyModule_AddIntMacro(m, S_IWGRP)) return NULL; + if (PyModule_AddIntMacro(m, S_IXGRP)) return NULL; + + if (PyModule_AddIntMacro(m, S_IRWXO)) return NULL; + if (PyModule_AddIntMacro(m, S_IROTH)) return NULL; + if (PyModule_AddIntMacro(m, S_IWOTH)) return NULL; + if (PyModule_AddIntMacro(m, S_IXOTH)) return NULL; + + if (PyModule_AddIntMacro(m, UF_NODUMP)) return NULL; + if (PyModule_AddIntMacro(m, UF_IMMUTABLE)) return NULL; + if (PyModule_AddIntMacro(m, UF_APPEND)) return NULL; + if (PyModule_AddIntMacro(m, UF_OPAQUE)) return NULL; + if (PyModule_AddIntMacro(m, UF_NOUNLINK)) return NULL; + if (PyModule_AddIntMacro(m, UF_COMPRESSED)) return NULL; + if (PyModule_AddIntMacro(m, UF_HIDDEN)) return NULL; + if (PyModule_AddIntMacro(m, SF_ARCHIVED)) return NULL; + if (PyModule_AddIntMacro(m, SF_IMMUTABLE)) return NULL; + if (PyModule_AddIntMacro(m, SF_APPEND)) return NULL; + if (PyModule_AddIntMacro(m, SF_NOUNLINK)) return NULL; + if (PyModule_AddIntMacro(m, SF_SNAPSHOT)) return NULL; + + if (PyModule_AddIntConstant(m, "ST_MODE", 0)) return NULL; + if (PyModule_AddIntConstant(m, "ST_INO", 1)) return NULL; + if (PyModule_AddIntConstant(m, "ST_DEV", 2)) return NULL; + if (PyModule_AddIntConstant(m, "ST_NLINK", 3)) return NULL; + if (PyModule_AddIntConstant(m, "ST_UID", 4)) return NULL; + if (PyModule_AddIntConstant(m, "ST_GID", 5)) return NULL; + if (PyModule_AddIntConstant(m, "ST_SIZE", 6)) return NULL; + if (PyModule_AddIntConstant(m, "ST_ATIME", 7)) return NULL; + if (PyModule_AddIntConstant(m, "ST_MTIME", 8)) return NULL; + if (PyModule_AddIntConstant(m, "ST_CTIME", 9)) return NULL; + +#ifdef MS_WINDOWS + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_ARCHIVE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_COMPRESSED)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_DEVICE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_DIRECTORY)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_ENCRYPTED)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_HIDDEN)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_INTEGRITY_STREAM)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_NORMAL)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_NO_SCRUB_DATA)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_OFFLINE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_READONLY)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_REPARSE_POINT)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_SPARSE_FILE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_SYSTEM)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_TEMPORARY)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_VIRTUAL)) return NULL; + + if (PyModule_AddObject(m, "IO_REPARSE_TAG_SYMLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK))) return NULL; + if (PyModule_AddObject(m, "IO_REPARSE_TAG_MOUNT_POINT", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT))) return NULL; + if (PyModule_AddObject(m, "IO_REPARSE_TAG_APPEXECLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK))) return NULL; +#endif + + return m; +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Modules/_statisticsmodule.c b/python/Modules/_statisticsmodule.c new file mode 100755 index 0000000..a646e96 --- /dev/null +++ b/python/Modules/_statisticsmodule.c @@ -0,0 +1,150 @@ +/* statistics accelerator C extension: _statistics module. */ + +#include "Python.h" +#include "structmember.h" +#include "clinic/_statisticsmodule.c.h" + +/*[clinic input] +module _statistics + +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=864a6f59b76123b2]*/ + +/* + * There is no closed-form solution to the inverse CDF for the normal + * distribution, so we use a rational approximation instead: + * Wichura, M.J. (1988). "Algorithm AS241: The Percentage Points of the + * Normal Distribution". Applied Statistics. Blackwell Publishing. 37 + * (3): 477–484. doi:10.2307/2347330. JSTOR 2347330. + */ + +/*[clinic input] +_statistics._normal_dist_inv_cdf -> double + p: double + mu: double + sigma: double + / +[clinic start generated code]*/ + +static double +_statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu, + double sigma) +/*[clinic end generated code: output=02fd19ddaab36602 input=24715a74be15296a]*/ +{ + double q, num, den, r, x; + if (p <= 0.0 || p >= 1.0 || sigma <= 0.0) { + goto error; + } + + q = p - 0.5; + if(fabs(q) <= 0.425) { + r = 0.180625 - q * q; + // Hash sum-55.8831928806149014439 + num = (((((((2.5090809287301226727e+3 * r + + 3.3430575583588128105e+4) * r + + 6.7265770927008700853e+4) * r + + 4.5921953931549871457e+4) * r + + 1.3731693765509461125e+4) * r + + 1.9715909503065514427e+3) * r + + 1.3314166789178437745e+2) * r + + 3.3871328727963666080e+0) * q; + den = (((((((5.2264952788528545610e+3 * r + + 2.8729085735721942674e+4) * r + + 3.9307895800092710610e+4) * r + + 2.1213794301586595867e+4) * r + + 5.3941960214247511077e+3) * r + + 6.8718700749205790830e+2) * r + + 4.2313330701600911252e+1) * r + + 1.0); + if (den == 0.0) { + goto error; + } + x = num / den; + return mu + (x * sigma); + } + r = (q <= 0.0) ? p : (1.0 - p); + if (r <= 0.0 || r >= 1.0) { + goto error; + } + r = sqrt(-log(r)); + if (r <= 5.0) { + r = r - 1.6; + // Hash sum-49.33206503301610289036 + num = (((((((7.74545014278341407640e-4 * r + + 2.27238449892691845833e-2) * r + + 2.41780725177450611770e-1) * r + + 1.27045825245236838258e+0) * r + + 3.64784832476320460504e+0) * r + + 5.76949722146069140550e+0) * r + + 4.63033784615654529590e+0) * r + + 1.42343711074968357734e+0); + den = (((((((1.05075007164441684324e-9 * r + + 5.47593808499534494600e-4) * r + + 1.51986665636164571966e-2) * r + + 1.48103976427480074590e-1) * r + + 6.89767334985100004550e-1) * r + + 1.67638483018380384940e+0) * r + + 2.05319162663775882187e+0) * r + + 1.0); + } else { + r -= 5.0; + // Hash sum-47.52583317549289671629 + num = (((((((2.01033439929228813265e-7 * r + + 2.71155556874348757815e-5) * r + + 1.24266094738807843860e-3) * r + + 2.65321895265761230930e-2) * r + + 2.96560571828504891230e-1) * r + + 1.78482653991729133580e+0) * r + + 5.46378491116411436990e+0) * r + + 6.65790464350110377720e+0); + den = (((((((2.04426310338993978564e-15 * r + + 1.42151175831644588870e-7) * r + + 1.84631831751005468180e-5) * r + + 7.86869131145613259100e-4) * r + + 1.48753612908506148525e-2) * r + + 1.36929880922735805310e-1) * r + + 5.99832206555887937690e-1) * r + + 1.0); + } + if (den == 0.0) { + goto error; + } + x = num / den; + if (q < 0.0) { + x = -x; + } + return mu + (x * sigma); + + error: + PyErr_SetString(PyExc_ValueError, "inv_cdf undefined for these parameters"); + return -1.0; +} + + +static PyMethodDef statistics_methods[] = { + _STATISTICS__NORMAL_DIST_INV_CDF_METHODDEF + {NULL, NULL, 0, NULL} +}; + +PyDoc_STRVAR(statistics_doc, +"Accelerators for the statistics module.\n"); + +static struct PyModuleDef statisticsmodule = { + PyModuleDef_HEAD_INIT, + "_statistics", + statistics_doc, + -1, + statistics_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__statistics(void) +{ + PyObject *m = PyModule_Create(&statisticsmodule); + if (!m) return NULL; + return m; +} diff --git a/python/Modules/_struct.c b/python/Modules/_struct.c new file mode 100755 index 0000000..64a9827 --- /dev/null +++ b/python/Modules/_struct.c @@ -0,0 +1,2399 @@ +/* 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" +#include + +/*[clinic input] +class Struct "PyStructObject *" "&PyStructType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/ + +static PyTypeObject PyStructType; + +/* 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, &PyStructType) +#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType) + + +/* Exception */ + +static PyObject *StructError; + + +/* 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 { + PyErr_SetString(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)) + PyErr_SetString(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)) + PyErr_SetString(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)) + PyErr_SetString(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)) + PyErr_SetString(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)) + PyErr_SetString(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)) + PyErr_SetString(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()) { + PyErr_SetString(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) + PyErr_Format(StructError, + "'%c' format requires 0 <= number <= %zu", + f->format, + ulargest); + else { + const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1); + PyErr_Format(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 + + [bln] distiguishes among big-endian, little-endian and native. + [pu] distiguishes 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) { + PyErr_SetString(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) { + PyErr_SetString(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) +{ + if (!PyBytes_Check(v) || PyBytes_GET_SIZE(v) != 1) { + PyErr_SetString(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) { + PyErr_SetString(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) { + PyErr_SetString(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(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(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(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(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(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(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(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(StructError, "embedded null character"); + return -1; + } + + f = whichtable(&fmt); + + s = fmt; + size = 0; + len = 0; + ncodes = 0; + while ((c = *s++) != '\0') { + if (Py_ISSPACE(Py_CHARMASK(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') { + PyErr_SetString(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') { + if (Py_ISSPACE(Py_CHARMASK(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: + PyErr_SetString(StructError, + "total struct size too long"); + return -1; +} + +static PyObject * +s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *self; + + assert(type != NULL && type->tp_alloc != NULL); + + self = type->tp_alloc(type, 0); + if (self != NULL) { + 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", + Py_TYPE(format)->tp_name); + return -1; + } + + Py_SETREF(self->s_format, format); + + ret = prepare_s(self); + return ret; +} + +static void +s_dealloc(PyStructObject *s) +{ + if (s->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)s); + if (s->s_codes != NULL) { + PyMem_FREE(s->s_codes); + } + Py_DECREF(s->s_format); + Py_TYPE(s)->tp_free((PyObject *)s); +} + +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(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. + +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) +/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/ +{ + assert(self->s_codes != NULL); + + if (offset < 0) { + if (offset + self->s_size > 0) { + PyErr_Format(StructError, + "not enough data to unpack %zd bytes at offset %zd", + self->s_size, + offset); + return NULL; + } + + if (offset + buffer->len < 0) { + PyErr_Format(StructError, + "offset %zd out of range for %zd-byte buffer", + offset, + buffer->len); + return NULL; + } + offset += buffer->len; + } + + if ((buffer->len - offset) < self->s_size) { + PyErr_Format(StructError, + "unpack_from requires a buffer of at least %zu bytes for " + "unpacking %zd bytes at offset %zd " + "(actual buffer size is %zd)", + (size_t)self->s_size + (size_t)offset, + 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 */ + PyObject_GC_UnTrack(self); + Py_XDECREF(self->so); + PyBuffer_Release(&self->buf); + PyObject_GC_Del(self); +} + +static int +unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg) +{ + 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; +} + +static PyTypeObject unpackiter_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "unpack_iterator", /* tp_name */ + sizeof(unpackiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)unpackiter_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, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)unpackiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)unpackiter_iternext, /* tp_iternext */ + unpackiter_methods /* tp_methods */ +}; + +/*[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(StructError, + "cannot iteratively unpack with a struct of length 0"); + return NULL; + } + + iter = (unpackiterobject *) PyType_GenericAlloc(&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) { + PyErr_Format(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; + void *p; + isstring = PyBytes_Check(v); + if (!isstring && !PyByteArray_Check(v)) { + PyErr_SetString(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; + void *p; + isstring = PyBytes_Check(v); + if (!isstring && !PyByteArray_Check(v)) { + PyErr_SetString(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)) + PyErr_SetString(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) +{ + PyStructObject *soself; + PyObject *result; + + /* Validate arguments. */ + soself = (PyStructObject *)self; + assert(PyStruct_Check(self)); + assert(soself->s_codes != NULL); + if (nargs != soself->s_len) + { + PyErr_Format(StructError, + "pack expected %zd items for packing (got %zd)", soself->s_len, nargs); + return NULL; + } + + /* Allocate a new buffer */ + result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size); + if (result == NULL) + return NULL; + + /* Call the guts */ + if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +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(StructError, + "pack_into expected buffer argument"); + } + else if (nargs == 1) { + PyErr_Format(StructError, + "pack_into expected offset argument"); + } + else { + PyErr_Format(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) { + PyErr_Format(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) { + PyErr_Format(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); + + PyErr_Format(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", (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 */ +}; + +#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 */ +}; + +static +PyTypeObject PyStructType = { + PyVarObject_HEAD_INIT(NULL, 0) + "Struct", + sizeof(PyStructObject), + 0, + (destructor)s_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 */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Struct___init____doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + s_methods, /* tp_methods */ + NULL, /* tp_members */ + s_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + Struct___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + s_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + +/* ---- 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; + } + + s_object = PyDict_GetItemWithError(cache, fmt); + if (s_object != NULL) { + Py_INCREF(s_object); + *ptr = (PyStructObject *)s_object; + return Py_CLEANUP_SUPPORTED; + } + else if (PyErr_Occurred()) { + return 0; + } + + s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL); + 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]; + + 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]; + + 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 + {"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"); + + +static struct PyModuleDef _structmodule = { + PyModuleDef_HEAD_INIT, + "_struct", + module_doc, + -1, + module_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__struct(void) +{ + PyObject *m; + + m = PyModule_Create(&_structmodule); + if (m == NULL) + return NULL; + + Py_TYPE(&PyStructType) = &PyType_Type; + if (PyType_Ready(&PyStructType) < 0) + return NULL; + + if (PyType_Ready(&unpackiter_type) < 0) + return NULL; + + /* 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 */ + if (StructError == NULL) { + StructError = PyErr_NewException("struct.error", NULL, NULL); + if (StructError == NULL) + return NULL; + } + + Py_INCREF(StructError); + PyModule_AddObject(m, "error", StructError); + + Py_INCREF((PyObject*)&PyStructType); + PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType); + + return m; +} diff --git a/python/Modules/_testbuffer.c b/python/Modules/_testbuffer.c new file mode 100755 index 0000000..d7d3cc8 --- /dev/null +++ b/python/Modules/_testbuffer.c @@ -0,0 +1,2894 @@ +/* C Extension module to test all aspects of PEP-3118. + Written by Stefan Krah. */ + + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" + + +/* struct module */ +static PyObject *structmodule = NULL; +static PyObject *Struct = NULL; +static PyObject *calcsize = NULL; + +/* cache simple format string */ +static const char *simple_fmt = "B"; +static PyObject *simple_format = NULL; +#define SIMPLE_FORMAT(fmt) (fmt == NULL || strcmp(fmt, "B") == 0) +#define FIX_FORMAT(fmt) (fmt == NULL ? "B" : fmt) + + +/**************************************************************************/ +/* NDArray Object */ +/**************************************************************************/ + +static PyTypeObject NDArray_Type; +#define NDArray_Check(v) (Py_TYPE(v) == &NDArray_Type) + +#define CHECK_LIST_OR_TUPLE(v) \ + if (!PyList_Check(v) && !PyTuple_Check(v)) { \ + PyErr_SetString(PyExc_TypeError, \ + #v " must be a list or a tuple"); \ + return NULL; \ + } \ + +#define PyMem_XFree(v) \ + do { if (v) PyMem_Free(v); } while (0) + +/* Maximum number of dimensions. */ +#define ND_MAX_NDIM (2 * PyBUF_MAX_NDIM) + +/* Check for the presence of suboffsets in the first dimension. */ +#define HAVE_PTR(suboffsets) (suboffsets && suboffsets[0] >= 0) +/* Adjust ptr if suboffsets are present. */ +#define ADJUST_PTR(ptr, suboffsets) \ + (HAVE_PTR(suboffsets) ? *((char**)ptr) + suboffsets[0] : ptr) + +/* Default: NumPy style (strides), read-only, no var-export, C-style layout */ +#define ND_DEFAULT 0x000 +/* User configurable flags for the ndarray */ +#define ND_VAREXPORT 0x001 /* change layout while buffers are exported */ +/* User configurable flags for each base buffer */ +#define ND_WRITABLE 0x002 /* mark base buffer as writable */ +#define ND_FORTRAN 0x004 /* Fortran contiguous layout */ +#define ND_SCALAR 0x008 /* scalar: ndim = 0 */ +#define ND_PIL 0x010 /* convert to PIL-style array (suboffsets) */ +#define ND_REDIRECT 0x020 /* redirect buffer requests */ +#define ND_GETBUF_FAIL 0x040 /* trigger getbuffer failure */ +#define ND_GETBUF_UNDEFINED 0x080 /* undefined view.obj */ +/* Internal flags for the base buffer */ +#define ND_C 0x100 /* C contiguous layout (default) */ +#define ND_OWN_ARRAYS 0x200 /* consumer owns arrays */ + +/* ndarray properties */ +#define ND_IS_CONSUMER(nd) \ + (((NDArrayObject *)nd)->head == &((NDArrayObject *)nd)->staticbuf) + +/* ndbuf->flags properties */ +#define ND_C_CONTIGUOUS(flags) (!!(flags&(ND_SCALAR|ND_C))) +#define ND_FORTRAN_CONTIGUOUS(flags) (!!(flags&(ND_SCALAR|ND_FORTRAN))) +#define ND_ANY_CONTIGUOUS(flags) (!!(flags&(ND_SCALAR|ND_C|ND_FORTRAN))) + +/* getbuffer() requests */ +#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT) +#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) +#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) +#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS) +#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES) +#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND) +#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE) +#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT) + + +/* Single node of a list of base buffers. The list is needed to implement + changes in memory layout while exported buffers are active. */ +static PyTypeObject NDArray_Type; + +struct ndbuf; +typedef struct ndbuf { + struct ndbuf *next; + struct ndbuf *prev; + Py_ssize_t len; /* length of data */ + Py_ssize_t offset; /* start of the array relative to data */ + char *data; /* raw data */ + int flags; /* capabilities of the base buffer */ + Py_ssize_t exports; /* number of exports */ + Py_buffer base; /* base buffer */ +} ndbuf_t; + +typedef struct { + PyObject_HEAD + int flags; /* ndarray flags */ + ndbuf_t staticbuf; /* static buffer for re-exporting mode */ + ndbuf_t *head; /* currently active base buffer */ +} NDArrayObject; + + +static ndbuf_t * +ndbuf_new(Py_ssize_t nitems, Py_ssize_t itemsize, Py_ssize_t offset, int flags) +{ + ndbuf_t *ndbuf; + Py_buffer *base; + Py_ssize_t len; + + len = nitems * itemsize; + if (offset % itemsize) { + PyErr_SetString(PyExc_ValueError, + "offset must be a multiple of itemsize"); + return NULL; + } + if (offset < 0 || offset+itemsize > len) { + PyErr_SetString(PyExc_ValueError, "offset out of bounds"); + return NULL; + } + + ndbuf = PyMem_Malloc(sizeof *ndbuf); + if (ndbuf == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ndbuf->next = NULL; + ndbuf->prev = NULL; + ndbuf->len = len; + ndbuf->offset= offset; + + ndbuf->data = PyMem_Malloc(len); + if (ndbuf->data == NULL) { + PyErr_NoMemory(); + PyMem_Free(ndbuf); + return NULL; + } + + ndbuf->flags = flags; + ndbuf->exports = 0; + + base = &ndbuf->base; + base->obj = NULL; + base->buf = ndbuf->data; + base->len = len; + base->itemsize = 1; + base->readonly = 0; + base->format = NULL; + base->ndim = 1; + base->shape = NULL; + base->strides = NULL; + base->suboffsets = NULL; + base->internal = ndbuf; + + return ndbuf; +} + +static void +ndbuf_free(ndbuf_t *ndbuf) +{ + Py_buffer *base = &ndbuf->base; + + PyMem_XFree(ndbuf->data); + PyMem_XFree(base->format); + PyMem_XFree(base->shape); + PyMem_XFree(base->strides); + PyMem_XFree(base->suboffsets); + + PyMem_Free(ndbuf); +} + +static void +ndbuf_push(NDArrayObject *nd, ndbuf_t *elt) +{ + elt->next = nd->head; + if (nd->head) nd->head->prev = elt; + nd->head = elt; + elt->prev = NULL; +} + +static void +ndbuf_delete(NDArrayObject *nd, ndbuf_t *elt) +{ + if (elt->prev) + elt->prev->next = elt->next; + else + nd->head = elt->next; + + if (elt->next) + elt->next->prev = elt->prev; + + ndbuf_free(elt); +} + +static void +ndbuf_pop(NDArrayObject *nd) +{ + ndbuf_delete(nd, nd->head); +} + + +static PyObject * +ndarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + NDArrayObject *nd; + + nd = PyObject_New(NDArrayObject, &NDArray_Type); + if (nd == NULL) + return NULL; + + nd->flags = 0; + nd->head = NULL; + return (PyObject *)nd; +} + +static void +ndarray_dealloc(NDArrayObject *self) +{ + if (self->head) { + if (ND_IS_CONSUMER(self)) { + Py_buffer *base = &self->head->base; + if (self->head->flags & ND_OWN_ARRAYS) { + PyMem_XFree(base->shape); + PyMem_XFree(base->strides); + PyMem_XFree(base->suboffsets); + } + PyBuffer_Release(base); + } + else { + while (self->head) + ndbuf_pop(self); + } + } + PyObject_Del(self); +} + +static int +ndarray_init_staticbuf(PyObject *exporter, NDArrayObject *nd, int flags) +{ + Py_buffer *base = &nd->staticbuf.base; + + if (PyObject_GetBuffer(exporter, base, flags) < 0) + return -1; + + nd->head = &nd->staticbuf; + + nd->head->next = NULL; + nd->head->prev = NULL; + nd->head->len = -1; + nd->head->offset = -1; + nd->head->data = NULL; + + nd->head->flags = base->readonly ? 0 : ND_WRITABLE; + nd->head->exports = 0; + + return 0; +} + +static void +init_flags(ndbuf_t *ndbuf) +{ + if (ndbuf->base.ndim == 0) + ndbuf->flags |= ND_SCALAR; + if (ndbuf->base.suboffsets) + ndbuf->flags |= ND_PIL; + if (PyBuffer_IsContiguous(&ndbuf->base, 'C')) + ndbuf->flags |= ND_C; + if (PyBuffer_IsContiguous(&ndbuf->base, 'F')) + ndbuf->flags |= ND_FORTRAN; +} + + +/****************************************************************************/ +/* Buffer/List conversions */ +/****************************************************************************/ + +static Py_ssize_t *strides_from_shape(const ndbuf_t *, int flags); + +/* Get number of members in a struct: see issue #12740 */ +typedef struct { + PyObject_HEAD + Py_ssize_t s_size; + Py_ssize_t s_len; +} PyPartialStructObject; + +static Py_ssize_t +get_nmemb(PyObject *s) +{ + return ((PyPartialStructObject *)s)->s_len; +} + +/* Pack all items into the buffer of 'obj'. The 'format' parameter must be + in struct module syntax. For standard C types, a single item is an integer. + For compound types, a single item is a tuple of integers. */ +static int +pack_from_list(PyObject *obj, PyObject *items, PyObject *format, + Py_ssize_t itemsize) +{ + PyObject *structobj, *pack_into; + PyObject *args, *offset; + PyObject *item, *tmp; + Py_ssize_t nitems; /* number of items */ + Py_ssize_t nmemb; /* number of members in a single item */ + Py_ssize_t i, j; + int ret = 0; + + assert(PyObject_CheckBuffer(obj)); + assert(PyList_Check(items) || PyTuple_Check(items)); + + structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL); + if (structobj == NULL) + return -1; + + nitems = PySequence_Fast_GET_SIZE(items); + nmemb = get_nmemb(structobj); + assert(nmemb >= 1); + + pack_into = PyObject_GetAttrString(structobj, "pack_into"); + if (pack_into == NULL) { + Py_DECREF(structobj); + return -1; + } + + /* nmemb >= 1 */ + args = PyTuple_New(2 + nmemb); + if (args == NULL) { + Py_DECREF(pack_into); + Py_DECREF(structobj); + return -1; + } + + offset = NULL; + for (i = 0; i < nitems; i++) { + /* Loop invariant: args[j] are borrowed references or NULL. */ + PyTuple_SET_ITEM(args, 0, obj); + for (j = 1; j < 2+nmemb; j++) + PyTuple_SET_ITEM(args, j, NULL); + + Py_XDECREF(offset); + offset = PyLong_FromSsize_t(i*itemsize); + if (offset == NULL) { + ret = -1; + break; + } + PyTuple_SET_ITEM(args, 1, offset); + + item = PySequence_Fast_GET_ITEM(items, i); + if ((PyBytes_Check(item) || PyLong_Check(item) || + PyFloat_Check(item)) && nmemb == 1) { + PyTuple_SET_ITEM(args, 2, item); + } + else if ((PyList_Check(item) || PyTuple_Check(item)) && + PySequence_Length(item) == nmemb) { + for (j = 0; j < nmemb; j++) { + tmp = PySequence_Fast_GET_ITEM(item, j); + PyTuple_SET_ITEM(args, 2+j, tmp); + } + } + else { + PyErr_SetString(PyExc_ValueError, + "mismatch between initializer element and format string"); + ret = -1; + break; + } + + tmp = PyObject_CallObject(pack_into, args); + if (tmp == NULL) { + ret = -1; + break; + } + Py_DECREF(tmp); + } + + Py_INCREF(obj); /* args[0] */ + /* args[1]: offset is either NULL or should be dealloc'd */ + for (i = 2; i < 2+nmemb; i++) { + tmp = PyTuple_GET_ITEM(args, i); + Py_XINCREF(tmp); + } + Py_DECREF(args); + + Py_DECREF(pack_into); + Py_DECREF(structobj); + return ret; + +} + +/* Pack single element */ +static int +pack_single(char *ptr, PyObject *item, const char *fmt, Py_ssize_t itemsize) +{ + PyObject *structobj = NULL, *pack_into = NULL, *args = NULL; + PyObject *format = NULL, *mview = NULL, *zero = NULL; + Py_ssize_t i, nmemb; + int ret = -1; + PyObject *x; + + if (fmt == NULL) fmt = "B"; + + format = PyUnicode_FromString(fmt); + if (format == NULL) + goto out; + + structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL); + if (structobj == NULL) + goto out; + + nmemb = get_nmemb(structobj); + assert(nmemb >= 1); + + mview = PyMemoryView_FromMemory(ptr, itemsize, PyBUF_WRITE); + if (mview == NULL) + goto out; + + zero = PyLong_FromLong(0); + if (zero == NULL) + goto out; + + pack_into = PyObject_GetAttrString(structobj, "pack_into"); + if (pack_into == NULL) + goto out; + + args = PyTuple_New(2+nmemb); + if (args == NULL) + goto out; + + PyTuple_SET_ITEM(args, 0, mview); + PyTuple_SET_ITEM(args, 1, zero); + + if ((PyBytes_Check(item) || PyLong_Check(item) || + PyFloat_Check(item)) && nmemb == 1) { + PyTuple_SET_ITEM(args, 2, item); + } + else if ((PyList_Check(item) || PyTuple_Check(item)) && + PySequence_Length(item) == nmemb) { + for (i = 0; i < nmemb; i++) { + x = PySequence_Fast_GET_ITEM(item, i); + PyTuple_SET_ITEM(args, 2+i, x); + } + } + else { + PyErr_SetString(PyExc_ValueError, + "mismatch between initializer element and format string"); + goto args_out; + } + + x = PyObject_CallObject(pack_into, args); + if (x != NULL) { + Py_DECREF(x); + ret = 0; + } + + +args_out: + for (i = 0; i < 2+nmemb; i++) + Py_XINCREF(PyTuple_GET_ITEM(args, i)); + Py_XDECREF(args); +out: + Py_XDECREF(pack_into); + Py_XDECREF(zero); + Py_XDECREF(mview); + Py_XDECREF(structobj); + Py_XDECREF(format); + return ret; +} + +static void +copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize, + char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets, + char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets, + char *mem) +{ + Py_ssize_t i; + + assert(ndim >= 1); + + if (ndim == 1) { + if (!HAVE_PTR(dsuboffsets) && !HAVE_PTR(ssuboffsets) && + dstrides[0] == itemsize && sstrides[0] == itemsize) { + memmove(dptr, sptr, shape[0] * itemsize); + } + else { + char *p; + assert(mem != NULL); + for (i=0, p=mem; iformat), FIX_FORMAT(src->format)) != 0 || + dest->itemsize != src->itemsize || + dest->ndim != src->ndim) + return -1; + + for (i = 0; i < dest->ndim; i++) { + if (dest->shape[i] != src->shape[i]) + return -1; + if (dest->shape[i] == 0) + break; + } + + return 0; +} + +/* Copy src to dest. Both buffers must have the same format, itemsize, + ndim and shape. Copying is atomic, the function never fails with + a partial copy. */ +static int +copy_buffer(Py_buffer *dest, Py_buffer *src) +{ + char *mem = NULL; + + assert(dest->ndim > 0); + + if (cmp_structure(dest, src) < 0) { + PyErr_SetString(PyExc_ValueError, + "ndarray assignment: lvalue and rvalue have different structures"); + return -1; + } + + if ((dest->suboffsets && dest->suboffsets[dest->ndim-1] >= 0) || + (src->suboffsets && src->suboffsets[src->ndim-1] >= 0) || + dest->strides[dest->ndim-1] != dest->itemsize || + src->strides[src->ndim-1] != src->itemsize) { + mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize); + if (mem == NULL) { + PyErr_NoMemory(); + return -1; + } + } + + copy_rec(dest->shape, dest->ndim, dest->itemsize, + dest->buf, dest->strides, dest->suboffsets, + src->buf, src->strides, src->suboffsets, + mem); + + PyMem_XFree(mem); + return 0; +} + + +/* Unpack single element */ +static PyObject * +unpack_single(char *ptr, const char *fmt, Py_ssize_t itemsize) +{ + PyObject *x, *unpack_from, *mview; + + if (fmt == NULL) { + fmt = "B"; + itemsize = 1; + } + + unpack_from = PyObject_GetAttrString(structmodule, "unpack_from"); + if (unpack_from == NULL) + return NULL; + + mview = PyMemoryView_FromMemory(ptr, itemsize, PyBUF_READ); + if (mview == NULL) { + Py_DECREF(unpack_from); + return NULL; + } + + x = PyObject_CallFunction(unpack_from, "sO", fmt, mview); + Py_DECREF(unpack_from); + Py_DECREF(mview); + if (x == NULL) + return NULL; + + if (PyTuple_GET_SIZE(x) == 1) { + PyObject *tmp = PyTuple_GET_ITEM(x, 0); + Py_INCREF(tmp); + Py_DECREF(x); + return tmp; + } + + return x; +} + +/* Unpack a multi-dimensional matrix into a nested list. Return a scalar + for ndim = 0. */ +static PyObject * +unpack_rec(PyObject *unpack_from, char *ptr, PyObject *mview, char *item, + const Py_ssize_t *shape, const Py_ssize_t *strides, + const Py_ssize_t *suboffsets, Py_ssize_t ndim, Py_ssize_t itemsize) +{ + PyObject *lst, *x; + Py_ssize_t i; + + assert(ndim >= 0); + assert(shape != NULL); + assert(strides != NULL); + + if (ndim == 0) { + memcpy(item, ptr, itemsize); + x = PyObject_CallFunctionObjArgs(unpack_from, mview, NULL); + if (x == NULL) + return NULL; + if (PyTuple_GET_SIZE(x) == 1) { + PyObject *tmp = PyTuple_GET_ITEM(x, 0); + Py_INCREF(tmp); + Py_DECREF(x); + return tmp; + } + return x; + } + + lst = PyList_New(shape[0]); + if (lst == NULL) + return NULL; + + for (i = 0; i < shape[0]; ptr+=strides[0], i++) { + char *nextptr = ADJUST_PTR(ptr, suboffsets); + + x = unpack_rec(unpack_from, nextptr, mview, item, + shape+1, strides+1, suboffsets ? suboffsets+1 : NULL, + ndim-1, itemsize); + if (x == NULL) { + Py_DECREF(lst); + return NULL; + } + + PyList_SET_ITEM(lst, i, x); + } + + return lst; +} + + +static PyObject * +ndarray_as_list(NDArrayObject *nd) +{ + PyObject *structobj = NULL, *unpack_from = NULL; + PyObject *lst = NULL, *mview = NULL; + Py_buffer *base = &nd->head->base; + Py_ssize_t *shape = base->shape; + Py_ssize_t *strides = base->strides; + Py_ssize_t simple_shape[1]; + Py_ssize_t simple_strides[1]; + char *item = NULL; + PyObject *format; + char *fmt = base->format; + + base = &nd->head->base; + + if (fmt == NULL) { + PyErr_SetString(PyExc_ValueError, + "ndarray: tolist() does not support format=NULL, use " + "tobytes()"); + return NULL; + } + if (shape == NULL) { + assert(ND_C_CONTIGUOUS(nd->head->flags)); + assert(base->strides == NULL); + assert(base->ndim <= 1); + shape = simple_shape; + shape[0] = base->len; + strides = simple_strides; + strides[0] = base->itemsize; + } + else if (strides == NULL) { + assert(ND_C_CONTIGUOUS(nd->head->flags)); + strides = strides_from_shape(nd->head, 0); + if (strides == NULL) + return NULL; + } + + format = PyUnicode_FromString(fmt); + if (format == NULL) + goto out; + + structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL); + Py_DECREF(format); + if (structobj == NULL) + goto out; + + unpack_from = PyObject_GetAttrString(structobj, "unpack_from"); + if (unpack_from == NULL) + goto out; + + item = PyMem_Malloc(base->itemsize); + if (item == NULL) { + PyErr_NoMemory(); + goto out; + } + + mview = PyMemoryView_FromMemory(item, base->itemsize, PyBUF_WRITE); + if (mview == NULL) + goto out; + + lst = unpack_rec(unpack_from, base->buf, mview, item, + shape, strides, base->suboffsets, + base->ndim, base->itemsize); + +out: + Py_XDECREF(mview); + PyMem_XFree(item); + Py_XDECREF(unpack_from); + Py_XDECREF(structobj); + if (strides != base->strides && strides != simple_strides) + PyMem_XFree(strides); + + return lst; +} + + +/****************************************************************************/ +/* Initialize ndbuf */ +/****************************************************************************/ + +/* + State of a new ndbuf during initialization. 'OK' means that initialization + is complete. 'PTR' means that a pointer has been initialized, but the + state of the memory is still undefined and ndbuf->offset is disregarded. + + +-----------------+-----------+-------------+----------------+ + | | ndbuf_new | init_simple | init_structure | + +-----------------+-----------+-------------+----------------+ + | next | OK (NULL) | OK | OK | + +-----------------+-----------+-------------+----------------+ + | prev | OK (NULL) | OK | OK | + +-----------------+-----------+-------------+----------------+ + | len | OK | OK | OK | + +-----------------+-----------+-------------+----------------+ + | offset | OK | OK | OK | + +-----------------+-----------+-------------+----------------+ + | data | PTR | OK | OK | + +-----------------+-----------+-------------+----------------+ + | flags | user | user | OK | + +-----------------+-----------+-------------+----------------+ + | exports | OK (0) | OK | OK | + +-----------------+-----------+-------------+----------------+ + | base.obj | OK (NULL) | OK | OK | + +-----------------+-----------+-------------+----------------+ + | base.buf | PTR | PTR | OK | + +-----------------+-----------+-------------+----------------+ + | base.len | len(data) | len(data) | OK | + +-----------------+-----------+-------------+----------------+ + | base.itemsize | 1 | OK | OK | + +-----------------+-----------+-------------+----------------+ + | base.readonly | 0 | OK | OK | + +-----------------+-----------+-------------+----------------+ + | base.format | NULL | OK | OK | + +-----------------+-----------+-------------+----------------+ + | base.ndim | 1 | 1 | OK | + +-----------------+-----------+-------------+----------------+ + | base.shape | NULL | NULL | OK | + +-----------------+-----------+-------------+----------------+ + | base.strides | NULL | NULL | OK | + +-----------------+-----------+-------------+----------------+ + | base.suboffsets | NULL | NULL | OK | + +-----------------+-----------+-------------+----------------+ + | base.internal | OK | OK | OK | + +-----------------+-----------+-------------+----------------+ + +*/ + +static Py_ssize_t +get_itemsize(PyObject *format) +{ + PyObject *tmp; + Py_ssize_t itemsize; + + tmp = PyObject_CallFunctionObjArgs(calcsize, format, NULL); + if (tmp == NULL) + return -1; + itemsize = PyLong_AsSsize_t(tmp); + Py_DECREF(tmp); + + return itemsize; +} + +static char * +get_format(PyObject *format) +{ + PyObject *tmp; + char *fmt; + + tmp = PyUnicode_AsASCIIString(format); + if (tmp == NULL) + return NULL; + fmt = PyMem_Malloc(PyBytes_GET_SIZE(tmp)+1); + if (fmt == NULL) { + PyErr_NoMemory(); + Py_DECREF(tmp); + return NULL; + } + strcpy(fmt, PyBytes_AS_STRING(tmp)); + Py_DECREF(tmp); + + return fmt; +} + +static int +init_simple(ndbuf_t *ndbuf, PyObject *items, PyObject *format, + Py_ssize_t itemsize) +{ + PyObject *mview; + Py_buffer *base = &ndbuf->base; + int ret; + + mview = PyMemoryView_FromBuffer(base); + if (mview == NULL) + return -1; + + ret = pack_from_list(mview, items, format, itemsize); + Py_DECREF(mview); + if (ret < 0) + return -1; + + base->readonly = !(ndbuf->flags & ND_WRITABLE); + base->itemsize = itemsize; + base->format = get_format(format); + if (base->format == NULL) + return -1; + + return 0; +} + +static Py_ssize_t * +seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape) +{ + Py_ssize_t *dest; + Py_ssize_t x, i; + + /* ndim = len <= ND_MAX_NDIM, so PyMem_New() is actually not needed. */ + dest = PyMem_New(Py_ssize_t, len); + if (dest == NULL) { + PyErr_NoMemory(); + return NULL; + } + + for (i = 0; i < len; i++) { + PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i); + if (!PyLong_Check(tmp)) { + PyErr_Format(PyExc_ValueError, + "elements of %s must be integers", + is_shape ? "shape" : "strides"); + PyMem_Free(dest); + return NULL; + } + x = PyLong_AsSsize_t(tmp); + if (PyErr_Occurred()) { + PyMem_Free(dest); + return NULL; + } + if (is_shape && x < 0) { + PyErr_Format(PyExc_ValueError, + "elements of shape must be integers >= 0"); + PyMem_Free(dest); + return NULL; + } + dest[i] = x; + } + + return dest; +} + +static Py_ssize_t * +strides_from_shape(const ndbuf_t *ndbuf, int flags) +{ + const Py_buffer *base = &ndbuf->base; + Py_ssize_t *s, i; + + s = PyMem_Malloc(base->ndim * (sizeof *s)); + if (s == NULL) { + PyErr_NoMemory(); + return NULL; + } + + if (flags & ND_FORTRAN) { + s[0] = base->itemsize; + for (i = 1; i < base->ndim; i++) + s[i] = s[i-1] * base->shape[i-1]; + } + else { + s[base->ndim-1] = base->itemsize; + for (i = base->ndim-2; i >= 0; i--) + s[i] = s[i+1] * base->shape[i+1]; + } + + return s; +} + +/* Bounds check: + + len := complete length of allocated memory + offset := start of the array + + A single array element is indexed by: + + i = indices[0] * strides[0] + indices[1] * strides[1] + ... + + imin is reached when all indices[n] combined with positive strides are 0 + and all indices combined with negative strides are shape[n]-1, which is + the maximum index for the nth dimension. + + imax is reached when all indices[n] combined with negative strides are 0 + and all indices combined with positive strides are shape[n]-1. +*/ +static int +verify_structure(Py_ssize_t len, Py_ssize_t itemsize, Py_ssize_t offset, + const Py_ssize_t *shape, const Py_ssize_t *strides, + Py_ssize_t ndim) +{ + Py_ssize_t imin, imax; + Py_ssize_t n; + + assert(ndim >= 0); + + if (ndim == 0 && (offset < 0 || offset+itemsize > len)) + goto invalid_combination; + + for (n = 0; n < ndim; n++) + if (strides[n] % itemsize) { + PyErr_SetString(PyExc_ValueError, + "strides must be a multiple of itemsize"); + return -1; + } + + for (n = 0; n < ndim; n++) + if (shape[n] == 0) + return 0; + + imin = imax = 0; + for (n = 0; n < ndim; n++) + if (strides[n] <= 0) + imin += (shape[n]-1) * strides[n]; + else + imax += (shape[n]-1) * strides[n]; + + if (imin + offset < 0 || imax + offset + itemsize > len) + goto invalid_combination; + + return 0; + + +invalid_combination: + PyErr_SetString(PyExc_ValueError, + "invalid combination of buffer, shape and strides"); + return -1; +} + +/* + Convert a NumPy-style array to an array using suboffsets to stride in + the first dimension. Requirements: ndim > 0. + + Contiguous example + ================== + + Input: + ------ + shape = {2, 2, 3}; + strides = {6, 3, 1}; + suboffsets = NULL; + data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + buf = &data[0] + + Output: + ------- + shape = {2, 2, 3}; + strides = {sizeof(char *), 3, 1}; + suboffsets = {0, -1, -1}; + data = {p1, p2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + | | ^ ^ + `---'---' | + | | + `---------------------' + buf = &data[0] + + So, in the example the input resembles the three-dimensional array + char v[2][2][3], while the output resembles an array of two pointers + to two-dimensional arrays: char (*v[2])[2][3]. + + + Non-contiguous example: + ======================= + + Input (with offset and negative strides): + ----------------------------------------- + shape = {2, 2, 3}; + strides = {-6, 3, -1}; + offset = 8 + suboffsets = NULL; + data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + + Output: + ------- + shape = {2, 2, 3}; + strides = {-sizeof(char *), 3, -1}; + suboffsets = {2, -1, -1}; + newdata = {p1, p2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + | | ^ ^ ^ ^ + `---'---' | | `- p2+suboffsets[0] + | `-----------|--- p1+suboffsets[0] + `---------------------' + buf = &newdata[1] # striding backwards over the pointers. + + suboffsets[0] is the same as the offset that one would specify if + the two {2, 3} subarrays were created directly, hence the name. +*/ +static int +init_suboffsets(ndbuf_t *ndbuf) +{ + Py_buffer *base = &ndbuf->base; + Py_ssize_t start, step; + Py_ssize_t imin, suboffset0; + Py_ssize_t addsize; + Py_ssize_t n; + char *data; + + assert(base->ndim > 0); + assert(base->suboffsets == NULL); + + /* Allocate new data with additional space for shape[0] pointers. */ + addsize = base->shape[0] * (sizeof (char *)); + + /* Align array start to a multiple of 8. */ + addsize = 8 * ((addsize + 7) / 8); + + data = PyMem_Malloc(ndbuf->len + addsize); + if (data == NULL) { + PyErr_NoMemory(); + return -1; + } + + memcpy(data + addsize, ndbuf->data, ndbuf->len); + + PyMem_Free(ndbuf->data); + ndbuf->data = data; + ndbuf->len += addsize; + base->buf = ndbuf->data; + + /* imin: minimum index of the input array relative to ndbuf->offset. + suboffset0: offset for each sub-array of the output. This is the + same as calculating -imin' for a sub-array of ndim-1. */ + imin = suboffset0 = 0; + for (n = 0; n < base->ndim; n++) { + if (base->shape[n] == 0) + break; + if (base->strides[n] <= 0) { + Py_ssize_t x = (base->shape[n]-1) * base->strides[n]; + imin += x; + suboffset0 += (n >= 1) ? -x : 0; + } + } + + /* Initialize the array of pointers to the sub-arrays. */ + start = addsize + ndbuf->offset + imin; + step = base->strides[0] < 0 ? -base->strides[0] : base->strides[0]; + + for (n = 0; n < base->shape[0]; n++) + ((char **)base->buf)[n] = (char *)base->buf + start + n*step; + + /* Initialize suboffsets. */ + base->suboffsets = PyMem_Malloc(base->ndim * (sizeof *base->suboffsets)); + if (base->suboffsets == NULL) { + PyErr_NoMemory(); + return -1; + } + base->suboffsets[0] = suboffset0; + for (n = 1; n < base->ndim; n++) + base->suboffsets[n] = -1; + + /* Adjust strides for the first (zeroth) dimension. */ + if (base->strides[0] >= 0) { + base->strides[0] = sizeof(char *); + } + else { + /* Striding backwards. */ + base->strides[0] = -(Py_ssize_t)sizeof(char *); + if (base->shape[0] > 0) + base->buf = (char *)base->buf + (base->shape[0]-1) * sizeof(char *); + } + + ndbuf->flags &= ~(ND_C|ND_FORTRAN); + ndbuf->offset = 0; + return 0; +} + +static void +init_len(Py_buffer *base) +{ + Py_ssize_t i; + + base->len = 1; + for (i = 0; i < base->ndim; i++) + base->len *= base->shape[i]; + base->len *= base->itemsize; +} + +static int +init_structure(ndbuf_t *ndbuf, PyObject *shape, PyObject *strides, + Py_ssize_t ndim) +{ + Py_buffer *base = &ndbuf->base; + + base->ndim = (int)ndim; + if (ndim == 0) { + if (ndbuf->flags & ND_PIL) { + PyErr_SetString(PyExc_TypeError, + "ndim = 0 cannot be used in conjunction with ND_PIL"); + return -1; + } + ndbuf->flags |= (ND_SCALAR|ND_C|ND_FORTRAN); + return 0; + } + + /* shape */ + base->shape = seq_as_ssize_array(shape, ndim, 1); + if (base->shape == NULL) + return -1; + + /* strides */ + if (strides) { + base->strides = seq_as_ssize_array(strides, ndim, 0); + } + else { + base->strides = strides_from_shape(ndbuf, ndbuf->flags); + } + if (base->strides == NULL) + return -1; + if (verify_structure(base->len, base->itemsize, ndbuf->offset, + base->shape, base->strides, ndim) < 0) + return -1; + + /* buf */ + base->buf = ndbuf->data + ndbuf->offset; + + /* len */ + init_len(base); + + /* ndbuf->flags */ + if (PyBuffer_IsContiguous(base, 'C')) + ndbuf->flags |= ND_C; + if (PyBuffer_IsContiguous(base, 'F')) + ndbuf->flags |= ND_FORTRAN; + + + /* convert numpy array to suboffset representation */ + if (ndbuf->flags & ND_PIL) { + /* modifies base->buf, base->strides and base->suboffsets **/ + return init_suboffsets(ndbuf); + } + + return 0; +} + +static ndbuf_t * +init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides, + Py_ssize_t offset, PyObject *format, int flags) +{ + ndbuf_t *ndbuf; + Py_ssize_t ndim; + Py_ssize_t nitems; + Py_ssize_t itemsize; + + /* ndim = len(shape) */ + CHECK_LIST_OR_TUPLE(shape) + ndim = PySequence_Fast_GET_SIZE(shape); + if (ndim > ND_MAX_NDIM) { + PyErr_Format(PyExc_ValueError, + "ndim must not exceed %d", ND_MAX_NDIM); + return NULL; + } + + /* len(strides) = len(shape) */ + if (strides) { + CHECK_LIST_OR_TUPLE(strides) + if (PySequence_Fast_GET_SIZE(strides) == 0) + strides = NULL; + else if (flags & ND_FORTRAN) { + PyErr_SetString(PyExc_TypeError, + "ND_FORTRAN cannot be used together with strides"); + return NULL; + } + else if (PySequence_Fast_GET_SIZE(strides) != ndim) { + PyErr_SetString(PyExc_ValueError, + "len(shape) != len(strides)"); + return NULL; + } + } + + /* itemsize */ + itemsize = get_itemsize(format); + if (itemsize <= 0) { + if (itemsize == 0) { + PyErr_SetString(PyExc_ValueError, + "itemsize must not be zero"); + } + return NULL; + } + + /* convert scalar to list */ + if (ndim == 0) { + items = Py_BuildValue("(O)", items); + if (items == NULL) + return NULL; + } + else { + CHECK_LIST_OR_TUPLE(items) + Py_INCREF(items); + } + + /* number of items */ + nitems = PySequence_Fast_GET_SIZE(items); + if (nitems == 0) { + PyErr_SetString(PyExc_ValueError, + "initializer list or tuple must not be empty"); + Py_DECREF(items); + return NULL; + } + + ndbuf = ndbuf_new(nitems, itemsize, offset, flags); + if (ndbuf == NULL) { + Py_DECREF(items); + return NULL; + } + + + if (init_simple(ndbuf, items, format, itemsize) < 0) + goto error; + if (init_structure(ndbuf, shape, strides, ndim) < 0) + goto error; + + Py_DECREF(items); + return ndbuf; + +error: + Py_DECREF(items); + ndbuf_free(ndbuf); + return NULL; +} + +/* initialize and push a new base onto the linked list */ +static int +ndarray_push_base(NDArrayObject *nd, PyObject *items, + PyObject *shape, PyObject *strides, + Py_ssize_t offset, PyObject *format, int flags) +{ + ndbuf_t *ndbuf; + + ndbuf = init_ndbuf(items, shape, strides, offset, format, flags); + if (ndbuf == NULL) + return -1; + + ndbuf_push(nd, ndbuf); + return 0; +} + +#define PyBUF_UNUSED 0x10000 +static int +ndarray_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + NDArrayObject *nd = (NDArrayObject *)self; + static char *kwlist[] = { + "obj", "shape", "strides", "offset", "format", "flags", "getbuf", NULL + }; + PyObject *v = NULL; /* initializer: scalar, list, tuple or base object */ + PyObject *shape = NULL; /* size of each dimension */ + PyObject *strides = NULL; /* number of bytes to the next elt in each dim */ + Py_ssize_t offset = 0; /* buffer offset */ + PyObject *format = simple_format; /* struct module specifier: "B" */ + int flags = ND_DEFAULT; /* base buffer and ndarray flags */ + + int getbuf = PyBUF_UNUSED; /* re-exporter: getbuffer request flags */ + + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOnOii", kwlist, + &v, &shape, &strides, &offset, &format, &flags, &getbuf)) + return -1; + + /* NDArrayObject is re-exporter */ + if (PyObject_CheckBuffer(v) && shape == NULL) { + if (strides || offset || format != simple_format || + !(flags == ND_DEFAULT || flags == ND_REDIRECT)) { + PyErr_SetString(PyExc_TypeError, + "construction from exporter object only takes 'obj', 'getbuf' " + "and 'flags' arguments"); + return -1; + } + + getbuf = (getbuf == PyBUF_UNUSED) ? PyBUF_FULL_RO : getbuf; + + if (ndarray_init_staticbuf(v, nd, getbuf) < 0) + return -1; + + init_flags(nd->head); + nd->head->flags |= flags; + + return 0; + } + + /* NDArrayObject is the original base object. */ + if (getbuf != PyBUF_UNUSED) { + PyErr_SetString(PyExc_TypeError, + "getbuf argument only valid for construction from exporter " + "object"); + return -1; + } + if (shape == NULL) { + PyErr_SetString(PyExc_TypeError, + "shape is a required argument when constructing from " + "list, tuple or scalar"); + return -1; + } + + if (flags & ND_VAREXPORT) { + nd->flags |= ND_VAREXPORT; + flags &= ~ND_VAREXPORT; + } + + /* Initialize and push the first base buffer onto the linked list. */ + return ndarray_push_base(nd, v, shape, strides, offset, format, flags); +} + +/* Push an additional base onto the linked list. */ +static PyObject * +ndarray_push(PyObject *self, PyObject *args, PyObject *kwds) +{ + NDArrayObject *nd = (NDArrayObject *)self; + static char *kwlist[] = { + "items", "shape", "strides", "offset", "format", "flags", NULL + }; + PyObject *items = NULL; /* initializer: scalar, list or tuple */ + PyObject *shape = NULL; /* size of each dimension */ + PyObject *strides = NULL; /* number of bytes to the next elt in each dim */ + PyObject *format = simple_format; /* struct module specifier: "B" */ + Py_ssize_t offset = 0; /* buffer offset */ + int flags = ND_DEFAULT; /* base buffer flags */ + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OnOi", kwlist, + &items, &shape, &strides, &offset, &format, &flags)) + return NULL; + + if (flags & ND_VAREXPORT) { + PyErr_SetString(PyExc_ValueError, + "ND_VAREXPORT flag can only be used during object creation"); + return NULL; + } + if (ND_IS_CONSUMER(nd)) { + PyErr_SetString(PyExc_BufferError, + "structure of re-exporting object is immutable"); + return NULL; + } + if (!(nd->flags&ND_VAREXPORT) && nd->head->exports > 0) { + PyErr_Format(PyExc_BufferError, + "cannot change structure: %zd exported buffer%s", + nd->head->exports, nd->head->exports==1 ? "" : "s"); + return NULL; + } + + if (ndarray_push_base(nd, items, shape, strides, + offset, format, flags) < 0) + return NULL; + Py_RETURN_NONE; +} + +/* Pop a base from the linked list (if possible). */ +static PyObject * +ndarray_pop(PyObject *self, PyObject *dummy) +{ + NDArrayObject *nd = (NDArrayObject *)self; + if (ND_IS_CONSUMER(nd)) { + PyErr_SetString(PyExc_BufferError, + "structure of re-exporting object is immutable"); + return NULL; + } + if (nd->head->exports > 0) { + PyErr_Format(PyExc_BufferError, + "cannot change structure: %zd exported buffer%s", + nd->head->exports, nd->head->exports==1 ? "" : "s"); + return NULL; + } + if (nd->head->next == NULL) { + PyErr_SetString(PyExc_BufferError, + "list only has a single base"); + return NULL; + } + + ndbuf_pop(nd); + Py_RETURN_NONE; +} + +/**************************************************************************/ +/* getbuffer */ +/**************************************************************************/ + +static int +ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags) +{ + ndbuf_t *ndbuf = self->head; + Py_buffer *base = &ndbuf->base; + int baseflags = ndbuf->flags; + + /* redirect mode */ + if (base->obj != NULL && (baseflags&ND_REDIRECT)) { + return PyObject_GetBuffer(base->obj, view, flags); + } + + /* start with complete information */ + *view = *base; + view->obj = NULL; + + /* reconstruct format */ + if (view->format == NULL) + view->format = "B"; + + if (base->ndim != 0 && + ((REQ_SHAPE(flags) && base->shape == NULL) || + (REQ_STRIDES(flags) && base->strides == NULL))) { + /* The ndarray is a re-exporter that has been created without full + information for testing purposes. In this particular case the + ndarray is not a PEP-3118 compliant buffer provider. */ + PyErr_SetString(PyExc_BufferError, + "re-exporter does not provide format, shape or strides"); + return -1; + } + + if (baseflags & ND_GETBUF_FAIL) { + PyErr_SetString(PyExc_BufferError, + "ND_GETBUF_FAIL: forced test exception"); + if (baseflags & ND_GETBUF_UNDEFINED) + view->obj = (PyObject *)0x1; /* wrong but permitted in <= 3.2 */ + return -1; + } + + if (REQ_WRITABLE(flags) && base->readonly) { + PyErr_SetString(PyExc_BufferError, + "ndarray is not writable"); + return -1; + } + if (!REQ_FORMAT(flags)) { + /* NULL indicates that the buffer's data type has been cast to 'B'. + view->itemsize is the _previous_ itemsize. If shape is present, + the equality product(shape) * itemsize = len still holds at this + point. The equality calcsize(format) = itemsize does _not_ hold + from here on! */ + view->format = NULL; + } + + if (REQ_C_CONTIGUOUS(flags) && !ND_C_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "ndarray is not C-contiguous"); + return -1; + } + if (REQ_F_CONTIGUOUS(flags) && !ND_FORTRAN_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "ndarray is not Fortran contiguous"); + return -1; + } + if (REQ_ANY_CONTIGUOUS(flags) && !ND_ANY_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "ndarray is not contiguous"); + return -1; + } + if (!REQ_INDIRECT(flags) && (baseflags & ND_PIL)) { + PyErr_SetString(PyExc_BufferError, + "ndarray cannot be represented without suboffsets"); + return -1; + } + if (!REQ_STRIDES(flags)) { + if (!ND_C_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "ndarray is not C-contiguous"); + return -1; + } + view->strides = NULL; + } + if (!REQ_SHAPE(flags)) { + /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous, + so base->buf = ndbuf->data. */ + if (view->format != NULL) { + /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do + not make sense. */ + PyErr_Format(PyExc_BufferError, + "ndarray: cannot cast to unsigned bytes if the format flag " + "is present"); + return -1; + } + /* product(shape) * itemsize = len and calcsize(format) = itemsize + do _not_ hold from here on! */ + view->ndim = 1; + view->shape = NULL; + } + + /* Ascertain that the new buffer has the same contiguity as the exporter */ + if (ND_C_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'C') || + /* skip cast to 1-d */ + (view->format != NULL && view->shape != NULL && + ND_FORTRAN_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'F')) || + /* cast to 1-d */ + (view->format == NULL && view->shape == NULL && + !PyBuffer_IsContiguous(view, 'F'))) { + PyErr_SetString(PyExc_BufferError, + "ndarray: contiguity mismatch in getbuf()"); + return -1; + } + + view->obj = (PyObject *)self; + Py_INCREF(view->obj); + self->head->exports++; + + return 0; +} + +static void +ndarray_releasebuf(NDArrayObject *self, Py_buffer *view) +{ + if (!ND_IS_CONSUMER(self)) { + ndbuf_t *ndbuf = view->internal; + if (--ndbuf->exports == 0 && ndbuf != self->head) + ndbuf_delete(self, ndbuf); + } +} + +static PyBufferProcs ndarray_as_buffer = { + (getbufferproc)ndarray_getbuf, /* bf_getbuffer */ + (releasebufferproc)ndarray_releasebuf /* bf_releasebuffer */ +}; + + +/**************************************************************************/ +/* indexing/slicing */ +/**************************************************************************/ + +static char * +ptr_from_index(Py_buffer *base, Py_ssize_t index) +{ + char *ptr; + Py_ssize_t nitems; /* items in the first dimension */ + + if (base->shape) + nitems = base->shape[0]; + else { + assert(base->ndim == 1 && SIMPLE_FORMAT(base->format)); + nitems = base->len; + } + + if (index < 0) { + index += nitems; + } + if (index < 0 || index >= nitems) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return NULL; + } + + ptr = (char *)base->buf; + + if (base->strides == NULL) + ptr += base->itemsize * index; + else + ptr += base->strides[0] * index; + + ptr = ADJUST_PTR(ptr, base->suboffsets); + + return ptr; +} + +static PyObject * +ndarray_item(NDArrayObject *self, Py_ssize_t index) +{ + ndbuf_t *ndbuf = self->head; + Py_buffer *base = &ndbuf->base; + char *ptr; + + if (base->ndim == 0) { + PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar"); + return NULL; + } + + ptr = ptr_from_index(base, index); + if (ptr == NULL) + return NULL; + + if (base->ndim == 1) { + return unpack_single(ptr, base->format, base->itemsize); + } + else { + NDArrayObject *nd; + Py_buffer *subview; + + nd = (NDArrayObject *)ndarray_new(&NDArray_Type, NULL, NULL); + if (nd == NULL) + return NULL; + + if (ndarray_init_staticbuf((PyObject *)self, nd, PyBUF_FULL_RO) < 0) { + Py_DECREF(nd); + return NULL; + } + + subview = &nd->staticbuf.base; + + subview->buf = ptr; + subview->len /= subview->shape[0]; + + subview->ndim--; + subview->shape++; + if (subview->strides) subview->strides++; + if (subview->suboffsets) subview->suboffsets++; + + init_flags(&nd->staticbuf); + + return (PyObject *)nd; + } +} + +/* + For each dimension, we get valid (start, stop, step, slicelength) quadruples + from PySlice_GetIndicesEx(). + + Slicing NumPy arrays + ==================== + + A pointer to an element in a NumPy array is defined by: + + ptr = (char *)buf + indices[0] * strides[0] + + ... + + indices[ndim-1] * strides[ndim-1] + + Adjust buf: + ----------- + Adding start[n] for each dimension effectively adds the constant: + + c = start[0] * strides[0] + ... + start[ndim-1] * strides[ndim-1] + + Therefore init_slice() adds all start[n] directly to buf. + + Adjust shape: + ------------- + Obviously shape[n] = slicelength[n] + + Adjust strides: + --------------- + In the original array, the next element in a dimension is reached + by adding strides[n] to the pointer. In the sliced array, elements + may be skipped, so the next element is reached by adding: + + strides[n] * step[n] + + Slicing PIL arrays + ================== + + Layout: + ------- + In the first (zeroth) dimension, PIL arrays have an array of pointers + to sub-arrays of ndim-1. Striding in the first dimension is done by + getting the index of the nth pointer, dereference it and then add a + suboffset to it. The arrays pointed to can best be seen a regular + NumPy arrays. + + Adjust buf: + ----------- + In the original array, buf points to a location (usually the start) + in the array of pointers. For the sliced array, start[0] can be + added to buf in the same manner as for NumPy arrays. + + Adjust suboffsets: + ------------------ + Due to the dereferencing step in the addressing scheme, it is not + possible to adjust buf for higher dimensions. Recall that the + sub-arrays pointed to are regular NumPy arrays, so for each of + those arrays adding start[n] effectively adds the constant: + + c = start[1] * strides[1] + ... + start[ndim-1] * strides[ndim-1] + + This constant is added to suboffsets[0]. suboffsets[0] in turn is + added to each pointer right after dereferencing. + + Adjust shape and strides: + ------------------------- + Shape and strides are not influenced by the dereferencing step, so + they are adjusted in the same manner as for NumPy arrays. + + Multiple levels of suboffsets + ============================= + + For a construct like an array of pointers to array of pointers to + sub-arrays of ndim-2: + + suboffsets[0] = start[1] * strides[1] + suboffsets[1] = start[2] * strides[2] + ... +*/ +static int +init_slice(Py_buffer *base, PyObject *key, int dim) +{ + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_Unpack(key, &start, &stop, &step) < 0) { + return -1; + } + slicelength = PySlice_AdjustIndices(base->shape[dim], &start, &stop, step); + + + if (base->suboffsets == NULL || dim == 0) { + adjust_buf: + base->buf = (char *)base->buf + base->strides[dim] * start; + } + else { + Py_ssize_t n = dim-1; + while (n >= 0 && base->suboffsets[n] < 0) + n--; + if (n < 0) + goto adjust_buf; /* all suboffsets are negative */ + base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start; + } + base->shape[dim] = slicelength; + base->strides[dim] = base->strides[dim] * step; + + return 0; +} + +static int +copy_structure(Py_buffer *base) +{ + Py_ssize_t *shape = NULL, *strides = NULL, *suboffsets = NULL; + Py_ssize_t i; + + shape = PyMem_Malloc(base->ndim * (sizeof *shape)); + strides = PyMem_Malloc(base->ndim * (sizeof *strides)); + if (shape == NULL || strides == NULL) + goto err_nomem; + + suboffsets = NULL; + if (base->suboffsets) { + suboffsets = PyMem_Malloc(base->ndim * (sizeof *suboffsets)); + if (suboffsets == NULL) + goto err_nomem; + } + + for (i = 0; i < base->ndim; i++) { + shape[i] = base->shape[i]; + strides[i] = base->strides[i]; + if (suboffsets) + suboffsets[i] = base->suboffsets[i]; + } + + base->shape = shape; + base->strides = strides; + base->suboffsets = suboffsets; + + return 0; + +err_nomem: + PyErr_NoMemory(); + PyMem_XFree(shape); + PyMem_XFree(strides); + PyMem_XFree(suboffsets); + return -1; +} + +static PyObject * +ndarray_subscript(NDArrayObject *self, PyObject *key) +{ + NDArrayObject *nd; + ndbuf_t *ndbuf; + Py_buffer *base = &self->head->base; + + if (base->ndim == 0) { + if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) { + return unpack_single(base->buf, base->format, base->itemsize); + } + else if (key == Py_Ellipsis) { + Py_INCREF(self); + return (PyObject *)self; + } + else { + PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar"); + return NULL; + } + } + if (PyIndex_Check(key)) { + Py_ssize_t index = PyLong_AsSsize_t(key); + if (index == -1 && PyErr_Occurred()) + return NULL; + return ndarray_item(self, index); + } + + nd = (NDArrayObject *)ndarray_new(&NDArray_Type, NULL, NULL); + if (nd == NULL) + return NULL; + + /* new ndarray is a consumer */ + if (ndarray_init_staticbuf((PyObject *)self, nd, PyBUF_FULL_RO) < 0) { + Py_DECREF(nd); + return NULL; + } + + /* copy shape, strides and suboffsets */ + ndbuf = nd->head; + base = &ndbuf->base; + if (copy_structure(base) < 0) { + Py_DECREF(nd); + return NULL; + } + ndbuf->flags |= ND_OWN_ARRAYS; + + if (PySlice_Check(key)) { + /* one-dimensional slice */ + if (init_slice(base, key, 0) < 0) + goto err_occurred; + } + else if (PyTuple_Check(key)) { + /* multi-dimensional slice */ + PyObject *tuple = key; + Py_ssize_t i, n; + + n = PyTuple_GET_SIZE(tuple); + for (i = 0; i < n; i++) { + key = PyTuple_GET_ITEM(tuple, i); + if (!PySlice_Check(key)) + goto type_error; + if (init_slice(base, key, (int)i) < 0) + goto err_occurred; + } + } + else { + goto type_error; + } + + init_len(base); + init_flags(ndbuf); + + return (PyObject *)nd; + + +type_error: + PyErr_Format(PyExc_TypeError, + "cannot index memory using \"%.200s\"", + key->ob_type->tp_name); +err_occurred: + Py_DECREF(nd); + return NULL; +} + + +static int +ndarray_ass_subscript(NDArrayObject *self, PyObject *key, PyObject *value) +{ + NDArrayObject *nd; + Py_buffer *dest = &self->head->base; + Py_buffer src; + char *ptr; + Py_ssize_t index; + int ret = -1; + + if (dest->readonly) { + PyErr_SetString(PyExc_TypeError, "ndarray is not writable"); + return -1; + } + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "ndarray data cannot be deleted"); + return -1; + } + if (dest->ndim == 0) { + if (key == Py_Ellipsis || + (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0)) { + ptr = (char *)dest->buf; + return pack_single(ptr, value, dest->format, dest->itemsize); + } + else { + PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar"); + return -1; + } + } + if (dest->ndim == 1 && PyIndex_Check(key)) { + /* rvalue must be a single item */ + index = PyLong_AsSsize_t(key); + if (index == -1 && PyErr_Occurred()) + return -1; + else { + ptr = ptr_from_index(dest, index); + if (ptr == NULL) + return -1; + } + return pack_single(ptr, value, dest->format, dest->itemsize); + } + + /* rvalue must be an exporter */ + if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) == -1) + return -1; + + nd = (NDArrayObject *)ndarray_subscript(self, key); + if (nd != NULL) { + dest = &nd->head->base; + ret = copy_buffer(dest, &src); + Py_DECREF(nd); + } + + PyBuffer_Release(&src); + return ret; +} + +static PyObject * +slice_indices(PyObject *self, PyObject *args) +{ + PyObject *ret, *key, *tmp; + Py_ssize_t s[4]; /* start, stop, step, slicelength */ + Py_ssize_t i, len; + + if (!PyArg_ParseTuple(args, "On", &key, &len)) { + return NULL; + } + if (!PySlice_Check(key)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be a slice object"); + return NULL; + } + if (PySlice_Unpack(key, &s[0], &s[1], &s[2]) < 0) { + return NULL; + } + s[3] = PySlice_AdjustIndices(len, &s[0], &s[1], s[2]); + + ret = PyTuple_New(4); + if (ret == NULL) + return NULL; + + for (i = 0; i < 4; i++) { + tmp = PyLong_FromSsize_t(s[i]); + if (tmp == NULL) + goto error; + PyTuple_SET_ITEM(ret, i, tmp); + } + + return ret; + +error: + Py_DECREF(ret); + return NULL; +} + + +static PyMappingMethods ndarray_as_mapping = { + NULL, /* mp_length */ + (binaryfunc)ndarray_subscript, /* mp_subscript */ + (objobjargproc)ndarray_ass_subscript /* mp_ass_subscript */ +}; + +static PySequenceMethods ndarray_as_sequence = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)ndarray_item, /* sq_item */ +}; + + +/**************************************************************************/ +/* getters */ +/**************************************************************************/ + +static PyObject * +ssize_array_as_tuple(Py_ssize_t *array, Py_ssize_t len) +{ + PyObject *tuple, *x; + Py_ssize_t i; + + if (array == NULL) + return PyTuple_New(0); + + tuple = PyTuple_New(len); + if (tuple == NULL) + return NULL; + + for (i = 0; i < len; i++) { + x = PyLong_FromSsize_t(array[i]); + if (x == NULL) { + Py_DECREF(tuple); + return NULL; + } + PyTuple_SET_ITEM(tuple, i, x); + } + + return tuple; +} + +static PyObject * +ndarray_get_flags(NDArrayObject *self, void *closure) +{ + return PyLong_FromLong(self->head->flags); +} + +static PyObject * +ndarray_get_offset(NDArrayObject *self, void *closure) +{ + ndbuf_t *ndbuf = self->head; + return PyLong_FromSsize_t(ndbuf->offset); +} + +static PyObject * +ndarray_get_obj(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + + if (base->obj == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(base->obj); + return base->obj; +} + +static PyObject * +ndarray_get_nbytes(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + return PyLong_FromSsize_t(base->len); +} + +static PyObject * +ndarray_get_readonly(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + return PyBool_FromLong(base->readonly); +} + +static PyObject * +ndarray_get_itemsize(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + return PyLong_FromSsize_t(base->itemsize); +} + +static PyObject * +ndarray_get_format(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + char *fmt = base->format ? base->format : ""; + return PyUnicode_FromString(fmt); +} + +static PyObject * +ndarray_get_ndim(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + return PyLong_FromSsize_t(base->ndim); +} + +static PyObject * +ndarray_get_shape(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + return ssize_array_as_tuple(base->shape, base->ndim); +} + +static PyObject * +ndarray_get_strides(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + return ssize_array_as_tuple(base->strides, base->ndim); +} + +static PyObject * +ndarray_get_suboffsets(NDArrayObject *self, void *closure) +{ + Py_buffer *base = &self->head->base; + return ssize_array_as_tuple(base->suboffsets, base->ndim); +} + +static PyObject * +ndarray_c_contig(PyObject *self, PyObject *dummy) +{ + NDArrayObject *nd = (NDArrayObject *)self; + int ret = PyBuffer_IsContiguous(&nd->head->base, 'C'); + + if (ret != ND_C_CONTIGUOUS(nd->head->flags)) { + PyErr_SetString(PyExc_RuntimeError, + "results from PyBuffer_IsContiguous() and flags differ"); + return NULL; + } + return PyBool_FromLong(ret); +} + +static PyObject * +ndarray_fortran_contig(PyObject *self, PyObject *dummy) +{ + NDArrayObject *nd = (NDArrayObject *)self; + int ret = PyBuffer_IsContiguous(&nd->head->base, 'F'); + + if (ret != ND_FORTRAN_CONTIGUOUS(nd->head->flags)) { + PyErr_SetString(PyExc_RuntimeError, + "results from PyBuffer_IsContiguous() and flags differ"); + return NULL; + } + return PyBool_FromLong(ret); +} + +static PyObject * +ndarray_contig(PyObject *self, PyObject *dummy) +{ + NDArrayObject *nd = (NDArrayObject *)self; + int ret = PyBuffer_IsContiguous(&nd->head->base, 'A'); + + if (ret != ND_ANY_CONTIGUOUS(nd->head->flags)) { + PyErr_SetString(PyExc_RuntimeError, + "results from PyBuffer_IsContiguous() and flags differ"); + return NULL; + } + return PyBool_FromLong(ret); +} + + +static PyGetSetDef ndarray_getset [] = +{ + /* ndbuf */ + { "flags", (getter)ndarray_get_flags, NULL, NULL, NULL}, + { "offset", (getter)ndarray_get_offset, NULL, NULL, NULL}, + /* ndbuf.base */ + { "obj", (getter)ndarray_get_obj, NULL, NULL, NULL}, + { "nbytes", (getter)ndarray_get_nbytes, NULL, NULL, NULL}, + { "readonly", (getter)ndarray_get_readonly, NULL, NULL, NULL}, + { "itemsize", (getter)ndarray_get_itemsize, NULL, NULL, NULL}, + { "format", (getter)ndarray_get_format, NULL, NULL, NULL}, + { "ndim", (getter)ndarray_get_ndim, NULL, NULL, NULL}, + { "shape", (getter)ndarray_get_shape, NULL, NULL, NULL}, + { "strides", (getter)ndarray_get_strides, NULL, NULL, NULL}, + { "suboffsets", (getter)ndarray_get_suboffsets, NULL, NULL, NULL}, + { "c_contiguous", (getter)ndarray_c_contig, NULL, NULL, NULL}, + { "f_contiguous", (getter)ndarray_fortran_contig, NULL, NULL, NULL}, + { "contiguous", (getter)ndarray_contig, NULL, NULL, NULL}, + {NULL} +}; + +static PyObject * +ndarray_tolist(PyObject *self, PyObject *dummy) +{ + return ndarray_as_list((NDArrayObject *)self); +} + +static PyObject * +ndarray_tobytes(PyObject *self, PyObject *dummy) +{ + ndbuf_t *ndbuf = ((NDArrayObject *)self)->head; + Py_buffer *src = &ndbuf->base; + Py_buffer dest; + PyObject *ret = NULL; + char *mem; + + if (ND_C_CONTIGUOUS(ndbuf->flags)) + return PyBytes_FromStringAndSize(src->buf, src->len); + + assert(src->shape != NULL); + assert(src->strides != NULL); + assert(src->ndim > 0); + + mem = PyMem_Malloc(src->len); + if (mem == NULL) { + PyErr_NoMemory(); + return NULL; + } + + dest = *src; + dest.buf = mem; + dest.suboffsets = NULL; + dest.strides = strides_from_shape(ndbuf, 0); + if (dest.strides == NULL) + goto out; + if (copy_buffer(&dest, src) < 0) + goto out; + + ret = PyBytes_FromStringAndSize(mem, src->len); + +out: + PyMem_XFree(dest.strides); + PyMem_Free(mem); + return ret; +} + +/* add redundant (negative) suboffsets for testing */ +static PyObject * +ndarray_add_suboffsets(PyObject *self, PyObject *dummy) +{ + NDArrayObject *nd = (NDArrayObject *)self; + Py_buffer *base = &nd->head->base; + Py_ssize_t i; + + if (base->suboffsets != NULL) { + PyErr_SetString(PyExc_TypeError, + "cannot add suboffsets to PIL-style array"); + return NULL; + } + if (base->strides == NULL) { + PyErr_SetString(PyExc_TypeError, + "cannot add suboffsets to array without strides"); + return NULL; + } + + base->suboffsets = PyMem_Malloc(base->ndim * (sizeof *base->suboffsets)); + if (base->suboffsets == NULL) { + PyErr_NoMemory(); + return NULL; + } + + for (i = 0; i < base->ndim; i++) + base->suboffsets[i] = -1; + + nd->head->flags &= ~(ND_C|ND_FORTRAN); + + Py_RETURN_NONE; +} + +/* Test PyMemoryView_FromBuffer(): return a memoryview from a static buffer. + Obviously this is fragile and only one such view may be active at any + time. Never use anything like this in real code! */ +static char *infobuf = NULL; +static PyObject * +ndarray_memoryview_from_buffer(PyObject *self, PyObject *dummy) +{ + const NDArrayObject *nd = (NDArrayObject *)self; + const Py_buffer *view = &nd->head->base; + const ndbuf_t *ndbuf; + static char format[ND_MAX_NDIM+1]; + static Py_ssize_t shape[ND_MAX_NDIM]; + static Py_ssize_t strides[ND_MAX_NDIM]; + static Py_ssize_t suboffsets[ND_MAX_NDIM]; + static Py_buffer info; + char *p; + + if (!ND_IS_CONSUMER(nd)) + ndbuf = nd->head; /* self is ndarray/original exporter */ + else if (NDArray_Check(view->obj) && !ND_IS_CONSUMER(view->obj)) + /* self is ndarray and consumer from ndarray/original exporter */ + ndbuf = ((NDArrayObject *)view->obj)->head; + else { + PyErr_SetString(PyExc_TypeError, + "memoryview_from_buffer(): ndarray must be original exporter or " + "consumer from ndarray/original exporter"); + return NULL; + } + + info = *view; + p = PyMem_Realloc(infobuf, ndbuf->len); + if (p == NULL) { + PyMem_Free(infobuf); + PyErr_NoMemory(); + infobuf = NULL; + return NULL; + } + else { + infobuf = p; + } + /* copy the complete raw data */ + memcpy(infobuf, ndbuf->data, ndbuf->len); + info.buf = infobuf + ((char *)view->buf - ndbuf->data); + + if (view->format) { + if (strlen(view->format) > ND_MAX_NDIM) { + PyErr_Format(PyExc_TypeError, + "memoryview_from_buffer: format is limited to %d characters", + ND_MAX_NDIM); + return NULL; + } + strcpy(format, view->format); + info.format = format; + } + if (view->ndim > ND_MAX_NDIM) { + PyErr_Format(PyExc_TypeError, + "memoryview_from_buffer: ndim is limited to %d", ND_MAX_NDIM); + return NULL; + } + if (view->shape) { + memcpy(shape, view->shape, view->ndim * sizeof(Py_ssize_t)); + info.shape = shape; + } + if (view->strides) { + memcpy(strides, view->strides, view->ndim * sizeof(Py_ssize_t)); + info.strides = strides; + } + if (view->suboffsets) { + memcpy(suboffsets, view->suboffsets, view->ndim * sizeof(Py_ssize_t)); + info.suboffsets = suboffsets; + } + + return PyMemoryView_FromBuffer(&info); +} + +/* Get a single item from bufobj at the location specified by seq. + seq is a list or tuple of indices. The purpose of this function + is to check other functions against PyBuffer_GetPointer(). */ +static PyObject * +get_pointer(PyObject *self, PyObject *args) +{ + PyObject *ret = NULL, *bufobj, *seq; + Py_buffer view; + Py_ssize_t indices[ND_MAX_NDIM]; + Py_ssize_t i; + void *ptr; + + if (!PyArg_ParseTuple(args, "OO", &bufobj, &seq)) { + return NULL; + } + + CHECK_LIST_OR_TUPLE(seq); + if (PyObject_GetBuffer(bufobj, &view, PyBUF_FULL_RO) < 0) + return NULL; + + if (view.ndim > ND_MAX_NDIM) { + PyErr_Format(PyExc_ValueError, + "get_pointer(): ndim > %d", ND_MAX_NDIM); + goto out; + } + if (PySequence_Fast_GET_SIZE(seq) != view.ndim) { + PyErr_SetString(PyExc_ValueError, + "get_pointer(): len(indices) != ndim"); + goto out; + } + + for (i = 0; i < view.ndim; i++) { + PyObject *x = PySequence_Fast_GET_ITEM(seq, i); + indices[i] = PyLong_AsSsize_t(x); + if (PyErr_Occurred()) + goto out; + if (indices[i] < 0 || indices[i] >= view.shape[i]) { + PyErr_Format(PyExc_ValueError, + "get_pointer(): invalid index %zd at position %zd", + indices[i], i); + goto out; + } + } + + ptr = PyBuffer_GetPointer(&view, indices); + ret = unpack_single(ptr, view.format, view.itemsize); + +out: + PyBuffer_Release(&view); + return ret; +} + +static PyObject * +get_sizeof_void_p(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return PyLong_FromSize_t(sizeof(void *)); +} + +static char +get_ascii_order(PyObject *order) +{ + PyObject *ascii_order; + char ord; + + if (!PyUnicode_Check(order)) { + PyErr_SetString(PyExc_TypeError, + "order must be a string"); + return CHAR_MAX; + } + + ascii_order = PyUnicode_AsASCIIString(order); + if (ascii_order == NULL) { + return CHAR_MAX; + } + + ord = PyBytes_AS_STRING(ascii_order)[0]; + Py_DECREF(ascii_order); + + if (ord != 'C' && ord != 'F' && ord != 'A') { + PyErr_SetString(PyExc_ValueError, + "invalid order, must be C, F or A"); + return CHAR_MAX; + } + + return ord; +} + +/* Get a contiguous memoryview. */ +static PyObject * +get_contiguous(PyObject *self, PyObject *args) +{ + PyObject *obj; + PyObject *buffertype; + PyObject *order; + long type; + char ord; + + if (!PyArg_ParseTuple(args, "OOO", &obj, &buffertype, &order)) { + return NULL; + } + + if (!PyLong_Check(buffertype)) { + PyErr_SetString(PyExc_TypeError, + "buffertype must be PyBUF_READ or PyBUF_WRITE"); + return NULL; + } + + type = PyLong_AsLong(buffertype); + if (type == -1 && PyErr_Occurred()) { + return NULL; + } + if (type != PyBUF_READ && type != PyBUF_WRITE) { + PyErr_SetString(PyExc_ValueError, + "invalid buffer type"); + return NULL; + } + + ord = get_ascii_order(order); + if (ord == CHAR_MAX) + return NULL; + + return PyMemoryView_GetContiguous(obj, (int)type, ord); +} + +/* PyBuffer_ToContiguous() */ +static PyObject * +py_buffer_to_contiguous(PyObject *self, PyObject *args) +{ + PyObject *obj; + PyObject *order; + PyObject *ret = NULL; + int flags; + char ord; + Py_buffer view; + char *buf = NULL; + + if (!PyArg_ParseTuple(args, "OOi", &obj, &order, &flags)) { + return NULL; + } + + if (PyObject_GetBuffer(obj, &view, flags) < 0) { + return NULL; + } + + ord = get_ascii_order(order); + if (ord == CHAR_MAX) { + goto out; + } + + buf = PyMem_Malloc(view.len); + if (buf == NULL) { + PyErr_NoMemory(); + goto out; + } + + if (PyBuffer_ToContiguous(buf, &view, view.len, ord) < 0) { + goto out; + } + + ret = PyBytes_FromStringAndSize(buf, view.len); + +out: + PyBuffer_Release(&view); + PyMem_XFree(buf); + return ret; +} + +static int +fmtcmp(const char *fmt1, const char *fmt2) +{ + if (fmt1 == NULL) { + return fmt2 == NULL || strcmp(fmt2, "B") == 0; + } + if (fmt2 == NULL) { + return fmt1 == NULL || strcmp(fmt1, "B") == 0; + } + return strcmp(fmt1, fmt2) == 0; +} + +static int +arraycmp(const Py_ssize_t *a1, const Py_ssize_t *a2, const Py_ssize_t *shape, + Py_ssize_t ndim) +{ + Py_ssize_t i; + + + for (i = 0; i < ndim; i++) { + if (shape && shape[i] <= 1) { + /* strides can differ if the dimension is less than 2 */ + continue; + } + if (a1[i] != a2[i]) { + return 0; + } + } + + return 1; +} + +/* Compare two contiguous buffers for physical equality. */ +static PyObject * +cmp_contig(PyObject *self, PyObject *args) +{ + PyObject *b1, *b2; /* buffer objects */ + Py_buffer v1, v2; + PyObject *ret; + int equal = 0; + + if (!PyArg_ParseTuple(args, "OO", &b1, &b2)) { + return NULL; + } + + if (PyObject_GetBuffer(b1, &v1, PyBUF_FULL_RO) < 0) { + PyErr_SetString(PyExc_TypeError, + "cmp_contig: first argument does not implement the buffer " + "protocol"); + return NULL; + } + if (PyObject_GetBuffer(b2, &v2, PyBUF_FULL_RO) < 0) { + PyErr_SetString(PyExc_TypeError, + "cmp_contig: second argument does not implement the buffer " + "protocol"); + PyBuffer_Release(&v1); + return NULL; + } + + if (!(PyBuffer_IsContiguous(&v1, 'C')&&PyBuffer_IsContiguous(&v2, 'C')) && + !(PyBuffer_IsContiguous(&v1, 'F')&&PyBuffer_IsContiguous(&v2, 'F'))) { + goto result; + } + + /* readonly may differ if created from non-contiguous */ + if (v1.len != v2.len || + v1.itemsize != v2.itemsize || + v1.ndim != v2.ndim || + !fmtcmp(v1.format, v2.format) || + !!v1.shape != !!v2.shape || + !!v1.strides != !!v2.strides || + !!v1.suboffsets != !!v2.suboffsets) { + goto result; + } + + if ((v1.shape && !arraycmp(v1.shape, v2.shape, NULL, v1.ndim)) || + (v1.strides && !arraycmp(v1.strides, v2.strides, v1.shape, v1.ndim)) || + (v1.suboffsets && !arraycmp(v1.suboffsets, v2.suboffsets, NULL, + v1.ndim))) { + goto result; + } + + if (memcmp((char *)v1.buf, (char *)v2.buf, v1.len) != 0) { + goto result; + } + + equal = 1; + +result: + PyBuffer_Release(&v1); + PyBuffer_Release(&v2); + + ret = equal ? Py_True : Py_False; + Py_INCREF(ret); + return ret; +} + +static PyObject * +is_contiguous(PyObject *self, PyObject *args) +{ + PyObject *obj; + PyObject *order; + PyObject *ret = NULL; + Py_buffer view, *base; + char ord; + + if (!PyArg_ParseTuple(args, "OO", &obj, &order)) { + return NULL; + } + + ord = get_ascii_order(order); + if (ord == CHAR_MAX) { + return NULL; + } + + if (NDArray_Check(obj)) { + /* Skip the buffer protocol to check simple etc. buffers directly. */ + base = &((NDArrayObject *)obj)->head->base; + ret = PyBuffer_IsContiguous(base, ord) ? Py_True : Py_False; + } + else { + if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) { + PyErr_SetString(PyExc_TypeError, + "is_contiguous: object does not implement the buffer " + "protocol"); + return NULL; + } + ret = PyBuffer_IsContiguous(&view, ord) ? Py_True : Py_False; + PyBuffer_Release(&view); + } + + Py_INCREF(ret); + return ret; +} + +static Py_hash_t +ndarray_hash(PyObject *self) +{ + const NDArrayObject *nd = (NDArrayObject *)self; + const Py_buffer *view = &nd->head->base; + PyObject *bytes; + Py_hash_t hash; + + if (!view->readonly) { + PyErr_SetString(PyExc_ValueError, + "cannot hash writable ndarray object"); + return -1; + } + if (view->obj != NULL && PyObject_Hash(view->obj) == -1) { + return -1; + } + + bytes = ndarray_tobytes(self, NULL); + if (bytes == NULL) { + return -1; + } + + hash = PyObject_Hash(bytes); + Py_DECREF(bytes); + return hash; +} + + +static PyMethodDef ndarray_methods [] = +{ + { "tolist", ndarray_tolist, METH_NOARGS, NULL }, + { "tobytes", ndarray_tobytes, METH_NOARGS, NULL }, + { "push", (PyCFunction)(void(*)(void))ndarray_push, METH_VARARGS|METH_KEYWORDS, NULL }, + { "pop", ndarray_pop, METH_NOARGS, NULL }, + { "add_suboffsets", ndarray_add_suboffsets, METH_NOARGS, NULL }, + { "memoryview_from_buffer", ndarray_memoryview_from_buffer, METH_NOARGS, NULL }, + {NULL} +}; + +static PyTypeObject NDArray_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "ndarray", /* Name of this type */ + sizeof(NDArrayObject), /* Basic object size */ + 0, /* Item size for varobject */ + (destructor)ndarray_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &ndarray_as_sequence, /* tp_as_sequence */ + &ndarray_as_mapping, /* tp_as_mapping */ + (hashfunc)ndarray_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &ndarray_as_buffer, /* 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 */ + ndarray_methods, /* tp_methods */ + 0, /* tp_members */ + ndarray_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + ndarray_init, /* tp_init */ + 0, /* tp_alloc */ + ndarray_new, /* tp_new */ +}; + +/**************************************************************************/ +/* StaticArray Object */ +/**************************************************************************/ + +static PyTypeObject StaticArray_Type; + +typedef struct { + PyObject_HEAD + int legacy_mode; /* if true, use the view.obj==NULL hack */ +} StaticArrayObject; + +static char static_mem[12] = {0,1,2,3,4,5,6,7,8,9,10,11}; +static Py_ssize_t static_shape[1] = {12}; +static Py_ssize_t static_strides[1] = {1}; +static Py_buffer static_buffer = { + static_mem, /* buf */ + NULL, /* obj */ + 12, /* len */ + 1, /* itemsize */ + 1, /* readonly */ + 1, /* ndim */ + "B", /* format */ + static_shape, /* shape */ + static_strides, /* strides */ + NULL, /* suboffsets */ + NULL /* internal */ +}; + +static PyObject * +staticarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return (PyObject *)PyObject_New(StaticArrayObject, &StaticArray_Type); +} + +static int +staticarray_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + StaticArrayObject *a = (StaticArrayObject *)self; + static char *kwlist[] = { + "legacy_mode", NULL + }; + PyObject *legacy_mode = Py_False; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &legacy_mode)) + return -1; + + a->legacy_mode = (legacy_mode != Py_False); + return 0; +} + +static void +staticarray_dealloc(StaticArrayObject *self) +{ + PyObject_Del(self); +} + +/* Return a buffer for a PyBUF_FULL_RO request. Flags are not checked, + which makes this object a non-compliant exporter! */ +static int +staticarray_getbuf(StaticArrayObject *self, Py_buffer *view, int flags) +{ + *view = static_buffer; + + if (self->legacy_mode) { + view->obj = NULL; /* Don't use this in new code. */ + } + else { + view->obj = (PyObject *)self; + Py_INCREF(view->obj); + } + + return 0; +} + +static PyBufferProcs staticarray_as_buffer = { + (getbufferproc)staticarray_getbuf, /* bf_getbuffer */ + NULL, /* bf_releasebuffer */ +}; + +static PyTypeObject StaticArray_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "staticarray", /* Name of this type */ + sizeof(StaticArrayObject), /* Basic object size */ + 0, /* Item size for varobject */ + (destructor)staticarray_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 */ + &staticarray_as_buffer, /* 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 */ + staticarray_init, /* tp_init */ + 0, /* tp_alloc */ + staticarray_new, /* tp_new */ +}; + + +static struct PyMethodDef _testbuffer_functions[] = { + {"slice_indices", slice_indices, METH_VARARGS, NULL}, + {"get_pointer", get_pointer, METH_VARARGS, NULL}, + {"get_sizeof_void_p", get_sizeof_void_p, METH_NOARGS, NULL}, + {"get_contiguous", get_contiguous, METH_VARARGS, NULL}, + {"py_buffer_to_contiguous", py_buffer_to_contiguous, METH_VARARGS, NULL}, + {"is_contiguous", is_contiguous, METH_VARARGS, NULL}, + {"cmp_contig", cmp_contig, METH_VARARGS, NULL}, + {NULL, NULL} +}; + +static struct PyModuleDef _testbuffermodule = { + PyModuleDef_HEAD_INIT, + "_testbuffer", + NULL, + -1, + _testbuffer_functions, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__testbuffer(void) +{ + PyObject *m; + + m = PyModule_Create(&_testbuffermodule); + if (m == NULL) + return NULL; + + Py_TYPE(&NDArray_Type) = &PyType_Type; + Py_INCREF(&NDArray_Type); + PyModule_AddObject(m, "ndarray", (PyObject *)&NDArray_Type); + + Py_TYPE(&StaticArray_Type) = &PyType_Type; + Py_INCREF(&StaticArray_Type); + PyModule_AddObject(m, "staticarray", (PyObject *)&StaticArray_Type); + + structmodule = PyImport_ImportModule("struct"); + if (structmodule == NULL) + return NULL; + + Struct = PyObject_GetAttrString(structmodule, "Struct"); + calcsize = PyObject_GetAttrString(structmodule, "calcsize"); + if (Struct == NULL || calcsize == NULL) + return NULL; + + simple_format = PyUnicode_FromString(simple_fmt); + if (simple_format == NULL) + return NULL; + + PyModule_AddIntMacro(m, ND_MAX_NDIM); + PyModule_AddIntMacro(m, ND_VAREXPORT); + PyModule_AddIntMacro(m, ND_WRITABLE); + PyModule_AddIntMacro(m, ND_FORTRAN); + PyModule_AddIntMacro(m, ND_SCALAR); + PyModule_AddIntMacro(m, ND_PIL); + PyModule_AddIntMacro(m, ND_GETBUF_FAIL); + PyModule_AddIntMacro(m, ND_GETBUF_UNDEFINED); + PyModule_AddIntMacro(m, ND_REDIRECT); + + PyModule_AddIntMacro(m, PyBUF_SIMPLE); + PyModule_AddIntMacro(m, PyBUF_WRITABLE); + PyModule_AddIntMacro(m, PyBUF_FORMAT); + PyModule_AddIntMacro(m, PyBUF_ND); + PyModule_AddIntMacro(m, PyBUF_STRIDES); + PyModule_AddIntMacro(m, PyBUF_INDIRECT); + PyModule_AddIntMacro(m, PyBUF_C_CONTIGUOUS); + PyModule_AddIntMacro(m, PyBUF_F_CONTIGUOUS); + PyModule_AddIntMacro(m, PyBUF_ANY_CONTIGUOUS); + PyModule_AddIntMacro(m, PyBUF_FULL); + PyModule_AddIntMacro(m, PyBUF_FULL_RO); + PyModule_AddIntMacro(m, PyBUF_RECORDS); + PyModule_AddIntMacro(m, PyBUF_RECORDS_RO); + PyModule_AddIntMacro(m, PyBUF_STRIDED); + PyModule_AddIntMacro(m, PyBUF_STRIDED_RO); + PyModule_AddIntMacro(m, PyBUF_CONTIG); + PyModule_AddIntMacro(m, PyBUF_CONTIG_RO); + + PyModule_AddIntMacro(m, PyBUF_READ); + PyModule_AddIntMacro(m, PyBUF_WRITE); + + return m; +} + + + diff --git a/python/Modules/_testcapimodule.c b/python/Modules/_testcapimodule.c new file mode 100755 index 0000000..0d37e47 --- /dev/null +++ b/python/Modules/_testcapimodule.c @@ -0,0 +1,6491 @@ +// /* +// * C Extension module to test Python interpreter C APIs. +// * +// * The 'test_*' functions exported by this module are run as part of the +// * standard Python regression test, via Lib/test/test_capi.py. +// */ + +// /* The Visual Studio projects builds _testcapi with Py_BUILD_CORE_MODULE +// define, but we only want to test the public C API, not the internal +// C API. */ +// #undef Py_BUILD_CORE_MODULE + +// #define PY_SSIZE_T_CLEAN + +// #include "Python.h" +// #include "datetime.h" +// #include "marshal.h" +// #include "pythread.h" +// #include "structmember.h" +// #include +// #include + +// #ifdef MS_WINDOWS +// # include /* struct timeval */ +// #endif + +// #ifdef HAVE_SYS_WAIT_H +// #include /* For W_STOPCODE */ +// #endif + +// #ifdef Py_BUILD_CORE +// # error "_testcapi must test the public Python C API, not CPython internal C API" +// #endif + +// static struct PyModuleDef _testcapimodule; + +// static PyObject *TestError; /* set to exception object in init */ + +// /* Raise TestError with test_name + ": " + msg, and return NULL. */ + +// static PyObject * +// raiseTestError(const char* test_name, const char* msg) +// { +// PyErr_Format(TestError, "%s: %s", test_name, msg); +// return NULL; +// } + +// /* Test #defines from pyconfig.h (particularly the SIZEOF_* defines). + +// The ones derived from autoconf on the UNIX-like OSes can be relied +// upon (in the absence of sloppy cross-compiling), but the Windows +// platforms have these hardcoded. Better safe than sorry. +// */ +// static PyObject* +// sizeof_error(const char* fatname, const char* typname, +// int expected, int got) +// { +// PyErr_Format(TestError, +// "%s #define == %d but sizeof(%s) == %d", +// fatname, expected, typname, got); +// return (PyObject*)NULL; +// } + +// static PyObject* +// test_config(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// #define CHECK_SIZEOF(FATNAME, TYPE) \ +// if (FATNAME != sizeof(TYPE)) \ +// return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE)) + +// CHECK_SIZEOF(SIZEOF_SHORT, short); +// CHECK_SIZEOF(SIZEOF_INT, int); +// CHECK_SIZEOF(SIZEOF_LONG, long); +// CHECK_SIZEOF(SIZEOF_VOID_P, void*); +// CHECK_SIZEOF(SIZEOF_TIME_T, time_t); +// CHECK_SIZEOF(SIZEOF_LONG_LONG, long long); + +// #undef CHECK_SIZEOF + +// Py_RETURN_NONE; +// } + +// static PyObject* +// test_sizeof_c_types(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) +// #pragma GCC diagnostic push +// #pragma GCC diagnostic ignored "-Wtype-limits" +// #endif +// #define CHECK_SIZEOF(TYPE, EXPECTED) \ +// if (EXPECTED != sizeof(TYPE)) { \ +// PyErr_Format(TestError, \ +// "sizeof(%s) = %u instead of %u", \ +// #TYPE, sizeof(TYPE), EXPECTED); \ +// return (PyObject*)NULL; \ +// } +// #define IS_SIGNED(TYPE) (((TYPE)-1) < (TYPE)0) +// #define CHECK_SIGNNESS(TYPE, SIGNED) \ +// if (IS_SIGNED(TYPE) != SIGNED) { \ +// PyErr_Format(TestError, \ +// "%s signness is, instead of %i", \ +// #TYPE, IS_SIGNED(TYPE), SIGNED); \ +// return (PyObject*)NULL; \ +// } + +// /* integer types */ +// CHECK_SIZEOF(Py_UCS1, 1); +// CHECK_SIZEOF(Py_UCS2, 2); +// CHECK_SIZEOF(Py_UCS4, 4); +// CHECK_SIGNNESS(Py_UCS1, 0); +// CHECK_SIGNNESS(Py_UCS2, 0); +// CHECK_SIGNNESS(Py_UCS4, 0); +// CHECK_SIZEOF(int32_t, 4); +// CHECK_SIGNNESS(int32_t, 1); +// CHECK_SIZEOF(uint32_t, 4); +// CHECK_SIGNNESS(uint32_t, 0); +// CHECK_SIZEOF(int64_t, 8); +// CHECK_SIGNNESS(int64_t, 1); +// CHECK_SIZEOF(uint64_t, 8); +// CHECK_SIGNNESS(uint64_t, 0); + +// /* pointer/size types */ +// CHECK_SIZEOF(size_t, sizeof(void *)); +// CHECK_SIGNNESS(size_t, 0); +// CHECK_SIZEOF(Py_ssize_t, sizeof(void *)); +// CHECK_SIGNNESS(Py_ssize_t, 1); + +// CHECK_SIZEOF(uintptr_t, sizeof(void *)); +// CHECK_SIGNNESS(uintptr_t, 0); +// CHECK_SIZEOF(intptr_t, sizeof(void *)); +// CHECK_SIGNNESS(intptr_t, 1); + +// Py_RETURN_NONE; + +// #undef IS_SIGNED +// #undef CHECK_SIGNESS +// #undef CHECK_SIZEOF +// #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) +// #pragma GCC diagnostic pop +// #endif +// } + + +// static PyObject* +// test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject* list; +// int i; + +// /* SF bug 132008: PyList_Reverse segfaults */ +// #define NLIST 30 +// list = PyList_New(NLIST); +// if (list == (PyObject*)NULL) +// return (PyObject*)NULL; +// /* list = range(NLIST) */ +// for (i = 0; i < NLIST; ++i) { +// PyObject* anint = PyLong_FromLong(i); +// if (anint == (PyObject*)NULL) { +// Py_DECREF(list); +// return (PyObject*)NULL; +// } +// PyList_SET_ITEM(list, i, anint); +// } +// /* list.reverse(), via PyList_Reverse() */ +// i = PyList_Reverse(list); /* should not blow up! */ +// if (i != 0) { +// Py_DECREF(list); +// return (PyObject*)NULL; +// } +// /* Check that list == range(29, -1, -1) now */ +// for (i = 0; i < NLIST; ++i) { +// PyObject* anint = PyList_GET_ITEM(list, i); +// if (PyLong_AS_LONG(anint) != NLIST-1-i) { +// PyErr_SetString(TestError, +// "test_list_api: reverse screwed up"); +// Py_DECREF(list); +// return (PyObject*)NULL; +// } +// } +// Py_DECREF(list); +// #undef NLIST + +// Py_RETURN_NONE; +// } + +// static int +// test_dict_inner(int count) +// { +// Py_ssize_t pos = 0, iterations = 0; +// int i; +// PyObject *dict = PyDict_New(); +// PyObject *v, *k; + +// if (dict == NULL) +// return -1; + +// for (i = 0; i < count; i++) { +// v = PyLong_FromLong(i); +// if (v == NULL) { +// return -1; +// } +// if (PyDict_SetItem(dict, v, v) < 0) { +// Py_DECREF(v); +// return -1; +// } +// Py_DECREF(v); +// } + +// while (PyDict_Next(dict, &pos, &k, &v)) { +// PyObject *o; +// iterations++; + +// i = PyLong_AS_LONG(v) + 1; +// o = PyLong_FromLong(i); +// if (o == NULL) +// return -1; +// if (PyDict_SetItem(dict, k, o) < 0) { +// Py_DECREF(o); +// return -1; +// } +// Py_DECREF(o); +// } + +// Py_DECREF(dict); + +// if (iterations != count) { +// PyErr_SetString( +// TestError, +// "test_dict_iteration: dict iteration went wrong "); +// return -1; +// } else { +// return 0; +// } +// } + +// static PyObject* +// test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored)) +// { +// int i; + +// for (i = 0; i < 200; i++) { +// if (test_dict_inner(i) < 0) { +// return NULL; +// } +// } + +// Py_RETURN_NONE; +// } + +// static PyObject* +// dict_getitem_knownhash(PyObject *self, PyObject *args) +// { +// PyObject *mp, *key, *result; +// Py_ssize_t hash; + +// if (!PyArg_ParseTuple(args, "OOn:dict_getitem_knownhash", +// &mp, &key, &hash)) { +// return NULL; +// } + +// result = _PyDict_GetItem_KnownHash(mp, key, (Py_hash_t)hash); +// if (result == NULL && !PyErr_Occurred()) { +// _PyErr_SetKeyError(key); +// return NULL; +// } + +// Py_XINCREF(result); +// return result; +// } + +// static PyObject* +// dict_hassplittable(PyObject *self, PyObject *arg) +// { +// if (!PyDict_Check(arg)) { +// PyErr_Format(PyExc_TypeError, +// "dict_hassplittable() argument must be dict, not '%s'", +// arg->ob_type->tp_name); +// return NULL; +// } + +// return PyBool_FromLong(_PyDict_HasSplitTable((PyDictObject*)arg)); +// } + +// /* Issue #4701: Check that PyObject_Hash implicitly calls +// * PyType_Ready if it hasn't already been called +// */ +// static PyTypeObject _HashInheritanceTester_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "hashinheritancetester", /* Name of this type */ +// sizeof(PyObject), /* Basic object size */ +// 0, /* Item size for varobject */ +// (destructor)PyObject_Del, /* 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_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 */ +// PyType_GenericNew, /* tp_new */ +// }; + +// static PyObject* +// test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored)) +// { +// PyTypeObject *type; +// PyObject *obj; +// Py_hash_t hash; + +// type = &_HashInheritanceTester_Type; + +// if (type->tp_dict != NULL) +// /* The type has already been initialized. This probably means +// -R is being used. */ +// Py_RETURN_NONE; + + +// obj = PyObject_New(PyObject, type); +// if (obj == NULL) { +// PyErr_Clear(); +// PyErr_SetString( +// TestError, +// "test_lazy_hash_inheritance: failed to create object"); +// return NULL; +// } + +// if (type->tp_dict != NULL) { +// PyErr_SetString( +// TestError, +// "test_lazy_hash_inheritance: type initialised too soon"); +// Py_DECREF(obj); +// return NULL; +// } + +// hash = PyObject_Hash(obj); +// if ((hash == -1) && PyErr_Occurred()) { +// PyErr_Clear(); +// PyErr_SetString( +// TestError, +// "test_lazy_hash_inheritance: could not hash object"); +// Py_DECREF(obj); +// return NULL; +// } + +// if (type->tp_dict == NULL) { +// PyErr_SetString( +// TestError, +// "test_lazy_hash_inheritance: type not initialised by hash()"); +// Py_DECREF(obj); +// return NULL; +// } + +// if (type->tp_hash != PyType_Type.tp_hash) { +// PyErr_SetString( +// TestError, +// "test_lazy_hash_inheritance: unexpected hash function"); +// Py_DECREF(obj); +// return NULL; +// } + +// Py_DECREF(obj); + +// Py_RETURN_NONE; +// } + + +// /* Tests of PyLong_{As, From}{Unsigned,}Long(), and +// PyLong_{As, From}{Unsigned,}LongLong(). + +// Note that the meat of the test is contained in testcapi_long.h. +// This is revolting, but delicate code duplication is worse: "almost +// exactly the same" code is needed to test long long, but the ubiquitous +// dependence on type names makes it impossible to use a parameterized +// function. A giant macro would be even worse than this. A C++ template +// would be perfect. + +// The "report an error" functions are deliberately not part of the #include +// file: if the test fails, you can set a breakpoint in the appropriate +// error function directly, and crawl back from there in the debugger. +// */ + +// #define UNBIND(X) Py_DECREF(X); (X) = NULL + +// static PyObject * +// raise_test_long_error(const char* msg) +// { +// return raiseTestError("test_long_api", msg); +// } + +// #define TESTNAME test_long_api_inner +// #define TYPENAME long +// #define F_S_TO_PY PyLong_FromLong +// #define F_PY_TO_S PyLong_AsLong +// #define F_U_TO_PY PyLong_FromUnsignedLong +// #define F_PY_TO_U PyLong_AsUnsignedLong + +// #include "testcapi_long.h" + +// static PyObject * +// test_long_api(PyObject* self, PyObject *Py_UNUSED(ignored)) +// { +// return TESTNAME(raise_test_long_error); +// } + +// #undef TESTNAME +// #undef TYPENAME +// #undef F_S_TO_PY +// #undef F_PY_TO_S +// #undef F_U_TO_PY +// #undef F_PY_TO_U + +// static PyObject * +// raise_test_longlong_error(const char* msg) +// { +// return raiseTestError("test_longlong_api", msg); +// } + +// #define TESTNAME test_longlong_api_inner +// #define TYPENAME long long +// #define F_S_TO_PY PyLong_FromLongLong +// #define F_PY_TO_S PyLong_AsLongLong +// #define F_U_TO_PY PyLong_FromUnsignedLongLong +// #define F_PY_TO_U PyLong_AsUnsignedLongLong + +// #include "testcapi_long.h" + +// static PyObject * +// test_longlong_api(PyObject* self, PyObject *args) +// { +// return TESTNAME(raise_test_longlong_error); +// } + +// #undef TESTNAME +// #undef TYPENAME +// #undef F_S_TO_PY +// #undef F_PY_TO_S +// #undef F_U_TO_PY +// #undef F_PY_TO_U + +// /* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG +// is tested by test_long_api_inner. This test will concentrate on proper +// handling of overflow. +// */ + +// static PyObject * +// test_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *num, *one, *temp; +// long value; +// int overflow; + +// /* Test that overflow is set properly for a large value. */ +// /* num is a number larger than LONG_MAX even on 64-bit platforms */ +// num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != 1) +// return raiseTestError("test_long_and_overflow", +// "overflow was not set to 1"); + +// /* Same again, with num = LONG_MAX + 1 */ +// num = PyLong_FromLong(LONG_MAX); +// if (num == NULL) +// return NULL; +// one = PyLong_FromLong(1L); +// if (one == NULL) { +// Py_DECREF(num); +// return NULL; +// } +// temp = PyNumber_Add(num, one); +// Py_DECREF(one); +// Py_DECREF(num); +// num = temp; +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != 1) +// return raiseTestError("test_long_and_overflow", +// "overflow was not set to 1"); + +// /* Test that overflow is set properly for a large negative value. */ +// /* num is a number smaller than LONG_MIN even on 64-bit platforms */ +// num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != -1) +// return raiseTestError("test_long_and_overflow", +// "overflow was not set to -1"); + +// /* Same again, with num = LONG_MIN - 1 */ +// num = PyLong_FromLong(LONG_MIN); +// if (num == NULL) +// return NULL; +// one = PyLong_FromLong(1L); +// if (one == NULL) { +// Py_DECREF(num); +// return NULL; +// } +// temp = PyNumber_Subtract(num, one); +// Py_DECREF(one); +// Py_DECREF(num); +// num = temp; +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != -1) +// return raiseTestError("test_long_and_overflow", +// "overflow was not set to -1"); + +// /* Test that overflow is cleared properly for small values. */ +// num = PyLong_FromString("FF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != 0xFF) +// return raiseTestError("test_long_and_overflow", +// "expected return value 0xFF"); +// if (overflow != 0) +// return raiseTestError("test_long_and_overflow", +// "overflow was not cleared"); + +// num = PyLong_FromString("-FF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -0xFF) +// return raiseTestError("test_long_and_overflow", +// "expected return value 0xFF"); +// if (overflow != 0) +// return raiseTestError("test_long_and_overflow", +// "overflow was set incorrectly"); + +// num = PyLong_FromLong(LONG_MAX); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != LONG_MAX) +// return raiseTestError("test_long_and_overflow", +// "expected return value LONG_MAX"); +// if (overflow != 0) +// return raiseTestError("test_long_and_overflow", +// "overflow was not cleared"); + +// num = PyLong_FromLong(LONG_MIN); +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != LONG_MIN) +// return raiseTestError("test_long_and_overflow", +// "expected return value LONG_MIN"); +// if (overflow != 0) +// return raiseTestError("test_long_and_overflow", +// "overflow was not cleared"); + +// Py_RETURN_NONE; +// } + +// /* Test the PyLong_AsLongLongAndOverflow API. General conversion to +// long long is tested by test_long_api_inner. This test will +// concentrate on proper handling of overflow. +// */ + +// static PyObject * +// test_long_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *num, *one, *temp; +// long long value; +// int overflow; + +// /* Test that overflow is set properly for a large value. */ +// /* num is a number larger than PY_LLONG_MAX on a typical machine. */ +// num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != 1) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was not set to 1"); + +// /* Same again, with num = PY_LLONG_MAX + 1 */ +// num = PyLong_FromLongLong(PY_LLONG_MAX); +// if (num == NULL) +// return NULL; +// one = PyLong_FromLong(1L); +// if (one == NULL) { +// Py_DECREF(num); +// return NULL; +// } +// temp = PyNumber_Add(num, one); +// Py_DECREF(one); +// Py_DECREF(num); +// num = temp; +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != 1) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was not set to 1"); + +// /* Test that overflow is set properly for a large negative value. */ +// /* num is a number smaller than PY_LLONG_MIN on a typical platform */ +// num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != -1) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was not set to -1"); + +// /* Same again, with num = PY_LLONG_MIN - 1 */ +// num = PyLong_FromLongLong(PY_LLONG_MIN); +// if (num == NULL) +// return NULL; +// one = PyLong_FromLong(1L); +// if (one == NULL) { +// Py_DECREF(num); +// return NULL; +// } +// temp = PyNumber_Subtract(num, one); +// Py_DECREF(one); +// Py_DECREF(num); +// num = temp; +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -1) +// return raiseTestError("test_long_long_and_overflow", +// "return value was not set to -1"); +// if (overflow != -1) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was not set to -1"); + +// /* Test that overflow is cleared properly for small values. */ +// num = PyLong_FromString("FF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != 0xFF) +// return raiseTestError("test_long_long_and_overflow", +// "expected return value 0xFF"); +// if (overflow != 0) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was not cleared"); + +// num = PyLong_FromString("-FF", NULL, 16); +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != -0xFF) +// return raiseTestError("test_long_long_and_overflow", +// "expected return value 0xFF"); +// if (overflow != 0) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was set incorrectly"); + +// num = PyLong_FromLongLong(PY_LLONG_MAX); +// if (num == NULL) +// return NULL; +// overflow = 1234; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != PY_LLONG_MAX) +// return raiseTestError("test_long_long_and_overflow", +// "expected return value PY_LLONG_MAX"); +// if (overflow != 0) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was not cleared"); + +// num = PyLong_FromLongLong(PY_LLONG_MIN); +// if (num == NULL) +// return NULL; +// overflow = 0; +// value = PyLong_AsLongLongAndOverflow(num, &overflow); +// Py_DECREF(num); +// if (value == -1 && PyErr_Occurred()) +// return NULL; +// if (value != PY_LLONG_MIN) +// return raiseTestError("test_long_long_and_overflow", +// "expected return value PY_LLONG_MIN"); +// if (overflow != 0) +// return raiseTestError("test_long_long_and_overflow", +// "overflow was not cleared"); + +// Py_RETURN_NONE; +// } + +// /* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that +// non-integer arguments are handled correctly. It should be extended to +// test overflow handling. +// */ + +// static PyObject * +// test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// size_t out_u; +// Py_ssize_t out_s; + +// Py_INCREF(Py_None); + +// out_u = PyLong_AsSize_t(Py_None); +// if (out_u != (size_t)-1 || !PyErr_Occurred()) +// return raiseTestError("test_long_as_size_t", +// "PyLong_AsSize_t(None) didn't complain"); +// if (!PyErr_ExceptionMatches(PyExc_TypeError)) +// return raiseTestError("test_long_as_size_t", +// "PyLong_AsSize_t(None) raised " +// "something other than TypeError"); +// PyErr_Clear(); + +// out_s = PyLong_AsSsize_t(Py_None); +// if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred()) +// return raiseTestError("test_long_as_size_t", +// "PyLong_AsSsize_t(None) didn't complain"); +// if (!PyErr_ExceptionMatches(PyExc_TypeError)) +// return raiseTestError("test_long_as_size_t", +// "PyLong_AsSsize_t(None) raised " +// "something other than TypeError"); +// PyErr_Clear(); + +// /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ +// return Py_None; +// } + +// static PyObject * +// test_long_as_unsigned_long_long_mask(PyObject *self, +// PyObject *Py_UNUSED(ignored)) +// { +// unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL); + +// if (res != (unsigned long long)-1 || !PyErr_Occurred()) { +// return raiseTestError("test_long_as_unsigned_long_long_mask", +// "PyLong_AsUnsignedLongLongMask(NULL) didn't " +// "complain"); +// } +// if (!PyErr_ExceptionMatches(PyExc_SystemError)) { +// return raiseTestError("test_long_as_unsigned_long_long_mask", +// "PyLong_AsUnsignedLongLongMask(NULL) raised " +// "something other than SystemError"); +// } +// PyErr_Clear(); +// Py_RETURN_NONE; +// } + +// /* Test the PyLong_AsDouble API. At present this just tests that +// non-integer arguments are handled correctly. +// */ + +// static PyObject * +// test_long_as_double(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// double out; + +// Py_INCREF(Py_None); + +// out = PyLong_AsDouble(Py_None); +// if (out != -1.0 || !PyErr_Occurred()) +// return raiseTestError("test_long_as_double", +// "PyLong_AsDouble(None) didn't complain"); +// if (!PyErr_ExceptionMatches(PyExc_TypeError)) +// return raiseTestError("test_long_as_double", +// "PyLong_AsDouble(None) raised " +// "something other than TypeError"); +// PyErr_Clear(); + +// /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ +// return Py_None; +// } + +// /* Test the L code for PyArg_ParseTuple. This should deliver a long long +// for both long and int arguments. The test may leak a little memory if +// it fails. +// */ +// static PyObject * +// test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *tuple, *num; +// long long value; + +// tuple = PyTuple_New(1); +// if (tuple == NULL) +// return NULL; + +// num = PyLong_FromLong(42); +// if (num == NULL) +// return NULL; + +// PyTuple_SET_ITEM(tuple, 0, num); + +// value = -1; +// if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { +// return NULL; +// } +// if (value != 42) +// return raiseTestError("test_L_code", +// "L code returned wrong value for long 42"); + +// Py_DECREF(num); +// num = PyLong_FromLong(42); +// if (num == NULL) +// return NULL; + +// PyTuple_SET_ITEM(tuple, 0, num); + +// value = -1; +// if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { +// return NULL; +// } +// if (value != 42) +// return raiseTestError("test_L_code", +// "L code returned wrong value for int 42"); + +// Py_DECREF(tuple); +// Py_RETURN_NONE; +// } + +// static PyObject * +// return_none(void *unused) +// { +// Py_RETURN_NONE; +// } + +// static PyObject * +// raise_error(void *unused) +// { +// PyErr_SetNone(PyExc_ValueError); +// return NULL; +// } + +// static int +// test_buildvalue_N_error(const char *fmt) +// { +// PyObject *arg, *res; + +// arg = PyList_New(0); +// if (arg == NULL) { +// return -1; +// } + +// Py_INCREF(arg); +// res = Py_BuildValue(fmt, return_none, NULL, arg); +// if (res == NULL) { +// return -1; +// } +// Py_DECREF(res); +// if (Py_REFCNT(arg) != 1) { +// PyErr_Format(TestError, "test_buildvalue_N: " +// "arg was not decrefed in successful " +// "Py_BuildValue(\"%s\")", fmt); +// return -1; +// } + +// Py_INCREF(arg); +// res = Py_BuildValue(fmt, raise_error, NULL, arg); +// if (res != NULL || !PyErr_Occurred()) { +// PyErr_Format(TestError, "test_buildvalue_N: " +// "Py_BuildValue(\"%s\") didn't complain", fmt); +// return -1; +// } +// PyErr_Clear(); +// if (Py_REFCNT(arg) != 1) { +// PyErr_Format(TestError, "test_buildvalue_N: " +// "arg was not decrefed in failed " +// "Py_BuildValue(\"%s\")", fmt); +// return -1; +// } +// Py_DECREF(arg); +// return 0; +// } + +// static PyObject * +// test_buildvalue_N(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *arg, *res; + +// arg = PyList_New(0); +// if (arg == NULL) { +// return NULL; +// } +// Py_INCREF(arg); +// res = Py_BuildValue("N", arg); +// if (res == NULL) { +// return NULL; +// } +// if (res != arg) { +// return raiseTestError("test_buildvalue_N", +// "Py_BuildValue(\"N\") returned wrong result"); +// } +// if (Py_REFCNT(arg) != 2) { +// return raiseTestError("test_buildvalue_N", +// "arg was not decrefed in Py_BuildValue(\"N\")"); +// } +// Py_DECREF(res); +// Py_DECREF(arg); + +// if (test_buildvalue_N_error("O&N") < 0) +// return NULL; +// if (test_buildvalue_N_error("(O&N)") < 0) +// return NULL; +// if (test_buildvalue_N_error("[O&N]") < 0) +// return NULL; +// if (test_buildvalue_N_error("{O&N}") < 0) +// return NULL; +// if (test_buildvalue_N_error("{()O&(())N}") < 0) +// return NULL; + +// Py_RETURN_NONE; +// } + + +// static PyObject * +// get_args(PyObject *self, PyObject *args) +// { +// if (args == NULL) { +// args = Py_None; +// } +// Py_INCREF(args); +// return args; +// } + +// static PyObject * +// get_kwargs(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// if (kwargs == NULL) { +// kwargs = Py_None; +// } +// Py_INCREF(kwargs); +// return kwargs; +// } + +// /* Test tuple argument processing */ +// static PyObject * +// getargs_tuple(PyObject *self, PyObject *args) +// { +// int a, b, c; +// if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c)) +// return NULL; +// return Py_BuildValue("iii", a, b, c); +// } + +// /* test PyArg_ParseTupleAndKeywords */ +// static PyObject * +// getargs_keywords(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// static char *keywords[] = {"arg1","arg2","arg3","arg4","arg5", NULL}; +// static const char fmt[] = "(ii)i|(i(ii))(iii)i"; +// int int_args[10]={-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +// if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, +// &int_args[0], &int_args[1], &int_args[2], &int_args[3], &int_args[4], +// &int_args[5], &int_args[6], &int_args[7], &int_args[8], &int_args[9])) +// return NULL; +// return Py_BuildValue("iiiiiiiiii", +// int_args[0], int_args[1], int_args[2], int_args[3], int_args[4], +// int_args[5], int_args[6], int_args[7], int_args[8], int_args[9]); +// } + +// /* test PyArg_ParseTupleAndKeywords keyword-only arguments */ +// static PyObject * +// getargs_keyword_only(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// static char *keywords[] = {"required", "optional", "keyword_only", NULL}; +// int required = -1; +// int optional = -1; +// int keyword_only = -1; + +// if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i$i", keywords, +// &required, &optional, &keyword_only)) +// return NULL; +// return Py_BuildValue("iii", required, optional, keyword_only); +// } + +// /* test PyArg_ParseTupleAndKeywords positional-only arguments */ +// static PyObject * +// getargs_positional_only_and_keywords(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// static char *keywords[] = {"", "", "keyword", NULL}; +// int required = -1; +// int optional = -1; +// int keyword = -1; + +// if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii", keywords, +// &required, &optional, &keyword)) +// return NULL; +// return Py_BuildValue("iii", required, optional, keyword); +// } + +// /* Functions to call PyArg_ParseTuple with integer format codes, +// and return the result. +// */ +// static PyObject * +// getargs_b(PyObject *self, PyObject *args) +// { +// unsigned char value; +// if (!PyArg_ParseTuple(args, "b", &value)) +// return NULL; +// return PyLong_FromUnsignedLong((unsigned long)value); +// } + +// static PyObject * +// getargs_B(PyObject *self, PyObject *args) +// { +// unsigned char value; +// if (!PyArg_ParseTuple(args, "B", &value)) +// return NULL; +// return PyLong_FromUnsignedLong((unsigned long)value); +// } + +// static PyObject * +// getargs_h(PyObject *self, PyObject *args) +// { +// short value; +// if (!PyArg_ParseTuple(args, "h", &value)) +// return NULL; +// return PyLong_FromLong((long)value); +// } + +// static PyObject * +// getargs_H(PyObject *self, PyObject *args) +// { +// unsigned short value; +// if (!PyArg_ParseTuple(args, "H", &value)) +// return NULL; +// return PyLong_FromUnsignedLong((unsigned long)value); +// } + +// static PyObject * +// getargs_I(PyObject *self, PyObject *args) +// { +// unsigned int value; +// if (!PyArg_ParseTuple(args, "I", &value)) +// return NULL; +// return PyLong_FromUnsignedLong((unsigned long)value); +// } + +// static PyObject * +// getargs_k(PyObject *self, PyObject *args) +// { +// unsigned long value; +// if (!PyArg_ParseTuple(args, "k", &value)) +// return NULL; +// return PyLong_FromUnsignedLong(value); +// } + +// static PyObject * +// getargs_i(PyObject *self, PyObject *args) +// { +// int value; +// if (!PyArg_ParseTuple(args, "i", &value)) +// return NULL; +// return PyLong_FromLong((long)value); +// } + +// static PyObject * +// getargs_l(PyObject *self, PyObject *args) +// { +// long value; +// if (!PyArg_ParseTuple(args, "l", &value)) +// return NULL; +// return PyLong_FromLong(value); +// } + +// static PyObject * +// getargs_n(PyObject *self, PyObject *args) +// { +// Py_ssize_t value; +// if (!PyArg_ParseTuple(args, "n", &value)) +// return NULL; +// return PyLong_FromSsize_t(value); +// } + +// static PyObject * +// getargs_p(PyObject *self, PyObject *args) +// { +// int value; +// if (!PyArg_ParseTuple(args, "p", &value)) +// return NULL; +// return PyLong_FromLong(value); +// } + +// static PyObject * +// getargs_L(PyObject *self, PyObject *args) +// { +// long long value; +// if (!PyArg_ParseTuple(args, "L", &value)) +// return NULL; +// return PyLong_FromLongLong(value); +// } + +// static PyObject * +// getargs_K(PyObject *self, PyObject *args) +// { +// unsigned long long value; +// if (!PyArg_ParseTuple(args, "K", &value)) +// return NULL; +// return PyLong_FromUnsignedLongLong(value); +// } + +// /* This function not only tests the 'k' getargs code, but also the +// PyLong_AsUnsignedLongMask() function. */ +// static PyObject * +// test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *tuple, *num; +// unsigned long value; + +// tuple = PyTuple_New(1); +// if (tuple == NULL) +// return NULL; + +// /* a number larger than ULONG_MAX even on 64-bit platforms */ +// num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); +// if (num == NULL) +// return NULL; + +// value = PyLong_AsUnsignedLongMask(num); +// if (value != ULONG_MAX) +// return raiseTestError("test_k_code", +// "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); + +// PyTuple_SET_ITEM(tuple, 0, num); + +// value = 0; +// if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { +// return NULL; +// } +// if (value != ULONG_MAX) +// return raiseTestError("test_k_code", +// "k code returned wrong value for long 0xFFF...FFF"); + +// Py_DECREF(num); +// num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16); +// if (num == NULL) +// return NULL; + +// value = PyLong_AsUnsignedLongMask(num); +// if (value != (unsigned long)-0x42) +// return raiseTestError("test_k_code", +// "PyLong_AsUnsignedLongMask() returned wrong " +// "value for long -0xFFF..000042"); + +// PyTuple_SET_ITEM(tuple, 0, num); + +// value = 0; +// if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { +// return NULL; +// } +// if (value != (unsigned long)-0x42) +// return raiseTestError("test_k_code", +// "k code returned wrong value for long -0xFFF..000042"); + +// Py_DECREF(tuple); +// Py_RETURN_NONE; +// } + +// static PyObject * +// getargs_f(PyObject *self, PyObject *args) +// { +// float f; +// if (!PyArg_ParseTuple(args, "f", &f)) +// return NULL; +// return PyFloat_FromDouble(f); +// } + +// static PyObject * +// getargs_d(PyObject *self, PyObject *args) +// { +// double d; +// if (!PyArg_ParseTuple(args, "d", &d)) +// return NULL; +// return PyFloat_FromDouble(d); +// } + +// static PyObject * +// getargs_D(PyObject *self, PyObject *args) +// { +// Py_complex cval; +// if (!PyArg_ParseTuple(args, "D", &cval)) +// return NULL; +// return PyComplex_FromCComplex(cval); +// } + +// static PyObject * +// getargs_S(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// if (!PyArg_ParseTuple(args, "S", &obj)) +// return NULL; +// Py_INCREF(obj); +// return obj; +// } + +// static PyObject * +// getargs_Y(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// if (!PyArg_ParseTuple(args, "Y", &obj)) +// return NULL; +// Py_INCREF(obj); +// return obj; +// } + +// static PyObject * +// getargs_U(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// if (!PyArg_ParseTuple(args, "U", &obj)) +// return NULL; +// Py_INCREF(obj); +// return obj; +// } + +// static PyObject * +// getargs_c(PyObject *self, PyObject *args) +// { +// char c; +// if (!PyArg_ParseTuple(args, "c", &c)) +// return NULL; +// return PyLong_FromLong((unsigned char)c); +// } + +// static PyObject * +// getargs_C(PyObject *self, PyObject *args) +// { +// int c; +// if (!PyArg_ParseTuple(args, "C", &c)) +// return NULL; +// return PyLong_FromLong(c); +// } + +// static PyObject * +// getargs_s(PyObject *self, PyObject *args) +// { +// char *str; +// if (!PyArg_ParseTuple(args, "s", &str)) +// return NULL; +// return PyBytes_FromString(str); +// } + +// static PyObject * +// getargs_s_star(PyObject *self, PyObject *args) +// { +// Py_buffer buffer; +// PyObject *bytes; +// if (!PyArg_ParseTuple(args, "s*", &buffer)) +// return NULL; +// bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); +// PyBuffer_Release(&buffer); +// return bytes; +// } + +// static PyObject * +// getargs_s_hash(PyObject *self, PyObject *args) +// { +// char *str; +// Py_ssize_t size; +// if (!PyArg_ParseTuple(args, "s#", &str, &size)) +// return NULL; +// return PyBytes_FromStringAndSize(str, size); +// } + +// static PyObject * +// getargs_z(PyObject *self, PyObject *args) +// { +// char *str; +// if (!PyArg_ParseTuple(args, "z", &str)) +// return NULL; +// if (str != NULL) +// return PyBytes_FromString(str); +// else +// Py_RETURN_NONE; +// } + +// static PyObject * +// getargs_z_star(PyObject *self, PyObject *args) +// { +// Py_buffer buffer; +// PyObject *bytes; +// if (!PyArg_ParseTuple(args, "z*", &buffer)) +// return NULL; +// if (buffer.buf != NULL) +// bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); +// else { +// Py_INCREF(Py_None); +// bytes = Py_None; +// } +// PyBuffer_Release(&buffer); +// return bytes; +// } + +// static PyObject * +// getargs_z_hash(PyObject *self, PyObject *args) +// { +// char *str; +// Py_ssize_t size; +// if (!PyArg_ParseTuple(args, "z#", &str, &size)) +// return NULL; +// if (str != NULL) +// return PyBytes_FromStringAndSize(str, size); +// else +// Py_RETURN_NONE; +// } + +// static PyObject * +// getargs_y(PyObject *self, PyObject *args) +// { +// char *str; +// if (!PyArg_ParseTuple(args, "y", &str)) +// return NULL; +// return PyBytes_FromString(str); +// } + +// static PyObject * +// getargs_y_star(PyObject *self, PyObject *args) +// { +// Py_buffer buffer; +// PyObject *bytes; +// if (!PyArg_ParseTuple(args, "y*", &buffer)) +// return NULL; +// bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); +// PyBuffer_Release(&buffer); +// return bytes; +// } + +// static PyObject * +// getargs_y_hash(PyObject *self, PyObject *args) +// { +// char *str; +// Py_ssize_t size; +// if (!PyArg_ParseTuple(args, "y#", &str, &size)) +// return NULL; +// return PyBytes_FromStringAndSize(str, size); +// } + +// static PyObject * +// getargs_u(PyObject *self, PyObject *args) +// { +// Py_UNICODE *str; +// if (!PyArg_ParseTuple(args, "u", &str)) +// return NULL; +// return PyUnicode_FromWideChar(str, -1); +// } + +// static PyObject * +// getargs_u_hash(PyObject *self, PyObject *args) +// { +// Py_UNICODE *str; +// Py_ssize_t size; +// if (!PyArg_ParseTuple(args, "u#", &str, &size)) +// return NULL; +// return PyUnicode_FromWideChar(str, size); +// } + +// static PyObject * +// getargs_Z(PyObject *self, PyObject *args) +// { +// Py_UNICODE *str; +// if (!PyArg_ParseTuple(args, "Z", &str)) +// return NULL; +// if (str != NULL) { +// return PyUnicode_FromWideChar(str, -1); +// } else +// Py_RETURN_NONE; +// } + +// static PyObject * +// getargs_Z_hash(PyObject *self, PyObject *args) +// { +// Py_UNICODE *str; +// Py_ssize_t size; +// if (!PyArg_ParseTuple(args, "Z#", &str, &size)) +// return NULL; +// if (str != NULL) +// return PyUnicode_FromWideChar(str, size); +// else +// Py_RETURN_NONE; +// } + +// static PyObject * +// getargs_es(PyObject *self, PyObject *args) +// { +// PyObject *arg, *result; +// const char *encoding = NULL; +// char *str; + +// if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) +// return NULL; +// if (!PyArg_Parse(arg, "es", encoding, &str)) +// return NULL; +// result = PyBytes_FromString(str); +// PyMem_Free(str); +// return result; +// } + +// static PyObject * +// getargs_et(PyObject *self, PyObject *args) +// { +// PyObject *arg, *result; +// const char *encoding = NULL; +// char *str; + +// if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) +// return NULL; +// if (!PyArg_Parse(arg, "et", encoding, &str)) +// return NULL; +// result = PyBytes_FromString(str); +// PyMem_Free(str); +// return result; +// } + +// static PyObject * +// getargs_es_hash(PyObject *self, PyObject *args) +// { +// PyObject *arg, *result; +// const char *encoding = NULL; +// PyByteArrayObject *buffer = NULL; +// char *str = NULL; +// Py_ssize_t size; + +// if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) +// return NULL; +// if (buffer != NULL) { +// str = PyByteArray_AS_STRING(buffer); +// size = PyByteArray_GET_SIZE(buffer); +// } +// if (!PyArg_Parse(arg, "es#", encoding, &str, &size)) +// return NULL; +// result = PyBytes_FromStringAndSize(str, size); +// if (buffer == NULL) +// PyMem_Free(str); +// return result; +// } + +// static PyObject * +// getargs_et_hash(PyObject *self, PyObject *args) +// { +// PyObject *arg, *result; +// const char *encoding = NULL; +// PyByteArrayObject *buffer = NULL; +// char *str = NULL; +// Py_ssize_t size; + +// if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) +// return NULL; +// if (buffer != NULL) { +// str = PyByteArray_AS_STRING(buffer); +// size = PyByteArray_GET_SIZE(buffer); +// } +// if (!PyArg_Parse(arg, "et#", encoding, &str, &size)) +// return NULL; +// result = PyBytes_FromStringAndSize(str, size); +// if (buffer == NULL) +// PyMem_Free(str); +// return result; +// } + +// /* Test the s and z codes for PyArg_ParseTuple. +// */ +// static PyObject * +// test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// /* Unicode strings should be accepted */ +// PyObject *tuple, *obj; +// char *value; + +// tuple = PyTuple_New(1); +// if (tuple == NULL) +// return NULL; + +// obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"), +// "latin-1", NULL); +// if (obj == NULL) +// return NULL; + +// PyTuple_SET_ITEM(tuple, 0, obj); + +// /* These two blocks used to raise a TypeError: +// * "argument must be string without null bytes, not str" +// */ +// if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) { +// return NULL; +// } + +// if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) { +// return NULL; +// } + +// Py_DECREF(tuple); +// Py_RETURN_NONE; +// } + +// static PyObject * +// parse_tuple_and_keywords(PyObject *self, PyObject *args) +// { +// PyObject *sub_args; +// PyObject *sub_kwargs; +// const char *sub_format; +// PyObject *sub_keywords; + +// Py_ssize_t i, size; +// char *keywords[8 + 1]; /* space for NULL at end */ +// PyObject *o; +// PyObject *converted[8]; + +// int result; +// PyObject *return_value = NULL; + +// double buffers[8][4]; /* double ensures alignment where necessary */ + +// if (!PyArg_ParseTuple(args, "OOsO:parse_tuple_and_keywords", +// &sub_args, &sub_kwargs, +// &sub_format, &sub_keywords)) +// return NULL; + +// if (!(PyList_CheckExact(sub_keywords) || PyTuple_CheckExact(sub_keywords))) { +// PyErr_SetString(PyExc_ValueError, +// "parse_tuple_and_keywords: sub_keywords must be either list or tuple"); +// return NULL; +// } + +// memset(buffers, 0, sizeof(buffers)); +// memset(converted, 0, sizeof(converted)); +// memset(keywords, 0, sizeof(keywords)); + +// size = PySequence_Fast_GET_SIZE(sub_keywords); +// if (size > 8) { +// PyErr_SetString(PyExc_ValueError, +// "parse_tuple_and_keywords: too many keywords in sub_keywords"); +// goto exit; +// } + +// for (i = 0; i < size; i++) { +// o = PySequence_Fast_GET_ITEM(sub_keywords, i); +// if (!PyUnicode_FSConverter(o, (void *)(converted + i))) { +// PyErr_Format(PyExc_ValueError, +// "parse_tuple_and_keywords: could not convert keywords[%zd] to narrow string", i); +// goto exit; +// } +// keywords[i] = PyBytes_AS_STRING(converted[i]); +// } + +// result = PyArg_ParseTupleAndKeywords(sub_args, sub_kwargs, +// sub_format, keywords, +// buffers + 0, buffers + 1, buffers + 2, buffers + 3, +// buffers + 4, buffers + 5, buffers + 6, buffers + 7); + +// if (result) { +// return_value = Py_None; +// Py_INCREF(Py_None); +// } + +// exit: +// size = sizeof(converted) / sizeof(converted[0]); +// for (i = 0; i < size; i++) { +// Py_XDECREF(converted[i]); +// } +// return return_value; +// } + +// static volatile int x; + +// /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case +// of an error. +// */ +// static PyObject * +// test_u_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *tuple, *obj; +// Py_UNICODE *value; +// Py_ssize_t len; + +// /* issue4122: Undefined reference to _Py_ascii_whitespace on Windows */ +// /* Just use the macro and check that it compiles */ +// x = Py_UNICODE_ISSPACE(25); + +// tuple = PyTuple_New(1); +// if (tuple == NULL) +// return NULL; + +// obj = PyUnicode_Decode("test", strlen("test"), +// "ascii", NULL); +// if (obj == NULL) +// return NULL; + +// PyTuple_SET_ITEM(tuple, 0, obj); + +// value = 0; +// if (!PyArg_ParseTuple(tuple, "u:test_u_code", &value)) { +// return NULL; +// } +// if (value != PyUnicode_AS_UNICODE(obj)) +// return raiseTestError("test_u_code", +// "u code returned wrong value for u'test'"); +// value = 0; +// if (!PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len)) { +// return NULL; +// } +// if (value != PyUnicode_AS_UNICODE(obj) || +// len != PyUnicode_GET_SIZE(obj)) +// return raiseTestError("test_u_code", +// "u# code returned wrong values for u'test'"); + +// Py_DECREF(tuple); +// Py_RETURN_NONE; +// } + +// /* Test Z and Z# codes for PyArg_ParseTuple */ +// static PyObject * +// test_Z_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *tuple, *obj; +// const Py_UNICODE *value1, *value2; +// Py_ssize_t len1, len2; + +// tuple = PyTuple_New(2); +// if (tuple == NULL) +// return NULL; + +// obj = PyUnicode_FromString("test"); +// PyTuple_SET_ITEM(tuple, 0, obj); +// Py_INCREF(Py_None); +// PyTuple_SET_ITEM(tuple, 1, Py_None); + +// /* swap values on purpose */ +// value1 = NULL; +// value2 = PyUnicode_AS_UNICODE(obj); + +// /* Test Z for both values */ +// if (!PyArg_ParseTuple(tuple, "ZZ:test_Z_code", &value1, &value2)) { +// return NULL; +// } +// if (value1 != PyUnicode_AS_UNICODE(obj)) +// return raiseTestError("test_Z_code", +// "Z code returned wrong value for 'test'"); +// if (value2 != NULL) +// return raiseTestError("test_Z_code", +// "Z code returned wrong value for None"); + +// value1 = NULL; +// value2 = PyUnicode_AS_UNICODE(obj); +// len1 = -1; +// len2 = -1; + +// /* Test Z# for both values */ +// if (!PyArg_ParseTuple(tuple, "Z#Z#:test_Z_code", &value1, &len1, +// &value2, &len2)) +// { +// return NULL; +// } +// if (value1 != PyUnicode_AS_UNICODE(obj) || +// len1 != PyUnicode_GET_SIZE(obj)) +// return raiseTestError("test_Z_code", +// "Z# code returned wrong values for 'test'"); +// if (value2 != NULL || +// len2 != 0) +// return raiseTestError("test_Z_code", +// "Z# code returned wrong values for None'"); + +// Py_DECREF(tuple); +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// #if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) +// const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; +// size_t wtextlen = 1; +// const wchar_t invalid[1] = {(wchar_t)0x110000u}; +// #else +// const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu}; +// size_t wtextlen = 2; +// #endif +// PyObject *wide, *utf8; + +// wide = PyUnicode_FromWideChar(wtext, wtextlen); +// if (wide == NULL) +// return NULL; + +// utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d"); +// if (utf8 == NULL) { +// Py_DECREF(wide); +// return NULL; +// } + +// if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) { +// Py_DECREF(wide); +// Py_DECREF(utf8); +// return raiseTestError("test_widechar", +// "wide string and utf8 string " +// "have different length"); +// } +// if (PyUnicode_Compare(wide, utf8)) { +// Py_DECREF(wide); +// Py_DECREF(utf8); +// if (PyErr_Occurred()) +// return NULL; +// return raiseTestError("test_widechar", +// "wide string and utf8 string " +// "are different"); +// } + +// Py_DECREF(wide); +// Py_DECREF(utf8); + +// #if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) +// wide = PyUnicode_FromWideChar(invalid, 1); +// if (wide == NULL) +// PyErr_Clear(); +// else +// return raiseTestError("test_widechar", +// "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); + +// wide = PyUnicode_FromUnicode(invalid, 1); +// if (wide == NULL) +// PyErr_Clear(); +// else +// return raiseTestError("test_widechar", +// "PyUnicode_FromUnicode(L\"\\U00110000\", 1) didn't fail"); + +// wide = PyUnicode_FromUnicode(NULL, 1); +// if (wide == NULL) +// return NULL; +// PyUnicode_AS_UNICODE(wide)[0] = invalid[0]; +// if (_PyUnicode_Ready(wide) < 0) { +// Py_DECREF(wide); +// PyErr_Clear(); +// } +// else { +// Py_DECREF(wide); +// return raiseTestError("test_widechar", +// "PyUnicode_Ready() didn't fail"); +// } +// #endif + +// Py_RETURN_NONE; +// } + +// static PyObject * +// unicode_aswidechar(PyObject *self, PyObject *args) +// { +// PyObject *unicode, *result; +// Py_ssize_t buflen, size; +// wchar_t *buffer; + +// if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) +// return NULL; +// buffer = PyMem_New(wchar_t, buflen); +// if (buffer == NULL) +// return PyErr_NoMemory(); + +// size = PyUnicode_AsWideChar(unicode, buffer, buflen); +// if (size == -1) { +// PyMem_Free(buffer); +// return NULL; +// } + +// if (size < buflen) +// buflen = size + 1; +// else +// buflen = size; +// result = PyUnicode_FromWideChar(buffer, buflen); +// PyMem_Free(buffer); +// if (result == NULL) +// return NULL; + +// return Py_BuildValue("(Nn)", result, size); +// } + +// static PyObject * +// unicode_aswidecharstring(PyObject *self, PyObject *args) +// { +// PyObject *unicode, *result; +// Py_ssize_t size; +// wchar_t *buffer; + +// if (!PyArg_ParseTuple(args, "U", &unicode)) +// return NULL; + +// buffer = PyUnicode_AsWideCharString(unicode, &size); +// if (buffer == NULL) +// return NULL; + +// result = PyUnicode_FromWideChar(buffer, size + 1); +// PyMem_Free(buffer); +// if (result == NULL) +// return NULL; +// return Py_BuildValue("(Nn)", result, size); +// } + +// static PyObject * +// unicode_asucs4(PyObject *self, PyObject *args) +// { +// PyObject *unicode, *result; +// Py_UCS4 *buffer; +// int copy_null; +// Py_ssize_t str_len, buf_len; + +// if (!PyArg_ParseTuple(args, "Unp:unicode_asucs4", &unicode, &str_len, ©_null)) { +// return NULL; +// } + +// buf_len = str_len + 1; +// buffer = PyMem_NEW(Py_UCS4, buf_len); +// if (buffer == NULL) { +// return PyErr_NoMemory(); +// } +// memset(buffer, 0, sizeof(Py_UCS4)*buf_len); +// buffer[str_len] = 0xffffU; + +// if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) { +// PyMem_FREE(buffer); +// return NULL; +// } + +// result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len); +// PyMem_FREE(buffer); +// return result; +// } + +// static PyObject * +// unicode_findchar(PyObject *self, PyObject *args) +// { +// PyObject *str; +// int direction; +// unsigned int ch; +// Py_ssize_t result; +// Py_ssize_t start, end; + +// if (!PyArg_ParseTuple(args, "UInni:unicode_findchar", &str, &ch, +// &start, &end, &direction)) { +// return NULL; +// } + +// result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); +// if (result == -2) +// return NULL; +// else +// return PyLong_FromSsize_t(result); +// } + +// static PyObject * +// unicode_copycharacters(PyObject *self, PyObject *args) +// { +// PyObject *from, *to, *to_copy; +// Py_ssize_t from_start, to_start, how_many, copied; + +// if (!PyArg_ParseTuple(args, "UnOnn:unicode_copycharacters", &to, &to_start, +// &from, &from_start, &how_many)) { +// return NULL; +// } + +// if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to), +// PyUnicode_MAX_CHAR_VALUE(to)))) { +// return NULL; +// } +// if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) { +// Py_DECREF(to_copy); +// return NULL; +// } + +// if ((copied = PyUnicode_CopyCharacters(to_copy, to_start, from, +// from_start, how_many)) < 0) { +// Py_DECREF(to_copy); +// return NULL; +// } + +// return Py_BuildValue("(Nn)", to_copy, copied); +// } + +// static PyObject * +// unicode_encodedecimal(PyObject *self, PyObject *args) +// { +// Py_UNICODE *unicode; +// Py_ssize_t length; +// char *errors = NULL; +// PyObject *decimal; +// Py_ssize_t decimal_length, new_length; +// int res; + +// if (!PyArg_ParseTuple(args, "u#|s", &unicode, &length, &errors)) +// return NULL; + +// decimal_length = length * 7; /* len('€') */ +// decimal = PyBytes_FromStringAndSize(NULL, decimal_length); +// if (decimal == NULL) +// return NULL; + +// res = PyUnicode_EncodeDecimal(unicode, length, +// PyBytes_AS_STRING(decimal), +// errors); +// if (res < 0) { +// Py_DECREF(decimal); +// return NULL; +// } + +// new_length = strlen(PyBytes_AS_STRING(decimal)); +// assert(new_length <= decimal_length); +// res = _PyBytes_Resize(&decimal, new_length); +// if (res < 0) +// return NULL; + +// return decimal; +// } + +// static PyObject * +// unicode_transformdecimaltoascii(PyObject *self, PyObject *args) +// { +// Py_UNICODE *unicode; +// Py_ssize_t length; +// if (!PyArg_ParseTuple(args, "u#|s", &unicode, &length)) +// return NULL; +// return PyUnicode_TransformDecimalToASCII(unicode, length); +// } + +// static PyObject * +// unicode_legacy_string(PyObject *self, PyObject *args) +// { +// Py_UNICODE *data; +// Py_ssize_t len; +// PyObject *u; + +// if (!PyArg_ParseTuple(args, "u#", &data, &len)) +// return NULL; + +// u = PyUnicode_FromUnicode(NULL, len); +// if (u == NULL) +// return NULL; + +// memcpy(PyUnicode_AS_UNICODE(u), data, len * sizeof(Py_UNICODE)); + +// if (len > 0) { /* The empty string is always ready. */ +// assert(!PyUnicode_IS_READY(u)); +// } + +// return u; +// } + +// static PyObject * +// getargs_w_star(PyObject *self, PyObject *args) +// { +// Py_buffer buffer; +// PyObject *result; +// char *str; + +// if (!PyArg_ParseTuple(args, "w*:getargs_w_star", &buffer)) +// return NULL; + +// if (2 <= buffer.len) { +// str = buffer.buf; +// str[0] = '['; +// str[buffer.len-1] = ']'; +// } + +// result = PyBytes_FromStringAndSize(buffer.buf, buffer.len); +// PyBuffer_Release(&buffer); +// return result; +// } + + +// static PyObject * +// test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// /* Test that formats can begin with '|'. See issue #4720. */ +// PyObject *tuple, *dict = NULL; +// static char *kwlist[] = {NULL}; +// int result; +// tuple = PyTuple_New(0); +// if (!tuple) +// return NULL; +// if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) { +// goto done; +// } +// dict = PyDict_New(); +// if (!dict) +// goto done; +// result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse", kwlist); +// done: +// Py_DECREF(tuple); +// Py_XDECREF(dict); +// if (!result) { +// return NULL; +// } +// else { +// Py_RETURN_NONE; +// } +// } + +// static PyObject * +// codec_incrementalencoder(PyObject *self, PyObject *args) +// { +// const char *encoding, *errors = NULL; +// if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder", +// &encoding, &errors)) +// return NULL; +// return PyCodec_IncrementalEncoder(encoding, errors); +// } + +// static PyObject * +// codec_incrementaldecoder(PyObject *self, PyObject *args) +// { +// const char *encoding, *errors = NULL; +// if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder", +// &encoding, &errors)) +// return NULL; +// return PyCodec_IncrementalDecoder(encoding, errors); +// } + + +// /* Simple test of _PyLong_NumBits and _PyLong_Sign. */ +// static PyObject * +// test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// struct triple { +// long input; +// size_t nbits; +// int sign; +// } testcases[] = {{0, 0, 0}, +// {1L, 1, 1}, +// {-1L, 1, -1}, +// {2L, 2, 1}, +// {-2L, 2, -1}, +// {3L, 2, 1}, +// {-3L, 2, -1}, +// {4L, 3, 1}, +// {-4L, 3, -1}, +// {0x7fffL, 15, 1}, /* one Python int digit */ +// {-0x7fffL, 15, -1}, +// {0xffffL, 16, 1}, +// {-0xffffL, 16, -1}, +// {0xfffffffL, 28, 1}, +// {-0xfffffffL, 28, -1}}; +// size_t i; + +// for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { +// size_t nbits; +// int sign; +// PyObject *plong; + +// plong = PyLong_FromLong(testcases[i].input); +// if (plong == NULL) +// return NULL; +// nbits = _PyLong_NumBits(plong); +// sign = _PyLong_Sign(plong); + +// Py_DECREF(plong); +// if (nbits != testcases[i].nbits) +// return raiseTestError("test_long_numbits", +// "wrong result for _PyLong_NumBits"); +// if (sign != testcases[i].sign) +// return raiseTestError("test_long_numbits", +// "wrong result for _PyLong_Sign"); +// } +// Py_RETURN_NONE; +// } + +// /* Example passing NULLs to PyObject_Str(NULL). */ + +// static PyObject * +// test_null_strings(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *o1 = PyObject_Str(NULL), *o2 = PyObject_Str(NULL); +// PyObject *tuple = PyTuple_Pack(2, o1, o2); +// Py_XDECREF(o1); +// Py_XDECREF(o2); +// return tuple; +// } + +// static PyObject * +// raise_exception(PyObject *self, PyObject *args) +// { +// PyObject *exc; +// PyObject *exc_args, *v; +// int num_args, i; + +// if (!PyArg_ParseTuple(args, "Oi:raise_exception", +// &exc, &num_args)) +// return NULL; + +// exc_args = PyTuple_New(num_args); +// if (exc_args == NULL) +// return NULL; +// for (i = 0; i < num_args; ++i) { +// v = PyLong_FromLong(i); +// if (v == NULL) { +// Py_DECREF(exc_args); +// return NULL; +// } +// PyTuple_SET_ITEM(exc_args, i, v); +// } +// PyErr_SetObject(exc, exc_args); +// Py_DECREF(exc_args); +// return NULL; +// } + +// static PyObject * +// set_errno(PyObject *self, PyObject *args) +// { +// int new_errno; + +// if (!PyArg_ParseTuple(args, "i:set_errno", &new_errno)) +// return NULL; + +// errno = new_errno; +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_set_exc_info(PyObject *self, PyObject *args) +// { +// PyObject *orig_exc; +// PyObject *new_type, *new_value, *new_tb; +// PyObject *type, *value, *tb; +// if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info", +// &new_type, &new_value, &new_tb)) +// return NULL; + +// PyErr_GetExcInfo(&type, &value, &tb); + +// Py_INCREF(new_type); +// Py_INCREF(new_value); +// Py_INCREF(new_tb); +// PyErr_SetExcInfo(new_type, new_value, new_tb); + +// orig_exc = PyTuple_Pack(3, type ? type : Py_None, value ? value : Py_None, tb ? tb : Py_None); +// Py_XDECREF(type); +// Py_XDECREF(value); +// Py_XDECREF(tb); +// return orig_exc; +// } + +// static int test_run_counter = 0; + +// static PyObject * +// test_datetime_capi(PyObject *self, PyObject *args) { +// if (PyDateTimeAPI) { +// if (test_run_counter) { +// /* Probably regrtest.py -R */ +// Py_RETURN_NONE; +// } +// else { +// PyErr_SetString(PyExc_AssertionError, +// "PyDateTime_CAPI somehow initialized"); +// return NULL; +// } +// } +// test_run_counter++; +// PyDateTime_IMPORT; + +// if (PyDateTimeAPI) +// Py_RETURN_NONE; +// else +// return NULL; +// } + +// /* Functions exposing the C API type checking for testing */ +// #define MAKE_DATETIME_CHECK_FUNC(check_method, exact_method) \ +// PyObject *obj; \ +// int exact = 0; \ +// if (!PyArg_ParseTuple(args, "O|p", &obj, &exact)) { \ +// return NULL; \ +// } \ +// int rv = exact?exact_method(obj):check_method(obj); \ +// if (rv) { \ +// Py_RETURN_TRUE; \ +// } else { \ +// Py_RETURN_FALSE; \ +// } + +// static PyObject * +// datetime_check_date(PyObject *self, PyObject *args) { +// MAKE_DATETIME_CHECK_FUNC(PyDate_Check, PyDate_CheckExact) +// } + +// static PyObject * +// datetime_check_time(PyObject *self, PyObject *args) { +// MAKE_DATETIME_CHECK_FUNC(PyTime_Check, PyTime_CheckExact) +// } + +// static PyObject * +// datetime_check_datetime(PyObject *self, PyObject *args) { +// MAKE_DATETIME_CHECK_FUNC(PyDateTime_Check, PyDateTime_CheckExact) +// } + +// static PyObject * +// datetime_check_delta(PyObject *self, PyObject *args) { +// MAKE_DATETIME_CHECK_FUNC(PyDelta_Check, PyDelta_CheckExact) +// } + +// static PyObject * +// datetime_check_tzinfo(PyObject *self, PyObject *args) { +// MAKE_DATETIME_CHECK_FUNC(PyTZInfo_Check, PyTZInfo_CheckExact) +// } + + +// /* Makes three variations on timezone representing UTC-5: +// 1. timezone with offset and name from PyDateTimeAPI +// 2. timezone with offset and name from PyTimeZone_FromOffsetAndName +// 3. timezone with offset (no name) from PyTimeZone_FromOffset +// */ +// static PyObject * +// make_timezones_capi(PyObject *self, PyObject *args) { +// PyObject *offset = PyDelta_FromDSU(0, -18000, 0); +// PyObject *name = PyUnicode_FromString("EST"); + +// PyObject *est_zone_capi = PyDateTimeAPI->TimeZone_FromTimeZone(offset, name); +// PyObject *est_zone_macro = PyTimeZone_FromOffsetAndName(offset, name); +// PyObject *est_zone_macro_noname = PyTimeZone_FromOffset(offset); + +// Py_DecRef(offset); +// Py_DecRef(name); + +// PyObject *rv = PyTuple_New(3); + +// PyTuple_SET_ITEM(rv, 0, est_zone_capi); +// PyTuple_SET_ITEM(rv, 1, est_zone_macro); +// PyTuple_SET_ITEM(rv, 2, est_zone_macro_noname); + +// return rv; +// } + +// static PyObject * +// get_timezones_offset_zero(PyObject *self, PyObject *args) { +// PyObject *offset = PyDelta_FromDSU(0, 0, 0); +// PyObject *name = PyUnicode_FromString(""); + +// // These two should return the UTC singleton +// PyObject *utc_singleton_0 = PyTimeZone_FromOffset(offset); +// PyObject *utc_singleton_1 = PyTimeZone_FromOffsetAndName(offset, NULL); + +// // This one will return +00:00 zone, but not the UTC singleton +// PyObject *non_utc_zone = PyTimeZone_FromOffsetAndName(offset, name); + +// Py_DecRef(offset); +// Py_DecRef(name); + +// PyObject *rv = PyTuple_New(3); +// PyTuple_SET_ITEM(rv, 0, utc_singleton_0); +// PyTuple_SET_ITEM(rv, 1, utc_singleton_1); +// PyTuple_SET_ITEM(rv, 2, non_utc_zone); + +// return rv; +// } + +// static PyObject * +// get_timezone_utc_capi(PyObject* self, PyObject *args) { +// int macro = 0; +// if (!PyArg_ParseTuple(args, "|p", ¯o)) { +// return NULL; +// } +// if (macro) { +// Py_INCREF(PyDateTime_TimeZone_UTC); +// return PyDateTime_TimeZone_UTC; +// } else { +// Py_INCREF(PyDateTimeAPI->TimeZone_UTC); +// return PyDateTimeAPI->TimeZone_UTC; +// } +// } + +// static PyObject * +// get_date_fromdate(PyObject *self, PyObject *args) +// { +// PyObject *rv = NULL; +// int macro; +// int year, month, day; + +// if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) { +// return NULL; +// } + +// if (macro) { +// rv = PyDate_FromDate(year, month, day); +// } +// else { +// rv = PyDateTimeAPI->Date_FromDate( +// year, month, day, +// PyDateTimeAPI->DateType); +// } +// return rv; +// } + +// static PyObject * +// get_datetime_fromdateandtime(PyObject *self, PyObject *args) +// { +// PyObject *rv = NULL; +// int macro; +// int year, month, day; +// int hour, minute, second, microsecond; + +// if (!PyArg_ParseTuple(args, "piiiiiii", +// ¯o, +// &year, &month, &day, +// &hour, &minute, &second, µsecond)) { +// return NULL; +// } + +// if (macro) { +// rv = PyDateTime_FromDateAndTime( +// year, month, day, +// hour, minute, second, microsecond); +// } +// else { +// rv = PyDateTimeAPI->DateTime_FromDateAndTime( +// year, month, day, +// hour, minute, second, microsecond, +// Py_None, +// PyDateTimeAPI->DateTimeType); +// } +// return rv; +// } + +// static PyObject * +// get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args) +// { +// PyObject *rv = NULL; +// int macro; +// int year, month, day; +// int hour, minute, second, microsecond, fold; + +// if (!PyArg_ParseTuple(args, "piiiiiiii", +// ¯o, +// &year, &month, &day, +// &hour, &minute, &second, µsecond, +// &fold)) { +// return NULL; +// } + +// if (macro) { +// rv = PyDateTime_FromDateAndTimeAndFold( +// year, month, day, +// hour, minute, second, microsecond, +// fold); +// } +// else { +// rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold( +// year, month, day, +// hour, minute, second, microsecond, +// Py_None, +// fold, +// PyDateTimeAPI->DateTimeType); +// } +// return rv; +// } + +// static PyObject * +// get_time_fromtime(PyObject *self, PyObject *args) +// { +// PyObject *rv = NULL; +// int macro; +// int hour, minute, second, microsecond; + +// if (!PyArg_ParseTuple(args, "piiii", +// ¯o, +// &hour, &minute, &second, µsecond)) { +// return NULL; +// } + +// if (macro) { +// rv = PyTime_FromTime(hour, minute, second, microsecond); +// } +// else { +// rv = PyDateTimeAPI->Time_FromTime( +// hour, minute, second, microsecond, +// Py_None, +// PyDateTimeAPI->TimeType); +// } +// return rv; +// } + +// static PyObject * +// get_time_fromtimeandfold(PyObject *self, PyObject *args) +// { +// PyObject *rv = NULL; +// int macro; +// int hour, minute, second, microsecond, fold; + +// if (!PyArg_ParseTuple(args, "piiiii", +// ¯o, +// &hour, &minute, &second, µsecond, +// &fold)) { +// return NULL; +// } + +// if (macro) { +// rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold); +// } +// else { +// rv = PyDateTimeAPI->Time_FromTimeAndFold( +// hour, minute, second, microsecond, +// Py_None, +// fold, +// PyDateTimeAPI->TimeType); +// } +// return rv; +// } + +// static PyObject * +// get_delta_fromdsu(PyObject *self, PyObject *args) +// { +// PyObject *rv = NULL; +// int macro; +// int days, seconds, microseconds; + +// if (!PyArg_ParseTuple(args, "piii", +// ¯o, +// &days, &seconds, µseconds)) { +// return NULL; +// } + +// if (macro) { +// rv = PyDelta_FromDSU(days, seconds, microseconds); +// } +// else { +// rv = PyDateTimeAPI->Delta_FromDelta( +// days, seconds, microseconds, 1, +// PyDateTimeAPI->DeltaType); +// } + +// return rv; +// } + +// static PyObject * +// get_date_fromtimestamp(PyObject* self, PyObject *args) +// { +// PyObject *tsargs = NULL, *ts = NULL, *rv = NULL; +// int macro = 0; + +// if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) { +// return NULL; +// } + +// // Construct the argument tuple +// if ((tsargs = PyTuple_Pack(1, ts)) == NULL) { +// return NULL; +// } + +// // Pass along to the API function +// if (macro) { +// rv = PyDate_FromTimestamp(tsargs); +// } +// else { +// rv = PyDateTimeAPI->Date_FromTimestamp( +// (PyObject *)PyDateTimeAPI->DateType, tsargs +// ); +// } + +// Py_DECREF(tsargs); +// return rv; +// } + +// static PyObject * +// get_datetime_fromtimestamp(PyObject* self, PyObject *args) +// { +// int macro = 0; +// int usetz = 0; +// PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL; +// if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) { +// return NULL; +// } + +// // Construct the argument tuple +// if (usetz) { +// tsargs = PyTuple_Pack(2, ts, tzinfo); +// } +// else { +// tsargs = PyTuple_Pack(1, ts); +// } + +// if (tsargs == NULL) { +// return NULL; +// } + +// // Pass along to the API function +// if (macro) { +// rv = PyDateTime_FromTimestamp(tsargs); +// } +// else { +// rv = PyDateTimeAPI->DateTime_FromTimestamp( +// (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL +// ); +// } + +// Py_DECREF(tsargs); +// return rv; +// } + + +// /* test_thread_state spawns a thread of its own, and that thread releases +// * `thread_done` when it's finished. The driver code has to know when the +// * thread finishes, because the thread uses a PyObject (the callable) that +// * may go away when the driver finishes. The former lack of this explicit +// * synchronization caused rare segfaults, so rare that they were seen only +// * on a Mac buildbot (although they were possible on any box). +// */ +// static PyThread_type_lock thread_done = NULL; + +// static int +// _make_call(void *callable) +// { +// PyObject *rc; +// int success; +// PyGILState_STATE s = PyGILState_Ensure(); +// rc = _PyObject_CallNoArg((PyObject *)callable); +// success = (rc != NULL); +// Py_XDECREF(rc); +// PyGILState_Release(s); +// return success; +// } + +// /* Same thing, but releases `thread_done` when it returns. This variant +// * should be called only from threads spawned by test_thread_state(). +// */ +// static void +// _make_call_from_thread(void *callable) +// { +// _make_call(callable); +// PyThread_release_lock(thread_done); +// } + +// static PyObject * +// test_thread_state(PyObject *self, PyObject *args) +// { +// PyObject *fn; +// int success = 1; + +// if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn)) +// return NULL; + +// if (!PyCallable_Check(fn)) { +// PyErr_Format(PyExc_TypeError, "'%s' object is not callable", +// fn->ob_type->tp_name); +// return NULL; +// } + +// /* Ensure Python is set up for threading */ +// PyEval_InitThreads(); +// thread_done = PyThread_allocate_lock(); +// if (thread_done == NULL) +// return PyErr_NoMemory(); +// PyThread_acquire_lock(thread_done, 1); + +// /* Start a new thread with our callback. */ +// PyThread_start_new_thread(_make_call_from_thread, fn); +// /* Make the callback with the thread lock held by this thread */ +// success &= _make_call(fn); +// /* Do it all again, but this time with the thread-lock released */ +// Py_BEGIN_ALLOW_THREADS +// success &= _make_call(fn); +// PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ +// Py_END_ALLOW_THREADS + +// /* And once more with and without a thread +// XXX - should use a lock and work out exactly what we are trying +// to test +// */ +// Py_BEGIN_ALLOW_THREADS +// PyThread_start_new_thread(_make_call_from_thread, fn); +// success &= _make_call(fn); +// PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ +// Py_END_ALLOW_THREADS + +// /* Release lock we acquired above. This is required on HP-UX. */ +// PyThread_release_lock(thread_done); + +// PyThread_free_lock(thread_done); +// if (!success) +// return NULL; +// Py_RETURN_NONE; +// } + +// /* test Py_AddPendingCalls using threads */ +// static int _pending_callback(void *arg) +// { +// /* we assume the argument is callable object to which we own a reference */ +// PyObject *callable = (PyObject *)arg; +// PyObject *r = _PyObject_CallNoArg(callable); +// Py_DECREF(callable); +// Py_XDECREF(r); +// return r != NULL ? 0 : -1; +// } + +// /* The following requests n callbacks to _pending_callback. It can be +// * run from any python thread. +// */ +// static PyObject * +// pending_threadfunc(PyObject *self, PyObject *arg) +// { +// PyObject *callable; +// int r; +// if (PyArg_ParseTuple(arg, "O", &callable) == 0) +// return NULL; + +// /* create the reference for the callbackwhile we hold the lock */ +// Py_INCREF(callable); + +// Py_BEGIN_ALLOW_THREADS +// r = Py_AddPendingCall(&_pending_callback, callable); +// Py_END_ALLOW_THREADS + +// if (r<0) { +// Py_DECREF(callable); /* unsuccessful add, destroy the extra reference */ +// Py_RETURN_FALSE; +// } +// Py_RETURN_TRUE; +// } + +// /* Some tests of PyUnicode_FromFormat(). This needs more tests. */ +// static PyObject * +// test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *result; +// char *msg; + +// #define CHECK_1_FORMAT(FORMAT, TYPE) \ +// result = PyUnicode_FromFormat(FORMAT, (TYPE)1); \ +// if (result == NULL) \ +// return NULL; \ +// if (!_PyUnicode_EqualToASCIIString(result, "1")) { \ +// msg = FORMAT " failed at 1"; \ +// goto Fail; \ +// } \ +// Py_DECREF(result) + +// CHECK_1_FORMAT("%d", int); +// CHECK_1_FORMAT("%ld", long); +// /* The z width modifier was added in Python 2.5. */ +// CHECK_1_FORMAT("%zd", Py_ssize_t); + +// /* The u type code was added in Python 2.5. */ +// CHECK_1_FORMAT("%u", unsigned int); +// CHECK_1_FORMAT("%lu", unsigned long); +// CHECK_1_FORMAT("%zu", size_t); + +// /* "%lld" and "%llu" support added in Python 2.7. */ +// CHECK_1_FORMAT("%llu", unsigned long long); +// CHECK_1_FORMAT("%lld", long long); + +// Py_RETURN_NONE; + +// Fail: +// Py_XDECREF(result); +// return raiseTestError("test_string_from_format", msg); + +// #undef CHECK_1_FORMAT +// } + + +// static PyObject * +// test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { +// PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); +// int result; +// if (py_s == NULL) +// return NULL; +// result = PyUnicode_CompareWithASCIIString(py_s, "str"); +// Py_DECREF(py_s); +// if (!result) { +// PyErr_SetString(TestError, "Python string ending in NULL " +// "should not compare equal to c string."); +// return NULL; +// } +// Py_RETURN_NONE; +// } + +// /* This is here to provide a docstring for test_descr. */ +// static PyObject * +// test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// Py_RETURN_NONE; +// } + +// /* Test PyOS_string_to_double. */ +// static PyObject * +// test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) { +// double result; +// const char *msg; + +// #define CHECK_STRING(STR, expected) \ +// result = PyOS_string_to_double(STR, NULL, NULL); \ +// if (result == -1.0 && PyErr_Occurred()) \ +// return NULL; \ +// if (result != (double)expected) { \ +// msg = "conversion of " STR " to float failed"; \ +// goto fail; \ +// } + +// #define CHECK_INVALID(STR) \ +// result = PyOS_string_to_double(STR, NULL, NULL); \ +// if (result == -1.0 && PyErr_Occurred()) { \ +// if (PyErr_ExceptionMatches(PyExc_ValueError)) \ +// PyErr_Clear(); \ +// else \ +// return NULL; \ +// } \ +// else { \ +// msg = "conversion of " STR " didn't raise ValueError"; \ +// goto fail; \ +// } + +// CHECK_STRING("0.1", 0.1); +// CHECK_STRING("1.234", 1.234); +// CHECK_STRING("-1.35", -1.35); +// CHECK_STRING(".1e01", 1.0); +// CHECK_STRING("2.e-2", 0.02); + +// CHECK_INVALID(" 0.1"); +// CHECK_INVALID("\t\n-3"); +// CHECK_INVALID(".123 "); +// CHECK_INVALID("3\n"); +// CHECK_INVALID("123abc"); + +// Py_RETURN_NONE; +// fail: +// return raiseTestError("test_string_to_double", msg); +// #undef CHECK_STRING +// #undef CHECK_INVALID +// } + + +// /* Coverage testing of capsule objects. */ + +// static const char *capsule_name = "capsule name"; +// static char *capsule_pointer = "capsule pointer"; +// static char *capsule_context = "capsule context"; +// static const char *capsule_error = NULL; +// static int +// capsule_destructor_call_count = 0; + +// static void +// capsule_destructor(PyObject *o) { +// capsule_destructor_call_count++; +// if (PyCapsule_GetContext(o) != capsule_context) { +// capsule_error = "context did not match in destructor!"; +// } else if (PyCapsule_GetDestructor(o) != capsule_destructor) { +// capsule_error = "destructor did not match in destructor! (woah!)"; +// } else if (PyCapsule_GetName(o) != capsule_name) { +// capsule_error = "name did not match in destructor!"; +// } else if (PyCapsule_GetPointer(o, capsule_name) != capsule_pointer) { +// capsule_error = "pointer did not match in destructor!"; +// } +// } + +// typedef struct { +// char *name; +// char *module; +// char *attribute; +// } known_capsule; + +// static PyObject * +// test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *object; +// const char *error = NULL; +// void *pointer; +// void *pointer2; +// known_capsule known_capsules[] = { +// #define KNOWN_CAPSULE(module, name) { module "." name, module, name } +// KNOWN_CAPSULE("_socket", "CAPI"), +// KNOWN_CAPSULE("_curses", "_C_API"), +// KNOWN_CAPSULE("datetime", "datetime_CAPI"), +// { NULL, NULL }, +// }; +// known_capsule *known = &known_capsules[0]; + +// #define FAIL(x) { error = (x); goto exit; } + +// #define CHECK_DESTRUCTOR \ +// if (capsule_error) { \ +// FAIL(capsule_error); \ +// } \ +// else if (!capsule_destructor_call_count) { \ +// FAIL("destructor not called!"); \ +// } \ +// capsule_destructor_call_count = 0; \ + +// object = PyCapsule_New(capsule_pointer, capsule_name, capsule_destructor); +// PyCapsule_SetContext(object, capsule_context); +// capsule_destructor(object); +// CHECK_DESTRUCTOR; +// Py_DECREF(object); +// CHECK_DESTRUCTOR; + +// object = PyCapsule_New(known, "ignored", NULL); +// PyCapsule_SetPointer(object, capsule_pointer); +// PyCapsule_SetName(object, capsule_name); +// PyCapsule_SetDestructor(object, capsule_destructor); +// PyCapsule_SetContext(object, capsule_context); +// capsule_destructor(object); +// CHECK_DESTRUCTOR; +// /* intentionally access using the wrong name */ +// pointer2 = PyCapsule_GetPointer(object, "the wrong name"); +// if (!PyErr_Occurred()) { +// FAIL("PyCapsule_GetPointer should have failed but did not!"); +// } +// PyErr_Clear(); +// if (pointer2) { +// if (pointer2 == capsule_pointer) { +// FAIL("PyCapsule_GetPointer should not have" +// " returned the internal pointer!"); +// } else { +// FAIL("PyCapsule_GetPointer should have " +// "returned NULL pointer but did not!"); +// } +// } +// PyCapsule_SetDestructor(object, NULL); +// Py_DECREF(object); +// if (capsule_destructor_call_count) { +// FAIL("destructor called when it should not have been!"); +// } + +// for (known = &known_capsules[0]; known->module != NULL; known++) { +// /* yeah, ordinarily I wouldn't do this either, +// but it's fine for this test harness. +// */ +// static char buffer[256]; +// #undef FAIL +// #define FAIL(x) \ +// { \ +// sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \ +// x, known->module, known->attribute); \ +// error = buffer; \ +// goto exit; \ +// } \ + +// PyObject *module = PyImport_ImportModule(known->module); +// if (module) { +// pointer = PyCapsule_Import(known->name, 0); +// if (!pointer) { +// Py_DECREF(module); +// FAIL("PyCapsule_GetPointer returned NULL unexpectedly!"); +// } +// object = PyObject_GetAttrString(module, known->attribute); +// if (!object) { +// Py_DECREF(module); +// return NULL; +// } +// pointer2 = PyCapsule_GetPointer(object, +// "weebles wobble but they don't fall down"); +// if (!PyErr_Occurred()) { +// Py_DECREF(object); +// Py_DECREF(module); +// FAIL("PyCapsule_GetPointer should have failed but did not!"); +// } +// PyErr_Clear(); +// if (pointer2) { +// Py_DECREF(module); +// Py_DECREF(object); +// if (pointer2 == pointer) { +// FAIL("PyCapsule_GetPointer should not have" +// " returned its internal pointer!"); +// } else { +// FAIL("PyCapsule_GetPointer should have" +// " returned NULL pointer but did not!"); +// } +// } +// Py_DECREF(object); +// Py_DECREF(module); +// } +// else +// PyErr_Clear(); +// } + +// exit: +// if (error) { +// return raiseTestError("test_capsule", error); +// } +// Py_RETURN_NONE; +// #undef FAIL +// } + +// #ifdef HAVE_GETTIMEOFDAY +// /* Profiling of integer performance */ +// static void print_delta(int test, struct timeval *s, struct timeval *e) +// { +// e->tv_sec -= s->tv_sec; +// e->tv_usec -= s->tv_usec; +// if (e->tv_usec < 0) { +// e->tv_sec -=1; +// e->tv_usec += 1000000; +// } +// printf("Test %d: %d.%06ds\n", test, (int)e->tv_sec, (int)e->tv_usec); +// } + +// static PyObject * +// profile_int(PyObject *self, PyObject* args) +// { +// int i, k; +// struct timeval start, stop; +// PyObject *single, **multiple, *op1, *result; + +// /* Test 1: Allocate and immediately deallocate +// many small integers */ +// gettimeofday(&start, NULL); +// for(k=0; k < 20000; k++) +// for(i=0; i < 1000; i++) { +// single = PyLong_FromLong(i); +// Py_DECREF(single); +// } +// gettimeofday(&stop, NULL); +// print_delta(1, &start, &stop); + +// /* Test 2: Allocate and immediately deallocate +// many large integers */ +// gettimeofday(&start, NULL); +// for(k=0; k < 20000; k++) +// for(i=0; i < 1000; i++) { +// single = PyLong_FromLong(i+1000000); +// Py_DECREF(single); +// } +// gettimeofday(&stop, NULL); +// print_delta(2, &start, &stop); + +// /* Test 3: Allocate a few integers, then release +// them all simultaneously. */ +// multiple = malloc(sizeof(PyObject*) * 1000); +// if (multiple == NULL) +// return PyErr_NoMemory(); +// gettimeofday(&start, NULL); +// for(k=0; k < 20000; k++) { +// for(i=0; i < 1000; i++) { +// multiple[i] = PyLong_FromLong(i+1000000); +// } +// for(i=0; i < 1000; i++) { +// Py_DECREF(multiple[i]); +// } +// } +// gettimeofday(&stop, NULL); +// print_delta(3, &start, &stop); +// free(multiple); + +// /* Test 4: Allocate many integers, then release +// them all simultaneously. */ +// multiple = malloc(sizeof(PyObject*) * 1000000); +// if (multiple == NULL) +// return PyErr_NoMemory(); +// gettimeofday(&start, NULL); +// for(k=0; k < 20; k++) { +// for(i=0; i < 1000000; i++) { +// multiple[i] = PyLong_FromLong(i+1000000); +// } +// for(i=0; i < 1000000; i++) { +// Py_DECREF(multiple[i]); +// } +// } +// gettimeofday(&stop, NULL); +// print_delta(4, &start, &stop); +// free(multiple); + +// /* Test 5: Allocate many integers < 32000 */ +// multiple = malloc(sizeof(PyObject*) * 1000000); +// if (multiple == NULL) +// return PyErr_NoMemory(); +// gettimeofday(&start, NULL); +// for(k=0; k < 10; k++) { +// for(i=0; i < 1000000; i++) { +// multiple[i] = PyLong_FromLong(i+1000); +// } +// for(i=0; i < 1000000; i++) { +// Py_DECREF(multiple[i]); +// } +// } +// gettimeofday(&stop, NULL); +// print_delta(5, &start, &stop); +// free(multiple); + +// /* Test 6: Perform small int addition */ +// op1 = PyLong_FromLong(1); +// gettimeofday(&start, NULL); +// for(i=0; i < 10000000; i++) { +// result = PyNumber_Add(op1, op1); +// Py_DECREF(result); +// } +// gettimeofday(&stop, NULL); +// Py_DECREF(op1); +// print_delta(6, &start, &stop); + +// /* Test 7: Perform medium int addition */ +// op1 = PyLong_FromLong(1000); +// if (op1 == NULL) +// return NULL; +// gettimeofday(&start, NULL); +// for(i=0; i < 10000000; i++) { +// result = PyNumber_Add(op1, op1); +// Py_XDECREF(result); +// } +// gettimeofday(&stop, NULL); +// Py_DECREF(op1); +// print_delta(7, &start, &stop); + +// Py_RETURN_NONE; +// } +// #endif + +// /* To test the format of tracebacks as printed out. */ +// static PyObject * +// traceback_print(PyObject *self, PyObject *args) +// { +// PyObject *file; +// PyObject *traceback; +// int result; + +// if (!PyArg_ParseTuple(args, "OO:traceback_print", +// &traceback, &file)) +// return NULL; + +// result = PyTraceBack_Print(traceback, file); +// if (result < 0) +// return NULL; +// Py_RETURN_NONE; +// } + +// /* To test the format of exceptions as printed out. */ +// static PyObject * +// exception_print(PyObject *self, PyObject *args) +// { +// PyObject *value; +// PyObject *tb; + +// if (!PyArg_ParseTuple(args, "O:exception_print", +// &value)) +// return NULL; +// if (!PyExceptionInstance_Check(value)) { +// PyErr_Format(PyExc_TypeError, "an exception instance is required"); +// return NULL; +// } + +// tb = PyException_GetTraceback(value); +// PyErr_Display((PyObject *) Py_TYPE(value), value, tb); +// Py_XDECREF(tb); + +// Py_RETURN_NONE; +// } + + + + +// /* reliably raise a MemoryError */ +// static PyObject * +// raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyErr_NoMemory(); +// return NULL; +// } + +// /* Issue 6012 */ +// static PyObject *str1, *str2; +// static int +// failing_converter(PyObject *obj, void *arg) +// { +// /* Clone str1, then let the conversion fail. */ +// assert(str1); +// str2 = str1; +// Py_INCREF(str2); +// return 0; +// } +// static PyObject* +// argparsing(PyObject *o, PyObject *args) +// { +// PyObject *res; +// str1 = str2 = NULL; +// if (!PyArg_ParseTuple(args, "O&O&", +// PyUnicode_FSConverter, &str1, +// failing_converter, &str2)) { +// if (!str2) +// /* argument converter not called? */ +// return NULL; +// /* Should be 1 */ +// res = PyLong_FromSsize_t(Py_REFCNT(str2)); +// Py_DECREF(str2); +// PyErr_Clear(); +// return res; +// } +// Py_RETURN_NONE; +// } + +// /* To test that the result of PyCode_NewEmpty has the right members. */ +// static PyObject * +// code_newempty(PyObject *self, PyObject *args) +// { +// const char *filename; +// const char *funcname; +// int firstlineno; + +// if (!PyArg_ParseTuple(args, "ssi:code_newempty", +// &filename, &funcname, &firstlineno)) +// return NULL; + +// return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno); +// } + +// /* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). +// Run via Lib/test/test_exceptions.py */ +// static PyObject * +// make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// const char *name; +// const char *doc = NULL; +// PyObject *base = NULL; +// PyObject *dict = NULL; + +// static char *kwlist[] = {"name", "doc", "base", "dict", NULL}; + +// if (!PyArg_ParseTupleAndKeywords(args, kwargs, +// "s|sOO:make_exception_with_doc", kwlist, +// &name, &doc, &base, &dict)) +// return NULL; + +// return PyErr_NewExceptionWithDoc(name, doc, base, dict); +// } + +// static PyObject * +// make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// Py_buffer info; +// if (PyBuffer_FillInfo(&info, NULL, NULL, 1, 1, PyBUF_FULL_RO) < 0) +// return NULL; +// return PyMemoryView_FromBuffer(&info); +// } + +// static PyObject * +// test_from_contiguous(PyObject* self, PyObject *Py_UNUSED(ignored)) +// { +// int data[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; +// int init[5] = {0, 1, 2, 3, 4}; +// Py_ssize_t itemsize = sizeof(int); +// Py_ssize_t shape = 5; +// Py_ssize_t strides = 2 * itemsize; +// Py_buffer view = { +// data, +// NULL, +// 5 * itemsize, +// itemsize, +// 1, +// 1, +// NULL, +// &shape, +// &strides, +// NULL, +// NULL +// }; +// int *ptr; +// int i; + +// PyBuffer_FromContiguous(&view, init, view.len, 'C'); +// ptr = view.buf; +// for (i = 0; i < 5; i++) { +// if (ptr[2*i] != i) { +// PyErr_SetString(TestError, +// "test_from_contiguous: incorrect result"); +// return NULL; +// } +// } + +// view.buf = &data[8]; +// view.strides[0] = -2 * itemsize; + +// PyBuffer_FromContiguous(&view, init, view.len, 'C'); +// ptr = view.buf; +// for (i = 0; i < 5; i++) { +// if (*(ptr-2*i) != i) { +// PyErr_SetString(TestError, +// "test_from_contiguous: incorrect result"); +// return NULL; +// } +// } + +// Py_RETURN_NONE; +// } + +// #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) +// extern PyTypeObject _PyBytesIOBuffer_Type; + +// static PyObject * +// test_pep3118_obsolete_write_locks(PyObject* self, PyObject *Py_UNUSED(ignored)) +// { +// PyTypeObject *type = &_PyBytesIOBuffer_Type; +// PyObject *b; +// char *dummy[1]; +// int ret, match; + +// /* PyBuffer_FillInfo() */ +// ret = PyBuffer_FillInfo(NULL, NULL, dummy, 1, 0, PyBUF_SIMPLE); +// match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); +// PyErr_Clear(); +// if (ret != -1 || match == 0) +// goto error; + +// /* bytesiobuf_getbuffer() */ +// b = type->tp_alloc(type, 0); +// if (b == NULL) { +// return NULL; +// } + +// ret = PyObject_GetBuffer(b, NULL, PyBUF_SIMPLE); +// Py_DECREF(b); +// match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); +// PyErr_Clear(); +// if (ret != -1 || match == 0) +// goto error; + +// Py_RETURN_NONE; + +// error: +// PyErr_SetString(TestError, +// "test_pep3118_obsolete_write_locks: failure"); +// return NULL; +// } +// #endif + +// /* This tests functions that historically supported write locks. It is +// wrong to call getbuffer() with view==NULL and a compliant getbufferproc +// is entitled to segfault in that case. */ +// static PyObject * +// getbuffer_with_null_view(PyObject* self, PyObject *obj) +// { +// if (PyObject_GetBuffer(obj, NULL, PyBUF_SIMPLE) < 0) +// return NULL; + +// Py_RETURN_NONE; +// } + +// /* Test that the fatal error from not having a current thread doesn't +// cause an infinite loop. Run via Lib/test/test_capi.py */ +// static PyObject * +// crash_no_current_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// Py_BEGIN_ALLOW_THREADS +// /* Using PyThreadState_Get() directly allows the test to pass in +// !pydebug mode. However, the test only actually tests anything +// in pydebug mode, since that's where the infinite loop was in +// the first place. */ +// PyThreadState_Get(); +// Py_END_ALLOW_THREADS +// return NULL; +// } + +// /* To run some code in a sub-interpreter. */ +// static PyObject * +// run_in_subinterp(PyObject *self, PyObject *args) +// { +// const char *code; +// int r; +// PyThreadState *substate, *mainstate; +// /* only initialise 'cflags.cf_flags' to test backwards compatibility */ +// PyCompilerFlags cflags = {0}; + +// if (!PyArg_ParseTuple(args, "s:run_in_subinterp", +// &code)) +// return NULL; + +// mainstate = PyThreadState_Get(); + +// PyThreadState_Swap(NULL); + +// substate = Py_NewInterpreter(); +// if (substate == NULL) { +// /* Since no new thread state was created, there is no exception to +// propagate; raise a fresh one after swapping in the old thread +// state. */ +// PyThreadState_Swap(mainstate); +// PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed"); +// return NULL; +// } +// r = PyRun_SimpleStringFlags(code, &cflags); +// Py_EndInterpreter(substate); + +// PyThreadState_Swap(mainstate); + +// return PyLong_FromLong(r); +// } + +// static int +// check_time_rounding(int round) +// { +// if (round != _PyTime_ROUND_FLOOR +// && round != _PyTime_ROUND_CEILING +// && round != _PyTime_ROUND_HALF_EVEN +// && round != _PyTime_ROUND_UP) { +// PyErr_SetString(PyExc_ValueError, "invalid rounding"); +// return -1; +// } +// return 0; +// } + +// static PyObject * +// test_pytime_object_to_time_t(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// time_t sec; +// int round; +// if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_time_t", &obj, &round)) +// return NULL; +// if (check_time_rounding(round) < 0) +// return NULL; +// if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) +// return NULL; +// return _PyLong_FromTime_t(sec); +// } + +// static PyObject * +// test_pytime_object_to_timeval(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// time_t sec; +// long usec; +// int round; +// if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timeval", &obj, &round)) +// return NULL; +// if (check_time_rounding(round) < 0) +// return NULL; +// if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) +// return NULL; +// return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); +// } + +// static PyObject * +// test_pytime_object_to_timespec(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// time_t sec; +// long nsec; +// int round; +// if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timespec", &obj, &round)) +// return NULL; +// if (check_time_rounding(round) < 0) +// return NULL; +// if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) +// return NULL; +// return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); +// } + +// static void +// slot_tp_del(PyObject *self) +// { +// _Py_IDENTIFIER(__tp_del__); +// PyObject *del, *res; +// PyObject *error_type, *error_value, *error_traceback; + +// /* Temporarily resurrect the object. */ +// assert(self->ob_refcnt == 0); +// self->ob_refcnt = 1; + +// /* Save the current exception, if any. */ +// PyErr_Fetch(&error_type, &error_value, &error_traceback); + +// /* Execute __del__ method, if any. */ +// del = _PyObject_LookupSpecial(self, &PyId___tp_del__); +// if (del != NULL) { +// res = _PyObject_CallNoArg(del); +// if (res == NULL) +// PyErr_WriteUnraisable(del); +// else +// Py_DECREF(res); +// Py_DECREF(del); +// } + +// /* Restore the saved exception. */ +// PyErr_Restore(error_type, error_value, error_traceback); + +// /* Undo the temporary resurrection; can't use DECREF here, it would +// * cause a recursive call. +// */ +// assert(self->ob_refcnt > 0); +// if (--self->ob_refcnt == 0) +// return; /* this is the normal path out */ + +// /* __del__ resurrected it! Make it look like the original Py_DECREF +// * never happened. +// */ +// { +// Py_ssize_t refcnt = self->ob_refcnt; +// _Py_NewReference(self); +// self->ob_refcnt = refcnt; +// } +// assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); +// /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so +// * we need to undo that. */ +// _Py_DEC_REFTOTAL; +// /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object +// * chain, so no more to do there. +// * If COUNT_ALLOCS, the original decref bumped tp_frees, and +// * _Py_NewReference bumped tp_allocs: both of those need to be +// * undone. +// */ +// #ifdef COUNT_ALLOCS +// --Py_TYPE(self)->tp_frees; +// --Py_TYPE(self)->tp_allocs; +// #endif +// } + +// static PyObject * +// with_tp_del(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// PyTypeObject *tp; + +// if (!PyArg_ParseTuple(args, "O:with_tp_del", &obj)) +// return NULL; +// tp = (PyTypeObject *) obj; +// if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { +// PyErr_Format(PyExc_TypeError, +// "heap type expected, got %R", obj); +// return NULL; +// } +// tp->tp_del = slot_tp_del; +// Py_INCREF(obj); +// return obj; +// } + +// static PyObject * +// without_gc(PyObject *Py_UNUSED(self), PyObject *obj) +// { +// PyTypeObject *tp = (PyTypeObject*)obj; +// if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { +// return PyErr_Format(PyExc_TypeError, "heap type expected, got %R", obj); +// } +// if (PyType_IS_GC(tp)) { +// // Don't try this at home, kids: +// tp->tp_flags -= Py_TPFLAGS_HAVE_GC; +// tp->tp_free = PyObject_Del; +// tp->tp_traverse = NULL; +// tp->tp_clear = NULL; +// } +// assert(!PyType_IS_GC(tp)); +// Py_INCREF(obj); +// return obj; +// } + +// static PyMethodDef ml; + +// static PyObject * +// create_cfunction(PyObject *self, PyObject *args) +// { +// return PyCFunction_NewEx(&ml, self, NULL); +// } + +// static PyMethodDef ml = { +// "create_cfunction", +// create_cfunction, +// METH_NOARGS, +// NULL +// }; + +// static PyObject * +// _test_incref(PyObject *ob) +// { +// Py_INCREF(ob); +// return ob; +// } + +// static PyObject * +// test_xincref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *obj = PyLong_FromLong(0); +// Py_XINCREF(_test_incref(obj)); +// Py_DECREF(obj); +// Py_DECREF(obj); +// Py_DECREF(obj); +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_incref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *obj = PyLong_FromLong(0); +// Py_INCREF(_test_incref(obj)); +// Py_DECREF(obj); +// Py_DECREF(obj); +// Py_DECREF(obj); +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_xdecref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) +// { +// Py_XDECREF(PyLong_FromLong(0)); +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_decref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) +// { +// Py_DECREF(PyLong_FromLong(0)); +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_structseq_newtype_doesnt_leak(PyObject *Py_UNUSED(self), +// PyObject *Py_UNUSED(args)) +// { +// PyStructSequence_Desc descr; +// PyStructSequence_Field descr_fields[3]; + +// descr_fields[0] = (PyStructSequence_Field){"foo", "foo value"}; +// descr_fields[1] = (PyStructSequence_Field){NULL, "some hidden value"}; +// descr_fields[2] = (PyStructSequence_Field){0, NULL}; + +// descr.name = "_testcapi.test_descr"; +// descr.doc = "This is used to test for memory leaks in NewType"; +// descr.fields = descr_fields; +// descr.n_in_sequence = 1; + +// PyTypeObject* structseq_type = PyStructSequence_NewType(&descr); +// assert(structseq_type != NULL); +// assert(PyType_Check(structseq_type)); +// assert(PyType_FastSubclass(structseq_type, Py_TPFLAGS_TUPLE_SUBCLASS)); +// Py_DECREF(structseq_type); + +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_incref_decref_API(PyObject *ob, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *obj = PyLong_FromLong(0); +// Py_IncRef(obj); +// Py_DecRef(obj); +// Py_DecRef(obj); +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// void *ptr; + +// ptr = PyMem_RawMalloc(0); +// if (ptr == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "PyMem_RawMalloc(0) returns NULL"); +// return NULL; +// } +// PyMem_RawFree(ptr); + +// ptr = PyMem_RawCalloc(0, 0); +// if (ptr == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "PyMem_RawCalloc(0, 0) returns NULL"); +// return NULL; +// } +// PyMem_RawFree(ptr); + +// ptr = PyMem_Malloc(0); +// if (ptr == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "PyMem_Malloc(0) returns NULL"); +// return NULL; +// } +// PyMem_Free(ptr); + +// ptr = PyMem_Calloc(0, 0); +// if (ptr == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "PyMem_Calloc(0, 0) returns NULL"); +// return NULL; +// } +// PyMem_Free(ptr); + +// ptr = PyObject_Malloc(0); +// if (ptr == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "PyObject_Malloc(0) returns NULL"); +// return NULL; +// } +// PyObject_Free(ptr); + +// ptr = PyObject_Calloc(0, 0); +// if (ptr == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "PyObject_Calloc(0, 0) returns NULL"); +// return NULL; +// } +// PyObject_Free(ptr); + +// Py_RETURN_NONE; +// } + +// typedef struct { +// PyMemAllocatorEx alloc; + +// size_t malloc_size; +// size_t calloc_nelem; +// size_t calloc_elsize; +// void *realloc_ptr; +// size_t realloc_new_size; +// void *free_ptr; +// void *ctx; +// } alloc_hook_t; + +// static void* hook_malloc(void* ctx, size_t size) +// { +// alloc_hook_t *hook = (alloc_hook_t *)ctx; +// hook->ctx = ctx; +// hook->malloc_size = size; +// return hook->alloc.malloc(hook->alloc.ctx, size); +// } + +// static void* hook_calloc(void* ctx, size_t nelem, size_t elsize) +// { +// alloc_hook_t *hook = (alloc_hook_t *)ctx; +// hook->ctx = ctx; +// hook->calloc_nelem = nelem; +// hook->calloc_elsize = elsize; +// return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); +// } + +// static void* hook_realloc(void* ctx, void* ptr, size_t new_size) +// { +// alloc_hook_t *hook = (alloc_hook_t *)ctx; +// hook->ctx = ctx; +// hook->realloc_ptr = ptr; +// hook->realloc_new_size = new_size; +// return hook->alloc.realloc(hook->alloc.ctx, ptr, new_size); +// } + +// static void hook_free(void *ctx, void *ptr) +// { +// alloc_hook_t *hook = (alloc_hook_t *)ctx; +// hook->ctx = ctx; +// hook->free_ptr = ptr; +// hook->alloc.free(hook->alloc.ctx, ptr); +// } + +// static PyObject * +// test_setallocators(PyMemAllocatorDomain domain) +// { +// PyObject *res = NULL; +// const char *error_msg; +// alloc_hook_t hook; +// PyMemAllocatorEx alloc; +// size_t size, size2, nelem, elsize; +// void *ptr, *ptr2; + +// memset(&hook, 0, sizeof(hook)); + +// alloc.ctx = &hook; +// alloc.malloc = &hook_malloc; +// alloc.calloc = &hook_calloc; +// alloc.realloc = &hook_realloc; +// alloc.free = &hook_free; +// PyMem_GetAllocator(domain, &hook.alloc); +// PyMem_SetAllocator(domain, &alloc); + +// /* malloc, realloc, free */ +// size = 42; +// hook.ctx = NULL; +// switch(domain) +// { +// case PYMEM_DOMAIN_RAW: ptr = PyMem_RawMalloc(size); break; +// case PYMEM_DOMAIN_MEM: ptr = PyMem_Malloc(size); break; +// case PYMEM_DOMAIN_OBJ: ptr = PyObject_Malloc(size); break; +// default: ptr = NULL; break; +// } + +// #define CHECK_CTX(FUNC) \ +// if (hook.ctx != &hook) { \ +// error_msg = FUNC " wrong context"; \ +// goto fail; \ +// } \ +// hook.ctx = NULL; /* reset for next check */ + +// if (ptr == NULL) { +// error_msg = "malloc failed"; +// goto fail; +// } +// CHECK_CTX("malloc"); +// if (hook.malloc_size != size) { +// error_msg = "malloc invalid size"; +// goto fail; +// } + +// size2 = 200; +// switch(domain) +// { +// case PYMEM_DOMAIN_RAW: ptr2 = PyMem_RawRealloc(ptr, size2); break; +// case PYMEM_DOMAIN_MEM: ptr2 = PyMem_Realloc(ptr, size2); break; +// case PYMEM_DOMAIN_OBJ: ptr2 = PyObject_Realloc(ptr, size2); break; +// default: ptr2 = NULL; break; +// } + +// if (ptr2 == NULL) { +// error_msg = "realloc failed"; +// goto fail; +// } +// CHECK_CTX("realloc"); +// if (hook.realloc_ptr != ptr +// || hook.realloc_new_size != size2) { +// error_msg = "realloc invalid parameters"; +// goto fail; +// } + +// switch(domain) +// { +// case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr2); break; +// case PYMEM_DOMAIN_MEM: PyMem_Free(ptr2); break; +// case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr2); break; +// } + +// CHECK_CTX("free"); +// if (hook.free_ptr != ptr2) { +// error_msg = "free invalid pointer"; +// goto fail; +// } + +// /* calloc, free */ +// nelem = 2; +// elsize = 5; +// switch(domain) +// { +// case PYMEM_DOMAIN_RAW: ptr = PyMem_RawCalloc(nelem, elsize); break; +// case PYMEM_DOMAIN_MEM: ptr = PyMem_Calloc(nelem, elsize); break; +// case PYMEM_DOMAIN_OBJ: ptr = PyObject_Calloc(nelem, elsize); break; +// default: ptr = NULL; break; +// } + +// if (ptr == NULL) { +// error_msg = "calloc failed"; +// goto fail; +// } +// CHECK_CTX("calloc"); +// if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { +// error_msg = "calloc invalid nelem or elsize"; +// goto fail; +// } + +// hook.free_ptr = NULL; +// switch(domain) +// { +// case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr); break; +// case PYMEM_DOMAIN_MEM: PyMem_Free(ptr); break; +// case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr); break; +// } + +// CHECK_CTX("calloc free"); +// if (hook.free_ptr != ptr) { +// error_msg = "calloc free invalid pointer"; +// goto fail; +// } + +// Py_INCREF(Py_None); +// res = Py_None; +// goto finally; + +// fail: +// PyErr_SetString(PyExc_RuntimeError, error_msg); + +// finally: +// PyMem_SetAllocator(domain, &hook.alloc); +// return res; + +// #undef CHECK_CTX +// } + +// static PyObject * +// test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// return test_setallocators(PYMEM_DOMAIN_RAW); +// } + +// static PyObject * +// test_pymem_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// return test_setallocators(PYMEM_DOMAIN_MEM); +// } + +// static PyObject * +// test_pyobject_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// return test_setallocators(PYMEM_DOMAIN_OBJ); +// } + +// /* Most part of the following code is inherited from the pyfailmalloc project +// * written by Victor Stinner. */ +// static struct { +// int installed; +// PyMemAllocatorEx raw; +// PyMemAllocatorEx mem; +// PyMemAllocatorEx obj; +// } FmHook; + +// static struct { +// int start; +// int stop; +// Py_ssize_t count; +// } FmData; + +// static int +// fm_nomemory(void) +// { +// FmData.count++; +// if (FmData.count > FmData.start && +// (FmData.stop <= 0 || FmData.count <= FmData.stop)) { +// return 1; +// } +// return 0; +// } + +// static void * +// hook_fmalloc(void *ctx, size_t size) +// { +// PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; +// if (fm_nomemory()) { +// return NULL; +// } +// return alloc->malloc(alloc->ctx, size); +// } + +// static void * +// hook_fcalloc(void *ctx, size_t nelem, size_t elsize) +// { +// PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; +// if (fm_nomemory()) { +// return NULL; +// } +// return alloc->calloc(alloc->ctx, nelem, elsize); +// } + +// static void * +// hook_frealloc(void *ctx, void *ptr, size_t new_size) +// { +// PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; +// if (fm_nomemory()) { +// return NULL; +// } +// return alloc->realloc(alloc->ctx, ptr, new_size); +// } + +// static void +// hook_ffree(void *ctx, void *ptr) +// { +// PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; +// alloc->free(alloc->ctx, ptr); +// } + +// static void +// fm_setup_hooks(void) +// { +// PyMemAllocatorEx alloc; + +// if (FmHook.installed) { +// return; +// } +// FmHook.installed = 1; + +// alloc.malloc = hook_fmalloc; +// alloc.calloc = hook_fcalloc; +// alloc.realloc = hook_frealloc; +// alloc.free = hook_ffree; +// PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw); +// PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem); +// PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj); + +// alloc.ctx = &FmHook.raw; +// PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); + +// alloc.ctx = &FmHook.mem; +// PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); + +// alloc.ctx = &FmHook.obj; +// PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); +// } + +// static void +// fm_remove_hooks(void) +// { +// if (FmHook.installed) { +// FmHook.installed = 0; +// PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw); +// PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem); +// PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj); +// } +// } + +// static PyObject* +// set_nomemory(PyObject *self, PyObject *args) +// { +// /* Memory allocation fails after 'start' allocation requests, and until +// * 'stop' allocation requests except when 'stop' is negative or equal +// * to 0 (default) in which case allocation failures never stop. */ +// FmData.count = 0; +// FmData.stop = 0; +// if (!PyArg_ParseTuple(args, "i|i", &FmData.start, &FmData.stop)) { +// return NULL; +// } +// fm_setup_hooks(); +// Py_RETURN_NONE; +// } + +// static PyObject* +// remove_mem_hooks(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// fm_remove_hooks(); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(docstring_empty, +// "" +// ); + +// PyDoc_STRVAR(docstring_no_signature, +// "This docstring has no signature." +// ); + +// PyDoc_STRVAR(docstring_with_invalid_signature, +// "docstring_with_invalid_signature($module, /, boo)\n" +// "\n" +// "This docstring has an invalid signature." +// ); + +// PyDoc_STRVAR(docstring_with_invalid_signature2, +// "docstring_with_invalid_signature2($module, /, boo)\n" +// "\n" +// "--\n" +// "\n" +// "This docstring also has an invalid signature." +// ); + +// PyDoc_STRVAR(docstring_with_signature, +// "docstring_with_signature($module, /, sig)\n" +// "--\n" +// "\n" +// "This docstring has a valid signature." +// ); + +// PyDoc_STRVAR(docstring_with_signature_but_no_doc, +// "docstring_with_signature_but_no_doc($module, /, sig)\n" +// "--\n" +// "\n" +// ); + +// PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, +// "docstring_with_signature_and_extra_newlines($module, /, parameter)\n" +// "--\n" +// "\n" +// "\n" +// "This docstring has a valid signature and some extra newlines." +// ); + +// PyDoc_STRVAR(docstring_with_signature_with_defaults, +// "docstring_with_signature_with_defaults(module, s='avocado',\n" +// " b=b'bytes', d=3.14, i=35, n=None, t=True, f=False,\n" +// " local=the_number_three, sys=sys.maxsize,\n" +// " exp=sys.maxsize - 1)\n" +// "--\n" +// "\n" +// "\n" +// "\n" +// "This docstring has a valid signature with parameters,\n" +// "and the parameters take defaults of varying types." +// ); + +// typedef struct { +// PyThread_type_lock start_event; +// PyThread_type_lock exit_event; +// PyObject *callback; +// } test_c_thread_t; + +// static void +// temporary_c_thread(void *data) +// { +// test_c_thread_t *test_c_thread = data; +// PyGILState_STATE state; +// PyObject *res; + +// PyThread_release_lock(test_c_thread->start_event); + +// /* Allocate a Python thread state for this thread */ +// state = PyGILState_Ensure(); + +// res = _PyObject_CallNoArg(test_c_thread->callback); +// Py_CLEAR(test_c_thread->callback); + +// if (res == NULL) { +// PyErr_Print(); +// } +// else { +// Py_DECREF(res); +// } + +// /* Destroy the Python thread state for this thread */ +// PyGILState_Release(state); + +// PyThread_release_lock(test_c_thread->exit_event); + +// PyThread_exit_thread(); +// } + +// static PyObject * +// call_in_temporary_c_thread(PyObject *self, PyObject *callback) +// { +// PyObject *res = NULL; +// test_c_thread_t test_c_thread; +// long thread; + +// PyEval_InitThreads(); + +// test_c_thread.start_event = PyThread_allocate_lock(); +// test_c_thread.exit_event = PyThread_allocate_lock(); +// test_c_thread.callback = NULL; +// if (!test_c_thread.start_event || !test_c_thread.exit_event) { +// PyErr_SetString(PyExc_RuntimeError, "could not allocate lock"); +// goto exit; +// } + +// Py_INCREF(callback); +// test_c_thread.callback = callback; + +// PyThread_acquire_lock(test_c_thread.start_event, 1); +// PyThread_acquire_lock(test_c_thread.exit_event, 1); + +// thread = PyThread_start_new_thread(temporary_c_thread, &test_c_thread); +// if (thread == -1) { +// PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); +// PyThread_release_lock(test_c_thread.start_event); +// PyThread_release_lock(test_c_thread.exit_event); +// goto exit; +// } + +// PyThread_acquire_lock(test_c_thread.start_event, 1); +// PyThread_release_lock(test_c_thread.start_event); + +// Py_BEGIN_ALLOW_THREADS +// PyThread_acquire_lock(test_c_thread.exit_event, 1); +// PyThread_release_lock(test_c_thread.exit_event); +// Py_END_ALLOW_THREADS + +// Py_INCREF(Py_None); +// res = Py_None; + +// exit: +// Py_CLEAR(test_c_thread.callback); +// if (test_c_thread.start_event) +// PyThread_free_lock(test_c_thread.start_event); +// if (test_c_thread.exit_event) +// PyThread_free_lock(test_c_thread.exit_event); +// return res; +// } + +// /* marshal */ + +// static PyObject* +// pymarshal_write_long_to_file(PyObject* self, PyObject *args) +// { +// long value; +// char *filename; +// int version; +// FILE *fp; + +// if (!PyArg_ParseTuple(args, "lsi:pymarshal_write_long_to_file", +// &value, &filename, &version)) +// return NULL; + +// fp = fopen(filename, "wb"); +// if (fp == NULL) { +// PyErr_SetFromErrno(PyExc_OSError); +// return NULL; +// } + +// PyMarshal_WriteLongToFile(value, fp, version); + +// fclose(fp); +// if (PyErr_Occurred()) +// return NULL; +// Py_RETURN_NONE; +// } + +// static PyObject* +// pymarshal_write_object_to_file(PyObject* self, PyObject *args) +// { +// PyObject *obj; +// char *filename; +// int version; +// FILE *fp; + +// if (!PyArg_ParseTuple(args, "Osi:pymarshal_write_object_to_file", +// &obj, &filename, &version)) +// return NULL; + +// fp = fopen(filename, "wb"); +// if (fp == NULL) { +// PyErr_SetFromErrno(PyExc_OSError); +// return NULL; +// } + +// PyMarshal_WriteObjectToFile(obj, fp, version); + +// fclose(fp); +// if (PyErr_Occurred()) +// return NULL; +// Py_RETURN_NONE; +// } + +// static PyObject* +// pymarshal_read_short_from_file(PyObject* self, PyObject *args) +// { +// int value; +// long pos; +// char *filename; +// FILE *fp; + +// if (!PyArg_ParseTuple(args, "s:pymarshal_read_short_from_file", &filename)) +// return NULL; + +// fp = fopen(filename, "rb"); +// if (fp == NULL) { +// PyErr_SetFromErrno(PyExc_OSError); +// return NULL; +// } + +// value = PyMarshal_ReadShortFromFile(fp); +// pos = ftell(fp); + +// fclose(fp); +// if (PyErr_Occurred()) +// return NULL; +// return Py_BuildValue("il", value, pos); +// } + +// static PyObject* +// pymarshal_read_long_from_file(PyObject* self, PyObject *args) +// { +// long value, pos; +// char *filename; +// FILE *fp; + +// if (!PyArg_ParseTuple(args, "s:pymarshal_read_long_from_file", &filename)) +// return NULL; + +// fp = fopen(filename, "rb"); +// if (fp == NULL) { +// PyErr_SetFromErrno(PyExc_OSError); +// return NULL; +// } + +// value = PyMarshal_ReadLongFromFile(fp); +// pos = ftell(fp); + +// fclose(fp); +// if (PyErr_Occurred()) +// return NULL; +// return Py_BuildValue("ll", value, pos); +// } + +// static PyObject* +// pymarshal_read_last_object_from_file(PyObject* self, PyObject *args) +// { +// PyObject *obj; +// long pos; +// char *filename; +// FILE *fp; + +// if (!PyArg_ParseTuple(args, "s:pymarshal_read_last_object_from_file", &filename)) +// return NULL; + +// fp = fopen(filename, "rb"); +// if (fp == NULL) { +// PyErr_SetFromErrno(PyExc_OSError); +// return NULL; +// } + +// obj = PyMarshal_ReadLastObjectFromFile(fp); +// pos = ftell(fp); + +// fclose(fp); +// return Py_BuildValue("Nl", obj, pos); +// } + +// static PyObject* +// pymarshal_read_object_from_file(PyObject* self, PyObject *args) +// { +// PyObject *obj; +// long pos; +// char *filename; +// FILE *fp; + +// if (!PyArg_ParseTuple(args, "s:pymarshal_read_object_from_file", &filename)) +// return NULL; + +// fp = fopen(filename, "rb"); +// if (fp == NULL) { +// PyErr_SetFromErrno(PyExc_OSError); +// return NULL; +// } + +// obj = PyMarshal_ReadObjectFromFile(fp); +// pos = ftell(fp); + +// fclose(fp); +// return Py_BuildValue("Nl", obj, pos); +// } + +// static PyObject* +// return_null_without_error(PyObject *self, PyObject *args) +// { +// /* invalid call: return NULL without setting an error, +// * _Py_CheckFunctionResult() must detect such bug at runtime. */ +// PyErr_Clear(); +// return NULL; +// } + +// static PyObject* +// return_result_with_error(PyObject *self, PyObject *args) +// { +// /* invalid call: return a result with an error set, +// * _Py_CheckFunctionResult() must detect such bug at runtime. */ +// PyErr_SetNone(PyExc_ValueError); +// Py_RETURN_NONE; +// } + +// static PyObject * +// test_pytime_fromseconds(PyObject *self, PyObject *args) +// { +// int seconds; +// _PyTime_t ts; + +// if (!PyArg_ParseTuple(args, "i", &seconds)) +// return NULL; +// ts = _PyTime_FromSeconds(seconds); +// return _PyTime_AsNanosecondsObject(ts); +// } + +// static PyObject * +// test_pytime_fromsecondsobject(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// int round; +// _PyTime_t ts; + +// if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) +// return NULL; +// if (check_time_rounding(round) < 0) +// return NULL; +// if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) +// return NULL; +// return _PyTime_AsNanosecondsObject(ts); +// } + +// static PyObject * +// test_pytime_assecondsdouble(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// _PyTime_t ts; +// double d; + +// if (!PyArg_ParseTuple(args, "O", &obj)) { +// return NULL; +// } +// if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { +// return NULL; +// } +// d = _PyTime_AsSecondsDouble(ts); +// return PyFloat_FromDouble(d); +// } + +// static PyObject * +// test_PyTime_AsTimeval(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// int round; +// _PyTime_t t; +// struct timeval tv; +// PyObject *seconds; + +// if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) +// return NULL; +// if (check_time_rounding(round) < 0) { +// return NULL; +// } +// if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { +// return NULL; +// } +// if (_PyTime_AsTimeval(t, &tv, round) < 0) { +// return NULL; +// } + +// seconds = PyLong_FromLongLong(tv.tv_sec); +// if (seconds == NULL) { +// return NULL; +// } +// return Py_BuildValue("Nl", seconds, tv.tv_usec); +// } + +// #ifdef HAVE_CLOCK_GETTIME +// static PyObject * +// test_PyTime_AsTimespec(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// _PyTime_t t; +// struct timespec ts; + +// if (!PyArg_ParseTuple(args, "O", &obj)) { +// return NULL; +// } +// if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { +// return NULL; +// } +// if (_PyTime_AsTimespec(t, &ts) == -1) { +// return NULL; +// } +// return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +// } +// #endif + +// static PyObject * +// test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// int round; +// _PyTime_t t, ms; + +// if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { +// return NULL; +// } +// if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { +// return NULL; +// } +// if (check_time_rounding(round) < 0) { +// return NULL; +// } +// ms = _PyTime_AsMilliseconds(t, round); +// /* This conversion rely on the fact that _PyTime_t is a number of +// nanoseconds */ +// return _PyTime_AsNanosecondsObject(ms); +// } + +// static PyObject * +// test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) +// { +// PyObject *obj; +// int round; +// _PyTime_t t, ms; + +// if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) +// return NULL; +// if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { +// return NULL; +// } +// if (check_time_rounding(round) < 0) { +// return NULL; +// } +// ms = _PyTime_AsMicroseconds(t, round); +// /* This conversion rely on the fact that _PyTime_t is a number of +// nanoseconds */ +// return _PyTime_AsNanosecondsObject(ms); +// } + +// static PyObject* +// get_recursion_depth(PyObject *self, PyObject *args) +// { +// PyThreadState *tstate = PyThreadState_Get(); + +// /* subtract one to ignore the frame of the get_recursion_depth() call */ +// return PyLong_FromLong(tstate->recursion_depth - 1); +// } + +// static PyObject* +// pymem_buffer_overflow(PyObject *self, PyObject *args) +// { +// char *buffer; + +// /* Deliberate buffer overflow to check that PyMem_Free() detects +// the overflow when debug hooks are installed. */ +// buffer = PyMem_Malloc(16); +// if (buffer == NULL) { +// PyErr_NoMemory(); +// return NULL; +// } +// buffer[16] = 'x'; +// PyMem_Free(buffer); + +// Py_RETURN_NONE; +// } + +// static PyObject* +// pymem_api_misuse(PyObject *self, PyObject *args) +// { +// char *buffer; + +// /* Deliberate misusage of Python allocators: +// allococate with PyMem but release with PyMem_Raw. */ +// buffer = PyMem_Malloc(16); +// PyMem_RawFree(buffer); + +// Py_RETURN_NONE; +// } + +// static PyObject* +// pymem_malloc_without_gil(PyObject *self, PyObject *args) +// { +// char *buffer; + +// /* Deliberate bug to test debug hooks on Python memory allocators: +// call PyMem_Malloc() without holding the GIL */ +// Py_BEGIN_ALLOW_THREADS +// buffer = PyMem_Malloc(10); +// Py_END_ALLOW_THREADS + +// PyMem_Free(buffer); + +// Py_RETURN_NONE; +// } + + +// static PyObject* +// test_pymem_getallocatorsname(PyObject *self, PyObject *args) +// { +// const char *name = _PyMem_GetCurrentAllocatorName(); +// if (name == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name"); +// return NULL; +// } +// return PyUnicode_FromString(name); +// } + + +// static PyObject* +// test_pyobject_is_freed(const char *test_name, PyObject *op) +// { +// if (!_PyObject_IsFreed(op)) { +// return raiseTestError(test_name, "object is not seen as freed"); +// } +// Py_RETURN_NONE; +// } + + +// static PyObject* +// check_pyobject_null_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +// { +// PyObject *op = NULL; +// return test_pyobject_is_freed("check_pyobject_null_is_freed", op); +// } + + +// static PyObject* +// check_pyobject_uninitialized_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +// { +// PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); +// if (op == NULL) { +// return NULL; +// } +// /* Initialize reference count to avoid early crash in ceval or GC */ +// Py_REFCNT(op) = 1; +// /* object fields like ob_type are uninitialized! */ +// return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); +// } + + +// static PyObject* +// check_pyobject_forbidden_bytes_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +// { +// /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ +// PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); +// if (op == NULL) { +// return NULL; +// } +// /* Initialize reference count to avoid early crash in ceval or GC */ +// Py_REFCNT(op) = 1; +// /* ob_type field is after the memory block: part of "forbidden bytes" +// when using debug hooks on memory allocators! */ +// return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); +// } + + +// static PyObject* +// check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +// { +// PyObject *op = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); +// if (op == NULL) { +// return NULL; +// } +// Py_TYPE(op)->tp_dealloc(op); +// /* Reset reference count to avoid early crash in ceval or GC */ +// Py_REFCNT(op) = 1; +// /* object memory is freed! */ +// return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); +// } + + +// static PyObject* +// pyobject_malloc_without_gil(PyObject *self, PyObject *args) +// { +// char *buffer; + +// /* Deliberate bug to test debug hooks on Python memory allocators: +// call PyObject_Malloc() without holding the GIL */ +// Py_BEGIN_ALLOW_THREADS +// buffer = PyObject_Malloc(10); +// Py_END_ALLOW_THREADS + +// PyObject_Free(buffer); + +// Py_RETURN_NONE; +// } + +// static PyObject * +// tracemalloc_track(PyObject *self, PyObject *args) +// { +// unsigned int domain; +// PyObject *ptr_obj; +// void *ptr; +// Py_ssize_t size; +// int release_gil = 0; +// int res; + +// if (!PyArg_ParseTuple(args, "IOn|i", &domain, &ptr_obj, &size, &release_gil)) +// return NULL; +// ptr = PyLong_AsVoidPtr(ptr_obj); +// if (PyErr_Occurred()) +// return NULL; + +// if (release_gil) { +// Py_BEGIN_ALLOW_THREADS +// res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); +// Py_END_ALLOW_THREADS +// } +// else { +// res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); +// } + +// if (res < 0) { +// PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Track error"); +// return NULL; +// } + +// Py_RETURN_NONE; +// } + +// static PyObject * +// tracemalloc_untrack(PyObject *self, PyObject *args) +// { +// unsigned int domain; +// PyObject *ptr_obj; +// void *ptr; +// int res; + +// if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) +// return NULL; +// ptr = PyLong_AsVoidPtr(ptr_obj); +// if (PyErr_Occurred()) +// return NULL; + +// res = PyTraceMalloc_Untrack(domain, (uintptr_t)ptr); +// if (res < 0) { +// PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Untrack error"); +// return NULL; +// } + +// Py_RETURN_NONE; +// } + +// static PyObject * +// tracemalloc_get_traceback(PyObject *self, PyObject *args) +// { +// unsigned int domain; +// PyObject *ptr_obj; +// void *ptr; + +// if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) +// return NULL; +// ptr = PyLong_AsVoidPtr(ptr_obj); +// if (PyErr_Occurred()) +// return NULL; + +// return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); +// } + +// static PyObject * +// dict_get_version(PyObject *self, PyObject *args) +// { +// PyDictObject *dict; +// uint64_t version; + +// if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict)) +// return NULL; + +// version = dict->ma_version_tag; + +// Py_BUILD_ASSERT(sizeof(unsigned PY_LONG_LONG) >= sizeof(version)); +// return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)version); +// } + + +// static PyObject * +// raise_SIGINT_then_send_None(PyObject *self, PyObject *args) +// { +// PyGenObject *gen; + +// if (!PyArg_ParseTuple(args, "O!", &PyGen_Type, &gen)) +// return NULL; + +// /* This is used in a test to check what happens if a signal arrives just +// as we're in the process of entering a yield from chain (see +// bpo-30039). + +// Needs to be done in C, because: +// - we don't have a Python wrapper for raise() +// - we need to make sure that the Python-level signal handler doesn't run +// *before* we enter the generator frame, which is impossible in Python +// because we check for signals before every bytecode operation. +// */ +// raise(SIGINT); +// return _PyGen_Send(gen, Py_None); +// } + + +// static int +// fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs) +// { +// if (args == Py_None) { +// *stack = NULL; +// *nargs = 0; +// } +// else if (PyTuple_Check(args)) { +// *stack = ((PyTupleObject *)args)->ob_item; +// *nargs = PyTuple_GET_SIZE(args); +// } +// else { +// PyErr_SetString(PyExc_TypeError, "args must be None or a tuple"); +// return -1; +// } +// return 0; +// } + + +// static PyObject * +// test_pyobject_fastcall(PyObject *self, PyObject *args) +// { +// PyObject *func, *func_args; +// PyObject **stack; +// Py_ssize_t nargs; + +// if (!PyArg_ParseTuple(args, "OO", &func, &func_args)) { +// return NULL; +// } + +// if (fastcall_args(func_args, &stack, &nargs) < 0) { +// return NULL; +// } +// return _PyObject_FastCall(func, stack, nargs); +// } + + +// static PyObject * +// test_pyobject_fastcalldict(PyObject *self, PyObject *args) +// { +// PyObject *func, *func_args, *kwargs; +// PyObject **stack; +// Py_ssize_t nargs; + +// if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwargs)) { +// return NULL; +// } + +// if (fastcall_args(func_args, &stack, &nargs) < 0) { +// return NULL; +// } + +// if (kwargs == Py_None) { +// kwargs = NULL; +// } +// else if (!PyDict_Check(kwargs)) { +// PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict"); +// return NULL; +// } + +// return _PyObject_FastCallDict(func, stack, nargs, kwargs); +// } + + +// static PyObject * +// test_pyobject_vectorcall(PyObject *self, PyObject *args) +// { +// PyObject *func, *func_args, *kwnames = NULL; +// PyObject **stack; +// Py_ssize_t nargs, nkw; + +// if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwnames)) { +// return NULL; +// } + +// if (fastcall_args(func_args, &stack, &nargs) < 0) { +// return NULL; +// } + +// if (kwnames == Py_None) { +// kwnames = NULL; +// } +// else if (PyTuple_Check(kwnames)) { +// nkw = PyTuple_GET_SIZE(kwnames); +// if (nargs < nkw) { +// PyErr_SetString(PyExc_ValueError, "kwnames longer than args"); +// return NULL; +// } +// nargs -= nkw; +// } +// else { +// PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); +// return NULL; +// } +// return _PyObject_Vectorcall(func, stack, nargs, kwnames); +// } + + +// static PyObject * +// test_pyvectorcall_call(PyObject *self, PyObject *args) +// { +// PyObject *func; +// PyObject *argstuple; +// PyObject *kwargs = NULL; + +// if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) { +// return NULL; +// } + +// if (!PyTuple_Check(argstuple)) { +// PyErr_SetString(PyExc_TypeError, "args must be a tuple"); +// return NULL; +// } +// if (kwargs != NULL && !PyDict_Check(kwargs)) { +// PyErr_SetString(PyExc_TypeError, "kwargs must be a dict"); +// return NULL; +// } + +// return PyVectorcall_Call(func, argstuple, kwargs); +// } + + +// static PyObject* +// stack_pointer(PyObject *self, PyObject *args) +// { +// int v = 5; +// return PyLong_FromVoidPtr(&v); +// } + + +// #ifdef W_STOPCODE +// static PyObject* +// py_w_stopcode(PyObject *self, PyObject *args) +// { +// int sig, status; +// if (!PyArg_ParseTuple(args, "i", &sig)) { +// return NULL; +// } +// status = W_STOPCODE(sig); +// return PyLong_FromLong(status); +// } +// #endif + + +// static PyObject * +// get_mapping_keys(PyObject* self, PyObject *obj) +// { +// return PyMapping_Keys(obj); +// } + +// static PyObject * +// get_mapping_values(PyObject* self, PyObject *obj) +// { +// return PyMapping_Values(obj); +// } + +// static PyObject * +// get_mapping_items(PyObject* self, PyObject *obj) +// { +// return PyMapping_Items(obj); +// } + + +// static PyObject * +// test_pythread_tss_key_state(PyObject *self, PyObject *args) +// { +// Py_tss_t tss_key = Py_tss_NEEDS_INIT; +// if (PyThread_tss_is_created(&tss_key)) { +// return raiseTestError("test_pythread_tss_key_state", +// "TSS key not in an uninitialized state at " +// "creation time"); +// } +// if (PyThread_tss_create(&tss_key) != 0) { +// PyErr_SetString(PyExc_RuntimeError, "PyThread_tss_create failed"); +// return NULL; +// } +// if (!PyThread_tss_is_created(&tss_key)) { +// return raiseTestError("test_pythread_tss_key_state", +// "PyThread_tss_create succeeded, " +// "but with TSS key in an uninitialized state"); +// } +// if (PyThread_tss_create(&tss_key) != 0) { +// return raiseTestError("test_pythread_tss_key_state", +// "PyThread_tss_create unsuccessful with " +// "an already initialized key"); +// } +// #define CHECK_TSS_API(expr) \ +// (void)(expr); \ +// if (!PyThread_tss_is_created(&tss_key)) { \ +// return raiseTestError("test_pythread_tss_key_state", \ +// "TSS key initialization state was not " \ +// "preserved after calling " #expr); } +// CHECK_TSS_API(PyThread_tss_set(&tss_key, NULL)); +// CHECK_TSS_API(PyThread_tss_get(&tss_key)); +// #undef CHECK_TSS_API +// PyThread_tss_delete(&tss_key); +// if (PyThread_tss_is_created(&tss_key)) { +// return raiseTestError("test_pythread_tss_key_state", +// "PyThread_tss_delete called, but did not " +// "set the key state to uninitialized"); +// } + +// Py_tss_t *ptr_key = PyThread_tss_alloc(); +// if (ptr_key == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "PyThread_tss_alloc failed"); +// return NULL; +// } +// if (PyThread_tss_is_created(ptr_key)) { +// return raiseTestError("test_pythread_tss_key_state", +// "TSS key not in an uninitialized state at " +// "allocation time"); +// } +// PyThread_tss_free(ptr_key); +// ptr_key = NULL; +// Py_RETURN_NONE; +// } + + +// static PyObject* +// new_hamt(PyObject *self, PyObject *args) +// { +// return _PyContext_NewHamtForTests(); +// } + + +// /* def bad_get(self, obj, cls): +// cls() +// return repr(self) +// */ +// static PyObject* +// bad_get(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +// { +// PyObject *self, *obj, *cls; +// if (!_PyArg_UnpackStack(args, nargs, "bad_get", 3, 3, &self, &obj, &cls)) { +// return NULL; +// } + +// PyObject *res = PyObject_CallObject(cls, NULL); +// if (res == NULL) { +// return NULL; +// } +// Py_DECREF(res); + +// return PyObject_Repr(self); +// } + + +// static PyObject * +// encode_locale_ex(PyObject *self, PyObject *args) +// { +// PyObject *unicode; +// int current_locale = 0; +// wchar_t *wstr; +// PyObject *res = NULL; +// const char *errors = NULL; + +// if (!PyArg_ParseTuple(args, "U|is", &unicode, ¤t_locale, &errors)) { +// return NULL; +// } +// wstr = PyUnicode_AsWideCharString(unicode, NULL); +// if (wstr == NULL) { +// return NULL; +// } +// _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + +// char *str = NULL; +// size_t error_pos; +// const char *reason = NULL; +// int ret = _Py_EncodeLocaleEx(wstr, +// &str, &error_pos, &reason, +// current_locale, error_handler); +// PyMem_Free(wstr); + +// switch(ret) { +// case 0: +// res = PyBytes_FromString(str); +// PyMem_RawFree(str); +// break; +// case -1: +// PyErr_NoMemory(); +// break; +// case -2: +// PyErr_Format(PyExc_RuntimeError, "encode error: pos=%zu, reason=%s", +// error_pos, reason); +// break; +// case -3: +// PyErr_SetString(PyExc_ValueError, "unsupported error handler"); +// break; +// default: +// PyErr_SetString(PyExc_ValueError, "unknow error code"); +// break; +// } +// return res; +// } + + +// static PyObject * +// decode_locale_ex(PyObject *self, PyObject *args) +// { +// char *str; +// int current_locale = 0; +// PyObject *res = NULL; +// const char *errors = NULL; + +// if (!PyArg_ParseTuple(args, "y|is", &str, ¤t_locale, &errors)) { +// return NULL; +// } +// _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + +// wchar_t *wstr = NULL; +// size_t wlen = 0; +// const char *reason = NULL; +// int ret = _Py_DecodeLocaleEx(str, +// &wstr, &wlen, &reason, +// current_locale, error_handler); + +// switch(ret) { +// case 0: +// res = PyUnicode_FromWideChar(wstr, wlen); +// PyMem_RawFree(wstr); +// break; +// case -1: +// PyErr_NoMemory(); +// break; +// case -2: +// PyErr_Format(PyExc_RuntimeError, "decode error: pos=%zu, reason=%s", +// wlen, reason); +// break; +// case -3: +// PyErr_SetString(PyExc_ValueError, "unsupported error handler"); +// break; +// default: +// PyErr_SetString(PyExc_ValueError, "unknow error code"); +// break; +// } +// return res; +// } + + +// #ifdef Py_REF_DEBUG +// static PyObject * +// negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) +// { +// PyObject *obj = PyUnicode_FromString("negative_refcount"); +// if (obj == NULL) { +// return NULL; +// } +// assert(Py_REFCNT(obj) == 1); + +// Py_REFCNT(obj) = 0; +// /* Py_DECREF() must call _Py_NegativeRefcount() and abort Python */ +// Py_DECREF(obj); + +// Py_RETURN_NONE; +// } +// #endif + + +// static PyObject* +// test_write_unraisable_exc(PyObject *self, PyObject *args) +// { +// PyObject *exc, *err_msg, *obj; +// if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) { +// return NULL; +// } + +// const char *err_msg_utf8; +// if (err_msg != Py_None) { +// err_msg_utf8 = PyUnicode_AsUTF8(err_msg); +// if (err_msg_utf8 == NULL) { +// return NULL; +// } +// } +// else { +// err_msg_utf8 = NULL; +// } + +// PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); +// _PyErr_WriteUnraisableMsg(err_msg_utf8, obj); +// Py_RETURN_NONE; +// } + + +// static PyObject* +// pynumber_tobase(PyObject *module, PyObject *args) +// { +// PyObject *obj; +// int base; +// if (!PyArg_ParseTuple(args, "Oi:pynumber_tobase", +// &obj, &base)) { +// return NULL; +// } +// return PyNumber_ToBase(obj, base); +// } + + +// static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); + +// static PyMethodDef TestMethods[] = { +// {"raise_exception", raise_exception, METH_VARARGS}, +// {"raise_memoryerror", raise_memoryerror, METH_NOARGS}, +// {"set_errno", set_errno, METH_VARARGS}, +// {"test_config", test_config, METH_NOARGS}, +// {"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS}, +// {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, +// {"datetime_check_date", datetime_check_date, METH_VARARGS}, +// {"datetime_check_time", datetime_check_time, METH_VARARGS}, +// {"datetime_check_datetime", datetime_check_datetime, METH_VARARGS}, +// {"datetime_check_delta", datetime_check_delta, METH_VARARGS}, +// {"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS}, +// {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, +// {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, +// {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, +// {"get_date_fromdate", get_date_fromdate, METH_VARARGS}, +// {"get_datetime_fromdateandtime", get_datetime_fromdateandtime, METH_VARARGS}, +// {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS}, +// {"get_time_fromtime", get_time_fromtime, METH_VARARGS}, +// {"get_time_fromtimeandfold", get_time_fromtimeandfold, METH_VARARGS}, +// {"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS}, +// {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS}, +// {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS}, +// {"test_list_api", test_list_api, METH_NOARGS}, +// {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, +// {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, +// {"dict_hassplittable", dict_hassplittable, METH_O}, +// {"test_lazy_hash_inheritance", test_lazy_hash_inheritance,METH_NOARGS}, +// {"test_long_api", test_long_api, METH_NOARGS}, +// {"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS}, +// {"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS}, +// {"test_xdecref_doesnt_leak",test_xdecref_doesnt_leak, METH_NOARGS}, +// {"test_decref_doesnt_leak", test_decref_doesnt_leak, METH_NOARGS}, +// {"test_structseq_newtype_doesnt_leak", +// test_structseq_newtype_doesnt_leak, METH_NOARGS}, +// {"test_incref_decref_API", test_incref_decref_API, METH_NOARGS}, +// {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, +// {"test_long_as_double", test_long_as_double, METH_NOARGS}, +// {"test_long_as_size_t", test_long_as_size_t, METH_NOARGS}, +// {"test_long_as_unsigned_long_long_mask", +// test_long_as_unsigned_long_long_mask, METH_NOARGS}, +// {"test_long_numbits", test_long_numbits, METH_NOARGS}, +// {"test_k_code", test_k_code, METH_NOARGS}, +// {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, +// {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, +// {"test_null_strings", test_null_strings, METH_NOARGS}, +// {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, +// {"test_with_docstring", test_with_docstring, METH_NOARGS, +// PyDoc_STR("This is a pretty normal docstring.")}, +// {"test_string_to_double", test_string_to_double, METH_NOARGS}, +// {"test_unicode_compare_with_ascii", test_unicode_compare_with_ascii, +// METH_NOARGS}, +// {"test_capsule", (PyCFunction)test_capsule, METH_NOARGS}, +// {"test_from_contiguous", (PyCFunction)test_from_contiguous, METH_NOARGS}, +// #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) +// {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, +// #endif +// {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, +// {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, +// {"test_buildvalue_issue38913", test_buildvalue_issue38913, METH_NOARGS}, +// {"get_args", get_args, METH_VARARGS}, +// {"get_kwargs", (PyCFunction)(void(*)(void))get_kwargs, METH_VARARGS|METH_KEYWORDS}, +// {"getargs_tuple", getargs_tuple, METH_VARARGS}, +// {"getargs_keywords", (PyCFunction)(void(*)(void))getargs_keywords, +// METH_VARARGS|METH_KEYWORDS}, +// {"getargs_keyword_only", (PyCFunction)(void(*)(void))getargs_keyword_only, +// METH_VARARGS|METH_KEYWORDS}, +// {"getargs_positional_only_and_keywords", +// (PyCFunction)(void(*)(void))getargs_positional_only_and_keywords, +// METH_VARARGS|METH_KEYWORDS}, +// {"getargs_b", getargs_b, METH_VARARGS}, +// {"getargs_B", getargs_B, METH_VARARGS}, +// {"getargs_h", getargs_h, METH_VARARGS}, +// {"getargs_H", getargs_H, METH_VARARGS}, +// {"getargs_I", getargs_I, METH_VARARGS}, +// {"getargs_k", getargs_k, METH_VARARGS}, +// {"getargs_i", getargs_i, METH_VARARGS}, +// {"getargs_l", getargs_l, METH_VARARGS}, +// {"getargs_n", getargs_n, METH_VARARGS}, +// {"getargs_p", getargs_p, METH_VARARGS}, +// {"getargs_L", getargs_L, METH_VARARGS}, +// {"getargs_K", getargs_K, METH_VARARGS}, +// {"test_longlong_api", test_longlong_api, METH_NOARGS}, +// {"test_long_long_and_overflow",test_long_long_and_overflow, METH_NOARGS}, +// {"test_L_code", test_L_code, METH_NOARGS}, +// {"getargs_f", getargs_f, METH_VARARGS}, +// {"getargs_d", getargs_d, METH_VARARGS}, +// {"getargs_D", getargs_D, METH_VARARGS}, +// {"getargs_S", getargs_S, METH_VARARGS}, +// {"getargs_Y", getargs_Y, METH_VARARGS}, +// {"getargs_U", getargs_U, METH_VARARGS}, +// {"getargs_c", getargs_c, METH_VARARGS}, +// {"getargs_C", getargs_C, METH_VARARGS}, +// {"getargs_s", getargs_s, METH_VARARGS}, +// {"getargs_s_star", getargs_s_star, METH_VARARGS}, +// {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, +// {"getargs_z", getargs_z, METH_VARARGS}, +// {"getargs_z_star", getargs_z_star, METH_VARARGS}, +// {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, +// {"getargs_y", getargs_y, METH_VARARGS}, +// {"getargs_y_star", getargs_y_star, METH_VARARGS}, +// {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, +// {"getargs_u", getargs_u, METH_VARARGS}, +// {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, +// {"getargs_Z", getargs_Z, METH_VARARGS}, +// {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, +// {"getargs_w_star", getargs_w_star, METH_VARARGS}, +// {"getargs_es", getargs_es, METH_VARARGS}, +// {"getargs_et", getargs_et, METH_VARARGS}, +// {"getargs_es_hash", getargs_es_hash, METH_VARARGS}, +// {"getargs_et_hash", getargs_et_hash, METH_VARARGS}, +// {"codec_incrementalencoder", +// (PyCFunction)codec_incrementalencoder, METH_VARARGS}, +// {"codec_incrementaldecoder", +// (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, +// {"test_s_code", test_s_code, METH_NOARGS}, +// {"test_u_code", test_u_code, METH_NOARGS}, +// {"test_Z_code", test_Z_code, METH_NOARGS}, +// {"test_widechar", test_widechar, METH_NOARGS}, +// {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, +// {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, +// {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, +// {"unicode_findchar", unicode_findchar, METH_VARARGS}, +// {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, +// {"unicode_encodedecimal", unicode_encodedecimal, METH_VARARGS}, +// {"unicode_transformdecimaltoascii", unicode_transformdecimaltoascii, METH_VARARGS}, +// {"unicode_legacy_string", unicode_legacy_string, METH_VARARGS}, +// {"_test_thread_state", test_thread_state, METH_VARARGS}, +// {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, +// #ifdef HAVE_GETTIMEOFDAY +// {"profile_int", profile_int, METH_NOARGS}, +// #endif +// {"traceback_print", traceback_print, METH_VARARGS}, +// {"exception_print", exception_print, METH_VARARGS}, +// {"set_exc_info", test_set_exc_info, METH_VARARGS}, +// {"argparsing", argparsing, METH_VARARGS}, +// {"code_newempty", code_newempty, METH_VARARGS}, +// {"make_exception_with_doc", (PyCFunction)(void(*)(void))make_exception_with_doc, +// METH_VARARGS | METH_KEYWORDS}, +// {"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer, +// METH_NOARGS}, +// {"crash_no_current_thread", crash_no_current_thread, METH_NOARGS}, +// {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, +// {"pytime_object_to_time_t", test_pytime_object_to_time_t, METH_VARARGS}, +// {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, +// {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, +// {"with_tp_del", with_tp_del, METH_VARARGS}, +// {"create_cfunction", create_cfunction, METH_NOARGS}, +// {"test_pymem_alloc0", test_pymem_alloc0, METH_NOARGS}, +// {"test_pymem_setrawallocators",test_pymem_setrawallocators, METH_NOARGS}, +// {"test_pymem_setallocators",test_pymem_setallocators, METH_NOARGS}, +// {"test_pyobject_setallocators",test_pyobject_setallocators, METH_NOARGS}, +// {"set_nomemory", (PyCFunction)set_nomemory, METH_VARARGS, +// PyDoc_STR("set_nomemory(start:int, stop:int = 0)")}, +// {"remove_mem_hooks", remove_mem_hooks, METH_NOARGS, +// PyDoc_STR("Remove memory hooks.")}, +// {"no_docstring", +// (PyCFunction)test_with_docstring, METH_NOARGS}, +// {"docstring_empty", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_empty}, +// {"docstring_no_signature", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_no_signature}, +// {"docstring_with_invalid_signature", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_with_invalid_signature}, +// {"docstring_with_invalid_signature2", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_with_invalid_signature2}, +// {"docstring_with_signature", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_with_signature}, +// {"docstring_with_signature_but_no_doc", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_with_signature_but_no_doc}, +// {"docstring_with_signature_and_extra_newlines", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_with_signature_and_extra_newlines}, +// {"docstring_with_signature_with_defaults", +// (PyCFunction)test_with_docstring, METH_NOARGS, +// docstring_with_signature_with_defaults}, +// {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_O, +// PyDoc_STR("set_error_class(error_class) -> None")}, +// {"pymarshal_write_long_to_file", +// pymarshal_write_long_to_file, METH_VARARGS}, +// {"pymarshal_write_object_to_file", +// pymarshal_write_object_to_file, METH_VARARGS}, +// {"pymarshal_read_short_from_file", +// pymarshal_read_short_from_file, METH_VARARGS}, +// {"pymarshal_read_long_from_file", +// pymarshal_read_long_from_file, METH_VARARGS}, +// {"pymarshal_read_last_object_from_file", +// pymarshal_read_last_object_from_file, METH_VARARGS}, +// {"pymarshal_read_object_from_file", +// pymarshal_read_object_from_file, METH_VARARGS}, +// {"return_null_without_error", +// return_null_without_error, METH_NOARGS}, +// {"return_result_with_error", +// return_result_with_error, METH_NOARGS}, +// {"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS}, +// {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, +// {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, +// {"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, +// #ifdef HAVE_CLOCK_GETTIME +// {"PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, +// #endif +// {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, +// {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, +// {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, +// {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS}, +// {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, +// {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, +// {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, +// {"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS}, +// {"check_pyobject_uninitialized_is_freed", check_pyobject_uninitialized_is_freed, METH_NOARGS}, +// {"check_pyobject_forbidden_bytes_is_freed", check_pyobject_forbidden_bytes_is_freed, METH_NOARGS}, +// {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS}, +// {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, +// {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, +// {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, +// {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS}, +// {"dict_get_version", dict_get_version, METH_VARARGS}, +// {"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS}, +// {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, +// {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, +// {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, +// {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, +// {"stack_pointer", stack_pointer, METH_NOARGS}, +// #ifdef W_STOPCODE +// {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, +// #endif +// {"get_mapping_keys", get_mapping_keys, METH_O}, +// {"get_mapping_values", get_mapping_values, METH_O}, +// {"get_mapping_items", get_mapping_items, METH_O}, +// {"test_pythread_tss_key_state", test_pythread_tss_key_state, METH_VARARGS}, +// {"hamt", new_hamt, METH_NOARGS}, +// {"bad_get", (PyCFunction)(void(*)(void))bad_get, METH_FASTCALL}, +// {"EncodeLocaleEx", encode_locale_ex, METH_VARARGS}, +// {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, +// #ifdef Py_REF_DEBUG +// {"negative_refcount", negative_refcount, METH_NOARGS}, +// #endif +// {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS}, +// {"pynumber_tobase", pynumber_tobase, METH_VARARGS}, +// {"without_gc", without_gc, METH_O}, +// {NULL, NULL} /* sentinel */ +// }; + +// #define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);} + +// typedef struct { +// char bool_member; +// char byte_member; +// unsigned char ubyte_member; +// short short_member; +// unsigned short ushort_member; +// int int_member; +// unsigned int uint_member; +// long long_member; +// unsigned long ulong_member; +// Py_ssize_t pyssizet_member; +// float float_member; +// double double_member; +// char inplace_member[6]; +// long long longlong_member; +// unsigned long long ulonglong_member; +// } all_structmembers; + +// typedef struct { +// PyObject_HEAD +// all_structmembers structmembers; +// } test_structmembers; + +// static struct PyMemberDef test_members[] = { +// {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, +// {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, +// {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, +// {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, +// {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, +// {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, +// {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, +// {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, +// {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, +// {"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL}, +// {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, +// {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, +// {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, +// {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, +// {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, +// {NULL} +// }; + + +// static PyObject * +// test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +// { +// static char *keywords[] = { +// "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", +// "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET", +// "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE", +// "T_LONGLONG", "T_ULONGLONG", +// NULL}; +// static const char fmt[] = "|bbBhHiIlknfds#LK"; +// test_structmembers *ob; +// const char *s = NULL; +// Py_ssize_t string_len = 0; +// ob = PyObject_New(test_structmembers, type); +// if (ob == NULL) +// return NULL; +// memset(&ob->structmembers, 0, sizeof(all_structmembers)); +// if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, +// &ob->structmembers.bool_member, +// &ob->structmembers.byte_member, +// &ob->structmembers.ubyte_member, +// &ob->structmembers.short_member, +// &ob->structmembers.ushort_member, +// &ob->structmembers.int_member, +// &ob->structmembers.uint_member, +// &ob->structmembers.long_member, +// &ob->structmembers.ulong_member, +// &ob->structmembers.pyssizet_member, +// &ob->structmembers.float_member, +// &ob->structmembers.double_member, +// &s, &string_len +// , &ob->structmembers.longlong_member, +// &ob->structmembers.ulonglong_member +// )) { +// Py_DECREF(ob); +// return NULL; +// } +// if (s != NULL) { +// if (string_len > 5) { +// Py_DECREF(ob); +// PyErr_SetString(PyExc_ValueError, "string too long"); +// return NULL; +// } +// strcpy(ob->structmembers.inplace_member, s); +// } +// else { +// strcpy(ob->structmembers.inplace_member, ""); +// } +// return (PyObject *)ob; +// } + +// static void +// test_structmembers_free(PyObject *ob) +// { +// PyObject_FREE(ob); +// } + +// static PyTypeObject test_structmembersType = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "test_structmembersType", +// sizeof(test_structmembers), /* tp_basicsize */ +// 0, /* tp_itemsize */ +// test_structmembers_free, /* destructor 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 */ +// PyObject_GenericSetAttr, /* tp_setattro */ +// 0, /* tp_as_buffer */ +// 0, /* tp_flags */ +// "Type containing all structmember types", +// 0, /* traverseproc tp_traverse */ +// 0, /* tp_clear */ +// 0, /* tp_richcompare */ +// 0, /* tp_weaklistoffset */ +// 0, /* tp_iter */ +// 0, /* tp_iternext */ +// 0, /* tp_methods */ +// test_members, /* tp_members */ +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// test_structmembers_new, /* tp_new */ +// }; + + +// typedef struct { +// PyObject_HEAD +// } matmulObject; + +// static PyObject * +// matmulType_matmul(PyObject *self, PyObject *other) +// { +// return Py_BuildValue("(sOO)", "matmul", self, other); +// } + +// static PyObject * +// matmulType_imatmul(PyObject *self, PyObject *other) +// { +// return Py_BuildValue("(sOO)", "imatmul", self, other); +// } + +// static void +// matmulType_dealloc(PyObject *self) +// { +// Py_TYPE(self)->tp_free(self); +// } + +// static PyNumberMethods matmulType_as_number = { +// 0, /* nb_add */ +// 0, /* nb_subtract */ +// 0, /* nb_multiply */ +// 0, /* nb_remainde r*/ +// 0, /* nb_divmod */ +// 0, /* nb_power */ +// 0, /* nb_negative */ +// 0, /* tp_positive */ +// 0, /* tp_absolute */ +// 0, /* tp_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 */ +// 0, /* nb_floor_divide */ +// 0, /* nb_true_divide */ +// 0, /* nb_inplace_floor_divide */ +// 0, /* nb_inplace_true_divide */ +// 0, /* nb_index */ +// matmulType_matmul, /* nb_matrix_multiply */ +// matmulType_imatmul /* nb_matrix_inplace_multiply */ +// }; + +// static PyTypeObject matmulType = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "matmulType", +// sizeof(matmulObject), /* tp_basicsize */ +// 0, /* tp_itemsize */ +// matmulType_dealloc, /* destructor tp_dealloc */ +// 0, /* tp_vectorcall_offset */ +// 0, /* tp_getattr */ +// 0, /* tp_setattr */ +// 0, /* tp_as_async */ +// 0, /* tp_repr */ +// &matmulType_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 */ +// PyObject_GenericSetAttr, /* tp_setattro */ +// 0, /* tp_as_buffer */ +// 0, /* tp_flags */ +// "C level type with matrix operations defined", +// 0, /* traverseproc tp_traverse */ +// 0, /* tp_clear */ +// 0, /* tp_richcompare */ +// 0, /* tp_weaklistoffset */ +// 0, /* tp_iter */ +// 0, /* tp_iternext */ +// 0, /* tp_methods */ +// 0, /* tp_members */ +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// PyType_GenericNew, /* tp_new */ +// PyObject_Del, /* tp_free */ +// }; + +// typedef struct { +// PyObject_HEAD +// } ipowObject; + +// static PyObject * +// ipowType_ipow(PyObject *self, PyObject *other, PyObject *mod) +// { +// return Py_BuildValue("OO", other, mod); +// } + +// static PyNumberMethods ipowType_as_number = { +// .nb_inplace_power = ipowType_ipow +// }; + +// static PyTypeObject ipowType = { +// PyVarObject_HEAD_INIT(NULL, 0) +// .tp_name = "ipowType", +// .tp_basicsize = sizeof(ipowObject), +// .tp_as_number = &ipowType_as_number, +// .tp_new = PyType_GenericNew +// }; + +// typedef struct { +// PyObject_HEAD +// PyObject *ao_iterator; +// } awaitObject; + + +// static PyObject * +// awaitObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +// { +// PyObject *v; +// awaitObject *ao; + +// if (!PyArg_UnpackTuple(args, "awaitObject", 1, 1, &v)) +// return NULL; + +// ao = (awaitObject *)type->tp_alloc(type, 0); +// if (ao == NULL) { +// return NULL; +// } + +// Py_INCREF(v); +// ao->ao_iterator = v; + +// return (PyObject *)ao; +// } + + +// static void +// awaitObject_dealloc(awaitObject *ao) +// { +// Py_CLEAR(ao->ao_iterator); +// Py_TYPE(ao)->tp_free(ao); +// } + + +// static PyObject * +// awaitObject_await(awaitObject *ao) +// { +// Py_INCREF(ao->ao_iterator); +// return ao->ao_iterator; +// } + +// static PyAsyncMethods awaitType_as_async = { +// (unaryfunc)awaitObject_await, /* am_await */ +// 0, /* am_aiter */ +// 0 /* am_anext */ +// }; + + +// static PyTypeObject awaitType = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "awaitType", +// sizeof(awaitObject), /* tp_basicsize */ +// 0, /* tp_itemsize */ +// (destructor)awaitObject_dealloc, /* destructor tp_dealloc */ +// 0, /* tp_vectorcall_offset */ +// 0, /* tp_getattr */ +// 0, /* tp_setattr */ +// &awaitType_as_async, /* 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 */ +// PyObject_GenericSetAttr, /* tp_setattro */ +// 0, /* tp_as_buffer */ +// 0, /* tp_flags */ +// "C level type with tp_as_async", +// 0, /* traverseproc tp_traverse */ +// 0, /* tp_clear */ +// 0, /* tp_richcompare */ +// 0, /* tp_weaklistoffset */ +// 0, /* tp_iter */ +// 0, /* tp_iternext */ +// 0, /* tp_methods */ +// 0, /* tp_members */ +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// 0, +// awaitObject_new, /* tp_new */ +// PyObject_Del, /* tp_free */ +// }; + + +// static int recurse_infinitely_error_init(PyObject *, PyObject *, PyObject *); + +// static PyTypeObject PyRecursingInfinitelyError_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "RecursingInfinitelyError", /* tp_name */ +// sizeof(PyBaseExceptionObject), /* 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 */ +// 0, /* tp_as_buffer */ +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ +// "Instantiating this exception starts infinite recursion.", /* 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)recurse_infinitely_error_init, /* tp_init */ +// 0, /* tp_alloc */ +// 0, /* tp_new */ +// }; + +// static int +// recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds) +// { +// PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type; + +// /* Instantiating this exception starts infinite recursion. */ +// Py_INCREF(type); +// PyErr_SetObject(type, NULL); +// return -1; +// } + + +// /* Test bpo-35983: create a subclass of "list" which checks that instances +// * are not deallocated twice */ + +// typedef struct { +// PyListObject list; +// int deallocated; +// } MyListObject; + +// static PyObject * +// MyList_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +// { +// PyObject* op = PyList_Type.tp_new(type, args, kwds); +// ((MyListObject*)op)->deallocated = 0; +// return op; +// } + +// void +// MyList_dealloc(MyListObject* op) +// { +// if (op->deallocated) { +// /* We cannot raise exceptions here but we still want the testsuite +// * to fail when we hit this */ +// Py_FatalError("MyList instance deallocated twice"); +// } +// op->deallocated = 1; +// PyList_Type.tp_dealloc((PyObject *)op); +// } + +// static PyTypeObject MyList_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "MyList", +// sizeof(MyListObject), +// 0, +// (destructor)MyList_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, /* 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, /* &PyList_Type */ /* tp_base */ +// 0, /* tp_dict */ +// 0, /* tp_descr_get */ +// 0, /* tp_descr_set */ +// 0, /* tp_dictoffset */ +// 0, /* tp_init */ +// 0, /* tp_alloc */ +// MyList_new, /* tp_new */ +// }; + + +// /* Test PEP 560 */ + +// typedef struct { +// PyObject_HEAD +// PyObject *item; +// } PyGenericAliasObject; + +// static void +// generic_alias_dealloc(PyGenericAliasObject *self) +// { +// Py_CLEAR(self->item); +// Py_TYPE(self)->tp_free((PyObject *)self); +// } + +// static PyObject * +// generic_alias_mro_entries(PyGenericAliasObject *self, PyObject *bases) +// { +// return PyTuple_Pack(1, self->item); +// } + +// static PyMethodDef generic_alias_methods[] = { +// {"__mro_entries__", (PyCFunction)(void(*)(void))generic_alias_mro_entries, METH_O, NULL}, +// {NULL} /* sentinel */ +// }; + +// static PyTypeObject GenericAlias_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "GenericAlias", +// sizeof(PyGenericAliasObject), +// 0, +// .tp_dealloc = (destructor)generic_alias_dealloc, +// .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +// .tp_methods = generic_alias_methods, +// }; + +// static PyObject * +// generic_alias_new(PyObject *item) +// { +// PyGenericAliasObject *o = PyObject_New(PyGenericAliasObject, &GenericAlias_Type); +// if (o == NULL) { +// return NULL; +// } +// Py_INCREF(item); +// o->item = item; +// return (PyObject*) o; +// } + +// typedef struct { +// PyObject_HEAD +// } PyGenericObject; + +// static PyObject * +// generic_class_getitem(PyObject *type, PyObject *item) +// { +// return generic_alias_new(item); +// } + +// static PyMethodDef generic_methods[] = { +// {"__class_getitem__", generic_class_getitem, METH_O|METH_CLASS, NULL}, +// {NULL} /* sentinel */ +// }; + +// static PyTypeObject Generic_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "Generic", +// sizeof(PyGenericObject), +// 0, +// .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +// .tp_methods = generic_methods, +// }; + + +// /* Test PEP 590 */ + +// typedef struct { +// PyObject_HEAD +// vectorcallfunc vectorcall; +// } MethodDescriptorObject; + +// static PyObject * +// MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, +// size_t nargsf, PyObject *kwnames) +// { +// /* True if using the vectorcall function in MethodDescriptorObject +// * but False for MethodDescriptor2Object */ +// MethodDescriptorObject *md = (MethodDescriptorObject *)callable; +// return PyBool_FromLong(md->vectorcall != NULL); +// } + +// static PyObject * +// MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) +// { +// MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0); +// op->vectorcall = MethodDescriptor_vectorcall; +// return (PyObject *)op; +// } + +// static PyObject * +// func_descr_get(PyObject *func, PyObject *obj, PyObject *type) +// { +// if (obj == Py_None || obj == NULL) { +// Py_INCREF(func); +// return func; +// } +// return PyMethod_New(func, obj); +// } + +// static PyObject * +// nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) +// { +// Py_INCREF(func); +// return func; +// } + +// static PyObject * +// call_return_args(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// Py_INCREF(args); +// return args; +// } + +// static PyTypeObject MethodDescriptorBase_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "MethodDescriptorBase", +// sizeof(MethodDescriptorObject), +// .tp_new = MethodDescriptor_new, +// .tp_call = PyVectorcall_Call, +// .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), +// .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | +// Py_TPFLAGS_METHOD_DESCRIPTOR | _Py_TPFLAGS_HAVE_VECTORCALL, +// .tp_descr_get = func_descr_get, +// }; + +// static PyTypeObject MethodDescriptorDerived_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "MethodDescriptorDerived", +// .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +// }; + +// static PyTypeObject MethodDescriptorNopGet_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "MethodDescriptorNopGet", +// .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +// .tp_call = call_return_args, +// .tp_descr_get = nop_descr_get, +// }; + +// typedef struct { +// MethodDescriptorObject base; +// vectorcallfunc vectorcall; +// } MethodDescriptor2Object; + +// static PyObject * +// MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw) +// { +// MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type); +// op->base.vectorcall = NULL; +// op->vectorcall = MethodDescriptor_vectorcall; +// return (PyObject *)op; +// } + +// static PyTypeObject MethodDescriptor2_Type = { +// PyVarObject_HEAD_INIT(NULL, 0) +// "MethodDescriptor2", +// sizeof(MethodDescriptor2Object), +// .tp_new = MethodDescriptor2_new, +// .tp_call = PyVectorcall_Call, +// .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), +// .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_HAVE_VECTORCALL, +// }; + +// PyDoc_STRVAR(heapgctype__doc__, +// "A heap type with GC, and with overridden dealloc.\n\n" +// "The 'value' attribute is set to 10 in __init__."); + +// typedef struct { +// PyObject_HEAD +// int value; +// } HeapCTypeObject; + +// static struct PyMemberDef heapctype_members[] = { +// {"value", T_INT, offsetof(HeapCTypeObject, value)}, +// {NULL} /* Sentinel */ +// }; + +// static int +// heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// ((HeapCTypeObject *)self)->value = 10; +// return 0; +// } + +// static void +// heapgcctype_dealloc(HeapCTypeObject *self) +// { +// PyTypeObject *tp = Py_TYPE(self); +// PyObject_GC_UnTrack(self); +// PyObject_GC_Del(self); +// Py_DECREF(tp); +// } + +// static PyType_Slot HeapGcCType_slots[] = { +// {Py_tp_init, heapctype_init}, +// {Py_tp_members, heapctype_members}, +// {Py_tp_dealloc, heapgcctype_dealloc}, +// {Py_tp_doc, (char*)heapgctype__doc__}, +// {0, 0}, +// }; + +// static PyType_Spec HeapGcCType_spec = { +// "_testcapi.HeapGcCType", +// sizeof(HeapCTypeObject), +// 0, +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, +// HeapGcCType_slots +// }; + +// PyDoc_STRVAR(heapctype__doc__, +// "A heap type without GC, but with overridden dealloc.\n\n" +// "The 'value' attribute is set to 10 in __init__."); + +// static void +// heapctype_dealloc(HeapCTypeObject *self) +// { +// PyTypeObject *tp = Py_TYPE(self); +// PyObject_Del(self); +// Py_DECREF(tp); +// } + +// static PyType_Slot HeapCType_slots[] = { +// {Py_tp_init, heapctype_init}, +// {Py_tp_members, heapctype_members}, +// {Py_tp_dealloc, heapctype_dealloc}, +// {Py_tp_doc, (char*)heapctype__doc__}, +// {0, 0}, +// }; + +// static PyType_Spec HeapCType_spec = { +// "_testcapi.HeapCType", +// sizeof(HeapCTypeObject), +// 0, +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +// HeapCType_slots +// }; + +// PyDoc_STRVAR(heapctypesubclass__doc__, +// "Subclass of HeapCType, without GC.\n\n" +// "__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +// typedef struct { +// HeapCTypeObject base; +// int value2; +// } HeapCTypeSubclassObject; + +// static int +// heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// /* Call __init__ of the superclass */ +// if (heapctype_init(self, args, kwargs) < 0) { +// return -1; +// } +// /* Initialize additional element */ +// ((HeapCTypeSubclassObject *)self)->value2 = 20; +// return 0; +// } + +// static struct PyMemberDef heapctypesubclass_members[] = { +// {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, +// {NULL} /* Sentinel */ +// }; + +// static PyType_Slot HeapCTypeSubclass_slots[] = { +// {Py_tp_init, heapctypesubclass_init}, +// {Py_tp_members, heapctypesubclass_members}, +// {Py_tp_doc, (char*)heapctypesubclass__doc__}, +// {0, 0}, +// }; + +// static PyType_Spec HeapCTypeSubclass_spec = { +// "_testcapi.HeapCTypeSubclass", +// sizeof(HeapCTypeSubclassObject), +// 0, +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +// HeapCTypeSubclass_slots +// }; + +// PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, +// "Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" +// "__class__ is set to plain HeapCTypeSubclass during finalization.\n" +// "__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +// static int +// heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base); +// initproc base_init = PyType_GetSlot(base, Py_tp_init); +// base_init(self, args, kwargs); +// return 0; +// } + +// static void +// heapctypesubclasswithfinalizer_finalize(PyObject *self) +// { +// PyObject *error_type, *error_value, *error_traceback, *m; +// PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL; + +// /* Save the current exception, if any. */ +// PyErr_Fetch(&error_type, &error_value, &error_traceback); + +// m = PyState_FindModule(&_testcapimodule); +// if (m == NULL) { +// goto cleanup_finalize; +// } +// oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer"); +// newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass"); +// if (oldtype == NULL || newtype == NULL) { +// goto cleanup_finalize; +// } + +// if (PyObject_SetAttrString(self, "__class__", newtype) < 0) { +// goto cleanup_finalize; +// } +// refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype)); +// if (refcnt == NULL) { +// goto cleanup_finalize; +// } +// if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) { +// goto cleanup_finalize; +// } +// Py_DECREF(refcnt); +// refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype)); +// if (refcnt == NULL) { +// goto cleanup_finalize; +// } +// if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) { +// goto cleanup_finalize; +// } + +// cleanup_finalize: +// Py_XDECREF(oldtype); +// Py_XDECREF(newtype); +// Py_XDECREF(refcnt); + +// /* Restore the saved exception. */ +// PyErr_Restore(error_type, error_value, error_traceback); +// } + +// static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = { +// {Py_tp_init, heapctypesubclasswithfinalizer_init}, +// {Py_tp_members, heapctypesubclass_members}, +// {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize}, +// {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__}, +// {0, 0}, +// }; + +// static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = { +// "_testcapi.HeapCTypeSubclassWithFinalizer", +// sizeof(HeapCTypeSubclassObject), +// 0, +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, +// HeapCTypeSubclassWithFinalizer_slots +// }; + +// PyDoc_STRVAR(heapctypesetattr__doc__, +// "A heap type without GC, but with overridden __setattr__.\n\n" +// "The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); + +// typedef struct { +// PyObject_HEAD +// long value; +// } HeapCTypeSetattrObject; + +// static struct PyMemberDef heapctypesetattr_members[] = { +// {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, +// {NULL} /* Sentinel */ +// }; + +// static int +// heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs) +// { +// ((HeapCTypeSetattrObject *)self)->value = 10; +// return 0; +// } + +// static void +// heapctypesetattr_dealloc(HeapCTypeSetattrObject *self) +// { +// PyTypeObject *tp = Py_TYPE(self); +// PyObject_Del(self); +// Py_DECREF(tp); +// } + +// static int +// heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value) +// { +// PyObject *svalue = PyUnicode_FromString("value"); +// if (svalue == NULL) +// return -1; +// int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ); +// Py_DECREF(svalue); +// if (eq < 0) +// return -1; +// if (!eq) { +// return PyObject_GenericSetAttr((PyObject*) self, attr, value); +// } +// if (value == NULL) { +// self->value = 0; +// return 0; +// } +// PyObject *ivalue = PyNumber_Long(value); +// if (ivalue == NULL) +// return -1; +// long v = PyLong_AsLong(ivalue); +// Py_DECREF(ivalue); +// if (v == -1 && PyErr_Occurred()) +// return -1; +// self->value = v; +// return 0; +// } + +// static PyType_Slot HeapCTypeSetattr_slots[] = { +// {Py_tp_init, heapctypesetattr_init}, +// {Py_tp_members, heapctypesetattr_members}, +// {Py_tp_setattro, heapctypesetattr_setattro}, +// {Py_tp_dealloc, heapctypesetattr_dealloc}, +// {Py_tp_doc, (char*)heapctypesetattr__doc__}, +// {0, 0}, +// }; + +// static PyType_Spec HeapCTypeSetattr_spec = { +// "_testcapi.HeapCTypeSetattr", +// sizeof(HeapCTypeSetattrObject), +// 0, +// Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +// HeapCTypeSetattr_slots +// }; + +// static struct PyModuleDef _testcapimodule = { +// PyModuleDef_HEAD_INIT, +// "_testcapi", +// NULL, +// -1, +// TestMethods, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// /* Per PEP 489, this module will not be converted to multi-phase initialization +// */ + +// PyMODINIT_FUNC +// PyInit__testcapi(void) +// { +// PyObject *m; + +// m = PyModule_Create(&_testcapimodule); +// if (m == NULL) +// return NULL; + +// Py_TYPE(&_HashInheritanceTester_Type)=&PyType_Type; + +// Py_TYPE(&test_structmembersType)=&PyType_Type; +// Py_INCREF(&test_structmembersType); +// /* don't use a name starting with "test", since we don't want +// test_capi to automatically call this */ +// PyModule_AddObject(m, "_test_structmembersType", (PyObject *)&test_structmembersType); +// if (PyType_Ready(&matmulType) < 0) +// return NULL; +// Py_INCREF(&matmulType); +// PyModule_AddObject(m, "matmulType", (PyObject *)&matmulType); +// if (PyType_Ready(&ipowType) < 0) { +// return NULL; +// } +// Py_INCREF(&ipowType); +// PyModule_AddObject(m, "ipowType", (PyObject *)&ipowType); + +// if (PyType_Ready(&awaitType) < 0) +// return NULL; +// Py_INCREF(&awaitType); +// PyModule_AddObject(m, "awaitType", (PyObject *)&awaitType); + +// MyList_Type.tp_base = &PyList_Type; +// if (PyType_Ready(&MyList_Type) < 0) +// return NULL; +// Py_INCREF(&MyList_Type); +// PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type); + +// /* bpo-37250: old Cython code sets tp_print to 0, we check that +// * this doesn't break anything. */ +// MyList_Type.tp_print = 0; + +// if (PyType_Ready(&MethodDescriptorBase_Type) < 0) +// return NULL; +// Py_INCREF(&MethodDescriptorBase_Type); +// PyModule_AddObject(m, "MethodDescriptorBase", (PyObject *)&MethodDescriptorBase_Type); + +// MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type; +// if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) +// return NULL; +// Py_INCREF(&MethodDescriptorDerived_Type); +// PyModule_AddObject(m, "MethodDescriptorDerived", (PyObject *)&MethodDescriptorDerived_Type); + +// MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type; +// if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) +// return NULL; +// Py_INCREF(&MethodDescriptorNopGet_Type); +// PyModule_AddObject(m, "MethodDescriptorNopGet", (PyObject *)&MethodDescriptorNopGet_Type); + +// MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type; +// if (PyType_Ready(&MethodDescriptor2_Type) < 0) +// return NULL; +// Py_INCREF(&MethodDescriptor2_Type); +// PyModule_AddObject(m, "MethodDescriptor2", (PyObject *)&MethodDescriptor2_Type); + +// if (PyType_Ready(&GenericAlias_Type) < 0) +// return NULL; +// Py_INCREF(&GenericAlias_Type); +// PyModule_AddObject(m, "GenericAlias", (PyObject *)&GenericAlias_Type); + +// if (PyType_Ready(&Generic_Type) < 0) +// return NULL; +// Py_INCREF(&Generic_Type); +// PyModule_AddObject(m, "Generic", (PyObject *)&Generic_Type); + +// PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception; +// if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) { +// return NULL; +// } +// Py_INCREF(&PyRecursingInfinitelyError_Type); +// PyModule_AddObject(m, "RecursingInfinitelyError", +// (PyObject *)&PyRecursingInfinitelyError_Type); + +// PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX)); +// PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN)); +// PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX)); +// PyModule_AddObject(m, "SHRT_MAX", PyLong_FromLong(SHRT_MAX)); +// PyModule_AddObject(m, "SHRT_MIN", PyLong_FromLong(SHRT_MIN)); +// PyModule_AddObject(m, "USHRT_MAX", PyLong_FromLong(USHRT_MAX)); +// PyModule_AddObject(m, "INT_MAX", PyLong_FromLong(INT_MAX)); +// PyModule_AddObject(m, "INT_MIN", PyLong_FromLong(INT_MIN)); +// PyModule_AddObject(m, "UINT_MAX", PyLong_FromUnsignedLong(UINT_MAX)); +// PyModule_AddObject(m, "LONG_MAX", PyLong_FromLong(LONG_MAX)); +// PyModule_AddObject(m, "LONG_MIN", PyLong_FromLong(LONG_MIN)); +// PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX)); +// PyModule_AddObject(m, "FLT_MAX", PyFloat_FromDouble(FLT_MAX)); +// PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN)); +// PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX)); +// PyModule_AddObject(m, "DBL_MIN", PyFloat_FromDouble(DBL_MIN)); +// PyModule_AddObject(m, "LLONG_MAX", PyLong_FromLongLong(PY_LLONG_MAX)); +// PyModule_AddObject(m, "LLONG_MIN", PyLong_FromLongLong(PY_LLONG_MIN)); +// PyModule_AddObject(m, "ULLONG_MAX", PyLong_FromUnsignedLongLong(PY_ULLONG_MAX)); +// PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); +// PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyLong_FromSsize_t(PY_SSIZE_T_MIN)); +// PyModule_AddObject(m, "SIZEOF_PYGC_HEAD", PyLong_FromSsize_t(sizeof(PyGC_Head))); +// PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t))); +// Py_INCREF(&PyInstanceMethod_Type); +// PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); + +// PyModule_AddIntConstant(m, "the_number_three", 3); +// PyObject *v; +// #ifdef WITH_PYMALLOC +// v = Py_True; +// #else +// v = Py_False; +// #endif +// Py_INCREF(v); +// PyModule_AddObject(m, "WITH_PYMALLOC", v); + +// TestError = PyErr_NewException("_testcapi.error", NULL, NULL); +// Py_INCREF(TestError); +// PyModule_AddObject(m, "error", TestError); + +// PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); +// if (HeapGcCType == NULL) { +// return NULL; +// } +// PyModule_AddObject(m, "HeapGcCType", HeapGcCType); + +// PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); +// if (HeapCType == NULL) { +// return NULL; +// } +// PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); +// if (subclass_bases == NULL) { +// return NULL; +// } +// PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); +// if (HeapCTypeSubclass == NULL) { +// return NULL; +// } +// Py_DECREF(subclass_bases); +// PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); + +// PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); +// if (HeapCTypeSetattr == NULL) { +// return NULL; +// } +// PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); + +// PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); +// if (subclass_with_finalizer_bases == NULL) { +// return NULL; +// } +// PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( +// &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); +// if (HeapCTypeSubclassWithFinalizer == NULL) { +// return NULL; +// } +// Py_DECREF(subclass_with_finalizer_bases); +// PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); + +// PyState_AddModule(m, &_testcapimodule); +// return m; +// } + + +// /* Test the C API exposed when PY_SSIZE_T_CLEAN is not defined */ + +// #undef Py_BuildValue +// PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); + +// static PyObject * +// test_buildvalue_issue38913(PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// PyObject *res; +// const char str[] = "string"; +// const Py_UNICODE unicode[] = L"unicode"; +// PyErr_SetNone(PyExc_ZeroDivisionError); + +// res = Py_BuildValue("(s#O)", str, 1, Py_None); +// assert(res == NULL); +// if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { +// return NULL; +// } +// res = Py_BuildValue("(z#O)", str, 1, Py_None); +// assert(res == NULL); +// if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { +// return NULL; +// } +// res = Py_BuildValue("(y#O)", str, 1, Py_None); +// assert(res == NULL); +// if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { +// return NULL; +// } +// res = Py_BuildValue("(u#O)", unicode, 1, Py_None); +// assert(res == NULL); +// if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { +// return NULL; +// } + +// PyErr_Clear(); +// Py_RETURN_NONE; +// } diff --git a/python/Modules/_testimportmultiple.c b/python/Modules/_testimportmultiple.c new file mode 100755 index 0000000..1caeb66 --- /dev/null +++ b/python/Modules/_testimportmultiple.c @@ -0,0 +1,57 @@ +/* + * C extensions module to test importing multiple modules from one compiled + * file (issue16421). This file defines 3 modules (_testimportmodule, + * foo, bar), only the first one is called the same as the compiled file. + */ +#include + +static struct PyModuleDef _testimportmultiple = { + PyModuleDef_HEAD_INIT, + "_testimportmultiple", + "_testimportmultiple doc", + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__testimportmultiple(void) +{ + return PyModule_Create(&_testimportmultiple); +} + +static struct PyModuleDef _foomodule = { + PyModuleDef_HEAD_INIT, + "_testimportmultiple_foo", + "_testimportmultiple_foo doc", + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__testimportmultiple_foo(void) +{ + return PyModule_Create(&_foomodule); +} + +static struct PyModuleDef _barmodule = { + PyModuleDef_HEAD_INIT, + "_testimportmultiple_bar", + "_testimportmultiple_bar doc", + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__testimportmultiple_bar(void){ + return PyModule_Create(&_barmodule); +} + diff --git a/python/Modules/_testinternalcapi.c b/python/Modules/_testinternalcapi.c new file mode 100755 index 0000000..3a931ca --- /dev/null +++ b/python/Modules/_testinternalcapi.c @@ -0,0 +1,88 @@ +/* + * C Extension module to test Python internal C APIs (Include/internal). + */ + +#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 + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "pycore_initconfig.h" + + +#ifdef MS_WINDOWS +#include + +static int +_add_windows_config(PyObject *configs) +{ + HMODULE hPython3; + wchar_t py3path[MAX_PATH]; + PyObject *dict = PyDict_New(); + PyObject *obj = NULL; + if (!dict) { + return -1; + } + + hPython3 = GetModuleHandleW(PY3_DLLNAME); + if (hPython3 && GetModuleFileNameW(hPython3, py3path, MAX_PATH)) { + obj = PyUnicode_FromWideChar(py3path, -1); + } else { + obj = Py_None; + Py_INCREF(obj); + } + if (obj && + !PyDict_SetItemString(dict, "python3_dll", obj) && + !PyDict_SetItemString(configs, "windows", dict)) { + Py_DECREF(obj); + Py_DECREF(dict); + return 0; + } + Py_DECREF(obj); + Py_DECREF(dict); + return -1; +} +#endif + + +static PyObject * +get_configs(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *dict = _Py_GetConfigsAsDict(); +#ifdef MS_WINDOWS + if (dict) { + if (_add_windows_config(dict) < 0) { + Py_CLEAR(dict); + } + } +#endif + return dict; +} + + +static PyMethodDef TestMethods[] = { + {"get_configs", get_configs, METH_NOARGS}, + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef _testcapimodule = { + PyModuleDef_HEAD_INIT, + "_testinternalcapi", + NULL, + -1, + TestMethods, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__testinternalcapi(void) +{ + return PyModule_Create(&_testcapimodule); +} diff --git a/python/Modules/_testmultiphase.c b/python/Modules/_testmultiphase.c new file mode 100755 index 0000000..4933abb --- /dev/null +++ b/python/Modules/_testmultiphase.c @@ -0,0 +1,680 @@ + +/* Testing module for multi-phase initialization of extension modules (PEP 489) + */ + +#include "Python.h" + +/* Example objects */ +typedef struct { + PyObject_HEAD + PyObject *x_attr; /* Attributes dictionary */ +} ExampleObject; + +typedef struct { + PyObject *integer; +} testmultiphase_state; + +/* Example methods */ + +static int +Example_traverse(ExampleObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->x_attr); + return 0; +} + +static void +Example_finalize(ExampleObject *self) +{ + Py_CLEAR(self->x_attr); +} + +static PyObject * +Example_demo(ExampleObject *self, PyObject *args) +{ + PyObject *o = NULL; + if (!PyArg_ParseTuple(args, "|O:demo", &o)) + return NULL; + if (o != NULL && PyUnicode_Check(o)) { + Py_INCREF(o); + return o; + } + Py_RETURN_NONE; +} + + +static PyMethodDef Example_methods[] = { + {"demo", (PyCFunction)Example_demo, METH_VARARGS, + PyDoc_STR("demo() -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +Example_getattro(ExampleObject *self, PyObject *name) +{ + if (self->x_attr != NULL) { + PyObject *v = PyDict_GetItemWithError(self->x_attr, name); + if (v != NULL) { + Py_INCREF(v); + return v; + } + else if (PyErr_Occurred()) { + return NULL; + } + } + return PyObject_GenericGetAttr((PyObject *)self, name); +} + +static int +Example_setattr(ExampleObject *self, const char *name, PyObject *v) +{ + if (self->x_attr == NULL) { + self->x_attr = PyDict_New(); + if (self->x_attr == NULL) + return -1; + } + if (v == NULL) { + int rv = PyDict_DelItemString(self->x_attr, name); + if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetString(PyExc_AttributeError, + "delete non-existing Example attribute"); + return rv; + } + else + return PyDict_SetItemString(self->x_attr, name, v); +} + +static PyType_Slot Example_Type_slots[] = { + {Py_tp_doc, "The Example type"}, + {Py_tp_finalize, Example_finalize}, + {Py_tp_traverse, Example_traverse}, + {Py_tp_getattro, Example_getattro}, + {Py_tp_setattr, Example_setattr}, + {Py_tp_methods, Example_methods}, + {0, 0}, +}; + +static PyType_Spec Example_Type_spec = { + "_testimportexec.Example", + sizeof(ExampleObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + Example_Type_slots +}; + +/* Function of two integers returning integer */ + +PyDoc_STRVAR(testexport_foo_doc, +"foo(i,j)\n\ +\n\ +Return the sum of i and j."); + +static PyObject * +testexport_foo(PyObject *self, PyObject *args) +{ + long i, j; + long res; + if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) + return NULL; + res = i + j; + return PyLong_FromLong(res); +} + +/* Test that PyState registration fails */ + +PyDoc_STRVAR(call_state_registration_func_doc, +"register_state(0): call PyState_FindModule()\n\ +register_state(1): call PyState_AddModule()\n\ +register_state(2): call PyState_RemoveModule()"); + +static PyObject * +call_state_registration_func(PyObject *mod, PyObject *args) +{ + int i, ret; + PyModuleDef *def = PyModule_GetDef(mod); + if (def == NULL) { + return NULL; + } + if (!PyArg_ParseTuple(args, "i:call_state_registration_func", &i)) + return NULL; + switch (i) { + case 0: + mod = PyState_FindModule(def); + if (mod == NULL) { + Py_RETURN_NONE; + } + return mod; + case 1: + ret = PyState_AddModule(mod, def); + if (ret != 0) { + return NULL; + } + break; + case 2: + ret = PyState_RemoveModule(def); + if (ret != 0) { + return NULL; + } + break; + } + Py_RETURN_NONE; +} + + +static PyType_Slot Str_Type_slots[] = { + {Py_tp_base, NULL}, /* filled out in module exec function */ + {0, 0}, +}; + +static PyType_Spec Str_Type_spec = { + "_testimportexec.Str", + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Str_Type_slots +}; + +static PyMethodDef testexport_methods[] = { + {"foo", testexport_foo, METH_VARARGS, + testexport_foo_doc}, + {"call_state_registration_func", call_state_registration_func, + METH_VARARGS, call_state_registration_func_doc}, + {NULL, NULL} /* sentinel */ +}; + +static int execfunc(PyObject *m) +{ + PyObject *temp = NULL; + + /* Due to cross platform compiler issues the slots must be filled + * here. It's required for portability to Windows without requiring + * C++. */ + Str_Type_slots[0].pfunc = &PyUnicode_Type; + + /* Add a custom type */ + temp = PyType_FromSpec(&Example_Type_spec); + if (temp == NULL) + goto fail; + if (PyModule_AddObject(m, "Example", temp) != 0) + goto fail; + + /* Add an exception type */ + temp = PyErr_NewException("_testimportexec.error", NULL, NULL); + if (temp == NULL) + goto fail; + if (PyModule_AddObject(m, "error", temp) != 0) + goto fail; + + /* Add Str */ + temp = PyType_FromSpec(&Str_Type_spec); + if (temp == NULL) + goto fail; + if (PyModule_AddObject(m, "Str", temp) != 0) + goto fail; + + if (PyModule_AddIntConstant(m, "int_const", 1969) != 0) + goto fail; + + if (PyModule_AddStringConstant(m, "str_const", "something different") != 0) + goto fail; + + return 0; + fail: + return -1; +} + +/* Helper for module definitions; there'll be a lot of them */ + +#define TEST_MODULE_DEF_EX(name, slots, methods, statesize, traversefunc) { \ + PyModuleDef_HEAD_INIT, /* m_base */ \ + name, /* m_name */ \ + PyDoc_STR("Test module " name), /* m_doc */ \ + statesize, /* m_size */ \ + methods, /* m_methods */ \ + slots, /* m_slots */ \ + traversefunc, /* m_traverse */ \ + NULL, /* m_clear */ \ + NULL, /* m_free */ \ +} + +#define TEST_MODULE_DEF(name, slots, methods) TEST_MODULE_DEF_EX(name, slots, methods, 0, NULL) + +static PyModuleDef_Slot main_slots[] = { + {Py_mod_exec, execfunc}, + {0, NULL}, +}; + +static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods); + +PyMODINIT_FUNC +PyInit__testmultiphase(PyObject *spec) +{ + return PyModuleDef_Init(&main_def); +} + + +/**** Importing a non-module object ****/ + +static PyModuleDef def_nonmodule; +static PyModuleDef def_nonmodule_with_methods; + +/* Create a SimpleNamespace(three=3) */ +static PyObject* +createfunc_nonmodule(PyObject *spec, PyModuleDef *def) +{ + PyObject *dct, *ns, *three; + + if (def != &def_nonmodule && def != &def_nonmodule_with_methods) { + PyErr_SetString(PyExc_SystemError, "def does not match"); + return NULL; + } + + dct = PyDict_New(); + if (dct == NULL) + return NULL; + + three = PyLong_FromLong(3); + if (three == NULL) { + Py_DECREF(dct); + return NULL; + } + PyDict_SetItemString(dct, "three", three); + Py_DECREF(three); + + ns = _PyNamespace_New(dct); + Py_DECREF(dct); + return ns; +} + +static PyModuleDef_Slot slots_create_nonmodule[] = { + {Py_mod_create, createfunc_nonmodule}, + {0, NULL}, +}; + +static PyModuleDef def_nonmodule = TEST_MODULE_DEF( + "_testmultiphase_nonmodule", slots_create_nonmodule, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_nonmodule(PyObject *spec) +{ + return PyModuleDef_Init(&def_nonmodule); +} + +PyDoc_STRVAR(nonmodule_bar_doc, +"bar(i,j)\n\ +\n\ +Return the difference of i - j."); + +static PyObject * +nonmodule_bar(PyObject *self, PyObject *args) +{ + long i, j; + long res; + if (!PyArg_ParseTuple(args, "ll:bar", &i, &j)) + return NULL; + res = i - j; + return PyLong_FromLong(res); +} + +static PyMethodDef nonmodule_methods[] = { + {"bar", nonmodule_bar, METH_VARARGS, nonmodule_bar_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF( + "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods); + +PyMODINIT_FUNC +PyInit__testmultiphase_nonmodule_with_methods(PyObject *spec) +{ + return PyModuleDef_Init(&def_nonmodule_with_methods); +} + +/**** Non-ASCII-named modules ****/ + +static PyModuleDef def_nonascii_latin = { \ + PyModuleDef_HEAD_INIT, /* m_base */ + "_testmultiphase_nonascii_latin", /* m_name */ + PyDoc_STR("Module named in Czech"), /* m_doc */ + 0, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC +PyInitU__testmultiphase_zkouka_naten_evc07gi8e(PyObject *spec) +{ + return PyModuleDef_Init(&def_nonascii_latin); +} + +static PyModuleDef def_nonascii_kana = { \ + PyModuleDef_HEAD_INIT, /* m_base */ + "_testmultiphase_nonascii_kana", /* m_name */ + PyDoc_STR("Module named in Japanese"), /* m_doc */ + 0, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC +PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec) +{ + return PyModuleDef_Init(&def_nonascii_kana); +} + +/*** Module with a single-character name ***/ + +PyMODINIT_FUNC +PyInit_x(PyObject *spec) +{ + return PyModuleDef_Init(&main_def); +} + +/**** Testing NULL slots ****/ + +static PyModuleDef null_slots_def = TEST_MODULE_DEF( + "_testmultiphase_null_slots", NULL, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_null_slots(PyObject *spec) +{ + return PyModuleDef_Init(&null_slots_def); +} + +/**** Problematic modules ****/ + +static PyModuleDef_Slot slots_bad_large[] = { + {_Py_mod_LAST_SLOT + 1, NULL}, + {0, NULL}, +}; + +static PyModuleDef def_bad_large = TEST_MODULE_DEF( + "_testmultiphase_bad_slot_large", slots_bad_large, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_bad_slot_large(PyObject *spec) +{ + return PyModuleDef_Init(&def_bad_large); +} + +static PyModuleDef_Slot slots_bad_negative[] = { + {-1, NULL}, + {0, NULL}, +}; + +static PyModuleDef def_bad_negative = TEST_MODULE_DEF( + "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_bad_slot_negative(PyObject *spec) +{ + return PyModuleDef_Init(&def_bad_negative); +} + +static PyModuleDef def_create_int_with_state = { \ + PyModuleDef_HEAD_INIT, /* m_base */ + "create_with_state", /* m_name */ + PyDoc_STR("Not a PyModuleObject object, but requests per-module state"), + 10, /* m_size */ + NULL, /* m_methods */ + slots_create_nonmodule, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC +PyInit__testmultiphase_create_int_with_state(PyObject *spec) +{ + return PyModuleDef_Init(&def_create_int_with_state); +} + + +static PyModuleDef def_negative_size = { \ + PyModuleDef_HEAD_INIT, /* m_base */ + "negative_size", /* m_name */ + PyDoc_STR("PyModuleDef with negative m_size"), + -1, /* m_size */ + NULL, /* m_methods */ + slots_create_nonmodule, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC +PyInit__testmultiphase_negative_size(PyObject *spec) +{ + return PyModuleDef_Init(&def_negative_size); +} + + +static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods); + +PyMODINIT_FUNC +PyInit__testmultiphase_export_uninitialized(PyObject *spec) +{ + return (PyObject*) &uninitialized_def; +} + +PyMODINIT_FUNC +PyInit__testmultiphase_export_null(PyObject *spec) +{ + return NULL; +} + +PyMODINIT_FUNC +PyInit__testmultiphase_export_raise(PyObject *spec) +{ + PyErr_SetString(PyExc_SystemError, "bad export function"); + return NULL; +} + +PyMODINIT_FUNC +PyInit__testmultiphase_export_unreported_exception(PyObject *spec) +{ + PyErr_SetString(PyExc_SystemError, "bad export function"); + return PyModuleDef_Init(&main_def); +} + +static PyObject* +createfunc_null(PyObject *spec, PyModuleDef *def) +{ + return NULL; +} + +static PyModuleDef_Slot slots_create_null[] = { + {Py_mod_create, createfunc_null}, + {0, NULL}, +}; + +static PyModuleDef def_create_null = TEST_MODULE_DEF( + "_testmultiphase_create_null", slots_create_null, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_create_null(PyObject *spec) +{ + return PyModuleDef_Init(&def_create_null); +} + +static PyObject* +createfunc_raise(PyObject *spec, PyModuleDef *def) +{ + PyErr_SetString(PyExc_SystemError, "bad create function"); + return NULL; +} + +static PyModuleDef_Slot slots_create_raise[] = { + {Py_mod_create, createfunc_raise}, + {0, NULL}, +}; + +static PyModuleDef def_create_raise = TEST_MODULE_DEF( + "_testmultiphase_create_null", slots_create_raise, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_create_raise(PyObject *spec) +{ + return PyModuleDef_Init(&def_create_raise); +} + +static PyObject* +createfunc_unreported_exception(PyObject *spec, PyModuleDef *def) +{ + PyErr_SetString(PyExc_SystemError, "bad create function"); + return PyModule_New("foo"); +} + +static PyModuleDef_Slot slots_create_unreported_exception[] = { + {Py_mod_create, createfunc_unreported_exception}, + {0, NULL}, +}; + +static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF( + "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_create_unreported_exception(PyObject *spec) +{ + return PyModuleDef_Init(&def_create_unreported_exception); +} + +static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = { + {Py_mod_create, createfunc_nonmodule}, + {Py_mod_exec, execfunc}, + {0, NULL}, +}; + +static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF( + "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_nonmodule_with_exec_slots(PyObject *spec) +{ + return PyModuleDef_Init(&def_nonmodule_with_exec_slots); +} + +static int +execfunc_err(PyObject *mod) +{ + return -1; +} + +static PyModuleDef_Slot slots_exec_err[] = { + {Py_mod_exec, execfunc_err}, + {0, NULL}, +}; + +static PyModuleDef def_exec_err = TEST_MODULE_DEF( + "_testmultiphase_exec_err", slots_exec_err, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_exec_err(PyObject *spec) +{ + return PyModuleDef_Init(&def_exec_err); +} + +static int +execfunc_raise(PyObject *spec) +{ + PyErr_SetString(PyExc_SystemError, "bad exec function"); + return -1; +} + +static PyModuleDef_Slot slots_exec_raise[] = { + {Py_mod_exec, execfunc_raise}, + {0, NULL}, +}; + +static PyModuleDef def_exec_raise = TEST_MODULE_DEF( + "_testmultiphase_exec_raise", slots_exec_raise, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_exec_raise(PyObject *mod) +{ + return PyModuleDef_Init(&def_exec_raise); +} + +static int +execfunc_unreported_exception(PyObject *mod) +{ + PyErr_SetString(PyExc_SystemError, "bad exec function"); + return 0; +} + +static PyModuleDef_Slot slots_exec_unreported_exception[] = { + {Py_mod_exec, execfunc_unreported_exception}, + {0, NULL}, +}; + +static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF( + "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_exec_unreported_exception(PyObject *spec) +{ + return PyModuleDef_Init(&def_exec_unreported_exception); +} + +static int +bad_traverse(PyObject *self, visitproc visit, void *arg) { + testmultiphase_state *m_state; + + m_state = PyModule_GetState(self); + + /* The following assertion mimics any traversal function that doesn't correctly handle + * the case during module creation where the module state hasn't been created yet. + * + * The check that it is used to test only runs in debug mode, so it is OK that the + * assert() will get compiled out in fully optimised release builds. + */ + assert(m_state != NULL); + Py_VISIT(m_state->integer); + return 0; +} + +static int +execfunc_with_bad_traverse(PyObject *mod) { + testmultiphase_state *m_state; + + m_state = PyModule_GetState(mod); + if (m_state == NULL) { + return -1; + } + + m_state->integer = PyLong_FromLong(0x7fffffff); + Py_INCREF(m_state->integer); + + return 0; +} + +static PyModuleDef_Slot slots_with_bad_traverse[] = { + {Py_mod_exec, execfunc_with_bad_traverse}, + {0, NULL} +}; + +static PyModuleDef def_with_bad_traverse = TEST_MODULE_DEF_EX( + "_testmultiphase_with_bad_traverse", slots_with_bad_traverse, NULL, + sizeof(testmultiphase_state), bad_traverse); + +PyMODINIT_FUNC +PyInit__testmultiphase_with_bad_traverse(PyObject *spec) { + return PyModuleDef_Init(&def_with_bad_traverse); +} + +/*** Helper for imp test ***/ + +static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods); + +PyMODINIT_FUNC +PyInit_imp_dummy(PyObject *spec) +{ + return PyModuleDef_Init(&imp_dummy_def); +} + diff --git a/python/Modules/_threadmodule.c b/python/Modules/_threadmodule.c new file mode 100755 index 0000000..fadf57a --- /dev/null +++ b/python/Modules/_threadmodule.c @@ -0,0 +1,1583 @@ + +/* Thread module */ +/* Interface to Sjoerd's portable C thread library */ + +#include "Python.h" +#include "pycore_pylifecycle.h" +#include "pycore_pystate.h" +#include "structmember.h" /* offsetof */ +#include "pythread.h" + +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_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 * +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); +} + +static PyMethodDef lock_methods[] = { + {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, + 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}, + {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, + METH_VARARGS | METH_KEYWORDS, acquire_doc}, + {"__exit__", (PyCFunction)lock_PyThread_release_lock, + METH_VARARGS, release_doc}, + {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_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 * +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 * +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 * +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) +{ + rlockobject *self; + + self = (rlockobject *) type->tp_alloc(type, 0); + if (self != NULL) { + 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); +} + + +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}, + {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire, + METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, + {"__exit__", (PyCFunction)rlock_release, + METH_VARARGS, rlock_release_doc}, + {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_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 */ + +#include "structmember.h" + +/* 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_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; + } + + dummy = PyDict_GetItemWithError(tdict, self->key); + 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 { + assert(Py_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, + /* 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 */ (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_TYPE(self) != &localtype) + /* 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); + return value; + } + else if (PyErr_Occurred()) { + return NULL; + } + /* 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; + 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; +}; + +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(&_PyRuntime, 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)) + /* SystemExit is ignored silently */ + PyErr_Clear(); + else { + _PyErr_WriteUnraisableMsg("in thread started by", boot->func); + } + } + else { + 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); + PyThreadState_DeleteCurrent(); + PyThread_exit_thread(); +} + +static PyObject * +thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) +{ + 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; + } + 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); + if (boot->tstate == NULL) { + PyMem_DEL(boot); + return PyErr_NoMemory(); + } + Py_INCREF(func); + Py_INCREF(args); + Py_XINCREF(keyw); + PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ + 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 * +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 * +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 * +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."); + +#ifdef PY_HAVE_THREAD_NATIVE_ID +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\ +Return a non-negative integer identifying the thread as reported\n\ +by the OS (kernel). This may be used to uniquely identify a\n\ +particular thread within a system."); +#endif + +static PyObject * +thread__count(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + return PyLong_FromLong(interp->num_threads); +} + +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 +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) { + assert(Py_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 * +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)."); + +static int +thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, + PyObject *exc_traceback, PyObject *thread) +{ + _Py_IDENTIFIER(name); + /* print(f"Exception in thread {thread.name}:", file=file) */ + if (PyFile_WriteString("Exception in thread ", file) < 0) { + return -1; + } + + PyObject *name = NULL; + if (thread != Py_None) { + if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) { + return -1; + } + } + if (name != NULL) { + if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) { + Py_DECREF(name); + return -1; + } + Py_DECREF(name); + } + else { + unsigned long ident = PyThread_get_thread_ident(); + PyObject *str = PyUnicode_FromFormat("%lu", ident); + if (str != NULL) { + if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) { + Py_DECREF(str); + return -1; + } + Py_DECREF(str); + } + else { + PyErr_Clear(); + + if (PyFile_WriteString("", file) < 0) { + return -1; + } + } + } + + if (PyFile_WriteString(":\n", file) < 0) { + return -1; + } + + /* Display the traceback */ + _PyErr_Display(file, exc_type, exc_value, exc_traceback); + + /* Call file.flush() */ + PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + if (!res) { + return -1; + } + Py_DECREF(res); + + return 0; +} + + +PyDoc_STRVAR(ExceptHookArgs__doc__, +"ExceptHookArgs\n\ +\n\ +Type used to pass arguments to threading.excepthook."); + +static PyTypeObject ExceptHookArgsType; + +static PyStructSequence_Field ExceptHookArgs_fields[] = { + {"exc_type", "Exception type"}, + {"exc_value", "Exception value"}, + {"exc_traceback", "Exception traceback"}, + {"thread", "Thread"}, + {0} +}; + +static PyStructSequence_Desc ExceptHookArgs_desc = { + .name = "_thread.ExceptHookArgs", + .doc = ExceptHookArgs__doc__, + .fields = ExceptHookArgs_fields, + .n_in_sequence = 4 +}; + + +static PyObject * +thread_excepthook(PyObject *self, PyObject *args) +{ + if (Py_TYPE(args) != &ExceptHookArgsType) { + PyErr_SetString(PyExc_TypeError, + "_thread.excepthook argument type " + "must be ExceptHookArgs"); + return NULL; + } + + /* Borrowed reference */ + PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); + if (exc_type == PyExc_SystemExit) { + /* silently ignore SystemExit */ + Py_RETURN_NONE; + } + + /* Borrowed references */ + PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); + PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); + PyObject *thread = PyStructSequence_GET_ITEM(args, 3); + + PyObject *file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL || file == Py_None) { + if (thread == Py_None) { + /* do nothing if sys.stderr is None and thread is None */ + Py_RETURN_NONE; + } + + file = PyObject_GetAttrString(thread, "_stderr"); + if (file == NULL) { + return NULL; + } + if (file == Py_None) { + Py_DECREF(file); + /* do nothing if sys.stderr is None and sys.stderr was None + when the thread was created */ + Py_RETURN_NONE; + } + } + else { + Py_INCREF(file); + } + + int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb, + thread); + Py_DECREF(file); + if (res < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(excepthook_doc, +"excepthook(exc_type, exc_value, exc_traceback, thread)\n\ +\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}, + {"allocate_lock", thread_PyThread_allocate_lock, + METH_NOARGS, allocate_doc}, + {"allocate", thread_PyThread_allocate_lock, + METH_NOARGS, allocate_doc}, + {"exit_thread", thread_PyThread_exit_thread, + METH_NOARGS, exit_doc}, + {"exit", thread_PyThread_exit_thread, + METH_NOARGS, exit_doc}, + {"interrupt_main", thread_PyThread_interrupt_main, + METH_NOARGS, interrupt_doc}, + {"get_ident", thread_get_ident, + 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}, + {"_set_sentinel", thread__set_sentinel, + 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; + 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; + 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; + + 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; +} diff --git a/python/Modules/_tkinter.c b/python/Modules/_tkinter.c new file mode 100755 index 0000000..8825c83 --- /dev/null +++ b/python/Modules/_tkinter.c @@ -0,0 +1,3644 @@ +// /*********************************************************** +// Copyright (C) 1994 Steen Lumholt. + +// All Rights Reserved + +// ******************************************************************/ + +// /* _tkinter.c -- Interface to libtk.a and libtcl.a. */ + +// /* TCL/TK VERSION INFO: + +// Only Tcl/Tk 8.4 and later are supported. Older versions are not +// supported. Use Python 3.4 or older if you cannot upgrade your +// Tcl/Tk libraries. +// */ + +// /* XXX Further speed-up ideas, involving Tcl 8.0 features: + +// - Register a new Tcl type, "Python callable", which can be called more +// efficiently and passed to Tcl_EvalObj() directly (if this is possible). + +// */ + +// #define PY_SSIZE_T_CLEAN + +// #include "Python.h" +// #include + +// #include "pythread.h" + +// #ifdef MS_WINDOWS +// #include +// #endif + +// #define CHECK_SIZE(size, elemsize) \ +// ((size_t)(size) <= Py_MIN((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize))) + +// /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define +// it always; if Tcl is not threaded, the thread functions in +// Tcl are empty. */ +// #define TCL_THREADS + +// #ifdef TK_FRAMEWORK +// #include +// #include +// #else +// #include +// #include +// #endif + +// #include "tkinter.h" + +// #if TK_HEX_VERSION < 0x08040200 +// #error "Tk older than 8.4 not supported" +// #endif + +// #if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \ +// TK_HEX_VERSION >= 0x08060200 +// #define HAVE_LIBTOMMAMTH +// #include +// #endif + +// #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) +// #define HAVE_CREATEFILEHANDLER +// #endif + +// #ifdef HAVE_CREATEFILEHANDLER + +// /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere +// with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */ +// #ifndef TCL_UNIX_FD +// # ifdef TCL_WIN_SOCKET +// # define TCL_UNIX_FD (! TCL_WIN_SOCKET) +// # else +// # define TCL_UNIX_FD 1 +// # endif +// #endif + +// /* Tcl_CreateFileHandler() changed several times; these macros deal with the +// messiness. In Tcl 8.0 and later, it is not available on Windows (and on +// Unix, only because Jack added it back); when available on Windows, it only +// applies to sockets. */ + +// #ifdef MS_WINDOWS +// #define FHANDLETYPE TCL_WIN_SOCKET +// #else +// #define FHANDLETYPE TCL_UNIX_FD +// #endif + +// /* If Tcl can wait for a Unix file descriptor, define the EventHook() routine +// which uses this to handle Tcl events while the user is typing commands. */ + +// #if FHANDLETYPE == TCL_UNIX_FD +// #define WAIT_FOR_STDIN +// #endif + +// #endif /* HAVE_CREATEFILEHANDLER */ + +// /* Use OS native encoding for converting between Python strings and +// Tcl objects. +// On Windows use UTF-16 (or UTF-32 for 32-bit Tcl_UniChar) with the +// "surrogatepass" error handler for converting to/from Tcl Unicode objects. +// On Linux use UTF-8 with the "surrogateescape" error handler for converting +// to/from Tcl String objects. */ +// #ifdef MS_WINDOWS +// #define USE_TCL_UNICODE 1 +// #else +// #define USE_TCL_UNICODE 0 +// #endif + +// #if PY_LITTLE_ENDIAN +// #define NATIVE_BYTEORDER -1 +// #else +// #define NATIVE_BYTEORDER 1 +// #endif + +// #ifdef MS_WINDOWS +// #include +// #define WAIT_FOR_STDIN + +// static PyObject * +// _get_tcl_lib_path() +// { +// static PyObject *tcl_library_path = NULL; +// static int already_checked = 0; + +// if (already_checked == 0) { +// PyObject *prefix; +// struct stat stat_buf; +// int stat_return_value; + +// prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1); +// if (prefix == NULL) { +// return NULL; +// } + +// /* Check expected location for an installed Python first */ +// tcl_library_path = PyUnicode_FromString("\\tcl\\tcl" TCL_VERSION); +// if (tcl_library_path == NULL) { +// return NULL; +// } +// tcl_library_path = PyUnicode_Concat(prefix, tcl_library_path); +// if (tcl_library_path == NULL) { +// return NULL; +// } +// stat_return_value = _Py_stat(tcl_library_path, &stat_buf); +// if (stat_return_value == -2) { +// return NULL; +// } +// if (stat_return_value == -1) { +// /* install location doesn't exist, reset errno and see if +// we're a repository build */ +// errno = 0; +// #ifdef Py_TCLTK_DIR +// tcl_library_path = PyUnicode_FromString( +// Py_TCLTK_DIR "\\lib\\tcl" TCL_VERSION); +// if (tcl_library_path == NULL) { +// return NULL; +// } +// stat_return_value = _Py_stat(tcl_library_path, &stat_buf); +// if (stat_return_value == -2) { +// return NULL; +// } +// if (stat_return_value == -1) { +// /* tcltkDir for a repository build doesn't exist either, +// reset errno and leave Tcl to its own devices */ +// errno = 0; +// tcl_library_path = NULL; +// } +// #else +// tcl_library_path = NULL; +// #endif +// } +// already_checked = 1; +// } +// return tcl_library_path; +// } +// #endif /* MS_WINDOWS */ + +// /* The threading situation is complicated. Tcl is not thread-safe, except +// when configured with --enable-threads. + +// So we need to use a lock around all uses of Tcl. Previously, the +// Python interpreter lock was used for this. However, this causes +// problems when other Python threads need to run while Tcl is blocked +// waiting for events. + +// To solve this problem, a separate lock for Tcl is introduced. +// Holding it is incompatible with holding Python's interpreter lock. +// The following four macros manipulate both locks together. + +// ENTER_TCL and LEAVE_TCL are brackets, just like +// Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. They should be +// used whenever a call into Tcl is made that could call an event +// handler, or otherwise affect the state of a Tcl interpreter. These +// assume that the surrounding code has the Python interpreter lock; +// inside the brackets, the Python interpreter lock has been released +// and the lock for Tcl has been acquired. + +// Sometimes, it is necessary to have both the Python lock and the Tcl +// lock. (For example, when transferring data from the Tcl +// interpreter result to a Python string object.) This can be done by +// using different macros to close the ENTER_TCL block: ENTER_OVERLAP +// reacquires the Python lock (and restores the thread state) but +// doesn't release the Tcl lock; LEAVE_OVERLAP_TCL releases the Tcl +// lock. + +// By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event +// handlers when the handler needs to use Python. Such event handlers +// are entered while the lock for Tcl is held; the event handler +// presumably needs to use Python. ENTER_PYTHON releases the lock for +// Tcl and acquires the Python interpreter lock, restoring the +// appropriate thread state, and LEAVE_PYTHON releases the Python +// interpreter lock and re-acquires the lock for Tcl. It is okay for +// ENTER_TCL/LEAVE_TCL pairs to be contained inside the code between +// ENTER_PYTHON and LEAVE_PYTHON. + +// These locks expand to several statements and brackets; they should +// not be used in branches of if statements and the like. + +// If Tcl is threaded, this approach won't work anymore. The Tcl +// interpreter is only valid in the thread that created it, and all Tk +// activity must happen in this thread, also. That means that the +// mainloop must be invoked in the thread that created the +// interpreter. Invoking commands from other threads is possible; +// _tkinter will queue an event for the interpreter thread, which will +// then execute the command and pass back the result. If the main +// thread is not in the mainloop, and invoking commands causes an +// exception; if the main loop is running but not processing events, +// the command invocation will block. + +// In addition, for a threaded Tcl, a single global tcl_tstate won't +// be sufficient anymore, since multiple Tcl interpreters may +// simultaneously dispatch in different threads. So we use the Tcl TLS +// API. + +// */ + +// static PyThread_type_lock tcl_lock = 0; + +// #ifdef TCL_THREADS +// static Tcl_ThreadDataKey state_key; +// typedef PyThreadState *ThreadSpecificData; +// #define tcl_tstate \ +// (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*))) +// #else +// static PyThreadState *tcl_tstate = NULL; +// #endif + +// #define ENTER_TCL \ +// { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \ +// if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; + +// #define LEAVE_TCL \ +// tcl_tstate = NULL; \ +// if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS} + +// #define ENTER_OVERLAP \ +// Py_END_ALLOW_THREADS + +// #define LEAVE_OVERLAP_TCL \ +// tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); } + +// #define ENTER_PYTHON \ +// { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \ +// if(tcl_lock) \ +// PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); } + +// #define LEAVE_PYTHON \ +// { PyThreadState *tstate = PyEval_SaveThread(); \ +// if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; } + +// #define CHECK_TCL_APPARTMENT \ +// if (((TkappObject *)self)->threaded && \ +// ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \ +// PyErr_SetString(PyExc_RuntimeError, \ +// "Calling Tcl from different apartment"); \ +// return 0; \ +// } + +// #ifndef FREECAST +// #define FREECAST (char *) +// #endif + +// /**** Tkapp Object Declaration ****/ + +// static PyObject *Tkapp_Type; + +// typedef struct { +// PyObject_HEAD +// Tcl_Interp *interp; +// int wantobjects; +// int threaded; /* True if tcl_platform[threaded] */ +// Tcl_ThreadId thread_id; +// int dispatching; +// /* We cannot include tclInt.h, as this is internal. +// So we cache interesting types here. */ +// const Tcl_ObjType *OldBooleanType; +// const Tcl_ObjType *BooleanType; +// const Tcl_ObjType *ByteArrayType; +// const Tcl_ObjType *DoubleType; +// const Tcl_ObjType *IntType; +// const Tcl_ObjType *WideIntType; +// const Tcl_ObjType *BignumType; +// const Tcl_ObjType *ListType; +// const Tcl_ObjType *ProcBodyType; +// const Tcl_ObjType *StringType; +// } TkappObject; + +// #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) + +// #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ +// (void *) v, Py_REFCNT(v))) + + + +// /**** Error Handling ****/ + +// static PyObject *Tkinter_TclError; +// static int quitMainLoop = 0; +// static int errorInCmd = 0; +// static PyObject *excInCmd; +// static PyObject *valInCmd; +// static PyObject *trbInCmd; + +// #ifdef TKINTER_PROTECT_LOADTK +// static int tk_load_failed = 0; +// #endif + + +// static PyObject *Tkapp_UnicodeResult(TkappObject *); + +// static PyObject * +// Tkinter_Error(TkappObject *self) +// { +// PyObject *res = Tkapp_UnicodeResult(self); +// if (res != NULL) { +// PyErr_SetObject(Tkinter_TclError, res); +// Py_DECREF(res); +// } +// return NULL; +// } + + + +// /**** Utils ****/ + +// static int Tkinter_busywaitinterval = 20; + +// #ifndef MS_WINDOWS + +// /* Millisecond sleep() for Unix platforms. */ + +// static void +// Sleep(int milli) +// { +// /* XXX Too bad if you don't have select(). */ +// struct timeval t; +// t.tv_sec = milli/1000; +// t.tv_usec = (milli%1000) * 1000; +// select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t); +// } +// #endif /* MS_WINDOWS */ + +// /* Wait up to 1s for the mainloop to come up. */ + +// static int +// WaitForMainloop(TkappObject* self) +// { +// int i; +// for (i = 0; i < 10; i++) { +// if (self->dispatching) +// return 1; +// Py_BEGIN_ALLOW_THREADS +// Sleep(100); +// Py_END_ALLOW_THREADS +// } +// if (self->dispatching) +// return 1; +// PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop"); +// return 0; +// } + + + +// #define ARGSZ 64 + + + +// static PyObject * +// unicodeFromTclStringAndSize(const char *s, Py_ssize_t size) +// { +// PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); +// if (r != NULL || !PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { +// return r; +// } + +// char *buf = NULL; +// PyErr_Clear(); +// /* Tcl encodes null character as \xc0\x80. +// https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8 */ +// if (memchr(s, '\xc0', size)) { +// char *q; +// const char *e = s + size; +// q = buf = (char *)PyMem_Malloc(size); +// if (buf == NULL) { +// PyErr_NoMemory(); +// return NULL; +// } +// while (s != e) { +// if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { +// *q++ = '\0'; +// s += 2; +// } +// else +// *q++ = *s++; +// } +// s = buf; +// size = q - s; +// } +// r = PyUnicode_DecodeUTF8(s, size, "surrogateescape"); +// if (buf != NULL) { +// PyMem_Free(buf); +// } +// if (r == NULL || PyUnicode_KIND(r) == PyUnicode_1BYTE_KIND) { +// return r; +// } + +// /* In CESU-8 non-BMP characters are represented as a surrogate pair, +// like in UTF-16, and then each surrogate code point is encoded in UTF-8. +// https://en.wikipedia.org/wiki/CESU-8 */ +// Py_ssize_t len = PyUnicode_GET_LENGTH(r); +// Py_ssize_t i, j; +// /* All encoded surrogate characters start with \xED. */ +// i = PyUnicode_FindChar(r, 0xdcED, 0, len, 1); +// if (i == -2) { +// Py_DECREF(r); +// return NULL; +// } +// if (i == -1) { +// return r; +// } +// Py_UCS4 *u = PyUnicode_AsUCS4Copy(r); +// Py_DECREF(r); +// if (u == NULL) { +// return NULL; +// } +// Py_UCS4 ch; +// for (j = i; i < len; i++, u[j++] = ch) { +// Py_UCS4 ch1, ch2, ch3, high, low; +// /* Low surrogates U+D800 - U+DBFF are encoded as +// \xED\xA0\x80 - \xED\xAF\xBF. */ +// ch1 = ch = u[i]; +// if (ch1 != 0xdcED) continue; +// ch2 = u[i + 1]; +// if (!(0xdcA0 <= ch2 && ch2 <= 0xdcAF)) continue; +// ch3 = u[i + 2]; +// if (!(0xdc80 <= ch3 && ch3 <= 0xdcBF)) continue; +// high = 0xD000 | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F); +// assert(Py_UNICODE_IS_HIGH_SURROGATE(high)); +// /* High surrogates U+DC00 - U+DFFF are encoded as +// \xED\xB0\x80 - \xED\xBF\xBF. */ +// ch1 = u[i + 3]; +// if (ch1 != 0xdcED) continue; +// ch2 = u[i + 4]; +// if (!(0xdcB0 <= ch2 && ch2 <= 0xdcBF)) continue; +// ch3 = u[i + 5]; +// if (!(0xdc80 <= ch3 && ch3 <= 0xdcBF)) continue; +// low = 0xD000 | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F); +// assert(Py_UNICODE_IS_HIGH_SURROGATE(high)); +// ch = Py_UNICODE_JOIN_SURROGATES(high, low); +// i += 5; +// } +// r = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, u, j); +// PyMem_Free(u); +// return r; +// } + +// static PyObject * +// unicodeFromTclString(const char *s) +// { +// return unicodeFromTclStringAndSize(s, strlen(s)); +// } + +// static PyObject * +// unicodeFromTclObj(Tcl_Obj *value) +// { +// int len; +// #if USE_TCL_UNICODE +// int byteorder = NATIVE_BYTEORDER; +// const Tcl_UniChar *u = Tcl_GetUnicodeFromObj(value, &len); +// if (sizeof(Tcl_UniChar) == 2) +// return PyUnicode_DecodeUTF16((const char *)u, len * 2, +// "surrogatepass", &byteorder); +// else if (sizeof(Tcl_UniChar) == 4) +// return PyUnicode_DecodeUTF32((const char *)u, len * 4, +// "surrogatepass", &byteorder); +// else +// Py_UNREACHABLE(); +// #else +// const char *s = Tcl_GetStringFromObj(value, &len); +// return unicodeFromTclStringAndSize(s, len); +// #endif +// } + + +// static PyObject * +// Split(const char *list) +// { +// int argc; +// const char **argv; +// PyObject *v; + +// if (list == NULL) { +// Py_RETURN_NONE; +// } + +// if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { +// /* Not a list. +// * Could be a quoted string containing funnies, e.g. {"}. +// * Return the string itself. +// */ +// return unicodeFromTclString(list); +// } + +// if (argc == 0) +// v = PyUnicode_FromString(""); +// else if (argc == 1) +// v = unicodeFromTclString(argv[0]); +// else if ((v = PyTuple_New(argc)) != NULL) { +// int i; +// PyObject *w; + +// for (i = 0; i < argc; i++) { +// if ((w = Split(argv[i])) == NULL) { +// Py_DECREF(v); +// v = NULL; +// break; +// } +// PyTuple_SET_ITEM(v, i, w); +// } +// } +// Tcl_Free(FREECAST argv); +// return v; +// } + +// /* In some cases, Tcl will still return strings that are supposed to +// be lists. SplitObj walks through a nested tuple, finding string +// objects that need to be split. */ + +// static PyObject * +// SplitObj(PyObject *arg) +// { +// if (PyTuple_Check(arg)) { +// Py_ssize_t i, size; +// PyObject *elem, *newelem, *result; + +// size = PyTuple_GET_SIZE(arg); +// result = NULL; +// /* Recursively invoke SplitObj for all tuple items. +// If this does not return a new object, no action is +// needed. */ +// for(i = 0; i < size; i++) { +// elem = PyTuple_GET_ITEM(arg, i); +// newelem = SplitObj(elem); +// if (!newelem) { +// Py_XDECREF(result); +// return NULL; +// } +// if (!result) { +// Py_ssize_t k; +// if (newelem == elem) { +// Py_DECREF(newelem); +// continue; +// } +// result = PyTuple_New(size); +// if (!result) +// return NULL; +// for(k = 0; k < i; k++) { +// elem = PyTuple_GET_ITEM(arg, k); +// Py_INCREF(elem); +// PyTuple_SET_ITEM(result, k, elem); +// } +// } +// PyTuple_SET_ITEM(result, i, newelem); +// } +// if (result) +// return result; +// /* Fall through, returning arg. */ +// } +// else if (PyList_Check(arg)) { +// Py_ssize_t i, size; +// PyObject *elem, *newelem, *result; + +// size = PyList_GET_SIZE(arg); +// result = PyTuple_New(size); +// if (!result) +// return NULL; +// /* Recursively invoke SplitObj for all list items. */ +// for(i = 0; i < size; i++) { +// elem = PyList_GET_ITEM(arg, i); +// newelem = SplitObj(elem); +// if (!newelem) { +// Py_XDECREF(result); +// return NULL; +// } +// PyTuple_SET_ITEM(result, i, newelem); +// } +// return result; +// } +// else if (PyUnicode_Check(arg)) { +// int argc; +// const char **argv; +// const char *list = PyUnicode_AsUTF8(arg); + +// if (list == NULL || +// Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { +// Py_INCREF(arg); +// return arg; +// } +// Tcl_Free(FREECAST argv); +// if (argc > 1) +// return Split(list); +// /* Fall through, returning arg. */ +// } +// else if (PyBytes_Check(arg)) { +// int argc; +// const char **argv; +// char *list = PyBytes_AS_STRING(arg); + +// if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { +// Py_INCREF(arg); +// return arg; +// } +// Tcl_Free(FREECAST argv); +// if (argc > 1) +// return Split(PyBytes_AS_STRING(arg)); +// /* Fall through, returning arg. */ +// } +// Py_INCREF(arg); +// return arg; +// } + + +// /*[clinic input] +// module _tkinter +// class _tkinter.tkapp "TkappObject *" "&Tkapp_Type_spec" +// class _tkinter.Tcl_Obj "PyTclObject *" "&PyTclObject_Type_spec" +// class _tkinter.tktimertoken "TkttObject *" "&Tktt_Type_spec" +// [clinic start generated code]*/ +// /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b1ebf15c162ee229]*/ + +// /**** Tkapp Object ****/ + +// #ifndef WITH_APPINIT +// int +// Tcl_AppInit(Tcl_Interp *interp) +// { +// const char * _tkinter_skip_tk_init; + +// if (Tcl_Init(interp) == TCL_ERROR) { +// PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp)); +// return TCL_ERROR; +// } + +// _tkinter_skip_tk_init = Tcl_GetVar(interp, +// "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY); +// if (_tkinter_skip_tk_init != NULL && +// strcmp(_tkinter_skip_tk_init, "1") == 0) { +// return TCL_OK; +// } + +// #ifdef TKINTER_PROTECT_LOADTK +// if (tk_load_failed) { +// PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG); +// return TCL_ERROR; +// } +// #endif + +// if (Tk_Init(interp) == TCL_ERROR) { +// #ifdef TKINTER_PROTECT_LOADTK +// tk_load_failed = 1; +// #endif +// PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp)); +// return TCL_ERROR; +// } + +// return TCL_OK; +// } +// #endif /* !WITH_APPINIT */ + + + + +// /* Initialize the Tk application; see the `main' function in +// * `tkMain.c'. +// */ + +// static void EnableEventHook(void); /* Forward */ +// static void DisableEventHook(void); /* Forward */ + +// static TkappObject * +// Tkapp_New(const char *screenName, const char *className, +// int interactive, int wantobjects, int wantTk, int sync, +// const char *use) +// { +// TkappObject *v; +// char *argv0; + +// v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type); +// if (v == NULL) +// return NULL; + +// v->interp = Tcl_CreateInterp(); +// v->wantobjects = wantobjects; +// v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded", +// TCL_GLOBAL_ONLY) != NULL; +// v->thread_id = Tcl_GetCurrentThread(); +// v->dispatching = 0; + +// #ifndef TCL_THREADS +// if (v->threaded) { +// PyErr_SetString(PyExc_RuntimeError, +// "Tcl is threaded but _tkinter is not"); +// Py_DECREF(v); +// return 0; +// } +// #endif +// if (v->threaded && tcl_lock) { +// /* If Tcl is threaded, we don't need the lock. */ +// PyThread_free_lock(tcl_lock); +// tcl_lock = NULL; +// } + +// v->OldBooleanType = Tcl_GetObjType("boolean"); +// v->BooleanType = Tcl_GetObjType("booleanString"); +// v->ByteArrayType = Tcl_GetObjType("bytearray"); +// v->DoubleType = Tcl_GetObjType("double"); +// v->IntType = Tcl_GetObjType("int"); +// v->WideIntType = Tcl_GetObjType("wideInt"); +// v->BignumType = Tcl_GetObjType("bignum"); +// v->ListType = Tcl_GetObjType("list"); +// v->ProcBodyType = Tcl_GetObjType("procbody"); +// v->StringType = Tcl_GetObjType("string"); + +// /* Delete the 'exit' command, which can screw things up */ +// Tcl_DeleteCommand(v->interp, "exit"); + +// if (screenName != NULL) +// Tcl_SetVar2(v->interp, "env", "DISPLAY", +// screenName, TCL_GLOBAL_ONLY); + +// if (interactive) +// Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY); +// else +// Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); + +// /* This is used to get the application class for Tk 4.1 and up */ +// argv0 = (char*)PyMem_Malloc(strlen(className) + 1); +// if (!argv0) { +// PyErr_NoMemory(); +// Py_DECREF(v); +// return NULL; +// } + +// strcpy(argv0, className); +// if (Py_ISUPPER(Py_CHARMASK(argv0[0]))) +// argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0])); +// Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY); +// PyMem_Free(argv0); + +// if (! wantTk) { +// Tcl_SetVar(v->interp, +// "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY); +// } +// #ifdef TKINTER_PROTECT_LOADTK +// else if (tk_load_failed) { +// Tcl_SetVar(v->interp, +// "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); +// } +// #endif + +// /* some initial arguments need to be in argv */ +// if (sync || use) { +// char *args; +// Py_ssize_t len = 0; + +// if (sync) +// len += sizeof "-sync"; +// if (use) +// len += strlen(use) + sizeof "-use "; /* never overflows */ + +// args = (char*)PyMem_Malloc(len); +// if (!args) { +// PyErr_NoMemory(); +// Py_DECREF(v); +// return NULL; +// } + +// args[0] = '\0'; +// if (sync) +// strcat(args, "-sync"); +// if (use) { +// if (sync) +// strcat(args, " "); +// strcat(args, "-use "); +// strcat(args, use); +// } + +// Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY); +// PyMem_Free(args); +// } + +// #ifdef MS_WINDOWS +// { +// PyObject *str_path; +// PyObject *utf8_path; +// DWORD ret; + +// ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0); +// if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { +// str_path = _get_tcl_lib_path(); +// if (str_path == NULL && PyErr_Occurred()) { +// return NULL; +// } +// if (str_path != NULL) { +// utf8_path = PyUnicode_AsUTF8String(str_path); +// if (utf8_path == NULL) { +// return NULL; +// } +// Tcl_SetVar(v->interp, +// "tcl_library", +// PyBytes_AS_STRING(utf8_path), +// TCL_GLOBAL_ONLY); +// Py_DECREF(utf8_path); +// } +// } +// } +// #endif + +// if (Tcl_AppInit(v->interp) != TCL_OK) { +// PyObject *result = Tkinter_Error(v); +// #ifdef TKINTER_PROTECT_LOADTK +// if (wantTk) { +// const char *_tkinter_tk_failed; +// _tkinter_tk_failed = Tcl_GetVar(v->interp, +// "_tkinter_tk_failed", TCL_GLOBAL_ONLY); + +// if ( _tkinter_tk_failed != NULL && +// strcmp(_tkinter_tk_failed, "1") == 0) { +// tk_load_failed = 1; +// } +// } +// #endif +// Py_DECREF((PyObject *)v); +// return (TkappObject *)result; +// } + +// EnableEventHook(); + +// return v; +// } + + +// static void +// Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev, +// Tcl_Condition *cond, Tcl_Mutex *mutex) +// { +// Py_BEGIN_ALLOW_THREADS; +// Tcl_MutexLock(mutex); +// Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL); +// Tcl_ThreadAlert(self->thread_id); +// Tcl_ConditionWait(cond, mutex, NULL); +// Tcl_MutexUnlock(mutex); +// Py_END_ALLOW_THREADS +// } + + +// /** Tcl Eval **/ + +// typedef struct { +// PyObject_HEAD +// Tcl_Obj *value; +// PyObject *string; /* This cannot cause cycles. */ +// } PyTclObject; + +// static PyObject *PyTclObject_Type; +// #define PyTclObject_Check(v) ((v)->ob_type == (PyTypeObject *) PyTclObject_Type) + +// static PyObject * +// newPyTclObject(Tcl_Obj *arg) +// { +// PyTclObject *self; +// self = PyObject_New(PyTclObject, (PyTypeObject *) PyTclObject_Type); +// if (self == NULL) +// return NULL; +// Tcl_IncrRefCount(arg); +// self->value = arg; +// self->string = NULL; +// return (PyObject*)self; +// } + +// static void +// PyTclObject_dealloc(PyTclObject *self) +// { +// PyObject *tp = (PyObject *) Py_TYPE(self); +// Tcl_DecrRefCount(self->value); +// Py_XDECREF(self->string); +// PyObject_Del(self); +// Py_DECREF(tp); +// } + +// /* Like _str, but create Unicode if necessary. */ +// PyDoc_STRVAR(PyTclObject_string__doc__, +// "the string representation of this object, either as str or bytes"); + +// static PyObject * +// PyTclObject_string(PyTclObject *self, void *ignored) +// { +// if (!self->string) { +// self->string = unicodeFromTclObj(self->value); +// if (!self->string) +// return NULL; +// } +// Py_INCREF(self->string); +// return self->string; +// } + +// static PyObject * +// PyTclObject_str(PyTclObject *self) +// { +// if (self->string) { +// Py_INCREF(self->string); +// return self->string; +// } +// /* XXX Could chache result if it is non-ASCII. */ +// return unicodeFromTclObj(self->value); +// } + +// static PyObject * +// PyTclObject_repr(PyTclObject *self) +// { +// PyObject *repr, *str = PyTclObject_str(self); +// if (str == NULL) +// return NULL; +// repr = PyUnicode_FromFormat("<%s object: %R>", +// self->value->typePtr->name, str); +// Py_DECREF(str); +// return repr; +// } + +// static PyObject * +// PyTclObject_richcompare(PyObject *self, PyObject *other, int op) +// { +// int result; + +// /* neither argument should be NULL, unless something's gone wrong */ +// if (self == NULL || other == NULL) { +// PyErr_BadInternalCall(); +// return NULL; +// } + +// /* both arguments should be instances of PyTclObject */ +// if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) { +// Py_RETURN_NOTIMPLEMENTED; +// } + +// if (self == other) +// /* fast path when self and other are identical */ +// result = 0; +// else +// result = strcmp(Tcl_GetString(((PyTclObject *)self)->value), +// Tcl_GetString(((PyTclObject *)other)->value)); +// Py_RETURN_RICHCOMPARE(result, 0, op); +// } + +// PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); + +// static PyObject* +// get_typename(PyTclObject* obj, void* ignored) +// { +// return unicodeFromTclString(obj->value->typePtr->name); +// } + + +// static PyGetSetDef PyTclObject_getsetlist[] = { +// {"typename", (getter)get_typename, NULL, get_typename__doc__}, +// {"string", (getter)PyTclObject_string, NULL, +// PyTclObject_string__doc__}, +// {0}, +// }; + +// static PyType_Slot PyTclObject_Type_slots[] = { +// {Py_tp_dealloc, (destructor)PyTclObject_dealloc}, +// {Py_tp_repr, (reprfunc)PyTclObject_repr}, +// {Py_tp_str, (reprfunc)PyTclObject_str}, +// {Py_tp_getattro, PyObject_GenericGetAttr}, +// {Py_tp_richcompare, PyTclObject_richcompare}, +// {Py_tp_getset, PyTclObject_getsetlist}, +// {0, 0} +// }; + +// static PyType_Spec PyTclObject_Type_spec = { +// "_tkinter.Tcl_Obj", +// sizeof(PyTclObject), +// 0, +// Py_TPFLAGS_DEFAULT, +// PyTclObject_Type_slots, +// }; + + +// #if SIZE_MAX > INT_MAX +// #define CHECK_STRING_LENGTH(s) do { \ +// if (s != NULL && strlen(s) >= INT_MAX) { \ +// PyErr_SetString(PyExc_OverflowError, "string is too long"); \ +// return NULL; \ +// } } while(0) +// #else +// #define CHECK_STRING_LENGTH(s) +// #endif + +// #ifdef HAVE_LIBTOMMAMTH +// static Tcl_Obj* +// asBignumObj(PyObject *value) +// { +// Tcl_Obj *result; +// int neg; +// PyObject *hexstr; +// const char *hexchars; +// mp_int bigValue; + +// neg = Py_SIZE(value) < 0; +// hexstr = _PyLong_Format(value, 16); +// if (hexstr == NULL) +// return NULL; +// hexchars = PyUnicode_AsUTF8(hexstr); +// if (hexchars == NULL) { +// Py_DECREF(hexstr); +// return NULL; +// } +// hexchars += neg + 2; /* skip sign and "0x" */ +// mp_init(&bigValue); +// if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) { +// mp_clear(&bigValue); +// Py_DECREF(hexstr); +// PyErr_NoMemory(); +// return NULL; +// } +// Py_DECREF(hexstr); +// bigValue.sign = neg ? MP_NEG : MP_ZPOS; +// result = Tcl_NewBignumObj(&bigValue); +// mp_clear(&bigValue); +// if (result == NULL) { +// PyErr_NoMemory(); +// return NULL; +// } +// return result; +// } +// #endif + +// static Tcl_Obj* +// AsObj(PyObject *value) +// { +// Tcl_Obj *result; + +// if (PyBytes_Check(value)) { +// if (PyBytes_GET_SIZE(value) >= INT_MAX) { +// PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); +// return NULL; +// } +// return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value), +// (int)PyBytes_GET_SIZE(value)); +// } + +// if (PyBool_Check(value)) +// return Tcl_NewBooleanObj(PyObject_IsTrue(value)); + +// if (PyLong_CheckExact(value)) { +// int overflow; +// long longValue; +// #ifdef TCL_WIDE_INT_TYPE +// Tcl_WideInt wideValue; +// #endif +// longValue = PyLong_AsLongAndOverflow(value, &overflow); +// if (!overflow) { +// return Tcl_NewLongObj(longValue); +// } +// /* If there is an overflow in the long conversion, +// fall through to wideInt handling. */ +// #ifdef TCL_WIDE_INT_TYPE +// if (_PyLong_AsByteArray((PyLongObject *)value, +// (unsigned char *)(void *)&wideValue, +// sizeof(wideValue), +// PY_LITTLE_ENDIAN, +// /* signed */ 1) == 0) { +// return Tcl_NewWideIntObj(wideValue); +// } +// PyErr_Clear(); +// #endif +// /* If there is an overflow in the wideInt conversion, +// fall through to bignum handling. */ +// #ifdef HAVE_LIBTOMMAMTH +// return asBignumObj(value); +// #endif +// /* If there is no wideInt or bignum support, +// fall through to default object handling. */ +// } + +// if (PyFloat_Check(value)) +// return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); + +// if (PyTuple_Check(value) || PyList_Check(value)) { +// Tcl_Obj **argv; +// Py_ssize_t size, i; + +// size = PySequence_Fast_GET_SIZE(value); +// if (size == 0) +// return Tcl_NewListObj(0, NULL); +// if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { +// PyErr_SetString(PyExc_OverflowError, +// PyTuple_Check(value) ? "tuple is too long" : +// "list is too long"); +// return NULL; +// } +// argv = (Tcl_Obj **) PyMem_Malloc(((size_t)size) * sizeof(Tcl_Obj *)); +// if (!argv) { +// PyErr_NoMemory(); +// return NULL; +// } +// for (i = 0; i < size; i++) +// argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i)); +// result = Tcl_NewListObj((int)size, argv); +// PyMem_Free(argv); +// return result; +// } + +// if (PyUnicode_Check(value)) { +// if (PyUnicode_READY(value) == -1) +// return NULL; + +// Py_ssize_t size = PyUnicode_GET_LENGTH(value); +// if (size == 0) { +// return Tcl_NewStringObj("", 0); +// } +// if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { +// PyErr_SetString(PyExc_OverflowError, "string is too long"); +// return NULL; +// } +// if (PyUnicode_IS_ASCII(value)) { +// return Tcl_NewStringObj((const char *)PyUnicode_DATA(value), +// (int)size); +// } + +// PyObject *encoded; +// #if USE_TCL_UNICODE +// if (sizeof(Tcl_UniChar) == 2) +// encoded = _PyUnicode_EncodeUTF16(value, +// "surrogatepass", NATIVE_BYTEORDER); +// else if (sizeof(Tcl_UniChar) == 4) +// encoded = _PyUnicode_EncodeUTF32(value, +// "surrogatepass", NATIVE_BYTEORDER); +// else +// Py_UNREACHABLE(); +// #else +// encoded = _PyUnicode_AsUTF8String(value, "surrogateescape"); +// #endif +// if (!encoded) { +// return NULL; +// } +// size = PyBytes_GET_SIZE(encoded); +// if (size > INT_MAX) { +// Py_DECREF(encoded); +// PyErr_SetString(PyExc_OverflowError, "string is too long"); +// return NULL; +// } +// #if USE_TCL_UNICODE +// result = Tcl_NewUnicodeObj((const Tcl_UniChar *)PyBytes_AS_STRING(encoded), +// (int)(size / sizeof(Tcl_UniChar))); +// #else +// result = Tcl_NewStringObj(PyBytes_AS_STRING(encoded), (int)size); +// #endif +// Py_DECREF(encoded); +// return result; +// } + +// if (PyTclObject_Check(value)) { +// return ((PyTclObject*)value)->value; +// } + +// { +// PyObject *v = PyObject_Str(value); +// if (!v) +// return 0; +// result = AsObj(v); +// Py_DECREF(v); +// return result; +// } +// } + +// static PyObject * +// fromBoolean(TkappObject *tkapp, Tcl_Obj *value) +// { +// int boolValue; +// if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR) +// return Tkinter_Error(tkapp); +// return PyBool_FromLong(boolValue); +// } + +// static PyObject* +// fromWideIntObj(TkappObject *tkapp, Tcl_Obj *value) +// { +// Tcl_WideInt wideValue; +// if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { +// if (sizeof(wideValue) <= SIZEOF_LONG_LONG) +// return PyLong_FromLongLong(wideValue); +// return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue, +// sizeof(wideValue), +// PY_LITTLE_ENDIAN, +// /* signed */ 1); +// } +// return NULL; +// } + +// #ifdef HAVE_LIBTOMMAMTH +// static PyObject* +// fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) +// { +// mp_int bigValue; +// unsigned long numBytes; +// unsigned char *bytes; +// PyObject *res; + +// if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK) +// return Tkinter_Error(tkapp); +// numBytes = mp_unsigned_bin_size(&bigValue); +// bytes = PyMem_Malloc(numBytes); +// if (bytes == NULL) { +// mp_clear(&bigValue); +// return PyErr_NoMemory(); +// } +// if (mp_to_unsigned_bin_n(&bigValue, bytes, +// &numBytes) != MP_OKAY) { +// mp_clear(&bigValue); +// PyMem_Free(bytes); +// return PyErr_NoMemory(); +// } +// res = _PyLong_FromByteArray(bytes, numBytes, +// /* big-endian */ 0, +// /* unsigned */ 0); +// PyMem_Free(bytes); +// if (res != NULL && bigValue.sign == MP_NEG) { +// PyObject *res2 = PyNumber_Negative(res); +// Py_DECREF(res); +// res = res2; +// } +// mp_clear(&bigValue); +// return res; +// } +// #endif + +// static PyObject* +// FromObj(TkappObject *tkapp, Tcl_Obj *value) +// { +// PyObject *result = NULL; +// Tcl_Interp *interp = Tkapp_Interp(tkapp); + +// if (value->typePtr == NULL) { +// return unicodeFromTclObj(value); +// } + +// if (value->typePtr == tkapp->BooleanType || +// value->typePtr == tkapp->OldBooleanType) { +// return fromBoolean(tkapp, value); +// } + +// if (value->typePtr == tkapp->ByteArrayType) { +// int size; +// char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); +// return PyBytes_FromStringAndSize(data, size); +// } + +// if (value->typePtr == tkapp->DoubleType) { +// return PyFloat_FromDouble(value->internalRep.doubleValue); +// } + +// if (value->typePtr == tkapp->IntType) { +// long longValue; +// if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK) +// return PyLong_FromLong(longValue); +// /* If there is an error in the long conversion, +// fall through to wideInt handling. */ +// } + +// if (value->typePtr == tkapp->IntType || +// value->typePtr == tkapp->WideIntType) { +// result = fromWideIntObj(tkapp, value); +// if (result != NULL || PyErr_Occurred()) +// return result; +// Tcl_ResetResult(interp); +// /* If there is an error in the wideInt conversion, +// fall through to bignum handling. */ +// } + +// #ifdef HAVE_LIBTOMMAMTH +// if (value->typePtr == tkapp->IntType || +// value->typePtr == tkapp->WideIntType || +// value->typePtr == tkapp->BignumType) { +// return fromBignumObj(tkapp, value); +// } +// #endif + +// if (value->typePtr == tkapp->ListType) { +// int size; +// int i, status; +// PyObject *elem; +// Tcl_Obj *tcl_elem; + +// status = Tcl_ListObjLength(interp, value, &size); +// if (status == TCL_ERROR) +// return Tkinter_Error(tkapp); +// result = PyTuple_New(size); +// if (!result) +// return NULL; +// for (i = 0; i < size; i++) { +// status = Tcl_ListObjIndex(interp, value, i, &tcl_elem); +// if (status == TCL_ERROR) { +// Py_DECREF(result); +// return Tkinter_Error(tkapp); +// } +// elem = FromObj(tkapp, tcl_elem); +// if (!elem) { +// Py_DECREF(result); +// return NULL; +// } +// PyTuple_SET_ITEM(result, i, elem); +// } +// return result; +// } + +// if (value->typePtr == tkapp->ProcBodyType) { +// /* fall through: return tcl object. */ +// } + +// if (value->typePtr == tkapp->StringType) { +// return unicodeFromTclObj(value); +// } + +// #if TK_HEX_VERSION >= 0x08050000 +// if (tkapp->BooleanType == NULL && +// strcmp(value->typePtr->name, "booleanString") == 0) { +// /* booleanString type is not registered in Tcl */ +// tkapp->BooleanType = value->typePtr; +// return fromBoolean(tkapp, value); +// } +// #endif + +// #ifdef HAVE_LIBTOMMAMTH +// if (tkapp->BignumType == NULL && +// strcmp(value->typePtr->name, "bignum") == 0) { +// /* bignum type is not registered in Tcl */ +// tkapp->BignumType = value->typePtr; +// return fromBignumObj(tkapp, value); +// } +// #endif + +// return newPyTclObject(value); +// } + +// /* This mutex synchronizes inter-thread command calls. */ +// TCL_DECLARE_MUTEX(call_mutex) + +// typedef struct Tkapp_CallEvent { +// Tcl_Event ev; /* Must be first */ +// TkappObject *self; +// PyObject *args; +// int flags; +// PyObject **res; +// PyObject **exc_type, **exc_value, **exc_tb; +// Tcl_Condition *done; +// } Tkapp_CallEvent; + +// void +// Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc) +// { +// int i; +// for (i = 0; i < objc; i++) +// Tcl_DecrRefCount(objv[i]); +// if (objv != objStore) +// PyMem_Free(objv); +// } + +// /* Convert Python objects to Tcl objects. This must happen in the +// interpreter thread, which may or may not be the calling thread. */ + +// static Tcl_Obj** +// Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) +// { +// Tcl_Obj **objv = objStore; +// Py_ssize_t objc = 0, i; +// if (args == NULL) +// /* do nothing */; + +// else if (!(PyTuple_Check(args) || PyList_Check(args))) { +// objv[0] = AsObj(args); +// if (objv[0] == NULL) +// goto finally; +// objc = 1; +// Tcl_IncrRefCount(objv[0]); +// } +// else { +// objc = PySequence_Fast_GET_SIZE(args); + +// if (objc > ARGSZ) { +// if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) { +// PyErr_SetString(PyExc_OverflowError, +// PyTuple_Check(args) ? "tuple is too long" : +// "list is too long"); +// return NULL; +// } +// objv = (Tcl_Obj **)PyMem_Malloc(((size_t)objc) * sizeof(Tcl_Obj *)); +// if (objv == NULL) { +// PyErr_NoMemory(); +// objc = 0; +// goto finally; +// } +// } + +// for (i = 0; i < objc; i++) { +// PyObject *v = PySequence_Fast_GET_ITEM(args, i); +// if (v == Py_None) { +// objc = i; +// break; +// } +// objv[i] = AsObj(v); +// if (!objv[i]) { +// /* Reset objc, so it attempts to clear +// objects only up to i. */ +// objc = i; +// goto finally; +// } +// Tcl_IncrRefCount(objv[i]); +// } +// } +// *pobjc = (int)objc; +// return objv; +// finally: +// Tkapp_CallDeallocArgs(objv, objStore, (int)objc); +// return NULL; +// } + +// /* Convert the results of a command call into a Python string. */ + +// static PyObject * +// Tkapp_UnicodeResult(TkappObject *self) +// { +// return unicodeFromTclObj(Tcl_GetObjResult(self->interp)); +// } + + +// /* Convert the results of a command call into a Python objects. */ + +// static PyObject * +// Tkapp_ObjectResult(TkappObject *self) +// { +// PyObject *res = NULL; +// Tcl_Obj *value = Tcl_GetObjResult(self->interp); +// if (self->wantobjects) { +// /* Not sure whether the IncrRef is necessary, but something +// may overwrite the interpreter result while we are +// converting it. */ +// Tcl_IncrRefCount(value); +// res = FromObj(self, value); +// Tcl_DecrRefCount(value); +// } else { +// res = unicodeFromTclObj(value); +// } +// return res; +// } + + +// /* Tkapp_CallProc is the event procedure that is executed in the context of +// the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't +// hold the Python lock. */ + +// static int +// Tkapp_CallProc(Tkapp_CallEvent *e, int flags) +// { +// Tcl_Obj *objStore[ARGSZ]; +// Tcl_Obj **objv; +// int objc; +// int i; +// ENTER_PYTHON +// objv = Tkapp_CallArgs(e->args, objStore, &objc); +// if (!objv) { +// PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); +// *(e->res) = NULL; +// } +// LEAVE_PYTHON +// if (!objv) +// goto done; +// i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags); +// ENTER_PYTHON +// if (i == TCL_ERROR) { +// *(e->res) = Tkinter_Error(e->self); +// } +// else { +// *(e->res) = Tkapp_ObjectResult(e->self); +// } +// if (*(e->res) == NULL) { +// PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); +// } +// LEAVE_PYTHON + +// Tkapp_CallDeallocArgs(objv, objStore, objc); +// done: +// /* Wake up calling thread. */ +// Tcl_MutexLock(&call_mutex); +// Tcl_ConditionNotify(e->done); +// Tcl_MutexUnlock(&call_mutex); +// return 1; +// } + + +// /* This is the main entry point for calling a Tcl command. +// It supports three cases, with regard to threading: +// 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in +// the context of the calling thread. +// 2. Tcl is threaded, caller of the command is in the interpreter thread: +// Execute the command in the calling thread. Since the Tcl lock will +// not be used, we can merge that with case 1. +// 3. Tcl is threaded, caller is in a different thread: Must queue an event to +// the interpreter thread. Allocation of Tcl objects needs to occur in the +// interpreter thread, so we ship the PyObject* args to the target thread, +// and perform processing there. */ + +// static PyObject * +// Tkapp_Call(PyObject *selfptr, PyObject *args) +// { +// Tcl_Obj *objStore[ARGSZ]; +// Tcl_Obj **objv = NULL; +// int objc, i; +// PyObject *res = NULL; +// TkappObject *self = (TkappObject*)selfptr; +// int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL; + +// /* If args is a single tuple, replace with contents of tuple */ +// if (PyTuple_GET_SIZE(args) == 1) { +// PyObject *item = PyTuple_GET_ITEM(args, 0); +// if (PyTuple_Check(item)) +// args = item; +// } +// if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { +// /* We cannot call the command directly. Instead, we must +// marshal the parameters to the interpreter thread. */ +// Tkapp_CallEvent *ev; +// Tcl_Condition cond = NULL; +// PyObject *exc_type, *exc_value, *exc_tb; +// if (!WaitForMainloop(self)) +// return NULL; +// ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent)); +// if (ev == NULL) { +// PyErr_NoMemory(); +// return NULL; +// } +// ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc; +// ev->self = self; +// ev->args = args; +// ev->res = &res; +// ev->exc_type = &exc_type; +// ev->exc_value = &exc_value; +// ev->exc_tb = &exc_tb; +// ev->done = &cond; + +// Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex); + +// if (res == NULL) { +// if (exc_type) +// PyErr_Restore(exc_type, exc_value, exc_tb); +// else +// PyErr_SetObject(Tkinter_TclError, exc_value); +// } +// Tcl_ConditionFinalize(&cond); +// } +// else +// { + +// objv = Tkapp_CallArgs(args, objStore, &objc); +// if (!objv) +// return NULL; + +// ENTER_TCL + +// i = Tcl_EvalObjv(self->interp, objc, objv, flags); + +// ENTER_OVERLAP + +// if (i == TCL_ERROR) +// Tkinter_Error(self); +// else +// res = Tkapp_ObjectResult(self); + +// LEAVE_OVERLAP_TCL + +// Tkapp_CallDeallocArgs(objv, objStore, objc); +// } +// return res; +// } + + +// /*[clinic input] +// _tkinter.tkapp.eval + +// script: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_eval_impl(TkappObject *self, const char *script) +// /*[clinic end generated code: output=24b79831f700dea0 input=481484123a455f22]*/ +// { +// PyObject *res = NULL; +// int err; + +// CHECK_STRING_LENGTH(script); +// CHECK_TCL_APPARTMENT; + +// ENTER_TCL +// err = Tcl_Eval(Tkapp_Interp(self), script); +// ENTER_OVERLAP +// if (err == TCL_ERROR) +// res = Tkinter_Error(self); +// else +// res = Tkapp_UnicodeResult(self); +// LEAVE_OVERLAP_TCL +// return res; +// } + +// /*[clinic input] +// _tkinter.tkapp.evalfile + +// fileName: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName) +// /*[clinic end generated code: output=63be88dcee4f11d3 input=873ab707e5e947e1]*/ +// { +// PyObject *res = NULL; +// int err; + +// CHECK_STRING_LENGTH(fileName); +// CHECK_TCL_APPARTMENT; + +// ENTER_TCL +// err = Tcl_EvalFile(Tkapp_Interp(self), fileName); +// ENTER_OVERLAP +// if (err == TCL_ERROR) +// res = Tkinter_Error(self); +// else +// res = Tkapp_UnicodeResult(self); +// LEAVE_OVERLAP_TCL +// return res; +// } + +// /*[clinic input] +// _tkinter.tkapp.record + +// script: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_record_impl(TkappObject *self, const char *script) +// /*[clinic end generated code: output=0ffe08a0061730df input=c0b0db5a21412cac]*/ +// { +// PyObject *res = NULL; +// int err; + +// CHECK_STRING_LENGTH(script); +// CHECK_TCL_APPARTMENT; + +// ENTER_TCL +// err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL); +// ENTER_OVERLAP +// if (err == TCL_ERROR) +// res = Tkinter_Error(self); +// else +// res = Tkapp_UnicodeResult(self); +// LEAVE_OVERLAP_TCL +// return res; +// } + +// /*[clinic input] +// _tkinter.tkapp.adderrorinfo + +// msg: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg) +// /*[clinic end generated code: output=52162eaca2ee53cb input=f4b37aec7c7e8c77]*/ +// { +// CHECK_STRING_LENGTH(msg); +// CHECK_TCL_APPARTMENT; + +// ENTER_TCL +// Tcl_AddErrorInfo(Tkapp_Interp(self), msg); +// LEAVE_TCL + +// Py_RETURN_NONE; +// } + + + +// /** Tcl Variable **/ + +// typedef PyObject* (*EventFunc)(TkappObject *, PyObject *, int); + +// TCL_DECLARE_MUTEX(var_mutex) + +// typedef struct VarEvent { +// Tcl_Event ev; /* must be first */ +// TkappObject *self; +// PyObject *args; +// int flags; +// EventFunc func; +// PyObject **res; +// PyObject **exc_type; +// PyObject **exc_val; +// Tcl_Condition *cond; +// } VarEvent; + +// /*[python] + +// class varname_converter(CConverter): +// type = 'const char *' +// converter = 'varname_converter' + +// [python]*/ +// /*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + +// static int +// varname_converter(PyObject *in, void *_out) +// { +// const char *s; +// const char **out = (const char**)_out; +// if (PyBytes_Check(in)) { +// if (PyBytes_GET_SIZE(in) > INT_MAX) { +// PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); +// return 0; +// } +// s = PyBytes_AS_STRING(in); +// if (strlen(s) != (size_t)PyBytes_GET_SIZE(in)) { +// PyErr_SetString(PyExc_ValueError, "embedded null byte"); +// return 0; +// } +// *out = s; +// return 1; +// } +// if (PyUnicode_Check(in)) { +// Py_ssize_t size; +// s = PyUnicode_AsUTF8AndSize(in, &size); +// if (s == NULL) { +// return 0; +// } +// if (size > INT_MAX) { +// PyErr_SetString(PyExc_OverflowError, "string is too long"); +// return 0; +// } +// if (strlen(s) != (size_t)size) { +// PyErr_SetString(PyExc_ValueError, "embedded null character"); +// return 0; +// } +// *out = s; +// return 1; +// } +// if (PyTclObject_Check(in)) { +// *out = Tcl_GetString(((PyTclObject *)in)->value); +// return 1; +// } +// PyErr_Format(PyExc_TypeError, +// "must be str, bytes or Tcl_Obj, not %.50s", +// in->ob_type->tp_name); +// return 0; +// } + + +// static void +// var_perform(VarEvent *ev) +// { +// *(ev->res) = ev->func(ev->self, ev->args, ev->flags); +// if (!*(ev->res)) { +// PyObject *exc, *val, *tb; +// PyErr_Fetch(&exc, &val, &tb); +// PyErr_NormalizeException(&exc, &val, &tb); +// *(ev->exc_type) = exc; +// *(ev->exc_val) = val; +// Py_XDECREF(tb); +// } + +// } + +// static int +// var_proc(VarEvent* ev, int flags) +// { +// ENTER_PYTHON +// var_perform(ev); +// Tcl_MutexLock(&var_mutex); +// Tcl_ConditionNotify(ev->cond); +// Tcl_MutexUnlock(&var_mutex); +// LEAVE_PYTHON +// return 1; +// } + + +// static PyObject* +// var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) +// { +// TkappObject *self = (TkappObject*)selfptr; +// if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { +// VarEvent *ev; +// PyObject *res, *exc_type, *exc_val; +// Tcl_Condition cond = NULL; + +// /* The current thread is not the interpreter thread. Marshal +// the call to the interpreter thread, then wait for +// completion. */ +// if (!WaitForMainloop(self)) +// return NULL; + +// ev = (VarEvent*)attemptckalloc(sizeof(VarEvent)); +// if (ev == NULL) { +// PyErr_NoMemory(); +// return NULL; +// } +// ev->self = self; +// ev->args = args; +// ev->flags = flags; +// ev->func = func; +// ev->res = &res; +// ev->exc_type = &exc_type; +// ev->exc_val = &exc_val; +// ev->cond = &cond; +// ev->ev.proc = (Tcl_EventProc*)var_proc; +// Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex); +// Tcl_ConditionFinalize(&cond); +// if (!res) { +// PyErr_SetObject(exc_type, exc_val); +// Py_DECREF(exc_type); +// Py_DECREF(exc_val); +// return NULL; +// } +// return res; +// } +// /* Tcl is not threaded, or this is the interpreter thread. */ +// return func(self, args, flags); +// } + +// static PyObject * +// SetVar(TkappObject *self, PyObject *args, int flags) +// { +// const char *name1, *name2; +// PyObject *newValue; +// PyObject *res = NULL; +// Tcl_Obj *newval, *ok; + +// switch (PyTuple_GET_SIZE(args)) { +// case 2: +// if (!PyArg_ParseTuple(args, "O&O:setvar", +// varname_converter, &name1, &newValue)) +// return NULL; +// /* XXX Acquire tcl lock??? */ +// newval = AsObj(newValue); +// if (newval == NULL) +// return NULL; +// ENTER_TCL +// ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL, +// newval, flags); +// ENTER_OVERLAP +// if (!ok) +// Tkinter_Error(self); +// else { +// res = Py_None; +// Py_INCREF(res); +// } +// LEAVE_OVERLAP_TCL +// break; +// case 3: +// if (!PyArg_ParseTuple(args, "ssO:setvar", +// &name1, &name2, &newValue)) +// return NULL; +// CHECK_STRING_LENGTH(name1); +// CHECK_STRING_LENGTH(name2); +// /* XXX must hold tcl lock already??? */ +// newval = AsObj(newValue); +// ENTER_TCL +// ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags); +// ENTER_OVERLAP +// if (!ok) +// Tkinter_Error(self); +// else { +// res = Py_None; +// Py_INCREF(res); +// } +// LEAVE_OVERLAP_TCL +// break; +// default: +// PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments"); +// return NULL; +// } +// return res; +// } + +// static PyObject * +// Tkapp_SetVar(PyObject *self, PyObject *args) +// { +// return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG); +// } + +// static PyObject * +// Tkapp_GlobalSetVar(PyObject *self, PyObject *args) +// { +// return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); +// } + + + +// static PyObject * +// GetVar(TkappObject *self, PyObject *args, int flags) +// { +// const char *name1, *name2=NULL; +// PyObject *res = NULL; +// Tcl_Obj *tres; + +// if (!PyArg_ParseTuple(args, "O&|s:getvar", +// varname_converter, &name1, &name2)) +// return NULL; + +// CHECK_STRING_LENGTH(name2); +// ENTER_TCL +// tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); +// ENTER_OVERLAP +// if (tres == NULL) { +// Tkinter_Error(self); +// } else { +// if (self->wantobjects) { +// res = FromObj(self, tres); +// } +// else { +// res = unicodeFromTclObj(tres); +// } +// } +// LEAVE_OVERLAP_TCL +// return res; +// } + +// static PyObject * +// Tkapp_GetVar(PyObject *self, PyObject *args) +// { +// return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG); +// } + +// static PyObject * +// Tkapp_GlobalGetVar(PyObject *self, PyObject *args) +// { +// return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); +// } + + + +// static PyObject * +// UnsetVar(TkappObject *self, PyObject *args, int flags) +// { +// char *name1, *name2=NULL; +// int code; +// PyObject *res = NULL; + +// if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2)) +// return NULL; + +// CHECK_STRING_LENGTH(name1); +// CHECK_STRING_LENGTH(name2); +// ENTER_TCL +// code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags); +// ENTER_OVERLAP +// if (code == TCL_ERROR) +// res = Tkinter_Error(self); +// else { +// Py_INCREF(Py_None); +// res = Py_None; +// } +// LEAVE_OVERLAP_TCL +// return res; +// } + +// static PyObject * +// Tkapp_UnsetVar(PyObject *self, PyObject *args) +// { +// return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG); +// } + +// static PyObject * +// Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args) +// { +// return var_invoke(UnsetVar, self, args, +// TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); +// } + + + +// /** Tcl to Python **/ + +// /*[clinic input] +// _tkinter.tkapp.getint + +// arg: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) +// /*[clinic end generated code: output=88cf293fae307cfe input=034026997c5b91f8]*/ +// { +// char *s; +// Tcl_Obj *value; +// PyObject *result; + +// if (PyLong_Check(arg)) { +// Py_INCREF(arg); +// return arg; +// } + +// if (PyTclObject_Check(arg)) { +// value = ((PyTclObject*)arg)->value; +// Tcl_IncrRefCount(value); +// } +// else { +// if (!PyArg_Parse(arg, "s:getint", &s)) +// return NULL; +// CHECK_STRING_LENGTH(s); +// value = Tcl_NewStringObj(s, -1); +// if (value == NULL) +// return Tkinter_Error(self); +// } +// /* Don't use Tcl_GetInt() because it returns ambiguous result for value +// in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform). + +// Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for +// value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). +// */ +// #ifdef HAVE_LIBTOMMAMTH +// result = fromBignumObj(self, value); +// #else +// result = fromWideIntObj(self, value); +// #endif +// Tcl_DecrRefCount(value); +// if (result != NULL || PyErr_Occurred()) +// return result; +// return Tkinter_Error(self); +// } + +// /*[clinic input] +// _tkinter.tkapp.getdouble + +// arg: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) +// /*[clinic end generated code: output=c52b138bd8b956b9 input=22015729ce9ef7f8]*/ +// { +// char *s; +// double v; + +// if (PyFloat_Check(arg)) { +// Py_INCREF(arg); +// return arg; +// } + +// if (PyNumber_Check(arg)) { +// return PyNumber_Float(arg); +// } + +// if (PyTclObject_Check(arg)) { +// if (Tcl_GetDoubleFromObj(Tkapp_Interp(self), +// ((PyTclObject*)arg)->value, +// &v) == TCL_ERROR) +// return Tkinter_Error(self); +// return PyFloat_FromDouble(v); +// } + +// if (!PyArg_Parse(arg, "s:getdouble", &s)) +// return NULL; +// CHECK_STRING_LENGTH(s); +// if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) +// return Tkinter_Error(self); +// return PyFloat_FromDouble(v); +// } + +// /*[clinic input] +// _tkinter.tkapp.getboolean + +// arg: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) +// /*[clinic end generated code: output=726a9ae445821d91 input=7f11248ef8f8776e]*/ +// { +// char *s; +// int v; + +// if (PyLong_Check(arg)) { /* int or bool */ +// return PyBool_FromLong(Py_SIZE(arg) != 0); +// } + +// if (PyTclObject_Check(arg)) { +// if (Tcl_GetBooleanFromObj(Tkapp_Interp(self), +// ((PyTclObject*)arg)->value, +// &v) == TCL_ERROR) +// return Tkinter_Error(self); +// return PyBool_FromLong(v); +// } + +// if (!PyArg_Parse(arg, "s:getboolean", &s)) +// return NULL; +// CHECK_STRING_LENGTH(s); +// if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) +// return Tkinter_Error(self); +// return PyBool_FromLong(v); +// } + +// /*[clinic input] +// _tkinter.tkapp.exprstring + +// s: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s) +// /*[clinic end generated code: output=beda323d3ed0abb1 input=fa78f751afb2f21b]*/ +// { +// PyObject *res = NULL; +// int retval; + +// CHECK_STRING_LENGTH(s); +// CHECK_TCL_APPARTMENT; + +// ENTER_TCL +// retval = Tcl_ExprString(Tkapp_Interp(self), s); +// ENTER_OVERLAP +// if (retval == TCL_ERROR) +// res = Tkinter_Error(self); +// else +// res = Tkapp_UnicodeResult(self); +// LEAVE_OVERLAP_TCL +// return res; +// } + +// /*[clinic input] +// _tkinter.tkapp.exprlong + +// s: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s) +// /*[clinic end generated code: output=5d6a46b63c6ebcf9 input=11bd7eee0c57b4dc]*/ +// { +// PyObject *res = NULL; +// int retval; +// long v; + +// CHECK_STRING_LENGTH(s); +// CHECK_TCL_APPARTMENT; + +// ENTER_TCL +// retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v); +// ENTER_OVERLAP +// if (retval == TCL_ERROR) +// res = Tkinter_Error(self); +// else +// res = PyLong_FromLong(v); +// LEAVE_OVERLAP_TCL +// return res; +// } + +// /*[clinic input] +// _tkinter.tkapp.exprdouble + +// s: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s) +// /*[clinic end generated code: output=ff78df1081ea4158 input=ff02bc11798832d5]*/ +// { +// PyObject *res = NULL; +// double v; +// int retval; + +// CHECK_STRING_LENGTH(s); +// CHECK_TCL_APPARTMENT; +// PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0) +// ENTER_TCL +// retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v); +// ENTER_OVERLAP +// PyFPE_END_PROTECT(retval) +// if (retval == TCL_ERROR) +// res = Tkinter_Error(self); +// else +// res = PyFloat_FromDouble(v); +// LEAVE_OVERLAP_TCL +// return res; +// } + +// /*[clinic input] +// _tkinter.tkapp.exprboolean + +// s: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s) +// /*[clinic end generated code: output=8b28038c22887311 input=c8c66022bdb8d5d3]*/ +// { +// PyObject *res = NULL; +// int retval; +// int v; + +// CHECK_STRING_LENGTH(s); +// CHECK_TCL_APPARTMENT; +// ENTER_TCL +// retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); +// ENTER_OVERLAP +// if (retval == TCL_ERROR) +// res = Tkinter_Error(self); +// else +// res = PyLong_FromLong(v); +// LEAVE_OVERLAP_TCL +// return res; +// } + + + +// /*[clinic input] +// _tkinter.tkapp.splitlist + +// arg: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) +// /*[clinic end generated code: output=13b51d34386d36fb input=2b2e13351e3c0b53]*/ +// { +// char *list; +// int argc; +// const char **argv; +// PyObject *v; +// int i; + +// if (PyTclObject_Check(arg)) { +// int objc; +// Tcl_Obj **objv; +// if (Tcl_ListObjGetElements(Tkapp_Interp(self), +// ((PyTclObject*)arg)->value, +// &objc, &objv) == TCL_ERROR) { +// return Tkinter_Error(self); +// } +// if (!(v = PyTuple_New(objc))) +// return NULL; +// for (i = 0; i < objc; i++) { +// PyObject *s = FromObj(self, objv[i]); +// if (!s) { +// Py_DECREF(v); +// return NULL; +// } +// PyTuple_SET_ITEM(v, i, s); +// } +// return v; +// } +// if (PyTuple_Check(arg)) { +// Py_INCREF(arg); +// return arg; +// } +// if (PyList_Check(arg)) { +// return PySequence_Tuple(arg); +// } + +// if (!PyArg_Parse(arg, "et:splitlist", "utf-8", &list)) +// return NULL; + +// if (strlen(list) >= INT_MAX) { +// PyErr_SetString(PyExc_OverflowError, "string is too long"); +// PyMem_Free(list); +// return NULL; +// } +// if (Tcl_SplitList(Tkapp_Interp(self), list, +// &argc, &argv) == TCL_ERROR) { +// PyMem_Free(list); +// return Tkinter_Error(self); +// } + +// if (!(v = PyTuple_New(argc))) +// goto finally; + +// for (i = 0; i < argc; i++) { +// PyObject *s = unicodeFromTclString(argv[i]); +// if (!s) { +// Py_DECREF(v); +// v = NULL; +// goto finally; +// } +// PyTuple_SET_ITEM(v, i, s); +// } + +// finally: +// ckfree(FREECAST argv); +// PyMem_Free(list); +// return v; +// } + +// /*[clinic input] +// _tkinter.tkapp.split + +// arg: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_split(TkappObject *self, PyObject *arg) +// /*[clinic end generated code: output=e08ad832363facfd input=a1c78349eacaa140]*/ +// { +// PyObject *v; +// char *list; + +// if (PyTclObject_Check(arg)) { +// Tcl_Obj *value = ((PyTclObject*)arg)->value; +// int objc; +// Tcl_Obj **objv; +// int i; +// if (Tcl_ListObjGetElements(Tkapp_Interp(self), value, +// &objc, &objv) == TCL_ERROR) { +// return FromObj(self, value); +// } +// if (objc == 0) +// return PyUnicode_FromString(""); +// if (objc == 1) +// return FromObj(self, objv[0]); +// if (!(v = PyTuple_New(objc))) +// return NULL; +// for (i = 0; i < objc; i++) { +// PyObject *s = FromObj(self, objv[i]); +// if (!s) { +// Py_DECREF(v); +// return NULL; +// } +// PyTuple_SET_ITEM(v, i, s); +// } +// return v; +// } +// if (PyTuple_Check(arg) || PyList_Check(arg)) +// return SplitObj(arg); + +// if (!PyArg_Parse(arg, "et:split", "utf-8", &list)) +// return NULL; +// if (strlen(list) >= INT_MAX) { +// PyErr_SetString(PyExc_OverflowError, "string is too long"); +// PyMem_Free(list); +// return NULL; +// } +// v = Split(list); +// PyMem_Free(list); +// return v; +// } + + + +// /** Tcl Command **/ + +// /* Client data struct */ +// typedef struct { +// PyObject *self; +// PyObject *func; +// } PythonCmd_ClientData; + +// static int +// PythonCmd_Error(Tcl_Interp *interp) +// { +// errorInCmd = 1; +// PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); +// LEAVE_PYTHON +// return TCL_ERROR; +// } + +// /* This is the Tcl command that acts as a wrapper for Python +// * function or method. +// */ +// static int +// PythonCmd(ClientData clientData, Tcl_Interp *interp, +// int objc, Tcl_Obj *const objv[]) +// { +// PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; +// PyObject *args, *res; +// int i; +// Tcl_Obj *obj_res; + +// ENTER_PYTHON + +// /* Create argument tuple (objv1, ..., objvN) */ +// if (!(args = PyTuple_New(objc - 1))) +// return PythonCmd_Error(interp); + +// for (i = 0; i < (objc - 1); i++) { +// PyObject *s = unicodeFromTclObj(objv[i + 1]); +// if (!s) { +// Py_DECREF(args); +// return PythonCmd_Error(interp); +// } +// PyTuple_SET_ITEM(args, i, s); +// } + +// res = PyObject_Call(data->func, args, NULL); +// Py_DECREF(args); + +// if (res == NULL) +// return PythonCmd_Error(interp); + +// obj_res = AsObj(res); +// if (obj_res == NULL) { +// Py_DECREF(res); +// return PythonCmd_Error(interp); +// } +// Tcl_SetObjResult(interp, obj_res); +// Py_DECREF(res); + +// LEAVE_PYTHON + +// return TCL_OK; +// } + + +// static void +// PythonCmdDelete(ClientData clientData) +// { +// PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; + +// ENTER_PYTHON +// Py_XDECREF(data->self); +// Py_XDECREF(data->func); +// PyMem_DEL(data); +// LEAVE_PYTHON +// } + + + + +// TCL_DECLARE_MUTEX(command_mutex) + +// typedef struct CommandEvent{ +// Tcl_Event ev; +// Tcl_Interp* interp; +// const char *name; +// int create; +// int *status; +// ClientData *data; +// Tcl_Condition *done; +// } CommandEvent; + +// static int +// Tkapp_CommandProc(CommandEvent *ev, int flags) +// { +// if (ev->create) +// *ev->status = Tcl_CreateObjCommand( +// ev->interp, ev->name, PythonCmd, +// ev->data, PythonCmdDelete) == NULL; +// else +// *ev->status = Tcl_DeleteCommand(ev->interp, ev->name); +// Tcl_MutexLock(&command_mutex); +// Tcl_ConditionNotify(ev->done); +// Tcl_MutexUnlock(&command_mutex); +// return 1; +// } + +// /*[clinic input] +// _tkinter.tkapp.createcommand + +// name: str +// func: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, +// PyObject *func) +// /*[clinic end generated code: output=2a1c79a4ee2af410 input=255785cb70edc6a0]*/ +// { +// PythonCmd_ClientData *data; +// int err; + +// CHECK_STRING_LENGTH(name); +// if (!PyCallable_Check(func)) { +// PyErr_SetString(PyExc_TypeError, "command not callable"); +// return NULL; +// } + +// if (self->threaded && self->thread_id != Tcl_GetCurrentThread() && +// !WaitForMainloop(self)) +// return NULL; + +// data = PyMem_NEW(PythonCmd_ClientData, 1); +// if (!data) +// return PyErr_NoMemory(); +// Py_INCREF(self); +// Py_INCREF(func); +// data->self = (PyObject *) self; +// data->func = func; +// if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { +// Tcl_Condition cond = NULL; +// CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); +// if (ev == NULL) { +// PyErr_NoMemory(); +// PyMem_DEL(data); +// return NULL; +// } +// ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; +// ev->interp = self->interp; +// ev->create = 1; +// ev->name = name; +// ev->data = (ClientData)data; +// ev->status = &err; +// ev->done = &cond; +// Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex); +// Tcl_ConditionFinalize(&cond); +// } +// else +// { +// ENTER_TCL +// err = Tcl_CreateObjCommand( +// Tkapp_Interp(self), name, PythonCmd, +// (ClientData)data, PythonCmdDelete) == NULL; +// LEAVE_TCL +// } +// if (err) { +// PyErr_SetString(Tkinter_TclError, "can't create Tcl command"); +// PyMem_DEL(data); +// return NULL; +// } + +// Py_RETURN_NONE; +// } + + + +// /*[clinic input] +// _tkinter.tkapp.deletecommand + +// name: str +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name) +// /*[clinic end generated code: output=a67e8cb5845e0d2d input=53e9952eae1f85f5]*/ +// { +// int err; + +// CHECK_STRING_LENGTH(name); + +// if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { +// Tcl_Condition cond = NULL; +// CommandEvent *ev; +// ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); +// if (ev == NULL) { +// PyErr_NoMemory(); +// return NULL; +// } +// ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; +// ev->interp = self->interp; +// ev->create = 0; +// ev->name = name; +// ev->status = &err; +// ev->done = &cond; +// Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, +// &command_mutex); +// Tcl_ConditionFinalize(&cond); +// } +// else +// { +// ENTER_TCL +// err = Tcl_DeleteCommand(self->interp, name); +// LEAVE_TCL +// } +// if (err == -1) { +// PyErr_SetString(Tkinter_TclError, "can't delete Tcl command"); +// return NULL; +// } +// Py_RETURN_NONE; +// } + + + +// #ifdef HAVE_CREATEFILEHANDLER +// /** File Handler **/ + +// typedef struct _fhcdata { +// PyObject *func; +// PyObject *file; +// int id; +// struct _fhcdata *next; +// } FileHandler_ClientData; + +// static FileHandler_ClientData *HeadFHCD; + +// static FileHandler_ClientData * +// NewFHCD(PyObject *func, PyObject *file, int id) +// { +// FileHandler_ClientData *p; +// p = PyMem_NEW(FileHandler_ClientData, 1); +// if (p != NULL) { +// Py_XINCREF(func); +// Py_XINCREF(file); +// p->func = func; +// p->file = file; +// p->id = id; +// p->next = HeadFHCD; +// HeadFHCD = p; +// } +// return p; +// } + +// static void +// DeleteFHCD(int id) +// { +// FileHandler_ClientData *p, **pp; + +// pp = &HeadFHCD; +// while ((p = *pp) != NULL) { +// if (p->id == id) { +// *pp = p->next; +// Py_XDECREF(p->func); +// Py_XDECREF(p->file); +// PyMem_DEL(p); +// } +// else +// pp = &p->next; +// } +// } + +// static void +// FileHandler(ClientData clientData, int mask) +// { +// FileHandler_ClientData *data = (FileHandler_ClientData *)clientData; +// PyObject *func, *file, *res; + +// ENTER_PYTHON +// func = data->func; +// file = data->file; + +// res = PyObject_CallFunction(func, "Oi", file, mask); +// if (res == NULL) { +// errorInCmd = 1; +// PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); +// } +// Py_XDECREF(res); +// LEAVE_PYTHON +// } + +// /*[clinic input] +// _tkinter.tkapp.createfilehandler + +// file: object +// mask: int +// func: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file, +// int mask, PyObject *func) +// /*[clinic end generated code: output=f73ce82de801c353 input=84943a5286e47947]*/ +// { +// FileHandler_ClientData *data; +// int tfile; + +// CHECK_TCL_APPARTMENT; + +// tfile = PyObject_AsFileDescriptor(file); +// if (tfile < 0) +// return NULL; +// if (!PyCallable_Check(func)) { +// PyErr_SetString(PyExc_TypeError, "bad argument list"); +// return NULL; +// } + +// data = NewFHCD(func, file, tfile); +// if (data == NULL) +// return NULL; + +// /* Ought to check for null Tcl_File object... */ +// ENTER_TCL +// Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data); +// LEAVE_TCL +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _tkinter.tkapp.deletefilehandler + +// file: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_deletefilehandler(TkappObject *self, PyObject *file) +// /*[clinic end generated code: output=b53cc96ebf9476fd input=abbec19d66312e2a]*/ +// { +// int tfile; + +// CHECK_TCL_APPARTMENT; + +// tfile = PyObject_AsFileDescriptor(file); +// if (tfile < 0) +// return NULL; + +// DeleteFHCD(tfile); + +// /* Ought to check for null Tcl_File object... */ +// ENTER_TCL +// Tcl_DeleteFileHandler(tfile); +// LEAVE_TCL +// Py_RETURN_NONE; +// } +// #endif /* HAVE_CREATEFILEHANDLER */ + + +// /**** Tktt Object (timer token) ****/ + +// static PyObject *Tktt_Type; + +// typedef struct { +// PyObject_HEAD +// Tcl_TimerToken token; +// PyObject *func; +// } TkttObject; + +// /*[clinic input] +// _tkinter.tktimertoken.deletetimerhandler + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self) +// /*[clinic end generated code: output=bd7fe17f328cfa55 input=40bd070ff85f5cf3]*/ +// { +// TkttObject *v = self; +// PyObject *func = v->func; + +// if (v->token != NULL) { +// Tcl_DeleteTimerHandler(v->token); +// v->token = NULL; +// } +// if (func != NULL) { +// v->func = NULL; +// Py_DECREF(func); +// Py_DECREF(v); /* See Tktt_New() */ +// } +// Py_RETURN_NONE; +// } + +// static TkttObject * +// Tktt_New(PyObject *func) +// { +// TkttObject *v; + +// v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type); +// if (v == NULL) +// return NULL; + +// Py_INCREF(func); +// v->token = NULL; +// v->func = func; + +// /* Extra reference, deleted when called or when handler is deleted */ +// Py_INCREF(v); +// return v; +// } + +// static void +// Tktt_Dealloc(PyObject *self) +// { +// TkttObject *v = (TkttObject *)self; +// PyObject *func = v->func; +// PyObject *tp = (PyObject *) Py_TYPE(self); + +// Py_XDECREF(func); + +// PyObject_Del(self); +// Py_DECREF(tp); +// } + +// static PyObject * +// Tktt_Repr(PyObject *self) +// { +// TkttObject *v = (TkttObject *)self; +// return PyUnicode_FromFormat("", +// v, +// v->func == NULL ? ", handler deleted" : ""); +// } + +// /** Timer Handler **/ + +// static void +// TimerHandler(ClientData clientData) +// { +// TkttObject *v = (TkttObject *)clientData; +// PyObject *func = v->func; +// PyObject *res; + +// if (func == NULL) +// return; + +// v->func = NULL; + +// ENTER_PYTHON + +// res = _PyObject_CallNoArg(func); +// Py_DECREF(func); +// Py_DECREF(v); /* See Tktt_New() */ + +// if (res == NULL) { +// errorInCmd = 1; +// PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); +// } +// else +// Py_DECREF(res); + +// LEAVE_PYTHON +// } + +// /*[clinic input] +// _tkinter.tkapp.createtimerhandler + +// milliseconds: int +// func: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, +// PyObject *func) +// /*[clinic end generated code: output=2da5959b9d031911 input=ba6729f32f0277a5]*/ +// { +// TkttObject *v; + +// if (!PyCallable_Check(func)) { +// PyErr_SetString(PyExc_TypeError, "bad argument list"); +// return NULL; +// } + +// CHECK_TCL_APPARTMENT; + +// v = Tktt_New(func); +// if (v) { +// v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, +// (ClientData)v); +// } + +// return (PyObject *) v; +// } + + +// /** Event Loop **/ + +// /*[clinic input] +// _tkinter.tkapp.mainloop + +// threshold: int = 0 +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold) +// /*[clinic end generated code: output=0ba8eabbe57841b0 input=036bcdcf03d5eca0]*/ +// { +// PyThreadState *tstate = PyThreadState_Get(); + +// CHECK_TCL_APPARTMENT; +// self->dispatching = 1; + +// quitMainLoop = 0; +// while (Tk_GetNumMainWindows() > threshold && +// !quitMainLoop && +// !errorInCmd) +// { +// int result; + +// if (self->threaded) { +// /* Allow other Python threads to run. */ +// ENTER_TCL +// result = Tcl_DoOneEvent(0); +// LEAVE_TCL +// } +// else { +// Py_BEGIN_ALLOW_THREADS +// if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); +// tcl_tstate = tstate; +// result = Tcl_DoOneEvent(TCL_DONT_WAIT); +// tcl_tstate = NULL; +// if(tcl_lock)PyThread_release_lock(tcl_lock); +// if (result == 0) +// Sleep(Tkinter_busywaitinterval); +// Py_END_ALLOW_THREADS +// } + +// if (PyErr_CheckSignals() != 0) { +// self->dispatching = 0; +// return NULL; +// } +// if (result < 0) +// break; +// } +// self->dispatching = 0; +// quitMainLoop = 0; + +// if (errorInCmd) { +// errorInCmd = 0; +// PyErr_Restore(excInCmd, valInCmd, trbInCmd); +// excInCmd = valInCmd = trbInCmd = NULL; +// return NULL; +// } +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _tkinter.tkapp.dooneevent + +// flags: int = 0 +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags) +// /*[clinic end generated code: output=27c6b2aa464cac29 input=6542b928e364b793]*/ +// { +// int rv; + +// ENTER_TCL +// rv = Tcl_DoOneEvent(flags); +// LEAVE_TCL +// return PyLong_FromLong(rv); +// } + +// /*[clinic input] +// _tkinter.tkapp.quit +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_quit_impl(TkappObject *self) +// /*[clinic end generated code: output=7f21eeff481f754f input=e03020dc38aff23c]*/ +// { +// quitMainLoop = 1; +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _tkinter.tkapp.interpaddr +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_interpaddr_impl(TkappObject *self) +// /*[clinic end generated code: output=6caaae3273b3c95a input=2dd32cbddb55a111]*/ +// { +// return PyLong_FromVoidPtr(Tkapp_Interp(self)); +// } + +// /*[clinic input] +// _tkinter.tkapp.loadtk +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_loadtk_impl(TkappObject *self) +// /*[clinic end generated code: output=e9e10a954ce46d2a input=b5e82afedd6354f0]*/ +// { +// Tcl_Interp *interp = Tkapp_Interp(self); +// const char * _tk_exists = NULL; +// int err; + +// #ifdef TKINTER_PROTECT_LOADTK +// /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the +// * first call failed. +// * To avoid the deadlock, we just refuse the second call through +// * a static variable. +// */ +// if (tk_load_failed) { +// PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG); +// return NULL; +// } +// #endif + +// /* We want to guard against calling Tk_Init() multiple times */ +// CHECK_TCL_APPARTMENT; +// ENTER_TCL +// err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version"); +// ENTER_OVERLAP +// if (err == TCL_ERROR) { +// /* This sets an exception, but we cannot return right +// away because we need to exit the overlap first. */ +// Tkinter_Error(self); +// } else { +// _tk_exists = Tcl_GetStringResult(Tkapp_Interp(self)); +// } +// LEAVE_OVERLAP_TCL +// if (err == TCL_ERROR) { +// return NULL; +// } +// if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { +// if (Tk_Init(interp) == TCL_ERROR) { +// Tkinter_Error(self); +// #ifdef TKINTER_PROTECT_LOADTK +// tk_load_failed = 1; +// #endif +// return NULL; +// } +// } +// Py_RETURN_NONE; +// } + +// static PyObject * +// Tkapp_WantObjects(PyObject *self, PyObject *args) +// { + +// int wantobjects = -1; +// if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects)) +// return NULL; +// if (wantobjects == -1) +// return PyBool_FromLong(((TkappObject*)self)->wantobjects); +// ((TkappObject*)self)->wantobjects = wantobjects; + +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _tkinter.tkapp.willdispatch + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_tkapp_willdispatch_impl(TkappObject *self) +// /*[clinic end generated code: output=0e3f46d244642155 input=d88f5970843d6dab]*/ +// { +// self->dispatching = 1; + +// Py_RETURN_NONE; +// } + + +// /**** Tkapp Type Methods ****/ + +// static void +// Tkapp_Dealloc(PyObject *self) +// { +// PyObject *tp = (PyObject *) Py_TYPE(self); +// /*CHECK_TCL_APPARTMENT;*/ +// ENTER_TCL +// Tcl_DeleteInterp(Tkapp_Interp(self)); +// LEAVE_TCL +// PyObject_Del(self); +// Py_DECREF(tp); +// DisableEventHook(); +// } + + + +// /**** Tkinter Module ****/ + +// typedef struct { +// PyObject* tuple; +// Py_ssize_t size; /* current size */ +// Py_ssize_t maxsize; /* allocated size */ +// } FlattenContext; + +// static int +// _bump(FlattenContext* context, Py_ssize_t size) +// { +// /* expand tuple to hold (at least) size new items. +// return true if successful, false if an exception was raised */ + +// Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */ + +// if (maxsize < context->size + size) +// maxsize = context->size + size; /* never overflows */ + +// context->maxsize = maxsize; + +// return _PyTuple_Resize(&context->tuple, maxsize) >= 0; +// } + +// static int +// _flatten1(FlattenContext* context, PyObject* item, int depth) +// { +// /* add tuple or list to argument tuple (recursively) */ + +// Py_ssize_t i, size; + +// if (depth > 1000) { +// PyErr_SetString(PyExc_ValueError, +// "nesting too deep in _flatten"); +// return 0; +// } else if (PyTuple_Check(item) || PyList_Check(item)) { +// size = PySequence_Fast_GET_SIZE(item); +// /* preallocate (assume no nesting) */ +// if (context->size + size > context->maxsize && +// !_bump(context, size)) +// return 0; +// /* copy items to output tuple */ +// for (i = 0; i < size; i++) { +// PyObject *o = PySequence_Fast_GET_ITEM(item, i); +// if (PyList_Check(o) || PyTuple_Check(o)) { +// if (!_flatten1(context, o, depth + 1)) +// return 0; +// } else if (o != Py_None) { +// if (context->size + 1 > context->maxsize && +// !_bump(context, 1)) +// return 0; +// Py_INCREF(o); +// PyTuple_SET_ITEM(context->tuple, +// context->size++, o); +// } +// } +// } else { +// PyErr_SetString(PyExc_TypeError, "argument must be sequence"); +// return 0; +// } +// return 1; +// } + +// /*[clinic input] +// _tkinter._flatten + +// item: object +// / + +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter__flatten(PyObject *module, PyObject *item) +// /*[clinic end generated code: output=cad02a3f97f29862 input=6b9c12260aa1157f]*/ +// { +// FlattenContext context; + +// context.maxsize = PySequence_Size(item); +// if (context.maxsize < 0) +// return NULL; +// if (context.maxsize == 0) +// return PyTuple_New(0); + +// context.tuple = PyTuple_New(context.maxsize); +// if (!context.tuple) +// return NULL; + +// context.size = 0; + +// if (!_flatten1(&context, item,0)) +// return NULL; + +// if (_PyTuple_Resize(&context.tuple, context.size)) +// return NULL; + +// return context.tuple; +// } + +// /*[clinic input] +// _tkinter.create + +// screenName: str(accept={str, NoneType}) = None +// baseName: str = "" +// className: str = "Tk" +// interactive: bool(accept={int}) = False +// wantobjects: bool(accept={int}) = False +// wantTk: bool(accept={int}) = True +// if false, then Tk_Init() doesn't get called +// sync: bool(accept={int}) = False +// if true, then pass -sync to wish +// use: str(accept={str, NoneType}) = None +// if not None, then pass -use to wish +// / + +// [clinic start generated code]*/ + +// 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) +// /*[clinic end generated code: output=e3315607648e6bb4 input=da9b17ee7358d862]*/ +// { +// /* XXX baseName is not used anymore; +// * try getting rid of it. */ +// CHECK_STRING_LENGTH(screenName); +// CHECK_STRING_LENGTH(baseName); +// CHECK_STRING_LENGTH(className); +// CHECK_STRING_LENGTH(use); + +// return (PyObject *) Tkapp_New(screenName, className, +// interactive, wantobjects, wantTk, +// sync, use); +// } + +// /*[clinic input] +// _tkinter.setbusywaitinterval + +// new_val: int +// / + +// Set the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter. + +// It should be set to a divisor of the maximum time between frames in an animation. +// [clinic start generated code]*/ + +// static PyObject * +// _tkinter_setbusywaitinterval_impl(PyObject *module, int new_val) +// /*[clinic end generated code: output=42bf7757dc2d0ab6 input=deca1d6f9e6dae47]*/ +// { +// if (new_val < 0) { +// PyErr_SetString(PyExc_ValueError, +// "busywaitinterval must be >= 0"); +// return NULL; +// } +// Tkinter_busywaitinterval = new_val; +// Py_RETURN_NONE; +// } + +// /*[clinic input] +// _tkinter.getbusywaitinterval -> int + +// Return the current busy-wait interval between successive calls to Tcl_DoOneEvent in a threaded Python interpreter. +// [clinic start generated code]*/ + +// static int +// _tkinter_getbusywaitinterval_impl(PyObject *module) +// /*[clinic end generated code: output=23b72d552001f5c7 input=a695878d2d576a84]*/ +// { +// return Tkinter_busywaitinterval; +// } + +// #include "clinic/_tkinter.c.h" + +// static PyMethodDef Tktt_methods[] = +// { +// _TKINTER_TKTIMERTOKEN_DELETETIMERHANDLER_METHODDEF +// {NULL, NULL} +// }; + +// static PyType_Slot Tktt_Type_slots[] = { +// {Py_tp_dealloc, Tktt_Dealloc}, +// {Py_tp_repr, Tktt_Repr}, +// {Py_tp_methods, Tktt_methods}, +// {0, 0} +// }; + +// static PyType_Spec Tktt_Type_spec = { +// "_tkinter.tktimertoken", +// sizeof(TkttObject), +// 0, +// Py_TPFLAGS_DEFAULT, +// Tktt_Type_slots, +// }; + + +// /**** Tkapp Method List ****/ + +// static PyMethodDef Tkapp_methods[] = +// { +// _TKINTER_TKAPP_WILLDISPATCH_METHODDEF +// {"wantobjects", Tkapp_WantObjects, METH_VARARGS}, +// {"call", Tkapp_Call, METH_VARARGS}, +// _TKINTER_TKAPP_EVAL_METHODDEF +// _TKINTER_TKAPP_EVALFILE_METHODDEF +// _TKINTER_TKAPP_RECORD_METHODDEF +// _TKINTER_TKAPP_ADDERRORINFO_METHODDEF +// {"setvar", Tkapp_SetVar, METH_VARARGS}, +// {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS}, +// {"getvar", Tkapp_GetVar, METH_VARARGS}, +// {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS}, +// {"unsetvar", Tkapp_UnsetVar, METH_VARARGS}, +// {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS}, +// _TKINTER_TKAPP_GETINT_METHODDEF +// _TKINTER_TKAPP_GETDOUBLE_METHODDEF +// _TKINTER_TKAPP_GETBOOLEAN_METHODDEF +// _TKINTER_TKAPP_EXPRSTRING_METHODDEF +// _TKINTER_TKAPP_EXPRLONG_METHODDEF +// _TKINTER_TKAPP_EXPRDOUBLE_METHODDEF +// _TKINTER_TKAPP_EXPRBOOLEAN_METHODDEF +// _TKINTER_TKAPP_SPLITLIST_METHODDEF +// _TKINTER_TKAPP_SPLIT_METHODDEF +// _TKINTER_TKAPP_CREATECOMMAND_METHODDEF +// _TKINTER_TKAPP_DELETECOMMAND_METHODDEF +// _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF +// _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF +// _TKINTER_TKAPP_CREATETIMERHANDLER_METHODDEF +// _TKINTER_TKAPP_MAINLOOP_METHODDEF +// _TKINTER_TKAPP_DOONEEVENT_METHODDEF +// _TKINTER_TKAPP_QUIT_METHODDEF +// _TKINTER_TKAPP_INTERPADDR_METHODDEF +// _TKINTER_TKAPP_LOADTK_METHODDEF +// {NULL, NULL} +// }; + +// static PyType_Slot Tkapp_Type_slots[] = { +// {Py_tp_dealloc, Tkapp_Dealloc}, +// {Py_tp_methods, Tkapp_methods}, +// {0, 0} +// }; + + +// static PyType_Spec Tkapp_Type_spec = { +// "_tkinter.tkapp", +// sizeof(TkappObject), +// 0, +// Py_TPFLAGS_DEFAULT, +// Tkapp_Type_slots, +// }; + +// static PyMethodDef moduleMethods[] = +// { +// _TKINTER__FLATTEN_METHODDEF +// _TKINTER_CREATE_METHODDEF +// _TKINTER_SETBUSYWAITINTERVAL_METHODDEF +// _TKINTER_GETBUSYWAITINTERVAL_METHODDEF +// {NULL, NULL} +// }; + +// #ifdef WAIT_FOR_STDIN + +// static int stdin_ready = 0; + +// #ifndef MS_WINDOWS +// static void +// MyFileProc(void *clientData, int mask) +// { +// stdin_ready = 1; +// } +// #endif + +// static PyThreadState *event_tstate = NULL; + +// static int +// EventHook(void) +// { +// #ifndef MS_WINDOWS +// int tfile; +// #endif +// PyEval_RestoreThread(event_tstate); +// stdin_ready = 0; +// errorInCmd = 0; +// #ifndef MS_WINDOWS +// tfile = fileno(stdin); +// Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL); +// #endif +// while (!errorInCmd && !stdin_ready) { +// int result; +// #ifdef MS_WINDOWS +// if (_kbhit()) { +// stdin_ready = 1; +// break; +// } +// #endif +// Py_BEGIN_ALLOW_THREADS +// if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); +// tcl_tstate = event_tstate; + +// result = Tcl_DoOneEvent(TCL_DONT_WAIT); + +// tcl_tstate = NULL; +// if(tcl_lock)PyThread_release_lock(tcl_lock); +// if (result == 0) +// Sleep(Tkinter_busywaitinterval); +// Py_END_ALLOW_THREADS + +// if (result < 0) +// break; +// } +// #ifndef MS_WINDOWS +// Tcl_DeleteFileHandler(tfile); +// #endif +// if (errorInCmd) { +// errorInCmd = 0; +// PyErr_Restore(excInCmd, valInCmd, trbInCmd); +// excInCmd = valInCmd = trbInCmd = NULL; +// PyErr_Print(); +// } +// PyEval_SaveThread(); +// return 0; +// } + +// #endif + +// static void +// EnableEventHook(void) +// { +// #ifdef WAIT_FOR_STDIN +// if (PyOS_InputHook == NULL) { +// event_tstate = PyThreadState_Get(); +// PyOS_InputHook = EventHook; +// } +// #endif +// } + +// static void +// DisableEventHook(void) +// { +// #ifdef WAIT_FOR_STDIN +// if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) { +// PyOS_InputHook = NULL; +// } +// #endif +// } + + +// static struct PyModuleDef _tkintermodule = { +// PyModuleDef_HEAD_INIT, +// "_tkinter", +// NULL, +// -1, +// moduleMethods, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit__tkinter(void) +// { +// PyObject *m, *uexe, *cexe, *o; + +// tcl_lock = PyThread_allocate_lock(); +// if (tcl_lock == NULL) +// return NULL; + +// m = PyModule_Create(&_tkintermodule); +// if (m == NULL) +// return NULL; + +// o = PyErr_NewException("_tkinter.TclError", NULL, NULL); +// if (o == NULL) { +// Py_DECREF(m); +// return NULL; +// } +// Py_INCREF(o); +// if (PyModule_AddObject(m, "TclError", o)) { +// Py_DECREF(o); +// Py_DECREF(m); +// return NULL; +// } +// Tkinter_TclError = o; + +// if (PyModule_AddIntConstant(m, "READABLE", TCL_READABLE)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "WRITABLE", TCL_WRITABLE)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "EXCEPTION", TCL_EXCEPTION)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "WINDOW_EVENTS", TCL_WINDOW_EVENTS)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "FILE_EVENTS", TCL_FILE_EVENTS)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "TIMER_EVENTS", TCL_TIMER_EVENTS)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "IDLE_EVENTS", TCL_IDLE_EVENTS)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "ALL_EVENTS", TCL_ALL_EVENTS)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddIntConstant(m, "DONT_WAIT", TCL_DONT_WAIT)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddStringConstant(m, "TK_VERSION", TK_VERSION)) { +// Py_DECREF(m); +// return NULL; +// } +// if (PyModule_AddStringConstant(m, "TCL_VERSION", TCL_VERSION)) { +// Py_DECREF(m); +// return NULL; +// } + +// o = PyType_FromSpec(&Tkapp_Type_spec); +// if (o == NULL) { +// Py_DECREF(m); +// return NULL; +// } +// ((PyTypeObject *)o)->tp_new = NULL; +// if (PyModule_AddObject(m, "TkappType", o)) { +// Py_DECREF(o); +// Py_DECREF(m); +// return NULL; +// } +// Tkapp_Type = o; + +// o = PyType_FromSpec(&Tktt_Type_spec); +// if (o == NULL) { +// Py_DECREF(m); +// return NULL; +// } +// ((PyTypeObject *)o)->tp_new = NULL; +// if (PyModule_AddObject(m, "TkttType", o)) { +// Py_DECREF(o); +// Py_DECREF(m); +// return NULL; +// } +// Tktt_Type = o; + +// o = PyType_FromSpec(&PyTclObject_Type_spec); +// if (o == NULL) { +// Py_DECREF(m); +// return NULL; +// } +// ((PyTypeObject *)o)->tp_new = NULL; +// if (PyModule_AddObject(m, "Tcl_Obj", o)) { +// Py_DECREF(o); +// Py_DECREF(m); +// return NULL; +// } +// PyTclObject_Type = o; + +// #ifdef TK_AQUA +// /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems +// * start waking up. Note that Tcl_FindExecutable will do this, this +// * code must be above it! The original warning from +// * tkMacOSXAppInit.c is copied below. +// * +// * NB - You have to swap in the Tk Notifier BEFORE you start up the +// * Tcl interpreter for now. It probably should work to do this +// * in the other order, but for now it doesn't seem to. +// * +// */ +// Tk_MacOSXSetupTkNotifier(); +// #endif + + +// /* This helps the dynamic loader; in Unicode aware Tcl versions +// it also helps Tcl find its encodings. */ +// uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1); +// if (uexe) { +// cexe = PyUnicode_EncodeFSDefault(uexe); +// if (cexe) { +// #ifdef MS_WINDOWS +// int set_var = 0; +// PyObject *str_path; +// wchar_t *wcs_path; +// DWORD ret; + +// ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0); + +// if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { +// str_path = _get_tcl_lib_path(); +// if (str_path == NULL && PyErr_Occurred()) { +// Py_DECREF(m); +// return NULL; +// } +// if (str_path != NULL) { +// wcs_path = PyUnicode_AsWideCharString(str_path, NULL); +// if (wcs_path == NULL) { +// Py_DECREF(m); +// return NULL; +// } +// SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); +// set_var = 1; +// } +// } + +// Tcl_FindExecutable(PyBytes_AS_STRING(cexe)); + +// if (set_var) { +// SetEnvironmentVariableW(L"TCL_LIBRARY", NULL); +// PyMem_Free(wcs_path); +// } +// #else +// Tcl_FindExecutable(PyBytes_AS_STRING(cexe)); +// #endif /* MS_WINDOWS */ +// } +// Py_XDECREF(cexe); +// Py_DECREF(uexe); +// } + +// if (PyErr_Occurred()) { +// Py_DECREF(m); +// return NULL; +// } + +// #if 0 +// /* This was not a good idea; through bindings, +// Tcl_Finalize() may invoke Python code but at that point the +// interpreter and thread state have already been destroyed! */ +// Py_AtExit(Tcl_Finalize); +// #endif +// return m; +// } diff --git a/python/Modules/_tracemalloc.c b/python/Modules/_tracemalloc.c new file mode 100755 index 0000000..cbcf55f --- /dev/null +++ b/python/Modules/_tracemalloc.c @@ -0,0 +1,1770 @@ +#include "Python.h" +#include "pycore_traceback.h" +#include "hashtable.h" +#include "frameobject.h" +#include "pythread.h" +#include "osdefs.h" + +#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 + +/* 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. */ +typedef struct +#ifdef __GNUC__ +__attribute__((packed)) +#endif +{ + uintptr_t ptr; + unsigned int domain; +} pointer_t; + +/* Pack the frame_t structure to reduce the memory footprint on 64-bit + architectures: 12 bytes instead of 16. */ +typedef struct +#ifdef __GNUC__ +__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; +#ifdef _MSC_VER +#pragma pack(pop) +#endif + + +typedef struct { + Py_uhash_t hash; + int nframe; + frame_t frames[1]; +} traceback_t; + +#define TRACEBACK_SIZE(NFRAME) \ + (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) + +#define MAX_NFRAME \ + ((INT_MAX - (int)sizeof(traceback_t)) / (int)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; + +/* pointer (void*) => trace (trace_t). + Protected by TABLES_LOCK(). */ +static _Py_hashtable_t *tracemalloc_traces = 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 +hashtable_hash_pyobject(_Py_hashtable_t *ht, const void *pkey) +{ + PyObject *obj; + + _Py_HASHTABLE_READ_KEY(ht, pkey, obj); + return PyObject_Hash(obj); +} + + +static int +hashtable_compare_unicode(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) +{ + PyObject *key1, *key2; + + _Py_HASHTABLE_READ_KEY(ht, pkey, key1); + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, key2); + + if (key1 != NULL && key2 != NULL) + return (PyUnicode_Compare(key1, key2) == 0); + else + return key1 == key2; +} + + +static Py_uhash_t +hashtable_hash_pointer_t(_Py_hashtable_t *ht, const void *pkey) +{ + pointer_t ptr; + Py_uhash_t hash; + + _Py_HASHTABLE_READ_KEY(ht, pkey, ptr); + + hash = (Py_uhash_t)_Py_HashPointer((void*)ptr.ptr); + hash ^= ptr.domain; + return hash; +} + + +static int +hashtable_compare_pointer_t(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) +{ + pointer_t ptr1, ptr2; + + _Py_HASHTABLE_READ_KEY(ht, pkey, ptr1); + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, ptr2); + + /* compare pointer before domain, because pointer is more likely to be + different */ + return (ptr1.ptr == ptr2.ptr && ptr1.domain == ptr2.domain); + +} + + +static _Py_hashtable_t * +hashtable_new(size_t key_size, size_t data_size, + _Py_hashtable_hash_func hash_func, + _Py_hashtable_compare_func compare_func) +{ + _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; + return _Py_hashtable_new_full(key_size, data_size, 0, + hash_func, compare_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_hash_traceback(_Py_hashtable_t *ht, const void *pkey) +{ + traceback_t *traceback; + + _Py_HASHTABLE_READ_KEY(ht, pkey, traceback); + return traceback->hash; +} + + +static int +hashtable_compare_traceback(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) +{ + traceback_t *traceback1, *traceback2; + const frame_t *frame1, *frame2; + int i; + + _Py_HASHTABLE_READ_KEY(ht, pkey, traceback1); + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, traceback2); + + if (traceback1->nframe != traceback2->nframe) + return 0; + + for (i=0; i < traceback1->nframe; i++) { + frame1 = &traceback1->frames[i]; + frame2 = &traceback2->frames[i]; + + if (frame1->lineno != frame2->lineno) + 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) +{ + PyCodeObject *code; + PyObject *filename; + _Py_hashtable_entry_t *entry; + int lineno; + + frame->filename = unknown_filename; + lineno = PyFrame_GetLineNumber(pyframe); + if (lineno < 0) + lineno = 0; + frame->lineno = (unsigned int)lineno; + + code = pyframe->f_code; + if (code == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to get the code object of the frame"); +#endif + return; + } + + if (code->co_filename == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to get the filename of the code object"); +#endif + return; + } + + filename = code->co_filename; + assert(filename != NULL); + if (filename == NULL) + 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 */ + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_filenames, filename); + if (entry != NULL) { + _Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_filenames, entry, filename); + } + else { + /* tracemalloc_filenames is responsible to keep a reference + to the filename */ + Py_INCREF(filename); + if (_Py_HASHTABLE_SET_NODATA(tracemalloc_filenames, filename) < 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); + } + x += 97531UL; + return x; +} + + +static void +traceback_get_frames(traceback_t *traceback) +{ + PyThreadState *tstate; + PyFrameObject *pyframe; + + tstate = PyGILState_GetThisThreadState(); + if (tstate == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to get the current thread state"); +#endif + return; + } + + for (pyframe = tstate->frame; pyframe != NULL; pyframe = pyframe->f_back) { + tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]); + assert(traceback->frames[traceback->nframe].filename != NULL); + traceback->nframe++; + if (traceback->nframe == _Py_tracemalloc_config.max_nframe) + break; + } +} + + +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_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) { + _Py_HASHTABLE_ENTRY_READ_KEY(tracemalloc_tracebacks, entry, traceback); + } + 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_NODATA(tracemalloc_tracebacks, copy) < 0) { + raw_free(copy); +#ifdef TRACE_DEBUG + tracemalloc_error("failed to intern the traceback: putdata failed"); +#endif + return NULL; + } + traceback = copy; + } + return traceback; +} + + +static int +tracemalloc_use_domain_cb(_Py_hashtable_t *old_traces, + _Py_hashtable_entry_t *entry, void *user_data) +{ + uintptr_t ptr; + pointer_t key; + _Py_hashtable_t *new_traces = (_Py_hashtable_t *)user_data; + const void *pdata = _Py_HASHTABLE_ENTRY_PDATA(old_traces, entry); + + _Py_HASHTABLE_ENTRY_READ_KEY(old_traces, entry, ptr); + key.ptr = ptr; + key.domain = DEFAULT_DOMAIN; + + return _Py_hashtable_set(new_traces, + sizeof(key), &key, + old_traces->data_size, pdata); +} + + +/* Convert tracemalloc_traces from compact key (uintptr_t) to pointer_t key. + * Return 0 on success, -1 on error. */ +static int +tracemalloc_use_domain(void) +{ + _Py_hashtable_t *new_traces = NULL; + + assert(!_Py_tracemalloc_config.use_domain); + + new_traces = hashtable_new(sizeof(pointer_t), + sizeof(trace_t), + hashtable_hash_pointer_t, + hashtable_compare_pointer_t); + if (new_traces == NULL) { + return -1; + } + + if (_Py_hashtable_foreach(tracemalloc_traces, tracemalloc_use_domain_cb, + new_traces) < 0) + { + _Py_hashtable_destroy(new_traces); + return -1; + } + + _Py_hashtable_destroy(tracemalloc_traces); + tracemalloc_traces = new_traces; + + _Py_tracemalloc_config.use_domain = 1; + + return 0; +} + + +static void +tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr) +{ + trace_t trace; + int removed; + + assert(_Py_tracemalloc_config.tracing); + + if (_Py_tracemalloc_config.use_domain) { + pointer_t key = {ptr, domain}; + removed = _Py_HASHTABLE_POP(tracemalloc_traces, key, trace); + } + else { + removed = _Py_HASHTABLE_POP(tracemalloc_traces, ptr, trace); + } + if (!removed) { + return; + } + + assert(tracemalloc_traced_memory >= trace.size); + tracemalloc_traced_memory -= trace.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) +{ + pointer_t key = {ptr, domain}; + traceback_t *traceback; + trace_t trace; + _Py_hashtable_entry_t* entry; + int res; + + assert(_Py_tracemalloc_config.tracing); + + traceback = traceback_new(); + if (traceback == NULL) { + return -1; + } + + if (!_Py_tracemalloc_config.use_domain && domain != DEFAULT_DOMAIN) { + /* first trace using a non-zero domain whereas traces use compact + (uintptr_t) keys: switch to pointer_t keys. */ + if (tracemalloc_use_domain() < 0) { + return -1; + } + } + + if (_Py_tracemalloc_config.use_domain) { + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, key); + } + else { + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, ptr); + } + + if (entry != NULL) { + /* the memory block is already tracked */ + _Py_HASHTABLE_ENTRY_READ_DATA(tracemalloc_traces, entry, trace); + assert(tracemalloc_traced_memory >= trace.size); + tracemalloc_traced_memory -= trace.size; + + trace.size = size; + trace.traceback = traceback; + _Py_HASHTABLE_ENTRY_WRITE_DATA(tracemalloc_traces, entry, trace); + } + else { + trace.size = size; + trace.traceback = traceback; + + if (_Py_tracemalloc_config.use_domain) { + res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace); + } + else { + res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); + } + if (res != 0) { + 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 + a trace at address (domain, 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. */ + Py_UNREACHABLE(); + } + 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 */ + + +static int +tracemalloc_clear_filename(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, + void *user_data) +{ + PyObject *filename; + + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, filename); + Py_DECREF(filename); + return 0; +} + + +static int +traceback_free_traceback(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, + void *user_data) +{ + traceback_t *traceback; + + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, traceback); + raw_free(traceback); + return 0; +} + + +/* reentrant flag must be set to call this function and GIL must be held */ +static void +tracemalloc_clear_traces(void) +{ + /* The GIL protects variables againt concurrent access */ + assert(PyGILState_Check()); + + TABLES_LOCK(); + _Py_hashtable_clear(tracemalloc_traces); + tracemalloc_traced_memory = 0; + tracemalloc_peak_traced_memory = 0; + TABLES_UNLOCK(); + + _Py_hashtable_foreach(tracemalloc_tracebacks, traceback_free_traceback, NULL); + _Py_hashtable_clear(tracemalloc_tracebacks); + + _Py_hashtable_foreach(tracemalloc_filenames, tracemalloc_clear_filename, NULL); + _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; + } + + 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 + + tracemalloc_filenames = hashtable_new(sizeof(PyObject *), 0, + hashtable_hash_pyobject, + hashtable_compare_unicode); + + tracemalloc_tracebacks = hashtable_new(sizeof(traceback_t *), 0, + hashtable_hash_traceback, + hashtable_compare_traceback); + + if (_Py_tracemalloc_config.use_domain) { + tracemalloc_traces = hashtable_new(sizeof(pointer_t), + sizeof(trace_t), + hashtable_hash_pointer_t, + hashtable_compare_pointer_t); + } + else { + tracemalloc_traces = hashtable_new(sizeof(uintptr_t), + sizeof(trace_t), + _Py_hashtable_hash_ptr, + _Py_hashtable_compare_direct); + } + + if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL + || tracemalloc_traces == NULL) { + PyErr_NoMemory(); + return -1; + } + + unknown_filename = PyUnicode_FromString(""); + if (unknown_filename == NULL) + return -1; + PyUnicode_InternInPlace(&unknown_filename); + + tracemalloc_empty_traceback.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); + + _Py_tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED; + return 0; +} + + +static void +tracemalloc_deinit(void) +{ + if (_Py_tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED) + return; + _Py_tracemalloc_config.initialized = TRACEMALLOC_FINALIZED; + + tracemalloc_stop(); + + /* destroy hash tables */ + _Py_hashtable_destroy(tracemalloc_tracebacks); + _Py_hashtable_destroy(tracemalloc_filenames); + _Py_hashtable_destroy(tracemalloc_traces); + +#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 || max_nframe > MAX_NFRAME) { + PyErr_Format(PyExc_ValueError, + "the number of frames must be in range [1; %i]", + (int)MAX_NFRAME); + return -1; + } + + if (tracemalloc_init() < 0) { + return -1; + } + + if (_Py_tracemalloc_config.tracing) { + /* hook already installed: do nothing */ + return 0; + } + + assert(1 <= max_nframe && max_nframe <= MAX_NFRAME); + _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 */ + _Py_tracemalloc_config.tracing = 1; + + return 0; +} + + +static void +tracemalloc_stop(void) +{ + if (!_Py_tracemalloc_config.tracing) + 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]*/ +{ + 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) +{ + int i; + PyObject *frames, *frame; + + if (intern_table != NULL) { + if (_Py_HASHTABLE_GET(intern_table, traceback, frames)) { + Py_INCREF(frames); + return frames; + } + } + + frames = PyTuple_New(traceback->nframe); + if (frames == NULL) + return NULL; + + for (i=0; i < traceback->nframe; i++) { + 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 (_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* +trace_to_pyobject(unsigned int domain, trace_t *trace, + _Py_hashtable_t *intern_tracebacks) +{ + PyObject *trace_obj = NULL; + PyObject *obj; + + trace_obj = PyTuple_New(3); + 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); + + return trace_obj; +} + + +typedef struct { + _Py_hashtable_t *traces; + _Py_hashtable_t *tracebacks; + PyObject *list; +} get_traces_t; + +static int +tracemalloc_get_traces_fill(_Py_hashtable_t *traces, _Py_hashtable_entry_t *entry, + void *user_data) +{ + get_traces_t *get_traces = user_data; + unsigned int domain; + trace_t trace; + PyObject *tracemalloc_obj; + int res; + + if (_Py_tracemalloc_config.use_domain) { + pointer_t key; + _Py_HASHTABLE_ENTRY_READ_KEY(traces, entry, key); + domain = key.domain; + } + else { + domain = DEFAULT_DOMAIN; + } + _Py_HASHTABLE_ENTRY_READ_DATA(traces, entry, trace); + + tracemalloc_obj = trace_to_pyobject(domain, &trace, get_traces->tracebacks); + if (tracemalloc_obj == NULL) + return 1; + + res = PyList_Append(get_traces->list, tracemalloc_obj); + Py_DECREF(tracemalloc_obj); + if (res < 0) + return 1; + + return 0; +} + + +static int +tracemalloc_pyobject_decref_cb(_Py_hashtable_t *tracebacks, + _Py_hashtable_entry_t *entry, + void *user_data) +{ + PyObject *obj; + _Py_HASHTABLE_ENTRY_READ_DATA(tracebacks, entry, obj); + Py_DECREF(obj); + return 0; +} + + + +/*[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; + int err; + + get_traces.traces = NULL; + 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 */ + get_traces.tracebacks = hashtable_new(sizeof(traceback_t *), + sizeof(PyObject *), + _Py_hashtable_hash_ptr, + _Py_hashtable_compare_direct); + if (get_traces.tracebacks == NULL) { + PyErr_NoMemory(); + goto error; + } + + TABLES_LOCK(); + get_traces.traces = _Py_hashtable_copy(tracemalloc_traces); + TABLES_UNLOCK(); + + if (get_traces.traces == NULL) { + PyErr_NoMemory(); + goto error; + } + + set_reentrant(1); + err = _Py_hashtable_foreach(get_traces.traces, + tracemalloc_get_traces_fill, &get_traces); + set_reentrant(0); + if (err) + goto error; + + goto finally; + +error: + Py_CLEAR(get_traces.list); + +finally: + if (get_traces.tracebacks != NULL) { + _Py_hashtable_foreach(get_traces.tracebacks, + tracemalloc_pyobject_decref_cb, NULL); + _Py_hashtable_destroy(get_traces.tracebacks); + } + if (get_traces.traces != NULL) { + _Py_hashtable_destroy(get_traces.traces); + } + + return get_traces.list; +} + + +static traceback_t* +tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr) +{ + trace_t trace; + int found; + + if (!_Py_tracemalloc_config.tracing) + return NULL; + + TABLES_LOCK(); + if (_Py_tracemalloc_config.use_domain) { + pointer_t key = {ptr, domain}; + found = _Py_HASHTABLE_GET(tracemalloc_traces, key, trace); + } + else { + found = _Py_HASHTABLE_GET(tracemalloc_traces, ptr, trace); + } + TABLES_UNLOCK(); + + if (!found) + 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); + if (PyType_IS_GC(type)) { + 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; + + 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]*/ +{ + return PyLong_FromLong(_Py_tracemalloc_config.max_nframe); +} + + + +/*[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); + 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); +} + + +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 + /* 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; + + 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) +{ + if (!_Py_tracemalloc_config.tracing) { + /* 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. + + Do nothing if tracemalloc is not tracing memory allocations + or if the object memory block is not already traced. */ +int +_PyTraceMalloc_NewReference(PyObject *op) +{ + assert(PyGILState_Check()); + + if (!_Py_tracemalloc_config.tracing) { + /* tracemalloc is not tracing: do nothing */ + return -1; + } + + uintptr_t ptr; + PyTypeObject *type = Py_TYPE(op); + if (PyType_IS_GC(type)) { + ptr = (uintptr_t)((char *)op - sizeof(PyGC_Head)); + } + else { + ptr = (uintptr_t)op; + } + + _Py_hashtable_entry_t* entry; + int res = -1; + + TABLES_LOCK(); + if (_Py_tracemalloc_config.use_domain) { + pointer_t key = {ptr, DEFAULT_DOMAIN}; + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, key); + } + else { + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, ptr); + } + + if (entry != NULL) { + /* update the traceback of the memory block */ + traceback_t *traceback = traceback_new(); + if (traceback != NULL) { + trace_t trace; + _Py_HASHTABLE_ENTRY_READ_DATA(tracemalloc_traces, entry, trace); + trace.traceback = traceback; + _Py_HASHTABLE_ENTRY_WRITE_DATA(tracemalloc_traces, entry, trace); + res = 0; + } + } + /* else: cannot track the object, its memory block size is unknown */ + TABLES_UNLOCK(); + + return res; +} + + +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/python/Modules/_uuidmodule.c b/python/Modules/_uuidmodule.c new file mode 100755 index 0000000..7156864 --- /dev/null +++ b/python/Modules/_uuidmodule.c @@ -0,0 +1,75 @@ +// /* +// * Python UUID module that wraps libuuid - +// * DCE compatible Universally Unique Identifier library. +// */ + +// #define PY_SSIZE_T_CLEAN + +// #include "Python.h" +// #ifdef HAVE_UUID_UUID_H +// #include +// #elif defined(HAVE_UUID_H) +// #include +// #endif + +// static PyObject * +// py_uuid_generate_time_safe(PyObject *Py_UNUSED(context), +// PyObject *Py_UNUSED(ignored)) +// { +// uuid_t uuid; +// #ifdef HAVE_UUID_GENERATE_TIME_SAFE +// int res; + +// res = uuid_generate_time_safe(uuid); +// return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res); +// #elif defined(HAVE_UUID_CREATE) +// uint32_t status; +// uuid_create(&uuid, &status); +// # if defined(HAVE_UUID_ENC_BE) +// unsigned char buf[sizeof(uuid)]; +// uuid_enc_be(buf, &uuid); +// return Py_BuildValue("y#i", buf, sizeof(uuid), (int) status); +// # else +// return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status); +// # endif +// #else +// uuid_generate_time(uuid); +// return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None); +// #endif +// } + + +// static PyMethodDef uuid_methods[] = { +// {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL}, +// {NULL, NULL, 0, NULL} /* sentinel */ +// }; + +// static struct PyModuleDef uuidmodule = { +// PyModuleDef_HEAD_INIT, +// .m_name = "_uuid", +// .m_size = -1, +// .m_methods = uuid_methods, +// }; + +// PyMODINIT_FUNC +// PyInit__uuid(void) +// { +// PyObject *mod; +// assert(sizeof(uuid_t) == 16); +// #ifdef HAVE_UUID_GENERATE_TIME_SAFE +// int has_uuid_generate_time_safe = 1; +// #else +// int has_uuid_generate_time_safe = 0; +// #endif +// mod = PyModule_Create(&uuidmodule); +// if (mod == NULL) { +// return NULL; +// } +// if (PyModule_AddIntConstant(mod, "has_uuid_generate_time_safe", +// has_uuid_generate_time_safe) < 0) { +// Py_DECREF(mod); +// return NULL; +// } + +// return mod; +// } diff --git a/python/Modules/_weakref.c b/python/Modules/_weakref.c new file mode 100755 index 0000000..c1238e0 --- /dev/null +++ b/python/Modules/_weakref.c @@ -0,0 +1,174 @@ +#include "Python.h" + + +#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} +}; + + +static struct PyModuleDef weakrefmodule = { + PyModuleDef_HEAD_INIT, + "_weakref", + "Weak-reference support module.", + -1, + weakref_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__weakref(void) +{ + PyObject *m; + + m = PyModule_Create(&weakrefmodule); + + if (m != NULL) { + Py_INCREF(&_PyWeakref_RefType); + PyModule_AddObject(m, "ref", + (PyObject *) &_PyWeakref_RefType); + Py_INCREF(&_PyWeakref_RefType); + PyModule_AddObject(m, "ReferenceType", + (PyObject *) &_PyWeakref_RefType); + Py_INCREF(&_PyWeakref_ProxyType); + PyModule_AddObject(m, "ProxyType", + (PyObject *) &_PyWeakref_ProxyType); + Py_INCREF(&_PyWeakref_CallableProxyType); + PyModule_AddObject(m, "CallableProxyType", + (PyObject *) &_PyWeakref_CallableProxyType); + } + return m; +} diff --git a/python/Modules/_winapi.c b/python/Modules/_winapi.c new file mode 100755 index 0000000..6cdd09e --- /dev/null +++ b/python/Modules/_winapi.c @@ -0,0 +1,2045 @@ +// /* +// * 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 http://www.python.org/2.4/license for licensing details. */ + +// #include "Python.h" +// #include "structmember.h" + +// #define WINDOWS_LEAN_AND_MEAN +// #include "windows.h" +// #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 *" "&OverlappedType" +// [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('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') + +// class LPVOID_return_converter(CReturnConverter): +// type = 'LPVOID' + +// def render(self, function, data): +// self.declare(data) +// 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 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 OverlappedType = { +// 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_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, &OverlappedType); +// 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] +// _winapi.CreateFileMapping -> HANDLE + +// file_handle: HANDLE +// security_attributes: LPSECURITY_ATTRIBUTES +// protect: DWORD +// max_size_high: DWORD +// max_size_low: DWORD +// name: LPCWSTR +// / +// [clinic start generated code]*/ + +// 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) +// /*[clinic end generated code: output=6c0a4d5cf7f6fcc6 input=3dc5cf762a74dee8]*/ +// { +// HANDLE handle; + +// Py_BEGIN_ALLOW_THREADS +// handle = CreateFileMappingW(file_handle, security_attributes, +// protect, max_size_high, max_size_low, +// 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_RawMalloc(rdb_size); +// if (rdb == NULL) +// goto cleanup; + +// memset(rdb, 0, rdb_size); +// 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; +// } + +// 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 +// desired_access: DWORD +// file_offset_high: DWORD +// file_offset_low: DWORD +// number_bytes: size_t +// / +// [clinic start generated code]*/ + +// static LPVOID +// _winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map, +// DWORD desired_access, DWORD file_offset_high, +// DWORD file_offset_low, size_t number_bytes) +// /*[clinic end generated code: output=f23b1ee4823663e3 input=177471073be1a103]*/ +// { +// LPVOID address; + +// Py_BEGIN_ALLOW_THREADS +// address = MapViewOfFile(file_map, desired_access, file_offset_high, +// file_offset_low, number_bytes); +// Py_END_ALLOW_THREADS + +// if (address == NULL) +// PyErr_SetFromWindowsErr(0); + +// return address; +// } + +// /*[clinic input] +// _winapi.OpenFileMapping -> HANDLE + +// desired_access: DWORD +// inherit_handle: BOOL +// name: LPCWSTR +// / +// [clinic start generated code]*/ + +// static HANDLE +// _winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access, +// BOOL inherit_handle, LPCWSTR name) +// /*[clinic end generated code: output=08cc44def1cb11f1 input=131f2a405359de7f]*/ +// { +// HANDLE handle; + +// Py_BEGIN_ALLOW_THREADS +// handle = OpenFileMappingW(desired_access, inherit_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.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); +// Py_END_ALLOW_THREADS +// 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; +// 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]; +// } +// } + +// 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; + +// 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] +// _winapi.VirtualQuerySize -> size_t + +// address: LPCVOID +// / +// [clinic start generated code]*/ + +// static size_t +// _winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address) +// /*[clinic end generated code: output=40c8e0ff5ec964df input=6b784a69755d0bb6]*/ +// { +// SIZE_T size_of_buf; +// MEMORY_BASIC_INFORMATION mem_basic_info; +// SIZE_T region_size; + +// Py_BEGIN_ALLOW_THREADS +// size_of_buf = VirtualQuery(address, &mem_basic_info, sizeof(mem_basic_info)); +// Py_END_ALLOW_THREADS + +// if (size_of_buf == 0) +// PyErr_SetFromWindowsErr(0); + +// region_size = mem_basic_info.RegionSize; +// return region_size; +// } + +// /*[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; +// 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 +// _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_MAPVIEWOFFILE_METHODDEF +// _WINAPI_OPENFILEMAPPING_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(&OverlappedType) < 0) +// return NULL; + +// m = PyModule_Create(&winapi_module); +// if (m == NULL) +// return NULL; +// d = PyModule_GetDict(m); + +// PyDict_SetItemString(d, "Overlapped", (PyObject *) &OverlappedType); + +// /* 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_HANDLE, INVALID_HANDLE_VALUE); +// WINAPI_CONSTANT(F_DWORD, MEM_COMMIT); +// WINAPI_CONSTANT(F_DWORD, MEM_FREE); +// WINAPI_CONSTANT(F_DWORD, MEM_IMAGE); +// 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, PAGE_EXECUTE); +// WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READ); +// WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READWRITE); +// WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_WRITECOPY); +// WINAPI_CONSTANT(F_DWORD, PAGE_GUARD); +// WINAPI_CONSTANT(F_DWORD, PAGE_NOACCESS); +// WINAPI_CONSTANT(F_DWORD, PAGE_NOCACHE); +// WINAPI_CONSTANT(F_DWORD, PAGE_READONLY); +// 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, SYNCHRONIZE); +// 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; +// } diff --git a/python/Modules/_xxsubinterpretersmodule.c b/python/Modules/_xxsubinterpretersmodule.c new file mode 100755 index 0000000..bda2a25 --- /dev/null +++ b/python/Modules/_xxsubinterpretersmodule.c @@ -0,0 +1,2558 @@ + +/* interpreters module */ +/* low-level access to interpreter primitives */ + +#include "Python.h" +#include "frameobject.h" +#include "interpreteridobject.h" + + +static char * +_copy_raw_string(PyObject *strobj) +{ + const char *str = PyUnicode_AsUTF8(strobj); + if (str == NULL) { + return NULL; + } + char *copied = PyMem_Malloc(strlen(str)+1); + if (copied == NULL) { + PyErr_NoMemory(); + return NULL; + } + strcpy(copied, str); + return copied; +} + +static PyInterpreterState * +_get_current(void) +{ + // _PyInterpreterState_Get() aborts if lookup fails, so don't need + // to check the result for NULL. + return _PyInterpreterState_Get(); +} + + +/* data-sharing-specific code ***********************************************/ + +struct _sharednsitem { + char *name; + _PyCrossInterpreterData data; +}; + +static void _sharednsitem_clear(struct _sharednsitem *); // forward + +static int +_sharednsitem_init(struct _sharednsitem *item, PyObject *key, PyObject *value) +{ + item->name = _copy_raw_string(key); + if (item->name == NULL) { + return -1; + } + if (_PyObject_GetCrossInterpreterData(value, &item->data) != 0) { + _sharednsitem_clear(item); + return -1; + } + return 0; +} + +static void +_sharednsitem_clear(struct _sharednsitem *item) +{ + if (item->name != NULL) { + PyMem_Free(item->name); + item->name = NULL; + } + _PyCrossInterpreterData_Release(&item->data); +} + +static int +_sharednsitem_apply(struct _sharednsitem *item, PyObject *ns) +{ + PyObject *name = PyUnicode_FromString(item->name); + if (name == NULL) { + return -1; + } + PyObject *value = _PyCrossInterpreterData_NewObject(&item->data); + if (value == NULL) { + Py_DECREF(name); + return -1; + } + int res = PyDict_SetItem(ns, name, value); + Py_DECREF(name); + Py_DECREF(value); + return res; +} + +typedef struct _sharedns { + Py_ssize_t len; + struct _sharednsitem* items; +} _sharedns; + +static _sharedns * +_sharedns_new(Py_ssize_t len) +{ + _sharedns *shared = PyMem_NEW(_sharedns, 1); + if (shared == NULL) { + PyErr_NoMemory(); + return NULL; + } + shared->len = len; + shared->items = PyMem_NEW(struct _sharednsitem, len); + if (shared->items == NULL) { + PyErr_NoMemory(); + PyMem_Free(shared); + return NULL; + } + return shared; +} + +static void +_sharedns_free(_sharedns *shared) +{ + for (Py_ssize_t i=0; i < shared->len; i++) { + _sharednsitem_clear(&shared->items[i]); + } + PyMem_Free(shared->items); + PyMem_Free(shared); +} + +static _sharedns * +_get_shared_ns(PyObject *shareable) +{ + if (shareable == NULL || shareable == Py_None) { + return NULL; + } + Py_ssize_t len = PyDict_Size(shareable); + if (len == 0) { + return NULL; + } + + _sharedns *shared = _sharedns_new(len); + if (shared == NULL) { + return NULL; + } + Py_ssize_t pos = 0; + for (Py_ssize_t i=0; i < len; i++) { + PyObject *key, *value; + if (PyDict_Next(shareable, &pos, &key, &value) == 0) { + break; + } + if (_sharednsitem_init(&shared->items[i], key, value) != 0) { + break; + } + } + if (PyErr_Occurred()) { + _sharedns_free(shared); + return NULL; + } + return shared; +} + +static int +_sharedns_apply(_sharedns *shared, PyObject *ns) +{ + for (Py_ssize_t i=0; i < shared->len; i++) { + if (_sharednsitem_apply(&shared->items[i], ns) != 0) { + return -1; + } + } + return 0; +} + +// Ultimately we'd like to preserve enough information about the +// exception and traceback that we could re-constitute (or at least +// simulate, a la traceback.TracebackException), and even chain, a copy +// of the exception in the calling interpreter. + +typedef struct _sharedexception { + char *name; + char *msg; +} _sharedexception; + +static _sharedexception * +_sharedexception_new(void) +{ + _sharedexception *err = PyMem_NEW(_sharedexception, 1); + if (err == NULL) { + PyErr_NoMemory(); + return NULL; + } + err->name = NULL; + err->msg = NULL; + return err; +} + +static void +_sharedexception_clear(_sharedexception *exc) +{ + if (exc->name != NULL) { + PyMem_Free(exc->name); + } + if (exc->msg != NULL) { + PyMem_Free(exc->msg); + } +} + +static void +_sharedexception_free(_sharedexception *exc) +{ + _sharedexception_clear(exc); + PyMem_Free(exc); +} + +static _sharedexception * +_sharedexception_bind(PyObject *exctype, PyObject *exc, PyObject *tb) +{ + assert(exctype != NULL); + char *failure = NULL; + + _sharedexception *err = _sharedexception_new(); + if (err == NULL) { + goto finally; + } + + PyObject *name = PyUnicode_FromFormat("%S", exctype); + if (name == NULL) { + failure = "unable to format exception type name"; + goto finally; + } + err->name = _copy_raw_string(name); + Py_DECREF(name); + if (err->name == NULL) { + if (PyErr_ExceptionMatches(PyExc_MemoryError)) { + failure = "out of memory copying exception type name"; + } else { + failure = "unable to encode and copy exception type name"; + } + goto finally; + } + + if (exc != NULL) { + PyObject *msg = PyUnicode_FromFormat("%S", exc); + if (msg == NULL) { + failure = "unable to format exception message"; + goto finally; + } + err->msg = _copy_raw_string(msg); + Py_DECREF(msg); + if (err->msg == NULL) { + if (PyErr_ExceptionMatches(PyExc_MemoryError)) { + failure = "out of memory copying exception message"; + } else { + failure = "unable to encode and copy exception message"; + } + goto finally; + } + } + +finally: + if (failure != NULL) { + PyErr_Clear(); + if (err->name != NULL) { + PyMem_Free(err->name); + err->name = NULL; + } + err->msg = failure; + } + return err; +} + +static void +_sharedexception_apply(_sharedexception *exc, PyObject *wrapperclass) +{ + if (exc->name != NULL) { + if (exc->msg != NULL) { + PyErr_Format(wrapperclass, "%s: %s", exc->name, exc->msg); + } + else { + PyErr_SetString(wrapperclass, exc->name); + } + } + else if (exc->msg != NULL) { + PyErr_SetString(wrapperclass, exc->msg); + } + else { + PyErr_SetNone(wrapperclass); + } +} + + +/* channel-specific code ****************************************************/ + +#define CHANNEL_SEND 1 +#define CHANNEL_BOTH 0 +#define CHANNEL_RECV -1 + +static PyObject *ChannelError; +static PyObject *ChannelNotFoundError; +static PyObject *ChannelClosedError; +static PyObject *ChannelEmptyError; +static PyObject *ChannelNotEmptyError; + +static int +channel_exceptions_init(PyObject *ns) +{ + // XXX Move the exceptions into per-module memory? + + // A channel-related operation failed. + ChannelError = PyErr_NewException("_xxsubinterpreters.ChannelError", + PyExc_RuntimeError, NULL); + if (ChannelError == NULL) { + return -1; + } + if (PyDict_SetItemString(ns, "ChannelError", ChannelError) != 0) { + return -1; + } + + // An operation tried to use a channel that doesn't exist. + ChannelNotFoundError = PyErr_NewException( + "_xxsubinterpreters.ChannelNotFoundError", ChannelError, NULL); + if (ChannelNotFoundError == NULL) { + return -1; + } + if (PyDict_SetItemString(ns, "ChannelNotFoundError", ChannelNotFoundError) != 0) { + return -1; + } + + // An operation tried to use a closed channel. + ChannelClosedError = PyErr_NewException( + "_xxsubinterpreters.ChannelClosedError", ChannelError, NULL); + if (ChannelClosedError == NULL) { + return -1; + } + if (PyDict_SetItemString(ns, "ChannelClosedError", ChannelClosedError) != 0) { + return -1; + } + + // An operation tried to pop from an empty channel. + ChannelEmptyError = PyErr_NewException( + "_xxsubinterpreters.ChannelEmptyError", ChannelError, NULL); + if (ChannelEmptyError == NULL) { + return -1; + } + if (PyDict_SetItemString(ns, "ChannelEmptyError", ChannelEmptyError) != 0) { + return -1; + } + + // An operation tried to close a non-empty channel. + ChannelNotEmptyError = PyErr_NewException( + "_xxsubinterpreters.ChannelNotEmptyError", ChannelError, NULL); + if (ChannelNotEmptyError == NULL) { + return -1; + } + if (PyDict_SetItemString(ns, "ChannelNotEmptyError", ChannelNotEmptyError) != 0) { + return -1; + } + + return 0; +} + +/* the channel queue */ + +struct _channelitem; + +typedef struct _channelitem { + _PyCrossInterpreterData *data; + struct _channelitem *next; +} _channelitem; + +static _channelitem * +_channelitem_new(void) +{ + _channelitem *item = PyMem_NEW(_channelitem, 1); + if (item == NULL) { + PyErr_NoMemory(); + return NULL; + } + item->data = NULL; + item->next = NULL; + return item; +} + +static void +_channelitem_clear(_channelitem *item) +{ + if (item->data != NULL) { + _PyCrossInterpreterData_Release(item->data); + PyMem_Free(item->data); + item->data = NULL; + } + item->next = NULL; +} + +static void +_channelitem_free(_channelitem *item) +{ + _channelitem_clear(item); + PyMem_Free(item); +} + +static void +_channelitem_free_all(_channelitem *item) +{ + while (item != NULL) { + _channelitem *last = item; + item = item->next; + _channelitem_free(last); + } +} + +static _PyCrossInterpreterData * +_channelitem_popped(_channelitem *item) +{ + _PyCrossInterpreterData *data = item->data; + item->data = NULL; + _channelitem_free(item); + return data; +} + +typedef struct _channelqueue { + int64_t count; + _channelitem *first; + _channelitem *last; +} _channelqueue; + +static _channelqueue * +_channelqueue_new(void) +{ + _channelqueue *queue = PyMem_NEW(_channelqueue, 1); + if (queue == NULL) { + PyErr_NoMemory(); + return NULL; + } + queue->count = 0; + queue->first = NULL; + queue->last = NULL; + return queue; +} + +static void +_channelqueue_clear(_channelqueue *queue) +{ + _channelitem_free_all(queue->first); + queue->count = 0; + queue->first = NULL; + queue->last = NULL; +} + +static void +_channelqueue_free(_channelqueue *queue) +{ + _channelqueue_clear(queue); + PyMem_Free(queue); +} + +static int +_channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data) +{ + _channelitem *item = _channelitem_new(); + if (item == NULL) { + return -1; + } + item->data = data; + + queue->count += 1; + if (queue->first == NULL) { + queue->first = item; + } + else { + queue->last->next = item; + } + queue->last = item; + return 0; +} + +static _PyCrossInterpreterData * +_channelqueue_get(_channelqueue *queue) +{ + _channelitem *item = queue->first; + if (item == NULL) { + return NULL; + } + queue->first = item->next; + if (queue->last == item) { + queue->last = NULL; + } + queue->count -= 1; + + return _channelitem_popped(item); +} + +/* channel-interpreter associations */ + +struct _channelend; + +typedef struct _channelend { + struct _channelend *next; + int64_t interp; + int open; +} _channelend; + +static _channelend * +_channelend_new(int64_t interp) +{ + _channelend *end = PyMem_NEW(_channelend, 1); + if (end == NULL) { + PyErr_NoMemory(); + return NULL; + } + end->next = NULL; + end->interp = interp; + end->open = 1; + return end; +} + +static void +_channelend_free(_channelend *end) +{ + PyMem_Free(end); +} + +static void +_channelend_free_all(_channelend *end) +{ + while (end != NULL) { + _channelend *last = end; + end = end->next; + _channelend_free(last); + } +} + +static _channelend * +_channelend_find(_channelend *first, int64_t interp, _channelend **pprev) +{ + _channelend *prev = NULL; + _channelend *end = first; + while (end != NULL) { + if (end->interp == interp) { + break; + } + prev = end; + end = end->next; + } + if (pprev != NULL) { + *pprev = prev; + } + return end; +} + +typedef struct _channelassociations { + // Note that the list entries are never removed for interpreter + // for which the channel is closed. This should be a problem in + // practice. Also, a channel isn't automatically closed when an + // interpreter is destroyed. + int64_t numsendopen; + int64_t numrecvopen; + _channelend *send; + _channelend *recv; +} _channelends; + +static _channelends * +_channelends_new(void) +{ + _channelends *ends = PyMem_NEW(_channelends, 1); + if (ends== NULL) { + return NULL; + } + ends->numsendopen = 0; + ends->numrecvopen = 0; + ends->send = NULL; + ends->recv = NULL; + return ends; +} + +static void +_channelends_clear(_channelends *ends) +{ + _channelend_free_all(ends->send); + ends->send = NULL; + ends->numsendopen = 0; + + _channelend_free_all(ends->recv); + ends->recv = NULL; + ends->numrecvopen = 0; +} + +static void +_channelends_free(_channelends *ends) +{ + _channelends_clear(ends); + PyMem_Free(ends); +} + +static _channelend * +_channelends_add(_channelends *ends, _channelend *prev, int64_t interp, + int send) +{ + _channelend *end = _channelend_new(interp); + if (end == NULL) { + return NULL; + } + + if (prev == NULL) { + if (send) { + ends->send = end; + } + else { + ends->recv = end; + } + } + else { + prev->next = end; + } + if (send) { + ends->numsendopen += 1; + } + else { + ends->numrecvopen += 1; + } + return end; +} + +static int +_channelends_associate(_channelends *ends, int64_t interp, int send) +{ + _channelend *prev; + _channelend *end = _channelend_find(send ? ends->send : ends->recv, + interp, &prev); + if (end != NULL) { + if (!end->open) { + PyErr_SetString(ChannelClosedError, "channel already closed"); + return -1; + } + // already associated + return 0; + } + if (_channelends_add(ends, prev, interp, send) == NULL) { + return -1; + } + return 0; +} + +static int +_channelends_is_open(_channelends *ends) +{ + if (ends->numsendopen != 0 || ends->numrecvopen != 0) { + return 1; + } + if (ends->send == NULL && ends->recv == NULL) { + return 1; + } + return 0; +} + +static void +_channelends_close_end(_channelends *ends, _channelend *end, int send) +{ + end->open = 0; + if (send) { + ends->numsendopen -= 1; + } + else { + ends->numrecvopen -= 1; + } +} + +static int +_channelends_close_interpreter(_channelends *ends, int64_t interp, int which) +{ + _channelend *prev; + _channelend *end; + if (which >= 0) { // send/both + end = _channelend_find(ends->send, interp, &prev); + if (end == NULL) { + // never associated so add it + end = _channelends_add(ends, prev, interp, 1); + if (end == NULL) { + return -1; + } + } + _channelends_close_end(ends, end, 1); + } + if (which <= 0) { // recv/both + end = _channelend_find(ends->recv, interp, &prev); + if (end == NULL) { + // never associated so add it + end = _channelends_add(ends, prev, interp, 0); + if (end == NULL) { + return -1; + } + } + _channelends_close_end(ends, end, 0); + } + return 0; +} + +static void +_channelends_close_all(_channelends *ends, int which, int force) +{ + // XXX Handle the ends. + // XXX Handle force is True. + + // Ensure all the "send"-associated interpreters are closed. + _channelend *end; + for (end = ends->send; end != NULL; end = end->next) { + _channelends_close_end(ends, end, 1); + } + + // Ensure all the "recv"-associated interpreters are closed. + for (end = ends->recv; end != NULL; end = end->next) { + _channelends_close_end(ends, end, 0); + } +} + +/* channels */ + +struct _channel; +struct _channel_closing; +static void _channel_clear_closing(struct _channel *); +static void _channel_finish_closing(struct _channel *); + +typedef struct _channel { + PyThread_type_lock mutex; + _channelqueue *queue; + _channelends *ends; + int open; + struct _channel_closing *closing; +} _PyChannelState; + +static _PyChannelState * +_channel_new(void) +{ + _PyChannelState *chan = PyMem_NEW(_PyChannelState, 1); + if (chan == NULL) { + return NULL; + } + chan->mutex = PyThread_allocate_lock(); + if (chan->mutex == NULL) { + PyMem_Free(chan); + PyErr_SetString(ChannelError, + "can't initialize mutex for new channel"); + return NULL; + } + chan->queue = _channelqueue_new(); + if (chan->queue == NULL) { + PyMem_Free(chan); + return NULL; + } + chan->ends = _channelends_new(); + if (chan->ends == NULL) { + _channelqueue_free(chan->queue); + PyMem_Free(chan); + return NULL; + } + chan->open = 1; + chan->closing = NULL; + return chan; +} + +static void +_channel_free(_PyChannelState *chan) +{ + _channel_clear_closing(chan); + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + _channelqueue_free(chan->queue); + _channelends_free(chan->ends); + PyThread_release_lock(chan->mutex); + + PyThread_free_lock(chan->mutex); + PyMem_Free(chan); +} + +static int +_channel_add(_PyChannelState *chan, int64_t interp, + _PyCrossInterpreterData *data) +{ + int res = -1; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + if (!chan->open) { + PyErr_SetString(ChannelClosedError, "channel closed"); + goto done; + } + if (_channelends_associate(chan->ends, interp, 1) != 0) { + goto done; + } + + if (_channelqueue_put(chan->queue, data) != 0) { + goto done; + } + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +static _PyCrossInterpreterData * +_channel_next(_PyChannelState *chan, int64_t interp) +{ + _PyCrossInterpreterData *data = NULL; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + if (!chan->open) { + PyErr_SetString(ChannelClosedError, "channel closed"); + goto done; + } + if (_channelends_associate(chan->ends, interp, 0) != 0) { + goto done; + } + + data = _channelqueue_get(chan->queue); + if (data == NULL && !PyErr_Occurred() && chan->closing != NULL) { + chan->open = 0; + } + +done: + PyThread_release_lock(chan->mutex); + if (chan->queue->count == 0) { + _channel_finish_closing(chan); + } + return data; +} + +static int +_channel_close_interpreter(_PyChannelState *chan, int64_t interp, int end) +{ + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + int res = -1; + if (!chan->open) { + PyErr_SetString(ChannelClosedError, "channel already closed"); + goto done; + } + + if (_channelends_close_interpreter(chan->ends, interp, end) != 0) { + goto done; + } + chan->open = _channelends_is_open(chan->ends); + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +static int +_channel_close_all(_PyChannelState *chan, int end, int force) +{ + int res = -1; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + if (!chan->open) { + PyErr_SetString(ChannelClosedError, "channel already closed"); + goto done; + } + + if (!force && chan->queue->count > 0) { + PyErr_SetString(ChannelNotEmptyError, + "may not be closed if not empty (try force=True)"); + goto done; + } + + chan->open = 0; + + // We *could* also just leave these in place, since we've marked + // the channel as closed already. + _channelends_close_all(chan->ends, end, force); + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +/* the set of channels */ + +struct _channelref; + +typedef struct _channelref { + int64_t id; + _PyChannelState *chan; + struct _channelref *next; + Py_ssize_t objcount; +} _channelref; + +static _channelref * +_channelref_new(int64_t id, _PyChannelState *chan) +{ + _channelref *ref = PyMem_NEW(_channelref, 1); + if (ref == NULL) { + return NULL; + } + ref->id = id; + ref->chan = chan; + ref->next = NULL; + ref->objcount = 0; + return ref; +} + +//static void +//_channelref_clear(_channelref *ref) +//{ +// ref->id = -1; +// ref->chan = NULL; +// ref->next = NULL; +// ref->objcount = 0; +//} + +static void +_channelref_free(_channelref *ref) +{ + if (ref->chan != NULL) { + _channel_clear_closing(ref->chan); + } + //_channelref_clear(ref); + PyMem_Free(ref); +} + +static _channelref * +_channelref_find(_channelref *first, int64_t id, _channelref **pprev) +{ + _channelref *prev = NULL; + _channelref *ref = first; + while (ref != NULL) { + if (ref->id == id) { + break; + } + prev = ref; + ref = ref->next; + } + if (pprev != NULL) { + *pprev = prev; + } + return ref; +} + +typedef struct _channels { + PyThread_type_lock mutex; + _channelref *head; + int64_t numopen; + int64_t next_id; +} _channels; + +static int +_channels_init(_channels *channels) +{ + if (channels->mutex == NULL) { + channels->mutex = PyThread_allocate_lock(); + if (channels->mutex == NULL) { + PyErr_SetString(ChannelError, + "can't initialize mutex for channel management"); + return -1; + } + } + channels->head = NULL; + channels->numopen = 0; + channels->next_id = 0; + return 0; +} + +static int64_t +_channels_next_id(_channels *channels) // needs lock +{ + int64_t id = channels->next_id; + if (id < 0) { + /* overflow */ + PyErr_SetString(ChannelError, + "failed to get a channel ID"); + return -1; + } + channels->next_id += 1; + return id; +} + +static _PyChannelState * +_channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex) +{ + _PyChannelState *chan = NULL; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + if (pmutex != NULL) { + *pmutex = NULL; + } + + _channelref *ref = _channelref_find(channels->head, id, NULL); + if (ref == NULL) { + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); + goto done; + } + if (ref->chan == NULL || !ref->chan->open) { + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); + goto done; + } + + if (pmutex != NULL) { + // The mutex will be closed by the caller. + *pmutex = channels->mutex; + } + + chan = ref->chan; +done: + if (pmutex == NULL || *pmutex == NULL) { + PyThread_release_lock(channels->mutex); + } + return chan; +} + +static int64_t +_channels_add(_channels *channels, _PyChannelState *chan) +{ + int64_t cid = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + // Create a new ref. + int64_t id = _channels_next_id(channels); + if (id < 0) { + goto done; + } + _channelref *ref = _channelref_new(id, chan); + if (ref == NULL) { + goto done; + } + + // Add it to the list. + // We assume that the channel is a new one (not already in the list). + ref->next = channels->head; + channels->head = ref; + channels->numopen += 1; + + cid = id; +done: + PyThread_release_lock(channels->mutex); + return cid; +} + +/* forward */ +static int _channel_set_closing(struct _channelref *, PyThread_type_lock); + +static int +_channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, + int end, int force) +{ + int res = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + if (pchan != NULL) { + *pchan = NULL; + } + + _channelref *ref = _channelref_find(channels->head, cid, NULL); + if (ref == NULL) { + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", cid); + goto done; + } + + if (ref->chan == NULL) { + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); + goto done; + } + else if (!force && end == CHANNEL_SEND && ref->chan->closing != NULL) { + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); + goto done; + } + else { + if (_channel_close_all(ref->chan, end, force) != 0) { + if (end == CHANNEL_SEND && + PyErr_ExceptionMatches(ChannelNotEmptyError)) { + if (ref->chan->closing != NULL) { + PyErr_Format(ChannelClosedError, + "channel %" PRId64 " closed", cid); + goto done; + } + // Mark the channel as closing and return. The channel + // will be cleaned up in _channel_next(). + PyErr_Clear(); + if (_channel_set_closing(ref, channels->mutex) != 0) { + goto done; + } + if (pchan != NULL) { + *pchan = ref->chan; + } + res = 0; + } + goto done; + } + if (pchan != NULL) { + *pchan = ref->chan; + } + else { + _channel_free(ref->chan); + } + ref->chan = NULL; + } + + res = 0; +done: + PyThread_release_lock(channels->mutex); + return res; +} + +static void +_channels_remove_ref(_channels *channels, _channelref *ref, _channelref *prev, + _PyChannelState **pchan) +{ + if (ref == channels->head) { + channels->head = ref->next; + } + else { + prev->next = ref->next; + } + channels->numopen -= 1; + + if (pchan != NULL) { + *pchan = ref->chan; + } + _channelref_free(ref); +} + +static int +_channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) +{ + int res = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + if (pchan != NULL) { + *pchan = NULL; + } + + _channelref *prev = NULL; + _channelref *ref = _channelref_find(channels->head, id, &prev); + if (ref == NULL) { + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); + goto done; + } + + _channels_remove_ref(channels, ref, prev, pchan); + + res = 0; +done: + PyThread_release_lock(channels->mutex); + return res; +} + +static int +_channels_add_id_object(_channels *channels, int64_t id) +{ + int res = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + _channelref *ref = _channelref_find(channels->head, id, NULL); + if (ref == NULL) { + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); + goto done; + } + ref->objcount += 1; + + res = 0; +done: + PyThread_release_lock(channels->mutex); + return res; +} + +static void +_channels_drop_id_object(_channels *channels, int64_t id) +{ + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + _channelref *prev = NULL; + _channelref *ref = _channelref_find(channels->head, id, &prev); + if (ref == NULL) { + // Already destroyed. + goto done; + } + ref->objcount -= 1; + + // Destroy if no longer used. + if (ref->objcount == 0) { + _PyChannelState *chan = NULL; + _channels_remove_ref(channels, ref, prev, &chan); + if (chan != NULL) { + _channel_free(chan); + } + } + +done: + PyThread_release_lock(channels->mutex); +} + +static int64_t * +_channels_list_all(_channels *channels, int64_t *count) +{ + int64_t *cids = NULL; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + int64_t numopen = channels->numopen; + if (numopen >= PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_RuntimeError, "too many channels open"); + goto done; + } + int64_t *ids = PyMem_NEW(int64_t, (Py_ssize_t)(channels->numopen)); + if (ids == NULL) { + goto done; + } + _channelref *ref = channels->head; + for (int64_t i=0; ref != NULL; ref = ref->next, i++) { + ids[i] = ref->id; + } + *count = channels->numopen; + + cids = ids; +done: + PyThread_release_lock(channels->mutex); + return cids; +} + +/* support for closing non-empty channels */ + +struct _channel_closing { + struct _channelref *ref; +}; + +static int +_channel_set_closing(struct _channelref *ref, PyThread_type_lock mutex) { + struct _channel *chan = ref->chan; + if (chan == NULL) { + // already closed + return 0; + } + int res = -1; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + if (chan->closing != NULL) { + PyErr_SetString(ChannelClosedError, "channel closed"); + goto done; + } + chan->closing = PyMem_NEW(struct _channel_closing, 1); + if (chan->closing == NULL) { + goto done; + } + chan->closing->ref = ref; + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +static void +_channel_clear_closing(struct _channel *chan) { + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + if (chan->closing != NULL) { + PyMem_Free(chan->closing); + chan->closing = NULL; + } + PyThread_release_lock(chan->mutex); +} + +static void +_channel_finish_closing(struct _channel *chan) { + struct _channel_closing *closing = chan->closing; + if (closing == NULL) { + return; + } + _channelref *ref = closing->ref; + _channel_clear_closing(chan); + // Do the things that would have been done in _channels_close(). + ref->chan = NULL; + _channel_free(chan); +} + +/* "high"-level channel-related functions */ + +static int64_t +_channel_create(_channels *channels) +{ + _PyChannelState *chan = _channel_new(); + if (chan == NULL) { + return -1; + } + int64_t id = _channels_add(channels, chan); + if (id < 0) { + _channel_free(chan); + return -1; + } + return id; +} + +static int +_channel_destroy(_channels *channels, int64_t id) +{ + _PyChannelState *chan = NULL; + if (_channels_remove(channels, id, &chan) != 0) { + return -1; + } + if (chan != NULL) { + _channel_free(chan); + } + return 0; +} + +static int +_channel_send(_channels *channels, int64_t id, PyObject *obj) +{ + PyInterpreterState *interp = _get_current(); + if (interp == NULL) { + return -1; + } + + // Look up the channel. + PyThread_type_lock mutex = NULL; + _PyChannelState *chan = _channels_lookup(channels, id, &mutex); + if (chan == NULL) { + return -1; + } + // Past this point we are responsible for releasing the mutex. + + if (chan->closing != NULL) { + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); + PyThread_release_lock(mutex); + return -1; + } + + // Convert the object to cross-interpreter data. + _PyCrossInterpreterData *data = PyMem_NEW(_PyCrossInterpreterData, 1); + if (data == NULL) { + PyThread_release_lock(mutex); + return -1; + } + if (_PyObject_GetCrossInterpreterData(obj, data) != 0) { + PyThread_release_lock(mutex); + PyMem_Free(data); + return -1; + } + + // Add the data to the channel. + int res = _channel_add(chan, PyInterpreterState_GetID(interp), data); + PyThread_release_lock(mutex); + if (res != 0) { + _PyCrossInterpreterData_Release(data); + PyMem_Free(data); + return -1; + } + + return 0; +} + +static PyObject * +_channel_recv(_channels *channels, int64_t id) +{ + PyInterpreterState *interp = _get_current(); + if (interp == NULL) { + return NULL; + } + + // Look up the channel. + PyThread_type_lock mutex = NULL; + _PyChannelState *chan = _channels_lookup(channels, id, &mutex); + if (chan == NULL) { + return NULL; + } + // Past this point we are responsible for releasing the mutex. + + // Pop off the next item from the channel. + _PyCrossInterpreterData *data = _channel_next(chan, PyInterpreterState_GetID(interp)); + PyThread_release_lock(mutex); + if (data == NULL) { + if (!PyErr_Occurred()) { + PyErr_Format(ChannelEmptyError, "channel %" PRId64 " is empty", id); + } + return NULL; + } + + // Convert the data back to an object. + PyObject *obj = _PyCrossInterpreterData_NewObject(data); + if (obj == NULL) { + return NULL; + } + _PyCrossInterpreterData_Release(data); + PyMem_Free(data); + + return obj; +} + +static int +_channel_drop(_channels *channels, int64_t id, int send, int recv) +{ + PyInterpreterState *interp = _get_current(); + if (interp == NULL) { + return -1; + } + + // Look up the channel. + PyThread_type_lock mutex = NULL; + _PyChannelState *chan = _channels_lookup(channels, id, &mutex); + if (chan == NULL) { + return -1; + } + // Past this point we are responsible for releasing the mutex. + + // Close one or both of the two ends. + int res = _channel_close_interpreter(chan, PyInterpreterState_GetID(interp), send-recv); + PyThread_release_lock(mutex); + return res; +} + +static int +_channel_close(_channels *channels, int64_t id, int end, int force) +{ + return _channels_close(channels, id, NULL, end, force); +} + +/* ChannelID class */ + +static PyTypeObject ChannelIDtype; + +typedef struct channelid { + PyObject_HEAD + int64_t id; + int end; + int resolve; + _channels *channels; +} channelid; + +static int +channel_id_converter(PyObject *arg, void *ptr) +{ + int64_t cid; + if (PyObject_TypeCheck(arg, &ChannelIDtype)) { + cid = ((channelid *)arg)->id; + } + else if (PyIndex_Check(arg)) { + cid = PyLong_AsLongLong(arg); + if (cid == -1 && PyErr_Occurred()) { + return 0; + } + if (cid < 0) { + PyErr_Format(PyExc_ValueError, + "channel ID must be a non-negative int, got %R", arg); + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "channel ID must be an int, got %.100s", + arg->ob_type->tp_name); + return 0; + } + *(int64_t *)ptr = cid; + return 1; +} + +static channelid * +newchannelid(PyTypeObject *cls, int64_t cid, int end, _channels *channels, + int force, int resolve) +{ + channelid *self = PyObject_New(channelid, cls); + if (self == NULL) { + return NULL; + } + self->id = cid; + self->end = end; + self->resolve = resolve; + self->channels = channels; + + if (_channels_add_id_object(channels, cid) != 0) { + if (force && PyErr_ExceptionMatches(ChannelNotFoundError)) { + PyErr_Clear(); + } + else { + Py_DECREF((PyObject *)self); + return NULL; + } + } + + return self; +} + +static _channels * _global_channels(void); + +static PyObject * +channelid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", "send", "recv", "force", "_resolve", NULL}; + int64_t cid; + int send = -1; + int recv = -1; + int force = 0; + int resolve = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&|$pppp:ChannelID.__new__", kwlist, + channel_id_converter, &cid, &send, &recv, &force, &resolve)) + return NULL; + + // Handle "send" and "recv". + if (send == 0 && recv == 0) { + PyErr_SetString(PyExc_ValueError, + "'send' and 'recv' cannot both be False"); + return NULL; + } + + int end = 0; + if (send == 1) { + if (recv == 0 || recv == -1) { + end = CHANNEL_SEND; + } + } + else if (recv == 1) { + end = CHANNEL_RECV; + } + + return (PyObject *)newchannelid(cls, cid, end, _global_channels(), + force, resolve); +} + +static void +channelid_dealloc(PyObject *v) +{ + int64_t cid = ((channelid *)v)->id; + _channels *channels = ((channelid *)v)->channels; + Py_TYPE(v)->tp_free(v); + + _channels_drop_id_object(channels, cid); +} + +static PyObject * +channelid_repr(PyObject *self) +{ + PyTypeObject *type = Py_TYPE(self); + const char *name = _PyType_Name(type); + + channelid *cid = (channelid *)self; + const char *fmt; + if (cid->end == CHANNEL_SEND) { + fmt = "%s(%" PRId64 ", send=True)"; + } + else if (cid->end == CHANNEL_RECV) { + fmt = "%s(%" PRId64 ", recv=True)"; + } + else { + fmt = "%s(%" PRId64 ")"; + } + return PyUnicode_FromFormat(fmt, name, cid->id); +} + +static PyObject * +channelid_str(PyObject *self) +{ + channelid *cid = (channelid *)self; + return PyUnicode_FromFormat("%" PRId64 "", cid->id); +} + +static PyObject * +channelid_int(PyObject *self) +{ + channelid *cid = (channelid *)self; + return PyLong_FromLongLong(cid->id); +} + +static PyNumberMethods channelid_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + (unaryfunc)channelid_int, /* nb_int */ + 0, /* nb_reserved */ + 0, /* nb_float */ + + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + + (unaryfunc)channelid_int, /* nb_index */ +}; + +static Py_hash_t +channelid_hash(PyObject *self) +{ + channelid *cid = (channelid *)self; + PyObject *id = PyLong_FromLongLong(cid->id); + if (id == NULL) { + return -1; + } + Py_hash_t hash = PyObject_Hash(id); + Py_DECREF(id); + return hash; +} + +static PyObject * +channelid_richcompare(PyObject *self, PyObject *other, int op) +{ + if (op != Py_EQ && op != Py_NE) { + Py_RETURN_NOTIMPLEMENTED; + } + + if (!PyObject_TypeCheck(self, &ChannelIDtype)) { + Py_RETURN_NOTIMPLEMENTED; + } + + channelid *cid = (channelid *)self; + int equal; + if (PyObject_TypeCheck(other, &ChannelIDtype)) { + channelid *othercid = (channelid *)other; + equal = (cid->end == othercid->end) && (cid->id == othercid->id); + } + else if (PyLong_Check(other)) { + /* Fast path */ + int overflow; + long long othercid = PyLong_AsLongLongAndOverflow(other, &overflow); + if (othercid == -1 && PyErr_Occurred()) { + return NULL; + } + equal = !overflow && (othercid >= 0) && (cid->id == othercid); + } + else if (PyNumber_Check(other)) { + PyObject *pyid = PyLong_FromLongLong(cid->id); + if (pyid == NULL) { + return NULL; + } + PyObject *res = PyObject_RichCompare(pyid, other, op); + Py_DECREF(pyid); + return res; + } + else { + Py_RETURN_NOTIMPLEMENTED; + } + + if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static PyObject * +_channel_from_cid(PyObject *cid, int end) +{ + PyObject *highlevel = PyImport_ImportModule("interpreters"); + if (highlevel == NULL) { + PyErr_Clear(); + highlevel = PyImport_ImportModule("test.support.interpreters"); + if (highlevel == NULL) { + return NULL; + } + } + const char *clsname = (end == CHANNEL_RECV) ? "RecvChannel" : + "SendChannel"; + PyObject *cls = PyObject_GetAttrString(highlevel, clsname); + Py_DECREF(highlevel); + if (cls == NULL) { + return NULL; + } + PyObject *chan = PyObject_CallFunctionObjArgs(cls, cid, NULL); + Py_DECREF(cls); + if (chan == NULL) { + return NULL; + } + return chan; +} + +struct _channelid_xid { + int64_t id; + int end; + int resolve; +}; + +static PyObject * +_channelid_from_xid(_PyCrossInterpreterData *data) +{ + struct _channelid_xid *xid = (struct _channelid_xid *)data->data; + // Note that we do not preserve the "resolve" flag. + PyObject *cid = (PyObject *)newchannelid(&ChannelIDtype, xid->id, xid->end, + _global_channels(), 0, 0); + if (xid->end == 0) { + return cid; + } + if (!xid->resolve) { + return cid; + } + + /* Try returning a high-level channel end but fall back to the ID. */ + PyObject *chan = _channel_from_cid(cid, xid->end); + if (chan == NULL) { + PyErr_Clear(); + return cid; + } + Py_DECREF(cid); + return chan; +} + +static int +_channelid_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + struct _channelid_xid *xid = PyMem_NEW(struct _channelid_xid, 1); + if (xid == NULL) { + return -1; + } + xid->id = ((channelid *)obj)->id; + xid->end = ((channelid *)obj)->end; + xid->resolve = ((channelid *)obj)->resolve; + + data->data = xid; + Py_INCREF(obj); + data->obj = obj; + data->new_object = _channelid_from_xid; + data->free = PyMem_Free; + return 0; +} + +static PyObject * +channelid_end(PyObject *self, void *end) +{ + int force = 1; + channelid *cid = (channelid *)self; + if (end != NULL) { + return (PyObject *)newchannelid(Py_TYPE(self), cid->id, *(int *)end, + cid->channels, force, cid->resolve); + } + + if (cid->end == CHANNEL_SEND) { + return PyUnicode_InternFromString("send"); + } + if (cid->end == CHANNEL_RECV) { + return PyUnicode_InternFromString("recv"); + } + return PyUnicode_InternFromString("both"); +} + +static int _channelid_end_send = CHANNEL_SEND; +static int _channelid_end_recv = CHANNEL_RECV; + +static PyGetSetDef channelid_getsets[] = { + {"end", (getter)channelid_end, NULL, + PyDoc_STR("'send', 'recv', or 'both'")}, + {"send", (getter)channelid_end, NULL, + PyDoc_STR("the 'send' end of the channel"), &_channelid_end_send}, + {"recv", (getter)channelid_end, NULL, + PyDoc_STR("the 'recv' end of the channel"), &_channelid_end_recv}, + {NULL} +}; + +PyDoc_STRVAR(channelid_doc, +"A channel ID identifies a channel and may be used as an int."); + +static PyTypeObject ChannelIDtype = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "_xxsubinterpreters.ChannelID", /* tp_name */ + sizeof(channelid), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)channelid_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)channelid_repr, /* tp_repr */ + &channelid_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + channelid_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)channelid_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + channelid_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + channelid_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + channelid_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 */ + // Note that we do not set tp_new to channelid_new. Instead we + // set it to NULL, meaning it cannot be instantiated from Python + // code. We do this because there is a strong relationship between + // channel IDs and the channel lifecycle, so this limitation avoids + // related complications. + NULL, /* tp_new */ +}; + + +/* interpreter-specific code ************************************************/ + +static PyObject * RunFailedError = NULL; + +static int +interp_exceptions_init(PyObject *ns) +{ + // XXX Move the exceptions into per-module memory? + + if (RunFailedError == NULL) { + // An uncaught exception came out of interp_run_string(). + RunFailedError = PyErr_NewException("_xxsubinterpreters.RunFailedError", + PyExc_RuntimeError, NULL); + if (RunFailedError == NULL) { + return -1; + } + if (PyDict_SetItemString(ns, "RunFailedError", RunFailedError) != 0) { + return -1; + } + } + + return 0; +} + +static int +_is_running(PyInterpreterState *interp) +{ + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + if (PyThreadState_Next(tstate) != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "interpreter has more than one thread"); + return -1; + } + PyFrameObject *frame = tstate->frame; + if (frame == NULL) { + if (PyErr_Occurred() != NULL) { + return -1; + } + return 0; + } + return (int)(frame->f_executing); +} + +static int +_ensure_not_running(PyInterpreterState *interp) +{ + int is_running = _is_running(interp); + if (is_running < 0) { + return -1; + } + if (is_running) { + PyErr_Format(PyExc_RuntimeError, "interpreter already running"); + return -1; + } + return 0; +} + +static int +_run_script(PyInterpreterState *interp, const char *codestr, + _sharedns *shared, _sharedexception **exc) +{ + PyObject *exctype = NULL; + PyObject *excval = NULL; + PyObject *tb = NULL; + + PyObject *main_mod = _PyInterpreterState_GetMainModule(interp); + if (main_mod == NULL) { + goto error; + } + PyObject *ns = PyModule_GetDict(main_mod); // borrowed + Py_DECREF(main_mod); + if (ns == NULL) { + goto error; + } + Py_INCREF(ns); + + // Apply the cross-interpreter data. + if (shared != NULL) { + if (_sharedns_apply(shared, ns) != 0) { + Py_DECREF(ns); + goto error; + } + } + + // Run the string (see PyRun_SimpleStringFlags). + PyObject *result = PyRun_StringFlags(codestr, Py_file_input, ns, ns, NULL); + Py_DECREF(ns); + if (result == NULL) { + goto error; + } + else { + Py_DECREF(result); // We throw away the result. + } + + *exc = NULL; + return 0; + +error: + PyErr_Fetch(&exctype, &excval, &tb); + + _sharedexception *sharedexc = _sharedexception_bind(exctype, excval, tb); + Py_XDECREF(exctype); + Py_XDECREF(excval); + Py_XDECREF(tb); + if (sharedexc == NULL) { + fprintf(stderr, "RunFailedError: script raised an uncaught exception"); + PyErr_Clear(); + sharedexc = NULL; + } + else { + assert(!PyErr_Occurred()); + } + *exc = sharedexc; + return -1; +} + +static int +_run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, + PyObject *shareables) +{ + if (_ensure_not_running(interp) < 0) { + return -1; + } + + _sharedns *shared = _get_shared_ns(shareables); + if (shared == NULL && PyErr_Occurred()) { + return -1; + } + + // Switch to interpreter. + PyThreadState *save_tstate = NULL; + if (interp != _PyInterpreterState_Get()) { + // XXX Using the "head" thread isn't strictly correct. + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + // XXX Possible GILState issues? + save_tstate = PyThreadState_Swap(tstate); + } + + // Run the script. + _sharedexception *exc = NULL; + int result = _run_script(interp, codestr, shared, &exc); + + // Switch back. + if (save_tstate != NULL) { + PyThreadState_Swap(save_tstate); + } + + // Propagate any exception out to the caller. + if (exc != NULL) { + _sharedexception_apply(exc, RunFailedError); + _sharedexception_free(exc); + } + else if (result != 0) { + // We were unable to allocate a shared exception. + PyErr_NoMemory(); + } + + if (shared != NULL) { + _sharedns_free(shared); + } + + return result; +} + + +/* module level code ********************************************************/ + +/* globals is the process-global state for the module. It holds all + the data that we need to share between interpreters, so it cannot + hold PyObject values. */ +static struct globals { + _channels channels; +} _globals = {{0}}; + +static int +_init_globals(void) +{ + if (_channels_init(&_globals.channels) != 0) { + return -1; + } + return 0; +} + +static _channels * +_global_channels(void) { + return &_globals.channels; +} + +static PyObject * +interp_create(PyObject *self, PyObject *args) +{ + if (!PyArg_UnpackTuple(args, "create", 0, 0)) { + return NULL; + } + + // Create and initialize the new interpreter. + PyThreadState *save_tstate = PyThreadState_Get(); + // XXX Possible GILState issues? + PyThreadState *tstate = Py_NewInterpreter(); + PyThreadState_Swap(save_tstate); + if (tstate == NULL) { + /* Since no new thread state was created, there is no exception to + propagate; raise a fresh one after swapping in the old thread + state. */ + PyErr_SetString(PyExc_RuntimeError, "interpreter creation failed"); + return NULL; + } + PyObject *idobj = _PyInterpreterState_GetIDObject(tstate->interp); + if (idobj == NULL) { + // XXX Possible GILState issues? + save_tstate = PyThreadState_Swap(tstate); + Py_EndInterpreter(tstate); + PyThreadState_Swap(save_tstate); + return NULL; + } + _PyInterpreterState_RequireIDRef(tstate->interp, 1); + return idobj; +} + +PyDoc_STRVAR(create_doc, +"create() -> ID\n\ +\n\ +Create a new interpreter and return a unique generated ID."); + + +static PyObject * +interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", NULL}; + PyObject *id; + // XXX Use "L" for id? + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O:destroy", kwlist, &id)) { + return NULL; + } + + // Look up the interpreter. + PyInterpreterState *interp = _PyInterpreterID_LookUp(id); + if (interp == NULL) { + return NULL; + } + + // Ensure we don't try to destroy the current interpreter. + PyInterpreterState *current = _get_current(); + if (current == NULL) { + return NULL; + } + if (interp == current) { + PyErr_SetString(PyExc_RuntimeError, + "cannot destroy the current interpreter"); + return NULL; + } + + // Ensure the interpreter isn't running. + /* XXX We *could* support destroying a running interpreter but + aren't going to worry about it for now. */ + if (_ensure_not_running(interp) < 0) { + return NULL; + } + + // Destroy the interpreter. + //PyInterpreterState_Delete(interp); + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + // XXX Possible GILState issues? + PyThreadState *save_tstate = PyThreadState_Swap(tstate); + Py_EndInterpreter(tstate); + PyThreadState_Swap(save_tstate); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(destroy_doc, +"destroy(id)\n\ +\n\ +Destroy the identified interpreter.\n\ +\n\ +Attempting to destroy the current interpreter results in a RuntimeError.\n\ +So does an unrecognized ID."); + + +static PyObject * +interp_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *ids, *id; + PyInterpreterState *interp; + + ids = PyList_New(0); + if (ids == NULL) { + return NULL; + } + + interp = PyInterpreterState_Head(); + while (interp != NULL) { + id = _PyInterpreterState_GetIDObject(interp); + if (id == NULL) { + Py_DECREF(ids); + return NULL; + } + // insert at front of list + int res = PyList_Insert(ids, 0, id); + Py_DECREF(id); + if (res < 0) { + Py_DECREF(ids); + return NULL; + } + + interp = PyInterpreterState_Next(interp); + } + + return ids; +} + +PyDoc_STRVAR(list_all_doc, +"list_all() -> [ID]\n\ +\n\ +Return a list containing the ID of every existing interpreter."); + + +static PyObject * +interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyInterpreterState *interp =_get_current(); + if (interp == NULL) { + return NULL; + } + return _PyInterpreterState_GetIDObject(interp); +} + +PyDoc_STRVAR(get_current_doc, +"get_current() -> ID\n\ +\n\ +Return the ID of current interpreter."); + + +static PyObject * +interp_get_main(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + // Currently, 0 is always the main interpreter. + PY_INT64_T id = 0; + return _PyInterpreterID_New(id); +} + +PyDoc_STRVAR(get_main_doc, +"get_main() -> ID\n\ +\n\ +Return the ID of main interpreter."); + + +static PyObject * +interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", "script", "shared", NULL}; + PyObject *id, *code; + PyObject *shared = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "OU|O:run_string", kwlist, + &id, &code, &shared)) { + return NULL; + } + + // Look up the interpreter. + PyInterpreterState *interp = _PyInterpreterID_LookUp(id); + if (interp == NULL) { + return NULL; + } + + // Extract code. + Py_ssize_t size; + const char *codestr = PyUnicode_AsUTF8AndSize(code, &size); + if (codestr == NULL) { + return NULL; + } + if (strlen(codestr) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, + "source code string cannot contain null bytes"); + return NULL; + } + + // Run the code in the interpreter. + if (_run_script_in_interpreter(interp, codestr, shared) != 0) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(run_string_doc, +"run_string(id, script, shared)\n\ +\n\ +Execute the provided string in the identified interpreter.\n\ +\n\ +See PyRun_SimpleStrings."); + + +static PyObject * +object_is_shareable(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"obj", NULL}; + PyObject *obj; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O:is_shareable", kwlist, &obj)) { + return NULL; + } + + if (_PyObject_CheckCrossInterpreterData(obj) == 0) { + Py_RETURN_TRUE; + } + PyErr_Clear(); + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(is_shareable_doc, +"is_shareable(obj) -> bool\n\ +\n\ +Return True if the object's data may be shared between interpreters and\n\ +False otherwise."); + + +static PyObject * +interp_is_running(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", NULL}; + PyObject *id; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O:is_running", kwlist, &id)) { + return NULL; + } + + PyInterpreterState *interp = _PyInterpreterID_LookUp(id); + if (interp == NULL) { + return NULL; + } + int is_running = _is_running(interp); + if (is_running < 0) { + return NULL; + } + if (is_running) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(is_running_doc, +"is_running(id) -> bool\n\ +\n\ +Return whether or not the identified interpreter is running."); + +static PyObject * +channel_create(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + int64_t cid = _channel_create(&_globals.channels); + if (cid < 0) { + return NULL; + } + PyObject *id = (PyObject *)newchannelid(&ChannelIDtype, cid, 0, + &_globals.channels, 0, 0); + if (id == NULL) { + if (_channel_destroy(&_globals.channels, cid) != 0) { + // XXX issue a warning? + } + return NULL; + } + assert(((channelid *)id)->channels != NULL); + return id; +} + +PyDoc_STRVAR(channel_create_doc, +"channel_create() -> cid\n\ +\n\ +Create a new cross-interpreter channel and return a unique generated ID."); + +static PyObject * +channel_destroy(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", NULL}; + int64_t cid; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:channel_destroy", kwlist, + channel_id_converter, &cid)) { + return NULL; + } + + if (_channel_destroy(&_globals.channels, cid) != 0) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_destroy_doc, +"channel_destroy(cid)\n\ +\n\ +Close and finalize the channel. Afterward attempts to use the channel\n\ +will behave as though it never existed."); + +static PyObject * +channel_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + int64_t count = 0; + int64_t *cids = _channels_list_all(&_globals.channels, &count); + if (cids == NULL) { + if (count == 0) { + return PyList_New(0); + } + return NULL; + } + PyObject *ids = PyList_New((Py_ssize_t)count); + if (ids == NULL) { + goto finally; + } + int64_t *cur = cids; + for (int64_t i=0; i < count; cur++, i++) { + PyObject *id = (PyObject *)newchannelid(&ChannelIDtype, *cur, 0, + &_globals.channels, 0, 0); + if (id == NULL) { + Py_DECREF(ids); + ids = NULL; + break; + } + PyList_SET_ITEM(ids, i, id); + } + +finally: + PyMem_Free(cids); + return ids; +} + +PyDoc_STRVAR(channel_list_all_doc, +"channel_list_all() -> [cid]\n\ +\n\ +Return the list of all IDs for active channels."); + +static PyObject * +channel_send(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "obj", NULL}; + int64_t cid; + PyObject *obj; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O:channel_send", kwlist, + channel_id_converter, &cid, &obj)) { + return NULL; + } + + if (_channel_send(&_globals.channels, cid, obj) != 0) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_send_doc, +"channel_send(cid, obj)\n\ +\n\ +Add the object's data to the channel's queue."); + +static PyObject * +channel_recv(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", NULL}; + int64_t cid; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:channel_recv", kwlist, + channel_id_converter, &cid)) { + return NULL; + } + + return _channel_recv(&_globals.channels, cid); +} + +PyDoc_STRVAR(channel_recv_doc, +"channel_recv(cid) -> obj\n\ +\n\ +Return a new object from the data at the from of the channel's queue."); + +static PyObject * +channel_close(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; + int64_t cid; + int send = 0; + int recv = 0; + int force = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&|$ppp:channel_close", kwlist, + channel_id_converter, &cid, &send, &recv, &force)) { + return NULL; + } + + if (_channel_close(&_globals.channels, cid, send-recv, force) != 0) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_close_doc, +"channel_close(cid, *, send=None, recv=None, force=False)\n\ +\n\ +Close the channel for all interpreters.\n\ +\n\ +If the channel is empty then the keyword args are ignored and both\n\ +ends are immediately closed. Otherwise, if 'force' is True then\n\ +all queued items are released and both ends are immediately\n\ +closed.\n\ +\n\ +If the channel is not empty *and* 'force' is False then following\n\ +happens:\n\ +\n\ + * recv is True (regardless of send):\n\ + - raise ChannelNotEmptyError\n\ + * recv is None and send is None:\n\ + - raise ChannelNotEmptyError\n\ + * send is True and recv is not True:\n\ + - fully close the 'send' end\n\ + - close the 'recv' end to interpreters not already receiving\n\ + - fully close it once empty\n\ +\n\ +Closing an already closed channel results in a ChannelClosedError.\n\ +\n\ +Once the channel's ID has no more ref counts in any interpreter\n\ +the channel will be destroyed."); + +static PyObject * +channel_release(PyObject *self, PyObject *args, PyObject *kwds) +{ + // Note that only the current interpreter is affected. + static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; + int64_t cid; + int send = 0; + int recv = 0; + int force = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&|$ppp:channel_release", kwlist, + channel_id_converter, &cid, &send, &recv, &force)) { + return NULL; + } + if (send == 0 && recv == 0) { + send = 1; + recv = 1; + } + + // XXX Handle force is True. + // XXX Fix implicit release. + + if (_channel_drop(&_globals.channels, cid, send, recv) != 0) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_release_doc, +"channel_release(cid, *, send=None, recv=None, force=True)\n\ +\n\ +Close the channel for the current interpreter. 'send' and 'recv'\n\ +(bool) may be used to indicate the ends to close. By default both\n\ +ends are closed. Closing an already closed end is a noop."); + +static PyObject * +channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds) +{ + return channelid_new(&ChannelIDtype, args, kwds); +} + +static PyMethodDef module_functions[] = { + {"create", (PyCFunction)interp_create, + METH_VARARGS, create_doc}, + {"destroy", (PyCFunction)(void(*)(void))interp_destroy, + METH_VARARGS | METH_KEYWORDS, destroy_doc}, + {"list_all", interp_list_all, + METH_NOARGS, list_all_doc}, + {"get_current", interp_get_current, + METH_NOARGS, get_current_doc}, + {"get_main", interp_get_main, + METH_NOARGS, get_main_doc}, + {"is_running", (PyCFunction)(void(*)(void))interp_is_running, + METH_VARARGS | METH_KEYWORDS, is_running_doc}, + {"run_string", (PyCFunction)(void(*)(void))interp_run_string, + METH_VARARGS | METH_KEYWORDS, run_string_doc}, + + {"is_shareable", (PyCFunction)(void(*)(void))object_is_shareable, + METH_VARARGS | METH_KEYWORDS, is_shareable_doc}, + + {"channel_create", channel_create, + METH_NOARGS, channel_create_doc}, + {"channel_destroy", (PyCFunction)(void(*)(void))channel_destroy, + METH_VARARGS | METH_KEYWORDS, channel_destroy_doc}, + {"channel_list_all", channel_list_all, + METH_NOARGS, channel_list_all_doc}, + {"channel_send", (PyCFunction)(void(*)(void))channel_send, + METH_VARARGS | METH_KEYWORDS, channel_send_doc}, + {"channel_recv", (PyCFunction)(void(*)(void))channel_recv, + METH_VARARGS | METH_KEYWORDS, channel_recv_doc}, + {"channel_close", (PyCFunction)(void(*)(void))channel_close, + METH_VARARGS | METH_KEYWORDS, channel_close_doc}, + {"channel_release", (PyCFunction)(void(*)(void))channel_release, + METH_VARARGS | METH_KEYWORDS, channel_release_doc}, + {"_channel_id", (PyCFunction)(void(*)(void))channel__channel_id, + METH_VARARGS | METH_KEYWORDS, NULL}, + + {NULL, NULL} /* sentinel */ +}; + + +/* initialization function */ + +PyDoc_STRVAR(module_doc, +"This module provides primitive operations to manage Python interpreters.\n\ +The 'interpreters' module provides a more convenient interface."); + +static struct PyModuleDef interpretersmodule = { + PyModuleDef_HEAD_INIT, + "_xxsubinterpreters", /* m_name */ + module_doc, /* m_doc */ + -1, /* m_size */ + module_functions, /* m_methods */ + NULL, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; + + +PyMODINIT_FUNC +PyInit__xxsubinterpreters(void) +{ + if (_init_globals() != 0) { + return NULL; + } + + /* Initialize types */ + if (PyType_Ready(&ChannelIDtype) != 0) { + return NULL; + } + + /* Create the module */ + PyObject *module = PyModule_Create(&interpretersmodule); + if (module == NULL) { + return NULL; + } + + /* Add exception types */ + PyObject *ns = PyModule_GetDict(module); // borrowed + if (interp_exceptions_init(ns) != 0) { + return NULL; + } + if (channel_exceptions_init(ns) != 0) { + return NULL; + } + + /* Add other types */ + Py_INCREF(&ChannelIDtype); + if (PyDict_SetItemString(ns, "ChannelID", (PyObject *)&ChannelIDtype) != 0) { + return NULL; + } + Py_INCREF(&_PyInterpreterID_Type); + if (PyDict_SetItemString(ns, "InterpreterID", (PyObject *)&_PyInterpreterID_Type) != 0) { + return NULL; + } + + if (_PyCrossInterpreterData_RegisterClass(&ChannelIDtype, _channelid_shared)) { + return NULL; + } + + return module; +} diff --git a/python/Modules/_xxtestfuzz/README.rst b/python/Modules/_xxtestfuzz/README.rst new file mode 100755 index 0000000..42bd02a --- /dev/null +++ b/python/Modules/_xxtestfuzz/README.rst @@ -0,0 +1,56 @@ +Fuzz Tests for CPython +====================== + +These fuzz tests are designed to be included in Google's `oss-fuzz`_ project. + +oss-fuzz works against a library exposing a function of the form +``int LLVMFuzzerTestOneInput(const uint8_t* data, size_t length)``. We provide +that library (``fuzzer.c``), and include a ``_fuzz`` module for testing with +some toy values -- no fuzzing occurs in Python's test suite. + +oss-fuzz will regularly pull from CPython, discover all the tests in +``fuzz_tests.txt``, and run them -- so adding a new test here means it will +automatically be run in oss-fuzz, while also being smoke-tested as part of +CPython's test suite. + +Adding a new fuzz test +---------------------- + +Add the test name on a new line in ``fuzz_tests.txt``. + +In ``fuzzer.c``, add a function to be run:: + + int $test_name (const char* data, size_t size) { + ... + return 0; + } + + +And invoke it from ``LLVMFuzzerTestOneInput``:: + + #if _Py_FUZZ_YES(fuzz_builtin_float) + rv |= _run_fuzz(data, size, fuzz_builtin_float); + #endif + +``LLVMFuzzerTestOneInput`` will run in oss-fuzz, with each test in +``fuzz_tests.txt`` run separately. + +Seed data (corpus) for the test can be provided in a subfolder called +``_corpus`` such as ``fuzz_json_loads_corpus``. A wide variety +of good input samples allows the fuzzer to more easily explore a diverse +set of paths and provides a better base to find buggy input from. + +Dictionaries of tokens (see oss-fuzz documentation for more details) can +be placed in the ``dictionaries`` folder with the name of the test. +For example, ``dictionaries/fuzz_json_loads.dict`` contains JSON tokens +to guide the fuzzer. + +What makes a good fuzz test +--------------------------- + +Libraries written in C that might handle untrusted data are worthwhile. The +more complex the logic (e.g. parsing), the more likely this is to be a useful +fuzz test. See the existing examples for reference, and refer to the +`oss-fuzz`_ docs. + +.. _oss-fuzz: https://github.com/google/oss-fuzz diff --git a/python/Modules/_xxtestfuzz/_xxtestfuzz.c b/python/Modules/_xxtestfuzz/_xxtestfuzz.c new file mode 100755 index 0000000..781dd23 --- /dev/null +++ b/python/Modules/_xxtestfuzz/_xxtestfuzz.c @@ -0,0 +1,53 @@ +#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) +{ + PyObject *m = NULL; + + if ((m = PyModule_Create(&_fuzzmodule)) == NULL) { + return NULL; + } + return m; +} diff --git a/python/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict b/python/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict new file mode 100755 index 0000000..ad64917 --- /dev/null +++ b/python/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict @@ -0,0 +1,40 @@ +"0" +",0" +":0" +"0:" +"-1.2e+3" + +"true" +"false" +"null" + +"\"\"" +",\"\"" +":\"\"" +"\"\":" + +"{}" +",{}" +":{}" +"{\"\":0}" +"{{}}" + +"[]" +",[]" +":[]" +"[0]" +"[[]]" + +"''" +"\\" +"\\b" +"\\f" +"\\n" +"\\r" +"\\t" +"\\u0000" +"\\x00" +"\\0" +"\\uD800\\uDC00" +"\\uDBFF\\uDFFF" + diff --git a/python/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict b/python/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict new file mode 100755 index 0000000..961306a --- /dev/null +++ b/python/Modules/_xxtestfuzz/dictionaries/fuzz_sre_compile.dict @@ -0,0 +1,219 @@ +"?" +"abc" +"()" +"[]" +"abc|def" +"abc|def|ghi" +"^xxx$" +"ab\\b\\d\\bcd" +"\\w|\\d" +"a*?" +"abc+" +"abc+?" +"xyz?" +"xyz??" +"xyz{0,1}" +"xyz{0,1}?" +"xyz{93}" +"xyz{1,32}" +"xyz{1,32}?" +"xyz{1,}" +"xyz{1,}?" +"a\\fb\\nc\\rd\\te\\vf" +"a\\nb\\bc" +"(?:foo)" +"(?: foo )" +"foo|(bar|baz)|quux" +"foo(?=bar)baz" +"foo(?!bar)baz" +"foo(?<=bar)baz" +"foo(?)" +"(?.)" +"(?.)\\k" diff --git a/python/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv b/python/Modules/_xxtestfuzz/fuzz_csv_reader_corpus/test.csv new file mode 100755 index 0000000000000000000000000000000000000000..8b7887d0f1d2426354ec0d01fb06768604406dc0 GIT binary patch literal 118 zcmXwwNeX~45ClEv6~mkq8$tbmUm11KfN_oBf`3;C)}bkAs#j@sr5t^b;+GPOf(O5_Fsw=uRKQIfG-Vn@SIH^Pt&RC5#NlL@()@BrgB} literal 0 HcmV?d00001 diff --git a/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json new file mode 100755 index 0000000..fe51488 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json @@ -0,0 +1 @@ +[] diff --git a/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json new file mode 100755 index 0000000..0967ef4 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json @@ -0,0 +1 @@ +{} diff --git a/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json new file mode 100755 index 0000000..70e2685 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"] \ No newline at end of file diff --git a/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json new file mode 100755 index 0000000..d3c63c7 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json new file mode 100755 index 0000000..4528d51 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json new file mode 100755 index 0000000..ce1e6ec --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json @@ -0,0 +1 @@ +[1, 2, 3, "abcd", "xyz"] diff --git a/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links new file mode 100755 index 0000000..d99247c --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/anchor_links @@ -0,0 +1 @@ +XX] diff --git a/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters new file mode 100755 index 0000000..0c67ee7 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/characters @@ -0,0 +1 @@ +XX^(Tim|Robert)\s+the\s+(Enchanter|Shrubber)$ diff --git a/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn new file mode 100755 index 0000000..cce8919 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/isbn @@ -0,0 +1 @@ +XX/((978[\--– ])?[0-9][0-9\--– ]{10}[\--– ][0-9xX])|((978)?[0-9]{9}[0-9Xx])/ diff --git a/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number new file mode 100755 index 0000000..1e2efc5 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_sre_compile_corpus/phone_number @@ -0,0 +1 @@ +XX(\+1|1)?[ \-\.]?\(?(?[0-9]{3})\)?[ \-\.]?(?[0-9]{3})[ \-\.]?(?[0-9]{4})[ \.]*(ext|x)?[ \.]*(?[0-9]{0,5}) diff --git a/python/Modules/_xxtestfuzz/fuzz_tests.txt b/python/Modules/_xxtestfuzz/fuzz_tests.txt new file mode 100755 index 0000000..9d330a6 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzz_tests.txt @@ -0,0 +1,7 @@ +fuzz_builtin_float +fuzz_builtin_int +fuzz_builtin_unicode +fuzz_json_loads +fuzz_sre_compile +fuzz_sre_match +fuzz_csv_reader diff --git a/python/Modules/_xxtestfuzz/fuzzer.c b/python/Modules/_xxtestfuzz/fuzzer.c new file mode 100755 index 0000000..1821eb2 --- /dev/null +++ b/python/Modules/_xxtestfuzz/fuzzer.c @@ -0,0 +1,426 @@ +/* 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) { + /* 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; +} + +#define MAX_JSON_TEST_SIZE 0x10000 + +PyObject* json_loads_method = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_json_loads() { + /* Import json.loads */ + PyObject* json_module = PyImport_ImportModule("json"); + if (json_module == NULL) { + return 0; + } + json_loads_method = PyObject_GetAttrString(json_module, "loads"); + return json_loads_method != NULL; +} +/* Fuzz json.loads(x) */ +static int fuzz_json_loads(const char* data, size_t size) { + /* Since python supports arbitrarily large ints in JSON, + long inputs can lead to timeouts on boring inputs like + `json.loads("9" * 100000)` */ + if (size > MAX_JSON_TEST_SIZE) { + return 0; + } + PyObject* input_bytes = PyBytes_FromStringAndSize(data, size); + if (input_bytes == NULL) { + return 0; + } + PyObject* parsed = PyObject_CallFunctionObjArgs(json_loads_method, input_bytes, NULL); + if (parsed == NULL) { + /* Ignore ValueError as the fuzzer will more than likely + generate some invalid json and values */ + if (PyErr_ExceptionMatches(PyExc_ValueError) || + /* Ignore RecursionError as the fuzzer generates long sequences of + arrays such as `[[[...` */ + PyErr_ExceptionMatches(PyExc_RecursionError) || + /* Ignore unicode errors, invalid byte sequences are common */ + PyErr_ExceptionMatches(PyExc_UnicodeDecodeError) + ) { + PyErr_Clear(); + } + } + Py_DECREF(input_bytes); + Py_XDECREF(parsed); + return 0; +} + +#define MAX_RE_TEST_SIZE 0x10000 + +PyObject* sre_compile_method = NULL; +PyObject* sre_error_exception = NULL; +int SRE_FLAG_DEBUG = 0; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_sre_compile() { + /* Import sre_compile.compile and sre.error */ + PyObject* sre_compile_module = PyImport_ImportModule("sre_compile"); + if (sre_compile_module == NULL) { + return 0; + } + sre_compile_method = PyObject_GetAttrString(sre_compile_module, "compile"); + if (sre_compile_method == NULL) { + return 0; + } + + PyObject* sre_constants = PyImport_ImportModule("sre_constants"); + if (sre_constants == NULL) { + return 0; + } + sre_error_exception = PyObject_GetAttrString(sre_constants, "error"); + if (sre_error_exception == NULL) { + return 0; + } + PyObject* debug_flag = PyObject_GetAttrString(sre_constants, "SRE_FLAG_DEBUG"); + if (debug_flag == NULL) { + return 0; + } + SRE_FLAG_DEBUG = PyLong_AsLong(debug_flag); + return 1; +} +/* Fuzz _sre.compile(x) */ +static int fuzz_sre_compile(const char* data, size_t size) { + /* Ignore really long regex patterns that will timeout the fuzzer */ + if (size > MAX_RE_TEST_SIZE) { + return 0; + } + /* We treat the first 2 bytes of the input as a number for the flags */ + if (size < 2) { + return 0; + } + uint16_t flags = ((uint16_t*) data)[0]; + /* We remove the SRE_FLAG_DEBUG if present. This is because it + prints to stdout which greatly decreases fuzzing speed */ + flags &= ~SRE_FLAG_DEBUG; + + /* Pull the pattern from the remaining bytes */ + PyObject* pattern_bytes = PyBytes_FromStringAndSize(data + 2, size - 2); + if (pattern_bytes == NULL) { + return 0; + } + PyObject* flags_obj = PyLong_FromUnsignedLong(flags); + if (flags_obj == NULL) { + Py_DECREF(pattern_bytes); + return 0; + } + + /* compiled = _sre.compile(data[2:], data[0:2] */ + PyObject* compiled = PyObject_CallFunctionObjArgs( + sre_compile_method, pattern_bytes, flags_obj, NULL); + /* Ignore ValueError as the fuzzer will more than likely + generate some invalid combination of flags */ + if (compiled == NULL && PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + } + /* Ignore some common errors thrown by sre_parse: + Overflow, Assertion and Index */ + if (compiled == NULL && (PyErr_ExceptionMatches(PyExc_OverflowError) || + PyErr_ExceptionMatches(PyExc_AssertionError) || + PyErr_ExceptionMatches(PyExc_IndexError)) + ) { + PyErr_Clear(); + } + /* Ignore re.error */ + if (compiled == NULL && PyErr_ExceptionMatches(sre_error_exception)) { + PyErr_Clear(); + } + + Py_DECREF(pattern_bytes); + Py_DECREF(flags_obj); + Py_XDECREF(compiled); + return 0; +} + +/* Some random patterns used to test re.match. + Be careful not to add catostraphically slow regexes here, we want to + exercise the matching code without causing timeouts.*/ +static const char* regex_patterns[] = { + ".", "^", "abc", "abc|def", "^xxx$", "\\b", "()", "[a-zA-Z0-9]", + "abc+", "[^A-Z]", "[x]", "(?=)", "a{z}", "a+b", "a*?", "a??", "a+?", + "{}", "a{,}", "{", "}", "^\\(*\\d{3}\\)*( |-)*\\d{3}( |-)*\\d{4}$", + "(?:a*)*", "a{1,2}?" +}; +const size_t NUM_PATTERNS = sizeof(regex_patterns) / sizeof(regex_patterns[0]); +PyObject** compiled_patterns = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_sre_match() { + PyObject* re_module = PyImport_ImportModule("re"); + if (re_module == NULL) { + return 0; + } + compiled_patterns = (PyObject**) PyMem_RawMalloc( + sizeof(PyObject*) * NUM_PATTERNS); + if (compiled_patterns == NULL) { + PyErr_NoMemory(); + return 0; + } + + /* Precompile all the regex patterns on the first run for faster fuzzing */ + for (size_t i = 0; i < NUM_PATTERNS; i++) { + PyObject* compiled = PyObject_CallMethod( + re_module, "compile", "y", regex_patterns[i]); + /* Bail if any of the patterns fail to compile */ + if (compiled == NULL) { + return 0; + } + compiled_patterns[i] = compiled; + } + return 1; +} +/* Fuzz re.match(x) */ +static int fuzz_sre_match(const char* data, size_t size) { + if (size < 1 || size > MAX_RE_TEST_SIZE) { + return 0; + } + /* Use the first byte as a uint8_t specifying the index of the + regex to use */ + unsigned char idx = (unsigned char) data[0]; + idx = idx % NUM_PATTERNS; + + /* Pull the string to match from the remaining bytes */ + PyObject* to_match = PyBytes_FromStringAndSize(data + 1, size - 1); + if (to_match == NULL) { + return 0; + } + + PyObject* pattern = compiled_patterns[idx]; + PyObject* match_callable = PyObject_GetAttrString(pattern, "match"); + + PyObject* matches = PyObject_CallFunctionObjArgs(match_callable, to_match, NULL); + + Py_XDECREF(matches); + Py_DECREF(match_callable); + Py_DECREF(to_match); + return 0; +} + +#define MAX_CSV_TEST_SIZE 0x10000 +PyObject* csv_module = NULL; +PyObject* csv_error = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_csv_reader() { + /* Import csv and csv.Error */ + csv_module = PyImport_ImportModule("csv"); + if (csv_module == NULL) { + return 0; + } + csv_error = PyObject_GetAttrString(csv_module, "Error"); + return csv_error != NULL; +} +/* Fuzz csv.reader([x]) */ +static int fuzz_csv_reader(const char* data, size_t size) { + if (size < 1 || size > MAX_CSV_TEST_SIZE) { + return 0; + } + /* Ignore non null-terminated strings since _csv can't handle + embeded nulls */ + if (memchr(data, '\0', size) == NULL) { + return 0; + } + + PyObject* s = PyUnicode_FromString(data); + /* Ignore exceptions until we have a valid string */ + if (s == NULL) { + PyErr_Clear(); + return 0; + } + + /* Split on \n so we can test multiple lines */ + PyObject* lines = PyObject_CallMethod(s, "split", "s", "\n"); + if (lines == NULL) { + Py_DECREF(s); + return 0; + } + + PyObject* reader = PyObject_CallMethod(csv_module, "reader", "N", lines); + if (reader) { + /* Consume all of the reader as an iterator */ + PyObject* parsed_line; + while ((parsed_line = PyIter_Next(reader))) { + Py_DECREF(parsed_line); + } + } + + /* Ignore csv.Error because we're probably going to generate + some bad files (embeded new-lines, unterminated quotes etc) */ + if (PyErr_ExceptionMatches(csv_error)) { + PyErr_Clear(); + } + + Py_XDECREF(reader); + Py_DECREF(s); + 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; } + + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + wchar_t* wide_program_name = Py_DecodeLocale(*argv[0], NULL); + Py_SetProgramName(wide_program_name); + 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 +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_json_loads) + static int JSON_LOADS_INITIALIZED = 0; + if (!JSON_LOADS_INITIALIZED && !init_json_loads()) { + PyErr_Print(); + abort(); + } else { + JSON_LOADS_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_json_loads); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_sre_compile) + static int SRE_COMPILE_INITIALIZED = 0; + if (!SRE_COMPILE_INITIALIZED && !init_sre_compile()) { + PyErr_Print(); + abort(); + } else { + SRE_COMPILE_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_sre_compile); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_sre_match) + static int SRE_MATCH_INITIALIZED = 0; + if (!SRE_MATCH_INITIALIZED && !init_sre_match()) { + PyErr_Print(); + abort(); + } else { + SRE_MATCH_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_sre_match); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_csv_reader) + static int CSV_READER_INITIALIZED = 0; + if (!CSV_READER_INITIALIZED && !init_csv_reader()) { + PyErr_Print(); + abort(); + } else { + CSV_READER_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_csv_reader); +#endif + return rv; +} diff --git a/python/Modules/addrinfo.h b/python/Modules/addrinfo.h new file mode 100755 index 0000000..c3c8624 --- /dev/null +++ b/python/Modules/addrinfo.h @@ -0,0 +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 diff --git a/python/Modules/arraymodule.c b/python/Modules/arraymodule.c new file mode 100755 index 0000000..abcdd1e --- /dev/null +++ b/python/Modules/arraymodule.c @@ -0,0 +1,3095 @@ +/* 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 "structmember.h" + +#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 */ + int 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) +#define array_CheckExact(op) (Py_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) { + Py_SIZE(self) = newsize; + return 0; + } + + if (newsize == 0) { + PyMem_FREE(self->ob_item); + self->ob_item = NULL; + Py_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; + Py_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) +{ + long x = ((char *)ap->ob_item)[i]; + if (x >= 128) + x -= 256; + 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(((Py_UNICODE *) ap->ob_item)[i]); +} + +static int +u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + Py_UNICODE *p; + Py_ssize_t len; + + if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len)) + return -1; + if (len != 1) { + PyErr_SetString(PyExc_TypeError, + "array item must be unicode character"); + return -1; + } + if (i >= 0) + ((Py_UNICODE *)ap->ob_item)[i] = p[0]; + 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, Py_UNICODE) +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(Py_UNICODE), 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_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_CallMethodIdObjArgs(f, &PyId_write, bytes, NULL); + 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.fromstring + + buffer: Py_buffer(accept={str, 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). + +This method is deprecated. Use frombytes instead. +[clinic start generated code]*/ + +static PyObject * +array_array_fromstring_impl(arrayobject *self, Py_buffer *buffer) +/*[clinic end generated code: output=31c4baa779df84ce input=a3341a512e11d773]*/ +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "fromstring() is deprecated. Use frombytes() instead.", 2) != 0) + return NULL; + return frombytes(self, buffer); +} + +/*[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=2bbf2b53ebfcc988]*/ +{ + 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.tostring + +Convert the array to an array of machine values and return the bytes representation. + +This method is deprecated. Use tobytes instead. +[clinic start generated code]*/ + +static PyObject * +array_array_tostring_impl(arrayobject *self) +/*[clinic end generated code: output=7d6bd92745a2c8f3 input=b6c0ddee7b30457e]*/ +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "tostring() is deprecated. Use tobytes() instead.", 2) != 0) + return NULL; + return array_array_tobytes_impl(self); +} + +/*[clinic input] +array.array.fromunicode + + ustr: Py_UNICODE(zeroes=True) + / + +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, const Py_UNICODE *ustr, + Py_ssize_clean_t ustr_length) +/*[clinic end generated code: output=cf2f662908e2befc input=150f00566ffbca6e]*/ +{ + char typecode; + + typecode = self->ob_descr->typecode; + if (typecode != 'u') { + PyErr_SetString(PyExc_ValueError, + "fromunicode() may only be called on " + "unicode type arrays"); + return NULL; + } + if (ustr_length > 0) { + Py_ssize_t old_size = Py_SIZE(self); + if (array_resize(self, old_size + ustr_length) == -1) + return NULL; + memcpy(self->ob_item + old_size * sizeof(Py_UNICODE), + ustr, ustr_length * sizeof(Py_UNICODE)); + } + + 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]*/ +{ + char typecode; + typecode = self->ob_descr->typecode; + if (typecode != 'u') { + PyErr_SetString(PyExc_ValueError, + "tounicode() may only be called on unicode type arrays"); + return NULL; + } + return PyUnicode_FromWideChar((Py_UNICODE *) 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: { + 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: { + 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: { + 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_FROMSTRING_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_TOSTRING_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 { + 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 (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_UNICODE *ustr; + Py_ssize_t n; + + ustr = PyUnicode_AsUnicode(initial); + if (ustr == NULL) { + PyErr_NoMemory(); + Py_DECREF(a); + return NULL; + } + + n = PyUnicode_GET_DATA_SIZE(initial); + if (n > 0) { + arrayobject *self = (arrayobject *)a; + char *item = self->ob_item; + item = (char *)PyMem_Realloc(item, n); + if (item == NULL) { + PyErr_NoMemory(); + Py_DECREF(a); + return NULL; + } + self->ob_item = item; + Py_SIZE(self) = n / sizeof(Py_UNICODE); + memcpy(item, ustr, n); + self->allocated = Py_SIZE(self); + } + } + 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\ + 'u' Unicode character 2 (see note)\n\ + 'h' signed integer 2\n\ + 'H' unsigned integer 2\n\ + 'i' signed integer 2\n\ + 'I' unsigned integer 2\n\ + 'l' signed integer 4\n\ + 'L' unsigned integer 4\n\ + 'q' signed integer 8 (see note)\n\ + 'Q' unsigned integer 8 (see note)\n\ + 'f' floating point 4\n\ + 'd' floating point 8\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\ +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 */ + 0, /* tp_vectorcall_offset */ + 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]*/ +{ + _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 */ + 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,/* 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; + Py_ssize_t size = 0; + const struct arraydescr *descr; + + if (PyType_Ready(&Arraytype) < 0) + return -1; + Py_TYPE(&PyArrayIter_Type) = &PyType_Type; + + Py_INCREF((PyObject *)&Arraytype); + if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) { + Py_DECREF((PyObject *)&Arraytype); + return -1; + } + Py_INCREF((PyObject *)&Arraytype); + if (PyModule_AddObject(m, "array", (PyObject *)&Arraytype) < 0) { + Py_DECREF((PyObject *)&Arraytype); + return -1; + } + + for (descr=descriptors; descr->typecode != '\0'; descr++) { + size++; + } + + 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); +} diff --git a/python/Modules/atexitmodule.c b/python/Modules/atexitmodule.c new file mode 100755 index 0000000..1d6d6e5 --- /dev/null +++ b/python/Modules/atexitmodule.c @@ -0,0 +1,354 @@ +/* + * 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; + +#define GET_ATEXIT_STATE(mod) ((atexitmodule_state*)PyModule_GetState(mod)) + + +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; + + 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) +{ + 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; + + 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; + + modstate = GET_ATEXIT_STATE(self); + if (modstate != NULL) { + for (i = 0; i < modstate->ncallbacks; i++) { + atexit_callback *cb = modstate->atexit_callbacks[i]; + if (cb == NULL) + continue; + Py_VISIT(cb->func); + Py_VISIT(cb->args); + Py_VISIT(cb->kwargs); + } + } + return 0; +} + +static int +atexit_m_clear(PyObject *self) +{ + atexitmodule_state *modstate; + modstate = GET_ATEXIT_STATE(self); + if (modstate != NULL) { + atexit_cleanup(modstate); + } + return 0; +} + +static void +atexit_free(PyObject *m) +{ + atexitmodule_state *modstate; + modstate = GET_ATEXIT_STATE(m); + if (modstate != NULL) { + 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; + + 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[] = { + {"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; + + 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); +} diff --git a/python/Modules/audioop.c b/python/Modules/audioop.c new file mode 100755 index 0000000..f4fdeb2 --- /dev/null +++ b/python/Modules/audioop.c @@ -0,0 +1,1927 @@ + +/* 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 PyObject *AudioopError; + +static int +audioop_check_size(int size) +{ + if (size < 1 || size > 4) { + PyErr_SetString(AudioopError, "Size should be 1, 2, 3 or 4"); + return 0; + } + else + return 1; +} + +static int +audioop_check_parameters(Py_ssize_t len, int size) +{ + if (!audioop_check_size(size)) + return 0; + if (len % size != 0) { + PyErr_SetString(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; + + if (!audioop_check_parameters(fragment->len, width)) + return NULL; + if (index < 0 || index >= fragment->len/width) { + PyErr_SetString(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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) { + PyErr_SetString(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) { + PyErr_SetString(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) { + PyErr_SetString(AudioopError, "Strings should be even-sized"); + return NULL; + } + if (fragment->len != reference->len) { + PyErr_SetString(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) { + PyErr_SetString(AudioopError, "Strings should be even-sized"); + return NULL; + } + cp1 = (const int16_t *)fragment->buf; + len1 = fragment->len >> 1; + + if (length < 0 || len1 < length) { + PyErr_SetString(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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; + if (!audioop_check_parameters(len, width)) + return NULL; + if (((len / width) & 1) != 0) { + PyErr_SetString(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(fragment1->len, width)) + return NULL; + if (fragment1->len != fragment2->len) { + PyErr_SetString(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_parameters(fragment->len, width)) + return NULL; + if (!audioop_check_size(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; + + if (!audioop_check_size(width)) + return NULL; + if (nchannels < 1) { + PyErr_SetString(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) { + PyErr_SetString(AudioopError, + "weightA should be >= 1, weightB should be >= 0"); + return NULL; + } + assert(fragment->len >= 0); + if (fragment->len % bytes_per_frame != 0) { + PyErr_SetString(AudioopError, "not a whole number of frames"); + return NULL; + } + if (inrate <= 0 || outrate <= 0) { + PyErr_SetString(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) { + PyErr_SetString(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_size(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_size(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; + + if (!audioop_check_parameters(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; + + if (!audioop_check_size(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 } +}; + + +static struct PyModuleDef audioopmodule = { + PyModuleDef_HEAD_INIT, + "audioop", + NULL, + -1, + audioop_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_audioop(void) +{ + PyObject *m, *d; + m = PyModule_Create(&audioopmodule); + if (m == NULL) + return NULL; + d = PyModule_GetDict(m); + if (d == NULL) + return NULL; + AudioopError = PyErr_NewException("audioop.error", NULL, NULL); + if (AudioopError != NULL) + PyDict_SetItemString(d,"error",AudioopError); + return m; +} diff --git a/python/Modules/binascii.c b/python/Modules/binascii.c new file mode 100755 index 0000000..1c7dc35 --- /dev/null +++ b/python/Modules/binascii.c @@ -0,0 +1,1668 @@ +/* +** 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; + +/* +** 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 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, + 41,42,43,44, 45,46,47,48, 49,50,51,-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; + 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)) { + 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' ) { + 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; + 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 */ + 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); +} + + +static int +binascii_find_valid(const unsigned char *s, Py_ssize_t slen, int num) +{ + /* Finds & returns the (num+1)th + ** valid character for base64, or -1 if none. + */ + + int ret = -1; + unsigned char c, b64val; + + while ((slen > 0) && (ret == -1)) { + c = *s; + b64val = table_a2b_base64[c & 0x7f]; + if ( ((c <= 0x7f) && (b64val != (unsigned char)-1)) ) { + if (num == 0) + ret = *s; + num--; + } + + s++; + slen--; + } + return ret; +} + +/*[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]*/ +{ + const unsigned char *ascii_data; + unsigned char *bin_data; + unsigned char *bin_data_start; + int leftbits = 0; + unsigned char this_ch; + unsigned int leftchar = 0; + Py_ssize_t ascii_len, bin_len; + int quad_pos = 0; + _PyBytesWriter writer; + binascii_state *state; + + ascii_data = data->buf; + ascii_len = data->len; + + assert(ascii_len >= 0); + + if (ascii_len > PY_SSIZE_T_MAX - 3) + return PyErr_NoMemory(); + + bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ + + _PyBytesWriter_Init(&writer); + + /* Allocate the buffer */ + bin_data = _PyBytesWriter_Alloc(&writer, bin_len); + if (bin_data == NULL) + return NULL; + bin_data_start = bin_data; + + for( ; ascii_len > 0; ascii_len--, ascii_data++) { + this_ch = *ascii_data; + + if (this_ch > 0x7f || + this_ch == '\r' || this_ch == '\n' || this_ch == ' ') + continue; + + /* Check for pad sequences and ignore + ** the invalid ones. + */ + if (this_ch == BASE64_PAD) { + if ( (quad_pos < 2) || + ((quad_pos == 2) && + (binascii_find_valid(ascii_data, ascii_len, 1) + != BASE64_PAD)) ) + { + continue; + } + else { + /* A pad sequence means no more input. + ** We've already interpreted the data + ** from the quad at this point. + */ + leftbits = 0; + break; + } + } + + this_ch = table_a2b_base64[*ascii_data]; + if ( this_ch == (unsigned char) -1 ) + continue; + + /* + ** Shift it in on the low end, and see if there's + ** a byte ready for output. + */ + quad_pos = (quad_pos + 1) & 0x03; + leftchar = (leftchar << 6) | (this_ch); + leftbits += 6; + + if ( leftbits >= 8 ) { + leftbits -= 8; + *bin_data++ = (leftchar >> leftbits) & 0xff; + leftchar &= ((1 << leftbits) - 1); + } + } + + if (leftbits != 0) { + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + if (leftbits == 6) { + /* + ** 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: " + "number of data characters (%zd) cannot be 1 more " + "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; + } + + 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 ) { + 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]*/ +{ + 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 ) { + 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 ) { + 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]*/ +{ + 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]*/ +{ + 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]*/ +{ + 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 ) { \ + 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. + */ + 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] +binascii.crc_hqx -> unsigned_int + + data: Py_buffer + crc: unsigned_int(bitwise=True) + / + +Compute CRC-CCITT incrementally. +[clinic start generated code]*/ + +static unsigned int +binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: output=8ec2a78590d19170 input=f18240ff8c705b79]*/ +{ + 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 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 + 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()". + +Example: +>>> binascii.b2a_hex(b'\xb9\x01\xef') +b'b901ef' +>>> binascii.hexlify(b'\xb9\x01\xef', ':') +b'b9:01:ef' +>>> binascii.b2a_hex(b'\xb9\x01\xef', b'_', 2) +b'b9_01ef' +[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. + +The return value is a bytes object. This function is also +available as "b2a_hex()". +[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; + 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) { + 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) { + unsigned int top = _PyLong_DigitValue[Py_CHARMASK(argbuf[i])]; + unsigned int bot = _PyLong_DigitValue[Py_CHARMASK(argbuf[i+1])]; + if (top >= 16 || bot >= 16) { + state = PyModule_GetState(module); + if (state == NULL) { + 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. + * The previous implementation used calloc() so we'll zero out the + * memory here too, since PyMem_Malloc() does not guarantee that. + */ + odata = (unsigned char *) PyMem_Malloc(datalen); + if (odata == NULL) { + PyErr_NoMemory(); + return NULL; + } + memset(odata, 0, datalen); + + 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++; + 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. + * The previous implementation used calloc() so we'll zero out the + * memory here too, since PyMem_Malloc() does not guarantee that. + */ + odata = (unsigned char *) PyMem_Malloc(odatalen); + if (odata == NULL) { + PyErr_NoMemory(); + return NULL; + } + memset(odata, 0, odatalen); + + 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 *m) { + int result; + binascii_state *state = PyModule_GetState(m); + if (state == NULL) { + return -1; + } + + state->Error = PyErr_NewException("binascii.Error", PyExc_ValueError, NULL); + if (state->Error == NULL) { + return -1; + } + result = PyModule_AddObject(m, "Error", state->Error); + if (result == -1) { + return -1; + } + + state->Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL); + if (state->Incomplete == NULL) { + return -1; + } + result = PyModule_AddObject(m, "Incomplete", state->Incomplete); + if (result == -1) { + return -1; + } + + return 0; +} + +static PyModuleDef_Slot binascii_slots[] = { + {Py_mod_exec, binascii_exec}, + {0, NULL} +}; + +static struct PyModuleDef binasciimodule = { + PyModuleDef_HEAD_INIT, + "binascii", + doc_binascii, + sizeof(binascii_state), + binascii_module_methods, + binascii_slots, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_binascii(void) +{ + return PyModuleDef_Init(&binasciimodule); +} diff --git a/python/Modules/cjkcodecs/README b/python/Modules/cjkcodecs/README new file mode 100755 index 0000000..b2370bc --- /dev/null +++ b/python/Modules/cjkcodecs/README @@ -0,0 +1,79 @@ +To generate or modify mapping headers +------------------------------------- +Mapping headers are imported from CJKCodecs as pre-generated form. +If you need to tweak or add something on it, please look at tools/ +subdirectory of CJKCodecs' distribution. + + + +Notes on implmentation characteristics of each codecs +----------------------------------------------------- + +1) Big5 codec + + The big5 codec maps the following characters as cp950 does rather + than conforming Unicode.org's that maps to 0xFFFD. + + BIG5 Unicode Description + + 0xA15A 0x2574 SPACING UNDERSCORE + 0xA1C3 0xFFE3 SPACING HEAVY OVERSCORE + 0xA1C5 0x02CD SPACING HEAVY UNDERSCORE + 0xA1FE 0xFF0F LT DIAG UP RIGHT TO LOW LEFT + 0xA240 0xFF3C LT DIAG UP LEFT TO LOW RIGHT + 0xA2CC 0x5341 HANGZHOU NUMERAL TEN + 0xA2CE 0x5345 HANGZHOU NUMERAL THIRTY + + Because unicode 0x5341, 0x5345, 0xFF0F, 0xFF3C is mapped to another + big5 codes already, a roundtrip compatibility is not guaranteed for + them. + + +2) cp932 codec + + To conform to Windows's real mapping, cp932 codec maps the following + codepoints in addition of the official cp932 mapping. + + CP932 Unicode Description + + 0x80 0x80 UNDEFINED + 0xA0 0xF8F0 UNDEFINED + 0xFD 0xF8F1 UNDEFINED + 0xFE 0xF8F2 UNDEFINED + 0xFF 0xF8F3 UNDEFINED + + +3) euc-jisx0213 codec + + The euc-jisx0213 codec maps JIS X 0213 Plane 1 code 0x2140 into + unicode U+FF3C instead of U+005C as on unicode.org's mapping. + Because euc-jisx0213 has REVERSE SOLIDUS on 0x5c already and A140 + is shown as a full width character, mapping to U+FF3C can make + more sense. + + The euc-jisx0213 codec is enabled to decode JIS X 0212 codes on + codeset 2. Because JIS X 0212 and JIS X 0213 Plane 2 don't have + overlapped by each other, it doesn't bother standard conformations + (and JIS X 0213 Plane 2 is intended to use so.) On encoding + sessions, the codec will try to encode kanji characters in this + order: + + JIS X 0213 Plane 1 -> JIS X 0213 Plane 2 -> JIS X 0212 + + +4) euc-jp codec + + The euc-jp codec is a compatibility instance on these points: + - U+FF3C FULLWIDTH REVERSE SOLIDUS is mapped to EUC-JP A1C0 (vice versa) + - U+00A5 YEN SIGN is mapped to EUC-JP 0x5c. (one way) + - U+203E OVERLINE is mapped to EUC-JP 0x7e. (one way) + + +5) shift-jis codec + + The shift-jis codec is mapping 0x20-0x7e area to U+20-U+7E directly + instead of using JIS X 0201 for compatibility. The differences are: + - U+005C REVERSE SOLIDUS is mapped to SHIFT-JIS 0x5c. + - U+007E TILDE is mapped to SHIFT-JIS 0x7e. + - U+FF3C FULL-WIDTH REVERSE SOLIDUS is mapped to SHIFT-JIS 815f. + diff --git a/python/Modules/cjkcodecs/_codecs_cn.c b/python/Modules/cjkcodecs/_codecs_cn.c new file mode 100755 index 0000000..8a62f7e --- /dev/null +++ b/python/Modules/cjkcodecs/_codecs_cn.c @@ -0,0 +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 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) +{ + state->c[CN_STATE_OFFSET] = 0; + return 0; +} + +ENCODER_RESET(hz) +{ + if (state->c[CN_STATE_OFFSET] != 0) { + 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) { + if (state->c[CN_STATE_OFFSET]) { + 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; + + if (state->c[CN_STATE_OFFSET] == 0) { + 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) +{ + state->c[CN_STATE_OFFSET] = 0; + 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); + if (c2 == '~' && state->c[CN_STATE_OFFSET] == 0) + 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 */ + 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; + + 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) diff --git a/python/Modules/cjkcodecs/_codecs_hk.c b/python/Modules/cjkcodecs/_codecs_hk.c new file mode 100755 index 0000000..4f21569 --- /dev/null +++ b/python/Modules/cjkcodecs/_codecs_hk.c @@ -0,0 +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) diff --git a/python/Modules/cjkcodecs/_codecs_iso2022.c b/python/Modules/cjkcodecs/_codecs_iso2022.c new file mode 100755 index 0000000..7394cf6 --- /dev/null +++ b/python/Modules/cjkcodecs/_codecs_iso2022.c @@ -0,0 +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) diff --git a/python/Modules/cjkcodecs/_codecs_jp.c b/python/Modules/cjkcodecs/_codecs_jp.c new file mode 100755 index 0000000..3a33295 --- /dev/null +++ b/python/Modules/cjkcodecs/_codecs_jp.c @@ -0,0 +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) diff --git a/python/Modules/cjkcodecs/_codecs_kr.c b/python/Modules/cjkcodecs/_codecs_kr.c new file mode 100755 index 0000000..6d6acb5 --- /dev/null +++ b/python/Modules/cjkcodecs/_codecs_kr.c @@ -0,0 +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) diff --git a/python/Modules/cjkcodecs/_codecs_tw.c b/python/Modules/cjkcodecs/_codecs_tw.c new file mode 100755 index 0000000..722b26b --- /dev/null +++ b/python/Modules/cjkcodecs/_codecs_tw.c @@ -0,0 +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) diff --git a/python/Modules/cjkcodecs/alg_jisx0201.h b/python/Modules/cjkcodecs/alg_jisx0201.h new file mode 100755 index 0000000..3034b5a --- /dev/null +++ b/python/Modules/cjkcodecs/alg_jisx0201.h @@ -0,0 +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) diff --git a/python/Modules/cjkcodecs/cjkcodecs.h b/python/Modules/cjkcodecs/cjkcodecs.h new file mode 100755 index 0000000..b67f348 --- /dev/null +++ b/python/Modules/cjkcodecs/cjkcodecs.h @@ -0,0 +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, \ + int kind, 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) + +#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); \ + OUTBYTE1(c1); \ + } 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); \ + OUTBYTE1(c1); \ + OUTBYTE2(c2); \ + OUTBYTE3(c3); \ + } 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; + + r = PyObject_CallFunctionObjArgs(cofunc, codecobj, NULL); + 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/python/Modules/cjkcodecs/clinic/multibytecodec.c.h b/python/Modules/cjkcodecs/clinic/multibytecodec.c.h new file mode 100755 index 0000000..5ddbbe2 --- /dev/null +++ b/python/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -0,0 +1,528 @@ +/*[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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + input = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("encode", "argument 'errors'", "str or None", args[1]); + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &input, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&input, 'C')) { + _PyArg_BadArgument("decode", "argument 'input'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("decode", "argument 'errors'", "str or None", args[1]); + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + input = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[1]); + if (final == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = _multibytecodec_MultibyteIncrementalEncoder_encode_impl(self, input, final); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_getstate__doc__, +"getstate($self, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_GETSTATE_METHODDEF \ + {"getstate", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_getstate, METH_NOARGS, _multibytecodec_MultibyteIncrementalEncoder_getstate__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_getstate_impl(MultibyteIncrementalEncoderObject *self); + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_getstate(MultibyteIncrementalEncoderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteIncrementalEncoder_getstate_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_setstate__doc__, +"setstate($self, state, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_SETSTATE_METHODDEF \ + {"setstate", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_setstate, METH_O, _multibytecodec_MultibyteIncrementalEncoder_setstate__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEncoderObject *self, + PyLongObject *statelong); + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_setstate(MultibyteIncrementalEncoderObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyLongObject *statelong; + + if (!PyLong_Check(arg)) { + _PyArg_BadArgument("setstate", "argument", "int", arg); + goto exit; + } + statelong = (PyLongObject *)arg; + return_value = _multibytecodec_MultibyteIncrementalEncoder_setstate_impl(self, statelong); + +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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &input, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&input, 'C')) { + _PyArg_BadArgument("decode", "argument 'input'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[1]); + if (final == -1 && PyErr_Occurred()) { + 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; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_getstate__doc__, +"getstate($self, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_GETSTATE_METHODDEF \ + {"getstate", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_getstate, METH_NOARGS, _multibytecodec_MultibyteIncrementalDecoder_getstate__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_getstate_impl(MultibyteIncrementalDecoderObject *self); + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_getstate(MultibyteIncrementalDecoderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteIncrementalDecoder_getstate_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_setstate__doc__, +"setstate($self, state, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_SETSTATE_METHODDEF \ + {"setstate", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_setstate, METH_O, _multibytecodec_MultibyteIncrementalDecoder_setstate__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_setstate_impl(MultibyteIncrementalDecoderObject *self, + PyObject *state); + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_setstate(MultibyteIncrementalDecoderObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *state; + + if (!PyTuple_Check(arg)) { + _PyArg_BadArgument("setstate", "argument", "tuple", arg); + goto exit; + } + state = arg; + return_value = _multibytecodec_MultibyteIncrementalDecoder_setstate_impl(self, state); + +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 \ + {"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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readlines", nargs, 0, 1)) { + 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__}, +/*[clinic end generated code: output=5ce6fd4ca1f95620 input=a9049054013a1b77]*/ diff --git a/python/Modules/cjkcodecs/emu_jisx0213_2000.h b/python/Modules/cjkcodecs/emu_jisx0213_2000.h new file mode 100755 index 0000000..a5d5a70 --- /dev/null +++ b/python/Modules/cjkcodecs/emu_jisx0213_2000.h @@ -0,0 +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; \ + } + diff --git a/python/Modules/cjkcodecs/mappings_cn.h b/python/Modules/cjkcodecs/mappings_cn.h new file mode 100755 index 0000000..1f8c299 --- /dev/null +++ b/python/Modules/cjkcodecs/mappings_cn.h @@ -0,0 +1,4103 @@ +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/python/Modules/cjkcodecs/mappings_hk.h b/python/Modules/cjkcodecs/mappings_hk.h new file mode 100755 index 0000000..1b1d70e --- /dev/null +++ b/python/Modules/cjkcodecs/mappings_hk.h @@ -0,0 +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}, +}; + diff --git a/python/Modules/cjkcodecs/mappings_jisx0213_pair.h b/python/Modules/cjkcodecs/mappings_jisx0213_pair.h new file mode 100755 index 0000000..729e4bc --- /dev/null +++ b/python/Modules/cjkcodecs/mappings_jisx0213_pair.h @@ -0,0 +1,59 @@ +#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/python/Modules/cjkcodecs/mappings_jp.h b/python/Modules/cjkcodecs/mappings_jp.h new file mode 100755 index 0000000..c6dae3d --- /dev/null +++ b/python/Modules/cjkcodecs/mappings_jp.h @@ -0,0 +1,4765 @@ +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/python/Modules/cjkcodecs/mappings_kr.h b/python/Modules/cjkcodecs/mappings_kr.h new file mode 100755 index 0000000..7e6fdd2 --- /dev/null +++ b/python/Modules/cjkcodecs/mappings_kr.h @@ -0,0 +1,3251 @@ +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/python/Modules/cjkcodecs/mappings_tw.h b/python/Modules/cjkcodecs/mappings_tw.h new file mode 100755 index 0000000..ec3f9f7 --- /dev/null +++ b/python/Modules/cjkcodecs/mappings_tw.h @@ -0,0 +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}, +}; diff --git a/python/Modules/cjkcodecs/multibytecodec.c b/python/Modules/cjkcodecs/multibytecodec.c new file mode 100755 index 0000000..4a751f7 --- /dev/null +++ b/python/Modules/cjkcodecs/multibytecodec.c @@ -0,0 +1,2103 @@ +/* + * multibytecodec.c: Common Multibyte Codec Implementation + * + * Written by Hye-Shik Chang + */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "structmember.h" +#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 *args, *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; + + args = PyTuple_New(1); + if (args == NULL) { + Py_DECREF(cb); + return NULL; + } + + PyTuple_SET_ITEM(args, 0, exc); + Py_INCREF(exc); + + r = PyObject_CallObject(cb, args); + Py_DECREF(args); + 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; + 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; + 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 + 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; + 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)", + cres->ob_type->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_CallMethodIdObjArgs(self->stream, &PyId_write, str, NULL); + 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_CallMethodIdObjArgs(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) +{ + int i; + PyObject *m; + PyTypeObject *typelist[] = { + &MultibyteIncrementalEncoder_Type, + &MultibyteIncrementalDecoder_Type, + &MultibyteStreamReader_Type, + &MultibyteStreamWriter_Type, + NULL + }; + + if (PyType_Ready(&MultibyteCodec_Type) < 0) + return NULL; + + m = PyModule_Create(&_multibytecodecmodule); + if (m == NULL) + return NULL; + + for (i = 0; typelist[i] != NULL; i++) { + if (PyType_Ready(typelist[i]) < 0) + return NULL; + Py_INCREF(typelist[i]); + PyModule_AddObject(m, typelist[i]->tp_name, + (PyObject *)typelist[i]); + } + + if (PyErr_Occurred()) { + Py_FatalError("can't initialize the _multibytecodec module"); + Py_DECREF(m); + m = NULL; + } + return m; +} diff --git a/python/Modules/cjkcodecs/multibytecodec.h b/python/Modules/cjkcodecs/multibytecodec.h new file mode 100755 index 0000000..6d34534 --- /dev/null +++ b/python/Modules/cjkcodecs/multibytecodec.h @@ -0,0 +1,139 @@ +/* + * 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 + * need to add a new field to this struct, ensure that its byte order + * is independent of CPU endianness so that the return value of + * 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, + int kind, 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; + +#define MultibyteCodec_Check(op) ((op)->ob_type == &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 diff --git a/python/Modules/clinic/_abc.c.h b/python/Modules/clinic/_abc.c.h new file mode 100755 index 0000000..62c6552 --- /dev/null +++ b/python/Modules/clinic/_abc.c.h @@ -0,0 +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 \ + {"_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; + + if (!_PyArg_CheckPositional("_abc_register", nargs, 2, 2)) { + 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 \ + {"_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; + + if (!_PyArg_CheckPositional("_abc_instancecheck", nargs, 2, 2)) { + 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 \ + {"_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; + + if (!_PyArg_CheckPositional("_abc_subclasscheck", nargs, 2, 2)) { + 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); +} +/*[clinic end generated code: output=2544b4b5ae50a089 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_asynciomodule.c.h b/python/Modules/clinic/_asynciomodule.c.h new file mode 100755 index 0000000..17eb773 --- /dev/null +++ b/python/Modules/clinic/_asynciomodule.c.h @@ -0,0 +1,835 @@ +/*[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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 0, 0, argsbuf); + if (!fastargs) { + 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__, +"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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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__, +"cancel($self, /)\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 \ + {"cancel", (PyCFunction)_asyncio_Future_cancel, METH_NOARGS, _asyncio_Future_cancel__doc__}, + +static PyObject * +_asyncio_Future_cancel_impl(FutureObj *self); + +static PyObject * +_asyncio_Future_cancel(FutureObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Future_cancel_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__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 +_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 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 *name = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + coro = fastargs[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + loop = fastargs[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + name = fastargs[2]; +skip_optional_kwonly: + return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio_Task_current_task__doc__, +"current_task($type, /, loop=None)\n" +"--\n" +"\n" +"Return the currently running task in an event loop or None.\n" +"\n" +"By default the current task for the current event loop is returned.\n" +"\n" +"None is returned when called not in the context of a Task."); + +#define _ASYNCIO_TASK_CURRENT_TASK_METHODDEF \ + {"current_task", (PyCFunction)(void(*)(void))_asyncio_Task_current_task, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, _asyncio_Task_current_task__doc__}, + +static PyObject * +_asyncio_Task_current_task_impl(PyTypeObject *type, PyObject *loop); + +static PyObject * +_asyncio_Task_current_task(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"loop", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "current_task", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *loop = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + loop = args[0]; +skip_optional_pos: + return_value = _asyncio_Task_current_task_impl(type, loop); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio_Task_all_tasks__doc__, +"all_tasks($type, /, loop=None)\n" +"--\n" +"\n" +"Return a set of all tasks for an event loop.\n" +"\n" +"By default all tasks for the current event loop are returned."); + +#define _ASYNCIO_TASK_ALL_TASKS_METHODDEF \ + {"all_tasks", (PyCFunction)(void(*)(void))_asyncio_Task_all_tasks, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, _asyncio_Task_all_tasks__doc__}, + +static PyObject * +_asyncio_Task_all_tasks_impl(PyTypeObject *type, PyObject *loop); + +static PyObject * +_asyncio_Task_all_tasks(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"loop", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "all_tasks", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *loop = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + loop = args[0]; +skip_optional_pos: + return_value = _asyncio_Task_all_tasks_impl(type, loop); + +exit: + return return_value; +} + +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, /)\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 \ + {"cancel", (PyCFunction)_asyncio_Task_cancel, METH_NOARGS, _asyncio_Task_cancel__doc__}, + +static PyObject * +_asyncio_Task_cancel_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_cancel(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_cancel_impl(self); +} + +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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[0]) { + limit = args[0]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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__}, + +PyDoc_STRVAR(_asyncio_Task_get_coro__doc__, +"get_coro($self, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK_GET_CORO_METHODDEF \ + {"get_coro", (PyCFunction)_asyncio_Task_get_coro, METH_NOARGS, _asyncio_Task_get_coro__doc__}, + +static PyObject * +_asyncio_Task_get_coro_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_get_coro(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_get_coro_impl(self); +} + +PyDoc_STRVAR(_asyncio_Task_get_name__doc__, +"get_name($self, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK_GET_NAME_METHODDEF \ + {"get_name", (PyCFunction)_asyncio_Task_get_name, METH_NOARGS, _asyncio_Task_get_name__doc__}, + +static PyObject * +_asyncio_Task_get_name_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_get_name(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_get_name_impl(self); +} + +PyDoc_STRVAR(_asyncio_Task_set_name__doc__, +"set_name($self, value, /)\n" +"--\n" +"\n"); + +#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 \ + {"_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 _PyArg_Parser _parser = {NULL, _keywords, "_register_task", 0}; + PyObject *argsbuf[1]; + PyObject *task; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"_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 _PyArg_Parser _parser = {NULL, _keywords, "_unregister_task", 0}; + PyObject *argsbuf[1]; + PyObject *task; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"_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 _PyArg_Parser _parser = {NULL, _keywords, "_enter_task", 0}; + PyObject *argsbuf[2]; + PyObject *loop; + PyObject *task; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + 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 \ + {"_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 _PyArg_Parser _parser = {NULL, _keywords, "_leave_task", 0}; + PyObject *argsbuf[2]; + PyObject *loop; + PyObject *task; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + loop = args[0]; + task = args[1]; + return_value = _asyncio__leave_task_impl(module, loop, task); + +exit: + return return_value; +} +/*[clinic end generated code: output=585ba1f8de5b4103 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_bz2module.c.h b/python/Modules/clinic/_bz2module.c.h new file mode 100755 index 0000000..ac826bd --- /dev/null +++ b/python/Modules/clinic/_bz2module.c.h @@ -0,0 +1,223 @@ +/*[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; + } + 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; + + if ((Py_TYPE(self) == &BZ2Compressor_Type) && + !_PyArg_NoKeywords("BZ2Compressor", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("BZ2Compressor", PyTuple_GET_SIZE(args), 0, 1)) { + goto exit; + } + if (PyTuple_GET_SIZE(args) < 1) { + goto skip_optional; + } + if (PyFloat_Check(PyTuple_GET_ITEM(args, 0))) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + compresslevel = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + if (compresslevel == -1 && PyErr_Occurred()) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + 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; + } + 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; + + if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + !_PyArg_NoPositional("BZ2Decompressor", args)) { + goto exit; + } + if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { + goto exit; + } + return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self); + +exit: + return return_value; +} +/*[clinic end generated code: output=ec3d1b3652c98823 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_codecsmodule.c.h b/python/Modules/clinic/_codecsmodule.c.h new file mode 100755 index 0000000..772c8ca --- /dev/null +++ b/python/Modules/clinic/_codecsmodule.c.h @@ -0,0 +1,2925 @@ +/*[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; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + obj = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("encode", "argument 'encoding'", "str", args[1]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("encode", "argument 'errors'", "str", args[2]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[2], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + obj = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[1]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("decode", "argument 'errors'", "str", args[2]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[2], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("_forget_codec", "argument", "str", arg); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("escape_decode", nargs, 1, 2)) { + goto exit; + } + if (PyUnicode_Check(args[0])) { + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); + if (ptr == NULL) { + goto exit; + } + PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + } + else { /* any bytes-like object */ + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("escape_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("escape_decode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("escape_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyBytes_Check(args[0])) { + _PyArg_BadArgument("escape_encode", "argument 1", "bytes", args[0]); + goto exit; + } + data = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("escape_encode", "argument 2", "str or None", args[1]); + goto exit; + } +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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_7_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_7_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_7_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_8_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_8_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_8_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_16_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_16_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_16_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_16_le_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_16_le_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_16_le_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_16_be_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_16_be_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_16_be_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_16_ex_decode", nargs, 1, 4)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_16_ex_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_16_ex_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + byteorder = _PyLong_AsInt(args[2]); + if (byteorder == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[3]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_32_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_32_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_32_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_32_le_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_32_le_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_32_le_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_32_be_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_32_be_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_32_be_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_32_ex_decode", nargs, 1, 4)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("utf_32_ex_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_32_ex_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + byteorder = _PyLong_AsInt(args[2]); + if (byteorder == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[3]); + if (final == -1 && PyErr_Occurred()) { + 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__, +"unicode_escape_decode($module, data, errors=None, /)\n" +"--\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, + const char *errors); + +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; + + if (!_PyArg_CheckPositional("unicode_escape_decode", nargs, 1, 2)) { + goto exit; + } + if (PyUnicode_Check(args[0])) { + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); + if (ptr == NULL) { + goto exit; + } + PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + } + else { /* any bytes-like object */ + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("unicode_escape_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("unicode_escape_decode", "argument 2", "str or None", args[1]); + goto exit; + } +skip_optional: + return_value = _codecs_unicode_escape_decode_impl(module, &data, errors); + +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, /)\n" +"--\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, + const char *errors); + +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; + + if (!_PyArg_CheckPositional("raw_unicode_escape_decode", nargs, 1, 2)) { + goto exit; + } + if (PyUnicode_Check(args[0])) { + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); + if (ptr == NULL) { + goto exit; + } + PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + } + else { /* any bytes-like object */ + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("raw_unicode_escape_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("raw_unicode_escape_decode", "argument 2", "str or None", args[1]); + goto exit; + } +skip_optional: + return_value = _codecs_raw_unicode_escape_decode_impl(module, &data, errors); + +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; + + if (!_PyArg_CheckPositional("latin_1_decode", nargs, 1, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("latin_1_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("latin_1_decode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ascii_decode", nargs, 1, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("ascii_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("ascii_decode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + PyObject *mapping = Py_None; + + if (!_PyArg_CheckPositional("charmap_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("charmap_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("charmap_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("mbcs_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("mbcs_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("mbcs_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("oem_decode", nargs, 1, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("oem_decode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("oem_decode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[2]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("code_page_decode", nargs, 2, 4)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + codepage = _PyLong_AsInt(args[0]); + if (codepage == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("code_page_decode", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (args[2] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[2])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[2], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("code_page_decode", "argument 3", "str or None", args[2]); + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + final = _PyLong_AsInt(args[3]); + if (final == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("readbuffer_encode", nargs, 1, 2)) { + goto exit; + } + if (PyUnicode_Check(args[0])) { + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); + if (ptr == NULL) { + goto exit; + } + PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + } + else { /* any bytes-like object */ + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("readbuffer_encode", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + } + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("readbuffer_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_7_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_7_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_7_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_8_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_8_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_8_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_16_encode", nargs, 1, 3)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_16_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_16_encode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + byteorder = _PyLong_AsInt(args[2]); + if (byteorder == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_16_le_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_16_le_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_16_le_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_16_be_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_16_be_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_16_be_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_32_encode", nargs, 1, 3)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_32_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_32_encode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + byteorder = _PyLong_AsInt(args[2]); + if (byteorder == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_32_le_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_32_le_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_32_le_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("utf_32_be_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("utf_32_be_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("utf_32_be_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("unicode_escape_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("unicode_escape_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("unicode_escape_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("raw_unicode_escape_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("raw_unicode_escape_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("raw_unicode_escape_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("latin_1_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("latin_1_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("latin_1_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ascii_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("ascii_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("ascii_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + PyObject *mapping = Py_None; + + if (!_PyArg_CheckPositional("charmap_encode", nargs, 1, 3)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("charmap_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("charmap_encode", "argument 2", "str or None", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("charmap_build", "argument", "str", arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("mbcs_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("mbcs_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("mbcs_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("oem_encode", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("oem_encode", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + str = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (args[1] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("oem_encode", "argument 2", "str or None", args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("code_page_encode", nargs, 2, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + code_page = _PyLong_AsInt(args[0]); + if (code_page == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("code_page_encode", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + str = args[1]; + if (nargs < 3) { + goto skip_optional; + } + if (args[2] == Py_None) { + errors = NULL; + } + else if (PyUnicode_Check(args[2])) { + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[2], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("code_page_encode", "argument 3", "str or None", args[2]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("register_error", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("register_error", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[0], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("lookup_error", "argument", "str", arg); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(arg, &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + 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) */ +/*[clinic end generated code: output=51b42d170889524c input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_collectionsmodule.c.h b/python/Modules/clinic/_collectionsmodule.c.h new file mode 100755 index 0000000..c3ba1a6 --- /dev/null +++ b/python/Modules/clinic/_collectionsmodule.c.h @@ -0,0 +1,76 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_collections__count_elements__doc__, +"_count_elements($module, mapping, iterable, /)\n" +"--\n" +"\n" +"Count elements in the iterable, updating the mapping"); + +#define _COLLECTIONS__COUNT_ELEMENTS_METHODDEF \ + {"_count_elements", (PyCFunction)(void(*)(void))_collections__count_elements, METH_FASTCALL, _collections__count_elements__doc__}, + +static PyObject * +_collections__count_elements_impl(PyObject *module, PyObject *mapping, + PyObject *iterable); + +static PyObject * +_collections__count_elements(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *mapping; + PyObject *iterable; + + if (!_PyArg_CheckPositional("_count_elements", nargs, 2, 2)) { + goto exit; + } + mapping = args[0]; + iterable = args[1]; + return_value = _collections__count_elements_impl(module, mapping, iterable); + +exit: + return return_value; +} + +static PyObject * +tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc); + +static PyObject * +tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + Py_ssize_t index; + PyObject *doc; + + if ((type == &tuplegetter_type) && + !_PyArg_NoKeywords("_tuplegetter", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("_tuplegetter", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + if (PyFloat_Check(PyTuple_GET_ITEM(args, 0))) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(PyTuple_GET_ITEM(args, 0)); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + index = ival; + } + doc = PyTuple_GET_ITEM(args, 1); + return_value = tuplegetter_new_impl(type, index, doc); + +exit: + return return_value; +} +/*[clinic end generated code: output=9d2bfcc9df5faf35 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_contextvarsmodule.c.h b/python/Modules/clinic/_contextvarsmodule.c.h new file mode 100755 index 0000000..b1885e4 --- /dev/null +++ b/python/Modules/clinic/_contextvarsmodule.c.h @@ -0,0 +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]*/ diff --git a/python/Modules/clinic/_cryptmodule.c.h b/python/Modules/clinic/_cryptmodule.c.h new file mode 100755 index 0000000..ea91d7c --- /dev/null +++ b/python/Modules/clinic/_cryptmodule.c.h @@ -0,0 +1,63 @@ +/*[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; + + if (!_PyArg_CheckPositional("crypt", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("crypt", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t word_length; + word = PyUnicode_AsUTF8AndSize(args[0], &word_length); + if (word == NULL) { + goto exit; + } + if (strlen(word) != (size_t)word_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("crypt", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t salt_length; + salt = PyUnicode_AsUTF8AndSize(args[1], &salt_length); + if (salt == NULL) { + goto exit; + } + if (strlen(salt) != (size_t)salt_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = crypt_crypt_impl(module, word, salt); + +exit: + return return_value; +} +/*[clinic end generated code: output=549de0d43b030126 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_curses_panel.c.h b/python/Modules/clinic/_curses_panel.c.h new file mode 100755 index 0000000..9840ed8 --- /dev/null +++ b/python/Modules/clinic/_curses_panel.c.h @@ -0,0 +1,338 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, +"bottom($self, /)\n" +"--\n" +"\n" +"Push the panel to the bottom of the stack."); + +#define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ + {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__}, + +static PyObject * +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_bottom(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_bottom_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_hide__doc__, +"hide($self, /)\n" +"--\n" +"\n" +"Hide the panel.\n" +"\n" +"This does not delete the object, it just makes the window on screen invisible."); + +#define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ + {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__}, + +static PyObject * +_curses_panel_panel_hide_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_hide(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_hide_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_show__doc__, +"show($self, /)\n" +"--\n" +"\n" +"Display the panel (which might have been hidden)."); + +#define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ + {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__}, + +static PyObject * +_curses_panel_panel_show_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_show(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_show_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_top__doc__, +"top($self, /)\n" +"--\n" +"\n" +"Push panel to the top of the stack."); + +#define _CURSES_PANEL_PANEL_TOP_METHODDEF \ + {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__}, + +static PyObject * +_curses_panel_panel_top_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_top(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_top_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_above__doc__, +"above($self, /)\n" +"--\n" +"\n" +"Return the panel above the current panel."); + +#define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ + {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, + +static PyObject * +_curses_panel_panel_above_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_above_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_below__doc__, +"below($self, /)\n" +"--\n" +"\n" +"Return the panel below the current panel."); + +#define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ + {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, + +static PyObject * +_curses_panel_panel_below_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_below_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, +"hidden($self, /)\n" +"--\n" +"\n" +"Return True if the panel is hidden (not visible), False otherwise."); + +#define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ + {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, + +static PyObject * +_curses_panel_panel_hidden_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_hidden_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_move__doc__, +"move($self, y, x, /)\n" +"--\n" +"\n" +"Move the panel to the screen coordinates (y, x)."); + +#define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ + {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_FASTCALL, _curses_panel_panel_move__doc__}, + +static PyObject * +_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x); + +static PyObject * +_curses_panel_panel_move(PyCursesPanelObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + + if (!_PyArg_CheckPositional("move", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + y = _PyLong_AsInt(args[0]); + if (y == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + x = _PyLong_AsInt(args[1]); + if (x == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_panel_panel_move_impl(self, y, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_panel_window__doc__, +"window($self, /)\n" +"--\n" +"\n" +"Return the window object associated with the panel."); + +#define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ + {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, + +static PyObject * +_curses_panel_panel_window_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_window_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_replace__doc__, +"replace($self, win, /)\n" +"--\n" +"\n" +"Change the window associated with the panel to the window win."); + +#define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ + {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__}, + +static PyObject * +_curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyCursesWindowObject *win); + +static PyObject * +_curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *win; + + if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { + _PyArg_BadArgument("replace", "argument", (&PyCursesWindow_Type)->tp_name, arg); + goto exit; + } + win = (PyCursesWindowObject *)arg; + return_value = _curses_panel_panel_replace_impl(self, win); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, +"set_userptr($self, obj, /)\n" +"--\n" +"\n" +"Set the panel\'s user pointer to obj."); + +#define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ + {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__}, + +PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, +"userptr($self, /)\n" +"--\n" +"\n" +"Return the user pointer for the panel."); + +#define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ + {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__}, + +static PyObject * +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_userptr(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_userptr_impl(self); +} + +PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, +"bottom_panel($module, /)\n" +"--\n" +"\n" +"Return the bottom panel in the panel stack."); + +#define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ + {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, + +static PyObject * +_curses_panel_bottom_panel_impl(PyObject *module); + +static PyObject * +_curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_bottom_panel_impl(module); +} + +PyDoc_STRVAR(_curses_panel_new_panel__doc__, +"new_panel($module, win, /)\n" +"--\n" +"\n" +"Return a panel object, associating it with the given window win."); + +#define _CURSES_PANEL_NEW_PANEL_METHODDEF \ + {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, + +static PyObject * +_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); + +static PyObject * +_curses_panel_new_panel(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *win; + + if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { + _PyArg_BadArgument("new_panel", "argument", (&PyCursesWindow_Type)->tp_name, arg); + goto exit; + } + win = (PyCursesWindowObject *)arg; + return_value = _curses_panel_new_panel_impl(module, win); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_top_panel__doc__, +"top_panel($module, /)\n" +"--\n" +"\n" +"Return the top panel in the panel stack."); + +#define _CURSES_PANEL_TOP_PANEL_METHODDEF \ + {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, + +static PyObject * +_curses_panel_top_panel_impl(PyObject *module); + +static PyObject * +_curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_top_panel_impl(module); +} + +PyDoc_STRVAR(_curses_panel_update_panels__doc__, +"update_panels($module, /)\n" +"--\n" +"\n" +"Updates the virtual screen after changes in the panel stack.\n" +"\n" +"This does not call curses.doupdate(), so you\'ll have to do this yourself."); + +#define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ + {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, + +static PyObject * +_curses_panel_update_panels_impl(PyObject *module); + +static PyObject * +_curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_update_panels_impl(module); +} +/*[clinic end generated code: output=d96dc1fd68e898d9 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_cursesmodule.c.h b/python/Modules/clinic/_cursesmodule.c.h new file mode 100755 index 0000000..889c2f6 --- /dev/null +++ b/python/Modules/clinic/_cursesmodule.c.h @@ -0,0 +1,4562 @@ +/*[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."); + +#define _CURSES_WINDOW_ADDCH_METHODDEF \ + {"addch", (PyCFunction)_curses_window_addch, METH_VARARGS, _curses_window_addch__doc__}, + +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 * +_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; + 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: + PyErr_SetString(PyExc_TypeError, "_curses.window.addch requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_addstr__doc__, +"addstr([y, x,] str, [attr])\n" +"Paint the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to add.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Paint the string str at (y, x) with attributes attr,\n" +"overwriting anything previously on the display.\n" +"By default, the character position and attributes are the\n" +"current settings for the window object."); + +#define _CURSES_WINDOW_ADDSTR_METHODDEF \ + {"addstr", (PyCFunction)_curses_window_addstr, METH_VARARGS, _curses_window_addstr__doc__}, + +static PyObject * +_curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr); + +static PyObject * +_curses_window_addstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:addstr", &str)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:addstr", &str, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:addstr", &y, &x, &str)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:addstr", &y, &x, &str, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.addstr requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_addstr_impl(self, group_left_1, y, x, str, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_addnstr__doc__, +"addnstr([y, x,] str, n, [attr])\n" +"Paint at most n characters of the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to add.\n" +" n\n" +" Maximal number of characters.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Paint at most n characters of the string str at (y, x) with\n" +"attributes attr, overwriting anything previously on the display.\n" +"By default, the character position and attributes are the\n" +"current settings for the window object."); + +#define _CURSES_WINDOW_ADDNSTR_METHODDEF \ + {"addnstr", (PyCFunction)_curses_window_addnstr, METH_VARARGS, _curses_window_addnstr__doc__}, + +static PyObject * +_curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_addnstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int n; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:addnstr", &str, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:addnstr", &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:addnstr", &y, &x, &str, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:addnstr", &y, &x, &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.addnstr requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_addnstr_impl(self, group_left_1, y, x, str, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_bkgd__doc__, +"bkgd($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Set the background property of the window.\n" +"\n" +" ch\n" +" Background character.\n" +" attr\n" +" Background attributes."); + +#define _CURSES_WINDOW_BKGD_METHODDEF \ + {"bkgd", (PyCFunction)(void(*)(void))_curses_window_bkgd, METH_FASTCALL, _curses_window_bkgd__doc__}, + +static PyObject * +_curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr); + +static PyObject * +_curses_window_bkgd(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_CheckPositional("bkgd", nargs, 1, 2)) { + goto exit; + } + ch = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + attr = PyLong_AsLong(args[1]); + if (attr == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_window_bkgd_impl(self, ch, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attroff__doc__, +"attroff($self, attr, /)\n" +"--\n" +"\n" +"Remove attribute attr from the \"background\" set."); + +#define _CURSES_WINDOW_ATTROFF_METHODDEF \ + {"attroff", (PyCFunction)_curses_window_attroff, METH_O, _curses_window_attroff__doc__}, + +static PyObject * +_curses_window_attroff_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attroff(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + attr = PyLong_AsLong(arg); + if (attr == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_window_attroff_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attron__doc__, +"attron($self, attr, /)\n" +"--\n" +"\n" +"Add attribute attr from the \"background\" set."); + +#define _CURSES_WINDOW_ATTRON_METHODDEF \ + {"attron", (PyCFunction)_curses_window_attron, METH_O, _curses_window_attron__doc__}, + +static PyObject * +_curses_window_attron_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attron(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + attr = PyLong_AsLong(arg); + if (attr == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_window_attron_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attrset__doc__, +"attrset($self, attr, /)\n" +"--\n" +"\n" +"Set the \"background\" set of attributes."); + +#define _CURSES_WINDOW_ATTRSET_METHODDEF \ + {"attrset", (PyCFunction)_curses_window_attrset, METH_O, _curses_window_attrset__doc__}, + +static PyObject * +_curses_window_attrset_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attrset(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + attr = PyLong_AsLong(arg); + if (attr == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_window_attrset_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_bkgdset__doc__, +"bkgdset($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Set the window\'s background.\n" +"\n" +" ch\n" +" Background character.\n" +" attr\n" +" Background attributes."); + +#define _CURSES_WINDOW_BKGDSET_METHODDEF \ + {"bkgdset", (PyCFunction)(void(*)(void))_curses_window_bkgdset, METH_FASTCALL, _curses_window_bkgdset__doc__}, + +static PyObject * +_curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, + long attr); + +static PyObject * +_curses_window_bkgdset(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_CheckPositional("bkgdset", nargs, 1, 2)) { + goto exit; + } + ch = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + attr = PyLong_AsLong(args[1]); + if (attr == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_window_bkgdset_impl(self, ch, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_border__doc__, +"border($self, ls=_curses.ACS_VLINE, rs=_curses.ACS_VLINE,\n" +" ts=_curses.ACS_HLINE, bs=_curses.ACS_HLINE,\n" +" tl=_curses.ACS_ULCORNER, tr=_curses.ACS_URCORNER,\n" +" bl=_curses.ACS_LLCORNER, br=_curses.ACS_LRCORNER, /)\n" +"--\n" +"\n" +"Draw a border around the edges of the window.\n" +"\n" +" ls\n" +" Left side.\n" +" rs\n" +" Right side.\n" +" ts\n" +" Top side.\n" +" bs\n" +" Bottom side.\n" +" tl\n" +" Upper-left corner.\n" +" tr\n" +" Upper-right corner.\n" +" bl\n" +" Bottom-left corner.\n" +" br\n" +" Bottom-right corner.\n" +"\n" +"Each parameter specifies the character to use for a specific part of the\n" +"border. The characters can be specified as integers or as one-character\n" +"strings. A 0 value for any parameter will cause the default character to be\n" +"used for that parameter."); + +#define _CURSES_WINDOW_BORDER_METHODDEF \ + {"border", (PyCFunction)(void(*)(void))_curses_window_border, METH_FASTCALL, _curses_window_border__doc__}, + +static PyObject * +_curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, + PyObject *rs, PyObject *ts, PyObject *bs, + PyObject *tl, PyObject *tr, PyObject *bl, + PyObject *br); + +static PyObject * +_curses_window_border(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ls = NULL; + PyObject *rs = NULL; + PyObject *ts = NULL; + PyObject *bs = NULL; + PyObject *tl = NULL; + PyObject *tr = NULL; + PyObject *bl = NULL; + PyObject *br = NULL; + + if (!_PyArg_CheckPositional("border", nargs, 0, 8)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + ls = args[0]; + if (nargs < 2) { + goto skip_optional; + } + rs = args[1]; + if (nargs < 3) { + goto skip_optional; + } + ts = args[2]; + if (nargs < 4) { + goto skip_optional; + } + bs = args[3]; + if (nargs < 5) { + goto skip_optional; + } + tl = args[4]; + if (nargs < 6) { + goto skip_optional; + } + tr = args[5]; + if (nargs < 7) { + goto skip_optional; + } + bl = args[6]; + if (nargs < 8) { + goto skip_optional; + } + br = args[7]; +skip_optional: + return_value = _curses_window_border_impl(self, ls, rs, ts, bs, tl, tr, bl, br); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_box__doc__, +"box([verch=0, horch=0])\n" +"Draw a border around the edges of the window.\n" +"\n" +" verch\n" +" Left and right side.\n" +" horch\n" +" Top and bottom side.\n" +"\n" +"Similar to border(), but both ls and rs are verch and both ts and bs are\n" +"horch. The default corner characters are always used by this function."); + +#define _CURSES_WINDOW_BOX_METHODDEF \ + {"box", (PyCFunction)_curses_window_box, METH_VARARGS, _curses_window_box__doc__}, + +static PyObject * +_curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, + PyObject *verch, PyObject *horch); + +static PyObject * +_curses_window_box(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + PyObject *verch = _PyLong_Zero; + PyObject *horch = _PyLong_Zero; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:box", &verch, &horch)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.box requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_box_impl(self, group_right_1, verch, horch); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_delch__doc__, +"delch([y, x])\n" +"Delete any character at (y, x).\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate."); + +#define _CURSES_WINDOW_DELCH_METHODDEF \ + {"delch", (PyCFunction)_curses_window_delch, METH_VARARGS, _curses_window_delch__doc__}, + +static PyObject * +_curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_delch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:delch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.delch requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_delch_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_derwin__doc__, +"derwin([nlines=0, ncols=0,] begin_y, begin_x)\n" +"Create a sub-window (window-relative coordinates).\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"derwin() is the same as calling subwin(), except that begin_y and begin_x\n" +"are relative to the origin of the window, rather than relative to the entire\n" +"screen."); + +#define _CURSES_WINDOW_DERWIN_METHODDEF \ + {"derwin", (PyCFunction)_curses_window_derwin, METH_VARARGS, _curses_window_derwin__doc__}, + +static PyObject * +_curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x); + +static PyObject * +_curses_window_derwin(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int nlines = 0; + int ncols = 0; + int begin_y; + int begin_x; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:derwin", &begin_y, &begin_x)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:derwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.derwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_window_derwin_impl(self, group_left_1, nlines, ncols, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_echochar__doc__, +"echochar($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Add character ch with attribute attr, and refresh.\n" +"\n" +" ch\n" +" Character to add.\n" +" attr\n" +" Attributes for the character."); + +#define _CURSES_WINDOW_ECHOCHAR_METHODDEF \ + {"echochar", (PyCFunction)(void(*)(void))_curses_window_echochar, METH_FASTCALL, _curses_window_echochar__doc__}, + +static PyObject * +_curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, + long attr); + +static PyObject * +_curses_window_echochar(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_CheckPositional("echochar", nargs, 1, 2)) { + goto exit; + } + ch = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + attr = PyLong_AsLong(args[1]); + if (attr == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_window_echochar_impl(self, ch, attr); + +exit: + return return_value; +} + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_window_enclose__doc__, +"enclose($self, y, x, /)\n" +"--\n" +"\n" +"Return True if the screen-relative coordinates are enclosed by the window.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate."); + +#define _CURSES_WINDOW_ENCLOSE_METHODDEF \ + {"enclose", (PyCFunction)(void(*)(void))_curses_window_enclose, METH_FASTCALL, _curses_window_enclose__doc__}, + +static long +_curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x); + +static PyObject * +_curses_window_enclose(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + long _return_value; + + if (!_PyArg_CheckPositional("enclose", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + y = _PyLong_AsInt(args[0]); + if (y == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + x = _PyLong_AsInt(args[1]); + if (x == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = _curses_window_enclose_impl(self, y, x); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_window_getbkgd__doc__, +"getbkgd($self, /)\n" +"--\n" +"\n" +"Return the window\'s current background character/attribute pair."); + +#define _CURSES_WINDOW_GETBKGD_METHODDEF \ + {"getbkgd", (PyCFunction)_curses_window_getbkgd, METH_NOARGS, _curses_window_getbkgd__doc__}, + +static long +_curses_window_getbkgd_impl(PyCursesWindowObject *self); + +static PyObject * +_curses_window_getbkgd(PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + long _return_value; + + _return_value = _curses_window_getbkgd_impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_getch__doc__, +"getch([y, x])\n" +"Get a character code from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"The integer returned does not have to be in ASCII range: function keys,\n" +"keypad keys and so on return numbers higher than 256. In no-delay mode, -1\n" +"is returned if there is no input, else getch() waits until a key is pressed."); + +#define _CURSES_WINDOW_GETCH_METHODDEF \ + {"getch", (PyCFunction)_curses_window_getch, METH_VARARGS, _curses_window_getch__doc__}, + +static int +_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_getch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + int _return_value; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:getch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.getch requires 0 to 2 arguments"); + goto exit; + } + _return_value = _curses_window_getch_impl(self, group_right_1, y, x); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_getkey__doc__, +"getkey([y, x])\n" +"Get a character (string) from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"Returning a string instead of an integer, as getch() does. Function keys,\n" +"keypad keys and other special keys return a multibyte string containing the\n" +"key name. In no-delay mode, an exception is raised if there is no input."); + +#define _CURSES_WINDOW_GETKEY_METHODDEF \ + {"getkey", (PyCFunction)_curses_window_getkey, METH_VARARGS, _curses_window_getkey__doc__}, + +static PyObject * +_curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_getkey(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:getkey", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.getkey requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_getkey_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +#if defined(HAVE_NCURSESW) + +PyDoc_STRVAR(_curses_window_get_wch__doc__, +"get_wch([y, x])\n" +"Get a wide character from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"Return a character for most keys, or an integer for function keys,\n" +"keypad keys, and other special keys."); + +#define _CURSES_WINDOW_GET_WCH_METHODDEF \ + {"get_wch", (PyCFunction)_curses_window_get_wch, METH_VARARGS, _curses_window_get_wch__doc__}, + +static PyObject * +_curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_get_wch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:get_wch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.get_wch requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_get_wch_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +#endif /* defined(HAVE_NCURSESW) */ + +PyDoc_STRVAR(_curses_window_hline__doc__, +"hline([y, x,] ch, n, [attr=_curses.A_NORMAL])\n" +"Display a horizontal line.\n" +"\n" +" y\n" +" Starting Y-coordinate.\n" +" x\n" +" Starting X-coordinate.\n" +" ch\n" +" Character to draw.\n" +" n\n" +" Line length.\n" +" attr\n" +" Attributes for the characters."); + +#define _CURSES_WINDOW_HLINE_METHODDEF \ + {"hline", (PyCFunction)_curses_window_hline, METH_VARARGS, _curses_window_hline__doc__}, + +static PyObject * +_curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_hline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int n; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:hline", &ch, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:hline", &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:hline", &y, &x, &ch, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:hline", &y, &x, &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.hline requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_hline_impl(self, group_left_1, y, x, ch, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insch__doc__, +"insch([y, x,] ch, [attr=_curses.A_NORMAL])\n" +"Insert a character before the current or specified position.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" ch\n" +" Character to insert.\n" +" attr\n" +" Attributes for the character.\n" +"\n" +"All characters to the right of the cursor are shifted one position right, with\n" +"the rightmost characters on the line being lost."); + +#define _CURSES_WINDOW_INSCH_METHODDEF \ + {"insch", (PyCFunction)_curses_window_insch, METH_VARARGS, _curses_window_insch__doc__}, + +static PyObject * +_curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int group_right_1, + long attr); + +static PyObject * +_curses_window_insch(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; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:insch", &ch)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:insch", &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:insch", &y, &x, &ch)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:insch", &y, &x, &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insch requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_insch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_inch__doc__, +"inch([y, x])\n" +"Return the character at the given position in the window.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"The bottom 8 bits are the character proper, and upper bits are the attributes."); + +#define _CURSES_WINDOW_INCH_METHODDEF \ + {"inch", (PyCFunction)_curses_window_inch, METH_VARARGS, _curses_window_inch__doc__}, + +static unsigned long +_curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_inch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + unsigned long _return_value; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:inch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.inch requires 0 to 2 arguments"); + goto exit; + } + _return_value = _curses_window_inch_impl(self, group_right_1, y, x); + if ((_return_value == (unsigned long)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insstr__doc__, +"insstr([y, x,] str, [attr])\n" +"Insert the string before the current or specified position.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to insert.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Insert a character string (as many characters as will fit on the line)\n" +"before the character under the cursor. All characters to the right of\n" +"the cursor are shifted right, with the rightmost characters on the line\n" +"being lost. The cursor position does not change (after moving to y, x,\n" +"if specified)."); + +#define _CURSES_WINDOW_INSSTR_METHODDEF \ + {"insstr", (PyCFunction)_curses_window_insstr, METH_VARARGS, _curses_window_insstr__doc__}, + +static PyObject * +_curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr); + +static PyObject * +_curses_window_insstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:insstr", &str)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:insstr", &str, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:insstr", &y, &x, &str)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:insstr", &y, &x, &str, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insstr requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_insstr_impl(self, group_left_1, y, x, str, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insnstr__doc__, +"insnstr([y, x,] str, n, [attr])\n" +"Insert at most n characters of the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to insert.\n" +" n\n" +" Maximal number of characters.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Insert a character string (as many characters as will fit on the line)\n" +"before the character under the cursor, up to n characters. If n is zero\n" +"or negative, the entire string is inserted. All characters to the right\n" +"of the cursor are shifted right, with the rightmost characters on the line\n" +"being lost. The cursor position does not change (after moving to y, x, if\n" +"specified)."); + +#define _CURSES_WINDOW_INSNSTR_METHODDEF \ + {"insnstr", (PyCFunction)_curses_window_insnstr, METH_VARARGS, _curses_window_insnstr__doc__}, + +static PyObject * +_curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_insnstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int n; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:insnstr", &str, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:insnstr", &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:insnstr", &y, &x, &str, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:insnstr", &y, &x, &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insnstr requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_insnstr_impl(self, group_left_1, y, x, str, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_is_linetouched__doc__, +"is_linetouched($self, line, /)\n" +"--\n" +"\n" +"Return True if the specified line was modified, otherwise return False.\n" +"\n" +" line\n" +" Line number.\n" +"\n" +"Raise a curses.error exception if line is not valid for the given window."); + +#define _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF \ + {"is_linetouched", (PyCFunction)_curses_window_is_linetouched, METH_O, _curses_window_is_linetouched__doc__}, + +static PyObject * +_curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line); + +static PyObject * +_curses_window_is_linetouched(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int line; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + line = _PyLong_AsInt(arg); + if (line == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_window_is_linetouched_impl(self, line); + +exit: + return return_value; +} + +#if defined(py_is_pad) + +PyDoc_STRVAR(_curses_window_noutrefresh__doc__, +"noutrefresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\n" +"Mark for refresh but wait.\n" +"\n" +"This function updates the data structure representing the desired state of the\n" +"window, but does not force an update of the physical screen. To accomplish\n" +"that, call doupdate()."); + +#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \ + {"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_VARARGS, _curses_window_noutrefresh__doc__}, + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self, + int group_right_1, int pminrow, int pmincol, + int sminrow, int smincol, int smaxrow, + int smaxcol); + +static PyObject * +_curses_window_noutrefresh(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int pminrow = 0; + int pmincol = 0; + int sminrow = 0; + int smincol = 0; + int smaxrow = 0; + int smaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 6: + if (!PyArg_ParseTuple(args, "iiiiii:noutrefresh", &pminrow, &pmincol, &sminrow, &smincol, &smaxrow, &smaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.noutrefresh requires 0 to 6 arguments"); + goto exit; + } + return_value = _curses_window_noutrefresh_impl(self, group_right_1, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); + +exit: + return return_value; +} + +#endif /* defined(py_is_pad) */ + +#if !defined(py_is_pad) + +PyDoc_STRVAR(_curses_window_noutrefresh__doc__, +"noutrefresh($self, /)\n" +"--\n" +"\n" +"Mark for refresh but wait.\n" +"\n" +"This function updates the data structure representing the desired state of the\n" +"window, but does not force an update of the physical screen. To accomplish\n" +"that, call doupdate()."); + +#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \ + {"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_NOARGS, _curses_window_noutrefresh__doc__}, + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self); + +static PyObject * +_curses_window_noutrefresh(PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_window_noutrefresh_impl(self); +} + +#endif /* !defined(py_is_pad) */ + +PyDoc_STRVAR(_curses_window_overlay__doc__, +"overlay(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])\n" +"Overlay the window on top of destwin.\n" +"\n" +"The windows need not be the same size, only the overlapping region is copied.\n" +"This copy is non-destructive, which means that the current background\n" +"character does not overwrite the old contents of destwin.\n" +"\n" +"To get fine-grained control over the copied region, the second form of\n" +"overlay() can be used. sminrow and smincol are the upper-left coordinates\n" +"of the source window, and the other variables mark a rectangle in the\n" +"destination window."); + +#define _CURSES_WINDOW_OVERLAY_METHODDEF \ + {"overlay", (PyCFunction)_curses_window_overlay, METH_VARARGS, _curses_window_overlay__doc__}, + +static PyObject * +_curses_window_overlay_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, int group_right_1, + int sminrow, int smincol, int dminrow, + int dmincol, int dmaxrow, int dmaxcol); + +static PyObject * +_curses_window_overlay(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *destwin; + int group_right_1 = 0; + int sminrow = 0; + int smincol = 0; + int dminrow = 0; + int dmincol = 0; + int dmaxrow = 0; + int dmaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O!:overlay", &PyCursesWindow_Type, &destwin)) { + goto exit; + } + break; + case 7: + if (!PyArg_ParseTuple(args, "O!iiiiii:overlay", &PyCursesWindow_Type, &destwin, &sminrow, &smincol, &dminrow, &dmincol, &dmaxrow, &dmaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.overlay requires 1 to 7 arguments"); + goto exit; + } + return_value = _curses_window_overlay_impl(self, destwin, group_right_1, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_overwrite__doc__, +"overwrite(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow,\n" +" dmaxcol])\n" +"Overwrite the window on top of destwin.\n" +"\n" +"The windows need not be the same size, in which case only the overlapping\n" +"region is copied. This copy is destructive, which means that the current\n" +"background character overwrites the old contents of destwin.\n" +"\n" +"To get fine-grained control over the copied region, the second form of\n" +"overwrite() can be used. sminrow and smincol are the upper-left coordinates\n" +"of the source window, the other variables mark a rectangle in the destination\n" +"window."); + +#define _CURSES_WINDOW_OVERWRITE_METHODDEF \ + {"overwrite", (PyCFunction)_curses_window_overwrite, METH_VARARGS, _curses_window_overwrite__doc__}, + +static PyObject * +_curses_window_overwrite_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, + int group_right_1, int sminrow, int smincol, + int dminrow, int dmincol, int dmaxrow, + int dmaxcol); + +static PyObject * +_curses_window_overwrite(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *destwin; + int group_right_1 = 0; + int sminrow = 0; + int smincol = 0; + int dminrow = 0; + int dmincol = 0; + int dmaxrow = 0; + int dmaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O!:overwrite", &PyCursesWindow_Type, &destwin)) { + goto exit; + } + break; + case 7: + if (!PyArg_ParseTuple(args, "O!iiiiii:overwrite", &PyCursesWindow_Type, &destwin, &sminrow, &smincol, &dminrow, &dmincol, &dmaxrow, &dmaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.overwrite requires 1 to 7 arguments"); + goto exit; + } + return_value = _curses_window_overwrite_impl(self, destwin, group_right_1, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_putwin__doc__, +"putwin($self, file, /)\n" +"--\n" +"\n" +"Write all data associated with the window into the provided file object.\n" +"\n" +"This information can be later retrieved using the getwin() function."); + +#define _CURSES_WINDOW_PUTWIN_METHODDEF \ + {"putwin", (PyCFunction)_curses_window_putwin, METH_O, _curses_window_putwin__doc__}, + +PyDoc_STRVAR(_curses_window_redrawln__doc__, +"redrawln($self, beg, num, /)\n" +"--\n" +"\n" +"Mark the specified lines corrupted.\n" +"\n" +" beg\n" +" Starting line number.\n" +" num\n" +" The number of lines.\n" +"\n" +"They should be completely redrawn on the next refresh() call."); + +#define _CURSES_WINDOW_REDRAWLN_METHODDEF \ + {"redrawln", (PyCFunction)(void(*)(void))_curses_window_redrawln, METH_FASTCALL, _curses_window_redrawln__doc__}, + +static PyObject * +_curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num); + +static PyObject * +_curses_window_redrawln(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int beg; + int num; + + if (!_PyArg_CheckPositional("redrawln", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + beg = _PyLong_AsInt(args[0]); + if (beg == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + num = _PyLong_AsInt(args[1]); + if (num == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_window_redrawln_impl(self, beg, num); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_refresh__doc__, +"refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\n" +"Update the display immediately.\n" +"\n" +"Synchronize actual screen with previous drawing/deleting methods.\n" +"The 6 optional arguments can only be specified when the window is a pad\n" +"created with newpad(). The additional parameters are needed to indicate\n" +"what part of the pad and screen are involved. pminrow and pmincol specify\n" +"the upper left-hand corner of the rectangle to be displayed in the pad.\n" +"sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to\n" +"be displayed on the screen. The lower right-hand corner of the rectangle to\n" +"be displayed in the pad is calculated from the screen coordinates, since the\n" +"rectangles must be the same size. Both rectangles must be entirely contained\n" +"within their respective structures. Negative values of pminrow, pmincol,\n" +"sminrow, or smincol are treated as if they were zero."); + +#define _CURSES_WINDOW_REFRESH_METHODDEF \ + {"refresh", (PyCFunction)_curses_window_refresh, METH_VARARGS, _curses_window_refresh__doc__}, + +static PyObject * +_curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, + int pminrow, int pmincol, int sminrow, + int smincol, int smaxrow, int smaxcol); + +static PyObject * +_curses_window_refresh(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int pminrow = 0; + int pmincol = 0; + int sminrow = 0; + int smincol = 0; + int smaxrow = 0; + int smaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 6: + if (!PyArg_ParseTuple(args, "iiiiii:refresh", &pminrow, &pmincol, &sminrow, &smincol, &smaxrow, &smaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.refresh requires 0 to 6 arguments"); + goto exit; + } + return_value = _curses_window_refresh_impl(self, group_right_1, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_setscrreg__doc__, +"setscrreg($self, top, bottom, /)\n" +"--\n" +"\n" +"Define a software scrolling region.\n" +"\n" +" top\n" +" First line number.\n" +" bottom\n" +" Last line number.\n" +"\n" +"All scrolling actions will take place in this region."); + +#define _CURSES_WINDOW_SETSCRREG_METHODDEF \ + {"setscrreg", (PyCFunction)(void(*)(void))_curses_window_setscrreg, METH_FASTCALL, _curses_window_setscrreg__doc__}, + +static PyObject * +_curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, + int bottom); + +static PyObject * +_curses_window_setscrreg(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int top; + int bottom; + + if (!_PyArg_CheckPositional("setscrreg", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + top = _PyLong_AsInt(args[0]); + if (top == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bottom = _PyLong_AsInt(args[1]); + if (bottom == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_window_setscrreg_impl(self, top, bottom); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_subwin__doc__, +"subwin([nlines=0, ncols=0,] begin_y, begin_x)\n" +"Create a sub-window (screen-relative coordinates).\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"By default, the sub-window will extend from the specified position to the\n" +"lower right corner of the window."); + +#define _CURSES_WINDOW_SUBWIN_METHODDEF \ + {"subwin", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__}, + +static PyObject * +_curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x); + +static PyObject * +_curses_window_subwin(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int nlines = 0; + int ncols = 0; + int begin_y; + int begin_x; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:subwin", &begin_y, &begin_x)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:subwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.subwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_window_subwin_impl(self, group_left_1, nlines, ncols, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_scroll__doc__, +"scroll([lines=1])\n" +"Scroll the screen or scrolling region.\n" +"\n" +" lines\n" +" Number of lines to scroll.\n" +"\n" +"Scroll upward if the argument is positive and downward if it is negative."); + +#define _CURSES_WINDOW_SCROLL_METHODDEF \ + {"scroll", (PyCFunction)_curses_window_scroll, METH_VARARGS, _curses_window_scroll__doc__}, + +static PyObject * +_curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, + int lines); + +static PyObject * +_curses_window_scroll(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int lines = 1; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 1: + if (!PyArg_ParseTuple(args, "i:scroll", &lines)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.scroll requires 0 to 1 arguments"); + goto exit; + } + return_value = _curses_window_scroll_impl(self, group_right_1, lines); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_touchline__doc__, +"touchline(start, count, [changed=True])\n" +"Pretend count lines have been changed, starting with line start.\n" +"\n" +"If changed is supplied, it specifies whether the affected lines are marked\n" +"as having been changed (changed=True) or unchanged (changed=False)."); + +#define _CURSES_WINDOW_TOUCHLINE_METHODDEF \ + {"touchline", (PyCFunction)_curses_window_touchline, METH_VARARGS, _curses_window_touchline__doc__}, + +static PyObject * +_curses_window_touchline_impl(PyCursesWindowObject *self, int start, + int count, int group_right_1, int changed); + +static PyObject * +_curses_window_touchline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int start; + int count; + int group_right_1 = 0; + int changed = 1; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:touchline", &start, &count)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "iii:touchline", &start, &count, &changed)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.touchline requires 2 to 3 arguments"); + goto exit; + } + return_value = _curses_window_touchline_impl(self, start, count, group_right_1, changed); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_vline__doc__, +"vline([y, x,] ch, n, [attr=_curses.A_NORMAL])\n" +"Display a vertical line.\n" +"\n" +" y\n" +" Starting Y-coordinate.\n" +" x\n" +" Starting X-coordinate.\n" +" ch\n" +" Character to draw.\n" +" n\n" +" Line length.\n" +" attr\n" +" Attributes for the character."); + +#define _CURSES_WINDOW_VLINE_METHODDEF \ + {"vline", (PyCFunction)_curses_window_vline, METH_VARARGS, _curses_window_vline__doc__}, + +static PyObject * +_curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_vline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int n; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:vline", &ch, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:vline", &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:vline", &y, &x, &ch, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:vline", &y, &x, &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.vline requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_vline_impl(self, group_left_1, y, x, ch, n, group_right_1, attr); + +exit: + return return_value; +} + +#if defined(HAVE_CURSES_FILTER) + +PyDoc_STRVAR(_curses_filter__doc__, +"filter($module, /)\n" +"--\n" +"\n"); + +#define _CURSES_FILTER_METHODDEF \ + {"filter", (PyCFunction)_curses_filter, METH_NOARGS, _curses_filter__doc__}, + +static PyObject * +_curses_filter_impl(PyObject *module); + +static PyObject * +_curses_filter(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_filter_impl(module); +} + +#endif /* defined(HAVE_CURSES_FILTER) */ + +PyDoc_STRVAR(_curses_baudrate__doc__, +"baudrate($module, /)\n" +"--\n" +"\n" +"Return the output speed of the terminal in bits per second."); + +#define _CURSES_BAUDRATE_METHODDEF \ + {"baudrate", (PyCFunction)_curses_baudrate, METH_NOARGS, _curses_baudrate__doc__}, + +static PyObject * +_curses_baudrate_impl(PyObject *module); + +static PyObject * +_curses_baudrate(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_baudrate_impl(module); +} + +PyDoc_STRVAR(_curses_beep__doc__, +"beep($module, /)\n" +"--\n" +"\n" +"Emit a short attention sound."); + +#define _CURSES_BEEP_METHODDEF \ + {"beep", (PyCFunction)_curses_beep, METH_NOARGS, _curses_beep__doc__}, + +static PyObject * +_curses_beep_impl(PyObject *module); + +static PyObject * +_curses_beep(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_beep_impl(module); +} + +PyDoc_STRVAR(_curses_can_change_color__doc__, +"can_change_color($module, /)\n" +"--\n" +"\n" +"Return True if the programmer can change the colors displayed by the terminal."); + +#define _CURSES_CAN_CHANGE_COLOR_METHODDEF \ + {"can_change_color", (PyCFunction)_curses_can_change_color, METH_NOARGS, _curses_can_change_color__doc__}, + +static PyObject * +_curses_can_change_color_impl(PyObject *module); + +static PyObject * +_curses_can_change_color(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_can_change_color_impl(module); +} + +PyDoc_STRVAR(_curses_cbreak__doc__, +"cbreak($module, flag=True, /)\n" +"--\n" +"\n" +"Enter cbreak mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling nocbreak().\n" +"\n" +"In cbreak mode (sometimes called \"rare\" mode) normal tty line buffering is\n" +"turned off and characters are available to be read one by one. However,\n" +"unlike raw mode, special characters (interrupt, quit, suspend, and flow\n" +"control) retain their effects on the tty driver and calling program.\n" +"Calling first raw() then cbreak() leaves the terminal in cbreak mode."); + +#define _CURSES_CBREAK_METHODDEF \ + {"cbreak", (PyCFunction)(void(*)(void))_curses_cbreak, METH_FASTCALL, _curses_cbreak__doc__}, + +static PyObject * +_curses_cbreak_impl(PyObject *module, int flag); + +static PyObject * +_curses_cbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_CheckPositional("cbreak", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(args[0]); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_cbreak_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_color_content__doc__, +"color_content($module, color_number, /)\n" +"--\n" +"\n" +"Return the red, green, and blue (RGB) components of the specified color.\n" +"\n" +" color_number\n" +" The number of the color (0 - (COLORS-1)).\n" +"\n" +"A 3-tuple is returned, containing the R, G, B values for the given color,\n" +"which will be between 0 (no component) and 1000 (maximum amount of component)."); + +#define _CURSES_COLOR_CONTENT_METHODDEF \ + {"color_content", (PyCFunction)_curses_color_content, METH_O, _curses_color_content__doc__}, + +static PyObject * +_curses_color_content_impl(PyObject *module, short color_number); + +static PyObject * +_curses_color_content(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short color_number; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + color_number = (short) ival; + } + } + return_value = _curses_color_content_impl(module, color_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_color_pair__doc__, +"color_pair($module, pair_number, /)\n" +"--\n" +"\n" +"Return the attribute value for displaying text in the specified color.\n" +"\n" +" pair_number\n" +" The number of the color pair.\n" +"\n" +"This attribute value can be combined with A_STANDOUT, A_REVERSE, and the\n" +"other A_* attributes. pair_number() is the counterpart to this function."); + +#define _CURSES_COLOR_PAIR_METHODDEF \ + {"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__}, + +static PyObject * +_curses_color_pair_impl(PyObject *module, short pair_number); + +static PyObject * +_curses_color_pair(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short pair_number; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + pair_number = (short) ival; + } + } + return_value = _curses_color_pair_impl(module, pair_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_curs_set__doc__, +"curs_set($module, visibility, /)\n" +"--\n" +"\n" +"Set the cursor state.\n" +"\n" +" visibility\n" +" 0 for invisible, 1 for normal visible, or 2 for very visible.\n" +"\n" +"If the terminal supports the visibility requested, the previous cursor\n" +"state is returned; otherwise, an exception is raised. On many terminals,\n" +"the \"visible\" mode is an underline cursor and the \"very visible\" mode is\n" +"a block cursor."); + +#define _CURSES_CURS_SET_METHODDEF \ + {"curs_set", (PyCFunction)_curses_curs_set, METH_O, _curses_curs_set__doc__}, + +static PyObject * +_curses_curs_set_impl(PyObject *module, int visibility); + +static PyObject * +_curses_curs_set(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int visibility; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + visibility = _PyLong_AsInt(arg); + if (visibility == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_curs_set_impl(module, visibility); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_def_prog_mode__doc__, +"def_prog_mode($module, /)\n" +"--\n" +"\n" +"Save the current terminal mode as the \"program\" mode.\n" +"\n" +"The \"program\" mode is the mode when the running program is using curses.\n" +"\n" +"Subsequent calls to reset_prog_mode() will restore this mode."); + +#define _CURSES_DEF_PROG_MODE_METHODDEF \ + {"def_prog_mode", (PyCFunction)_curses_def_prog_mode, METH_NOARGS, _curses_def_prog_mode__doc__}, + +static PyObject * +_curses_def_prog_mode_impl(PyObject *module); + +static PyObject * +_curses_def_prog_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_def_prog_mode_impl(module); +} + +PyDoc_STRVAR(_curses_def_shell_mode__doc__, +"def_shell_mode($module, /)\n" +"--\n" +"\n" +"Save the current terminal mode as the \"shell\" mode.\n" +"\n" +"The \"shell\" mode is the mode when the running program is not using curses.\n" +"\n" +"Subsequent calls to reset_shell_mode() will restore this mode."); + +#define _CURSES_DEF_SHELL_MODE_METHODDEF \ + {"def_shell_mode", (PyCFunction)_curses_def_shell_mode, METH_NOARGS, _curses_def_shell_mode__doc__}, + +static PyObject * +_curses_def_shell_mode_impl(PyObject *module); + +static PyObject * +_curses_def_shell_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_def_shell_mode_impl(module); +} + +PyDoc_STRVAR(_curses_delay_output__doc__, +"delay_output($module, ms, /)\n" +"--\n" +"\n" +"Insert a pause in output.\n" +"\n" +" ms\n" +" Duration in milliseconds."); + +#define _CURSES_DELAY_OUTPUT_METHODDEF \ + {"delay_output", (PyCFunction)_curses_delay_output, METH_O, _curses_delay_output__doc__}, + +static PyObject * +_curses_delay_output_impl(PyObject *module, int ms); + +static PyObject * +_curses_delay_output(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int ms; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + ms = _PyLong_AsInt(arg); + if (ms == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_delay_output_impl(module, ms); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_doupdate__doc__, +"doupdate($module, /)\n" +"--\n" +"\n" +"Update the physical screen to match the virtual screen."); + +#define _CURSES_DOUPDATE_METHODDEF \ + {"doupdate", (PyCFunction)_curses_doupdate, METH_NOARGS, _curses_doupdate__doc__}, + +static PyObject * +_curses_doupdate_impl(PyObject *module); + +static PyObject * +_curses_doupdate(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_doupdate_impl(module); +} + +PyDoc_STRVAR(_curses_echo__doc__, +"echo($module, flag=True, /)\n" +"--\n" +"\n" +"Enter echo mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noecho().\n" +"\n" +"In echo mode, each character input is echoed to the screen as it is entered."); + +#define _CURSES_ECHO_METHODDEF \ + {"echo", (PyCFunction)(void(*)(void))_curses_echo, METH_FASTCALL, _curses_echo__doc__}, + +static PyObject * +_curses_echo_impl(PyObject *module, int flag); + +static PyObject * +_curses_echo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_CheckPositional("echo", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(args[0]); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_echo_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_endwin__doc__, +"endwin($module, /)\n" +"--\n" +"\n" +"De-initialize the library, and return terminal to normal status."); + +#define _CURSES_ENDWIN_METHODDEF \ + {"endwin", (PyCFunction)_curses_endwin, METH_NOARGS, _curses_endwin__doc__}, + +static PyObject * +_curses_endwin_impl(PyObject *module); + +static PyObject * +_curses_endwin(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_endwin_impl(module); +} + +PyDoc_STRVAR(_curses_erasechar__doc__, +"erasechar($module, /)\n" +"--\n" +"\n" +"Return the user\'s current erase character."); + +#define _CURSES_ERASECHAR_METHODDEF \ + {"erasechar", (PyCFunction)_curses_erasechar, METH_NOARGS, _curses_erasechar__doc__}, + +static PyObject * +_curses_erasechar_impl(PyObject *module); + +static PyObject * +_curses_erasechar(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_erasechar_impl(module); +} + +PyDoc_STRVAR(_curses_flash__doc__, +"flash($module, /)\n" +"--\n" +"\n" +"Flash the screen.\n" +"\n" +"That is, change it to reverse-video and then change it back in a short interval."); + +#define _CURSES_FLASH_METHODDEF \ + {"flash", (PyCFunction)_curses_flash, METH_NOARGS, _curses_flash__doc__}, + +static PyObject * +_curses_flash_impl(PyObject *module); + +static PyObject * +_curses_flash(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_flash_impl(module); +} + +PyDoc_STRVAR(_curses_flushinp__doc__, +"flushinp($module, /)\n" +"--\n" +"\n" +"Flush all input buffers.\n" +"\n" +"This throws away any typeahead that has been typed by the user and has not\n" +"yet been processed by the program."); + +#define _CURSES_FLUSHINP_METHODDEF \ + {"flushinp", (PyCFunction)_curses_flushinp, METH_NOARGS, _curses_flushinp__doc__}, + +static PyObject * +_curses_flushinp_impl(PyObject *module); + +static PyObject * +_curses_flushinp(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_flushinp_impl(module); +} + +#if defined(getsyx) + +PyDoc_STRVAR(_curses_getsyx__doc__, +"getsyx($module, /)\n" +"--\n" +"\n" +"Return the current coordinates of the virtual screen cursor.\n" +"\n" +"Return a (y, x) tuple. If leaveok is currently true, return (-1, -1)."); + +#define _CURSES_GETSYX_METHODDEF \ + {"getsyx", (PyCFunction)_curses_getsyx, METH_NOARGS, _curses_getsyx__doc__}, + +static PyObject * +_curses_getsyx_impl(PyObject *module); + +static PyObject * +_curses_getsyx(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_getsyx_impl(module); +} + +#endif /* defined(getsyx) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_getmouse__doc__, +"getmouse($module, /)\n" +"--\n" +"\n" +"Retrieve the queued mouse event.\n" +"\n" +"After getch() returns KEY_MOUSE to signal a mouse event, this function\n" +"returns a 5-tuple (id, x, y, z, bstate)."); + +#define _CURSES_GETMOUSE_METHODDEF \ + {"getmouse", (PyCFunction)_curses_getmouse, METH_NOARGS, _curses_getmouse__doc__}, + +static PyObject * +_curses_getmouse_impl(PyObject *module); + +static PyObject * +_curses_getmouse(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_getmouse_impl(module); +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_ungetmouse__doc__, +"ungetmouse($module, id, x, y, z, bstate, /)\n" +"--\n" +"\n" +"Push a KEY_MOUSE event onto the input queue.\n" +"\n" +"The following getmouse() will return the given state data."); + +#define _CURSES_UNGETMOUSE_METHODDEF \ + {"ungetmouse", (PyCFunction)(void(*)(void))_curses_ungetmouse, METH_FASTCALL, _curses_ungetmouse__doc__}, + +static PyObject * +_curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, + unsigned long bstate); + +static PyObject * +_curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short id; + int x; + int y; + int z; + unsigned long bstate; + + if (!_PyArg_CheckPositional("ungetmouse", nargs, 5, 5)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[0]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + id = (short) ival; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + x = _PyLong_AsInt(args[1]); + if (x == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + y = _PyLong_AsInt(args[2]); + if (y == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + z = _PyLong_AsInt(args[3]); + if (z == -1 && PyErr_Occurred()) { + goto exit; + } + if (!PyLong_Check(args[4])) { + _PyArg_BadArgument("ungetmouse", "argument 5", "int", args[4]); + goto exit; + } + bstate = PyLong_AsUnsignedLongMask(args[4]); + return_value = _curses_ungetmouse_impl(module, id, x, y, z, bstate); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_getwin__doc__, +"getwin($module, file, /)\n" +"--\n" +"\n" +"Read window related data stored in the file by an earlier putwin() call.\n" +"\n" +"The routine then creates and initializes a new window using that data,\n" +"returning the new window object."); + +#define _CURSES_GETWIN_METHODDEF \ + {"getwin", (PyCFunction)_curses_getwin, METH_O, _curses_getwin__doc__}, + +PyDoc_STRVAR(_curses_halfdelay__doc__, +"halfdelay($module, tenths, /)\n" +"--\n" +"\n" +"Enter half-delay mode.\n" +"\n" +" tenths\n" +" Maximal blocking delay in tenths of seconds (1 - 255).\n" +"\n" +"Use nocbreak() to leave half-delay mode."); + +#define _CURSES_HALFDELAY_METHODDEF \ + {"halfdelay", (PyCFunction)_curses_halfdelay, METH_O, _curses_halfdelay__doc__}, + +static PyObject * +_curses_halfdelay_impl(PyObject *module, unsigned char tenths); + +static PyObject * +_curses_halfdelay(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned char tenths; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is less than minimum"); + goto exit; + } + else if (ival > UCHAR_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is greater than maximum"); + goto exit; + } + else { + tenths = (unsigned char) ival; + } + } + return_value = _curses_halfdelay_impl(module, tenths); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_has_colors__doc__, +"has_colors($module, /)\n" +"--\n" +"\n" +"Return True if the terminal can display colors; otherwise, return False."); + +#define _CURSES_HAS_COLORS_METHODDEF \ + {"has_colors", (PyCFunction)_curses_has_colors, METH_NOARGS, _curses_has_colors__doc__}, + +static PyObject * +_curses_has_colors_impl(PyObject *module); + +static PyObject * +_curses_has_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_colors_impl(module); +} + +PyDoc_STRVAR(_curses_has_ic__doc__, +"has_ic($module, /)\n" +"--\n" +"\n" +"Return True if the terminal has insert- and delete-character capabilities."); + +#define _CURSES_HAS_IC_METHODDEF \ + {"has_ic", (PyCFunction)_curses_has_ic, METH_NOARGS, _curses_has_ic__doc__}, + +static PyObject * +_curses_has_ic_impl(PyObject *module); + +static PyObject * +_curses_has_ic(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_ic_impl(module); +} + +PyDoc_STRVAR(_curses_has_il__doc__, +"has_il($module, /)\n" +"--\n" +"\n" +"Return True if the terminal has insert- and delete-line capabilities."); + +#define _CURSES_HAS_IL_METHODDEF \ + {"has_il", (PyCFunction)_curses_has_il, METH_NOARGS, _curses_has_il__doc__}, + +static PyObject * +_curses_has_il_impl(PyObject *module); + +static PyObject * +_curses_has_il(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_il_impl(module); +} + +#if defined(HAVE_CURSES_HAS_KEY) + +PyDoc_STRVAR(_curses_has_key__doc__, +"has_key($module, key, /)\n" +"--\n" +"\n" +"Return True if the current terminal type recognizes a key with that value.\n" +"\n" +" key\n" +" Key number."); + +#define _CURSES_HAS_KEY_METHODDEF \ + {"has_key", (PyCFunction)_curses_has_key, METH_O, _curses_has_key__doc__}, + +static PyObject * +_curses_has_key_impl(PyObject *module, int key); + +static PyObject * +_curses_has_key(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int key; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + key = _PyLong_AsInt(arg); + if (key == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_has_key_impl(module, key); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_HAS_KEY) */ + +PyDoc_STRVAR(_curses_init_color__doc__, +"init_color($module, color_number, r, g, b, /)\n" +"--\n" +"\n" +"Change the definition of a color.\n" +"\n" +" color_number\n" +" The number of the color to be changed (0 - (COLORS-1)).\n" +" r\n" +" Red component (0 - 1000).\n" +" g\n" +" Green component (0 - 1000).\n" +" b\n" +" Blue component (0 - 1000).\n" +"\n" +"When init_color() is used, all occurrences of that color on the screen\n" +"immediately change to the new definition. This function is a no-op on\n" +"most terminals; it is active only if can_change_color() returns true."); + +#define _CURSES_INIT_COLOR_METHODDEF \ + {"init_color", (PyCFunction)(void(*)(void))_curses_init_color, METH_FASTCALL, _curses_init_color__doc__}, + +static PyObject * +_curses_init_color_impl(PyObject *module, short color_number, short r, + short g, short b); + +static PyObject * +_curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short color_number; + short r; + short g; + short b; + + if (!_PyArg_CheckPositional("init_color", nargs, 4, 4)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[0]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + color_number = (short) ival; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[1]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + r = (short) ival; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[2]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + g = (short) ival; + } + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[3]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + b = (short) ival; + } + } + return_value = _curses_init_color_impl(module, color_number, r, g, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_init_pair__doc__, +"init_pair($module, pair_number, fg, bg, /)\n" +"--\n" +"\n" +"Change the definition of a color-pair.\n" +"\n" +" pair_number\n" +" The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).\n" +" fg\n" +" Foreground color number (-1 - (COLORS-1)).\n" +" bg\n" +" Background color number (-1 - (COLORS-1)).\n" +"\n" +"If the color-pair was previously initialized, the screen is refreshed and\n" +"all occurrences of that color-pair are changed to the new definition."); + +#define _CURSES_INIT_PAIR_METHODDEF \ + {"init_pair", (PyCFunction)(void(*)(void))_curses_init_pair, METH_FASTCALL, _curses_init_pair__doc__}, + +static PyObject * +_curses_init_pair_impl(PyObject *module, short pair_number, short fg, + short bg); + +static PyObject * +_curses_init_pair(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short pair_number; + short fg; + short bg; + + if (!_PyArg_CheckPositional("init_pair", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[0]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + pair_number = (short) ival; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[1]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + fg = (short) ival; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(args[2]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + bg = (short) ival; + } + } + return_value = _curses_init_pair_impl(module, pair_number, fg, bg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_initscr__doc__, +"initscr($module, /)\n" +"--\n" +"\n" +"Initialize the library.\n" +"\n" +"Return a WindowObject which represents the whole screen."); + +#define _CURSES_INITSCR_METHODDEF \ + {"initscr", (PyCFunction)_curses_initscr, METH_NOARGS, _curses_initscr__doc__}, + +static PyObject * +_curses_initscr_impl(PyObject *module); + +static PyObject * +_curses_initscr(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_initscr_impl(module); +} + +PyDoc_STRVAR(_curses_setupterm__doc__, +"setupterm($module, /, term=None, fd=-1)\n" +"--\n" +"\n" +"Initialize the terminal.\n" +"\n" +" term\n" +" Terminal name.\n" +" If omitted, the value of the TERM environment variable will be used.\n" +" fd\n" +" File descriptor to which any initialization sequences will be sent.\n" +" If not supplied, the file descriptor for sys.stdout will be used."); + +#define _CURSES_SETUPTERM_METHODDEF \ + {"setupterm", (PyCFunction)(void(*)(void))_curses_setupterm, METH_FASTCALL|METH_KEYWORDS, _curses_setupterm__doc__}, + +static PyObject * +_curses_setupterm_impl(PyObject *module, const char *term, int fd); + +static PyObject * +_curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"term", "fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "setupterm", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + const char *term = NULL; + int fd = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (args[0] == Py_None) { + term = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t term_length; + term = PyUnicode_AsUTF8AndSize(args[0], &term_length); + if (term == NULL) { + goto exit; + } + if (strlen(term) != (size_t)term_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("setupterm", "argument 'term'", "str or None", args[0]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fd = _PyLong_AsInt(args[1]); + if (fd == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = _curses_setupterm_impl(module, term, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_intrflush__doc__, +"intrflush($module, flag, /)\n" +"--\n" +"\n"); + +#define _CURSES_INTRFLUSH_METHODDEF \ + {"intrflush", (PyCFunction)_curses_intrflush, METH_O, _curses_intrflush__doc__}, + +static PyObject * +_curses_intrflush_impl(PyObject *module, int flag); + +static PyObject * +_curses_intrflush(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(arg); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_intrflush_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_isendwin__doc__, +"isendwin($module, /)\n" +"--\n" +"\n" +"Return True if endwin() has been called."); + +#define _CURSES_ISENDWIN_METHODDEF \ + {"isendwin", (PyCFunction)_curses_isendwin, METH_NOARGS, _curses_isendwin__doc__}, + +static PyObject * +_curses_isendwin_impl(PyObject *module); + +static PyObject * +_curses_isendwin(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_isendwin_impl(module); +} + +#if defined(HAVE_CURSES_IS_TERM_RESIZED) + +PyDoc_STRVAR(_curses_is_term_resized__doc__, +"is_term_resized($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Return True if resize_term() would modify the window structure, False otherwise.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width."); + +#define _CURSES_IS_TERM_RESIZED_METHODDEF \ + {"is_term_resized", (PyCFunction)(void(*)(void))_curses_is_term_resized, METH_FASTCALL, _curses_is_term_resized__doc__}, + +static PyObject * +_curses_is_term_resized_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_is_term_resized(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_CheckPositional("is_term_resized", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + nlines = _PyLong_AsInt(args[0]); + if (nlines == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + ncols = _PyLong_AsInt(args[1]); + if (ncols == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_is_term_resized_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_IS_TERM_RESIZED) */ + +PyDoc_STRVAR(_curses_keyname__doc__, +"keyname($module, key, /)\n" +"--\n" +"\n" +"Return the name of specified key.\n" +"\n" +" key\n" +" Key number."); + +#define _CURSES_KEYNAME_METHODDEF \ + {"keyname", (PyCFunction)_curses_keyname, METH_O, _curses_keyname__doc__}, + +static PyObject * +_curses_keyname_impl(PyObject *module, int key); + +static PyObject * +_curses_keyname(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int key; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + key = _PyLong_AsInt(arg); + if (key == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_keyname_impl(module, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_killchar__doc__, +"killchar($module, /)\n" +"--\n" +"\n" +"Return the user\'s current line kill character."); + +#define _CURSES_KILLCHAR_METHODDEF \ + {"killchar", (PyCFunction)_curses_killchar, METH_NOARGS, _curses_killchar__doc__}, + +static PyObject * +_curses_killchar_impl(PyObject *module); + +static PyObject * +_curses_killchar(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_killchar_impl(module); +} + +PyDoc_STRVAR(_curses_longname__doc__, +"longname($module, /)\n" +"--\n" +"\n" +"Return the terminfo long name field describing the current terminal.\n" +"\n" +"The maximum length of a verbose description is 128 characters. It is defined\n" +"only after the call to initscr()."); + +#define _CURSES_LONGNAME_METHODDEF \ + {"longname", (PyCFunction)_curses_longname, METH_NOARGS, _curses_longname__doc__}, + +static PyObject * +_curses_longname_impl(PyObject *module); + +static PyObject * +_curses_longname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_longname_impl(module); +} + +PyDoc_STRVAR(_curses_meta__doc__, +"meta($module, yes, /)\n" +"--\n" +"\n" +"Enable/disable meta keys.\n" +"\n" +"If yes is True, allow 8-bit characters to be input. If yes is False,\n" +"allow only 7-bit characters."); + +#define _CURSES_META_METHODDEF \ + {"meta", (PyCFunction)_curses_meta, METH_O, _curses_meta__doc__}, + +static PyObject * +_curses_meta_impl(PyObject *module, int yes); + +static PyObject * +_curses_meta(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int yes; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + yes = _PyLong_AsInt(arg); + if (yes == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_meta_impl(module, yes); + +exit: + return return_value; +} + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_mouseinterval__doc__, +"mouseinterval($module, interval, /)\n" +"--\n" +"\n" +"Set and retrieve the maximum time between press and release in a click.\n" +"\n" +" interval\n" +" Time in milliseconds.\n" +"\n" +"Set the maximum time that can elapse between press and release events in\n" +"order for them to be recognized as a click, and return the previous interval\n" +"value."); + +#define _CURSES_MOUSEINTERVAL_METHODDEF \ + {"mouseinterval", (PyCFunction)_curses_mouseinterval, METH_O, _curses_mouseinterval__doc__}, + +static PyObject * +_curses_mouseinterval_impl(PyObject *module, int interval); + +static PyObject * +_curses_mouseinterval(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int interval; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + interval = _PyLong_AsInt(arg); + if (interval == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_mouseinterval_impl(module, interval); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_mousemask__doc__, +"mousemask($module, newmask, /)\n" +"--\n" +"\n" +"Set the mouse events to be reported, and return a tuple (availmask, oldmask).\n" +"\n" +"Return a tuple (availmask, oldmask). availmask indicates which of the\n" +"specified mouse events can be reported; on complete failure it returns 0.\n" +"oldmask is the previous value of the given window\'s mouse event mask.\n" +"If this function is never called, no mouse events are ever reported."); + +#define _CURSES_MOUSEMASK_METHODDEF \ + {"mousemask", (PyCFunction)_curses_mousemask, METH_O, _curses_mousemask__doc__}, + +static PyObject * +_curses_mousemask_impl(PyObject *module, unsigned long newmask); + +static PyObject * +_curses_mousemask(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned long newmask; + + if (!PyLong_Check(arg)) { + _PyArg_BadArgument("mousemask", "argument", "int", arg); + goto exit; + } + newmask = PyLong_AsUnsignedLongMask(arg); + return_value = _curses_mousemask_impl(module, newmask); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_napms__doc__, +"napms($module, ms, /)\n" +"--\n" +"\n" +"Sleep for specified time.\n" +"\n" +" ms\n" +" Duration in milliseconds."); + +#define _CURSES_NAPMS_METHODDEF \ + {"napms", (PyCFunction)_curses_napms, METH_O, _curses_napms__doc__}, + +static PyObject * +_curses_napms_impl(PyObject *module, int ms); + +static PyObject * +_curses_napms(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int ms; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + ms = _PyLong_AsInt(arg); + if (ms == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_napms_impl(module, ms); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_newpad__doc__, +"newpad($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Create and return a pointer to a new pad data structure.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width."); + +#define _CURSES_NEWPAD_METHODDEF \ + {"newpad", (PyCFunction)(void(*)(void))_curses_newpad, METH_FASTCALL, _curses_newpad__doc__}, + +static PyObject * +_curses_newpad_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_newpad(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_CheckPositional("newpad", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + nlines = _PyLong_AsInt(args[0]); + if (nlines == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + ncols = _PyLong_AsInt(args[1]); + if (ncols == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_newpad_impl(module, nlines, ncols); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_newwin__doc__, +"newwin(nlines, ncols, [begin_y=0, begin_x=0])\n" +"Return a new window.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"By default, the window will extend from the specified position to the lower\n" +"right corner of the screen."); + +#define _CURSES_NEWWIN_METHODDEF \ + {"newwin", (PyCFunction)_curses_newwin, METH_VARARGS, _curses_newwin__doc__}, + +static PyObject * +_curses_newwin_impl(PyObject *module, int nlines, int ncols, + int group_right_1, int begin_y, int begin_x); + +static PyObject * +_curses_newwin(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + int group_right_1 = 0; + int begin_y = 0; + int begin_x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:newwin", &nlines, &ncols)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:newwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.newwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_newwin_impl(module, nlines, ncols, group_right_1, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_nl__doc__, +"nl($module, flag=True, /)\n" +"--\n" +"\n" +"Enter newline mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling nonl().\n" +"\n" +"This mode translates the return key into newline on input, and translates\n" +"newline into return and line-feed on output. Newline mode is initially on."); + +#define _CURSES_NL_METHODDEF \ + {"nl", (PyCFunction)(void(*)(void))_curses_nl, METH_FASTCALL, _curses_nl__doc__}, + +static PyObject * +_curses_nl_impl(PyObject *module, int flag); + +static PyObject * +_curses_nl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_CheckPositional("nl", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(args[0]); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_nl_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_nocbreak__doc__, +"nocbreak($module, /)\n" +"--\n" +"\n" +"Leave cbreak mode.\n" +"\n" +"Return to normal \"cooked\" mode with line buffering."); + +#define _CURSES_NOCBREAK_METHODDEF \ + {"nocbreak", (PyCFunction)_curses_nocbreak, METH_NOARGS, _curses_nocbreak__doc__}, + +static PyObject * +_curses_nocbreak_impl(PyObject *module); + +static PyObject * +_curses_nocbreak(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_nocbreak_impl(module); +} + +PyDoc_STRVAR(_curses_noecho__doc__, +"noecho($module, /)\n" +"--\n" +"\n" +"Leave echo mode.\n" +"\n" +"Echoing of input characters is turned off."); + +#define _CURSES_NOECHO_METHODDEF \ + {"noecho", (PyCFunction)_curses_noecho, METH_NOARGS, _curses_noecho__doc__}, + +static PyObject * +_curses_noecho_impl(PyObject *module); + +static PyObject * +_curses_noecho(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noecho_impl(module); +} + +PyDoc_STRVAR(_curses_nonl__doc__, +"nonl($module, /)\n" +"--\n" +"\n" +"Leave newline mode.\n" +"\n" +"Disable translation of return into newline on input, and disable low-level\n" +"translation of newline into newline/return on output."); + +#define _CURSES_NONL_METHODDEF \ + {"nonl", (PyCFunction)_curses_nonl, METH_NOARGS, _curses_nonl__doc__}, + +static PyObject * +_curses_nonl_impl(PyObject *module); + +static PyObject * +_curses_nonl(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_nonl_impl(module); +} + +PyDoc_STRVAR(_curses_noqiflush__doc__, +"noqiflush($module, /)\n" +"--\n" +"\n" +"Disable queue flushing.\n" +"\n" +"When queue flushing is disabled, normal flush of input and output queues\n" +"associated with the INTR, QUIT and SUSP characters will not be done."); + +#define _CURSES_NOQIFLUSH_METHODDEF \ + {"noqiflush", (PyCFunction)_curses_noqiflush, METH_NOARGS, _curses_noqiflush__doc__}, + +static PyObject * +_curses_noqiflush_impl(PyObject *module); + +static PyObject * +_curses_noqiflush(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noqiflush_impl(module); +} + +PyDoc_STRVAR(_curses_noraw__doc__, +"noraw($module, /)\n" +"--\n" +"\n" +"Leave raw mode.\n" +"\n" +"Return to normal \"cooked\" mode with line buffering."); + +#define _CURSES_NORAW_METHODDEF \ + {"noraw", (PyCFunction)_curses_noraw, METH_NOARGS, _curses_noraw__doc__}, + +static PyObject * +_curses_noraw_impl(PyObject *module); + +static PyObject * +_curses_noraw(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noraw_impl(module); +} + +PyDoc_STRVAR(_curses_pair_content__doc__, +"pair_content($module, pair_number, /)\n" +"--\n" +"\n" +"Return a tuple (fg, bg) containing the colors for the requested color pair.\n" +"\n" +" pair_number\n" +" The number of the color pair (1 - (COLOR_PAIRS-1))."); + +#define _CURSES_PAIR_CONTENT_METHODDEF \ + {"pair_content", (PyCFunction)_curses_pair_content, METH_O, _curses_pair_content__doc__}, + +static PyObject * +_curses_pair_content_impl(PyObject *module, short pair_number); + +static PyObject * +_curses_pair_content(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short pair_number; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + long ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + pair_number = (short) ival; + } + } + return_value = _curses_pair_content_impl(module, pair_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_pair_number__doc__, +"pair_number($module, attr, /)\n" +"--\n" +"\n" +"Return the number of the color-pair set by the specified attribute value.\n" +"\n" +"color_pair() is the counterpart to this function."); + +#define _CURSES_PAIR_NUMBER_METHODDEF \ + {"pair_number", (PyCFunction)_curses_pair_number, METH_O, _curses_pair_number__doc__}, + +static PyObject * +_curses_pair_number_impl(PyObject *module, int attr); + +static PyObject * +_curses_pair_number(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int attr; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + attr = _PyLong_AsInt(arg); + if (attr == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_pair_number_impl(module, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_putp__doc__, +"putp($module, string, /)\n" +"--\n" +"\n" +"Emit the value of a specified terminfo capability for the current terminal.\n" +"\n" +"Note that the output of putp() always goes to standard output."); + +#define _CURSES_PUTP_METHODDEF \ + {"putp", (PyCFunction)_curses_putp, METH_O, _curses_putp__doc__}, + +static PyObject * +_curses_putp_impl(PyObject *module, const char *string); + +static PyObject * +_curses_putp(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *string; + + if (!PyArg_Parse(arg, "y:putp", &string)) { + goto exit; + } + return_value = _curses_putp_impl(module, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_qiflush__doc__, +"qiflush($module, flag=True, /)\n" +"--\n" +"\n" +"Enable queue flushing.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noqiflush().\n" +"\n" +"If queue flushing is enabled, all output in the display driver queue\n" +"will be flushed when the INTR, QUIT and SUSP characters are read."); + +#define _CURSES_QIFLUSH_METHODDEF \ + {"qiflush", (PyCFunction)(void(*)(void))_curses_qiflush, METH_FASTCALL, _curses_qiflush__doc__}, + +static PyObject * +_curses_qiflush_impl(PyObject *module, int flag); + +static PyObject * +_curses_qiflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_CheckPositional("qiflush", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(args[0]); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_qiflush_impl(module, flag); + +exit: + return return_value; +} + +#if (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) + +PyDoc_STRVAR(_curses_update_lines_cols__doc__, +"update_lines_cols($module, /)\n" +"--\n" +"\n"); + +#define _CURSES_UPDATE_LINES_COLS_METHODDEF \ + {"update_lines_cols", (PyCFunction)_curses_update_lines_cols, METH_NOARGS, _curses_update_lines_cols__doc__}, + +static PyObject * +_curses_update_lines_cols_impl(PyObject *module); + +static PyObject * +_curses_update_lines_cols(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_update_lines_cols_impl(module); +} + +#endif /* (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) */ + +PyDoc_STRVAR(_curses_raw__doc__, +"raw($module, flag=True, /)\n" +"--\n" +"\n" +"Enter raw mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noraw().\n" +"\n" +"In raw mode, normal line buffering and processing of interrupt, quit,\n" +"suspend, and flow control keys are turned off; characters are presented to\n" +"curses input functions one by one."); + +#define _CURSES_RAW_METHODDEF \ + {"raw", (PyCFunction)(void(*)(void))_curses_raw, METH_FASTCALL, _curses_raw__doc__}, + +static PyObject * +_curses_raw_impl(PyObject *module, int flag); + +static PyObject * +_curses_raw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_CheckPositional("raw", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(args[0]); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _curses_raw_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_reset_prog_mode__doc__, +"reset_prog_mode($module, /)\n" +"--\n" +"\n" +"Restore the terminal to \"program\" mode, as previously saved by def_prog_mode()."); + +#define _CURSES_RESET_PROG_MODE_METHODDEF \ + {"reset_prog_mode", (PyCFunction)_curses_reset_prog_mode, METH_NOARGS, _curses_reset_prog_mode__doc__}, + +static PyObject * +_curses_reset_prog_mode_impl(PyObject *module); + +static PyObject * +_curses_reset_prog_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_reset_prog_mode_impl(module); +} + +PyDoc_STRVAR(_curses_reset_shell_mode__doc__, +"reset_shell_mode($module, /)\n" +"--\n" +"\n" +"Restore the terminal to \"shell\" mode, as previously saved by def_shell_mode()."); + +#define _CURSES_RESET_SHELL_MODE_METHODDEF \ + {"reset_shell_mode", (PyCFunction)_curses_reset_shell_mode, METH_NOARGS, _curses_reset_shell_mode__doc__}, + +static PyObject * +_curses_reset_shell_mode_impl(PyObject *module); + +static PyObject * +_curses_reset_shell_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_reset_shell_mode_impl(module); +} + +PyDoc_STRVAR(_curses_resetty__doc__, +"resetty($module, /)\n" +"--\n" +"\n" +"Restore terminal mode."); + +#define _CURSES_RESETTY_METHODDEF \ + {"resetty", (PyCFunction)_curses_resetty, METH_NOARGS, _curses_resetty__doc__}, + +static PyObject * +_curses_resetty_impl(PyObject *module); + +static PyObject * +_curses_resetty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_resetty_impl(module); +} + +#if defined(HAVE_CURSES_RESIZETERM) + +PyDoc_STRVAR(_curses_resizeterm__doc__, +"resizeterm($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Resize the standard and current windows to the specified dimensions.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +"\n" +"Adjusts other bookkeeping data used by the curses library that record the\n" +"window dimensions (in particular the SIGWINCH handler)."); + +#define _CURSES_RESIZETERM_METHODDEF \ + {"resizeterm", (PyCFunction)(void(*)(void))_curses_resizeterm, METH_FASTCALL, _curses_resizeterm__doc__}, + +static PyObject * +_curses_resizeterm_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_resizeterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_CheckPositional("resizeterm", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + nlines = _PyLong_AsInt(args[0]); + if (nlines == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + ncols = _PyLong_AsInt(args[1]); + if (ncols == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_resizeterm_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_RESIZETERM) */ + +#if defined(HAVE_CURSES_RESIZE_TERM) + +PyDoc_STRVAR(_curses_resize_term__doc__, +"resize_term($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Backend function used by resizeterm(), performing most of the work.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +"\n" +"When resizing the windows, resize_term() blank-fills the areas that are\n" +"extended. The calling application should fill in these areas with appropriate\n" +"data. The resize_term() function attempts to resize all windows. However,\n" +"due to the calling convention of pads, it is not possible to resize these\n" +"without additional interaction with the application."); + +#define _CURSES_RESIZE_TERM_METHODDEF \ + {"resize_term", (PyCFunction)(void(*)(void))_curses_resize_term, METH_FASTCALL, _curses_resize_term__doc__}, + +static PyObject * +_curses_resize_term_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_resize_term(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_CheckPositional("resize_term", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + nlines = _PyLong_AsInt(args[0]); + if (nlines == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + ncols = _PyLong_AsInt(args[1]); + if (ncols == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_resize_term_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_RESIZE_TERM) */ + +PyDoc_STRVAR(_curses_savetty__doc__, +"savetty($module, /)\n" +"--\n" +"\n" +"Save terminal mode."); + +#define _CURSES_SAVETTY_METHODDEF \ + {"savetty", (PyCFunction)_curses_savetty, METH_NOARGS, _curses_savetty__doc__}, + +static PyObject * +_curses_savetty_impl(PyObject *module); + +static PyObject * +_curses_savetty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_savetty_impl(module); +} + +#if defined(getsyx) + +PyDoc_STRVAR(_curses_setsyx__doc__, +"setsyx($module, y, x, /)\n" +"--\n" +"\n" +"Set the virtual screen cursor.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"If y and x are both -1, then leaveok is set."); + +#define _CURSES_SETSYX_METHODDEF \ + {"setsyx", (PyCFunction)(void(*)(void))_curses_setsyx, METH_FASTCALL, _curses_setsyx__doc__}, + +static PyObject * +_curses_setsyx_impl(PyObject *module, int y, int x); + +static PyObject * +_curses_setsyx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + + if (!_PyArg_CheckPositional("setsyx", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + y = _PyLong_AsInt(args[0]); + if (y == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + x = _PyLong_AsInt(args[1]); + if (x == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_setsyx_impl(module, y, x); + +exit: + return return_value; +} + +#endif /* defined(getsyx) */ + +PyDoc_STRVAR(_curses_start_color__doc__, +"start_color($module, /)\n" +"--\n" +"\n" +"Initializes eight basic colors and global variables COLORS and COLOR_PAIRS.\n" +"\n" +"Must be called if the programmer wants to use colors, and before any other\n" +"color manipulation routine is called. It is good practice to call this\n" +"routine right after initscr().\n" +"\n" +"It also restores the colors on the terminal to the values they had when the\n" +"terminal was just turned on."); + +#define _CURSES_START_COLOR_METHODDEF \ + {"start_color", (PyCFunction)_curses_start_color, METH_NOARGS, _curses_start_color__doc__}, + +static PyObject * +_curses_start_color_impl(PyObject *module); + +static PyObject * +_curses_start_color(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_start_color_impl(module); +} + +PyDoc_STRVAR(_curses_termattrs__doc__, +"termattrs($module, /)\n" +"--\n" +"\n" +"Return a logical OR of all video attributes supported by the terminal."); + +#define _CURSES_TERMATTRS_METHODDEF \ + {"termattrs", (PyCFunction)_curses_termattrs, METH_NOARGS, _curses_termattrs__doc__}, + +static PyObject * +_curses_termattrs_impl(PyObject *module); + +static PyObject * +_curses_termattrs(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_termattrs_impl(module); +} + +PyDoc_STRVAR(_curses_termname__doc__, +"termname($module, /)\n" +"--\n" +"\n" +"Return the value of the environment variable TERM, truncated to 14 characters."); + +#define _CURSES_TERMNAME_METHODDEF \ + {"termname", (PyCFunction)_curses_termname, METH_NOARGS, _curses_termname__doc__}, + +static PyObject * +_curses_termname_impl(PyObject *module); + +static PyObject * +_curses_termname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_termname_impl(module); +} + +PyDoc_STRVAR(_curses_tigetflag__doc__, +"tigetflag($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the Boolean capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"The value -1 is returned if capname is not a Boolean capability, or 0 if\n" +"it is canceled or absent from the terminal description."); + +#define _CURSES_TIGETFLAG_METHODDEF \ + {"tigetflag", (PyCFunction)_curses_tigetflag, METH_O, _curses_tigetflag__doc__}, + +static PyObject * +_curses_tigetflag_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetflag(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("tigetflag", "argument", "str", arg); + goto exit; + } + Py_ssize_t capname_length; + capname = PyUnicode_AsUTF8AndSize(arg, &capname_length); + if (capname == NULL) { + goto exit; + } + if (strlen(capname) != (size_t)capname_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _curses_tigetflag_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tigetnum__doc__, +"tigetnum($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the numeric capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"The value -2 is returned if capname is not a numeric capability, or -1 if\n" +"it is canceled or absent from the terminal description."); + +#define _CURSES_TIGETNUM_METHODDEF \ + {"tigetnum", (PyCFunction)_curses_tigetnum, METH_O, _curses_tigetnum__doc__}, + +static PyObject * +_curses_tigetnum_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetnum(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("tigetnum", "argument", "str", arg); + goto exit; + } + Py_ssize_t capname_length; + capname = PyUnicode_AsUTF8AndSize(arg, &capname_length); + if (capname == NULL) { + goto exit; + } + if (strlen(capname) != (size_t)capname_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _curses_tigetnum_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tigetstr__doc__, +"tigetstr($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the string capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"None is returned if capname is not a string capability, or is canceled or\n" +"absent from the terminal description."); + +#define _CURSES_TIGETSTR_METHODDEF \ + {"tigetstr", (PyCFunction)_curses_tigetstr, METH_O, _curses_tigetstr__doc__}, + +static PyObject * +_curses_tigetstr_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetstr(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("tigetstr", "argument", "str", arg); + goto exit; + } + Py_ssize_t capname_length; + capname = PyUnicode_AsUTF8AndSize(arg, &capname_length); + if (capname == NULL) { + goto exit; + } + if (strlen(capname) != (size_t)capname_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _curses_tigetstr_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tparm__doc__, +"tparm($module, str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0,\n" +" i9=0, /)\n" +"--\n" +"\n" +"Instantiate the specified byte string with the supplied parameters.\n" +"\n" +" str\n" +" Parameterized byte string obtained from the terminfo database."); + +#define _CURSES_TPARM_METHODDEF \ + {"tparm", (PyCFunction)(void(*)(void))_curses_tparm, METH_FASTCALL, _curses_tparm__doc__}, + +static PyObject * +_curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, + int i4, int i5, int i6, int i7, int i8, int i9); + +static PyObject * +_curses_tparm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *str; + int i1 = 0; + int i2 = 0; + int i3 = 0; + int i4 = 0; + int i5 = 0; + int i6 = 0; + int i7 = 0; + int i8 = 0; + int i9 = 0; + + if (!_PyArg_ParseStack(args, nargs, "y|iiiiiiiii:tparm", + &str, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9)) { + goto exit; + } + return_value = _curses_tparm_impl(module, str, i1, i2, i3, i4, i5, i6, i7, i8, i9); + +exit: + return return_value; +} + +#if defined(HAVE_CURSES_TYPEAHEAD) + +PyDoc_STRVAR(_curses_typeahead__doc__, +"typeahead($module, fd, /)\n" +"--\n" +"\n" +"Specify that the file descriptor fd be used for typeahead checking.\n" +"\n" +" fd\n" +" File descriptor.\n" +"\n" +"If fd is -1, then no typeahead checking is done."); + +#define _CURSES_TYPEAHEAD_METHODDEF \ + {"typeahead", (PyCFunction)_curses_typeahead, METH_O, _curses_typeahead__doc__}, + +static PyObject * +_curses_typeahead_impl(PyObject *module, int fd); + +static PyObject * +_curses_typeahead(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 = _curses_typeahead_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_TYPEAHEAD) */ + +PyDoc_STRVAR(_curses_unctrl__doc__, +"unctrl($module, ch, /)\n" +"--\n" +"\n" +"Return a string which is a printable representation of the character ch.\n" +"\n" +"Control characters are displayed as a caret followed by the character,\n" +"for example as ^C. Printing characters are left as they are."); + +#define _CURSES_UNCTRL_METHODDEF \ + {"unctrl", (PyCFunction)_curses_unctrl, METH_O, _curses_unctrl__doc__}, + +PyDoc_STRVAR(_curses_ungetch__doc__, +"ungetch($module, ch, /)\n" +"--\n" +"\n" +"Push ch so the next getch() will return it."); + +#define _CURSES_UNGETCH_METHODDEF \ + {"ungetch", (PyCFunction)_curses_ungetch, METH_O, _curses_ungetch__doc__}, + +#if defined(HAVE_NCURSESW) + +PyDoc_STRVAR(_curses_unget_wch__doc__, +"unget_wch($module, ch, /)\n" +"--\n" +"\n" +"Push ch so the next get_wch() will return it."); + +#define _CURSES_UNGET_WCH_METHODDEF \ + {"unget_wch", (PyCFunction)_curses_unget_wch, METH_O, _curses_unget_wch__doc__}, + +#endif /* defined(HAVE_NCURSESW) */ + +#if defined(HAVE_CURSES_USE_ENV) + +PyDoc_STRVAR(_curses_use_env__doc__, +"use_env($module, flag, /)\n" +"--\n" +"\n" +"Use environment variables LINES and COLUMNS.\n" +"\n" +"If used, this function should be called before initscr() or newterm() are\n" +"called.\n" +"\n" +"When flag is False, the values of lines and columns specified in the terminfo\n" +"database will be used, even if environment variables LINES and COLUMNS (used\n" +"by default) are set, or if curses is running in a window (in which case\n" +"default behavior would be to use the window size if LINES and COLUMNS are\n" +"not set)."); + +#define _CURSES_USE_ENV_METHODDEF \ + {"use_env", (PyCFunction)_curses_use_env, METH_O, _curses_use_env__doc__}, + +static PyObject * +_curses_use_env_impl(PyObject *module, int flag); + +static PyObject * +_curses_use_env(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(arg); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_use_env_impl(module, flag); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_USE_ENV) */ + +#if !defined(STRICT_SYSV_CURSES) + +PyDoc_STRVAR(_curses_use_default_colors__doc__, +"use_default_colors($module, /)\n" +"--\n" +"\n" +"Allow use of default values for colors on terminals supporting this feature.\n" +"\n" +"Use this to support transparency in your application. The default color\n" +"is assigned to the color number -1."); + +#define _CURSES_USE_DEFAULT_COLORS_METHODDEF \ + {"use_default_colors", (PyCFunction)_curses_use_default_colors, METH_NOARGS, _curses_use_default_colors__doc__}, + +static PyObject * +_curses_use_default_colors_impl(PyObject *module); + +static PyObject * +_curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_use_default_colors_impl(module); +} + +#endif /* !defined(STRICT_SYSV_CURSES) */ + +#ifndef _CURSES_WINDOW_ENCLOSE_METHODDEF + #define _CURSES_WINDOW_ENCLOSE_METHODDEF +#endif /* !defined(_CURSES_WINDOW_ENCLOSE_METHODDEF) */ + +#ifndef _CURSES_WINDOW_GET_WCH_METHODDEF + #define _CURSES_WINDOW_GET_WCH_METHODDEF +#endif /* !defined(_CURSES_WINDOW_GET_WCH_METHODDEF) */ + +#ifndef _CURSES_WINDOW_NOUTREFRESH_METHODDEF + #define _CURSES_WINDOW_NOUTREFRESH_METHODDEF +#endif /* !defined(_CURSES_WINDOW_NOUTREFRESH_METHODDEF) */ + +#ifndef _CURSES_FILTER_METHODDEF + #define _CURSES_FILTER_METHODDEF +#endif /* !defined(_CURSES_FILTER_METHODDEF) */ + +#ifndef _CURSES_GETSYX_METHODDEF + #define _CURSES_GETSYX_METHODDEF +#endif /* !defined(_CURSES_GETSYX_METHODDEF) */ + +#ifndef _CURSES_GETMOUSE_METHODDEF + #define _CURSES_GETMOUSE_METHODDEF +#endif /* !defined(_CURSES_GETMOUSE_METHODDEF) */ + +#ifndef _CURSES_UNGETMOUSE_METHODDEF + #define _CURSES_UNGETMOUSE_METHODDEF +#endif /* !defined(_CURSES_UNGETMOUSE_METHODDEF) */ + +#ifndef _CURSES_HAS_KEY_METHODDEF + #define _CURSES_HAS_KEY_METHODDEF +#endif /* !defined(_CURSES_HAS_KEY_METHODDEF) */ + +#ifndef _CURSES_IS_TERM_RESIZED_METHODDEF + #define _CURSES_IS_TERM_RESIZED_METHODDEF +#endif /* !defined(_CURSES_IS_TERM_RESIZED_METHODDEF) */ + +#ifndef _CURSES_MOUSEINTERVAL_METHODDEF + #define _CURSES_MOUSEINTERVAL_METHODDEF +#endif /* !defined(_CURSES_MOUSEINTERVAL_METHODDEF) */ + +#ifndef _CURSES_MOUSEMASK_METHODDEF + #define _CURSES_MOUSEMASK_METHODDEF +#endif /* !defined(_CURSES_MOUSEMASK_METHODDEF) */ + +#ifndef _CURSES_UPDATE_LINES_COLS_METHODDEF + #define _CURSES_UPDATE_LINES_COLS_METHODDEF +#endif /* !defined(_CURSES_UPDATE_LINES_COLS_METHODDEF) */ + +#ifndef _CURSES_RESIZETERM_METHODDEF + #define _CURSES_RESIZETERM_METHODDEF +#endif /* !defined(_CURSES_RESIZETERM_METHODDEF) */ + +#ifndef _CURSES_RESIZE_TERM_METHODDEF + #define _CURSES_RESIZE_TERM_METHODDEF +#endif /* !defined(_CURSES_RESIZE_TERM_METHODDEF) */ + +#ifndef _CURSES_SETSYX_METHODDEF + #define _CURSES_SETSYX_METHODDEF +#endif /* !defined(_CURSES_SETSYX_METHODDEF) */ + +#ifndef _CURSES_TYPEAHEAD_METHODDEF + #define _CURSES_TYPEAHEAD_METHODDEF +#endif /* !defined(_CURSES_TYPEAHEAD_METHODDEF) */ + +#ifndef _CURSES_UNGET_WCH_METHODDEF + #define _CURSES_UNGET_WCH_METHODDEF +#endif /* !defined(_CURSES_UNGET_WCH_METHODDEF) */ + +#ifndef _CURSES_USE_ENV_METHODDEF + #define _CURSES_USE_ENV_METHODDEF +#endif /* !defined(_CURSES_USE_ENV_METHODDEF) */ + +#ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF + #define _CURSES_USE_DEFAULT_COLORS_METHODDEF +#endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ +/*[clinic end generated code: output=c5267f2ffe238810 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_datetimemodule.c.h b/python/Modules/clinic/_datetimemodule.c.h new file mode 100755 index 0000000..447036c --- /dev/null +++ b/python/Modules/clinic/_datetimemodule.c.h @@ -0,0 +1,58 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(datetime_date_fromtimestamp__doc__, +"fromtimestamp($type, timestamp, /)\n" +"--\n" +"\n" +"Create a date from a POSIX timestamp.\n" +"\n" +"The timestamp is a number, e.g. created via time.time(), that is interpreted\n" +"as local time."); + +#define DATETIME_DATE_FROMTIMESTAMP_METHODDEF \ + {"fromtimestamp", (PyCFunction)datetime_date_fromtimestamp, METH_O|METH_CLASS, datetime_date_fromtimestamp__doc__}, + +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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + 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; +} +/*[clinic end generated code: output=aae916ab728ca85b input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_dbmmodule.c.h b/python/Modules/clinic/_dbmmodule.c.h new file mode 100755 index 0000000..a7d7350 --- /dev/null +++ b/python/Modules/clinic/_dbmmodule.c.h @@ -0,0 +1,180 @@ +/*[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 \ + {"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 \ + {"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; + + if (!_PyArg_CheckPositional("open", nargs, 1, 3)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("open", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + filename = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("open", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t flags_length; + flags = PyUnicode_AsUTF8AndSize(args[1], &flags_length); + if (flags == NULL) { + goto exit; + } + if (strlen(flags) != (size_t)flags_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + 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; + } +skip_optional: + return_value = dbmopen_impl(module, filename, flags, mode); + +exit: + return return_value; +} +/*[clinic end generated code: output=7ced103488cbca7a input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_elementtree.c.h b/python/Modules/clinic/_elementtree.c.h new file mode 100755 index 0000000..0bc4bb5 --- /dev/null +++ b/python/Modules/clinic/_elementtree.c.h @@ -0,0 +1,972 @@ +/*[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; + } + 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; + + if (!PyDict_Check(arg)) { + _PyArg_BadArgument("__deepcopy__", "argument", "dict", arg); + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + path = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + default_value = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + 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_getchildren__doc__, +"getchildren($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_GETCHILDREN_METHODDEF \ + {"getchildren", (PyCFunction)_elementtree_Element_getchildren, METH_NOARGS, _elementtree_Element_getchildren__doc__}, + +static PyObject * +_elementtree_Element_getchildren_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_getchildren(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_getchildren_impl(self); +} + +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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + 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_getiterator__doc__, +"getiterator($self, /, tag=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_GETITERATOR_METHODDEF \ + {"getiterator", (PyCFunction)(void(*)(void))_elementtree_Element_getiterator, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_getiterator__doc__}, + +static PyObject * +_elementtree_Element_getiterator_impl(ElementObject *self, PyObject *tag); + +static PyObject * +_elementtree_Element_getiterator(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, "getiterator", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *tag = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + tag = args[0]; +skip_optional_pos: + return_value = _elementtree_Element_getiterator_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; + + if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + index = ival; + } + if (!PyObject_TypeCheck(args[1], &Element_Type)) { + _PyArg_BadArgument("insert", "argument 2", (&Element_Type)->tp_name, args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("makeelement", nargs, 2, 2)) { + goto exit; + } + tag = args[0]; + 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; + + if (!PyObject_TypeCheck(arg, &Element_Type)) { + _PyArg_BadArgument("remove", "argument", (&Element_Type)->tp_name, arg); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("set", nargs, 2, 2)) { + 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, + 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 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]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + PyObject *element_factory = Py_None; + PyObject *comment_factory = Py_None; + 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; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + element_factory = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + comment_factory = fastargs[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[2]) { + pi_factory = fastargs[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + insert_comments = PyObject_IsTrue(fastargs[3]); + if (insert_comments < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + insert_pis = PyObject_IsTrue(fastargs[4]); + if (insert_pis < 0) { + goto exit; + } +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; +} + +PyDoc_STRVAR(_elementtree__set_factories__doc__, +"_set_factories($module, comment_factory, pi_factory, /)\n" +"--\n" +"\n" +"Change the factories used to create comments and processing instructions.\n" +"\n" +"For internal use only."); + +#define _ELEMENTTREE__SET_FACTORIES_METHODDEF \ + {"_set_factories", (PyCFunction)(void(*)(void))_elementtree__set_factories, METH_FASTCALL, _elementtree__set_factories__doc__}, + +static PyObject * +_elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, + PyObject *pi_factory); + +static PyObject * +_elementtree__set_factories(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *comment_factory; + PyObject *pi_factory; + + if (!_PyArg_CheckPositional("_set_factories", nargs, 2, 2)) { + goto exit; + } + comment_factory = args[0]; + pi_factory = args[1]; + return_value = _elementtree__set_factories_impl(module, comment_factory, pi_factory); + +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_comment__doc__, +"comment($self, text, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_COMMENT_METHODDEF \ + {"comment", (PyCFunction)_elementtree_TreeBuilder_comment, METH_O, _elementtree_TreeBuilder_comment__doc__}, + +PyDoc_STRVAR(_elementtree_TreeBuilder_pi__doc__, +"pi($self, target, text=None, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_PI_METHODDEF \ + {"pi", (PyCFunction)(void(*)(void))_elementtree_TreeBuilder_pi, METH_FASTCALL, _elementtree_TreeBuilder_pi__doc__}, + +static PyObject * +_elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target, + PyObject *text); + +static PyObject * +_elementtree_TreeBuilder_pi(TreeBuilderObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *target; + PyObject *text = Py_None; + + if (!_PyArg_CheckPositional("pi", nargs, 1, 2)) { + goto exit; + } + target = args[0]; + if (nargs < 2) { + goto skip_optional; + } + text = args[1]; +skip_optional: + return_value = _elementtree_TreeBuilder_pi_impl(self, target, text); + +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__, +"start($self, tag, attrs=None, /)\n" +"--\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; + PyObject *attrs = Py_None; + + if (!_PyArg_CheckPositional("start", nargs, 1, 2)) { + goto exit; + } + tag = args[0]; + if (nargs < 2) { + goto skip_optional; + } + attrs = args[1]; +skip_optional: + 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 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 0, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[0]) { + target = fastargs[0]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[1] == Py_None) { + encoding = NULL; + } + else if (PyUnicode_Check(fastargs[1])) { + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("XMLParser", "argument 'encoding'", "str or None", fastargs[1]); + goto exit; + } +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 \ + {"_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; + + if (!_PyArg_CheckPositional("_setevents", nargs, 1, 2)) { + 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; +} +/*[clinic end generated code: output=1443ed7bb9f9e03e input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_gdbmmodule.c.h b/python/Modules/clinic/_gdbmmodule.c.h new file mode 100755 index 0000000..aa37a24 --- /dev/null +++ b/python/Modules/clinic/_gdbmmodule.c.h @@ -0,0 +1,301 @@ +/*[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; + + if (!_PyArg_CheckPositional("get", nargs, 1, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("setdefault", nargs, 1, 2)) { + 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" +" while k != 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 \ + {"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; + + if (!_PyArg_CheckPositional("open", nargs, 1, 3)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("open", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + filename = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("open", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t flags_length; + flags = PyUnicode_AsUTF8AndSize(args[1], &flags_length); + if (flags == NULL) { + goto exit; + } + if (strlen(flags) != (size_t)flags_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + 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; + } +skip_optional: + return_value = dbmopen_impl(module, filename, flags, mode); + +exit: + return return_value; +} +/*[clinic end generated code: output=2766471b2fa1a816 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_hashopenssl.c.h b/python/Modules/clinic/_hashopenssl.c.h new file mode 100755 index 0000000..9aaea47 --- /dev/null +++ b/python/Modules/clinic/_hashopenssl.c.h @@ -0,0 +1,626 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(EVP_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define EVP_COPY_METHODDEF \ + {"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__}, + +static PyObject * +EVP_copy_impl(EVPobject *self); + +static PyObject * +EVP_copy(EVPobject *self, PyObject *Py_UNUSED(ignored)) +{ + return EVP_copy_impl(self); +} + +PyDoc_STRVAR(EVP_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define EVP_DIGEST_METHODDEF \ + {"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__}, + +static PyObject * +EVP_digest_impl(EVPobject *self); + +static PyObject * +EVP_digest(EVPobject *self, PyObject *Py_UNUSED(ignored)) +{ + return EVP_digest_impl(self); +} + +PyDoc_STRVAR(EVP_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define EVP_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__}, + +static PyObject * +EVP_hexdigest_impl(EVPobject *self); + +static PyObject * +EVP_hexdigest(EVPobject *self, PyObject *Py_UNUSED(ignored)) +{ + return EVP_hexdigest_impl(self); +} + +PyDoc_STRVAR(EVP_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define EVP_UPDATE_METHODDEF \ + {"update", (PyCFunction)EVP_update, METH_O, EVP_update__doc__}, + +PyDoc_STRVAR(EVP_new__doc__, +"new($module, /, name, string=b\'\')\n" +"--\n" +"\n" +"Return a new hash object using the named algorithm.\n" +"\n" +"An optional string argument may be provided and will be\n" +"automatically hashed.\n" +"\n" +"The MD5 and SHA1 algorithms are always supported."); + +#define EVP_NEW_METHODDEF \ + {"new", (PyCFunction)(void(*)(void))EVP_new, METH_FASTCALL|METH_KEYWORDS, EVP_new__doc__}, + +static PyObject * +EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj); + +static PyObject * +EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "new", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *name_obj; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + name_obj = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[1]; +skip_optional_pos: + return_value = EVP_new_impl(module, name_obj, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_md5__doc__, +"openssl_md5($module, /, string=b\'\')\n" +"--\n" +"\n" +"Returns a md5 hash object; optionally initialized with a string"); + +#define _HASHLIB_OPENSSL_MD5_METHODDEF \ + {"openssl_md5", (PyCFunction)(void(*)(void))_hashlib_openssl_md5, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_md5__doc__}, + +static PyObject * +_hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_md5_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha1__doc__, +"openssl_sha1($module, /, string=b\'\')\n" +"--\n" +"\n" +"Returns a sha1 hash object; optionally initialized with a string"); + +#define _HASHLIB_OPENSSL_SHA1_METHODDEF \ + {"openssl_sha1", (PyCFunction)(void(*)(void))_hashlib_openssl_sha1, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha1__doc__}, + +static PyObject * +_hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha1_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha224__doc__, +"openssl_sha224($module, /, string=b\'\')\n" +"--\n" +"\n" +"Returns a sha224 hash object; optionally initialized with a string"); + +#define _HASHLIB_OPENSSL_SHA224_METHODDEF \ + {"openssl_sha224", (PyCFunction)(void(*)(void))_hashlib_openssl_sha224, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha224__doc__}, + +static PyObject * +_hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha224_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha256__doc__, +"openssl_sha256($module, /, string=b\'\')\n" +"--\n" +"\n" +"Returns a sha256 hash object; optionally initialized with a string"); + +#define _HASHLIB_OPENSSL_SHA256_METHODDEF \ + {"openssl_sha256", (PyCFunction)(void(*)(void))_hashlib_openssl_sha256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha256__doc__}, + +static PyObject * +_hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha256_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha384__doc__, +"openssl_sha384($module, /, string=b\'\')\n" +"--\n" +"\n" +"Returns a sha384 hash object; optionally initialized with a string"); + +#define _HASHLIB_OPENSSL_SHA384_METHODDEF \ + {"openssl_sha384", (PyCFunction)(void(*)(void))_hashlib_openssl_sha384, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha384__doc__}, + +static PyObject * +_hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha384_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_openssl_sha512__doc__, +"openssl_sha512($module, /, string=b\'\')\n" +"--\n" +"\n" +"Returns a sha512 hash object; optionally initialized with a string"); + +#define _HASHLIB_OPENSSL_SHA512_METHODDEF \ + {"openssl_sha512", (PyCFunction)(void(*)(void))_hashlib_openssl_sha512, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha512__doc__}, + +static PyObject * +_hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj); + +static PyObject * +_hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *data_obj = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + data_obj = args[0]; +skip_optional_pos: + return_value = _hashlib_openssl_sha512_impl(module, data_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(pbkdf2_hmac__doc__, +"pbkdf2_hmac($module, /, hash_name, password, salt, iterations,\n" +" dklen=None)\n" +"--\n" +"\n" +"Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as pseudorandom function."); + +#define PBKDF2_HMAC_METHODDEF \ + {"pbkdf2_hmac", (PyCFunction)(void(*)(void))pbkdf2_hmac, METH_FASTCALL|METH_KEYWORDS, pbkdf2_hmac__doc__}, + +static PyObject * +pbkdf2_hmac_impl(PyObject *module, const char *hash_name, + Py_buffer *password, Py_buffer *salt, long iterations, + PyObject *dklen_obj); + +static PyObject * +pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"hash_name", "password", "salt", "iterations", "dklen", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "pbkdf2_hmac", 0}; + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; + const char *hash_name; + Py_buffer password = {NULL, NULL}; + Py_buffer salt = {NULL, NULL}; + long iterations; + PyObject *dklen_obj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 5, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("pbkdf2_hmac", "argument 'hash_name'", "str", args[0]); + goto exit; + } + Py_ssize_t hash_name_length; + hash_name = PyUnicode_AsUTF8AndSize(args[0], &hash_name_length); + if (hash_name == NULL) { + goto exit; + } + if (strlen(hash_name) != (size_t)hash_name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (PyObject_GetBuffer(args[1], &password, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&password, 'C')) { + _PyArg_BadArgument("pbkdf2_hmac", "argument 'password'", "contiguous buffer", args[1]); + goto exit; + } + if (PyObject_GetBuffer(args[2], &salt, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&salt, 'C')) { + _PyArg_BadArgument("pbkdf2_hmac", "argument 'salt'", "contiguous buffer", args[2]); + goto exit; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + iterations = PyLong_AsLong(args[3]); + if (iterations == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + dklen_obj = args[4]; +skip_optional_pos: + return_value = pbkdf2_hmac_impl(module, hash_name, &password, &salt, iterations, dklen_obj); + +exit: + /* Cleanup for password */ + if (password.obj) { + PyBuffer_Release(&password); + } + /* Cleanup for salt */ + if (salt.obj) { + PyBuffer_Release(&salt); + } + + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &password, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&password, 'C')) { + _PyArg_BadArgument("scrypt", "argument 'password'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + if (PyObject_GetBuffer(args[1], &salt, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&salt, 'C')) { + _PyArg_BadArgument("scrypt", "argument 'salt'", "contiguous buffer", args[1]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (!PyLong_Check(args[2])) { + _PyArg_BadArgument("scrypt", "argument 'n'", "int", args[2]); + goto exit; + } + n_obj = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!PyLong_Check(args[3])) { + _PyArg_BadArgument("scrypt", "argument 'r'", "int", args[3]); + goto exit; + } + r_obj = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[4]) { + if (!PyLong_Check(args[4])) { + _PyArg_BadArgument("scrypt", "argument 'p'", "int", args[4]); + goto exit; + } + p_obj = args[4]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[5]) { + if (PyFloat_Check(args[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + maxmem = PyLong_AsLong(args[5]); + if (maxmem == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + dklen = PyLong_AsLong(args[6]); + if (dklen == -1 && PyErr_Occurred()) { + 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)) */ + +PyDoc_STRVAR(_hashlib_hmac_digest__doc__, +"hmac_digest($module, /, key, msg, digest)\n" +"--\n" +"\n" +"Single-shot HMAC."); + +#define _HASHLIB_HMAC_DIGEST_METHODDEF \ + {"hmac_digest", (PyCFunction)(void(*)(void))_hashlib_hmac_digest, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_digest__doc__}, + +static PyObject * +_hashlib_hmac_digest_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, + const char *digest); + +static PyObject * +_hashlib_hmac_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + 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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&key, 'C')) { + _PyArg_BadArgument("hmac_digest", "argument 'key'", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &msg, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&msg, 'C')) { + _PyArg_BadArgument("hmac_digest", "argument 'msg'", "contiguous buffer", args[1]); + goto exit; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("hmac_digest", "argument 'digest'", "str", args[2]); + goto exit; + } + Py_ssize_t digest_length; + digest = PyUnicode_AsUTF8AndSize(args[2], &digest_length); + if (digest == NULL) { + goto exit; + } + if (strlen(digest) != (size_t)digest_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _hashlib_hmac_digest_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; +} + +#ifndef _HASHLIB_SCRYPT_METHODDEF + #define _HASHLIB_SCRYPT_METHODDEF +#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ +/*[clinic end generated code: output=38c2637f67e9bb79 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_heapqmodule.c.h b/python/Modules/clinic/_heapqmodule.c.h new file mode 100755 index 0000000..5540370 --- /dev/null +++ b/python/Modules/clinic/_heapqmodule.c.h @@ -0,0 +1,172 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_heapq_heappush__doc__, +"heappush($module, heap, item, /)\n" +"--\n" +"\n" +"Push item onto heap, maintaining the heap invariant."); + +#define _HEAPQ_HEAPPUSH_METHODDEF \ + {"heappush", (PyCFunction)(void(*)(void))_heapq_heappush, METH_FASTCALL, _heapq_heappush__doc__}, + +static PyObject * +_heapq_heappush_impl(PyObject *module, PyObject *heap, PyObject *item); + +static PyObject * +_heapq_heappush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *heap; + PyObject *item; + + if (!_PyArg_CheckPositional("heappush", nargs, 2, 2)) { + goto exit; + } + heap = args[0]; + item = args[1]; + return_value = _heapq_heappush_impl(module, heap, item); + +exit: + return return_value; +} + +PyDoc_STRVAR(_heapq_heappop__doc__, +"heappop($module, heap, /)\n" +"--\n" +"\n" +"Pop the smallest item off the heap, maintaining the heap invariant."); + +#define _HEAPQ_HEAPPOP_METHODDEF \ + {"heappop", (PyCFunction)_heapq_heappop, METH_O, _heapq_heappop__doc__}, + +PyDoc_STRVAR(_heapq_heapreplace__doc__, +"heapreplace($module, heap, item, /)\n" +"--\n" +"\n" +"Pop and return the current smallest value, and add the new item.\n" +"\n" +"This is more efficient than heappop() followed by heappush(), and can be\n" +"more appropriate when using a fixed-size heap. Note that the value\n" +"returned may be larger than item! That constrains reasonable uses of\n" +"this routine unless written as part of a conditional replacement:\n" +"\n" +" if item > heap[0]:\n" +" item = heapreplace(heap, item)"); + +#define _HEAPQ_HEAPREPLACE_METHODDEF \ + {"heapreplace", (PyCFunction)(void(*)(void))_heapq_heapreplace, METH_FASTCALL, _heapq_heapreplace__doc__}, + +static PyObject * +_heapq_heapreplace_impl(PyObject *module, PyObject *heap, PyObject *item); + +static PyObject * +_heapq_heapreplace(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *heap; + PyObject *item; + + if (!_PyArg_CheckPositional("heapreplace", nargs, 2, 2)) { + goto exit; + } + heap = args[0]; + item = args[1]; + return_value = _heapq_heapreplace_impl(module, heap, item); + +exit: + return return_value; +} + +PyDoc_STRVAR(_heapq_heappushpop__doc__, +"heappushpop($module, heap, item, /)\n" +"--\n" +"\n" +"Push item on the heap, then pop and return the smallest item from the heap.\n" +"\n" +"The combined action runs more efficiently than heappush() followed by\n" +"a separate call to heappop()."); + +#define _HEAPQ_HEAPPUSHPOP_METHODDEF \ + {"heappushpop", (PyCFunction)(void(*)(void))_heapq_heappushpop, METH_FASTCALL, _heapq_heappushpop__doc__}, + +static PyObject * +_heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item); + +static PyObject * +_heapq_heappushpop(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *heap; + PyObject *item; + + if (!_PyArg_CheckPositional("heappushpop", nargs, 2, 2)) { + goto exit; + } + heap = args[0]; + item = args[1]; + return_value = _heapq_heappushpop_impl(module, heap, item); + +exit: + return return_value; +} + +PyDoc_STRVAR(_heapq_heapify__doc__, +"heapify($module, heap, /)\n" +"--\n" +"\n" +"Transform list into a heap, in-place, in O(len(heap)) time."); + +#define _HEAPQ_HEAPIFY_METHODDEF \ + {"heapify", (PyCFunction)_heapq_heapify, METH_O, _heapq_heapify__doc__}, + +PyDoc_STRVAR(_heapq__heappop_max__doc__, +"_heappop_max($module, heap, /)\n" +"--\n" +"\n" +"Maxheap variant of heappop."); + +#define _HEAPQ__HEAPPOP_MAX_METHODDEF \ + {"_heappop_max", (PyCFunction)_heapq__heappop_max, METH_O, _heapq__heappop_max__doc__}, + +PyDoc_STRVAR(_heapq__heapreplace_max__doc__, +"_heapreplace_max($module, heap, item, /)\n" +"--\n" +"\n" +"Maxheap variant of heapreplace."); + +#define _HEAPQ__HEAPREPLACE_MAX_METHODDEF \ + {"_heapreplace_max", (PyCFunction)(void(*)(void))_heapq__heapreplace_max, METH_FASTCALL, _heapq__heapreplace_max__doc__}, + +static PyObject * +_heapq__heapreplace_max_impl(PyObject *module, PyObject *heap, + PyObject *item); + +static PyObject * +_heapq__heapreplace_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *heap; + PyObject *item; + + if (!_PyArg_CheckPositional("_heapreplace_max", nargs, 2, 2)) { + goto exit; + } + heap = args[0]; + item = args[1]; + return_value = _heapq__heapreplace_max_impl(module, heap, item); + +exit: + return return_value; +} + +PyDoc_STRVAR(_heapq__heapify_max__doc__, +"_heapify_max($module, heap, /)\n" +"--\n" +"\n" +"Maxheap variant of heapify."); + +#define _HEAPQ__HEAPIFY_MAX_METHODDEF \ + {"_heapify_max", (PyCFunction)_heapq__heapify_max, METH_O, _heapq__heapify_max__doc__}, +/*[clinic end generated code: output=37ef2a3319971c8d input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_lzmamodule.c.h b/python/Modules/clinic/_lzmamodule.c.h new file mode 100755 index 0000000..82ef4d5 --- /dev/null +++ b/python/Modules/clinic/_lzmamodule.c.h @@ -0,0 +1,337 @@ +/*[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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + 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; + } + 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}; + 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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 3, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + if (PyFloat_Check(fastargs[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + format = _PyLong_AsInt(fastargs[0]); + if (format == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[1]) { + memlimit = fastargs[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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}; + + 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 \ + {"_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}; + + if (!_PyArg_CheckPositional("_decode_filter_properties", nargs, 2, 2)) { + goto exit; + } + if (!lzma_vli_converter(args[0], &filter_id)) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &encoded_props, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&encoded_props, 'C')) { + _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; +} +/*[clinic end generated code: output=f7477a10e86a717d input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_opcode.c.h b/python/Modules/clinic/_opcode.c.h new file mode 100755 index 0000000..777701f --- /dev/null +++ b/python/Modules/clinic/_opcode.c.h @@ -0,0 +1,64 @@ +/*[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 \ + {"stack_effect", (PyCFunction)(void(*)(void))_opcode_stack_effect, METH_FASTCALL|METH_KEYWORDS, _opcode_stack_effect__doc__}, + +static int +_opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, + PyObject *jump); + +static PyObject * +_opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + 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; + PyObject *jump = Py_None; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + opcode = _PyLong_AsInt(args[0]); + if (opcode == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional_posonly; + } + noptargs--; + oparg = args[1]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_kwonly; + } + 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; +} +/*[clinic end generated code: output=7bc08f2835b2cf89 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_operator.c.h b/python/Modules/clinic/_operator.c.h new file mode 100755 index 0000000..f9e353d --- /dev/null +++ b/python/Modules/clinic/_operator.c.h @@ -0,0 +1,1494 @@ +/*[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; + + if (!_PyArg_CheckPositional("add", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("sub", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("mul", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("matmul", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("floordiv", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("truediv", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("mod", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("lshift", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("rshift", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("and_", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("xor", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("or_", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("iadd", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("isub", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("imul", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("imatmul", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ifloordiv", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("itruediv", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("imod", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ilshift", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("irshift", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("iand", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ixor", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ior", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("concat", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("iconcat", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("contains", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("indexOf", nargs, 2, 2)) { + 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 the number of times b occurs in a."); + +#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; + + if (!_PyArg_CheckPositional("countOf", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("getitem", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("setitem", nargs, 3, 3)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("delitem", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("eq", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ne", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("lt", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("le", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("gt", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ge", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ipow", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("is_", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("is_not", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("length_hint", nargs, 1, 2)) { + goto exit; + } + obj = args[0]; + if (nargs < 2) { + goto skip_optional; + } + 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; + } + 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 \ + {"_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; + + if (!_PyArg_CheckPositional("_compare_digest", nargs, 2, 2)) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = _operator__compare_digest_impl(module, a, b); + +exit: + return return_value; +} +/*[clinic end generated code: output=e7ed71a8c475a901 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_pickle.c.h b/python/Modules/clinic/_pickle.c.h new file mode 100755 index 0000000..0457a43 --- /dev/null +++ b/python/Modules/clinic/_pickle.c.h @@ -0,0 +1,839 @@ +/*[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" +"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" +"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" +"serialized into *file* as part of the pickle stream.\n" +"\n" +"If *buffer_callback* is not None, then it can be called any number\n" +"of times with a buffer view. If the callback returns a false value\n" +"(such as None), the given buffer is out-of-band; otherwise the\n" +"buffer is serialized in-band, i.e. inside the pickle stream.\n" +"\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, + PyObject *protocol, int fix_imports, + PyObject *buffer_callback); + +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 *protocol = Py_None; + 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; + } + file = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[1]) { + protocol = fastargs[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + fix_imports = PyObject_IsTrue(fastargs[2]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("find_class", nargs, 2, 2)) { + 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__, +"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, + const char *errors, PyObject *buffers); + +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 *buffers = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + file = fastargs[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + fix_imports = PyObject_IsTrue(fastargs[1]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[2]) { + if (!PyUnicode_Check(fastargs[2])) { + _PyArg_BadArgument("Unpickler", "argument 'encoding'", "str", fastargs[2]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[2], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + if (!PyUnicode_Check(fastargs[3])) { + _PyArg_BadArgument("Unpickler", "argument 'errors'", "str", fastargs[3]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(fastargs[3], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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__, +"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" +"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" +"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 \ + {"dump", (PyCFunction)(void(*)(void))_pickle_dump, METH_FASTCALL|METH_KEYWORDS, _pickle_dump__doc__}, + +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 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 *protocol = Py_None; + 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; + } + obj = args[0]; + file = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + protocol = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + fix_imports = PyObject_IsTrue(args[3]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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__, +"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" +"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" +"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 \ + {"dumps", (PyCFunction)(void(*)(void))_pickle_dumps, METH_FASTCALL|METH_KEYWORDS, _pickle_dumps__doc__}, + +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 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 *protocol = Py_None; + 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; + } + obj = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + protocol = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[2]) { + fix_imports = PyObject_IsTrue(args[2]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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" +" 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 \ + {"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, + 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 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 *buffers = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + file = args[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + fix_imports = PyObject_IsTrue(args[1]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("load", "argument 'encoding'", "str", args[2]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[2], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("load", "argument 'errors'", "str", args[3]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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__, +"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 \ + {"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, + 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 const char * const _keywords[] = {"data", "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 *buffers = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + data = args[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + fix_imports = PyObject_IsTrue(args[1]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("loads", "argument 'encoding'", "str", args[2]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[2], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("loads", "argument 'errors'", "str", args[3]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + buffers = args[4]; +skip_optional_kwonly: + return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors, buffers); + +exit: + return return_value; +} +/*[clinic end generated code: output=e2506823be1960c5 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_queuemodule.c.h b/python/Modules/clinic/_queuemodule.c.h new file mode 100755 index 0000000..c25eacf --- /dev/null +++ b/python/Modules/clinic/_queuemodule.c.h @@ -0,0 +1,253 @@ +/*[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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + item = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + block = PyObject_IsTrue(args[1]); + if (block < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "put_nowait", 0}; + PyObject *argsbuf[1]; + PyObject *item; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + block = PyObject_IsTrue(args[0]); + if (block < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; +} +/*[clinic end generated code: output=b4717e2974cbc909 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_randommodule.c.h b/python/Modules/clinic/_randommodule.c.h new file mode 100755 index 0000000..a467811 --- /dev/null +++ b/python/Modules/clinic/_randommodule.c.h @@ -0,0 +1,117 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_random_Random_random__doc__, +"random($self, /)\n" +"--\n" +"\n" +"random() -> x in the interval [0, 1)."); + +#define _RANDOM_RANDOM_RANDOM_METHODDEF \ + {"random", (PyCFunction)_random_Random_random, METH_NOARGS, _random_Random_random__doc__}, + +static PyObject * +_random_Random_random_impl(RandomObject *self); + +static PyObject * +_random_Random_random(RandomObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _random_Random_random_impl(self); +} + +PyDoc_STRVAR(_random_Random_seed__doc__, +"seed($self, n=None, /)\n" +"--\n" +"\n" +"seed([n]) -> None.\n" +"\n" +"Defaults to use urandom and falls back to a combination\n" +"of the current time and the process identifier."); + +#define _RANDOM_RANDOM_SEED_METHODDEF \ + {"seed", (PyCFunction)(void(*)(void))_random_Random_seed, METH_FASTCALL, _random_Random_seed__doc__}, + +static PyObject * +_random_Random_seed_impl(RandomObject *self, PyObject *n); + +static PyObject * +_random_Random_seed(RandomObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *n = Py_None; + + if (!_PyArg_CheckPositional("seed", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + n = args[0]; +skip_optional: + return_value = _random_Random_seed_impl(self, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_random_Random_getstate__doc__, +"getstate($self, /)\n" +"--\n" +"\n" +"getstate() -> tuple containing the current state."); + +#define _RANDOM_RANDOM_GETSTATE_METHODDEF \ + {"getstate", (PyCFunction)_random_Random_getstate, METH_NOARGS, _random_Random_getstate__doc__}, + +static PyObject * +_random_Random_getstate_impl(RandomObject *self); + +static PyObject * +_random_Random_getstate(RandomObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _random_Random_getstate_impl(self); +} + +PyDoc_STRVAR(_random_Random_setstate__doc__, +"setstate($self, state, /)\n" +"--\n" +"\n" +"setstate(state) -> None. Restores generator state."); + +#define _RANDOM_RANDOM_SETSTATE_METHODDEF \ + {"setstate", (PyCFunction)_random_Random_setstate, METH_O, _random_Random_setstate__doc__}, + +PyDoc_STRVAR(_random_Random_getrandbits__doc__, +"getrandbits($self, k, /)\n" +"--\n" +"\n" +"getrandbits(k) -> x. Generates an int with k random bits."); + +#define _RANDOM_RANDOM_GETRANDBITS_METHODDEF \ + {"getrandbits", (PyCFunction)_random_Random_getrandbits, METH_O, _random_Random_getrandbits__doc__}, + +static PyObject * +_random_Random_getrandbits_impl(RandomObject *self, int k); + +static PyObject * +_random_Random_getrandbits(RandomObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int k; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + k = _PyLong_AsInt(arg); + if (k == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _random_Random_getrandbits_impl(self, k); + +exit: + return return_value; +} +/*[clinic end generated code: output=a7feb0c9c8d1b627 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_sre.c.h b/python/Modules/clinic/_sre.c.h new file mode 100755 index 0000000..d398a85 --- /dev/null +++ b/python/Modules/clinic/_sre.c.h @@ -0,0 +1,1210 @@ +/*[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; + } + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + string = args[0]; + 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; + } + { + 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; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + string = args[0]; + 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; + } + { + 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; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + string = args[0]; + 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; + } + { + 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; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + string = args[0]; + 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; + } + { + 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; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + string = args[0]; + 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; + } + { + 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; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + string = args[0]; + 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; + } + { + 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; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + 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; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + repl = args[0]; + string = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } +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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + repl = args[0]; + string = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } +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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + PyObject *argsbuf[6]; + 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; + } + pattern = args[0]; + 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 (!PyList_Check(args[2])) { + _PyArg_BadArgument("compile", "argument 'code'", "list", args[2]); + goto exit; + } + code = 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; + } + groups = ival; + } + if (!PyDict_Check(args[4])) { + _PyArg_BadArgument("compile", "argument 'groupindex'", "dict", args[4]); + goto exit; + } + groupindex = args[4]; + if (!PyTuple_Check(args[5])) { + _PyArg_BadArgument("compile", "argument 'indexgroup'", "tuple", args[5]); + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "expand", 0}; + PyObject *argsbuf[1]; + PyObject *template; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("start", nargs, 0, 1)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("end", nargs, 0, 1)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("span", nargs, 0, 1)) { + 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); +} +/*[clinic end generated code: output=1adeddce58ae284c input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_ssl.c.h b/python/Modules/clinic/_ssl.c.h new file mode 100755 index 0000000..ce8669a --- /dev/null +++ b/python/Modules/clinic/_ssl.c.h @@ -0,0 +1,1485 @@ +/*[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 \ + {"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; + + if (!_PyArg_CheckPositional("getpeercert", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + binary_mode = PyObject_IsTrue(args[0]); + if (binary_mode < 0) { + 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}; + + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { + 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 \ + {"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 _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"; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("get_channel_binding", "argument 'cb_type'", "str", args[0]); + goto exit; + } + Py_ssize_t cb_type_length; + cb_type = PyUnicode_AsUTF8AndSize(args[0], &cb_type_length); + if (cb_type == NULL) { + goto exit; + } + if (strlen(cb_type) != (size_t)cb_type_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + 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; + } + if (!_PyArg_CheckPositional("_SSLContext", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + if (PyFloat_Check(PyTuple_GET_ITEM(args, 0))) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + proto_version = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("set_ciphers", "argument", "str", arg); + goto exit; + } + Py_ssize_t cipherlist_length; + cipherlist = PyUnicode_AsUTF8AndSize(arg, &cipherlist_length); + if (cipherlist == NULL) { + goto exit; + } + if (strlen(cipherlist) != (size_t)cipherlist_length) { + 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}; + + if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { + 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}; + + if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { + 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 \ + {"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 _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 *keyfile = Py_None; + PyObject *password = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + certfile = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + keyfile = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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 \ + {"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 _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; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + cafile = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[1]) { + capath = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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 \ + {"_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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + 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; + } + sock = args[0]; + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + server_side = _PyLong_AsInt(args[1]); + if (server_side == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + hostname_obj = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + owner = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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 \ + {"_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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyObject_TypeCheck(args[0], &PySSLMemoryBIO_Type)) { + _PyArg_BadArgument("_wrap_bio", "argument 'incoming'", (&PySSLMemoryBIO_Type)->tp_name, args[0]); + goto exit; + } + incoming = (PySSLMemoryBIO *)args[0]; + if (!PyObject_TypeCheck(args[1], &PySSLMemoryBIO_Type)) { + _PyArg_BadArgument("_wrap_bio", "argument 'outgoing'", (&PySSLMemoryBIO_Type)->tp_name, args[1]); + goto exit; + } + outgoing = (PySSLMemoryBIO *)args[1]; + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + server_side = _PyLong_AsInt(args[2]); + if (server_side == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[3]) { + hostname_obj = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[4]) { + owner = args[4]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + binary_form = PyObject_IsTrue(args[0]); + if (binary_form < 0) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + len = _PyLong_AsInt(args[0]); + if (len == -1 && PyErr_Occurred()) { + 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}; + + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("RAND_add", nargs, 2, 2)) { + goto exit; + } + if (PyUnicode_Check(args[0])) { + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); + if (ptr == NULL) { + goto exit; + } + PyBuffer_FillInfo(&view, args[0], (void *)ptr, len, 1, 0); + } + else { /* any bytes-like object */ + if (PyObject_GetBuffer(args[0], &view, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&view, 'C')) { + _PyArg_BadArgument("RAND_add", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + entropy = PyFloat_AS_DOUBLE(args[1]); + } + else + { + entropy = PyFloat_AsDouble(args[1]); + if (entropy == -1.0 && PyErr_Occurred()) { + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("txt2obj", "argument 'txt'", "str", args[0]); + goto exit; + } + Py_ssize_t txt_length; + txt = PyUnicode_AsUTF8AndSize(args[0], &txt_length); + if (txt == NULL) { + goto exit; + } + if (strlen(txt) != (size_t)txt_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + name = PyObject_IsTrue(args[1]); + if (name < 0) { + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "enum_certificates", 0}; + PyObject *argsbuf[1]; + const char *store_name; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("enum_certificates", "argument 'store_name'", "str", args[0]); + goto exit; + } + Py_ssize_t store_name_length; + store_name = PyUnicode_AsUTF8AndSize(args[0], &store_name_length); + if (store_name == NULL) { + goto exit; + } + if (strlen(store_name) != (size_t)store_name_length) { + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "enum_crls", 0}; + PyObject *argsbuf[1]; + const char *store_name; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("enum_crls", "argument 'store_name'", "str", args[0]); + goto exit; + } + Py_ssize_t store_name_length; + store_name = PyUnicode_AsUTF8AndSize(args[0], &store_name_length); + if (store_name == NULL) { + goto exit; + } + if (strlen(store_name) != (size_t)store_name_length) { + 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) */ +/*[clinic end generated code: output=a4aeb3f92a091c64 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_statisticsmodule.c.h b/python/Modules/clinic/_statisticsmodule.c.h new file mode 100755 index 0000000..5ff01ef --- /dev/null +++ b/python/Modules/clinic/_statisticsmodule.c.h @@ -0,0 +1,68 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_statistics__normal_dist_inv_cdf__doc__, +"_normal_dist_inv_cdf($module, p, mu, sigma, /)\n" +"--\n" +"\n"); + +#define _STATISTICS__NORMAL_DIST_INV_CDF_METHODDEF \ + {"_normal_dist_inv_cdf", (PyCFunction)(void(*)(void))_statistics__normal_dist_inv_cdf, METH_FASTCALL, _statistics__normal_dist_inv_cdf__doc__}, + +static double +_statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu, + double sigma); + +static PyObject * +_statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + double p; + double mu; + double sigma; + double _return_value; + + if (!_PyArg_CheckPositional("_normal_dist_inv_cdf", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_CheckExact(args[0])) { + p = PyFloat_AS_DOUBLE(args[0]); + } + else + { + p = PyFloat_AsDouble(args[0]); + if (p == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + mu = PyFloat_AS_DOUBLE(args[1]); + } + else + { + mu = PyFloat_AsDouble(args[1]); + if (mu == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[2])) { + sigma = PyFloat_AS_DOUBLE(args[2]); + } + else + { + sigma = PyFloat_AsDouble(args[2]); + if (sigma == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + _return_value = _statistics__normal_dist_inv_cdf_impl(module, p, mu, sigma); + if ((_return_value == -1.0) && PyErr_Occurred()) { + goto exit; + } + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=c5826928a238326c input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_struct.c.h b/python/Modules/clinic/_struct.c.h new file mode 100755 index 0000000..36c4b40 --- /dev/null +++ b/python/Modules/clinic/_struct.c.h @@ -0,0 +1,389 @@ +/*[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; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + 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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { + 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" +"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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &buffer, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buffer, 'C')) { + _PyArg_BadArgument("unpack_from", "argument 'buffer'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + 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; + } + 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; + + 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 \ + {"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}; + + if (!_PyArg_CheckPositional("unpack", nargs, 2, 2)) { + goto exit; + } + if (!cache_struct_converter(args[0], &s_object)) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buffer, 'C')) { + _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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!cache_struct_converter(args[0], &s_object)) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buffer, 'C')) { + _PyArg_BadArgument("unpack_from", "argument 'buffer'", "contiguous buffer", args[1]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("iter_unpack", nargs, 2, 2)) { + 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; +} +/*[clinic end generated code: output=6a6228cfc4b7099c input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_tkinter.c.h b/python/Modules/clinic/_tkinter.c.h new file mode 100755 index 0000000..73c3fae --- /dev/null +++ b/python/Modules/clinic/_tkinter.c.h @@ -0,0 +1,915 @@ +/*[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; + } + Py_ssize_t script_length; + script = PyUnicode_AsUTF8AndSize(arg, &script_length); + if (script == NULL) { + goto exit; + } + if (strlen(script) != (size_t)script_length) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("evalfile", "argument", "str", arg); + goto exit; + } + Py_ssize_t fileName_length; + fileName = PyUnicode_AsUTF8AndSize(arg, &fileName_length); + if (fileName == NULL) { + goto exit; + } + if (strlen(fileName) != (size_t)fileName_length) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("record", "argument", "str", arg); + goto exit; + } + Py_ssize_t script_length; + script = PyUnicode_AsUTF8AndSize(arg, &script_length); + if (script == NULL) { + goto exit; + } + if (strlen(script) != (size_t)script_length) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("adderrorinfo", "argument", "str", arg); + goto exit; + } + Py_ssize_t msg_length; + msg = PyUnicode_AsUTF8AndSize(arg, &msg_length); + if (msg == NULL) { + goto exit; + } + if (strlen(msg) != (size_t)msg_length) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("exprstring", "argument", "str", arg); + goto exit; + } + Py_ssize_t s_length; + s = PyUnicode_AsUTF8AndSize(arg, &s_length); + if (s == NULL) { + goto exit; + } + if (strlen(s) != (size_t)s_length) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("exprlong", "argument", "str", arg); + goto exit; + } + Py_ssize_t s_length; + s = PyUnicode_AsUTF8AndSize(arg, &s_length); + if (s == NULL) { + goto exit; + } + if (strlen(s) != (size_t)s_length) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("exprdouble", "argument", "str", arg); + goto exit; + } + Py_ssize_t s_length; + s = PyUnicode_AsUTF8AndSize(arg, &s_length); + if (s == NULL) { + goto exit; + } + if (strlen(s) != (size_t)s_length) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("exprboolean", "argument", "str", arg); + goto exit; + } + Py_ssize_t s_length; + s = PyUnicode_AsUTF8AndSize(arg, &s_length); + if (s == NULL) { + goto exit; + } + if (strlen(s) != (size_t)s_length) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("createcommand", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("createcommand", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("deletecommand", "argument", "str", arg); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(arg, &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("createfilehandler", nargs, 3, 3)) { + goto exit; + } + file = args[0]; + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mask = _PyLong_AsInt(args[1]); + if (mask == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("createtimerhandler", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + milliseconds = _PyLong_AsInt(args[0]); + if (milliseconds == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("mainloop", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + threshold = _PyLong_AsInt(args[0]); + if (threshold == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("dooneevent", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = _PyLong_AsInt(args[0]); + if (flags == -1 && PyErr_Occurred()) { + 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__, +"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 \ + {"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; + const char *baseName = ""; + 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; + } + if (nargs < 1) { + goto skip_optional; + } + if (args[0] == Py_None) { + screenName = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t screenName_length; + screenName = PyUnicode_AsUTF8AndSize(args[0], &screenName_length); + if (screenName == NULL) { + goto exit; + } + if (strlen(screenName) != (size_t)screenName_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("create", "argument 1", "str or None", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("create", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t baseName_length; + baseName = PyUnicode_AsUTF8AndSize(args[1], &baseName_length); + if (baseName == NULL) { + goto exit; + } + if (strlen(baseName) != (size_t)baseName_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("create", "argument 3", "str", args[2]); + goto exit; + } + Py_ssize_t className_length; + className = PyUnicode_AsUTF8AndSize(args[2], &className_length); + if (className == NULL) { + goto exit; + } + if (strlen(className) != (size_t)className_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + interactive = _PyLong_AsInt(args[3]); + if (interactive == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 5) { + goto skip_optional; + } + if (PyFloat_Check(args[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + wantobjects = _PyLong_AsInt(args[4]); + if (wantobjects == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 6) { + goto skip_optional; + } + if (PyFloat_Check(args[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + wantTk = _PyLong_AsInt(args[5]); + if (wantTk == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 7) { + goto skip_optional; + } + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + sync = _PyLong_AsInt(args[6]); + if (sync == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 8) { + goto skip_optional; + } + if (args[7] == Py_None) { + use = NULL; + } + else if (PyUnicode_Check(args[7])) { + Py_ssize_t use_length; + use = PyUnicode_AsUTF8AndSize(args[7], &use_length); + if (use == NULL) { + goto exit; + } + if (strlen(use) != (size_t)use_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("create", "argument 8", "str or None", args[7]); + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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) */ +/*[clinic end generated code: output=492b8b833fe54bc9 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_tracemalloc.c.h b/python/Modules/clinic/_tracemalloc.c.h new file mode 100755 index 0000000..68fafdc --- /dev/null +++ b/python/Modules/clinic/_tracemalloc.c.h @@ -0,0 +1,200 @@ +/*[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; + + if (!_PyArg_CheckPositional("start", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + nframe = _PyLong_AsInt(args[0]); + if (nframe == -1 && PyErr_Occurred()) { + 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); +} +/*[clinic end generated code: output=1bc96dc569706afa input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_weakref.c.h b/python/Modules/clinic/_weakref.c.h new file mode 100755 index 0000000..c3a908f --- /dev/null +++ b/python/Modules/clinic/_weakref.c.h @@ -0,0 +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 \ + {"_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; + + if (!_PyArg_CheckPositional("_remove_dead_weakref", nargs, 2, 2)) { + 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; +} +/*[clinic end generated code: output=c543dc2cd6ece975 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/_winapi.c.h b/python/Modules/clinic/_winapi.c.h new file mode 100755 index 0000000..e21f2bc --- /dev/null +++ b/python/Modules/clinic/_winapi.c.h @@ -0,0 +1,1100 @@ +/*[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 \ + {"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 \ + {"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; +} + +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" +"--\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" +"--\n" +"\n"); + +#define _WINAPI_MAPVIEWOFFILE_METHODDEF \ + {"MapViewOfFile", (PyCFunction)(void(*)(void))_winapi_MapViewOfFile, METH_FASTCALL, _winapi_MapViewOfFile__doc__}, + +static LPVOID +_winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map, + DWORD desired_access, DWORD file_offset_high, + DWORD file_offset_low, size_t number_bytes); + +static PyObject * +_winapi_MapViewOfFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE file_map; + DWORD desired_access; + DWORD file_offset_high; + DWORD file_offset_low; + size_t number_bytes; + LPVOID _return_value; + + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "kkkO&:MapViewOfFile", + &file_map, &desired_access, &file_offset_high, &file_offset_low, _PyLong_Size_t_Converter, &number_bytes)) { + goto exit; + } + _return_value = _winapi_MapViewOfFile_impl(module, file_map, desired_access, file_offset_high, file_offset_low, number_bytes); + if ((_return_value == NULL) && PyErr_Occurred()) { + goto exit; + } + return_value = HANDLE_TO_PYNUM(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_OpenFileMapping__doc__, +"OpenFileMapping($module, desired_access, inherit_handle, name, /)\n" +"--\n" +"\n"); + +#define _WINAPI_OPENFILEMAPPING_METHODDEF \ + {"OpenFileMapping", (PyCFunction)(void(*)(void))_winapi_OpenFileMapping, METH_FASTCALL, _winapi_OpenFileMapping__doc__}, + +static HANDLE +_winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access, + BOOL inherit_handle, LPCWSTR name); + +static PyObject * +_winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + DWORD desired_access; + BOOL inherit_handle; + LPCWSTR name; + HANDLE _return_value; + + if (!_PyArg_ParseStack(args, nargs, "kiu:OpenFileMapping", + &desired_access, &inherit_handle, &name)) { + goto exit; + } + _return_value = _winapi_OpenFileMapping_impl(module, desired_access, inherit_handle, 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_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 \ + {"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 \ + {"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 \ + {"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 \ + {"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; +} + +PyDoc_STRVAR(_winapi_VirtualQuerySize__doc__, +"VirtualQuerySize($module, address, /)\n" +"--\n" +"\n"); + +#define _WINAPI_VIRTUALQUERYSIZE_METHODDEF \ + {"VirtualQuerySize", (PyCFunction)_winapi_VirtualQuerySize, METH_O, _winapi_VirtualQuerySize__doc__}, + +static size_t +_winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address); + +static PyObject * +_winapi_VirtualQuerySize(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + LPCVOID address; + size_t _return_value; + + if (!PyArg_Parse(arg, "" F_POINTER ":VirtualQuerySize", &address)) { + goto exit; + } + _return_value = _winapi_VirtualQuerySize_impl(module, address); + if ((_return_value == (size_t)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSize_t(_return_value); + +exit: + return return_value; +} + +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 \ + {"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 \ + {"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 \ + {"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 \ + {"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; +} +/*[clinic end generated code: output=f3897898ea1da99d input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/arraymodule.c.h b/python/Modules/clinic/arraymodule.c.h new file mode 100755 index 0000000..33f82d4 --- /dev/null +++ b/python/Modules/clinic/arraymodule.c.h @@ -0,0 +1,602 @@ +/*[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; + + if (!_PyArg_CheckPositional("pop", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("fromfile", nargs, 2, 2)) { + goto exit; + } + f = args[0]; + 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; + } + 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_fromstring__doc__, +"fromstring($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).\n" +"\n" +"This method is deprecated. Use frombytes instead."); + +#define ARRAY_ARRAY_FROMSTRING_METHODDEF \ + {"fromstring", (PyCFunction)array_array_fromstring, METH_O, array_array_fromstring__doc__}, + +static PyObject * +array_array_fromstring_impl(arrayobject *self, Py_buffer *buffer); + +static PyObject * +array_array_fromstring(arrayobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + + if (PyUnicode_Check(arg)) { + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize(arg, &len); + if (ptr == NULL) { + goto exit; + } + PyBuffer_FillInfo(&buffer, arg, (void *)ptr, len, 1, 0); + } + else { /* any bytes-like object */ + if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buffer, 'C')) { + _PyArg_BadArgument("fromstring", "argument", "contiguous buffer", arg); + goto exit; + } + } + return_value = array_array_fromstring_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +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}; + + if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { + 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_tostring__doc__, +"tostring($self, /)\n" +"--\n" +"\n" +"Convert the array to an array of machine values and return the bytes representation.\n" +"\n" +"This method is deprecated. Use tobytes instead."); + +#define ARRAY_ARRAY_TOSTRING_METHODDEF \ + {"tostring", (PyCFunction)array_array_tostring, METH_NOARGS, array_array_tostring__doc__}, + +static PyObject * +array_array_tostring_impl(arrayobject *self); + +static PyObject * +array_array_tostring(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tostring_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, const Py_UNICODE *ustr, + Py_ssize_clean_t ustr_length); + +static PyObject * +array_array_fromunicode(arrayobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const Py_UNICODE *ustr; + Py_ssize_clean_t ustr_length; + + if (!PyArg_Parse(arg, "u#:fromunicode", &ustr, &ustr_length)) { + goto exit; + } + return_value = array_array_fromunicode_impl(self, ustr, ustr_length); + +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; + + if (!_PyArg_CheckPositional("_array_reconstructor", nargs, 4, 4)) { + goto exit; + } + arraytype = (PyTypeObject *)args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("_array_reconstructor", "argument 2", "a unicode character", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1])) { + goto exit; + } + if (PyUnicode_GET_LENGTH(args[1]) != 1) { + _PyArg_BadArgument("_array_reconstructor", "argument 2", "a unicode character", args[1]); + goto exit; + } + typecode = PyUnicode_READ_CHAR(args[1], 0); + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mformat_code = _PyLong_AsInt(args[2]); + if (mformat_code == -1 && PyErr_Occurred()) { + 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__}, +/*[clinic end generated code: output=6aa421571e2c0756 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/audioop.c.h b/python/Modules/clinic/audioop.c.h new file mode 100755 index 0000000..8745533 --- /dev/null +++ b/python/Modules/clinic/audioop.c.h @@ -0,0 +1,1472 @@ +/*[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; + + if (!_PyArg_CheckPositional("getsample", nargs, 3, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("getsample", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("max", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("max", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("minmax", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("minmax", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("avg", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("avg", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("rms", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("rms", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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}; + + if (!_PyArg_CheckPositional("findfit", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("findfit", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &reference, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&reference, 'C')) { + _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 \ + {"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}; + + if (!_PyArg_CheckPositional("findfactor", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("findfactor", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &reference, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&reference, 'C')) { + _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 \ + {"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; + + if (!_PyArg_CheckPositional("findmax", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("findmax", "argument 1", "contiguous buffer", args[0]); + 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 = 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; + + if (!_PyArg_CheckPositional("avgpp", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("avgpp", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("maxpp", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("maxpp", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("cross", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("cross", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("mul", nargs, 3, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("mul", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_CheckExact(args[2])) { + factor = PyFloat_AS_DOUBLE(args[2]); + } + else + { + factor = PyFloat_AsDouble(args[2]); + if (factor == -1.0 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("tomono", nargs, 4, 4)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("tomono", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_CheckExact(args[2])) { + lfactor = PyFloat_AS_DOUBLE(args[2]); + } + else + { + lfactor = PyFloat_AsDouble(args[2]); + if (lfactor == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[3])) { + rfactor = PyFloat_AS_DOUBLE(args[3]); + } + else + { + rfactor = PyFloat_AsDouble(args[3]); + if (rfactor == -1.0 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("tostereo", nargs, 4, 4)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("tostereo", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_CheckExact(args[2])) { + lfactor = PyFloat_AS_DOUBLE(args[2]); + } + else + { + lfactor = PyFloat_AsDouble(args[2]); + if (lfactor == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[3])) { + rfactor = PyFloat_AS_DOUBLE(args[3]); + } + else + { + rfactor = PyFloat_AsDouble(args[3]); + if (rfactor == -1.0 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("add", nargs, 3, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment1, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment1, 'C')) { + _PyArg_BadArgument("add", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &fragment2, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment2, 'C')) { + _PyArg_BadArgument("add", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[2]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("bias", nargs, 3, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("bias", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bias = _PyLong_AsInt(args[2]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("reverse", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("reverse", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("byteswap", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("byteswap", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("lin2lin", nargs, 3, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("lin2lin", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + newwidth = _PyLong_AsInt(args[2]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ratecv", nargs, 6, 8)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("ratecv", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + nchannels = _PyLong_AsInt(args[2]); + if (nchannels == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + inrate = _PyLong_AsInt(args[3]); + if (inrate == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + outrate = _PyLong_AsInt(args[4]); + if (outrate == -1 && PyErr_Occurred()) { + goto exit; + } + state = args[5]; + if (nargs < 7) { + goto skip_optional; + } + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + weightA = _PyLong_AsInt(args[6]); + if (weightA == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 8) { + goto skip_optional; + } + if (PyFloat_Check(args[7])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + weightB = _PyLong_AsInt(args[7]); + if (weightB == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("lin2ulaw", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("lin2ulaw", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ulaw2lin", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("ulaw2lin", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("lin2alaw", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("lin2alaw", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("alaw2lin", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("alaw2lin", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("lin2adpcm", nargs, 3, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("lin2adpcm", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("adpcm2lin", nargs, 3, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&fragment, 'C')) { + _PyArg_BadArgument("adpcm2lin", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + width = _PyLong_AsInt(args[1]); + if (width == -1 && PyErr_Occurred()) { + 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; +} +/*[clinic end generated code: output=6b4f2c597f295abc input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/binascii.c.h b/python/Modules/clinic/binascii.c.h new file mode 100755 index 0000000..82942f0 --- /dev/null +++ b/python/Modules/clinic/binascii.c.h @@ -0,0 +1,804 @@ +/*[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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("b2a_uu", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + backtick = _PyLong_AsInt(args[1]); + if (backtick == -1 && PyErr_Occurred()) { + 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}; + + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("b2a_base64", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + newline = _PyLong_AsInt(args[1]); + if (newline == -1 && PyErr_Occurred()) { + 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}; + + 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}; + + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + 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}; + + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + 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}; + + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + 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 \ + {"crc_hqx", (PyCFunction)(void(*)(void))binascii_crc_hqx, METH_FASTCALL, binascii_crc_hqx__doc__}, + +static unsigned int +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; + unsigned int _return_value; + + if (!_PyArg_CheckPositional("crc_hqx", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("crc_hqx", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (crc == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } + _return_value = binascii_crc_hqx_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_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; + + if (!_PyArg_CheckPositional("crc32", nargs, 1, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("crc32", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (crc == (unsigned int)-1 && PyErr_Occurred()) { + 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__, +"b2a_hex($module, /, data, sep=, bytes_per_sep=1)\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" +"available as \"hexlify()\".\n" +"\n" +"Example:\n" +">>> binascii.b2a_hex(b\'\\xb9\\x01\\xef\')\n" +"b\'b901ef\'\n" +">>> binascii.hexlify(b\'\\xb9\\x01\\xef\', \':\')\n" +"b\'b9:01:ef\'\n" +">>> binascii.b2a_hex(b\'\\xb9\\x01\\xef\', b\'_\', 2)\n" +"b\'b9_01ef\'"); + +#define BINASCII_B2A_HEX_METHODDEF \ + {"b2a_hex", (PyCFunction)(void(*)(void))binascii_b2a_hex, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_hex__doc__}, + +static PyObject * +binascii_b2a_hex_impl(PyObject *module, Py_buffer *data, PyObject *sep, + int bytes_per_sep); + +static PyObject * +binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + 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}; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("b2a_hex", "argument 'data'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + sep = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[2]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +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__, +"hexlify($module, /, data, sep=, bytes_per_sep=1)\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" +"available as \"b2a_hex()\"."); + +#define BINASCII_HEXLIFY_METHODDEF \ + {"hexlify", (PyCFunction)(void(*)(void))binascii_hexlify, METH_FASTCALL|METH_KEYWORDS, binascii_hexlify__doc__}, + +static PyObject * +binascii_hexlify_impl(PyObject *module, Py_buffer *data, PyObject *sep, + int bytes_per_sep); + +static PyObject * +binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + 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}; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("hexlify", "argument 'data'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + sep = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[2]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +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}; + + 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}; + + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!ascii_buffer_converter(args[0], &data)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + header = _PyLong_AsInt(args[1]); + if (header == -1 && PyErr_Occurred()) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("b2a_qp", "argument 'data'", "contiguous buffer", args[0]); + 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; + } + quotetabs = _PyLong_AsInt(args[1]); + if (quotetabs == -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; + } + istext = _PyLong_AsInt(args[2]); + if (istext == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + header = _PyLong_AsInt(args[3]); + if (header == -1 && PyErr_Occurred()) { + 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; +} +/*[clinic end generated code: output=ec26d03c2007eaac input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/cmathmodule.c.h b/python/Modules/clinic/cmathmodule.c.h new file mode 100755 index 0000000..81a8437 --- /dev/null +++ b/python/Modules/clinic/cmathmodule.c.h @@ -0,0 +1,971 @@ +/*[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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_acos_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_acosh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_asin_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_asinh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_atan_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_atanh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_cos_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_cosh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_exp_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_log10_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_sin_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_sinh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_sqrt_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_tan_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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 */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_tanh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + 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" +"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 \ + {"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; + + if (!_PyArg_CheckPositional("log", nargs, 1, 2)) { + goto exit; + } + x = PyComplex_AsCComplex(args[0]); + if (PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + 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; + + 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; + + 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 \ + {"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; + + if (!_PyArg_CheckPositional("rect", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_CheckExact(args[0])) { + r = PyFloat_AS_DOUBLE(args[0]); + } + else + { + r = PyFloat_AsDouble(args[0]); + if (r == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + phi = PyFloat_AS_DOUBLE(args[1]); + } + else + { + phi = PyFloat_AsDouble(args[1]); + if (phi == -1.0 && PyErr_Occurred()) { + 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; + + 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; + + 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; + + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = PyComplex_AsCComplex(args[0]); + if (PyErr_Occurred()) { + goto exit; + } + b = PyComplex_AsCComplex(args[1]); + if (PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[2]) { + if (PyFloat_CheckExact(args[2])) { + rel_tol = PyFloat_AS_DOUBLE(args[2]); + } + else + { + rel_tol = PyFloat_AsDouble(args[2]); + if (rel_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyFloat_CheckExact(args[3])) { + abs_tol = PyFloat_AS_DOUBLE(args[3]); + } + else + { + abs_tol = PyFloat_AsDouble(args[3]); + if (abs_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +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; +} +/*[clinic end generated code: output=3edc4484b10ae752 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/fcntlmodule.c.h b/python/Modules/clinic/fcntlmodule.c.h new file mode 100755 index 0000000..024a44c --- /dev/null +++ b/python/Modules/clinic/fcntlmodule.c.h @@ -0,0 +1,271 @@ +/*[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; + + if (!_PyArg_CheckPositional("fcntl", nargs, 2, 3)) { + goto exit; + } + if (!conv_descriptor(args[0], &fd)) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + code = _PyLong_AsInt(args[1]); + if (code == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ioctl", nargs, 2, 4)) { + goto exit; + } + if (!conv_descriptor(args[0], &fd)) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + code = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (code == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + ob_arg = args[2]; + if (nargs < 4) { + goto skip_optional; + } + mutate_arg = PyObject_IsTrue(args[3]); + if (mutate_arg < 0) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("flock", nargs, 2, 2)) { + goto exit; + } + if (!conv_descriptor(args[0], &fd)) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + code = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("lockf", nargs, 2, 5)) { + goto exit; + } + if (!conv_descriptor(args[0], &fd)) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + code = _PyLong_AsInt(args[1]); + if (code == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + lenobj = args[2]; + if (nargs < 4) { + goto skip_optional; + } + startobj = args[3]; + if (nargs < 5) { + goto skip_optional; + } + if (PyFloat_Check(args[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + whence = _PyLong_AsInt(args[4]); + if (whence == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + 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/python/Modules/clinic/gcmodule.c.h b/python/Modules/clinic/gcmodule.c.h new file mode 100755 index 0000000..22d2aa4 --- /dev/null +++ b/python/Modules/clinic/gcmodule.c.h @@ -0,0 +1,376 @@ +/*[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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + generation = _PyLong_AsInt(args[0]); + if (generation == -1 && PyErr_Occurred()) { + 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; + + 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 = 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" +"Return a list of objects tracked by the collector (excluding the list returned).\n" +"\n" +" generation\n" +" Generation to extract the objects from.\n" +"\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 \ + {"get_objects", (PyCFunction)(void(*)(void))gc_get_objects, METH_FASTCALL|METH_KEYWORDS, gc_get_objects__doc__}, + +static PyObject * +gc_get_objects_impl(PyObject *module, Py_ssize_t generation); + +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}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + Py_ssize_t generation = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!_Py_convert_optional_to_ssize_t(args[0], &generation)) { + goto exit; + } +skip_optional_pos: + return_value = gc_get_objects_impl(module, generation); + +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_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=e40d384b1f0d513c input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/grpmodule.c.h b/python/Modules/clinic/grpmodule.c.h new file mode 100755 index 0000000..2e2690a --- /dev/null +++ b/python/Modules/clinic/grpmodule.c.h @@ -0,0 +1,100 @@ +/*[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 _PyArg_Parser _parser = {NULL, _keywords, "getgrgid", 0}; + PyObject *argsbuf[1]; + PyObject *id; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "getgrnam", 0}; + PyObject *argsbuf[1]; + PyObject *name; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("getgrnam", "argument 'name'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + 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); +} +/*[clinic end generated code: output=9b3f26779e4e1a52 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/itertoolsmodule.c.h b/python/Modules/clinic/itertoolsmodule.c.h new file mode 100755 index 0000000..20594b0 --- /dev/null +++ b/python/Modules/clinic/itertoolsmodule.c.h @@ -0,0 +1,645 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(itertools_groupby__doc__, +"groupby(iterable, key=None)\n" +"--\n" +"\n" +"make an iterator that returns consecutive keys and groups from the iterable\n" +"\n" +" iterable\n" +" Elements to divide into groups according to the key function.\n" +" key\n" +" A function for computing the group category for each element.\n" +" If the key function is not specified or is None, the element itself\n" +" is used for grouping."); + +static PyObject * +itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc); + +static PyObject * +itertools_groupby(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"iterable", "key", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "groupby", 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 *it; + PyObject *keyfunc = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + it = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + keyfunc = fastargs[1]; +skip_optional_pos: + return_value = itertools_groupby_impl(type, it, keyfunc); + +exit: + return return_value; +} + +static PyObject * +itertools__grouper_impl(PyTypeObject *type, PyObject *parent, + PyObject *tgtkey); + +static PyObject * +itertools__grouper(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *parent; + PyObject *tgtkey; + + if ((type == &_grouper_type) && + !_PyArg_NoKeywords("_grouper", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("_grouper", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), &groupby_type)) { + _PyArg_BadArgument("_grouper", "argument 1", (&groupby_type)->tp_name, PyTuple_GET_ITEM(args, 0)); + goto exit; + } + parent = PyTuple_GET_ITEM(args, 0); + tgtkey = PyTuple_GET_ITEM(args, 1); + return_value = itertools__grouper_impl(type, parent, tgtkey); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_teedataobject__doc__, +"teedataobject(iterable, values, next, /)\n" +"--\n" +"\n" +"Data container common to multiple tee objects."); + +static PyObject * +itertools_teedataobject_impl(PyTypeObject *type, PyObject *it, + PyObject *values, PyObject *next); + +static PyObject * +itertools_teedataobject(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *it; + PyObject *values; + PyObject *next; + + if ((type == &teedataobject_type) && + !_PyArg_NoKeywords("teedataobject", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("teedataobject", PyTuple_GET_SIZE(args), 3, 3)) { + goto exit; + } + it = PyTuple_GET_ITEM(args, 0); + if (!PyList_Check(PyTuple_GET_ITEM(args, 1))) { + _PyArg_BadArgument("teedataobject", "argument 2", "list", PyTuple_GET_ITEM(args, 1)); + goto exit; + } + values = PyTuple_GET_ITEM(args, 1); + next = PyTuple_GET_ITEM(args, 2); + return_value = itertools_teedataobject_impl(type, it, values, next); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools__tee__doc__, +"_tee(iterable, /)\n" +"--\n" +"\n" +"Iterator wrapped to make it copyable."); + +static PyObject * +itertools__tee_impl(PyTypeObject *type, PyObject *iterable); + +static PyObject * +itertools__tee(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *iterable; + + if ((type == &tee_type) && + !_PyArg_NoKeywords("_tee", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("_tee", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + iterable = PyTuple_GET_ITEM(args, 0); + return_value = itertools__tee_impl(type, iterable); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_tee__doc__, +"tee($module, iterable, n=2, /)\n" +"--\n" +"\n" +"Returns a tuple of n independent iterators."); + +#define ITERTOOLS_TEE_METHODDEF \ + {"tee", (PyCFunction)(void(*)(void))itertools_tee, METH_FASTCALL, itertools_tee__doc__}, + +static PyObject * +itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n); + +static PyObject * +itertools_tee(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *iterable; + Py_ssize_t n = 2; + + if (!_PyArg_CheckPositional("tee", nargs, 1, 2)) { + goto exit; + } + iterable = args[0]; + if (nargs < 2) { + goto skip_optional; + } + 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; + } + n = ival; + } +skip_optional: + return_value = itertools_tee_impl(module, iterable, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_cycle__doc__, +"cycle(iterable, /)\n" +"--\n" +"\n" +"Return elements from the iterable until it is exhausted. Then repeat the sequence indefinitely."); + +static PyObject * +itertools_cycle_impl(PyTypeObject *type, PyObject *iterable); + +static PyObject * +itertools_cycle(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *iterable; + + if ((type == &cycle_type) && + !_PyArg_NoKeywords("cycle", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("cycle", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + iterable = PyTuple_GET_ITEM(args, 0); + return_value = itertools_cycle_impl(type, iterable); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_dropwhile__doc__, +"dropwhile(predicate, iterable, /)\n" +"--\n" +"\n" +"Drop items from the iterable while predicate(item) is true.\n" +"\n" +"Afterwards, return every element until the iterable is exhausted."); + +static PyObject * +itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq); + +static PyObject * +itertools_dropwhile(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *func; + PyObject *seq; + + if ((type == &dropwhile_type) && + !_PyArg_NoKeywords("dropwhile", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("dropwhile", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + func = PyTuple_GET_ITEM(args, 0); + seq = PyTuple_GET_ITEM(args, 1); + return_value = itertools_dropwhile_impl(type, func, seq); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_takewhile__doc__, +"takewhile(predicate, iterable, /)\n" +"--\n" +"\n" +"Return successive entries from an iterable as long as the predicate evaluates to true for each entry."); + +static PyObject * +itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq); + +static PyObject * +itertools_takewhile(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *func; + PyObject *seq; + + if ((type == &takewhile_type) && + !_PyArg_NoKeywords("takewhile", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("takewhile", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + func = PyTuple_GET_ITEM(args, 0); + seq = PyTuple_GET_ITEM(args, 1); + return_value = itertools_takewhile_impl(type, func, seq); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_starmap__doc__, +"starmap(function, iterable, /)\n" +"--\n" +"\n" +"Return an iterator whose values are returned from the function evaluated with an argument tuple taken from the given sequence."); + +static PyObject * +itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq); + +static PyObject * +itertools_starmap(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *func; + PyObject *seq; + + if ((type == &starmap_type) && + !_PyArg_NoKeywords("starmap", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("starmap", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + func = PyTuple_GET_ITEM(args, 0); + seq = PyTuple_GET_ITEM(args, 1); + return_value = itertools_starmap_impl(type, func, seq); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_chain_from_iterable__doc__, +"from_iterable($type, iterable, /)\n" +"--\n" +"\n" +"Alternative chain() constructor taking a single iterable argument that evaluates lazily."); + +#define ITERTOOLS_CHAIN_FROM_ITERABLE_METHODDEF \ + {"from_iterable", (PyCFunction)itertools_chain_from_iterable, METH_O|METH_CLASS, itertools_chain_from_iterable__doc__}, + +PyDoc_STRVAR(itertools_combinations__doc__, +"combinations(iterable, r)\n" +"--\n" +"\n" +"Return successive r-length combinations of elements in the iterable.\n" +"\n" +"combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)"); + +static PyObject * +itertools_combinations_impl(PyTypeObject *type, PyObject *iterable, + Py_ssize_t r); + +static PyObject * +itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"iterable", "r", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "combinations", 0}; + PyObject *argsbuf[2]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *iterable; + Py_ssize_t r; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + iterable = fastargs[0]; + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(fastargs[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + r = ival; + } + return_value = itertools_combinations_impl(type, iterable, r); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_combinations_with_replacement__doc__, +"combinations_with_replacement(iterable, r)\n" +"--\n" +"\n" +"Return successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats.\n" +"\n" +"combinations_with_replacement(\'ABC\', 2) --> AA AB AC BB BC CC\""); + +static PyObject * +itertools_combinations_with_replacement_impl(PyTypeObject *type, + PyObject *iterable, + Py_ssize_t r); + +static PyObject * +itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"iterable", "r", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "combinations_with_replacement", 0}; + PyObject *argsbuf[2]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *iterable; + Py_ssize_t r; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + iterable = fastargs[0]; + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(fastargs[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + r = ival; + } + return_value = itertools_combinations_with_replacement_impl(type, iterable, r); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_permutations__doc__, +"permutations(iterable, r=None)\n" +"--\n" +"\n" +"Return successive r-length permutations of elements in the iterable.\n" +"\n" +"permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)"); + +static PyObject * +itertools_permutations_impl(PyTypeObject *type, PyObject *iterable, + PyObject *robj); + +static PyObject * +itertools_permutations(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"iterable", "r", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "permutations", 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 *iterable; + PyObject *robj = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + iterable = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + robj = fastargs[1]; +skip_optional_pos: + return_value = itertools_permutations_impl(type, iterable, robj); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_accumulate__doc__, +"accumulate(iterable, func=None, *, initial=None)\n" +"--\n" +"\n" +"Return series of accumulated sums (or other binary function results)."); + +static PyObject * +itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable, + PyObject *binop, PyObject *initial); + +static PyObject * +itertools_accumulate(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"iterable", "func", "initial", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "accumulate", 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 *iterable; + PyObject *binop = Py_None; + PyObject *initial = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + iterable = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[1]) { + binop = fastargs[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + initial = fastargs[2]; +skip_optional_kwonly: + return_value = itertools_accumulate_impl(type, iterable, binop, initial); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_compress__doc__, +"compress(data, selectors)\n" +"--\n" +"\n" +"Return data elements corresponding to true selector elements.\n" +"\n" +"Forms a shorter iterator from selected data elements using the selectors to\n" +"choose the data elements."); + +static PyObject * +itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2); + +static PyObject * +itertools_compress(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "selectors", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + PyObject *argsbuf[2]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *seq1; + PyObject *seq2; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + seq1 = fastargs[0]; + seq2 = fastargs[1]; + return_value = itertools_compress_impl(type, seq1, seq2); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_filterfalse__doc__, +"filterfalse(function, iterable, /)\n" +"--\n" +"\n" +"Return those items of iterable for which function(item) is false.\n" +"\n" +"If function is None, return the items that are false."); + +static PyObject * +itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq); + +static PyObject * +itertools_filterfalse(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *func; + PyObject *seq; + + if ((type == &filterfalse_type) && + !_PyArg_NoKeywords("filterfalse", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("filterfalse", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + func = PyTuple_GET_ITEM(args, 0); + seq = PyTuple_GET_ITEM(args, 1); + return_value = itertools_filterfalse_impl(type, func, seq); + +exit: + return return_value; +} + +PyDoc_STRVAR(itertools_count__doc__, +"count(start=0, step=1)\n" +"--\n" +"\n" +"Return a count object whose .__next__() method returns consecutive values.\n" +"\n" +"Equivalent to:\n" +" def count(firstval=0, step=1):\n" +" x = firstval\n" +" while 1:\n" +" yield x\n" +" x += step"); + +static PyObject * +itertools_count_impl(PyTypeObject *type, PyObject *long_cnt, + PyObject *long_step); + +static PyObject * +itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"start", "step", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "count", 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 *long_cnt = NULL; + PyObject *long_step = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + long_cnt = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + long_step = fastargs[1]; +skip_optional_pos: + return_value = itertools_count_impl(type, long_cnt, long_step); + +exit: + return return_value; +} +/*[clinic end generated code: output=392c9706e79f6710 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/mathmodule.c.h b/python/Modules/clinic/mathmodule.c.h new file mode 100755 index 0000000..95d68ee --- /dev/null +++ b/python/Modules/clinic/mathmodule.c.h @@ -0,0 +1,811 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(math_gcd__doc__, +"gcd($module, x, y, /)\n" +"--\n" +"\n" +"greatest common divisor of x and y"); + +#define MATH_GCD_METHODDEF \ + {"gcd", (PyCFunction)(void(*)(void))math_gcd, METH_FASTCALL, math_gcd__doc__}, + +static PyObject * +math_gcd_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +math_gcd(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + + if (!_PyArg_CheckPositional("gcd", nargs, 2, 2)) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = math_gcd_impl(module, a, b); + +exit: + return return_value; +} + +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" +"\n" +"Return the integer part of the square root of the input."); + +#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; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_CheckExact(args[0])) { + x = PyFloat_AS_DOUBLE(args[0]); + } + else + { + x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + 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; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_CheckExact(args[0])) { + x = PyFloat_AS_DOUBLE(args[0]); + } + else + { + x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + y = PyFloat_AS_DOUBLE(args[1]); + } + else + { + y = PyFloat_AsDouble(args[1]); + if (y == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + return_value = math_fmod_impl(module, x, y); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_dist__doc__, +"dist($module, p, q, /)\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" +"coordinates. Both inputs must have the same dimension.\n" +"\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 * +math_dist_impl(PyObject *module, PyObject *p, PyObject *q); + +static PyObject * +math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *p; + PyObject *q; + + if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_CheckExact(args[0])) { + x = PyFloat_AS_DOUBLE(args[0]); + } + else + { + x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + y = PyFloat_AS_DOUBLE(args[1]); + } + else + { + y = PyFloat_AsDouble(args[1]); + if (y == -1.0 && PyErr_Occurred()) { + 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; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + 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; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + 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; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + 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; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + 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; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_CheckExact(args[0])) { + a = PyFloat_AS_DOUBLE(args[0]); + } + else + { + a = PyFloat_AsDouble(args[0]); + if (a == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (PyFloat_CheckExact(args[1])) { + b = PyFloat_AS_DOUBLE(args[1]); + } + else + { + b = PyFloat_AsDouble(args[1]); + if (b == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[2]) { + if (PyFloat_CheckExact(args[2])) { + rel_tol = PyFloat_AS_DOUBLE(args[2]); + } + else + { + rel_tol = PyFloat_AsDouble(args[2]); + if (rel_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyFloat_CheckExact(args[3])) { + abs_tol = PyFloat_AS_DOUBLE(args[3]); + } + else + { + abs_tol = PyFloat_AsDouble(args[3]); + if (abs_tol == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +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; +} + +PyDoc_STRVAR(math_prod__doc__, +"prod($module, iterable, /, *, start=1)\n" +"--\n" +"\n" +"Calculate the product of all the elements in the input iterable.\n" +"\n" +"The default start value for the product is 1.\n" +"\n" +"When the iterable is empty, return the start value. This function is\n" +"intended specifically for use with numeric values and may reject\n" +"non-numeric types."); + +#define MATH_PROD_METHODDEF \ + {"prod", (PyCFunction)(void(*)(void))math_prod, METH_FASTCALL|METH_KEYWORDS, math_prod__doc__}, + +static PyObject * +math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start); + +static PyObject * +math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "start", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "prod", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *iterable; + PyObject *start = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + iterable = args[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + start = args[1]; +skip_optional_kwonly: + return_value = math_prod_impl(module, iterable, start); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_perm__doc__, +"perm($module, n, k=None, /)\n" +"--\n" +"\n" +"Number of ways to choose k items from n items without repetition and with order.\n" +"\n" +"Evaluates to n! / (n - k)! when k <= n and evaluates\n" +"to zero when k > n.\n" +"\n" +"If k is not specified or is None, then k defaults to n\n" +"and the function returns n!.\n" +"\n" +"Raises TypeError if either of the arguments are not integers.\n" +"Raises ValueError if either of the arguments are negative."); + +#define MATH_PERM_METHODDEF \ + {"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__}, + +static PyObject * +math_perm_impl(PyObject *module, PyObject *n, PyObject *k); + +static PyObject * +math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *n; + PyObject *k = Py_None; + + if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) { + goto exit; + } + n = args[0]; + if (nargs < 2) { + goto skip_optional; + } + k = args[1]; +skip_optional: + return_value = math_perm_impl(module, n, k); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_comb__doc__, +"comb($module, n, k, /)\n" +"--\n" +"\n" +"Number of ways to choose k items from n items without repetition and without order.\n" +"\n" +"Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n" +"to zero when k > n.\n" +"\n" +"Also called the binomial coefficient because it is equivalent\n" +"to the coefficient of k-th term in polynomial expansion of the\n" +"expression (1 + x)**n.\n" +"\n" +"Raises TypeError if either of the arguments are not integers.\n" +"Raises ValueError if either of the arguments are negative."); + +#define MATH_COMB_METHODDEF \ + {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__}, + +static PyObject * +math_comb_impl(PyObject *module, PyObject *n, PyObject *k); + +static PyObject * +math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *n; + PyObject *k; + + if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) { + goto exit; + } + n = args[0]; + k = args[1]; + return_value = math_comb_impl(module, n, k); + +exit: + return return_value; +} +/*[clinic end generated code: output=9a2b3dc91eb9aadd input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/md5module.c.h b/python/Modules/clinic/md5module.c.h new file mode 100755 index 0000000..12484cc --- /dev/null +++ b/python/Modules/clinic/md5module.c.h @@ -0,0 +1,104 @@ +/*[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\'\')\n" +"--\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 * +_md5_md5_impl(PyObject *module, PyObject *string); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "md5", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + string = args[0]; +skip_optional_pos: + return_value = _md5_md5_impl(module, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=53133f08cf9095fc input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/posixmodule.c.h b/python/Modules/clinic/posixmodule.c.h new file mode 100755 index 0000000..042eb4b --- /dev/null +++ b/python/Modules/clinic/posixmodule.c.h @@ -0,0 +1,8771 @@ +/*[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 _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; + + 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 (args[1]) { + if (!FSTATAT_DIR_FD_CONVERTER(args[1], &dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + follow_symlinks = PyObject_IsTrue(args[2]); + if (follow_symlinks < 0) { + 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 \ + {"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 _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; + + 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 (!FSTATAT_DIR_FD_CONVERTER(args[1], &dir_fd)) { + 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 \ + {"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 _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; + + 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 (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_kwonly; + } + if (args[2]) { + if (!FACCESSAT_DIR_FD_CONVERTER(args[2], &dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + effective_ids = PyObject_IsTrue(args[3]); + if (effective_ids < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + follow_symlinks = PyObject_IsTrue(args[4]); + if (follow_symlinks < 0) { + 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; + + 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_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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "chdir", 0}; + PyObject *argsbuf[1]; + 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; + } + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "fchdir", 0}; + PyObject *argsbuf[1]; + int fd; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + 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 (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_kwonly; + } + if (args[2]) { + if (!FCHMODAT_DIR_FD_CONVERTER(args[2], &dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + follow_symlinks = PyObject_IsTrue(args[3]); + if (follow_symlinks < 0) { + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "fchmod", 0}; + PyObject *argsbuf[2]; + int fd; + int mode; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 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; + } + mode = _PyLong_AsInt(args[1]); + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "lchmod", 0}; + PyObject *argsbuf[2]; + 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; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + 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; + } + 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 _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; + + 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 (!PyLong_Check(args[1])) { + _PyArg_BadArgument("chflags", "argument 'flags'", "int", args[1]); + goto exit; + } + flags = PyLong_AsUnsignedLongMask(args[1]); + if (!noptargs) { + goto skip_optional_pos; + } + follow_symlinks = PyObject_IsTrue(args[2]); + if (follow_symlinks < 0) { + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "lchflags", 0}; + PyObject *argsbuf[2]; + 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; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + if (!PyLong_Check(args[1])) { + _PyArg_BadArgument("lchflags", "argument 'flags'", "int", args[1]); + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "chroot", 0}; + PyObject *argsbuf[1]; + 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; + } + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "fsync", 0}; + PyObject *argsbuf[1]; + int fd; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "fdatasync", 0}; + PyObject *argsbuf[1]; + int fd; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + if (!_Py_Uid_Converter(args[1], &uid)) { + goto exit; + } + if (!_Py_Gid_Converter(args[2], &gid)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + if (!FCHOWNAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + follow_symlinks = PyObject_IsTrue(args[4]); + if (follow_symlinks < 0) { + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "fchown", 0}; + PyObject *argsbuf[3]; + int fd; + uid_t uid; + gid_t gid; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 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 (!_Py_Uid_Converter(args[1], &uid)) { + goto exit; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + if (!_Py_Uid_Converter(args[1], &uid)) { + goto exit; + } + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 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_kwonly; + } + if (args[2]) { + if (!dir_fd_converter(args[2], &src_dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!dir_fd_converter(args[3], &dst_dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + follow_symlinks = PyObject_IsTrue(args[4]); + if (follow_symlinks < 0) { + 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 \ + {"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 _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); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!path_converter(args[0], &path)) { + goto exit; + } +skip_optional_pos: + 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__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 \ + {"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 _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; + + 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 (!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 (!MKDIRAT_DIR_FD_CONVERTER(args[2], &dir_fd)) { + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "getpriority", 0}; + PyObject *argsbuf[2]; + int which; + int who; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + which = _PyLong_AsInt(args[0]); + if (which == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + who = _PyLong_AsInt(args[1]); + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "setpriority", 0}; + PyObject *argsbuf[3]; + int which; + int who; + int priority; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + which = _PyLong_AsInt(args[0]); + if (which == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + who = _PyLong_AsInt(args[1]); + if (who == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + priority = _PyLong_AsInt(args[2]); + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 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_kwonly; + } + if (args[2]) { + if (!dir_fd_converter(args[2], &src_dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (!dir_fd_converter(args[3], &dst_dir_fd)) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 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_kwonly; + } + if (args[2]) { + if (!dir_fd_converter(args[2], &src_dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (!dir_fd_converter(args[3], &dst_dir_fd)) { + 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 \ + {"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 _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; + + 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 (!UNLINKAT_DIR_FD_CONVERTER(args[1], &dir_fd)) { + 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 \ + {"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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + PyObject *argsbuf[1]; + PyObject *command = NULL; + long _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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 \ + {"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 _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; + + 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 (!UNLINKAT_DIR_FD_CONVERTER(args[1], &dir_fd)) { + 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 \ + {"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 _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; + + 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 (!UNLINKAT_DIR_FD_CONVERTER(args[1], &dir_fd)) { + 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__, +"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 \ + {"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 _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); + PyObject *times = Py_None; + 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; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + times = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[2]) { + ns = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (!FUTIMENSAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + follow_symlinks = PyObject_IsTrue(args[4]); + if (follow_symlinks < 0) { + 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 \ + {"_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 _PyArg_Parser _parser = {NULL, _keywords, "_exit", 0}; + PyObject *argsbuf[1]; + int status; + + 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__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; + + if (!_PyArg_CheckPositional("execv", nargs, 2, 2)) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + 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) */ + +#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" +" setsigmask=(), setsigdef=(), scheduler=)\n" +"--\n" +"\n" +"Execute the program specified by path in a new 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.\n" +" file_actions\n" +" A sequence of file action tuples.\n" +" setpgroup\n" +" The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.\n" +" resetids\n" +" If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.\n" +" setsid\n" +" If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.\n" +" setsigmask\n" +" The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.\n" +" setsigdef\n" +" The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.\n" +" scheduler\n" +" A tuple with the scheduler policy (optional) and parameters."); + +#define OS_POSIX_SPAWN_METHODDEF \ + {"posix_spawn", (PyCFunction)(void(*)(void))os_posix_spawn, METH_FASTCALL|METH_KEYWORDS, os_posix_spawn__doc__}, + +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); + +static PyObject * +os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawn", 0}; + PyObject *argsbuf[10]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); + PyObject *argv; + PyObject *env; + PyObject *file_actions = NULL; + PyObject *setpgroup = NULL; + int resetids = 0; + int setsid = 0; + PyObject *setsigmask = NULL; + PyObject *setsigdef = NULL; + PyObject *scheduler = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + argv = args[1]; + env = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + file_actions = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[4]) { + setpgroup = args[4]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[5]) { + if (PyFloat_Check(args[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + resetids = _PyLong_AsInt(args[5]); + if (resetids == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[6]) { + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + setsid = _PyLong_AsInt(args[6]); + if (setsid == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[7]) { + setsigmask = args[7]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[8]) { + setsigdef = args[8]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + scheduler = args[9]; +skip_optional_kwonly: + return_value = os_posix_spawn_impl(module, &path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, scheduler); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_POSIX_SPAWN) */ + +#if defined(HAVE_POSIX_SPAWNP) + +PyDoc_STRVAR(os_posix_spawnp__doc__, +"posix_spawnp($module, path, argv, env, /, *, file_actions=(),\n" +" setpgroup=, resetids=False, setsid=False,\n" +" setsigmask=(), setsigdef=(), scheduler=)\n" +"--\n" +"\n" +"Execute the program specified by path in a new 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.\n" +" file_actions\n" +" A sequence of file action tuples.\n" +" setpgroup\n" +" The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.\n" +" resetids\n" +" If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.\n" +" setsid\n" +" If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated.\n" +" setsigmask\n" +" The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.\n" +" setsigdef\n" +" The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.\n" +" scheduler\n" +" A tuple with the scheduler policy (optional) and parameters."); + +#define OS_POSIX_SPAWNP_METHODDEF \ + {"posix_spawnp", (PyCFunction)(void(*)(void))os_posix_spawnp, METH_FASTCALL|METH_KEYWORDS, os_posix_spawnp__doc__}, + +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); + +static PyObject * +os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawnp", 0}; + PyObject *argsbuf[10]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0); + PyObject *argv; + PyObject *env; + PyObject *file_actions = NULL; + PyObject *setpgroup = NULL; + int resetids = 0; + int setsid = 0; + PyObject *setsigmask = NULL; + PyObject *setsigdef = NULL; + PyObject *scheduler = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + argv = args[1]; + env = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + file_actions = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[4]) { + setpgroup = args[4]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[5]) { + if (PyFloat_Check(args[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + resetids = _PyLong_AsInt(args[5]); + if (resetids == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[6]) { + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + setsid = _PyLong_AsInt(args[6]); + if (setsid == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[7]) { + setsigmask = args[7]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[8]) { + setsigdef = args[8]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + scheduler = args[9]; +skip_optional_kwonly: + return_value = os_posix_spawnp_impl(module, &path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, scheduler); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_POSIX_SPAWNP) */ + +#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 \ + {"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; + + if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mode = _PyLong_AsInt(args[0]); + if (mode == -1 && PyErr_Occurred()) { + goto exit; + } + if (!path_converter(args[1], &path)) { + goto exit; + } + argv = args[2]; + 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 \ + {"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; + + if (!_PyArg_CheckPositional("spawnve", nargs, 4, 4)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mode = _PyLong_AsInt(args[0]); + if (mode == -1 && PyErr_Occurred()) { + goto exit; + } + if (!path_converter(args[1], &path)) { + goto exit; + } + 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; +} + +#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) */ + +#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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[0]) { + before = args[0]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[1]) { + after_in_child = args[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_max", 0}; + PyObject *argsbuf[1]; + int policy; + + 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; + } + policy = _PyLong_AsInt(args[0]); + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_min", 0}; + PyObject *argsbuf[1]; + int policy; + + 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; + } + policy = _PyLong_AsInt(args[0]); + 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) + +PyDoc_STRVAR(os_sched_getscheduler__doc__, +"sched_getscheduler($module, pid, /)\n" +"--\n" +"\n" +"Get the scheduling policy for the process identifiedy 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" +"Current 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, + struct sched_param *param); + +static PyObject * +os_sched_setscheduler(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + int policy; + struct sched_param param; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "iO&:sched_setscheduler", + &pid, &policy, convert_sched_param, ¶m)) { + goto exit; + } + return_value = os_sched_setscheduler_impl(module, pid, policy, ¶m); + +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, + struct sched_param *param); + +static PyObject * +os_sched_setparam(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + struct sched_param param; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "O&:sched_setparam", + &pid, convert_sched_param, ¶m)) { + goto exit; + } + return_value = os_sched_setparam_impl(module, pid, ¶m); + +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_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_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(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, int length, Py_off_t offset); + +static PyObject * +os_pread(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int 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; + } + length = _PyLong_AsInt(args[1]); + if (length == -1 && PyErr_Occurred()) { + goto exit; + } + 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(__APPLE__) + +PyDoc_STRVAR(os__fcopyfile__doc__, +"_fcopyfile($module, infd, outfd, 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 infd, int outfd, int flags); + +static PyObject * +os__fcopyfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int infd; + int outfd; + 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; + } + infd = _PyLong_AsInt(args[0]); + if (infd == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + outfd = _PyLong_AsInt(args[1]); + if (outfd == -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, infd, outfd, 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) { + 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; + } + 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_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_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); + if (!args) { + 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()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + dst = _PyLong_AsInt(args[1]); + if (dst == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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}; + 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 (!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; + } +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; + } + 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; + } +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; + } + 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; + } + 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; + } + if (!Py_off_t_converter(args[1], &length)) { + 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)) { + 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], &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" ); + goto exit; + } + 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; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + advice = _PyLong_AsInt(args[3]); + if (advice == -1 && PyErr_Occurred()) { + goto exit; + } + 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(HAVE_PUTENV) && 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; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + name = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("putenv", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + value = args[1]; + return_value = os_putenv_impl(module, name, value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_PUTENV) && defined(MS_WINDOWS) */ + +#if defined(HAVE_PUTENV) && !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; + } + 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(HAVE_PUTENV) && !defined(MS_WINDOWS) */ + +#if defined(HAVE_UNSETENV) + +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 = 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(HAVE_UNSETENV) */ + +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 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; + } + 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_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; + } + 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; + } + 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; + } + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { + goto exit; + } + if (!conv_path_confname(args[1], &name)) { + goto exit; + } + _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 (!conv_path_confname(args[1], &name)) { + goto exit; + } + _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; + } + 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 _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; + + 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 (!path_converter(args[1], &attribute)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[2]); + if (follow_symlinks < 0) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + if (!path_converter(args[1], &attribute)) { + goto exit; + } + if (PyObject_GetBuffer(args[2], &value, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&value, 'C')) { + _PyArg_BadArgument("setxattr", "argument 'value'", "contiguous buffer", args[2]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[3]) { + 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; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[4]); + if (follow_symlinks < 0) { + 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 \ + {"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 _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; + + 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 (!path_converter(args[1], &attribute)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[2]); + if (follow_symlinks < 0) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (!path_converter(args[0], &path)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[1]); + if (follow_symlinks < 0) { + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + size = ival; + } + return_value = os_urandom_impl(module, size); + +exit: + return return_value; +} + +#if defined(HAVE_MEMFD_CREATE) + +PyDoc_STRVAR(os_memfd_create__doc__, +"memfd_create($module, /, name, flags=MFD_CLOEXEC)\n" +"--\n" +"\n"); + +#define OS_MEMFD_CREATE_METHODDEF \ + {"memfd_create", (PyCFunction)(void(*)(void))os_memfd_create, METH_FASTCALL|METH_KEYWORDS, os_memfd_create__doc__}, + +static PyObject * +os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags); + +static PyObject * +os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "flags", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "memfd_create", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *name = NULL; + unsigned int flags = MFD_CLOEXEC; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_FSConverter(args[0], &name)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (flags == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = os_memfd_create_impl(module, name, flags); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + + return return_value; +} + +#endif /* defined(HAVE_MEMFD_CREATE) */ + +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; + } + 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 \ + {"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; + + if (!_PyArg_CheckPositional("set_inheritable", 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; + } + inheritable = _PyLong_AsInt(args[1]); + 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 \ + {"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) */ + +#if !defined(MS_WINDOWS) + +PyDoc_STRVAR(os_get_blocking__doc__, +"get_blocking($module, fd, /)\n" +"--\n" +"\n" +"Get the blocking mode of the file descriptor.\n" +"\n" +"Return False if the O_NONBLOCK flag is set, True if the flag is cleared."); + +#define OS_GET_BLOCKING_METHODDEF \ + {"get_blocking", (PyCFunction)os_get_blocking, METH_O, os_get_blocking__doc__}, + +static int +os_get_blocking_impl(PyObject *module, int fd); + +static PyObject * +os_get_blocking(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_get_blocking_impl(module, fd); + 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_blocking__doc__, +"set_blocking($module, fd, blocking, /)\n" +"--\n" +"\n" +"Set the blocking mode of the specified file descriptor.\n" +"\n" +"Set the O_NONBLOCK flag if blocking is False,\n" +"clear the O_NONBLOCK flag otherwise."); + +#define OS_SET_BLOCKING_METHODDEF \ + {"set_blocking", (PyCFunction)(void(*)(void))os_set_blocking, METH_FASTCALL, os_set_blocking__doc__}, + +static PyObject * +os_set_blocking_impl(PyObject *module, int fd, int blocking); + +static PyObject * +os_set_blocking(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int blocking; + + if (!_PyArg_CheckPositional("set_blocking", 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; + } + blocking = _PyLong_AsInt(args[1]); + if (blocking == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_set_blocking_impl(module, fd, blocking); + +exit: + return return_value; +} + +#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 \ + {"is_symlink", (PyCFunction)os_DirEntry_is_symlink, METH_NOARGS, os_DirEntry_is_symlink__doc__}, + +static int +os_DirEntry_is_symlink_impl(DirEntry *self); + +static PyObject * +os_DirEntry_is_symlink(DirEntry *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = os_DirEntry_is_symlink_impl(self); + 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_FASTCALL|METH_KEYWORDS, os_DirEntry_stat__doc__}, + +static PyObject * +os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks); + +static PyObject * +os_DirEntry_stat(DirEntry *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"follow_symlinks", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int follow_symlinks = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = os_DirEntry_stat_impl(self, 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 \ + {"is_dir", (PyCFunction)(void(*)(void))os_DirEntry_is_dir, METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_dir__doc__}, + +static int +os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks); + +static PyObject * +os_DirEntry_is_dir(DirEntry *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"follow_symlinks", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "is_dir", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int follow_symlinks = 1; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: + _return_value = os_DirEntry_is_dir_impl(self, 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 \ + {"is_file", (PyCFunction)(void(*)(void))os_DirEntry_is_file, METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_file__doc__}, + +static int +os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks); + +static PyObject * +os_DirEntry_is_file(DirEntry *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"follow_symlinks", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "is_file", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int follow_symlinks = 1; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: + _return_value = os_DirEntry_is_file_impl(self, 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 \ + {"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 _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); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!path_converter(args[0], &path)) { + 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 \ + {"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 _PyArg_Parser _parser = {NULL, _keywords, "fspath", 0}; + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + size = ival; + } + if (!noptargs) { + goto skip_optional_pos; + } + 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; + } +skip_optional_pos: + 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__, +"_add_dll_directory($module, /, path)\n" +"--\n" +"\n" +"Add a path to the DLL search path.\n" +"\n" +"This search path is used when resolving dependencies for imported\n" +"extension modules (the module itself is resolved through sys.path),\n" +"and also by ctypes.\n" +"\n" +"Returns an opaque value that may be passed to os.remove_dll_directory\n" +"to remove this directory from the search path."); + +#define OS__ADD_DLL_DIRECTORY_METHODDEF \ + {"_add_dll_directory", (PyCFunction)(void(*)(void))os__add_dll_directory, METH_FASTCALL|METH_KEYWORDS, os__add_dll_directory__doc__}, + +static PyObject * +os__add_dll_directory_impl(PyObject *module, path_t *path); + +static PyObject * +os__add_dll_directory(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, "_add_dll_directory", 0}; + PyObject *argsbuf[1]; + path_t path = PATH_T_INITIALIZE("_add_dll_directory", "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__add_dll_directory_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__remove_dll_directory__doc__, +"_remove_dll_directory($module, /, cookie)\n" +"--\n" +"\n" +"Removes a path from the DLL search path.\n" +"\n" +"The parameter is an opaque value that was returned from\n" +"os.add_dll_directory. You can only remove directories that you added\n" +"yourself."); + +#define OS__REMOVE_DLL_DIRECTORY_METHODDEF \ + {"_remove_dll_directory", (PyCFunction)(void(*)(void))os__remove_dll_directory, METH_FASTCALL|METH_KEYWORDS, os__remove_dll_directory__doc__}, + +static PyObject * +os__remove_dll_directory_impl(PyObject *module, PyObject *cookie); + +static PyObject * +os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"cookie", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_remove_dll_directory", 0}; + PyObject *argsbuf[1]; + PyObject *cookie; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + cookie = args[0]; + return_value = os__remove_dll_directory_impl(module, cookie); + +exit: + return return_value; +} + +#endif /* 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__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_POSIX_SPAWN_METHODDEF + #define OS_POSIX_SPAWN_METHODDEF +#endif /* !defined(OS_POSIX_SPAWN_METHODDEF) */ + +#ifndef OS_POSIX_SPAWNP_METHODDEF + #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_GETGROUPS_METHODDEF + #define OS_GETGROUPS_METHODDEF +#endif /* !defined(OS_GETGROUPS_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_READLINK_METHODDEF + #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__FCOPYFILE_METHODDEF + #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_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_MEMFD_CREATE_METHODDEF + #define OS_MEMFD_CREATE_METHODDEF +#endif /* !defined(OS_MEMFD_CREATE_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) */ + +#ifndef OS_SET_BLOCKING_METHODDEF + #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__ADD_DLL_DIRECTORY_METHODDEF + #define OS__ADD_DLL_DIRECTORY_METHODDEF +#endif /* !defined(OS__ADD_DLL_DIRECTORY_METHODDEF) */ + +#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF + #define OS__REMOVE_DLL_DIRECTORY_METHODDEF +#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ +/*[clinic end generated code: output=579785e080461faa input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/pwdmodule.c.h b/python/Modules/clinic/pwdmodule.c.h new file mode 100755 index 0000000..cb83062 --- /dev/null +++ b/python/Modules/clinic/pwdmodule.c.h @@ -0,0 +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__, +"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 * +pwd_getpwnam_impl(PyObject *module, PyObject *name); + +static PyObject * +pwd_getpwnam(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("getpwnam", "argument", "str", arg); + 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) */ +/*[clinic end generated code: output=7fceab7f1a85da36 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/pyexpat.c.h b/python/Modules/clinic/pyexpat.c.h new file mode 100755 index 0000000..ee5907c --- /dev/null +++ b/python/Modules/clinic/pyexpat.c.h @@ -0,0 +1,405 @@ +/*[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; + + if (!_PyArg_CheckPositional("Parse", nargs, 1, 2)) { + goto exit; + } + data = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + isfinal = _PyLong_AsInt(args[1]); + if (isfinal == -1 && PyErr_Occurred()) { + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("SetBase", "argument", "str", arg); + goto exit; + } + Py_ssize_t base_length; + base = PyUnicode_AsUTF8AndSize(arg, &base_length); + if (base == NULL) { + goto exit; + } + if (strlen(base) != (size_t)base_length) { + 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__, +"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 \ + {"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; + + if (!_PyArg_CheckPositional("ExternalEntityParserCreate", nargs, 1, 2)) { + goto exit; + } + if (args[0] == Py_None) { + context = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t context_length; + context = PyUnicode_AsUTF8AndSize(args[0], &context_length); + if (context == NULL) { + goto exit; + } + if (strlen(context) != (size_t)context_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 1", "str or None", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("UseForeignDTD", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { + 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" +" intern=)\n" +"--\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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (args[0] == Py_None) { + encoding = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[0], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("ParserCreate", "argument 'encoding'", "str or None", args[0]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[1]) { + if (args[1] == Py_None) { + namespace_separator = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t namespace_separator_length; + namespace_separator = PyUnicode_AsUTF8AndSize(args[1], &namespace_separator_length); + if (namespace_separator == NULL) { + goto exit; + } + if (strlen(namespace_separator) != (size_t)namespace_separator_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("ParserCreate", "argument 'namespace_separator'", "str or None", args[1]); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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) */ +/*[clinic end generated code: output=68ce25024280af41 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/resource.c.h b/python/Modules/clinic/resource.c.h new file mode 100755 index 0000000..80efb71 --- /dev/null +++ b/python/Modules/clinic/resource.c.h @@ -0,0 +1,181 @@ +/*[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; + } + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("setrlimit", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + resource = _PyLong_AsInt(args[0]); + if (resource == -1 && PyErr_Occurred()) { + 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) */ +/*[clinic end generated code: output=ef3034f291156a34 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/selectmodule.c.h b/python/Modules/clinic/selectmodule.c.h new file mode 100755 index 0000000..a9e1484 --- /dev/null +++ b/python/Modules/clinic/selectmodule.c.h @@ -0,0 +1,1222 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(select_select__doc__, +"select($module, rlist, wlist, xlist, timeout=None, /)\n" +"--\n" +"\n" +"Wait until one or more file descriptors are ready for some kind of I/O.\n" +"\n" +"The first three arguments are iterables of file descriptors to be waited for:\n" +"rlist -- wait until ready for reading\n" +"wlist -- wait until ready for writing\n" +"xlist -- wait for an \"exceptional condition\"\n" +"If only one kind of condition is required, pass [] for the other lists.\n" +"\n" +"A file descriptor is either a socket or file object, or a small integer\n" +"gotten from a fileno() method call on one of those.\n" +"\n" +"The optional 4th argument specifies a timeout in seconds; it may be\n" +"a floating point number to specify fractions of seconds. If it is absent\n" +"or None, the call will never time out.\n" +"\n" +"The return value is a tuple of three lists corresponding to the first three\n" +"arguments; each contains the subset of the corresponding file descriptors\n" +"that are ready.\n" +"\n" +"*** IMPORTANT NOTICE ***\n" +"On Windows, only sockets are supported; on Unix, all file\n" +"descriptors can be used."); + +#define SELECT_SELECT_METHODDEF \ + {"select", (PyCFunction)(void(*)(void))select_select, METH_FASTCALL, select_select__doc__}, + +static PyObject * +select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, + PyObject *xlist, PyObject *timeout_obj); + +static PyObject * +select_select(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *rlist; + PyObject *wlist; + PyObject *xlist; + PyObject *timeout_obj = Py_None; + + if (!_PyArg_CheckPositional("select", nargs, 3, 4)) { + goto exit; + } + rlist = args[0]; + wlist = args[1]; + xlist = args[2]; + if (nargs < 4) { + goto skip_optional; + } + timeout_obj = args[3]; +skip_optional: + return_value = select_select_impl(module, rlist, wlist, xlist, timeout_obj); + +exit: + return return_value; +} + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_register__doc__, +"register($self, fd,\n" +" eventmask=select.POLLIN | select.POLLPRI | select.POLLOUT, /)\n" +"--\n" +"\n" +"Register a file descriptor with the polling object.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_POLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)(void(*)(void))select_poll_register, METH_FASTCALL, select_poll_register__doc__}, + +static PyObject * +select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask); + +static PyObject * +select_poll_register(pollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!_PyArg_CheckPositional("register", nargs, 1, 2)) { + goto exit; + } + if (!fildes_converter(args[0], &fd)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) { + goto exit; + } +skip_optional: + return_value = select_poll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_modify__doc__, +"modify($self, fd, eventmask, /)\n" +"--\n" +"\n" +"Modify an already registered file descriptor.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" a bitmask describing the type of events to check for"); + +#define SELECT_POLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)(void(*)(void))select_poll_modify, METH_FASTCALL, select_poll_modify__doc__}, + +static PyObject * +select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask); + +static PyObject * +select_poll_modify(pollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask; + + if (!_PyArg_CheckPositional("modify", nargs, 2, 2)) { + goto exit; + } + if (!fildes_converter(args[0], &fd)) { + goto exit; + } + if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) { + goto exit; + } + return_value = select_poll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_unregister__doc__, +"unregister($self, fd, /)\n" +"--\n" +"\n" +"Remove a file descriptor being tracked by the polling object."); + +#define SELECT_POLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_poll_unregister, METH_O, select_poll_unregister__doc__}, + +static PyObject * +select_poll_unregister_impl(pollObject *self, int fd); + +static PyObject * +select_poll_unregister(pollObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!fildes_converter(arg, &fd)) { + goto exit; + } + return_value = select_poll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll_poll__doc__, +"poll($self, timeout=None, /)\n" +"--\n" +"\n" +"Polls the set of registered file descriptors.\n" +"\n" +"Returns a list containing any descriptors that have events or errors to\n" +"report, as a list of (fd, event) 2-tuples."); + +#define SELECT_POLL_POLL_METHODDEF \ + {"poll", (PyCFunction)(void(*)(void))select_poll_poll, METH_FASTCALL, select_poll_poll__doc__}, + +static PyObject * +select_poll_poll_impl(pollObject *self, PyObject *timeout_obj); + +static PyObject * +select_poll_poll(pollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *timeout_obj = Py_None; + + if (!_PyArg_CheckPositional("poll", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + timeout_obj = args[0]; +skip_optional: + return_value = select_poll_poll_impl(self, timeout_obj); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_register__doc__, +"register($self, fd,\n" +" eventmask=select.POLLIN | select.POLLPRI | select.POLLOUT, /)\n" +"--\n" +"\n" +"Register a file descriptor with the polling object.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_DEVPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)(void(*)(void))select_devpoll_register, METH_FASTCALL, select_devpoll_register__doc__}, + +static PyObject * +select_devpoll_register_impl(devpollObject *self, int fd, + unsigned short eventmask); + +static PyObject * +select_devpoll_register(devpollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!_PyArg_CheckPositional("register", nargs, 1, 2)) { + goto exit; + } + if (!fildes_converter(args[0], &fd)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) { + goto exit; + } +skip_optional: + return_value = select_devpoll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_modify__doc__, +"modify($self, fd,\n" +" eventmask=select.POLLIN | select.POLLPRI | select.POLLOUT, /)\n" +"--\n" +"\n" +"Modify a possible already registered file descriptor.\n" +"\n" +" fd\n" +" either an integer, or an object with a fileno() method returning\n" +" an int\n" +" eventmask\n" +" an optional bitmask describing the type of events to check for"); + +#define SELECT_DEVPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)(void(*)(void))select_devpoll_modify, METH_FASTCALL, select_devpoll_modify__doc__}, + +static PyObject * +select_devpoll_modify_impl(devpollObject *self, int fd, + unsigned short eventmask); + +static PyObject * +select_devpoll_modify(devpollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; + + if (!_PyArg_CheckPositional("modify", nargs, 1, 2)) { + goto exit; + } + if (!fildes_converter(args[0], &fd)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyLong_UnsignedShort_Converter(args[1], &eventmask)) { + goto exit; + } +skip_optional: + return_value = select_devpoll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_unregister__doc__, +"unregister($self, fd, /)\n" +"--\n" +"\n" +"Remove a file descriptor being tracked by the polling object."); + +#define SELECT_DEVPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)select_devpoll_unregister, METH_O, select_devpoll_unregister__doc__}, + +static PyObject * +select_devpoll_unregister_impl(devpollObject *self, int fd); + +static PyObject * +select_devpoll_unregister(devpollObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!fildes_converter(arg, &fd)) { + goto exit; + } + return_value = select_devpoll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_poll__doc__, +"poll($self, timeout=None, /)\n" +"--\n" +"\n" +"Polls the set of registered file descriptors.\n" +"\n" +"Returns a list containing any descriptors that have events or errors to\n" +"report, as a list of (fd, event) 2-tuples."); + +#define SELECT_DEVPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)(void(*)(void))select_devpoll_poll, METH_FASTCALL, select_devpoll_poll__doc__}, + +static PyObject * +select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj); + +static PyObject * +select_devpoll_poll(devpollObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *timeout_obj = Py_None; + + if (!_PyArg_CheckPositional("poll", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + timeout_obj = args[0]; +skip_optional: + return_value = select_devpoll_poll_impl(self, timeout_obj); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the devpoll file descriptor.\n" +"\n" +"Further operations on the devpoll object will raise an exception."); + +#define SELECT_DEVPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_devpoll_close, METH_NOARGS, select_devpoll_close__doc__}, + +static PyObject * +select_devpoll_close_impl(devpollObject *self); + +static PyObject * +select_devpoll_close(devpollObject *self, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_close_impl(self); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the file descriptor."); + +#define SELECT_DEVPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_devpoll_fileno, METH_NOARGS, select_devpoll_fileno__doc__}, + +static PyObject * +select_devpoll_fileno_impl(devpollObject *self); + +static PyObject * +select_devpoll_fileno(devpollObject *self, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_fileno_impl(self); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) + +PyDoc_STRVAR(select_poll__doc__, +"poll($module, /)\n" +"--\n" +"\n" +"Returns a polling object.\n" +"\n" +"This object supports registering and unregistering file descriptors, and then\n" +"polling them for I/O events."); + +#define SELECT_POLL_METHODDEF \ + {"poll", (PyCFunction)select_poll, METH_NOARGS, select_poll__doc__}, + +static PyObject * +select_poll_impl(PyObject *module); + +static PyObject * +select_poll(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return select_poll_impl(module); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) */ + +#if (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) + +PyDoc_STRVAR(select_devpoll__doc__, +"devpoll($module, /)\n" +"--\n" +"\n" +"Returns a polling object.\n" +"\n" +"This object supports registering and unregistering file descriptors, and then\n" +"polling them for I/O events."); + +#define SELECT_DEVPOLL_METHODDEF \ + {"devpoll", (PyCFunction)select_devpoll, METH_NOARGS, select_devpoll__doc__}, + +static PyObject * +select_devpoll_impl(PyObject *module); + +static PyObject * +select_devpoll(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return select_devpoll_impl(module); +} + +#endif /* (defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)) && defined(HAVE_SYS_DEVPOLL_H) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll__doc__, +"epoll(sizehint=-1, flags=0)\n" +"--\n" +"\n" +"Returns an epolling object.\n" +"\n" +" sizehint\n" +" The expected number of events to be registered. It must be positive,\n" +" or -1 to use the default. It is only used on older systems where\n" +" epoll_create1() is not available; otherwise it has no effect (though its\n" +" value is still checked).\n" +" flags\n" +" Deprecated and completely ignored. However, when supplied, its value\n" +" must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised."); + +static PyObject * +select_epoll_impl(PyTypeObject *type, int sizehint, int flags); + +static PyObject * +select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sizehint", "flags", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "epoll", 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; + int sizehint = -1; + int flags = 0; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + if (PyFloat_Check(fastargs[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + sizehint = _PyLong_AsInt(fastargs[0]); + if (sizehint == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(fastargs[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = _PyLong_AsInt(fastargs[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = select_epoll_impl(type, sizehint, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the epoll control file descriptor.\n" +"\n" +"Further operations on the epoll object will raise an exception."); + +#define SELECT_EPOLL_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_epoll_close, METH_NOARGS, select_epoll_close__doc__}, + +static PyObject * +select_epoll_close_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_close(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll_close_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the epoll control file descriptor."); + +#define SELECT_EPOLL_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_epoll_fileno, METH_NOARGS, select_epoll_fileno__doc__}, + +static PyObject * +select_epoll_fileno_impl(pyEpoll_Object *self); + +static PyObject * +select_epoll_fileno(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll_fileno_impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_fromfd__doc__, +"fromfd($type, fd, /)\n" +"--\n" +"\n" +"Create an epoll object from a given control fd."); + +#define SELECT_EPOLL_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_epoll_fromfd, METH_O|METH_CLASS, select_epoll_fromfd__doc__}, + +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *type, int fd); + +static PyObject * +select_epoll_fromfd(PyTypeObject *type, 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 = select_epoll_fromfd_impl(type, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_register__doc__, +"register($self, /, fd,\n" +" eventmask=select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT)\n" +"--\n" +"\n" +"Registers a new fd or raises an OSError if the fd is already registered.\n" +"\n" +" fd\n" +" the target file descriptor of the operation\n" +" eventmask\n" +" a bit set composed of the various EPOLL constants\n" +"\n" +"The epoll interface supports all file descriptors that support poll."); + +#define SELECT_EPOLL_REGISTER_METHODDEF \ + {"register", (PyCFunction)(void(*)(void))select_epoll_register, METH_FASTCALL|METH_KEYWORDS, select_epoll_register__doc__}, + +static PyObject * +select_epoll_register_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask); + +static PyObject * +select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "eventmask", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "register", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int fd; + unsigned int eventmask = EPOLLIN | EPOLLPRI | EPOLLOUT; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!fildes_converter(args[0], &fd)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (eventmask == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = select_epoll_register_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_modify__doc__, +"modify($self, /, fd, eventmask)\n" +"--\n" +"\n" +"Modify event mask for a registered file descriptor.\n" +"\n" +" fd\n" +" the target file descriptor of the operation\n" +" eventmask\n" +" a bit set composed of the various EPOLL constants"); + +#define SELECT_EPOLL_MODIFY_METHODDEF \ + {"modify", (PyCFunction)(void(*)(void))select_epoll_modify, METH_FASTCALL|METH_KEYWORDS, select_epoll_modify__doc__}, + +static PyObject * +select_epoll_modify_impl(pyEpoll_Object *self, int fd, + unsigned int eventmask); + +static PyObject * +select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "eventmask", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "modify", 0}; + PyObject *argsbuf[2]; + int fd; + unsigned int eventmask; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!fildes_converter(args[0], &fd)) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (eventmask == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } + return_value = select_epoll_modify_impl(self, fd, eventmask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_unregister__doc__, +"unregister($self, /, fd)\n" +"--\n" +"\n" +"Remove a registered file descriptor from the epoll object.\n" +"\n" +" fd\n" +" the target file descriptor of the operation"); + +#define SELECT_EPOLL_UNREGISTER_METHODDEF \ + {"unregister", (PyCFunction)(void(*)(void))select_epoll_unregister, METH_FASTCALL|METH_KEYWORDS, select_epoll_unregister__doc__}, + +static PyObject * +select_epoll_unregister_impl(pyEpoll_Object *self, int fd); + +static PyObject * +select_epoll_unregister(pyEpoll_Object *self, 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, "unregister", 0}; + PyObject *argsbuf[1]; + int fd; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!fildes_converter(args[0], &fd)) { + goto exit; + } + return_value = select_epoll_unregister_impl(self, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll_poll__doc__, +"poll($self, /, timeout=None, maxevents=-1)\n" +"--\n" +"\n" +"Wait for events on the epoll file descriptor.\n" +"\n" +" timeout\n" +" the maximum time to wait in seconds (as float);\n" +" a timeout of None or -1 makes poll wait indefinitely\n" +" maxevents\n" +" the maximum number of events returned; -1 means no limit\n" +"\n" +"Returns a list containing any descriptors that have events to report,\n" +"as a list of (fd, events) 2-tuples."); + +#define SELECT_EPOLL_POLL_METHODDEF \ + {"poll", (PyCFunction)(void(*)(void))select_epoll_poll, METH_FASTCALL|METH_KEYWORDS, select_epoll_poll__doc__}, + +static PyObject * +select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, + int maxevents); + +static PyObject * +select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"timeout", "maxevents", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "poll", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *timeout_obj = Py_None; + int maxevents = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + timeout_obj = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + maxevents = _PyLong_AsInt(args[1]); + if (maxevents == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = select_epoll_poll_impl(self, timeout_obj, maxevents); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll___enter____doc__, +"__enter__($self, /)\n" +"--\n" +"\n"); + +#define SELECT_EPOLL___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)select_epoll___enter__, METH_NOARGS, select_epoll___enter____doc__}, + +static PyObject * +select_epoll___enter___impl(pyEpoll_Object *self); + +static PyObject * +select_epoll___enter__(pyEpoll_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_epoll___enter___impl(self); +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_EPOLL) + +PyDoc_STRVAR(select_epoll___exit____doc__, +"__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" +"--\n" +"\n"); + +#define SELECT_EPOLL___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)(void(*)(void))select_epoll___exit__, METH_FASTCALL, select_epoll___exit____doc__}, + +static PyObject * +select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb); + +static PyObject * +select_epoll___exit__(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc_type = Py_None; + PyObject *exc_value = Py_None; + PyObject *exc_tb = Py_None; + + if (!_PyArg_CheckPositional("__exit__", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + exc_type = args[0]; + if (nargs < 2) { + goto skip_optional; + } + exc_value = args[1]; + if (nargs < 3) { + goto skip_optional; + } + exc_tb = args[2]; +skip_optional: + return_value = select_epoll___exit___impl(self, exc_type, exc_value, exc_tb); + +exit: + return return_value; +} + +#endif /* defined(HAVE_EPOLL) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue__doc__, +"kqueue()\n" +"--\n" +"\n" +"Kqueue syscall wrapper.\n" +"\n" +"For example, to start watching a socket for input:\n" +">>> kq = kqueue()\n" +">>> sock = socket()\n" +">>> sock.connect((host, port))\n" +">>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n" +"\n" +"To wait one second for it to become writeable:\n" +">>> kq.control(None, 1, 1000)\n" +"\n" +"To stop listening:\n" +">>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)"); + +static PyObject * +select_kqueue_impl(PyTypeObject *type); + +static PyObject * +select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + + if ((type == &kqueue_queue_Type) && + !_PyArg_NoPositional("kqueue", args)) { + goto exit; + } + if ((type == &kqueue_queue_Type) && + !_PyArg_NoKeywords("kqueue", kwargs)) { + goto exit; + } + return_value = select_kqueue_impl(type); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the kqueue control file descriptor.\n" +"\n" +"Further operations on the kqueue object will raise an exception."); + +#define SELECT_KQUEUE_CLOSE_METHODDEF \ + {"close", (PyCFunction)select_kqueue_close, METH_NOARGS, select_kqueue_close__doc__}, + +static PyObject * +select_kqueue_close_impl(kqueue_queue_Object *self); + +static PyObject * +select_kqueue_close(kqueue_queue_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_kqueue_close_impl(self); +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the kqueue control file descriptor."); + +#define SELECT_KQUEUE_FILENO_METHODDEF \ + {"fileno", (PyCFunction)select_kqueue_fileno, METH_NOARGS, select_kqueue_fileno__doc__}, + +static PyObject * +select_kqueue_fileno_impl(kqueue_queue_Object *self); + +static PyObject * +select_kqueue_fileno(kqueue_queue_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return select_kqueue_fileno_impl(self); +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_fromfd__doc__, +"fromfd($type, fd, /)\n" +"--\n" +"\n" +"Create a kqueue object from a given control fd."); + +#define SELECT_KQUEUE_FROMFD_METHODDEF \ + {"fromfd", (PyCFunction)select_kqueue_fromfd, METH_O|METH_CLASS, select_kqueue_fromfd__doc__}, + +static PyObject * +select_kqueue_fromfd_impl(PyTypeObject *type, int fd); + +static PyObject * +select_kqueue_fromfd(PyTypeObject *type, 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 = select_kqueue_fromfd_impl(type, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#if defined(HAVE_KQUEUE) + +PyDoc_STRVAR(select_kqueue_control__doc__, +"control($self, changelist, maxevents, timeout=None, /)\n" +"--\n" +"\n" +"Calls the kernel kevent function.\n" +"\n" +" changelist\n" +" Must be an iterable of kevent objects describing the changes to be made\n" +" to the kernel\'s watch list or None.\n" +" maxevents\n" +" The maximum number of events that the kernel will return.\n" +" timeout\n" +" The maximum time to wait in seconds, or else None to wait forever.\n" +" This accepts floats for smaller timeouts, too."); + +#define SELECT_KQUEUE_CONTROL_METHODDEF \ + {"control", (PyCFunction)(void(*)(void))select_kqueue_control, METH_FASTCALL, select_kqueue_control__doc__}, + +static PyObject * +select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, + int maxevents, PyObject *otimeout); + +static PyObject * +select_kqueue_control(kqueue_queue_Object *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *changelist; + int maxevents; + PyObject *otimeout = Py_None; + + if (!_PyArg_CheckPositional("control", nargs, 2, 3)) { + goto exit; + } + changelist = args[0]; + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + maxevents = _PyLong_AsInt(args[1]); + if (maxevents == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + otimeout = args[2]; +skip_optional: + return_value = select_kqueue_control_impl(self, changelist, maxevents, otimeout); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KQUEUE) */ + +#ifndef SELECT_POLL_REGISTER_METHODDEF + #define SELECT_POLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_POLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_POLL_MODIFY_METHODDEF + #define SELECT_POLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_POLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_POLL_UNREGISTER_METHODDEF + #define SELECT_POLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_POLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_POLL_POLL_METHODDEF + #define SELECT_POLL_POLL_METHODDEF +#endif /* !defined(SELECT_POLL_POLL_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_REGISTER_METHODDEF + #define SELECT_DEVPOLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_MODIFY_METHODDEF + #define SELECT_DEVPOLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_UNREGISTER_METHODDEF + #define SELECT_DEVPOLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_POLL_METHODDEF + #define SELECT_DEVPOLL_POLL_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_POLL_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_CLOSE_METHODDEF + #define SELECT_DEVPOLL_CLOSE_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_CLOSE_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_FILENO_METHODDEF + #define SELECT_DEVPOLL_FILENO_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_FILENO_METHODDEF) */ + +#ifndef SELECT_POLL_METHODDEF + #define SELECT_POLL_METHODDEF +#endif /* !defined(SELECT_POLL_METHODDEF) */ + +#ifndef SELECT_DEVPOLL_METHODDEF + #define SELECT_DEVPOLL_METHODDEF +#endif /* !defined(SELECT_DEVPOLL_METHODDEF) */ + +#ifndef SELECT_EPOLL_CLOSE_METHODDEF + #define SELECT_EPOLL_CLOSE_METHODDEF +#endif /* !defined(SELECT_EPOLL_CLOSE_METHODDEF) */ + +#ifndef SELECT_EPOLL_FILENO_METHODDEF + #define SELECT_EPOLL_FILENO_METHODDEF +#endif /* !defined(SELECT_EPOLL_FILENO_METHODDEF) */ + +#ifndef SELECT_EPOLL_FROMFD_METHODDEF + #define SELECT_EPOLL_FROMFD_METHODDEF +#endif /* !defined(SELECT_EPOLL_FROMFD_METHODDEF) */ + +#ifndef SELECT_EPOLL_REGISTER_METHODDEF + #define SELECT_EPOLL_REGISTER_METHODDEF +#endif /* !defined(SELECT_EPOLL_REGISTER_METHODDEF) */ + +#ifndef SELECT_EPOLL_MODIFY_METHODDEF + #define SELECT_EPOLL_MODIFY_METHODDEF +#endif /* !defined(SELECT_EPOLL_MODIFY_METHODDEF) */ + +#ifndef SELECT_EPOLL_UNREGISTER_METHODDEF + #define SELECT_EPOLL_UNREGISTER_METHODDEF +#endif /* !defined(SELECT_EPOLL_UNREGISTER_METHODDEF) */ + +#ifndef SELECT_EPOLL_POLL_METHODDEF + #define SELECT_EPOLL_POLL_METHODDEF +#endif /* !defined(SELECT_EPOLL_POLL_METHODDEF) */ + +#ifndef SELECT_EPOLL___ENTER___METHODDEF + #define SELECT_EPOLL___ENTER___METHODDEF +#endif /* !defined(SELECT_EPOLL___ENTER___METHODDEF) */ + +#ifndef SELECT_EPOLL___EXIT___METHODDEF + #define SELECT_EPOLL___EXIT___METHODDEF +#endif /* !defined(SELECT_EPOLL___EXIT___METHODDEF) */ + +#ifndef SELECT_KQUEUE_CLOSE_METHODDEF + #define SELECT_KQUEUE_CLOSE_METHODDEF +#endif /* !defined(SELECT_KQUEUE_CLOSE_METHODDEF) */ + +#ifndef SELECT_KQUEUE_FILENO_METHODDEF + #define SELECT_KQUEUE_FILENO_METHODDEF +#endif /* !defined(SELECT_KQUEUE_FILENO_METHODDEF) */ + +#ifndef SELECT_KQUEUE_FROMFD_METHODDEF + #define SELECT_KQUEUE_FROMFD_METHODDEF +#endif /* !defined(SELECT_KQUEUE_FROMFD_METHODDEF) */ + +#ifndef SELECT_KQUEUE_CONTROL_METHODDEF + #define SELECT_KQUEUE_CONTROL_METHODDEF +#endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ +/*[clinic end generated code: output=86010dde10ca89c6 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/sha1module.c.h b/python/Modules/clinic/sha1module.c.h new file mode 100755 index 0000000..001c6af --- /dev/null +++ b/python/Modules/clinic/sha1module.c.h @@ -0,0 +1,104 @@ +/*[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\'\')\n" +"--\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 * +_sha1_sha1_impl(PyObject *module, PyObject *string); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sha1", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + string = args[0]; +skip_optional_pos: + return_value = _sha1_sha1_impl(module, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=1ae7e73ec84a27d5 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/sha256module.c.h b/python/Modules/clinic/sha256module.c.h new file mode 100755 index 0000000..658abb1 --- /dev/null +++ b/python/Modules/clinic/sha256module.c.h @@ -0,0 +1,141 @@ +/*[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\'\')\n" +"--\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 * +_sha256_sha256_impl(PyObject *module, PyObject *string); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sha256", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + string = args[0]; +skip_optional_pos: + return_value = _sha256_sha256_impl(module, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha256_sha224__doc__, +"sha224($module, /, string=b\'\')\n" +"--\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 * +_sha256_sha224_impl(PyObject *module, PyObject *string); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sha224", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + string = args[0]; +skip_optional_pos: + return_value = _sha256_sha224_impl(module, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=c54d0956ec88409d input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/sha512module.c.h b/python/Modules/clinic/sha512module.c.h new file mode 100755 index 0000000..459a934 --- /dev/null +++ b/python/Modules/clinic/sha512module.c.h @@ -0,0 +1,141 @@ +/*[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\'\')\n" +"--\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 * +_sha512_sha512_impl(PyObject *module, PyObject *string); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sha512", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + string = args[0]; +skip_optional_pos: + return_value = _sha512_sha512_impl(module, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha512_sha384__doc__, +"sha384($module, /, string=b\'\')\n" +"--\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 * +_sha512_sha384_impl(PyObject *module, PyObject *string); + +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", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sha384", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + string = args[0]; +skip_optional_pos: + return_value = _sha512_sha384_impl(module, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=580df4b667084a7e input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/signalmodule.c.h b/python/Modules/clinic/signalmodule.c.h new file mode 100755 index 0000000..3cb1db1 --- /dev/null +++ b/python/Modules/clinic/signalmodule.c.h @@ -0,0 +1,661 @@ +/*[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; + } + 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) */ + +PyDoc_STRVAR(signal_raise_signal__doc__, +"raise_signal($module, signalnum, /)\n" +"--\n" +"\n" +"Send a signal to the executing process."); + +#define SIGNAL_RAISE_SIGNAL_METHODDEF \ + {"raise_signal", (PyCFunction)signal_raise_signal, METH_O, signal_raise_signal__doc__}, + +static PyObject * +signal_raise_signal_impl(PyObject *module, int signalnum); + +static PyObject * +signal_raise_signal(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; + } + signalnum = _PyLong_AsInt(arg); + if (signalnum == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = signal_raise_signal_impl(module, signalnum); + +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 \ + {"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; + + if (!_PyArg_CheckPositional("signal", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + signalnum = _PyLong_AsInt(args[0]); + if (signalnum == -1 && PyErr_Occurred()) { + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + signalnum = _PyLong_AsInt(arg); + if (signalnum == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = signal_getsignal_impl(module, signalnum); + +exit: + return return_value; +} + +PyDoc_STRVAR(signal_strsignal__doc__, +"strsignal($module, signalnum, /)\n" +"--\n" +"\n" +"Return the system description of the given signal.\n" +"\n" +"The return values can be such as \"Interrupt\", \"Segmentation fault\", etc.\n" +"Returns None if the signal is not recognized."); + +#define SIGNAL_STRSIGNAL_METHODDEF \ + {"strsignal", (PyCFunction)signal_strsignal, METH_O, signal_strsignal__doc__}, + +static PyObject * +signal_strsignal_impl(PyObject *module, int signalnum); + +static PyObject * +signal_strsignal(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; + } + signalnum = _PyLong_AsInt(arg); + if (signalnum == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = signal_strsignal_impl(module, signalnum); + +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 \ + {"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; + + if (!_PyArg_CheckPositional("siginterrupt", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + signalnum = _PyLong_AsInt(args[0]); + if (signalnum == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(args[1]); + 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 \ + {"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; + + if (!_PyArg_CheckPositional("setitimer", nargs, 2, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + which = _PyLong_AsInt(args[0]); + if (which == -1 && PyErr_Occurred()) { + goto exit; + } + seconds = args[1]; + if (nargs < 3) { + goto skip_optional; + } + 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; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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) */ + +#if 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 \ + {"pthread_sigmask", (PyCFunction)(void(*)(void))signal_pthread_sigmask, METH_FASTCALL, signal_pthread_sigmask__doc__}, + +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; + sigset_t mask; + + if (!_PyArg_CheckPositional("pthread_sigmask", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + how = _PyLong_AsInt(args[0]); + if (how == -1 && PyErr_Occurred()) { + goto exit; + } + if (!_Py_Sigset_Converter(args[1], &mask)) { + goto exit; + } + return_value = signal_pthread_sigmask_impl(module, how, mask); + +exit: + return return_value; +} + +#endif /* defined(PYPTHREAD_SIGMASK) */ + +#if 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); +} + +#endif /* defined(HAVE_SIGPENDING) */ + +#if 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__}, + +static PyObject * +signal_sigwait_impl(PyObject *module, sigset_t sigset); + +static PyObject * +signal_sigwait(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + sigset_t sigset; + + if (!_Py_Sigset_Converter(arg, &sigset)) { + goto exit; + } + return_value = signal_sigwait_impl(module, sigset); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SIGWAIT) */ + +#if (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) + +PyDoc_STRVAR(signal_valid_signals__doc__, +"valid_signals($module, /)\n" +"--\n" +"\n" +"Return a set of valid signal numbers on this platform.\n" +"\n" +"The signal numbers returned by this function can be safely passed to\n" +"functions like `pthread_sigmask`."); + +#define SIGNAL_VALID_SIGNALS_METHODDEF \ + {"valid_signals", (PyCFunction)signal_valid_signals, METH_NOARGS, signal_valid_signals__doc__}, + +static PyObject * +signal_valid_signals_impl(PyObject *module); + +static PyObject * +signal_valid_signals(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return signal_valid_signals_impl(module); +} + +#endif /* (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) */ + +#if 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__}, + +static PyObject * +signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset); + +static PyObject * +signal_sigwaitinfo(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + sigset_t sigset; + + if (!_Py_Sigset_Converter(arg, &sigset)) { + goto exit; + } + return_value = signal_sigwaitinfo_impl(module, sigset); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SIGWAITINFO) */ + +#if 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 \ + {"sigtimedwait", (PyCFunction)(void(*)(void))signal_sigtimedwait, METH_FASTCALL, signal_sigtimedwait__doc__}, + +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; + sigset_t sigset; + PyObject *timeout_obj; + + if (!_PyArg_CheckPositional("sigtimedwait", nargs, 2, 2)) { + 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; +} + +#endif /* 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 \ + {"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; + + if (!_PyArg_CheckPositional("pthread_kill", nargs, 2, 2)) { + goto exit; + } + if (!PyLong_Check(args[0])) { + _PyArg_BadArgument("pthread_kill", "argument 1", "int", args[0]); + goto exit; + } + thread_id = PyLong_AsUnsignedLongMask(args[0]); + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + signalnum = _PyLong_AsInt(args[1]); + 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) */ + +#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) */ +/*[clinic end generated code: output=3320b8f73c20ba60 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/spwdmodule.c.h b/python/Modules/clinic/spwdmodule.c.h new file mode 100755 index 0000000..411d234 --- /dev/null +++ b/python/Modules/clinic/spwdmodule.c.h @@ -0,0 +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; + + if (!PyUnicode_Check(arg_)) { + _PyArg_BadArgument("getspnam", "argument", "str", arg_); + 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) */ +/*[clinic end generated code: output=eec8d0bedcd312e5 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/symtablemodule.c.h b/python/Modules/clinic/symtablemodule.c.h new file mode 100755 index 0000000..4a17f13 --- /dev/null +++ b/python/Modules/clinic/symtablemodule.c.h @@ -0,0 +1,51 @@ +/*[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 \ + {"symtable", (PyCFunction)(void(*)(void))_symtable_symtable, METH_FASTCALL, _symtable_symtable__doc__}, + +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 *source; + PyObject *filename; + const char *startstr; + + if (!_PyArg_CheckPositional("symtable", nargs, 3, 3)) { + goto exit; + } + source = args[0]; + if (!PyUnicode_FSDecoder(args[1], &filename)) { + goto exit; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("symtable", "argument 3", "str", args[2]); + goto exit; + } + Py_ssize_t startstr_length; + startstr = PyUnicode_AsUTF8AndSize(args[2], &startstr_length); + if (startstr == NULL) { + goto exit; + } + if (strlen(startstr) != (size_t)startstr_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _symtable_symtable_impl(module, source, filename, startstr); + +exit: + return return_value; +} +/*[clinic end generated code: output=a12f75cdbdf4e52a input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/unicodedata.c.h b/python/Modules/clinic/unicodedata.c.h new file mode 100755 index 0000000..4251db2 --- /dev/null +++ b/python/Modules/clinic/unicodedata.c.h @@ -0,0 +1,562 @@ +/*[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 \ + {"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; + + if (!_PyArg_CheckPositional("decimal", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("decimal", "argument 1", "a unicode character", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0])) { + goto exit; + } + if (PyUnicode_GET_LENGTH(args[0]) != 1) { + _PyArg_BadArgument("decimal", "argument 1", "a unicode character", args[0]); + goto exit; + } + chr = PyUnicode_READ_CHAR(args[0], 0); + if (nargs < 2) { + goto skip_optional; + } + 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__, +"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 \ + {"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; + + if (!_PyArg_CheckPositional("digit", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("digit", "argument 1", "a unicode character", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0])) { + goto exit; + } + if (PyUnicode_GET_LENGTH(args[0]) != 1) { + _PyArg_BadArgument("digit", "argument 1", "a unicode character", args[0]); + goto exit; + } + chr = PyUnicode_READ_CHAR(args[0], 0); + if (nargs < 2) { + goto skip_optional; + } + 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__, +"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 \ + {"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; + + if (!_PyArg_CheckPositional("numeric", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("numeric", "argument 1", "a unicode character", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0])) { + goto exit; + } + if (PyUnicode_GET_LENGTH(args[0]) != 1) { + _PyArg_BadArgument("numeric", "argument 1", "a unicode character", args[0]); + goto exit; + } + chr = PyUnicode_READ_CHAR(args[0], 0); + if (nargs < 2) { + goto skip_optional; + } + 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("category", "argument", "a unicode character", arg); + goto exit; + } + if (PyUnicode_READY(arg)) { + goto exit; + } + if (PyUnicode_GET_LENGTH(arg) != 1) { + _PyArg_BadArgument("category", "argument", "a unicode character", 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("bidirectional", "argument", "a unicode character", arg); + goto exit; + } + if (PyUnicode_READY(arg)) { + goto exit; + } + if (PyUnicode_GET_LENGTH(arg) != 1) { + _PyArg_BadArgument("bidirectional", "argument", "a unicode character", 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("combining", "argument", "a unicode character", arg); + goto exit; + } + if (PyUnicode_READY(arg)) { + goto exit; + } + if (PyUnicode_GET_LENGTH(arg) != 1) { + _PyArg_BadArgument("combining", "argument", "a unicode character", 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("mirrored", "argument", "a unicode character", arg); + goto exit; + } + if (PyUnicode_READY(arg)) { + goto exit; + } + if (PyUnicode_GET_LENGTH(arg) != 1) { + _PyArg_BadArgument("mirrored", "argument", "a unicode character", 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("east_asian_width", "argument", "a unicode character", arg); + goto exit; + } + if (PyUnicode_READY(arg)) { + goto exit; + } + if (PyUnicode_GET_LENGTH(arg) != 1) { + _PyArg_BadArgument("east_asian_width", "argument", "a unicode character", 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; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("decomposition", "argument", "a unicode character", arg); + goto exit; + } + if (PyUnicode_READY(arg)) { + goto exit; + } + if (PyUnicode_GET_LENGTH(arg) != 1) { + _PyArg_BadArgument("decomposition", "argument", "a unicode character", arg); + goto exit; + } + chr = PyUnicode_READ_CHAR(arg, 0); + 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" +"\n" +"Return whether the Unicode string unistr is in the normal form \'form\'.\n" +"\n" +"Valid values for form are \'NFC\', \'NFKC\', \'NFD\', and \'NFKD\'."); + +#define UNICODEDATA_UCD_IS_NORMALIZED_METHODDEF \ + {"is_normalized", (PyCFunction)(void(*)(void))unicodedata_UCD_is_normalized, METH_FASTCALL, unicodedata_UCD_is_normalized__doc__}, + +static PyObject * +unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, + PyObject *input); + +static PyObject * +unicodedata_UCD_is_normalized(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *form; + PyObject *input; + + if (!_PyArg_CheckPositional("is_normalized", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("is_normalized", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + form = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("is_normalized", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + input = args[1]; + return_value = unicodedata_UCD_is_normalized_impl(self, form, input); + +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 \ + {"normalize", (PyCFunction)(void(*)(void))unicodedata_UCD_normalize, METH_FASTCALL, unicodedata_UCD_normalize__doc__}, + +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 *form; + PyObject *input; + + if (!_PyArg_CheckPositional("normalize", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("normalize", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + form = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("normalize", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + input = args[1]; + 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 \ + {"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; + + if (!_PyArg_CheckPositional("name", nargs, 1, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("name", "argument 1", "a unicode character", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0])) { + goto exit; + } + if (PyUnicode_GET_LENGTH(args[0]) != 1) { + _PyArg_BadArgument("name", "argument 1", "a unicode character", args[0]); + goto exit; + } + chr = PyUnicode_READ_CHAR(args[0], 0); + if (nargs < 2) { + goto skip_optional; + } + 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; +} +/*[clinic end generated code: output=10c23477dbe8a202 input=a9049054013a1b77]*/ diff --git a/python/Modules/clinic/zlibmodule.c.h b/python/Modules/clinic/zlibmodule.c.h new file mode 100755 index 0000000..77ea04a --- /dev/null +++ b/python/Modules/clinic/zlibmodule.c.h @@ -0,0 +1,788 @@ +/*[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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("compress", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + level = _PyLong_AsInt(args[1]); + if (level == -1 && PyErr_Occurred()) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); + 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; + } + wbits = _PyLong_AsInt(args[1]); + if (wbits == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!ssize_t_converter(args[2], &bufsize)) { + 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 \ + {"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 _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}; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 6, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + level = _PyLong_AsInt(args[0]); + if (level == -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; + } + method = _PyLong_AsInt(args[1]); + if (method == -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; + } + wbits = _PyLong_AsInt(args[2]); + if (wbits == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[3]) { + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + memLevel = _PyLong_AsInt(args[3]); + if (memLevel == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[4]) { + if (PyFloat_Check(args[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + strategy = _PyLong_AsInt(args[4]); + if (strategy == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyObject_GetBuffer(args[5], &zdict, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&zdict, 'C')) { + _PyArg_BadArgument("compressobj", "argument 'zdict'", "contiguous buffer", args[5]); + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + wbits = _PyLong_AsInt(args[0]); + if (wbits == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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}; + + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + 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 \ + {"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 _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; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!ssize_t_converter(args[1], &max_length)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mode = _PyLong_AsInt(args[0]); + if (mode == -1 && PyErr_Occurred()) { + 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) + +PyDoc_STRVAR(zlib_Compress___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#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___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define ZLIB_COMPRESS___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)zlib_Compress___deepcopy__, METH_O, zlib_Compress___deepcopy____doc__}, + +#endif /* defined(HAVE_ZLIB_COPY) */ + +#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) */ + +#if defined(HAVE_ZLIB_COPY) + +PyDoc_STRVAR(zlib_Decompress___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#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___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)zlib_Decompress___deepcopy__, METH_O, 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 \ + {"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; + + if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!ssize_t_converter(args[0], &length)) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("adler32", nargs, 1, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("adler32", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (value == (unsigned int)-1 && PyErr_Occurred()) { + 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 \ + {"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; + + if (!_PyArg_CheckPositional("crc32", nargs, 1, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("crc32", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (value == (unsigned int)-1 && PyErr_Occurred()) { + 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) */ + +#ifndef ZLIB_COMPRESS___COPY___METHODDEF + #define ZLIB_COMPRESS___COPY___METHODDEF +#endif /* !defined(ZLIB_COMPRESS___COPY___METHODDEF) */ + +#ifndef ZLIB_COMPRESS___DEEPCOPY___METHODDEF + #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___DEEPCOPY___METHODDEF + #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF +#endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ +/*[clinic end generated code: output=faae38ef96b88b16 input=a9049054013a1b77]*/ diff --git a/python/Modules/cmathmodule.c b/python/Modules/cmathmodule.c new file mode 100755 index 0000000..02c09bb --- /dev/null +++ b/python/Modules/cmathmodule.c @@ -0,0 +1,1413 @@ +/* Complex math module */ + +/* much code borrowed from mathmodule.c */ + +#include "Python.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): + return 'errno = 0; PyFPE_START_PROTECT("complex function", goto exit);' + + +class Py_complex_protected_return_converter(CReturnConverter): + type = "Py_complex" + + def render(self, function, data): + self.declare(data) + data.return_conversion.append(""" +PyFPE_END_PROTECT(_return_value); +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=345daa075b1028e7]*/ + +#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) +/*[clinic end generated code: output=4effdb7d258e0d94 input=230ed3a71ecd000a]*/ +{ + Py_complex y; + + errno = 0; + PyFPE_START_PROTECT("complex function", return 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); + } + PyFPE_END_PROTECT(x) + 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; + PyFPE_START_PROTECT("arg function", return 0) + phi = c_atan2(z); + PyFPE_END_PROTECT(phi) + 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; + PyFPE_START_PROTECT("polar function", return 0) + phi = c_atan2(z); /* should not cause any exception */ + r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */ + PyFPE_END_PROTECT(r) + 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; + PyFPE_START_PROTECT("rect function", return 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; + } + + PyFPE_END_PROTECT(z) + 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; +} diff --git a/python/Modules/config.c b/python/Modules/config.c new file mode 100755 index 0000000..68a07bf --- /dev/null +++ b/python/Modules/config.c @@ -0,0 +1,114 @@ +/* Generated automatically from ./Modules/config.c.in by makesetup. */ +/* -*- 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_posix(void); +extern PyObject* PyInit_errno(void); +extern PyObject* PyInit_pwd(void); +extern PyObject* PyInit__sre(void); +extern PyObject* PyInit__codecs(void); +extern PyObject* PyInit__weakref(void); +extern PyObject* PyInit__functools(void); +extern PyObject* PyInit__operator(void); +extern PyObject* PyInit__collections(void); +extern PyObject* PyInit__abc(void); +extern PyObject* PyInit_itertools(void); +extern PyObject* PyInit_atexit(void); +extern PyObject* PyInit__signal(void); +extern PyObject* PyInit__stat(void); +extern PyObject* PyInit_time(void); +extern PyObject* PyInit__thread(void); +extern PyObject* PyInit__locale(void); +extern PyObject* PyInit__io(void); +extern PyObject* PyInit_faulthandler(void); +extern PyObject* PyInit__tracemalloc(void); +extern PyObject* PyInit__symtable(void); +extern PyObject* PyInit_xxsubtype(void); + +/* -- ADDMODULE MARKER 1 -- */ + +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[] = { + + {"posix", PyInit_posix}, + {"errno", PyInit_errno}, + {"pwd", PyInit_pwd}, + {"_sre", PyInit__sre}, + {"_codecs", PyInit__codecs}, + {"_weakref", PyInit__weakref}, + {"_functools", PyInit__functools}, + {"_operator", PyInit__operator}, + {"_collections", PyInit__collections}, + {"_abc", PyInit__abc}, + {"itertools", PyInit_itertools}, + {"atexit", PyInit_atexit}, + {"_signal", PyInit__signal}, + {"_stat", PyInit__stat}, + {"time", PyInit_time}, + {"_thread", PyInit__thread}, + {"_locale", PyInit__locale}, + {"_io", PyInit__io}, + {"faulthandler", PyInit_faulthandler}, + {"_tracemalloc", PyInit__tracemalloc}, + {"_symtable", PyInit__symtable}, + {"xxsubtype", PyInit_xxsubtype}, + +/* -- ADDMODULE MARKER 2 -- */ + + /* 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/python/Modules/config.c.in b/python/Modules/config.c.in new file mode 100755 index 0000000..d69e8e8 --- /dev/null +++ b/python/Modules/config.c.in @@ -0,0 +1,67 @@ +/* -*- 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 + + +/* -- ADDMODULE MARKER 1 -- */ + +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[] = { + +/* -- ADDMODULE MARKER 2 -- */ + + /* 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/python/Modules/errnomodule.c b/python/Modules/errnomodule.c new file mode 100755 index 0000000..06ed53a --- /dev/null +++ b/python/Modules/errnomodule.c @@ -0,0 +1,935 @@ + +/* 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 void +_inscode(PyObject *d, PyObject *de, const char *name, int code) +{ + PyObject *u = PyUnicode_FromString(name); + PyObject *v = PyLong_FromLong((long) code); + + /* Don't bother checking for errors; they'll be caught at the end + * of the module initialization function by the caller of + * initerrno(). + */ + if (u && v) { + /* insert in modules dict */ + PyDict_SetItem(d, u, v); + /* insert in errorcode dict */ + PyDict_SetItem(de, v, u); + } + Py_XDECREF(u); + Py_XDECREF(v); +} + +PyDoc_STRVAR(errno__doc__, +"This module makes available standard errno system symbols.\n\ +\n\ +The value of each symbol is the corresponding integer value,\n\ +e.g., on most systems, errno.ENOENT equals the integer 2.\n\ +\n\ +The dictionary errno.errorcode maps numeric codes to symbol names,\n\ +e.g., errno.errorcode[2] could be the string 'ENOENT'.\n\ +\n\ +Symbols that are not relevant to the underlying system are not defined.\n\ +\n\ +To map error codes to error messages, use the function os.strerror(),\n\ +e.g. os.strerror(2) could return 'No such file or directory'."); + +static struct PyModuleDef errnomodule = { + PyModuleDef_HEAD_INIT, + "errno", + errno__doc__, + -1, + errno_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_errno(void) +{ + PyObject *m, *d, *de; + m = PyModule_Create(&errnomodule); + if (m == NULL) + return NULL; + d = PyModule_GetDict(m); + de = PyDict_New(); + if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0) + return NULL; + +/* Macro so I don't have to edit each and every line below... */ +#define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code) + + /* + * 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 + inscode(d, ds, de, "ENODEV", ENODEV, "No such device"); +#endif +#ifdef ENOCSI + inscode(d, ds, de, "ENOCSI", ENOCSI, "No CSI structure available"); +#endif +#ifdef EHOSTUNREACH + inscode(d, ds, de, "EHOSTUNREACH", EHOSTUNREACH, "No route to host"); +#else +#ifdef WSAEHOSTUNREACH + inscode(d, ds, de, "EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); +#endif +#endif +#ifdef ENOMSG + inscode(d, ds, de, "ENOMSG", ENOMSG, "No message of desired type"); +#endif +#ifdef EUCLEAN + inscode(d, ds, de, "EUCLEAN", EUCLEAN, "Structure needs cleaning"); +#endif +#ifdef EL2NSYNC + inscode(d, ds, de, "EL2NSYNC", EL2NSYNC, "Level 2 not synchronized"); +#endif +#ifdef EL2HLT + inscode(d, ds, de, "EL2HLT", EL2HLT, "Level 2 halted"); +#endif +#ifdef ENODATA + inscode(d, ds, de, "ENODATA", ENODATA, "No data available"); +#endif +#ifdef ENOTBLK + inscode(d, ds, de, "ENOTBLK", ENOTBLK, "Block device required"); +#endif +#ifdef ENOSYS + inscode(d, ds, de, "ENOSYS", ENOSYS, "Function not implemented"); +#endif +#ifdef EPIPE + inscode(d, ds, de, "EPIPE", EPIPE, "Broken pipe"); +#endif +#ifdef EINVAL + inscode(d, ds, de, "EINVAL", EINVAL, "Invalid argument"); +#else +#ifdef WSAEINVAL + inscode(d, ds, de, "EINVAL", WSAEINVAL, "Invalid argument"); +#endif +#endif +#ifdef EOVERFLOW + inscode(d, ds, de, "EOVERFLOW", EOVERFLOW, "Value too large for defined data type"); +#endif +#ifdef EADV + inscode(d, ds, de, "EADV", EADV, "Advertise error"); +#endif +#ifdef EINTR + inscode(d, ds, de, "EINTR", EINTR, "Interrupted system call"); +#else +#ifdef WSAEINTR + inscode(d, ds, de, "EINTR", WSAEINTR, "Interrupted system call"); +#endif +#endif +#ifdef EUSERS + inscode(d, ds, de, "EUSERS", EUSERS, "Too many users"); +#else +#ifdef WSAEUSERS + inscode(d, ds, de, "EUSERS", WSAEUSERS, "Too many users"); +#endif +#endif +#ifdef ENOTEMPTY + inscode(d, ds, de, "ENOTEMPTY", ENOTEMPTY, "Directory not empty"); +#else +#ifdef WSAENOTEMPTY + inscode(d, ds, de, "ENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); +#endif +#endif +#ifdef ENOBUFS + inscode(d, ds, de, "ENOBUFS", ENOBUFS, "No buffer space available"); +#else +#ifdef WSAENOBUFS + inscode(d, ds, de, "ENOBUFS", WSAENOBUFS, "No buffer space available"); +#endif +#endif +#ifdef EPROTO + inscode(d, ds, de, "EPROTO", EPROTO, "Protocol error"); +#endif +#ifdef EREMOTE + inscode(d, ds, de, "EREMOTE", EREMOTE, "Object is remote"); +#else +#ifdef WSAEREMOTE + inscode(d, ds, de, "EREMOTE", WSAEREMOTE, "Object is remote"); +#endif +#endif +#ifdef ENAVAIL + inscode(d, ds, de, "ENAVAIL", ENAVAIL, "No XENIX semaphores available"); +#endif +#ifdef ECHILD + inscode(d, ds, de, "ECHILD", ECHILD, "No child processes"); +#endif +#ifdef ELOOP + inscode(d, ds, de, "ELOOP", ELOOP, "Too many symbolic links encountered"); +#else +#ifdef WSAELOOP + inscode(d, ds, de, "ELOOP", WSAELOOP, "Too many symbolic links encountered"); +#endif +#endif +#ifdef EXDEV + inscode(d, ds, de, "EXDEV", EXDEV, "Cross-device link"); +#endif +#ifdef E2BIG + inscode(d, ds, de, "E2BIG", E2BIG, "Arg list too long"); +#endif +#ifdef ESRCH + inscode(d, ds, de, "ESRCH", ESRCH, "No such process"); +#endif +#ifdef EMSGSIZE + inscode(d, ds, de, "EMSGSIZE", EMSGSIZE, "Message too long"); +#else +#ifdef WSAEMSGSIZE + inscode(d, ds, de, "EMSGSIZE", WSAEMSGSIZE, "Message too long"); +#endif +#endif +#ifdef EAFNOSUPPORT + inscode(d, ds, de, "EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol"); +#else +#ifdef WSAEAFNOSUPPORT + inscode(d, ds, de, "EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); +#endif +#endif +#ifdef EBADR + inscode(d, ds, de, "EBADR", EBADR, "Invalid request descriptor"); +#endif +#ifdef EHOSTDOWN + inscode(d, ds, de, "EHOSTDOWN", EHOSTDOWN, "Host is down"); +#else +#ifdef WSAEHOSTDOWN + inscode(d, ds, de, "EHOSTDOWN", WSAEHOSTDOWN, "Host is down"); +#endif +#endif +#ifdef EPFNOSUPPORT + inscode(d, ds, de, "EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported"); +#else +#ifdef WSAEPFNOSUPPORT + inscode(d, ds, de, "EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); +#endif +#endif +#ifdef ENOPROTOOPT + inscode(d, ds, de, "ENOPROTOOPT", ENOPROTOOPT, "Protocol not available"); +#else +#ifdef WSAENOPROTOOPT + inscode(d, ds, de, "ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); +#endif +#endif +#ifdef EBUSY + inscode(d, ds, de, "EBUSY", EBUSY, "Device or resource busy"); +#endif +#ifdef EWOULDBLOCK + inscode(d, ds, de, "EWOULDBLOCK", EWOULDBLOCK, "Operation would block"); +#else +#ifdef WSAEWOULDBLOCK + inscode(d, ds, de, "EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); +#endif +#endif +#ifdef EBADFD + inscode(d, ds, de, "EBADFD", EBADFD, "File descriptor in bad state"); +#endif +#ifdef EDOTDOT + inscode(d, ds, de, "EDOTDOT", EDOTDOT, "RFS specific error"); +#endif +#ifdef EISCONN + inscode(d, ds, de, "EISCONN", EISCONN, "Transport endpoint is already connected"); +#else +#ifdef WSAEISCONN + inscode(d, ds, de, "EISCONN", WSAEISCONN, "Transport endpoint is already connected"); +#endif +#endif +#ifdef ENOANO + inscode(d, ds, de, "ENOANO", ENOANO, "No anode"); +#endif +#ifdef ESHUTDOWN + inscode(d, ds, de, "ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown"); +#else +#ifdef WSAESHUTDOWN + inscode(d, ds, de, "ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); +#endif +#endif +#ifdef ECHRNG + inscode(d, ds, de, "ECHRNG", ECHRNG, "Channel number out of range"); +#endif +#ifdef ELIBBAD + inscode(d, ds, de, "ELIBBAD", ELIBBAD, "Accessing a corrupted shared library"); +#endif +#ifdef ENONET + inscode(d, ds, de, "ENONET", ENONET, "Machine is not on the network"); +#endif +#ifdef EBADE + inscode(d, ds, de, "EBADE", EBADE, "Invalid exchange"); +#endif +#ifdef EBADF + inscode(d, ds, de, "EBADF", EBADF, "Bad file number"); +#else +#ifdef WSAEBADF + inscode(d, ds, de, "EBADF", WSAEBADF, "Bad file number"); +#endif +#endif +#ifdef EMULTIHOP + inscode(d, ds, de, "EMULTIHOP", EMULTIHOP, "Multihop attempted"); +#endif +#ifdef EIO + inscode(d, ds, de, "EIO", EIO, "I/O error"); +#endif +#ifdef EUNATCH + inscode(d, ds, de, "EUNATCH", EUNATCH, "Protocol driver not attached"); +#endif +#ifdef EPROTOTYPE + inscode(d, ds, de, "EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket"); +#else +#ifdef WSAEPROTOTYPE + inscode(d, ds, de, "EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); +#endif +#endif +#ifdef ENOSPC + inscode(d, ds, de, "ENOSPC", ENOSPC, "No space left on device"); +#endif +#ifdef ENOEXEC + inscode(d, ds, de, "ENOEXEC", ENOEXEC, "Exec format error"); +#endif +#ifdef EALREADY + inscode(d, ds, de, "EALREADY", EALREADY, "Operation already in progress"); +#else +#ifdef WSAEALREADY + inscode(d, ds, de, "EALREADY", WSAEALREADY, "Operation already in progress"); +#endif +#endif +#ifdef ENETDOWN + inscode(d, ds, de, "ENETDOWN", ENETDOWN, "Network is down"); +#else +#ifdef WSAENETDOWN + inscode(d, ds, de, "ENETDOWN", WSAENETDOWN, "Network is down"); +#endif +#endif +#ifdef ENOTNAM + inscode(d, ds, de, "ENOTNAM", ENOTNAM, "Not a XENIX named type file"); +#endif +#ifdef EACCES + inscode(d, ds, de, "EACCES", EACCES, "Permission denied"); +#else +#ifdef WSAEACCES + inscode(d, ds, de, "EACCES", WSAEACCES, "Permission denied"); +#endif +#endif +#ifdef ELNRNG + inscode(d, ds, de, "ELNRNG", ELNRNG, "Link number out of range"); +#endif +#ifdef EILSEQ + inscode(d, ds, de, "EILSEQ", EILSEQ, "Illegal byte sequence"); +#endif +#ifdef ENOTDIR + inscode(d, ds, de, "ENOTDIR", ENOTDIR, "Not a directory"); +#endif +#ifdef ENOTUNIQ + inscode(d, ds, de, "ENOTUNIQ", ENOTUNIQ, "Name not unique on network"); +#endif +#ifdef EPERM + inscode(d, ds, de, "EPERM", EPERM, "Operation not permitted"); +#endif +#ifdef EDOM + inscode(d, ds, de, "EDOM", EDOM, "Math argument out of domain of func"); +#endif +#ifdef EXFULL + inscode(d, ds, de, "EXFULL", EXFULL, "Exchange full"); +#endif +#ifdef ECONNREFUSED + inscode(d, ds, de, "ECONNREFUSED", ECONNREFUSED, "Connection refused"); +#else +#ifdef WSAECONNREFUSED + inscode(d, ds, de, "ECONNREFUSED", WSAECONNREFUSED, "Connection refused"); +#endif +#endif +#ifdef EISDIR + inscode(d, ds, de, "EISDIR", EISDIR, "Is a directory"); +#endif +#ifdef EPROTONOSUPPORT + inscode(d, ds, de, "EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported"); +#else +#ifdef WSAEPROTONOSUPPORT + inscode(d, ds, de, "EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); +#endif +#endif +#ifdef EROFS + inscode(d, ds, de, "EROFS", EROFS, "Read-only file system"); +#endif +#ifdef EADDRNOTAVAIL + inscode(d, ds, de, "EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address"); +#else +#ifdef WSAEADDRNOTAVAIL + inscode(d, ds, de, "EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); +#endif +#endif +#ifdef EIDRM + inscode(d, ds, de, "EIDRM", EIDRM, "Identifier removed"); +#endif +#ifdef ECOMM + inscode(d, ds, de, "ECOMM", ECOMM, "Communication error on send"); +#endif +#ifdef ESRMNT + inscode(d, ds, de, "ESRMNT", ESRMNT, "Srmount error"); +#endif +#ifdef EREMOTEIO + inscode(d, ds, de, "EREMOTEIO", EREMOTEIO, "Remote I/O error"); +#endif +#ifdef EL3RST + inscode(d, ds, de, "EL3RST", EL3RST, "Level 3 reset"); +#endif +#ifdef EBADMSG + inscode(d, ds, de, "EBADMSG", EBADMSG, "Not a data message"); +#endif +#ifdef ENFILE + inscode(d, ds, de, "ENFILE", ENFILE, "File table overflow"); +#endif +#ifdef ELIBMAX + inscode(d, ds, de, "ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries"); +#endif +#ifdef ESPIPE + inscode(d, ds, de, "ESPIPE", ESPIPE, "Illegal seek"); +#endif +#ifdef ENOLINK + inscode(d, ds, de, "ENOLINK", ENOLINK, "Link has been severed"); +#endif +#ifdef ENETRESET + inscode(d, ds, de, "ENETRESET", ENETRESET, "Network dropped connection because of reset"); +#else +#ifdef WSAENETRESET + inscode(d, ds, de, "ENETRESET", WSAENETRESET, "Network dropped connection because of reset"); +#endif +#endif +#ifdef ETIMEDOUT + inscode(d, ds, de, "ETIMEDOUT", ETIMEDOUT, "Connection timed out"); +#else +#ifdef WSAETIMEDOUT + inscode(d, ds, de, "ETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); +#endif +#endif +#ifdef ENOENT + inscode(d, ds, de, "ENOENT", ENOENT, "No such file or directory"); +#endif +#ifdef EEXIST + inscode(d, ds, de, "EEXIST", EEXIST, "File exists"); +#endif +#ifdef EDQUOT + inscode(d, ds, de, "EDQUOT", EDQUOT, "Quota exceeded"); +#else +#ifdef WSAEDQUOT + inscode(d, ds, de, "EDQUOT", WSAEDQUOT, "Quota exceeded"); +#endif +#endif +#ifdef ENOSTR + inscode(d, ds, de, "ENOSTR", ENOSTR, "Device not a stream"); +#endif +#ifdef EBADSLT + inscode(d, ds, de, "EBADSLT", EBADSLT, "Invalid slot"); +#endif +#ifdef EBADRQC + inscode(d, ds, de, "EBADRQC", EBADRQC, "Invalid request code"); +#endif +#ifdef ELIBACC + inscode(d, ds, de, "ELIBACC", ELIBACC, "Can not access a needed shared library"); +#endif +#ifdef EFAULT + inscode(d, ds, de, "EFAULT", EFAULT, "Bad address"); +#else +#ifdef WSAEFAULT + inscode(d, ds, de, "EFAULT", WSAEFAULT, "Bad address"); +#endif +#endif +#ifdef EFBIG + inscode(d, ds, de, "EFBIG", EFBIG, "File too large"); +#endif +#ifdef EDEADLK + inscode(d, ds, de, "EDEADLK", EDEADLK, "Resource deadlock would occur"); +#endif +#ifdef ENOTCONN + inscode(d, ds, de, "ENOTCONN", ENOTCONN, "Transport endpoint is not connected"); +#else +#ifdef WSAENOTCONN + inscode(d, ds, de, "ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); +#endif +#endif +#ifdef EDESTADDRREQ + inscode(d, ds, de, "EDESTADDRREQ", EDESTADDRREQ, "Destination address required"); +#else +#ifdef WSAEDESTADDRREQ + inscode(d, ds, de, "EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); +#endif +#endif +#ifdef ELIBSCN + inscode(d, ds, de, "ELIBSCN", ELIBSCN, ".lib section in a.out corrupted"); +#endif +#ifdef ENOLCK + inscode(d, ds, de, "ENOLCK", ENOLCK, "No record locks available"); +#endif +#ifdef EISNAM + inscode(d, ds, de, "EISNAM", EISNAM, "Is a named type file"); +#endif +#ifdef ECONNABORTED + inscode(d, ds, de, "ECONNABORTED", ECONNABORTED, "Software caused connection abort"); +#else +#ifdef WSAECONNABORTED + inscode(d, ds, de, "ECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); +#endif +#endif +#ifdef ENETUNREACH + inscode(d, ds, de, "ENETUNREACH", ENETUNREACH, "Network is unreachable"); +#else +#ifdef WSAENETUNREACH + inscode(d, ds, de, "ENETUNREACH", WSAENETUNREACH, "Network is unreachable"); +#endif +#endif +#ifdef ESTALE + inscode(d, ds, de, "ESTALE", ESTALE, "Stale NFS file handle"); +#else +#ifdef WSAESTALE + inscode(d, ds, de, "ESTALE", WSAESTALE, "Stale NFS file handle"); +#endif +#endif +#ifdef ENOSR + inscode(d, ds, de, "ENOSR", ENOSR, "Out of streams resources"); +#endif +#ifdef ENOMEM + inscode(d, ds, de, "ENOMEM", ENOMEM, "Out of memory"); +#endif +#ifdef ENOTSOCK + inscode(d, ds, de, "ENOTSOCK", ENOTSOCK, "Socket operation on non-socket"); +#else +#ifdef WSAENOTSOCK + inscode(d, ds, de, "ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); +#endif +#endif +#ifdef ESTRPIPE + inscode(d, ds, de, "ESTRPIPE", ESTRPIPE, "Streams pipe error"); +#endif +#ifdef EMLINK + inscode(d, ds, de, "EMLINK", EMLINK, "Too many links"); +#endif +#ifdef ERANGE + inscode(d, ds, de, "ERANGE", ERANGE, "Math result not representable"); +#endif +#ifdef ELIBEXEC + inscode(d, ds, de, "ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly"); +#endif +#ifdef EL3HLT + inscode(d, ds, de, "EL3HLT", EL3HLT, "Level 3 halted"); +#endif +#ifdef ECONNRESET + inscode(d, ds, de, "ECONNRESET", ECONNRESET, "Connection reset by peer"); +#else +#ifdef WSAECONNRESET + inscode(d, ds, de, "ECONNRESET", WSAECONNRESET, "Connection reset by peer"); +#endif +#endif +#ifdef EADDRINUSE + inscode(d, ds, de, "EADDRINUSE", EADDRINUSE, "Address already in use"); +#else +#ifdef WSAEADDRINUSE + inscode(d, ds, de, "EADDRINUSE", WSAEADDRINUSE, "Address already in use"); +#endif +#endif +#ifdef EOPNOTSUPP + inscode(d, ds, de, "EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint"); +#else +#ifdef WSAEOPNOTSUPP + inscode(d, ds, de, "EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); +#endif +#endif +#ifdef EREMCHG + inscode(d, ds, de, "EREMCHG", EREMCHG, "Remote address changed"); +#endif +#ifdef EAGAIN + inscode(d, ds, de, "EAGAIN", EAGAIN, "Try again"); +#endif +#ifdef ENAMETOOLONG + inscode(d, ds, de, "ENAMETOOLONG", ENAMETOOLONG, "File name too long"); +#else +#ifdef WSAENAMETOOLONG + inscode(d, ds, de, "ENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); +#endif +#endif +#ifdef ENOTTY + inscode(d, ds, de, "ENOTTY", ENOTTY, "Not a typewriter"); +#endif +#ifdef ERESTART + inscode(d, ds, de, "ERESTART", ERESTART, "Interrupted system call should be restarted"); +#endif +#ifdef ESOCKTNOSUPPORT + inscode(d, ds, de, "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported"); +#else +#ifdef WSAESOCKTNOSUPPORT + inscode(d, ds, de, "ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); +#endif +#endif +#ifdef ETIME + inscode(d, ds, de, "ETIME", ETIME, "Timer expired"); +#endif +#ifdef EBFONT + inscode(d, ds, de, "EBFONT", EBFONT, "Bad font file format"); +#endif +#ifdef EDEADLOCK + inscode(d, ds, de, "EDEADLOCK", EDEADLOCK, "Error EDEADLOCK"); +#endif +#ifdef ETOOMANYREFS + inscode(d, ds, de, "ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice"); +#else +#ifdef WSAETOOMANYREFS + inscode(d, ds, de, "ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); +#endif +#endif +#ifdef EMFILE + inscode(d, ds, de, "EMFILE", EMFILE, "Too many open files"); +#else +#ifdef WSAEMFILE + inscode(d, ds, de, "EMFILE", WSAEMFILE, "Too many open files"); +#endif +#endif +#ifdef ETXTBSY + inscode(d, ds, de, "ETXTBSY", ETXTBSY, "Text file busy"); +#endif +#ifdef EINPROGRESS + inscode(d, ds, de, "EINPROGRESS", EINPROGRESS, "Operation now in progress"); +#else +#ifdef WSAEINPROGRESS + inscode(d, ds, de, "EINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); +#endif +#endif +#ifdef ENXIO + inscode(d, ds, de, "ENXIO", ENXIO, "No such device or address"); +#endif +#ifdef ENOPKG + inscode(d, ds, de, "ENOPKG", ENOPKG, "Package not installed"); +#endif +#ifdef WSASY + inscode(d, ds, de, "WSASY", WSASY, "Error WSASY"); +#endif +#ifdef WSAEHOSTDOWN + inscode(d, ds, de, "WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down"); +#endif +#ifdef WSAENETDOWN + inscode(d, ds, de, "WSAENETDOWN", WSAENETDOWN, "Network is down"); +#endif +#ifdef WSAENOTSOCK + inscode(d, ds, de, "WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); +#endif +#ifdef WSAEHOSTUNREACH + inscode(d, ds, de, "WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); +#endif +#ifdef WSAELOOP + inscode(d, ds, de, "WSAELOOP", WSAELOOP, "Too many symbolic links encountered"); +#endif +#ifdef WSAEMFILE + inscode(d, ds, de, "WSAEMFILE", WSAEMFILE, "Too many open files"); +#endif +#ifdef WSAESTALE + inscode(d, ds, de, "WSAESTALE", WSAESTALE, "Stale NFS file handle"); +#endif +#ifdef WSAVERNOTSUPPORTED + inscode(d, ds, de, "WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED"); +#endif +#ifdef WSAENETUNREACH + inscode(d, ds, de, "WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable"); +#endif +#ifdef WSAEPROCLIM + inscode(d, ds, de, "WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM"); +#endif +#ifdef WSAEFAULT + inscode(d, ds, de, "WSAEFAULT", WSAEFAULT, "Bad address"); +#endif +#ifdef WSANOTINITIALISED + inscode(d, ds, de, "WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED"); +#endif +#ifdef WSAEUSERS + inscode(d, ds, de, "WSAEUSERS", WSAEUSERS, "Too many users"); +#endif +#ifdef WSAMAKEASYNCREPL + inscode(d, ds, de, "WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL"); +#endif +#ifdef WSAENOPROTOOPT + inscode(d, ds, de, "WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); +#endif +#ifdef WSAECONNABORTED + inscode(d, ds, de, "WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); +#endif +#ifdef WSAENAMETOOLONG + inscode(d, ds, de, "WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); +#endif +#ifdef WSAENOTEMPTY + inscode(d, ds, de, "WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); +#endif +#ifdef WSAESHUTDOWN + inscode(d, ds, de, "WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); +#endif +#ifdef WSAEAFNOSUPPORT + inscode(d, ds, de, "WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); +#endif +#ifdef WSAETOOMANYREFS + inscode(d, ds, de, "WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); +#endif +#ifdef WSAEACCES + inscode(d, ds, de, "WSAEACCES", WSAEACCES, "Permission denied"); +#endif +#ifdef WSATR + inscode(d, ds, de, "WSATR", WSATR, "Error WSATR"); +#endif +#ifdef WSABASEERR + inscode(d, ds, de, "WSABASEERR", WSABASEERR, "Error WSABASEERR"); +#endif +#ifdef WSADESCRIPTIO + inscode(d, ds, de, "WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO"); +#endif +#ifdef WSAEMSGSIZE + inscode(d, ds, de, "WSAEMSGSIZE", WSAEMSGSIZE, "Message too long"); +#endif +#ifdef WSAEBADF + inscode(d, ds, de, "WSAEBADF", WSAEBADF, "Bad file number"); +#endif +#ifdef WSAECONNRESET + inscode(d, ds, de, "WSAECONNRESET", WSAECONNRESET, "Connection reset by peer"); +#endif +#ifdef WSAGETSELECTERRO + inscode(d, ds, de, "WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO"); +#endif +#ifdef WSAETIMEDOUT + inscode(d, ds, de, "WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); +#endif +#ifdef WSAENOBUFS + inscode(d, ds, de, "WSAENOBUFS", WSAENOBUFS, "No buffer space available"); +#endif +#ifdef WSAEDISCON + inscode(d, ds, de, "WSAEDISCON", WSAEDISCON, "Error WSAEDISCON"); +#endif +#ifdef WSAEINTR + inscode(d, ds, de, "WSAEINTR", WSAEINTR, "Interrupted system call"); +#endif +#ifdef WSAEPROTOTYPE + inscode(d, ds, de, "WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); +#endif +#ifdef WSAHOS + inscode(d, ds, de, "WSAHOS", WSAHOS, "Error WSAHOS"); +#endif +#ifdef WSAEADDRINUSE + inscode(d, ds, de, "WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use"); +#endif +#ifdef WSAEADDRNOTAVAIL + inscode(d, ds, de, "WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); +#endif +#ifdef WSAEALREADY + inscode(d, ds, de, "WSAEALREADY", WSAEALREADY, "Operation already in progress"); +#endif +#ifdef WSAEPROTONOSUPPORT + inscode(d, ds, de, "WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); +#endif +#ifdef WSASYSNOTREADY + inscode(d, ds, de, "WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY"); +#endif +#ifdef WSAEWOULDBLOCK + inscode(d, ds, de, "WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); +#endif +#ifdef WSAEPFNOSUPPORT + inscode(d, ds, de, "WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); +#endif +#ifdef WSAEOPNOTSUPP + inscode(d, ds, de, "WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); +#endif +#ifdef WSAEISCONN + inscode(d, ds, de, "WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected"); +#endif +#ifdef WSAEDQUOT + inscode(d, ds, de, "WSAEDQUOT", WSAEDQUOT, "Quota exceeded"); +#endif +#ifdef WSAENOTCONN + inscode(d, ds, de, "WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); +#endif +#ifdef WSAEREMOTE + inscode(d, ds, de, "WSAEREMOTE", WSAEREMOTE, "Object is remote"); +#endif +#ifdef WSAEINVAL + inscode(d, ds, de, "WSAEINVAL", WSAEINVAL, "Invalid argument"); +#endif +#ifdef WSAEINPROGRESS + inscode(d, ds, de, "WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); +#endif +#ifdef WSAGETSELECTEVEN + inscode(d, ds, de, "WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN"); +#endif +#ifdef WSAESOCKTNOSUPPORT + inscode(d, ds, de, "WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); +#endif +#ifdef WSAGETASYNCERRO + inscode(d, ds, de, "WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO"); +#endif +#ifdef WSAMAKESELECTREPL + inscode(d, ds, de, "WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL"); +#endif +#ifdef WSAGETASYNCBUFLE + inscode(d, ds, de, "WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE"); +#endif +#ifdef WSAEDESTADDRREQ + inscode(d, ds, de, "WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); +#endif +#ifdef WSAECONNREFUSED + inscode(d, ds, de, "WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused"); +#endif +#ifdef WSAENETRESET + inscode(d, ds, de, "WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset"); +#endif +#ifdef WSAN + inscode(d, ds, de, "WSAN", WSAN, "Error WSAN"); +#endif +#ifdef ENOMEDIUM + inscode(d, ds, de, "ENOMEDIUM", ENOMEDIUM, "No medium found"); +#endif +#ifdef EMEDIUMTYPE + inscode(d, ds, de, "EMEDIUMTYPE", EMEDIUMTYPE, "Wrong medium type"); +#endif +#ifdef ECANCELED + inscode(d, ds, de, "ECANCELED", ECANCELED, "Operation Canceled"); +#endif +#ifdef ENOKEY + inscode(d, ds, de, "ENOKEY", ENOKEY, "Required key not available"); +#endif +#ifdef EKEYEXPIRED + inscode(d, ds, de, "EKEYEXPIRED", EKEYEXPIRED, "Key has expired"); +#endif +#ifdef EKEYREVOKED + inscode(d, ds, de, "EKEYREVOKED", EKEYREVOKED, "Key has been revoked"); +#endif +#ifdef EKEYREJECTED + inscode(d, ds, de, "EKEYREJECTED", EKEYREJECTED, "Key was rejected by service"); +#endif +#ifdef EOWNERDEAD + inscode(d, ds, de, "EOWNERDEAD", EOWNERDEAD, "Owner died"); +#endif +#ifdef ENOTRECOVERABLE + inscode(d, ds, de, "ENOTRECOVERABLE", ENOTRECOVERABLE, "State not recoverable"); +#endif +#ifdef ERFKILL + inscode(d, ds, de, "ERFKILL", ERFKILL, "Operation not possible due to RF-kill"); +#endif + + /* Solaris-specific errnos */ +#ifdef ECANCELED + inscode(d, ds, de, "ECANCELED", ECANCELED, "Operation canceled"); +#endif +#ifdef ENOTSUP + inscode(d, ds, de, "ENOTSUP", ENOTSUP, "Operation not supported"); +#endif +#ifdef EOWNERDEAD + inscode(d, ds, de, "EOWNERDEAD", EOWNERDEAD, "Process died with the lock"); +#endif +#ifdef ENOTRECOVERABLE + inscode(d, ds, de, "ENOTRECOVERABLE", ENOTRECOVERABLE, "Lock is not recoverable"); +#endif +#ifdef ELOCKUNMAPPED + inscode(d, ds, de, "ELOCKUNMAPPED", ELOCKUNMAPPED, "Locked lock was unmapped"); +#endif +#ifdef ENOTACTIVE + inscode(d, ds, de, "ENOTACTIVE", ENOTACTIVE, "Facility is not active"); +#endif + + /* MacOSX specific errnos */ +#ifdef EAUTH + inscode(d, ds, de, "EAUTH", EAUTH, "Authentication error"); +#endif +#ifdef EBADARCH + inscode(d, ds, de, "EBADARCH", EBADARCH, "Bad CPU type in executable"); +#endif +#ifdef EBADEXEC + inscode(d, ds, de, "EBADEXEC", EBADEXEC, "Bad executable (or shared library)"); +#endif +#ifdef EBADMACHO + inscode(d, ds, de, "EBADMACHO", EBADMACHO, "Malformed Mach-o file"); +#endif +#ifdef EBADRPC + inscode(d, ds, de, "EBADRPC", EBADRPC, "RPC struct is bad"); +#endif +#ifdef EDEVERR + inscode(d, ds, de, "EDEVERR", EDEVERR, "Device error"); +#endif +#ifdef EFTYPE + inscode(d, ds, de, "EFTYPE", EFTYPE, "Inappropriate file type or format"); +#endif +#ifdef ENEEDAUTH + inscode(d, ds, de, "ENEEDAUTH", ENEEDAUTH, "Need authenticator"); +#endif +#ifdef ENOATTR + inscode(d, ds, de, "ENOATTR", ENOATTR, "Attribute not found"); +#endif +#ifdef ENOPOLICY + inscode(d, ds, de, "ENOPOLICY", ENOPOLICY, "Policy not found"); +#endif +#ifdef EPROCLIM + inscode(d, ds, de, "EPROCLIM", EPROCLIM, "Too many processes"); +#endif +#ifdef EPROCUNAVAIL + inscode(d, ds, de, "EPROCUNAVAIL", EPROCUNAVAIL, "Bad procedure for program"); +#endif +#ifdef EPROGMISMATCH + inscode(d, ds, de, "EPROGMISMATCH", EPROGMISMATCH, "Program version wrong"); +#endif +#ifdef EPROGUNAVAIL + inscode(d, ds, de, "EPROGUNAVAIL", EPROGUNAVAIL, "RPC prog. not avail"); +#endif +#ifdef EPWROFF + inscode(d, ds, de, "EPWROFF", EPWROFF, "Device power is off"); +#endif +#ifdef ERPCMISMATCH + inscode(d, ds, de, "ERPCMISMATCH", ERPCMISMATCH, "RPC version wrong"); +#endif +#ifdef ESHLIBVERS + inscode(d, ds, de, "ESHLIBVERS", ESHLIBVERS, "Shared library version mismatch"); +#endif + + Py_DECREF(de); + return m; +} diff --git a/python/Modules/expat/COPYING b/python/Modules/expat/COPYING new file mode 100755 index 0000000..8d288f0 --- /dev/null +++ b/python/Modules/expat/COPYING @@ -0,0 +1,21 @@ +Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper +Copyright (c) 2001-2017 Expat maintainers + +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. diff --git a/python/Modules/expat/ascii.h b/python/Modules/expat/ascii.h new file mode 100755 index 0000000..c3587e5 --- /dev/null +++ b/python/Modules/expat/ascii.h @@ -0,0 +1,120 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +#define ASCII_A 0x41 +#define ASCII_B 0x42 +#define ASCII_C 0x43 +#define ASCII_D 0x44 +#define ASCII_E 0x45 +#define ASCII_F 0x46 +#define ASCII_G 0x47 +#define ASCII_H 0x48 +#define ASCII_I 0x49 +#define ASCII_J 0x4A +#define ASCII_K 0x4B +#define ASCII_L 0x4C +#define ASCII_M 0x4D +#define ASCII_N 0x4E +#define ASCII_O 0x4F +#define ASCII_P 0x50 +#define ASCII_Q 0x51 +#define ASCII_R 0x52 +#define ASCII_S 0x53 +#define ASCII_T 0x54 +#define ASCII_U 0x55 +#define ASCII_V 0x56 +#define ASCII_W 0x57 +#define ASCII_X 0x58 +#define ASCII_Y 0x59 +#define ASCII_Z 0x5A + +#define ASCII_a 0x61 +#define ASCII_b 0x62 +#define ASCII_c 0x63 +#define ASCII_d 0x64 +#define ASCII_e 0x65 +#define ASCII_f 0x66 +#define ASCII_g 0x67 +#define ASCII_h 0x68 +#define ASCII_i 0x69 +#define ASCII_j 0x6A +#define ASCII_k 0x6B +#define ASCII_l 0x6C +#define ASCII_m 0x6D +#define ASCII_n 0x6E +#define ASCII_o 0x6F +#define ASCII_p 0x70 +#define ASCII_q 0x71 +#define ASCII_r 0x72 +#define ASCII_s 0x73 +#define ASCII_t 0x74 +#define ASCII_u 0x75 +#define ASCII_v 0x76 +#define ASCII_w 0x77 +#define ASCII_x 0x78 +#define ASCII_y 0x79 +#define ASCII_z 0x7A + +#define ASCII_0 0x30 +#define ASCII_1 0x31 +#define ASCII_2 0x32 +#define ASCII_3 0x33 +#define ASCII_4 0x34 +#define ASCII_5 0x35 +#define ASCII_6 0x36 +#define ASCII_7 0x37 +#define ASCII_8 0x38 +#define ASCII_9 0x39 + +#define ASCII_TAB 0x09 +#define ASCII_SPACE 0x20 +#define ASCII_EXCL 0x21 +#define ASCII_QUOT 0x22 +#define ASCII_AMP 0x26 +#define ASCII_APOS 0x27 +#define ASCII_MINUS 0x2D +#define ASCII_PERIOD 0x2E +#define ASCII_COLON 0x3A +#define ASCII_SEMI 0x3B +#define ASCII_LT 0x3C +#define ASCII_EQUALS 0x3D +#define ASCII_GT 0x3E +#define ASCII_LSQB 0x5B +#define ASCII_RSQB 0x5D +#define ASCII_UNDERSCORE 0x5F +#define ASCII_LPAREN 0x28 +#define ASCII_RPAREN 0x29 +#define ASCII_FF 0x0C +#define ASCII_SLASH 0x2F +#define ASCII_HASH 0x23 +#define ASCII_PIPE 0x7C +#define ASCII_COMMA 0x2C diff --git a/python/Modules/expat/asciitab.h b/python/Modules/expat/asciitab.h new file mode 100755 index 0000000..63b1d1b --- /dev/null +++ b/python/Modules/expat/asciitab.h @@ -0,0 +1,64 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, + /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, + /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, + /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, + /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, + /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, + /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, + /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, + /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, + /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, + /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/python/Modules/expat/expat.h b/python/Modules/expat/expat.h new file mode 100755 index 0000000..6c8eb1f --- /dev/null +++ b/python/Modules/expat/expat.h @@ -0,0 +1,1024 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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 Expat_INCLUDED +#define Expat_INCLUDED 1 + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool)1) +#define XML_FALSE ((XML_Bool)0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI, + /* Added in 2.2.1. */ + XML_ERROR_INVALID_ARGUMENT +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char *name; + unsigned int numchildren; + XML_Content *children; +}; + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void(XMLCALL *XML_AttlistDeclHandler)( + void *userData, const XML_Char *elname, const XML_Char *attname, + const XML_Char *att_type, const XML_Char *dflt, int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl); + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionately high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void(XMLCALL *XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void(XMLCALL *XML_EndElementHandler)(void *userData, + const XML_Char *name); + +/* s is not 0 terminated. */ +typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData, + const XML_Char *s, int len); + +/* target and data are 0 terminated */ +typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data); + +typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData); +typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void(XMLCALL *XML_EntityDeclHandler)( + 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); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superseded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)( + void *userData, const XML_Char *entityName, const XML_Char *base, + const XML_Char *systemId, const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int(XMLCALL *convert)(void *data, const char *s); + void(XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. Returns -1 if parser == NULL. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute or + parser == NULL. Each attribute/value pair counts as 2; thus this + correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +#ifdef XML_ATTR_INFO +/* Source file byte offsets for the start and end of attribute names and values. + The value indices are exclusive of surrounding quotes; thus in a UTF-8 source + file an attribute value of "blah" will yield: + info->valueEnd - info->valueStart = 4 bytes. +*/ +typedef struct { + XML_Index nameStart; /* Offset to beginning of the attribute name. */ + XML_Index nameEnd; /* Offset after the attribute name's last byte. */ + XML_Index valueStart; /* Offset to beginning of the attribute value. */ + XML_Index valueEnd; /* Offset after the attribute value's last byte. */ +} XML_AttrInfo; + +/* Returns an array of XML_AttrInfo structures for the attribute/value pairs + passed in last call to the XML_StartElementHandler that were specified + in the start-tag rather than defaulted. Each attribute/value pair counts + as 1; thus the number of entries in the array is + XML_GetSpecifiedAttributeCount(parser) / 2. +*/ +XMLPARSEAPI(const XML_AttrInfo *) +XML_GetAttributeInfo(XML_Parser parser); +#endif + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED }; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. + Note: If parser == NULL, the function will do nothing and return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* Sets the hash salt to use for internal hash calculations. + Helps in preventing DoS attacks based on predicting hash + function behavior. This must be called before parsing is started. + Returns 1 if successful, 0 when called after parsing has started. + Note: If parser == NULL, the function will do nothing and return 0. +*/ +XMLPARSEAPI(int) +XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. + + Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber + return 0 to indicate an error. + Note: XML_GetCurrentByteIndex returns -1 to indicate an error. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, int *offset, int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_ATTR_MALLOC +XML_ATTR_ALLOC_SIZE(2) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_ATTR_ALLOC_SIZE(3) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS, + XML_FEATURE_LARGE_SIZE, + XML_FEATURE_ATTR_INFO + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + +/* Expat follows the semantic versioning convention. + See http://semver.org. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 2 +#define XML_MICRO_VERSION 8 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/python/Modules/expat/expat_config.h b/python/Modules/expat/expat_config.h new file mode 100755 index 0000000..afbedd0 --- /dev/null +++ b/python/Modules/expat/expat_config.h @@ -0,0 +1,21 @@ +/* + * Expat configuration for python. This file is not part of the expat + * distribution. + */ +#ifndef EXPAT_CONFIG_H +#define EXPAT_CONFIG_H + +#include +#ifdef WORDS_BIGENDIAN +#define BYTEORDER 4321 +#else +#define BYTEORDER 1234 +#endif + +#define HAVE_MEMMOVE 1 + +#define XML_NS 1 +#define XML_DTD 1 +#define XML_CONTEXT_BYTES 1024 + +#endif /* EXPAT_CONFIG_H */ diff --git a/python/Modules/expat/expat_external.h b/python/Modules/expat/expat_external.h new file mode 100755 index 0000000..f2b75dd --- /dev/null +++ b/python/Modules/expat/expat_external.h @@ -0,0 +1,163 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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 Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ + +/* Namespace external symbols to allow multiple libexpat version to + co-exist. */ +#include "pyexpatns.h" + +#ifndef XMLCALL +# if defined(_MSC_VER) +# define XMLCALL __cdecl +# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER) +# define XMLCALL __attribute__((cdecl)) +# else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +# define XMLCALL +# endif +#endif /* not defined XMLCALL */ + +#if ! defined(XML_STATIC) && ! defined(XMLIMPORT) +# ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__) +# define XMLIMPORT __declspec(dllimport) +# endif + +# endif +#endif /* not defined XML_STATIC */ + +#ifndef XML_ENABLE_VISIBILITY +# define XML_ENABLE_VISIBILITY 0 +#endif + +#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY +# define XMLIMPORT __attribute__((visibility("default"))) +#endif + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +# define XMLIMPORT +#endif + +#if defined(__GNUC__) \ + && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) +# define XML_ATTR_MALLOC __attribute__((__malloc__)) +#else +# define XML_ATTR_MALLOC +#endif + +#if defined(__GNUC__) \ + && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) +#else +# define XML_ATTR_ALLOC_SIZE(x) +#endif + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +# ifndef XML_UNICODE +# define XML_UNICODE +# endif +# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) +# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" +# endif +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +# ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +# else +typedef unsigned short XML_Char; +typedef char XML_LChar; +# endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/python/Modules/expat/iasciitab.h b/python/Modules/expat/iasciitab.h new file mode 100755 index 0000000..ea97cfc --- /dev/null +++ b/python/Modules/expat/iasciitab.h @@ -0,0 +1,65 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, + /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, + /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, + /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, + /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, + /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, + /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, + /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, + /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, + /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, + /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/python/Modules/expat/internal.h b/python/Modules/expat/internal.h new file mode 100755 index 0000000..60913da --- /dev/null +++ b/python/Modules/expat/internal.h @@ -0,0 +1,123 @@ +/* internal.h + + Internal definitions used by Expat. This is not needed to compile + client code. + + The following calling convention macros are defined for frequently + called functions: + + FASTCALL - Used for those internal functions that have a simple + body and a low number of arguments and local variables. + + PTRCALL - Used for functions called though function pointers. + + PTRFASTCALL - Like PTRCALL, but for low number of arguments. + + inline - Used for selected internal functions for which inlining + may improve performance on some platforms. + + Note: Use of these macros is based on judgement, not hard rules, + and therefore subject to change. + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__) +/* We'll use this version by default only where we know it helps. + + regparm() generates warnings on Solaris boxes. See SF bug #692878. + + Instability reported with egcs on a RedHat Linux 7.3. + Let's comment out: + #define FASTCALL __attribute__((stdcall, regparm(3))) + and let's try this: +*/ +# define FASTCALL __attribute__((regparm(3))) +# define PTRFASTCALL __attribute__((regparm(3))) +#endif + +/* Using __fastcall seems to have an unexpected negative effect under + MS VC++, especially for function pointers, so we won't use it for + now on that platform. It may be reconsidered for a future release + if it can be made more effective. + Likely reason: __fastcall on Windows is like stdcall, therefore + the compiler cannot perform stack optimizations for call clusters. +*/ + +/* Make sure all of these are defined if they aren't already. */ + +#ifndef FASTCALL +# define FASTCALL +#endif + +#ifndef PTRCALL +# define PTRCALL +#endif + +#ifndef PTRFASTCALL +# define PTRFASTCALL +#endif + +#ifndef XML_MIN_SIZE +# if ! defined(__cplusplus) && ! defined(inline) +# ifdef __GNUC__ +# define inline __inline +# endif /* __GNUC__ */ +# endif +#endif /* XML_MIN_SIZE */ + +#ifdef __cplusplus +# define inline inline +#else +# ifndef inline +# define inline +# endif +#endif + +#ifndef UNUSED_P +# define UNUSED_P(p) (void)p +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_ENABLE_VISIBILITY +# if XML_ENABLE_VISIBILITY +__attribute__((visibility("default"))) +# endif +#endif +void +_INTERNAL_trim_to_complete_utf8_characters(const char *from, + const char **fromLimRef); + +#ifdef __cplusplus +} +#endif diff --git a/python/Modules/expat/latin1tab.h b/python/Modules/expat/latin1tab.h new file mode 100755 index 0000000..6f91604 --- /dev/null +++ b/python/Modules/expat/latin1tab.h @@ -0,0 +1,64 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, + /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, + /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, + /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/python/Modules/expat/nametab.h b/python/Modules/expat/nametab.h new file mode 100755 index 0000000..3681df3 --- /dev/null +++ b/python/Modules/expat/nametab.h @@ -0,0 +1,136 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +static const unsigned namingBitmap[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000, + 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, + 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, + 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF, + 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, + 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE, + 0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, + 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF, + 0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, + 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF, + 0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, + 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF, + 0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF, + 0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000, + 0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, + 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40, + 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000, + 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, + 0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, + 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000, + 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB, + 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, + 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, + 0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, + 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF, + 0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, + 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF, + 0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, + 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718, + 0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, + 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF, + 0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE, + 0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, + 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, + 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0x77FFFFFF, +}; +static const unsigned char nmstrtPages[] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; +static const unsigned char namePages[] = { + 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; diff --git a/python/Modules/expat/pyexpatns.h b/python/Modules/expat/pyexpatns.h new file mode 100755 index 0000000..963cc18 --- /dev/null +++ b/python/Modules/expat/pyexpatns.h @@ -0,0 +1,125 @@ +/* Copyright (c) 2005-2006 ActiveState Software Inc. + * + * Namespace all expat exported symbols to avoid dynamic loading symbol + * collisions when embedding Python. + * + * The Problem: + * - you embed Python in some app + * - the app dynamically loads libexpat of version X + * - the embedded Python imports pyexpat (which was built against + * libexpat version X+n) + * --> pyexpat gets the expat symbols from the already loaded and *older* + * libexpat: crash (Specifically the crash we observed was in + * getting an old XML_ErrorString (from xmlparse.c) and then calling + * it with newer values in the XML_Error enum: + * + * // pyexpat.c, line 1970 + * ... + * // Added in Expat 1.95.7. + * MYCONST(XML_ERROR_UNBOUND_PREFIX); + * ... + * + * + * The Solution: + * Prefix all exported symbols with "PyExpat_". This is similar to + * what Mozilla does for some common libs: + * http://lxr.mozilla.org/seamonkey/source/modules/libimg/png/mozpngconf.h#115 + * + * The list of relevant exported symbols can be had with this command: + * + nm pyexpat.so \ + | grep -v " [a-zBUA] " \ + | grep -v "_fini\|_init\|initpyexpat" + * + * If any of those symbols are NOT prefixed with "PyExpat_" then + * a #define should be added for it here. + */ + +#ifndef PYEXPATNS_H +#define PYEXPATNS_H + +#define XML_DefaultCurrent PyExpat_XML_DefaultCurrent +#define XML_ErrorString PyExpat_XML_ErrorString +// #define XML_ExpatVersion PyExpat_XML_ExpatVersion +// #define XML_ExpatVersionInfo PyExpat_XML_ExpatVersionInfo +#define XML_ExternalEntityParserCreate PyExpat_XML_ExternalEntityParserCreate +#define XML_FreeContentModel PyExpat_XML_FreeContentModel +#define XML_GetBase PyExpat_XML_GetBase +#define XML_GetBuffer PyExpat_XML_GetBuffer +#define XML_GetCurrentByteCount PyExpat_XML_GetCurrentByteCount +#define XML_GetCurrentByteIndex PyExpat_XML_GetCurrentByteIndex +#define XML_GetCurrentColumnNumber PyExpat_XML_GetCurrentColumnNumber +#define XML_GetCurrentLineNumber PyExpat_XML_GetCurrentLineNumber +#define XML_GetErrorCode PyExpat_XML_GetErrorCode +#define XML_GetFeatureList PyExpat_XML_GetFeatureList +#define XML_GetIdAttributeIndex PyExpat_XML_GetIdAttributeIndex +#define XML_GetInputContext PyExpat_XML_GetInputContext +#define XML_GetParsingStatus PyExpat_XML_GetParsingStatus +#define XML_GetSpecifiedAttributeCount PyExpat_XML_GetSpecifiedAttributeCount +#define XmlGetUtf16InternalEncoding PyExpat_XmlGetUtf16InternalEncoding +#define XmlGetUtf16InternalEncodingNS PyExpat_XmlGetUtf16InternalEncodingNS +#define XmlGetUtf8InternalEncoding PyExpat_XmlGetUtf8InternalEncoding +#define XmlGetUtf8InternalEncodingNS PyExpat_XmlGetUtf8InternalEncodingNS +#define XmlInitEncoding PyExpat_XmlInitEncoding +#define XmlInitEncodingNS PyExpat_XmlInitEncodingNS +#define XmlInitUnknownEncoding PyExpat_XmlInitUnknownEncoding +#define XmlInitUnknownEncodingNS PyExpat_XmlInitUnknownEncodingNS +#define XML_MemFree PyExpat_XML_MemFree +#define XML_MemMalloc PyExpat_XML_MemMalloc +#define XML_MemRealloc PyExpat_XML_MemRealloc +#define XML_Parse PyExpat_XML_Parse +#define XML_ParseBuffer PyExpat_XML_ParseBuffer +#define XML_ParserCreate PyExpat_XML_ParserCreate +#define XML_ParserCreate_MM PyExpat_XML_ParserCreate_MM +#define XML_ParserCreateNS PyExpat_XML_ParserCreateNS +#define XML_ParserFree PyExpat_XML_ParserFree +#define XML_ParserReset PyExpat_XML_ParserReset +#define XmlParseXmlDecl PyExpat_XmlParseXmlDecl +#define XmlParseXmlDeclNS PyExpat_XmlParseXmlDeclNS +#define XmlPrologStateInit PyExpat_XmlPrologStateInit +#define XmlPrologStateInitExternalEntity PyExpat_XmlPrologStateInitExternalEntity +#define XML_ResumeParser PyExpat_XML_ResumeParser +#define XML_SetAttlistDeclHandler PyExpat_XML_SetAttlistDeclHandler +#define XML_SetBase PyExpat_XML_SetBase +#define XML_SetCdataSectionHandler PyExpat_XML_SetCdataSectionHandler +#define XML_SetCharacterDataHandler PyExpat_XML_SetCharacterDataHandler +#define XML_SetCommentHandler PyExpat_XML_SetCommentHandler +#define XML_SetDefaultHandler PyExpat_XML_SetDefaultHandler +#define XML_SetDefaultHandlerExpand PyExpat_XML_SetDefaultHandlerExpand +#define XML_SetDoctypeDeclHandler PyExpat_XML_SetDoctypeDeclHandler +#define XML_SetElementDeclHandler PyExpat_XML_SetElementDeclHandler +#define XML_SetElementHandler PyExpat_XML_SetElementHandler +#define XML_SetEncoding PyExpat_XML_SetEncoding +#define XML_SetEndCdataSectionHandler PyExpat_XML_SetEndCdataSectionHandler +#define XML_SetEndDoctypeDeclHandler PyExpat_XML_SetEndDoctypeDeclHandler +#define XML_SetEndElementHandler PyExpat_XML_SetEndElementHandler +#define XML_SetEndNamespaceDeclHandler PyExpat_XML_SetEndNamespaceDeclHandler +#define XML_SetEntityDeclHandler PyExpat_XML_SetEntityDeclHandler +#define XML_SetExternalEntityRefHandler PyExpat_XML_SetExternalEntityRefHandler +#define XML_SetExternalEntityRefHandlerArg PyExpat_XML_SetExternalEntityRefHandlerArg +#define XML_SetHashSalt PyExpat_XML_SetHashSalt +#define XML_SetNamespaceDeclHandler PyExpat_XML_SetNamespaceDeclHandler +#define XML_SetNotationDeclHandler PyExpat_XML_SetNotationDeclHandler +#define XML_SetNotStandaloneHandler PyExpat_XML_SetNotStandaloneHandler +#define XML_SetParamEntityParsing PyExpat_XML_SetParamEntityParsing +#define XML_SetProcessingInstructionHandler PyExpat_XML_SetProcessingInstructionHandler +#define XML_SetReturnNSTriplet PyExpat_XML_SetReturnNSTriplet +#define XML_SetSkippedEntityHandler PyExpat_XML_SetSkippedEntityHandler +#define XML_SetStartCdataSectionHandler PyExpat_XML_SetStartCdataSectionHandler +#define XML_SetStartDoctypeDeclHandler PyExpat_XML_SetStartDoctypeDeclHandler +#define XML_SetStartElementHandler PyExpat_XML_SetStartElementHandler +#define XML_SetStartNamespaceDeclHandler PyExpat_XML_SetStartNamespaceDeclHandler +#define XML_SetUnknownEncodingHandler PyExpat_XML_SetUnknownEncodingHandler +#define XML_SetUnparsedEntityDeclHandler PyExpat_XML_SetUnparsedEntityDeclHandler +#define XML_SetUserData PyExpat_XML_SetUserData +#define XML_SetXmlDeclHandler PyExpat_XML_SetXmlDeclHandler +#define XmlSizeOfUnknownEncoding PyExpat_XmlSizeOfUnknownEncoding +#define XML_StopParser PyExpat_XML_StopParser +#define XML_UseForeignDTD PyExpat_XML_UseForeignDTD +#define XML_UseParserAsHandlerArg PyExpat_XML_UseParserAsHandlerArg +#define XmlUtf16Encode PyExpat_XmlUtf16Encode +#define XmlUtf8Encode PyExpat_XmlUtf8Encode + + +#endif /* !PYEXPATNS_H */ + diff --git a/python/Modules/expat/siphash.h b/python/Modules/expat/siphash.h new file mode 100755 index 0000000..bfee65a --- /dev/null +++ b/python/Modules/expat/siphash.h @@ -0,0 +1,398 @@ +/* ========================================================================== + * siphash.h - SipHash-2-4 in a single header file + * -------------------------------------------------------------------------- + * Derived by William Ahern from the reference implementation[1] published[2] + * by Jean-Philippe Aumasson and Daniel J. Berstein. + * Minimal changes by Sebastian Pipping and Victor Stinner on top, see below. + * Licensed under the CC0 Public Domain Dedication license. + * + * 1. https://www.131002.net/siphash/siphash24.c + * 2. https://www.131002.net/siphash/ + * -------------------------------------------------------------------------- + * HISTORY: + * + * 2019-08-03 (Sebastian Pipping) + * - Mark part of sip24_valid as to be excluded from clang-format + * - Re-format code using clang-format 9 + * + * 2018-07-08 (Anton Maklakov) + * - Add "fall through" markers for GCC's -Wimplicit-fallthrough + * + * 2017-11-03 (Sebastian Pipping) + * - Hide sip_tobin and sip_binof unless SIPHASH_TOBIN macro is defined + * + * 2017-07-25 (Vadim Zeitlin) + * - Fix use of SIPHASH_MAIN macro + * + * 2017-07-05 (Sebastian Pipping) + * - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++ + * - Add const qualifiers at two places + * - Ensure <=80 characters line length (assuming tab width 4) + * + * 2017-06-23 (Victor Stinner) + * - Address Win64 compile warnings + * + * 2017-06-18 (Sebastian Pipping) + * - Clarify license note in the header + * - Address C89 issues: + * - Stop using inline keyword (and let compiler decide) + * - Replace _Bool by int + * - Turn macro siphash24 into a function + * - Address invalid conversion (void pointer) by explicit cast + * - Address lack of stdint.h for Visual Studio 2003 to 2008 + * - Always expose sip24_valid (for self-tests) + * + * 2012-11-04 - Born. (William Ahern) + * -------------------------------------------------------------------------- + * USAGE: + * + * SipHash-2-4 takes as input two 64-bit words as the key, some number of + * message bytes, and outputs a 64-bit word as the message digest. This + * implementation employs two data structures: a struct sipkey for + * representing the key, and a struct siphash for representing the hash + * state. + * + * For converting a 16-byte unsigned char array to a key, use either the + * macro sip_keyof or the routine sip_tokey. The former instantiates a + * compound literal key, while the latter requires a key object as a + * parameter. + * + * unsigned char secret[16]; + * arc4random_buf(secret, sizeof secret); + * struct sipkey *key = sip_keyof(secret); + * + * For hashing a message, use either the convenience macro siphash24 or the + * routines sip24_init, sip24_update, and sip24_final. + * + * struct siphash state; + * void *msg; + * size_t len; + * uint64_t hash; + * + * sip24_init(&state, key); + * sip24_update(&state, msg, len); + * hash = sip24_final(&state); + * + * or + * + * hash = siphash24(msg, len, key); + * + * To convert the 64-bit hash value to a canonical 8-byte little-endian + * binary representation, use either the macro sip_binof or the routine + * sip_tobin. The former instantiates and returns a compound literal array, + * while the latter requires an array object as a parameter. + * -------------------------------------------------------------------------- + * NOTES: + * + * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers + * lacking compound literal support. Instead, you must use the lower-level + * interfaces which take as parameters the temporary state objects. + * + * o Uppercase macros may evaluate parameters more than once. Lowercase + * macros should not exhibit any such side effects. + * ========================================================================== + */ +#ifndef SIPHASH_H +#define SIPHASH_H + +#include /* size_t */ + +#if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600) +/* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */ +typedef unsigned __int8 uint8_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#else +# include /* uint64_t uint32_t uint8_t */ +#endif + +/* + * Workaround to not require a C++11 compiler for using ULL suffix + * if this code is included and compiled as C++; related GCC warning is: + * warning: use of C++11 long long integer constant [-Wlong-long] + */ +#define _SIP_ULL(high, low) (((uint64_t)high << 32) | low) + +#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) + +#define SIP_U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v) >> 0); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); + +#define SIP_U64TO8_LE(p, v) \ + SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ + SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); + +#define SIP_U8TO64_LE(p) \ + (((uint64_t)((p)[0]) << 0) | ((uint64_t)((p)[1]) << 8) \ + | ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) \ + | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \ + | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) + +#define SIPHASH_INITIALIZER \ + { 0, 0, 0, 0, {0}, 0, 0 } + +struct siphash { + uint64_t v0, v1, v2, v3; + + unsigned char buf[8], *p; + uint64_t c; +}; /* struct siphash */ + +#define SIP_KEYLEN 16 + +struct sipkey { + uint64_t k[2]; +}; /* struct sipkey */ + +#define sip_keyof(k) sip_tokey(&(struct sipkey){{0}}, (k)) + +static struct sipkey * +sip_tokey(struct sipkey *key, const void *src) { + key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); + key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); + return key; +} /* sip_tokey() */ + +#ifdef SIPHASH_TOBIN + +# define sip_binof(v) sip_tobin((unsigned char[8]){0}, (v)) + +static void * +sip_tobin(void *dst, uint64_t u64) { + SIP_U64TO8_LE((unsigned char *)dst, u64); + return dst; +} /* sip_tobin() */ + +#endif /* SIPHASH_TOBIN */ + +static void +sip_round(struct siphash *H, const int rounds) { + int i; + + for (i = 0; i < rounds; i++) { + H->v0 += H->v1; + H->v1 = SIP_ROTL(H->v1, 13); + H->v1 ^= H->v0; + H->v0 = SIP_ROTL(H->v0, 32); + + H->v2 += H->v3; + H->v3 = SIP_ROTL(H->v3, 16); + H->v3 ^= H->v2; + + H->v0 += H->v3; + H->v3 = SIP_ROTL(H->v3, 21); + H->v3 ^= H->v0; + + H->v2 += H->v1; + H->v1 = SIP_ROTL(H->v1, 17); + H->v1 ^= H->v2; + H->v2 = SIP_ROTL(H->v2, 32); + } +} /* sip_round() */ + +static struct siphash * +sip24_init(struct siphash *H, const struct sipkey *key) { + H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0]; + H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1]; + H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0]; + H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1]; + + H->p = H->buf; + H->c = 0; + + return H; +} /* sip24_init() */ + +#define sip_endof(a) (&(a)[sizeof(a) / sizeof *(a)]) + +static struct siphash * +sip24_update(struct siphash *H, const void *src, size_t len) { + const unsigned char *p = (const unsigned char *)src, *pe = p + len; + uint64_t m; + + do { + while (p < pe && H->p < sip_endof(H->buf)) + *H->p++ = *p++; + + if (H->p < sip_endof(H->buf)) + break; + + m = SIP_U8TO64_LE(H->buf); + H->v3 ^= m; + sip_round(H, 2); + H->v0 ^= m; + + H->p = H->buf; + H->c += 8; + } while (p < pe); + + return H; +} /* sip24_update() */ + +static uint64_t +sip24_final(struct siphash *H) { + const char left = (char)(H->p - H->buf); + uint64_t b = (H->c + left) << 56; + + switch (left) { + case 7: + b |= (uint64_t)H->buf[6] << 48; + /* fall through */ + case 6: + b |= (uint64_t)H->buf[5] << 40; + /* fall through */ + case 5: + b |= (uint64_t)H->buf[4] << 32; + /* fall through */ + case 4: + b |= (uint64_t)H->buf[3] << 24; + /* fall through */ + case 3: + b |= (uint64_t)H->buf[2] << 16; + /* fall through */ + case 2: + b |= (uint64_t)H->buf[1] << 8; + /* fall through */ + case 1: + b |= (uint64_t)H->buf[0] << 0; + /* fall through */ + case 0: + break; + } + + H->v3 ^= b; + sip_round(H, 2); + H->v0 ^= b; + H->v2 ^= 0xff; + sip_round(H, 4); + + return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; +} /* sip24_final() */ + +static uint64_t +siphash24(const void *src, size_t len, const struct sipkey *key) { + struct siphash state = SIPHASH_INITIALIZER; + return sip24_final(sip24_update(sip24_init(&state, key), src, len)); +} /* siphash24() */ + +/* + * SipHash-2-4 output with + * k = 00 01 02 ... + * and + * in = (empty string) + * in = 00 (1 byte) + * in = 00 01 (2 bytes) + * in = 00 01 02 (3 bytes) + * ... + * in = 00 01 02 ... 3e (63 bytes) + */ +static int +sip24_valid(void) { + /* clang-format off */ + static const unsigned char vectors[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } + }; + /* clang-format on */ + + unsigned char in[64]; + struct sipkey k; + size_t i; + + sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011" + "\012\013\014\015\016\017"); + + for (i = 0; i < sizeof in; ++i) { + in[i] = (unsigned char)i; + + if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) + return 0; + } + + return 1; +} /* sip24_valid() */ + +#ifdef SIPHASH_MAIN + +# include + +int +main(void) { + const int ok = sip24_valid(); + + if (ok) + puts("OK"); + else + puts("FAIL"); + + return ! ok; +} /* main() */ + +#endif /* SIPHASH_MAIN */ + +#endif /* SIPHASH_H */ diff --git a/python/Modules/expat/utf8tab.h b/python/Modules/expat/utf8tab.h new file mode 100755 index 0000000..a22986a --- /dev/null +++ b/python/Modules/expat/utf8tab.h @@ -0,0 +1,64 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, + /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/python/Modules/expat/winconfig.h b/python/Modules/expat/winconfig.h new file mode 100755 index 0000000..562a4a8 --- /dev/null +++ b/python/Modules/expat/winconfig.h @@ -0,0 +1,56 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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 WINCONFIG_H +#define WINCONFIG_H + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +#include +#include + +#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ +# include +#else /* !defined(HAVE_EXPAT_CONFIG_H) */ + +# define XML_NS 1 +# define XML_DTD 1 +# define XML_CONTEXT_BYTES 1024 + +/* we will assume all Windows platforms are little endian */ +# define BYTEORDER 1234 + +#endif /* !defined(HAVE_EXPAT_CONFIG_H) */ + +#endif /* ndef WINCONFIG_H */ diff --git a/python/Modules/expat/xmlparse.c b/python/Modules/expat/xmlparse.c new file mode 100755 index 0000000..077167e --- /dev/null +++ b/python/Modules/expat/xmlparse.c @@ -0,0 +1,6893 @@ +// /* f2d0ab6d1d4422a08cf1cf3bbdfba96b49dea42fb5ff4615e03a2a25c306e769 (2.2.8+) +// __ __ _ +// ___\ \/ /_ __ __ _| |_ +// / _ \\ /| '_ \ / _` | __| +// | __// \| |_) | (_| | |_ +// \___/_/\_\ .__/ \__,_|\__| +// |_| XML parser + +// Copyright (c) 1997-2000 Thai Open Source Software Center Ltd +// Copyright (c) 2000-2017 Expat development team +// Licensed under the MIT license: + +// 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. +// */ + +// #if ! defined(_GNU_SOURCE) +// # define _GNU_SOURCE 1 /* syscall prototype */ +// #endif + +// #ifdef _WIN32 +// /* force stdlib to define rand_s() */ +// # define _CRT_RAND_S +// #endif + +// #include +// #include /* memset(), memcpy() */ +// #include +// #include /* UINT_MAX */ +// #include /* fprintf */ +// #include /* getenv, rand_s */ + +// #ifdef _WIN32 +// # define getpid GetCurrentProcessId +// #else +// # include /* gettimeofday() */ +// # include /* getpid() */ +// # include /* getpid() */ +// # include /* O_RDONLY */ +// # include +// #endif + +// #define XML_BUILDING_EXPAT 1 + +// #ifdef _WIN32 +// # include "winconfig.h" +// #elif defined(HAVE_EXPAT_CONFIG_H) +// # include +// #endif /* ndef _WIN32 */ + +// #include "ascii.h" +// #include "expat.h" +// #include "siphash.h" + +// #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) +// # if defined(HAVE_GETRANDOM) +// # include /* getrandom */ +// # else +// # include /* syscall */ +// # include /* SYS_getrandom */ +// # endif +// # if ! defined(GRND_NONBLOCK) +// # define GRND_NONBLOCK 0x0001 +// # endif /* defined(GRND_NONBLOCK) */ +// #endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ + +// #if defined(HAVE_LIBBSD) \ +// && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) +// # include +// #endif + +// #if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) +// # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +// #endif + +// #if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \ +// && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \ +// && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \ +// && ! defined(XML_POOR_ENTROPY) +// # error You do not have support for any sources of high quality entropy \ +// enabled. For end user security, that is probably not what you want. \ +// \ +// Your options include: \ +// * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ +// * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ +// * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ +// * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \ +// * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ +// * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ +// * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \ +// * Windows (rand_s): _WIN32. \ +// \ +// If insist on not using any of these, bypass this error by defining \ +// XML_POOR_ENTROPY; you have been warned. \ +// \ +// If you have reasons to patch this detection code away or need changes \ +// to the build system, please open a bug. Thank you! +// #endif + +// #ifdef XML_UNICODE +// # define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX +// # define XmlConvert XmlUtf16Convert +// # define XmlGetInternalEncoding XmlGetUtf16InternalEncoding +// # define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS +// # define XmlEncode XmlUtf16Encode +// /* Using pointer subtraction to convert to integer type. */ +// # define MUST_CONVERT(enc, s) \ +// (! (enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) +// typedef unsigned short ICHAR; +// #else +// # define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX +// # define XmlConvert XmlUtf8Convert +// # define XmlGetInternalEncoding XmlGetUtf8InternalEncoding +// # define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS +// # define XmlEncode XmlUtf8Encode +// # define MUST_CONVERT(enc, s) (! (enc)->isUtf8) +// typedef char ICHAR; +// #endif + +// #ifndef XML_NS + +// # define XmlInitEncodingNS XmlInitEncoding +// # define XmlInitUnknownEncodingNS XmlInitUnknownEncoding +// # undef XmlGetInternalEncodingNS +// # define XmlGetInternalEncodingNS XmlGetInternalEncoding +// # define XmlParseXmlDeclNS XmlParseXmlDecl + +// #endif + +// #ifdef XML_UNICODE + +// # ifdef XML_UNICODE_WCHAR_T +// # define XML_T(x) (const wchar_t) x +// # define XML_L(x) L##x +// # else +// # define XML_T(x) (const unsigned short)x +// # define XML_L(x) x +// # endif + +// #else + +// # define XML_T(x) x +// # define XML_L(x) x + +// #endif + +// /* Round up n to be a multiple of sz, where sz is a power of 2. */ +// #define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) + +// /* Do safe (NULL-aware) pointer arithmetic */ +// #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) + +// #include "internal.h" +// #include "xmltok.h" +// #include "xmlrole.h" + +// typedef const XML_Char *KEY; + +// typedef struct { +// KEY name; +// } NAMED; + +// typedef struct { +// NAMED **v; +// unsigned char power; +// size_t size; +// size_t used; +// const XML_Memory_Handling_Suite *mem; +// } HASH_TABLE; + +// static size_t keylen(KEY s); + +// static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); + +// /* For probing (after a collision) we need a step size relative prime +// to the hash table size, which is a power of 2. We use double-hashing, +// since we can calculate a second hash value cheaply by taking those bits +// of the first hash value that were discarded (masked out) when the table +// index was calculated: index = hash & mask, where mask = table->size - 1. +// We limit the maximum step size to table->size / 4 (mask >> 2) and make +// it odd, since odd numbers are always relative prime to a power of 2. +// */ +// #define SECOND_HASH(hash, mask, power) \ +// ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2)) +// #define PROBE_STEP(hash, mask, power) \ +// ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) + +// typedef struct { +// NAMED **p; +// NAMED **end; +// } HASH_TABLE_ITER; + +// #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ +// #define INIT_DATA_BUF_SIZE 1024 +// #define INIT_ATTS_SIZE 16 +// #define INIT_ATTS_VERSION 0xFFFFFFFF +// #define INIT_BLOCK_SIZE 1024 +// #define INIT_BUFFER_SIZE 1024 + +// #define EXPAND_SPARE 24 + +// typedef struct binding { +// struct prefix *prefix; +// struct binding *nextTagBinding; +// struct binding *prevPrefixBinding; +// const struct attribute_id *attId; +// XML_Char *uri; +// int uriLen; +// int uriAlloc; +// } BINDING; + +// typedef struct prefix { +// const XML_Char *name; +// BINDING *binding; +// } PREFIX; + +// typedef struct { +// const XML_Char *str; +// const XML_Char *localPart; +// const XML_Char *prefix; +// int strLen; +// int uriLen; +// int prefixLen; +// } TAG_NAME; + +// /* TAG represents an open element. +// The name of the element is stored in both the document and API +// encodings. The memory buffer 'buf' is a separately-allocated +// memory area which stores the name. During the XML_Parse()/ +// XMLParseBuffer() when the element is open, the memory for the 'raw' +// version of the name (in the document encoding) is shared with the +// document buffer. If the element is open across calls to +// XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to +// contain the 'raw' name as well. + +// A parser re-uses these structures, maintaining a list of allocated +// TAG objects in a free list. +// */ +// typedef struct tag { +// struct tag *parent; /* parent of this element */ +// const char *rawName; /* tagName in the original encoding */ +// int rawNameLength; +// TAG_NAME name; /* tagName in the API encoding */ +// char *buf; /* buffer for name components */ +// char *bufEnd; /* end of the buffer */ +// BINDING *bindings; +// } TAG; + +// typedef struct { +// const XML_Char *name; +// const XML_Char *textPtr; +// int textLen; /* length in XML_Chars */ +// int processed; /* # of processed bytes - when suspended */ +// const XML_Char *systemId; +// const XML_Char *base; +// const XML_Char *publicId; +// const XML_Char *notation; +// XML_Bool open; +// XML_Bool is_param; +// XML_Bool is_internal; /* true if declared in internal subset outside PE */ +// } ENTITY; + +// typedef struct { +// enum XML_Content_Type type; +// enum XML_Content_Quant quant; +// const XML_Char *name; +// int firstchild; +// int lastchild; +// int childcnt; +// int nextsib; +// } CONTENT_SCAFFOLD; + +// #define INIT_SCAFFOLD_ELEMENTS 32 + +// typedef struct block { +// struct block *next; +// int size; +// XML_Char s[1]; +// } BLOCK; + +// typedef struct { +// BLOCK *blocks; +// BLOCK *freeBlocks; +// const XML_Char *end; +// XML_Char *ptr; +// XML_Char *start; +// const XML_Memory_Handling_Suite *mem; +// } STRING_POOL; + +// /* The XML_Char before the name is used to determine whether +// an attribute has been specified. */ +// typedef struct attribute_id { +// XML_Char *name; +// PREFIX *prefix; +// XML_Bool maybeTokenized; +// XML_Bool xmlns; +// } ATTRIBUTE_ID; + +// typedef struct { +// const ATTRIBUTE_ID *id; +// XML_Bool isCdata; +// const XML_Char *value; +// } DEFAULT_ATTRIBUTE; + +// typedef struct { +// unsigned long version; +// unsigned long hash; +// const XML_Char *uriName; +// } NS_ATT; + +// typedef struct { +// const XML_Char *name; +// PREFIX *prefix; +// const ATTRIBUTE_ID *idAtt; +// int nDefaultAtts; +// int allocDefaultAtts; +// DEFAULT_ATTRIBUTE *defaultAtts; +// } ELEMENT_TYPE; + +// typedef struct { +// HASH_TABLE generalEntities; +// HASH_TABLE elementTypes; +// HASH_TABLE attributeIds; +// HASH_TABLE prefixes; +// STRING_POOL pool; +// STRING_POOL entityValuePool; +// /* false once a parameter entity reference has been skipped */ +// XML_Bool keepProcessing; +// /* true once an internal or external PE reference has been encountered; +// this includes the reference to an external subset */ +// XML_Bool hasParamEntityRefs; +// XML_Bool standalone; +// #ifdef XML_DTD +// /* indicates if external PE has been read */ +// XML_Bool paramEntityRead; +// HASH_TABLE paramEntities; +// #endif /* XML_DTD */ +// PREFIX defaultPrefix; +// /* === scaffolding for building content model === */ +// XML_Bool in_eldecl; +// CONTENT_SCAFFOLD *scaffold; +// unsigned contentStringLen; +// unsigned scaffSize; +// unsigned scaffCount; +// int scaffLevel; +// int *scaffIndex; +// } DTD; + +// typedef struct open_internal_entity { +// const char *internalEventPtr; +// const char *internalEventEndPtr; +// struct open_internal_entity *next; +// ENTITY *entity; +// int startTagLevel; +// XML_Bool betweenDecl; /* WFC: PE Between Declarations */ +// } OPEN_INTERNAL_ENTITY; + +// typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, +// const char *end, const char **endPtr); + +// static Processor prologProcessor; +// static Processor prologInitProcessor; +// static Processor contentProcessor; +// static Processor cdataSectionProcessor; +// #ifdef XML_DTD +// static Processor ignoreSectionProcessor; +// static Processor externalParEntProcessor; +// static Processor externalParEntInitProcessor; +// static Processor entityValueProcessor; +// static Processor entityValueInitProcessor; +// #endif /* XML_DTD */ +// static Processor epilogProcessor; +// static Processor errorProcessor; +// static Processor externalEntityInitProcessor; +// static Processor externalEntityInitProcessor2; +// static Processor externalEntityInitProcessor3; +// static Processor externalEntityContentProcessor; +// static Processor internalEntityProcessor; + +// static enum XML_Error handleUnknownEncoding(XML_Parser parser, +// const XML_Char *encodingName); +// static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, +// const char *s, const char *next); +// static enum XML_Error initializeEncoding(XML_Parser parser); +// static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, +// const char *s, const char *end, int tok, +// const char *next, const char **nextPtr, +// XML_Bool haveMore, XML_Bool allowClosingDoctype); +// static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, +// XML_Bool betweenDecl); +// static enum XML_Error doContent(XML_Parser parser, int startTagLevel, +// const ENCODING *enc, const char *start, +// const char *end, const char **endPtr, +// XML_Bool haveMore); +// static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, +// const char **startPtr, const char *end, +// const char **nextPtr, XML_Bool haveMore); +// #ifdef XML_DTD +// static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *, +// const char **startPtr, const char *end, +// const char **nextPtr, XML_Bool haveMore); +// #endif /* XML_DTD */ + +// static void freeBindings(XML_Parser parser, BINDING *bindings); +// static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, +// const char *s, TAG_NAME *tagNamePtr, +// BINDING **bindingsPtr); +// static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, +// const ATTRIBUTE_ID *attId, const XML_Char *uri, +// BINDING **bindingsPtr); +// static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, +// XML_Bool isId, const XML_Char *dfltValue, +// XML_Parser parser); +// static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, +// XML_Bool isCdata, const char *, +// const char *, STRING_POOL *); +// static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *, +// XML_Bool isCdata, const char *, +// const char *, STRING_POOL *); +// static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, +// const char *start, const char *end); +// static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); +// static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, +// const char *start, const char *end); +// static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, +// const char *start, const char *end); +// static int reportComment(XML_Parser parser, const ENCODING *enc, +// const char *start, const char *end); +// static void reportDefault(XML_Parser parser, const ENCODING *enc, +// const char *start, const char *end); + +// static const XML_Char *getContext(XML_Parser parser); +// static XML_Bool setContext(XML_Parser parser, const XML_Char *context); + +// static void FASTCALL normalizePublicId(XML_Char *s); + +// static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms); +// /* do not call if m_parentParser != NULL */ +// static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); +// static void dtdDestroy(DTD *p, XML_Bool isDocEntity, +// const XML_Memory_Handling_Suite *ms); +// static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, +// const XML_Memory_Handling_Suite *ms); +// static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *, +// const HASH_TABLE *); +// static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, +// size_t createSize); +// static void FASTCALL hashTableInit(HASH_TABLE *, +// const XML_Memory_Handling_Suite *ms); +// static void FASTCALL hashTableClear(HASH_TABLE *); +// static void FASTCALL hashTableDestroy(HASH_TABLE *); +// static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); +// static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *); + +// static void FASTCALL poolInit(STRING_POOL *, +// const XML_Memory_Handling_Suite *ms); +// static void FASTCALL poolClear(STRING_POOL *); +// static void FASTCALL poolDestroy(STRING_POOL *); +// static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, +// const char *ptr, const char *end); +// static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, +// const char *ptr, const char *end); +// static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); +// static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, +// const XML_Char *s); +// static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, +// int n); +// static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, +// const XML_Char *s); + +// static int FASTCALL nextScaffoldPart(XML_Parser parser); +// static XML_Content *build_model(XML_Parser parser); +// static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc, +// const char *ptr, const char *end); + +// static XML_Char *copyString(const XML_Char *s, +// const XML_Memory_Handling_Suite *memsuite); + +// static unsigned long generate_hash_secret_salt(XML_Parser parser); +// static XML_Bool startParsing(XML_Parser parser); + +// static XML_Parser parserCreate(const XML_Char *encodingName, +// const XML_Memory_Handling_Suite *memsuite, +// const XML_Char *nameSep, DTD *dtd); + +// static void parserInit(XML_Parser parser, const XML_Char *encodingName); + +// #define poolStart(pool) ((pool)->start) +// #define poolEnd(pool) ((pool)->ptr) +// #define poolLength(pool) ((pool)->ptr - (pool)->start) +// #define poolChop(pool) ((void)--(pool->ptr)) +// #define poolLastChar(pool) (((pool)->ptr)[-1]) +// #define poolDiscard(pool) ((pool)->ptr = (pool)->start) +// #define poolFinish(pool) ((pool)->start = (pool)->ptr) +// #define poolAppendChar(pool, c) \ +// (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ +// ? 0 \ +// : ((*((pool)->ptr)++ = c), 1)) + +// struct XML_ParserStruct { +// /* The first member must be m_userData so that the XML_GetUserData +// macro works. */ +// void *m_userData; +// void *m_handlerArg; +// char *m_buffer; +// const XML_Memory_Handling_Suite m_mem; +// /* first character to be parsed */ +// const char *m_bufferPtr; +// /* past last character to be parsed */ +// char *m_bufferEnd; +// /* allocated end of m_buffer */ +// const char *m_bufferLim; +// XML_Index m_parseEndByteIndex; +// const char *m_parseEndPtr; +// XML_Char *m_dataBuf; +// XML_Char *m_dataBufEnd; +// XML_StartElementHandler m_startElementHandler; +// XML_EndElementHandler m_endElementHandler; +// XML_CharacterDataHandler m_characterDataHandler; +// XML_ProcessingInstructionHandler m_processingInstructionHandler; +// XML_CommentHandler m_commentHandler; +// XML_StartCdataSectionHandler m_startCdataSectionHandler; +// XML_EndCdataSectionHandler m_endCdataSectionHandler; +// XML_DefaultHandler m_defaultHandler; +// XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; +// XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; +// XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; +// XML_NotationDeclHandler m_notationDeclHandler; +// XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; +// XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; +// XML_NotStandaloneHandler m_notStandaloneHandler; +// XML_ExternalEntityRefHandler m_externalEntityRefHandler; +// XML_Parser m_externalEntityRefHandlerArg; +// XML_SkippedEntityHandler m_skippedEntityHandler; +// XML_UnknownEncodingHandler m_unknownEncodingHandler; +// XML_ElementDeclHandler m_elementDeclHandler; +// XML_AttlistDeclHandler m_attlistDeclHandler; +// XML_EntityDeclHandler m_entityDeclHandler; +// XML_XmlDeclHandler m_xmlDeclHandler; +// const ENCODING *m_encoding; +// INIT_ENCODING m_initEncoding; +// const ENCODING *m_internalEncoding; +// const XML_Char *m_protocolEncodingName; +// XML_Bool m_ns; +// XML_Bool m_ns_triplets; +// void *m_unknownEncodingMem; +// void *m_unknownEncodingData; +// void *m_unknownEncodingHandlerData; +// void(XMLCALL *m_unknownEncodingRelease)(void *); +// PROLOG_STATE m_prologState; +// Processor *m_processor; +// enum XML_Error m_errorCode; +// const char *m_eventPtr; +// const char *m_eventEndPtr; +// const char *m_positionPtr; +// OPEN_INTERNAL_ENTITY *m_openInternalEntities; +// OPEN_INTERNAL_ENTITY *m_freeInternalEntities; +// XML_Bool m_defaultExpandInternalEntities; +// int m_tagLevel; +// ENTITY *m_declEntity; +// const XML_Char *m_doctypeName; +// const XML_Char *m_doctypeSysid; +// const XML_Char *m_doctypePubid; +// const XML_Char *m_declAttributeType; +// const XML_Char *m_declNotationName; +// const XML_Char *m_declNotationPublicId; +// ELEMENT_TYPE *m_declElementType; +// ATTRIBUTE_ID *m_declAttributeId; +// XML_Bool m_declAttributeIsCdata; +// XML_Bool m_declAttributeIsId; +// DTD *m_dtd; +// const XML_Char *m_curBase; +// TAG *m_tagStack; +// TAG *m_freeTagList; +// BINDING *m_inheritedBindings; +// BINDING *m_freeBindingList; +// int m_attsSize; +// int m_nSpecifiedAtts; +// int m_idAttIndex; +// ATTRIBUTE *m_atts; +// NS_ATT *m_nsAtts; +// unsigned long m_nsAttsVersion; +// unsigned char m_nsAttsPower; +// #ifdef XML_ATTR_INFO +// XML_AttrInfo *m_attInfo; +// #endif +// POSITION m_position; +// STRING_POOL m_tempPool; +// STRING_POOL m_temp2Pool; +// char *m_groupConnector; +// unsigned int m_groupSize; +// XML_Char m_namespaceSeparator; +// XML_Parser m_parentParser; +// XML_ParsingStatus m_parsingStatus; +// #ifdef XML_DTD +// XML_Bool m_isParamEntity; +// XML_Bool m_useForeignDTD; +// enum XML_ParamEntityParsing m_paramEntityParsing; +// #endif +// unsigned long m_hash_secret_salt; +// }; + +// #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) +// #define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) +// #define FREE(parser, p) (parser->m_mem.free_fcn((p))) + +// XML_Parser XMLCALL +// XML_ParserCreate(const XML_Char *encodingName) { +// return XML_ParserCreate_MM(encodingName, NULL, NULL); +// } + +// XML_Parser XMLCALL +// XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { +// XML_Char tmp[2]; +// *tmp = nsSep; +// return XML_ParserCreate_MM(encodingName, NULL, tmp); +// } + +// static const XML_Char implicitContext[] +// = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, +// ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, +// ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, +// ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, +// ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, +// ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, +// ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, +// ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, +// '\0'}; + +// /* To avoid warnings about unused functions: */ +// #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) + +// # if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) + +// /* Obtain entropy on Linux 3.17+ */ +// static int +// writeRandomBytes_getrandom_nonblock(void *target, size_t count) { +// int success = 0; /* full count bytes written? */ +// size_t bytesWrittenTotal = 0; +// const unsigned int getrandomFlags = GRND_NONBLOCK; + +// do { +// void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); +// const size_t bytesToWrite = count - bytesWrittenTotal; + +// const int bytesWrittenMore = +// # if defined(HAVE_GETRANDOM) +// getrandom(currentTarget, bytesToWrite, getrandomFlags); +// # else +// syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); +// # endif + +// if (bytesWrittenMore > 0) { +// bytesWrittenTotal += bytesWrittenMore; +// if (bytesWrittenTotal >= count) +// success = 1; +// } +// } while (! success && (errno == EINTR)); + +// return success; +// } + +// # endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ + +// # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) + +// /* Extract entropy from /dev/urandom */ +// static int +// writeRandomBytes_dev_urandom(void *target, size_t count) { +// int success = 0; /* full count bytes written? */ +// size_t bytesWrittenTotal = 0; + +// const int fd = open("/dev/urandom", O_RDONLY); +// if (fd < 0) { +// return 0; +// } + +// do { +// void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); +// const size_t bytesToWrite = count - bytesWrittenTotal; + +// const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); + +// if (bytesWrittenMore > 0) { +// bytesWrittenTotal += bytesWrittenMore; +// if (bytesWrittenTotal >= count) +// success = 1; +// } +// } while (! success && (errno == EINTR)); + +// close(fd); +// return success; +// } + +// # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ + +// #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ + +// #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) + +// static void +// writeRandomBytes_arc4random(void *target, size_t count) { +// size_t bytesWrittenTotal = 0; + +// while (bytesWrittenTotal < count) { +// const uint32_t random32 = arc4random(); +// size_t i = 0; + +// for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); +// i++, bytesWrittenTotal++) { +// const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); +// ((uint8_t *)target)[bytesWrittenTotal] = random8; +// } +// } +// } + +// #endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */ + +// #ifdef _WIN32 + +// /* Obtain entropy on Windows using the rand_s() function which +// * generates cryptographically secure random numbers. Internally it +// * uses RtlGenRandom API which is present in Windows XP and later. +// */ +// static int +// writeRandomBytes_rand_s(void *target, size_t count) { +// size_t bytesWrittenTotal = 0; + +// while (bytesWrittenTotal < count) { +// unsigned int random32 = 0; +// size_t i = 0; + +// if (rand_s(&random32)) +// return 0; /* failure */ + +// for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); +// i++, bytesWrittenTotal++) { +// const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); +// ((uint8_t *)target)[bytesWrittenTotal] = random8; +// } +// } +// return 1; /* success */ +// } + +// #endif /* _WIN32 */ + +// #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) + +// static unsigned long +// gather_time_entropy(void) { +// # ifdef _WIN32 +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); /* never fails */ +// return ft.dwHighDateTime ^ ft.dwLowDateTime; +// # else +// struct timeval tv; +// int gettimeofday_res; + +// gettimeofday_res = gettimeofday(&tv, NULL); + +// # if defined(NDEBUG) +// (void)gettimeofday_res; +// # else +// assert(gettimeofday_res == 0); +// # endif /* defined(NDEBUG) */ + +// /* Microseconds time is <20 bits entropy */ +// return tv.tv_usec; +// # endif +// } + +// #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ + +// static unsigned long +// ENTROPY_DEBUG(const char *label, unsigned long entropy) { +// const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); +// if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { +// fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, +// (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); +// } +// return entropy; +// } + +// static unsigned long +// generate_hash_secret_salt(XML_Parser parser) { +// unsigned long entropy; +// (void)parser; + +// /* "Failproof" high quality providers: */ +// #if defined(HAVE_ARC4RANDOM_BUF) +// arc4random_buf(&entropy, sizeof(entropy)); +// return ENTROPY_DEBUG("arc4random_buf", entropy); +// #elif defined(HAVE_ARC4RANDOM) +// writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); +// return ENTROPY_DEBUG("arc4random", entropy); +// #else +// /* Try high quality providers first .. */ +// # ifdef _WIN32 +// if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { +// return ENTROPY_DEBUG("rand_s", entropy); +// } +// # elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) +// if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { +// return ENTROPY_DEBUG("getrandom", entropy); +// } +// # endif +// # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) +// if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { +// return ENTROPY_DEBUG("/dev/urandom", entropy); +// } +// # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ +// /* .. and self-made low quality for backup: */ + +// /* Process ID is 0 bits entropy if attacker has local access */ +// entropy = gather_time_entropy() ^ getpid(); + +// /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ +// if (sizeof(unsigned long) == 4) { +// return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); +// } else { +// return ENTROPY_DEBUG("fallback(8)", +// entropy * (unsigned long)2305843009213693951ULL); +// } +// #endif +// } + +// static unsigned long +// get_hash_secret_salt(XML_Parser parser) { +// if (parser->m_parentParser != NULL) +// return get_hash_secret_salt(parser->m_parentParser); +// return parser->m_hash_secret_salt; +// } + +// static XML_Bool /* only valid for root parser */ +// startParsing(XML_Parser parser) { +// /* hash functions must be initialized before setContext() is called */ +// if (parser->m_hash_secret_salt == 0) +// parser->m_hash_secret_salt = generate_hash_secret_salt(parser); +// if (parser->m_ns) { +// /* implicit context only set for root parser, since child +// parsers (i.e. external entity parsers) will inherit it +// */ +// return setContext(parser, implicitContext); +// } +// return XML_TRUE; +// } + +// XML_Parser XMLCALL +// XML_ParserCreate_MM(const XML_Char *encodingName, +// const XML_Memory_Handling_Suite *memsuite, +// const XML_Char *nameSep) { +// return parserCreate(encodingName, memsuite, nameSep, NULL); +// } + +// static XML_Parser +// parserCreate(const XML_Char *encodingName, +// const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, +// DTD *dtd) { +// XML_Parser parser; + +// if (memsuite) { +// XML_Memory_Handling_Suite *mtemp; +// parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); +// if (parser != NULL) { +// mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); +// mtemp->malloc_fcn = memsuite->malloc_fcn; +// mtemp->realloc_fcn = memsuite->realloc_fcn; +// mtemp->free_fcn = memsuite->free_fcn; +// } +// } else { +// XML_Memory_Handling_Suite *mtemp; +// parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); +// if (parser != NULL) { +// mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); +// mtemp->malloc_fcn = malloc; +// mtemp->realloc_fcn = realloc; +// mtemp->free_fcn = free; +// } +// } + +// if (! parser) +// return parser; + +// parser->m_buffer = NULL; +// parser->m_bufferLim = NULL; + +// parser->m_attsSize = INIT_ATTS_SIZE; +// parser->m_atts +// = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); +// if (parser->m_atts == NULL) { +// FREE(parser, parser); +// return NULL; +// } +// #ifdef XML_ATTR_INFO +// parser->m_attInfo = (XML_AttrInfo *)MALLOC( +// parser, parser->m_attsSize * sizeof(XML_AttrInfo)); +// if (parser->m_attInfo == NULL) { +// FREE(parser, parser->m_atts); +// FREE(parser, parser); +// return NULL; +// } +// #endif +// parser->m_dataBuf +// = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); +// if (parser->m_dataBuf == NULL) { +// FREE(parser, parser->m_atts); +// #ifdef XML_ATTR_INFO +// FREE(parser, parser->m_attInfo); +// #endif +// FREE(parser, parser); +// return NULL; +// } +// parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; + +// if (dtd) +// parser->m_dtd = dtd; +// else { +// parser->m_dtd = dtdCreate(&parser->m_mem); +// if (parser->m_dtd == NULL) { +// FREE(parser, parser->m_dataBuf); +// FREE(parser, parser->m_atts); +// #ifdef XML_ATTR_INFO +// FREE(parser, parser->m_attInfo); +// #endif +// FREE(parser, parser); +// return NULL; +// } +// } + +// parser->m_freeBindingList = NULL; +// parser->m_freeTagList = NULL; +// parser->m_freeInternalEntities = NULL; + +// parser->m_groupSize = 0; +// parser->m_groupConnector = NULL; + +// parser->m_unknownEncodingHandler = NULL; +// parser->m_unknownEncodingHandlerData = NULL; + +// parser->m_namespaceSeparator = ASCII_EXCL; +// parser->m_ns = XML_FALSE; +// parser->m_ns_triplets = XML_FALSE; + +// parser->m_nsAtts = NULL; +// parser->m_nsAttsVersion = 0; +// parser->m_nsAttsPower = 0; + +// parser->m_protocolEncodingName = NULL; + +// poolInit(&parser->m_tempPool, &(parser->m_mem)); +// poolInit(&parser->m_temp2Pool, &(parser->m_mem)); +// parserInit(parser, encodingName); + +// if (encodingName && ! parser->m_protocolEncodingName) { +// XML_ParserFree(parser); +// return NULL; +// } + +// if (nameSep) { +// parser->m_ns = XML_TRUE; +// parser->m_internalEncoding = XmlGetInternalEncodingNS(); +// parser->m_namespaceSeparator = *nameSep; +// } else { +// parser->m_internalEncoding = XmlGetInternalEncoding(); +// } + +// return parser; +// } + +// static void +// parserInit(XML_Parser parser, const XML_Char *encodingName) { +// parser->m_processor = prologInitProcessor; +// XmlPrologStateInit(&parser->m_prologState); +// if (encodingName != NULL) { +// parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); +// } +// parser->m_curBase = NULL; +// XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); +// parser->m_userData = NULL; +// parser->m_handlerArg = NULL; +// parser->m_startElementHandler = NULL; +// parser->m_endElementHandler = NULL; +// parser->m_characterDataHandler = NULL; +// parser->m_processingInstructionHandler = NULL; +// parser->m_commentHandler = NULL; +// parser->m_startCdataSectionHandler = NULL; +// parser->m_endCdataSectionHandler = NULL; +// parser->m_defaultHandler = NULL; +// parser->m_startDoctypeDeclHandler = NULL; +// parser->m_endDoctypeDeclHandler = NULL; +// parser->m_unparsedEntityDeclHandler = NULL; +// parser->m_notationDeclHandler = NULL; +// parser->m_startNamespaceDeclHandler = NULL; +// parser->m_endNamespaceDeclHandler = NULL; +// parser->m_notStandaloneHandler = NULL; +// parser->m_externalEntityRefHandler = NULL; +// parser->m_externalEntityRefHandlerArg = parser; +// parser->m_skippedEntityHandler = NULL; +// parser->m_elementDeclHandler = NULL; +// parser->m_attlistDeclHandler = NULL; +// parser->m_entityDeclHandler = NULL; +// parser->m_xmlDeclHandler = NULL; +// parser->m_bufferPtr = parser->m_buffer; +// parser->m_bufferEnd = parser->m_buffer; +// parser->m_parseEndByteIndex = 0; +// parser->m_parseEndPtr = NULL; +// parser->m_declElementType = NULL; +// parser->m_declAttributeId = NULL; +// parser->m_declEntity = NULL; +// parser->m_doctypeName = NULL; +// parser->m_doctypeSysid = NULL; +// parser->m_doctypePubid = NULL; +// parser->m_declAttributeType = NULL; +// parser->m_declNotationName = NULL; +// parser->m_declNotationPublicId = NULL; +// parser->m_declAttributeIsCdata = XML_FALSE; +// parser->m_declAttributeIsId = XML_FALSE; +// memset(&parser->m_position, 0, sizeof(POSITION)); +// parser->m_errorCode = XML_ERROR_NONE; +// parser->m_eventPtr = NULL; +// parser->m_eventEndPtr = NULL; +// parser->m_positionPtr = NULL; +// parser->m_openInternalEntities = NULL; +// parser->m_defaultExpandInternalEntities = XML_TRUE; +// parser->m_tagLevel = 0; +// parser->m_tagStack = NULL; +// parser->m_inheritedBindings = NULL; +// parser->m_nSpecifiedAtts = 0; +// parser->m_unknownEncodingMem = NULL; +// parser->m_unknownEncodingRelease = NULL; +// parser->m_unknownEncodingData = NULL; +// parser->m_parentParser = NULL; +// parser->m_parsingStatus.parsing = XML_INITIALIZED; +// #ifdef XML_DTD +// parser->m_isParamEntity = XML_FALSE; +// parser->m_useForeignDTD = XML_FALSE; +// parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +// #endif +// parser->m_hash_secret_salt = 0; +// } + +// /* moves list of bindings to m_freeBindingList */ +// static void FASTCALL +// moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { +// while (bindings) { +// BINDING *b = bindings; +// bindings = bindings->nextTagBinding; +// b->nextTagBinding = parser->m_freeBindingList; +// parser->m_freeBindingList = b; +// } +// } + +// XML_Bool XMLCALL +// XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { +// TAG *tStk; +// OPEN_INTERNAL_ENTITY *openEntityList; + +// if (parser == NULL) +// return XML_FALSE; + +// if (parser->m_parentParser) +// return XML_FALSE; +// /* move m_tagStack to m_freeTagList */ +// tStk = parser->m_tagStack; +// while (tStk) { +// TAG *tag = tStk; +// tStk = tStk->parent; +// tag->parent = parser->m_freeTagList; +// moveToFreeBindingList(parser, tag->bindings); +// tag->bindings = NULL; +// parser->m_freeTagList = tag; +// } +// /* move m_openInternalEntities to m_freeInternalEntities */ +// openEntityList = parser->m_openInternalEntities; +// while (openEntityList) { +// OPEN_INTERNAL_ENTITY *openEntity = openEntityList; +// openEntityList = openEntity->next; +// openEntity->next = parser->m_freeInternalEntities; +// parser->m_freeInternalEntities = openEntity; +// } +// moveToFreeBindingList(parser, parser->m_inheritedBindings); +// FREE(parser, parser->m_unknownEncodingMem); +// if (parser->m_unknownEncodingRelease) +// parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); +// poolClear(&parser->m_tempPool); +// poolClear(&parser->m_temp2Pool); +// FREE(parser, (void *)parser->m_protocolEncodingName); +// parser->m_protocolEncodingName = NULL; +// parserInit(parser, encodingName); +// dtdReset(parser->m_dtd, &parser->m_mem); +// return XML_TRUE; +// } + +// enum XML_Status XMLCALL +// XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { +// if (parser == NULL) +// return XML_STATUS_ERROR; +// /* Block after XML_Parse()/XML_ParseBuffer() has been called. +// XXX There's no way for the caller to determine which of the +// XXX possible error cases caused the XML_STATUS_ERROR return. +// */ +// if (parser->m_parsingStatus.parsing == XML_PARSING +// || parser->m_parsingStatus.parsing == XML_SUSPENDED) +// return XML_STATUS_ERROR; + +// /* Get rid of any previous encoding name */ +// FREE(parser, (void *)parser->m_protocolEncodingName); + +// if (encodingName == NULL) +// /* No new encoding name */ +// parser->m_protocolEncodingName = NULL; +// else { +// /* Copy the new encoding name into allocated memory */ +// parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); +// if (! parser->m_protocolEncodingName) +// return XML_STATUS_ERROR; +// } +// return XML_STATUS_OK; +// } + +// XML_Parser XMLCALL +// XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, +// const XML_Char *encodingName) { +// XML_Parser parser = oldParser; +// DTD *newDtd = NULL; +// DTD *oldDtd; +// XML_StartElementHandler oldStartElementHandler; +// XML_EndElementHandler oldEndElementHandler; +// XML_CharacterDataHandler oldCharacterDataHandler; +// XML_ProcessingInstructionHandler oldProcessingInstructionHandler; +// XML_CommentHandler oldCommentHandler; +// XML_StartCdataSectionHandler oldStartCdataSectionHandler; +// XML_EndCdataSectionHandler oldEndCdataSectionHandler; +// XML_DefaultHandler oldDefaultHandler; +// XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; +// XML_NotationDeclHandler oldNotationDeclHandler; +// XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; +// XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; +// XML_NotStandaloneHandler oldNotStandaloneHandler; +// XML_ExternalEntityRefHandler oldExternalEntityRefHandler; +// XML_SkippedEntityHandler oldSkippedEntityHandler; +// XML_UnknownEncodingHandler oldUnknownEncodingHandler; +// XML_ElementDeclHandler oldElementDeclHandler; +// XML_AttlistDeclHandler oldAttlistDeclHandler; +// XML_EntityDeclHandler oldEntityDeclHandler; +// XML_XmlDeclHandler oldXmlDeclHandler; +// ELEMENT_TYPE *oldDeclElementType; + +// void *oldUserData; +// void *oldHandlerArg; +// XML_Bool oldDefaultExpandInternalEntities; +// XML_Parser oldExternalEntityRefHandlerArg; +// #ifdef XML_DTD +// enum XML_ParamEntityParsing oldParamEntityParsing; +// int oldInEntityValue; +// #endif +// XML_Bool oldns_triplets; +// /* Note that the new parser shares the same hash secret as the old +// parser, so that dtdCopy and copyEntityTable can lookup values +// from hash tables associated with either parser without us having +// to worry which hash secrets each table has. +// */ +// unsigned long oldhash_secret_salt; + +// /* Validate the oldParser parameter before we pull everything out of it */ +// if (oldParser == NULL) +// return NULL; + +// /* Stash the original parser contents on the stack */ +// oldDtd = parser->m_dtd; +// oldStartElementHandler = parser->m_startElementHandler; +// oldEndElementHandler = parser->m_endElementHandler; +// oldCharacterDataHandler = parser->m_characterDataHandler; +// oldProcessingInstructionHandler = parser->m_processingInstructionHandler; +// oldCommentHandler = parser->m_commentHandler; +// oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; +// oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; +// oldDefaultHandler = parser->m_defaultHandler; +// oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; +// oldNotationDeclHandler = parser->m_notationDeclHandler; +// oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; +// oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; +// oldNotStandaloneHandler = parser->m_notStandaloneHandler; +// oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; +// oldSkippedEntityHandler = parser->m_skippedEntityHandler; +// oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; +// oldElementDeclHandler = parser->m_elementDeclHandler; +// oldAttlistDeclHandler = parser->m_attlistDeclHandler; +// oldEntityDeclHandler = parser->m_entityDeclHandler; +// oldXmlDeclHandler = parser->m_xmlDeclHandler; +// oldDeclElementType = parser->m_declElementType; + +// oldUserData = parser->m_userData; +// oldHandlerArg = parser->m_handlerArg; +// oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; +// oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; +// #ifdef XML_DTD +// oldParamEntityParsing = parser->m_paramEntityParsing; +// oldInEntityValue = parser->m_prologState.inEntityValue; +// #endif +// oldns_triplets = parser->m_ns_triplets; +// /* Note that the new parser shares the same hash secret as the old +// parser, so that dtdCopy and copyEntityTable can lookup values +// from hash tables associated with either parser without us having +// to worry which hash secrets each table has. +// */ +// oldhash_secret_salt = parser->m_hash_secret_salt; + +// #ifdef XML_DTD +// if (! context) +// newDtd = oldDtd; +// #endif /* XML_DTD */ + +// /* Note that the magical uses of the pre-processor to make field +// access look more like C++ require that `parser' be overwritten +// here. This makes this function more painful to follow than it +// would be otherwise. +// */ +// if (parser->m_ns) { +// XML_Char tmp[2]; +// *tmp = parser->m_namespaceSeparator; +// parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); +// } else { +// parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); +// } + +// if (! parser) +// return NULL; + +// parser->m_startElementHandler = oldStartElementHandler; +// parser->m_endElementHandler = oldEndElementHandler; +// parser->m_characterDataHandler = oldCharacterDataHandler; +// parser->m_processingInstructionHandler = oldProcessingInstructionHandler; +// parser->m_commentHandler = oldCommentHandler; +// parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; +// parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; +// parser->m_defaultHandler = oldDefaultHandler; +// parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; +// parser->m_notationDeclHandler = oldNotationDeclHandler; +// parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; +// parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; +// parser->m_notStandaloneHandler = oldNotStandaloneHandler; +// parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; +// parser->m_skippedEntityHandler = oldSkippedEntityHandler; +// parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; +// parser->m_elementDeclHandler = oldElementDeclHandler; +// parser->m_attlistDeclHandler = oldAttlistDeclHandler; +// parser->m_entityDeclHandler = oldEntityDeclHandler; +// parser->m_xmlDeclHandler = oldXmlDeclHandler; +// parser->m_declElementType = oldDeclElementType; +// parser->m_userData = oldUserData; +// if (oldUserData == oldHandlerArg) +// parser->m_handlerArg = parser->m_userData; +// else +// parser->m_handlerArg = parser; +// if (oldExternalEntityRefHandlerArg != oldParser) +// parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; +// parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; +// parser->m_ns_triplets = oldns_triplets; +// parser->m_hash_secret_salt = oldhash_secret_salt; +// parser->m_parentParser = oldParser; +// #ifdef XML_DTD +// parser->m_paramEntityParsing = oldParamEntityParsing; +// parser->m_prologState.inEntityValue = oldInEntityValue; +// if (context) { +// #endif /* XML_DTD */ +// if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) +// || ! setContext(parser, context)) { +// XML_ParserFree(parser); +// return NULL; +// } +// parser->m_processor = externalEntityInitProcessor; +// #ifdef XML_DTD +// } else { +// /* The DTD instance referenced by parser->m_dtd is shared between the +// document's root parser and external PE parsers, therefore one does not +// need to call setContext. In addition, one also *must* not call +// setContext, because this would overwrite existing prefix->binding +// pointers in parser->m_dtd with ones that get destroyed with the external +// PE parser. This would leave those prefixes with dangling pointers. +// */ +// parser->m_isParamEntity = XML_TRUE; +// XmlPrologStateInitExternalEntity(&parser->m_prologState); +// parser->m_processor = externalParEntInitProcessor; +// } +// #endif /* XML_DTD */ +// return parser; +// } + +// static void FASTCALL +// destroyBindings(BINDING *bindings, XML_Parser parser) { +// for (;;) { +// BINDING *b = bindings; +// if (! b) +// break; +// bindings = b->nextTagBinding; +// FREE(parser, b->uri); +// FREE(parser, b); +// } +// } + +// void XMLCALL +// XML_ParserFree(XML_Parser parser) { +// TAG *tagList; +// OPEN_INTERNAL_ENTITY *entityList; +// if (parser == NULL) +// return; +// /* free m_tagStack and m_freeTagList */ +// tagList = parser->m_tagStack; +// for (;;) { +// TAG *p; +// if (tagList == NULL) { +// if (parser->m_freeTagList == NULL) +// break; +// tagList = parser->m_freeTagList; +// parser->m_freeTagList = NULL; +// } +// p = tagList; +// tagList = tagList->parent; +// FREE(parser, p->buf); +// destroyBindings(p->bindings, parser); +// FREE(parser, p); +// } +// /* free m_openInternalEntities and m_freeInternalEntities */ +// entityList = parser->m_openInternalEntities; +// for (;;) { +// OPEN_INTERNAL_ENTITY *openEntity; +// if (entityList == NULL) { +// if (parser->m_freeInternalEntities == NULL) +// break; +// entityList = parser->m_freeInternalEntities; +// parser->m_freeInternalEntities = NULL; +// } +// openEntity = entityList; +// entityList = entityList->next; +// FREE(parser, openEntity); +// } + +// destroyBindings(parser->m_freeBindingList, parser); +// destroyBindings(parser->m_inheritedBindings, parser); +// poolDestroy(&parser->m_tempPool); +// poolDestroy(&parser->m_temp2Pool); +// FREE(parser, (void *)parser->m_protocolEncodingName); +// #ifdef XML_DTD +// /* external parameter entity parsers share the DTD structure +// parser->m_dtd with the root parser, so we must not destroy it +// */ +// if (! parser->m_isParamEntity && parser->m_dtd) +// #else +// if (parser->m_dtd) +// #endif /* XML_DTD */ +// dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, +// &parser->m_mem); +// FREE(parser, (void *)parser->m_atts); +// #ifdef XML_ATTR_INFO +// FREE(parser, (void *)parser->m_attInfo); +// #endif +// FREE(parser, parser->m_groupConnector); +// FREE(parser, parser->m_buffer); +// FREE(parser, parser->m_dataBuf); +// FREE(parser, parser->m_nsAtts); +// FREE(parser, parser->m_unknownEncodingMem); +// if (parser->m_unknownEncodingRelease) +// parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); +// FREE(parser, parser); +// } + +// void XMLCALL +// XML_UseParserAsHandlerArg(XML_Parser parser) { +// if (parser != NULL) +// parser->m_handlerArg = parser; +// } + +// enum XML_Error XMLCALL +// XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { +// if (parser == NULL) +// return XML_ERROR_INVALID_ARGUMENT; +// #ifdef XML_DTD +// /* block after XML_Parse()/XML_ParseBuffer() has been called */ +// if (parser->m_parsingStatus.parsing == XML_PARSING +// || parser->m_parsingStatus.parsing == XML_SUSPENDED) +// return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; +// parser->m_useForeignDTD = useDTD; +// return XML_ERROR_NONE; +// #else +// return XML_ERROR_FEATURE_REQUIRES_XML_DTD; +// #endif +// } + +// void XMLCALL +// XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { +// if (parser == NULL) +// return; +// /* block after XML_Parse()/XML_ParseBuffer() has been called */ +// if (parser->m_parsingStatus.parsing == XML_PARSING +// || parser->m_parsingStatus.parsing == XML_SUSPENDED) +// return; +// parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; +// } + +// void XMLCALL +// XML_SetUserData(XML_Parser parser, void *p) { +// if (parser == NULL) +// return; +// if (parser->m_handlerArg == parser->m_userData) +// parser->m_handlerArg = parser->m_userData = p; +// else +// parser->m_userData = p; +// } + +// enum XML_Status XMLCALL +// XML_SetBase(XML_Parser parser, const XML_Char *p) { +// if (parser == NULL) +// return XML_STATUS_ERROR; +// if (p) { +// p = poolCopyString(&parser->m_dtd->pool, p); +// if (! p) +// return XML_STATUS_ERROR; +// parser->m_curBase = p; +// } else +// parser->m_curBase = NULL; +// return XML_STATUS_OK; +// } + +// const XML_Char *XMLCALL +// XML_GetBase(XML_Parser parser) { +// if (parser == NULL) +// return NULL; +// return parser->m_curBase; +// } + +// int XMLCALL +// XML_GetSpecifiedAttributeCount(XML_Parser parser) { +// if (parser == NULL) +// return -1; +// return parser->m_nSpecifiedAtts; +// } + +// int XMLCALL +// XML_GetIdAttributeIndex(XML_Parser parser) { +// if (parser == NULL) +// return -1; +// return parser->m_idAttIndex; +// } + +// #ifdef XML_ATTR_INFO +// const XML_AttrInfo *XMLCALL +// XML_GetAttributeInfo(XML_Parser parser) { +// if (parser == NULL) +// return NULL; +// return parser->m_attInfo; +// } +// #endif + +// void XMLCALL +// XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, +// XML_EndElementHandler end) { +// if (parser == NULL) +// return; +// parser->m_startElementHandler = start; +// parser->m_endElementHandler = end; +// } + +// void XMLCALL +// XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { +// if (parser != NULL) +// parser->m_startElementHandler = start; +// } + +// void XMLCALL +// XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { +// if (parser != NULL) +// parser->m_endElementHandler = end; +// } + +// void XMLCALL +// XML_SetCharacterDataHandler(XML_Parser parser, +// XML_CharacterDataHandler handler) { +// if (parser != NULL) +// parser->m_characterDataHandler = handler; +// } + +// void XMLCALL +// XML_SetProcessingInstructionHandler(XML_Parser parser, +// XML_ProcessingInstructionHandler handler) { +// if (parser != NULL) +// parser->m_processingInstructionHandler = handler; +// } + +// void XMLCALL +// XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { +// if (parser != NULL) +// parser->m_commentHandler = handler; +// } + +// void XMLCALL +// XML_SetCdataSectionHandler(XML_Parser parser, +// XML_StartCdataSectionHandler start, +// XML_EndCdataSectionHandler end) { +// if (parser == NULL) +// return; +// parser->m_startCdataSectionHandler = start; +// parser->m_endCdataSectionHandler = end; +// } + +// void XMLCALL +// XML_SetStartCdataSectionHandler(XML_Parser parser, +// XML_StartCdataSectionHandler start) { +// if (parser != NULL) +// parser->m_startCdataSectionHandler = start; +// } + +// void XMLCALL +// XML_SetEndCdataSectionHandler(XML_Parser parser, +// XML_EndCdataSectionHandler end) { +// if (parser != NULL) +// parser->m_endCdataSectionHandler = end; +// } + +// void XMLCALL +// XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { +// if (parser == NULL) +// return; +// parser->m_defaultHandler = handler; +// parser->m_defaultExpandInternalEntities = XML_FALSE; +// } + +// void XMLCALL +// XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { +// if (parser == NULL) +// return; +// parser->m_defaultHandler = handler; +// parser->m_defaultExpandInternalEntities = XML_TRUE; +// } + +// void XMLCALL +// XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, +// XML_EndDoctypeDeclHandler end) { +// if (parser == NULL) +// return; +// parser->m_startDoctypeDeclHandler = start; +// parser->m_endDoctypeDeclHandler = end; +// } + +// void XMLCALL +// XML_SetStartDoctypeDeclHandler(XML_Parser parser, +// XML_StartDoctypeDeclHandler start) { +// if (parser != NULL) +// parser->m_startDoctypeDeclHandler = start; +// } + +// void XMLCALL +// XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { +// if (parser != NULL) +// parser->m_endDoctypeDeclHandler = end; +// } + +// void XMLCALL +// XML_SetUnparsedEntityDeclHandler(XML_Parser parser, +// XML_UnparsedEntityDeclHandler handler) { +// if (parser != NULL) +// parser->m_unparsedEntityDeclHandler = handler; +// } + +// void XMLCALL +// XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { +// if (parser != NULL) +// parser->m_notationDeclHandler = handler; +// } + +// void XMLCALL +// XML_SetNamespaceDeclHandler(XML_Parser parser, +// XML_StartNamespaceDeclHandler start, +// XML_EndNamespaceDeclHandler end) { +// if (parser == NULL) +// return; +// parser->m_startNamespaceDeclHandler = start; +// parser->m_endNamespaceDeclHandler = end; +// } + +// void XMLCALL +// XML_SetStartNamespaceDeclHandler(XML_Parser parser, +// XML_StartNamespaceDeclHandler start) { +// if (parser != NULL) +// parser->m_startNamespaceDeclHandler = start; +// } + +// void XMLCALL +// XML_SetEndNamespaceDeclHandler(XML_Parser parser, +// XML_EndNamespaceDeclHandler end) { +// if (parser != NULL) +// parser->m_endNamespaceDeclHandler = end; +// } + +// void XMLCALL +// XML_SetNotStandaloneHandler(XML_Parser parser, +// XML_NotStandaloneHandler handler) { +// if (parser != NULL) +// parser->m_notStandaloneHandler = handler; +// } + +// void XMLCALL +// XML_SetExternalEntityRefHandler(XML_Parser parser, +// XML_ExternalEntityRefHandler handler) { +// if (parser != NULL) +// parser->m_externalEntityRefHandler = handler; +// } + +// void XMLCALL +// XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { +// if (parser == NULL) +// return; +// if (arg) +// parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; +// else +// parser->m_externalEntityRefHandlerArg = parser; +// } + +// void XMLCALL +// XML_SetSkippedEntityHandler(XML_Parser parser, +// XML_SkippedEntityHandler handler) { +// if (parser != NULL) +// parser->m_skippedEntityHandler = handler; +// } + +// void XMLCALL +// XML_SetUnknownEncodingHandler(XML_Parser parser, +// XML_UnknownEncodingHandler handler, void *data) { +// if (parser == NULL) +// return; +// parser->m_unknownEncodingHandler = handler; +// parser->m_unknownEncodingHandlerData = data; +// } + +// void XMLCALL +// XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { +// if (parser != NULL) +// parser->m_elementDeclHandler = eldecl; +// } + +// void XMLCALL +// XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { +// if (parser != NULL) +// parser->m_attlistDeclHandler = attdecl; +// } + +// void XMLCALL +// XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { +// if (parser != NULL) +// parser->m_entityDeclHandler = handler; +// } + +// void XMLCALL +// XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { +// if (parser != NULL) +// parser->m_xmlDeclHandler = handler; +// } + +// int XMLCALL +// XML_SetParamEntityParsing(XML_Parser parser, +// enum XML_ParamEntityParsing peParsing) { +// if (parser == NULL) +// return 0; +// /* block after XML_Parse()/XML_ParseBuffer() has been called */ +// if (parser->m_parsingStatus.parsing == XML_PARSING +// || parser->m_parsingStatus.parsing == XML_SUSPENDED) +// return 0; +// #ifdef XML_DTD +// parser->m_paramEntityParsing = peParsing; +// return 1; +// #else +// return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; +// #endif +// } + +// int XMLCALL +// XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { +// if (parser == NULL) +// return 0; +// if (parser->m_parentParser) +// return XML_SetHashSalt(parser->m_parentParser, hash_salt); +// /* block after XML_Parse()/XML_ParseBuffer() has been called */ +// if (parser->m_parsingStatus.parsing == XML_PARSING +// || parser->m_parsingStatus.parsing == XML_SUSPENDED) +// return 0; +// parser->m_hash_secret_salt = hash_salt; +// return 1; +// } + +// enum XML_Status XMLCALL +// XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { +// if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { +// if (parser != NULL) +// parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; +// return XML_STATUS_ERROR; +// } +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// parser->m_errorCode = XML_ERROR_SUSPENDED; +// return XML_STATUS_ERROR; +// case XML_FINISHED: +// parser->m_errorCode = XML_ERROR_FINISHED; +// return XML_STATUS_ERROR; +// case XML_INITIALIZED: +// if (parser->m_parentParser == NULL && ! startParsing(parser)) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// return XML_STATUS_ERROR; +// } +// /* fall through */ +// default: +// parser->m_parsingStatus.parsing = XML_PARSING; +// } + +// if (len == 0) { +// parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; +// if (! isFinal) +// return XML_STATUS_OK; +// parser->m_positionPtr = parser->m_bufferPtr; +// parser->m_parseEndPtr = parser->m_bufferEnd; + +// /* If data are left over from last buffer, and we now know that these +// data are the final chunk of input, then we have to check them again +// to detect errors based on that fact. +// */ +// parser->m_errorCode +// = parser->m_processor(parser, parser->m_bufferPtr, +// parser->m_parseEndPtr, &parser->m_bufferPtr); + +// if (parser->m_errorCode == XML_ERROR_NONE) { +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// /* It is hard to be certain, but it seems that this case +// * cannot occur. This code is cleaning up a previous parse +// * with no new data (since len == 0). Changing the parsing +// * state requires getting to execute a handler function, and +// * there doesn't seem to be an opportunity for that while in +// * this circumstance. +// * +// * Given the uncertainty, we retain the code but exclude it +// * from coverage tests. +// * +// * LCOV_EXCL_START +// */ +// XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, +// parser->m_bufferPtr, &parser->m_position); +// parser->m_positionPtr = parser->m_bufferPtr; +// return XML_STATUS_SUSPENDED; +// /* LCOV_EXCL_STOP */ +// case XML_INITIALIZED: +// case XML_PARSING: +// parser->m_parsingStatus.parsing = XML_FINISHED; +// /* fall through */ +// default: +// return XML_STATUS_OK; +// } +// } +// parser->m_eventEndPtr = parser->m_eventPtr; +// parser->m_processor = errorProcessor; +// return XML_STATUS_ERROR; +// } +// #ifndef XML_CONTEXT_BYTES +// else if (parser->m_bufferPtr == parser->m_bufferEnd) { +// const char *end; +// int nLeftOver; +// enum XML_Status result; +// /* Detect overflow (a+b > MAX <==> b > MAX-a) */ +// if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// parser->m_eventPtr = parser->m_eventEndPtr = NULL; +// parser->m_processor = errorProcessor; +// return XML_STATUS_ERROR; +// } +// parser->m_parseEndByteIndex += len; +// parser->m_positionPtr = s; +// parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; + +// parser->m_errorCode +// = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); + +// if (parser->m_errorCode != XML_ERROR_NONE) { +// parser->m_eventEndPtr = parser->m_eventPtr; +// parser->m_processor = errorProcessor; +// return XML_STATUS_ERROR; +// } else { +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// result = XML_STATUS_SUSPENDED; +// break; +// case XML_INITIALIZED: +// case XML_PARSING: +// if (isFinal) { +// parser->m_parsingStatus.parsing = XML_FINISHED; +// return XML_STATUS_OK; +// } +// /* fall through */ +// default: +// result = XML_STATUS_OK; +// } +// } + +// XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, +// &parser->m_position); +// nLeftOver = s + len - end; +// if (nLeftOver) { +// if (parser->m_buffer == NULL +// || nLeftOver > parser->m_bufferLim - parser->m_buffer) { +// /* avoid _signed_ integer overflow */ +// char *temp = NULL; +// const int bytesToAllocate = (int)((unsigned)len * 2U); +// if (bytesToAllocate > 0) { +// temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate); +// } +// if (temp == NULL) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// parser->m_eventPtr = parser->m_eventEndPtr = NULL; +// parser->m_processor = errorProcessor; +// return XML_STATUS_ERROR; +// } +// parser->m_buffer = temp; +// parser->m_bufferLim = parser->m_buffer + bytesToAllocate; +// } +// memcpy(parser->m_buffer, end, nLeftOver); +// } +// parser->m_bufferPtr = parser->m_buffer; +// parser->m_bufferEnd = parser->m_buffer + nLeftOver; +// parser->m_positionPtr = parser->m_bufferPtr; +// parser->m_parseEndPtr = parser->m_bufferEnd; +// parser->m_eventPtr = parser->m_bufferPtr; +// parser->m_eventEndPtr = parser->m_bufferPtr; +// return result; +// } +// #endif /* not defined XML_CONTEXT_BYTES */ +// else { +// void *buff = XML_GetBuffer(parser, len); +// if (buff == NULL) +// return XML_STATUS_ERROR; +// else { +// memcpy(buff, s, len); +// return XML_ParseBuffer(parser, len, isFinal); +// } +// } +// } + +// enum XML_Status XMLCALL +// XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { +// const char *start; +// enum XML_Status result = XML_STATUS_OK; + +// if (parser == NULL) +// return XML_STATUS_ERROR; +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// parser->m_errorCode = XML_ERROR_SUSPENDED; +// return XML_STATUS_ERROR; +// case XML_FINISHED: +// parser->m_errorCode = XML_ERROR_FINISHED; +// return XML_STATUS_ERROR; +// case XML_INITIALIZED: +// if (parser->m_parentParser == NULL && ! startParsing(parser)) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// return XML_STATUS_ERROR; +// } +// /* fall through */ +// default: +// parser->m_parsingStatus.parsing = XML_PARSING; +// } + +// start = parser->m_bufferPtr; +// parser->m_positionPtr = start; +// parser->m_bufferEnd += len; +// parser->m_parseEndPtr = parser->m_bufferEnd; +// parser->m_parseEndByteIndex += len; +// parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; + +// parser->m_errorCode = parser->m_processor( +// parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); + +// if (parser->m_errorCode != XML_ERROR_NONE) { +// parser->m_eventEndPtr = parser->m_eventPtr; +// parser->m_processor = errorProcessor; +// return XML_STATUS_ERROR; +// } else { +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// result = XML_STATUS_SUSPENDED; +// break; +// case XML_INITIALIZED: +// case XML_PARSING: +// if (isFinal) { +// parser->m_parsingStatus.parsing = XML_FINISHED; +// return result; +// } +// default:; /* should not happen */ +// } +// } + +// XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, +// parser->m_bufferPtr, &parser->m_position); +// parser->m_positionPtr = parser->m_bufferPtr; +// return result; +// } + +// void *XMLCALL +// XML_GetBuffer(XML_Parser parser, int len) { +// if (parser == NULL) +// return NULL; +// if (len < 0) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// return NULL; +// } +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// parser->m_errorCode = XML_ERROR_SUSPENDED; +// return NULL; +// case XML_FINISHED: +// parser->m_errorCode = XML_ERROR_FINISHED; +// return NULL; +// default:; +// } + +// if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) { +// #ifdef XML_CONTEXT_BYTES +// int keep; +// #endif /* defined XML_CONTEXT_BYTES */ +// /* Do not invoke signed arithmetic overflow: */ +// int neededSize = (int)((unsigned)len +// + (unsigned)EXPAT_SAFE_PTR_DIFF( +// parser->m_bufferEnd, parser->m_bufferPtr)); +// if (neededSize < 0) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// return NULL; +// } +// #ifdef XML_CONTEXT_BYTES +// keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); +// if (keep > XML_CONTEXT_BYTES) +// keep = XML_CONTEXT_BYTES; +// neededSize += keep; +// #endif /* defined XML_CONTEXT_BYTES */ +// if (neededSize +// <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { +// #ifdef XML_CONTEXT_BYTES +// if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { +// int offset +// = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) +// - keep; +// /* The buffer pointers cannot be NULL here; we have at least some bytes +// * in the buffer */ +// memmove(parser->m_buffer, &parser->m_buffer[offset], +// parser->m_bufferEnd - parser->m_bufferPtr + keep); +// parser->m_bufferEnd -= offset; +// parser->m_bufferPtr -= offset; +// } +// #else +// if (parser->m_buffer && parser->m_bufferPtr) { +// memmove(parser->m_buffer, parser->m_bufferPtr, +// EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); +// parser->m_bufferEnd +// = parser->m_buffer +// + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); +// parser->m_bufferPtr = parser->m_buffer; +// } +// #endif /* not defined XML_CONTEXT_BYTES */ +// } else { +// char *newBuf; +// int bufferSize +// = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); +// if (bufferSize == 0) +// bufferSize = INIT_BUFFER_SIZE; +// do { +// /* Do not invoke signed arithmetic overflow: */ +// bufferSize = (int)(2U * (unsigned)bufferSize); +// } while (bufferSize < neededSize && bufferSize > 0); +// if (bufferSize <= 0) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// return NULL; +// } +// newBuf = (char *)MALLOC(parser, bufferSize); +// if (newBuf == 0) { +// parser->m_errorCode = XML_ERROR_NO_MEMORY; +// return NULL; +// } +// parser->m_bufferLim = newBuf + bufferSize; +// #ifdef XML_CONTEXT_BYTES +// if (parser->m_bufferPtr) { +// memcpy(newBuf, &parser->m_bufferPtr[-keep], +// EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) +// + keep); +// FREE(parser, parser->m_buffer); +// parser->m_buffer = newBuf; +// parser->m_bufferEnd +// = parser->m_buffer +// + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) +// + keep; +// parser->m_bufferPtr = parser->m_buffer + keep; +// } else { +// /* This must be a brand new buffer with no data in it yet */ +// parser->m_bufferEnd = newBuf; +// parser->m_bufferPtr = parser->m_buffer = newBuf; +// } +// #else +// if (parser->m_bufferPtr) { +// memcpy(newBuf, parser->m_bufferPtr, +// EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); +// FREE(parser, parser->m_buffer); +// parser->m_bufferEnd +// = newBuf +// + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); +// } else { +// /* This must be a brand new buffer with no data in it yet */ +// parser->m_bufferEnd = newBuf; +// } +// parser->m_bufferPtr = parser->m_buffer = newBuf; +// #endif /* not defined XML_CONTEXT_BYTES */ +// } +// parser->m_eventPtr = parser->m_eventEndPtr = NULL; +// parser->m_positionPtr = NULL; +// } +// return parser->m_bufferEnd; +// } + +// enum XML_Status XMLCALL +// XML_StopParser(XML_Parser parser, XML_Bool resumable) { +// if (parser == NULL) +// return XML_STATUS_ERROR; +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// if (resumable) { +// parser->m_errorCode = XML_ERROR_SUSPENDED; +// return XML_STATUS_ERROR; +// } +// parser->m_parsingStatus.parsing = XML_FINISHED; +// break; +// case XML_FINISHED: +// parser->m_errorCode = XML_ERROR_FINISHED; +// return XML_STATUS_ERROR; +// default: +// if (resumable) { +// #ifdef XML_DTD +// if (parser->m_isParamEntity) { +// parser->m_errorCode = XML_ERROR_SUSPEND_PE; +// return XML_STATUS_ERROR; +// } +// #endif +// parser->m_parsingStatus.parsing = XML_SUSPENDED; +// } else +// parser->m_parsingStatus.parsing = XML_FINISHED; +// } +// return XML_STATUS_OK; +// } + +// enum XML_Status XMLCALL +// XML_ResumeParser(XML_Parser parser) { +// enum XML_Status result = XML_STATUS_OK; + +// if (parser == NULL) +// return XML_STATUS_ERROR; +// if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { +// parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; +// return XML_STATUS_ERROR; +// } +// parser->m_parsingStatus.parsing = XML_PARSING; + +// parser->m_errorCode = parser->m_processor( +// parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); + +// if (parser->m_errorCode != XML_ERROR_NONE) { +// parser->m_eventEndPtr = parser->m_eventPtr; +// parser->m_processor = errorProcessor; +// return XML_STATUS_ERROR; +// } else { +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// result = XML_STATUS_SUSPENDED; +// break; +// case XML_INITIALIZED: +// case XML_PARSING: +// if (parser->m_parsingStatus.finalBuffer) { +// parser->m_parsingStatus.parsing = XML_FINISHED; +// return result; +// } +// default:; +// } +// } + +// XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, +// parser->m_bufferPtr, &parser->m_position); +// parser->m_positionPtr = parser->m_bufferPtr; +// return result; +// } + +// void XMLCALL +// XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { +// if (parser == NULL) +// return; +// assert(status != NULL); +// *status = parser->m_parsingStatus; +// } + +// enum XML_Error XMLCALL +// XML_GetErrorCode(XML_Parser parser) { +// if (parser == NULL) +// return XML_ERROR_INVALID_ARGUMENT; +// return parser->m_errorCode; +// } + +// XML_Index XMLCALL +// XML_GetCurrentByteIndex(XML_Parser parser) { +// if (parser == NULL) +// return -1; +// if (parser->m_eventPtr) +// return (XML_Index)(parser->m_parseEndByteIndex +// - (parser->m_parseEndPtr - parser->m_eventPtr)); +// return -1; +// } + +// int XMLCALL +// XML_GetCurrentByteCount(XML_Parser parser) { +// if (parser == NULL) +// return 0; +// if (parser->m_eventEndPtr && parser->m_eventPtr) +// return (int)(parser->m_eventEndPtr - parser->m_eventPtr); +// return 0; +// } + +// const char *XMLCALL +// XML_GetInputContext(XML_Parser parser, int *offset, int *size) { +// #ifdef XML_CONTEXT_BYTES +// if (parser == NULL) +// return NULL; +// if (parser->m_eventPtr && parser->m_buffer) { +// if (offset != NULL) +// *offset = (int)(parser->m_eventPtr - parser->m_buffer); +// if (size != NULL) +// *size = (int)(parser->m_bufferEnd - parser->m_buffer); +// return parser->m_buffer; +// } +// #else +// (void)parser; +// (void)offset; +// (void)size; +// #endif /* defined XML_CONTEXT_BYTES */ +// return (char *)0; +// } + +// XML_Size XMLCALL +// XML_GetCurrentLineNumber(XML_Parser parser) { +// if (parser == NULL) +// return 0; +// if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { +// XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, +// parser->m_eventPtr, &parser->m_position); +// parser->m_positionPtr = parser->m_eventPtr; +// } +// return parser->m_position.lineNumber + 1; +// } + +// XML_Size XMLCALL +// XML_GetCurrentColumnNumber(XML_Parser parser) { +// if (parser == NULL) +// return 0; +// if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { +// XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, +// parser->m_eventPtr, &parser->m_position); +// parser->m_positionPtr = parser->m_eventPtr; +// } +// return parser->m_position.columnNumber; +// } + +// void XMLCALL +// XML_FreeContentModel(XML_Parser parser, XML_Content *model) { +// if (parser != NULL) +// FREE(parser, model); +// } + +// void *XMLCALL +// XML_MemMalloc(XML_Parser parser, size_t size) { +// if (parser == NULL) +// return NULL; +// return MALLOC(parser, size); +// } + +// void *XMLCALL +// XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { +// if (parser == NULL) +// return NULL; +// return REALLOC(parser, ptr, size); +// } + +// void XMLCALL +// XML_MemFree(XML_Parser parser, void *ptr) { +// if (parser != NULL) +// FREE(parser, ptr); +// } + +// void XMLCALL +// XML_DefaultCurrent(XML_Parser parser) { +// if (parser == NULL) +// return; +// if (parser->m_defaultHandler) { +// if (parser->m_openInternalEntities) +// reportDefault(parser, parser->m_internalEncoding, +// parser->m_openInternalEntities->internalEventPtr, +// parser->m_openInternalEntities->internalEventEndPtr); +// else +// reportDefault(parser, parser->m_encoding, parser->m_eventPtr, +// parser->m_eventEndPtr); +// } +// } + +// const XML_LChar *XMLCALL +// XML_ErrorString(enum XML_Error code) { +// switch (code) { +// case XML_ERROR_NONE: +// return NULL; +// case XML_ERROR_NO_MEMORY: +// return XML_L("out of memory"); +// case XML_ERROR_SYNTAX: +// return XML_L("syntax error"); +// case XML_ERROR_NO_ELEMENTS: +// return XML_L("no element found"); +// case XML_ERROR_INVALID_TOKEN: +// return XML_L("not well-formed (invalid token)"); +// case XML_ERROR_UNCLOSED_TOKEN: +// return XML_L("unclosed token"); +// case XML_ERROR_PARTIAL_CHAR: +// return XML_L("partial character"); +// case XML_ERROR_TAG_MISMATCH: +// return XML_L("mismatched tag"); +// case XML_ERROR_DUPLICATE_ATTRIBUTE: +// return XML_L("duplicate attribute"); +// case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: +// return XML_L("junk after document element"); +// case XML_ERROR_PARAM_ENTITY_REF: +// return XML_L("illegal parameter entity reference"); +// case XML_ERROR_UNDEFINED_ENTITY: +// return XML_L("undefined entity"); +// case XML_ERROR_RECURSIVE_ENTITY_REF: +// return XML_L("recursive entity reference"); +// case XML_ERROR_ASYNC_ENTITY: +// return XML_L("asynchronous entity"); +// case XML_ERROR_BAD_CHAR_REF: +// return XML_L("reference to invalid character number"); +// case XML_ERROR_BINARY_ENTITY_REF: +// return XML_L("reference to binary entity"); +// case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: +// return XML_L("reference to external entity in attribute"); +// case XML_ERROR_MISPLACED_XML_PI: +// return XML_L("XML or text declaration not at start of entity"); +// case XML_ERROR_UNKNOWN_ENCODING: +// return XML_L("unknown encoding"); +// case XML_ERROR_INCORRECT_ENCODING: +// return XML_L("encoding specified in XML declaration is incorrect"); +// case XML_ERROR_UNCLOSED_CDATA_SECTION: +// return XML_L("unclosed CDATA section"); +// case XML_ERROR_EXTERNAL_ENTITY_HANDLING: +// return XML_L("error in processing external entity reference"); +// case XML_ERROR_NOT_STANDALONE: +// return XML_L("document is not standalone"); +// case XML_ERROR_UNEXPECTED_STATE: +// return XML_L("unexpected parser state - please send a bug report"); +// case XML_ERROR_ENTITY_DECLARED_IN_PE: +// return XML_L("entity declared in parameter entity"); +// case XML_ERROR_FEATURE_REQUIRES_XML_DTD: +// return XML_L("requested feature requires XML_DTD support in Expat"); +// case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: +// return XML_L("cannot change setting once parsing has begun"); +// /* Added in 1.95.7. */ +// case XML_ERROR_UNBOUND_PREFIX: +// return XML_L("unbound prefix"); +// /* Added in 1.95.8. */ +// case XML_ERROR_UNDECLARING_PREFIX: +// return XML_L("must not undeclare prefix"); +// case XML_ERROR_INCOMPLETE_PE: +// return XML_L("incomplete markup in parameter entity"); +// case XML_ERROR_XML_DECL: +// return XML_L("XML declaration not well-formed"); +// case XML_ERROR_TEXT_DECL: +// return XML_L("text declaration not well-formed"); +// case XML_ERROR_PUBLICID: +// return XML_L("illegal character(s) in public id"); +// case XML_ERROR_SUSPENDED: +// return XML_L("parser suspended"); +// case XML_ERROR_NOT_SUSPENDED: +// return XML_L("parser not suspended"); +// case XML_ERROR_ABORTED: +// return XML_L("parsing aborted"); +// case XML_ERROR_FINISHED: +// return XML_L("parsing finished"); +// case XML_ERROR_SUSPEND_PE: +// return XML_L("cannot suspend in external parameter entity"); +// /* Added in 2.0.0. */ +// case XML_ERROR_RESERVED_PREFIX_XML: +// return XML_L( +// "reserved prefix (xml) must not be undeclared or bound to another namespace name"); +// case XML_ERROR_RESERVED_PREFIX_XMLNS: +// return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); +// case XML_ERROR_RESERVED_NAMESPACE_URI: +// return XML_L( +// "prefix must not be bound to one of the reserved namespace names"); +// /* Added in 2.2.5. */ +// case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ +// return XML_L("invalid argument"); +// } +// return NULL; +// } + +// const XML_LChar *XMLCALL +// XML_ExpatVersion(void) { +// /* V1 is used to string-ize the version number. However, it would +// string-ize the actual version macro *names* unless we get them +// substituted before being passed to V1. CPP is defined to expand +// a macro, then rescan for more expansions. Thus, we use V2 to expand +// the version macros, then CPP will expand the resulting V1() macro +// with the correct numerals. */ +// /* ### I'm assuming cpp is portable in this respect... */ + +// #define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c) +// #define V2(a, b, c) XML_L("expat_") V1(a, b, c) + +// return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); + +// #undef V1 +// #undef V2 +// } + +// XML_Expat_Version XMLCALL +// XML_ExpatVersionInfo(void) { +// XML_Expat_Version version; + +// version.major = XML_MAJOR_VERSION; +// version.minor = XML_MINOR_VERSION; +// version.micro = XML_MICRO_VERSION; + +// return version; +// } + +// const XML_Feature *XMLCALL +// XML_GetFeatureList(void) { +// static const XML_Feature features[] +// = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), +// sizeof(XML_Char)}, +// {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), +// sizeof(XML_LChar)}, +// #ifdef XML_UNICODE +// {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, +// #endif +// #ifdef XML_UNICODE_WCHAR_T +// {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, +// #endif +// #ifdef XML_DTD +// {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, +// #endif +// #ifdef XML_CONTEXT_BYTES +// {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), +// XML_CONTEXT_BYTES}, +// #endif +// #ifdef XML_MIN_SIZE +// {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, +// #endif +// #ifdef XML_NS +// {XML_FEATURE_NS, XML_L("XML_NS"), 0}, +// #endif +// #ifdef XML_LARGE_SIZE +// {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, +// #endif +// #ifdef XML_ATTR_INFO +// {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, +// #endif +// {XML_FEATURE_END, NULL, 0}}; + +// return features; +// } + +// /* Initially tag->rawName always points into the parse buffer; +// for those TAG instances opened while the current parse buffer was +// processed, and not yet closed, we need to store tag->rawName in a more +// permanent location, since the parse buffer is about to be discarded. +// */ +// static XML_Bool +// storeRawNames(XML_Parser parser) { +// TAG *tag = parser->m_tagStack; +// while (tag) { +// int bufSize; +// int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); +// char *rawNameBuf = tag->buf + nameLen; +// /* Stop if already stored. Since m_tagStack is a stack, we can stop +// at the first entry that has already been copied; everything +// below it in the stack is already been accounted for in a +// previous call to this function. +// */ +// if (tag->rawName == rawNameBuf) +// break; +// /* For re-use purposes we need to ensure that the +// size of tag->buf is a multiple of sizeof(XML_Char). +// */ +// bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); +// if (bufSize > tag->bufEnd - tag->buf) { +// char *temp = (char *)REALLOC(parser, tag->buf, bufSize); +// if (temp == NULL) +// return XML_FALSE; +// /* if tag->name.str points to tag->buf (only when namespace +// processing is off) then we have to update it +// */ +// if (tag->name.str == (XML_Char *)tag->buf) +// tag->name.str = (XML_Char *)temp; +// /* if tag->name.localPart is set (when namespace processing is on) +// then update it as well, since it will always point into tag->buf +// */ +// if (tag->name.localPart) +// tag->name.localPart +// = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); +// tag->buf = temp; +// tag->bufEnd = temp + bufSize; +// rawNameBuf = temp + nameLen; +// } +// memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); +// tag->rawName = rawNameBuf; +// tag = tag->parent; +// } +// return XML_TRUE; +// } + +// static enum XML_Error PTRCALL +// contentProcessor(XML_Parser parser, const char *start, const char *end, +// const char **endPtr) { +// enum XML_Error result +// = doContent(parser, 0, parser->m_encoding, start, end, endPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer); +// if (result == XML_ERROR_NONE) { +// if (! storeRawNames(parser)) +// return XML_ERROR_NO_MEMORY; +// } +// return result; +// } + +// static enum XML_Error PTRCALL +// externalEntityInitProcessor(XML_Parser parser, const char *start, +// const char *end, const char **endPtr) { +// enum XML_Error result = initializeEncoding(parser); +// if (result != XML_ERROR_NONE) +// return result; +// parser->m_processor = externalEntityInitProcessor2; +// return externalEntityInitProcessor2(parser, start, end, endPtr); +// } + +// static enum XML_Error PTRCALL +// externalEntityInitProcessor2(XML_Parser parser, const char *start, +// const char *end, const char **endPtr) { +// const char *next = start; /* XmlContentTok doesn't always set the last arg */ +// int tok = XmlContentTok(parser->m_encoding, start, end, &next); +// switch (tok) { +// case XML_TOK_BOM: +// /* If we are at the end of the buffer, this would cause the next stage, +// i.e. externalEntityInitProcessor3, to pass control directly to +// doContent (by detecting XML_TOK_NONE) without processing any xml text +// declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. +// */ +// if (next == end && ! parser->m_parsingStatus.finalBuffer) { +// *endPtr = next; +// return XML_ERROR_NONE; +// } +// start = next; +// break; +// case XML_TOK_PARTIAL: +// if (! parser->m_parsingStatus.finalBuffer) { +// *endPtr = start; +// return XML_ERROR_NONE; +// } +// parser->m_eventPtr = start; +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// if (! parser->m_parsingStatus.finalBuffer) { +// *endPtr = start; +// return XML_ERROR_NONE; +// } +// parser->m_eventPtr = start; +// return XML_ERROR_PARTIAL_CHAR; +// } +// parser->m_processor = externalEntityInitProcessor3; +// return externalEntityInitProcessor3(parser, start, end, endPtr); +// } + +// static enum XML_Error PTRCALL +// externalEntityInitProcessor3(XML_Parser parser, const char *start, +// const char *end, const char **endPtr) { +// int tok; +// const char *next = start; /* XmlContentTok doesn't always set the last arg */ +// parser->m_eventPtr = start; +// tok = XmlContentTok(parser->m_encoding, start, end, &next); +// parser->m_eventEndPtr = next; + +// switch (tok) { +// case XML_TOK_XML_DECL: { +// enum XML_Error result; +// result = processXmlDecl(parser, 1, start, next); +// if (result != XML_ERROR_NONE) +// return result; +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// *endPtr = next; +// return XML_ERROR_NONE; +// case XML_FINISHED: +// return XML_ERROR_ABORTED; +// default: +// start = next; +// } +// } break; +// case XML_TOK_PARTIAL: +// if (! parser->m_parsingStatus.finalBuffer) { +// *endPtr = start; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// if (! parser->m_parsingStatus.finalBuffer) { +// *endPtr = start; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_PARTIAL_CHAR; +// } +// parser->m_processor = externalEntityContentProcessor; +// parser->m_tagLevel = 1; +// return externalEntityContentProcessor(parser, start, end, endPtr); +// } + +// static enum XML_Error PTRCALL +// externalEntityContentProcessor(XML_Parser parser, const char *start, +// const char *end, const char **endPtr) { +// enum XML_Error result +// = doContent(parser, 1, parser->m_encoding, start, end, endPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer); +// if (result == XML_ERROR_NONE) { +// if (! storeRawNames(parser)) +// return XML_ERROR_NO_MEMORY; +// } +// return result; +// } + +// static enum XML_Error +// doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, +// const char *s, const char *end, const char **nextPtr, +// XML_Bool haveMore) { +// /* save one level of indirection */ +// DTD *const dtd = parser->m_dtd; + +// const char **eventPP; +// const char **eventEndPP; +// if (enc == parser->m_encoding) { +// eventPP = &parser->m_eventPtr; +// eventEndPP = &parser->m_eventEndPtr; +// } else { +// eventPP = &(parser->m_openInternalEntities->internalEventPtr); +// eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); +// } +// *eventPP = s; + +// for (;;) { +// const char *next = s; /* XmlContentTok doesn't always set the last arg */ +// int tok = XmlContentTok(enc, s, end, &next); +// *eventEndPP = next; +// switch (tok) { +// case XML_TOK_TRAILING_CR: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// *eventEndPP = end; +// if (parser->m_characterDataHandler) { +// XML_Char c = 0xA; +// parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, end); +// /* We are at the end of the final buffer, should we check for +// XML_SUSPENDED, XML_FINISHED? +// */ +// if (startTagLevel == 0) +// return XML_ERROR_NO_ELEMENTS; +// if (parser->m_tagLevel != startTagLevel) +// return XML_ERROR_ASYNC_ENTITY; +// *nextPtr = end; +// return XML_ERROR_NONE; +// case XML_TOK_NONE: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// if (startTagLevel > 0) { +// if (parser->m_tagLevel != startTagLevel) +// return XML_ERROR_ASYNC_ENTITY; +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_NO_ELEMENTS; +// case XML_TOK_INVALID: +// *eventPP = next; +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_PARTIAL_CHAR; +// case XML_TOK_ENTITY_REF: { +// const XML_Char *name; +// ENTITY *entity; +// XML_Char ch = (XML_Char)XmlPredefinedEntityName( +// enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); +// if (ch) { +// if (parser->m_characterDataHandler) +// parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); +// else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// break; +// } +// name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! name) +// return XML_ERROR_NO_MEMORY; +// entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); +// poolDiscard(&dtd->pool); +// /* First, determine if a check for an existing declaration is needed; +// if yes, check that the entity exists, and that it is internal, +// otherwise call the skipped entity or default handler. +// */ +// if (! dtd->hasParamEntityRefs || dtd->standalone) { +// if (! entity) +// return XML_ERROR_UNDEFINED_ENTITY; +// else if (! entity->is_internal) +// return XML_ERROR_ENTITY_DECLARED_IN_PE; +// } else if (! entity) { +// if (parser->m_skippedEntityHandler) +// parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); +// else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// break; +// } +// if (entity->open) +// return XML_ERROR_RECURSIVE_ENTITY_REF; +// if (entity->notation) +// return XML_ERROR_BINARY_ENTITY_REF; +// if (entity->textPtr) { +// enum XML_Error result; +// if (! parser->m_defaultExpandInternalEntities) { +// if (parser->m_skippedEntityHandler) +// parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, +// 0); +// else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// break; +// } +// result = processInternalEntity(parser, entity, XML_FALSE); +// if (result != XML_ERROR_NONE) +// return result; +// } else if (parser->m_externalEntityRefHandler) { +// const XML_Char *context; +// entity->open = XML_TRUE; +// context = getContext(parser); +// entity->open = XML_FALSE; +// if (! context) +// return XML_ERROR_NO_MEMORY; +// if (! parser->m_externalEntityRefHandler( +// parser->m_externalEntityRefHandlerArg, context, entity->base, +// entity->systemId, entity->publicId)) +// return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +// poolDiscard(&parser->m_tempPool); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// break; +// } +// case XML_TOK_START_TAG_NO_ATTS: +// /* fall through */ +// case XML_TOK_START_TAG_WITH_ATTS: { +// TAG *tag; +// enum XML_Error result; +// XML_Char *toPtr; +// if (parser->m_freeTagList) { +// tag = parser->m_freeTagList; +// parser->m_freeTagList = parser->m_freeTagList->parent; +// } else { +// tag = (TAG *)MALLOC(parser, sizeof(TAG)); +// if (! tag) +// return XML_ERROR_NO_MEMORY; +// tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); +// if (! tag->buf) { +// FREE(parser, tag); +// return XML_ERROR_NO_MEMORY; +// } +// tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; +// } +// tag->bindings = NULL; +// tag->parent = parser->m_tagStack; +// parser->m_tagStack = tag; +// tag->name.localPart = NULL; +// tag->name.prefix = NULL; +// tag->rawName = s + enc->minBytesPerChar; +// tag->rawNameLength = XmlNameLength(enc, tag->rawName); +// ++parser->m_tagLevel; +// { +// const char *rawNameEnd = tag->rawName + tag->rawNameLength; +// const char *fromPtr = tag->rawName; +// toPtr = (XML_Char *)tag->buf; +// for (;;) { +// int bufSize; +// int convLen; +// const enum XML_Convert_Result convert_res +// = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, +// (ICHAR *)tag->bufEnd - 1); +// convLen = (int)(toPtr - (XML_Char *)tag->buf); +// if ((fromPtr >= rawNameEnd) +// || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { +// tag->name.strLen = convLen; +// break; +// } +// bufSize = (int)(tag->bufEnd - tag->buf) << 1; +// { +// char *temp = (char *)REALLOC(parser, tag->buf, bufSize); +// if (temp == NULL) +// return XML_ERROR_NO_MEMORY; +// tag->buf = temp; +// tag->bufEnd = temp + bufSize; +// toPtr = (XML_Char *)temp + convLen; +// } +// } +// } +// tag->name.str = (XML_Char *)tag->buf; +// *toPtr = XML_T('\0'); +// result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); +// if (result) +// return result; +// if (parser->m_startElementHandler) +// parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, +// (const XML_Char **)parser->m_atts); +// else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// poolClear(&parser->m_tempPool); +// break; +// } +// case XML_TOK_EMPTY_ELEMENT_NO_ATTS: +// /* fall through */ +// case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { +// const char *rawName = s + enc->minBytesPerChar; +// enum XML_Error result; +// BINDING *bindings = NULL; +// XML_Bool noElmHandlers = XML_TRUE; +// TAG_NAME name; +// name.str = poolStoreString(&parser->m_tempPool, enc, rawName, +// rawName + XmlNameLength(enc, rawName)); +// if (! name.str) +// return XML_ERROR_NO_MEMORY; +// poolFinish(&parser->m_tempPool); +// result = storeAtts(parser, enc, s, &name, &bindings); +// if (result != XML_ERROR_NONE) { +// freeBindings(parser, bindings); +// return result; +// } +// poolFinish(&parser->m_tempPool); +// if (parser->m_startElementHandler) { +// parser->m_startElementHandler(parser->m_handlerArg, name.str, +// (const XML_Char **)parser->m_atts); +// noElmHandlers = XML_FALSE; +// } +// if (parser->m_endElementHandler) { +// if (parser->m_startElementHandler) +// *eventPP = *eventEndPP; +// parser->m_endElementHandler(parser->m_handlerArg, name.str); +// noElmHandlers = XML_FALSE; +// } +// if (noElmHandlers && parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// poolClear(&parser->m_tempPool); +// freeBindings(parser, bindings); +// } +// if ((parser->m_tagLevel == 0) +// && (parser->m_parsingStatus.parsing != XML_FINISHED)) { +// if (parser->m_parsingStatus.parsing == XML_SUSPENDED) +// parser->m_processor = epilogProcessor; +// else +// return epilogProcessor(parser, next, end, nextPtr); +// } +// break; +// case XML_TOK_END_TAG: +// if (parser->m_tagLevel == startTagLevel) +// return XML_ERROR_ASYNC_ENTITY; +// else { +// int len; +// const char *rawName; +// TAG *tag = parser->m_tagStack; +// parser->m_tagStack = tag->parent; +// tag->parent = parser->m_freeTagList; +// parser->m_freeTagList = tag; +// rawName = s + enc->minBytesPerChar * 2; +// len = XmlNameLength(enc, rawName); +// if (len != tag->rawNameLength +// || memcmp(tag->rawName, rawName, len) != 0) { +// *eventPP = rawName; +// return XML_ERROR_TAG_MISMATCH; +// } +// --parser->m_tagLevel; +// if (parser->m_endElementHandler) { +// const XML_Char *localPart; +// const XML_Char *prefix; +// XML_Char *uri; +// localPart = tag->name.localPart; +// if (parser->m_ns && localPart) { +// /* localPart and prefix may have been overwritten in +// tag->name.str, since this points to the binding->uri +// buffer which gets re-used; so we have to add them again +// */ +// uri = (XML_Char *)tag->name.str + tag->name.uriLen; +// /* don't need to check for space - already done in storeAtts() */ +// while (*localPart) +// *uri++ = *localPart++; +// prefix = (XML_Char *)tag->name.prefix; +// if (parser->m_ns_triplets && prefix) { +// *uri++ = parser->m_namespaceSeparator; +// while (*prefix) +// *uri++ = *prefix++; +// } +// *uri = XML_T('\0'); +// } +// parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// while (tag->bindings) { +// BINDING *b = tag->bindings; +// if (parser->m_endNamespaceDeclHandler) +// parser->m_endNamespaceDeclHandler(parser->m_handlerArg, +// b->prefix->name); +// tag->bindings = tag->bindings->nextTagBinding; +// b->nextTagBinding = parser->m_freeBindingList; +// parser->m_freeBindingList = b; +// b->prefix->binding = b->prevPrefixBinding; +// } +// if ((parser->m_tagLevel == 0) +// && (parser->m_parsingStatus.parsing != XML_FINISHED)) { +// if (parser->m_parsingStatus.parsing == XML_SUSPENDED) +// parser->m_processor = epilogProcessor; +// else +// return epilogProcessor(parser, next, end, nextPtr); +// } +// } +// break; +// case XML_TOK_CHAR_REF: { +// int n = XmlCharRefNumber(enc, s); +// if (n < 0) +// return XML_ERROR_BAD_CHAR_REF; +// if (parser->m_characterDataHandler) { +// XML_Char buf[XML_ENCODE_MAX]; +// parser->m_characterDataHandler(parser->m_handlerArg, buf, +// XmlEncode(n, (ICHAR *)buf)); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// } break; +// case XML_TOK_XML_DECL: +// return XML_ERROR_MISPLACED_XML_PI; +// case XML_TOK_DATA_NEWLINE: +// if (parser->m_characterDataHandler) { +// XML_Char c = 0xA; +// parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// break; +// case XML_TOK_CDATA_SECT_OPEN: { +// enum XML_Error result; +// if (parser->m_startCdataSectionHandler) +// parser->m_startCdataSectionHandler(parser->m_handlerArg); +// /* BEGIN disabled code */ +// /* Suppose you doing a transformation on a document that involves +// changing only the character data. You set up a defaultHandler +// and a characterDataHandler. The defaultHandler simply copies +// characters through. The characterDataHandler does the +// transformation and writes the characters out escaping them as +// necessary. This case will fail to work if we leave out the +// following two lines (because & and < inside CDATA sections will +// be incorrectly escaped). + +// However, now we have a start/endCdataSectionHandler, so it seems +// easier to let the user deal with this. +// */ +// else if (0 && parser->m_characterDataHandler) +// parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, +// 0); +// /* END disabled code */ +// else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); +// if (result != XML_ERROR_NONE) +// return result; +// else if (! next) { +// parser->m_processor = cdataSectionProcessor; +// return result; +// } +// } break; +// case XML_TOK_TRAILING_RSQB: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// if (parser->m_characterDataHandler) { +// if (MUST_CONVERT(enc, s)) { +// ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; +// XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); +// parser->m_characterDataHandler( +// parser->m_handlerArg, parser->m_dataBuf, +// (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); +// } else +// parser->m_characterDataHandler( +// parser->m_handlerArg, (XML_Char *)s, +// (int)((XML_Char *)end - (XML_Char *)s)); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, end); +// /* We are at the end of the final buffer, should we check for +// XML_SUSPENDED, XML_FINISHED? +// */ +// if (startTagLevel == 0) { +// *eventPP = end; +// return XML_ERROR_NO_ELEMENTS; +// } +// if (parser->m_tagLevel != startTagLevel) { +// *eventPP = end; +// return XML_ERROR_ASYNC_ENTITY; +// } +// *nextPtr = end; +// return XML_ERROR_NONE; +// case XML_TOK_DATA_CHARS: { +// XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; +// if (charDataHandler) { +// if (MUST_CONVERT(enc, s)) { +// for (;;) { +// ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; +// const enum XML_Convert_Result convert_res = XmlConvert( +// enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); +// *eventEndPP = s; +// charDataHandler(parser->m_handlerArg, parser->m_dataBuf, +// (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); +// if ((convert_res == XML_CONVERT_COMPLETED) +// || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) +// break; +// *eventPP = s; +// } +// } else +// charDataHandler(parser->m_handlerArg, (XML_Char *)s, +// (int)((XML_Char *)next - (XML_Char *)s)); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// } break; +// case XML_TOK_PI: +// if (! reportProcessingInstruction(parser, enc, s, next)) +// return XML_ERROR_NO_MEMORY; +// break; +// case XML_TOK_COMMENT: +// if (! reportComment(parser, enc, s, next)) +// return XML_ERROR_NO_MEMORY; +// break; +// default: +// /* All of the tokens produced by XmlContentTok() have their own +// * explicit cases, so this default is not strictly necessary. +// * However it is a useful safety net, so we retain the code and +// * simply exclude it from the coverage tests. +// * +// * LCOV_EXCL_START +// */ +// if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// break; +// /* LCOV_EXCL_STOP */ +// } +// *eventPP = s = next; +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// *nextPtr = next; +// return XML_ERROR_NONE; +// case XML_FINISHED: +// return XML_ERROR_ABORTED; +// default:; +// } +// } +// /* not reached */ +// } + +// /* This function does not call free() on the allocated memory, merely +// * moving it to the parser's m_freeBindingList where it can be freed or +// * reused as appropriate. +// */ +// static void +// freeBindings(XML_Parser parser, BINDING *bindings) { +// while (bindings) { +// BINDING *b = bindings; + +// /* m_startNamespaceDeclHandler will have been called for this +// * binding in addBindings(), so call the end handler now. +// */ +// if (parser->m_endNamespaceDeclHandler) +// parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); + +// bindings = bindings->nextTagBinding; +// b->nextTagBinding = parser->m_freeBindingList; +// parser->m_freeBindingList = b; +// b->prefix->binding = b->prevPrefixBinding; +// } +// } + +// /* Precondition: all arguments must be non-NULL; +// Purpose: +// - normalize attributes +// - check attributes for well-formedness +// - generate namespace aware attribute names (URI, prefix) +// - build list of attributes for startElementHandler +// - default attributes +// - process namespace declarations (check and report them) +// - generate namespace aware element name (URI, prefix) +// */ +// static enum XML_Error +// storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, +// TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// ELEMENT_TYPE *elementType; +// int nDefaultAtts; +// const XML_Char **appAtts; /* the attribute list for the application */ +// int attIndex = 0; +// int prefixLen; +// int i; +// int n; +// XML_Char *uri; +// int nPrefixes = 0; +// BINDING *binding; +// const XML_Char *localPart; + +// /* lookup the element type name */ +// elementType +// = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0); +// if (! elementType) { +// const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); +// if (! name) +// return XML_ERROR_NO_MEMORY; +// elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, +// sizeof(ELEMENT_TYPE)); +// if (! elementType) +// return XML_ERROR_NO_MEMORY; +// if (parser->m_ns && ! setElementTypePrefix(parser, elementType)) +// return XML_ERROR_NO_MEMORY; +// } +// nDefaultAtts = elementType->nDefaultAtts; + +// /* get the attributes from the tokenizer */ +// n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); +// if (n + nDefaultAtts > parser->m_attsSize) { +// int oldAttsSize = parser->m_attsSize; +// ATTRIBUTE *temp; +// #ifdef XML_ATTR_INFO +// XML_AttrInfo *temp2; +// #endif +// parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; +// temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, +// parser->m_attsSize * sizeof(ATTRIBUTE)); +// if (temp == NULL) { +// parser->m_attsSize = oldAttsSize; +// return XML_ERROR_NO_MEMORY; +// } +// parser->m_atts = temp; +// #ifdef XML_ATTR_INFO +// temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, +// parser->m_attsSize * sizeof(XML_AttrInfo)); +// if (temp2 == NULL) { +// parser->m_attsSize = oldAttsSize; +// return XML_ERROR_NO_MEMORY; +// } +// parser->m_attInfo = temp2; +// #endif +// if (n > oldAttsSize) +// XmlGetAttributes(enc, attStr, n, parser->m_atts); +// } + +// appAtts = (const XML_Char **)parser->m_atts; +// for (i = 0; i < n; i++) { +// ATTRIBUTE *currAtt = &parser->m_atts[i]; +// #ifdef XML_ATTR_INFO +// XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; +// #endif +// /* add the name and value to the attribute list */ +// ATTRIBUTE_ID *attId +// = getAttributeId(parser, enc, currAtt->name, +// currAtt->name + XmlNameLength(enc, currAtt->name)); +// if (! attId) +// return XML_ERROR_NO_MEMORY; +// #ifdef XML_ATTR_INFO +// currAttInfo->nameStart +// = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); +// currAttInfo->nameEnd +// = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); +// currAttInfo->valueStart = parser->m_parseEndByteIndex +// - (parser->m_parseEndPtr - currAtt->valuePtr); +// currAttInfo->valueEnd = parser->m_parseEndByteIndex +// - (parser->m_parseEndPtr - currAtt->valueEnd); +// #endif +// /* Detect duplicate attributes by their QNames. This does not work when +// namespace processing is turned on and different prefixes for the same +// namespace are used. For this case we have a check further down. +// */ +// if ((attId->name)[-1]) { +// if (enc == parser->m_encoding) +// parser->m_eventPtr = parser->m_atts[i].name; +// return XML_ERROR_DUPLICATE_ATTRIBUTE; +// } +// (attId->name)[-1] = 1; +// appAtts[attIndex++] = attId->name; +// if (! parser->m_atts[i].normalized) { +// enum XML_Error result; +// XML_Bool isCdata = XML_TRUE; + +// /* figure out whether declared as other than CDATA */ +// if (attId->maybeTokenized) { +// int j; +// for (j = 0; j < nDefaultAtts; j++) { +// if (attId == elementType->defaultAtts[j].id) { +// isCdata = elementType->defaultAtts[j].isCdata; +// break; +// } +// } +// } + +// /* normalize the attribute value */ +// result = storeAttributeValue( +// parser, enc, isCdata, parser->m_atts[i].valuePtr, +// parser->m_atts[i].valueEnd, &parser->m_tempPool); +// if (result) +// return result; +// appAtts[attIndex] = poolStart(&parser->m_tempPool); +// poolFinish(&parser->m_tempPool); +// } else { +// /* the value did not need normalizing */ +// appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, +// parser->m_atts[i].valuePtr, +// parser->m_atts[i].valueEnd); +// if (appAtts[attIndex] == 0) +// return XML_ERROR_NO_MEMORY; +// poolFinish(&parser->m_tempPool); +// } +// /* handle prefixed attribute names */ +// if (attId->prefix) { +// if (attId->xmlns) { +// /* deal with namespace declarations here */ +// enum XML_Error result = addBinding(parser, attId->prefix, attId, +// appAtts[attIndex], bindingsPtr); +// if (result) +// return result; +// --attIndex; +// } else { +// /* deal with other prefixed names later */ +// attIndex++; +// nPrefixes++; +// (attId->name)[-1] = 2; +// } +// } else +// attIndex++; +// } + +// /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ +// parser->m_nSpecifiedAtts = attIndex; +// if (elementType->idAtt && (elementType->idAtt->name)[-1]) { +// for (i = 0; i < attIndex; i += 2) +// if (appAtts[i] == elementType->idAtt->name) { +// parser->m_idAttIndex = i; +// break; +// } +// } else +// parser->m_idAttIndex = -1; + +// /* do attribute defaulting */ +// for (i = 0; i < nDefaultAtts; i++) { +// const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; +// if (! (da->id->name)[-1] && da->value) { +// if (da->id->prefix) { +// if (da->id->xmlns) { +// enum XML_Error result = addBinding(parser, da->id->prefix, da->id, +// da->value, bindingsPtr); +// if (result) +// return result; +// } else { +// (da->id->name)[-1] = 2; +// nPrefixes++; +// appAtts[attIndex++] = da->id->name; +// appAtts[attIndex++] = da->value; +// } +// } else { +// (da->id->name)[-1] = 1; +// appAtts[attIndex++] = da->id->name; +// appAtts[attIndex++] = da->value; +// } +// } +// } +// appAtts[attIndex] = 0; + +// /* expand prefixed attribute names, check for duplicates, +// and clear flags that say whether attributes were specified */ +// i = 0; +// if (nPrefixes) { +// int j; /* hash table index */ +// unsigned long version = parser->m_nsAttsVersion; +// int nsAttsSize = (int)1 << parser->m_nsAttsPower; +// unsigned char oldNsAttsPower = parser->m_nsAttsPower; +// /* size of hash table must be at least 2 * (# of prefixed attributes) */ +// if ((nPrefixes << 1) +// >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ +// NS_ATT *temp; +// /* hash table size must also be a power of 2 and >= 8 */ +// while (nPrefixes >> parser->m_nsAttsPower++) +// ; +// if (parser->m_nsAttsPower < 3) +// parser->m_nsAttsPower = 3; +// nsAttsSize = (int)1 << parser->m_nsAttsPower; +// temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, +// nsAttsSize * sizeof(NS_ATT)); +// if (! temp) { +// /* Restore actual size of memory in m_nsAtts */ +// parser->m_nsAttsPower = oldNsAttsPower; +// return XML_ERROR_NO_MEMORY; +// } +// parser->m_nsAtts = temp; +// version = 0; /* force re-initialization of m_nsAtts hash table */ +// } +// /* using a version flag saves us from initializing m_nsAtts every time */ +// if (! version) { /* initialize version flags when version wraps around */ +// version = INIT_ATTS_VERSION; +// for (j = nsAttsSize; j != 0;) +// parser->m_nsAtts[--j].version = version; +// } +// parser->m_nsAttsVersion = --version; + +// /* expand prefixed names and check for duplicates */ +// for (; i < attIndex; i += 2) { +// const XML_Char *s = appAtts[i]; +// if (s[-1] == 2) { /* prefixed */ +// ATTRIBUTE_ID *id; +// const BINDING *b; +// unsigned long uriHash; +// struct siphash sip_state; +// struct sipkey sip_key; + +// copy_salt_to_sipkey(parser, &sip_key); +// sip24_init(&sip_state, &sip_key); + +// ((XML_Char *)s)[-1] = 0; /* clear flag */ +// id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); +// if (! id || ! id->prefix) { +// /* This code is walking through the appAtts array, dealing +// * with (in this case) a prefixed attribute name. To be in +// * the array, the attribute must have already been bound, so +// * has to have passed through the hash table lookup once +// * already. That implies that an entry for it already +// * exists, so the lookup above will return a pointer to +// * already allocated memory. There is no opportunaity for +// * the allocator to fail, so the condition above cannot be +// * fulfilled. +// * +// * Since it is difficult to be certain that the above +// * analysis is complete, we retain the test and merely +// * remove the code from coverage tests. +// */ +// return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ +// } +// b = id->prefix->binding; +// if (! b) +// return XML_ERROR_UNBOUND_PREFIX; + +// for (j = 0; j < b->uriLen; j++) { +// const XML_Char c = b->uri[j]; +// if (! poolAppendChar(&parser->m_tempPool, c)) +// return XML_ERROR_NO_MEMORY; +// } + +// sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); + +// while (*s++ != XML_T(ASCII_COLON)) +// ; + +// sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); + +// do { /* copies null terminator */ +// if (! poolAppendChar(&parser->m_tempPool, *s)) +// return XML_ERROR_NO_MEMORY; +// } while (*s++); + +// uriHash = (unsigned long)sip24_final(&sip_state); + +// { /* Check hash table for duplicate of expanded name (uriName). +// Derived from code in lookup(parser, HASH_TABLE *table, ...). +// */ +// unsigned char step = 0; +// unsigned long mask = nsAttsSize - 1; +// j = uriHash & mask; /* index into hash table */ +// while (parser->m_nsAtts[j].version == version) { +// /* for speed we compare stored hash values first */ +// if (uriHash == parser->m_nsAtts[j].hash) { +// const XML_Char *s1 = poolStart(&parser->m_tempPool); +// const XML_Char *s2 = parser->m_nsAtts[j].uriName; +// /* s1 is null terminated, but not s2 */ +// for (; *s1 == *s2 && *s1 != 0; s1++, s2++) +// ; +// if (*s1 == 0) +// return XML_ERROR_DUPLICATE_ATTRIBUTE; +// } +// if (! step) +// step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); +// j < step ? (j += nsAttsSize - step) : (j -= step); +// } +// } + +// if (parser->m_ns_triplets) { /* append namespace separator and prefix */ +// parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; +// s = b->prefix->name; +// do { +// if (! poolAppendChar(&parser->m_tempPool, *s)) +// return XML_ERROR_NO_MEMORY; +// } while (*s++); +// } + +// /* store expanded name in attribute list */ +// s = poolStart(&parser->m_tempPool); +// poolFinish(&parser->m_tempPool); +// appAtts[i] = s; + +// /* fill empty slot with new version, uriName and hash value */ +// parser->m_nsAtts[j].version = version; +// parser->m_nsAtts[j].hash = uriHash; +// parser->m_nsAtts[j].uriName = s; + +// if (! --nPrefixes) { +// i += 2; +// break; +// } +// } else /* not prefixed */ +// ((XML_Char *)s)[-1] = 0; /* clear flag */ +// } +// } +// /* clear flags for the remaining attributes */ +// for (; i < attIndex; i += 2) +// ((XML_Char *)(appAtts[i]))[-1] = 0; +// for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) +// binding->attId->name[-1] = 0; + +// if (! parser->m_ns) +// return XML_ERROR_NONE; + +// /* expand the element type name */ +// if (elementType->prefix) { +// binding = elementType->prefix->binding; +// if (! binding) +// return XML_ERROR_UNBOUND_PREFIX; +// localPart = tagNamePtr->str; +// while (*localPart++ != XML_T(ASCII_COLON)) +// ; +// } else if (dtd->defaultPrefix.binding) { +// binding = dtd->defaultPrefix.binding; +// localPart = tagNamePtr->str; +// } else +// return XML_ERROR_NONE; +// prefixLen = 0; +// if (parser->m_ns_triplets && binding->prefix->name) { +// for (; binding->prefix->name[prefixLen++];) +// ; /* prefixLen includes null terminator */ +// } +// tagNamePtr->localPart = localPart; +// tagNamePtr->uriLen = binding->uriLen; +// tagNamePtr->prefix = binding->prefix->name; +// tagNamePtr->prefixLen = prefixLen; +// for (i = 0; localPart[i++];) +// ; /* i includes null terminator */ +// n = i + binding->uriLen + prefixLen; +// if (n > binding->uriAlloc) { +// TAG *p; +// uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); +// if (! uri) +// return XML_ERROR_NO_MEMORY; +// binding->uriAlloc = n + EXPAND_SPARE; +// memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); +// for (p = parser->m_tagStack; p; p = p->parent) +// if (p->name.str == binding->uri) +// p->name.str = uri; +// FREE(parser, binding->uri); +// binding->uri = uri; +// } +// /* if m_namespaceSeparator != '\0' then uri includes it already */ +// uri = binding->uri + binding->uriLen; +// memcpy(uri, localPart, i * sizeof(XML_Char)); +// /* we always have a namespace separator between localPart and prefix */ +// if (prefixLen) { +// uri += i - 1; +// *uri = parser->m_namespaceSeparator; /* replace null terminator */ +// memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); +// } +// tagNamePtr->str = binding->uri; +// return XML_ERROR_NONE; +// } + +// /* addBinding() overwrites the value of prefix->binding without checking. +// Therefore one must keep track of the old value outside of addBinding(). +// */ +// static enum XML_Error +// addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, +// const XML_Char *uri, BINDING **bindingsPtr) { +// static const XML_Char xmlNamespace[] +// = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, +// ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, +// ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, +// ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, +// ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, +// ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, +// ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, +// ASCII_e, '\0'}; +// static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; +// static const XML_Char xmlnsNamespace[] +// = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, +// ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, +// ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, +// ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x, +// ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'}; +// static const int xmlnsLen +// = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1; + +// XML_Bool mustBeXML = XML_FALSE; +// XML_Bool isXML = XML_TRUE; +// XML_Bool isXMLNS = XML_TRUE; + +// BINDING *b; +// int len; + +// /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ +// if (*uri == XML_T('\0') && prefix->name) +// return XML_ERROR_UNDECLARING_PREFIX; + +// if (prefix->name && prefix->name[0] == XML_T(ASCII_x) +// && prefix->name[1] == XML_T(ASCII_m) +// && prefix->name[2] == XML_T(ASCII_l)) { +// /* Not allowed to bind xmlns */ +// if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) +// && prefix->name[5] == XML_T('\0')) +// return XML_ERROR_RESERVED_PREFIX_XMLNS; + +// if (prefix->name[3] == XML_T('\0')) +// mustBeXML = XML_TRUE; +// } + +// for (len = 0; uri[len]; len++) { +// if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) +// isXML = XML_FALSE; + +// if (! mustBeXML && isXMLNS +// && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) +// isXMLNS = XML_FALSE; +// } +// isXML = isXML && len == xmlLen; +// isXMLNS = isXMLNS && len == xmlnsLen; + +// if (mustBeXML != isXML) +// return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML +// : XML_ERROR_RESERVED_NAMESPACE_URI; + +// if (isXMLNS) +// return XML_ERROR_RESERVED_NAMESPACE_URI; + +// if (parser->m_namespaceSeparator) +// len++; +// if (parser->m_freeBindingList) { +// b = parser->m_freeBindingList; +// if (len > b->uriAlloc) { +// XML_Char *temp = (XML_Char *)REALLOC( +// parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); +// if (temp == NULL) +// return XML_ERROR_NO_MEMORY; +// b->uri = temp; +// b->uriAlloc = len + EXPAND_SPARE; +// } +// parser->m_freeBindingList = b->nextTagBinding; +// } else { +// b = (BINDING *)MALLOC(parser, sizeof(BINDING)); +// if (! b) +// return XML_ERROR_NO_MEMORY; +// b->uri +// = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); +// if (! b->uri) { +// FREE(parser, b); +// return XML_ERROR_NO_MEMORY; +// } +// b->uriAlloc = len + EXPAND_SPARE; +// } +// b->uriLen = len; +// memcpy(b->uri, uri, len * sizeof(XML_Char)); +// if (parser->m_namespaceSeparator) +// b->uri[len - 1] = parser->m_namespaceSeparator; +// b->prefix = prefix; +// b->attId = attId; +// b->prevPrefixBinding = prefix->binding; +// /* NULL binding when default namespace undeclared */ +// if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) +// prefix->binding = NULL; +// else +// prefix->binding = b; +// b->nextTagBinding = *bindingsPtr; +// *bindingsPtr = b; +// /* if attId == NULL then we are not starting a namespace scope */ +// if (attId && parser->m_startNamespaceDeclHandler) +// parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, +// prefix->binding ? uri : 0); +// return XML_ERROR_NONE; +// } + +// /* The idea here is to avoid using stack for each CDATA section when +// the whole file is parsed with one call. +// */ +// static enum XML_Error PTRCALL +// cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, +// const char **endPtr) { +// enum XML_Error result +// = doCdataSection(parser, parser->m_encoding, &start, end, endPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer); +// if (result != XML_ERROR_NONE) +// return result; +// if (start) { +// if (parser->m_parentParser) { /* we are parsing an external entity */ +// parser->m_processor = externalEntityContentProcessor; +// return externalEntityContentProcessor(parser, start, end, endPtr); +// } else { +// parser->m_processor = contentProcessor; +// return contentProcessor(parser, start, end, endPtr); +// } +// } +// return result; +// } + +// /* startPtr gets set to non-null if the section is closed, and to null if +// the section is not yet closed. +// */ +// static enum XML_Error +// doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, +// const char *end, const char **nextPtr, XML_Bool haveMore) { +// const char *s = *startPtr; +// const char **eventPP; +// const char **eventEndPP; +// if (enc == parser->m_encoding) { +// eventPP = &parser->m_eventPtr; +// *eventPP = s; +// eventEndPP = &parser->m_eventEndPtr; +// } else { +// eventPP = &(parser->m_openInternalEntities->internalEventPtr); +// eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); +// } +// *eventPP = s; +// *startPtr = NULL; + +// for (;;) { +// const char *next; +// int tok = XmlCdataSectionTok(enc, s, end, &next); +// *eventEndPP = next; +// switch (tok) { +// case XML_TOK_CDATA_SECT_CLOSE: +// if (parser->m_endCdataSectionHandler) +// parser->m_endCdataSectionHandler(parser->m_handlerArg); +// /* BEGIN disabled code */ +// /* see comment under XML_TOK_CDATA_SECT_OPEN */ +// else if (0 && parser->m_characterDataHandler) +// parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, +// 0); +// /* END disabled code */ +// else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// *startPtr = next; +// *nextPtr = next; +// if (parser->m_parsingStatus.parsing == XML_FINISHED) +// return XML_ERROR_ABORTED; +// else +// return XML_ERROR_NONE; +// case XML_TOK_DATA_NEWLINE: +// if (parser->m_characterDataHandler) { +// XML_Char c = 0xA; +// parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// break; +// case XML_TOK_DATA_CHARS: { +// XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; +// if (charDataHandler) { +// if (MUST_CONVERT(enc, s)) { +// for (;;) { +// ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; +// const enum XML_Convert_Result convert_res = XmlConvert( +// enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); +// *eventEndPP = next; +// charDataHandler(parser->m_handlerArg, parser->m_dataBuf, +// (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); +// if ((convert_res == XML_CONVERT_COMPLETED) +// || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) +// break; +// *eventPP = s; +// } +// } else +// charDataHandler(parser->m_handlerArg, (XML_Char *)s, +// (int)((XML_Char *)next - (XML_Char *)s)); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// } break; +// case XML_TOK_INVALID: +// *eventPP = next; +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_PARTIAL_CHAR; +// case XML_TOK_PARTIAL: +// case XML_TOK_NONE: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_UNCLOSED_CDATA_SECTION; +// default: +// /* Every token returned by XmlCdataSectionTok() has its own +// * explicit case, so this default case will never be executed. +// * We retain it as a safety net and exclude it from the coverage +// * statistics. +// * +// * LCOV_EXCL_START +// */ +// *eventPP = next; +// return XML_ERROR_UNEXPECTED_STATE; +// /* LCOV_EXCL_STOP */ +// } + +// *eventPP = s = next; +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// *nextPtr = next; +// return XML_ERROR_NONE; +// case XML_FINISHED: +// return XML_ERROR_ABORTED; +// default:; +// } +// } +// /* not reached */ +// } + +// #ifdef XML_DTD + +// /* The idea here is to avoid using stack for each IGNORE section when +// the whole file is parsed with one call. +// */ +// static enum XML_Error PTRCALL +// ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end, +// const char **endPtr) { +// enum XML_Error result +// = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer); +// if (result != XML_ERROR_NONE) +// return result; +// if (start) { +// parser->m_processor = prologProcessor; +// return prologProcessor(parser, start, end, endPtr); +// } +// return result; +// } + +// /* startPtr gets set to non-null is the section is closed, and to null +// if the section is not yet closed. +// */ +// static enum XML_Error +// doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, +// const char *end, const char **nextPtr, XML_Bool haveMore) { +// const char *next; +// int tok; +// const char *s = *startPtr; +// const char **eventPP; +// const char **eventEndPP; +// if (enc == parser->m_encoding) { +// eventPP = &parser->m_eventPtr; +// *eventPP = s; +// eventEndPP = &parser->m_eventEndPtr; +// } else { +// /* It's not entirely clear, but it seems the following two lines +// * of code cannot be executed. The only occasions on which 'enc' +// * is not 'encoding' are when this function is called +// * from the internal entity processing, and IGNORE sections are an +// * error in internal entities. +// * +// * Since it really isn't clear that this is true, we keep the code +// * and just remove it from our coverage tests. +// * +// * LCOV_EXCL_START +// */ +// eventPP = &(parser->m_openInternalEntities->internalEventPtr); +// eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); +// /* LCOV_EXCL_STOP */ +// } +// *eventPP = s; +// *startPtr = NULL; +// tok = XmlIgnoreSectionTok(enc, s, end, &next); +// *eventEndPP = next; +// switch (tok) { +// case XML_TOK_IGNORE_SECT: +// if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// *startPtr = next; +// *nextPtr = next; +// if (parser->m_parsingStatus.parsing == XML_FINISHED) +// return XML_ERROR_ABORTED; +// else +// return XML_ERROR_NONE; +// case XML_TOK_INVALID: +// *eventPP = next; +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_PARTIAL_CHAR; +// case XML_TOK_PARTIAL: +// case XML_TOK_NONE: +// if (haveMore) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ +// default: +// /* All of the tokens that XmlIgnoreSectionTok() returns have +// * explicit cases to handle them, so this default case is never +// * executed. We keep it as a safety net anyway, and remove it +// * from our test coverage statistics. +// * +// * LCOV_EXCL_START +// */ +// *eventPP = next; +// return XML_ERROR_UNEXPECTED_STATE; +// /* LCOV_EXCL_STOP */ +// } +// /* not reached */ +// } + +// #endif /* XML_DTD */ + +// static enum XML_Error +// initializeEncoding(XML_Parser parser) { +// const char *s; +// #ifdef XML_UNICODE +// char encodingBuf[128]; +// /* See comments abount `protoclEncodingName` in parserInit() */ +// if (! parser->m_protocolEncodingName) +// s = NULL; +// else { +// int i; +// for (i = 0; parser->m_protocolEncodingName[i]; i++) { +// if (i == sizeof(encodingBuf) - 1 +// || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { +// encodingBuf[0] = '\0'; +// break; +// } +// encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; +// } +// encodingBuf[i] = '\0'; +// s = encodingBuf; +// } +// #else +// s = parser->m_protocolEncodingName; +// #endif +// if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)( +// &parser->m_initEncoding, &parser->m_encoding, s)) +// return XML_ERROR_NONE; +// return handleUnknownEncoding(parser, parser->m_protocolEncodingName); +// } + +// static enum XML_Error +// processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, +// const char *next) { +// const char *encodingName = NULL; +// const XML_Char *storedEncName = NULL; +// const ENCODING *newEncoding = NULL; +// const char *version = NULL; +// const char *versionend; +// const XML_Char *storedversion = NULL; +// int standalone = -1; +// if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( +// isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, +// &version, &versionend, &encodingName, &newEncoding, &standalone)) { +// if (isGeneralTextEntity) +// return XML_ERROR_TEXT_DECL; +// else +// return XML_ERROR_XML_DECL; +// } +// if (! isGeneralTextEntity && standalone == 1) { +// parser->m_dtd->standalone = XML_TRUE; +// #ifdef XML_DTD +// if (parser->m_paramEntityParsing +// == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) +// parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +// #endif /* XML_DTD */ +// } +// if (parser->m_xmlDeclHandler) { +// if (encodingName != NULL) { +// storedEncName = poolStoreString( +// &parser->m_temp2Pool, parser->m_encoding, encodingName, +// encodingName + XmlNameLength(parser->m_encoding, encodingName)); +// if (! storedEncName) +// return XML_ERROR_NO_MEMORY; +// poolFinish(&parser->m_temp2Pool); +// } +// if (version) { +// storedversion +// = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version, +// versionend - parser->m_encoding->minBytesPerChar); +// if (! storedversion) +// return XML_ERROR_NO_MEMORY; +// } +// parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, +// standalone); +// } else if (parser->m_defaultHandler) +// reportDefault(parser, parser->m_encoding, s, next); +// if (parser->m_protocolEncodingName == NULL) { +// if (newEncoding) { +// /* Check that the specified encoding does not conflict with what +// * the parser has already deduced. Do we have the same number +// * of bytes in the smallest representation of a character? If +// * this is UTF-16, is it the same endianness? +// */ +// if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar +// || (newEncoding->minBytesPerChar == 2 +// && newEncoding != parser->m_encoding)) { +// parser->m_eventPtr = encodingName; +// return XML_ERROR_INCORRECT_ENCODING; +// } +// parser->m_encoding = newEncoding; +// } else if (encodingName) { +// enum XML_Error result; +// if (! storedEncName) { +// storedEncName = poolStoreString( +// &parser->m_temp2Pool, parser->m_encoding, encodingName, +// encodingName + XmlNameLength(parser->m_encoding, encodingName)); +// if (! storedEncName) +// return XML_ERROR_NO_MEMORY; +// } +// result = handleUnknownEncoding(parser, storedEncName); +// poolClear(&parser->m_temp2Pool); +// if (result == XML_ERROR_UNKNOWN_ENCODING) +// parser->m_eventPtr = encodingName; +// return result; +// } +// } + +// if (storedEncName || storedversion) +// poolClear(&parser->m_temp2Pool); + +// return XML_ERROR_NONE; +// } + +// static enum XML_Error +// handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { +// if (parser->m_unknownEncodingHandler) { +// XML_Encoding info; +// int i; +// for (i = 0; i < 256; i++) +// info.map[i] = -1; +// info.convert = NULL; +// info.data = NULL; +// info.release = NULL; +// if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, +// encodingName, &info)) { +// ENCODING *enc; +// parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); +// if (! parser->m_unknownEncodingMem) { +// if (info.release) +// info.release(info.data); +// return XML_ERROR_NO_MEMORY; +// } +// enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)( +// parser->m_unknownEncodingMem, info.map, info.convert, info.data); +// if (enc) { +// parser->m_unknownEncodingData = info.data; +// parser->m_unknownEncodingRelease = info.release; +// parser->m_encoding = enc; +// return XML_ERROR_NONE; +// } +// } +// if (info.release != NULL) +// info.release(info.data); +// } +// return XML_ERROR_UNKNOWN_ENCODING; +// } + +// static enum XML_Error PTRCALL +// prologInitProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// enum XML_Error result = initializeEncoding(parser); +// if (result != XML_ERROR_NONE) +// return result; +// parser->m_processor = prologProcessor; +// return prologProcessor(parser, s, end, nextPtr); +// } + +// #ifdef XML_DTD + +// static enum XML_Error PTRCALL +// externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// enum XML_Error result = initializeEncoding(parser); +// if (result != XML_ERROR_NONE) +// return result; + +// /* we know now that XML_Parse(Buffer) has been called, +// so we consider the external parameter entity read */ +// parser->m_dtd->paramEntityRead = XML_TRUE; + +// if (parser->m_prologState.inEntityValue) { +// parser->m_processor = entityValueInitProcessor; +// return entityValueInitProcessor(parser, s, end, nextPtr); +// } else { +// parser->m_processor = externalParEntProcessor; +// return externalParEntProcessor(parser, s, end, nextPtr); +// } +// } + +// static enum XML_Error PTRCALL +// entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// int tok; +// const char *start = s; +// const char *next = start; +// parser->m_eventPtr = start; + +// for (;;) { +// tok = XmlPrologTok(parser->m_encoding, start, end, &next); +// parser->m_eventEndPtr = next; +// if (tok <= 0) { +// if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// switch (tok) { +// case XML_TOK_INVALID: +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL: +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// return XML_ERROR_PARTIAL_CHAR; +// case XML_TOK_NONE: /* start == end */ +// default: +// break; +// } +// /* found end of entity value - can store it now */ +// return storeEntityValue(parser, parser->m_encoding, s, end); +// } else if (tok == XML_TOK_XML_DECL) { +// enum XML_Error result; +// result = processXmlDecl(parser, 0, start, next); +// if (result != XML_ERROR_NONE) +// return result; +// /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For +// * that to happen, a parameter entity parsing handler must have attempted +// * to suspend the parser, which fails and raises an error. The parser can +// * be aborted, but can't be suspended. +// */ +// if (parser->m_parsingStatus.parsing == XML_FINISHED) +// return XML_ERROR_ABORTED; +// *nextPtr = next; +// /* stop scanning for text declaration - we found one */ +// parser->m_processor = entityValueProcessor; +// return entityValueProcessor(parser, next, end, nextPtr); +// } +// /* If we are at the end of the buffer, this would cause XmlPrologTok to +// return XML_TOK_NONE on the next call, which would then cause the +// function to exit with *nextPtr set to s - that is what we want for other +// tokens, but not for the BOM - we would rather like to skip it; +// then, when this routine is entered the next time, XmlPrologTok will +// return XML_TOK_INVALID, since the BOM is still in the buffer +// */ +// else if (tok == XML_TOK_BOM && next == end +// && ! parser->m_parsingStatus.finalBuffer) { +// *nextPtr = next; +// return XML_ERROR_NONE; +// } +// /* If we get this token, we have the start of what might be a +// normal tag, but not a declaration (i.e. it doesn't begin with +// "m_eventPtr = start; +// } +// } + +// static enum XML_Error PTRCALL +// externalParEntProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// const char *next = s; +// int tok; + +// tok = XmlPrologTok(parser->m_encoding, s, end, &next); +// if (tok <= 0) { +// if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// switch (tok) { +// case XML_TOK_INVALID: +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL: +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// return XML_ERROR_PARTIAL_CHAR; +// case XML_TOK_NONE: /* start == end */ +// default: +// break; +// } +// } +// /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. +// However, when parsing an external subset, doProlog will not accept a BOM +// as valid, and report a syntax error, so we have to skip the BOM +// */ +// else if (tok == XML_TOK_BOM) { +// s = next; +// tok = XmlPrologTok(parser->m_encoding, s, end, &next); +// } + +// parser->m_processor = prologProcessor; +// return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); +// } + +// static enum XML_Error PTRCALL +// entityValueProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// const char *start = s; +// const char *next = s; +// const ENCODING *enc = parser->m_encoding; +// int tok; + +// for (;;) { +// tok = XmlPrologTok(enc, start, end, &next); +// if (tok <= 0) { +// if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// switch (tok) { +// case XML_TOK_INVALID: +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL: +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// return XML_ERROR_PARTIAL_CHAR; +// case XML_TOK_NONE: /* start == end */ +// default: +// break; +// } +// /* found end of entity value - can store it now */ +// return storeEntityValue(parser, enc, s, end); +// } +// start = next; +// } +// } + +// #endif /* XML_DTD */ + +// static enum XML_Error PTRCALL +// prologProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// const char *next = s; +// int tok = XmlPrologTok(parser->m_encoding, s, end, &next); +// return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); +// } + +// static enum XML_Error +// doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, +// int tok, const char *next, const char **nextPtr, XML_Bool haveMore, +// XML_Bool allowClosingDoctype) { +// #ifdef XML_DTD +// static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; +// #endif /* XML_DTD */ +// static const XML_Char atypeCDATA[] +// = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +// static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; +// static const XML_Char atypeIDREF[] +// = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; +// static const XML_Char atypeIDREFS[] +// = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; +// static const XML_Char atypeENTITY[] +// = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; +// static const XML_Char atypeENTITIES[] +// = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, +// ASCII_I, ASCII_E, ASCII_S, '\0'}; +// static const XML_Char atypeNMTOKEN[] +// = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; +// static const XML_Char atypeNMTOKENS[] +// = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, +// ASCII_E, ASCII_N, ASCII_S, '\0'}; +// static const XML_Char notationPrefix[] +// = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, +// ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; +// static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; +// static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; + +// /* save one level of indirection */ +// DTD *const dtd = parser->m_dtd; + +// const char **eventPP; +// const char **eventEndPP; +// enum XML_Content_Quant quant; + +// if (enc == parser->m_encoding) { +// eventPP = &parser->m_eventPtr; +// eventEndPP = &parser->m_eventEndPtr; +// } else { +// eventPP = &(parser->m_openInternalEntities->internalEventPtr); +// eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); +// } + +// for (;;) { +// int role; +// XML_Bool handleDefault = XML_TRUE; +// *eventPP = s; +// *eventEndPP = next; +// if (tok <= 0) { +// if (haveMore && tok != XML_TOK_INVALID) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// switch (tok) { +// case XML_TOK_INVALID: +// *eventPP = next; +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL: +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// return XML_ERROR_PARTIAL_CHAR; +// case -XML_TOK_PROLOG_S: +// tok = -tok; +// break; +// case XML_TOK_NONE: +// #ifdef XML_DTD +// /* for internal PE NOT referenced between declarations */ +// if (enc != parser->m_encoding +// && ! parser->m_openInternalEntities->betweenDecl) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// /* WFC: PE Between Declarations - must check that PE contains +// complete markup, not only for external PEs, but also for +// internal PEs if the reference occurs between declarations. +// */ +// if (parser->m_isParamEntity || enc != parser->m_encoding) { +// if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) +// == XML_ROLE_ERROR) +// return XML_ERROR_INCOMPLETE_PE; +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// #endif /* XML_DTD */ +// return XML_ERROR_NO_ELEMENTS; +// default: +// tok = -tok; +// next = end; +// break; +// } +// } +// role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); +// switch (role) { +// case XML_ROLE_XML_DECL: { +// enum XML_Error result = processXmlDecl(parser, 0, s, next); +// if (result != XML_ERROR_NONE) +// return result; +// enc = parser->m_encoding; +// handleDefault = XML_FALSE; +// } break; +// case XML_ROLE_DOCTYPE_NAME: +// if (parser->m_startDoctypeDeclHandler) { +// parser->m_doctypeName +// = poolStoreString(&parser->m_tempPool, enc, s, next); +// if (! parser->m_doctypeName) +// return XML_ERROR_NO_MEMORY; +// poolFinish(&parser->m_tempPool); +// parser->m_doctypePubid = NULL; +// handleDefault = XML_FALSE; +// } +// parser->m_doctypeSysid = NULL; /* always initialize to NULL */ +// break; +// case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: +// if (parser->m_startDoctypeDeclHandler) { +// parser->m_startDoctypeDeclHandler( +// parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, +// parser->m_doctypePubid, 1); +// parser->m_doctypeName = NULL; +// poolClear(&parser->m_tempPool); +// handleDefault = XML_FALSE; +// } +// break; +// #ifdef XML_DTD +// case XML_ROLE_TEXT_DECL: { +// enum XML_Error result = processXmlDecl(parser, 1, s, next); +// if (result != XML_ERROR_NONE) +// return result; +// enc = parser->m_encoding; +// handleDefault = XML_FALSE; +// } break; +// #endif /* XML_DTD */ +// case XML_ROLE_DOCTYPE_PUBLIC_ID: +// #ifdef XML_DTD +// parser->m_useForeignDTD = XML_FALSE; +// parser->m_declEntity = (ENTITY *)lookup( +// parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); +// if (! parser->m_declEntity) +// return XML_ERROR_NO_MEMORY; +// #endif /* XML_DTD */ +// dtd->hasParamEntityRefs = XML_TRUE; +// if (parser->m_startDoctypeDeclHandler) { +// XML_Char *pubId; +// if (! XmlIsPublicId(enc, s, next, eventPP)) +// return XML_ERROR_PUBLICID; +// pubId = poolStoreString(&parser->m_tempPool, enc, +// s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! pubId) +// return XML_ERROR_NO_MEMORY; +// normalizePublicId(pubId); +// poolFinish(&parser->m_tempPool); +// parser->m_doctypePubid = pubId; +// handleDefault = XML_FALSE; +// goto alreadyChecked; +// } +// /* fall through */ +// case XML_ROLE_ENTITY_PUBLIC_ID: +// if (! XmlIsPublicId(enc, s, next, eventPP)) +// return XML_ERROR_PUBLICID; +// alreadyChecked: +// if (dtd->keepProcessing && parser->m_declEntity) { +// XML_Char *tem +// = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! tem) +// return XML_ERROR_NO_MEMORY; +// normalizePublicId(tem); +// parser->m_declEntity->publicId = tem; +// poolFinish(&dtd->pool); +// /* Don't suppress the default handler if we fell through from +// * the XML_ROLE_DOCTYPE_PUBLIC_ID case. +// */ +// if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_DOCTYPE_CLOSE: +// if (allowClosingDoctype != XML_TRUE) { +// /* Must not close doctype from within expanded parameter entities */ +// return XML_ERROR_INVALID_TOKEN; +// } + +// if (parser->m_doctypeName) { +// parser->m_startDoctypeDeclHandler( +// parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, +// parser->m_doctypePubid, 0); +// poolClear(&parser->m_tempPool); +// handleDefault = XML_FALSE; +// } +// /* parser->m_doctypeSysid will be non-NULL in the case of a previous +// XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler +// was not set, indicating an external subset +// */ +// #ifdef XML_DTD +// if (parser->m_doctypeSysid || parser->m_useForeignDTD) { +// XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; +// dtd->hasParamEntityRefs = XML_TRUE; +// if (parser->m_paramEntityParsing +// && parser->m_externalEntityRefHandler) { +// ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, +// externalSubsetName, sizeof(ENTITY)); +// if (! entity) { +// /* The external subset name "#" will have already been +// * inserted into the hash table at the start of the +// * external entity parsing, so no allocation will happen +// * and lookup() cannot fail. +// */ +// return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ +// } +// if (parser->m_useForeignDTD) +// entity->base = parser->m_curBase; +// dtd->paramEntityRead = XML_FALSE; +// if (! parser->m_externalEntityRefHandler( +// parser->m_externalEntityRefHandlerArg, 0, entity->base, +// entity->systemId, entity->publicId)) +// return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +// if (dtd->paramEntityRead) { +// if (! dtd->standalone && parser->m_notStandaloneHandler +// && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) +// return XML_ERROR_NOT_STANDALONE; +// } +// /* if we didn't read the foreign DTD then this means that there +// is no external subset and we must reset dtd->hasParamEntityRefs +// */ +// else if (! parser->m_doctypeSysid) +// dtd->hasParamEntityRefs = hadParamEntityRefs; +// /* end of DTD - no need to update dtd->keepProcessing */ +// } +// parser->m_useForeignDTD = XML_FALSE; +// } +// #endif /* XML_DTD */ +// if (parser->m_endDoctypeDeclHandler) { +// parser->m_endDoctypeDeclHandler(parser->m_handlerArg); +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_INSTANCE_START: +// #ifdef XML_DTD +// /* if there is no DOCTYPE declaration then now is the +// last chance to read the foreign DTD +// */ +// if (parser->m_useForeignDTD) { +// XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; +// dtd->hasParamEntityRefs = XML_TRUE; +// if (parser->m_paramEntityParsing +// && parser->m_externalEntityRefHandler) { +// ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, +// externalSubsetName, sizeof(ENTITY)); +// if (! entity) +// return XML_ERROR_NO_MEMORY; +// entity->base = parser->m_curBase; +// dtd->paramEntityRead = XML_FALSE; +// if (! parser->m_externalEntityRefHandler( +// parser->m_externalEntityRefHandlerArg, 0, entity->base, +// entity->systemId, entity->publicId)) +// return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +// if (dtd->paramEntityRead) { +// if (! dtd->standalone && parser->m_notStandaloneHandler +// && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) +// return XML_ERROR_NOT_STANDALONE; +// } +// /* if we didn't read the foreign DTD then this means that there +// is no external subset and we must reset dtd->hasParamEntityRefs +// */ +// else +// dtd->hasParamEntityRefs = hadParamEntityRefs; +// /* end of DTD - no need to update dtd->keepProcessing */ +// } +// } +// #endif /* XML_DTD */ +// parser->m_processor = contentProcessor; +// return contentProcessor(parser, s, end, nextPtr); +// case XML_ROLE_ATTLIST_ELEMENT_NAME: +// parser->m_declElementType = getElementType(parser, enc, s, next); +// if (! parser->m_declElementType) +// return XML_ERROR_NO_MEMORY; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_NAME: +// parser->m_declAttributeId = getAttributeId(parser, enc, s, next); +// if (! parser->m_declAttributeId) +// return XML_ERROR_NO_MEMORY; +// parser->m_declAttributeIsCdata = XML_FALSE; +// parser->m_declAttributeType = NULL; +// parser->m_declAttributeIsId = XML_FALSE; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_CDATA: +// parser->m_declAttributeIsCdata = XML_TRUE; +// parser->m_declAttributeType = atypeCDATA; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_ID: +// parser->m_declAttributeIsId = XML_TRUE; +// parser->m_declAttributeType = atypeID; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_IDREF: +// parser->m_declAttributeType = atypeIDREF; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: +// parser->m_declAttributeType = atypeIDREFS; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: +// parser->m_declAttributeType = atypeENTITY; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: +// parser->m_declAttributeType = atypeENTITIES; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: +// parser->m_declAttributeType = atypeNMTOKEN; +// goto checkAttListDeclHandler; +// case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: +// parser->m_declAttributeType = atypeNMTOKENS; +// checkAttListDeclHandler: +// if (dtd->keepProcessing && parser->m_attlistDeclHandler) +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_ATTRIBUTE_ENUM_VALUE: +// case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: +// if (dtd->keepProcessing && parser->m_attlistDeclHandler) { +// const XML_Char *prefix; +// if (parser->m_declAttributeType) { +// prefix = enumValueSep; +// } else { +// prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix +// : enumValueStart); +// } +// if (! poolAppendString(&parser->m_tempPool, prefix)) +// return XML_ERROR_NO_MEMORY; +// if (! poolAppend(&parser->m_tempPool, enc, s, next)) +// return XML_ERROR_NO_MEMORY; +// parser->m_declAttributeType = parser->m_tempPool.start; +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: +// case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: +// if (dtd->keepProcessing) { +// if (! defineAttribute(parser->m_declElementType, +// parser->m_declAttributeId, +// parser->m_declAttributeIsCdata, +// parser->m_declAttributeIsId, 0, parser)) +// return XML_ERROR_NO_MEMORY; +// if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { +// if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) +// || (*parser->m_declAttributeType == XML_T(ASCII_N) +// && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { +// /* Enumerated or Notation type */ +// if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) +// || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) +// return XML_ERROR_NO_MEMORY; +// parser->m_declAttributeType = parser->m_tempPool.start; +// poolFinish(&parser->m_tempPool); +// } +// *eventEndPP = s; +// parser->m_attlistDeclHandler( +// parser->m_handlerArg, parser->m_declElementType->name, +// parser->m_declAttributeId->name, parser->m_declAttributeType, 0, +// role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); +// poolClear(&parser->m_tempPool); +// handleDefault = XML_FALSE; +// } +// } +// break; +// case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: +// case XML_ROLE_FIXED_ATTRIBUTE_VALUE: +// if (dtd->keepProcessing) { +// const XML_Char *attVal; +// enum XML_Error result = storeAttributeValue( +// parser, enc, parser->m_declAttributeIsCdata, +// s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool); +// if (result) +// return result; +// attVal = poolStart(&dtd->pool); +// poolFinish(&dtd->pool); +// /* ID attributes aren't allowed to have a default */ +// if (! defineAttribute( +// parser->m_declElementType, parser->m_declAttributeId, +// parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) +// return XML_ERROR_NO_MEMORY; +// if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { +// if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) +// || (*parser->m_declAttributeType == XML_T(ASCII_N) +// && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { +// /* Enumerated or Notation type */ +// if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) +// || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) +// return XML_ERROR_NO_MEMORY; +// parser->m_declAttributeType = parser->m_tempPool.start; +// poolFinish(&parser->m_tempPool); +// } +// *eventEndPP = s; +// parser->m_attlistDeclHandler( +// parser->m_handlerArg, parser->m_declElementType->name, +// parser->m_declAttributeId->name, parser->m_declAttributeType, +// attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); +// poolClear(&parser->m_tempPool); +// handleDefault = XML_FALSE; +// } +// } +// break; +// case XML_ROLE_ENTITY_VALUE: +// if (dtd->keepProcessing) { +// enum XML_Error result = storeEntityValue( +// parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); +// if (parser->m_declEntity) { +// parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); +// parser->m_declEntity->textLen +// = (int)(poolLength(&dtd->entityValuePool)); +// poolFinish(&dtd->entityValuePool); +// if (parser->m_entityDeclHandler) { +// *eventEndPP = s; +// parser->m_entityDeclHandler( +// parser->m_handlerArg, parser->m_declEntity->name, +// parser->m_declEntity->is_param, parser->m_declEntity->textPtr, +// parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); +// handleDefault = XML_FALSE; +// } +// } else +// poolDiscard(&dtd->entityValuePool); +// if (result != XML_ERROR_NONE) +// return result; +// } +// break; +// case XML_ROLE_DOCTYPE_SYSTEM_ID: +// #ifdef XML_DTD +// parser->m_useForeignDTD = XML_FALSE; +// #endif /* XML_DTD */ +// dtd->hasParamEntityRefs = XML_TRUE; +// if (parser->m_startDoctypeDeclHandler) { +// parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, +// s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (parser->m_doctypeSysid == NULL) +// return XML_ERROR_NO_MEMORY; +// poolFinish(&parser->m_tempPool); +// handleDefault = XML_FALSE; +// } +// #ifdef XML_DTD +// else +// /* use externalSubsetName to make parser->m_doctypeSysid non-NULL +// for the case where no parser->m_startDoctypeDeclHandler is set */ +// parser->m_doctypeSysid = externalSubsetName; +// #endif /* XML_DTD */ +// if (! dtd->standalone +// #ifdef XML_DTD +// && ! parser->m_paramEntityParsing +// #endif /* XML_DTD */ +// && parser->m_notStandaloneHandler +// && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) +// return XML_ERROR_NOT_STANDALONE; +// #ifndef XML_DTD +// break; +// #else /* XML_DTD */ +// if (! parser->m_declEntity) { +// parser->m_declEntity = (ENTITY *)lookup( +// parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); +// if (! parser->m_declEntity) +// return XML_ERROR_NO_MEMORY; +// parser->m_declEntity->publicId = NULL; +// } +// #endif /* XML_DTD */ +// /* fall through */ +// case XML_ROLE_ENTITY_SYSTEM_ID: +// if (dtd->keepProcessing && parser->m_declEntity) { +// parser->m_declEntity->systemId +// = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! parser->m_declEntity->systemId) +// return XML_ERROR_NO_MEMORY; +// parser->m_declEntity->base = parser->m_curBase; +// poolFinish(&dtd->pool); +// /* Don't suppress the default handler if we fell through from +// * the XML_ROLE_DOCTYPE_SYSTEM_ID case. +// */ +// if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_ENTITY_COMPLETE: +// if (dtd->keepProcessing && parser->m_declEntity +// && parser->m_entityDeclHandler) { +// *eventEndPP = s; +// parser->m_entityDeclHandler( +// parser->m_handlerArg, parser->m_declEntity->name, +// parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base, +// parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0); +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_ENTITY_NOTATION_NAME: +// if (dtd->keepProcessing && parser->m_declEntity) { +// parser->m_declEntity->notation +// = poolStoreString(&dtd->pool, enc, s, next); +// if (! parser->m_declEntity->notation) +// return XML_ERROR_NO_MEMORY; +// poolFinish(&dtd->pool); +// if (parser->m_unparsedEntityDeclHandler) { +// *eventEndPP = s; +// parser->m_unparsedEntityDeclHandler( +// parser->m_handlerArg, parser->m_declEntity->name, +// parser->m_declEntity->base, parser->m_declEntity->systemId, +// parser->m_declEntity->publicId, parser->m_declEntity->notation); +// handleDefault = XML_FALSE; +// } else if (parser->m_entityDeclHandler) { +// *eventEndPP = s; +// parser->m_entityDeclHandler( +// parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0, +// parser->m_declEntity->base, parser->m_declEntity->systemId, +// parser->m_declEntity->publicId, parser->m_declEntity->notation); +// handleDefault = XML_FALSE; +// } +// } +// break; +// case XML_ROLE_GENERAL_ENTITY_NAME: { +// if (XmlPredefinedEntityName(enc, s, next)) { +// parser->m_declEntity = NULL; +// break; +// } +// if (dtd->keepProcessing) { +// const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); +// if (! name) +// return XML_ERROR_NO_MEMORY; +// parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, +// name, sizeof(ENTITY)); +// if (! parser->m_declEntity) +// return XML_ERROR_NO_MEMORY; +// if (parser->m_declEntity->name != name) { +// poolDiscard(&dtd->pool); +// parser->m_declEntity = NULL; +// } else { +// poolFinish(&dtd->pool); +// parser->m_declEntity->publicId = NULL; +// parser->m_declEntity->is_param = XML_FALSE; +// /* if we have a parent parser or are reading an internal parameter +// entity, then the entity declaration is not considered "internal" +// */ +// parser->m_declEntity->is_internal +// = ! (parser->m_parentParser || parser->m_openInternalEntities); +// if (parser->m_entityDeclHandler) +// handleDefault = XML_FALSE; +// } +// } else { +// poolDiscard(&dtd->pool); +// parser->m_declEntity = NULL; +// } +// } break; +// case XML_ROLE_PARAM_ENTITY_NAME: +// #ifdef XML_DTD +// if (dtd->keepProcessing) { +// const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); +// if (! name) +// return XML_ERROR_NO_MEMORY; +// parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, +// name, sizeof(ENTITY)); +// if (! parser->m_declEntity) +// return XML_ERROR_NO_MEMORY; +// if (parser->m_declEntity->name != name) { +// poolDiscard(&dtd->pool); +// parser->m_declEntity = NULL; +// } else { +// poolFinish(&dtd->pool); +// parser->m_declEntity->publicId = NULL; +// parser->m_declEntity->is_param = XML_TRUE; +// /* if we have a parent parser or are reading an internal parameter +// entity, then the entity declaration is not considered "internal" +// */ +// parser->m_declEntity->is_internal +// = ! (parser->m_parentParser || parser->m_openInternalEntities); +// if (parser->m_entityDeclHandler) +// handleDefault = XML_FALSE; +// } +// } else { +// poolDiscard(&dtd->pool); +// parser->m_declEntity = NULL; +// } +// #else /* not XML_DTD */ +// parser->m_declEntity = NULL; +// #endif /* XML_DTD */ +// break; +// case XML_ROLE_NOTATION_NAME: +// parser->m_declNotationPublicId = NULL; +// parser->m_declNotationName = NULL; +// if (parser->m_notationDeclHandler) { +// parser->m_declNotationName +// = poolStoreString(&parser->m_tempPool, enc, s, next); +// if (! parser->m_declNotationName) +// return XML_ERROR_NO_MEMORY; +// poolFinish(&parser->m_tempPool); +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_NOTATION_PUBLIC_ID: +// if (! XmlIsPublicId(enc, s, next, eventPP)) +// return XML_ERROR_PUBLICID; +// if (parser +// ->m_declNotationName) { /* means m_notationDeclHandler != NULL */ +// XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, +// s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! tem) +// return XML_ERROR_NO_MEMORY; +// normalizePublicId(tem); +// parser->m_declNotationPublicId = tem; +// poolFinish(&parser->m_tempPool); +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_NOTATION_SYSTEM_ID: +// if (parser->m_declNotationName && parser->m_notationDeclHandler) { +// const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc, +// s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! systemId) +// return XML_ERROR_NO_MEMORY; +// *eventEndPP = s; +// parser->m_notationDeclHandler( +// parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, +// systemId, parser->m_declNotationPublicId); +// handleDefault = XML_FALSE; +// } +// poolClear(&parser->m_tempPool); +// break; +// case XML_ROLE_NOTATION_NO_SYSTEM_ID: +// if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { +// *eventEndPP = s; +// parser->m_notationDeclHandler( +// parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, +// 0, parser->m_declNotationPublicId); +// handleDefault = XML_FALSE; +// } +// poolClear(&parser->m_tempPool); +// break; +// case XML_ROLE_ERROR: +// switch (tok) { +// case XML_TOK_PARAM_ENTITY_REF: +// /* PE references in internal subset are +// not allowed within declarations. */ +// return XML_ERROR_PARAM_ENTITY_REF; +// case XML_TOK_XML_DECL: +// return XML_ERROR_MISPLACED_XML_PI; +// default: +// return XML_ERROR_SYNTAX; +// } +// #ifdef XML_DTD +// case XML_ROLE_IGNORE_SECT: { +// enum XML_Error result; +// if (parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); +// handleDefault = XML_FALSE; +// result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); +// if (result != XML_ERROR_NONE) +// return result; +// else if (! next) { +// parser->m_processor = ignoreSectionProcessor; +// return result; +// } +// } break; +// #endif /* XML_DTD */ +// case XML_ROLE_GROUP_OPEN: +// if (parser->m_prologState.level >= parser->m_groupSize) { +// if (parser->m_groupSize) { +// { +// char *const new_connector = (char *)REALLOC( +// parser, parser->m_groupConnector, parser->m_groupSize *= 2); +// if (new_connector == NULL) { +// parser->m_groupSize /= 2; +// return XML_ERROR_NO_MEMORY; +// } +// parser->m_groupConnector = new_connector; +// } + +// if (dtd->scaffIndex) { +// int *const new_scaff_index = (int *)REALLOC( +// parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); +// if (new_scaff_index == NULL) +// return XML_ERROR_NO_MEMORY; +// dtd->scaffIndex = new_scaff_index; +// } +// } else { +// parser->m_groupConnector +// = (char *)MALLOC(parser, parser->m_groupSize = 32); +// if (! parser->m_groupConnector) { +// parser->m_groupSize = 0; +// return XML_ERROR_NO_MEMORY; +// } +// } +// } +// parser->m_groupConnector[parser->m_prologState.level] = 0; +// if (dtd->in_eldecl) { +// int myindex = nextScaffoldPart(parser); +// if (myindex < 0) +// return XML_ERROR_NO_MEMORY; +// assert(dtd->scaffIndex != NULL); +// dtd->scaffIndex[dtd->scaffLevel] = myindex; +// dtd->scaffLevel++; +// dtd->scaffold[myindex].type = XML_CTYPE_SEQ; +// if (parser->m_elementDeclHandler) +// handleDefault = XML_FALSE; +// } +// break; +// case XML_ROLE_GROUP_SEQUENCE: +// if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) +// return XML_ERROR_SYNTAX; +// parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; +// if (dtd->in_eldecl && parser->m_elementDeclHandler) +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_GROUP_CHOICE: +// if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) +// return XML_ERROR_SYNTAX; +// if (dtd->in_eldecl +// && ! parser->m_groupConnector[parser->m_prologState.level] +// && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type +// != XML_CTYPE_MIXED)) { +// dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type +// = XML_CTYPE_CHOICE; +// if (parser->m_elementDeclHandler) +// handleDefault = XML_FALSE; +// } +// parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; +// break; +// case XML_ROLE_PARAM_ENTITY_REF: +// #ifdef XML_DTD +// case XML_ROLE_INNER_PARAM_ENTITY_REF: +// dtd->hasParamEntityRefs = XML_TRUE; +// if (! parser->m_paramEntityParsing) +// dtd->keepProcessing = dtd->standalone; +// else { +// const XML_Char *name; +// ENTITY *entity; +// name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! name) +// return XML_ERROR_NO_MEMORY; +// entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); +// poolDiscard(&dtd->pool); +// /* first, determine if a check for an existing declaration is needed; +// if yes, check that the entity exists, and that it is internal, +// otherwise call the skipped entity handler +// */ +// if (parser->m_prologState.documentEntity +// && (dtd->standalone ? ! parser->m_openInternalEntities +// : ! dtd->hasParamEntityRefs)) { +// if (! entity) +// return XML_ERROR_UNDEFINED_ENTITY; +// else if (! entity->is_internal) { +// /* It's hard to exhaustively search the code to be sure, +// * but there doesn't seem to be a way of executing the +// * following line. There are two cases: +// * +// * If 'standalone' is false, the DTD must have no +// * parameter entities or we wouldn't have passed the outer +// * 'if' statement. That measn the only entity in the hash +// * table is the external subset name "#" which cannot be +// * given as a parameter entity name in XML syntax, so the +// * lookup must have returned NULL and we don't even reach +// * the test for an internal entity. +// * +// * If 'standalone' is true, it does not seem to be +// * possible to create entities taking this code path that +// * are not internal entities, so fail the test above. +// * +// * Because this analysis is very uncertain, the code is +// * being left in place and merely removed from the +// * coverage test statistics. +// */ +// return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ +// } +// } else if (! entity) { +// dtd->keepProcessing = dtd->standalone; +// /* cannot report skipped entities in declarations */ +// if ((role == XML_ROLE_PARAM_ENTITY_REF) +// && parser->m_skippedEntityHandler) { +// parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); +// handleDefault = XML_FALSE; +// } +// break; +// } +// if (entity->open) +// return XML_ERROR_RECURSIVE_ENTITY_REF; +// if (entity->textPtr) { +// enum XML_Error result; +// XML_Bool betweenDecl +// = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); +// result = processInternalEntity(parser, entity, betweenDecl); +// if (result != XML_ERROR_NONE) +// return result; +// handleDefault = XML_FALSE; +// break; +// } +// if (parser->m_externalEntityRefHandler) { +// dtd->paramEntityRead = XML_FALSE; +// entity->open = XML_TRUE; +// if (! parser->m_externalEntityRefHandler( +// parser->m_externalEntityRefHandlerArg, 0, entity->base, +// entity->systemId, entity->publicId)) { +// entity->open = XML_FALSE; +// return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +// } +// entity->open = XML_FALSE; +// handleDefault = XML_FALSE; +// if (! dtd->paramEntityRead) { +// dtd->keepProcessing = dtd->standalone; +// break; +// } +// } else { +// dtd->keepProcessing = dtd->standalone; +// break; +// } +// } +// #endif /* XML_DTD */ +// if (! dtd->standalone && parser->m_notStandaloneHandler +// && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) +// return XML_ERROR_NOT_STANDALONE; +// break; + +// /* Element declaration stuff */ + +// case XML_ROLE_ELEMENT_NAME: +// if (parser->m_elementDeclHandler) { +// parser->m_declElementType = getElementType(parser, enc, s, next); +// if (! parser->m_declElementType) +// return XML_ERROR_NO_MEMORY; +// dtd->scaffLevel = 0; +// dtd->scaffCount = 0; +// dtd->in_eldecl = XML_TRUE; +// handleDefault = XML_FALSE; +// } +// break; + +// case XML_ROLE_CONTENT_ANY: +// case XML_ROLE_CONTENT_EMPTY: +// if (dtd->in_eldecl) { +// if (parser->m_elementDeclHandler) { +// XML_Content *content +// = (XML_Content *)MALLOC(parser, sizeof(XML_Content)); +// if (! content) +// return XML_ERROR_NO_MEMORY; +// content->quant = XML_CQUANT_NONE; +// content->name = NULL; +// content->numchildren = 0; +// content->children = NULL; +// content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY +// : XML_CTYPE_EMPTY); +// *eventEndPP = s; +// parser->m_elementDeclHandler( +// parser->m_handlerArg, parser->m_declElementType->name, content); +// handleDefault = XML_FALSE; +// } +// dtd->in_eldecl = XML_FALSE; +// } +// break; + +// case XML_ROLE_CONTENT_PCDATA: +// if (dtd->in_eldecl) { +// dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type +// = XML_CTYPE_MIXED; +// if (parser->m_elementDeclHandler) +// handleDefault = XML_FALSE; +// } +// break; + +// case XML_ROLE_CONTENT_ELEMENT: +// quant = XML_CQUANT_NONE; +// goto elementContent; +// case XML_ROLE_CONTENT_ELEMENT_OPT: +// quant = XML_CQUANT_OPT; +// goto elementContent; +// case XML_ROLE_CONTENT_ELEMENT_REP: +// quant = XML_CQUANT_REP; +// goto elementContent; +// case XML_ROLE_CONTENT_ELEMENT_PLUS: +// quant = XML_CQUANT_PLUS; +// elementContent: +// if (dtd->in_eldecl) { +// ELEMENT_TYPE *el; +// const XML_Char *name; +// int nameLen; +// const char *nxt +// = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); +// int myindex = nextScaffoldPart(parser); +// if (myindex < 0) +// return XML_ERROR_NO_MEMORY; +// dtd->scaffold[myindex].type = XML_CTYPE_NAME; +// dtd->scaffold[myindex].quant = quant; +// el = getElementType(parser, enc, s, nxt); +// if (! el) +// return XML_ERROR_NO_MEMORY; +// name = el->name; +// dtd->scaffold[myindex].name = name; +// nameLen = 0; +// for (; name[nameLen++];) +// ; +// dtd->contentStringLen += nameLen; +// if (parser->m_elementDeclHandler) +// handleDefault = XML_FALSE; +// } +// break; + +// case XML_ROLE_GROUP_CLOSE: +// quant = XML_CQUANT_NONE; +// goto closeGroup; +// case XML_ROLE_GROUP_CLOSE_OPT: +// quant = XML_CQUANT_OPT; +// goto closeGroup; +// case XML_ROLE_GROUP_CLOSE_REP: +// quant = XML_CQUANT_REP; +// goto closeGroup; +// case XML_ROLE_GROUP_CLOSE_PLUS: +// quant = XML_CQUANT_PLUS; +// closeGroup: +// if (dtd->in_eldecl) { +// if (parser->m_elementDeclHandler) +// handleDefault = XML_FALSE; +// dtd->scaffLevel--; +// dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; +// if (dtd->scaffLevel == 0) { +// if (! handleDefault) { +// XML_Content *model = build_model(parser); +// if (! model) +// return XML_ERROR_NO_MEMORY; +// *eventEndPP = s; +// parser->m_elementDeclHandler( +// parser->m_handlerArg, parser->m_declElementType->name, model); +// } +// dtd->in_eldecl = XML_FALSE; +// dtd->contentStringLen = 0; +// } +// } +// break; +// /* End element declaration stuff */ + +// case XML_ROLE_PI: +// if (! reportProcessingInstruction(parser, enc, s, next)) +// return XML_ERROR_NO_MEMORY; +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_COMMENT: +// if (! reportComment(parser, enc, s, next)) +// return XML_ERROR_NO_MEMORY; +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_NONE: +// switch (tok) { +// case XML_TOK_BOM: +// handleDefault = XML_FALSE; +// break; +// } +// break; +// case XML_ROLE_DOCTYPE_NONE: +// if (parser->m_startDoctypeDeclHandler) +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_ENTITY_NONE: +// if (dtd->keepProcessing && parser->m_entityDeclHandler) +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_NOTATION_NONE: +// if (parser->m_notationDeclHandler) +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_ATTLIST_NONE: +// if (dtd->keepProcessing && parser->m_attlistDeclHandler) +// handleDefault = XML_FALSE; +// break; +// case XML_ROLE_ELEMENT_NONE: +// if (parser->m_elementDeclHandler) +// handleDefault = XML_FALSE; +// break; +// } /* end of big switch */ + +// if (handleDefault && parser->m_defaultHandler) +// reportDefault(parser, enc, s, next); + +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// *nextPtr = next; +// return XML_ERROR_NONE; +// case XML_FINISHED: +// return XML_ERROR_ABORTED; +// default: +// s = next; +// tok = XmlPrologTok(enc, s, end, &next); +// } +// } +// /* not reached */ +// } + +// static enum XML_Error PTRCALL +// epilogProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// parser->m_processor = epilogProcessor; +// parser->m_eventPtr = s; +// for (;;) { +// const char *next = NULL; +// int tok = XmlPrologTok(parser->m_encoding, s, end, &next); +// parser->m_eventEndPtr = next; +// switch (tok) { +// /* report partial linebreak - it might be the last token */ +// case -XML_TOK_PROLOG_S: +// if (parser->m_defaultHandler) { +// reportDefault(parser, parser->m_encoding, s, next); +// if (parser->m_parsingStatus.parsing == XML_FINISHED) +// return XML_ERROR_ABORTED; +// } +// *nextPtr = next; +// return XML_ERROR_NONE; +// case XML_TOK_NONE: +// *nextPtr = s; +// return XML_ERROR_NONE; +// case XML_TOK_PROLOG_S: +// if (parser->m_defaultHandler) +// reportDefault(parser, parser->m_encoding, s, next); +// break; +// case XML_TOK_PI: +// if (! reportProcessingInstruction(parser, parser->m_encoding, s, next)) +// return XML_ERROR_NO_MEMORY; +// break; +// case XML_TOK_COMMENT: +// if (! reportComment(parser, parser->m_encoding, s, next)) +// return XML_ERROR_NO_MEMORY; +// break; +// case XML_TOK_INVALID: +// parser->m_eventPtr = next; +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL: +// if (! parser->m_parsingStatus.finalBuffer) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_UNCLOSED_TOKEN; +// case XML_TOK_PARTIAL_CHAR: +// if (! parser->m_parsingStatus.finalBuffer) { +// *nextPtr = s; +// return XML_ERROR_NONE; +// } +// return XML_ERROR_PARTIAL_CHAR; +// default: +// return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; +// } +// parser->m_eventPtr = s = next; +// switch (parser->m_parsingStatus.parsing) { +// case XML_SUSPENDED: +// *nextPtr = next; +// return XML_ERROR_NONE; +// case XML_FINISHED: +// return XML_ERROR_ABORTED; +// default:; +// } +// } +// } + +// static enum XML_Error +// processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { +// const char *textStart, *textEnd; +// const char *next; +// enum XML_Error result; +// OPEN_INTERNAL_ENTITY *openEntity; + +// if (parser->m_freeInternalEntities) { +// openEntity = parser->m_freeInternalEntities; +// parser->m_freeInternalEntities = openEntity->next; +// } else { +// openEntity +// = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); +// if (! openEntity) +// return XML_ERROR_NO_MEMORY; +// } +// entity->open = XML_TRUE; +// entity->processed = 0; +// openEntity->next = parser->m_openInternalEntities; +// parser->m_openInternalEntities = openEntity; +// openEntity->entity = entity; +// openEntity->startTagLevel = parser->m_tagLevel; +// openEntity->betweenDecl = betweenDecl; +// openEntity->internalEventPtr = NULL; +// openEntity->internalEventEndPtr = NULL; +// textStart = (char *)entity->textPtr; +// textEnd = (char *)(entity->textPtr + entity->textLen); +// /* Set a safe default value in case 'next' does not get set */ +// next = textStart; + +// #ifdef XML_DTD +// if (entity->is_param) { +// int tok +// = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); +// result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, +// tok, next, &next, XML_FALSE, XML_FALSE); +// } else +// #endif /* XML_DTD */ +// result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, +// textStart, textEnd, &next, XML_FALSE); + +// if (result == XML_ERROR_NONE) { +// if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { +// entity->processed = (int)(next - textStart); +// parser->m_processor = internalEntityProcessor; +// } else { +// entity->open = XML_FALSE; +// parser->m_openInternalEntities = openEntity->next; +// /* put openEntity back in list of free instances */ +// openEntity->next = parser->m_freeInternalEntities; +// parser->m_freeInternalEntities = openEntity; +// } +// } +// return result; +// } + +// static enum XML_Error PTRCALL +// internalEntityProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// ENTITY *entity; +// const char *textStart, *textEnd; +// const char *next; +// enum XML_Error result; +// OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; +// if (! openEntity) +// return XML_ERROR_UNEXPECTED_STATE; + +// entity = openEntity->entity; +// textStart = ((char *)entity->textPtr) + entity->processed; +// textEnd = (char *)(entity->textPtr + entity->textLen); +// /* Set a safe default value in case 'next' does not get set */ +// next = textStart; + +// #ifdef XML_DTD +// if (entity->is_param) { +// int tok +// = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); +// result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, +// tok, next, &next, XML_FALSE, XML_TRUE); +// } else +// #endif /* XML_DTD */ +// result = doContent(parser, openEntity->startTagLevel, +// parser->m_internalEncoding, textStart, textEnd, &next, +// XML_FALSE); + +// if (result != XML_ERROR_NONE) +// return result; +// else if (textEnd != next +// && parser->m_parsingStatus.parsing == XML_SUSPENDED) { +// entity->processed = (int)(next - (char *)entity->textPtr); +// return result; +// } else { +// entity->open = XML_FALSE; +// parser->m_openInternalEntities = openEntity->next; +// /* put openEntity back in list of free instances */ +// openEntity->next = parser->m_freeInternalEntities; +// parser->m_freeInternalEntities = openEntity; +// } + +// #ifdef XML_DTD +// if (entity->is_param) { +// int tok; +// parser->m_processor = prologProcessor; +// tok = XmlPrologTok(parser->m_encoding, s, end, &next); +// return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE); +// } else +// #endif /* XML_DTD */ +// { +// parser->m_processor = contentProcessor; +// /* see externalEntityContentProcessor vs contentProcessor */ +// return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, +// s, end, nextPtr, +// (XML_Bool)! parser->m_parsingStatus.finalBuffer); +// } +// } + +// static enum XML_Error PTRCALL +// errorProcessor(XML_Parser parser, const char *s, const char *end, +// const char **nextPtr) { +// UNUSED_P(s); +// UNUSED_P(end); +// UNUSED_P(nextPtr); +// return parser->m_errorCode; +// } + +// static enum XML_Error +// storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, +// const char *ptr, const char *end, STRING_POOL *pool) { +// enum XML_Error result +// = appendAttributeValue(parser, enc, isCdata, ptr, end, pool); +// if (result) +// return result; +// if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) +// poolChop(pool); +// if (! poolAppendChar(pool, XML_T('\0'))) +// return XML_ERROR_NO_MEMORY; +// return XML_ERROR_NONE; +// } + +// static enum XML_Error +// appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, +// const char *ptr, const char *end, STRING_POOL *pool) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// for (;;) { +// const char *next; +// int tok = XmlAttributeValueTok(enc, ptr, end, &next); +// switch (tok) { +// case XML_TOK_NONE: +// return XML_ERROR_NONE; +// case XML_TOK_INVALID: +// if (enc == parser->m_encoding) +// parser->m_eventPtr = next; +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_PARTIAL: +// if (enc == parser->m_encoding) +// parser->m_eventPtr = ptr; +// return XML_ERROR_INVALID_TOKEN; +// case XML_TOK_CHAR_REF: { +// XML_Char buf[XML_ENCODE_MAX]; +// int i; +// int n = XmlCharRefNumber(enc, ptr); +// if (n < 0) { +// if (enc == parser->m_encoding) +// parser->m_eventPtr = ptr; +// return XML_ERROR_BAD_CHAR_REF; +// } +// if (! isCdata && n == 0x20 /* space */ +// && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) +// break; +// n = XmlEncode(n, (ICHAR *)buf); +// /* The XmlEncode() functions can never return 0 here. That +// * error return happens if the code point passed in is either +// * negative or greater than or equal to 0x110000. The +// * XmlCharRefNumber() functions will all return a number +// * strictly less than 0x110000 or a negative value if an error +// * occurred. The negative value is intercepted above, so +// * XmlEncode() is never passed a value it might return an +// * error for. +// */ +// for (i = 0; i < n; i++) { +// if (! poolAppendChar(pool, buf[i])) +// return XML_ERROR_NO_MEMORY; +// } +// } break; +// case XML_TOK_DATA_CHARS: +// if (! poolAppend(pool, enc, ptr, next)) +// return XML_ERROR_NO_MEMORY; +// break; +// case XML_TOK_TRAILING_CR: +// next = ptr + enc->minBytesPerChar; +// /* fall through */ +// case XML_TOK_ATTRIBUTE_VALUE_S: +// case XML_TOK_DATA_NEWLINE: +// if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) +// break; +// if (! poolAppendChar(pool, 0x20)) +// return XML_ERROR_NO_MEMORY; +// break; +// case XML_TOK_ENTITY_REF: { +// const XML_Char *name; +// ENTITY *entity; +// char checkEntityDecl; +// XML_Char ch = (XML_Char)XmlPredefinedEntityName( +// enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); +// if (ch) { +// if (! poolAppendChar(pool, ch)) +// return XML_ERROR_NO_MEMORY; +// break; +// } +// name = poolStoreString(&parser->m_temp2Pool, enc, +// ptr + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! name) +// return XML_ERROR_NO_MEMORY; +// entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); +// poolDiscard(&parser->m_temp2Pool); +// /* First, determine if a check for an existing declaration is needed; +// if yes, check that the entity exists, and that it is internal. +// */ +// if (pool == &dtd->pool) /* are we called from prolog? */ +// checkEntityDecl = +// #ifdef XML_DTD +// parser->m_prologState.documentEntity && +// #endif /* XML_DTD */ +// (dtd->standalone ? ! parser->m_openInternalEntities +// : ! dtd->hasParamEntityRefs); +// else /* if (pool == &parser->m_tempPool): we are called from content */ +// checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone; +// if (checkEntityDecl) { +// if (! entity) +// return XML_ERROR_UNDEFINED_ENTITY; +// else if (! entity->is_internal) +// return XML_ERROR_ENTITY_DECLARED_IN_PE; +// } else if (! entity) { +// /* Cannot report skipped entity here - see comments on +// parser->m_skippedEntityHandler. +// if (parser->m_skippedEntityHandler) +// parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); +// */ +// /* Cannot call the default handler because this would be +// out of sync with the call to the startElementHandler. +// if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) +// reportDefault(parser, enc, ptr, next); +// */ +// break; +// } +// if (entity->open) { +// if (enc == parser->m_encoding) { +// /* It does not appear that this line can be executed. +// * +// * The "if (entity->open)" check catches recursive entity +// * definitions. In order to be called with an open +// * entity, it must have gone through this code before and +// * been through the recursive call to +// * appendAttributeValue() some lines below. That call +// * sets the local encoding ("enc") to the parser's +// * internal encoding (internal_utf8 or internal_utf16), +// * which can never be the same as the principle encoding. +// * It doesn't appear there is another code path that gets +// * here with entity->open being TRUE. +// * +// * Since it is not certain that this logic is watertight, +// * we keep the line and merely exclude it from coverage +// * tests. +// */ +// parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ +// } +// return XML_ERROR_RECURSIVE_ENTITY_REF; +// } +// if (entity->notation) { +// if (enc == parser->m_encoding) +// parser->m_eventPtr = ptr; +// return XML_ERROR_BINARY_ENTITY_REF; +// } +// if (! entity->textPtr) { +// if (enc == parser->m_encoding) +// parser->m_eventPtr = ptr; +// return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; +// } else { +// enum XML_Error result; +// const XML_Char *textEnd = entity->textPtr + entity->textLen; +// entity->open = XML_TRUE; +// result = appendAttributeValue(parser, parser->m_internalEncoding, +// isCdata, (char *)entity->textPtr, +// (char *)textEnd, pool); +// entity->open = XML_FALSE; +// if (result) +// return result; +// } +// } break; +// default: +// /* The only token returned by XmlAttributeValueTok() that does +// * not have an explicit case here is XML_TOK_PARTIAL_CHAR. +// * Getting that would require an entity name to contain an +// * incomplete XML character (e.g. \xE2\x82); however previous +// * tokenisers will have already recognised and rejected such +// * names before XmlAttributeValueTok() gets a look-in. This +// * default case should be retained as a safety net, but the code +// * excluded from coverage tests. +// * +// * LCOV_EXCL_START +// */ +// if (enc == parser->m_encoding) +// parser->m_eventPtr = ptr; +// return XML_ERROR_UNEXPECTED_STATE; +// /* LCOV_EXCL_STOP */ +// } +// ptr = next; +// } +// /* not reached */ +// } + +// static enum XML_Error +// storeEntityValue(XML_Parser parser, const ENCODING *enc, +// const char *entityTextPtr, const char *entityTextEnd) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// STRING_POOL *pool = &(dtd->entityValuePool); +// enum XML_Error result = XML_ERROR_NONE; +// #ifdef XML_DTD +// int oldInEntityValue = parser->m_prologState.inEntityValue; +// parser->m_prologState.inEntityValue = 1; +// #endif /* XML_DTD */ +// /* never return Null for the value argument in EntityDeclHandler, +// since this would indicate an external entity; therefore we +// have to make sure that entityValuePool.start is not null */ +// if (! pool->blocks) { +// if (! poolGrow(pool)) +// return XML_ERROR_NO_MEMORY; +// } + +// for (;;) { +// const char *next; +// int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); +// switch (tok) { +// case XML_TOK_PARAM_ENTITY_REF: +// #ifdef XML_DTD +// if (parser->m_isParamEntity || enc != parser->m_encoding) { +// const XML_Char *name; +// ENTITY *entity; +// name = poolStoreString(&parser->m_tempPool, enc, +// entityTextPtr + enc->minBytesPerChar, +// next - enc->minBytesPerChar); +// if (! name) { +// result = XML_ERROR_NO_MEMORY; +// goto endEntityValue; +// } +// entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); +// poolDiscard(&parser->m_tempPool); +// if (! entity) { +// /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ +// /* cannot report skipped entity here - see comments on +// parser->m_skippedEntityHandler +// if (parser->m_skippedEntityHandler) +// parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); +// */ +// dtd->keepProcessing = dtd->standalone; +// goto endEntityValue; +// } +// if (entity->open) { +// if (enc == parser->m_encoding) +// parser->m_eventPtr = entityTextPtr; +// result = XML_ERROR_RECURSIVE_ENTITY_REF; +// goto endEntityValue; +// } +// if (entity->systemId) { +// if (parser->m_externalEntityRefHandler) { +// dtd->paramEntityRead = XML_FALSE; +// entity->open = XML_TRUE; +// if (! parser->m_externalEntityRefHandler( +// parser->m_externalEntityRefHandlerArg, 0, entity->base, +// entity->systemId, entity->publicId)) { +// entity->open = XML_FALSE; +// result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; +// goto endEntityValue; +// } +// entity->open = XML_FALSE; +// if (! dtd->paramEntityRead) +// dtd->keepProcessing = dtd->standalone; +// } else +// dtd->keepProcessing = dtd->standalone; +// } else { +// entity->open = XML_TRUE; +// result = storeEntityValue( +// parser, parser->m_internalEncoding, (char *)entity->textPtr, +// (char *)(entity->textPtr + entity->textLen)); +// entity->open = XML_FALSE; +// if (result) +// goto endEntityValue; +// } +// break; +// } +// #endif /* XML_DTD */ +// /* In the internal subset, PE references are not legal +// within markup declarations, e.g entity values in this case. */ +// parser->m_eventPtr = entityTextPtr; +// result = XML_ERROR_PARAM_ENTITY_REF; +// goto endEntityValue; +// case XML_TOK_NONE: +// result = XML_ERROR_NONE; +// goto endEntityValue; +// case XML_TOK_ENTITY_REF: +// case XML_TOK_DATA_CHARS: +// if (! poolAppend(pool, enc, entityTextPtr, next)) { +// result = XML_ERROR_NO_MEMORY; +// goto endEntityValue; +// } +// break; +// case XML_TOK_TRAILING_CR: +// next = entityTextPtr + enc->minBytesPerChar; +// /* fall through */ +// case XML_TOK_DATA_NEWLINE: +// if (pool->end == pool->ptr && ! poolGrow(pool)) { +// result = XML_ERROR_NO_MEMORY; +// goto endEntityValue; +// } +// *(pool->ptr)++ = 0xA; +// break; +// case XML_TOK_CHAR_REF: { +// XML_Char buf[XML_ENCODE_MAX]; +// int i; +// int n = XmlCharRefNumber(enc, entityTextPtr); +// if (n < 0) { +// if (enc == parser->m_encoding) +// parser->m_eventPtr = entityTextPtr; +// result = XML_ERROR_BAD_CHAR_REF; +// goto endEntityValue; +// } +// n = XmlEncode(n, (ICHAR *)buf); +// /* The XmlEncode() functions can never return 0 here. That +// * error return happens if the code point passed in is either +// * negative or greater than or equal to 0x110000. The +// * XmlCharRefNumber() functions will all return a number +// * strictly less than 0x110000 or a negative value if an error +// * occurred. The negative value is intercepted above, so +// * XmlEncode() is never passed a value it might return an +// * error for. +// */ +// for (i = 0; i < n; i++) { +// if (pool->end == pool->ptr && ! poolGrow(pool)) { +// result = XML_ERROR_NO_MEMORY; +// goto endEntityValue; +// } +// *(pool->ptr)++ = buf[i]; +// } +// } break; +// case XML_TOK_PARTIAL: +// if (enc == parser->m_encoding) +// parser->m_eventPtr = entityTextPtr; +// result = XML_ERROR_INVALID_TOKEN; +// goto endEntityValue; +// case XML_TOK_INVALID: +// if (enc == parser->m_encoding) +// parser->m_eventPtr = next; +// result = XML_ERROR_INVALID_TOKEN; +// goto endEntityValue; +// default: +// /* This default case should be unnecessary -- all the tokens +// * that XmlEntityValueTok() can return have their own explicit +// * cases -- but should be retained for safety. We do however +// * exclude it from the coverage statistics. +// * +// * LCOV_EXCL_START +// */ +// if (enc == parser->m_encoding) +// parser->m_eventPtr = entityTextPtr; +// result = XML_ERROR_UNEXPECTED_STATE; +// goto endEntityValue; +// /* LCOV_EXCL_STOP */ +// } +// entityTextPtr = next; +// } +// endEntityValue: +// #ifdef XML_DTD +// parser->m_prologState.inEntityValue = oldInEntityValue; +// #endif /* XML_DTD */ +// return result; +// } + +// static void FASTCALL +// normalizeLines(XML_Char *s) { +// XML_Char *p; +// for (;; s++) { +// if (*s == XML_T('\0')) +// return; +// if (*s == 0xD) +// break; +// } +// p = s; +// do { +// if (*s == 0xD) { +// *p++ = 0xA; +// if (*++s == 0xA) +// s++; +// } else +// *p++ = *s++; +// } while (*s); +// *p = XML_T('\0'); +// } + +// static int +// reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, +// const char *start, const char *end) { +// const XML_Char *target; +// XML_Char *data; +// const char *tem; +// if (! parser->m_processingInstructionHandler) { +// if (parser->m_defaultHandler) +// reportDefault(parser, enc, start, end); +// return 1; +// } +// start += enc->minBytesPerChar * 2; +// tem = start + XmlNameLength(enc, start); +// target = poolStoreString(&parser->m_tempPool, enc, start, tem); +// if (! target) +// return 0; +// poolFinish(&parser->m_tempPool); +// data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), +// end - enc->minBytesPerChar * 2); +// if (! data) +// return 0; +// normalizeLines(data); +// parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); +// poolClear(&parser->m_tempPool); +// return 1; +// } + +// static int +// reportComment(XML_Parser parser, const ENCODING *enc, const char *start, +// const char *end) { +// XML_Char *data; +// if (! parser->m_commentHandler) { +// if (parser->m_defaultHandler) +// reportDefault(parser, enc, start, end); +// return 1; +// } +// data = poolStoreString(&parser->m_tempPool, enc, +// start + enc->minBytesPerChar * 4, +// end - enc->minBytesPerChar * 3); +// if (! data) +// return 0; +// normalizeLines(data); +// parser->m_commentHandler(parser->m_handlerArg, data); +// poolClear(&parser->m_tempPool); +// return 1; +// } + +// static void +// reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, +// const char *end) { +// if (MUST_CONVERT(enc, s)) { +// enum XML_Convert_Result convert_res; +// const char **eventPP; +// const char **eventEndPP; +// if (enc == parser->m_encoding) { +// eventPP = &parser->m_eventPtr; +// eventEndPP = &parser->m_eventEndPtr; +// } else { +// /* To get here, two things must be true; the parser must be +// * using a character encoding that is not the same as the +// * encoding passed in, and the encoding passed in must need +// * conversion to the internal format (UTF-8 unless XML_UNICODE +// * is defined). The only occasions on which the encoding passed +// * in is not the same as the parser's encoding are when it is +// * the internal encoding (e.g. a previously defined parameter +// * entity, already converted to internal format). This by +// * definition doesn't need conversion, so the whole branch never +// * gets executed. +// * +// * For safety's sake we don't delete these lines and merely +// * exclude them from coverage statistics. +// * +// * LCOV_EXCL_START +// */ +// eventPP = &(parser->m_openInternalEntities->internalEventPtr); +// eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); +// /* LCOV_EXCL_STOP */ +// } +// do { +// ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; +// convert_res +// = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); +// *eventEndPP = s; +// parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, +// (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); +// *eventPP = s; +// } while ((convert_res != XML_CONVERT_COMPLETED) +// && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); +// } else +// parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, +// (int)((XML_Char *)end - (XML_Char *)s)); +// } + +// static int +// defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, +// XML_Bool isId, const XML_Char *value, XML_Parser parser) { +// DEFAULT_ATTRIBUTE *att; +// if (value || isId) { +// /* The handling of default attributes gets messed up if we have +// a default which duplicates a non-default. */ +// int i; +// for (i = 0; i < type->nDefaultAtts; i++) +// if (attId == type->defaultAtts[i].id) +// return 1; +// if (isId && ! type->idAtt && ! attId->xmlns) +// type->idAtt = attId; +// } +// if (type->nDefaultAtts == type->allocDefaultAtts) { +// if (type->allocDefaultAtts == 0) { +// type->allocDefaultAtts = 8; +// type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC( +// parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); +// if (! type->defaultAtts) { +// type->allocDefaultAtts = 0; +// return 0; +// } +// } else { +// DEFAULT_ATTRIBUTE *temp; +// int count = type->allocDefaultAtts * 2; +// temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, +// (count * sizeof(DEFAULT_ATTRIBUTE))); +// if (temp == NULL) +// return 0; +// type->allocDefaultAtts = count; +// type->defaultAtts = temp; +// } +// } +// att = type->defaultAtts + type->nDefaultAtts; +// att->id = attId; +// att->value = value; +// att->isCdata = isCdata; +// if (! isCdata) +// attId->maybeTokenized = XML_TRUE; +// type->nDefaultAtts += 1; +// return 1; +// } + +// static int +// setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// const XML_Char *name; +// for (name = elementType->name; *name; name++) { +// if (*name == XML_T(ASCII_COLON)) { +// PREFIX *prefix; +// const XML_Char *s; +// for (s = elementType->name; s != name; s++) { +// if (! poolAppendChar(&dtd->pool, *s)) +// return 0; +// } +// if (! poolAppendChar(&dtd->pool, XML_T('\0'))) +// return 0; +// prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), +// sizeof(PREFIX)); +// if (! prefix) +// return 0; +// if (prefix->name == poolStart(&dtd->pool)) +// poolFinish(&dtd->pool); +// else +// poolDiscard(&dtd->pool); +// elementType->prefix = prefix; +// break; +// } +// } +// return 1; +// } + +// static ATTRIBUTE_ID * +// getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, +// const char *end) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// ATTRIBUTE_ID *id; +// const XML_Char *name; +// if (! poolAppendChar(&dtd->pool, XML_T('\0'))) +// return NULL; +// name = poolStoreString(&dtd->pool, enc, start, end); +// if (! name) +// return NULL; +// /* skip quotation mark - its storage will be re-used (like in name[-1]) */ +// ++name; +// id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, +// sizeof(ATTRIBUTE_ID)); +// if (! id) +// return NULL; +// if (id->name != name) +// poolDiscard(&dtd->pool); +// else { +// poolFinish(&dtd->pool); +// if (! parser->m_ns) +// ; +// else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) +// && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n) +// && name[4] == XML_T(ASCII_s) +// && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { +// if (name[5] == XML_T('\0')) +// id->prefix = &dtd->defaultPrefix; +// else +// id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, +// sizeof(PREFIX)); +// id->xmlns = XML_TRUE; +// } else { +// int i; +// for (i = 0; name[i]; i++) { +// /* attributes without prefix are *not* in the default namespace */ +// if (name[i] == XML_T(ASCII_COLON)) { +// int j; +// for (j = 0; j < i; j++) { +// if (! poolAppendChar(&dtd->pool, name[j])) +// return NULL; +// } +// if (! poolAppendChar(&dtd->pool, XML_T('\0'))) +// return NULL; +// id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, +// poolStart(&dtd->pool), sizeof(PREFIX)); +// if (! id->prefix) +// return NULL; +// if (id->prefix->name == poolStart(&dtd->pool)) +// poolFinish(&dtd->pool); +// else +// poolDiscard(&dtd->pool); +// break; +// } +// } +// } +// } +// return id; +// } + +// #define CONTEXT_SEP XML_T(ASCII_FF) + +// static const XML_Char * +// getContext(XML_Parser parser) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// HASH_TABLE_ITER iter; +// XML_Bool needSep = XML_FALSE; + +// if (dtd->defaultPrefix.binding) { +// int i; +// int len; +// if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) +// return NULL; +// len = dtd->defaultPrefix.binding->uriLen; +// if (parser->m_namespaceSeparator) +// len--; +// for (i = 0; i < len; i++) { +// if (! poolAppendChar(&parser->m_tempPool, +// dtd->defaultPrefix.binding->uri[i])) { +// /* Because of memory caching, I don't believe this line can be +// * executed. +// * +// * This is part of a loop copying the default prefix binding +// * URI into the parser's temporary string pool. Previously, +// * that URI was copied into the same string pool, with a +// * terminating NUL character, as part of setContext(). When +// * the pool was cleared, that leaves a block definitely big +// * enough to hold the URI on the free block list of the pool. +// * The URI copy in getContext() therefore cannot run out of +// * memory. +// * +// * If the pool is used between the setContext() and +// * getContext() calls, the worst it can do is leave a bigger +// * block on the front of the free list. Given that this is +// * all somewhat inobvious and program logic can be changed, we +// * don't delete the line but we do exclude it from the test +// * coverage statistics. +// */ +// return NULL; /* LCOV_EXCL_LINE */ +// } +// } +// needSep = XML_TRUE; +// } + +// hashTableIterInit(&iter, &(dtd->prefixes)); +// for (;;) { +// int i; +// int len; +// const XML_Char *s; +// PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); +// if (! prefix) +// break; +// if (! prefix->binding) { +// /* This test appears to be (justifiable) paranoia. There does +// * not seem to be a way of injecting a prefix without a binding +// * that doesn't get errored long before this function is called. +// * The test should remain for safety's sake, so we instead +// * exclude the following line from the coverage statistics. +// */ +// continue; /* LCOV_EXCL_LINE */ +// } +// if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) +// return NULL; +// for (s = prefix->name; *s; s++) +// if (! poolAppendChar(&parser->m_tempPool, *s)) +// return NULL; +// if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) +// return NULL; +// len = prefix->binding->uriLen; +// if (parser->m_namespaceSeparator) +// len--; +// for (i = 0; i < len; i++) +// if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) +// return NULL; +// needSep = XML_TRUE; +// } + +// hashTableIterInit(&iter, &(dtd->generalEntities)); +// for (;;) { +// const XML_Char *s; +// ENTITY *e = (ENTITY *)hashTableIterNext(&iter); +// if (! e) +// break; +// if (! e->open) +// continue; +// if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) +// return NULL; +// for (s = e->name; *s; s++) +// if (! poolAppendChar(&parser->m_tempPool, *s)) +// return 0; +// needSep = XML_TRUE; +// } + +// if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) +// return NULL; +// return parser->m_tempPool.start; +// } + +// static XML_Bool +// setContext(XML_Parser parser, const XML_Char *context) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// const XML_Char *s = context; + +// while (*context != XML_T('\0')) { +// if (*s == CONTEXT_SEP || *s == XML_T('\0')) { +// ENTITY *e; +// if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) +// return XML_FALSE; +// e = (ENTITY *)lookup(parser, &dtd->generalEntities, +// poolStart(&parser->m_tempPool), 0); +// if (e) +// e->open = XML_TRUE; +// if (*s != XML_T('\0')) +// s++; +// context = s; +// poolDiscard(&parser->m_tempPool); +// } else if (*s == XML_T(ASCII_EQUALS)) { +// PREFIX *prefix; +// if (poolLength(&parser->m_tempPool) == 0) +// prefix = &dtd->defaultPrefix; +// else { +// if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) +// return XML_FALSE; +// prefix +// = (PREFIX *)lookup(parser, &dtd->prefixes, +// poolStart(&parser->m_tempPool), sizeof(PREFIX)); +// if (! prefix) +// return XML_FALSE; +// if (prefix->name == poolStart(&parser->m_tempPool)) { +// prefix->name = poolCopyString(&dtd->pool, prefix->name); +// if (! prefix->name) +// return XML_FALSE; +// } +// poolDiscard(&parser->m_tempPool); +// } +// for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); +// context++) +// if (! poolAppendChar(&parser->m_tempPool, *context)) +// return XML_FALSE; +// if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) +// return XML_FALSE; +// if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), +// &parser->m_inheritedBindings) +// != XML_ERROR_NONE) +// return XML_FALSE; +// poolDiscard(&parser->m_tempPool); +// if (*context != XML_T('\0')) +// ++context; +// s = context; +// } else { +// if (! poolAppendChar(&parser->m_tempPool, *s)) +// return XML_FALSE; +// s++; +// } +// } +// return XML_TRUE; +// } + +// static void FASTCALL +// normalizePublicId(XML_Char *publicId) { +// XML_Char *p = publicId; +// XML_Char *s; +// for (s = publicId; *s; s++) { +// switch (*s) { +// case 0x20: +// case 0xD: +// case 0xA: +// if (p != publicId && p[-1] != 0x20) +// *p++ = 0x20; +// break; +// default: +// *p++ = *s; +// } +// } +// if (p != publicId && p[-1] == 0x20) +// --p; +// *p = XML_T('\0'); +// } + +// static DTD * +// dtdCreate(const XML_Memory_Handling_Suite *ms) { +// DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); +// if (p == NULL) +// return p; +// poolInit(&(p->pool), ms); +// poolInit(&(p->entityValuePool), ms); +// hashTableInit(&(p->generalEntities), ms); +// hashTableInit(&(p->elementTypes), ms); +// hashTableInit(&(p->attributeIds), ms); +// hashTableInit(&(p->prefixes), ms); +// #ifdef XML_DTD +// p->paramEntityRead = XML_FALSE; +// hashTableInit(&(p->paramEntities), ms); +// #endif /* XML_DTD */ +// p->defaultPrefix.name = NULL; +// p->defaultPrefix.binding = NULL; + +// p->in_eldecl = XML_FALSE; +// p->scaffIndex = NULL; +// p->scaffold = NULL; +// p->scaffLevel = 0; +// p->scaffSize = 0; +// p->scaffCount = 0; +// p->contentStringLen = 0; + +// p->keepProcessing = XML_TRUE; +// p->hasParamEntityRefs = XML_FALSE; +// p->standalone = XML_FALSE; +// return p; +// } + +// static void +// dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) { +// HASH_TABLE_ITER iter; +// hashTableIterInit(&iter, &(p->elementTypes)); +// for (;;) { +// ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); +// if (! e) +// break; +// if (e->allocDefaultAtts != 0) +// ms->free_fcn(e->defaultAtts); +// } +// hashTableClear(&(p->generalEntities)); +// #ifdef XML_DTD +// p->paramEntityRead = XML_FALSE; +// hashTableClear(&(p->paramEntities)); +// #endif /* XML_DTD */ +// hashTableClear(&(p->elementTypes)); +// hashTableClear(&(p->attributeIds)); +// hashTableClear(&(p->prefixes)); +// poolClear(&(p->pool)); +// poolClear(&(p->entityValuePool)); +// p->defaultPrefix.name = NULL; +// p->defaultPrefix.binding = NULL; + +// p->in_eldecl = XML_FALSE; + +// ms->free_fcn(p->scaffIndex); +// p->scaffIndex = NULL; +// ms->free_fcn(p->scaffold); +// p->scaffold = NULL; + +// p->scaffLevel = 0; +// p->scaffSize = 0; +// p->scaffCount = 0; +// p->contentStringLen = 0; + +// p->keepProcessing = XML_TRUE; +// p->hasParamEntityRefs = XML_FALSE; +// p->standalone = XML_FALSE; +// } + +// static void +// dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) { +// HASH_TABLE_ITER iter; +// hashTableIterInit(&iter, &(p->elementTypes)); +// for (;;) { +// ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); +// if (! e) +// break; +// if (e->allocDefaultAtts != 0) +// ms->free_fcn(e->defaultAtts); +// } +// hashTableDestroy(&(p->generalEntities)); +// #ifdef XML_DTD +// hashTableDestroy(&(p->paramEntities)); +// #endif /* XML_DTD */ +// hashTableDestroy(&(p->elementTypes)); +// hashTableDestroy(&(p->attributeIds)); +// hashTableDestroy(&(p->prefixes)); +// poolDestroy(&(p->pool)); +// poolDestroy(&(p->entityValuePool)); +// if (isDocEntity) { +// ms->free_fcn(p->scaffIndex); +// ms->free_fcn(p->scaffold); +// } +// ms->free_fcn(p); +// } + +// /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. +// The new DTD has already been initialized. +// */ +// static int +// dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, +// const XML_Memory_Handling_Suite *ms) { +// HASH_TABLE_ITER iter; + +// /* Copy the prefix table. */ + +// hashTableIterInit(&iter, &(oldDtd->prefixes)); +// for (;;) { +// const XML_Char *name; +// const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); +// if (! oldP) +// break; +// name = poolCopyString(&(newDtd->pool), oldP->name); +// if (! name) +// return 0; +// if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) +// return 0; +// } + +// hashTableIterInit(&iter, &(oldDtd->attributeIds)); + +// /* Copy the attribute id table. */ + +// for (;;) { +// ATTRIBUTE_ID *newA; +// const XML_Char *name; +// const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); + +// if (! oldA) +// break; +// /* Remember to allocate the scratch byte before the name. */ +// if (! poolAppendChar(&(newDtd->pool), XML_T('\0'))) +// return 0; +// name = poolCopyString(&(newDtd->pool), oldA->name); +// if (! name) +// return 0; +// ++name; +// newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, +// sizeof(ATTRIBUTE_ID)); +// if (! newA) +// return 0; +// newA->maybeTokenized = oldA->maybeTokenized; +// if (oldA->prefix) { +// newA->xmlns = oldA->xmlns; +// if (oldA->prefix == &oldDtd->defaultPrefix) +// newA->prefix = &newDtd->defaultPrefix; +// else +// newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), +// oldA->prefix->name, 0); +// } +// } + +// /* Copy the element type table. */ + +// hashTableIterInit(&iter, &(oldDtd->elementTypes)); + +// for (;;) { +// int i; +// ELEMENT_TYPE *newE; +// const XML_Char *name; +// const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); +// if (! oldE) +// break; +// name = poolCopyString(&(newDtd->pool), oldE->name); +// if (! name) +// return 0; +// newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, +// sizeof(ELEMENT_TYPE)); +// if (! newE) +// return 0; +// if (oldE->nDefaultAtts) { +// newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn( +// oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); +// if (! newE->defaultAtts) { +// return 0; +// } +// } +// if (oldE->idAtt) +// newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), +// oldE->idAtt->name, 0); +// newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; +// if (oldE->prefix) +// newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), +// oldE->prefix->name, 0); +// for (i = 0; i < newE->nDefaultAtts; i++) { +// newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup( +// oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); +// newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; +// if (oldE->defaultAtts[i].value) { +// newE->defaultAtts[i].value +// = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); +// if (! newE->defaultAtts[i].value) +// return 0; +// } else +// newE->defaultAtts[i].value = NULL; +// } +// } + +// /* Copy the entity tables. */ +// if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool), +// &(oldDtd->generalEntities))) +// return 0; + +// #ifdef XML_DTD +// if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool), +// &(oldDtd->paramEntities))) +// return 0; +// newDtd->paramEntityRead = oldDtd->paramEntityRead; +// #endif /* XML_DTD */ + +// newDtd->keepProcessing = oldDtd->keepProcessing; +// newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; +// newDtd->standalone = oldDtd->standalone; + +// /* Don't want deep copying for scaffolding */ +// newDtd->in_eldecl = oldDtd->in_eldecl; +// newDtd->scaffold = oldDtd->scaffold; +// newDtd->contentStringLen = oldDtd->contentStringLen; +// newDtd->scaffSize = oldDtd->scaffSize; +// newDtd->scaffLevel = oldDtd->scaffLevel; +// newDtd->scaffIndex = oldDtd->scaffIndex; + +// return 1; +// } /* End dtdCopy */ + +// static int +// copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, +// STRING_POOL *newPool, const HASH_TABLE *oldTable) { +// HASH_TABLE_ITER iter; +// const XML_Char *cachedOldBase = NULL; +// const XML_Char *cachedNewBase = NULL; + +// hashTableIterInit(&iter, oldTable); + +// for (;;) { +// ENTITY *newE; +// const XML_Char *name; +// const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); +// if (! oldE) +// break; +// name = poolCopyString(newPool, oldE->name); +// if (! name) +// return 0; +// newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); +// if (! newE) +// return 0; +// if (oldE->systemId) { +// const XML_Char *tem = poolCopyString(newPool, oldE->systemId); +// if (! tem) +// return 0; +// newE->systemId = tem; +// if (oldE->base) { +// if (oldE->base == cachedOldBase) +// newE->base = cachedNewBase; +// else { +// cachedOldBase = oldE->base; +// tem = poolCopyString(newPool, cachedOldBase); +// if (! tem) +// return 0; +// cachedNewBase = newE->base = tem; +// } +// } +// if (oldE->publicId) { +// tem = poolCopyString(newPool, oldE->publicId); +// if (! tem) +// return 0; +// newE->publicId = tem; +// } +// } else { +// const XML_Char *tem +// = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); +// if (! tem) +// return 0; +// newE->textPtr = tem; +// newE->textLen = oldE->textLen; +// } +// if (oldE->notation) { +// const XML_Char *tem = poolCopyString(newPool, oldE->notation); +// if (! tem) +// return 0; +// newE->notation = tem; +// } +// newE->is_param = oldE->is_param; +// newE->is_internal = oldE->is_internal; +// } +// return 1; +// } + +// #define INIT_POWER 6 + +// static XML_Bool FASTCALL +// keyeq(KEY s1, KEY s2) { +// for (; *s1 == *s2; s1++, s2++) +// if (*s1 == 0) +// return XML_TRUE; +// return XML_FALSE; +// } + +// static size_t +// keylen(KEY s) { +// size_t len = 0; +// for (; *s; s++, len++) +// ; +// return len; +// } + +// static void +// copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) { +// key->k[0] = 0; +// key->k[1] = get_hash_secret_salt(parser); +// } + +// static unsigned long FASTCALL +// hash(XML_Parser parser, KEY s) { +// struct siphash state; +// struct sipkey key; +// (void)sip24_valid; +// copy_salt_to_sipkey(parser, &key); +// sip24_init(&state, &key); +// sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); +// return (unsigned long)sip24_final(&state); +// } + +// static NAMED * +// lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { +// size_t i; +// if (table->size == 0) { +// size_t tsize; +// if (! createSize) +// return NULL; +// table->power = INIT_POWER; +// /* table->size is a power of 2 */ +// table->size = (size_t)1 << INIT_POWER; +// tsize = table->size * sizeof(NAMED *); +// table->v = (NAMED **)table->mem->malloc_fcn(tsize); +// if (! table->v) { +// table->size = 0; +// return NULL; +// } +// memset(table->v, 0, tsize); +// i = hash(parser, name) & ((unsigned long)table->size - 1); +// } else { +// unsigned long h = hash(parser, name); +// unsigned long mask = (unsigned long)table->size - 1; +// unsigned char step = 0; +// i = h & mask; +// while (table->v[i]) { +// if (keyeq(name, table->v[i]->name)) +// return table->v[i]; +// if (! step) +// step = PROBE_STEP(h, mask, table->power); +// i < step ? (i += table->size - step) : (i -= step); +// } +// if (! createSize) +// return NULL; + +// /* check for overflow (table is half full) */ +// if (table->used >> (table->power - 1)) { +// unsigned char newPower = table->power + 1; +// size_t newSize = (size_t)1 << newPower; +// unsigned long newMask = (unsigned long)newSize - 1; +// size_t tsize = newSize * sizeof(NAMED *); +// NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); +// if (! newV) +// return NULL; +// memset(newV, 0, tsize); +// for (i = 0; i < table->size; i++) +// if (table->v[i]) { +// unsigned long newHash = hash(parser, table->v[i]->name); +// size_t j = newHash & newMask; +// step = 0; +// while (newV[j]) { +// if (! step) +// step = PROBE_STEP(newHash, newMask, newPower); +// j < step ? (j += newSize - step) : (j -= step); +// } +// newV[j] = table->v[i]; +// } +// table->mem->free_fcn(table->v); +// table->v = newV; +// table->power = newPower; +// table->size = newSize; +// i = h & newMask; +// step = 0; +// while (table->v[i]) { +// if (! step) +// step = PROBE_STEP(h, newMask, newPower); +// i < step ? (i += newSize - step) : (i -= step); +// } +// } +// } +// table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); +// if (! table->v[i]) +// return NULL; +// memset(table->v[i], 0, createSize); +// table->v[i]->name = name; +// (table->used)++; +// return table->v[i]; +// } + +// static void FASTCALL +// hashTableClear(HASH_TABLE *table) { +// size_t i; +// for (i = 0; i < table->size; i++) { +// table->mem->free_fcn(table->v[i]); +// table->v[i] = NULL; +// } +// table->used = 0; +// } + +// static void FASTCALL +// hashTableDestroy(HASH_TABLE *table) { +// size_t i; +// for (i = 0; i < table->size; i++) +// table->mem->free_fcn(table->v[i]); +// table->mem->free_fcn(table->v); +// } + +// static void FASTCALL +// hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) { +// p->power = 0; +// p->size = 0; +// p->used = 0; +// p->v = NULL; +// p->mem = ms; +// } + +// static void FASTCALL +// hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { +// iter->p = table->v; +// iter->end = iter->p + table->size; +// } + +// static NAMED *FASTCALL +// hashTableIterNext(HASH_TABLE_ITER *iter) { +// while (iter->p != iter->end) { +// NAMED *tem = *(iter->p)++; +// if (tem) +// return tem; +// } +// return NULL; +// } + +// static void FASTCALL +// poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) { +// pool->blocks = NULL; +// pool->freeBlocks = NULL; +// pool->start = NULL; +// pool->ptr = NULL; +// pool->end = NULL; +// pool->mem = ms; +// } + +// static void FASTCALL +// poolClear(STRING_POOL *pool) { +// if (! pool->freeBlocks) +// pool->freeBlocks = pool->blocks; +// else { +// BLOCK *p = pool->blocks; +// while (p) { +// BLOCK *tem = p->next; +// p->next = pool->freeBlocks; +// pool->freeBlocks = p; +// p = tem; +// } +// } +// pool->blocks = NULL; +// pool->start = NULL; +// pool->ptr = NULL; +// pool->end = NULL; +// } + +// static void FASTCALL +// poolDestroy(STRING_POOL *pool) { +// BLOCK *p = pool->blocks; +// while (p) { +// BLOCK *tem = p->next; +// pool->mem->free_fcn(p); +// p = tem; +// } +// p = pool->freeBlocks; +// while (p) { +// BLOCK *tem = p->next; +// pool->mem->free_fcn(p); +// p = tem; +// } +// } + +// static XML_Char * +// poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, +// const char *end) { +// if (! pool->ptr && ! poolGrow(pool)) +// return NULL; +// for (;;) { +// const enum XML_Convert_Result convert_res = XmlConvert( +// enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); +// if ((convert_res == XML_CONVERT_COMPLETED) +// || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) +// break; +// if (! poolGrow(pool)) +// return NULL; +// } +// return pool->start; +// } + +// static const XML_Char *FASTCALL +// poolCopyString(STRING_POOL *pool, const XML_Char *s) { +// do { +// if (! poolAppendChar(pool, *s)) +// return NULL; +// } while (*s++); +// s = pool->start; +// poolFinish(pool); +// return s; +// } + +// static const XML_Char * +// poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { +// if (! pool->ptr && ! poolGrow(pool)) { +// /* The following line is unreachable given the current usage of +// * poolCopyStringN(). Currently it is called from exactly one +// * place to copy the text of a simple general entity. By that +// * point, the name of the entity is already stored in the pool, so +// * pool->ptr cannot be NULL. +// * +// * If poolCopyStringN() is used elsewhere as it well might be, +// * this line may well become executable again. Regardless, this +// * sort of check shouldn't be removed lightly, so we just exclude +// * it from the coverage statistics. +// */ +// return NULL; /* LCOV_EXCL_LINE */ +// } +// for (; n > 0; --n, s++) { +// if (! poolAppendChar(pool, *s)) +// return NULL; +// } +// s = pool->start; +// poolFinish(pool); +// return s; +// } + +// static const XML_Char *FASTCALL +// poolAppendString(STRING_POOL *pool, const XML_Char *s) { +// while (*s) { +// if (! poolAppendChar(pool, *s)) +// return NULL; +// s++; +// } +// return pool->start; +// } + +// static XML_Char * +// poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, +// const char *end) { +// if (! poolAppend(pool, enc, ptr, end)) +// return NULL; +// if (pool->ptr == pool->end && ! poolGrow(pool)) +// return NULL; +// *(pool->ptr)++ = 0; +// return pool->start; +// } + +// static size_t +// poolBytesToAllocateFor(int blockSize) { +// /* Unprotected math would be: +// ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); +// ** +// ** Detect overflow, avoiding _signed_ overflow undefined behavior +// ** For a + b * c we check b * c in isolation first, so that addition of a +// ** on top has no chance of making us accept a small non-negative number +// */ +// const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ + +// if (blockSize <= 0) +// return 0; + +// if (blockSize > (int)(INT_MAX / stretch)) +// return 0; + +// { +// const int stretchedBlockSize = blockSize * (int)stretch; +// const int bytesToAllocate +// = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); +// if (bytesToAllocate < 0) +// return 0; + +// return (size_t)bytesToAllocate; +// } +// } + +// static XML_Bool FASTCALL +// poolGrow(STRING_POOL *pool) { +// if (pool->freeBlocks) { +// if (pool->start == 0) { +// pool->blocks = pool->freeBlocks; +// pool->freeBlocks = pool->freeBlocks->next; +// pool->blocks->next = NULL; +// pool->start = pool->blocks->s; +// pool->end = pool->start + pool->blocks->size; +// pool->ptr = pool->start; +// return XML_TRUE; +// } +// if (pool->end - pool->start < pool->freeBlocks->size) { +// BLOCK *tem = pool->freeBlocks->next; +// pool->freeBlocks->next = pool->blocks; +// pool->blocks = pool->freeBlocks; +// pool->freeBlocks = tem; +// memcpy(pool->blocks->s, pool->start, +// (pool->end - pool->start) * sizeof(XML_Char)); +// pool->ptr = pool->blocks->s + (pool->ptr - pool->start); +// pool->start = pool->blocks->s; +// pool->end = pool->start + pool->blocks->size; +// return XML_TRUE; +// } +// } +// if (pool->blocks && pool->start == pool->blocks->s) { +// BLOCK *temp; +// int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U); +// size_t bytesToAllocate; + +// /* NOTE: Needs to be calculated prior to calling `realloc` +// to avoid dangling pointers: */ +// const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; + +// if (blockSize < 0) { +// /* This condition traps a situation where either more than +// * INT_MAX/2 bytes have already been allocated. This isn't +// * readily testable, since it is unlikely that an average +// * machine will have that much memory, so we exclude it from the +// * coverage statistics. +// */ +// return XML_FALSE; /* LCOV_EXCL_LINE */ +// } + +// bytesToAllocate = poolBytesToAllocateFor(blockSize); +// if (bytesToAllocate == 0) +// return XML_FALSE; + +// temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks, +// (unsigned)bytesToAllocate); +// if (temp == NULL) +// return XML_FALSE; +// pool->blocks = temp; +// pool->blocks->size = blockSize; +// pool->ptr = pool->blocks->s + offsetInsideBlock; +// pool->start = pool->blocks->s; +// pool->end = pool->start + blockSize; +// } else { +// BLOCK *tem; +// int blockSize = (int)(pool->end - pool->start); +// size_t bytesToAllocate; + +// if (blockSize < 0) { +// /* This condition traps a situation where either more than +// * INT_MAX bytes have already been allocated (which is prevented +// * by various pieces of program logic, not least this one, never +// * mind the unlikelihood of actually having that much memory) or +// * the pool control fields have been corrupted (which could +// * conceivably happen in an extremely buggy user handler +// * function). Either way it isn't readily testable, so we +// * exclude it from the coverage statistics. +// */ +// return XML_FALSE; /* LCOV_EXCL_LINE */ +// } + +// if (blockSize < INIT_BLOCK_SIZE) +// blockSize = INIT_BLOCK_SIZE; +// else { +// /* Detect overflow, avoiding _signed_ overflow undefined behavior */ +// if ((int)((unsigned)blockSize * 2U) < 0) { +// return XML_FALSE; +// } +// blockSize *= 2; +// } + +// bytesToAllocate = poolBytesToAllocateFor(blockSize); +// if (bytesToAllocate == 0) +// return XML_FALSE; + +// tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); +// if (! tem) +// return XML_FALSE; +// tem->size = blockSize; +// tem->next = pool->blocks; +// pool->blocks = tem; +// if (pool->ptr != pool->start) +// memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); +// pool->ptr = tem->s + (pool->ptr - pool->start); +// pool->start = tem->s; +// pool->end = tem->s + blockSize; +// } +// return XML_TRUE; +// } + +// static int FASTCALL +// nextScaffoldPart(XML_Parser parser) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// CONTENT_SCAFFOLD *me; +// int next; + +// if (! dtd->scaffIndex) { +// dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); +// if (! dtd->scaffIndex) +// return -1; +// dtd->scaffIndex[0] = 0; +// } + +// if (dtd->scaffCount >= dtd->scaffSize) { +// CONTENT_SCAFFOLD *temp; +// if (dtd->scaffold) { +// temp = (CONTENT_SCAFFOLD *)REALLOC( +// parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); +// if (temp == NULL) +// return -1; +// dtd->scaffSize *= 2; +// } else { +// temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS +// * sizeof(CONTENT_SCAFFOLD)); +// if (temp == NULL) +// return -1; +// dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; +// } +// dtd->scaffold = temp; +// } +// next = dtd->scaffCount++; +// me = &dtd->scaffold[next]; +// if (dtd->scaffLevel) { +// CONTENT_SCAFFOLD *parent +// = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]]; +// if (parent->lastchild) { +// dtd->scaffold[parent->lastchild].nextsib = next; +// } +// if (! parent->childcnt) +// parent->firstchild = next; +// parent->lastchild = next; +// parent->childcnt++; +// } +// me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; +// return next; +// } + +// static void +// build_node(XML_Parser parser, int src_node, XML_Content *dest, +// XML_Content **contpos, XML_Char **strpos) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// dest->type = dtd->scaffold[src_node].type; +// dest->quant = dtd->scaffold[src_node].quant; +// if (dest->type == XML_CTYPE_NAME) { +// const XML_Char *src; +// dest->name = *strpos; +// src = dtd->scaffold[src_node].name; +// for (;;) { +// *(*strpos)++ = *src; +// if (! *src) +// break; +// src++; +// } +// dest->numchildren = 0; +// dest->children = NULL; +// } else { +// unsigned int i; +// int cn; +// dest->numchildren = dtd->scaffold[src_node].childcnt; +// dest->children = *contpos; +// *contpos += dest->numchildren; +// for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren; +// i++, cn = dtd->scaffold[cn].nextsib) { +// build_node(parser, cn, &(dest->children[i]), contpos, strpos); +// } +// dest->name = NULL; +// } +// } + +// static XML_Content * +// build_model(XML_Parser parser) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// XML_Content *ret; +// XML_Content *cpos; +// XML_Char *str; +// int allocsize = (dtd->scaffCount * sizeof(XML_Content) +// + (dtd->contentStringLen * sizeof(XML_Char))); + +// ret = (XML_Content *)MALLOC(parser, allocsize); +// if (! ret) +// return NULL; + +// str = (XML_Char *)(&ret[dtd->scaffCount]); +// cpos = &ret[1]; + +// build_node(parser, 0, ret, &cpos, &str); +// return ret; +// } + +// static ELEMENT_TYPE * +// getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, +// const char *end) { +// DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +// const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); +// ELEMENT_TYPE *ret; + +// if (! name) +// return NULL; +// ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, +// sizeof(ELEMENT_TYPE)); +// if (! ret) +// return NULL; +// if (ret->name != name) +// poolDiscard(&dtd->pool); +// else { +// poolFinish(&dtd->pool); +// if (! setElementTypePrefix(parser, ret)) +// return NULL; +// } +// return ret; +// } + +// static XML_Char * +// copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { +// int charsRequired = 0; +// XML_Char *result; + +// /* First determine how long the string is */ +// while (s[charsRequired] != 0) { +// charsRequired++; +// } +// /* Include the terminator */ +// charsRequired++; + +// /* Now allocate space for the copy */ +// result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); +// if (result == NULL) +// return NULL; +// /* Copy the original into place */ +// memcpy(result, s, charsRequired * sizeof(XML_Char)); +// return result; +// } diff --git a/python/Modules/expat/xmlrole.c b/python/Modules/expat/xmlrole.c new file mode 100755 index 0000000..4d3e3e8 --- /dev/null +++ b/python/Modules/expat/xmlrole.c @@ -0,0 +1,1247 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +#include + +#ifdef _WIN32 +# include "winconfig.h" +#else +# ifdef HAVE_EXPAT_CONFIG_H +# include +# endif +#endif /* ndef _WIN32 */ + +#include "expat_external.h" +#include "internal.h" +#include "xmlrole.h" +#include "ascii.h" + +/* Doesn't check: + + that ,| are not mixed in a model group + content of literals + +*/ + +static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'}; +static const char KW_ATTLIST[] + = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'}; +static const char KW_CDATA[] + = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_DOCTYPE[] + = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'}; +static const char KW_ELEMENT[] + = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'}; +static const char KW_EMPTY[] + = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'}; +static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, + ASCII_I, ASCII_E, ASCII_S, '\0'}; +static const char KW_ENTITY[] + = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; +static const char KW_FIXED[] + = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'}; +static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'}; +static const char KW_IDREF[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; +static const char KW_IDREFS[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; +#ifdef XML_DTD +static const char KW_IGNORE[] + = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'}; +#endif +static const char KW_IMPLIED[] + = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'}; +#ifdef XML_DTD +static const char KW_INCLUDE[] + = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'}; +#endif +static const char KW_NDATA[] + = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_NMTOKEN[] + = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; +static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, + ASCII_E, ASCII_N, ASCII_S, '\0'}; +static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, + ASCII_I, ASCII_O, ASCII_N, '\0'}; +static const char KW_PCDATA[] + = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_PUBLIC[] + = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'}; +static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, + ASCII_R, ASCII_E, ASCII_D, '\0'}; +static const char KW_SYSTEM[] + = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'}; + +#ifndef MIN_BYTES_PER_CHAR +# define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) +#endif + +#ifdef XML_DTD +# define setTopLevel(state) \ + ((state)->handler \ + = ((state)->documentEntity ? internalSubset : externalSubset1)) +#else /* not XML_DTD */ +# define setTopLevel(state) ((state)->handler = internalSubset) +#endif /* not XML_DTD */ + +typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok, + const char *ptr, const char *end, + const ENCODING *enc); + +static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2, + doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2, + entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10, + notation0, notation1, notation2, notation3, notation4, attlist0, attlist1, + attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8, + attlist9, element0, element1, element2, element3, element4, element5, + element6, element7, +#ifdef XML_DTD + externalSubset0, externalSubset1, condSect0, condSect1, condSect2, +#endif /* XML_DTD */ + declClose, error; + +static int FASTCALL common(PROLOG_STATE *state, int tok); + +static int PTRCALL +prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + state->handler = prolog1; + return XML_ROLE_NONE; + case XML_TOK_XML_DECL: + state->handler = prolog1; + return XML_ROLE_XML_DECL; + case XML_TOK_PI: + state->handler = prolog1; + return XML_ROLE_PI; + case XML_TOK_COMMENT: + state->handler = prolog1; + return XML_ROLE_COMMENT; + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_BOM: + /* This case can never arise. To reach this role function, the + * parse must have passed through prolog0 and therefore have had + * some form of input, even if only a space. At that point, a + * byte order mark is no longer a valid character (though + * technically it should be interpreted as a non-breaking space), + * so will be rejected by the tokenizing stages. + */ + return XML_ROLE_NONE; /* LCOV_EXCL_LINE */ + case XML_TOK_DECL_OPEN: + if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = doctype1; + return XML_ROLE_DOCTYPE_NAME; + } + return common(state, tok); +} + +static int PTRCALL +doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = doctype3; + return XML_ROLE_DOCTYPE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = doctype2; + return XML_ROLE_DOCTYPE_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype3; + return XML_ROLE_DOCTYPE_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype4; + return XML_ROLE_DOCTYPE_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static int PTRCALL +doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static int PTRCALL +internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_ENTITY)) { + state->handler = entity0; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_ATTLIST)) { + state->handler = attlist0; + return XML_ROLE_ATTLIST_NONE; + } + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_ELEMENT)) { + state->handler = element0; + return XML_ROLE_ELEMENT_NONE; + } + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_NOTATION)) { + state->handler = notation0; + return XML_ROLE_NOTATION_NONE; + } + break; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_PARAM_ENTITY_REF: + return XML_ROLE_PARAM_ENTITY_REF; + case XML_TOK_CLOSE_BRACKET: + state->handler = doctype5; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_NONE: + return XML_ROLE_NONE; + } + return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + state->handler = externalSubset1; + if (tok == XML_TOK_XML_DECL) + return XML_ROLE_TEXT_DECL; + return externalSubset1(state, tok, ptr, end, enc); +} + +static int PTRCALL +externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_COND_SECT_OPEN: + state->handler = condSect0; + return XML_ROLE_NONE; + case XML_TOK_COND_SECT_CLOSE: + if (state->includeLevel == 0) + break; + state->includeLevel -= 1; + return XML_ROLE_NONE; + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_BRACKET: + break; + case XML_TOK_NONE: + if (state->includeLevel) + break; + return XML_ROLE_NONE; + default: + return internalSubset(state, tok, ptr, end, enc); + } + return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_PERCENT: + state->handler = entity1; + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = entity2; + return XML_ROLE_GENERAL_ENTITY_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = entity7; + return XML_ROLE_PARAM_ENTITY_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity4; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity3; + return XML_ROLE_ENTITY_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity4; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity5; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ENTITY_COMPLETE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { + state->handler = entity6; + return XML_ROLE_ENTITY_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_NOTATION_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity9; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity8; + return XML_ROLE_ENTITY_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity9; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity10; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ENTITY_COMPLETE; + } + return common(state, tok); +} + +static int PTRCALL +notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_NAME: + state->handler = notation1; + return XML_ROLE_NOTATION_NAME; + } + return common(state, tok); +} + +static int PTRCALL +notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = notation3; + return XML_ROLE_NOTATION_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = notation2; + return XML_ROLE_NOTATION_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = notation4; + return XML_ROLE_NOTATION_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_NOTATION_NONE; + return XML_ROLE_NOTATION_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_NOTATION_NONE; + return XML_ROLE_NOTATION_SYSTEM_ID; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_NOTATION_NO_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist1; + return XML_ROLE_ATTLIST_ELEMENT_NAME; + } + return common(state, tok); +} + +static int PTRCALL +attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist2; + return XML_ROLE_ATTRIBUTE_NAME; + } + return common(state, tok); +} + +static int PTRCALL +attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: { + static const char *const types[] = { + KW_CDATA, KW_ID, KW_IDREF, KW_IDREFS, + KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS, + }; + int i; + for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++) + if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { + state->handler = attlist8; + return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; + } + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { + state->handler = attlist5; + return XML_ROLE_ATTLIST_NONE; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = attlist3; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NMTOKEN: + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist4; + return XML_ROLE_ATTRIBUTE_ENUM_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OR: + state->handler = attlist3; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OPEN_PAREN: + state->handler = attlist6; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + state->handler = attlist7; + return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OR: + state->handler = attlist6; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +/* default value */ +static int PTRCALL +attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_IMPLIED)) { + state->handler = attlist1; + return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_REQUIRED)) { + state->handler = attlist1; + return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_FIXED)) { + state->handler = attlist9; + return XML_ROLE_ATTLIST_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_FIXED_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element1; + return XML_ROLE_ELEMENT_NAME; + } + return common(state, tok); +} + +static int PTRCALL +element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_CONTENT_EMPTY; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_CONTENT_ANY; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = element2; + state->level = 1; + return XML_ROLE_GROUP_OPEN; + } + return common(state, tok); +} + +static int PTRCALL +element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_PCDATA)) { + state->handler = element3; + return XML_ROLE_CONTENT_PCDATA; + } + break; + case XML_TOK_OPEN_PAREN: + state->level = 2; + state->handler = element6; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static int PTRCALL +element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_ELEMENT_NONE; + } + return common(state, tok); +} + +static int PTRCALL +element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element5; + return XML_ROLE_CONTENT_ELEMENT; + } + return common(state, tok); +} + +static int PTRCALL +element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_ELEMENT_NONE; + } + return common(state, tok); +} + +static int PTRCALL +element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_OPEN_PAREN: + state->level += 1; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static int PTRCALL +element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_CLOSE_PAREN_QUESTION: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_OPT; + case XML_TOK_CLOSE_PAREN_PLUS: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_PLUS; + case XML_TOK_COMMA: + state->handler = element6; + return XML_ROLE_GROUP_SEQUENCE; + case XML_TOK_OR: + state->handler = element6; + return XML_ROLE_GROUP_CHOICE; + } + return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { + state->handler = condSect1; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { + state->handler = condSect2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + state->includeLevel += 1; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static int PTRCALL +condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + return XML_ROLE_IGNORE_SECT; + } + return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return state->role_none; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return state->role_none; + } + return common(state, tok); +} + +/* This function will only be invoked if the internal logic of the + * parser has broken down. It is used in two cases: + * + * 1: When the XML prolog has been finished. At this point the + * processor (the parser level above these role handlers) should + * switch from prologProcessor to contentProcessor and reinitialise + * the handler function. + * + * 2: When an error has been detected (via common() below). At this + * point again the processor should be switched to errorProcessor, + * which will never call a handler. + * + * The result of this is that error() can only be called if the + * processor switch failed to happen, which is an internal error and + * therefore we shouldn't be able to provoke it simply by using the + * library. It is a necessary backstop, however, so we merely exclude + * it from the coverage statistics. + * + * LCOV_EXCL_START + */ +static int PTRCALL +error(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(state); + UNUSED_P(tok); + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + return XML_ROLE_NONE; +} +/* LCOV_EXCL_STOP */ + +static int FASTCALL +common(PROLOG_STATE *state, int tok) { +#ifdef XML_DTD + if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) + return XML_ROLE_INNER_PARAM_ENTITY_REF; +#endif + state->handler = error; + return XML_ROLE_ERROR; +} + +void +XmlPrologStateInit(PROLOG_STATE *state) { + state->handler = prolog0; +#ifdef XML_DTD + state->documentEntity = 1; + state->includeLevel = 0; + state->inEntityValue = 0; +#endif /* XML_DTD */ +} + +#ifdef XML_DTD + +void +XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { + state->handler = externalSubset0; + state->documentEntity = 0; + state->includeLevel = 0; +} + +#endif /* XML_DTD */ diff --git a/python/Modules/expat/xmlrole.h b/python/Modules/expat/xmlrole.h new file mode 100755 index 0000000..036aba6 --- /dev/null +++ b/python/Modules/expat/xmlrole.h @@ -0,0 +1,139 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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 XmlRole_INCLUDED +#define XmlRole_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +# define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt +#endif + +#include "xmltok.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + XML_ROLE_ERROR = -1, + XML_ROLE_NONE = 0, + XML_ROLE_XML_DECL, + XML_ROLE_INSTANCE_START, + XML_ROLE_DOCTYPE_NONE, + XML_ROLE_DOCTYPE_NAME, + XML_ROLE_DOCTYPE_SYSTEM_ID, + XML_ROLE_DOCTYPE_PUBLIC_ID, + XML_ROLE_DOCTYPE_INTERNAL_SUBSET, + XML_ROLE_DOCTYPE_CLOSE, + XML_ROLE_GENERAL_ENTITY_NAME, + XML_ROLE_PARAM_ENTITY_NAME, + XML_ROLE_ENTITY_NONE, + XML_ROLE_ENTITY_VALUE, + XML_ROLE_ENTITY_SYSTEM_ID, + XML_ROLE_ENTITY_PUBLIC_ID, + XML_ROLE_ENTITY_COMPLETE, + XML_ROLE_ENTITY_NOTATION_NAME, + XML_ROLE_NOTATION_NONE, + XML_ROLE_NOTATION_NAME, + XML_ROLE_NOTATION_SYSTEM_ID, + XML_ROLE_NOTATION_NO_SYSTEM_ID, + XML_ROLE_NOTATION_PUBLIC_ID, + XML_ROLE_ATTRIBUTE_NAME, + XML_ROLE_ATTRIBUTE_TYPE_CDATA, + XML_ROLE_ATTRIBUTE_TYPE_ID, + XML_ROLE_ATTRIBUTE_TYPE_IDREF, + XML_ROLE_ATTRIBUTE_TYPE_IDREFS, + XML_ROLE_ATTRIBUTE_TYPE_ENTITY, + XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, + XML_ROLE_ATTRIBUTE_ENUM_VALUE, + XML_ROLE_ATTRIBUTE_NOTATION_VALUE, + XML_ROLE_ATTLIST_NONE, + XML_ROLE_ATTLIST_ELEMENT_NAME, + XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, + XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, + XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, + XML_ROLE_FIXED_ATTRIBUTE_VALUE, + XML_ROLE_ELEMENT_NONE, + XML_ROLE_ELEMENT_NAME, + XML_ROLE_CONTENT_ANY, + XML_ROLE_CONTENT_EMPTY, + XML_ROLE_CONTENT_PCDATA, + XML_ROLE_GROUP_OPEN, + XML_ROLE_GROUP_CLOSE, + XML_ROLE_GROUP_CLOSE_REP, + XML_ROLE_GROUP_CLOSE_OPT, + XML_ROLE_GROUP_CLOSE_PLUS, + XML_ROLE_GROUP_CHOICE, + XML_ROLE_GROUP_SEQUENCE, + XML_ROLE_CONTENT_ELEMENT, + XML_ROLE_CONTENT_ELEMENT_REP, + XML_ROLE_CONTENT_ELEMENT_OPT, + XML_ROLE_CONTENT_ELEMENT_PLUS, + XML_ROLE_PI, + XML_ROLE_COMMENT, +#ifdef XML_DTD + XML_ROLE_TEXT_DECL, + XML_ROLE_IGNORE_SECT, + XML_ROLE_INNER_PARAM_ENTITY_REF, +#endif /* XML_DTD */ + XML_ROLE_PARAM_ENTITY_REF +}; + +typedef struct prolog_state { + int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr, + const char *end, const ENCODING *enc); + unsigned level; + int role_none; +#ifdef XML_DTD + unsigned includeLevel; + int documentEntity; + int inEntityValue; +#endif /* XML_DTD */ +} PROLOG_STATE; + +void XmlPrologStateInit(PROLOG_STATE *); +#ifdef XML_DTD +void XmlPrologStateInitExternalEntity(PROLOG_STATE *); +#endif /* XML_DTD */ + +#define XmlTokenRole(state, tok, ptr, end, enc) \ + (((state)->handler)(state, tok, ptr, end, enc)) + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlRole_INCLUDED */ diff --git a/python/Modules/expat/xmltok.c b/python/Modules/expat/xmltok.c new file mode 100755 index 0000000..7e2ed10 --- /dev/null +++ b/python/Modules/expat/xmltok.c @@ -0,0 +1,1672 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +#ifdef _WIN32 +# include "winconfig.h" +#else +# ifdef HAVE_EXPAT_CONFIG_H +# include +# endif +#endif /* ndef _WIN32 */ + +#include +#include /* memcpy */ + +#if defined(_MSC_VER) && (_MSC_VER <= 1700) +/* for vs2012/11.0/1700 and earlier Visual Studio compilers */ +# define bool int +# define false 0 +# define true 1 +#else +# include +#endif + +#include "expat_external.h" +#include "internal.h" +#include "xmltok.h" +#include "nametab.h" + +#ifdef XML_DTD +# define IGNORE_SECTION_TOK_VTABLE , PREFIX_CC(ignoreSectionTok) +#else +# define IGNORE_SECTION_TOK_VTABLE /* as nothing */ +#endif + +#define VTABLE1 \ + {PREFIX_CC(prologTok), PREFIX_CC(contentTok), \ + PREFIX_CC(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE}, \ + {PREFIX_CC(attributeValueTok), PREFIX_CC(entityValueTok)}, \ + PREFIX_CC(nameMatchesAscii), PREFIX_CC(nameLength), PREFIX_CC(skipS), \ + PREFIX_CC(getAtts), PREFIX_CC(charRefNumber), PREFIX_CC(predefinedEntityName), \ + PREFIX_CC(updatePosition), PREFIX_CC(isPublicId) + +#define VTABLE VTABLE1, PREFIX_CC(toUtf8), PREFIX_CC(toUtf16) + +#define UCS2_GET_NAMING(pages, hi, lo) \ + (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo)&0x1F))) + +/* A 2 byte UTF-8 representation splits the characters 11 bits between + the bottom 5 and 6 bits of the bytes. We need 8 bits to index into + pages, 3 bits to add to that index and 5 bits to generate the mask. +*/ +#define UTF8_GET_NAMING2(pages, byte) \ + (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)] \ + & (1u << (((byte)[1]) & 0x1F))) + +/* A 3 byte UTF-8 representation splits the characters 16 bits between + the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index + into pages, 3 bits to add to that index and 5 bits to generate the + mask. +*/ +#define UTF8_GET_NAMING3(pages, byte) \ + (namingBitmap \ + [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)] \ + << 3) \ + + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ + & (1u << (((byte)[2]) & 0x1F))) + +#define UTF8_GET_NAMING(pages, p, n) \ + ((n) == 2 \ + ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ + : ((n) == 3 ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) : 0)) + +/* Detection of invalid UTF-8 sequences is based on Table 3.1B + of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ + with the additional restriction of not allowing the Unicode + code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). + Implementation details: + (A & 0x80) == 0 means A < 0x80 + and + (A & 0xC0) == 0xC0 means A > 0xBF +*/ + +#define UTF8_INVALID2(p) \ + ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) + +#define UTF8_INVALID3(p) \ + (((p)[2] & 0x80) == 0 \ + || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \ + : ((p)[2] & 0xC0) == 0xC0) \ + || ((*p) == 0xE0 \ + ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ + : ((p)[1] & 0x80) == 0 \ + || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) + +#define UTF8_INVALID4(p) \ + (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0 \ + || ((p)[2] & 0xC0) == 0xC0 \ + || ((*p) == 0xF0 \ + ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ + : ((p)[1] & 0x80) == 0 \ + || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) + +static int PTRFASTCALL +isNever(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + UNUSED_P(p); + return 0; +} + +static int PTRFASTCALL +utf8_isName2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isName3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); +} + +#define utf8_isName4 isNever + +static int PTRFASTCALL +utf8_isNmstrt2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isNmstrt3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); +} + +#define utf8_isNmstrt4 isNever + +static int PTRFASTCALL +utf8_isInvalid2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_INVALID2((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_INVALID3((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid4(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_INVALID4((const unsigned char *)p); +} + +struct normal_encoding { + ENCODING enc; + unsigned char type[256]; +#ifdef XML_MIN_SIZE + int(PTRFASTCALL *byteType)(const ENCODING *, const char *); + int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); + int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); + int(PTRCALL *charMatches)(const ENCODING *, const char *, int); +#endif /* XML_MIN_SIZE */ + int(PTRFASTCALL *isName2)(const ENCODING *, const char *); + int(PTRFASTCALL *isName3)(const ENCODING *, const char *); + int(PTRFASTCALL *isName4)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); +}; + +#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc)) + +#ifdef XML_MIN_SIZE + +# define STANDARD_VTABLE(E) \ + E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches, + +#else + +# define STANDARD_VTABLE(E) /* as nothing */ + +#endif + +#define NORMAL_VTABLE(E) \ + E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \ + E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4 + +#define NULL_VTABLE \ + /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ + /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ + /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL + +static int FASTCALL checkCharRefNumber(int); + +#include "xmltok_impl.h" +#include "ascii.h" + +#ifdef XML_MIN_SIZE +# define sb_isNameMin isNever +# define sb_isNmstrtMin isNever +#endif + +#ifdef XML_MIN_SIZE +# define MINBPC(enc) ((enc)->minBytesPerChar) +#else +/* minimum bytes per character */ +# define MINBPC(enc) 1 +#endif + +#define SB_BYTE_TYPE(enc, p) \ + (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) + +#ifdef XML_MIN_SIZE +static int PTRFASTCALL +sb_byteType(const ENCODING *enc, const char *p) { + return SB_BYTE_TYPE(enc, p); +} +# define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) +#else +# define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) +#endif + +#ifdef XML_MIN_SIZE +# define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) +static int PTRFASTCALL +sb_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return *p; +} +#else +# define BYTE_TO_ASCII(enc, p) (*(p)) +#endif + +#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) +#define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) +#define IS_INVALID_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) + +#ifdef XML_MIN_SIZE +# define IS_NAME_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) +#else +# define IS_NAME_CHAR_MINBPC(enc, p) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) +#endif + +#ifdef XML_MIN_SIZE +# define CHAR_MATCHES(enc, p, c) \ + (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) +static int PTRCALL +sb_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return *p == c; +} +#else +/* c is an ASCII character */ +# define CHAR_MATCHES(enc, p, c) (*(p) == c) +#endif + +#define PREFIX_CC(ident) normal_##ident +#define XML_TOK_IMPL_C +#include "xmltok_impl.c" +#undef XML_TOK_IMPL_C + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ + UTF8_cval1 = 0x00, + UTF8_cval2 = 0xc0, + UTF8_cval3 = 0xe0, + UTF8_cval4 = 0xf0 +}; + +void +_INTERNAL_trim_to_complete_utf8_characters(const char *from, + const char **fromLimRef) { + const char *fromLim = *fromLimRef; + size_t walked = 0; + for (; fromLim > from; fromLim--, walked++) { + const unsigned char prev = (unsigned char)fromLim[-1]; + if ((prev & 0xf8u) + == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ + if (walked + 1 >= 4) { + fromLim += 4 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0xf0u) + == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ + if (walked + 1 >= 3) { + fromLim += 3 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0xe0u) + == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ + if (walked + 1 >= 2) { + fromLim += 2 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0x80u) + == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ + break; + } + } + *fromLimRef = fromLim; +} + +static enum XML_Convert_Result PTRCALL +utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + bool input_incomplete = false; + bool output_exhausted = false; + + /* Avoid copying partial characters (due to limited space). */ + const ptrdiff_t bytesAvailable = fromLim - *fromP; + const ptrdiff_t bytesStorable = toLim - *toP; + UNUSED_P(enc); + if (bytesAvailable > bytesStorable) { + fromLim = *fromP + bytesStorable; + output_exhausted = true; + } + + /* Avoid copying partial characters (from incomplete input). */ + { + const char *const fromLimBefore = fromLim; + _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); + if (fromLim < fromLimBefore) { + input_incomplete = true; + } + } + + { + const ptrdiff_t bytesToCopy = fromLim - *fromP; + memcpy(*toP, *fromP, bytesToCopy); + *fromP += bytesToCopy; + *toP += bytesToCopy; + } + + if (output_exhausted) /* needs to go first */ + return XML_CONVERT_OUTPUT_EXHAUSTED; + else if (input_incomplete) + return XML_CONVERT_INPUT_INCOMPLETE; + else + return XML_CONVERT_COMPLETED; +} + +static enum XML_Convert_Result PTRCALL +utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; + unsigned short *to = *toP; + const char *from = *fromP; + while (from < fromLim && to < toLim) { + switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { + case BT_LEAD2: + if (fromLim - from < 2) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } + *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); + from += 2; + break; + case BT_LEAD3: + if (fromLim - from < 3) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } + *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) + | (from[2] & 0x3f)); + from += 3; + break; + case BT_LEAD4: { + unsigned long n; + if (toLim - to < 2) { + res = XML_CONVERT_OUTPUT_EXHAUSTED; + goto after; + } + if (fromLim - from < 4) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } + n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) + | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); + n -= 0x10000; + to[0] = (unsigned short)((n >> 10) | 0xD800); + to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); + to += 2; + from += 4; + } break; + default: + *to++ = *from++; + break; + } + } + if (from < fromLim) + res = XML_CONVERT_OUTPUT_EXHAUSTED; +after: + *fromP = from; + *toP = to; + return res; +} + +#ifdef XML_NS +static const struct normal_encoding utf8_encoding_ns + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +# include "asciitab.h" +# include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; +#endif + +static const struct normal_encoding utf8_encoding + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; + +#ifdef XML_NS + +static const struct normal_encoding internal_utf8_encoding_ns + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +# include "iasciitab.h" +# include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; + +#endif + +static const struct normal_encoding internal_utf8_encoding + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; + +static enum XML_Convert_Result PTRCALL +latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + UNUSED_P(enc); + for (;;) { + unsigned char c; + if (*fromP == fromLim) + return XML_CONVERT_COMPLETED; + c = (unsigned char)**fromP; + if (c & 0x80) { + if (toLim - *toP < 2) + return XML_CONVERT_OUTPUT_EXHAUSTED; + *(*toP)++ = (char)((c >> 6) | UTF8_cval2); + *(*toP)++ = (char)((c & 0x3f) | 0x80); + (*fromP)++; + } else { + if (*toP == toLim) + return XML_CONVERT_OUTPUT_EXHAUSTED; + *(*toP)++ = *(*fromP)++; + } + } +} + +static enum XML_Convert_Result PTRCALL +latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { + UNUSED_P(enc); + while (*fromP < fromLim && *toP < toLim) + *(*toP)++ = (unsigned char)*(*fromP)++; + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; +} + +#ifdef XML_NS + +static const struct normal_encoding latin1_encoding_ns + = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding latin1_encoding + = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +static enum XML_Convert_Result PTRCALL +ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + UNUSED_P(enc); + while (*fromP < fromLim && *toP < toLim) + *(*toP)++ = *(*fromP)++; + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; +} + +#ifdef XML_NS + +static const struct normal_encoding ascii_encoding_ns + = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, + { +# include "asciitab.h" + /* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding ascii_encoding + = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON + /* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +static int PTRFASTCALL +unicode_byte_type(char hi, char lo) { + switch ((unsigned char)hi) { + /* 0xD800–0xDBFF first 16-bit code unit or high surrogate (W1) */ + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + return BT_LEAD4; + /* 0xDC00–0xDFFF second 16-bit code unit or low surrogate (W2) */ + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + return BT_TRAIL; + case 0xFF: + switch ((unsigned char)lo) { + case 0xFF: /* noncharacter-FFFF */ + case 0xFE: /* noncharacter-FFFE */ + return BT_NONXML; + } + break; + } + return BT_NONASCII; +} + +#define DEFINE_UTF16_TO_UTF8(E) \ + static enum XML_Convert_Result PTRCALL E##toUtf8( \ + const ENCODING *enc, const char **fromP, const char *fromLim, \ + char **toP, const char *toLim) { \ + const char *from = *fromP; \ + UNUSED_P(enc); \ + fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ + for (; from < fromLim; from += 2) { \ + int plane; \ + unsigned char lo2; \ + unsigned char lo = GET_LO(from); \ + unsigned char hi = GET_HI(from); \ + switch (hi) { \ + case 0: \ + if (lo < 0x80) { \ + if (*toP == toLim) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + *(*toP)++ = lo; \ + break; \ + } \ + /* fall through */ \ + case 0x1: \ + case 0x2: \ + case 0x3: \ + case 0x4: \ + case 0x5: \ + case 0x6: \ + case 0x7: \ + if (toLim - *toP < 2) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + default: \ + if (toLim - *toP < 3) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ + *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ + *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + case 0xD8: \ + case 0xD9: \ + case 0xDA: \ + case 0xDB: \ + if (toLim - *toP < 4) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + if (fromLim - from < 4) { \ + *fromP = from; \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + } \ + plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ + *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \ + *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ + from += 2; \ + lo2 = GET_LO(from); \ + *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \ + | (lo2 >> 6) | 0x80); \ + *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ + break; \ + } \ + } \ + *fromP = from; \ + if (from < fromLim) \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + else \ + return XML_CONVERT_COMPLETED; \ + } + +#define DEFINE_UTF16_TO_UTF16(E) \ + static enum XML_Convert_Result PTRCALL E##toUtf16( \ + const ENCODING *enc, const char **fromP, const char *fromLim, \ + unsigned short **toP, const unsigned short *toLim) { \ + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ + UNUSED_P(enc); \ + fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ + /* Avoid copying first half only of surrogate */ \ + if (fromLim - *fromP > ((toLim - *toP) << 1) \ + && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ + fromLim -= 2; \ + res = XML_CONVERT_INPUT_INCOMPLETE; \ + } \ + for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ + *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ + if ((*toP == toLim) && (*fromP < fromLim)) \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + else \ + return res; \ + } + +#define SET2(ptr, ch) (((ptr)[0] = ((ch)&0xff)), ((ptr)[1] = ((ch) >> 8))) +#define GET_LO(ptr) ((unsigned char)(ptr)[0]) +#define GET_HI(ptr) ((unsigned char)(ptr)[1]) + +DEFINE_UTF16_TO_UTF8(little2_) +DEFINE_UTF16_TO_UTF16(little2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define SET2(ptr, ch) (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch)&0xFF))) +#define GET_LO(ptr) ((unsigned char)(ptr)[1]) +#define GET_HI(ptr) ((unsigned char)(ptr)[0]) + +DEFINE_UTF16_TO_UTF8(big2_) +DEFINE_UTF16_TO_UTF16(big2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define LITTLE2_BYTE_TYPE(enc, p) \ + ((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ + : unicode_byte_type((p)[1], (p)[0])) +#define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) +#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == c) +#define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) +#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +little2_byteType(const ENCODING *enc, const char *p) { + return LITTLE2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +little2_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_BYTE_TO_ASCII(p); +} + +static int PTRCALL +little2_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return LITTLE2_CHAR_MATCHES(p, c); +} + +static int PTRFASTCALL +little2_isNameMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_IS_NAME_CHAR_MINBPC(p); +} + +static int PTRFASTCALL +little2_isNmstrtMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p); +} + +# undef VTABLE +# define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +# undef PREFIX_CC +# define PREFIX_CC(ident) little2_##ident +# define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +# define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) +# define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p) +# define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c) +# define IS_NAME_CHAR(enc, p, n) 0 +# define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p) +# define IS_NMSTRT_CHAR(enc, p, n) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) + +# define XML_TOK_IMPL_C +# include "xmltok_impl.c" +# undef XML_TOK_IMPL_C + +# undef MINBPC +# undef BYTE_TYPE +# undef BYTE_TO_ASCII +# undef CHAR_MATCHES +# undef IS_NAME_CHAR +# undef IS_NAME_CHAR_MINBPC +# undef IS_NMSTRT_CHAR +# undef IS_NMSTRT_CHAR_MINBPC +# undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding little2_encoding_ns + = {{VTABLE, 2, 0, +# if BYTEORDER == 1234 + 1 +# else + 0 +# endif + }, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding little2_encoding + = {{VTABLE, 2, 0, +#if BYTEORDER == 1234 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +#if BYTEORDER != 4321 + +# ifdef XML_NS + +static const struct normal_encoding internal_little2_encoding_ns + = {{VTABLE, 2, 0, 1}, + { +# include "iasciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +# endif + +static const struct normal_encoding internal_little2_encoding + = {{VTABLE, 2, 0, 1}, + { +# define BT_COLON BT_NMSTRT +# include "iasciitab.h" +# undef BT_COLON +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +#endif + +#define BIG2_BYTE_TYPE(enc, p) \ + ((p)[0] == 0 \ + ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ + : unicode_byte_type((p)[0], (p)[1])) +#define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) +#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == c) +#define BIG2_IS_NAME_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) +#define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +big2_byteType(const ENCODING *enc, const char *p) { + return BIG2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +big2_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_BYTE_TO_ASCII(p); +} + +static int PTRCALL +big2_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return BIG2_CHAR_MATCHES(p, c); +} + +static int PTRFASTCALL +big2_isNameMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_IS_NAME_CHAR_MINBPC(p); +} + +static int PTRFASTCALL +big2_isNmstrtMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_IS_NMSTRT_CHAR_MINBPC(p); +} + +# undef VTABLE +# define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +# undef PREFIX_CC +# define PREFIX_CC(ident) big2_##ident +# define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +# define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) +# define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p) +# define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c) +# define IS_NAME_CHAR(enc, p, n) 0 +# define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p) +# define IS_NMSTRT_CHAR(enc, p, n) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p) + +# define XML_TOK_IMPL_C +# include "xmltok_impl.c" +# undef XML_TOK_IMPL_C + +# undef MINBPC +# undef BYTE_TYPE +# undef BYTE_TO_ASCII +# undef CHAR_MATCHES +# undef IS_NAME_CHAR +# undef IS_NAME_CHAR_MINBPC +# undef IS_NMSTRT_CHAR +# undef IS_NMSTRT_CHAR_MINBPC +# undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding big2_encoding_ns + = {{VTABLE, 2, 0, +# if BYTEORDER == 4321 + 1 +# else + 0 +# endif + }, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding big2_encoding + = {{VTABLE, 2, 0, +#if BYTEORDER == 4321 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +#if BYTEORDER != 1234 + +# ifdef XML_NS + +static const struct normal_encoding internal_big2_encoding_ns + = {{VTABLE, 2, 0, 1}, + { +# include "iasciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +# endif + +static const struct normal_encoding internal_big2_encoding + = {{VTABLE, 2, 0, 1}, + { +# define BT_COLON BT_NMSTRT +# include "iasciitab.h" +# undef BT_COLON +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +#endif + +#undef PREFIX_CC + +static int FASTCALL +streqci(const char *s1, const char *s2) { + for (;;) { + char c1 = *s1++; + char c2 = *s2++; + if (ASCII_a <= c1 && c1 <= ASCII_z) + c1 += ASCII_A - ASCII_a; + if (ASCII_a <= c2 && c2 <= ASCII_z) + /* The following line will never get executed. streqci() is + * only called from two places, both of which guarantee to put + * upper-case strings into s2. + */ + c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ + if (c1 != c2) + return 0; + if (! c1) + break; + } + return 1; +} + +static void PTRCALL +initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, + POSITION *pos) { + UNUSED_P(enc); + normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); +} + +static int +toAscii(const ENCODING *enc, const char *ptr, const char *end) { + char buf[1]; + char *p = buf; + XmlUtf8Convert(enc, &ptr, end, &p, p + 1); + if (p == buf) + return -1; + else + return buf[0]; +} + +static int FASTCALL +isSpace(int c) { + switch (c) { + case 0x20: + case 0xD: + case 0xA: + case 0x9: + return 1; + } + return 0; +} + +/* Return 1 if there's just optional white space or there's an S + followed by name=val. +*/ +static int +parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, + const char **namePtr, const char **nameEndPtr, + const char **valPtr, const char **nextTokPtr) { + int c; + char open; + if (ptr == end) { + *namePtr = NULL; + return 1; + } + if (! isSpace(toAscii(enc, ptr, end))) { + *nextTokPtr = ptr; + return 0; + } + do { + ptr += enc->minBytesPerChar; + } while (isSpace(toAscii(enc, ptr, end))); + if (ptr == end) { + *namePtr = NULL; + return 1; + } + *namePtr = ptr; + for (;;) { + c = toAscii(enc, ptr, end); + if (c == -1) { + *nextTokPtr = ptr; + return 0; + } + if (c == ASCII_EQUALS) { + *nameEndPtr = ptr; + break; + } + if (isSpace(c)) { + *nameEndPtr = ptr; + do { + ptr += enc->minBytesPerChar; + } while (isSpace(c = toAscii(enc, ptr, end))); + if (c != ASCII_EQUALS) { + *nextTokPtr = ptr; + return 0; + } + break; + } + ptr += enc->minBytesPerChar; + } + if (ptr == *namePtr) { + *nextTokPtr = ptr; + return 0; + } + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + while (isSpace(c)) { + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + } + if (c != ASCII_QUOT && c != ASCII_APOS) { + *nextTokPtr = ptr; + return 0; + } + open = (char)c; + ptr += enc->minBytesPerChar; + *valPtr = ptr; + for (;; ptr += enc->minBytesPerChar) { + c = toAscii(enc, ptr, end); + if (c == open) + break; + if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z) + && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD + && c != ASCII_MINUS && c != ASCII_UNDERSCORE) { + *nextTokPtr = ptr; + return 0; + } + } + *nextTokPtr = ptr + enc->minBytesPerChar; + return 1; +} + +static const char KW_version[] + = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'}; + +static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, + ASCII_i, ASCII_n, ASCII_g, '\0'}; + +static const char KW_standalone[] + = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, + ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'}; + +static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'}; + +static const char KW_no[] = {ASCII_n, ASCII_o, '\0'}; + +static int +doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, + const char *), + int isGeneralTextEntity, const ENCODING *enc, const char *ptr, + const char *end, const char **badPtr, const char **versionPtr, + const char **versionEndPtr, const char **encodingName, + const ENCODING **encoding, int *standalone) { + const char *val = NULL; + const char *name = NULL; + const char *nameEnd = NULL; + ptr += 5 * enc->minBytesPerChar; + end -= 2 * enc->minBytesPerChar; + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) + || ! name) { + *badPtr = ptr; + return 0; + } + if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { + if (! isGeneralTextEntity) { + *badPtr = name; + return 0; + } + } else { + if (versionPtr) + *versionPtr = val; + if (versionEndPtr) + *versionEndPtr = ptr; + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (! name) { + if (isGeneralTextEntity) { + /* a TextDecl must have an EncodingDecl */ + *badPtr = ptr; + return 0; + } + return 1; + } + } + if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { + int c = toAscii(enc, val, end); + if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) { + *badPtr = val; + return 0; + } + if (encodingName) + *encodingName = val; + if (encoding) + *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (! name) + return 1; + } + if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) + || isGeneralTextEntity) { + *badPtr = name; + return 0; + } + if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { + if (standalone) + *standalone = 1; + } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { + if (standalone) + *standalone = 0; + } else { + *badPtr = val; + return 0; + } + while (isSpace(toAscii(enc, ptr, end))) + ptr += enc->minBytesPerChar; + if (ptr != end) { + *badPtr = ptr; + return 0; + } + return 1; +} + +static int FASTCALL +checkCharRefNumber(int result) { + switch (result >> 8) { + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + return -1; + case 0: + if (latin1_encoding.type[result] == BT_NONXML) + return -1; + break; + case 0xFF: + if (result == 0xFFFE || result == 0xFFFF) + return -1; + break; + } + return result; +} + +int FASTCALL +XmlUtf8Encode(int c, char *buf) { + enum { + /* minN is minimum legal resulting value for N byte sequence */ + min2 = 0x80, + min3 = 0x800, + min4 = 0x10000 + }; + + if (c < 0) + return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ + if (c < min2) { + buf[0] = (char)(c | UTF8_cval1); + return 1; + } + if (c < min3) { + buf[0] = (char)((c >> 6) | UTF8_cval2); + buf[1] = (char)((c & 0x3f) | 0x80); + return 2; + } + if (c < min4) { + buf[0] = (char)((c >> 12) | UTF8_cval3); + buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); + buf[2] = (char)((c & 0x3f) | 0x80); + return 3; + } + if (c < 0x110000) { + buf[0] = (char)((c >> 18) | UTF8_cval4); + buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); + buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); + buf[3] = (char)((c & 0x3f) | 0x80); + return 4; + } + return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ +} + +int FASTCALL +XmlUtf16Encode(int charNum, unsigned short *buf) { + if (charNum < 0) + return 0; + if (charNum < 0x10000) { + buf[0] = (unsigned short)charNum; + return 1; + } + if (charNum < 0x110000) { + charNum -= 0x10000; + buf[0] = (unsigned short)((charNum >> 10) + 0xD800); + buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); + return 2; + } + return 0; +} + +struct unknown_encoding { + struct normal_encoding normal; + CONVERTER convert; + void *userData; + unsigned short utf16[256]; + char utf8[256][4]; +}; + +#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc)) + +int +XmlSizeOfUnknownEncoding(void) { + return sizeof(struct unknown_encoding); +} + +static int PTRFASTCALL +unknown_isName(const ENCODING *enc, const char *p) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isNmstrt(const ENCODING *enc, const char *p) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isInvalid(const ENCODING *enc, const char *p) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; +} + +static enum XML_Convert_Result PTRCALL +unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + char buf[XML_UTF8_ENCODE_MAX]; + for (;;) { + const char *utf8; + int n; + if (*fromP == fromLim) + return XML_CONVERT_COMPLETED; + utf8 = uenc->utf8[(unsigned char)**fromP]; + n = *utf8++; + if (n == 0) { + int c = uenc->convert(uenc->userData, *fromP); + n = XmlUtf8Encode(c, buf); + if (n > toLim - *toP) + return XML_CONVERT_OUTPUT_EXHAUSTED; + utf8 = buf; + *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2)); + } else { + if (n > toLim - *toP) + return XML_CONVERT_OUTPUT_EXHAUSTED; + (*fromP)++; + } + memcpy(*toP, utf8, n); + *toP += n; + } +} + +static enum XML_Convert_Result PTRCALL +unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + while (*fromP < fromLim && *toP < toLim) { + unsigned short c = uenc->utf16[(unsigned char)**fromP]; + if (c == 0) { + c = (unsigned short)uenc->convert(uenc->userData, *fromP); + *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2)); + } else + (*fromP)++; + *(*toP)++ = c; + } + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; +} + +ENCODING * +XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, + void *userData) { + int i; + struct unknown_encoding *e = (struct unknown_encoding *)mem; + memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding)); + for (i = 0; i < 128; i++) + if (latin1_encoding.type[i] != BT_OTHER + && latin1_encoding.type[i] != BT_NONXML && table[i] != i) + return 0; + for (i = 0; i < 256; i++) { + int c = table[i]; + if (c == -1) { + e->normal.type[i] = BT_MALFORM; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } else if (c < 0) { + if (c < -4) + return 0; + /* Multi-byte sequences need a converter function */ + if (! convert) + return 0; + e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); + e->utf8[i][0] = 0; + e->utf16[i] = 0; + } else if (c < 0x80) { + if (latin1_encoding.type[c] != BT_OTHER + && latin1_encoding.type[c] != BT_NONXML && c != i) + return 0; + e->normal.type[i] = latin1_encoding.type[c]; + e->utf8[i][0] = 1; + e->utf8[i][1] = (char)c; + e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); + } else if (checkCharRefNumber(c) < 0) { + e->normal.type[i] = BT_NONXML; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } else { + if (c > 0xFFFF) + return 0; + if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NMSTRT; + else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NAME; + else + e->normal.type[i] = BT_OTHER; + e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); + e->utf16[i] = (unsigned short)c; + } + } + e->userData = userData; + e->convert = convert; + if (convert) { + e->normal.isName2 = unknown_isName; + e->normal.isName3 = unknown_isName; + e->normal.isName4 = unknown_isName; + e->normal.isNmstrt2 = unknown_isNmstrt; + e->normal.isNmstrt3 = unknown_isNmstrt; + e->normal.isNmstrt4 = unknown_isNmstrt; + e->normal.isInvalid2 = unknown_isInvalid; + e->normal.isInvalid3 = unknown_isInvalid; + e->normal.isInvalid4 = unknown_isInvalid; + } + e->normal.enc.utf8Convert = unknown_toUtf8; + e->normal.enc.utf16Convert = unknown_toUtf16; + return &(e->normal.enc); +} + +/* If this enumeration is changed, getEncodingIndex and encodings +must also be changed. */ +enum { + UNKNOWN_ENC = -1, + ISO_8859_1_ENC = 0, + US_ASCII_ENC, + UTF_8_ENC, + UTF_16_ENC, + UTF_16BE_ENC, + UTF_16LE_ENC, + /* must match encodingNames up to here */ + NO_ENC +}; + +static const char KW_ISO_8859_1[] + = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, + ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'}; +static const char KW_US_ASCII[] + = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, + ASCII_C, ASCII_I, ASCII_I, '\0'}; +static const char KW_UTF_8[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'}; +static const char KW_UTF_16[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'}; +static const char KW_UTF_16BE[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, + ASCII_6, ASCII_B, ASCII_E, '\0'}; +static const char KW_UTF_16LE[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, + ASCII_6, ASCII_L, ASCII_E, '\0'}; + +static int FASTCALL +getEncodingIndex(const char *name) { + static const char *const encodingNames[] = { + KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE, + }; + int i; + if (name == NULL) + return NO_ENC; + for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++) + if (streqci(name, encodingNames[i])) + return i; + return UNKNOWN_ENC; +} + +/* For binary compatibility, we store the index of the encoding + specified at initialization in the isUtf16 member. +*/ + +#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) +#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) + +/* This is what detects the encoding. encodingTable maps from + encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of + the external (protocol) specified encoding; state is + XML_CONTENT_STATE if we're parsing an external text entity, and + XML_PROLOG_STATE otherwise. +*/ + +static int +initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc, + int state, const char *ptr, const char *end, const char **nextTokPtr) { + const ENCODING **encPtr; + + if (ptr >= end) + return XML_TOK_NONE; + encPtr = enc->encPtr; + if (ptr + 1 == end) { + /* only a single byte available for auto-detection */ +#ifndef XML_DTD /* FIXME */ + /* a well-formed document entity must have more than one byte */ + if (state != XML_CONTENT_STATE) + return XML_TOK_PARTIAL; +#endif + /* so we're parsing an external text entity... */ + /* if UTF-16 was externally specified, then we need at least 2 bytes */ + switch (INIT_ENC_INDEX(enc)) { + case UTF_16_ENC: + case UTF_16LE_ENC: + case UTF_16BE_ENC: + return XML_TOK_PARTIAL; + } + switch ((unsigned char)*ptr) { + case 0xFE: + case 0xFF: + case 0xEF: /* possibly first byte of UTF-8 BOM */ + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) + break; + /* fall through */ + case 0x00: + case 0x3C: + return XML_TOK_PARTIAL; + } + } else { + switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { + case 0xFEFF: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XML_TOK_BOM; + /* 00 3C is handled in the default case */ + case 0x3C00: + if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC + || INIT_ENC_INDEX(enc) == UTF_16_ENC) + && state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + case 0xFFFE: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XML_TOK_BOM; + case 0xEFBB: + /* Maybe a UTF-8 BOM (EF BB BF) */ + /* If there's an explicitly specified (external) encoding + of ISO-8859-1 or some flavour of UTF-16 + and this is an external text entity, + don't look for the BOM, + because it might be a legal data. + */ + if (state == XML_CONTENT_STATE) { + int e = INIT_ENC_INDEX(enc); + if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC + || e == UTF_16_ENC) + break; + } + if (ptr + 2 == end) + return XML_TOK_PARTIAL; + if ((unsigned char)ptr[2] == 0xBF) { + *nextTokPtr = ptr + 3; + *encPtr = encodingTable[UTF_8_ENC]; + return XML_TOK_BOM; + } + break; + default: + if (ptr[0] == '\0') { + /* 0 isn't a legal data character. Furthermore a document + entity can only start with ASCII characters. So the only + way this can fail to be big-endian UTF-16 if it it's an + external parsed general entity that's labelled as + UTF-16LE. + */ + if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) + break; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } else if (ptr[1] == '\0') { + /* We could recover here in the case: + - parsing an external entity + - second byte is 0 + - no externally specified encoding + - no encoding declaration + by assuming UTF-16LE. But we don't, because this would mean when + presented just with a single byte, we couldn't reliably determine + whether we needed further bytes. + */ + if (state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } + break; + } + } + *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +} + +#define NS(x) x +#define ns(x) x +#define XML_TOK_NS_C +#include "xmltok_ns.c" +#undef XML_TOK_NS_C +#undef NS +#undef ns + +#ifdef XML_NS + +# define NS(x) x##NS +# define ns(x) x##_ns + +# define XML_TOK_NS_C +# include "xmltok_ns.c" +# undef XML_TOK_NS_C + +# undef NS +# undef ns + +ENCODING * +XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, + void *userData) { + ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); + if (enc) + ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; + return enc; +} + +#endif /* XML_NS */ diff --git a/python/Modules/expat/xmltok.h b/python/Modules/expat/xmltok.h new file mode 100755 index 0000000..2adbf53 --- /dev/null +++ b/python/Modules/expat/xmltok.h @@ -0,0 +1,315 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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 XmlTok_INCLUDED +#define XmlTok_INCLUDED 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following token may be returned by XmlContentTok */ +#define XML_TOK_TRAILING_RSQB \ + -5 /* ] or ]] at the end of the scan; might be \ + start of illegal ]]> sequence */ +/* The following tokens may be returned by both XmlPrologTok and + XmlContentTok. +*/ +#define XML_TOK_NONE -4 /* The string to be scanned is empty */ +#define XML_TOK_TRAILING_CR \ + -3 /* A CR at the end of the scan; \ + might be part of CRLF sequence */ +#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ +#define XML_TOK_PARTIAL -1 /* only part of a token */ +#define XML_TOK_INVALID 0 + +/* The following tokens are returned by XmlContentTok; some are also + returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. +*/ +#define XML_TOK_START_TAG_WITH_ATTS 1 +#define XML_TOK_START_TAG_NO_ATTS 2 +#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ +#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 +#define XML_TOK_END_TAG 5 +#define XML_TOK_DATA_CHARS 6 +#define XML_TOK_DATA_NEWLINE 7 +#define XML_TOK_CDATA_SECT_OPEN 8 +#define XML_TOK_ENTITY_REF 9 +#define XML_TOK_CHAR_REF 10 /* numeric character reference */ + +/* The following tokens may be returned by both XmlPrologTok and + XmlContentTok. +*/ +#define XML_TOK_PI 11 /* processing instruction */ +#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ +#define XML_TOK_COMMENT 13 +#define XML_TOK_BOM 14 /* Byte order mark */ + +/* The following tokens are returned only by XmlPrologTok */ +#define XML_TOK_PROLOG_S 15 +#define XML_TOK_DECL_OPEN 16 /* */ +#define XML_TOK_NAME 18 +#define XML_TOK_NMTOKEN 19 +#define XML_TOK_POUND_NAME 20 /* #name */ +#define XML_TOK_OR 21 /* | */ +#define XML_TOK_PERCENT 22 +#define XML_TOK_OPEN_PAREN 23 +#define XML_TOK_CLOSE_PAREN 24 +#define XML_TOK_OPEN_BRACKET 25 +#define XML_TOK_CLOSE_BRACKET 26 +#define XML_TOK_LITERAL 27 +#define XML_TOK_PARAM_ENTITY_REF 28 +#define XML_TOK_INSTANCE_START 29 + +/* The following occur only in element type declarations */ +#define XML_TOK_NAME_QUESTION 30 /* name? */ +#define XML_TOK_NAME_ASTERISK 31 /* name* */ +#define XML_TOK_NAME_PLUS 32 /* name+ */ +#define XML_TOK_COND_SECT_OPEN 33 /* */ +#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ +#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ +#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ +#define XML_TOK_COMMA 38 + +/* The following token is returned only by XmlAttributeValueTok */ +#define XML_TOK_ATTRIBUTE_VALUE_S 39 + +/* The following token is returned only by XmlCdataSectionTok */ +#define XML_TOK_CDATA_SECT_CLOSE 40 + +/* With namespace processing this is returned by XmlPrologTok for a + name with a colon. +*/ +#define XML_TOK_PREFIXED_NAME 41 + +#ifdef XML_DTD +# define XML_TOK_IGNORE_SECT 42 +#endif /* XML_DTD */ + +#ifdef XML_DTD +# define XML_N_STATES 4 +#else /* not XML_DTD */ +# define XML_N_STATES 3 +#endif /* not XML_DTD */ + +#define XML_PROLOG_STATE 0 +#define XML_CONTENT_STATE 1 +#define XML_CDATA_SECTION_STATE 2 +#ifdef XML_DTD +# define XML_IGNORE_SECTION_STATE 3 +#endif /* XML_DTD */ + +#define XML_N_LITERAL_TYPES 2 +#define XML_ATTRIBUTE_VALUE_LITERAL 0 +#define XML_ENTITY_VALUE_LITERAL 1 + +/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ +#define XML_UTF8_ENCODE_MAX 4 +/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ +#define XML_UTF16_ENCODE_MAX 2 + +typedef struct position { + /* first line and first column are 0 not 1 */ + XML_Size lineNumber; + XML_Size columnNumber; +} POSITION; + +typedef struct { + const char *name; + const char *valuePtr; + const char *valueEnd; + char normalized; +} ATTRIBUTE; + +struct encoding; +typedef struct encoding ENCODING; + +typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *, + const char **); + +enum XML_Convert_Result { + XML_CONVERT_COMPLETED = 0, + XML_CONVERT_INPUT_INCOMPLETE = 1, + XML_CONVERT_OUTPUT_EXHAUSTED + = 2 /* and therefore potentially input remaining as well */ +}; + +struct encoding { + SCANNER scanners[XML_N_STATES]; + SCANNER literalScanners[XML_N_LITERAL_TYPES]; + int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *, + const char *); + int(PTRFASTCALL *nameLength)(const ENCODING *, const char *); + const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); + int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax, + ATTRIBUTE *atts); + int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); + int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *, + const char *); + void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr, + const char *end, POSITION *); + int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr, + const char *end, const char **badPtr); + enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, char **toP, + const char *toLim); + enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + unsigned short **toP, + const unsigned short *toLim); + int minBytesPerChar; + char isUtf8; + char isUtf16; +}; + +/* Scan the string starting at ptr until the end of the next complete + token, but do not scan past eptr. Return an integer giving the + type of token. + + Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. + + Return XML_TOK_PARTIAL when the string does not contain a complete + token; nextTokPtr will not be set. + + Return XML_TOK_INVALID when the string does not start a valid + token; nextTokPtr will be set to point to the character which made + the token invalid. + + Otherwise the string starts with a valid token; nextTokPtr will be + set to point to the character following the end of that token. + + Each data character counts as a single token, but adjacent data + characters may be returned together. Similarly for characters in + the prolog outside literals, comments and processing instructions. +*/ + +#define XmlTok(enc, state, ptr, end, nextTokPtr) \ + (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) + +#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) + +#define XmlContentTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) + +#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) + +#ifdef XML_DTD + +# define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) + +#endif /* XML_DTD */ + +/* This is used for performing a 2nd-level tokenization on the content + of a literal that has already been returned by XmlTok. +*/ +#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ + (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) + +#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ + (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) + +#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr)) + +#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr)) + +#define XmlGetAttributes(enc, ptr, attsMax, atts) \ + (((enc)->getAtts)(enc, ptr, attsMax, atts)) + +#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr)) + +#define XmlPredefinedEntityName(enc, ptr, end) \ + (((enc)->predefinedEntityName)(enc, ptr, end)) + +#define XmlUpdatePosition(enc, ptr, end, pos) \ + (((enc)->updatePosition)(enc, ptr, end, pos)) + +#define XmlIsPublicId(enc, ptr, end, badPtr) \ + (((enc)->isPublicId)(enc, ptr, end, badPtr)) + +#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) + +#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) + +typedef struct { + ENCODING initEnc; + const ENCODING **encPtr; +} INIT_ENCODING; + +int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, + const char **encodingNamePtr, + const ENCODING **namedEncodingPtr, int *standalonePtr); + +int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); +const ENCODING *XmlGetUtf8InternalEncoding(void); +const ENCODING *XmlGetUtf16InternalEncoding(void); +int FASTCALL XmlUtf8Encode(int charNumber, char *buf); +int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); +int XmlSizeOfUnknownEncoding(void); + +typedef int(XMLCALL *CONVERTER)(void *userData, const char *p); + +ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, + void *userData); + +int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, + const char **encodingNamePtr, + const ENCODING **namedEncodingPtr, int *standalonePtr); + +int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); +const ENCODING *XmlGetUtf8InternalEncodingNS(void); +const ENCODING *XmlGetUtf16InternalEncodingNS(void); +ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, + void *userData); +#ifdef __cplusplus +} +#endif + +#endif /* not XmlTok_INCLUDED */ diff --git a/python/Modules/expat/xmltok_impl.c b/python/Modules/expat/xmltok_impl.c new file mode 100755 index 0000000..460ae9f --- /dev/null +++ b/python/Modules/expat/xmltok_impl.c @@ -0,0 +1,1804 @@ +/* This file is included! + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +#ifdef XML_TOK_IMPL_C + +# ifndef IS_INVALID_CHAR +# define IS_INVALID_CHAR(enc, ptr, n) (0) +# endif + +# define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +# define INVALID_CASES(ptr, nextTokPtr) \ + INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ + case BT_NONXML: \ + case BT_MALFORM: \ + case BT_TRAIL: \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; + +# define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (! IS_NAME_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +# define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (! IS_NAME_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + /* fall through */ \ + case BT_NMSTRT: \ + case BT_HEX: \ + case BT_DIGIT: \ + case BT_NAME: \ + case BT_MINUS: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) + +# define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (! IS_NMSTRT_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +# define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (! IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + /* fall through */ \ + case BT_NMSTRT: \ + case BT_HEX: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) + +# ifndef PREFIX_CC +# define PREFIX_CC(ident) ident +# endif + +# define HAS_CHARS(enc, ptr, end, count) (end - ptr >= count * MINBPC(enc)) + +# define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1) + +# define REQUIRE_CHARS(enc, ptr, end, count) \ + { \ + if (! HAS_CHARS(enc, ptr, end, count)) { \ + return XML_TOK_PARTIAL; \ + } \ + } + +# define REQUIRE_CHAR(enc, ptr, end) REQUIRE_CHARS(enc, ptr, end, 1) + +/* ptr points to character following " */ + switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { + case BT_S: + case BT_CR: + case BT_LF: + case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* fall through */ + case BT_S: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + case BT_NMSTRT: + case BT_HEX: + ptr += MINBPC(enc); + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX_CC(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, + int *tokPtr) { + int upper = 0; + UNUSED_P(enc); + *tokPtr = XML_TOK_PI; + if (end - ptr != MINBPC(enc) * 3) + return 1; + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_x: + break; + case ASCII_X: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_m: + break; + case ASCII_M: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + break; + case ASCII_L: + upper = 1; + break; + default: + return 1; + } + if (upper) + return 0; + *tokPtr = XML_TOK_XML_DECL; + return 1; +} + +/* ptr points to character following "= end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_RSQB: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CDATA_SECT_CLOSE; + case BT_CR: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC(enc); + break; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + case BT_RSQB: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "= end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_LT: + return PREFIX_CC(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_AMP: + return PREFIX_CC(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_CR: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + case BT_RSQB: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_RSQB; + if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_RSQB; + if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC(enc); + break; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_RSQB: + if (HAS_CHARS(enc, ptr, end, 2)) { + if (! CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { + ptr += MINBPC(enc); + break; + } + if (HAS_CHARS(enc, ptr, end, 3)) { + if (! CHAR_MATCHES(enc, ptr + 2 * MINBPC(enc), ASCII_GT)) { + ptr += MINBPC(enc); + break; + } + *nextTokPtr = ptr + 2 * MINBPC(enc); + return XML_TOK_INVALID; + } + } + /* fall through */ + case BT_AMP: + case BT_LT: + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "%" */ + +static int PTRCALL +PREFIX_CC(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + REQUIRE_CHAR(enc, ptr, end); + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: + case BT_LF: + case BT_CR: + case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_PERCENT; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_SEMI: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_PARAM_ENTITY_REF; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX_CC(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + REQUIRE_CHAR(enc, ptr, end); + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_CR: + case BT_LF: + case BT_S: + case BT_RPAR: + case BT_GT: + case BT_PERCNT: + case BT_VERBAR: + *nextTokPtr = ptr; + return XML_TOK_POUND_NAME; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -XML_TOK_POUND_NAME; +} + +static int PTRCALL +PREFIX_CC(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + while (HAS_CHAR(enc, ptr, end)) { + int t = BYTE_TYPE(enc, ptr); + switch (t) { + INVALID_CASES(ptr, nextTokPtr) + case BT_QUOT: + case BT_APOS: + ptr += MINBPC(enc); + if (t != open) + break; + if (! HAS_CHAR(enc, ptr, end)) + return -XML_TOK_LITERAL; + *nextTokPtr = ptr; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: + case BT_CR: + case BT_LF: + case BT_GT: + case BT_PERCNT: + case BT_LSQB: + return XML_TOK_LITERAL; + default: + return XML_TOK_INVALID; + } + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX_CC(prologTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + int tok; + if (ptr >= end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_QUOT: + return PREFIX_CC(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_APOS: + return PREFIX_CC(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_LT: { + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX_CC(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX_CC(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + case BT_CR: + if (ptr + MINBPC(enc) == end) { + *nextTokPtr = end; + /* indicate that this might be part of a CR/LF pair */ + return -XML_TOK_PROLOG_S; + } + /* fall through */ + case BT_S: + case BT_LF: + for (;;) { + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + break; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: + case BT_LF: + break; + case BT_CR: + /* don't split CR/LF pair */ + if (ptr + MINBPC(enc) != end) + break; + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + } + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + case BT_PERCNT: + return PREFIX_CC(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_COMMA: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_COMMA; + case BT_LSQB: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_BRACKET; + case BT_RSQB: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return -XML_TOK_CLOSE_BRACKET; + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + REQUIRE_CHARS(enc, ptr, end, 2); + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { + *nextTokPtr = ptr + 2 * MINBPC(enc); + return XML_TOK_COND_SECT_CLOSE; + } + } + *nextTokPtr = ptr; + return XML_TOK_CLOSE_BRACKET; + case BT_LPAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_PAREN; + case BT_RPAR: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return -XML_TOK_CLOSE_PAREN; + switch (BYTE_TYPE(enc, ptr)) { + case BT_AST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_ASTERISK; + case BT_QUEST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_QUESTION; + case BT_PLUS: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_PLUS; + case BT_CR: + case BT_LF: + case BT_S: + case BT_GT: + case BT_COMMA: + case BT_VERBAR: + case BT_RPAR: + *nextTokPtr = ptr; + return XML_TOK_CLOSE_PAREN; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_VERBAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OR; + case BT_GT: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DECL_CLOSE; + case BT_NUM: + return PREFIX_CC(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NMSTRT: + case BT_HEX: + tok = XML_TOK_NAME; + ptr += MINBPC(enc); + break; + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: +# ifdef XML_NS + case BT_COLON: +# endif + tok = XML_TOK_NMTOKEN; + ptr += MINBPC(enc); + break; + case BT_NONASCII: + if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NAME; + break; + } + if (IS_NAME_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NMTOKEN; + break; + } + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: + case BT_RPAR: + case BT_COMMA: + case BT_VERBAR: + case BT_LSQB: + case BT_PERCNT: + case BT_S: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return tok; +# ifdef XML_NS + case BT_COLON: + ptr += MINBPC(enc); + switch (tok) { + case XML_TOK_NAME: + REQUIRE_CHAR(enc, ptr, end); + tok = XML_TOK_PREFIX_CCED_NAME; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + default: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case XML_TOK_PREFIX_CCED_NAME: + tok = XML_TOK_NMTOKEN; + break; + } + break; +# endif + case BT_PLUS: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -tok; +} + +static int PTRCALL +PREFIX_CC(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + const char *start; + if (ptr >= end) + return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) { + /* This line cannot be executed. The incoming data has already + * been tokenized once, so incomplete characters like this have + * already been eliminated from the input. Retaining the paranoia + * check is still valuable, however. + */ + return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ + } + start = ptr; + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX_CC(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LT: + /* this is for inside entity references */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_S: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_ATTRIBUTE_VALUE_S; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +static int PTRCALL +PREFIX_CC(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + const char *start; + if (ptr >= end) + return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) { + /* This line cannot be executed. The incoming data has already + * been tokenized once, so incomplete characters like this have + * already been eliminated from the input. Retaining the paranoia + * check is still valuable, however. + */ + return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ + } + start = ptr; + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX_CC(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_PERCNT: + if (ptr == start) { + int tok = PREFIX_CC(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +# ifdef XML_DTD + +static int PTRCALL +PREFIX_CC(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + int level = 0; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + end = ptr + n; + } + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + INVALID_CASES(ptr, nextTokPtr) + case BT_LT: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { + ++level; + ptr += MINBPC(enc); + } + } + break; + case BT_RSQB: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } + } + break; + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +# endif /* XML_DTD */ + +static int PTRCALL +PREFIX_CC(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, + const char **badPtr) { + ptr += MINBPC(enc); + end -= MINBPC(enc); + for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_DIGIT: + case BT_HEX: + case BT_MINUS: + case BT_APOS: + case BT_LPAR: + case BT_RPAR: + case BT_PLUS: + case BT_COMMA: + case BT_SOL: + case BT_EQUALS: + case BT_QUEST: + case BT_CR: + case BT_LF: + case BT_SEMI: + case BT_EXCL: + case BT_AST: + case BT_PERCNT: + case BT_NUM: +# ifdef XML_NS + case BT_COLON: +# endif + break; + case BT_S: + if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { + *badPtr = ptr; + return 0; + } + break; + case BT_NAME: + case BT_NMSTRT: + if (! (BYTE_TO_ASCII(enc, ptr) & ~0x7f)) + break; + /* fall through */ + default: + switch (BYTE_TO_ASCII(enc, ptr)) { + case 0x24: /* $ */ + case 0x40: /* @ */ + break; + default: + *badPtr = ptr; + return 0; + } + break; + } + } + return 1; +} + +/* This must only be called for a well-formed start-tag or empty + element tag. Returns the number of attributes. Pointers to the + first attsMax attributes are stored in atts. +*/ + +static int PTRCALL +PREFIX_CC(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, + ATTRIBUTE *atts) { + enum { other, inName, inValue } state = inName; + int nAtts = 0; + int open = 0; /* defined when state == inValue; + initialization just to shut up compilers */ + + for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { +# define START_NAME \ + if (state == other) { \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ + } +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + START_NAME ptr += (n - MINBPC(enc)); \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + START_NAME + break; +# undef START_NAME + case BT_QUOT: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_QUOT; + } else if (open == BT_QUOT) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_APOS: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_APOS; + } else if (open == BT_APOS) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_AMP: + if (nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_S: + if (state == inName) + state = other; + else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE + || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE + || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) + atts[nAtts].normalized = 0; + break; + case BT_CR: + case BT_LF: + /* This case ensures that the first attribute name is counted + Apart from that we could just change state on the quote. */ + if (state == inName) + state = other; + else if (state == inValue && nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_GT: + case BT_SOL: + if (state != inValue) + return nAtts; + break; + default: + break; + } + } + /* not reached */ +} + +static int PTRFASTCALL +PREFIX_CC(charRefNumber)(const ENCODING *enc, const char *ptr) { + int result = 0; + /* skip &# */ + UNUSED_P(enc); + ptr += 2 * MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_x)) { + for (ptr += MINBPC(enc); ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); + ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + switch (c) { + case ASCII_0: + case ASCII_1: + case ASCII_2: + case ASCII_3: + case ASCII_4: + case ASCII_5: + case ASCII_6: + case ASCII_7: + case ASCII_8: + case ASCII_9: + result <<= 4; + result |= (c - ASCII_0); + break; + case ASCII_A: + case ASCII_B: + case ASCII_C: + case ASCII_D: + case ASCII_E: + case ASCII_F: + result <<= 4; + result += 10 + (c - ASCII_A); + break; + case ASCII_a: + case ASCII_b: + case ASCII_c: + case ASCII_d: + case ASCII_e: + case ASCII_f: + result <<= 4; + result += 10 + (c - ASCII_a); + break; + } + if (result >= 0x110000) + return -1; + } + } else { + for (; ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + result *= 10; + result += (c - ASCII_0); + if (result >= 0x110000) + return -1; + } + } + return checkCharRefNumber(result); +} + +static int PTRCALL +PREFIX_CC(predefinedEntityName)(const ENCODING *enc, const char *ptr, + const char *end) { + UNUSED_P(enc); + switch ((end - ptr) / MINBPC(enc)) { + case 2: + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + return ASCII_LT; + case ASCII_g: + return ASCII_GT; + } + } + break; + case 3: + if (CHAR_MATCHES(enc, ptr, ASCII_a)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_m)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) + return ASCII_AMP; + } + } + break; + case 4: + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_q: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_u)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_t)) + return ASCII_QUOT; + } + } + break; + case ASCII_a: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_s)) + return ASCII_APOS; + } + } + break; + } + } + return 0; +} + +static int PTRCALL +PREFIX_CC(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, + const char *end1, const char *ptr2) { + UNUSED_P(enc); + for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { + if (end1 - ptr1 < MINBPC(enc)) { + /* This line cannot be executed. The incoming data has already + * been tokenized once, so incomplete characters like this have + * already been eliminated from the input. Retaining the + * paranoia check is still valuable, however. + */ + return 0; /* LCOV_EXCL_LINE */ + } + if (! CHAR_MATCHES(enc, ptr1, *ptr2)) + return 0; + } + return ptr1 == end1; +} + +static int PTRFASTCALL +PREFIX_CC(nameLength)(const ENCODING *enc, const char *ptr) { + const char *start = ptr; + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: +# ifdef XML_NS + case BT_COLON: +# endif + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + ptr += MINBPC(enc); + break; + default: + return (int)(ptr - start); + } + } +} + +static const char *PTRFASTCALL +PREFIX_CC(skipS)(const ENCODING *enc, const char *ptr) { + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_LF: + case BT_CR: + case BT_S: + ptr += MINBPC(enc); + break; + default: + return ptr; + } + } +} + +static void PTRCALL +PREFIX_CC(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, + POSITION *pos) { + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_LF: + pos->columnNumber = (XML_Size)-1; + pos->lineNumber++; + ptr += MINBPC(enc); + break; + case BT_CR: + pos->lineNumber++; + ptr += MINBPC(enc); + if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + pos->columnNumber = (XML_Size)-1; + break; + default: + ptr += MINBPC(enc); + break; + } + pos->columnNumber++; + } +} + +# undef DO_LEAD_CASE +# undef MULTIBYTE_CASES +# undef INVALID_CASES +# undef CHECK_NAME_CASE +# undef CHECK_NAME_CASES +# undef CHECK_NMSTRT_CASE +# undef CHECK_NMSTRT_CASES + +#endif /* XML_TOK_IMPL_C */ diff --git a/python/Modules/expat/xmltok_impl.h b/python/Modules/expat/xmltok_impl.h new file mode 100755 index 0000000..e925dbc --- /dev/null +++ b/python/Modules/expat/xmltok_impl.h @@ -0,0 +1,73 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +enum { + BT_NONXML, /* e.g. noncharacter-FFFF */ + BT_MALFORM, /* illegal, with regard to encoding */ + BT_LT, /* less than = "<" */ + BT_AMP, /* ampersand = "&" */ + BT_RSQB, /* right square bracket = "[" */ + BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */ + BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */ + BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */ + BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */ + BT_CR, /* carriage return = "\r" */ + BT_LF, /* line feed = "\n" */ + BT_GT, /* greater than = ">" */ + BT_QUOT, /* quotation character = "\"" */ + BT_APOS, /* aposthrophe = "'" */ + BT_EQUALS, /* equal sign = "=" */ + BT_QUEST, /* question mark = "?" */ + BT_EXCL, /* exclamation mark = "!" */ + BT_SOL, /* solidus, slash = "/" */ + BT_SEMI, /* semicolon = ";" */ + BT_NUM, /* number sign = "#" */ + BT_LSQB, /* left square bracket = "[" */ + BT_S, /* white space, e.g. "\t", " "[, "\r"] */ + BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */ + BT_COLON, /* colon = ":" */ + BT_HEX, /* hex letter = "A".."F" + "a".."f" */ + BT_DIGIT, /* digit = "0".."9" */ + BT_NAME, /* dot and middle dot = "." + chr(0xb7) */ + BT_MINUS, /* minus = "-" */ + BT_OTHER, /* known not to be a name or name start character */ + BT_NONASCII, /* might be a name or name start character */ + BT_PERCNT, /* percent sign = "%" */ + BT_LPAR, /* left parenthesis = "(" */ + BT_RPAR, /* right parenthesis = "(" */ + BT_AST, /* asterisk = "*" */ + BT_PLUS, /* plus sign = "+" */ + BT_COMMA, /* comma = "," */ + BT_VERBAR /* vertical bar = "|" */ +}; + +#include diff --git a/python/Modules/expat/xmltok_ns.c b/python/Modules/expat/xmltok_ns.c new file mode 100755 index 0000000..919c74e --- /dev/null +++ b/python/Modules/expat/xmltok_ns.c @@ -0,0 +1,118 @@ +/* This file is included! + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000-2017 Expat development team + Licensed under the MIT license: + + 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. +*/ + +#ifdef XML_TOK_NS_C + +const ENCODING * +NS(XmlGetUtf8InternalEncoding)(void) { + return &ns(internal_utf8_encoding).enc; +} + +const ENCODING * +NS(XmlGetUtf16InternalEncoding)(void) { +# if BYTEORDER == 1234 + return &ns(internal_little2_encoding).enc; +# elif BYTEORDER == 4321 + return &ns(internal_big2_encoding).enc; +# else + const short n = 1; + return (*(const char *)&n ? &ns(internal_little2_encoding).enc + : &ns(internal_big2_encoding).enc); +# endif +} + +static const ENCODING *const NS(encodings)[] = { + &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, + &ns(utf8_encoding).enc, &ns(big2_encoding).enc, + &ns(big2_encoding).enc, &ns(little2_encoding).enc, + &ns(utf8_encoding).enc /* NO_ENC */ +}; + +static int PTRCALL +NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, + ptr, end, nextTokPtr); +} + +static int PTRCALL +NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, + ptr, end, nextTokPtr); +} + +int +NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, + const char *name) { + int i = getEncodingIndex(name); + if (i == UNKNOWN_ENC) + return 0; + SET_INIT_ENC_INDEX(p, i); + p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); + p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); + p->initEnc.updatePosition = initUpdatePosition; + p->encPtr = encPtr; + *encPtr = &(p->initEnc); + return 1; +} + +static const ENCODING * +NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { +# define ENCODING_MAX 128 + char buf[ENCODING_MAX]; + char *p = buf; + int i; + XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); + if (ptr != end) + return 0; + *p = 0; + if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) + return enc; + i = getEncodingIndex(buf); + if (i == UNKNOWN_ENC) + return 0; + return NS(encodings)[i]; +} + +int +NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, + const char **encodingName, const ENCODING **encoding, + int *standalone) { + return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end, + badPtr, versionPtr, versionEndPtr, encodingName, + encoding, standalone); +} + +#endif /* XML_TOK_NS_C */ diff --git a/python/Modules/faulthandler.c b/python/Modules/faulthandler.c new file mode 100755 index 0000000..230cde4 --- /dev/null +++ b/python/Modules/faulthandler.c @@ -0,0 +1,1417 @@ +#include "Python.h" +#include "pycore_initconfig.h" +#include "pycore_traceback.h" +#include "pythread.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) + +#define FAULTHANDLER_LATER + +#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}; + +#ifdef FAULTHANDLER_LATER +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; +#endif + +#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); + +#ifdef HAVE_SIGALTSTACK +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_CallMethodId(file, &PyId_fileno, NULL); + 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_CallMethodId(file, &PyId_flush, NULL); + 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 + +/* Install the handler for fatal signals, faulthandler_fatal_error(). */ + +static int +faulthandler_enable(void) +{ + if (fatal_error.enabled) { + return 0; + } + fatal_error.enabled = 1; + + for (size_t i=0; i < faulthandler_nsignals; i++) { + fault_handler_t *handler; +#ifdef HAVE_SIGACTION + struct sigaction action; +#endif + int err; + + handler = &faulthandler_handlers[i]; + assert(!handler->enabled); +#ifdef HAVE_SIGACTION + 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 HAVE_SIGALTSTACK + if (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, + 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; + fatal_error.interp = tstate->interp; + + 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* +faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(fatal_error.enabled); +} + +#ifdef FAULTHANDLER_LATER + +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) +{ + /* 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; + + fd = faulthandler_get_fileno(&file); + if (fd < 0) + return NULL; + + /* 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; + thread.interp = tstate->interp; + 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; +} +#endif /* FAULTHANDLER_LATER */ + +#ifdef FAULTHANDLER_USER +static int +faulthandler_register(int signum, int chain, _Py_sighandler_t *p_previous) +{ +#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_SIGALTSTACK + if (stack.ss_sp != NULL) { + /* Call the signal handler on an alternate signal stack + provided by sigaltstack() */ + action.sa_flags |= SA_ONSTACK; + } +#endif + return sigaction(signum, &action, p_previous); +#else + _Py_sighandler_t previous; + previous = signal(signum, faulthandler_user); + if (p_previous != NULL) + *p_previous = 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) { + user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t)); + if (user_signals == NULL) + return PyErr_NoMemory(); + memset(user_signals, 0, NSIG * sizeof(user_signal_t)); + } + user = &user_signals[signum]; + + if (!user->enabled) { + 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 = tstate->interp; + 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 +faulthandler_fatal_error_thread(void *plock) +{ +#ifndef __clang__ + PyThread_type_lock *lock = (PyThread_type_lock *)plock; +#endif + + Py_FatalError("in new thread"); + +#ifndef __clang__ + /* Issue #28152: Py_FatalError() is declared with + __attribute__((__noreturn__)). GCC emits a warning without + "PyThread_release_lock()" (compiler bug?), but Clang is smarter and + emits a warning on the return. */ + + /* notify the caller that we are done */ + PyThread_release_lock(lock); +#endif +} + +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(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) +#define FAULTHANDLER_STACK_OVERFLOW + +static uintptr_t +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 * +faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + size_t depth, size; + uintptr_t sp = (uintptr_t)&depth; + uintptr_t stop, lower_limit, upper_limit; + + faulthandler_suppress_crash_report(); + depth = 0; + + if (STACK_OVERFLOW_MAX_SIZE <= sp) { + lower_limit = sp - STACK_OVERFLOW_MAX_SIZE; + } + else { + lower_limit = 0; + } + + if (UINTPTR_MAX - STACK_OVERFLOW_MAX_SIZE >= sp) { + upper_limit = sp + STACK_OVERFLOW_MAX_SIZE; + } + else { + upper_limit = UINTPTR_MAX; + } + + 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; +} +#endif /* defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) */ + + +static int +faulthandler_traverse(PyObject *module, visitproc visit, void *arg) +{ +#ifdef FAULTHANDLER_LATER + Py_VISIT(thread.file); +#endif +#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")}, + {"disable", faulthandler_disable_py, METH_NOARGS, + 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", + (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")}, +#ifdef FAULTHANDLER_LATER + {"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", + faulthandler_cancel_dump_traceback_later_py, METH_NOARGS, + PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call " + "to dump_traceback_later().")}, +#endif + +#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", + (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 + {"_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", + EXCEPTION_ACCESS_VIOLATION)) { + goto error; + } + if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", + EXCEPTION_INT_DIVIDE_BY_ZERO)) { + goto error; + } + if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", + EXCEPTION_STACK_OVERFLOW)) { + goto error; + } + + /* RaiseException() flags (prefixed by an underscore) */ + if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", + EXCEPTION_NONCONTINUABLE)) { + goto error; + } + if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", + EXCEPTION_NONCONTINUABLE_EXCEPTION)) { + goto error; + } +#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; + } + + PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL); + Py_DECREF(module); + if (res == NULL) { + return -1; + } + Py_DECREF(res); + + return 0; +} + +PyStatus +_PyFaulthandler_Init(int enable) +{ +#ifdef HAVE_SIGALTSTACK + int err; + + /* Try to allocate an alternate stack for faulthandler() signal handler to + * be able to allocate memory on the stack, even on a stack overflow. If it + * fails, ignore the error. */ + 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; + stack.ss_sp = PyMem_Malloc(stack.ss_size); + if (stack.ss_sp != NULL) { + err = sigaltstack(&stack, &old_stack); + if (err) { + PyMem_Free(stack.ss_sp); + stack.ss_sp = NULL; + } + } +#endif +#ifdef FAULTHANDLER_LATER + thread.file = NULL; + thread.cancel_event = PyThread_allocate_lock(); + thread.running = PyThread_allocate_lock(); + if (!thread.cancel_event || !thread.running) { + return _PyStatus_ERR("failed to allocate locks for faulthandler"); + } + PyThread_acquire_lock(thread.cancel_event, 1); +#endif + + if (enable) { + if (faulthandler_init_enable() < 0) { + return _PyStatus_ERR("failed to enable faulthandler"); + } + } + return _PyStatus_OK(); +} + +void _PyFaulthandler_Fini(void) +{ +#ifdef FAULTHANDLER_LATER + /* 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; + } +#endif + +#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 HAVE_SIGALTSTACK + 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 +} diff --git a/python/Modules/fcntlmodule.c b/python/Modules/fcntlmodule.c new file mode 100755 index 0000000..a7d2193 --- /dev/null +++ b/python/Modules/fcntlmodule.c @@ -0,0 +1,681 @@ + +/* 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 (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 (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; + + 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, +"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 +#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_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; + if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1; + if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1; + if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1; + 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 */ + if (all_ins(m) < 0) + return NULL; + + return m; +} diff --git a/python/Modules/gc_weakref.txt b/python/Modules/gc_weakref.txt new file mode 100755 index 0000000..2f18402 --- /dev/null +++ b/python/Modules/gc_weakref.txt @@ -0,0 +1,219 @@ +Intro +===== + +The basic rule for dealing with weakref callbacks (and __del__ methods too, +for that matter) during cyclic gc: + + Once gc has computed the set of unreachable objects, no Python-level + code can be allowed to access an unreachable object. + +If that can happen, then the Python code can resurrect unreachable objects +too, and gc can't detect that without starting over. Since gc eventually +runs tp_clear on all unreachable objects, if an unreachable object is +resurrected then tp_clear will eventually be called on it (or may already +have been called before resurrection). At best (and this has been an +historically common bug), tp_clear empties an instance's __dict__, and +"impossible" AttributeErrors result. At worst, tp_clear leaves behind an +insane object at the C level, and segfaults result (historically, most +often by setting a class's mro pointer to NULL, after which attribute +lookups performed by the class can segfault). + +OTOH, it's OK to run Python-level code that can't access unreachable +objects, and sometimes that's necessary. The chief example is the callback +attached to a reachable weakref W to an unreachable object O. Since O is +going away, and W is still alive, the callback must be invoked. Because W +is still alive, everything reachable from its callback is also reachable, +so it's also safe to invoke the callback (although that's trickier than it +sounds, since other reachable weakrefs to other unreachable objects may +still exist, and be accessible to the callback -- there are lots of painful +details like this covered in the rest of this file). + +Python 2.4/2.3.5 +================ + +The "Before 2.3.3" section below turned out to be wrong in some ways, but +I'm leaving it as-is because it's more right than wrong, and serves as a +wonderful example of how painful analysis can miss not only the forest for +the trees, but also miss the trees for the aphids sucking the trees +dry . + +The primary thing it missed is that when a weakref to a piece of cyclic +trash (CT) exists, then any call to any Python code whatsoever can end up +materializing a strong reference to that weakref's CT referent, and so +possibly resurrect an insane object (one for which cyclic gc has called-- or +will call before it's done --tp_clear()). It's not even necessarily that a +weakref callback or __del__ method does something nasty on purpose: as +soon as we execute Python code, threads other than the gc thread can run +too, and they can do ordinary things with weakrefs that end up resurrecting +CT while gc is running. + + http://www.python.org/sf/1055820 + +shows how innocent it can be, and also how nasty. Variants of the three +focussed test cases attached to that bug report are now part of Python's +standard Lib/test/test_gc.py. + +Jim Fulton gave the best nutshell summary of the new (in 2.4 and 2.3.5) +approach: + + Clearing cyclic trash can call Python code. If there are weakrefs to + any of the cyclic trash, then those weakrefs can be used to resurrect + the objects. Therefore, *before* clearing cyclic trash, we need to + remove any weakrefs. If any of the weakrefs being removed have + callbacks, then we need to save the callbacks and call them *after* all + of the weakrefs have been cleared. + +Alas, doing just that much doesn't work, because it overlooks what turned +out to be the much subtler problems that were fixed earlier, and described +below. We do clear all weakrefs to CT now before breaking cycles, but not +all callbacks encountered can be run later. That's explained in horrid +detail below. + +Older text follows, with a some later comments in [] brackets: + +Before 2.3.3 +============ + +Before 2.3.3, Python's cyclic gc didn't pay any attention to weakrefs. +Segfaults in Zope3 resulted. + +weakrefs in Python are designed to, at worst, let *other* objects learn +that a given object has died, via a callback function. The weakly +referenced object itself is not passed to the callback, and the presumption +is that the weakly referenced object is unreachable trash at the time the +callback is invoked. + +That's usually true, but not always. Suppose a weakly referenced object +becomes part of a clump of cyclic trash. When enough cycles are broken by +cyclic gc that the object is reclaimed, the callback is invoked. If it's +possible for the callback to get at objects in the cycle(s), then it may be +possible for those objects to access (via strong references in the cycle) +the weakly referenced object being torn down, or other objects in the cycle +that have already suffered a tp_clear() call. There's no guarantee that an +object is in a sane state after tp_clear(). Bad things (including +segfaults) can happen right then, during the callback's execution, or can +happen at any later time if the callback manages to resurrect an insane +object. + +[That missed that, in addition, a weakref to CT can exist outside CT, and + any callback into Python can use such a non-CT weakref to resurrect its CT + referent. The same bad kinds of things can happen then.] + +Note that if it's possible for the callback to get at objects in the trash +cycles, it must also be the case that the callback itself is part of the +trash cycles. Else the callback would have acted as an external root to +the current collection, and nothing reachable from it would be in cyclic +trash either. + +[Except that a non-CT callback can also use a non-CT weakref to get at + CT objects.] + +More, if the callback itself is in cyclic trash, then the weakref to which +the callback is attached must also be trash, and for the same kind of +reason: if the weakref acted as an external root, then the callback could +not have been cyclic trash. + +So a problem here requires that a weakref, that weakref's callback, and the +weakly referenced object, all be in cyclic trash at the same time. This +isn't easy to stumble into by accident while Python is running, and, indeed, +it took quite a while to dream up failing test cases. Zope3 saw segfaults +during shutdown, during the second call of gc in Py_Finalize, after most +modules had been torn down. That creates many trash cycles (esp. those +involving classes), making the problem much more likely. Once you +know what's required to provoke the problem, though, it's easy to create +tests that segfault before shutdown. + +In 2.3.3, before breaking cycles, we first clear all the weakrefs with +callbacks in cyclic trash. Since the weakrefs *are* trash, and there's no +defined-- or even predictable --order in which tp_clear() gets called on +cyclic trash, it's defensible to first clear weakrefs with callbacks. It's +a feature of Python's weakrefs too that when a weakref goes away, the +callback (if any) associated with it is thrown away too, unexecuted. + +[In 2.4/2.3.5, we first clear all weakrefs to CT objects, whether or not + those weakrefs are themselves CT, and whether or not they have callbacks. + The callbacks (if any) on non-CT weakrefs (if any) are invoked later, + after all weakrefs-to-CT have been cleared. The callbacks (if any) on CT + weakrefs (if any) are never invoked, for the excruciating reasons + explained here.] + +Just that much is almost enough to prevent problems, by throwing away +*almost* all the weakref callbacks that could get triggered by gc. The +problem remaining is that clearing a weakref with a callback decrefs the +callback object, and the callback object may *itself* be weakly referenced, +via another weakref with another callback. So the process of clearing +weakrefs can trigger callbacks attached to other weakrefs, and those +latter weakrefs may or may not be part of cyclic trash. + +So, to prevent any Python code from running while gc is invoking tp_clear() +on all the objects in cyclic trash, + +[That was always wrong: we can't stop Python code from running when gc + is breaking cycles. If an object with a __del__ method is not itself in + a cycle, but is reachable only from CT, then breaking cycles will, as a + matter of course, drop the refcount on that object to 0, and its __del__ + will run right then. What we can and must stop is running any Python + code that could access CT.] + it's not quite enough just to invoke +tp_clear() on weakrefs with callbacks first. Instead the weakref module +grew a new private function (_PyWeakref_ClearRef) that does only part of +tp_clear(): it removes the weakref from the weakly-referenced object's list +of weakrefs, but does not decref the callback object. So calling +_PyWeakref_ClearRef(wr) ensures that wr's callback object will never +trigger, and (unlike weakref's tp_clear()) also prevents any callback +associated *with* wr's callback object from triggering. + +[Although we may trigger such callbacks later, as explained below.] + +Then we can call tp_clear on all the cyclic objects and never trigger +Python code. + +[As above, not so: it means never trigger Python code that can access CT.] + +After we do that, the callback objects still need to be decref'ed. Callbacks +(if any) *on* the callback objects that were also part of cyclic trash won't +get invoked, because we cleared all trash weakrefs with callbacks at the +start. Callbacks on the callback objects that were not part of cyclic trash +acted as external roots to everything reachable from them, so nothing +reachable from them was part of cyclic trash, so gc didn't do any damage to +objects reachable from them, and it's safe to call them at the end of gc. + +[That's so. In addition, now we also invoke (if any) the callbacks on + non-CT weakrefs to CT objects, during the same pass that decrefs the + callback objects.] + +An alternative would have been to treat objects with callbacks like objects +with __del__ methods, refusing to collect them, appending them to gc.garbage +instead. That would have been much easier. Jim Fulton gave a strong +argument against that (on Python-Dev): + + There's a big difference between __del__ and weakref callbacks. + The __del__ method is "internal" to a design. When you design a + class with a del method, you know you have to avoid including the + class in cycles. + + Now, suppose you have a design that makes has no __del__ methods but + that does use cyclic data structures. You reason about the design, + run tests, and convince yourself you don't have a leak. + + Now, suppose some external code creates a weakref to one of your + objects. All of a sudden, you start leaking. You can look at your + code all you want and you won't find a reason for the leak. + +IOW, a class designer can out-think __del__ problems, but has no control +over who creates weakrefs to his classes or class instances. The class +user has little chance either of predicting when the weakrefs he creates +may end up in cycles. + +Callbacks on weakref callbacks are executed in an arbitrary order, and +that's not good (a primary reason not to collect cycles with objects with +__del__ methods is to avoid running finalizers in an arbitrary order). +However, a weakref callback on a weakref callback has got to be rare. +It's possible to do such a thing, so gc has to be robust against it, but +I doubt anyone has done it outside the test case I wrote for it. + +[The callbacks (if any) on non-CT weakrefs to CT objects are also executed + in an arbitrary order now. But they were before too, depending on the + vagaries of when tp_clear() happened to break enough cycles to trigger + them. People simply shouldn't try to use __del__ or weakref callbacks to + do fancy stuff.] diff --git a/python/Modules/gcmodule.c b/python/Modules/gcmodule.c new file mode 100755 index 0000000..8173725 --- /dev/null +++ b/python/Modules/gcmodule.c @@ -0,0 +1,2063 @@ +/* + + 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_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "frameobject.h" /* for PyFrame_ClearFreeList */ +#include "pydtrace.h" +#include "pytime.h" /* for _PyTime_GetMonotonicClock() */ + +/*[clinic input] +module gc +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b5c9690ecc842d79]*/ + +#define GC_DEBUG (0) /* Enable more asserts */ + +#define GC_NEXT _PyGCHead_NEXT +#define GC_PREV _PyGCHead_PREV + +// update_refs() set this bit for all objects in current generation. +// subtract_refs() and move_unreachable() uses this to distinguish +// visited object is in GCing or not. +// +// move_unreachable() removes this flag from reachable objects. +// Only unreachable objects have this flag. +// +// No objects in interpreter have this flag after GC ends. +#define PREV_MASK_COLLECTING _PyGC_PREV_MASK_COLLECTING + +// Lowest bit of _gc_next is used for UNREACHABLE flag. +// +// This flag represents the object is in unreachable list in move_unreachable() +// +// Although this flag is used only in move_unreachable(), move_unreachable() +// doesn't clear this flag to skip unnecessary iteration. +// move_legacy_finalizers() removes this flag instead. +// Between them, unreachable list is not normal list and we can not use +// 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)) + +static inline int +gc_is_collecting(PyGC_Head *g) +{ + return (g->_gc_prev & PREV_MASK_COLLECTING) != 0; +} + +static inline void +gc_clear_collecting(PyGC_Head *g) +{ + g->_gc_prev &= ~PREV_MASK_COLLECTING; +} + +static inline Py_ssize_t +gc_get_refs(PyGC_Head *g) +{ + return (Py_ssize_t)(g->_gc_prev >> _PyGC_PREV_SHIFT); +} + +static inline void +gc_set_refs(PyGC_Head *g, Py_ssize_t refs) +{ + g->_gc_prev = (g->_gc_prev & ~_PyGC_PREV_MASK) + | ((uintptr_t)(refs) << _PyGC_PREV_SHIFT); +} + +static inline void +gc_reset_refs(PyGC_Head *g, Py_ssize_t refs) +{ + g->_gc_prev = (g->_gc_prev & _PyGC_PREV_MASK_FINALIZED) + | PREV_MASK_COLLECTING + | ((uintptr_t)(refs) << _PyGC_PREV_SHIFT); +} + +static inline void +gc_decref(PyGC_Head *g) +{ + _PyObject_ASSERT_WITH_MSG(FROM_GC(g), + gc_get_refs(g) > 0, + "refcount is too small"); + g->_gc_prev -= 1 << _PyGC_PREV_SHIFT; +} + +/* Python string to use if unhandled exception occurs */ +static PyObject *gc_str = NULL; + +/* 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(state, n) (&(state)->generations[n].head) + +void +_PyGC_Initialize(struct _gc_runtime_state *state) +{ + state->enabled = 1; /* automatic collection enabled? */ + +#define _GEN_HEAD(n) GEN_HEAD(state, n) + 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++) { + state->generations[i] = generations[i]; + }; + state->generation0 = GEN_HEAD(state, 0); + struct gc_generation permanent_generation = { + {(uintptr_t)&state->permanent_generation.head, + (uintptr_t)&state->permanent_generation.head}, 0, 0 + }; + state->permanent_generation = permanent_generation; +} + +/* +_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. + +PREV_MASK_COLLECTING + Objects in generation being collected are marked PREV_MASK_COLLECTING in + update_refs(). + + +_gc_next values +--------------- + +_gc_next takes these values: + +0 + The object is not tracked + +!= 0 + Pointer to the next object in the GC list. + Additionally, lowest bit is used temporary for + NEXT_MASK_UNREACHABLE flag described below. + +NEXT_MASK_UNREACHABLE + 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 ***/ + +static inline void +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) +{ + return (list->_gc_next == (uintptr_t)list); +} + +/* Append `node` to `list`. */ +static inline void +gc_list_append(PyGC_Head *node, PyGC_Head *list) +{ + PyGC_Head *last = (PyGC_Head *)list->_gc_prev; + + // last <-> node + _PyGCHead_SET_PREV(node, last); + _PyGCHead_SET_NEXT(last, node); + + // node <-> list + _PyGCHead_SET_NEXT(node, list); + list->_gc_prev = (uintptr_t)node; +} + +/* Remove `node` from the gc list it's currently in. */ +static inline void +gc_list_remove(PyGC_Head *node) +{ + PyGC_Head *prev = GC_PREV(node); + PyGC_Head *next = GC_NEXT(node); + + _PyGCHead_SET_NEXT(prev, next); + _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. */ + 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. */ + // 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)) { + PyGC_Head *to_tail = GC_PREV(to); + PyGC_Head *from_head = GC_NEXT(from); + PyGC_Head *from_tail = GC_PREV(from); + assert(from_head != from); + assert(from_tail != from); + + _PyGCHead_SET_NEXT(to_tail, from_head); + _PyGCHead_SET_PREV(from_head, to_tail); + + _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; + for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(gc)) { + n++; + } + return n; +} + +/* 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; + 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; +} + +#if GC_DEBUG +// validate_list checks list consistency. And it works as document +// describing when expected_mask is set / unset. +static void +validate_list(PyGC_Head *head, uintptr_t expected_mask) +{ + PyGC_Head *prev = head; + PyGC_Head *gc = GC_NEXT(head); + while (gc != head) { + assert(GC_NEXT(gc) != NULL); + assert(GC_PREV(gc) == prev); + assert((gc->_gc_prev & PREV_MASK_COLLECTING) == expected_mask); + prev = gc; + gc = GC_NEXT(gc); + } + assert(prev == GC_PREV(head)); +} +#else +#define validate_list(x,y) do{}while(0) +#endif + +/*** 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) +{ + 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? + */ + _PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0); + } +} + +/* 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. + */ + 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; + 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, + op); + } +} + +/* 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); + + // Ignore untracked objects and objects in other generation. + if (gc->_gc_next == 0 || !gc_is_collecting(gc)) { + return 0; + } + + if (gc->_gc_next & NEXT_MASK_UNREACHABLE) { + /* This had gc_refs = 0 when move_unreachable got + * to it, but turns out it's reachable after all. + * 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 + PyGC_Head *prev = GC_PREV(gc); + PyGC_Head *next = (PyGC_Head*)(gc->_gc_next & ~NEXT_MASK_UNREACHABLE); + _PyObject_ASSERT(FROM_GC(prev), + prev->_gc_next & NEXT_MASK_UNREACHABLE); + _PyObject_ASSERT(FROM_GC(next), + next->_gc_next & NEXT_MASK_UNREACHABLE); + prev->_gc_next = gc->_gc_next; // copy NEXT_MASK_UNREACHABLE + _PyGCHead_SET_PREV(next, prev); + + 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 + * we need to do is tell move_unreachable that it's + * reachable. + */ + gc_set_refs(gc, 1); + } + /* Else there's nothing to do. + * If gc_refs > 0, it must be in move_unreachable's 'young' + * list, and move_unreachable will eventually get to it. + */ + 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, + * 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. + * + * 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) +{ + // 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) { + 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; + _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, + (visitproc)visit_reachable, + (void *)young); + // relink gc_prev to prev element. + _PyGCHead_SET_PREV(gc, prev); + // 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. + */ + // Move gc to unreachable. + // No need to gc->next->prev = prev because it is single linked. + prev->_gc_next = gc->_gc_next; + + // We can't use gc_list_append() here because we use + // NEXT_MASK_UNREACHABLE here. + PyGC_Head *last = GC_PREV(unreachable); + // NOTE: Since all objects in unreachable set has + // NEXT_MASK_UNREACHABLE flag, we set it unconditionally. + // But this may set the flat to unreachable too. + // move_legacy_finalizers() should care about it. + last->_gc_next = (NEXT_MASK_UNREACHABLE | (uintptr_t)gc); + _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. + young->_gc_prev = (uintptr_t)prev; +} + +static void +untrack_tuples(PyGC_Head *head) +{ + PyGC_Head *next, *gc = GC_NEXT(head); + while (gc != head) { + PyObject *op = FROM_GC(gc); + next = GC_NEXT(gc); + if (PyTuple_CheckExact(op)) { + _PyTuple_MaybeUntrack(op); + } + 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); + next = GC_NEXT(gc); + if (PyDict_CheckExact(op)) { + _PyDict_MaybeUntrack(op); + } + gc = next; + } +} + +/* Return true if object has a pre-PEP 442 finalization method. */ +static int +has_legacy_finalizer(PyObject *op) +{ + return op->ob_type->tp_del != NULL; +} + +/* 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) +{ + PyGC_Head *gc, *next; + unreachable->_gc_next &= ~NEXT_MASK_UNREACHABLE; + + /* March over unreachable. Move objects with finalizers into + * `finalizers`. + */ + for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) { + 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)) { + gc_clear_collecting(gc); + gc_list_move(gc, finalizers); + } + } +} + +/* 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_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; + 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. + */ + for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) { + 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 + * could expose objects that have tp_clear already called on + * them. Or, it could resurrect unreachable objects. One way + * this can happen is if some container objects do not implement + * tp_traverse. Then, wr_object can be outside the unreachable + * set but can be deallocated as a result of breaking the + * reference cycle. If we don't clear the weakref, the callback + * will run and potentially cause a crash. See bpo-38006 for + * one example. + */ + _PyWeakref_ClearRef((PyWeakReference *)op); + } + + 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. + */ + _PyObject_ASSERT((PyObject *)wr, wr->wr_object == op); + _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: + * + * 1. There's no need to call it. The object and the weakref are + * both going away, so it's legitimate to pretend the weakref is + * going away first. The user has to ensure a weakref outlives its + * referent if they want a guarantee that the wr callback will get + * invoked. + * + * 2. It may be catastrophic to call it. If the callback is also in + * cyclic trash (CT), then although the CT is unreachable from + * outside the current generation, CT may be reachable from the + * callback. Then the callback could resurrect insane objects. + * + * Since the callback is never needed and may be unsafe in this case, + * wr is simply left in the unreachable set. Note that because we + * already called _PyWeakref_ClearRef(wr), its callback will never + * trigger. + * + * OTOH, if wr isn't part of CT, we should invoke the callback: the + * weakref outlived the trash. Note that since wr isn't CT in this + * case, its callback can't be CT either -- wr acted as an external + * root to this generation, and therefore its callback did too. So + * nothing in CT is reachable from the callback either, so it's hard + * to imagine how calling it later could create a problem for us. wr + * is moved to wrcb_to_call in this case. + */ + if (gc_is_collecting(AS_GC(wr))) { + /* it should already have been cleared above */ + assert(wr->wr_object == Py_None); + 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; + + gc = (PyGC_Head*)wrcb_to_call._gc_next; + op = FROM_GC(gc); + _PyObject_ASSERT(op, PyWeakref_Check(op)); + wr = (PyWeakReference *)op; + callback = wr->wr_callback; + _PyObject_ASSERT(op, callback != NULL); + + /* copy-paste of weakrefobject.c's handle_callback() */ + temp = PyObject_CallFunctionObjArgs(callback, wr, NULL); + 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); + } + else { + ++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 +handle_legacy_finalizers(struct _gc_runtime_state *state, + PyGC_Head *finalizers, PyGC_Head *old) +{ + assert(!PyErr_Occurred()); + + PyGC_Head *gc = GC_NEXT(finalizers); + if (state->garbage == NULL) { + state->garbage = PyList_New(0); + if (state->garbage == NULL) + Py_FatalError("gc couldn't create gc.garbage list"); + } + for (; gc != finalizers; gc = GC_NEXT(gc)) { + PyObject *op = FROM_GC(gc); + + if ((state->debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { + if (PyList_Append(state->garbage, op) < 0) { + PyErr_Clear(); + 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 +finalize_garbage(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)) { + 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) { + _PyGCHead_SET_FINALIZED(gc); + Py_INCREF(op); + finalize(op); + assert(!PyErr_Occurred()); + Py_DECREF(op); + } + } + gc_list_merge(&seen, collectable); +} + +/* Walk the collectable list and check that they are really unreachable + from the outside (some objects could have been resurrected by a + finalizer). */ +static int +check_garbage(PyGC_Head *collectable) +{ + int ret = 0; + PyGC_Head *gc; + for (gc = GC_NEXT(collectable); gc != collectable; gc = GC_NEXT(gc)) { + // Use gc_refs and break gc_prev again. + gc_set_refs(gc, Py_REFCNT(FROM_GC(gc))); + _PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0); + } + subtract_refs(collectable); + PyGC_Head *prev = collectable; + for (gc = GC_NEXT(collectable); gc != collectable; gc = GC_NEXT(gc)) { + _PyObject_ASSERT_WITH_MSG(FROM_GC(gc), + gc_get_refs(gc) >= 0, + "refcount is too small"); + if (gc_get_refs(gc) != 0) { + ret = -1; + } + // Restore gc_prev here. + _PyGCHead_SET_PREV(gc, prev); + gc_clear_collecting(gc); + prev = gc; + } + return ret; +} + +/* 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(struct _gc_runtime_state *state, + PyGC_Head *collectable, PyGC_Head *old) +{ + assert(!PyErr_Occurred()); + + while (!gc_list_is_empty(collectable)) { + PyGC_Head *gc = GC_NEXT(collectable); + PyObject *op = FROM_GC(gc); + + _PyObject_ASSERT_WITH_MSG(op, Py_REFCNT(op) > 0, + "refcount is too small"); + + if (state->debug & DEBUG_SAVEALL) { + assert(state->garbage != NULL); + if (PyList_Append(state->garbage, op) < 0) { + PyErr_Clear(); + } + } + else { + inquiry clear; + if ((clear = Py_TYPE(op)->tp_clear) != NULL) { + Py_INCREF(op); + (void) clear(op); + if (PyErr_Occurred()) { + _PyErr_WriteUnraisableMsg("in tp_clear of", + (PyObject*)Py_TYPE(op)); + } + Py_DECREF(op); + } + } + if (GC_NEXT(collectable) == gc) { + /* object is still alive, move it, it may die later */ + 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) +{ + (void)PyMethod_ClearFreeList(); + (void)PyFrame_ClearFreeList(); + (void)PyCFunction_ClearFreeList(); + (void)PyTuple_ClearFreeList(); + (void)PyUnicode_ClearFreeList(); + (void)PyFloat_ClearFreeList(); + (void)PyList_ClearFreeList(); + (void)PyDict_ClearFreeList(); + (void)PySet_ClearFreeList(); + (void)PyAsyncGen_ClearFreeLists(); + (void)PyContext_ClearFreeList(); +} + +// Show stats for objects in each gennerations. +static void +show_stats_each_generations(struct _gc_runtime_state *state) +{ + char buf[100]; + size_t pos = 0; + + for (int i = 0; i < NUM_GENERATIONS && pos < sizeof(buf); i++) { + pos += PyOS_snprintf(buf+pos, sizeof(buf)-pos, + " %"PY_FORMAT_SIZE_T"d", + gc_list_size(GEN_HEAD(state, i))); + } + + PySys_FormatStderr( + "gc: objects in each generation:%s\n" + "gc: objects in permanent generation: %zd\n", + buf, gc_list_size(&state->permanent_generation.head)); +} + +/* This is the main function. Read this to understand how the + * collection process works. */ +static Py_ssize_t +collect(struct _gc_runtime_state *state, 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 */ + + if (state->debug & DEBUG_STATS) { + PySys_WriteStderr("gc: collecting generation %d...\n", generation); + show_stats_each_generations(state); + t1 = _PyTime_GetMonotonicClock(); + } + + if (PyDTrace_GC_START_ENABLED()) + PyDTrace_GC_START(generation); + + /* update collection and allocation counters */ + if (generation+1 < NUM_GENERATIONS) + state->generations[generation+1].count += 1; + for (i = 0; i <= generation; i++) + state->generations[i].count = 0; + + /* merge younger generations with one we are currently collecting */ + for (i = 0; i < generation; i++) { + gc_list_merge(GEN_HEAD(state, i), GEN_HEAD(state, generation)); + } + + /* handy references */ + young = GEN_HEAD(state, generation); + if (generation < NUM_GENERATIONS-1) + old = GEN_HEAD(state, generation+1); + else + old = young; + + validate_list(young, 0); + validate_list(old, 0); + /* Using ob_refcnt and gc_refs, calculate which objects in the + * container set are reachable from outside the set (i.e., have a + * refcount greater than 0 when all the references within the + * set are taken into account). + */ + update_refs(young); // gc_prev is used for gc_refs + subtract_refs(young); + + /* Leave everything reachable from outside young in young, and move + * everything else (in young) to unreachable. + * NOTE: This used to move the reachable objects into a reachable + * set instead. But most things usually turn out to be reachable, + * so it's more efficient to move the unreachable things. + */ + gc_list_init(&unreachable); + move_unreachable(young, &unreachable); // gc_prev is pointer again + validate_list(young, 0); + + untrack_tuples(young); + /* Move reachable objects to next generation. */ + if (young != old) { + if (generation == NUM_GENERATIONS - 2) { + state->long_lived_pending += gc_list_size(young); + } + gc_list_merge(young, old); + } + else { + /* We only untrack dicts in full collections, to avoid quadratic + dict build-up. See issue #14775. */ + untrack_dicts(young); + state->long_lived_pending = 0; + state->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); + // 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); + + validate_list(&finalizers, 0); + validate_list(&unreachable, PREV_MASK_COLLECTING); + + /* Print debugging information. */ + if (state->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); + + validate_list(old, 0); + validate_list(&unreachable, PREV_MASK_COLLECTING); + + /* Call tp_finalize on objects which have one. */ + finalize_garbage(&unreachable); + + if (check_garbage(&unreachable)) { // clear PREV_MASK_COLLECTING here + gc_list_merge(&unreachable, old); + } + else { + /* Call tp_clear on objects in the unreachable set. This will cause + * the reference cycles to be broken. It may also cause some objects + * in finalizers to be freed. + */ + m += gc_list_size(&unreachable); + delete_garbage(state, &unreachable, old); + } + + /* Collect statistics on uncollectable objects found and print + * debugging information. */ + for (gc = GC_NEXT(&finalizers); gc != &finalizers; gc = GC_NEXT(gc)) { + n++; + if (state->debug & DEBUG_UNCOLLECTABLE) + debug_cycle("uncollectable", FROM_GC(gc)); + } + if (state->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. + */ + handle_legacy_finalizers(state, &finalizers, old); + validate_list(old, 0); + + /* Clear free list only during the collection of the highest + * generation */ + if (generation == NUM_GENERATIONS-1) { + clear_freelists(); + } + + if (PyErr_Occurred()) { + if (nofail) { + PyErr_Clear(); + } + else { + if (gc_str == NULL) + gc_str = PyUnicode_FromString("garbage collection"); + PyErr_WriteUnraisable(gc_str); + Py_FatalError("unexpected exception during garbage collection"); + } + } + + /* Update stats */ + if (n_collected) { + *n_collected = m; + } + if (n_uncollectable) { + *n_uncollectable = n; + } + + struct gc_generation_stats *stats = &state->generation_stats[generation]; + stats->collections++; + stats->collected += m; + stats->uncollectable += n; + + if (PyDTrace_GC_DONE_ENABLED()) { + PyDTrace_GC_DONE(n+m); + } + + assert(!PyErr_Occurred()); + return n+m; +} + +/* Invoke progress callbacks to notify clients that garbage collection + * is starting or stopping + */ +static void +invoke_gc_callback(struct _gc_runtime_state *state, const char *phase, + int generation, Py_ssize_t collected, + Py_ssize_t uncollectable) +{ + assert(!PyErr_Occurred()); + + /* we may get called very early */ + if (state->callbacks == NULL) { + return; + } + + /* The local variable cannot be rebound, check it for sanity */ + assert(PyList_CheckExact(state->callbacks)); + PyObject *info = NULL; + if (PyList_GET_SIZE(state->callbacks) != 0) { + 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(state->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); + assert(!PyErr_Occurred()); +} + +/* Perform garbage collection of a generation and invoke + * progress callbacks. + */ +static Py_ssize_t +collect_with_callback(struct _gc_runtime_state *state, int generation) +{ + assert(!PyErr_Occurred()); + Py_ssize_t result, collected, uncollectable; + invoke_gc_callback(state, "start", generation, 0, 0); + result = collect(state, generation, &collected, &uncollectable, 0); + invoke_gc_callback(state, "stop", generation, collected, uncollectable); + assert(!PyErr_Occurred()); + return result; +} + +static Py_ssize_t +collect_generations(struct _gc_runtime_state *state) +{ + /* 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 (state->generations[i].count > state->generations[i].threshold) { + /* Avoid quadratic performance degradation in number + of tracked objects. See comments at the beginning + of this file, and issue #4074. + */ + if (i == NUM_GENERATIONS - 1 + && state->long_lived_pending < state->long_lived_total / 4) + continue; + n = collect_with_callback(state, 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]*/ +{ + _PyRuntime.gc.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]*/ +{ + _PyRuntime.gc.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]*/ +{ + return _PyRuntime.gc.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]*/ +{ + + if (generation < 0 || generation >= NUM_GENERATIONS) { + PyErr_SetString(PyExc_ValueError, "invalid generation"); + return -1; + } + + struct _gc_runtime_state *state = &_PyRuntime.gc; + Py_ssize_t n; + if (state->collecting) { + /* already collecting, don't do anything */ + n = 0; + } + else { + state->collecting = 1; + n = collect_with_callback(state, generation); + state->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]*/ +{ + _PyRuntime.gc.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]*/ +{ + return _PyRuntime.gc.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 * +gc_set_threshold(PyObject *self, PyObject *args) +{ + struct _gc_runtime_state *state = &_PyRuntime.gc; + if (!PyArg_ParseTuple(args, "i|ii:set_threshold", + &state->generations[0].threshold, + &state->generations[1].threshold, + &state->generations[2].threshold)) + return NULL; + for (int i = 3; i < NUM_GENERATIONS; i++) { + /* generations higher than 2 get the same threshold */ + state->generations[i].threshold = state->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]*/ +{ + struct _gc_runtime_state *state = &_PyRuntime.gc; + return Py_BuildValue("(iii)", + state->generations[0].threshold, + state->generations[1].threshold, + state->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]*/ +{ + struct _gc_runtime_state *state = &_PyRuntime.gc; + return Py_BuildValue("(iii)", + state->generations[0].count, + state->generations[1].count, + state->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; + 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) +{ + int i; + if (PySys_Audit("gc.get_referrers", "(O)", args) < 0) { + return NULL; + } + + PyObject *result = PyList_New(0); + if (!result) return NULL; + + struct _gc_runtime_state *state = &_PyRuntime.gc; + for (i = 0; i < NUM_GENERATIONS; i++) { + if (!(gc_referrers_for(args, GEN_HEAD(state, 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; + 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); + + 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 + 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). + +If generation is not None, return only the objects tracked by the collector +that are in that generation. +[clinic start generated code]*/ + +static PyObject * +gc_get_objects_impl(PyObject *module, Py_ssize_t generation) +/*[clinic end generated code: output=48b35fea4ba6cb0e input=ef7da9df9806754c]*/ +{ + int i; + PyObject* result; + struct _gc_runtime_state *state = &_PyRuntime.gc; + + if (PySys_Audit("gc.get_objects", "n", generation) < 0) { + return NULL; + } + + result = PyList_New(0); + if (result == NULL) { + return NULL; + } + + /* If generation is passed, we extract only that generation */ + if (generation != -1) { + if (generation >= NUM_GENERATIONS) { + PyErr_Format(PyExc_ValueError, + "generation parameter must be less than the number of " + "available generations (%i)", + NUM_GENERATIONS); + goto error; + } + + if (generation < 0) { + PyErr_SetString(PyExc_ValueError, + "generation parameter cannot be negative"); + goto error; + } + + if (append_objects(result, GEN_HEAD(state, generation))) { + goto error; + } + + return result; + } + + /* If generation is not passed or None, get all objects from all generations */ + for (i = 0; i < NUM_GENERATIONS; i++) { + if (append_objects(result, GEN_HEAD(state, i))) { + goto error; + } + } + 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; + + /* To get consistent values despite allocations while constructing + the result list, we use a snapshot of the running stats. */ + struct _gc_runtime_state *state = &_PyRuntime.gc; + for (i = 0; i < NUM_GENERATIONS; i++) { + stats[i] = state->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 (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)) + result = Py_True; + else + result = Py_False; + Py_INCREF(result); + return result; +} + +/*[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]*/ +{ + struct _gc_runtime_state *state = &_PyRuntime.gc; + for (int i = 0; i < NUM_GENERATIONS; ++i) { + gc_list_merge(GEN_HEAD(state, i), &state->permanent_generation.head); + state->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]*/ +{ + struct _gc_runtime_state *state = &_PyRuntime.gc; + gc_list_merge(&state->permanent_generation.head, GEN_HEAD(state, 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]*/ +{ + return gc_list_size(&_PyRuntime.gc.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" +"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 + {"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) +{ + PyObject *m; + + m = PyModule_Create(&gcmodule); + + if (m == NULL) { + return NULL; + } + + struct _gc_runtime_state *state = &_PyRuntime.gc; + if (state->garbage == NULL) { + state->garbage = PyList_New(0); + if (state->garbage == NULL) + return NULL; + } + Py_INCREF(state->garbage); + if (PyModule_AddObject(m, "garbage", state->garbage) < 0) + return NULL; + + if (state->callbacks == NULL) { + state->callbacks = PyList_New(0); + if (state->callbacks == NULL) + return NULL; + } + Py_INCREF(state->callbacks); + if (PyModule_AddObject(m, "callbacks", state->callbacks) < 0) + 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) +{ + struct _gc_runtime_state *state = &_PyRuntime.gc; + if (!state->enabled) { + return 0; + } + + Py_ssize_t n; + if (state->collecting) { + /* already collecting, don't do anything */ + n = 0; + } + else { + PyObject *exc, *value, *tb; + state->collecting = 1; + PyErr_Fetch(&exc, &value, &tb); + n = collect_with_callback(state, NUM_GENERATIONS - 1); + PyErr_Restore(exc, value, tb); + state->collecting = 0; + } + + return n; +} + +Py_ssize_t +_PyGC_CollectIfEnabled(void) +{ + return PyGC_Collect(); +} + +Py_ssize_t +_PyGC_CollectNoFail(void) +{ + assert(!PyErr_Occurred()); + + struct _gc_runtime_state *state = &_PyRuntime.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. + */ + if (state->collecting) { + n = 0; + } + else { + state->collecting = 1; + n = collect(state, NUM_GENERATIONS - 1, NULL, NULL, 1); + state->collecting = 0; + } + return n; +} + +void +_PyGC_DumpShutdownStats(_PyRuntimeState *runtime) +{ + struct _gc_runtime_state *state = &runtime->gc; + if (!(state->debug & DEBUG_SAVEALL) + && state->garbage != NULL && PyList_GET_SIZE(state->garbage) > 0) { + const char *message; + if (state->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, + PyList_GET_SIZE(state->garbage))) + PyErr_WriteUnraisable(NULL); + if (state->debug & DEBUG_UNCOLLECTABLE) { + PyObject *repr = NULL, *bytes = NULL; + repr = PyObject_Repr(state->garbage); + if (!repr || !(bytes = PyUnicode_EncodeFSDefault(repr))) + PyErr_WriteUnraisable(state->garbage); + else { + PySys_WriteStderr( + " %s\n", + PyBytes_AS_STRING(bytes) + ); + } + Py_XDECREF(repr); + Py_XDECREF(bytes); + } + } +} + +void +_PyGC_Fini(_PyRuntimeState *runtime) +{ + struct _gc_runtime_state *state = &runtime->gc; + Py_CLEAR(state->garbage); + Py_CLEAR(state->callbacks); +} + +/* for debugging */ +void +_PyGC_Dump(PyGC_Head *g) +{ + _PyObject_Dump(FROM_GC(g)); +} + +/* 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); +} + +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. + */ + if (_PyObject_GC_IS_TRACKED(op)) { + _PyObject_GC_UNTRACK(op); + } +} + +static PyObject * +_PyObject_GC_Alloc(int use_calloc, size_t basicsize) +{ + struct _gc_runtime_state *state = &_PyRuntime.gc; + PyObject *op; + PyGC_Head *g; + size_t size; + if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) + return PyErr_NoMemory(); + size = sizeof(PyGC_Head) + basicsize; + if (use_calloc) + g = (PyGC_Head *)PyObject_Calloc(1, size); + else + g = (PyGC_Head *)PyObject_Malloc(size); + if (g == NULL) + return PyErr_NoMemory(); + assert(((uintptr_t)g & 3) == 0); // g must be aligned 4bytes boundary + g->_gc_next = 0; + g->_gc_prev = 0; + state->generations[0].count++; /* number of allocated GC objects */ + if (state->generations[0].count > state->generations[0].threshold && + state->enabled && + state->generations[0].threshold && + !state->collecting && + !PyErr_Occurred()) { + state->collecting = 1; + collect_generations(state); + state->collecting = 0; + } + 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); + _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); + Py_SIZE(op) = nitems; + return op; +} + +void +PyObject_GC_Del(void *op) +{ + PyGC_Head *g = AS_GC(op); + if (_PyObject_GC_IS_TRACKED(op)) { + gc_list_remove(g); + } + struct _gc_runtime_state *state = &_PyRuntime.gc; + if (state->generations[0].count > 0) { + state->generations[0].count--; + } + PyObject_FREE(g); +} diff --git a/python/Modules/getaddrinfo.c b/python/Modules/getaddrinfo.c new file mode 100755 index 0000000..d33a100 --- /dev/null +++ b/python/Modules/getaddrinfo.c @@ -0,0 +1,661 @@ +/* + * 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. + */ +// #define u_char unsigned char +// #define u_short unsigned short + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HAVE_ADDRINFO +#define HAVE_SOCKADDR_STORAGE + +#include "addrinfo.h" + +#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/python/Modules/getbuildinfo.c b/python/Modules/getbuildinfo.c new file mode 100755 index 0000000..330f6ed --- /dev/null +++ b/python/Modules/getbuildinfo.c @@ -0,0 +1,67 @@ +#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 = "default"; + 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/python/Modules/getnameinfo.c b/python/Modules/getnameinfo.c new file mode 100755 index 0000000..dc13a81 --- /dev/null +++ b/python/Modules/getnameinfo.c @@ -0,0 +1,235 @@ +/* + * 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(). + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HAVE_ADDRINFO +#define HAVE_SOCKADDR_STORAGE + +#include "addrinfo.h" + +#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/python/Modules/getpath.c b/python/Modules/getpath.c new file mode 100755 index 0000000..2c92fc0 --- /dev/null +++ b/python/Modules/getpath.c @@ -0,0 +1,1363 @@ +/* Return the initial module search path. */ + +#include "Python.h" +#include "pycore_initconfig.h" +#include "osdefs.h" +#include "pycore_fileutils.h" +#include "pycore_pathconfig.h" +#include "pycore_pystate.h" + +#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 authomatic path computations. + * + * 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 must be constant defined" +#endif + +#ifndef LANDMARK +#define LANDMARK L"os.py" +#endif + +#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 */ + + wchar_t *pythonpath; /* PYTHONPATH macro */ + wchar_t *prefix; /* PREFIX macro */ + wchar_t *exec_prefix; /* EXEC_PREFIX macro */ + + wchar_t *lib_python; /* "lib/pythonX.Y" */ + + int prefix_found; /* found platform independent libraries? */ + int exec_prefix_found; /* found the platform dependent libraries? */ + + int warnings; + const wchar_t *pythonpath_env; +} 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; + } + dir[i] = '\0'; +} + + +/* Is file, not directory */ +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 module -- check for .pyc too */ +static int +ismodule(wchar_t *filename, size_t filename_len) +{ + if (isfile(filename)) { + return 1; + } + + /* Check for the compiled version of prefix. */ + if (wcslen(filename) + 2 <= filename_len) { + wcscat(filename, L"c"); + if (isfile(filename)) { + return 1; + } + } + return 0; +} + + +/* 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 +isdir(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. + buflen: 'buffer' length in characters including trailing NUL. */ +static PyStatus +joinpath(wchar_t *buffer, const wchar_t *stuff, size_t buflen) +{ + size_t n, k; + if (stuff[0] != SEP) { + n = wcslen(buffer); + if (n >= buflen) { + return PATHLEN_ERR(); + } + + if (n > 0 && buffer[n-1] != SEP) { + buffer[n++] = SEP; + } + } + else { + n = 0; + } + + k = wcslen(stuff); + if (n + k >= buflen) { + return PATHLEN_ERR(); + } + wcsncpy(buffer+n, stuff, k); + buffer[n+k] = '\0'; + + return _PyStatus_OK(); +} + + +static inline int +safe_wcscpy(wchar_t *dst, const wchar_t *src, size_t n) +{ + size_t srclen = wcslen(src); + if (n <= srclen) { + dst[0] = L'\0'; + return -1; + } + memcpy(dst, src, (srclen + 1) * sizeof(wchar_t)); + return 0; +} + + +/* copy_absolute requires that path be allocated at least + 'pathlen' characters (including trailing NUL). */ +static PyStatus +copy_absolute(wchar_t *path, const wchar_t *p, size_t pathlen) +{ + if (p[0] == SEP) { + if (safe_wcscpy(path, p, pathlen) < 0) { + return PATHLEN_ERR(); + } + } + else { + if (!_Py_wgetcwd(path, pathlen)) { + /* unable to get the current directory */ + if (safe_wcscpy(path, p, pathlen) < 0) { + return PATHLEN_ERR(); + } + return _PyStatus_OK(); + } + if (p[0] == '.' && p[1] == SEP) { + p += 2; + } + PyStatus status = joinpath(path, p, pathlen); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +/* path_len: path length in characters including trailing NUL */ +static PyStatus +absolutize(wchar_t *path, size_t path_len) +{ + if (path[0] == SEP) { + return _PyStatus_OK(); + } + + wchar_t abs_path[MAXPATHLEN+1]; + PyStatus status = copy_absolute(abs_path, path, Py_ARRAY_LENGTH(abs_path)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (safe_wcscpy(path, abs_path, path_len) < 0) { + return PATHLEN_ERR(); + } + return _PyStatus_OK(); +} + + +#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, size_t progpathlen) +{ + /* 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(); + } + + if (n + s >= progpathlen) { + return PATHLEN_ERR(); + } + wcsncpy(progpath + n, EXE_SUFFIX, s); + progpath[n+s] = '\0'; + + if (!isxfile(progpath)) { + /* Path that added suffix is invalid: truncate (remove suffix) */ + progpath[n] = '\0'; + } + + return _PyStatus_OK(); +} +#endif + + +/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN + bytes long. +*/ +static PyStatus +search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + const wchar_t *argv0_path, + wchar_t *prefix, size_t prefix_len, int *found) +{ + wchar_t path[MAXPATHLEN+1]; + memset(path, 0, sizeof(path)); + size_t path_len = Py_ARRAY_LENGTH(path); + + PyStatus status; + + /* 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'; + } + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + *found = 1; + return _PyStatus_OK(); + } + + /* Check to see if argv[0] is in the build directory */ + if (safe_wcscpy(path, argv0_path, path_len) < 0) { + return PATHLEN_ERR(); + } + status = joinpath(path, L"Modules/Setup.local", path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (isfile(path)) { + /* Check VPATH to see if argv0_path is in the build directory. + VPATH can be empty. */ + wchar_t *vpath = Py_DecodeLocale(VPATH, NULL); + if (vpath != NULL) { + /* Path: / / Lib / LANDMARK */ + if (safe_wcscpy(prefix, argv0_path, prefix_len) < 0) { + return PATHLEN_ERR(); + } + status = joinpath(prefix, vpath, prefix_len); + PyMem_RawFree(vpath); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = joinpath(prefix, L"Lib", prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + status = joinpath(prefix, LANDMARK, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (ismodule(prefix, prefix_len)) { + *found = -1; + reduce(prefix); + return _PyStatus_OK(); + } + } + } + + /* Search from argv0_path, until root is found */ + status = copy_absolute(prefix, argv0_path, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + do { + /* Path: / / LANDMARK */ + size_t n = wcslen(prefix); + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + status = joinpath(prefix, LANDMARK, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (ismodule(prefix, prefix_len)) { + *found = 1; + reduce(prefix); + return _PyStatus_OK(); + } + prefix[n] = L'\0'; + reduce(prefix); + } while (prefix[0]); + + /* Look at configure's PREFIX. + Path: / / LANDMARK */ + if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) { + return PATHLEN_ERR(); + } + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + status = joinpath(prefix, LANDMARK, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (ismodule(prefix, prefix_len)) { + *found = 1; + reduce(prefix); + return _PyStatus_OK(); + } + + /* Fail */ + *found = 0; + return _PyStatus_OK(); +} + + +static PyStatus +calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + const wchar_t *argv0_path, + wchar_t *prefix, size_t prefix_len) +{ + PyStatus status; + + status = search_for_prefix(calculate, pathconfig, argv0_path, + prefix, prefix_len, + &calculate->prefix_found); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (!calculate->prefix_found) { + if (calculate->warnings) { + fprintf(stderr, + "Could not find platform independent libraries \n"); + } + if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) { + return PATHLEN_ERR(); + } + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +static PyStatus +calculate_set_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + wchar_t *prefix) +{ + /* 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); + reduce(prefix); + /* The prefix is the root directory, but reduce() chopped + * off the "/". */ + if (!prefix[0]) { + wcscpy(prefix, separator); + } + pathconfig->prefix = _PyMem_RawWcsdup(prefix); + } + else { + pathconfig->prefix = _PyMem_RawWcsdup(calculate->prefix); + } + + 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, + int *found) +{ + PyStatus status; + + wchar_t filename[MAXPATHLEN+1]; + memset(filename, 0, sizeof(filename)); + size_t filename_len = Py_ARRAY_LENGTH(filename); + + /* Check to see if argv[0] is in the build directory. "pybuilddir.txt" + is written by setup.py and contains the relative path to the location + of shared library modules. + + Filename: / "pybuilddir.txt" */ + if (safe_wcscpy(filename, argv0_path, filename_len) < 0) { + return PATHLEN_ERR(); + } + status = joinpath(filename, L"pybuilddir.txt", filename_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (!isfile(filename)) { + return _PyStatus_OK(); + } + + FILE *fp = _Py_wfopen(filename, L"rb"); + if (fp == NULL) { + errno = 0; + return _PyStatus_OK(); + } + + char buf[MAXPATHLEN + 1]; + size_t n = fread(buf, 1, Py_ARRAY_LENGTH(buf) - 1, fp); + buf[n] = '\0'; + fclose(fp); + + size_t dec_len; + wchar_t *pybuilddir = _Py_DecodeUTF8_surrogateescape(buf, n, &dec_len); + if (!pybuilddir) { + return DECODE_LOCALE_ERR("pybuilddir.txt", dec_len); + } + + /* Path: / */ + if (safe_wcscpy(exec_prefix, argv0_path, exec_prefix_len) < 0) { + PyMem_RawFree(pybuilddir); + return PATHLEN_ERR(); + } + status = joinpath(exec_prefix, pybuilddir, exec_prefix_len); + PyMem_RawFree(pybuilddir); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + *found = -1; + return _PyStatus_OK(); +} + + +/* 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, + const wchar_t *argv0_path, + wchar_t *exec_prefix, size_t exec_prefix_len, + int *found) +{ + PyStatus status; + + /* If PYTHONHOME is set, we believe it unconditionally */ + if (pathconfig->home) { + /* Path: / / "lib-dynload" */ + wchar_t *delim = wcschr(pathconfig->home, DELIM); + if (delim) { + if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) { + return PATHLEN_ERR(); + } + } + 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(argv0_path, exec_prefix, exec_prefix_len, + found); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + if (*found) { + return _PyStatus_OK(); + } + + /* Search from argv0_path, until root is found */ + status = copy_absolute(exec_prefix, argv0_path, exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + do { + /* Path: / / "lib-dynload" */ + size_t n = wcslen(exec_prefix); + 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; + } + if (isdir(exec_prefix)) { + *found = 1; + return _PyStatus_OK(); + } + exec_prefix[n] = L'\0'; + reduce(exec_prefix); + } while (exec_prefix[0]); + + /* Look at configure's EXEC_PREFIX. + + Path: / / "lib-dynload" */ + if (safe_wcscpy(exec_prefix, calculate->exec_prefix, 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; + } + if (isdir(exec_prefix)) { + *found = 1; + return _PyStatus_OK(); + } + + /* Fail */ + *found = 0; + return _PyStatus_OK(); +} + + +static PyStatus +calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + const wchar_t *argv0_path, + wchar_t *exec_prefix, size_t exec_prefix_len) +{ + PyStatus status; + + status = search_for_exec_prefix(calculate, pathconfig, argv0_path, + exec_prefix, exec_prefix_len, + &calculate->exec_prefix_found); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (!calculate->exec_prefix_found) { + if (calculate->warnings) { + fprintf(stderr, + "Could not find platform dependent libraries \n"); + } + if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) { + return PATHLEN_ERR(); + } + status = joinpath(exec_prefix, L"lib/lib-dynload", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ + return _PyStatus_OK(); +} + + +static PyStatus +calculate_set_exec_prefix(PyCalculatePath *calculate, + _PyPathConfig *pathconfig, + wchar_t *exec_prefix) +{ + if (calculate->exec_prefix_found > 0) { + reduce(exec_prefix); + reduce(exec_prefix); + reduce(exec_prefix); + if (!exec_prefix[0]) { + wcscpy(exec_prefix, separator); + } + + pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix); + } + else { + pathconfig->exec_prefix = _PyMem_RawWcsdup(calculate->exec_prefix); + } + + if (pathconfig->exec_prefix == NULL) { + return _PyStatus_NO_MEMORY(); + } + + return _PyStatus_OK(); +} + + +static PyStatus +calculate_program_full_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) +{ + PyStatus status; + wchar_t program_full_path[MAXPATHLEN + 1]; + const size_t program_full_path_len = Py_ARRAY_LENGTH(program_full_path); + memset(program_full_path, 0, sizeof(program_full_path)); + +#ifdef __APPLE__ + char execpath[MAXPATHLEN + 1]; + uint32_t nsexeclength = Py_ARRAY_LENGTH(execpath) - 1; +#endif + + /* 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)) { + if (safe_wcscpy(program_full_path, pathconfig->program_name, + program_full_path_len) < 0) { + return PATHLEN_ERR(); + } + } +#ifdef __APPLE__ + /* 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. + * If /opt/python2.3/bin isn't in your path, or is near the end, + * this algorithm may incorrectly find /usr/bin/python. To work + * around this, we can use _NSGetExecutablePath to get a better + * hint of what the intended interpreter was, although this + * will fail if a relative path was used. but in that case, + * absolutize() should help us out below + */ + else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && + execpath[0] == SEP) + { + size_t len; + wchar_t *path = Py_DecodeLocale(execpath, &len); + if (path == NULL) { + return DECODE_LOCALE_ERR("executable path", len); + } + if (safe_wcscpy(program_full_path, path, program_full_path_len) < 0) { + PyMem_RawFree(path); + return PATHLEN_ERR(); + } + PyMem_RawFree(path); + } +#endif /* __APPLE__ */ + else if (calculate->path_env) { + wchar_t *path = calculate->path_env; + while (1) { + wchar_t *delim = wcschr(path, DELIM); + + if (delim) { + size_t len = delim - path; + if (len >= program_full_path_len) { + return PATHLEN_ERR(); + } + wcsncpy(program_full_path, path, len); + program_full_path[len] = '\0'; + } + else { + if (safe_wcscpy(program_full_path, path, + program_full_path_len) < 0) { + return PATHLEN_ERR(); + } + } + + status = joinpath(program_full_path, pathconfig->program_name, + program_full_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (isxfile(program_full_path)) { + break; + } + + if (!delim) { + program_full_path[0] = L'\0'; + break; + } + path = delim + 1; + } + } + else { + program_full_path[0] = '\0'; + } + if (program_full_path[0] != SEP && program_full_path[0] != '\0') { + status = absolutize(program_full_path, program_full_path_len); + 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 + * sys.executable to return the name of a directory under the same + * path (bpo-28441). + */ + if (program_full_path[0] != '\0') { + status = add_exe_suffix(program_full_path, program_full_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } +#endif + + pathconfig->program_full_path = _PyMem_RawWcsdup(program_full_path); + if (pathconfig->program_full_path == NULL) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} + + +static PyStatus +calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path, + wchar_t *argv0_path, size_t argv0_path_len) +{ + if (safe_wcscpy(argv0_path, program_full_path, argv0_path_len) < 0) { + return PATHLEN_ERR(); + } + +#ifdef WITH_NEXT_FRAMEWORK + NSModule pythonModule; + + /* On Mac OS X we have a special case if we're running from a framework. + ** This is because the python home should be set relative to the library, + ** which is in the framework, not relative to the executable, which may + ** be outside of the framework. Except when we're in the build directory... + */ + pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); + /* Use dylib functions to find out where the framework was loaded from */ + const char* modPath = NSLibraryNameForModule(pythonModule); + if (modPath != NULL) { + /* We're in a framework. */ + /* See if we might be in the build directory. The framework in the + ** build directory is incomplete, it only has the .dylib and a few + ** needed symlinks, it doesn't have the Lib directories and such. + ** If we're running with the framework from the build directory we must + ** be running the interpreter in the build directory, so we use the + ** build-directory-specific logic to find Lib and such. + */ + PyStatus status; + size_t len; + wchar_t* wbuf = Py_DecodeLocale(modPath, &len); + if (wbuf == NULL) { + return DECODE_LOCALE_ERR("framework location", len); + } + + if (safe_wcscpy(argv0_path, wbuf, argv0_path_len) < 0) { + return PATHLEN_ERR(); + } + reduce(argv0_path); + status = joinpath(argv0_path, calculate->lib_python, argv0_path_len); + if (_PyStatus_EXCEPTION(status)) { + PyMem_RawFree(wbuf); + return status; + } + status = joinpath(argv0_path, LANDMARK, argv0_path_len); + if (_PyStatus_EXCEPTION(status)) { + PyMem_RawFree(wbuf); + return status; + } + if (!ismodule(argv0_path, Py_ARRAY_LENGTH(argv0_path))) { + /* We are in the build directory so use the name of the + executable - we know that the absolute path is passed */ + if (safe_wcscpy(argv0_path, program_full_path, + argv0_path_len) < 0) { + return PATHLEN_ERR(); + } + } + else { + /* Use the location of the library as the program_full_path */ + if (safe_wcscpy(argv0_path, wbuf, argv0_path_len) < 0) { + return PATHLEN_ERR(); + } + } + PyMem_RawFree(wbuf); + } +#endif + +#if HAVE_READLINK + wchar_t tmpbuffer[MAXPATHLEN + 1]; + const size_t buflen = Py_ARRAY_LENGTH(tmpbuffer); + int linklen = _Py_wreadlink(program_full_path, tmpbuffer, buflen); + while (linklen != -1) { + if (tmpbuffer[0] == SEP) { + /* tmpbuffer should never be longer than MAXPATHLEN, + but extra check does not hurt */ + if (safe_wcscpy(argv0_path, tmpbuffer, argv0_path_len) < 0) { + return PATHLEN_ERR(); + } + } + else { + /* Interpret relative to program_full_path */ + PyStatus status; + reduce(argv0_path); + status = joinpath(argv0_path, tmpbuffer, argv0_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + linklen = _Py_wreadlink(argv0_path, tmpbuffer, buflen); + } +#endif /* HAVE_READLINK */ + + reduce(argv0_path); + /* At this point, argv0_path is guaranteed to be less than + MAXPATHLEN bytes long. */ + 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. +*/ +static PyStatus +calculate_read_pyenv(PyCalculatePath *calculate, + wchar_t *argv0_path, size_t argv0_path_len) +{ + PyStatus status; + const wchar_t *env_cfg = L"pyvenv.cfg"; + FILE *env_file; + + wchar_t filename[MAXPATHLEN+1]; + const size_t filename_len = Py_ARRAY_LENGTH(filename); + memset(filename, 0, sizeof(filename)); + + /* Filename: / "pyvenv.cfg" */ + if (safe_wcscpy(filename, argv0_path, filename_len) < 0) { + return PATHLEN_ERR(); + } + + status = joinpath(filename, env_cfg, filename_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + env_file = _Py_wfopen(filename, L"r"); + if (env_file == NULL) { + errno = 0; + + /* Filename: / "pyvenv.cfg" */ + reduce(filename); + reduce(filename); + status = joinpath(filename, env_cfg, filename_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + env_file = _Py_wfopen(filename, L"r"); + if (env_file == NULL) { + errno = 0; + return _PyStatus_OK(); + } + } + + /* Look for a 'home' variable and set argv0_path to it, if found */ + wchar_t home[MAXPATHLEN+1]; + memset(home, 0, sizeof(home)); + + if (_Py_FindEnvConfigValue(env_file, L"home", + home, Py_ARRAY_LENGTH(home))) { + if (safe_wcscpy(argv0_path, home, argv0_path_len) < 0) { + fclose(env_file); + return PATHLEN_ERR(); + } + } + fclose(env_file); + return _PyStatus_OK(); +} + + +static PyStatus +calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix, + wchar_t *zip_path, size_t zip_path_len) +{ + PyStatus status; + + if (calculate->prefix_found > 0) { + /* Use the reduced prefix returned by Py_GetPrefix() */ + if (safe_wcscpy(zip_path, prefix, zip_path_len) < 0) { + return PATHLEN_ERR(); + } + reduce(zip_path); + reduce(zip_path); + } + else { + if (safe_wcscpy(zip_path, calculate->prefix, zip_path_len) < 0) { + return PATHLEN_ERR(); + } + } + status = joinpath(zip_path, L"lib/python3.8", zip_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* Replace "00" with version */ + // size_t bufsz = wcslen(zip_path); + // zip_path[bufsz - 6] = VERSION[0]; + // zip_path[bufsz - 5] = VERSION[2]; + return _PyStatus_OK(); +} + + +static PyStatus +calculate_module_search_path(PyCalculatePath *calculate, + _PyPathConfig *pathconfig, + const wchar_t *prefix, + const wchar_t *exec_prefix, + const wchar_t *zip_path) +{ + /* 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; + size_t prefixsz = wcslen(prefix) + 1; + while (1) { + wchar_t *delim = wcschr(defpath, DELIM); + + if (defpath[0] != SEP) { + /* Paths are relative to prefix */ + bufsz += prefixsz; + } + + if (delim) { + bufsz += delim - defpath + 1; + } + else { + bufsz += wcslen(defpath) + 1; + break; + } + defpath = delim + 1; + } + + bufsz += wcslen(zip_path) + 1; + bufsz += wcslen(exec_prefix) + 1; + + /* 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 */ + if (calculate->pythonpath_env) { + wcscpy(buf, calculate->pythonpath_env); + wcscat(buf, delimiter); + } + + /* Next is the default zip path */ + wcscat(buf, zip_path); + wcscat(buf, delimiter); + + /* Next goes merge of compile-time $PYTHONPATH with + * dynamically located prefix. + */ + defpath = calculate->pythonpath; + while (1) { + wchar_t *delim = wcschr(defpath, DELIM); + + if (defpath[0] != SEP) { + wcscat(buf, prefix); + if (prefixsz >= 2 && 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 */ + wcscat(buf, exec_prefix); + + pathconfig->module_search_path = buf; + return _PyStatus_OK(); +} + + +static PyStatus +calculate_init(PyCalculatePath *calculate, const PyConfig *config) +{ + size_t 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); + } + } + + calculate->pythonpath = Py_DecodeLocale(PYTHONPATH, &len); + if (!calculate->pythonpath) { + return DECODE_LOCALE_ERR("PYTHONPATH define", len); + } + + calculate->prefix = Py_DecodeLocale(PREFIX, &len); + if (!calculate->prefix) { + return DECODE_LOCALE_ERR("PREFIX define", len); + } + calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len); + if (!calculate->exec_prefix) { + return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); + } + calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len); + if (!calculate->lib_python) { + return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); + } + + calculate->warnings = config->pathconfig_warnings; + calculate->pythonpath_env = config->pythonpath_env; + + return _PyStatus_OK(); +} + + +static void +calculate_free(PyCalculatePath *calculate) +{ + PyMem_RawFree(calculate->pythonpath); + PyMem_RawFree(calculate->prefix); + PyMem_RawFree(calculate->exec_prefix); + PyMem_RawFree(calculate->lib_python); + PyMem_RawFree(calculate->path_env); +} + + +static PyStatus +calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) +{ + PyStatus status; + + if (pathconfig->program_full_path == NULL) { + status = calculate_program_full_path(calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + wchar_t argv0_path[MAXPATHLEN+1]; + memset(argv0_path, 0, sizeof(argv0_path)); + + status = calculate_argv0_path(calculate, pathconfig->program_full_path, + argv0_path, Py_ARRAY_LENGTH(argv0_path)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* If a pyvenv.cfg configure file is found, + argv0_path is overriden with its 'home' variable. */ + status = calculate_read_pyenv(calculate, + argv0_path, Py_ARRAY_LENGTH(argv0_path)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + wchar_t prefix[MAXPATHLEN+1]; + memset(prefix, 0, sizeof(prefix)); + status = calculate_prefix(calculate, pathconfig, + argv0_path, + prefix, Py_ARRAY_LENGTH(prefix)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + wchar_t zip_path[MAXPATHLEN+1]; /* ".../lib/pythonXY.zip" */ + memset(zip_path, 0, sizeof(zip_path)); + + status = calculate_zip_path(calculate, prefix, + zip_path, Py_ARRAY_LENGTH(zip_path)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + wchar_t exec_prefix[MAXPATHLEN+1]; + memset(exec_prefix, 0, sizeof(exec_prefix)); + status = calculate_exec_prefix(calculate, pathconfig, argv0_path, + exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if ((!calculate->prefix_found || !calculate->exec_prefix_found) && + calculate->warnings) + { + fprintf(stderr, + "Consider setting $PYTHONHOME to [:]\n"); + } + + if (pathconfig->module_search_path == NULL) { + status = calculate_module_search_path(calculate, pathconfig, + prefix, exec_prefix, zip_path); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (pathconfig->prefix == NULL) { + status = calculate_set_prefix(calculate, pathconfig, prefix); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (pathconfig->exec_prefix == NULL) { + status = calculate_set_exec_prefix(calculate, pathconfig, exec_prefix); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + return _PyStatus_OK(); +} + + +/* Calculate the Python path configuration. + + Inputs: + + - PATH environment variable + - Macros: PYTHONPATH, PREFIX, EXEC_PREFIX, VERSION (ex: "3.9"). + PREFIX and EXEC_PREFIX are generated by the configure script. + PYTHONPATH macro is the default search path. + - pybuilddir.txt file + - pyvenv.cfg configuration file + - PyConfig fields ('config' function argument): + + - pathconfig_warnings + - pythonpath_env (PYTHONPATH environment variable) + + - _PyPathConfig fields ('pathconfig' function argument): + + - program_name: see config_init_program_name() + - home: Py_SetPythonHome() or PYTHONHOME environment variable + + - current working directory: see copy_absolute() + + Outputs, 'pathconfig' fields: + + - program_full_path + - module_search_path + - prefix + - exec_prefix + + 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)); + + status = calculate_init(&calculate, config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = calculate_path(&calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = _PyStatus_OK(); + +done: + calculate_free(&calculate); + return status; +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Modules/grpmodule.c b/python/Modules/grpmodule.c new file mode 100755 index 0000000..ab766b9 --- /dev/null +++ b/python/Modules/grpmodule.c @@ -0,0 +1,349 @@ + +/* 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, +}; + + +static int initialized; +static PyTypeObject StructGrpType; + +#define DEFAULT_BUFFER_SIZE 1024 + +static PyObject * +mkgrent(struct group *p) +{ + int setIndex = 0; + PyObject *v = PyStructSequence_New(&StructGrpType), *w; + char **member; + + if (v == 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]*/ +{ + 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", + id->ob_type->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); + } +#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) { + bufsize = DEFAULT_BUFFER_SIZE; + } + + while (1) { + buf2 = PyMem_RawRealloc(buf, bufsize); + if (buf2 == NULL) { + p = NULL; + nomem = 1; + break; + } + buf = buf2; + status = getgrgid_r(gid, &grp, buf, bufsize, &p); + if (status != 0) { + p = NULL; + } + if (p != NULL || status != ERANGE) { + break; + } + if (bufsize > (PY_SSIZE_T_MAX >> 1)) { + nomem = 1; + break; + } + bufsize <<= 1; + } + + Py_END_ALLOW_THREADS +#else + p = getgrgid(gid); +#endif + if (p == NULL) { + PyMem_RawFree(buf); + 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; + } + 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]*/ +{ + 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; +#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) { + bufsize = DEFAULT_BUFFER_SIZE; + } + + while(1) { + buf2 = PyMem_RawRealloc(buf, bufsize); + if (buf2 == NULL) { + p = NULL; + nomem = 1; + break; + } + buf = buf2; + status = getgrnam_r(name_chars, &grp, buf, bufsize, &p); + if (status != 0) { + p = NULL; + } + if (p != NULL || status != ERANGE) { + break; + } + if (bufsize > (PY_SSIZE_T_MAX >> 1)) { + nomem = 1; + break; + } + bufsize <<= 1; + } + + Py_END_ALLOW_THREADS +#else + p = getgrnam(name_chars); +#endif + if (p == NULL) { + if (nomem == 1) { + PyErr_NoMemory(); + } + else { + PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %R", name); + } + 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.)"); + + + +static struct PyModuleDef grpmodule = { + PyModuleDef_HEAD_INIT, + "grp", + grp__doc__, + -1, + grp_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_grp(void) +{ + PyObject *m, *d; + m = PyModule_Create(&grpmodule); + if (m == NULL) + return NULL; + d = PyModule_GetDict(m); + if (!initialized) { + if (PyStructSequence_InitType2(&StructGrpType, + &struct_group_type_desc) < 0) + return NULL; + } + if (PyDict_SetItemString(d, "struct_group", + (PyObject *)&StructGrpType) < 0) + return NULL; + initialized = 1; + return m; +} diff --git a/python/Modules/hashlib.h b/python/Modules/hashlib.h new file mode 100755 index 0000000..978593e --- /dev/null +++ b/python/Modules/hashlib.h @@ -0,0 +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, \ + "Unicode-objects 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 + diff --git a/python/Modules/hashtable.c b/python/Modules/hashtable.c new file mode 100755 index 0000000..4a36a1e --- /dev/null +++ b/python/Modules/hashtable.c @@ -0,0 +1,524 @@ +/* The implementation of the hash table (_Py_hashtable_t) is based on the + cfuhash project: + http://sourceforge.net/projects/libcfu/ + + Copyright of cfuhash: + ---------------------------------- + Creation date: 2005-06-24 21:22:40 + Authors: Don + Change log: + + Copyright (c) 2005 Don Owens + All rights reserved. + + This code is released under the BSD license: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the author 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 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. + ---------------------------------- +*/ + +#include "Python.h" +#include "hashtable.h" + +#define HASHTABLE_MIN_SIZE 16 +#define HASHTABLE_HIGH 0.50 +#define HASHTABLE_LOW 0.10 +#define HASHTABLE_REHASH_FACTOR 2.0 / (HASHTABLE_LOW + HASHTABLE_HIGH) + +#define BUCKETS_HEAD(SLIST) \ + ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(SLIST))) +#define TABLE_HEAD(HT, BUCKET) \ + ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(HT)->buckets[BUCKET])) +#define ENTRY_NEXT(ENTRY) \ + ((_Py_hashtable_entry_t *)_Py_SLIST_ITEM_NEXT(ENTRY)) +#define HASHTABLE_ITEM_SIZE(HT) \ + (sizeof(_Py_hashtable_entry_t) + (HT)->key_size + (HT)->data_size) + +#define ENTRY_READ_PDATA(TABLE, ENTRY, DATA_SIZE, PDATA) \ + do { \ + assert((DATA_SIZE) == (TABLE)->data_size); \ + memcpy((PDATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \ + (DATA_SIZE)); \ + } while (0) + +#define ENTRY_WRITE_PDATA(TABLE, ENTRY, DATA_SIZE, PDATA) \ + do { \ + assert((DATA_SIZE) == (TABLE)->data_size); \ + memcpy((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \ + (PDATA), (DATA_SIZE)); \ + } while (0) + +/* Forward declaration */ +static void hashtable_rehash(_Py_hashtable_t *ht); + +static void +_Py_slist_init(_Py_slist_t *list) +{ + list->head = NULL; +} + + +static void +_Py_slist_prepend(_Py_slist_t *list, _Py_slist_item_t *item) +{ + item->next = list->head; + list->head = item; +} + + +static void +_Py_slist_remove(_Py_slist_t *list, _Py_slist_item_t *previous, + _Py_slist_item_t *item) +{ + if (previous != NULL) + previous->next = item->next; + else + list->head = item->next; +} + + +Py_uhash_t +_Py_hashtable_hash_ptr(struct _Py_hashtable_t *ht, const void *pkey) +{ + void *key; + + _Py_HASHTABLE_READ_KEY(ht, pkey, key); + return (Py_uhash_t)_Py_HashPointer(key); +} + + +int +_Py_hashtable_compare_direct(_Py_hashtable_t *ht, const void *pkey, + const _Py_hashtable_entry_t *entry) +{ + const void *pkey2 = _Py_HASHTABLE_ENTRY_PKEY(entry); + return (memcmp(pkey, pkey2, ht->key_size) == 0); +} + + +/* makes sure the real size of the buckets array is a power of 2 */ +static size_t +round_size(size_t s) +{ + size_t i; + if (s < HASHTABLE_MIN_SIZE) + return HASHTABLE_MIN_SIZE; + i = 1; + while (i < s) + i <<= 1; + return i; +} + + +_Py_hashtable_t * +_Py_hashtable_new_full(size_t key_size, size_t data_size, + size_t init_size, + _Py_hashtable_hash_func hash_func, + _Py_hashtable_compare_func compare_func, + _Py_hashtable_allocator_t *allocator) +{ + _Py_hashtable_t *ht; + size_t buckets_size; + _Py_hashtable_allocator_t alloc; + + if (allocator == NULL) { + alloc.malloc = PyMem_RawMalloc; + alloc.free = PyMem_RawFree; + } + else + alloc = *allocator; + + ht = (_Py_hashtable_t *)alloc.malloc(sizeof(_Py_hashtable_t)); + if (ht == NULL) + return ht; + + ht->num_buckets = round_size(init_size); + ht->entries = 0; + ht->key_size = key_size; + ht->data_size = data_size; + + buckets_size = ht->num_buckets * sizeof(ht->buckets[0]); + ht->buckets = alloc.malloc(buckets_size); + if (ht->buckets == NULL) { + alloc.free(ht); + return NULL; + } + memset(ht->buckets, 0, buckets_size); + + ht->hash_func = hash_func; + ht->compare_func = compare_func; + ht->alloc = alloc; + return ht; +} + + +_Py_hashtable_t * +_Py_hashtable_new(size_t key_size, size_t data_size, + _Py_hashtable_hash_func hash_func, + _Py_hashtable_compare_func compare_func) +{ + return _Py_hashtable_new_full(key_size, data_size, + HASHTABLE_MIN_SIZE, + hash_func, compare_func, + NULL); +} + + +size_t +_Py_hashtable_size(_Py_hashtable_t *ht) +{ + size_t size; + + size = sizeof(_Py_hashtable_t); + + /* buckets */ + size += ht->num_buckets * sizeof(_Py_hashtable_entry_t *); + + /* entries */ + size += ht->entries * HASHTABLE_ITEM_SIZE(ht); + + return size; +} + + +#ifdef Py_DEBUG +void +_Py_hashtable_print_stats(_Py_hashtable_t *ht) +{ + size_t size; + size_t chain_len, max_chain_len, total_chain_len, nchains; + _Py_hashtable_entry_t *entry; + size_t hv; + double load; + + size = _Py_hashtable_size(ht); + + load = (double)ht->entries / ht->num_buckets; + + max_chain_len = 0; + total_chain_len = 0; + nchains = 0; + for (hv = 0; hv < ht->num_buckets; hv++) { + entry = TABLE_HEAD(ht, hv); + if (entry != NULL) { + chain_len = 0; + for (; entry; entry = ENTRY_NEXT(entry)) { + chain_len++; + } + if (chain_len > max_chain_len) + max_chain_len = chain_len; + total_chain_len += chain_len; + nchains++; + } + } + printf("hash table %p: entries=%" + PY_FORMAT_SIZE_T "u/%" PY_FORMAT_SIZE_T "u (%.0f%%), ", + (void *)ht, ht->entries, ht->num_buckets, load * 100.0); + if (nchains) + printf("avg_chain_len=%.1f, ", (double)total_chain_len / nchains); + printf("max_chain_len=%" PY_FORMAT_SIZE_T "u, %" PY_FORMAT_SIZE_T "u KiB\n", + max_chain_len, size / 1024); +} +#endif + + +_Py_hashtable_entry_t * +_Py_hashtable_get_entry(_Py_hashtable_t *ht, + size_t key_size, const void *pkey) +{ + Py_uhash_t key_hash; + size_t index; + _Py_hashtable_entry_t *entry; + + assert(key_size == ht->key_size); + + key_hash = ht->hash_func(ht, pkey); + index = key_hash & (ht->num_buckets - 1); + + for (entry = TABLE_HEAD(ht, index); entry != NULL; entry = ENTRY_NEXT(entry)) { + if (entry->key_hash == key_hash && ht->compare_func(ht, pkey, entry)) + break; + } + + return entry; +} + + +static int +_Py_hashtable_pop_entry(_Py_hashtable_t *ht, size_t key_size, const void *pkey, + void *data, size_t data_size) +{ + Py_uhash_t key_hash; + size_t index; + _Py_hashtable_entry_t *entry, *previous; + + assert(key_size == ht->key_size); + + key_hash = ht->hash_func(ht, pkey); + index = key_hash & (ht->num_buckets - 1); + + previous = NULL; + for (entry = TABLE_HEAD(ht, index); entry != NULL; entry = ENTRY_NEXT(entry)) { + if (entry->key_hash == key_hash && ht->compare_func(ht, pkey, entry)) + break; + previous = entry; + } + + if (entry == NULL) + return 0; + + _Py_slist_remove(&ht->buckets[index], (_Py_slist_item_t *)previous, + (_Py_slist_item_t *)entry); + ht->entries--; + + if (data != NULL) + ENTRY_READ_PDATA(ht, entry, data_size, data); + ht->alloc.free(entry); + + if ((float)ht->entries / (float)ht->num_buckets < HASHTABLE_LOW) + hashtable_rehash(ht); + return 1; +} + + +int +_Py_hashtable_set(_Py_hashtable_t *ht, size_t key_size, const void *pkey, + size_t data_size, const void *data) +{ + Py_uhash_t key_hash; + size_t index; + _Py_hashtable_entry_t *entry; + + assert(key_size == ht->key_size); + + assert(data != NULL || data_size == 0); +#ifndef NDEBUG + /* Don't write the assertion on a single line because it is interesting + to know the duplicated entry if the assertion failed. The entry can + be read using a debugger. */ + entry = _Py_hashtable_get_entry(ht, key_size, pkey); + assert(entry == NULL); +#endif + + key_hash = ht->hash_func(ht, pkey); + index = key_hash & (ht->num_buckets - 1); + + entry = ht->alloc.malloc(HASHTABLE_ITEM_SIZE(ht)); + if (entry == NULL) { + /* memory allocation failed */ + return -1; + } + + entry->key_hash = key_hash; + memcpy((void *)_Py_HASHTABLE_ENTRY_PKEY(entry), pkey, ht->key_size); + if (data) + ENTRY_WRITE_PDATA(ht, entry, data_size, data); + + _Py_slist_prepend(&ht->buckets[index], (_Py_slist_item_t*)entry); + ht->entries++; + + if ((float)ht->entries / (float)ht->num_buckets > HASHTABLE_HIGH) + hashtable_rehash(ht); + return 0; +} + + +int +_Py_hashtable_get(_Py_hashtable_t *ht, size_t key_size,const void *pkey, + size_t data_size, void *data) +{ + _Py_hashtable_entry_t *entry; + + assert(data != NULL); + + entry = _Py_hashtable_get_entry(ht, key_size, pkey); + if (entry == NULL) + return 0; + ENTRY_READ_PDATA(ht, entry, data_size, data); + return 1; +} + + +int +_Py_hashtable_pop(_Py_hashtable_t *ht, size_t key_size, const void *pkey, + size_t data_size, void *data) +{ + assert(data != NULL); + return _Py_hashtable_pop_entry(ht, key_size, pkey, data, data_size); +} + + +/* Code commented since the function is not needed in Python */ +#if 0 +void +_Py_hashtable_delete(_Py_hashtable_t *ht, size_t key_size, const void *pkey) +{ +#ifndef NDEBUG + int found = _Py_hashtable_pop_entry(ht, key_size, pkey, NULL, 0); + assert(found); +#else + (void)_Py_hashtable_pop_entry(ht, key_size, pkey, NULL, 0); +#endif +} +#endif + + +int +_Py_hashtable_foreach(_Py_hashtable_t *ht, + _Py_hashtable_foreach_func func, + void *arg) +{ + _Py_hashtable_entry_t *entry; + size_t hv; + + for (hv = 0; hv < ht->num_buckets; hv++) { + for (entry = TABLE_HEAD(ht, hv); entry; entry = ENTRY_NEXT(entry)) { + int res = func(ht, entry, arg); + if (res) + return res; + } + } + return 0; +} + + +static void +hashtable_rehash(_Py_hashtable_t *ht) +{ + size_t buckets_size, new_size, bucket; + _Py_slist_t *old_buckets = NULL; + size_t old_num_buckets; + + new_size = round_size((size_t)(ht->entries * HASHTABLE_REHASH_FACTOR)); + if (new_size == ht->num_buckets) + return; + + old_num_buckets = ht->num_buckets; + + buckets_size = new_size * sizeof(ht->buckets[0]); + old_buckets = ht->buckets; + ht->buckets = ht->alloc.malloc(buckets_size); + if (ht->buckets == NULL) { + /* cancel rehash on memory allocation failure */ + ht->buckets = old_buckets ; + /* memory allocation failed */ + return; + } + memset(ht->buckets, 0, buckets_size); + + ht->num_buckets = new_size; + + for (bucket = 0; bucket < old_num_buckets; bucket++) { + _Py_hashtable_entry_t *entry, *next; + for (entry = BUCKETS_HEAD(old_buckets[bucket]); entry != NULL; entry = next) { + size_t entry_index; + + + assert(ht->hash_func(ht, _Py_HASHTABLE_ENTRY_PKEY(entry)) == entry->key_hash); + next = ENTRY_NEXT(entry); + entry_index = entry->key_hash & (new_size - 1); + + _Py_slist_prepend(&ht->buckets[entry_index], (_Py_slist_item_t*)entry); + } + } + + ht->alloc.free(old_buckets); +} + + +void +_Py_hashtable_clear(_Py_hashtable_t *ht) +{ + _Py_hashtable_entry_t *entry, *next; + size_t i; + + for (i=0; i < ht->num_buckets; i++) { + for (entry = TABLE_HEAD(ht, i); entry != NULL; entry = next) { + next = ENTRY_NEXT(entry); + ht->alloc.free(entry); + } + _Py_slist_init(&ht->buckets[i]); + } + ht->entries = 0; + hashtable_rehash(ht); +} + + +void +_Py_hashtable_destroy(_Py_hashtable_t *ht) +{ + size_t i; + + for (i = 0; i < ht->num_buckets; i++) { + _Py_slist_item_t *entry = ht->buckets[i].head; + while (entry) { + _Py_slist_item_t *entry_next = entry->next; + ht->alloc.free(entry); + entry = entry_next; + } + } + + ht->alloc.free(ht->buckets); + ht->alloc.free(ht); +} + + +_Py_hashtable_t * +_Py_hashtable_copy(_Py_hashtable_t *src) +{ + const size_t key_size = src->key_size; + const size_t data_size = src->data_size; + _Py_hashtable_t *dst; + _Py_hashtable_entry_t *entry; + size_t bucket; + int err; + + dst = _Py_hashtable_new_full(key_size, data_size, + src->num_buckets, + src->hash_func, + src->compare_func, + &src->alloc); + if (dst == NULL) + return NULL; + + for (bucket=0; bucket < src->num_buckets; bucket++) { + entry = TABLE_HEAD(src, bucket); + for (; entry; entry = ENTRY_NEXT(entry)) { + const void *pkey = _Py_HASHTABLE_ENTRY_PKEY(entry); + const void *pdata = _Py_HASHTABLE_ENTRY_PDATA(src, entry); + err = _Py_hashtable_set(dst, key_size, pkey, data_size, pdata); + if (err) { + _Py_hashtable_destroy(dst); + return NULL; + } + } + } + return dst; +} diff --git a/python/Modules/hashtable.h b/python/Modules/hashtable.h new file mode 100755 index 0000000..dbec23d --- /dev/null +++ b/python/Modules/hashtable.h @@ -0,0 +1,211 @@ +#ifndef Py_HASHTABLE_H +#define Py_HASHTABLE_H +/* The whole API is private */ +#ifndef Py_LIMITED_API + +/* Single linked list */ + +typedef struct _Py_slist_item_s { + struct _Py_slist_item_s *next; +} _Py_slist_item_t; + +typedef struct { + _Py_slist_item_t *head; +} _Py_slist_t; + +#define _Py_SLIST_ITEM_NEXT(ITEM) (((_Py_slist_item_t *)ITEM)->next) + +#define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head) + + +/* _Py_hashtable: table entry */ + +typedef struct { + /* used by _Py_hashtable_t.buckets to link entries */ + _Py_slist_item_t _Py_slist_item; + + Py_uhash_t key_hash; + + /* key (key_size bytes) and then data (data_size bytes) follows */ +} _Py_hashtable_entry_t; + +#define _Py_HASHTABLE_ENTRY_PKEY(ENTRY) \ + ((const void *)((char *)(ENTRY) \ + + sizeof(_Py_hashtable_entry_t))) + +#define _Py_HASHTABLE_ENTRY_PDATA(TABLE, ENTRY) \ + ((const void *)((char *)(ENTRY) \ + + sizeof(_Py_hashtable_entry_t) \ + + (TABLE)->key_size)) + +/* Get a key value from pkey: use memcpy() rather than a pointer dereference + to avoid memory alignment issues. */ +#define _Py_HASHTABLE_READ_KEY(TABLE, PKEY, DST_KEY) \ + do { \ + assert(sizeof(DST_KEY) == (TABLE)->key_size); \ + memcpy(&(DST_KEY), (PKEY), sizeof(DST_KEY)); \ + } while (0) + +#define _Py_HASHTABLE_ENTRY_READ_KEY(TABLE, ENTRY, KEY) \ + do { \ + assert(sizeof(KEY) == (TABLE)->key_size); \ + memcpy(&(KEY), _Py_HASHTABLE_ENTRY_PKEY(ENTRY), sizeof(KEY)); \ + } while (0) + +#define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, ENTRY, DATA) \ + do { \ + assert(sizeof(DATA) == (TABLE)->data_size); \ + memcpy(&(DATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \ + sizeof(DATA)); \ + } while (0) + +#define _Py_HASHTABLE_ENTRY_WRITE_DATA(TABLE, ENTRY, DATA) \ + do { \ + assert(sizeof(DATA) == (TABLE)->data_size); \ + memcpy((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \ + &(DATA), sizeof(DATA)); \ + } while (0) + + +/* _Py_hashtable: prototypes */ + +/* Forward declaration */ +struct _Py_hashtable_t; + +typedef Py_uhash_t (*_Py_hashtable_hash_func) (struct _Py_hashtable_t *ht, + const void *pkey); +typedef int (*_Py_hashtable_compare_func) (struct _Py_hashtable_t *ht, + const void *pkey, + const _Py_hashtable_entry_t *he); + +typedef struct { + /* allocate a memory block */ + void* (*malloc) (size_t size); + + /* release a memory block */ + void (*free) (void *ptr); +} _Py_hashtable_allocator_t; + + +/* _Py_hashtable: table */ + +typedef struct _Py_hashtable_t { + size_t num_buckets; + size_t entries; /* Total number of entries in the table. */ + _Py_slist_t *buckets; + size_t key_size; + size_t data_size; + + _Py_hashtable_hash_func hash_func; + _Py_hashtable_compare_func compare_func; + _Py_hashtable_allocator_t alloc; +} _Py_hashtable_t; + +/* hash a pointer (void*) */ +PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr( + struct _Py_hashtable_t *ht, + const void *pkey); + +/* comparison using memcmp() */ +PyAPI_FUNC(int) _Py_hashtable_compare_direct( + _Py_hashtable_t *ht, + const void *pkey, + const _Py_hashtable_entry_t *entry); + +PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new( + size_t key_size, + size_t data_size, + _Py_hashtable_hash_func hash_func, + _Py_hashtable_compare_func compare_func); + +PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full( + size_t key_size, + size_t data_size, + size_t init_size, + _Py_hashtable_hash_func hash_func, + _Py_hashtable_compare_func compare_func, + _Py_hashtable_allocator_t *allocator); + +PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht); + +/* Return a copy of the hash table */ +PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_copy(_Py_hashtable_t *src); + +PyAPI_FUNC(void) _Py_hashtable_clear(_Py_hashtable_t *ht); + +typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_t *ht, + _Py_hashtable_entry_t *entry, + void *arg); + +/* Call func() on each entry of the hashtable. + Iteration stops if func() result is non-zero, in this case it's the result + of the call. Otherwise, the function returns 0. */ +PyAPI_FUNC(int) _Py_hashtable_foreach( + _Py_hashtable_t *ht, + _Py_hashtable_foreach_func func, + void *arg); + +PyAPI_FUNC(size_t) _Py_hashtable_size(_Py_hashtable_t *ht); + +/* Add a new entry to the hash. The key must not be present in the hash table. + Return 0 on success, -1 on memory error. + + Don't call directly this function, + but use _Py_HASHTABLE_SET() and _Py_HASHTABLE_SET_NODATA() macros */ +PyAPI_FUNC(int) _Py_hashtable_set( + _Py_hashtable_t *ht, + size_t key_size, + const void *pkey, + size_t data_size, + const void *data); + +#define _Py_HASHTABLE_SET(TABLE, KEY, DATA) \ + _Py_hashtable_set(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA)) + +#define _Py_HASHTABLE_SET_NODATA(TABLE, KEY) \ + _Py_hashtable_set(TABLE, sizeof(KEY), &(KEY), 0, NULL) + + +/* Get an entry. + Return NULL if the key does not exist. + + Don't call directly this function, but use _Py_HASHTABLE_GET_ENTRY() + macro */ +PyAPI_FUNC(_Py_hashtable_entry_t*) _Py_hashtable_get_entry( + _Py_hashtable_t *ht, + size_t key_size, + const void *pkey); + +#define _Py_HASHTABLE_GET_ENTRY(TABLE, KEY) \ + _Py_hashtable_get_entry(TABLE, sizeof(KEY), &(KEY)) + + +/* Get data from an entry. Copy entry data into data and return 1 if the entry + exists, return 0 if the entry does not exist. + + Don't call directly this function, but use _Py_HASHTABLE_GET() macro */ +PyAPI_FUNC(int) _Py_hashtable_get( + _Py_hashtable_t *ht, + size_t key_size, + const void *pkey, + size_t data_size, + void *data); + +#define _Py_HASHTABLE_GET(TABLE, KEY, DATA) \ + _Py_hashtable_get(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA)) + + +/* Don't call directly this function, but use _Py_HASHTABLE_POP() macro */ +PyAPI_FUNC(int) _Py_hashtable_pop( + _Py_hashtable_t *ht, + size_t key_size, + const void *pkey, + size_t data_size, + void *data); + +#define _Py_HASHTABLE_POP(TABLE, KEY, DATA) \ + _Py_hashtable_pop(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA)) + + +#endif /* Py_LIMITED_API */ +#endif diff --git a/python/Modules/itertoolsmodule.c b/python/Modules/itertoolsmodule.c new file mode 100755 index 0000000..eb04c26 --- /dev/null +++ b/python/Modules/itertoolsmodule.c @@ -0,0 +1,4790 @@ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "pycore_tupleobject.h" +#include "structmember.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() + +/* Itertools module written and maintained + by Raymond D. Hettinger +*/ + +/*[clinic input] +module itertools +class itertools.groupby "groupbyobject *" "&groupby_type" +class itertools._grouper "_grouperobject *" "&_grouper_type" +class itertools.teedataobject "teedataobject *" "&teedataobject_type" +class itertools._tee "teeobject *" "&tee_type" +class itertools.cycle "cycleobject *" "&cycle_type" +class itertools.dropwhile "dropwhileobject *" "&dropwhile_type" +class itertools.takewhile "takewhileobject *" "&takewhile_type" +class itertools.starmap "starmapobject *" "&starmap_type" +class itertools.chain "chainobject *" "&chain_type" +class itertools.combinations "combinationsobject *" "&combinations_type" +class itertools.combinations_with_replacement "cwr_object *" "&cwr_type" +class itertools.permutations "permutationsobject *" "&permutations_type" +class itertools.accumulate "accumulateobject *" "&accumulate_type" +class itertools.compress "compressobject *" "&compress_type" +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; +static PyTypeObject tee_type; +static PyTypeObject cycle_type; +static PyTypeObject dropwhile_type; +static PyTypeObject takewhile_type; +static PyTypeObject starmap_type; +static PyTypeObject combinations_type; +static PyTypeObject cwr_type; +static PyTypeObject permutations_type; +static PyTypeObject accumulate_type; +static PyTypeObject compress_type; +static PyTypeObject filterfalse_type; +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 *); + +/*[clinic input] +@classmethod +itertools.groupby.__new__ + + iterable as it: object + Elements to divide into groups according to the key function. + key as keyfunc: object = None + A function for computing the group category for each element. + If the key function is not specified or is None, the element itself + is used for grouping. + +make an iterator that returns consecutive keys and groups from the iterable +[clinic start generated code]*/ + +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 { + newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL); + 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 */ + 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_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 */ + itertools_groupby, /* tp_new */ + 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 * +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 * +_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + 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 */ + 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, /* 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 */ + int running; + PyObject *nextlink; + PyObject *(values[LINKCELLS]); +} teedataobject; + +typedef struct { + PyObject_HEAD + teedataobject *dataobj; + int index; /* 0 <= index <= LINKCELLS */ + PyObject *weakreflist; +} teeobject; + +static PyTypeObject teedataobject_type; + +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); + if (tdo->running) { + PyErr_SetString(PyExc_RuntimeError, + "cannot re-enter the tee iterator"); + return NULL; + } + tdo->running = 1; + 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) +{ + while (obj && Py_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 * +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); +} + +/*[clinic input] +@classmethod +itertools.teedataobject.__new__ + iterable as it: object + values: object(subclass_of='&PyList_Type') + next: object + / +Data container common to multiple tee objects. +[clinic start generated code]*/ + +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) { + if (Py_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 */ + 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, /* 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 */ + itertools_teedataobject, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +static PyTypeObject tee_type; + +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; + PyObject *it = NULL; + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + if (PyObject_TypeCheck(it, &tee_type)) { + to = (teeobject *)tee_copy((teeobject *)it, NULL); + goto done; + } + + to = PyObject_GC_New(teeobject, &tee_type); + if (to == NULL) + goto done; + to->dataobj = (teedataobject *)teedataobject_newinternal(it); + if (!to->dataobj) { + PyObject_GC_Del(to); + to = NULL; + goto done; + } + + to->index = 0; + to->weakreflist = NULL; + PyObject_GC_Track(to); +done: + Py_XDECREF(it); + return (PyObject *)to; +} + +/*[clinic input] +@classmethod +itertools._tee.__new__ + iterable: object + / +Iterator wrapped to make it copyable. +[clinic start generated code]*/ + +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 * +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 */ + 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 */ + 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 */ + itertools__tee, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +/*[clinic input] +itertools.tee + iterable: object + n: Py_ssize_t = 2 + / +Returns a tuple of n independent iterators. +[clinic start generated code]*/ + +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; + +static PyTypeObject cycle_type; + +/*[clinic input] +@classmethod +itertools.cycle.__new__ + iterable: object + / +Return elements from the iterable until it is exhausted. Then repeat the sequence indefinitely. +[clinic start generated code]*/ + +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; +} + +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)(Oi)", Py_TYPE(lz), it, lz->saved, 1); + } + return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), lz->it, lz->saved, + lz->firstpass); +} + +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; + +static PyTypeObject dropwhile_type; + +/*[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 * +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; + + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); + 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 */ + 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_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 */ + itertools_dropwhile, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* takewhile object **********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; + long stop; +} takewhileobject; + +static PyTypeObject takewhile_type; + +/*[clinic input] +@classmethod +itertools.takewhile.__new__ + predicate as func: object + iterable as seq: object + / +Return successive entries from an iterable as long as the predicate evaluates to true for each entry. +[clinic start generated code]*/ + +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; + + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); + 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 */ + 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_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 */ + 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 * +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\ +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 */ + 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 */ + 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; + +static PyTypeObject starmap_type; + +/*[clinic input] +@classmethod +itertools.starmap.__new__ + function as func: object + iterable as seq: object + / +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 * +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 * +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 */ + 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_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 */ + 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); +} + +/*[clinic input] +@classmethod +itertools.chain.from_iterable + iterable as arg: object + / +Alternative chain() constructor taking a single iterable argument that evaluates lazily. +[clinic start generated code]*/ + +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 * +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[] = { + ITERTOOLS_CHAIN_FROM_ITERABLE_METHODDEF + {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)chain_setstate, METH_O, + setstate_doc}, + {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_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; + result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools); + 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 */ + 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 */ + 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; + +static PyTypeObject combinations_type; + + +/*[clinic input] +@classmethod +itertools.combinations.__new__ + iterable: object + r: Py_ssize_t +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 * +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; + result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); + 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 * +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 */ + 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_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 */ + 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; + +static PyTypeObject cwr_type; + +/*[clinic input] +@classmethod +itertools.combinations_with_replacement.__new__ + iterable: object + r: Py_ssize_t +Return successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats. + +combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC" +[clinic start generated code]*/ + +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; + result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); + 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 * +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 */ + 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_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 */ + itertools_combinations_with_replacement, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* permutations object ******************************************************** + +def permutations(iterable, r=None): + 'permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)' + pool = tuple(iterable) + n = len(pool) + r = n if r is None else r + indices = range(n) + cycles = range(n-r+1, n+1)[::-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; + +static PyTypeObject permutations_type; + +/*[clinic input] +@classmethod +itertools.permutations.__new__ + iterable: object + r as robj: object = None +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 * +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; + result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); + 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 * +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 */ + 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_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 */ + itertools_permutations, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* accumulate object ********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *total; + PyObject *it; + PyObject *binop; + PyObject *initial; +} accumulateobject; + +static PyTypeObject accumulate_type; + +/*[clinic input] +@classmethod +itertools.accumulate.__new__ + iterable: object + func as binop: object = None + * + initial: object = None +Return series of accumulated sums (or other binary function results). +[clinic start generated code]*/ + +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; + 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); + 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_VISIT(lz->initial); + return 0; +} + +static PyObject * +accumulate_next(accumulateobject *lz) +{ + PyObject *val, *newtotal; + + if (lz->initial != Py_None) { + lz->total = lz->initial; + Py_INCREF(Py_None); + lz->initial = Py_None; + 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) { + 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_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_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 */ + 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; + +static PyTypeObject compress_type; + +/*[clinic input] +@classmethod +itertools.compress.__new__ + data as seq1: object + selectors as seq2: object +Return data elements corresponding to true selector elements. + +Forms a shorter iterator from selected data elements using the selectors to +choose the data elements. +[clinic start generated code]*/ + +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 * +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 */ + 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_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 */ + itertools_compress, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* filterfalse object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; +} filterfalseobject; + +static PyTypeObject filterfalse_type; + +/*[clinic input] +@classmethod +itertools.filterfalse.__new__ + function as func: object + iterable as seq: object + / +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 * +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; + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); + 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 */ + 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_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 */ + 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. +*/ + +static PyTypeObject count_type; + +/*[clinic input] +@classmethod +itertools.count.__new__ + start as long_cnt: object(c_default="NULL") = 0 + step as long_step: object(c_default="NULL") = 1 +Return a count object whose .__next__() method returns consecutive values. + +Equivalent to: + def count(firstval=0, step=1): + x = firstval + while 1: + yield x + x += step +[clinic start generated code]*/ + +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); + 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 * +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 */ + 0, /* tp_vectorcall_offset */ + 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 */ + 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 */ + 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; + Py_ssize_t cnt = -1, n_kwds = 0; + static char *kwargs[] = {"object", "times", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs, + &element, &cnt)) + return NULL; + + if (kwds != NULL) + n_kwds = PyDict_GET_SIZE(kwds); + /* Does user supply times argument? */ + if ((PyTuple_Size(args) + n_kwds == 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 * +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 * +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 */ + 0, /* tp_vectorcall_offset */ + 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) +{ + _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) { + fillvalue = NULL; + if (PyDict_GET_SIZE(kwds) == 1) { + fillvalue = _PyDict_GetItemIdWithError(kwds, &PyId_fillvalue); + } + if (fillvalue == NULL) { + if (!PyErr_Occurred()) { + 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); + } + // 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 * +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 */ + 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 */ + 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\ +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\ +"); + + +static PyMethodDef module_methods[] = { + ITERTOOLS_TEE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef itertoolsmodule = { + PyModuleDef_HEAD_INIT, + "itertools", + module_doc, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_itertools(void) +{ + int i; + PyObject *m; + const char *name; + 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, + NULL + }; + + Py_TYPE(&teedataobject_type) = &PyType_Type; + m = PyModule_Create(&itertoolsmodule); + if (m == NULL) + return NULL; + + for (i=0 ; typelist[i] != NULL ; i++) { + if (PyType_Ready(typelist[i]) < 0) + return NULL; + name = _PyType_Name(typelist[i]); + Py_INCREF(typelist[i]); + PyModule_AddObject(m, name, (PyObject *)typelist[i]); + } + + return m; +} diff --git a/python/Modules/ld_so_aix b/python/Modules/ld_so_aix new file mode 100755 index 0000000..1d6decb --- /dev/null +++ b/python/Modules/ld_so_aix @@ -0,0 +1,195 @@ +#!/bin/sh +# +# ======================================================================== +# FILE: ld_so_aix +# TYPE: executable, uses makexp_aix +# SYSTEM: AIX +# +# DESCRIPTION: Creates a shareable .o from a set of pre-compiled +# (unshared) .o files +# +# USAGE: ld_so_aix [CC] [arguments] +# +# ARGUMENTS: Same as for "ld". The following arguments are processed +# or supplied by this script (those marked with an asterisk +# can be overridden from command line): +# +# Argument Default value +# (*) -o [OutputFileName] -o shr.o +# (*) -e [EntryPointLabel] -e init[OutputBaseName] +# (*) -bE:[ExportFile] -bE:[OutputBaseName].exp +# (*) -bI:[ImportFile] -bI:./python.exp +# -bM:[ModuleType] -bM:SRE +# -bhalt:[Number] -bhalt:4 +# -T[Number] -T512 +# -H[Number] -H512 +# -lm +# +# The compiler specific ("-lc" or "-lc_r", "-lpthreads",...) +# arguments will be automatically passed to "ld" according +# to the CC command provided as a first argument to this +# script. Usually, the same CC command was used to produce +# the pre-compiled .o file(s). +# +# NOTES: 1. Since "ld_so_aix" was originally written for building +# shared modules for the Python interpreter, the -e and +# -bI default values match Python's conventions. In +# Python, the entry point for a shared module is based +# on the module's name (e.g., the "mathmodule" will +# expect an entry point of "initmath"). +# 2. The script accepts multiple .o or .a input files and +# creates a single (shared) output file. The export list +# that is created is based on the output file's basename +# with the suffix ".exp". +# 3. The resulting shared object file is left in the +# current directory. +# 4. Uncommenting the "echo" lines gives detailed output +# about the commands executed in the script. +# +# +# HISTORY: Oct-1996 -- Support added for multiple .o files -- +# -- and optional arguments processing. -- +# Chris Myers (myers@tc.cornell.edu), Keith Kwok +# (kkwok@tc.cornell.edu) and Vladimir Marangozov +# +# Aug-6-1996 -- Take care of the compiler specific -- +# -- args by leaving CC to invoke "ld". -- +# Vladimir Marangozov +# +# Jul-1-1996 -- Make sure to use /usr/ccs/bin/ld -- +# -- Use makexp_aix for the export list. -- +# Vladimir Marangozov (Vladimir.Marangozov@imag.fr) +# +# Manus Hand (mhand@csn.net) -- Initial code -- 6/24/96 +# ======================================================================== +# + +usage="Usage: ld_so_aix [CC command] [ld arguments]" +if test ! -n "$*"; then + echo $usage; exit 2 +fi + +makexp=`dirname $0`/makexp_aix +test -x "${makexp}" || makexp="/home/cc/tt/armpython/Python-3.8.10/Modules/makexp_aix" + +# Check for existence of compiler. +CC=$1; shift +whichcc=`which $CC` + +if test ! -x "$whichcc"; then + echo "ld_so_aix: Compiler '$CC' not found; exiting." + exit 2 +fi + +if test ! -n "$*"; then + echo $usage; exit 2 +fi + +# Default import file for Python +# Can be overridden by providing a -bI: argument. +impfile="./python.exp" + +# Parse arguments +while test -n "$1" +do + case "$1" in + -e | -Wl,-e) + if test -z "$2"; then + echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2 + else + shift; entry=$1 + fi + ;; + -e* | -Wl,-e*) + entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"` + ;; + -o) + if test -z "$2"; then + echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2 + else + shift; objfile=$1 + fi + ;; + -o*) + objfile=`echo $1 | sed "s/-o//"` + ;; + -bI:* | -Wl,-bI:*) + impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"` + ;; + -bE:* | -Wl,-bE:*) + expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"` + ;; + *.o | *.a) + objs="$objs $1" + args="$args $1" + ;; + -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm) + ;; + *) + args="$args $1" + ;; + esac + shift +done + +if test "$objfile" = "libpython3.8.so"; then + ldsocoremode="true" +fi + +if test -z "$objs"; then + echo "ld_so_aix: No input files; exiting." + exit 2 +elif test ! -r "$impfile" -a -z "$ldsocoremode"; then + echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting." + exit 2 +fi + +# If -o wasn't specified, assume "-o shr.o" +if test -z "$objfile"; then + objfile=shr.o +fi + +filename=`basename $objfile | sed "s/\.[^.]*$//"` + +# If -bE: wasn't specified, assume "-bE:$filename.exp" +if test -z "$expfile"; then + expfile="$filename.exp" +fi + +# Default entry symbol for Python modules = init[modulename] +# Can be overridden by providing a -e argument. +if test -z "$entry"; then + entry=PyInit_`echo $filename | sed "s/module.*//"` +fi + +#echo "ld_so_aix: Debug info section" +#echo " -> output file : $objfile" +#echo " -> import file : $impfile" +#echo " -> export file : $expfile" +#echo " -> entry point : $entry" +#echo " -> object files: $objs" +#echo " -> CC arguments: $args" + +if test -z "$ldsocoremode"; then + CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4" +else + CCOPT="-Wl,-bnoentry -Wl,-bE:$expfile -Wl,-bhalt:4" +fi +CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -Wl,-brtl -Wl,-bnortllib -lm -o $objfile" + +CCARGS="$args" + +# Export list generation. +#echo $makexp $expfile "$objfile" $objs +$makexp $expfile "$objfile" $objs + +# Perform the link. +#echo $CC $CCOPT $CCARGS +$CC $CCOPT $CCARGS +retval=$? + +# Delete the module's export list file. +# Comment this line if you need it. +rm -f $expfile + +exit $retval diff --git a/python/Modules/ld_so_aix.in b/python/Modules/ld_so_aix.in new file mode 100755 index 0000000..f4eab40 --- /dev/null +++ b/python/Modules/ld_so_aix.in @@ -0,0 +1,195 @@ +#!/bin/sh +# +# ======================================================================== +# FILE: ld_so_aix +# TYPE: executable, uses makexp_aix +# SYSTEM: AIX +# +# DESCRIPTION: Creates a shareable .o from a set of pre-compiled +# (unshared) .o files +# +# USAGE: ld_so_aix [CC] [arguments] +# +# ARGUMENTS: Same as for "ld". The following arguments are processed +# or supplied by this script (those marked with an asterisk +# can be overridden from command line): +# +# Argument Default value +# (*) -o [OutputFileName] -o shr.o +# (*) -e [EntryPointLabel] -e init[OutputBaseName] +# (*) -bE:[ExportFile] -bE:[OutputBaseName].exp +# (*) -bI:[ImportFile] -bI:./python.exp +# -bM:[ModuleType] -bM:SRE +# -bhalt:[Number] -bhalt:4 +# -T[Number] -T512 +# -H[Number] -H512 +# -lm +# +# The compiler specific ("-lc" or "-lc_r", "-lpthreads",...) +# arguments will be automatically passed to "ld" according +# to the CC command provided as a first argument to this +# script. Usually, the same CC command was used to produce +# the pre-compiled .o file(s). +# +# NOTES: 1. Since "ld_so_aix" was originally written for building +# shared modules for the Python interpreter, the -e and +# -bI default values match Python's conventions. In +# Python, the entry point for a shared module is based +# on the module's name (e.g., the "mathmodule" will +# expect an entry point of "initmath"). +# 2. The script accepts multiple .o or .a input files and +# creates a single (shared) output file. The export list +# that is created is based on the output file's basename +# with the suffix ".exp". +# 3. The resulting shared object file is left in the +# current directory. +# 4. Uncommenting the "echo" lines gives detailed output +# about the commands executed in the script. +# +# +# HISTORY: Oct-1996 -- Support added for multiple .o files -- +# -- and optional arguments processing. -- +# Chris Myers (myers@tc.cornell.edu), Keith Kwok +# (kkwok@tc.cornell.edu) and Vladimir Marangozov +# +# Aug-6-1996 -- Take care of the compiler specific -- +# -- args by leaving CC to invoke "ld". -- +# Vladimir Marangozov +# +# Jul-1-1996 -- Make sure to use /usr/ccs/bin/ld -- +# -- Use makexp_aix for the export list. -- +# Vladimir Marangozov (Vladimir.Marangozov@imag.fr) +# +# Manus Hand (mhand@csn.net) -- Initial code -- 6/24/96 +# ======================================================================== +# + +usage="Usage: ld_so_aix [CC command] [ld arguments]" +if test ! -n "$*"; then + echo $usage; exit 2 +fi + +makexp=`dirname $0`/makexp_aix +test -x "${makexp}" || makexp="@abs_srcdir@/makexp_aix" + +# Check for existence of compiler. +CC=$1; shift +whichcc=`which $CC` + +if test ! -x "$whichcc"; then + echo "ld_so_aix: Compiler '$CC' not found; exiting." + exit 2 +fi + +if test ! -n "$*"; then + echo $usage; exit 2 +fi + +# Default import file for Python +# Can be overridden by providing a -bI: argument. +impfile="./python.exp" + +# Parse arguments +while test -n "$1" +do + case "$1" in + -e | -Wl,-e) + if test -z "$2"; then + echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2 + else + shift; entry=$1 + fi + ;; + -e* | -Wl,-e*) + entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"` + ;; + -o) + if test -z "$2"; then + echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2 + else + shift; objfile=$1 + fi + ;; + -o*) + objfile=`echo $1 | sed "s/-o//"` + ;; + -bI:* | -Wl,-bI:*) + impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"` + ;; + -bE:* | -Wl,-bE:*) + expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"` + ;; + *.o | *.a) + objs="$objs $1" + args="$args $1" + ;; + -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm) + ;; + *) + args="$args $1" + ;; + esac + shift +done + +if test "$objfile" = "libpython@VERSION@@ABIFLAGS@.so"; then + ldsocoremode="true" +fi + +if test -z "$objs"; then + echo "ld_so_aix: No input files; exiting." + exit 2 +elif test ! -r "$impfile" -a -z "$ldsocoremode"; then + echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting." + exit 2 +fi + +# If -o wasn't specified, assume "-o shr.o" +if test -z "$objfile"; then + objfile=shr.o +fi + +filename=`basename $objfile | sed "s/\.[^.]*$//"` + +# If -bE: wasn't specified, assume "-bE:$filename.exp" +if test -z "$expfile"; then + expfile="$filename.exp" +fi + +# Default entry symbol for Python modules = init[modulename] +# Can be overridden by providing a -e argument. +if test -z "$entry"; then + entry=PyInit_`echo $filename | sed "s/module.*//"` +fi + +#echo "ld_so_aix: Debug info section" +#echo " -> output file : $objfile" +#echo " -> import file : $impfile" +#echo " -> export file : $expfile" +#echo " -> entry point : $entry" +#echo " -> object files: $objs" +#echo " -> CC arguments: $args" + +if test -z "$ldsocoremode"; then + CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4" +else + CCOPT="-Wl,-bnoentry -Wl,-bE:$expfile -Wl,-bhalt:4" +fi +CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -Wl,-brtl -Wl,-bnortllib -lm -o $objfile" + +CCARGS="$args" + +# Export list generation. +#echo $makexp $expfile "$objfile" $objs +$makexp $expfile "$objfile" $objs + +# Perform the link. +#echo $CC $CCOPT $CCARGS +$CC $CCOPT $CCARGS +retval=$? + +# Delete the module's export list file. +# Comment this line if you need it. +rm -f $expfile + +exit $retval diff --git a/python/Modules/main.c b/python/Modules/main.c new file mode 100755 index 0000000..ea6250e --- /dev/null +++ b/python/Modules/main.c @@ -0,0 +1,748 @@ +/* Python interpreter main program */ + +#include "Python.h" +#include "pycore_initconfig.h" +#include "pycore_pylifecycle.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" + +#ifdef __FreeBSD__ +# include /* fedisableexcept() */ +#endif + +/* Includes for exit_sigint() */ +#include /* perror() */ +#ifdef HAVE_SIGNAL_H +# include /* SIGINT */ +#endif +#if defined(HAVE_GETPID) && defined(HAVE_UNISTD_H) +# include /* getpid() */ +#endif +#ifdef MS_WINDOWS +# include /* STATUS_CONTROL_C_EXIT */ +#endif +/* End of includes for exit_sigint() */ + +#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; + } + + /* 754 requires that FP exceptions run in "no stop" mode by default, + * and until C vendors implement C99's ways to control FP exceptions, + * Python requires non-stop mode. Alas, some platforms enable FP + * exceptions by default. Here we disable them. + */ +#ifdef __FreeBSD__ + fedisableexcept(FE_OVERFLOW); +#endif + + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); + + status = _Py_PreInitializeFromPyArgv(&preconfig, args); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + /* 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 { + 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 + on the command line */ +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(); + return 0; +} + + +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); + return 0; + } + + Py_DECREF(importer); + *importer_p = sys_path0; + return 0; + +error: + Py_XDECREF(sys_path0); + + PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n"); + return pymain_err_print(exitcode); +} + + +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 { + sys_path = NULL; + } + 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; +} + + +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 +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 { + 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 +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 = Py_BuildValue("(Oi)", module, set_argv0); + if (runargs == NULL) { + fprintf(stderr, + "Could not create arguments for runpy._run_module_as_main\n"); + Py_DECREF(runpy); + 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) { + _Py_UnhandledKeyboardInterrupt = 1; + } + Py_DECREF(runpy); + Py_DECREF(runmodule); + Py_DECREF(module); + Py_DECREF(runargs); + if (result == NULL) { + return pymain_exit_err_print(); + } + Py_DECREF(result); + return 0; +} + + +static int +pymain_run_file(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; + 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", + config->program_name, cfilename, err, strerror(err)); + PyMem_RawFree(cfilename_buffer); + return 2; + } + + if (config->skip_source_first_line) { + 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; + if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { + fprintf(stderr, + "%ls: '%ls' is a directory, cannot continue\n", + config->program_name, filename); + 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 +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 + FILE *fp = _Py_wfopen(wstartup, L"r"); +#else + FILE *fp = _Py_fopen(startup, "r"); +#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 +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 +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_UNSAFE(); + /* pymain_run_stdin() modify the config */ + PyConfig *config = &interp->config; + + 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) { + 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 { + *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 +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 + Py_Initialize()-Py_Finalize() can be called multiple times. */ + _PyPathConfig_ClearGlobal(); + _Py_ClearStandardStreamEncoding(); + _Py_ClearArgcArgv(); + _PyRuntime_Finalize(); +} + + +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 + * about the user's ^C. https://www.cons.org/cracauer/sigint.html */ +#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) + if (PyOS_setsig(SIGINT, SIG_DFL) == SIG_ERR) { + 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 */ +#ifdef MS_WINDOWS + /* cmd.exe detects this, prints ^C, and offers to terminate. */ + /* https://msdn.microsoft.com/en-us/library/cc704588.aspx */ + return STATUS_CONTROL_C_EXIT; +#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 +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) +{ + _PyArgv args = { + .argc = argc, + .use_bytes_argv = 0, + .bytes_argv = NULL, + .wchar_argv = argv}; + return pymain_main(&args); +} + + +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 diff --git a/python/Modules/makesetup b/python/Modules/makesetup new file mode 100755 index 0000000..fefe3fd --- /dev/null +++ b/python/Modules/makesetup @@ -0,0 +1,309 @@ +#! /bin/sh + +# Convert templates into Makefile and config.c, based on the module +# definitions found in the file Setup. +# +# Usage: makesetup [-s dir] [-c file] [-m file] [Setup] ... [-n [Setup] ...] +# +# Options: +# -s directory: alternative source directory (default .) +# -l directory: library source directory (default derived from $0) +# -c file: alternative config.c template (default $libdir/config.c.in) +# -c -: don't write config.c +# -m file: alternative Makefile template (default ./Makefile.pre) +# -m -: don't write Makefile +# +# Remaining arguments are one or more Setup files (default ./Setup). +# Setup files after a -n option are used for their variables, modules +# and libraries but not for their .o files. +# +# See Setup for a description of the format of the Setup file. +# +# The following edits are made: +# +# Copying config.c.in to config.c: +# - insert an identifying comment at the start +# - for each mentioned in Setup before *noconfig*: +# + insert 'extern PyObject* PyInit_(void);' before MARKER 1 +# + insert '{"", PyInit_},' before MARKER 2 +# +# Copying Makefile.pre to Makefile: +# - insert an identifying comment at the start +# - replace _MODBUILT_NAMES_ by the list of *static* and *shared* modules +# from Setup +# - replace _MODDISABLED_NAMES_ by the list of *disabled* modules from Setup +# - replace _MODOBJS_ by the list of objects from Setup (except for +# Setup files after a -n option) +# - replace _MODLIBS_ by the list of libraries from Setup +# - for each object file mentioned in Setup, append a rule +# '.o: .c; ' to the end of the Makefile +# - for each module mentioned in Setup, append a rule +# which creates a shared library version to the end of the Makefile +# - for each variable definition found in Setup, insert the definition +# before the comment 'Definitions added by makesetup' + +# Loop over command line options +usage=' +usage: makesetup [-s srcdir] [-l libdir] [-c config.c.in] [-m Makefile.pre] + [Setup] ... [-n [Setup] ...]' +srcdir='.' +libdir='' +config='' +makepre='' +noobjects='' +doconfig=yes +while : +do + case $1 in + -s) shift; srcdir=$1; shift;; + -l) shift; libdir=$1; shift;; + -c) shift; config=$1; shift;; + -m) shift; makepre=$1; shift;; + --) shift; break;; + -n) noobjects=yes;; + -*) echo "$usage" 1>&2; exit 2;; + *) break;; + esac +done + +# Set default libdir and config if not set by command line +# (Not all systems have dirname) +case $libdir in +'') case $0 in + */*) libdir=`echo $0 | sed 's,/[^/]*$,,'`;; + *) libdir=.;; + esac;; +esac +case $config in +'') config=$libdir/config.c.in;; +esac +case $makepre in +'') makepre=Makefile.pre;; +esac + +# Newline for sed i and a commands +NL='\ +' + +# Setup to link with extra libraries when making shared extensions. +# Currently, only Cygwin needs this baggage. +case `uname -s` in +CYGWIN*) if test $libdir = . + then + ExtraLibDir=. + else + ExtraLibDir='$(LIBPL)' + fi + ExtraLibs="-L$ExtraLibDir -lpython\$(LDVERSION)";; +esac + +# Main loop +for i in ${*-Setup} +do + case $i in + -n) echo '*noobjects*';; + *) echo '*doconfig*'; cat "$i";; + esac +done | +sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | +( + rulesf="@rules.$$" + trap 'rm -f $rulesf' 0 1 2 3 + echo " +# Rules appended by makesetup +" >$rulesf + DEFS= + BUILT= + DISABLED= + MODS= + SHAREDMODS= + OBJS= + LIBS= + LOCALLIBS= + BASELIBS= + while read line + do + # to handle backslashes for sh's that don't automatically + # continue a read when the last char is a backslash + while echo $line | grep '\\$' > /dev/null + do + read extraline + line=`echo $line| sed s/.$//`$extraline + done + + # Output DEFS in reverse order so first definition overrides + case $line in + *=*) DEFS="$line$NL$DEFS"; continue;; + 'include '*) DEFS="$line$NL$DEFS"; continue;; + '*noobjects*') + case $noobjects in + yes) ;; + *) LOCALLIBS=$LIBS; LIBS=;; + esac + noobjects=yes; + continue;; + '*doconfig*') doconfig=yes; continue;; + '*static*') doconfig=yes; continue;; + '*noconfig*') doconfig=no; continue;; + '*shared*') doconfig=no; continue;; + '*disabled*') doconfig=disabled; continue;; + esac + srcs= + cpps= + libs= + mods= + skip= + for arg in $line + do + case $skip in + libs) libs="$libs $arg"; skip=; continue;; + cpps) cpps="$cpps $arg"; skip=; continue;; + srcs) srcs="$srcs $arg"; skip=; continue;; + esac + case $arg in + -framework) libs="$libs $arg"; skip=libs; + # OSX/OSXS/Darwin framework link cmd + ;; + -[IDUCfF]*) cpps="$cpps $arg";; + -Xcompiler) skip=cpps;; + -Xlinker) libs="$libs $arg"; skip=libs;; + -rpath) libs="$libs $arg"; skip=libs;; + --rpath) libs="$libs $arg"; skip=libs;; + -[A-Zl]*) libs="$libs $arg";; + *.a) libs="$libs $arg";; + *.so) libs="$libs $arg";; + *.sl) libs="$libs $arg";; + /*.o) libs="$libs $arg";; + *.def) libs="$libs $arg";; + *.o) srcs="$srcs `basename $arg .o`.c";; + *.[cC]) srcs="$srcs $arg";; + *.m) srcs="$srcs $arg";; # Objective-C src + *.cc) srcs="$srcs $arg";; + *.c++) srcs="$srcs $arg";; + *.cxx) srcs="$srcs $arg";; + *.cpp) srcs="$srcs $arg";; + \$*) libs="$libs $arg" + cpps="$cpps $arg";; + *.*) echo 1>&2 "bad word $arg in $line" + exit 1;; + -u) skip=libs; libs="$libs -u";; + [a-zA-Z_]*) mods="$mods $arg";; + *) echo 1>&2 "bad word $arg in $line" + exit 1;; + esac + done + case $doconfig in + yes) + LIBS="$LIBS $libs" + MODS="$MODS $mods" + BUILT="$BUILT $mods" + ;; + no) + BUILT="$BUILT $mods" + ;; + disabled) + DISABLED="$DISABLED $mods" + continue + ;; + esac + case $noobjects in + yes) continue;; + esac + objs='' + for src in $srcs + do + case $src in + *.c) obj=`basename $src .c`.o; cc='$(CC)';; + *.cc) obj=`basename $src .cc`.o; cc='$(CXX)';; + *.c++) obj=`basename $src .c++`.o; cc='$(CXX)';; + *.C) obj=`basename $src .C`.o; cc='$(CXX)';; + *.cxx) obj=`basename $src .cxx`.o; cc='$(CXX)';; + *.cpp) obj=`basename $src .cpp`.o; cc='$(CXX)';; + *.m) obj=`basename $src .m`.o; cc='$(CC)';; # Obj-C + *) continue;; + esac + obj="$srcdir/$obj" + objs="$objs $obj" + case $src in + glmodule.c) ;; + /*) ;; + \$*) ;; + *) src='$(srcdir)/'"$srcdir/$src";; + esac + case $doconfig in + no) cc="$cc \$(CCSHARED) \$(PY_CFLAGS) \$(PY_CPPFLAGS)";; + *) + cc="$cc \$(PY_BUILTIN_MODULE_CFLAGS)";; + esac + rule="$obj: $src; $cc $cpps -c $src -o $obj" + echo "$rule" >>$rulesf + done + case $doconfig in + yes) OBJS="$OBJS $objs";; + esac + for mod in $mods + do + file="$srcdir/$mod\$(EXT_SUFFIX)" + case $doconfig in + no) SHAREDMODS="$SHAREDMODS $file";; + esac + rule="$file: $objs" + rule="$rule; \$(BLDSHARED) $objs $libs $ExtraLibs -o $file" + echo "$rule" >>$rulesf + done + done + + case $SHAREDMODS in + '') ;; + *) DEFS="SHAREDMODS=$SHAREDMODS$NL$DEFS";; + esac + + case $noobjects in + yes) BASELIBS=$LIBS;; + *) LOCALLIBS=$LIBS;; + esac + LIBS='$(LOCALMODLIBS) $(BASEMODLIBS)' + DEFS="BASEMODLIBS=$BASELIBS$NL$DEFS" + DEFS="LOCALMODLIBS=$LOCALLIBS$NL$DEFS" + + EXTDECLS= + INITBITS= + for mod in $MODS + do + EXTDECLS="${EXTDECLS}extern PyObject* PyInit_$mod(void);$NL" + INITBITS="${INITBITS} {\"$mod\", PyInit_$mod},$NL" + done + + + case $config in + -) ;; + *) sed -e " + 1i$NL/* Generated automatically from $config by makesetup. */ + /MARKER 1/i$NL$EXTDECLS + + /MARKER 2/i$NL$INITBITS + + " $config >config.c + ;; + esac + + case $makepre in + -) ;; + *) sedf="@sed.in.$$" + trap 'rm -f $sedf' 0 1 2 3 + echo "1i\\" >$sedf + str="# Generated automatically from $makepre by makesetup." + echo "$str" >>$sedf + echo "s%_MODBUILT_NAMES_%$BUILT%" >>$sedf + echo "s%_MODDISABLED_NAMES_%$DISABLED%" >>$sedf + echo "s%_MODOBJS_%$OBJS%" >>$sedf + echo "s%_MODLIBS_%$LIBS%" >>$sedf + echo "/Definitions added by makesetup/a$NL$NL$DEFS" >>$sedf + sed -f $sedf $makepre >Makefile + cat $rulesf >>Makefile + rm -f $sedf + ;; + esac + + rm -f $rulesf +) diff --git a/python/Modules/makexp_aix b/python/Modules/makexp_aix new file mode 100755 index 0000000..cb349c2 --- /dev/null +++ b/python/Modules/makexp_aix @@ -0,0 +1,81 @@ +#!/bin/sh +# +# =========================================================================== +# FILE: makexp_aix +# TYPE: standalone executable +# SYSTEM: AIX 3.2.5 and AIX 4 +# +# DESCRIPTION: This script creates an export list of ALL global symbols +# from a list of object or archive files. +# +# USAGE: makexp_aix "" ... +# +# where: +# is the target export list filename. +# is the path/file string to be appended +# after the "#!" symbols in the first line of the +# export file. Passing "" means deferred resolution. +# is an object (.o) or an archive file (.a). +# +# HISTORY: +# 3-Apr-1998 -- remove C++ entries of the form Class::method +# Vladimir Marangozov +# +# 1-Jul-1996 -- added header information +# Vladimir Marangozov +# +# 28-Jun-1996 -- initial code +# Vladimir Marangozov (Vladimir.Marangozov@imag.fr) +# ========================================================================== + +# Variables +expFileName=$1 +toAppendStr=$2 +shift; shift; +inputFiles=$* +automsg="Generated automatically by makexp_aix" +notemsg="NOTE: lists _all_ global symbols defined in the above file(s)." +curwdir=`pwd` + +# Create the export file and setup the header info +echo "#!"$toAppendStr > $expFileName +echo "*" >> $expFileName +echo "* $automsg (`date -u`)" >> $expFileName +echo "*" >> $expFileName +echo "* Base Directory: $curwdir" >> $expFileName +echo "* Input File(s) : $inputFiles" >> $expFileName +echo "*" >> $expFileName +echo "* $notemsg" >> $expFileName +echo "*" >> $expFileName + +# Extract the symbol list using 'nm' which produces quite +# different output under AIX 4 than under AIX 3.2.5. +# The following handles both versions by using a common flagset. +# Here are some hidden tricks: +# 1. Use /usr/ccs/bin/nm. Relevant to AIX 3.2.5 which has +# another version under /usr/ucb/bin/nm. +# 2. Use the -B flag to have a standard BSD representation +# of the symbol list on both AIX 3.2.5 and AIX 4. The "-B" +# flag is missing in the AIX 3.2.5 online usage help of 'nm'. +# 3. Use the -x flag to have a hex representation of the symbol +# values. This fills the leading whitespaces on AIX 4, +# thus simplifying the sed statement. +# 4. Eliminate all entries except those with either "B", "D" +# or "T" key letters. We are interested only in the global +# (extern) BSS, DATA and TEXT symbols. With the same statement +# we eliminate object member lines relevant to AIX 4. +# 5. Eliminate entries containing a dot. We can have a dot only +# as a symbol prefix, but such symbols are undefined externs. +# 6. Eliminate everything including the key letter, so that we're +# left with just the symbol name. +# 7. Eliminate all entries containing two colons, like Class::method +# + +# Use -X32_64 if it appears to be implemented in this version of 'nm'. +NM=/usr/ccs/bin/nm +xopt=-X32_64 +$NM -e $xopt $1 >/dev/null 2>&1 || xopt="" + +$NM -Bex $xopt $inputFiles \ +| sed -e '/ [^BDT] /d' -e '/\./d' -e 's/.* [BDT] //' -e '/::/d' \ +| sort | uniq >> $expFileName diff --git a/python/Modules/mathmodule.c b/python/Modules/mathmodule.c new file mode 100755 index 0000000..b78fced --- /dev/null +++ b/python/Modules/mathmodule.c @@ -0,0 +1,3395 @@ +/* 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 "_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 + speed improvement for extracting float arguments. +*/ + +#define ASSIGN_DOUBLE(target_var, obj, error_label) \ + if (PyFloat_CheckExact(obj)) { \ + target_var = PyFloat_AS_DOUBLE(obj); \ + } \ + else if (PyLong_CheckExact(obj)) { \ + target_var = PyLong_AsDouble(obj); \ + if (target_var == -1.0 && PyErr_Occurred()) { \ + goto error_label; \ + } \ + } \ + else { \ + target_var = PyFloat_AsDouble(obj); \ + if (target_var == -1.0 && PyErr_Occurred()) { \ + goto error_label; \ + } \ + } + +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 mutiplication + 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 */ + } +} + + +/*[clinic input] +math.gcd + + x as a: object + y as b: object + / + +greatest common divisor of x and y +[clinic start generated code]*/ + +static PyObject * +math_gcd_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=7b2e0c151bd7a5d8 input=c2691e57fb2a98fa]*/ +{ + PyObject *g; + + a = PyNumber_Index(a); + if (a == NULL) + return NULL; + b = PyNumber_Index(b); + if (b == NULL) { + Py_DECREF(a); + return NULL; + } + g = _PyLong_GCD(a, b); + Py_DECREF(a); + Py_DECREF(b); + return g; +} + + +/* 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 one in absolute value. + */ + if (fabs(x) < 1.0) + 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; + PyFPE_START_PROTECT("in math_1", return 0); + r = (*func)(x); + PyFPE_END_PROTECT(r); + 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; + PyFPE_START_PROTECT("in math_1a", return 0); + r = (*func)(x); + PyFPE_END_PROTECT(r); + 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_1_to_int(PyObject *arg, double (*func) (double), int can_overflow) +{ + return math_1_to_whatever(arg, func, PyLong_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; + if (!_PyArg_CheckPositional(funcname, nargs, 2, 2)) + return NULL; + x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } + y = PyFloat_AsDouble(args[1]); + if (y == -1.0 && PyErr_Occurred()) { + return NULL; + } + errno = 0; + PyFPE_START_PROTECT("in math_2", return 0); + r = (*func)(x, y); + PyFPE_END_PROTECT(r); + 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" + "Return the arc cosine (measured in radians) of x.") +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.") +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.") +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__); + PyObject *method, *result; + + method = _PyObject_LookupSpecial(number, &PyId___ceil__); + if (method == NULL) { + if (PyErr_Occurred()) + return NULL; + return math_1_to_int(number, ceil, 0); + } + result = _PyObject_CallNoArg(method); + Py_DECREF(method); + return result; +} + +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]*/ +{ + _Py_IDENTIFIER(__floor__); + PyObject *method, *result; + + method = _PyObject_LookupSpecial(number, &PyId___floor__); + if (method == NULL) { + if (PyErr_Occurred()) + return NULL; + return math_1_to_int(number, floor, 0); + } + result = _PyObject_CallNoArg(method); + Py_DECREF(method); + return result; +} + +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; + + PyFPE_START_PROTECT("fsum", Py_DECREF(iter); 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); + + _fsum_error: + PyFPE_END_PROTECT(hi) + Py_DECREF(iter); + if (p != ps) + PyMem_Free(p); + return sum; + + error_with_item: + Py_DECREF(item); + goto _fsum_error; +} + +#undef NUM_PARTIALS + + +/* Return the smallest integer k such that n < 2**k, or 0 if n == 0. + * Equivalent to floor(lg(x))+1. Also equivalent to: bitwidth_of_type - + * count_leading_zero_bits(x) + */ + +/* XXX: This routine does more or less the same thing as + * bits_in_digit() in Objects/longobject.c. Someday it would be nice to + * consolidate them. On BSD, there's a library function called fls() + * that we could use, and GCC provides __builtin_clz(). + */ + +static unsigned long +bit_length(unsigned long n) +{ + unsigned long len = 0; + while (n != 0) { + ++len; + n >>= 1; + } + return len; +} + +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 +`a` for which `a * a <= n`, or equivalently the integer part of the exact +square root of `n`. + +We use an adaptive-precision pure-integer version of Newton's iteration. Given +a positive integer `n`, the algorithm produces at each iteration an integer +approximation `a` to the square root of `n >> s` for some even integer `s`, +with `s` decreasing as the iterations progress. On the final iteration, `s` is +zero and we have an approximation to the square root of `n` itself. + +At every step, the approximation `a` is strictly within 1.0 of the true square +root, so we have + + (a - 1)**2 < (n >> s) < (a + 1)**2 + +After the final iteration, a check-and-correct step is needed to determine +whether `a` or `a - 1` gives the desired integer square root of `n`. + +The algorithm is remarkable in its simplicity. There's no need for a +per-iteration check-and-correct step, and termination is straightforward: the +number of iterations is known in advance (it's exactly `floor(log2(log2(n)))` +for `n > 1`). The only tricky part of the correctness proof is in establishing +that the bound `(a - 1)**2 < (n >> s) < (a + 1)**2` is maintained from one +iteration to the next. A sketch of the proof of this is given below. + +In addition to the proof sketch, a formal, computer-verified proof +of correctness (using Lean) of an equivalent recursive algorithm can be found +here: + + https://github.com/mdickinson/snippets/blob/master/proofs/isqrt/src/isqrt.lean + + +Here's Python code equivalent to the C implementation below: + + def isqrt(n): + """ + Return the integer part of the square root of the input. + """ + n = operator.index(n) + + if n < 0: + raise ValueError("isqrt() argument must be nonnegative") + if n == 0: + return 0 + + c = (n.bit_length() - 1) // 2 + a = 1 + d = 0 + for s in reversed(range(c.bit_length())): + # Loop invariant: (a-1)**2 < (n >> 2*(c - d)) < (a+1)**2 + e = d + d = c >> s + a = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a + + return a - (a*a > n) + + +Sketch of proof of correctness +------------------------------ + +The delicate part of the correctness proof is showing that the loop invariant +is preserved from one iteration to the next. That is, just before the line + + a = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a + +is executed in the above code, we know that + + (1) (a - 1)**2 < (n >> 2*(c - e)) < (a + 1)**2. + +(since `e` is always the value of `d` from the previous iteration). We must +prove that after that line is executed, we have + + (a - 1)**2 < (n >> 2*(c - d)) < (a + 1)**2 + +To facilitate the proof, we make some changes of notation. Write `m` for +`n >> 2*(c-d)`, and write `b` for the new value of `a`, so + + b = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a + +or equivalently: + + (2) b = (a << d - e - 1) + (m >> d - e + 1) // a + +Then we can rewrite (1) as: + + (3) (a - 1)**2 < (m >> 2*(d - e)) < (a + 1)**2 + +and we must show that (b - 1)**2 < m < (b + 1)**2. + +From this point on, we switch to mathematical notation, so `/` means exact +division rather than integer division and `^` is used for exponentiation. We +use the `√` symbol for the exact square root. In (3), we can remove the +implicit floor operation to give: + + (4) (a - 1)^2 < m / 4^(d - e) < (a + 1)^2 + +Taking square roots throughout (4), scaling by `2^(d-e)`, and rearranging gives + + (5) 0 <= | 2^(d-e)a - √m | < 2^(d-e) + +Squaring and dividing through by `2^(d-e+1) a` gives + + (6) 0 <= 2^(d-e-1) a + m / (2^(d-e+1) a) - √m < 2^(d-e-1) / a + +We'll show below that `2^(d-e-1) <= a`. Given that, we can replace the +right-hand side of (6) with `1`, and now replacing the central +term `m / (2^(d-e+1) a)` with its floor in (6) gives + + (7) -1 < 2^(d-e-1) a + m // 2^(d-e+1) a - √m < 1 + +Or equivalently, from (2): + + (7) -1 < b - √m < 1 + +and rearranging gives that `(b-1)^2 < m < (b+1)^2`, which is what we needed +to prove. + +We're not quite done: we still have to prove the inequality `2^(d - e - 1) <= +a` that was used to get line (7) above. From the definition of `c`, we have +`4^c <= n`, which implies + + (8) 4^d <= m + +also, since `e == d >> 1`, `d` is at most `2e + 1`, from which it follows +that `2d - 2e - 1 <= d` and hence that + + (9) 4^(2d - 2e - 1) <= m + +Dividing both sides by `4^(d - e)` gives + + (10) 4^(d - e - 1) <= m / 4^(d - e) + +But we know from (4) that `m / 4^(d-e) < (a + 1)^2`, hence + + (11) 4^(d - e - 1) < (a + 1)^2 + +Now taking square roots of both sides and observing that both `2^(d-e-1)` and +`a` are integers gives `2^(d - e - 1) <= a`, which is what we needed. This +completes the proof sketch. + +*/ + + +/* Approximate square root of a large 64-bit integer. + + Given `n` satisfying `2**62 <= n < 2**64`, return `a` + satisfying `(a - 1)**2 < n < (a + 1)**2`. */ + +static uint64_t +_approximate_isqrt(uint64_t n) +{ + uint32_t u = 1U + (n >> 62); + u = (u << 1) + (n >> 59) / u; + u = (u << 3) + (n >> 53) / u; + u = (u << 7) + (n >> 41) / u; + return (u << 15) + (n >> 17) / u; +} + +/*[clinic input] +math.isqrt + + n: object + / + +Return the integer part of the square root of the input. +[clinic start generated code]*/ + +static PyObject * +math_isqrt(PyObject *module, PyObject *n) +/*[clinic end generated code: output=35a6f7f980beab26 input=5b6e7ae4fa6c43d6]*/ +{ + int a_too_large, c_bit_length; + size_t c, d; + uint64_t m, u; + PyObject *a = NULL, *b; + + n = PyNumber_Index(n); + if (n == NULL) { + return NULL; + } + + if (_PyLong_Sign(n) < 0) { + PyErr_SetString( + PyExc_ValueError, + "isqrt() argument must be nonnegative"); + goto error; + } + if (_PyLong_Sign(n) == 0) { + Py_DECREF(n); + return PyLong_FromLong(0); + } + + /* c = (n.bit_length() - 1) // 2 */ + c = _PyLong_NumBits(n); + if (c == (size_t)(-1)) { + goto error; + } + c = (c - 1U) / 2U; + + /* Fast path: if c <= 31 then n < 2**64 and we can compute directly with a + fast, almost branch-free algorithm. In the final correction, we use `u*u + - 1 >= m` instead of the simpler `u*u > m` in order to get the correct + result in the corner case where `u=2**32`. */ + 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, + 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 = 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, 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)) { + 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 (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 { + PyFPE_START_PROTECT("in math_frexp", return 0); + x = frexp(x, &i); + PyFPE_END_PROTECT(x); + } + 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; + PyFPE_START_PROTECT("in math_ldexp", return 0); + r = ldexp(x, (int)exp); + PyFPE_END_PROTECT(r); + 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; + PyFPE_START_PROTECT("in math_modf", return 0); + x = modf(x, &y); + PyFPE_END_PROTECT(x); + 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; + PyFPE_START_PROTECT("in math_fmod", return 0); + r = fmod(x, y); + PyFPE_END_PROTECT(r); + 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 +equal to the absolute value of the largest magnitude +entry in the vector. If n==0, then *max* should be 0.0. +If an infinity is present in the vec, *max* should be INF. + +The *found_nan* variable indicates whether some member of +the *vec* is a NaN. + +To improve accuracy and to increase the number of cases where +vector_norm() is commutative, we use a variant of Neumaier +summation specialized to exploit that we always know that +|csum| >= |x|. + +The *csum* variable tracks the cumulative sum and *frac* tracks +the cumulative fractional errors at each step. Since this +variant assumes that |csum| >= |x| at each step, we establish +the precondition by starting the accumulation from 1.0 which +represents the largest possible value of (x/max)**2. + +After the loop is finished, the initial 1.0 is subtracted out +for a net zero effect on the final sum. Since *csum* will be +greater than 1.0, the subtraction of 1.0 will not cause +fractional digits to be dropped from *csum*. + +*/ + +static inline double +vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) +{ + double x, csum = 1.0, oldcsum, frac = 0.0; + Py_ssize_t i; + + if (Py_IS_INFINITY(max)) { + return max; + } + if (found_nan) { + return Py_NAN; + } + if (max == 0.0 || n <= 1) { + return max; + } + for (i=0 ; i < n ; i++) { + x = vec[i]; + assert(Py_IS_FINITE(x) && fabs(x) <= max); + x /= max; + x = x*x; + oldcsum = csum; + csum += x; + assert(csum >= x); + frac += (oldcsum - csum) + x; + } + return max * sqrt(csum - 1.0 + frac); +} + +#define NUM_STACK_ELEMS 16 + +/*[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 +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 * +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; + Py_ssize_t i, m, n; + int found_nan = 0, p_allocated = 0, q_allocated = 0; + double diffs_on_stack[NUM_STACK_ELEMS]; + double *diffs = diffs_on_stack; + + if (!PyTuple_Check(p)) { + p = PySequence_Tuple(p); + if (p == NULL) { + return NULL; + } + p_allocated = 1; + } + if (!PyTuple_Check(q)) { + q = PySequence_Tuple(q); + if (q == NULL) { + if (p_allocated) { + Py_DECREF(p); + } + 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; + + } + if (n > NUM_STACK_ELEMS) { + diffs = (double *) PyObject_Malloc(n * sizeof(double)); + if (diffs == NULL) { + return PyErr_NoMemory(); + } + } + for (i=0 ; i max) { + max = x; + } + } + result = vector_norm(n, diffs, max, found_nan); + if (diffs != diffs_on_stack) { + PyObject_Free(diffs); + } + if (p_allocated) { + Py_DECREF(p); + } + if (q_allocated) { + Py_DECREF(q); + } + return PyFloat_FromDouble(result); + + error_exit: + if (diffs != diffs_on_stack) { + PyObject_Free(diffs); + } + if (p_allocated) { + Py_DECREF(p); + } + if (q_allocated) { + 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) +{ + Py_ssize_t i; + PyObject *item; + double max = 0.0; + double x, result; + 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) { + return PyErr_NoMemory(); + } + } + for (i = 0; i < nargs; i++) { + item = args[i]; + ASSIGN_DOUBLE(x, item, error_exit); + x = fabs(x); + coordinates[i] = x; + found_nan |= Py_IS_NAN(x); + if (x > max) { + max = x; + } + } + result = vector_norm(nargs, coordinates, max, found_nan); + if (coordinates != coord_on_stack) { + PyObject_Free(coordinates); + } + return PyFloat_FromDouble(result); + + error_exit: + if (coordinates != coord_on_stack) { + PyObject_Free(coordinates); + } + return NULL; +} + +#undef NUM_STACK_ELEMS + +PyDoc_STRVAR(math_hypot_doc, + "hypot(*coordinates) -> value\n\n\ +Multidimensional Euclidean distance from the origin to a point.\n\ +\n\ +Roughly equivalent to:\n\ + sqrt(sum(x**2 for x in coordinates))\n\ +\n\ +For a two dimensional point (x, y), gives the hypotenuse\n\ +using the Pythagorean theorem: sqrt(x*x + y*y).\n\ +\n\ +For example, the hypotenuse of a 3/4/5 right triangle is:\n\ +\n\ + >>> hypot(3.0, 4.0)\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; + PyFPE_START_PROTECT("in math_pow", return 0); + r = pow(x, y); + PyFPE_END_PROTECT(r); + /* 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 + they didn't work on all platforms, or failed in endcases (a product of + -sys.maxint-1 has been a particular pain). + + Here's another way: + + The native long product x*y is either exactly right or *way* off, being + just the last n bits of the true product, where n is the number of bits + in a long (the delivered product is the true product plus i*2**n for + some integer i). + + The native double product (double)x * (double)y is subject to three + rounding errors: on a sizeof(long)==8 box, each cast to double can lose + info, and even on a sizeof(long)==4 box, the multiplication can lose info. + But, unlike the native long product, it's not in *range* trouble: even + if sizeof(long)==32 (256-bit longs), the product easily fits in the + dynamic range of a double. So the leading 50 (or so) bits of the double + product are correct. + + We check these two ways against each other, and declare victory if they're + approximately the same. Else, because the native long product is the only + one that can lose catastrophic amounts of information, it's the native long + product that must have overflowed. + + */ + + long longprod = (long)((unsigned long)a * b); + double doubleprod = (double)a * (double)b; + double doubled_longprod = (double)longprod; + + if (doubled_longprod == doubleprod) { + return 0; + } + + const double diff = doubled_longprod - doubleprod; + const double absdiff = diff >= 0.0 ? diff : -diff; + const double absprod = doubleprod >= 0.0 ? doubleprod : -doubleprod; + + if (32.0 * absdiff <= absprod) { + return 0; + } + + return 1; +} + +/*[clinic input] +math.prod + + iterable: object + / + * + start: object(c_default="NULL") = 1 + +Calculate the product of all the elements in the input iterable. + +The default start value for the product is 1. + +When the iterable is empty, return the start value. This function is +intended specifically for use with numeric values and may reject +non-numeric types. +[clinic start generated code]*/ + +static PyObject * +math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) +/*[clinic end generated code: output=36153bedac74a198 input=4c5ab0682782ed54]*/ +{ + PyObject *result = start; + PyObject *temp, *item, *iter; + + iter = PyObject_GetIter(iterable); + if (iter == NULL) { + return NULL; + } + + if (result == NULL) { + result = PyLong_FromLong(1); + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } else { + Py_INCREF(result); + } +#ifndef SLOW_PROD + /* Fast paths for integers keeping temporary products in C. + * Assumes all inputs are the same type. + * If the assumption fails, default to use PyObjects instead. + */ + if (PyLong_CheckExact(result)) { + int overflow; + long i_result = PyLong_AsLongAndOverflow(result, &overflow); + /* If this already overflowed, don't even enter the loop. */ + if (overflow == 0) { + Py_DECREF(result); + result = NULL; + } + /* Loop over all the items in the iterable until we finish, we overflow + * or we found a non integer element */ + while(result == NULL) { + item = PyIter_Next(iter); + if (item == NULL) { + Py_DECREF(iter); + if (PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(i_result); + } + if (PyLong_CheckExact(item)) { + long b = PyLong_AsLongAndOverflow(item, &overflow); + if (overflow == 0 && !_check_long_mult_overflow(i_result, b)) { + long x = i_result * b; + i_result = x; + Py_DECREF(item); + continue; + } + } + /* Either overflowed or is not an int. + * Restore real objects and process normally */ + result = PyLong_FromLong(i_result); + if (result == NULL) { + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + temp = PyNumber_Multiply(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } + } + + /* Fast paths for floats keeping temporary products in C. + * Assumes all inputs are the same type. + * If the assumption fails, default to use PyObjects instead. + */ + if (PyFloat_CheckExact(result)) { + double f_result = PyFloat_AS_DOUBLE(result); + Py_DECREF(result); + result = NULL; + while(result == NULL) { + item = PyIter_Next(iter); + if (item == NULL) { + Py_DECREF(iter); + if (PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(f_result); + } + if (PyFloat_CheckExact(item)) { + f_result *= PyFloat_AS_DOUBLE(item); + Py_DECREF(item); + continue; + } + if (PyLong_CheckExact(item)) { + long value; + int overflow; + value = PyLong_AsLongAndOverflow(item, &overflow); + if (!overflow) { + f_result *= (double)value; + Py_DECREF(item); + continue; + } + } + result = PyFloat_FromDouble(f_result); + if (result == NULL) { + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + temp = PyNumber_Multiply(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } + } +#endif + /* Consume rest of the iterable (if any) that could not be handled + * by specialized functions above.*/ + for(;;) { + item = PyIter_Next(iter); + if (item == NULL) { + /* error, or end-of-sequence */ + if (PyErr_Occurred()) { + Py_DECREF(result); + result = NULL; + } + break; + } + temp = PyNumber_Multiply(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) + break; + } + Py_DECREF(iter); + return result; +} + + +/*[clinic input] +math.perm + + n: object + k: object = None + / + +Number of ways to choose k items from n items without repetition and with order. + +Evaluates to n! / (n - k)! when k <= n and evaluates +to zero when k > n. + +If k is not specified or is None, then k defaults to n +and the function returns n!. + +Raises TypeError if either of the arguments are not integers. +Raises ValueError if either of the arguments are negative. +[clinic start generated code]*/ + +static PyObject * +math_perm_impl(PyObject *module, PyObject *n, PyObject *k) +/*[clinic end generated code: output=e021a25469653e23 input=5311c5a00f359b53]*/ +{ + PyObject *result = NULL, *factor = NULL; + int overflow, cmp; + long long i, factors; + + if (k == Py_None) { + return math_factorial(module, n); + } + n = PyNumber_Index(n); + if (n == NULL) { + return NULL; + } + if (!PyLong_CheckExact(n)) { + Py_SETREF(n, _PyLong_Copy((PyLongObject *)n)); + if (n == NULL) { + return NULL; + } + } + k = PyNumber_Index(k); + if (k == NULL) { + Py_DECREF(n); + return NULL; + } + if (!PyLong_CheckExact(k)) { + Py_SETREF(k, _PyLong_Copy((PyLongObject *)k)); + if (k == NULL) { + Py_DECREF(n); + return NULL; + } + } + + if (Py_SIZE(n) < 0) { + PyErr_SetString(PyExc_ValueError, + "n must be a non-negative integer"); + goto error; + } + if (Py_SIZE(k) < 0) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + goto error; + } + + cmp = PyObject_RichCompareBool(n, k, Py_LT); + if (cmp != 0) { + if (cmp > 0) { + result = PyLong_FromLong(0); + goto done; + } + goto error; + } + + factors = PyLong_AsLongLongAndOverflow(k, &overflow); + if (overflow > 0) { + PyErr_Format(PyExc_OverflowError, + "k must not exceed %lld", + LLONG_MAX); + goto error; + } + else if (factors == -1) { + /* k is nonnegative, so a return value of -1 can only indicate error */ + goto error; + } + + if (factors == 0) { + result = PyLong_FromLong(1); + goto done; + } + + result = n; + Py_INCREF(result); + if (factors == 1) { + goto done; + } + + factor = n; + Py_INCREF(factor); + for (i = 1; i < factors; ++i) { + Py_SETREF(factor, PyNumber_Subtract(factor, _PyLong_One)); + if (factor == NULL) { + goto error; + } + Py_SETREF(result, PyNumber_Multiply(result, factor)); + if (result == NULL) { + goto error; + } + } + Py_DECREF(factor); + +done: + Py_DECREF(n); + Py_DECREF(k); + return result; + +error: + Py_XDECREF(factor); + Py_XDECREF(result); + Py_DECREF(n); + Py_DECREF(k); + return NULL; +} + + +/*[clinic input] +math.comb + + n: object + k: object + / + +Number of ways to choose k items from n items without repetition and without order. + +Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates +to zero when k > n. + +Also called the binomial coefficient because it is equivalent +to the coefficient of k-th term in polynomial expansion of the +expression (1 + x)**n. + +Raises TypeError if either of the arguments are not integers. +Raises ValueError if either of the arguments are negative. + +[clinic start generated code]*/ + +static PyObject * +math_comb_impl(PyObject *module, PyObject *n, PyObject *k) +/*[clinic end generated code: output=bd2cec8d854f3493 input=9a05315af2518709]*/ +{ + PyObject *result = NULL, *factor = NULL, *temp; + int overflow, cmp; + long long i, factors; + + n = PyNumber_Index(n); + if (n == NULL) { + return NULL; + } + if (!PyLong_CheckExact(n)) { + Py_SETREF(n, _PyLong_Copy((PyLongObject *)n)); + if (n == NULL) { + return NULL; + } + } + k = PyNumber_Index(k); + if (k == NULL) { + Py_DECREF(n); + return NULL; + } + if (!PyLong_CheckExact(k)) { + Py_SETREF(k, _PyLong_Copy((PyLongObject *)k)); + if (k == NULL) { + Py_DECREF(n); + return NULL; + } + } + + if (Py_SIZE(n) < 0) { + PyErr_SetString(PyExc_ValueError, + "n must be a non-negative integer"); + goto error; + } + if (Py_SIZE(k) < 0) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + goto error; + } + + /* k = min(k, n - k) */ + temp = PyNumber_Subtract(n, k); + if (temp == NULL) { + goto error; + } + if (Py_SIZE(temp) < 0) { + Py_DECREF(temp); + result = PyLong_FromLong(0); + goto done; + } + cmp = PyObject_RichCompareBool(temp, k, Py_LT); + if (cmp > 0) { + Py_SETREF(k, temp); + } + else { + Py_DECREF(temp); + if (cmp < 0) { + goto error; + } + } + + factors = PyLong_AsLongLongAndOverflow(k, &overflow); + if (overflow > 0) { + PyErr_Format(PyExc_OverflowError, + "min(n - k, k) must not exceed %lld", + LLONG_MAX); + goto error; + } + if (factors == -1) { + /* k is nonnegative, so a return value of -1 can only indicate error */ + goto error; + } + + if (factors == 0) { + result = PyLong_FromLong(1); + goto done; + } + + result = n; + Py_INCREF(result); + if (factors == 1) { + goto done; + } + + factor = n; + Py_INCREF(factor); + for (i = 1; i < factors; ++i) { + Py_SETREF(factor, PyNumber_Subtract(factor, _PyLong_One)); + if (factor == NULL) { + goto error; + } + Py_SETREF(result, PyNumber_Multiply(result, factor)); + if (result == NULL) { + goto error; + } + + temp = PyLong_FromUnsignedLongLong((unsigned long long)i + 1); + if (temp == NULL) { + goto error; + } + Py_SETREF(result, PyNumber_FloorDivide(result, temp)); + Py_DECREF(temp); + if (result == NULL) { + goto error; + } + } + Py_DECREF(factor); + +done: + Py_DECREF(n); + Py_DECREF(k); + return result; + +error: + Py_XDECREF(factor); + Py_XDECREF(result); + Py_DECREF(n); + Py_DECREF(k); + return NULL; +} + + +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 + {"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 + 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}, + MATH_GCD_METHODDEF + {"hypot", (PyCFunction)(void(*)(void))math_hypot, METH_FASTCALL, math_hypot_doc}, + MATH_ISCLOSE_METHODDEF + MATH_ISFINITE_METHODDEF + MATH_ISINF_METHODDEF + MATH_ISNAN_METHODDEF + MATH_ISQRT_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 + MATH_PROD_METHODDEF + MATH_PERM_METHODDEF + MATH_COMB_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +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, + "math", + module_doc, + -1, + math_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_math(void) +{ + PyObject *m; + + m = PyModule_Create(&mathmodule); + if (m == NULL) + goto finally; + + 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())); +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); +#endif + + finally: + return m; +} diff --git a/python/Modules/md5module.c b/python/Modules/md5module.c new file mode 100755 index 0000000..64fab80 --- /dev/null +++ b/python/Modules/md5module.c @@ -0,0 +1,584 @@ +/* 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; + + +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_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*/ + 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*/ + 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'' + +Return a new MD5 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +_md5_md5_impl(PyObject *module, PyObject *string) +/*[clinic end generated code: output=2cfd0f8c091b97e6 input=d12ef8f72d684f7b]*/ +{ + 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. */ + +#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } + + +static struct PyModuleDef _md5module = { + PyModuleDef_HEAD_INIT, + "_md5", + NULL, + -1, + MD5_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__md5(void) +{ + PyObject *m; + + Py_TYPE(&MD5type) = &PyType_Type; + if (PyType_Ready(&MD5type) < 0) + return NULL; + + m = PyModule_Create(&_md5module); + if (m == NULL) + return NULL; + + Py_INCREF((PyObject *)&MD5type); + PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type); + return m; +} diff --git a/python/Modules/mmapmodule.c b/python/Modules/mmapmodule.c new file mode 100755 index 0000000..1875886 --- /dev/null +++ b/python/Modules/mmapmodule.c @@ -0,0 +1,1617 @@ +/* + / 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 "structmember.h" + +#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 + int 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 + 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); + Py_END_ALLOW_THREADS + 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); + } + 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??? + */ + HANDLE map_handle = self->map_handle; + HANDLE file_handle = self->file_handle; + char *data = self->data; + self->map_handle = NULL; + self->file_handle = INVALID_HANDLE_VALUE; + self->data = NULL; + 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 + int fd = self->fd; + char *data = self->data; + 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) + Py_RETURN_NONE; + +#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; + } + 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); + + return _PyObject_CallMethodId(self, &PyId_close, NULL); +} + +#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 + +#ifdef HAVE_MADVISE +static PyObject * +mmap_madvise_method(mmap_object *self, PyObject *args) +{ + int option; + Py_ssize_t start = 0, length; + + CHECK_VALID(NULL); + length = self->size; + + if (!PyArg_ParseTuple(args, "i|nn:madvise", &option, &start, &length)) { + return NULL; + } + + if (start < 0 || start >= self->size) { + PyErr_SetString(PyExc_ValueError, "madvise start out of bounds"); + return NULL; + } + if (length < 0) { + PyErr_SetString(PyExc_ValueError, "madvise length invalid"); + return NULL; + } + if (PY_SSIZE_T_MAX - start < length) { + PyErr_SetString(PyExc_OverflowError, "madvise length too large"); + return NULL; + } + + if (start + length > self->size) { + length = self->size - start; + } + + if (madvise(self->data + start, length, option) != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + Py_RETURN_NONE; +} +#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}, +#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); + 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 { + 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 */ + (destructor) mmap_object_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &mmap_as_sequence, /*tp_as_sequence*/ + &mmap_as_mapping, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + 0, /*tp_setattro*/ + &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."); + } + + 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; + + /* VxWorks only supports MAP_ANONYMOUS with MAP_PRIVATE flag */ +#ifdef __VXWORKS__ + flags &= ~MAP_SHARED; + 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; + } + + 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); + 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); + +#ifdef HAVE_MADVISE + // Conventional advice values +#ifdef MADV_NORMAL + setint(dict, "MADV_NORMAL", MADV_NORMAL); +#endif +#ifdef MADV_RANDOM + setint(dict, "MADV_RANDOM", MADV_RANDOM); +#endif +#ifdef MADV_SEQUENTIAL + setint(dict, "MADV_SEQUENTIAL", MADV_SEQUENTIAL); +#endif +#ifdef MADV_WILLNEED + setint(dict, "MADV_WILLNEED", MADV_WILLNEED); +#endif +#ifdef MADV_DONTNEED + setint(dict, "MADV_DONTNEED", MADV_DONTNEED); +#endif + + // Linux-specific advice values +#ifdef MADV_REMOVE + setint(dict, "MADV_REMOVE", MADV_REMOVE); +#endif +#ifdef MADV_DONTFORK + setint(dict, "MADV_DONTFORK", MADV_DONTFORK); +#endif +#ifdef MADV_DOFORK + setint(dict, "MADV_DOFORK", MADV_DOFORK); +#endif +#ifdef MADV_HWPOISON + setint(dict, "MADV_HWPOISON", MADV_HWPOISON); +#endif +#ifdef MADV_MERGEABLE + setint(dict, "MADV_MERGEABLE", MADV_MERGEABLE); +#endif +#ifdef MADV_UNMERGEABLE + setint(dict, "MADV_UNMERGEABLE", MADV_UNMERGEABLE); +#endif +#ifdef MADV_SOFT_OFFLINE + setint(dict, "MADV_SOFT_OFFLINE", MADV_SOFT_OFFLINE); +#endif +#ifdef MADV_HUGEPAGE + setint(dict, "MADV_HUGEPAGE", MADV_HUGEPAGE); +#endif +#ifdef MADV_NOHUGEPAGE + setint(dict, "MADV_NOHUGEPAGE", MADV_NOHUGEPAGE); +#endif +#ifdef MADV_DONTDUMP + setint(dict, "MADV_DONTDUMP", MADV_DONTDUMP); +#endif +#ifdef MADV_DODUMP + setint(dict, "MADV_DODUMP", MADV_DODUMP); +#endif +#ifdef MADV_FREE // (Also present on FreeBSD and macOS.) + setint(dict, "MADV_FREE", MADV_FREE); +#endif + + // FreeBSD-specific +#ifdef MADV_NOSYNC + setint(dict, "MADV_NOSYNC", MADV_NOSYNC); +#endif +#ifdef MADV_AUTOSYNC + setint(dict, "MADV_AUTOSYNC", MADV_AUTOSYNC); +#endif +#ifdef MADV_NOCORE + setint(dict, "MADV_NOCORE", MADV_NOCORE); +#endif +#ifdef MADV_CORE + setint(dict, "MADV_CORE", MADV_CORE); +#endif +#ifdef MADV_PROTECT + setint(dict, "MADV_PROTECT", MADV_PROTECT); +#endif +#endif // HAVE_MADVISE + + return module; +} diff --git a/python/Modules/nismodule.c b/python/Modules/nismodule.c new file mode 100755 index 0000000..e1fa45c --- /dev/null +++ b/python/Modules/nismodule.c @@ -0,0 +1,469 @@ +// /*********************************************************** +// Written by: +// Fred Gansevles +// B&O group, +// Faculteit der Informatica, +// Universiteit Twente, +// Enschede, +// the Netherlands. +// ******************************************************************/ + +// /* NIS module implementation */ + +// #include "Python.h" + +// #include +// #include +// #include +// #include +// #include + +// #ifdef __sgi +// /* This is missing from rpcsvc/ypclnt.h */ +// extern int yp_get_default_domain(char **); +// #endif + +// PyDoc_STRVAR(get_default_domain__doc__, +// "get_default_domain() -> str\n\ +// Corresponds to the C library yp_get_default_domain() call, returning\n\ +// the default NIS domain.\n"); + +// PyDoc_STRVAR(match__doc__, +// "match(key, map, domain = defaultdomain)\n\ +// Corresponds to the C library yp_match() call, returning the value of\n\ +// key in the given map. Optionally domain can be specified but it\n\ +// defaults to the system default domain.\n"); + +// PyDoc_STRVAR(cat__doc__, +// "cat(map, domain = defaultdomain)\n\ +// Returns the entire map as a dictionary. Optionally domain can be\n\ +// specified but it defaults to the system default domain.\n"); + +// PyDoc_STRVAR(maps__doc__, +// "maps(domain = defaultdomain)\n\ +// Returns an array of all available NIS maps within a domain. If domain\n\ +// is not specified it defaults to the system default domain.\n"); + +// static PyObject *NisError; + +// static PyObject * +// nis_error (int err) +// { +// PyErr_SetString(NisError, yperr_string(err)); +// return NULL; +// } + +// static struct nis_map { +// char *alias; +// char *map; +// int fix; +// } aliases [] = { +// {"passwd", "passwd.byname", 0}, +// {"group", "group.byname", 0}, +// {"networks", "networks.byaddr", 0}, +// {"hosts", "hosts.byname", 0}, +// {"protocols", "protocols.bynumber", 0}, +// {"services", "services.byname", 0}, +// {"aliases", "mail.aliases", 1}, /* created with 'makedbm -a' */ +// {"ethers", "ethers.byname", 0}, +// {0L, 0L, 0} +// }; + +// static char * +// nis_mapname (char *map, int *pfix) +// { +// int i; + +// *pfix = 0; +// for (i=0; aliases[i].alias != 0L; i++) { +// if (!strcmp (aliases[i].alias, map) || !strcmp (aliases[i].map, map)) { +// *pfix = aliases[i].fix; +// return aliases[i].map; +// } +// } + +// return map; +// } + +// #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) +// typedef int (*foreachfunc)(unsigned long, char *, int, char *, int, void *); +// #else +// typedef int (*foreachfunc)(int, char *, int, char *, int, char *); +// #endif + +// struct ypcallback_data { +// PyObject *dict; +// int fix; +// PyThreadState *state; +// }; + +// static int +// nis_foreach (int instatus, char *inkey, int inkeylen, char *inval, +// int invallen, struct ypcallback_data *indata) +// { +// if (instatus == YP_TRUE) { +// PyObject *key; +// PyObject *val; +// int err; + +// PyEval_RestoreThread(indata->state); +// if (indata->fix) { +// if (inkeylen > 0 && inkey[inkeylen-1] == '\0') +// inkeylen--; +// if (invallen > 0 && inval[invallen-1] == '\0') +// invallen--; +// } +// key = PyUnicode_DecodeFSDefaultAndSize(inkey, inkeylen); +// val = PyUnicode_DecodeFSDefaultAndSize(inval, invallen); +// if (key == NULL || val == NULL) { +// /* XXX error -- don't know how to handle */ +// PyErr_Clear(); +// Py_XDECREF(key); +// Py_XDECREF(val); +// indata->state = PyEval_SaveThread(); +// return 1; +// } +// err = PyDict_SetItem(indata->dict, key, val); +// Py_DECREF(key); +// Py_DECREF(val); +// if (err != 0) +// PyErr_Clear(); +// indata->state = PyEval_SaveThread(); +// if (err != 0) +// return 1; +// return 0; +// } +// return 1; +// } + +// static PyObject * +// nis_get_default_domain (PyObject *self, PyObject *Py_UNUSED(ignored)) +// { +// char *domain; +// int err; +// PyObject *res; + +// if ((err = yp_get_default_domain(&domain)) != 0) +// return nis_error(err); + +// res = PyUnicode_FromStringAndSize (domain, strlen(domain)); +// return res; +// } + +// static PyObject * +// nis_match (PyObject *self, PyObject *args, PyObject *kwdict) +// { +// char *match; +// char *domain = NULL; +// Py_ssize_t keylen; +// int len; +// char *key, *map; +// int err; +// PyObject *ukey, *bkey, *res; +// int fix; +// static char *kwlist[] = {"key", "map", "domain", NULL}; + +// if (!PyArg_ParseTupleAndKeywords(args, kwdict, +// "Us|s:match", kwlist, +// &ukey, &map, &domain)) +// return NULL; +// if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL) +// return NULL; +// /* check for embedded null bytes */ +// if (PyBytes_AsStringAndSize(bkey, &key, &keylen) == -1) { +// Py_DECREF(bkey); +// return NULL; +// } +// if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) { +// Py_DECREF(bkey); +// return nis_error(err); +// } +// map = nis_mapname (map, &fix); +// if (fix) +// keylen++; +// Py_BEGIN_ALLOW_THREADS +// err = yp_match (domain, map, key, keylen, &match, &len); +// Py_END_ALLOW_THREADS +// Py_DECREF(bkey); +// if (fix) +// len--; +// if (err != 0) +// return nis_error(err); +// res = PyUnicode_DecodeFSDefaultAndSize(match, len); +// free (match); +// return res; +// } + +// static PyObject * +// nis_cat (PyObject *self, PyObject *args, PyObject *kwdict) +// { +// char *domain = NULL; +// char *map; +// struct ypall_callback cb; +// struct ypcallback_data data; +// PyObject *dict; +// int err; +// static char *kwlist[] = {"map", "domain", NULL}; + +// if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|s:cat", +// kwlist, &map, &domain)) +// return NULL; +// if (!domain && ((err = yp_get_default_domain(&domain)) != 0)) +// return nis_error(err); +// dict = PyDict_New (); +// if (dict == NULL) +// return NULL; +// cb.foreach = (foreachfunc)nis_foreach; +// data.dict = dict; +// map = nis_mapname (map, &data.fix); +// cb.data = (char *)&data; +// data.state = PyEval_SaveThread(); +// err = yp_all (domain, map, &cb); +// PyEval_RestoreThread(data.state); +// if (err != 0) { +// Py_DECREF(dict); +// return nis_error(err); +// } +// return dict; +// } + +// /* These should be u_long on Sun h/w but not on 64-bit h/w. +// This is not portable to machines with 16-bit ints and no prototypes */ +// #ifndef YPPROC_MAPLIST +// #define YPPROC_MAPLIST 11 +// #endif +// #ifndef YPPROG +// #define YPPROG 100004 +// #endif +// #ifndef YPVERS +// #define YPVERS 2 +// #endif + +// typedef char *domainname; +// typedef char *mapname; + +// enum nisstat { +// NIS_TRUE = 1, +// NIS_NOMORE = 2, +// NIS_FALSE = 0, +// NIS_NOMAP = -1, +// NIS_NODOM = -2, +// NIS_NOKEY = -3, +// NIS_BADOP = -4, +// NIS_BADDB = -5, +// NIS_YPERR = -6, +// NIS_BADARGS = -7, +// NIS_VERS = -8 +// }; +// typedef enum nisstat nisstat; + +// struct nismaplist { +// mapname map; +// struct nismaplist *next; +// }; +// typedef struct nismaplist nismaplist; + +// struct nisresp_maplist { +// nisstat stat; +// nismaplist *maps; +// }; +// typedef struct nisresp_maplist nisresp_maplist; + +// static struct timeval TIMEOUT = { 25, 0 }; + +// static +// bool_t +// nis_xdr_domainname(XDR *xdrs, domainname *objp) +// { +// if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) { +// return (FALSE); +// } +// return (TRUE); +// } + +// static +// bool_t +// nis_xdr_mapname(XDR *xdrs, mapname *objp) +// { +// if (!xdr_string(xdrs, objp, YPMAXMAP)) { +// return (FALSE); +// } +// return (TRUE); +// } + +// static +// bool_t +// nis_xdr_ypmaplist(XDR *xdrs, nismaplist *objp) +// { +// if (!nis_xdr_mapname(xdrs, &objp->map)) { +// return (FALSE); +// } +// if (!xdr_pointer(xdrs, (char **)&objp->next, +// sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist)) +// { +// return (FALSE); +// } +// return (TRUE); +// } + +// static +// bool_t +// nis_xdr_ypstat(XDR *xdrs, nisstat *objp) +// { +// if (!xdr_enum(xdrs, (enum_t *)objp)) { +// return (FALSE); +// } +// return (TRUE); +// } + + +// static +// bool_t +// nis_xdr_ypresp_maplist(XDR *xdrs, nisresp_maplist *objp) +// { +// if (!nis_xdr_ypstat(xdrs, &objp->stat)) { +// return (FALSE); +// } +// if (!xdr_pointer(xdrs, (char **)&objp->maps, +// sizeof(nismaplist), (xdrproc_t)nis_xdr_ypmaplist)) +// { +// return (FALSE); +// } +// return (TRUE); +// } + + +// static +// nisresp_maplist * +// nisproc_maplist_2(domainname *argp, CLIENT *clnt) +// { +// static nisresp_maplist res; + +// memset(&res, 0, sizeof(res)); +// if (clnt_call(clnt, YPPROC_MAPLIST, +// (xdrproc_t)nis_xdr_domainname, (caddr_t)argp, +// (xdrproc_t)nis_xdr_ypresp_maplist, (caddr_t)&res, +// TIMEOUT) != RPC_SUCCESS) +// { +// return (NULL); +// } +// return (&res); +// } + +// static +// nismaplist * +// nis_maplist (char *dom) +// { +// nisresp_maplist *list; +// CLIENT *cl; +// char *server = NULL; +// int mapi = 0; + +// while (!server && aliases[mapi].map != 0L) { +// yp_master (dom, aliases[mapi].map, &server); +// mapi++; +// } +// if (!server) { +// PyErr_SetString(NisError, "No NIS master found for any map"); +// return NULL; +// } +// cl = clnt_create(server, YPPROG, YPVERS, "tcp"); +// if (cl == NULL) { +// PyErr_SetString(NisError, clnt_spcreateerror(server)); +// goto finally; +// } +// list = nisproc_maplist_2 (&dom, cl); +// clnt_destroy(cl); +// if (list == NULL) +// goto finally; +// if (list->stat != NIS_TRUE) +// goto finally; + +// free(server); +// return list->maps; + +// finally: +// free(server); +// return NULL; +// } + +// static PyObject * +// nis_maps (PyObject *self, PyObject *args, PyObject *kwdict) +// { +// char *domain = NULL; +// nismaplist *maps; +// PyObject *list; +// int err; +// static char *kwlist[] = {"domain", NULL}; + +// if (!PyArg_ParseTupleAndKeywords(args, kwdict, +// "|s:maps", kwlist, &domain)) +// return NULL; +// if (!domain && ((err = yp_get_default_domain (&domain)) != 0)) { +// nis_error(err); +// return NULL; +// } + +// if ((maps = nis_maplist (domain)) == NULL) +// return NULL; +// if ((list = PyList_New(0)) == NULL) +// return NULL; +// for (; maps; maps = maps->next) { +// PyObject *str = PyUnicode_FromString(maps->map); +// if (!str || PyList_Append(list, str) < 0) +// { +// Py_XDECREF(str); +// Py_DECREF(list); +// list = NULL; +// break; +// } +// Py_DECREF(str); +// } +// /* XXX Shouldn't we free the list of maps now? */ +// return list; +// } + +// static PyMethodDef nis_methods[] = { +// {"match", (PyCFunction)(void(*)(void))nis_match, +// METH_VARARGS | METH_KEYWORDS, +// match__doc__}, +// {"cat", (PyCFunction)(void(*)(void))nis_cat, +// METH_VARARGS | METH_KEYWORDS, +// cat__doc__}, +// {"maps", (PyCFunction)(void(*)(void))nis_maps, +// METH_VARARGS | METH_KEYWORDS, +// maps__doc__}, +// {"get_default_domain", nis_get_default_domain, +// METH_NOARGS, +// get_default_domain__doc__}, +// {NULL, NULL} /* Sentinel */ +// }; + +// PyDoc_STRVAR(nis__doc__, +// "This module contains functions for accessing NIS maps.\n"); + +// static struct PyModuleDef nismodule = { +// PyModuleDef_HEAD_INIT, +// "nis", +// nis__doc__, +// -1, +// nis_methods, +// NULL, +// NULL, +// NULL, +// NULL +// }; + +// PyMODINIT_FUNC +// PyInit_nis(void) +// { +// PyObject *m, *d; +// m = PyModule_Create(&nismodule); +// if (m == NULL) +// return NULL; +// d = PyModule_GetDict(m); +// NisError = PyErr_NewException("nis.error", NULL, NULL); +// if (NisError != NULL) +// PyDict_SetItemString(d, "error", NisError); +// return m; +// } diff --git a/python/Modules/ossaudiodev.c b/python/Modules/ossaudiodev.c new file mode 100755 index 0000000..f7712d9 --- /dev/null +++ b/python/Modules/ossaudiodev.c @@ -0,0 +1,1311 @@ +/* + * ossaudiodev -- Python interface to the OSS (Open Sound System) API. + * This is the standard audio API for Linux and some + * flavours of BSD [XXX which ones?]; it is also available + * for a wide range of commercial Unices. + * + * Originally written by Peter Bosch, March 2000, as linuxaudiodev. + * + * Renamed to ossaudiodev and rearranged/revised/hacked up + * by Greg Ward , November 2002. + * Mixer interface by Nicholas FitzRoy-Dale , Dec 2002. + * + * (c) 2000 Peter Bosch. All Rights Reserved. + * (c) 2002 Gregory P. Ward. All Rights Reserved. + * (c) 2002 Python Software Foundation. All Rights Reserved. + * + * XXX need a license statement + * + * $Id$ + */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "structmember.h" + +#ifdef HAVE_FCNTL_H +#include +#else +#define O_RDONLY 00 +#define O_WRONLY 01 +#endif + +#include +#ifdef __ANDROID__ +#include +#else +#include +#endif + +#ifdef __linux__ + +#ifndef HAVE_STDINT_H +typedef unsigned long uint32_t; +#endif + +#elif defined(__FreeBSD__) + +# ifndef SNDCTL_DSP_CHANNELS +# define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS +# endif + +#endif + +typedef struct { + PyObject_HEAD + const char *devicename; /* name of the device file */ + int fd; /* file descriptor */ + int mode; /* file mode (O_RDONLY, etc.) */ + Py_ssize_t icount; /* input count */ + Py_ssize_t ocount; /* output count */ + uint32_t afmts; /* audio formats supported by hardware */ +} oss_audio_t; + +typedef struct { + PyObject_HEAD + int fd; /* The open mixer device */ +} oss_mixer_t; + + +static PyTypeObject OSSAudioType; +static PyTypeObject OSSMixerType; + +static PyObject *OSSAudioError; + + +/* ---------------------------------------------------------------------- + * DSP object initialization/deallocation + */ + +static oss_audio_t * +newossobject(PyObject *arg) +{ + oss_audio_t *self; + int fd, afmts, imode; + const char *devicename = NULL; + const char *mode = NULL; + + /* Two ways to call open(): + open(device, mode) (for consistency with builtin open()) + open(mode) (for backwards compatibility) + because the *first* argument is optional, parsing args is + a wee bit tricky. */ + if (!PyArg_ParseTuple(arg, "s|s:open", &devicename, &mode)) + return NULL; + if (mode == NULL) { /* only one arg supplied */ + mode = devicename; + devicename = NULL; + } + + if (strcmp(mode, "r") == 0) + imode = O_RDONLY; + else if (strcmp(mode, "w") == 0) + imode = O_WRONLY; + else if (strcmp(mode, "rw") == 0) + imode = O_RDWR; + else { + PyErr_SetString(OSSAudioError, "mode must be 'r', 'w', or 'rw'"); + return NULL; + } + + /* Open the correct device: either the 'device' argument, + or the AUDIODEV environment variable, or "/dev/dsp". */ + if (devicename == NULL) { /* called with one arg */ + devicename = getenv("AUDIODEV"); + if (devicename == NULL) /* $AUDIODEV not set */ + devicename = "/dev/dsp"; + } + + /* Open with O_NONBLOCK to avoid hanging on devices that only allow + one open at a time. This does *not* affect later I/O; OSS + provides a special ioctl() for non-blocking read/write, which is + exposed via oss_nonblock() below. */ + fd = _Py_open(devicename, imode|O_NONBLOCK); + if (fd == -1) + return NULL; + + /* And (try to) put it back in blocking mode so we get the + expected write() semantics. */ + if (fcntl(fd, F_SETFL, 0) == -1) { + close(fd); + PyErr_SetFromErrnoWithFilename(PyExc_OSError, devicename); + return NULL; + } + + if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) { + close(fd); + PyErr_SetFromErrnoWithFilename(PyExc_OSError, devicename); + return NULL; + } + /* Create and initialize the object */ + if ((self = PyObject_New(oss_audio_t, &OSSAudioType)) == NULL) { + close(fd); + return NULL; + } + self->devicename = devicename; + self->fd = fd; + self->mode = imode; + self->icount = self->ocount = 0; + self->afmts = afmts; + return self; +} + +static void +oss_dealloc(oss_audio_t *self) +{ + /* if already closed, don't reclose it */ + if (self->fd != -1) + close(self->fd); + PyObject_Del(self); +} + + +/* ---------------------------------------------------------------------- + * Mixer object initialization/deallocation + */ + +static oss_mixer_t * +newossmixerobject(PyObject *arg) +{ + const char *devicename = NULL; + int fd; + oss_mixer_t *self; + + if (!PyArg_ParseTuple(arg, "|s", &devicename)) { + return NULL; + } + + if (devicename == NULL) { + devicename = getenv("MIXERDEV"); + if (devicename == NULL) /* MIXERDEV not set */ + devicename = "/dev/mixer"; + } + + fd = _Py_open(devicename, O_RDWR); + if (fd == -1) + return NULL; + + if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) { + close(fd); + return NULL; + } + + self->fd = fd; + + return self; +} + +static void +oss_mixer_dealloc(oss_mixer_t *self) +{ + /* if already closed, don't reclose it */ + if (self->fd != -1) + close(self->fd); + PyObject_Del(self); +} + + +/* Methods to wrap the OSS ioctls. The calling convention is pretty + simple: + nonblock() -> ioctl(fd, SNDCTL_DSP_NONBLOCK) + fmt = setfmt(fmt) -> ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) + etc. +*/ + + +/* ---------------------------------------------------------------------- + * Helper functions + */ + +/* Check if a given file descriptor is valid (i.e. hasn't been closed). + * If true, return 1. Otherwise, raise ValueError and return 0. + */ +static int _is_fd_valid(int fd) +{ + /* the FD is set to -1 in oss_close()/oss_mixer_close() */ + if (fd >= 0) { + return 1; + } else { + PyErr_SetString(PyExc_ValueError, + "Operation on closed OSS device."); + return 0; + } +} + +/* _do_ioctl_1() is a private helper function used for the OSS ioctls -- + SNDCTL_DSP_{SETFMT,CHANNELS,SPEED} -- that are called from C + like this: + ioctl(fd, SNDCTL_DSP_cmd, &arg) + + where arg is the value to set, and on return the driver sets arg to + the value that was actually set. Mapping this to Python is obvious: + arg = dsp.xxx(arg) +*/ +static PyObject * +_do_ioctl_1(int fd, PyObject *args, char *fname, unsigned long cmd) +{ + char argfmt[33] = "i:"; + int arg; + + assert(strlen(fname) <= 30); + strncat(argfmt, fname, 30); + if (!PyArg_ParseTuple(args, argfmt, &arg)) + return NULL; + + if (ioctl(fd, cmd, &arg) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + return PyLong_FromLong(arg); +} + + +/* _do_ioctl_1_internal() is a wrapper for ioctls that take no inputs + but return an output -- ie. we need to pass a pointer to a local C + variable so the driver can write its output there, but from Python + all we see is the return value. For example, + SOUND_MIXER_READ_DEVMASK returns a bitmask of available mixer + devices, but does not use the value of the parameter passed-in in any + way. +*/ +static PyObject * +_do_ioctl_1_internal(int fd, PyObject *args, char *fname, unsigned long cmd) +{ + char argfmt[32] = ":"; + int arg = 0; + + assert(strlen(fname) <= 30); + strncat(argfmt, fname, 30); + if (!PyArg_ParseTuple(args, argfmt, &arg)) + return NULL; + + if (ioctl(fd, cmd, &arg) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + return PyLong_FromLong(arg); +} + + + +/* _do_ioctl_0() is a private helper for the no-argument ioctls: + SNDCTL_DSP_{SYNC,RESET,POST}. */ +static PyObject * +_do_ioctl_0(int fd, PyObject *args, char *fname, unsigned long cmd) +{ + char argfmt[32] = ":"; + int rv; + + assert(strlen(fname) <= 30); + strncat(argfmt, fname, 30); + if (!PyArg_ParseTuple(args, argfmt)) + return NULL; + + /* According to hannu@opensound.com, all three of the ioctls that + use this function can block, so release the GIL. This is + especially important for SYNC, which can block for several + seconds. */ + Py_BEGIN_ALLOW_THREADS + rv = ioctl(fd, cmd, 0); + Py_END_ALLOW_THREADS + + if (rv == -1) + return PyErr_SetFromErrno(PyExc_OSError); + Py_RETURN_NONE; +} + + +/* ---------------------------------------------------------------------- + * Methods of DSP objects (OSSAudioType) + */ + +static PyObject * +oss_nonblock(oss_audio_t *self, PyObject *unused) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + /* Hmmm: it doesn't appear to be possible to return to blocking + mode once we're in non-blocking mode! */ + if (ioctl(self->fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + Py_RETURN_NONE; +} + +static PyObject * +oss_setfmt(oss_audio_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1(self->fd, args, "setfmt", SNDCTL_DSP_SETFMT); +} + +static PyObject * +oss_getfmts(oss_audio_t *self, PyObject *unused) +{ + int mask; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (ioctl(self->fd, SNDCTL_DSP_GETFMTS, &mask) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + return PyLong_FromLong(mask); +} + +static PyObject * +oss_channels(oss_audio_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1(self->fd, args, "channels", SNDCTL_DSP_CHANNELS); +} + +static PyObject * +oss_speed(oss_audio_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1(self->fd, args, "speed", SNDCTL_DSP_SPEED); +} + +static PyObject * +oss_sync(oss_audio_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_0(self->fd, args, "sync", SNDCTL_DSP_SYNC); +} + +static PyObject * +oss_reset(oss_audio_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_0(self->fd, args, "reset", SNDCTL_DSP_RESET); +} + +static PyObject * +oss_post(oss_audio_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_0(self->fd, args, "post", SNDCTL_DSP_POST); +} + + +/* Regular file methods: read(), write(), close(), etc. as well + as one convenience method, writeall(). */ + +static PyObject * +oss_read(oss_audio_t *self, PyObject *args) +{ + Py_ssize_t size, count; + PyObject *rv; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (!PyArg_ParseTuple(args, "n:read", &size)) + return NULL; + + rv = PyBytes_FromStringAndSize(NULL, size); + if (rv == NULL) + return NULL; + + count = _Py_read(self->fd, PyBytes_AS_STRING(rv), size); + if (count == -1) { + Py_DECREF(rv); + return NULL; + } + + self->icount += count; + _PyBytes_Resize(&rv, count); + return rv; +} + +static PyObject * +oss_write(oss_audio_t *self, PyObject *args) +{ + Py_buffer data; + Py_ssize_t rv; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (!PyArg_ParseTuple(args, "y*:write", &data)) { + return NULL; + } + + rv = _Py_write(self->fd, data.buf, data.len); + PyBuffer_Release(&data); + if (rv == -1) + return NULL; + + self->ocount += rv; + return PyLong_FromLong(rv); +} + +static PyObject * +oss_writeall(oss_audio_t *self, PyObject *args) +{ + Py_buffer data; + const char *cp; + Py_ssize_t size; + Py_ssize_t rv; + fd_set write_set_fds; + int select_rv; + + /* NB. writeall() is only useful in non-blocking mode: according to + Guenter Geiger on the linux-audio-dev list + (http://eca.cx/lad/2002/11/0380.html), OSS guarantees that + write() in blocking mode consumes the whole buffer. In blocking + mode, the behaviour of write() and writeall() from Python is + indistinguishable. */ + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (!PyArg_ParseTuple(args, "y*:writeall", &data)) + return NULL; + + if (!_PyIsSelectable_fd(self->fd)) { + PyErr_SetString(PyExc_ValueError, + "file descriptor out of range for select"); + PyBuffer_Release(&data); + return NULL; + } + /* use select to wait for audio device to be available */ + FD_ZERO(&write_set_fds); + FD_SET(self->fd, &write_set_fds); + cp = (const char *)data.buf; + size = data.len; + + while (size > 0) { + Py_BEGIN_ALLOW_THREADS + select_rv = select(self->fd+1, NULL, &write_set_fds, NULL, NULL); + Py_END_ALLOW_THREADS + + assert(select_rv != 0); /* no timeout, can't expire */ + if (select_rv == -1) { + PyBuffer_Release(&data); + return PyErr_SetFromErrno(PyExc_OSError); + } + + rv = _Py_write(self->fd, cp, Py_MIN(size, INT_MAX)); + if (rv == -1) { + /* buffer is full, try again */ + if (errno == EAGAIN) { + PyErr_Clear(); + continue; + } + /* it's a real error */ + PyBuffer_Release(&data); + return NULL; + } + + /* wrote rv bytes */ + self->ocount += rv; + size -= rv; + cp += rv; + } + PyBuffer_Release(&data); + Py_RETURN_NONE; +} + +static PyObject * +oss_close(oss_audio_t *self, PyObject *unused) +{ + if (self->fd >= 0) { + Py_BEGIN_ALLOW_THREADS + close(self->fd); + Py_END_ALLOW_THREADS + self->fd = -1; + } + Py_RETURN_NONE; +} + +static PyObject * +oss_self(PyObject *self, PyObject *unused) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +oss_exit(PyObject *self, PyObject *unused) +{ + _Py_IDENTIFIER(close); + + PyObject *ret = _PyObject_CallMethodId(self, &PyId_close, NULL); + if (!ret) + return NULL; + Py_DECREF(ret); + Py_RETURN_NONE; +} + +static PyObject * +oss_fileno(oss_audio_t *self, PyObject *unused) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return PyLong_FromLong(self->fd); +} + + +/* Convenience methods: these generally wrap a couple of ioctls into one + common task. */ + +static PyObject * +oss_setparameters(oss_audio_t *self, PyObject *args) +{ + int wanted_fmt, wanted_channels, wanted_rate, strict=0; + int fmt, channels, rate; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (!PyArg_ParseTuple(args, "iii|i:setparameters", + &wanted_fmt, &wanted_channels, &wanted_rate, + &strict)) + return NULL; + + fmt = wanted_fmt; + if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + if (strict && fmt != wanted_fmt) { + return PyErr_Format + (OSSAudioError, + "unable to set requested format (wanted %d, got %d)", + wanted_fmt, fmt); + } + + channels = wanted_channels; + if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + if (strict && channels != wanted_channels) { + return PyErr_Format + (OSSAudioError, + "unable to set requested channels (wanted %d, got %d)", + wanted_channels, channels); + } + + rate = wanted_rate; + if (ioctl(self->fd, SNDCTL_DSP_SPEED, &rate) == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + if (strict && rate != wanted_rate) { + return PyErr_Format + (OSSAudioError, + "unable to set requested rate (wanted %d, got %d)", + wanted_rate, rate); + } + + /* Construct the return value: a (fmt, channels, rate) tuple that + tells what the audio hardware was actually set to. */ + return Py_BuildValue("(iii)", fmt, channels, rate); +} + +static int +_ssize(oss_audio_t *self, int *nchannels, int *ssize) +{ + int fmt; + + fmt = 0; + if (ioctl(self->fd, SNDCTL_DSP_SETFMT, &fmt) < 0) + return -errno; + + switch (fmt) { + case AFMT_MU_LAW: + case AFMT_A_LAW: + case AFMT_U8: + case AFMT_S8: + *ssize = 1; /* 8 bit formats: 1 byte */ + break; + case AFMT_S16_LE: + case AFMT_S16_BE: + case AFMT_U16_LE: + case AFMT_U16_BE: + *ssize = 2; /* 16 bit formats: 2 byte */ + break; + case AFMT_MPEG: + case AFMT_IMA_ADPCM: + default: + return -EOPNOTSUPP; + } + if (ioctl(self->fd, SNDCTL_DSP_CHANNELS, nchannels) < 0) + return -errno; + return 0; +} + + +/* bufsize returns the size of the hardware audio buffer in number + of samples */ +static PyObject * +oss_bufsize(oss_audio_t *self, PyObject *unused) +{ + audio_buf_info ai; + int nchannels=0, ssize=0; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyLong_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize)); +} + +/* obufcount returns the number of samples that are available in the + hardware for playing */ +static PyObject * +oss_obufcount(oss_audio_t *self, PyObject *unused) +{ + audio_buf_info ai; + int nchannels=0, ssize=0; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyLong_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) / + (ssize * nchannels)); +} + +/* obufcount returns the number of samples that can be played without + blocking */ +static PyObject * +oss_obuffree(oss_audio_t *self, PyObject *unused) +{ + audio_buf_info ai; + int nchannels=0, ssize=0; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyLong_FromLong(ai.bytes / (ssize * nchannels)); +} + +static PyObject * +oss_getptr(oss_audio_t *self, PyObject *unused) +{ + count_info info; + int req; + + if (!_is_fd_valid(self->fd)) + return NULL; + + if (self->mode == O_RDONLY) + req = SNDCTL_DSP_GETIPTR; + else + req = SNDCTL_DSP_GETOPTR; + if (ioctl(self->fd, req, &info) == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr); +} + + +/* ---------------------------------------------------------------------- + * Methods of mixer objects (OSSMixerType) + */ + +static PyObject * +oss_mixer_close(oss_mixer_t *self, PyObject *unused) +{ + if (self->fd >= 0) { + close(self->fd); + self->fd = -1; + } + Py_RETURN_NONE; +} + +static PyObject * +oss_mixer_fileno(oss_mixer_t *self, PyObject *unused) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return PyLong_FromLong(self->fd); +} + +/* Simple mixer interface methods */ + +static PyObject * +oss_mixer_controls(oss_mixer_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1_internal(self->fd, args, "controls", + SOUND_MIXER_READ_DEVMASK); +} + +static PyObject * +oss_mixer_stereocontrols(oss_mixer_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1_internal(self->fd, args, "stereocontrols", + SOUND_MIXER_READ_STEREODEVS); +} + +static PyObject * +oss_mixer_reccontrols(oss_mixer_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1_internal(self->fd, args, "reccontrols", + SOUND_MIXER_READ_RECMASK); +} + +static PyObject * +oss_mixer_get(oss_mixer_t *self, PyObject *args) +{ + int channel, volume; + + if (!_is_fd_valid(self->fd)) + return NULL; + + /* Can't use _do_ioctl_1 because of encoded arg thingy. */ + if (!PyArg_ParseTuple(args, "i:get", &channel)) + return NULL; + + if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) { + PyErr_SetString(OSSAudioError, "Invalid mixer channel specified."); + return NULL; + } + + if (ioctl(self->fd, MIXER_READ(channel), &volume) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8); +} + +static PyObject * +oss_mixer_set(oss_mixer_t *self, PyObject *args) +{ + int channel, volume, leftVol, rightVol; + + if (!_is_fd_valid(self->fd)) + return NULL; + + /* Can't use _do_ioctl_1 because of encoded arg thingy. */ + if (!PyArg_ParseTuple(args, "i(ii):set", &channel, &leftVol, &rightVol)) + return NULL; + + if (channel < 0 || channel > SOUND_MIXER_NRDEVICES) { + PyErr_SetString(OSSAudioError, "Invalid mixer channel specified."); + return NULL; + } + + if (leftVol < 0 || rightVol < 0 || leftVol > 100 || rightVol > 100) { + PyErr_SetString(OSSAudioError, "Volumes must be between 0 and 100."); + return NULL; + } + + volume = (rightVol << 8) | leftVol; + + if (ioctl(self->fd, MIXER_WRITE(channel), &volume) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + return Py_BuildValue("(ii)", volume & 0xff, (volume & 0xff00) >> 8); +} + +static PyObject * +oss_mixer_get_recsrc(oss_mixer_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1_internal(self->fd, args, "get_recsrc", + SOUND_MIXER_READ_RECSRC); +} + +static PyObject * +oss_mixer_set_recsrc(oss_mixer_t *self, PyObject *args) +{ + if (!_is_fd_valid(self->fd)) + return NULL; + + return _do_ioctl_1(self->fd, args, "set_recsrc", + SOUND_MIXER_WRITE_RECSRC); +} + + +/* ---------------------------------------------------------------------- + * Method tables and other bureaucracy + */ + +static PyMethodDef oss_methods[] = { + /* Regular file methods */ + { "read", (PyCFunction)oss_read, METH_VARARGS }, + { "write", (PyCFunction)oss_write, METH_VARARGS }, + { "writeall", (PyCFunction)oss_writeall, METH_VARARGS }, + { "close", (PyCFunction)oss_close, METH_NOARGS }, + { "fileno", (PyCFunction)oss_fileno, METH_NOARGS }, + + /* Simple ioctl wrappers */ + { "nonblock", (PyCFunction)oss_nonblock, METH_NOARGS }, + { "setfmt", (PyCFunction)oss_setfmt, METH_VARARGS }, + { "getfmts", (PyCFunction)oss_getfmts, METH_NOARGS }, + { "channels", (PyCFunction)oss_channels, METH_VARARGS }, + { "speed", (PyCFunction)oss_speed, METH_VARARGS }, + { "sync", (PyCFunction)oss_sync, METH_VARARGS }, + { "reset", (PyCFunction)oss_reset, METH_VARARGS }, + { "post", (PyCFunction)oss_post, METH_VARARGS }, + + /* Convenience methods -- wrap a couple of ioctls together */ + { "setparameters", (PyCFunction)oss_setparameters, METH_VARARGS }, + { "bufsize", (PyCFunction)oss_bufsize, METH_NOARGS }, + { "obufcount", (PyCFunction)oss_obufcount, METH_NOARGS }, + { "obuffree", (PyCFunction)oss_obuffree, METH_NOARGS }, + { "getptr", (PyCFunction)oss_getptr, METH_NOARGS }, + + /* Aliases for backwards compatibility */ + { "flush", (PyCFunction)oss_sync, METH_VARARGS }, + + /* Support for the context management protocol */ + { "__enter__", oss_self, METH_NOARGS }, + { "__exit__", oss_exit, METH_VARARGS }, + + { NULL, NULL} /* sentinel */ +}; + +static PyMethodDef oss_mixer_methods[] = { + /* Regular file method - OSS mixers are ioctl-only interface */ + { "close", (PyCFunction)oss_mixer_close, METH_NOARGS }, + { "fileno", (PyCFunction)oss_mixer_fileno, METH_NOARGS }, + + /* Support for the context management protocol */ + { "__enter__", oss_self, METH_NOARGS }, + { "__exit__", oss_exit, METH_VARARGS }, + + /* Simple ioctl wrappers */ + { "controls", (PyCFunction)oss_mixer_controls, METH_VARARGS }, + { "stereocontrols", (PyCFunction)oss_mixer_stereocontrols, METH_VARARGS}, + { "reccontrols", (PyCFunction)oss_mixer_reccontrols, METH_VARARGS}, + { "get", (PyCFunction)oss_mixer_get, METH_VARARGS }, + { "set", (PyCFunction)oss_mixer_set, METH_VARARGS }, + { "get_recsrc", (PyCFunction)oss_mixer_get_recsrc, METH_VARARGS }, + { "set_recsrc", (PyCFunction)oss_mixer_set_recsrc, METH_VARARGS }, + + { NULL, NULL} +}; + +static PyMemberDef oss_members[] = { + {"name", T_STRING, offsetof(oss_audio_t, devicename), READONLY, NULL}, + {NULL} +}; + +static PyObject * +oss_closed_getter(oss_audio_t *self, void *closure) +{ + return PyBool_FromLong(self->fd == -1); +} + +static PyObject * +oss_mode_getter(oss_audio_t *self, void *closure) +{ + switch(self->mode) { + case O_RDONLY: + return PyUnicode_FromString("r"); + break; + case O_RDWR: + return PyUnicode_FromString("rw"); + break; + case O_WRONLY: + return PyUnicode_FromString("w"); + break; + default: + /* From newossobject(), self->mode can only be one + of these three values. */ + Py_UNREACHABLE(); + } +} + +static PyGetSetDef oss_getsetlist[] = { + {"closed", (getter)oss_closed_getter, (setter)NULL, NULL}, + {"mode", (getter)oss_mode_getter, (setter)NULL, NULL}, + {NULL}, +}; + +static PyTypeObject OSSAudioType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "ossaudiodev.oss_audio_device", /*tp_name*/ + sizeof(oss_audio_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)oss_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*/ + oss_methods, /*tp_methods*/ + oss_members, /*tp_members*/ + oss_getsetlist, /*tp_getset*/ +}; + +static PyTypeObject OSSMixerType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "ossaudiodev.oss_mixer_device", /*tp_name*/ + sizeof(oss_mixer_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)oss_mixer_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*/ + oss_mixer_methods, /*tp_methods*/ +}; + + +static PyObject * +ossopen(PyObject *self, PyObject *args) +{ + return (PyObject *)newossobject(args); +} + +static PyObject * +ossopenmixer(PyObject *self, PyObject *args) +{ + return (PyObject *)newossmixerobject(args); +} + +static PyMethodDef ossaudiodev_methods[] = { + { "open", ossopen, METH_VARARGS }, + { "openmixer", ossopenmixer, METH_VARARGS }, + { 0, 0 }, +}; + + +#define _EXPORT_INT(mod, name) \ + if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return NULL; + + +static char *control_labels[] = SOUND_DEVICE_LABELS; +static char *control_names[] = SOUND_DEVICE_NAMES; + + +static int +build_namelists (PyObject *module) +{ + PyObject *labels; + PyObject *names; + PyObject *s; + int num_controls; + int i; + + num_controls = Py_ARRAY_LENGTH(control_labels); + assert(num_controls == Py_ARRAY_LENGTH(control_names)); + + labels = PyList_New(num_controls); + names = PyList_New(num_controls); + if (labels == NULL || names == NULL) + goto error2; + for (i = 0; i < num_controls; i++) { + s = PyUnicode_FromString(control_labels[i]); + if (s == NULL) + goto error2; + PyList_SET_ITEM(labels, i, s); + + s = PyUnicode_FromString(control_names[i]); + if (s == NULL) + goto error2; + PyList_SET_ITEM(names, i, s); + } + + if (PyModule_AddObject(module, "control_labels", labels) == -1) + goto error2; + if (PyModule_AddObject(module, "control_names", names) == -1) + goto error1; + + return 0; + +error2: + Py_XDECREF(labels); +error1: + Py_XDECREF(names); + return -1; +} + + +static struct PyModuleDef ossaudiodevmodule = { + PyModuleDef_HEAD_INIT, + "ossaudiodev", + NULL, + -1, + ossaudiodev_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_ossaudiodev(void) +{ + PyObject *m; + + if (PyType_Ready(&OSSAudioType) < 0) + return NULL; + + if (PyType_Ready(&OSSMixerType) < 0) + return NULL; + + m = PyModule_Create(&ossaudiodevmodule); + if (m == NULL) + return NULL; + + OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError", + NULL, NULL); + if (OSSAudioError) { + /* Each call to PyModule_AddObject decrefs it; compensate: */ + Py_INCREF(OSSAudioError); + Py_INCREF(OSSAudioError); + PyModule_AddObject(m, "error", OSSAudioError); + PyModule_AddObject(m, "OSSAudioError", OSSAudioError); + } + + /* Build 'control_labels' and 'control_names' lists and add them + to the module. */ + if (build_namelists(m) == -1) /* XXX what to do here? */ + return NULL; + + /* Expose the audio format numbers -- essential! */ + _EXPORT_INT(m, AFMT_QUERY); + _EXPORT_INT(m, AFMT_MU_LAW); + _EXPORT_INT(m, AFMT_A_LAW); + _EXPORT_INT(m, AFMT_IMA_ADPCM); + _EXPORT_INT(m, AFMT_U8); + _EXPORT_INT(m, AFMT_S16_LE); + _EXPORT_INT(m, AFMT_S16_BE); + _EXPORT_INT(m, AFMT_S8); + _EXPORT_INT(m, AFMT_U16_LE); + _EXPORT_INT(m, AFMT_U16_BE); + _EXPORT_INT(m, AFMT_MPEG); +#ifdef AFMT_AC3 + _EXPORT_INT(m, AFMT_AC3); +#endif +#ifdef AFMT_S16_NE + _EXPORT_INT(m, AFMT_S16_NE); +#endif +#ifdef AFMT_U16_NE + _EXPORT_INT(m, AFMT_U16_NE); +#endif +#ifdef AFMT_S32_LE + _EXPORT_INT(m, AFMT_S32_LE); +#endif +#ifdef AFMT_S32_BE + _EXPORT_INT(m, AFMT_S32_BE); +#endif +#ifdef AFMT_MPEG + _EXPORT_INT(m, AFMT_MPEG); +#endif + + /* Expose the sound mixer device numbers. */ + _EXPORT_INT(m, SOUND_MIXER_NRDEVICES); + _EXPORT_INT(m, SOUND_MIXER_VOLUME); + _EXPORT_INT(m, SOUND_MIXER_BASS); + _EXPORT_INT(m, SOUND_MIXER_TREBLE); + _EXPORT_INT(m, SOUND_MIXER_SYNTH); + _EXPORT_INT(m, SOUND_MIXER_PCM); + _EXPORT_INT(m, SOUND_MIXER_SPEAKER); + _EXPORT_INT(m, SOUND_MIXER_LINE); + _EXPORT_INT(m, SOUND_MIXER_MIC); + _EXPORT_INT(m, SOUND_MIXER_CD); + _EXPORT_INT(m, SOUND_MIXER_IMIX); + _EXPORT_INT(m, SOUND_MIXER_ALTPCM); + _EXPORT_INT(m, SOUND_MIXER_RECLEV); + _EXPORT_INT(m, SOUND_MIXER_IGAIN); + _EXPORT_INT(m, SOUND_MIXER_OGAIN); + _EXPORT_INT(m, SOUND_MIXER_LINE1); + _EXPORT_INT(m, SOUND_MIXER_LINE2); + _EXPORT_INT(m, SOUND_MIXER_LINE3); +#ifdef SOUND_MIXER_DIGITAL1 + _EXPORT_INT(m, SOUND_MIXER_DIGITAL1); +#endif +#ifdef SOUND_MIXER_DIGITAL2 + _EXPORT_INT(m, SOUND_MIXER_DIGITAL2); +#endif +#ifdef SOUND_MIXER_DIGITAL3 + _EXPORT_INT(m, SOUND_MIXER_DIGITAL3); +#endif +#ifdef SOUND_MIXER_PHONEIN + _EXPORT_INT(m, SOUND_MIXER_PHONEIN); +#endif +#ifdef SOUND_MIXER_PHONEOUT + _EXPORT_INT(m, SOUND_MIXER_PHONEOUT); +#endif +#ifdef SOUND_MIXER_VIDEO + _EXPORT_INT(m, SOUND_MIXER_VIDEO); +#endif +#ifdef SOUND_MIXER_RADIO + _EXPORT_INT(m, SOUND_MIXER_RADIO); +#endif +#ifdef SOUND_MIXER_MONITOR + _EXPORT_INT(m, SOUND_MIXER_MONITOR); +#endif + + /* Expose all the ioctl numbers for masochists who like to do this + stuff directly. */ + _EXPORT_INT(m, SNDCTL_COPR_HALT); + _EXPORT_INT(m, SNDCTL_COPR_LOAD); + _EXPORT_INT(m, SNDCTL_COPR_RCODE); + _EXPORT_INT(m, SNDCTL_COPR_RCVMSG); + _EXPORT_INT(m, SNDCTL_COPR_RDATA); + _EXPORT_INT(m, SNDCTL_COPR_RESET); + _EXPORT_INT(m, SNDCTL_COPR_RUN); + _EXPORT_INT(m, SNDCTL_COPR_SENDMSG); + _EXPORT_INT(m, SNDCTL_COPR_WCODE); + _EXPORT_INT(m, SNDCTL_COPR_WDATA); +#ifdef SNDCTL_DSP_BIND_CHANNEL + _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL); +#endif + _EXPORT_INT(m, SNDCTL_DSP_CHANNELS); + _EXPORT_INT(m, SNDCTL_DSP_GETBLKSIZE); + _EXPORT_INT(m, SNDCTL_DSP_GETCAPS); +#ifdef SNDCTL_DSP_GETCHANNELMASK + _EXPORT_INT(m, SNDCTL_DSP_GETCHANNELMASK); +#endif + _EXPORT_INT(m, SNDCTL_DSP_GETFMTS); + _EXPORT_INT(m, SNDCTL_DSP_GETIPTR); + _EXPORT_INT(m, SNDCTL_DSP_GETISPACE); +#ifdef SNDCTL_DSP_GETODELAY + _EXPORT_INT(m, SNDCTL_DSP_GETODELAY); +#endif + _EXPORT_INT(m, SNDCTL_DSP_GETOPTR); + _EXPORT_INT(m, SNDCTL_DSP_GETOSPACE); +#ifdef SNDCTL_DSP_GETSPDIF + _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF); +#endif + _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER); + _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF); + _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF); + _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK); + _EXPORT_INT(m, SNDCTL_DSP_POST); +#ifdef SNDCTL_DSP_PROFILE + _EXPORT_INT(m, SNDCTL_DSP_PROFILE); +#endif + _EXPORT_INT(m, SNDCTL_DSP_RESET); + _EXPORT_INT(m, SNDCTL_DSP_SAMPLESIZE); + _EXPORT_INT(m, SNDCTL_DSP_SETDUPLEX); + _EXPORT_INT(m, SNDCTL_DSP_SETFMT); + _EXPORT_INT(m, SNDCTL_DSP_SETFRAGMENT); +#ifdef SNDCTL_DSP_SETSPDIF + _EXPORT_INT(m, SNDCTL_DSP_SETSPDIF); +#endif + _EXPORT_INT(m, SNDCTL_DSP_SETSYNCRO); + _EXPORT_INT(m, SNDCTL_DSP_SETTRIGGER); + _EXPORT_INT(m, SNDCTL_DSP_SPEED); + _EXPORT_INT(m, SNDCTL_DSP_STEREO); + _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE); + _EXPORT_INT(m, SNDCTL_DSP_SYNC); + _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE); + _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR); + _EXPORT_INT(m, SNDCTL_MIDI_INFO); + _EXPORT_INT(m, SNDCTL_MIDI_MPUCMD); + _EXPORT_INT(m, SNDCTL_MIDI_MPUMODE); + _EXPORT_INT(m, SNDCTL_MIDI_PRETIME); + _EXPORT_INT(m, SNDCTL_SEQ_CTRLRATE); + _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT); + _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT); +#ifdef SNDCTL_SEQ_GETTIME + _EXPORT_INT(m, SNDCTL_SEQ_GETTIME); +#endif + _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS); + _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS); + _EXPORT_INT(m, SNDCTL_SEQ_OUTOFBAND); + _EXPORT_INT(m, SNDCTL_SEQ_PANIC); + _EXPORT_INT(m, SNDCTL_SEQ_PERCMODE); + _EXPORT_INT(m, SNDCTL_SEQ_RESET); + _EXPORT_INT(m, SNDCTL_SEQ_RESETSAMPLES); + _EXPORT_INT(m, SNDCTL_SEQ_SYNC); + _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI); + _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD); +#ifdef SNDCTL_SYNTH_CONTROL + _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL); +#endif +#ifdef SNDCTL_SYNTH_ID + _EXPORT_INT(m, SNDCTL_SYNTH_ID); +#endif + _EXPORT_INT(m, SNDCTL_SYNTH_INFO); + _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL); +#ifdef SNDCTL_SYNTH_REMOVESAMPLE + _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE); +#endif + _EXPORT_INT(m, SNDCTL_TMR_CONTINUE); + _EXPORT_INT(m, SNDCTL_TMR_METRONOME); + _EXPORT_INT(m, SNDCTL_TMR_SELECT); + _EXPORT_INT(m, SNDCTL_TMR_SOURCE); + _EXPORT_INT(m, SNDCTL_TMR_START); + _EXPORT_INT(m, SNDCTL_TMR_STOP); + _EXPORT_INT(m, SNDCTL_TMR_TEMPO); + _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE); + return m; +} diff --git a/python/Modules/overlapped.c b/python/Modules/overlapped.c new file mode 100755 index 0000000..2b57f69 --- /dev/null +++ b/python/Modules/overlapped.c @@ -0,0 +1,1881 @@ +// /* +// * 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" + +// #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; + +// 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_READ_FROM: +// if(self->read_from.result) { +// Py_VISIT(self->read_from.result); +// } +// if(self->read_from.allocated_buffer) { +// Py_VISIT(self->read_from.allocated_buffer); +// } +// } +// return 0; +// } + +// // UDP functions + +// PyDoc_STRVAR( +// WSAConnect_doc, +// "WSAConnect(client_handle, address_as_bytes) -> Overlapped[None]\n\n" +// "Bind a remote address to a connectionless (UDP) socket"); + +// /* +// * Note: WSAConnect does not support Overlapped I/O so this function should +// * _only_ be used for connectionless sockets (UDP). +// */ +// static PyObject * +// overlapped_WSAConnect(PyObject *self, PyObject *args) +// { +// SOCKET ConnectSocket; +// PyObject *AddressObj; +// char AddressBuf[sizeof(struct sockaddr_in6)]; +// SOCKADDR *Address = (SOCKADDR*)AddressBuf; +// int Length; +// int err; + +// if (!PyArg_ParseTuple(args, F_HANDLE "O", &ConnectSocket, &AddressObj)) { +// return NULL; +// } + +// Length = sizeof(AddressBuf); +// Length = parse_address(AddressObj, Address, Length); +// if (Length < 0) { +// return NULL; +// } + +// Py_BEGIN_ALLOW_THREADS +// // WSAConnect does not support overlapped I/O so this call will +// // successfully complete immediately. +// err = WSAConnect(ConnectSocket, Address, Length, +// NULL, NULL, NULL, NULL); +// Py_END_ALLOW_THREADS + +// if (err == 0) { +// Py_RETURN_NONE; +// } +// else { +// return SetFromWindowsErr(WSAGetLastError()); +// } +// } + +// PyDoc_STRVAR( +// Overlapped_WSASendTo_doc, +// "WSASendTo(handle, buf, flags, address_as_bytes) -> " +// "Overlapped[bytes_transferred]\n\n" +// "Start overlapped sendto over a connectionless (UDP) socket"); + +// static PyObject * +// Overlapped_WSASendTo(OverlappedObject *self, PyObject *args) +// { +// HANDLE handle; +// PyObject *bufobj; +// DWORD flags; +// PyObject *AddressObj; +// char AddressBuf[sizeof(struct sockaddr_in6)]; +// SOCKADDR *Address = (SOCKADDR*)AddressBuf; +// int AddressLength; +// DWORD written; +// WSABUF wsabuf; +// int ret; +// DWORD err; + +// if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD "O", +// &handle, &bufobj, &flags, &AddressObj)) +// { +// return NULL; +// } + +// // Parse the "to" address +// AddressLength = sizeof(AddressBuf); +// AddressLength = parse_address(AddressObj, Address, AddressLength); +// if (AddressLength < 0) { +// 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_TO; +// self->handle = handle; +// wsabuf.len = (DWORD)self->user_buffer.len; +// wsabuf.buf = self->user_buffer.buf; + +// Py_BEGIN_ALLOW_THREADS +// ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags, +// Address, AddressLength, &self->overlapped, NULL); +// Py_END_ALLOW_THREADS + +// self->error = err = (ret == SOCKET_ERROR ? WSAGetLastError() : +// ERROR_SUCCESS); + +// switch(err) { +// case ERROR_SUCCESS: +// case ERROR_IO_PENDING: +// Py_RETURN_NONE; +// default: +// self->type = TYPE_NOT_STARTED; +// return SetFromWindowsErr(err); +// } +// } + + + +// PyDoc_STRVAR( +// Overlapped_WSARecvFrom_doc, +// "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n" +// "Start overlapped receive"); + +// static PyObject * +// Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *args) +// { +// HANDLE handle; +// DWORD size; +// DWORD flags = 0; +// DWORD nread; +// PyObject *buf; +// WSABUF wsabuf; +// int ret; +// DWORD err; + +// 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; +// } + +// wsabuf.len = size; +// wsabuf.buf = PyBytes_AS_STRING(buf); + +// self->type = TYPE_READ_FROM; +// self->handle = handle; +// self->read_from.allocated_buffer = buf; +// memset(&self->read_from.address, 0, sizeof(self->read_from.address)); +// self->read_from.address_length = sizeof(self->read_from.address); + +// Py_BEGIN_ALLOW_THREADS +// ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags, +// (SOCKADDR*)&self->read_from.address, +// &self->read_from.address_length, +// &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: +// self->type = TYPE_NOT_STARTED; +// return SetFromWindowsErr(err); +// } +// } + + +// 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, +// /* 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 */ 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}, +// {"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; + +// if (PyType_Ready(&OverlappedType) < 0) +// return NULL; + +// m = PyModule_Create(&overlapped_module); +// if (PyModule_AddObject(m, "Overlapped", (PyObject *)&OverlappedType) < 0) +// 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; +// } diff --git a/python/Modules/parsermodule.c b/python/Modules/parsermodule.c new file mode 100755 index 0000000..079d00f --- /dev/null +++ b/python/Modules/parsermodule.c @@ -0,0 +1,1221 @@ +/* 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 */ + /* 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[] = { + {"compile", (PyCFunction)(void(*)(void))parser_compilest, PUBLIC_METHOD_TYPE, + 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.")}, + {"issuite", (PyCFunction)(void(*)(void))parser_issuite, PUBLIC_METHOD_TYPE, + 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.")}, + {"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 */ + 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 */ + + /* 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) ((v)->ob_type == &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; + 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); + if (res) { + ((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; + } + const dfa *nt_dfa = &_PyParser_Grammar.g_dfa[type]; + 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); + if ((ch_type >= NT_OFFSET + _PyParser_Grammar.g_ndfas) + || (ISTERMINAL(ch_type) && (ch_type >= N_TOKENS)) + || (ch_type < 0) + ) { + PyErr_Format(parser_error, "Unrecognized node type %d.", ch_type); + return 0; + } + if (ch_type == suite && TYPE(tree) == funcdef) { + /* This is the opposite hack of what we do in parser.c + (search for func_body_suite), except we don't ever + 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); + + 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; + + 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; + + if (ISNONTERMINAL(next_type)) { + PyErr_Format(parser_error, "Expected %s, got %s.", + _PyParser_Grammar.g_dfa[next_type - NT_OFFSET].d_name, + ISTERMINAL(ch_type) ? _PyParser_TokenNames[ch_type] : + _PyParser_Grammar.g_dfa[ch_type - NT_OFFSET].d_name); + } + else if (expected_str != NULL) { + PyErr_Format(parser_error, "Illegal terminal: expected '%s'.", + 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"); + } + 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; + PyObject *empty_dict = NULL; + + if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) { + PyObject *newargs; + PyObject *tuple; + + if ((empty_dict = PyDict_New()) == NULL) + goto finally; + if ((newargs = Py_BuildValue("Oi", st, 1)) == NULL) + goto finally; + tuple = parser_st2tuple((PyST_Object*)NULL, newargs, empty_dict); + if (tuple != NULL) { + result = Py_BuildValue("O(O)", pickle_constructor, tuple); + Py_DECREF(tuple); + } + Py_DECREF(newargs); + } + finally: + Py_XDECREF(empty_dict); + + 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.")}, + {"expr", (PyCFunction)(void(*)(void))parser_expr, PUBLIC_METHOD_TYPE, + 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.")}, + {"issuite", (PyCFunction)(void(*)(void))parser_issuite, PUBLIC_METHOD_TYPE, + 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.")}, + {"sequence2st", (PyCFunction)(void(*)(void))parser_tuple2st, PUBLIC_METHOD_TYPE, + 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.")}, + {"st2list", (PyCFunction)(void(*)(void))parser_st2list, PUBLIC_METHOD_TYPE, + 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; + + 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/python/Modules/posixmodule.c b/python/Modules/posixmodule.c new file mode 100755 index 0000000..d7edabe --- /dev/null +++ b/python/Modules/posixmodule.c @@ -0,0 +1,14854 @@ + +/* 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'. */ + + + +#ifdef __APPLE__ + /* + * Step 1 of support for weak-linking a number of symbols existing on + * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block + * at the end of this file for more information. + */ +# pragma weak lchown +# pragma weak statvfs +# pragma weak fstatvfs + +#endif /* __APPLE__ */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#ifdef MS_WINDOWS + /* include early to avoid conflict with pycore_condvar.h: + + #define WIN32_LEAN_AND_MEAN + #include + + FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */ +# include +# include +#endif + +#include "pycore_ceval.h" /* _PyEval_ReInitThreads() */ +#include "pycore_pystate.h" /* _PyRuntime */ +#include "pythread.h" +#include "structmember.h" +#ifndef MS_WINDOWS +# include "posixmodule.h" +#else +# include "winreparse.h" +#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() */ + +#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() */ +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif /* HAVE_SYS_TYPES_H */ + +#ifdef HAVE_SYS_STAT_H +#include +#endif /* HAVE_SYS_STAT_H */ + +#ifdef HAVE_SYS_WAIT_H +#include /* For WNOHANG */ +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif /* HAVE_FCNTL_H */ + +#ifdef HAVE_GRP_H +#include +#endif + +#ifdef HAVE_SYSEXITS_H +#include +#endif /* HAVE_SYSEXITS_H */ + +#ifdef HAVE_SYS_LOADAVG_H +#include +#endif + +#ifdef HAVE_SYS_SENDFILE_H +#include +#endif + +#if defined(__APPLE__) +#include +#endif + +#ifdef HAVE_SCHED_H +#include +#endif + +#ifdef HAVE_COPY_FILE_RANGE +#include +#endif + +#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__) +#define USE_XATTRS +#endif + +#ifdef USE_XATTRS +#include +#endif + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#endif + +#ifdef HAVE_DLFCN_H +#include +#endif + +#ifdef __hpux +#include +#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 */ +#define HAVE_OPENDIR 1 +#define HAVE_SYSTEM 1 +#include +#else +#ifdef _MSC_VER /* Microsoft compiler */ +#define HAVE_GETPPID 1 +#define HAVE_GETLOGIN 1 +#define HAVE_SPAWNV 1 +#define HAVE_EXECV 1 +#define HAVE_WSPAWNV 1 +#define HAVE_WEXECV 1 +#define HAVE_PIPE 1 +#define HAVE_SYSTEM 1 +#define HAVE_CWAIT 1 +#define HAVE_FSYNC 1 +#define fsync _commit +#else +/* Unix functions that the configure script doesn't check for */ +#ifndef __VXWORKS__ +#define HAVE_EXECV 1 +#define HAVE_FORK 1 +#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ +#define HAVE_FORK1 1 +#endif +#endif +#define HAVE_GETEGID 1 +#define HAVE_GETEUID 1 +#define HAVE_GETGID 1 +#define HAVE_GETPPID 1 +#define HAVE_GETUID 1 +#define HAVE_KILL 1 +#define HAVE_OPENDIR 1 +#define HAVE_PIPE 1 +#define HAVE_SYSTEM 1 +#define HAVE_WAIT 1 +#define HAVE_TTYNAME 1 +#endif /* _MSC_VER */ +#endif /* ! __WATCOMC__ || __QNX__ */ + + +/*[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__) +#include +#include +#include +#include +#ifndef _P_WAIT +#define _P_WAIT 0 +#define _P_NOWAIT 1 +#define _P_NOWAITO 1 +#endif +#endif /* __VXWORKS__ */ + +#ifdef HAVE_POSIX_SPAWN +#include +#endif + +#ifdef HAVE_UTIME_H +#include +#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 +#include +#endif /* HAVE_SYS_TIMES_H */ + +#ifdef HAVE_SYS_PARAM_H +#include +#endif /* HAVE_SYS_PARAM_H */ + +#ifdef HAVE_SYS_UTSNAME_H +#include +#endif /* HAVE_SYS_UTSNAME_H */ + +#ifdef HAVE_DIRENT_H +#include +#define NAMLEN(dirent) strlen((dirent)->d_name) +#else +#if defined(__WATCOMC__) && !defined(__QNX__) +#include +#define NAMLEN(dirent) strlen((dirent)->d_name) +#else +#define dirent direct +#define NAMLEN(dirent) (dirent)->d_namlen +#endif +#ifdef HAVE_SYS_NDIR_H +#include +#endif +#ifdef HAVE_SYS_DIR_H +#include +#endif +#ifdef HAVE_NDIR_H +#include +#endif +#endif + +#ifdef _MSC_VER +#ifdef HAVE_DIRECT_H +#include +#endif +#ifdef HAVE_IO_H +#include +#endif +#ifdef HAVE_PROCESS_H +#include +#endif +#ifndef IO_REPARSE_TAG_SYMLINK +#define IO_REPARSE_TAG_SYMLINK (0xA000000CL) +#endif +#ifndef IO_REPARSE_TAG_MOUNT_POINT +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) +#endif +#include "osdefs.h" +#include +#include +#include /* for ShellExecute() */ +#include /* for UNLEN */ +#define HAVE_SYMLINK +#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 +/* 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) +#endif + +#ifndef WEXITSTATUS +#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) +#endif + +#ifndef WTERMSIG +#define WTERMSIG(u_wait) ((u_wait).w_termsig) +#endif + +#define WAIT_TYPE union wait +#define WAIT_STATUS_INT(s) (s.w_status) + +#else /* !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) +#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 +# define STAT win32_stat +# define LSTAT win32_lstat +# define FSTAT _Py_fstat_noraise +# define STRUCT_STAT struct _Py_stat_struct +#else +# define STAT stat +# define LSTAT lstat +# define FSTAT fstat +# define STRUCT_STAT struct stat +#endif + +#if defined(MAJOR_IN_MKDEV) +#include +#else +#if defined(MAJOR_IN_SYSMACROS) +#include +#endif +#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) +#include +#endif +#endif + +#ifdef MS_WINDOWS +#define INITFUNC PyInit_nt +#define MODNAME "nt" +#else +#define INITFUNC PyInit_posix +#define MODNAME "posix" +#endif + +#if defined(__sun) +/* Something to implement in autoconf, not present in autoconf 2.69 */ +#define HAVE_STRUCT_STAT_ST_FSTYPE 1 +#endif + +/* memfd_create is either defined in sys/mman.h or sys/memfd.h + * linux/memfd.h defines additional flags + */ +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_SYS_MEMFD_H +#include +#endif +#ifdef HAVE_LINUX_MEMFD_H +#include +#endif + +#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); + res = PyObject_CallObject(func, NULL); + 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"); + + run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0); +} + +void +PyOS_AfterFork_Child(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + _PyGILState_Reinit(runtime); + _PyEval_ReInitThreads(runtime); + _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); +} +#endif + +/* 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 *); +#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, void *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", + Py_TYPE(obj)->tp_name); + 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); + *(uid_t *)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, void *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", + Py_TYPE(obj)->tp_name); + 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); + *(gid_t *)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", + Py_TYPE(o)->tp_name); + return 0; + } +} + + +/* + * 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. */ + _Py_IDENTIFIER(__fspath__); + 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", Py_TYPE(o)->tp_name, + Py_TYPE(res)->tp_name); + 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 + wide = PyUnicode_AsUnicodeAndSize(o, &length); + 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", + Py_TYPE(o)->tp_name)) { + 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", + Py_TYPE(o)->tp_name); + 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; + } + + wide = PyUnicode_AsUnicodeAndSize(wo, &length); + 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); + } + 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; + } + } + } + if (!PyErr_Occurred()) { + Py_DECREF(iterator); + return 1; + } + +error: + Py_DECREF(iterator); + return 0; +} +#endif /* HAVE_SIGSET_T */ + +#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 (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: + 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 +}; +static PyTypeObject* WaitidResultType; +#endif + +static int initialized; +static PyTypeObject* StatResultType; +static PyTypeObject* StatVFSResultType; +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) +static PyTypeObject* SchedParamType; +#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 PyObject *billion = NULL; + +static void +fill_time(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, 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(STRUCT_STAT *st) +{ + unsigned long ansec, mnsec, cnsec; + PyObject *v = PyStructSequence_New(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(v, 7, st->st_atime, ansec); + fill_time(v, 8, st->st_mtime, mnsec); + fill_time(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(const char *function_name, path_t *path, + int dir_fd, int follow_symlinks) +{ + STRUCT_STAT st; + int result; + +#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) + result = fstatat(dir_fd, path->narrow, &st, + follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); + else +#endif /* HAVE_FSTATAT */ + result = STAT(path->narrow, &st); +#endif /* MS_WINDOWS */ + Py_END_ALLOW_THREADS + + if (result != 0) { + return path_error(path); + } + + return _pystat_fromstructstat(&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" + +class sched_param_converter(CConverter): + type = 'struct sched_param' + converter = 'convert_sched_param' + impl_by_reference = True; + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/ + +/*[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("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("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 + +#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) { + 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 +#endif + result = access(path->narrow, mode); + Py_END_ALLOW_THREADS + 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]*/ +{ + char *ret; + + ret = ttyname(fd); + if (ret == NULL) { + return posix_error(); + } + return PyUnicode_DecodeFSDefault(ret); +} +#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; +#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 +#ifdef HAVE_LCHMOD + if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) + result = lchmod(path->narrow, mode); + else +#endif +#ifdef HAVE_FCHMODAT + if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) { + /* + * 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 +#endif + result = chmod(path->narrow, mode); + Py_END_ALLOW_THREADS + + if (result) { +#ifdef HAVE_FCHMODAT + 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 + return path_error(path); + } +#endif + + 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_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; + +#ifdef __APPLE__ + /* + * This is for Mac OS X 10.3, which doesn't have lchown. + * (But we still have an lchown symbol because of weak-linking.) + * It doesn't have fchownat either. So there's no possibility + * of a graceful failover. + */ + if ((!follow_symlinks) && (lchown == NULL)) { + follow_symlinks_specified("chown", follow_symlinks); + return NULL; + } +#endif + + 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)) + result = fchownat(dir_fd, path->narrow, uid, gid, + follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); + else +#endif + result = chown(path->narrow, uid, gid); + Py_END_ALLOW_THREADS + + 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 + +#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)) + result = linkat(src_dir_fd, src->narrow, + dst_dir_fd, dst->narrow, + follow_symlinks ? AT_SYMLINK_FOLLOW : 0); + else +#endif /* HAVE_LINKAT */ + result = link(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + + 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) { + /* 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 +#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 woutbuf[MAX_PATH], *woutbufp = woutbuf; + wchar_t *wtemp; + DWORD result; + PyObject *v; + + result = GetFullPathNameW(path->wide, + Py_ARRAY_LENGTH(woutbuf), + woutbuf, &wtemp); + if (result > Py_ARRAY_LENGTH(woutbuf)) { + woutbufp = PyMem_New(wchar_t, result); + if (!woutbufp) + return PyErr_NoMemory(); + result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp); + } + if (result) { + v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp)); + if (path->narrow) + Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); + } else + v = win32_error_object("GetFullPathNameW", path->object); + if (woutbufp != woutbuf) + PyMem_Free(woutbufp); + return v; +} + + +/*[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; + + 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 (buffer[0] && buffer[1] == L':') { + if (buffer[2] == L'\\') { + end = &buffer[3]; + } else { + end = &buffer[2]; + } + } else { + end = PathSkipRootW(buffer); + } + Py_END_ALLOW_THREADS + if (!end || end == buffer) { + result = Py_BuildValue("sO", "", path->object); + } else if (!*end) { + result = Py_BuildValue("Os", path->object, ""); + } else { + size_t rootLen = (size_t)(end - buffer); + result = Py_BuildValue("NN", + PyUnicode_FromWideChar(path->wide, rootLen), + PyUnicode_FromWideChar(path->wide + rootLen, -1) + ); + } + 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; + + 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) + result = mkdirat(dir_fd, path->narrow, mode); + else +#endif +#if defined(__WATCOMC__) && !defined(__QNX__) + result = mkdir(path->narrow); +#else + result = mkdir(path->narrow, mode); +#endif + Py_END_ALLOW_THREADS + 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 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) + result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); + else +#endif + result = rename(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + + 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; + + 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) + result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR); + else +#endif + result = rmdir(path->narrow); +#endif + Py_END_ALLOW_THREADS + + 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; + + 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) + result = unlinkat(dir_fd, path->narrow, 0); + else +#endif /* HAVE_UNLINKAT */ + result = unlink(path->narrow); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + 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 = { + "uname_result", /* name */ + uname_result__doc__, /* doc */ + uname_result_fields, + 5 +}; + +static PyTypeObject* UnameResultType; + + +#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(); + + value = PyStructSequence_New(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) +{ +#ifdef 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 + UTIME_TO_TIMESPEC; + return futimens(fd, time); +#else + 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 + UTIME_TO_TIMESPEC; + return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW); +#else + UTIME_TO_TIMEVAL; + return lutimes(path, time); +#endif +} + +#endif + +#ifndef MS_WINDOWS + +static int +utime_default(utime_t *ut, const char *path) +{ +#ifdef 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 *py_long, time_t *s, long *ns) +{ + int result = 0; + PyObject *divmod; + divmod = PyNumber_Divmod(py_long, 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", + Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name); + 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(PyTuple_GET_ITEM(ns, 0), + &utime.atime_s, &utime.atime_ns) || + !split_py_long_to_s_and_ns(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 (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 *param, struct sched_param *res); +#endif + +static int +parse_posix_spawn_flags(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 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 + } + + 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; + } + + if (scheduler) { +#ifdef POSIX_SPAWN_SETSCHEDULER + PyObject *py_schedpolicy; + struct sched_param schedparam; + + if (!PyArg_ParseTuple(scheduler, "OO&" + ";A scheduler tuple must have two elements", + &py_schedpolicy, convert_sched_param, &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(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, Py_TYPE(obj)->tp_name); + 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; + + if (_PyInterpreterState_Get() != PyInterpreterState_Main()) { + PyErr_SetString(PyExc_RuntimeError, "fork not supported for 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 identifiedy 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=5f14cfd1f189e1a0]*/ +{ + 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. + +Current 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=ab4de35a9a7811f2]*/ +{ + 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 *param, struct sched_param *res) +{ + long priority; + + if (Py_TYPE(param) != 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: sched_param + / + +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, + struct sched_param *param) +/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/ +{ + /* + ** 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, param) == -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(); + result = PyStructSequence_New(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: sched_param + / + +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, + struct sched_param *param) +/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/ +{ + if (sched_setparam(pid, param)) + 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 +#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 + +/* AC 3.5: funny apple logic below */ +PyDoc_STRVAR(posix_getgrouplist__doc__, +"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\ +Returns a list of groups to which a user belongs.\n\n\ + user: username to lookup\n\ + group: base group id of the user"); + +static PyObject * +posix_getgrouplist(PyObject *self, PyObject *args) +{ + const char *user; + int i, ngroups; + PyObject *list; +#ifdef __APPLE__ + int *groups, basegid; +#else + gid_t *groups, basegid; +#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; + +#ifdef __APPLE__ + if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid)) + return NULL; +#else + if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user, + _Py_Gid_Converter, &basegid)) + return NULL; +#endif + + 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 +PyDoc_STRVAR(posix_initgroups__doc__, +"initgroups(username, gid) -> None\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."); + +/* AC 3.5: funny apple logic */ +static PyObject * +posix_initgroups(PyObject *self, PyObject *args) +{ + PyObject *oname; + const char *username; + int res; +#ifdef __APPLE__ + int gid; +#else + gid_t gid; +#endif + +#ifdef __APPLE__ + if (!PyArg_ParseTuple(args, "O&i:initgroups", + PyUnicode_FSConverter, &oname, + &gid)) +#else + if (!PyArg_ParseTuple(args, "O&O&:initgroups", + PyUnicode_FSConverter, &oname, + _Py_Gid_Converter, &gid)) +#endif + return NULL; + username = PyBytes_AS_STRING(oname); + + res = initgroups(username, gid); + Py_DECREF(oname); + if (res == -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(pid_t pid, int status, struct rusage *ru) +{ + PyObject *result; + static PyObject *struct_rusage; + _Py_IDENTIFIER(struct_rusage); + + if (pid == -1) + return posix_error(); + + if (struct_rusage == NULL) { + PyObject *m = PyImport_ImportModuleNoBlock("resource"); + if (m == NULL) + return NULL; + struct_rusage = _PyObject_GetAttrId(m, &PyId_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); + 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(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(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; + + result = PyStructSequence_New(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(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; + + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_READLINKAT + if (dir_fd != DEFAULT_DIR_FD) + length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN); + else +#endif + length = readlink(path->narrow, buffer, MAXPATHLEN); + Py_END_ALLOW_THREADS + + 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; +#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 +#if HAVE_SYMLINKAT + if (dir_fd != DEFAULT_DIR_FD) + result = symlinkat(src->narrow, dir_fd, dst->narrow); + else +#endif + result = symlink(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + + 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 +}; + +static PyTypeObject* TimesResultType; + +#ifdef MS_WINDOWS +#define HAVE_TIMES /* mandatory, for the method table */ +#endif + +#ifdef HAVE_TIMES + +static PyObject * +build_times_result(double user, double system, + double children_user, double children_system, + double elapsed) +{ + PyObject *value = PyStructSequence_New(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( + (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( + (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 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) + fd = openat(dir_fd, path->narrow, flags, mode); + 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 + + 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) + 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]; +#else + int i; +#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 + for (i = Py_MAX(fd_low, 0); i < fd_high; i++) + 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] +# TODO length should be size_t! but Python doesn't support parsing size_t yet. +os.pread + + fd: int + length: int + 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, int length, Py_off_t offset) +/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/ +{ + 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 { + 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 + + 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 +PyDoc_STRVAR(posix_sendfile__doc__, +"sendfile(out, in, offset, count) -> byteswritten\n\ +sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\ + -> byteswritten\n\ +Copy count bytes from file descriptor in to file descriptor out."); + +/* AC 3.5: don't bother converting, has optional group*/ +static PyObject * +posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) +{ + int in, out; + Py_ssize_t ret; + int async_err = 0; + off_t offset; + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#ifndef __APPLE__ + Py_ssize_t len; +#endif + PyObject *headers = NULL, *trailers = NULL; + Py_buffer *hbuf, *tbuf; + off_t sbytes; + struct sf_hdtr sf; + int flags = 0; + /* Beware that "in" clashes with Python's own "in" operator keyword */ + static char *keywords[] = {"out", "in", + "offset", "count", + "headers", "trailers", "flags", NULL}; + + sf.headers = NULL; + sf.trailers = NULL; + +#ifdef __APPLE__ + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", + keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes, +#else + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile", + keywords, &out, &in, Py_off_t_converter, &offset, &len, +#endif + &headers, &trailers, &flags)) + return 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, out, offset, &sbytes, &sf, flags); +#else + ret = sendfile(in, out, offset, len, &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 + Py_ssize_t count; + PyObject *offobj; + static char *keywords[] = {"out", "in", + "offset", "count", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile", + keywords, &out, &in, &offobj, &count)) + return NULL; +#ifdef __linux__ + if (offobj == Py_None) { + do { + Py_BEGIN_ALLOW_THREADS + ret = sendfile(out, in, 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 + if (!Py_off_t_converter(offobj, &offset)) + return NULL; + + +#if defined(__sun) && defined(__SVR4) + // 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, in, &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 + + infd: int + outfd: 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 infd, int outfd, int flags) +/*[clinic end generated code: output=8e8885c721ec38e3 input=69e0770e600cb44f]*/ +{ + int ret; + + Py_BEGIN_ALLOW_THREADS + ret = fcopyfile(infd, outfd, 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(&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_SUPPRESS_IPH + return_value = isatty(fd); + _Py_END_SUPPRESS_IPH + 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 + 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())); +#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 HAVE_PUTENV + +/* Save putenv() parameters as values here, so we can collect them when they + * get re-set with another call for the same key. */ +static PyObject *posix_putenv_garbage; + +static void +posix_putenv_garbage_setitem(PyObject *name, PyObject *value) +{ + /* Install the first arg and newstr in posix_putenv_garbage; + * this will cause previous value to be collected. This has to + * happen after the real putenv() call because the old value + * was still accessible until then. */ + if (PyDict_SetItem(posix_putenv_garbage, name, value)) + /* really not much we can do; just leak */ + PyErr_Clear(); + else + Py_DECREF(value); +} + + +#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]*/ +{ + const wchar_t *env; + Py_ssize_t size; + + /* 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 = PyUnicode_FromFormat("%U=%U", name, value); + if (unicode == NULL) { + return NULL; + } + + env = PyUnicode_AsUnicodeAndSize(unicode, &size); + if (env == NULL) + goto error; + if (size > _MAX_ENV) { + PyErr_Format(PyExc_ValueError, + "the environment variable is longer than %u characters", + _MAX_ENV); + goto error; + } + if (wcslen(env) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto error; + } + + if (_wputenv(env)) { + posix_error(); + goto error; + } + + posix_putenv_garbage_setitem(name, unicode); + Py_RETURN_NONE; + +error: + Py_DECREF(unicode); + return NULL; +} +#else /* MS_WINDOWS */ +/*[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]*/ +{ + PyObject *bytes = NULL; + char *env; + 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; + } + bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); + if (bytes == NULL) { + return NULL; + } + + env = PyBytes_AS_STRING(bytes); + if (putenv(env)) { + Py_DECREF(bytes); + return posix_error(); + } + + posix_putenv_garbage_setitem(name, bytes); + Py_RETURN_NONE; +} +#endif /* MS_WINDOWS */ +#endif /* HAVE_PUTENV */ + + +#ifdef HAVE_UNSETENV +/*[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]*/ +{ +#ifndef HAVE_BROKEN_UNSETENV + int err; +#endif + + if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { + return NULL; + } + +#ifdef HAVE_BROKEN_UNSETENV + unsetenv(PyBytes_AS_STRING(name)); +#else + err = unsetenv(PyBytes_AS_STRING(name)); + if (err) + return posix_error(); +#endif + + /* Remove the key from posix_putenv_garbage; + * this will cause it to be collected. This has to + * happen after the real unsetenv() call because the + * old value was still accessible until then. + */ + if (PyDict_DelItem(posix_putenv_garbage, name)) { + /* really not much we can do; just leak */ + if (!PyErr_ExceptionMatches(PyExc_KeyError)) { + return NULL; + } + PyErr_Clear(); + } + Py_RETURN_NONE; +} +#endif /* HAVE_UNSETENV */ + + +/*[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(struct statvfs st) { + PyObject *v = PyStructSequence_New(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(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) { +#ifdef __APPLE__ + /* handle weak-linking on Mac OS X 10.3 */ + if (fstatvfs == NULL) { + fd_specified("statvfs", path->fd); + return NULL; + } +#endif + 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(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_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; + } + + 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; + } + + 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; + } + + 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; + } + + 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; + } + + 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.memfd_create + + name: FSConverter + flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC + +[clinic start generated code]*/ + +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); + } + return PyLong_FromLong(fd); +} +#endif + +/* Terminal size querying */ + +static PyTypeObject* TerminalSizeType; + +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) +/* AC 3.5: fd should accept None */ +PyDoc_STRVAR(termsize__doc__, + "Return the size of the terminal window as (columns, lines).\n" \ + "\n" \ + "The optional argument fd (default standard output) specifies\n" \ + "which file descriptor should be queried.\n" \ + "\n" \ + "If the file descriptor is not connected to a terminal, an OSError\n" \ + "is thrown.\n" \ + "\n" \ + "This function will only be defined if an implementation is\n" \ + "available for this system.\n" \ + "\n" \ + "shutil.get_terminal_size is the high-level function which should\n" \ + "normally be used, os.get_terminal_size is the low-level implementation."); + +static PyObject* +get_terminal_size(PyObject *self, PyObject *args) +{ + int columns, lines; + PyObject *termsize; + + int fd = fileno(stdout); + /* 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. + */ + + if (!PyArg_ParseTuple(args, "|i", &fd)) + return NULL; + +#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 */ + + termsize = PyStructSequence_New(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 + /* Declare prototype here to avoid pulling in all of the Win7 APIs in 3.8 */ + DWORD WINAPI GetActiveProcessorCount(WORD group); + 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. + +Return False if the O_NONBLOCK flag is set, True if the flag is cleared. +[clinic start generated code]*/ + +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. + +Set the O_NONBLOCK flag if blocking is False, +clear the O_NONBLOCK flag otherwise. +[clinic start generated code]*/ + +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=3138f09f7c683f1d]*/ + +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 void +DirEntry_dealloc(DirEntry *entry) +{ + Py_XDECREF(entry->name); + Py_XDECREF(entry->path); + Py_XDECREF(entry->stat); + Py_XDECREF(entry->lstat); + Py_TYPE(entry)->tp_free((PyObject *)entry); +} + +/* Forward reference */ +static int +DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits); + +/*[clinic input] +os.DirEntry.is_symlink -> bool + +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) +/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/ +{ +#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(self, 0, S_IFLNK); +#else + /* POSIX without d_type */ + return DirEntry_test_mode(self, 0, S_IFLNK); +#endif +} + +static PyObject * +DirEntry_fetch_stat(DirEntry *self, int follow_symlinks) +{ + int result; + STRUCT_STAT st; + PyObject *ub; + +#ifdef MS_WINDOWS + if (!PyUnicode_FSDecoder(self->path, &ub)) + return NULL; + const wchar_t *path = PyUnicode_AsUnicode(ub); +#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 + result = fstatat(self->dir_fd, path, &st, + follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); +#else + PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat"); + return NULL; +#endif /* HAVE_FSTATAT */ + } + 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(&st); +} + +static PyObject * +DirEntry_get_lstat(DirEntry *self) +{ + if (!self->lstat) { +#ifdef MS_WINDOWS + self->lstat = _pystat_fromstructstat(&self->win32_lstat); +#else /* POSIX */ + self->lstat = DirEntry_fetch_stat(self, 0); +#endif + } + Py_XINCREF(self->lstat); + return self->lstat; +} + +/*[clinic input] +os.DirEntry.stat + * + 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, int follow_symlinks) +/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/ +{ + if (!follow_symlinks) + return DirEntry_get_lstat(self); + + if (!self->stat) { + int result = os_DirEntry_is_symlink_impl(self); + if (result == -1) + return NULL; + else if (result) + self->stat = DirEntry_fetch_stat(self, 1); + else + self->stat = DirEntry_get_lstat(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(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 + _Py_IDENTIFIER(st_mode); + +#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, 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; + } + st_mode = _PyObject_GetAttrId(stat, &PyId_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 + * + 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, int follow_symlinks) +/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/ +{ + return DirEntry_test_mode(self, follow_symlinks, S_IFDIR); +} + +/*[clinic input] +os.DirEntry.is_file -> bool + * + 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, int follow_symlinks) +/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/ +{ + return DirEntry_test_mode(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; + path = PyUnicode_AsUnicode(unicode); + 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 + {NULL} +}; + +static PyTypeObject DirEntryType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODNAME ".DirEntry", /* tp_name */ + sizeof(DirEntry), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)DirEntry_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)DirEntry_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 */ + DirEntry_methods, /* tp_methods */ + DirEntry_members, /* tp_members */ +}; + +#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(path_t *path, WIN32_FIND_DATAW *dataW) +{ + DirEntry *entry; + BY_HANDLE_FILE_INFORMATION file_info; + ULONG reparse_tag; + wchar_t *joined_path; + + entry = PyObject_New(DirEntry, &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(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; + + entry = PyObject_New(DirEntry, &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) { + entry = DirEntry_from_find_data(&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) { + entry = DirEntry_from_posix_info(&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) +{ + if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) + return; + + Py_TYPE(iterator)->tp_free((PyObject *)iterator); +} + +static PyMethodDef ScandirIterator_methods[] = { + {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, + {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, + {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, + {NULL} +}; + +static PyTypeObject ScandirIteratorType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODNAME ".ScandirIterator", /* tp_name */ + sizeof(ScandirIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)ScandirIterator_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 */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)ScandirIterator_iternext, /* tp_iternext */ + ScandirIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + (destructor)ScandirIterator_finalize, /* tp_finalize */ +}; + +/*[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; + } + + iterator = PyObject_New(ScandirIterator, &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 (path->fd != -1) { + /* 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 +#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(). */ + _Py_IDENTIFIER(__fspath__); + 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", + Py_TYPE(path)->tp_name); + } + + 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", Py_TYPE(path)->tp_name, + Py_TYPE(path_repr)->tp_name); + 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); + +/*[clinic input] +os._add_dll_directory + + path: path_t + +Add a path to the DLL search path. + +This search path is used when resolving dependencies for imported +extension modules (the module itself is resolved through sys.path), +and also by ctypes. + +Returns an opaque value that may be passed to os.remove_dll_directory +to remove this directory from the search path. +[clinic start generated code]*/ + +static PyObject * +os__add_dll_directory_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/ +{ + HMODULE hKernel32; + PAddDllDirectory AddDllDirectory; + DLL_DIRECTORY_COOKIE cookie = 0; + DWORD err = 0; + + if (PySys_Audit("os.add_dll_directory", "(O)", path->object) < 0) { + return NULL; + } + + /* For Windows 7, we have to load this. As this will be a fairly + infrequent operation, just do it each time. Kernel32 is always + loaded. */ + Py_BEGIN_ALLOW_THREADS + if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || + !(AddDllDirectory = (PAddDllDirectory)GetProcAddress( + hKernel32, "AddDllDirectory")) || + !(cookie = (*AddDllDirectory)(path->wide))) { + err = GetLastError(); + } + Py_END_ALLOW_THREADS + + if (err) { + return win32_error_object_err("add_dll_directory", + path->object, err); + } + + return PyCapsule_New(cookie, "DLL directory cookie", NULL); +} + +/*[clinic input] +os._remove_dll_directory + + cookie: object + +Removes a path from the DLL search path. + +The parameter is an opaque value that was returned from +os.add_dll_directory. You can only remove directories that you added +yourself. +[clinic start generated code]*/ + +static PyObject * +os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) +/*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/ +{ + HMODULE hKernel32; + PRemoveDllDirectory RemoveDllDirectory; + DLL_DIRECTORY_COOKIE cookieValue; + DWORD err = 0; + + if (!PyCapsule_IsValid(cookie, "DLL directory cookie")) { + PyErr_SetString(PyExc_TypeError, + "Provided cookie was not returned from os.add_dll_directory"); + return NULL; + } + + cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer( + cookie, "DLL directory cookie"); + + /* For Windows 7, we have to load this. As this will be a fairly + infrequent operation, just do it each time. Kernel32 is always + loaded. */ + Py_BEGIN_ALLOW_THREADS + if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || + !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress( + hKernel32, "RemoveDllDirectory")) || + !(*RemoveDllDirectory)(cookieValue)) { + err = GetLastError(); + } + Py_END_ALLOW_THREADS + + if (err) { + return win32_error_object_err("remove_dll_directory", + NULL, err); + } + + if (PyCapsule_SetName(cookie, NULL)) { + return NULL; + } + + Py_RETURN_NONE; +} + +#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 + 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__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 +#ifdef HAVE_GETGROUPLIST + {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__}, +#endif + 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 +#ifdef MS_WINDOWS + OS_STARTFILE_METHODDEF +#endif + OS_SETUID_METHODDEF + OS_SETEUID_METHODDEF + OS_SETREUID_METHODDEF + OS_SETGID_METHODDEF + OS_SETEGID_METHODDEF + OS_SETREGID_METHODDEF + OS_SETGROUPS_METHODDEF +#ifdef HAVE_INITGROUPS + {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, +#endif /* HAVE_INITGROUPS */ + OS_GETPGID_METHODDEF + OS_SETPGRP_METHODDEF + OS_WAIT_METHODDEF + OS_WAIT3_METHODDEF + OS_WAIT4_METHODDEF + OS_WAITID_METHODDEF + OS_WAITPID_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 +#ifdef HAVE_SENDFILE + {"sendfile", (PyCFunction)(void(*)(void))posix_sendfile, METH_VARARGS | METH_KEYWORDS, + posix_sendfile__doc__}, +#endif + 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 + +#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) + {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__}, +#endif + OS_CPU_COUNT_METHODDEF + OS_GET_INHERITABLE_METHODDEF + OS_SET_INHERITABLE_METHODDEF + OS_GET_HANDLE_INHERITABLE_METHODDEF + OS_SET_HANDLE_INHERITABLE_METHODDEF +#ifndef MS_WINDOWS + OS_GET_BLOCKING_METHODDEF + OS_SET_BLOCKING_METHODDEF +#endif + OS_SCANDIR_METHODDEF + OS_FSPATH_METHODDEF + OS_GETRANDOM_METHODDEF + OS_MEMFD_CREATE_METHODDEF +#ifdef MS_WINDOWS + OS__ADD_DLL_DIRECTORY_METHODDEF + OS__REMOVE_DLL_DIRECTORY_METHODDEF +#endif + {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; +#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_DUMPED + if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1; +#endif +#ifdef CLD_TRAPPED + if (PyModule_AddIntMacro(m, CLD_TRAPPED)) 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; + if (PyModule_AddIntConstant(m, "POSIX_SPAWN_CLOSE", POSIX_SPAWN_CLOSE)) return -1; + if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1; +#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_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 +#ifdef HAVE_MEMFD_CREATE + if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1; + if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1; +#ifdef MFD_HUGETLB + if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1; +#endif +#ifdef MFD_HUGE_SHIFT + if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1; +#endif +#ifdef MFD_HUGE_MASK + if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1; +#endif +#ifdef MFD_HUGE_64KB + if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1; +#endif +#ifdef MFD_HUGE_512KB + if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1; +#endif +#ifdef MFD_HUGE_1MB + if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1; +#endif +#ifdef MFD_HUGE_2MB + if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1; +#endif +#ifdef MFD_HUGE_8MB + if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1; +#endif +#ifdef MFD_HUGE_16MB + if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1; +#endif +#ifdef MFD_HUGE_32MB + if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1; +#endif +#ifdef MFD_HUGE_256MB + if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1; +#endif +#ifdef MFD_HUGE_512MB + if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1; +#endif +#ifdef MFD_HUGE_1GB + if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1; +#endif +#ifdef MFD_HUGE_2GB + if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1; +#endif +#ifdef MFD_HUGE_16GB + 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 + +#ifdef MS_WINDOWS + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_APPLICATION_DIR", LOAD_LIBRARY_SEARCH_APPLICATION_DIR)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_SYSTEM32", LOAD_LIBRARY_SEARCH_SYSTEM32)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_USER_DIRS", LOAD_LIBRARY_SEARCH_USER_DIRS)) return -1; + if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1; +#endif + + return 0; +} + + +static struct PyModuleDef posixmodule = { + PyModuleDef_HEAD_INIT, + MODNAME, + posix__doc__, + -1, + posix_methods, + NULL, + NULL, + NULL, + NULL +}; + + +static const char * const have_functions[] = { + +#ifdef HAVE_FACCESSAT + "HAVE_FACCESSAT", +#endif + +#ifdef HAVE_FCHDIR + "HAVE_FCHDIR", +#endif + +#ifdef HAVE_FCHMOD + "HAVE_FCHMOD", +#endif + +#ifdef HAVE_FCHMODAT + "HAVE_FCHMODAT", +#endif + +#ifdef HAVE_FCHOWN + "HAVE_FCHOWN", +#endif + +#ifdef HAVE_FCHOWNAT + "HAVE_FCHOWNAT", +#endif + +#ifdef HAVE_FEXECVE + "HAVE_FEXECVE", +#endif + +#ifdef HAVE_FDOPENDIR + "HAVE_FDOPENDIR", +#endif + +#ifdef HAVE_FPATHCONF + "HAVE_FPATHCONF", +#endif + +#ifdef HAVE_FSTATAT + "HAVE_FSTATAT", +#endif + +#ifdef HAVE_FSTATVFS + "HAVE_FSTATVFS", +#endif + +#if defined HAVE_FTRUNCATE || defined MS_WINDOWS + "HAVE_FTRUNCATE", +#endif + +#ifdef HAVE_FUTIMENS + "HAVE_FUTIMENS", +#endif + +#ifdef HAVE_FUTIMES + "HAVE_FUTIMES", +#endif + +#ifdef HAVE_FUTIMESAT + "HAVE_FUTIMESAT", +#endif + +#ifdef HAVE_LINKAT + "HAVE_LINKAT", +#endif + +#ifdef HAVE_LCHFLAGS + "HAVE_LCHFLAGS", +#endif + +#ifdef HAVE_LCHMOD + "HAVE_LCHMOD", +#endif + +#ifdef HAVE_LCHOWN + "HAVE_LCHOWN", +#endif + +#ifdef HAVE_LSTAT + "HAVE_LSTAT", +#endif + +#ifdef HAVE_LUTIMES + "HAVE_LUTIMES", +#endif + +#ifdef HAVE_MEMFD_CREATE + "HAVE_MEMFD_CREATE", +#endif + +#ifdef HAVE_MKDIRAT + "HAVE_MKDIRAT", +#endif + +#ifdef HAVE_MKFIFOAT + "HAVE_MKFIFOAT", +#endif + +#ifdef HAVE_MKNODAT + "HAVE_MKNODAT", +#endif + +#ifdef HAVE_OPENAT + "HAVE_OPENAT", +#endif + +#ifdef HAVE_READLINKAT + "HAVE_READLINKAT", +#endif + +#ifdef HAVE_RENAMEAT + "HAVE_RENAMEAT", +#endif + +#ifdef HAVE_SYMLINKAT + "HAVE_SYMLINKAT", +#endif + +#ifdef HAVE_UNLINKAT + "HAVE_UNLINKAT", +#endif + +#ifdef HAVE_UTIMENSAT + "HAVE_UTIMENSAT", +#endif + +#ifdef MS_WINDOWS + "MS_WINDOWS", +#endif + + NULL +}; + + +PyMODINIT_FUNC +INITFUNC(void) +{ + PyObject *m, *v; + PyObject *list; + const char * const *trace; + + m = PyModule_Create(&posixmodule); + if (m == NULL) + return NULL; + + /* Initialize environ dictionary */ + v = convertenviron(); + Py_XINCREF(v); + if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) + return NULL; + Py_DECREF(v); + + if (all_ins(m)) + return NULL; + + if (setup_confname_tables(m)) + return NULL; + + Py_INCREF(PyExc_OSError); + PyModule_AddObject(m, "error", PyExc_OSError); + +#ifdef HAVE_PUTENV + if (posix_putenv_garbage == NULL) + posix_putenv_garbage = PyDict_New(); +#endif + + if (!initialized) { +#if defined(HAVE_WAITID) && !defined(__APPLE__) + waitid_result_desc.name = MODNAME ".waitid_result"; + WaitidResultType = PyStructSequence_NewType(&waitid_result_desc); + if (WaitidResultType == NULL) { + return NULL; + } +#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; + stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; + StatResultType = PyStructSequence_NewType(&stat_result_desc); + if (StatResultType == NULL) { + return NULL; + } + structseq_new = StatResultType->tp_new; + StatResultType->tp_new = statresult_new; + + statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ + StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc); + if (StatVFSResultType == NULL) { + return NULL; + } +#ifdef NEED_TICKS_PER_SECOND +# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) + ticks_per_second = sysconf(_SC_CLK_TCK); +# elif defined(HZ) + ticks_per_second = HZ; +# else + ticks_per_second = 60; /* magic fallback value; may be bogus */ +# 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"; + SchedParamType = PyStructSequence_NewType(&sched_param_desc); + if (SchedParamType == NULL) { + return NULL; + } + SchedParamType->tp_new = os_sched_param; +#endif + + /* initialize TerminalSize_info */ + TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc); + if (TerminalSizeType == NULL) { + return NULL; + } + + /* initialize scandir types */ + if (PyType_Ready(&ScandirIteratorType) < 0) + return NULL; + if (PyType_Ready(&DirEntryType) < 0) + return NULL; + } +#if defined(HAVE_WAITID) && !defined(__APPLE__) + Py_INCREF((PyObject*) WaitidResultType); + PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType); +#endif + Py_INCREF((PyObject*) StatResultType); + PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType); + Py_INCREF((PyObject*) StatVFSResultType); + PyModule_AddObject(m, "statvfs_result", + (PyObject*) StatVFSResultType); + +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) + Py_INCREF(SchedParamType); + PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType); +#endif + + times_result_desc.name = MODNAME ".times_result"; + TimesResultType = PyStructSequence_NewType(×_result_desc); + if (TimesResultType == NULL) { + return NULL; + } + PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType); + + uname_result_desc.name = MODNAME ".uname_result"; + UnameResultType = PyStructSequence_NewType(&uname_result_desc); + if (UnameResultType == NULL) { + return NULL; + } + PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType); + +#ifdef __APPLE__ + /* + * Step 2 of weak-linking support on Mac OS X. + * + * The code below removes functions that are not available on the + * currently active platform. + * + * This block allow one to use a python binary that was build on + * OSX 10.4 on OSX 10.3, without losing access to new APIs on + * OSX 10.4. + */ +#ifdef HAVE_FSTATVFS + if (fstatvfs == NULL) { + if (PyObject_DelAttrString(m, "fstatvfs") == -1) { + return NULL; + } + } +#endif /* HAVE_FSTATVFS */ + +#ifdef HAVE_STATVFS + if (statvfs == NULL) { + if (PyObject_DelAttrString(m, "statvfs") == -1) { + return NULL; + } + } +#endif /* HAVE_STATVFS */ + +# ifdef HAVE_LCHOWN + if (lchown == NULL) { + if (PyObject_DelAttrString(m, "lchown") == -1) { + return NULL; + } + } +#endif /* HAVE_LCHOWN */ + + +#endif /* __APPLE__ */ + + Py_INCREF(TerminalSizeType); + PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType); + + billion = PyLong_FromLong(1000000000); + if (!billion) + return NULL; + + /* 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 + */ + list = PyList_New(0); + if (!list) + return NULL; + for (trace = have_functions; *trace; trace++) { + PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL); + if (!unicode) + return NULL; + if (PyList_Append(list, unicode)) + return NULL; + Py_DECREF(unicode); + } + PyModule_AddObject(m, "_have_functions", list); + + Py_INCREF((PyObject *) &DirEntryType); + PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType); + + initialized = 1; + + return m; +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Modules/posixmodule.h b/python/Modules/posixmodule.h new file mode 100755 index 0000000..1e00562 --- /dev/null +++ b/python/Modules/posixmodule.h @@ -0,0 +1,34 @@ +/* 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 *, void *); +PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, void *); +#endif /* MS_WINDOWS */ + +#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ + defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) +# define HAVE_SIGSET_T +#endif + +#ifdef HAVE_SIGSET_T +PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); +#endif /* HAVE_SIGSET_T */ +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_POSIXMODULE_H */ diff --git a/python/Modules/pwdmodule.c b/python/Modules/pwdmodule.c new file mode 100755 index 0000000..e0232b8 --- /dev/null +++ b/python/Modules/pwdmodule.c @@ -0,0 +1,343 @@ + +/* 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."); + + +static int initialized; +static PyTypeObject StructPwdType; + +#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; + PyObject *v = PyStructSequence_New(&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]*/ +{ + PyObject *retval = NULL; + uid_t uid; + int nomem = 0; + 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; + } +#ifdef HAVE_GETPWUID_R + int status; + Py_ssize_t bufsize; + /* Note: 'pwd' will be used via pointer 'p' on getpwuid_r success. */ + struct passwd pwd; + + Py_BEGIN_ALLOW_THREADS + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) { + bufsize = DEFAULT_BUFFER_SIZE; + } + + while(1) { + buf2 = PyMem_RawRealloc(buf, bufsize); + if (buf2 == NULL) { + p = NULL; + nomem = 1; + break; + } + buf = buf2; + status = getpwuid_r(uid, &pwd, buf, bufsize, &p); + if (status != 0) { + p = NULL; + } + if (p != NULL || status != ERANGE) { + break; + } + if (bufsize > (PY_SSIZE_T_MAX >> 1)) { + nomem = 1; + break; + } + bufsize <<= 1; + } + + Py_END_ALLOW_THREADS +#else + p = getpwuid(uid); +#endif + if (p == NULL) { + PyMem_RawFree(buf); + 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; + } + retval = mkpwent(p); +#ifdef HAVE_GETPWUID_R + PyMem_RawFree(buf); +#endif + return retval; +} + +/*[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 * +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; + + 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_GETPWNAM_R + int status; + Py_ssize_t bufsize; + /* Note: 'pwd' will be used via pointer 'p' on getpwnam_r success. */ + struct passwd pwd; + + Py_BEGIN_ALLOW_THREADS + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) { + bufsize = DEFAULT_BUFFER_SIZE; + } + + while(1) { + buf2 = PyMem_RawRealloc(buf, bufsize); + if (buf2 == NULL) { + p = NULL; + nomem = 1; + break; + } + buf = buf2; + status = getpwnam_r(name_chars, &pwd, buf, bufsize, &p); + if (status != 0) { + p = NULL; + } + if (p != NULL || status != ERANGE) { + break; + } + if (bufsize > (PY_SSIZE_T_MAX >> 1)) { + nomem = 1; + break; + } + bufsize <<= 1; + } + + Py_END_ALLOW_THREADS +#else + p = getpwnam(name_chars); +#endif + if (p == NULL) { + if (nomem == 1) { + PyErr_NoMemory(); + } + else { + PyErr_Format(PyExc_KeyError, + "getpwnam(): name not found: %R", name); + } + 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 */ +}; + +static struct PyModuleDef pwdmodule = { + PyModuleDef_HEAD_INIT, + "pwd", + pwd__doc__, + -1, + pwd_methods, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit_pwd(void) +{ + PyObject *m; + m = PyModule_Create(&pwdmodule); + if (m == NULL) + return NULL; + + if (!initialized) { + if (PyStructSequence_InitType2(&StructPwdType, + &struct_pwd_type_desc) < 0) + return NULL; + initialized = 1; + } + Py_INCREF((PyObject *) &StructPwdType); + PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType); + return m; +} diff --git a/python/Modules/pyexpat.c b/python/Modules/pyexpat.c new file mode 100755 index 0000000..934b58d --- /dev/null +++ b/python/Modules/pyexpat.c @@ -0,0 +1,1936 @@ +// #include "Python.h" +// #include + +// #include "structmember.h" +// #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; +// err = PyObject_CallFunctionObjArgs(ErrorObject, buffer, NULL); +// 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 = PyEval_CallObject(func, args); +// 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 (!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; +// } +// 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); + +// 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); +// PyObject_GC_Track(new_parser); + +// 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); +// } +// } +// 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; +// 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); +// PyObject_GC_Track(self); + +// /* 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); + +// 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; +// } + +// 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 +// * "right" thing to do, though, but this probably won't +// * happen. +// */ +// 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 +// data handler is already active, we need to be more +// careful. What we can safely do is replace the existing +// character data handler callback function with a no-op +// function that will refuse to call Python. The downside +// is that this doesn't completely remove the character +// data handler from the C layer if there's any callback +// active, so Expat does a little more work than it +// otherwise would, but that's really an odd case. A more +// elaborate system of handlers and state could remove the +// C handler more effectively. */ +// 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) \ +// { \ +// return PyLong_FromLong((long) XML_Get##name(self->itself)); \ +// } +// INT_GETTER(ErrorCode) +// INT_GETTER(ErrorLineNumber) +// INT_GETTER(ErrorColumnNumber) +// INT_GETTER(ErrorByteIndex) +// INT_GETTER(CurrentLineNumber) +// INT_GETTER(CurrentColumnNumber) +// INT_GETTER(CurrentByteIndex) + +// #undef INT_GETTER + +// static PyObject * +// xmlparse_buffer_text_getter(xmlparseobject *self, void *closure) +// { +// return PyBool_FromLong(self->buffer != NULL); +// } + +// static int +// xmlparse_buffer_text_setter(xmlparseobject *self, PyObject *v, void *closure) +// { +// 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) { +// PyErr_NoMemory(); +// return -1; +// } +// self->buffer_used = 0; +// } +// } +// else if (self->buffer != NULL) { +// if (flush_character_buffer(self) < 0) +// return -1; +// PyMem_Free(self->buffer); +// self->buffer = NULL; +// } +// return 0; +// } + +// static PyObject * +// xmlparse_buffer_size_getter(xmlparseobject *self, void *closure) +// { +// return PyLong_FromLong((long) self->buffer_size); +// } + +// static int +// 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; +// } + +// new_buffer_size = PyLong_AsLong(v); +// if (new_buffer_size <= 0) { +// if (!PyErr_Occurred()) +// PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero"); +// return -1; +// } + +// /* trivial case -- no change */ +// if (new_buffer_size == self->buffer_size) { +// 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; +// } + +// 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); +// } +// self->buffer = PyMem_Malloc(new_buffer_size); +// if (self->buffer == NULL) { +// PyErr_NoMemory(); +// return -1; +// } +// self->buffer_size = new_buffer_size; +// return 0; +// } + +// static PyObject * +// xmlparse_buffer_used_getter(xmlparseobject *self, void *closure) +// { +// return PyLong_FromLong((long) self->buffer_used); +// } + +// static PyObject * +// xmlparse_namespace_prefixes_getter(xmlparseobject *self, void *closure) +// { +// return PyBool_FromLong(self->ns_prefixes); +// } + +// static int +// xmlparse_namespace_prefixes_setter(xmlparseobject *self, PyObject *v, void *closure) +// { +// if (v == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); +// return -1; +// } +// int b = PyObject_IsTrue(v); +// if (b < 0) +// return -1; +// self->ns_prefixes = b; +// XML_SetReturnNSTriplet(self->itself, self->ns_prefixes); +// return 0; +// } + +// static PyObject * +// xmlparse_ordered_attributes_getter(xmlparseobject *self, void *closure) +// { +// return PyBool_FromLong(self->ordered_attributes); +// } + +// static int +// xmlparse_ordered_attributes_setter(xmlparseobject *self, PyObject *v, void *closure) +// { +// 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 +// xmlparse_specified_attributes_setter(xmlparseobject *self, PyObject *v, void *closure) +// { +// if (v == NULL) { +// PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); +// return -1; +// } +// int b = PyObject_IsTrue(v); +// if (b < 0) +// return -1; +// self->specified_attributes = b; +// return 0; +// } + +// static PyMemberDef xmlparse_members[] = { +// {"intern", T_OBJECT, offsetof(xmlparseobject, intern), READONLY, NULL}, +// {NULL} +// }; + +// #define XMLPARSE_GETTER_DEF(name) \ +// {#name, (getter)xmlparse_##name##_getter, NULL, NULL}, +// #define XMLPARSE_GETTER_SETTER_DEF(name) \ +// {#name, (getter)xmlparse_##name##_getter, \ +// (setter)xmlparse_##name##_setter, NULL}, + +// static PyGetSetDef xmlparse_getsetlist[] = { +// XMLPARSE_GETTER_DEF(ErrorCode) +// XMLPARSE_GETTER_DEF(ErrorLineNumber) +// XMLPARSE_GETTER_DEF(ErrorColumnNumber) +// XMLPARSE_GETTER_DEF(ErrorByteIndex) +// XMLPARSE_GETTER_DEF(CurrentLineNumber) +// XMLPARSE_GETTER_DEF(CurrentColumnNumber) +// XMLPARSE_GETTER_DEF(CurrentByteIndex) +// XMLPARSE_GETTER_SETTER_DEF(buffer_size) +// XMLPARSE_GETTER_SETTER_DEF(buffer_text) +// XMLPARSE_GETTER_DEF(buffer_used) +// XMLPARSE_GETTER_SETTER_DEF(namespace_prefixes) +// XMLPARSE_GETTER_SETTER_DEF(ordered_attributes) +// XMLPARSE_GETTER_SETTER_DEF(specified_attributes) +// {NULL}, +// }; + +// #undef XMLPARSE_GETTER_DEF +// #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*/ +// 0, /*tp_vectorcall_offset*/ +// 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*/ +// (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 */ +// xmlparse_members, /* tp_members */ +// xmlparse_getsetlist, /* tp_getset */ +// }; + +// /* 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) +// /*[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 +// }; + +// static int init_handler_descrs(void) +// { +// int i; +// assert(!PyType_HasFeature(&Xmlparsetype, Py_TPFLAGS_VALID_VERSION_TAG)); +// for (i = 0; handler_info[i].name != NULL; i++) { +// struct HandlerInfo *hi = &handler_info[i]; +// hi->getset.name = hi->name; +// hi->getset.get = (getter)xmlparse_handler_getter; +// hi->getset.set = (setter)xmlparse_handler_setter; +// hi->getset.closure = &handler_info[i]; + +// PyObject *descr = PyDescr_NewGetSet(&Xmlparsetype, &hi->getset); +// if (descr == NULL) +// return -1; + +// if (PyDict_GetItemWithError(Xmlparsetype.tp_dict, PyDescr_NAME(descr))) { +// Py_DECREF(descr); +// continue; +// } +// else if (PyErr_Occurred()) { +// Py_DECREF(descr); +// return -1; +// } +// if (PyDict_SetItem(Xmlparsetype.tp_dict, PyDescr_NAME(descr), descr) < 0) { +// Py_DECREF(descr); +// return -1; +// } +// Py_DECREF(descr); +// } +// 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; + +// 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; +// } +// 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); +// 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[] = { + +// #define HANDLER_INFO(name) \ +// {#name, (xmlhandlersetter)XML_Set##name, (xmlhandler)my_##name}, + +// HANDLER_INFO(StartElementHandler) +// HANDLER_INFO(EndElementHandler) +// HANDLER_INFO(ProcessingInstructionHandler) +// HANDLER_INFO(CharacterDataHandler) +// HANDLER_INFO(UnparsedEntityDeclHandler) +// HANDLER_INFO(NotationDeclHandler) +// HANDLER_INFO(StartNamespaceDeclHandler) +// HANDLER_INFO(EndNamespaceDeclHandler) +// HANDLER_INFO(CommentHandler) +// HANDLER_INFO(StartCdataSectionHandler) +// HANDLER_INFO(EndCdataSectionHandler) +// HANDLER_INFO(DefaultHandler) +// HANDLER_INFO(DefaultHandlerExpand) +// HANDLER_INFO(NotStandaloneHandler) +// HANDLER_INFO(ExternalEntityRefHandler) +// HANDLER_INFO(StartDoctypeDeclHandler) +// HANDLER_INFO(EndDoctypeDeclHandler) +// HANDLER_INFO(EntityDeclHandler) +// HANDLER_INFO(XmlDeclHandler) +// HANDLER_INFO(ElementDeclHandler) +// HANDLER_INFO(AttlistDeclHandler) +// #if XML_COMBINED_VERSION >= 19504 +// HANDLER_INFO(SkippedEntityHandler) +// #endif + +// #undef HANDLER_INFO + +// {NULL, NULL, NULL} /* sentinel */ +// }; diff --git a/python/Modules/readline.c b/python/Modules/readline.c new file mode 100755 index 0000000..92c1de4 --- /dev/null +++ b/python/Modules/readline.c @@ -0,0 +1,1387 @@ +// /* This module makes GNU readline available to Python. It has ideas +// * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory +// * Center. The completer interface was inspired by Lele Gaifax. More +// * recently, it was largely rewritten by Guido van Rossum. +// */ + +// /* Standard definitions */ +// #include "Python.h" +// #include +// #include +// #include +// #include + +// #if defined(HAVE_SETLOCALE) +// /* GNU readline() mistakenly sets the LC_CTYPE locale. +// * This is evil. Only the user or the app's main() should do this! +// * We must save and restore the locale around the rl_initialize() call. +// */ +// #define SAVE_LOCALE +// #include +// #endif + +// #ifdef SAVE_LOCALE +// # define RESTORE_LOCALE(sl) { setlocale(LC_CTYPE, sl); free(sl); } +// #else +// # define RESTORE_LOCALE(sl) +// #endif + +// /* GNU readline definitions */ +// #undef HAVE_CONFIG_H /* Else readline/chardefs.h includes strings.h */ +// #include +// #include + +// #ifdef HAVE_RL_COMPLETION_MATCHES +// #define completion_matches(x, y) \ +// rl_completion_matches((x), ((rl_compentry_func_t *)(y))) +// #else +// #if defined(_RL_FUNCTION_TYPEDEF) +// extern char **completion_matches(char *, rl_compentry_func_t *); +// #else + +// #if !defined(__APPLE__) +// extern char **completion_matches(char *, CPFunction *); +// #endif +// #endif +// #endif + +// /* +// * It is possible to link the readline module to the readline +// * emulation library of editline/libedit. +// * +// * This emulation library is not 100% API compatible with the "real" readline +// * and cannot be detected at compile-time, +// * hence we use a runtime check to detect if the Python readlinke module is +// * linked to libedit. +// * +// * Currently there is one known API incompatibility: +// * - 'get_history' has a 1-based index with GNU readline, and a 0-based +// * index with older versions of libedit's emulation. +// * - Note that replace_history and remove_history use a 0-based index +// * with both implementations. +// */ +// static int using_libedit_emulation = 0; +// static const char libedit_version_tag[] = "EditLine wrapper"; + +// static int libedit_history_start = 0; + +// #ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK +// static void +// on_completion_display_matches_hook(char **matches, +// int num_matches, int max_length); +// #endif + +// /* Memory allocated for rl_completer_word_break_characters +// (see issue #17289 for the motivation). */ +// static char *completer_word_break_characters; + +// typedef struct { +// /* Specify hook functions in Python */ +// PyObject *completion_display_matches_hook; +// PyObject *startup_hook; +// PyObject *pre_input_hook; + +// PyObject *completer; /* Specify a word completer in Python */ +// PyObject *begidx; +// PyObject *endidx; +// } readlinestate; + + +// #define readline_state(o) ((readlinestate *)PyModule_GetState(o)) + +// static int +// readline_clear(PyObject *m) +// { +// readlinestate *state = readline_state(m); +// Py_CLEAR(state->completion_display_matches_hook); +// Py_CLEAR(state->startup_hook); +// Py_CLEAR(state->pre_input_hook); +// Py_CLEAR(state->completer); +// Py_CLEAR(state->begidx); +// Py_CLEAR(state->endidx); +// return 0; +// } + +// static int +// readline_traverse(PyObject *m, visitproc visit, void *arg) +// { +// readlinestate *state = readline_state(m); +// Py_VISIT(state->completion_display_matches_hook); +// Py_VISIT(state->startup_hook); +// Py_VISIT(state->pre_input_hook); +// Py_VISIT(state->completer); +// Py_VISIT(state->begidx); +// Py_VISIT(state->endidx); +// return 0; +// } + +// static void +// readline_free(void *m) +// { +// readline_clear((PyObject *)m); +// } + +// static PyModuleDef readlinemodule; + +// #define readlinestate_global ((readlinestate *)PyModule_GetState(PyState_FindModule(&readlinemodule))) + + +// /* Convert to/from multibyte C strings */ + +// static PyObject * +// encode(PyObject *b) +// { +// return PyUnicode_EncodeLocale(b, "surrogateescape"); +// } + +// static PyObject * +// decode(const char *s) +// { +// return PyUnicode_DecodeLocale(s, "surrogateescape"); +// } + + +// /* +// Explicitly disable bracketed paste in the interactive interpreter, even if it's +// set in the inputrc, is enabled by default (eg GNU Readline 8.1), or a user calls +// readline.read_init_file(). The Python REPL has not implemented bracketed +// paste support. Also, bracketed mode writes the "\x1b[?2004h" escape sequence +// into stdout which causes test failures in applications that don't support it. +// It can still be explicitly enabled by calling readline.parse_and_bind("set +// enable-bracketed-paste on"). See bpo-42819 for more details. + +// This should be removed if bracketed paste mode is implemented (bpo-39820). +// */ + +// static void +// disable_bracketed_paste(void) +// { +// if (!using_libedit_emulation) { +// rl_variable_bind ("enable-bracketed-paste", "off"); +// } +// } + +// /* Exported function to send one line to readline's init file parser */ + +// static PyObject * +// parse_and_bind(PyObject *self, PyObject *string) +// { +// char *copy; +// PyObject *encoded = encode(string); +// if (encoded == NULL) { +// return NULL; +// } +// /* Make a copy -- rl_parse_and_bind() modifies its argument */ +// /* Bernard Herzog */ +// copy = PyMem_Malloc(1 + PyBytes_GET_SIZE(encoded)); +// if (copy == NULL) { +// Py_DECREF(encoded); +// return PyErr_NoMemory(); +// } +// strcpy(copy, PyBytes_AS_STRING(encoded)); +// Py_DECREF(encoded); +// rl_parse_and_bind(copy); +// PyMem_Free(copy); /* Free the copy */ +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_parse_and_bind, +// "parse_and_bind(string) -> None\n\ +// Execute the init line provided in the string argument."); + + +// /* Exported function to parse a readline init file */ + +// static PyObject * +// read_init_file(PyObject *self, PyObject *args) +// { +// PyObject *filename_obj = Py_None, *filename_bytes; +// if (!PyArg_ParseTuple(args, "|O:read_init_file", &filename_obj)) +// return NULL; +// if (filename_obj != Py_None) { +// if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) +// return NULL; +// errno = rl_read_init_file(PyBytes_AsString(filename_bytes)); +// Py_DECREF(filename_bytes); +// } else +// errno = rl_read_init_file(NULL); +// if (errno) +// return PyErr_SetFromErrno(PyExc_OSError); +// disable_bracketed_paste(); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_read_init_file, +// "read_init_file([filename]) -> None\n\ +// Execute a readline initialization file.\n\ +// The default filename is the last filename used."); + + +// /* Exported function to load a readline history file */ + +// static PyObject * +// read_history_file(PyObject *self, PyObject *args) +// { +// PyObject *filename_obj = Py_None, *filename_bytes; +// if (!PyArg_ParseTuple(args, "|O:read_history_file", &filename_obj)) +// return NULL; +// if (filename_obj != Py_None) { +// if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) +// return NULL; +// errno = read_history(PyBytes_AsString(filename_bytes)); +// Py_DECREF(filename_bytes); +// } else +// errno = read_history(NULL); +// if (errno) +// return PyErr_SetFromErrno(PyExc_OSError); +// Py_RETURN_NONE; +// } + +// static int _history_length = -1; /* do not truncate history by default */ +// PyDoc_STRVAR(doc_read_history_file, +// "read_history_file([filename]) -> None\n\ +// Load a readline history file.\n\ +// The default filename is ~/.history."); + + +// /* Exported function to save a readline history file */ + +// static PyObject * +// write_history_file(PyObject *self, PyObject *args) +// { +// PyObject *filename_obj = Py_None, *filename_bytes; +// char *filename; +// int err; +// if (!PyArg_ParseTuple(args, "|O:write_history_file", &filename_obj)) +// return NULL; +// if (filename_obj != Py_None) { +// if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) +// return NULL; +// filename = PyBytes_AsString(filename_bytes); +// } else { +// filename_bytes = NULL; +// filename = NULL; +// } +// errno = err = write_history(filename); +// if (!err && _history_length >= 0) +// history_truncate_file(filename, _history_length); +// Py_XDECREF(filename_bytes); +// errno = err; +// if (errno) +// return PyErr_SetFromErrno(PyExc_OSError); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_write_history_file, +// "write_history_file([filename]) -> None\n\ +// Save a readline history file.\n\ +// The default filename is ~/.history."); + + +// #ifdef HAVE_RL_APPEND_HISTORY +// /* Exported function to save part of a readline history file */ + +// static PyObject * +// append_history_file(PyObject *self, PyObject *args) +// { +// int nelements; +// PyObject *filename_obj = Py_None, *filename_bytes; +// char *filename; +// int err; +// if (!PyArg_ParseTuple(args, "i|O:append_history_file", &nelements, &filename_obj)) +// return NULL; +// if (filename_obj != Py_None) { +// if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) +// return NULL; +// filename = PyBytes_AsString(filename_bytes); +// } else { +// filename_bytes = NULL; +// filename = NULL; +// } +// errno = err = append_history(nelements, filename); +// if (!err && _history_length >= 0) +// history_truncate_file(filename, _history_length); +// Py_XDECREF(filename_bytes); +// errno = err; +// if (errno) +// return PyErr_SetFromErrno(PyExc_OSError); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_append_history_file, +// "append_history_file(nelements[, filename]) -> None\n\ +// Append the last nelements items of the history list to file.\n\ +// The default filename is ~/.history."); +// #endif + + +// /* Set history length */ + +// static PyObject* +// set_history_length(PyObject *self, PyObject *args) +// { +// int length = _history_length; +// if (!PyArg_ParseTuple(args, "i:set_history_length", &length)) +// return NULL; +// _history_length = length; +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(set_history_length_doc, +// "set_history_length(length) -> None\n\ +// set the maximal number of lines which will be written to\n\ +// the history file. A negative length is used to inhibit\n\ +// history truncation."); + + +// /* Get history length */ + +// static PyObject* +// get_history_length(PyObject *self, PyObject *noarg) +// { +// return PyLong_FromLong(_history_length); +// } + +// PyDoc_STRVAR(get_history_length_doc, +// "get_history_length() -> int\n\ +// return the maximum number of lines that will be written to\n\ +// the history file."); + + +// /* Generic hook function setter */ + +// static PyObject * +// set_hook(const char *funcname, PyObject **hook_var, PyObject *args) +// { +// PyObject *function = Py_None; +// char buf[80]; +// PyOS_snprintf(buf, sizeof(buf), "|O:set_%.50s", funcname); +// if (!PyArg_ParseTuple(args, buf, &function)) +// return NULL; +// if (function == Py_None) { +// Py_CLEAR(*hook_var); +// } +// else if (PyCallable_Check(function)) { +// Py_INCREF(function); +// Py_XSETREF(*hook_var, function); +// } +// else { +// PyErr_Format(PyExc_TypeError, +// "set_%.50s(func): argument not callable", +// funcname); +// return NULL; +// } +// Py_RETURN_NONE; +// } + + +// static PyObject * +// set_completion_display_matches_hook(PyObject *self, PyObject *args) +// { +// PyObject *result = set_hook("completion_display_matches_hook", +// &readlinestate_global->completion_display_matches_hook, args); +// #ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK +// /* We cannot set this hook globally, since it replaces the +// default completion display. */ +// rl_completion_display_matches_hook = +// readlinestate_global->completion_display_matches_hook ? +// #if defined(_RL_FUNCTION_TYPEDEF) +// (rl_compdisp_func_t *)on_completion_display_matches_hook : 0; +// #else +// (VFunction *)on_completion_display_matches_hook : 0; +// #endif +// #endif +// return result; + +// } + +// PyDoc_STRVAR(doc_set_completion_display_matches_hook, +// "set_completion_display_matches_hook([function]) -> None\n\ +// Set or remove the completion display function.\n\ +// The function is called as\n\ +// function(substitution, [matches], longest_match_length)\n\ +// once each time matches need to be displayed."); + +// static PyObject * +// set_startup_hook(PyObject *self, PyObject *args) +// { +// return set_hook("startup_hook", &readlinestate_global->startup_hook, args); +// } + +// PyDoc_STRVAR(doc_set_startup_hook, +// "set_startup_hook([function]) -> None\n\ +// Set or remove the function invoked by the rl_startup_hook callback.\n\ +// The function is called with no arguments just\n\ +// before readline prints the first prompt."); + + +// #ifdef HAVE_RL_PRE_INPUT_HOOK + +// /* Set pre-input hook */ + +// static PyObject * +// set_pre_input_hook(PyObject *self, PyObject *args) +// { +// return set_hook("pre_input_hook", &readlinestate_global->pre_input_hook, args); +// } + +// PyDoc_STRVAR(doc_set_pre_input_hook, +// "set_pre_input_hook([function]) -> None\n\ +// Set or remove the function invoked by the rl_pre_input_hook callback.\n\ +// The function is called with no arguments after the first prompt\n\ +// has been printed and just before readline starts reading input\n\ +// characters."); + +// #endif + + +// /* Get the completion type for the scope of the tab-completion */ +// static PyObject * +// get_completion_type(PyObject *self, PyObject *noarg) +// { +// return PyLong_FromLong(rl_completion_type); +// } + +// PyDoc_STRVAR(doc_get_completion_type, +// "get_completion_type() -> int\n\ +// Get the type of completion being attempted."); + + +// /* Get the beginning index for the scope of the tab-completion */ + +// static PyObject * +// get_begidx(PyObject *self, PyObject *noarg) +// { +// Py_INCREF(readlinestate_global->begidx); +// return readlinestate_global->begidx; +// } + +// PyDoc_STRVAR(doc_get_begidx, +// "get_begidx() -> int\n\ +// get the beginning index of the completion scope"); + + +// /* Get the ending index for the scope of the tab-completion */ + +// static PyObject * +// get_endidx(PyObject *self, PyObject *noarg) +// { +// Py_INCREF(readlinestate_global->endidx); +// return readlinestate_global->endidx; +// } + +// PyDoc_STRVAR(doc_get_endidx, +// "get_endidx() -> int\n\ +// get the ending index of the completion scope"); + + +// /* Set the tab-completion word-delimiters that readline uses */ + +// static PyObject * +// set_completer_delims(PyObject *self, PyObject *string) +// { +// char *break_chars; +// PyObject *encoded = encode(string); +// if (encoded == NULL) { +// return NULL; +// } +// /* Keep a reference to the allocated memory in the module state in case +// some other module modifies rl_completer_word_break_characters +// (see issue #17289). */ +// break_chars = strdup(PyBytes_AS_STRING(encoded)); +// Py_DECREF(encoded); +// if (break_chars) { +// free(completer_word_break_characters); +// completer_word_break_characters = break_chars; +// rl_completer_word_break_characters = break_chars; +// Py_RETURN_NONE; +// } +// else +// return PyErr_NoMemory(); +// } + +// PyDoc_STRVAR(doc_set_completer_delims, +// "set_completer_delims(string) -> None\n\ +// set the word delimiters for completion"); + +// /* _py_free_history_entry: Utility function to free a history entry. */ + +// #if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0500 + +// /* Readline version >= 5.0 introduced a timestamp field into the history entry +// structure; this needs to be freed to avoid a memory leak. This version of +// readline also introduced the handy 'free_history_entry' function, which +// takes care of the timestamp. */ + +// static void +// _py_free_history_entry(HIST_ENTRY *entry) +// { +// histdata_t data = free_history_entry(entry); +// free(data); +// } + +// #else + +// /* No free_history_entry function; free everything manually. */ + +// static void +// _py_free_history_entry(HIST_ENTRY *entry) +// { +// if (entry->line) +// free((void *)entry->line); +// if (entry->data) +// free(entry->data); +// free(entry); +// } + +// #endif + +// static PyObject * +// py_remove_history(PyObject *self, PyObject *args) +// { +// int entry_number; +// HIST_ENTRY *entry; + +// if (!PyArg_ParseTuple(args, "i:remove_history_item", &entry_number)) +// return NULL; +// if (entry_number < 0) { +// PyErr_SetString(PyExc_ValueError, +// "History index cannot be negative"); +// return NULL; +// } +// entry = remove_history(entry_number); +// if (!entry) { +// PyErr_Format(PyExc_ValueError, +// "No history item at position %d", +// entry_number); +// return NULL; +// } +// /* free memory allocated for the history entry */ +// _py_free_history_entry(entry); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_remove_history, +// "remove_history_item(pos) -> None\n\ +// remove history item given by its position"); + +// static PyObject * +// py_replace_history(PyObject *self, PyObject *args) +// { +// int entry_number; +// PyObject *line; +// PyObject *encoded; +// HIST_ENTRY *old_entry; + +// if (!PyArg_ParseTuple(args, "iU:replace_history_item", &entry_number, +// &line)) { +// return NULL; +// } +// if (entry_number < 0) { +// PyErr_SetString(PyExc_ValueError, +// "History index cannot be negative"); +// return NULL; +// } +// encoded = encode(line); +// if (encoded == NULL) { +// return NULL; +// } +// old_entry = replace_history_entry(entry_number, PyBytes_AS_STRING(encoded), (void *)NULL); +// Py_DECREF(encoded); +// if (!old_entry) { +// PyErr_Format(PyExc_ValueError, +// "No history item at position %d", +// entry_number); +// return NULL; +// } +// /* free memory allocated for the old history entry */ +// _py_free_history_entry(old_entry); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_replace_history, +// "replace_history_item(pos, line) -> None\n\ +// replaces history item given by its position with contents of line"); + +// /* Add a line to the history buffer */ + +// static PyObject * +// py_add_history(PyObject *self, PyObject *string) +// { +// PyObject *encoded = encode(string); +// if (encoded == NULL) { +// return NULL; +// } +// add_history(PyBytes_AS_STRING(encoded)); +// Py_DECREF(encoded); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_add_history, +// "add_history(string) -> None\n\ +// add an item to the history buffer"); + +// static int should_auto_add_history = 1; + +// /* Enable or disable automatic history */ + +// static PyObject * +// py_set_auto_history(PyObject *self, PyObject *args) +// { +// if (!PyArg_ParseTuple(args, "p:set_auto_history", +// &should_auto_add_history)) { +// return NULL; +// } +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_set_auto_history, +// "set_auto_history(enabled) -> None\n\ +// Enables or disables automatic history."); + + +// /* Get the tab-completion word-delimiters that readline uses */ + +// static PyObject * +// get_completer_delims(PyObject *self, PyObject *noarg) +// { +// return decode(rl_completer_word_break_characters); +// } + +// PyDoc_STRVAR(doc_get_completer_delims, +// "get_completer_delims() -> string\n\ +// get the word delimiters for completion"); + + +// /* Set the completer function */ + +// static PyObject * +// set_completer(PyObject *self, PyObject *args) +// { +// return set_hook("completer", &readlinestate_global->completer, args); +// } + +// PyDoc_STRVAR(doc_set_completer, +// "set_completer([function]) -> None\n\ +// Set or remove the completer function.\n\ +// The function is called as function(text, state),\n\ +// for state in 0, 1, 2, ..., until it returns a non-string.\n\ +// It should return the next possible completion starting with 'text'."); + + +// static PyObject * +// get_completer(PyObject *self, PyObject *noargs) +// { +// if (readlinestate_global->completer == NULL) { +// Py_RETURN_NONE; +// } +// Py_INCREF(readlinestate_global->completer); +// return readlinestate_global->completer; +// } + +// PyDoc_STRVAR(doc_get_completer, +// "get_completer() -> function\n\ +// \n\ +// Returns current completer function."); + +// /* Private function to get current length of history. XXX It may be +// * possible to replace this with a direct use of history_length instead, +// * but it's not clear whether BSD's libedit keeps history_length up to date. +// * See issue #8065.*/ + +// static int +// _py_get_history_length(void) +// { +// HISTORY_STATE *hist_st = history_get_history_state(); +// int length = hist_st->length; +// /* the history docs don't say so, but the address of hist_st changes each +// time history_get_history_state is called which makes me think it's +// freshly malloc'd memory... on the other hand, the address of the last +// line stays the same as long as history isn't extended, so it appears to +// be malloc'd but managed by the history package... */ +// free(hist_st); +// return length; +// } + +// /* Exported function to get any element of history */ + +// static PyObject * +// get_history_item(PyObject *self, PyObject *args) +// { +// int idx = 0; +// HIST_ENTRY *hist_ent; + +// if (!PyArg_ParseTuple(args, "i:get_history_item", &idx)) +// return NULL; +// if (using_libedit_emulation) { +// /* Older versions of libedit's readline emulation +// * use 0-based indexes, while readline and newer +// * versions of libedit use 1-based indexes. +// */ +// int length = _py_get_history_length(); + +// idx = idx - 1 + libedit_history_start; + +// /* +// * Apple's readline emulation crashes when +// * the index is out of range, therefore +// * test for that and fail gracefully. +// */ +// if (idx < (0 + libedit_history_start) +// || idx >= (length + libedit_history_start)) { +// Py_RETURN_NONE; +// } +// } +// if ((hist_ent = history_get(idx))) +// return decode(hist_ent->line); +// else { +// Py_RETURN_NONE; +// } +// } + +// PyDoc_STRVAR(doc_get_history_item, +// "get_history_item() -> string\n\ +// return the current contents of history item at index."); + + +// /* Exported function to get current length of history */ + +// static PyObject * +// get_current_history_length(PyObject *self, PyObject *noarg) +// { +// return PyLong_FromLong((long)_py_get_history_length()); +// } + +// PyDoc_STRVAR(doc_get_current_history_length, +// "get_current_history_length() -> integer\n\ +// return the current (not the maximum) length of history."); + + +// /* Exported function to read the current line buffer */ + +// static PyObject * +// get_line_buffer(PyObject *self, PyObject *noarg) +// { +// return decode(rl_line_buffer); +// } + +// PyDoc_STRVAR(doc_get_line_buffer, +// "get_line_buffer() -> string\n\ +// return the current contents of the line buffer."); + + +// #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + +// /* Exported function to clear the current history */ + +// static PyObject * +// py_clear_history(PyObject *self, PyObject *noarg) +// { +// clear_history(); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_clear_history, +// "clear_history() -> None\n\ +// Clear the current readline history."); +// #endif + + +// /* Exported function to insert text into the line buffer */ + +// static PyObject * +// insert_text(PyObject *self, PyObject *string) +// { +// PyObject *encoded = encode(string); +// if (encoded == NULL) { +// return NULL; +// } +// rl_insert_text(PyBytes_AS_STRING(encoded)); +// Py_DECREF(encoded); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_insert_text, +// "insert_text(string) -> None\n\ +// Insert text into the line buffer at the cursor position."); + + +// /* Redisplay the line buffer */ + +// static PyObject * +// redisplay(PyObject *self, PyObject *noarg) +// { +// rl_redisplay(); +// Py_RETURN_NONE; +// } + +// PyDoc_STRVAR(doc_redisplay, +// "redisplay() -> None\n\ +// Change what's displayed on the screen to reflect the current\n\ +// contents of the line buffer."); + + +// /* Table of functions exported by the module */ + +// static struct PyMethodDef readline_methods[] = +// { +// {"parse_and_bind", parse_and_bind, METH_O, doc_parse_and_bind}, +// {"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer}, +// {"insert_text", insert_text, METH_O, doc_insert_text}, +// {"redisplay", redisplay, METH_NOARGS, doc_redisplay}, +// {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file}, +// {"read_history_file", read_history_file, +// METH_VARARGS, doc_read_history_file}, +// {"write_history_file", write_history_file, +// METH_VARARGS, doc_write_history_file}, +// #ifdef HAVE_RL_APPEND_HISTORY +// {"append_history_file", append_history_file, +// METH_VARARGS, doc_append_history_file}, +// #endif +// {"get_history_item", get_history_item, +// METH_VARARGS, doc_get_history_item}, +// {"get_current_history_length", (PyCFunction)get_current_history_length, +// METH_NOARGS, doc_get_current_history_length}, +// {"set_history_length", set_history_length, +// METH_VARARGS, set_history_length_doc}, +// {"get_history_length", get_history_length, +// METH_NOARGS, get_history_length_doc}, +// {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, +// {"get_completer", get_completer, METH_NOARGS, doc_get_completer}, +// {"get_completion_type", get_completion_type, +// METH_NOARGS, doc_get_completion_type}, +// {"get_begidx", get_begidx, METH_NOARGS, doc_get_begidx}, +// {"get_endidx", get_endidx, METH_NOARGS, doc_get_endidx}, + +// {"set_completer_delims", set_completer_delims, +// METH_O, doc_set_completer_delims}, +// {"set_auto_history", py_set_auto_history, METH_VARARGS, doc_set_auto_history}, +// {"add_history", py_add_history, METH_O, doc_add_history}, +// {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history}, +// {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history}, +// {"get_completer_delims", get_completer_delims, +// METH_NOARGS, doc_get_completer_delims}, + +// {"set_completion_display_matches_hook", set_completion_display_matches_hook, +// METH_VARARGS, doc_set_completion_display_matches_hook}, +// {"set_startup_hook", set_startup_hook, +// METH_VARARGS, doc_set_startup_hook}, +// #ifdef HAVE_RL_PRE_INPUT_HOOK +// {"set_pre_input_hook", set_pre_input_hook, +// METH_VARARGS, doc_set_pre_input_hook}, +// #endif +// #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER +// {"clear_history", py_clear_history, METH_NOARGS, doc_clear_history}, +// #endif +// {0, 0} +// }; + + +// /* C function to call the Python hooks. */ + +// static int +// on_hook(PyObject *func) +// { +// int result = 0; +// if (func != NULL) { +// PyObject *r; +// r = _PyObject_CallNoArg(func); +// if (r == NULL) +// goto error; +// if (r == Py_None) +// result = 0; +// else { +// result = _PyLong_AsInt(r); +// if (result == -1 && PyErr_Occurred()) +// goto error; +// } +// Py_DECREF(r); +// goto done; +// error: +// PyErr_Clear(); +// Py_XDECREF(r); +// done: +// return result; +// } +// return result; +// } + +// static int +// #if defined(_RL_FUNCTION_TYPEDEF) +// on_startup_hook(void) +// #else +// on_startup_hook() +// #endif +// { +// int r; +// PyGILState_STATE gilstate = PyGILState_Ensure(); +// r = on_hook(readlinestate_global->startup_hook); +// PyGILState_Release(gilstate); +// return r; +// } + +// #ifdef HAVE_RL_PRE_INPUT_HOOK +// static int +// #if defined(_RL_FUNCTION_TYPEDEF) +// on_pre_input_hook(void) +// #else +// on_pre_input_hook() +// #endif +// { +// int r; +// PyGILState_STATE gilstate = PyGILState_Ensure(); +// r = on_hook(readlinestate_global->pre_input_hook); +// PyGILState_Release(gilstate); +// return r; +// } +// #endif + + +// /* C function to call the Python completion_display_matches */ + +// #ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK +// static void +// on_completion_display_matches_hook(char **matches, +// int num_matches, int max_length) +// { +// int i; +// PyObject *sub, *m=NULL, *s=NULL, *r=NULL; +// PyGILState_STATE gilstate = PyGILState_Ensure(); +// m = PyList_New(num_matches); +// if (m == NULL) +// goto error; +// for (i = 0; i < num_matches; i++) { +// s = decode(matches[i+1]); +// if (s == NULL) +// goto error; +// PyList_SET_ITEM(m, i, s); +// } +// sub = decode(matches[0]); +// r = PyObject_CallFunction(readlinestate_global->completion_display_matches_hook, +// "NNi", sub, m, max_length); + +// m=NULL; + +// if (r == NULL || +// (r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) { +// goto error; +// } +// Py_CLEAR(r); + +// if (0) { +// error: +// PyErr_Clear(); +// Py_XDECREF(m); +// Py_XDECREF(r); +// } +// PyGILState_Release(gilstate); +// } + +// #endif + +// #ifdef HAVE_RL_RESIZE_TERMINAL +// static volatile sig_atomic_t sigwinch_received; +// static PyOS_sighandler_t sigwinch_ohandler; + +// static void +// readline_sigwinch_handler(int signum) +// { +// sigwinch_received = 1; +// if (sigwinch_ohandler && +// sigwinch_ohandler != SIG_IGN && sigwinch_ohandler != SIG_DFL) +// sigwinch_ohandler(signum); + +// #ifndef HAVE_SIGACTION +// /* If the handler was installed with signal() rather than sigaction(), +// we need to reinstall it. */ +// PyOS_setsig(SIGWINCH, readline_sigwinch_handler); +// #endif +// } +// #endif + +// /* C function to call the Python completer. */ + +// static char * +// on_completion(const char *text, int state) +// { +// char *result = NULL; +// if (readlinestate_global->completer != NULL) { +// PyObject *r = NULL, *t; +// PyGILState_STATE gilstate = PyGILState_Ensure(); +// rl_attempted_completion_over = 1; +// t = decode(text); +// r = PyObject_CallFunction(readlinestate_global->completer, "Ni", t, state); +// if (r == NULL) +// goto error; +// if (r == Py_None) { +// result = NULL; +// } +// else { +// PyObject *encoded = encode(r); +// if (encoded == NULL) +// goto error; +// result = strdup(PyBytes_AS_STRING(encoded)); +// Py_DECREF(encoded); +// } +// Py_DECREF(r); +// goto done; +// error: +// PyErr_Clear(); +// Py_XDECREF(r); +// done: +// PyGILState_Release(gilstate); +// return result; +// } +// return result; +// } + + +// /* A more flexible constructor that saves the "begidx" and "endidx" +// * before calling the normal completer */ + +// static char ** +// flex_complete(const char *text, int start, int end) +// { +// char **result; +// char saved; +// size_t start_size, end_size; +// wchar_t *s; +// PyGILState_STATE gilstate = PyGILState_Ensure(); +// #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER +// rl_completion_append_character ='\0'; +// #endif +// #ifdef HAVE_RL_COMPLETION_SUPPRESS_APPEND +// rl_completion_suppress_append = 0; +// #endif + +// saved = rl_line_buffer[start]; +// rl_line_buffer[start] = 0; +// s = Py_DecodeLocale(rl_line_buffer, &start_size); +// rl_line_buffer[start] = saved; +// if (s == NULL) { +// goto done; +// } +// PyMem_RawFree(s); +// saved = rl_line_buffer[end]; +// rl_line_buffer[end] = 0; +// s = Py_DecodeLocale(rl_line_buffer + start, &end_size); +// rl_line_buffer[end] = saved; +// if (s == NULL) { +// goto done; +// } +// PyMem_RawFree(s); +// start = (int)start_size; +// end = start + (int)end_size; + +// done: +// Py_XDECREF(readlinestate_global->begidx); +// Py_XDECREF(readlinestate_global->endidx); +// readlinestate_global->begidx = PyLong_FromLong((long) start); +// readlinestate_global->endidx = PyLong_FromLong((long) end); +// result = completion_matches((char *)text, *on_completion); +// PyGILState_Release(gilstate); +// return result; +// } + + +// /* Helper to initialize GNU readline properly. */ + +// static void +// setup_readline(readlinestate *mod_state) +// { +// #ifdef SAVE_LOCALE +// char *saved_locale = strdup(setlocale(LC_CTYPE, NULL)); +// if (!saved_locale) +// Py_FatalError("not enough memory to save locale"); +// #endif + +// /* The name must be defined before initialization */ +// rl_readline_name = "python"; + +// /* the libedit readline emulation resets key bindings etc +// * when calling rl_initialize. So call it upfront +// */ +// if (using_libedit_emulation) +// rl_initialize(); + +// /* Detect if libedit's readline emulation uses 0-based +// * indexing or 1-based indexing. +// */ +// add_history("1"); +// if (history_get(1) == NULL) { +// libedit_history_start = 0; +// } else { +// libedit_history_start = 1; +// } +// clear_history(); + +// using_history(); + +// /* Force rebind of TAB to insert-tab */ +// rl_bind_key('\t', rl_insert); +// /* Bind both ESC-TAB and ESC-ESC to the completion function */ +// rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap); +// rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap); +// #ifdef HAVE_RL_RESIZE_TERMINAL +// /* Set up signal handler for window resize */ +// sigwinch_ohandler = PyOS_setsig(SIGWINCH, readline_sigwinch_handler); +// #endif +// /* Set our hook functions */ +// rl_startup_hook = on_startup_hook; +// #ifdef HAVE_RL_PRE_INPUT_HOOK +// rl_pre_input_hook = on_pre_input_hook; +// #endif +// /* Set our completion function */ +// rl_attempted_completion_function = flex_complete; +// /* Set Python word break characters */ +// completer_word_break_characters = +// rl_completer_word_break_characters = +// strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?"); +// /* All nonalphanums except '.' */ + +// mod_state->begidx = PyLong_FromLong(0L); +// mod_state->endidx = PyLong_FromLong(0L); + +// if (!using_libedit_emulation) +// { +// if (!isatty(STDOUT_FILENO)) { +// /* Issue #19884: stdout is not a terminal. Disable meta modifier +// keys to not write the ANSI sequence "\033[1034h" into stdout. On +// terminals supporting 8 bit characters like TERM=xterm-256color +// (which is now the default Fedora since Fedora 18), the meta key is +// used to enable support of 8 bit characters (ANSI sequence +// "\033[1034h"). + +// With libedit, this call makes readline() crash. */ +// rl_variable_bind ("enable-meta-key", "off"); +// } +// } + +// /* Initialize (allows .inputrc to override) +// * +// * XXX: A bug in the readline-2.2 library causes a memory leak +// * inside this function. Nothing we can do about it. +// */ +// if (using_libedit_emulation) +// rl_read_init_file(NULL); +// else +// rl_initialize(); + +// disable_bracketed_paste(); + +// RESTORE_LOCALE(saved_locale) +// } + +// /* Wrapper around GNU readline that handles signals differently. */ + +// static char *completed_input_string; +// static void +// rlhandler(char *text) +// { +// completed_input_string = text; +// rl_callback_handler_remove(); +// } + +// static char * +// readline_until_enter_or_signal(const char *prompt, int *signal) +// { +// char * not_done_reading = ""; +// fd_set selectset; + +// *signal = 0; +// #ifdef HAVE_RL_CATCH_SIGNAL +// rl_catch_signals = 0; +// #endif + +// rl_callback_handler_install (prompt, rlhandler); +// FD_ZERO(&selectset); + +// completed_input_string = not_done_reading; + +// while (completed_input_string == not_done_reading) { +// int has_input = 0, err = 0; + +// while (!has_input) +// { struct timeval timeout = {0, 100000}; /* 0.1 seconds */ + +// /* [Bug #1552726] Only limit the pause if an input hook has been +// defined. */ +// struct timeval *timeoutp = NULL; +// if (PyOS_InputHook) +// timeoutp = &timeout; +// #ifdef HAVE_RL_RESIZE_TERMINAL +// /* Update readline's view of the window size after SIGWINCH */ +// if (sigwinch_received) { +// sigwinch_received = 0; +// rl_resize_terminal(); +// } +// #endif +// FD_SET(fileno(rl_instream), &selectset); +// /* select resets selectset if no input was available */ +// has_input = select(fileno(rl_instream) + 1, &selectset, +// NULL, NULL, timeoutp); +// err = errno; +// if(PyOS_InputHook) PyOS_InputHook(); +// } + +// if (has_input > 0) { +// rl_callback_read_char(); +// } +// else if (err == EINTR) { +// int s; +// PyEval_RestoreThread(_PyOS_ReadlineTState); +// s = PyErr_CheckSignals(); +// PyEval_SaveThread(); +// if (s < 0) { +// rl_free_line_state(); +// #if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0700 +// rl_callback_sigcleanup(); +// #endif +// rl_cleanup_after_signal(); +// rl_callback_handler_remove(); +// *signal = 1; +// completed_input_string = NULL; +// } +// } +// } + +// return completed_input_string; +// } + + +// static char * +// call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) +// { +// size_t n; +// char *p; +// int signal; + +// #ifdef SAVE_LOCALE +// char *saved_locale = strdup(setlocale(LC_CTYPE, NULL)); +// if (!saved_locale) +// Py_FatalError("not enough memory to save locale"); +// _Py_SetLocaleFromEnv(LC_CTYPE); +// #endif + +// if (sys_stdin != rl_instream || sys_stdout != rl_outstream) { +// rl_instream = sys_stdin; +// rl_outstream = sys_stdout; +// #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER +// rl_prep_terminal (1); +// #endif +// } + +// p = readline_until_enter_or_signal(prompt, &signal); + +// /* we got an interrupt signal */ +// if (signal) { +// RESTORE_LOCALE(saved_locale) +// return NULL; +// } + +// /* We got an EOF, return an empty string. */ +// if (p == NULL) { +// p = PyMem_RawMalloc(1); +// if (p != NULL) +// *p = '\0'; +// RESTORE_LOCALE(saved_locale) +// return p; +// } + +// /* we have a valid line */ +// n = strlen(p); +// if (should_auto_add_history && n > 0) { +// const char *line; +// int length = _py_get_history_length(); +// if (length > 0) { +// HIST_ENTRY *hist_ent; +// if (using_libedit_emulation) { +// /* handle older 0-based or newer 1-based indexing */ +// hist_ent = history_get(length + libedit_history_start - 1); +// } else +// hist_ent = history_get(length); +// line = hist_ent ? hist_ent->line : ""; +// } else +// line = ""; +// if (strcmp(p, line)) +// add_history(p); +// } +// /* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and +// release the original. */ +// char *q = p; +// p = PyMem_RawMalloc(n+2); +// if (p != NULL) { +// memcpy(p, q, n); +// p[n] = '\n'; +// p[n+1] = '\0'; +// } +// free(q); +// RESTORE_LOCALE(saved_locale) +// return p; +// } + + +// /* Initialize the module */ + +// PyDoc_STRVAR(doc_module, +// "Importing this module enables command line editing using GNU readline."); + +// PyDoc_STRVAR(doc_module_le, +// "Importing this module enables command line editing using libedit readline."); + +// static struct PyModuleDef readlinemodule = { +// PyModuleDef_HEAD_INIT, +// "readline", +// doc_module, +// sizeof(readlinestate), +// readline_methods, +// NULL, +// readline_traverse, +// readline_clear, +// readline_free +// }; + + +// PyMODINIT_FUNC +// PyInit_readline(void) +// { +// PyObject *m; +// readlinestate *mod_state; + +// if (strncmp(rl_library_version, libedit_version_tag, strlen(libedit_version_tag)) == 0) { +// using_libedit_emulation = 1; +// } + +// if (using_libedit_emulation) +// readlinemodule.m_doc = doc_module_le; + + +// m = PyModule_Create(&readlinemodule); + +// if (m == NULL) +// return NULL; + +// if (PyModule_AddIntConstant(m, "_READLINE_VERSION", +// RL_READLINE_VERSION) < 0) { +// goto error; +// } +// if (PyModule_AddIntConstant(m, "_READLINE_RUNTIME_VERSION", +// rl_readline_version) < 0) { +// goto error; +// } +// if (PyModule_AddStringConstant(m, "_READLINE_LIBRARY_VERSION", +// rl_library_version) < 0) +// { +// goto error; +// } + +// mod_state = (readlinestate *) PyModule_GetState(m); +// PyOS_ReadlineFunctionPointer = call_readline; +// setup_readline(mod_state); + +// return m; + +// error: +// Py_DECREF(m); +// return NULL; +// } diff --git a/python/Modules/resource.c b/python/Modules/resource.c new file mode 100755 index 0000000..afde03c --- /dev/null +++ b/python/Modules/resource.c @@ -0,0 +1,494 @@ + +#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 (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 */ + + +static struct PyModuleDef resourcemodule = { + PyModuleDef_HEAD_INIT, + "resource", + NULL, + -1, + resource_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_resource(void) +{ + PyObject *m, *v; + + /* Create the module and add the functions */ + m = PyModule_Create(&resourcemodule); + if (m == NULL) + return NULL; + + /* Add some symbolic constants to the module */ + Py_INCREF(PyExc_OSError); + PyModule_AddObject(m, "error", PyExc_OSError); + if (!initialized) { + if (PyStructSequence_InitType2(&StructRUsageType, + &struct_rusage_desc) < 0) + return NULL; + } + + Py_INCREF(&StructRUsageType); + PyModule_AddObject(m, "struct_rusage", + (PyObject*) &StructRUsageType); + + /* insert constants */ +#ifdef RLIMIT_CPU + PyModule_AddIntMacro(m, RLIMIT_CPU); +#endif + +#ifdef RLIMIT_FSIZE + PyModule_AddIntMacro(m, RLIMIT_FSIZE); +#endif + +#ifdef RLIMIT_DATA + PyModule_AddIntMacro(m, RLIMIT_DATA); +#endif + +#ifdef RLIMIT_STACK + PyModule_AddIntMacro(m, RLIMIT_STACK); +#endif + +#ifdef RLIMIT_CORE + PyModule_AddIntMacro(m, RLIMIT_CORE); +#endif + +#ifdef RLIMIT_NOFILE + PyModule_AddIntMacro(m, RLIMIT_NOFILE); +#endif + +#ifdef RLIMIT_OFILE + PyModule_AddIntMacro(m, RLIMIT_OFILE); +#endif + +#ifdef RLIMIT_VMEM + PyModule_AddIntMacro(m, RLIMIT_VMEM); +#endif + +#ifdef RLIMIT_AS + PyModule_AddIntMacro(m, RLIMIT_AS); +#endif + +#ifdef RLIMIT_RSS + PyModule_AddIntMacro(m, RLIMIT_RSS); +#endif + +#ifdef RLIMIT_NPROC + PyModule_AddIntMacro(m, RLIMIT_NPROC); +#endif + +#ifdef RLIMIT_MEMLOCK + PyModule_AddIntMacro(m, RLIMIT_MEMLOCK); +#endif + +#ifdef RLIMIT_SBSIZE + PyModule_AddIntMacro(m, RLIMIT_SBSIZE); +#endif + +/* Linux specific */ +#ifdef RLIMIT_MSGQUEUE + PyModule_AddIntMacro(m, RLIMIT_MSGQUEUE); +#endif + +#ifdef RLIMIT_NICE + PyModule_AddIntMacro(m, RLIMIT_NICE); +#endif + +#ifdef RLIMIT_RTPRIO + PyModule_AddIntMacro(m, RLIMIT_RTPRIO); +#endif + +#ifdef RLIMIT_RTTIME + PyModule_AddIntMacro(m, RLIMIT_RTTIME); +#endif + +#ifdef RLIMIT_SIGPENDING + PyModule_AddIntMacro(m, RLIMIT_SIGPENDING); +#endif + +/* target */ +#ifdef RUSAGE_SELF + PyModule_AddIntMacro(m, RUSAGE_SELF); +#endif + +#ifdef RUSAGE_CHILDREN + PyModule_AddIntMacro(m, RUSAGE_CHILDREN); +#endif + +#ifdef RUSAGE_BOTH + PyModule_AddIntMacro(m, RUSAGE_BOTH); +#endif + +#ifdef RUSAGE_THREAD + PyModule_AddIntMacro(m, RUSAGE_THREAD); +#endif + +/* FreeBSD specific */ + +#ifdef RLIMIT_SWAP + PyModule_AddIntMacro(m, RLIMIT_SWAP); +#endif + +#ifdef RLIMIT_SBSIZE + PyModule_AddIntMacro(m, RLIMIT_SBSIZE); +#endif + +#ifdef RLIMIT_NPTS + PyModule_AddIntMacro(m, RLIMIT_NPTS); +#endif + + if (sizeof(RLIM_INFINITY) > sizeof(long)) { + v = PyLong_FromLongLong((long long) RLIM_INFINITY); + } else + { + v = PyLong_FromLong((long) RLIM_INFINITY); + } + if (v) { + PyModule_AddObject(m, "RLIM_INFINITY", v); + } + initialized = 1; + return m; +} diff --git a/python/Modules/rotatingtree.c b/python/Modules/rotatingtree.c new file mode 100755 index 0000000..07e08bc --- /dev/null +++ b/python/Modules/rotatingtree.c @@ -0,0 +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; +} diff --git a/python/Modules/rotatingtree.h b/python/Modules/rotatingtree.h new file mode 100755 index 0000000..7b3e5fd --- /dev/null +++ b/python/Modules/rotatingtree.h @@ -0,0 +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); diff --git a/python/Modules/selectmodule.c b/python/Modules/selectmodule.c new file mode 100755 index 0000000..a71b642 --- /dev/null +++ b/python/Modules/selectmodule.c @@ -0,0 +1,2693 @@ +/* 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 + +#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 + +/*[clinic input] +module select +class select.poll "pollObject *" "&poll_Type" +class select.devpoll "devpollObject *" "&devpoll_Type" +class select.epoll "pyEpoll_Object *" "&pyEpoll_Type" +class select.kqueue "kqueue_queue_Object *" "&kqueue_queue_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ded80abdad2b7552]*/ + +static int +fildes_converter(PyObject *o, void *p) +{ + int fd; + int *pointer = (int *)p; + fd = PyObject_AsFileDescriptor(o); + if (fd == -1) + return 0; + *pointer = fd; + return 1; +} + +/*[python input] +class fildes_converter(CConverter): + type = 'int' + converter = 'fildes_converter' +[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 */ + +/*[clinic input] +select.select + + rlist: object + wlist: object + xlist: object + timeout as timeout_obj: object = None + / + +Wait until one or more file descriptors are ready for some kind of I/O. + +The first three arguments are iterables of file descriptors to be waited for: +rlist -- wait until ready for reading +wlist -- wait until ready for writing +xlist -- wait for an "exceptional condition" +If only one kind of condition is required, pass [] for the other lists. + +A file descriptor is either a socket or file object, or a small integer +gotten from a fileno() method call on one of those. + +The optional 4th argument specifies a timeout in seconds; it may be +a floating point number to specify fractions of seconds. If it is absent +or None, the call will never time out. + +The return value is a tuple of three lists corresponding to the first three +arguments; each contains the subset of the corresponding file descriptors +that are ready. + +*** IMPORTANT NOTICE *** +On Windows, only sockets are supported; on Unix, all file +descriptors can be used. +[clinic start generated code]*/ + +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 */ + + /* 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; + if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0) + goto finally; + if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0) + 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? + */ + rlist = set2list(&ifdset, rfd2obj); + wlist = set2list(&ofdset, wfd2obj); + xlist = set2list(&efdset, efd2obj); + 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; + +static PyTypeObject poll_Type; + +/* 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 * +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; + 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; +} + + +/*[clinic input] +select.poll.modify + + fd: fildes + either an integer, or an object with a fileno() method returning + an int + eventmask: unsigned_short + a bitmask describing the type of events to check for + / + +Modify an already registered file descriptor. +[clinic start generated code]*/ + +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; + if (PyDict_GetItemWithError(self->dict, key) == NULL) { + if (!PyErr_Occurred()) { + errno = ENOENT; + PyErr_SetFromErrno(PyExc_OSError); + } + 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; +} + + +/*[clinic input] +select.poll.unregister + + fd: fildes + / + +Remove a file descriptor being tracked by the polling object. +[clinic start generated code]*/ + +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; +} + +/*[clinic input] +select.poll.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 * +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; + + 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; + self = PyObject_New(pollObject, &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; +} + +static void +poll_dealloc(pollObject *self) +{ + if (self->ufds != NULL) + PyMem_DEL(self->ufds); + Py_XDECREF(self->dict); + PyObject_Del(self); +} + + +#ifdef HAVE_SYS_DEVPOLL_H +typedef struct { + PyObject_HEAD + int fd_devpoll; + int max_n_fds; + int n_fds; + struct pollfd *fds; +} devpollObject; + +static PyTypeObject devpoll_Type; + +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; +} + +/*[clinic input] +select.devpoll.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 * +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 + 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 + / + +Modify a possible already registered file descriptor. +[clinic start generated code]*/ + +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 * +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; +} + +/*[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 * +select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) +/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/ +{ + 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 */ + 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; +} + +/*[clinic input] +select.devpoll.close + +Close the devpoll file descriptor. + +Further operations on the devpoll object will raise an exception. +[clinic start generated code]*/ + +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; +} + +/*[clinic input] +select.devpoll.fileno + +Return the file descriptor. +[clinic start generated code]*/ + +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; + } + + self = PyObject_New(devpollObject, &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; +} + +static void +devpoll_dealloc(devpollObject *self) +{ + (void)devpoll_internal_close(self); + PyMem_DEL(self->fds); + PyObject_Del(self); +} + +#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 * +select_poll_impl(PyObject *module) +/*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/ +{ + return (PyObject *)newPollObject(); +} + +#ifdef HAVE_SYS_DEVPOLL_H + +/*[clinic input] +select.devpoll + +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 * +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; + +static PyTypeObject pyEpoll_Type; +#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &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; + + assert(type != NULL && type->tp_alloc != NULL); + self = (pyEpoll_Object *) type->tp_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; +} + + +/*[clinic input] +@classmethod +select.epoll.__new__ + + sizehint: int = -1 + The expected number of events to be registered. It must be positive, + or -1 to use the default. It is only used on older systems where + epoll_create1() is not available; otherwise it has no effect (though its + value is still checked). + flags: int = 0 + Deprecated and completely ignored. However, when supplied, its value + must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised. + +Returns an epolling object. +[clinic start generated code]*/ + +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) { + 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) +{ + (void)pyepoll_internal_close(self); + Py_TYPE(self)->tp_free(self); +} + +/*[clinic input] +select.epoll.close + +Close the epoll control file descriptor. + +Further operations on the epoll object will raise an exception. +[clinic start generated code]*/ + +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; +} + +/*[clinic input] +select.epoll.fileno + +Return the epoll control file descriptor. +[clinic start generated code]*/ + +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); +} + + +/*[clinic input] +@classmethod +select.epoll.fromfd + + fd: int + / + +Create an epoll object from a given control fd. +[clinic start generated code]*/ + +static PyObject * +select_epoll_fromfd_impl(PyTypeObject *type, int fd) +/*[clinic end generated code: output=c15de2a083524e8e input=faecefdb55e3046e]*/ +{ + SOCKET s_fd = (SOCKET)fd; + return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd); +} + + +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); + if (errno == EBADF) { + /* fd already closed */ + result = 0; + errno = 0; + } + 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 + + fd: fildes + the target file descriptor of the operation + eventmask: unsigned_int(c_default="EPOLLIN | EPOLLPRI | EPOLLOUT", bitwise=True) = select.EPOLLIN | select.EPOLLPRI | select.EPOLLOUT + a bit set composed of the various EPOLL constants + +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 * +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 * +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 * +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 * +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; + _PyTime_t timeout = -1, ms = -1, deadline = 0; + + 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(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) { + ms = -1; + } + + 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; +} + + +/*[clinic input] +select.epoll.__enter__ + +[clinic start generated code]*/ + +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; +} + +/*[clinic input] +select.epoll.__exit__ + + exc_type: object = None + exc_value: object = None + exc_tb: object = None + / + +[clinic start generated code]*/ + +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]*/ +{ + _Py_IDENTIFIER(close); + + return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL); +} + +static PyGetSetDef pyepoll_getsetlist[] = { + {"closed", (getter)pyepoll_get_closed, NULL, + "True if the epoll handler is closed"}, + {0}, +}; + +#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; + +static PyTypeObject kqueue_event_Type; + +#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type)) + +typedef struct { + PyObject_HEAD + SOCKET kqfd; /* kqueue control fd */ +} kqueue_queue_Object; + +static PyTypeObject kqueue_queue_Type; + +#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &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); +} + +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 && type->tp_alloc != NULL); + self = (kqueue_queue_Object *) type->tp_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; +} + +/*[clinic input] +@classmethod +select.kqueue.__new__ + +Kqueue syscall wrapper. + +For example, to start watching a socket for input: +>>> kq = kqueue() +>>> sock = socket() +>>> sock.connect((host, port)) +>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0) + +To wait one second for it to become writeable: +>>> kq.control(None, 1, 1000) + +To stop listening: +>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0) +[clinic start generated code]*/ + +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) +{ + kqueue_queue_internal_close(self); + Py_TYPE(self)->tp_free(self); +} + +/*[clinic input] +select.kqueue.close + +Close the kqueue control file descriptor. + +Further operations on the kqueue object will raise an exception. +[clinic start generated code]*/ + +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; +} + +/*[clinic input] +select.kqueue.fileno + +Return the kqueue control file descriptor. +[clinic start generated code]*/ + +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); +} + +/*[clinic input] +@classmethod +select.kqueue.fromfd + + fd: int + / + +Create a kqueue object from a given control fd. +[clinic start generated code]*/ + +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. + maxevents: int + The maximum number of events that the kernel will return. + timeout as otimeout: object = None + The maximum time to wait in seconds, or else None to wait forever. + This accepts floats for smaller timeouts, too. + / + +Calls the kernel kevent function. +[clinic start generated code]*/ + +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(); + + if (maxevents < 0) { + PyErr_Format(PyExc_ValueError, + "Length of eventlist must be 0 or positive, got %d", + maxevents); + 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", + Py_TYPE(otimeout)->tp_name); + 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 (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, + 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; + + ch = PyObject_New(kqueue_event_Object, &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; +} + +static PyGetSetDef kqueue_queue_getsetlist[] = { + {"closed", (getter)kqueue_queue_get_closed, NULL, + "True if the kqueue handler is closed"}, + {0}, +}; + +#endif /* HAVE_KQUEUE */ + + +/* ************************************************************************ */ + +#include "clinic/selectmodule.c.h" + +#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) + +static PyMethodDef poll_methods[] = { + SELECT_POLL_REGISTER_METHODDEF + SELECT_POLL_MODIFY_METHODDEF + SELECT_POLL_UNREGISTER_METHODDEF + SELECT_POLL_POLL_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject poll_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) + "select.poll", /*tp_name*/ + sizeof(pollObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)poll_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*/ + poll_methods, /*tp_methods*/ +}; + +#ifdef HAVE_SYS_DEVPOLL_H + +static PyMethodDef devpoll_methods[] = { + SELECT_DEVPOLL_REGISTER_METHODDEF + SELECT_DEVPOLL_MODIFY_METHODDEF + SELECT_DEVPOLL_UNREGISTER_METHODDEF + SELECT_DEVPOLL_POLL_METHODDEF + SELECT_DEVPOLL_CLOSE_METHODDEF + SELECT_DEVPOLL_FILENO_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject devpoll_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) + "select.devpoll", /*tp_name*/ + sizeof(devpollObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)devpoll_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*/ + devpoll_methods, /*tp_methods*/ + 0, /* tp_members */ + devpoll_getsetlist, /* tp_getset */ +}; + +#endif /* HAVE_SYS_DEVPOLL_H */ + +#endif /* HAVE_POLL */ + +#ifdef HAVE_EPOLL + +static PyMethodDef pyepoll_methods[] = { + SELECT_EPOLL_FROMFD_METHODDEF + SELECT_EPOLL_CLOSE_METHODDEF + SELECT_EPOLL_FILENO_METHODDEF + SELECT_EPOLL_MODIFY_METHODDEF + SELECT_EPOLL_REGISTER_METHODDEF + SELECT_EPOLL_UNREGISTER_METHODDEF + SELECT_EPOLL_POLL_METHODDEF + SELECT_EPOLL___ENTER___METHODDEF + SELECT_EPOLL___EXIT___METHODDEF + {NULL, NULL}, +}; + +static PyTypeObject pyEpoll_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "select.epoll", /* tp_name */ + sizeof(pyEpoll_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pyepoll_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 */ + select_epoll__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pyepoll_methods, /* tp_methods */ + 0, /* tp_members */ + pyepoll_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 */ + select_epoll, /* tp_new */ + 0, /* tp_free */ +}; + +#endif /* HAVE_EPOLL */ + +#ifdef HAVE_KQUEUE + +static PyTypeObject kqueue_event_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "select.kevent", /* tp_name */ + sizeof(kqueue_event_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)kqueue_event_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 */ + kqueue_event_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + kqueue_event_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)kqueue_event_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ +}; + +static PyMethodDef kqueue_queue_methods[] = { + SELECT_KQUEUE_FROMFD_METHODDEF + SELECT_KQUEUE_CLOSE_METHODDEF + SELECT_KQUEUE_FILENO_METHODDEF + SELECT_KQUEUE_CONTROL_METHODDEF + {NULL, NULL}, +}; + +static PyTypeObject kqueue_queue_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "select.kqueue", /* tp_name */ + sizeof(kqueue_queue_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)kqueue_queue_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 */ + select_kqueue__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + kqueue_queue_methods, /* tp_methods */ + 0, /* tp_members */ + kqueue_queue_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 */ + select_kqueue, /* tp_new */ + 0, /* tp_free */ +}; + +#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."); + + +static struct PyModuleDef selectmodule = { + PyModuleDef_HEAD_INIT, + "select", + module_doc, + -1, + select_methods, + NULL, + NULL, + NULL, + NULL +}; + + + + +PyMODINIT_FUNC +PyInit_select(void) +{ + PyObject *m; + m = PyModule_Create(&selectmodule); + if (m == NULL) + return NULL; + + 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 + if (PyType_Ready(&poll_Type) < 0) + return NULL; + 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 + if (PyType_Ready(&devpoll_Type) < 0) + return NULL; +#endif + +#ifdef HAVE_EPOLL + Py_TYPE(&pyEpoll_Type) = &PyType_Type; + if (PyType_Ready(&pyEpoll_Type) < 0) + return NULL; + + Py_INCREF(&pyEpoll_Type); + PyModule_AddObject(m, "epoll", (PyObject *) &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 + kqueue_event_Type.tp_new = PyType_GenericNew; + Py_TYPE(&kqueue_event_Type) = &PyType_Type; + if(PyType_Ready(&kqueue_event_Type) < 0) + return NULL; + + Py_INCREF(&kqueue_event_Type); + PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type); + + Py_TYPE(&kqueue_queue_Type) = &PyType_Type; + if(PyType_Ready(&kqueue_queue_Type) < 0) + return NULL; + Py_INCREF(&kqueue_queue_Type); + PyModule_AddObject(m, "kqueue", (PyObject *)&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; +} diff --git a/python/Modules/sha1module.c b/python/Modules/sha1module.c new file mode 100755 index 0000000..4a8dbd8 --- /dev/null +++ b/python/Modules/sha1module.c @@ -0,0 +1,561 @@ +/* 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; + } + + /* pad upto 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*/ + 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*/ + 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'' + +Return a new SHA1 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +_sha1_sha1_impl(PyObject *module, PyObject *string) +/*[clinic end generated code: output=e5982830d1dece51 input=27ea54281d995ec2]*/ +{ + 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. */ + +#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } + + +static struct PyModuleDef _sha1module = { + PyModuleDef_HEAD_INIT, + "_sha1", + NULL, + -1, + SHA1_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__sha1(void) +{ + PyObject *m; + + Py_TYPE(&SHA1type) = &PyType_Type; + if (PyType_Ready(&SHA1type) < 0) + return NULL; + + m = PyModule_Create(&_sha1module); + if (m == NULL) + return NULL; + + Py_INCREF((PyObject *)&SHA1type); + PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type); + return m; +} diff --git a/python/Modules/sha256module.c b/python/Modules/sha256module.c new file mode 100755 index 0000000..a1c8b1a --- /dev/null +++ b/python/Modules/sha256module.c @@ -0,0 +1,729 @@ +/* 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 "structmember.h" +#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; + +#if SIZEOF_INT == 4 +typedef unsigned int SHA_INT32; /* 32-bit integer */ +#else +/* not defined. compilation will die. */ +#endif + +/* 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) +{ + SHA_INT32 value; + + byteCount /= sizeof(*buffer); + while (byteCount--) { + value = *buffer; + value = ( ( value & 0xFF00FF00L ) >> 8 ) | \ + ( ( value & 0x00FF00FFL ) << 8 ); + *buffer++ = ( value << 16 ) | ( value >> 16 ); + } +} +#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; + + if (Py_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*/ + 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*/ + 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_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'' + +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) +/*[clinic end generated code: output=fa644436dcea5c31 input=09cce3fb855056b2]*/ +{ + 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'' + +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) +/*[clinic end generated code: output=21e3ba22c3404f93 input=27a04ba24c353a73]*/ +{ + 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. */ + +#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } + + +static struct PyModuleDef _sha256module = { + PyModuleDef_HEAD_INIT, + "_sha256", + NULL, + -1, + SHA_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__sha256(void) +{ + PyObject *m; + + Py_TYPE(&SHA224type) = &PyType_Type; + if (PyType_Ready(&SHA224type) < 0) + return NULL; + Py_TYPE(&SHA256type) = &PyType_Type; + if (PyType_Ready(&SHA256type) < 0) + 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; + +} diff --git a/python/Modules/sha512module.c b/python/Modules/sha512module.c new file mode 100755 index 0000000..4167fd3 --- /dev/null +++ b/python/Modules/sha512module.c @@ -0,0 +1,793 @@ +/* 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 "structmember.h" +#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; + +#if SIZEOF_INT == 4 +typedef unsigned int SHA_INT32; /* 32-bit integer */ +typedef unsigned long long SHA_INT64; /* 64-bit integer */ +#else +/* not defined. compilation will die. */ +#endif + +/* 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) +{ + SHA_INT64 value; + + byteCount /= sizeof(*buffer); + while (byteCount--) { + value = *buffer; + + ((unsigned char*)buffer)[0] = (unsigned char)(value >> 56) & 0xff; + ((unsigned char*)buffer)[1] = (unsigned char)(value >> 48) & 0xff; + ((unsigned char*)buffer)[2] = (unsigned char)(value >> 40) & 0xff; + ((unsigned char*)buffer)[3] = (unsigned char)(value >> 32) & 0xff; + ((unsigned char*)buffer)[4] = (unsigned char)(value >> 24) & 0xff; + ((unsigned char*)buffer)[5] = (unsigned char)(value >> 16) & 0xff; + ((unsigned char*)buffer)[6] = (unsigned char)(value >> 8) & 0xff; + ((unsigned char*)buffer)[7] = (unsigned char)(value ) & 0xff; + + 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. + * + * 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; + + if (((PyObject*)self)->ob_type == &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*/ + 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*/ + 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_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'' + +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) +/*[clinic end generated code: output=8b865a2df73bd387 input=e69bad9ae9b6a308]*/ +{ + 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'' + +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) +/*[clinic end generated code: output=ae4b2e26decf81e8 input=c9327788d4ea4545]*/ +{ + 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. */ + +#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } + + +static struct PyModuleDef _sha512module = { + PyModuleDef_HEAD_INIT, + "_sha512", + NULL, + -1, + SHA_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__sha512(void) +{ + PyObject *m; + + Py_TYPE(&SHA384type) = &PyType_Type; + if (PyType_Ready(&SHA384type) < 0) + return NULL; + Py_TYPE(&SHA512type) = &PyType_Type; + if (PyType_Ready(&SHA512type) < 0) + return NULL; + + m = PyModule_Create(&_sha512module); + if (m == 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; +} diff --git a/python/Modules/signalmodule.c b/python/Modules/signalmodule.c new file mode 100755 index 0000000..4b855d6 --- /dev/null +++ b/python/Modules/signalmodule.c @@ -0,0 +1,1865 @@ + +/* 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_ceval.h" +#include "pycore_pystate.h" + +#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_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]*/ + +/*[python input] + +class sigset_t_converter(CConverter): + type = 'sigset_t' + converter = '_Py_Sigset_Converter' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/ + +/* + 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 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 + 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. +*/ + +#include "pythread.h" + +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 int +is_main_interp(_PyRuntimeState *runtime, PyInterpreterState *interp) +{ + unsigned long thread = PyThread_get_thread_ident(); + return (thread == runtime->main_thread + && interp == runtime->interpreters.main); +} + +static int +is_main(_PyRuntimeState *runtime) +{ + PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + return is_main_interp(runtime, interp); +} + +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; + 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_Restore(exc, val, tb); + 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_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); + + /* Notify ceval.c */ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + _PyEval_SignalReceived(&runtime->ceval); + + /* 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) + { + /* Py_AddPendingCall() isn't signal-safe, but we + still use it for this exceptional case. */ + _PyEval_AddPendingCall(tstate, &runtime->ceval, + 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)) + { + /* Py_AddPendingCall() isn't signal-safe, but we + still use it for this exceptional case. */ + _PyEval_AddPendingCall(tstate, &runtime->ceval, + report_wakeup_write_error, + (void *)(intptr_t)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 + +/*[clinic input] +signal.raise_signal + + signalnum: int + / + +Send a signal to the executing process. +[clinic start generated code]*/ + +static PyObject * +signal_raise_signal_impl(PyObject *module, int signalnum) +/*[clinic end generated code: output=e2b014220aa6111d input=e90c0f9a42358de6]*/ +{ + int err; + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + err = raise(signalnum); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (err) { + return PyErr_SetFromErrno(PyExc_OSError); + } + 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 + + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main(runtime)) { + PyErr_SetString(PyExc_ValueError, + "signal only works in main thread"); + return NULL; + } + if (signalnum < 1 || signalnum >= NSIG) { + PyErr_SetString(PyExc_ValueError, + "signal number out of range"); + return NULL; + } + if (handler == IgnoreHandler) + func = SIG_IGN; + else if (handler == DefaultHandler) + func = SIG_DFL; + else if (!PyCallable_Check(handler)) { + PyErr_SetString(PyExc_TypeError, +"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object"); + return NULL; + } + else + func = signal_handler; + /* Check for pending signals before changing signal handler */ + if (_PyErr_CheckSignals()) { + 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; + if (old_handler != NULL) + 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 + + signalnum: int + / + +Return the system description of the given signal. + +The return values can be such as "Interrupt", "Segmentation fault", etc. +Returns None if the signal is not recognized. +[clinic start generated code]*/ + +static PyObject * +signal_strsignal_impl(PyObject *module, int signalnum) +/*[clinic end generated code: output=44e12e1e3b666261 input=b77914b03f856c74]*/ +{ + char *res; + + if (signalnum < 1 || signalnum >= NSIG) { + PyErr_SetString(PyExc_ValueError, + "signal number out of range"); + return NULL; + } + +#ifndef HAVE_STRSIGNAL + switch (signalnum) { + /* Though being a UNIX, HP-UX does not provide strsignal(3). */ +#ifndef MS_WINDOWS + case SIGHUP: + res = "Hangup"; + break; + case SIGALRM: + res = "Alarm clock"; + break; + case SIGPIPE: + res = "Broken pipe"; + break; + case SIGQUIT: + res = "Quit"; + break; + case SIGCHLD: + res = "Child exited"; + break; +#endif + /* Custom redefinition of POSIX signals allowed on Windows. */ + case SIGINT: + res = "Interrupt"; + break; + case SIGILL: + res = "Illegal instruction"; + break; + case SIGABRT: + res = "Aborted"; + break; + case SIGFPE: + res = "Floating point exception"; + break; + case SIGSEGV: + res = "Segmentation fault"; + break; + case SIGTERM: + res = "Terminated"; + break; + 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 + + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main(runtime)) { + PyErr_SetString(PyExc_ValueError, + "set_wakeup_fd only works in main thread"); + 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(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(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 + +#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 */ + + +#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) + +/*[clinic input] +signal.valid_signals + +Return a set of valid signal numbers on this platform. + +The signal numbers returned by this function can be safely passed to +functions like `pthread_sigmask`. +[clinic start generated code]*/ + +static PyObject * +signal_valid_signals_impl(PyObject *module) +/*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/ +{ +#ifdef MS_WINDOWS +#ifdef SIGBREAK + PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE, + SIGILL, SIGINT, SIGSEGV, SIGTERM); +#else + PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL, + SIGINT, SIGSEGV, SIGTERM); +#endif + if (tup == NULL) { + return NULL; + } + PyObject *set = PySet_New(tup); + Py_DECREF(tup); + return set; +#else + sigset_t mask; + if (sigemptyset(&mask) || sigfillset(&mask)) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return sigset_to_set(mask); +#endif +} + +#endif /* #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) */ + + +#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 + +#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 * +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 + 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 + + 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 * +signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, + 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 + 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 */ + + +#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) */ + + + +/* 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 + {"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_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) +{ + 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); + + DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); + if (!DefaultHandler || + PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) { + goto finally; + } + + IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); + if (!IgnoreHandler || + PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) { + 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 + + 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); + 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); +#ifdef HAVE_GETITIMER + Py_CLEAR(ItimerError); +#endif +} + + +/* Declared in pyerrors.h */ +int +PyErr_CheckSignals(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main(runtime)) { + return 0; + } + + return _PyErr_CheckSignals(); +} + + +/* Declared in cpython/pyerrors.h */ +int +_PyErr_CheckSignals(void) +{ + int i; + PyObject *f; + + if (!_Py_atomic_load(&is_tripped)) + 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); + + if (!(f = (PyObject *)PyEval_GetFrame())) + f = Py_None; + + for (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 + * signal handler for it by the time PyErr_CheckSignals() is called + * (see bpo-43406). + */ + PyObject *func = Handlers[i].func; + if (func == NULL || func == Py_None || func == IgnoreHandler || + func == DefaultHandler) { + /* No Python signal handler due to aforementioned race condition. + * We can't call raise() as it would break the assumption + * that PyErr_SetInterrupt() only *simulates* an incoming + * signal (i.e. it will never kill the process). + * We also don't want to interrupt user code with a cryptic + * asynchronous exception, so instead just write out an + * unraisable error. + */ + PyErr_Format(PyExc_OSError, + "Signal %i ignored due to race condition", + i); + PyErr_WriteUnraisable(Py_None); + continue; + } + + PyObject *result = NULL; + PyObject *arglist = Py_BuildValue("(iO)", i, f); + if (arglist) { + result = PyEval_CallObject(func, arglist); + Py_DECREF(arglist); + } + if (!result) { + /* On error, re-schedule a call to PyErr_CheckSignals() */ + _Py_atomic_store(&is_tripped, 1); + return -1; + } + Py_DECREF(result); + } + + return 0; +} + + +/* Simulate the effect of a signal.SIGINT signal arriving. The next time + PyErr_CheckSignals is called, the Python SIGINT signal handler will be + raised. + + Missing signal handler for the SIGINT signal is silently ignored. */ +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); + } +} + + +static int +signal_install_handlers(void) +{ +#ifdef SIGPIPE + PyOS_setsig(SIGPIPE, SIG_IGN); +#endif +#ifdef SIGXFZ + PyOS_setsig(SIGXFZ, SIG_IGN); +#endif +#ifdef SIGXFSZ + PyOS_setsig(SIGXFSZ, SIG_IGN); +#endif + + // Import _signal to install the Python SIGINT handler + PyObject *module = PyImport_ImportModule("_signal"); + if (!module) { + return -1; + } + Py_DECREF(module); + + return 0; +} + + +int +_PySignal_Init(int install_signal_handlers) +{ +#ifdef MS_WINDOWS + /* Create manual-reset event, initially unset */ + sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE); + if (sigint_event == NULL) { + PyErr_SetFromWindowsErr(0); + return -1; + } +#endif + + if (install_signal_handlers) { + if (signal_install_handlers() < 0) { + return -1; + } + } + + return 0; +} + + +void +PyOS_FiniInterrupts(void) +{ + finisignal(); +} + + +// The caller doesn't have to hold the GIL +int +_PyOS_InterruptOccurred(PyThreadState *tstate) +{ + if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) { + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main_interp(runtime, tstate->interp)) { + return 0; + } + _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0); + return 1; + } + return 0; +} + + +// The caller must to hold the GIL +int +PyOS_InterruptOccurred(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyOS_InterruptOccurred(tstate); +} + + +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) +{ + _PyRuntimeState *runtime = &_PyRuntime; + return is_main(runtime); +} + +#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/python/Modules/socketmodule.c b/python/Modules/socketmodule.c new file mode 100755 index 0000000..5406f8b --- /dev/null +++ b/python/Modules/socketmodule.c @@ -0,0 +1,8305 @@ +/* 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. +- 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 + +*/ + +#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 "structmember.h" + +#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(0 | 1) -- 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\ +if_nameindex() -- return all network interface indices and names\n\ +if_nametoindex(name) -- return the corresponding interface index\n\ +if_indextoname(index) -- return the corresponding interface name\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(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) +# include "pythread.h" +#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 + +/* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */ +#ifdef MS_WINDOWS +#define IPPROTO_ICMP IPPROTO_ICMP +#define IPPROTO_IGMP IPPROTO_IGMP +#define IPPROTO_GGP IPPROTO_GGP +#define IPPROTO_TCP IPPROTO_TCP +#define IPPROTO_PUP IPPROTO_PUP +#define IPPROTO_UDP IPPROTO_UDP +#define IPPROTO_IDP IPPROTO_IDP +#define IPPROTO_ND IPPROTO_ND +#define IPPROTO_RAW IPPROTO_RAW +#define IPPROTO_MAX IPPROTO_MAX +#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS +#define IPPROTO_IPV4 IPPROTO_IPV4 +#define IPPROTO_IPV6 IPPROTO_IPV6 +#define IPPROTO_ROUTING IPPROTO_ROUTING +#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT +#define IPPROTO_ESP IPPROTO_ESP +#define IPPROTO_AH IPPROTO_AH +#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 +#define IPPROTO_NONE IPPROTO_NONE +#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS +#define IPPROTO_EGP IPPROTO_EGP +#define IPPROTO_PIM IPPROTO_PIM +#define IPPROTO_ICLFXBM IPPROTO_ICLFXBM // WinSock2 only +#define IPPROTO_ST IPPROTO_ST // WinSock2 only +#define IPPROTO_CBT IPPROTO_CBT // WinSock2 only +#define IPPROTO_IGP IPPROTO_IGP // WinSock2 only +#define IPPROTO_RDP IPPROTO_RDP // WinSock2 only +#define IPPROTO_PGM IPPROTO_PGM // WinSock2 only +#define IPPROTO_L2TP IPPROTO_L2TP // WinSock2 only +#define IPPROTO_SCTP IPPROTO_SCTP // WinSock2 only +#endif /* MS_WINDOWS */ + +/* 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 +#undef EAFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define snprintf _snprintf +#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 + +/* 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, (char *)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); + + /* 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. */ + if (ms < 0) { +#ifdef INFTIM + ms = INFTIM; +#else + ms = -1; +#endif + } + + 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 readyness. */ + 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) { + bdaddr->b[0] = b0; + bdaddr->b[1] = b1; + bdaddr->b[2] = b2; + bdaddr->b[3] = b3; + bdaddr->b[4] = b4; + bdaddr->b[5] = b5; + 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]; + + 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]); + 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) { + + 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; + } + + 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; + } + + 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__ */ + + 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 */ + 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", + obj->ob_type->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, + struct sockaddr *addr_ret, int *len_ret, const char *caller) +{ + switch (s->sock_family) { + +#if defined(AF_UNIX) + case AF_UNIX: + { + struct sockaddr_un* addr; + 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); + + addr = (struct sockaddr_un*)addr_ret; +#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: + { + struct sockaddr_nl* addr; + int pid, groups; + addr = (struct sockaddr_nl *)addr_ret; + 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; + } + 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 */ + +#if defined(AF_QIPCRTR) + case AF_QIPCRTR: + { + struct sockaddr_qrtr* addr; + unsigned int node, port; + addr = (struct sockaddr_qrtr *)addr_ret; + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, + "getsockaddrarg: " + "AF_QIPCRTR address must be tuple, not %.500s", + Py_TYPE(args)->tp_name); + return 0; + } + if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &node, &port)) + return 0; + addr->sq_family = AF_QIPCRTR; + addr->sq_node = node; + addr->sq_port = port; + *len_ret = sizeof(*addr); + return 1; + } +#endif /* AF_QIPCRTR */ + +#if defined(AF_VSOCK) + case AF_VSOCK: + { + struct sockaddr_vm* addr; + int port, cid; + addr = (struct sockaddr_vm *)addr_ret; + 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 sockaddr_in* addr; + 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; + } + if (!PyArg_ParseTuple(args, + "O&i;AF_INET address must be a pair " + "(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; + } + addr=(struct sockaddr_in*)addr_ret; + 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, + "%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 sockaddr_in6* addr; + 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; + } + if (!PyArg_ParseTuple(args, + "O&i|II;AF_INET6 address must be a tuple " + "(host, port[, flowinfo[, scopeid]])", + idna_converter, &host, &port, &flowinfo, + &scope_id)) + { + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Format(PyExc_OverflowError, + "%s(): port must be 0-65535.", caller); + } + return 0; + } + addr = (struct sockaddr_in6*)addr_ret; + 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, + "%s(): port must be 0-65535.", caller); + return 0; + } + if (flowinfo > 0xfffff) { + PyErr_Format( + 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) { + case BTPROTO_L2CAP: + { + struct sockaddr_l2 *addr; + const char *straddr; + + addr = (struct sockaddr_l2 *)addr_ret; + 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; + } + case BTPROTO_RFCOMM: + { + struct sockaddr_rc *addr; + const char *straddr; + + addr = (struct sockaddr_rc *)addr_ret; + _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; + } + case BTPROTO_HCI: + { + struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret; +#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))) { + 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: + { + struct sockaddr_sco *addr; + const char *straddr; + + addr = (struct sockaddr_sco *)addr_ret; + _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__ */ + 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 sockaddr_ll* addr; + 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; + } + /* XXX: improve the default error message according to the + documentation of AF_PACKET, which would be added as part + of bpo-25041. */ + if (!PyArg_ParseTuple(args, + "si|iiy*;AF_PACKET address must be a tuple of " + "two to five elements", + &interfaceName, &protoNumber, &pkttype, &hatype, + &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) { + PyErr_Format( + PyExc_OverflowError, + "%s(): proto must be 0-65535.", caller); + PyBuffer_Release(&haddr); + return 0; + } + addr = (struct sockaddr_ll*)addr_ret; + 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; + struct sockaddr_tipc *addr; + + 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, + "IIII|I;AF_TIPC address must be a tuple " + "(addr_type, v1, v2, v3[, scope])", + &atype, &v1, &v2, &v3, &scope)) + { + return 0; + } + + addr = (struct sockaddr_tipc *) addr_ret; + 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) + { + struct sockaddr_can *addr; + PyObject *interfaceName; + struct ifreq ifr; + Py_ssize_t len; + addr = (struct sockaddr_can *)addr_ret; + + 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; + } + if (!PyArg_ParseTuple(args, + "O&;AF_CAN address must be a tuple " + "(interface, )", + PyUnicode_FSConverter, &interfaceName)) + { + 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: + { + struct sockaddr_can *addr; + PyObject *interfaceName; + struct ifreq ifr; + Py_ssize_t len; + unsigned long int rx_id, tx_id; + + addr = (struct sockaddr_can *)addr_ret; + + 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 */ + 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: + { + struct sockaddr_ctl *addr; + + addr = (struct sockaddr_ctl *)addr_ret; + 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: + PyErr_Format(PyExc_OSError, + "%s(): unsupported PF_SYSTEM protocol", caller); + return 0; + } +#endif /* PF_SYSTEM */ +#ifdef HAVE_SOCKADDR_ALG + case AF_ALG: + { + struct sockaddr_alg *sa; + const char *type; + const char *name; + sa = (struct sockaddr_alg *)addr_ret; + + 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", + caller, Py_TYPE(args)->tp_name); + return 0; + } + if (!PyArg_ParseTuple(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: + 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 */ + +#if defined(AF_QIPCRTR) + case AF_QIPCRTR: + { + *len_ret = sizeof (struct sockaddr_qrtr); + return 1; + } +#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) + { + + case BTPROTO_L2CAP: + *len_ret = sizeof (struct sockaddr_l2); + return 1; + case BTPROTO_RFCOMM: + *len_ret = sizeof (struct sockaddr_rc); + return 1; + 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__ */ + 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, SAS2SA(&addrbuf), &addrlen, "bind")) { + return NULL; + } + + if (PySys_Audit("socket.bind", "OO", s, addro) < 0) { + 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(); + } + } + 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, SAS2SA(&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, SAS2SA(&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, SAS2SA(&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, SAS2SA(&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_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); + PyModule_AddIntMacro(m, BTPROTO_L2CAP); + PyModule_AddIntMacro(m, BTPROTO_HCI); + PyModule_AddIntMacro(m, SOL_HCI); +#if !defined(__NetBSD__) && !defined(__DragonFly__) + PyModule_AddIntMacro(m, HCI_FILTER); +#endif +#if !defined(__FreeBSD__) +#if !defined(__NetBSD__) && !defined(__DragonFly__) + PyModule_AddIntMacro(m, HCI_TIME_STAMP); +#endif + PyModule_AddIntMacro(m, HCI_DATA_DIR); + PyModule_AddIntMacro(m, BTPROTO_SCO); +#endif + PyModule_AddIntMacro(m, BTPROTO_RFCOMM); + PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00"); + PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF"); +#endif + +#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 + 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 +#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_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); + + /* BCM flags */ + PyModule_AddIntConstant(m, "CAN_BCM_SETTIMER", SETTIMER); + PyModule_AddIntConstant(m, "CAN_BCM_STARTTIMER", STARTTIMER); + PyModule_AddIntConstant(m, "CAN_BCM_TX_COUNTEVT", TX_COUNTEVT); + PyModule_AddIntConstant(m, "CAN_BCM_TX_ANNOUNCE", TX_ANNOUNCE); + PyModule_AddIntConstant(m, "CAN_BCM_TX_CP_CAN_ID", TX_CP_CAN_ID); + PyModule_AddIntConstant(m, "CAN_BCM_RX_FILTER_ID", RX_FILTER_ID); + PyModule_AddIntConstant(m, "CAN_BCM_RX_CHECK_DLC", RX_CHECK_DLC); + PyModule_AddIntConstant(m, "CAN_BCM_RX_NO_AUTOTIMER", RX_NO_AUTOTIMER); + PyModule_AddIntConstant(m, "CAN_BCM_RX_ANNOUNCE_RESUME", RX_ANNOUNCE_RESUME); + PyModule_AddIntConstant(m, "CAN_BCM_TX_RESET_MULTI_IDX", TX_RESET_MULTI_IDX); + PyModule_AddIntConstant(m, "CAN_BCM_RX_RTR_FRAME", RX_RTR_FRAME); +#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 +#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_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); + PyModule_AddIntMacro(m, IPPROTO_CBT); + PyModule_AddIntMacro(m, IPPROTO_IGP); + PyModule_AddIntMacro(m, IPPROTO_RDP); + PyModule_AddIntMacro(m, IPPROTO_PGM); + PyModule_AddIntMacro(m, IPPROTO_L2TP); + 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 +/* 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 +# endif +# include +#else +# 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_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_BLUETOOTH_BLUETOOTH_H + struct sockaddr_l2 bt_l2; + struct sockaddr_rc bt_rc; + struct sockaddr_sco bt_sco; + struct sockaddr_hci bt_hci; +#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 +} 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/python/Modules/spwdmodule.c b/python/Modules/spwdmodule.c new file mode 100755 index 0000000..1601ec0 --- /dev/null +++ b/python/Modules/spwdmodule.c @@ -0,0 +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; +} diff --git a/python/Modules/sre.h b/python/Modules/sre.h new file mode 100755 index 0000000..a728488 --- /dev/null +++ b/python/Modules/sre.h @@ -0,0 +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; + SRE_CODE* pattern; /* points to REPEAT operator arguments */ + 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 */ + void* ptr; /* current position (also end of current slice) */ + void* beginning; /* start of original string */ + void* start; /* start of current slice */ + 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; + 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 diff --git a/python/Modules/sre_constants.h b/python/Modules/sre_constants.h new file mode 100755 index 0000000..c8ccb32 --- /dev/null +++ b/python/Modules/sre_constants.h @@ -0,0 +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 diff --git a/python/Modules/sre_lib.h b/python/Modules/sre_lib.h new file mode 100755 index 0000000..437ab43 --- /dev/null +++ b/python/Modules/sre_lib.h @@ -0,0 +1,1545 @@ +/* + * 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, 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) +SRE(charset)(SRE_STATE* state, 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) +SRE(charset_loc_ignore)(SRE_STATE* state, 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); +} + +LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int toplevel); + +LOCAL(Py_ssize_t) +SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) +{ + SRE_CODE chr; + SRE_CHAR c; + SRE_CHAR* ptr = (SRE_CHAR *)state->ptr; + SRE_CHAR* end = (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) +SRE(info)(SRE_STATE* state, 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 */ + + SRE_CHAR* end = (SRE_CHAR*) state->end; + SRE_CHAR* ptr = (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) + +#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(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; + SRE_CHAR* ptr; + 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) +SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int toplevel) +{ + SRE_CHAR* end = (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 +*/ diff --git a/python/Modules/symtablemodule.c b/python/Modules/symtablemodule.c new file mode 100755 index 0000000..9180f18 --- /dev/null +++ b/python/Modules/symtablemodule.c @@ -0,0 +1,126 @@ +#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 * +_symtable_symtable_impl(PyObject *module, PyObject *source, + PyObject *filename, const char *startstr) +/*[clinic end generated code: output=59eb0d5fc7285ac4 input=9dd8a50c0c36a4d7]*/ +{ + 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); + if (str == NULL) { + 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); + Py_XDECREF(source_copy); + return NULL; + } + st = _Py_SymtableStringObjectFlags(str, filename, start, &cf); + Py_DECREF(filename); + Py_XDECREF(source_copy); + if (st == 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); + 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; +} diff --git a/python/Modules/syslogmodule.c b/python/Modules/syslogmodule.c new file mode 100755 index 0000000..66ea270 --- /dev/null +++ b/python/Modules/syslogmodule.c @@ -0,0 +1,354 @@ +/*********************************************************** +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" + +#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, 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; + } + + 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; + + 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. + * So, we can still do loggin 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) +{ + 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 (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[] = { + {"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} +}; + +/* Initialization function for the module */ + + +static struct PyModuleDef syslogmodule = { + PyModuleDef_HEAD_INIT, + "syslog", + NULL, + -1, + syslog_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_syslog(void) +{ + PyObject *m; + + /* Create the module and add the functions */ + m = PyModule_Create(&syslogmodule); + if (m == NULL) + return NULL; + + /* Add some symbolic constants to the module */ + + /* Priorities */ + PyModule_AddIntMacro(m, LOG_EMERG); + PyModule_AddIntMacro(m, LOG_ALERT); + PyModule_AddIntMacro(m, LOG_CRIT); + PyModule_AddIntMacro(m, LOG_ERR); + PyModule_AddIntMacro(m, LOG_WARNING); + PyModule_AddIntMacro(m, LOG_NOTICE); + PyModule_AddIntMacro(m, LOG_INFO); + PyModule_AddIntMacro(m, LOG_DEBUG); + + /* openlog() option flags */ + PyModule_AddIntMacro(m, LOG_PID); + PyModule_AddIntMacro(m, LOG_CONS); + PyModule_AddIntMacro(m, LOG_NDELAY); +#ifdef LOG_ODELAY + PyModule_AddIntMacro(m, LOG_ODELAY); +#endif +#ifdef LOG_NOWAIT + PyModule_AddIntMacro(m, LOG_NOWAIT); +#endif +#ifdef LOG_PERROR + PyModule_AddIntMacro(m, LOG_PERROR); +#endif + + /* Facilities */ + PyModule_AddIntMacro(m, LOG_KERN); + PyModule_AddIntMacro(m, LOG_USER); + PyModule_AddIntMacro(m, LOG_MAIL); + PyModule_AddIntMacro(m, LOG_DAEMON); + PyModule_AddIntMacro(m, LOG_AUTH); + PyModule_AddIntMacro(m, LOG_LPR); + PyModule_AddIntMacro(m, LOG_LOCAL0); + PyModule_AddIntMacro(m, LOG_LOCAL1); + PyModule_AddIntMacro(m, LOG_LOCAL2); + PyModule_AddIntMacro(m, LOG_LOCAL3); + PyModule_AddIntMacro(m, LOG_LOCAL4); + PyModule_AddIntMacro(m, LOG_LOCAL5); + PyModule_AddIntMacro(m, LOG_LOCAL6); + PyModule_AddIntMacro(m, 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 + + PyModule_AddIntMacro(m, LOG_SYSLOG); + PyModule_AddIntMacro(m, LOG_CRON); + PyModule_AddIntMacro(m, LOG_UUCP); + PyModule_AddIntMacro(m, LOG_NEWS); + +#ifdef LOG_AUTHPRIV + PyModule_AddIntMacro(m, LOG_AUTHPRIV); +#endif + + return m; +} diff --git a/python/Modules/termios.c b/python/Modules/termios.c new file mode 100755 index 0000000..aee7f12 --- /dev/null +++ b/python/Modules/termios.c @@ -0,0 +1,972 @@ +/* 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."); + +static PyObject *TermiosError; + +static int fdconv(PyObject* obj, void* p) +{ + int fd; + + fd = PyObject_AsFileDescriptor(obj); + if (fd >= 0) { + *(int*)p = fd; + return 1; + } + return 0; +} + +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(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... */ + if (tcgetattr(fd, &mode) == -1) + return PyErr_SetFromErrno(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) + return PyErr_SetFromErrno(TermiosError); + if (cfsetospeed(&mode, (speed_t) ospeed) == -1) + return PyErr_SetFromErrno(TermiosError); + if (tcsetattr(fd, when, &mode) == -1) + return PyErr_SetFromErrno(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) + return PyErr_SetFromErrno(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) + return PyErr_SetFromErrno(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) + return PyErr_SetFromErrno(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) + return PyErr_SetFromErrno(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 +#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 struct PyModuleDef termiosmodule = { + PyModuleDef_HEAD_INIT, + "termios", + termios__doc__, + -1, + termios_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_termios(void) +{ + PyObject *m; + struct constant *constant = termios_constants; + + m = PyModule_Create(&termiosmodule); + if (m == NULL) + return NULL; + + if (TermiosError == NULL) { + TermiosError = PyErr_NewException("termios.error", NULL, NULL); + } + Py_INCREF(TermiosError); + PyModule_AddObject(m, "error", TermiosError); + + while (constant->name != NULL) { + PyModule_AddIntConstant(m, constant->name, constant->value); + ++constant; + } + return m; +} diff --git a/python/Modules/testcapi_long.h b/python/Modules/testcapi_long.h new file mode 100755 index 0000000..6bddad7 --- /dev/null +++ b/python/Modules/testcapi_long.h @@ -0,0 +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; +} diff --git a/python/Modules/timemodule.c b/python/Modules/timemodule.c new file mode 100755 index 0000000..096911d --- /dev/null +++ b/python/Modules/timemodule.c @@ -0,0 +1,1918 @@ +/* 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(__WATCOMC__) && !defined(__QNX__) +#include +#else +#ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#include "pythread.h" +#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 + +#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 +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."); +#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 + if (Py_TYPE(args) == &StructTimeType) { + PyObject *item; + item = PyStructSequence_GET_ITEM(args, 9); + if (item != Py_None) { + p->tm_zone = (char *)PyUnicode_AsUTF8(item); + if (p->tm_zone == NULL) { + return 0; + } +#if defined(__linux__) && !defined(__GLIBC__) + // Make an attempt to return the C library's own timezone strings to + // it. musl refuses to process a tm_zone field unless it produced + // it. See issue #34672. + if (utc_string && strcmp(p->tm_zone, utc_string) == 0) { + p->tm_zone = utc_string; + } + else if (tzname[0] && strcmp(p->tm_zone, tzname[0]) == 0) { + p->tm_zone = tzname[0]; + } + else if (tzname[1] && strcmp(p->tm_zone, tzname[1]) == 0) { + p->tm_zone = tzname[1]; + } +#endif + } + item = PyStructSequence_GET_ITEM(args, 10); + if (item != Py_None) { + p->tm_gmtoff = PyLong_AsLong(item); + 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; + } + +#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 * +time_mktime(PyObject *self, PyObject *tm_tuple) +{ + struct tm tm; + time_t tt; + + if (!gettmarg(tm_tuple, &tm, + "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 + to 03:14:07 UTC, January 19, 2038. Thanks to the workaround below, + it is possible to support years in range [1902; 2037] */ + if (tm.tm_year < 2 || tm.tm_year > 137) { + /* 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 + +#ifdef _AIX + /* bpo-34373: AIX mktime() has an integer overflow for years in range + [1902; 1969]. Workaround the issue by using a year greater or equal than + 1970 (tm_year >= 70): mktime() behaves correctly in that case + (ex: properly report errors). tm_year and tm_wday are adjusted after + mktime() call. */ + int orig_tm_year = tm.tm_year; + int delta_days = 0; + while (tm.tm_year < 70) { + /* Use 4 years to account properly leap years */ + tm.tm_year += 4; + delta_days -= (366 + (365 * 3)); + } +#endif + + 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. */ + && tm.tm_wday == -1) + { + 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; + } + + 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; +#ifdef CLOCK_PROF + const clockid_t clk_id = CLOCK_PROF; + const char *function = "clock_gettime(CLOCK_PROF)"; +#else + const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID; + const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)"; +#endif + + if (clock_gettime(clk_id, &ts) == 0) { + 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 + + /* 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; +} + +#elif defined(__sun) && defined(__SVR4) +#define HAVE_THREAD_TIME +static int +_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +{ + /* bpo-35455: On Solaris, CLOCK_THREAD_CPUTIME_ID clock is not always + available; use gethrvtime() to substitute this functionality. */ + if (info) { + info->implementation = "gethrvtime()"; + info->resolution = 1e-9; + info->monotonic = 1; + info->adjustable = 0; + } + *tp = _PyTime_FromNanoseconds(gethrvtime()); + return 0; +} + +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) +#define HAVE_THREAD_TIME +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 +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."); +#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) { + if (_PyTime_GetThreadTimeWithInfo(&t, &info) < 0) { + return NULL; + } + } +#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 +} +#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. + */ +#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); +#ifdef MS_WINDOWS + TIME_ZONE_INFORMATION tzinfo = {0}; + GetTimeZoneInformation(&tzinfo); + otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1); + if (otz0 == NULL) { + return -1; + } + otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1); + if (otz1 == NULL) { + Py_DECREF(otz0); + 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; + } +#endif // MS_WINDOWS + 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; + struct tm p; + time_t janzone_t, julyzone_t; + char janname[10], julyname[10]; + t = (time((time_t *)0) / YEAR) * YEAR; + _PyTime_localtime(t, &p); + get_zone(janname, 9, &p); + janzone_t = -get_gmtoff(t, &p); + janname[9] = '\0'; + t += YEAR/2; + _PyTime_localtime(t, &p); + 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) + if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE + || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE) + { + PyErr_SetString(PyExc_RuntimeError, "invalid GMT offset"); + return -1; + } + int janzone = (int)janzone_t; + int julyzone = (int)julyzone_t; + + PyObject *tzname_obj; + if (janzone < julyzone) { + /* DST is reversed in the southern hemisphere */ + PyModule_AddIntConstant(m, "timezone", julyzone); + PyModule_AddIntConstant(m, "altzone", janzone); + PyModule_AddIntConstant(m, "daylight", janzone != julyzone); + tzname_obj = Py_BuildValue("(zz)", julyname, janname); + } else { + PyModule_AddIntConstant(m, "timezone", janzone); + 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"); + + + +static struct PyModuleDef timemodule = { + PyModuleDef_HEAD_INIT, + "time", + module_doc, + -1, + time_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_time(void) +{ + PyObject *m; + m = PyModule_Create(&timemodule); + if (m == NULL) + return NULL; + + /* Set, or reset, module variables like time.timezone */ + if (init_timezone(m) < 0) { + return NULL; + } + +#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) + +#ifdef CLOCK_REALTIME + PyModule_AddIntMacro(m, CLOCK_REALTIME); +#endif +#ifdef CLOCK_MONOTONIC + PyModule_AddIntMacro(m, CLOCK_MONOTONIC); +#endif +#ifdef CLOCK_MONOTONIC_RAW + PyModule_AddIntMacro(m, CLOCK_MONOTONIC_RAW); +#endif +#ifdef CLOCK_HIGHRES + PyModule_AddIntMacro(m, CLOCK_HIGHRES); +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID + PyModule_AddIntMacro(m, CLOCK_PROCESS_CPUTIME_ID); +#endif +#ifdef CLOCK_THREAD_CPUTIME_ID + PyModule_AddIntMacro(m, CLOCK_THREAD_CPUTIME_ID); +#endif +#ifdef CLOCK_PROF + PyModule_AddIntMacro(m, CLOCK_PROF); +#endif +#ifdef CLOCK_BOOTTIME + PyModule_AddIntMacro(m, CLOCK_BOOTTIME); +#endif +#ifdef CLOCK_UPTIME + PyModule_AddIntMacro(m, CLOCK_UPTIME); +#endif +#ifdef CLOCK_UPTIME_RAW + PyModule_AddIntMacro(m, CLOCK_UPTIME_RAW); +#endif + +#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 NULL; + } + Py_INCREF(&StructTimeType); + PyModule_AddIntConstant(m, "_STRUCT_TM_ITEMS", 11); + PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType); + initialized = 1; + +#if defined(__linux__) && !defined(__GLIBC__) + struct tm tm; + const time_t zero = 0; + if (gmtime_r(&zero, &tm) != NULL) + utc_string = tm.tm_zone; +#endif + + if (PyErr_Occurred()) { + return NULL; + } + return m; +} + +/* 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/python/Modules/tkappinit.c b/python/Modules/tkappinit.c new file mode 100755 index 0000000..493da65 --- /dev/null +++ b/python/Modules/tkappinit.c @@ -0,0 +1,166 @@ +// /* appinit.c -- Tcl and Tk application initialization. + +// The function Tcl_AppInit() below initializes various Tcl packages. +// It is called for each Tcl interpreter created by _tkinter.create(). +// It needs to be compiled with -DWITH_ flags for each package +// that you are statically linking with. You may have to add sections +// for packages not yet listed below. + +// Note that those packages for which Tcl_StaticPackage() is called with +// a NULL first argument are known as "static loadable" packages to +// Tcl but not actually initialized. To use these, you have to load +// it explicitly, e.g. tkapp.eval("load {} Blt"). +// */ + +// #include +// #include +// #include + +// #include "tkinter.h" + +// #ifdef TKINTER_PROTECT_LOADTK +// /* See Tkapp_TkInit in _tkinter.c for the usage of tk_load_faile */ +// static int tk_load_failed; +// #endif + +// int +// Tcl_AppInit(Tcl_Interp *interp) +// { +// const char *_tkinter_skip_tk_init; +// #ifdef TKINTER_PROTECT_LOADTK +// const char *_tkinter_tk_failed; +// #endif + +// #ifdef TK_AQUA +// #ifndef MAX_PATH_LEN +// #define MAX_PATH_LEN 1024 +// #endif +// char tclLibPath[MAX_PATH_LEN], tkLibPath[MAX_PATH_LEN]; +// Tcl_Obj* pathPtr; + +// /* pre- Tcl_Init code copied from tkMacOSXAppInit.c */ +// Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tcllibrary", +// tclLibPath, MAX_PATH_LEN, 0); + +// if (tclLibPath[0] != '\0') { +// Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY); +// Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY); +// Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY); +// } + +// if (tclLibPath[0] != '\0') { +// Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY); +// Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY); +// Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY); +// } +// #endif +// if (Tcl_Init (interp) == TCL_ERROR) +// return TCL_ERROR; + +// #ifdef TK_AQUA +// /* pre- Tk_Init code copied from tkMacOSXAppInit.c */ +// Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tklibrary", +// tkLibPath, MAX_PATH_LEN, 1); + +// if (tclLibPath[0] != '\0') { +// pathPtr = Tcl_NewStringObj(tclLibPath, -1); +// } else { +// Tcl_Obj *pathPtr = TclGetLibraryPath(); +// } + +// if (tkLibPath[0] != '\0') { +// Tcl_Obj *objPtr; + +// Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY); +// objPtr = Tcl_NewStringObj(tkLibPath, -1); +// Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); +// } + +// TclSetLibraryPath(pathPtr); +// #endif + +// #ifdef WITH_XXX +// /* Initialize modules that don't require Tk */ +// #endif + +// _tkinter_skip_tk_init = Tcl_GetVar(interp, +// "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY); +// if (_tkinter_skip_tk_init != NULL && +// strcmp(_tkinter_skip_tk_init, "1") == 0) { +// return TCL_OK; +// } + +// #ifdef TKINTER_PROTECT_LOADTK +// _tkinter_tk_failed = Tcl_GetVar(interp, +// "_tkinter_tk_failed", TCL_GLOBAL_ONLY); + +// if (tk_load_failed || ( +// _tkinter_tk_failed != NULL && +// strcmp(_tkinter_tk_failed, "1") == 0)) { +// Tcl_SetResult(interp, TKINTER_LOADTK_ERRMSG, TCL_STATIC); +// return TCL_ERROR; +// } +// #endif + +// if (Tk_Init(interp) == TCL_ERROR) { +// #ifdef TKINTER_PROTECT_LOADTK +// tk_load_failed = 1; +// Tcl_SetVar(interp, "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); +// #endif +// return TCL_ERROR; +// } + +// Tk_MainWindow(interp); + +// #ifdef TK_AQUA +// TkMacOSXInitAppleEvents(interp); +// TkMacOSXInitMenus(interp); +// #endif + +// #ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */ +// { +// extern void TkImaging_Init(Tcl_Interp *); +// TkImaging_Init(interp); +// /* XXX TkImaging_Init() doesn't have the right return type */ +// /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/ +// } +// #endif + +// #ifdef WITH_PIL_OLD /* 0.2b4 and earlier */ +// { +// extern void TkImaging_Init(void); +// /* XXX TkImaging_Init() doesn't have the right prototype */ +// /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/ +// } +// #endif + +// #ifdef WITH_TIX +// { +// extern int Tix_Init(Tcl_Interp *interp); +// extern int Tix_SafeInit(Tcl_Interp *interp); +// Tcl_StaticPackage(NULL, "Tix", Tix_Init, Tix_SafeInit); +// } +// #endif + +// #ifdef WITH_BLT +// { +// extern int Blt_Init(Tcl_Interp *); +// extern int Blt_SafeInit(Tcl_Interp *); +// Tcl_StaticPackage(NULL, "Blt", Blt_Init, Blt_SafeInit); +// } +// #endif + +// #ifdef WITH_TOGL +// { +// /* XXX I've heard rumors that this doesn't work */ +// extern int Togl_Init(Tcl_Interp *); +// /* XXX Is there no Togl_SafeInit? */ +// Tcl_StaticPackage(NULL, "Togl", Togl_Init, NULL); +// } +// #endif + +// #ifdef WITH_XXX + +// #endif +// return TCL_OK; +// } diff --git a/python/Modules/tkinter.h b/python/Modules/tkinter.h new file mode 100755 index 0000000..cb5a806 --- /dev/null +++ b/python/Modules/tkinter.h @@ -0,0 +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 */ diff --git a/python/Modules/unicodedata.c b/python/Modules/unicodedata.c new file mode 100755 index 0000000..5e8ba60 --- /dev/null +++ b/python/Modules/unicodedata.c @@ -0,0 +1,1485 @@ +/* ------------------------------------------------------------------------ + + 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" + +#include + +_Py_IDENTIFIER(NFC); +_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; +#define UCD_Check(o) (Py_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; + 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 +find_nfc_index(PyObject *self, 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; + 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 */ + f = find_nfc_index(self, 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; + } + } + l = find_nfc_index(self, 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<combining; + if (combining && prev_combining > combining) + return NO; /* non-canonical sort order, not normalized */ + prev_combining = combining; + + unsigned char quickcheck_whole = record->normalization_quick_check; + if (yes_only) { + if (quickcheck_whole & (3 << quickcheck_shift)) + return MAYBE; + } else { + switch ((quickcheck_whole >> quickcheck_shift) & 3) { + case NO: + return NO; + case MAYBE: + result = MAYBE; /* this string might need normalization */ + } + } + } + return result; +} + +/*[clinic input] +unicodedata.UCD.is_normalized + + self: self + form: unicode + unistr as input: unicode + / + +Return whether the Unicode string unistr is in the normal form 'form'. + +Valid values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, + PyObject *input) +/*[clinic end generated code: output=11e5a3694e723ca5 input=a544f14cea79e508]*/ +{ + if (PyUnicode_READY(input) == -1) { + return NULL; + } + + if (PyUnicode_GET_LENGTH(input) == 0) { + /* special case empty input strings. */ + Py_RETURN_TRUE; + } + + PyObject *result; + int nfc = 0; + int k = 0; + QuickcheckResult m; + + PyObject *cmp; + int match = 0; + + if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { + nfc = 1; + } + else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { + nfc = 1; + k = 1; + } + else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { + /* matches default values for `nfc` and `k` */ + } + else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { + k = 1; + } + else { + PyErr_SetString(PyExc_ValueError, "invalid normalization form"); + return NULL; + } + + m = is_normalized_quickcheck(self, input, nfc, k, false); + + if (m == MAYBE) { + cmp = (nfc ? nfc_nfkc : nfd_nfkd)(self, input, k); + if (cmp == NULL) { + return NULL; + } + match = PyUnicode_Compare(input, cmp); + Py_DECREF(cmp); + result = (match == 0) ? Py_True : Py_False; + } + else { + result = (m == YES) ? Py_True : Py_False; + } + + Py_INCREF(result); + return result; +} + + +/*[clinic input] +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 * +unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, + 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_EqualToASCIIId(form, &PyId_NFC)) { + if (is_normalized_quickcheck(self, input, 1, 0, true) == YES) { + Py_INCREF(input); + return input; + } + return nfc_nfkc(self, input, 0); + } + if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { + if (is_normalized_quickcheck(self, input, 1, 1, true) == YES) { + Py_INCREF(input); + return input; + } + return nfc_nfkc(self, input, 1); + } + if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { + if (is_normalized_quickcheck(self, input, 0, 0, true) == YES) { + Py_INCREF(input); + return input; + } + return nfd_nfkd(self, input, 0); + } + if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { + if (is_normalized_quickcheck(self, input, 0, 1, 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++) { + h = (h * scale) + (unsigned char) Py_TOUPPER(Py_CHARMASK(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 + (0x3400 <= code && code <= 0x4DB5) || /* CJK Ideograph Extension A */ + (0x4E00 <= code && code <= 0x9FEF) || /* CJK Ideograph */ + (0x20000 <= code && code <= 0x2A6D6) || /* 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 */ + (0x2CEB0 <= code && code <= 0x2EBEF); /* CJK Ideograph Extension F */ +} + +/* 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 (Py_TOUPPER(Py_CHARMASK(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 + 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*/ + 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_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_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: +*/ diff --git a/python/Modules/unicodedata_db.h b/python/Modules/unicodedata_db.h new file mode 100755 index 0000000..286287d --- /dev/null +++ b/python/Modules/unicodedata_db.h @@ -0,0 +1,7664 @@ +/* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ + +#define UNIDATA_VERSION "12.1.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}, + {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 376 +#define TOTAL_LAST 62 +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}, + {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} +}; + +/* 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, + 149, 150, 151, 152, 153, 154, 155, 156, 138, 157, 138, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 138, 167, 168, 138, 169, 170, 171, 172, + 138, 173, 174, 138, 175, 176, 177, 138, 138, 178, 179, 180, 181, 138, + 182, 138, 183, 41, 41, 41, 41, 41, 41, 41, 184, 185, 41, 186, 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, 187, 138, 138, + 138, 138, 138, 138, 138, 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, 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, 138, 138, + 138, 138, 138, 138, 138, 138, 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, 189, 190, 191, 192, 138, 138, 138, 138, 193, + 194, 195, 196, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 197, 101, 101, 101, 101, 101, + 198, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 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, 199, 101, 101, 200, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 201, 202, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 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, 203, + 204, 205, 206, 207, 208, 138, 209, 210, 211, 212, 213, 214, 215, 216, 78, + 78, 78, 78, 217, 218, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 219, 138, 220, 138, 138, 221, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 222, 223, 224, 138, 138, 138, 138, 138, 225, 226, 227, 138, + 228, 229, 138, 138, 230, 231, 232, 233, 234, 138, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 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, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 251, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 252, 101, 253, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 254, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 255, 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, 256, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 257, 138, 258, 259, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 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, 260, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 260, +}; + +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, + 118, 118, 0, 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, 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, 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, 140, 143, 140, 140, 48, 81, + 86, 81, 81, 135, 135, 135, 144, 144, 144, 144, 144, 144, 144, 144, 48, + 48, 135, 135, 83, 83, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 83, 53, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, + 140, 140, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 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, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 0, 0, 48, 48, 48, 48, 0, + 0, 146, 48, 147, 140, 140, 135, 135, 135, 135, 0, 0, 140, 140, 0, 0, 148, + 148, 143, 48, 0, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 0, 144, 144, 0, 144, + 48, 48, 135, 135, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 48, 48, 85, 85, 149, 149, 149, 149, 149, 149, 80, 85, 48, 83, 81, 0, 0, + 135, 135, 140, 0, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 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, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 144, 0, 48, 144, 0, 48, + 48, 0, 0, 146, 0, 140, 140, 140, 135, 135, 0, 0, 0, 0, 135, 135, 0, 0, + 135, 135, 143, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 48, 0, + 144, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 135, 135, 48, 48, 48, 135, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, + 135, 140, 0, 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, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, + 48, 0, 0, 146, 48, 140, 140, 140, 135, 135, 135, 135, 135, 0, 135, 135, + 140, 0, 140, 140, 143, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 135, 135, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 83, 85, 0, 0, 0, 0, 0, 0, 0, 48, 135, 135, 135, 135, 135, 135, + 0, 135, 140, 140, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 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, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, + 48, 48, 0, 0, 146, 48, 147, 135, 140, 135, 135, 135, 135, 0, 0, 140, 148, + 0, 0, 148, 148, 143, 0, 0, 0, 0, 0, 0, 0, 0, 150, 147, 0, 0, 0, 0, 144, + 144, 0, 48, 48, 48, 135, 135, 0, 0, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 80, 48, 149, 149, 149, 149, 149, 149, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 135, 48, 0, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 0, 48, + 48, 141, 48, 0, 0, 0, 48, 48, 0, 48, 0, 48, 48, 0, 0, 0, 48, 48, 0, 0, 0, + 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, + 0, 0, 0, 147, 140, 135, 140, 140, 0, 0, 0, 140, 140, 140, 0, 148, 148, + 148, 143, 0, 0, 48, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 149, 149, + 149, 26, 26, 26, 26, 26, 26, 85, 26, 0, 0, 0, 0, 0, 135, 140, 140, 140, + 135, 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, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, + 0, 0, 48, 135, 135, 135, 140, 140, 140, 140, 0, 135, 135, 151, 0, 135, + 135, 135, 143, 0, 0, 0, 0, 0, 0, 0, 152, 153, 0, 48, 48, 48, 0, 0, 0, 0, + 0, 48, 48, 135, 135, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 0, 0, 0, 0, 0, 0, 0, 83, 154, 154, 154, 154, 154, 154, 154, 80, 48, + 135, 140, 140, 83, 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, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, + 48, 48, 0, 0, 146, 48, 140, 155, 148, 140, 147, 140, 140, 0, 155, 148, + 148, 0, 148, 148, 135, 143, 0, 0, 0, 0, 0, 0, 0, 147, 147, 0, 0, 0, 0, 0, + 0, 0, 48, 0, 48, 48, 135, 135, 0, 0, 145, 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, 0, 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, 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, 135, 0, 0, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 80, 48, 48, 48, 48, 48, 48, 0, 0, 140, 140, 0, 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, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 156, 0, 0, 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, 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, 145, 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, 0, 48, 0, 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, 0, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 135, 48, 157, 135, 135, 135, 135, 160, 160, 143, 135, 135, 48, 0, 0, 48, + 48, 48, 48, 48, 0, 53, 0, 161, 161, 161, 161, 135, 135, 0, 0, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 157, 157, 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, 48, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, 162, 83, + 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, 80, 80, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 80, 86, 80, 86, 80, 163, 164, 165, 164, + 165, 140, 140, 48, 48, 48, 144, 48, 48, 48, 48, 0, 48, 48, 48, 48, 144, + 48, 48, 48, 48, 144, 48, 48, 48, 48, 144, 48, 48, 48, 48, 144, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 144, 48, 48, 48, 0, 0, 0, 0, 166, + 167, 168, 169, 168, 168, 170, 168, 170, 167, 167, 167, 167, 135, 140, + 167, 168, 81, 81, 143, 83, 81, 81, 48, 48, 48, 48, 48, 135, 135, 135, + 135, 135, 135, 168, 135, 135, 135, 135, 0, 135, 135, 135, 135, 168, 135, + 135, 135, 135, 168, 135, 135, 135, 135, 168, 135, 135, 135, 135, 168, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 168, 135, + 135, 135, 0, 80, 80, 80, 80, 80, 80, 80, 80, 86, 80, 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, 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, 145, 83, 83, 83, + 83, 83, 83, 48, 48, 48, 48, 48, 48, 140, 140, 135, 135, 48, 48, 48, 48, + 135, 135, 135, 48, 140, 140, 140, 48, 48, 140, 140, 140, 140, 140, 140, + 140, 48, 48, 48, 135, 135, 135, 135, 48, 48, 48, 48, 48, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 135, 135, 143, 83, 83, 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, 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, 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, 143, + 135, 83, 83, 83, 53, 83, 83, 83, 85, 48, 81, 0, 0, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 154, 154, 154, 154, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 81, 81, 81, 81, 81, 81, 81, 0, 0, 86, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 135, 135, 135, 135, 135, 135, 135, 135, + 140, 140, 135, 146, 0, 0, 0, 83, 83, 83, 83, 83, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 0, 0, 0, 48, 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, + 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, 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, 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, + 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, 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, + 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, 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, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 43, 43, 43, 43, 35, 183, 47, 47, 44, 47, 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, 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, 38, 43, 38, 43, 38, 43, 44, 47, 44, 47, 44, 47, 43, 43, + 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, + 43, 43, 0, 0, 38, 38, 38, 38, 38, 38, 0, 0, 43, 43, 43, 43, 43, 43, 43, + 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 43, 43, 38, + 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 0, 0, 38, 38, 38, 38, + 38, 38, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 0, 38, 0, 38, 0, 38, 0, 38, + 43, 43, 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 184, + 43, 184, 43, 184, 43, 184, 43, 184, 43, 184, 43, 184, 0, 0, 43, 43, 43, + 43, 43, 43, 43, 43, 185, 185, 185, 185, 185, 185, 185, 185, 43, 43, 43, + 43, 43, 43, 43, 43, 185, 185, 185, 185, 185, 185, 185, 185, 43, 43, 43, + 43, 43, 43, 43, 43, 185, 185, 185, 185, 185, 185, 185, 185, 43, 43, 43, + 43, 43, 0, 43, 43, 38, 38, 38, 186, 185, 58, 184, 58, 58, 76, 43, 43, 43, + 0, 43, 43, 38, 186, 38, 186, 185, 76, 76, 76, 43, 43, 43, 184, 0, 0, 43, + 43, 38, 38, 38, 186, 0, 76, 76, 76, 43, 43, 43, 184, 43, 43, 43, 43, 38, + 38, 38, 186, 38, 76, 187, 187, 0, 0, 43, 43, 43, 0, 43, 43, 38, 186, 38, + 186, 185, 187, 58, 0, 188, 188, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 175, 175, 175, 190, 191, 192, 193, 84, 192, 192, 192, 22, 194, 195, + 196, 197, 198, 195, 196, 197, 198, 22, 22, 22, 138, 199, 199, 199, 22, + 200, 201, 202, 203, 204, 205, 206, 21, 207, 110, 207, 208, 209, 22, 194, + 194, 138, 28, 36, 22, 194, 138, 199, 210, 210, 138, 138, 138, 211, 164, + 165, 194, 194, 194, 138, 138, 138, 138, 138, 138, 138, 138, 78, 138, 210, + 138, 138, 194, 138, 138, 138, 138, 138, 138, 138, 189, 175, 175, 175, + 175, 175, 0, 212, 213, 214, 215, 175, 175, 175, 175, 175, 175, 216, 51, + 0, 0, 34, 216, 216, 216, 216, 216, 217, 217, 218, 219, 220, 221, 216, 34, + 34, 34, 34, 216, 216, 216, 216, 216, 217, 217, 218, 219, 220, 0, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 0, 0, 85, 85, 85, 85, 85, + 85, 85, 85, 222, 223, 85, 85, 23, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 81, 81, 177, 177, 81, 81, 81, 81, 177, 177, 177, 81, 81, 82, + 82, 82, 82, 81, 82, 82, 82, 177, 177, 81, 86, 81, 177, 177, 86, 86, 86, + 86, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 49, 225, + 26, 225, 224, 49, 26, 225, 35, 49, 49, 49, 35, 35, 49, 49, 49, 46, 26, + 49, 225, 26, 78, 49, 49, 49, 49, 49, 26, 26, 224, 225, 225, 26, 49, 26, + 226, 26, 49, 26, 186, 226, 49, 49, 227, 35, 49, 49, 44, 49, 35, 157, 157, + 157, 157, 35, 26, 224, 35, 35, 49, 49, 228, 78, 78, 78, 78, 49, 35, 35, + 35, 35, 26, 78, 26, 26, 47, 80, 229, 229, 229, 37, 37, 229, 229, 229, + 229, 229, 229, 37, 37, 37, 37, 229, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 231, 231, 231, 231, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 231, 231, 231, 231, 231, 231, 174, 174, 174, 44, + 47, 174, 174, 174, 174, 37, 26, 26, 0, 0, 0, 0, 40, 40, 40, 40, 40, 30, + 30, 30, 30, 30, 232, 232, 26, 26, 26, 26, 78, 26, 26, 78, 26, 26, 78, 26, + 26, 26, 26, 26, 26, 26, 232, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 233, 232, 232, 26, 26, 40, 26, 40, 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, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 40, + 234, 235, 235, 236, 78, 78, 40, 235, 236, 234, 235, 236, 234, 78, 40, 78, + 235, 237, 238, 78, 235, 234, 78, 78, 78, 235, 234, 234, 235, 40, 235, + 235, 234, 234, 40, 236, 40, 236, 40, 40, 40, 40, 235, 239, 228, 235, 228, + 228, 234, 234, 234, 40, 40, 40, 40, 78, 234, 78, 234, 235, 235, 234, 234, + 234, 236, 234, 234, 236, 234, 234, 236, 235, 236, 234, 234, 235, 78, 78, + 78, 78, 78, 235, 234, 234, 234, 78, 78, 78, 78, 78, 78, 78, 78, 78, 234, + 240, 40, 236, 78, 235, 235, 235, 235, 234, 234, 235, 235, 78, 232, 240, + 240, 236, 236, 234, 234, 236, 236, 234, 234, 236, 236, 234, 234, 234, + 234, 234, 234, 236, 236, 235, 235, 236, 236, 235, 235, 236, 236, 234, + 234, 234, 78, 78, 234, 234, 234, 234, 78, 78, 40, 78, 78, 234, 40, 78, + 78, 78, 78, 78, 78, 78, 78, 234, 234, 78, 40, 234, 234, 234, 234, 234, + 234, 236, 236, 236, 236, 234, 234, 234, 234, 234, 234, 234, 234, 234, 78, + 78, 78, 78, 78, 234, 235, 78, 78, 78, 78, 78, 78, 78, 78, 78, 234, 234, + 234, 234, 234, 78, 78, 234, 234, 78, 78, 78, 78, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 236, 236, 236, 236, 234, 234, 234, 234, 234, + 234, 236, 236, 236, 236, 78, 78, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 26, 26, 26, 26, 26, 26, 26, 26, + 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, 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, 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, 0, 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, 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, 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, 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, + 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, + 26, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, + 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, + 26, 30, 40, 26, 26, 26, 26, 30, 30, 26, 26, 30, 40, 26, 26, 26, 26, 30, + 30, 30, 26, 26, 30, 26, 26, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 26, 26, 26, 26, 26, + 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, 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, + 26, 30, 30, 30, 30, 26, 30, 30, 26, 40, 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, 241, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 30, 30, 26, 241, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 80, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, + 30, 26, 26, 26, 26, 241, 241, 30, 30, 30, 30, 30, 30, 30, 30, 241, 30, + 30, 30, 30, 30, 241, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 26, 30, 26, 26, 26, 26, 30, 30, 241, 30, 30, 30, 30, 30, 30, 30, 241, + 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, 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, 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, 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, + 234, 234, 234, 234, 234, 234, 78, 78, 78, 78, 78, 78, 78, 78, 234, 78, + 78, 78, 78, 78, 78, 78, 234, 234, 234, 234, 234, 234, 78, 78, 78, 234, + 78, 78, 78, 78, 234, 234, 234, 234, 234, 78, 234, 234, 78, 78, 164, 165, + 164, 165, 234, 78, 78, 78, 78, 234, 78, 234, 234, 234, 78, 78, 234, 234, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 234, 234, 234, 234, 234, 234, 78, + 78, 164, 165, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 234, 234, + 228, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 78, 234, 234, 234, 234, 78, 78, 234, 78, 234, 78, 78, 234, + 78, 234, 234, 234, 234, 78, 78, 78, 78, 78, 234, 234, 78, 78, 78, 78, 78, + 78, 234, 234, 234, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 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, 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, 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, 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, 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, + 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, 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, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 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, 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, + 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, 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, 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, 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, + 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, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, + 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, 0, 0, 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, + 251, 251, 251, 241, 252, 171, 253, 254, 255, 254, 255, 254, 255, 254, + 255, 254, 255, 241, 241, 254, 255, 254, 255, 254, 255, 254, 255, 256, + 257, 258, 258, 241, 253, 253, 253, 253, 253, 253, 253, 253, 253, 259, + 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 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, 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, 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, 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, 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, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 48, 81, 82, 82, 82, 138, 81, + 81, 81, 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, 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, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 54, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 47, 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, 47, 44, 47, 44, 47, 44, 47, 44, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 47, 44, 47, 44, 47, 44, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 52, 275, 275, 44, 47, 44, 47, 48, 44, 47, 44, 47, 47, + 47, 44, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 140, 140, 135, 135, 140, 26, 26, 26, 26, 0, 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, 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, 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, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 48, 48, + 48, 48, 48, 48, 83, 83, 83, 48, 83, 48, 48, 135, 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, 135, 135, + 135, 135, 135, 86, 86, 86, 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, 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, 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, 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, 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, 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, + 53, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 135, 135, + 140, 140, 83, 83, 48, 53, 53, 140, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, + 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, 275, 51, 51, 51, 51, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 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, 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, 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, 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, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 35, + 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, + 35, 0, 0, 0, 0, 0, 279, 280, 279, 281, 281, 281, 281, 281, 281, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, + 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 81, 81, + 285, 288, 288, 289, 289, 286, 287, 286, 287, 286, 287, 286, 287, 286, + 287, 286, 287, 286, 287, 286, 287, 251, 251, 286, 287, 285, 285, 285, + 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 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, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 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, 48, 48, 48, 48, 48, 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, 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, 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, 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, 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, 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, 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, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 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, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, + 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 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, + 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, + 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, 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, 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, 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, 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, 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, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 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, 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, 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, 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, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 107, 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, 118, 86, 86, 81, 81, 81, 86, 81, 86, 86, 86, 86, 330, 330, 330, + 330, 113, 113, 113, 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 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, 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, 154, 154, 154, 154, 154, + 154, 154, 154, 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, 143, 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, 141, 48, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 141, 48, 48, 48, 48, 140, 140, 140, 135, 135, 135, 135, 140, 140, 143, + 142, 83, 83, 190, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, + 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, 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, 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, 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, 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, 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, 0, 0, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 48, 83, 48, 83, 83, 83, 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, 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, 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, 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, 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, 48, 0, 0, 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, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, + 0, 146, 146, 48, 147, 140, 135, 140, 140, 140, 140, 0, 0, 140, 140, 0, 0, + 148, 148, 176, 0, 0, 48, 0, 0, 0, 0, 0, 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, 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, + 0, 83, 0, 83, 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, 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, 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, + 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, 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, + 48, 48, 48, 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 44, 44, 44, 44, 44, 44, 44, 44, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 48, 48, 48, 140, 135, 135, + 135, 135, 135, 135, 135, 0, 135, 135, 135, 135, 135, 135, 140, 331, 48, + 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 0, 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, 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, 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, 48, 48, 48, 48, 48, 48, 48, + 135, 135, 135, 135, 135, 135, 0, 0, 0, 135, 0, 135, 135, 0, 135, 135, + 135, 146, 135, 143, 143, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 26, 26, 85, 85, 85, 85, + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 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, 48, 48, 48, 48, 48, + 48, 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, 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, 44, 44, 44, 44, 44, 44, 44, 44, + 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, 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 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, 252, 252, 251, 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, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 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, 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, 332, 332, 332, 332, 332, 332, 332, 333, 333, 177, 177, 177, + 80, 80, 80, 334, 333, 333, 333, 333, 333, 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, 81, 81, 81, 81, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 332, 332, 332, 332, 332, + 332, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 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, 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, 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, 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, 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, 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, 0, 49, 49, 0, 0, 49, 0, 0, 49, 49, 0, 0, 49, 49, + 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 0, 35, 0, 35, + 35, 35, 35, 35, 35, 35, 0, 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, + 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 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, 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, + 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, 49, 49, 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, 335, 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, 335, 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, 335, 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, 335, 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, 335, 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, 336, 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 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, 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, 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, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 81, 81, 81, 81, 81, 81, 81, 53, 53, 53, 53, 53, 53, 53, 0, + 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 48, 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, 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, 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, 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, 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, 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, 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, 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, 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, 131, 0, 131, 0, 0, 131, 0, + 131, 0, 131, 0, 131, 0, 131, 0, 131, 131, 0, 131, 0, 0, 131, 131, 131, + 131, 0, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, + 131, 131, 131, 0, 131, 0, 131, 131, 131, 131, 131, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 154, 154, 0, 0, 0, 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, 337, 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, 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, 224, 224, 224, 0, 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, 270, 338, 244, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 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, 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, 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, 26, 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, 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, 339, 339, 339, 339, 339, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 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, 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, 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, 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, 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, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 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, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 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, 0, 0, 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, 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, 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, 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, + 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 241, 241, 241, 241, 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, 0, 0, + 241, 241, 241, 241, 241, 241, 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, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 0, 0, 241, 241, 241, 241, 0, 0, 0, 0, 241, 241, 241, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 0, 0, 0, + 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 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, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 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, 0, 0, +}; + +/* 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, + 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, + 12457, 12531, 1290, 12456, 12473, 12463, 12540, 12489, 1034, 12456, + 12540, 12459, 12540, 778, 12458, 12531, 12473, 778, 12458, 12540, 12512, + 778, 12459, 12452, 12522, 1034, 12459, 12521, 12483, 12488, 1034, 12459, + 12525, 12522, 12540, 778, 12460, 12525, 12531, 778, 12460, 12531, 12510, + 522, 12462, 12460, 778, 12462, 12491, 12540, 1034, 12461, 12517, 12522, + 12540, 1034, 12462, 12523, 12480, 12540, 522, 12461, 12525, 1290, 12461, + 12525, 12464, 12521, 12512, 1546, 12461, 12525, 12513, 12540, 12488, + 12523, 1290, 12461, 12525, 12527, 12483, 12488, 778, 12464, 12521, 12512, + 1290, 12464, 12521, 12512, 12488, 12531, 1290, 12463, 12523, 12476, + 12452, 12525, 1034, 12463, 12525, 12540, 12493, 778, 12465, 12540, 12473, + 778, 12467, 12523, 12490, 778, 12467, 12540, 12509, 1034, 12469, 12452, + 12463, 12523, 1290, 12469, 12531, 12481, 12540, 12512, 1034, 12471, + 12522, 12531, 12464, 778, 12475, 12531, 12481, 778, 12475, 12531, 12488, + 778, 12480, 12540, 12473, 522, 12487, 12471, 522, 12489, 12523, 522, + 12488, 12531, 522, 12490, 12494, 778, 12494, 12483, 12488, 778, 12495, + 12452, 12484, 1290, 12497, 12540, 12475, 12531, 12488, 778, 12497, 12540, + 12484, 1034, 12496, 12540, 12524, 12523, 1290, 12500, 12450, 12473, + 12488, 12523, 778, 12500, 12463, 12523, 522, 12500, 12467, 522, 12499, + 12523, 1290, 12501, 12449, 12521, 12483, 12489, 1034, 12501, 12451, + 12540, 12488, 1290, 12502, 12483, 12471, 12455, 12523, 778, 12501, 12521, + 12531, 1290, 12504, 12463, 12479, 12540, 12523, 522, 12506, 12477, 778, + 12506, 12491, 12498, 778, 12504, 12523, 12484, 778, 12506, 12531, 12473, + 778, 12506, 12540, 12472, 778, 12505, 12540, 12479, 1034, 12509, 12452, + 12531, 12488, 778, 12508, 12523, 12488, 522, 12507, 12531, 778, 12509, + 12531, 12489, 778, 12507, 12540, 12523, 778, 12507, 12540, 12531, 1034, + 12510, 12452, 12463, 12525, 778, 12510, 12452, 12523, 778, 12510, 12483, + 12495, 778, 12510, 12523, 12463, 1290, 12510, 12531, 12471, 12519, 12531, + 1034, 12511, 12463, 12525, 12531, 522, 12511, 12522, 1290, 12511, 12522, + 12496, 12540, 12523, 522, 12513, 12460, 1034, 12513, 12460, 12488, 12531, + 1034, 12513, 12540, 12488, 12523, 778, 12516, 12540, 12489, 778, 12516, + 12540, 12523, 778, 12518, 12450, 12531, 1034, 12522, 12483, 12488, 12523, + 522, 12522, 12521, 778, 12523, 12500, 12540, 1034, 12523, 12540, 12502, + 12523, 522, 12524, 12512, 1290, 12524, 12531, 12488, 12466, 12531, 778, + 12527, 12483, 12488, 514, 48, 28857, 514, 49, 28857, 514, 50, 28857, 514, + 51, 28857, 514, 52, 28857, 514, 53, 28857, 514, 54, 28857, 514, 55, + 28857, 514, 56, 28857, 514, 57, 28857, 770, 49, 48, 28857, 770, 49, 49, + 28857, 770, 49, 50, 28857, 770, 49, 51, 28857, 770, 49, 52, 28857, 770, + 49, 53, 28857, 770, 49, 54, 28857, 770, 49, 55, 28857, 770, 49, 56, + 28857, 770, 49, 57, 28857, 770, 50, 48, 28857, 770, 50, 49, 28857, 770, + 50, 50, 28857, 770, 50, 51, 28857, 770, 50, 52, 28857, 778, 104, 80, 97, + 522, 100, 97, 522, 65, 85, 778, 98, 97, 114, 522, 111, 86, 522, 112, 99, + 522, 100, 109, 778, 100, 109, 178, 778, 100, 109, 179, 522, 73, 85, 522, + 24179, 25104, 522, 26157, 21644, 522, 22823, 27491, 522, 26126, 27835, + 1034, 26666, 24335, 20250, 31038, 522, 112, 65, 522, 110, 65, 522, 956, + 65, 522, 109, 65, 522, 107, 65, 522, 75, 66, 522, 77, 66, 522, 71, 66, + 778, 99, 97, 108, 1034, 107, 99, 97, 108, 522, 112, 70, 522, 110, 70, + 522, 956, 70, 522, 956, 103, 522, 109, 103, 522, 107, 103, 522, 72, 122, + 778, 107, 72, 122, 778, 77, 72, 122, 778, 71, 72, 122, 778, 84, 72, 122, + 522, 956, 8467, 522, 109, 8467, 522, 100, 8467, 522, 107, 8467, 522, 102, + 109, 522, 110, 109, 522, 956, 109, 522, 109, 109, 522, 99, 109, 522, 107, + 109, 778, 109, 109, 178, 778, 99, 109, 178, 522, 109, 178, 778, 107, 109, + 178, 778, 109, 109, 179, 778, 99, 109, 179, 522, 109, 179, 778, 107, 109, + 179, 778, 109, 8725, 115, 1034, 109, 8725, 115, 178, 522, 80, 97, 778, + 107, 80, 97, 778, 77, 80, 97, 778, 71, 80, 97, 778, 114, 97, 100, 1290, + 114, 97, 100, 8725, 115, 1546, 114, 97, 100, 8725, 115, 178, 522, 112, + 115, 522, 110, 115, 522, 956, 115, 522, 109, 115, 522, 112, 86, 522, 110, + 86, 522, 956, 86, 522, 109, 86, 522, 107, 86, 522, 77, 86, 522, 112, 87, + 522, 110, 87, 522, 956, 87, 522, 109, 87, 522, 107, 87, 522, 77, 87, 522, + 107, 937, 522, 77, 937, 1034, 97, 46, 109, 46, 522, 66, 113, 522, 99, 99, + 522, 99, 100, 1034, 67, 8725, 107, 103, 778, 67, 111, 46, 522, 100, 66, + 522, 71, 121, 522, 104, 97, 522, 72, 80, 522, 105, 110, 522, 75, 75, 522, + 75, 77, 522, 107, 116, 522, 108, 109, 522, 108, 110, 778, 108, 111, 103, + 522, 108, 120, 522, 109, 98, 778, 109, 105, 108, 778, 109, 111, 108, 522, + 80, 72, 1034, 112, 46, 109, 46, 778, 80, 80, 77, 522, 80, 82, 522, 115, + 114, 522, 83, 118, 522, 87, 98, 778, 86, 8725, 109, 778, 65, 8725, 109, + 514, 49, 26085, 514, 50, 26085, 514, 51, 26085, 514, 52, 26085, 514, 53, + 26085, 514, 54, 26085, 514, 55, 26085, 514, 56, 26085, 514, 57, 26085, + 770, 49, 48, 26085, 770, 49, 49, 26085, 770, 49, 50, 26085, 770, 49, 51, + 26085, 770, 49, 52, 26085, 770, 49, 53, 26085, 770, 49, 54, 26085, 770, + 49, 55, 26085, 770, 49, 56, 26085, 770, 49, 57, 26085, 770, 50, 48, + 26085, 770, 50, 49, 26085, 770, 50, 50, 26085, 770, 50, 51, 26085, 770, + 50, 52, 26085, 770, 50, 53, 26085, 770, 50, 54, 26085, 770, 50, 55, + 26085, 770, 50, 56, 26085, 770, 50, 57, 26085, 770, 51, 48, 26085, 770, + 51, 49, 26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, + 294, 259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 256, 35912, + 256, 26356, 256, 36554, 256, 36040, 256, 28369, 256, 20018, 256, 21477, + 256, 40860, 256, 40860, 256, 22865, 256, 37329, 256, 21895, 256, 22856, + 256, 25078, 256, 30313, 256, 32645, 256, 34367, 256, 34746, 256, 35064, + 256, 37007, 256, 27138, 256, 27931, 256, 28889, 256, 29662, 256, 33853, + 256, 37226, 256, 39409, 256, 20098, 256, 21365, 256, 27396, 256, 29211, + 256, 34349, 256, 40478, 256, 23888, 256, 28651, 256, 34253, 256, 35172, + 256, 25289, 256, 33240, 256, 34847, 256, 24266, 256, 26391, 256, 28010, + 256, 29436, 256, 37070, 256, 20358, 256, 20919, 256, 21214, 256, 25796, + 256, 27347, 256, 29200, 256, 30439, 256, 32769, 256, 34310, 256, 34396, + 256, 36335, 256, 38706, 256, 39791, 256, 40442, 256, 30860, 256, 31103, + 256, 32160, 256, 33737, 256, 37636, 256, 40575, 256, 35542, 256, 22751, + 256, 24324, 256, 31840, 256, 32894, 256, 29282, 256, 30922, 256, 36034, + 256, 38647, 256, 22744, 256, 23650, 256, 27155, 256, 28122, 256, 28431, + 256, 32047, 256, 32311, 256, 38475, 256, 21202, 256, 32907, 256, 20956, + 256, 20940, 256, 31260, 256, 32190, 256, 33777, 256, 38517, 256, 35712, + 256, 25295, 256, 27138, 256, 35582, 256, 20025, 256, 23527, 256, 24594, + 256, 29575, 256, 30064, 256, 21271, 256, 30971, 256, 20415, 256, 24489, + 256, 19981, 256, 27852, 256, 25976, 256, 32034, 256, 21443, 256, 22622, + 256, 30465, 256, 33865, 256, 35498, 256, 27578, 256, 36784, 256, 27784, + 256, 25342, 256, 33509, 256, 25504, 256, 30053, 256, 20142, 256, 20841, + 256, 20937, 256, 26753, 256, 31975, 256, 33391, 256, 35538, 256, 37327, + 256, 21237, 256, 21570, 256, 22899, 256, 24300, 256, 26053, 256, 28670, + 256, 31018, 256, 38317, 256, 39530, 256, 40599, 256, 40654, 256, 21147, + 256, 26310, 256, 27511, 256, 36706, 256, 24180, 256, 24976, 256, 25088, + 256, 25754, 256, 28451, 256, 29001, 256, 29833, 256, 31178, 256, 32244, + 256, 32879, 256, 36646, 256, 34030, 256, 36899, 256, 37706, 256, 21015, + 256, 21155, 256, 21693, 256, 28872, 256, 35010, 256, 35498, 256, 24265, + 256, 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, 20196, + 256, 22265, 256, 23527, 256, 23994, 256, 24604, 256, 29618, 256, 29801, + 256, 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, + 256, 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, + 256, 20698, 256, 23534, 256, 23615, 256, 26009, 256, 27138, 256, 29134, + 256, 30274, 256, 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, + 256, 21129, 256, 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, + 256, 30041, 256, 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, + 256, 38520, 256, 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, + 256, 24900, 256, 26647, 256, 29575, 256, 38534, 256, 21033, 256, 21519, + 256, 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, + 256, 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, + 256, 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, + 256, 38563, 256, 40023, 256, 40607, 256, 26519, 256, 28107, 256, 33256, + 256, 31435, 256, 31520, 256, 31890, 256, 29376, 256, 28825, 256, 35672, + 256, 20160, 256, 33590, 256, 21050, 256, 20999, 256, 24230, 256, 25299, + 256, 31958, 256, 23429, 256, 27934, 256, 26292, 256, 36667, 256, 34892, + 256, 38477, 256, 35211, 256, 24275, 256, 20800, 256, 21952, 256, 22618, + 256, 26228, 256, 20958, 256, 29482, 256, 30410, 256, 31036, 256, 31070, + 256, 31077, 256, 31119, 256, 38742, 256, 31934, 256, 32701, 256, 34322, + 256, 35576, 256, 36920, 256, 37117, 256, 39151, 256, 39164, 256, 39208, + 256, 40372, 256, 37086, 256, 38583, 256, 20398, 256, 20711, 256, 20813, + 256, 21193, 256, 21220, 256, 21329, 256, 21917, 256, 22022, 256, 22120, + 256, 22592, 256, 22696, 256, 23652, 256, 23662, 256, 24724, 256, 24936, + 256, 24974, 256, 25074, 256, 25935, 256, 26082, 256, 26257, 256, 26757, + 256, 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, + 256, 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, + 256, 31069, 256, 31117, 256, 31118, 256, 31296, 256, 31361, 256, 31680, + 256, 32244, 256, 32265, 256, 32321, 256, 32626, 256, 32773, 256, 33261, + 256, 33401, 256, 33401, 256, 33879, 256, 35088, 256, 35222, 256, 35585, + 256, 35641, 256, 36051, 256, 36104, 256, 36790, 256, 36920, 256, 38627, + 256, 38911, 256, 38971, 256, 24693, 256, 148206, 256, 33304, 256, 20006, + 256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191, + 256, 21242, 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618, + 256, 22707, 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, + 256, 24281, 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, + 256, 24974, 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628, + 256, 25682, 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454, + 256, 27513, 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450, + 256, 28702, 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482, + 256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410, + 256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409, + 256, 31680, 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773, + 256, 33618, 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222, + 256, 35519, 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565, + 256, 35641, 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273, + 256, 37494, 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911, + 256, 38923, 256, 38971, 256, 39698, 256, 40860, 256, 141386, 256, 141380, + 256, 144341, 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, + 154832, 256, 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, + 105, 514, 102, 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, + 116, 514, 115, 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, + 514, 1406, 1398, 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, + 1506, 262, 1488, 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, + 262, 1512, 262, 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, + 64329, 1473, 512, 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, + 1488, 1468, 512, 1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, + 1468, 512, 1493, 1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, + 512, 1498, 1468, 512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, + 1504, 1468, 512, 1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, + 1468, 512, 1511, 1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, + 512, 1493, 1465, 512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, + 1488, 1500, 267, 1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, + 1659, 267, 1662, 268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, + 269, 1664, 270, 1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, + 1663, 268, 1663, 269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, + 270, 1657, 267, 1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, + 1702, 269, 1702, 270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, + 267, 1667, 268, 1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, + 1670, 270, 1670, 267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, + 268, 1677, 267, 1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, + 1672, 267, 1688, 268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, + 269, 1705, 270, 1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, + 1715, 268, 1715, 269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, + 270, 1713, 267, 1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, + 1723, 267, 1728, 268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, + 267, 1726, 268, 1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, + 1747, 268, 1747, 267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, + 268, 1735, 267, 1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, + 1739, 268, 1739, 267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, + 268, 1744, 269, 1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, + 524, 1574, 1575, 523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, + 1574, 1608, 523, 1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, + 1734, 523, 1574, 1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, + 525, 1574, 1744, 523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, + 1740, 268, 1740, 269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, + 523, 1574, 1605, 523, 1574, 1609, 523, 1574, 1610, 523, 1576, 1580, 523, + 1576, 1581, 523, 1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, + 1610, 523, 1578, 1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, + 523, 1578, 1609, 523, 1578, 1610, 523, 1579, 1580, 523, 1579, 1605, 523, + 1579, 1609, 523, 1579, 1610, 523, 1580, 1581, 523, 1580, 1605, 523, 1581, + 1580, 523, 1581, 1605, 523, 1582, 1580, 523, 1582, 1581, 523, 1582, 1605, + 523, 1587, 1580, 523, 1587, 1581, 523, 1587, 1582, 523, 1587, 1605, 523, + 1589, 1581, 523, 1589, 1605, 523, 1590, 1580, 523, 1590, 1581, 523, 1590, + 1582, 523, 1590, 1605, 523, 1591, 1581, 523, 1591, 1605, 523, 1592, 1605, + 523, 1593, 1580, 523, 1593, 1605, 523, 1594, 1580, 523, 1594, 1605, 523, + 1601, 1580, 523, 1601, 1581, 523, 1601, 1582, 523, 1601, 1605, 523, 1601, + 1609, 523, 1601, 1610, 523, 1602, 1581, 523, 1602, 1605, 523, 1602, 1609, + 523, 1602, 1610, 523, 1603, 1575, 523, 1603, 1580, 523, 1603, 1581, 523, + 1603, 1582, 523, 1603, 1604, 523, 1603, 1605, 523, 1603, 1609, 523, 1603, + 1610, 523, 1604, 1580, 523, 1604, 1581, 523, 1604, 1582, 523, 1604, 1605, + 523, 1604, 1609, 523, 1604, 1610, 523, 1605, 1580, 523, 1605, 1581, 523, + 1605, 1582, 523, 1605, 1605, 523, 1605, 1609, 523, 1605, 1610, 523, 1606, + 1580, 523, 1606, 1581, 523, 1606, 1582, 523, 1606, 1605, 523, 1606, 1609, + 523, 1606, 1610, 523, 1607, 1580, 523, 1607, 1605, 523, 1607, 1609, 523, + 1607, 1610, 523, 1610, 1580, 523, 1610, 1581, 523, 1610, 1582, 523, 1610, + 1605, 523, 1610, 1609, 523, 1610, 1610, 523, 1584, 1648, 523, 1585, 1648, + 523, 1609, 1648, 779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, + 1617, 779, 32, 1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, + 1574, 1585, 524, 1574, 1586, 524, 1574, 1605, 524, 1574, 1606, 524, 1574, + 1609, 524, 1574, 1610, 524, 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, + 524, 1576, 1606, 524, 1576, 1609, 524, 1576, 1610, 524, 1578, 1585, 524, + 1578, 1586, 524, 1578, 1605, 524, 1578, 1606, 524, 1578, 1609, 524, 1578, + 1610, 524, 1579, 1585, 524, 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, + 524, 1579, 1609, 524, 1579, 1610, 524, 1601, 1609, 524, 1601, 1610, 524, + 1602, 1609, 524, 1602, 1610, 524, 1603, 1575, 524, 1603, 1604, 524, 1603, + 1605, 524, 1603, 1609, 524, 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, + 524, 1604, 1610, 524, 1605, 1575, 524, 1605, 1605, 524, 1606, 1585, 524, + 1606, 1586, 524, 1606, 1605, 524, 1606, 1606, 524, 1606, 1609, 524, 1606, + 1610, 524, 1609, 1648, 524, 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, + 524, 1610, 1606, 524, 1610, 1609, 524, 1610, 1610, 525, 1574, 1580, 525, + 1574, 1581, 525, 1574, 1582, 525, 1574, 1605, 525, 1574, 1607, 525, 1576, + 1580, 525, 1576, 1581, 525, 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, + 525, 1578, 1580, 525, 1578, 1581, 525, 1578, 1582, 525, 1578, 1605, 525, + 1578, 1607, 525, 1579, 1605, 525, 1580, 1581, 525, 1580, 1605, 525, 1581, + 1580, 525, 1581, 1605, 525, 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, + 525, 1587, 1581, 525, 1587, 1582, 525, 1587, 1605, 525, 1589, 1581, 525, + 1589, 1582, 525, 1589, 1605, 525, 1590, 1580, 525, 1590, 1581, 525, 1590, + 1582, 525, 1590, 1605, 525, 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, + 525, 1593, 1605, 525, 1594, 1580, 525, 1594, 1605, 525, 1601, 1580, 525, + 1601, 1581, 525, 1601, 1582, 525, 1601, 1605, 525, 1602, 1581, 525, 1602, + 1605, 525, 1603, 1580, 525, 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, + 525, 1603, 1605, 525, 1604, 1580, 525, 1604, 1581, 525, 1604, 1582, 525, + 1604, 1605, 525, 1604, 1607, 525, 1605, 1580, 525, 1605, 1581, 525, 1605, + 1582, 525, 1605, 1605, 525, 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, + 525, 1606, 1605, 525, 1606, 1607, 525, 1607, 1580, 525, 1607, 1605, 525, + 1607, 1648, 525, 1610, 1580, 525, 1610, 1581, 525, 1610, 1582, 525, 1610, + 1605, 525, 1610, 1607, 526, 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, + 526, 1576, 1607, 526, 1578, 1605, 526, 1578, 1607, 526, 1579, 1605, 526, + 1579, 1607, 526, 1587, 1605, 526, 1587, 1607, 526, 1588, 1605, 526, 1588, + 1607, 526, 1603, 1604, 526, 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, + 526, 1606, 1607, 526, 1610, 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, + 782, 1600, 1615, 1617, 782, 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, + 1610, 523, 1593, 1609, 523, 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, + 523, 1587, 1609, 523, 1587, 1610, 523, 1588, 1609, 523, 1588, 1610, 523, + 1581, 1609, 523, 1581, 1610, 523, 1580, 1609, 523, 1580, 1610, 523, 1582, + 1609, 523, 1582, 1610, 523, 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, + 523, 1590, 1610, 523, 1588, 1580, 523, 1588, 1581, 523, 1588, 1582, 523, + 1588, 1605, 523, 1588, 1585, 523, 1587, 1585, 523, 1589, 1585, 523, 1590, + 1585, 524, 1591, 1609, 524, 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, + 524, 1594, 1609, 524, 1594, 1610, 524, 1587, 1609, 524, 1587, 1610, 524, + 1588, 1609, 524, 1588, 1610, 524, 1581, 1609, 524, 1581, 1610, 524, 1580, + 1609, 524, 1580, 1610, 524, 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, + 524, 1589, 1610, 524, 1590, 1609, 524, 1590, 1610, 524, 1588, 1580, 524, + 1588, 1581, 524, 1588, 1582, 524, 1588, 1605, 524, 1588, 1585, 524, 1587, + 1585, 524, 1589, 1585, 524, 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, + 525, 1588, 1582, 525, 1588, 1605, 525, 1587, 1607, 525, 1588, 1607, 525, + 1591, 1605, 526, 1587, 1580, 526, 1587, 1581, 526, 1587, 1582, 526, 1588, + 1580, 526, 1588, 1581, 526, 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, + 524, 1575, 1611, 523, 1575, 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, + 1580, 781, 1578, 1581, 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, + 1605, 781, 1578, 1605, 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, + 1582, 780, 1580, 1605, 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, + 1610, 780, 1581, 1605, 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, + 1581, 780, 1587, 1580, 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, + 1581, 781, 1587, 1605, 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, + 1605, 780, 1589, 1581, 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, + 1605, 780, 1588, 1581, 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, + 1610, 780, 1588, 1605, 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, + 1605, 781, 1588, 1605, 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, + 1605, 781, 1590, 1582, 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, + 1581, 781, 1591, 1605, 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, + 1605, 780, 1593, 1605, 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, + 1609, 780, 1594, 1605, 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, + 1609, 780, 1601, 1582, 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, + 1581, 780, 1602, 1605, 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, + 1610, 780, 1604, 1581, 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, + 1580, 780, 1604, 1582, 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, + 1581, 781, 1604, 1605, 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, + 1605, 780, 1605, 1581, 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, + 1605, 781, 1605, 1582, 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, + 1582, 781, 1607, 1605, 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, + 1605, 780, 1606, 1581, 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, + 1605, 780, 1606, 1580, 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, + 1609, 780, 1610, 1605, 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, + 1610, 780, 1578, 1580, 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, + 1610, 780, 1578, 1582, 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, + 1609, 780, 1580, 1605, 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, + 1609, 780, 1587, 1582, 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, + 1610, 780, 1590, 1581, 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, + 1610, 780, 1610, 1581, 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, + 1610, 780, 1605, 1605, 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, + 1610, 781, 1602, 1605, 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, + 1610, 780, 1603, 1605, 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, + 1610, 781, 1604, 1580, 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, + 1605, 780, 1606, 1580, 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, + 1610, 780, 1605, 1580, 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, + 1610, 781, 1603, 1605, 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, + 1605, 780, 1587, 1582, 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, + 1746, 779, 1602, 1604, 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, + 1603, 1576, 1585, 1035, 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, + 1605, 1035, 1585, 1587, 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, + 1608, 1587, 1604, 1605, 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, + 32, 1575, 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, + 1604, 1605, 2059, 1580, 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, + 1585, 1740, 1575, 1604, 265, 44, 265, 12289, 265, 12290, 265, 58, 265, + 59, 265, 33, 265, 63, 265, 12310, 265, 12311, 265, 8230, 265, 8229, 265, + 8212, 265, 8211, 265, 95, 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, + 265, 12308, 265, 12309, 265, 12304, 265, 12305, 265, 12298, 265, 12299, + 265, 12296, 265, 12297, 265, 12300, 265, 12301, 265, 12302, 265, 12303, + 265, 91, 265, 93, 258, 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, + 258, 95, 258, 95, 271, 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, + 63, 271, 33, 271, 8212, 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, + 271, 12309, 271, 35, 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, + 62, 271, 61, 271, 92, 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, + 1600, 1611, 523, 32, 1612, 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, + 523, 32, 1615, 526, 1600, 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, + 1617, 526, 1600, 1617, 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, + 1570, 268, 1570, 267, 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, + 268, 1573, 267, 1574, 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, + 1575, 267, 1576, 268, 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, + 267, 1578, 268, 1578, 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, + 1579, 270, 1579, 267, 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, + 268, 1581, 269, 1581, 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, + 1582, 267, 1583, 268, 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, + 267, 1586, 268, 1586, 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, + 1588, 268, 1588, 269, 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, + 270, 1589, 267, 1590, 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, + 1591, 269, 1591, 270, 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, + 267, 1593, 268, 1593, 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, + 1594, 270, 1594, 267, 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, + 268, 1602, 269, 1602, 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, + 1603, 267, 1604, 268, 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, + 269, 1605, 270, 1605, 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, + 1607, 268, 1607, 269, 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, + 268, 1609, 267, 1610, 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, + 524, 1604, 1570, 523, 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, + 1604, 1573, 523, 1604, 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, + 264, 36, 264, 37, 264, 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, + 264, 44, 264, 45, 264, 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, + 264, 52, 264, 53, 264, 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, + 264, 60, 264, 61, 264, 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, + 264, 68, 264, 69, 264, 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, + 264, 76, 264, 77, 264, 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, + 264, 84, 264, 85, 264, 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, + 264, 92, 264, 93, 264, 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, + 264, 100, 264, 101, 264, 102, 264, 103, 264, 104, 264, 105, 264, 106, + 264, 107, 264, 108, 264, 109, 264, 110, 264, 111, 264, 112, 264, 113, + 264, 114, 264, 115, 264, 116, 264, 117, 264, 118, 264, 119, 264, 120, + 264, 121, 264, 122, 264, 123, 264, 124, 264, 125, 264, 126, 264, 10629, + 264, 10630, 272, 12290, 272, 12300, 272, 12301, 272, 12289, 272, 12539, + 272, 12530, 272, 12449, 272, 12451, 272, 12453, 272, 12455, 272, 12457, + 272, 12515, 272, 12517, 272, 12519, 272, 12483, 272, 12540, 272, 12450, + 272, 12452, 272, 12454, 272, 12456, 272, 12458, 272, 12459, 272, 12461, + 272, 12463, 272, 12465, 272, 12467, 272, 12469, 272, 12471, 272, 12473, + 272, 12475, 272, 12477, 272, 12479, 272, 12481, 272, 12484, 272, 12486, + 272, 12488, 272, 12490, 272, 12491, 272, 12492, 272, 12493, 272, 12494, + 272, 12495, 272, 12498, 272, 12501, 272, 12504, 272, 12507, 272, 12510, + 272, 12511, 272, 12512, 272, 12513, 272, 12514, 272, 12516, 272, 12518, + 272, 12520, 272, 12521, 272, 12522, 272, 12523, 272, 12524, 272, 12525, + 272, 12527, 272, 12531, 272, 12441, 272, 12442, 272, 12644, 272, 12593, + 272, 12594, 272, 12595, 272, 12596, 272, 12597, 272, 12598, 272, 12599, + 272, 12600, 272, 12601, 272, 12602, 272, 12603, 272, 12604, 272, 12605, + 272, 12606, 272, 12607, 272, 12608, 272, 12609, 272, 12610, 272, 12611, + 272, 12612, 272, 12613, 272, 12614, 272, 12615, 272, 12616, 272, 12617, + 272, 12618, 272, 12619, 272, 12620, 272, 12621, 272, 12622, 272, 12623, + 272, 12624, 272, 12625, 272, 12626, 272, 12627, 272, 12628, 272, 12629, + 272, 12630, 272, 12631, 272, 12632, 272, 12633, 272, 12634, 272, 12635, + 272, 12636, 272, 12637, 272, 12638, 272, 12639, 272, 12640, 272, 12641, + 272, 12642, 272, 12643, 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, + 264, 165, 264, 8361, 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, + 8595, 272, 9632, 272, 9675, 512, 69785, 69818, 512, 69787, 69818, 512, + 69797, 69818, 512, 69937, 69927, 512, 69938, 69927, 512, 70471, 70462, + 512, 70471, 70487, 512, 70841, 70842, 512, 70841, 70832, 512, 70841, + 70845, 512, 71096, 71087, 512, 71097, 71087, 512, 119127, 119141, 512, + 119128, 119141, 512, 119135, 119150, 512, 119135, 119151, 512, 119135, + 119152, 512, 119135, 119153, 512, 119135, 119154, 512, 119225, 119141, + 512, 119226, 119141, 512, 119227, 119150, 512, 119228, 119150, 512, + 119227, 119151, 512, 119228, 119151, 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, 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, 67, 262, 68, 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, + 262, 80, 262, 81, 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, 102, 262, + 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 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, 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, 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, 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, + 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, + 305, 262, 567, 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, 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, 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, 988, 262, 989, 262, + 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, + 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, + 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, + 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, + 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, + 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, + 56, 262, 57, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, + 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1604, 262, 1605, + 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, + 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, + 262, 1592, 262, 1594, 262, 1646, 262, 1722, 262, 1697, 262, 1647, 262, + 1576, 262, 1580, 262, 1607, 262, 1581, 262, 1610, 262, 1603, 262, 1604, + 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, + 1602, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1594, + 262, 1580, 262, 1581, 262, 1610, 262, 1604, 262, 1606, 262, 1587, 262, + 1593, 262, 1589, 262, 1602, 262, 1588, 262, 1582, 262, 1590, 262, 1594, + 262, 1722, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 262, + 1591, 262, 1610, 262, 1603, 262, 1605, 262, 1606, 262, 1587, 262, 1593, + 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 262, + 1582, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1697, 262, 1575, + 262, 1576, 262, 1580, 262, 1583, 262, 1607, 262, 1608, 262, 1586, 262, + 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, + 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, + 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, + 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, + 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, + 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, + 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 514, 48, 46, + 514, 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, + 44, 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, + 770, 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, + 40, 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, + 74, 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, + 41, 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, + 770, 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, + 40, 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, + 12308, 83, 12309, 263, 67, 263, 82, 519, 67, 68, 519, 87, 90, 266, 65, + 266, 66, 266, 67, 266, 68, 266, 69, 266, 70, 266, 71, 266, 72, 266, 73, + 266, 74, 266, 75, 266, 76, 266, 77, 266, 78, 266, 79, 266, 80, 266, 81, + 266, 82, 266, 83, 266, 84, 266, 85, 266, 86, 266, 87, 266, 88, 266, 89, + 266, 90, 522, 72, 86, 522, 77, 86, 522, 83, 68, 522, 83, 83, 778, 80, 80, + 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 515, 77, 82, 522, 68, 74, 522, + 12411, 12363, 522, 12467, 12467, 266, 12469, 266, 25163, 266, 23383, 266, + 21452, 266, 12487, 266, 20108, 266, 22810, 266, 35299, 266, 22825, 266, + 20132, 266, 26144, 266, 28961, 266, 26009, 266, 21069, 266, 24460, 266, + 20877, 266, 26032, 266, 21021, 266, 32066, 266, 29983, 266, 36009, 266, + 22768, 266, 21561, 266, 28436, 266, 25237, 266, 25429, 266, 19968, 266, + 19977, 266, 36938, 266, 24038, 266, 20013, 266, 21491, 266, 25351, 266, + 36208, 266, 25171, 266, 31105, 266, 31354, 266, 21512, 266, 28288, 266, + 26377, 266, 26376, 266, 30003, 266, 21106, 266, 21942, 266, 37197, 770, + 12308, 26412, 12309, 770, 12308, 19977, 12309, 770, 12308, 20108, 12309, + 770, 12308, 23433, 12309, 770, 12308, 28857, 12309, 770, 12308, 25171, + 12309, 770, 12308, 30423, 12309, 770, 12308, 21213, 12309, 770, 12308, + 25943, 12309, 263, 24471, 263, 21487, 256, 20029, 256, 20024, 256, 20033, + 256, 131362, 256, 20320, 256, 20398, 256, 20411, 256, 20482, 256, 20602, + 256, 20633, 256, 20711, 256, 20687, 256, 13470, 256, 132666, 256, 20813, + 256, 20820, 256, 20836, 256, 20855, 256, 132380, 256, 13497, 256, 20839, + 256, 20877, 256, 132427, 256, 20887, 256, 20900, 256, 20172, 256, 20908, + 256, 20917, 256, 168415, 256, 20981, 256, 20995, 256, 13535, 256, 21051, + 256, 21062, 256, 21106, 256, 21111, 256, 13589, 256, 21191, 256, 21193, + 256, 21220, 256, 21242, 256, 21253, 256, 21254, 256, 21271, 256, 21321, + 256, 21329, 256, 21338, 256, 21363, 256, 21373, 256, 21375, 256, 21375, + 256, 21375, 256, 133676, 256, 28784, 256, 21450, 256, 21471, 256, 133987, + 256, 21483, 256, 21489, 256, 21510, 256, 21662, 256, 21560, 256, 21576, + 256, 21608, 256, 21666, 256, 21750, 256, 21776, 256, 21843, 256, 21859, + 256, 21892, 256, 21892, 256, 21913, 256, 21931, 256, 21939, 256, 21954, + 256, 22294, 256, 22022, 256, 22295, 256, 22097, 256, 22132, 256, 20999, + 256, 22766, 256, 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, + 256, 22577, 256, 22700, 256, 136420, 256, 22770, 256, 22775, 256, 22790, + 256, 22810, 256, 22818, 256, 22882, 256, 136872, 256, 136938, 256, 23020, + 256, 23067, 256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, + 256, 23304, 256, 23358, 256, 23358, 256, 137672, 256, 23491, 256, 23512, + 256, 23527, 256, 23539, 256, 138008, 256, 23551, 256, 23558, 256, 24403, + 256, 23586, 256, 14209, 256, 23648, 256, 23662, 256, 23744, 256, 23693, + 256, 138724, 256, 23875, 256, 138726, 256, 23918, 256, 23915, 256, 23932, + 256, 24033, 256, 24034, 256, 14383, 256, 24061, 256, 24104, 256, 24125, + 256, 24169, 256, 14434, 256, 139651, 256, 14460, 256, 24240, 256, 24243, + 256, 24246, 256, 24266, 256, 172946, 256, 24318, 256, 140081, 256, + 140081, 256, 33281, 256, 24354, 256, 24354, 256, 14535, 256, 144056, 256, + 156122, 256, 24418, 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, + 24535, 256, 24569, 256, 24705, 256, 14650, 256, 14620, 256, 24724, 256, + 141012, 256, 24775, 256, 24904, 256, 24908, 256, 24910, 256, 24908, 256, + 24954, 256, 24974, 256, 25010, 256, 24996, 256, 25007, 256, 25054, 256, + 25074, 256, 25078, 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, + 25300, 256, 25424, 256, 142092, 256, 25405, 256, 25340, 256, 25448, 256, + 25475, 256, 25572, 256, 142321, 256, 25634, 256, 25541, 256, 25513, 256, + 14894, 256, 25705, 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, + 25935, 256, 25964, 256, 143370, 256, 26083, 256, 26360, 256, 26185, 256, + 15129, 256, 26257, 256, 15112, 256, 15076, 256, 20882, 256, 20885, 256, + 26368, 256, 26268, 256, 32941, 256, 17369, 256, 26391, 256, 26395, 256, + 26401, 256, 26462, 256, 26451, 256, 144323, 256, 15177, 256, 26618, 256, + 26501, 256, 26706, 256, 26757, 256, 144493, 256, 26766, 256, 26655, 256, + 26900, 256, 15261, 256, 26946, 256, 27043, 256, 27114, 256, 27304, 256, + 145059, 256, 27355, 256, 15384, 256, 27425, 256, 145575, 256, 27476, 256, + 15438, 256, 27506, 256, 27551, 256, 27578, 256, 27579, 256, 146061, 256, + 138507, 256, 146170, 256, 27726, 256, 146620, 256, 27839, 256, 27853, + 256, 27751, 256, 27926, 256, 27966, 256, 28023, 256, 27969, 256, 28009, + 256, 28024, 256, 28037, 256, 146718, 256, 27956, 256, 28207, 256, 28270, + 256, 15667, 256, 28363, 256, 28359, 256, 147153, 256, 28153, 256, 28526, + 256, 147294, 256, 147342, 256, 28614, 256, 28729, 256, 28702, 256, 28699, + 256, 15766, 256, 28746, 256, 28797, 256, 28791, 256, 28845, 256, 132389, + 256, 28997, 256, 148067, 256, 29084, 256, 148395, 256, 29224, 256, 29237, + 256, 29264, 256, 149000, 256, 29312, 256, 29333, 256, 149301, 256, + 149524, 256, 29562, 256, 29579, 256, 16044, 256, 29605, 256, 16056, 256, + 16056, 256, 29767, 256, 29788, 256, 29809, 256, 29829, 256, 29898, 256, + 16155, 256, 29988, 256, 150582, 256, 30014, 256, 150674, 256, 30064, 256, + 139679, 256, 30224, 256, 151457, 256, 151480, 256, 151620, 256, 16380, + 256, 16392, 256, 30452, 256, 151795, 256, 151794, 256, 151833, 256, + 151859, 256, 30494, 256, 30495, 256, 30495, 256, 30538, 256, 16441, 256, + 30603, 256, 16454, 256, 16534, 256, 152605, 256, 30798, 256, 30860, 256, + 30924, 256, 16611, 256, 153126, 256, 31062, 256, 153242, 256, 153285, + 256, 31119, 256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, 31311, + 256, 153980, 256, 154279, 256, 154279, 256, 31470, 256, 16898, 256, + 154539, 256, 31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, 256, + 17056, 256, 31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, 256, + 17153, 256, 32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, 256, + 156231, 256, 17241, 256, 156377, 256, 32634, 256, 156478, 256, 32661, + 256, 32762, 256, 32773, 256, 156890, 256, 156963, 256, 32864, 256, + 157096, 256, 32880, 256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, + 17419, 256, 33086, 256, 23221, 256, 157607, 256, 157621, 256, 144275, + 256, 144284, 256, 33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, + 256, 33419, 256, 33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, + 256, 33510, 256, 158524, 256, 33509, 256, 33565, 256, 33635, 256, 33709, + 256, 33571, 256, 33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, + 256, 33740, 256, 33756, 256, 158774, 256, 159083, 256, 158933, 256, + 17707, 256, 34033, 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, + 159532, 256, 17757, 256, 17761, 256, 159665, 256, 159954, 256, 17771, + 256, 34384, 256, 34396, 256, 34407, 256, 34409, 256, 34473, 256, 34440, + 256, 34574, 256, 34530, 256, 34681, 256, 34600, 256, 34667, 256, 34694, + 256, 17879, 256, 34785, 256, 34817, 256, 17913, 256, 34912, 256, 34915, + 256, 161383, 256, 35031, 256, 35038, 256, 17973, 256, 35066, 256, 13499, + 256, 161966, 256, 162150, 256, 18110, 256, 18119, 256, 35488, 256, 35565, + 256, 35722, 256, 35925, 256, 162984, 256, 36011, 256, 36033, 256, 36123, + 256, 36215, 256, 163631, 256, 133124, 256, 36299, 256, 36284, 256, 36336, + 256, 133342, 256, 36564, 256, 36664, 256, 165330, 256, 165357, 256, + 37012, 256, 37105, 256, 37137, 256, 165678, 256, 37147, 256, 37432, 256, + 37591, 256, 37592, 256, 37500, 256, 37881, 256, 37909, 256, 166906, 256, + 38283, 256, 18837, 256, 38327, 256, 167287, 256, 18918, 256, 38595, 256, + 23986, 256, 38691, 256, 168261, 256, 168474, 256, 19054, 256, 19062, 256, + 38880, 256, 168970, 256, 19122, 256, 169110, 256, 38923, 256, 38923, 256, + 38953, 256, 169398, 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, + 39362, 256, 39422, 256, 19406, 256, 170800, 256, 39698, 256, 40000, 256, + 40189, 256, 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 +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, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 0, 0, 0, 0, 84, 85, + 86, 87, 88, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 92, 93, 0, 0, 0, 0, 94, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 98, 99, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6667, 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, 0, 0, 7207, + 0, 7209, 0, 0, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, + 7229, 0, 7231, 0, 7233, 0, 0, 7235, 7237, 0, 0, 0, 7239, 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, 0, 0, 7375, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7587, + 7590, 7593, 7596, 7600, 7604, 7607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7610, 7613, 7616, 7619, 7622, 0, 0, 0, 0, 0, 7625, 0, 7628, 7631, 7633, + 7635, 7637, 7639, 7641, 7643, 7645, 7647, 7649, 7651, 7654, 7657, 7660, + 7663, 7666, 7669, 7672, 7675, 7678, 7681, 7684, 7687, 0, 7690, 7693, + 7696, 7699, 7702, 0, 7705, 0, 7708, 7711, 0, 7714, 7717, 0, 7720, 7723, + 7726, 7729, 7732, 7735, 7738, 7741, 7744, 7747, 7750, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7946, 7948, 7950, 7952, 7954, 7956, 7958, 7960, 7962, + 7964, 7966, 7968, 7970, 7972, 7974, 7976, 7978, 7980, 7982, 7984, 7986, + 7988, 7990, 7992, 7995, 7998, 8001, 8004, 8007, 8010, 8013, 8016, 8019, + 8022, 8025, 8028, 8031, 8034, 8037, 8040, 8043, 8046, 8048, 8050, 8052, + 8054, 8057, 8060, 8063, 8066, 8069, 8072, 8075, 8078, 8081, 8084, 8087, + 8090, 8093, 8096, 8099, 8102, 8105, 8108, 8111, 8114, 8117, 8120, 8123, + 8126, 8129, 8132, 8135, 8138, 8141, 8144, 8147, 8150, 8153, 8156, 8159, + 8162, 8165, 8168, 8171, 8174, 8177, 8180, 8183, 8186, 8189, 8192, 8195, + 8198, 8201, 8204, 8207, 8210, 8213, 8216, 8219, 8222, 8225, 8228, 8231, + 8234, 8237, 8240, 8243, 8246, 8249, 8252, 8255, 8258, 8261, 8264, 8267, + 8270, 8273, 8276, 8279, 8282, 8285, 8288, 8291, 8294, 8297, 8300, 8303, + 8306, 8309, 8312, 8315, 8318, 8321, 8324, 8327, 8330, 8333, 8336, 8340, + 8344, 8348, 8352, 8356, 8360, 8363, 8366, 8369, 8372, 8375, 8378, 8381, + 8384, 8387, 8390, 8393, 8396, 8399, 8402, 8405, 8408, 8411, 8414, 8417, + 8420, 8423, 8426, 8429, 8432, 8435, 8438, 8441, 8444, 8447, 8450, 8453, + 8456, 8459, 8462, 8465, 8468, 8471, 8474, 8477, 8480, 8483, 8486, 8489, + 8492, 8495, 8498, 8501, 8504, 8507, 8510, 8513, 8516, 8519, 8522, 8525, + 8528, 8531, 8534, 8537, 8540, 8543, 8546, 8549, 8552, 8555, 8558, 8561, + 8564, 8567, 8570, 8573, 8576, 8579, 8582, 8585, 8588, 8591, 8594, 8597, + 8600, 8603, 8606, 8609, 8612, 8615, 8618, 8621, 8624, 8627, 8630, 8633, + 8636, 8639, 8642, 8645, 8648, 8651, 8654, 8657, 8660, 8663, 8666, 8669, + 8672, 8675, 8678, 8681, 8684, 8687, 8690, 8693, 8696, 8699, 8702, 8705, + 8708, 8711, 8714, 8717, 8720, 8723, 8726, 8729, 8732, 8735, 8738, 8741, + 8744, 8747, 8750, 8753, 8756, 8759, 8762, 8765, 8768, 8771, 8774, 8777, + 8780, 8783, 8786, 8790, 8794, 8798, 8801, 8804, 8807, 8810, 8813, 8816, + 8819, 8822, 8825, 8828, 8831, 8834, 8837, 8840, 8843, 8846, 8849, 8852, + 8855, 8858, 8861, 8864, 8867, 8870, 8873, 8876, 8879, 8882, 8885, 8888, + 8891, 8894, 8897, 8900, 8903, 8906, 8909, 8912, 8915, 8918, 8921, 8924, + 8927, 8930, 8933, 8936, 8939, 8942, 8945, 8948, 8951, 8954, 8957, 8960, + 8963, 8966, 8969, 8972, 8975, 8978, 8981, 8984, 8987, 8990, 8993, 8996, + 8999, 9002, 9005, 9008, 9011, 9014, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9017, 9021, 9025, 9029, 9033, 9037, 9041, 9045, 9049, + 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097, + 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145, + 9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193, + 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241, + 9245, 9249, 9253, 9257, 9261, 9265, 9269, 0, 0, 9273, 9277, 9281, 9285, + 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333, + 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381, + 9385, 9389, 9393, 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, + 9433, 9437, 9441, 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, + 9481, 9485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9489, 9493, + 9497, 9502, 9507, 9512, 9517, 9522, 9527, 9532, 9536, 9555, 9564, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9569, 9571, 9573, + 9575, 9577, 9579, 9581, 9583, 9585, 9587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9589, 9591, 9593, 9595, 9597, 9599, + 9601, 9603, 9605, 9607, 9609, 9611, 9613, 9615, 9617, 9619, 9621, 9623, + 9625, 9627, 9629, 0, 0, 9631, 9633, 9635, 9637, 9639, 9641, 9643, 9645, + 9647, 9649, 9651, 9653, 0, 9655, 9657, 9659, 9661, 9663, 9665, 9667, + 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, + 0, 9693, 9695, 9697, 9699, 0, 0, 0, 0, 9701, 9704, 9707, 0, 9710, 0, + 9713, 9716, 9719, 9722, 9725, 9728, 9731, 9734, 9737, 9740, 9743, 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, 9980, 9983, 9986, 9989, + 9992, 9995, 9998, 0, 0, 0, 0, 10001, 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, 0, 0, 0, 10381, 10383, 10385, 10387, 10389, + 10391, 0, 0, 10393, 10395, 10397, 10399, 10401, 10403, 0, 0, 10405, + 10407, 10409, 10411, 10413, 10415, 0, 0, 10417, 10419, 10421, 0, 0, 0, + 10423, 10425, 10427, 10429, 10431, 10433, 10435, 0, 10437, 10439, 10441, + 10443, 10445, 10447, 10449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10451, 0, 10454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10460, 10463, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10466, 10469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10472, + 10475, 0, 10478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10481, 10484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10487, 10490, 10493, 10496, 10499, 10502, 10505, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10508, 10511, 10514, 10517, 10520, + 10523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10526, 10528, 10530, + 10532, 10534, 10536, 10538, 10540, 10542, 10544, 10546, 10548, 10550, + 10552, 10554, 10556, 10558, 10560, 10562, 10564, 10566, 10568, 10570, + 10572, 10574, 10576, 10578, 10580, 10582, 10584, 10586, 10588, 10590, + 10592, 10594, 10596, 10598, 10600, 10602, 10604, 10606, 10608, 10610, + 10612, 10614, 10616, 10618, 10620, 10622, 10624, 10626, 10628, 10630, + 10632, 10634, 10636, 10638, 10640, 10642, 10644, 10646, 10648, 10650, + 10652, 10654, 10656, 10658, 10660, 10662, 10664, 10666, 10668, 10670, + 10672, 10674, 10676, 10678, 10680, 10682, 10684, 10686, 10688, 10690, + 10692, 10694, 0, 10696, 10698, 10700, 10702, 10704, 10706, 10708, 10710, + 10712, 10714, 10716, 10718, 10720, 10722, 10724, 10726, 10728, 10730, + 10732, 10734, 10736, 10738, 10740, 10742, 10744, 10746, 10748, 10750, + 10752, 10754, 10756, 10758, 10760, 10762, 10764, 10766, 10768, 10770, + 10772, 10774, 10776, 10778, 10780, 10782, 10784, 10786, 10788, 10790, + 10792, 10794, 10796, 10798, 10800, 10802, 10804, 10806, 10808, 10810, + 10812, 10814, 10816, 10818, 10820, 10822, 10824, 10826, 10828, 10830, + 10832, 10834, 10836, 0, 10838, 10840, 0, 0, 10842, 0, 0, 10844, 10846, 0, + 0, 10848, 10850, 10852, 10854, 0, 10856, 10858, 10860, 10862, 10864, + 10866, 10868, 10870, 10872, 10874, 10876, 10878, 0, 10880, 0, 10882, + 10884, 10886, 10888, 10890, 10892, 10894, 0, 10896, 10898, 10900, 10902, + 10904, 10906, 10908, 10910, 10912, 10914, 10916, 10918, 10920, 10922, + 10924, 10926, 10928, 10930, 10932, 10934, 10936, 10938, 10940, 10942, + 10944, 10946, 10948, 10950, 10952, 10954, 10956, 10958, 10960, 10962, + 10964, 10966, 10968, 10970, 10972, 10974, 10976, 10978, 10980, 10982, + 10984, 10986, 10988, 10990, 10992, 10994, 10996, 10998, 11000, 11002, + 11004, 11006, 11008, 11010, 11012, 11014, 11016, 11018, 11020, 11022, + 11024, 0, 11026, 11028, 11030, 11032, 0, 0, 11034, 11036, 11038, 11040, + 11042, 11044, 11046, 11048, 0, 11050, 11052, 11054, 11056, 11058, 11060, + 11062, 0, 11064, 11066, 11068, 11070, 11072, 11074, 11076, 11078, 11080, + 11082, 11084, 11086, 11088, 11090, 11092, 11094, 11096, 11098, 11100, + 11102, 11104, 11106, 11108, 11110, 11112, 11114, 11116, 11118, 0, 11120, + 11122, 11124, 11126, 0, 11128, 11130, 11132, 11134, 11136, 0, 11138, 0, + 0, 0, 11140, 11142, 11144, 11146, 11148, 11150, 11152, 0, 11154, 11156, + 11158, 11160, 11162, 11164, 11166, 11168, 11170, 11172, 11174, 11176, + 11178, 11180, 11182, 11184, 11186, 11188, 11190, 11192, 11194, 11196, + 11198, 11200, 11202, 11204, 11206, 11208, 11210, 11212, 11214, 11216, + 11218, 11220, 11222, 11224, 11226, 11228, 11230, 11232, 11234, 11236, + 11238, 11240, 11242, 11244, 11246, 11248, 11250, 11252, 11254, 11256, + 11258, 11260, 11262, 11264, 11266, 11268, 11270, 11272, 11274, 11276, + 11278, 11280, 11282, 11284, 11286, 11288, 11290, 11292, 11294, 11296, + 11298, 11300, 11302, 11304, 11306, 11308, 11310, 11312, 11314, 11316, + 11318, 11320, 11322, 11324, 11326, 11328, 11330, 11332, 11334, 11336, + 11338, 11340, 11342, 11344, 11346, 11348, 11350, 11352, 11354, 11356, + 11358, 11360, 11362, 11364, 11366, 11368, 11370, 11372, 11374, 11376, + 11378, 11380, 11382, 11384, 11386, 11388, 11390, 11392, 11394, 11396, + 11398, 11400, 11402, 11404, 11406, 11408, 11410, 11412, 11414, 11416, + 11418, 11420, 11422, 11424, 11426, 11428, 11430, 11432, 11434, 11436, + 11438, 11440, 11442, 11444, 11446, 11448, 11450, 11452, 11454, 11456, + 11458, 11460, 11462, 11464, 11466, 11468, 11470, 11472, 11474, 11476, + 11478, 11480, 11482, 11484, 11486, 11488, 11490, 11492, 11494, 11496, + 11498, 11500, 11502, 11504, 11506, 11508, 11510, 11512, 11514, 11516, + 11518, 11520, 11522, 11524, 11526, 11528, 11530, 11532, 11534, 11536, + 11538, 11540, 11542, 11544, 11546, 11548, 11550, 11552, 11554, 11556, + 11558, 11560, 11562, 11564, 11566, 11568, 11570, 11572, 11574, 11576, + 11578, 11580, 11582, 11584, 11586, 11588, 11590, 11592, 11594, 11596, + 11598, 11600, 11602, 11604, 11606, 11608, 11610, 11612, 11614, 11616, + 11618, 11620, 11622, 11624, 11626, 11628, 11630, 11632, 11634, 11636, + 11638, 11640, 11642, 11644, 11646, 11648, 11650, 11652, 11654, 11656, + 11658, 11660, 11662, 11664, 11666, 11668, 11670, 11672, 11674, 11676, + 11678, 11680, 11682, 11684, 11686, 11688, 11690, 11692, 11694, 11696, + 11698, 11700, 11702, 11704, 11706, 11708, 11710, 11712, 11714, 11716, + 11718, 11720, 11722, 11724, 11726, 11728, 11730, 11732, 11734, 11736, + 11738, 11740, 11742, 11744, 11746, 11748, 11750, 11752, 11754, 11756, + 11758, 11760, 11762, 11764, 11766, 11768, 11770, 11772, 11774, 11776, + 11778, 11780, 11782, 11784, 11786, 11788, 11790, 11792, 11794, 11796, + 11798, 11800, 11802, 11804, 11806, 11808, 11810, 11812, 11814, 11816, + 11818, 11820, 11822, 11824, 11826, 11828, 11830, 11832, 0, 0, 11834, + 11836, 11838, 11840, 11842, 11844, 11846, 11848, 11850, 11852, 11854, + 11856, 11858, 11860, 11862, 11864, 11866, 11868, 11870, 11872, 11874, + 11876, 11878, 11880, 11882, 11884, 11886, 11888, 11890, 11892, 11894, + 11896, 11898, 11900, 11902, 11904, 11906, 11908, 11910, 11912, 11914, + 11916, 11918, 11920, 11922, 11924, 11926, 11928, 11930, 11932, 11934, + 11936, 11938, 11940, 11942, 11944, 11946, 11948, 11950, 11952, 11954, + 11956, 11958, 11960, 11962, 11964, 11966, 11968, 11970, 11972, 11974, + 11976, 11978, 11980, 11982, 11984, 11986, 11988, 11990, 11992, 11994, + 11996, 11998, 12000, 12002, 12004, 12006, 12008, 12010, 12012, 12014, + 12016, 12018, 12020, 12022, 12024, 12026, 12028, 12030, 12032, 12034, + 12036, 12038, 12040, 12042, 12044, 12046, 12048, 12050, 12052, 12054, + 12056, 12058, 12060, 12062, 12064, 12066, 12068, 12070, 12072, 12074, + 12076, 12078, 12080, 12082, 12084, 12086, 12088, 12090, 12092, 12094, + 12096, 12098, 12100, 12102, 12104, 12106, 12108, 12110, 12112, 12114, + 12116, 12118, 12120, 12122, 12124, 12126, 12128, 12130, 12132, 12134, + 12136, 12138, 12140, 12142, 12144, 12146, 12148, 12150, 12152, 12154, + 12156, 12158, 12160, 12162, 12164, 12166, 12168, 12170, 12172, 12174, + 12176, 12178, 12180, 12182, 12184, 12186, 12188, 12190, 12192, 12194, + 12196, 12198, 12200, 12202, 12204, 12206, 12208, 12210, 12212, 12214, + 12216, 12218, 12220, 12222, 12224, 12226, 12228, 12230, 12232, 12234, + 12236, 12238, 12240, 12242, 12244, 12246, 12248, 12250, 12252, 12254, + 12256, 12258, 12260, 12262, 12264, 12266, 12268, 12270, 12272, 12274, + 12276, 12278, 12280, 12282, 12284, 12286, 12288, 12290, 12292, 12294, + 12296, 12298, 12300, 12302, 12304, 12306, 12308, 12310, 12312, 12314, + 12316, 12318, 12320, 12322, 12324, 12326, 12328, 12330, 12332, 12334, + 12336, 12338, 12340, 12342, 12344, 12346, 12348, 12350, 12352, 12354, + 12356, 12358, 12360, 12362, 12364, 12366, 12368, 12370, 12372, 12374, + 12376, 12378, 12380, 12382, 12384, 12386, 12388, 12390, 12392, 12394, + 12396, 12398, 12400, 12402, 12404, 12406, 12408, 12410, 12412, 12414, + 12416, 0, 0, 12418, 12420, 12422, 12424, 12426, 12428, 12430, 12432, + 12434, 12436, 12438, 12440, 12442, 12444, 12446, 12448, 12450, 12452, + 12454, 12456, 12458, 12460, 12462, 12464, 12466, 12468, 12470, 12472, + 12474, 12476, 12478, 12480, 12482, 12484, 12486, 12488, 12490, 12492, + 12494, 12496, 12498, 12500, 12502, 12504, 12506, 12508, 12510, 12512, + 12514, 12516, 12518, 12520, 12522, 12524, 0, 12526, 12528, 12530, 12532, + 12534, 12536, 12538, 12540, 12542, 12544, 12546, 12548, 12550, 12552, + 12554, 12556, 12558, 12560, 12562, 12564, 12566, 12568, 12570, 12572, + 12574, 12576, 12578, 0, 12580, 12582, 0, 12584, 0, 0, 12586, 0, 12588, + 12590, 12592, 12594, 12596, 12598, 12600, 12602, 12604, 12606, 0, 12608, + 12610, 12612, 12614, 0, 12616, 0, 12618, 0, 0, 0, 0, 0, 0, 12620, 0, 0, + 0, 0, 12622, 0, 12624, 0, 12626, 0, 12628, 12630, 12632, 0, 12634, 12636, + 0, 12638, 0, 0, 12640, 0, 12642, 0, 12644, 0, 12646, 0, 12648, 0, 12650, + 12652, 0, 12654, 0, 0, 12656, 12658, 12660, 12662, 0, 12664, 12666, + 12668, 12670, 12672, 12674, 12676, 0, 12678, 12680, 12682, 12684, 0, + 12686, 12688, 12690, 12692, 0, 12694, 0, 12696, 12698, 12700, 12702, + 12704, 12706, 12708, 12710, 12712, 12714, 0, 12716, 12718, 12720, 12722, + 12724, 12726, 12728, 12730, 12732, 12734, 12736, 12738, 12740, 12742, + 12744, 12746, 12748, 0, 0, 0, 0, 0, 12750, 12752, 12754, 0, 12756, 12758, + 12760, 12762, 12764, 0, 12766, 12768, 12770, 12772, 12774, 12776, 12778, + 12780, 12782, 12784, 12786, 12788, 12790, 12792, 12794, 12796, 12798, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12800, 12803, + 12806, 12809, 12812, 12815, 12818, 12821, 12824, 12827, 12830, 0, 0, 0, + 0, 0, 12833, 12837, 12841, 12845, 12849, 12853, 12857, 12861, 12865, + 12869, 12873, 12877, 12881, 12885, 12889, 12893, 12897, 12901, 12905, + 12909, 12913, 12917, 12921, 12925, 12929, 12933, 12937, 12941, 12943, + 12945, 12948, 0, 12951, 12953, 12955, 12957, 12959, 12961, 12963, 12965, + 12967, 12969, 12971, 12973, 12975, 12977, 12979, 12981, 12983, 12985, + 12987, 12989, 12991, 12993, 12995, 12997, 12999, 13001, 13003, 13006, + 13009, 13012, 13015, 13019, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13022, 13025, 13028, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 13031, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13034, + 13037, 13040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13042, 13044, 13046, + 13048, 13050, 13052, 13054, 13056, 13058, 13060, 13062, 13064, 13066, + 13068, 13070, 13072, 13074, 13076, 13078, 13080, 13082, 13084, 13086, + 13088, 13090, 13092, 13094, 13096, 13098, 13100, 13102, 13104, 13106, + 13108, 13110, 13112, 13114, 13116, 13118, 13120, 13122, 13124, 13126, + 13128, 0, 0, 0, 0, 13130, 13134, 13138, 13142, 13146, 13150, 13154, + 13158, 13162, 0, 0, 0, 0, 0, 0, 0, 13166, 13168, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13170, 13172, 13174, 13176, + 13178, 13180, 13182, 13184, 13186, 13188, 13190, 13192, 13194, 13196, + 13198, 13200, 13202, 13204, 13206, 13208, 13210, 13212, 13214, 13216, + 13218, 13220, 13222, 13224, 13226, 13228, 13230, 13232, 13234, 13236, + 13238, 13240, 13242, 13244, 13246, 13248, 13250, 13252, 13254, 13256, + 13258, 13260, 13262, 13264, 13266, 13268, 13270, 13272, 13274, 13276, + 13278, 13280, 13282, 13284, 13286, 13288, 13290, 13292, 13294, 13296, + 13298, 13300, 13302, 13304, 13306, 13308, 13310, 13312, 13314, 13316, + 13318, 13320, 13322, 13324, 13326, 13328, 13330, 13332, 13334, 13336, + 13338, 13340, 13342, 13344, 13346, 13348, 13350, 13352, 13354, 13356, + 13358, 13360, 13362, 13364, 13366, 13368, 13370, 13372, 13374, 13376, + 13378, 13380, 13382, 13384, 13386, 13388, 13390, 13392, 13394, 13396, + 13398, 13400, 13402, 13404, 13406, 13408, 13410, 13412, 13414, 13416, + 13418, 13420, 13422, 13424, 13426, 13428, 13430, 13432, 13434, 13436, + 13438, 13440, 13442, 13444, 13446, 13448, 13450, 13452, 13454, 13456, + 13458, 13460, 13462, 13464, 13466, 13468, 13470, 13472, 13474, 13476, + 13478, 13480, 13482, 13484, 13486, 13488, 13490, 13492, 13494, 13496, + 13498, 13500, 13502, 13504, 13506, 13508, 13510, 13512, 13514, 13516, + 13518, 13520, 13522, 13524, 13526, 13528, 13530, 13532, 13534, 13536, + 13538, 13540, 13542, 13544, 13546, 13548, 13550, 13552, 13554, 13556, + 13558, 13560, 13562, 13564, 13566, 13568, 13570, 13572, 13574, 13576, + 13578, 13580, 13582, 13584, 13586, 13588, 13590, 13592, 13594, 13596, + 13598, 13600, 13602, 13604, 13606, 13608, 13610, 13612, 13614, 13616, + 13618, 13620, 13622, 13624, 13626, 13628, 13630, 13632, 13634, 13636, + 13638, 13640, 13642, 13644, 13646, 13648, 13650, 13652, 13654, 13656, + 13658, 13660, 13662, 13664, 13666, 13668, 13670, 13672, 13674, 13676, + 13678, 13680, 13682, 13684, 13686, 13688, 13690, 13692, 13694, 13696, + 13698, 13700, 13702, 13704, 13706, 13708, 13710, 13712, 13714, 13716, + 13718, 13720, 13722, 13724, 13726, 13728, 13730, 13732, 13734, 13736, + 13738, 13740, 13742, 13744, 13746, 13748, 13750, 13752, 13754, 13756, + 13758, 13760, 13762, 13764, 13766, 13768, 13770, 13772, 13774, 13776, + 13778, 13780, 13782, 13784, 13786, 13788, 13790, 13792, 13794, 13796, + 13798, 13800, 13802, 13804, 13806, 13808, 13810, 13812, 13814, 13816, + 13818, 13820, 13822, 13824, 13826, 13828, 13830, 13832, 13834, 13836, + 13838, 13840, 13842, 13844, 13846, 13848, 13850, 13852, 13854, 13856, + 13858, 13860, 13862, 13864, 13866, 13868, 13870, 13872, 13874, 13876, + 13878, 13880, 13882, 13884, 13886, 13888, 13890, 13892, 13894, 13896, + 13898, 13900, 13902, 13904, 13906, 13908, 13910, 13912, 13914, 13916, + 13918, 13920, 13922, 13924, 13926, 13928, 13930, 13932, 13934, 13936, + 13938, 13940, 13942, 13944, 13946, 13948, 13950, 13952, 13954, 13956, + 13958, 13960, 13962, 13964, 13966, 13968, 13970, 13972, 13974, 13976, + 13978, 13980, 13982, 13984, 13986, 13988, 13990, 13992, 13994, 13996, + 13998, 14000, 14002, 14004, 14006, 14008, 14010, 14012, 14014, 14016, + 14018, 14020, 14022, 14024, 14026, 14028, 14030, 14032, 14034, 14036, + 14038, 14040, 14042, 14044, 14046, 14048, 14050, 14052, 14054, 14056, + 14058, 14060, 14062, 14064, 14066, 14068, 14070, 14072, 14074, 14076, + 14078, 14080, 14082, 14084, 14086, 14088, 14090, 14092, 14094, 14096, + 14098, 14100, 14102, 14104, 14106, 14108, 14110, 14112, 14114, 14116, + 14118, 14120, 14122, 14124, 14126, 14128, 14130, 14132, 14134, 14136, + 14138, 14140, 14142, 14144, 14146, 14148, 14150, 14152, 14154, 14156, + 14158, 14160, 14162, 14164, 14166, 14168, 14170, 14172, 14174, 14176, + 14178, 14180, 14182, 14184, 14186, 14188, 14190, 14192, 14194, 14196, + 14198, 14200, 14202, 14204, 14206, 14208, 14210, 14212, 14214, 14216, + 14218, 14220, 14222, 14224, 14226, 14228, 14230, 14232, 14234, 14236, + 14238, 14240, 14242, 14244, 14246, 14248, 14250, 14252, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, + 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 20, 0, 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29, + 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 33, 34, 35, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 39, 0, + 40, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 46, 47, 0, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, + 51, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 56, 0, 57, 58, 59, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 61, 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, 0, + 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 78, 79, 80, 81, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 85, + 0, 86, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 89, 90, 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, + 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, 111, 112, 113, + 114, 115, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, + 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 124, 0, 0, 125, 0, 0, 0, 0, + 0, 0, 0, 0, 126, 127, 128, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 130, 131, 132, 133, 134, 135, 0, 0, 0, 0, 0, 0, 0, 0, 136, 137, 138, 139, + 140, 141, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 144, 145, 146, 0, 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, 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, 165, 0, 166, 167, 168, 0, 0, 0, 0, 0, 0, + 0, 0, 169, 0, 0, 170, 171, 172, 173, 174, 0, 0, 0, 0, 0, 0, 0, 0, 175, + 176, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 179, 180, 181, 182, + 183, 184, 185, 0, 0, 0, 0, 0, 0, 0, 0, 186, 187, 188, 189, 190, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 194, 195, 196, 197, 198, 199, 200, 0, 0, 0, 0, 0, 0, 0, 0, 201, 202, + 203, 204, 205, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 208, 0, 209, + 210, 211, 0, 0, 0, 0, 0, 0, 0, 0, 212, 213, 214, 215, 216, 217, 218, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 221, 222, 223, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 227, 228, 0, 229, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 231, 232, 0, 233, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 235, + 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 256, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 0, + 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, + 263, 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, 266, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 269, 270, 271, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 277, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, + 0, 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, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 292, + 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, 0, 294, 0, 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, 297, 298, 299, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 301, 0, 302, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, 305, 306, 0, 307, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 309, 0, 310, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 312, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, 0, 0, + 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, 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, 319, 0, 0, 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, 321, 322, 0, 0, + 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, 0, 325, 0, 0, 326, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 327, 0, 0, 0, 328, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 330, + 331, 0, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 0, 0, 0, 334, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 336, 337, 338, 0, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 340, 0, 0, 341, + 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, + 0, 347, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 350, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 352, 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, 0, + 354, 355, 0, 356, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 358, 0, 0, 0, 359, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 361, 362, 363, 0, 364, 0, 0, 365, 0, 0, 0, 0, 0, 0, 0, 0, 366, 0, + 0, 367, 0, 0, 0, 368, 0, 0, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 0, 370, 0, + 0, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 374, 375, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 379, 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 381, 382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 384, 385, 386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 389, 390, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, 0, 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, 395, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 396, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 398, 399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 403, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 406, 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, + 409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 414, 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, 0, 417, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 419, 0, + 0, 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, 421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 424, 0, 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, + 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, 0, 431, 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, 0, 434, 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, 436, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 437, 438, 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, 441, 0, 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, 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, 445, 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, 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, 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, 453, 0, 0, 0, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 456, 0, + 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, 459, 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, 461, 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, 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, 466, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 468, 0, 0, 0, + 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 470, 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, 0, 472, 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, 475, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, 0, 0, 0, 0, 0, 477, 0, 0, + 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 480, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 486, 0, 0, + 0, 0, 0, 0, 0, 487, 0, 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, 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, 491, 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, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 496, 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, 0, 498, 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, 501, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, 0, 0, 0, 503, + 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 0, 512, 0, + 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, + 515, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, + 0, 518, 0, 0, 0, 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 520, 0, 0, 0, 0, 0, 0, 0, 0, 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, 524, 0, 0, 0, 0, 0, 0, 0, 0, 525, 0, 0, 0, 0, + 0, 0, 526, 0, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, 0, 0, 0, 528, 0, 0, 0, 0, + 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 530, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, + 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 0, 0, 539, 0, 0, 0, 0, 0, 0, 540, 0, 0, + 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 544, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 547, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 0, 553, 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, 557, 0, 0, 0, 0, 0, 0, 558, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 562, 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, 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, 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 573, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 574, 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, 0, 0, 0, 0, 0, 0, 0, 577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 581, 0, 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, 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, 585, 0, 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, + 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, 589, 0, 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, 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, + 593, 0, 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, 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, 597, 0, 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, + 599, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 620, 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, 622, 0, 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, 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, 626, 0, 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, 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, 630, 0, 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, 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, 634, 0, 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, 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, + 638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 639, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 640, 0, 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, 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, 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, 0, 648, 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, 651, 0, 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, +}; + +static const unsigned int comp_data[] = { + 0, 0, 0, 0, 0, 0, 0, 8814, 0, 8800, 0, 0, 0, 0, 0, 8815, 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, 0, 0, 0, 7682, 0, 0, 7684, 0, 0, 0, 0, 7686, 0, + 0, 0, 0, 262, 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 199, 0, + 0, 7690, 0, 0, 0, 0, 270, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 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, 7710, 0, 0, 0, 0, + 500, 284, 0, 7712, 286, 288, 0, 0, 0, 0, 486, 0, 0, 0, 0, 0, 290, 0, 0, + 292, 0, 0, 0, 7714, 7718, 0, 0, 0, 542, 0, 7716, 0, 0, 0, 7720, 0, 0, + 7722, 0, 0, 0, 0, 0, 204, 205, 206, 296, 298, 300, 304, 207, 7880, 0, 0, + 463, 520, 522, 0, 0, 0, 7882, 302, 0, 0, 7724, 0, 0, 308, 0, 0, 0, 0, + 7728, 0, 488, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 310, 7732, 0, 0, 0, 0, 313, + 0, 0, 0, 0, 0, 317, 0, 7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 0, + 0, 7742, 7744, 0, 0, 0, 0, 0, 0, 7746, 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, 210, + 211, 212, 213, 332, 334, 558, 214, 7886, 0, 336, 465, 524, 526, 0, 0, + 416, 7884, 490, 0, 0, 0, 0, 7764, 0, 0, 0, 0, 7766, 0, 0, 0, 0, 340, + 7768, 0, 0, 0, 0, 344, 528, 530, 0, 0, 0, 7770, 0, 0, 0, 342, 7774, 0, 0, + 0, 0, 346, 348, 0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 7778, 0, 0, 536, 350, + 0, 0, 7786, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, 7788, 0, 0, 538, 354, 0, + 7792, 0, 0, 7790, 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, 0, 0, 0, 7804, 0, 0, 0, 0, 0, 7806, 7808, 7810, 372, 0, 0, 0, 7814, + 7812, 0, 7816, 0, 0, 7818, 7820, 0, 0, 7922, 221, 374, 7928, 562, 0, + 7822, 376, 7926, 0, 0, 0, 0, 7924, 0, 0, 0, 0, 0, 377, 7824, 0, 0, 0, + 379, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 7826, 7828, 0, 0, 0, 224, 225, 226, + 227, 257, 259, 551, 228, 7843, 229, 0, 462, 513, 515, 0, 0, 0, 7841, 0, + 7681, 0, 0, 261, 0, 7683, 0, 0, 0, 0, 0, 0, 7685, 7687, 0, 0, 0, 0, 263, + 265, 0, 0, 0, 267, 0, 0, 0, 0, 269, 0, 231, 0, 0, 7691, 0, 0, 0, 0, 271, + 0, 0, 0, 0, 0, 7693, 0, 0, 0, 7697, 0, 7699, 0, 0, 7695, 0, 0, 0, 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, 7711, 0, 0, 0, 0, 501, 285, + 0, 7713, 287, 289, 0, 0, 0, 0, 487, 0, 291, 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, 0, 0, 0, 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, 309, 0, 0, 0, + 0, 496, 0, 0, 0, 7729, 0, 0, 0, 0, 0, 489, 0, 7731, 0, 0, 0, 311, 0, 0, + 0, 0, 7733, 0, 0, 0, 0, 314, 0, 318, 0, 0, 0, 0, 0, 7735, 0, 0, 0, 316, + 0, 7741, 0, 0, 7739, 0, 0, 0, 0, 7743, 0, 0, 0, 0, 7745, 0, 0, 7747, 0, + 0, 0, 0, 505, 324, 0, 241, 0, 0, 7749, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, + 7751, 0, 0, 0, 326, 0, 7755, 0, 0, 7753, 0, 0, 0, 242, 243, 244, 245, + 333, 335, 559, 246, 7887, 0, 337, 466, 525, 527, 0, 0, 417, 7885, 0, 0, + 0, 0, 491, 0, 0, 0, 0, 7765, 7767, 0, 0, 0, 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, + 0, 0, 0, 347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 7779, + 0, 0, 537, 351, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, 7789, 0, 0, 539, 355, + 0, 7793, 0, 0, 7791, 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, 7805, 0, 7807, 0, 0, 0, 0, 7809, 7811, 373, 0, 0, 0, 7815, + 7813, 0, 7832, 0, 0, 0, 7817, 0, 0, 7819, 7821, 0, 0, 7923, 253, 375, + 7929, 563, 0, 7823, 255, 7927, 7833, 0, 0, 0, 7925, 0, 378, 7825, 0, 0, + 0, 380, 0, 0, 0, 0, 382, 0, 7827, 0, 0, 0, 0, 7829, 0, 0, 0, 8173, 901, + 0, 0, 8129, 0, 7846, 7844, 0, 7850, 7848, 0, 0, 0, 0, 0, 478, 0, 0, 506, + 0, 0, 0, 0, 0, 508, 0, 0, 482, 0, 0, 7688, 0, 0, 0, 0, 7872, 7870, 0, + 7876, 0, 0, 0, 0, 7874, 0, 0, 7726, 0, 0, 0, 0, 7890, 7888, 0, 7894, 0, + 0, 0, 0, 7892, 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 0, 0, 554, 0, 0, 510, + 0, 0, 0, 0, 475, 471, 0, 0, 469, 0, 0, 473, 0, 0, 7847, 7845, 0, 7851, + 7849, 0, 0, 0, 0, 0, 479, 0, 0, 507, 0, 0, 0, 0, 0, 509, 0, 0, 483, 0, 0, + 7689, 0, 0, 0, 0, 7873, 7871, 0, 7877, 0, 0, 0, 0, 7875, 0, 0, 7727, 0, + 0, 0, 0, 7891, 7889, 0, 7895, 0, 0, 0, 0, 7893, 0, 0, 7757, 0, 0, 557, 0, + 0, 7759, 0, 0, 555, 0, 0, 511, 0, 0, 0, 0, 476, 472, 0, 0, 470, 0, 0, + 474, 0, 0, 7856, 7854, 0, 7860, 7858, 0, 0, 0, 0, 0, 7857, 7855, 0, 7861, + 0, 0, 0, 0, 7859, 0, 7700, 7702, 0, 0, 0, 0, 7701, 7703, 7760, 7762, 0, + 0, 0, 0, 7761, 7763, 0, 0, 7780, 0, 7781, 0, 0, 0, 0, 0, 7782, 0, 7783, + 0, 0, 0, 0, 7800, 0, 0, 0, 0, 0, 7801, 0, 0, 0, 7802, 0, 7803, 0, 0, 0, + 0, 7835, 0, 0, 0, 7900, 7898, 0, 7904, 0, 0, 0, 0, 7902, 0, 0, 0, 0, + 7906, 7901, 7899, 0, 7905, 7903, 0, 0, 0, 0, 7907, 0, 0, 0, 0, 7914, + 7912, 0, 7918, 0, 0, 0, 0, 7916, 0, 0, 0, 0, 7920, 7915, 7913, 0, 7919, + 7917, 0, 0, 0, 0, 7921, 0, 0, 0, 494, 0, 0, 492, 0, 0, 0, 0, 0, 493, 0, + 480, 0, 0, 0, 0, 0, 481, 0, 0, 7708, 0, 0, 0, 0, 0, 7709, 560, 0, 0, 0, + 0, 0, 561, 0, 0, 0, 0, 495, 0, 0, 8122, 902, 0, 0, 8121, 8120, 7944, + 7945, 0, 0, 0, 0, 0, 8124, 8136, 904, 0, 0, 0, 0, 7960, 7961, 0, 0, 8138, + 905, 7976, 7977, 0, 0, 0, 0, 0, 8140, 8154, 906, 0, 0, 8153, 8152, 0, + 938, 0, 0, 7992, 7993, 0, 0, 8184, 908, 8008, 8009, 0, 0, 0, 0, 0, 8172, + 0, 0, 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 8025, 0, 0, 8186, + 911, 0, 0, 0, 0, 8040, 8041, 0, 8188, 0, 0, 0, 0, 0, 8116, 0, 8132, 0, 0, + 0, 0, 8048, 940, 0, 0, 8113, 8112, 7936, 7937, 0, 0, 0, 0, 8118, 8115, + 8050, 941, 0, 0, 0, 0, 7952, 7953, 0, 0, 8052, 942, 7968, 7969, 0, 0, 0, + 0, 8134, 8131, 8054, 943, 0, 0, 8145, 8144, 0, 970, 0, 0, 7984, 7985, + 8150, 0, 0, 0, 0, 0, 8056, 972, 8000, 8001, 0, 0, 0, 0, 8164, 8165, 0, 0, + 8058, 973, 0, 0, 8161, 8160, 0, 971, 0, 0, 8016, 8017, 0, 0, 0, 0, 8166, + 0, 8060, 974, 0, 0, 0, 0, 8032, 8033, 8182, 8179, 0, 0, 0, 0, 8146, 912, + 0, 0, 8151, 0, 8162, 944, 0, 0, 8167, 0, 0, 0, 0, 0, 0, 8180, 0, 979, 0, + 0, 0, 0, 0, 980, 0, 1031, 0, 0, 0, 1232, 0, 1234, 0, 0, 0, 1027, 1024, 0, + 0, 0, 0, 1238, 0, 1025, 0, 0, 0, 1217, 0, 1244, 0, 0, 0, 0, 0, 1246, 0, + 0, 1037, 0, 0, 0, 1250, 1049, 0, 1252, 0, 0, 0, 1036, 0, 0, 0, 1254, 0, + 0, 1262, 1038, 0, 1264, 0, 0, 1266, 0, 0, 1268, 0, 0, 0, 0, 0, 1272, 0, + 1260, 0, 0, 0, 1233, 0, 1235, 0, 0, 0, 1107, 1104, 0, 0, 0, 0, 1239, 0, + 1105, 0, 0, 0, 1218, 0, 1245, 0, 0, 0, 0, 0, 1247, 0, 0, 1117, 0, 0, 0, + 1251, 1081, 0, 1253, 0, 0, 0, 1116, 0, 0, 0, 1255, 0, 0, 1263, 1118, 0, + 1265, 0, 0, 1267, 0, 0, 1269, 0, 0, 0, 0, 0, 1273, 0, 1261, 0, 0, 0, 0, + 0, 1111, 0, 0, 1142, 0, 1143, 0, 0, 0, 0, 1242, 0, 0, 0, 0, 0, 1243, 0, + 1258, 0, 0, 0, 0, 0, 1259, 1570, 1571, 1573, 0, 0, 0, 0, 1572, 0, 1574, + 0, 0, 0, 0, 0, 1730, 0, 1747, 0, 0, 0, 0, 0, 1728, 0, 0, 0, 2345, 0, + 2353, 0, 0, 0, 0, 0, 2356, 0, 0, 2507, 2508, 0, 0, 2891, 2888, 2892, 0, + 0, 0, 2964, 0, 0, 0, 0, 3018, 3020, 0, 0, 0, 0, 3019, 0, 0, 0, 3144, 0, + 0, 0, 3264, 3274, 3271, 3272, 0, 0, 0, 0, 3275, 0, 0, 0, 3402, 3404, 0, + 0, 0, 0, 3403, 0, 0, 0, 3546, 3548, 3550, 0, 0, 0, 3549, 4134, 0, 0, 0, + 0, 0, 0, 6918, 0, 6920, 0, 0, 0, 0, 0, 6922, 0, 6924, 0, 0, 0, 0, 0, + 6926, 0, 6930, 0, 0, 0, 0, 0, 6971, 0, 6973, 0, 0, 0, 0, 0, 6976, 0, + 6977, 0, 0, 0, 0, 0, 6979, 0, 0, 7736, 0, 7737, 0, 0, 0, 0, 0, 7772, 0, + 7773, 0, 0, 0, 7784, 0, 0, 0, 0, 0, 7785, 0, 7852, 0, 0, 7862, 0, 0, + 7853, 0, 0, 7863, 0, 0, 7878, 0, 0, 0, 0, 0, 7879, 0, 7896, 0, 0, 0, 0, + 0, 7897, 0, 0, 0, 7938, 7940, 0, 0, 7942, 8064, 7939, 7941, 0, 0, 7943, + 8065, 0, 0, 0, 0, 0, 8066, 0, 8067, 0, 0, 0, 0, 0, 8068, 0, 8069, 0, 0, + 0, 0, 0, 8070, 0, 8071, 0, 0, 0, 0, 7946, 7948, 0, 0, 7950, 8072, 7947, + 7949, 0, 0, 7951, 8073, 0, 0, 0, 0, 0, 8074, 0, 8075, 0, 0, 0, 0, 0, + 8076, 0, 8077, 0, 0, 0, 0, 0, 8078, 0, 8079, 0, 0, 0, 0, 7954, 7956, + 7955, 7957, 0, 0, 0, 0, 7962, 7964, 7963, 7965, 0, 0, 0, 0, 7970, 7972, + 0, 0, 7974, 8080, 7971, 7973, 0, 0, 7975, 8081, 0, 0, 0, 0, 0, 8082, 0, + 8083, 0, 0, 0, 0, 0, 8084, 0, 8085, 0, 0, 0, 0, 0, 8086, 0, 8087, 0, 0, + 0, 0, 7978, 7980, 0, 0, 7982, 8088, 7979, 7981, 0, 0, 7983, 8089, 0, 0, + 0, 0, 0, 8090, 0, 8091, 0, 0, 0, 0, 0, 8092, 0, 8093, 0, 0, 0, 0, 0, + 8094, 0, 8095, 0, 0, 0, 0, 7986, 7988, 0, 0, 7990, 0, 7987, 7989, 0, 0, + 7991, 0, 0, 0, 0, 0, 7994, 7996, 0, 0, 7998, 0, 7995, 7997, 0, 0, 7999, + 0, 0, 0, 0, 0, 8002, 8004, 8003, 8005, 0, 0, 0, 0, 8010, 8012, 8011, + 8013, 0, 0, 0, 0, 8018, 8020, 0, 0, 8022, 0, 8019, 8021, 0, 0, 8023, 0, + 0, 0, 0, 0, 8027, 8029, 0, 0, 8031, 0, 8034, 8036, 0, 0, 8038, 8096, 0, + 0, 0, 0, 8035, 8037, 0, 0, 8039, 8097, 0, 8098, 0, 0, 0, 0, 0, 8099, 0, + 8100, 0, 0, 0, 0, 0, 8101, 0, 8102, 0, 0, 0, 0, 0, 8103, 8042, 8044, 0, + 0, 8046, 8104, 0, 0, 0, 0, 8043, 8045, 0, 0, 8047, 8105, 0, 8106, 0, 0, + 0, 0, 0, 8107, 0, 8108, 0, 0, 0, 0, 0, 8109, 0, 8110, 0, 0, 0, 0, 0, + 8111, 0, 8114, 0, 0, 0, 0, 0, 8130, 0, 8178, 0, 0, 0, 0, 0, 8119, 8141, + 8142, 0, 0, 8143, 0, 0, 0, 0, 0, 0, 8135, 0, 8183, 0, 0, 0, 0, 8157, + 8158, 0, 0, 8159, 0, 0, 0, 0, 8602, 0, 8603, 0, 0, 0, 0, 0, 8622, 0, + 8653, 0, 0, 0, 0, 0, 8655, 0, 8654, 0, 0, 0, 0, 0, 8708, 0, 8713, 0, 0, + 0, 0, 0, 8716, 0, 8740, 0, 0, 0, 0, 0, 8742, 0, 8769, 0, 0, 0, 0, 0, + 8772, 0, 8775, 0, 0, 0, 0, 0, 8777, 0, 8813, 0, 0, 0, 0, 0, 8802, 0, + 8816, 0, 0, 0, 0, 0, 8817, 0, 8820, 0, 0, 0, 0, 0, 8821, 0, 8824, 0, 0, + 0, 0, 0, 8825, 0, 8832, 0, 0, 0, 0, 0, 8833, 0, 8928, 0, 0, 0, 0, 0, + 8929, 0, 8836, 0, 0, 0, 0, 0, 8837, 0, 8840, 0, 0, 0, 0, 0, 8841, 0, + 8930, 0, 0, 0, 0, 0, 8931, 0, 8876, 0, 0, 0, 0, 0, 8877, 0, 8878, 0, 0, + 0, 0, 0, 8879, 0, 8938, 0, 0, 0, 0, 0, 8939, 0, 8940, 0, 0, 0, 0, 0, + 8941, 0, 0, 12436, 0, 12364, 0, 0, 0, 0, 0, 12366, 0, 12368, 0, 0, 0, 0, + 0, 12370, 0, 12372, 0, 0, 0, 0, 0, 12374, 0, 12376, 0, 0, 0, 0, 0, 12378, + 0, 12380, 0, 0, 0, 0, 0, 12382, 0, 12384, 0, 0, 0, 0, 0, 12386, 0, 12389, + 0, 0, 0, 0, 0, 12391, 0, 12393, 0, 0, 0, 0, 0, 12400, 12401, 12403, + 12404, 0, 0, 0, 0, 12406, 12407, 12409, 12410, 0, 0, 0, 0, 12412, 12413, + 12446, 0, 0, 0, 0, 0, 12532, 0, 12460, 0, 0, 0, 0, 0, 12462, 0, 12464, 0, + 0, 0, 0, 0, 12466, 0, 12468, 0, 0, 0, 0, 0, 12470, 0, 12472, 0, 0, 0, 0, + 0, 12474, 0, 12476, 0, 0, 0, 0, 0, 12478, 0, 12480, 0, 0, 0, 0, 0, 12482, + 0, 12485, 0, 0, 0, 0, 0, 12487, 0, 12489, 0, 0, 0, 0, 0, 12496, 12497, + 12499, 12500, 0, 0, 0, 0, 12502, 12503, 12505, 12506, 0, 0, 0, 0, 12508, + 12509, 12535, 0, 0, 0, 0, 0, 12536, 0, 12537, 0, 0, 0, 0, 0, 12538, 0, + 12542, 0, 0, 0, 69786, 0, 0, 0, 0, 0, 69788, 0, 69803, 0, 0, 0, 0, 0, 0, + 69934, 0, 69935, 0, 0, 70475, 70476, 0, 0, 70844, 70843, 70846, 0, 0, + 71098, 0, 0, 0, 0, 0, 71099, +}; + +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, 2, 148, 149, 150, 151, 152, 153, 154, 155, 156, 2, 157, 158, 2, 159, + 160, 161, 162, 2, 163, 164, 2, 165, 166, 167, 2, 2, 168, 169, 170, 171, + 2, 172, 2, 173, 51, 51, 51, 51, 51, 51, 51, 174, 175, 51, 176, 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, 177, 2, 2, 2, 2, 2, 2, 2, 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, 178, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 179, 180, 181, + 182, 2, 2, 2, 2, 89, 183, 184, 185, 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, 186, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 187, 51, 51, 188, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 191, 192, 193, 194, 195, 2, 2, 196, 2, + 2, 2, 197, 198, 199, 51, 51, 51, 51, 51, 200, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 201, 2, 202, 2, 2, 203, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 204, 205, 2, + 2, 2, 2, 2, 206, 207, 208, 2, 209, 210, 2, 2, 211, 212, 213, 214, 215, 2, + 51, 51, 51, 51, 51, 51, 51, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 225, 226, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 87, 227, 2, 228, 229, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 230, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 231, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 232, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 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, 234, 51, 235, 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, 236, 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, 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, 230, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 238, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, + 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, 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, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 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, + 0, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 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, + 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 9, 9, + 9, 9, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 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, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 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, 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, 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, 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, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 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, 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, 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, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 9, + 9, 9, 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, 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, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 0, 9, 9, 9, 9, 0, 9, + 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 0, 9, 0, 9, 0, 9, 9, 9, 0, 9, + 9, 0, 9, 0, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 9, 0, 9, 0, 0, 9, 9, 9, + 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 0, 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, 0, 0, 0, 0, 0, 9, 9, 9, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 9, 9, 9, 9, 9, 9, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 9, 9, + 9, 9, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 19, 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, 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, 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, + 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, 0, + 0, 0, 0, 0, 0, 0, 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/python/Modules/unicodename_db.h b/python/Modules/unicodename_db.h new file mode 100755 index 0000000..6052110 --- /dev/null +++ b/python/Modules/unicodename_db.h @@ -0,0 +1,29046 @@ +/* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ + +#define NAME_MAXLEN 256 + +/* lexicon */ +static const unsigned char lexicon[] = { + 76, 69, 84, 84, 69, 210, 83, 73, 71, 206, 87, 73, 84, 200, 83, 77, 65, + 76, 204, 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, + 84, 73, 77, 69, 211, 66, 65, 77, 85, 205, 65, 78, 196, 66, 79, 76, 196, + 65, 78, 65, 84, 79, 76, 73, 65, 206, 72, 65, 78, 71, 85, 204, 76, 73, 78, + 69, 65, 210, 78, 85, 77, 66, 69, 210, 71, 82, 69, 69, 203, 76, 73, 71, + 65, 84, 85, 82, 197, 77, 85, 83, 73, 67, 65, 204, 69, 84, 72, 73, 79, 80, + 73, 195, 70, 79, 210, 67, 79, 77, 66, 73, 78, 73, 78, 199, 193, 67, 89, + 82, 73, 76, 76, 73, 195, 73, 84, 65, 76, 73, 195, 84, 65, 77, 73, 204, + 78, 85, 83, 72, 213, 82, 65, 68, 73, 67, 65, 204, 83, 65, 78, 83, 45, 83, + 69, 82, 73, 198, 67, 73, 82, 67, 76, 69, 196, 83, 81, 85, 65, 82, 197, + 70, 73, 78, 65, 204, 84, 65, 201, 76, 69, 70, 212, 65, 82, 82, 79, 87, + 128, 68, 79, 85, 66, 76, 197, 82, 73, 71, 72, 212, 86, 65, 201, 83, 73, + 71, 78, 128, 72, 69, 78, 84, 65, 73, 71, 65, 78, 193, 65, 66, 79, 86, 69, + 128, 66, 76, 65, 67, 203, 87, 72, 73, 84, 197, 66, 69, 76, 79, 87, 128, + 65, 82, 82, 79, 215, 86, 65, 82, 73, 65, 84, 73, 79, 206, 65, 128, 66, + 82, 65, 73, 76, 76, 197, 80, 65, 84, 84, 69, 82, 206, 85, 128, 66, 89, + 90, 65, 78, 84, 73, 78, 197, 73, 128, 73, 83, 79, 76, 65, 84, 69, 196, + 75, 65, 84, 65, 75, 65, 78, 193, 79, 128, 77, 79, 68, 73, 70, 73, 69, + 210, 194, 77, 89, 65, 78, 77, 65, 210, 68, 79, 212, 79, 198, 77, 65, 82, + 75, 128, 75, 65, 78, 71, 88, 201, 75, 73, 75, 65, 75, 85, 201, 77, 69, + 78, 68, 197, 84, 73, 66, 69, 84, 65, 206, 86, 69, 82, 84, 73, 67, 65, + 204, 73, 78, 73, 84, 73, 65, 204, 72, 69, 65, 86, 217, 72, 77, 79, 78, + 199, 77, 69, 69, 205, 67, 79, 80, 84, 73, 195, 75, 72, 77, 69, 210, 65, + 66, 79, 86, 197, 82, 73, 71, 72, 84, 87, 65, 82, 68, 211, 67, 65, 82, 82, + 73, 69, 210, 89, 69, 200, 71, 69, 79, 82, 71, 73, 65, 206, 67, 72, 69, + 82, 79, 75, 69, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 79, 78, 197, + 80, 76, 85, 211, 84, 87, 207, 79, 78, 69, 128, 68, 69, 86, 65, 78, 65, + 71, 65, 82, 201, 84, 87, 79, 128, 83, 81, 85, 65, 82, 69, 196, 80, 72, + 65, 83, 69, 45, 197, 83, 89, 77, 66, 79, 76, 128, 83, 84, 82, 79, 75, 69, + 128, 76, 69, 70, 84, 87, 65, 82, 68, 211, 67, 79, 78, 83, 79, 78, 65, 78, + 212, 77, 73, 65, 207, 86, 79, 67, 65, 76, 73, 195, 66, 79, 216, 77, 73, + 68, 68, 76, 197, 84, 73, 76, 197, 68, 85, 80, 76, 79, 89, 65, 206, 84, + 72, 82, 69, 197, 74, 79, 78, 71, 83, 69, 79, 78, 199, 77, 65, 82, 203, + 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 90, 69, 196, 84, 72, 65, 205, 71, + 79, 78, 68, 201, 72, 79, 79, 75, 128, 72, 69, 66, 82, 69, 215, 85, 208, + 71, 76, 65, 71, 79, 76, 73, 84, 73, 195, 76, 79, 215, 79, 86, 69, 210, + 83, 73, 89, 65, 209, 68, 82, 65, 87, 73, 78, 71, 211, 72, 73, 71, 200, + 77, 65, 76, 65, 89, 65, 76, 65, 205, 73, 78, 68, 69, 216, 80, 65, 72, 65, + 87, 200, 84, 72, 82, 69, 69, 128, 68, 79, 87, 206, 70, 79, 85, 82, 128, + 67, 72, 79, 83, 69, 79, 78, 199, 72, 65, 76, 70, 87, 73, 68, 84, 200, 72, + 65, 78, 68, 45, 70, 73, 83, 212, 77, 69, 82, 79, 73, 84, 73, 195, 66, 65, + 76, 73, 78, 69, 83, 197, 72, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 73, 195, 83, 67, 82, 73, 80, 212, 70, 73, 86, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 205, 80, 72, 65, 83, 69, 45, 196, 84, 79, 128, 65, 76, 67, + 72, 69, 77, 73, 67, 65, 204, 65, 76, 69, 198, 84, 79, 78, 197, 83, 73, + 78, 72, 65, 76, 193, 66, 65, 82, 128, 75, 65, 128, 78, 85, 77, 69, 82, + 73, 195, 72, 65, 76, 198, 66, 82, 65, 72, 77, 201, 72, 85, 78, 71, 65, + 82, 73, 65, 206, 80, 65, 128, 84, 72, 85, 77, 194, 84, 85, 82, 78, 69, + 196, 89, 65, 128, 66, 65, 82, 194, 77, 65, 128, 83, 73, 88, 128, 72, 65, + 200, 82, 65, 128, 84, 72, 79, 85, 83, 65, 78, 68, 128, 69, 73, 71, 72, + 84, 128, 76, 65, 128, 78, 79, 82, 84, 200, 70, 85, 76, 76, 87, 73, 68, + 84, 200, 76, 73, 71, 72, 212, 78, 65, 128, 83, 69, 86, 69, 78, 128, 66, + 82, 65, 67, 75, 69, 84, 128, 69, 81, 85, 65, 204, 76, 79, 78, 199, 78, + 73, 78, 69, 128, 83, 65, 128, 84, 65, 199, 68, 79, 77, 73, 78, 207, 65, + 67, 85, 84, 69, 128, 70, 82, 65, 75, 84, 85, 210, 72, 73, 82, 65, 71, 65, + 78, 193, 84, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 210, 70, 82, 65, + 67, 84, 73, 79, 206, 79, 80, 69, 206, 80, 72, 65, 83, 69, 45, 195, 84, + 69, 76, 85, 71, 213, 90, 90, 89, 88, 128, 90, 90, 89, 84, 128, 90, 90, + 89, 82, 88, 128, 90, 90, 89, 82, 128, 90, 90, 89, 80, 128, 90, 90, 89, + 65, 128, 90, 90, 89, 128, 90, 90, 85, 88, 128, 90, 90, 85, 82, 88, 128, + 90, 90, 85, 82, 128, 90, 90, 85, 80, 128, 90, 90, 85, 128, 90, 90, 83, + 89, 65, 128, 90, 90, 83, 65, 128, 90, 90, 79, 88, 128, 90, 90, 79, 80, + 128, 90, 90, 79, 128, 90, 90, 73, 88, 128, 90, 90, 73, 84, 128, 90, 90, + 73, 80, 128, 90, 90, 73, 69, 88, 128, 90, 90, 73, 69, 84, 128, 90, 90, + 73, 69, 80, 128, 90, 90, 73, 69, 128, 90, 90, 73, 128, 90, 90, 69, 88, + 128, 90, 90, 69, 80, 128, 90, 90, 69, 69, 128, 90, 90, 69, 128, 90, 90, + 65, 88, 128, 90, 90, 65, 84, 128, 90, 90, 65, 80, 128, 90, 90, 65, 65, + 128, 90, 90, 65, 128, 90, 89, 71, 79, 83, 128, 90, 87, 83, 80, 128, 90, + 87, 78, 74, 128, 90, 87, 78, 66, 83, 80, 128, 90, 87, 74, 128, 90, 87, + 202, 90, 87, 65, 82, 65, 75, 65, 89, 128, 90, 87, 65, 128, 90, 85, 84, + 128, 90, 85, 79, 88, 128, 90, 85, 79, 80, 128, 90, 85, 79, 128, 90, 85, + 77, 128, 90, 85, 66, 85, 82, 128, 90, 85, 53, 128, 90, 85, 181, 90, 213, + 90, 83, 72, 65, 128, 90, 82, 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, + 84, 128, 90, 79, 79, 128, 90, 79, 77, 66, 73, 69, 128, 90, 79, 65, 128, + 90, 76, 65, 77, 193, 90, 76, 65, 128, 90, 76, 193, 90, 74, 69, 128, 90, + 73, 90, 50, 128, 90, 73, 81, 65, 65, 128, 90, 73, 80, 80, 69, 82, 45, 77, + 79, 85, 84, 200, 90, 73, 78, 79, 82, 128, 90, 73, 76, 68, 69, 128, 90, + 73, 71, 90, 65, 199, 90, 73, 71, 128, 90, 73, 68, 193, 90, 73, 66, 128, + 90, 73, 194, 90, 73, 51, 128, 90, 201, 90, 72, 89, 88, 128, 90, 72, 89, + 84, 128, 90, 72, 89, 82, 88, 128, 90, 72, 89, 82, 128, 90, 72, 89, 80, + 128, 90, 72, 89, 128, 90, 72, 87, 69, 128, 90, 72, 87, 65, 128, 90, 72, + 85, 88, 128, 90, 72, 85, 84, 128, 90, 72, 85, 82, 88, 128, 90, 72, 85, + 82, 128, 90, 72, 85, 80, 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, 79, + 80, 128, 90, 72, 85, 79, 128, 90, 72, 85, 128, 90, 72, 79, 88, 128, 90, + 72, 79, 84, 128, 90, 72, 79, 80, 128, 90, 72, 79, 79, 128, 90, 72, 79, + 73, 128, 90, 72, 79, 128, 90, 72, 73, 86, 69, 84, 69, 128, 90, 72, 73, + 76, 128, 90, 72, 73, 128, 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, 90, + 72, 69, 80, 128, 90, 72, 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, 90, + 72, 65, 89, 73, 78, 128, 90, 72, 65, 88, 128, 90, 72, 65, 84, 128, 90, + 72, 65, 82, 128, 90, 72, 65, 80, 128, 90, 72, 65, 73, 78, 128, 90, 72, + 65, 65, 128, 90, 72, 65, 128, 90, 72, 128, 90, 69, 85, 83, 128, 90, 69, + 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, 82, 207, 90, 69, 78, 128, 90, + 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, 74, 65, 128, 90, 69, 66, 82, + 193, 90, 69, 50, 128, 90, 197, 90, 65, 89, 78, 128, 90, 65, 89, 73, 78, + 45, 89, 79, 68, 72, 128, 90, 65, 89, 73, 78, 128, 90, 65, 89, 73, 206, + 90, 65, 86, 73, 89, 65, 78, 73, 128, 90, 65, 84, 65, 128, 90, 65, 82, 81, + 65, 128, 90, 65, 82, 76, 128, 90, 65, 81, 69, 198, 90, 65, 78, 65, 66, + 65, 90, 65, 210, 90, 65, 77, 88, 128, 90, 65, 76, 128, 90, 65, 204, 90, + 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, 73, 128, 90, 65, 72, 128, 90, + 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, 128, 90, 65, 55, 128, 90, 193, + 90, 48, 49, 54, 72, 128, 90, 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, + 128, 90, 48, 49, 54, 69, 128, 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, + 67, 128, 90, 48, 49, 54, 66, 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, + 54, 128, 90, 48, 49, 53, 73, 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, + 53, 71, 128, 90, 48, 49, 53, 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, + 49, 53, 68, 128, 90, 48, 49, 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, + 48, 49, 53, 65, 128, 90, 48, 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, + 49, 51, 128, 90, 48, 49, 50, 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, + 128, 90, 48, 48, 57, 128, 90, 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, + 48, 48, 54, 128, 90, 48, 48, 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, + 48, 52, 65, 128, 90, 48, 48, 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, + 48, 51, 65, 128, 90, 48, 48, 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, + 48, 50, 67, 128, 90, 48, 48, 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, + 48, 48, 50, 128, 90, 48, 48, 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, + 89, 84, 128, 89, 89, 82, 88, 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, + 89, 69, 128, 89, 89, 65, 65, 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, + 79, 79, 128, 89, 87, 79, 128, 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, + 87, 69, 128, 89, 87, 65, 65, 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, + 88, 128, 89, 85, 87, 79, 81, 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, + 78, 84, 85, 128, 89, 85, 85, 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, + 85, 211, 89, 85, 82, 88, 128, 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, + 209, 89, 85, 80, 128, 89, 85, 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, + 79, 80, 128, 89, 85, 79, 77, 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, + 85, 77, 128, 89, 85, 74, 128, 89, 85, 73, 128, 89, 85, 69, 81, 128, 89, + 85, 69, 128, 89, 85, 68, 72, 128, 89, 85, 68, 200, 89, 85, 65, 78, 128, + 89, 85, 65, 69, 78, 128, 89, 85, 45, 89, 69, 79, 128, 89, 85, 45, 89, 69, + 128, 89, 85, 45, 85, 128, 89, 85, 45, 79, 128, 89, 85, 45, 73, 128, 89, + 85, 45, 69, 79, 128, 89, 85, 45, 69, 128, 89, 85, 45, 65, 69, 128, 89, + 85, 45, 65, 128, 89, 85, 45, 52, 128, 89, 85, 45, 51, 128, 89, 85, 45, + 50, 128, 89, 85, 45, 49, 128, 89, 85, 128, 89, 213, 89, 82, 89, 128, 89, + 80, 83, 73, 76, 73, 128, 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, 75, + 82, 73, 83, 73, 83, 128, 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, 79, + 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, 88, + 128, 89, 79, 87, 68, 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, + 128, 89, 79, 85, 84, 72, 70, 85, 204, 89, 79, 213, 89, 79, 84, 128, 89, + 79, 82, 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, 128, 89, 79, + 79, 128, 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, 68, 128, 89, + 79, 196, 89, 79, 65, 128, 89, 79, 45, 89, 79, 128, 89, 79, 45, 89, 69, + 79, 128, 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, 128, 89, 79, + 45, 79, 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, 89, 79, 45, + 65, 69, 128, 89, 79, 45, 65, 128, 89, 79, 45, 54, 128, 89, 79, 45, 53, + 128, 89, 79, 45, 52, 128, 89, 79, 45, 51, 128, 89, 79, 45, 50, 128, 89, + 79, 45, 49, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, 88, 128, 89, + 73, 87, 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, 78, 71, 128, + 89, 73, 73, 128, 89, 73, 72, 128, 89, 73, 199, 89, 73, 69, 88, 128, 89, + 73, 69, 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, 128, 89, 73, 69, + 128, 89, 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, 89, 73, 128, 89, + 72, 69, 128, 89, 70, 69, 83, 73, 83, 128, 89, 70, 69, 83, 73, 211, 89, + 70, 69, 206, 89, 69, 89, 128, 89, 69, 87, 128, 89, 69, 85, 88, 128, 89, + 69, 85, 82, 65, 69, 128, 89, 69, 85, 81, 128, 89, 69, 85, 77, 128, 89, + 69, 85, 65, 69, 84, 128, 89, 69, 85, 65, 69, 128, 89, 69, 84, 73, 86, + 128, 89, 69, 83, 84, 85, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 83, + 65, 78, 71, 75, 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, 71, + 45, 83, 73, 79, 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 80, 65, 78, + 83, 73, 79, 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 77, 73, 69, 85, + 77, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 75, 73, 89, 69, 79, 75, 128, + 89, 69, 83, 73, 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 89, + 69, 83, 73, 69, 85, 78, 71, 45, 72, 73, 69, 85, 72, 128, 89, 69, 83, 73, + 69, 85, 78, 71, 128, 89, 69, 82, 85, 128, 89, 69, 82, 213, 89, 69, 82, + 73, 128, 89, 69, 82, 65, 200, 89, 69, 82, 128, 89, 69, 79, 82, 73, 78, + 72, 73, 69, 85, 72, 128, 89, 69, 79, 45, 89, 65, 128, 89, 69, 79, 45, 85, + 128, 89, 69, 79, 45, 79, 128, 89, 69, 78, 73, 83, 69, 201, 89, 69, 78, + 65, 80, 128, 89, 69, 78, 128, 89, 69, 206, 89, 69, 76, 76, 79, 87, 128, + 89, 69, 76, 76, 79, 215, 89, 69, 73, 78, 128, 89, 69, 72, 128, 89, 69, + 69, 71, 128, 89, 69, 69, 128, 89, 69, 65, 210, 89, 69, 65, 128, 89, 65, + 90, 90, 128, 89, 65, 90, 72, 128, 89, 65, 90, 128, 89, 65, 89, 68, 128, + 89, 65, 89, 65, 78, 78, 65, 128, 89, 65, 89, 128, 89, 65, 87, 78, 73, 78, + 199, 89, 65, 87, 78, 128, 89, 65, 87, 128, 89, 65, 86, 128, 89, 65, 85, + 128, 89, 65, 84, 84, 128, 89, 65, 84, 73, 128, 89, 65, 84, 72, 128, 89, + 65, 84, 128, 89, 65, 83, 83, 128, 89, 65, 83, 72, 128, 89, 65, 83, 128, + 89, 65, 82, 82, 128, 89, 65, 82, 78, 128, 89, 65, 82, 128, 89, 65, 210, + 89, 65, 81, 128, 89, 65, 80, 128, 89, 65, 78, 83, 65, 89, 65, 128, 89, + 65, 78, 71, 128, 89, 65, 78, 199, 89, 65, 78, 128, 89, 65, 77, 79, 75, + 128, 89, 65, 77, 65, 75, 75, 65, 78, 128, 89, 65, 77, 128, 89, 65, 76, + 128, 89, 65, 75, 72, 72, 128, 89, 65, 75, 72, 128, 89, 65, 75, 65, 83, + 72, 128, 89, 65, 75, 128, 89, 65, 74, 85, 82, 86, 69, 68, 73, 195, 89, + 65, 74, 128, 89, 65, 73, 128, 89, 65, 72, 72, 128, 89, 65, 72, 128, 89, + 65, 71, 78, 128, 89, 65, 71, 72, 72, 128, 89, 65, 71, 72, 128, 89, 65, + 71, 128, 89, 65, 70, 213, 89, 65, 70, 128, 89, 65, 69, 77, 77, 65, 69, + 128, 89, 65, 68, 72, 128, 89, 65, 68, 68, 72, 128, 89, 65, 68, 68, 128, + 89, 65, 68, 128, 89, 65, 67, 72, 128, 89, 65, 66, 72, 128, 89, 65, 66, + 128, 89, 65, 65, 82, 85, 128, 89, 65, 65, 73, 128, 89, 65, 65, 68, 79, + 128, 89, 65, 45, 89, 79, 128, 89, 65, 45, 85, 128, 89, 65, 45, 79, 128, + 89, 65, 45, 53, 128, 89, 65, 45, 52, 128, 89, 65, 45, 51, 128, 89, 65, + 45, 50, 128, 89, 65, 45, 49, 128, 89, 48, 48, 56, 128, 89, 48, 48, 55, + 128, 89, 48, 48, 54, 128, 89, 48, 48, 53, 128, 89, 48, 48, 52, 128, 89, + 48, 48, 51, 128, 89, 48, 48, 50, 128, 89, 48, 48, 49, 65, 128, 89, 48, + 48, 49, 128, 89, 45, 67, 82, 69, 197, 88, 89, 88, 128, 88, 89, 85, 128, + 88, 89, 84, 128, 88, 89, 82, 88, 128, 88, 89, 82, 128, 88, 89, 80, 128, + 88, 89, 79, 79, 74, 128, 88, 89, 79, 79, 128, 88, 89, 79, 128, 88, 89, + 73, 128, 88, 89, 69, 69, 205, 88, 89, 69, 69, 128, 88, 89, 69, 128, 88, + 89, 65, 65, 128, 88, 89, 65, 128, 88, 89, 128, 88, 87, 73, 128, 88, 87, + 69, 69, 128, 88, 87, 69, 128, 88, 87, 65, 65, 128, 88, 87, 65, 128, 88, + 87, 128, 88, 215, 88, 86, 69, 128, 88, 86, 65, 128, 88, 85, 79, 88, 128, + 88, 85, 79, 128, 88, 85, 128, 88, 83, 72, 65, 65, 89, 65, 84, 72, 73, 89, + 65, 128, 88, 79, 88, 128, 88, 79, 84, 128, 88, 79, 82, 128, 88, 79, 80, + 72, 128, 88, 79, 80, 128, 88, 79, 65, 128, 88, 79, 128, 88, 73, 88, 128, + 88, 73, 84, 128, 88, 73, 82, 79, 206, 88, 73, 80, 128, 88, 73, 69, 88, + 128, 88, 73, 69, 84, 128, 88, 73, 69, 80, 128, 88, 73, 69, 128, 88, 73, + 65, 78, 71, 81, 201, 88, 73, 65, 66, 128, 88, 73, 128, 88, 71, 128, 88, + 69, 89, 78, 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, 69, + 128, 88, 69, 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, 88, 65, 80, 72, + 128, 88, 65, 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, 48, 48, 56, 65, + 128, 88, 48, 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, 48, 54, 65, 128, + 88, 48, 48, 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, 52, 66, 128, 88, + 48, 48, 52, 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, 51, 128, 88, 48, + 48, 50, 128, 88, 48, 48, 49, 128, 88, 45, 216, 87, 90, 128, 87, 89, 78, + 78, 128, 87, 89, 78, 206, 87, 86, 73, 128, 87, 86, 69, 128, 87, 86, 65, + 128, 87, 86, 128, 87, 85, 80, 128, 87, 85, 79, 88, 128, 87, 85, 79, 80, + 128, 87, 85, 79, 128, 87, 85, 78, 74, 207, 87, 85, 78, 128, 87, 85, 76, + 85, 128, 87, 85, 76, 213, 87, 85, 73, 128, 87, 85, 69, 128, 87, 85, 65, + 69, 84, 128, 87, 85, 65, 69, 78, 128, 87, 85, 128, 87, 82, 217, 87, 82, + 79, 78, 71, 128, 87, 82, 73, 83, 212, 87, 82, 73, 78, 75, 76, 69, 83, + 128, 87, 82, 73, 78, 75, 76, 69, 211, 87, 82, 73, 78, 75, 76, 69, 68, + 128, 87, 82, 69, 83, 84, 76, 69, 82, 83, 128, 87, 82, 69, 78, 67, 72, + 128, 87, 82, 69, 65, 84, 200, 87, 82, 65, 80, 80, 69, 196, 87, 82, 65, + 80, 128, 87, 79, 88, 128, 87, 79, 87, 128, 87, 79, 82, 83, 72, 73, 80, + 128, 87, 79, 82, 82, 73, 69, 196, 87, 79, 82, 76, 196, 87, 79, 82, 75, + 69, 82, 128, 87, 79, 82, 75, 128, 87, 79, 82, 203, 87, 79, 82, 68, 83, + 80, 65, 67, 69, 128, 87, 79, 82, 196, 87, 79, 80, 128, 87, 79, 79, 78, + 128, 87, 79, 79, 76, 128, 87, 79, 79, 68, 83, 45, 67, 82, 69, 197, 87, + 79, 79, 68, 128, 87, 79, 78, 128, 87, 79, 206, 87, 79, 77, 69, 78, 211, + 87, 79, 77, 69, 206, 87, 79, 77, 65, 78, 211, 87, 79, 77, 65, 78, 128, + 87, 79, 77, 65, 206, 87, 79, 76, 79, 83, 79, 128, 87, 79, 76, 198, 87, + 79, 69, 128, 87, 79, 65, 128, 87, 79, 45, 55, 128, 87, 79, 45, 54, 128, + 87, 79, 45, 53, 128, 87, 79, 45, 52, 128, 87, 79, 45, 51, 128, 87, 79, + 45, 50, 128, 87, 79, 45, 49, 128, 87, 73, 84, 72, 79, 85, 212, 87, 73, + 84, 72, 73, 78, 128, 87, 73, 84, 72, 73, 206, 87, 73, 82, 69, 196, 87, + 73, 78, 84, 69, 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 75, + 128, 87, 73, 78, 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, 78, 69, + 128, 87, 73, 78, 197, 87, 73, 78, 68, 85, 128, 87, 73, 78, 68, 79, 87, + 128, 87, 73, 78, 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, 73, 76, + 84, 69, 196, 87, 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, 217, + 87, 73, 71, 71, 76, 69, 83, 128, 87, 73, 68, 84, 72, 128, 87, 73, 68, 69, + 78, 73, 78, 199, 87, 73, 68, 69, 45, 72, 69, 65, 68, 69, 196, 87, 73, 68, + 197, 87, 73, 65, 78, 71, 87, 65, 65, 75, 128, 87, 73, 65, 78, 71, 128, + 87, 73, 45, 53, 128, 87, 73, 45, 52, 128, 87, 73, 45, 51, 128, 87, 73, + 45, 50, 128, 87, 73, 45, 49, 128, 87, 72, 79, 76, 197, 87, 72, 73, 84, + 69, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 87, 72, 73, 84, 69, 128, 87, + 72, 69, 69, 76, 69, 196, 87, 72, 69, 69, 76, 67, 72, 65, 73, 82, 128, 87, + 72, 69, 69, 76, 67, 72, 65, 73, 210, 87, 72, 69, 69, 76, 128, 87, 72, 69, + 69, 204, 87, 72, 69, 65, 84, 128, 87, 72, 65, 76, 69, 128, 87, 72, 128, + 87, 71, 128, 87, 69, 88, 128, 87, 69, 85, 88, 128, 87, 69, 212, 87, 69, + 83, 84, 69, 82, 206, 87, 69, 83, 84, 45, 67, 82, 69, 197, 87, 69, 83, 84, + 128, 87, 69, 83, 212, 87, 69, 80, 128, 87, 69, 79, 128, 87, 69, 78, 128, + 87, 69, 76, 76, 128, 87, 69, 73, 71, 72, 212, 87, 69, 73, 69, 82, 83, 84, + 82, 65, 83, 211, 87, 69, 73, 128, 87, 69, 69, 78, 128, 87, 69, 68, 71, + 69, 45, 84, 65, 73, 76, 69, 196, 87, 69, 68, 71, 69, 128, 87, 69, 68, 68, + 73, 78, 71, 128, 87, 69, 66, 128, 87, 69, 65, 82, 217, 87, 69, 65, 80, + 79, 78, 128, 87, 69, 45, 52, 128, 87, 69, 45, 51, 128, 87, 69, 45, 50, + 128, 87, 69, 45, 49, 128, 87, 67, 128, 87, 66, 128, 87, 65, 89, 128, 87, + 65, 217, 87, 65, 88, 73, 78, 199, 87, 65, 88, 128, 87, 65, 87, 45, 65, + 89, 73, 78, 45, 82, 69, 83, 72, 128, 87, 65, 87, 128, 87, 65, 215, 87, + 65, 86, 217, 87, 65, 86, 73, 78, 199, 87, 65, 86, 69, 83, 128, 87, 65, + 86, 69, 128, 87, 65, 86, 197, 87, 65, 85, 128, 87, 65, 84, 84, 79, 128, + 87, 65, 84, 69, 82, 77, 69, 76, 79, 78, 128, 87, 65, 84, 69, 82, 128, 87, + 65, 84, 69, 210, 87, 65, 84, 67, 72, 128, 87, 65, 84, 128, 87, 65, 83, + 84, 73, 78, 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, 75, 69, 84, 128, 87, + 65, 83, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, 128, 87, 65, 83, + 76, 193, 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 65, 76, 76, 65, + 205, 87, 65, 82, 78, 73, 78, 199, 87, 65, 82, 65, 78, 199, 87, 65, 81, + 70, 65, 128, 87, 65, 80, 128, 87, 65, 78, 73, 78, 199, 87, 65, 78, 71, + 75, 85, 79, 81, 128, 87, 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 78, 67, + 72, 207, 87, 65, 78, 128, 87, 65, 76, 76, 80, 76, 65, 78, 197, 87, 65, + 76, 76, 128, 87, 65, 76, 204, 87, 65, 76, 75, 128, 87, 65, 76, 203, 87, + 65, 73, 84, 73, 78, 71, 128, 87, 65, 73, 83, 84, 128, 87, 65, 73, 128, + 87, 65, 70, 70, 76, 69, 128, 87, 65, 69, 78, 128, 87, 65, 69, 128, 87, + 65, 68, 68, 65, 128, 87, 65, 65, 86, 85, 128, 87, 65, 45, 53, 128, 87, + 65, 45, 52, 128, 87, 65, 45, 51, 128, 87, 65, 45, 50, 128, 87, 65, 45, + 49, 128, 87, 48, 50, 53, 128, 87, 48, 50, 52, 65, 128, 87, 48, 50, 52, + 128, 87, 48, 50, 51, 128, 87, 48, 50, 50, 128, 87, 48, 50, 49, 128, 87, + 48, 50, 48, 128, 87, 48, 49, 57, 128, 87, 48, 49, 56, 65, 128, 87, 48, + 49, 56, 128, 87, 48, 49, 55, 65, 128, 87, 48, 49, 55, 128, 87, 48, 49, + 54, 128, 87, 48, 49, 53, 128, 87, 48, 49, 52, 65, 128, 87, 48, 49, 52, + 128, 87, 48, 49, 51, 128, 87, 48, 49, 50, 128, 87, 48, 49, 49, 128, 87, + 48, 49, 48, 65, 128, 87, 48, 49, 48, 128, 87, 48, 48, 57, 65, 128, 87, + 48, 48, 57, 128, 87, 48, 48, 56, 128, 87, 48, 48, 55, 128, 87, 48, 48, + 54, 128, 87, 48, 48, 53, 128, 87, 48, 48, 52, 128, 87, 48, 48, 51, 65, + 128, 87, 48, 48, 51, 128, 87, 48, 48, 50, 128, 87, 48, 48, 49, 128, 86, + 90, 77, 69, 84, 128, 86, 89, 88, 128, 86, 89, 84, 128, 86, 89, 82, 88, + 128, 86, 89, 82, 128, 86, 89, 80, 128, 86, 89, 128, 86, 87, 74, 128, 86, + 87, 65, 128, 86, 87, 128, 86, 85, 88, 128, 86, 85, 85, 128, 86, 85, 84, + 128, 86, 85, 82, 88, 128, 86, 85, 82, 128, 86, 85, 80, 128, 86, 85, 76, + 71, 65, 210, 86, 85, 76, 67, 65, 78, 85, 83, 128, 86, 85, 69, 81, 128, + 86, 84, 83, 128, 86, 84, 128, 86, 83, 57, 57, 128, 86, 83, 57, 56, 128, + 86, 83, 57, 55, 128, 86, 83, 57, 54, 128, 86, 83, 57, 53, 128, 86, 83, + 57, 52, 128, 86, 83, 57, 51, 128, 86, 83, 57, 50, 128, 86, 83, 57, 49, + 128, 86, 83, 57, 48, 128, 86, 83, 57, 128, 86, 83, 56, 57, 128, 86, 83, + 56, 56, 128, 86, 83, 56, 55, 128, 86, 83, 56, 54, 128, 86, 83, 56, 53, + 128, 86, 83, 56, 52, 128, 86, 83, 56, 51, 128, 86, 83, 56, 50, 128, 86, + 83, 56, 49, 128, 86, 83, 56, 48, 128, 86, 83, 56, 128, 86, 83, 55, 57, + 128, 86, 83, 55, 56, 128, 86, 83, 55, 55, 128, 86, 83, 55, 54, 128, 86, + 83, 55, 53, 128, 86, 83, 55, 52, 128, 86, 83, 55, 51, 128, 86, 83, 55, + 50, 128, 86, 83, 55, 49, 128, 86, 83, 55, 48, 128, 86, 83, 55, 128, 86, + 83, 54, 57, 128, 86, 83, 54, 56, 128, 86, 83, 54, 55, 128, 86, 83, 54, + 54, 128, 86, 83, 54, 53, 128, 86, 83, 54, 52, 128, 86, 83, 54, 51, 128, + 86, 83, 54, 50, 128, 86, 83, 54, 49, 128, 86, 83, 54, 48, 128, 86, 83, + 54, 128, 86, 83, 53, 57, 128, 86, 83, 53, 56, 128, 86, 83, 53, 55, 128, + 86, 83, 53, 54, 128, 86, 83, 53, 53, 128, 86, 83, 53, 52, 128, 86, 83, + 53, 51, 128, 86, 83, 53, 50, 128, 86, 83, 53, 49, 128, 86, 83, 53, 48, + 128, 86, 83, 53, 128, 86, 83, 52, 57, 128, 86, 83, 52, 56, 128, 86, 83, + 52, 55, 128, 86, 83, 52, 54, 128, 86, 83, 52, 53, 128, 86, 83, 52, 52, + 128, 86, 83, 52, 51, 128, 86, 83, 52, 50, 128, 86, 83, 52, 49, 128, 86, + 83, 52, 48, 128, 86, 83, 52, 128, 86, 83, 51, 57, 128, 86, 83, 51, 56, + 128, 86, 83, 51, 55, 128, 86, 83, 51, 54, 128, 86, 83, 51, 53, 128, 86, + 83, 51, 52, 128, 86, 83, 51, 51, 128, 86, 83, 51, 50, 128, 86, 83, 51, + 49, 128, 86, 83, 51, 48, 128, 86, 83, 51, 128, 86, 83, 50, 57, 128, 86, + 83, 50, 56, 128, 86, 83, 50, 55, 128, 86, 83, 50, 54, 128, 86, 83, 50, + 53, 54, 128, 86, 83, 50, 53, 53, 128, 86, 83, 50, 53, 52, 128, 86, 83, + 50, 53, 51, 128, 86, 83, 50, 53, 50, 128, 86, 83, 50, 53, 49, 128, 86, + 83, 50, 53, 48, 128, 86, 83, 50, 53, 128, 86, 83, 50, 52, 57, 128, 86, + 83, 50, 52, 56, 128, 86, 83, 50, 52, 55, 128, 86, 83, 50, 52, 54, 128, + 86, 83, 50, 52, 53, 128, 86, 83, 50, 52, 52, 128, 86, 83, 50, 52, 51, + 128, 86, 83, 50, 52, 50, 128, 86, 83, 50, 52, 49, 128, 86, 83, 50, 52, + 48, 128, 86, 83, 50, 52, 128, 86, 83, 50, 51, 57, 128, 86, 83, 50, 51, + 56, 128, 86, 83, 50, 51, 55, 128, 86, 83, 50, 51, 54, 128, 86, 83, 50, + 51, 53, 128, 86, 83, 50, 51, 52, 128, 86, 83, 50, 51, 51, 128, 86, 83, + 50, 51, 50, 128, 86, 83, 50, 51, 49, 128, 86, 83, 50, 51, 48, 128, 86, + 83, 50, 51, 128, 86, 83, 50, 50, 57, 128, 86, 83, 50, 50, 56, 128, 86, + 83, 50, 50, 55, 128, 86, 83, 50, 50, 54, 128, 86, 83, 50, 50, 53, 128, + 86, 83, 50, 50, 52, 128, 86, 83, 50, 50, 51, 128, 86, 83, 50, 50, 50, + 128, 86, 83, 50, 50, 49, 128, 86, 83, 50, 50, 48, 128, 86, 83, 50, 50, + 128, 86, 83, 50, 49, 57, 128, 86, 83, 50, 49, 56, 128, 86, 83, 50, 49, + 55, 128, 86, 83, 50, 49, 54, 128, 86, 83, 50, 49, 53, 128, 86, 83, 50, + 49, 52, 128, 86, 83, 50, 49, 51, 128, 86, 83, 50, 49, 50, 128, 86, 83, + 50, 49, 49, 128, 86, 83, 50, 49, 48, 128, 86, 83, 50, 49, 128, 86, 83, + 50, 48, 57, 128, 86, 83, 50, 48, 56, 128, 86, 83, 50, 48, 55, 128, 86, + 83, 50, 48, 54, 128, 86, 83, 50, 48, 53, 128, 86, 83, 50, 48, 52, 128, + 86, 83, 50, 48, 51, 128, 86, 83, 50, 48, 50, 128, 86, 83, 50, 48, 49, + 128, 86, 83, 50, 48, 48, 128, 86, 83, 50, 48, 128, 86, 83, 50, 128, 86, + 83, 49, 57, 57, 128, 86, 83, 49, 57, 56, 128, 86, 83, 49, 57, 55, 128, + 86, 83, 49, 57, 54, 128, 86, 83, 49, 57, 53, 128, 86, 83, 49, 57, 52, + 128, 86, 83, 49, 57, 51, 128, 86, 83, 49, 57, 50, 128, 86, 83, 49, 57, + 49, 128, 86, 83, 49, 57, 48, 128, 86, 83, 49, 57, 128, 86, 83, 49, 56, + 57, 128, 86, 83, 49, 56, 56, 128, 86, 83, 49, 56, 55, 128, 86, 83, 49, + 56, 54, 128, 86, 83, 49, 56, 53, 128, 86, 83, 49, 56, 52, 128, 86, 83, + 49, 56, 51, 128, 86, 83, 49, 56, 50, 128, 86, 83, 49, 56, 49, 128, 86, + 83, 49, 56, 48, 128, 86, 83, 49, 56, 128, 86, 83, 49, 55, 57, 128, 86, + 83, 49, 55, 56, 128, 86, 83, 49, 55, 55, 128, 86, 83, 49, 55, 54, 128, + 86, 83, 49, 55, 53, 128, 86, 83, 49, 55, 52, 128, 86, 83, 49, 55, 51, + 128, 86, 83, 49, 55, 50, 128, 86, 83, 49, 55, 49, 128, 86, 83, 49, 55, + 48, 128, 86, 83, 49, 55, 128, 86, 83, 49, 54, 57, 128, 86, 83, 49, 54, + 56, 128, 86, 83, 49, 54, 55, 128, 86, 83, 49, 54, 54, 128, 86, 83, 49, + 54, 53, 128, 86, 83, 49, 54, 52, 128, 86, 83, 49, 54, 51, 128, 86, 83, + 49, 54, 50, 128, 86, 83, 49, 54, 49, 128, 86, 83, 49, 54, 48, 128, 86, + 83, 49, 54, 128, 86, 83, 49, 53, 57, 128, 86, 83, 49, 53, 56, 128, 86, + 83, 49, 53, 55, 128, 86, 83, 49, 53, 54, 128, 86, 83, 49, 53, 53, 128, + 86, 83, 49, 53, 52, 128, 86, 83, 49, 53, 51, 128, 86, 83, 49, 53, 50, + 128, 86, 83, 49, 53, 49, 128, 86, 83, 49, 53, 48, 128, 86, 83, 49, 53, + 128, 86, 83, 49, 52, 57, 128, 86, 83, 49, 52, 56, 128, 86, 83, 49, 52, + 55, 128, 86, 83, 49, 52, 54, 128, 86, 83, 49, 52, 53, 128, 86, 83, 49, + 52, 52, 128, 86, 83, 49, 52, 51, 128, 86, 83, 49, 52, 50, 128, 86, 83, + 49, 52, 49, 128, 86, 83, 49, 52, 48, 128, 86, 83, 49, 52, 128, 86, 83, + 49, 51, 57, 128, 86, 83, 49, 51, 56, 128, 86, 83, 49, 51, 55, 128, 86, + 83, 49, 51, 54, 128, 86, 83, 49, 51, 53, 128, 86, 83, 49, 51, 52, 128, + 86, 83, 49, 51, 51, 128, 86, 83, 49, 51, 50, 128, 86, 83, 49, 51, 49, + 128, 86, 83, 49, 51, 48, 128, 86, 83, 49, 51, 128, 86, 83, 49, 50, 57, + 128, 86, 83, 49, 50, 56, 128, 86, 83, 49, 50, 55, 128, 86, 83, 49, 50, + 54, 128, 86, 83, 49, 50, 53, 128, 86, 83, 49, 50, 52, 128, 86, 83, 49, + 50, 51, 128, 86, 83, 49, 50, 50, 128, 86, 83, 49, 50, 49, 128, 86, 83, + 49, 50, 48, 128, 86, 83, 49, 50, 128, 86, 83, 49, 49, 57, 128, 86, 83, + 49, 49, 56, 128, 86, 83, 49, 49, 55, 128, 86, 83, 49, 49, 54, 128, 86, + 83, 49, 49, 53, 128, 86, 83, 49, 49, 52, 128, 86, 83, 49, 49, 51, 128, + 86, 83, 49, 49, 50, 128, 86, 83, 49, 49, 49, 128, 86, 83, 49, 49, 48, + 128, 86, 83, 49, 49, 128, 86, 83, 49, 48, 57, 128, 86, 83, 49, 48, 56, + 128, 86, 83, 49, 48, 55, 128, 86, 83, 49, 48, 54, 128, 86, 83, 49, 48, + 53, 128, 86, 83, 49, 48, 52, 128, 86, 83, 49, 48, 51, 128, 86, 83, 49, + 48, 50, 128, 86, 83, 49, 48, 49, 128, 86, 83, 49, 48, 48, 128, 86, 83, + 49, 48, 128, 86, 83, 49, 128, 86, 83, 128, 86, 82, 65, 67, 72, 89, 128, + 86, 79, 88, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, 82, 73, 69, 210, 86, + 79, 87, 128, 86, 79, 85, 128, 86, 79, 84, 128, 86, 79, 211, 86, 79, 80, + 128, 86, 79, 79, 73, 128, 86, 79, 79, 128, 86, 79, 77, 73, 84, 73, 78, + 71, 128, 86, 79, 77, 128, 86, 79, 76, 85, 77, 197, 86, 79, 76, 84, 65, + 71, 197, 86, 79, 76, 76, 69, 89, 66, 65, 76, 76, 128, 86, 79, 76, 67, 65, + 78, 79, 128, 86, 79, 76, 65, 80, 85, 203, 86, 79, 73, 196, 86, 79, 73, + 67, 73, 78, 71, 128, 86, 79, 73, 67, 69, 76, 69, 83, 211, 86, 79, 73, 67, + 69, 196, 86, 79, 68, 128, 86, 79, 67, 65, 76, 73, 90, 65, 84, 73, 79, + 206, 86, 79, 67, 65, 204, 86, 79, 128, 86, 73, 89, 79, 128, 86, 73, 88, + 128, 86, 73, 84, 82, 73, 79, 76, 45, 50, 128, 86, 73, 84, 82, 73, 79, 76, + 128, 86, 73, 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, 69, 128, 86, 73, + 84, 128, 86, 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, 73, 83, 65, 82, 71, + 65, 89, 65, 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, 73, 83, 65, 82, 71, + 193, 86, 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, 128, 86, 73, 82, + 71, 65, 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, 128, 86, 73, 79, + 76, 73, 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, 128, 86, 73, 78, 69, + 71, 65, 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, 128, 86, 73, 78, 69, + 71, 65, 210, 86, 73, 78, 69, 128, 86, 73, 78, 197, 86, 73, 78, 128, 86, + 73, 76, 76, 65, 71, 69, 128, 86, 73, 73, 128, 86, 73, 71, 73, 78, 84, 73, + 76, 69, 128, 86, 73, 69, 88, 128, 86, 73, 69, 87, 73, 78, 199, 86, 73, + 69, 87, 68, 65, 84, 193, 86, 73, 69, 84, 128, 86, 73, 69, 212, 86, 73, + 69, 80, 128, 86, 73, 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, 68, + 74, 128, 86, 73, 68, 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, 73, + 68, 69, 207, 86, 73, 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, 73, + 66, 82, 65, 84, 73, 79, 206, 86, 72, 65, 128, 86, 70, 65, 128, 86, 69, + 89, 90, 128, 86, 69, 88, 128, 86, 69, 87, 128, 86, 69, 215, 86, 69, 85, + 88, 128, 86, 69, 85, 77, 128, 86, 69, 85, 65, 69, 80, 69, 78, 128, 86, + 69, 85, 65, 69, 128, 86, 69, 83, 84, 65, 128, 86, 69, 83, 84, 128, 86, + 69, 83, 83, 69, 204, 86, 69, 82, 217, 86, 69, 82, 84, 73, 67, 65, 76, 76, + 89, 128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 217, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 54, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 54, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, + 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 51, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 50, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 54, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 53, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, + 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 52, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 51, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 53, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 53, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, + 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 53, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 52, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 52, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 52, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, + 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 54, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 53, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 51, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 51, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, + 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 48, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 54, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 50, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 50, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, + 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 49, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 48, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 49, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 49, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, + 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 50, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 49, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 48, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 48, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, + 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 51, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 50, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 48, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 128, + 86, 69, 82, 83, 73, 67, 76, 69, 128, 86, 69, 82, 83, 197, 86, 69, 82, 71, + 69, 128, 86, 69, 82, 68, 73, 71, 82, 73, 83, 128, 86, 69, 82, 128, 86, + 69, 80, 128, 86, 69, 78, 68, 128, 86, 69, 76, 73, 128, 86, 69, 73, 76, + 128, 86, 69, 72, 73, 67, 76, 69, 128, 86, 69, 72, 128, 86, 69, 200, 86, + 69, 69, 128, 86, 69, 197, 86, 69, 68, 69, 128, 86, 69, 67, 84, 79, 210, + 86, 65, 89, 65, 78, 78, 65, 128, 86, 65, 88, 128, 86, 65, 86, 128, 86, + 65, 214, 86, 65, 85, 128, 86, 65, 84, 72, 89, 128, 86, 65, 84, 128, 86, + 65, 83, 84, 78, 69, 83, 211, 86, 65, 83, 73, 83, 128, 86, 65, 82, 89, + 211, 86, 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 84, 128, 86, + 65, 82, 73, 65, 78, 212, 86, 65, 82, 73, 65, 128, 86, 65, 82, 73, 193, + 86, 65, 82, 69, 73, 65, 201, 86, 65, 82, 69, 73, 193, 86, 65, 82, 65, 65, + 75, 65, 78, 128, 86, 65, 80, 79, 85, 82, 83, 128, 86, 65, 80, 128, 86, + 65, 78, 69, 128, 86, 65, 77, 80, 73, 82, 69, 128, 86, 65, 77, 65, 71, 79, + 77, 85, 75, 72, 65, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, 72, 193, 86, + 65, 76, 76, 69, 89, 128, 86, 65, 75, 65, 73, 89, 65, 82, 65, 65, 128, 86, + 65, 74, 128, 86, 65, 73, 128, 86, 65, 72, 128, 86, 65, 200, 86, 65, 65, + 86, 85, 128, 86, 65, 65, 128, 86, 48, 52, 48, 65, 128, 86, 48, 52, 48, + 128, 86, 48, 51, 57, 128, 86, 48, 51, 56, 128, 86, 48, 51, 55, 65, 128, + 86, 48, 51, 55, 128, 86, 48, 51, 54, 128, 86, 48, 51, 53, 128, 86, 48, + 51, 52, 128, 86, 48, 51, 51, 65, 128, 86, 48, 51, 51, 128, 86, 48, 51, + 50, 128, 86, 48, 51, 49, 65, 128, 86, 48, 51, 49, 128, 86, 48, 51, 48, + 65, 128, 86, 48, 51, 48, 128, 86, 48, 50, 57, 65, 128, 86, 48, 50, 57, + 128, 86, 48, 50, 56, 65, 128, 86, 48, 50, 56, 128, 86, 48, 50, 55, 128, + 86, 48, 50, 54, 128, 86, 48, 50, 53, 128, 86, 48, 50, 52, 128, 86, 48, + 50, 51, 65, 128, 86, 48, 50, 51, 128, 86, 48, 50, 50, 128, 86, 48, 50, + 49, 128, 86, 48, 50, 48, 76, 128, 86, 48, 50, 48, 75, 128, 86, 48, 50, + 48, 74, 128, 86, 48, 50, 48, 73, 128, 86, 48, 50, 48, 72, 128, 86, 48, + 50, 48, 71, 128, 86, 48, 50, 48, 70, 128, 86, 48, 50, 48, 69, 128, 86, + 48, 50, 48, 68, 128, 86, 48, 50, 48, 67, 128, 86, 48, 50, 48, 66, 128, + 86, 48, 50, 48, 65, 128, 86, 48, 50, 48, 128, 86, 48, 49, 57, 128, 86, + 48, 49, 56, 128, 86, 48, 49, 55, 128, 86, 48, 49, 54, 128, 86, 48, 49, + 53, 128, 86, 48, 49, 52, 128, 86, 48, 49, 51, 128, 86, 48, 49, 50, 66, + 128, 86, 48, 49, 50, 65, 128, 86, 48, 49, 50, 128, 86, 48, 49, 49, 67, + 128, 86, 48, 49, 49, 66, 128, 86, 48, 49, 49, 65, 128, 86, 48, 49, 49, + 128, 86, 48, 49, 48, 128, 86, 48, 48, 57, 128, 86, 48, 48, 56, 128, 86, + 48, 48, 55, 66, 128, 86, 48, 48, 55, 65, 128, 86, 48, 48, 55, 128, 86, + 48, 48, 54, 128, 86, 48, 48, 53, 128, 86, 48, 48, 52, 128, 86, 48, 48, + 51, 128, 86, 48, 48, 50, 65, 128, 86, 48, 48, 50, 128, 86, 48, 48, 49, + 73, 128, 86, 48, 48, 49, 72, 128, 86, 48, 48, 49, 71, 128, 86, 48, 48, + 49, 70, 128, 86, 48, 48, 49, 69, 128, 86, 48, 48, 49, 68, 128, 86, 48, + 48, 49, 67, 128, 86, 48, 48, 49, 66, 128, 86, 48, 48, 49, 65, 128, 86, + 48, 48, 49, 128, 85, 90, 85, 128, 85, 90, 72, 65, 75, 75, 85, 128, 85, + 90, 51, 128, 85, 90, 179, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, + 87, 85, 128, 85, 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, + 85, 85, 51, 128, 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, + 73, 128, 85, 83, 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, + 128, 85, 83, 72, 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, + 83, 72, 50, 128, 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, + 69, 45, 50, 128, 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, + 85, 82, 85, 218, 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, + 85, 68, 193, 85, 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, + 78, 69, 128, 85, 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, + 83, 128, 85, 82, 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, + 85, 80, 87, 65, 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 211, 85, 80, 87, + 65, 82, 68, 128, 85, 80, 87, 65, 82, 196, 85, 80, 84, 85, 82, 78, 128, + 85, 80, 83, 73, 76, 79, 78, 128, 85, 80, 83, 73, 76, 79, 206, 85, 80, 83, + 73, 68, 69, 45, 68, 79, 87, 206, 85, 80, 82, 73, 71, 72, 212, 85, 80, 80, + 69, 82, 128, 85, 80, 80, 69, 210, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, + 65, 128, 85, 80, 45, 80, 79, 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, + 85, 79, 71, 128, 85, 78, 78, 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, + 85, 78, 75, 78, 79, 87, 78, 128, 85, 78, 75, 128, 85, 78, 73, 86, 69, 82, + 83, 65, 204, 85, 78, 73, 84, 89, 128, 85, 78, 73, 84, 69, 196, 85, 78, + 73, 84, 128, 85, 78, 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, + 206, 85, 78, 73, 70, 79, 82, 77, 128, 85, 78, 73, 70, 73, 69, 196, 85, + 78, 73, 67, 79, 82, 206, 85, 78, 69, 86, 69, 206, 85, 78, 68, 207, 85, + 78, 68, 69, 82, 84, 73, 69, 128, 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, + 78, 68, 69, 82, 68, 79, 84, 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, + 78, 68, 69, 82, 128, 85, 78, 68, 69, 210, 85, 78, 67, 73, 193, 85, 78, + 67, 69, 82, 84, 65, 73, 78, 84, 217, 85, 78, 66, 76, 69, 78, 68, 69, 196, + 85, 78, 65, 83, 80, 73, 82, 65, 84, 69, 68, 128, 85, 78, 65, 80, 128, 85, + 78, 65, 77, 85, 83, 69, 196, 85, 78, 65, 128, 85, 206, 85, 77, 85, 77, + 128, 85, 77, 85, 205, 85, 77, 66, 82, 69, 76, 76, 65, 128, 85, 77, 66, + 82, 69, 76, 76, 193, 85, 77, 66, 73, 78, 128, 85, 75, 85, 128, 85, 75, + 82, 65, 73, 78, 73, 65, 206, 85, 75, 65, 82, 65, 128, 85, 75, 65, 82, + 193, 85, 75, 128, 85, 73, 76, 76, 69, 65, 78, 78, 128, 85, 73, 71, 72, + 85, 210, 85, 72, 68, 128, 85, 71, 65, 82, 73, 84, 73, 195, 85, 69, 89, + 128, 85, 69, 78, 128, 85, 69, 73, 128, 85, 69, 69, 128, 85, 69, 65, 128, + 85, 68, 85, 71, 128, 85, 68, 65, 84, 84, 65, 128, 85, 68, 65, 84, 84, + 193, 85, 68, 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 67, 128, 85, 66, + 85, 70, 73, 76, 73, 128, 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, 68, + 65, 77, 65, 128, 85, 66, 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, 128, + 85, 65, 128, 85, 178, 85, 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, 48, + 52, 48, 128, 85, 48, 51, 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, 55, + 128, 85, 48, 51, 54, 128, 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, 85, + 48, 51, 51, 128, 85, 48, 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, 48, + 51, 49, 128, 85, 48, 51, 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, 50, + 57, 128, 85, 48, 50, 56, 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, 128, + 85, 48, 50, 53, 128, 85, 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, 85, + 48, 50, 51, 128, 85, 48, 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, 50, + 48, 128, 85, 48, 49, 57, 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, 128, + 85, 48, 49, 54, 128, 85, 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, 48, + 49, 51, 128, 85, 48, 49, 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, 48, + 128, 85, 48, 48, 57, 128, 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, 85, + 48, 48, 54, 66, 128, 85, 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, 85, + 48, 48, 53, 128, 85, 48, 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, 48, + 50, 128, 85, 48, 48, 49, 128, 85, 45, 83, 72, 65, 80, 69, 196, 85, 45, + 73, 45, 73, 128, 85, 45, 69, 79, 45, 69, 85, 128, 85, 45, 66, 82, 74, 71, + 85, 128, 85, 45, 53, 128, 84, 90, 85, 128, 84, 90, 79, 65, 128, 84, 90, + 79, 128, 84, 90, 73, 210, 84, 90, 73, 128, 84, 90, 69, 69, 128, 84, 90, + 69, 128, 84, 90, 65, 65, 128, 84, 90, 65, 128, 84, 90, 128, 84, 89, 210, + 84, 89, 80, 69, 45, 183, 84, 89, 80, 69, 45, 54, 128, 84, 89, 80, 69, 45, + 182, 84, 89, 80, 69, 45, 53, 128, 84, 89, 80, 69, 45, 181, 84, 89, 80, + 69, 45, 52, 128, 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, 51, 128, + 84, 89, 80, 69, 45, 179, 84, 89, 80, 69, 45, 178, 84, 89, 80, 69, 45, 49, + 45, 50, 128, 84, 89, 80, 69, 45, 177, 84, 89, 80, 197, 84, 89, 79, 128, + 84, 89, 73, 128, 84, 89, 69, 128, 84, 89, 65, 89, 128, 84, 89, 65, 128, + 84, 88, 87, 86, 128, 84, 88, 87, 214, 84, 88, 72, 69, 69, 202, 84, 88, + 65, 128, 84, 87, 79, 79, 128, 84, 87, 79, 45, 87, 65, 217, 84, 87, 79, + 45, 84, 72, 73, 82, 84, 89, 128, 84, 87, 79, 45, 76, 73, 78, 197, 84, 87, + 79, 45, 72, 69, 65, 68, 69, 196, 84, 87, 79, 45, 69, 205, 84, 87, 79, 45, + 67, 73, 82, 67, 76, 197, 84, 87, 73, 83, 84, 73, 78, 71, 128, 84, 87, 73, + 83, 84, 69, 196, 84, 87, 73, 73, 128, 84, 87, 73, 128, 84, 87, 69, 78, + 84, 89, 45, 84, 87, 79, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 207, 84, + 87, 69, 78, 84, 89, 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, 78, 84, 89, + 45, 83, 73, 88, 128, 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, 69, 78, 128, + 84, 87, 69, 78, 84, 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, + 78, 73, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 84, + 87, 69, 78, 84, 89, 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, 84, 89, 45, + 70, 73, 86, 197, 84, 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, + 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, + 128, 84, 87, 69, 78, 84, 217, 84, 87, 69, 78, 84, 73, 69, 84, 72, 83, + 128, 84, 87, 69, 78, 84, 73, 69, 84, 72, 128, 84, 87, 69, 76, 86, 69, 45, + 84, 72, 73, 82, 84, 89, 128, 84, 87, 69, 76, 86, 69, 128, 84, 87, 69, 76, + 86, 197, 84, 87, 69, 76, 70, 84, 72, 83, 128, 84, 87, 69, 76, 70, 84, 72, + 128, 84, 87, 69, 128, 84, 87, 65, 65, 128, 84, 87, 65, 128, 84, 86, 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, + 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, 80, 78, 73, 128, 84, 85, 80, 128, 84, 85, 79, 88, 128, 84, + 85, 79, 84, 128, 84, 85, 79, 80, 128, 84, 85, 79, 128, 84, 85, 78, 78, + 89, 128, 84, 85, 77, 69, 84, 69, 83, 128, 84, 85, 77, 66, 76, 69, 210, + 84, 85, 77, 65, 69, 128, 84, 85, 77, 128, 84, 85, 205, 84, 85, 76, 73, + 80, 128, 84, 85, 75, 87, 69, 78, 84, 73, 83, 128, 84, 85, 75, 128, 84, + 85, 71, 82, 73, 203, 84, 85, 71, 50, 128, 84, 85, 71, 178, 84, 85, 66, + 69, 128, 84, 85, 66, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, 80, + 128, 84, 85, 65, 69, 128, 84, 85, 45, 84, 79, 128, 84, 85, 45, 52, 128, + 84, 85, 45, 51, 128, 84, 85, 45, 50, 128, 84, 85, 45, 49, 128, 84, 213, + 84, 84, 85, 85, 128, 84, 84, 85, 68, 68, 65, 71, 128, 84, 84, 85, 68, 68, + 65, 65, 71, 128, 84, 84, 85, 128, 84, 84, 84, 72, 65, 128, 84, 84, 84, + 65, 128, 84, 84, 83, 85, 128, 84, 84, 83, 79, 128, 84, 84, 83, 73, 128, + 84, 84, 83, 69, 69, 128, 84, 84, 83, 69, 128, 84, 84, 83, 65, 128, 84, + 84, 79, 79, 128, 84, 84, 73, 73, 128, 84, 84, 73, 128, 84, 84, 72, 87, + 69, 128, 84, 84, 72, 85, 128, 84, 84, 72, 79, 79, 128, 84, 84, 72, 79, + 128, 84, 84, 72, 73, 128, 84, 84, 72, 69, 69, 128, 84, 84, 72, 69, 128, + 84, 84, 72, 65, 65, 128, 84, 84, 72, 128, 84, 84, 69, 72, 69, 72, 128, + 84, 84, 69, 72, 69, 200, 84, 84, 69, 72, 128, 84, 84, 69, 200, 84, 84, + 69, 69, 128, 84, 84, 65, 89, 65, 78, 78, 65, 128, 84, 84, 65, 85, 128, + 84, 84, 65, 73, 128, 84, 84, 65, 65, 128, 84, 84, 50, 128, 84, 83, 87, + 69, 128, 84, 83, 87, 66, 128, 84, 83, 87, 65, 128, 84, 83, 86, 128, 84, + 83, 83, 69, 128, 84, 83, 83, 65, 128, 84, 83, 79, 214, 84, 83, 73, 85, + 128, 84, 83, 72, 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, + 72, 79, 79, 203, 84, 83, 72, 79, 79, 74, 128, 84, 83, 72, 69, 83, 128, + 84, 83, 72, 69, 71, 128, 84, 83, 72, 69, 199, 84, 83, 72, 69, 69, 74, + 128, 84, 83, 72, 69, 128, 84, 83, 72, 65, 194, 84, 83, 72, 65, 128, 84, + 83, 69, 82, 69, 128, 84, 83, 69, 69, 66, 128, 84, 83, 65, 68, 73, 128, + 84, 83, 65, 68, 201, 84, 83, 65, 66, 128, 84, 83, 65, 65, 68, 73, 89, + 128, 84, 83, 65, 65, 128, 84, 83, 193, 84, 211, 84, 82, 89, 66, 76, 73, + 79, 206, 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, 75, 128, 84, 82, 85, + 78, 67, 65, 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, 128, 84, 82, 85, 77, + 80, 45, 57, 128, 84, 82, 85, 77, 80, 45, 56, 128, 84, 82, 85, 77, 80, 45, + 55, 128, 84, 82, 85, 77, 80, 45, 54, 128, 84, 82, 85, 77, 80, 45, 53, + 128, 84, 82, 85, 77, 80, 45, 52, 128, 84, 82, 85, 77, 80, 45, 51, 128, + 84, 82, 85, 77, 80, 45, 50, 49, 128, 84, 82, 85, 77, 80, 45, 50, 48, 128, + 84, 82, 85, 77, 80, 45, 50, 128, 84, 82, 85, 77, 80, 45, 49, 57, 128, 84, + 82, 85, 77, 80, 45, 49, 56, 128, 84, 82, 85, 77, 80, 45, 49, 55, 128, 84, + 82, 85, 77, 80, 45, 49, 54, 128, 84, 82, 85, 77, 80, 45, 49, 53, 128, 84, + 82, 85, 77, 80, 45, 49, 52, 128, 84, 82, 85, 77, 80, 45, 49, 51, 128, 84, + 82, 85, 77, 80, 45, 49, 50, 128, 84, 82, 85, 77, 80, 45, 49, 49, 128, 84, + 82, 85, 77, 80, 45, 49, 48, 128, 84, 82, 85, 77, 80, 45, 49, 128, 84, 82, + 85, 69, 128, 84, 82, 85, 197, 84, 82, 85, 67, 75, 128, 84, 82, 79, 80, + 73, 67, 65, 204, 84, 82, 79, 80, 72, 89, 128, 84, 82, 79, 77, 73, 75, 79, + 83, 89, 78, 65, 71, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 80, 83, 73, + 70, 73, 83, 84, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 80, 65, 82, 65, + 75, 65, 76, 69, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 78, 128, 84, + 82, 79, 77, 73, 75, 79, 206, 84, 82, 79, 77, 73, 75, 79, 76, 89, 71, 73, + 83, 77, 65, 128, 84, 82, 79, 76, 76, 69, 89, 66, 85, 83, 128, 84, 82, 79, + 76, 76, 69, 89, 128, 84, 82, 79, 75, 85, 84, 65, 83, 84, 201, 84, 82, 79, + 69, 90, 69, 78, 73, 65, 206, 84, 82, 73, 85, 77, 80, 72, 128, 84, 82, 73, + 84, 79, 211, 84, 82, 73, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 82, 73, + 83, 73, 77, 79, 85, 128, 84, 82, 73, 83, 69, 77, 69, 128, 84, 82, 73, 80, + 79, 68, 128, 84, 82, 73, 80, 76, 73, 128, 84, 82, 73, 80, 76, 69, 128, + 84, 82, 73, 80, 76, 197, 84, 82, 73, 79, 206, 84, 82, 73, 76, 76, 73, 79, + 78, 83, 128, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 73, 71, 82, 65, 77, + 77, 79, 211, 84, 82, 73, 71, 82, 65, 205, 84, 82, 73, 71, 79, 82, 71, 79, + 78, 128, 84, 82, 73, 70, 79, 78, 73, 65, 83, 128, 84, 82, 73, 70, 79, 76, + 73, 65, 84, 197, 84, 82, 73, 68, 69, 78, 84, 128, 84, 82, 73, 68, 69, 78, + 212, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 73, 65, 78, 71, 85, 76, + 65, 210, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79, 85, 78, 196, 84, 82, + 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 196, 84, 82, 73, 65, 78, + 71, 76, 69, 128, 84, 82, 73, 65, 78, 71, 76, 197, 84, 82, 73, 65, 128, + 84, 82, 73, 128, 84, 82, 69, 83, 73, 76, 76, 79, 128, 84, 82, 69, 78, 68, + 128, 84, 82, 69, 78, 196, 84, 82, 69, 77, 79, 76, 79, 45, 51, 128, 84, + 82, 69, 77, 79, 76, 79, 45, 50, 128, 84, 82, 69, 77, 79, 76, 79, 45, 49, + 128, 84, 82, 69, 69, 128, 84, 82, 69, 197, 84, 82, 69, 68, 69, 67, 73, + 76, 69, 128, 84, 82, 69, 65, 68, 73, 78, 71, 128, 84, 82, 65, 89, 128, + 84, 82, 65, 86, 69, 76, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 84, 82, + 65, 86, 69, 76, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 84, 82, 65, + 80, 69, 90, 73, 85, 77, 128, 84, 82, 65, 78, 83, 86, 69, 82, 83, 65, 204, + 84, 82, 65, 78, 83, 80, 79, 83, 73, 84, 73, 79, 206, 84, 82, 65, 78, 83, + 80, 76, 85, 84, 79, 128, 84, 82, 65, 78, 83, 77, 73, 212, 84, 82, 65, 78, + 83, 77, 73, 83, 83, 73, 79, 78, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, + 73, 79, 206, 84, 82, 65, 77, 87, 65, 89, 128, 84, 82, 65, 77, 128, 84, + 82, 65, 205, 84, 82, 65, 73, 78, 128, 84, 82, 65, 73, 206, 84, 82, 65, + 73, 76, 73, 78, 199, 84, 82, 65, 70, 70, 73, 67, 128, 84, 82, 65, 70, 70, + 73, 195, 84, 82, 65, 68, 73, 84, 73, 79, 78, 65, 204, 84, 82, 65, 68, + 197, 84, 82, 65, 67, 84, 79, 82, 128, 84, 82, 65, 67, 75, 66, 65, 76, 76, + 128, 84, 82, 65, 67, 75, 128, 84, 82, 65, 128, 84, 82, 128, 84, 79, 88, + 128, 84, 79, 87, 69, 82, 128, 84, 79, 87, 65, 82, 68, 211, 84, 79, 86, + 128, 84, 79, 85, 82, 78, 79, 73, 211, 84, 79, 85, 67, 72, 84, 79, 78, + 197, 84, 79, 85, 67, 72, 73, 78, 199, 84, 79, 85, 67, 72, 69, 211, 84, + 79, 85, 67, 200, 84, 79, 84, 65, 204, 84, 79, 84, 128, 84, 79, 83, 128, + 84, 79, 82, 84, 79, 73, 83, 197, 84, 79, 82, 83, 79, 45, 87, 65, 76, 76, + 80, 76, 65, 78, 197, 84, 79, 82, 83, 79, 45, 70, 76, 79, 79, 82, 80, 76, + 65, 78, 197, 84, 79, 82, 83, 79, 128, 84, 79, 82, 78, 65, 68, 79, 128, + 84, 79, 82, 67, 85, 76, 85, 83, 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, + 79, 82, 67, 72, 128, 84, 79, 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, + 79, 80, 45, 76, 73, 71, 72, 84, 69, 196, 84, 79, 80, 128, 84, 79, 208, + 84, 79, 79, 84, 72, 128, 84, 79, 79, 78, 128, 84, 79, 79, 76, 66, 79, 88, + 128, 84, 79, 78, 79, 83, 128, 84, 79, 78, 71, 85, 69, 128, 84, 79, 78, + 71, 85, 197, 84, 79, 78, 71, 128, 84, 79, 78, 69, 45, 86, 128, 84, 79, + 78, 69, 45, 83, 128, 84, 79, 78, 69, 45, 77, 128, 84, 79, 78, 69, 45, 74, + 128, 84, 79, 78, 69, 45, 71, 128, 84, 79, 78, 69, 45, 68, 128, 84, 79, + 78, 69, 45, 66, 128, 84, 79, 78, 69, 45, 56, 128, 84, 79, 78, 69, 45, 55, + 128, 84, 79, 78, 69, 45, 54, 128, 84, 79, 78, 69, 45, 53, 128, 84, 79, + 78, 69, 45, 52, 128, 84, 79, 78, 69, 45, 51, 128, 84, 79, 78, 69, 45, 50, + 128, 84, 79, 78, 69, 45, 49, 128, 84, 79, 78, 69, 128, 84, 79, 78, 65, + 204, 84, 79, 77, 80, 73, 128, 84, 79, 77, 65, 84, 79, 128, 84, 79, 76, + 79, 78, 71, 128, 84, 79, 75, 89, 207, 84, 79, 73, 76, 69, 84, 128, 84, + 79, 71, 69, 84, 72, 69, 82, 128, 84, 79, 68, 207, 84, 79, 65, 78, 68, 65, + 75, 72, 73, 65, 84, 128, 84, 79, 65, 128, 84, 79, 45, 82, 65, 128, 84, + 79, 45, 54, 128, 84, 79, 45, 53, 128, 84, 79, 45, 52, 128, 84, 79, 45, + 51, 128, 84, 79, 45, 50, 128, 84, 79, 45, 49, 128, 84, 78, 128, 84, 76, + 86, 128, 84, 76, 85, 128, 84, 76, 79, 128, 84, 76, 73, 128, 84, 76, 72, + 89, 65, 128, 84, 76, 72, 87, 69, 128, 84, 76, 72, 85, 128, 84, 76, 72, + 79, 79, 128, 84, 76, 72, 79, 128, 84, 76, 72, 73, 128, 84, 76, 72, 69, + 69, 128, 84, 76, 72, 69, 128, 84, 76, 72, 65, 128, 84, 76, 69, 69, 128, + 84, 76, 65, 128, 84, 74, 69, 128, 84, 73, 88, 128, 84, 73, 87, 82, 128, + 84, 73, 87, 78, 128, 84, 73, 87, 65, 218, 84, 73, 84, 85, 65, 69, 80, + 128, 84, 73, 84, 76, 79, 128, 84, 73, 84, 76, 207, 84, 73, 84, 193, 84, + 73, 84, 128, 84, 73, 82, 89, 65, 75, 128, 84, 73, 82, 84, 193, 84, 73, + 82, 79, 78, 73, 65, 206, 84, 73, 82, 72, 85, 84, 193, 84, 73, 82, 69, + 196, 84, 73, 82, 128, 84, 73, 210, 84, 73, 80, 80, 73, 128, 84, 73, 80, + 69, 72, 65, 128, 84, 73, 80, 128, 84, 73, 208, 84, 73, 78, 89, 128, 84, + 73, 78, 217, 84, 73, 78, 78, 69, 128, 84, 73, 78, 67, 84, 85, 82, 69, + 128, 84, 73, 78, 65, 71, 77, 65, 128, 84, 73, 77, 69, 83, 128, 84, 73, + 77, 69, 210, 84, 73, 77, 69, 128, 84, 73, 76, 84, 73, 78, 71, 128, 84, + 73, 76, 84, 73, 78, 199, 84, 73, 76, 84, 128, 84, 73, 76, 69, 83, 128, + 84, 73, 76, 68, 69, 128, 84, 73, 76, 68, 197, 84, 73, 76, 128, 84, 73, + 204, 84, 73, 75, 69, 85, 84, 45, 84, 72, 73, 69, 85, 84, 72, 128, 84, 73, + 75, 69, 85, 84, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 84, + 73, 75, 69, 85, 84, 45, 83, 73, 79, 83, 128, 84, 73, 75, 69, 85, 84, 45, + 82, 73, 69, 85, 76, 128, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, + 128, 84, 73, 75, 69, 85, 84, 45, 77, 73, 69, 85, 77, 128, 84, 73, 75, 69, + 85, 84, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 67, + 73, 69, 85, 67, 128, 84, 73, 75, 69, 85, 84, 45, 67, 72, 73, 69, 85, 67, + 72, 128, 84, 73, 75, 69, 85, 84, 128, 84, 73, 75, 69, 85, 212, 84, 73, + 71, 72, 84, 76, 89, 45, 67, 76, 79, 83, 69, 196, 84, 73, 71, 72, 212, 84, + 73, 71, 69, 82, 128, 84, 73, 71, 69, 210, 84, 73, 70, 73, 78, 65, 71, + 200, 84, 73, 69, 88, 128, 84, 73, 69, 80, 128, 84, 73, 197, 84, 73, 67, + 75, 69, 84, 83, 128, 84, 73, 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, + 84, 73, 67, 203, 84, 73, 65, 82, 65, 128, 84, 73, 50, 128, 84, 73, 45, + 55, 128, 84, 73, 45, 54, 128, 84, 73, 45, 53, 128, 84, 73, 45, 52, 128, + 84, 73, 45, 51, 128, 84, 73, 45, 50, 128, 84, 73, 45, 49, 128, 84, 72, + 90, 128, 84, 72, 89, 79, 79, 205, 84, 72, 87, 79, 79, 128, 84, 72, 87, + 79, 128, 84, 72, 87, 73, 73, 128, 84, 72, 87, 73, 128, 84, 72, 87, 69, + 69, 128, 84, 72, 87, 65, 65, 128, 84, 72, 87, 65, 128, 84, 72, 85, 82, + 211, 84, 72, 85, 82, 73, 83, 65, 218, 84, 72, 85, 78, 71, 128, 84, 72, + 85, 78, 68, 69, 82, 83, 84, 79, 82, 77, 128, 84, 72, 85, 78, 68, 69, 82, + 128, 84, 72, 85, 78, 68, 69, 210, 84, 72, 85, 77, 66, 211, 84, 72, 85, + 77, 66, 128, 84, 72, 82, 79, 87, 73, 78, 199, 84, 72, 82, 79, 85, 71, 72, + 128, 84, 72, 82, 79, 85, 71, 200, 84, 72, 82, 69, 69, 45, 84, 72, 73, 82, + 84, 89, 128, 84, 72, 82, 69, 69, 45, 81, 85, 65, 82, 84, 69, 210, 84, 72, + 82, 69, 69, 45, 80, 69, 82, 45, 69, 205, 84, 72, 82, 69, 69, 45, 76, 73, + 78, 197, 84, 72, 82, 69, 69, 45, 76, 69, 71, 71, 69, 196, 84, 72, 82, 69, + 69, 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, 78, 68, 45, 84, 87, 69, 78, + 84, 73, 69, 84, 72, 128, 84, 72, 82, 69, 69, 45, 69, 205, 84, 72, 82, 69, + 69, 45, 68, 79, 212, 84, 72, 82, 69, 69, 45, 196, 84, 72, 82, 69, 69, 45, + 67, 73, 82, 67, 76, 197, 84, 72, 82, 69, 65, 68, 128, 84, 72, 79, 85, 83, + 65, 78, 68, 83, 128, 84, 72, 79, 85, 83, 65, 78, 68, 211, 84, 72, 79, 85, + 83, 65, 78, 196, 84, 72, 79, 85, 71, 72, 212, 84, 72, 79, 85, 128, 84, + 72, 79, 82, 78, 128, 84, 72, 79, 82, 206, 84, 72, 79, 78, 71, 128, 84, + 72, 79, 77, 128, 84, 72, 79, 74, 128, 84, 72, 79, 65, 128, 84, 72, 207, + 84, 72, 73, 85, 84, 72, 128, 84, 72, 73, 84, 65, 128, 84, 72, 73, 82, 84, + 89, 45, 83, 69, 67, 79, 78, 68, 128, 84, 72, 73, 82, 84, 89, 45, 83, 69, + 67, 79, 78, 196, 84, 72, 73, 82, 84, 89, 45, 79, 78, 69, 128, 84, 72, 73, + 82, 84, 89, 45, 70, 73, 86, 197, 84, 72, 73, 82, 84, 217, 84, 72, 73, 82, + 84, 69, 69, 78, 128, 84, 72, 73, 82, 84, 69, 69, 206, 84, 72, 73, 82, 68, + 83, 128, 84, 72, 73, 82, 68, 211, 84, 72, 73, 82, 68, 45, 83, 84, 65, 71, + 197, 84, 72, 73, 82, 68, 128, 84, 72, 73, 82, 196, 84, 72, 73, 78, 75, + 73, 78, 199, 84, 72, 73, 78, 71, 128, 84, 72, 73, 73, 128, 84, 72, 73, + 71, 72, 128, 84, 72, 73, 69, 85, 84, 200, 84, 72, 73, 67, 203, 84, 72, + 73, 65, 66, 128, 84, 72, 69, 89, 128, 84, 72, 69, 84, 72, 69, 128, 84, + 72, 69, 84, 72, 128, 84, 72, 69, 84, 65, 128, 84, 72, 69, 84, 193, 84, + 72, 69, 83, 80, 73, 65, 206, 84, 72, 69, 83, 69, 79, 83, 128, 84, 72, 69, + 83, 69, 79, 211, 84, 72, 69, 211, 84, 72, 69, 82, 77, 79, 77, 69, 84, 69, + 82, 128, 84, 72, 69, 82, 77, 79, 68, 89, 78, 65, 77, 73, 67, 128, 84, 72, + 69, 82, 69, 70, 79, 82, 69, 128, 84, 72, 69, 82, 197, 84, 72, 69, 206, + 84, 72, 69, 77, 65, 84, 73, 83, 77, 79, 211, 84, 72, 69, 77, 65, 128, 84, + 72, 69, 77, 193, 84, 72, 69, 72, 128, 84, 72, 69, 200, 84, 72, 69, 65, + 128, 84, 72, 197, 84, 72, 65, 87, 128, 84, 72, 65, 78, 84, 72, 65, 75, + 72, 65, 84, 128, 84, 72, 65, 78, 78, 65, 128, 84, 72, 65, 78, 128, 84, + 72, 65, 206, 84, 72, 65, 77, 69, 68, 72, 128, 84, 72, 65, 76, 128, 84, + 72, 65, 204, 84, 72, 65, 74, 128, 84, 72, 65, 201, 84, 72, 65, 72, 65, + 78, 128, 84, 72, 65, 65, 78, 193, 84, 72, 65, 65, 76, 85, 128, 84, 72, + 45, 67, 82, 69, 197, 84, 69, 88, 84, 128, 84, 69, 88, 212, 84, 69, 88, + 128, 84, 69, 86, 73, 82, 128, 84, 69, 85, 84, 69, 85, 88, 128, 84, 69, + 85, 84, 69, 85, 87, 69, 78, 128, 84, 69, 85, 84, 128, 84, 69, 85, 78, + 128, 84, 69, 85, 65, 69, 81, 128, 84, 69, 85, 65, 69, 78, 128, 84, 69, + 85, 128, 84, 69, 84, 82, 65, 83, 73, 77, 79, 85, 128, 84, 69, 84, 82, 65, + 83, 69, 77, 69, 128, 84, 69, 84, 82, 65, 80, 76, 73, 128, 84, 69, 84, 82, + 65, 71, 82, 65, 205, 84, 69, 84, 82, 65, 70, 79, 78, 73, 65, 83, 128, 84, + 69, 84, 72, 128, 84, 69, 84, 200, 84, 69, 84, 65, 82, 84, 79, 211, 84, + 69, 84, 65, 82, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 69, 84, 128, 84, + 69, 212, 84, 69, 83, 212, 84, 69, 83, 83, 69, 82, 65, 128, 84, 69, 83, + 83, 69, 82, 193, 84, 69, 83, 83, 65, 82, 79, 206, 84, 69, 83, 200, 84, + 69, 82, 77, 73, 78, 65, 84, 79, 82, 128, 84, 69, 82, 77, 73, 78, 65, 204, + 84, 69, 80, 128, 84, 69, 78, 85, 84, 79, 128, 84, 69, 78, 85, 128, 84, + 69, 78, 213, 84, 69, 78, 84, 72, 128, 84, 69, 78, 84, 128, 84, 69, 78, + 83, 69, 128, 84, 69, 78, 83, 197, 84, 69, 78, 83, 128, 84, 69, 78, 211, + 84, 69, 78, 78, 73, 211, 84, 69, 78, 71, 197, 84, 69, 78, 45, 84, 72, 73, + 82, 84, 89, 128, 84, 69, 78, 128, 84, 69, 206, 84, 69, 77, 80, 85, 211, + 84, 69, 77, 80, 76, 69, 128, 84, 69, 76, 85, 128, 84, 69, 76, 79, 85, + 211, 84, 69, 76, 76, 69, 210, 84, 69, 76, 73, 83, 72, 193, 84, 69, 76, + 69, 86, 73, 83, 73, 79, 78, 128, 84, 69, 76, 69, 83, 67, 79, 80, 69, 128, + 84, 69, 76, 69, 80, 72, 79, 78, 69, 128, 84, 69, 76, 69, 80, 72, 79, 78, + 197, 84, 69, 76, 69, 73, 65, 128, 84, 69, 76, 69, 71, 82, 65, 80, 200, + 84, 69, 75, 128, 84, 69, 73, 87, 83, 128, 84, 69, 71, 69, 72, 128, 84, + 69, 69, 84, 72, 128, 84, 69, 69, 84, 200, 84, 69, 69, 78, 83, 128, 84, + 69, 69, 69, 69, 128, 84, 69, 197, 84, 69, 68, 85, 78, 71, 128, 84, 69, + 68, 68, 217, 84, 69, 65, 82, 211, 84, 69, 65, 82, 68, 82, 79, 80, 45, 83, + 80, 79, 75, 69, 196, 84, 69, 65, 82, 68, 82, 79, 80, 45, 83, 72, 65, 78, + 75, 69, 196, 84, 69, 65, 82, 68, 82, 79, 80, 45, 66, 65, 82, 66, 69, 196, + 84, 69, 65, 82, 45, 79, 70, 198, 84, 69, 65, 67, 85, 208, 84, 69, 45, 85, + 128, 84, 69, 45, 57, 128, 84, 69, 45, 56, 128, 84, 69, 45, 55, 128, 84, + 69, 45, 54, 128, 84, 69, 45, 53, 128, 84, 69, 45, 52, 128, 84, 69, 45, + 51, 128, 84, 69, 45, 50, 128, 84, 69, 45, 49, 128, 84, 67, 72, 69, 72, + 69, 72, 128, 84, 67, 72, 69, 72, 69, 200, 84, 67, 72, 69, 72, 128, 84, + 67, 72, 69, 200, 84, 67, 72, 69, 128, 84, 195, 84, 65, 89, 128, 84, 65, + 88, 73, 128, 84, 65, 88, 128, 84, 65, 87, 69, 76, 76, 69, 77, 69, 212, + 84, 65, 87, 65, 128, 84, 65, 87, 128, 84, 65, 215, 84, 65, 86, 73, 89, + 65, 78, 73, 128, 84, 65, 86, 128, 84, 65, 214, 84, 65, 85, 82, 85, 83, + 128, 84, 65, 85, 77, 128, 84, 65, 213, 84, 65, 84, 87, 69, 69, 76, 128, + 84, 65, 84, 87, 69, 69, 204, 84, 65, 84, 84, 79, 79, 69, 196, 84, 65, 84, + 128, 84, 65, 83, 83, 73, 128, 84, 65, 83, 128, 84, 65, 82, 85, 78, 71, + 128, 84, 65, 82, 84, 65, 82, 45, 50, 128, 84, 65, 82, 84, 65, 82, 128, + 84, 65, 82, 71, 69, 84, 128, 84, 65, 81, 128, 84, 65, 80, 69, 82, 128, + 84, 65, 80, 197, 84, 65, 80, 128, 84, 65, 79, 128, 84, 65, 78, 78, 69, + 196, 84, 65, 78, 71, 69, 82, 73, 78, 69, 128, 84, 65, 78, 71, 69, 78, 84, + 128, 84, 65, 78, 71, 69, 78, 212, 84, 65, 78, 199, 84, 65, 78, 65, 66, + 65, 84, 193, 84, 65, 78, 65, 128, 84, 65, 78, 128, 84, 65, 77, 73, 78, + 71, 128, 84, 65, 77, 65, 206, 84, 65, 77, 128, 84, 65, 76, 76, 217, 84, + 65, 76, 76, 128, 84, 65, 76, 204, 84, 65, 76, 73, 78, 71, 128, 84, 65, + 76, 73, 78, 199, 84, 65, 76, 69, 78, 84, 83, 128, 84, 65, 76, 69, 78, + 212, 84, 65, 75, 82, 201, 84, 65, 75, 72, 65, 76, 76, 85, 83, 128, 84, + 65, 75, 69, 79, 85, 212, 84, 65, 75, 69, 128, 84, 65, 75, 52, 128, 84, + 65, 75, 180, 84, 65, 75, 128, 84, 65, 73, 83, 89, 79, 85, 128, 84, 65, + 73, 76, 76, 69, 83, 211, 84, 65, 73, 76, 128, 84, 65, 73, 204, 84, 65, + 72, 65, 76, 65, 128, 84, 65, 72, 128, 84, 65, 200, 84, 65, 71, 66, 65, + 78, 87, 193, 84, 65, 71, 65, 76, 79, 199, 84, 65, 71, 128, 84, 65, 69, + 206, 84, 65, 67, 79, 128, 84, 65, 67, 75, 128, 84, 65, 67, 203, 84, 65, + 66, 85, 76, 65, 84, 73, 79, 78, 128, 84, 65, 66, 85, 76, 65, 84, 73, 79, + 206, 84, 65, 66, 83, 128, 84, 65, 66, 76, 69, 128, 84, 65, 66, 76, 197, + 84, 65, 66, 128, 84, 65, 194, 84, 65, 65, 83, 72, 65, 69, 128, 84, 65, + 65, 81, 128, 84, 65, 65, 77, 128, 84, 65, 65, 76, 85, 74, 193, 84, 65, + 65, 73, 128, 84, 65, 65, 70, 128, 84, 65, 50, 128, 84, 65, 45, 82, 79, + 76, 128, 84, 65, 45, 52, 128, 84, 65, 45, 51, 128, 84, 65, 45, 50, 128, + 84, 65, 45, 49, 128, 84, 48, 51, 54, 128, 84, 48, 51, 53, 128, 84, 48, + 51, 52, 128, 84, 48, 51, 51, 65, 128, 84, 48, 51, 51, 128, 84, 48, 51, + 50, 65, 128, 84, 48, 51, 50, 128, 84, 48, 51, 49, 128, 84, 48, 51, 48, + 128, 84, 48, 50, 57, 128, 84, 48, 50, 56, 128, 84, 48, 50, 55, 128, 84, + 48, 50, 54, 128, 84, 48, 50, 53, 128, 84, 48, 50, 52, 128, 84, 48, 50, + 51, 128, 84, 48, 50, 50, 128, 84, 48, 50, 49, 128, 84, 48, 50, 48, 128, + 84, 48, 49, 57, 128, 84, 48, 49, 56, 128, 84, 48, 49, 55, 128, 84, 48, + 49, 54, 65, 128, 84, 48, 49, 54, 128, 84, 48, 49, 53, 128, 84, 48, 49, + 52, 128, 84, 48, 49, 51, 128, 84, 48, 49, 50, 128, 84, 48, 49, 49, 65, + 128, 84, 48, 49, 49, 128, 84, 48, 49, 48, 128, 84, 48, 48, 57, 65, 128, + 84, 48, 48, 57, 128, 84, 48, 48, 56, 65, 128, 84, 48, 48, 56, 128, 84, + 48, 48, 55, 65, 128, 84, 48, 48, 55, 128, 84, 48, 48, 54, 128, 84, 48, + 48, 53, 128, 84, 48, 48, 52, 128, 84, 48, 48, 51, 65, 128, 84, 48, 48, + 51, 128, 84, 48, 48, 50, 128, 84, 48, 48, 49, 128, 84, 45, 83, 72, 73, + 82, 84, 128, 84, 45, 82, 69, 88, 128, 83, 90, 90, 128, 83, 90, 87, 71, + 128, 83, 90, 87, 65, 128, 83, 90, 85, 128, 83, 90, 79, 128, 83, 90, 73, + 128, 83, 90, 69, 69, 128, 83, 90, 69, 128, 83, 90, 65, 65, 128, 83, 90, + 65, 128, 83, 90, 128, 83, 89, 88, 128, 83, 89, 84, 128, 83, 89, 83, 84, + 69, 205, 83, 89, 82, 88, 128, 83, 89, 82, 77, 65, 84, 73, 75, 73, 128, + 83, 89, 82, 77, 65, 128, 83, 89, 82, 73, 78, 71, 69, 128, 83, 89, 82, 73, + 65, 195, 83, 89, 82, 128, 83, 89, 80, 128, 83, 89, 79, 85, 87, 65, 128, + 83, 89, 78, 69, 86, 77, 65, 128, 83, 89, 78, 68, 69, 83, 77, 79, 211, 83, + 89, 78, 67, 72, 82, 79, 78, 79, 85, 211, 83, 89, 78, 65, 71, 79, 71, 85, + 69, 128, 83, 89, 78, 65, 71, 77, 193, 83, 89, 78, 65, 70, 73, 128, 83, + 89, 78, 128, 83, 89, 77, 77, 69, 84, 82, 89, 128, 83, 89, 77, 77, 69, 84, + 82, 73, 195, 83, 89, 77, 66, 79, 76, 83, 128, 83, 89, 77, 66, 79, 76, + 211, 83, 89, 77, 66, 79, 76, 45, 57, 128, 83, 89, 77, 66, 79, 76, 45, 56, + 128, 83, 89, 77, 66, 79, 76, 45, 55, 128, 83, 89, 77, 66, 79, 76, 45, 54, + 128, 83, 89, 77, 66, 79, 76, 45, 53, 52, 128, 83, 89, 77, 66, 79, 76, 45, + 53, 51, 128, 83, 89, 77, 66, 79, 76, 45, 53, 50, 128, 83, 89, 77, 66, 79, + 76, 45, 53, 49, 128, 83, 89, 77, 66, 79, 76, 45, 53, 48, 128, 83, 89, 77, + 66, 79, 76, 45, 53, 128, 83, 89, 77, 66, 79, 76, 45, 52, 57, 128, 83, 89, + 77, 66, 79, 76, 45, 52, 56, 128, 83, 89, 77, 66, 79, 76, 45, 52, 55, 128, + 83, 89, 77, 66, 79, 76, 45, 52, 53, 128, 83, 89, 77, 66, 79, 76, 45, 52, + 51, 128, 83, 89, 77, 66, 79, 76, 45, 52, 50, 128, 83, 89, 77, 66, 79, 76, + 45, 52, 48, 128, 83, 89, 77, 66, 79, 76, 45, 52, 128, 83, 89, 77, 66, 79, + 76, 45, 51, 57, 128, 83, 89, 77, 66, 79, 76, 45, 51, 56, 128, 83, 89, 77, + 66, 79, 76, 45, 51, 55, 128, 83, 89, 77, 66, 79, 76, 45, 51, 54, 128, 83, + 89, 77, 66, 79, 76, 45, 51, 50, 128, 83, 89, 77, 66, 79, 76, 45, 51, 48, + 128, 83, 89, 77, 66, 79, 76, 45, 51, 128, 83, 89, 77, 66, 79, 76, 45, 50, + 57, 128, 83, 89, 77, 66, 79, 76, 45, 50, 55, 128, 83, 89, 77, 66, 79, 76, + 45, 50, 54, 128, 83, 89, 77, 66, 79, 76, 45, 50, 53, 128, 83, 89, 77, 66, + 79, 76, 45, 50, 52, 128, 83, 89, 77, 66, 79, 76, 45, 50, 51, 128, 83, 89, + 77, 66, 79, 76, 45, 50, 50, 128, 83, 89, 77, 66, 79, 76, 45, 50, 49, 128, + 83, 89, 77, 66, 79, 76, 45, 50, 48, 128, 83, 89, 77, 66, 79, 76, 45, 50, + 128, 83, 89, 77, 66, 79, 76, 45, 49, 57, 128, 83, 89, 77, 66, 79, 76, 45, + 49, 56, 128, 83, 89, 77, 66, 79, 76, 45, 49, 55, 128, 83, 89, 77, 66, 79, + 76, 45, 49, 54, 128, 83, 89, 77, 66, 79, 76, 45, 49, 53, 128, 83, 89, 77, + 66, 79, 76, 45, 49, 52, 128, 83, 89, 77, 66, 79, 76, 45, 49, 51, 128, 83, + 89, 77, 66, 79, 76, 45, 49, 50, 128, 83, 89, 77, 66, 79, 76, 45, 49, 49, + 128, 83, 89, 77, 66, 79, 76, 45, 49, 48, 128, 83, 89, 77, 66, 79, 76, 45, + 49, 128, 83, 89, 76, 79, 84, 201, 83, 89, 73, 128, 83, 89, 128, 83, 87, + 90, 128, 83, 87, 85, 78, 199, 83, 87, 79, 82, 68, 83, 128, 83, 87, 79, + 82, 68, 128, 83, 87, 79, 79, 128, 83, 87, 79, 128, 83, 87, 73, 82, 204, + 83, 87, 73, 77, 83, 85, 73, 84, 128, 83, 87, 73, 77, 77, 73, 78, 71, 128, + 83, 87, 73, 77, 77, 69, 82, 128, 83, 87, 73, 73, 128, 83, 87, 73, 128, + 83, 87, 71, 128, 83, 87, 69, 69, 84, 128, 83, 87, 69, 69, 212, 83, 87, + 69, 65, 84, 128, 83, 87, 69, 65, 212, 83, 87, 65, 83, 200, 83, 87, 65, + 80, 80, 73, 78, 71, 128, 83, 87, 65, 78, 128, 83, 87, 65, 65, 128, 83, + 87, 128, 83, 86, 65, 83, 84, 201, 83, 86, 65, 82, 73, 84, 65, 128, 83, + 86, 65, 82, 73, 84, 193, 83, 85, 88, 128, 83, 85, 85, 128, 83, 85, 84, + 82, 193, 83, 85, 84, 128, 83, 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, + 85, 83, 72, 73, 128, 83, 85, 82, 89, 65, 128, 83, 85, 82, 88, 128, 83, + 85, 82, 82, 79, 85, 78, 68, 128, 83, 85, 82, 82, 79, 85, 78, 196, 83, 85, + 82, 70, 69, 82, 128, 83, 85, 82, 70, 65, 67, 197, 83, 85, 82, 69, 128, + 83, 85, 82, 65, 78, 71, 128, 83, 85, 82, 57, 128, 83, 85, 82, 128, 83, + 85, 210, 83, 85, 80, 82, 65, 76, 73, 78, 69, 65, 210, 83, 85, 80, 69, 82, + 86, 73, 83, 69, 128, 83, 85, 80, 69, 82, 86, 73, 76, 76, 65, 73, 78, 128, + 83, 85, 80, 69, 82, 83, 69, 84, 128, 83, 85, 80, 69, 82, 83, 69, 212, 83, + 85, 80, 69, 82, 83, 67, 82, 73, 80, 212, 83, 85, 80, 69, 82, 73, 77, 80, + 79, 83, 69, 196, 83, 85, 80, 69, 82, 72, 69, 82, 79, 128, 83, 85, 80, 69, + 82, 70, 73, 88, 69, 196, 83, 85, 80, 69, 210, 83, 85, 80, 128, 83, 85, + 79, 88, 128, 83, 85, 79, 80, 128, 83, 85, 79, 128, 83, 85, 78, 83, 69, + 212, 83, 85, 78, 82, 73, 83, 69, 128, 83, 85, 78, 82, 73, 83, 197, 83, + 85, 78, 71, 76, 65, 83, 83, 69, 83, 128, 83, 85, 78, 71, 128, 83, 85, 78, + 70, 76, 79, 87, 69, 82, 128, 83, 85, 78, 68, 65, 78, 69, 83, 197, 83, 85, + 78, 128, 83, 85, 206, 83, 85, 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, + 84, 73, 79, 78, 128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, + 83, 72, 128, 83, 85, 77, 128, 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, + 85, 78, 128, 83, 85, 75, 85, 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, + 83, 85, 73, 84, 65, 66, 76, 69, 128, 83, 85, 73, 212, 83, 85, 72, 85, 82, + 128, 83, 85, 69, 128, 83, 85, 68, 50, 128, 83, 85, 68, 128, 83, 85, 67, + 75, 73, 78, 199, 83, 85, 67, 75, 69, 68, 128, 83, 85, 67, 203, 83, 85, + 67, 67, 69, 69, 68, 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, + 67, 69, 69, 68, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, + 84, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, + 84, 73, 84, 85, 84, 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, + 85, 66, 83, 69, 84, 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, + 73, 80, 212, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, + 73, 78, 69, 65, 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, + 85, 66, 76, 73, 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, + 84, 69, 45, 50, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, + 76, 73, 77, 65, 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 82, 128, 83, 85, + 66, 74, 79, 73, 78, 69, 196, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, + 73, 84, 79, 128, 83, 85, 66, 71, 82, 79, 85, 80, 128, 83, 85, 66, 71, 82, + 79, 85, 208, 83, 85, 66, 128, 83, 85, 65, 77, 128, 83, 85, 65, 69, 84, + 128, 83, 85, 65, 69, 78, 128, 83, 85, 65, 69, 128, 83, 85, 65, 66, 128, + 83, 85, 65, 128, 83, 85, 45, 56, 128, 83, 85, 45, 55, 128, 83, 85, 45, + 54, 128, 83, 85, 45, 53, 128, 83, 85, 45, 52, 128, 83, 85, 45, 51, 128, + 83, 85, 45, 50, 128, 83, 85, 45, 49, 128, 83, 213, 83, 84, 88, 128, 83, + 84, 87, 65, 128, 83, 84, 85, 80, 65, 128, 83, 84, 85, 70, 70, 69, 196, + 83, 84, 85, 68, 89, 128, 83, 84, 85, 68, 73, 207, 83, 84, 85, 67, 75, 45, + 79, 85, 212, 83, 84, 83, 128, 83, 84, 82, 79, 78, 199, 83, 84, 82, 79, + 75, 69, 83, 128, 83, 84, 82, 79, 75, 69, 211, 83, 84, 82, 79, 75, 69, 45, + 57, 128, 83, 84, 82, 79, 75, 69, 45, 56, 128, 83, 84, 82, 79, 75, 69, 45, + 55, 128, 83, 84, 82, 79, 75, 69, 45, 54, 128, 83, 84, 82, 79, 75, 69, 45, + 53, 128, 83, 84, 82, 79, 75, 69, 45, 52, 128, 83, 84, 82, 79, 75, 69, 45, + 51, 128, 83, 84, 82, 79, 75, 69, 45, 50, 128, 83, 84, 82, 79, 75, 69, 45, + 49, 49, 128, 83, 84, 82, 79, 75, 69, 45, 49, 48, 128, 83, 84, 82, 79, 75, + 69, 45, 49, 128, 83, 84, 82, 79, 75, 197, 83, 84, 82, 73, 80, 69, 128, + 83, 84, 82, 73, 78, 71, 128, 83, 84, 82, 73, 78, 199, 83, 84, 82, 73, 75, + 69, 84, 72, 82, 79, 85, 71, 72, 128, 83, 84, 82, 73, 75, 197, 83, 84, 82, + 73, 68, 69, 128, 83, 84, 82, 73, 67, 84, 76, 217, 83, 84, 82, 69, 84, 67, + 72, 69, 196, 83, 84, 82, 69, 84, 67, 72, 128, 83, 84, 82, 69, 83, 211, + 83, 84, 82, 69, 78, 71, 84, 72, 128, 83, 84, 82, 69, 65, 77, 69, 82, 128, + 83, 84, 82, 65, 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 87, 128, 83, + 84, 82, 65, 84, 85, 77, 45, 50, 128, 83, 84, 82, 65, 84, 85, 77, 128, 83, + 84, 82, 65, 84, 85, 205, 83, 84, 82, 65, 84, 73, 65, 206, 83, 84, 82, 65, + 73, 78, 69, 82, 128, 83, 84, 82, 65, 73, 71, 72, 84, 78, 69, 83, 83, 128, + 83, 84, 82, 65, 73, 71, 72, 84, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, + 84, 82, 65, 73, 70, 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, + 128, 83, 84, 79, 86, 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, + 87, 65, 84, 67, 72, 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, + 80, 80, 65, 71, 69, 128, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, + 79, 78, 69, 128, 83, 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, + 73, 82, 82, 85, 208, 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, + 83, 84, 73, 76, 197, 83, 84, 73, 71, 77, 65, 128, 83, 84, 73, 67, 75, 73, + 78, 199, 83, 84, 73, 67, 203, 83, 84, 69, 84, 72, 79, 83, 67, 79, 80, 69, + 128, 83, 84, 69, 82, 69, 79, 128, 83, 84, 69, 80, 128, 83, 84, 69, 78, + 79, 71, 82, 65, 80, 72, 73, 195, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, + 217, 83, 84, 69, 65, 77, 73, 78, 199, 83, 84, 69, 65, 77, 128, 83, 84, + 69, 65, 205, 83, 84, 65, 86, 82, 79, 85, 128, 83, 84, 65, 86, 82, 79, 83, + 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 65, 85, 82, 79, 83, 128, 83, + 84, 65, 84, 85, 197, 83, 84, 65, 84, 73, 79, 78, 128, 83, 84, 65, 84, 69, + 82, 83, 128, 83, 84, 65, 84, 69, 128, 83, 84, 65, 82, 84, 73, 78, 199, + 83, 84, 65, 82, 84, 128, 83, 84, 65, 82, 212, 83, 84, 65, 82, 83, 128, + 83, 84, 65, 82, 82, 69, 196, 83, 84, 65, 82, 75, 128, 83, 84, 65, 82, + 128, 83, 84, 65, 210, 83, 84, 65, 78, 68, 83, 84, 73, 76, 76, 128, 83, + 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, + 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, + 69, 65, 75, 73, 78, 199, 83, 80, 69, 65, 75, 69, 82, 128, 83, 80, 69, 65, + 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, 79, 45, 69, 86, 73, 204, 83, 80, + 65, 84, 72, 73, 128, 83, 80, 65, 82, 75, 76, 73, 78, 199, 83, 80, 65, 82, + 75, 76, 69, 83, 128, 83, 80, 65, 82, 75, 76, 69, 82, 128, 83, 80, 65, 82, + 75, 76, 69, 128, 83, 80, 65, 71, 72, 69, 84, 84, 73, 128, 83, 80, 65, 68, + 69, 83, 128, 83, 80, 65, 68, 197, 83, 80, 65, 67, 73, 78, 199, 83, 80, + 65, 67, 197, 83, 80, 65, 128, 83, 79, 89, 79, 77, 66, 207, 83, 79, 89, + 128, 83, 79, 87, 73, 76, 207, 83, 79, 87, 128, 83, 79, 85, 84, 72, 69, + 82, 206, 83, 79, 85, 84, 72, 45, 83, 76, 65, 86, 69, 217, 83, 79, 85, 84, + 200, 83, 79, 85, 82, 67, 69, 128, 83, 79, 85, 78, 68, 128, 83, 79, 85, + 78, 196, 83, 79, 85, 78, 65, 80, 128, 83, 79, 85, 128, 83, 79, 83, 128, + 83, 79, 82, 193, 83, 79, 81, 128, 83, 79, 79, 206, 83, 79, 78, 74, 65, + 77, 128, 83, 79, 78, 71, 128, 83, 79, 78, 128, 83, 79, 77, 80, 69, 78, + 199, 83, 79, 77, 128, 83, 79, 76, 73, 68, 85, 83, 128, 83, 79, 76, 73, + 68, 85, 211, 83, 79, 76, 73, 196, 83, 79, 76, 68, 73, 69, 82, 128, 83, + 79, 72, 128, 83, 79, 71, 68, 73, 65, 206, 83, 79, 70, 84, 87, 65, 82, 69, + 45, 70, 85, 78, 67, 84, 73, 79, 206, 83, 79, 70, 84, 78, 69, 83, 83, 128, + 83, 79, 70, 84, 66, 65, 76, 76, 128, 83, 79, 70, 212, 83, 79, 198, 83, + 79, 67, 75, 83, 128, 83, 79, 67, 73, 69, 84, 89, 128, 83, 79, 67, 67, 69, + 210, 83, 79, 65, 80, 128, 83, 79, 65, 128, 83, 79, 45, 55, 128, 83, 79, + 45, 54, 128, 83, 79, 45, 53, 128, 83, 79, 45, 52, 128, 83, 79, 45, 51, + 128, 83, 79, 45, 50, 128, 83, 79, 45, 49, 128, 83, 207, 83, 78, 79, 87, + 77, 65, 78, 128, 83, 78, 79, 87, 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, + 75, 69, 128, 83, 78, 79, 87, 66, 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, + 87, 128, 83, 78, 79, 215, 83, 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, + 83, 78, 69, 69, 90, 73, 78, 199, 83, 78, 65, 208, 83, 78, 65, 75, 69, + 128, 83, 78, 65, 75, 197, 83, 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, + 79, 75, 73, 78, 199, 83, 77, 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, + 78, 199, 83, 77, 73, 76, 69, 128, 83, 77, 73, 76, 197, 83, 77, 69, 65, + 82, 128, 83, 77, 65, 83, 200, 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, + 76, 76, 128, 83, 76, 85, 82, 128, 83, 76, 79, 87, 76, 89, 128, 83, 76, + 79, 87, 128, 83, 76, 79, 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 84, + 72, 128, 83, 76, 79, 212, 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, + 69, 128, 83, 76, 79, 65, 206, 83, 76, 73, 78, 71, 128, 83, 76, 73, 71, + 72, 84, 76, 217, 83, 76, 73, 68, 73, 78, 71, 128, 83, 76, 73, 68, 69, 82, + 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, 197, 83, 76, 69, 85, 84, + 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, 199, 83, 76, + 69, 69, 208, 83, 76, 69, 68, 128, 83, 76, 65, 86, 79, 78, 73, 195, 83, + 76, 65, 86, 69, 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, 200, 83, + 76, 65, 78, 84, 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, 83, 75, + 85, 78, 75, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, 76, 204, 83, 75, + 76, 73, 82, 79, 206, 83, 75, 73, 78, 128, 83, 75, 73, 69, 82, 128, 83, + 75, 201, 83, 75, 69, 87, 69, 196, 83, 75, 65, 84, 69, 66, 79, 65, 82, 68, + 128, 83, 75, 65, 84, 69, 128, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, + 197, 83, 73, 88, 84, 89, 45, 70, 79, 85, 82, 84, 72, 83, 128, 83, 73, 88, + 84, 89, 45, 70, 79, 85, 82, 84, 72, 128, 83, 73, 88, 84, 89, 45, 70, 79, + 85, 82, 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, + 88, 84, 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, + 83, 73, 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, + 84, 72, 45, 50, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 45, 49, 128, 83, + 73, 88, 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, + 83, 73, 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, + 45, 84, 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, + 83, 73, 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, + 83, 73, 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 73, + 78, 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 128, 83, + 73, 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 73, 79, 83, + 45, 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 45, + 75, 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, 45, 80, 72, 73, 69, 85, 80, + 72, 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, 73, 79, 83, 128, 83, 73, 79, + 83, 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, 83, 45, 77, 73, 69, 85, 77, + 128, 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 73, 79, 83, + 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, 80, 128, 83, 73, 79, + 83, 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, 83, 45, 72, 73, 69, 85, 72, + 128, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 83, 73, 79, 83, 45, 67, + 72, 73, 69, 85, 67, 72, 128, 83, 73, 79, 211, 83, 73, 78, 85, 83, 79, 73, + 196, 83, 73, 78, 79, 76, 79, 71, 73, 67, 65, 204, 83, 73, 78, 78, 89, 73, + 73, 89, 72, 69, 128, 83, 73, 78, 75, 73, 78, 71, 128, 83, 73, 78, 71, 76, + 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, 83, 73, 78, 71, 76, 69, 45, 83, + 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, 197, + 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, 71, 76, 197, 83, 73, 78, 71, 65, + 65, 84, 128, 83, 73, 78, 197, 83, 73, 78, 68, 72, 201, 83, 73, 206, 83, + 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, 83, 128, 83, 73, 77, 85, 76, 84, + 65, 78, 69, 79, 85, 211, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, + 77, 73, 76, 65, 82, 128, 83, 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, + 83, 73, 211, 83, 73, 77, 65, 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, + 128, 83, 73, 76, 86, 69, 82, 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, + 81, 85, 193, 83, 73, 76, 72, 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, + 79, 85, 69, 84, 84, 197, 83, 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, + 83, 73, 75, 50, 128, 83, 73, 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, + 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, 73, 71, + 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, 83, 73, + 68, 69, 87, 65, 89, 211, 83, 73, 68, 69, 128, 83, 73, 68, 197, 83, 73, + 68, 68, 72, 73, 128, 83, 73, 68, 68, 72, 65, 77, 128, 83, 73, 68, 68, 72, + 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, 69, + 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, 73, 45, 54, 128, 83, 73, 45, + 53, 128, 83, 73, 45, 52, 128, 83, 73, 45, 51, 128, 83, 73, 45, 50, 128, + 83, 73, 45, 49, 128, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, 128, + 83, 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, 83, + 72, 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, 79, + 89, 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, 73, + 73, 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, 83, + 72, 87, 65, 65, 128, 83, 72, 87, 65, 128, 83, 72, 86, 128, 83, 72, 85, + 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, 84, 84, 76, 69, 67, 79, 67, 75, + 128, 83, 72, 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, 128, + 83, 72, 85, 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, 128, + 83, 72, 85, 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, 72, + 85, 70, 70, 76, 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, 72, + 85, 69, 84, 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 65, 78, 71, 88, + 73, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, 72, + 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 85, 71, 128, + 83, 72, 82, 73, 78, 69, 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, + 73, 128, 83, 72, 82, 73, 128, 83, 72, 79, 89, 128, 83, 72, 79, 88, 128, + 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, 85, 76, 68, 69, 82, 69, 196, 83, + 72, 79, 85, 76, 68, 69, 210, 83, 72, 79, 85, 128, 83, 72, 79, 84, 128, + 83, 72, 79, 82, 84, 83, 128, 83, 72, 79, 82, 84, 211, 83, 72, 79, 82, 84, + 72, 65, 78, 196, 83, 72, 79, 82, 84, 69, 78, 69, 82, 128, 83, 72, 79, 82, + 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 89, + 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 84, 89, 210, 83, 72, + 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, 79, 204, 83, 72, 79, 82, 84, 45, + 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, + 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 77, 65, + 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 72, 65, 71, 65, 76, + 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 66, 74, 65, 82, 75, 65, + 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 65, 210, 83, 72, 79, 82, + 84, 128, 83, 72, 79, 82, 212, 83, 72, 79, 81, 128, 83, 72, 79, 209, 83, + 72, 79, 80, 80, 73, 78, 199, 83, 72, 79, 80, 128, 83, 72, 79, 79, 84, 73, + 78, 199, 83, 72, 79, 79, 84, 128, 83, 72, 79, 79, 73, 128, 83, 72, 79, + 79, 128, 83, 72, 79, 71, 201, 83, 72, 79, 199, 83, 72, 79, 69, 83, 128, + 83, 72, 79, 69, 128, 83, 72, 79, 197, 83, 72, 79, 67, 75, 69, 196, 83, + 72, 79, 65, 128, 83, 72, 79, 128, 83, 72, 73, 89, 89, 65, 65, 76, 65, 65, + 128, 83, 72, 73, 84, 65, 128, 83, 72, 73, 84, 193, 83, 72, 73, 82, 212, + 83, 72, 73, 82, 65, 69, 128, 83, 72, 73, 82, 128, 83, 72, 73, 210, 83, + 72, 73, 81, 128, 83, 72, 73, 78, 84, 207, 83, 72, 73, 78, 73, 71, 128, + 83, 72, 73, 78, 68, 193, 83, 72, 73, 206, 83, 72, 73, 77, 65, 128, 83, + 72, 73, 77, 193, 83, 72, 73, 77, 128, 83, 72, 73, 205, 83, 72, 73, 73, + 78, 128, 83, 72, 73, 73, 128, 83, 72, 73, 70, 212, 83, 72, 73, 69, 76, + 68, 128, 83, 72, 73, 68, 128, 83, 72, 73, 196, 83, 72, 72, 65, 128, 83, + 72, 72, 193, 83, 72, 69, 88, 128, 83, 72, 69, 86, 65, 128, 83, 72, 69, + 85, 88, 128, 83, 72, 69, 85, 79, 81, 128, 83, 72, 69, 85, 65, 69, 81, 84, + 85, 128, 83, 72, 69, 85, 65, 69, 81, 128, 83, 72, 69, 85, 65, 69, 128, + 83, 72, 69, 84, 128, 83, 72, 69, 212, 83, 72, 69, 83, 72, 76, 65, 77, + 128, 83, 72, 69, 83, 72, 73, 71, 128, 83, 72, 69, 83, 72, 73, 199, 83, + 72, 69, 83, 72, 50, 128, 83, 72, 69, 83, 72, 128, 83, 72, 69, 83, 200, + 83, 72, 69, 81, 69, 204, 83, 72, 69, 80, 128, 83, 72, 69, 78, 128, 83, + 72, 69, 76, 76, 128, 83, 72, 69, 76, 204, 83, 72, 69, 76, 70, 128, 83, + 72, 69, 73, 128, 83, 72, 69, 71, 57, 128, 83, 72, 69, 69, 80, 128, 83, + 72, 69, 69, 78, 85, 128, 83, 72, 69, 69, 78, 128, 83, 72, 69, 69, 206, + 83, 72, 69, 69, 128, 83, 72, 69, 45, 71, 79, 65, 84, 128, 83, 72, 197, + 83, 72, 67, 72, 79, 79, 73, 128, 83, 72, 67, 72, 65, 128, 83, 72, 65, 89, + 128, 83, 72, 65, 88, 128, 83, 72, 65, 86, 73, 89, 65, 78, 73, 128, 83, + 72, 65, 86, 73, 65, 206, 83, 72, 65, 86, 69, 196, 83, 72, 65, 85, 128, + 83, 72, 65, 84, 128, 83, 72, 65, 82, 85, 128, 83, 72, 65, 82, 213, 83, + 72, 65, 82, 80, 128, 83, 72, 65, 82, 208, 83, 72, 65, 82, 75, 128, 83, + 72, 65, 82, 65, 68, 193, 83, 72, 65, 82, 65, 128, 83, 72, 65, 82, 50, + 128, 83, 72, 65, 82, 178, 83, 72, 65, 80, 73, 78, 71, 128, 83, 72, 65, + 80, 69, 83, 128, 83, 72, 65, 80, 197, 83, 72, 65, 80, 128, 83, 72, 65, + 78, 71, 128, 83, 72, 65, 78, 128, 83, 72, 65, 206, 83, 72, 65, 77, 82, + 79, 67, 75, 128, 83, 72, 65, 76, 83, 72, 69, 76, 69, 84, 128, 83, 72, 65, + 76, 76, 79, 215, 83, 72, 65, 75, 84, 73, 128, 83, 72, 65, 75, 73, 78, 71, + 128, 83, 72, 65, 75, 73, 78, 199, 83, 72, 65, 75, 69, 82, 128, 83, 72, + 65, 75, 128, 83, 72, 65, 73, 128, 83, 72, 65, 70, 84, 128, 83, 72, 65, + 70, 212, 83, 72, 65, 68, 79, 87, 69, 196, 83, 72, 65, 68, 69, 196, 83, + 72, 65, 68, 69, 128, 83, 72, 65, 68, 68, 65, 128, 83, 72, 65, 68, 68, + 193, 83, 72, 65, 68, 128, 83, 72, 65, 196, 83, 72, 65, 66, 54, 128, 83, + 72, 65, 65, 128, 83, 72, 65, 54, 128, 83, 72, 65, 182, 83, 72, 65, 51, + 128, 83, 72, 65, 179, 83, 71, 82, 193, 83, 71, 79, 210, 83, 71, 67, 128, + 83, 71, 65, 215, 83, 71, 65, 194, 83, 71, 128, 83, 69, 89, 75, 128, 83, + 69, 88, 84, 85, 76, 193, 83, 69, 88, 84, 73, 76, 69, 128, 83, 69, 88, 84, + 65, 78, 211, 83, 69, 86, 69, 82, 65, 78, 67, 69, 128, 83, 69, 86, 69, 78, + 84, 89, 128, 83, 69, 86, 69, 78, 84, 217, 83, 69, 86, 69, 78, 84, 72, + 128, 83, 69, 86, 69, 78, 84, 69, 69, 78, 128, 83, 69, 86, 69, 78, 84, 69, + 69, 206, 83, 69, 86, 69, 78, 45, 84, 72, 73, 82, 84, 89, 128, 83, 69, 86, + 69, 206, 83, 69, 85, 88, 128, 83, 69, 85, 78, 89, 65, 77, 128, 83, 69, + 85, 65, 69, 81, 128, 83, 69, 84, 70, 79, 78, 128, 83, 69, 83, 84, 69, 82, + 84, 73, 85, 211, 83, 69, 83, 81, 85, 73, 81, 85, 65, 68, 82, 65, 84, 69, + 128, 83, 69, 83, 65, 77, 197, 83, 69, 82, 86, 73, 67, 197, 83, 69, 82, + 73, 79, 85, 211, 83, 69, 82, 73, 70, 83, 128, 83, 69, 82, 73, 70, 211, + 83, 69, 82, 73, 70, 128, 83, 69, 81, 85, 69, 78, 84, 73, 65, 76, 128, 83, + 69, 81, 85, 69, 78, 67, 197, 83, 69, 80, 84, 85, 80, 76, 197, 83, 69, 80, + 84, 69, 77, 66, 69, 82, 128, 83, 69, 80, 65, 82, 65, 84, 79, 82, 128, 83, + 69, 80, 65, 82, 65, 84, 79, 210, 83, 69, 80, 65, 82, 65, 84, 69, 196, 83, + 69, 78, 84, 79, 128, 83, 69, 78, 84, 73, 128, 83, 69, 78, 84, 65, 71, 79, + 78, 128, 83, 69, 77, 85, 78, 67, 73, 193, 83, 69, 77, 75, 65, 84, 72, + 128, 83, 69, 77, 75, 128, 83, 69, 77, 73, 86, 79, 87, 69, 204, 83, 69, + 77, 73, 83, 79, 70, 212, 83, 69, 77, 73, 83, 69, 88, 84, 73, 76, 69, 128, + 83, 69, 77, 73, 77, 73, 78, 73, 77, 193, 83, 69, 77, 73, 68, 73, 82, 69, + 67, 212, 83, 69, 77, 73, 67, 79, 76, 79, 78, 128, 83, 69, 77, 73, 67, 79, + 76, 79, 206, 83, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 210, 83, 69, 77, + 73, 67, 73, 82, 67, 76, 197, 83, 69, 77, 73, 66, 82, 69, 86, 73, 211, 83, + 69, 77, 73, 45, 86, 79, 73, 67, 69, 196, 83, 69, 76, 70, 73, 69, 128, 83, + 69, 76, 70, 128, 83, 69, 76, 69, 78, 65, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 57, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 56, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 57, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 53, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 57, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 50, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 55, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 56, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 52, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 56, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 56, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 49, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 56, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 57, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 55, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 54, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 55, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 51, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 55, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 48, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, + 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 56, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, + 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 53, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 54, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, + 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 50, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, + 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 56, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 55, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 53, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 52, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 50, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 49, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 57, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 55, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 54, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 52, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 51, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 49, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 48, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 57, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 54, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 51, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 48, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 56, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 54, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 53, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 53, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, + 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 50, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 57, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, + 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 54, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 52, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 51, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 50, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 50, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, + 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 55, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 54, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 50, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, + 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 51, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 50, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 48, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 50, 50, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, + 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 55, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 50, 50, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 52, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 51, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 50, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 48, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 50, 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 56, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 55, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 50, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 52, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 51, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, + 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 48, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 56, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 55, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 48, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, + 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 52, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 48, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 49, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 48, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 57, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 57, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 54, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 57, 53, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 51, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 50, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 55, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 54, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 56, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 51, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 50, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, + 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 55, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 55, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 54, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, + 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 51, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 55, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 48, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, + 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 55, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 54, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 52, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 51, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 54, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 48, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 56, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 55, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 52, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 49, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 48, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 56, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 52, 55, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 53, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 52, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 49, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 48, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 57, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 56, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 51, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 53, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 52, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, + 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 49, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 57, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 56, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, + 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 53, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 50, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 49, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 57, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 49, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 54, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 53, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 50, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 49, 49, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 57, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 48, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 48, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 54, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 48, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 51, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 50, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 48, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 48, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 128, + 83, 69, 76, 69, 67, 84, 79, 210, 83, 69, 76, 69, 67, 84, 69, 196, 83, 69, + 73, 83, 77, 65, 128, 83, 69, 73, 83, 77, 193, 83, 69, 72, 128, 83, 69, + 71, 79, 76, 128, 83, 69, 71, 78, 79, 128, 83, 69, 71, 77, 69, 78, 84, + 128, 83, 69, 69, 86, 128, 83, 69, 69, 78, 85, 128, 83, 69, 69, 78, 128, + 83, 69, 69, 206, 83, 69, 69, 68, 76, 73, 78, 71, 128, 83, 69, 69, 45, 78, + 79, 45, 69, 86, 73, 204, 83, 69, 68, 78, 65, 128, 83, 69, 67, 84, 79, 82, + 128, 83, 69, 67, 84, 73, 79, 78, 128, 83, 69, 67, 84, 73, 79, 206, 83, + 69, 67, 82, 69, 84, 128, 83, 69, 67, 65, 78, 84, 128, 83, 69, 66, 65, 84, + 66, 69, 73, 212, 83, 69, 65, 84, 128, 83, 69, 65, 76, 128, 83, 69, 65, + 71, 85, 76, 204, 83, 69, 45, 53, 128, 83, 69, 45, 52, 128, 83, 69, 45, + 51, 128, 83, 68, 79, 78, 199, 83, 68, 128, 83, 67, 87, 65, 128, 83, 67, + 82, 85, 80, 76, 69, 128, 83, 67, 82, 79, 76, 76, 128, 83, 67, 82, 73, 80, + 84, 128, 83, 67, 82, 69, 69, 78, 128, 83, 67, 82, 69, 69, 206, 83, 67, + 82, 69, 65, 77, 73, 78, 199, 83, 67, 79, 82, 80, 73, 85, 83, 128, 83, 67, + 79, 82, 80, 73, 79, 78, 128, 83, 67, 79, 82, 69, 128, 83, 67, 79, 79, 84, + 69, 82, 128, 83, 67, 73, 83, 83, 79, 82, 83, 128, 83, 67, 73, 128, 83, + 67, 72, 87, 65, 128, 83, 67, 72, 87, 193, 83, 67, 72, 82, 79, 69, 68, 69, + 82, 128, 83, 67, 72, 79, 79, 76, 128, 83, 67, 72, 79, 79, 204, 83, 67, + 72, 79, 76, 65, 82, 128, 83, 67, 72, 69, 77, 193, 83, 67, 69, 80, 84, 69, + 210, 83, 67, 65, 82, 70, 128, 83, 67, 65, 78, 68, 73, 67, 85, 83, 128, + 83, 67, 65, 78, 68, 73, 67, 85, 211, 83, 67, 65, 206, 83, 67, 65, 76, 69, + 83, 128, 83, 66, 85, 194, 83, 66, 82, 85, 204, 83, 65, 89, 73, 83, 201, + 83, 65, 89, 65, 78, 78, 65, 128, 83, 65, 89, 128, 83, 65, 88, 79, 80, 72, + 79, 78, 69, 128, 83, 65, 88, 73, 77, 65, 84, 65, 128, 83, 65, 87, 65, 78, + 128, 83, 65, 87, 128, 83, 65, 86, 79, 85, 82, 73, 78, 199, 83, 65, 85, + 82, 79, 80, 79, 68, 128, 83, 65, 85, 82, 65, 83, 72, 84, 82, 193, 83, 65, + 85, 73, 76, 128, 83, 65, 85, 67, 69, 82, 128, 83, 65, 84, 85, 82, 78, + 128, 83, 65, 84, 75, 65, 65, 78, 75, 85, 85, 128, 83, 65, 84, 75, 65, 65, + 78, 128, 83, 65, 84, 69, 76, 76, 73, 84, 69, 128, 83, 65, 84, 69, 76, 76, + 73, 84, 197, 83, 65, 84, 67, 72, 69, 76, 128, 83, 65, 84, 65, 78, 71, 65, + 128, 83, 65, 83, 72, 128, 83, 65, 83, 65, 75, 128, 83, 65, 82, 73, 128, + 83, 65, 82, 193, 83, 65, 82, 128, 83, 65, 81, 128, 83, 65, 80, 65, 128, + 83, 65, 78, 89, 79, 79, 71, 193, 83, 65, 78, 89, 65, 75, 193, 83, 65, 78, + 84, 73, 73, 77, 85, 128, 83, 65, 78, 83, 75, 82, 73, 212, 83, 65, 78, 78, + 89, 65, 128, 83, 65, 78, 71, 65, 50, 128, 83, 65, 78, 68, 87, 73, 67, 72, + 128, 83, 65, 78, 68, 72, 201, 83, 65, 78, 68, 65, 76, 128, 83, 65, 78, + 65, 72, 128, 83, 65, 78, 128, 83, 65, 77, 89, 79, 203, 83, 65, 77, 86, + 65, 84, 128, 83, 65, 77, 80, 73, 128, 83, 65, 77, 80, 72, 65, 79, 128, + 83, 65, 77, 75, 65, 128, 83, 65, 77, 69, 75, 72, 128, 83, 65, 77, 69, 75, + 200, 83, 65, 77, 66, 65, 128, 83, 65, 77, 65, 82, 73, 84, 65, 206, 83, + 65, 77, 128, 83, 65, 76, 84, 73, 82, 69, 128, 83, 65, 76, 84, 73, 76, 76, + 79, 128, 83, 65, 76, 84, 45, 50, 128, 83, 65, 76, 84, 128, 83, 65, 76, + 212, 83, 65, 76, 76, 65, 76, 76, 65, 72, 79, 213, 83, 65, 76, 76, 193, + 83, 65, 76, 65, 205, 83, 65, 76, 65, 68, 128, 83, 65, 76, 65, 128, 83, + 65, 76, 45, 65, 77, 77, 79, 78, 73, 65, 67, 128, 83, 65, 76, 128, 83, 65, + 75, 84, 65, 128, 83, 65, 75, 79, 84, 128, 83, 65, 75, 73, 78, 128, 83, + 65, 75, 72, 193, 83, 65, 75, 69, 85, 65, 69, 128, 83, 65, 75, 197, 83, + 65, 74, 68, 65, 72, 128, 83, 65, 73, 76, 66, 79, 65, 84, 128, 83, 65, 73, + 76, 128, 83, 65, 73, 75, 85, 82, 85, 128, 83, 65, 72, 128, 83, 65, 71, + 73, 84, 84, 65, 82, 73, 85, 83, 128, 83, 65, 71, 65, 128, 83, 65, 71, + 128, 83, 65, 199, 83, 65, 70, 72, 65, 128, 83, 65, 70, 69, 84, 217, 83, + 65, 68, 72, 69, 128, 83, 65, 68, 72, 197, 83, 65, 68, 69, 128, 83, 65, + 68, 128, 83, 65, 196, 83, 65, 67, 82, 73, 70, 73, 67, 73, 65, 204, 83, + 65, 65, 73, 128, 83, 65, 65, 68, 72, 85, 128, 83, 65, 45, 73, 128, 83, + 65, 45, 56, 128, 83, 65, 45, 55, 128, 83, 65, 45, 54, 128, 83, 65, 45, + 53, 128, 83, 65, 45, 52, 128, 83, 65, 45, 51, 128, 83, 65, 45, 50, 128, + 83, 65, 45, 49, 128, 83, 48, 52, 54, 128, 83, 48, 52, 53, 128, 83, 48, + 52, 52, 128, 83, 48, 52, 51, 128, 83, 48, 52, 50, 128, 83, 48, 52, 49, + 128, 83, 48, 52, 48, 128, 83, 48, 51, 57, 128, 83, 48, 51, 56, 128, 83, + 48, 51, 55, 128, 83, 48, 51, 54, 128, 83, 48, 51, 53, 65, 128, 83, 48, + 51, 53, 128, 83, 48, 51, 52, 128, 83, 48, 51, 51, 128, 83, 48, 51, 50, + 128, 83, 48, 51, 49, 128, 83, 48, 51, 48, 128, 83, 48, 50, 57, 128, 83, + 48, 50, 56, 128, 83, 48, 50, 55, 128, 83, 48, 50, 54, 66, 128, 83, 48, + 50, 54, 65, 128, 83, 48, 50, 54, 128, 83, 48, 50, 53, 128, 83, 48, 50, + 52, 128, 83, 48, 50, 51, 128, 83, 48, 50, 50, 128, 83, 48, 50, 49, 128, + 83, 48, 50, 48, 128, 83, 48, 49, 57, 128, 83, 48, 49, 56, 128, 83, 48, + 49, 55, 65, 128, 83, 48, 49, 55, 128, 83, 48, 49, 54, 128, 83, 48, 49, + 53, 128, 83, 48, 49, 52, 66, 128, 83, 48, 49, 52, 65, 128, 83, 48, 49, + 52, 128, 83, 48, 49, 51, 128, 83, 48, 49, 50, 128, 83, 48, 49, 49, 128, + 83, 48, 49, 48, 128, 83, 48, 48, 57, 128, 83, 48, 48, 56, 128, 83, 48, + 48, 55, 128, 83, 48, 48, 54, 65, 128, 83, 48, 48, 54, 128, 83, 48, 48, + 53, 128, 83, 48, 48, 52, 128, 83, 48, 48, 51, 128, 83, 48, 48, 50, 65, + 128, 83, 48, 48, 50, 128, 83, 48, 48, 49, 128, 83, 45, 87, 128, 83, 45, + 83, 72, 65, 80, 69, 196, 82, 89, 89, 128, 82, 89, 88, 128, 82, 89, 84, + 128, 82, 89, 82, 88, 128, 82, 89, 82, 128, 82, 89, 80, 128, 82, 87, 79, + 79, 128, 82, 87, 79, 128, 82, 87, 73, 73, 128, 82, 87, 73, 128, 82, 87, + 69, 69, 128, 82, 87, 69, 128, 82, 87, 65, 72, 65, 128, 82, 87, 65, 65, + 128, 82, 87, 65, 128, 82, 85, 88, 128, 82, 85, 85, 66, 85, 82, 85, 128, + 82, 85, 85, 128, 82, 85, 84, 128, 82, 85, 83, 83, 73, 65, 206, 82, 85, + 83, 73, 128, 82, 85, 82, 88, 128, 82, 85, 82, 128, 82, 85, 80, 73, 73, + 128, 82, 85, 80, 69, 197, 82, 85, 80, 128, 82, 85, 79, 88, 128, 82, 85, + 79, 80, 128, 82, 85, 79, 128, 82, 85, 78, 79, 85, 84, 128, 82, 85, 78, + 78, 73, 78, 199, 82, 85, 78, 78, 69, 82, 128, 82, 85, 78, 73, 195, 82, + 85, 78, 128, 82, 85, 77, 201, 82, 85, 77, 65, 201, 82, 85, 77, 128, 82, + 85, 205, 82, 85, 76, 69, 82, 128, 82, 85, 76, 69, 45, 68, 69, 76, 65, 89, + 69, 68, 128, 82, 85, 76, 69, 128, 82, 85, 76, 65, 73, 128, 82, 85, 75, + 75, 65, 75, 72, 65, 128, 82, 85, 73, 83, 128, 82, 85, 71, 66, 217, 82, + 85, 68, 73, 77, 69, 78, 84, 193, 82, 85, 66, 76, 197, 82, 85, 194, 82, + 85, 65, 128, 82, 85, 45, 54, 128, 82, 85, 45, 53, 128, 82, 85, 45, 52, + 128, 82, 85, 45, 51, 128, 82, 85, 45, 50, 128, 82, 85, 45, 49, 128, 82, + 84, 72, 65, 78, 199, 82, 84, 69, 128, 82, 84, 65, 71, 83, 128, 82, 84, + 65, 71, 211, 82, 82, 89, 88, 128, 82, 82, 89, 84, 128, 82, 82, 89, 82, + 88, 128, 82, 82, 89, 82, 128, 82, 82, 89, 80, 128, 82, 82, 85, 88, 128, + 82, 82, 85, 85, 128, 82, 82, 85, 84, 128, 82, 82, 85, 82, 88, 128, 82, + 82, 85, 82, 128, 82, 82, 85, 80, 128, 82, 82, 85, 79, 88, 128, 82, 82, + 85, 79, 128, 82, 82, 85, 128, 82, 82, 82, 65, 128, 82, 82, 79, 88, 128, + 82, 82, 79, 84, 128, 82, 82, 79, 80, 128, 82, 82, 79, 79, 128, 82, 82, + 79, 128, 82, 82, 73, 73, 128, 82, 82, 73, 128, 82, 82, 69, 88, 128, 82, + 82, 69, 84, 128, 82, 82, 69, 80, 128, 82, 82, 69, 72, 128, 82, 82, 69, + 200, 82, 82, 69, 69, 128, 82, 82, 69, 128, 82, 82, 65, 88, 128, 82, 82, + 65, 85, 128, 82, 82, 65, 73, 128, 82, 82, 65, 65, 128, 82, 79, 87, 66, + 79, 65, 84, 128, 82, 79, 85, 78, 68, 69, 196, 82, 79, 85, 78, 68, 45, 84, + 73, 80, 80, 69, 196, 82, 79, 84, 85, 78, 68, 65, 128, 82, 79, 84, 65, 84, + 73, 79, 78, 83, 128, 82, 79, 84, 65, 84, 73, 79, 78, 45, 87, 65, 76, 76, + 80, 76, 65, 78, 197, 82, 79, 84, 65, 84, 73, 79, 78, 45, 70, 76, 79, 79, + 82, 80, 76, 65, 78, 197, 82, 79, 84, 65, 84, 73, 79, 78, 128, 82, 79, 84, + 65, 84, 73, 79, 206, 82, 79, 84, 65, 84, 69, 196, 82, 79, 83, 72, 128, + 82, 79, 83, 69, 84, 84, 69, 128, 82, 79, 83, 69, 128, 82, 79, 79, 84, + 128, 82, 79, 79, 83, 84, 69, 82, 128, 82, 79, 79, 77, 128, 82, 79, 79, + 75, 128, 82, 79, 79, 203, 82, 79, 79, 70, 128, 82, 79, 77, 65, 78, 73, + 65, 206, 82, 79, 77, 65, 206, 82, 79, 77, 128, 82, 79, 76, 76, 73, 78, + 199, 82, 79, 76, 76, 69, 210, 82, 79, 76, 76, 69, 68, 45, 85, 208, 82, + 79, 76, 204, 82, 79, 72, 73, 78, 71, 89, 193, 82, 79, 71, 128, 82, 79, + 196, 82, 79, 67, 75, 69, 84, 128, 82, 79, 67, 203, 82, 79, 67, 128, 82, + 79, 66, 79, 212, 82, 79, 66, 65, 84, 128, 82, 79, 65, 83, 84, 69, 196, + 82, 79, 65, 82, 128, 82, 79, 65, 128, 82, 79, 45, 54, 128, 82, 79, 45, + 53, 128, 82, 79, 45, 52, 128, 82, 79, 45, 51, 128, 82, 79, 45, 50, 128, + 82, 79, 45, 49, 128, 82, 78, 89, 73, 78, 199, 82, 78, 79, 79, 78, 128, + 82, 78, 79, 79, 206, 82, 78, 65, 205, 82, 77, 84, 128, 82, 76, 79, 128, + 82, 76, 77, 128, 82, 76, 73, 128, 82, 76, 69, 128, 82, 74, 69, 211, 82, + 74, 69, 128, 82, 74, 197, 82, 73, 86, 69, 82, 128, 82, 73, 84, 85, 65, + 76, 128, 82, 73, 84, 84, 79, 82, 85, 128, 82, 73, 84, 83, 73, 128, 82, + 73, 83, 73, 78, 199, 82, 73, 83, 72, 128, 82, 73, 82, 65, 128, 82, 73, + 80, 80, 76, 197, 82, 73, 80, 128, 82, 73, 78, 71, 211, 82, 73, 78, 71, + 73, 78, 199, 82, 73, 78, 71, 69, 196, 82, 73, 78, 70, 79, 82, 90, 65, 78, + 68, 79, 128, 82, 73, 206, 82, 73, 77, 71, 66, 65, 128, 82, 73, 77, 128, + 82, 73, 75, 82, 73, 75, 128, 82, 73, 71, 86, 69, 68, 73, 195, 82, 73, 71, + 72, 84, 87, 65, 82, 68, 83, 128, 82, 73, 71, 72, 84, 72, 65, 78, 196, 82, + 73, 71, 72, 84, 45, 84, 79, 45, 76, 69, 70, 212, 82, 73, 71, 72, 84, 45, + 83, 73, 68, 197, 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 79, 87, 69, 196, + 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 69, 196, 82, 73, 71, 72, 84, 45, + 80, 79, 73, 78, 84, 73, 78, 199, 82, 73, 71, 72, 84, 45, 76, 73, 71, 72, + 84, 69, 196, 82, 73, 71, 72, 84, 45, 72, 65, 78, 68, 69, 196, 82, 73, 71, + 72, 84, 45, 72, 65, 78, 196, 82, 73, 71, 72, 84, 45, 70, 65, 67, 73, 78, + 199, 82, 73, 71, 72, 84, 128, 82, 73, 70, 76, 69, 128, 82, 73, 69, 85, + 76, 45, 89, 69, 83, 73, 69, 85, 78, 71, 128, 82, 73, 69, 85, 76, 45, 89, + 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 45, 72, 73, 69, 85, 72, 128, 82, + 73, 69, 85, 76, 45, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 82, + 73, 69, 85, 76, 45, 84, 73, 75, 69, 85, 84, 45, 72, 73, 69, 85, 72, 128, + 82, 73, 69, 85, 76, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, + 45, 84, 72, 73, 69, 85, 84, 72, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, + 78, 71, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, + 78, 71, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, + 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 75, + 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 83, 73, 79, 83, 128, 82, + 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 84, 73, 75, 69, 85, 84, 128, + 82, 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 82, + 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 80, 72, 73, 69, 85, 80, 72, + 128, 82, 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 72, 73, 69, 85, 72, + 128, 82, 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, + 45, 80, 72, 73, 69, 85, 80, 72, 128, 82, 73, 69, 85, 76, 45, 80, 65, 78, + 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 78, 73, 69, 85, 78, 128, 82, + 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 83, 73, 79, 83, 128, 82, 73, + 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 75, 73, 89, 69, 79, 75, 128, 82, + 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 72, 73, 69, 85, 72, 128, 82, + 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76, 45, 75, + 73, 89, 69, 79, 75, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 75, + 73, 89, 69, 79, 75, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, 45, + 75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 75, 65, 80, 89, 69, + 79, 85, 78, 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 72, 73, 69, + 85, 72, 128, 82, 73, 69, 85, 76, 45, 67, 73, 69, 85, 67, 128, 82, 73, 69, + 85, 204, 82, 73, 69, 76, 128, 82, 73, 69, 69, 128, 82, 73, 67, 75, 83, + 72, 65, 87, 128, 82, 73, 67, 69, 77, 128, 82, 73, 67, 69, 128, 82, 73, + 67, 197, 82, 73, 66, 66, 79, 78, 128, 82, 73, 66, 66, 79, 206, 82, 73, + 65, 204, 82, 73, 45, 55, 128, 82, 73, 45, 54, 128, 82, 73, 45, 53, 128, + 82, 73, 45, 52, 128, 82, 73, 45, 51, 128, 82, 73, 45, 50, 128, 82, 73, + 45, 49, 128, 82, 72, 79, 84, 73, 195, 82, 72, 79, 128, 82, 72, 207, 82, + 72, 73, 78, 79, 67, 69, 82, 79, 83, 128, 82, 72, 65, 128, 82, 72, 128, + 82, 71, 89, 73, 78, 71, 83, 128, 82, 71, 89, 65, 78, 128, 82, 71, 89, + 193, 82, 69, 86, 79, 76, 86, 73, 78, 199, 82, 69, 86, 79, 76, 85, 84, 73, + 79, 78, 128, 82, 69, 86, 77, 65, 128, 82, 69, 86, 73, 65, 128, 82, 69, + 86, 69, 82, 83, 69, 68, 45, 83, 67, 72, 87, 65, 128, 82, 69, 86, 69, 82, + 83, 69, 68, 128, 82, 69, 86, 69, 82, 83, 69, 196, 82, 69, 86, 69, 82, 83, + 197, 82, 69, 85, 88, 128, 82, 69, 85, 128, 82, 69, 84, 85, 82, 78, 128, + 82, 69, 84, 85, 82, 206, 82, 69, 84, 82, 79, 70, 76, 69, 216, 82, 69, 84, + 82, 69, 65, 84, 128, 82, 69, 84, 79, 82, 84, 128, 82, 69, 83, 85, 80, 73, + 78, 85, 83, 128, 82, 69, 83, 84, 82, 79, 79, 77, 128, 82, 69, 83, 84, 82, + 73, 67, 84, 69, 196, 82, 69, 83, 84, 128, 82, 69, 83, 80, 79, 78, 83, 69, + 128, 82, 69, 83, 79, 85, 82, 67, 69, 128, 82, 69, 83, 79, 76, 85, 84, 73, + 79, 78, 128, 82, 69, 83, 73, 83, 84, 65, 78, 67, 69, 128, 82, 69, 83, 73, + 68, 69, 78, 67, 69, 128, 82, 69, 83, 72, 45, 65, 89, 73, 78, 45, 68, 65, + 76, 69, 84, 72, 128, 82, 69, 83, 72, 45, 65, 89, 73, 78, 128, 82, 69, 83, + 200, 82, 69, 82, 69, 78, 71, 71, 65, 78, 128, 82, 69, 82, 69, 75, 65, 78, + 128, 82, 69, 80, 82, 69, 83, 69, 78, 84, 128, 82, 69, 80, 76, 65, 67, 69, + 77, 69, 78, 212, 82, 69, 80, 72, 65, 128, 82, 69, 80, 72, 128, 82, 69, + 80, 69, 84, 73, 84, 73, 79, 206, 82, 69, 80, 69, 65, 84, 69, 196, 82, 69, + 80, 69, 65, 84, 128, 82, 69, 80, 69, 65, 212, 82, 69, 80, 65, 89, 65, + 128, 82, 69, 80, 65, 128, 82, 69, 80, 193, 82, 69, 78, 84, 79, 71, 69, + 78, 128, 82, 69, 78, 128, 82, 69, 206, 82, 69, 77, 85, 128, 82, 69, 77, + 73, 78, 68, 69, 210, 82, 69, 77, 69, 68, 89, 128, 82, 69, 76, 73, 71, 73, + 79, 78, 128, 82, 69, 76, 73, 69, 86, 69, 196, 82, 69, 76, 69, 65, 83, 69, + 128, 82, 69, 76, 65, 88, 69, 68, 128, 82, 69, 76, 65, 84, 73, 79, 78, 65, + 204, 82, 69, 76, 65, 84, 73, 79, 78, 128, 82, 69, 76, 65, 65, 128, 82, + 69, 74, 65, 78, 199, 82, 69, 73, 87, 65, 128, 82, 69, 73, 196, 82, 69, + 73, 128, 82, 69, 71, 85, 76, 85, 83, 45, 52, 128, 82, 69, 71, 85, 76, 85, + 83, 45, 51, 128, 82, 69, 71, 85, 76, 85, 83, 45, 50, 128, 82, 69, 71, 85, + 76, 85, 83, 128, 82, 69, 71, 85, 76, 85, 211, 82, 69, 71, 73, 83, 84, 69, + 82, 69, 196, 82, 69, 71, 73, 79, 78, 65, 204, 82, 69, 71, 73, 65, 45, 50, + 128, 82, 69, 71, 73, 65, 128, 82, 69, 70, 79, 82, 77, 69, 196, 82, 69, + 70, 69, 82, 69, 78, 67, 197, 82, 69, 68, 85, 80, 76, 73, 67, 65, 84, 73, + 79, 78, 128, 82, 69, 67, 89, 67, 76, 73, 78, 199, 82, 69, 67, 89, 67, 76, + 69, 196, 82, 69, 67, 84, 73, 76, 73, 78, 69, 65, 210, 82, 69, 67, 84, 65, + 78, 71, 85, 76, 65, 210, 82, 69, 67, 84, 65, 78, 71, 76, 69, 128, 82, 69, + 67, 84, 65, 78, 71, 76, 197, 82, 69, 67, 82, 69, 65, 84, 73, 79, 78, 65, + 204, 82, 69, 67, 79, 82, 68, 73, 78, 199, 82, 69, 67, 79, 82, 68, 69, 82, + 128, 82, 69, 67, 79, 82, 68, 128, 82, 69, 67, 79, 82, 196, 82, 69, 67, + 73, 84, 65, 84, 73, 86, 197, 82, 69, 67, 69, 80, 84, 73, 86, 197, 82, 69, + 67, 69, 73, 86, 69, 82, 128, 82, 69, 67, 69, 73, 86, 69, 210, 82, 69, 67, + 69, 73, 80, 84, 128, 82, 69, 65, 76, 71, 65, 82, 45, 50, 128, 82, 69, 65, + 76, 71, 65, 82, 128, 82, 69, 65, 72, 77, 85, 75, 128, 82, 69, 65, 67, 72, + 128, 82, 69, 45, 52, 128, 82, 69, 45, 51, 128, 82, 69, 45, 50, 128, 82, + 69, 45, 49, 128, 82, 68, 207, 82, 68, 69, 204, 82, 66, 65, 83, 193, 82, + 65, 90, 79, 82, 128, 82, 65, 89, 83, 128, 82, 65, 89, 211, 82, 65, 89, + 65, 78, 78, 65, 128, 82, 65, 84, 73, 79, 128, 82, 65, 84, 72, 65, 128, + 82, 65, 84, 72, 193, 82, 65, 84, 65, 128, 82, 65, 84, 128, 82, 65, 83, + 87, 65, 68, 73, 128, 82, 65, 83, 79, 85, 204, 82, 65, 83, 72, 65, 128, + 82, 65, 81, 128, 82, 65, 80, 73, 83, 77, 65, 128, 82, 65, 78, 71, 197, + 82, 65, 78, 65, 128, 82, 65, 78, 128, 82, 65, 77, 211, 82, 65, 77, 66, + 65, 84, 128, 82, 65, 75, 72, 65, 78, 71, 128, 82, 65, 75, 65, 65, 82, 65, + 65, 78, 83, 65, 89, 65, 128, 82, 65, 73, 83, 73, 78, 199, 82, 65, 73, 83, + 69, 68, 128, 82, 65, 73, 83, 69, 196, 82, 65, 73, 78, 66, 79, 87, 128, + 82, 65, 73, 76, 87, 65, 89, 128, 82, 65, 73, 76, 87, 65, 217, 82, 65, 73, + 76, 128, 82, 65, 73, 68, 207, 82, 65, 73, 68, 65, 128, 82, 65, 72, 77, + 65, 84, 85, 76, 76, 65, 200, 82, 65, 72, 128, 82, 65, 70, 69, 128, 82, + 65, 69, 77, 128, 82, 65, 68, 73, 79, 65, 67, 84, 73, 86, 197, 82, 65, 68, + 73, 79, 128, 82, 65, 68, 73, 207, 82, 65, 68, 201, 82, 65, 68, 128, 82, + 65, 196, 82, 65, 67, 81, 85, 69, 212, 82, 65, 67, 73, 78, 71, 128, 82, + 65, 67, 73, 78, 199, 82, 65, 67, 67, 79, 79, 78, 128, 82, 65, 66, 66, 73, + 84, 128, 82, 65, 66, 66, 73, 212, 82, 65, 66, 128, 82, 65, 65, 73, 128, + 82, 65, 51, 128, 82, 65, 50, 128, 82, 65, 45, 75, 65, 82, 65, 128, 82, + 65, 45, 52, 128, 82, 65, 45, 51, 128, 82, 65, 45, 50, 128, 82, 65, 45, + 49, 128, 82, 48, 50, 57, 128, 82, 48, 50, 56, 128, 82, 48, 50, 55, 128, + 82, 48, 50, 54, 128, 82, 48, 50, 53, 128, 82, 48, 50, 52, 128, 82, 48, + 50, 51, 128, 82, 48, 50, 50, 128, 82, 48, 50, 49, 128, 82, 48, 50, 48, + 128, 82, 48, 49, 57, 128, 82, 48, 49, 56, 128, 82, 48, 49, 55, 128, 82, + 48, 49, 54, 65, 128, 82, 48, 49, 54, 128, 82, 48, 49, 53, 128, 82, 48, + 49, 52, 128, 82, 48, 49, 51, 128, 82, 48, 49, 50, 128, 82, 48, 49, 49, + 128, 82, 48, 49, 48, 65, 128, 82, 48, 49, 48, 128, 82, 48, 48, 57, 128, + 82, 48, 48, 56, 128, 82, 48, 48, 55, 128, 82, 48, 48, 54, 128, 82, 48, + 48, 53, 128, 82, 48, 48, 52, 128, 82, 48, 48, 51, 66, 128, 82, 48, 48, + 51, 65, 128, 82, 48, 48, 51, 128, 82, 48, 48, 50, 65, 128, 82, 48, 48, + 50, 128, 82, 48, 48, 49, 128, 82, 45, 67, 82, 69, 197, 81, 89, 88, 128, + 81, 89, 85, 128, 81, 89, 84, 128, 81, 89, 82, 88, 128, 81, 89, 82, 128, + 81, 89, 80, 128, 81, 89, 79, 128, 81, 89, 73, 128, 81, 89, 69, 69, 128, + 81, 89, 69, 128, 81, 89, 65, 65, 128, 81, 89, 65, 128, 81, 89, 128, 81, + 87, 73, 128, 81, 87, 69, 69, 128, 81, 87, 69, 128, 81, 87, 65, 65, 128, + 81, 87, 65, 128, 81, 85, 88, 128, 81, 85, 86, 128, 81, 85, 85, 86, 128, + 81, 85, 85, 128, 81, 85, 84, 128, 81, 85, 83, 72, 83, 72, 65, 89, 65, + 128, 81, 85, 82, 88, 128, 81, 85, 82, 128, 81, 85, 80, 128, 81, 85, 79, + 88, 128, 81, 85, 79, 84, 197, 81, 85, 79, 84, 65, 84, 73, 79, 206, 81, + 85, 79, 84, 128, 81, 85, 79, 80, 128, 81, 85, 79, 128, 81, 85, 75, 128, + 81, 85, 73, 78, 84, 73, 76, 69, 128, 81, 85, 73, 78, 84, 69, 83, 83, 69, + 78, 67, 69, 128, 81, 85, 73, 78, 68, 73, 67, 69, 83, 73, 77, 193, 81, 85, + 73, 78, 67, 85, 78, 88, 128, 81, 85, 73, 78, 65, 82, 73, 85, 211, 81, 85, + 73, 76, 212, 81, 85, 73, 76, 76, 128, 81, 85, 73, 67, 203, 81, 85, 73, + 128, 81, 85, 70, 128, 81, 85, 69, 83, 84, 73, 79, 78, 69, 196, 81, 85, + 69, 83, 84, 73, 79, 78, 128, 81, 85, 69, 83, 84, 73, 79, 206, 81, 85, 69, + 69, 78, 128, 81, 85, 69, 69, 206, 81, 85, 69, 128, 81, 85, 66, 85, 84, + 83, 128, 81, 85, 65, 84, 69, 82, 78, 73, 79, 206, 81, 85, 65, 82, 84, 69, + 82, 83, 128, 81, 85, 65, 82, 84, 69, 82, 211, 81, 85, 65, 82, 84, 69, 82, + 128, 81, 85, 65, 78, 84, 73, 84, 217, 81, 85, 65, 68, 82, 85, 80, 76, + 197, 81, 85, 65, 68, 82, 65, 78, 84, 128, 81, 85, 65, 68, 82, 65, 78, + 212, 81, 85, 65, 68, 67, 79, 76, 79, 78, 128, 81, 85, 65, 68, 128, 81, + 85, 65, 196, 81, 85, 65, 128, 81, 85, 128, 81, 208, 81, 79, 88, 128, 81, + 79, 84, 128, 81, 79, 80, 72, 128, 81, 79, 80, 65, 128, 81, 79, 80, 128, + 81, 79, 79, 128, 81, 79, 207, 81, 79, 70, 128, 81, 79, 198, 81, 79, 65, + 128, 81, 79, 128, 81, 78, 128, 81, 73, 88, 128, 81, 73, 84, 83, 65, 128, + 81, 73, 84, 128, 81, 73, 80, 128, 81, 73, 73, 128, 81, 73, 70, 128, 81, + 73, 69, 88, 128, 81, 73, 69, 84, 128, 81, 73, 69, 80, 128, 81, 73, 69, + 128, 81, 73, 128, 81, 72, 87, 73, 128, 81, 72, 87, 69, 69, 128, 81, 72, + 87, 69, 128, 81, 72, 87, 65, 65, 128, 81, 72, 87, 65, 128, 81, 72, 85, + 128, 81, 72, 79, 80, 72, 128, 81, 72, 79, 128, 81, 72, 73, 128, 81, 72, + 69, 69, 128, 81, 72, 69, 128, 81, 72, 65, 85, 128, 81, 72, 65, 65, 128, + 81, 72, 65, 128, 81, 71, 65, 128, 81, 69, 84, 65, 78, 65, 128, 81, 69, + 69, 128, 81, 69, 128, 81, 65, 89, 128, 81, 65, 85, 128, 81, 65, 84, 65, + 78, 128, 81, 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, 128, 81, + 65, 80, 72, 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, 84, 211, + 81, 65, 76, 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, 73, 128, + 81, 65, 70, 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, 65, 73, + 128, 81, 65, 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, 55, 128, + 81, 48, 48, 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, 81, 48, + 48, 51, 128, 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, 128, 80, + 89, 88, 128, 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, 128, 80, + 89, 80, 128, 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, 79, 128, + 80, 87, 207, 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, 69, 128, + 80, 87, 69, 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, 80, 85, + 90, 90, 76, 197, 80, 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, 85, 128, + 80, 85, 84, 82, 69, 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, 128, 80, + 85, 212, 80, 85, 83, 72, 80, 73, 78, 128, 80, 85, 83, 72, 80, 73, 75, 65, + 128, 80, 85, 83, 72, 73, 78, 199, 80, 85, 82, 88, 128, 80, 85, 82, 83, + 69, 128, 80, 85, 82, 80, 76, 197, 80, 85, 82, 78, 65, 77, 65, 128, 80, + 85, 82, 73, 84, 89, 128, 80, 85, 82, 73, 70, 89, 128, 80, 85, 82, 128, + 80, 85, 81, 128, 80, 85, 80, 128, 80, 85, 79, 88, 128, 80, 85, 79, 80, + 128, 80, 85, 79, 128, 80, 85, 78, 71, 65, 65, 77, 128, 80, 85, 78, 71, + 128, 80, 85, 78, 67, 84, 85, 211, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, + 78, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 206, 80, 85, 77, 80, + 128, 80, 85, 77, 128, 80, 85, 70, 70, 69, 68, 128, 80, 85, 69, 128, 80, + 85, 67, 75, 128, 80, 85, 66, 76, 73, 195, 80, 85, 194, 80, 85, 65, 81, + 128, 80, 85, 65, 69, 128, 80, 85, 65, 67, 72, 85, 197, 80, 85, 50, 128, + 80, 85, 49, 128, 80, 85, 128, 80, 84, 72, 65, 72, 193, 80, 84, 69, 128, + 80, 83, 73, 76, 201, 80, 83, 73, 70, 73, 83, 84, 79, 83, 89, 78, 65, 71, + 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 80, 65, 82, 65, 75, 65, 76, + 69, 83, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 206, 80, 83, 73, 70, + 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 128, 80, 83, 73, 128, 80, 83, + 65, 76, 84, 69, 210, 80, 83, 128, 80, 82, 79, 86, 69, 128, 80, 82, 79, + 84, 79, 86, 65, 82, 89, 211, 80, 82, 79, 84, 79, 211, 80, 82, 79, 84, 69, + 67, 84, 69, 196, 80, 82, 79, 83, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, + 128, 80, 82, 79, 83, 69, 82, 80, 73, 78, 65, 128, 80, 82, 79, 80, 79, 82, + 84, 73, 79, 78, 65, 204, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 128, 80, + 82, 79, 80, 69, 82, 84, 217, 80, 82, 79, 80, 69, 76, 76, 69, 210, 80, 82, + 79, 79, 70, 128, 80, 82, 79, 76, 79, 78, 71, 69, 196, 80, 82, 79, 76, 65, + 84, 73, 79, 78, 197, 80, 82, 79, 74, 69, 67, 84, 79, 82, 128, 80, 82, 79, + 74, 69, 67, 84, 73, 86, 69, 128, 80, 82, 79, 74, 69, 67, 84, 73, 79, 78, + 128, 80, 82, 79, 72, 73, 66, 73, 84, 69, 196, 80, 82, 79, 71, 82, 69, 83, + 83, 128, 80, 82, 79, 71, 82, 65, 205, 80, 82, 79, 70, 79, 85, 78, 68, + 128, 80, 82, 79, 68, 85, 67, 84, 128, 80, 82, 79, 68, 85, 67, 212, 80, + 82, 79, 66, 73, 78, 199, 80, 82, 73, 86, 65, 84, 69, 128, 80, 82, 73, 86, + 65, 84, 197, 80, 82, 73, 86, 65, 67, 217, 80, 82, 73, 83, 72, 84, 72, 65, + 77, 65, 84, 82, 193, 80, 82, 73, 78, 84, 83, 128, 80, 82, 73, 78, 84, 69, + 82, 128, 80, 82, 73, 78, 84, 69, 210, 80, 82, 73, 78, 84, 128, 80, 82, + 73, 78, 212, 80, 82, 73, 78, 67, 69, 83, 83, 128, 80, 82, 73, 78, 67, 69, + 128, 80, 82, 73, 77, 69, 128, 80, 82, 73, 77, 197, 80, 82, 69, 86, 73, + 79, 85, 211, 80, 82, 69, 84, 90, 69, 76, 128, 80, 82, 69, 83, 83, 69, + 196, 80, 82, 69, 83, 69, 84, 128, 80, 82, 69, 83, 69, 78, 84, 65, 84, 73, + 79, 206, 80, 82, 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 80, 82, 69, 80, + 79, 78, 68, 69, 82, 65, 78, 67, 69, 128, 80, 82, 69, 78, 75, 72, 65, 128, + 80, 82, 69, 71, 78, 65, 78, 212, 80, 82, 69, 70, 73, 88, 69, 196, 80, 82, + 69, 70, 65, 67, 197, 80, 82, 69, 67, 73, 80, 73, 84, 65, 84, 69, 128, 80, + 82, 69, 67, 69, 68, 73, 78, 199, 80, 82, 69, 67, 69, 68, 69, 83, 128, 80, + 82, 69, 67, 69, 68, 69, 211, 80, 82, 69, 67, 69, 68, 69, 196, 80, 82, 69, + 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, 68, 197, 80, 82, 65, 89, 69, + 210, 80, 82, 65, 77, 45, 80, 73, 73, 128, 80, 82, 65, 77, 45, 80, 73, + 201, 80, 82, 65, 77, 45, 77, 85, 79, 89, 128, 80, 82, 65, 77, 45, 77, 85, + 79, 217, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, 77, 45, 66, + 85, 79, 206, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, 77, 45, 66, + 69, 201, 80, 82, 65, 77, 128, 80, 82, 65, 205, 80, 82, 128, 80, 80, 86, + 128, 80, 80, 77, 128, 80, 80, 65, 128, 80, 79, 89, 128, 80, 79, 88, 128, + 80, 79, 87, 69, 82, 211, 80, 79, 87, 69, 82, 128, 80, 79, 87, 69, 210, + 80, 79, 87, 68, 69, 82, 69, 196, 80, 79, 87, 68, 69, 82, 128, 80, 79, 85, + 78, 196, 80, 79, 85, 76, 84, 82, 217, 80, 79, 85, 67, 72, 128, 80, 79, + 84, 65, 84, 79, 128, 80, 79, 84, 65, 66, 76, 197, 80, 79, 212, 80, 79, + 83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 79, 83, 84, 66, 79, 88, 128, + 80, 79, 83, 84, 65, 204, 80, 79, 83, 84, 128, 80, 79, 83, 212, 80, 79, + 83, 83, 69, 83, 83, 73, 79, 78, 128, 80, 79, 83, 83, 69, 83, 83, 73, 79, + 206, 80, 79, 83, 73, 84, 73, 79, 78, 83, 128, 80, 79, 83, 73, 84, 73, 79, + 78, 128, 80, 79, 83, 69, 73, 68, 79, 78, 128, 80, 79, 82, 84, 65, 66, 76, + 197, 80, 79, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, 82, 82, 69, 67, 84, + 85, 211, 80, 79, 80, 80, 73, 78, 199, 80, 79, 80, 80, 69, 82, 128, 80, + 79, 80, 67, 79, 82, 78, 128, 80, 79, 80, 128, 80, 79, 208, 80, 79, 79, + 68, 76, 69, 128, 80, 79, 79, 128, 80, 79, 78, 68, 79, 128, 80, 79, 206, + 80, 79, 77, 77, 69, 69, 128, 80, 79, 77, 77, 69, 197, 80, 79, 76, 79, + 128, 80, 79, 76, 73, 83, 72, 128, 80, 79, 76, 73, 67, 197, 80, 79, 76, + 201, 80, 79, 76, 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, 89, 84, 73, + 69, 128, 80, 79, 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, 211, 80, 79, + 73, 78, 84, 79, 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, 79, 73, 78, 84, + 69, 196, 80, 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, 80, 79, 69, 84, + 82, 217, 80, 79, 69, 84, 73, 195, 80, 79, 68, 65, 84, 85, 83, 128, 80, + 79, 67, 75, 69, 212, 80, 79, 65, 128, 80, 79, 128, 80, 207, 80, 78, 69, + 85, 77, 65, 84, 65, 128, 80, 76, 85, 84, 207, 80, 76, 85, 84, 65, 128, + 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 76, 85, 83, 128, 80, 76, 85, + 82, 65, 76, 128, 80, 76, 85, 77, 69, 196, 80, 76, 85, 77, 128, 80, 76, + 85, 75, 128, 80, 76, 85, 71, 128, 80, 76, 85, 128, 80, 76, 79, 87, 128, + 80, 76, 79, 80, 72, 85, 128, 80, 76, 72, 65, 85, 128, 80, 76, 69, 84, 72, + 82, 79, 78, 128, 80, 76, 69, 65, 68, 73, 78, 199, 80, 76, 68, 128, 80, + 76, 65, 89, 73, 78, 199, 80, 76, 65, 84, 69, 128, 80, 76, 65, 83, 84, 73, + 67, 83, 128, 80, 76, 65, 78, 69, 84, 128, 80, 76, 65, 78, 69, 128, 80, + 76, 65, 78, 67, 203, 80, 76, 65, 75, 128, 80, 76, 65, 71, 73, 79, 211, + 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 82, 128, 80, 76, 65, 67, 69, 72, + 79, 76, 68, 69, 210, 80, 76, 65, 67, 197, 80, 76, 65, 128, 80, 73, 90, + 90, 73, 67, 65, 84, 79, 128, 80, 73, 90, 90, 65, 128, 80, 73, 88, 128, + 80, 73, 87, 82, 128, 80, 73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 84, + 67, 72, 70, 79, 82, 203, 80, 73, 84, 128, 80, 73, 83, 84, 79, 76, 128, + 80, 73, 83, 69, 76, 69, 72, 128, 80, 73, 83, 67, 69, 83, 128, 80, 73, 82, + 73, 71, 128, 80, 73, 82, 73, 199, 80, 73, 82, 73, 69, 69, 78, 128, 80, + 73, 82, 65, 67, 89, 128, 80, 73, 82, 50, 128, 80, 73, 80, 73, 78, 71, + 128, 80, 73, 80, 65, 69, 77, 71, 66, 73, 69, 69, 128, 80, 73, 80, 65, 69, + 77, 66, 65, 128, 80, 73, 80, 128, 80, 73, 78, 87, 72, 69, 69, 204, 80, + 73, 78, 69, 65, 80, 80, 76, 69, 128, 80, 73, 78, 197, 80, 73, 78, 67, 72, + 73, 78, 199, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, 73, 76, 76, + 128, 80, 73, 76, 197, 80, 73, 76, 67, 82, 79, 215, 80, 73, 75, 85, 82, + 85, 128, 80, 73, 75, 79, 128, 80, 73, 71, 128, 80, 73, 199, 80, 73, 69, + 88, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, + 69, 85, 80, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 80, 73, 69, 85, + 80, 45, 83, 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 80, 73, 69, 85, + 80, 45, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, 69, + 85, 80, 45, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, 73, 69, 85, + 80, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 80, 73, 69, 85, + 80, 45, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 80, 73, 69, 85, 80, + 45, 82, 73, 69, 85, 76, 45, 80, 72, 73, 69, 85, 80, 72, 128, 80, 73, 69, + 85, 80, 45, 82, 73, 69, 85, 76, 128, 80, 73, 69, 85, 80, 45, 78, 73, 69, + 85, 78, 128, 80, 73, 69, 85, 80, 45, 77, 73, 69, 85, 77, 128, 80, 73, 69, + 85, 80, 45, 75, 72, 73, 69, 85, 75, 72, 128, 80, 73, 69, 85, 80, 45, 67, + 73, 69, 85, 67, 128, 80, 73, 69, 85, 80, 45, 67, 72, 73, 69, 85, 67, 72, + 128, 80, 73, 69, 85, 208, 80, 73, 69, 84, 128, 80, 73, 69, 80, 128, 80, + 73, 69, 69, 84, 128, 80, 73, 69, 69, 81, 128, 80, 73, 69, 67, 69, 128, + 80, 73, 69, 128, 80, 73, 67, 84, 85, 82, 69, 128, 80, 73, 67, 75, 69, 84, + 128, 80, 73, 67, 75, 128, 80, 73, 65, 83, 85, 84, 79, 82, 85, 128, 80, + 73, 65, 83, 77, 193, 80, 73, 65, 78, 79, 128, 80, 201, 80, 72, 87, 65, + 128, 80, 72, 85, 84, 72, 65, 79, 128, 80, 72, 85, 210, 80, 72, 85, 78, + 71, 128, 80, 72, 82, 65, 83, 69, 128, 80, 72, 79, 78, 69, 83, 128, 80, + 72, 79, 76, 85, 83, 128, 80, 72, 79, 69, 78, 73, 67, 73, 65, 206, 80, 72, + 79, 65, 128, 80, 72, 79, 128, 80, 72, 207, 80, 72, 78, 65, 69, 203, 80, + 72, 73, 78, 84, 72, 85, 128, 80, 72, 73, 76, 79, 83, 79, 80, 72, 69, 82, + 211, 80, 72, 73, 76, 73, 80, 80, 73, 78, 197, 80, 72, 73, 69, 85, 80, 72, + 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 72, 73, 69, 85, 80, 72, 45, 83, + 73, 79, 83, 128, 80, 72, 73, 69, 85, 80, 72, 45, 80, 73, 69, 85, 80, 128, + 80, 72, 73, 69, 85, 80, 72, 45, 72, 73, 69, 85, 72, 128, 80, 72, 73, 69, + 85, 80, 200, 80, 72, 73, 128, 80, 72, 201, 80, 72, 69, 69, 128, 80, 72, + 69, 128, 80, 72, 65, 83, 69, 45, 198, 80, 72, 65, 83, 69, 45, 194, 80, + 72, 65, 83, 69, 45, 193, 80, 72, 65, 82, 89, 78, 71, 69, 65, 204, 80, 72, + 65, 82, 128, 80, 72, 65, 78, 128, 80, 72, 65, 77, 128, 80, 72, 65, 73, + 83, 84, 79, 211, 80, 72, 65, 71, 83, 45, 80, 193, 80, 72, 65, 66, 128, + 80, 72, 65, 65, 82, 75, 65, 65, 128, 80, 72, 65, 65, 128, 80, 71, 128, + 80, 70, 128, 80, 69, 85, 88, 128, 80, 69, 85, 84, 65, 69, 128, 80, 69, + 85, 84, 128, 80, 69, 84, 82, 201, 80, 69, 84, 65, 83, 84, 79, 75, 79, 85, + 70, 73, 83, 77, 65, 128, 80, 69, 84, 65, 83, 84, 73, 128, 80, 69, 84, 65, + 83, 77, 65, 128, 80, 69, 84, 65, 76, 76, 69, 196, 80, 69, 83, 79, 128, + 80, 69, 83, 207, 80, 69, 83, 72, 50, 128, 80, 69, 83, 72, 178, 80, 69, + 83, 69, 84, 193, 80, 69, 211, 80, 69, 82, 84, 72, 207, 80, 69, 82, 83, + 80, 69, 67, 84, 73, 86, 69, 128, 80, 69, 82, 83, 79, 78, 65, 204, 80, 69, + 82, 83, 79, 78, 128, 80, 69, 82, 83, 79, 206, 80, 69, 82, 83, 73, 65, + 206, 80, 69, 82, 83, 69, 86, 69, 82, 73, 78, 199, 80, 69, 82, 80, 69, 78, + 68, 73, 67, 85, 76, 65, 82, 128, 80, 69, 82, 80, 69, 78, 68, 73, 67, 85, + 76, 65, 210, 80, 69, 82, 78, 73, 206, 80, 69, 82, 77, 73, 84, 84, 69, + 196, 80, 69, 82, 77, 73, 195, 80, 69, 82, 77, 65, 78, 69, 78, 212, 80, + 69, 82, 73, 83, 80, 79, 77, 69, 78, 73, 128, 80, 69, 82, 73, 83, 80, 79, + 77, 69, 78, 201, 80, 69, 82, 70, 79, 82, 77, 73, 78, 199, 80, 69, 82, 70, + 69, 67, 84, 85, 205, 80, 69, 82, 70, 69, 67, 84, 65, 128, 80, 69, 82, 70, + 69, 67, 84, 193, 80, 69, 82, 67, 85, 83, 83, 73, 86, 69, 128, 80, 69, 82, + 67, 69, 78, 212, 80, 69, 80, 80, 69, 82, 128, 80, 69, 80, 69, 84, 128, + 80, 69, 80, 69, 212, 80, 69, 79, 82, 84, 200, 80, 69, 79, 80, 76, 69, + 128, 80, 69, 78, 84, 65, 84, 72, 76, 79, 78, 128, 80, 69, 78, 84, 65, 83, + 69, 77, 69, 128, 80, 69, 78, 84, 65, 71, 82, 65, 77, 128, 80, 69, 78, 84, + 65, 71, 79, 78, 128, 80, 69, 78, 83, 85, 128, 80, 69, 78, 83, 73, 86, + 197, 80, 69, 78, 78, 217, 80, 69, 78, 78, 65, 78, 84, 128, 80, 69, 78, + 73, 72, 73, 128, 80, 69, 78, 71, 85, 73, 78, 128, 80, 69, 78, 71, 75, 65, + 76, 128, 80, 69, 78, 69, 84, 82, 65, 84, 73, 79, 78, 128, 80, 69, 78, 67, + 73, 76, 128, 80, 69, 76, 65, 83, 84, 79, 78, 128, 80, 69, 76, 65, 83, 84, + 79, 206, 80, 69, 73, 84, 72, 128, 80, 69, 72, 69, 72, 128, 80, 69, 72, + 69, 200, 80, 69, 72, 128, 80, 69, 200, 80, 69, 69, 90, 73, 128, 80, 69, + 69, 83, 72, 73, 128, 80, 69, 69, 80, 128, 80, 69, 69, 77, 128, 80, 69, + 69, 73, 128, 80, 69, 69, 128, 80, 69, 68, 69, 83, 84, 82, 73, 65, 78, 83, + 128, 80, 69, 68, 69, 83, 84, 82, 73, 65, 78, 128, 80, 69, 68, 69, 83, 84, + 65, 76, 128, 80, 69, 68, 69, 83, 84, 65, 204, 80, 69, 68, 65, 204, 80, + 69, 65, 78, 85, 84, 83, 128, 80, 69, 65, 75, 211, 80, 69, 65, 67, 79, 67, + 75, 128, 80, 69, 65, 67, 72, 128, 80, 69, 65, 67, 69, 128, 80, 69, 65, + 67, 197, 80, 68, 73, 128, 80, 68, 70, 128, 80, 68, 128, 80, 67, 128, 80, + 65, 90, 69, 82, 128, 80, 65, 89, 69, 82, 79, 75, 128, 80, 65, 89, 65, 78, + 78, 65, 128, 80, 65, 89, 128, 80, 65, 88, 128, 80, 65, 87, 78, 128, 80, + 65, 87, 206, 80, 65, 215, 80, 65, 86, 73, 89, 65, 78, 73, 128, 80, 65, + 85, 83, 197, 80, 65, 85, 128, 80, 65, 213, 80, 65, 84, 84, 69, 82, 78, + 128, 80, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 65, 84, 72, 65, 75, + 75, 85, 128, 80, 65, 84, 200, 80, 65, 84, 65, 75, 128, 80, 65, 84, 65, + 72, 128, 80, 65, 84, 128, 80, 65, 83, 85, 81, 128, 80, 65, 83, 83, 80, + 79, 82, 212, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 85, 80, + 45, 79, 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, + 76, 45, 68, 79, 87, 78, 45, 79, 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, + 77, 66, 65, 78, 71, 128, 80, 65, 83, 83, 69, 78, 71, 69, 210, 80, 65, 83, + 83, 69, 196, 80, 65, 83, 72, 84, 65, 128, 80, 65, 83, 72, 65, 69, 128, + 80, 65, 83, 69, 81, 128, 80, 65, 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, + 77, 128, 80, 65, 82, 84, 217, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, + 208, 80, 65, 82, 84, 73, 65, 76, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, + 196, 80, 65, 82, 84, 73, 65, 204, 80, 65, 82, 84, 72, 73, 65, 206, 80, + 65, 82, 212, 80, 65, 82, 82, 79, 84, 128, 80, 65, 82, 75, 128, 80, 65, + 82, 73, 67, 72, 79, 78, 128, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, 78, + 79, 206, 80, 65, 82, 69, 82, 69, 78, 128, 80, 65, 82, 69, 78, 84, 72, 69, + 83, 73, 83, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, 80, 65, 82, + 69, 78, 84, 72, 69, 83, 69, 211, 80, 65, 82, 65, 80, 72, 82, 65, 83, 197, + 80, 65, 82, 65, 76, 76, 69, 76, 79, 71, 82, 65, 77, 128, 80, 65, 82, 65, + 76, 76, 69, 76, 128, 80, 65, 82, 65, 76, 76, 69, 204, 80, 65, 82, 65, 75, + 76, 73, 84, 73, 75, 73, 128, 80, 65, 82, 65, 75, 76, 73, 84, 73, 75, 201, + 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, 80, 65, 82, 65, 71, 82, 65, + 80, 72, 85, 211, 80, 65, 82, 65, 71, 82, 65, 80, 72, 79, 83, 128, 80, 65, + 82, 65, 71, 82, 65, 80, 72, 128, 80, 65, 82, 65, 71, 82, 65, 80, 200, 80, + 65, 82, 65, 67, 72, 85, 84, 69, 128, 80, 65, 82, 65, 128, 80, 65, 82, + 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, + 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, 128, 80, 65, 80, 69, 82, + 128, 80, 65, 80, 69, 210, 80, 65, 80, 128, 80, 65, 208, 80, 65, 207, 80, + 65, 78, 89, 85, 75, 85, 128, 80, 65, 78, 89, 73, 75, 85, 128, 80, 65, 78, + 89, 69, 67, 69, 75, 128, 80, 65, 78, 89, 65, 78, 71, 71, 65, 128, 80, 65, + 78, 89, 65, 75, 82, 65, 128, 80, 65, 78, 84, 73, 128, 80, 65, 78, 83, 73, + 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, 65, 78, 83, 73, 79, 83, 45, 75, + 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, 80, 128, 80, 65, 78, 79, 78, + 71, 79, 78, 65, 78, 128, 80, 65, 78, 79, 76, 79, 78, 71, 128, 80, 65, 78, + 71, 87, 73, 83, 65, 68, 128, 80, 65, 78, 71, 82, 65, 78, 71, 75, 69, 80, + 128, 80, 65, 78, 71, 79, 76, 65, 84, 128, 80, 65, 78, 71, 76, 79, 78, 71, + 128, 80, 65, 78, 71, 76, 65, 89, 65, 82, 128, 80, 65, 78, 71, 75, 79, 78, + 128, 80, 65, 78, 71, 75, 65, 84, 128, 80, 65, 78, 71, 72, 85, 76, 85, + 128, 80, 65, 78, 71, 128, 80, 65, 78, 69, 85, 76, 69, 85, 78, 71, 128, + 80, 65, 78, 68, 193, 80, 65, 78, 67, 65, 75, 69, 83, 128, 80, 65, 78, 65, + 77, 128, 80, 65, 78, 65, 69, 76, 65, 69, 78, 71, 128, 80, 65, 78, 128, + 80, 65, 206, 80, 65, 77, 85, 78, 71, 75, 65, 72, 128, 80, 65, 77, 85, 68, + 80, 79, 68, 128, 80, 65, 77, 83, 72, 65, 69, 128, 80, 65, 77, 80, 72, 89, + 76, 73, 65, 206, 80, 65, 77, 73, 78, 71, 75, 65, 76, 128, 80, 65, 77, 69, + 80, 69, 84, 128, 80, 65, 77, 69, 78, 69, 78, 71, 128, 80, 65, 77, 65, 68, + 65, 128, 80, 65, 77, 65, 65, 69, 72, 128, 80, 65, 76, 85, 84, 65, 128, + 80, 65, 76, 79, 67, 72, 75, 65, 128, 80, 65, 76, 77, 89, 82, 69, 78, 197, + 80, 65, 76, 77, 211, 80, 65, 76, 77, 128, 80, 65, 76, 205, 80, 65, 76, + 76, 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 201, 80, + 65, 76, 69, 84, 84, 69, 128, 80, 65, 76, 65, 85, 78, 199, 80, 65, 76, 65, + 84, 65, 76, 73, 90, 69, 196, 80, 65, 76, 65, 84, 65, 76, 73, 90, 65, 84, + 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 204, 80, 65, 75, 80, 65, 203, + 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 73, 82, 84, 72, 82, 65, + 128, 80, 65, 73, 82, 69, 196, 80, 65, 73, 78, 84, 66, 82, 85, 83, 72, + 128, 80, 65, 73, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, 72, 128, 80, + 65, 71, 79, 68, 65, 128, 80, 65, 71, 69, 83, 128, 80, 65, 71, 69, 82, + 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, 80, 65, 68, 68, 76, 197, 80, + 65, 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, 80, 65, 67, + 75, 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, 65, 84, 85, + 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, 77, 128, + 80, 65, 65, 82, 65, 69, 128, 80, 65, 65, 77, 128, 80, 65, 65, 73, 128, + 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80, 65, 65, 128, 80, 50, 128, + 80, 48, 49, 49, 128, 80, 48, 49, 48, 128, 80, 48, 48, 57, 128, 80, 48, + 48, 56, 128, 80, 48, 48, 55, 128, 80, 48, 48, 54, 128, 80, 48, 48, 53, + 128, 80, 48, 48, 52, 128, 80, 48, 48, 51, 65, 128, 80, 48, 48, 51, 128, + 80, 48, 48, 50, 128, 80, 48, 48, 49, 65, 128, 80, 48, 48, 49, 128, 79, + 89, 83, 84, 69, 82, 128, 79, 89, 82, 65, 78, 73, 83, 77, 193, 79, 89, 65, + 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, 73, 193, 79, 88, 69, 73, + 65, 201, 79, 88, 69, 73, 193, 79, 87, 76, 128, 79, 86, 69, 82, 82, 73, + 68, 69, 128, 79, 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, + 69, 128, 79, 86, 69, 82, 76, 65, 89, 128, 79, 86, 69, 82, 76, 65, 217, + 79, 86, 69, 82, 76, 65, 80, 80, 73, 78, 199, 79, 86, 69, 82, 76, 65, 80, + 128, 79, 86, 69, 82, 76, 65, 73, 68, 128, 79, 86, 69, 82, 72, 69, 65, 84, + 69, 196, 79, 86, 69, 82, 66, 65, 82, 128, 79, 86, 65, 76, 128, 79, 86, + 65, 204, 79, 85, 84, 76, 73, 78, 69, 196, 79, 85, 84, 76, 73, 78, 69, + 128, 79, 85, 84, 69, 210, 79, 85, 84, 66, 79, 216, 79, 85, 78, 75, 73, + 193, 79, 85, 78, 67, 69, 128, 79, 85, 78, 67, 197, 79, 84, 85, 128, 79, + 84, 84, 79, 77, 65, 206, 79, 84, 84, 69, 82, 128, 79, 84, 84, 65, 86, + 193, 79, 84, 84, 128, 79, 84, 72, 69, 82, 211, 79, 84, 72, 69, 210, 79, + 84, 72, 65, 76, 65, 206, 79, 84, 72, 65, 76, 128, 79, 83, 77, 65, 78, 89, + 193, 79, 83, 67, 128, 79, 83, 65, 71, 197, 79, 82, 84, 72, 79, 71, 79, + 78, 65, 204, 79, 82, 84, 72, 79, 68, 79, 216, 79, 82, 78, 65, 84, 197, + 79, 82, 78, 65, 77, 69, 78, 84, 83, 128, 79, 82, 78, 65, 77, 69, 78, 84, + 128, 79, 82, 78, 65, 77, 69, 78, 212, 79, 82, 75, 72, 79, 206, 79, 82, + 73, 89, 193, 79, 82, 73, 71, 73, 78, 65, 204, 79, 82, 73, 71, 73, 78, + 128, 79, 82, 69, 45, 50, 128, 79, 82, 68, 73, 78, 65, 204, 79, 82, 68, + 69, 210, 79, 82, 67, 72, 73, 68, 128, 79, 82, 65, 78, 71, 85, 84, 65, 78, + 128, 79, 82, 65, 78, 71, 197, 79, 80, 84, 73, 79, 206, 79, 80, 84, 73, + 67, 65, 204, 79, 80, 80, 82, 69, 83, 83, 73, 79, 78, 128, 79, 80, 80, 79, + 83, 73, 84, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, 78, 199, 79, 80, 80, + 79, 83, 69, 128, 79, 80, 72, 73, 85, 67, 72, 85, 83, 128, 79, 80, 69, 82, + 65, 84, 79, 82, 128, 79, 80, 69, 82, 65, 84, 79, 210, 79, 80, 69, 82, 65, + 84, 73, 78, 199, 79, 80, 69, 78, 73, 78, 199, 79, 80, 69, 78, 45, 80, + 128, 79, 80, 69, 78, 45, 79, 85, 84, 76, 73, 78, 69, 196, 79, 80, 69, 78, + 45, 79, 128, 79, 80, 69, 78, 45, 207, 79, 80, 69, 78, 45, 72, 69, 65, 68, + 69, 196, 79, 80, 69, 78, 45, 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 84, + 80, 85, 212, 79, 80, 69, 78, 128, 79, 79, 90, 69, 128, 79, 79, 89, 65, + 78, 78, 65, 128, 79, 79, 85, 128, 79, 79, 77, 85, 128, 79, 79, 72, 128, + 79, 79, 69, 128, 79, 79, 66, 79, 79, 70, 73, 76, 73, 128, 79, 78, 85, + 128, 79, 78, 83, 85, 128, 79, 78, 78, 128, 79, 78, 75, 65, 82, 128, 79, + 78, 73, 79, 78, 128, 79, 78, 69, 83, 69, 76, 70, 128, 79, 78, 69, 45, 87, + 65, 217, 79, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 79, 78, 69, 45, 80, + 73, 69, 67, 197, 79, 78, 69, 45, 76, 73, 78, 197, 79, 78, 69, 45, 72, 85, + 78, 68, 82, 69, 68, 45, 65, 78, 68, 45, 83, 73, 88, 84, 73, 69, 84, 72, + 128, 79, 78, 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, 128, 79, 78, 45, + 79, 70, 198, 79, 77, 73, 83, 83, 73, 79, 206, 79, 77, 73, 67, 82, 79, 78, + 128, 79, 77, 73, 67, 82, 79, 206, 79, 77, 69, 71, 65, 128, 79, 77, 69, + 71, 193, 79, 77, 65, 76, 79, 78, 128, 79, 76, 73, 86, 69, 128, 79, 76, + 73, 71, 79, 206, 79, 76, 68, 128, 79, 75, 84, 207, 79, 75, 65, 82, 65, + 128, 79, 75, 65, 82, 193, 79, 74, 73, 66, 87, 65, 217, 79, 74, 69, 79, + 78, 128, 79, 73, 78, 128, 79, 73, 76, 128, 79, 73, 204, 79, 72, 77, 128, + 79, 72, 205, 79, 71, 82, 69, 128, 79, 71, 79, 78, 69, 75, 128, 79, 71, + 79, 78, 69, 203, 79, 71, 72, 65, 205, 79, 70, 70, 73, 67, 69, 82, 128, + 79, 70, 70, 73, 67, 69, 128, 79, 70, 70, 73, 67, 197, 79, 70, 70, 128, + 79, 69, 89, 128, 79, 69, 82, 128, 79, 69, 75, 128, 79, 69, 69, 128, 79, + 68, 69, 78, 128, 79, 68, 68, 128, 79, 68, 196, 79, 67, 84, 79, 80, 85, + 83, 128, 79, 67, 84, 79, 66, 69, 82, 128, 79, 67, 84, 69, 212, 79, 67, + 84, 65, 71, 79, 78, 65, 204, 79, 67, 84, 65, 71, 79, 78, 128, 79, 67, + 210, 79, 67, 76, 79, 67, 75, 128, 79, 67, 67, 76, 85, 83, 73, 79, 78, + 128, 79, 66, 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 79, 66, 83, 69, 82, + 86, 69, 210, 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, 70, 73, + 76, 73, 128, 79, 66, 76, 73, 81, 85, 197, 79, 66, 74, 69, 67, 212, 79, + 66, 69, 76, 85, 83, 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, 79, + 65, 89, 128, 79, 65, 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, 128, + 79, 193, 79, 48, 53, 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, 48, + 65, 128, 79, 48, 53, 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, 128, + 79, 48, 52, 55, 128, 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, 48, + 52, 52, 128, 79, 48, 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, 49, + 128, 79, 48, 52, 48, 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, 79, + 48, 51, 55, 128, 79, 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, 79, + 48, 51, 54, 66, 128, 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, 79, + 48, 51, 53, 128, 79, 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, 48, + 51, 51, 128, 79, 48, 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, 48, + 65, 128, 79, 48, 51, 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, 57, + 128, 79, 48, 50, 56, 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, 79, + 48, 50, 53, 65, 128, 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, 79, + 48, 50, 52, 128, 79, 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, 50, + 49, 128, 79, 48, 50, 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, 57, + 65, 128, 79, 48, 49, 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, 128, + 79, 48, 49, 54, 128, 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, 48, + 49, 51, 128, 79, 48, 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, 48, + 67, 128, 79, 48, 49, 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, 49, + 48, 128, 79, 48, 48, 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, 128, + 79, 48, 48, 54, 70, 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, 68, + 128, 79, 48, 48, 54, 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, 54, + 65, 128, 79, 48, 48, 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, 53, + 128, 79, 48, 48, 52, 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, 79, + 48, 48, 49, 65, 128, 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, 45, + 79, 45, 73, 128, 79, 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, 84, + 128, 78, 90, 89, 82, 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, 128, + 78, 90, 89, 128, 78, 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, + 85, 82, 128, 78, 90, 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, 79, + 88, 128, 78, 90, 85, 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, 90, + 79, 88, 128, 78, 90, 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, 84, + 128, 78, 90, 73, 80, 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, 80, + 128, 78, 90, 73, 69, 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, 90, + 69, 85, 77, 128, 78, 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, 84, + 128, 78, 90, 65, 81, 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, 90, + 193, 78, 89, 87, 65, 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, 78, + 89, 85, 84, 128, 78, 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, 89, + 85, 79, 80, 128, 78, 89, 85, 79, 128, 78, 89, 85, 78, 128, 78, 89, 85, + 69, 128, 78, 89, 85, 128, 78, 89, 79, 88, 128, 78, 89, 79, 84, 128, 78, + 89, 79, 80, 128, 78, 89, 79, 79, 128, 78, 89, 79, 78, 128, 78, 89, 79, + 65, 128, 78, 89, 79, 128, 78, 89, 74, 65, 128, 78, 89, 73, 88, 128, 78, + 89, 73, 84, 128, 78, 89, 73, 212, 78, 89, 73, 211, 78, 89, 73, 210, 78, + 89, 73, 80, 128, 78, 89, 73, 78, 45, 68, 79, 128, 78, 89, 73, 78, 128, + 78, 89, 73, 73, 128, 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, 128, + 78, 89, 73, 69, 80, 128, 78, 89, 73, 69, 128, 78, 89, 73, 65, 75, 69, 78, + 199, 78, 89, 73, 128, 78, 89, 201, 78, 89, 72, 65, 128, 78, 89, 69, 84, + 128, 78, 89, 69, 212, 78, 89, 69, 78, 128, 78, 89, 69, 72, 128, 78, 89, + 69, 200, 78, 89, 69, 69, 128, 78, 89, 69, 128, 78, 89, 196, 78, 89, 67, + 65, 128, 78, 89, 65, 85, 128, 78, 89, 65, 74, 128, 78, 89, 65, 73, 128, + 78, 89, 65, 72, 128, 78, 89, 65, 69, 77, 65, 69, 128, 78, 89, 65, 65, + 128, 78, 87, 79, 79, 128, 78, 87, 79, 128, 78, 87, 73, 73, 128, 78, 87, + 73, 128, 78, 87, 69, 128, 78, 87, 65, 65, 128, 78, 87, 65, 128, 78, 87, + 128, 78, 86, 128, 78, 85, 88, 128, 78, 85, 85, 78, 128, 78, 85, 85, 128, + 78, 85, 84, 73, 76, 76, 85, 128, 78, 85, 84, 128, 78, 85, 212, 78, 85, + 82, 88, 128, 78, 85, 82, 128, 78, 85, 80, 128, 78, 85, 79, 88, 128, 78, + 85, 79, 80, 128, 78, 85, 79, 128, 78, 85, 78, 85, 90, 128, 78, 85, 78, + 85, 218, 78, 85, 78, 71, 128, 78, 85, 78, 65, 86, 85, 212, 78, 85, 78, + 65, 86, 73, 203, 78, 85, 78, 128, 78, 85, 206, 78, 85, 77, 69, 82, 207, + 78, 85, 77, 69, 82, 65, 84, 79, 210, 78, 85, 77, 69, 82, 65, 204, 78, 85, + 77, 66, 69, 82, 83, 128, 78, 85, 77, 66, 69, 82, 128, 78, 85, 77, 128, + 78, 85, 76, 76, 128, 78, 85, 76, 204, 78, 85, 76, 128, 78, 85, 75, 84, + 65, 128, 78, 85, 75, 84, 193, 78, 85, 69, 78, 71, 128, 78, 85, 69, 128, + 78, 85, 66, 73, 65, 206, 78, 85, 65, 69, 128, 78, 85, 49, 49, 128, 78, + 85, 49, 177, 78, 85, 48, 50, 50, 65, 128, 78, 85, 48, 50, 50, 128, 78, + 85, 48, 50, 49, 128, 78, 85, 48, 50, 48, 128, 78, 85, 48, 49, 57, 128, + 78, 85, 48, 49, 56, 65, 128, 78, 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, + 128, 78, 85, 48, 49, 54, 128, 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, + 52, 128, 78, 85, 48, 49, 51, 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, + 49, 49, 65, 128, 78, 85, 48, 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, + 78, 85, 48, 49, 48, 128, 78, 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, + 128, 78, 85, 48, 48, 55, 128, 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, + 53, 128, 78, 85, 48, 48, 52, 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, + 48, 50, 128, 78, 85, 48, 48, 49, 128, 78, 85, 45, 51, 128, 78, 85, 45, + 50, 128, 78, 85, 45, 49, 128, 78, 84, 88, 73, 86, 128, 78, 84, 88, 65, + 128, 78, 84, 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 85, 74, 128, 78, + 84, 213, 78, 84, 83, 65, 85, 128, 78, 84, 83, 65, 128, 78, 84, 79, 81, + 80, 69, 78, 128, 78, 84, 79, 71, 128, 78, 84, 79, 199, 78, 84, 73, 69, + 197, 78, 84, 72, 65, 85, 128, 78, 84, 69, 85, 78, 71, 66, 65, 128, 78, + 84, 69, 85, 77, 128, 78, 84, 69, 78, 128, 78, 84, 69, 69, 128, 78, 84, + 65, 80, 128, 78, 84, 65, 208, 78, 84, 65, 65, 128, 78, 84, 65, 128, 78, + 83, 85, 79, 212, 78, 83, 85, 78, 128, 78, 83, 85, 77, 128, 78, 83, 79, + 77, 128, 78, 83, 73, 69, 69, 84, 128, 78, 83, 73, 69, 69, 80, 128, 78, + 83, 73, 69, 69, 128, 78, 83, 72, 85, 84, 128, 78, 83, 72, 85, 212, 78, + 83, 72, 85, 79, 80, 128, 78, 83, 72, 85, 69, 128, 78, 83, 72, 73, 69, 69, + 128, 78, 83, 72, 69, 69, 128, 78, 83, 72, 65, 81, 128, 78, 83, 72, 65, + 128, 78, 83, 69, 85, 65, 69, 78, 128, 78, 83, 69, 78, 128, 78, 83, 65, + 128, 78, 82, 89, 88, 128, 78, 82, 89, 84, 128, 78, 82, 89, 82, 88, 128, + 78, 82, 89, 82, 128, 78, 82, 89, 80, 128, 78, 82, 89, 128, 78, 82, 85, + 88, 128, 78, 82, 85, 84, 128, 78, 82, 85, 82, 88, 128, 78, 82, 85, 82, + 128, 78, 82, 85, 80, 128, 78, 82, 85, 65, 128, 78, 82, 85, 128, 78, 82, + 79, 88, 128, 78, 82, 79, 80, 128, 78, 82, 79, 128, 78, 82, 69, 88, 128, + 78, 82, 69, 84, 128, 78, 82, 69, 211, 78, 82, 69, 80, 128, 78, 82, 69, + 128, 78, 82, 65, 88, 128, 78, 82, 65, 84, 128, 78, 82, 65, 80, 128, 78, + 82, 65, 128, 78, 81, 73, 71, 128, 78, 81, 65, 128, 78, 80, 76, 65, 128, + 78, 80, 65, 128, 78, 79, 89, 128, 78, 79, 88, 128, 78, 79, 87, 67, 128, + 78, 79, 86, 73, 76, 69, 128, 78, 79, 86, 69, 77, 66, 69, 82, 128, 78, 79, + 84, 84, 79, 128, 78, 79, 84, 69, 83, 128, 78, 79, 84, 69, 72, 69, 65, 68, + 128, 78, 79, 84, 69, 72, 69, 65, 196, 78, 79, 84, 69, 66, 79, 79, 75, + 128, 78, 79, 84, 69, 66, 79, 79, 203, 78, 79, 84, 69, 128, 78, 79, 84, + 197, 78, 79, 84, 67, 72, 69, 196, 78, 79, 84, 67, 72, 128, 78, 79, 84, + 65, 84, 73, 79, 206, 78, 79, 84, 128, 78, 79, 212, 78, 79, 83, 69, 128, + 78, 79, 83, 197, 78, 79, 82, 84, 72, 87, 69, 83, 212, 78, 79, 82, 84, 72, + 69, 82, 206, 78, 79, 82, 84, 72, 69, 65, 83, 84, 45, 80, 79, 73, 78, 84, + 73, 78, 199, 78, 79, 82, 77, 65, 204, 78, 79, 82, 68, 73, 195, 78, 79, + 210, 78, 79, 80, 128, 78, 79, 79, 78, 85, 128, 78, 79, 79, 128, 78, 79, + 78, 70, 79, 82, 75, 73, 78, 71, 128, 78, 79, 78, 45, 80, 79, 84, 65, 66, + 76, 197, 78, 79, 78, 45, 74, 79, 73, 78, 69, 82, 128, 78, 79, 78, 45, 66, + 82, 69, 65, 75, 73, 78, 199, 78, 79, 78, 128, 78, 79, 77, 73, 83, 77, + 193, 78, 79, 77, 73, 78, 65, 204, 78, 79, 75, 72, 85, 75, 128, 78, 79, + 68, 69, 128, 78, 79, 65, 128, 78, 79, 45, 66, 82, 69, 65, 203, 78, 79, + 45, 53, 128, 78, 79, 45, 52, 128, 78, 79, 45, 51, 128, 78, 79, 45, 50, + 128, 78, 79, 45, 49, 128, 78, 78, 85, 85, 128, 78, 78, 85, 128, 78, 78, + 79, 79, 128, 78, 78, 79, 128, 78, 78, 78, 85, 85, 128, 78, 78, 78, 85, + 128, 78, 78, 78, 79, 79, 128, 78, 78, 78, 79, 128, 78, 78, 78, 73, 73, + 128, 78, 78, 78, 73, 128, 78, 78, 78, 69, 69, 128, 78, 78, 78, 69, 128, + 78, 78, 78, 65, 85, 128, 78, 78, 78, 65, 73, 128, 78, 78, 78, 65, 65, + 128, 78, 78, 78, 65, 128, 78, 78, 78, 128, 78, 78, 72, 65, 128, 78, 78, + 71, 79, 79, 128, 78, 78, 71, 79, 128, 78, 78, 71, 73, 73, 128, 78, 78, + 71, 73, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, 65, 128, 78, 78, 71, + 128, 78, 78, 66, 83, 80, 128, 78, 77, 128, 78, 76, 65, 85, 128, 78, 76, + 48, 50, 48, 128, 78, 76, 48, 49, 57, 128, 78, 76, 48, 49, 56, 128, 78, + 76, 48, 49, 55, 65, 128, 78, 76, 48, 49, 55, 128, 78, 76, 48, 49, 54, + 128, 78, 76, 48, 49, 53, 128, 78, 76, 48, 49, 52, 128, 78, 76, 48, 49, + 51, 128, 78, 76, 48, 49, 50, 128, 78, 76, 48, 49, 49, 128, 78, 76, 48, + 49, 48, 128, 78, 76, 48, 48, 57, 128, 78, 76, 48, 48, 56, 128, 78, 76, + 48, 48, 55, 128, 78, 76, 48, 48, 54, 128, 78, 76, 48, 48, 53, 65, 128, + 78, 76, 48, 48, 53, 128, 78, 76, 48, 48, 52, 128, 78, 76, 48, 48, 51, + 128, 78, 76, 48, 48, 50, 128, 78, 76, 48, 48, 49, 128, 78, 76, 128, 78, + 75, 79, 77, 128, 78, 75, 207, 78, 75, 73, 78, 68, 73, 128, 78, 75, 65, + 85, 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 75, 65, 128, 78, 74, 89, + 88, 128, 78, 74, 89, 84, 128, 78, 74, 89, 82, 88, 128, 78, 74, 89, 82, + 128, 78, 74, 89, 80, 128, 78, 74, 89, 128, 78, 74, 85, 88, 128, 78, 74, + 85, 82, 88, 128, 78, 74, 85, 82, 128, 78, 74, 85, 81, 65, 128, 78, 74, + 85, 80, 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, + 69, 81, 128, 78, 74, 85, 65, 69, 128, 78, 74, 85, 128, 78, 74, 79, 88, + 128, 78, 74, 79, 84, 128, 78, 74, 79, 80, 128, 78, 74, 79, 79, 128, 78, + 74, 79, 128, 78, 74, 73, 88, 128, 78, 74, 73, 84, 128, 78, 74, 73, 80, + 128, 78, 74, 73, 69, 88, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, + 80, 128, 78, 74, 73, 69, 69, 128, 78, 74, 73, 69, 128, 78, 74, 73, 128, + 78, 74, 201, 78, 74, 69, 85, 88, 128, 78, 74, 69, 85, 84, 128, 78, 74, + 69, 85, 65, 69, 78, 65, 128, 78, 74, 69, 85, 65, 69, 77, 128, 78, 74, 69, + 69, 69, 69, 128, 78, 74, 69, 69, 128, 78, 74, 69, 197, 78, 74, 69, 128, + 78, 74, 65, 81, 128, 78, 74, 65, 80, 128, 78, 74, 65, 69, 77, 76, 73, + 128, 78, 74, 65, 69, 77, 128, 78, 74, 65, 65, 128, 78, 73, 88, 128, 78, + 73, 84, 82, 69, 128, 78, 73, 83, 65, 71, 128, 78, 73, 82, 85, 71, 85, + 128, 78, 73, 80, 128, 78, 73, 78, 84, 72, 128, 78, 73, 78, 69, 84, 89, + 128, 78, 73, 78, 69, 84, 217, 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, + 73, 78, 69, 84, 69, 69, 206, 78, 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, + 128, 78, 73, 78, 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, 65, + 178, 78, 73, 78, 57, 128, 78, 73, 78, 128, 78, 73, 77, 128, 78, 73, 205, + 78, 73, 75, 79, 76, 83, 66, 85, 82, 199, 78, 73, 75, 72, 65, 72, 73, 84, + 128, 78, 73, 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, 128, 78, 73, 72, + 83, 72, 86, 65, 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, 73, 78, 128, 78, + 73, 71, 73, 68, 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, 128, 78, 73, 71, + 72, 212, 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, 73, 69, 88, 128, + 78, 73, 69, 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, 73, 69, 85, 78, + 45, 84, 72, 73, 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, 45, 83, 73, 79, + 83, 128, 78, 73, 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, 78, 73, 69, 85, + 78, 45, 80, 73, 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, 80, 65, 78, 83, + 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, 78, + 73, 69, 85, 78, 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, 85, 78, 45, 67, + 73, 69, 85, 67, 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, 69, 85, 67, 72, + 128, 78, 73, 69, 85, 206, 78, 73, 69, 80, 128, 78, 73, 69, 128, 78, 73, + 66, 128, 78, 73, 65, 128, 78, 73, 50, 128, 78, 73, 45, 84, 69, 128, 78, + 73, 45, 55, 128, 78, 73, 45, 54, 128, 78, 73, 45, 53, 128, 78, 73, 45, + 52, 128, 78, 73, 45, 51, 128, 78, 73, 45, 50, 128, 78, 73, 45, 49, 128, + 78, 72, 85, 69, 128, 78, 72, 74, 65, 128, 78, 72, 128, 78, 71, 89, 69, + 128, 78, 71, 86, 69, 128, 78, 71, 85, 85, 128, 78, 71, 85, 79, 88, 128, + 78, 71, 85, 79, 84, 128, 78, 71, 85, 79, 128, 78, 71, 85, 65, 78, 128, + 78, 71, 85, 65, 69, 84, 128, 78, 71, 85, 65, 69, 128, 78, 71, 79, 88, + 128, 78, 71, 79, 85, 128, 78, 71, 79, 213, 78, 71, 79, 84, 128, 78, 71, + 79, 81, 128, 78, 71, 79, 80, 128, 78, 71, 79, 78, 128, 78, 71, 79, 77, + 128, 78, 71, 79, 69, 72, 128, 78, 71, 79, 69, 200, 78, 71, 207, 78, 71, + 75, 89, 69, 69, 128, 78, 71, 75, 87, 65, 69, 78, 128, 78, 71, 75, 85, 80, + 128, 78, 71, 75, 85, 78, 128, 78, 71, 75, 85, 77, 128, 78, 71, 75, 85, + 69, 78, 90, 69, 85, 77, 128, 78, 71, 75, 85, 197, 78, 71, 75, 73, 78, 68, + 201, 78, 71, 75, 73, 69, 69, 128, 78, 71, 75, 69, 85, 88, 128, 78, 71, + 75, 69, 85, 82, 73, 128, 78, 71, 75, 69, 85, 65, 69, 81, 128, 78, 71, 75, + 69, 85, 65, 69, 77, 128, 78, 71, 75, 65, 81, 128, 78, 71, 75, 65, 80, + 128, 78, 71, 75, 65, 65, 77, 73, 128, 78, 71, 75, 65, 128, 78, 71, 73, + 69, 88, 128, 78, 71, 73, 69, 80, 128, 78, 71, 73, 69, 128, 78, 71, 72, + 65, 128, 78, 71, 71, 87, 65, 69, 78, 128, 78, 71, 71, 85, 82, 65, 69, + 128, 78, 71, 71, 85, 80, 128, 78, 71, 71, 85, 79, 81, 128, 78, 71, 71, + 85, 79, 209, 78, 71, 71, 85, 79, 78, 128, 78, 71, 71, 85, 79, 77, 128, + 78, 71, 71, 85, 77, 128, 78, 71, 71, 85, 69, 69, 84, 128, 78, 71, 71, 85, + 65, 69, 83, 72, 65, 197, 78, 71, 71, 85, 65, 69, 206, 78, 71, 71, 85, 65, + 128, 78, 71, 71, 85, 128, 78, 71, 71, 79, 79, 128, 78, 71, 71, 79, 128, + 78, 71, 71, 73, 128, 78, 71, 71, 69, 85, 88, 128, 78, 71, 71, 69, 85, 65, + 69, 84, 128, 78, 71, 71, 69, 85, 65, 69, 128, 78, 71, 71, 69, 213, 78, + 71, 71, 69, 78, 128, 78, 71, 71, 69, 69, 84, 128, 78, 71, 71, 69, 69, 69, + 69, 128, 78, 71, 71, 69, 69, 128, 78, 71, 71, 69, 128, 78, 71, 71, 65, + 80, 128, 78, 71, 71, 65, 65, 77, 65, 69, 128, 78, 71, 71, 65, 65, 77, + 128, 78, 71, 71, 65, 65, 128, 78, 71, 71, 128, 78, 71, 69, 88, 128, 78, + 71, 69, 85, 82, 69, 85, 84, 128, 78, 71, 69, 80, 128, 78, 71, 69, 78, + 128, 78, 71, 69, 69, 128, 78, 71, 69, 65, 68, 65, 76, 128, 78, 71, 65, + 88, 128, 78, 71, 65, 85, 128, 78, 71, 65, 84, 128, 78, 71, 65, 211, 78, + 71, 65, 81, 128, 78, 71, 65, 80, 128, 78, 71, 65, 78, 71, 85, 128, 78, + 71, 65, 78, 128, 78, 71, 65, 73, 128, 78, 71, 65, 72, 128, 78, 71, 65, + 65, 73, 128, 78, 71, 193, 78, 70, 128, 78, 69, 88, 212, 78, 69, 88, 128, + 78, 69, 87, 83, 80, 65, 80, 69, 82, 128, 78, 69, 87, 76, 73, 78, 69, 128, + 78, 69, 87, 76, 73, 78, 197, 78, 69, 87, 193, 78, 69, 87, 128, 78, 69, + 215, 78, 69, 85, 84, 82, 65, 76, 128, 78, 69, 85, 84, 82, 65, 204, 78, + 69, 85, 84, 69, 82, 128, 78, 69, 84, 87, 79, 82, 75, 69, 196, 78, 69, + 212, 78, 69, 83, 84, 69, 196, 78, 69, 83, 83, 85, 83, 128, 78, 69, 82, + 196, 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, 84, 85, 78, 69, 128, + 78, 69, 80, 84, 85, 78, 197, 78, 69, 80, 128, 78, 69, 79, 128, 78, 69, + 207, 78, 69, 78, 79, 69, 128, 78, 69, 78, 65, 78, 79, 128, 78, 69, 78, + 128, 78, 69, 76, 128, 78, 69, 73, 84, 72, 69, 210, 78, 69, 71, 65, 84, + 73, 86, 197, 78, 69, 71, 65, 84, 73, 79, 206, 78, 69, 71, 65, 84, 69, + 196, 78, 69, 67, 75, 84, 73, 69, 128, 78, 69, 67, 75, 128, 78, 69, 66, + 69, 78, 83, 84, 73, 77, 77, 69, 128, 78, 69, 45, 75, 79, 128, 78, 68, 85, + 88, 128, 78, 68, 85, 84, 128, 78, 68, 85, 82, 88, 128, 78, 68, 85, 82, + 128, 78, 68, 85, 80, 128, 78, 68, 85, 78, 128, 78, 68, 213, 78, 68, 79, + 88, 128, 78, 68, 79, 84, 128, 78, 68, 79, 80, 128, 78, 68, 79, 79, 128, + 78, 68, 79, 78, 128, 78, 68, 79, 77, 66, 85, 128, 78, 68, 79, 76, 197, + 78, 68, 73, 88, 128, 78, 68, 73, 84, 128, 78, 68, 73, 81, 128, 78, 68, + 73, 80, 128, 78, 68, 73, 69, 88, 128, 78, 68, 73, 69, 128, 78, 68, 73, + 68, 65, 128, 78, 68, 73, 65, 81, 128, 78, 68, 69, 88, 128, 78, 68, 69, + 85, 88, 128, 78, 68, 69, 85, 84, 128, 78, 68, 69, 85, 65, 69, 82, 69, 69, + 128, 78, 68, 69, 80, 128, 78, 68, 69, 69, 128, 78, 68, 69, 128, 78, 68, + 65, 88, 128, 78, 68, 65, 84, 128, 78, 68, 65, 80, 128, 78, 68, 65, 77, + 128, 78, 68, 65, 65, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 68, 65, 65, + 128, 78, 68, 65, 193, 78, 67, 72, 65, 85, 128, 78, 67, 65, 128, 78, 66, + 89, 88, 128, 78, 66, 89, 84, 128, 78, 66, 89, 82, 88, 128, 78, 66, 89, + 82, 128, 78, 66, 89, 80, 128, 78, 66, 89, 128, 78, 66, 85, 88, 128, 78, + 66, 85, 84, 128, 78, 66, 85, 82, 88, 128, 78, 66, 85, 82, 128, 78, 66, + 85, 80, 128, 78, 66, 85, 128, 78, 66, 79, 88, 128, 78, 66, 79, 84, 128, + 78, 66, 79, 80, 128, 78, 66, 79, 128, 78, 66, 73, 88, 128, 78, 66, 73, + 84, 128, 78, 66, 73, 80, 128, 78, 66, 73, 69, 88, 128, 78, 66, 73, 69, + 80, 128, 78, 66, 73, 69, 128, 78, 66, 73, 128, 78, 66, 72, 128, 78, 66, + 65, 88, 128, 78, 66, 65, 84, 128, 78, 66, 65, 80, 128, 78, 66, 65, 128, + 78, 65, 90, 65, 210, 78, 65, 89, 65, 78, 78, 65, 128, 78, 65, 89, 128, + 78, 65, 88, 73, 65, 206, 78, 65, 88, 128, 78, 65, 85, 84, 72, 83, 128, + 78, 65, 85, 83, 69, 65, 84, 69, 196, 78, 65, 85, 68, 73, 218, 78, 65, 84, + 85, 82, 65, 204, 78, 65, 84, 73, 79, 78, 65, 204, 78, 65, 83, 75, 65, 80, + 201, 78, 65, 83, 72, 73, 128, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, + 78, 128, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 206, 78, 65, 83, 65, + 204, 78, 65, 82, 82, 79, 215, 78, 65, 82, 128, 78, 65, 81, 128, 78, 65, + 79, 211, 78, 65, 78, 83, 65, 78, 65, 81, 128, 78, 65, 78, 71, 77, 79, 78, + 84, 72, 79, 128, 78, 65, 78, 68, 73, 78, 65, 71, 65, 82, 201, 78, 65, 78, + 68, 128, 78, 65, 78, 65, 128, 78, 65, 77, 69, 128, 78, 65, 77, 197, 78, + 65, 77, 50, 128, 78, 65, 75, 128, 78, 65, 73, 82, 193, 78, 65, 73, 204, + 78, 65, 71, 82, 201, 78, 65, 71, 65, 82, 128, 78, 65, 71, 65, 128, 78, + 65, 71, 193, 78, 65, 71, 128, 78, 65, 199, 78, 65, 69, 128, 78, 65, 66, + 76, 65, 128, 78, 65, 66, 65, 84, 65, 69, 65, 206, 78, 65, 65, 83, 73, 75, + 89, 65, 89, 65, 128, 78, 65, 65, 75, 83, 73, 75, 89, 65, 89, 65, 128, 78, + 65, 65, 73, 128, 78, 65, 193, 78, 65, 52, 128, 78, 65, 50, 128, 78, 65, + 45, 57, 128, 78, 65, 45, 56, 128, 78, 65, 45, 55, 128, 78, 65, 45, 54, + 128, 78, 65, 45, 53, 128, 78, 65, 45, 52, 128, 78, 65, 45, 51, 128, 78, + 65, 45, 50, 128, 78, 65, 45, 49, 128, 78, 48, 52, 50, 128, 78, 48, 52, + 49, 128, 78, 48, 52, 48, 128, 78, 48, 51, 57, 128, 78, 48, 51, 56, 128, + 78, 48, 51, 55, 65, 128, 78, 48, 51, 55, 128, 78, 48, 51, 54, 128, 78, + 48, 51, 53, 65, 128, 78, 48, 51, 53, 128, 78, 48, 51, 52, 65, 128, 78, + 48, 51, 52, 128, 78, 48, 51, 51, 65, 128, 78, 48, 51, 51, 128, 78, 48, + 51, 50, 128, 78, 48, 51, 49, 128, 78, 48, 51, 48, 128, 78, 48, 50, 57, + 128, 78, 48, 50, 56, 128, 78, 48, 50, 55, 128, 78, 48, 50, 54, 128, 78, + 48, 50, 53, 65, 128, 78, 48, 50, 53, 128, 78, 48, 50, 52, 128, 78, 48, + 50, 51, 128, 78, 48, 50, 50, 128, 78, 48, 50, 49, 128, 78, 48, 50, 48, + 128, 78, 48, 49, 57, 128, 78, 48, 49, 56, 66, 128, 78, 48, 49, 56, 65, + 128, 78, 48, 49, 56, 128, 78, 48, 49, 55, 128, 78, 48, 49, 54, 128, 78, + 48, 49, 53, 128, 78, 48, 49, 52, 128, 78, 48, 49, 51, 128, 78, 48, 49, + 50, 128, 78, 48, 49, 49, 128, 78, 48, 49, 48, 128, 78, 48, 48, 57, 128, + 78, 48, 48, 56, 128, 78, 48, 48, 55, 128, 78, 48, 48, 54, 128, 78, 48, + 48, 53, 128, 78, 48, 48, 52, 128, 78, 48, 48, 51, 128, 78, 48, 48, 50, + 128, 78, 48, 48, 49, 128, 78, 45, 77, 85, 45, 77, 79, 45, 50, 128, 78, + 45, 77, 85, 45, 77, 79, 45, 49, 128, 78, 45, 67, 82, 69, 197, 78, 45, 65, + 82, 217, 77, 89, 88, 128, 77, 89, 84, 128, 77, 89, 83, 76, 73, 84, 69, + 128, 77, 89, 80, 128, 77, 89, 65, 128, 77, 89, 193, 77, 89, 128, 77, 87, + 79, 79, 128, 77, 87, 79, 128, 77, 87, 73, 73, 128, 77, 87, 73, 128, 77, + 87, 69, 69, 128, 77, 87, 69, 128, 77, 87, 65, 65, 128, 77, 87, 65, 128, + 77, 87, 128, 77, 215, 77, 86, 83, 128, 77, 86, 79, 80, 128, 77, 86, 73, + 128, 77, 86, 69, 85, 65, 69, 78, 71, 65, 77, 128, 77, 86, 128, 77, 214, + 77, 85, 88, 128, 77, 85, 85, 86, 85, 90, 72, 65, 75, 75, 85, 128, 77, 85, + 85, 83, 73, 75, 65, 84, 79, 65, 78, 128, 77, 85, 85, 82, 68, 72, 65, 74, + 193, 77, 85, 85, 128, 77, 85, 84, 72, 65, 76, 73, 89, 65, 128, 77, 85, + 84, 128, 77, 85, 83, 73, 67, 128, 77, 85, 83, 73, 195, 77, 85, 83, 72, + 82, 79, 79, 77, 128, 77, 85, 83, 72, 51, 128, 77, 85, 83, 72, 179, 77, + 85, 83, 72, 128, 77, 85, 83, 200, 77, 85, 83, 128, 77, 85, 82, 88, 128, + 77, 85, 82, 71, 85, 50, 128, 77, 85, 82, 69, 128, 77, 85, 82, 68, 65, + 128, 77, 85, 82, 68, 193, 77, 85, 82, 128, 77, 85, 81, 68, 65, 77, 128, + 77, 85, 80, 128, 77, 85, 79, 88, 128, 77, 85, 79, 84, 128, 77, 85, 79, + 80, 128, 77, 85, 79, 77, 65, 69, 128, 77, 85, 79, 128, 77, 85, 78, 83, + 85, 66, 128, 77, 85, 78, 65, 72, 128, 77, 85, 78, 128, 77, 85, 76, 84, + 73, 83, 69, 84, 128, 77, 85, 76, 84, 73, 83, 69, 212, 77, 85, 76, 84, 73, + 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 77, 85, 76, 84, 73, 80, 76, 73, + 67, 65, 84, 73, 79, 206, 77, 85, 76, 84, 73, 80, 76, 69, 128, 77, 85, 76, + 84, 73, 80, 76, 197, 77, 85, 76, 84, 73, 79, 67, 85, 76, 65, 210, 77, 85, + 76, 84, 73, 77, 65, 80, 128, 77, 85, 76, 84, 201, 77, 85, 76, 84, 65, 78, + 201, 77, 85, 75, 80, 72, 82, 69, 78, 71, 128, 77, 85, 75, 75, 85, 82, 85, + 78, 73, 128, 77, 85, 73, 78, 128, 77, 85, 71, 83, 128, 77, 85, 71, 128, + 77, 85, 199, 77, 85, 69, 78, 128, 77, 85, 69, 128, 77, 85, 67, 72, 128, + 77, 85, 67, 200, 77, 85, 67, 65, 65, 68, 128, 77, 85, 65, 83, 128, 77, + 85, 65, 78, 128, 77, 85, 65, 69, 128, 77, 85, 45, 71, 65, 65, 72, 76, 65, + 193, 77, 85, 45, 52, 128, 77, 85, 45, 51, 128, 77, 85, 45, 50, 128, 77, + 85, 45, 49, 128, 77, 213, 77, 84, 65, 86, 82, 85, 76, 201, 77, 83, 128, + 77, 82, 207, 77, 210, 77, 80, 65, 128, 77, 79, 89, 65, 73, 128, 77, 79, + 88, 128, 77, 79, 86, 73, 197, 77, 79, 86, 69, 211, 77, 79, 86, 69, 77, + 69, 78, 84, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, + 69, 78, 84, 45, 72, 73, 78, 71, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, + 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, 69, 78, 84, + 45, 68, 73, 65, 71, 79, 78, 65, 204, 77, 79, 86, 69, 77, 69, 78, 84, 128, + 77, 79, 86, 69, 77, 69, 78, 212, 77, 79, 86, 69, 196, 77, 79, 86, 69, + 128, 77, 79, 85, 84, 72, 128, 77, 79, 85, 83, 69, 128, 77, 79, 85, 83, + 197, 77, 79, 85, 78, 84, 65, 73, 78, 83, 128, 77, 79, 85, 78, 84, 65, 73, + 78, 128, 77, 79, 85, 78, 84, 65, 73, 206, 77, 79, 85, 78, 212, 77, 79, + 85, 78, 68, 128, 77, 79, 85, 78, 196, 77, 79, 84, 79, 82, 87, 65, 89, + 128, 77, 79, 84, 79, 82, 73, 90, 69, 196, 77, 79, 84, 79, 82, 67, 89, 67, + 76, 69, 128, 77, 79, 84, 79, 210, 77, 79, 84, 72, 69, 82, 128, 77, 79, + 84, 72, 69, 210, 77, 79, 84, 128, 77, 79, 83, 81, 85, 73, 84, 79, 128, + 77, 79, 83, 81, 85, 69, 128, 77, 79, 82, 84, 85, 85, 77, 128, 77, 79, 82, + 84, 65, 82, 128, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 204, 77, + 79, 82, 78, 73, 78, 71, 128, 77, 79, 80, 128, 77, 79, 79, 83, 69, 45, 67, + 82, 69, 197, 77, 79, 79, 78, 128, 77, 79, 79, 206, 77, 79, 79, 77, 80, + 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, 79, 68, 128, 77, + 79, 79, 196, 77, 79, 79, 128, 77, 79, 78, 84, 73, 69, 69, 78, 128, 77, + 79, 78, 84, 72, 128, 77, 79, 78, 84, 200, 77, 79, 78, 83, 84, 69, 82, + 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 79, 78, 79, 83, 80, 65, + 67, 197, 77, 79, 78, 79, 82, 65, 73, 76, 128, 77, 79, 78, 79, 71, 82, 65, + 80, 200, 77, 79, 78, 79, 71, 82, 65, 77, 77, 79, 211, 77, 79, 78, 79, 71, + 82, 65, 205, 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, 77, 79, 78, 79, + 67, 85, 76, 65, 210, 77, 79, 78, 79, 67, 76, 69, 128, 77, 79, 78, 75, 69, + 89, 128, 77, 79, 78, 75, 69, 217, 77, 79, 78, 73, 128, 77, 79, 78, 71, + 75, 69, 85, 65, 69, 81, 128, 77, 79, 78, 69, 89, 45, 77, 79, 85, 84, 200, + 77, 79, 78, 69, 217, 77, 79, 78, 128, 77, 79, 206, 77, 79, 76, 128, 77, + 79, 72, 65, 77, 77, 65, 196, 77, 79, 68, 85, 76, 207, 77, 79, 68, 73, 70, + 73, 69, 82, 45, 57, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 56, 128, 77, + 79, 68, 73, 70, 73, 69, 82, 45, 55, 128, 77, 79, 68, 73, 70, 73, 69, 82, + 45, 54, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 53, 128, 77, 79, 68, 73, + 70, 73, 69, 82, 45, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 51, 128, + 77, 79, 68, 73, 70, 73, 69, 82, 45, 50, 128, 77, 79, 68, 73, 70, 73, 69, + 82, 45, 49, 54, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 53, 128, 77, + 79, 68, 73, 70, 73, 69, 82, 45, 49, 52, 128, 77, 79, 68, 73, 70, 73, 69, + 82, 45, 49, 51, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 50, 128, 77, + 79, 68, 73, 70, 73, 69, 82, 45, 49, 49, 128, 77, 79, 68, 73, 70, 73, 69, + 82, 45, 49, 48, 128, 77, 79, 68, 73, 70, 73, 69, 82, 128, 77, 79, 68, + 201, 77, 79, 68, 69, 83, 84, 89, 128, 77, 79, 68, 69, 82, 206, 77, 79, + 68, 69, 77, 128, 77, 79, 68, 69, 76, 83, 128, 77, 79, 68, 69, 76, 128, + 77, 79, 68, 69, 128, 77, 79, 66, 73, 76, 197, 77, 79, 65, 128, 77, 79, + 45, 54, 128, 77, 79, 45, 53, 128, 77, 79, 45, 52, 128, 77, 79, 45, 51, + 128, 77, 207, 77, 78, 89, 65, 205, 77, 78, 65, 83, 128, 77, 77, 83, 80, + 128, 77, 77, 128, 77, 205, 77, 76, 65, 128, 77, 76, 128, 77, 75, 80, 65, + 82, 65, 209, 77, 73, 88, 128, 77, 73, 84, 128, 77, 73, 83, 82, 65, 128, + 77, 73, 82, 73, 66, 65, 65, 82, 85, 128, 77, 73, 82, 73, 128, 77, 73, 82, + 69, 68, 128, 77, 73, 80, 128, 77, 73, 78, 89, 128, 77, 73, 78, 85, 83, + 45, 79, 82, 45, 80, 76, 85, 211, 77, 73, 78, 85, 83, 128, 77, 73, 78, 73, + 83, 84, 69, 82, 128, 77, 73, 78, 73, 77, 73, 90, 69, 128, 77, 73, 78, 73, + 77, 65, 128, 77, 73, 78, 73, 68, 73, 83, 67, 128, 77, 73, 78, 73, 66, 85, + 83, 128, 77, 73, 77, 69, 128, 77, 73, 77, 128, 77, 73, 76, 76, 73, 79, + 78, 83, 128, 77, 73, 76, 76, 73, 79, 78, 211, 77, 73, 76, 76, 69, 84, + 128, 77, 73, 76, 76, 197, 77, 73, 76, 204, 77, 73, 76, 75, 217, 77, 73, + 76, 75, 128, 77, 73, 76, 73, 84, 65, 82, 217, 77, 73, 76, 128, 77, 73, + 75, 85, 82, 79, 78, 128, 77, 73, 75, 82, 79, 206, 77, 73, 75, 82, 73, + 128, 77, 73, 73, 78, 128, 77, 73, 73, 77, 128, 77, 73, 73, 128, 77, 73, + 199, 77, 73, 69, 88, 128, 77, 73, 69, 85, 77, 45, 84, 73, 75, 69, 85, 84, + 128, 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 77, + 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 77, 73, + 69, 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 73, 69, 85, 77, 45, 80, 73, + 69, 85, 80, 45, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, + 85, 80, 128, 77, 73, 69, 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, 77, + 73, 69, 85, 77, 45, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, 67, + 73, 69, 85, 67, 128, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, 72, + 128, 77, 73, 69, 85, 205, 77, 73, 69, 80, 128, 77, 73, 69, 69, 128, 77, + 73, 69, 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 68, 68, 76, 69, 45, 87, + 69, 76, 83, 200, 77, 73, 68, 68, 76, 69, 128, 77, 73, 68, 45, 76, 69, 86, + 69, 204, 77, 73, 196, 77, 73, 67, 82, 79, 83, 67, 79, 80, 69, 128, 77, + 73, 67, 82, 79, 80, 72, 79, 78, 69, 128, 77, 73, 67, 82, 79, 66, 69, 128, + 77, 73, 67, 82, 207, 77, 73, 67, 210, 77, 73, 45, 55, 128, 77, 73, 45, + 54, 128, 77, 73, 45, 53, 128, 77, 73, 45, 52, 128, 77, 73, 45, 51, 128, + 77, 73, 45, 50, 128, 77, 73, 45, 49, 128, 77, 72, 90, 128, 77, 72, 65, + 128, 77, 72, 128, 77, 71, 85, 88, 128, 77, 71, 85, 84, 128, 77, 71, 85, + 82, 88, 128, 77, 71, 85, 82, 128, 77, 71, 85, 80, 128, 77, 71, 85, 79, + 88, 128, 77, 71, 85, 79, 80, 128, 77, 71, 85, 79, 128, 77, 71, 85, 128, + 77, 71, 79, 88, 128, 77, 71, 79, 84, 128, 77, 71, 79, 80, 128, 77, 71, + 79, 128, 77, 71, 207, 77, 71, 73, 69, 88, 128, 77, 71, 73, 69, 128, 77, + 71, 69, 88, 128, 77, 71, 69, 80, 128, 77, 71, 69, 128, 77, 71, 66, 85, + 128, 77, 71, 66, 79, 79, 128, 77, 71, 66, 79, 70, 85, 77, 128, 77, 71, + 66, 79, 128, 77, 71, 66, 73, 128, 77, 71, 66, 69, 85, 78, 128, 77, 71, + 66, 69, 78, 128, 77, 71, 66, 69, 69, 128, 77, 71, 66, 69, 128, 77, 71, + 66, 65, 83, 65, 81, 128, 77, 71, 66, 65, 83, 65, 128, 77, 71, 65, 88, + 128, 77, 71, 65, 84, 128, 77, 71, 65, 80, 128, 77, 71, 65, 128, 77, 71, + 128, 77, 70, 79, 78, 128, 77, 70, 79, 206, 77, 70, 79, 128, 77, 70, 73, + 89, 65, 81, 128, 77, 70, 73, 69, 69, 128, 77, 70, 69, 85, 84, 128, 77, + 70, 69, 85, 81, 128, 77, 70, 69, 85, 65, 69, 128, 77, 70, 65, 65, 128, + 77, 69, 90, 90, 79, 128, 77, 69, 88, 128, 77, 69, 85, 212, 77, 69, 85, + 81, 128, 77, 69, 85, 78, 74, 79, 77, 78, 68, 69, 85, 81, 128, 77, 69, 85, + 78, 128, 77, 69, 84, 82, 79, 128, 77, 69, 84, 82, 73, 67, 65, 204, 77, + 69, 84, 82, 73, 65, 128, 77, 69, 84, 82, 69, 84, 69, 211, 77, 69, 84, 79, + 66, 69, 76, 85, 83, 128, 77, 69, 84, 69, 75, 128, 77, 69, 84, 69, 71, + 128, 77, 69, 84, 65, 76, 128, 77, 69, 84, 193, 77, 69, 83, 83, 69, 78, + 73, 65, 206, 77, 69, 83, 83, 65, 71, 69, 128, 77, 69, 83, 83, 65, 71, + 197, 77, 69, 83, 79, 128, 77, 69, 83, 73, 128, 77, 69, 83, 72, 128, 77, + 69, 82, 80, 69, 82, 83, 79, 78, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, + 82, 75, 72, 193, 77, 69, 82, 73, 68, 73, 65, 78, 83, 128, 77, 69, 82, 73, + 128, 77, 69, 82, 71, 69, 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, + 82, 67, 85, 82, 217, 77, 69, 78, 79, 82, 65, 200, 77, 69, 78, 79, 69, + 128, 77, 69, 78, 68, 85, 84, 128, 77, 69, 78, 128, 77, 69, 77, 79, 128, + 77, 69, 77, 66, 69, 82, 83, 72, 73, 80, 128, 77, 69, 77, 66, 69, 82, 128, + 77, 69, 77, 66, 69, 210, 77, 69, 77, 45, 81, 79, 80, 72, 128, 77, 69, 77, + 128, 77, 69, 205, 77, 69, 76, 79, 68, 73, 195, 77, 69, 76, 73, 75, 128, + 77, 69, 73, 90, 73, 128, 77, 69, 71, 65, 84, 79, 78, 128, 77, 69, 71, 65, + 80, 72, 79, 78, 69, 128, 77, 69, 71, 65, 76, 73, 128, 77, 69, 69, 84, 79, + 82, 85, 128, 77, 69, 69, 84, 69, 201, 77, 69, 69, 84, 128, 77, 69, 69, + 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, 202, 77, 69, 69, 69, 69, + 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 68, 73, 85, 205, 77, 69, 68, + 73, 69, 86, 65, 204, 77, 69, 68, 73, 67, 73, 78, 69, 128, 77, 69, 68, 73, + 67, 65, 204, 77, 69, 68, 73, 65, 204, 77, 69, 68, 69, 70, 65, 73, 68, 82, + 73, 206, 77, 69, 68, 65, 76, 128, 77, 69, 67, 72, 65, 78, 73, 67, 65, + 204, 77, 69, 65, 84, 128, 77, 69, 65, 212, 77, 69, 65, 83, 85, 82, 69, + 196, 77, 69, 65, 83, 85, 82, 69, 128, 77, 69, 65, 83, 85, 82, 197, 77, + 69, 45, 77, 65, 128, 77, 69, 45, 50, 128, 77, 69, 45, 49, 128, 77, 68, + 85, 206, 77, 196, 77, 67, 72, 213, 77, 67, 72, 65, 206, 77, 195, 77, 66, + 85, 85, 128, 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, 128, 77, 66, 85, + 69, 128, 77, 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, 69, 128, 77, 66, + 79, 79, 128, 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, 66, 73, 212, 77, + 66, 73, 82, 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, 66, 69, 85, 88, + 128, 77, 66, 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, 128, 77, 66, 69, + 82, 65, 69, 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, 75, 69, 69, 84, + 128, 77, 66, 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, 81, 128, 77, 66, + 65, 78, 89, 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, 77, 66, 65, 65, 75, + 69, 84, 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, 77, 66, 193, 77, 66, + 52, 128, 77, 66, 51, 128, 77, 66, 50, 128, 77, 65, 89, 69, 203, 77, 65, + 89, 65, 78, 78, 65, 128, 77, 65, 89, 65, 206, 77, 65, 89, 128, 77, 65, + 88, 73, 77, 73, 90, 69, 128, 77, 65, 88, 73, 77, 65, 128, 77, 65, 88, + 128, 77, 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, 77, 65, 84, 82, + 73, 88, 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, 65, 84, 128, + 77, 65, 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, 83, 83, 65, 71, + 69, 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, 77, 65, 83, 72, + 70, 65, 65, 84, 128, 77, 65, 83, 72, 50, 128, 77, 65, 83, 67, 85, 76, 73, + 78, 197, 77, 65, 83, 65, 82, 65, 205, 77, 65, 82, 89, 128, 77, 65, 82, + 87, 65, 82, 201, 77, 65, 82, 85, 75, 85, 128, 77, 65, 82, 84, 89, 82, 73, + 193, 77, 65, 82, 84, 73, 65, 204, 77, 65, 82, 82, 89, 73, 78, 199, 77, + 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, 82, 65, 84, 65, 78, 128, 77, 65, + 82, 75, 211, 77, 65, 82, 75, 69, 82, 128, 77, 65, 82, 75, 45, 52, 128, + 77, 65, 82, 75, 45, 51, 128, 77, 65, 82, 75, 45, 50, 128, 77, 65, 82, 75, + 45, 49, 128, 77, 65, 82, 69, 128, 77, 65, 82, 67, 72, 69, 206, 77, 65, + 82, 67, 72, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, 84, 65, 67, 67, 65, + 84, 79, 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 83, 73, + 84, 69, 128, 77, 65, 82, 66, 85, 84, 65, 128, 77, 65, 82, 66, 85, 84, + 193, 77, 65, 82, 128, 77, 65, 81, 65, 70, 128, 77, 65, 81, 128, 77, 65, + 80, 76, 197, 77, 65, 80, 73, 81, 128, 77, 65, 208, 77, 65, 79, 128, 77, + 65, 78, 85, 65, 204, 77, 65, 78, 84, 69, 76, 80, 73, 69, 67, 197, 77, 65, + 78, 83, 89, 79, 78, 128, 77, 65, 78, 83, 85, 65, 69, 128, 77, 65, 78, 78, + 65, 218, 77, 65, 78, 78, 65, 128, 77, 65, 78, 73, 67, 72, 65, 69, 65, + 206, 77, 65, 78, 71, 79, 128, 77, 65, 78, 71, 65, 76, 65, 77, 128, 77, + 65, 78, 68, 65, 82, 73, 78, 128, 77, 65, 78, 68, 65, 73, 76, 73, 78, 199, + 77, 65, 78, 68, 65, 73, 195, 77, 65, 78, 67, 72, 213, 77, 65, 78, 65, + 212, 77, 65, 78, 65, 67, 76, 69, 83, 128, 77, 65, 76, 84, 69, 83, 197, + 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 69, 128, 77, 65, 76, 197, + 77, 65, 76, 65, 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, 77, 65, 75, + 83, 85, 82, 193, 77, 65, 75, 65, 83, 65, 210, 77, 65, 73, 90, 69, 128, + 77, 65, 73, 89, 65, 77, 79, 75, 128, 77, 65, 73, 84, 65, 73, 75, 72, 85, + 128, 77, 65, 73, 82, 85, 128, 77, 65, 73, 77, 85, 65, 78, 128, 77, 65, + 73, 77, 65, 76, 65, 73, 128, 77, 65, 73, 76, 66, 79, 216, 77, 65, 73, 75, + 85, 82, 79, 128, 77, 65, 73, 68, 69, 78, 128, 77, 65, 73, 128, 77, 65, + 72, 74, 79, 78, 199, 77, 65, 72, 72, 65, 128, 77, 65, 72, 65, 80, 82, 65, + 78, 65, 128, 77, 65, 72, 65, 80, 65, 75, 72, 128, 77, 65, 72, 65, 74, 65, + 78, 201, 77, 65, 72, 65, 65, 80, 82, 65, 65, 78, 193, 77, 65, 72, 128, + 77, 65, 71, 78, 73, 70, 89, 73, 78, 199, 77, 65, 71, 78, 69, 84, 128, 77, + 65, 71, 69, 128, 77, 65, 69, 83, 73, 128, 77, 65, 69, 78, 89, 73, 128, + 77, 65, 69, 78, 74, 69, 84, 128, 77, 65, 69, 77, 86, 69, 85, 88, 128, 77, + 65, 69, 77, 75, 80, 69, 78, 128, 77, 65, 69, 77, 71, 66, 73, 69, 69, 128, + 77, 65, 69, 77, 66, 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, 65, 128, + 77, 65, 69, 77, 128, 77, 65, 69, 76, 69, 69, 128, 77, 65, 69, 75, 69, 85, + 80, 128, 77, 65, 68, 89, 65, 128, 77, 65, 68, 85, 128, 77, 65, 68, 68, + 65, 72, 128, 77, 65, 68, 68, 65, 200, 77, 65, 68, 68, 65, 128, 77, 65, + 68, 68, 193, 77, 65, 67, 82, 79, 78, 45, 71, 82, 65, 86, 69, 128, 77, 65, + 67, 82, 79, 78, 45, 66, 82, 69, 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, + 65, 67, 85, 84, 69, 128, 77, 65, 67, 82, 79, 78, 128, 77, 65, 67, 82, 79, + 206, 77, 65, 67, 72, 73, 78, 69, 128, 77, 65, 65, 89, 89, 65, 65, 128, + 77, 65, 65, 73, 128, 77, 65, 65, 128, 77, 65, 50, 128, 77, 65, 45, 55, + 128, 77, 65, 45, 54, 128, 77, 65, 45, 53, 128, 77, 65, 45, 52, 128, 77, + 65, 45, 51, 128, 77, 65, 45, 50, 128, 77, 65, 45, 49, 128, 77, 49, 57, + 183, 77, 49, 57, 182, 77, 49, 57, 181, 77, 49, 57, 180, 77, 49, 57, 179, + 77, 49, 57, 178, 77, 49, 57, 177, 77, 49, 57, 176, 77, 49, 56, 185, 77, + 49, 56, 184, 77, 49, 56, 183, 77, 49, 56, 182, 77, 49, 56, 181, 77, 49, + 56, 180, 77, 49, 56, 179, 77, 49, 56, 178, 77, 49, 56, 177, 77, 49, 56, + 176, 77, 49, 55, 185, 77, 49, 55, 184, 77, 49, 55, 183, 77, 49, 55, 182, + 77, 49, 55, 181, 77, 49, 55, 180, 77, 49, 55, 179, 77, 49, 55, 178, 77, + 49, 55, 177, 77, 49, 55, 176, 77, 49, 54, 185, 77, 49, 54, 184, 77, 49, + 54, 183, 77, 49, 54, 182, 77, 49, 54, 181, 77, 49, 54, 180, 77, 49, 54, + 179, 77, 49, 54, 178, 77, 49, 54, 177, 77, 49, 54, 176, 77, 49, 53, 185, + 77, 49, 53, 184, 77, 49, 53, 183, 77, 49, 53, 182, 77, 49, 53, 181, 77, + 49, 53, 180, 77, 49, 53, 179, 77, 49, 53, 178, 77, 49, 53, 177, 77, 49, + 53, 176, 77, 49, 52, 185, 77, 49, 52, 184, 77, 49, 52, 183, 77, 49, 52, + 182, 77, 49, 52, 181, 77, 49, 52, 180, 77, 49, 52, 179, 77, 49, 52, 178, + 77, 49, 52, 177, 77, 49, 52, 176, 77, 49, 51, 185, 77, 49, 51, 184, 77, + 49, 51, 183, 77, 49, 51, 182, 77, 49, 51, 181, 77, 49, 51, 180, 77, 49, + 51, 179, 77, 49, 51, 178, 77, 49, 51, 177, 77, 49, 51, 176, 77, 49, 50, + 185, 77, 49, 50, 184, 77, 49, 50, 183, 77, 49, 50, 182, 77, 49, 50, 181, + 77, 49, 50, 180, 77, 49, 50, 179, 77, 49, 50, 178, 77, 49, 50, 177, 77, + 49, 50, 176, 77, 49, 49, 185, 77, 49, 49, 184, 77, 49, 49, 183, 77, 49, + 49, 182, 77, 49, 49, 181, 77, 49, 49, 180, 77, 49, 49, 179, 77, 49, 49, + 178, 77, 49, 49, 177, 77, 49, 49, 176, 77, 49, 48, 185, 77, 49, 48, 184, + 77, 49, 48, 183, 77, 49, 48, 182, 77, 49, 48, 181, 77, 49, 48, 180, 77, + 49, 48, 179, 77, 49, 48, 178, 77, 49, 48, 177, 77, 49, 48, 176, 77, 48, + 57, 185, 77, 48, 57, 184, 77, 48, 57, 183, 77, 48, 57, 182, 77, 48, 57, + 181, 77, 48, 57, 180, 77, 48, 57, 179, 77, 48, 57, 178, 77, 48, 57, 177, + 77, 48, 57, 176, 77, 48, 56, 185, 77, 48, 56, 184, 77, 48, 56, 183, 77, + 48, 56, 182, 77, 48, 56, 181, 77, 48, 56, 180, 77, 48, 56, 179, 77, 48, + 56, 178, 77, 48, 56, 177, 77, 48, 56, 176, 77, 48, 55, 185, 77, 48, 55, + 184, 77, 48, 55, 183, 77, 48, 55, 182, 77, 48, 55, 181, 77, 48, 55, 180, + 77, 48, 55, 179, 77, 48, 55, 178, 77, 48, 55, 177, 77, 48, 55, 176, 77, + 48, 54, 185, 77, 48, 54, 184, 77, 48, 54, 183, 77, 48, 54, 182, 77, 48, + 54, 181, 77, 48, 54, 180, 77, 48, 54, 179, 77, 48, 54, 178, 77, 48, 54, + 177, 77, 48, 54, 176, 77, 48, 53, 185, 77, 48, 53, 184, 77, 48, 53, 183, + 77, 48, 53, 182, 77, 48, 53, 181, 77, 48, 53, 180, 77, 48, 53, 179, 77, + 48, 53, 178, 77, 48, 53, 177, 77, 48, 53, 176, 77, 48, 52, 185, 77, 48, + 52, 184, 77, 48, 52, 183, 77, 48, 52, 182, 77, 48, 52, 181, 77, 48, 52, + 52, 128, 77, 48, 52, 180, 77, 48, 52, 51, 128, 77, 48, 52, 179, 77, 48, + 52, 50, 128, 77, 48, 52, 178, 77, 48, 52, 49, 128, 77, 48, 52, 177, 77, + 48, 52, 48, 65, 128, 77, 48, 52, 48, 128, 77, 48, 52, 176, 77, 48, 51, + 57, 128, 77, 48, 51, 185, 77, 48, 51, 56, 128, 77, 48, 51, 184, 77, 48, + 51, 55, 128, 77, 48, 51, 183, 77, 48, 51, 54, 128, 77, 48, 51, 182, 77, + 48, 51, 53, 128, 77, 48, 51, 181, 77, 48, 51, 52, 128, 77, 48, 51, 180, + 77, 48, 51, 51, 66, 128, 77, 48, 51, 51, 65, 128, 77, 48, 51, 51, 128, + 77, 48, 51, 179, 77, 48, 51, 50, 128, 77, 48, 51, 178, 77, 48, 51, 49, + 65, 128, 77, 48, 51, 49, 128, 77, 48, 51, 177, 77, 48, 51, 48, 128, 77, + 48, 51, 176, 77, 48, 50, 57, 128, 77, 48, 50, 185, 77, 48, 50, 56, 65, + 128, 77, 48, 50, 56, 128, 77, 48, 50, 184, 77, 48, 50, 55, 128, 77, 48, + 50, 183, 77, 48, 50, 54, 128, 77, 48, 50, 182, 77, 48, 50, 53, 128, 77, + 48, 50, 181, 77, 48, 50, 52, 65, 128, 77, 48, 50, 52, 128, 77, 48, 50, + 180, 77, 48, 50, 51, 128, 77, 48, 50, 179, 77, 48, 50, 50, 65, 128, 77, + 48, 50, 50, 128, 77, 48, 50, 178, 77, 48, 50, 49, 128, 77, 48, 50, 177, + 77, 48, 50, 48, 128, 77, 48, 50, 176, 77, 48, 49, 57, 128, 77, 48, 49, + 185, 77, 48, 49, 56, 128, 77, 48, 49, 184, 77, 48, 49, 55, 65, 128, 77, + 48, 49, 55, 128, 77, 48, 49, 183, 77, 48, 49, 54, 65, 128, 77, 48, 49, + 54, 128, 77, 48, 49, 182, 77, 48, 49, 53, 65, 128, 77, 48, 49, 53, 128, + 77, 48, 49, 181, 77, 48, 49, 52, 128, 77, 48, 49, 180, 77, 48, 49, 51, + 128, 77, 48, 49, 179, 77, 48, 49, 50, 72, 128, 77, 48, 49, 50, 71, 128, + 77, 48, 49, 50, 70, 128, 77, 48, 49, 50, 69, 128, 77, 48, 49, 50, 68, + 128, 77, 48, 49, 50, 67, 128, 77, 48, 49, 50, 66, 128, 77, 48, 49, 50, + 65, 128, 77, 48, 49, 50, 128, 77, 48, 49, 178, 77, 48, 49, 49, 128, 77, + 48, 49, 177, 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, 128, 77, 48, 49, + 176, 77, 48, 48, 57, 128, 77, 48, 48, 185, 77, 48, 48, 56, 128, 77, 48, + 48, 184, 77, 48, 48, 55, 128, 77, 48, 48, 183, 77, 48, 48, 54, 128, 77, + 48, 48, 182, 77, 48, 48, 53, 128, 77, 48, 48, 181, 77, 48, 48, 52, 128, + 77, 48, 48, 180, 77, 48, 48, 51, 65, 128, 77, 48, 48, 51, 128, 77, 48, + 48, 179, 77, 48, 48, 50, 128, 77, 48, 48, 178, 77, 48, 48, 49, 66, 128, + 77, 48, 48, 49, 65, 128, 77, 48, 48, 49, 128, 77, 48, 48, 177, 76, 218, + 76, 89, 89, 128, 76, 89, 88, 128, 76, 89, 84, 128, 76, 89, 82, 88, 128, + 76, 89, 82, 128, 76, 89, 80, 128, 76, 89, 73, 84, 128, 76, 89, 73, 78, + 199, 76, 89, 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, 76, 88, 128, 76, + 87, 79, 79, 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, 76, 87, 73, 128, + 76, 87, 69, 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, 76, 85, 88, 128, + 76, 85, 85, 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, 76, 85, 80, 128, + 76, 85, 79, 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, 80, 128, 76, 85, + 79, 128, 76, 85, 78, 71, 83, 73, 128, 76, 85, 78, 65, 84, 197, 76, 85, + 205, 76, 85, 76, 128, 76, 85, 73, 83, 128, 76, 85, 72, 85, 82, 128, 76, + 85, 72, 128, 76, 85, 200, 76, 85, 71, 71, 65, 71, 69, 128, 76, 85, 71, + 65, 76, 128, 76, 85, 71, 65, 204, 76, 85, 69, 128, 76, 85, 197, 76, 85, + 66, 128, 76, 85, 65, 69, 80, 128, 76, 85, 51, 128, 76, 85, 50, 128, 76, + 85, 178, 76, 82, 79, 128, 76, 82, 77, 128, 76, 82, 73, 128, 76, 82, 69, + 128, 76, 79, 90, 69, 78, 71, 69, 128, 76, 79, 90, 69, 78, 71, 197, 76, + 79, 88, 128, 76, 79, 87, 69, 82, 69, 196, 76, 79, 87, 69, 210, 76, 79, + 87, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 76, 79, 87, 45, 77, 73, + 196, 76, 79, 87, 45, 70, 65, 76, 76, 73, 78, 199, 76, 79, 87, 45, 185, + 76, 79, 86, 197, 76, 79, 85, 82, 69, 128, 76, 79, 85, 68, 83, 80, 69, 65, + 75, 69, 82, 128, 76, 79, 85, 68, 76, 217, 76, 79, 84, 85, 83, 128, 76, + 79, 84, 85, 211, 76, 79, 84, 73, 79, 206, 76, 79, 84, 128, 76, 79, 83, + 83, 76, 69, 83, 83, 128, 76, 79, 82, 82, 89, 128, 76, 79, 82, 82, 65, 73, + 78, 69, 128, 76, 79, 81, 128, 76, 79, 80, 128, 76, 79, 79, 84, 128, 76, + 79, 79, 80, 69, 196, 76, 79, 79, 80, 128, 76, 79, 79, 208, 76, 79, 79, + 78, 128, 76, 79, 79, 203, 76, 79, 79, 128, 76, 79, 78, 83, 85, 77, 128, + 76, 79, 78, 71, 65, 128, 76, 79, 78, 71, 193, 76, 79, 78, 71, 45, 76, 69, + 71, 71, 69, 196, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 89, 82, + 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 83, 79, 204, 76, 79, + 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 79, 83, 211, 76, 79, 78, 71, 45, + 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, 210, 76, 79, 78, 71, 45, 66, 82, + 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, 204, 76, 79, 78, 71, 45, 66, 82, + 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, 77, 65, 69, 128, 76, 79, 77, + 128, 76, 79, 205, 76, 79, 76, 76, 73, 80, 79, 80, 128, 76, 79, 76, 76, + 128, 76, 79, 71, 210, 76, 79, 71, 79, 84, 89, 80, 197, 76, 79, 71, 79, + 71, 82, 65, 205, 76, 79, 71, 128, 76, 79, 68, 69, 83, 84, 79, 78, 69, + 128, 76, 79, 67, 79, 77, 79, 84, 73, 86, 69, 128, 76, 79, 67, 75, 73, 78, + 71, 45, 83, 72, 73, 70, 212, 76, 79, 67, 203, 76, 79, 67, 65, 84, 73, 86, + 69, 128, 76, 79, 67, 65, 84, 73, 79, 78, 45, 87, 65, 76, 76, 80, 76, 65, + 78, 197, 76, 79, 67, 65, 84, 73, 79, 78, 45, 70, 76, 79, 79, 82, 80, 76, + 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, 78, 128, 76, 79, 67, 65, 84, 73, + 79, 206, 76, 79, 66, 83, 84, 69, 82, 128, 76, 79, 65, 128, 76, 78, 128, + 76, 76, 85, 85, 128, 76, 76, 79, 79, 128, 76, 76, 76, 85, 85, 128, 76, + 76, 76, 85, 128, 76, 76, 76, 79, 79, 128, 76, 76, 76, 79, 128, 76, 76, + 76, 73, 73, 128, 76, 76, 76, 73, 128, 76, 76, 76, 69, 69, 128, 76, 76, + 76, 69, 128, 76, 76, 76, 65, 85, 128, 76, 76, 76, 65, 73, 128, 76, 76, + 76, 65, 65, 128, 76, 76, 76, 65, 128, 76, 76, 76, 128, 76, 76, 72, 65, + 128, 76, 76, 65, 77, 65, 128, 76, 74, 85, 68, 73, 74, 69, 128, 76, 74, + 69, 128, 76, 74, 128, 76, 73, 90, 65, 82, 68, 128, 76, 73, 88, 128, 76, + 73, 87, 78, 128, 76, 73, 86, 82, 197, 76, 73, 84, 84, 76, 69, 128, 76, + 73, 84, 84, 76, 197, 76, 73, 84, 84, 69, 210, 76, 73, 84, 82, 193, 76, + 73, 84, 200, 76, 73, 83, 213, 76, 73, 83, 128, 76, 73, 82, 193, 76, 73, + 81, 85, 73, 196, 76, 73, 81, 128, 76, 73, 80, 83, 84, 73, 67, 75, 128, + 76, 73, 80, 211, 76, 73, 208, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, + 75, 69, 196, 76, 73, 78, 203, 76, 73, 78, 71, 83, 65, 128, 76, 73, 78, + 69, 83, 128, 76, 73, 78, 69, 211, 76, 73, 78, 69, 45, 57, 128, 76, 73, + 78, 69, 45, 55, 128, 76, 73, 78, 69, 45, 51, 128, 76, 73, 78, 69, 45, 49, + 128, 76, 73, 77, 77, 85, 52, 128, 76, 73, 77, 77, 85, 50, 128, 76, 73, + 77, 77, 85, 128, 76, 73, 77, 77, 213, 76, 73, 77, 73, 84, 69, 196, 76, + 73, 77, 73, 84, 65, 84, 73, 79, 78, 128, 76, 73, 77, 73, 84, 128, 76, 73, + 77, 69, 128, 76, 73, 77, 66, 213, 76, 73, 77, 66, 211, 76, 73, 77, 194, + 76, 73, 76, 89, 128, 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, 128, 76, + 73, 71, 72, 84, 78, 73, 78, 71, 128, 76, 73, 71, 72, 84, 78, 73, 78, 199, + 76, 73, 71, 72, 84, 72, 79, 85, 83, 69, 128, 76, 73, 71, 72, 84, 128, 76, + 73, 71, 65, 84, 73, 78, 199, 76, 73, 70, 84, 69, 82, 128, 76, 73, 70, 69, + 128, 76, 73, 69, 88, 128, 76, 73, 69, 84, 128, 76, 73, 69, 80, 128, 76, + 73, 69, 69, 128, 76, 73, 69, 128, 76, 73, 68, 128, 76, 73, 67, 75, 73, + 78, 199, 76, 73, 66, 82, 65, 128, 76, 73, 66, 69, 82, 84, 89, 128, 76, + 73, 65, 66, 73, 76, 73, 84, 217, 76, 72, 73, 73, 128, 76, 72, 65, 86, 73, + 89, 65, 78, 73, 128, 76, 72, 65, 199, 76, 72, 65, 65, 128, 76, 72, 128, + 76, 69, 90, 72, 128, 76, 69, 88, 128, 76, 69, 86, 73, 84, 65, 84, 73, 78, + 71, 128, 76, 69, 85, 77, 128, 76, 69, 85, 65, 69, 80, 128, 76, 69, 85, + 65, 69, 77, 128, 76, 69, 85, 128, 76, 69, 213, 76, 69, 84, 84, 69, 82, + 83, 128, 76, 69, 84, 84, 69, 82, 128, 76, 69, 212, 76, 69, 83, 83, 69, + 210, 76, 69, 83, 83, 45, 84, 72, 65, 78, 128, 76, 69, 83, 83, 45, 84, 72, + 65, 206, 76, 69, 83, 72, 128, 76, 69, 80, 67, 72, 193, 76, 69, 80, 128, + 76, 69, 79, 80, 65, 82, 68, 128, 76, 69, 79, 128, 76, 69, 78, 84, 73, 67, + 85, 76, 65, 210, 76, 69, 78, 73, 83, 128, 76, 69, 78, 73, 211, 76, 69, + 78, 71, 84, 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, 72, 45, 55, 128, + 76, 69, 78, 71, 84, 72, 45, 54, 128, 76, 69, 78, 71, 84, 72, 45, 53, 128, + 76, 69, 78, 71, 84, 72, 45, 52, 128, 76, 69, 78, 71, 84, 72, 45, 51, 128, + 76, 69, 78, 71, 84, 72, 45, 50, 128, 76, 69, 78, 71, 84, 72, 45, 49, 128, + 76, 69, 78, 71, 84, 200, 76, 69, 78, 71, 65, 128, 76, 69, 78, 71, 193, + 76, 69, 77, 79, 78, 128, 76, 69, 77, 79, 73, 128, 76, 69, 76, 69, 84, + 128, 76, 69, 76, 69, 212, 76, 69, 203, 76, 69, 73, 77, 77, 65, 128, 76, + 69, 73, 77, 77, 193, 76, 69, 73, 128, 76, 69, 71, 83, 128, 76, 69, 71, + 73, 79, 78, 128, 76, 69, 71, 69, 84, 79, 211, 76, 69, 71, 128, 76, 69, + 199, 76, 69, 70, 84, 87, 65, 82, 68, 83, 128, 76, 69, 70, 84, 45, 84, 79, + 45, 82, 73, 71, 72, 212, 76, 69, 70, 84, 45, 83, 84, 69, 205, 76, 69, 70, + 84, 45, 83, 73, 68, 197, 76, 69, 70, 84, 45, 83, 72, 65, 68, 69, 196, 76, + 69, 70, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 76, 69, 70, 84, 45, 76, + 73, 71, 72, 84, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 68, 69, 196, 76, + 69, 70, 84, 45, 72, 65, 78, 196, 76, 69, 70, 84, 45, 70, 65, 67, 73, 78, + 199, 76, 69, 70, 84, 128, 76, 69, 69, 82, 65, 69, 87, 65, 128, 76, 69, + 69, 75, 128, 76, 69, 69, 69, 69, 128, 76, 69, 68, 71, 69, 82, 128, 76, + 69, 65, 84, 72, 69, 82, 128, 76, 69, 65, 70, 217, 76, 69, 65, 70, 128, + 76, 69, 65, 198, 76, 69, 65, 68, 69, 82, 128, 76, 69, 65, 196, 76, 68, + 65, 78, 128, 76, 68, 50, 128, 76, 67, 201, 76, 67, 197, 76, 65, 90, 217, + 76, 65, 89, 65, 78, 78, 65, 128, 76, 65, 88, 128, 76, 65, 87, 128, 76, + 65, 215, 76, 65, 85, 76, 65, 128, 76, 65, 85, 75, 65, 218, 76, 65, 85, + 74, 128, 76, 65, 85, 71, 72, 73, 78, 71, 128, 76, 65, 84, 73, 78, 65, 84, + 197, 76, 65, 84, 73, 75, 128, 76, 65, 84, 69, 82, 65, 204, 76, 65, 84, + 197, 76, 65, 83, 212, 76, 65, 82, 89, 78, 71, 69, 65, 204, 76, 65, 82, + 201, 76, 65, 82, 71, 69, 83, 84, 128, 76, 65, 82, 71, 69, 210, 76, 65, + 82, 71, 69, 128, 76, 65, 82, 71, 197, 76, 65, 81, 128, 76, 65, 80, 65, + 81, 128, 76, 65, 207, 76, 65, 78, 84, 69, 82, 78, 128, 76, 65, 78, 71, + 85, 65, 71, 197, 76, 65, 78, 69, 83, 128, 76, 65, 78, 196, 76, 65, 78, + 128, 76, 65, 77, 80, 128, 76, 65, 77, 69, 68, 72, 128, 76, 65, 77, 69, + 68, 128, 76, 65, 77, 69, 196, 76, 65, 77, 69, 128, 76, 65, 77, 197, 76, + 65, 77, 68, 65, 128, 76, 65, 77, 68, 128, 76, 65, 77, 66, 68, 193, 76, + 65, 77, 65, 68, 72, 128, 76, 65, 76, 128, 76, 65, 204, 76, 65, 75, 75, + 72, 65, 78, 71, 89, 65, 79, 128, 76, 65, 75, 72, 65, 78, 128, 76, 65, 75, + 72, 128, 76, 65, 75, 200, 76, 65, 75, 45, 55, 52, 57, 128, 76, 65, 75, + 45, 55, 50, 52, 128, 76, 65, 75, 45, 54, 54, 56, 128, 76, 65, 75, 45, 54, + 52, 56, 128, 76, 65, 75, 45, 54, 52, 184, 76, 65, 75, 45, 54, 51, 54, + 128, 76, 65, 75, 45, 54, 49, 55, 128, 76, 65, 75, 45, 54, 49, 183, 76, + 65, 75, 45, 54, 48, 56, 128, 76, 65, 75, 45, 53, 53, 48, 128, 76, 65, 75, + 45, 52, 57, 53, 128, 76, 65, 75, 45, 52, 57, 51, 128, 76, 65, 75, 45, 52, + 57, 50, 128, 76, 65, 75, 45, 52, 57, 48, 128, 76, 65, 75, 45, 52, 56, 51, + 128, 76, 65, 75, 45, 52, 55, 48, 128, 76, 65, 75, 45, 52, 53, 55, 128, + 76, 65, 75, 45, 52, 53, 48, 128, 76, 65, 75, 45, 52, 52, 57, 128, 76, 65, + 75, 45, 52, 52, 185, 76, 65, 75, 45, 52, 52, 49, 128, 76, 65, 75, 45, 51, + 57, 48, 128, 76, 65, 75, 45, 51, 56, 52, 128, 76, 65, 75, 45, 51, 56, 51, + 128, 76, 65, 75, 45, 51, 52, 56, 128, 76, 65, 75, 45, 51, 52, 55, 128, + 76, 65, 75, 45, 51, 52, 51, 128, 76, 65, 75, 45, 50, 54, 54, 128, 76, 65, + 75, 45, 50, 54, 53, 128, 76, 65, 75, 45, 50, 51, 56, 128, 76, 65, 75, 45, + 50, 50, 56, 128, 76, 65, 75, 45, 50, 50, 53, 128, 76, 65, 75, 45, 50, 50, + 48, 128, 76, 65, 75, 45, 50, 49, 57, 128, 76, 65, 75, 45, 50, 49, 48, + 128, 76, 65, 75, 45, 49, 52, 50, 128, 76, 65, 75, 45, 49, 51, 48, 128, + 76, 65, 75, 45, 48, 57, 50, 128, 76, 65, 75, 45, 48, 56, 49, 128, 76, 65, + 75, 45, 48, 56, 177, 76, 65, 75, 45, 48, 56, 48, 128, 76, 65, 75, 45, 48, + 55, 185, 76, 65, 75, 45, 48, 54, 50, 128, 76, 65, 75, 45, 48, 53, 49, + 128, 76, 65, 75, 45, 48, 53, 48, 128, 76, 65, 75, 45, 48, 51, 48, 128, + 76, 65, 75, 45, 48, 50, 53, 128, 76, 65, 75, 45, 48, 50, 49, 128, 76, 65, + 75, 45, 48, 50, 48, 128, 76, 65, 75, 45, 48, 48, 51, 128, 76, 65, 74, 65, + 78, 89, 65, 76, 65, 78, 128, 76, 65, 73, 78, 199, 76, 65, 201, 76, 65, + 72, 83, 72, 85, 128, 76, 65, 72, 128, 76, 65, 71, 85, 83, 128, 76, 65, + 71, 213, 76, 65, 71, 65, 82, 128, 76, 65, 71, 65, 210, 76, 65, 71, 65, + 66, 128, 76, 65, 71, 65, 194, 76, 65, 69, 86, 128, 76, 65, 69, 128, 76, + 65, 68, 217, 76, 65, 67, 82, 79, 83, 83, 197, 76, 65, 67, 75, 128, 76, + 65, 67, 65, 128, 76, 65, 66, 79, 85, 82, 73, 78, 71, 128, 76, 65, 66, 79, + 82, 128, 76, 65, 66, 73, 65, 76, 73, 90, 65, 84, 73, 79, 206, 76, 65, 66, + 73, 65, 204, 76, 65, 66, 69, 76, 128, 76, 65, 66, 65, 84, 128, 76, 65, + 194, 76, 65, 65, 78, 65, 69, 128, 76, 65, 65, 78, 128, 76, 65, 65, 77, + 85, 128, 76, 65, 65, 77, 128, 76, 65, 65, 73, 128, 76, 54, 128, 76, 52, + 128, 76, 51, 128, 76, 50, 128, 76, 48, 48, 54, 65, 128, 76, 48, 48, 50, + 65, 128, 76, 45, 84, 89, 80, 197, 76, 45, 83, 72, 65, 80, 69, 196, 75, + 89, 85, 82, 73, 73, 128, 75, 89, 85, 128, 75, 89, 79, 128, 75, 89, 76, + 73, 83, 77, 65, 128, 75, 89, 73, 128, 75, 89, 69, 128, 75, 89, 65, 84, + 72, 79, 211, 75, 89, 65, 65, 128, 75, 89, 65, 128, 75, 88, 87, 73, 128, + 75, 88, 87, 69, 69, 128, 75, 88, 87, 69, 128, 75, 88, 87, 65, 65, 128, + 75, 88, 87, 65, 128, 75, 88, 85, 128, 75, 88, 79, 128, 75, 88, 73, 128, + 75, 88, 69, 69, 128, 75, 88, 69, 128, 75, 88, 65, 65, 128, 75, 88, 65, + 128, 75, 87, 86, 128, 75, 87, 85, 51, 49, 56, 128, 75, 87, 79, 79, 128, + 75, 87, 79, 128, 75, 87, 77, 128, 75, 87, 73, 73, 128, 75, 87, 73, 128, + 75, 87, 69, 69, 128, 75, 87, 69, 128, 75, 87, 66, 128, 75, 87, 65, 89, + 128, 75, 87, 65, 69, 84, 128, 75, 87, 65, 65, 128, 75, 86, 65, 128, 75, + 86, 128, 75, 85, 90, 72, 73, 128, 75, 85, 88, 128, 75, 85, 86, 128, 75, + 85, 85, 72, 128, 75, 85, 84, 128, 75, 85, 83, 77, 65, 128, 75, 85, 83, + 72, 85, 50, 128, 75, 85, 83, 72, 85, 178, 75, 85, 82, 88, 128, 75, 85, + 82, 85, 90, 69, 73, 82, 79, 128, 75, 85, 82, 84, 128, 75, 85, 82, 79, 79, + 78, 69, 128, 75, 85, 82, 128, 75, 85, 210, 75, 85, 81, 128, 75, 85, 79, + 88, 128, 75, 85, 79, 80, 128, 75, 85, 79, 208, 75, 85, 79, 77, 128, 75, + 85, 79, 128, 75, 85, 78, 71, 128, 75, 85, 78, 68, 68, 65, 76, 73, 89, 65, + 128, 75, 85, 76, 128, 75, 85, 204, 75, 85, 71, 128, 75, 85, 69, 84, 128, + 75, 85, 66, 128, 75, 85, 65, 86, 128, 75, 85, 65, 66, 128, 75, 85, 65, + 128, 75, 85, 55, 128, 75, 85, 52, 128, 75, 85, 180, 75, 85, 51, 128, 75, + 85, 179, 75, 85, 45, 55, 128, 75, 85, 45, 54, 128, 75, 85, 45, 53, 128, + 75, 85, 45, 52, 128, 75, 85, 45, 51, 128, 75, 85, 45, 50, 128, 75, 85, + 45, 49, 128, 75, 84, 128, 75, 83, 83, 85, 85, 128, 75, 83, 83, 85, 128, + 75, 83, 83, 79, 79, 128, 75, 83, 83, 79, 128, 75, 83, 83, 73, 73, 128, + 75, 83, 83, 73, 128, 75, 83, 83, 69, 69, 128, 75, 83, 83, 69, 128, 75, + 83, 83, 65, 85, 128, 75, 83, 83, 65, 73, 128, 75, 83, 83, 65, 65, 128, + 75, 83, 83, 65, 128, 75, 83, 83, 128, 75, 83, 73, 128, 75, 82, 79, 78, + 79, 83, 128, 75, 82, 69, 77, 65, 83, 84, 73, 128, 75, 82, 65, 84, 73, 77, + 79, 89, 80, 79, 82, 82, 79, 79, 78, 128, 75, 82, 65, 84, 73, 77, 79, 75, + 79, 85, 70, 73, 83, 77, 65, 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, 128, + 75, 82, 65, 84, 73, 77, 193, 75, 80, 85, 128, 75, 80, 79, 81, 128, 75, + 80, 79, 79, 128, 75, 80, 79, 128, 75, 80, 73, 128, 75, 80, 69, 85, 88, + 128, 75, 80, 69, 69, 128, 75, 80, 69, 128, 75, 80, 65, 82, 65, 81, 128, + 75, 80, 65, 78, 128, 75, 80, 65, 72, 128, 75, 80, 65, 128, 75, 80, 128, + 75, 79, 88, 128, 75, 79, 86, 85, 85, 128, 75, 79, 86, 128, 75, 79, 84, + 79, 128, 75, 79, 82, 85, 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, 128, + 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, 78, 73, 195, 75, 79, 81, 78, 68, + 79, 78, 128, 75, 79, 80, 80, 65, 128, 75, 79, 80, 128, 75, 79, 79, 86, + 128, 75, 79, 79, 80, 79, 128, 75, 79, 79, 77, 85, 85, 84, 128, 75, 79, + 79, 66, 128, 75, 79, 79, 128, 75, 79, 78, 84, 69, 86, 77, 65, 128, 75, + 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, 201, 75, 79, 77, 66, 85, 86, 65, + 128, 75, 79, 77, 66, 85, 86, 193, 75, 79, 77, 66, 213, 75, 79, 75, 79, + 128, 75, 79, 75, 69, 128, 75, 79, 75, 128, 75, 79, 203, 75, 79, 73, 78, + 73, 128, 75, 79, 73, 128, 75, 79, 201, 75, 79, 72, 128, 75, 79, 71, 72, + 79, 77, 128, 75, 79, 69, 84, 128, 75, 79, 66, 128, 75, 79, 65, 76, 65, + 128, 75, 79, 65, 128, 75, 79, 45, 75, 73, 128, 75, 79, 45, 51, 128, 75, + 79, 45, 50, 128, 75, 79, 45, 49, 128, 75, 78, 85, 67, 75, 76, 69, 83, + 128, 75, 78, 85, 67, 75, 76, 69, 128, 75, 78, 79, 66, 83, 128, 75, 78, + 73, 71, 72, 84, 45, 82, 79, 79, 75, 128, 75, 78, 73, 71, 72, 84, 45, 81, + 85, 69, 69, 78, 128, 75, 78, 73, 71, 72, 84, 45, 66, 73, 83, 72, 79, 80, + 128, 75, 78, 73, 71, 72, 84, 128, 75, 78, 73, 71, 72, 212, 75, 78, 73, + 70, 69, 128, 75, 78, 73, 70, 197, 75, 78, 69, 69, 76, 73, 78, 199, 75, + 77, 128, 75, 205, 75, 76, 73, 84, 79, 78, 128, 75, 76, 65, 83, 77, 65, + 128, 75, 76, 65, 83, 77, 193, 75, 76, 65, 128, 75, 76, 128, 75, 75, 79, + 128, 75, 75, 73, 128, 75, 75, 69, 69, 128, 75, 75, 69, 128, 75, 75, 65, + 128, 75, 75, 128, 75, 74, 69, 128, 75, 73, 89, 69, 79, 75, 45, 84, 73, + 75, 69, 85, 84, 128, 75, 73, 89, 69, 79, 75, 45, 83, 73, 79, 83, 45, 75, + 73, 89, 69, 79, 75, 128, 75, 73, 89, 69, 79, 75, 45, 82, 73, 69, 85, 76, + 128, 75, 73, 89, 69, 79, 75, 45, 80, 73, 69, 85, 80, 128, 75, 73, 89, 69, + 79, 75, 45, 78, 73, 69, 85, 78, 128, 75, 73, 89, 69, 79, 75, 45, 75, 72, + 73, 69, 85, 75, 72, 128, 75, 73, 89, 69, 79, 75, 45, 67, 72, 73, 69, 85, + 67, 72, 128, 75, 73, 89, 69, 79, 203, 75, 73, 88, 128, 75, 73, 87, 73, + 70, 82, 85, 73, 84, 128, 75, 73, 87, 128, 75, 73, 86, 128, 75, 73, 84, + 69, 128, 75, 73, 84, 128, 75, 73, 83, 83, 73, 78, 199, 75, 73, 83, 83, + 128, 75, 73, 83, 211, 75, 73, 83, 73, 77, 53, 128, 75, 73, 83, 73, 77, + 181, 75, 73, 83, 72, 128, 75, 73, 83, 65, 76, 128, 75, 73, 82, 79, 87, + 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, 69, 69, 84, 79, 82, 85, 128, 75, + 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, 75, 73, 82, 79, 128, 75, 73, 82, + 71, 72, 73, 218, 75, 73, 81, 128, 75, 73, 80, 128, 75, 73, 208, 75, 73, + 78, 83, 72, 73, 80, 128, 75, 73, 78, 78, 193, 75, 73, 78, 68, 69, 82, 71, + 65, 82, 84, 69, 78, 128, 75, 73, 77, 79, 78, 79, 128, 75, 73, 76, 76, 69, + 82, 128, 75, 73, 73, 90, 72, 128, 75, 73, 73, 128, 75, 73, 72, 128, 75, + 73, 69, 88, 128, 75, 73, 69, 86, 65, 206, 75, 73, 69, 80, 128, 75, 73, + 69, 69, 77, 128, 75, 73, 69, 128, 75, 73, 68, 128, 75, 73, 196, 75, 73, + 67, 75, 128, 75, 73, 66, 128, 75, 73, 65, 86, 128, 75, 73, 65, 66, 128, + 75, 73, 45, 56, 128, 75, 73, 45, 55, 128, 75, 73, 45, 54, 128, 75, 73, + 45, 53, 128, 75, 73, 45, 52, 128, 75, 73, 45, 51, 128, 75, 73, 45, 50, + 128, 75, 73, 45, 49, 128, 75, 72, 90, 128, 75, 72, 87, 65, 73, 128, 75, + 72, 85, 69, 78, 45, 76, 85, 197, 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, + 87, 65, 68, 201, 75, 72, 85, 68, 65, 77, 128, 75, 72, 85, 65, 84, 128, + 75, 72, 79, 85, 128, 75, 72, 79, 212, 75, 72, 79, 78, 78, 65, 128, 75, + 72, 79, 78, 128, 75, 72, 79, 77, 85, 84, 128, 75, 72, 79, 74, 75, 201, + 75, 72, 79, 128, 75, 72, 207, 75, 72, 77, 213, 75, 72, 73, 84, 128, 75, + 72, 73, 78, 89, 65, 128, 75, 72, 73, 69, 85, 75, 200, 75, 72, 73, 128, + 75, 72, 201, 75, 72, 72, 79, 128, 75, 72, 72, 65, 128, 75, 72, 69, 84, + 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, 69, 128, 75, 72, 69, 128, 75, + 72, 65, 86, 128, 75, 72, 65, 82, 79, 83, 72, 84, 72, 201, 75, 72, 65, 82, + 128, 75, 72, 65, 80, 72, 128, 75, 72, 65, 78, 199, 75, 72, 65, 78, 68, + 193, 75, 72, 65, 77, 84, 201, 75, 72, 65, 75, 65, 83, 83, 73, 65, 206, + 75, 72, 65, 73, 128, 75, 72, 65, 72, 128, 75, 72, 65, 200, 75, 72, 65, + 66, 128, 75, 72, 65, 65, 128, 75, 71, 128, 75, 69, 89, 67, 65, 80, 128, + 75, 69, 89, 67, 65, 208, 75, 69, 89, 66, 79, 65, 82, 68, 128, 75, 69, 89, + 66, 79, 65, 82, 196, 75, 69, 88, 128, 75, 69, 86, 128, 75, 69, 85, 89, + 69, 85, 88, 128, 75, 69, 85, 83, 72, 69, 85, 65, 69, 80, 128, 75, 69, 85, + 83, 69, 85, 88, 128, 75, 69, 85, 80, 85, 81, 128, 75, 69, 85, 79, 212, + 75, 69, 85, 77, 128, 75, 69, 85, 75, 69, 85, 84, 78, 68, 65, 128, 75, 69, + 85, 75, 65, 81, 128, 75, 69, 85, 65, 69, 84, 77, 69, 85, 78, 128, 75, 69, + 85, 65, 69, 82, 73, 128, 75, 69, 84, 84, 201, 75, 69, 83, 72, 50, 128, + 75, 69, 82, 69, 84, 128, 75, 69, 79, 87, 128, 75, 69, 78, 84, 73, 77, 65, + 84, 65, 128, 75, 69, 78, 84, 73, 77, 65, 84, 193, 75, 69, 78, 84, 73, 77, + 193, 75, 69, 78, 65, 84, 128, 75, 69, 78, 128, 75, 69, 206, 75, 69, 77, + 80, 85, 76, 128, 75, 69, 77, 80, 85, 204, 75, 69, 77, 80, 76, 73, 128, + 75, 69, 77, 80, 76, 201, 75, 69, 77, 80, 72, 82, 69, 78, 71, 128, 75, 69, + 77, 66, 65, 78, 71, 128, 75, 69, 76, 86, 73, 206, 75, 69, 72, 69, 72, + 128, 75, 69, 72, 69, 200, 75, 69, 72, 128, 75, 69, 70, 85, 76, 65, 128, + 75, 69, 69, 86, 128, 75, 69, 69, 83, 85, 128, 75, 69, 69, 80, 73, 78, + 199, 75, 69, 69, 78, 71, 128, 75, 69, 69, 66, 128, 75, 69, 66, 128, 75, + 69, 65, 65, 69, 128, 75, 67, 65, 76, 128, 75, 66, 128, 75, 65, 90, 65, + 75, 200, 75, 65, 89, 65, 78, 78, 65, 128, 75, 65, 89, 65, 200, 75, 65, + 88, 128, 75, 65, 87, 86, 128, 75, 65, 87, 73, 128, 75, 65, 87, 66, 128, + 75, 65, 86, 89, 75, 65, 128, 75, 65, 86, 89, 75, 193, 75, 65, 86, 128, + 75, 65, 85, 86, 128, 75, 65, 85, 78, 65, 128, 75, 65, 85, 206, 75, 65, + 85, 66, 128, 75, 65, 84, 79, 128, 75, 65, 84, 72, 73, 83, 84, 73, 128, + 75, 65, 84, 72, 65, 75, 193, 75, 65, 84, 65, 86, 65, 83, 77, 65, 128, 75, + 65, 84, 65, 86, 193, 75, 65, 84, 65, 75, 65, 78, 65, 45, 72, 73, 82, 65, + 71, 65, 78, 193, 75, 65, 83, 82, 65, 84, 65, 78, 128, 75, 65, 83, 82, 65, + 84, 65, 206, 75, 65, 83, 82, 65, 128, 75, 65, 83, 82, 193, 75, 65, 83, + 75, 65, 76, 128, 75, 65, 83, 75, 65, 204, 75, 65, 83, 72, 77, 73, 82, + 201, 75, 65, 82, 83, 72, 65, 78, 65, 128, 75, 65, 82, 79, 82, 73, 73, + 128, 75, 65, 82, 79, 82, 65, 78, 128, 75, 65, 82, 79, 82, 128, 75, 65, + 82, 207, 75, 65, 82, 69, 206, 75, 65, 82, 65, 84, 84, 79, 128, 75, 65, + 82, 65, 78, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, 83, 65, 78, 71, 80, + 73, 69, 85, 80, 128, 75, 65, 80, 89, 69, 79, 85, 78, 82, 73, 69, 85, 76, + 128, 75, 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, 85, 80, 72, 128, 75, + 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, 75, 65, 80, 80, 65, + 128, 75, 65, 80, 80, 193, 75, 65, 80, 79, 128, 75, 65, 80, 72, 128, 75, + 65, 80, 65, 76, 128, 75, 65, 80, 65, 128, 75, 65, 208, 75, 65, 78, 84, + 65, 74, 193, 75, 65, 78, 78, 65, 68, 193, 75, 65, 78, 71, 65, 82, 79, 79, + 128, 75, 65, 78, 71, 128, 75, 65, 78, 199, 75, 65, 78, 65, 75, 79, 128, + 75, 65, 77, 52, 128, 75, 65, 77, 50, 128, 75, 65, 77, 128, 75, 65, 75, + 79, 128, 75, 65, 75, 65, 66, 65, 84, 128, 75, 65, 75, 128, 75, 65, 203, + 75, 65, 73, 86, 128, 75, 65, 73, 84, 72, 201, 75, 65, 73, 82, 73, 128, + 75, 65, 73, 66, 128, 75, 65, 73, 128, 75, 65, 201, 75, 65, 70, 65, 128, + 75, 65, 70, 128, 75, 65, 198, 75, 65, 68, 53, 128, 75, 65, 68, 181, 75, + 65, 68, 52, 128, 75, 65, 68, 51, 128, 75, 65, 68, 179, 75, 65, 68, 50, + 128, 75, 65, 68, 128, 75, 65, 66, 193, 75, 65, 66, 128, 75, 65, 65, 86, + 128, 75, 65, 65, 73, 128, 75, 65, 65, 70, 85, 128, 75, 65, 65, 70, 128, + 75, 65, 65, 67, 85, 128, 75, 65, 65, 66, 65, 128, 75, 65, 65, 66, 128, + 75, 65, 50, 128, 75, 65, 178, 75, 65, 45, 75, 69, 128, 75, 65, 45, 57, + 128, 75, 65, 45, 56, 128, 75, 65, 45, 55, 128, 75, 65, 45, 54, 128, 75, + 65, 45, 53, 128, 75, 65, 45, 52, 128, 75, 65, 45, 51, 128, 75, 65, 45, + 50, 128, 75, 65, 45, 49, 49, 128, 75, 65, 45, 49, 48, 128, 75, 65, 45, + 49, 128, 75, 48, 48, 56, 128, 75, 48, 48, 55, 128, 75, 48, 48, 54, 128, + 75, 48, 48, 53, 128, 75, 48, 48, 52, 128, 75, 48, 48, 51, 128, 75, 48, + 48, 50, 128, 75, 48, 48, 49, 128, 74, 87, 65, 128, 74, 85, 85, 128, 74, + 85, 84, 128, 74, 85, 83, 84, 73, 70, 73, 67, 65, 84, 73, 79, 78, 128, 74, + 85, 80, 73, 84, 69, 82, 128, 74, 85, 79, 84, 128, 74, 85, 79, 80, 128, + 74, 85, 78, 79, 128, 74, 85, 78, 71, 83, 69, 79, 78, 199, 74, 85, 78, 69, + 128, 74, 85, 76, 89, 128, 74, 85, 71, 71, 76, 73, 78, 71, 128, 74, 85, + 69, 85, 73, 128, 74, 85, 68, 85, 76, 128, 74, 85, 68, 71, 69, 128, 74, + 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200, 74, 79, 89, 83, 84, 73, + 67, 75, 128, 74, 79, 89, 79, 85, 211, 74, 79, 89, 128, 74, 79, 86, 69, + 128, 74, 79, 212, 74, 79, 78, 71, 128, 74, 79, 78, 193, 74, 79, 75, 69, + 82, 128, 74, 79, 73, 78, 84, 83, 128, 74, 79, 73, 78, 69, 68, 128, 74, + 79, 73, 78, 128, 74, 79, 65, 128, 74, 78, 89, 65, 128, 74, 74, 89, 88, + 128, 74, 74, 89, 84, 128, 74, 74, 89, 80, 128, 74, 74, 89, 128, 74, 74, + 85, 88, 128, 74, 74, 85, 84, 128, 74, 74, 85, 82, 88, 128, 74, 74, 85, + 82, 128, 74, 74, 85, 80, 128, 74, 74, 85, 79, 88, 128, 74, 74, 85, 79, + 80, 128, 74, 74, 85, 79, 128, 74, 74, 85, 128, 74, 74, 79, 88, 128, 74, + 74, 79, 84, 128, 74, 74, 79, 80, 128, 74, 74, 79, 128, 74, 74, 73, 88, + 128, 74, 74, 73, 84, 128, 74, 74, 73, 80, 128, 74, 74, 73, 69, 88, 128, + 74, 74, 73, 69, 84, 128, 74, 74, 73, 69, 80, 128, 74, 74, 73, 69, 128, + 74, 74, 73, 128, 74, 74, 69, 69, 128, 74, 74, 69, 128, 74, 74, 65, 128, + 74, 73, 76, 128, 74, 73, 73, 77, 128, 74, 73, 73, 128, 74, 73, 72, 86, + 65, 77, 85, 76, 73, 89, 65, 128, 74, 73, 71, 83, 65, 215, 74, 73, 65, + 128, 74, 72, 79, 88, 128, 74, 72, 79, 128, 74, 72, 69, 72, 128, 74, 72, + 65, 89, 73, 78, 128, 74, 72, 65, 78, 128, 74, 72, 65, 77, 128, 74, 72, + 65, 65, 128, 74, 72, 65, 128, 74, 69, 85, 128, 74, 69, 82, 85, 83, 65, + 76, 69, 77, 128, 74, 69, 82, 65, 206, 74, 69, 82, 65, 128, 74, 69, 82, + 128, 74, 69, 72, 128, 74, 69, 200, 74, 69, 71, 79, 71, 65, 78, 128, 74, + 69, 69, 77, 128, 74, 69, 69, 205, 74, 69, 65, 78, 83, 128, 74, 65, 89, + 78, 128, 74, 65, 89, 73, 78, 128, 74, 65, 89, 65, 78, 78, 65, 128, 74, + 65, 87, 128, 74, 65, 86, 73, 89, 65, 78, 73, 128, 74, 65, 86, 65, 78, 69, + 83, 197, 74, 65, 85, 128, 74, 65, 82, 128, 74, 65, 80, 65, 78, 69, 83, + 197, 74, 65, 80, 65, 78, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, + 76, 76, 65, 74, 65, 76, 65, 76, 79, 85, 72, 79, 85, 128, 74, 65, 73, 206, + 74, 65, 73, 128, 74, 65, 72, 128, 74, 65, 68, 69, 128, 74, 65, 67, 75, + 83, 128, 74, 65, 67, 75, 45, 79, 45, 76, 65, 78, 84, 69, 82, 78, 128, 74, + 65, 67, 203, 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 73, 90, 72, + 73, 84, 83, 65, 128, 73, 90, 72, 73, 84, 83, 193, 73, 90, 72, 69, 128, + 73, 90, 65, 75, 65, 89, 193, 73, 89, 69, 75, 128, 73, 89, 65, 78, 78, 65, + 128, 73, 85, 74, 65, 128, 73, 84, 211, 73, 84, 69, 82, 65, 84, 73, 79, + 206, 73, 84, 69, 77, 128, 73, 83, 83, 72, 65, 82, 128, 73, 83, 79, 83, + 67, 69, 76, 69, 211, 73, 83, 79, 78, 128, 73, 83, 79, 206, 73, 83, 79, + 76, 65, 84, 69, 128, 73, 83, 76, 65, 78, 68, 128, 73, 83, 69, 78, 45, 73, + 83, 69, 78, 128, 73, 83, 65, 75, 73, 193, 73, 83, 45, 80, 73, 76, 76, 65, + 128, 73, 82, 85, 89, 65, 78, 78, 65, 128, 73, 82, 85, 85, 89, 65, 78, 78, + 65, 128, 73, 82, 79, 78, 45, 67, 79, 80, 80, 69, 210, 73, 82, 79, 78, + 128, 73, 82, 66, 128, 73, 79, 84, 73, 70, 73, 69, 196, 73, 79, 84, 65, + 84, 69, 196, 73, 79, 84, 65, 128, 73, 79, 84, 193, 73, 79, 82, 128, 73, + 79, 78, 71, 128, 73, 79, 68, 72, 65, 68, 72, 128, 73, 78, 86, 73, 83, 73, + 66, 76, 197, 73, 78, 86, 69, 82, 84, 69, 68, 128, 73, 78, 86, 69, 82, 84, + 69, 196, 73, 78, 86, 69, 82, 84, 69, 66, 82, 65, 84, 69, 128, 73, 78, 86, + 69, 82, 83, 197, 73, 78, 84, 82, 79, 68, 85, 67, 69, 82, 128, 73, 78, 84, + 73, 128, 73, 78, 84, 69, 82, 83, 89, 76, 76, 65, 66, 73, 195, 73, 78, 84, + 69, 82, 83, 69, 67, 84, 73, 79, 78, 128, 73, 78, 84, 69, 82, 83, 69, 67, + 84, 73, 79, 206, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 78, 199, 73, 78, + 84, 69, 82, 82, 79, 66, 65, 78, 71, 128, 73, 78, 84, 69, 82, 82, 79, 66, + 65, 78, 199, 73, 78, 84, 69, 82, 80, 79, 76, 65, 84, 73, 79, 206, 73, 78, + 84, 69, 82, 76, 79, 67, 75, 69, 196, 73, 78, 84, 69, 82, 76, 73, 78, 69, + 65, 210, 73, 78, 84, 69, 82, 76, 65, 67, 69, 196, 73, 78, 84, 69, 82, 73, + 79, 210, 73, 78, 84, 69, 82, 69, 83, 212, 73, 78, 84, 69, 82, 67, 65, 76, + 65, 84, 69, 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 78, 128, 73, 78, + 84, 69, 71, 82, 65, 84, 73, 79, 206, 73, 78, 84, 69, 71, 82, 65, 76, 128, + 73, 78, 84, 69, 71, 82, 65, 204, 73, 78, 83, 85, 76, 65, 210, 73, 78, 83, + 84, 82, 85, 77, 69, 78, 84, 65, 204, 73, 78, 83, 73, 68, 69, 128, 73, 78, + 83, 73, 68, 197, 73, 78, 83, 69, 82, 84, 73, 79, 206, 73, 78, 83, 69, 82, + 212, 73, 78, 83, 69, 67, 84, 128, 73, 78, 83, 67, 82, 73, 80, 84, 73, 79, + 78, 65, 204, 73, 78, 80, 85, 212, 73, 78, 78, 79, 67, 69, 78, 67, 69, + 128, 73, 78, 78, 78, 128, 73, 78, 78, 69, 82, 128, 73, 78, 78, 69, 210, + 73, 78, 78, 128, 73, 78, 73, 78, 71, 85, 128, 73, 78, 72, 73, 66, 73, + 212, 73, 78, 72, 69, 82, 69, 78, 212, 73, 78, 72, 65, 76, 69, 128, 73, + 78, 71, 87, 65, 90, 128, 73, 78, 70, 79, 82, 77, 65, 84, 73, 79, 206, 73, + 78, 70, 76, 85, 69, 78, 67, 69, 128, 73, 78, 70, 73, 78, 73, 84, 89, 128, + 73, 78, 70, 73, 78, 73, 84, 217, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, + 73, 78, 68, 73, 82, 69, 67, 212, 73, 78, 68, 73, 67, 84, 73, 79, 206, 73, + 78, 68, 73, 67, 65, 84, 79, 82, 128, 73, 78, 68, 73, 67, 65, 84, 79, 210, + 73, 78, 68, 73, 195, 73, 78, 68, 73, 65, 206, 73, 78, 68, 69, 88, 128, + 73, 78, 68, 69, 80, 69, 78, 68, 69, 78, 212, 73, 78, 67, 82, 69, 77, 69, + 78, 84, 128, 73, 78, 67, 82, 69, 65, 83, 69, 211, 73, 78, 67, 82, 69, 65, + 83, 69, 128, 73, 78, 67, 82, 69, 65, 83, 197, 73, 78, 67, 79, 77, 80, 76, + 69, 84, 197, 73, 78, 67, 79, 77, 73, 78, 199, 73, 78, 67, 76, 85, 68, 73, + 78, 199, 73, 78, 67, 72, 128, 73, 78, 66, 79, 216, 73, 78, 65, 80, 128, + 73, 78, 45, 65, 76, 65, 70, 128, 73, 77, 80, 69, 82, 73, 65, 204, 73, 77, + 80, 69, 82, 70, 69, 67, 84, 85, 205, 73, 77, 80, 69, 82, 70, 69, 67, 84, + 65, 128, 73, 77, 80, 69, 82, 70, 69, 67, 84, 193, 73, 77, 78, 128, 73, + 77, 73, 83, 69, 79, 211, 73, 77, 73, 78, 51, 128, 73, 77, 73, 78, 128, + 73, 77, 73, 206, 73, 77, 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 77, 73, + 70, 84, 72, 79, 82, 65, 128, 73, 77, 73, 70, 79, 78, 79, 78, 128, 73, 77, + 73, 68, 73, 65, 82, 71, 79, 78, 128, 73, 77, 65, 71, 197, 73, 76, 85, 89, + 65, 78, 78, 65, 128, 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, 78, 78, + 65, 128, 73, 76, 85, 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, 73, 76, + 73, 77, 77, 85, 51, 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, 77, 77, + 213, 73, 76, 50, 128, 73, 75, 65, 82, 65, 128, 73, 75, 65, 82, 193, 73, + 74, 128, 73, 73, 89, 65, 78, 78, 65, 128, 73, 71, 73, 128, 73, 71, 201, + 73, 71, 71, 87, 83, 128, 73, 70, 73, 78, 128, 73, 69, 85, 78, 71, 45, 84, + 73, 75, 69, 85, 84, 128, 73, 69, 85, 78, 71, 45, 84, 72, 73, 69, 85, 84, + 72, 128, 73, 69, 85, 78, 71, 45, 82, 73, 69, 85, 76, 128, 73, 69, 85, 78, + 71, 45, 80, 73, 69, 85, 80, 128, 73, 69, 85, 78, 71, 45, 80, 72, 73, 69, + 85, 80, 72, 128, 73, 69, 85, 78, 71, 45, 67, 73, 69, 85, 67, 128, 73, 69, + 85, 78, 71, 45, 67, 72, 73, 69, 85, 67, 72, 128, 73, 69, 85, 78, 199, 73, + 68, 76, 69, 128, 73, 68, 73, 77, 128, 73, 68, 73, 205, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 57, 49, 52, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 57, 48, 52, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 56, 68, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 56, 67, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 56, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 68, 52, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 65, 55, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 57, 56, 49, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 55, 54, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 55, 53, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 55, 53, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 49, 50, + 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 48, 66, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 70, 49, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 54, 69, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 54, 55, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 54, 55, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 54, 50, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 66, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 54, 53, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 54, 53, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 54, 51, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 48, + 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 57, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 53, 51, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 54, 50, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 53, 70, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 53, 68, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 66, 56, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 66, 53, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 57, 50, 57, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 53, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 53, 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 53, 53, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 52, 51, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 52, 48, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 51, 70, 51, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 53, 51, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 53, 50, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 53, 50, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 52, + 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 49, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 49, 56, 68, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 52, 69, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 52, 69, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 52, 69, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 48, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 48, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 200, 73, 68, 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 78, + 128, 73, 68, 69, 78, 84, 73, 67, 65, 204, 73, 67, 79, 78, 128, 73, 67, + 72, 79, 85, 128, 73, 67, 72, 79, 83, 128, 73, 67, 72, 73, 77, 65, 84, 79, + 83, 128, 73, 67, 72, 65, 68, 73, 78, 128, 73, 67, 69, 76, 65, 78, 68, 73, + 67, 45, 89, 82, 128, 73, 66, 73, 70, 73, 76, 73, 128, 73, 65, 85, 68, 65, + 128, 73, 48, 49, 53, 128, 73, 48, 49, 52, 128, 73, 48, 49, 51, 128, 73, + 48, 49, 50, 128, 73, 48, 49, 49, 65, 128, 73, 48, 49, 49, 128, 73, 48, + 49, 48, 65, 128, 73, 48, 49, 48, 128, 73, 48, 48, 57, 65, 128, 73, 48, + 48, 57, 128, 73, 48, 48, 56, 128, 73, 48, 48, 55, 128, 73, 48, 48, 54, + 128, 73, 48, 48, 53, 65, 128, 73, 48, 48, 53, 128, 73, 48, 48, 52, 128, + 73, 48, 48, 51, 128, 73, 48, 48, 50, 128, 73, 48, 48, 49, 128, 73, 45, + 89, 85, 128, 73, 45, 89, 79, 128, 73, 45, 89, 69, 79, 128, 73, 45, 89, + 69, 128, 73, 45, 89, 65, 69, 128, 73, 45, 89, 65, 45, 79, 128, 73, 45, + 89, 65, 128, 73, 45, 79, 45, 73, 128, 73, 45, 79, 128, 73, 45, 69, 85, + 128, 73, 45, 66, 69, 65, 77, 128, 73, 45, 65, 82, 65, 69, 65, 128, 73, + 45, 65, 128, 72, 90, 90, 90, 71, 128, 72, 90, 90, 90, 128, 72, 90, 90, + 80, 128, 72, 90, 90, 128, 72, 90, 87, 71, 128, 72, 90, 87, 128, 72, 90, + 84, 128, 72, 90, 71, 128, 72, 89, 83, 84, 69, 82, 69, 83, 73, 211, 72, + 89, 80, 79, 68, 73, 65, 83, 84, 79, 76, 69, 128, 72, 89, 80, 72, 69, 78, + 65, 84, 73, 79, 206, 72, 89, 80, 72, 69, 78, 45, 77, 73, 78, 85, 83, 128, + 72, 89, 80, 72, 69, 78, 128, 72, 89, 80, 72, 69, 206, 72, 89, 71, 73, 69, + 73, 65, 128, 72, 89, 71, 73, 69, 65, 128, 72, 88, 87, 71, 128, 72, 88, + 85, 79, 88, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, 80, 128, 72, + 88, 85, 79, 128, 72, 88, 79, 88, 128, 72, 88, 79, 84, 128, 72, 88, 79, + 80, 128, 72, 88, 79, 128, 72, 88, 73, 88, 128, 72, 88, 73, 84, 128, 72, + 88, 73, 80, 128, 72, 88, 73, 69, 88, 128, 72, 88, 73, 69, 84, 128, 72, + 88, 73, 69, 80, 128, 72, 88, 73, 69, 128, 72, 88, 73, 128, 72, 88, 69, + 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 128, 72, 88, 65, 88, 128, 72, + 88, 65, 84, 128, 72, 88, 65, 80, 128, 72, 88, 65, 128, 72, 87, 85, 128, + 72, 87, 65, 73, 82, 128, 72, 87, 65, 72, 128, 72, 85, 86, 65, 128, 72, + 85, 83, 72, 69, 196, 72, 85, 83, 72, 128, 72, 85, 82, 65, 78, 128, 72, + 85, 79, 84, 128, 72, 85, 78, 68, 82, 69, 68, 83, 128, 72, 85, 78, 68, 82, + 69, 68, 211, 72, 85, 78, 68, 82, 69, 68, 128, 72, 85, 78, 68, 82, 69, + 196, 72, 85, 78, 128, 72, 85, 77, 208, 72, 85, 77, 65, 78, 128, 72, 85, + 77, 65, 206, 72, 85, 76, 50, 128, 72, 85, 73, 73, 84, 79, 128, 72, 85, + 71, 71, 73, 78, 199, 72, 85, 66, 50, 128, 72, 85, 66, 178, 72, 85, 66, + 128, 72, 85, 65, 82, 65, 68, 68, 79, 128, 72, 85, 65, 78, 128, 72, 85, + 45, 51, 128, 72, 85, 45, 50, 128, 72, 85, 45, 49, 128, 72, 84, 83, 128, + 72, 84, 74, 128, 72, 82, 89, 86, 78, 73, 193, 72, 80, 87, 71, 128, 72, + 80, 65, 128, 72, 80, 128, 72, 79, 85, 83, 197, 72, 79, 85, 82, 71, 76, + 65, 83, 83, 128, 72, 79, 85, 82, 71, 76, 65, 83, 211, 72, 79, 85, 82, + 128, 72, 79, 85, 210, 72, 79, 84, 69, 76, 128, 72, 79, 84, 65, 128, 72, + 79, 83, 80, 73, 84, 65, 76, 128, 72, 79, 82, 83, 69, 128, 72, 79, 82, 83, + 197, 72, 79, 82, 82, 128, 72, 79, 82, 78, 83, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 76, 217, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 54, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 54, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, + 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, + 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, + 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 49, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 48, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 54, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 53, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 52, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 51, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 50, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 53, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 52, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 52, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 52, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 52, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 52, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 52, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, + 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, + 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, + 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 52, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 51, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 50, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 49, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 48, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 54, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 53, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 50, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 50, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 50, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 50, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 49, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 49, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 49, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, + 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, + 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, + 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 48, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 54, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 53, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 52, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 51, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 50, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 49, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 204, 72, 79, 82, + 73, 128, 72, 79, 82, 193, 72, 79, 79, 85, 128, 72, 79, 79, 82, 85, 128, + 72, 79, 79, 80, 128, 72, 79, 79, 78, 128, 72, 79, 79, 75, 69, 68, 128, + 72, 79, 79, 75, 69, 196, 72, 79, 78, 69, 89, 66, 69, 69, 128, 72, 79, 78, + 69, 217, 72, 79, 77, 79, 84, 72, 69, 84, 73, 67, 128, 72, 79, 77, 79, 84, + 72, 69, 84, 73, 195, 72, 79, 76, 79, 128, 72, 79, 76, 76, 79, 215, 72, + 79, 76, 69, 128, 72, 79, 76, 68, 73, 78, 199, 72, 79, 76, 65, 77, 128, + 72, 79, 76, 65, 205, 72, 79, 75, 65, 128, 72, 79, 67, 75, 69, 217, 72, + 79, 67, 72, 79, 128, 72, 79, 45, 56, 128, 72, 79, 45, 55, 128, 72, 79, + 45, 54, 128, 72, 79, 45, 53, 128, 72, 79, 45, 52, 128, 72, 79, 45, 51, + 128, 72, 79, 45, 50, 128, 72, 79, 45, 49, 128, 72, 78, 85, 84, 128, 72, + 78, 85, 79, 88, 128, 72, 78, 85, 79, 128, 72, 78, 85, 66, 128, 72, 78, + 79, 88, 128, 72, 78, 79, 84, 128, 72, 78, 79, 80, 128, 72, 78, 73, 88, + 128, 72, 78, 73, 84, 128, 72, 78, 73, 80, 128, 72, 78, 73, 69, 88, 128, + 72, 78, 73, 69, 84, 128, 72, 78, 73, 69, 80, 128, 72, 78, 73, 69, 128, + 72, 78, 73, 128, 72, 78, 69, 88, 128, 72, 78, 69, 80, 128, 72, 78, 69, + 128, 72, 78, 65, 88, 128, 72, 78, 65, 85, 128, 72, 78, 65, 84, 128, 72, + 78, 65, 80, 128, 72, 78, 65, 128, 72, 77, 89, 88, 128, 72, 77, 89, 82, + 88, 128, 72, 77, 89, 82, 128, 72, 77, 89, 80, 128, 72, 77, 89, 128, 72, + 77, 85, 88, 128, 72, 77, 85, 84, 128, 72, 77, 85, 82, 88, 128, 72, 77, + 85, 82, 128, 72, 77, 85, 80, 128, 72, 77, 85, 79, 88, 128, 72, 77, 85, + 79, 80, 128, 72, 77, 85, 79, 128, 72, 77, 85, 128, 72, 77, 79, 88, 128, + 72, 77, 79, 84, 128, 72, 77, 79, 80, 128, 72, 77, 79, 128, 72, 77, 73, + 88, 128, 72, 77, 73, 84, 128, 72, 77, 73, 80, 128, 72, 77, 73, 69, 88, + 128, 72, 77, 73, 69, 80, 128, 72, 77, 73, 69, 128, 72, 77, 73, 128, 72, + 77, 69, 128, 72, 77, 65, 88, 128, 72, 77, 65, 84, 128, 72, 77, 65, 80, + 128, 72, 77, 65, 128, 72, 76, 89, 88, 128, 72, 76, 89, 84, 128, 72, 76, + 89, 82, 88, 128, 72, 76, 89, 82, 128, 72, 76, 89, 80, 128, 72, 76, 89, + 128, 72, 76, 85, 88, 128, 72, 76, 85, 84, 128, 72, 76, 85, 82, 88, 128, + 72, 76, 85, 82, 128, 72, 76, 85, 80, 128, 72, 76, 85, 79, 88, 128, 72, + 76, 85, 79, 80, 128, 72, 76, 85, 79, 128, 72, 76, 85, 128, 72, 76, 79, + 88, 128, 72, 76, 79, 80, 128, 72, 76, 79, 128, 72, 76, 73, 88, 128, 72, + 76, 73, 84, 128, 72, 76, 73, 80, 128, 72, 76, 73, 69, 88, 128, 72, 76, + 73, 69, 80, 128, 72, 76, 73, 69, 128, 72, 76, 73, 128, 72, 76, 69, 88, + 128, 72, 76, 69, 80, 128, 72, 76, 69, 128, 72, 76, 65, 88, 128, 72, 76, + 65, 85, 128, 72, 76, 65, 84, 128, 72, 76, 65, 80, 128, 72, 76, 65, 128, + 72, 76, 128, 72, 75, 128, 72, 73, 90, 66, 128, 72, 73, 89, 79, 128, 72, + 73, 84, 84, 73, 78, 199, 72, 73, 83, 84, 79, 82, 73, 195, 72, 73, 82, 73, + 81, 128, 72, 73, 80, 80, 79, 80, 79, 84, 65, 77, 85, 83, 128, 72, 73, 78, + 71, 69, 68, 128, 72, 73, 78, 71, 69, 196, 72, 73, 78, 71, 69, 128, 72, + 73, 78, 68, 213, 72, 73, 75, 73, 78, 199, 72, 73, 71, 72, 45, 83, 80, 69, + 69, 196, 72, 73, 71, 72, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 72, + 73, 71, 72, 45, 76, 79, 215, 72, 73, 71, 72, 45, 72, 69, 69, 76, 69, 196, + 72, 73, 69, 88, 128, 72, 73, 69, 85, 72, 45, 83, 73, 79, 83, 128, 72, 73, + 69, 85, 72, 45, 82, 73, 69, 85, 76, 128, 72, 73, 69, 85, 72, 45, 80, 73, + 69, 85, 80, 128, 72, 73, 69, 85, 72, 45, 78, 73, 69, 85, 78, 128, 72, 73, + 69, 85, 72, 45, 77, 73, 69, 85, 77, 128, 72, 73, 69, 85, 200, 72, 73, 69, + 82, 79, 71, 76, 89, 80, 72, 73, 195, 72, 73, 69, 128, 72, 73, 68, 73, 78, + 199, 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, 128, 72, 73, 66, 73, 83, + 67, 85, 83, 128, 72, 73, 45, 82, 69, 83, 128, 72, 73, 45, 55, 128, 72, + 73, 45, 54, 128, 72, 73, 45, 53, 128, 72, 73, 45, 52, 128, 72, 73, 45, + 51, 128, 72, 73, 45, 50, 128, 72, 73, 45, 49, 128, 72, 72, 87, 65, 128, + 72, 72, 85, 128, 72, 72, 73, 128, 72, 72, 69, 69, 128, 72, 72, 69, 128, + 72, 72, 65, 65, 128, 72, 71, 128, 72, 69, 89, 84, 128, 72, 69, 88, 73, + 70, 79, 82, 205, 72, 69, 88, 65, 71, 82, 65, 205, 72, 69, 88, 65, 71, 79, + 78, 128, 72, 69, 82, 85, 84, 85, 128, 72, 69, 82, 85, 128, 72, 69, 82, + 77, 73, 84, 73, 65, 206, 72, 69, 82, 77, 73, 79, 78, 73, 65, 206, 72, 69, + 82, 77, 69, 83, 128, 72, 69, 82, 69, 128, 72, 69, 82, 66, 128, 72, 69, + 82, 65, 69, 85, 205, 72, 69, 78, 71, 128, 72, 69, 78, 199, 72, 69, 77, + 80, 128, 72, 69, 76, 77, 69, 84, 128, 72, 69, 76, 77, 69, 212, 72, 69, + 76, 205, 72, 69, 76, 76, 83, 67, 72, 82, 69, 73, 66, 69, 210, 72, 69, 76, + 73, 88, 128, 72, 69, 76, 73, 67, 79, 80, 84, 69, 82, 128, 72, 69, 75, 85, + 84, 65, 65, 82, 85, 128, 72, 69, 73, 83, 69, 73, 128, 72, 69, 73, 71, 72, + 84, 128, 72, 69, 69, 73, 128, 72, 69, 68, 71, 69, 72, 79, 71, 128, 72, + 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, 78, 76, 217, 72, 69, 65, 86, 69, + 78, 128, 72, 69, 65, 86, 69, 206, 72, 69, 65, 82, 84, 83, 128, 72, 69, + 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, 72, 69, 65, 82, 84, 128, 72, 69, + 65, 82, 212, 72, 69, 65, 82, 73, 78, 199, 72, 69, 65, 82, 45, 78, 79, 45, + 69, 86, 73, 204, 72, 69, 65, 68, 83, 84, 82, 79, 75, 69, 128, 72, 69, 65, + 68, 83, 84, 79, 78, 197, 72, 69, 65, 68, 83, 67, 65, 82, 70, 128, 72, 69, + 65, 68, 80, 72, 79, 78, 69, 128, 72, 69, 65, 68, 73, 78, 71, 128, 72, 69, + 65, 68, 45, 66, 65, 78, 68, 65, 71, 69, 128, 72, 69, 45, 55, 128, 72, 69, + 45, 54, 128, 72, 69, 45, 53, 128, 72, 69, 45, 52, 128, 72, 69, 45, 51, + 128, 72, 69, 45, 50, 128, 72, 69, 45, 49, 128, 72, 68, 82, 128, 72, 67, + 128, 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, 72, 66, 65, 83, 193, + 72, 65, 89, 65, 78, 78, 65, 128, 72, 65, 87, 74, 128, 72, 65, 86, 69, + 128, 72, 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 65, 213, 72, + 65, 84, 82, 65, 206, 72, 65, 84, 72, 73, 128, 72, 65, 84, 69, 128, 72, + 65, 84, 67, 72, 73, 78, 199, 72, 65, 84, 65, 198, 72, 65, 83, 69, 210, + 72, 65, 83, 65, 78, 84, 65, 128, 72, 65, 82, 80, 79, 79, 78, 128, 72, 65, + 82, 80, 79, 79, 206, 72, 65, 82, 77, 79, 78, 73, 67, 128, 72, 65, 82, 75, + 76, 69, 65, 206, 72, 65, 82, 68, 78, 69, 83, 83, 128, 72, 65, 82, 196, + 72, 65, 82, 66, 65, 72, 65, 89, 128, 72, 65, 80, 80, 217, 72, 65, 78, 85, + 78, 79, 207, 72, 65, 78, 73, 70, 201, 72, 65, 78, 71, 90, 72, 79, 213, + 72, 65, 78, 68, 83, 72, 65, 75, 69, 128, 72, 65, 78, 68, 83, 128, 72, 65, + 78, 68, 211, 72, 65, 78, 68, 76, 69, 83, 128, 72, 65, 78, 68, 76, 69, + 128, 72, 65, 78, 68, 66, 65, 76, 76, 128, 72, 65, 78, 68, 66, 65, 71, + 128, 72, 65, 78, 68, 45, 79, 86, 65, 76, 128, 72, 65, 78, 68, 45, 79, 86, + 65, 204, 72, 65, 78, 68, 45, 72, 79, 79, 75, 128, 72, 65, 78, 68, 45, 72, + 79, 79, 203, 72, 65, 78, 68, 45, 72, 73, 78, 71, 69, 128, 72, 65, 78, 68, + 45, 72, 73, 78, 71, 197, 72, 65, 78, 68, 45, 70, 76, 65, 84, 128, 72, 65, + 78, 68, 45, 70, 76, 65, 212, 72, 65, 78, 68, 45, 70, 73, 83, 84, 128, 72, + 65, 78, 68, 45, 67, 85, 82, 76, 73, 67, 85, 69, 128, 72, 65, 78, 68, 45, + 67, 85, 82, 76, 73, 67, 85, 197, 72, 65, 78, 68, 45, 67, 85, 80, 128, 72, + 65, 78, 68, 45, 67, 85, 208, 72, 65, 78, 68, 45, 67, 76, 65, 87, 128, 72, + 65, 78, 68, 45, 67, 76, 65, 215, 72, 65, 78, 68, 45, 67, 73, 82, 67, 76, + 69, 128, 72, 65, 78, 68, 45, 67, 73, 82, 67, 76, 197, 72, 65, 78, 68, 45, + 65, 78, 71, 76, 69, 128, 72, 65, 78, 68, 45, 65, 78, 71, 76, 197, 72, 65, + 78, 68, 128, 72, 65, 78, 45, 65, 75, 65, 84, 128, 72, 65, 77, 90, 65, + 128, 72, 65, 77, 90, 193, 72, 65, 77, 83, 84, 69, 210, 72, 65, 77, 77, + 69, 82, 128, 72, 65, 77, 77, 69, 210, 72, 65, 77, 66, 85, 82, 71, 69, 82, + 128, 72, 65, 76, 81, 65, 128, 72, 65, 76, 79, 128, 72, 65, 76, 70, 45, + 67, 73, 82, 67, 76, 197, 72, 65, 76, 70, 45, 50, 128, 72, 65, 76, 70, 45, + 49, 128, 72, 65, 76, 70, 128, 72, 65, 76, 66, 69, 82, 68, 128, 72, 65, + 76, 65, 78, 84, 65, 128, 72, 65, 73, 84, 85, 128, 72, 65, 73, 211, 72, + 65, 73, 82, 67, 85, 84, 128, 72, 65, 71, 76, 65, 218, 72, 65, 71, 76, + 128, 72, 65, 70, 85, 75, 72, 65, 128, 72, 65, 70, 85, 75, 72, 128, 72, + 65, 69, 71, 204, 72, 65, 68, 69, 83, 128, 72, 65, 65, 82, 85, 128, 72, + 65, 65, 77, 128, 72, 65, 193, 72, 65, 45, 72, 65, 128, 72, 65, 45, 57, + 128, 72, 65, 45, 56, 128, 72, 65, 45, 55, 128, 72, 65, 45, 54, 128, 72, + 65, 45, 53, 128, 72, 65, 45, 52, 128, 72, 65, 45, 51, 128, 72, 65, 45, + 50, 128, 72, 65, 45, 49, 49, 128, 72, 65, 45, 49, 48, 128, 72, 65, 45, + 49, 128, 72, 48, 48, 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, 54, 65, + 128, 72, 48, 48, 54, 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, 128, 72, + 48, 48, 51, 128, 72, 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, 45, 84, + 89, 80, 197, 71, 89, 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, 128, 71, + 89, 73, 128, 71, 89, 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, 83, 128, + 71, 89, 65, 65, 128, 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, 128, 71, + 87, 73, 128, 71, 87, 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, 65, 128, + 71, 87, 65, 128, 71, 86, 65, 78, 71, 128, 71, 86, 128, 71, 85, 82, 85, + 83, 72, 128, 71, 85, 82, 85, 78, 128, 71, 85, 82, 77, 85, 75, 72, 201, + 71, 85, 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, 55, 128, 71, 85, 78, + 85, 128, 71, 85, 78, 213, 71, 85, 78, 74, 65, 76, 193, 71, 85, 205, 71, + 85, 76, 128, 71, 85, 74, 65, 82, 65, 84, 201, 71, 85, 73, 84, 65, 82, + 128, 71, 85, 73, 68, 197, 71, 85, 199, 71, 85, 69, 73, 128, 71, 85, 69, + 72, 128, 71, 85, 69, 200, 71, 85, 68, 128, 71, 85, 196, 71, 85, 65, 82, + 68, 83, 77, 65, 78, 128, 71, 85, 65, 82, 68, 69, 68, 78, 69, 83, 83, 128, + 71, 85, 65, 82, 68, 69, 196, 71, 85, 65, 82, 68, 128, 71, 85, 65, 82, 65, + 78, 201, 71, 85, 193, 71, 85, 178, 71, 84, 69, 210, 71, 83, 85, 77, 128, + 71, 83, 85, 205, 71, 82, 213, 71, 82, 79, 87, 73, 78, 199, 71, 82, 79, + 85, 78, 68, 128, 71, 82, 79, 78, 84, 72, 73, 83, 77, 65, 84, 65, 128, 71, + 82, 73, 78, 78, 73, 78, 199, 71, 82, 73, 77, 65, 67, 73, 78, 199, 71, 82, + 69, 71, 79, 82, 73, 65, 206, 71, 82, 69, 69, 78, 128, 71, 82, 69, 69, + 206, 71, 82, 69, 65, 84, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, + 45, 84, 72, 65, 78, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 206, + 71, 82, 69, 65, 84, 69, 210, 71, 82, 69, 65, 212, 71, 82, 65, 86, 69, 89, + 65, 82, 196, 71, 82, 65, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 71, 82, + 65, 86, 69, 45, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, 128, 71, 82, + 65, 86, 197, 71, 82, 65, 84, 69, 82, 128, 71, 82, 65, 83, 83, 128, 71, + 82, 65, 83, 211, 71, 82, 65, 83, 208, 71, 82, 65, 80, 72, 69, 77, 197, + 71, 82, 65, 80, 69, 83, 128, 71, 82, 65, 78, 84, 72, 193, 71, 82, 65, 77, + 77, 193, 71, 82, 65, 73, 78, 128, 71, 82, 65, 68, 85, 65, 84, 73, 79, + 206, 71, 82, 65, 68, 85, 65, 76, 128, 71, 82, 65, 67, 69, 128, 71, 82, + 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, 77, 73, 75, 79, 206, + 71, 79, 82, 84, 128, 71, 79, 82, 73, 76, 76, 65, 128, 71, 79, 82, 71, 79, + 84, 69, 82, 73, 128, 71, 79, 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, + 78, 128, 71, 79, 82, 71, 79, 206, 71, 79, 82, 71, 73, 128, 71, 79, 82, + 65, 128, 71, 79, 79, 196, 71, 79, 78, 71, 128, 71, 79, 76, 70, 69, 82, + 128, 71, 79, 76, 68, 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, 71, 79, + 71, 71, 76, 69, 83, 128, 71, 79, 66, 76, 73, 78, 128, 71, 79, 65, 76, + 128, 71, 79, 65, 204, 71, 79, 65, 128, 71, 78, 89, 73, 83, 128, 71, 78, + 65, 86, 73, 89, 65, 78, 73, 128, 71, 76, 79, 87, 73, 78, 199, 71, 76, 79, + 86, 69, 83, 128, 71, 76, 79, 86, 69, 128, 71, 76, 79, 84, 84, 65, 204, + 71, 76, 79, 66, 197, 71, 76, 73, 83, 83, 65, 78, 68, 207, 71, 76, 69, 73, + 67, 200, 71, 76, 65, 71, 79, 76, 73, 128, 71, 76, 65, 128, 71, 74, 69, + 128, 71, 73, 88, 128, 71, 73, 84, 128, 71, 73, 83, 72, 128, 71, 73, 83, + 200, 71, 73, 83, 65, 76, 128, 71, 73, 82, 85, 68, 65, 65, 128, 71, 73, + 82, 76, 211, 71, 73, 82, 76, 128, 71, 73, 82, 65, 70, 70, 197, 71, 73, + 82, 51, 128, 71, 73, 82, 179, 71, 73, 82, 50, 128, 71, 73, 82, 178, 71, + 73, 80, 128, 71, 73, 78, 73, 73, 128, 71, 73, 77, 69, 76, 128, 71, 73, + 77, 69, 204, 71, 73, 77, 128, 71, 73, 71, 65, 128, 71, 73, 71, 128, 71, + 73, 70, 212, 71, 73, 69, 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, + 66, 79, 85, 211, 71, 73, 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, + 72, 90, 128, 71, 72, 87, 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, + 85, 78, 78, 193, 71, 72, 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, + 84, 128, 71, 72, 79, 128, 71, 72, 73, 77, 69, 76, 128, 71, 72, 73, 128, + 71, 72, 72, 65, 128, 71, 72, 69, 89, 83, 128, 71, 72, 69, 85, 88, 128, + 71, 72, 69, 85, 78, 128, 71, 72, 69, 85, 71, 72, 69, 85, 65, 69, 77, 128, + 71, 72, 69, 85, 71, 72, 69, 78, 128, 71, 72, 69, 85, 65, 69, 82, 65, 69, + 128, 71, 72, 69, 85, 65, 69, 71, 72, 69, 85, 65, 69, 128, 71, 72, 69, 84, + 128, 71, 72, 69, 69, 128, 71, 72, 69, 128, 71, 72, 197, 71, 72, 65, 89, + 78, 128, 71, 72, 65, 82, 65, 69, 128, 71, 72, 65, 80, 128, 71, 72, 65, + 78, 128, 71, 72, 65, 77, 77, 65, 128, 71, 72, 65, 77, 65, 76, 128, 71, + 72, 65, 73, 78, 85, 128, 71, 72, 65, 73, 78, 128, 71, 72, 65, 73, 206, + 71, 72, 65, 68, 128, 71, 72, 65, 65, 77, 65, 69, 128, 71, 72, 65, 65, + 128, 71, 71, 87, 73, 128, 71, 71, 87, 69, 69, 128, 71, 71, 87, 69, 128, + 71, 71, 87, 65, 65, 128, 71, 71, 87, 65, 128, 71, 71, 85, 88, 128, 71, + 71, 85, 84, 128, 71, 71, 85, 82, 88, 128, 71, 71, 85, 82, 128, 71, 71, + 85, 79, 88, 128, 71, 71, 85, 79, 84, 128, 71, 71, 85, 79, 80, 128, 71, + 71, 85, 79, 128, 71, 71, 79, 88, 128, 71, 71, 79, 84, 128, 71, 71, 79, + 80, 128, 71, 71, 73, 88, 128, 71, 71, 73, 84, 128, 71, 71, 73, 69, 88, + 128, 71, 71, 73, 69, 80, 128, 71, 71, 73, 69, 128, 71, 71, 69, 88, 128, + 71, 71, 69, 84, 128, 71, 71, 69, 80, 128, 71, 71, 65, 88, 128, 71, 71, + 65, 84, 128, 71, 69, 84, 193, 71, 69, 83, 84, 85, 82, 69, 128, 71, 69, + 83, 72, 85, 128, 71, 69, 83, 72, 84, 73, 78, 128, 71, 69, 83, 72, 84, 73, + 206, 71, 69, 83, 72, 50, 128, 71, 69, 82, 83, 72, 65, 89, 73, 77, 128, + 71, 69, 82, 77, 65, 206, 71, 69, 82, 69, 83, 72, 128, 71, 69, 82, 69, 83, + 200, 71, 69, 79, 77, 69, 84, 82, 73, 67, 65, 76, 76, 217, 71, 69, 79, 77, + 69, 84, 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, + 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, + 128, 71, 65, 78, 68, 193, 71, 65, 78, 50, 128, 71, 65, 78, 178, 71, 65, + 77, 77, 65, 128, 71, 65, 77, 76, 65, 128, 71, 65, 77, 76, 128, 71, 65, + 77, 69, 128, 71, 65, 77, 197, 71, 65, 77, 65, 78, 128, 71, 65, 77, 65, + 76, 128, 71, 65, 77, 65, 204, 71, 65, 76, 201, 71, 65, 71, 128, 71, 65, + 70, 128, 71, 65, 198, 71, 65, 69, 84, 84, 65, 45, 80, 73, 76, 76, 65, + 128, 71, 65, 68, 79, 76, 128, 71, 65, 68, 128, 71, 65, 196, 71, 65, 66, + 65, 128, 71, 65, 66, 193, 71, 65, 65, 70, 85, 128, 71, 65, 178, 71, 48, + 53, 52, 128, 71, 48, 53, 51, 128, 71, 48, 53, 50, 128, 71, 48, 53, 49, + 128, 71, 48, 53, 48, 128, 71, 48, 52, 57, 128, 71, 48, 52, 56, 128, 71, + 48, 52, 55, 128, 71, 48, 52, 54, 128, 71, 48, 52, 53, 65, 128, 71, 48, + 52, 53, 128, 71, 48, 52, 52, 128, 71, 48, 52, 51, 65, 128, 71, 48, 52, + 51, 128, 71, 48, 52, 50, 128, 71, 48, 52, 49, 128, 71, 48, 52, 48, 128, + 71, 48, 51, 57, 128, 71, 48, 51, 56, 128, 71, 48, 51, 55, 65, 128, 71, + 48, 51, 55, 128, 71, 48, 51, 54, 65, 128, 71, 48, 51, 54, 128, 71, 48, + 51, 53, 128, 71, 48, 51, 52, 128, 71, 48, 51, 51, 128, 71, 48, 51, 50, + 128, 71, 48, 51, 49, 128, 71, 48, 51, 48, 128, 71, 48, 50, 57, 128, 71, + 48, 50, 56, 128, 71, 48, 50, 55, 128, 71, 48, 50, 54, 65, 128, 71, 48, + 50, 54, 128, 71, 48, 50, 53, 128, 71, 48, 50, 52, 128, 71, 48, 50, 51, + 128, 71, 48, 50, 50, 128, 71, 48, 50, 49, 128, 71, 48, 50, 48, 65, 128, + 71, 48, 50, 48, 128, 71, 48, 49, 57, 128, 71, 48, 49, 56, 128, 71, 48, + 49, 55, 128, 71, 48, 49, 54, 128, 71, 48, 49, 53, 128, 71, 48, 49, 52, + 128, 71, 48, 49, 51, 128, 71, 48, 49, 50, 128, 71, 48, 49, 49, 65, 128, + 71, 48, 49, 49, 128, 71, 48, 49, 48, 128, 71, 48, 48, 57, 128, 71, 48, + 48, 56, 128, 71, 48, 48, 55, 66, 128, 71, 48, 48, 55, 65, 128, 71, 48, + 48, 55, 128, 71, 48, 48, 54, 65, 128, 71, 48, 48, 54, 128, 71, 48, 48, + 53, 128, 71, 48, 48, 52, 128, 71, 48, 48, 51, 128, 71, 48, 48, 50, 128, + 71, 48, 48, 49, 128, 70, 89, 88, 128, 70, 89, 84, 128, 70, 89, 80, 128, + 70, 89, 65, 128, 70, 87, 73, 128, 70, 87, 69, 69, 128, 70, 87, 69, 128, + 70, 87, 65, 65, 128, 70, 87, 65, 128, 70, 86, 83, 51, 128, 70, 86, 83, + 50, 128, 70, 86, 83, 49, 128, 70, 85, 88, 128, 70, 85, 84, 128, 70, 85, + 83, 69, 128, 70, 85, 83, 193, 70, 85, 82, 88, 128, 70, 85, 80, 128, 70, + 85, 78, 69, 82, 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 65, 204, 70, 85, + 78, 67, 84, 73, 79, 78, 128, 70, 85, 76, 76, 78, 69, 83, 83, 128, 70, 85, + 76, 204, 70, 85, 74, 73, 128, 70, 85, 69, 84, 128, 70, 85, 69, 204, 70, + 85, 69, 128, 70, 85, 65, 128, 70, 84, 72, 79, 82, 193, 70, 83, 73, 128, + 70, 82, 79, 87, 78, 73, 78, 71, 128, 70, 82, 79, 87, 78, 73, 78, 199, 70, + 82, 79, 87, 78, 128, 70, 82, 79, 87, 206, 70, 82, 79, 78, 84, 45, 84, 73, + 76, 84, 69, 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, 73, 78, 199, 70, 82, + 79, 78, 212, 70, 82, 79, 205, 70, 82, 79, 71, 128, 70, 82, 79, 199, 70, + 82, 73, 84, 85, 128, 70, 82, 73, 69, 83, 128, 70, 82, 73, 69, 196, 70, + 82, 73, 67, 65, 84, 73, 86, 69, 128, 70, 82, 69, 84, 66, 79, 65, 82, 68, + 128, 70, 82, 69, 78, 67, 200, 70, 82, 69, 69, 90, 73, 78, 199, 70, 82, + 69, 69, 128, 70, 82, 69, 197, 70, 82, 65, 78, 75, 211, 70, 82, 65, 78, + 195, 70, 82, 65, 77, 69, 83, 128, 70, 82, 65, 77, 69, 128, 70, 82, 65, + 77, 197, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, 82, 65, 71, 77, 69, 78, + 84, 128, 70, 79, 88, 128, 70, 79, 216, 70, 79, 85, 82, 84, 69, 69, 78, + 128, 70, 79, 85, 82, 84, 69, 69, 206, 70, 79, 85, 82, 45, 84, 72, 73, 82, + 84, 89, 128, 70, 79, 85, 82, 45, 83, 84, 82, 73, 78, 199, 70, 79, 85, 82, + 45, 80, 69, 82, 45, 69, 205, 70, 79, 85, 82, 45, 76, 73, 78, 197, 70, 79, + 85, 210, 70, 79, 85, 78, 84, 65, 73, 78, 128, 70, 79, 85, 78, 84, 65, 73, + 206, 70, 79, 83, 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, 82, 68, + 128, 70, 79, 82, 87, 65, 82, 196, 70, 79, 82, 84, 89, 45, 70, 73, 86, + 197, 70, 79, 82, 84, 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, 84, 85, + 78, 197, 70, 79, 82, 84, 73, 69, 84, 72, 128, 70, 79, 82, 84, 69, 128, + 70, 79, 82, 77, 211, 70, 79, 82, 77, 69, 69, 128, 70, 79, 82, 77, 69, + 197, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, 128, 70, 79, 82, 77, 65, + 212, 70, 79, 82, 75, 69, 196, 70, 79, 82, 69, 72, 69, 65, 196, 70, 79, + 82, 67, 69, 83, 128, 70, 79, 82, 67, 69, 128, 70, 79, 80, 128, 70, 79, + 79, 84, 83, 84, 79, 79, 76, 128, 70, 79, 79, 84, 80, 82, 73, 78, 84, 83, + 128, 70, 79, 79, 84, 78, 79, 84, 197, 70, 79, 79, 84, 66, 65, 76, 76, + 128, 70, 79, 79, 84, 128, 70, 79, 79, 76, 128, 70, 79, 79, 68, 128, 70, + 79, 79, 128, 70, 79, 78, 212, 70, 79, 78, 71, 77, 65, 78, 128, 70, 79, + 77, 128, 70, 79, 76, 76, 89, 128, 70, 79, 76, 76, 79, 87, 73, 78, 71, + 128, 70, 79, 76, 68, 69, 82, 128, 70, 79, 76, 68, 69, 196, 70, 79, 71, + 71, 89, 128, 70, 79, 71, 128, 70, 207, 70, 77, 128, 70, 76, 89, 73, 78, + 199, 70, 76, 89, 128, 70, 76, 85, 84, 84, 69, 82, 73, 78, 71, 128, 70, + 76, 85, 84, 84, 69, 82, 73, 78, 199, 70, 76, 85, 84, 69, 128, 70, 76, 85, + 83, 72, 69, 196, 70, 76, 79, 87, 73, 78, 199, 70, 76, 79, 87, 69, 82, 83, + 128, 70, 76, 79, 87, 69, 210, 70, 76, 79, 85, 82, 73, 83, 72, 128, 70, + 76, 79, 82, 69, 84, 84, 69, 128, 70, 76, 79, 82, 65, 204, 70, 76, 79, 80, + 80, 217, 70, 76, 79, 79, 82, 128, 70, 76, 79, 79, 210, 70, 76, 73, 80, + 128, 70, 76, 73, 71, 72, 84, 128, 70, 76, 73, 67, 203, 70, 76, 69, 88, + 85, 83, 128, 70, 76, 69, 88, 69, 196, 70, 76, 69, 88, 128, 70, 76, 69, + 85, 82, 79, 78, 128, 70, 76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, 128, + 70, 76, 65, 84, 84, 69, 78, 69, 196, 70, 76, 65, 84, 78, 69, 83, 83, 128, + 70, 76, 65, 84, 66, 82, 69, 65, 68, 128, 70, 76, 65, 83, 72, 128, 70, 76, + 65, 77, 73, 78, 71, 79, 128, 70, 76, 65, 77, 69, 128, 70, 76, 65, 71, 83, + 128, 70, 76, 65, 71, 45, 53, 128, 70, 76, 65, 71, 45, 52, 128, 70, 76, + 65, 71, 45, 51, 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 49, + 128, 70, 76, 65, 71, 128, 70, 76, 65, 199, 70, 76, 65, 128, 70, 76, 128, + 70, 73, 88, 69, 68, 45, 70, 79, 82, 205, 70, 73, 88, 128, 70, 73, 86, 69, + 45, 84, 72, 73, 82, 84, 89, 128, 70, 73, 86, 69, 45, 76, 73, 78, 197, 70, + 73, 84, 90, 80, 65, 84, 82, 73, 67, 203, 70, 73, 84, 65, 128, 70, 73, 84, + 128, 70, 73, 83, 84, 69, 196, 70, 73, 83, 72, 73, 78, 199, 70, 73, 83, + 72, 72, 79, 79, 75, 128, 70, 73, 83, 72, 72, 79, 79, 203, 70, 73, 83, 72, + 69, 89, 69, 128, 70, 73, 83, 72, 128, 70, 73, 83, 200, 70, 73, 82, 83, + 212, 70, 73, 82, 73, 128, 70, 73, 82, 69, 87, 79, 82, 75, 83, 128, 70, + 73, 82, 69, 87, 79, 82, 203, 70, 73, 82, 69, 67, 82, 65, 67, 75, 69, 82, + 128, 70, 73, 82, 69, 128, 70, 73, 82, 197, 70, 73, 80, 128, 70, 73, 78, + 73, 84, 197, 70, 73, 78, 71, 69, 82, 83, 128, 70, 73, 78, 71, 69, 82, + 211, 70, 73, 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, 73, 78, 71, 69, + 82, 69, 196, 70, 73, 78, 71, 69, 82, 45, 80, 79, 83, 212, 70, 73, 78, 71, + 69, 82, 128, 70, 73, 78, 71, 69, 210, 70, 73, 78, 65, 78, 67, 73, 65, 76, + 128, 70, 73, 78, 65, 76, 128, 70, 73, 76, 205, 70, 73, 76, 76, 69, 82, + 45, 50, 128, 70, 73, 76, 76, 69, 82, 45, 49, 128, 70, 73, 76, 76, 69, 82, + 128, 70, 73, 76, 76, 69, 196, 70, 73, 76, 76, 128, 70, 73, 76, 204, 70, + 73, 76, 197, 70, 73, 73, 128, 70, 73, 71, 85, 82, 69, 45, 51, 128, 70, + 73, 71, 85, 82, 69, 45, 50, 128, 70, 73, 71, 85, 82, 69, 45, 49, 128, 70, + 73, 71, 85, 82, 197, 70, 73, 71, 72, 84, 128, 70, 73, 70, 84, 89, 128, + 70, 73, 70, 84, 217, 70, 73, 70, 84, 72, 83, 128, 70, 73, 70, 84, 72, + 128, 70, 73, 70, 84, 69, 69, 78, 128, 70, 73, 70, 84, 69, 69, 206, 70, + 73, 69, 76, 68, 128, 70, 73, 69, 76, 196, 70, 72, 84, 79, 82, 193, 70, + 70, 76, 128, 70, 70, 73, 128, 70, 69, 85, 88, 128, 70, 69, 85, 70, 69, + 85, 65, 69, 84, 128, 70, 69, 84, 72, 128, 70, 69, 83, 84, 73, 86, 65, 76, + 128, 70, 69, 82, 82, 89, 128, 70, 69, 82, 82, 73, 211, 70, 69, 82, 77, + 65, 84, 65, 128, 70, 69, 82, 77, 65, 84, 193, 70, 69, 79, 200, 70, 69, + 78, 199, 70, 69, 78, 67, 69, 82, 128, 70, 69, 78, 67, 69, 128, 70, 69, + 77, 73, 78, 73, 78, 197, 70, 69, 77, 65, 76, 69, 128, 70, 69, 77, 65, 76, + 197, 70, 69, 76, 76, 79, 87, 83, 72, 73, 80, 128, 70, 69, 73, 128, 70, + 69, 72, 213, 70, 69, 72, 128, 70, 69, 200, 70, 69, 69, 78, 71, 128, 70, + 69, 69, 77, 128, 70, 69, 69, 68, 128, 70, 69, 69, 196, 70, 69, 69, 128, + 70, 69, 66, 82, 85, 65, 82, 89, 128, 70, 69, 65, 84, 72, 69, 82, 128, 70, + 69, 65, 84, 72, 69, 210, 70, 69, 65, 82, 78, 128, 70, 69, 65, 82, 70, 85, + 204, 70, 69, 65, 82, 128, 70, 65, 89, 65, 78, 78, 65, 128, 70, 65, 89, + 128, 70, 65, 88, 128, 70, 65, 216, 70, 65, 84, 73, 71, 85, 69, 128, 70, + 65, 84, 72, 69, 82, 128, 70, 65, 84, 72, 69, 210, 70, 65, 84, 72, 65, 84, + 65, 78, 128, 70, 65, 84, 72, 65, 84, 65, 206, 70, 65, 84, 72, 65, 128, + 70, 65, 84, 72, 193, 70, 65, 84, 128, 70, 65, 83, 84, 128, 70, 65, 82, + 83, 201, 70, 65, 82, 128, 70, 65, 81, 128, 70, 65, 80, 128, 70, 65, 78, + 71, 128, 70, 65, 78, 69, 82, 79, 83, 73, 211, 70, 65, 78, 128, 70, 65, + 77, 73, 76, 89, 128, 70, 65, 77, 128, 70, 65, 76, 76, 69, 206, 70, 65, + 76, 65, 70, 69, 76, 128, 70, 65, 74, 128, 70, 65, 73, 82, 89, 128, 70, + 65, 73, 76, 85, 82, 69, 128, 70, 65, 73, 72, 85, 128, 70, 65, 73, 66, + 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84, 128, 70, 65, 67, 84, 79, 82, + 89, 128, 70, 65, 67, 84, 79, 210, 70, 65, 67, 83, 73, 77, 73, 76, 197, + 70, 65, 67, 73, 78, 71, 83, 128, 70, 65, 67, 69, 45, 54, 128, 70, 65, 67, + 69, 45, 53, 128, 70, 65, 67, 69, 45, 52, 128, 70, 65, 67, 69, 45, 51, + 128, 70, 65, 67, 69, 45, 50, 128, 70, 65, 67, 69, 45, 49, 128, 70, 65, + 65, 77, 65, 69, 128, 70, 65, 65, 73, 128, 70, 65, 65, 70, 85, 128, 70, + 48, 53, 51, 128, 70, 48, 53, 50, 128, 70, 48, 53, 49, 67, 128, 70, 48, + 53, 49, 66, 128, 70, 48, 53, 49, 65, 128, 70, 48, 53, 49, 128, 70, 48, + 53, 48, 128, 70, 48, 52, 57, 128, 70, 48, 52, 56, 128, 70, 48, 52, 55, + 65, 128, 70, 48, 52, 55, 128, 70, 48, 52, 54, 65, 128, 70, 48, 52, 54, + 128, 70, 48, 52, 53, 65, 128, 70, 48, 52, 53, 128, 70, 48, 52, 52, 128, + 70, 48, 52, 51, 128, 70, 48, 52, 50, 128, 70, 48, 52, 49, 128, 70, 48, + 52, 48, 128, 70, 48, 51, 57, 128, 70, 48, 51, 56, 65, 128, 70, 48, 51, + 56, 128, 70, 48, 51, 55, 65, 128, 70, 48, 51, 55, 128, 70, 48, 51, 54, + 128, 70, 48, 51, 53, 128, 70, 48, 51, 52, 128, 70, 48, 51, 51, 128, 70, + 48, 51, 50, 128, 70, 48, 51, 49, 65, 128, 70, 48, 51, 49, 128, 70, 48, + 51, 48, 128, 70, 48, 50, 57, 128, 70, 48, 50, 56, 128, 70, 48, 50, 55, + 128, 70, 48, 50, 54, 128, 70, 48, 50, 53, 128, 70, 48, 50, 52, 128, 70, + 48, 50, 51, 128, 70, 48, 50, 50, 128, 70, 48, 50, 49, 65, 128, 70, 48, + 50, 49, 128, 70, 48, 50, 48, 128, 70, 48, 49, 57, 128, 70, 48, 49, 56, + 128, 70, 48, 49, 55, 128, 70, 48, 49, 54, 128, 70, 48, 49, 53, 128, 70, + 48, 49, 52, 128, 70, 48, 49, 51, 65, 128, 70, 48, 49, 51, 128, 70, 48, + 49, 50, 128, 70, 48, 49, 49, 128, 70, 48, 49, 48, 128, 70, 48, 48, 57, + 128, 70, 48, 48, 56, 128, 70, 48, 48, 55, 128, 70, 48, 48, 54, 128, 70, + 48, 48, 53, 128, 70, 48, 48, 52, 128, 70, 48, 48, 51, 128, 70, 48, 48, + 50, 128, 70, 48, 48, 49, 65, 128, 70, 48, 48, 49, 128, 69, 90, 83, 128, + 69, 90, 200, 69, 90, 69, 78, 128, 69, 90, 69, 206, 69, 90, 128, 69, 89, + 89, 89, 128, 69, 89, 69, 83, 128, 69, 89, 69, 211, 69, 89, 69, 76, 65, + 83, 72, 69, 211, 69, 89, 69, 71, 76, 65, 83, 83, 69, 83, 128, 69, 89, 69, + 71, 65, 90, 69, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 69, 89, 69, 71, + 65, 90, 69, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 69, 89, 69, 66, + 82, 79, 87, 211, 69, 89, 69, 66, 82, 79, 215, 69, 89, 197, 69, 89, 66, + 69, 89, 70, 73, 76, 73, 128, 69, 89, 65, 78, 78, 65, 128, 69, 88, 84, 82, + 69, 77, 69, 76, 217, 69, 88, 84, 82, 65, 84, 69, 82, 82, 69, 83, 84, 82, + 73, 65, 204, 69, 88, 84, 82, 65, 45, 76, 79, 215, 69, 88, 84, 82, 65, 45, + 72, 73, 71, 200, 69, 88, 84, 82, 193, 69, 88, 84, 73, 78, 71, 85, 73, 83, + 72, 69, 82, 128, 69, 88, 84, 69, 78, 83, 73, 79, 78, 128, 69, 88, 84, 69, + 78, 68, 69, 68, 128, 69, 88, 84, 69, 78, 68, 69, 196, 69, 88, 80, 82, 69, + 83, 83, 73, 79, 78, 76, 69, 83, 211, 69, 88, 80, 79, 78, 69, 78, 212, 69, + 88, 80, 76, 79, 68, 73, 78, 199, 69, 88, 79, 128, 69, 88, 207, 69, 88, + 73, 83, 84, 83, 128, 69, 88, 73, 83, 84, 128, 69, 88, 72, 65, 85, 83, 84, + 73, 79, 78, 128, 69, 88, 72, 65, 76, 69, 128, 69, 88, 67, 76, 65, 77, 65, + 84, 73, 79, 78, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 206, 69, 88, + 67, 73, 84, 69, 77, 69, 78, 84, 128, 69, 88, 67, 72, 65, 78, 71, 69, 128, + 69, 88, 67, 69, 83, 83, 128, 69, 88, 67, 69, 76, 76, 69, 78, 84, 128, 69, + 87, 69, 128, 69, 86, 69, 82, 217, 69, 86, 69, 82, 71, 82, 69, 69, 206, + 69, 86, 69, 78, 73, 78, 71, 128, 69, 85, 82, 79, 80, 69, 65, 206, 69, 85, + 82, 79, 80, 69, 45, 65, 70, 82, 73, 67, 65, 128, 69, 85, 82, 79, 45, 67, + 85, 82, 82, 69, 78, 67, 217, 69, 85, 82, 207, 69, 85, 76, 69, 210, 69, + 85, 45, 85, 128, 69, 85, 45, 79, 128, 69, 85, 45, 69, 85, 128, 69, 85, + 45, 69, 79, 128, 69, 85, 45, 69, 128, 69, 85, 45, 65, 128, 69, 84, 88, + 128, 69, 84, 78, 65, 72, 84, 65, 128, 69, 84, 72, 69, 204, 69, 84, 69, + 82, 79, 206, 69, 84, 69, 82, 78, 73, 84, 89, 128, 69, 84, 69, 82, 78, 73, + 84, 217, 69, 84, 66, 128, 69, 83, 90, 128, 69, 83, 85, 75, 85, 85, 68, + 79, 128, 69, 83, 84, 73, 77, 65, 84, 69, 83, 128, 69, 83, 84, 73, 77, 65, + 84, 69, 196, 69, 83, 72, 69, 51, 128, 69, 83, 72, 50, 49, 128, 69, 83, + 72, 49, 54, 128, 69, 83, 67, 65, 80, 69, 128, 69, 83, 67, 128, 69, 83, + 65, 128, 69, 83, 45, 84, 69, 128, 69, 83, 45, 51, 128, 69, 83, 45, 50, + 128, 69, 83, 45, 49, 128, 69, 82, 82, 79, 82, 45, 66, 65, 82, 82, 69, + 196, 69, 82, 82, 128, 69, 82, 73, 211, 69, 82, 73, 78, 50, 128, 69, 82, + 73, 78, 178, 69, 82, 71, 128, 69, 82, 65, 83, 197, 69, 81, 85, 73, 86, + 65, 76, 69, 78, 212, 69, 81, 85, 73, 76, 65, 84, 69, 82, 65, 204, 69, 81, + 85, 73, 72, 79, 80, 80, 69, 82, 128, 69, 81, 85, 73, 72, 79, 80, 80, 69, + 210, 69, 81, 85, 73, 68, 128, 69, 81, 85, 73, 65, 78, 71, 85, 76, 65, + 210, 69, 81, 85, 65, 76, 83, 128, 69, 81, 85, 65, 76, 211, 69, 81, 85, + 65, 76, 128, 69, 80, 83, 73, 76, 79, 78, 128, 69, 80, 83, 73, 76, 79, + 206, 69, 80, 79, 67, 72, 128, 69, 80, 73, 71, 82, 65, 80, 72, 73, 195, + 69, 80, 73, 68, 65, 85, 82, 69, 65, 206, 69, 80, 69, 78, 84, 72, 69, 84, + 73, 195, 69, 80, 69, 71, 69, 82, 77, 65, 128, 69, 80, 65, 67, 212, 69, + 79, 84, 128, 69, 79, 77, 128, 69, 79, 76, 72, 88, 128, 69, 79, 76, 128, + 69, 79, 72, 128, 69, 78, 89, 128, 69, 78, 86, 69, 76, 79, 80, 69, 128, + 69, 78, 86, 69, 76, 79, 80, 197, 69, 78, 85, 77, 69, 82, 65, 84, 73, 79, + 206, 69, 78, 84, 82, 89, 45, 50, 128, 69, 78, 84, 82, 89, 45, 49, 128, + 69, 78, 84, 82, 89, 128, 69, 78, 84, 82, 217, 69, 78, 84, 72, 85, 83, 73, + 65, 83, 77, 128, 69, 78, 84, 69, 82, 80, 82, 73, 83, 69, 128, 69, 78, 84, + 69, 82, 73, 78, 199, 69, 78, 84, 69, 82, 128, 69, 78, 84, 69, 210, 69, + 78, 84, 45, 83, 72, 65, 80, 69, 196, 69, 78, 81, 85, 73, 82, 89, 128, 69, + 78, 81, 128, 69, 78, 79, 211, 69, 78, 78, 73, 128, 69, 78, 78, 128, 69, + 78, 76, 65, 82, 71, 69, 77, 69, 78, 84, 128, 69, 78, 71, 73, 78, 69, 128, + 69, 78, 68, 79, 70, 79, 78, 79, 78, 128, 69, 78, 68, 73, 78, 199, 69, 78, + 68, 69, 80, 128, 69, 78, 68, 69, 65, 86, 79, 85, 82, 128, 69, 78, 67, 79, + 85, 78, 84, 69, 82, 83, 128, 69, 78, 67, 76, 79, 83, 85, 82, 69, 83, 128, + 69, 78, 67, 76, 79, 83, 85, 82, 69, 128, 69, 78, 67, 76, 79, 83, 73, 78, + 199, 69, 78, 67, 128, 69, 78, 65, 82, 88, 73, 211, 69, 78, 65, 82, 77, + 79, 78, 73, 79, 211, 69, 77, 80, 84, 217, 69, 77, 80, 72, 65, 84, 73, + 195, 69, 77, 80, 72, 65, 83, 73, 211, 69, 77, 79, 74, 201, 69, 77, 66, + 82, 79, 73, 68, 69, 82, 89, 128, 69, 77, 66, 76, 69, 77, 128, 69, 77, 66, + 69, 76, 76, 73, 83, 72, 77, 69, 78, 84, 128, 69, 77, 66, 69, 68, 68, 73, + 78, 71, 128, 69, 76, 89, 77, 65, 73, 195, 69, 76, 89, 128, 69, 76, 84, + 128, 69, 76, 76, 73, 80, 84, 73, 195, 69, 76, 76, 73, 80, 83, 73, 83, + 128, 69, 76, 76, 73, 80, 83, 69, 128, 69, 76, 73, 70, 73, 128, 69, 76, + 69, 86, 69, 78, 45, 84, 72, 73, 82, 84, 89, 128, 69, 76, 69, 86, 69, 78, + 128, 69, 76, 69, 86, 69, 206, 69, 76, 69, 86, 65, 84, 85, 211, 69, 76, + 69, 80, 72, 65, 78, 84, 128, 69, 76, 69, 77, 69, 78, 212, 69, 76, 69, 67, + 84, 82, 73, 67, 65, 204, 69, 76, 69, 67, 84, 82, 73, 195, 69, 76, 66, 65, + 83, 65, 206, 69, 76, 65, 77, 73, 84, 69, 128, 69, 76, 65, 77, 73, 84, + 197, 69, 76, 65, 70, 82, 79, 78, 128, 69, 75, 83, 84, 82, 69, 80, 84, 79, + 78, 128, 69, 75, 83, 128, 69, 75, 70, 79, 78, 73, 84, 73, 75, 79, 78, + 128, 69, 75, 65, 82, 65, 128, 69, 75, 65, 77, 128, 69, 74, 69, 67, 212, + 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, + 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, + 128, 68, 90, 72, 69, 128, 68, 90, 72, 65, 128, 68, 90, 69, 76, 79, 128, + 68, 90, 69, 69, 128, 68, 90, 69, 128, 68, 90, 65, 89, 128, 68, 90, 65, + 65, 128, 68, 90, 65, 128, 68, 90, 128, 68, 218, 68, 89, 79, 128, 68, 89, + 207, 68, 89, 78, 65, 77, 73, 195, 68, 89, 69, 72, 128, 68, 89, 69, 200, + 68, 89, 65, 78, 128, 68, 87, 79, 128, 68, 87, 69, 128, 68, 87, 65, 128, + 68, 86, 73, 83, 86, 65, 82, 65, 128, 68, 86, 68, 128, 68, 86, 128, 68, + 85, 84, 73, 69, 83, 128, 68, 85, 83, 75, 128, 68, 85, 83, 72, 69, 78, 78, + 65, 128, 68, 85, 82, 65, 84, 73, 79, 78, 128, 68, 85, 82, 50, 128, 68, + 85, 80, 79, 78, 68, 73, 85, 211, 68, 85, 79, 88, 128, 68, 85, 79, 128, + 68, 85, 78, 52, 128, 68, 85, 78, 51, 128, 68, 85, 78, 179, 68, 85, 77, + 80, 76, 73, 78, 71, 128, 68, 85, 77, 128, 68, 85, 204, 68, 85, 72, 128, + 68, 85, 71, 85, 68, 128, 68, 85, 199, 68, 85, 67, 75, 128, 68, 85, 66, + 50, 128, 68, 85, 66, 128, 68, 85, 194, 68, 82, 89, 128, 68, 82, 217, 68, + 82, 85, 77, 83, 84, 73, 67, 75, 83, 128, 68, 82, 85, 77, 128, 68, 82, 85, + 205, 68, 82, 79, 80, 83, 128, 68, 82, 79, 80, 76, 69, 84, 128, 68, 82, + 79, 80, 45, 83, 72, 65, 68, 79, 87, 69, 196, 68, 82, 79, 208, 68, 82, 79, + 79, 76, 73, 78, 199, 68, 82, 79, 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, + 69, 128, 68, 82, 73, 86, 197, 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, + 68, 82, 69, 83, 83, 128, 68, 82, 69, 65, 77, 217, 68, 82, 65, 85, 71, 72, + 84, 211, 68, 82, 65, 77, 128, 68, 82, 65, 205, 68, 82, 65, 71, 79, 78, + 128, 68, 82, 65, 71, 79, 206, 68, 82, 65, 70, 84, 73, 78, 199, 68, 82, + 65, 67, 72, 77, 65, 83, 128, 68, 82, 65, 67, 72, 77, 65, 128, 68, 82, 65, + 67, 72, 77, 193, 68, 79, 87, 78, 87, 65, 82, 68, 83, 128, 68, 79, 87, 78, + 87, 65, 82, 68, 211, 68, 79, 87, 78, 87, 65, 82, 196, 68, 79, 87, 78, 83, + 67, 65, 76, 73, 78, 199, 68, 79, 87, 78, 45, 80, 79, 73, 78, 84, 73, 78, + 199, 68, 79, 87, 78, 128, 68, 79, 86, 69, 128, 68, 79, 86, 197, 68, 79, + 85, 71, 72, 78, 85, 84, 128, 68, 79, 85, 66, 84, 128, 68, 79, 85, 66, 76, + 69, 196, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 68, 79, 85, + 66, 76, 69, 45, 76, 73, 78, 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, + 78, 197, 68, 79, 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, + 76, 69, 128, 68, 79, 84, 84, 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, + 45, 78, 128, 68, 79, 84, 84, 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, + 128, 68, 79, 84, 84, 69, 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, + 83, 45, 55, 56, 128, 68, 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, + 56, 128, 68, 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, + 128, 68, 79, 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, + 79, 84, 83, 45, 53, 55, 56, 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, + 84, 83, 45, 53, 54, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, + 79, 84, 83, 45, 53, 54, 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, + 84, 83, 45, 53, 128, 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, + 52, 55, 56, 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, + 54, 56, 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, + 52, 54, 55, 128, 68, 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, + 53, 56, 128, 68, 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, + 52, 53, 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, + 45, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, + 79, 84, 83, 45, 52, 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, + 84, 83, 45, 52, 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, + 51, 55, 56, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, + 54, 56, 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, + 51, 54, 55, 128, 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, + 53, 56, 128, 68, 79, 84, 83, 45, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, + 51, 53, 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, + 45, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 55, 128, 68, + 79, 84, 83, 45, 51, 53, 54, 128, 68, 79, 84, 83, 45, 51, 53, 128, 68, 79, + 84, 83, 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, + 79, 84, 83, 45, 51, 52, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56, 128, + 68, 79, 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, + 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, + 52, 53, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68, 79, 84, + 83, 45, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 56, 128, + 68, 79, 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, + 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84, + 83, 45, 51, 52, 53, 128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, + 45, 51, 128, 68, 79, 84, 83, 45, 50, 56, 128, 68, 79, 84, 83, 45, 50, 55, + 56, 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56, + 128, 68, 79, 84, 83, 45, 50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 54, + 55, 128, 68, 79, 84, 83, 45, 50, 54, 128, 68, 79, 84, 83, 45, 50, 53, 56, + 128, 68, 79, 84, 83, 45, 50, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, + 55, 128, 68, 79, 84, 83, 45, 50, 53, 54, 56, 128, 68, 79, 84, 83, 45, 50, + 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, 54, 55, 128, 68, 79, 84, + 83, 45, 50, 53, 54, 128, 68, 79, 84, 83, 45, 50, 53, 128, 68, 79, 84, 83, + 45, 50, 52, 56, 128, 68, 79, 84, 83, 45, 50, 52, 55, 56, 128, 68, 79, 84, + 83, 45, 50, 52, 55, 128, 68, 79, 84, 83, 45, 50, 52, 54, 56, 128, 68, 79, + 84, 83, 45, 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 52, 54, 55, + 128, 68, 79, 84, 83, 45, 50, 52, 54, 128, 68, 79, 84, 83, 45, 50, 52, 53, + 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, + 50, 52, 53, 55, 128, 68, 79, 84, 83, 45, 50, 52, 53, 54, 56, 128, 68, 79, + 84, 83, 45, 50, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, + 54, 55, 128, 68, 79, 84, 83, 45, 50, 52, 53, 54, 128, 68, 79, 84, 83, 45, + 50, 52, 53, 128, 68, 79, 84, 83, 45, 50, 52, 128, 68, 79, 84, 83, 45, 50, + 51, 56, 128, 68, 79, 84, 83, 45, 50, 51, 55, 56, 128, 68, 79, 84, 83, 45, + 50, 51, 55, 128, 68, 79, 84, 83, 45, 50, 51, 54, 56, 128, 68, 79, 84, 83, + 45, 50, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 54, 55, 128, 68, + 79, 84, 83, 45, 50, 51, 54, 128, 68, 79, 84, 83, 45, 50, 51, 53, 56, 128, + 68, 79, 84, 83, 45, 50, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, + 53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 56, 128, 68, 79, 84, 83, + 45, 50, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 55, + 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 128, 68, 79, 84, 83, 45, 50, 51, + 53, 128, 68, 79, 84, 83, 45, 50, 51, 52, 56, 128, 68, 79, 84, 83, 45, 50, + 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 55, 128, 68, 79, 84, + 83, 45, 50, 51, 52, 54, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 55, + 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, + 50, 51, 52, 54, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 56, 128, 68, 79, + 84, 83, 45, 50, 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, + 53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 54, 56, 128, 68, 79, 84, + 83, 45, 50, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, + 53, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 54, 128, 68, 79, 84, + 83, 45, 50, 51, 52, 53, 128, 68, 79, 84, 83, 45, 50, 51, 52, 128, 68, 79, + 84, 83, 45, 50, 51, 128, 68, 79, 84, 83, 45, 50, 128, 68, 79, 84, 83, 45, + 49, 56, 128, 68, 79, 84, 83, 45, 49, 55, 56, 128, 68, 79, 84, 83, 45, 49, + 55, 128, 68, 79, 84, 83, 45, 49, 54, 56, 128, 68, 79, 84, 83, 45, 49, 54, + 55, 56, 128, 68, 79, 84, 83, 45, 49, 54, 55, 128, 68, 79, 84, 83, 45, 49, + 54, 128, 68, 79, 84, 83, 45, 49, 53, 56, 128, 68, 79, 84, 83, 45, 49, 53, + 55, 56, 128, 68, 79, 84, 83, 45, 49, 53, 55, 128, 68, 79, 84, 83, 45, 49, + 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 53, 54, 55, 56, 128, 68, 79, 84, + 83, 45, 49, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 53, 54, 128, 68, 79, + 84, 83, 45, 49, 53, 128, 68, 79, 84, 83, 45, 49, 52, 56, 128, 68, 79, 84, + 83, 45, 49, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52, 55, 128, 68, 79, + 84, 83, 45, 49, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, 52, 54, 55, 56, + 128, 68, 79, 84, 83, 45, 49, 52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 52, + 54, 128, 68, 79, 84, 83, 45, 49, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, + 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 55, 128, 68, 79, 84, + 83, 45, 49, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 54, 55, + 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, + 49, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 52, 53, 128, 68, 79, 84, 83, + 45, 49, 52, 128, 68, 79, 84, 83, 45, 49, 51, 56, 128, 68, 79, 84, 83, 45, + 49, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 55, 128, 68, 79, 84, 83, + 45, 49, 51, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 54, 55, 56, 128, 68, + 79, 84, 83, 45, 49, 51, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 54, 128, + 68, 79, 84, 83, 45, 49, 51, 53, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, + 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 55, 128, 68, 79, 84, 83, 45, + 49, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 55, 56, 128, + 68, 79, 84, 83, 45, 49, 51, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, + 53, 54, 128, 68, 79, 84, 83, 45, 49, 51, 53, 128, 68, 79, 84, 83, 45, 49, + 51, 52, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 55, 56, 128, 68, 79, 84, + 83, 45, 49, 51, 52, 55, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 56, 128, + 68, 79, 84, 83, 45, 49, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, + 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 128, 68, 79, 84, + 83, 45, 49, 51, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 55, + 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, + 49, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 54, 55, + 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 54, 55, 128, 68, 79, 84, 83, + 45, 49, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 128, 68, + 79, 84, 83, 45, 49, 51, 52, 128, 68, 79, 84, 83, 45, 49, 51, 128, 68, 79, + 84, 83, 45, 49, 50, 56, 128, 68, 79, 84, 83, 45, 49, 50, 55, 56, 128, 68, + 79, 84, 83, 45, 49, 50, 55, 128, 68, 79, 84, 83, 45, 49, 50, 54, 56, 128, + 68, 79, 84, 83, 45, 49, 50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, + 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 54, 128, 68, 79, 84, 83, 45, 49, + 50, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53, 55, 56, 128, 68, 79, 84, + 83, 45, 49, 50, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 53, 54, 56, 128, + 68, 79, 84, 83, 45, 49, 50, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, + 50, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 53, 54, 128, 68, 79, 84, + 83, 45, 49, 50, 53, 128, 68, 79, 84, 83, 45, 49, 50, 52, 56, 128, 68, 79, + 84, 83, 45, 49, 50, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 55, + 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, + 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 55, 128, 68, + 79, 84, 83, 45, 49, 50, 52, 54, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, + 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 55, 56, 128, 68, 79, 84, 83, + 45, 49, 50, 52, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, 56, + 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, + 45, 49, 50, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, + 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 128, 68, 79, 84, 83, 45, 49, 50, + 52, 128, 68, 79, 84, 83, 45, 49, 50, 51, 56, 128, 68, 79, 84, 83, 45, 49, + 50, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 55, 128, 68, 79, 84, + 83, 45, 49, 50, 51, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 55, + 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 55, 128, 68, 79, 84, 83, 45, + 49, 50, 51, 54, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 56, 128, 68, 79, + 84, 83, 45, 49, 50, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, + 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 56, 128, 68, 79, 84, + 83, 45, 49, 50, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, + 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 128, 68, 79, 84, + 83, 45, 49, 50, 51, 53, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 56, 128, + 68, 79, 84, 83, 45, 49, 50, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, + 50, 51, 52, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 56, 128, 68, + 79, 84, 83, 45, 49, 50, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, + 50, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 128, 68, + 79, 84, 83, 45, 49, 50, 51, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, + 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 55, 128, + 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, + 49, 50, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, + 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 128, 68, 79, + 84, 83, 45, 49, 50, 51, 52, 53, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, + 128, 68, 79, 84, 83, 45, 49, 50, 51, 128, 68, 79, 84, 83, 45, 49, 50, + 128, 68, 79, 84, 83, 45, 49, 128, 68, 79, 84, 83, 128, 68, 79, 84, 211, + 68, 79, 84, 76, 69, 83, 211, 68, 79, 82, 85, 128, 68, 79, 82, 79, 77, + 197, 68, 79, 79, 82, 128, 68, 79, 79, 78, 71, 128, 68, 79, 78, 71, 128, + 68, 79, 77, 65, 73, 206, 68, 79, 76, 80, 72, 73, 78, 128, 68, 79, 76, 76, + 83, 128, 68, 79, 76, 76, 65, 210, 68, 79, 76, 73, 85, 77, 128, 68, 79, + 75, 77, 65, 73, 128, 68, 79, 73, 84, 128, 68, 79, 73, 78, 199, 68, 79, + 73, 128, 68, 79, 71, 82, 193, 68, 79, 71, 128, 68, 79, 199, 68, 79, 69, + 211, 68, 79, 68, 69, 75, 65, 84, 65, 128, 68, 79, 67, 85, 77, 69, 78, 84, + 128, 68, 79, 67, 85, 77, 69, 78, 212, 68, 79, 66, 82, 79, 128, 68, 79, + 65, 67, 72, 65, 83, 72, 77, 69, 69, 128, 68, 79, 65, 67, 72, 65, 83, 72, + 77, 69, 197, 68, 79, 65, 128, 68, 79, 45, 79, 128, 68, 78, 193, 68, 77, + 128, 68, 205, 68, 76, 85, 128, 68, 76, 79, 128, 68, 76, 73, 128, 68, 76, + 72, 89, 65, 128, 68, 76, 72, 65, 128, 68, 76, 69, 69, 128, 68, 76, 65, + 128, 68, 76, 128, 68, 75, 65, 82, 128, 68, 75, 65, 210, 68, 74, 69, 82, + 86, 73, 128, 68, 74, 69, 82, 86, 128, 68, 74, 69, 128, 68, 74, 65, 128, + 68, 73, 90, 90, 217, 68, 73, 89, 193, 68, 73, 86, 79, 82, 67, 197, 68, + 73, 86, 73, 83, 73, 79, 78, 128, 68, 73, 86, 73, 83, 73, 79, 206, 68, 73, + 86, 73, 78, 199, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 68, 73, 86, + 73, 68, 69, 83, 128, 68, 73, 86, 73, 68, 69, 82, 83, 128, 68, 73, 86, 73, + 68, 69, 82, 128, 68, 73, 86, 73, 68, 69, 196, 68, 73, 86, 73, 68, 69, + 128, 68, 73, 86, 73, 68, 197, 68, 73, 86, 69, 82, 71, 69, 78, 67, 69, + 128, 68, 73, 84, 84, 207, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, 128, + 68, 73, 83, 84, 73, 78, 71, 85, 73, 83, 72, 128, 68, 73, 83, 84, 73, 76, + 76, 128, 68, 73, 83, 83, 79, 76, 86, 69, 45, 50, 128, 68, 73, 83, 83, 79, + 76, 86, 69, 128, 68, 73, 83, 80, 85, 84, 69, 196, 68, 73, 83, 80, 69, 82, + 83, 73, 79, 78, 128, 68, 73, 83, 75, 128, 68, 73, 83, 73, 77, 79, 85, + 128, 68, 73, 83, 72, 128, 68, 73, 83, 67, 79, 78, 84, 73, 78, 85, 79, 85, + 211, 68, 73, 83, 195, 68, 73, 83, 65, 80, 80, 79, 73, 78, 84, 69, 196, + 68, 73, 83, 65, 66, 76, 69, 196, 68, 73, 82, 71, 193, 68, 73, 82, 69, 67, + 84, 76, 217, 68, 73, 82, 69, 67, 84, 73, 79, 78, 65, 204, 68, 73, 82, 69, + 67, 84, 73, 79, 206, 68, 73, 80, 84, 69, 128, 68, 73, 80, 80, 69, 82, + 128, 68, 73, 80, 76, 79, 85, 78, 128, 68, 73, 80, 76, 73, 128, 68, 73, + 80, 76, 201, 68, 73, 78, 71, 66, 65, 212, 68, 73, 206, 68, 73, 77, 77, + 73, 78, 71, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 51, 128, 68, + 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 50, 128, 68, 73, 77, 73, 78, 85, + 84, 73, 79, 78, 45, 49, 128, 68, 73, 77, 73, 78, 73, 83, 72, 77, 69, 78, + 84, 128, 68, 73, 77, 73, 68, 73, 193, 68, 73, 77, 69, 78, 83, 73, 79, 78, + 65, 204, 68, 73, 77, 69, 78, 83, 73, 79, 206, 68, 73, 77, 50, 128, 68, + 73, 77, 178, 68, 73, 76, 128, 68, 73, 71, 82, 65, 80, 72, 128, 68, 73, + 71, 82, 65, 80, 200, 68, 73, 71, 82, 65, 77, 77, 79, 211, 68, 73, 71, 82, + 65, 77, 77, 193, 68, 73, 71, 82, 65, 205, 68, 73, 71, 79, 82, 71, 79, 78, + 128, 68, 73, 71, 79, 82, 71, 79, 206, 68, 73, 71, 73, 84, 83, 128, 68, + 73, 71, 65, 77, 77, 65, 128, 68, 73, 71, 193, 68, 73, 70, 84, 79, 71, 71, + 79, 211, 68, 73, 70, 79, 78, 73, 65, 83, 128, 68, 73, 70, 70, 73, 67, 85, + 76, 84, 217, 68, 73, 70, 70, 73, 67, 85, 76, 84, 73, 69, 83, 128, 68, 73, + 70, 70, 69, 82, 69, 78, 84, 73, 65, 76, 128, 68, 73, 70, 70, 69, 82, 69, + 78, 67, 197, 68, 73, 70, 65, 84, 128, 68, 73, 69, 83, 73, 83, 128, 68, + 73, 69, 83, 73, 211, 68, 73, 69, 83, 69, 204, 68, 73, 69, 80, 128, 68, + 73, 197, 68, 73, 66, 128, 68, 73, 65, 84, 79, 78, 79, 206, 68, 73, 65, + 84, 79, 78, 73, 75, 201, 68, 73, 65, 83, 84, 79, 76, 201, 68, 73, 65, 77, + 79, 78, 68, 83, 128, 68, 73, 65, 77, 79, 78, 68, 128, 68, 73, 65, 77, 79, + 78, 196, 68, 73, 65, 77, 69, 84, 69, 210, 68, 73, 65, 76, 89, 84, 73, 75, + 65, 128, 68, 73, 65, 76, 89, 84, 73, 75, 193, 68, 73, 65, 76, 69, 67, 84, + 45, 208, 68, 73, 65, 71, 79, 78, 65, 76, 128, 68, 73, 65, 69, 82, 69, 83, + 73, 90, 69, 196, 68, 73, 65, 69, 82, 69, 83, 73, 83, 45, 82, 73, 78, 71, + 128, 68, 73, 65, 69, 82, 69, 83, 73, 83, 128, 68, 73, 65, 69, 82, 69, 83, + 73, 211, 68, 72, 79, 85, 128, 68, 72, 79, 79, 128, 68, 72, 79, 128, 68, + 72, 73, 73, 128, 68, 72, 72, 85, 128, 68, 72, 72, 79, 79, 128, 68, 72, + 72, 79, 128, 68, 72, 72, 73, 128, 68, 72, 72, 69, 69, 128, 68, 72, 72, + 69, 128, 68, 72, 72, 65, 128, 68, 72, 69, 69, 128, 68, 72, 65, 82, 77, + 65, 128, 68, 72, 65, 77, 69, 68, 72, 128, 68, 72, 65, 76, 69, 84, 72, + 128, 68, 72, 65, 76, 65, 84, 72, 128, 68, 72, 65, 76, 128, 68, 72, 65, + 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, 128, 68, 72, 65, 65, 128, 68, + 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, 84, 69, 82, 79, 213, 68, 69, + 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, 128, 68, 69, 86, 73, 67, + 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, 128, 68, 69, 85, 78, 71, + 128, 68, 69, 83, 75, 84, 79, 208, 68, 69, 83, 203, 68, 69, 83, 73, 71, + 78, 128, 68, 69, 83, 73, 128, 68, 69, 83, 69, 82, 84, 128, 68, 69, 83, + 69, 82, 212, 68, 69, 83, 69, 82, 69, 212, 68, 69, 83, 67, 82, 73, 80, 84, + 73, 79, 206, 68, 69, 83, 67, 69, 78, 68, 73, 78, 199, 68, 69, 83, 67, 69, + 78, 68, 69, 82, 128, 68, 69, 82, 69, 84, 45, 72, 73, 68, 69, 84, 128, 68, + 69, 82, 69, 84, 128, 68, 69, 82, 69, 76, 73, 67, 212, 68, 69, 80, 84, 72, + 128, 68, 69, 80, 65, 82, 84, 85, 82, 69, 128, 68, 69, 80, 65, 82, 84, 77, + 69, 78, 212, 68, 69, 80, 65, 82, 84, 73, 78, 199, 68, 69, 78, 84, 73, 83, + 84, 82, 217, 68, 69, 78, 84, 65, 204, 68, 69, 78, 79, 77, 73, 78, 65, 84, + 79, 82, 128, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 210, 68, 69, 78, 78, + 69, 78, 128, 68, 69, 78, 71, 128, 68, 69, 78, 197, 68, 69, 78, 65, 82, + 73, 85, 211, 68, 69, 76, 84, 65, 128, 68, 69, 76, 84, 193, 68, 69, 76, + 84, 128, 68, 69, 76, 80, 72, 73, 195, 68, 69, 76, 73, 86, 69, 82, 217, + 68, 69, 76, 73, 86, 69, 82, 65, 78, 67, 69, 128, 68, 69, 76, 73, 77, 73, + 84, 69, 82, 128, 68, 69, 76, 73, 77, 73, 84, 69, 210, 68, 69, 76, 73, 67, + 73, 79, 85, 211, 68, 69, 76, 69, 84, 73, 79, 206, 68, 69, 76, 69, 84, 69, + 128, 68, 69, 76, 69, 84, 197, 68, 69, 75, 65, 128, 68, 69, 75, 128, 68, + 69, 73, 128, 68, 69, 72, 73, 128, 68, 69, 71, 82, 69, 69, 83, 128, 68, + 69, 71, 82, 69, 197, 68, 69, 70, 73, 78, 73, 84, 73, 79, 78, 128, 68, 69, + 70, 69, 67, 84, 73, 86, 69, 78, 69, 83, 211, 68, 69, 69, 82, 128, 68, 69, + 69, 80, 76, 89, 128, 68, 69, 69, 76, 128, 68, 69, 67, 82, 69, 83, 67, 69, + 78, 68, 79, 128, 68, 69, 67, 82, 69, 65, 83, 69, 128, 68, 69, 67, 82, 69, + 65, 83, 197, 68, 69, 67, 79, 82, 65, 84, 73, 86, 197, 68, 69, 67, 79, 82, + 65, 84, 73, 79, 78, 128, 68, 69, 67, 73, 83, 73, 86, 69, 78, 69, 83, 83, + 128, 68, 69, 67, 73, 77, 65, 204, 68, 69, 67, 73, 68, 85, 79, 85, 211, + 68, 69, 67, 69, 77, 66, 69, 82, 128, 68, 69, 67, 65, 89, 69, 68, 128, 68, + 69, 66, 73, 212, 68, 69, 65, 84, 72, 128, 68, 69, 65, 198, 68, 69, 65, + 68, 128, 68, 68, 87, 65, 128, 68, 68, 85, 88, 128, 68, 68, 85, 84, 128, + 68, 68, 85, 82, 88, 128, 68, 68, 85, 82, 128, 68, 68, 85, 80, 128, 68, + 68, 85, 79, 88, 128, 68, 68, 85, 79, 80, 128, 68, 68, 85, 79, 128, 68, + 68, 85, 128, 68, 68, 79, 88, 128, 68, 68, 79, 84, 128, 68, 68, 79, 80, + 128, 68, 68, 79, 65, 128, 68, 68, 73, 88, 128, 68, 68, 73, 84, 128, 68, + 68, 73, 80, 128, 68, 68, 73, 69, 88, 128, 68, 68, 73, 69, 80, 128, 68, + 68, 73, 69, 128, 68, 68, 73, 128, 68, 68, 72, 85, 128, 68, 68, 72, 79, + 128, 68, 68, 72, 69, 69, 128, 68, 68, 72, 69, 128, 68, 68, 72, 65, 65, + 128, 68, 68, 72, 65, 128, 68, 68, 69, 88, 128, 68, 68, 69, 80, 128, 68, + 68, 69, 69, 128, 68, 68, 69, 128, 68, 68, 68, 72, 65, 128, 68, 68, 68, + 65, 128, 68, 68, 65, 89, 65, 78, 78, 65, 128, 68, 68, 65, 88, 128, 68, + 68, 65, 84, 128, 68, 68, 65, 80, 128, 68, 68, 65, 76, 128, 68, 68, 65, + 204, 68, 68, 65, 72, 65, 76, 128, 68, 68, 65, 72, 65, 204, 68, 68, 65, + 65, 128, 68, 67, 83, 128, 68, 67, 72, 69, 128, 68, 67, 52, 128, 68, 67, + 51, 128, 68, 67, 50, 128, 68, 67, 49, 128, 68, 194, 68, 65, 89, 45, 78, + 73, 71, 72, 84, 128, 68, 65, 217, 68, 65, 87, 66, 128, 68, 65, 86, 73, + 89, 65, 78, 73, 128, 68, 65, 86, 73, 68, 128, 68, 65, 84, 197, 68, 65, + 83, 73, 65, 128, 68, 65, 83, 73, 193, 68, 65, 83, 72, 69, 196, 68, 65, + 83, 72, 128, 68, 65, 83, 200, 68, 65, 83, 69, 73, 65, 128, 68, 65, 82, + 84, 128, 68, 65, 82, 75, 69, 78, 73, 78, 71, 128, 68, 65, 82, 75, 69, 78, + 73, 78, 199, 68, 65, 82, 203, 68, 65, 82, 71, 65, 128, 68, 65, 82, 65, + 52, 128, 68, 65, 82, 65, 51, 128, 68, 65, 82, 128, 68, 65, 80, 45, 80, + 82, 65, 205, 68, 65, 80, 45, 80, 73, 201, 68, 65, 80, 45, 77, 85, 79, + 217, 68, 65, 80, 45, 66, 85, 79, 206, 68, 65, 80, 45, 66, 69, 201, 68, + 65, 208, 68, 65, 78, 84, 65, 89, 65, 76, 65, 78, 128, 68, 65, 78, 84, 65, + 74, 193, 68, 65, 78, 71, 79, 128, 68, 65, 78, 71, 128, 68, 65, 78, 199, + 68, 65, 78, 68, 65, 128, 68, 65, 78, 67, 73, 78, 71, 128, 68, 65, 78, 67, + 69, 82, 128, 68, 65, 77, 80, 128, 68, 65, 77, 208, 68, 65, 77, 77, 65, + 84, 65, 78, 128, 68, 65, 77, 77, 65, 84, 65, 206, 68, 65, 77, 77, 65, + 128, 68, 65, 77, 77, 193, 68, 65, 77, 65, 82, 85, 128, 68, 65, 76, 69, + 84, 72, 45, 82, 69, 83, 72, 128, 68, 65, 76, 69, 84, 128, 68, 65, 76, 69, + 212, 68, 65, 76, 68, 65, 128, 68, 65, 76, 65, 84, 72, 128, 68, 65, 76, + 65, 84, 200, 68, 65, 76, 65, 84, 128, 68, 65, 73, 82, 128, 68, 65, 73, + 78, 71, 128, 68, 65, 73, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 45, 50, + 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68, 65, 71, 83, 128, 68, + 65, 71, 71, 69, 82, 128, 68, 65, 71, 71, 69, 210, 68, 65, 71, 69, 83, 72, + 128, 68, 65, 71, 69, 83, 200, 68, 65, 71, 66, 65, 83, 73, 78, 78, 65, + 128, 68, 65, 71, 65, 218, 68, 65, 71, 65, 76, 71, 65, 128, 68, 65, 71, + 51, 128, 68, 65, 199, 68, 65, 69, 78, 71, 128, 68, 65, 69, 199, 68, 65, + 68, 128, 68, 65, 196, 68, 65, 65, 83, 85, 128, 68, 65, 65, 76, 73, 128, + 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, 55, 72, 128, 68, 48, 54, 55, 71, + 128, 68, 48, 54, 55, 70, 128, 68, 48, 54, 55, 69, 128, 68, 48, 54, 55, + 68, 128, 68, 48, 54, 55, 67, 128, 68, 48, 54, 55, 66, 128, 68, 48, 54, + 55, 65, 128, 68, 48, 54, 55, 128, 68, 48, 54, 54, 128, 68, 48, 54, 53, + 128, 68, 48, 54, 52, 128, 68, 48, 54, 51, 128, 68, 48, 54, 50, 128, 68, + 48, 54, 49, 128, 68, 48, 54, 48, 128, 68, 48, 53, 57, 128, 68, 48, 53, + 56, 128, 68, 48, 53, 55, 128, 68, 48, 53, 54, 128, 68, 48, 53, 53, 128, + 68, 48, 53, 52, 65, 128, 68, 48, 53, 52, 128, 68, 48, 53, 51, 128, 68, + 48, 53, 50, 65, 128, 68, 48, 53, 50, 128, 68, 48, 53, 49, 128, 68, 48, + 53, 48, 73, 128, 68, 48, 53, 48, 72, 128, 68, 48, 53, 48, 71, 128, 68, + 48, 53, 48, 70, 128, 68, 48, 53, 48, 69, 128, 68, 48, 53, 48, 68, 128, + 68, 48, 53, 48, 67, 128, 68, 48, 53, 48, 66, 128, 68, 48, 53, 48, 65, + 128, 68, 48, 53, 48, 128, 68, 48, 52, 57, 128, 68, 48, 52, 56, 65, 128, + 68, 48, 52, 56, 128, 68, 48, 52, 55, 128, 68, 48, 52, 54, 65, 128, 68, + 48, 52, 54, 128, 68, 48, 52, 53, 128, 68, 48, 52, 52, 128, 68, 48, 52, + 51, 128, 68, 48, 52, 50, 128, 68, 48, 52, 49, 128, 68, 48, 52, 48, 128, + 68, 48, 51, 57, 128, 68, 48, 51, 56, 128, 68, 48, 51, 55, 128, 68, 48, + 51, 54, 128, 68, 48, 51, 53, 128, 68, 48, 51, 52, 65, 128, 68, 48, 51, + 52, 128, 68, 48, 51, 51, 128, 68, 48, 51, 50, 128, 68, 48, 51, 49, 65, + 128, 68, 48, 51, 49, 128, 68, 48, 51, 48, 128, 68, 48, 50, 57, 128, 68, + 48, 50, 56, 128, 68, 48, 50, 55, 65, 128, 68, 48, 50, 55, 128, 68, 48, + 50, 54, 128, 68, 48, 50, 53, 128, 68, 48, 50, 52, 128, 68, 48, 50, 51, + 128, 68, 48, 50, 50, 128, 68, 48, 50, 49, 128, 68, 48, 50, 48, 128, 68, + 48, 49, 57, 128, 68, 48, 49, 56, 128, 68, 48, 49, 55, 128, 68, 48, 49, + 54, 128, 68, 48, 49, 53, 128, 68, 48, 49, 52, 128, 68, 48, 49, 51, 128, + 68, 48, 49, 50, 128, 68, 48, 49, 49, 128, 68, 48, 49, 48, 128, 68, 48, + 48, 57, 128, 68, 48, 48, 56, 65, 128, 68, 48, 48, 56, 128, 68, 48, 48, + 55, 128, 68, 48, 48, 54, 128, 68, 48, 48, 53, 128, 68, 48, 48, 52, 128, + 68, 48, 48, 51, 128, 68, 48, 48, 50, 128, 68, 48, 48, 49, 128, 67, 89, + 88, 128, 67, 89, 84, 128, 67, 89, 82, 88, 128, 67, 89, 82, 69, 78, 65, + 73, 195, 67, 89, 82, 128, 67, 89, 80, 82, 73, 79, 212, 67, 89, 80, 69, + 82, 85, 83, 128, 67, 89, 80, 128, 67, 89, 76, 73, 78, 68, 82, 73, 67, 73, + 84, 89, 128, 67, 89, 67, 76, 79, 78, 69, 128, 67, 89, 65, 89, 128, 67, + 89, 65, 87, 128, 67, 89, 65, 128, 67, 87, 79, 79, 128, 67, 87, 79, 128, + 67, 87, 73, 73, 128, 67, 87, 73, 128, 67, 87, 69, 79, 82, 84, 72, 128, + 67, 87, 69, 128, 67, 87, 65, 65, 128, 67, 85, 88, 128, 67, 85, 85, 128, + 67, 85, 212, 67, 85, 83, 84, 79, 77, 83, 128, 67, 85, 83, 84, 79, 77, 69, + 210, 67, 85, 83, 84, 65, 82, 68, 128, 67, 85, 83, 80, 128, 67, 85, 82, + 88, 128, 67, 85, 82, 86, 73, 78, 199, 67, 85, 82, 86, 69, 68, 128, 67, + 85, 82, 86, 69, 196, 67, 85, 82, 86, 69, 128, 67, 85, 82, 86, 197, 67, + 85, 82, 83, 73, 86, 197, 67, 85, 82, 82, 217, 67, 85, 82, 82, 69, 78, 84, + 128, 67, 85, 82, 82, 69, 78, 212, 67, 85, 82, 76, 217, 67, 85, 82, 76, + 73, 78, 199, 67, 85, 82, 76, 128, 67, 85, 82, 128, 67, 85, 80, 80, 69, + 68, 128, 67, 85, 80, 80, 69, 196, 67, 85, 80, 73, 68, 79, 128, 67, 85, + 80, 67, 65, 75, 69, 128, 67, 85, 79, 88, 128, 67, 85, 79, 80, 128, 67, + 85, 79, 128, 67, 85, 205, 67, 85, 76, 84, 73, 86, 65, 84, 73, 79, 206, + 67, 85, 67, 85, 77, 66, 69, 82, 128, 67, 85, 66, 69, 68, 128, 67, 85, 66, + 69, 128, 67, 85, 66, 197, 67, 85, 65, 84, 82, 73, 76, 76, 79, 128, 67, + 85, 65, 84, 82, 73, 76, 76, 207, 67, 85, 65, 205, 67, 83, 73, 128, 67, + 82, 89, 83, 84, 65, 204, 67, 82, 89, 80, 84, 79, 71, 82, 65, 77, 77, 73, + 195, 67, 82, 89, 73, 78, 199, 67, 82, 85, 90, 69, 73, 82, 207, 67, 82, + 85, 67, 73, 70, 79, 82, 205, 67, 82, 85, 67, 73, 66, 76, 69, 45, 53, 128, + 67, 82, 85, 67, 73, 66, 76, 69, 45, 52, 128, 67, 82, 85, 67, 73, 66, 76, + 69, 45, 51, 128, 67, 82, 85, 67, 73, 66, 76, 69, 45, 50, 128, 67, 82, 85, + 67, 73, 66, 76, 69, 128, 67, 82, 79, 87, 78, 128, 67, 82, 79, 83, 83, 73, + 78, 71, 128, 67, 82, 79, 83, 83, 73, 78, 199, 67, 82, 79, 83, 83, 72, 65, + 84, 67, 200, 67, 82, 79, 83, 83, 69, 68, 45, 84, 65, 73, 76, 128, 67, 82, + 79, 83, 83, 69, 68, 128, 67, 82, 79, 83, 83, 69, 196, 67, 82, 79, 83, 83, + 66, 79, 78, 69, 83, 128, 67, 82, 79, 83, 83, 128, 67, 82, 79, 83, 211, + 67, 82, 79, 80, 128, 67, 82, 79, 73, 88, 128, 67, 82, 79, 73, 83, 83, 65, + 78, 84, 128, 67, 82, 79, 67, 85, 211, 67, 82, 79, 67, 79, 68, 73, 76, 69, + 128, 67, 82, 73, 67, 75, 69, 84, 128, 67, 82, 73, 67, 75, 69, 212, 67, + 82, 69, 83, 67, 69, 78, 84, 83, 128, 67, 82, 69, 83, 67, 69, 78, 84, 128, + 67, 82, 69, 83, 67, 69, 78, 212, 67, 82, 69, 68, 73, 212, 67, 82, 69, 65, + 84, 73, 86, 197, 67, 82, 69, 65, 77, 128, 67, 82, 65, 89, 79, 78, 128, + 67, 82, 65, 66, 128, 67, 82, 128, 67, 79, 88, 128, 67, 79, 87, 66, 79, + 217, 67, 79, 87, 128, 67, 79, 215, 67, 79, 86, 69, 82, 73, 78, 199, 67, + 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, + 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, + 89, 76, 69, 70, 212, 67, 79, 80, 89, 128, 67, 79, 80, 82, 79, 68, 85, 67, + 84, 128, 67, 79, 80, 80, 69, 82, 45, 50, 128, 67, 79, 80, 80, 69, 82, + 128, 67, 79, 80, 128, 67, 79, 79, 76, 128, 67, 79, 79, 75, 73, 78, 71, + 128, 67, 79, 79, 75, 73, 69, 128, 67, 79, 79, 75, 69, 196, 67, 79, 79, + 128, 67, 79, 78, 86, 69, 82, 71, 73, 78, 199, 67, 79, 78, 86, 69, 78, 73, + 69, 78, 67, 197, 67, 79, 78, 84, 82, 79, 76, 128, 67, 79, 78, 84, 82, 79, + 204, 67, 79, 78, 84, 82, 65, 82, 73, 69, 84, 89, 128, 67, 79, 78, 84, 82, + 65, 67, 84, 73, 79, 78, 128, 67, 79, 78, 84, 79, 85, 82, 69, 196, 67, 79, + 78, 84, 79, 85, 210, 67, 79, 78, 84, 73, 78, 85, 73, 78, 199, 67, 79, 78, + 84, 73, 78, 85, 65, 84, 73, 79, 206, 67, 79, 78, 84, 69, 78, 84, 73, 79, + 78, 128, 67, 79, 78, 84, 69, 77, 80, 76, 65, 84, 73, 79, 78, 128, 67, 79, + 78, 84, 65, 73, 78, 211, 67, 79, 78, 84, 65, 73, 78, 73, 78, 199, 67, 79, + 78, 84, 65, 73, 206, 67, 79, 78, 84, 65, 67, 84, 128, 67, 79, 78, 83, 84, + 82, 85, 67, 84, 73, 79, 78, 128, 67, 79, 78, 83, 84, 82, 85, 67, 84, 73, + 79, 206, 67, 79, 78, 83, 84, 65, 78, 84, 128, 67, 79, 78, 83, 84, 65, 78, + 212, 67, 79, 78, 83, 84, 65, 78, 67, 89, 128, 67, 79, 78, 83, 69, 67, 85, + 84, 73, 86, 197, 67, 79, 78, 74, 85, 78, 67, 84, 73, 79, 78, 128, 67, 79, + 78, 74, 85, 71, 65, 84, 197, 67, 79, 78, 74, 79, 73, 78, 73, 78, 199, 67, + 79, 78, 74, 79, 73, 78, 69, 68, 128, 67, 79, 78, 74, 79, 73, 78, 69, 196, + 67, 79, 78, 73, 67, 65, 204, 67, 79, 78, 71, 82, 85, 69, 78, 212, 67, 79, + 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, 128, 67, 79, 78, 70, 85, + 83, 69, 196, 67, 79, 78, 70, 79, 85, 78, 68, 69, 196, 67, 79, 78, 70, 76, + 73, 67, 84, 128, 67, 79, 78, 70, 69, 84, 84, 201, 67, 79, 78, 67, 65, 86, + 69, 45, 83, 73, 68, 69, 196, 67, 79, 78, 67, 65, 86, 69, 45, 80, 79, 73, + 78, 84, 69, 196, 67, 79, 77, 80, 85, 84, 69, 82, 83, 128, 67, 79, 77, 80, + 85, 84, 69, 82, 128, 67, 79, 77, 80, 82, 69, 83, 83, 73, 79, 78, 128, 67, + 79, 77, 80, 82, 69, 83, 83, 69, 196, 67, 79, 77, 80, 79, 83, 73, 84, 73, + 79, 78, 128, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 206, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 55, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 55, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 55, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 55, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 55, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 55, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 55, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 55, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 55, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 55, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 55, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 55, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 55, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 55, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 55, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 55, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 55, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 55, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 55, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 55, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 55, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 55, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 55, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 55, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 55, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 55, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 54, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 54, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 54, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 54, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 53, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 53, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 53, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 53, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 52, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 52, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 52, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 52, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 51, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 51, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 51, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 51, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 50, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 50, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 50, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 50, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 49, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 49, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 49, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 49, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 48, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, + 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 54, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 53, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 50, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 49, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, + 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 55, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 54, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 51, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 50, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, + 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 56, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 55, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 52, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 51, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, + 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 57, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 56, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 53, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 52, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, + 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 48, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 57, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 54, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 53, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, + 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 49, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 48, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 55, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 54, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, + 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 50, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 49, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 56, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 55, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, + 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 51, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 50, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 57, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 56, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, + 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 52, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 51, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 48, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 57, 128, 67, 79, 77, 80, + 79, 78, 69, 78, 84, 45, 48, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, + 84, 45, 48, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, + 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 53, 128, 67, 79, + 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 52, 128, 67, 79, 77, 80, 79, 78, + 69, 78, 84, 45, 48, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 48, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 49, 128, + 67, 79, 77, 80, 79, 78, 69, 78, 212, 67, 79, 77, 80, 76, 73, 65, 78, 67, + 69, 128, 67, 79, 77, 80, 76, 69, 84, 73, 79, 78, 128, 67, 79, 77, 80, 76, + 69, 84, 69, 68, 128, 67, 79, 77, 80, 76, 69, 77, 69, 78, 84, 128, 67, 79, + 77, 80, 65, 83, 83, 128, 67, 79, 77, 80, 65, 82, 69, 128, 67, 79, 77, 77, + 79, 206, 67, 79, 77, 77, 69, 82, 67, 73, 65, 204, 67, 79, 77, 77, 65, 78, + 68, 128, 67, 79, 77, 77, 65, 128, 67, 79, 77, 77, 193, 67, 79, 77, 69, + 84, 128, 67, 79, 77, 66, 73, 78, 69, 68, 128, 67, 79, 77, 66, 73, 78, 65, + 84, 73, 79, 78, 128, 67, 79, 77, 66, 128, 67, 79, 76, 85, 77, 78, 128, + 67, 79, 76, 79, 82, 128, 67, 79, 76, 76, 73, 83, 73, 79, 206, 67, 79, 76, + 76, 128, 67, 79, 76, 196, 67, 79, 70, 70, 73, 78, 128, 67, 79, 69, 78, + 71, 128, 67, 79, 69, 78, 199, 67, 79, 68, 65, 128, 67, 79, 67, 79, 78, + 85, 84, 128, 67, 79, 67, 75, 84, 65, 73, 204, 67, 79, 65, 84, 128, 67, + 79, 65, 83, 84, 69, 82, 128, 67, 79, 65, 128, 67, 77, 128, 67, 205, 67, + 76, 85, 83, 84, 69, 82, 45, 73, 78, 73, 84, 73, 65, 204, 67, 76, 85, 83, + 84, 69, 82, 45, 70, 73, 78, 65, 204, 67, 76, 85, 83, 84, 69, 210, 67, 76, + 85, 66, 83, 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, 69, 196, 67, 76, 85, + 66, 128, 67, 76, 85, 194, 67, 76, 79, 87, 206, 67, 76, 79, 86, 69, 82, + 128, 67, 76, 79, 85, 68, 128, 67, 76, 79, 85, 196, 67, 76, 79, 84, 72, + 69, 83, 128, 67, 76, 79, 84, 72, 128, 67, 76, 79, 83, 69, 84, 128, 67, + 76, 79, 83, 69, 78, 69, 83, 83, 128, 67, 76, 79, 83, 69, 68, 128, 67, 76, + 79, 83, 197, 67, 76, 79, 67, 75, 87, 73, 83, 197, 67, 76, 79, 67, 203, + 67, 76, 73, 86, 73, 83, 128, 67, 76, 73, 80, 66, 79, 65, 82, 68, 128, 67, + 76, 73, 78, 75, 73, 78, 199, 67, 76, 73, 78, 71, 73, 78, 199, 67, 76, 73, + 77, 66, 73, 78, 71, 128, 67, 76, 73, 77, 65, 67, 85, 83, 128, 67, 76, 73, + 70, 70, 128, 67, 76, 73, 67, 75, 128, 67, 76, 69, 70, 45, 50, 128, 67, + 76, 69, 70, 45, 49, 128, 67, 76, 69, 70, 128, 67, 76, 69, 198, 67, 76, + 69, 65, 86, 69, 82, 128, 67, 76, 69, 65, 210, 67, 76, 65, 83, 83, 73, 67, + 65, 204, 67, 76, 65, 80, 80, 73, 78, 199, 67, 76, 65, 80, 80, 69, 210, + 67, 76, 65, 78, 128, 67, 76, 65, 206, 67, 76, 65, 77, 83, 72, 69, 76, + 204, 67, 76, 65, 73, 77, 128, 67, 76, 128, 67, 73, 88, 128, 67, 73, 86, + 73, 76, 73, 65, 78, 128, 67, 73, 84, 89, 83, 67, 65, 80, 69, 128, 67, 73, + 84, 89, 83, 67, 65, 80, 197, 67, 73, 84, 201, 67, 73, 84, 65, 84, 73, 79, + 206, 67, 73, 84, 128, 67, 73, 82, 67, 85, 211, 67, 73, 82, 67, 85, 77, + 70, 76, 69, 88, 128, 67, 73, 82, 67, 85, 77, 70, 76, 69, 216, 67, 73, 82, + 67, 85, 76, 65, 84, 73, 79, 206, 67, 73, 82, 67, 76, 73, 78, 71, 128, 67, + 73, 82, 67, 76, 73, 78, 199, 67, 73, 82, 67, 76, 69, 83, 128, 67, 73, 82, + 67, 76, 69, 211, 67, 73, 82, 67, 76, 69, 68, 128, 67, 73, 80, 128, 67, + 73, 78, 78, 65, 66, 65, 82, 128, 67, 73, 78, 69, 77, 65, 128, 67, 73, + 206, 67, 73, 205, 67, 73, 73, 128, 67, 73, 69, 88, 128, 67, 73, 69, 85, + 67, 45, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, 67, + 45, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, 67, 45, 73, 69, 85, 78, 71, + 128, 67, 73, 69, 85, 195, 67, 73, 69, 84, 128, 67, 73, 69, 80, 128, 67, + 73, 69, 128, 67, 72, 89, 88, 128, 67, 72, 89, 84, 128, 67, 72, 89, 82, + 88, 128, 67, 72, 89, 82, 128, 67, 72, 89, 80, 128, 67, 72, 87, 86, 128, + 67, 72, 85, 88, 128, 67, 72, 85, 82, 88, 128, 67, 72, 85, 82, 67, 72, + 128, 67, 72, 85, 82, 128, 67, 72, 85, 80, 128, 67, 72, 85, 79, 88, 128, + 67, 72, 85, 79, 84, 128, 67, 72, 85, 79, 80, 128, 67, 72, 85, 79, 128, + 67, 72, 85, 76, 65, 128, 67, 72, 85, 128, 67, 72, 82, 89, 83, 65, 78, 84, + 72, 69, 77, 85, 77, 128, 67, 72, 82, 79, 78, 79, 85, 128, 67, 72, 82, 79, + 78, 79, 78, 128, 67, 72, 82, 79, 77, 193, 67, 72, 82, 79, 193, 67, 72, + 82, 73, 86, 73, 128, 67, 72, 82, 73, 83, 84, 77, 65, 83, 128, 67, 72, 82, + 73, 83, 84, 77, 65, 211, 67, 72, 79, 89, 128, 67, 72, 79, 88, 128, 67, + 72, 79, 84, 128, 67, 72, 79, 82, 69, 86, 77, 193, 67, 72, 79, 80, 83, 84, + 73, 67, 75, 83, 128, 67, 72, 79, 80, 128, 67, 72, 79, 75, 69, 128, 67, + 72, 79, 69, 128, 67, 72, 79, 67, 79, 76, 65, 84, 197, 67, 72, 79, 65, + 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, + 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, + 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, 83, 128, 67, 72, 73, + 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, + 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, 79, 78, 128, 67, 72, + 73, 82, 69, 84, 128, 67, 72, 73, 80, 77, 85, 78, 75, 128, 67, 72, 73, 78, + 79, 79, 203, 67, 72, 73, 78, 71, 128, 67, 72, 73, 78, 69, 83, 197, 67, + 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, 73, 76, 76, 213, 67, + 72, 73, 76, 68, 82, 69, 206, 67, 72, 73, 76, 68, 128, 67, 72, 73, 76, + 128, 67, 72, 73, 75, 201, 67, 72, 73, 69, 85, 67, 72, 45, 75, 72, 73, 69, + 85, 75, 72, 128, 67, 72, 73, 69, 85, 67, 72, 45, 72, 73, 69, 85, 72, 128, + 67, 72, 73, 69, 85, 67, 200, 67, 72, 73, 67, 75, 69, 78, 128, 67, 72, 73, + 67, 75, 128, 67, 72, 73, 128, 67, 72, 201, 67, 72, 72, 65, 128, 67, 72, + 69, 88, 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, + 84, 69, 82, 128, 67, 72, 65, 82, 128, 67, 72, 65, 80, 84, 69, 82, 128, + 67, 72, 65, 80, 128, 67, 72, 65, 78, 71, 128, 67, 72, 65, 78, 128, 67, + 72, 65, 77, 75, 79, 128, 67, 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, + 77, 73, 76, 73, 128, 67, 72, 65, 205, 67, 72, 65, 75, 77, 193, 67, 72, + 65, 73, 78, 83, 128, 67, 72, 65, 68, 65, 128, 67, 72, 65, 196, 67, 72, + 65, 65, 128, 67, 71, 74, 128, 67, 69, 88, 128, 67, 69, 86, 73, 84, 85, + 128, 67, 69, 82, 69, 83, 128, 67, 69, 82, 69, 77, 79, 78, 89, 128, 67, + 69, 82, 69, 75, 128, 67, 69, 82, 45, 87, 65, 128, 67, 69, 80, 128, 67, + 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, + 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, + 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, + 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 67, 73, 69, + 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 67, 72, 73, 69, + 85, 67, 72, 128, 67, 69, 78, 84, 85, 82, 73, 65, 204, 67, 69, 78, 84, 82, + 69, 76, 73, 78, 197, 67, 69, 78, 84, 82, 69, 68, 128, 67, 69, 78, 84, 82, + 69, 196, 67, 69, 78, 84, 82, 69, 128, 67, 69, 78, 84, 82, 197, 67, 69, + 78, 84, 82, 65, 76, 73, 90, 65, 84, 73, 79, 206, 67, 69, 78, 128, 67, 69, + 76, 84, 73, 195, 67, 69, 76, 83, 73, 85, 83, 128, 67, 69, 76, 69, 66, 82, + 65, 84, 73, 79, 78, 128, 67, 69, 73, 82, 84, 128, 67, 69, 73, 76, 73, 78, + 71, 128, 67, 69, 73, 76, 73, 78, 199, 67, 69, 69, 86, 128, 67, 69, 69, + 66, 128, 67, 69, 69, 128, 67, 69, 68, 73, 76, 76, 65, 128, 67, 69, 68, + 73, 76, 76, 193, 67, 69, 68, 201, 67, 69, 67, 69, 75, 128, 67, 69, 67, + 65, 75, 128, 67, 69, 67, 65, 203, 67, 69, 65, 76, 67, 128, 67, 67, 85, + 128, 67, 67, 79, 128, 67, 67, 73, 128, 67, 67, 72, 85, 128, 67, 67, 72, + 79, 128, 67, 67, 72, 73, 128, 67, 67, 72, 72, 85, 128, 67, 67, 72, 72, + 79, 128, 67, 67, 72, 72, 73, 128, 67, 67, 72, 72, 69, 69, 128, 67, 67, + 72, 72, 69, 128, 67, 67, 72, 72, 65, 65, 128, 67, 67, 72, 72, 65, 128, + 67, 67, 72, 69, 69, 128, 67, 67, 72, 69, 128, 67, 67, 72, 65, 65, 128, + 67, 67, 72, 65, 128, 67, 67, 72, 128, 67, 67, 69, 69, 128, 67, 67, 69, + 128, 67, 67, 65, 65, 128, 67, 67, 65, 128, 67, 65, 89, 78, 128, 67, 65, + 89, 65, 78, 78, 65, 128, 67, 65, 88, 128, 67, 65, 86, 69, 128, 67, 65, + 85, 84, 73, 79, 206, 67, 65, 85, 76, 68, 82, 79, 78, 128, 67, 65, 85, 68, + 65, 128, 67, 65, 85, 67, 65, 83, 73, 65, 206, 67, 65, 85, 128, 67, 65, + 84, 65, 87, 65, 128, 67, 65, 84, 128, 67, 65, 212, 67, 65, 83, 84, 76, + 69, 128, 67, 65, 83, 75, 69, 212, 67, 65, 82, 89, 83, 84, 73, 65, 206, + 67, 65, 82, 84, 87, 72, 69, 69, 76, 128, 67, 65, 82, 84, 82, 73, 68, 71, + 69, 128, 67, 65, 82, 84, 128, 67, 65, 82, 211, 67, 65, 82, 82, 79, 84, + 128, 67, 65, 82, 82, 73, 65, 71, 197, 67, 65, 82, 80, 69, 78, 84, 82, + 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, 69, 204, 67, 65, 82, 79, + 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, 203, 67, 65, 82, 73, 65, + 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, 212, 67, 65, 82, 197, 67, + 65, 82, 68, 83, 128, 67, 65, 82, 68, 128, 67, 65, 82, 196, 67, 65, 82, + 128, 67, 65, 210, 67, 65, 80, 85, 212, 67, 65, 80, 84, 73, 86, 69, 128, + 67, 65, 80, 82, 73, 67, 79, 82, 78, 128, 67, 65, 80, 80, 69, 196, 67, 65, + 80, 79, 128, 67, 65, 80, 73, 84, 85, 76, 85, 77, 128, 67, 65, 80, 73, 84, + 65, 76, 128, 67, 65, 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, + 79, 69, 128, 67, 65, 78, 78, 79, 78, 128, 67, 65, 78, 78, 69, 196, 67, + 65, 78, 199, 67, 65, 78, 69, 128, 67, 65, 78, 68, 89, 128, 67, 65, 78, + 68, 82, 65, 66, 73, 78, 68, 85, 128, 67, 65, 78, 68, 82, 65, 66, 73, 78, + 68, 213, 67, 65, 78, 68, 82, 65, 128, 67, 65, 78, 68, 82, 193, 67, 65, + 78, 68, 76, 69, 128, 67, 65, 78, 67, 69, 82, 128, 67, 65, 78, 67, 69, 76, + 76, 65, 84, 73, 79, 206, 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, 67, 69, + 204, 67, 65, 78, 128, 67, 65, 77, 80, 73, 78, 71, 128, 67, 65, 77, 78, + 85, 195, 67, 65, 77, 69, 82, 65, 128, 67, 65, 77, 69, 82, 193, 67, 65, + 77, 69, 76, 128, 67, 65, 76, 89, 65, 128, 67, 65, 76, 89, 193, 67, 65, + 76, 88, 128, 67, 65, 76, 76, 128, 67, 65, 76, 204, 67, 65, 76, 69, 78, + 68, 65, 82, 128, 67, 65, 76, 69, 78, 68, 65, 210, 67, 65, 76, 67, 85, 76, + 65, 84, 79, 82, 128, 67, 65, 76, 67, 128, 67, 65, 75, 82, 65, 128, 67, + 65, 75, 197, 67, 65, 73, 128, 67, 65, 72, 128, 67, 65, 69, 83, 85, 82, + 65, 128, 67, 65, 68, 85, 67, 69, 85, 83, 128, 67, 65, 68, 193, 67, 65, + 67, 84, 85, 83, 128, 67, 65, 66, 76, 69, 87, 65, 89, 128, 67, 65, 66, 73, + 78, 69, 84, 128, 67, 65, 66, 66, 65, 71, 69, 45, 84, 82, 69, 69, 128, 67, + 65, 65, 78, 71, 128, 67, 65, 65, 73, 128, 67, 193, 67, 48, 50, 52, 128, + 67, 48, 50, 51, 128, 67, 48, 50, 50, 128, 67, 48, 50, 49, 128, 67, 48, + 50, 48, 128, 67, 48, 49, 57, 128, 67, 48, 49, 56, 128, 67, 48, 49, 55, + 128, 67, 48, 49, 54, 128, 67, 48, 49, 53, 128, 67, 48, 49, 52, 128, 67, + 48, 49, 51, 128, 67, 48, 49, 50, 128, 67, 48, 49, 49, 128, 67, 48, 49, + 48, 65, 128, 67, 48, 49, 48, 128, 67, 48, 48, 57, 128, 67, 48, 48, 56, + 128, 67, 48, 48, 55, 128, 67, 48, 48, 54, 128, 67, 48, 48, 53, 128, 67, + 48, 48, 52, 128, 67, 48, 48, 51, 128, 67, 48, 48, 50, 67, 128, 67, 48, + 48, 50, 66, 128, 67, 48, 48, 50, 65, 128, 67, 48, 48, 50, 128, 67, 48, + 48, 49, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 67, 45, 51, + 57, 128, 67, 45, 49, 56, 128, 66, 90, 85, 78, 199, 66, 90, 72, 201, 66, + 89, 84, 197, 66, 89, 69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, 85, 75, + 82, 65, 73, 78, 73, 65, 206, 66, 88, 71, 128, 66, 87, 73, 128, 66, 87, + 69, 69, 128, 66, 87, 69, 128, 66, 87, 65, 128, 66, 85, 85, 77, 73, 83, + 72, 128, 66, 85, 84, 84, 79, 78, 128, 66, 85, 84, 84, 79, 206, 66, 85, + 84, 84, 69, 82, 70, 76, 89, 128, 66, 85, 84, 84, 69, 82, 128, 66, 85, + 212, 66, 85, 83, 84, 211, 66, 85, 83, 212, 66, 85, 83, 83, 89, 69, 82, + 85, 128, 66, 85, 83, 73, 78, 69, 83, 211, 66, 85, 211, 66, 85, 82, 213, + 66, 85, 82, 82, 73, 84, 79, 128, 66, 85, 82, 50, 128, 66, 85, 210, 66, + 85, 79, 88, 128, 66, 85, 79, 80, 128, 66, 85, 78, 78, 217, 66, 85, 78, + 71, 128, 66, 85, 77, 80, 217, 66, 85, 76, 85, 71, 128, 66, 85, 76, 85, + 199, 66, 85, 76, 76, 83, 69, 89, 69, 128, 66, 85, 76, 76, 211, 66, 85, + 76, 76, 72, 79, 82, 78, 128, 66, 85, 76, 76, 72, 79, 82, 206, 66, 85, 76, + 76, 69, 84, 128, 66, 85, 76, 76, 69, 212, 66, 85, 76, 76, 128, 66, 85, + 76, 66, 128, 66, 85, 75, 89, 128, 66, 85, 73, 76, 68, 73, 78, 71, 83, + 128, 66, 85, 73, 76, 68, 73, 78, 71, 128, 66, 85, 73, 76, 68, 73, 78, + 199, 66, 85, 72, 73, 196, 66, 85, 71, 73, 78, 69, 83, 197, 66, 85, 71, + 128, 66, 85, 70, 70, 65, 76, 79, 128, 66, 85, 68, 128, 66, 85, 67, 75, + 76, 69, 128, 66, 85, 66, 66, 76, 69, 83, 128, 66, 85, 66, 66, 76, 69, + 128, 66, 83, 84, 65, 82, 128, 66, 83, 75, 85, 210, 66, 83, 75, 65, 173, + 66, 83, 68, 85, 211, 66, 82, 85, 83, 200, 66, 82, 79, 87, 206, 66, 82, + 79, 79, 77, 128, 66, 82, 79, 78, 90, 69, 128, 66, 82, 79, 75, 69, 206, + 66, 82, 79, 67, 67, 79, 76, 73, 128, 66, 82, 79, 65, 196, 66, 82, 73, 83, + 84, 76, 69, 128, 66, 82, 73, 71, 72, 84, 78, 69, 83, 211, 66, 82, 73, 69, + 70, 83, 128, 66, 82, 73, 69, 70, 67, 65, 83, 69, 128, 66, 82, 73, 68, 71, + 197, 66, 82, 73, 68, 197, 66, 82, 73, 67, 75, 128, 66, 82, 73, 128, 66, + 82, 69, 86, 73, 83, 128, 66, 82, 69, 86, 69, 45, 77, 65, 67, 82, 79, 78, + 128, 66, 82, 69, 86, 197, 66, 82, 69, 65, 84, 200, 66, 82, 69, 65, 83, + 84, 45, 70, 69, 69, 68, 73, 78, 71, 128, 66, 82, 69, 65, 75, 84, 72, 82, + 79, 85, 71, 72, 128, 66, 82, 68, 193, 66, 82, 65, 78, 67, 72, 73, 78, + 199, 66, 82, 65, 78, 67, 72, 69, 83, 128, 66, 82, 65, 78, 67, 72, 128, + 66, 82, 65, 78, 67, 200, 66, 82, 65, 75, 67, 69, 84, 128, 66, 82, 65, 73, + 78, 128, 66, 82, 65, 67, 75, 69, 84, 69, 196, 66, 82, 65, 67, 75, 69, + 212, 66, 82, 65, 67, 69, 128, 66, 81, 128, 66, 80, 72, 128, 66, 79, 89, + 211, 66, 79, 89, 128, 66, 79, 88, 73, 78, 199, 66, 79, 87, 84, 73, 69, + 128, 66, 79, 87, 84, 73, 197, 66, 79, 87, 76, 73, 78, 71, 128, 66, 79, + 87, 76, 128, 66, 79, 87, 204, 66, 79, 87, 73, 78, 199, 66, 79, 215, 66, + 79, 85, 81, 85, 69, 84, 128, 66, 79, 85, 81, 85, 69, 212, 66, 79, 85, 78, + 68, 65, 82, 217, 66, 79, 84, 84, 79, 77, 45, 83, 72, 65, 68, 69, 196, 66, + 79, 84, 84, 79, 77, 45, 76, 73, 71, 72, 84, 69, 196, 66, 79, 84, 84, 79, + 77, 128, 66, 79, 84, 84, 79, 205, 66, 79, 84, 84, 76, 69, 128, 66, 79, + 84, 84, 76, 197, 66, 79, 84, 200, 66, 79, 82, 85, 84, 79, 128, 66, 79, + 82, 65, 88, 45, 51, 128, 66, 79, 82, 65, 88, 45, 50, 128, 66, 79, 82, 65, + 88, 128, 66, 79, 80, 79, 77, 79, 70, 207, 66, 79, 79, 84, 83, 128, 66, + 79, 79, 84, 128, 66, 79, 79, 77, 69, 82, 65, 78, 71, 128, 66, 79, 79, 75, + 83, 128, 66, 79, 79, 75, 77, 65, 82, 75, 128, 66, 79, 79, 75, 77, 65, 82, + 203, 66, 79, 78, 69, 128, 66, 79, 77, 66, 128, 66, 79, 77, 128, 66, 79, + 76, 84, 128, 66, 79, 76, 212, 66, 79, 72, 65, 73, 82, 73, 195, 66, 79, + 68, 89, 128, 66, 79, 68, 217, 66, 79, 65, 82, 128, 66, 79, 65, 128, 66, + 76, 85, 69, 128, 66, 76, 85, 197, 66, 76, 79, 87, 73, 78, 199, 66, 76, + 79, 87, 70, 73, 83, 72, 128, 66, 76, 79, 215, 66, 76, 79, 83, 83, 79, 77, + 128, 66, 76, 79, 79, 68, 128, 66, 76, 79, 78, 196, 66, 76, 79, 67, 75, + 128, 66, 76, 73, 78, 203, 66, 76, 65, 78, 75, 128, 66, 76, 65, 78, 203, + 66, 76, 65, 68, 197, 66, 76, 65, 67, 75, 76, 69, 84, 84, 69, 210, 66, 76, + 65, 67, 75, 70, 79, 79, 212, 66, 76, 65, 67, 75, 45, 76, 69, 84, 84, 69, + 210, 66, 76, 65, 67, 75, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 66, 76, + 65, 67, 75, 128, 66, 75, 65, 173, 66, 73, 84, 84, 69, 82, 128, 66, 73, + 84, 73, 78, 199, 66, 73, 84, 197, 66, 73, 84, 67, 79, 73, 206, 66, 73, + 83, 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, 65, 200, 66, 73, 83, 72, + 79, 208, 66, 73, 83, 69, 67, 84, 73, 78, 199, 66, 73, 83, 65, 72, 128, + 66, 73, 82, 85, 128, 66, 73, 82, 84, 72, 68, 65, 217, 66, 73, 82, 71, 65, + 128, 66, 73, 82, 71, 193, 66, 73, 82, 68, 128, 66, 73, 79, 72, 65, 90, + 65, 82, 196, 66, 73, 78, 79, 86, 73, 76, 69, 128, 66, 73, 78, 79, 67, 85, + 76, 65, 210, 66, 73, 78, 68, 73, 78, 199, 66, 73, 78, 68, 73, 128, 66, + 73, 78, 65, 82, 217, 66, 73, 76, 76, 73, 79, 78, 83, 128, 66, 73, 76, 76, + 73, 65, 82, 68, 83, 128, 66, 73, 76, 76, 69, 196, 66, 73, 76, 65, 66, 73, + 65, 204, 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, 128, 66, 73, 199, 66, + 73, 69, 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, 66, 73, 68, 65, 75, 85, + 79, 206, 66, 73, 67, 89, 67, 76, 73, 83, 84, 128, 66, 73, 67, 89, 67, 76, + 69, 83, 128, 66, 73, 67, 89, 67, 76, 69, 128, 66, 73, 67, 69, 80, 83, + 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 197, 66, 73, 66, 128, 66, 201, + 66, 72, 85, 128, 66, 72, 79, 79, 128, 66, 72, 79, 128, 66, 72, 73, 128, + 66, 72, 69, 84, 72, 128, 66, 72, 69, 69, 128, 66, 72, 69, 128, 66, 72, + 65, 84, 84, 73, 80, 82, 79, 76, 213, 66, 72, 65, 77, 128, 66, 72, 65, 73, + 75, 83, 85, 75, 201, 66, 72, 65, 65, 128, 66, 72, 65, 128, 66, 69, 89, + 89, 65, 76, 128, 66, 69, 88, 128, 66, 69, 86, 69, 82, 65, 71, 69, 128, + 66, 69, 86, 69, 82, 65, 71, 197, 66, 69, 84, 87, 69, 69, 78, 128, 66, 69, + 84, 87, 69, 69, 206, 66, 69, 84, 72, 128, 66, 69, 84, 65, 128, 66, 69, + 84, 193, 66, 69, 212, 66, 69, 83, 73, 68, 197, 66, 69, 82, 75, 65, 78, + 65, 206, 66, 69, 82, 66, 69, 210, 66, 69, 80, 128, 66, 69, 79, 82, 195, + 66, 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 84, 128, + 66, 69, 78, 212, 66, 69, 78, 71, 65, 76, 201, 66, 69, 78, 68, 69, 128, + 66, 69, 78, 68, 128, 66, 69, 78, 196, 66, 69, 206, 66, 69, 76, 84, 128, + 66, 69, 76, 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 72, 79, 208, 66, + 69, 76, 76, 128, 66, 69, 76, 204, 66, 69, 76, 71, 84, 72, 79, 210, 66, + 69, 73, 84, 72, 128, 66, 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, 128, + 66, 69, 72, 69, 200, 66, 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, 78, + 78, 73, 78, 71, 128, 66, 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, 73, + 206, 66, 69, 70, 79, 82, 197, 66, 69, 69, 84, 76, 69, 128, 66, 69, 69, + 84, 65, 128, 66, 69, 69, 210, 66, 69, 69, 72, 73, 86, 69, 128, 66, 69, + 69, 72, 128, 66, 69, 69, 200, 66, 69, 67, 65, 85, 83, 69, 128, 66, 69, + 65, 86, 69, 210, 66, 69, 65, 84, 73, 78, 199, 66, 69, 65, 84, 128, 66, + 69, 65, 82, 68, 69, 196, 66, 69, 65, 82, 128, 66, 69, 65, 210, 66, 69, + 65, 78, 128, 66, 69, 65, 77, 69, 196, 66, 69, 65, 68, 83, 128, 66, 69, + 65, 67, 200, 66, 67, 65, 68, 128, 66, 67, 65, 196, 66, 66, 89, 88, 128, + 66, 66, 89, 84, 128, 66, 66, 89, 80, 128, 66, 66, 89, 128, 66, 66, 85, + 88, 128, 66, 66, 85, 84, 128, 66, 66, 85, 82, 88, 128, 66, 66, 85, 82, + 128, 66, 66, 85, 80, 128, 66, 66, 85, 79, 88, 128, 66, 66, 85, 79, 80, + 128, 66, 66, 85, 79, 128, 66, 66, 85, 128, 66, 66, 79, 88, 128, 66, 66, + 79, 84, 128, 66, 66, 79, 80, 128, 66, 66, 79, 128, 66, 66, 73, 88, 128, + 66, 66, 73, 80, 128, 66, 66, 73, 69, 88, 128, 66, 66, 73, 69, 84, 128, + 66, 66, 73, 69, 80, 128, 66, 66, 73, 69, 128, 66, 66, 73, 128, 66, 66, + 69, 88, 128, 66, 66, 69, 80, 128, 66, 66, 69, 69, 128, 66, 66, 69, 128, + 66, 66, 65, 88, 128, 66, 66, 65, 84, 128, 66, 66, 65, 80, 128, 66, 66, + 65, 65, 128, 66, 66, 65, 128, 66, 65, 89, 65, 78, 78, 65, 128, 66, 65, + 85, 128, 66, 65, 84, 84, 69, 82, 89, 128, 66, 65, 84, 72, 84, 85, 66, + 128, 66, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 66, 65, 84, 72, 128, + 66, 65, 84, 200, 66, 65, 84, 65, 203, 66, 65, 83, 83, 65, 128, 66, 65, + 83, 83, 193, 66, 65, 83, 75, 69, 84, 66, 65, 76, 204, 66, 65, 83, 72, 75, + 73, 210, 66, 65, 83, 72, 128, 66, 65, 83, 69, 76, 73, 78, 197, 66, 65, + 83, 69, 66, 65, 76, 76, 128, 66, 65, 83, 69, 128, 66, 65, 83, 197, 66, + 65, 82, 83, 128, 66, 65, 82, 211, 66, 65, 82, 82, 73, 69, 82, 128, 66, + 65, 82, 82, 69, 75, 72, 128, 66, 65, 82, 82, 69, 69, 128, 66, 65, 82, 82, + 69, 197, 66, 65, 82, 76, 73, 78, 69, 128, 66, 65, 82, 76, 69, 89, 128, + 66, 65, 82, 73, 89, 79, 79, 83, 65, 78, 128, 66, 65, 82, 66, 69, 210, 66, + 65, 82, 65, 50, 128, 66, 65, 210, 66, 65, 78, 84, 79, 67, 128, 66, 65, + 78, 75, 78, 79, 84, 197, 66, 65, 78, 75, 128, 66, 65, 78, 203, 66, 65, + 78, 74, 79, 128, 66, 65, 78, 68, 128, 66, 65, 78, 65, 78, 65, 128, 66, + 65, 78, 50, 128, 66, 65, 78, 178, 66, 65, 77, 66, 79, 79, 83, 128, 66, + 65, 77, 66, 79, 79, 128, 66, 65, 76, 85, 68, 65, 128, 66, 65, 76, 76, 80, + 79, 73, 78, 212, 66, 65, 76, 76, 79, 84, 128, 66, 65, 76, 76, 79, 212, + 66, 65, 76, 76, 79, 79, 78, 45, 83, 80, 79, 75, 69, 196, 66, 65, 76, 76, + 79, 79, 78, 128, 66, 65, 76, 76, 69, 212, 66, 65, 76, 68, 128, 66, 65, + 76, 65, 71, 128, 66, 65, 76, 128, 66, 65, 204, 66, 65, 73, 82, 75, 65, + 78, 128, 66, 65, 73, 77, 65, 73, 128, 66, 65, 72, 84, 128, 66, 65, 72, + 73, 82, 71, 79, 77, 85, 75, 72, 65, 128, 66, 65, 72, 65, 82, 50, 128, 66, + 65, 72, 65, 82, 178, 66, 65, 72, 128, 66, 65, 71, 85, 69, 84, 84, 197, + 66, 65, 71, 83, 128, 66, 65, 71, 71, 65, 71, 197, 66, 65, 71, 69, 76, + 128, 66, 65, 71, 65, 128, 66, 65, 71, 51, 128, 66, 65, 199, 66, 65, 68, + 77, 73, 78, 84, 79, 206, 66, 65, 68, 71, 69, 82, 128, 66, 65, 68, 71, 69, + 128, 66, 65, 68, 128, 66, 65, 196, 66, 65, 67, 84, 82, 73, 65, 206, 66, + 65, 67, 79, 78, 128, 66, 65, 67, 75, 87, 65, 82, 68, 128, 66, 65, 67, 75, + 83, 80, 65, 67, 69, 128, 66, 65, 67, 75, 83, 76, 65, 83, 72, 128, 66, 65, + 67, 75, 83, 76, 65, 83, 200, 66, 65, 67, 75, 83, 76, 65, 78, 84, 69, 196, + 66, 65, 67, 75, 72, 65, 78, 196, 66, 65, 67, 75, 45, 84, 73, 76, 84, 69, + 196, 66, 65, 67, 75, 128, 66, 65, 67, 203, 66, 65, 66, 89, 128, 66, 65, + 66, 217, 66, 65, 65, 82, 69, 82, 85, 128, 66, 65, 45, 50, 128, 66, 51, + 48, 53, 128, 66, 50, 53, 180, 66, 50, 52, 183, 66, 50, 52, 179, 66, 50, + 52, 178, 66, 50, 52, 177, 66, 50, 52, 176, 66, 50, 51, 179, 66, 50, 51, + 177, 66, 50, 51, 176, 66, 50, 50, 181, 66, 50, 50, 176, 66, 49, 57, 177, + 66, 49, 55, 182, 66, 49, 55, 179, 66, 49, 54, 57, 128, 66, 49, 54, 56, + 128, 66, 49, 54, 55, 128, 66, 49, 54, 54, 128, 66, 49, 54, 53, 128, 66, + 49, 54, 52, 128, 66, 49, 54, 179, 66, 49, 54, 178, 66, 49, 54, 49, 128, + 66, 49, 54, 48, 128, 66, 49, 53, 185, 66, 49, 53, 56, 128, 66, 49, 53, + 55, 128, 66, 49, 53, 182, 66, 49, 53, 53, 128, 66, 49, 53, 52, 128, 66, + 49, 53, 51, 128, 66, 49, 53, 50, 128, 66, 49, 53, 177, 66, 49, 53, 48, + 128, 66, 49, 52, 54, 128, 66, 49, 52, 181, 66, 49, 52, 50, 128, 66, 49, + 52, 177, 66, 49, 52, 176, 66, 49, 51, 181, 66, 49, 51, 179, 66, 49, 51, + 50, 128, 66, 49, 51, 177, 66, 49, 51, 176, 66, 49, 50, 184, 66, 49, 50, + 183, 66, 49, 50, 181, 66, 49, 50, 179, 66, 49, 50, 178, 66, 49, 50, 177, + 66, 49, 50, 176, 66, 49, 48, 57, 205, 66, 49, 48, 57, 198, 66, 49, 48, + 56, 205, 66, 49, 48, 56, 198, 66, 49, 48, 55, 205, 66, 49, 48, 55, 198, + 66, 49, 48, 54, 205, 66, 49, 48, 54, 198, 66, 49, 48, 53, 205, 66, 49, + 48, 53, 198, 66, 49, 48, 181, 66, 49, 48, 180, 66, 49, 48, 178, 66, 49, + 48, 176, 66, 48, 57, 177, 66, 48, 57, 176, 66, 48, 56, 57, 128, 66, 48, + 56, 183, 66, 48, 56, 54, 128, 66, 48, 56, 181, 66, 48, 56, 51, 128, 66, + 48, 56, 50, 128, 66, 48, 56, 177, 66, 48, 56, 176, 66, 48, 55, 57, 128, + 66, 48, 55, 184, 66, 48, 55, 183, 66, 48, 55, 182, 66, 48, 55, 181, 66, + 48, 55, 180, 66, 48, 55, 179, 66, 48, 55, 178, 66, 48, 55, 177, 66, 48, + 55, 176, 66, 48, 54, 185, 66, 48, 54, 184, 66, 48, 54, 183, 66, 48, 54, + 182, 66, 48, 54, 181, 66, 48, 54, 52, 128, 66, 48, 54, 51, 128, 66, 48, + 54, 178, 66, 48, 54, 177, 66, 48, 54, 176, 66, 48, 53, 185, 66, 48, 53, + 184, 66, 48, 53, 183, 66, 48, 53, 54, 128, 66, 48, 53, 181, 66, 48, 53, + 180, 66, 48, 53, 179, 66, 48, 53, 178, 66, 48, 53, 177, 66, 48, 53, 176, + 66, 48, 52, 57, 128, 66, 48, 52, 184, 66, 48, 52, 55, 128, 66, 48, 52, + 182, 66, 48, 52, 181, 66, 48, 52, 180, 66, 48, 52, 179, 66, 48, 52, 178, + 66, 48, 52, 177, 66, 48, 52, 176, 66, 48, 51, 185, 66, 48, 51, 184, 66, + 48, 51, 183, 66, 48, 51, 182, 66, 48, 51, 52, 128, 66, 48, 51, 179, 66, + 48, 51, 178, 66, 48, 51, 177, 66, 48, 51, 176, 66, 48, 50, 185, 66, 48, + 50, 184, 66, 48, 50, 183, 66, 48, 50, 182, 66, 48, 50, 181, 66, 48, 50, + 180, 66, 48, 50, 179, 66, 48, 50, 50, 128, 66, 48, 50, 177, 66, 48, 50, + 176, 66, 48, 49, 57, 128, 66, 48, 49, 56, 128, 66, 48, 49, 183, 66, 48, + 49, 182, 66, 48, 49, 181, 66, 48, 49, 180, 66, 48, 49, 179, 66, 48, 49, + 178, 66, 48, 49, 177, 66, 48, 49, 176, 66, 48, 48, 57, 128, 66, 48, 48, + 185, 66, 48, 48, 56, 128, 66, 48, 48, 184, 66, 48, 48, 55, 128, 66, 48, + 48, 183, 66, 48, 48, 54, 128, 66, 48, 48, 182, 66, 48, 48, 53, 65, 128, + 66, 48, 48, 53, 128, 66, 48, 48, 181, 66, 48, 48, 52, 128, 66, 48, 48, + 180, 66, 48, 48, 51, 128, 66, 48, 48, 179, 66, 48, 48, 50, 128, 66, 48, + 48, 178, 66, 48, 48, 49, 128, 66, 48, 48, 177, 65, 90, 85, 128, 65, 89, + 66, 128, 65, 89, 65, 72, 128, 65, 88, 69, 128, 65, 87, 69, 128, 65, 87, + 65, 217, 65, 86, 79, 67, 65, 68, 79, 128, 65, 86, 69, 83, 84, 65, 206, + 65, 86, 69, 82, 65, 71, 197, 65, 86, 65, 75, 82, 65, 72, 65, 83, 65, 78, + 89, 65, 128, 65, 86, 65, 71, 82, 65, 72, 65, 128, 65, 85, 89, 65, 78, 78, + 65, 128, 65, 85, 84, 85, 77, 78, 128, 65, 85, 84, 79, 77, 79, 66, 73, 76, + 69, 128, 65, 85, 84, 79, 77, 65, 84, 69, 196, 65, 85, 84, 207, 65, 85, + 83, 84, 82, 65, 204, 65, 85, 82, 73, 80, 73, 71, 77, 69, 78, 84, 128, 65, + 85, 82, 65, 77, 65, 90, 68, 65, 65, 72, 65, 128, 65, 85, 82, 65, 77, 65, + 90, 68, 65, 65, 45, 50, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, 128, + 65, 85, 78, 78, 128, 65, 85, 71, 85, 83, 84, 128, 65, 85, 71, 77, 69, 78, + 84, 65, 84, 73, 79, 206, 65, 85, 69, 128, 65, 85, 66, 69, 82, 71, 73, 78, + 69, 128, 65, 84, 84, 73, 195, 65, 84, 84, 72, 65, 67, 65, 78, 128, 65, + 84, 84, 69, 78, 84, 73, 79, 78, 128, 65, 84, 84, 65, 203, 65, 84, 84, 65, + 67, 72, 69, 196, 65, 84, 79, 205, 65, 84, 78, 65, 200, 65, 84, 77, 65, + 65, 85, 128, 65, 84, 73, 89, 65, 128, 65, 84, 73, 85, 128, 65, 84, 73, + 75, 82, 65, 77, 65, 128, 65, 84, 72, 76, 69, 84, 73, 195, 65, 84, 72, 65, + 82, 86, 65, 86, 69, 68, 73, 195, 65, 84, 72, 65, 80, 65, 83, 67, 65, 206, + 65, 84, 72, 45, 84, 72, 65, 76, 65, 84, 72, 65, 128, 65, 83, 90, 128, 65, + 83, 89, 85, 82, 193, 65, 83, 89, 77, 80, 84, 79, 84, 73, 67, 65, 76, 76, + 217, 65, 83, 84, 82, 79, 78, 79, 77, 73, 67, 65, 204, 65, 83, 84, 82, 79, + 76, 79, 71, 73, 67, 65, 204, 65, 83, 84, 82, 65, 69, 65, 128, 65, 83, 84, + 79, 78, 73, 83, 72, 69, 196, 65, 83, 84, 69, 82, 73, 83, 77, 128, 65, 83, + 84, 69, 82, 73, 83, 75, 211, 65, 83, 84, 69, 82, 73, 83, 75, 128, 65, 83, + 84, 69, 82, 73, 83, 203, 65, 83, 84, 69, 82, 73, 83, 67, 85, 83, 128, 65, + 83, 83, 89, 82, 73, 65, 206, 65, 83, 83, 69, 82, 84, 73, 79, 78, 128, 65, + 83, 80, 73, 82, 65, 84, 73, 79, 78, 128, 65, 83, 80, 73, 82, 65, 84, 69, + 196, 65, 83, 80, 69, 82, 128, 65, 83, 73, 65, 45, 65, 85, 83, 84, 82, 65, + 76, 73, 65, 128, 65, 83, 72, 71, 65, 66, 128, 65, 83, 72, 69, 83, 128, + 65, 83, 72, 57, 128, 65, 83, 72, 51, 128, 65, 83, 72, 178, 65, 83, 67, + 69, 78, 84, 128, 65, 83, 67, 69, 78, 68, 73, 78, 199, 65, 83, 65, 76, 50, + 128, 65, 83, 45, 83, 65, 74, 68, 65, 128, 65, 82, 85, 72, 85, 65, 128, + 65, 82, 84, 211, 65, 82, 84, 73, 83, 212, 65, 82, 84, 73, 67, 85, 76, 65, + 84, 69, 196, 65, 82, 84, 65, 66, 197, 65, 82, 84, 65, 128, 65, 82, 83, + 69, 79, 83, 128, 65, 82, 83, 69, 79, 211, 65, 82, 83, 69, 78, 73, 67, + 128, 65, 82, 82, 79, 87, 83, 128, 65, 82, 82, 79, 87, 211, 65, 82, 82, + 79, 87, 72, 69, 65, 68, 83, 128, 65, 82, 82, 79, 87, 72, 69, 65, 68, 128, + 65, 82, 82, 79, 87, 72, 69, 65, 196, 65, 82, 82, 79, 87, 45, 84, 65, 73, + 76, 128, 65, 82, 82, 73, 86, 73, 78, 71, 128, 65, 82, 82, 73, 86, 69, + 128, 65, 82, 82, 65, 89, 128, 65, 82, 80, 69, 71, 71, 73, 65, 84, 207, + 65, 82, 79, 85, 83, 73, 78, 199, 65, 82, 79, 85, 82, 193, 65, 82, 79, 85, + 78, 68, 45, 80, 82, 79, 70, 73, 76, 69, 128, 65, 82, 79, 85, 78, 196, 65, + 82, 77, 89, 128, 65, 82, 77, 79, 85, 82, 128, 65, 82, 77, 69, 78, 73, 65, + 206, 65, 82, 77, 128, 65, 82, 205, 65, 82, 76, 65, 85, 199, 65, 82, 75, + 84, 73, 75, 207, 65, 82, 75, 65, 66, 128, 65, 82, 75, 65, 65, 78, 85, + 128, 65, 82, 73, 83, 84, 69, 82, 65, 128, 65, 82, 73, 83, 84, 69, 82, + 193, 65, 82, 73, 69, 83, 128, 65, 82, 71, 79, 84, 69, 82, 73, 128, 65, + 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78, 128, 65, 82, 71, 73, 128, + 65, 82, 69, 80, 65, 128, 65, 82, 69, 65, 128, 65, 82, 68, 72, 65, 86, 73, + 83, 65, 82, 71, 65, 128, 65, 82, 68, 72, 65, 67, 65, 78, 68, 82, 65, 128, + 65, 82, 67, 72, 65, 73, 79, 78, 128, 65, 82, 67, 72, 65, 73, 79, 206, 65, + 82, 67, 72, 65, 73, 195, 65, 82, 67, 200, 65, 82, 67, 128, 65, 82, 195, + 65, 82, 65, 77, 65, 73, 195, 65, 82, 65, 69, 65, 69, 128, 65, 82, 65, 69, + 65, 45, 85, 128, 65, 82, 65, 69, 65, 45, 73, 128, 65, 82, 65, 69, 65, 45, + 69, 79, 128, 65, 82, 65, 69, 65, 45, 69, 128, 65, 82, 65, 69, 65, 45, 65, + 128, 65, 82, 65, 68, 128, 65, 82, 65, 196, 65, 82, 65, 66, 73, 67, 45, + 73, 78, 68, 73, 195, 65, 82, 65, 66, 73, 65, 206, 65, 82, 45, 82, 85, 66, + 128, 65, 82, 45, 82, 65, 72, 77, 65, 206, 65, 82, 45, 82, 65, 72, 69, 69, + 77, 128, 65, 81, 85, 65, 82, 73, 85, 83, 128, 65, 81, 85, 65, 70, 79, 82, + 84, 73, 83, 128, 65, 81, 85, 193, 65, 80, 85, 206, 65, 80, 82, 73, 76, + 128, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 76, 217, 65, 80, 80, 82, + 79, 88, 73, 77, 65, 84, 69, 128, 65, 80, 80, 82, 79, 65, 67, 72, 69, 211, + 65, 80, 80, 82, 79, 65, 67, 72, 128, 65, 80, 80, 76, 73, 67, 65, 84, 73, + 79, 78, 128, 65, 80, 80, 76, 73, 67, 65, 84, 73, 79, 206, 65, 80, 79, 84, + 72, 69, 83, 128, 65, 80, 79, 84, 72, 69, 77, 65, 128, 65, 80, 79, 83, 84, + 82, 79, 80, 72, 69, 128, 65, 80, 79, 83, 84, 82, 79, 70, 79, 83, 128, 65, + 80, 79, 83, 84, 82, 79, 70, 79, 211, 65, 80, 79, 83, 84, 82, 79, 70, 79, + 201, 65, 80, 79, 76, 76, 79, 78, 128, 65, 80, 79, 68, 69, 88, 73, 65, + 128, 65, 80, 79, 68, 69, 82, 77, 193, 65, 80, 76, 79, 85, 78, 128, 65, + 80, 76, 201, 65, 80, 204, 65, 80, 73, 78, 128, 65, 80, 69, 83, 207, 65, + 80, 67, 128, 65, 80, 65, 82, 84, 128, 65, 80, 65, 65, 84, 79, 128, 65, + 79, 85, 128, 65, 79, 82, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, + 128, 65, 78, 85, 83, 86, 65, 82, 65, 128, 65, 78, 85, 83, 86, 65, 82, + 193, 65, 78, 85, 68, 65, 84, 84, 65, 128, 65, 78, 85, 68, 65, 84, 84, + 193, 65, 78, 84, 73, 82, 69, 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, + 78, 84, 73, 77, 79, 78, 89, 45, 50, 128, 65, 78, 84, 73, 77, 79, 78, 89, + 128, 65, 78, 84, 73, 77, 79, 78, 217, 65, 78, 84, 73, 77, 79, 78, 73, 65, + 84, 69, 128, 65, 78, 84, 73, 75, 69, 78, 79, 77, 65, 128, 65, 78, 84, 73, + 75, 69, 78, 79, 75, 89, 76, 73, 83, 77, 65, 128, 65, 78, 84, 73, 70, 79, + 78, 73, 65, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 45, + 82, 79, 84, 65, 84, 69, 196, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, + 83, 69, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 197, 65, 78, + 84, 69, 78, 78, 65, 128, 65, 78, 84, 69, 78, 78, 193, 65, 78, 84, 65, 82, + 71, 79, 77, 85, 75, 72, 65, 128, 65, 78, 83, 85, 218, 65, 78, 83, 72, 69, + 128, 65, 78, 80, 69, 65, 128, 65, 78, 207, 65, 78, 78, 85, 73, 84, 217, + 65, 78, 78, 79, 84, 65, 84, 73, 79, 206, 65, 78, 78, 65, 65, 85, 128, 65, + 78, 75, 72, 128, 65, 78, 74, 73, 128, 65, 78, 73, 77, 65, 76, 128, 65, + 78, 72, 85, 128, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78, 71, 85, 73, 83, + 72, 69, 196, 65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 82, 217, 65, + 78, 71, 76, 73, 67, 65, 78, 193, 65, 78, 71, 76, 69, 68, 128, 65, 78, 71, + 76, 69, 196, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 128, 65, 78, 71, 75, + 65, 128, 65, 78, 71, 69, 210, 65, 78, 71, 69, 76, 128, 65, 78, 71, 69, + 68, 128, 65, 78, 68, 65, 80, 128, 65, 78, 67, 79, 82, 65, 128, 65, 78, + 67, 72, 79, 82, 128, 65, 78, 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, + 65, 78, 65, 80, 128, 65, 78, 45, 78, 73, 83, 70, 128, 65, 77, 85, 76, 69, + 84, 128, 65, 77, 80, 83, 128, 65, 77, 80, 72, 79, 82, 65, 128, 65, 77, + 80, 69, 82, 83, 65, 78, 68, 128, 65, 77, 80, 69, 82, 83, 65, 78, 196, 65, + 77, 79, 85, 78, 212, 65, 77, 69, 82, 73, 67, 65, 83, 128, 65, 77, 69, 82, + 73, 67, 65, 206, 65, 77, 66, 85, 76, 65, 78, 67, 69, 128, 65, 77, 66, + 193, 65, 77, 66, 128, 65, 77, 65, 82, 128, 65, 77, 65, 210, 65, 77, 65, + 76, 71, 65, 77, 65, 84, 73, 79, 206, 65, 77, 65, 76, 71, 65, 77, 128, 65, + 76, 86, 69, 79, 76, 65, 210, 65, 76, 85, 77, 128, 65, 76, 84, 69, 82, 78, + 65, 84, 73, 86, 197, 65, 76, 84, 69, 82, 78, 65, 84, 73, 79, 206, 65, 76, + 84, 69, 82, 78, 65, 84, 73, 78, 71, 128, 65, 76, 84, 69, 82, 78, 65, 84, + 73, 78, 199, 65, 76, 84, 69, 82, 78, 65, 84, 69, 128, 65, 76, 84, 69, 82, + 78, 65, 84, 197, 65, 76, 84, 65, 128, 65, 76, 80, 72, 65, 128, 65, 76, + 80, 72, 193, 65, 76, 80, 65, 80, 82, 65, 78, 65, 128, 65, 76, 80, 65, 80, + 82, 65, 65, 78, 193, 65, 76, 80, 65, 128, 65, 76, 77, 79, 83, 212, 65, + 76, 76, 79, 128, 65, 76, 76, 73, 65, 78, 67, 69, 128, 65, 76, 76, 201, + 65, 76, 76, 65, 200, 65, 76, 75, 65, 76, 73, 45, 50, 128, 65, 76, 75, 65, + 76, 73, 128, 65, 76, 73, 71, 78, 69, 196, 65, 76, 73, 70, 85, 128, 65, + 76, 73, 70, 128, 65, 76, 73, 198, 65, 76, 73, 69, 78, 128, 65, 76, 73, + 69, 206, 65, 76, 71, 73, 218, 65, 76, 70, 65, 128, 65, 76, 69, 85, 212, + 65, 76, 69, 82, 84, 128, 65, 76, 69, 80, 72, 128, 65, 76, 69, 77, 66, 73, + 67, 128, 65, 76, 69, 70, 128, 65, 76, 66, 65, 78, 73, 65, 206, 65, 76, + 65, 89, 72, 69, 128, 65, 76, 65, 89, 72, 197, 65, 76, 65, 82, 205, 65, + 76, 65, 80, 72, 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 75, 84, + 73, 69, 83, 69, 76, 83, 75, 65, 66, 128, 65, 75, 83, 65, 128, 65, 75, 72, + 77, 73, 77, 73, 195, 65, 75, 66, 65, 210, 65, 75, 65, 82, 65, 128, 65, + 75, 65, 82, 193, 65, 73, 89, 65, 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, + 203, 65, 73, 86, 65, 128, 65, 73, 84, 79, 206, 65, 73, 82, 80, 76, 65, + 78, 69, 128, 65, 73, 82, 80, 76, 65, 78, 197, 65, 73, 78, 213, 65, 73, + 78, 78, 128, 65, 73, 76, 77, 128, 65, 73, 75, 65, 82, 65, 128, 65, 73, + 72, 86, 85, 83, 128, 65, 72, 83, 68, 65, 128, 65, 72, 83, 65, 128, 65, + 72, 79, 205, 65, 72, 65, 78, 199, 65, 72, 65, 71, 71, 65, 210, 65, 72, + 65, 68, 128, 65, 71, 85, 78, 71, 128, 65, 71, 79, 71, 201, 65, 71, 71, + 82, 65, 86, 65, 84, 73, 79, 78, 128, 65, 71, 71, 82, 65, 86, 65, 84, 69, + 196, 65, 71, 65, 73, 78, 83, 212, 65, 71, 65, 73, 78, 128, 65, 70, 84, + 69, 210, 65, 70, 83, 65, 65, 81, 128, 65, 70, 82, 73, 67, 65, 206, 65, + 70, 79, 82, 69, 77, 69, 78, 84, 73, 79, 78, 69, 68, 128, 65, 70, 71, 72, + 65, 78, 201, 65, 70, 70, 82, 73, 67, 65, 84, 73, 79, 206, 65, 70, 70, 73, + 216, 65, 69, 89, 65, 78, 78, 65, 128, 65, 69, 89, 128, 65, 69, 83, 67, + 85, 76, 65, 80, 73, 85, 83, 128, 65, 69, 83, 67, 128, 65, 69, 83, 128, + 65, 69, 82, 73, 65, 204, 65, 69, 82, 128, 65, 69, 76, 65, 45, 80, 73, 76, + 76, 65, 128, 65, 69, 76, 128, 65, 69, 75, 128, 65, 69, 71, 69, 65, 206, + 65, 69, 71, 128, 65, 69, 69, 89, 65, 78, 78, 65, 128, 65, 69, 69, 128, + 65, 69, 68, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 68, 128, 65, 69, 66, + 128, 65, 68, 86, 65, 78, 84, 65, 71, 69, 128, 65, 68, 86, 65, 78, 67, 69, + 128, 65, 68, 85, 76, 84, 128, 65, 68, 77, 73, 83, 83, 73, 79, 206, 65, + 68, 77, 69, 84, 79, 83, 128, 65, 68, 76, 65, 205, 65, 68, 72, 69, 83, 73, + 86, 197, 65, 68, 69, 71, 128, 65, 68, 69, 199, 65, 68, 68, 82, 69, 83, + 83, 69, 196, 65, 68, 68, 82, 69, 83, 211, 65, 68, 68, 65, 75, 128, 65, + 68, 65, 203, 65, 67, 85, 84, 69, 45, 77, 65, 67, 82, 79, 78, 128, 65, 67, + 85, 84, 69, 45, 71, 82, 65, 86, 69, 45, 65, 67, 85, 84, 69, 128, 65, 67, + 85, 84, 197, 65, 67, 84, 85, 65, 76, 76, 217, 65, 67, 84, 73, 86, 65, 84, + 197, 65, 67, 82, 79, 80, 72, 79, 78, 73, 195, 65, 67, 75, 78, 79, 87, 76, + 69, 68, 71, 69, 128, 65, 67, 67, 85, 77, 85, 76, 65, 84, 73, 79, 78, 128, + 65, 67, 67, 79, 85, 78, 212, 65, 67, 67, 79, 77, 77, 79, 68, 65, 84, 73, + 79, 78, 128, 65, 67, 67, 69, 80, 84, 128, 65, 67, 67, 69, 78, 84, 45, 83, + 84, 65, 67, 67, 65, 84, 79, 128, 65, 67, 67, 69, 78, 84, 128, 65, 67, 67, + 69, 78, 212, 65, 67, 65, 68, 69, 77, 217, 65, 66, 89, 83, 77, 65, 204, + 65, 66, 85, 78, 68, 65, 78, 67, 69, 128, 65, 66, 75, 72, 65, 83, 73, 65, + 206, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, 65, 66, 65, 70, 73, + 76, 73, 128, 65, 66, 65, 67, 85, 83, 128, 65, 66, 178, 65, 66, 49, 57, + 49, 128, 65, 66, 49, 56, 56, 128, 65, 66, 49, 56, 48, 128, 65, 66, 49, + 55, 49, 128, 65, 66, 49, 54, 52, 128, 65, 66, 49, 51, 49, 66, 128, 65, + 66, 49, 51, 49, 65, 128, 65, 66, 49, 50, 51, 128, 65, 66, 49, 50, 50, + 128, 65, 66, 49, 50, 48, 128, 65, 66, 49, 49, 56, 128, 65, 66, 48, 56, + 55, 128, 65, 66, 48, 56, 54, 128, 65, 66, 48, 56, 53, 128, 65, 66, 48, + 56, 50, 128, 65, 66, 48, 56, 49, 128, 65, 66, 48, 56, 48, 128, 65, 66, + 48, 55, 57, 128, 65, 66, 48, 55, 56, 128, 65, 66, 48, 55, 55, 128, 65, + 66, 48, 55, 54, 128, 65, 66, 48, 55, 52, 128, 65, 66, 48, 55, 51, 128, + 65, 66, 48, 55, 48, 128, 65, 66, 48, 54, 57, 128, 65, 66, 48, 54, 55, + 128, 65, 66, 48, 54, 54, 128, 65, 66, 48, 54, 53, 128, 65, 66, 48, 54, + 49, 128, 65, 66, 48, 54, 48, 128, 65, 66, 48, 53, 57, 128, 65, 66, 48, + 53, 56, 128, 65, 66, 48, 53, 55, 128, 65, 66, 48, 53, 54, 128, 65, 66, + 48, 53, 53, 128, 65, 66, 48, 53, 52, 128, 65, 66, 48, 53, 51, 128, 65, + 66, 48, 53, 49, 128, 65, 66, 48, 53, 48, 128, 65, 66, 48, 52, 57, 128, + 65, 66, 48, 52, 56, 128, 65, 66, 48, 52, 55, 128, 65, 66, 48, 52, 54, + 128, 65, 66, 48, 52, 53, 128, 65, 66, 48, 52, 52, 128, 65, 66, 48, 52, + 49, 128, 65, 66, 48, 52, 48, 128, 65, 66, 48, 51, 57, 128, 65, 66, 48, + 51, 56, 128, 65, 66, 48, 51, 55, 128, 65, 66, 48, 51, 52, 128, 65, 66, + 48, 51, 49, 128, 65, 66, 48, 51, 48, 128, 65, 66, 48, 50, 57, 128, 65, + 66, 48, 50, 56, 128, 65, 66, 48, 50, 55, 128, 65, 66, 48, 50, 54, 128, + 65, 66, 48, 50, 52, 128, 65, 66, 48, 50, 51, 77, 128, 65, 66, 48, 50, 51, + 128, 65, 66, 48, 50, 50, 77, 128, 65, 66, 48, 50, 50, 70, 128, 65, 66, + 48, 50, 50, 128, 65, 66, 48, 50, 49, 77, 128, 65, 66, 48, 50, 49, 70, + 128, 65, 66, 48, 50, 49, 128, 65, 66, 48, 50, 48, 128, 65, 66, 48, 49, + 55, 128, 65, 66, 48, 49, 54, 128, 65, 66, 48, 49, 51, 128, 65, 66, 48, + 49, 49, 128, 65, 66, 48, 49, 48, 128, 65, 66, 48, 48, 57, 128, 65, 66, + 48, 48, 56, 128, 65, 66, 48, 48, 55, 128, 65, 66, 48, 48, 54, 128, 65, + 66, 48, 48, 53, 128, 65, 66, 48, 48, 52, 128, 65, 66, 48, 48, 51, 128, + 65, 66, 48, 48, 50, 128, 65, 66, 48, 48, 49, 128, 65, 65, 90, 72, 65, 65, + 75, 75, 85, 128, 65, 65, 89, 73, 78, 128, 65, 65, 89, 65, 78, 78, 65, + 128, 65, 65, 89, 128, 65, 65, 87, 128, 65, 65, 79, 128, 65, 65, 74, 128, + 65, 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 65, 48, 51, 50, 128, 65, 65, + 48, 51, 49, 128, 65, 65, 48, 51, 48, 128, 65, 65, 48, 50, 57, 128, 65, + 65, 48, 50, 56, 128, 65, 65, 48, 50, 55, 128, 65, 65, 48, 50, 54, 128, + 65, 65, 48, 50, 53, 128, 65, 65, 48, 50, 52, 128, 65, 65, 48, 50, 51, + 128, 65, 65, 48, 50, 50, 128, 65, 65, 48, 50, 49, 128, 65, 65, 48, 50, + 48, 128, 65, 65, 48, 49, 57, 128, 65, 65, 48, 49, 56, 128, 65, 65, 48, + 49, 55, 128, 65, 65, 48, 49, 54, 128, 65, 65, 48, 49, 53, 128, 65, 65, + 48, 49, 52, 128, 65, 65, 48, 49, 51, 128, 65, 65, 48, 49, 50, 128, 65, + 65, 48, 49, 49, 128, 65, 65, 48, 49, 48, 128, 65, 65, 48, 48, 57, 128, + 65, 65, 48, 48, 56, 128, 65, 65, 48, 48, 55, 66, 128, 65, 65, 48, 48, 55, + 65, 128, 65, 65, 48, 48, 55, 128, 65, 65, 48, 48, 54, 128, 65, 65, 48, + 48, 53, 128, 65, 65, 48, 48, 52, 128, 65, 65, 48, 48, 51, 128, 65, 65, + 48, 48, 50, 128, 65, 65, 48, 48, 49, 128, 65, 56, 48, 55, 128, 65, 56, + 48, 54, 128, 65, 56, 48, 53, 128, 65, 56, 48, 52, 128, 65, 56, 48, 51, + 128, 65, 56, 48, 50, 128, 65, 56, 48, 49, 128, 65, 56, 48, 48, 128, 65, + 55, 51, 178, 65, 55, 50, 182, 65, 55, 49, 183, 65, 55, 49, 181, 65, 55, + 49, 180, 65, 55, 49, 179, 65, 55, 49, 178, 65, 55, 49, 177, 65, 55, 49, + 176, 65, 55, 48, 57, 45, 182, 65, 55, 48, 57, 45, 180, 65, 55, 48, 57, + 45, 179, 65, 55, 48, 57, 45, 178, 65, 55, 48, 185, 65, 55, 48, 184, 65, + 55, 48, 183, 65, 55, 48, 182, 65, 55, 48, 181, 65, 55, 48, 180, 65, 55, + 48, 179, 65, 55, 48, 178, 65, 55, 48, 177, 65, 54, 54, 52, 128, 65, 54, + 54, 51, 128, 65, 54, 54, 50, 128, 65, 54, 54, 49, 128, 65, 54, 54, 48, + 128, 65, 54, 53, 57, 128, 65, 54, 53, 56, 128, 65, 54, 53, 55, 128, 65, + 54, 53, 54, 128, 65, 54, 53, 53, 128, 65, 54, 53, 52, 128, 65, 54, 53, + 51, 128, 65, 54, 53, 50, 128, 65, 54, 53, 49, 128, 65, 54, 52, 57, 128, + 65, 54, 52, 56, 128, 65, 54, 52, 54, 128, 65, 54, 52, 53, 128, 65, 54, + 52, 52, 128, 65, 54, 52, 51, 128, 65, 54, 52, 50, 128, 65, 54, 52, 48, + 128, 65, 54, 51, 56, 128, 65, 54, 51, 55, 128, 65, 54, 51, 52, 128, 65, + 54, 50, 57, 128, 65, 54, 50, 56, 128, 65, 54, 50, 55, 128, 65, 54, 50, + 54, 128, 65, 54, 50, 52, 128, 65, 54, 50, 51, 128, 65, 54, 50, 50, 128, + 65, 54, 50, 49, 128, 65, 54, 50, 48, 128, 65, 54, 49, 57, 128, 65, 54, + 49, 56, 128, 65, 54, 49, 55, 128, 65, 54, 49, 54, 128, 65, 54, 49, 53, + 128, 65, 54, 49, 52, 128, 65, 54, 49, 51, 128, 65, 54, 49, 50, 128, 65, + 54, 49, 49, 128, 65, 54, 49, 48, 128, 65, 54, 48, 57, 128, 65, 54, 48, + 56, 128, 65, 54, 48, 54, 128, 65, 54, 48, 52, 128, 65, 54, 48, 51, 128, + 65, 54, 48, 50, 128, 65, 54, 48, 49, 128, 65, 54, 48, 48, 128, 65, 53, + 57, 56, 128, 65, 53, 57, 54, 128, 65, 53, 57, 53, 128, 65, 53, 57, 52, + 128, 65, 53, 57, 50, 128, 65, 53, 57, 49, 128, 65, 53, 56, 57, 128, 65, + 53, 56, 56, 128, 65, 53, 56, 55, 128, 65, 53, 56, 54, 128, 65, 53, 56, + 53, 128, 65, 53, 56, 52, 128, 65, 53, 56, 51, 128, 65, 53, 56, 50, 128, + 65, 53, 56, 49, 128, 65, 53, 56, 48, 128, 65, 53, 55, 57, 128, 65, 53, + 55, 56, 128, 65, 53, 55, 55, 128, 65, 53, 55, 54, 128, 65, 53, 55, 53, + 128, 65, 53, 55, 52, 128, 65, 53, 55, 51, 128, 65, 53, 55, 50, 128, 65, + 53, 55, 49, 128, 65, 53, 55, 48, 128, 65, 53, 54, 57, 128, 65, 53, 54, + 56, 128, 65, 53, 54, 54, 128, 65, 53, 54, 53, 128, 65, 53, 54, 52, 128, + 65, 53, 54, 51, 128, 65, 53, 53, 57, 128, 65, 53, 53, 55, 128, 65, 53, + 53, 54, 128, 65, 53, 53, 53, 128, 65, 53, 53, 52, 128, 65, 53, 53, 51, + 128, 65, 53, 53, 50, 128, 65, 53, 53, 49, 128, 65, 53, 53, 48, 128, 65, + 53, 52, 57, 128, 65, 53, 52, 56, 128, 65, 53, 52, 55, 128, 65, 53, 52, + 53, 128, 65, 53, 52, 50, 128, 65, 53, 52, 49, 128, 65, 53, 52, 48, 128, + 65, 53, 51, 57, 128, 65, 53, 51, 56, 128, 65, 53, 51, 55, 128, 65, 53, + 51, 54, 128, 65, 53, 51, 53, 128, 65, 53, 51, 52, 128, 65, 53, 51, 50, + 128, 65, 53, 51, 49, 128, 65, 53, 51, 48, 128, 65, 53, 50, 57, 128, 65, + 53, 50, 56, 128, 65, 53, 50, 55, 128, 65, 53, 50, 54, 128, 65, 53, 50, + 53, 128, 65, 53, 50, 52, 128, 65, 53, 50, 51, 128, 65, 53, 50, 50, 128, + 65, 53, 50, 49, 128, 65, 53, 50, 48, 128, 65, 53, 49, 57, 128, 65, 53, + 49, 56, 128, 65, 53, 49, 55, 128, 65, 53, 49, 54, 128, 65, 53, 49, 53, + 128, 65, 53, 49, 52, 128, 65, 53, 49, 51, 128, 65, 53, 49, 50, 128, 65, + 53, 49, 49, 128, 65, 53, 49, 48, 128, 65, 53, 48, 57, 128, 65, 53, 48, + 56, 128, 65, 53, 48, 55, 128, 65, 53, 48, 54, 128, 65, 53, 48, 53, 128, + 65, 53, 48, 52, 128, 65, 53, 48, 51, 128, 65, 53, 48, 50, 128, 65, 53, + 48, 49, 128, 65, 52, 57, 55, 128, 65, 52, 57, 54, 128, 65, 52, 57, 53, + 128, 65, 52, 57, 52, 128, 65, 52, 57, 51, 128, 65, 52, 57, 50, 128, 65, + 52, 57, 49, 128, 65, 52, 57, 48, 128, 65, 52, 56, 57, 128, 65, 52, 56, + 56, 128, 65, 52, 56, 55, 128, 65, 52, 56, 54, 128, 65, 52, 56, 53, 128, + 65, 52, 56, 52, 128, 65, 52, 56, 51, 128, 65, 52, 56, 50, 128, 65, 52, + 56, 49, 128, 65, 52, 56, 48, 128, 65, 52, 55, 57, 128, 65, 52, 55, 56, + 128, 65, 52, 55, 55, 128, 65, 52, 55, 54, 128, 65, 52, 55, 53, 128, 65, + 52, 55, 52, 128, 65, 52, 55, 51, 128, 65, 52, 55, 50, 128, 65, 52, 55, + 49, 128, 65, 52, 55, 48, 128, 65, 52, 54, 57, 128, 65, 52, 54, 56, 128, + 65, 52, 54, 55, 128, 65, 52, 54, 54, 128, 65, 52, 54, 53, 128, 65, 52, + 54, 52, 128, 65, 52, 54, 51, 128, 65, 52, 54, 50, 128, 65, 52, 54, 49, + 128, 65, 52, 54, 48, 128, 65, 52, 53, 57, 128, 65, 52, 53, 56, 128, 65, + 52, 53, 55, 65, 128, 65, 52, 53, 55, 128, 65, 52, 53, 54, 128, 65, 52, + 53, 53, 128, 65, 52, 53, 52, 128, 65, 52, 53, 51, 128, 65, 52, 53, 50, + 128, 65, 52, 53, 49, 128, 65, 52, 53, 48, 65, 128, 65, 52, 53, 48, 128, + 65, 52, 52, 57, 128, 65, 52, 52, 56, 128, 65, 52, 52, 55, 128, 65, 52, + 52, 54, 128, 65, 52, 52, 53, 128, 65, 52, 52, 52, 128, 65, 52, 52, 51, + 128, 65, 52, 52, 50, 128, 65, 52, 52, 49, 128, 65, 52, 52, 48, 128, 65, + 52, 51, 57, 128, 65, 52, 51, 56, 128, 65, 52, 51, 55, 128, 65, 52, 51, + 54, 128, 65, 52, 51, 53, 128, 65, 52, 51, 52, 128, 65, 52, 51, 51, 128, + 65, 52, 51, 50, 128, 65, 52, 51, 49, 128, 65, 52, 51, 48, 128, 65, 52, + 50, 57, 128, 65, 52, 50, 56, 128, 65, 52, 50, 55, 128, 65, 52, 50, 54, + 128, 65, 52, 50, 53, 128, 65, 52, 50, 52, 128, 65, 52, 50, 51, 128, 65, + 52, 50, 50, 128, 65, 52, 50, 49, 128, 65, 52, 50, 48, 128, 65, 52, 49, + 57, 128, 65, 52, 49, 56, 45, 86, 65, 83, 128, 65, 52, 49, 56, 128, 65, + 52, 49, 55, 45, 86, 65, 83, 128, 65, 52, 49, 55, 128, 65, 52, 49, 54, 45, + 86, 65, 83, 128, 65, 52, 49, 54, 128, 65, 52, 49, 53, 45, 86, 65, 83, + 128, 65, 52, 49, 53, 128, 65, 52, 49, 52, 45, 86, 65, 83, 128, 65, 52, + 49, 52, 128, 65, 52, 49, 51, 45, 86, 65, 83, 128, 65, 52, 49, 51, 128, + 65, 52, 49, 50, 45, 86, 65, 83, 128, 65, 52, 49, 50, 128, 65, 52, 49, 49, + 45, 86, 65, 83, 128, 65, 52, 49, 49, 128, 65, 52, 49, 48, 193, 65, 52, + 49, 48, 45, 86, 65, 83, 128, 65, 52, 49, 176, 65, 52, 48, 57, 45, 86, 65, + 83, 128, 65, 52, 48, 57, 128, 65, 52, 48, 56, 45, 86, 65, 83, 128, 65, + 52, 48, 56, 128, 65, 52, 48, 55, 45, 86, 65, 83, 128, 65, 52, 48, 55, + 128, 65, 52, 48, 54, 45, 86, 65, 83, 128, 65, 52, 48, 54, 128, 65, 52, + 48, 53, 45, 86, 65, 83, 128, 65, 52, 48, 53, 128, 65, 52, 48, 52, 45, 86, + 65, 83, 128, 65, 52, 48, 52, 128, 65, 52, 48, 51, 45, 86, 65, 83, 128, + 65, 52, 48, 51, 128, 65, 52, 48, 50, 45, 86, 65, 83, 128, 65, 52, 48, 50, + 128, 65, 52, 48, 49, 45, 86, 65, 83, 128, 65, 52, 48, 49, 128, 65, 52, + 48, 48, 45, 86, 65, 83, 128, 65, 52, 48, 48, 128, 65, 51, 57, 57, 128, + 65, 51, 57, 56, 128, 65, 51, 57, 55, 128, 65, 51, 57, 54, 128, 65, 51, + 57, 53, 128, 65, 51, 57, 52, 128, 65, 51, 57, 179, 65, 51, 57, 50, 128, + 65, 51, 57, 49, 128, 65, 51, 57, 48, 128, 65, 51, 56, 57, 128, 65, 51, + 56, 56, 128, 65, 51, 56, 55, 128, 65, 51, 56, 54, 65, 128, 65, 51, 56, + 54, 128, 65, 51, 56, 53, 128, 65, 51, 56, 52, 128, 65, 51, 56, 51, 65, + 128, 65, 51, 56, 179, 65, 51, 56, 50, 128, 65, 51, 56, 49, 65, 128, 65, + 51, 56, 49, 128, 65, 51, 56, 48, 128, 65, 51, 55, 57, 128, 65, 51, 55, + 56, 128, 65, 51, 55, 55, 128, 65, 51, 55, 54, 128, 65, 51, 55, 53, 128, + 65, 51, 55, 52, 128, 65, 51, 55, 51, 128, 65, 51, 55, 50, 128, 65, 51, + 55, 49, 65, 128, 65, 51, 55, 49, 128, 65, 51, 55, 48, 128, 65, 51, 54, + 57, 128, 65, 51, 54, 56, 65, 128, 65, 51, 54, 56, 128, 65, 51, 54, 55, + 128, 65, 51, 54, 54, 128, 65, 51, 54, 53, 128, 65, 51, 54, 52, 65, 128, + 65, 51, 54, 52, 128, 65, 51, 54, 51, 128, 65, 51, 54, 50, 128, 65, 51, + 54, 49, 128, 65, 51, 54, 48, 128, 65, 51, 53, 57, 65, 128, 65, 51, 53, + 57, 128, 65, 51, 53, 56, 128, 65, 51, 53, 55, 128, 65, 51, 53, 54, 128, + 65, 51, 53, 53, 128, 65, 51, 53, 52, 128, 65, 51, 53, 51, 128, 65, 51, + 53, 50, 128, 65, 51, 53, 49, 128, 65, 51, 53, 48, 128, 65, 51, 52, 57, + 128, 65, 51, 52, 56, 128, 65, 51, 52, 55, 128, 65, 51, 52, 54, 128, 65, + 51, 52, 53, 128, 65, 51, 52, 52, 128, 65, 51, 52, 51, 128, 65, 51, 52, + 50, 128, 65, 51, 52, 49, 128, 65, 51, 52, 48, 128, 65, 51, 51, 57, 128, + 65, 51, 51, 56, 128, 65, 51, 51, 55, 128, 65, 51, 51, 54, 67, 128, 65, + 51, 51, 54, 66, 128, 65, 51, 51, 54, 65, 128, 65, 51, 51, 54, 128, 65, + 51, 51, 53, 128, 65, 51, 51, 52, 128, 65, 51, 51, 51, 128, 65, 51, 51, + 50, 67, 128, 65, 51, 51, 50, 66, 128, 65, 51, 51, 50, 65, 128, 65, 51, + 51, 50, 128, 65, 51, 51, 49, 128, 65, 51, 51, 48, 128, 65, 51, 50, 57, + 65, 128, 65, 51, 50, 57, 128, 65, 51, 50, 56, 128, 65, 51, 50, 55, 128, + 65, 51, 50, 54, 128, 65, 51, 50, 53, 128, 65, 51, 50, 52, 128, 65, 51, + 50, 51, 128, 65, 51, 50, 50, 128, 65, 51, 50, 49, 128, 65, 51, 50, 48, + 128, 65, 51, 49, 57, 128, 65, 51, 49, 56, 128, 65, 51, 49, 55, 128, 65, + 51, 49, 54, 128, 65, 51, 49, 53, 128, 65, 51, 49, 52, 128, 65, 51, 49, + 51, 67, 128, 65, 51, 49, 51, 66, 128, 65, 51, 49, 51, 65, 128, 65, 51, + 49, 51, 128, 65, 51, 49, 50, 128, 65, 51, 49, 49, 128, 65, 51, 49, 48, + 128, 65, 51, 48, 57, 67, 128, 65, 51, 48, 57, 66, 128, 65, 51, 48, 57, + 65, 128, 65, 51, 48, 57, 128, 65, 51, 48, 56, 128, 65, 51, 48, 55, 128, + 65, 51, 48, 54, 128, 65, 51, 48, 53, 128, 65, 51, 48, 52, 128, 65, 51, + 48, 51, 128, 65, 51, 48, 50, 128, 65, 51, 48, 49, 128, 65, 51, 48, 48, + 128, 65, 50, 57, 57, 65, 128, 65, 50, 57, 57, 128, 65, 50, 57, 56, 128, + 65, 50, 57, 55, 128, 65, 50, 57, 54, 128, 65, 50, 57, 53, 128, 65, 50, + 57, 52, 65, 128, 65, 50, 57, 52, 128, 65, 50, 57, 51, 128, 65, 50, 57, + 50, 128, 65, 50, 57, 49, 128, 65, 50, 57, 48, 128, 65, 50, 56, 57, 65, + 128, 65, 50, 56, 57, 128, 65, 50, 56, 56, 128, 65, 50, 56, 55, 128, 65, + 50, 56, 54, 128, 65, 50, 56, 53, 128, 65, 50, 56, 52, 128, 65, 50, 56, + 51, 128, 65, 50, 56, 50, 128, 65, 50, 56, 49, 128, 65, 50, 56, 48, 128, + 65, 50, 55, 57, 128, 65, 50, 55, 56, 128, 65, 50, 55, 55, 128, 65, 50, + 55, 54, 128, 65, 50, 55, 53, 128, 65, 50, 55, 52, 128, 65, 50, 55, 51, + 128, 65, 50, 55, 50, 128, 65, 50, 55, 49, 128, 65, 50, 55, 48, 128, 65, + 50, 54, 57, 128, 65, 50, 54, 56, 128, 65, 50, 54, 55, 65, 128, 65, 50, + 54, 55, 128, 65, 50, 54, 54, 128, 65, 50, 54, 53, 128, 65, 50, 54, 52, + 128, 65, 50, 54, 51, 128, 65, 50, 54, 50, 128, 65, 50, 54, 49, 128, 65, + 50, 54, 48, 128, 65, 50, 53, 57, 128, 65, 50, 53, 56, 128, 65, 50, 53, + 55, 128, 65, 50, 53, 54, 128, 65, 50, 53, 53, 128, 65, 50, 53, 52, 128, + 65, 50, 53, 51, 128, 65, 50, 53, 50, 128, 65, 50, 53, 49, 128, 65, 50, + 53, 48, 128, 65, 50, 52, 57, 128, 65, 50, 52, 56, 128, 65, 50, 52, 55, + 128, 65, 50, 52, 54, 128, 65, 50, 52, 53, 128, 65, 50, 52, 52, 128, 65, + 50, 52, 51, 128, 65, 50, 52, 50, 128, 65, 50, 52, 49, 128, 65, 50, 52, + 48, 128, 65, 50, 51, 57, 128, 65, 50, 51, 56, 128, 65, 50, 51, 55, 128, + 65, 50, 51, 54, 128, 65, 50, 51, 53, 128, 65, 50, 51, 52, 128, 65, 50, + 51, 51, 128, 65, 50, 51, 50, 128, 65, 50, 51, 49, 128, 65, 50, 51, 48, + 128, 65, 50, 50, 57, 128, 65, 50, 50, 56, 128, 65, 50, 50, 55, 65, 128, + 65, 50, 50, 55, 128, 65, 50, 50, 54, 128, 65, 50, 50, 53, 128, 65, 50, + 50, 52, 128, 65, 50, 50, 51, 128, 65, 50, 50, 50, 128, 65, 50, 50, 49, + 128, 65, 50, 50, 48, 128, 65, 50, 49, 57, 128, 65, 50, 49, 56, 128, 65, + 50, 49, 55, 128, 65, 50, 49, 54, 65, 128, 65, 50, 49, 54, 128, 65, 50, + 49, 53, 65, 128, 65, 50, 49, 53, 128, 65, 50, 49, 52, 128, 65, 50, 49, + 51, 128, 65, 50, 49, 50, 128, 65, 50, 49, 49, 128, 65, 50, 49, 48, 128, + 65, 50, 48, 57, 65, 128, 65, 50, 48, 57, 128, 65, 50, 48, 56, 128, 65, + 50, 48, 55, 65, 128, 65, 50, 48, 55, 128, 65, 50, 48, 54, 128, 65, 50, + 48, 53, 128, 65, 50, 48, 52, 128, 65, 50, 48, 51, 128, 65, 50, 48, 50, + 66, 128, 65, 50, 48, 50, 65, 128, 65, 50, 48, 50, 128, 65, 50, 48, 49, + 128, 65, 50, 48, 48, 128, 65, 49, 57, 57, 128, 65, 49, 57, 56, 128, 65, + 49, 57, 55, 128, 65, 49, 57, 54, 128, 65, 49, 57, 53, 128, 65, 49, 57, + 52, 128, 65, 49, 57, 51, 128, 65, 49, 57, 50, 128, 65, 49, 57, 49, 128, + 65, 49, 57, 48, 128, 65, 49, 56, 57, 128, 65, 49, 56, 56, 128, 65, 49, + 56, 55, 128, 65, 49, 56, 54, 128, 65, 49, 56, 53, 128, 65, 49, 56, 52, + 128, 65, 49, 56, 51, 128, 65, 49, 56, 50, 128, 65, 49, 56, 49, 128, 65, + 49, 56, 48, 128, 65, 49, 55, 57, 128, 65, 49, 55, 56, 128, 65, 49, 55, + 55, 128, 65, 49, 55, 54, 128, 65, 49, 55, 53, 128, 65, 49, 55, 52, 128, + 65, 49, 55, 51, 128, 65, 49, 55, 50, 128, 65, 49, 55, 49, 128, 65, 49, + 55, 48, 128, 65, 49, 54, 57, 128, 65, 49, 54, 56, 128, 65, 49, 54, 55, + 128, 65, 49, 54, 54, 128, 65, 49, 54, 53, 128, 65, 49, 54, 52, 128, 65, + 49, 54, 51, 128, 65, 49, 54, 50, 128, 65, 49, 54, 49, 128, 65, 49, 54, + 48, 128, 65, 49, 53, 57, 128, 65, 49, 53, 56, 128, 65, 49, 53, 55, 128, + 65, 49, 53, 54, 128, 65, 49, 53, 53, 128, 65, 49, 53, 52, 128, 65, 49, + 53, 51, 128, 65, 49, 53, 50, 128, 65, 49, 53, 49, 128, 65, 49, 53, 48, + 128, 65, 49, 52, 57, 128, 65, 49, 52, 56, 128, 65, 49, 52, 55, 128, 65, + 49, 52, 54, 128, 65, 49, 52, 53, 128, 65, 49, 52, 52, 128, 65, 49, 52, + 51, 128, 65, 49, 52, 50, 128, 65, 49, 52, 49, 128, 65, 49, 52, 48, 128, + 65, 49, 51, 57, 128, 65, 49, 51, 56, 128, 65, 49, 51, 55, 128, 65, 49, + 51, 54, 128, 65, 49, 51, 53, 65, 128, 65, 49, 51, 53, 128, 65, 49, 51, + 52, 128, 65, 49, 51, 51, 128, 65, 49, 51, 50, 128, 65, 49, 51, 49, 67, + 128, 65, 49, 51, 49, 128, 65, 49, 51, 48, 128, 65, 49, 50, 57, 128, 65, + 49, 50, 56, 128, 65, 49, 50, 55, 128, 65, 49, 50, 54, 128, 65, 49, 50, + 53, 65, 128, 65, 49, 50, 53, 128, 65, 49, 50, 52, 128, 65, 49, 50, 51, + 128, 65, 49, 50, 50, 128, 65, 49, 50, 49, 128, 65, 49, 50, 48, 66, 128, + 65, 49, 50, 48, 128, 65, 49, 49, 57, 128, 65, 49, 49, 56, 128, 65, 49, + 49, 55, 128, 65, 49, 49, 54, 128, 65, 49, 49, 53, 65, 128, 65, 49, 49, + 53, 128, 65, 49, 49, 52, 128, 65, 49, 49, 51, 128, 65, 49, 49, 50, 128, + 65, 49, 49, 49, 128, 65, 49, 49, 48, 66, 128, 65, 49, 49, 48, 65, 128, + 65, 49, 49, 48, 128, 65, 49, 48, 57, 128, 65, 49, 48, 56, 128, 65, 49, + 48, 55, 67, 128, 65, 49, 48, 55, 66, 128, 65, 49, 48, 55, 65, 128, 65, + 49, 48, 55, 128, 65, 49, 48, 54, 128, 65, 49, 48, 53, 66, 128, 65, 49, + 48, 53, 65, 128, 65, 49, 48, 53, 128, 65, 49, 48, 52, 67, 128, 65, 49, + 48, 52, 66, 128, 65, 49, 48, 52, 65, 128, 65, 49, 48, 52, 128, 65, 49, + 48, 51, 128, 65, 49, 48, 50, 65, 128, 65, 49, 48, 50, 128, 65, 49, 48, + 49, 65, 128, 65, 49, 48, 49, 128, 65, 49, 48, 48, 65, 128, 65, 49, 48, + 48, 45, 49, 48, 50, 128, 65, 49, 48, 48, 128, 65, 48, 57, 57, 128, 65, + 48, 57, 56, 65, 128, 65, 48, 57, 56, 128, 65, 48, 57, 55, 65, 128, 65, + 48, 57, 55, 128, 65, 48, 57, 54, 128, 65, 48, 57, 53, 128, 65, 48, 57, + 52, 128, 65, 48, 57, 51, 128, 65, 48, 57, 50, 128, 65, 48, 57, 49, 128, + 65, 48, 57, 48, 128, 65, 48, 56, 57, 128, 65, 48, 56, 56, 128, 65, 48, + 56, 55, 128, 65, 48, 56, 54, 128, 65, 48, 56, 53, 128, 65, 48, 56, 52, + 128, 65, 48, 56, 51, 128, 65, 48, 56, 50, 128, 65, 48, 56, 49, 128, 65, + 48, 56, 48, 128, 65, 48, 55, 57, 128, 65, 48, 55, 56, 128, 65, 48, 55, + 55, 128, 65, 48, 55, 54, 128, 65, 48, 55, 53, 128, 65, 48, 55, 52, 128, + 65, 48, 55, 51, 128, 65, 48, 55, 50, 128, 65, 48, 55, 49, 128, 65, 48, + 55, 48, 128, 65, 48, 54, 57, 128, 65, 48, 54, 56, 128, 65, 48, 54, 55, + 128, 65, 48, 54, 54, 67, 128, 65, 48, 54, 54, 66, 128, 65, 48, 54, 54, + 65, 128, 65, 48, 54, 54, 128, 65, 48, 54, 53, 128, 65, 48, 54, 52, 128, + 65, 48, 54, 51, 128, 65, 48, 54, 50, 128, 65, 48, 54, 49, 128, 65, 48, + 54, 48, 128, 65, 48, 53, 57, 128, 65, 48, 53, 56, 128, 65, 48, 53, 55, + 128, 65, 48, 53, 54, 128, 65, 48, 53, 53, 128, 65, 48, 53, 52, 128, 65, + 48, 53, 51, 128, 65, 48, 53, 50, 128, 65, 48, 53, 49, 128, 65, 48, 53, + 48, 128, 65, 48, 52, 57, 128, 65, 48, 52, 56, 128, 65, 48, 52, 55, 128, + 65, 48, 52, 54, 66, 128, 65, 48, 52, 54, 65, 128, 65, 48, 52, 54, 128, + 65, 48, 52, 53, 65, 128, 65, 48, 52, 53, 128, 65, 48, 52, 52, 128, 65, + 48, 52, 51, 65, 128, 65, 48, 52, 51, 128, 65, 48, 52, 50, 65, 128, 65, + 48, 52, 50, 128, 65, 48, 52, 49, 65, 128, 65, 48, 52, 49, 128, 65, 48, + 52, 48, 65, 128, 65, 48, 52, 48, 128, 65, 48, 51, 57, 65, 128, 65, 48, + 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, 128, 65, 48, 51, 54, + 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, 48, 51, 51, 128, 65, + 48, 51, 50, 65, 128, 65, 48, 50, 56, 66, 128, 65, 48, 50, 54, 65, 128, + 65, 48, 49, 55, 65, 128, 65, 48, 49, 52, 65, 128, 65, 48, 49, 48, 65, + 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, 128, 65, 48, 48, 53, + 65, 128, 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, 10, 14, 19, 27, 34, 44, 49, 55, 64, 66, 69, 81, 89, 102, 108, + 113, 118, 124, 129, 137, 146, 157, 162, 167, 170, 174, 183, 189, 195, + 201, 206, 214, 221, 229, 171, 232, 241, 242, 250, 256, 261, 266, 273, + 283, 290, 296, 301, 304, 308, 314, 320, 325, 328, 333, 343, 349, 354, + 359, 365, 370, 379, 381, 388, 395, 397, 406, 347, 408, 416, 424, 426, + 434, 435, 442, 445, 447, 452, 458, 465, 470, 477, 485, 492, 497, 502, + 506, 512, 517, 522, 532, 539, 542, 550, 558, 567, 570, 574, 577, 581, + 591, 595, 602, 609, 616, 623, 632, 641, 645, 652, 655, 661, 665, 673, + 678, 687, 265, 691, 704, 708, 713, 718, 724, 726, 736, 739, 743, 748, + 756, 760, 769, 774, 780, 786, 790, 795, 803, 812, 821, 829, 837, 840, + 793, 851, 857, 862, 870, 877, 880, 890, 894, 898, 905, 909, 912, 919, + 923, 614, 929, 938, 941, 946, 952, 955, 959, 962, 966, 969, 972, 981, + 987, 990, 995, 1004, 1009, 576, 1012, 1018, 1026, 1031, 1035, 1040, 1043, + 1046, 1052, 1058, 1065, 1073, 1076, 1085, 1093, 1097, 1104, 1110, 1115, + 1120, 1126, 1131, 1136, 1141, 1145, 1150, 1156, 1161, 1166, 1170, 1176, + 1181, 1186, 1191, 1195, 1200, 1205, 1210, 1216, 1222, 1228, 1233, 1237, + 1242, 1247, 1252, 1256, 1261, 1266, 1271, 1276, 1111, 1116, 1121, 1127, + 1132, 1280, 1142, 1286, 1291, 1296, 1303, 1307, 1310, 1319, 1146, 1323, + 1151, 1157, 1162, 1327, 1332, 1337, 1341, 1345, 1351, 1355, 1167, 1358, + 1360, 1177, 1365, 1369, 1182, 1375, 1187, 1379, 1383, 1390, 1192, 1394, + 1399, 1403, 1406, 1410, 1196, 1201, 1415, 1421, 1206, 1433, 1439, 1445, + 1451, 1211, 1223, 1229, 1455, 1459, 1463, 1466, 1234, 1470, 1472, 1477, + 1482, 1488, 1493, 1498, 1502, 1507, 1512, 1517, 1522, 1528, 1533, 1538, + 1544, 1550, 1555, 1559, 1564, 1569, 1574, 1579, 1584, 1588, 1596, 1601, + 1605, 1610, 1615, 1620, 1625, 1629, 1632, 1639, 1644, 1649, 1654, 1659, + 1665, 1670, 1674, 1238, 1677, 1682, 1687, 1692, 1243, 1696, 1700, 1707, + 1248, 1714, 1719, 1253, 1723, 1725, 1730, 1741, 1747, 1257, 1752, 1761, + 1262, 1766, 1772, 1777, 1267, 1782, 1791, 1796, 1800, 1803, 1808, 1812, + 1816, 1820, 1823, 1827, 1272, 1832, 1277, 1836, 1838, 1844, 1850, 1856, + 1862, 1868, 1874, 1880, 1886, 1891, 1897, 1903, 1909, 1915, 1921, 1927, + 1933, 1939, 1945, 1950, 1955, 1960, 1965, 1970, 1975, 1980, 1985, 1990, + 1995, 2001, 2006, 2012, 2017, 2023, 2029, 2034, 2040, 2046, 2052, 2058, + 2063, 2068, 2070, 2071, 2075, 2079, 2084, 2088, 2092, 2096, 2101, 2105, + 2108, 2113, 2117, 2122, 2126, 2130, 2135, 2139, 2142, 2146, 2152, 2166, + 2170, 2174, 2178, 2181, 2186, 2190, 2194, 2197, 2201, 2206, 2211, 2216, + 2221, 2225, 2229, 2233, 2237, 2241, 2246, 2250, 2255, 2259, 2264, 2270, + 2277, 2283, 2288, 2293, 2298, 2304, 2309, 2315, 2320, 2325, 2330, 2335, + 2340, 2343, 2345, 1128, 2349, 2356, 2364, 2374, 2383, 2397, 2401, 2405, + 2410, 2423, 2431, 2434, 2438, 2443, 2447, 2450, 2454, 2458, 2463, 1736, + 2468, 2472, 2475, 2479, 2485, 2492, 2499, 2505, 2510, 2515, 2521, 2527, + 2532, 2537, 2542, 2547, 2552, 2557, 2482, 2562, 1727, 2564, 2570, 2574, + 2579, 2583, 2587, 1635, 1749, 2592, 2596, 2600, 2603, 2608, 2613, 2618, + 2623, 2627, 2634, 2639, 2642, 2646, 2653, 2659, 2663, 2667, 2671, 2676, + 2683, 2688, 2693, 2700, 2706, 2712, 2718, 2739, 2753, 2770, 2785, 2801, + 2818, 2833, 2842, 2847, 2851, 2856, 2861, 2865, 2877, 2884, 2890, 2273, + 2896, 2903, 2909, 2913, 2916, 2923, 2929, 2934, 2938, 2943, 2947, 2951, + 2093, 2955, 2960, 2965, 2969, 2974, 2982, 2986, 2993, 2998, 3002, 3006, + 3010, 3015, 3020, 3025, 3029, 3034, 3039, 3043, 3048, 3053, 3057, 3060, + 3064, 3068, 3076, 3081, 3085, 3089, 3095, 3104, 3108, 3112, 3118, 3123, + 3130, 3134, 3144, 3148, 3152, 3157, 3161, 3166, 3172, 3177, 3181, 3185, + 3189, 2495, 3197, 3202, 3208, 3213, 3217, 3222, 3227, 3231, 3237, 3242, + 2097, 3248, 3254, 3259, 3264, 3269, 3274, 3279, 3284, 3289, 3294, 3299, + 3304, 3309, 3314, 3319, 3324, 3330, 3335, 1143, 101, 3341, 3345, 3349, + 3353, 3358, 3362, 3366, 3372, 3377, 3381, 3385, 3390, 3395, 3399, 3404, + 3408, 3411, 3415, 3420, 3424, 3429, 3433, 3436, 3438, 3442, 3446, 3451, + 3455, 3458, 3471, 3475, 3479, 3483, 3488, 3492, 3496, 3499, 3503, 3507, + 3512, 3516, 3521, 3526, 3531, 3535, 3542, 3547, 3550, 3553, 3558, 3564, + 3568, 3572, 3575, 3580, 3584, 3589, 3593, 3597, 3600, 3606, 3611, 3616, + 3622, 3627, 3632, 3638, 3644, 3649, 3654, 3659, 3664, 964, 654, 3667, + 3670, 3675, 3679, 3683, 3687, 3691, 3694, 3698, 3703, 3708, 3712, 3717, + 3721, 3726, 3730, 3734, 3738, 3744, 3750, 3753, 3756, 150, 3762, 3767, + 3776, 3784, 3793, 3803, 3810, 3816, 3823, 3828, 3832, 3836, 3844, 3851, + 3856, 3863, 3868, 3872, 3882, 3886, 3890, 3895, 3900, 3910, 2109, 3915, + 3919, 3922, 3928, 3933, 3939, 3945, 3950, 3957, 3961, 3965, 3969, 3974, + 3979, 3984, 3989, 3994, 3999, 592, 575, 1304, 4004, 4011, 4018, 4024, + 4029, 4036, 4043, 4048, 4054, 4060, 4065, 4069, 4075, 4082, 4087, 4091, + 4095, 2118, 4101, 4109, 4115, 4123, 807, 4129, 4137, 4148, 4152, 4162, + 4168, 4173, 4178, 4183, 4188, 2123, 4193, 4198, 4213, 4219, 4226, 4237, + 4247, 4253, 4258, 4264, 4270, 4273, 4276, 4280, 4285, 4288, 4295, 4304, + 4309, 4313, 4317, 4321, 4325, 4330, 4336, 4347, 4351, 3416, 4356, 4368, + 4374, 4382, 4386, 4391, 4398, 4403, 4408, 4413, 1504, 4418, 4421, 4424, + 4428, 4431, 4437, 4441, 4455, 4459, 4462, 4466, 4472, 4478, 4483, 4487, + 4491, 4497, 4508, 4514, 4519, 4525, 4529, 4537, 4549, 4559, 4565, 4570, + 4579, 4587, 4594, 4600, 4606, 4610, 4616, 4625, 4634, 4640, 4644, 4653, + 4658, 4662, 4667, 4671, 4679, 4685, 4689, 4696, 4701, 4705, 4711, 2131, + 4717, 4722, 4727, 4732, 4737, 1320, 4742, 4747, 4753, 4758, 4763, 4768, + 4773, 4778, 4783, 4789, 4794, 4800, 4805, 4810, 4815, 4821, 4826, 4831, + 4836, 4841, 4847, 4852, 4858, 4863, 4868, 4873, 4878, 4883, 4888, 4894, + 4899, 4904, 312, 369, 4909, 4915, 4919, 4923, 4928, 4932, 4936, 4939, + 4943, 4947, 4950, 4954, 4958, 4962, 4967, 4971, 4975, 4981, 4990, 4714, + 4995, 4999, 5002, 5007, 5012, 5017, 5022, 5027, 5032, 5037, 5042, 5047, + 5052, 5056, 5061, 5066, 5071, 5076, 5081, 5086, 5091, 5096, 5101, 5106, + 5110, 5115, 5120, 5125, 5130, 5135, 5140, 5145, 5150, 5155, 5160, 5164, + 5169, 5174, 5179, 5184, 5189, 5194, 5199, 5204, 5209, 5214, 5218, 5223, + 5228, 5233, 5238, 5243, 5248, 5253, 5258, 5263, 5268, 5272, 5277, 5282, + 5287, 5292, 5297, 5302, 5307, 5312, 5317, 5322, 5326, 5331, 5336, 5341, + 5346, 5351, 5356, 5361, 5366, 5371, 5376, 5380, 5385, 5390, 5395, 5400, + 5406, 5412, 5418, 5424, 5430, 5436, 5442, 5447, 5453, 5459, 5465, 5471, + 5477, 5483, 5489, 5495, 5501, 5507, 5512, 5518, 5524, 5530, 5536, 5542, + 5548, 5554, 5560, 5566, 5572, 5577, 5583, 5589, 5595, 5601, 5607, 5613, + 5619, 5625, 5631, 5637, 5642, 5648, 5654, 5660, 5666, 5672, 5678, 5684, + 5690, 5696, 5702, 5707, 5713, 5719, 5725, 5731, 5737, 5743, 5749, 5755, + 5761, 5767, 5772, 5776, 5782, 5788, 5794, 5800, 5806, 5812, 5818, 5824, + 5830, 5836, 5841, 5847, 5853, 5859, 5865, 5871, 5877, 5883, 5889, 5895, + 5901, 5906, 5912, 5918, 5924, 5930, 5936, 5942, 5948, 5954, 5960, 5966, + 5971, 5977, 5983, 5989, 5995, 6001, 6007, 6013, 6019, 6025, 6031, 6036, + 6042, 6048, 6054, 6060, 6066, 6072, 6078, 6084, 6090, 6096, 6101, 6107, + 6113, 6119, 6125, 6131, 6137, 6143, 6149, 6155, 6161, 6166, 6172, 6178, + 6184, 6190, 6196, 6202, 6208, 6214, 6220, 6226, 6231, 6237, 6243, 6249, + 6255, 6261, 6267, 6273, 6279, 6285, 6291, 6296, 6302, 6308, 6314, 6320, + 6326, 6332, 6338, 6344, 6350, 6356, 6361, 6367, 6373, 6379, 6385, 6391, + 6397, 6403, 6409, 6415, 6421, 6426, 6430, 6433, 6440, 6444, 6457, 6461, + 6465, 6469, 6472, 6476, 6481, 6485, 6494, 6498, 6504, 6511, 6522, 6530, + 6537, 6541, 6549, 6558, 6564, 6568, 6580, 6585, 6588, 6593, 6597, 6607, + 6615, 6623, 6629, 6633, 6643, 6653, 6661, 6668, 6675, 6681, 6687, 6694, + 6698, 6705, 6715, 6725, 6733, 6740, 6745, 6749, 6753, 6761, 6765, 6775, + 6780, 6787, 6795, 6800, 6804, 6809, 6813, 6820, 6825, 6839, 6844, 6849, + 6856, 3680, 6865, 6869, 6873, 6878, 6882, 6886, 6889, 6894, 6899, 6908, + 6914, 6920, 6925, 6931, 6935, 6946, 6956, 6971, 6986, 7001, 7016, 7031, + 7046, 7061, 7076, 7091, 7106, 7121, 7136, 7151, 7166, 7181, 7196, 7211, + 7226, 7241, 7256, 7271, 7286, 7301, 7316, 7331, 7346, 7361, 7376, 7391, + 7406, 7421, 7436, 7451, 7466, 7481, 7496, 7511, 7526, 7541, 7556, 7571, + 7586, 7601, 7616, 7631, 7646, 7661, 7676, 7691, 7700, 7709, 7714, 7720, + 7730, 7734, 7738, 7743, 7748, 7753, 7761, 7765, 7768, 7772, 3139, 7775, + 7780, 346, 520, 7786, 7794, 7798, 7802, 7805, 7809, 7815, 7819, 7827, + 7833, 7838, 7845, 7853, 7860, 7866, 7871, 7878, 7884, 7893, 7901, 7905, + 7910, 7918, 7930, 7941, 7948, 7959, 7963, 7967, 7971, 7974, 7980, 3443, + 7984, 7990, 7995, 8000, 8005, 8011, 8016, 8021, 8026, 8031, 8037, 8042, + 8047, 8053, 8058, 8064, 8069, 8075, 8080, 8086, 8091, 8096, 8101, 8106, + 8111, 8117, 8122, 8127, 8132, 8138, 8144, 8150, 8156, 8162, 8168, 8174, + 8180, 8186, 8192, 8198, 8204, 8209, 8214, 8219, 8224, 8229, 8234, 8239, + 8244, 8250, 8256, 8261, 8267, 8273, 8279, 8284, 8289, 8294, 8299, 8305, + 8311, 8316, 8321, 8326, 8331, 8336, 8342, 8347, 8353, 8359, 8365, 8371, + 8377, 8383, 8389, 8395, 8401, 2140, 7804, 8406, 8410, 8418, 8422, 8425, + 8432, 8435, 8439, 8447, 8452, 8457, 8448, 8462, 2167, 8466, 8472, 8478, + 8483, 8488, 8495, 8503, 8508, 8512, 8515, 8519, 8525, 8531, 8535, 1679, + 572, 8538, 8542, 8547, 8553, 8558, 8562, 8565, 8569, 8575, 8580, 8584, + 8591, 8595, 8599, 8603, 792, 1063, 8606, 8614, 8621, 8628, 8634, 8641, + 8649, 8656, 8667, 8674, 8680, 8685, 8697, 1163, 1328, 1333, 8708, 8712, + 1338, 8716, 8720, 8729, 8737, 8741, 8750, 8756, 8762, 8767, 8771, 8777, + 8782, 8790, 8797, 2838, 8804, 8810, 8814, 8823, 8832, 8841, 8850, 8856, + 8861, 8866, 8877, 8886, 8898, 8903, 8911, 2226, 8915, 8917, 8922, 8926, + 8935, 8943, 1342, 165, 3722, 3727, 8949, 8953, 8962, 8968, 8973, 8976, + 8985, 2238, 8991, 2830, 8995, 9003, 9007, 9011, 9015, 9019, 2247, 9023, + 9028, 9035, 9041, 9047, 9050, 9052, 9055, 9063, 9071, 9079, 9082, 9087, + 2260, 9092, 8459, 9095, 9097, 9102, 9107, 9112, 9117, 9122, 9127, 9132, + 9137, 9142, 9147, 9153, 9158, 9163, 9168, 9174, 9179, 9184, 9189, 9194, + 9199, 9204, 9210, 9215, 9220, 9225, 9230, 9235, 9240, 9245, 9250, 9255, + 9260, 9265, 9270, 9275, 9280, 9285, 9290, 9295, 9301, 9307, 9312, 9317, + 9322, 9327, 9332, 2271, 2278, 2284, 9337, 9345, 9351, 9359, 2310, 2316, + 9367, 2321, 2326, 2331, 2336, 9371, 9375, 9380, 9384, 9388, 9392, 9397, + 9401, 9406, 9410, 9413, 9416, 9422, 9429, 9435, 9442, 9448, 9455, 9461, + 9468, 9474, 9480, 9489, 9495, 9499, 9503, 9507, 9511, 9516, 9520, 9525, + 9529, 9535, 9539, 9544, 9551, 9562, 9570, 9580, 9586, 9596, 9605, 9612, + 9617, 9621, 9632, 9642, 9655, 9666, 9679, 9690, 9702, 9714, 9726, 9737, + 9750, 9763, 9770, 9776, 9787, 9797, 9811, 9818, 9824, 9833, 9841, 9845, + 9850, 9854, 9861, 9869, 9876, 9880, 9886, 9890, 9896, 9906, 9910, 9915, + 9920, 9927, 9933, 8636, 9943, 9947, 9954, 9960, 9967, 9974, 1062, 9978, + 9984, 9988, 9993, 9998, 10003, 10007, 10013, 10021, 10028, 10034, 10038, + 10041, 10047, 10057, 10061, 10067, 10072, 10076, 10081, 10085, 10091, + 10097, 10102, 10108, 10113, 10118, 10123, 2163, 10128, 10130, 10135, + 10143, 10152, 10156, 10162, 10167, 10172, 10177, 10182, 10188, 10193, + 10198, 4493, 10203, 10208, 10212, 10218, 10223, 10229, 10234, 10239, + 10245, 10250, 10157, 10256, 10260, 10267, 10273, 10278, 10282, 6835, + 10287, 10296, 10301, 10306, 9031, 9038, 10311, 3012, 10315, 10320, 10325, + 10330, 10168, 10334, 10339, 10344, 10173, 10348, 10178, 10353, 10360, + 10367, 10373, 10380, 10386, 10392, 10397, 10404, 10409, 10414, 10419, + 10425, 10183, 10189, 10431, 10437, 10442, 10447, 10455, 10194, 10460, + 10463, 10465, 10473, 10479, 10485, 10494, 10502, 10510, 10518, 10526, + 10534, 10542, 10550, 10558, 10567, 10576, 10584, 10593, 10602, 10611, + 10620, 10629, 10638, 10647, 10656, 10665, 10674, 10682, 10687, 10691, + 10697, 10705, 10712, 10727, 10744, 10763, 10772, 10780, 10795, 10806, + 10814, 10824, 10834, 10842, 10848, 10860, 10869, 10877, 10884, 10891, + 10898, 10904, 10909, 10919, 10927, 10937, 10944, 10954, 10964, 10974, + 10982, 10989, 10998, 11008, 11022, 11037, 11046, 11054, 11059, 11063, + 11072, 11078, 11083, 11093, 11103, 11113, 11118, 11122, 11132, 11141, + 11146, 11162, 11179, 11189, 11200, 11213, 11224, 11232, 11245, 11257, + 11265, 11270, 11274, 11280, 11285, 11293, 11301, 11308, 11319, 11324, + 11332, 11342, 11348, 11352, 11355, 11359, 11365, 11372, 11376, 11384, + 11393, 11401, 11408, 11413, 11418, 11422, 11426, 11434, 11449, 11465, + 11471, 11479, 11488, 11496, 11502, 11506, 11513, 11524, 11528, 11531, + 11537, 11542, 10199, 11550, 11556, 11563, 11569, 11574, 11581, 11588, + 11595, 11602, 11609, 11616, 11623, 11630, 11637, 11644, 11651, 11658, + 11665, 11672, 11679, 11684, 10740, 11689, 11695, 11702, 11709, 11714, + 11721, 11730, 11734, 11746, 11750, 11756, 11761, 11766, 11771, 11776, + 11781, 9069, 11786, 11789, 11793, 11797, 11801, 11805, 11811, 11817, + 11822, 11828, 11833, 11838, 11844, 11849, 11854, 9923, 11859, 11863, + 11867, 11871, 11876, 11881, 11886, 11894, 11900, 11905, 11909, 11913, + 11920, 11925, 11933, 11940, 11945, 11949, 11952, 11958, 11965, 11969, + 11972, 11977, 11981, 4532, 11987, 11996, 46, 12004, 12010, 12015, 12020, + 12028, 12035, 12040, 6770, 12046, 12052, 12057, 12061, 12064, 12079, + 12098, 12110, 12123, 12136, 12149, 12163, 12176, 12191, 12198, 10204, + 12204, 12218, 12223, 12229, 12234, 12242, 12247, 8819, 12252, 12255, + 12263, 12270, 12275, 12279, 12285, 12289, 12294, 12299, 12304, 12309, + 12314, 12319, 3017, 10822, 12324, 12328, 12334, 12340, 12345, 12351, + 12356, 10213, 12362, 12368, 12373, 12378, 12386, 12392, 12405, 12413, + 12420, 12426, 10219, 12432, 12440, 12448, 12455, 12468, 12481, 12493, + 12503, 12515, 12543, 12551, 12560, 12567, 12579, 12586, 12596, 12605, + 12613, 12620, 12625, 12631, 10224, 12636, 12642, 12647, 12652, 10230, + 12657, 12660, 12667, 12673, 12687, 12700, 12711, 9555, 12722, 12728, + 12737, 12745, 12752, 12758, 12769, 12775, 12780, 12788, 4020, 12794, + 12799, 12071, 12805, 12812, 12817, 10235, 12823, 12828, 12835, 12841, + 12847, 12852, 12860, 12868, 12875, 12879, 12891, 12905, 12915, 12920, + 12924, 12935, 12941, 12946, 12951, 10240, 12955, 10246, 12960, 12963, + 12968, 12980, 12987, 12992, 12996, 13004, 13009, 13013, 13018, 13022, + 13029, 13035, 10251, 10158, 13042, 3022, 12, 13049, 13054, 13058, 13062, + 13068, 13076, 13086, 13091, 13096, 13103, 13110, 13114, 13125, 13135, + 13144, 13153, 13165, 13170, 13174, 13182, 13196, 13200, 13203, 13207, + 13215, 13222, 13230, 13234, 13245, 13253, 13257, 13264, 13269, 13273, + 13279, 13284, 13290, 13295, 13300, 13304, 13310, 13315, 13326, 13330, + 13333, 13339, 13346, 13351, 13357, 13363, 13370, 13381, 13391, 13401, + 13410, 13417, 13426, 13430, 10261, 10268, 10274, 10279, 13436, 13442, + 13448, 13453, 13459, 10283, 13465, 13468, 13475, 13480, 13485, 13500, + 13516, 13531, 13539, 13545, 13550, 13555, 13560, 13565, 13570, 13575, + 13580, 13585, 13590, 1055, 357, 13595, 13603, 13610, 13616, 13621, 13626, + 10288, 13628, 13632, 13637, 13641, 13651, 13656, 13660, 13663, 13672, + 13676, 13679, 13686, 10297, 13691, 13694, 13702, 13709, 13717, 13721, + 13727, 13731, 13738, 13747, 13754, 13750, 13761, 13765, 13771, 13775, + 13779, 13783, 13789, 13799, 13807, 13814, 13818, 13826, 13831, 13835, + 13842, 13847, 13851, 13856, 13861, 13865, 13872, 13878, 13886, 13892, + 13897, 13907, 13914, 13919, 13924, 13928, 13932, 13940, 4362, 13948, + 13953, 10302, 13957, 13964, 13968, 13971, 13979, 13986, 13990, 6625, + 13994, 13999, 14004, 14008, 14019, 14029, 14034, 14040, 14045, 14049, + 14052, 14060, 14065, 14070, 14077, 14082, 10307, 14087, 14091, 14098, + 14103, 14108, 14113, 6793, 14118, 14123, 14128, 14133, 14139, 14144, + 14150, 14155, 14160, 14165, 14170, 14175, 14180, 14185, 14190, 14195, + 14200, 14205, 14210, 14215, 14220, 14225, 14230, 14236, 14241, 14246, + 14251, 14256, 14261, 14267, 14272, 14277, 14283, 14288, 14294, 14299, + 14305, 14310, 14315, 14320, 14325, 14331, 14336, 14341, 14346, 14354, + 985, 112, 14360, 14364, 14369, 14374, 14378, 14382, 14386, 14391, 14395, + 14400, 14404, 14407, 14411, 14415, 14421, 14426, 14436, 14442, 14450, + 14456, 14460, 14464, 14471, 14479, 14488, 14499, 14509, 14516, 14523, + 14527, 14536, 14545, 14553, 14560, 14569, 14578, 14587, 14596, 14606, + 14616, 14626, 14636, 14646, 14655, 14665, 14675, 14685, 14695, 14705, + 14715, 14725, 14734, 14744, 14754, 14764, 14774, 14784, 14794, 14803, + 14813, 14823, 14833, 14843, 14853, 14863, 14873, 14883, 14893, 14902, + 14912, 14922, 14932, 14942, 14952, 14962, 14972, 14982, 14992, 15002, + 15011, 15017, 1172, 15021, 15024, 15028, 15033, 15040, 15046, 15051, + 15055, 15060, 15069, 15078, 15086, 15091, 15095, 15099, 15105, 15110, + 15116, 10316, 15121, 15126, 15135, 15140, 10326, 15145, 15148, 15154, + 15162, 10331, 15169, 15173, 15177, 15182, 15186, 15196, 15202, 15208, + 15213, 15222, 15230, 15237, 15244, 15249, 15256, 15261, 15265, 15268, + 15279, 15289, 15302, 15311, 15319, 15330, 15342, 15352, 15362, 15367, + 15371, 15376, 15381, 15385, 15391, 15399, 15406, 15417, 15422, 15432, + 15441, 15445, 15448, 15455, 15465, 15474, 15481, 15485, 15492, 15498, + 15503, 15508, 15512, 15064, 15521, 15525, 15531, 15535, 15540, 15544, + 15551, 15558, 15562, 15571, 15579, 15587, 15594, 15602, 15614, 15625, + 15635, 15642, 15648, 15657, 15668, 15677, 15689, 15701, 15713, 15723, + 15732, 15742, 15751, 15759, 15766, 15775, 15783, 15787, 15792, 15798, + 15804, 15809, 15814, 15818, 15823, 15828, 15833, 15838, 15843, 15848, + 15853, 8480, 15858, 15860, 15864, 15869, 15875, 15882, 15888, 15894, + 15903, 15907, 15913, 15921, 15928, 15937, 15946, 15955, 15964, 15973, + 15982, 15991, 16000, 16010, 16020, 16029, 16035, 16042, 16049, 16055, + 16069, 16075, 16082, 16090, 16099, 16107, 16113, 16122, 16131, 16142, + 16148, 16158, 16166, 16173, 16181, 16190, 16203, 16212, 16220, 16227, + 16240, 16246, 16252, 16262, 16271, 16280, 16285, 16289, 16295, 16301, + 16306, 16313, 16320, 9937, 16325, 16330, 16337, 16345, 16350, 16362, + 16369, 16374, 16386, 14417, 16391, 16397, 16405, 16411, 16416, 16424, + 16432, 16439, 16447, 16453, 16461, 16469, 16475, 16483, 16489, 16494, + 16500, 16507, 16513, 16518, 16522, 16533, 16541, 16549, 16555, 16560, + 16567, 16576, 16582, 16587, 16595, 16602, 16611, 16625, 4306, 16629, + 16634, 16639, 16645, 16650, 16655, 16659, 16664, 16669, 16674, 8479, + 16679, 16684, 16689, 16694, 16699, 16703, 16708, 16713, 16718, 16723, + 16729, 16735, 13723, 16740, 16746, 16751, 16756, 16761, 10335, 16766, + 16771, 16776, 16781, 16786, 16800, 16817, 16835, 16847, 16860, 16877, + 16893, 16910, 16920, 16939, 16950, 16961, 16972, 2727, 16983, 16994, + 17005, 17022, 17033, 17044, 17049, 10340, 17054, 17058, 2420, 17062, + 17065, 17071, 17079, 17087, 17093, 17102, 17109, 17114, 17122, 17130, + 17137, 17141, 17146, 17152, 17159, 17167, 17174, 17186, 17193, 17199, + 17207, 17212, 17218, 17224, 17229, 13494, 17236, 17245, 17251, 17256, + 17264, 17273, 17281, 17288, 17294, 17302, 17309, 17315, 17321, 17328, + 17335, 17341, 17347, 17356, 17364, 17369, 17379, 17386, 17392, 17400, + 17406, 17414, 17422, 17429, 17442, 17449, 17458, 17467, 17476, 17484, + 17494, 17501, 17506, 3876, 17513, 17518, 1288, 17522, 17529, 16680, + 17533, 17539, 17543, 17551, 17563, 17568, 17575, 17581, 17586, 17593, + 16685, 17597, 17601, 17605, 16690, 17609, 16695, 17613, 17620, 17625, + 17629, 17636, 17640, 17648, 17655, 17660, 17668, 17672, 17679, 17696, + 17705, 17714, 17718, 17721, 17727, 17735, 17741, 17746, 17750, 17755, + 17760, 17765, 17770, 17775, 17780, 3954, 17785, 17787, 17795, 17802, + 17812, 17824, 17829, 17833, 17839, 17844, 17852, 17856, 17862, 17867, + 17873, 17876, 17883, 17891, 17898, 17904, 17909, 17915, 17920, 17927, + 17933, 17938, 17945, 17950, 17954, 17960, 17966, 17970, 17977, 17983, + 17988, 17994, 18002, 18010, 18017, 18023, 18028, 18034, 18040, 18048, + 18053, 18058, 18066, 18072, 18078, 18083, 18090, 18095, 18099, 18105, + 18111, 18116, 18123, 18128, 18134, 18137, 18143, 18154, 18160, 18163, + 18167, 18171, 18185, 18198, 18210, 18216, 18221, 18228, 18234, 18240, + 18251, 18263, 18275, 18285, 18294, 18302, 18309, 18320, 18330, 18340, + 18348, 18351, 16709, 18356, 18361, 16714, 16865, 18369, 18382, 18397, + 18408, 16882, 18426, 18439, 18452, 18463, 12086, 18474, 18487, 18506, + 18517, 18528, 18539, 2748, 18552, 18556, 18564, 18575, 18586, 18594, + 18609, 18624, 18635, 18642, 18648, 18656, 18660, 18666, 18669, 18682, + 18694, 18704, 18712, 18719, 18727, 18737, 18742, 18749, 18754, 18761, + 18772, 18782, 18788, 18793, 18798, 16719, 18802, 18808, 18814, 18819, + 18824, 18829, 18833, 16724, 16730, 18837, 16736, 18842, 18850, 18855, + 18859, 18866, 18874, 18881, 18890, 18897, 18901, 18905, 18910, 18915, + 18920, 18925, 18930, 10179, 18935, 18937, 18942, 18947, 18953, 18958, + 18963, 18968, 18973, 18977, 18983, 18989, 18994, 19000, 19005, 19010, + 19014, 19020, 19025, 19029, 19034, 19039, 19051, 19056, 19062, 19067, + 19072, 19078, 19084, 19089, 19094, 19099, 19106, 19112, 19123, 19130, + 19139, 19144, 19148, 263, 19152, 19160, 19165, 19171, 19178, 19185, + 19191, 19196, 19201, 19206, 19213, 19223, 19231, 19236, 19241, 19248, + 19254, 19263, 19273, 19283, 19297, 19311, 19325, 19339, 19354, 19369, + 19386, 19404, 19417, 19423, 19428, 19433, 19437, 19445, 19450, 19458, + 19464, 19470, 19475, 19480, 19484, 19490, 19495, 19499, 19506, 19511, + 19515, 19526, 19532, 19537, 19542, 19549, 19554, 19558, 3839, 19563, + 19569, 19576, 16741, 19582, 19586, 19592, 19597, 19602, 19606, 19612, + 19617, 19622, 19629, 19634, 15198, 19638, 19643, 19647, 19652, 19658, + 19664, 19671, 19681, 19689, 19696, 19701, 19705, 19714, 19722, 19729, + 19736, 19742, 19747, 19753, 19758, 19763, 19769, 19774, 19780, 19785, + 19791, 19797, 19804, 19810, 19815, 19820, 10405, 19829, 19832, 19840, + 19846, 19851, 19856, 19866, 19873, 19879, 19884, 19889, 19895, 19900, + 19906, 19911, 19917, 19924, 19930, 19936, 19941, 19949, 19956, 19961, + 19966, 19972, 19977, 19981, 19990, 20001, 20008, 20015, 20023, 20030, + 20037, 20042, 20047, 20053, 20058, 20066, 20072, 20078, 20085, 20091, + 20096, 20100, 20106, 20111, 20116, 20120, 20125, 1361, 8504, 3036, 20129, + 20133, 20137, 20141, 20145, 20149, 20152, 20157, 20164, 20172, 16752, + 20179, 20189, 20197, 20204, 20212, 20222, 20231, 20244, 20249, 20254, + 20262, 20269, 15307, 15316, 20276, 20286, 20301, 20307, 20314, 20321, + 20328, 20334, 20340, 20351, 20359, 20367, 20377, 20387, 20396, 16757, + 20405, 20411, 20417, 20426, 20434, 20442, 20447, 20456, 20464, 20476, + 20486, 20496, 20506, 20515, 20527, 20537, 20547, 20558, 20565, 20570, + 20577, 20589, 20601, 20613, 20625, 20637, 20649, 20661, 20673, 20685, + 20697, 20708, 20720, 20732, 20744, 20756, 20768, 20780, 20792, 20804, + 20816, 20828, 20839, 20851, 20863, 20875, 20887, 20899, 20911, 20923, + 20935, 20947, 20959, 20970, 20982, 20994, 21006, 21018, 21030, 21042, + 21054, 21066, 21078, 21090, 21101, 21113, 21125, 21137, 21149, 21161, + 21173, 21185, 21197, 21209, 21221, 21232, 21244, 21256, 21268, 21280, + 21292, 21304, 21316, 21328, 21340, 21352, 21363, 21375, 21387, 21399, + 21411, 21423, 21435, 21447, 21459, 21471, 21483, 21494, 21506, 21518, + 21530, 21542, 21555, 21568, 21581, 21594, 21607, 21620, 21633, 21645, + 21658, 21671, 21684, 21697, 21710, 21723, 21736, 21749, 21762, 21775, + 21787, 21800, 21813, 21826, 21839, 21852, 21865, 21878, 21891, 21904, + 21917, 21929, 21942, 21955, 21968, 21981, 21994, 22007, 22020, 22033, + 22046, 22059, 22071, 22084, 22097, 22110, 22123, 22136, 22149, 22162, + 22175, 22188, 22201, 22213, 22226, 22239, 22252, 22265, 22278, 22291, + 22304, 22317, 22330, 22343, 22355, 22366, 22379, 22392, 22405, 22418, + 22431, 22444, 22457, 22470, 22483, 22496, 22508, 22521, 22534, 22547, + 22560, 22573, 22586, 22599, 22612, 22625, 22638, 22650, 22663, 22676, + 22689, 22702, 22715, 22728, 22741, 22754, 22767, 22780, 22792, 22805, + 22818, 22831, 22844, 22857, 22870, 22883, 22896, 22909, 22922, 22934, + 22947, 22960, 22973, 22986, 22999, 23012, 23025, 23038, 23051, 23064, + 23076, 23089, 23102, 23115, 23128, 23141, 23154, 23167, 23180, 23193, + 23206, 23218, 23231, 23244, 23257, 23270, 23283, 23296, 23309, 23322, + 23335, 23348, 23360, 23373, 23386, 23399, 23412, 23425, 23438, 23451, + 23464, 23477, 23490, 23502, 23515, 23528, 23541, 23554, 23567, 23580, + 23593, 23606, 23619, 23632, 23644, 23657, 23670, 23683, 23696, 23709, + 23722, 23735, 23748, 23761, 23774, 23786, 23797, 23806, 23814, 23822, + 23829, 23835, 23839, 23845, 23851, 23859, 23864, 23870, 23875, 23879, + 23888, 10184, 23899, 23905, 23912, 23920, 23927, 12680, 12694, 23934, + 23941, 23950, 23955, 23960, 23967, 23972, 23977, 8520, 8526, 8532, 23982, + 23987, 23990, 23995, 24003, 24010, 24017, 24024, 24030, 24039, 24048, + 24057, 24063, 24071, 24080, 24084, 24090, 24095, 24105, 24112, 24118, + 24126, 24132, 24139, 24145, 24155, 24164, 24168, 24175, 24179, 24184, + 24190, 24198, 24202, 24212, 16767, 24221, 24227, 24231, 24240, 24249, + 24259, 24265, 16772, 24272, 24279, 24290, 24298, 24308, 24317, 24325, + 9902, 24333, 24338, 24344, 24349, 24353, 24357, 24361, 10923, 24366, + 24374, 24381, 24390, 24398, 24405, 24412, 24421, 24427, 976, 24434, + 24440, 24444, 24450, 24457, 24463, 24471, 24477, 24484, 24490, 24496, + 24505, 24509, 24517, 24526, 24533, 24538, 24542, 24553, 24558, 24563, + 24569, 24574, 24587, 8747, 24591, 24597, 24603, 24609, 24614, 24622, + 24626, 24633, 24642, 24647, 17045, 24655, 24659, 24671, 24676, 24680, + 24683, 24689, 24695, 24701, 24706, 24711, 24715, 24718, 24729, 24734, + 10456, 24741, 24746, 24751, 24756, 24761, 24766, 24771, 24776, 24781, + 10461, 24786, 24791, 24796, 24801, 24806, 24811, 24816, 24821, 24826, + 24831, 24836, 24841, 24847, 24852, 24857, 24862, 24867, 24872, 24877, + 24882, 24887, 24892, 24898, 24904, 24909, 24914, 24919, 24924, 24929, + 24934, 24939, 24944, 24949, 24955, 24960, 24965, 24970, 24976, 24982, + 24987, 24992, 24997, 25002, 25007, 25012, 25017, 25022, 25028, 25033, + 25038, 25043, 25048, 25054, 25059, 25064, 25068, 1284, 145, 25076, 25080, + 25084, 25088, 25093, 25097, 15204, 2346, 25101, 25106, 25110, 25115, + 25119, 25124, 25128, 25134, 25139, 25143, 25147, 25155, 25159, 25163, + 25170, 25175, 25180, 25184, 25190, 25195, 25199, 25204, 25209, 25213, + 25220, 25227, 25234, 25239, 25243, 25247, 25252, 25256, 25259, 25265, + 25278, 25283, 25289, 25298, 25303, 10683, 25308, 25317, 25322, 25325, + 25329, 25334, 25339, 25344, 25349, 25354, 2844, 2849, 25359, 25365, + 25369, 25375, 3800, 25380, 25385, 25390, 25396, 25401, 16138, 25406, + 25411, 25416, 25421, 25427, 25432, 25437, 25443, 25448, 25452, 25457, + 25462, 25467, 25472, 25477, 25481, 25486, 25490, 25495, 25500, 25505, + 25510, 25514, 25519, 25523, 25528, 25533, 25538, 25453, 3045, 25458, + 25543, 25551, 25558, 11017, 25570, 25578, 25588, 25606, 25625, 25634, + 25642, 25463, 25649, 25654, 25662, 25468, 25667, 25672, 25680, 25685, + 25690, 25694, 25473, 25699, 25707, 25712, 25716, 25723, 25729, 25738, + 25742, 25750, 25754, 25757, 25764, 25768, 25772, 25777, 25783, 25790, + 25795, 9929, 25799, 25804, 25809, 25814, 25819, 25824, 1689, 1694, 25829, + 25835, 25841, 25846, 25850, 25854, 25858, 25862, 25866, 25870, 25874, + 25878, 25881, 25887, 25894, 25902, 25908, 25914, 25919, 25924, 25930, + 25934, 25939, 25946, 16044, 16051, 25952, 25964, 25967, 25974, 25978, + 19187, 25985, 25993, 26004, 26013, 26026, 26036, 26050, 26062, 26076, + 26089, 26101, 26111, 26123, 26129, 26135, 26150, 26174, 26192, 26211, + 26224, 26238, 26256, 26272, 26289, 26307, 26318, 26337, 26354, 26374, + 26392, 26404, 26418, 26432, 26444, 26461, 26480, 26498, 26510, 26528, + 26547, 16925, 26560, 26580, 26592, 12117, 26604, 26609, 26614, 26619, + 26628, 26634, 26639, 26643, 26650, 26656, 26660, 26665, 26670, 26675, + 26680, 26685, 26690, 2440, 26695, 26701, 26705, 26708, 26719, 26723, + 26726, 26734, 26740, 14356, 26744, 26753, 26764, 26770, 26776, 26791, + 26800, 26808, 26815, 26820, 26824, 26831, 26837, 26846, 26854, 26861, + 26871, 26880, 26890, 26895, 26904, 26913, 26924, 26935, 26945, 26962, + 4450, 26972, 26976, 26986, 26994, 27004, 27015, 27021, 27026, 27036, + 27044, 27051, 27057, 27064, 27069, 25501, 27073, 27082, 27086, 27089, + 27094, 27102, 27109, 27118, 27126, 27134, 27142, 27152, 27161, 27167, + 27173, 27179, 27183, 25506, 25511, 27187, 27197, 27207, 27217, 27225, + 27232, 27242, 27250, 27258, 27264, 27272, 782, 27281, 17126, 599, 27295, + 27304, 27312, 27323, 27334, 27344, 27353, 27365, 27374, 27383, 27390, + 27396, 27406, 27415, 27424, 27432, 27440, 27450, 27458, 27466, 27472, + 27477, 27482, 27487, 7915, 27492, 27495, 27499, 27504, 27510, 27515, + 27519, 11142, 25524, 25529, 27527, 27533, 27539, 27544, 27549, 27553, + 27561, 27567, 27573, 27577, 3824, 27585, 27590, 27595, 27599, 27603, + 11266, 27610, 27618, 27632, 27639, 27646, 27652, 11275, 11281, 27660, + 27668, 27675, 27680, 27685, 25534, 27691, 27702, 27706, 27711, 2679, + 27716, 27727, 27733, 27738, 27742, 27746, 27749, 27756, 27763, 27769, + 27777, 27784, 27790, 27794, 7955, 27799, 27803, 27807, 27815, 27820, + 27825, 27830, 1717, 27835, 27840, 27845, 27850, 27855, 27860, 27865, + 27870, 27875, 27880, 27885, 27890, 27895, 27900, 27906, 27911, 27916, + 27921, 27926, 27931, 27936, 27942, 27947, 27952, 27957, 27962, 27967, + 27972, 27977, 27983, 27989, 27994, 28000, 28005, 28010, 5, 28016, 28020, + 28024, 28028, 28033, 28037, 28041, 28045, 28049, 28054, 28058, 28063, + 28067, 28070, 28074, 28079, 28083, 28088, 28092, 28096, 28100, 28105, + 28109, 28113, 28123, 28128, 28132, 28136, 28141, 28146, 28155, 28160, + 28165, 28169, 28173, 28182, 28195, 28207, 28216, 28225, 28230, 28236, + 28241, 28245, 28249, 28259, 28268, 28276, 28282, 28287, 28291, 28298, + 28308, 28317, 28325, 12474, 28333, 28341, 28350, 28359, 28367, 28377, + 28382, 28386, 28390, 28393, 28395, 28399, 28403, 28408, 28413, 28417, + 28421, 28424, 28428, 28431, 28435, 28438, 28441, 28445, 28451, 28455, + 28459, 28463, 28467, 28472, 28477, 28482, 28486, 28489, 28494, 28500, + 28505, 28511, 28516, 28520, 28526, 28530, 28534, 28539, 28543, 28548, + 28553, 28557, 28561, 28568, 28572, 28575, 28579, 28583, 28589, 28595, + 28599, 28603, 28608, 28615, 28621, 28625, 28634, 28638, 28642, 28645, + 28651, 28656, 28662, 1417, 1769, 28667, 28672, 28677, 28682, 28687, + 28692, 28697, 2150, 747, 28702, 28705, 28709, 28713, 28718, 28722, 17138, + 28726, 28731, 28736, 28740, 28743, 28748, 28752, 28757, 28761, 17142, + 28766, 28769, 28772, 28778, 28782, 28787, 28791, 28804, 28808, 28811, + 28819, 28828, 28835, 28840, 28846, 28852, 28860, 28867, 28874, 28878, + 28882, 28886, 28891, 28896, 28900, 28908, 28913, 28920, 28932, 28943, + 28948, 28952, 28959, 28963, 28968, 28974, 28977, 28982, 28987, 28994, + 28998, 29002, 29005, 29011, 8642, 2350, 29015, 29020, 29036, 10734, + 29056, 29065, 29081, 29085, 29092, 29095, 29101, 29111, 29117, 29126, + 29141, 29152, 29164, 29175, 29183, 29192, 29198, 29207, 29217, 29227, + 29238, 29249, 29259, 29268, 29275, 29284, 29292, 29299, 29306, 29314, + 29321, 29328, 29341, 29348, 29356, 29363, 29369, 29374, 29383, 29390, + 29396, 29401, 29409, 29417, 29424, 29431, 26996, 29443, 29455, 29469, + 29477, 29485, 29493, 29500, 29512, 29521, 29530, 29538, 29546, 29554, + 29561, 29567, 29576, 29584, 29594, 29603, 29613, 29622, 29631, 29639, + 29644, 29648, 29651, 29655, 29659, 29663, 29667, 29671, 29677, 29683, + 29688, 29696, 17200, 29703, 29708, 29715, 29721, 29728, 17208, 29735, + 29738, 29750, 29758, 29764, 29769, 29773, 29784, 29794, 29804, 11205, + 29813, 29822, 29830, 29840, 29849, 29856, 29863, 29871, 29875, 17219, + 29878, 29885, 29889, 4394, 29895, 29898, 29905, 29911, 29916, 29923, + 29929, 29933, 29938, 29942, 29951, 29958, 29964, 8700, 29971, 29979, + 29986, 29992, 29997, 30003, 30009, 30017, 30023, 30027, 30030, 30032, + 29656, 11218, 30041, 30046, 30052, 30062, 30067, 30074, 30080, 30085, + 30090, 30095, 30099, 30104, 30111, 30117, 30126, 30134, 30138, 30145, + 30151, 30160, 30167, 4648, 30173, 30179, 30184, 30191, 30203, 30214, + 30219, 30223, 30233, 30239, 30243, 30248, 30258, 30267, 30271, 30278, + 30286, 30293, 30299, 30304, 30312, 30319, 30324, 30331, 30343, 30352, + 30356, 15130, 30364, 30374, 30378, 30386, 28815, 30397, 30402, 30406, + 30413, 30420, 25186, 29581, 30425, 30429, 30432, 26324, 30437, 30451, + 30467, 30485, 30504, 30521, 30539, 26343, 30556, 30576, 26360, 30588, + 30600, 18413, 30612, 26380, 30626, 30638, 12130, 30652, 30657, 30662, + 30667, 30673, 30679, 30685, 30689, 30697, 30704, 30709, 30719, 30725, + 11692, 30731, 30733, 30738, 30746, 30750, 30107, 30756, 30763, 13395, + 13405, 30770, 30777, 30787, 30792, 30796, 30799, 30805, 30813, 30825, + 30835, 30851, 30864, 30878, 18431, 30892, 30899, 30903, 30906, 30911, + 30915, 30922, 30929, 30936, 30946, 30951, 30956, 30961, 30969, 30977, + 30982, 30991, 27017, 3485, 30996, 30999, 31002, 31007, 31014, 31019, + 31024, 31040, 31048, 31056, 10498, 31064, 31069, 31073, 31079, 31084, + 31090, 31093, 31099, 31111, 31119, 31126, 31132, 31139, 31150, 31164, + 31177, 31183, 31192, 31198, 31207, 31219, 31230, 31240, 31249, 31258, + 31266, 31277, 8682, 31284, 31291, 31297, 31302, 31308, 31315, 31326, + 31336, 31346, 31355, 31361, 31368, 31373, 31381, 31388, 31396, 31404, + 31416, 6904, 1094, 31423, 31432, 31440, 31446, 31452, 31457, 31461, + 31464, 31470, 31477, 31482, 31487, 31492, 31496, 31508, 31519, 31528, + 31536, 17401, 31541, 31549, 31554, 31562, 31568, 31574, 13388, 9497, + 31579, 31583, 31587, 31590, 31593, 31599, 31607, 31615, 31619, 31623, + 31628, 31632, 31635, 31644, 31649, 31653, 31656, 31664, 31675, 31684, + 31688, 31694, 31700, 31704, 31710, 31718, 31740, 31764, 31775, 31784, + 31790, 31797, 31804, 31810, 31818, 31824, 31829, 31840, 31858, 31865, + 31873, 31877, 31884, 31889, 31898, 31911, 31919, 31931, 31942, 31953, + 31963, 31977, 31986, 31994, 32006, 10751, 32017, 32028, 32039, 32051, + 32061, 32070, 32080, 32085, 32089, 32097, 32108, 32118, 32124, 32129, + 32133, 32136, 32139, 32147, 32155, 32164, 32174, 32183, 32189, 32203, + 2762, 32225, 32236, 32245, 32255, 32267, 32276, 32285, 32295, 32303, + 32311, 32320, 32325, 32336, 32341, 32350, 32356, 32367, 32371, 32374, + 32384, 32393, 32401, 32411, 32421, 32429, 32438, 32445, 32453, 32460, + 32469, 32478, 32483, 32488, 32492, 32500, 32507, 32511, 32519, 32526, + 32537, 32552, 32559, 32565, 32575, 32584, 32590, 32601, 32605, 32612, + 32616, 32623, 32629, 16275, 32635, 32639, 32644, 32650, 32657, 32661, + 32665, 32673, 32681, 32687, 32696, 32703, 32710, 32715, 32720, 32730, + 27071, 32734, 32737, 32742, 32747, 32752, 32757, 32762, 32767, 32772, + 32777, 32783, 32788, 32793, 32799, 1134, 725, 32804, 32811, 32820, 2398, + 32827, 32832, 32836, 32842, 1183, 653, 32847, 311, 32851, 32860, 32868, + 32877, 32885, 32892, 32903, 32911, 32920, 32930, 32938, 32943, 11373, + 32947, 32955, 32963, 32968, 17155, 4008, 32974, 32980, 32986, 6462, + 32991, 32995, 33002, 33008, 33014, 33018, 33024, 33029, 33036, 1376, + 33042, 33049, 33053, 1283, 6470, 33058, 33068, 33076, 33082, 33092, + 33101, 33109, 33115, 33120, 33128, 33135, 12911, 33141, 33148, 33153, + 33160, 33170, 1436, 230, 2149, 33176, 33182, 33189, 33200, 33211, 33219, + 33226, 33236, 33245, 33253, 33262, 33269, 33276, 33289, 33296, 33302, + 33313, 33332, 1188, 33337, 33342, 33350, 3891, 33354, 33359, 33363, + 33367, 1380, 28422, 33377, 33381, 33386, 33390, 33396, 3758, 33402, + 33410, 33417, 33428, 33437, 33445, 33470, 33478, 33483, 3892, 377, 33489, + 33497, 33505, 33512, 33518, 33523, 2218, 12332, 33530, 33536, 29934, + 30209, 33542, 613, 106, 33546, 33550, 33556, 715, 10371, 33561, 33568, + 33574, 33578, 33582, 1581, 33585, 33589, 17669, 33592, 33597, 33604, + 33610, 8713, 33615, 33623, 33630, 33636, 25696, 33640, 33644, 33648, + 33652, 3962, 19497, 33656, 33661, 33665, 33668, 33676, 33684, 33689, + 33698, 33706, 33709, 33716, 33726, 33738, 33746, 33751, 33755, 33763, + 33770, 33776, 33783, 33790, 33793, 33797, 33801, 1391, 33811, 33813, + 33818, 33824, 33830, 33835, 33840, 33845, 33850, 33855, 33860, 33865, + 33870, 33875, 33880, 33885, 33890, 33895, 33900, 33906, 33912, 33918, + 33924, 33929, 33934, 33939, 33945, 33950, 33955, 33960, 33966, 33971, + 33977, 33982, 33987, 33992, 33997, 34003, 34008, 34014, 34019, 34024, + 34029, 34034, 34040, 34045, 34051, 34056, 34061, 34066, 34071, 34076, + 34081, 34086, 34091, 34096, 34102, 34108, 34114, 34119, 34124, 34129, + 34134, 34140, 34146, 34152, 34158, 34164, 34170, 34175, 34181, 34186, + 34191, 34196, 34201, 34207, 2486, 34212, 2493, 2500, 2886, 34217, 2506, + 2516, 34223, 2548, 2553, 2558, 34227, 34232, 34237, 34243, 34248, 34253, + 34257, 34262, 34268, 34273, 34278, 34283, 34289, 34294, 34298, 34302, + 34307, 34312, 34317, 34322, 34327, 34333, 34339, 34344, 34348, 34353, + 34359, 34363, 34368, 34373, 34378, 34383, 34387, 34390, 34395, 34400, + 34405, 34410, 34415, 34421, 34427, 34432, 34437, 34442, 34446, 34451, + 34456, 34461, 34466, 34471, 34476, 34480, 34485, 34490, 34495, 34499, + 34503, 34507, 34512, 34520, 34525, 34530, 34536, 34542, 34548, 34553, + 34561, 34565, 34568, 34573, 34578, 34582, 34587, 34592, 34596, 34601, + 34605, 34608, 34613, 4104, 20257, 34618, 34623, 34628, 34633, 34641, + 24401, 33046, 10010, 34646, 34651, 34655, 34660, 34664, 34668, 34673, + 34677, 34680, 34683, 34687, 34692, 34696, 34704, 34708, 34711, 34716, + 34720, 34724, 34729, 34734, 34738, 34744, 34749, 34754, 34761, 34768, + 34772, 34775, 34781, 34790, 34797, 34805, 34812, 34816, 34821, 34825, + 34829, 34835, 34840, 34846, 34850, 34856, 34861, 34866, 34870, 34877, + 34883, 34889, 34895, 34901, 34908, 34914, 34920, 34926, 34932, 34938, + 34944, 34950, 34957, 34963, 34970, 34976, 34982, 34988, 34994, 35000, + 35006, 35012, 35018, 35024, 35030, 35035, 35040, 13266, 35045, 35051, + 35056, 35061, 35066, 35071, 35074, 35080, 35085, 35093, 35098, 35102, + 35107, 35113, 35122, 35128, 35133, 35138, 35143, 35147, 35152, 35156, + 35161, 35166, 35171, 35176, 35183, 35190, 35196, 35202, 35207, 19116, + 35214, 35220, 35227, 35233, 35239, 35244, 35252, 35257, 10916, 35261, + 35266, 35271, 35277, 35282, 35287, 35291, 35296, 35301, 35307, 35312, + 35317, 35322, 35326, 35331, 35336, 35340, 35345, 35350, 35354, 35359, + 35363, 35368, 35373, 35378, 35382, 35387, 35391, 35396, 35400, 35404, + 35408, 17825, 35413, 35420, 35429, 35435, 35441, 35450, 35458, 35467, + 35475, 35480, 35484, 35491, 35497, 35505, 35509, 35512, 35517, 35521, + 35530, 35538, 35556, 35562, 1435, 35568, 35571, 35575, 25836, 25842, + 35581, 35585, 35596, 35607, 35618, 35630, 35634, 35641, 35648, 35655, + 35660, 35664, 35672, 35677, 35682, 35687, 35692, 6527, 1050, 24400, + 35697, 35702, 35706, 35711, 35715, 35721, 35726, 35732, 35737, 35743, + 35748, 35754, 35759, 35765, 35771, 35777, 35782, 35738, 35744, 35786, + 35791, 35797, 35802, 35808, 35813, 35819, 35824, 35749, 11983, 35828, + 35760, 35766, 35772, 2978, 3672, 35834, 35837, 35842, 35848, 35854, + 35860, 35867, 35873, 35879, 35885, 35891, 35897, 35903, 35909, 35915, + 35921, 35927, 35933, 35939, 35946, 35952, 35958, 35964, 35970, 35976, + 35979, 35984, 35987, 35994, 35999, 36007, 36011, 36016, 36021, 36027, + 36032, 36037, 36041, 36046, 36052, 36057, 36063, 36068, 36074, 36079, + 36085, 36091, 36095, 36100, 36105, 36110, 36115, 36119, 36124, 36129, + 36134, 36140, 36146, 36152, 36158, 36163, 36167, 36170, 36176, 36182, + 36191, 36199, 36206, 36211, 36215, 36219, 36224, 17615, 36229, 36237, + 36243, 4050, 1293, 36248, 36252, 8763, 36258, 36264, 36271, 8772, 36275, + 36281, 36288, 36294, 36303, 36311, 36323, 36327, 36334, 36340, 36345, + 36349, 36353, 36356, 36366, 36375, 36383, 35739, 36388, 36398, 36408, + 36418, 36424, 36429, 36439, 36444, 36457, 36471, 36482, 36494, 36506, + 36520, 36533, 36545, 36557, 16966, 36571, 36576, 36581, 36585, 36589, + 36593, 36597, 36603, 36608, 36613, 36618, 36623, 36628, 36633, 1758, + 31228, 36638, 36643, 35787, 36648, 36651, 36656, 36661, 36666, 36672, + 36678, 18733, 11558, 36683, 36689, 36696, 18365, 36702, 36707, 36712, + 36716, 36721, 36726, 35792, 36731, 36736, 36741, 36747, 35798, 36752, + 36755, 36762, 36770, 36776, 36782, 36788, 36799, 36804, 36811, 36818, + 36825, 36833, 36842, 36851, 36857, 36863, 36871, 35803, 36876, 36882, + 36888, 35809, 36893, 36898, 36906, 36914, 36920, 36927, 36933, 36940, + 36947, 36953, 36961, 36971, 36978, 36984, 36989, 36995, 37000, 37005, + 37012, 37021, 37029, 37034, 37040, 37047, 37055, 37061, 37066, 37072, + 37081, 37088, 32169, 37094, 37098, 37103, 37112, 37117, 37122, 37127, + 14446, 37135, 37140, 37145, 37150, 37154, 37159, 37164, 37171, 37176, + 37181, 37186, 35814, 24329, 37192, 2589, 155, 37195, 37198, 37202, 37206, + 37216, 37224, 37231, 37235, 37239, 37242, 37250, 37257, 37264, 30163, + 37273, 37276, 37282, 37289, 37293, 37301, 37309, 37316, 37320, 37324, + 37327, 37333, 37340, 37344, 37348, 37355, 37363, 37371, 35750, 37378, + 37386, 37391, 37403, 11639, 11646, 11653, 11660, 11667, 11674, 578, 404, + 37409, 37414, 37419, 37425, 37430, 37435, 4071, 37440, 37443, 37448, + 37453, 37458, 37463, 37468, 37475, 25960, 37480, 37485, 37490, 37495, + 37500, 37506, 37511, 37517, 35990, 37523, 37528, 37534, 37540, 37550, + 37555, 37560, 37564, 37569, 37574, 37579, 37584, 37597, 37602, 25574, + 19579, 978, 37606, 37612, 37616, 37621, 37626, 37632, 37637, 37642, + 37646, 37651, 37656, 37662, 37667, 37672, 1298, 37676, 37681, 37686, + 37691, 37695, 37700, 37705, 37710, 37716, 37722, 37727, 37731, 37735, + 37740, 37745, 37750, 37754, 37759, 37767, 37771, 37777, 37781, 37788, + 37797, 19350, 35761, 37803, 37810, 37818, 37825, 37831, 37844, 37856, + 37861, 37867, 37871, 2905, 37875, 37879, 37335, 37888, 37899, 37910, + 37915, 32232, 37920, 37925, 37929, 32352, 25847, 37934, 37938, 37943, + 35767, 24436, 37947, 37952, 37958, 37963, 37967, 37971, 37974, 37978, + 37984, 37993, 38004, 38016, 35773, 38021, 38024, 38028, 38032, 38037, + 38042, 38047, 38052, 38057, 38062, 38067, 38072, 341, 38077, 38082, + 38087, 38092, 38097, 38102, 38108, 38113, 38118, 38124, 38129, 38135, + 38140, 38146, 38151, 38156, 38161, 38166, 38171, 38176, 38181, 38186, + 38192, 38197, 38202, 38207, 38212, 38217, 38222, 38227, 38233, 38239, + 38244, 38249, 38254, 38259, 38264, 38269, 38274, 38279, 38284, 38289, + 38294, 38299, 38304, 38309, 38314, 38319, 38324, 38329, 38339, 38349, + 38355, 331, 9, 38360, 38364, 38368, 38376, 38380, 38384, 38387, 16395, + 38390, 38395, 38399, 38404, 38408, 38413, 38417, 38422, 38426, 38429, + 38431, 38435, 38440, 38444, 38455, 38458, 38460, 38464, 38476, 38488, + 38497, 38501, 38511, 38515, 38521, 38526, 38535, 38541, 38546, 38551, + 38555, 38559, 38564, 38571, 38576, 38582, 38587, 38591, 38598, 29589, + 29599, 38602, 38607, 38612, 38617, 38624, 38628, 38635, 38641, 8918, + 38645, 38654, 38662, 38677, 38691, 38700, 38708, 38719, 38728, 38733, + 38740, 38750, 7924, 38760, 38765, 38770, 38774, 38777, 38782, 38786, + 38791, 38795, 38802, 38807, 38812, 38817, 38827, 38832, 38837, 38842, + 9883, 38847, 38849, 38857, 38860, 38863, 38865, 38869, 38875, 38879, + 38884, 38889, 38907, 38921, 38940, 38957, 38966, 38974, 38979, 38984, + 1428, 38990, 38996, 39001, 39011, 39020, 39028, 39033, 39039, 39044, + 39053, 39062, 39073, 39078, 39085, 39091, 39095, 39104, 39111, 39119, + 39126, 39139, 39147, 39151, 39161, 39166, 39170, 39178, 39186, 39191, + 39195, 39199, 39208, 39214, 39219, 39227, 39237, 39246, 39255, 39264, + 39275, 39283, 39294, 39303, 39311, 39318, 39324, 39329, 39340, 39351, + 39356, 39360, 39363, 39367, 39375, 39381, 39392, 39403, 39414, 39425, + 39436, 39447, 39458, 39469, 39481, 39493, 39505, 39517, 39529, 39541, + 39553, 39562, 39566, 39574, 39580, 39586, 39593, 39599, 39604, 39610, + 39614, 39619, 39624, 39629, 38334, 38344, 2460, 39634, 39636, 39641, + 39646, 39651, 39654, 39656, 39660, 39663, 39670, 39674, 11229, 39678, + 39684, 39694, 39699, 39705, 39709, 39714, 39727, 30057, 39733, 39742, + 39751, 20480, 39758, 39767, 36404, 39775, 39780, 39784, 39793, 39801, + 39808, 39813, 39817, 39822, 39827, 39835, 39839, 39847, 39853, 39859, + 39864, 39869, 39873, 39876, 39881, 39894, 39910, 26450, 39927, 39939, + 39956, 39968, 39982, 26467, 26486, 39994, 40006, 2779, 40020, 40025, + 40030, 40035, 40039, 40046, 40058, 40065, 40074, 40077, 40088, 40099, + 40107, 40112, 40116, 40121, 40126, 40131, 40136, 40141, 40146, 36868, + 927, 40151, 40155, 40159, 40162, 40167, 40172, 40178, 40183, 40188, + 40194, 40200, 40205, 40209, 40214, 40219, 40224, 40228, 40231, 40237, + 40242, 40247, 40252, 40256, 40261, 40267, 40275, 30336, 40280, 40285, + 40292, 40298, 40304, 40309, 40317, 25969, 40324, 40329, 40334, 40339, + 40343, 40346, 40351, 40355, 40359, 40366, 40372, 40378, 40384, 40391, + 40396, 40402, 39181, 40406, 40410, 40415, 40428, 40433, 40439, 40447, + 40454, 40462, 40472, 40478, 40484, 40490, 40494, 40503, 40511, 40518, + 40523, 40528, 12006, 40533, 40543, 40550, 40556, 40566, 40571, 40577, + 40585, 3924, 40592, 40599, 40605, 40612, 3930, 40616, 40621, 40632, + 40639, 40645, 40654, 40658, 4502, 40661, 40668, 40674, 40680, 40688, + 40698, 33513, 40705, 40713, 40719, 40724, 40730, 40735, 40739, 29901, + 40745, 40752, 40758, 40766, 40775, 40782, 40788, 40799, 27269, 40805, + 40815, 40820, 40824, 40832, 40840, 40847, 40853, 40858, 10874, 6502, + 40863, 40867, 40869, 40873, 40878, 40880, 40885, 40891, 40896, 40901, + 40908, 37471, 40914, 40919, 40923, 40928, 40932, 40941, 40945, 40951, + 40958, 40964, 40971, 40976, 40985, 40990, 40994, 40999, 41006, 41014, + 41022, 41027, 24492, 41031, 41034, 41038, 41042, 12429, 944, 41046, + 41051, 41059, 41064, 41068, 41077, 41084, 41088, 41092, 41100, 41107, + 15728, 41117, 41121, 41125, 41133, 41141, 41147, 41152, 41161, 15476, + 41167, 41176, 41183, 41188, 41195, 41202, 41210, 41217, 41225, 41233, + 41242, 41247, 41254, 41261, 41268, 41275, 41282, 41287, 41294, 41300, + 41317, 41325, 41335, 41343, 41350, 439, 41354, 41360, 41364, 41369, + 38724, 41375, 41378, 41382, 41388, 41399, 41407, 3935, 41415, 41421, + 41427, 41437, 41443, 41452, 41461, 41471, 41478, 41484, 41489, 3941, + 3947, 41498, 41505, 41513, 41518, 41522, 41529, 41537, 41544, 41551, + 41557, 41566, 41576, 41582, 41590, 41599, 41606, 41614, 41621, 25249, + 41625, 41632, 41638, 41648, 41657, 41665, 41676, 41680, 41690, 41697, + 41702, 41708, 41715, 41723, 41732, 41741, 41751, 41762, 41769, 41774, + 41781, 3193, 41789, 41795, 41800, 41807, 41813, 41819, 41824, 41837, + 41850, 41863, 41870, 41876, 41884, 41892, 41897, 41901, 41905, 41910, + 41915, 41920, 41925, 41930, 41935, 1397, 41940, 41944, 41948, 41952, + 41956, 41960, 41964, 41968, 41972, 41976, 41980, 41984, 41988, 41992, + 41996, 42000, 42004, 42008, 42012, 42016, 42020, 42024, 42028, 42032, + 42036, 42040, 42044, 42048, 42052, 42056, 42060, 42064, 42068, 42072, + 42076, 42080, 42084, 42088, 42092, 42096, 42100, 42104, 42108, 42112, + 42116, 42120, 42124, 42128, 42132, 42136, 42140, 42144, 42148, 42152, + 42156, 42160, 42164, 42168, 42172, 42176, 42180, 42184, 42188, 42192, + 42196, 42200, 42204, 42208, 42212, 42216, 42220, 42224, 42228, 42232, + 42236, 42240, 42244, 42248, 42252, 42256, 42260, 42264, 42268, 42272, + 42276, 42280, 42284, 42288, 42292, 42296, 42300, 42304, 42308, 42312, + 42316, 42320, 42324, 42328, 42332, 42336, 42340, 42344, 42348, 42352, + 42356, 42360, 42364, 42368, 42372, 42376, 42380, 42384, 42388, 42392, + 42396, 42400, 42404, 42408, 42412, 42416, 42420, 42424, 42428, 42432, + 42436, 42440, 42444, 42448, 42452, 42456, 42460, 42464, 42468, 42472, + 42476, 42480, 42484, 42488, 42492, 42496, 42500, 42504, 42508, 42512, + 42516, 42520, 42524, 42528, 42532, 42536, 42540, 42544, 42548, 42552, + 42557, 42561, 42566, 42570, 42575, 42579, 42584, 42588, 42594, 42599, + 42603, 42608, 42612, 42617, 42621, 42626, 42630, 42635, 42639, 42644, + 42648, 42653, 42657, 42663, 42669, 42674, 42678, 42683, 42687, 42693, + 42698, 42702, 42707, 42711, 42716, 42720, 42726, 42731, 42735, 42740, + 42744, 42749, 42753, 42758, 42762, 42768, 42773, 42777, 42782, 42786, + 42792, 42797, 42801, 42806, 42810, 42815, 42819, 42824, 42828, 42833, + 42837, 42843, 42848, 42852, 42858, 42863, 42867, 42873, 42878, 42882, + 42887, 42891, 42896, 42900, 42906, 42912, 42918, 42924, 42930, 42936, + 42942, 42948, 42953, 42957, 42962, 42966, 42972, 42977, 42981, 42986, + 42990, 42995, 42999, 43004, 43008, 43013, 43017, 43022, 43026, 43031, + 43035, 43041, 43046, 43050, 43055, 43059, 43065, 43071, 43076, 127, 63, + 43080, 43082, 43086, 43090, 43094, 43099, 43103, 43107, 43112, 10787, + 43117, 43123, 1703, 6943, 43129, 43132, 43137, 43141, 43146, 43150, + 43154, 43159, 11790, 43163, 43167, 43171, 571, 43175, 17934, 43180, + 43184, 43189, 43194, 43199, 43203, 43210, 30081, 43216, 43219, 43223, + 43228, 43234, 43238, 43241, 43249, 43255, 43260, 43264, 43267, 43271, + 43277, 43281, 43285, 3723, 3728, 14558, 43288, 43292, 43296, 43300, + 43304, 43312, 43319, 43323, 15426, 43330, 43335, 43349, 43356, 43367, + 361, 43372, 43376, 43382, 43394, 43400, 43406, 43411, 43417, 43421, + 33786, 43430, 43436, 43445, 43449, 43453, 43458, 43464, 43469, 43473, + 43478, 43482, 43486, 43493, 43499, 43504, 43515, 43530, 43545, 43560, + 43576, 43594, 11704, 43608, 43615, 43619, 43622, 43631, 43636, 43640, + 43648, 18568, 43656, 43660, 43670, 43681, 33711, 43694, 43698, 43707, + 43725, 43744, 43753, 43761, 43769, 11069, 11903, 43773, 25859, 43776, + 34700, 43781, 11068, 43786, 43792, 43797, 43803, 43808, 43814, 43819, + 43825, 43830, 43836, 43842, 43848, 43853, 43809, 43815, 43857, 43820, + 43826, 43831, 43862, 43837, 43843, 8931, 4327, 43868, 43876, 43880, + 43883, 43890, 43894, 43899, 43904, 43911, 43917, 43923, 43928, 17247, + 43932, 29918, 43936, 43940, 43944, 43950, 43954, 32103, 43963, 10043, + 43967, 10469, 43970, 43977, 43983, 43987, 13867, 43994, 44000, 44005, + 44012, 44019, 44026, 32872, 8828, 44033, 44040, 44047, 44053, 44058, + 44065, 44076, 44082, 44087, 44092, 44097, 44101, 44106, 44113, 43810, + 44117, 44127, 44136, 44147, 44153, 44161, 44168, 44173, 44178, 44183, + 44188, 44193, 44197, 44201, 44208, 44214, 44222, 2353, 29018, 11806, + 11818, 11823, 11829, 44231, 11834, 11839, 11845, 44236, 44246, 44250, + 11850, 44255, 19777, 44258, 44263, 44267, 40069, 44278, 44283, 44290, + 44297, 44301, 44304, 44312, 11717, 44319, 44322, 44328, 44338, 6554, + 44347, 44352, 44358, 44362, 44370, 44374, 44384, 44390, 44395, 44406, + 44415, 44424, 44433, 44442, 44451, 44460, 44469, 44475, 44481, 44486, + 44492, 44498, 44504, 44509, 44512, 44519, 44525, 44529, 44534, 44541, + 44548, 44552, 44555, 44565, 44578, 44587, 44596, 44607, 44620, 44632, + 44643, 44652, 44663, 44668, 44677, 44682, 11855, 44688, 44695, 44703, + 44708, 44713, 30127, 44717, 44724, 4267, 25, 44728, 44733, 19626, 44737, + 44740, 44743, 32289, 44747, 32881, 44755, 44759, 44763, 44766, 44772, + 44778, 44783, 35838, 44792, 44800, 44806, 44813, 32272, 44817, 32503, + 44821, 44830, 44834, 44842, 44848, 44854, 44859, 44863, 32907, 44869, + 44872, 44880, 44888, 4649, 44894, 44898, 44902, 44907, 44914, 44920, + 44925, 44930, 44934, 44940, 44945, 44951, 4555, 766, 44958, 44962, 44965, + 44977, 44984, 44989, 17807, 44993, 45001, 45009, 45017, 45025, 45032, + 45040, 45048, 45055, 45063, 45071, 45079, 45087, 45095, 45103, 45111, + 45119, 45127, 45135, 45143, 45150, 45158, 45166, 45174, 45182, 45190, + 45198, 45206, 45214, 45222, 45230, 45238, 45246, 45254, 45262, 45270, + 45278, 45286, 45294, 45302, 45309, 45317, 45324, 45332, 45340, 45348, + 45356, 45364, 45372, 45380, 45388, 45399, 25285, 45404, 45407, 45414, + 45418, 45424, 45428, 45434, 45439, 45445, 45450, 45455, 45459, 45463, + 45471, 45476, 45481, 45491, 45497, 45510, 45516, 45522, 45528, 45531, + 45538, 45543, 45549, 45554, 19522, 903, 45559, 45562, 45565, 45568, + 35922, 35928, 45571, 35934, 35947, 35953, 35959, 45577, 35965, 35971, + 45583, 45589, 18, 45597, 45604, 45608, 45612, 45620, 36757, 45624, 45628, + 45635, 45640, 45644, 45649, 45655, 45660, 45666, 45671, 45675, 45679, + 45683, 45688, 45692, 45697, 45701, 45705, 45712, 45717, 45721, 45725, + 45730, 45734, 45739, 45743, 45747, 45752, 45758, 18091, 18096, 45763, + 45767, 45770, 45776, 45780, 45784, 24286, 45789, 45793, 45799, 45806, + 45812, 45817, 38753, 45827, 45832, 45840, 45844, 45847, 36772, 45851, + 4620, 45856, 45861, 45865, 45870, 45874, 45879, 15494, 45890, 45894, + 45897, 45901, 45906, 45910, 45915, 45920, 45924, 45928, 45932, 45935, + 45939, 45942, 45947, 45952, 45957, 45962, 45967, 45972, 8415, 15510, + 45977, 45980, 45986, 45991, 45997, 46002, 46008, 46013, 46019, 46024, + 46030, 46036, 46042, 46047, 46051, 46055, 46062, 46071, 46087, 46103, + 46113, 32179, 46120, 46124, 46129, 46134, 46138, 46142, 41736, 46148, + 46153, 46157, 46164, 46169, 46174, 46178, 46181, 46185, 46191, 31031, + 46195, 24599, 46200, 46207, 46215, 46221, 46228, 46236, 46242, 46246, + 46251, 46257, 46265, 46270, 46274, 46283, 10768, 46291, 46295, 46303, + 46310, 46315, 46320, 46325, 46329, 46332, 46338, 46342, 46345, 46349, + 46356, 46361, 46365, 46371, 46375, 46381, 46386, 46391, 30422, 35985, + 46396, 46405, 46413, 46419, 46431, 46444, 46458, 46465, 46471, 46477, + 46482, 46490, 46493, 46495, 46502, 46509, 46515, 46519, 8414, 46522, + 46526, 46530, 46535, 46539, 46543, 46546, 46550, 46564, 26516, 46583, + 46596, 46609, 46622, 26534, 46637, 2732, 46652, 46658, 46662, 46672, + 46676, 46680, 46685, 46689, 46696, 46701, 46705, 46712, 46718, 46723, + 46729, 46739, 46751, 46762, 46767, 46774, 46778, 46782, 46785, 46793, + 18589, 4039, 46798, 18124, 46811, 46818, 46825, 46831, 46835, 46839, + 46844, 46850, 46855, 46861, 46865, 46869, 46872, 46877, 46881, 46886, + 46891, 46896, 46901, 46906, 46911, 46916, 46921, 46926, 8469, 18135, + 46931, 46935, 46941, 46950, 46955, 46964, 46971, 41572, 46977, 46982, + 46986, 46993, 46998, 47005, 47011, 47015, 47018, 47022, 47027, 2810, + 47034, 47041, 47045, 47048, 47053, 47058, 47064, 47069, 47074, 47078, + 47083, 47093, 47098, 47104, 47109, 44979, 47115, 47121, 47131, 47136, + 47141, 47145, 47150, 7926, 7938, 47155, 47158, 47165, 47171, 47180, 9963, + 39321, 47188, 47192, 47196, 36820, 47204, 47215, 47223, 41784, 47230, + 47235, 47240, 47251, 47258, 47269, 36844, 24616, 47277, 1022, 47282, + 15917, 47288, 32263, 47294, 47299, 47309, 47318, 47325, 47331, 47335, + 47338, 47345, 47351, 47358, 47364, 47374, 47382, 47388, 47394, 47399, + 47403, 47410, 47415, 47421, 47428, 47434, 46531, 47439, 47443, 15959, + 15968, 15977, 15986, 15995, 16024, 620, 16033, 47449, 47454, 47457, + 47463, 47471, 1315, 47476, 47480, 47485, 47490, 47495, 47502, 47508, + 47512, 47517, 47523, 47527, 35995, 47532, 47537, 47546, 47553, 47563, + 47569, 32307, 47586, 47595, 47603, 47609, 47614, 47621, 47627, 47635, + 47644, 47652, 47660, 47666, 47670, 47675, 47683, 33392, 36853, 47689, + 47708, 18492, 47722, 47738, 47752, 47758, 47763, 47768, 47773, 47779, + 36859, 47784, 47787, 47794, 47801, 47810, 47815, 47819, 420, 3100, 47826, + 47831, 47836, 31400, 47624, 47840, 47845, 47853, 47857, 47860, 47865, + 47871, 47877, 47882, 47886, 32380, 47889, 47894, 47898, 47901, 47906, + 47910, 47915, 47920, 47924, 47929, 47933, 47937, 47941, 24282, 24293, + 47946, 47951, 47957, 47962, 47968, 47974, 30987, 47979, 47983, 47986, + 47992, 47997, 48002, 48007, 48012, 48017, 48022, 48027, 48032, 48038, + 48044, 24379, 18795, 48049, 48054, 48059, 48064, 48069, 48074, 48079, + 48084, 450, 68, 36012, 36017, 36022, 36028, 36033, 36038, 48089, 36042, + 48093, 48097, 48101, 36047, 36053, 48115, 36064, 36069, 48123, 48128, + 36075, 48133, 48138, 48147, 48152, 48157, 48166, 48172, 48178, 48184, + 36092, 48197, 48206, 48212, 36096, 48216, 36101, 48221, 36106, 36111, + 48224, 48229, 48233, 48239, 15735, 48246, 15745, 48253, 48258, 36116, + 48262, 48267, 48272, 48277, 48282, 48286, 48291, 48296, 48302, 48307, + 48312, 48318, 48324, 48329, 48333, 48338, 48343, 48348, 48352, 48357, + 48362, 48367, 48373, 48379, 48385, 48390, 48394, 48399, 48403, 36120, + 36125, 36130, 48407, 48411, 48416, 48420, 48432, 36135, 36141, 36147, + 36159, 48438, 29955, 48442, 48447, 48451, 48456, 48463, 48468, 48473, + 48478, 48482, 48486, 48496, 48501, 48506, 48510, 48514, 48517, 48525, + 48530, 36207, 48534, 1407, 48540, 48545, 48551, 48559, 48563, 48572, + 48580, 48584, 48588, 48596, 48602, 48610, 48626, 48630, 48634, 48638, + 48643, 48649, 48664, 36244, 1711, 14075, 48668, 1294, 1309, 48680, 48688, + 48695, 48700, 48707, 48712, 10452, 963, 2575, 11882, 48719, 10350, 48724, + 48727, 48736, 1202, 48741, 46702, 48748, 48757, 48762, 48766, 48774, + 25915, 2631, 48781, 12382, 48791, 48797, 2371, 2381, 48806, 48815, 48825, + 48836, 3508, 39695, 48841, 4234, 4245, 19560, 1207, 48845, 48853, 48860, + 48865, 48869, 48873, 48878, 27530, 47029, 11973, 48886, 48895, 48904, + 48912, 48925, 48932, 48943, 48948, 48961, 48974, 48986, 48998, 49010, + 49021, 49034, 49045, 49056, 49066, 49074, 49082, 49094, 49106, 49117, + 49126, 49134, 49141, 49153, 49160, 49166, 49175, 49181, 49188, 49201, + 49206, 49216, 49221, 49227, 49232, 43984, 49236, 46334, 49243, 49250, + 49258, 49265, 2588, 49272, 49283, 49293, 49302, 49310, 49320, 49328, + 49337, 49347, 49356, 49361, 49367, 49373, 4083, 49384, 49394, 49403, + 49412, 49420, 49430, 49438, 49447, 49452, 49457, 49462, 1636, 47, 49470, + 49478, 49489, 49500, 19181, 49510, 49514, 49521, 49527, 49532, 49536, + 49547, 49557, 49566, 49577, 19599, 19604, 49582, 49591, 49596, 49606, + 49611, 49619, 49627, 49634, 49640, 1598, 259, 49644, 49650, 49655, 49658, + 2119, 2597, 49666, 49670, 49673, 1452, 49679, 16224, 1212, 49684, 49697, + 2721, 2742, 49711, 49723, 49735, 2756, 2773, 2788, 2804, 2821, 49749, + 49761, 2836, 49775, 1218, 1224, 1230, 12253, 49780, 49785, 49790, 49794, + 49809, 49824, 49839, 49854, 49869, 49884, 49899, 49914, 49929, 49944, + 49959, 49974, 49989, 50004, 50019, 50034, 50049, 50064, 50079, 50094, + 50109, 50124, 50139, 50154, 50169, 50184, 50199, 50214, 50229, 50244, + 50259, 50274, 50289, 50304, 50319, 50334, 50349, 50364, 50379, 50394, + 50409, 50424, 50439, 50454, 50469, 50484, 50499, 50514, 50529, 50544, + 50559, 50574, 50589, 50604, 50619, 50634, 50649, 50664, 50679, 50694, + 50709, 50724, 50739, 50754, 50769, 50784, 50799, 50814, 50829, 50844, + 50859, 50874, 50889, 50904, 50919, 50934, 50949, 50964, 50979, 50994, + 51009, 51024, 51039, 51054, 51069, 51084, 51099, 51114, 51129, 51144, + 51159, 51174, 51189, 51204, 51219, 51234, 51249, 51264, 51279, 51294, + 51309, 51324, 51339, 51354, 51369, 51384, 51399, 51414, 51429, 51444, + 51459, 51474, 51489, 51504, 51519, 51534, 51549, 51564, 51579, 51594, + 51609, 51624, 51639, 51654, 51669, 51684, 51699, 51714, 51729, 51744, + 51759, 51774, 51789, 51804, 51819, 51834, 51849, 51864, 51879, 51894, + 51909, 51924, 51939, 51954, 51969, 51984, 51999, 52014, 52029, 52044, + 52059, 52074, 52089, 52104, 52119, 52134, 52149, 52164, 52179, 52194, + 52209, 52224, 52239, 52254, 52269, 52284, 52299, 52314, 52329, 52344, + 52359, 52374, 52389, 52404, 52419, 52434, 52449, 52464, 52479, 52494, + 52509, 52524, 52539, 52554, 52569, 52584, 52599, 52614, 52629, 52644, + 52659, 52674, 52689, 52704, 52719, 52734, 52749, 52764, 52779, 52794, + 52809, 52824, 52839, 52854, 52869, 52884, 52899, 52914, 52929, 52944, + 52959, 52974, 52989, 53004, 53019, 53034, 53049, 53064, 53079, 53094, + 53109, 53124, 53139, 53154, 53169, 53184, 53199, 53214, 53229, 53244, + 53259, 53274, 53289, 53304, 53319, 53334, 53349, 53364, 53379, 53394, + 53409, 53424, 53439, 53454, 53469, 53484, 53499, 53514, 53529, 53544, + 53559, 53574, 53589, 53604, 53619, 53634, 53649, 53664, 53679, 53694, + 53709, 53724, 53739, 53754, 53769, 53784, 53799, 53814, 53829, 53844, + 53859, 53874, 53889, 53904, 53919, 53934, 53949, 53964, 53979, 53994, + 54009, 54024, 54039, 54054, 54069, 54084, 54099, 54114, 54129, 54144, + 54159, 54174, 54189, 54204, 54219, 54234, 54249, 54264, 54279, 54294, + 54309, 54324, 54339, 54354, 54369, 54384, 54399, 54414, 54429, 54444, + 54459, 54474, 54489, 54504, 54519, 54534, 54549, 54564, 54579, 54594, + 54609, 54624, 54639, 54654, 54669, 54684, 54699, 54714, 54729, 54744, + 54759, 54774, 54789, 54804, 54819, 54834, 54849, 54864, 54879, 54894, + 54909, 54924, 54939, 54954, 54969, 54984, 54999, 55014, 55029, 55044, + 55059, 55074, 55089, 55104, 55119, 55134, 55149, 55164, 55179, 55194, + 55209, 55224, 55239, 55254, 55269, 55284, 55299, 55314, 55329, 55344, + 55359, 55374, 55389, 55404, 55419, 55434, 55449, 55464, 55479, 55494, + 55509, 55524, 55539, 55554, 55569, 55584, 55599, 55614, 55629, 55644, + 55659, 55674, 55689, 55704, 55719, 55734, 55749, 55764, 55779, 55794, + 55809, 55824, 55839, 55854, 55869, 55884, 55899, 55914, 55929, 55944, + 55959, 55974, 55989, 56004, 56019, 56034, 56049, 56064, 56079, 56094, + 56109, 56124, 56139, 56154, 56169, 56184, 56199, 56214, 56229, 56244, + 56259, 56274, 56289, 56304, 56319, 56334, 56349, 56364, 56379, 56394, + 56409, 56424, 56439, 56454, 56469, 56484, 56499, 56514, 56529, 56544, + 56559, 56574, 56589, 56604, 56619, 56634, 56649, 56664, 56679, 56694, + 56709, 56724, 56739, 56754, 56769, 56784, 56799, 56814, 56829, 56844, + 56859, 56874, 56889, 56904, 56919, 56934, 56949, 56964, 56979, 56994, + 57009, 57024, 57039, 57054, 57069, 57084, 57099, 57114, 57129, 57144, + 57159, 57174, 57189, 57204, 57219, 57234, 57249, 57264, 57279, 57294, + 57309, 57324, 57339, 57354, 57369, 57384, 57399, 57414, 57429, 57444, + 57459, 57474, 57489, 57504, 57519, 57534, 57549, 57564, 57579, 57594, + 57609, 57625, 57641, 57657, 57673, 57689, 57705, 57721, 57737, 57753, + 57769, 57785, 57801, 57817, 57833, 57849, 57865, 57881, 57897, 57913, + 57929, 57945, 57961, 57977, 57993, 58009, 58025, 58041, 58057, 58073, + 58089, 58105, 58121, 58137, 58153, 58169, 58185, 58201, 58217, 58233, + 58249, 58265, 58281, 58297, 58313, 58329, 58345, 58361, 58377, 58393, + 58409, 58425, 58441, 58457, 58473, 58489, 58505, 58521, 58537, 58553, + 58569, 58585, 58601, 58617, 58633, 58649, 58665, 58681, 58697, 58713, + 58729, 58745, 58761, 58777, 58793, 58809, 58825, 58841, 58857, 58873, + 58889, 58905, 58921, 58937, 58953, 58969, 58985, 59001, 59017, 59033, + 59049, 59065, 59081, 59097, 59113, 59129, 59145, 59161, 59177, 59193, + 59209, 59225, 59241, 59257, 59273, 59289, 59305, 59321, 59337, 59353, + 59369, 59385, 59401, 59417, 59433, 59449, 59465, 59481, 59497, 59513, + 59529, 59545, 59561, 59577, 59593, 59609, 59625, 59641, 59657, 59673, + 59689, 59705, 59721, 59737, 59753, 59769, 59785, 59801, 59817, 59833, + 59849, 59865, 59881, 59897, 59913, 59929, 59945, 59961, 59977, 59993, + 60009, 60025, 60041, 60057, 60073, 60089, 60105, 60121, 60137, 60153, + 60169, 60185, 60201, 60217, 60233, 60249, 60265, 60281, 60297, 60313, + 60329, 60345, 60361, 60377, 60393, 60409, 60425, 60441, 60457, 60473, + 60489, 60505, 60521, 60537, 60553, 60569, 60585, 60601, 60617, 60633, + 60649, 60665, 60681, 60697, 60713, 60729, 60745, 60761, 60777, 60793, + 60809, 60825, 60841, 60857, 60873, 60889, 60905, 60921, 60937, 60953, + 60969, 60985, 61001, 61017, 61033, 61049, 61065, 61081, 61097, 61113, + 61129, 61145, 61161, 61177, 61193, 61209, 61225, 61241, 61257, 61273, + 61289, 61305, 61321, 61337, 61353, 61369, 61385, 61401, 61417, 61433, + 61449, 61465, 61481, 61497, 61513, 61529, 61545, 61561, 61577, 61593, + 61609, 61625, 61641, 61657, 61673, 61689, 61705, 61721, 61737, 61753, + 61769, 61785, 61801, 61817, 61833, 61849, 61865, 61881, 61897, 61913, + 61929, 61945, 61961, 61977, 61993, 62009, 62025, 62041, 62057, 62073, + 62089, 62105, 62121, 62137, 62153, 62169, 62185, 62201, 62217, 62233, + 62249, 62265, 62281, 62297, 62313, 62329, 62345, 62361, 62377, 62393, + 62409, 62425, 62441, 62457, 62473, 62489, 62505, 62521, 62537, 62553, + 62569, 62585, 62601, 62617, 62633, 62649, 62665, 62681, 62697, 62713, + 62729, 62745, 62761, 62777, 62793, 62809, 62825, 62841, 62857, 62873, + 62889, 62905, 62921, 62937, 62953, 62969, 62985, 63001, 63017, 63033, + 63049, 63065, 63081, 63097, 63113, 63129, 63145, 63161, 63177, 63193, + 63209, 63225, 63241, 63257, 63273, 63289, 63305, 63321, 63337, 63353, + 63369, 63385, 63401, 63417, 63433, 63449, 63465, 63481, 63497, 63513, + 63529, 63545, 63561, 63577, 63593, 63609, 63625, 63641, 63657, 63673, + 63689, 63705, 63721, 63737, 63753, 63769, 63785, 63801, 63817, 63833, + 63849, 63865, 63881, 63897, 63913, 63929, 63945, 63961, 63977, 63993, + 64009, 64025, 64041, 64057, 64073, 64089, 64105, 64121, 64137, 64153, + 64169, 64185, 64201, 64217, 64233, 64249, 64265, 64281, 64297, 64313, + 64329, 64345, 64361, 64377, 64393, 64409, 64425, 64441, 64457, 64473, + 64489, 64505, 64521, 64537, 64553, 64569, 64585, 64601, 64617, 64633, + 64649, 64665, 64681, 64697, 64713, 64729, 64745, 64761, 64777, 64793, + 64809, 64825, 64841, 64857, 64873, 64889, 64905, 64921, 64937, 64953, + 64969, 64985, 65001, 65017, 65033, 65049, 65065, 65081, 65097, 65113, + 65129, 65145, 65161, 65177, 65193, 65209, 65225, 65241, 65257, 65273, + 65289, 65305, 65321, 65337, 65353, 65369, 65385, 65401, 65417, 65433, + 65449, 65465, 65481, 65497, 65513, 65529, 65545, 65561, 65577, 65593, + 65609, 65625, 65641, 65657, 65673, 65689, 65705, 65721, 65737, 65753, + 65769, 65785, 65801, 65817, 65833, 65849, 65865, 65881, 65897, 65913, + 65929, 65945, 65961, 65977, 65993, 66009, 66025, 66041, 66057, 66073, + 66089, 66105, 66121, 66137, 66153, 66169, 66185, 66201, 66217, 66233, + 66249, 66265, 66281, 66290, 66305, 17090, 66314, 66319, 66325, 66331, + 66341, 66349, 17343, 18025, 11298, 66362, 1460, 1464, 66370, 4163, 31515, + 7863, 66376, 66381, 66386, 66391, 66396, 66402, 66407, 66413, 66418, + 66424, 66429, 66434, 66439, 66444, 66450, 66455, 66460, 66465, 66470, + 66475, 66480, 66485, 66491, 66496, 66502, 66509, 2635, 66514, 66520, + 9347, 66524, 66529, 66536, 66544, 4174, 4179, 4184, 4189, 65, 66548, + 66554, 66559, 66564, 66568, 66573, 66577, 66581, 12325, 66585, 66595, + 66608, 66619, 66632, 66639, 66645, 66653, 11807, 66660, 66665, 66671, + 66677, 66683, 66688, 66693, 66698, 66703, 66707, 66712, 66717, 66722, + 66728, 66734, 66740, 66745, 66749, 66754, 66759, 66763, 66768, 66773, + 66778, 66782, 12341, 12352, 12357, 1503, 66786, 66792, 1508, 19026, + 66797, 19035, 66802, 66808, 66813, 1539, 66819, 1545, 1551, 12387, 66824, + 66833, 66841, 66849, 66856, 66860, 66864, 66870, 66875, 35651, 66880, + 66887, 66894, 66899, 66903, 66907, 66916, 66921, 66926, 66931, 1556, 264, + 66936, 66940, 19161, 984, 66944, 66951, 66956, 66960, 19197, 1560, 44141, + 66963, 66968, 66978, 66987, 66992, 66996, 67002, 1565, 46983, 67007, + 67016, 67022, 67027, 67032, 12626, 12632, 67038, 67050, 67067, 67084, + 67101, 67118, 67135, 67152, 67169, 67186, 67203, 67220, 67237, 67254, + 67271, 67288, 67305, 67322, 67339, 67356, 67373, 67390, 67407, 67424, + 67441, 67458, 67475, 67492, 67509, 67526, 67543, 67560, 67577, 67594, + 67611, 67628, 67645, 67662, 67679, 67696, 67713, 67730, 67747, 67764, + 67781, 67798, 67815, 67832, 67849, 67866, 67883, 67894, 67904, 67909, + 1570, 67913, 67918, 67924, 67929, 67934, 67941, 10369, 1575, 67947, + 67956, 31894, 67961, 67972, 12643, 67982, 67987, 67993, 67998, 68005, + 68011, 68016, 1580, 19491, 68021, 68027, 12653, 68033, 68038, 68043, + 68048, 68053, 68058, 68063, 68068, 1585, 4638, 68073, 68078, 68084, + 68089, 68094, 68099, 68104, 68109, 68114, 68119, 68124, 68130, 68136, + 68142, 68147, 68151, 68156, 68161, 68165, 68170, 68175, 68180, 68185, + 68189, 68194, 68200, 68205, 68210, 68214, 68219, 68224, 68230, 68235, + 68240, 68246, 68252, 68257, 68261, 68266, 68271, 68276, 68280, 68285, + 68290, 68295, 68301, 68307, 68312, 68316, 68320, 68325, 68330, 68335, + 33586, 68339, 68344, 68349, 68355, 68360, 68365, 68369, 68374, 68379, + 68385, 68390, 68395, 68401, 68407, 68412, 68416, 68421, 68426, 68430, + 68435, 68440, 68445, 68451, 68457, 68462, 68466, 68471, 68476, 68480, + 68485, 68490, 68495, 68500, 68504, 68507, 68510, 68515, 68520, 36371, + 68527, 68535, 68541, 3840, 31837, 68554, 68561, 68567, 68573, 4014, + 68578, 12795, 68584, 68594, 68609, 68617, 12800, 68628, 68633, 68644, + 68656, 68668, 68680, 2827, 68692, 68697, 68709, 68713, 68719, 68725, + 68730, 68739, 68746, 68751, 68756, 68761, 68766, 68771, 68776, 1602, + 18664, 68781, 68786, 47049, 68790, 68794, 68799, 68803, 19639, 68808, + 68811, 68816, 68824, 68832, 1606, 12836, 12842, 1611, 68840, 68847, + 68852, 68861, 68871, 68878, 68883, 68888, 1616, 68895, 68900, 19759, + 68904, 68909, 68916, 68922, 68926, 68939, 68945, 68956, 68966, 68973, + 19781, 10263, 10270, 4248, 4254, 68980, 1621, 68985, 68994, 69000, 69008, + 69015, 69021, 69028, 69040, 69046, 69051, 69058, 69070, 69081, 69090, + 69100, 69110, 4142, 69118, 35445, 35454, 19821, 69131, 69136, 69141, + 69146, 69151, 69156, 69161, 1626, 1630, 69166, 69170, 69173, 69184, + 69189, 1640, 69197, 69202, 69207, 19880, 69219, 69222, 69228, 69234, + 69239, 69247, 1645, 69252, 69257, 69265, 69273, 69280, 69289, 69297, + 69306, 69310, 1650, 69319, 1655, 24467, 69324, 69331, 69337, 19967, + 69345, 69355, 69361, 69366, 69374, 69381, 69390, 69398, 69408, 69417, + 69427, 69436, 69447, 69457, 69467, 69476, 69486, 69500, 69513, 69522, + 69530, 69540, 69549, 69561, 69572, 69583, 69593, 19259, 69598, 12988, + 69607, 69613, 69618, 69625, 69632, 69638, 18870, 69648, 69654, 69659, + 69670, 69677, 69684, 69689, 69697, 13005, 13010, 69705, 69711, 69715, + 4232, 4243, 20043, 47137, 69723, 69729, 69734, 69742, 69749, 14056, + 69754, 69760, 69766, 1666, 69771, 69774, 69780, 69785, 69790, 69795, + 69800, 69805, 69810, 69815, 69820, 69826, 69832, 1373, 69837, 69842, + 69847, 69853, 69858, 69863, 69868, 69873, 69878, 69883, 1675, 13, 69889, + 69893, 69898, 69902, 69906, 69910, 36652, 69915, 26735, 69920, 69925, + 69929, 69932, 69936, 69940, 69945, 69949, 69954, 69958, 69964, 40163, + 40168, 40173, 69967, 69974, 69980, 69988, 46755, 69998, 40179, 36916, + 36667, 36673, 40195, 36679, 70003, 70008, 70012, 36949, 70019, 70022, + 70026, 70034, 70041, 70046, 70049, 70054, 70059, 70063, 70067, 70070, + 70080, 70092, 70099, 70105, 36684, 70112, 38567, 70115, 9364, 1108, + 70118, 70122, 70127, 4057, 70131, 70134, 15778, 70141, 70148, 70161, + 70169, 70178, 70187, 70193, 70198, 70208, 70221, 70233, 70240, 70245, + 70254, 70267, 41831, 70285, 70290, 70297, 70303, 70308, 844, 70313, + 70321, 70328, 70335, 31341, 866, 70341, 70347, 70357, 70365, 70371, + 70376, 36703, 6637, 36717, 70380, 70390, 70395, 70403, 70413, 70428, + 70434, 70440, 36727, 70445, 35793, 70449, 70454, 70461, 70466, 70470, + 70475, 70483, 19824, 70490, 70495, 70499, 6678, 36753, 70503, 70509, 330, + 70519, 70526, 70533, 70539, 70546, 70551, 70560, 15409, 66972, 66982, + 70566, 70574, 70578, 70582, 70586, 70590, 70595, 70599, 70605, 70613, + 70618, 70623, 70630, 70635, 70639, 70644, 70648, 70652, 70658, 70664, + 70669, 70673, 70678, 70682, 36877, 70686, 36883, 36889, 70691, 70697, + 70704, 70709, 70713, 35810, 19478, 70716, 70720, 70725, 70732, 70738, + 70742, 70747, 46351, 70753, 70757, 70764, 70768, 70773, 70779, 70785, + 70791, 70803, 70812, 70822, 70828, 70835, 70840, 70845, 70849, 70852, + 70858, 70865, 70870, 70875, 70882, 70889, 70896, 70902, 70907, 70912, + 70920, 36894, 2465, 70925, 70930, 70936, 70941, 70947, 70952, 70957, + 70962, 70968, 36915, 70973, 70979, 70985, 70991, 36985, 70996, 71001, + 71006, 36996, 71011, 71016, 71021, 71027, 71033, 37001, 71038, 71043, + 71048, 37056, 37062, 71053, 71058, 37067, 37089, 32170, 37095, 37099, + 71063, 13757, 71067, 71075, 71081, 71089, 71096, 71102, 71112, 71118, + 71125, 12225, 37113, 71131, 71144, 71153, 71159, 71168, 71174, 71180, + 71187, 27078, 71195, 71202, 71212, 71220, 71223, 37057, 71228, 71235, + 71240, 71244, 71248, 71253, 71257, 4371, 71262, 71267, 71272, 40257, + 40262, 71276, 40276, 71281, 40281, 71286, 71292, 40293, 40299, 40305, + 71297, 71303, 25970, 71314, 71317, 71329, 71337, 37136, 71341, 71350, + 71360, 71369, 37146, 71374, 71381, 71390, 71396, 71404, 71411, 71418, + 6729, 4978, 71423, 37068, 71429, 71432, 71438, 71445, 71450, 71455, + 26982, 71459, 71465, 71471, 71476, 71481, 71485, 71491, 71497, 38451, + 71502, 41446, 43251, 43257, 37177, 37182, 71506, 71510, 71514, 71517, + 71530, 71536, 71540, 71543, 71548, 38820, 71552, 35815, 24408, 71558, + 6658, 6666, 10069, 71561, 71566, 71571, 71576, 71581, 71586, 71591, + 71596, 71601, 71606, 71612, 71617, 71622, 71628, 71633, 71638, 71643, + 71648, 71653, 71658, 71664, 71669, 71675, 71680, 71685, 71690, 71695, + 71700, 71705, 71710, 71715, 71720, 71725, 71731, 71736, 71741, 71746, + 71751, 71756, 71761, 71767, 71772, 71777, 71782, 71787, 71792, 71797, + 71802, 71807, 71812, 71818, 71823, 71828, 71833, 71838, 71844, 71850, + 71855, 71861, 71866, 71871, 71876, 71881, 71886, 1453, 156, 71891, 71895, + 71899, 71903, 28871, 71907, 71911, 71916, 71920, 71925, 71929, 71934, + 71939, 71944, 71948, 71952, 71957, 71961, 15488, 71966, 71970, 71977, + 71987, 17688, 71996, 72005, 72009, 72014, 72019, 72023, 72027, 28659, + 3183, 72031, 72037, 20325, 72041, 72050, 72058, 72064, 72069, 72081, + 72093, 72098, 72102, 72107, 72111, 72117, 72123, 72128, 72138, 72148, + 72154, 72162, 72167, 72171, 72177, 72182, 72189, 72195, 72200, 72209, + 72218, 72222, 18204, 72225, 72234, 72242, 72254, 72265, 72276, 72285, + 72289, 72298, 72306, 72316, 72324, 72331, 72341, 72347, 72352, 72359, + 72368, 72374, 72379, 72386, 72392, 72403, 60, 35588, 72409, 30253, 30263, + 72415, 72423, 72430, 72436, 72440, 72450, 72461, 72469, 72478, 72483, + 72488, 72493, 72497, 72501, 20272, 72509, 72513, 72519, 72529, 72536, + 72542, 72548, 40356, 72552, 72554, 72557, 72563, 72567, 72578, 72588, + 72594, 72601, 72608, 15425, 72616, 72622, 72631, 72640, 72646, 11169, + 72652, 72658, 72663, 72668, 72675, 72680, 72687, 72693, 72698, 72706, + 72719, 72728, 72737, 69462, 69472, 72747, 72753, 72762, 72768, 72774, + 72781, 72788, 72795, 72802, 72809, 72814, 72818, 72822, 72825, 72835, + 72839, 72851, 9733, 72860, 72871, 72876, 72880, 69481, 72886, 72893, + 72902, 72910, 72918, 72923, 72927, 72932, 72937, 72947, 72955, 72967, + 72972, 72976, 72980, 72986, 72994, 73001, 73013, 73021, 73032, 73039, + 73045, 73055, 73061, 73065, 73074, 73083, 73090, 73096, 73101, 73105, + 73109, 73113, 73122, 73131, 73140, 73146, 73152, 73158, 73163, 73170, + 73176, 73184, 73191, 73197, 14520, 73202, 73208, 73212, 16579, 73216, + 73221, 73231, 73236, 73245, 73251, 73257, 73265, 73272, 73276, 73280, + 73287, 73293, 73301, 73308, 73314, 73325, 73329, 73333, 73337, 73340, + 73346, 73351, 73356, 73360, 73364, 73373, 73381, 73388, 73394, 73401, + 27708, 46480, 73406, 73414, 73418, 73422, 73425, 73433, 73440, 73446, + 73455, 73463, 73469, 73474, 73478, 73483, 73488, 73492, 73496, 73500, + 73505, 73514, 73518, 73525, 43360, 73529, 73535, 73543, 73547, 73553, + 73561, 73567, 73572, 73583, 73591, 73597, 73606, 26117, 73614, 73621, + 73628, 73635, 73642, 73649, 49969, 15240, 73656, 73663, 73668, 40392, + 4603, 73674, 73679, 73684, 73690, 73696, 73702, 73707, 73712, 73717, + 73722, 73728, 73733, 73739, 73744, 73750, 73755, 73760, 73765, 73770, + 73775, 73780, 73785, 73791, 73796, 73802, 73807, 73812, 73817, 73822, + 73827, 73832, 73838, 73843, 73848, 73853, 73858, 73863, 73868, 73873, + 73878, 73883, 73888, 73894, 73899, 73904, 73909, 73914, 73919, 73924, + 73929, 73934, 73940, 73945, 73950, 73955, 73960, 73965, 73970, 73975, + 73980, 73985, 73990, 73995, 74000, 74006, 1830, 282, 74011, 44259, 74015, + 74018, 74023, 74027, 74030, 3554, 74035, 74040, 74044, 74053, 74064, + 74081, 74099, 74107, 72914, 74114, 74117, 74127, 74134, 74143, 74159, + 74168, 74178, 74183, 74196, 74206, 74215, 74223, 74237, 74245, 74254, + 74258, 74261, 74268, 74274, 74285, 74292, 74304, 74315, 74326, 74335, + 74342, 1213, 772, 74352, 2668, 74356, 74361, 74370, 1013, 8806, 23861, + 74378, 74386, 74400, 74413, 74417, 74422, 74427, 74432, 74438, 74444, + 74449, 9356, 17731, 74454, 74458, 74466, 9793, 74471, 74477, 74486, + 74494, 1683, 12849, 1023, 4286, 74498, 74502, 74511, 74521, 2419, 31065, + 74530, 74536, 19731, 31080, 74542, 4451, 13231, 74548, 74555, 69179, + 74559, 74563, 74569, 74574, 74579, 3773, 160, 3799, 74584, 74596, 74600, + 74604, 74610, 74615, 31914, 74619, 13219, 2862, 4, 74624, 74634, 74645, + 74656, 74666, 74672, 74683, 74690, 74696, 74702, 74710, 74717, 74723, + 74733, 74743, 74753, 74762, 27065, 1225, 74767, 74771, 74775, 74781, + 74785, 2885, 2891, 9353, 2274, 74789, 74793, 74802, 74810, 74821, 74829, + 74837, 74843, 74848, 74859, 74870, 74878, 74884, 74889, 10978, 74899, + 74907, 74911, 74915, 74920, 74924, 74936, 32363, 17633, 74943, 74953, + 74959, 74965, 7739, 11080, 74975, 74986, 74997, 75007, 75016, 75020, + 75027, 1015, 1095, 75037, 75042, 75050, 68905, 75058, 75063, 75074, + 75081, 75095, 16388, 504, 75105, 75112, 75116, 75120, 75128, 75137, + 75145, 19776, 75151, 75165, 75172, 75178, 75186, 75195, 75202, 75212, + 75220, 75227, 75235, 75242, 4250, 116, 75250, 75261, 75265, 75277, 75283, + 13427, 204, 75288, 10401, 75293, 2930, 75297, 75304, 75310, 75321, 75331, + 75339, 75346, 9744, 75353, 75362, 75370, 4331, 75383, 4348, 75387, 75392, + 75398, 75403, 75408, 75413, 2935, 540, 75419, 75432, 75436, 75441, 2940, + 1829, 892, 75445, 4352, 75453, 75459, 75463, 783, 75473, 75482, 75487, + 3790, 75491, 17382, 17389, 53331, 75495, 4383, 4260, 15118, 75503, 75510, + 75515, 27129, 75519, 75526, 75532, 75537, 75542, 17402, 192, 75547, + 75559, 75565, 75573, 2952, 1720, 75581, 75583, 75588, 75593, 75598, + 75604, 75609, 75614, 75619, 75624, 75629, 75634, 75640, 75645, 75650, + 75655, 75660, 75665, 75670, 75675, 75680, 75686, 75691, 75696, 75701, + 75707, 75712, 75718, 75723, 75728, 75733, 75738, 75743, 75748, 75753, + 75759, 75764, 75770, 75775, 75780, 75785, 75790, 75795, 75800, 75805, + 75810, 9425, 9438, 4399, 4404, 4409, 4414, 26, 75816, 75822, 75827, + 75832, 75837, 75843, 75848, 75852, 75856, 75861, 75867, 75871, 75877, + 75882, 75887, 75893, 75898, 75902, 75907, 75912, 75916, 75919, 75921, + 75925, 75928, 75935, 75940, 75944, 75949, 75953, 75957, 75961, 75970, + 75974, 37410, 75977, 37415, 75984, 75989, 37420, 75998, 76007, 37426, + 76012, 37431, 76021, 76026, 13470, 76030, 76035, 76040, 37436, 76044, + 76053, 48174, 76057, 76060, 76064, 9024, 76070, 76073, 76078, 76083, + 76087, 4072, 37441, 76090, 76094, 76097, 76108, 76113, 76117, 76123, + 76131, 76144, 76148, 76156, 76165, 76171, 76176, 76182, 76186, 76192, + 76198, 76206, 76211, 76215, 76222, 76228, 76236, 76245, 76253, 37444, + 76260, 76270, 76279, 76287, 76298, 76311, 76316, 76321, 76325, 76334, + 76340, 76347, 76360, 76372, 76383, 76395, 76402, 76411, 76420, 76429, + 76436, 76442, 76449, 76457, 76464, 76472, 76481, 76489, 76496, 76504, + 76513, 76521, 76530, 76540, 76549, 76557, 76564, 76572, 76581, 76589, + 76598, 76608, 76617, 76625, 76634, 76644, 76653, 76663, 76674, 76684, + 76693, 76701, 76708, 76716, 76725, 76733, 76742, 76752, 76761, 76769, + 76778, 76788, 76797, 76807, 76818, 76828, 76837, 76845, 76854, 76864, + 76873, 76883, 76894, 76904, 76913, 76923, 76934, 76944, 76955, 76967, + 76978, 76988, 76997, 77005, 77012, 77020, 77029, 77037, 77046, 77056, + 77065, 77073, 77082, 77092, 77101, 77111, 77122, 77132, 77141, 77149, + 77158, 77168, 77177, 77187, 77198, 77208, 77217, 77227, 77238, 77248, + 77259, 77271, 77282, 77292, 77301, 77309, 77318, 77328, 77337, 77347, + 77358, 77368, 77377, 77387, 77398, 77408, 77419, 77431, 77442, 77452, + 77461, 77471, 77482, 77492, 77503, 77515, 77526, 77536, 77547, 77559, + 77570, 77582, 77595, 77607, 77618, 77628, 77637, 77645, 77652, 77660, + 77669, 77677, 77686, 77696, 77705, 77713, 77722, 77732, 77741, 77751, + 77762, 77772, 77781, 77789, 77798, 77808, 77817, 77827, 77838, 77848, + 77857, 77867, 77878, 77888, 77899, 77911, 77922, 77932, 77941, 77949, + 77958, 77968, 77977, 77987, 77998, 78008, 78017, 78027, 78038, 78048, + 78059, 78071, 78082, 78092, 78101, 78111, 78122, 78132, 78143, 78155, + 78166, 78176, 78187, 78199, 78210, 78222, 78235, 78247, 78258, 78268, + 78277, 78285, 78294, 78304, 78313, 78323, 78334, 78344, 78353, 78363, + 78374, 78384, 78395, 78407, 78418, 78428, 78437, 78447, 78458, 78468, + 78479, 78491, 78502, 78512, 78523, 78535, 78546, 78558, 78571, 78583, + 78594, 78604, 78613, 78623, 78634, 78644, 78655, 78667, 78678, 78688, + 78699, 78711, 78722, 78734, 78747, 78759, 78770, 78780, 78791, 78803, + 78814, 78826, 78839, 78851, 78862, 78874, 78887, 78899, 78912, 78926, + 78939, 78951, 78962, 78972, 78981, 78989, 78996, 79001, 79005, 8837, + 79012, 79017, 37454, 79023, 79028, 37459, 79034, 23983, 29818, 79039, + 79045, 79053, 79059, 79065, 79072, 79079, 79084, 79089, 79093, 79098, + 79102, 79105, 79109, 79118, 79127, 79135, 79141, 79153, 79164, 79168, + 3245, 8812, 79173, 79176, 79179, 79181, 79185, 79189, 79193, 79199, + 79204, 29881, 79209, 79213, 79216, 79221, 79225, 79232, 79238, 79242, + 6822, 79246, 79251, 37481, 79255, 79262, 79271, 79279, 79285, 79296, + 79304, 79313, 79321, 79328, 79335, 79341, 79352, 37486, 79357, 79368, + 79380, 79388, 79399, 79408, 79416, 79427, 79432, 79440, 2630, 79445, + 39762, 79458, 79462, 79474, 79482, 79487, 79495, 79506, 20490, 79515, + 79521, 79528, 79536, 79542, 37496, 79547, 4377, 66345, 79554, 79557, + 79565, 79578, 79591, 79604, 79617, 79624, 79635, 79644, 79649, 49786, + 49791, 79653, 79657, 79665, 79672, 79681, 79689, 79695, 79704, 79712, + 79719, 79727, 79731, 79740, 79749, 79759, 79772, 79785, 79795, 37501, + 79801, 79808, 79814, 79820, 37507, 79825, 79828, 79832, 79840, 79849, + 49569, 79857, 79866, 79874, 79881, 79889, 79899, 79908, 79917, 38949, + 79926, 79937, 79952, 79962, 10434, 24737, 79971, 79976, 79981, 79985, + 18862, 79990, 79995, 80001, 80006, 80011, 80017, 80022, 80027, 24697, + 80032, 80039, 80047, 80055, 80063, 80068, 80075, 80082, 80087, 1738, + 80091, 80095, 80103, 80111, 37524, 80117, 80123, 80135, 80141, 80148, + 80152, 80159, 80164, 80171, 80177, 80184, 80195, 80205, 80215, 80227, + 80233, 80241, 80247, 80257, 80267, 37551, 80276, 80285, 80291, 80303, + 80314, 80321, 80326, 80330, 80338, 80344, 80349, 80354, 80361, 80369, + 80381, 80391, 80400, 80409, 80417, 80424, 39595, 27496, 80430, 80435, + 80439, 80443, 80448, 80456, 80462, 80473, 80486, 80491, 80498, 37556, + 80503, 80515, 80524, 80532, 80542, 80553, 80566, 80573, 80582, 80591, + 80599, 80604, 80610, 80614, 1442, 80619, 80624, 80629, 80634, 80640, + 80645, 80650, 80656, 80662, 80667, 80671, 80676, 80681, 80686, 66912, + 80691, 80696, 80701, 80706, 80712, 80718, 80723, 80727, 80732, 18861, + 80737, 80743, 80748, 80754, 80759, 80764, 80769, 80774, 80778, 80784, + 80789, 80798, 80803, 80808, 80813, 80818, 80822, 80829, 80835, 4707, + 20088, 3210, 80840, 80844, 80849, 80853, 80857, 80861, 53586, 80865, + 80790, 80867, 80877, 37565, 80880, 80885, 80894, 80900, 6791, 37570, + 80904, 80910, 80915, 80921, 80926, 80930, 80937, 80942, 80952, 80961, + 80965, 80971, 80977, 80983, 80987, 80995, 81002, 81010, 81018, 37575, + 81025, 81028, 81039, 81046, 81052, 81057, 81061, 81067, 81075, 81082, + 81087, 81091, 81100, 81108, 81114, 81119, 37580, 81126, 26955, 81138, + 81144, 81149, 81155, 81162, 81168, 24430, 31538, 81174, 81179, 81185, + 81189, 81201, 80823, 80830, 24629, 81211, 81216, 81223, 81229, 81236, + 81242, 81253, 81258, 81266, 10139, 81271, 81274, 81280, 81284, 81288, + 81291, 81297, 81303, 37297, 4708, 1457, 15537, 81310, 81316, 81322, + 81328, 81334, 81340, 81346, 81352, 81358, 81363, 81368, 81373, 81378, + 81383, 81388, 81393, 81398, 81403, 81408, 81413, 81418, 81423, 81429, + 81434, 81439, 81445, 81450, 81455, 81461, 81467, 81473, 81479, 81485, + 81491, 81497, 81503, 81509, 81514, 81519, 81525, 81530, 81535, 81541, + 81546, 81551, 81556, 81561, 81566, 81571, 81576, 81581, 81586, 81591, + 81596, 81601, 81607, 81612, 81617, 81622, 81628, 81633, 81638, 81643, + 81648, 81654, 81659, 81664, 81669, 81674, 81679, 81684, 81689, 81694, + 81699, 81704, 81709, 81714, 81719, 81724, 81729, 81734, 81739, 81744, + 81749, 81755, 81760, 81765, 81770, 81775, 81780, 81785, 81790, 979, 169, + 81795, 81799, 81803, 81808, 81816, 81820, 81827, 81835, 81839, 81852, + 81860, 81865, 81870, 30316, 81874, 81879, 81883, 81888, 81892, 81900, + 81904, 23991, 81909, 81913, 69719, 81917, 81920, 81928, 81936, 81944, + 81949, 81954, 81961, 81968, 81974, 81980, 81985, 81992, 81997, 82005, + 74405, 82012, 82017, 69491, 82024, 82029, 82033, 82040, 82046, 82053, + 69518, 13542, 82061, 82066, 82071, 82075, 82078, 82089, 82098, 82104, + 82109, 82113, 82123, 82132, 47965, 82136, 82140, 82147, 82160, 82166, + 82174, 82183, 82194, 82205, 82216, 82227, 82236, 82242, 82251, 82259, + 82269, 82282, 82290, 82297, 82308, 82314, 82319, 82324, 82330, 82340, + 82346, 82356, 82364, 82371, 82381, 82390, 80505, 82398, 82404, 82412, + 82418, 72959, 82425, 82430, 82433, 82437, 82443, 82447, 82450, 82458, + 82464, 82470, 82478, 82490, 82502, 82509, 82514, 82518, 82529, 82537, + 82544, 82556, 82564, 82571, 82579, 82586, 82592, 82597, 82607, 82616, + 82624, 82629, 82639, 82648, 48830, 82655, 82659, 82664, 82672, 82679, + 82685, 82689, 82699, 82710, 82718, 82725, 82737, 82749, 82758, 79448, + 82765, 82775, 82787, 82798, 82812, 82820, 82830, 82837, 82845, 82858, + 82870, 82879, 82887, 82897, 82908, 82920, 82929, 82939, 82949, 82958, + 82965, 82974, 82989, 82997, 83007, 83016, 83024, 83037, 66315, 83052, + 83062, 83071, 83083, 83093, 83105, 83116, 83130, 83144, 83158, 83172, + 83186, 83200, 83214, 83228, 83242, 83256, 83270, 83284, 83298, 83312, + 83326, 83340, 83354, 83368, 83382, 83396, 83410, 83424, 83438, 83452, + 83466, 83480, 83494, 83508, 83522, 83536, 83550, 83564, 83578, 83592, + 83606, 83620, 83634, 83648, 83662, 83676, 83690, 83704, 83718, 83732, + 83746, 83760, 83774, 83788, 83802, 83816, 83830, 83844, 83858, 83872, + 83886, 83900, 83914, 83928, 83942, 83956, 83970, 83984, 83998, 84012, + 84026, 84040, 84054, 84068, 84082, 84096, 84110, 84124, 84138, 84152, + 84166, 84180, 84194, 84208, 84222, 84236, 84250, 84264, 84278, 84292, + 84306, 84320, 84334, 84348, 84362, 84376, 84390, 84404, 84418, 84432, + 84446, 84460, 84474, 84488, 84502, 84516, 84530, 84544, 84558, 84572, + 84586, 84600, 84614, 84628, 84642, 84656, 84670, 84684, 84698, 84712, + 84726, 84740, 84754, 84768, 84782, 84796, 84810, 84824, 84838, 84852, + 84866, 84880, 84894, 84908, 84922, 84936, 84950, 84964, 84978, 84992, + 85006, 85020, 85034, 85048, 85062, 85076, 85090, 85104, 85118, 85132, + 85146, 85160, 85174, 85188, 85202, 85216, 85230, 85244, 85258, 85272, + 85286, 85300, 85314, 85328, 85342, 85356, 85370, 85384, 85398, 85412, + 85426, 85440, 85454, 85468, 85482, 85496, 85510, 85524, 85538, 85552, + 85566, 85580, 85594, 85608, 85622, 85636, 85650, 85664, 85678, 85692, + 85706, 85720, 85734, 85748, 85762, 85776, 85790, 85804, 85818, 85832, + 85846, 85860, 85874, 85888, 85902, 85916, 85930, 85944, 85958, 85972, + 85986, 86000, 86014, 86028, 86042, 86056, 86070, 86084, 86098, 86112, + 86126, 86140, 86154, 86168, 86182, 86196, 86210, 86224, 86238, 86252, + 86266, 86280, 86294, 86308, 86322, 86336, 86350, 86364, 86378, 86392, + 86406, 86420, 86434, 86448, 86462, 86476, 86490, 86504, 86518, 86532, + 86546, 86560, 86574, 86588, 86602, 86616, 86630, 86644, 86658, 86672, + 86686, 86700, 86714, 86728, 86742, 86756, 86770, 86784, 86798, 86812, + 86826, 86840, 86854, 86868, 86882, 86896, 86910, 86924, 86938, 86952, + 86966, 86980, 86994, 87008, 87022, 87036, 87050, 87064, 87078, 87092, + 87106, 87120, 87134, 87148, 87162, 87176, 87190, 87204, 87218, 87232, + 87246, 87260, 87274, 87288, 87302, 87316, 87330, 87344, 87358, 87372, + 87386, 87400, 87414, 87428, 87442, 87456, 87470, 87484, 87498, 87512, + 87526, 87540, 87554, 87568, 87582, 87596, 87610, 87624, 87638, 87652, + 87666, 87680, 87694, 87708, 87722, 87736, 87750, 87764, 87778, 87792, + 87806, 87820, 87834, 87848, 87862, 87876, 87890, 87904, 87918, 87932, + 87946, 87960, 87974, 87988, 88002, 88016, 88030, 88044, 88058, 88072, + 88086, 88100, 88114, 88128, 88142, 88156, 88170, 88184, 88198, 88212, + 88226, 88240, 88254, 88268, 88282, 88296, 88310, 88324, 88338, 88352, + 88366, 88380, 88394, 88408, 88422, 88436, 88450, 88464, 88478, 88492, + 88506, 88520, 88534, 88548, 88562, 88576, 88590, 88604, 88618, 88632, + 88646, 88660, 88674, 88688, 88702, 88716, 88730, 88744, 88758, 88772, + 88786, 88800, 88814, 88828, 88842, 88856, 88870, 88884, 88898, 88912, + 88926, 88940, 88954, 88968, 88982, 88996, 89010, 89024, 89038, 89052, + 89066, 89080, 89094, 89108, 89122, 89136, 89150, 89164, 89178, 89192, + 89206, 89220, 89234, 89248, 89262, 89276, 89290, 89304, 89318, 89332, + 89346, 89360, 89374, 89388, 89402, 89416, 89430, 89444, 89458, 89472, + 89486, 89500, 89514, 89528, 89542, 89556, 89570, 89584, 89598, 89612, + 89626, 89640, 89654, 89668, 89682, 89696, 89710, 89724, 89738, 89752, + 89766, 89780, 89794, 89808, 89822, 89836, 89850, 89864, 89878, 89892, + 89906, 89920, 89934, 89948, 89962, 89976, 89990, 90004, 90018, 90032, + 90046, 90060, 90074, 90088, 90102, 90116, 90130, 90144, 90158, 90172, + 90186, 90200, 90214, 90228, 90242, 90256, 90270, 90284, 90298, 90312, + 90326, 90340, 90354, 90368, 90382, 90396, 90410, 90424, 90438, 90452, + 90466, 90480, 90494, 90508, 90522, 90536, 90550, 90564, 90578, 90592, + 90606, 90620, 90634, 90648, 90662, 90676, 90690, 90704, 90718, 90732, + 90746, 90760, 90774, 90788, 90802, 90816, 90830, 90844, 90858, 90872, + 90886, 90900, 90914, 90928, 90942, 90956, 90970, 90984, 90998, 91012, + 91026, 91040, 91054, 91068, 91082, 91096, 91110, 91124, 91138, 91152, + 91166, 91180, 91194, 91208, 91222, 91236, 91250, 91264, 91278, 91292, + 91306, 91320, 91334, 91348, 91362, 91376, 91390, 91404, 91418, 91432, + 91446, 91460, 91474, 91488, 91502, 91516, 91530, 91544, 91558, 91572, + 91586, 91600, 91614, 91628, 91642, 91656, 91670, 91684, 91698, 91712, + 91726, 91740, 91754, 91768, 91782, 91796, 91810, 91824, 91838, 91852, + 91866, 91880, 91894, 91908, 91922, 91936, 91950, 91964, 91978, 91992, + 92006, 92020, 92034, 92048, 92062, 92076, 92090, 92104, 92118, 92132, + 92146, 92160, 92174, 92188, 92202, 92216, 92230, 92244, 92258, 92272, + 92286, 92300, 92314, 92328, 92342, 92356, 92370, 92384, 92398, 92412, + 92426, 92440, 92454, 92468, 92482, 92496, 92510, 92524, 92538, 92552, + 92566, 92580, 92594, 92608, 92622, 92636, 92650, 92664, 92678, 92692, + 92706, 92720, 92734, 92748, 92762, 92776, 92790, 92804, 92818, 92832, + 92846, 92860, 92874, 92888, 92902, 92916, 92930, 92944, 92958, 92972, + 92986, 93000, 93014, 93028, 93042, 93056, 93070, 93084, 93098, 93112, + 93126, 93140, 93154, 93168, 93182, 93196, 93210, 93224, 93238, 93252, + 93266, 93280, 93294, 93308, 93322, 93336, 93350, 93364, 93378, 93392, + 93406, 93420, 93434, 93448, 93462, 93476, 93490, 93504, 93518, 93532, + 93546, 93560, 93574, 93588, 93602, 93616, 93630, 93644, 93658, 93672, + 93686, 93695, 93706, 93717, 93727, 93738, 93746, 93754, 93760, 93770, + 93778, 93784, 33472, 93789, 93795, 93804, 93816, 93821, 93828, 10992, + 20510, 93834, 93843, 93848, 93852, 93859, 93865, 93870, 93875, 93883, + 93891, 93896, 93904, 13996, 93908, 93911, 93913, 93928, 93941, 93948, + 93954, 93965, 93970, 93974, 93979, 93986, 93992, 93997, 94005, 74999, + 75009, 94011, 94018, 94028, 12212, 94035, 94040, 33710, 94049, 94054, + 94061, 94071, 94079, 94087, 94096, 94105, 94111, 94117, 94124, 94131, + 94136, 94140, 94148, 69535, 94153, 94162, 94170, 94177, 94182, 94186, + 94195, 94201, 94204, 94208, 94217, 94227, 81847, 94236, 94240, 94248, + 94252, 94258, 94269, 94279, 20519, 94290, 94299, 94307, 94315, 94322, + 69554, 9590, 94330, 94334, 94343, 94350, 94353, 31419, 94356, 94360, + 94365, 94382, 94394, 12170, 94406, 94411, 94416, 94421, 24081, 94425, + 94430, 94435, 94441, 94446, 6436, 94451, 24085, 94456, 94461, 94467, + 94474, 94479, 94484, 94490, 94496, 94502, 94507, 94513, 94517, 94531, + 94539, 94547, 94553, 94558, 94565, 94575, 94584, 94589, 94594, 94599, + 94607, 94618, 94623, 94629, 94634, 94643, 68029, 4637, 94648, 94666, + 94685, 94698, 94712, 94728, 94735, 94742, 94751, 94758, 94764, 94771, + 94776, 94782, 94788, 94796, 94802, 94807, 94812, 94828, 12183, 94842, + 94849, 94857, 94863, 94867, 94870, 94875, 94880, 94887, 94892, 94901, + 94907, 94912, 94918, 94924, 94933, 94942, 41290, 94947, 94955, 94964, + 13611, 94973, 94979, 94987, 94993, 94999, 95005, 95010, 95017, 95023, + 13622, 95028, 95031, 95036, 37607, 95046, 95055, 95060, 95066, 95071, + 95079, 95086, 95097, 95113, 95129, 95145, 95161, 95177, 95193, 95209, + 95225, 95241, 95257, 95273, 95289, 95305, 95321, 95337, 95353, 95369, + 95385, 95401, 95417, 95433, 95449, 95465, 95481, 95497, 95513, 95529, + 95545, 95561, 95577, 95593, 95609, 95625, 95641, 95657, 95673, 95689, + 95705, 95721, 95737, 95753, 95769, 95785, 95801, 95817, 95833, 95849, + 95865, 95881, 95897, 95913, 95929, 95945, 95961, 95977, 95993, 96009, + 96025, 96041, 96057, 96073, 96089, 96105, 96121, 96137, 96153, 96169, + 96185, 96201, 96217, 96233, 96249, 96265, 96281, 96297, 96313, 96329, + 96345, 96361, 96377, 96393, 96409, 96425, 96441, 96457, 96473, 96489, + 96505, 96521, 96537, 96553, 96569, 96585, 96601, 96617, 96633, 96649, + 96665, 96681, 96697, 96713, 96729, 96745, 96761, 96777, 96793, 96809, + 96825, 96841, 96857, 96873, 96889, 96905, 96921, 96937, 96953, 96969, + 96985, 97001, 97017, 97033, 97049, 97065, 97081, 97097, 97113, 97129, + 97145, 97161, 97177, 97193, 97209, 97225, 97241, 97257, 97273, 97289, + 97305, 97321, 97337, 97353, 97369, 97385, 97401, 97417, 97433, 97449, + 97465, 97481, 97497, 97513, 97529, 97545, 97561, 97577, 97593, 97609, + 97625, 97641, 97657, 97673, 97689, 97705, 97721, 97737, 97753, 97769, + 97785, 97801, 97817, 97833, 97849, 97865, 97881, 97897, 97913, 97929, + 97945, 97961, 97977, 97993, 98009, 98025, 98041, 98057, 98073, 98089, + 98105, 98121, 98137, 98153, 98169, 98185, 98201, 98217, 98233, 98249, + 98265, 98281, 98297, 98313, 98329, 98345, 98361, 98377, 98393, 98409, + 98425, 98441, 98457, 98473, 98489, 98505, 98521, 98537, 98553, 98569, + 98585, 98601, 98617, 98633, 98649, 98665, 98681, 98697, 98713, 98729, + 98745, 98761, 98777, 98793, 98809, 98825, 98841, 98857, 98873, 98889, + 98905, 98921, 98937, 98953, 98969, 98985, 99001, 99017, 99033, 99049, + 99065, 99081, 99097, 99113, 99129, 99145, 99161, 99177, 99193, 99209, + 99225, 99241, 99257, 99273, 99289, 99305, 99321, 99337, 99353, 99369, + 99385, 99401, 99417, 99433, 99449, 99465, 99481, 99497, 99513, 99529, + 99545, 99561, 99577, 99593, 99609, 99625, 99641, 99657, 99673, 99689, + 99705, 99721, 99737, 99753, 99769, 99785, 99801, 99817, 99833, 99849, + 99865, 99881, 99897, 99913, 99929, 99945, 99961, 99977, 99993, 100009, + 100025, 100041, 100057, 100073, 100089, 100105, 100121, 100137, 100153, + 100169, 100185, 100201, 100217, 100233, 100249, 100265, 100281, 100297, + 100313, 100329, 100345, 100361, 100377, 100393, 100409, 100425, 100441, + 100457, 100473, 100489, 100505, 100521, 100537, 100553, 100569, 100585, + 100601, 100617, 100633, 100649, 100665, 100681, 100697, 100713, 100729, + 100745, 100761, 100777, 100793, 100809, 100825, 100841, 100857, 100873, + 100889, 100905, 100921, 100937, 100953, 100969, 100985, 101001, 101017, + 101033, 101049, 101065, 101081, 101097, 101113, 101129, 101145, 101161, + 101177, 101193, 101209, 101225, 101241, 101257, 101273, 101289, 101305, + 101321, 101337, 101353, 101369, 101385, 101401, 101417, 101433, 101443, + 101448, 101456, 74328, 101461, 101467, 101472, 101479, 101488, 101496, + 101500, 4231, 101506, 101513, 101519, 101523, 19842, 44355, 3219, 101528, + 101532, 101536, 101543, 101549, 101558, 101564, 101571, 101575, 101596, + 101618, 101634, 101651, 101670, 101679, 101689, 101697, 101704, 101711, + 101717, 31280, 101731, 101735, 101741, 101749, 101761, 101767, 101775, + 101782, 101787, 101792, 101796, 101804, 101811, 101815, 101821, 101827, + 101832, 3879, 49986, 101838, 101842, 101846, 101850, 101855, 101860, + 101865, 101871, 101877, 101883, 101890, 101896, 101903, 101909, 101915, + 101920, 101926, 101931, 101935, 101940, 101944, 101949, 50001, 101953, + 101958, 101966, 101970, 101975, 101982, 101991, 101997, 102006, 102010, + 102017, 102021, 102024, 102031, 102037, 102046, 102056, 102066, 102071, + 102075, 102082, 102090, 102099, 102103, 102111, 102117, 102122, 102127, + 102133, 102139, 102144, 102148, 102154, 102159, 102163, 102167, 102170, + 102175, 102183, 102193, 102199, 102204, 102214, 47161, 102222, 102234, + 102240, 102247, 102253, 102257, 102262, 102268, 102280, 102291, 102298, + 102304, 102311, 102318, 102330, 102337, 102343, 24165, 102347, 102355, + 102361, 102368, 102374, 102380, 102386, 102391, 102396, 102401, 102405, + 102414, 102422, 102433, 7696, 102438, 19278, 102444, 102448, 102452, + 102456, 102464, 102473, 102477, 102484, 102493, 102501, 102514, 102520, + 101945, 34610, 102525, 102527, 102532, 102537, 102542, 102547, 102552, + 102557, 102562, 102567, 102572, 102577, 102582, 102587, 102592, 102597, + 102603, 102608, 102613, 102618, 102623, 102628, 102633, 102638, 102643, + 102649, 102655, 102661, 102666, 102671, 102683, 102688, 1872, 54, 102693, + 102698, 37617, 102702, 37622, 37627, 37633, 37638, 102706, 37643, 25306, + 102728, 102732, 102736, 102741, 102745, 37647, 102749, 102757, 102764, + 102770, 102780, 37652, 102787, 102790, 102795, 102799, 102808, 10802, + 102816, 37657, 25150, 102819, 102823, 102831, 1347, 102836, 37668, + 102839, 102844, 29608, 29618, 40892, 102849, 102854, 102859, 102864, + 102870, 102875, 102884, 102889, 102898, 102906, 102913, 102919, 102924, + 102929, 102934, 102944, 102953, 102961, 102966, 102974, 102978, 102986, + 102990, 102997, 103005, 37472, 44090, 103012, 103018, 103023, 103028, + 14031, 32595, 103033, 103038, 103043, 103049, 103056, 103062, 103071, + 103076, 103084, 103094, 103101, 103111, 103117, 103122, 103128, 103132, + 20541, 103139, 41844, 103152, 103157, 103163, 103178, 35667, 72741, + 103191, 103195, 103204, 103213, 103220, 103226, 103234, 103240, 103249, + 103256, 44210, 103262, 103265, 103269, 103273, 103277, 11546, 103283, + 103290, 103296, 103304, 103309, 103313, 27656, 103319, 103322, 103330, + 103337, 103345, 103358, 103372, 103379, 103385, 103392, 103398, 37682, + 103402, 103409, 103417, 103425, 103431, 37687, 103439, 103445, 103450, + 103460, 103466, 103475, 35462, 40263, 103483, 103488, 103493, 103497, + 103502, 103506, 103514, 103519, 17374, 18148, 103523, 103528, 37692, + 17527, 103532, 103537, 103541, 103548, 103557, 103561, 103569, 103575, + 103580, 103586, 8879, 103591, 103597, 103602, 103607, 103618, 103627, + 103639, 103654, 37980, 103660, 19397, 37696, 103664, 103671, 103677, + 103681, 27780, 103688, 103695, 46451, 103704, 103710, 103719, 103725, + 103730, 103738, 103744, 103749, 37706, 103754, 103763, 103772, 102286, + 103781, 103788, 103794, 103800, 103809, 103819, 103825, 103833, 103840, + 103844, 37711, 103847, 37717, 1386, 103852, 103860, 103868, 103878, + 103887, 103895, 103902, 103912, 37728, 103916, 103918, 103922, 103927, + 103931, 103935, 103941, 103946, 103950, 103961, 103966, 103975, 103980, + 3224, 103984, 103991, 103995, 104004, 104012, 104020, 104027, 104032, + 104037, 71293, 104041, 104044, 104050, 104058, 104064, 104068, 104073, + 104080, 104085, 104090, 104094, 104101, 104107, 104112, 40294, 104116, + 104119, 104124, 104128, 104133, 104140, 104145, 104149, 45518, 104157, + 29627, 29636, 104163, 104169, 104175, 104180, 104184, 104187, 104197, + 104206, 104211, 104217, 104224, 104230, 104234, 104242, 104247, 40300, + 82100, 104251, 104259, 104265, 104272, 104277, 104284, 104289, 104293, + 104298, 66531, 104304, 104310, 10078, 104315, 104320, 104324, 104329, + 104334, 104339, 104343, 104348, 104353, 104359, 104364, 104369, 104375, + 104381, 104386, 104390, 104395, 104400, 104405, 104409, 27779, 104414, + 104419, 104425, 104431, 104437, 104442, 104446, 104451, 104456, 104461, + 104465, 104470, 104475, 104480, 104485, 50256, 104489, 37736, 104497, + 104501, 104509, 104517, 104528, 104533, 104537, 25779, 79551, 104542, + 104548, 104553, 4542, 104563, 104570, 104575, 104583, 104592, 104597, + 104601, 104606, 104610, 104618, 104626, 104633, 74590, 104639, 104647, + 104654, 104665, 104671, 104677, 37746, 104680, 104687, 104695, 104700, + 104704, 31770, 69123, 104710, 104715, 104722, 104727, 9970, 104731, + 104739, 104746, 104753, 104762, 104769, 104775, 104789, 104797, 6517, + 104559, 104803, 104808, 104814, 104818, 104821, 104829, 104836, 104841, + 104854, 104861, 104867, 104871, 104879, 104884, 104891, 104897, 104902, + 69394, 104907, 104910, 104919, 104926, 104932, 104936, 104939, 104947, + 104953, 104962, 104972, 104982, 104991, 105002, 105010, 105021, 105026, + 105030, 105035, 105039, 41023, 105047, 24493, 41032, 105052, 97700, + 97716, 97732, 97748, 97764, 105057, 97796, 97812, 97828, 97844, 97956, + 97972, 105061, 98004, 98020, 105065, 105069, 105073, 105077, 98260, + 98292, 105081, 98324, 105085, 105089, 98468, 98484, 98500, 98516, 105093, + 98580, 98596, 105097, 98724, 98740, 98756, 98772, 98788, 98804, 98820, + 98836, 98852, 98868, 98980, 98996, 99012, 99028, 99044, 99060, 99076, + 99092, 99108, 99124, 105101, 100916, 101028, 101092, 101108, 101124, + 101140, 101156, 101172, 101284, 101300, 101316, 105105, 101364, 105109, + 101396, 101412, 101428, 105113, 105118, 105123, 105128, 105133, 105138, + 105143, 105147, 105151, 105156, 105161, 105165, 105170, 105175, 105179, + 105184, 105189, 105194, 105199, 105203, 105208, 105213, 105217, 105222, + 105226, 105230, 105234, 105238, 105243, 105247, 105251, 105255, 105259, + 105263, 105267, 105271, 105275, 105279, 105284, 105289, 105294, 105299, + 105304, 105309, 105314, 105319, 105324, 105329, 105333, 105337, 105341, + 105345, 105349, 105353, 105358, 105362, 105367, 105371, 105376, 105381, + 105385, 105389, 105394, 105398, 105402, 105406, 105410, 105414, 105418, + 105422, 105426, 105430, 105434, 105438, 105442, 105446, 105450, 105455, + 105460, 105464, 105468, 105472, 105476, 105480, 105484, 105489, 105493, + 105497, 105501, 105505, 105509, 105513, 105518, 105522, 105527, 105531, + 105535, 105539, 105543, 105547, 105551, 105555, 105559, 105563, 105567, + 105571, 105576, 105580, 105584, 105588, 105592, 105596, 105600, 105604, + 105608, 105612, 105616, 105620, 105625, 105629, 105633, 105638, 105643, + 105647, 105651, 105655, 105659, 105663, 105667, 105671, 105675, 105680, + 105684, 105689, 105693, 105698, 105702, 105707, 105711, 105717, 105722, + 105726, 105731, 105735, 105740, 105744, 105749, 105753, 105758, 1461, + 105762, 2966, 1726, 26950, 1634, 29563, 105766, 2975, 105770, 1316, + 105775, 1258, 105779, 105783, 2999, 105787, 105795, 105802, 105809, + 105823, 3003, 7803, 105832, 105840, 105847, 105858, 105867, 105871, + 105878, 105890, 105903, 105916, 105927, 105932, 105939, 105951, 105955, + 3007, 13692, 105965, 105970, 105979, 105989, 105994, 3011, 106002, + 106006, 106011, 106018, 106024, 106029, 106038, 106046, 106058, 106068, + 1263, 15119, 106081, 106085, 106091, 106105, 106117, 106129, 106137, + 106147, 106156, 106165, 106174, 106182, 106193, 106201, 4550, 106211, + 106222, 106231, 106237, 106252, 106259, 106265, 106270, 41162, 106275, + 3035, 15123, 106279, 106286, 9901, 106295, 106301, 3040, 37152, 106310, + 69023, 106317, 106321, 106327, 106338, 106344, 106349, 106356, 106362, + 106370, 106377, 106383, 106394, 106404, 106413, 106424, 106433, 106440, + 106446, 106456, 106464, 106470, 106485, 106491, 106496, 106503, 106511, + 106515, 106518, 106524, 106531, 106537, 106545, 106554, 106562, 106568, + 106577, 49571, 106591, 106596, 106602, 17133, 106607, 106620, 106632, + 106641, 106649, 106656, 106660, 106664, 106667, 106674, 106681, 106689, + 106697, 106706, 106714, 17038, 106722, 106727, 106731, 106743, 106750, + 106757, 106766, 906, 106776, 106785, 106796, 3061, 106800, 106804, + 106810, 106823, 106835, 106845, 106854, 106866, 30368, 106877, 106885, + 106894, 106905, 106916, 106926, 106936, 106944, 106953, 106961, 13139, + 106968, 106972, 106975, 106980, 106985, 106989, 106995, 1268, 107002, + 107006, 13780, 107010, 107021, 107030, 107038, 107047, 107055, 107071, + 107082, 107091, 107099, 107111, 107122, 107138, 107148, 107169, 107183, + 107196, 107204, 107211, 7849, 107224, 107229, 107235, 6526, 107241, + 107244, 107251, 107261, 8981, 107268, 107273, 107278, 107285, 107290, + 107298, 107307, 107315, 107320, 107329, 107336, 11040, 11049, 107342, + 107353, 107359, 107364, 107370, 3077, 3082, 107376, 977, 107382, 107389, + 107396, 107409, 107414, 2261, 87, 107422, 107429, 107434, 107442, 107452, + 107461, 107467, 107476, 107484, 107494, 107498, 107502, 107507, 107511, + 107523, 3105, 107531, 107539, 107544, 107555, 107566, 107578, 107589, + 107599, 107608, 24534, 107613, 107619, 107624, 107634, 107644, 107649, + 32484, 107655, 107660, 107669, 24546, 107673, 4654, 16, 107678, 107687, + 107694, 107701, 107707, 107712, 107716, 107722, 32508, 107727, 107732, + 69685, 107737, 107742, 107748, 107754, 107762, 107767, 107775, 107782, + 107788, 107793, 45394, 49465, 107799, 1797, 32, 107809, 107822, 107827, + 107835, 107840, 107846, 3131, 32563, 107851, 107859, 107866, 107871, + 107876, 107885, 4233, 4244, 70891, 107893, 107897, 1661, 1809, 107902, + 107907, 107914, 32916, 1813, 302, 107921, 107927, 107932, 3153, 107936, + 107941, 107948, 1817, 107953, 107959, 107964, 107976, 6757, 107986, + 107993, 1824, 107999, 108004, 108011, 108018, 108033, 108040, 108051, + 108056, 108064, 2696, 108068, 108080, 108085, 108089, 108095, 32362, + 2266, 108099, 108110, 108114, 108118, 108124, 108128, 108137, 108141, + 108152, 108156, 2312, 36969, 108160, 108170, 108178, 3244, 108184, + 108193, 108201, 10439, 108206, 108214, 108219, 108223, 108232, 108239, + 108245, 3214, 17197, 108249, 108262, 108280, 108285, 108293, 108301, + 108311, 11344, 15241, 108323, 108336, 108343, 108357, 108364, 108380, + 108387, 108393, 24584, 14454, 108400, 108407, 108417, 108426, 50255, + 108438, 108446, 50390, 108453, 108456, 108462, 108468, 108474, 108480, + 108486, 108493, 108500, 108506, 108512, 108518, 108524, 108530, 108536, + 108542, 108548, 108554, 108560, 108566, 108572, 108578, 108584, 108590, + 108596, 108602, 108608, 108614, 108620, 108626, 108632, 108638, 108644, + 108650, 108656, 108662, 108668, 108674, 108680, 108686, 108692, 108698, + 108704, 108710, 108716, 108722, 108728, 108734, 108740, 108746, 108752, + 108758, 108764, 108770, 108776, 108782, 108788, 108794, 108800, 108806, + 108813, 108819, 108826, 108833, 108839, 108846, 108853, 108859, 108865, + 108871, 108877, 108883, 108889, 108895, 108901, 108907, 108913, 108919, + 108925, 108931, 108937, 108943, 3228, 10412, 108949, 108959, 108965, + 108973, 108977, 106014, 3232, 108981, 102515, 24294, 14066, 4158, 108985, + 3238, 108989, 108999, 109005, 109011, 109017, 109023, 109029, 109035, + 109041, 109047, 109053, 109059, 109065, 109071, 109077, 109083, 109089, + 109095, 109101, 109107, 109113, 109119, 109125, 109131, 109137, 109143, + 109149, 109156, 109163, 109169, 109175, 109181, 109187, 109193, 109199, + 1273, 109205, 109210, 109215, 109220, 109225, 109230, 109235, 109240, + 109245, 109249, 109253, 109257, 109261, 109265, 109269, 109273, 109277, + 109281, 109287, 109293, 109299, 109305, 109309, 109313, 109317, 109321, + 109325, 109329, 109333, 109337, 109341, 109346, 109351, 109356, 109361, + 109366, 109371, 109376, 109381, 109386, 109391, 109396, 109401, 109406, + 109411, 109416, 109421, 109426, 109431, 109436, 109441, 109446, 109451, + 109456, 109461, 109466, 109471, 109476, 109481, 109486, 109491, 109496, + 109501, 109506, 109511, 109516, 109521, 109526, 109531, 109536, 109541, + 109546, 109551, 109556, 109561, 109566, 109571, 109576, 109581, 109586, + 109591, 109596, 109601, 109606, 109611, 109616, 109621, 109626, 109631, + 109636, 109641, 109646, 109651, 109656, 109661, 109666, 109671, 109676, + 109681, 109686, 109691, 109696, 109701, 109706, 109711, 109716, 109721, + 109726, 109731, 109736, 109741, 109746, 109751, 109756, 109761, 109766, + 109771, 109776, 109781, 109786, 109791, 109796, 109801, 109806, 109811, + 109816, 109821, 109826, 109831, 109836, 109841, 109846, 109851, 109856, + 109861, 109866, 109871, 109876, 109881, 109886, 109891, 109896, 109901, + 109906, 109911, 109916, 109921, 109926, 109931, 109936, 109941, 109946, + 109951, 109956, 109961, 109966, 109971, 109976, 109981, 109986, 109991, + 109996, 110001, 110006, 110011, 110016, 110021, 110026, 110031, 110036, + 110041, 110046, 110051, 110056, 110061, 110066, 110071, 110076, 110081, + 110086, 110091, 110096, 110101, 110106, 110111, 110116, 110121, 110126, + 110131, 110136, 110141, 110146, 110151, 110156, 110161, 110166, 110171, + 110176, 110181, 110186, 110191, 110196, 110201, 110206, 110211, 110216, + 110221, 110226, 110231, 110237, 110242, 110247, 110252, 110257, 110262, + 110267, 110272, 110278, 110283, 110288, 110293, 110298, 110303, 110308, + 110313, 110318, 110323, 110328, 110333, 110338, 110343, 110348, 110353, + 110358, 110363, 110368, 110373, 110378, 110383, 110388, 110393, 110398, + 110403, 110408, 110413, 110418, 110423, 110428, 110433, 110438, 110447, + 110452, 110461, 110466, 110475, 110480, 110489, 110494, 110503, 110508, + 110517, 110522, 110531, 110536, 110545, 110550, 110555, 110564, 110568, + 110577, 110582, 110591, 110596, 110605, 110610, 110619, 110624, 110633, + 110638, 110647, 110652, 110661, 110666, 110675, 110680, 110689, 110694, + 110703, 110708, 110713, 110718, 110723, 110728, 110733, 110738, 110742, + 110747, 110752, 110757, 110762, 110767, 110772, 110778, 110783, 110788, + 110793, 110799, 110803, 110808, 110814, 110819, 110824, 110829, 110834, + 110839, 110844, 110849, 110854, 110859, 110864, 110870, 110875, 110880, + 110885, 110891, 110896, 110901, 110906, 110911, 110917, 110922, 110927, + 110932, 110937, 110942, 110948, 110953, 110958, 110963, 110968, 110973, + 110978, 110983, 110988, 110993, 110998, 111003, 111008, 111013, 111018, + 111023, 111028, 111033, 111038, 111043, 111048, 111053, 111058, 111063, + 111069, 111075, 111081, 111086, 111091, 111096, 111101, 111107, 111113, + 111119, 111124, 111129, 111134, 111140, 111145, 111150, 111155, 111160, + 111165, 111170, 111175, 111180, 111185, 111190, 111195, 111200, 111205, + 111210, 111215, 111220, 111226, 111232, 111238, 111243, 111248, 111253, + 111258, 111264, 111270, 111276, 111281, 111286, 111291, 111296, 111301, + 111306, 111311, 111316, 111321, 18785, 111326, 111332, 111337, 111342, + 111347, 111352, 111357, 111363, 111368, 111373, 111378, 111383, 111388, + 111394, 111399, 111404, 111409, 111414, 111419, 111424, 111429, 111434, + 111439, 111444, 111449, 111454, 111459, 111464, 111469, 111474, 111479, + 111484, 111489, 111494, 111499, 111504, 111510, 111515, 111520, 111525, + 111530, 111535, 111540, 111545, 111550, 111555, 111560, 111565, 111570, + 111575, 111580, 111585, 111590, 111595, 111600, 111605, 111610, 111615, + 111620, 111625, 111630, 111635, 111640, 111645, 111650, 111655, 111660, + 111665, 111670, 111675, 111680, 111685, 111690, 111695, 111700, 111705, + 111710, 111716, 111721, 111726, 111731, 111736, 111741, 111746, 111751, + 111756, 111761, 111766, 111771, 111777, 111782, 111788, 111793, 111798, + 111803, 111808, 111813, 111818, 111824, 111829, 111834, 111840, 111845, + 111850, 111855, 111860, 111865, 111871, 111877, 111882, 111887, 14088, + 111892, 111897, 111902, 111907, 111912, 111917, 111922, 111927, 111932, + 111937, 111942, 111947, 111952, 111957, 111962, 111967, 111972, 111977, + 111982, 111987, 111992, 111997, 112002, 112007, 112012, 112017, 112022, + 112027, 112032, 112037, 112042, 112047, 112052, 112057, 112062, 112067, + 112072, 112077, 112082, 112087, 112092, 112097, 112102, 112107, 112112, + 112117, 112122, 112127, 112132, 112137, 112142, 112147, 112152, 112157, + 112162, 112167, 112172, 112177, 112182, 112187, 112192, 112197, 112202, + 112207, 112212, 112218, 112223, 112228, 112233, 112238, 112244, 112249, + 112254, 112259, 112264, 112269, 112274, 112280, 112285, 112290, 112295, + 112300, 112305, 112311, 112316, 112321, 112326, 112331, 112336, 112342, + 112347, 112352, 112357, 112362, 112367, 112373, 112379, 112384, 112389, + 112394, 112400, 112406, 112412, 112417, 112422, 112428, 112434, 112439, + 112445, 112451, 112457, 112462, 112467, 112473, 112478, 112484, 112489, + 112495, 112504, 112509, 112514, 112520, 112525, 112531, 112536, 112541, + 112546, 112551, 112556, 112561, 112566, 112571, 112576, 112581, 112586, + 112591, 112596, 112601, 112606, 112611, 112616, 112621, 112626, 112631, + 112636, 112641, 112646, 112651, 112656, 112661, 112666, 112671, 112676, + 112681, 112686, 112692, 112698, 112704, 112709, 112714, 112719, 112724, + 112729, 112734, 112739, 112744, 112749, 112754, 112759, 112764, 112769, + 112774, 112779, 112784, 112789, 112794, 112799, 112804, 112810, 112816, + 112821, 112827, 112832, 112837, 112843, 112848, 112854, 112859, 112865, + 112870, 112876, 112881, 112887, 112892, 112897, 112902, 112907, 112912, + 112917, 112922, 109000, 109006, 109012, 109018, 112928, 109024, 109030, + 112934, 109036, 109042, 109048, 109054, 109060, 109066, 109072, 109078, + 109084, 112940, 109090, 109096, 109102, 112946, 109108, 109114, 109120, + 109126, 112952, 109132, 109138, 109144, 109164, 112958, 112964, 109170, + 112970, 109176, 109182, 109188, 109194, 109200, 112976, 3255, 3260, + 112981, 3275, 3280, 3285, 112986, 112989, 112995, 113001, 113008, 113013, + 113018, 2317, +}; + +/* code->name phrasebook */ +#define phrasebook_shift 7 +#define phrasebook_short 194 +static const unsigned char phrasebook[] = { + 0, 205, 148, 236, 90, 78, 211, 62, 78, 31, 55, 239, 10, 55, 213, 45, 55, + 251, 111, 251, 30, 50, 213, 140, 53, 213, 140, 250, 179, 98, 55, 244, + 159, 231, 6, 234, 217, 204, 226, 205, 177, 17, 195, 79, 17, 100, 17, 102, + 17, 134, 17, 136, 17, 146, 17, 167, 17, 178, 17, 171, 17, 182, 244, 168, + 207, 105, 222, 140, 55, 236, 172, 55, 233, 94, 55, 211, 79, 78, 244, 157, + 250, 168, 8, 6, 1, 63, 8, 6, 1, 250, 112, 8, 6, 1, 247, 207, 8, 6, 1, + 240, 231, 8, 6, 1, 69, 8, 6, 1, 236, 49, 8, 6, 1, 234, 190, 8, 6, 1, 233, + 15, 8, 6, 1, 68, 8, 6, 1, 225, 217, 8, 6, 1, 225, 80, 8, 6, 1, 159, 8, 6, + 1, 221, 136, 8, 6, 1, 218, 55, 8, 6, 1, 72, 8, 6, 1, 214, 3, 8, 6, 1, + 211, 167, 8, 6, 1, 144, 8, 6, 1, 209, 80, 8, 6, 1, 203, 216, 8, 6, 1, 66, + 8, 6, 1, 199, 230, 8, 6, 1, 197, 199, 8, 6, 1, 196, 222, 8, 6, 1, 196, + 148, 8, 6, 1, 195, 158, 50, 47, 179, 210, 90, 205, 177, 53, 47, 179, 244, + 241, 252, 22, 126, 222, 75, 233, 101, 252, 22, 8, 4, 1, 63, 8, 4, 1, 250, + 112, 8, 4, 1, 247, 207, 8, 4, 1, 240, 231, 8, 4, 1, 69, 8, 4, 1, 236, 49, + 8, 4, 1, 234, 190, 8, 4, 1, 233, 15, 8, 4, 1, 68, 8, 4, 1, 225, 217, 8, + 4, 1, 225, 80, 8, 4, 1, 159, 8, 4, 1, 221, 136, 8, 4, 1, 218, 55, 8, 4, + 1, 72, 8, 4, 1, 214, 3, 8, 4, 1, 211, 167, 8, 4, 1, 144, 8, 4, 1, 209, + 80, 8, 4, 1, 203, 216, 8, 4, 1, 66, 8, 4, 1, 199, 230, 8, 4, 1, 197, 199, + 8, 4, 1, 196, 222, 8, 4, 1, 196, 148, 8, 4, 1, 195, 158, 50, 241, 18, + 179, 83, 222, 75, 53, 241, 18, 179, 202, 84, 216, 44, 205, 148, 226, 17, + 236, 90, 78, 247, 39, 55, 212, 63, 55, 241, 17, 55, 196, 60, 55, 248, 33, + 154, 208, 133, 55, 239, 150, 241, 105, 55, 235, 170, 214, 67, 226, 68, + 222, 179, 52, 251, 91, 211, 62, 78, 216, 19, 55, 205, 186, 231, 7, 210, + 149, 55, 220, 114, 239, 231, 55, 212, 124, 55, 204, 95, 102, 204, 95, + 134, 252, 10, 252, 22, 219, 69, 55, 212, 179, 55, 112, 238, 253, 247, 50, + 204, 95, 100, 220, 13, 214, 67, 226, 68, 210, 17, 52, 251, 91, 211, 62, + 78, 197, 217, 191, 97, 211, 87, 197, 217, 191, 97, 232, 225, 197, 217, + 191, 115, 211, 85, 226, 17, 211, 79, 78, 8, 6, 1, 39, 3, 233, 100, 8, 6, + 1, 39, 3, 186, 8, 6, 1, 39, 3, 244, 240, 8, 6, 1, 39, 3, 202, 84, 8, 6, + 1, 39, 3, 239, 150, 8, 6, 1, 39, 3, 210, 3, 57, 8, 6, 1, 251, 245, 8, 6, + 1, 247, 208, 3, 247, 50, 8, 6, 1, 237, 136, 3, 233, 100, 8, 6, 1, 237, + 136, 3, 186, 8, 6, 1, 237, 136, 3, 244, 240, 8, 6, 1, 237, 136, 3, 239, + 150, 8, 6, 1, 230, 249, 3, 233, 100, 8, 6, 1, 230, 249, 3, 186, 8, 6, 1, + 230, 249, 3, 244, 240, 8, 6, 1, 230, 249, 3, 239, 150, 8, 6, 1, 236, 121, + 8, 6, 1, 218, 56, 3, 202, 84, 8, 6, 1, 177, 3, 233, 100, 8, 6, 1, 177, 3, + 186, 8, 6, 1, 177, 3, 244, 240, 8, 6, 1, 177, 3, 202, 84, 8, 6, 1, 177, + 3, 239, 150, 218, 118, 55, 8, 6, 1, 177, 3, 106, 8, 6, 1, 118, 3, 233, + 100, 8, 6, 1, 118, 3, 186, 8, 6, 1, 118, 3, 244, 240, 8, 6, 1, 118, 3, + 239, 150, 8, 6, 1, 196, 149, 3, 186, 8, 6, 1, 202, 162, 8, 4, 1, 207, 13, + 209, 80, 8, 4, 1, 39, 3, 233, 100, 8, 4, 1, 39, 3, 186, 8, 4, 1, 39, 3, + 244, 240, 8, 4, 1, 39, 3, 202, 84, 8, 4, 1, 39, 3, 239, 150, 8, 4, 1, 39, + 3, 210, 3, 57, 8, 4, 1, 251, 245, 8, 4, 1, 247, 208, 3, 247, 50, 8, 4, 1, + 237, 136, 3, 233, 100, 8, 4, 1, 237, 136, 3, 186, 8, 4, 1, 237, 136, 3, + 244, 240, 8, 4, 1, 237, 136, 3, 239, 150, 8, 4, 1, 230, 249, 3, 233, 100, + 8, 4, 1, 230, 249, 3, 186, 8, 4, 1, 230, 249, 3, 244, 240, 8, 4, 1, 230, + 249, 3, 239, 150, 8, 4, 1, 236, 121, 8, 4, 1, 218, 56, 3, 202, 84, 8, 4, + 1, 177, 3, 233, 100, 8, 4, 1, 177, 3, 186, 8, 4, 1, 177, 3, 244, 240, 8, + 4, 1, 177, 3, 202, 84, 8, 4, 1, 177, 3, 239, 150, 239, 54, 55, 8, 4, 1, + 177, 3, 106, 8, 4, 1, 118, 3, 233, 100, 8, 4, 1, 118, 3, 186, 8, 4, 1, + 118, 3, 244, 240, 8, 4, 1, 118, 3, 239, 150, 8, 4, 1, 196, 149, 3, 186, + 8, 4, 1, 202, 162, 8, 4, 1, 196, 149, 3, 239, 150, 8, 6, 1, 39, 3, 220, + 114, 8, 4, 1, 39, 3, 220, 114, 8, 6, 1, 39, 3, 248, 47, 8, 4, 1, 39, 3, + 248, 47, 8, 6, 1, 39, 3, 214, 151, 8, 4, 1, 39, 3, 214, 151, 8, 6, 1, + 247, 208, 3, 186, 8, 4, 1, 247, 208, 3, 186, 8, 6, 1, 247, 208, 3, 244, + 240, 8, 4, 1, 247, 208, 3, 244, 240, 8, 6, 1, 247, 208, 3, 76, 57, 8, 4, + 1, 247, 208, 3, 76, 57, 8, 6, 1, 247, 208, 3, 247, 106, 8, 4, 1, 247, + 208, 3, 247, 106, 8, 6, 1, 240, 232, 3, 247, 106, 8, 4, 1, 240, 232, 3, + 247, 106, 8, 6, 1, 240, 232, 3, 106, 8, 4, 1, 240, 232, 3, 106, 8, 6, 1, + 237, 136, 3, 220, 114, 8, 4, 1, 237, 136, 3, 220, 114, 8, 6, 1, 237, 136, + 3, 248, 47, 8, 4, 1, 237, 136, 3, 248, 47, 8, 6, 1, 237, 136, 3, 76, 57, + 8, 4, 1, 237, 136, 3, 76, 57, 8, 6, 1, 237, 136, 3, 214, 151, 8, 4, 1, + 237, 136, 3, 214, 151, 8, 6, 1, 237, 136, 3, 247, 106, 8, 4, 1, 237, 136, + 3, 247, 106, 8, 6, 1, 234, 191, 3, 244, 240, 8, 4, 1, 234, 191, 3, 244, + 240, 8, 6, 1, 234, 191, 3, 248, 47, 8, 4, 1, 234, 191, 3, 248, 47, 8, 6, + 1, 234, 191, 3, 76, 57, 8, 4, 1, 234, 191, 3, 76, 57, 8, 6, 1, 234, 191, + 3, 247, 50, 8, 4, 1, 234, 191, 3, 247, 50, 8, 6, 1, 233, 16, 3, 244, 240, + 8, 4, 1, 233, 16, 3, 244, 240, 8, 6, 1, 233, 16, 3, 106, 8, 4, 1, 233, + 16, 3, 106, 8, 6, 1, 230, 249, 3, 202, 84, 8, 4, 1, 230, 249, 3, 202, 84, + 8, 6, 1, 230, 249, 3, 220, 114, 8, 4, 1, 230, 249, 3, 220, 114, 8, 6, 1, + 230, 249, 3, 248, 47, 8, 4, 1, 230, 249, 3, 248, 47, 8, 6, 1, 230, 249, + 3, 214, 151, 8, 4, 1, 230, 249, 3, 214, 151, 8, 6, 1, 230, 249, 3, 76, + 57, 8, 4, 1, 238, 252, 68, 8, 6, 33, 226, 118, 8, 4, 33, 226, 118, 8, 6, + 1, 225, 218, 3, 244, 240, 8, 4, 1, 225, 218, 3, 244, 240, 8, 6, 1, 225, + 81, 3, 247, 50, 8, 4, 1, 225, 81, 3, 247, 50, 8, 4, 1, 223, 210, 8, 6, 1, + 223, 100, 3, 186, 8, 4, 1, 223, 100, 3, 186, 8, 6, 1, 223, 100, 3, 247, + 50, 8, 4, 1, 223, 100, 3, 247, 50, 8, 6, 1, 223, 100, 3, 247, 106, 8, 4, + 1, 223, 100, 3, 247, 106, 8, 6, 1, 223, 100, 3, 112, 238, 253, 8, 4, 1, + 223, 100, 3, 112, 238, 253, 8, 6, 1, 223, 100, 3, 106, 8, 4, 1, 223, 100, + 3, 106, 8, 6, 1, 218, 56, 3, 186, 8, 4, 1, 218, 56, 3, 186, 8, 6, 1, 218, + 56, 3, 247, 50, 8, 4, 1, 218, 56, 3, 247, 50, 8, 6, 1, 218, 56, 3, 247, + 106, 8, 4, 1, 218, 56, 3, 247, 106, 8, 4, 1, 218, 56, 212, 37, 247, 219, + 251, 30, 8, 6, 1, 236, 215, 8, 4, 1, 236, 215, 8, 6, 1, 177, 3, 220, 114, + 8, 4, 1, 177, 3, 220, 114, 8, 6, 1, 177, 3, 248, 47, 8, 4, 1, 177, 3, + 248, 47, 8, 6, 1, 177, 3, 52, 186, 8, 4, 1, 177, 3, 52, 186, 8, 6, 33, + 214, 164, 8, 4, 33, 214, 164, 8, 6, 1, 211, 32, 3, 186, 8, 4, 1, 211, 32, + 3, 186, 8, 6, 1, 211, 32, 3, 247, 50, 8, 4, 1, 211, 32, 3, 247, 50, 8, 6, + 1, 211, 32, 3, 247, 106, 8, 4, 1, 211, 32, 3, 247, 106, 8, 6, 1, 209, 81, + 3, 186, 8, 4, 1, 209, 81, 3, 186, 8, 6, 1, 209, 81, 3, 244, 240, 8, 4, 1, + 209, 81, 3, 244, 240, 8, 6, 1, 209, 81, 3, 247, 50, 8, 4, 1, 209, 81, 3, + 247, 50, 8, 6, 1, 209, 81, 3, 247, 106, 8, 4, 1, 209, 81, 3, 247, 106, 8, + 6, 1, 203, 217, 3, 247, 50, 8, 4, 1, 203, 217, 3, 247, 50, 8, 6, 1, 203, + 217, 3, 247, 106, 8, 4, 1, 203, 217, 3, 247, 106, 8, 6, 1, 203, 217, 3, + 106, 8, 4, 1, 203, 217, 3, 106, 8, 6, 1, 118, 3, 202, 84, 8, 4, 1, 118, + 3, 202, 84, 8, 6, 1, 118, 3, 220, 114, 8, 4, 1, 118, 3, 220, 114, 8, 6, + 1, 118, 3, 248, 47, 8, 4, 1, 118, 3, 248, 47, 8, 6, 1, 118, 3, 210, 3, + 57, 8, 4, 1, 118, 3, 210, 3, 57, 8, 6, 1, 118, 3, 52, 186, 8, 4, 1, 118, + 3, 52, 186, 8, 6, 1, 118, 3, 214, 151, 8, 4, 1, 118, 3, 214, 151, 8, 6, + 1, 197, 200, 3, 244, 240, 8, 4, 1, 197, 200, 3, 244, 240, 8, 6, 1, 196, + 149, 3, 244, 240, 8, 4, 1, 196, 149, 3, 244, 240, 8, 6, 1, 196, 149, 3, + 239, 150, 8, 6, 1, 195, 159, 3, 186, 8, 4, 1, 195, 159, 3, 186, 8, 6, 1, + 195, 159, 3, 76, 57, 8, 4, 1, 195, 159, 3, 76, 57, 8, 6, 1, 195, 159, 3, + 247, 106, 8, 4, 1, 195, 159, 3, 247, 106, 8, 4, 1, 181, 209, 80, 8, 4, 1, + 74, 3, 106, 8, 6, 1, 74, 3, 122, 8, 6, 1, 74, 3, 201, 240, 8, 4, 1, 74, + 3, 201, 240, 8, 6, 1, 152, 167, 8, 4, 1, 152, 167, 8, 6, 1, 192, 72, 8, + 6, 1, 247, 208, 3, 122, 8, 4, 1, 247, 208, 3, 122, 8, 6, 1, 251, 220, + 240, 231, 8, 6, 1, 240, 232, 3, 122, 8, 6, 1, 240, 232, 3, 201, 240, 8, + 4, 1, 240, 232, 3, 201, 240, 8, 4, 1, 163, 239, 212, 8, 6, 1, 210, 89, + 69, 8, 6, 1, 208, 163, 8, 6, 1, 192, 69, 8, 6, 1, 236, 50, 3, 122, 8, 4, + 1, 236, 50, 3, 122, 8, 6, 1, 234, 191, 3, 122, 8, 6, 1, 234, 94, 8, 4, 1, + 231, 44, 8, 6, 1, 226, 7, 8, 6, 1, 230, 249, 3, 106, 8, 6, 1, 225, 81, 3, + 122, 8, 4, 1, 225, 81, 3, 122, 8, 4, 1, 223, 100, 3, 154, 8, 4, 1, 222, + 247, 3, 106, 8, 6, 1, 163, 221, 136, 8, 6, 1, 218, 56, 3, 50, 122, 8, 4, + 1, 218, 56, 3, 181, 53, 222, 172, 8, 6, 1, 177, 3, 112, 202, 84, 8, 6, 1, + 177, 3, 231, 102, 8, 4, 1, 177, 3, 231, 102, 8, 6, 1, 214, 146, 8, 4, 1, + 214, 146, 8, 6, 1, 214, 4, 3, 122, 8, 4, 1, 214, 4, 3, 122, 8, 1, 195, + 220, 8, 6, 1, 152, 102, 8, 4, 1, 152, 102, 8, 6, 1, 236, 141, 8, 1, 210, + 89, 236, 142, 221, 225, 8, 4, 1, 203, 217, 3, 213, 215, 122, 8, 6, 1, + 203, 217, 3, 122, 8, 4, 1, 203, 217, 3, 122, 8, 6, 1, 203, 217, 3, 210, + 95, 122, 8, 6, 1, 118, 3, 231, 102, 8, 4, 1, 118, 3, 231, 102, 8, 6, 1, + 200, 28, 8, 6, 1, 199, 231, 3, 122, 8, 6, 1, 196, 149, 3, 122, 8, 4, 1, + 196, 149, 3, 122, 8, 6, 1, 195, 159, 3, 106, 8, 4, 1, 195, 159, 3, 106, + 8, 6, 1, 236, 52, 8, 6, 1, 236, 53, 210, 88, 8, 4, 1, 236, 53, 210, 88, + 8, 4, 1, 236, 53, 3, 203, 135, 8, 1, 99, 3, 106, 8, 6, 1, 152, 146, 8, 4, + 1, 152, 146, 8, 1, 226, 17, 233, 152, 204, 227, 3, 106, 8, 1, 196, 225, + 8, 1, 239, 205, 244, 215, 8, 1, 222, 218, 244, 215, 8, 1, 251, 124, 244, + 215, 8, 1, 210, 95, 244, 215, 8, 6, 1, 237, 158, 3, 247, 106, 8, 6, 1, + 240, 232, 3, 4, 1, 195, 159, 3, 247, 106, 8, 4, 1, 237, 158, 3, 247, 106, + 8, 6, 1, 222, 41, 8, 6, 1, 223, 100, 3, 4, 1, 225, 217, 8, 4, 1, 222, 41, + 8, 6, 1, 216, 165, 8, 6, 1, 218, 56, 3, 4, 1, 225, 217, 8, 4, 1, 216, + 165, 8, 6, 1, 39, 3, 247, 106, 8, 4, 1, 39, 3, 247, 106, 8, 6, 1, 230, + 249, 3, 247, 106, 8, 4, 1, 230, 249, 3, 247, 106, 8, 6, 1, 177, 3, 247, + 106, 8, 4, 1, 177, 3, 247, 106, 8, 6, 1, 118, 3, 247, 106, 8, 4, 1, 118, + 3, 247, 106, 8, 6, 1, 118, 3, 239, 151, 26, 220, 114, 8, 4, 1, 118, 3, + 239, 151, 26, 220, 114, 8, 6, 1, 118, 3, 239, 151, 26, 186, 8, 4, 1, 118, + 3, 239, 151, 26, 186, 8, 6, 1, 118, 3, 239, 151, 26, 247, 106, 8, 4, 1, + 118, 3, 239, 151, 26, 247, 106, 8, 6, 1, 118, 3, 239, 151, 26, 233, 100, + 8, 4, 1, 118, 3, 239, 151, 26, 233, 100, 8, 4, 1, 163, 69, 8, 6, 1, 39, + 3, 239, 151, 26, 220, 114, 8, 4, 1, 39, 3, 239, 151, 26, 220, 114, 8, 6, + 1, 39, 3, 76, 90, 26, 220, 114, 8, 4, 1, 39, 3, 76, 90, 26, 220, 114, 8, + 6, 1, 251, 246, 3, 220, 114, 8, 4, 1, 251, 246, 3, 220, 114, 8, 6, 1, + 234, 191, 3, 106, 8, 4, 1, 234, 191, 3, 106, 8, 6, 1, 234, 191, 3, 247, + 106, 8, 4, 1, 234, 191, 3, 247, 106, 8, 6, 1, 225, 81, 3, 247, 106, 8, 4, + 1, 225, 81, 3, 247, 106, 8, 6, 1, 177, 3, 214, 151, 8, 4, 1, 177, 3, 214, + 151, 8, 6, 1, 177, 3, 214, 152, 26, 220, 114, 8, 4, 1, 177, 3, 214, 152, + 26, 220, 114, 8, 6, 1, 236, 53, 3, 247, 106, 8, 4, 1, 236, 53, 3, 247, + 106, 8, 4, 1, 225, 218, 3, 247, 106, 8, 6, 1, 237, 157, 8, 6, 1, 240, + 232, 3, 4, 1, 195, 158, 8, 4, 1, 237, 157, 8, 6, 1, 234, 191, 3, 186, 8, + 4, 1, 234, 191, 3, 186, 8, 6, 1, 231, 41, 8, 6, 1, 196, 225, 8, 6, 1, + 218, 56, 3, 233, 100, 8, 4, 1, 218, 56, 3, 233, 100, 8, 6, 1, 39, 3, 210, + 3, 90, 26, 186, 8, 4, 1, 39, 3, 210, 3, 90, 26, 186, 8, 6, 1, 251, 246, + 3, 186, 8, 4, 1, 251, 246, 3, 186, 8, 6, 1, 177, 3, 204, 196, 26, 186, 8, + 4, 1, 177, 3, 204, 196, 26, 186, 8, 6, 1, 39, 3, 52, 233, 100, 8, 4, 1, + 39, 3, 52, 233, 100, 8, 6, 1, 39, 3, 226, 17, 248, 47, 8, 4, 1, 39, 3, + 226, 17, 248, 47, 8, 6, 1, 237, 136, 3, 52, 233, 100, 8, 4, 1, 237, 136, + 3, 52, 233, 100, 8, 6, 1, 237, 136, 3, 226, 17, 248, 47, 8, 4, 1, 237, + 136, 3, 226, 17, 248, 47, 8, 6, 1, 230, 249, 3, 52, 233, 100, 8, 4, 1, + 230, 249, 3, 52, 233, 100, 8, 6, 1, 230, 249, 3, 226, 17, 248, 47, 8, 4, + 1, 230, 249, 3, 226, 17, 248, 47, 8, 6, 1, 177, 3, 52, 233, 100, 8, 4, 1, + 177, 3, 52, 233, 100, 8, 6, 1, 177, 3, 226, 17, 248, 47, 8, 4, 1, 177, 3, + 226, 17, 248, 47, 8, 6, 1, 211, 32, 3, 52, 233, 100, 8, 4, 1, 211, 32, 3, + 52, 233, 100, 8, 6, 1, 211, 32, 3, 226, 17, 248, 47, 8, 4, 1, 211, 32, 3, + 226, 17, 248, 47, 8, 6, 1, 118, 3, 52, 233, 100, 8, 4, 1, 118, 3, 52, + 233, 100, 8, 6, 1, 118, 3, 226, 17, 248, 47, 8, 4, 1, 118, 3, 226, 17, + 248, 47, 8, 6, 1, 209, 81, 3, 244, 160, 60, 8, 4, 1, 209, 81, 3, 244, + 160, 60, 8, 6, 1, 203, 217, 3, 244, 160, 60, 8, 4, 1, 203, 217, 3, 244, + 160, 60, 8, 6, 1, 195, 239, 8, 4, 1, 195, 239, 8, 6, 1, 233, 16, 3, 247, + 106, 8, 4, 1, 233, 16, 3, 247, 106, 8, 6, 1, 218, 56, 3, 181, 53, 222, + 172, 8, 4, 1, 240, 232, 3, 241, 21, 8, 6, 1, 214, 39, 8, 4, 1, 214, 39, + 8, 6, 1, 195, 159, 3, 122, 8, 4, 1, 195, 159, 3, 122, 8, 6, 1, 39, 3, 76, + 57, 8, 4, 1, 39, 3, 76, 57, 8, 6, 1, 237, 136, 3, 247, 50, 8, 4, 1, 237, + 136, 3, 247, 50, 8, 6, 1, 177, 3, 239, 151, 26, 220, 114, 8, 4, 1, 177, + 3, 239, 151, 26, 220, 114, 8, 6, 1, 177, 3, 202, 85, 26, 220, 114, 8, 4, + 1, 177, 3, 202, 85, 26, 220, 114, 8, 6, 1, 177, 3, 76, 57, 8, 4, 1, 177, + 3, 76, 57, 8, 6, 1, 177, 3, 76, 90, 26, 220, 114, 8, 4, 1, 177, 3, 76, + 90, 26, 220, 114, 8, 6, 1, 196, 149, 3, 220, 114, 8, 4, 1, 196, 149, 3, + 220, 114, 8, 4, 1, 223, 100, 3, 241, 21, 8, 4, 1, 218, 56, 3, 241, 21, 8, + 4, 1, 203, 217, 3, 241, 21, 8, 4, 1, 238, 252, 225, 217, 8, 4, 1, 240, + 51, 239, 110, 8, 4, 1, 211, 98, 239, 110, 8, 6, 1, 39, 3, 106, 8, 6, 1, + 247, 208, 3, 106, 8, 4, 1, 247, 208, 3, 106, 8, 6, 1, 223, 100, 3, 154, + 8, 6, 1, 203, 217, 3, 239, 147, 106, 8, 4, 1, 209, 81, 3, 204, 63, 203, + 135, 8, 4, 1, 195, 159, 3, 204, 63, 203, 135, 8, 6, 1, 233, 152, 204, + 226, 8, 4, 1, 233, 152, 204, 226, 8, 6, 1, 74, 3, 106, 8, 6, 1, 118, 154, + 8, 6, 1, 163, 199, 230, 8, 6, 1, 237, 136, 3, 106, 8, 4, 1, 237, 136, 3, + 106, 8, 6, 1, 225, 218, 3, 106, 8, 4, 1, 225, 218, 3, 106, 8, 6, 1, 4, + 211, 168, 3, 231, 165, 203, 135, 8, 4, 1, 211, 168, 3, 231, 165, 203, + 135, 8, 6, 1, 211, 32, 3, 106, 8, 4, 1, 211, 32, 3, 106, 8, 6, 1, 196, + 149, 3, 106, 8, 4, 1, 196, 149, 3, 106, 8, 4, 1, 163, 63, 8, 4, 1, 251, + 134, 8, 4, 1, 163, 251, 134, 8, 4, 1, 74, 3, 122, 8, 4, 1, 192, 72, 8, 4, + 1, 247, 208, 3, 241, 21, 8, 4, 1, 240, 232, 3, 203, 135, 8, 4, 1, 240, + 232, 3, 122, 8, 4, 1, 210, 89, 69, 8, 4, 1, 208, 163, 8, 4, 1, 208, 164, + 3, 122, 8, 4, 1, 192, 69, 8, 4, 1, 210, 89, 192, 69, 8, 4, 1, 210, 89, + 192, 237, 136, 3, 122, 8, 4, 1, 244, 203, 210, 89, 192, 69, 8, 4, 1, 238, + 252, 225, 218, 3, 106, 8, 4, 1, 234, 191, 3, 122, 8, 4, 1, 145, 234, 190, + 8, 1, 4, 6, 234, 190, 8, 4, 1, 234, 94, 8, 4, 1, 210, 208, 231, 102, 8, + 4, 1, 163, 233, 15, 8, 4, 1, 233, 16, 3, 122, 8, 4, 1, 232, 100, 3, 122, + 8, 4, 1, 230, 249, 3, 106, 8, 4, 1, 226, 7, 8, 1, 4, 6, 68, 8, 4, 1, 223, + 100, 3, 112, 202, 84, 8, 4, 1, 223, 100, 3, 248, 225, 8, 4, 1, 223, 100, + 3, 210, 95, 122, 8, 4, 1, 222, 125, 8, 4, 1, 163, 221, 136, 8, 4, 1, 163, + 221, 137, 3, 181, 222, 172, 8, 4, 1, 221, 137, 3, 122, 8, 4, 1, 218, 56, + 3, 50, 122, 8, 4, 1, 218, 56, 3, 210, 95, 122, 8, 1, 4, 6, 218, 55, 8, 4, + 1, 249, 74, 72, 8, 1, 4, 6, 214, 164, 8, 4, 1, 244, 203, 214, 124, 8, 4, + 1, 212, 246, 8, 4, 1, 163, 144, 8, 4, 1, 163, 211, 32, 3, 181, 222, 172, + 8, 4, 1, 163, 211, 32, 3, 122, 8, 4, 1, 211, 32, 3, 181, 222, 172, 8, 4, + 1, 211, 32, 3, 203, 135, 8, 4, 1, 211, 32, 3, 235, 108, 8, 4, 1, 210, 89, + 211, 32, 3, 235, 108, 8, 1, 4, 6, 144, 8, 1, 4, 6, 226, 17, 144, 8, 4, 1, + 209, 81, 3, 122, 8, 4, 1, 236, 141, 8, 4, 1, 238, 252, 225, 218, 3, 204, + 196, 26, 122, 8, 4, 1, 205, 91, 210, 89, 236, 141, 8, 4, 1, 236, 142, 3, + 241, 21, 8, 4, 1, 163, 203, 216, 8, 4, 1, 203, 217, 3, 210, 95, 122, 8, + 4, 1, 118, 154, 8, 4, 1, 200, 28, 8, 4, 1, 199, 231, 3, 122, 8, 4, 1, + 163, 199, 230, 8, 4, 1, 163, 197, 199, 8, 4, 1, 163, 196, 148, 8, 1, 4, + 6, 196, 148, 8, 4, 1, 195, 159, 3, 210, 95, 122, 8, 4, 1, 195, 159, 3, + 241, 21, 8, 4, 1, 236, 52, 8, 4, 1, 236, 53, 3, 241, 21, 8, 1, 233, 152, + 204, 226, 8, 1, 212, 253, 198, 244, 234, 241, 8, 1, 226, 17, 233, 152, + 204, 226, 8, 1, 204, 204, 247, 207, 8, 1, 248, 168, 244, 215, 8, 1, 4, 6, + 250, 112, 8, 4, 1, 244, 203, 192, 69, 8, 1, 4, 6, 234, 191, 3, 122, 8, 1, + 4, 6, 233, 15, 8, 4, 1, 225, 218, 3, 241, 57, 8, 4, 1, 163, 225, 80, 8, + 1, 4, 6, 159, 8, 4, 1, 211, 168, 3, 122, 8, 1, 233, 152, 204, 227, 3, + 106, 8, 1, 210, 89, 233, 152, 204, 227, 3, 106, 8, 4, 1, 237, 158, 239, + 110, 8, 4, 1, 239, 178, 239, 110, 8, 4, 1, 237, 158, 239, 111, 3, 241, + 21, 8, 4, 1, 201, 115, 239, 110, 8, 4, 1, 203, 7, 239, 110, 8, 4, 1, 203, + 75, 239, 111, 3, 241, 21, 8, 4, 1, 235, 167, 239, 110, 8, 4, 1, 221, 193, + 239, 110, 8, 4, 1, 221, 138, 239, 110, 8, 1, 248, 168, 213, 44, 8, 1, + 248, 176, 213, 44, 8, 4, 1, 163, 233, 16, 3, 235, 108, 8, 4, 1, 163, 233, + 16, 3, 235, 109, 26, 203, 135, 73, 1, 4, 233, 15, 73, 1, 4, 233, 16, 3, + 122, 73, 1, 4, 225, 217, 73, 1, 4, 144, 73, 1, 4, 163, 144, 73, 1, 4, + 163, 211, 32, 3, 122, 73, 1, 4, 6, 226, 17, 144, 73, 1, 4, 197, 199, 73, + 1, 4, 196, 148, 73, 1, 212, 19, 73, 1, 52, 212, 19, 73, 1, 163, 244, 159, + 73, 1, 251, 30, 73, 1, 210, 89, 244, 159, 73, 1, 53, 157, 210, 2, 73, 1, + 50, 157, 210, 2, 73, 1, 233, 152, 204, 226, 73, 1, 210, 89, 233, 152, + 204, 226, 73, 1, 50, 250, 217, 73, 1, 53, 250, 217, 73, 1, 124, 250, 217, + 73, 1, 135, 250, 217, 73, 1, 244, 241, 252, 22, 247, 106, 73, 1, 83, 222, + 75, 73, 1, 220, 114, 73, 1, 252, 10, 252, 22, 73, 1, 233, 101, 252, 22, + 73, 1, 126, 83, 222, 75, 73, 1, 126, 220, 114, 73, 1, 126, 233, 101, 252, + 22, 73, 1, 126, 252, 10, 252, 22, 73, 1, 201, 177, 244, 168, 73, 1, 157, + 201, 177, 244, 168, 73, 1, 247, 35, 53, 157, 210, 2, 73, 1, 247, 35, 50, + 157, 210, 2, 73, 1, 124, 203, 147, 73, 1, 135, 203, 147, 73, 1, 98, 55, + 73, 1, 219, 16, 55, 248, 47, 76, 57, 210, 3, 57, 214, 151, 4, 202, 84, + 52, 252, 10, 252, 22, 73, 1, 210, 73, 122, 73, 1, 241, 62, 252, 22, 73, + 1, 4, 234, 94, 73, 1, 4, 159, 73, 1, 4, 209, 80, 73, 1, 4, 196, 222, 73, + 1, 4, 210, 89, 233, 152, 204, 226, 73, 1, 236, 74, 152, 154, 73, 1, 130, + 152, 154, 73, 1, 219, 65, 152, 154, 73, 1, 126, 152, 154, 73, 1, 236, 73, + 152, 154, 73, 1, 196, 13, 239, 202, 152, 78, 73, 1, 196, 96, 239, 202, + 152, 78, 73, 1, 198, 242, 73, 1, 200, 68, 73, 1, 52, 251, 30, 73, 1, 126, + 135, 250, 217, 73, 1, 126, 124, 250, 217, 73, 1, 126, 50, 250, 217, 73, + 1, 126, 53, 250, 217, 73, 1, 126, 210, 2, 73, 1, 112, 233, 101, 252, 22, + 73, 1, 112, 52, 233, 101, 252, 22, 73, 1, 112, 52, 252, 10, 252, 22, 73, + 1, 126, 202, 84, 73, 1, 210, 215, 244, 168, 73, 1, 248, 243, 130, 202, + 11, 73, 1, 236, 222, 130, 202, 11, 73, 1, 248, 243, 126, 202, 11, 73, 1, + 236, 222, 126, 202, 11, 73, 1, 206, 246, 73, 1, 192, 206, 246, 73, 1, + 126, 50, 51, 38, 233, 101, 252, 22, 38, 252, 10, 252, 22, 38, 244, 241, + 252, 22, 38, 202, 84, 38, 220, 114, 38, 214, 19, 38, 248, 47, 38, 76, 57, + 38, 239, 150, 38, 231, 165, 57, 38, 210, 3, 57, 38, 52, 252, 10, 252, 22, + 38, 247, 106, 38, 83, 222, 76, 57, 38, 52, 83, 222, 76, 57, 38, 52, 233, + 101, 252, 22, 38, 247, 133, 38, 226, 17, 248, 47, 38, 163, 244, 160, 57, + 38, 244, 160, 57, 38, 210, 89, 244, 160, 57, 38, 244, 160, 90, 210, 22, + 38, 233, 101, 252, 23, 60, 38, 252, 10, 252, 23, 60, 38, 50, 203, 148, + 60, 38, 53, 203, 148, 60, 38, 50, 251, 91, 57, 38, 231, 102, 38, 50, 157, + 210, 3, 60, 38, 124, 203, 148, 60, 38, 135, 203, 148, 60, 38, 98, 2, 60, + 38, 219, 16, 2, 60, 38, 213, 213, 231, 165, 60, 38, 210, 95, 231, 165, + 60, 38, 76, 60, 38, 239, 151, 60, 38, 210, 3, 60, 38, 244, 160, 60, 38, + 247, 50, 38, 214, 151, 38, 83, 222, 76, 60, 38, 248, 40, 60, 38, 226, 17, + 52, 250, 252, 60, 38, 247, 107, 60, 38, 244, 241, 252, 23, 60, 38, 248, + 48, 60, 38, 226, 17, 248, 48, 60, 38, 202, 85, 60, 38, 220, 115, 60, 38, + 126, 222, 75, 38, 52, 126, 222, 75, 38, 202, 85, 214, 20, 38, 206, 182, + 204, 196, 214, 20, 38, 181, 204, 196, 214, 20, 38, 206, 182, 205, 178, + 214, 20, 38, 181, 205, 178, 214, 20, 38, 53, 157, 210, 3, 60, 38, 226, + 17, 248, 40, 60, 38, 47, 60, 38, 208, 141, 60, 38, 196, 223, 57, 38, 83, + 202, 84, 38, 52, 214, 19, 38, 233, 101, 152, 78, 38, 252, 10, 152, 78, + 38, 32, 213, 38, 38, 32, 223, 232, 38, 32, 239, 144, 201, 248, 38, 32, + 195, 225, 38, 248, 40, 57, 38, 236, 172, 2, 60, 38, 52, 83, 222, 76, 60, + 38, 50, 251, 91, 60, 38, 216, 19, 202, 85, 57, 38, 231, 171, 57, 38, 251, + 139, 180, 202, 30, 57, 38, 50, 53, 61, 60, 38, 200, 24, 61, 60, 38, 233, + 107, 225, 124, 38, 53, 250, 218, 57, 38, 50, 157, 210, 3, 57, 38, 235, + 164, 38, 196, 223, 60, 38, 50, 250, 218, 60, 38, 53, 250, 218, 60, 38, + 53, 250, 218, 26, 124, 250, 218, 60, 38, 53, 157, 210, 3, 57, 38, 76, 90, + 210, 22, 38, 250, 180, 60, 38, 52, 210, 3, 60, 38, 195, 24, 57, 38, 52, + 248, 48, 60, 38, 52, 248, 47, 38, 52, 220, 114, 38, 52, 220, 115, 60, 38, + 52, 202, 84, 38, 52, 226, 17, 248, 47, 38, 52, 91, 61, 60, 38, 8, 4, 1, + 63, 38, 8, 4, 1, 69, 38, 8, 4, 1, 68, 38, 8, 4, 1, 72, 38, 8, 4, 1, 66, + 38, 8, 4, 1, 247, 207, 38, 8, 4, 1, 240, 231, 38, 8, 4, 1, 233, 15, 38, + 8, 4, 1, 221, 136, 38, 8, 4, 1, 144, 38, 8, 4, 1, 203, 216, 38, 8, 4, 1, + 199, 230, 38, 8, 4, 1, 196, 222, 32, 6, 1, 232, 88, 32, 4, 1, 232, 88, + 32, 6, 1, 250, 251, 208, 222, 32, 4, 1, 250, 251, 208, 222, 32, 215, 142, + 55, 32, 221, 203, 215, 142, 55, 32, 6, 1, 213, 196, 239, 118, 32, 4, 1, + 213, 196, 239, 118, 32, 195, 225, 32, 4, 210, 89, 221, 173, 206, 87, 105, + 32, 4, 237, 250, 221, 173, 206, 87, 105, 32, 4, 210, 89, 237, 250, 221, + 173, 206, 87, 105, 32, 211, 79, 78, 32, 6, 1, 195, 232, 32, 201, 248, 32, + 239, 144, 201, 248, 32, 6, 1, 251, 135, 3, 201, 248, 32, 251, 74, 203, + 35, 32, 6, 1, 236, 175, 3, 201, 248, 32, 6, 1, 236, 127, 3, 201, 248, 32, + 6, 1, 226, 8, 3, 201, 248, 32, 6, 1, 214, 123, 3, 201, 248, 32, 6, 1, + 200, 29, 3, 201, 248, 32, 6, 1, 214, 125, 3, 201, 248, 32, 4, 1, 226, 8, + 3, 239, 144, 26, 201, 248, 32, 6, 1, 251, 134, 32, 6, 1, 248, 206, 32, 6, + 1, 234, 94, 32, 6, 1, 239, 212, 32, 6, 1, 236, 174, 32, 6, 1, 195, 78, + 32, 6, 1, 236, 126, 32, 6, 1, 202, 199, 32, 6, 1, 226, 7, 32, 6, 1, 225, + 2, 32, 6, 1, 222, 245, 32, 6, 1, 218, 145, 32, 6, 1, 215, 186, 32, 6, 1, + 196, 196, 32, 6, 1, 214, 122, 32, 6, 1, 212, 220, 32, 6, 1, 210, 74, 32, + 6, 1, 206, 86, 32, 6, 1, 203, 89, 32, 6, 1, 200, 28, 32, 6, 1, 212, 246, + 32, 6, 1, 245, 75, 32, 6, 1, 211, 238, 32, 6, 1, 214, 124, 32, 6, 1, 226, + 8, 3, 239, 143, 32, 6, 1, 200, 29, 3, 239, 143, 32, 4, 1, 251, 135, 3, + 201, 248, 32, 4, 1, 236, 175, 3, 201, 248, 32, 4, 1, 236, 127, 3, 201, + 248, 32, 4, 1, 226, 8, 3, 201, 248, 32, 4, 1, 200, 29, 3, 239, 144, 26, + 201, 248, 32, 4, 1, 251, 134, 32, 4, 1, 248, 206, 32, 4, 1, 234, 94, 32, + 4, 1, 239, 212, 32, 4, 1, 236, 174, 32, 4, 1, 195, 78, 32, 4, 1, 236, + 126, 32, 4, 1, 202, 199, 32, 4, 1, 226, 7, 32, 4, 1, 225, 2, 32, 4, 1, + 222, 245, 32, 4, 1, 218, 145, 32, 4, 1, 215, 186, 32, 4, 1, 196, 196, 32, + 4, 1, 214, 122, 32, 4, 1, 212, 220, 32, 4, 1, 210, 74, 32, 4, 1, 48, 206, + 86, 32, 4, 1, 206, 86, 32, 4, 1, 203, 89, 32, 4, 1, 200, 28, 32, 4, 1, + 212, 246, 32, 4, 1, 245, 75, 32, 4, 1, 211, 238, 32, 4, 1, 214, 124, 32, + 4, 1, 226, 8, 3, 239, 143, 32, 4, 1, 200, 29, 3, 239, 143, 32, 4, 1, 214, + 123, 3, 201, 248, 32, 4, 1, 200, 29, 3, 201, 248, 32, 4, 1, 214, 125, 3, + 201, 248, 32, 6, 225, 32, 105, 32, 248, 207, 105, 32, 202, 200, 105, 32, + 200, 29, 3, 231, 165, 105, 32, 200, 29, 3, 252, 10, 26, 231, 165, 105, + 32, 200, 29, 3, 239, 151, 26, 231, 165, 105, 32, 212, 247, 105, 32, 212, + 221, 105, 32, 225, 32, 105, 32, 1, 250, 251, 223, 236, 32, 4, 1, 250, + 251, 223, 236, 32, 1, 204, 236, 32, 4, 1, 204, 236, 32, 1, 239, 118, 32, + 4, 1, 239, 118, 32, 1, 223, 236, 32, 4, 1, 223, 236, 32, 1, 208, 222, 32, + 4, 1, 208, 222, 88, 6, 1, 206, 247, 88, 4, 1, 206, 247, 88, 6, 1, 235, + 174, 88, 4, 1, 235, 174, 88, 6, 1, 224, 129, 88, 4, 1, 224, 129, 88, 6, + 1, 231, 156, 88, 4, 1, 231, 156, 88, 6, 1, 234, 89, 88, 4, 1, 234, 89, + 88, 6, 1, 206, 213, 88, 4, 1, 206, 213, 88, 6, 1, 239, 228, 88, 4, 1, + 239, 228, 32, 225, 3, 105, 32, 210, 75, 105, 32, 221, 173, 206, 87, 105, + 32, 1, 195, 232, 32, 6, 202, 200, 105, 32, 221, 173, 236, 175, 105, 32, + 210, 89, 221, 173, 236, 175, 105, 32, 6, 1, 206, 198, 32, 4, 1, 206, 198, + 32, 6, 221, 173, 206, 87, 105, 32, 6, 1, 208, 219, 32, 4, 1, 208, 219, + 32, 210, 75, 3, 204, 196, 105, 32, 6, 210, 89, 221, 173, 206, 87, 105, + 32, 6, 237, 250, 221, 173, 206, 87, 105, 32, 6, 210, 89, 237, 250, 221, + 173, 206, 87, 105, 40, 6, 1, 226, 148, 3, 233, 100, 40, 6, 1, 226, 12, + 40, 6, 1, 239, 46, 40, 6, 1, 233, 161, 40, 6, 1, 200, 84, 226, 147, 40, + 6, 1, 237, 153, 40, 6, 1, 247, 217, 68, 40, 6, 1, 196, 24, 40, 6, 1, 225, + 193, 40, 6, 1, 222, 40, 40, 6, 1, 216, 157, 40, 6, 1, 201, 101, 40, 6, 1, + 224, 38, 40, 6, 1, 230, 249, 3, 233, 100, 40, 6, 1, 206, 182, 66, 40, 6, + 1, 237, 149, 40, 6, 1, 63, 40, 6, 1, 249, 9, 40, 6, 1, 199, 118, 40, 6, + 1, 233, 216, 40, 6, 1, 239, 252, 40, 6, 1, 226, 147, 40, 6, 1, 195, 65, + 40, 6, 1, 195, 88, 40, 6, 1, 68, 40, 6, 1, 206, 182, 68, 40, 6, 1, 155, + 40, 6, 1, 237, 7, 40, 6, 1, 236, 241, 40, 6, 1, 236, 230, 40, 6, 1, 72, + 40, 6, 1, 213, 92, 40, 6, 1, 236, 163, 40, 6, 1, 236, 151, 40, 6, 1, 203, + 68, 40, 6, 1, 66, 40, 6, 1, 237, 47, 40, 6, 1, 142, 40, 6, 1, 201, 107, + 40, 6, 1, 245, 103, 40, 6, 1, 207, 50, 40, 6, 1, 207, 2, 40, 6, 1, 232, + 173, 55, 40, 6, 1, 196, 47, 40, 6, 1, 205, 186, 55, 40, 6, 1, 69, 40, 6, + 1, 195, 217, 40, 6, 1, 164, 40, 4, 1, 63, 40, 4, 1, 249, 9, 40, 4, 1, + 199, 118, 40, 4, 1, 233, 216, 40, 4, 1, 239, 252, 40, 4, 1, 226, 147, 40, + 4, 1, 195, 65, 40, 4, 1, 195, 88, 40, 4, 1, 68, 40, 4, 1, 206, 182, 68, + 40, 4, 1, 155, 40, 4, 1, 237, 7, 40, 4, 1, 236, 241, 40, 4, 1, 236, 230, + 40, 4, 1, 72, 40, 4, 1, 213, 92, 40, 4, 1, 236, 163, 40, 4, 1, 236, 151, + 40, 4, 1, 203, 68, 40, 4, 1, 66, 40, 4, 1, 237, 47, 40, 4, 1, 142, 40, 4, + 1, 201, 107, 40, 4, 1, 245, 103, 40, 4, 1, 207, 50, 40, 4, 1, 207, 2, 40, + 4, 1, 232, 173, 55, 40, 4, 1, 196, 47, 40, 4, 1, 205, 186, 55, 40, 4, 1, + 69, 40, 4, 1, 195, 217, 40, 4, 1, 164, 40, 4, 1, 226, 148, 3, 233, 100, + 40, 4, 1, 226, 12, 40, 4, 1, 239, 46, 40, 4, 1, 233, 161, 40, 4, 1, 200, + 84, 226, 147, 40, 4, 1, 237, 153, 40, 4, 1, 247, 217, 68, 40, 4, 1, 196, + 24, 40, 4, 1, 225, 193, 40, 4, 1, 222, 40, 40, 4, 1, 216, 157, 40, 4, 1, + 201, 101, 40, 4, 1, 224, 38, 40, 4, 1, 230, 249, 3, 233, 100, 40, 4, 1, + 206, 182, 66, 40, 4, 1, 237, 149, 40, 6, 1, 214, 124, 40, 4, 1, 214, 124, + 40, 6, 1, 196, 84, 40, 4, 1, 196, 84, 40, 6, 1, 226, 5, 69, 40, 4, 1, + 226, 5, 69, 40, 6, 1, 222, 47, 195, 182, 40, 4, 1, 222, 47, 195, 182, 40, + 6, 1, 226, 5, 222, 47, 195, 182, 40, 4, 1, 226, 5, 222, 47, 195, 182, 40, + 6, 1, 248, 171, 195, 182, 40, 4, 1, 248, 171, 195, 182, 40, 6, 1, 226, 5, + 248, 171, 195, 182, 40, 4, 1, 226, 5, 248, 171, 195, 182, 40, 6, 1, 223, + 203, 40, 4, 1, 223, 203, 40, 6, 1, 211, 238, 40, 4, 1, 211, 238, 40, 6, + 1, 235, 103, 40, 4, 1, 235, 103, 40, 6, 1, 225, 219, 40, 4, 1, 225, 219, + 40, 6, 1, 225, 220, 3, 52, 233, 101, 252, 22, 40, 4, 1, 225, 220, 3, 52, + 233, 101, 252, 22, 40, 6, 1, 200, 87, 40, 4, 1, 200, 87, 40, 6, 1, 209, + 187, 214, 124, 40, 4, 1, 209, 187, 214, 124, 40, 6, 1, 214, 125, 3, 202, + 54, 40, 4, 1, 214, 125, 3, 202, 54, 40, 6, 1, 214, 49, 40, 4, 1, 214, 49, + 40, 6, 1, 223, 236, 40, 4, 1, 223, 236, 40, 202, 158, 55, 38, 40, 202, + 54, 38, 40, 213, 214, 38, 40, 240, 63, 212, 119, 38, 40, 211, 232, 212, + 119, 38, 40, 212, 103, 38, 40, 231, 58, 202, 158, 55, 38, 40, 219, 27, + 55, 40, 6, 1, 206, 182, 230, 249, 3, 203, 135, 40, 4, 1, 206, 182, 230, + 249, 3, 203, 135, 40, 6, 1, 207, 101, 55, 40, 4, 1, 207, 101, 55, 40, 6, + 1, 236, 164, 3, 202, 111, 40, 4, 1, 236, 164, 3, 202, 111, 40, 6, 1, 233, + 217, 3, 200, 27, 40, 4, 1, 233, 217, 3, 200, 27, 40, 6, 1, 233, 217, 3, + 106, 40, 4, 1, 233, 217, 3, 106, 40, 6, 1, 233, 217, 3, 112, 122, 40, 4, + 1, 233, 217, 3, 112, 122, 40, 6, 1, 195, 66, 3, 239, 195, 40, 4, 1, 195, + 66, 3, 239, 195, 40, 6, 1, 195, 89, 3, 239, 195, 40, 4, 1, 195, 89, 3, + 239, 195, 40, 6, 1, 225, 70, 3, 239, 195, 40, 4, 1, 225, 70, 3, 239, 195, + 40, 6, 1, 225, 70, 3, 83, 106, 40, 4, 1, 225, 70, 3, 83, 106, 40, 6, 1, + 225, 70, 3, 106, 40, 4, 1, 225, 70, 3, 106, 40, 6, 1, 249, 62, 155, 40, + 4, 1, 249, 62, 155, 40, 6, 1, 236, 231, 3, 239, 195, 40, 4, 1, 236, 231, + 3, 239, 195, 40, 6, 33, 236, 231, 233, 216, 40, 4, 33, 236, 231, 233, + 216, 40, 6, 1, 213, 93, 3, 112, 122, 40, 4, 1, 213, 93, 3, 112, 122, 40, + 6, 1, 252, 29, 142, 40, 4, 1, 252, 29, 142, 40, 6, 1, 236, 152, 3, 239, + 195, 40, 4, 1, 236, 152, 3, 239, 195, 40, 6, 1, 203, 69, 3, 239, 195, 40, + 4, 1, 203, 69, 3, 239, 195, 40, 6, 1, 204, 218, 66, 40, 4, 1, 204, 218, + 66, 40, 6, 1, 204, 218, 118, 3, 106, 40, 4, 1, 204, 218, 118, 3, 106, 40, + 6, 1, 233, 4, 3, 239, 195, 40, 4, 1, 233, 4, 3, 239, 195, 40, 6, 33, 203, + 69, 201, 107, 40, 4, 33, 203, 69, 201, 107, 40, 6, 1, 245, 104, 3, 239, + 195, 40, 4, 1, 245, 104, 3, 239, 195, 40, 6, 1, 245, 104, 3, 83, 106, 40, + 4, 1, 245, 104, 3, 83, 106, 40, 6, 1, 206, 224, 40, 4, 1, 206, 224, 40, + 6, 1, 252, 29, 245, 103, 40, 4, 1, 252, 29, 245, 103, 40, 6, 1, 252, 29, + 245, 104, 3, 239, 195, 40, 4, 1, 252, 29, 245, 104, 3, 239, 195, 40, 1, + 213, 203, 40, 6, 1, 195, 66, 3, 248, 47, 40, 4, 1, 195, 66, 3, 248, 47, + 40, 6, 1, 225, 70, 3, 122, 40, 4, 1, 225, 70, 3, 122, 40, 6, 1, 237, 8, + 3, 203, 135, 40, 4, 1, 237, 8, 3, 203, 135, 40, 6, 1, 236, 231, 3, 122, + 40, 4, 1, 236, 231, 3, 122, 40, 6, 1, 236, 231, 3, 203, 135, 40, 4, 1, + 236, 231, 3, 203, 135, 40, 6, 1, 224, 140, 245, 103, 40, 4, 1, 224, 140, + 245, 103, 40, 6, 1, 236, 242, 3, 203, 135, 40, 4, 1, 236, 242, 3, 203, + 135, 40, 4, 1, 213, 203, 40, 6, 1, 39, 3, 248, 47, 40, 4, 1, 39, 3, 248, + 47, 40, 6, 1, 39, 3, 239, 150, 40, 4, 1, 39, 3, 239, 150, 40, 6, 33, 39, + 226, 147, 40, 4, 33, 39, 226, 147, 40, 6, 1, 226, 148, 3, 248, 47, 40, 4, + 1, 226, 148, 3, 248, 47, 40, 6, 1, 208, 163, 40, 4, 1, 208, 163, 40, 6, + 1, 208, 164, 3, 239, 150, 40, 4, 1, 208, 164, 3, 239, 150, 40, 6, 1, 195, + 66, 3, 239, 150, 40, 4, 1, 195, 66, 3, 239, 150, 40, 6, 1, 195, 89, 3, + 239, 150, 40, 4, 1, 195, 89, 3, 239, 150, 40, 6, 1, 252, 29, 237, 153, + 40, 4, 1, 252, 29, 237, 153, 40, 6, 1, 230, 249, 3, 220, 114, 40, 4, 1, + 230, 249, 3, 220, 114, 40, 6, 1, 230, 249, 3, 239, 150, 40, 4, 1, 230, + 249, 3, 239, 150, 40, 6, 1, 177, 3, 239, 150, 40, 4, 1, 177, 3, 239, 150, + 40, 6, 1, 249, 74, 72, 40, 4, 1, 249, 74, 72, 40, 6, 1, 249, 74, 177, 3, + 239, 150, 40, 4, 1, 249, 74, 177, 3, 239, 150, 40, 6, 1, 237, 136, 3, + 239, 150, 40, 4, 1, 237, 136, 3, 239, 150, 40, 6, 1, 118, 3, 220, 114, + 40, 4, 1, 118, 3, 220, 114, 40, 6, 1, 118, 3, 239, 150, 40, 4, 1, 118, 3, + 239, 150, 40, 6, 1, 118, 3, 52, 186, 40, 4, 1, 118, 3, 52, 186, 40, 6, 1, + 245, 104, 3, 239, 150, 40, 4, 1, 245, 104, 3, 239, 150, 40, 6, 1, 233, + 217, 3, 239, 195, 40, 4, 1, 233, 217, 3, 239, 195, 40, 6, 1, 196, 48, 3, + 239, 150, 40, 4, 1, 196, 48, 3, 239, 150, 40, 6, 1, 233, 217, 3, 204, + 196, 26, 122, 40, 4, 1, 233, 217, 3, 204, 196, 26, 122, 40, 6, 1, 233, 4, + 3, 122, 40, 4, 1, 233, 4, 3, 122, 40, 6, 1, 233, 4, 3, 106, 40, 4, 1, + 233, 4, 3, 106, 40, 6, 1, 223, 246, 239, 252, 40, 4, 1, 223, 246, 239, + 252, 40, 6, 1, 223, 246, 239, 46, 40, 4, 1, 223, 246, 239, 46, 40, 6, 1, + 223, 246, 195, 15, 40, 4, 1, 223, 246, 195, 15, 40, 6, 1, 223, 246, 237, + 145, 40, 4, 1, 223, 246, 237, 145, 40, 6, 1, 223, 246, 222, 40, 40, 4, 1, + 223, 246, 222, 40, 40, 6, 1, 223, 246, 216, 157, 40, 4, 1, 223, 246, 216, + 157, 40, 6, 1, 223, 246, 206, 8, 40, 4, 1, 223, 246, 206, 8, 40, 6, 1, + 223, 246, 202, 48, 40, 4, 1, 223, 246, 202, 48, 40, 6, 1, 210, 89, 195, + 88, 40, 4, 1, 210, 89, 195, 88, 40, 6, 1, 237, 8, 3, 122, 40, 4, 1, 237, + 8, 3, 122, 40, 6, 1, 222, 122, 40, 4, 1, 222, 122, 40, 6, 1, 210, 77, 40, + 4, 1, 210, 77, 40, 6, 1, 196, 118, 40, 4, 1, 196, 118, 40, 6, 1, 211, + 159, 40, 4, 1, 211, 159, 40, 6, 1, 197, 109, 40, 4, 1, 197, 109, 40, 6, + 1, 251, 160, 155, 40, 4, 1, 251, 160, 155, 40, 6, 1, 237, 8, 3, 112, 122, + 40, 4, 1, 237, 8, 3, 112, 122, 40, 6, 1, 236, 231, 3, 112, 122, 40, 4, 1, + 236, 231, 3, 112, 122, 40, 6, 1, 213, 93, 3, 239, 195, 40, 4, 1, 213, 93, + 3, 239, 195, 40, 6, 1, 206, 225, 3, 239, 195, 40, 4, 1, 206, 225, 3, 239, + 195, 40, 6, 1, 236, 231, 3, 50, 122, 40, 4, 1, 236, 231, 3, 50, 122, 40, + 6, 1, 237, 137, 40, 4, 1, 237, 137, 40, 6, 1, 240, 45, 40, 4, 1, 240, 45, + 40, 6, 1, 237, 8, 3, 239, 195, 40, 4, 1, 237, 8, 3, 239, 195, 250, 230, + 6, 1, 250, 119, 250, 230, 6, 1, 248, 223, 250, 230, 6, 1, 233, 179, 250, + 230, 6, 1, 240, 136, 250, 230, 6, 1, 237, 60, 250, 230, 6, 1, 195, 115, + 250, 230, 6, 1, 237, 40, 250, 230, 6, 1, 236, 128, 250, 230, 6, 1, 149, + 250, 230, 6, 1, 195, 65, 250, 230, 6, 1, 226, 55, 250, 230, 6, 1, 222, + 44, 250, 230, 6, 1, 196, 200, 250, 230, 6, 1, 247, 174, 250, 230, 6, 1, + 224, 182, 250, 230, 6, 1, 231, 193, 250, 230, 6, 1, 225, 214, 250, 230, + 6, 1, 233, 227, 250, 230, 6, 1, 245, 93, 250, 230, 6, 1, 219, 164, 250, + 230, 6, 1, 196, 24, 250, 230, 6, 1, 216, 4, 250, 230, 6, 1, 207, 50, 250, + 230, 6, 1, 198, 248, 250, 230, 6, 1, 247, 16, 250, 230, 6, 1, 213, 72, + 250, 230, 6, 1, 225, 175, 250, 230, 6, 1, 169, 250, 230, 6, 1, 208, 119, + 250, 230, 6, 1, 199, 39, 250, 230, 6, 1, 202, 51, 250, 230, 6, 1, 210, + 142, 250, 230, 6, 1, 244, 182, 250, 230, 6, 1, 196, 8, 250, 230, 6, 1, + 212, 154, 250, 230, 6, 1, 224, 193, 250, 230, 6, 1, 214, 149, 250, 230, + 6, 1, 235, 176, 250, 230, 73, 1, 50, 157, 210, 2, 250, 230, 251, 30, 250, + 230, 236, 234, 78, 250, 230, 236, 90, 78, 250, 230, 244, 159, 250, 230, + 211, 79, 78, 250, 230, 252, 30, 78, 250, 230, 4, 1, 163, 250, 119, 250, + 230, 4, 1, 250, 119, 250, 230, 4, 1, 248, 223, 250, 230, 4, 1, 233, 179, + 250, 230, 4, 1, 240, 136, 250, 230, 4, 1, 237, 60, 250, 230, 4, 1, 195, + 115, 250, 230, 4, 1, 237, 40, 250, 230, 4, 1, 236, 128, 250, 230, 4, 1, + 149, 250, 230, 4, 1, 195, 65, 250, 230, 4, 1, 226, 55, 250, 230, 4, 1, + 222, 44, 250, 230, 4, 1, 196, 200, 250, 230, 4, 1, 247, 174, 250, 230, 4, + 1, 224, 182, 250, 230, 4, 1, 231, 193, 250, 230, 4, 1, 225, 214, 250, + 230, 4, 1, 233, 227, 250, 230, 4, 1, 245, 93, 250, 230, 4, 1, 219, 164, + 250, 230, 4, 1, 196, 24, 250, 230, 4, 1, 216, 4, 250, 230, 4, 1, 207, 50, + 250, 230, 4, 1, 198, 248, 250, 230, 4, 1, 247, 16, 250, 230, 4, 1, 213, + 72, 250, 230, 4, 1, 225, 175, 250, 230, 4, 1, 169, 250, 230, 4, 1, 208, + 119, 250, 230, 4, 1, 199, 39, 250, 230, 4, 1, 202, 51, 250, 230, 4, 1, + 210, 142, 250, 230, 4, 1, 244, 182, 250, 230, 4, 1, 196, 8, 250, 230, 4, + 1, 212, 154, 250, 230, 4, 1, 224, 193, 250, 230, 4, 1, 214, 149, 250, + 230, 4, 1, 235, 176, 250, 230, 4, 33, 237, 61, 196, 8, 250, 230, 4, 1, + 11, 3, 106, 250, 230, 234, 217, 204, 226, 250, 230, 231, 7, 210, 21, 250, + 230, 236, 124, 55, 222, 183, 250, 230, 236, 124, 55, 250, 230, 237, 222, + 55, 123, 252, 23, 236, 119, 123, 252, 23, 208, 120, 123, 252, 23, 207, + 27, 123, 252, 23, 195, 100, 211, 142, 123, 252, 23, 195, 100, 234, 113, + 123, 252, 23, 202, 66, 123, 252, 23, 210, 86, 123, 252, 23, 195, 98, 123, + 252, 23, 213, 124, 123, 252, 23, 196, 37, 123, 252, 23, 202, 240, 123, + 252, 23, 234, 22, 123, 252, 23, 234, 23, 218, 102, 123, 252, 23, 234, 20, + 123, 252, 23, 211, 143, 213, 156, 123, 252, 23, 203, 30, 234, 41, 123, + 252, 23, 213, 98, 123, 252, 23, 250, 159, 232, 240, 123, 252, 23, 218, + 112, 123, 252, 23, 220, 86, 123, 252, 23, 219, 153, 123, 252, 23, 219, + 154, 224, 194, 123, 252, 23, 240, 72, 123, 252, 23, 211, 154, 123, 252, + 23, 203, 30, 211, 137, 123, 252, 23, 196, 50, 248, 224, 195, 238, 123, + 252, 23, 214, 131, 123, 252, 23, 226, 106, 123, 252, 23, 239, 229, 123, + 252, 23, 195, 22, 123, 117, 220, 8, 244, 249, 123, 212, 111, 206, 227, + 123, 212, 111, 232, 164, 208, 120, 123, 212, 111, 232, 164, 213, 115, + 123, 212, 111, 232, 164, 211, 147, 123, 212, 111, 232, 33, 123, 212, 111, + 201, 104, 123, 212, 111, 208, 120, 123, 212, 111, 213, 115, 123, 212, + 111, 211, 147, 123, 212, 111, 231, 177, 123, 212, 111, 231, 178, 232, + 166, 36, 199, 122, 123, 212, 111, 211, 83, 123, 212, 111, 240, 121, 214, + 73, 220, 42, 123, 212, 111, 219, 142, 123, 211, 214, 220, 39, 123, 212, + 111, 210, 227, 123, 211, 214, 213, 126, 123, 212, 111, 206, 212, 238, + 253, 123, 212, 111, 206, 66, 238, 253, 123, 211, 214, 205, 187, 213, 117, + 123, 117, 200, 33, 238, 253, 123, 117, 221, 203, 238, 253, 123, 211, 214, + 215, 139, 232, 239, 123, 212, 111, 211, 148, 211, 142, 123, 1, 251, 164, + 123, 1, 248, 208, 123, 1, 233, 177, 123, 1, 240, 101, 123, 1, 232, 147, + 123, 1, 199, 122, 123, 1, 195, 92, 123, 1, 232, 89, 123, 1, 203, 1, 123, + 1, 195, 241, 123, 1, 48, 225, 35, 123, 1, 225, 35, 123, 1, 222, 241, 123, + 1, 48, 219, 171, 123, 1, 219, 171, 123, 1, 48, 215, 138, 123, 1, 215, + 138, 123, 1, 208, 225, 123, 1, 250, 117, 123, 1, 48, 213, 92, 123, 1, + 213, 92, 123, 1, 48, 201, 108, 123, 1, 201, 108, 123, 1, 211, 106, 123, + 1, 210, 109, 123, 1, 206, 211, 123, 1, 203, 85, 123, 195, 242, 201, 180, + 123, 33, 196, 22, 52, 199, 122, 123, 33, 196, 22, 199, 123, 195, 241, + 123, 33, 196, 22, 52, 195, 241, 123, 211, 214, 234, 22, 123, 211, 214, + 234, 20, 9, 31, 55, 9, 2, 208, 218, 9, 235, 35, 220, 24, 9, 2, 209, 3, 9, + 2, 208, 221, 9, 31, 117, 57, 251, 9, 241, 37, 209, 200, 251, 9, 235, 0, + 209, 200, 9, 210, 191, 251, 9, 213, 46, 219, 29, 55, 251, 9, 213, 46, + 203, 24, 202, 159, 55, 251, 222, 55, 9, 244, 159, 9, 240, 59, 207, 90, 9, + 212, 113, 199, 102, 55, 9, 2, 219, 8, 9, 2, 208, 235, 251, 167, 197, 133, + 9, 2, 251, 167, 250, 184, 9, 2, 210, 225, 251, 166, 9, 2, 210, 233, 251, + 144, 251, 82, 9, 2, 203, 126, 9, 4, 130, 203, 139, 9, 4, 130, 33, 151, 3, + 222, 250, 3, 196, 64, 9, 4, 130, 195, 106, 9, 4, 235, 200, 9, 4, 240, 95, + 9, 4, 224, 238, 9, 207, 105, 9, 1, 78, 9, 201, 165, 76, 211, 214, 78, 9, + 211, 79, 78, 9, 1, 224, 242, 196, 64, 9, 1, 232, 213, 9, 1, 151, 3, 220, + 110, 57, 9, 1, 151, 3, 232, 214, 57, 9, 1, 197, 118, 3, 232, 214, 57, 9, + 1, 151, 3, 232, 214, 60, 9, 1, 93, 3, 232, 214, 57, 9, 1, 251, 164, 9, 1, + 248, 239, 9, 1, 203, 42, 220, 35, 9, 1, 203, 41, 9, 1, 202, 213, 9, 1, + 225, 189, 9, 1, 232, 236, 9, 1, 224, 142, 9, 1, 240, 107, 9, 1, 202, 225, + 9, 1, 210, 142, 9, 1, 195, 106, 9, 1, 208, 125, 9, 1, 206, 251, 9, 1, + 209, 8, 9, 1, 240, 130, 9, 1, 203, 139, 9, 1, 195, 109, 9, 1, 251, 194, + 9, 1, 233, 225, 9, 1, 224, 192, 3, 99, 238, 251, 57, 9, 1, 224, 192, 3, + 115, 238, 251, 60, 9, 1, 235, 204, 93, 3, 226, 17, 199, 230, 9, 1, 235, + 204, 93, 3, 99, 238, 251, 57, 9, 1, 235, 204, 93, 3, 115, 238, 251, 57, + 9, 203, 91, 9, 1, 235, 176, 9, 1, 211, 152, 9, 1, 225, 35, 9, 1, 222, + 249, 9, 1, 219, 185, 9, 1, 216, 31, 9, 1, 232, 113, 9, 1, 197, 117, 9, 1, + 151, 220, 69, 9, 1, 196, 64, 9, 235, 198, 9, 240, 93, 9, 224, 236, 9, + 235, 200, 9, 240, 95, 9, 224, 238, 9, 207, 40, 9, 204, 119, 9, 220, 108, + 57, 9, 232, 214, 57, 9, 232, 214, 60, 9, 204, 143, 251, 164, 9, 226, 17, + 240, 95, 9, 117, 216, 32, 233, 196, 9, 194, 241, 9, 18, 2, 4, 199, 231, + 57, 9, 18, 2, 226, 17, 4, 199, 231, 57, 9, 18, 2, 76, 60, 9, 210, 89, + 240, 95, 9, 235, 201, 3, 99, 238, 250, 9, 197, 119, 232, 214, 60, 251, 9, + 17, 195, 79, 251, 9, 17, 100, 251, 9, 17, 102, 251, 9, 17, 134, 251, 9, + 17, 136, 251, 9, 17, 146, 251, 9, 17, 167, 251, 9, 17, 178, 251, 9, 17, + 171, 251, 9, 17, 182, 9, 213, 45, 55, 9, 239, 244, 207, 90, 9, 202, 158, + 207, 90, 9, 235, 101, 212, 109, 205, 7, 9, 1, 238, 252, 248, 239, 9, 1, + 238, 252, 211, 152, 9, 1, 204, 95, 251, 164, 9, 1, 151, 197, 134, 9, 1, + 151, 3, 197, 119, 232, 214, 57, 9, 1, 151, 3, 197, 119, 232, 214, 60, 9, + 1, 130, 232, 213, 9, 1, 130, 232, 214, 251, 164, 9, 1, 130, 232, 214, + 197, 117, 9, 1, 118, 3, 232, 214, 57, 9, 1, 130, 232, 214, 196, 64, 9, 1, + 201, 70, 9, 1, 201, 68, 9, 1, 248, 249, 9, 1, 203, 42, 3, 210, 2, 9, 1, + 203, 42, 3, 115, 238, 251, 90, 237, 230, 9, 1, 213, 72, 9, 1, 203, 39, 9, + 1, 248, 237, 9, 1, 168, 3, 232, 214, 57, 9, 1, 168, 3, 99, 238, 251, 83, + 57, 9, 1, 215, 95, 9, 1, 237, 162, 9, 1, 168, 3, 115, 238, 251, 57, 9, 1, + 203, 72, 9, 1, 203, 70, 9, 1, 240, 36, 9, 1, 240, 108, 3, 210, 2, 9, 1, + 240, 108, 3, 76, 60, 9, 1, 240, 108, 3, 76, 248, 227, 26, 4, 203, 139, 9, + 1, 240, 114, 9, 1, 240, 38, 9, 1, 237, 191, 9, 1, 240, 108, 3, 115, 238, + 251, 90, 237, 230, 9, 1, 240, 108, 3, 235, 7, 238, 251, 57, 9, 1, 209, + 173, 9, 1, 210, 143, 3, 4, 199, 230, 9, 1, 210, 143, 3, 210, 2, 9, 1, + 210, 143, 3, 76, 60, 9, 1, 210, 143, 3, 4, 199, 231, 60, 9, 1, 210, 143, + 3, 76, 248, 227, 26, 76, 57, 9, 1, 210, 143, 3, 99, 238, 251, 57, 9, 1, + 225, 186, 9, 1, 210, 143, 3, 235, 7, 238, 251, 57, 9, 1, 208, 126, 3, 76, + 248, 227, 26, 76, 57, 9, 1, 208, 126, 3, 115, 238, 251, 60, 9, 1, 208, + 126, 3, 115, 238, 251, 248, 227, 26, 115, 238, 251, 57, 9, 1, 209, 9, 3, + 99, 238, 251, 60, 9, 1, 209, 9, 3, 115, 238, 251, 57, 9, 1, 203, 140, 3, + 115, 238, 251, 57, 9, 1, 251, 195, 3, 115, 238, 251, 57, 9, 1, 238, 252, + 235, 176, 9, 1, 235, 177, 3, 76, 218, 162, 60, 9, 1, 235, 177, 3, 76, 60, + 9, 1, 199, 111, 9, 1, 235, 177, 3, 115, 238, 251, 60, 9, 1, 213, 70, 9, + 1, 211, 153, 3, 76, 57, 9, 1, 211, 153, 3, 115, 238, 251, 57, 9, 1, 224, + 191, 9, 1, 204, 63, 225, 35, 9, 1, 225, 36, 3, 210, 2, 9, 1, 225, 36, 3, + 76, 57, 9, 1, 217, 73, 9, 1, 225, 36, 3, 115, 238, 251, 60, 9, 1, 234, + 110, 9, 1, 234, 111, 3, 210, 2, 9, 1, 216, 250, 9, 1, 234, 111, 3, 99, + 238, 251, 60, 9, 1, 233, 63, 9, 1, 234, 111, 3, 115, 238, 251, 57, 9, 1, + 222, 250, 3, 4, 199, 230, 9, 1, 222, 250, 3, 76, 57, 9, 1, 222, 250, 3, + 115, 238, 251, 57, 9, 1, 222, 250, 3, 115, 238, 251, 60, 9, 1, 216, 32, + 3, 76, 60, 9, 1, 216, 32, 233, 196, 9, 1, 209, 235, 9, 1, 216, 32, 3, + 210, 2, 9, 1, 216, 32, 3, 115, 238, 251, 57, 9, 1, 232, 114, 239, 24, 9, + 1, 203, 73, 3, 76, 57, 9, 1, 232, 114, 3, 93, 57, 9, 1, 232, 114, 233, + 141, 9, 1, 232, 114, 233, 142, 3, 232, 214, 57, 9, 1, 203, 42, 220, 36, + 233, 141, 9, 1, 197, 118, 3, 210, 2, 9, 1, 224, 67, 214, 164, 9, 1, 214, + 164, 9, 1, 66, 9, 1, 195, 217, 9, 1, 224, 67, 195, 217, 9, 1, 197, 118, + 3, 99, 238, 251, 57, 9, 1, 199, 118, 9, 1, 235, 204, 196, 64, 9, 1, 93, + 3, 203, 135, 9, 1, 93, 3, 4, 199, 230, 9, 1, 197, 118, 3, 76, 57, 9, 1, + 69, 9, 1, 93, 3, 115, 238, 251, 60, 9, 1, 93, 249, 72, 9, 1, 93, 249, 73, + 3, 232, 214, 57, 9, 234, 217, 204, 226, 9, 1, 251, 245, 9, 4, 130, 33, + 209, 9, 3, 222, 250, 3, 151, 220, 69, 9, 4, 130, 33, 211, 153, 3, 222, + 250, 3, 151, 220, 69, 9, 4, 130, 87, 84, 20, 9, 4, 130, 222, 250, 251, + 164, 9, 4, 130, 225, 189, 9, 4, 130, 115, 238, 250, 9, 4, 130, 208, 125, + 9, 236, 222, 77, 250, 121, 9, 205, 3, 77, 209, 132, 237, 8, 232, 28, 9, + 4, 130, 209, 185, 195, 79, 9, 4, 130, 200, 31, 210, 162, 195, 79, 9, 4, + 130, 238, 252, 232, 138, 77, 224, 142, 9, 4, 130, 87, 70, 20, 9, 4, 126, + 208, 125, 9, 4, 130, 220, 109, 9, 4, 197, 117, 9, 4, 196, 64, 9, 4, 130, + 196, 64, 9, 4, 130, 216, 31, 9, 212, 149, 77, 208, 249, 9, 236, 232, 247, + 37, 126, 204, 226, 9, 236, 232, 247, 37, 130, 204, 226, 9, 209, 185, 130, + 204, 227, 3, 235, 135, 247, 36, 9, 4, 126, 219, 185, 9, 1, 240, 108, 3, + 226, 17, 199, 230, 9, 1, 210, 143, 3, 226, 17, 199, 230, 236, 79, 251, 9, + 17, 195, 79, 236, 79, 251, 9, 17, 100, 236, 79, 251, 9, 17, 102, 236, 79, + 251, 9, 17, 134, 236, 79, 251, 9, 17, 136, 236, 79, 251, 9, 17, 146, 236, + 79, 251, 9, 17, 167, 236, 79, 251, 9, 17, 178, 236, 79, 251, 9, 17, 171, + 236, 79, 251, 9, 17, 182, 9, 1, 206, 252, 3, 76, 60, 9, 1, 240, 131, 3, + 76, 60, 9, 1, 233, 226, 3, 76, 60, 9, 2, 206, 65, 251, 111, 9, 2, 206, + 65, 212, 70, 219, 164, 9, 1, 232, 114, 3, 226, 17, 199, 230, 203, 236, + 236, 222, 77, 213, 153, 203, 236, 204, 90, 234, 217, 204, 226, 203, 236, + 204, 145, 234, 217, 204, 226, 203, 236, 204, 90, 244, 168, 203, 236, 204, + 145, 244, 168, 203, 236, 231, 155, 244, 168, 203, 236, 244, 169, 206, 4, + 222, 184, 203, 236, 244, 169, 206, 4, 210, 22, 203, 236, 204, 90, 244, + 169, 206, 4, 222, 184, 203, 236, 204, 145, 244, 169, 206, 4, 210, 22, + 203, 236, 241, 123, 203, 236, 232, 171, 214, 184, 203, 236, 232, 171, + 219, 140, 203, 236, 232, 171, 250, 181, 203, 236, 252, 30, 78, 203, 236, + 1, 251, 169, 203, 236, 1, 204, 95, 251, 169, 203, 236, 1, 248, 205, 203, + 236, 1, 234, 100, 203, 236, 1, 234, 101, 234, 77, 203, 236, 1, 240, 104, + 203, 236, 1, 238, 252, 240, 105, 209, 251, 203, 236, 1, 232, 147, 203, + 236, 1, 197, 117, 203, 236, 1, 195, 106, 203, 236, 1, 232, 87, 203, 236, + 1, 202, 253, 203, 236, 1, 202, 254, 234, 77, 203, 236, 1, 195, 200, 203, + 236, 1, 195, 201, 232, 147, 203, 236, 1, 225, 5, 203, 236, 1, 222, 248, + 203, 236, 1, 219, 25, 203, 236, 1, 215, 138, 203, 236, 1, 207, 98, 203, + 236, 1, 48, 207, 98, 203, 236, 1, 69, 203, 236, 1, 213, 92, 203, 236, 1, + 210, 89, 213, 92, 203, 236, 1, 209, 5, 203, 236, 1, 211, 146, 203, 236, + 1, 209, 251, 203, 236, 1, 206, 211, 203, 236, 1, 203, 82, 203, 236, 1, + 213, 30, 248, 190, 203, 236, 1, 213, 30, 233, 223, 203, 236, 1, 213, 30, + 239, 171, 203, 236, 211, 228, 57, 203, 236, 211, 228, 60, 203, 236, 211, + 228, 237, 249, 203, 236, 195, 4, 57, 203, 236, 195, 4, 60, 203, 236, 195, + 4, 237, 249, 203, 236, 210, 186, 57, 203, 236, 210, 186, 60, 203, 236, + 237, 250, 195, 12, 231, 154, 203, 236, 237, 250, 195, 12, 251, 83, 203, + 236, 232, 152, 57, 203, 236, 232, 152, 60, 203, 236, 232, 151, 237, 249, + 203, 236, 236, 145, 57, 203, 236, 236, 145, 60, 203, 236, 209, 96, 203, + 236, 235, 170, 238, 253, 203, 236, 211, 56, 203, 236, 209, 126, 203, 236, + 99, 83, 238, 251, 57, 203, 236, 99, 83, 238, 251, 60, 203, 236, 115, 238, + 251, 57, 203, 236, 115, 238, 251, 60, 203, 236, 214, 182, 222, 76, 57, + 203, 236, 214, 182, 222, 76, 60, 203, 236, 218, 88, 203, 236, 249, 71, + 203, 236, 1, 205, 182, 195, 72, 203, 236, 1, 205, 182, 224, 135, 203, + 236, 1, 205, 182, 235, 189, 9, 1, 248, 240, 3, 115, 238, 251, 231, 104, + 60, 9, 1, 248, 240, 3, 76, 248, 227, 26, 115, 238, 251, 57, 9, 1, 248, + 240, 3, 115, 238, 251, 212, 107, 200, 24, 60, 9, 1, 248, 240, 3, 115, + 238, 251, 212, 107, 200, 24, 248, 227, 26, 99, 238, 251, 57, 9, 1, 248, + 240, 3, 99, 238, 251, 248, 227, 26, 76, 57, 9, 1, 248, 240, 3, 226, 17, + 4, 199, 231, 60, 9, 1, 248, 240, 3, 4, 199, 230, 9, 1, 168, 3, 99, 238, + 251, 57, 9, 1, 168, 3, 115, 238, 251, 212, 107, 200, 24, 60, 9, 1, 240, + 108, 3, 99, 238, 251, 199, 50, 248, 227, 26, 4, 203, 139, 9, 1, 240, 108, + 3, 226, 17, 4, 199, 231, 60, 9, 1, 210, 143, 3, 106, 9, 1, 208, 126, 3, + 235, 7, 238, 251, 57, 9, 1, 251, 195, 3, 99, 238, 251, 57, 9, 1, 251, + 195, 3, 115, 238, 251, 212, 107, 237, 231, 57, 9, 1, 251, 195, 3, 99, + 238, 251, 199, 50, 57, 9, 1, 235, 177, 3, 99, 238, 251, 60, 9, 1, 235, + 177, 3, 115, 238, 251, 212, 107, 200, 24, 60, 9, 1, 224, 192, 3, 76, 57, + 9, 1, 224, 192, 3, 115, 238, 251, 57, 9, 1, 224, 192, 3, 115, 238, 251, + 212, 107, 200, 24, 60, 9, 1, 87, 3, 76, 57, 9, 1, 87, 3, 76, 60, 9, 1, + 216, 32, 3, 99, 238, 251, 60, 9, 1, 216, 32, 3, 4, 203, 139, 9, 1, 216, + 32, 3, 4, 199, 230, 9, 1, 222, 250, 3, 154, 9, 1, 210, 143, 3, 99, 238, + 251, 199, 50, 57, 9, 1, 210, 143, 3, 232, 214, 57, 9, 1, 208, 126, 3, 99, + 238, 251, 199, 50, 57, 9, 1, 168, 3, 4, 9, 1, 203, 140, 60, 9, 1, 168, 3, + 4, 9, 1, 203, 140, 26, 99, 238, 250, 9, 1, 208, 126, 3, 4, 9, 1, 203, + 140, 26, 99, 238, 250, 9, 1, 210, 143, 3, 4, 9, 1, 203, 140, 26, 99, 238, + 250, 9, 1, 168, 3, 4, 9, 1, 203, 140, 57, 9, 1, 151, 3, 236, 79, 251, 9, + 17, 99, 57, 9, 1, 151, 3, 236, 79, 251, 9, 17, 115, 57, 9, 1, 235, 204, + 93, 3, 236, 79, 251, 9, 17, 99, 57, 9, 1, 235, 204, 93, 3, 236, 79, 251, + 9, 17, 115, 57, 9, 1, 235, 204, 93, 3, 236, 79, 251, 9, 17, 235, 7, 60, + 9, 1, 197, 118, 3, 236, 79, 251, 9, 17, 99, 57, 9, 1, 197, 118, 3, 236, + 79, 251, 9, 17, 115, 57, 9, 1, 93, 249, 73, 3, 236, 79, 251, 9, 17, 99, + 57, 9, 1, 93, 249, 73, 3, 236, 79, 251, 9, 17, 115, 57, 9, 1, 168, 3, + 236, 79, 251, 9, 17, 235, 7, 60, 9, 1, 208, 126, 3, 236, 79, 251, 9, 17, + 235, 7, 57, 9, 1, 208, 126, 3, 226, 17, 199, 230, 9, 1, 225, 36, 3, 99, + 238, 251, 57, 202, 230, 1, 232, 246, 202, 230, 1, 207, 5, 202, 230, 1, + 216, 30, 202, 230, 1, 210, 244, 202, 230, 1, 249, 143, 202, 230, 1, 222, + 119, 202, 230, 1, 225, 50, 202, 230, 1, 251, 151, 202, 230, 1, 199, 150, + 202, 230, 1, 219, 184, 202, 230, 1, 235, 237, 202, 230, 1, 239, 174, 202, + 230, 1, 202, 232, 202, 230, 1, 223, 79, 202, 230, 1, 234, 119, 202, 230, + 1, 233, 147, 202, 230, 1, 208, 124, 202, 230, 1, 240, 57, 202, 230, 1, + 195, 95, 202, 230, 1, 203, 84, 202, 230, 1, 196, 129, 202, 230, 1, 213, + 106, 202, 230, 1, 225, 198, 202, 230, 1, 245, 106, 202, 230, 1, 201, 77, + 202, 230, 1, 232, 79, 202, 230, 1, 224, 145, 202, 230, 1, 202, 231, 202, + 230, 1, 195, 113, 202, 230, 1, 206, 250, 202, 230, 1, 209, 12, 202, 230, + 1, 240, 134, 202, 230, 1, 149, 202, 230, 1, 195, 11, 202, 230, 1, 251, + 191, 202, 230, 1, 233, 224, 202, 230, 1, 211, 156, 202, 230, 1, 197, 159, + 202, 230, 252, 32, 202, 230, 252, 133, 202, 230, 230, 204, 202, 230, 237, + 53, 202, 230, 200, 107, 202, 230, 214, 101, 202, 230, 237, 63, 202, 230, + 236, 69, 202, 230, 214, 181, 202, 230, 214, 189, 202, 230, 204, 119, 202, + 230, 1, 217, 244, 216, 114, 17, 195, 79, 216, 114, 17, 100, 216, 114, 17, + 102, 216, 114, 17, 134, 216, 114, 17, 136, 216, 114, 17, 146, 216, 114, + 17, 167, 216, 114, 17, 178, 216, 114, 17, 171, 216, 114, 17, 182, 216, + 114, 1, 63, 216, 114, 1, 237, 54, 216, 114, 1, 68, 216, 114, 1, 69, 216, + 114, 1, 66, 216, 114, 1, 214, 102, 216, 114, 1, 72, 216, 114, 1, 240, + 122, 216, 114, 1, 218, 55, 216, 114, 1, 249, 145, 216, 114, 1, 161, 216, + 114, 1, 189, 216, 114, 1, 225, 214, 216, 114, 1, 247, 16, 216, 114, 1, + 240, 136, 216, 114, 1, 169, 216, 114, 1, 209, 181, 216, 114, 1, 183, 216, + 114, 1, 234, 65, 216, 114, 1, 235, 239, 216, 114, 1, 155, 216, 114, 1, + 172, 216, 114, 1, 218, 1, 197, 23, 216, 114, 1, 166, 216, 114, 1, 215, + 109, 216, 114, 1, 176, 216, 114, 1, 142, 216, 114, 1, 197, 166, 216, 114, + 1, 164, 216, 114, 1, 215, 110, 197, 23, 216, 114, 1, 225, 121, 225, 214, + 216, 114, 1, 225, 121, 247, 16, 216, 114, 1, 225, 121, 169, 216, 114, 38, + 206, 182, 130, 202, 11, 216, 114, 38, 206, 182, 126, 202, 11, 216, 114, + 38, 206, 182, 209, 250, 202, 11, 216, 114, 38, 181, 239, 194, 202, 11, + 216, 114, 38, 181, 130, 202, 11, 216, 114, 38, 181, 126, 202, 11, 216, + 114, 38, 181, 209, 250, 202, 11, 216, 114, 38, 217, 208, 78, 216, 114, + 38, 52, 76, 57, 216, 114, 130, 152, 251, 30, 216, 114, 126, 152, 251, 30, + 216, 114, 16, 214, 103, 239, 208, 216, 114, 16, 234, 64, 216, 114, 244, + 159, 216, 114, 236, 90, 78, 216, 114, 223, 52, 216, 114, 240, 83, 216, + 114, 238, 255, 55, 216, 114, 203, 116, 55, 208, 228, 1, 251, 171, 208, + 228, 1, 248, 145, 208, 228, 1, 234, 99, 208, 228, 1, 240, 106, 208, 228, + 1, 225, 225, 208, 228, 1, 249, 143, 208, 228, 1, 195, 82, 208, 228, 1, + 225, 234, 208, 228, 1, 202, 57, 208, 228, 1, 195, 181, 208, 228, 1, 225, + 51, 208, 228, 1, 223, 75, 208, 228, 1, 219, 25, 208, 228, 1, 215, 138, + 208, 228, 1, 206, 63, 208, 228, 1, 226, 86, 208, 228, 1, 235, 153, 208, + 228, 1, 201, 111, 208, 228, 1, 211, 76, 208, 228, 1, 209, 251, 208, 228, + 1, 207, 24, 208, 228, 1, 203, 161, 208, 228, 117, 226, 86, 208, 228, 117, + 226, 85, 208, 228, 117, 214, 176, 208, 228, 117, 240, 120, 208, 228, 73, + 1, 236, 179, 195, 181, 208, 228, 117, 236, 179, 195, 181, 208, 228, 18, + 2, 181, 69, 208, 228, 18, 2, 69, 208, 228, 18, 2, 214, 18, 252, 168, 208, + 228, 18, 2, 181, 252, 168, 208, 228, 18, 2, 252, 168, 208, 228, 18, 2, + 214, 18, 63, 208, 228, 18, 2, 181, 63, 208, 228, 18, 2, 63, 208, 228, 73, + 1, 206, 182, 63, 208, 228, 18, 2, 206, 182, 63, 208, 228, 18, 2, 181, 66, + 208, 228, 18, 2, 66, 208, 228, 73, 1, 68, 208, 228, 18, 2, 181, 68, 208, + 228, 18, 2, 68, 208, 228, 18, 2, 72, 208, 228, 18, 2, 204, 119, 208, 228, + 117, 217, 93, 208, 228, 211, 214, 217, 93, 208, 228, 211, 214, 251, 219, + 208, 228, 211, 214, 251, 96, 208, 228, 211, 214, 249, 49, 208, 228, 211, + 214, 250, 160, 208, 228, 211, 214, 206, 199, 208, 228, 252, 30, 78, 208, + 228, 211, 214, 219, 174, 211, 112, 208, 228, 211, 214, 195, 19, 208, 228, + 211, 214, 211, 112, 208, 228, 211, 214, 195, 112, 208, 228, 211, 214, + 201, 0, 208, 228, 211, 214, 250, 236, 208, 228, 211, 214, 205, 187, 220, + 10, 208, 228, 211, 214, 251, 77, 220, 58, 1, 232, 220, 220, 58, 1, 252, + 117, 220, 58, 1, 251, 217, 220, 58, 1, 252, 6, 220, 58, 1, 251, 209, 220, + 58, 1, 199, 251, 220, 58, 1, 250, 114, 220, 58, 1, 225, 234, 220, 58, 1, + 250, 157, 220, 58, 1, 251, 176, 220, 58, 1, 251, 181, 220, 58, 1, 251, + 173, 220, 58, 1, 251, 123, 220, 58, 1, 251, 106, 220, 58, 1, 250, 202, + 220, 58, 1, 226, 86, 220, 58, 1, 251, 46, 220, 58, 1, 250, 170, 220, 58, + 1, 251, 18, 220, 58, 1, 251, 14, 220, 58, 1, 250, 195, 220, 58, 1, 250, + 168, 220, 58, 1, 237, 175, 220, 58, 1, 225, 43, 220, 58, 1, 251, 194, + 220, 58, 251, 223, 78, 220, 58, 198, 246, 78, 220, 58, 234, 36, 78, 220, + 58, 211, 213, 203, 236, 1, 131, 217, 71, 203, 236, 1, 131, 225, 214, 203, + 236, 1, 131, 215, 109, 203, 236, 1, 131, 201, 78, 203, 236, 1, 131, 216, + 86, 203, 236, 1, 131, 216, 68, 203, 236, 1, 131, 248, 197, 203, 236, 1, + 131, 169, 203, 236, 1, 131, 222, 37, 203, 236, 1, 131, 222, 26, 203, 236, + 1, 131, 205, 80, 9, 1, 248, 240, 3, 4, 199, 231, 60, 9, 1, 248, 240, 3, + 232, 214, 57, 9, 1, 225, 190, 3, 99, 238, 251, 57, 9, 1, 203, 140, 3, 99, + 238, 251, 57, 9, 1, 235, 177, 3, 76, 248, 227, 26, 115, 238, 251, 57, 9, + 1, 211, 153, 3, 76, 60, 9, 1, 222, 250, 3, 52, 154, 9, 1, 87, 3, 115, + 238, 251, 57, 9, 1, 93, 3, 99, 238, 251, 248, 227, 26, 232, 214, 57, 9, + 1, 93, 3, 99, 238, 251, 248, 227, 26, 76, 57, 9, 1, 210, 143, 3, 221, + 225, 9, 1, 197, 118, 3, 76, 197, 38, 9, 1, 209, 214, 196, 64, 9, 1, 126, + 251, 164, 9, 1, 240, 108, 3, 115, 238, 251, 60, 9, 1, 209, 9, 3, 115, + 238, 251, 60, 9, 1, 234, 111, 3, 226, 17, 106, 9, 1, 204, 218, 197, 117, + 9, 1, 195, 107, 3, 226, 17, 199, 231, 57, 9, 1, 251, 195, 3, 115, 238, + 251, 60, 9, 1, 225, 36, 3, 76, 60, 9, 1, 248, 240, 3, 4, 87, 57, 9, 1, + 213, 73, 3, 4, 87, 57, 9, 1, 203, 42, 3, 4, 203, 42, 57, 9, 1, 210, 143, + 3, 4, 216, 32, 57, 9, 1, 93, 3, 99, 238, 251, 248, 227, 26, 4, 216, 32, + 57, 9, 1, 251, 220, 235, 176, 9, 1, 251, 220, 211, 152, 9, 1, 251, 220, + 216, 31, 9, 4, 126, 197, 117, 9, 4, 130, 197, 9, 251, 11, 9, 4, 130, 209, + 8, 9, 4, 130, 251, 194, 9, 4, 130, 211, 152, 9, 4, 130, 216, 32, 3, 224, + 238, 9, 4, 126, 216, 32, 3, 224, 238, 9, 4, 130, 197, 9, 250, 167, 9, 4, + 130, 197, 9, 250, 201, 9, 4, 130, 197, 9, 251, 105, 9, 4, 130, 197, 9, + 208, 243, 9, 4, 130, 197, 9, 211, 116, 9, 4, 130, 197, 9, 197, 140, 9, 4, + 130, 235, 35, 220, 24, 9, 4, 130, 2, 209, 3, 9, 239, 71, 236, 222, 77, + 250, 121, 9, 163, 240, 96, 60, 9, 241, 18, 235, 200, 9, 241, 18, 240, 95, + 9, 241, 18, 224, 238, 9, 241, 18, 235, 198, 9, 241, 18, 240, 93, 9, 241, + 18, 224, 236, 9, 152, 97, 76, 57, 9, 152, 99, 238, 251, 57, 9, 152, 221, + 226, 57, 9, 152, 97, 76, 60, 9, 152, 99, 238, 251, 60, 9, 152, 221, 226, + 60, 9, 192, 235, 198, 9, 192, 240, 93, 9, 192, 224, 236, 9, 4, 130, 197, + 117, 9, 235, 201, 3, 210, 2, 9, 235, 201, 3, 76, 57, 9, 224, 239, 3, 76, + 60, 9, 50, 250, 218, 57, 9, 53, 250, 218, 57, 9, 50, 250, 218, 60, 9, 53, + 250, 218, 60, 9, 52, 53, 250, 218, 57, 9, 52, 53, 250, 218, 90, 3, 238, + 253, 9, 53, 250, 218, 90, 3, 238, 253, 9, 240, 96, 3, 238, 253, 9, 117, + 206, 96, 216, 32, 233, 196, 101, 2, 226, 17, 247, 133, 101, 2, 247, 133, + 101, 2, 251, 51, 101, 2, 199, 2, 101, 1, 206, 182, 63, 101, 1, 63, 101, + 1, 252, 168, 101, 1, 68, 101, 1, 226, 120, 101, 1, 66, 101, 1, 199, 245, + 101, 1, 110, 144, 101, 1, 110, 159, 101, 1, 247, 136, 69, 101, 1, 206, + 182, 69, 101, 1, 69, 101, 1, 251, 200, 101, 1, 247, 136, 72, 101, 1, 206, + 182, 72, 101, 1, 72, 101, 1, 250, 150, 101, 1, 155, 101, 1, 224, 146, + 101, 1, 234, 123, 101, 1, 233, 230, 101, 1, 217, 71, 101, 1, 247, 174, + 101, 1, 247, 16, 101, 1, 225, 214, 101, 1, 225, 180, 101, 1, 215, 109, + 101, 1, 201, 78, 101, 1, 201, 66, 101, 1, 240, 41, 101, 1, 240, 25, 101, + 1, 216, 86, 101, 1, 189, 101, 1, 202, 233, 101, 1, 240, 136, 101, 1, 239, + 176, 101, 1, 176, 101, 1, 216, 68, 101, 1, 161, 101, 1, 213, 6, 101, 1, + 249, 145, 101, 1, 248, 197, 101, 1, 166, 101, 1, 164, 101, 1, 169, 101, + 1, 209, 181, 101, 1, 172, 101, 1, 222, 37, 101, 1, 222, 26, 101, 1, 199, + 152, 101, 1, 207, 50, 101, 1, 205, 80, 101, 1, 183, 101, 1, 142, 101, 18, + 2, 214, 164, 101, 18, 2, 214, 100, 101, 2, 215, 149, 101, 2, 250, 132, + 101, 18, 2, 252, 168, 101, 18, 2, 68, 101, 18, 2, 226, 120, 101, 18, 2, + 66, 101, 18, 2, 199, 245, 101, 18, 2, 110, 144, 101, 18, 2, 110, 209, + 182, 101, 18, 2, 247, 136, 69, 101, 18, 2, 206, 182, 69, 101, 18, 2, 69, + 101, 18, 2, 251, 200, 101, 18, 2, 247, 136, 72, 101, 18, 2, 206, 182, 72, + 101, 18, 2, 72, 101, 18, 2, 250, 150, 101, 2, 199, 7, 101, 18, 2, 212, + 11, 69, 101, 18, 2, 250, 127, 101, 214, 127, 101, 204, 206, 2, 200, 101, + 101, 204, 206, 2, 251, 53, 101, 233, 101, 252, 22, 101, 252, 10, 252, 22, + 101, 18, 2, 247, 136, 181, 69, 101, 18, 2, 200, 99, 101, 18, 2, 199, 244, + 101, 1, 211, 159, 101, 1, 224, 127, 101, 1, 233, 205, 101, 1, 195, 115, + 101, 1, 240, 30, 101, 1, 210, 77, 101, 1, 235, 239, 101, 1, 195, 167, + 101, 1, 110, 209, 182, 101, 1, 110, 222, 38, 101, 18, 2, 110, 159, 101, + 18, 2, 110, 222, 38, 101, 240, 88, 101, 52, 240, 88, 101, 17, 195, 79, + 101, 17, 100, 101, 17, 102, 101, 17, 134, 101, 17, 136, 101, 17, 146, + 101, 17, 167, 101, 17, 178, 101, 17, 171, 101, 17, 182, 101, 252, 30, 55, + 101, 2, 130, 205, 147, 238, 253, 101, 1, 247, 136, 63, 101, 1, 214, 164, + 101, 1, 214, 100, 101, 1, 250, 127, 101, 1, 200, 99, 101, 1, 199, 244, + 101, 1, 220, 16, 240, 41, 101, 1, 195, 74, 101, 1, 85, 164, 101, 1, 234, + 10, 101, 1, 225, 158, 101, 1, 233, 152, 204, 226, 101, 1, 240, 31, 101, + 1, 249, 45, 248, 219, 251, 80, 248, 219, 2, 247, 133, 248, 219, 2, 251, + 51, 248, 219, 2, 199, 2, 248, 219, 1, 63, 248, 219, 1, 252, 168, 248, + 219, 1, 68, 248, 219, 1, 226, 120, 248, 219, 1, 66, 248, 219, 1, 199, + 245, 248, 219, 1, 110, 144, 248, 219, 1, 110, 159, 248, 219, 1, 69, 248, + 219, 1, 251, 200, 248, 219, 1, 72, 248, 219, 1, 250, 150, 248, 219, 1, + 155, 248, 219, 1, 224, 146, 248, 219, 1, 234, 123, 248, 219, 1, 233, 230, + 248, 219, 1, 217, 71, 248, 219, 1, 247, 174, 248, 219, 1, 247, 16, 248, + 219, 1, 225, 214, 248, 219, 1, 225, 180, 248, 219, 1, 215, 109, 248, 219, + 1, 201, 78, 248, 219, 1, 201, 66, 248, 219, 1, 240, 41, 248, 219, 1, 240, + 25, 248, 219, 1, 216, 86, 248, 219, 1, 189, 248, 219, 1, 202, 233, 248, + 219, 1, 240, 136, 248, 219, 1, 239, 176, 248, 219, 1, 176, 248, 219, 1, + 161, 248, 219, 1, 213, 6, 248, 219, 1, 249, 145, 248, 219, 1, 248, 197, + 248, 219, 1, 166, 248, 219, 1, 164, 248, 219, 1, 169, 248, 219, 1, 172, + 248, 219, 1, 207, 50, 248, 219, 1, 205, 80, 248, 219, 1, 183, 248, 219, + 1, 142, 248, 219, 2, 215, 149, 248, 219, 2, 250, 132, 248, 219, 18, 2, + 252, 168, 248, 219, 18, 2, 68, 248, 219, 18, 2, 226, 120, 248, 219, 18, + 2, 66, 248, 219, 18, 2, 199, 245, 248, 219, 18, 2, 110, 144, 248, 219, + 18, 2, 110, 209, 182, 248, 219, 18, 2, 69, 248, 219, 18, 2, 251, 200, + 248, 219, 18, 2, 72, 248, 219, 18, 2, 250, 150, 248, 219, 2, 199, 7, 248, + 219, 1, 224, 137, 189, 248, 219, 250, 151, 222, 158, 78, 248, 219, 1, + 209, 181, 248, 219, 1, 210, 77, 248, 219, 1, 195, 167, 248, 219, 1, 110, + 209, 182, 248, 219, 1, 110, 222, 38, 248, 219, 18, 2, 110, 159, 248, 219, + 18, 2, 110, 222, 38, 248, 219, 17, 195, 79, 248, 219, 17, 100, 248, 219, + 17, 102, 248, 219, 17, 134, 248, 219, 17, 136, 248, 219, 17, 146, 248, + 219, 17, 167, 248, 219, 17, 178, 248, 219, 17, 171, 248, 219, 17, 182, + 248, 219, 1, 210, 252, 3, 112, 239, 146, 248, 219, 1, 210, 252, 3, 221, + 203, 239, 146, 248, 219, 209, 108, 78, 248, 219, 209, 108, 55, 248, 219, + 241, 17, 215, 141, 100, 248, 219, 241, 17, 215, 141, 102, 248, 219, 241, + 17, 215, 141, 134, 248, 219, 241, 17, 215, 141, 136, 248, 219, 241, 17, + 215, 141, 97, 222, 141, 202, 223, 202, 218, 239, 206, 248, 219, 241, 17, + 239, 207, 206, 23, 248, 219, 225, 235, 248, 219, 234, 90, 78, 248, 219, + 1, 199, 115, 251, 51, 248, 219, 252, 30, 55, 248, 219, 208, 215, 78, 233, + 42, 2, 252, 5, 248, 163, 233, 42, 2, 248, 163, 233, 42, 2, 199, 2, 233, + 42, 1, 63, 233, 42, 1, 252, 168, 233, 42, 1, 68, 233, 42, 1, 226, 120, + 233, 42, 1, 66, 233, 42, 1, 199, 245, 233, 42, 1, 237, 54, 233, 42, 1, + 251, 200, 233, 42, 1, 214, 102, 233, 42, 1, 250, 150, 233, 42, 1, 155, + 233, 42, 1, 224, 146, 233, 42, 1, 234, 123, 233, 42, 1, 233, 230, 233, + 42, 1, 217, 71, 233, 42, 1, 247, 174, 233, 42, 1, 247, 16, 233, 42, 1, + 225, 214, 233, 42, 1, 225, 180, 233, 42, 1, 215, 109, 233, 42, 1, 201, + 78, 233, 42, 1, 201, 66, 233, 42, 1, 240, 41, 233, 42, 1, 240, 25, 233, + 42, 1, 216, 86, 233, 42, 1, 189, 233, 42, 1, 202, 233, 233, 42, 1, 240, + 136, 233, 42, 1, 239, 176, 233, 42, 1, 176, 233, 42, 1, 161, 233, 42, 1, + 213, 6, 233, 42, 1, 249, 145, 233, 42, 1, 248, 197, 233, 42, 1, 166, 233, + 42, 1, 164, 233, 42, 1, 169, 233, 42, 1, 172, 233, 42, 1, 222, 37, 233, + 42, 1, 199, 152, 233, 42, 1, 207, 50, 233, 42, 1, 183, 233, 42, 1, 142, + 233, 42, 2, 215, 149, 233, 42, 18, 2, 252, 168, 233, 42, 18, 2, 68, 233, + 42, 18, 2, 226, 120, 233, 42, 18, 2, 66, 233, 42, 18, 2, 199, 245, 233, + 42, 18, 2, 237, 54, 233, 42, 18, 2, 251, 200, 233, 42, 18, 2, 214, 102, + 233, 42, 18, 2, 250, 150, 233, 42, 2, 199, 7, 233, 42, 2, 200, 103, 233, + 42, 1, 224, 127, 233, 42, 1, 233, 205, 233, 42, 1, 195, 115, 233, 42, 1, + 209, 181, 233, 42, 1, 235, 239, 233, 42, 17, 195, 79, 233, 42, 17, 100, + 233, 42, 17, 102, 233, 42, 17, 134, 233, 42, 17, 136, 233, 42, 17, 146, + 233, 42, 17, 167, 233, 42, 17, 178, 233, 42, 17, 171, 233, 42, 17, 182, + 233, 42, 202, 65, 233, 42, 252, 4, 233, 42, 225, 255, 233, 42, 200, 17, + 233, 42, 237, 15, 214, 107, 233, 42, 2, 196, 104, 233, 42, 252, 30, 55, + 233, 58, 2, 247, 133, 233, 58, 2, 251, 51, 233, 58, 2, 199, 2, 233, 58, + 1, 63, 233, 58, 1, 252, 168, 233, 58, 1, 68, 233, 58, 1, 226, 120, 233, + 58, 1, 66, 233, 58, 1, 199, 245, 233, 58, 1, 110, 144, 233, 58, 1, 110, + 159, 233, 58, 18, 247, 136, 69, 233, 58, 1, 69, 233, 58, 1, 251, 200, + 233, 58, 18, 247, 136, 72, 233, 58, 1, 72, 233, 58, 1, 250, 150, 233, 58, + 1, 155, 233, 58, 1, 224, 146, 233, 58, 1, 234, 123, 233, 58, 1, 233, 230, + 233, 58, 1, 217, 71, 233, 58, 1, 247, 174, 233, 58, 1, 247, 16, 233, 58, + 1, 225, 214, 233, 58, 1, 225, 180, 233, 58, 1, 215, 109, 233, 58, 1, 201, + 78, 233, 58, 1, 201, 66, 233, 58, 1, 240, 41, 233, 58, 1, 240, 25, 233, + 58, 1, 216, 86, 233, 58, 1, 189, 233, 58, 1, 202, 233, 233, 58, 1, 240, + 136, 233, 58, 1, 239, 176, 233, 58, 1, 176, 233, 58, 1, 161, 233, 58, 1, + 213, 6, 233, 58, 1, 249, 145, 233, 58, 1, 248, 197, 233, 58, 1, 166, 233, + 58, 1, 164, 233, 58, 1, 169, 233, 58, 1, 172, 233, 58, 1, 222, 37, 233, + 58, 1, 199, 152, 233, 58, 1, 207, 50, 233, 58, 1, 205, 80, 233, 58, 1, + 183, 233, 58, 1, 142, 233, 58, 2, 215, 149, 233, 58, 2, 250, 132, 233, + 58, 18, 2, 252, 168, 233, 58, 18, 2, 68, 233, 58, 18, 2, 226, 120, 233, + 58, 18, 2, 66, 233, 58, 18, 2, 199, 245, 233, 58, 18, 2, 110, 144, 233, + 58, 18, 2, 110, 209, 182, 233, 58, 18, 2, 247, 136, 69, 233, 58, 18, 2, + 69, 233, 58, 18, 2, 251, 200, 233, 58, 18, 2, 247, 136, 72, 233, 58, 18, + 2, 72, 233, 58, 18, 2, 250, 150, 233, 58, 2, 199, 7, 233, 58, 214, 127, + 233, 58, 1, 110, 209, 182, 233, 58, 1, 110, 222, 38, 233, 58, 18, 2, 110, + 159, 233, 58, 18, 2, 110, 222, 38, 233, 58, 17, 195, 79, 233, 58, 17, + 100, 233, 58, 17, 102, 233, 58, 17, 134, 233, 58, 17, 136, 233, 58, 17, + 146, 233, 58, 17, 167, 233, 58, 17, 178, 233, 58, 17, 171, 233, 58, 17, + 182, 233, 58, 252, 30, 55, 233, 58, 209, 108, 55, 233, 58, 1, 195, 74, + 233, 58, 2, 204, 119, 233, 58, 2, 207, 40, 233, 58, 2, 220, 107, 233, 58, + 2, 202, 153, 215, 150, 57, 233, 58, 2, 244, 250, 215, 150, 57, 233, 58, + 2, 200, 217, 215, 150, 57, 214, 62, 2, 247, 133, 214, 62, 2, 251, 51, + 214, 62, 2, 199, 2, 214, 62, 1, 63, 214, 62, 1, 252, 168, 214, 62, 1, 68, + 214, 62, 1, 226, 120, 214, 62, 1, 66, 214, 62, 1, 199, 245, 214, 62, 1, + 110, 144, 214, 62, 1, 110, 159, 214, 62, 1, 69, 214, 62, 1, 251, 200, + 214, 62, 1, 72, 214, 62, 1, 250, 150, 214, 62, 1, 155, 214, 62, 1, 224, + 146, 214, 62, 1, 234, 123, 214, 62, 1, 233, 230, 214, 62, 1, 217, 71, + 214, 62, 1, 247, 174, 214, 62, 1, 247, 16, 214, 62, 1, 225, 214, 214, 62, + 1, 225, 180, 214, 62, 1, 215, 109, 214, 62, 1, 201, 78, 214, 62, 1, 201, + 66, 214, 62, 1, 240, 41, 214, 62, 1, 240, 25, 214, 62, 1, 216, 86, 214, + 62, 1, 189, 214, 62, 1, 202, 233, 214, 62, 1, 240, 136, 214, 62, 1, 239, + 176, 214, 62, 1, 176, 214, 62, 1, 161, 214, 62, 1, 213, 6, 214, 62, 1, + 249, 145, 214, 62, 1, 248, 197, 214, 62, 1, 166, 214, 62, 1, 164, 214, + 62, 1, 169, 214, 62, 1, 172, 214, 62, 1, 222, 37, 214, 62, 1, 199, 152, + 214, 62, 1, 207, 50, 214, 62, 1, 205, 80, 214, 62, 1, 183, 214, 62, 1, + 142, 214, 62, 2, 215, 149, 214, 62, 2, 250, 132, 214, 62, 18, 2, 252, + 168, 214, 62, 18, 2, 68, 214, 62, 18, 2, 226, 120, 214, 62, 18, 2, 66, + 214, 62, 18, 2, 199, 245, 214, 62, 18, 2, 110, 144, 214, 62, 18, 2, 110, + 209, 182, 214, 62, 18, 2, 69, 214, 62, 18, 2, 251, 200, 214, 62, 18, 2, + 72, 214, 62, 18, 2, 250, 150, 214, 62, 2, 199, 7, 214, 62, 251, 201, 222, + 158, 78, 214, 62, 250, 151, 222, 158, 78, 214, 62, 1, 209, 181, 214, 62, + 1, 210, 77, 214, 62, 1, 195, 167, 214, 62, 1, 110, 209, 182, 214, 62, 1, + 110, 222, 38, 214, 62, 18, 2, 110, 159, 214, 62, 18, 2, 110, 222, 38, + 214, 62, 17, 195, 79, 214, 62, 17, 100, 214, 62, 17, 102, 214, 62, 17, + 134, 214, 62, 17, 136, 214, 62, 17, 146, 214, 62, 17, 167, 214, 62, 17, + 178, 214, 62, 17, 171, 214, 62, 17, 182, 214, 62, 225, 235, 214, 62, 1, + 197, 166, 214, 62, 191, 97, 211, 87, 214, 62, 191, 97, 232, 225, 214, 62, + 191, 115, 211, 85, 214, 62, 191, 97, 206, 21, 214, 62, 191, 97, 237, 26, + 214, 62, 191, 115, 206, 18, 42, 2, 251, 51, 42, 2, 199, 2, 42, 1, 63, 42, + 1, 252, 168, 42, 1, 68, 42, 1, 226, 120, 42, 1, 66, 42, 1, 199, 245, 42, + 1, 69, 42, 1, 237, 54, 42, 1, 251, 200, 42, 1, 72, 42, 1, 214, 102, 42, + 1, 250, 150, 42, 1, 155, 42, 1, 217, 71, 42, 1, 247, 174, 42, 1, 225, + 214, 42, 1, 215, 109, 42, 1, 201, 78, 42, 1, 216, 86, 42, 1, 189, 42, 1, + 176, 42, 1, 216, 68, 42, 1, 161, 42, 1, 166, 42, 1, 164, 42, 1, 169, 42, + 1, 209, 181, 42, 1, 172, 42, 1, 222, 37, 42, 1, 222, 26, 42, 1, 199, 152, + 42, 1, 207, 50, 42, 1, 205, 80, 42, 1, 183, 42, 1, 142, 42, 18, 2, 252, + 168, 42, 18, 2, 68, 42, 18, 2, 226, 120, 42, 18, 2, 66, 42, 18, 2, 199, + 245, 42, 18, 2, 69, 42, 18, 2, 237, 54, 42, 18, 2, 251, 200, 42, 18, 2, + 72, 42, 18, 2, 214, 102, 42, 18, 2, 250, 150, 42, 2, 199, 7, 42, 214, + 127, 42, 250, 151, 222, 158, 78, 42, 17, 195, 79, 42, 17, 100, 42, 17, + 102, 42, 17, 134, 42, 17, 136, 42, 17, 146, 42, 17, 167, 42, 17, 178, 42, + 17, 171, 42, 17, 182, 42, 31, 203, 23, 42, 31, 97, 231, 57, 42, 31, 97, + 170, 42, 240, 54, 55, 42, 218, 198, 55, 42, 196, 67, 55, 42, 239, 248, + 55, 42, 241, 74, 55, 42, 250, 203, 90, 55, 42, 209, 108, 55, 42, 31, 55, + 194, 194, 2, 38, 247, 134, 57, 194, 194, 2, 247, 133, 194, 194, 2, 251, + 51, 194, 194, 2, 199, 2, 194, 194, 2, 38, 251, 52, 57, 194, 194, 1, 63, + 194, 194, 1, 252, 168, 194, 194, 1, 68, 194, 194, 1, 226, 120, 194, 194, + 1, 66, 194, 194, 1, 199, 245, 194, 194, 1, 110, 144, 194, 194, 1, 110, + 159, 194, 194, 1, 69, 194, 194, 1, 237, 54, 194, 194, 1, 251, 200, 194, + 194, 1, 72, 194, 194, 1, 214, 102, 194, 194, 1, 250, 150, 194, 194, 1, + 155, 194, 194, 1, 224, 146, 194, 194, 1, 234, 123, 194, 194, 1, 233, 230, + 194, 194, 1, 217, 71, 194, 194, 1, 247, 174, 194, 194, 1, 247, 16, 194, + 194, 1, 225, 214, 194, 194, 1, 225, 180, 194, 194, 1, 215, 109, 194, 194, + 1, 201, 78, 194, 194, 1, 201, 66, 194, 194, 1, 240, 41, 194, 194, 1, 240, + 25, 194, 194, 1, 216, 86, 194, 194, 1, 189, 194, 194, 1, 202, 233, 194, + 194, 1, 240, 136, 194, 194, 1, 239, 176, 194, 194, 1, 176, 194, 194, 1, + 161, 194, 194, 1, 213, 6, 194, 194, 1, 249, 145, 194, 194, 1, 248, 197, + 194, 194, 1, 166, 194, 194, 1, 164, 194, 194, 1, 169, 194, 194, 1, 209, + 181, 194, 194, 1, 172, 194, 194, 1, 222, 37, 194, 194, 1, 222, 26, 194, + 194, 1, 199, 152, 194, 194, 1, 207, 50, 194, 194, 1, 205, 80, 194, 194, + 1, 183, 194, 194, 1, 142, 194, 194, 2, 250, 132, 194, 194, 18, 2, 252, + 168, 194, 194, 18, 2, 68, 194, 194, 18, 2, 226, 120, 194, 194, 18, 2, 66, + 194, 194, 18, 2, 199, 245, 194, 194, 18, 2, 110, 144, 194, 194, 18, 2, + 110, 209, 182, 194, 194, 18, 2, 69, 194, 194, 18, 2, 237, 54, 194, 194, + 18, 2, 251, 200, 194, 194, 18, 2, 72, 194, 194, 18, 2, 214, 102, 194, + 194, 18, 2, 250, 150, 194, 194, 2, 199, 7, 194, 194, 222, 158, 78, 194, + 194, 251, 201, 222, 158, 78, 194, 194, 1, 201, 113, 194, 194, 1, 237, + 156, 194, 194, 1, 209, 162, 194, 194, 1, 110, 209, 182, 194, 194, 1, 110, + 222, 38, 194, 194, 18, 2, 110, 159, 194, 194, 18, 2, 110, 222, 38, 194, + 194, 17, 195, 79, 194, 194, 17, 100, 194, 194, 17, 102, 194, 194, 17, + 134, 194, 194, 17, 136, 194, 194, 17, 146, 194, 194, 17, 167, 194, 194, + 17, 178, 194, 194, 17, 171, 194, 194, 17, 182, 194, 194, 2, 206, 100, + 194, 194, 191, 17, 195, 80, 36, 214, 168, 212, 57, 77, 136, 194, 194, + 191, 17, 97, 36, 214, 168, 212, 57, 77, 136, 194, 194, 191, 17, 99, 36, + 214, 168, 212, 57, 77, 136, 194, 194, 191, 17, 115, 36, 214, 168, 212, + 57, 77, 136, 194, 194, 191, 17, 97, 36, 236, 103, 212, 57, 77, 136, 194, + 194, 191, 17, 99, 36, 236, 103, 212, 57, 77, 136, 194, 194, 191, 17, 115, + 36, 236, 103, 212, 57, 77, 136, 194, 194, 2, 200, 250, 225, 11, 2, 205, + 147, 247, 133, 225, 11, 2, 247, 133, 225, 11, 2, 251, 51, 225, 11, 2, + 199, 2, 225, 11, 2, 206, 100, 225, 11, 1, 63, 225, 11, 1, 252, 168, 225, + 11, 1, 68, 225, 11, 1, 226, 120, 225, 11, 1, 66, 225, 11, 1, 199, 245, + 225, 11, 1, 110, 144, 225, 11, 1, 110, 159, 225, 11, 1, 69, 225, 11, 1, + 237, 54, 225, 11, 1, 251, 200, 225, 11, 1, 72, 225, 11, 1, 214, 102, 225, + 11, 1, 250, 150, 225, 11, 1, 155, 225, 11, 1, 224, 146, 225, 11, 1, 234, + 123, 225, 11, 1, 233, 230, 225, 11, 1, 217, 71, 225, 11, 1, 247, 174, + 225, 11, 1, 247, 16, 225, 11, 1, 225, 214, 225, 11, 1, 225, 180, 225, 11, + 1, 215, 109, 225, 11, 1, 201, 78, 225, 11, 1, 201, 66, 225, 11, 1, 240, + 41, 225, 11, 1, 240, 25, 225, 11, 1, 216, 86, 225, 11, 1, 189, 225, 11, + 1, 202, 233, 225, 11, 1, 240, 136, 225, 11, 1, 239, 176, 225, 11, 1, 176, + 225, 11, 1, 161, 225, 11, 1, 213, 6, 225, 11, 1, 249, 145, 225, 11, 1, + 248, 197, 225, 11, 1, 166, 225, 11, 1, 164, 225, 11, 1, 169, 225, 11, 1, + 209, 181, 225, 11, 1, 172, 225, 11, 1, 222, 37, 225, 11, 1, 199, 152, + 225, 11, 1, 207, 50, 225, 11, 1, 205, 80, 225, 11, 1, 183, 225, 11, 1, + 142, 225, 11, 2, 215, 149, 225, 11, 2, 250, 132, 225, 11, 18, 2, 252, + 168, 225, 11, 18, 2, 68, 225, 11, 18, 2, 226, 120, 225, 11, 18, 2, 66, + 225, 11, 18, 2, 199, 245, 225, 11, 18, 2, 110, 144, 225, 11, 18, 2, 110, + 209, 182, 225, 11, 18, 2, 69, 225, 11, 18, 2, 237, 54, 225, 11, 18, 2, + 251, 200, 225, 11, 18, 2, 72, 225, 11, 18, 2, 214, 102, 225, 11, 18, 2, + 250, 150, 225, 11, 2, 199, 7, 225, 11, 222, 158, 78, 225, 11, 251, 201, + 222, 158, 78, 225, 11, 1, 235, 239, 225, 11, 1, 110, 209, 182, 225, 11, + 1, 110, 222, 38, 225, 11, 18, 2, 110, 159, 225, 11, 18, 2, 110, 222, 38, + 225, 11, 17, 195, 79, 225, 11, 17, 100, 225, 11, 17, 102, 225, 11, 17, + 134, 225, 11, 17, 136, 225, 11, 17, 146, 225, 11, 17, 167, 225, 11, 17, + 178, 225, 11, 17, 171, 225, 11, 17, 182, 225, 11, 2, 225, 165, 225, 11, + 2, 200, 34, 131, 2, 38, 251, 52, 57, 131, 2, 247, 133, 131, 2, 251, 51, + 131, 2, 199, 2, 131, 1, 63, 131, 1, 252, 168, 131, 1, 68, 131, 1, 226, + 120, 131, 1, 66, 131, 1, 199, 245, 131, 1, 110, 144, 131, 1, 110, 159, + 131, 1, 69, 131, 1, 237, 54, 131, 1, 251, 200, 131, 1, 72, 131, 1, 214, + 102, 131, 1, 250, 150, 131, 1, 155, 131, 1, 224, 146, 131, 1, 234, 123, + 131, 1, 233, 230, 131, 1, 217, 71, 131, 1, 247, 174, 131, 1, 247, 16, + 131, 1, 225, 214, 131, 1, 225, 180, 131, 1, 215, 109, 131, 1, 201, 78, + 131, 1, 201, 66, 131, 1, 240, 41, 131, 1, 240, 25, 131, 1, 216, 86, 131, + 1, 189, 131, 1, 202, 233, 131, 1, 240, 136, 131, 1, 239, 176, 131, 1, + 176, 131, 1, 216, 68, 131, 1, 161, 131, 1, 213, 6, 131, 1, 249, 145, 131, + 1, 248, 197, 131, 1, 166, 131, 1, 164, 131, 1, 169, 131, 1, 209, 181, + 131, 1, 172, 131, 1, 222, 37, 131, 1, 222, 26, 131, 1, 199, 152, 131, 1, + 207, 50, 131, 1, 205, 80, 131, 1, 183, 131, 1, 142, 131, 1, 201, 47, 131, + 2, 83, 249, 80, 199, 7, 131, 2, 244, 243, 199, 7, 131, 2, 250, 132, 131, + 18, 2, 252, 168, 131, 18, 2, 68, 131, 18, 2, 226, 120, 131, 18, 2, 66, + 131, 18, 2, 199, 245, 131, 18, 2, 110, 144, 131, 18, 2, 110, 209, 182, + 131, 18, 2, 69, 131, 18, 2, 237, 54, 131, 18, 2, 251, 200, 131, 18, 2, + 72, 131, 18, 2, 214, 102, 131, 18, 2, 250, 150, 131, 2, 199, 7, 131, 1, + 76, 210, 116, 131, 2, 213, 156, 131, 1, 245, 64, 221, 136, 131, 1, 245, + 64, 196, 148, 131, 1, 245, 64, 222, 27, 131, 250, 151, 222, 158, 78, 131, + 191, 97, 214, 115, 131, 191, 97, 235, 17, 131, 191, 115, 237, 22, 131, + 191, 97, 200, 237, 131, 191, 97, 203, 14, 131, 191, 115, 200, 236, 131, + 191, 97, 235, 148, 131, 1, 250, 251, 226, 120, 131, 1, 110, 209, 182, + 131, 1, 110, 222, 38, 131, 18, 2, 110, 159, 131, 18, 2, 110, 222, 38, + 131, 17, 195, 79, 131, 17, 100, 131, 17, 102, 131, 17, 134, 131, 17, 136, + 131, 17, 146, 131, 17, 167, 131, 17, 178, 131, 17, 171, 131, 17, 182, + 131, 31, 203, 23, 131, 31, 97, 231, 57, 131, 31, 97, 170, 131, 191, 97, + 211, 87, 131, 191, 97, 232, 225, 131, 191, 115, 211, 85, 131, 191, 97, + 206, 21, 131, 191, 97, 237, 26, 131, 191, 115, 206, 18, 131, 240, 59, 78, + 131, 1, 245, 64, 216, 87, 131, 1, 245, 64, 218, 55, 131, 1, 245, 64, 209, + 182, 131, 1, 245, 64, 159, 131, 1, 245, 64, 222, 38, 131, 1, 245, 64, + 225, 80, 153, 2, 251, 50, 153, 2, 199, 1, 153, 1, 250, 120, 153, 1, 252, + 121, 153, 1, 251, 225, 153, 1, 251, 240, 153, 1, 225, 224, 153, 1, 226, + 119, 153, 1, 199, 236, 153, 1, 199, 239, 153, 1, 225, 250, 153, 1, 225, + 251, 153, 1, 226, 105, 153, 1, 226, 107, 153, 1, 236, 70, 153, 1, 237, + 49, 153, 1, 251, 183, 153, 1, 214, 7, 153, 1, 214, 95, 153, 1, 250, 135, + 153, 1, 251, 137, 224, 214, 153, 1, 220, 88, 224, 214, 153, 1, 251, 137, + 234, 68, 153, 1, 220, 88, 234, 68, 153, 1, 225, 10, 217, 241, 153, 1, + 208, 209, 234, 68, 153, 1, 251, 137, 247, 83, 153, 1, 220, 88, 247, 83, + 153, 1, 251, 137, 225, 196, 153, 1, 220, 88, 225, 196, 153, 1, 203, 159, + 217, 241, 153, 1, 203, 159, 208, 208, 217, 242, 153, 1, 208, 209, 225, + 196, 153, 1, 251, 137, 201, 74, 153, 1, 220, 88, 201, 74, 153, 1, 251, + 137, 240, 32, 153, 1, 220, 88, 240, 32, 153, 1, 218, 84, 217, 194, 153, + 1, 208, 209, 240, 32, 153, 1, 251, 137, 203, 76, 153, 1, 220, 88, 203, + 76, 153, 1, 251, 137, 240, 52, 153, 1, 220, 88, 240, 52, 153, 1, 240, 84, + 217, 194, 153, 1, 208, 209, 240, 52, 153, 1, 251, 137, 213, 100, 153, 1, + 220, 88, 213, 100, 153, 1, 251, 137, 249, 47, 153, 1, 220, 88, 249, 47, + 153, 1, 219, 249, 153, 1, 251, 117, 249, 47, 153, 1, 196, 74, 153, 1, + 210, 190, 153, 1, 240, 84, 222, 206, 153, 1, 199, 120, 153, 1, 203, 159, + 208, 179, 153, 1, 218, 84, 208, 179, 153, 1, 240, 84, 208, 179, 153, 1, + 232, 153, 153, 1, 218, 84, 222, 206, 153, 1, 235, 191, 153, 2, 251, 172, + 153, 18, 2, 251, 235, 153, 18, 2, 224, 171, 251, 242, 153, 18, 2, 239, + 119, 251, 242, 153, 18, 2, 224, 171, 225, 247, 153, 18, 2, 239, 119, 225, + 247, 153, 18, 2, 224, 171, 213, 242, 153, 18, 2, 239, 119, 213, 242, 153, + 18, 2, 234, 112, 153, 18, 2, 223, 247, 153, 18, 2, 239, 119, 223, 247, + 153, 18, 2, 223, 249, 239, 226, 153, 18, 2, 223, 248, 232, 247, 251, 235, + 153, 18, 2, 223, 248, 232, 247, 239, 119, 251, 235, 153, 18, 2, 223, 248, + 232, 247, 234, 67, 153, 18, 2, 234, 67, 153, 222, 50, 17, 195, 79, 153, + 222, 50, 17, 100, 153, 222, 50, 17, 102, 153, 222, 50, 17, 134, 153, 222, + 50, 17, 136, 153, 222, 50, 17, 146, 153, 222, 50, 17, 167, 153, 222, 50, + 17, 178, 153, 222, 50, 17, 171, 153, 222, 50, 17, 182, 153, 18, 2, 239, + 119, 234, 112, 153, 18, 2, 239, 119, 234, 67, 153, 211, 214, 223, 165, + 202, 228, 190, 224, 12, 225, 31, 202, 228, 190, 224, 118, 224, 141, 202, + 228, 190, 224, 118, 224, 109, 202, 228, 190, 224, 118, 224, 104, 202, + 228, 190, 224, 118, 224, 114, 202, 228, 190, 224, 118, 210, 211, 202, + 228, 190, 216, 253, 216, 240, 202, 228, 190, 245, 50, 247, 5, 202, 228, + 190, 245, 50, 245, 60, 202, 228, 190, 245, 50, 247, 4, 202, 228, 190, + 205, 201, 205, 200, 202, 228, 190, 245, 50, 245, 46, 202, 228, 190, 196, + 4, 196, 11, 202, 228, 190, 239, 29, 247, 13, 202, 228, 190, 202, 30, 213, + 114, 202, 228, 190, 202, 170, 202, 222, 202, 228, 190, 202, 170, 217, + 217, 202, 228, 190, 202, 170, 212, 223, 202, 228, 190, 216, 51, 217, 101, + 202, 228, 190, 239, 29, 239, 227, 202, 228, 190, 202, 30, 203, 106, 202, + 228, 190, 202, 170, 202, 136, 202, 228, 190, 202, 170, 202, 229, 202, + 228, 190, 202, 170, 202, 165, 202, 228, 190, 216, 51, 215, 186, 202, 228, + 190, 248, 117, 249, 110, 202, 228, 190, 212, 118, 212, 150, 202, 228, + 190, 212, 235, 212, 225, 202, 228, 190, 235, 52, 235, 239, 202, 228, 190, + 212, 235, 212, 255, 202, 228, 190, 235, 52, 235, 210, 202, 228, 190, 212, + 235, 208, 223, 202, 228, 190, 218, 252, 166, 202, 228, 190, 196, 4, 196, + 105, 202, 228, 190, 209, 233, 209, 133, 202, 228, 190, 209, 140, 202, + 228, 190, 222, 8, 222, 68, 202, 228, 190, 221, 191, 202, 228, 190, 197, + 35, 197, 156, 202, 228, 190, 205, 201, 208, 239, 202, 228, 190, 205, 201, + 209, 104, 202, 228, 190, 205, 201, 204, 163, 202, 228, 190, 231, 194, + 232, 35, 202, 228, 190, 222, 8, 245, 29, 202, 228, 190, 177, 251, 97, + 202, 228, 190, 231, 194, 216, 41, 202, 228, 190, 213, 217, 202, 228, 190, + 208, 203, 63, 202, 228, 190, 220, 82, 232, 211, 202, 228, 190, 208, 203, + 252, 168, 202, 228, 190, 208, 203, 251, 123, 202, 228, 190, 208, 203, 68, + 202, 228, 190, 208, 203, 226, 120, 202, 228, 190, 208, 203, 200, 99, 202, + 228, 190, 208, 203, 200, 97, 202, 228, 190, 208, 203, 66, 202, 228, 190, + 208, 203, 199, 245, 202, 228, 190, 212, 237, 202, 228, 241, 17, 16, 249, + 111, 202, 228, 190, 208, 203, 69, 202, 228, 190, 208, 203, 251, 245, 202, + 228, 190, 208, 203, 72, 202, 228, 190, 208, 203, 251, 201, 220, 76, 202, + 228, 190, 208, 203, 251, 201, 220, 77, 202, 228, 190, 222, 253, 202, 228, + 190, 220, 73, 202, 228, 190, 220, 74, 202, 228, 190, 220, 82, 237, 14, + 202, 228, 190, 220, 82, 202, 169, 202, 228, 190, 220, 82, 201, 183, 202, + 228, 190, 220, 82, 245, 108, 202, 228, 190, 202, 220, 202, 228, 190, 216, + 187, 202, 228, 190, 196, 99, 202, 228, 190, 235, 42, 202, 228, 17, 195, + 79, 202, 228, 17, 100, 202, 228, 17, 102, 202, 228, 17, 134, 202, 228, + 17, 136, 202, 228, 17, 146, 202, 228, 17, 167, 202, 228, 17, 178, 202, + 228, 17, 171, 202, 228, 17, 182, 202, 228, 190, 251, 92, 202, 228, 190, + 224, 115, 222, 232, 1, 224, 11, 222, 232, 1, 224, 118, 204, 108, 222, + 232, 1, 224, 118, 203, 117, 222, 232, 1, 213, 210, 233, 230, 222, 232, 1, + 216, 252, 222, 232, 1, 244, 182, 222, 232, 1, 213, 210, 247, 16, 222, + 232, 1, 205, 201, 203, 117, 222, 232, 1, 213, 210, 225, 180, 222, 232, 1, + 215, 73, 222, 232, 1, 213, 210, 215, 109, 222, 232, 1, 213, 210, 201, 78, + 222, 232, 1, 213, 210, 201, 66, 222, 232, 1, 213, 210, 240, 41, 222, 232, + 1, 213, 210, 240, 25, 222, 232, 1, 213, 210, 216, 86, 222, 232, 1, 239, + 28, 222, 232, 1, 149, 222, 232, 1, 202, 170, 204, 108, 222, 232, 1, 202, + 170, 203, 117, 222, 232, 1, 213, 210, 239, 176, 222, 232, 1, 216, 50, + 222, 232, 1, 248, 116, 222, 232, 1, 212, 117, 222, 232, 1, 212, 235, 204, + 108, 222, 232, 1, 235, 52, 203, 117, 222, 232, 1, 212, 235, 203, 117, + 222, 232, 1, 235, 52, 204, 108, 222, 232, 1, 213, 210, 248, 197, 222, + 232, 1, 218, 251, 222, 232, 1, 196, 3, 222, 232, 1, 222, 8, 222, 68, 222, + 232, 1, 222, 8, 221, 223, 222, 232, 1, 197, 34, 222, 232, 1, 208, 211, + 207, 50, 222, 232, 1, 208, 211, 205, 80, 222, 232, 1, 205, 201, 204, 108, + 222, 232, 1, 231, 194, 204, 108, 222, 232, 1, 213, 210, 222, 37, 222, + 232, 1, 72, 222, 232, 1, 231, 194, 203, 117, 222, 232, 236, 247, 222, + 232, 18, 2, 63, 222, 232, 18, 2, 220, 82, 225, 17, 222, 232, 18, 2, 252, + 168, 222, 232, 18, 2, 251, 123, 222, 232, 18, 2, 68, 222, 232, 18, 2, + 226, 120, 222, 232, 18, 2, 196, 148, 222, 232, 18, 2, 195, 168, 222, 232, + 18, 2, 66, 222, 232, 18, 2, 199, 245, 222, 232, 2, 213, 210, 199, 7, 222, + 232, 18, 2, 220, 82, 223, 245, 222, 232, 207, 100, 2, 222, 7, 222, 232, + 207, 100, 2, 215, 73, 222, 232, 18, 2, 69, 222, 232, 18, 2, 237, 33, 222, + 232, 18, 2, 72, 222, 232, 18, 2, 250, 122, 222, 232, 18, 2, 251, 200, + 222, 232, 224, 12, 172, 222, 232, 152, 220, 82, 237, 14, 222, 232, 152, + 220, 82, 202, 169, 222, 232, 152, 220, 82, 202, 122, 222, 232, 152, 220, + 82, 247, 91, 222, 232, 247, 139, 78, 222, 232, 216, 196, 222, 232, 17, + 195, 79, 222, 232, 17, 100, 222, 232, 17, 102, 222, 232, 17, 134, 222, + 232, 17, 136, 222, 232, 17, 146, 222, 232, 17, 167, 222, 232, 17, 178, + 222, 232, 17, 171, 222, 232, 17, 182, 222, 232, 231, 194, 216, 50, 222, + 232, 231, 194, 218, 251, 222, 232, 1, 224, 119, 233, 144, 222, 232, 1, + 224, 119, 215, 73, 82, 5, 214, 127, 82, 117, 233, 78, 196, 16, 219, 96, + 201, 119, 63, 82, 117, 233, 78, 196, 16, 219, 96, 255, 169, 209, 237, + 249, 11, 166, 82, 117, 233, 78, 196, 16, 219, 96, 255, 169, 233, 78, 201, + 99, 166, 82, 117, 84, 196, 16, 219, 96, 219, 209, 166, 82, 117, 244, 199, + 196, 16, 219, 96, 207, 57, 166, 82, 117, 247, 111, 196, 16, 219, 96, 212, + 224, 207, 43, 166, 82, 117, 196, 16, 219, 96, 201, 99, 207, 43, 166, 82, + 117, 208, 177, 207, 42, 82, 117, 248, 24, 196, 16, 219, 95, 82, 117, 248, + 138, 206, 192, 196, 16, 219, 95, 82, 117, 226, 22, 201, 98, 82, 117, 239, + 219, 201, 99, 248, 23, 82, 117, 207, 42, 82, 117, 215, 78, 207, 42, 82, + 117, 201, 99, 207, 42, 82, 117, 215, 78, 201, 99, 207, 42, 82, 117, 210, + 5, 245, 89, 205, 97, 207, 42, 82, 117, 210, 81, 233, 112, 207, 42, 82, + 117, 247, 111, 255, 173, 209, 145, 219, 208, 181, 247, 142, 82, 117, 233, + 78, 201, 98, 82, 221, 247, 2, 247, 14, 209, 144, 82, 221, 247, 2, 222, + 120, 209, 144, 82, 250, 174, 2, 207, 53, 234, 51, 255, 174, 209, 144, 82, + 250, 174, 2, 255, 171, 161, 82, 250, 174, 2, 208, 148, 201, 93, 82, 2, + 210, 185, 239, 43, 234, 50, 82, 2, 210, 185, 239, 43, 233, 146, 82, 2, + 210, 185, 239, 43, 233, 79, 82, 2, 210, 185, 217, 237, 234, 50, 82, 2, + 210, 185, 217, 237, 233, 146, 82, 2, 210, 185, 239, 43, 210, 185, 217, + 236, 82, 17, 195, 79, 82, 17, 100, 82, 17, 102, 82, 17, 134, 82, 17, 136, + 82, 17, 146, 82, 17, 167, 82, 17, 178, 82, 17, 171, 82, 17, 182, 82, 17, + 157, 100, 82, 17, 157, 102, 82, 17, 157, 134, 82, 17, 157, 136, 82, 17, + 157, 146, 82, 17, 157, 167, 82, 17, 157, 178, 82, 17, 157, 171, 82, 17, + 157, 182, 82, 17, 157, 195, 79, 82, 117, 248, 26, 209, 144, 82, 117, 217, + 62, 247, 209, 215, 90, 195, 13, 82, 117, 247, 111, 255, 173, 209, 145, + 247, 210, 219, 41, 247, 142, 82, 117, 217, 62, 247, 209, 207, 54, 209, + 144, 82, 117, 245, 104, 219, 95, 82, 117, 201, 114, 255, 170, 82, 117, + 233, 61, 209, 145, 233, 18, 82, 117, 233, 61, 209, 145, 233, 24, 82, 117, + 251, 98, 224, 136, 233, 18, 82, 117, 251, 98, 224, 136, 233, 24, 82, 2, + 196, 91, 201, 97, 82, 2, 220, 38, 201, 97, 82, 1, 155, 82, 1, 224, 146, + 82, 1, 234, 123, 82, 1, 233, 230, 82, 1, 217, 71, 82, 1, 247, 174, 82, 1, + 247, 16, 82, 1, 225, 214, 82, 1, 215, 109, 82, 1, 201, 78, 82, 1, 201, + 66, 82, 1, 240, 41, 82, 1, 240, 25, 82, 1, 216, 86, 82, 1, 189, 82, 1, + 202, 233, 82, 1, 240, 136, 82, 1, 239, 176, 82, 1, 176, 82, 1, 161, 82, + 1, 213, 6, 82, 1, 249, 145, 82, 1, 248, 197, 82, 1, 166, 82, 1, 201, 113, + 82, 1, 201, 103, 82, 1, 237, 156, 82, 1, 237, 150, 82, 1, 197, 166, 82, + 1, 195, 74, 82, 1, 195, 115, 82, 1, 255, 176, 82, 1, 164, 82, 1, 169, 82, + 1, 172, 82, 1, 207, 50, 82, 1, 205, 80, 82, 1, 183, 82, 1, 142, 82, 1, + 63, 82, 1, 223, 201, 82, 1, 235, 97, 169, 82, 1, 224, 36, 82, 1, 209, + 181, 82, 18, 2, 252, 168, 82, 18, 2, 68, 82, 18, 2, 226, 120, 82, 18, 2, + 66, 82, 18, 2, 199, 245, 82, 18, 2, 110, 144, 82, 18, 2, 110, 209, 182, + 82, 18, 2, 110, 159, 82, 18, 2, 110, 222, 38, 82, 18, 2, 69, 82, 18, 2, + 237, 54, 82, 18, 2, 72, 82, 18, 2, 214, 102, 82, 2, 209, 243, 204, 173, + 217, 72, 209, 232, 82, 2, 209, 237, 249, 10, 82, 18, 2, 210, 89, 68, 82, + 18, 2, 210, 89, 226, 120, 82, 2, 215, 90, 195, 14, 217, 245, 240, 136, + 82, 2, 205, 215, 222, 199, 82, 117, 232, 227, 82, 117, 213, 202, 82, 2, + 222, 202, 209, 144, 82, 2, 196, 96, 209, 144, 82, 2, 222, 203, 201, 114, + 247, 142, 82, 2, 219, 211, 247, 142, 82, 2, 233, 82, 247, 143, 210, 79, + 82, 2, 233, 82, 219, 197, 210, 79, 82, 2, 226, 17, 219, 211, 247, 142, + 82, 204, 152, 2, 222, 203, 201, 114, 247, 142, 82, 204, 152, 2, 219, 211, + 247, 142, 82, 204, 152, 2, 226, 17, 219, 211, 247, 142, 82, 204, 152, 1, + 155, 82, 204, 152, 1, 224, 146, 82, 204, 152, 1, 234, 123, 82, 204, 152, + 1, 233, 230, 82, 204, 152, 1, 217, 71, 82, 204, 152, 1, 247, 174, 82, + 204, 152, 1, 247, 16, 82, 204, 152, 1, 225, 214, 82, 204, 152, 1, 215, + 109, 82, 204, 152, 1, 201, 78, 82, 204, 152, 1, 201, 66, 82, 204, 152, 1, + 240, 41, 82, 204, 152, 1, 240, 25, 82, 204, 152, 1, 216, 86, 82, 204, + 152, 1, 189, 82, 204, 152, 1, 202, 233, 82, 204, 152, 1, 240, 136, 82, + 204, 152, 1, 239, 176, 82, 204, 152, 1, 176, 82, 204, 152, 1, 161, 82, + 204, 152, 1, 213, 6, 82, 204, 152, 1, 249, 145, 82, 204, 152, 1, 248, + 197, 82, 204, 152, 1, 166, 82, 204, 152, 1, 201, 113, 82, 204, 152, 1, + 201, 103, 82, 204, 152, 1, 237, 156, 82, 204, 152, 1, 237, 150, 82, 204, + 152, 1, 197, 166, 82, 204, 152, 1, 195, 74, 82, 204, 152, 1, 195, 115, + 82, 204, 152, 1, 255, 176, 82, 204, 152, 1, 164, 82, 204, 152, 1, 169, + 82, 204, 152, 1, 172, 82, 204, 152, 1, 207, 50, 82, 204, 152, 1, 205, 80, + 82, 204, 152, 1, 183, 82, 204, 152, 1, 142, 82, 204, 152, 1, 63, 82, 204, + 152, 1, 223, 201, 82, 204, 152, 1, 235, 97, 197, 166, 82, 204, 152, 1, + 235, 97, 164, 82, 204, 152, 1, 235, 97, 169, 82, 223, 188, 209, 141, 224, + 146, 82, 223, 188, 209, 141, 224, 147, 247, 210, 219, 41, 247, 142, 82, + 247, 126, 2, 85, 249, 0, 82, 247, 126, 2, 175, 249, 0, 82, 247, 126, 2, + 247, 130, 203, 58, 82, 247, 126, 2, 208, 176, 255, 175, 82, 16, 237, 217, + 248, 21, 82, 16, 210, 184, 209, 244, 82, 16, 213, 229, 234, 49, 82, 16, + 210, 184, 209, 245, 210, 81, 233, 111, 82, 16, 212, 224, 161, 82, 16, + 216, 28, 248, 21, 82, 16, 216, 28, 248, 22, 215, 78, 255, 172, 82, 16, + 216, 28, 248, 22, 233, 80, 255, 172, 82, 16, 216, 28, 248, 22, 247, 210, + 255, 172, 82, 2, 210, 185, 217, 237, 210, 185, 239, 42, 82, 2, 210, 185, + 217, 237, 233, 79, 82, 117, 248, 25, 206, 192, 233, 193, 219, 96, 210, + 80, 82, 117, 218, 253, 196, 16, 233, 193, 219, 96, 210, 80, 82, 117, 215, + 78, 201, 98, 82, 117, 84, 248, 54, 209, 234, 196, 16, 219, 96, 219, 209, + 166, 82, 117, 244, 199, 248, 54, 209, 234, 196, 16, 219, 96, 207, 57, + 166, 210, 21, 204, 69, 55, 222, 183, 204, 69, 55, 210, 21, 204, 69, 2, 3, + 238, 250, 222, 183, 204, 69, 2, 3, 238, 250, 82, 117, 222, 194, 219, 212, + 209, 144, 82, 117, 201, 209, 219, 212, 209, 144, 75, 1, 155, 75, 1, 224, + 146, 75, 1, 234, 123, 75, 1, 233, 230, 75, 1, 217, 71, 75, 1, 247, 174, + 75, 1, 247, 16, 75, 1, 225, 214, 75, 1, 225, 180, 75, 1, 215, 109, 75, 1, + 216, 52, 75, 1, 201, 78, 75, 1, 201, 66, 75, 1, 240, 41, 75, 1, 240, 25, + 75, 1, 216, 86, 75, 1, 189, 75, 1, 202, 233, 75, 1, 240, 136, 75, 1, 239, + 176, 75, 1, 176, 75, 1, 161, 75, 1, 213, 6, 75, 1, 249, 145, 75, 1, 248, + 197, 75, 1, 166, 75, 1, 164, 75, 1, 169, 75, 1, 172, 75, 1, 197, 166, 75, + 1, 183, 75, 1, 142, 75, 1, 222, 37, 75, 1, 63, 75, 1, 207, 25, 63, 75, 1, + 68, 75, 1, 226, 120, 75, 1, 66, 75, 1, 199, 245, 75, 1, 69, 75, 1, 218, + 216, 69, 75, 1, 72, 75, 1, 250, 150, 75, 18, 2, 203, 120, 252, 168, 75, + 18, 2, 252, 168, 75, 18, 2, 68, 75, 18, 2, 226, 120, 75, 18, 2, 66, 75, + 18, 2, 199, 245, 75, 18, 2, 69, 75, 18, 2, 251, 200, 75, 18, 2, 218, 216, + 226, 120, 75, 18, 2, 218, 216, 72, 75, 18, 2, 237, 136, 57, 75, 2, 251, + 51, 75, 2, 76, 60, 75, 2, 199, 2, 75, 2, 199, 7, 75, 2, 250, 199, 75, + 108, 2, 219, 194, 164, 75, 108, 2, 219, 194, 169, 75, 108, 2, 219, 194, + 197, 166, 75, 108, 2, 219, 194, 142, 75, 1, 233, 96, 183, 75, 17, 195, + 79, 75, 17, 100, 75, 17, 102, 75, 17, 134, 75, 17, 136, 75, 17, 146, 75, + 17, 167, 75, 17, 178, 75, 17, 171, 75, 17, 182, 75, 2, 222, 47, 208, 132, + 75, 2, 208, 132, 75, 16, 222, 0, 75, 16, 244, 152, 75, 16, 251, 221, 75, + 16, 234, 29, 75, 1, 207, 50, 75, 1, 205, 80, 75, 1, 110, 144, 75, 1, 110, + 209, 182, 75, 1, 110, 159, 75, 1, 110, 222, 38, 75, 18, 2, 110, 144, 75, + 18, 2, 110, 209, 182, 75, 18, 2, 110, 159, 75, 18, 2, 110, 222, 38, 75, + 1, 218, 216, 217, 71, 75, 1, 218, 216, 225, 180, 75, 1, 218, 216, 249, + 45, 75, 1, 218, 216, 249, 40, 75, 108, 2, 218, 216, 219, 194, 176, 75, + 108, 2, 218, 216, 219, 194, 166, 75, 108, 2, 218, 216, 219, 194, 172, 75, + 1, 207, 56, 224, 248, 207, 50, 75, 18, 2, 207, 56, 224, 248, 236, 116, + 75, 152, 117, 207, 56, 224, 248, 232, 161, 75, 152, 117, 207, 56, 224, + 248, 224, 210, 212, 234, 75, 1, 197, 86, 211, 179, 224, 248, 202, 233, + 75, 1, 197, 86, 211, 179, 224, 248, 211, 185, 75, 18, 2, 197, 86, 211, + 179, 224, 248, 236, 116, 75, 18, 2, 197, 86, 211, 179, 224, 248, 200, 99, + 75, 2, 197, 86, 211, 179, 224, 248, 202, 10, 75, 2, 197, 86, 211, 179, + 224, 248, 202, 9, 75, 2, 197, 86, 211, 179, 224, 248, 202, 8, 75, 2, 197, + 86, 211, 179, 224, 248, 202, 7, 75, 2, 197, 86, 211, 179, 224, 248, 202, + 6, 75, 1, 237, 67, 211, 179, 224, 248, 216, 86, 75, 1, 237, 67, 211, 179, + 224, 248, 195, 175, 75, 1, 237, 67, 211, 179, 224, 248, 233, 195, 75, 18, + 2, 234, 44, 224, 248, 68, 75, 18, 2, 224, 215, 214, 164, 75, 18, 2, 224, + 215, 66, 75, 18, 2, 224, 215, 237, 54, 75, 1, 207, 25, 155, 75, 1, 207, + 25, 224, 146, 75, 1, 207, 25, 234, 123, 75, 1, 207, 25, 247, 174, 75, 1, + 207, 25, 195, 115, 75, 1, 207, 25, 215, 109, 75, 1, 207, 25, 240, 136, + 75, 1, 207, 25, 176, 75, 1, 207, 25, 213, 6, 75, 1, 207, 25, 235, 239, + 75, 1, 207, 25, 249, 145, 75, 1, 207, 25, 202, 233, 75, 1, 207, 25, 142, + 75, 108, 2, 207, 25, 219, 194, 197, 166, 75, 18, 2, 207, 25, 252, 168, + 75, 18, 2, 207, 25, 69, 75, 18, 2, 207, 25, 237, 136, 57, 75, 18, 2, 207, + 25, 48, 196, 148, 75, 2, 207, 25, 202, 9, 75, 2, 207, 25, 202, 8, 75, 2, + 207, 25, 202, 6, 75, 2, 207, 25, 202, 5, 75, 2, 207, 25, 241, 91, 202, 9, + 75, 2, 207, 25, 241, 91, 202, 8, 75, 2, 207, 25, 241, 91, 236, 233, 202, + 11, 75, 1, 209, 119, 213, 212, 235, 239, 75, 2, 209, 119, 213, 212, 202, + 6, 75, 207, 25, 17, 195, 79, 75, 207, 25, 17, 100, 75, 207, 25, 17, 102, + 75, 207, 25, 17, 134, 75, 207, 25, 17, 136, 75, 207, 25, 17, 146, 75, + 207, 25, 17, 167, 75, 207, 25, 17, 178, 75, 207, 25, 17, 171, 75, 207, + 25, 17, 182, 75, 2, 224, 139, 202, 10, 75, 2, 224, 139, 202, 8, 75, 18, + 2, 251, 186, 63, 75, 18, 2, 251, 186, 251, 200, 75, 16, 207, 25, 100, 75, + 16, 207, 25, 236, 89, 94, 6, 1, 251, 106, 94, 6, 1, 249, 93, 94, 6, 1, + 234, 93, 94, 6, 1, 239, 6, 94, 6, 1, 236, 230, 94, 6, 1, 199, 16, 94, 6, + 1, 195, 82, 94, 6, 1, 203, 114, 94, 6, 1, 226, 86, 94, 6, 1, 225, 17, 94, + 6, 1, 222, 222, 94, 6, 1, 220, 62, 94, 6, 1, 217, 211, 94, 6, 1, 214, + 119, 94, 6, 1, 213, 157, 94, 6, 1, 195, 70, 94, 6, 1, 210, 229, 94, 6, 1, + 208, 219, 94, 6, 1, 203, 101, 94, 6, 1, 200, 72, 94, 6, 1, 212, 254, 94, + 6, 1, 224, 134, 94, 6, 1, 233, 221, 94, 6, 1, 211, 144, 94, 6, 1, 206, + 211, 94, 6, 1, 245, 62, 94, 6, 1, 247, 142, 94, 6, 1, 225, 162, 94, 6, 1, + 245, 0, 94, 6, 1, 247, 0, 94, 6, 1, 196, 206, 94, 6, 1, 225, 177, 94, 6, + 1, 232, 242, 94, 6, 1, 232, 147, 94, 6, 1, 232, 58, 94, 6, 1, 197, 109, + 94, 6, 1, 232, 175, 94, 6, 1, 231, 181, 94, 6, 1, 196, 5, 94, 6, 1, 251, + 234, 94, 1, 251, 106, 94, 1, 249, 93, 94, 1, 234, 93, 94, 1, 239, 6, 94, + 1, 236, 230, 94, 1, 199, 16, 94, 1, 195, 82, 94, 1, 203, 114, 94, 1, 226, + 86, 94, 1, 225, 17, 94, 1, 222, 222, 94, 1, 220, 62, 94, 1, 217, 211, 94, + 1, 214, 119, 94, 1, 213, 157, 94, 1, 195, 70, 94, 1, 210, 229, 94, 1, + 208, 219, 94, 1, 203, 101, 94, 1, 200, 72, 94, 1, 212, 254, 94, 1, 224, + 134, 94, 1, 233, 221, 94, 1, 211, 144, 94, 1, 206, 211, 94, 1, 245, 62, + 94, 1, 247, 142, 94, 1, 225, 162, 94, 1, 245, 0, 94, 1, 247, 0, 94, 1, + 196, 206, 94, 1, 225, 177, 94, 1, 232, 242, 94, 1, 232, 147, 94, 1, 232, + 58, 94, 1, 197, 109, 94, 1, 232, 175, 94, 1, 231, 181, 94, 1, 235, 153, + 94, 1, 196, 5, 94, 1, 236, 249, 94, 1, 163, 234, 93, 94, 1, 251, 194, 94, + 213, 154, 207, 90, 73, 1, 94, 217, 211, 94, 1, 251, 234, 94, 1, 232, 173, + 55, 94, 1, 223, 73, 55, 29, 137, 224, 48, 29, 137, 205, 72, 29, 137, 216, + 208, 29, 137, 202, 97, 29, 137, 205, 61, 29, 137, 210, 54, 29, 137, 219, + 56, 29, 137, 212, 206, 29, 137, 205, 69, 29, 137, 206, 52, 29, 137, 205, + 66, 29, 137, 226, 143, 29, 137, 245, 6, 29, 137, 205, 76, 29, 137, 245, + 71, 29, 137, 224, 122, 29, 137, 202, 191, 29, 137, 212, 244, 29, 137, + 232, 55, 29, 137, 216, 204, 29, 137, 205, 70, 29, 137, 216, 198, 29, 137, + 216, 202, 29, 137, 202, 94, 29, 137, 210, 42, 29, 137, 205, 68, 29, 137, + 210, 52, 29, 137, 224, 254, 29, 137, 219, 49, 29, 137, 225, 1, 29, 137, + 212, 201, 29, 137, 212, 199, 29, 137, 212, 187, 29, 137, 212, 195, 29, + 137, 212, 193, 29, 137, 212, 190, 29, 137, 212, 192, 29, 137, 212, 189, + 29, 137, 212, 194, 29, 137, 212, 204, 29, 137, 212, 205, 29, 137, 212, + 188, 29, 137, 212, 198, 29, 137, 224, 255, 29, 137, 224, 253, 29, 137, + 206, 45, 29, 137, 206, 43, 29, 137, 206, 35, 29, 137, 206, 38, 29, 137, + 206, 44, 29, 137, 206, 40, 29, 137, 206, 39, 29, 137, 206, 37, 29, 137, + 206, 48, 29, 137, 206, 50, 29, 137, 206, 51, 29, 137, 206, 46, 29, 137, + 206, 36, 29, 137, 206, 41, 29, 137, 206, 49, 29, 137, 245, 53, 29, 137, + 245, 51, 29, 137, 247, 29, 29, 137, 247, 27, 29, 137, 213, 174, 29, 137, + 226, 138, 29, 137, 226, 129, 29, 137, 226, 137, 29, 137, 226, 134, 29, + 137, 226, 132, 29, 137, 226, 136, 29, 137, 205, 73, 29, 137, 226, 141, + 29, 137, 226, 142, 29, 137, 226, 130, 29, 137, 226, 135, 29, 137, 196, + 46, 29, 137, 245, 5, 29, 137, 245, 54, 29, 137, 245, 52, 29, 137, 247, + 30, 29, 137, 247, 28, 29, 137, 245, 69, 29, 137, 245, 70, 29, 137, 245, + 55, 29, 137, 247, 31, 29, 137, 212, 242, 29, 137, 225, 0, 29, 137, 205, + 74, 29, 137, 196, 52, 29, 137, 224, 39, 29, 137, 216, 200, 29, 137, 216, + 206, 29, 137, 216, 205, 29, 137, 202, 91, 29, 137, 235, 134, 29, 225, + 102, 235, 134, 29, 225, 102, 63, 29, 225, 102, 251, 245, 29, 225, 102, + 164, 29, 225, 102, 196, 118, 29, 225, 102, 236, 192, 29, 225, 102, 69, + 29, 225, 102, 196, 56, 29, 225, 102, 196, 69, 29, 225, 102, 72, 29, 225, + 102, 197, 166, 29, 225, 102, 197, 157, 29, 225, 102, 214, 164, 29, 225, + 102, 196, 3, 29, 225, 102, 66, 29, 225, 102, 197, 91, 29, 225, 102, 197, + 109, 29, 225, 102, 197, 70, 29, 225, 102, 195, 217, 29, 225, 102, 236, + 116, 29, 225, 102, 196, 24, 29, 225, 102, 68, 29, 225, 102, 255, 164, 29, + 225, 102, 255, 163, 29, 225, 102, 196, 132, 29, 225, 102, 196, 130, 29, + 225, 102, 236, 190, 29, 225, 102, 236, 189, 29, 225, 102, 236, 191, 29, + 225, 102, 196, 55, 29, 225, 102, 196, 54, 29, 225, 102, 215, 18, 29, 225, + 102, 215, 19, 29, 225, 102, 215, 12, 29, 225, 102, 215, 17, 29, 225, 102, + 215, 15, 29, 225, 102, 195, 247, 29, 225, 102, 195, 246, 29, 225, 102, + 195, 245, 29, 225, 102, 195, 248, 29, 225, 102, 195, 249, 29, 225, 102, + 200, 172, 29, 225, 102, 200, 171, 29, 225, 102, 200, 169, 29, 225, 102, + 200, 165, 29, 225, 102, 200, 166, 29, 225, 102, 195, 212, 29, 225, 102, + 195, 209, 29, 225, 102, 195, 210, 29, 225, 102, 195, 204, 29, 225, 102, + 195, 205, 29, 225, 102, 195, 206, 29, 225, 102, 195, 208, 29, 225, 102, + 236, 110, 29, 225, 102, 236, 112, 29, 225, 102, 196, 23, 29, 225, 102, + 230, 244, 29, 225, 102, 230, 236, 29, 225, 102, 230, 239, 29, 225, 102, + 230, 237, 29, 225, 102, 230, 241, 29, 225, 102, 230, 243, 29, 225, 102, + 251, 6, 29, 225, 102, 251, 3, 29, 225, 102, 251, 1, 29, 225, 102, 251, 2, + 29, 225, 102, 205, 77, 29, 225, 102, 255, 165, 29, 225, 102, 196, 131, + 29, 225, 102, 196, 53, 29, 225, 102, 215, 14, 29, 225, 102, 215, 13, 29, + 116, 224, 48, 29, 116, 205, 72, 29, 116, 224, 41, 29, 116, 216, 208, 29, + 116, 216, 206, 29, 116, 216, 205, 29, 116, 202, 97, 29, 116, 210, 54, 29, + 116, 210, 49, 29, 116, 210, 46, 29, 116, 210, 39, 29, 116, 210, 34, 29, + 116, 210, 29, 29, 116, 210, 40, 29, 116, 210, 52, 29, 116, 219, 56, 29, + 116, 212, 206, 29, 116, 212, 195, 29, 116, 206, 52, 29, 116, 205, 66, 29, + 116, 226, 143, 29, 116, 245, 6, 29, 116, 245, 71, 29, 116, 224, 122, 29, + 116, 202, 191, 29, 116, 212, 244, 29, 116, 232, 55, 29, 116, 224, 42, 29, + 116, 224, 40, 29, 116, 216, 204, 29, 116, 216, 198, 29, 116, 216, 200, + 29, 116, 216, 203, 29, 116, 216, 199, 29, 116, 202, 94, 29, 116, 202, 91, + 29, 116, 210, 47, 29, 116, 210, 42, 29, 116, 210, 28, 29, 116, 210, 27, + 29, 116, 205, 68, 29, 116, 210, 44, 29, 116, 210, 43, 29, 116, 210, 36, + 29, 116, 210, 38, 29, 116, 210, 51, 29, 116, 210, 31, 29, 116, 210, 41, + 29, 116, 210, 50, 29, 116, 210, 26, 29, 116, 219, 52, 29, 116, 219, 47, + 29, 116, 219, 49, 29, 116, 219, 46, 29, 116, 219, 44, 29, 116, 219, 50, + 29, 116, 219, 55, 29, 116, 219, 53, 29, 116, 225, 1, 29, 116, 212, 197, + 29, 116, 212, 198, 29, 116, 212, 203, 29, 116, 224, 255, 29, 116, 206, + 45, 29, 116, 206, 35, 29, 116, 206, 38, 29, 116, 206, 40, 29, 116, 213, + 174, 29, 116, 226, 138, 29, 116, 226, 131, 29, 116, 205, 73, 29, 116, + 226, 139, 29, 116, 196, 46, 29, 116, 196, 40, 29, 116, 196, 41, 29, 116, + 212, 242, 29, 116, 225, 0, 29, 116, 232, 53, 29, 116, 232, 51, 29, 116, + 232, 54, 29, 116, 232, 52, 29, 116, 196, 52, 29, 116, 224, 44, 29, 116, + 224, 43, 29, 116, 224, 47, 29, 116, 224, 45, 29, 116, 224, 46, 29, 116, + 205, 70, 35, 5, 142, 35, 5, 231, 75, 35, 5, 232, 71, 35, 5, 232, 246, 35, + 5, 232, 118, 35, 5, 232, 147, 35, 5, 231, 193, 35, 5, 231, 184, 35, 5, + 172, 35, 5, 221, 191, 35, 5, 222, 109, 35, 5, 223, 82, 35, 5, 222, 188, + 35, 5, 222, 197, 35, 5, 222, 7, 35, 5, 221, 159, 35, 5, 232, 80, 35, 5, + 232, 74, 35, 5, 232, 76, 35, 5, 232, 79, 35, 5, 232, 77, 35, 5, 232, 78, + 35, 5, 232, 75, 35, 5, 232, 73, 35, 5, 166, 35, 5, 218, 145, 35, 5, 219, + 78, 35, 5, 220, 119, 35, 5, 219, 188, 35, 5, 219, 207, 35, 5, 218, 251, + 35, 5, 218, 72, 35, 5, 203, 227, 35, 5, 203, 221, 35, 5, 203, 223, 35, 5, + 203, 226, 35, 5, 203, 224, 35, 5, 203, 225, 35, 5, 203, 222, 35, 5, 203, + 220, 35, 5, 169, 35, 5, 209, 140, 35, 5, 210, 72, 35, 5, 210, 244, 35, 5, + 210, 155, 35, 5, 210, 183, 35, 5, 209, 232, 35, 5, 209, 98, 35, 5, 183, + 35, 5, 204, 172, 35, 5, 206, 112, 35, 5, 209, 13, 35, 5, 208, 129, 35, 5, + 208, 147, 35, 5, 205, 200, 35, 5, 204, 67, 35, 5, 207, 50, 35, 5, 206, + 151, 35, 5, 206, 223, 35, 5, 207, 45, 35, 5, 206, 253, 35, 5, 206, 255, + 35, 5, 206, 198, 35, 5, 206, 130, 35, 5, 211, 159, 35, 5, 211, 97, 35, 5, + 211, 121, 35, 5, 211, 158, 35, 5, 211, 138, 35, 5, 211, 139, 35, 5, 211, + 109, 35, 5, 211, 108, 35, 5, 211, 50, 35, 5, 211, 46, 35, 5, 211, 49, 35, + 5, 211, 47, 35, 5, 211, 48, 35, 5, 211, 135, 35, 5, 211, 127, 35, 5, 211, + 130, 35, 5, 211, 134, 35, 5, 211, 131, 35, 5, 211, 132, 35, 5, 211, 129, + 35, 5, 211, 126, 35, 5, 211, 122, 35, 5, 211, 125, 35, 5, 211, 123, 35, + 5, 211, 124, 35, 5, 249, 145, 35, 5, 248, 21, 35, 5, 248, 184, 35, 5, + 249, 143, 35, 5, 248, 251, 35, 5, 249, 9, 35, 5, 248, 116, 35, 5, 247, + 224, 35, 5, 199, 152, 35, 5, 197, 220, 35, 5, 199, 34, 35, 5, 199, 151, + 35, 5, 199, 113, 35, 5, 199, 118, 35, 5, 198, 248, 35, 5, 197, 209, 35, + 5, 189, 35, 5, 201, 40, 35, 5, 202, 122, 35, 5, 203, 162, 35, 5, 203, 48, + 35, 5, 203, 68, 35, 5, 149, 35, 5, 200, 245, 35, 5, 247, 174, 35, 5, 241, + 41, 35, 5, 245, 11, 35, 5, 247, 173, 35, 5, 247, 49, 35, 5, 247, 57, 35, + 5, 244, 182, 35, 5, 240, 254, 35, 5, 196, 208, 35, 5, 196, 177, 35, 5, + 196, 196, 35, 5, 196, 207, 35, 5, 196, 201, 35, 5, 196, 202, 35, 5, 196, + 185, 35, 5, 196, 184, 35, 5, 196, 170, 35, 5, 196, 166, 35, 5, 196, 169, + 35, 5, 196, 167, 35, 5, 196, 168, 35, 5, 176, 35, 5, 215, 186, 35, 5, + 216, 223, 35, 5, 217, 244, 35, 5, 217, 107, 35, 5, 217, 118, 35, 5, 216, + 50, 35, 5, 215, 118, 35, 5, 215, 109, 35, 5, 215, 66, 35, 5, 215, 89, 35, + 5, 215, 108, 35, 5, 215, 97, 35, 5, 215, 98, 35, 5, 215, 73, 35, 5, 215, + 56, 35, 5, 233, 152, 63, 35, 5, 233, 152, 66, 35, 5, 233, 152, 68, 35, 5, + 233, 152, 252, 168, 35, 5, 233, 152, 237, 54, 35, 5, 233, 152, 69, 35, 5, + 233, 152, 72, 35, 5, 233, 152, 197, 166, 35, 5, 155, 35, 5, 223, 187, 35, + 5, 224, 101, 35, 5, 225, 55, 35, 5, 224, 200, 35, 5, 224, 209, 35, 5, + 224, 11, 35, 5, 224, 6, 35, 5, 223, 136, 35, 5, 223, 129, 35, 5, 223, + 135, 35, 5, 223, 130, 35, 5, 223, 131, 35, 5, 223, 122, 35, 5, 223, 116, + 35, 5, 223, 118, 35, 5, 223, 121, 35, 5, 223, 119, 35, 5, 223, 120, 35, + 5, 223, 117, 35, 5, 223, 115, 35, 5, 223, 111, 35, 5, 223, 114, 35, 5, + 223, 112, 35, 5, 223, 113, 35, 5, 197, 166, 35, 5, 196, 243, 35, 5, 197, + 70, 35, 5, 197, 160, 35, 5, 197, 98, 35, 5, 197, 109, 35, 5, 197, 34, 35, + 5, 197, 26, 35, 5, 212, 253, 63, 35, 5, 212, 253, 66, 35, 5, 212, 253, + 68, 35, 5, 212, 253, 252, 168, 35, 5, 212, 253, 237, 54, 35, 5, 212, 253, + 69, 35, 5, 212, 253, 72, 35, 5, 195, 115, 35, 5, 194, 255, 35, 5, 195, + 33, 35, 5, 195, 113, 35, 5, 195, 85, 35, 5, 195, 88, 35, 5, 195, 11, 35, + 5, 194, 242, 35, 5, 195, 74, 35, 5, 195, 51, 35, 5, 195, 60, 35, 5, 195, + 73, 35, 5, 195, 64, 35, 5, 195, 65, 35, 5, 195, 57, 35, 5, 195, 42, 35, + 5, 164, 35, 5, 195, 217, 35, 5, 196, 24, 35, 5, 196, 129, 35, 5, 196, 66, + 35, 5, 196, 69, 35, 5, 196, 3, 35, 5, 195, 243, 35, 5, 240, 136, 35, 5, + 237, 201, 35, 5, 239, 152, 35, 5, 240, 135, 35, 5, 239, 237, 35, 5, 239, + 252, 35, 5, 239, 28, 35, 5, 237, 167, 35, 5, 240, 41, 35, 5, 240, 6, 35, + 5, 240, 18, 35, 5, 240, 40, 35, 5, 240, 28, 35, 5, 240, 29, 35, 5, 240, + 11, 35, 5, 239, 253, 35, 5, 225, 214, 35, 5, 225, 110, 35, 5, 225, 172, + 35, 5, 225, 213, 35, 5, 225, 191, 35, 5, 225, 193, 35, 5, 225, 129, 35, + 5, 225, 88, 35, 5, 234, 123, 35, 5, 233, 76, 35, 5, 233, 192, 35, 5, 234, + 120, 35, 5, 234, 40, 35, 5, 234, 48, 35, 5, 233, 144, 35, 5, 233, 143, + 35, 5, 233, 34, 35, 5, 233, 30, 35, 5, 233, 33, 35, 5, 233, 31, 35, 5, + 233, 32, 35, 5, 234, 10, 35, 5, 233, 246, 35, 5, 234, 0, 35, 5, 234, 9, + 35, 5, 234, 4, 35, 5, 234, 5, 35, 5, 233, 250, 35, 5, 233, 235, 35, 5, + 202, 233, 35, 5, 202, 142, 35, 5, 202, 195, 35, 5, 202, 232, 35, 5, 202, + 215, 35, 5, 202, 217, 35, 5, 202, 169, 35, 5, 202, 133, 35, 5, 247, 16, + 35, 5, 245, 30, 35, 5, 245, 75, 35, 5, 247, 15, 35, 5, 245, 99, 35, 5, + 245, 103, 35, 5, 245, 49, 35, 5, 245, 19, 35, 5, 213, 6, 35, 5, 212, 226, + 35, 5, 212, 246, 35, 5, 213, 5, 35, 5, 212, 248, 35, 5, 212, 249, 35, 5, + 212, 234, 35, 5, 212, 222, 35, 5, 201, 113, 35, 5, 201, 86, 35, 5, 201, + 92, 35, 5, 201, 112, 35, 5, 201, 106, 35, 5, 201, 107, 35, 5, 201, 90, + 35, 5, 201, 84, 35, 5, 200, 186, 35, 5, 200, 178, 35, 5, 200, 182, 35, 5, + 200, 185, 35, 5, 200, 183, 35, 5, 200, 184, 35, 5, 200, 180, 35, 5, 200, + 179, 35, 5, 235, 239, 35, 5, 234, 223, 35, 5, 235, 153, 35, 5, 235, 238, + 35, 5, 235, 182, 35, 5, 235, 189, 35, 5, 235, 51, 35, 5, 234, 201, 35, 5, + 161, 35, 5, 211, 227, 35, 5, 212, 220, 35, 5, 213, 243, 35, 5, 213, 79, + 35, 5, 213, 92, 35, 5, 212, 117, 35, 5, 211, 185, 35, 5, 209, 88, 35, 5, + 218, 61, 35, 5, 234, 195, 35, 38, 234, 36, 26, 18, 222, 158, 78, 35, 38, + 18, 222, 158, 78, 35, 38, 234, 36, 78, 35, 208, 133, 78, 35, 197, 8, 35, + 234, 217, 204, 226, 35, 244, 159, 35, 207, 105, 35, 244, 168, 35, 212, + 32, 244, 168, 35, 211, 79, 78, 35, 213, 154, 207, 90, 35, 17, 100, 35, + 17, 102, 35, 17, 134, 35, 17, 136, 35, 17, 146, 35, 17, 167, 35, 17, 178, + 35, 17, 171, 35, 17, 182, 35, 31, 203, 23, 35, 31, 200, 234, 35, 31, 202, + 177, 35, 31, 235, 14, 35, 31, 235, 145, 35, 31, 206, 13, 35, 31, 207, 65, + 35, 31, 237, 20, 35, 31, 216, 174, 35, 31, 231, 57, 35, 31, 203, 24, 170, + 35, 5, 208, 138, 218, 72, 35, 5, 218, 68, 35, 5, 218, 69, 35, 5, 218, 70, + 35, 5, 208, 138, 247, 224, 35, 5, 247, 221, 35, 5, 247, 222, 35, 5, 247, + 223, 35, 5, 208, 138, 234, 201, 35, 5, 234, 197, 35, 5, 234, 198, 35, 5, + 234, 199, 35, 5, 208, 138, 211, 185, 35, 5, 211, 181, 35, 5, 211, 182, + 35, 5, 211, 183, 35, 202, 12, 117, 196, 6, 35, 202, 12, 117, 239, 197, + 35, 202, 12, 117, 210, 8, 35, 202, 12, 117, 206, 182, 210, 8, 35, 202, + 12, 117, 239, 126, 35, 202, 12, 117, 224, 181, 35, 202, 12, 117, 245, 57, + 35, 202, 12, 117, 232, 60, 35, 202, 12, 117, 239, 196, 35, 202, 12, 117, + 223, 152, 95, 1, 63, 95, 1, 69, 95, 1, 68, 95, 1, 72, 95, 1, 66, 95, 1, + 199, 230, 95, 1, 234, 123, 95, 1, 155, 95, 1, 234, 48, 95, 1, 233, 192, + 95, 1, 233, 144, 95, 1, 233, 76, 95, 1, 233, 36, 95, 1, 142, 95, 1, 232, + 147, 95, 1, 232, 71, 95, 1, 231, 193, 95, 1, 231, 75, 95, 1, 231, 44, 95, + 1, 172, 95, 1, 222, 197, 95, 1, 222, 109, 95, 1, 222, 7, 95, 1, 221, 191, + 95, 1, 221, 160, 95, 1, 166, 95, 1, 219, 207, 95, 1, 219, 78, 95, 1, 218, + 251, 95, 1, 218, 145, 95, 1, 176, 95, 1, 231, 217, 95, 1, 217, 231, 95, + 1, 217, 118, 95, 1, 216, 223, 95, 1, 216, 50, 95, 1, 215, 186, 95, 1, + 215, 120, 95, 1, 211, 96, 95, 1, 211, 82, 95, 1, 211, 75, 95, 1, 211, 65, + 95, 1, 211, 54, 95, 1, 211, 52, 95, 1, 183, 95, 1, 209, 80, 95, 1, 208, + 147, 95, 1, 206, 112, 95, 1, 205, 200, 95, 1, 204, 172, 95, 1, 204, 72, + 95, 1, 240, 136, 95, 1, 189, 95, 1, 239, 252, 95, 1, 203, 68, 95, 1, 239, + 152, 95, 1, 202, 122, 95, 1, 239, 28, 95, 1, 237, 201, 95, 1, 237, 170, + 95, 1, 239, 40, 95, 1, 202, 47, 95, 1, 202, 46, 95, 1, 202, 35, 95, 1, + 202, 34, 95, 1, 202, 33, 95, 1, 202, 32, 95, 1, 201, 113, 95, 1, 201, + 107, 95, 1, 201, 92, 95, 1, 201, 90, 95, 1, 201, 86, 95, 1, 201, 85, 95, + 1, 197, 166, 95, 1, 197, 109, 95, 1, 197, 70, 95, 1, 197, 34, 95, 1, 196, + 243, 95, 1, 196, 230, 95, 1, 164, 95, 1, 196, 69, 95, 1, 196, 24, 95, 1, + 196, 3, 95, 1, 195, 217, 95, 1, 195, 176, 95, 1, 218, 79, 95, 4, 1, 196, + 69, 95, 4, 1, 196, 24, 95, 4, 1, 196, 3, 95, 4, 1, 195, 217, 95, 4, 1, + 195, 176, 95, 4, 1, 218, 79, 21, 22, 231, 7, 21, 22, 69, 21, 22, 252, + 132, 21, 22, 68, 21, 22, 226, 120, 21, 22, 72, 21, 22, 214, 102, 21, 22, + 196, 147, 214, 102, 21, 22, 92, 237, 54, 21, 22, 92, 68, 21, 22, 63, 21, + 22, 252, 168, 21, 22, 197, 109, 21, 22, 197, 87, 197, 109, 21, 22, 197, + 70, 21, 22, 197, 87, 197, 70, 21, 22, 197, 54, 21, 22, 197, 87, 197, 54, + 21, 22, 197, 34, 21, 22, 197, 87, 197, 34, 21, 22, 197, 15, 21, 22, 197, + 87, 197, 15, 21, 22, 217, 205, 197, 15, 21, 22, 197, 166, 21, 22, 197, + 87, 197, 166, 21, 22, 197, 160, 21, 22, 197, 87, 197, 160, 21, 22, 217, + 205, 197, 160, 21, 22, 251, 200, 21, 22, 196, 147, 197, 199, 21, 22, 233, + 152, 204, 226, 21, 22, 48, 186, 21, 22, 48, 233, 100, 21, 22, 48, 248, + 85, 157, 210, 2, 21, 22, 48, 201, 243, 157, 210, 2, 21, 22, 48, 53, 157, + 210, 2, 21, 22, 48, 210, 2, 21, 22, 48, 52, 186, 21, 22, 48, 52, 206, + 182, 83, 204, 183, 21, 22, 48, 112, 238, 253, 21, 22, 48, 206, 182, 231, + 155, 106, 21, 22, 48, 212, 125, 21, 22, 48, 135, 203, 147, 21, 22, 236, + 230, 21, 22, 226, 86, 21, 22, 214, 119, 21, 22, 251, 106, 21, 22, 213, + 92, 21, 22, 213, 241, 21, 22, 212, 220, 21, 22, 212, 182, 21, 22, 212, + 117, 21, 22, 212, 91, 21, 22, 196, 147, 212, 91, 21, 22, 92, 232, 118, + 21, 22, 92, 232, 71, 21, 22, 161, 21, 22, 213, 243, 21, 22, 211, 183, 21, + 22, 197, 87, 211, 183, 21, 22, 211, 181, 21, 22, 197, 87, 211, 181, 21, + 22, 211, 180, 21, 22, 197, 87, 211, 180, 21, 22, 211, 178, 21, 22, 197, + 87, 211, 178, 21, 22, 211, 177, 21, 22, 197, 87, 211, 177, 21, 22, 211, + 185, 21, 22, 197, 87, 211, 185, 21, 22, 211, 184, 21, 22, 197, 87, 211, + 184, 21, 22, 196, 147, 211, 184, 21, 22, 214, 3, 21, 22, 197, 87, 214, 3, + 21, 22, 92, 233, 15, 21, 22, 203, 68, 21, 22, 203, 160, 21, 22, 202, 122, + 21, 22, 202, 99, 21, 22, 149, 21, 22, 201, 247, 21, 22, 196, 147, 201, + 247, 21, 22, 92, 239, 237, 21, 22, 92, 239, 152, 21, 22, 189, 21, 22, + 203, 162, 21, 22, 200, 243, 21, 22, 197, 87, 200, 243, 21, 22, 200, 221, + 21, 22, 197, 87, 200, 221, 21, 22, 200, 220, 21, 22, 197, 87, 200, 220, + 21, 22, 102, 21, 22, 197, 87, 102, 21, 22, 200, 211, 21, 22, 197, 87, + 200, 211, 21, 22, 200, 245, 21, 22, 197, 87, 200, 245, 21, 22, 200, 244, + 21, 22, 197, 87, 200, 244, 21, 22, 217, 205, 200, 244, 21, 22, 203, 216, + 21, 22, 201, 73, 21, 22, 201, 57, 21, 22, 201, 55, 21, 22, 201, 78, 21, + 22, 224, 209, 21, 22, 225, 49, 21, 22, 224, 101, 21, 22, 224, 80, 21, 22, + 224, 11, 21, 22, 223, 242, 21, 22, 196, 147, 223, 242, 21, 22, 155, 21, + 22, 225, 55, 21, 22, 223, 131, 21, 22, 197, 87, 223, 131, 21, 22, 223, + 129, 21, 22, 197, 87, 223, 129, 21, 22, 223, 128, 21, 22, 197, 87, 223, + 128, 21, 22, 223, 126, 21, 22, 197, 87, 223, 126, 21, 22, 223, 125, 21, + 22, 197, 87, 223, 125, 21, 22, 223, 136, 21, 22, 197, 87, 223, 136, 21, + 22, 223, 135, 21, 22, 197, 87, 223, 135, 21, 22, 217, 205, 223, 135, 21, + 22, 225, 80, 21, 22, 223, 137, 21, 22, 205, 158, 224, 193, 21, 22, 205, + 158, 224, 81, 21, 22, 205, 158, 224, 1, 21, 22, 205, 158, 225, 33, 21, + 22, 247, 57, 21, 22, 247, 172, 21, 22, 245, 11, 21, 22, 245, 1, 21, 22, + 244, 182, 21, 22, 241, 117, 21, 22, 196, 147, 241, 117, 21, 22, 247, 174, + 21, 22, 247, 173, 21, 22, 240, 252, 21, 22, 197, 87, 240, 252, 21, 22, + 240, 250, 21, 22, 197, 87, 240, 250, 21, 22, 240, 249, 21, 22, 197, 87, + 240, 249, 21, 22, 240, 248, 21, 22, 197, 87, 240, 248, 21, 22, 240, 247, + 21, 22, 197, 87, 240, 247, 21, 22, 240, 254, 21, 22, 197, 87, 240, 254, + 21, 22, 240, 253, 21, 22, 197, 87, 240, 253, 21, 22, 217, 205, 240, 253, + 21, 22, 247, 207, 21, 22, 208, 178, 202, 235, 21, 22, 219, 207, 21, 22, + 220, 118, 21, 22, 219, 78, 21, 22, 219, 40, 21, 22, 218, 251, 21, 22, + 218, 195, 21, 22, 196, 147, 218, 195, 21, 22, 166, 21, 22, 220, 119, 21, + 22, 218, 70, 21, 22, 197, 87, 218, 70, 21, 22, 218, 68, 21, 22, 197, 87, + 218, 68, 21, 22, 218, 67, 21, 22, 197, 87, 218, 67, 21, 22, 218, 66, 21, + 22, 197, 87, 218, 66, 21, 22, 218, 65, 21, 22, 197, 87, 218, 65, 21, 22, + 218, 72, 21, 22, 197, 87, 218, 72, 21, 22, 218, 71, 21, 22, 197, 87, 218, + 71, 21, 22, 217, 205, 218, 71, 21, 22, 221, 136, 21, 22, 197, 87, 221, + 136, 21, 22, 219, 82, 21, 22, 250, 166, 221, 136, 21, 22, 208, 178, 221, + 136, 21, 22, 217, 118, 21, 22, 217, 243, 21, 22, 216, 223, 21, 22, 216, + 190, 21, 22, 216, 50, 21, 22, 216, 33, 21, 22, 196, 147, 216, 33, 21, 22, + 176, 21, 22, 217, 244, 21, 22, 215, 116, 21, 22, 197, 87, 215, 116, 21, + 22, 215, 118, 21, 22, 197, 87, 215, 118, 21, 22, 215, 117, 21, 22, 197, + 87, 215, 117, 21, 22, 217, 205, 215, 117, 21, 22, 218, 55, 21, 22, 92, + 217, 73, 21, 22, 216, 228, 21, 22, 222, 197, 21, 22, 223, 81, 21, 22, + 222, 109, 21, 22, 222, 91, 21, 22, 222, 7, 21, 22, 221, 229, 21, 22, 196, + 147, 221, 229, 21, 22, 172, 21, 22, 223, 82, 21, 22, 221, 157, 21, 22, + 197, 87, 221, 157, 21, 22, 221, 156, 21, 22, 197, 87, 221, 156, 21, 22, + 221, 155, 21, 22, 197, 87, 221, 155, 21, 22, 221, 154, 21, 22, 197, 87, + 221, 154, 21, 22, 221, 153, 21, 22, 197, 87, 221, 153, 21, 22, 221, 159, + 21, 22, 197, 87, 221, 159, 21, 22, 221, 158, 21, 22, 197, 87, 221, 158, + 21, 22, 159, 21, 22, 197, 87, 159, 21, 22, 219, 194, 159, 21, 22, 208, + 147, 21, 22, 209, 11, 21, 22, 206, 112, 21, 22, 206, 84, 21, 22, 205, + 200, 21, 22, 205, 171, 21, 22, 196, 147, 205, 171, 21, 22, 183, 21, 22, + 209, 13, 21, 22, 204, 62, 21, 22, 197, 87, 204, 62, 21, 22, 204, 56, 21, + 22, 197, 87, 204, 56, 21, 22, 204, 55, 21, 22, 197, 87, 204, 55, 21, 22, + 204, 50, 21, 22, 197, 87, 204, 50, 21, 22, 204, 49, 21, 22, 197, 87, 204, + 49, 21, 22, 204, 67, 21, 22, 197, 87, 204, 67, 21, 22, 204, 66, 21, 22, + 197, 87, 204, 66, 21, 22, 217, 205, 204, 66, 21, 22, 209, 80, 21, 22, + 250, 166, 209, 80, 21, 22, 204, 68, 21, 22, 248, 133, 209, 80, 21, 22, + 218, 188, 206, 7, 21, 22, 217, 205, 205, 252, 21, 22, 217, 205, 209, 78, + 21, 22, 217, 205, 205, 96, 21, 22, 217, 205, 204, 175, 21, 22, 217, 205, + 205, 251, 21, 22, 217, 205, 208, 150, 21, 22, 206, 255, 21, 22, 206, 223, + 21, 22, 206, 218, 21, 22, 206, 198, 21, 22, 206, 190, 21, 22, 207, 50, + 21, 22, 207, 45, 21, 22, 206, 127, 21, 22, 197, 87, 206, 127, 21, 22, + 206, 126, 21, 22, 197, 87, 206, 126, 21, 22, 206, 125, 21, 22, 197, 87, + 206, 125, 21, 22, 206, 124, 21, 22, 197, 87, 206, 124, 21, 22, 206, 123, + 21, 22, 197, 87, 206, 123, 21, 22, 206, 130, 21, 22, 197, 87, 206, 130, + 21, 22, 206, 129, 21, 22, 197, 87, 206, 129, 21, 22, 207, 52, 21, 22, + 196, 69, 21, 22, 196, 127, 21, 22, 196, 24, 21, 22, 196, 14, 21, 22, 196, + 3, 21, 22, 195, 237, 21, 22, 196, 147, 195, 237, 21, 22, 164, 21, 22, + 196, 129, 21, 22, 195, 173, 21, 22, 197, 87, 195, 173, 21, 22, 195, 172, + 21, 22, 197, 87, 195, 172, 21, 22, 195, 171, 21, 22, 197, 87, 195, 171, + 21, 22, 195, 170, 21, 22, 197, 87, 195, 170, 21, 22, 195, 169, 21, 22, + 197, 87, 195, 169, 21, 22, 195, 175, 21, 22, 197, 87, 195, 175, 21, 22, + 195, 174, 21, 22, 197, 87, 195, 174, 21, 22, 217, 205, 195, 174, 21, 22, + 196, 148, 21, 22, 248, 182, 196, 148, 21, 22, 197, 87, 196, 148, 21, 22, + 208, 178, 196, 24, 21, 22, 210, 183, 21, 22, 211, 31, 210, 183, 21, 22, + 197, 87, 222, 197, 21, 22, 210, 243, 21, 22, 210, 72, 21, 22, 210, 9, 21, + 22, 209, 232, 21, 22, 209, 206, 21, 22, 197, 87, 222, 7, 21, 22, 169, 21, + 22, 210, 244, 21, 22, 197, 87, 172, 21, 22, 209, 97, 21, 22, 197, 87, + 209, 97, 21, 22, 144, 21, 22, 197, 87, 144, 21, 22, 219, 194, 144, 21, + 22, 235, 189, 21, 22, 235, 236, 21, 22, 235, 153, 21, 22, 235, 139, 21, + 22, 235, 51, 21, 22, 235, 40, 21, 22, 235, 239, 21, 22, 235, 238, 21, 22, + 234, 200, 21, 22, 197, 87, 234, 200, 21, 22, 236, 49, 21, 22, 202, 217, + 21, 22, 218, 53, 202, 217, 21, 22, 202, 195, 21, 22, 218, 53, 202, 195, + 21, 22, 202, 189, 21, 22, 218, 53, 202, 189, 21, 22, 202, 169, 21, 22, + 202, 164, 21, 22, 202, 233, 21, 22, 202, 232, 21, 22, 202, 132, 21, 22, + 197, 87, 202, 132, 21, 22, 202, 235, 21, 22, 201, 64, 21, 22, 201, 62, + 21, 22, 201, 61, 21, 22, 201, 66, 21, 22, 201, 67, 21, 22, 200, 204, 21, + 22, 200, 203, 21, 22, 200, 202, 21, 22, 200, 206, 21, 22, 215, 137, 232, + 147, 21, 22, 215, 137, 232, 71, 21, 22, 215, 137, 232, 43, 21, 22, 215, + 137, 231, 193, 21, 22, 215, 137, 231, 166, 21, 22, 215, 137, 142, 21, 22, + 215, 137, 232, 246, 21, 22, 215, 137, 233, 15, 21, 22, 215, 136, 233, 15, + 21, 22, 232, 27, 21, 22, 211, 155, 21, 22, 211, 121, 21, 22, 211, 115, + 21, 22, 211, 109, 21, 22, 211, 104, 21, 22, 211, 159, 21, 22, 211, 158, + 21, 22, 211, 167, 21, 22, 202, 43, 21, 22, 202, 41, 21, 22, 202, 40, 21, + 22, 202, 44, 21, 22, 197, 87, 210, 183, 21, 22, 197, 87, 210, 72, 21, 22, + 197, 87, 209, 232, 21, 22, 197, 87, 169, 21, 22, 217, 69, 21, 22, 217, + 19, 21, 22, 217, 15, 21, 22, 216, 252, 21, 22, 216, 247, 21, 22, 217, 71, + 21, 22, 217, 70, 21, 22, 217, 73, 21, 22, 216, 79, 21, 22, 208, 178, 206, + 255, 21, 22, 208, 178, 206, 223, 21, 22, 208, 178, 206, 198, 21, 22, 208, + 178, 207, 50, 21, 22, 197, 13, 202, 217, 21, 22, 197, 13, 202, 195, 21, + 22, 197, 13, 202, 169, 21, 22, 197, 13, 202, 233, 21, 22, 197, 13, 202, + 235, 21, 22, 222, 116, 21, 22, 222, 115, 21, 22, 222, 114, 21, 22, 222, + 113, 21, 22, 222, 122, 21, 22, 222, 121, 21, 22, 222, 123, 21, 22, 202, + 234, 202, 217, 21, 22, 202, 234, 202, 195, 21, 22, 202, 234, 202, 189, + 21, 22, 202, 234, 202, 169, 21, 22, 202, 234, 202, 164, 21, 22, 202, 234, + 202, 233, 21, 22, 202, 234, 202, 232, 21, 22, 202, 234, 202, 235, 21, 22, + 251, 184, 250, 112, 21, 22, 248, 133, 69, 21, 22, 248, 133, 68, 21, 22, + 248, 133, 72, 21, 22, 248, 133, 63, 21, 22, 248, 133, 197, 109, 21, 22, + 248, 133, 197, 70, 21, 22, 248, 133, 197, 34, 21, 22, 248, 133, 197, 166, + 21, 22, 248, 133, 217, 118, 21, 22, 248, 133, 216, 223, 21, 22, 248, 133, + 216, 50, 21, 22, 248, 133, 176, 21, 22, 248, 133, 224, 209, 21, 22, 248, + 133, 224, 101, 21, 22, 248, 133, 224, 11, 21, 22, 248, 133, 155, 21, 22, + 208, 178, 232, 147, 21, 22, 208, 178, 232, 71, 21, 22, 208, 178, 231, + 193, 21, 22, 208, 178, 142, 21, 22, 92, 233, 198, 21, 22, 92, 233, 202, + 21, 22, 92, 233, 216, 21, 22, 92, 233, 215, 21, 22, 92, 233, 204, 21, 22, + 92, 233, 230, 21, 22, 92, 209, 140, 21, 22, 92, 209, 232, 21, 22, 92, + 210, 183, 21, 22, 92, 210, 155, 21, 22, 92, 210, 72, 21, 22, 92, 169, 21, + 22, 92, 196, 243, 21, 22, 92, 197, 34, 21, 22, 92, 197, 109, 21, 22, 92, + 197, 98, 21, 22, 92, 197, 70, 21, 22, 92, 197, 166, 21, 22, 92, 231, 36, + 21, 22, 92, 231, 37, 21, 22, 92, 231, 40, 21, 22, 92, 231, 39, 21, 22, + 92, 231, 38, 21, 22, 92, 231, 43, 21, 22, 92, 202, 142, 21, 22, 92, 202, + 169, 21, 22, 92, 202, 217, 21, 22, 92, 202, 215, 21, 22, 92, 202, 195, + 21, 22, 92, 202, 233, 21, 22, 92, 201, 45, 21, 22, 92, 201, 55, 21, 22, + 92, 201, 73, 21, 22, 92, 201, 72, 21, 22, 92, 201, 57, 21, 22, 92, 201, + 78, 21, 22, 92, 211, 227, 21, 22, 92, 212, 117, 21, 22, 92, 213, 92, 21, + 22, 92, 213, 79, 21, 22, 92, 212, 220, 21, 22, 92, 161, 21, 22, 92, 214, + 3, 21, 22, 92, 233, 76, 21, 22, 92, 233, 144, 21, 22, 92, 234, 48, 21, + 22, 92, 234, 40, 21, 22, 92, 233, 192, 21, 22, 92, 234, 123, 21, 22, 92, + 224, 110, 21, 22, 92, 224, 117, 21, 22, 92, 224, 131, 21, 22, 92, 224, + 130, 21, 22, 92, 224, 124, 21, 22, 92, 224, 146, 21, 22, 92, 224, 31, 21, + 22, 92, 224, 32, 21, 22, 92, 224, 35, 21, 22, 92, 224, 34, 21, 22, 92, + 224, 33, 21, 22, 92, 224, 36, 21, 22, 92, 224, 37, 21, 22, 92, 215, 186, + 21, 22, 92, 216, 50, 21, 22, 92, 217, 118, 21, 22, 92, 217, 107, 21, 22, + 92, 216, 223, 21, 22, 92, 176, 21, 22, 92, 218, 145, 21, 22, 92, 218, + 251, 21, 22, 92, 219, 207, 21, 22, 92, 219, 188, 21, 22, 92, 219, 78, 21, + 22, 92, 166, 21, 22, 92, 195, 217, 21, 22, 92, 196, 3, 21, 22, 92, 196, + 69, 21, 22, 92, 196, 66, 21, 22, 92, 196, 24, 21, 22, 92, 164, 21, 22, + 92, 225, 110, 21, 22, 208, 178, 225, 110, 21, 22, 92, 225, 129, 21, 22, + 92, 225, 193, 21, 22, 92, 225, 191, 21, 22, 92, 225, 172, 21, 22, 208, + 178, 225, 172, 21, 22, 92, 225, 214, 21, 22, 92, 225, 143, 21, 22, 92, + 225, 147, 21, 22, 92, 225, 157, 21, 22, 92, 225, 156, 21, 22, 92, 225, + 155, 21, 22, 92, 225, 158, 21, 22, 92, 221, 191, 21, 22, 92, 222, 7, 21, + 22, 92, 222, 197, 21, 22, 92, 222, 188, 21, 22, 92, 222, 109, 21, 22, 92, + 172, 21, 22, 92, 239, 33, 21, 22, 92, 239, 34, 21, 22, 92, 239, 39, 21, + 22, 92, 239, 38, 21, 22, 92, 239, 35, 21, 22, 92, 239, 40, 21, 22, 92, + 222, 112, 21, 22, 92, 222, 114, 21, 22, 92, 222, 118, 21, 22, 92, 222, + 117, 21, 22, 92, 222, 116, 21, 22, 92, 222, 122, 21, 22, 92, 202, 38, 21, + 22, 92, 202, 40, 21, 22, 92, 202, 43, 21, 22, 92, 202, 42, 21, 22, 92, + 202, 41, 21, 22, 92, 202, 44, 21, 22, 92, 202, 33, 21, 22, 92, 202, 34, + 21, 22, 92, 202, 46, 21, 22, 92, 202, 45, 21, 22, 92, 202, 35, 21, 22, + 92, 202, 47, 21, 22, 92, 194, 255, 21, 22, 92, 195, 11, 21, 22, 92, 195, + 88, 21, 22, 92, 195, 85, 21, 22, 92, 195, 33, 21, 22, 92, 195, 115, 21, + 22, 92, 195, 158, 21, 22, 92, 84, 195, 158, 21, 22, 92, 237, 143, 21, 22, + 92, 237, 144, 21, 22, 92, 237, 153, 21, 22, 92, 237, 152, 21, 22, 92, + 237, 147, 21, 22, 92, 237, 156, 21, 22, 92, 204, 172, 21, 22, 92, 205, + 200, 21, 22, 92, 208, 147, 21, 22, 92, 208, 129, 21, 22, 92, 206, 112, + 21, 22, 92, 183, 21, 22, 92, 206, 151, 21, 22, 92, 206, 198, 21, 22, 92, + 206, 255, 21, 22, 92, 206, 253, 21, 22, 92, 206, 223, 21, 22, 92, 207, + 50, 21, 22, 92, 207, 52, 21, 22, 92, 201, 86, 21, 22, 92, 201, 90, 21, + 22, 92, 201, 107, 21, 22, 92, 201, 106, 21, 22, 92, 201, 92, 21, 22, 92, + 201, 113, 21, 22, 92, 245, 30, 21, 22, 92, 245, 49, 21, 22, 92, 245, 103, + 21, 22, 92, 245, 99, 21, 22, 92, 245, 75, 21, 22, 92, 247, 16, 21, 22, + 92, 201, 48, 21, 22, 92, 201, 49, 21, 22, 92, 201, 52, 21, 22, 92, 201, + 51, 21, 22, 92, 201, 50, 21, 22, 92, 201, 53, 21, 22, 245, 76, 55, 21, + 22, 234, 217, 204, 226, 21, 22, 211, 151, 21, 22, 217, 67, 21, 22, 216, + 76, 21, 22, 216, 75, 21, 22, 216, 74, 21, 22, 216, 73, 21, 22, 216, 78, + 21, 22, 216, 77, 21, 22, 197, 13, 202, 130, 21, 22, 197, 13, 202, 129, + 21, 22, 197, 13, 202, 128, 21, 22, 197, 13, 202, 127, 21, 22, 197, 13, + 202, 126, 21, 22, 197, 13, 202, 133, 21, 22, 197, 13, 202, 132, 21, 22, + 197, 13, 48, 202, 235, 21, 22, 248, 133, 197, 199, 214, 153, 205, 149, + 78, 214, 153, 1, 248, 233, 214, 153, 1, 221, 177, 214, 153, 1, 235, 186, + 214, 153, 1, 208, 251, 214, 153, 1, 216, 172, 214, 153, 1, 200, 111, 214, + 153, 1, 240, 109, 214, 153, 1, 202, 71, 214, 153, 1, 244, 171, 214, 153, + 1, 247, 44, 214, 153, 1, 218, 128, 214, 153, 1, 233, 123, 214, 153, 1, + 217, 57, 214, 153, 1, 204, 219, 214, 153, 1, 209, 127, 214, 153, 1, 251, + 196, 214, 153, 1, 214, 106, 214, 153, 1, 200, 21, 214, 153, 1, 237, 80, + 214, 153, 1, 226, 11, 214, 153, 1, 237, 81, 214, 153, 1, 214, 72, 214, + 153, 1, 200, 88, 214, 153, 1, 226, 126, 214, 153, 1, 237, 78, 214, 153, + 1, 213, 69, 214, 153, 235, 185, 78, 214, 153, 210, 89, 235, 185, 78, 209, + 116, 1, 235, 175, 235, 166, 235, 190, 236, 49, 209, 116, 1, 199, 230, + 209, 116, 1, 200, 6, 200, 22, 66, 209, 116, 1, 195, 220, 209, 116, 1, + 196, 148, 209, 116, 1, 197, 199, 209, 116, 1, 202, 135, 202, 134, 202, + 162, 209, 116, 1, 236, 121, 209, 116, 1, 251, 70, 63, 209, 116, 1, 214, + 54, 72, 209, 116, 1, 252, 26, 63, 209, 116, 1, 251, 229, 209, 116, 1, + 221, 236, 72, 209, 116, 1, 206, 175, 72, 209, 116, 1, 72, 209, 116, 1, + 214, 164, 209, 116, 1, 214, 119, 209, 116, 1, 210, 222, 210, 235, 210, + 140, 144, 209, 116, 1, 224, 225, 209, 116, 1, 247, 40, 209, 116, 1, 224, + 226, 225, 80, 209, 116, 1, 234, 190, 209, 116, 1, 236, 215, 209, 116, 1, + 234, 43, 233, 21, 234, 190, 209, 116, 1, 234, 83, 209, 116, 1, 196, 235, + 196, 226, 197, 199, 209, 116, 1, 232, 237, 233, 15, 209, 116, 1, 232, + 241, 233, 15, 209, 116, 1, 221, 238, 233, 15, 209, 116, 1, 206, 178, 233, + 15, 209, 116, 1, 217, 200, 215, 99, 217, 201, 218, 55, 209, 116, 1, 206, + 176, 218, 55, 209, 116, 1, 237, 247, 209, 116, 1, 225, 245, 225, 249, + 225, 236, 68, 209, 116, 1, 69, 209, 116, 1, 225, 183, 225, 217, 209, 116, + 1, 234, 24, 209, 116, 1, 221, 239, 251, 245, 209, 116, 1, 206, 180, 63, + 209, 116, 1, 225, 228, 236, 188, 209, 116, 1, 213, 25, 213, 50, 214, 3, + 209, 116, 1, 251, 157, 236, 186, 209, 116, 1, 205, 155, 209, 80, 209, + 116, 1, 206, 88, 221, 235, 209, 80, 209, 116, 1, 206, 174, 209, 80, 209, + 116, 1, 247, 207, 209, 116, 1, 195, 158, 209, 116, 1, 202, 52, 202, 64, + 200, 188, 203, 216, 209, 116, 1, 206, 173, 203, 216, 209, 116, 1, 240, + 231, 209, 116, 1, 248, 211, 248, 214, 248, 139, 250, 112, 209, 116, 1, + 206, 179, 250, 112, 209, 116, 1, 237, 246, 209, 116, 1, 214, 86, 209, + 116, 1, 237, 34, 237, 41, 69, 209, 116, 1, 220, 51, 220, 63, 221, 136, + 209, 116, 1, 221, 237, 221, 136, 209, 116, 1, 206, 177, 221, 136, 209, + 116, 1, 222, 212, 223, 59, 221, 246, 159, 209, 116, 1, 237, 248, 209, + 116, 1, 226, 59, 209, 116, 1, 226, 60, 209, 116, 1, 240, 123, 240, 129, + 240, 231, 209, 116, 1, 214, 47, 236, 120, 72, 209, 116, 1, 237, 76, 209, + 116, 1, 226, 9, 209, 116, 1, 240, 251, 209, 116, 1, 247, 157, 209, 116, + 1, 247, 56, 209, 116, 1, 205, 13, 209, 116, 1, 221, 234, 209, 116, 1, + 206, 172, 209, 116, 1, 230, 200, 209, 116, 1, 211, 167, 209, 116, 1, 196, + 222, 209, 116, 206, 62, 211, 213, 209, 116, 218, 120, 211, 213, 209, 116, + 241, 62, 211, 213, 209, 116, 250, 233, 105, 209, 116, 200, 247, 105, 209, + 116, 248, 231, 105, 209, 116, 1, 225, 80, 209, 116, 1, 207, 52, 209, 116, + 1, 214, 102, 209, 116, 1, 234, 247, 247, 95, 214, 53, 209, 116, 1, 234, + 247, 247, 95, 225, 248, 209, 116, 1, 234, 247, 247, 95, 237, 40, 209, + 116, 1, 234, 247, 247, 95, 252, 25, 209, 116, 1, 234, 247, 247, 95, 251, + 229, 203, 142, 1, 63, 203, 142, 1, 68, 203, 142, 1, 66, 203, 142, 1, 155, + 203, 142, 1, 234, 123, 203, 142, 1, 217, 71, 203, 142, 1, 189, 203, 142, + 1, 240, 136, 203, 142, 1, 176, 203, 142, 1, 161, 203, 142, 1, 249, 145, + 203, 142, 1, 166, 203, 142, 1, 164, 203, 142, 1, 172, 203, 142, 1, 197, + 166, 203, 142, 1, 183, 203, 142, 1, 142, 203, 142, 18, 2, 68, 203, 142, + 18, 2, 66, 203, 142, 2, 199, 7, 232, 179, 1, 63, 232, 179, 1, 68, 232, + 179, 1, 66, 232, 179, 1, 155, 232, 179, 1, 234, 123, 232, 179, 1, 217, + 71, 232, 179, 1, 189, 232, 179, 1, 240, 136, 232, 179, 1, 176, 232, 179, + 1, 161, 232, 179, 1, 249, 145, 232, 179, 1, 166, 232, 179, 1, 164, 232, + 179, 1, 169, 232, 179, 1, 172, 232, 179, 1, 197, 166, 232, 179, 1, 183, + 232, 179, 1, 142, 232, 179, 18, 2, 68, 232, 179, 18, 2, 66, 232, 179, 2, + 213, 194, 212, 239, 206, 62, 211, 213, 212, 239, 52, 211, 213, 248, 13, + 1, 63, 248, 13, 1, 68, 248, 13, 1, 66, 248, 13, 1, 155, 248, 13, 1, 234, + 123, 248, 13, 1, 217, 71, 248, 13, 1, 189, 248, 13, 1, 240, 136, 248, 13, + 1, 176, 248, 13, 1, 161, 248, 13, 1, 249, 145, 248, 13, 1, 166, 248, 13, + 1, 164, 248, 13, 1, 169, 248, 13, 1, 172, 248, 13, 1, 197, 166, 248, 13, + 1, 183, 248, 13, 1, 142, 248, 13, 18, 2, 68, 248, 13, 18, 2, 66, 203, + 141, 1, 63, 203, 141, 1, 68, 203, 141, 1, 66, 203, 141, 1, 155, 203, 141, + 1, 234, 123, 203, 141, 1, 217, 71, 203, 141, 1, 189, 203, 141, 1, 240, + 136, 203, 141, 1, 176, 203, 141, 1, 161, 203, 141, 1, 249, 145, 203, 141, + 1, 166, 203, 141, 1, 164, 203, 141, 1, 172, 203, 141, 1, 197, 166, 203, + 141, 1, 183, 203, 141, 18, 2, 68, 203, 141, 18, 2, 66, 89, 1, 155, 89, 1, + 224, 146, 89, 1, 224, 11, 89, 1, 224, 117, 89, 1, 216, 252, 89, 1, 247, + 174, 89, 1, 247, 16, 89, 1, 244, 182, 89, 1, 245, 49, 89, 1, 215, 73, 89, + 1, 240, 136, 89, 1, 201, 66, 89, 1, 239, 28, 89, 1, 201, 61, 89, 1, 216, + 56, 89, 1, 189, 89, 1, 202, 233, 89, 1, 149, 89, 1, 202, 169, 89, 1, 216, + 50, 89, 1, 249, 145, 89, 1, 213, 6, 89, 1, 212, 117, 89, 1, 212, 234, 89, + 1, 218, 251, 89, 1, 196, 3, 89, 1, 209, 232, 89, 1, 222, 7, 89, 1, 198, + 248, 89, 1, 207, 50, 89, 1, 205, 39, 89, 1, 183, 89, 1, 142, 89, 1, 172, + 89, 1, 211, 159, 89, 226, 73, 18, 211, 145, 89, 226, 73, 18, 211, 158, + 89, 226, 73, 18, 211, 121, 89, 226, 73, 18, 211, 115, 89, 226, 73, 18, + 211, 97, 89, 226, 73, 18, 211, 66, 89, 226, 73, 18, 211, 54, 89, 226, 73, + 18, 211, 53, 89, 226, 73, 18, 209, 89, 89, 226, 73, 18, 209, 82, 89, 226, + 73, 18, 221, 151, 89, 226, 73, 18, 221, 139, 89, 226, 73, 18, 211, 139, + 89, 226, 73, 18, 211, 151, 89, 226, 73, 18, 211, 105, 200, 201, 100, 89, + 226, 73, 18, 211, 105, 200, 201, 102, 89, 226, 73, 18, 211, 141, 89, 18, + 226, 57, 251, 18, 89, 18, 226, 57, 252, 168, 89, 18, 2, 252, 168, 89, 18, + 2, 68, 89, 18, 2, 226, 120, 89, 18, 2, 196, 148, 89, 18, 2, 195, 168, 89, + 18, 2, 66, 89, 18, 2, 199, 245, 89, 18, 2, 200, 114, 89, 18, 2, 214, 164, + 89, 18, 2, 164, 89, 18, 2, 226, 147, 89, 18, 2, 69, 89, 18, 2, 251, 245, + 89, 18, 2, 251, 200, 89, 18, 2, 214, 102, 89, 18, 2, 250, 150, 89, 2, + 216, 188, 89, 2, 210, 177, 89, 2, 195, 179, 89, 2, 218, 83, 89, 2, 201, + 168, 89, 2, 249, 82, 89, 2, 209, 221, 89, 2, 202, 21, 89, 2, 225, 24, 89, + 2, 251, 202, 89, 2, 208, 220, 208, 212, 89, 2, 199, 4, 89, 2, 244, 174, + 89, 2, 249, 52, 89, 2, 224, 138, 89, 2, 249, 77, 89, 2, 247, 145, 212, + 183, 223, 143, 89, 2, 222, 165, 201, 247, 89, 2, 248, 199, 89, 2, 212, + 236, 218, 138, 89, 2, 223, 240, 89, 241, 17, 16, 210, 56, 89, 2, 250, + 131, 89, 2, 250, 153, 89, 17, 195, 79, 89, 17, 100, 89, 17, 102, 89, 17, + 134, 89, 17, 136, 89, 17, 146, 89, 17, 167, 89, 17, 178, 89, 17, 171, 89, + 17, 182, 89, 16, 222, 165, 250, 155, 205, 174, 89, 16, 222, 165, 250, + 155, 218, 104, 89, 16, 222, 165, 250, 155, 212, 182, 89, 16, 222, 165, + 250, 155, 248, 234, 89, 16, 222, 165, 250, 155, 247, 249, 89, 16, 222, + 165, 250, 155, 212, 49, 89, 16, 222, 165, 250, 155, 212, 43, 89, 16, 222, + 165, 250, 155, 212, 41, 89, 16, 222, 165, 250, 155, 212, 47, 89, 16, 222, + 165, 250, 155, 212, 45, 96, 248, 154, 96, 236, 247, 96, 244, 159, 96, + 234, 217, 204, 226, 96, 244, 168, 96, 235, 7, 238, 250, 96, 202, 20, 205, + 186, 231, 7, 96, 206, 104, 5, 248, 81, 220, 24, 96, 220, 59, 244, 159, + 96, 220, 59, 234, 217, 204, 226, 96, 216, 170, 96, 234, 246, 62, 208, + 115, 100, 96, 234, 246, 62, 208, 115, 102, 96, 234, 246, 62, 208, 115, + 134, 96, 18, 207, 90, 96, 17, 195, 79, 96, 17, 100, 96, 17, 102, 96, 17, + 134, 96, 17, 136, 96, 17, 146, 96, 17, 167, 96, 17, 178, 96, 17, 171, 96, + 17, 182, 96, 1, 63, 96, 1, 69, 96, 1, 68, 96, 1, 72, 96, 1, 66, 96, 1, + 214, 164, 96, 1, 200, 99, 96, 1, 237, 54, 96, 1, 176, 96, 1, 251, 97, 96, + 1, 249, 145, 96, 1, 161, 96, 1, 211, 159, 96, 1, 234, 123, 96, 1, 166, + 96, 1, 172, 96, 1, 183, 96, 1, 207, 50, 96, 1, 189, 96, 1, 240, 136, 96, + 1, 247, 16, 96, 1, 225, 214, 96, 1, 164, 96, 1, 169, 96, 1, 197, 166, 96, + 1, 235, 239, 96, 1, 155, 96, 1, 224, 146, 96, 1, 201, 113, 96, 1, 195, + 115, 96, 1, 232, 246, 96, 1, 195, 3, 96, 1, 222, 122, 96, 1, 195, 60, 96, + 1, 245, 75, 96, 1, 202, 20, 181, 18, 55, 96, 1, 202, 20, 69, 96, 1, 202, + 20, 68, 96, 1, 202, 20, 72, 96, 1, 202, 20, 66, 96, 1, 202, 20, 214, 164, + 96, 1, 202, 20, 200, 99, 96, 1, 202, 20, 251, 97, 96, 1, 202, 20, 249, + 145, 96, 1, 202, 20, 161, 96, 1, 202, 20, 211, 159, 96, 1, 202, 20, 234, + 123, 96, 1, 202, 20, 166, 96, 1, 202, 20, 189, 96, 1, 202, 20, 240, 136, + 96, 1, 202, 20, 247, 16, 96, 1, 202, 20, 225, 214, 96, 1, 202, 20, 201, + 113, 96, 1, 202, 20, 164, 96, 1, 202, 20, 197, 166, 96, 1, 202, 20, 155, + 96, 1, 202, 20, 234, 120, 96, 1, 202, 20, 232, 246, 96, 1, 202, 20, 225, + 171, 96, 1, 202, 20, 216, 213, 96, 1, 202, 20, 237, 156, 96, 1, 206, 104, + 69, 96, 1, 206, 104, 68, 96, 1, 206, 104, 225, 225, 96, 1, 206, 104, 200, + 99, 96, 1, 206, 104, 66, 96, 1, 206, 104, 251, 97, 96, 1, 206, 104, 155, + 96, 1, 206, 104, 234, 123, 96, 1, 206, 104, 142, 96, 1, 206, 104, 161, + 96, 1, 206, 104, 207, 50, 96, 1, 206, 104, 189, 96, 1, 206, 104, 240, + 136, 96, 1, 206, 104, 225, 214, 96, 1, 206, 104, 235, 239, 96, 1, 206, + 104, 234, 120, 96, 1, 206, 104, 232, 246, 96, 1, 206, 104, 201, 113, 96, + 1, 206, 104, 195, 115, 96, 1, 206, 104, 210, 244, 96, 1, 206, 104, 247, + 16, 96, 1, 206, 104, 195, 74, 96, 1, 220, 59, 68, 96, 1, 220, 59, 155, + 96, 1, 220, 59, 169, 96, 1, 220, 59, 235, 239, 96, 1, 220, 59, 195, 74, + 96, 1, 247, 17, 3, 99, 238, 250, 96, 1, 251, 156, 234, 103, 251, 52, 100, + 96, 1, 251, 156, 234, 103, 199, 3, 100, 96, 1, 251, 156, 234, 103, 240, + 97, 96, 1, 251, 156, 234, 103, 200, 109, 96, 1, 251, 156, 234, 103, 226, + 17, 200, 109, 96, 1, 251, 156, 234, 103, 249, 96, 96, 1, 251, 156, 234, + 103, 115, 249, 96, 96, 1, 251, 156, 234, 103, 63, 96, 1, 251, 156, 234, + 103, 68, 96, 1, 251, 156, 234, 103, 155, 96, 1, 251, 156, 234, 103, 217, + 71, 96, 1, 251, 156, 234, 103, 247, 174, 96, 1, 251, 156, 234, 103, 201, + 78, 96, 1, 251, 156, 234, 103, 201, 66, 96, 1, 251, 156, 234, 103, 240, + 41, 96, 1, 251, 156, 234, 103, 216, 86, 96, 1, 251, 156, 234, 103, 189, + 96, 1, 251, 156, 234, 103, 240, 136, 96, 1, 251, 156, 234, 103, 161, 96, + 1, 251, 156, 234, 103, 213, 6, 96, 1, 251, 156, 234, 103, 205, 80, 96, 1, + 251, 156, 234, 103, 195, 74, 96, 1, 251, 156, 234, 103, 195, 115, 96, 1, + 251, 156, 234, 103, 251, 209, 96, 1, 202, 20, 251, 156, 234, 103, 189, + 96, 1, 202, 20, 251, 156, 234, 103, 195, 74, 96, 1, 220, 59, 251, 156, + 234, 103, 233, 230, 96, 1, 220, 59, 251, 156, 234, 103, 217, 71, 96, 1, + 220, 59, 251, 156, 234, 103, 247, 174, 96, 1, 220, 59, 251, 156, 234, + 103, 225, 180, 96, 1, 220, 59, 251, 156, 234, 103, 201, 78, 96, 1, 220, + 59, 251, 156, 234, 103, 240, 25, 96, 1, 220, 59, 251, 156, 234, 103, 189, + 96, 1, 220, 59, 251, 156, 234, 103, 239, 176, 96, 1, 220, 59, 251, 156, + 234, 103, 205, 80, 96, 1, 220, 59, 251, 156, 234, 103, 240, 245, 96, 1, + 220, 59, 251, 156, 234, 103, 195, 74, 96, 1, 220, 59, 251, 156, 234, 103, + 195, 115, 96, 1, 251, 156, 234, 103, 157, 66, 96, 1, 251, 156, 234, 103, + 157, 164, 96, 1, 220, 59, 251, 156, 234, 103, 248, 197, 96, 1, 251, 156, + 234, 103, 240, 124, 96, 1, 220, 59, 251, 156, 234, 103, 222, 122, 21, 22, + 214, 8, 21, 22, 250, 122, 21, 22, 252, 122, 21, 22, 197, 112, 21, 22, + 212, 55, 21, 22, 213, 101, 21, 22, 211, 176, 21, 22, 203, 77, 21, 22, + 224, 216, 21, 22, 223, 133, 21, 22, 219, 251, 21, 22, 216, 1, 21, 22, + 217, 195, 21, 22, 222, 207, 21, 22, 205, 153, 21, 22, 208, 180, 21, 22, + 206, 160, 21, 22, 207, 3, 21, 22, 206, 122, 21, 22, 195, 226, 21, 22, + 196, 75, 21, 22, 210, 191, 21, 22, 215, 115, 21, 22, 214, 141, 215, 115, + 21, 22, 215, 114, 21, 22, 214, 141, 215, 114, 21, 22, 215, 113, 21, 22, + 214, 141, 215, 113, 21, 22, 215, 112, 21, 22, 214, 141, 215, 112, 21, 22, + 209, 94, 21, 22, 209, 93, 21, 22, 209, 92, 21, 22, 209, 91, 21, 22, 209, + 90, 21, 22, 209, 98, 21, 22, 214, 141, 214, 3, 21, 22, 214, 141, 203, + 216, 21, 22, 214, 141, 225, 80, 21, 22, 214, 141, 247, 207, 21, 22, 214, + 141, 221, 136, 21, 22, 214, 141, 218, 55, 21, 22, 214, 141, 209, 80, 21, + 22, 214, 141, 207, 52, 21, 22, 237, 67, 197, 199, 21, 22, 197, 86, 197, + 199, 21, 22, 48, 4, 210, 2, 21, 22, 48, 210, 215, 238, 253, 21, 22, 211, + 31, 209, 95, 21, 22, 197, 87, 221, 229, 21, 22, 197, 87, 223, 82, 21, 22, + 202, 131, 21, 22, 202, 133, 21, 22, 201, 58, 21, 22, 201, 60, 21, 22, + 201, 65, 21, 22, 202, 37, 21, 22, 202, 39, 21, 22, 208, 178, 206, 127, + 21, 22, 208, 178, 206, 190, 21, 22, 208, 178, 231, 166, 21, 22, 92, 233, + 29, 21, 22, 92, 239, 210, 234, 40, 21, 22, 92, 234, 120, 21, 22, 92, 233, + 34, 21, 22, 208, 178, 225, 90, 21, 22, 92, 225, 88, 21, 22, 248, 254, + 239, 210, 159, 21, 22, 248, 254, 239, 210, 144, 21, 22, 92, 239, 205, + 209, 80, 222, 85, 198, 226, 222, 135, 222, 85, 1, 155, 222, 85, 1, 224, + 146, 222, 85, 1, 234, 123, 222, 85, 1, 233, 230, 222, 85, 1, 217, 71, + 222, 85, 1, 247, 174, 222, 85, 1, 247, 16, 222, 85, 1, 225, 214, 222, 85, + 1, 225, 180, 222, 85, 1, 196, 97, 222, 85, 1, 189, 222, 85, 1, 202, 233, + 222, 85, 1, 240, 136, 222, 85, 1, 239, 176, 222, 85, 1, 176, 222, 85, 1, + 161, 222, 85, 1, 213, 6, 222, 85, 1, 249, 145, 222, 85, 1, 248, 197, 222, + 85, 1, 166, 222, 85, 1, 164, 222, 85, 1, 169, 222, 85, 1, 172, 222, 85, + 1, 197, 166, 222, 85, 1, 207, 50, 222, 85, 1, 205, 80, 222, 85, 1, 183, + 222, 85, 1, 142, 222, 85, 1, 233, 25, 222, 85, 1, 201, 217, 222, 85, 18, + 2, 63, 222, 85, 18, 2, 68, 222, 85, 18, 2, 66, 222, 85, 18, 2, 237, 54, + 222, 85, 18, 2, 251, 200, 222, 85, 18, 2, 214, 102, 222, 85, 18, 2, 250, + 150, 222, 85, 18, 2, 69, 222, 85, 18, 2, 72, 222, 85, 204, 152, 1, 164, + 222, 85, 204, 152, 1, 169, 222, 85, 204, 152, 1, 197, 166, 222, 85, 4, 1, + 155, 222, 85, 4, 1, 217, 71, 222, 85, 4, 1, 251, 51, 222, 85, 4, 1, 189, + 222, 85, 4, 1, 176, 222, 85, 4, 1, 161, 222, 85, 4, 1, 166, 222, 85, 4, + 1, 169, 222, 85, 4, 1, 172, 222, 85, 2, 218, 125, 222, 85, 2, 224, 188, + 222, 85, 2, 209, 14, 222, 85, 2, 221, 229, 222, 85, 236, 90, 78, 222, 85, + 211, 79, 78, 222, 85, 17, 195, 79, 222, 85, 17, 100, 222, 85, 17, 102, + 222, 85, 17, 134, 222, 85, 17, 136, 222, 85, 17, 146, 222, 85, 17, 167, + 222, 85, 17, 178, 222, 85, 17, 171, 222, 85, 17, 182, 49, 222, 198, 1, + 155, 49, 222, 198, 1, 196, 208, 49, 222, 198, 1, 217, 71, 49, 222, 198, + 1, 201, 113, 49, 222, 198, 1, 183, 49, 222, 198, 1, 164, 49, 222, 198, 1, + 189, 49, 222, 198, 1, 202, 233, 49, 222, 198, 1, 172, 49, 222, 198, 1, + 161, 49, 222, 198, 1, 213, 6, 49, 222, 198, 1, 166, 49, 222, 198, 1, 235, + 239, 49, 222, 198, 1, 199, 152, 49, 222, 198, 1, 142, 49, 222, 198, 1, + 211, 159, 49, 222, 198, 1, 224, 146, 49, 222, 198, 1, 201, 103, 49, 222, + 198, 1, 176, 49, 222, 198, 1, 63, 49, 222, 198, 1, 68, 49, 222, 198, 1, + 237, 54, 49, 222, 198, 1, 237, 40, 49, 222, 198, 1, 66, 49, 222, 198, 1, + 214, 102, 49, 222, 198, 1, 72, 49, 222, 198, 1, 200, 99, 49, 222, 198, 1, + 69, 49, 222, 198, 1, 250, 148, 49, 222, 198, 1, 251, 200, 49, 222, 198, + 1, 202, 9, 49, 222, 198, 1, 202, 8, 49, 222, 198, 1, 202, 7, 49, 222, + 198, 1, 202, 6, 49, 222, 198, 1, 202, 5, 217, 83, 49, 221, 185, 1, 130, + 211, 159, 217, 83, 49, 221, 185, 1, 126, 211, 159, 217, 83, 49, 221, 185, + 1, 130, 155, 217, 83, 49, 221, 185, 1, 130, 196, 208, 217, 83, 49, 221, + 185, 1, 130, 217, 71, 217, 83, 49, 221, 185, 1, 126, 155, 217, 83, 49, + 221, 185, 1, 126, 196, 208, 217, 83, 49, 221, 185, 1, 126, 217, 71, 217, + 83, 49, 221, 185, 1, 130, 201, 113, 217, 83, 49, 221, 185, 1, 130, 183, + 217, 83, 49, 221, 185, 1, 130, 164, 217, 83, 49, 221, 185, 1, 126, 201, + 113, 217, 83, 49, 221, 185, 1, 126, 183, 217, 83, 49, 221, 185, 1, 126, + 164, 217, 83, 49, 221, 185, 1, 130, 189, 217, 83, 49, 221, 185, 1, 130, + 202, 233, 217, 83, 49, 221, 185, 1, 130, 176, 217, 83, 49, 221, 185, 1, + 126, 189, 217, 83, 49, 221, 185, 1, 126, 202, 233, 217, 83, 49, 221, 185, + 1, 126, 176, 217, 83, 49, 221, 185, 1, 130, 161, 217, 83, 49, 221, 185, + 1, 130, 213, 6, 217, 83, 49, 221, 185, 1, 130, 166, 217, 83, 49, 221, + 185, 1, 126, 161, 217, 83, 49, 221, 185, 1, 126, 213, 6, 217, 83, 49, + 221, 185, 1, 126, 166, 217, 83, 49, 221, 185, 1, 130, 235, 239, 217, 83, + 49, 221, 185, 1, 130, 199, 152, 217, 83, 49, 221, 185, 1, 130, 172, 217, + 83, 49, 221, 185, 1, 126, 235, 239, 217, 83, 49, 221, 185, 1, 126, 199, + 152, 217, 83, 49, 221, 185, 1, 126, 172, 217, 83, 49, 221, 185, 1, 130, + 142, 217, 83, 49, 221, 185, 1, 130, 240, 136, 217, 83, 49, 221, 185, 1, + 130, 249, 145, 217, 83, 49, 221, 185, 1, 126, 142, 217, 83, 49, 221, 185, + 1, 126, 240, 136, 217, 83, 49, 221, 185, 1, 126, 249, 145, 217, 83, 49, + 221, 185, 1, 130, 223, 138, 217, 83, 49, 221, 185, 1, 130, 196, 174, 217, + 83, 49, 221, 185, 1, 126, 223, 138, 217, 83, 49, 221, 185, 1, 126, 196, + 174, 217, 83, 49, 221, 185, 1, 130, 204, 163, 217, 83, 49, 221, 185, 1, + 126, 204, 163, 217, 83, 49, 221, 185, 18, 2, 18, 206, 170, 217, 83, 49, + 221, 185, 18, 2, 252, 168, 217, 83, 49, 221, 185, 18, 2, 226, 120, 217, + 83, 49, 221, 185, 18, 2, 66, 217, 83, 49, 221, 185, 18, 2, 199, 245, 217, + 83, 49, 221, 185, 18, 2, 69, 217, 83, 49, 221, 185, 18, 2, 251, 245, 217, + 83, 49, 221, 185, 18, 2, 72, 217, 83, 49, 221, 185, 18, 2, 214, 190, 217, + 83, 49, 221, 185, 18, 2, 200, 99, 217, 83, 49, 221, 185, 18, 2, 250, 122, + 217, 83, 49, 221, 185, 18, 2, 252, 122, 217, 83, 49, 221, 185, 18, 2, + 199, 237, 217, 83, 49, 221, 185, 18, 2, 214, 8, 217, 83, 49, 221, 185, + 18, 2, 214, 187, 217, 83, 49, 221, 185, 18, 2, 200, 94, 217, 83, 49, 221, + 185, 18, 2, 225, 225, 217, 83, 49, 221, 185, 1, 48, 199, 230, 217, 83, + 49, 221, 185, 1, 48, 217, 73, 217, 83, 49, 221, 185, 1, 48, 218, 55, 217, + 83, 49, 221, 185, 1, 48, 221, 136, 217, 83, 49, 221, 185, 1, 48, 225, 80, + 217, 83, 49, 221, 185, 1, 48, 240, 231, 217, 83, 49, 221, 185, 1, 48, + 250, 112, 217, 83, 49, 221, 185, 152, 220, 28, 217, 83, 49, 221, 185, + 152, 220, 27, 217, 83, 49, 221, 185, 17, 195, 79, 217, 83, 49, 221, 185, + 17, 100, 217, 83, 49, 221, 185, 17, 102, 217, 83, 49, 221, 185, 17, 134, + 217, 83, 49, 221, 185, 17, 136, 217, 83, 49, 221, 185, 17, 146, 217, 83, + 49, 221, 185, 17, 167, 217, 83, 49, 221, 185, 17, 178, 217, 83, 49, 221, + 185, 17, 171, 217, 83, 49, 221, 185, 17, 182, 217, 83, 49, 221, 185, 120, + 17, 100, 217, 83, 49, 221, 185, 2, 223, 65, 217, 83, 49, 221, 185, 2, + 223, 64, 89, 16, 213, 111, 89, 16, 218, 105, 224, 3, 89, 16, 212, 183, + 224, 3, 89, 16, 248, 235, 224, 3, 89, 16, 247, 250, 224, 3, 89, 16, 212, + 50, 224, 3, 89, 16, 212, 44, 224, 3, 89, 16, 212, 42, 224, 3, 89, 16, + 212, 48, 224, 3, 89, 16, 212, 46, 224, 3, 89, 16, 240, 82, 224, 3, 89, + 16, 240, 78, 224, 3, 89, 16, 240, 77, 224, 3, 89, 16, 240, 80, 224, 3, + 89, 16, 240, 79, 224, 3, 89, 16, 240, 76, 224, 3, 89, 16, 200, 253, 89, + 16, 218, 105, 209, 219, 89, 16, 212, 183, 209, 219, 89, 16, 248, 235, + 209, 219, 89, 16, 247, 250, 209, 219, 89, 16, 212, 50, 209, 219, 89, 16, + 212, 44, 209, 219, 89, 16, 212, 42, 209, 219, 89, 16, 212, 48, 209, 219, + 89, 16, 212, 46, 209, 219, 89, 16, 240, 82, 209, 219, 89, 16, 240, 78, + 209, 219, 89, 16, 240, 77, 209, 219, 89, 16, 240, 80, 209, 219, 89, 16, + 240, 79, 209, 219, 89, 16, 240, 76, 209, 219, 248, 14, 1, 155, 248, 14, + 1, 234, 123, 248, 14, 1, 217, 71, 248, 14, 1, 217, 14, 248, 14, 1, 161, + 248, 14, 1, 249, 145, 248, 14, 1, 166, 248, 14, 1, 218, 151, 248, 14, 1, + 189, 248, 14, 1, 240, 136, 248, 14, 1, 176, 248, 14, 1, 215, 252, 248, + 14, 1, 247, 174, 248, 14, 1, 225, 214, 248, 14, 1, 215, 109, 248, 14, 1, + 215, 100, 248, 14, 1, 164, 248, 14, 1, 169, 248, 14, 1, 172, 248, 14, 1, + 199, 152, 248, 14, 1, 183, 248, 14, 1, 63, 248, 14, 1, 142, 248, 14, 18, + 2, 68, 248, 14, 18, 2, 66, 248, 14, 18, 2, 69, 248, 14, 18, 2, 72, 248, + 14, 18, 2, 251, 245, 248, 14, 213, 208, 248, 14, 236, 222, 77, 208, 132, + 49, 120, 1, 130, 155, 49, 120, 1, 130, 224, 146, 49, 120, 1, 130, 223, + 122, 49, 120, 1, 126, 155, 49, 120, 1, 126, 223, 122, 49, 120, 1, 126, + 224, 146, 49, 120, 1, 217, 71, 49, 120, 1, 130, 247, 174, 49, 120, 1, + 130, 247, 16, 49, 120, 1, 126, 247, 174, 49, 120, 1, 126, 183, 49, 120, + 1, 126, 247, 16, 49, 120, 1, 215, 109, 49, 120, 1, 210, 197, 49, 120, 1, + 130, 210, 195, 49, 120, 1, 240, 136, 49, 120, 1, 126, 210, 195, 49, 120, + 1, 210, 206, 49, 120, 1, 130, 189, 49, 120, 1, 130, 202, 233, 49, 120, 1, + 126, 189, 49, 120, 1, 126, 202, 233, 49, 120, 1, 176, 49, 120, 1, 249, + 145, 49, 120, 1, 130, 161, 49, 120, 1, 130, 213, 6, 49, 120, 1, 130, 235, + 239, 49, 120, 1, 126, 161, 49, 120, 1, 126, 235, 239, 49, 120, 1, 126, + 213, 6, 49, 120, 1, 166, 49, 120, 1, 126, 164, 49, 120, 1, 130, 164, 49, + 120, 1, 169, 49, 120, 1, 209, 129, 49, 120, 1, 172, 49, 120, 1, 221, 184, + 49, 120, 1, 197, 166, 49, 120, 1, 130, 207, 50, 49, 120, 1, 130, 205, 80, + 49, 120, 1, 130, 183, 49, 120, 1, 130, 142, 49, 120, 1, 222, 37, 49, 120, + 1, 63, 49, 120, 1, 126, 142, 49, 120, 1, 68, 49, 120, 1, 226, 120, 49, + 120, 1, 66, 49, 120, 1, 199, 245, 49, 120, 1, 237, 54, 49, 120, 1, 214, + 102, 49, 120, 1, 223, 65, 49, 120, 1, 233, 96, 183, 49, 120, 108, 2, 219, + 194, 169, 49, 120, 108, 2, 219, 194, 172, 49, 120, 108, 2, 223, 83, 203, + 111, 223, 54, 49, 120, 2, 220, 82, 225, 14, 223, 54, 49, 120, 108, 2, 48, + 217, 71, 49, 120, 108, 2, 126, 161, 49, 120, 108, 2, 130, 210, 196, 214, + 73, 126, 161, 49, 120, 108, 2, 166, 49, 120, 108, 2, 249, 145, 49, 120, + 108, 2, 183, 49, 120, 2, 208, 244, 49, 120, 18, 2, 63, 49, 120, 18, 2, + 220, 82, 208, 199, 49, 120, 18, 2, 252, 168, 49, 120, 18, 2, 203, 120, + 252, 168, 49, 120, 18, 2, 68, 49, 120, 18, 2, 226, 120, 49, 120, 18, 2, + 200, 99, 49, 120, 18, 2, 199, 244, 49, 120, 18, 2, 66, 49, 120, 18, 2, + 199, 245, 49, 120, 18, 2, 72, 49, 120, 18, 2, 214, 191, 60, 49, 120, 18, + 2, 214, 8, 49, 120, 18, 2, 69, 49, 120, 18, 2, 251, 245, 49, 120, 18, 2, + 214, 102, 49, 120, 18, 2, 251, 200, 49, 120, 18, 2, 120, 251, 200, 49, + 120, 18, 2, 214, 191, 57, 49, 120, 2, 220, 82, 225, 13, 49, 120, 2, 202, + 10, 49, 120, 2, 202, 9, 49, 120, 2, 224, 106, 202, 8, 49, 120, 2, 224, + 106, 202, 7, 49, 120, 2, 224, 106, 202, 6, 49, 120, 2, 210, 252, 232, + 245, 49, 120, 2, 220, 82, 208, 229, 49, 120, 2, 224, 105, 224, 250, 49, + 120, 38, 241, 44, 238, 253, 49, 120, 231, 157, 17, 195, 79, 49, 120, 231, + 157, 17, 100, 49, 120, 231, 157, 17, 102, 49, 120, 231, 157, 17, 134, 49, + 120, 231, 157, 17, 136, 49, 120, 231, 157, 17, 146, 49, 120, 231, 157, + 17, 167, 49, 120, 231, 157, 17, 178, 49, 120, 231, 157, 17, 171, 49, 120, + 231, 157, 17, 182, 49, 120, 120, 17, 195, 79, 49, 120, 120, 17, 100, 49, + 120, 120, 17, 102, 49, 120, 120, 17, 134, 49, 120, 120, 17, 136, 49, 120, + 120, 17, 146, 49, 120, 120, 17, 167, 49, 120, 120, 17, 178, 49, 120, 120, + 17, 171, 49, 120, 120, 17, 182, 49, 120, 2, 197, 64, 49, 120, 2, 197, 63, + 49, 120, 2, 208, 184, 49, 120, 2, 224, 177, 49, 120, 2, 231, 85, 49, 120, + 2, 239, 12, 49, 120, 2, 210, 89, 209, 194, 210, 206, 49, 120, 2, 220, 82, + 196, 98, 49, 120, 2, 225, 48, 49, 120, 2, 225, 47, 49, 120, 2, 208, 194, + 49, 120, 2, 208, 193, 49, 120, 2, 232, 182, 49, 120, 2, 247, 171, 38, + 237, 240, 244, 241, 252, 22, 38, 239, 149, 38, 226, 63, 38, 237, 231, 51, + 38, 201, 165, 238, 253, 38, 196, 221, 60, 38, 197, 56, 222, 76, 60, 38, + 192, 117, 60, 38, 52, 192, 117, 60, 38, 175, 247, 38, 204, 196, 60, 38, + 204, 182, 247, 38, 204, 196, 60, 38, 213, 142, 57, 38, 52, 213, 142, 57, + 38, 213, 142, 60, 38, 213, 142, 214, 20, 141, 2, 200, 82, 210, 59, 141, + 2, 200, 82, 247, 135, 141, 2, 247, 53, 141, 2, 204, 86, 141, 2, 248, 151, + 141, 1, 251, 179, 141, 1, 251, 180, 203, 50, 141, 1, 226, 116, 141, 1, + 226, 117, 203, 50, 141, 1, 200, 85, 141, 1, 200, 86, 203, 50, 141, 1, + 210, 252, 210, 122, 141, 1, 210, 252, 210, 123, 203, 50, 141, 1, 223, 83, + 222, 159, 141, 1, 223, 83, 222, 160, 203, 50, 141, 1, 237, 12, 141, 1, + 251, 197, 141, 1, 214, 137, 141, 1, 214, 138, 203, 50, 141, 1, 155, 141, + 1, 225, 70, 220, 85, 141, 1, 234, 123, 141, 1, 234, 124, 233, 129, 141, + 1, 217, 71, 141, 1, 247, 174, 141, 1, 247, 175, 223, 69, 141, 1, 225, + 214, 141, 1, 225, 215, 225, 184, 141, 1, 215, 109, 141, 1, 203, 169, 222, + 217, 141, 1, 203, 169, 218, 100, 220, 85, 141, 1, 240, 137, 218, 100, + 251, 136, 141, 1, 240, 137, 218, 100, 220, 85, 141, 1, 218, 1, 210, 209, + 141, 1, 189, 141, 1, 203, 169, 203, 81, 141, 1, 240, 136, 141, 1, 240, + 137, 220, 106, 141, 1, 176, 141, 1, 161, 141, 1, 213, 244, 225, 6, 141, + 1, 249, 145, 141, 1, 249, 146, 224, 189, 141, 1, 166, 141, 1, 164, 141, + 1, 169, 141, 1, 172, 141, 1, 197, 166, 141, 1, 209, 23, 209, 0, 141, 1, + 209, 23, 208, 206, 141, 1, 183, 141, 1, 142, 141, 2, 210, 112, 141, 18, + 2, 203, 50, 141, 18, 2, 200, 81, 141, 18, 2, 200, 82, 208, 202, 141, 18, + 2, 204, 121, 141, 18, 2, 204, 122, 226, 108, 141, 18, 2, 210, 252, 210, + 122, 141, 18, 2, 210, 252, 210, 123, 203, 50, 141, 18, 2, 223, 83, 222, + 159, 141, 18, 2, 223, 83, 222, 160, 203, 50, 141, 18, 2, 203, 121, 141, + 18, 2, 203, 122, 210, 122, 141, 18, 2, 203, 122, 203, 50, 141, 18, 2, + 203, 122, 210, 123, 203, 50, 141, 18, 2, 213, 48, 141, 18, 2, 213, 49, + 203, 50, 141, 252, 1, 252, 0, 141, 1, 225, 36, 208, 201, 141, 1, 224, + 112, 208, 201, 141, 1, 200, 181, 208, 201, 141, 1, 237, 48, 208, 201, + 141, 1, 199, 119, 208, 201, 141, 1, 195, 105, 208, 201, 141, 1, 250, 171, + 208, 201, 141, 17, 195, 79, 141, 17, 100, 141, 17, 102, 141, 17, 134, + 141, 17, 136, 141, 17, 146, 141, 17, 167, 141, 17, 178, 141, 17, 171, + 141, 17, 182, 141, 213, 171, 141, 213, 200, 141, 197, 48, 141, 247, 108, + 213, 193, 141, 247, 108, 206, 81, 141, 247, 108, 213, 139, 141, 213, 199, + 141, 34, 16, 239, 4, 141, 34, 16, 239, 209, 141, 34, 16, 237, 184, 141, + 34, 16, 240, 86, 141, 34, 16, 240, 87, 204, 86, 141, 34, 16, 239, 94, + 141, 34, 16, 240, 128, 141, 34, 16, 239, 185, 141, 34, 16, 240, 110, 141, + 34, 16, 240, 87, 234, 42, 141, 34, 16, 38, 203, 43, 141, 34, 16, 38, 236, + 219, 141, 34, 16, 38, 224, 184, 141, 34, 16, 38, 224, 186, 141, 34, 16, + 38, 225, 188, 141, 34, 16, 38, 224, 185, 3, 225, 188, 141, 34, 16, 38, + 224, 187, 3, 225, 188, 141, 34, 16, 38, 248, 220, 141, 34, 16, 38, 233, + 133, 141, 34, 16, 210, 20, 192, 237, 195, 141, 34, 16, 210, 20, 192, 240, + 126, 141, 34, 16, 210, 20, 244, 203, 201, 26, 141, 34, 16, 210, 20, 244, + 203, 203, 131, 141, 34, 16, 222, 182, 192, 213, 185, 141, 34, 16, 222, + 182, 192, 211, 211, 141, 34, 16, 222, 182, 244, 203, 212, 145, 141, 34, + 16, 222, 182, 244, 203, 212, 129, 141, 34, 16, 222, 182, 192, 212, 171, + 204, 110, 2, 213, 168, 204, 110, 2, 213, 181, 204, 110, 2, 213, 177, 204, + 110, 1, 63, 204, 110, 1, 68, 204, 110, 1, 66, 204, 110, 1, 251, 245, 204, + 110, 1, 72, 204, 110, 1, 69, 204, 110, 1, 236, 116, 204, 110, 1, 155, + 204, 110, 1, 211, 159, 204, 110, 1, 234, 123, 204, 110, 1, 217, 71, 204, + 110, 1, 247, 174, 204, 110, 1, 225, 214, 204, 110, 1, 195, 115, 204, 110, + 1, 215, 109, 204, 110, 1, 189, 204, 110, 1, 240, 136, 204, 110, 1, 176, + 204, 110, 1, 161, 204, 110, 1, 235, 239, 204, 110, 1, 199, 152, 204, 110, + 1, 249, 145, 204, 110, 1, 166, 204, 110, 1, 164, 204, 110, 1, 169, 204, + 110, 1, 172, 204, 110, 1, 197, 166, 204, 110, 1, 183, 204, 110, 1, 196, + 208, 204, 110, 1, 142, 204, 110, 108, 2, 213, 197, 204, 110, 108, 2, 213, + 170, 204, 110, 108, 2, 213, 167, 204, 110, 18, 2, 213, 184, 204, 110, 18, + 2, 213, 166, 204, 110, 18, 2, 213, 190, 204, 110, 18, 2, 213, 176, 204, + 110, 18, 2, 213, 198, 204, 110, 18, 2, 213, 186, 204, 110, 2, 213, 201, + 204, 110, 2, 199, 7, 204, 110, 108, 2, 213, 127, 166, 204, 110, 108, 2, + 213, 127, 197, 166, 204, 110, 1, 224, 146, 204, 110, 1, 204, 43, 204, + 110, 17, 195, 79, 204, 110, 17, 100, 204, 110, 17, 102, 204, 110, 17, + 134, 204, 110, 17, 136, 204, 110, 17, 146, 204, 110, 17, 167, 204, 110, + 17, 178, 204, 110, 17, 171, 204, 110, 17, 182, 204, 110, 250, 132, 204, + 110, 1, 210, 92, 204, 110, 1, 222, 132, 204, 110, 1, 248, 197, 204, 110, + 1, 48, 225, 80, 204, 110, 1, 48, 221, 136, 249, 55, 1, 63, 249, 55, 1, + 206, 73, 63, 249, 55, 1, 142, 249, 55, 1, 206, 73, 142, 249, 55, 1, 220, + 57, 142, 249, 55, 1, 249, 145, 249, 55, 1, 224, 247, 249, 145, 249, 55, + 1, 161, 249, 55, 1, 206, 73, 161, 249, 55, 1, 176, 249, 55, 1, 220, 57, + 176, 249, 55, 1, 197, 166, 249, 55, 1, 206, 73, 197, 166, 249, 55, 1, + 213, 216, 197, 166, 249, 55, 1, 234, 123, 249, 55, 1, 206, 73, 234, 123, + 249, 55, 1, 225, 214, 249, 55, 1, 240, 136, 249, 55, 1, 169, 249, 55, 1, + 206, 73, 169, 249, 55, 1, 166, 249, 55, 1, 206, 73, 166, 249, 55, 1, 205, + 157, 189, 249, 55, 1, 216, 23, 189, 249, 55, 1, 183, 249, 55, 1, 206, 73, + 183, 249, 55, 1, 220, 57, 183, 249, 55, 1, 164, 249, 55, 1, 206, 73, 164, + 249, 55, 1, 217, 71, 249, 55, 1, 172, 249, 55, 1, 206, 73, 172, 249, 55, + 1, 215, 109, 249, 55, 1, 247, 174, 249, 55, 1, 217, 159, 249, 55, 1, 219, + 241, 249, 55, 1, 68, 249, 55, 1, 66, 249, 55, 2, 202, 14, 249, 55, 18, 2, + 69, 249, 55, 18, 2, 213, 216, 69, 249, 55, 18, 2, 237, 54, 249, 55, 18, + 2, 68, 249, 55, 18, 2, 224, 247, 68, 249, 55, 18, 2, 72, 249, 55, 18, 2, + 224, 247, 72, 249, 55, 18, 2, 66, 249, 55, 18, 2, 118, 36, 206, 73, 183, + 249, 55, 108, 2, 217, 73, 249, 55, 108, 2, 233, 15, 249, 55, 213, 179, + 249, 55, 213, 175, 249, 55, 16, 248, 161, 218, 1, 219, 141, 249, 55, 16, + 248, 161, 212, 175, 249, 55, 16, 248, 161, 225, 107, 249, 55, 16, 248, + 161, 213, 179, 222, 143, 1, 155, 222, 143, 1, 224, 29, 222, 143, 1, 224, + 146, 222, 143, 1, 234, 123, 222, 143, 1, 233, 160, 222, 143, 1, 217, 71, + 222, 143, 1, 247, 174, 222, 143, 1, 247, 16, 222, 143, 1, 225, 214, 222, + 143, 1, 215, 109, 222, 143, 1, 189, 222, 143, 1, 202, 233, 222, 143, 1, + 240, 136, 222, 143, 1, 176, 222, 143, 1, 161, 222, 143, 1, 212, 150, 222, + 143, 1, 213, 6, 222, 143, 1, 235, 239, 222, 143, 1, 235, 95, 222, 143, 1, + 249, 145, 222, 143, 1, 248, 137, 222, 143, 1, 166, 222, 143, 1, 219, 2, + 222, 143, 1, 201, 113, 222, 143, 1, 201, 103, 222, 143, 1, 237, 156, 222, + 143, 1, 164, 222, 143, 1, 169, 222, 143, 1, 172, 222, 143, 1, 142, 222, + 143, 1, 232, 25, 222, 143, 1, 199, 152, 222, 143, 1, 183, 222, 143, 1, + 207, 50, 222, 143, 1, 197, 166, 222, 143, 1, 63, 222, 143, 204, 152, 1, + 164, 222, 143, 204, 152, 1, 169, 222, 143, 18, 2, 252, 168, 222, 143, 18, + 2, 68, 222, 143, 18, 2, 72, 222, 143, 18, 2, 214, 102, 222, 143, 18, 2, + 66, 222, 143, 18, 2, 199, 245, 222, 143, 18, 2, 69, 222, 143, 108, 2, + 225, 80, 222, 143, 108, 2, 221, 136, 222, 143, 108, 2, 159, 222, 143, + 108, 2, 218, 55, 222, 143, 108, 2, 214, 3, 222, 143, 108, 2, 144, 222, + 143, 108, 2, 203, 216, 222, 143, 108, 2, 215, 81, 222, 143, 108, 2, 225, + 13, 222, 143, 2, 210, 207, 222, 143, 2, 215, 149, 222, 143, 211, 214, + 203, 164, 222, 143, 211, 214, 215, 93, 202, 125, 203, 164, 222, 143, 211, + 214, 247, 25, 222, 143, 211, 214, 201, 95, 247, 25, 222, 143, 211, 214, + 201, 94, 222, 143, 17, 195, 79, 222, 143, 17, 100, 222, 143, 17, 102, + 222, 143, 17, 134, 222, 143, 17, 136, 222, 143, 17, 146, 222, 143, 17, + 167, 222, 143, 17, 178, 222, 143, 17, 171, 222, 143, 17, 182, 222, 143, + 1, 201, 78, 222, 143, 1, 201, 66, 222, 143, 1, 240, 41, 214, 135, 245, + 68, 17, 195, 79, 214, 135, 245, 68, 17, 100, 214, 135, 245, 68, 17, 102, + 214, 135, 245, 68, 17, 134, 214, 135, 245, 68, 17, 136, 214, 135, 245, + 68, 17, 146, 214, 135, 245, 68, 17, 167, 214, 135, 245, 68, 17, 178, 214, + 135, 245, 68, 17, 171, 214, 135, 245, 68, 17, 182, 214, 135, 245, 68, 1, + 172, 214, 135, 245, 68, 1, 250, 168, 214, 135, 245, 68, 1, 251, 217, 214, + 135, 245, 68, 1, 251, 97, 214, 135, 245, 68, 1, 251, 173, 214, 135, 245, + 68, 1, 223, 82, 214, 135, 245, 68, 1, 252, 130, 214, 135, 245, 68, 1, + 252, 131, 214, 135, 245, 68, 1, 252, 129, 214, 135, 245, 68, 1, 252, 123, + 214, 135, 245, 68, 1, 222, 109, 214, 135, 245, 68, 1, 225, 248, 214, 135, + 245, 68, 1, 226, 121, 214, 135, 245, 68, 1, 226, 14, 214, 135, 245, 68, + 1, 226, 1, 214, 135, 245, 68, 1, 221, 191, 214, 135, 245, 68, 1, 200, + 106, 214, 135, 245, 68, 1, 200, 104, 214, 135, 245, 68, 1, 200, 42, 214, + 135, 245, 68, 1, 199, 237, 214, 135, 245, 68, 1, 222, 197, 214, 135, 245, + 68, 1, 236, 183, 214, 135, 245, 68, 1, 237, 57, 214, 135, 245, 68, 1, + 236, 230, 214, 135, 245, 68, 1, 236, 155, 214, 135, 245, 68, 1, 222, 7, + 214, 135, 245, 68, 1, 214, 44, 214, 135, 245, 68, 1, 214, 186, 214, 135, + 245, 68, 1, 214, 29, 214, 135, 245, 68, 1, 214, 149, 214, 135, 245, 68, + 218, 146, 201, 43, 214, 135, 245, 68, 234, 118, 201, 44, 214, 135, 245, + 68, 218, 140, 201, 44, 214, 135, 245, 68, 210, 137, 214, 135, 245, 68, + 213, 4, 214, 135, 245, 68, 251, 208, 214, 135, 245, 68, 211, 214, 218, + 136, 214, 135, 245, 68, 211, 214, 52, 218, 136, 40, 4, 1, 209, 185, 199, + 118, 40, 4, 1, 221, 233, 239, 252, 40, 4, 1, 217, 210, 72, 40, 4, 1, 197, + 62, 236, 151, 40, 4, 1, 203, 120, 203, 68, 40, 4, 1, 202, 150, 203, 68, + 40, 4, 1, 203, 120, 232, 173, 55, 40, 4, 1, 203, 120, 196, 84, 40, 4, 1, + 200, 67, 200, 87, 94, 218, 147, 6, 1, 251, 106, 94, 218, 147, 6, 1, 249, + 93, 94, 218, 147, 6, 1, 234, 93, 94, 218, 147, 6, 1, 239, 6, 94, 218, + 147, 6, 1, 236, 230, 94, 218, 147, 6, 1, 199, 16, 94, 218, 147, 6, 1, + 195, 82, 94, 218, 147, 6, 1, 203, 114, 94, 218, 147, 6, 1, 226, 86, 94, + 218, 147, 6, 1, 225, 17, 94, 218, 147, 6, 1, 222, 222, 94, 218, 147, 6, + 1, 220, 62, 94, 218, 147, 6, 1, 217, 211, 94, 218, 147, 6, 1, 214, 119, + 94, 218, 147, 6, 1, 213, 157, 94, 218, 147, 6, 1, 195, 70, 94, 218, 147, + 6, 1, 210, 229, 94, 218, 147, 6, 1, 208, 219, 94, 218, 147, 6, 1, 203, + 101, 94, 218, 147, 6, 1, 200, 72, 94, 218, 147, 6, 1, 212, 254, 94, 218, + 147, 6, 1, 224, 134, 94, 218, 147, 6, 1, 233, 221, 94, 218, 147, 6, 1, + 211, 144, 94, 218, 147, 6, 1, 206, 211, 94, 218, 147, 6, 1, 245, 62, 94, + 218, 147, 6, 1, 247, 142, 94, 218, 147, 6, 1, 225, 162, 94, 218, 147, 6, + 1, 245, 0, 94, 218, 147, 6, 1, 247, 0, 94, 218, 147, 6, 1, 196, 206, 94, + 218, 147, 6, 1, 225, 177, 94, 218, 147, 6, 1, 232, 242, 94, 218, 147, 6, + 1, 232, 147, 94, 218, 147, 6, 1, 232, 58, 94, 218, 147, 6, 1, 197, 109, + 94, 218, 147, 6, 1, 232, 175, 94, 218, 147, 6, 1, 231, 181, 94, 218, 147, + 6, 1, 235, 153, 94, 218, 147, 6, 1, 196, 5, 94, 218, 147, 6, 1, 236, 249, + 94, 218, 147, 6, 1, 163, 234, 93, 94, 218, 147, 6, 1, 251, 194, 94, 218, + 147, 6, 1, 251, 234, 94, 218, 147, 6, 1, 232, 173, 55, 94, 218, 147, 6, + 1, 223, 73, 55, 204, 110, 211, 214, 248, 161, 204, 79, 204, 110, 211, + 214, 248, 161, 213, 180, 204, 110, 211, 214, 248, 161, 211, 201, 204, + 110, 211, 214, 248, 161, 247, 159, 204, 110, 211, 214, 248, 161, 222, + 133, 208, 198, 204, 110, 211, 214, 248, 161, 225, 70, 208, 198, 204, 110, + 211, 214, 248, 161, 240, 137, 208, 198, 204, 110, 211, 214, 248, 161, + 249, 146, 208, 198, 199, 115, 152, 224, 243, 199, 115, 152, 207, 16, 199, + 115, 152, 212, 29, 199, 115, 2, 216, 191, 199, 115, 2, 196, 106, 219, 61, + 204, 70, 199, 115, 152, 196, 106, 251, 213, 226, 73, 204, 70, 199, 115, + 152, 196, 106, 226, 73, 204, 70, 199, 115, 152, 196, 106, 224, 231, 226, + 73, 204, 70, 199, 115, 152, 247, 136, 60, 199, 115, 152, 196, 106, 224, + 231, 226, 73, 204, 71, 208, 165, 199, 115, 152, 52, 204, 70, 199, 115, + 152, 201, 165, 204, 70, 199, 115, 152, 224, 231, 251, 53, 199, 115, 152, + 76, 60, 199, 115, 152, 99, 238, 251, 60, 199, 115, 152, 115, 238, 251, + 60, 199, 115, 152, 210, 10, 224, 242, 226, 73, 204, 70, 199, 115, 152, + 250, 165, 226, 73, 204, 70, 199, 115, 2, 199, 3, 204, 70, 199, 115, 2, + 199, 3, 200, 101, 199, 115, 2, 210, 89, 199, 3, 200, 101, 199, 115, 2, + 199, 3, 251, 53, 199, 115, 2, 210, 89, 199, 3, 251, 53, 199, 115, 2, 199, + 3, 200, 102, 3, 203, 135, 199, 115, 2, 199, 3, 251, 54, 3, 203, 135, 199, + 115, 2, 251, 52, 251, 68, 199, 115, 2, 251, 52, 249, 112, 199, 115, 2, + 251, 52, 199, 142, 199, 115, 2, 251, 52, 199, 143, 3, 203, 135, 199, 115, + 2, 202, 58, 199, 115, 2, 232, 83, 181, 251, 51, 199, 115, 2, 181, 251, + 51, 199, 115, 2, 209, 142, 181, 251, 51, 199, 115, 2, 251, 52, 200, 108, + 218, 127, 199, 115, 2, 250, 247, 199, 115, 2, 209, 194, 250, 247, 199, + 115, 152, 247, 136, 57, 199, 115, 2, 225, 165, 199, 115, 2, 200, 34, 199, + 115, 2, 250, 163, 199, 115, 152, 210, 3, 57, 199, 115, 152, 52, 210, 3, + 57, 199, 115, 2, 52, 251, 52, 251, 68, 8, 1, 4, 6, 63, 8, 1, 4, 6, 251, + 245, 8, 4, 1, 163, 251, 245, 8, 1, 4, 6, 249, 74, 250, 112, 8, 1, 4, 6, + 247, 207, 8, 1, 4, 6, 240, 231, 8, 1, 4, 6, 236, 121, 8, 1, 4, 6, 69, 8, + 4, 1, 163, 192, 69, 8, 4, 1, 163, 68, 8, 1, 4, 6, 225, 217, 8, 1, 4, 6, + 225, 80, 8, 1, 4, 6, 223, 100, 3, 106, 8, 1, 4, 6, 221, 136, 8, 1, 4, 6, + 210, 89, 218, 55, 8, 1, 4, 6, 72, 8, 1, 4, 6, 192, 72, 8, 4, 1, 206, 96, + 72, 8, 4, 1, 206, 96, 192, 72, 8, 4, 1, 206, 96, 177, 3, 106, 8, 4, 1, + 163, 214, 164, 8, 1, 4, 6, 214, 39, 8, 4, 1, 201, 243, 157, 72, 8, 4, 1, + 248, 85, 157, 72, 8, 1, 4, 6, 214, 3, 8, 1, 4, 6, 210, 89, 144, 8, 1, 4, + 6, 163, 144, 8, 1, 4, 6, 203, 216, 8, 1, 4, 6, 66, 8, 4, 1, 206, 96, 66, + 8, 4, 1, 206, 96, 239, 148, 66, 8, 4, 1, 206, 96, 163, 221, 136, 8, 1, 4, + 6, 199, 230, 8, 1, 4, 6, 197, 199, 8, 1, 4, 6, 195, 158, 8, 1, 4, 6, 236, + 52, 8, 1, 198, 244, 222, 223, 205, 119, 8, 1, 251, 194, 32, 1, 4, 6, 234, + 94, 32, 1, 4, 6, 222, 245, 32, 1, 4, 6, 212, 220, 32, 1, 4, 6, 210, 74, + 32, 1, 4, 6, 211, 238, 40, 1, 4, 6, 237, 7, 73, 1, 6, 63, 73, 1, 6, 251, + 245, 73, 1, 6, 250, 112, 73, 1, 6, 249, 74, 250, 112, 73, 1, 6, 240, 231, + 73, 1, 6, 69, 73, 1, 6, 210, 89, 69, 73, 1, 6, 234, 190, 73, 1, 6, 233, + 15, 73, 1, 6, 68, 73, 1, 6, 225, 217, 73, 1, 6, 225, 80, 73, 1, 6, 159, + 73, 1, 6, 221, 136, 73, 1, 6, 218, 55, 73, 1, 6, 210, 89, 218, 55, 73, 1, + 6, 72, 73, 1, 6, 214, 39, 73, 1, 6, 214, 3, 73, 1, 6, 144, 73, 1, 6, 203, + 216, 73, 1, 6, 66, 73, 1, 6, 197, 199, 73, 1, 4, 63, 73, 1, 4, 163, 63, + 73, 1, 4, 251, 134, 73, 1, 4, 163, 251, 245, 73, 1, 4, 250, 112, 73, 1, + 4, 240, 231, 73, 1, 4, 69, 73, 1, 4, 208, 163, 73, 1, 4, 192, 69, 73, 1, + 4, 163, 192, 69, 73, 1, 4, 234, 190, 73, 1, 4, 163, 68, 73, 1, 4, 225, + 80, 73, 1, 4, 221, 136, 73, 1, 4, 236, 215, 73, 1, 4, 72, 73, 1, 4, 192, + 72, 73, 1, 4, 201, 243, 157, 72, 73, 1, 4, 248, 85, 157, 72, 73, 1, 4, + 214, 3, 73, 1, 4, 203, 216, 73, 1, 4, 66, 73, 1, 4, 206, 96, 66, 73, 1, + 4, 163, 221, 136, 73, 1, 4, 199, 230, 73, 1, 4, 251, 194, 73, 1, 4, 248, + 206, 73, 1, 4, 32, 234, 94, 73, 1, 4, 239, 212, 73, 1, 4, 32, 212, 246, + 73, 1, 4, 245, 75, 8, 204, 143, 4, 1, 68, 8, 204, 143, 4, 1, 144, 8, 204, + 143, 4, 1, 66, 8, 204, 143, 4, 1, 199, 230, 32, 204, 143, 4, 1, 248, 206, + 32, 204, 143, 4, 1, 234, 94, 32, 204, 143, 4, 1, 210, 74, 32, 204, 143, + 4, 1, 212, 246, 32, 204, 143, 4, 1, 245, 75, 8, 4, 1, 200, 99, 8, 4, 1, + 74, 3, 112, 202, 84, 8, 4, 1, 240, 232, 3, 112, 202, 84, 8, 4, 1, 236, + 50, 3, 112, 202, 84, 8, 4, 1, 221, 137, 3, 112, 202, 84, 8, 4, 1, 218, + 56, 3, 112, 202, 84, 8, 4, 1, 214, 4, 3, 112, 202, 84, 8, 4, 1, 211, 32, + 3, 112, 202, 84, 8, 4, 1, 211, 32, 3, 235, 109, 26, 112, 202, 84, 8, 4, + 1, 209, 81, 3, 112, 202, 84, 8, 4, 1, 203, 217, 3, 112, 202, 84, 8, 4, 1, + 195, 159, 3, 112, 202, 84, 8, 4, 1, 163, 234, 190, 73, 1, 40, 236, 230, + 8, 4, 1, 226, 39, 234, 190, 8, 4, 1, 202, 236, 3, 204, 200, 8, 4, 6, 1, + 230, 249, 3, 106, 8, 4, 1, 226, 8, 3, 106, 8, 4, 1, 214, 4, 3, 106, 8, 4, + 6, 1, 118, 3, 106, 8, 4, 1, 200, 29, 3, 106, 8, 4, 1, 74, 3, 213, 215, + 122, 8, 4, 1, 240, 232, 3, 213, 215, 122, 8, 4, 1, 236, 50, 3, 213, 215, + 122, 8, 4, 1, 234, 191, 3, 213, 215, 122, 8, 4, 1, 225, 81, 3, 213, 215, + 122, 8, 4, 1, 223, 100, 3, 213, 215, 122, 8, 4, 1, 221, 137, 3, 213, 215, + 122, 8, 4, 1, 218, 56, 3, 213, 215, 122, 8, 4, 1, 214, 4, 3, 213, 215, + 122, 8, 4, 1, 211, 32, 3, 213, 215, 122, 8, 4, 1, 209, 81, 3, 213, 215, + 122, 8, 4, 1, 236, 142, 3, 213, 215, 122, 8, 4, 1, 199, 231, 3, 213, 215, + 122, 8, 4, 1, 196, 223, 3, 213, 215, 122, 8, 4, 1, 195, 159, 3, 213, 215, + 122, 8, 4, 1, 39, 3, 210, 95, 122, 8, 4, 1, 251, 135, 3, 210, 95, 122, 8, + 4, 1, 240, 232, 3, 231, 165, 26, 203, 135, 8, 4, 1, 237, 136, 3, 210, 95, + 122, 8, 4, 1, 192, 237, 136, 3, 210, 95, 122, 8, 4, 1, 210, 89, 192, 237, + 136, 3, 210, 95, 122, 8, 4, 1, 208, 164, 3, 210, 95, 122, 8, 4, 1, 230, + 249, 3, 210, 95, 122, 8, 4, 1, 192, 177, 3, 210, 95, 122, 8, 4, 1, 236, + 142, 3, 210, 95, 122, 8, 4, 1, 118, 3, 210, 95, 122, 8, 4, 1, 236, 53, 3, + 210, 95, 122, 73, 1, 4, 163, 251, 134, 73, 1, 4, 247, 207, 73, 1, 4, 247, + 208, 3, 241, 21, 73, 1, 4, 236, 121, 73, 1, 4, 210, 89, 192, 69, 73, 1, + 4, 236, 49, 73, 1, 4, 238, 252, 225, 218, 3, 106, 73, 1, 4, 145, 234, + 190, 73, 1, 4, 163, 233, 15, 73, 1, 4, 230, 249, 3, 106, 73, 1, 4, 226, + 7, 73, 1, 4, 6, 68, 73, 1, 4, 6, 230, 249, 3, 106, 73, 1, 4, 225, 218, 3, + 241, 57, 73, 1, 4, 223, 100, 3, 210, 95, 122, 73, 1, 4, 223, 100, 3, 213, + 215, 122, 73, 1, 4, 6, 159, 73, 1, 4, 221, 137, 3, 122, 73, 1, 4, 163, + 221, 137, 3, 181, 222, 172, 73, 1, 4, 218, 56, 3, 50, 122, 73, 1, 4, 218, + 56, 3, 210, 95, 122, 73, 1, 4, 6, 218, 55, 73, 1, 4, 249, 74, 72, 73, 1, + 4, 212, 246, 73, 1, 4, 209, 81, 3, 122, 73, 1, 4, 236, 141, 73, 1, 4, + 203, 217, 3, 213, 215, 122, 73, 1, 4, 118, 154, 73, 1, 4, 200, 28, 73, 1, + 4, 6, 66, 73, 1, 4, 199, 231, 3, 122, 73, 1, 4, 163, 199, 230, 73, 1, 4, + 195, 158, 73, 1, 4, 195, 159, 3, 210, 95, 122, 73, 1, 4, 195, 159, 3, + 241, 21, 73, 1, 4, 236, 52, 73, 1, 4, 202, 199, 38, 237, 250, 233, 101, + 252, 22, 38, 237, 250, 252, 10, 252, 22, 38, 205, 213, 60, 38, 204, 77, + 78, 38, 220, 113, 38, 233, 98, 38, 220, 111, 38, 252, 8, 38, 233, 99, 38, + 252, 9, 38, 8, 4, 1, 211, 32, 60, 38, 248, 46, 38, 220, 112, 38, 52, 244, + 241, 57, 38, 214, 152, 57, 38, 195, 24, 60, 38, 225, 249, 60, 38, 200, + 22, 57, 38, 200, 5, 57, 38, 8, 4, 1, 235, 79, 192, 39, 57, 38, 8, 4, 1, + 251, 245, 38, 8, 4, 1, 251, 49, 38, 8, 4, 1, 250, 133, 38, 8, 4, 1, 247, + 208, 247, 50, 38, 8, 4, 1, 226, 39, 240, 231, 38, 8, 4, 1, 236, 121, 38, + 8, 4, 1, 234, 190, 38, 8, 1, 4, 6, 234, 190, 38, 8, 4, 1, 225, 80, 38, 8, + 4, 1, 159, 38, 8, 1, 4, 6, 159, 38, 8, 1, 4, 6, 221, 136, 38, 8, 4, 1, + 218, 55, 38, 8, 1, 4, 6, 218, 55, 38, 8, 1, 4, 6, 144, 38, 8, 4, 1, 211, + 32, 209, 188, 38, 8, 4, 1, 209, 80, 38, 8, 4, 1, 181, 209, 80, 38, 8, 4, + 1, 195, 158, 38, 8, 4, 1, 251, 134, 38, 8, 4, 1, 250, 112, 38, 8, 4, 1, + 248, 206, 38, 8, 4, 1, 208, 163, 38, 8, 4, 1, 236, 49, 38, 8, 4, 1, 223, + 100, 3, 52, 112, 202, 84, 38, 8, 4, 1, 177, 3, 175, 247, 38, 106, 38, 8, + 4, 1, 214, 3, 38, 8, 4, 1, 236, 141, 38, 8, 4, 1, 118, 3, 175, 247, 38, + 106, 38, 8, 4, 1, 197, 199, 38, 8, 4, 1, 39, 3, 239, 150, 38, 8, 4, 1, + 177, 3, 239, 150, 38, 8, 4, 1, 118, 3, 239, 150, 38, 124, 203, 148, 57, + 38, 224, 222, 90, 210, 22, 38, 224, 222, 90, 222, 184, 38, 76, 90, 222, + 184, 38, 197, 62, 226, 17, 248, 40, 60, 38, 239, 221, 78, 38, 52, 226, + 17, 248, 48, 60, 38, 251, 139, 180, 202, 30, 60, 38, 50, 250, 218, 57, + 38, 53, 250, 218, 26, 135, 250, 218, 60, 8, 6, 1, 39, 3, 210, 3, 60, 8, + 4, 1, 39, 3, 210, 3, 60, 8, 6, 1, 74, 3, 76, 57, 8, 4, 1, 74, 3, 76, 57, + 8, 6, 1, 74, 3, 76, 60, 8, 4, 1, 74, 3, 76, 60, 8, 6, 1, 74, 3, 222, 76, + 60, 8, 4, 1, 74, 3, 222, 76, 60, 8, 6, 1, 247, 208, 3, 247, 51, 26, 186, + 8, 4, 1, 247, 208, 3, 247, 51, 26, 186, 8, 6, 1, 240, 232, 3, 76, 57, 8, + 4, 1, 240, 232, 3, 76, 57, 8, 6, 1, 240, 232, 3, 76, 60, 8, 4, 1, 240, + 232, 3, 76, 60, 8, 6, 1, 240, 232, 3, 222, 76, 60, 8, 4, 1, 240, 232, 3, + 222, 76, 60, 8, 6, 1, 240, 232, 3, 247, 50, 8, 4, 1, 240, 232, 3, 247, + 50, 8, 6, 1, 240, 232, 3, 244, 241, 60, 8, 4, 1, 240, 232, 3, 244, 241, + 60, 8, 6, 1, 237, 136, 3, 220, 115, 26, 233, 100, 8, 4, 1, 237, 136, 3, + 220, 115, 26, 233, 100, 8, 6, 1, 237, 136, 3, 220, 115, 26, 186, 8, 4, 1, + 237, 136, 3, 220, 115, 26, 186, 8, 6, 1, 237, 136, 3, 244, 241, 60, 8, 4, + 1, 237, 136, 3, 244, 241, 60, 8, 6, 1, 237, 136, 3, 202, 85, 60, 8, 4, 1, + 237, 136, 3, 202, 85, 60, 8, 6, 1, 237, 136, 3, 247, 51, 26, 248, 47, 8, + 4, 1, 237, 136, 3, 247, 51, 26, 248, 47, 8, 6, 1, 236, 50, 3, 76, 57, 8, + 4, 1, 236, 50, 3, 76, 57, 8, 6, 1, 234, 191, 3, 220, 114, 8, 4, 1, 234, + 191, 3, 220, 114, 8, 6, 1, 233, 16, 3, 76, 57, 8, 4, 1, 233, 16, 3, 76, + 57, 8, 6, 1, 233, 16, 3, 76, 60, 8, 4, 1, 233, 16, 3, 76, 60, 8, 6, 1, + 233, 16, 3, 239, 150, 8, 4, 1, 233, 16, 3, 239, 150, 8, 6, 1, 233, 16, 3, + 247, 50, 8, 4, 1, 233, 16, 3, 247, 50, 8, 6, 1, 233, 16, 3, 248, 48, 60, + 8, 4, 1, 233, 16, 3, 248, 48, 60, 8, 6, 1, 230, 249, 3, 202, 85, 60, 8, + 4, 1, 230, 249, 3, 202, 85, 60, 8, 6, 1, 230, 249, 3, 239, 151, 26, 186, + 8, 4, 1, 230, 249, 3, 239, 151, 26, 186, 8, 6, 1, 225, 81, 3, 186, 8, 4, + 1, 225, 81, 3, 186, 8, 6, 1, 225, 81, 3, 76, 60, 8, 4, 1, 225, 81, 3, 76, + 60, 8, 6, 1, 225, 81, 3, 222, 76, 60, 8, 4, 1, 225, 81, 3, 222, 76, 60, + 8, 6, 1, 223, 100, 3, 76, 60, 8, 4, 1, 223, 100, 3, 76, 60, 8, 6, 1, 223, + 100, 3, 76, 248, 227, 26, 220, 114, 8, 4, 1, 223, 100, 3, 76, 248, 227, + 26, 220, 114, 8, 6, 1, 223, 100, 3, 222, 76, 60, 8, 4, 1, 223, 100, 3, + 222, 76, 60, 8, 6, 1, 223, 100, 3, 244, 241, 60, 8, 4, 1, 223, 100, 3, + 244, 241, 60, 8, 6, 1, 221, 137, 3, 186, 8, 4, 1, 221, 137, 3, 186, 8, 6, + 1, 221, 137, 3, 76, 57, 8, 4, 1, 221, 137, 3, 76, 57, 8, 6, 1, 221, 137, + 3, 76, 60, 8, 4, 1, 221, 137, 3, 76, 60, 8, 6, 1, 218, 56, 3, 76, 57, 8, + 4, 1, 218, 56, 3, 76, 57, 8, 6, 1, 218, 56, 3, 76, 60, 8, 4, 1, 218, 56, + 3, 76, 60, 8, 6, 1, 218, 56, 3, 222, 76, 60, 8, 4, 1, 218, 56, 3, 222, + 76, 60, 8, 6, 1, 218, 56, 3, 244, 241, 60, 8, 4, 1, 218, 56, 3, 244, 241, + 60, 8, 6, 1, 177, 3, 202, 85, 26, 186, 8, 4, 1, 177, 3, 202, 85, 26, 186, + 8, 6, 1, 177, 3, 202, 85, 26, 239, 150, 8, 4, 1, 177, 3, 202, 85, 26, + 239, 150, 8, 6, 1, 177, 3, 220, 115, 26, 233, 100, 8, 4, 1, 177, 3, 220, + 115, 26, 233, 100, 8, 6, 1, 177, 3, 220, 115, 26, 186, 8, 4, 1, 177, 3, + 220, 115, 26, 186, 8, 6, 1, 214, 4, 3, 186, 8, 4, 1, 214, 4, 3, 186, 8, + 6, 1, 214, 4, 3, 76, 57, 8, 4, 1, 214, 4, 3, 76, 57, 8, 6, 1, 211, 32, 3, + 76, 57, 8, 4, 1, 211, 32, 3, 76, 57, 8, 6, 1, 211, 32, 3, 76, 60, 8, 4, + 1, 211, 32, 3, 76, 60, 8, 6, 1, 211, 32, 3, 76, 248, 227, 26, 220, 114, + 8, 4, 1, 211, 32, 3, 76, 248, 227, 26, 220, 114, 8, 6, 1, 211, 32, 3, + 222, 76, 60, 8, 4, 1, 211, 32, 3, 222, 76, 60, 8, 6, 1, 209, 81, 3, 76, + 57, 8, 4, 1, 209, 81, 3, 76, 57, 8, 6, 1, 209, 81, 3, 76, 60, 8, 4, 1, + 209, 81, 3, 76, 60, 8, 6, 1, 209, 81, 3, 252, 10, 26, 76, 57, 8, 4, 1, + 209, 81, 3, 252, 10, 26, 76, 57, 8, 6, 1, 209, 81, 3, 247, 107, 26, 76, + 57, 8, 4, 1, 209, 81, 3, 247, 107, 26, 76, 57, 8, 6, 1, 209, 81, 3, 76, + 248, 227, 26, 76, 57, 8, 4, 1, 209, 81, 3, 76, 248, 227, 26, 76, 57, 8, + 6, 1, 203, 217, 3, 76, 57, 8, 4, 1, 203, 217, 3, 76, 57, 8, 6, 1, 203, + 217, 3, 76, 60, 8, 4, 1, 203, 217, 3, 76, 60, 8, 6, 1, 203, 217, 3, 222, + 76, 60, 8, 4, 1, 203, 217, 3, 222, 76, 60, 8, 6, 1, 203, 217, 3, 244, + 241, 60, 8, 4, 1, 203, 217, 3, 244, 241, 60, 8, 6, 1, 118, 3, 239, 151, + 60, 8, 4, 1, 118, 3, 239, 151, 60, 8, 6, 1, 118, 3, 202, 85, 60, 8, 4, 1, + 118, 3, 202, 85, 60, 8, 6, 1, 118, 3, 244, 241, 60, 8, 4, 1, 118, 3, 244, + 241, 60, 8, 6, 1, 118, 3, 202, 85, 26, 186, 8, 4, 1, 118, 3, 202, 85, 26, + 186, 8, 6, 1, 118, 3, 220, 115, 26, 239, 150, 8, 4, 1, 118, 3, 220, 115, + 26, 239, 150, 8, 6, 1, 199, 231, 3, 202, 84, 8, 4, 1, 199, 231, 3, 202, + 84, 8, 6, 1, 199, 231, 3, 76, 60, 8, 4, 1, 199, 231, 3, 76, 60, 8, 6, 1, + 197, 200, 3, 233, 100, 8, 4, 1, 197, 200, 3, 233, 100, 8, 6, 1, 197, 200, + 3, 186, 8, 4, 1, 197, 200, 3, 186, 8, 6, 1, 197, 200, 3, 239, 150, 8, 4, + 1, 197, 200, 3, 239, 150, 8, 6, 1, 197, 200, 3, 76, 57, 8, 4, 1, 197, + 200, 3, 76, 57, 8, 6, 1, 197, 200, 3, 76, 60, 8, 4, 1, 197, 200, 3, 76, + 60, 8, 6, 1, 196, 223, 3, 76, 57, 8, 4, 1, 196, 223, 3, 76, 57, 8, 6, 1, + 196, 223, 3, 239, 150, 8, 4, 1, 196, 223, 3, 239, 150, 8, 6, 1, 196, 149, + 3, 76, 57, 8, 4, 1, 196, 149, 3, 76, 57, 8, 6, 1, 195, 159, 3, 244, 240, + 8, 4, 1, 195, 159, 3, 244, 240, 8, 6, 1, 195, 159, 3, 76, 60, 8, 4, 1, + 195, 159, 3, 76, 60, 8, 6, 1, 195, 159, 3, 222, 76, 60, 8, 4, 1, 195, + 159, 3, 222, 76, 60, 8, 4, 1, 233, 16, 3, 222, 76, 60, 8, 4, 1, 203, 217, + 3, 239, 150, 8, 4, 1, 197, 200, 3, 210, 3, 57, 8, 4, 1, 196, 149, 3, 210, + 3, 57, 8, 4, 1, 39, 3, 53, 157, 210, 2, 8, 4, 1, 181, 209, 81, 3, 76, 57, + 8, 4, 1, 181, 209, 81, 3, 239, 147, 106, 8, 4, 1, 181, 209, 81, 3, 130, + 106, 8, 6, 1, 207, 13, 209, 80, 8, 4, 1, 239, 212, 8, 6, 1, 39, 3, 76, + 60, 8, 4, 1, 39, 3, 76, 60, 8, 6, 1, 39, 3, 231, 165, 57, 8, 4, 1, 39, 3, + 231, 165, 57, 8, 6, 1, 39, 3, 244, 241, 26, 186, 8, 4, 1, 39, 3, 244, + 241, 26, 186, 8, 6, 1, 39, 3, 244, 241, 26, 233, 100, 8, 4, 1, 39, 3, + 244, 241, 26, 233, 100, 8, 6, 1, 39, 3, 244, 241, 26, 231, 165, 57, 8, 4, + 1, 39, 3, 244, 241, 26, 231, 165, 57, 8, 6, 1, 39, 3, 244, 241, 26, 202, + 84, 8, 4, 1, 39, 3, 244, 241, 26, 202, 84, 8, 6, 1, 39, 3, 244, 241, 26, + 76, 60, 8, 4, 1, 39, 3, 244, 241, 26, 76, 60, 8, 6, 1, 39, 3, 248, 48, + 26, 186, 8, 4, 1, 39, 3, 248, 48, 26, 186, 8, 6, 1, 39, 3, 248, 48, 26, + 233, 100, 8, 4, 1, 39, 3, 248, 48, 26, 233, 100, 8, 6, 1, 39, 3, 248, 48, + 26, 231, 165, 57, 8, 4, 1, 39, 3, 248, 48, 26, 231, 165, 57, 8, 6, 1, 39, + 3, 248, 48, 26, 202, 84, 8, 4, 1, 39, 3, 248, 48, 26, 202, 84, 8, 6, 1, + 39, 3, 248, 48, 26, 76, 60, 8, 4, 1, 39, 3, 248, 48, 26, 76, 60, 8, 6, 1, + 237, 136, 3, 76, 60, 8, 4, 1, 237, 136, 3, 76, 60, 8, 6, 1, 237, 136, 3, + 231, 165, 57, 8, 4, 1, 237, 136, 3, 231, 165, 57, 8, 6, 1, 237, 136, 3, + 202, 84, 8, 4, 1, 237, 136, 3, 202, 84, 8, 6, 1, 237, 136, 3, 244, 241, + 26, 186, 8, 4, 1, 237, 136, 3, 244, 241, 26, 186, 8, 6, 1, 237, 136, 3, + 244, 241, 26, 233, 100, 8, 4, 1, 237, 136, 3, 244, 241, 26, 233, 100, 8, + 6, 1, 237, 136, 3, 244, 241, 26, 231, 165, 57, 8, 4, 1, 237, 136, 3, 244, + 241, 26, 231, 165, 57, 8, 6, 1, 237, 136, 3, 244, 241, 26, 202, 84, 8, 4, + 1, 237, 136, 3, 244, 241, 26, 202, 84, 8, 6, 1, 237, 136, 3, 244, 241, + 26, 76, 60, 8, 4, 1, 237, 136, 3, 244, 241, 26, 76, 60, 8, 6, 1, 230, + 249, 3, 231, 165, 57, 8, 4, 1, 230, 249, 3, 231, 165, 57, 8, 6, 1, 230, + 249, 3, 76, 60, 8, 4, 1, 230, 249, 3, 76, 60, 8, 6, 1, 177, 3, 76, 60, 8, + 4, 1, 177, 3, 76, 60, 8, 6, 1, 177, 3, 231, 165, 57, 8, 4, 1, 177, 3, + 231, 165, 57, 8, 6, 1, 177, 3, 244, 241, 26, 186, 8, 4, 1, 177, 3, 244, + 241, 26, 186, 8, 6, 1, 177, 3, 244, 241, 26, 233, 100, 8, 4, 1, 177, 3, + 244, 241, 26, 233, 100, 8, 6, 1, 177, 3, 244, 241, 26, 231, 165, 57, 8, + 4, 1, 177, 3, 244, 241, 26, 231, 165, 57, 8, 6, 1, 177, 3, 244, 241, 26, + 202, 84, 8, 4, 1, 177, 3, 244, 241, 26, 202, 84, 8, 6, 1, 177, 3, 244, + 241, 26, 76, 60, 8, 4, 1, 177, 3, 244, 241, 26, 76, 60, 8, 6, 1, 177, 3, + 231, 103, 26, 186, 8, 4, 1, 177, 3, 231, 103, 26, 186, 8, 6, 1, 177, 3, + 231, 103, 26, 233, 100, 8, 4, 1, 177, 3, 231, 103, 26, 233, 100, 8, 6, 1, + 177, 3, 231, 103, 26, 231, 165, 57, 8, 4, 1, 177, 3, 231, 103, 26, 231, + 165, 57, 8, 6, 1, 177, 3, 231, 103, 26, 202, 84, 8, 4, 1, 177, 3, 231, + 103, 26, 202, 84, 8, 6, 1, 177, 3, 231, 103, 26, 76, 60, 8, 4, 1, 177, 3, + 231, 103, 26, 76, 60, 8, 6, 1, 118, 3, 76, 60, 8, 4, 1, 118, 3, 76, 60, + 8, 6, 1, 118, 3, 231, 165, 57, 8, 4, 1, 118, 3, 231, 165, 57, 8, 6, 1, + 118, 3, 231, 103, 26, 186, 8, 4, 1, 118, 3, 231, 103, 26, 186, 8, 6, 1, + 118, 3, 231, 103, 26, 233, 100, 8, 4, 1, 118, 3, 231, 103, 26, 233, 100, + 8, 6, 1, 118, 3, 231, 103, 26, 231, 165, 57, 8, 4, 1, 118, 3, 231, 103, + 26, 231, 165, 57, 8, 6, 1, 118, 3, 231, 103, 26, 202, 84, 8, 4, 1, 118, + 3, 231, 103, 26, 202, 84, 8, 6, 1, 118, 3, 231, 103, 26, 76, 60, 8, 4, 1, + 118, 3, 231, 103, 26, 76, 60, 8, 6, 1, 196, 149, 3, 233, 100, 8, 4, 1, + 196, 149, 3, 233, 100, 8, 6, 1, 196, 149, 3, 76, 60, 8, 4, 1, 196, 149, + 3, 76, 60, 8, 6, 1, 196, 149, 3, 231, 165, 57, 8, 4, 1, 196, 149, 3, 231, + 165, 57, 8, 6, 1, 196, 149, 3, 202, 84, 8, 4, 1, 196, 149, 3, 202, 84, 8, + 6, 1, 219, 62, 222, 38, 8, 4, 1, 219, 62, 222, 38, 8, 6, 1, 219, 62, 199, + 230, 8, 4, 1, 219, 62, 199, 230, 8, 6, 1, 196, 149, 3, 221, 225, 8, 4, 1, + 196, 149, 3, 221, 225, 32, 4, 1, 251, 135, 3, 211, 231, 32, 4, 1, 251, + 135, 3, 240, 62, 32, 4, 1, 251, 135, 3, 211, 232, 26, 199, 133, 32, 4, 1, + 251, 135, 3, 240, 63, 26, 199, 133, 32, 4, 1, 251, 135, 3, 211, 232, 26, + 214, 9, 32, 4, 1, 251, 135, 3, 240, 63, 26, 214, 9, 32, 4, 1, 251, 135, + 3, 211, 232, 26, 213, 38, 32, 4, 1, 251, 135, 3, 240, 63, 26, 213, 38, + 32, 6, 1, 251, 135, 3, 211, 231, 32, 6, 1, 251, 135, 3, 240, 62, 32, 6, + 1, 251, 135, 3, 211, 232, 26, 199, 133, 32, 6, 1, 251, 135, 3, 240, 63, + 26, 199, 133, 32, 6, 1, 251, 135, 3, 211, 232, 26, 214, 9, 32, 6, 1, 251, + 135, 3, 240, 63, 26, 214, 9, 32, 6, 1, 251, 135, 3, 211, 232, 26, 213, + 38, 32, 6, 1, 251, 135, 3, 240, 63, 26, 213, 38, 32, 4, 1, 236, 175, 3, + 211, 231, 32, 4, 1, 236, 175, 3, 240, 62, 32, 4, 1, 236, 175, 3, 211, + 232, 26, 199, 133, 32, 4, 1, 236, 175, 3, 240, 63, 26, 199, 133, 32, 4, + 1, 236, 175, 3, 211, 232, 26, 214, 9, 32, 4, 1, 236, 175, 3, 240, 63, 26, + 214, 9, 32, 6, 1, 236, 175, 3, 211, 231, 32, 6, 1, 236, 175, 3, 240, 62, + 32, 6, 1, 236, 175, 3, 211, 232, 26, 199, 133, 32, 6, 1, 236, 175, 3, + 240, 63, 26, 199, 133, 32, 6, 1, 236, 175, 3, 211, 232, 26, 214, 9, 32, + 6, 1, 236, 175, 3, 240, 63, 26, 214, 9, 32, 4, 1, 236, 127, 3, 211, 231, + 32, 4, 1, 236, 127, 3, 240, 62, 32, 4, 1, 236, 127, 3, 211, 232, 26, 199, + 133, 32, 4, 1, 236, 127, 3, 240, 63, 26, 199, 133, 32, 4, 1, 236, 127, 3, + 211, 232, 26, 214, 9, 32, 4, 1, 236, 127, 3, 240, 63, 26, 214, 9, 32, 4, + 1, 236, 127, 3, 211, 232, 26, 213, 38, 32, 4, 1, 236, 127, 3, 240, 63, + 26, 213, 38, 32, 6, 1, 236, 127, 3, 211, 231, 32, 6, 1, 236, 127, 3, 240, + 62, 32, 6, 1, 236, 127, 3, 211, 232, 26, 199, 133, 32, 6, 1, 236, 127, 3, + 240, 63, 26, 199, 133, 32, 6, 1, 236, 127, 3, 211, 232, 26, 214, 9, 32, + 6, 1, 236, 127, 3, 240, 63, 26, 214, 9, 32, 6, 1, 236, 127, 3, 211, 232, + 26, 213, 38, 32, 6, 1, 236, 127, 3, 240, 63, 26, 213, 38, 32, 4, 1, 226, + 8, 3, 211, 231, 32, 4, 1, 226, 8, 3, 240, 62, 32, 4, 1, 226, 8, 3, 211, + 232, 26, 199, 133, 32, 4, 1, 226, 8, 3, 240, 63, 26, 199, 133, 32, 4, 1, + 226, 8, 3, 211, 232, 26, 214, 9, 32, 4, 1, 226, 8, 3, 240, 63, 26, 214, + 9, 32, 4, 1, 226, 8, 3, 211, 232, 26, 213, 38, 32, 4, 1, 226, 8, 3, 240, + 63, 26, 213, 38, 32, 6, 1, 226, 8, 3, 211, 231, 32, 6, 1, 226, 8, 3, 240, + 62, 32, 6, 1, 226, 8, 3, 211, 232, 26, 199, 133, 32, 6, 1, 226, 8, 3, + 240, 63, 26, 199, 133, 32, 6, 1, 226, 8, 3, 211, 232, 26, 214, 9, 32, 6, + 1, 226, 8, 3, 240, 63, 26, 214, 9, 32, 6, 1, 226, 8, 3, 211, 232, 26, + 213, 38, 32, 6, 1, 226, 8, 3, 240, 63, 26, 213, 38, 32, 4, 1, 214, 123, + 3, 211, 231, 32, 4, 1, 214, 123, 3, 240, 62, 32, 4, 1, 214, 123, 3, 211, + 232, 26, 199, 133, 32, 4, 1, 214, 123, 3, 240, 63, 26, 199, 133, 32, 4, + 1, 214, 123, 3, 211, 232, 26, 214, 9, 32, 4, 1, 214, 123, 3, 240, 63, 26, + 214, 9, 32, 6, 1, 214, 123, 3, 211, 231, 32, 6, 1, 214, 123, 3, 240, 62, + 32, 6, 1, 214, 123, 3, 211, 232, 26, 199, 133, 32, 6, 1, 214, 123, 3, + 240, 63, 26, 199, 133, 32, 6, 1, 214, 123, 3, 211, 232, 26, 214, 9, 32, + 6, 1, 214, 123, 3, 240, 63, 26, 214, 9, 32, 4, 1, 200, 29, 3, 211, 231, + 32, 4, 1, 200, 29, 3, 240, 62, 32, 4, 1, 200, 29, 3, 211, 232, 26, 199, + 133, 32, 4, 1, 200, 29, 3, 240, 63, 26, 199, 133, 32, 4, 1, 200, 29, 3, + 211, 232, 26, 214, 9, 32, 4, 1, 200, 29, 3, 240, 63, 26, 214, 9, 32, 4, + 1, 200, 29, 3, 211, 232, 26, 213, 38, 32, 4, 1, 200, 29, 3, 240, 63, 26, + 213, 38, 32, 6, 1, 200, 29, 3, 240, 62, 32, 6, 1, 200, 29, 3, 240, 63, + 26, 199, 133, 32, 6, 1, 200, 29, 3, 240, 63, 26, 214, 9, 32, 6, 1, 200, + 29, 3, 240, 63, 26, 213, 38, 32, 4, 1, 214, 125, 3, 211, 231, 32, 4, 1, + 214, 125, 3, 240, 62, 32, 4, 1, 214, 125, 3, 211, 232, 26, 199, 133, 32, + 4, 1, 214, 125, 3, 240, 63, 26, 199, 133, 32, 4, 1, 214, 125, 3, 211, + 232, 26, 214, 9, 32, 4, 1, 214, 125, 3, 240, 63, 26, 214, 9, 32, 4, 1, + 214, 125, 3, 211, 232, 26, 213, 38, 32, 4, 1, 214, 125, 3, 240, 63, 26, + 213, 38, 32, 6, 1, 214, 125, 3, 211, 231, 32, 6, 1, 214, 125, 3, 240, 62, + 32, 6, 1, 214, 125, 3, 211, 232, 26, 199, 133, 32, 6, 1, 214, 125, 3, + 240, 63, 26, 199, 133, 32, 6, 1, 214, 125, 3, 211, 232, 26, 214, 9, 32, + 6, 1, 214, 125, 3, 240, 63, 26, 214, 9, 32, 6, 1, 214, 125, 3, 211, 232, + 26, 213, 38, 32, 6, 1, 214, 125, 3, 240, 63, 26, 213, 38, 32, 4, 1, 251, + 135, 3, 199, 133, 32, 4, 1, 251, 135, 3, 214, 9, 32, 4, 1, 236, 175, 3, + 199, 133, 32, 4, 1, 236, 175, 3, 214, 9, 32, 4, 1, 236, 127, 3, 199, 133, + 32, 4, 1, 236, 127, 3, 214, 9, 32, 4, 1, 226, 8, 3, 199, 133, 32, 4, 1, + 226, 8, 3, 214, 9, 32, 4, 1, 214, 123, 3, 199, 133, 32, 4, 1, 214, 123, + 3, 214, 9, 32, 4, 1, 200, 29, 3, 199, 133, 32, 4, 1, 200, 29, 3, 214, 9, + 32, 4, 1, 214, 125, 3, 199, 133, 32, 4, 1, 214, 125, 3, 214, 9, 32, 4, 1, + 251, 135, 3, 211, 232, 26, 195, 225, 32, 4, 1, 251, 135, 3, 240, 63, 26, + 195, 225, 32, 4, 1, 251, 135, 3, 211, 232, 26, 199, 134, 26, 195, 225, + 32, 4, 1, 251, 135, 3, 240, 63, 26, 199, 134, 26, 195, 225, 32, 4, 1, + 251, 135, 3, 211, 232, 26, 214, 10, 26, 195, 225, 32, 4, 1, 251, 135, 3, + 240, 63, 26, 214, 10, 26, 195, 225, 32, 4, 1, 251, 135, 3, 211, 232, 26, + 213, 39, 26, 195, 225, 32, 4, 1, 251, 135, 3, 240, 63, 26, 213, 39, 26, + 195, 225, 32, 6, 1, 251, 135, 3, 211, 232, 26, 211, 245, 32, 6, 1, 251, + 135, 3, 240, 63, 26, 211, 245, 32, 6, 1, 251, 135, 3, 211, 232, 26, 199, + 134, 26, 211, 245, 32, 6, 1, 251, 135, 3, 240, 63, 26, 199, 134, 26, 211, + 245, 32, 6, 1, 251, 135, 3, 211, 232, 26, 214, 10, 26, 211, 245, 32, 6, + 1, 251, 135, 3, 240, 63, 26, 214, 10, 26, 211, 245, 32, 6, 1, 251, 135, + 3, 211, 232, 26, 213, 39, 26, 211, 245, 32, 6, 1, 251, 135, 3, 240, 63, + 26, 213, 39, 26, 211, 245, 32, 4, 1, 236, 127, 3, 211, 232, 26, 195, 225, + 32, 4, 1, 236, 127, 3, 240, 63, 26, 195, 225, 32, 4, 1, 236, 127, 3, 211, + 232, 26, 199, 134, 26, 195, 225, 32, 4, 1, 236, 127, 3, 240, 63, 26, 199, + 134, 26, 195, 225, 32, 4, 1, 236, 127, 3, 211, 232, 26, 214, 10, 26, 195, + 225, 32, 4, 1, 236, 127, 3, 240, 63, 26, 214, 10, 26, 195, 225, 32, 4, 1, + 236, 127, 3, 211, 232, 26, 213, 39, 26, 195, 225, 32, 4, 1, 236, 127, 3, + 240, 63, 26, 213, 39, 26, 195, 225, 32, 6, 1, 236, 127, 3, 211, 232, 26, + 211, 245, 32, 6, 1, 236, 127, 3, 240, 63, 26, 211, 245, 32, 6, 1, 236, + 127, 3, 211, 232, 26, 199, 134, 26, 211, 245, 32, 6, 1, 236, 127, 3, 240, + 63, 26, 199, 134, 26, 211, 245, 32, 6, 1, 236, 127, 3, 211, 232, 26, 214, + 10, 26, 211, 245, 32, 6, 1, 236, 127, 3, 240, 63, 26, 214, 10, 26, 211, + 245, 32, 6, 1, 236, 127, 3, 211, 232, 26, 213, 39, 26, 211, 245, 32, 6, + 1, 236, 127, 3, 240, 63, 26, 213, 39, 26, 211, 245, 32, 4, 1, 214, 125, + 3, 211, 232, 26, 195, 225, 32, 4, 1, 214, 125, 3, 240, 63, 26, 195, 225, + 32, 4, 1, 214, 125, 3, 211, 232, 26, 199, 134, 26, 195, 225, 32, 4, 1, + 214, 125, 3, 240, 63, 26, 199, 134, 26, 195, 225, 32, 4, 1, 214, 125, 3, + 211, 232, 26, 214, 10, 26, 195, 225, 32, 4, 1, 214, 125, 3, 240, 63, 26, + 214, 10, 26, 195, 225, 32, 4, 1, 214, 125, 3, 211, 232, 26, 213, 39, 26, + 195, 225, 32, 4, 1, 214, 125, 3, 240, 63, 26, 213, 39, 26, 195, 225, 32, + 6, 1, 214, 125, 3, 211, 232, 26, 211, 245, 32, 6, 1, 214, 125, 3, 240, + 63, 26, 211, 245, 32, 6, 1, 214, 125, 3, 211, 232, 26, 199, 134, 26, 211, + 245, 32, 6, 1, 214, 125, 3, 240, 63, 26, 199, 134, 26, 211, 245, 32, 6, + 1, 214, 125, 3, 211, 232, 26, 214, 10, 26, 211, 245, 32, 6, 1, 214, 125, + 3, 240, 63, 26, 214, 10, 26, 211, 245, 32, 6, 1, 214, 125, 3, 211, 232, + 26, 213, 39, 26, 211, 245, 32, 6, 1, 214, 125, 3, 240, 63, 26, 213, 39, + 26, 211, 245, 32, 4, 1, 251, 135, 3, 198, 224, 32, 4, 1, 251, 135, 3, + 220, 114, 32, 4, 1, 251, 135, 3, 199, 134, 26, 195, 225, 32, 4, 1, 251, + 135, 3, 195, 225, 32, 4, 1, 251, 135, 3, 214, 10, 26, 195, 225, 32, 4, 1, + 251, 135, 3, 213, 38, 32, 4, 1, 251, 135, 3, 213, 39, 26, 195, 225, 32, + 6, 1, 251, 135, 3, 198, 224, 32, 6, 1, 251, 135, 3, 220, 114, 32, 6, 1, + 251, 135, 3, 199, 133, 32, 6, 1, 251, 135, 3, 214, 9, 32, 6, 1, 251, 135, + 3, 211, 245, 32, 223, 232, 32, 211, 245, 32, 211, 231, 32, 213, 38, 32, + 239, 144, 26, 213, 38, 32, 4, 1, 236, 127, 3, 199, 134, 26, 195, 225, 32, + 4, 1, 236, 127, 3, 195, 225, 32, 4, 1, 236, 127, 3, 214, 10, 26, 195, + 225, 32, 4, 1, 236, 127, 3, 213, 38, 32, 4, 1, 236, 127, 3, 213, 39, 26, + 195, 225, 32, 6, 1, 236, 175, 3, 199, 133, 32, 6, 1, 236, 175, 3, 214, 9, + 32, 6, 1, 236, 127, 3, 199, 133, 32, 6, 1, 236, 127, 3, 214, 9, 32, 6, 1, + 236, 127, 3, 211, 245, 32, 211, 232, 26, 199, 133, 32, 211, 232, 26, 214, + 9, 32, 211, 232, 26, 213, 38, 32, 4, 1, 226, 8, 3, 198, 224, 32, 4, 1, + 226, 8, 3, 220, 114, 32, 4, 1, 226, 8, 3, 239, 144, 26, 199, 133, 32, 4, + 1, 226, 8, 3, 239, 144, 26, 214, 9, 32, 4, 1, 226, 8, 3, 213, 38, 32, 4, + 1, 226, 8, 3, 239, 144, 26, 213, 38, 32, 6, 1, 226, 8, 3, 198, 224, 32, + 6, 1, 226, 8, 3, 220, 114, 32, 6, 1, 226, 8, 3, 199, 133, 32, 6, 1, 226, + 8, 3, 214, 9, 32, 240, 63, 26, 199, 133, 32, 240, 63, 26, 214, 9, 32, + 240, 63, 26, 213, 38, 32, 4, 1, 200, 29, 3, 198, 224, 32, 4, 1, 200, 29, + 3, 220, 114, 32, 4, 1, 200, 29, 3, 239, 144, 26, 199, 133, 32, 4, 1, 200, + 29, 3, 239, 144, 26, 214, 9, 32, 4, 1, 210, 75, 3, 211, 231, 32, 4, 1, + 210, 75, 3, 240, 62, 32, 4, 1, 200, 29, 3, 213, 38, 32, 4, 1, 200, 29, 3, + 239, 144, 26, 213, 38, 32, 6, 1, 200, 29, 3, 198, 224, 32, 6, 1, 200, 29, + 3, 220, 114, 32, 6, 1, 200, 29, 3, 199, 133, 32, 6, 1, 200, 29, 3, 214, + 9, 32, 6, 1, 210, 75, 3, 240, 62, 32, 239, 144, 26, 199, 133, 32, 239, + 144, 26, 214, 9, 32, 199, 133, 32, 4, 1, 214, 125, 3, 199, 134, 26, 195, + 225, 32, 4, 1, 214, 125, 3, 195, 225, 32, 4, 1, 214, 125, 3, 214, 10, 26, + 195, 225, 32, 4, 1, 214, 125, 3, 213, 38, 32, 4, 1, 214, 125, 3, 213, 39, + 26, 195, 225, 32, 6, 1, 214, 123, 3, 199, 133, 32, 6, 1, 214, 123, 3, + 214, 9, 32, 6, 1, 214, 125, 3, 199, 133, 32, 6, 1, 214, 125, 3, 214, 9, + 32, 6, 1, 214, 125, 3, 211, 245, 32, 214, 9, 32, 240, 62, 236, 231, 211, + 94, 236, 242, 211, 94, 236, 231, 205, 148, 236, 242, 205, 148, 202, 148, + 205, 148, 235, 5, 205, 148, 206, 27, 205, 148, 235, 143, 205, 148, 211, + 214, 205, 148, 202, 188, 205, 148, 232, 234, 205, 148, 195, 80, 197, 59, + 205, 148, 195, 80, 197, 59, 216, 36, 195, 80, 197, 59, 225, 124, 222, + 175, 78, 210, 13, 78, 231, 7, 216, 37, 231, 7, 235, 143, 240, 65, 236, + 231, 240, 65, 236, 242, 240, 65, 231, 155, 154, 52, 83, 222, 75, 52, 126, + 222, 75, 50, 206, 62, 211, 62, 78, 53, 206, 62, 211, 62, 78, 206, 62, + 221, 207, 211, 62, 78, 206, 62, 232, 45, 211, 62, 78, 50, 52, 211, 62, + 78, 53, 52, 211, 62, 78, 52, 221, 207, 211, 62, 78, 52, 232, 45, 211, 62, + 78, 240, 118, 52, 240, 118, 248, 5, 201, 177, 248, 5, 97, 76, 222, 195, + 99, 76, 222, 195, 231, 155, 236, 247, 231, 5, 212, 110, 222, 76, 207, 90, + 213, 154, 207, 90, 222, 175, 236, 240, 210, 13, 236, 240, 212, 88, 239, + 84, 235, 22, 222, 175, 214, 17, 210, 13, 214, 17, 217, 210, 216, 44, 205, + 148, 213, 46, 219, 29, 55, 213, 46, 203, 24, 202, 159, 55, 212, 19, 52, + 212, 19, 201, 165, 212, 19, 210, 89, 212, 19, 210, 89, 52, 212, 19, 210, + 89, 201, 165, 212, 19, 247, 110, 206, 62, 222, 179, 251, 91, 211, 62, 78, + 206, 62, 210, 17, 251, 91, 211, 62, 78, 210, 154, 78, 52, 236, 90, 78, + 226, 26, 214, 19, 200, 59, 190, 202, 107, 247, 111, 226, 43, 212, 110, + 250, 177, 231, 8, 248, 5, 191, 205, 248, 50, 47, 248, 62, 3, 211, 73, 53, + 47, 248, 62, 3, 211, 73, 52, 211, 79, 78, 211, 79, 236, 90, 78, 236, 90, + 211, 79, 78, 202, 60, 2, 236, 128, 210, 89, 212, 179, 55, 58, 107, 248, + 5, 58, 91, 248, 5, 126, 250, 179, 210, 89, 207, 105, 244, 204, 200, 36, + 99, 250, 178, 251, 150, 199, 49, 244, 157, 219, 16, 55, 204, 46, 240, 65, + 226, 17, 200, 59, 235, 63, 211, 214, 78, 115, 76, 211, 213, 211, 90, 212, + 19, 235, 7, 76, 211, 213, 235, 101, 76, 211, 213, 99, 76, 211, 213, 235, + 7, 76, 78, 237, 250, 241, 61, 201, 176, 83, 235, 7, 238, 250, 219, 190, + 13, 205, 148, 197, 9, 225, 124, 234, 215, 251, 25, 226, 15, 202, 76, 226, + 15, 207, 90, 226, 15, 212, 125, 222, 175, 225, 240, 210, 13, 225, 240, + 235, 113, 204, 182, 225, 240, 212, 88, 239, 84, 225, 240, 226, 56, 203, + 248, 204, 64, 252, 12, 203, 248, 204, 64, 226, 56, 9, 235, 24, 207, 19, + 252, 12, 9, 235, 24, 207, 19, 217, 204, 17, 207, 20, 216, 40, 17, 207, + 20, 204, 95, 195, 79, 204, 95, 8, 4, 1, 68, 204, 95, 136, 204, 95, 146, + 204, 95, 167, 204, 95, 178, 204, 95, 171, 204, 95, 182, 204, 95, 98, 55, + 204, 95, 219, 15, 204, 95, 236, 172, 55, 204, 95, 50, 213, 140, 204, 95, + 53, 213, 140, 204, 95, 8, 4, 1, 218, 55, 204, 143, 195, 79, 204, 143, + 100, 204, 143, 102, 204, 143, 134, 204, 143, 136, 204, 143, 146, 204, + 143, 167, 204, 143, 178, 204, 143, 171, 204, 143, 182, 204, 143, 98, 55, + 204, 143, 219, 15, 204, 143, 236, 172, 55, 204, 143, 50, 213, 140, 204, + 143, 53, 213, 140, 8, 204, 143, 4, 1, 63, 8, 204, 143, 4, 1, 69, 8, 204, + 143, 4, 1, 72, 8, 204, 143, 4, 1, 196, 222, 8, 204, 143, 4, 1, 208, 163, + 8, 204, 143, 4, 1, 233, 15, 8, 204, 143, 4, 1, 225, 80, 8, 204, 143, 4, + 1, 159, 8, 204, 143, 4, 1, 221, 136, 8, 204, 143, 4, 1, 218, 55, 8, 204, + 143, 4, 1, 214, 3, 8, 204, 143, 4, 1, 209, 80, 8, 204, 143, 4, 1, 203, + 216, 236, 107, 55, 244, 169, 55, 241, 46, 55, 234, 243, 234, 248, 55, + 222, 55, 55, 219, 30, 55, 217, 228, 55, 213, 23, 55, 209, 108, 55, 197, + 17, 55, 217, 83, 206, 241, 55, 239, 5, 55, 236, 108, 55, 224, 70, 55, + 201, 27, 55, 237, 228, 55, 234, 21, 213, 58, 55, 213, 20, 55, 233, 71, + 55, 250, 140, 55, 231, 81, 55, 247, 52, 55, 222, 45, 201, 223, 55, 205, + 128, 55, 203, 21, 55, 226, 71, 209, 108, 55, 201, 6, 222, 55, 55, 216, + 26, 117, 55, 220, 60, 55, 209, 131, 55, 222, 224, 55, 248, 144, 55, 38, + 50, 232, 169, 57, 38, 53, 232, 169, 57, 38, 181, 83, 222, 76, 214, 20, + 38, 206, 182, 83, 222, 76, 214, 20, 38, 251, 65, 61, 57, 38, 244, 205, + 61, 57, 38, 50, 61, 57, 38, 53, 61, 57, 38, 210, 3, 214, 20, 38, 244, + 205, 210, 3, 214, 20, 38, 251, 65, 210, 3, 214, 20, 38, 115, 238, 251, + 57, 38, 235, 7, 238, 251, 57, 38, 236, 226, 244, 249, 38, 236, 226, 205, + 94, 38, 236, 226, 239, 140, 38, 236, 226, 244, 250, 249, 133, 38, 50, 53, + 61, 57, 38, 236, 226, 208, 154, 38, 236, 226, 224, 149, 38, 236, 226, + 200, 26, 212, 107, 201, 180, 38, 210, 90, 205, 178, 214, 20, 38, 52, 83, + 204, 196, 214, 20, 38, 251, 75, 105, 38, 201, 165, 200, 61, 38, 197, 62, + 248, 40, 57, 38, 107, 61, 214, 20, 38, 181, 52, 205, 178, 214, 20, 38, + 91, 232, 169, 3, 165, 237, 230, 38, 107, 232, 169, 3, 165, 237, 230, 38, + 50, 61, 60, 38, 53, 61, 60, 38, 250, 180, 57, 252, 18, 214, 159, 252, 2, + 202, 30, 202, 218, 204, 153, 237, 241, 6, 247, 207, 239, 231, 247, 42, + 247, 37, 222, 76, 105, 247, 112, 214, 159, 247, 166, 200, 71, 236, 109, + 241, 137, 208, 151, 239, 231, 235, 221, 145, 4, 234, 190, 145, 6, 233, + 15, 248, 134, 6, 233, 15, 237, 241, 6, 233, 15, 212, 144, 241, 137, 212, + 144, 241, 138, 127, 99, 212, 220, 145, 6, 68, 248, 134, 6, 68, 145, 6, + 159, 145, 4, 159, 223, 100, 74, 249, 80, 105, 237, 241, 6, 218, 55, 215, + 140, 55, 205, 162, 210, 166, 241, 104, 145, 6, 214, 3, 237, 241, 6, 214, + 3, 237, 241, 6, 211, 167, 145, 6, 144, 248, 134, 6, 144, 237, 241, 6, + 144, 212, 27, 203, 128, 210, 102, 207, 81, 78, 203, 34, 55, 201, 213, + 117, 55, 199, 101, 237, 241, 6, 195, 158, 214, 38, 55, 214, 148, 55, 226, + 17, 214, 148, 55, 248, 134, 6, 195, 158, 163, 32, 4, 1, 226, 7, 224, 190, + 55, 251, 85, 55, 145, 6, 250, 112, 248, 134, 6, 247, 207, 236, 133, 105, + 145, 4, 69, 145, 6, 69, 145, 6, 236, 49, 163, 6, 236, 49, 145, 6, 221, + 136, 145, 4, 72, 151, 105, 248, 209, 105, 233, 178, 105, 240, 102, 105, + 226, 61, 205, 160, 209, 194, 6, 211, 167, 235, 224, 55, 237, 241, 4, 212, + 220, 237, 241, 4, 234, 94, 237, 241, 6, 234, 94, 237, 241, 6, 212, 220, + 237, 241, 218, 54, 204, 114, 163, 45, 6, 234, 190, 163, 45, 6, 159, 210, + 89, 45, 6, 159, 163, 45, 6, 196, 148, 237, 241, 41, 6, 240, 231, 237, + 241, 41, 4, 240, 231, 237, 241, 41, 4, 69, 237, 241, 41, 4, 68, 237, 241, + 41, 4, 225, 217, 211, 249, 222, 75, 163, 251, 111, 213, 46, 55, 251, 175, + 163, 4, 236, 49, 16, 36, 208, 228, 205, 160, 197, 217, 191, 97, 207, 67, + 197, 217, 191, 97, 216, 173, 197, 217, 191, 97, 203, 14, 197, 217, 191, + 97, 202, 184, 197, 217, 191, 99, 202, 181, 197, 217, 191, 97, 235, 148, + 197, 217, 191, 99, 235, 147, 197, 217, 191, 115, 235, 147, 197, 217, 191, + 235, 7, 235, 147, 197, 217, 191, 97, 206, 17, 197, 217, 191, 235, 101, + 206, 15, 197, 217, 191, 97, 237, 26, 197, 217, 191, 115, 237, 24, 197, + 217, 191, 235, 101, 237, 24, 197, 217, 191, 207, 71, 237, 24, 191, 215, + 141, 100, 209, 208, 215, 142, 100, 209, 208, 215, 142, 102, 209, 208, + 215, 142, 134, 209, 208, 215, 142, 136, 209, 208, 215, 142, 146, 209, + 208, 215, 142, 167, 209, 208, 215, 142, 178, 209, 208, 215, 142, 171, + 209, 208, 215, 142, 182, 209, 208, 215, 142, 203, 23, 209, 208, 215, 142, + 236, 252, 209, 208, 215, 142, 200, 239, 209, 208, 215, 142, 235, 145, + 209, 208, 215, 142, 97, 231, 57, 209, 208, 215, 142, 235, 101, 231, 57, + 209, 208, 215, 142, 97, 170, 4, 209, 208, 215, 142, 100, 4, 209, 208, + 215, 142, 102, 4, 209, 208, 215, 142, 134, 4, 209, 208, 215, 142, 136, 4, + 209, 208, 215, 142, 146, 4, 209, 208, 215, 142, 167, 4, 209, 208, 215, + 142, 178, 4, 209, 208, 215, 142, 171, 4, 209, 208, 215, 142, 182, 4, 209, + 208, 215, 142, 203, 23, 4, 209, 208, 215, 142, 236, 252, 4, 209, 208, + 215, 142, 200, 239, 4, 209, 208, 215, 142, 235, 145, 4, 209, 208, 215, + 142, 97, 231, 57, 4, 209, 208, 215, 142, 235, 101, 231, 57, 4, 209, 208, + 215, 142, 97, 170, 209, 208, 215, 142, 97, 202, 159, 247, 208, 240, 231, + 209, 208, 215, 142, 235, 101, 170, 209, 208, 215, 142, 203, 24, 170, 209, + 208, 215, 142, 210, 89, 97, 231, 57, 8, 4, 1, 210, 89, 247, 207, 209, + 208, 215, 142, 206, 29, 222, 219, 20, 209, 208, 215, 142, 235, 146, 237, + 75, 20, 209, 208, 215, 142, 235, 146, 170, 209, 208, 215, 142, 97, 231, + 58, 170, 197, 217, 191, 195, 80, 202, 181, 163, 17, 102, 163, 17, 134, + 107, 51, 200, 24, 51, 91, 51, 237, 231, 51, 50, 53, 51, 124, 135, 51, + 173, 197, 89, 51, 173, 237, 69, 51, 205, 159, 237, 69, 51, 205, 159, 197, + 89, 51, 107, 61, 3, 106, 91, 61, 3, 106, 107, 197, 123, 51, 91, 197, 123, + 51, 107, 99, 232, 135, 51, 200, 24, 99, 232, 135, 51, 91, 99, 232, 135, + 51, 237, 231, 99, 232, 135, 51, 107, 61, 3, 203, 135, 91, 61, 3, 203, + 135, 107, 61, 234, 235, 154, 200, 24, 61, 234, 235, 154, 91, 61, 234, + 235, 154, 237, 231, 61, 234, 235, 154, 124, 135, 61, 3, 249, 66, 107, 61, + 3, 122, 91, 61, 3, 122, 107, 61, 3, 221, 225, 91, 61, 3, 221, 225, 50, + 53, 197, 123, 51, 50, 53, 61, 3, 106, 237, 231, 195, 24, 51, 200, 24, 61, + 3, 202, 68, 222, 174, 200, 24, 61, 3, 202, 68, 210, 11, 237, 231, 61, 3, + 202, 68, 222, 174, 237, 231, 61, 3, 202, 68, 210, 11, 91, 61, 3, 241, + 102, 237, 230, 237, 231, 61, 3, 241, 102, 222, 174, 251, 65, 201, 243, + 207, 108, 51, 244, 205, 201, 243, 207, 108, 51, 173, 197, 89, 61, 202, + 30, 181, 154, 107, 61, 202, 30, 249, 80, 127, 91, 61, 202, 30, 154, 251, + 65, 192, 244, 250, 51, 244, 205, 192, 244, 250, 51, 107, 232, 169, 3, + 165, 200, 23, 107, 232, 169, 3, 165, 237, 230, 200, 24, 232, 169, 3, 165, + 210, 11, 200, 24, 232, 169, 3, 165, 222, 174, 91, 232, 169, 3, 165, 200, + 23, 91, 232, 169, 3, 165, 237, 230, 237, 231, 232, 169, 3, 165, 210, 11, + 237, 231, 232, 169, 3, 165, 222, 174, 91, 61, 127, 107, 51, 200, 24, 61, + 107, 77, 237, 231, 51, 107, 61, 127, 91, 51, 107, 213, 219, 250, 214, + 200, 24, 213, 219, 250, 214, 91, 213, 219, 250, 214, 237, 231, 213, 219, + 250, 214, 107, 232, 169, 127, 91, 232, 168, 91, 232, 169, 127, 107, 232, + 168, 107, 52, 61, 3, 106, 50, 53, 52, 61, 3, 106, 91, 52, 61, 3, 106, + 107, 52, 51, 200, 24, 52, 51, 91, 52, 51, 237, 231, 52, 51, 50, 53, 52, + 51, 124, 135, 52, 51, 173, 197, 89, 52, 51, 173, 237, 69, 52, 51, 205, + 159, 237, 69, 52, 51, 205, 159, 197, 89, 52, 51, 107, 201, 165, 51, 91, + 201, 165, 51, 107, 205, 87, 51, 91, 205, 87, 51, 200, 24, 61, 3, 52, 106, + 237, 231, 61, 3, 52, 106, 107, 240, 64, 51, 200, 24, 240, 64, 51, 91, + 240, 64, 51, 237, 231, 240, 64, 51, 107, 61, 202, 30, 154, 91, 61, 202, + 30, 154, 107, 59, 51, 200, 24, 59, 51, 91, 59, 51, 237, 231, 59, 51, 200, + 24, 59, 61, 234, 235, 154, 200, 24, 59, 61, 214, 120, 213, 82, 200, 24, + 59, 61, 214, 120, 213, 83, 3, 231, 155, 154, 200, 24, 59, 61, 214, 120, + 213, 83, 3, 83, 154, 200, 24, 59, 52, 51, 200, 24, 59, 52, 61, 214, 120, + 213, 82, 91, 59, 61, 234, 235, 197, 148, 173, 197, 89, 61, 202, 30, 241, + 101, 205, 159, 237, 69, 61, 202, 30, 241, 101, 124, 135, 59, 51, 53, 61, + 3, 4, 244, 249, 237, 231, 61, 107, 77, 200, 24, 51, 115, 91, 250, 214, + 107, 61, 3, 83, 106, 91, 61, 3, 83, 106, 50, 53, 61, 3, 83, 106, 107, 61, + 3, 52, 83, 106, 91, 61, 3, 52, 83, 106, 50, 53, 61, 3, 52, 83, 106, 107, + 214, 90, 51, 91, 214, 90, 51, 50, 53, 214, 90, 51, 36, 251, 146, 244, + 153, 213, 132, 239, 124, 202, 208, 236, 85, 202, 208, 239, 19, 216, 19, + 236, 86, 236, 232, 207, 76, 226, 75, 217, 239, 237, 0, 214, 159, 216, 19, + 251, 107, 237, 0, 214, 159, 4, 237, 0, 214, 159, 241, 131, 250, 203, 219, + 168, 239, 19, 216, 19, 241, 133, 250, 203, 219, 168, 4, 241, 131, 250, + 203, 219, 168, 236, 222, 77, 211, 251, 218, 54, 212, 5, 218, 54, 241, + 108, 218, 54, 204, 114, 219, 16, 55, 219, 14, 55, 76, 212, 125, 239, 54, + 205, 248, 207, 77, 219, 15, 250, 180, 214, 82, 210, 3, 214, 82, 248, 6, + 214, 82, 47, 209, 200, 241, 37, 209, 200, 235, 0, 209, 200, 211, 247, + 149, 226, 63, 53, 251, 90, 251, 90, 219, 201, 251, 90, 205, 127, 251, 90, + 239, 57, 239, 19, 216, 19, 239, 61, 213, 146, 149, 216, 19, 213, 146, + 149, 221, 249, 251, 100, 221, 249, 214, 72, 226, 23, 200, 51, 226, 37, + 52, 226, 37, 201, 165, 226, 37, 241, 125, 226, 37, 204, 84, 226, 37, 198, + 236, 226, 37, 244, 205, 226, 37, 244, 205, 241, 125, 226, 37, 251, 65, + 241, 125, 226, 37, 202, 207, 248, 253, 210, 194, 211, 248, 76, 219, 15, + 236, 93, 234, 27, 211, 248, 231, 170, 202, 85, 214, 82, 210, 89, 202, 84, + 226, 17, 222, 204, 209, 80, 206, 64, 197, 122, 196, 253, 212, 5, 216, 19, + 202, 84, 219, 16, 202, 84, 250, 172, 180, 149, 216, 19, 250, 172, 180, + 149, 251, 21, 180, 149, 251, 21, 247, 232, 216, 19, 252, 11, 180, 149, + 217, 103, 251, 21, 216, 28, 252, 11, 180, 149, 251, 139, 180, 149, 216, + 19, 251, 139, 180, 149, 251, 139, 180, 214, 73, 180, 149, 201, 165, 202, + 84, 251, 147, 180, 149, 236, 165, 149, 234, 26, 236, 165, 149, 239, 125, + 248, 203, 251, 23, 202, 218, 222, 83, 234, 26, 180, 149, 251, 21, 180, + 202, 30, 214, 73, 202, 218, 226, 102, 214, 159, 226, 102, 77, 214, 73, + 251, 21, 180, 149, 244, 169, 236, 171, 236, 172, 244, 168, 210, 3, 226, + 87, 180, 149, 210, 3, 180, 149, 241, 94, 149, 236, 132, 236, 170, 149, + 205, 8, 236, 171, 239, 213, 180, 149, 180, 202, 30, 247, 219, 239, 232, + 219, 201, 247, 218, 211, 77, 180, 149, 216, 19, 180, 149, 230, 193, 149, + 216, 19, 230, 193, 149, 204, 203, 236, 165, 149, 222, 140, 214, 73, 180, + 149, 233, 94, 214, 73, 180, 149, 222, 140, 127, 180, 149, 233, 94, 127, + 180, 149, 222, 140, 247, 232, 216, 19, 180, 149, 233, 94, 247, 232, 216, + 19, 180, 149, 218, 135, 222, 139, 218, 135, 233, 93, 248, 203, 216, 19, + 236, 165, 149, 216, 19, 222, 139, 216, 19, 233, 93, 217, 103, 222, 140, + 216, 28, 180, 149, 217, 103, 233, 94, 216, 28, 180, 149, 222, 140, 214, + 73, 236, 165, 149, 233, 94, 214, 73, 236, 165, 149, 217, 103, 222, 140, + 216, 28, 236, 165, 149, 217, 103, 233, 94, 216, 28, 236, 165, 149, 222, + 140, 214, 73, 233, 93, 233, 94, 214, 73, 222, 139, 217, 103, 222, 140, + 216, 28, 233, 93, 217, 103, 233, 94, 216, 28, 222, 139, 212, 35, 204, + 133, 212, 36, 214, 73, 180, 149, 204, 134, 214, 73, 180, 149, 212, 36, + 214, 73, 236, 165, 149, 204, 134, 214, 73, 236, 165, 149, 239, 19, 216, + 19, 212, 38, 239, 19, 216, 19, 204, 135, 204, 142, 214, 159, 204, 94, + 214, 159, 216, 19, 39, 204, 142, 214, 159, 216, 19, 39, 204, 94, 214, + 159, 204, 142, 77, 214, 73, 180, 149, 204, 94, 77, 214, 73, 180, 149, + 217, 103, 39, 204, 142, 77, 216, 28, 180, 149, 217, 103, 39, 204, 94, 77, + 216, 28, 180, 149, 204, 142, 77, 3, 216, 19, 180, 149, 204, 94, 77, 3, + 216, 19, 180, 149, 218, 115, 218, 116, 218, 117, 218, 116, 200, 51, 47, + 226, 102, 214, 159, 47, 214, 63, 214, 159, 47, 226, 102, 77, 214, 73, + 180, 149, 47, 214, 63, 77, 214, 73, 180, 149, 47, 247, 125, 47, 241, 27, + 46, 212, 125, 46, 219, 15, 46, 202, 76, 46, 239, 54, 205, 248, 46, 76, + 214, 82, 46, 210, 3, 214, 82, 46, 250, 180, 214, 82, 46, 236, 171, 46, + 240, 65, 103, 212, 125, 103, 219, 15, 103, 202, 76, 103, 76, 214, 82, 53, + 203, 147, 50, 203, 147, 135, 203, 147, 124, 203, 147, 250, 183, 218, 240, + 201, 142, 235, 30, 201, 165, 83, 249, 80, 53, 201, 3, 52, 83, 249, 80, + 52, 53, 201, 3, 239, 19, 216, 19, 211, 241, 216, 19, 201, 142, 239, 19, + 216, 19, 235, 31, 217, 106, 52, 83, 249, 80, 52, 53, 201, 3, 212, 36, + 200, 64, 210, 136, 204, 134, 200, 64, 210, 136, 216, 25, 204, 156, 214, + 159, 241, 131, 250, 203, 216, 25, 204, 155, 216, 25, 204, 156, 77, 214, + 73, 180, 149, 241, 131, 250, 203, 216, 25, 204, 156, 214, 73, 180, 149, + 214, 63, 214, 159, 226, 102, 214, 159, 218, 122, 232, 92, 241, 142, 220, + 1, 226, 34, 196, 181, 217, 219, 216, 27, 53, 251, 91, 3, 250, 253, 53, + 201, 180, 218, 54, 221, 249, 251, 100, 218, 54, 221, 249, 214, 72, 218, + 54, 226, 23, 218, 54, 200, 51, 239, 141, 214, 82, 76, 214, 82, 205, 8, + 214, 82, 239, 54, 202, 76, 248, 71, 50, 216, 25, 235, 223, 207, 104, 212, + 5, 53, 216, 25, 235, 223, 207, 104, 212, 5, 50, 207, 104, 212, 5, 53, + 207, 104, 212, 5, 210, 89, 202, 85, 236, 171, 241, 18, 221, 249, 214, 72, + 241, 18, 221, 249, 251, 100, 52, 204, 141, 52, 204, 93, 52, 226, 23, 52, + 200, 51, 212, 155, 180, 26, 213, 146, 149, 222, 140, 3, 238, 253, 233, + 94, 3, 238, 253, 199, 48, 218, 135, 222, 139, 199, 48, 218, 135, 233, 93, + 222, 140, 180, 202, 30, 214, 73, 233, 93, 233, 94, 180, 202, 30, 214, 73, + 222, 139, 180, 202, 30, 214, 73, 222, 139, 180, 202, 30, 214, 73, 233, + 93, 180, 202, 30, 214, 73, 212, 35, 180, 202, 30, 214, 73, 204, 133, 239, + 19, 216, 19, 212, 39, 214, 73, 236, 173, 239, 19, 216, 19, 204, 136, 214, + 73, 236, 173, 216, 19, 47, 226, 102, 77, 214, 73, 180, 149, 216, 19, 47, + 214, 63, 77, 214, 73, 180, 149, 47, 226, 102, 77, 214, 73, 216, 19, 180, + 149, 47, 214, 63, 77, 214, 73, 216, 19, 180, 149, 222, 140, 247, 232, + 216, 19, 236, 165, 149, 233, 94, 247, 232, 216, 19, 236, 165, 149, 212, + 36, 247, 232, 216, 19, 236, 165, 149, 204, 134, 247, 232, 216, 19, 236, + 165, 149, 216, 19, 216, 25, 204, 156, 214, 159, 239, 19, 216, 19, 241, + 133, 250, 203, 216, 25, 204, 155, 216, 19, 216, 25, 204, 156, 77, 214, + 73, 180, 149, 239, 19, 216, 19, 241, 133, 250, 203, 216, 25, 204, 156, + 214, 73, 236, 173, 83, 236, 247, 219, 61, 231, 155, 236, 247, 124, 53, + 239, 147, 236, 247, 135, 53, 239, 147, 236, 247, 237, 0, 77, 3, 181, 231, + 155, 106, 237, 0, 77, 3, 83, 249, 80, 250, 169, 236, 222, 77, 231, 155, + 106, 4, 237, 0, 77, 3, 83, 249, 80, 250, 169, 236, 222, 77, 231, 155, + 106, 237, 0, 77, 3, 76, 57, 237, 0, 77, 3, 214, 26, 4, 237, 0, 77, 3, + 214, 26, 237, 0, 77, 3, 200, 62, 237, 0, 77, 3, 99, 231, 155, 204, 183, + 241, 131, 3, 181, 231, 155, 106, 241, 131, 3, 83, 249, 80, 250, 169, 236, + 222, 77, 231, 155, 106, 4, 241, 131, 3, 83, 249, 80, 250, 169, 236, 222, + 77, 231, 155, 106, 241, 131, 3, 214, 26, 4, 241, 131, 3, 214, 26, 195, + 159, 216, 17, 249, 123, 219, 167, 239, 142, 55, 237, 2, 51, 231, 87, 124, + 250, 217, 135, 250, 217, 211, 255, 213, 26, 197, 119, 222, 75, 50, 247, + 45, 53, 247, 45, 50, 235, 69, 53, 235, 69, 248, 85, 53, 241, 63, 248, 85, + 50, 241, 63, 201, 243, 53, 241, 63, 201, 243, 50, 241, 63, 210, 89, 216, + 19, 55, 47, 221, 198, 250, 253, 208, 122, 208, 131, 203, 34, 210, 167, + 212, 79, 226, 68, 199, 22, 205, 94, 212, 149, 77, 226, 33, 55, 163, 216, + 19, 55, 197, 129, 231, 89, 201, 243, 50, 241, 101, 201, 243, 53, 241, + 101, 248, 85, 50, 241, 101, 248, 85, 53, 241, 101, 201, 243, 157, 226, + 37, 248, 85, 157, 226, 37, 234, 230, 205, 219, 124, 250, 218, 248, 204, + 99, 231, 155, 249, 68, 214, 75, 224, 153, 236, 161, 202, 30, 202, 218, + 210, 22, 196, 223, 226, 87, 39, 210, 164, 248, 70, 224, 151, 222, 179, + 251, 91, 179, 210, 17, 251, 91, 179, 236, 161, 202, 30, 202, 218, 222, + 184, 248, 215, 210, 2, 240, 241, 251, 147, 250, 226, 203, 247, 201, 228, + 209, 113, 239, 104, 214, 64, 241, 146, 203, 103, 205, 233, 241, 90, 241, + 89, 251, 40, 234, 213, 16, 230, 242, 251, 40, 234, 213, 16, 205, 85, 211, + 94, 251, 40, 234, 213, 16, 211, 95, 236, 173, 251, 40, 234, 213, 16, 211, + 95, 239, 61, 251, 40, 234, 213, 16, 211, 95, 239, 140, 251, 40, 234, 213, + 16, 211, 95, 225, 116, 251, 40, 234, 213, 16, 211, 95, 244, 249, 251, 40, + 234, 213, 16, 244, 250, 204, 234, 251, 40, 234, 213, 16, 244, 250, 225, + 116, 251, 40, 234, 213, 16, 205, 249, 154, 251, 40, 234, 213, 16, 249, + 134, 154, 251, 40, 234, 213, 16, 211, 95, 205, 248, 251, 40, 234, 213, + 16, 211, 95, 249, 133, 251, 40, 234, 213, 16, 211, 95, 222, 139, 251, 40, + 234, 213, 16, 211, 95, 233, 93, 251, 40, 234, 213, 16, 107, 199, 140, + 251, 40, 234, 213, 16, 91, 199, 140, 251, 40, 234, 213, 16, 211, 95, 107, + 51, 251, 40, 234, 213, 16, 211, 95, 91, 51, 251, 40, 234, 213, 16, 244, + 250, 249, 133, 251, 40, 234, 213, 16, 135, 203, 148, 200, 62, 251, 40, + 234, 213, 16, 239, 213, 204, 234, 251, 40, 234, 213, 16, 211, 95, 135, + 247, 110, 251, 40, 234, 213, 16, 211, 95, 239, 212, 251, 40, 234, 213, + 16, 135, 203, 148, 225, 116, 251, 40, 234, 213, 16, 200, 24, 199, 140, + 251, 40, 234, 213, 16, 211, 95, 200, 24, 51, 251, 40, 234, 213, 16, 124, + 203, 148, 214, 26, 251, 40, 234, 213, 16, 239, 225, 204, 234, 251, 40, + 234, 213, 16, 211, 95, 124, 247, 110, 251, 40, 234, 213, 16, 211, 95, + 239, 224, 251, 40, 234, 213, 16, 124, 203, 148, 225, 116, 251, 40, 234, + 213, 16, 237, 231, 199, 140, 251, 40, 234, 213, 16, 211, 95, 237, 231, + 51, 251, 40, 234, 213, 16, 211, 61, 200, 62, 251, 40, 234, 213, 16, 239, + 213, 200, 62, 251, 40, 234, 213, 16, 239, 141, 200, 62, 251, 40, 234, + 213, 16, 225, 117, 200, 62, 251, 40, 234, 213, 16, 244, 250, 200, 62, + 251, 40, 234, 213, 16, 124, 206, 195, 225, 116, 251, 40, 234, 213, 16, + 211, 61, 211, 94, 251, 40, 234, 213, 16, 244, 250, 205, 7, 251, 40, 234, + 213, 16, 211, 95, 244, 168, 251, 40, 234, 213, 16, 124, 203, 148, 239, + 150, 251, 40, 234, 213, 16, 239, 225, 239, 150, 251, 40, 234, 213, 16, + 205, 8, 239, 150, 251, 40, 234, 213, 16, 225, 117, 239, 150, 251, 40, + 234, 213, 16, 244, 250, 239, 150, 251, 40, 234, 213, 16, 135, 206, 195, + 204, 234, 251, 40, 234, 213, 16, 50, 206, 195, 204, 234, 251, 40, 234, + 213, 16, 202, 85, 239, 150, 251, 40, 234, 213, 16, 233, 94, 239, 150, + 251, 40, 234, 213, 16, 244, 160, 154, 251, 40, 234, 213, 16, 239, 225, + 202, 84, 251, 40, 234, 213, 16, 195, 23, 251, 40, 234, 213, 16, 204, 235, + 202, 84, 251, 40, 234, 213, 16, 207, 106, 200, 62, 251, 40, 234, 213, 16, + 211, 95, 216, 19, 236, 173, 251, 40, 234, 213, 16, 211, 95, 211, 78, 251, + 40, 234, 213, 16, 135, 247, 111, 202, 84, 251, 40, 234, 213, 16, 124, + 247, 111, 202, 84, 251, 40, 234, 213, 16, 226, 7, 251, 40, 234, 213, 16, + 210, 74, 251, 40, 234, 213, 16, 214, 124, 251, 40, 234, 213, 16, 251, + 135, 200, 62, 251, 40, 234, 213, 16, 236, 175, 200, 62, 251, 40, 234, + 213, 16, 226, 8, 200, 62, 251, 40, 234, 213, 16, 214, 125, 200, 62, 251, + 40, 234, 213, 16, 251, 134, 216, 19, 245, 102, 78, 53, 251, 91, 3, 237, + 231, 195, 24, 51, 206, 163, 192, 248, 70, 248, 230, 105, 83, 222, 76, 3, + 112, 238, 253, 226, 43, 105, 241, 126, 200, 60, 105, 239, 77, 200, 60, + 105, 236, 234, 105, 241, 161, 105, 59, 47, 3, 247, 37, 83, 222, 75, 236, + 205, 105, 251, 126, 224, 154, 105, 232, 105, 105, 46, 231, 155, 249, 80, + 3, 216, 16, 46, 201, 181, 237, 235, 248, 33, 244, 250, 3, 216, 22, 51, + 200, 58, 105, 218, 200, 105, 231, 3, 105, 214, 91, 233, 14, 105, 214, 91, + 223, 98, 105, 213, 120, 105, 213, 119, 105, 239, 86, 241, 16, 16, 235, + 24, 102, 205, 183, 105, 251, 40, 234, 213, 16, 211, 94, 239, 244, 207, + 91, 224, 154, 105, 212, 21, 213, 227, 217, 76, 213, 227, 212, 16, 208, + 155, 105, 244, 221, 208, 155, 105, 50, 213, 141, 200, 33, 122, 50, 213, + 141, 236, 77, 50, 213, 141, 221, 203, 122, 53, 213, 141, 200, 33, 122, + 53, 213, 141, 236, 77, 53, 213, 141, 221, 203, 122, 50, 47, 248, 62, 200, + 33, 241, 101, 50, 47, 248, 62, 236, 77, 50, 47, 248, 62, 221, 203, 241, + 101, 53, 47, 248, 62, 200, 33, 241, 101, 53, 47, 248, 62, 236, 77, 53, + 47, 248, 62, 221, 203, 241, 101, 50, 241, 18, 248, 62, 200, 33, 122, 50, + 241, 18, 248, 62, 112, 212, 212, 50, 241, 18, 248, 62, 221, 203, 122, + 241, 18, 248, 62, 236, 77, 53, 241, 18, 248, 62, 200, 33, 122, 53, 241, + 18, 248, 62, 112, 212, 212, 53, 241, 18, 248, 62, 221, 203, 122, 226, 38, + 236, 77, 231, 155, 222, 76, 236, 77, 200, 33, 50, 214, 73, 221, 203, 53, + 241, 18, 248, 62, 208, 132, 200, 33, 53, 214, 73, 221, 203, 50, 241, 18, + 248, 62, 208, 132, 204, 115, 201, 242, 204, 115, 248, 84, 201, 243, 47, + 179, 248, 85, 47, 179, 248, 85, 47, 248, 62, 127, 201, 243, 47, 179, 44, + 16, 248, 84, 50, 83, 111, 222, 75, 53, 83, 111, 222, 75, 231, 155, 208, + 174, 222, 74, 231, 155, 208, 174, 222, 73, 231, 155, 208, 174, 222, 72, + 231, 155, 208, 174, 222, 71, 239, 204, 16, 175, 83, 26, 201, 243, 210, + 22, 239, 204, 16, 175, 83, 26, 248, 85, 210, 22, 239, 204, 16, 175, 83, + 3, 244, 249, 239, 204, 16, 175, 135, 26, 231, 155, 3, 244, 249, 239, 204, + 16, 175, 124, 26, 231, 155, 3, 244, 249, 239, 204, 16, 175, 83, 3, 201, + 180, 239, 204, 16, 175, 135, 26, 231, 155, 3, 201, 180, 239, 204, 16, + 175, 124, 26, 231, 155, 3, 201, 180, 239, 204, 16, 175, 83, 26, 197, 122, + 239, 204, 16, 175, 135, 26, 231, 155, 3, 197, 122, 239, 204, 16, 175, + 124, 26, 231, 155, 3, 197, 122, 239, 204, 16, 175, 135, 26, 231, 154, + 239, 204, 16, 175, 124, 26, 231, 154, 239, 204, 16, 175, 83, 26, 201, + 243, 222, 184, 239, 204, 16, 175, 83, 26, 248, 85, 222, 184, 47, 235, 37, + 210, 94, 105, 237, 16, 105, 83, 222, 76, 236, 77, 219, 137, 248, 47, 219, + 137, 181, 127, 206, 181, 219, 137, 206, 182, 127, 221, 240, 219, 137, + 181, 127, 99, 206, 167, 219, 137, 99, 206, 168, 127, 221, 240, 219, 137, + 99, 206, 168, 225, 125, 219, 137, 201, 161, 219, 137, 202, 249, 219, 137, + 213, 53, 237, 73, 233, 85, 234, 207, 201, 243, 213, 140, 248, 85, 213, + 140, 201, 243, 241, 18, 179, 248, 85, 241, 18, 179, 201, 243, 201, 231, + 206, 245, 179, 248, 85, 201, 231, 206, 245, 179, 59, 201, 197, 248, 215, + 210, 3, 3, 244, 249, 204, 216, 235, 80, 252, 26, 241, 15, 237, 1, 226, + 23, 239, 244, 236, 81, 105, 58, 210, 17, 52, 201, 180, 58, 222, 179, 52, + 201, 180, 58, 200, 35, 52, 201, 180, 58, 237, 234, 52, 201, 180, 58, 210, + 17, 52, 201, 181, 3, 83, 154, 58, 222, 179, 52, 201, 181, 3, 83, 154, 58, + 210, 17, 201, 181, 3, 52, 83, 154, 251, 168, 244, 206, 204, 223, 202, 77, + 244, 206, 231, 90, 3, 235, 60, 208, 217, 58, 219, 190, 222, 179, 201, + 180, 58, 219, 190, 210, 17, 201, 180, 58, 219, 190, 200, 35, 201, 180, + 58, 219, 190, 237, 234, 201, 180, 52, 83, 154, 58, 47, 36, 204, 226, 58, + 244, 250, 36, 210, 168, 212, 59, 105, 212, 59, 214, 118, 105, 212, 59, + 214, 120, 105, 212, 59, 205, 244, 105, 214, 178, 236, 68, 105, 16, 36, + 215, 146, 16, 36, 205, 3, 77, 232, 134, 16, 36, 205, 3, 77, 202, 237, 16, + 36, 236, 222, 77, 202, 237, 16, 36, 236, 222, 77, 201, 202, 16, 36, 236, + 208, 16, 36, 252, 14, 16, 36, 248, 229, 16, 36, 249, 132, 16, 36, 231, + 155, 203, 149, 16, 36, 222, 76, 235, 180, 16, 36, 83, 203, 149, 16, 36, + 235, 24, 235, 180, 16, 36, 247, 102, 210, 93, 16, 36, 206, 219, 214, 34, + 16, 36, 206, 219, 226, 86, 16, 36, 240, 60, 222, 66, 236, 143, 16, 36, + 239, 183, 241, 121, 100, 16, 36, 239, 183, 241, 121, 102, 16, 36, 239, + 183, 241, 121, 134, 16, 36, 239, 183, 241, 121, 136, 16, 36, 217, 104, + 252, 14, 16, 36, 203, 242, 226, 149, 16, 36, 236, 222, 77, 201, 203, 248, + 126, 16, 36, 247, 140, 16, 36, 236, 222, 77, 219, 189, 16, 36, 204, 139, + 16, 36, 236, 143, 16, 36, 235, 138, 207, 90, 16, 36, 233, 84, 207, 90, + 16, 36, 210, 169, 207, 90, 16, 36, 200, 50, 207, 90, 16, 36, 205, 148, + 16, 36, 239, 222, 248, 130, 105, 192, 248, 70, 16, 36, 217, 79, 16, 36, + 239, 223, 235, 24, 102, 16, 36, 204, 140, 235, 24, 102, 214, 174, 122, + 214, 174, 247, 11, 214, 174, 235, 27, 214, 174, 226, 17, 235, 27, 214, + 174, 248, 226, 248, 18, 214, 174, 248, 78, 202, 107, 214, 174, 248, 58, + 249, 85, 230, 192, 214, 174, 251, 113, 77, 245, 101, 214, 174, 240, 65, + 214, 174, 241, 4, 252, 18, 215, 144, 214, 174, 52, 249, 133, 46, 17, 100, + 46, 17, 102, 46, 17, 134, 46, 17, 136, 46, 17, 146, 46, 17, 167, 46, 17, + 178, 46, 17, 171, 46, 17, 182, 46, 31, 203, 23, 46, 31, 236, 252, 46, 31, + 200, 239, 46, 31, 202, 179, 46, 31, 235, 1, 46, 31, 235, 149, 46, 31, + 206, 23, 46, 31, 207, 68, 46, 31, 237, 28, 46, 31, 216, 176, 46, 31, 200, + 234, 119, 17, 100, 119, 17, 102, 119, 17, 134, 119, 17, 136, 119, 17, + 146, 119, 17, 167, 119, 17, 178, 119, 17, 171, 119, 17, 182, 119, 31, + 203, 23, 119, 31, 236, 252, 119, 31, 200, 239, 119, 31, 202, 179, 119, + 31, 235, 1, 119, 31, 235, 149, 119, 31, 206, 23, 119, 31, 207, 68, 119, + 31, 237, 28, 119, 31, 216, 176, 119, 31, 200, 234, 17, 97, 234, 217, 204, + 226, 17, 99, 234, 217, 204, 226, 17, 115, 234, 217, 204, 226, 17, 235, 7, + 234, 217, 204, 226, 17, 235, 101, 234, 217, 204, 226, 17, 206, 29, 234, + 217, 204, 226, 17, 207, 71, 234, 217, 204, 226, 17, 237, 31, 234, 217, + 204, 226, 17, 216, 179, 234, 217, 204, 226, 31, 203, 24, 234, 217, 204, + 226, 31, 236, 253, 234, 217, 204, 226, 31, 200, 240, 234, 217, 204, 226, + 31, 202, 180, 234, 217, 204, 226, 31, 235, 2, 234, 217, 204, 226, 31, + 235, 150, 234, 217, 204, 226, 31, 206, 24, 234, 217, 204, 226, 31, 207, + 69, 234, 217, 204, 226, 31, 237, 29, 234, 217, 204, 226, 31, 216, 177, + 234, 217, 204, 226, 31, 200, 235, 234, 217, 204, 226, 119, 8, 4, 1, 63, + 119, 8, 4, 1, 250, 112, 119, 8, 4, 1, 247, 207, 119, 8, 4, 1, 240, 231, + 119, 8, 4, 1, 69, 119, 8, 4, 1, 236, 49, 119, 8, 4, 1, 234, 190, 119, 8, + 4, 1, 233, 15, 119, 8, 4, 1, 68, 119, 8, 4, 1, 225, 217, 119, 8, 4, 1, + 225, 80, 119, 8, 4, 1, 159, 119, 8, 4, 1, 221, 136, 119, 8, 4, 1, 218, + 55, 119, 8, 4, 1, 72, 119, 8, 4, 1, 214, 3, 119, 8, 4, 1, 211, 167, 119, + 8, 4, 1, 144, 119, 8, 4, 1, 209, 80, 119, 8, 4, 1, 203, 216, 119, 8, 4, + 1, 66, 119, 8, 4, 1, 199, 230, 119, 8, 4, 1, 197, 199, 119, 8, 4, 1, 196, + 222, 119, 8, 4, 1, 196, 148, 119, 8, 4, 1, 195, 158, 46, 8, 6, 1, 63, 46, + 8, 6, 1, 250, 112, 46, 8, 6, 1, 247, 207, 46, 8, 6, 1, 240, 231, 46, 8, + 6, 1, 69, 46, 8, 6, 1, 236, 49, 46, 8, 6, 1, 234, 190, 46, 8, 6, 1, 233, + 15, 46, 8, 6, 1, 68, 46, 8, 6, 1, 225, 217, 46, 8, 6, 1, 225, 80, 46, 8, + 6, 1, 159, 46, 8, 6, 1, 221, 136, 46, 8, 6, 1, 218, 55, 46, 8, 6, 1, 72, + 46, 8, 6, 1, 214, 3, 46, 8, 6, 1, 211, 167, 46, 8, 6, 1, 144, 46, 8, 6, + 1, 209, 80, 46, 8, 6, 1, 203, 216, 46, 8, 6, 1, 66, 46, 8, 6, 1, 199, + 230, 46, 8, 6, 1, 197, 199, 46, 8, 6, 1, 196, 222, 46, 8, 6, 1, 196, 148, + 46, 8, 6, 1, 195, 158, 46, 8, 4, 1, 63, 46, 8, 4, 1, 250, 112, 46, 8, 4, + 1, 247, 207, 46, 8, 4, 1, 240, 231, 46, 8, 4, 1, 69, 46, 8, 4, 1, 236, + 49, 46, 8, 4, 1, 234, 190, 46, 8, 4, 1, 233, 15, 46, 8, 4, 1, 68, 46, 8, + 4, 1, 225, 217, 46, 8, 4, 1, 225, 80, 46, 8, 4, 1, 159, 46, 8, 4, 1, 221, + 136, 46, 8, 4, 1, 218, 55, 46, 8, 4, 1, 72, 46, 8, 4, 1, 214, 3, 46, 8, + 4, 1, 211, 167, 46, 8, 4, 1, 144, 46, 8, 4, 1, 209, 80, 46, 8, 4, 1, 203, + 216, 46, 8, 4, 1, 66, 46, 8, 4, 1, 199, 230, 46, 8, 4, 1, 197, 199, 46, + 8, 4, 1, 196, 222, 46, 8, 4, 1, 196, 148, 46, 8, 4, 1, 195, 158, 46, 17, + 195, 79, 217, 104, 46, 31, 236, 252, 217, 104, 46, 31, 200, 239, 217, + 104, 46, 31, 202, 179, 217, 104, 46, 31, 235, 1, 217, 104, 46, 31, 235, + 149, 217, 104, 46, 31, 206, 23, 217, 104, 46, 31, 207, 68, 217, 104, 46, + 31, 237, 28, 217, 104, 46, 31, 216, 176, 217, 104, 46, 31, 200, 234, 52, + 46, 17, 100, 52, 46, 17, 102, 52, 46, 17, 134, 52, 46, 17, 136, 52, 46, + 17, 146, 52, 46, 17, 167, 52, 46, 17, 178, 52, 46, 17, 171, 52, 46, 17, + 182, 52, 46, 31, 203, 23, 217, 104, 46, 17, 195, 79, 111, 129, 175, 231, + 154, 111, 129, 85, 231, 154, 111, 129, 175, 199, 100, 111, 129, 85, 199, + 100, 111, 129, 175, 201, 165, 240, 66, 231, 154, 111, 129, 85, 201, 165, + 240, 66, 231, 154, 111, 129, 175, 201, 165, 240, 66, 199, 100, 111, 129, + 85, 201, 165, 240, 66, 199, 100, 111, 129, 175, 211, 90, 240, 66, 231, + 154, 111, 129, 85, 211, 90, 240, 66, 231, 154, 111, 129, 175, 211, 90, + 240, 66, 199, 100, 111, 129, 85, 211, 90, 240, 66, 199, 100, 111, 129, + 175, 135, 26, 210, 22, 111, 129, 135, 175, 26, 53, 232, 120, 111, 129, + 135, 85, 26, 53, 222, 95, 111, 129, 85, 135, 26, 210, 22, 111, 129, 175, + 135, 26, 222, 184, 111, 129, 135, 175, 26, 50, 232, 120, 111, 129, 135, + 85, 26, 50, 222, 95, 111, 129, 85, 135, 26, 222, 184, 111, 129, 175, 124, + 26, 210, 22, 111, 129, 124, 175, 26, 53, 232, 120, 111, 129, 124, 85, 26, + 53, 222, 95, 111, 129, 85, 124, 26, 210, 22, 111, 129, 175, 124, 26, 222, + 184, 111, 129, 124, 175, 26, 50, 232, 120, 111, 129, 124, 85, 26, 50, + 222, 95, 111, 129, 85, 124, 26, 222, 184, 111, 129, 175, 83, 26, 210, 22, + 111, 129, 83, 175, 26, 53, 232, 120, 111, 129, 124, 85, 26, 53, 135, 222, + 95, 111, 129, 135, 85, 26, 53, 124, 222, 95, 111, 129, 83, 85, 26, 53, + 222, 95, 111, 129, 135, 175, 26, 53, 124, 232, 120, 111, 129, 124, 175, + 26, 53, 135, 232, 120, 111, 129, 85, 83, 26, 210, 22, 111, 129, 175, 83, + 26, 222, 184, 111, 129, 83, 175, 26, 50, 232, 120, 111, 129, 124, 85, 26, + 50, 135, 222, 95, 111, 129, 135, 85, 26, 50, 124, 222, 95, 111, 129, 83, + 85, 26, 50, 222, 95, 111, 129, 135, 175, 26, 50, 124, 232, 120, 111, 129, + 124, 175, 26, 50, 135, 232, 120, 111, 129, 85, 83, 26, 222, 184, 111, + 129, 175, 135, 26, 231, 154, 111, 129, 50, 85, 26, 53, 135, 222, 95, 111, + 129, 53, 85, 26, 50, 135, 222, 95, 111, 129, 135, 175, 26, 231, 155, 232, + 120, 111, 129, 135, 85, 26, 231, 155, 222, 95, 111, 129, 53, 175, 26, 50, + 135, 232, 120, 111, 129, 50, 175, 26, 53, 135, 232, 120, 111, 129, 85, + 135, 26, 231, 154, 111, 129, 175, 124, 26, 231, 154, 111, 129, 50, 85, + 26, 53, 124, 222, 95, 111, 129, 53, 85, 26, 50, 124, 222, 95, 111, 129, + 124, 175, 26, 231, 155, 232, 120, 111, 129, 124, 85, 26, 231, 155, 222, + 95, 111, 129, 53, 175, 26, 50, 124, 232, 120, 111, 129, 50, 175, 26, 53, + 124, 232, 120, 111, 129, 85, 124, 26, 231, 154, 111, 129, 175, 83, 26, + 231, 154, 111, 129, 50, 85, 26, 53, 83, 222, 95, 111, 129, 53, 85, 26, + 50, 83, 222, 95, 111, 129, 83, 175, 26, 231, 155, 232, 120, 111, 129, + 124, 85, 26, 135, 231, 155, 222, 95, 111, 129, 135, 85, 26, 124, 231, + 155, 222, 95, 111, 129, 83, 85, 26, 231, 155, 222, 95, 111, 129, 50, 124, + 85, 26, 53, 135, 222, 95, 111, 129, 53, 124, 85, 26, 50, 135, 222, 95, + 111, 129, 50, 135, 85, 26, 53, 124, 222, 95, 111, 129, 53, 135, 85, 26, + 50, 124, 222, 95, 111, 129, 135, 175, 26, 124, 231, 155, 232, 120, 111, + 129, 124, 175, 26, 135, 231, 155, 232, 120, 111, 129, 53, 175, 26, 50, + 83, 232, 120, 111, 129, 50, 175, 26, 53, 83, 232, 120, 111, 129, 85, 83, + 26, 231, 154, 111, 129, 175, 52, 240, 66, 231, 154, 111, 129, 85, 52, + 240, 66, 231, 154, 111, 129, 175, 52, 240, 66, 199, 100, 111, 129, 85, + 52, 240, 66, 199, 100, 111, 129, 52, 231, 154, 111, 129, 52, 199, 100, + 111, 129, 135, 206, 62, 26, 53, 237, 245, 111, 129, 135, 52, 26, 53, 206, + 61, 111, 129, 52, 135, 26, 210, 22, 111, 129, 135, 206, 62, 26, 50, 237, + 245, 111, 129, 135, 52, 26, 50, 206, 61, 111, 129, 52, 135, 26, 222, 184, + 111, 129, 124, 206, 62, 26, 53, 237, 245, 111, 129, 124, 52, 26, 53, 206, + 61, 111, 129, 52, 124, 26, 210, 22, 111, 129, 124, 206, 62, 26, 50, 237, + 245, 111, 129, 124, 52, 26, 50, 206, 61, 111, 129, 52, 124, 26, 222, 184, + 111, 129, 83, 206, 62, 26, 53, 237, 245, 111, 129, 83, 52, 26, 53, 206, + 61, 111, 129, 52, 83, 26, 210, 22, 111, 129, 83, 206, 62, 26, 50, 237, + 245, 111, 129, 83, 52, 26, 50, 206, 61, 111, 129, 52, 83, 26, 222, 184, + 111, 129, 135, 206, 62, 26, 231, 155, 237, 245, 111, 129, 135, 52, 26, + 231, 155, 206, 61, 111, 129, 52, 135, 26, 231, 154, 111, 129, 124, 206, + 62, 26, 231, 155, 237, 245, 111, 129, 124, 52, 26, 231, 155, 206, 61, + 111, 129, 52, 124, 26, 231, 154, 111, 129, 83, 206, 62, 26, 231, 155, + 237, 245, 111, 129, 83, 52, 26, 231, 155, 206, 61, 111, 129, 52, 83, 26, + 231, 154, 111, 129, 175, 250, 254, 135, 26, 210, 22, 111, 129, 175, 250, + 254, 135, 26, 222, 184, 111, 129, 175, 250, 254, 124, 26, 222, 184, 111, + 129, 175, 250, 254, 124, 26, 210, 22, 111, 129, 175, 239, 147, 200, 33, + 53, 202, 30, 221, 203, 222, 184, 111, 129, 175, 239, 147, 200, 33, 50, + 202, 30, 221, 203, 210, 22, 111, 129, 175, 239, 147, 241, 61, 111, 129, + 175, 222, 184, 111, 129, 175, 200, 36, 111, 129, 175, 210, 22, 111, 129, + 175, 237, 235, 111, 129, 85, 222, 184, 111, 129, 85, 200, 36, 111, 129, + 85, 210, 22, 111, 129, 85, 237, 235, 111, 129, 175, 50, 26, 85, 210, 22, + 111, 129, 175, 124, 26, 85, 237, 235, 111, 129, 85, 50, 26, 175, 210, 22, + 111, 129, 85, 124, 26, 175, 237, 235, 200, 33, 157, 248, 126, 221, 203, + 97, 237, 27, 248, 126, 221, 203, 97, 211, 88, 248, 126, 221, 203, 115, + 237, 25, 248, 126, 221, 203, 157, 248, 126, 221, 203, 235, 101, 237, 25, + 248, 126, 221, 203, 115, 211, 86, 248, 126, 221, 203, 207, 71, 237, 25, + 248, 126, 234, 217, 248, 126, 50, 207, 71, 237, 25, 248, 126, 50, 115, + 211, 86, 248, 126, 50, 235, 101, 237, 25, 248, 126, 50, 157, 248, 126, + 50, 115, 237, 25, 248, 126, 50, 97, 211, 88, 248, 126, 50, 97, 237, 27, + 248, 126, 53, 157, 248, 126, 175, 207, 39, 219, 190, 207, 39, 240, 71, + 207, 39, 200, 33, 97, 237, 27, 248, 126, 53, 97, 237, 27, 248, 126, 211, + 92, 221, 203, 222, 184, 211, 92, 221, 203, 210, 22, 211, 92, 200, 33, + 222, 184, 211, 92, 200, 33, 50, 26, 221, 203, 50, 26, 221, 203, 210, 22, + 211, 92, 200, 33, 50, 26, 221, 203, 210, 22, 211, 92, 200, 33, 50, 26, + 200, 33, 53, 26, 221, 203, 222, 184, 211, 92, 200, 33, 50, 26, 200, 33, + 53, 26, 221, 203, 210, 22, 211, 92, 200, 33, 210, 22, 211, 92, 200, 33, + 53, 26, 221, 203, 222, 184, 211, 92, 200, 33, 53, 26, 221, 203, 50, 26, + 221, 203, 210, 22, 58, 205, 94, 59, 205, 94, 59, 47, 3, 209, 185, 241, + 100, 59, 47, 241, 132, 58, 4, 205, 94, 47, 3, 231, 155, 235, 136, 47, 3, + 83, 235, 136, 47, 3, 214, 55, 241, 56, 235, 136, 47, 3, 200, 33, 50, 202, + 30, 221, 203, 53, 235, 136, 47, 3, 200, 33, 53, 202, 30, 221, 203, 50, + 235, 136, 47, 3, 239, 147, 241, 56, 235, 136, 58, 4, 205, 94, 59, 4, 205, + 94, 58, 210, 163, 59, 210, 163, 58, 83, 210, 163, 59, 83, 210, 163, 58, + 213, 144, 59, 213, 144, 58, 200, 35, 201, 180, 59, 200, 35, 201, 180, 58, + 200, 35, 4, 201, 180, 59, 200, 35, 4, 201, 180, 58, 210, 17, 201, 180, + 59, 210, 17, 201, 180, 58, 210, 17, 4, 201, 180, 59, 210, 17, 4, 201, + 180, 58, 210, 17, 212, 108, 59, 210, 17, 212, 108, 58, 237, 234, 201, + 180, 59, 237, 234, 201, 180, 58, 237, 234, 4, 201, 180, 59, 237, 234, 4, + 201, 180, 58, 222, 179, 201, 180, 59, 222, 179, 201, 180, 58, 222, 179, + 4, 201, 180, 59, 222, 179, 4, 201, 180, 58, 222, 179, 212, 108, 59, 222, + 179, 212, 108, 58, 239, 140, 59, 239, 140, 59, 239, 141, 241, 132, 58, 4, + 239, 140, 235, 110, 221, 198, 59, 244, 249, 237, 250, 244, 249, 244, 250, + 3, 83, 235, 136, 248, 1, 58, 244, 249, 244, 250, 3, 50, 157, 248, 136, + 244, 250, 3, 53, 157, 248, 136, 244, 250, 3, 221, 203, 157, 248, 136, + 244, 250, 3, 200, 33, 157, 248, 136, 244, 250, 3, 200, 33, 53, 211, 92, + 248, 136, 244, 250, 3, 251, 147, 247, 232, 200, 33, 50, 211, 92, 248, + 136, 50, 157, 58, 244, 249, 53, 157, 58, 244, 249, 226, 19, 248, 5, 226, + 19, 59, 244, 249, 200, 33, 157, 226, 19, 59, 244, 249, 221, 203, 157, + 226, 19, 59, 244, 249, 200, 33, 50, 211, 92, 244, 243, 250, 253, 200, 33, + 53, 211, 92, 244, 243, 250, 253, 221, 203, 53, 211, 92, 244, 243, 250, + 253, 221, 203, 50, 211, 92, 244, 243, 250, 253, 200, 33, 157, 244, 249, + 221, 203, 157, 244, 249, 58, 221, 203, 53, 201, 180, 58, 221, 203, 50, + 201, 180, 58, 200, 33, 50, 201, 180, 58, 200, 33, 53, 201, 180, 59, 248, + 5, 47, 3, 50, 157, 248, 136, 47, 3, 53, 157, 248, 136, 47, 3, 200, 33, + 50, 239, 147, 157, 248, 136, 47, 3, 221, 203, 53, 239, 147, 157, 248, + 136, 59, 47, 3, 83, 248, 150, 222, 75, 59, 200, 35, 201, 181, 3, 238, + 253, 200, 35, 201, 181, 3, 50, 157, 248, 136, 200, 35, 201, 181, 3, 53, + 157, 248, 136, 222, 228, 244, 249, 59, 47, 3, 200, 33, 50, 211, 91, 59, + 47, 3, 221, 203, 50, 211, 91, 59, 47, 3, 221, 203, 53, 211, 91, 59, 47, + 3, 200, 33, 53, 211, 91, 59, 244, 250, 3, 200, 33, 50, 211, 91, 59, 244, + 250, 3, 221, 203, 50, 211, 91, 59, 244, 250, 3, 221, 203, 53, 211, 91, + 59, 244, 250, 3, 200, 33, 53, 211, 91, 200, 33, 50, 201, 180, 200, 33, + 53, 201, 180, 221, 203, 50, 201, 180, 59, 219, 190, 205, 94, 58, 219, + 190, 205, 94, 59, 219, 190, 4, 205, 94, 58, 219, 190, 4, 205, 94, 221, + 203, 53, 201, 180, 58, 204, 112, 3, 210, 188, 244, 194, 200, 76, 205, + 202, 244, 162, 58, 205, 7, 59, 205, 7, 222, 92, 202, 137, 204, 111, 250, + 198, 216, 42, 239, 194, 216, 42, 241, 141, 214, 78, 58, 203, 33, 59, 203, + 33, 249, 99, 248, 70, 249, 99, 111, 3, 245, 101, 249, 99, 111, 3, 196, + 222, 208, 230, 200, 77, 3, 210, 218, 237, 208, 231, 96, 248, 201, 59, + 206, 191, 212, 212, 58, 206, 191, 212, 212, 207, 26, 210, 89, 209, 194, + 235, 66, 232, 127, 248, 5, 58, 50, 212, 107, 226, 72, 58, 53, 212, 107, + 226, 72, 59, 50, 212, 107, 226, 72, 59, 124, 212, 107, 226, 72, 59, 53, + 212, 107, 226, 72, 59, 135, 212, 107, 226, 72, 205, 255, 26, 241, 60, + 247, 86, 55, 210, 230, 55, 248, 158, 55, 247, 165, 251, 79, 214, 56, 241, + 61, 245, 76, 210, 74, 241, 62, 77, 221, 220, 241, 62, 77, 225, 182, 205, + 8, 26, 241, 71, 235, 204, 105, 251, 254, 207, 29, 232, 217, 26, 206, 103, + 213, 91, 105, 196, 13, 196, 95, 201, 170, 36, 232, 122, 201, 170, 36, + 223, 1, 201, 170, 36, 235, 118, 201, 170, 36, 202, 138, 201, 170, 36, + 197, 50, 201, 170, 36, 197, 127, 201, 170, 36, 218, 169, 201, 170, 36, + 237, 72, 197, 78, 77, 239, 168, 59, 234, 229, 235, 233, 59, 205, 218, + 235, 233, 58, 205, 218, 235, 233, 59, 204, 112, 3, 210, 188, 235, 113, + 211, 88, 218, 189, 222, 221, 211, 88, 218, 189, 219, 158, 235, 172, 55, + 237, 72, 220, 67, 55, 225, 95, 208, 192, 200, 16, 217, 94, 212, 121, 250, + 239, 203, 87, 234, 35, 247, 138, 222, 146, 199, 5, 222, 106, 208, 157, + 208, 255, 247, 120, 251, 15, 212, 160, 59, 245, 83, 224, 73, 59, 245, 83, + 211, 80, 59, 245, 83, 209, 203, 59, 245, 83, 248, 148, 59, 245, 83, 224, + 19, 59, 245, 83, 213, 103, 58, 245, 83, 224, 73, 58, 245, 83, 211, 80, + 58, 245, 83, 209, 203, 58, 245, 83, 248, 148, 58, 245, 83, 224, 19, 58, + 245, 83, 213, 103, 58, 205, 146, 204, 124, 59, 232, 127, 204, 124, 59, + 239, 141, 204, 124, 58, 244, 191, 204, 124, 59, 205, 146, 204, 124, 58, + 232, 127, 204, 124, 58, 239, 141, 204, 124, 59, 244, 191, 204, 124, 231, + 96, 205, 99, 211, 88, 216, 13, 237, 27, 216, 13, 249, 5, 237, 27, 216, 8, + 249, 5, 206, 22, 216, 8, 218, 89, 235, 83, 55, 218, 89, 217, 203, 55, + 218, 89, 207, 13, 55, 197, 89, 203, 236, 241, 61, 237, 69, 203, 236, 241, + 61, 200, 46, 210, 159, 105, 210, 159, 16, 36, 200, 200, 212, 140, 210, + 159, 16, 36, 200, 198, 212, 140, 210, 159, 16, 36, 200, 197, 212, 140, + 210, 159, 16, 36, 200, 195, 212, 140, 210, 159, 16, 36, 200, 193, 212, + 140, 210, 159, 16, 36, 200, 191, 212, 140, 210, 159, 16, 36, 200, 189, + 212, 140, 210, 159, 16, 36, 234, 32, 220, 2, 58, 200, 46, 210, 159, 105, + 210, 160, 213, 162, 105, 213, 131, 213, 162, 105, 213, 37, 213, 162, 55, + 197, 76, 105, 239, 133, 235, 232, 239, 133, 235, 231, 239, 133, 235, 230, + 239, 133, 235, 229, 239, 133, 235, 228, 239, 133, 235, 227, 59, 244, 250, + 3, 76, 210, 22, 59, 244, 250, 3, 99, 238, 250, 58, 244, 250, 3, 59, 76, + 210, 22, 58, 244, 250, 3, 99, 59, 238, 250, 218, 205, 36, 196, 95, 218, + 205, 36, 196, 12, 239, 114, 36, 233, 95, 196, 95, 239, 114, 36, 222, 138, + 196, 12, 239, 114, 36, 222, 138, 196, 95, 239, 114, 36, 233, 95, 196, 12, + 59, 235, 93, 58, 235, 93, 232, 217, 26, 212, 216, 251, 102, 241, 59, 204, + 47, 205, 17, 77, 251, 228, 208, 175, 251, 163, 235, 62, 234, 45, 205, 17, + 77, 232, 94, 250, 158, 105, 235, 78, 214, 30, 59, 205, 7, 115, 222, 70, + 241, 118, 210, 22, 115, 222, 70, 241, 118, 222, 184, 197, 138, 55, 130, + 198, 237, 55, 237, 240, 235, 172, 55, 237, 240, 220, 67, 55, 226, 29, + 235, 172, 26, 220, 67, 55, 220, 67, 26, 235, 172, 55, 220, 67, 3, 204, + 196, 55, 220, 67, 3, 204, 196, 26, 220, 67, 26, 235, 172, 55, 83, 220, + 67, 3, 204, 196, 55, 231, 155, 220, 67, 3, 204, 196, 55, 219, 190, 59, + 244, 249, 219, 190, 58, 244, 249, 219, 190, 4, 59, 244, 249, 220, 21, + 105, 239, 52, 105, 200, 43, 213, 130, 105, 244, 173, 234, 212, 200, 12, + 217, 86, 247, 22, 213, 209, 225, 101, 199, 45, 245, 56, 58, 218, 190, + 222, 89, 207, 61, 207, 102, 211, 70, 207, 79, 205, 190, 249, 103, 249, + 65, 103, 224, 153, 59, 237, 220, 220, 62, 59, 237, 220, 224, 73, 58, 237, + 220, 220, 62, 58, 237, 220, 224, 73, 205, 203, 197, 37, 205, 206, 204, + 112, 248, 236, 244, 194, 210, 217, 58, 205, 202, 202, 139, 244, 195, 26, + 210, 217, 163, 59, 206, 191, 212, 212, 163, 58, 206, 191, 212, 212, 59, + 239, 141, 226, 87, 205, 94, 241, 55, 222, 235, 239, 81, 247, 116, 214, + 81, 212, 216, 247, 117, 205, 237, 232, 104, 3, 59, 241, 61, 46, 241, 55, + 222, 235, 247, 12, 216, 51, 236, 199, 251, 131, 214, 111, 50, 197, 113, + 201, 210, 58, 200, 212, 50, 197, 113, 201, 210, 59, 200, 212, 50, 197, + 113, 201, 210, 58, 50, 222, 236, 219, 157, 59, 50, 222, 236, 219, 157, + 237, 215, 205, 228, 55, 85, 59, 237, 234, 201, 180, 50, 244, 203, 236, + 199, 103, 208, 230, 235, 213, 239, 147, 226, 87, 59, 244, 250, 226, 87, + 58, 205, 94, 58, 201, 144, 210, 100, 50, 236, 198, 210, 100, 50, 236, + 197, 250, 173, 16, 36, 200, 16, 85, 244, 250, 3, 204, 196, 26, 99, 238, + 251, 57, 213, 54, 210, 19, 226, 31, 213, 54, 222, 181, 226, 31, 213, 54, + 226, 17, 213, 54, 58, 241, 62, 214, 120, 206, 220, 206, 208, 206, 156, + 245, 22, 247, 94, 232, 32, 206, 30, 234, 46, 197, 37, 231, 69, 234, 46, + 3, 232, 186, 220, 44, 16, 36, 222, 94, 218, 169, 200, 77, 214, 120, 233, + 85, 235, 8, 235, 94, 226, 87, 231, 175, 235, 162, 208, 250, 47, 235, 7, + 241, 100, 206, 2, 230, 202, 206, 6, 213, 29, 3, 249, 103, 203, 15, 225, + 202, 249, 85, 105, 232, 131, 233, 97, 105, 234, 220, 211, 215, 241, 28, + 214, 120, 58, 205, 94, 59, 235, 94, 3, 231, 155, 112, 58, 204, 197, 58, + 209, 4, 208, 161, 200, 33, 248, 131, 208, 161, 58, 208, 161, 221, 203, + 248, 131, 208, 161, 59, 208, 161, 59, 85, 245, 102, 78, 203, 34, 222, 4, + 55, 203, 104, 237, 214, 251, 187, 236, 194, 210, 215, 235, 106, 210, 215, + 232, 209, 199, 32, 232, 209, 196, 246, 232, 209, 221, 203, 53, 213, 64, + 213, 64, 200, 33, 53, 213, 64, 59, 216, 212, 58, 216, 212, 245, 102, 78, + 85, 245, 102, 78, 218, 118, 196, 222, 85, 218, 118, 196, 222, 249, 99, + 196, 222, 85, 249, 99, 196, 222, 214, 30, 32, 241, 61, 85, 32, 241, 61, + 192, 247, 37, 241, 61, 85, 192, 247, 37, 241, 61, 8, 241, 61, 207, 37, + 59, 8, 241, 61, 214, 30, 8, 241, 61, 220, 64, 241, 61, 205, 8, 77, 240, + 58, 235, 7, 203, 53, 250, 179, 235, 7, 249, 100, 250, 179, 85, 235, 7, + 249, 100, 250, 179, 235, 7, 244, 189, 250, 179, 58, 235, 7, 212, 109, + 205, 7, 59, 235, 7, 212, 109, 205, 7, 205, 141, 204, 206, 214, 30, 59, + 205, 7, 46, 59, 205, 7, 192, 247, 37, 58, 205, 7, 58, 247, 37, 59, 205, + 7, 214, 30, 58, 205, 7, 85, 214, 30, 58, 205, 7, 212, 170, 205, 7, 207, + 37, 59, 205, 7, 85, 250, 179, 192, 247, 37, 250, 179, 237, 31, 205, 110, + 250, 179, 237, 31, 212, 109, 58, 205, 7, 237, 31, 212, 109, 212, 170, + 205, 7, 206, 29, 212, 109, 58, 205, 7, 237, 31, 212, 109, 210, 161, 58, + 205, 7, 85, 237, 31, 212, 109, 210, 161, 58, 205, 7, 200, 240, 212, 109, + 58, 205, 7, 206, 24, 212, 109, 250, 179, 203, 53, 250, 179, 192, 247, 37, + 203, 53, 250, 179, 85, 203, 53, 250, 179, 206, 29, 213, 17, 58, 26, 59, + 235, 65, 58, 235, 65, 59, 235, 65, 237, 31, 213, 17, 214, 30, 58, 235, + 65, 46, 192, 247, 37, 237, 31, 212, 109, 205, 7, 85, 203, 53, 212, 170, + 250, 179, 205, 204, 202, 101, 201, 173, 205, 204, 85, 245, 79, 205, 204, + 205, 143, 85, 205, 143, 249, 100, 250, 179, 237, 31, 203, 53, 211, 250, + 250, 179, 85, 237, 31, 203, 53, 211, 250, 250, 179, 241, 62, 78, 207, 37, + 59, 244, 249, 217, 104, 103, 241, 62, 78, 221, 203, 53, 237, 210, 59, + 205, 94, 200, 33, 53, 237, 210, 59, 205, 94, 221, 203, 53, 207, 37, 59, + 205, 94, 200, 33, 53, 207, 37, 59, 205, 94, 58, 211, 79, 117, 214, 59, + 59, 211, 79, 117, 214, 59, 59, 236, 90, 117, 214, 59, 58, 239, 141, 219, + 16, 59, 196, 222, 85, 236, 90, 117, 105, 175, 83, 154, 219, 190, 83, 154, + 85, 83, 154, 85, 206, 62, 163, 244, 160, 211, 62, 117, 214, 59, 85, 206, + 62, 244, 160, 211, 62, 117, 214, 59, 85, 52, 163, 244, 160, 211, 62, 117, + 214, 59, 85, 52, 244, 160, 211, 62, 117, 214, 59, 85, 126, 206, 62, 244, + 160, 211, 62, 117, 214, 59, 85, 126, 52, 244, 160, 211, 62, 117, 214, 59, + 241, 10, 204, 244, 213, 154, 2, 214, 59, 85, 236, 90, 117, 214, 59, 85, + 232, 127, 236, 90, 117, 214, 59, 85, 58, 232, 126, 209, 194, 85, 58, 232, + 127, 248, 5, 235, 66, 232, 126, 209, 194, 235, 66, 232, 127, 248, 5, 219, + 190, 50, 213, 141, 214, 59, 219, 190, 53, 213, 141, 214, 59, 219, 190, + 235, 79, 50, 213, 141, 214, 59, 219, 190, 235, 79, 53, 213, 141, 214, 59, + 219, 190, 222, 179, 251, 91, 248, 62, 214, 59, 219, 190, 210, 17, 251, + 91, 248, 62, 214, 59, 85, 222, 179, 251, 91, 211, 62, 117, 214, 59, 85, + 210, 17, 251, 91, 211, 62, 117, 214, 59, 85, 222, 179, 251, 91, 248, 62, + 214, 59, 85, 210, 17, 251, 91, 248, 62, 214, 59, 175, 50, 201, 231, 206, + 245, 248, 62, 214, 59, 175, 53, 201, 231, 206, 245, 248, 62, 214, 59, + 219, 190, 50, 241, 18, 248, 62, 214, 59, 219, 190, 53, 241, 18, 248, 62, + 214, 59, 239, 93, 217, 104, 46, 17, 100, 239, 93, 217, 104, 46, 17, 102, + 239, 93, 217, 104, 46, 17, 134, 239, 93, 217, 104, 46, 17, 136, 239, 93, + 217, 104, 46, 17, 146, 239, 93, 217, 104, 46, 17, 167, 239, 93, 217, 104, + 46, 17, 178, 239, 93, 217, 104, 46, 17, 171, 239, 93, 217, 104, 46, 17, + 182, 239, 93, 217, 104, 46, 31, 203, 23, 239, 93, 46, 45, 17, 100, 239, + 93, 46, 45, 17, 102, 239, 93, 46, 45, 17, 134, 239, 93, 46, 45, 17, 136, + 239, 93, 46, 45, 17, 146, 239, 93, 46, 45, 17, 167, 239, 93, 46, 45, 17, + 178, 239, 93, 46, 45, 17, 171, 239, 93, 46, 45, 17, 182, 239, 93, 46, 45, + 31, 203, 23, 239, 93, 217, 104, 46, 45, 17, 100, 239, 93, 217, 104, 46, + 45, 17, 102, 239, 93, 217, 104, 46, 45, 17, 134, 239, 93, 217, 104, 46, + 45, 17, 136, 239, 93, 217, 104, 46, 45, 17, 146, 239, 93, 217, 104, 46, + 45, 17, 167, 239, 93, 217, 104, 46, 45, 17, 178, 239, 93, 217, 104, 46, + 45, 17, 171, 239, 93, 217, 104, 46, 45, 17, 182, 239, 93, 217, 104, 46, + 45, 31, 203, 23, 85, 197, 61, 91, 51, 85, 98, 55, 85, 219, 16, 55, 85, + 239, 54, 55, 85, 205, 159, 237, 69, 51, 85, 91, 51, 85, 173, 237, 69, 51, + 237, 225, 212, 111, 91, 51, 85, 209, 186, 91, 51, 201, 179, 91, 51, 85, + 201, 179, 91, 51, 240, 64, 201, 179, 91, 51, 85, 240, 64, 201, 179, 91, + 51, 58, 91, 51, 202, 154, 201, 241, 91, 250, 217, 202, 154, 248, 83, 91, + 250, 217, 58, 91, 250, 217, 85, 58, 241, 10, 237, 231, 26, 91, 51, 85, + 58, 241, 10, 200, 24, 26, 91, 51, 205, 91, 58, 91, 51, 85, 241, 154, 58, + 91, 51, 210, 16, 59, 91, 51, 222, 178, 59, 91, 51, 249, 137, 207, 37, 59, + 91, 51, 234, 232, 207, 37, 59, 91, 51, 85, 221, 203, 210, 15, 59, 91, 51, + 85, 200, 33, 210, 15, 59, 91, 51, 216, 15, 221, 203, 210, 15, 59, 91, 51, + 241, 18, 221, 225, 216, 15, 200, 33, 210, 15, 59, 91, 51, 46, 85, 59, 91, + 51, 197, 72, 91, 51, 248, 135, 205, 159, 237, 69, 51, 248, 135, 91, 51, + 248, 135, 173, 237, 69, 51, 85, 248, 135, 205, 159, 237, 69, 51, 85, 248, + 135, 91, 51, 85, 248, 135, 173, 237, 69, 51, 203, 55, 91, 51, 85, 203, + 54, 91, 51, 197, 99, 91, 51, 85, 197, 99, 91, 51, 214, 87, 91, 51, 52, + 241, 18, 221, 225, 115, 239, 103, 251, 90, 59, 201, 181, 241, 132, 4, 59, + 201, 180, 213, 32, 192, 204, 141, 192, 204, 93, 50, 209, 79, 249, 123, + 239, 218, 53, 209, 79, 249, 123, 239, 218, 214, 73, 3, 76, 226, 41, 210, + 90, 205, 178, 212, 34, 204, 141, 204, 94, 212, 34, 205, 177, 83, 249, 80, + 3, 231, 155, 106, 13, 209, 250, 239, 146, 181, 239, 53, 13, 235, 213, + 239, 146, 103, 221, 249, 251, 100, 103, 221, 249, 214, 72, 59, 239, 141, + 3, 247, 35, 238, 253, 26, 3, 238, 253, 237, 0, 77, 214, 85, 200, 23, 221, + 203, 53, 241, 102, 3, 238, 253, 200, 33, 50, 241, 102, 3, 238, 253, 50, + 214, 32, 225, 127, 53, 214, 32, 225, 127, 234, 217, 214, 32, 225, 127, + 222, 228, 124, 203, 147, 222, 228, 135, 203, 147, 50, 26, 53, 52, 201, 3, + 50, 26, 53, 203, 147, 50, 218, 122, 181, 53, 203, 147, 181, 50, 203, 147, + 124, 203, 148, 3, 244, 250, 57, 221, 199, 239, 60, 247, 219, 231, 155, + 209, 124, 59, 241, 153, 239, 140, 59, 241, 153, 239, 141, 3, 107, 202, + 111, 59, 241, 153, 239, 141, 3, 91, 202, 111, 59, 47, 3, 107, 202, 111, + 59, 47, 3, 91, 202, 111, 13, 50, 59, 47, 179, 13, 53, 59, 47, 179, 13, + 50, 251, 91, 179, 13, 53, 251, 91, 179, 13, 50, 52, 251, 91, 179, 13, 53, + 52, 251, 91, 179, 13, 50, 59, 201, 231, 206, 245, 179, 13, 53, 59, 201, + 231, 206, 245, 179, 13, 50, 235, 79, 213, 140, 13, 53, 235, 79, 213, 140, + 200, 24, 211, 90, 51, 237, 231, 211, 90, 51, 251, 65, 234, 85, 244, 250, + 51, 244, 205, 234, 85, 244, 250, 51, 53, 61, 3, 46, 212, 125, 181, 107, + 51, 181, 91, 51, 181, 50, 53, 51, 181, 107, 52, 51, 181, 91, 52, 51, 181, + 50, 53, 52, 51, 181, 107, 61, 234, 235, 154, 181, 91, 61, 234, 235, 154, + 181, 107, 52, 61, 234, 235, 154, 181, 91, 52, 61, 234, 235, 154, 181, 91, + 205, 87, 51, 64, 65, 248, 129, 64, 65, 238, 249, 64, 65, 238, 121, 64, + 65, 238, 248, 64, 65, 238, 57, 64, 65, 238, 184, 64, 65, 238, 120, 64, + 65, 238, 247, 64, 65, 238, 25, 64, 65, 238, 152, 64, 65, 238, 88, 64, 65, + 238, 215, 64, 65, 238, 56, 64, 65, 238, 183, 64, 65, 238, 119, 64, 65, + 238, 246, 64, 65, 238, 9, 64, 65, 238, 136, 64, 65, 238, 72, 64, 65, 238, + 199, 64, 65, 238, 40, 64, 65, 238, 167, 64, 65, 238, 103, 64, 65, 238, + 230, 64, 65, 238, 24, 64, 65, 238, 151, 64, 65, 238, 87, 64, 65, 238, + 214, 64, 65, 238, 55, 64, 65, 238, 182, 64, 65, 238, 118, 64, 65, 238, + 245, 64, 65, 238, 1, 64, 65, 238, 128, 64, 65, 238, 64, 64, 65, 238, 191, + 64, 65, 238, 32, 64, 65, 238, 159, 64, 65, 238, 95, 64, 65, 238, 222, 64, + 65, 238, 16, 64, 65, 238, 143, 64, 65, 238, 79, 64, 65, 238, 206, 64, 65, + 238, 47, 64, 65, 238, 174, 64, 65, 238, 110, 64, 65, 238, 237, 64, 65, + 238, 8, 64, 65, 238, 135, 64, 65, 238, 71, 64, 65, 238, 198, 64, 65, 238, + 39, 64, 65, 238, 166, 64, 65, 238, 102, 64, 65, 238, 229, 64, 65, 238, + 23, 64, 65, 238, 150, 64, 65, 238, 86, 64, 65, 238, 213, 64, 65, 238, 54, + 64, 65, 238, 181, 64, 65, 238, 117, 64, 65, 238, 244, 64, 65, 237, 253, + 64, 65, 238, 124, 64, 65, 238, 60, 64, 65, 238, 187, 64, 65, 238, 28, 64, + 65, 238, 155, 64, 65, 238, 91, 64, 65, 238, 218, 64, 65, 238, 12, 64, 65, + 238, 139, 64, 65, 238, 75, 64, 65, 238, 202, 64, 65, 238, 43, 64, 65, + 238, 170, 64, 65, 238, 106, 64, 65, 238, 233, 64, 65, 238, 4, 64, 65, + 238, 131, 64, 65, 238, 67, 64, 65, 238, 194, 64, 65, 238, 35, 64, 65, + 238, 162, 64, 65, 238, 98, 64, 65, 238, 225, 64, 65, 238, 19, 64, 65, + 238, 146, 64, 65, 238, 82, 64, 65, 238, 209, 64, 65, 238, 50, 64, 65, + 238, 177, 64, 65, 238, 113, 64, 65, 238, 240, 64, 65, 238, 0, 64, 65, + 238, 127, 64, 65, 238, 63, 64, 65, 238, 190, 64, 65, 238, 31, 64, 65, + 238, 158, 64, 65, 238, 94, 64, 65, 238, 221, 64, 65, 238, 15, 64, 65, + 238, 142, 64, 65, 238, 78, 64, 65, 238, 205, 64, 65, 238, 46, 64, 65, + 238, 173, 64, 65, 238, 109, 64, 65, 238, 236, 64, 65, 238, 7, 64, 65, + 238, 134, 64, 65, 238, 70, 64, 65, 238, 197, 64, 65, 238, 38, 64, 65, + 238, 165, 64, 65, 238, 101, 64, 65, 238, 228, 64, 65, 238, 22, 64, 65, + 238, 149, 64, 65, 238, 85, 64, 65, 238, 212, 64, 65, 238, 53, 64, 65, + 238, 180, 64, 65, 238, 116, 64, 65, 238, 243, 64, 65, 237, 251, 64, 65, + 238, 122, 64, 65, 238, 58, 64, 65, 238, 185, 64, 65, 238, 26, 64, 65, + 238, 153, 64, 65, 238, 89, 64, 65, 238, 216, 64, 65, 238, 10, 64, 65, + 238, 137, 64, 65, 238, 73, 64, 65, 238, 200, 64, 65, 238, 41, 64, 65, + 238, 168, 64, 65, 238, 104, 64, 65, 238, 231, 64, 65, 238, 2, 64, 65, + 238, 129, 64, 65, 238, 65, 64, 65, 238, 192, 64, 65, 238, 33, 64, 65, + 238, 160, 64, 65, 238, 96, 64, 65, 238, 223, 64, 65, 238, 17, 64, 65, + 238, 144, 64, 65, 238, 80, 64, 65, 238, 207, 64, 65, 238, 48, 64, 65, + 238, 175, 64, 65, 238, 111, 64, 65, 238, 238, 64, 65, 237, 254, 64, 65, + 238, 125, 64, 65, 238, 61, 64, 65, 238, 188, 64, 65, 238, 29, 64, 65, + 238, 156, 64, 65, 238, 92, 64, 65, 238, 219, 64, 65, 238, 13, 64, 65, + 238, 140, 64, 65, 238, 76, 64, 65, 238, 203, 64, 65, 238, 44, 64, 65, + 238, 171, 64, 65, 238, 107, 64, 65, 238, 234, 64, 65, 238, 5, 64, 65, + 238, 132, 64, 65, 238, 68, 64, 65, 238, 195, 64, 65, 238, 36, 64, 65, + 238, 163, 64, 65, 238, 99, 64, 65, 238, 226, 64, 65, 238, 20, 64, 65, + 238, 147, 64, 65, 238, 83, 64, 65, 238, 210, 64, 65, 238, 51, 64, 65, + 238, 178, 64, 65, 238, 114, 64, 65, 238, 241, 64, 65, 237, 252, 64, 65, + 238, 123, 64, 65, 238, 59, 64, 65, 238, 186, 64, 65, 238, 27, 64, 65, + 238, 154, 64, 65, 238, 90, 64, 65, 238, 217, 64, 65, 238, 11, 64, 65, + 238, 138, 64, 65, 238, 74, 64, 65, 238, 201, 64, 65, 238, 42, 64, 65, + 238, 169, 64, 65, 238, 105, 64, 65, 238, 232, 64, 65, 238, 3, 64, 65, + 238, 130, 64, 65, 238, 66, 64, 65, 238, 193, 64, 65, 238, 34, 64, 65, + 238, 161, 64, 65, 238, 97, 64, 65, 238, 224, 64, 65, 238, 18, 64, 65, + 238, 145, 64, 65, 238, 81, 64, 65, 238, 208, 64, 65, 238, 49, 64, 65, + 238, 176, 64, 65, 238, 112, 64, 65, 238, 239, 64, 65, 237, 255, 64, 65, + 238, 126, 64, 65, 238, 62, 64, 65, 238, 189, 64, 65, 238, 30, 64, 65, + 238, 157, 64, 65, 238, 93, 64, 65, 238, 220, 64, 65, 238, 14, 64, 65, + 238, 141, 64, 65, 238, 77, 64, 65, 238, 204, 64, 65, 238, 45, 64, 65, + 238, 172, 64, 65, 238, 108, 64, 65, 238, 235, 64, 65, 238, 6, 64, 65, + 238, 133, 64, 65, 238, 69, 64, 65, 238, 196, 64, 65, 238, 37, 64, 65, + 238, 164, 64, 65, 238, 100, 64, 65, 238, 227, 64, 65, 238, 21, 64, 65, + 238, 148, 64, 65, 238, 84, 64, 65, 238, 211, 64, 65, 238, 52, 64, 65, + 238, 179, 64, 65, 238, 115, 64, 65, 238, 242, 91, 200, 215, 61, 3, 83, + 106, 91, 200, 215, 61, 3, 52, 83, 106, 107, 52, 61, 3, 83, 106, 91, 52, + 61, 3, 83, 106, 50, 53, 52, 61, 3, 83, 106, 91, 200, 215, 61, 234, 235, + 154, 107, 52, 61, 234, 235, 154, 91, 52, 61, 234, 235, 154, 237, 231, 61, + 3, 231, 155, 106, 200, 24, 61, 3, 231, 155, 106, 200, 24, 201, 165, 51, + 237, 231, 201, 165, 51, 107, 52, 240, 66, 51, 91, 52, 240, 66, 51, 107, + 201, 165, 240, 66, 51, 91, 201, 165, 240, 66, 51, 91, 200, 215, 201, 165, + 240, 66, 51, 91, 61, 3, 237, 250, 204, 243, 200, 24, 61, 202, 30, 154, + 237, 231, 61, 202, 30, 154, 91, 61, 3, 203, 136, 3, 83, 106, 91, 61, 3, + 203, 136, 3, 52, 83, 106, 91, 200, 215, 61, 3, 203, 135, 91, 200, 215, + 61, 3, 203, 136, 3, 83, 106, 91, 200, 215, 61, 3, 203, 136, 3, 52, 83, + 106, 107, 250, 219, 91, 250, 219, 107, 52, 250, 219, 91, 52, 250, 219, + 107, 61, 202, 30, 58, 239, 140, 91, 61, 202, 30, 58, 239, 140, 107, 61, + 234, 235, 249, 80, 202, 30, 58, 239, 140, 91, 61, 234, 235, 249, 80, 202, + 30, 58, 239, 140, 173, 197, 89, 26, 205, 159, 237, 69, 51, 173, 237, 69, + 26, 205, 159, 197, 89, 51, 173, 197, 89, 61, 3, 122, 173, 237, 69, 61, 3, + 122, 205, 159, 237, 69, 61, 3, 122, 205, 159, 197, 89, 61, 3, 122, 173, + 197, 89, 61, 26, 173, 237, 69, 51, 173, 237, 69, 61, 26, 205, 159, 237, + 69, 51, 205, 159, 237, 69, 61, 26, 205, 159, 197, 89, 51, 205, 159, 197, + 89, 61, 26, 173, 197, 89, 51, 209, 250, 239, 147, 241, 55, 235, 213, 239, + 146, 235, 213, 239, 147, 241, 55, 209, 250, 239, 146, 205, 159, 237, 69, + 61, 241, 55, 173, 237, 69, 51, 173, 237, 69, 61, 241, 55, 205, 159, 237, + 69, 51, 235, 213, 239, 147, 241, 55, 173, 237, 69, 51, 209, 250, 239, + 147, 241, 55, 205, 159, 237, 69, 51, 173, 237, 69, 61, 241, 55, 173, 197, + 89, 51, 173, 197, 89, 61, 241, 55, 173, 237, 69, 51, 197, 123, 61, 212, + 107, 239, 83, 210, 22, 61, 212, 107, 91, 202, 209, 241, 8, 200, 23, 61, + 212, 107, 91, 202, 209, 241, 8, 237, 230, 61, 212, 107, 237, 231, 202, + 209, 241, 8, 222, 174, 61, 212, 107, 237, 231, 202, 209, 241, 8, 210, 11, + 210, 14, 250, 254, 244, 205, 51, 222, 177, 250, 254, 251, 65, 51, 201, + 243, 250, 254, 251, 65, 51, 248, 85, 250, 254, 251, 65, 51, 201, 243, + 250, 254, 244, 205, 61, 3, 219, 15, 201, 243, 250, 254, 251, 65, 61, 3, + 212, 125, 221, 203, 53, 207, 107, 244, 205, 51, 221, 203, 50, 207, 107, + 251, 65, 51, 251, 65, 244, 203, 244, 250, 51, 244, 205, 244, 203, 244, + 250, 51, 91, 61, 90, 206, 182, 107, 51, 107, 61, 90, 206, 182, 91, 51, + 206, 182, 91, 61, 90, 107, 51, 91, 61, 3, 98, 60, 107, 61, 3, 98, 60, 91, + 61, 202, 145, 196, 222, 50, 53, 61, 202, 145, 4, 244, 249, 200, 24, 200, + 215, 61, 234, 235, 4, 244, 249, 50, 165, 124, 53, 165, 135, 232, 168, 50, + 165, 135, 53, 165, 124, 232, 168, 124, 165, 53, 135, 165, 50, 232, 168, + 124, 165, 50, 135, 165, 53, 232, 168, 50, 165, 124, 53, 165, 124, 232, + 168, 124, 165, 53, 135, 165, 53, 232, 168, 50, 165, 135, 53, 165, 135, + 232, 168, 124, 165, 50, 135, 165, 50, 232, 168, 107, 232, 169, 3, 165, + 124, 202, 30, 154, 91, 232, 169, 3, 165, 124, 202, 30, 154, 200, 24, 232, + 169, 3, 165, 53, 202, 30, 154, 237, 231, 232, 169, 3, 165, 53, 202, 30, + 154, 107, 232, 169, 3, 165, 135, 202, 30, 154, 91, 232, 169, 3, 165, 135, + 202, 30, 154, 200, 24, 232, 169, 3, 165, 50, 202, 30, 154, 237, 231, 232, + 169, 3, 165, 50, 202, 30, 154, 107, 232, 169, 3, 165, 124, 234, 235, 154, + 91, 232, 169, 3, 165, 124, 234, 235, 154, 200, 24, 232, 169, 3, 165, 53, + 234, 235, 154, 237, 231, 232, 169, 3, 165, 53, 234, 235, 154, 107, 232, + 169, 3, 165, 135, 234, 235, 154, 91, 232, 169, 3, 165, 135, 234, 235, + 154, 200, 24, 232, 169, 3, 165, 50, 234, 235, 154, 237, 231, 232, 169, 3, + 165, 50, 234, 235, 154, 107, 232, 169, 3, 165, 124, 90, 107, 232, 169, 3, + 165, 237, 235, 200, 24, 232, 169, 3, 165, 50, 248, 210, 200, 24, 232, + 169, 3, 165, 210, 22, 91, 232, 169, 3, 165, 124, 90, 91, 232, 169, 3, + 165, 237, 235, 237, 231, 232, 169, 3, 165, 50, 248, 210, 237, 231, 232, + 169, 3, 165, 210, 22, 107, 232, 169, 3, 165, 124, 90, 91, 232, 169, 3, + 165, 200, 36, 107, 232, 169, 3, 165, 135, 90, 91, 232, 169, 3, 165, 237, + 235, 91, 232, 169, 3, 165, 124, 90, 107, 232, 169, 3, 165, 200, 36, 91, + 232, 169, 3, 165, 135, 90, 107, 232, 169, 3, 165, 237, 235, 107, 232, + 169, 3, 165, 124, 90, 181, 240, 65, 107, 232, 169, 3, 165, 135, 248, 227, + 181, 240, 65, 91, 232, 169, 3, 165, 124, 90, 181, 240, 65, 91, 232, 169, + 3, 165, 135, 248, 227, 181, 240, 65, 200, 24, 232, 169, 3, 165, 50, 248, + 210, 237, 231, 232, 169, 3, 165, 210, 22, 237, 231, 232, 169, 3, 165, 50, + 248, 210, 200, 24, 232, 169, 3, 165, 210, 22, 53, 52, 61, 3, 209, 185, + 232, 137, 236, 172, 2, 90, 91, 51, 202, 85, 214, 83, 90, 91, 51, 107, 61, + 90, 202, 85, 214, 82, 91, 61, 90, 202, 85, 214, 82, 91, 61, 90, 251, 139, + 180, 149, 222, 140, 90, 107, 51, 107, 61, 202, 145, 222, 139, 233, 94, + 90, 91, 51, 204, 142, 90, 91, 51, 107, 61, 202, 145, 204, 141, 204, 94, + 90, 107, 51, 50, 235, 112, 203, 135, 53, 235, 112, 203, 135, 124, 235, + 112, 203, 135, 135, 235, 112, 203, 135, 201, 165, 83, 249, 80, 239, 218, + 195, 159, 216, 17, 205, 105, 195, 159, 216, 17, 200, 201, 244, 168, 50, + 59, 241, 18, 179, 53, 59, 241, 18, 179, 50, 59, 213, 140, 53, 59, 213, + 140, 195, 159, 216, 17, 50, 226, 102, 179, 195, 159, 216, 17, 53, 226, + 102, 179, 195, 159, 216, 17, 50, 248, 162, 179, 195, 159, 216, 17, 53, + 248, 162, 179, 50, 47, 248, 62, 3, 200, 62, 53, 47, 248, 62, 3, 200, 62, + 50, 47, 248, 62, 3, 202, 112, 226, 87, 201, 243, 241, 101, 53, 47, 248, + 62, 3, 202, 112, 226, 87, 248, 85, 241, 101, 50, 47, 248, 62, 3, 202, + 112, 226, 87, 248, 85, 241, 101, 53, 47, 248, 62, 3, 202, 112, 226, 87, + 201, 243, 241, 101, 50, 251, 91, 248, 62, 3, 238, 253, 53, 251, 91, 248, + 62, 3, 238, 253, 50, 250, 254, 222, 140, 179, 53, 250, 254, 233, 94, 179, + 52, 50, 250, 254, 233, 94, 179, 52, 53, 250, 254, 222, 140, 179, 50, 58, + 201, 231, 206, 245, 179, 53, 58, 201, 231, 206, 245, 179, 237, 250, 235, + 169, 83, 195, 24, 222, 75, 219, 201, 251, 91, 214, 85, 222, 184, 53, 251, + 91, 199, 132, 3, 205, 94, 219, 201, 53, 251, 91, 3, 238, 253, 251, 91, 3, + 209, 81, 226, 41, 252, 10, 251, 90, 205, 127, 251, 91, 214, 85, 222, 184, + 205, 127, 251, 91, 214, 85, 200, 36, 163, 251, 90, 210, 89, 251, 90, 251, + 91, 3, 200, 62, 210, 89, 251, 91, 3, 200, 62, 214, 182, 251, 91, 214, 85, + 200, 36, 214, 182, 251, 91, 214, 85, 237, 235, 219, 201, 251, 91, 3, 192, + 250, 232, 236, 218, 226, 87, 61, 212, 107, 124, 26, 210, 22, 219, 201, + 251, 91, 3, 192, 250, 232, 236, 218, 226, 87, 61, 212, 107, 124, 26, 222, + 184, 219, 201, 251, 91, 3, 192, 250, 232, 236, 218, 226, 87, 61, 212, + 107, 135, 26, 210, 22, 219, 201, 251, 91, 3, 192, 250, 232, 236, 218, + 226, 87, 61, 212, 107, 135, 26, 222, 184, 219, 201, 251, 91, 3, 192, 250, + 232, 236, 218, 226, 87, 61, 212, 107, 53, 26, 200, 36, 219, 201, 251, 91, + 3, 192, 250, 232, 236, 218, 226, 87, 61, 212, 107, 50, 26, 200, 36, 219, + 201, 251, 91, 3, 192, 250, 232, 236, 218, 226, 87, 61, 212, 107, 53, 26, + 237, 235, 219, 201, 251, 91, 3, 192, 250, 232, 236, 218, 226, 87, 61, + 212, 107, 50, 26, 237, 235, 210, 89, 236, 232, 207, 76, 236, 232, 207, + 77, 3, 214, 26, 236, 232, 207, 77, 3, 4, 244, 250, 57, 236, 232, 207, 77, + 3, 53, 61, 57, 236, 232, 207, 77, 3, 50, 61, 57, 244, 250, 3, 231, 155, + 154, 46, 83, 154, 46, 213, 145, 46, 210, 90, 205, 177, 46, 213, 32, 244, + 250, 239, 60, 247, 219, 231, 155, 249, 80, 26, 201, 243, 157, 239, 60, + 247, 219, 83, 154, 244, 250, 3, 204, 96, 196, 222, 46, 251, 63, 239, 54, + 55, 124, 61, 202, 145, 244, 249, 46, 59, 248, 5, 46, 248, 5, 46, 222, + 139, 46, 233, 93, 244, 250, 3, 4, 244, 250, 202, 30, 202, 218, 210, 22, + 244, 250, 3, 99, 231, 155, 204, 184, 202, 30, 202, 218, 210, 22, 103, + 209, 250, 239, 147, 205, 248, 103, 235, 213, 239, 147, 205, 248, 103, + 250, 179, 103, 4, 244, 249, 103, 205, 94, 99, 225, 126, 205, 92, 201, + 181, 3, 76, 57, 201, 181, 3, 200, 62, 209, 81, 226, 87, 201, 180, 201, + 181, 3, 207, 84, 250, 169, 248, 84, 53, 201, 181, 90, 50, 201, 180, 50, + 201, 181, 248, 210, 83, 154, 83, 249, 80, 248, 210, 53, 201, 180, 248, + 72, 3, 50, 157, 248, 136, 248, 72, 3, 53, 157, 248, 136, 58, 248, 71, 24, + 3, 50, 157, 248, 136, 24, 3, 53, 157, 248, 136, 59, 231, 89, 58, 231, 89, + 50, 197, 56, 235, 169, 53, 197, 56, 235, 169, 50, 52, 197, 56, 235, 169, + 53, 52, 197, 56, 235, 169, 226, 79, 226, 63, 202, 108, 127, 226, 63, 226, + 64, 217, 106, 3, 83, 154, 237, 244, 218, 122, 47, 3, 241, 124, 214, 31, + 226, 76, 250, 202, 206, 144, 212, 5, 236, 172, 2, 26, 205, 250, 213, 145, + 236, 172, 2, 26, 205, 250, 213, 146, 3, 202, 85, 57, 230, 193, 202, 30, + 26, 205, 250, 213, 145, 233, 155, 205, 6, 202, 206, 237, 234, 201, 181, + 3, 50, 157, 248, 136, 237, 234, 201, 181, 3, 53, 157, 248, 136, 58, 239, + 141, 3, 135, 51, 58, 221, 198, 59, 244, 250, 3, 135, 51, 58, 244, 250, 3, + 135, 51, 236, 154, 59, 205, 94, 236, 154, 58, 205, 94, 236, 154, 59, 239, + 140, 236, 154, 58, 239, 140, 236, 154, 59, 244, 249, 236, 154, 58, 244, + 249, 209, 123, 210, 90, 205, 178, 214, 82, 205, 178, 3, 214, 26, 210, 90, + 205, 178, 3, 231, 155, 106, 248, 171, 205, 177, 248, 171, 210, 90, 205, + 177, 52, 212, 125, 201, 165, 212, 125, 222, 179, 241, 10, 251, 91, 179, + 210, 17, 241, 10, 251, 91, 179, 202, 69, 219, 13, 218, 54, 46, 76, 214, + 82, 218, 54, 46, 98, 214, 82, 218, 54, 46, 24, 214, 82, 218, 54, 200, 52, + 214, 83, 3, 238, 253, 218, 54, 200, 52, 214, 83, 3, 212, 125, 218, 54, + 47, 226, 24, 214, 82, 218, 54, 47, 200, 52, 214, 82, 99, 221, 249, 26, + 214, 82, 99, 221, 249, 214, 73, 214, 82, 218, 54, 24, 214, 82, 218, 219, + 99, 204, 117, 204, 115, 3, 226, 37, 211, 90, 226, 38, 214, 82, 235, 121, + 213, 134, 226, 37, 226, 38, 3, 52, 106, 226, 38, 250, 130, 3, 205, 248, + 244, 242, 234, 214, 251, 65, 226, 35, 222, 76, 226, 36, 3, 210, 162, 213, + 113, 250, 227, 212, 101, 222, 76, 226, 36, 3, 207, 107, 213, 113, 250, + 227, 212, 101, 222, 76, 226, 36, 216, 19, 226, 81, 202, 218, 212, 101, + 226, 38, 250, 227, 39, 212, 111, 214, 82, 211, 84, 226, 38, 214, 82, 226, + 38, 3, 107, 61, 3, 122, 226, 38, 3, 24, 55, 226, 38, 3, 226, 23, 226, 38, + 3, 200, 51, 226, 38, 3, 214, 26, 226, 38, 3, 200, 62, 225, 127, 222, 228, + 50, 201, 181, 214, 82, 195, 159, 216, 17, 208, 169, 241, 160, 195, 159, + 216, 17, 208, 169, 212, 166, 195, 159, 216, 17, 208, 169, 212, 0, 98, 2, + 3, 4, 244, 250, 57, 98, 2, 3, 244, 241, 252, 23, 57, 98, 2, 3, 202, 85, + 57, 98, 2, 3, 76, 60, 98, 2, 3, 202, 85, 60, 98, 2, 3, 204, 143, 102, 98, + 2, 3, 58, 201, 180, 219, 16, 2, 3, 244, 160, 57, 219, 16, 2, 3, 76, 60, + 219, 16, 2, 3, 235, 213, 238, 250, 219, 16, 2, 3, 209, 250, 238, 250, 98, + 2, 226, 87, 50, 157, 244, 249, 98, 2, 226, 87, 53, 157, 244, 249, 199, + 117, 214, 73, 241, 62, 212, 5, 218, 118, 2, 3, 76, 57, 218, 118, 2, 3, + 200, 62, 207, 104, 212, 6, 3, 248, 85, 244, 202, 205, 222, 212, 5, 218, + 118, 2, 226, 87, 50, 157, 244, 249, 218, 118, 2, 226, 87, 53, 157, 244, + 249, 46, 218, 118, 2, 3, 244, 241, 252, 22, 218, 118, 2, 226, 87, 52, + 244, 249, 46, 239, 54, 55, 98, 2, 226, 87, 201, 180, 219, 16, 2, 226, 87, + 201, 180, 218, 118, 2, 226, 87, 201, 180, 226, 32, 212, 5, 210, 12, 226, + 32, 212, 5, 195, 159, 216, 17, 210, 135, 241, 160, 251, 121, 214, 73, + 241, 108, 226, 24, 3, 238, 253, 200, 52, 3, 219, 16, 55, 200, 52, 3, 214, + 26, 226, 24, 3, 214, 26, 226, 24, 3, 221, 249, 251, 100, 200, 52, 3, 221, + 249, 214, 72, 200, 52, 90, 226, 23, 226, 24, 90, 200, 51, 200, 52, 90, + 249, 80, 90, 226, 23, 226, 24, 90, 249, 80, 90, 200, 51, 200, 52, 248, + 210, 26, 225, 126, 3, 200, 51, 226, 24, 248, 210, 26, 225, 126, 3, 226, + 23, 244, 203, 200, 52, 3, 207, 83, 244, 203, 226, 24, 3, 207, 83, 52, 47, + 226, 23, 52, 47, 200, 51, 244, 203, 200, 52, 3, 207, 84, 26, 205, 222, + 212, 5, 221, 249, 26, 3, 76, 57, 221, 249, 214, 73, 3, 76, 57, 52, 221, + 249, 251, 100, 52, 221, 249, 214, 72, 99, 226, 25, 221, 249, 251, 100, + 99, 226, 25, 221, 249, 214, 72, 205, 232, 222, 228, 214, 72, 205, 232, + 222, 228, 251, 100, 221, 249, 214, 73, 214, 22, 221, 249, 251, 100, 221, + 249, 26, 3, 112, 204, 243, 221, 249, 214, 73, 3, 112, 204, 243, 221, 249, + 26, 3, 231, 155, 240, 65, 221, 249, 214, 73, 3, 231, 155, 240, 65, 221, + 249, 26, 3, 52, 214, 26, 221, 249, 26, 3, 200, 62, 221, 249, 26, 3, 52, + 200, 62, 4, 199, 114, 3, 200, 62, 221, 249, 214, 73, 3, 52, 214, 26, 221, + 249, 214, 73, 3, 52, 200, 62, 195, 159, 216, 17, 239, 7, 251, 55, 195, + 159, 216, 17, 210, 205, 251, 55, 236, 172, 2, 3, 76, 60, 230, 193, 3, 76, + 57, 201, 165, 231, 155, 249, 80, 3, 52, 83, 106, 201, 165, 231, 155, 249, + 80, 3, 201, 165, 83, 106, 202, 85, 214, 83, 3, 76, 57, 202, 85, 214, 83, + 3, 209, 250, 238, 250, 206, 71, 219, 16, 206, 70, 241, 147, 3, 76, 57, + 236, 172, 3, 250, 179, 251, 139, 180, 202, 30, 3, 244, 241, 252, 22, 251, + 21, 180, 214, 73, 180, 149, 236, 172, 2, 90, 98, 55, 98, 2, 90, 236, 172, + 55, 236, 172, 2, 90, 202, 85, 214, 82, 52, 244, 169, 236, 173, 99, 241, + 140, 236, 172, 206, 85, 115, 241, 140, 236, 172, 206, 85, 236, 172, 2, 3, + 99, 238, 251, 90, 26, 99, 238, 251, 60, 236, 165, 3, 235, 7, 238, 251, + 57, 222, 140, 3, 244, 250, 226, 41, 233, 94, 3, 244, 250, 226, 41, 222, + 140, 3, 211, 79, 117, 57, 233, 94, 3, 211, 79, 117, 57, 222, 140, 214, + 73, 205, 250, 180, 149, 233, 94, 214, 73, 205, 250, 180, 149, 222, 140, + 214, 73, 205, 250, 180, 202, 30, 3, 76, 226, 41, 233, 94, 214, 73, 205, + 250, 180, 202, 30, 3, 76, 226, 41, 222, 140, 214, 73, 205, 250, 180, 202, + 30, 3, 76, 57, 233, 94, 214, 73, 205, 250, 180, 202, 30, 3, 76, 57, 222, + 140, 214, 73, 205, 250, 180, 202, 30, 3, 76, 90, 210, 22, 233, 94, 214, + 73, 205, 250, 180, 202, 30, 3, 76, 90, 222, 184, 222, 140, 214, 73, 251, + 22, 233, 94, 214, 73, 251, 22, 222, 140, 26, 206, 60, 216, 19, 180, 149, + 233, 94, 26, 206, 60, 216, 19, 180, 149, 222, 140, 26, 216, 19, 251, 22, + 233, 94, 26, 216, 19, 251, 22, 222, 140, 90, 237, 243, 180, 90, 233, 93, + 233, 94, 90, 237, 243, 180, 90, 222, 139, 222, 140, 90, 206, 71, 214, 73, + 236, 173, 233, 94, 90, 206, 71, 214, 73, 236, 173, 222, 140, 90, 206, 71, + 90, 233, 93, 233, 94, 90, 206, 71, 90, 222, 139, 222, 140, 90, 233, 94, + 90, 237, 243, 236, 173, 233, 94, 90, 222, 140, 90, 237, 243, 236, 173, + 222, 140, 90, 205, 250, 180, 90, 233, 94, 90, 205, 250, 236, 173, 233, + 94, 90, 205, 250, 180, 90, 222, 140, 90, 205, 250, 236, 173, 205, 250, + 180, 202, 30, 214, 73, 222, 139, 205, 250, 180, 202, 30, 214, 73, 233, + 93, 205, 250, 180, 202, 30, 214, 73, 222, 140, 3, 76, 226, 41, 205, 250, + 180, 202, 30, 214, 73, 233, 94, 3, 76, 226, 41, 237, 243, 180, 202, 30, + 214, 73, 222, 139, 237, 243, 180, 202, 30, 214, 73, 233, 93, 237, 243, + 205, 250, 180, 202, 30, 214, 73, 222, 139, 237, 243, 205, 250, 180, 202, + 30, 214, 73, 233, 93, 206, 71, 214, 73, 222, 139, 206, 71, 214, 73, 233, + 93, 206, 71, 90, 222, 140, 90, 236, 172, 55, 206, 71, 90, 233, 94, 90, + 236, 172, 55, 52, 217, 90, 222, 139, 52, 217, 90, 233, 93, 52, 217, 90, + 222, 140, 3, 200, 62, 233, 94, 214, 22, 222, 139, 233, 94, 248, 210, 222, + 139, 222, 140, 244, 203, 247, 219, 241, 11, 233, 94, 244, 203, 247, 219, + 241, 11, 222, 140, 244, 203, 247, 219, 241, 12, 90, 205, 250, 236, 173, + 233, 94, 244, 203, 247, 219, 241, 12, 90, 205, 250, 236, 173, 205, 223, + 202, 222, 222, 226, 202, 222, 205, 223, 202, 223, 214, 73, 180, 149, 222, + 226, 202, 223, 214, 73, 180, 149, 236, 172, 2, 3, 247, 254, 57, 212, 36, + 90, 206, 60, 236, 172, 55, 204, 134, 90, 206, 60, 236, 172, 55, 212, 36, + 90, 206, 60, 216, 19, 180, 149, 204, 134, 90, 206, 60, 216, 19, 180, 149, + 212, 36, 90, 236, 172, 55, 204, 134, 90, 236, 172, 55, 212, 36, 90, 216, + 19, 180, 149, 204, 134, 90, 216, 19, 180, 149, 212, 36, 90, 251, 139, + 180, 149, 204, 134, 90, 251, 139, 180, 149, 212, 36, 90, 216, 19, 251, + 139, 180, 149, 204, 134, 90, 216, 19, 251, 139, 180, 149, 52, 212, 35, + 52, 204, 133, 204, 142, 3, 238, 253, 204, 94, 3, 238, 253, 204, 142, 3, + 98, 2, 60, 204, 94, 3, 98, 2, 60, 204, 142, 3, 218, 118, 2, 60, 204, 94, + 3, 218, 118, 2, 60, 204, 142, 77, 214, 73, 180, 202, 30, 3, 76, 57, 204, + 94, 77, 214, 73, 180, 202, 30, 3, 76, 57, 204, 142, 77, 90, 236, 172, 55, + 204, 94, 77, 90, 236, 172, 55, 204, 142, 77, 90, 202, 85, 214, 82, 204, + 94, 77, 90, 202, 85, 214, 82, 204, 142, 77, 90, 251, 139, 180, 149, 204, + 94, 77, 90, 251, 139, 180, 149, 204, 142, 77, 90, 216, 19, 180, 149, 204, + 94, 77, 90, 216, 19, 180, 149, 47, 50, 192, 111, 214, 82, 47, 53, 192, + 111, 214, 82, 244, 203, 204, 141, 244, 203, 204, 93, 244, 203, 204, 142, + 214, 73, 180, 149, 244, 203, 204, 94, 214, 73, 180, 149, 204, 142, 90, + 204, 93, 204, 94, 90, 204, 141, 204, 142, 90, 204, 141, 204, 94, 90, 204, + 93, 204, 94, 248, 210, 204, 141, 204, 94, 248, 210, 26, 225, 126, 247, + 219, 240, 66, 3, 204, 141, 237, 0, 77, 214, 85, 237, 230, 212, 156, 3, + 203, 49, 201, 242, 201, 198, 226, 23, 235, 25, 216, 34, 206, 182, 50, + 203, 147, 206, 182, 135, 203, 147, 206, 182, 124, 203, 147, 213, 33, 3, + 209, 80, 83, 249, 80, 201, 165, 53, 201, 3, 52, 83, 249, 80, 50, 201, 3, + 83, 249, 80, 52, 50, 201, 3, 52, 83, 249, 80, 52, 50, 201, 3, 181, 240, + 66, 234, 235, 50, 219, 169, 77, 52, 199, 100, 206, 182, 135, 203, 148, 3, + 214, 26, 206, 182, 124, 203, 148, 3, 200, 62, 206, 182, 124, 203, 148, + 90, 206, 182, 135, 203, 147, 52, 135, 203, 147, 52, 124, 203, 147, 52, + 204, 196, 216, 19, 55, 210, 89, 52, 204, 196, 216, 19, 55, 239, 19, 216, + 19, 239, 62, 3, 210, 89, 217, 105, 205, 248, 83, 222, 76, 3, 244, 250, + 57, 83, 222, 76, 3, 244, 250, 60, 135, 203, 148, 3, 244, 250, 60, 213, + 146, 3, 231, 155, 106, 213, 146, 3, 202, 85, 214, 82, 201, 165, 83, 249, + 80, 248, 164, 210, 136, 201, 165, 83, 249, 80, 3, 231, 155, 106, 201, + 165, 244, 169, 214, 82, 201, 165, 217, 90, 222, 139, 201, 165, 217, 90, + 233, 93, 237, 243, 205, 250, 222, 140, 214, 73, 180, 149, 237, 243, 205, + 250, 233, 94, 214, 73, 180, 149, 201, 165, 205, 178, 248, 164, 210, 136, + 222, 228, 201, 165, 83, 249, 80, 214, 82, 52, 205, 178, 214, 82, 59, 83, + 154, 218, 54, 59, 83, 154, 173, 237, 69, 59, 51, 173, 197, 89, 59, 51, + 205, 159, 237, 69, 59, 51, 205, 159, 197, 89, 59, 51, 50, 53, 59, 51, + 107, 58, 51, 200, 24, 58, 51, 237, 231, 58, 51, 173, 237, 69, 58, 51, + 173, 197, 89, 58, 51, 205, 159, 237, 69, 58, 51, 205, 159, 197, 89, 58, + 51, 50, 53, 58, 51, 124, 135, 58, 51, 91, 61, 3, 202, 68, 237, 230, 91, + 61, 3, 202, 68, 200, 23, 107, 61, 3, 202, 68, 237, 230, 107, 61, 3, 202, + 68, 200, 23, 47, 3, 201, 243, 157, 248, 136, 47, 3, 248, 85, 157, 248, + 136, 47, 3, 200, 33, 53, 239, 147, 157, 248, 136, 47, 3, 221, 203, 50, + 239, 147, 157, 248, 136, 239, 141, 3, 50, 157, 248, 136, 239, 141, 3, 53, + 157, 248, 136, 239, 141, 3, 201, 243, 157, 248, 136, 239, 141, 3, 248, + 85, 157, 248, 136, 237, 250, 205, 94, 58, 222, 228, 205, 94, 59, 222, + 228, 205, 94, 58, 199, 48, 4, 205, 94, 59, 199, 48, 4, 205, 94, 58, 213, + 55, 59, 213, 55, 59, 232, 85, 58, 232, 85, 231, 155, 58, 232, 85, 58, + 222, 228, 244, 249, 58, 219, 190, 239, 140, 59, 219, 190, 239, 140, 58, + 219, 190, 221, 198, 59, 219, 190, 221, 198, 58, 4, 239, 140, 58, 4, 221, + 198, 59, 4, 221, 198, 58, 231, 155, 236, 248, 59, 231, 155, 236, 248, 58, + 83, 236, 248, 59, 83, 236, 248, 50, 61, 3, 4, 244, 249, 115, 107, 250, + 214, 50, 61, 3, 46, 212, 125, 181, 107, 205, 87, 51, 107, 200, 215, 61, + 3, 83, 106, 107, 200, 215, 61, 3, 52, 83, 106, 107, 200, 215, 61, 234, + 235, 154, 107, 200, 215, 201, 165, 240, 66, 51, 107, 61, 3, 237, 250, + 204, 243, 107, 61, 3, 203, 136, 3, 83, 106, 107, 61, 3, 203, 136, 3, 52, + 83, 106, 107, 200, 215, 61, 3, 203, 135, 107, 200, 215, 61, 3, 203, 136, + 3, 83, 106, 107, 200, 215, 61, 3, 203, 136, 3, 52, 83, 106, 107, 61, 202, + 145, 196, 222, 197, 123, 61, 212, 107, 239, 83, 222, 184, 236, 172, 2, + 90, 107, 51, 210, 90, 202, 85, 214, 83, 90, 107, 51, 107, 61, 90, 210, + 90, 251, 139, 180, 149, 91, 61, 202, 145, 233, 93, 91, 61, 202, 145, 204, + 93, 107, 211, 90, 51, 91, 211, 90, 51, 210, 90, 202, 85, 214, 83, 90, 91, + 51, 91, 61, 90, 210, 90, 251, 139, 180, 149, 202, 85, 214, 83, 90, 107, + 51, 107, 61, 90, 251, 139, 180, 149, 107, 61, 90, 210, 90, 202, 85, 214, + 82, 91, 61, 90, 210, 90, 202, 85, 214, 82, 237, 231, 201, 179, 195, 24, + 51, 206, 182, 205, 250, 173, 51, 206, 182, 249, 135, 205, 159, 51, 59, + 219, 190, 205, 7, 58, 4, 205, 7, 59, 4, 205, 7, 58, 210, 17, 213, 55, 59, + 210, 17, 213, 55, 85, 222, 228, 244, 249, 85, 214, 28, 3, 214, 28, 226, + 41, 85, 244, 250, 3, 244, 250, 226, 41, 85, 244, 249, 85, 46, 208, 230, + 205, 250, 173, 61, 3, 231, 164, 232, 137, 249, 135, 205, 159, 61, 3, 231, + 164, 203, 135, 205, 250, 173, 61, 3, 231, 155, 203, 135, 249, 135, 205, + 159, 61, 3, 231, 155, 203, 135, 248, 218, 61, 212, 107, 237, 231, 202, + 209, 173, 237, 68, 206, 182, 248, 218, 61, 212, 107, 237, 231, 202, 209, + 173, 237, 68, 107, 201, 179, 51, 200, 24, 201, 179, 51, 91, 201, 179, 51, + 237, 231, 201, 179, 51, 50, 53, 201, 179, 51, 124, 135, 201, 179, 51, + 173, 197, 89, 201, 179, 51, 173, 237, 69, 201, 179, 51, 205, 159, 237, + 69, 201, 179, 51, 205, 159, 197, 89, 201, 179, 51, 107, 201, 179, 240, + 64, 51, 200, 24, 201, 179, 240, 64, 51, 91, 201, 179, 240, 64, 51, 237, + 231, 201, 179, 240, 64, 51, 244, 205, 201, 179, 192, 244, 250, 51, 251, + 65, 201, 179, 192, 244, 250, 51, 107, 201, 179, 61, 202, 30, 154, 200, + 24, 201, 179, 61, 202, 30, 154, 91, 201, 179, 61, 202, 30, 154, 237, 231, + 201, 179, 61, 202, 30, 154, 173, 197, 89, 201, 179, 61, 202, 30, 154, + 173, 237, 69, 201, 179, 61, 202, 30, 154, 205, 159, 237, 69, 201, 179, + 61, 202, 30, 154, 205, 159, 197, 89, 201, 179, 61, 202, 30, 154, 107, + 201, 179, 61, 3, 52, 231, 155, 106, 200, 24, 201, 179, 61, 3, 52, 231, + 155, 106, 91, 201, 179, 61, 3, 52, 231, 155, 106, 237, 231, 201, 179, 61, + 3, 52, 231, 155, 106, 231, 155, 203, 155, 224, 153, 83, 203, 155, 224, + 153, 107, 201, 179, 61, 127, 91, 201, 179, 51, 200, 24, 201, 179, 61, + 107, 77, 237, 231, 201, 179, 51, 91, 201, 179, 61, 127, 107, 201, 179, + 51, 237, 231, 201, 179, 61, 107, 77, 200, 24, 201, 179, 51, 107, 201, + 179, 213, 219, 250, 214, 200, 24, 201, 179, 213, 219, 250, 214, 91, 201, + 179, 213, 219, 250, 214, 237, 231, 201, 179, 213, 219, 250, 214, 107, 58, + 46, 59, 51, 200, 24, 58, 46, 59, 51, 91, 58, 46, 59, 51, 237, 231, 58, + 46, 59, 51, 251, 65, 201, 179, 53, 200, 167, 51, 251, 65, 201, 179, 248, + 85, 200, 167, 51, 251, 65, 201, 179, 50, 200, 167, 51, 251, 65, 201, 179, + 201, 243, 200, 167, 51, 210, 94, 222, 184, 210, 94, 210, 22, 217, 80, + 222, 184, 217, 80, 210, 22, 235, 7, 241, 102, 250, 215, 244, 245, 251, + 64, 91, 58, 51, 202, 154, 201, 241, 107, 236, 166, 250, 217, 202, 154, + 210, 18, 200, 24, 236, 166, 250, 217, 202, 154, 201, 241, 91, 236, 166, + 250, 217, 202, 154, 222, 180, 237, 231, 236, 166, 250, 217, 58, 107, 236, + 166, 250, 217, 58, 200, 24, 236, 166, 250, 217, 58, 91, 236, 166, 250, + 217, 58, 237, 231, 236, 166, 250, 217, 237, 231, 201, 179, 61, 3, 181, + 202, 68, 222, 174, 237, 231, 201, 179, 61, 3, 181, 202, 68, 210, 11, 200, + 24, 201, 179, 61, 3, 181, 202, 68, 222, 174, 200, 24, 201, 179, 61, 3, + 181, 202, 68, 210, 11, 107, 201, 179, 61, 3, 181, 202, 68, 200, 23, 91, + 201, 179, 61, 3, 181, 202, 68, 200, 23, 107, 201, 179, 61, 3, 181, 202, + 68, 237, 230, 91, 201, 179, 61, 3, 181, 202, 68, 237, 230, 58, 241, 10, + 237, 231, 26, 107, 51, 58, 241, 10, 237, 231, 26, 91, 51, 58, 241, 10, + 200, 24, 26, 107, 51, 58, 241, 10, 200, 24, 26, 91, 51, 58, 241, 10, 107, + 26, 200, 24, 51, 58, 241, 10, 91, 26, 200, 24, 51, 58, 241, 10, 107, 26, + 237, 231, 51, 58, 241, 10, 91, 26, 237, 231, 51, 210, 63, 61, 135, 222, + 184, 210, 63, 61, 135, 210, 22, 210, 63, 61, 124, 222, 184, 210, 63, 61, + 124, 210, 22, 210, 63, 61, 50, 200, 36, 210, 63, 61, 53, 200, 36, 210, + 63, 61, 50, 237, 235, 210, 63, 61, 53, 237, 235, 200, 24, 59, 61, 234, + 235, 249, 80, 3, 231, 155, 154, 124, 250, 218, 226, 87, 39, 210, 164, + 248, 70, 214, 22, 59, 205, 92, 214, 22, 59, 26, 58, 205, 92, 214, 22, 58, + 205, 92, 249, 99, 111, 3, 175, 196, 222, 46, 196, 222, 46, 27, 196, 222, + 58, 47, 247, 34, 58, 239, 141, 247, 34, 163, 58, 213, 55, 231, 155, 58, + 214, 173, 58, 214, 173, 58, 219, 190, 200, 35, 201, 181, 247, 34, 58, + 219, 190, 237, 234, 201, 181, 247, 34, 58, 219, 190, 222, 179, 201, 181, + 247, 34, 58, 219, 190, 210, 17, 201, 181, 247, 34, 217, 95, 235, 24, 102, + 201, 243, 157, 58, 244, 249, 248, 85, 157, 58, 244, 249, 175, 235, 7, + 212, 109, 58, 241, 6, 209, 194, 175, 235, 7, 212, 109, 58, 241, 6, 59, + 235, 7, 212, 109, 241, 6, 209, 194, 59, 235, 7, 212, 109, 241, 6, 47, + 212, 79, 226, 68, 200, 66, 55, 233, 84, 78, 212, 122, 235, 24, 102, 212, + 122, 235, 24, 134, 212, 122, 235, 24, 136, 212, 122, 235, 24, 146, 201, + 200, 211, 246, 250, 175, 231, 10, 212, 231, 217, 91, 59, 218, 190, 207, + 113, 58, 239, 141, 214, 120, 241, 61, 201, 143, 175, 218, 190, 250, 210, + 241, 25, 232, 243, 195, 77, 223, 204, 251, 34, 251, 252, 197, 218, 212, + 80, 50, 157, 58, 205, 7, 53, 157, 58, 205, 7, 205, 8, 3, 50, 157, 248, + 136, 205, 8, 3, 53, 157, 248, 136, 107, 200, 215, 61, 3, 201, 181, 250, + 216, 200, 24, 200, 215, 61, 3, 201, 181, 250, 216, 91, 200, 215, 61, 3, + 201, 181, 250, 216, 237, 231, 200, 215, 61, 3, 201, 181, 250, 216, 236, + 156, 235, 24, 100, 236, 156, 235, 24, 102, 208, 130, 209, 103, 250, 174, + 16, 199, 19, 209, 103, 250, 174, 16, 216, 5, 209, 103, 250, 174, 16, 211, + 67, 209, 103, 250, 174, 16, 248, 159, 209, 103, 250, 174, 16, 207, 96, + 209, 103, 250, 174, 16, 201, 192, 236, 172, 2, 3, 226, 64, 60, 200, 48, + 105, 207, 92, 105, 237, 240, 105, 213, 123, 105, 210, 89, 53, 251, 90, + 232, 106, 213, 107, 105, 125, 6, 1, 250, 113, 125, 6, 1, 248, 9, 125, 6, + 1, 199, 116, 125, 6, 1, 233, 159, 125, 6, 1, 239, 23, 125, 6, 1, 196, 38, + 125, 6, 1, 195, 58, 125, 6, 1, 237, 151, 125, 6, 1, 195, 84, 125, 6, 1, + 225, 221, 125, 6, 1, 84, 225, 221, 125, 6, 1, 68, 125, 6, 1, 239, 44, + 125, 6, 1, 225, 23, 125, 6, 1, 222, 39, 125, 6, 1, 218, 59, 125, 6, 1, + 217, 206, 125, 6, 1, 214, 104, 125, 6, 1, 212, 104, 125, 6, 1, 209, 249, + 125, 6, 1, 205, 229, 125, 6, 1, 200, 246, 125, 6, 1, 200, 83, 125, 6, 1, + 234, 238, 125, 6, 1, 232, 91, 125, 6, 1, 214, 40, 125, 6, 1, 213, 92, + 125, 6, 1, 206, 154, 125, 6, 1, 201, 92, 125, 6, 1, 245, 36, 125, 6, 1, + 207, 50, 125, 6, 1, 196, 47, 125, 6, 1, 196, 49, 125, 6, 1, 196, 82, 125, + 6, 1, 205, 123, 142, 125, 6, 1, 195, 217, 125, 6, 1, 4, 195, 182, 125, 6, + 1, 4, 195, 183, 3, 203, 135, 125, 6, 1, 196, 3, 125, 6, 1, 226, 6, 4, + 195, 182, 125, 6, 1, 248, 171, 195, 182, 125, 6, 1, 226, 6, 248, 171, + 195, 182, 125, 6, 1, 235, 103, 125, 6, 1, 225, 219, 125, 6, 1, 206, 153, + 125, 6, 1, 201, 155, 63, 125, 6, 1, 222, 216, 218, 59, 125, 4, 1, 250, + 113, 125, 4, 1, 248, 9, 125, 4, 1, 199, 116, 125, 4, 1, 233, 159, 125, 4, + 1, 239, 23, 125, 4, 1, 196, 38, 125, 4, 1, 195, 58, 125, 4, 1, 237, 151, + 125, 4, 1, 195, 84, 125, 4, 1, 225, 221, 125, 4, 1, 84, 225, 221, 125, 4, + 1, 68, 125, 4, 1, 239, 44, 125, 4, 1, 225, 23, 125, 4, 1, 222, 39, 125, + 4, 1, 218, 59, 125, 4, 1, 217, 206, 125, 4, 1, 214, 104, 125, 4, 1, 212, + 104, 125, 4, 1, 209, 249, 125, 4, 1, 205, 229, 125, 4, 1, 200, 246, 125, + 4, 1, 200, 83, 125, 4, 1, 234, 238, 125, 4, 1, 232, 91, 125, 4, 1, 214, + 40, 125, 4, 1, 213, 92, 125, 4, 1, 206, 154, 125, 4, 1, 201, 92, 125, 4, + 1, 245, 36, 125, 4, 1, 207, 50, 125, 4, 1, 196, 47, 125, 4, 1, 196, 49, + 125, 4, 1, 196, 82, 125, 4, 1, 205, 123, 142, 125, 4, 1, 195, 217, 125, + 4, 1, 4, 195, 182, 125, 4, 1, 4, 195, 183, 3, 203, 135, 125, 4, 1, 196, + 3, 125, 4, 1, 226, 6, 4, 195, 182, 125, 4, 1, 248, 171, 195, 182, 125, 4, + 1, 226, 6, 248, 171, 195, 182, 125, 4, 1, 235, 103, 125, 4, 1, 225, 219, + 125, 4, 1, 206, 153, 125, 4, 1, 201, 155, 63, 125, 4, 1, 222, 216, 218, + 59, 8, 6, 1, 223, 100, 3, 52, 154, 8, 4, 1, 223, 100, 3, 52, 154, 8, 6, + 1, 223, 100, 3, 112, 202, 84, 8, 6, 1, 214, 4, 3, 106, 8, 6, 1, 211, 32, + 3, 203, 135, 8, 4, 1, 39, 3, 106, 8, 4, 1, 203, 217, 3, 239, 147, 106, 8, + 6, 1, 233, 16, 3, 239, 195, 8, 4, 1, 233, 16, 3, 239, 195, 8, 6, 1, 225, + 81, 3, 239, 195, 8, 4, 1, 225, 81, 3, 239, 195, 8, 6, 1, 195, 159, 3, + 239, 195, 8, 4, 1, 195, 159, 3, 239, 195, 8, 6, 1, 251, 134, 8, 6, 1, + 221, 137, 3, 122, 8, 6, 1, 163, 63, 8, 6, 1, 163, 251, 134, 8, 4, 1, 199, + 231, 3, 53, 122, 8, 6, 1, 197, 200, 3, 122, 8, 4, 1, 197, 200, 3, 122, 8, + 4, 1, 199, 231, 3, 241, 21, 8, 6, 1, 157, 233, 15, 8, 4, 1, 157, 233, 15, + 8, 4, 1, 203, 133, 212, 246, 8, 4, 1, 237, 136, 3, 216, 16, 8, 4, 1, 163, + 211, 32, 3, 203, 135, 8, 4, 1, 177, 3, 126, 210, 3, 226, 41, 8, 1, 4, 6, + 163, 69, 8, 204, 143, 4, 1, 225, 217, 73, 1, 6, 199, 230, 8, 6, 1, 209, + 81, 3, 204, 63, 203, 135, 8, 6, 1, 195, 159, 3, 204, 63, 203, 135, 88, 6, + 1, 251, 158, 88, 4, 1, 251, 158, 88, 6, 1, 199, 31, 88, 4, 1, 199, 31, + 88, 6, 1, 234, 94, 88, 4, 1, 234, 94, 88, 6, 1, 240, 103, 88, 4, 1, 240, + 103, 88, 6, 1, 237, 32, 88, 4, 1, 237, 32, 88, 6, 1, 205, 164, 88, 4, 1, + 205, 164, 88, 6, 1, 195, 96, 88, 4, 1, 195, 96, 88, 6, 1, 232, 162, 88, + 4, 1, 232, 162, 88, 6, 1, 202, 197, 88, 4, 1, 202, 197, 88, 6, 1, 230, + 207, 88, 4, 1, 230, 207, 88, 6, 1, 225, 7, 88, 4, 1, 225, 7, 88, 6, 1, + 222, 211, 88, 4, 1, 222, 211, 88, 6, 1, 219, 78, 88, 4, 1, 219, 78, 88, + 6, 1, 216, 223, 88, 4, 1, 216, 223, 88, 6, 1, 223, 203, 88, 4, 1, 223, + 203, 88, 6, 1, 72, 88, 4, 1, 72, 88, 6, 1, 212, 220, 88, 4, 1, 212, 220, + 88, 6, 1, 209, 232, 88, 4, 1, 209, 232, 88, 6, 1, 206, 74, 88, 4, 1, 206, + 74, 88, 6, 1, 203, 89, 88, 4, 1, 203, 89, 88, 6, 1, 200, 114, 88, 4, 1, + 200, 114, 88, 6, 1, 235, 153, 88, 4, 1, 235, 153, 88, 6, 1, 224, 124, 88, + 4, 1, 224, 124, 88, 6, 1, 211, 238, 88, 4, 1, 211, 238, 88, 6, 1, 214, + 96, 88, 4, 1, 214, 96, 88, 6, 1, 239, 145, 251, 164, 88, 4, 1, 239, 145, + 251, 164, 88, 6, 1, 37, 88, 251, 194, 88, 4, 1, 37, 88, 251, 194, 88, 6, + 1, 241, 44, 237, 32, 88, 4, 1, 241, 44, 237, 32, 88, 6, 1, 239, 145, 225, + 7, 88, 4, 1, 239, 145, 225, 7, 88, 6, 1, 239, 145, 216, 223, 88, 4, 1, + 239, 145, 216, 223, 88, 6, 1, 241, 44, 216, 223, 88, 4, 1, 241, 44, 216, + 223, 88, 6, 1, 37, 88, 214, 96, 88, 4, 1, 37, 88, 214, 96, 88, 6, 1, 208, + 222, 88, 4, 1, 208, 222, 88, 6, 1, 241, 59, 206, 247, 88, 4, 1, 241, 59, + 206, 247, 88, 6, 1, 37, 88, 206, 247, 88, 4, 1, 37, 88, 206, 247, 88, 6, + 1, 37, 88, 236, 141, 88, 4, 1, 37, 88, 236, 141, 88, 6, 1, 251, 177, 224, + 129, 88, 4, 1, 251, 177, 224, 129, 88, 6, 1, 239, 145, 231, 156, 88, 4, + 1, 239, 145, 231, 156, 88, 6, 1, 37, 88, 231, 156, 88, 4, 1, 37, 88, 231, + 156, 88, 6, 1, 37, 88, 142, 88, 4, 1, 37, 88, 142, 88, 6, 1, 223, 99, + 142, 88, 4, 1, 223, 99, 142, 88, 6, 1, 37, 88, 232, 112, 88, 4, 1, 37, + 88, 232, 112, 88, 6, 1, 37, 88, 232, 165, 88, 4, 1, 37, 88, 232, 165, 88, + 6, 1, 37, 88, 234, 89, 88, 4, 1, 37, 88, 234, 89, 88, 6, 1, 37, 88, 239, + 47, 88, 4, 1, 37, 88, 239, 47, 88, 6, 1, 37, 88, 206, 213, 88, 4, 1, 37, + 88, 206, 213, 88, 6, 1, 37, 215, 153, 206, 213, 88, 4, 1, 37, 215, 153, + 206, 213, 88, 6, 1, 37, 215, 153, 217, 19, 88, 4, 1, 37, 215, 153, 217, + 19, 88, 6, 1, 37, 215, 153, 215, 89, 88, 4, 1, 37, 215, 153, 215, 89, 88, + 6, 1, 37, 215, 153, 197, 124, 88, 4, 1, 37, 215, 153, 197, 124, 88, 16, + 225, 31, 88, 16, 219, 79, 209, 232, 88, 16, 212, 221, 209, 232, 88, 16, + 204, 252, 88, 16, 203, 90, 209, 232, 88, 16, 224, 125, 209, 232, 88, 16, + 206, 214, 206, 74, 88, 6, 1, 241, 44, 206, 247, 88, 4, 1, 241, 44, 206, + 247, 88, 6, 1, 241, 44, 234, 89, 88, 4, 1, 241, 44, 234, 89, 88, 38, 216, + 224, 57, 88, 38, 205, 116, 250, 187, 88, 38, 205, 116, 222, 148, 88, 6, + 1, 248, 109, 224, 129, 88, 4, 1, 248, 109, 224, 129, 88, 37, 215, 153, + 234, 217, 204, 226, 88, 37, 215, 153, 239, 86, 211, 79, 78, 88, 37, 215, + 153, 226, 66, 211, 79, 78, 88, 37, 215, 153, 199, 102, 239, 59, 88, 191, + 97, 232, 225, 88, 234, 217, 204, 226, 88, 218, 185, 239, 59, 94, 4, 1, + 251, 106, 94, 4, 1, 249, 93, 94, 4, 1, 234, 93, 94, 4, 1, 239, 6, 94, 4, + 1, 236, 230, 94, 4, 1, 199, 16, 94, 4, 1, 195, 82, 94, 4, 1, 203, 114, + 94, 4, 1, 226, 86, 94, 4, 1, 225, 17, 94, 4, 1, 222, 222, 94, 4, 1, 220, + 62, 94, 4, 1, 217, 211, 94, 4, 1, 214, 119, 94, 4, 1, 213, 157, 94, 4, 1, + 195, 70, 94, 4, 1, 210, 229, 94, 4, 1, 208, 219, 94, 4, 1, 203, 101, 94, + 4, 1, 200, 72, 94, 4, 1, 212, 254, 94, 4, 1, 224, 134, 94, 4, 1, 233, + 221, 94, 4, 1, 211, 144, 94, 4, 1, 206, 211, 94, 4, 1, 245, 62, 94, 4, 1, + 247, 142, 94, 4, 1, 225, 162, 94, 4, 1, 245, 0, 94, 4, 1, 247, 0, 94, 4, + 1, 196, 206, 94, 4, 1, 225, 177, 94, 4, 1, 232, 242, 94, 4, 1, 232, 147, + 94, 4, 1, 232, 58, 94, 4, 1, 197, 109, 94, 4, 1, 232, 175, 94, 4, 1, 231, + 181, 94, 4, 1, 196, 5, 94, 4, 1, 251, 234, 202, 104, 1, 164, 202, 104, 1, + 196, 125, 202, 104, 1, 196, 124, 202, 104, 1, 196, 114, 202, 104, 1, 196, + 112, 202, 104, 1, 248, 212, 252, 24, 196, 107, 202, 104, 1, 196, 107, + 202, 104, 1, 196, 122, 202, 104, 1, 196, 119, 202, 104, 1, 196, 121, 202, + 104, 1, 196, 120, 202, 104, 1, 196, 29, 202, 104, 1, 196, 116, 202, 104, + 1, 196, 105, 202, 104, 1, 201, 32, 196, 105, 202, 104, 1, 196, 102, 202, + 104, 1, 196, 110, 202, 104, 1, 248, 212, 252, 24, 196, 110, 202, 104, 1, + 201, 32, 196, 110, 202, 104, 1, 196, 109, 202, 104, 1, 196, 129, 202, + 104, 1, 196, 103, 202, 104, 1, 201, 32, 196, 103, 202, 104, 1, 196, 92, + 202, 104, 1, 201, 32, 196, 92, 202, 104, 1, 196, 24, 202, 104, 1, 196, + 71, 202, 104, 1, 251, 207, 196, 71, 202, 104, 1, 201, 32, 196, 71, 202, + 104, 1, 196, 101, 202, 104, 1, 196, 100, 202, 104, 1, 196, 97, 202, 104, + 1, 201, 32, 196, 111, 202, 104, 1, 201, 32, 196, 95, 202, 104, 1, 196, + 93, 202, 104, 1, 195, 217, 202, 104, 1, 196, 90, 202, 104, 1, 196, 88, + 202, 104, 1, 196, 113, 202, 104, 1, 201, 32, 196, 113, 202, 104, 1, 250, + 118, 196, 113, 202, 104, 1, 196, 87, 202, 104, 1, 196, 85, 202, 104, 1, + 196, 86, 202, 104, 1, 196, 84, 202, 104, 1, 196, 83, 202, 104, 1, 196, + 123, 202, 104, 1, 196, 81, 202, 104, 1, 196, 79, 202, 104, 1, 196, 78, + 202, 104, 1, 196, 75, 202, 104, 1, 196, 72, 202, 104, 1, 203, 80, 196, + 72, 202, 104, 1, 196, 70, 202, 104, 1, 196, 69, 202, 104, 1, 196, 3, 202, + 104, 73, 1, 223, 72, 78, 202, 104, 207, 91, 78, 202, 104, 108, 225, 124, + 35, 5, 222, 6, 35, 5, 218, 244, 35, 5, 209, 224, 35, 5, 205, 192, 35, 5, + 206, 197, 35, 5, 248, 115, 35, 5, 202, 22, 35, 5, 244, 181, 35, 5, 216, + 43, 35, 5, 215, 72, 35, 5, 233, 152, 214, 190, 35, 5, 195, 10, 35, 5, + 239, 26, 35, 5, 240, 10, 35, 5, 225, 128, 35, 5, 202, 168, 35, 5, 245, + 48, 35, 5, 212, 233, 35, 5, 212, 116, 35, 5, 233, 236, 35, 5, 233, 232, + 35, 5, 233, 233, 35, 5, 233, 234, 35, 5, 205, 80, 35, 5, 205, 34, 35, 5, + 205, 47, 35, 5, 205, 79, 35, 5, 205, 52, 35, 5, 205, 53, 35, 5, 205, 39, + 35, 5, 247, 80, 35, 5, 247, 59, 35, 5, 247, 61, 35, 5, 247, 79, 35, 5, + 247, 77, 35, 5, 247, 78, 35, 5, 247, 60, 35, 5, 194, 228, 35, 5, 194, + 206, 35, 5, 194, 219, 35, 5, 194, 227, 35, 5, 194, 222, 35, 5, 194, 223, + 35, 5, 194, 211, 35, 5, 247, 75, 35, 5, 247, 62, 35, 5, 247, 64, 35, 5, + 247, 74, 35, 5, 247, 72, 35, 5, 247, 73, 35, 5, 247, 63, 35, 5, 211, 44, + 35, 5, 211, 34, 35, 5, 211, 40, 35, 5, 211, 43, 35, 5, 211, 41, 35, 5, + 211, 42, 35, 5, 211, 39, 35, 5, 223, 110, 35, 5, 223, 102, 35, 5, 223, + 105, 35, 5, 223, 109, 35, 5, 223, 106, 35, 5, 223, 107, 35, 5, 223, 103, + 35, 5, 196, 164, 35, 5, 196, 151, 35, 5, 196, 159, 35, 5, 196, 163, 35, + 5, 196, 161, 35, 5, 196, 162, 35, 5, 196, 158, 35, 5, 233, 27, 35, 5, + 233, 17, 35, 5, 233, 20, 35, 5, 233, 26, 35, 5, 233, 22, 35, 5, 233, 23, + 35, 5, 233, 19, 38, 40, 1, 249, 9, 38, 40, 1, 199, 118, 38, 40, 1, 233, + 216, 38, 40, 1, 239, 252, 38, 40, 1, 195, 65, 38, 40, 1, 195, 88, 38, 40, + 1, 155, 38, 40, 1, 237, 7, 38, 40, 1, 236, 241, 38, 40, 1, 236, 230, 38, + 40, 1, 72, 38, 40, 1, 213, 92, 38, 40, 1, 236, 163, 38, 40, 1, 236, 151, + 38, 40, 1, 203, 68, 38, 40, 1, 142, 38, 40, 1, 201, 107, 38, 40, 1, 245, + 103, 38, 40, 1, 207, 50, 38, 40, 1, 207, 2, 38, 40, 1, 235, 103, 38, 40, + 1, 236, 147, 38, 40, 1, 63, 38, 40, 1, 226, 147, 38, 40, 1, 239, 45, 38, + 40, 1, 218, 203, 200, 87, 38, 40, 1, 196, 84, 38, 40, 1, 195, 217, 38, + 40, 1, 226, 5, 63, 38, 40, 1, 222, 47, 195, 182, 38, 40, 1, 248, 171, + 195, 182, 38, 40, 1, 226, 5, 248, 171, 195, 182, 53, 251, 91, 204, 138, + 220, 24, 53, 251, 91, 237, 250, 204, 138, 220, 24, 50, 204, 138, 179, 53, + 204, 138, 179, 50, 237, 250, 204, 138, 179, 53, 237, 250, 204, 138, 179, + 210, 215, 226, 28, 220, 24, 210, 215, 237, 250, 226, 28, 220, 24, 237, + 250, 201, 199, 220, 24, 50, 201, 199, 179, 53, 201, 199, 179, 210, 215, + 205, 94, 50, 210, 215, 214, 121, 179, 53, 210, 215, 214, 121, 179, 237, + 55, 241, 98, 213, 152, 235, 26, 213, 152, 210, 89, 235, 26, 213, 152, + 231, 4, 237, 250, 214, 185, 237, 231, 251, 101, 200, 24, 251, 101, 237, + 250, 210, 17, 251, 90, 52, 214, 182, 231, 7, 226, 17, 226, 26, 213, 207, + 248, 57, 231, 8, 3, 239, 150, 202, 85, 3, 210, 3, 57, 50, 126, 213, 143, + 179, 53, 126, 213, 143, 179, 202, 85, 3, 76, 57, 202, 85, 3, 76, 60, 50, + 83, 249, 80, 3, 211, 73, 53, 83, 249, 80, 3, 211, 73, 201, 243, 50, 157, + 179, 201, 243, 53, 157, 179, 248, 85, 50, 157, 179, 248, 85, 53, 157, + 179, 50, 206, 96, 118, 179, 53, 206, 96, 118, 179, 50, 52, 213, 140, 53, + 52, 213, 140, 99, 238, 251, 127, 97, 76, 211, 213, 97, 76, 127, 99, 238, + 251, 211, 213, 103, 235, 7, 76, 211, 213, 235, 101, 76, 78, 210, 89, 211, + 79, 78, 83, 202, 84, 210, 3, 212, 110, 197, 9, 207, 91, 112, 238, 253, + 163, 244, 159, 210, 215, 238, 253, 210, 215, 244, 159, 163, 207, 105, + 240, 119, 3, 50, 233, 70, 240, 119, 3, 53, 233, 70, 163, 240, 118, 201, + 243, 157, 208, 133, 55, 200, 216, 240, 65, 202, 152, 240, 65, 204, 242, + 234, 217, 204, 226, 83, 206, 29, 238, 250, 197, 56, 83, 222, 75, 247, + 123, 52, 231, 7, 210, 89, 244, 159, 52, 221, 204, 211, 62, 78, 240, 66, + 3, 50, 200, 27, 52, 204, 77, 78, 226, 17, 126, 224, 221, 226, 17, 126, + 224, 222, 3, 224, 222, 57, 126, 224, 221, 126, 224, 222, 3, 238, 253, 52, + 205, 19, 244, 159, 237, 250, 205, 177, 201, 165, 240, 118, 219, 191, 244, + 159, 213, 151, 78, 211, 212, 236, 254, 78, 241, 99, 199, 102, 239, 59, + 12, 44, 210, 119, 12, 44, 244, 214, 12, 44, 208, 136, 100, 12, 44, 208, + 136, 102, 12, 44, 208, 136, 134, 12, 44, 213, 28, 12, 44, 248, 70, 12, + 44, 203, 152, 12, 44, 224, 22, 100, 12, 44, 224, 22, 102, 12, 44, 239, + 56, 12, 44, 208, 140, 12, 44, 4, 100, 12, 44, 4, 102, 12, 44, 222, 244, + 100, 12, 44, 222, 244, 102, 12, 44, 222, 244, 134, 12, 44, 222, 244, 136, + 12, 44, 205, 212, 12, 44, 202, 156, 12, 44, 205, 209, 100, 12, 44, 205, + 209, 102, 12, 44, 232, 127, 100, 12, 44, 232, 127, 102, 12, 44, 232, 209, + 12, 44, 210, 204, 12, 44, 245, 45, 12, 44, 204, 111, 12, 44, 218, 189, + 12, 44, 239, 249, 12, 44, 218, 178, 12, 44, 244, 232, 12, 44, 197, 128, + 100, 12, 44, 197, 128, 102, 12, 44, 235, 118, 12, 44, 213, 105, 100, 12, + 44, 213, 105, 102, 12, 44, 206, 69, 157, 201, 191, 201, 118, 12, 44, 241, + 83, 12, 44, 239, 17, 12, 44, 225, 209, 12, 44, 248, 108, 77, 244, 197, + 12, 44, 236, 67, 12, 44, 205, 118, 100, 12, 44, 205, 118, 102, 12, 44, + 249, 95, 12, 44, 206, 76, 12, 44, 247, 204, 206, 76, 12, 44, 217, 89, + 100, 12, 44, 217, 89, 102, 12, 44, 217, 89, 134, 12, 44, 217, 89, 136, + 12, 44, 219, 150, 12, 44, 206, 249, 12, 44, 210, 210, 12, 44, 236, 97, + 12, 44, 214, 133, 12, 44, 248, 29, 100, 12, 44, 248, 29, 102, 12, 44, + 219, 199, 12, 44, 218, 184, 12, 44, 233, 104, 100, 12, 44, 233, 104, 102, + 12, 44, 233, 104, 134, 12, 44, 202, 102, 12, 44, 244, 196, 12, 44, 197, + 89, 100, 12, 44, 197, 89, 102, 12, 44, 247, 204, 208, 129, 12, 44, 206, + 69, 231, 102, 12, 44, 231, 102, 12, 44, 247, 204, 205, 131, 12, 44, 247, + 204, 206, 244, 12, 44, 235, 37, 12, 44, 247, 204, 247, 99, 12, 44, 206, + 69, 197, 150, 12, 44, 197, 151, 100, 12, 44, 197, 151, 102, 12, 44, 244, + 235, 12, 44, 247, 204, 233, 135, 12, 44, 181, 100, 12, 44, 181, 102, 12, + 44, 247, 204, 221, 240, 12, 44, 247, 204, 234, 74, 12, 44, 218, 173, 100, + 12, 44, 218, 173, 102, 12, 44, 210, 217, 12, 44, 248, 118, 12, 44, 247, + 204, 203, 107, 222, 190, 12, 44, 247, 204, 222, 192, 12, 44, 247, 204, + 197, 50, 12, 44, 247, 204, 235, 55, 12, 44, 237, 66, 100, 12, 44, 237, + 66, 102, 12, 44, 237, 66, 134, 12, 44, 247, 204, 237, 65, 12, 44, 232, + 137, 12, 44, 247, 204, 231, 98, 12, 44, 248, 104, 12, 44, 233, 200, 12, + 44, 247, 204, 235, 111, 12, 44, 247, 204, 248, 156, 12, 44, 247, 204, + 208, 233, 12, 44, 206, 69, 197, 79, 12, 44, 206, 69, 196, 61, 12, 44, + 247, 204, 234, 236, 12, 44, 225, 216, 236, 102, 12, 44, 247, 204, 236, + 102, 12, 44, 225, 216, 201, 244, 12, 44, 247, 204, 201, 244, 12, 44, 225, + 216, 237, 223, 12, 44, 247, 204, 237, 223, 12, 44, 201, 1, 12, 44, 225, + 216, 201, 1, 12, 44, 247, 204, 201, 1, 79, 44, 100, 79, 44, 222, 75, 79, + 44, 238, 253, 79, 44, 205, 248, 79, 44, 208, 135, 79, 44, 122, 79, 44, + 102, 79, 44, 222, 104, 79, 44, 220, 62, 79, 44, 222, 169, 79, 44, 236, + 204, 79, 44, 171, 79, 44, 135, 248, 70, 79, 44, 241, 86, 79, 44, 230, + 201, 79, 44, 203, 152, 79, 44, 192, 248, 70, 79, 44, 224, 21, 79, 44, + 212, 58, 79, 44, 196, 255, 79, 44, 205, 107, 79, 44, 53, 192, 248, 70, + 79, 44, 232, 59, 236, 225, 79, 44, 203, 23, 79, 44, 239, 56, 79, 44, 208, + 140, 79, 44, 244, 214, 79, 44, 212, 8, 79, 44, 251, 216, 79, 44, 218, + 164, 79, 44, 236, 225, 79, 44, 237, 72, 79, 44, 208, 168, 79, 44, 233, + 144, 79, 44, 233, 145, 205, 226, 79, 44, 236, 101, 79, 44, 248, 170, 79, + 44, 197, 21, 79, 44, 245, 66, 79, 44, 209, 205, 79, 44, 226, 82, 79, 44, + 205, 224, 79, 44, 222, 243, 79, 44, 241, 96, 79, 44, 205, 98, 79, 44, + 218, 169, 79, 44, 209, 246, 79, 44, 197, 6, 79, 44, 214, 110, 79, 44, + 201, 9, 79, 44, 237, 203, 79, 44, 206, 182, 202, 156, 79, 44, 237, 250, + 244, 214, 79, 44, 181, 204, 202, 79, 44, 99, 232, 184, 79, 44, 206, 188, + 79, 44, 248, 77, 79, 44, 205, 208, 79, 44, 248, 36, 79, 44, 204, 241, 79, + 44, 232, 126, 79, 44, 232, 226, 79, 44, 239, 1, 79, 44, 232, 209, 79, 44, + 248, 57, 79, 44, 210, 204, 79, 44, 208, 153, 79, 44, 239, 88, 79, 44, + 250, 123, 79, 44, 205, 94, 79, 44, 216, 18, 79, 44, 204, 111, 79, 44, + 208, 180, 79, 44, 218, 189, 79, 44, 201, 190, 79, 44, 223, 68, 79, 44, + 204, 226, 79, 44, 239, 249, 79, 44, 197, 104, 79, 44, 239, 29, 216, 18, + 79, 44, 244, 155, 79, 44, 234, 210, 79, 44, 244, 226, 79, 44, 204, 247, + 79, 44, 197, 127, 79, 44, 235, 118, 79, 44, 244, 222, 79, 44, 235, 196, + 79, 44, 52, 196, 222, 79, 44, 157, 201, 191, 201, 118, 79, 44, 205, 239, + 79, 44, 235, 208, 79, 44, 241, 83, 79, 44, 239, 17, 79, 44, 212, 4, 79, + 44, 225, 209, 79, 44, 219, 173, 79, 44, 202, 83, 79, 44, 204, 58, 79, 44, + 222, 98, 79, 44, 200, 2, 79, 44, 235, 151, 79, 44, 248, 108, 77, 244, + 197, 79, 44, 206, 102, 79, 44, 237, 250, 203, 15, 79, 44, 197, 73, 79, + 44, 206, 1, 79, 44, 239, 75, 79, 44, 236, 67, 79, 44, 205, 134, 79, 44, + 51, 79, 44, 204, 228, 79, 44, 205, 117, 79, 44, 201, 216, 79, 44, 233, + 113, 79, 44, 247, 85, 79, 44, 205, 12, 79, 44, 249, 95, 79, 44, 210, 60, + 79, 44, 206, 76, 79, 44, 225, 201, 79, 44, 217, 88, 79, 44, 206, 249, 79, + 44, 235, 184, 79, 44, 214, 133, 79, 44, 251, 100, 79, 44, 212, 132, 79, + 44, 237, 76, 79, 44, 248, 28, 79, 44, 219, 199, 79, 44, 219, 17, 79, 44, + 207, 112, 79, 44, 250, 221, 79, 44, 218, 184, 79, 44, 201, 249, 79, 44, + 214, 80, 79, 44, 248, 112, 79, 44, 204, 224, 79, 44, 244, 167, 79, 44, + 233, 103, 79, 44, 202, 102, 79, 44, 226, 45, 79, 44, 248, 124, 79, 44, + 197, 151, 236, 225, 79, 44, 244, 196, 79, 44, 197, 88, 79, 44, 208, 129, + 79, 44, 231, 102, 79, 44, 205, 131, 79, 44, 199, 144, 79, 44, 249, 4, 79, + 44, 212, 184, 79, 44, 249, 125, 79, 44, 206, 244, 79, 44, 210, 157, 79, + 44, 209, 117, 79, 44, 235, 37, 79, 44, 248, 110, 79, 44, 247, 99, 79, 44, + 248, 141, 79, 44, 218, 186, 79, 44, 197, 150, 79, 44, 244, 235, 79, 44, + 197, 46, 79, 44, 239, 67, 79, 44, 199, 17, 79, 44, 233, 135, 79, 44, 221, + 240, 79, 44, 234, 74, 79, 44, 218, 172, 79, 44, 205, 247, 79, 44, 206, + 182, 203, 134, 248, 156, 79, 44, 210, 217, 79, 44, 248, 118, 79, 44, 196, + 245, 79, 44, 235, 233, 79, 44, 222, 190, 79, 44, 203, 107, 222, 190, 79, + 44, 222, 186, 79, 44, 205, 161, 79, 44, 222, 192, 79, 44, 197, 50, 79, + 44, 235, 55, 79, 44, 237, 65, 79, 44, 232, 137, 79, 44, 234, 252, 79, 44, + 231, 98, 79, 44, 248, 104, 79, 44, 203, 119, 79, 44, 232, 233, 79, 44, + 235, 144, 79, 44, 209, 10, 197, 46, 79, 44, 247, 87, 79, 44, 233, 200, + 79, 44, 235, 111, 79, 44, 248, 156, 79, 44, 208, 233, 79, 44, 239, 234, + 79, 44, 197, 79, 79, 44, 232, 102, 79, 44, 196, 61, 79, 44, 219, 28, 79, + 44, 248, 136, 79, 44, 236, 237, 79, 44, 234, 236, 79, 44, 201, 162, 79, + 44, 237, 206, 79, 44, 210, 198, 79, 44, 216, 20, 79, 44, 236, 102, 79, + 44, 201, 244, 79, 44, 237, 223, 79, 44, 201, 1, 79, 44, 235, 58, 143, + 239, 193, 190, 50, 202, 30, 210, 22, 143, 239, 193, 190, 90, 202, 30, 60, + 143, 239, 193, 190, 50, 202, 30, 112, 26, 210, 22, 143, 239, 193, 190, + 90, 202, 30, 112, 26, 60, 143, 239, 193, 190, 234, 217, 204, 81, 143, + 239, 193, 190, 204, 82, 234, 235, 57, 143, 239, 193, 190, 204, 82, 234, + 235, 60, 143, 239, 193, 190, 204, 82, 234, 235, 222, 184, 143, 239, 193, + 190, 204, 82, 234, 235, 200, 33, 222, 184, 143, 239, 193, 190, 204, 82, + 234, 235, 200, 33, 210, 22, 143, 239, 193, 190, 204, 82, 234, 235, 221, + 203, 222, 184, 143, 239, 193, 190, 214, 24, 143, 205, 148, 143, 244, 159, + 143, 234, 217, 204, 226, 239, 64, 78, 225, 202, 226, 65, 205, 11, 105, + 143, 225, 232, 78, 143, 244, 199, 78, 143, 31, 195, 79, 50, 251, 91, 179, + 53, 251, 91, 179, 50, 52, 251, 91, 179, 53, 52, 251, 91, 179, 50, 241, + 102, 179, 53, 241, 102, 179, 50, 59, 241, 102, 179, 53, 59, 241, 102, + 179, 50, 58, 222, 147, 179, 53, 58, 222, 147, 179, 212, 72, 78, 234, 13, + 78, 50, 201, 231, 206, 245, 179, 53, 201, 231, 206, 245, 179, 50, 59, + 222, 147, 179, 53, 59, 222, 147, 179, 50, 59, 201, 231, 206, 245, 179, + 53, 59, 201, 231, 206, 245, 179, 50, 59, 47, 179, 53, 59, 47, 179, 197, + 123, 240, 65, 210, 89, 52, 212, 20, 211, 62, 78, 52, 212, 20, 211, 62, + 78, 126, 52, 212, 20, 211, 62, 78, 212, 72, 117, 235, 233, 232, 181, 215, + 142, 100, 232, 181, 215, 142, 102, 232, 181, 215, 142, 134, 232, 181, + 215, 142, 136, 232, 181, 215, 142, 146, 232, 181, 215, 142, 167, 232, + 181, 215, 142, 178, 232, 181, 215, 142, 171, 232, 181, 215, 142, 182, + 143, 222, 128, 152, 78, 143, 209, 250, 152, 78, 143, 239, 202, 152, 78, + 143, 236, 203, 152, 78, 29, 206, 62, 76, 152, 78, 29, 52, 76, 152, 78, + 197, 119, 240, 65, 83, 225, 16, 210, 120, 78, 83, 225, 16, 210, 120, 3, + 198, 244, 205, 162, 78, 83, 225, 16, 210, 120, 117, 200, 33, 232, 225, + 83, 225, 16, 210, 120, 3, 198, 244, 205, 162, 117, 200, 33, 232, 225, 83, + 225, 16, 210, 120, 117, 221, 203, 232, 225, 46, 212, 72, 78, 143, 203, + 36, 222, 76, 235, 181, 207, 91, 105, 232, 181, 215, 142, 203, 23, 232, + 181, 215, 142, 200, 234, 232, 181, 215, 142, 202, 177, 83, 143, 225, 232, + 78, 220, 5, 78, 213, 134, 251, 127, 78, 143, 62, 226, 68, 143, 157, 235, + 137, 205, 148, 188, 1, 4, 63, 188, 1, 63, 188, 1, 4, 68, 188, 1, 68, 188, + 1, 4, 66, 188, 1, 66, 188, 1, 4, 69, 188, 1, 69, 188, 1, 4, 72, 188, 1, + 72, 188, 1, 155, 188, 1, 234, 123, 188, 1, 224, 101, 188, 1, 233, 192, + 188, 1, 223, 187, 188, 1, 233, 76, 188, 1, 224, 209, 188, 1, 234, 48, + 188, 1, 224, 11, 188, 1, 233, 144, 188, 1, 183, 188, 1, 195, 115, 188, 1, + 206, 112, 188, 1, 195, 33, 188, 1, 204, 172, 188, 1, 194, 255, 188, 1, + 208, 147, 188, 1, 195, 88, 188, 1, 205, 200, 188, 1, 195, 11, 188, 1, + 189, 188, 1, 240, 136, 188, 1, 202, 122, 188, 1, 239, 152, 188, 1, 4, + 201, 40, 188, 1, 201, 40, 188, 1, 237, 201, 188, 1, 203, 68, 188, 1, 239, + 252, 188, 1, 149, 188, 1, 239, 28, 188, 1, 176, 188, 1, 216, 223, 188, 1, + 215, 186, 188, 1, 217, 118, 188, 1, 216, 50, 188, 1, 142, 188, 1, 249, + 145, 188, 1, 161, 188, 1, 232, 71, 188, 1, 248, 184, 188, 1, 212, 220, + 188, 1, 231, 75, 188, 1, 248, 21, 188, 1, 211, 227, 188, 1, 232, 147, + 188, 1, 249, 9, 188, 1, 213, 92, 188, 1, 231, 193, 188, 1, 248, 116, 188, + 1, 212, 117, 188, 1, 166, 188, 1, 219, 78, 188, 1, 218, 145, 188, 1, 219, + 207, 188, 1, 218, 251, 188, 1, 4, 164, 188, 1, 164, 188, 1, 4, 195, 217, + 188, 1, 195, 217, 188, 1, 4, 196, 3, 188, 1, 196, 3, 188, 1, 169, 188, 1, + 210, 72, 188, 1, 209, 140, 188, 1, 210, 183, 188, 1, 209, 232, 188, 1, 4, + 197, 166, 188, 1, 197, 166, 188, 1, 197, 70, 188, 1, 197, 109, 188, 1, + 197, 34, 188, 1, 218, 55, 188, 1, 197, 220, 188, 1, 4, 155, 188, 1, 4, + 224, 209, 38, 224, 234, 198, 244, 205, 162, 78, 38, 224, 234, 207, 110, + 205, 162, 78, 224, 234, 198, 244, 205, 162, 78, 224, 234, 207, 110, 205, + 162, 78, 188, 225, 232, 78, 188, 198, 244, 225, 232, 78, 188, 239, 111, + 195, 233, 224, 234, 52, 231, 7, 71, 1, 4, 63, 71, 1, 63, 71, 1, 4, 68, + 71, 1, 68, 71, 1, 4, 66, 71, 1, 66, 71, 1, 4, 69, 71, 1, 69, 71, 1, 4, + 72, 71, 1, 72, 71, 1, 155, 71, 1, 234, 123, 71, 1, 224, 101, 71, 1, 233, + 192, 71, 1, 223, 187, 71, 1, 233, 76, 71, 1, 224, 209, 71, 1, 234, 48, + 71, 1, 224, 11, 71, 1, 233, 144, 71, 1, 183, 71, 1, 195, 115, 71, 1, 206, + 112, 71, 1, 195, 33, 71, 1, 204, 172, 71, 1, 194, 255, 71, 1, 208, 147, + 71, 1, 195, 88, 71, 1, 205, 200, 71, 1, 195, 11, 71, 1, 189, 71, 1, 240, + 136, 71, 1, 202, 122, 71, 1, 239, 152, 71, 1, 4, 201, 40, 71, 1, 201, 40, + 71, 1, 237, 201, 71, 1, 203, 68, 71, 1, 239, 252, 71, 1, 149, 71, 1, 239, + 28, 71, 1, 176, 71, 1, 216, 223, 71, 1, 215, 186, 71, 1, 217, 118, 71, 1, + 216, 50, 71, 1, 142, 71, 1, 249, 145, 71, 1, 161, 71, 1, 232, 71, 71, 1, + 248, 184, 71, 1, 212, 220, 71, 1, 231, 75, 71, 1, 248, 21, 71, 1, 211, + 227, 71, 1, 232, 147, 71, 1, 249, 9, 71, 1, 213, 92, 71, 1, 231, 193, 71, + 1, 248, 116, 71, 1, 212, 117, 71, 1, 166, 71, 1, 219, 78, 71, 1, 218, + 145, 71, 1, 219, 207, 71, 1, 218, 251, 71, 1, 4, 164, 71, 1, 164, 71, 1, + 4, 195, 217, 71, 1, 195, 217, 71, 1, 4, 196, 3, 71, 1, 196, 3, 71, 1, + 169, 71, 1, 210, 72, 71, 1, 209, 140, 71, 1, 210, 183, 71, 1, 209, 232, + 71, 1, 4, 197, 166, 71, 1, 197, 166, 71, 1, 197, 70, 71, 1, 197, 109, 71, + 1, 197, 34, 71, 1, 218, 55, 71, 1, 197, 220, 71, 1, 4, 155, 71, 1, 4, + 224, 209, 71, 1, 199, 152, 71, 1, 199, 34, 71, 1, 199, 118, 71, 1, 198, + 248, 71, 112, 238, 253, 224, 234, 211, 252, 205, 162, 78, 71, 225, 232, + 78, 71, 198, 244, 225, 232, 78, 71, 239, 111, 223, 229, 248, 94, 1, 250, + 112, 248, 94, 1, 214, 3, 248, 94, 1, 221, 136, 248, 94, 1, 236, 49, 248, + 94, 1, 240, 231, 248, 94, 1, 203, 216, 248, 94, 1, 218, 55, 248, 94, 1, + 159, 248, 94, 1, 234, 190, 248, 94, 1, 225, 80, 248, 94, 1, 233, 15, 248, + 94, 1, 225, 217, 248, 94, 1, 211, 167, 248, 94, 1, 196, 222, 248, 94, 1, + 195, 75, 248, 94, 1, 247, 18, 248, 94, 1, 207, 52, 248, 94, 1, 144, 248, + 94, 1, 195, 158, 248, 94, 1, 247, 207, 248, 94, 1, 209, 80, 248, 94, 1, + 63, 248, 94, 1, 72, 248, 94, 1, 69, 248, 94, 1, 237, 40, 248, 94, 1, 251, + 200, 248, 94, 1, 237, 33, 248, 94, 1, 250, 150, 248, 94, 1, 214, 39, 248, + 94, 1, 251, 106, 248, 94, 1, 236, 230, 248, 94, 1, 251, 97, 248, 94, 1, + 236, 215, 248, 94, 1, 236, 163, 248, 94, 1, 68, 248, 94, 1, 66, 248, 94, + 1, 225, 230, 248, 94, 1, 199, 230, 248, 94, 1, 217, 73, 248, 94, 1, 233, + 148, 248, 94, 1, 226, 121, 248, 94, 1, 177, 3, 76, 57, 248, 94, 1, 216, + 87, 29, 1, 224, 48, 29, 1, 205, 72, 29, 1, 224, 41, 29, 1, 216, 208, 29, + 1, 216, 206, 29, 1, 216, 205, 29, 1, 202, 97, 29, 1, 205, 61, 29, 1, 210, + 54, 29, 1, 210, 49, 29, 1, 210, 46, 29, 1, 210, 39, 29, 1, 210, 34, 29, + 1, 210, 29, 29, 1, 210, 40, 29, 1, 210, 52, 29, 1, 219, 56, 29, 1, 212, + 206, 29, 1, 205, 69, 29, 1, 212, 195, 29, 1, 206, 52, 29, 1, 205, 66, 29, + 1, 226, 143, 29, 1, 245, 6, 29, 1, 205, 76, 29, 1, 245, 71, 29, 1, 224, + 122, 29, 1, 202, 191, 29, 1, 212, 244, 29, 1, 232, 55, 29, 1, 63, 29, 1, + 251, 245, 29, 1, 164, 29, 1, 196, 118, 29, 1, 236, 192, 29, 1, 69, 29, 1, + 196, 56, 29, 1, 196, 69, 29, 1, 72, 29, 1, 197, 166, 29, 1, 197, 157, 29, + 1, 214, 164, 29, 1, 196, 3, 29, 1, 66, 29, 1, 197, 91, 29, 1, 197, 109, + 29, 1, 197, 70, 29, 1, 195, 217, 29, 1, 236, 116, 29, 1, 196, 24, 29, 1, + 68, 29, 235, 134, 29, 1, 205, 70, 29, 1, 216, 198, 29, 1, 216, 200, 29, + 1, 216, 203, 29, 1, 210, 47, 29, 1, 210, 28, 29, 1, 210, 36, 29, 1, 210, + 41, 29, 1, 210, 26, 29, 1, 219, 49, 29, 1, 219, 46, 29, 1, 219, 50, 29, + 1, 225, 1, 29, 1, 212, 201, 29, 1, 212, 187, 29, 1, 212, 193, 29, 1, 212, + 190, 29, 1, 212, 204, 29, 1, 212, 188, 29, 1, 224, 255, 29, 1, 224, 253, + 29, 1, 206, 45, 29, 1, 206, 43, 29, 1, 206, 35, 29, 1, 206, 40, 29, 1, + 206, 50, 29, 1, 213, 174, 29, 1, 205, 73, 29, 1, 196, 46, 29, 1, 196, 40, + 29, 1, 196, 41, 29, 1, 225, 0, 29, 1, 205, 74, 29, 1, 196, 52, 29, 1, + 195, 247, 29, 1, 195, 246, 29, 1, 195, 249, 29, 1, 195, 204, 29, 1, 195, + 205, 29, 1, 195, 208, 29, 1, 251, 6, 29, 1, 251, 0, 143, 251, 76, 222, + 64, 78, 143, 251, 76, 210, 90, 78, 143, 251, 76, 97, 78, 143, 251, 76, + 99, 78, 143, 251, 76, 115, 78, 143, 251, 76, 235, 7, 78, 143, 251, 76, + 201, 243, 78, 143, 251, 76, 112, 78, 143, 251, 76, 248, 85, 78, 143, 251, + 76, 235, 113, 78, 143, 251, 76, 208, 136, 78, 143, 251, 76, 202, 185, 78, + 143, 251, 76, 235, 0, 78, 143, 251, 76, 232, 123, 78, 143, 251, 76, 237, + 73, 78, 143, 251, 76, 220, 63, 78, 248, 94, 1, 248, 21, 248, 94, 1, 195, + 33, 248, 94, 1, 225, 172, 248, 94, 1, 233, 76, 248, 94, 1, 237, 54, 248, + 94, 1, 236, 212, 248, 94, 1, 214, 102, 248, 94, 1, 214, 106, 248, 94, 1, + 226, 1, 248, 94, 1, 251, 78, 248, 94, 1, 226, 52, 248, 94, 1, 200, 42, + 248, 94, 1, 226, 103, 248, 94, 1, 217, 51, 248, 94, 1, 251, 193, 248, 94, + 1, 250, 145, 248, 94, 1, 251, 123, 248, 94, 1, 214, 127, 248, 94, 1, 214, + 109, 248, 94, 1, 226, 49, 248, 94, 48, 1, 214, 3, 248, 94, 48, 1, 203, + 216, 248, 94, 48, 1, 225, 80, 248, 94, 48, 1, 233, 15, 248, 94, 1, 233, + 231, 248, 94, 1, 222, 123, 248, 94, 1, 194, 235, 12, 204, 196, 203, 216, + 12, 204, 196, 197, 82, 12, 204, 196, 196, 197, 12, 204, 196, 247, 220, + 12, 204, 196, 204, 68, 12, 204, 196, 230, 253, 12, 204, 196, 231, 1, 12, + 204, 196, 231, 84, 12, 204, 196, 230, 254, 12, 204, 196, 203, 219, 12, + 204, 196, 231, 0, 12, 204, 196, 230, 252, 12, 204, 196, 231, 82, 12, 204, + 196, 230, 255, 12, 204, 196, 230, 251, 12, 204, 196, 218, 55, 12, 204, + 196, 233, 15, 12, 204, 196, 209, 80, 12, 204, 196, 214, 3, 12, 204, 196, + 205, 151, 12, 204, 196, 240, 231, 12, 204, 196, 231, 2, 12, 204, 196, + 232, 81, 12, 204, 196, 203, 228, 12, 204, 196, 204, 45, 12, 204, 196, + 205, 23, 12, 204, 196, 207, 58, 12, 204, 196, 213, 96, 12, 204, 196, 211, + 169, 12, 204, 196, 202, 31, 12, 204, 196, 203, 218, 12, 204, 196, 204, + 57, 12, 204, 196, 231, 12, 12, 204, 196, 230, 250, 12, 204, 196, 213, 8, + 12, 204, 196, 211, 167, 71, 1, 4, 223, 187, 71, 1, 4, 206, 112, 71, 1, 4, + 204, 172, 71, 1, 4, 149, 71, 1, 4, 215, 186, 71, 1, 4, 142, 71, 1, 4, + 232, 71, 71, 1, 4, 231, 75, 71, 1, 4, 232, 147, 71, 1, 4, 231, 193, 71, + 1, 4, 218, 145, 71, 1, 4, 169, 71, 1, 4, 210, 72, 71, 1, 4, 209, 140, 71, + 1, 4, 210, 183, 71, 1, 4, 209, 232, 119, 29, 224, 48, 119, 29, 216, 208, + 119, 29, 202, 97, 119, 29, 210, 54, 119, 29, 219, 56, 119, 29, 212, 206, + 119, 29, 206, 52, 119, 29, 226, 143, 119, 29, 245, 6, 119, 29, 245, 71, + 119, 29, 224, 122, 119, 29, 202, 191, 119, 29, 212, 244, 119, 29, 232, + 55, 119, 29, 224, 49, 63, 119, 29, 216, 209, 63, 119, 29, 202, 98, 63, + 119, 29, 210, 55, 63, 119, 29, 219, 57, 63, 119, 29, 212, 207, 63, 119, + 29, 206, 53, 63, 119, 29, 226, 144, 63, 119, 29, 245, 7, 63, 119, 29, + 245, 72, 63, 119, 29, 224, 123, 63, 119, 29, 202, 192, 63, 119, 29, 212, + 245, 63, 119, 29, 232, 56, 63, 119, 29, 245, 7, 66, 119, 223, 233, 190, + 214, 142, 119, 223, 233, 190, 177, 231, 75, 119, 230, 191, 100, 119, 230, + 191, 102, 119, 230, 191, 134, 119, 230, 191, 136, 119, 230, 191, 146, + 119, 230, 191, 167, 119, 230, 191, 178, 119, 230, 191, 171, 119, 230, + 191, 182, 119, 230, 191, 203, 23, 119, 230, 191, 218, 189, 119, 230, 191, + 235, 118, 119, 230, 191, 197, 127, 119, 230, 191, 197, 14, 119, 230, 191, + 219, 143, 119, 230, 191, 237, 72, 119, 230, 191, 204, 111, 119, 230, 191, + 204, 229, 119, 230, 191, 232, 156, 119, 230, 191, 205, 189, 119, 230, + 191, 217, 222, 119, 230, 191, 205, 133, 119, 230, 191, 235, 129, 119, + 230, 191, 241, 148, 119, 230, 191, 223, 71, 119, 230, 191, 210, 113, 119, + 230, 191, 247, 152, 119, 230, 191, 204, 178, 119, 230, 191, 204, 91, 119, + 230, 191, 236, 202, 119, 230, 191, 210, 103, 119, 230, 191, 251, 142, + 119, 230, 191, 235, 161, 119, 230, 191, 210, 101, 119, 230, 191, 207, + 112, 119, 230, 191, 210, 178, 46, 230, 191, 211, 78, 46, 230, 191, 224, + 75, 46, 230, 191, 208, 166, 46, 230, 191, 223, 229, 46, 31, 203, 24, 214, + 120, 58, 205, 94, 46, 31, 200, 235, 214, 120, 58, 205, 94, 46, 31, 202, + 178, 214, 120, 58, 205, 94, 46, 31, 235, 15, 214, 120, 58, 205, 94, 46, + 31, 235, 146, 214, 120, 58, 205, 94, 46, 31, 206, 14, 214, 120, 58, 205, + 94, 46, 31, 207, 66, 214, 120, 58, 205, 94, 46, 31, 237, 21, 214, 120, + 58, 205, 94, 213, 130, 55, 46, 31, 200, 235, 100, 46, 31, 200, 235, 102, + 46, 31, 200, 235, 134, 46, 31, 200, 235, 136, 46, 31, 200, 235, 146, 46, + 31, 200, 235, 167, 46, 31, 200, 235, 178, 46, 31, 200, 235, 171, 46, 31, + 200, 235, 182, 46, 31, 202, 177, 46, 31, 202, 178, 100, 46, 31, 202, 178, + 102, 46, 31, 202, 178, 134, 46, 31, 202, 178, 136, 46, 31, 202, 178, 146, + 46, 29, 224, 48, 46, 29, 216, 208, 46, 29, 202, 97, 46, 29, 210, 54, 46, + 29, 219, 56, 46, 29, 212, 206, 46, 29, 206, 52, 46, 29, 226, 143, 46, 29, + 245, 6, 46, 29, 245, 71, 46, 29, 224, 122, 46, 29, 202, 191, 46, 29, 212, + 244, 46, 29, 232, 55, 46, 29, 224, 49, 63, 46, 29, 216, 209, 63, 46, 29, + 202, 98, 63, 46, 29, 210, 55, 63, 46, 29, 219, 57, 63, 46, 29, 212, 207, + 63, 46, 29, 206, 53, 63, 46, 29, 226, 144, 63, 46, 29, 245, 7, 63, 46, + 29, 245, 72, 63, 46, 29, 224, 123, 63, 46, 29, 202, 192, 63, 46, 29, 212, + 245, 63, 46, 29, 232, 56, 63, 46, 223, 233, 190, 247, 6, 46, 223, 233, + 190, 225, 106, 46, 29, 226, 144, 66, 223, 233, 205, 11, 105, 46, 230, + 191, 100, 46, 230, 191, 102, 46, 230, 191, 134, 46, 230, 191, 136, 46, + 230, 191, 146, 46, 230, 191, 167, 46, 230, 191, 178, 46, 230, 191, 171, + 46, 230, 191, 182, 46, 230, 191, 203, 23, 46, 230, 191, 218, 189, 46, + 230, 191, 235, 118, 46, 230, 191, 197, 127, 46, 230, 191, 197, 14, 46, + 230, 191, 219, 143, 46, 230, 191, 237, 72, 46, 230, 191, 204, 111, 46, + 230, 191, 204, 229, 46, 230, 191, 232, 156, 46, 230, 191, 205, 189, 46, + 230, 191, 217, 222, 46, 230, 191, 205, 133, 46, 230, 191, 235, 129, 46, + 230, 191, 241, 148, 46, 230, 191, 223, 71, 46, 230, 191, 208, 134, 46, + 230, 191, 220, 66, 46, 230, 191, 235, 171, 46, 230, 191, 204, 123, 46, + 230, 191, 236, 94, 46, 230, 191, 212, 15, 46, 230, 191, 250, 154, 46, + 230, 191, 225, 233, 46, 230, 191, 210, 101, 46, 230, 191, 241, 107, 46, + 230, 191, 241, 95, 46, 230, 191, 232, 48, 46, 230, 191, 247, 36, 46, 230, + 191, 221, 208, 46, 230, 191, 222, 184, 46, 230, 191, 210, 22, 46, 230, + 191, 219, 192, 46, 230, 191, 210, 131, 46, 230, 191, 204, 178, 46, 230, + 191, 204, 91, 46, 230, 191, 236, 202, 46, 230, 191, 210, 103, 46, 230, + 191, 251, 142, 46, 230, 191, 216, 194, 46, 31, 202, 178, 167, 46, 31, + 202, 178, 178, 46, 31, 202, 178, 171, 46, 31, 202, 178, 182, 46, 31, 235, + 14, 46, 31, 235, 15, 100, 46, 31, 235, 15, 102, 46, 31, 235, 15, 134, 46, + 31, 235, 15, 136, 46, 31, 235, 15, 146, 46, 31, 235, 15, 167, 46, 31, + 235, 15, 178, 46, 31, 235, 15, 171, 46, 31, 235, 15, 182, 46, 31, 235, + 145, 143, 203, 36, 16, 36, 225, 204, 143, 203, 36, 16, 36, 235, 183, 143, + 203, 36, 16, 36, 220, 31, 143, 203, 36, 16, 36, 251, 20, 143, 203, 36, + 16, 36, 219, 251, 143, 203, 36, 16, 36, 225, 103, 143, 203, 36, 16, 36, + 225, 104, 143, 203, 36, 16, 36, 250, 146, 143, 203, 36, 16, 36, 207, 89, + 143, 203, 36, 16, 36, 214, 170, 143, 203, 36, 16, 36, 216, 6, 143, 203, + 36, 16, 36, 239, 246, 47, 232, 81, 47, 236, 159, 47, 236, 104, 222, 81, + 222, 108, 55, 46, 71, 63, 46, 71, 68, 46, 71, 66, 46, 71, 69, 46, 71, 72, + 46, 71, 155, 46, 71, 224, 101, 46, 71, 223, 187, 46, 71, 224, 209, 46, + 71, 224, 11, 46, 71, 183, 46, 71, 206, 112, 46, 71, 204, 172, 46, 71, + 208, 147, 46, 71, 205, 200, 46, 71, 189, 46, 71, 202, 122, 46, 71, 201, + 40, 46, 71, 203, 68, 46, 71, 149, 46, 71, 176, 46, 71, 216, 223, 46, 71, + 215, 186, 46, 71, 217, 118, 46, 71, 216, 50, 46, 71, 142, 46, 71, 232, + 71, 46, 71, 231, 75, 46, 71, 232, 147, 46, 71, 231, 193, 46, 71, 166, 46, + 71, 219, 78, 46, 71, 218, 145, 46, 71, 219, 207, 46, 71, 218, 251, 46, + 71, 164, 46, 71, 195, 217, 46, 71, 196, 3, 46, 71, 169, 46, 71, 210, 72, + 46, 71, 209, 140, 46, 71, 210, 183, 46, 71, 209, 232, 46, 71, 197, 166, + 46, 71, 197, 70, 46, 71, 197, 109, 46, 71, 197, 34, 47, 236, 162, 217, + 223, 210, 139, 47, 251, 45, 47, 250, 204, 47, 251, 72, 47, 252, 125, 47, + 226, 54, 47, 226, 21, 47, 200, 39, 47, 236, 131, 47, 237, 51, 47, 214, + 105, 47, 214, 98, 47, 225, 29, 47, 224, 249, 47, 224, 244, 47, 234, 78, + 47, 234, 88, 47, 233, 180, 47, 233, 176, 47, 223, 101, 47, 233, 167, 47, + 224, 66, 47, 224, 65, 47, 224, 64, 47, 224, 63, 47, 233, 44, 47, 233, 43, + 47, 223, 150, 47, 223, 153, 47, 224, 196, 47, 223, 231, 47, 223, 239, 47, + 208, 252, 47, 208, 210, 47, 206, 33, 47, 207, 95, 47, 207, 94, 47, 240, + 132, 47, 239, 189, 47, 238, 254, 47, 202, 13, 47, 217, 216, 47, 216, 7, + 47, 232, 230, 47, 213, 237, 47, 213, 236, 47, 249, 142, 47, 212, 217, 47, + 212, 180, 47, 212, 181, 47, 248, 152, 47, 231, 70, 47, 231, 65, 47, 247, + 235, 47, 231, 49, 47, 232, 109, 47, 213, 19, 47, 213, 60, 47, 232, 90, + 47, 213, 56, 47, 213, 74, 47, 248, 246, 47, 212, 106, 47, 248, 90, 47, + 231, 169, 47, 212, 92, 47, 231, 160, 47, 231, 162, 47, 220, 79, 47, 220, + 75, 47, 220, 84, 47, 220, 17, 47, 220, 48, 47, 219, 35, 47, 219, 10, 47, + 219, 9, 47, 219, 180, 47, 219, 177, 47, 219, 181, 47, 196, 128, 47, 196, + 126, 47, 195, 202, 47, 209, 248, 47, 209, 252, 47, 209, 107, 47, 209, + 100, 47, 210, 128, 47, 210, 125, 47, 197, 125, 143, 203, 36, 16, 36, 231, + 92, 195, 79, 143, 203, 36, 16, 36, 231, 92, 100, 143, 203, 36, 16, 36, + 231, 92, 102, 143, 203, 36, 16, 36, 231, 92, 134, 143, 203, 36, 16, 36, + 231, 92, 136, 143, 203, 36, 16, 36, 231, 92, 146, 143, 203, 36, 16, 36, + 231, 92, 167, 143, 203, 36, 16, 36, 231, 92, 178, 143, 203, 36, 16, 36, + 231, 92, 171, 143, 203, 36, 16, 36, 231, 92, 182, 143, 203, 36, 16, 36, + 231, 92, 203, 23, 143, 203, 36, 16, 36, 231, 92, 236, 252, 143, 203, 36, + 16, 36, 231, 92, 200, 239, 143, 203, 36, 16, 36, 231, 92, 202, 179, 143, + 203, 36, 16, 36, 231, 92, 235, 1, 143, 203, 36, 16, 36, 231, 92, 235, + 149, 143, 203, 36, 16, 36, 231, 92, 206, 23, 143, 203, 36, 16, 36, 231, + 92, 207, 68, 143, 203, 36, 16, 36, 231, 92, 237, 28, 143, 203, 36, 16, + 36, 231, 92, 216, 176, 143, 203, 36, 16, 36, 231, 92, 200, 234, 143, 203, + 36, 16, 36, 231, 92, 200, 227, 143, 203, 36, 16, 36, 231, 92, 200, 222, + 143, 203, 36, 16, 36, 231, 92, 200, 224, 143, 203, 36, 16, 36, 231, 92, + 200, 229, 47, 231, 83, 47, 240, 136, 47, 250, 150, 47, 154, 47, 214, 29, + 47, 213, 97, 47, 239, 31, 47, 239, 32, 205, 93, 47, 239, 32, 241, 35, 47, + 225, 230, 47, 236, 162, 217, 223, 232, 110, 47, 236, 162, 217, 223, 203, + 239, 47, 236, 162, 217, 223, 203, 132, 47, 236, 162, 217, 223, 219, 176, + 47, 241, 97, 47, 213, 244, 251, 109, 47, 176, 47, 218, 146, 63, 47, 166, + 47, 155, 47, 224, 212, 47, 219, 246, 47, 234, 66, 47, 247, 158, 47, 224, + 211, 47, 213, 9, 47, 217, 75, 47, 218, 146, 236, 49, 47, 218, 146, 234, + 190, 47, 219, 119, 47, 224, 148, 47, 231, 2, 47, 224, 103, 47, 219, 80, + 47, 233, 194, 47, 202, 124, 47, 218, 146, 159, 47, 219, 3, 47, 239, 41, + 47, 224, 30, 47, 235, 53, 47, 216, 88, 47, 218, 146, 221, 136, 47, 219, + 0, 47, 244, 183, 47, 224, 24, 47, 219, 1, 205, 93, 47, 244, 184, 205, 93, + 47, 221, 137, 205, 93, 47, 224, 25, 205, 93, 47, 219, 1, 241, 35, 47, + 244, 184, 241, 35, 47, 221, 137, 241, 35, 47, 224, 25, 241, 35, 47, 221, + 137, 127, 209, 80, 47, 221, 137, 127, 209, 81, 205, 93, 47, 161, 47, 223, + 223, 47, 218, 151, 47, 233, 118, 47, 210, 234, 47, 210, 235, 127, 209, + 80, 47, 210, 235, 127, 209, 81, 205, 93, 47, 211, 240, 47, 215, 227, 47, + 218, 146, 209, 80, 47, 218, 148, 47, 211, 187, 47, 215, 120, 47, 218, + 146, 199, 230, 47, 218, 79, 47, 223, 139, 47, 218, 80, 219, 180, 47, 211, + 186, 47, 215, 119, 47, 218, 146, 197, 199, 47, 218, 73, 47, 223, 137, 47, + 218, 74, 219, 180, 47, 225, 81, 214, 147, 47, 221, 137, 214, 147, 47, + 251, 123, 47, 248, 65, 47, 247, 81, 47, 247, 58, 47, 247, 208, 127, 224, + 148, 47, 244, 182, 47, 240, 50, 47, 233, 28, 47, 142, 47, 231, 84, 47, + 226, 86, 47, 224, 37, 47, 224, 25, 247, 124, 47, 223, 189, 47, 222, 10, + 47, 222, 9, 47, 221, 250, 47, 221, 152, 47, 219, 247, 205, 224, 47, 219, + 34, 47, 218, 217, 47, 213, 7, 47, 212, 120, 47, 212, 53, 47, 212, 51, 47, + 205, 84, 47, 204, 72, 47, 197, 111, 47, 199, 231, 127, 221, 136, 47, 39, + 127, 221, 136, 143, 203, 36, 16, 36, 240, 54, 100, 143, 203, 36, 16, 36, + 240, 54, 102, 143, 203, 36, 16, 36, 240, 54, 134, 143, 203, 36, 16, 36, + 240, 54, 136, 143, 203, 36, 16, 36, 240, 54, 146, 143, 203, 36, 16, 36, + 240, 54, 167, 143, 203, 36, 16, 36, 240, 54, 178, 143, 203, 36, 16, 36, + 240, 54, 171, 143, 203, 36, 16, 36, 240, 54, 182, 143, 203, 36, 16, 36, + 240, 54, 203, 23, 143, 203, 36, 16, 36, 240, 54, 236, 252, 143, 203, 36, + 16, 36, 240, 54, 200, 239, 143, 203, 36, 16, 36, 240, 54, 202, 179, 143, + 203, 36, 16, 36, 240, 54, 235, 1, 143, 203, 36, 16, 36, 240, 54, 235, + 149, 143, 203, 36, 16, 36, 240, 54, 206, 23, 143, 203, 36, 16, 36, 240, + 54, 207, 68, 143, 203, 36, 16, 36, 240, 54, 237, 28, 143, 203, 36, 16, + 36, 240, 54, 216, 176, 143, 203, 36, 16, 36, 240, 54, 200, 234, 143, 203, + 36, 16, 36, 240, 54, 200, 227, 143, 203, 36, 16, 36, 240, 54, 200, 222, + 143, 203, 36, 16, 36, 240, 54, 200, 224, 143, 203, 36, 16, 36, 240, 54, + 200, 229, 143, 203, 36, 16, 36, 240, 54, 200, 230, 143, 203, 36, 16, 36, + 240, 54, 200, 225, 143, 203, 36, 16, 36, 240, 54, 200, 226, 143, 203, 36, + 16, 36, 240, 54, 200, 233, 143, 203, 36, 16, 36, 240, 54, 200, 228, 143, + 203, 36, 16, 36, 240, 54, 202, 177, 143, 203, 36, 16, 36, 240, 54, 202, + 175, 47, 234, 105, 232, 84, 36, 202, 218, 241, 75, 232, 122, 232, 84, 36, + 202, 218, 210, 171, 237, 72, 232, 84, 36, 239, 122, 250, 169, 202, 218, + 248, 241, 232, 84, 36, 195, 230, 235, 45, 232, 84, 36, 197, 152, 232, 84, + 36, 241, 151, 232, 84, 36, 202, 218, 250, 228, 232, 84, 36, 231, 176, + 202, 19, 232, 84, 36, 4, 203, 115, 232, 84, 36, 201, 193, 232, 84, 36, + 213, 90, 232, 84, 36, 205, 9, 232, 84, 36, 235, 173, 232, 84, 36, 233, + 96, 212, 75, 232, 84, 36, 218, 237, 232, 84, 36, 236, 201, 232, 84, 36, + 235, 46, 232, 84, 36, 197, 7, 214, 120, 202, 218, 239, 247, 232, 84, 36, + 251, 24, 232, 84, 36, 241, 130, 232, 84, 36, 248, 142, 202, 144, 232, 84, + 36, 233, 116, 232, 84, 36, 205, 111, 251, 44, 232, 84, 36, 210, 93, 232, + 84, 36, 226, 48, 232, 84, 36, 233, 96, 203, 115, 232, 84, 36, 218, 165, + 241, 100, 232, 84, 36, 233, 96, 212, 28, 232, 84, 36, 202, 218, 252, 27, + 197, 127, 232, 84, 36, 202, 218, 244, 211, 235, 118, 232, 84, 36, 226, + 62, 232, 84, 36, 237, 177, 232, 84, 36, 210, 96, 232, 84, 36, 233, 96, + 212, 58, 232, 84, 36, 212, 2, 232, 84, 36, 240, 70, 77, 202, 218, 222, + 95, 232, 84, 36, 202, 218, 235, 211, 232, 84, 36, 214, 78, 232, 84, 36, + 214, 177, 232, 84, 36, 239, 217, 232, 84, 36, 239, 239, 232, 84, 36, 226, + 77, 232, 84, 36, 248, 51, 232, 84, 36, 244, 161, 202, 30, 219, 183, 232, + 84, 36, 234, 73, 202, 19, 232, 84, 36, 211, 197, 200, 25, 232, 84, 36, + 214, 77, 232, 84, 36, 202, 218, 197, 93, 232, 84, 36, 210, 84, 232, 84, + 36, 202, 218, 247, 87, 232, 84, 36, 202, 218, 250, 224, 202, 138, 232, + 84, 36, 202, 218, 224, 197, 204, 233, 218, 169, 232, 84, 36, 239, 184, + 232, 84, 36, 202, 218, 220, 20, 220, 80, 232, 84, 36, 252, 28, 232, 84, + 36, 202, 218, 197, 144, 232, 84, 36, 202, 218, 234, 28, 197, 50, 232, 84, + 36, 202, 218, 225, 112, 223, 1, 232, 84, 36, 239, 72, 232, 84, 36, 222, + 82, 232, 84, 36, 226, 51, 201, 117, 232, 84, 36, 4, 212, 28, 232, 84, 36, + 251, 218, 244, 151, 232, 84, 36, 248, 244, 244, 151, 11, 5, 225, 234, 11, + 5, 225, 226, 11, 5, 68, 11, 5, 226, 4, 11, 5, 226, 145, 11, 5, 226, 128, + 11, 5, 226, 147, 11, 5, 226, 146, 11, 5, 250, 168, 11, 5, 250, 124, 11, + 5, 63, 11, 5, 251, 46, 11, 5, 200, 37, 11, 5, 200, 41, 11, 5, 200, 38, + 11, 5, 214, 49, 11, 5, 214, 13, 11, 5, 72, 11, 5, 214, 93, 11, 5, 236, + 95, 11, 5, 69, 11, 5, 196, 243, 11, 5, 248, 145, 11, 5, 248, 140, 11, 5, + 248, 184, 11, 5, 248, 157, 11, 5, 248, 173, 11, 5, 248, 172, 11, 5, 248, + 175, 11, 5, 248, 174, 11, 5, 249, 56, 11, 5, 249, 48, 11, 5, 249, 145, + 11, 5, 249, 81, 11, 5, 247, 247, 11, 5, 247, 251, 11, 5, 247, 248, 11, 5, + 248, 89, 11, 5, 248, 70, 11, 5, 248, 116, 11, 5, 248, 95, 11, 5, 248, + 200, 11, 5, 249, 9, 11, 5, 248, 213, 11, 5, 247, 231, 11, 5, 247, 225, + 11, 5, 248, 21, 11, 5, 247, 246, 11, 5, 247, 239, 11, 5, 247, 244, 11, 5, + 247, 213, 11, 5, 247, 211, 11, 5, 247, 218, 11, 5, 247, 216, 11, 5, 247, + 214, 11, 5, 247, 215, 11, 5, 212, 157, 11, 5, 212, 153, 11, 5, 212, 220, + 11, 5, 212, 169, 11, 5, 212, 186, 11, 5, 212, 213, 11, 5, 212, 209, 11, + 5, 213, 116, 11, 5, 213, 102, 11, 5, 161, 11, 5, 213, 163, 11, 5, 211, + 207, 11, 5, 211, 209, 11, 5, 211, 208, 11, 5, 212, 68, 11, 5, 212, 56, + 11, 5, 212, 117, 11, 5, 212, 87, 11, 5, 211, 193, 11, 5, 211, 189, 11, 5, + 211, 227, 11, 5, 211, 206, 11, 5, 211, 198, 11, 5, 211, 204, 11, 5, 211, + 171, 11, 5, 211, 170, 11, 5, 211, 175, 11, 5, 211, 174, 11, 5, 211, 172, + 11, 5, 211, 173, 11, 5, 249, 30, 11, 5, 249, 29, 11, 5, 249, 36, 11, 5, + 249, 31, 11, 5, 249, 33, 11, 5, 249, 32, 11, 5, 249, 35, 11, 5, 249, 34, + 11, 5, 249, 42, 11, 5, 249, 41, 11, 5, 249, 45, 11, 5, 249, 43, 11, 5, + 249, 21, 11, 5, 249, 23, 11, 5, 249, 22, 11, 5, 249, 26, 11, 5, 249, 25, + 11, 5, 249, 28, 11, 5, 249, 27, 11, 5, 249, 37, 11, 5, 249, 40, 11, 5, + 249, 38, 11, 5, 249, 17, 11, 5, 249, 16, 11, 5, 249, 24, 11, 5, 249, 20, + 11, 5, 249, 18, 11, 5, 249, 19, 11, 5, 249, 13, 11, 5, 249, 12, 11, 5, + 249, 15, 11, 5, 249, 14, 11, 5, 217, 182, 11, 5, 217, 181, 11, 5, 217, + 187, 11, 5, 217, 183, 11, 5, 217, 184, 11, 5, 217, 186, 11, 5, 217, 185, + 11, 5, 217, 190, 11, 5, 217, 189, 11, 5, 217, 192, 11, 5, 217, 191, 11, + 5, 217, 178, 11, 5, 217, 177, 11, 5, 217, 180, 11, 5, 217, 179, 11, 5, + 217, 171, 11, 5, 217, 170, 11, 5, 217, 175, 11, 5, 217, 174, 11, 5, 217, + 172, 11, 5, 217, 173, 11, 5, 217, 165, 11, 5, 217, 164, 11, 5, 217, 169, + 11, 5, 217, 168, 11, 5, 217, 166, 11, 5, 217, 167, 11, 5, 231, 237, 11, + 5, 231, 236, 11, 5, 231, 242, 11, 5, 231, 238, 11, 5, 231, 239, 11, 5, + 231, 241, 11, 5, 231, 240, 11, 5, 231, 245, 11, 5, 231, 244, 11, 5, 231, + 247, 11, 5, 231, 246, 11, 5, 231, 228, 11, 5, 231, 230, 11, 5, 231, 229, + 11, 5, 231, 233, 11, 5, 231, 232, 11, 5, 231, 235, 11, 5, 231, 234, 11, + 5, 231, 224, 11, 5, 231, 223, 11, 5, 231, 231, 11, 5, 231, 227, 11, 5, + 231, 225, 11, 5, 231, 226, 11, 5, 231, 218, 11, 5, 231, 222, 11, 5, 231, + 221, 11, 5, 231, 219, 11, 5, 231, 220, 11, 5, 219, 6, 11, 5, 219, 5, 11, + 5, 219, 78, 11, 5, 219, 12, 11, 5, 219, 42, 11, 5, 219, 60, 11, 5, 219, + 58, 11, 5, 220, 4, 11, 5, 219, 254, 11, 5, 166, 11, 5, 220, 43, 11, 5, + 218, 107, 11, 5, 218, 106, 11, 5, 218, 110, 11, 5, 218, 108, 11, 5, 218, + 180, 11, 5, 218, 153, 11, 5, 218, 251, 11, 5, 218, 187, 11, 5, 219, 130, + 11, 5, 219, 207, 11, 5, 218, 87, 11, 5, 218, 81, 11, 5, 218, 145, 11, 5, + 218, 103, 11, 5, 218, 96, 11, 5, 218, 101, 11, 5, 218, 58, 11, 5, 218, + 57, 11, 5, 218, 63, 11, 5, 218, 60, 11, 5, 235, 104, 11, 5, 235, 98, 11, + 5, 235, 153, 11, 5, 235, 120, 11, 5, 235, 202, 11, 5, 235, 193, 11, 5, + 235, 239, 11, 5, 235, 207, 11, 5, 234, 254, 11, 5, 235, 51, 11, 5, 235, + 32, 11, 5, 234, 206, 11, 5, 234, 205, 11, 5, 234, 223, 11, 5, 234, 211, + 11, 5, 234, 209, 11, 5, 234, 210, 11, 5, 234, 193, 11, 5, 234, 192, 11, + 5, 234, 196, 11, 5, 234, 194, 11, 5, 198, 255, 11, 5, 198, 250, 11, 5, + 199, 34, 11, 5, 199, 8, 11, 5, 199, 23, 11, 5, 199, 20, 11, 5, 199, 26, + 11, 5, 199, 25, 11, 5, 199, 126, 11, 5, 199, 121, 11, 5, 199, 152, 11, 5, + 199, 139, 11, 5, 198, 229, 11, 5, 198, 225, 11, 5, 198, 248, 11, 5, 198, + 231, 11, 5, 199, 38, 11, 5, 199, 106, 11, 5, 197, 213, 11, 5, 197, 211, + 11, 5, 197, 220, 11, 5, 197, 216, 11, 5, 197, 214, 11, 5, 197, 215, 11, + 5, 197, 203, 11, 5, 197, 202, 11, 5, 197, 207, 11, 5, 197, 206, 11, 5, + 197, 204, 11, 5, 197, 205, 11, 5, 239, 65, 11, 5, 239, 51, 11, 5, 239, + 152, 11, 5, 239, 92, 11, 5, 239, 127, 11, 5, 239, 132, 11, 5, 239, 131, + 11, 5, 240, 61, 11, 5, 240, 55, 11, 5, 240, 136, 11, 5, 240, 81, 11, 5, + 237, 182, 11, 5, 237, 183, 11, 5, 238, 253, 11, 5, 237, 229, 11, 5, 239, + 28, 11, 5, 239, 0, 11, 5, 239, 182, 11, 5, 239, 252, 11, 5, 239, 203, 11, + 5, 237, 173, 11, 5, 237, 171, 11, 5, 237, 201, 11, 5, 237, 181, 11, 5, + 237, 176, 11, 5, 237, 179, 11, 5, 202, 57, 11, 5, 202, 49, 11, 5, 202, + 122, 11, 5, 202, 67, 11, 5, 202, 105, 11, 5, 202, 107, 11, 5, 202, 106, + 11, 5, 203, 94, 11, 5, 203, 79, 11, 5, 189, 11, 5, 203, 105, 11, 5, 201, + 15, 11, 5, 201, 14, 11, 5, 201, 17, 11, 5, 201, 16, 11, 5, 201, 229, 11, + 5, 201, 219, 11, 5, 149, 11, 5, 201, 242, 11, 5, 202, 239, 11, 5, 203, + 68, 11, 5, 203, 10, 11, 5, 200, 254, 11, 5, 200, 249, 11, 5, 201, 40, 11, + 5, 201, 13, 11, 5, 200, 255, 11, 5, 201, 10, 11, 5, 240, 13, 11, 5, 240, + 12, 11, 5, 240, 18, 11, 5, 240, 14, 11, 5, 240, 15, 11, 5, 240, 17, 11, + 5, 240, 16, 11, 5, 240, 34, 11, 5, 240, 33, 11, 5, 240, 41, 11, 5, 240, + 35, 11, 5, 240, 3, 11, 5, 240, 5, 11, 5, 240, 4, 11, 5, 240, 8, 11, 5, + 240, 7, 11, 5, 240, 11, 11, 5, 240, 9, 11, 5, 240, 26, 11, 5, 240, 29, + 11, 5, 240, 27, 11, 5, 239, 255, 11, 5, 239, 254, 11, 5, 240, 6, 11, 5, + 240, 2, 11, 5, 240, 0, 11, 5, 240, 1, 11, 5, 217, 137, 11, 5, 217, 136, + 11, 5, 217, 144, 11, 5, 217, 139, 11, 5, 217, 140, 11, 5, 217, 141, 11, + 5, 217, 153, 11, 5, 217, 152, 11, 5, 217, 159, 11, 5, 217, 154, 11, 5, + 217, 129, 11, 5, 217, 128, 11, 5, 217, 135, 11, 5, 217, 130, 11, 5, 217, + 145, 11, 5, 217, 151, 11, 5, 217, 149, 11, 5, 217, 121, 11, 5, 217, 120, + 11, 5, 217, 126, 11, 5, 217, 124, 11, 5, 217, 122, 11, 5, 217, 123, 11, + 5, 231, 203, 11, 5, 231, 202, 11, 5, 231, 209, 11, 5, 231, 204, 11, 5, + 231, 206, 11, 5, 231, 205, 11, 5, 231, 208, 11, 5, 231, 207, 11, 5, 231, + 215, 11, 5, 231, 213, 11, 5, 231, 217, 11, 5, 231, 216, 11, 5, 231, 196, + 11, 5, 231, 197, 11, 5, 231, 200, 11, 5, 231, 199, 11, 5, 231, 201, 11, + 5, 231, 210, 11, 5, 231, 212, 11, 5, 231, 211, 11, 5, 231, 195, 11, 5, + 216, 168, 11, 5, 216, 166, 11, 5, 216, 223, 11, 5, 216, 171, 11, 5, 216, + 197, 11, 5, 216, 211, 11, 5, 216, 210, 11, 5, 217, 197, 11, 5, 176, 11, + 5, 217, 213, 11, 5, 215, 130, 11, 5, 215, 132, 11, 5, 215, 131, 11, 5, + 216, 18, 11, 5, 216, 2, 11, 5, 216, 50, 11, 5, 216, 29, 11, 5, 217, 77, + 11, 5, 217, 118, 11, 5, 217, 96, 11, 5, 215, 125, 11, 5, 215, 121, 11, 5, + 215, 186, 11, 5, 215, 129, 11, 5, 215, 127, 11, 5, 215, 128, 11, 5, 232, + 12, 11, 5, 232, 11, 11, 5, 232, 17, 11, 5, 232, 13, 11, 5, 232, 14, 11, + 5, 232, 16, 11, 5, 232, 15, 11, 5, 232, 23, 11, 5, 232, 21, 11, 5, 232, + 25, 11, 5, 232, 24, 11, 5, 232, 4, 11, 5, 232, 6, 11, 5, 232, 5, 11, 5, + 232, 8, 11, 5, 232, 10, 11, 5, 232, 9, 11, 5, 232, 18, 11, 5, 232, 20, + 11, 5, 232, 19, 11, 5, 232, 0, 11, 5, 231, 255, 11, 5, 232, 7, 11, 5, + 232, 3, 11, 5, 232, 1, 11, 5, 232, 2, 11, 5, 231, 250, 11, 5, 231, 249, + 11, 5, 231, 254, 11, 5, 231, 253, 11, 5, 231, 251, 11, 5, 231, 252, 11, + 5, 222, 51, 11, 5, 222, 43, 11, 5, 222, 109, 11, 5, 222, 61, 11, 5, 222, + 100, 11, 5, 222, 99, 11, 5, 222, 103, 11, 5, 222, 101, 11, 5, 222, 220, + 11, 5, 222, 208, 11, 5, 172, 11, 5, 222, 231, 11, 5, 221, 169, 11, 5, + 221, 168, 11, 5, 221, 171, 11, 5, 221, 170, 11, 5, 221, 216, 11, 5, 221, + 200, 11, 5, 222, 7, 11, 5, 221, 222, 11, 5, 222, 126, 11, 5, 222, 197, + 11, 5, 222, 144, 11, 5, 221, 163, 11, 5, 221, 161, 11, 5, 221, 191, 11, + 5, 221, 167, 11, 5, 221, 165, 11, 5, 221, 166, 11, 5, 221, 141, 11, 5, + 221, 140, 11, 5, 221, 151, 11, 5, 221, 144, 11, 5, 221, 142, 11, 5, 221, + 143, 11, 5, 233, 163, 11, 5, 233, 162, 11, 5, 233, 192, 11, 5, 233, 175, + 11, 5, 233, 184, 11, 5, 233, 183, 11, 5, 233, 186, 11, 5, 233, 185, 11, + 5, 234, 75, 11, 5, 234, 70, 11, 5, 234, 123, 11, 5, 234, 86, 11, 5, 233, + 49, 11, 5, 233, 48, 11, 5, 233, 51, 11, 5, 233, 50, 11, 5, 233, 121, 11, + 5, 233, 119, 11, 5, 233, 144, 11, 5, 233, 130, 11, 5, 234, 14, 11, 5, + 234, 12, 11, 5, 234, 48, 11, 5, 234, 25, 11, 5, 233, 38, 11, 5, 233, 37, + 11, 5, 233, 76, 11, 5, 233, 47, 11, 5, 233, 39, 11, 5, 233, 46, 11, 5, + 224, 55, 11, 5, 224, 50, 11, 5, 224, 101, 11, 5, 224, 69, 11, 5, 224, 82, + 11, 5, 224, 86, 11, 5, 224, 84, 11, 5, 224, 235, 11, 5, 224, 217, 11, 5, + 155, 11, 5, 225, 8, 11, 5, 223, 158, 11, 5, 223, 163, 11, 5, 223, 160, + 11, 5, 223, 230, 11, 5, 223, 225, 11, 5, 224, 11, 11, 5, 223, 237, 11, 5, + 224, 172, 11, 5, 224, 155, 11, 5, 224, 209, 11, 5, 224, 176, 11, 5, 223, + 145, 11, 5, 223, 141, 11, 5, 223, 187, 11, 5, 223, 157, 11, 5, 223, 149, + 11, 5, 223, 154, 11, 5, 233, 252, 11, 5, 233, 251, 11, 5, 234, 0, 11, 5, + 233, 253, 11, 5, 233, 255, 11, 5, 233, 254, 11, 5, 234, 7, 11, 5, 234, 6, + 11, 5, 234, 10, 11, 5, 234, 8, 11, 5, 233, 243, 11, 5, 233, 242, 11, 5, + 233, 245, 11, 5, 233, 244, 11, 5, 233, 248, 11, 5, 233, 247, 11, 5, 233, + 250, 11, 5, 233, 249, 11, 5, 234, 2, 11, 5, 234, 1, 11, 5, 234, 5, 11, 5, + 234, 3, 11, 5, 233, 238, 11, 5, 233, 237, 11, 5, 233, 246, 11, 5, 233, + 241, 11, 5, 233, 239, 11, 5, 233, 240, 11, 5, 219, 97, 11, 5, 219, 98, + 11, 5, 219, 116, 11, 5, 219, 115, 11, 5, 219, 118, 11, 5, 219, 117, 11, + 5, 219, 88, 11, 5, 219, 90, 11, 5, 219, 89, 11, 5, 219, 93, 11, 5, 219, + 92, 11, 5, 219, 95, 11, 5, 219, 94, 11, 5, 219, 99, 11, 5, 219, 101, 11, + 5, 219, 100, 11, 5, 219, 84, 11, 5, 219, 83, 11, 5, 219, 91, 11, 5, 219, + 87, 11, 5, 219, 85, 11, 5, 219, 86, 11, 5, 231, 22, 11, 5, 231, 21, 11, + 5, 231, 28, 11, 5, 231, 23, 11, 5, 231, 25, 11, 5, 231, 24, 11, 5, 231, + 27, 11, 5, 231, 26, 11, 5, 231, 33, 11, 5, 231, 32, 11, 5, 231, 35, 11, + 5, 231, 34, 11, 5, 231, 14, 11, 5, 231, 13, 11, 5, 231, 16, 11, 5, 231, + 15, 11, 5, 231, 18, 11, 5, 231, 17, 11, 5, 231, 20, 11, 5, 231, 19, 11, + 5, 231, 29, 11, 5, 231, 31, 11, 5, 231, 30, 11, 5, 217, 16, 11, 5, 217, + 18, 11, 5, 217, 17, 11, 5, 217, 61, 11, 5, 217, 59, 11, 5, 217, 71, 11, + 5, 217, 64, 11, 5, 216, 233, 11, 5, 216, 232, 11, 5, 216, 234, 11, 5, + 216, 244, 11, 5, 216, 241, 11, 5, 216, 252, 11, 5, 216, 246, 11, 5, 217, + 52, 11, 5, 217, 58, 11, 5, 217, 54, 11, 5, 232, 31, 11, 5, 232, 49, 11, + 5, 232, 58, 11, 5, 232, 165, 11, 5, 232, 154, 11, 5, 142, 11, 5, 232, + 177, 11, 5, 231, 51, 11, 5, 231, 50, 11, 5, 231, 53, 11, 5, 231, 52, 11, + 5, 231, 95, 11, 5, 231, 86, 11, 5, 231, 193, 11, 5, 231, 158, 11, 5, 232, + 86, 11, 5, 232, 147, 11, 5, 232, 98, 11, 5, 197, 130, 11, 5, 197, 115, + 11, 5, 197, 166, 11, 5, 197, 141, 11, 5, 196, 232, 11, 5, 196, 234, 11, + 5, 196, 233, 11, 5, 197, 0, 11, 5, 197, 34, 11, 5, 197, 10, 11, 5, 197, + 83, 11, 5, 197, 109, 11, 5, 197, 90, 11, 5, 195, 18, 11, 5, 195, 17, 11, + 5, 195, 33, 11, 5, 195, 21, 11, 5, 195, 26, 11, 5, 195, 28, 11, 5, 195, + 27, 11, 5, 195, 97, 11, 5, 195, 94, 11, 5, 195, 115, 11, 5, 195, 101, 11, + 5, 194, 248, 11, 5, 194, 250, 11, 5, 194, 249, 11, 5, 195, 6, 11, 5, 195, + 5, 11, 5, 195, 11, 11, 5, 195, 7, 11, 5, 195, 76, 11, 5, 195, 88, 11, 5, + 195, 81, 11, 5, 194, 244, 11, 5, 194, 243, 11, 5, 194, 255, 11, 5, 194, + 247, 11, 5, 194, 245, 11, 5, 194, 246, 11, 5, 194, 230, 11, 5, 194, 229, + 11, 5, 194, 235, 11, 5, 194, 233, 11, 5, 194, 231, 11, 5, 194, 232, 11, + 5, 244, 238, 11, 5, 244, 231, 11, 5, 245, 11, 11, 5, 244, 251, 11, 5, + 245, 8, 11, 5, 245, 2, 11, 5, 245, 10, 11, 5, 245, 9, 11, 5, 247, 92, 11, + 5, 247, 84, 11, 5, 247, 174, 11, 5, 247, 125, 11, 5, 241, 29, 11, 5, 241, + 31, 11, 5, 241, 30, 11, 5, 241, 93, 11, 5, 241, 81, 11, 5, 244, 182, 11, + 5, 241, 112, 11, 5, 247, 20, 11, 5, 247, 57, 11, 5, 247, 26, 11, 5, 241, + 1, 11, 5, 240, 255, 11, 5, 241, 41, 11, 5, 241, 27, 11, 5, 241, 7, 11, 5, + 241, 22, 11, 5, 240, 234, 11, 5, 240, 233, 11, 5, 240, 246, 11, 5, 240, + 240, 11, 5, 240, 235, 11, 5, 240, 237, 11, 5, 194, 213, 11, 5, 194, 212, + 11, 5, 194, 219, 11, 5, 194, 214, 11, 5, 194, 216, 11, 5, 194, 215, 11, + 5, 194, 218, 11, 5, 194, 217, 11, 5, 194, 225, 11, 5, 194, 224, 11, 5, + 194, 228, 11, 5, 194, 226, 11, 5, 194, 209, 11, 5, 194, 211, 11, 5, 194, + 210, 11, 5, 194, 220, 11, 5, 194, 223, 11, 5, 194, 221, 11, 5, 194, 202, + 11, 5, 194, 206, 11, 5, 194, 205, 11, 5, 194, 203, 11, 5, 194, 204, 11, + 5, 194, 196, 11, 5, 194, 195, 11, 5, 194, 201, 11, 5, 194, 199, 11, 5, + 194, 197, 11, 5, 194, 198, 11, 5, 215, 41, 11, 5, 215, 40, 11, 5, 215, + 46, 11, 5, 215, 42, 11, 5, 215, 43, 11, 5, 215, 45, 11, 5, 215, 44, 11, + 5, 215, 51, 11, 5, 215, 50, 11, 5, 215, 54, 11, 5, 215, 53, 11, 5, 215, + 34, 11, 5, 215, 35, 11, 5, 215, 38, 11, 5, 215, 39, 11, 5, 215, 47, 11, + 5, 215, 49, 11, 5, 215, 29, 11, 5, 215, 37, 11, 5, 215, 33, 11, 5, 215, + 30, 11, 5, 215, 31, 11, 5, 215, 24, 11, 5, 215, 23, 11, 5, 215, 28, 11, + 5, 215, 27, 11, 5, 215, 25, 11, 5, 215, 26, 11, 5, 206, 31, 11, 5, 167, + 11, 5, 206, 112, 11, 5, 206, 34, 11, 5, 206, 92, 11, 5, 206, 95, 11, 5, + 206, 93, 11, 5, 208, 199, 11, 5, 208, 183, 11, 5, 183, 11, 5, 208, 207, + 11, 5, 204, 101, 11, 5, 204, 103, 11, 5, 204, 102, 11, 5, 205, 165, 11, + 5, 205, 154, 11, 5, 205, 200, 11, 5, 205, 169, 11, 5, 207, 63, 11, 5, + 208, 147, 11, 5, 207, 93, 11, 5, 204, 76, 11, 5, 204, 73, 11, 5, 204, + 172, 11, 5, 204, 100, 11, 5, 204, 80, 11, 5, 204, 88, 11, 5, 203, 230, + 11, 5, 203, 229, 11, 5, 204, 44, 11, 5, 203, 238, 11, 5, 203, 232, 11, 5, + 203, 237, 11, 5, 205, 41, 11, 5, 205, 40, 11, 5, 205, 47, 11, 5, 205, 42, + 11, 5, 205, 44, 11, 5, 205, 46, 11, 5, 205, 45, 11, 5, 205, 56, 11, 5, + 205, 54, 11, 5, 205, 80, 11, 5, 205, 57, 11, 5, 205, 36, 11, 5, 205, 35, + 11, 5, 205, 39, 11, 5, 205, 37, 11, 5, 205, 50, 11, 5, 205, 53, 11, 5, + 205, 51, 11, 5, 205, 32, 11, 5, 205, 30, 11, 5, 205, 34, 11, 5, 205, 33, + 11, 5, 205, 25, 11, 5, 205, 24, 11, 5, 205, 29, 11, 5, 205, 28, 11, 5, + 205, 26, 11, 5, 205, 27, 11, 5, 195, 69, 11, 5, 195, 68, 11, 5, 195, 74, + 11, 5, 195, 71, 11, 5, 195, 48, 11, 5, 195, 50, 11, 5, 195, 49, 11, 5, + 195, 53, 11, 5, 195, 52, 11, 5, 195, 57, 11, 5, 195, 54, 11, 5, 195, 62, + 11, 5, 195, 61, 11, 5, 195, 65, 11, 5, 195, 63, 11, 5, 195, 44, 11, 5, + 195, 43, 11, 5, 195, 51, 11, 5, 195, 47, 11, 5, 195, 45, 11, 5, 195, 46, + 11, 5, 195, 36, 11, 5, 195, 35, 11, 5, 195, 40, 11, 5, 195, 39, 11, 5, + 195, 37, 11, 5, 195, 38, 11, 5, 245, 109, 11, 5, 245, 105, 11, 5, 247, + 16, 11, 5, 247, 2, 11, 5, 245, 26, 11, 5, 245, 25, 11, 5, 245, 28, 11, 5, + 245, 27, 11, 5, 245, 41, 11, 5, 245, 40, 11, 5, 245, 49, 11, 5, 245, 44, + 11, 5, 245, 80, 11, 5, 245, 78, 11, 5, 245, 103, 11, 5, 245, 88, 11, 5, + 245, 20, 11, 5, 245, 30, 11, 5, 245, 24, 11, 5, 245, 21, 11, 5, 245, 23, + 11, 5, 245, 13, 11, 5, 245, 12, 11, 5, 245, 17, 11, 5, 245, 16, 11, 5, + 245, 14, 11, 5, 245, 15, 11, 5, 209, 177, 11, 5, 209, 181, 11, 5, 209, + 159, 11, 5, 209, 160, 11, 5, 209, 164, 11, 5, 209, 163, 11, 5, 209, 167, + 11, 5, 209, 165, 11, 5, 209, 171, 11, 5, 209, 170, 11, 5, 209, 176, 11, + 5, 209, 172, 11, 5, 209, 155, 11, 5, 209, 153, 11, 5, 209, 161, 11, 5, + 209, 158, 11, 5, 209, 156, 11, 5, 209, 157, 11, 5, 209, 148, 11, 5, 209, + 147, 11, 5, 209, 152, 11, 5, 209, 151, 11, 5, 209, 149, 11, 5, 209, 150, + 11, 5, 215, 250, 11, 5, 215, 249, 11, 5, 215, 252, 11, 5, 215, 251, 11, + 5, 215, 241, 11, 5, 215, 243, 11, 5, 215, 242, 11, 5, 215, 245, 11, 5, + 215, 244, 11, 5, 215, 248, 11, 5, 215, 247, 11, 5, 215, 235, 11, 5, 215, + 234, 11, 5, 215, 240, 11, 5, 215, 238, 11, 5, 215, 236, 11, 5, 215, 237, + 11, 5, 215, 229, 11, 5, 215, 228, 11, 5, 215, 233, 11, 5, 215, 232, 11, + 5, 215, 230, 11, 5, 215, 231, 11, 5, 207, 9, 11, 5, 207, 4, 11, 5, 207, + 50, 11, 5, 207, 22, 11, 5, 206, 139, 11, 5, 206, 141, 11, 5, 206, 140, + 11, 5, 206, 166, 11, 5, 206, 161, 11, 5, 206, 198, 11, 5, 206, 186, 11, + 5, 206, 233, 11, 5, 206, 226, 11, 5, 206, 255, 11, 5, 206, 242, 11, 5, + 206, 135, 11, 5, 206, 132, 11, 5, 206, 151, 11, 5, 206, 138, 11, 5, 206, + 136, 11, 5, 206, 137, 11, 5, 206, 115, 11, 5, 206, 114, 11, 5, 206, 121, + 11, 5, 206, 118, 11, 5, 206, 116, 11, 5, 206, 117, 11, 5, 210, 198, 11, + 5, 210, 192, 11, 5, 169, 11, 5, 210, 204, 11, 5, 209, 110, 11, 5, 209, + 112, 11, 5, 209, 111, 11, 5, 209, 195, 11, 5, 209, 183, 11, 5, 209, 232, + 11, 5, 209, 199, 11, 5, 210, 82, 11, 5, 210, 183, 11, 5, 210, 124, 11, 5, + 209, 102, 11, 5, 209, 99, 11, 5, 209, 140, 11, 5, 209, 109, 11, 5, 209, + 105, 11, 5, 209, 106, 11, 5, 209, 84, 11, 5, 209, 83, 11, 5, 209, 89, 11, + 5, 209, 87, 11, 5, 209, 85, 11, 5, 209, 86, 11, 5, 225, 160, 11, 5, 225, + 159, 11, 5, 225, 172, 11, 5, 225, 161, 11, 5, 225, 168, 11, 5, 225, 167, + 11, 5, 225, 170, 11, 5, 225, 169, 11, 5, 225, 98, 11, 5, 225, 97, 11, 5, + 225, 100, 11, 5, 225, 99, 11, 5, 225, 116, 11, 5, 225, 114, 11, 5, 225, + 129, 11, 5, 225, 118, 11, 5, 225, 91, 11, 5, 225, 89, 11, 5, 225, 110, + 11, 5, 225, 96, 11, 5, 225, 93, 11, 5, 225, 94, 11, 5, 225, 83, 11, 5, + 225, 82, 11, 5, 225, 87, 11, 5, 225, 86, 11, 5, 225, 84, 11, 5, 225, 85, + 11, 5, 211, 113, 11, 5, 211, 111, 11, 5, 211, 121, 11, 5, 211, 114, 11, + 5, 211, 118, 11, 5, 211, 117, 11, 5, 211, 120, 11, 5, 211, 119, 11, 5, + 211, 63, 11, 5, 211, 60, 11, 5, 211, 65, 11, 5, 211, 64, 11, 5, 211, 100, + 11, 5, 211, 99, 11, 5, 211, 109, 11, 5, 211, 103, 11, 5, 211, 55, 11, 5, + 211, 51, 11, 5, 211, 97, 11, 5, 211, 59, 11, 5, 211, 57, 11, 5, 211, 58, + 11, 5, 211, 35, 11, 5, 211, 33, 11, 5, 211, 45, 11, 5, 211, 38, 11, 5, + 211, 36, 11, 5, 211, 37, 11, 5, 225, 149, 11, 5, 225, 148, 11, 5, 225, + 155, 11, 5, 225, 150, 11, 5, 225, 152, 11, 5, 225, 151, 11, 5, 225, 154, + 11, 5, 225, 153, 11, 5, 225, 140, 11, 5, 225, 142, 11, 5, 225, 141, 11, + 5, 225, 145, 11, 5, 225, 144, 11, 5, 225, 147, 11, 5, 225, 146, 11, 5, + 225, 136, 11, 5, 225, 135, 11, 5, 225, 143, 11, 5, 225, 139, 11, 5, 225, + 137, 11, 5, 225, 138, 11, 5, 225, 132, 11, 5, 225, 131, 11, 5, 225, 134, + 11, 5, 225, 133, 11, 5, 216, 141, 11, 5, 216, 140, 11, 5, 216, 148, 11, + 5, 216, 142, 11, 5, 216, 144, 11, 5, 216, 143, 11, 5, 216, 147, 11, 5, + 216, 145, 11, 5, 216, 130, 11, 5, 216, 131, 11, 5, 216, 136, 11, 5, 216, + 135, 11, 5, 216, 139, 11, 5, 216, 137, 11, 5, 216, 125, 11, 5, 216, 134, + 11, 5, 216, 129, 11, 5, 216, 126, 11, 5, 216, 127, 11, 5, 216, 120, 11, + 5, 216, 119, 11, 5, 216, 124, 11, 5, 216, 123, 11, 5, 216, 121, 11, 5, + 216, 122, 11, 5, 215, 76, 11, 5, 215, 75, 11, 5, 215, 89, 11, 5, 215, 80, + 11, 5, 215, 85, 11, 5, 215, 84, 11, 5, 215, 87, 11, 5, 215, 86, 11, 5, + 215, 61, 11, 5, 215, 63, 11, 5, 215, 62, 11, 5, 215, 68, 11, 5, 215, 67, + 11, 5, 215, 73, 11, 5, 215, 69, 11, 5, 215, 59, 11, 5, 215, 57, 11, 5, + 215, 66, 11, 5, 215, 60, 11, 5, 196, 187, 11, 5, 196, 186, 11, 5, 196, + 196, 11, 5, 196, 189, 11, 5, 196, 191, 11, 5, 196, 190, 11, 5, 196, 193, + 11, 5, 196, 192, 11, 5, 196, 175, 11, 5, 196, 176, 11, 5, 196, 180, 11, + 5, 196, 179, 11, 5, 196, 185, 11, 5, 196, 183, 11, 5, 196, 152, 11, 5, + 196, 150, 11, 5, 196, 165, 11, 5, 196, 155, 11, 5, 196, 153, 11, 5, 196, + 154, 11, 5, 196, 9, 11, 5, 196, 7, 11, 5, 196, 24, 11, 5, 196, 10, 11, 5, + 196, 18, 11, 5, 196, 17, 11, 5, 196, 21, 11, 5, 196, 19, 11, 5, 195, 190, + 11, 5, 195, 189, 11, 5, 195, 193, 11, 5, 195, 191, 11, 5, 195, 232, 11, + 5, 195, 227, 11, 5, 196, 3, 11, 5, 195, 236, 11, 5, 195, 181, 11, 5, 195, + 177, 11, 5, 195, 217, 11, 5, 195, 188, 11, 5, 195, 184, 11, 5, 195, 185, + 11, 5, 195, 161, 11, 5, 195, 160, 11, 5, 195, 168, 11, 5, 195, 164, 11, + 5, 195, 162, 11, 5, 195, 163, 11, 44, 211, 100, 11, 44, 222, 109, 11, 44, + 224, 55, 11, 44, 215, 80, 11, 44, 240, 240, 11, 44, 205, 47, 11, 44, 233, + 249, 11, 44, 234, 25, 11, 44, 219, 78, 11, 44, 231, 22, 11, 44, 221, 143, + 11, 44, 249, 17, 11, 44, 218, 187, 11, 44, 196, 3, 11, 44, 211, 193, 11, + 44, 231, 16, 11, 44, 203, 94, 11, 44, 234, 123, 11, 44, 194, 247, 11, 44, + 240, 234, 11, 44, 240, 1, 11, 44, 247, 244, 11, 44, 233, 245, 11, 44, + 215, 69, 11, 44, 201, 40, 11, 44, 214, 93, 11, 44, 225, 136, 11, 44, 195, + 6, 11, 44, 211, 171, 11, 44, 231, 235, 11, 44, 196, 9, 11, 44, 197, 215, + 11, 44, 206, 121, 11, 44, 199, 106, 11, 44, 195, 115, 11, 44, 225, 129, + 11, 44, 215, 33, 11, 44, 225, 134, 11, 44, 233, 121, 11, 44, 225, 154, + 11, 44, 197, 34, 11, 44, 237, 201, 11, 44, 206, 137, 11, 44, 222, 103, + 11, 44, 240, 246, 11, 44, 241, 30, 11, 44, 244, 251, 11, 44, 231, 19, 11, + 44, 207, 9, 11, 44, 194, 246, 11, 44, 206, 186, 11, 44, 245, 103, 11, 44, + 194, 216, 11, 44, 217, 186, 11, 44, 224, 209, 222, 52, 1, 249, 145, 222, + 52, 1, 161, 222, 52, 1, 213, 6, 222, 52, 1, 240, 136, 222, 52, 1, 189, + 222, 52, 1, 202, 233, 222, 52, 1, 234, 123, 222, 52, 1, 155, 222, 52, 1, + 224, 146, 222, 52, 1, 225, 214, 222, 52, 1, 247, 174, 222, 52, 1, 247, + 16, 222, 52, 1, 237, 156, 222, 52, 1, 201, 113, 222, 52, 1, 201, 103, + 222, 52, 1, 166, 222, 52, 1, 176, 222, 52, 1, 172, 222, 52, 1, 183, 222, + 52, 1, 195, 74, 222, 52, 1, 195, 115, 222, 52, 1, 217, 71, 222, 52, 1, + 142, 222, 52, 1, 196, 208, 222, 52, 1, 232, 80, 222, 52, 1, 235, 239, + 222, 52, 1, 197, 166, 222, 52, 1, 207, 50, 222, 52, 1, 164, 222, 52, 1, + 233, 230, 222, 52, 1, 63, 222, 52, 1, 251, 245, 222, 52, 1, 69, 222, 52, + 1, 236, 116, 222, 52, 1, 68, 222, 52, 1, 72, 222, 52, 1, 66, 222, 52, 1, + 200, 99, 222, 52, 1, 200, 92, 222, 52, 1, 214, 164, 222, 52, 1, 152, 218, + 62, 202, 122, 222, 52, 1, 152, 218, 1, 212, 117, 222, 52, 1, 152, 218, + 62, 240, 245, 222, 52, 1, 152, 218, 62, 248, 116, 222, 52, 1, 152, 218, + 62, 176, 222, 52, 1, 152, 218, 62, 225, 181, 222, 52, 211, 214, 244, 159, + 222, 52, 211, 214, 234, 217, 204, 226, 54, 5, 237, 54, 54, 5, 237, 50, + 54, 5, 232, 118, 54, 5, 197, 98, 54, 5, 197, 97, 54, 5, 213, 79, 54, 5, + 248, 191, 54, 5, 248, 251, 54, 5, 219, 233, 54, 5, 223, 218, 54, 5, 219, + 110, 54, 5, 234, 61, 54, 5, 235, 182, 54, 5, 199, 113, 54, 5, 203, 48, + 54, 5, 202, 215, 54, 5, 239, 166, 54, 5, 239, 163, 54, 5, 222, 188, 54, + 5, 210, 155, 54, 5, 239, 237, 54, 5, 217, 150, 54, 5, 208, 129, 54, 5, + 206, 253, 54, 5, 195, 85, 54, 5, 195, 64, 54, 5, 247, 49, 54, 5, 225, + 191, 54, 5, 216, 155, 54, 5, 196, 66, 54, 5, 224, 200, 54, 5, 217, 44, + 54, 5, 234, 40, 54, 5, 219, 188, 54, 5, 217, 107, 54, 5, 215, 97, 54, 5, + 68, 54, 5, 226, 86, 54, 5, 232, 71, 54, 5, 232, 41, 54, 5, 197, 70, 54, + 5, 197, 52, 54, 5, 212, 220, 54, 5, 248, 189, 54, 5, 248, 184, 54, 5, + 219, 226, 54, 5, 223, 215, 54, 5, 219, 107, 54, 5, 234, 57, 54, 5, 235, + 153, 54, 5, 199, 34, 54, 5, 202, 122, 54, 5, 202, 195, 54, 5, 239, 158, + 54, 5, 239, 162, 54, 5, 222, 109, 54, 5, 210, 72, 54, 5, 239, 152, 54, 5, + 217, 144, 54, 5, 206, 112, 54, 5, 206, 223, 54, 5, 195, 33, 54, 5, 195, + 60, 54, 5, 245, 11, 54, 5, 225, 172, 54, 5, 216, 148, 54, 5, 196, 24, 54, + 5, 224, 101, 54, 5, 217, 36, 54, 5, 233, 192, 54, 5, 219, 78, 54, 5, 216, + 223, 54, 5, 215, 89, 54, 5, 63, 54, 5, 251, 106, 54, 5, 217, 66, 54, 5, + 142, 54, 5, 232, 212, 54, 5, 197, 166, 54, 5, 197, 146, 54, 5, 161, 54, + 5, 248, 197, 54, 5, 249, 145, 54, 5, 219, 241, 54, 5, 223, 223, 54, 5, + 223, 221, 54, 5, 219, 114, 54, 5, 234, 65, 54, 5, 235, 239, 54, 5, 199, + 152, 54, 5, 189, 54, 5, 202, 233, 54, 5, 239, 176, 54, 5, 239, 165, 54, + 5, 172, 54, 5, 169, 54, 5, 240, 136, 54, 5, 217, 159, 54, 5, 183, 54, 5, + 207, 50, 54, 5, 195, 115, 54, 5, 195, 74, 54, 5, 247, 174, 54, 5, 225, + 214, 54, 5, 216, 164, 54, 5, 164, 54, 5, 155, 54, 5, 225, 17, 54, 5, 217, + 50, 54, 5, 234, 123, 54, 5, 166, 54, 5, 176, 54, 5, 215, 109, 54, 5, 214, + 102, 54, 5, 214, 97, 54, 5, 231, 166, 54, 5, 197, 15, 54, 5, 197, 11, 54, + 5, 212, 91, 54, 5, 248, 187, 54, 5, 248, 103, 54, 5, 219, 221, 54, 5, + 223, 213, 54, 5, 219, 103, 54, 5, 234, 53, 54, 5, 235, 40, 54, 5, 198, + 233, 54, 5, 201, 247, 54, 5, 202, 164, 54, 5, 239, 155, 54, 5, 239, 160, + 54, 5, 221, 229, 54, 5, 209, 206, 54, 5, 239, 3, 54, 5, 217, 131, 54, 5, + 205, 171, 54, 5, 206, 190, 54, 5, 195, 8, 54, 5, 195, 55, 54, 5, 241, + 117, 54, 5, 225, 119, 54, 5, 216, 138, 54, 5, 195, 237, 54, 5, 223, 242, + 54, 5, 217, 34, 54, 5, 233, 132, 54, 5, 218, 195, 54, 5, 216, 33, 54, 5, + 215, 70, 54, 5, 66, 54, 5, 200, 72, 54, 5, 231, 75, 54, 5, 231, 59, 54, + 5, 196, 243, 54, 5, 196, 236, 54, 5, 211, 227, 54, 5, 248, 186, 54, 5, + 248, 21, 54, 5, 219, 220, 54, 5, 223, 211, 54, 5, 219, 102, 54, 5, 234, + 52, 54, 5, 234, 223, 54, 5, 197, 220, 54, 5, 201, 40, 54, 5, 202, 142, + 54, 5, 239, 153, 54, 5, 239, 159, 54, 5, 221, 191, 54, 5, 209, 140, 54, + 5, 237, 201, 54, 5, 217, 126, 54, 5, 204, 172, 54, 5, 206, 151, 54, 5, + 194, 255, 54, 5, 195, 51, 54, 5, 241, 41, 54, 5, 225, 110, 54, 5, 216, + 134, 54, 5, 195, 217, 54, 5, 223, 187, 54, 5, 217, 33, 54, 5, 233, 76, + 54, 5, 218, 145, 54, 5, 215, 186, 54, 5, 215, 66, 54, 5, 72, 54, 5, 214, + 119, 54, 5, 216, 248, 54, 5, 231, 193, 54, 5, 231, 169, 54, 5, 197, 34, + 54, 5, 197, 16, 54, 5, 212, 117, 54, 5, 248, 188, 54, 5, 248, 116, 54, 5, + 219, 222, 54, 5, 223, 214, 54, 5, 219, 105, 54, 5, 234, 55, 54, 5, 234, + 54, 54, 5, 235, 51, 54, 5, 198, 248, 54, 5, 149, 54, 5, 202, 169, 54, 5, + 239, 156, 54, 5, 239, 161, 54, 5, 222, 7, 54, 5, 209, 232, 54, 5, 239, + 28, 54, 5, 217, 135, 54, 5, 205, 200, 54, 5, 206, 198, 54, 5, 195, 11, + 54, 5, 195, 57, 54, 5, 244, 182, 54, 5, 225, 129, 54, 5, 216, 139, 54, 5, + 196, 3, 54, 5, 224, 11, 54, 5, 217, 35, 54, 5, 233, 144, 54, 5, 218, 251, + 54, 5, 216, 50, 54, 5, 215, 73, 54, 5, 69, 54, 5, 236, 230, 54, 5, 217, + 55, 54, 5, 232, 147, 54, 5, 232, 101, 54, 5, 197, 109, 54, 5, 197, 92, + 54, 5, 213, 92, 54, 5, 248, 192, 54, 5, 249, 9, 54, 5, 219, 234, 54, 5, + 223, 219, 54, 5, 223, 217, 54, 5, 219, 111, 54, 5, 234, 62, 54, 5, 234, + 60, 54, 5, 235, 189, 54, 5, 199, 118, 54, 5, 203, 68, 54, 5, 202, 217, + 54, 5, 239, 167, 54, 5, 239, 164, 54, 5, 222, 197, 54, 5, 210, 183, 54, + 5, 239, 252, 54, 5, 217, 151, 54, 5, 208, 147, 54, 5, 206, 255, 54, 5, + 195, 88, 54, 5, 195, 65, 54, 5, 247, 57, 54, 5, 225, 193, 54, 5, 216, + 157, 54, 5, 196, 69, 54, 5, 224, 209, 54, 5, 217, 45, 54, 5, 217, 41, 54, + 5, 234, 48, 54, 5, 234, 34, 54, 5, 219, 207, 54, 5, 217, 118, 54, 5, 215, + 98, 54, 5, 217, 73, 54, 5, 222, 150, 54, 244, 159, 54, 234, 217, 204, + 226, 54, 211, 79, 78, 54, 5, 217, 134, 235, 239, 54, 5, 217, 134, 155, + 54, 5, 217, 134, 205, 171, 54, 16, 235, 178, 54, 16, 224, 198, 54, 16, + 202, 72, 54, 16, 216, 190, 54, 16, 249, 87, 54, 16, 235, 238, 54, 16, + 203, 162, 54, 16, 240, 86, 54, 16, 239, 2, 54, 16, 223, 164, 54, 16, 201, + 251, 54, 16, 239, 27, 54, 16, 225, 120, 54, 17, 195, 79, 54, 17, 100, 54, + 17, 102, 54, 17, 134, 54, 17, 136, 54, 17, 146, 54, 17, 167, 54, 17, 178, + 54, 17, 171, 54, 17, 182, 54, 5, 217, 134, 166, 54, 5, 217, 134, 239, 28, + 40, 6, 1, 195, 83, 40, 4, 1, 195, 83, 40, 6, 1, 237, 151, 40, 4, 1, 237, + 151, 40, 6, 1, 210, 89, 237, 153, 40, 4, 1, 210, 89, 237, 153, 40, 6, 1, + 226, 7, 40, 4, 1, 226, 7, 40, 6, 1, 239, 45, 40, 4, 1, 239, 45, 40, 6, 1, + 218, 203, 200, 87, 40, 4, 1, 218, 203, 200, 87, 40, 6, 1, 248, 35, 214, + 124, 40, 4, 1, 248, 35, 214, 124, 40, 6, 1, 217, 85, 196, 51, 40, 4, 1, + 217, 85, 196, 51, 40, 6, 1, 196, 48, 3, 249, 139, 196, 51, 40, 4, 1, 196, + 48, 3, 249, 139, 196, 51, 40, 6, 1, 226, 5, 196, 84, 40, 4, 1, 226, 5, + 196, 84, 40, 6, 1, 210, 89, 195, 217, 40, 4, 1, 210, 89, 195, 217, 40, 6, + 1, 226, 5, 63, 40, 4, 1, 226, 5, 63, 40, 6, 1, 244, 203, 222, 47, 195, + 182, 40, 4, 1, 244, 203, 222, 47, 195, 182, 40, 6, 1, 248, 128, 195, 182, + 40, 4, 1, 248, 128, 195, 182, 40, 6, 1, 226, 5, 244, 203, 222, 47, 195, + 182, 40, 4, 1, 226, 5, 244, 203, 222, 47, 195, 182, 40, 6, 1, 196, 5, 40, + 4, 1, 196, 5, 40, 6, 1, 210, 89, 201, 107, 40, 4, 1, 210, 89, 201, 107, + 40, 6, 1, 205, 186, 239, 252, 40, 4, 1, 205, 186, 239, 252, 40, 6, 1, + 205, 186, 237, 7, 40, 4, 1, 205, 186, 237, 7, 40, 6, 1, 205, 186, 236, + 241, 40, 4, 1, 205, 186, 236, 241, 40, 6, 1, 218, 207, 72, 40, 4, 1, 218, + 207, 72, 40, 6, 1, 248, 160, 72, 40, 4, 1, 248, 160, 72, 40, 6, 1, 52, + 218, 207, 72, 40, 4, 1, 52, 218, 207, 72, 40, 1, 218, 121, 72, 38, 40, + 197, 201, 38, 40, 203, 24, 219, 27, 55, 38, 40, 231, 58, 219, 27, 55, 38, + 40, 202, 159, 219, 27, 55, 205, 246, 250, 179, 38, 40, 1, 200, 84, 226, + 147, 38, 40, 1, 68, 38, 40, 1, 196, 24, 38, 40, 1, 66, 38, 40, 1, 232, + 173, 55, 38, 40, 1, 196, 47, 38, 40, 1, 205, 186, 55, 38, 40, 1, 214, + 124, 38, 40, 224, 221, 38, 40, 213, 99, 40, 224, 221, 40, 213, 99, 40, 6, + 1, 237, 166, 40, 4, 1, 237, 166, 40, 6, 1, 237, 142, 40, 4, 1, 237, 142, + 40, 6, 1, 195, 41, 40, 4, 1, 195, 41, 40, 6, 1, 247, 73, 40, 4, 1, 247, + 73, 40, 6, 1, 237, 138, 40, 4, 1, 237, 138, 40, 6, 1, 203, 69, 3, 112, + 122, 40, 4, 1, 203, 69, 3, 112, 122, 40, 6, 1, 200, 243, 40, 4, 1, 200, + 243, 40, 6, 1, 201, 82, 40, 4, 1, 201, 82, 40, 6, 1, 201, 87, 40, 4, 1, + 201, 87, 40, 6, 1, 203, 74, 40, 4, 1, 203, 74, 40, 6, 1, 231, 40, 40, 4, + 1, 231, 40, 40, 6, 1, 206, 127, 40, 4, 1, 206, 127, 40, 6, 1, 52, 72, 40, + 4, 1, 52, 72, 40, 6, 1, 241, 59, 72, 40, 4, 1, 241, 59, 72, 73, 1, 40, + 232, 173, 55, 73, 1, 40, 205, 186, 55, 38, 40, 1, 237, 47, 38, 40, 1, + 226, 5, 69, 25, 1, 63, 25, 1, 155, 25, 1, 66, 25, 1, 223, 187, 25, 1, + 237, 54, 25, 1, 210, 155, 25, 1, 203, 145, 25, 1, 72, 25, 1, 215, 89, 25, + 1, 68, 25, 1, 172, 25, 1, 161, 25, 1, 210, 9, 25, 1, 210, 57, 25, 1, 222, + 187, 25, 1, 219, 187, 25, 1, 203, 162, 25, 1, 217, 157, 25, 1, 216, 162, + 25, 1, 221, 136, 25, 1, 204, 74, 25, 1, 218, 145, 25, 1, 206, 218, 25, 1, + 206, 112, 25, 1, 206, 228, 25, 1, 207, 72, 25, 1, 223, 106, 25, 1, 224, + 172, 25, 1, 215, 154, 25, 1, 215, 186, 25, 1, 216, 133, 25, 1, 195, 234, + 25, 1, 206, 151, 25, 1, 195, 186, 25, 1, 164, 25, 1, 215, 223, 25, 1, + 224, 158, 25, 1, 213, 10, 25, 1, 216, 155, 25, 1, 215, 203, 25, 1, 211, + 218, 25, 1, 196, 240, 25, 1, 213, 79, 25, 1, 235, 182, 25, 1, 209, 140, + 25, 1, 221, 191, 25, 1, 219, 78, 25, 1, 216, 223, 25, 1, 210, 91, 25, 1, + 210, 229, 25, 1, 224, 182, 25, 1, 216, 255, 25, 1, 217, 50, 25, 1, 217, + 71, 25, 1, 206, 198, 25, 1, 211, 223, 25, 1, 234, 223, 25, 1, 235, 44, + 25, 1, 197, 166, 25, 1, 176, 25, 1, 222, 109, 25, 1, 212, 220, 25, 1, + 221, 221, 25, 1, 224, 11, 25, 1, 219, 231, 25, 1, 210, 126, 25, 1, 219, + 164, 25, 1, 166, 25, 1, 202, 122, 25, 1, 224, 101, 25, 1, 218, 251, 25, + 1, 219, 239, 25, 1, 203, 1, 25, 1, 223, 223, 25, 1, 203, 23, 25, 1, 215, + 189, 25, 1, 208, 227, 25, 1, 235, 235, 25, 1, 223, 226, 25, 1, 224, 2, + 25, 38, 117, 223, 235, 25, 38, 117, 201, 25, 25, 216, 161, 25, 234, 217, + 204, 226, 25, 244, 168, 25, 244, 159, 25, 207, 105, 25, 211, 79, 78, 73, + 1, 245, 61, 152, 196, 13, 212, 171, 73, 1, 245, 61, 152, 196, 96, 212, + 171, 73, 1, 245, 61, 152, 196, 13, 207, 23, 73, 1, 245, 61, 152, 196, 96, + 207, 23, 73, 1, 245, 61, 152, 196, 13, 211, 97, 73, 1, 245, 61, 152, 196, + 96, 211, 97, 73, 1, 245, 61, 152, 196, 13, 209, 140, 73, 1, 245, 61, 152, + 196, 96, 209, 140, 73, 1, 236, 74, 237, 250, 152, 154, 73, 1, 130, 237, + 250, 152, 154, 73, 1, 219, 65, 237, 250, 152, 154, 73, 1, 126, 237, 250, + 152, 154, 73, 1, 236, 73, 237, 250, 152, 154, 73, 1, 236, 74, 237, 250, + 222, 176, 152, 154, 73, 1, 130, 237, 250, 222, 176, 152, 154, 73, 1, 219, + 65, 237, 250, 222, 176, 152, 154, 73, 1, 126, 237, 250, 222, 176, 152, + 154, 73, 1, 236, 73, 237, 250, 222, 176, 152, 154, 73, 1, 236, 74, 222, + 176, 152, 154, 73, 1, 130, 222, 176, 152, 154, 73, 1, 219, 65, 222, 176, + 152, 154, 73, 1, 126, 222, 176, 152, 154, 73, 1, 236, 73, 222, 176, 152, + 154, 73, 1, 76, 83, 154, 73, 1, 76, 205, 248, 73, 1, 76, 231, 155, 154, + 73, 1, 221, 203, 53, 241, 102, 251, 90, 73, 1, 210, 215, 124, 51, 73, 1, + 210, 215, 135, 51, 73, 1, 210, 215, 236, 90, 78, 73, 1, 210, 215, 226, + 17, 236, 90, 78, 73, 1, 126, 226, 17, 236, 90, 78, 73, 1, 204, 206, 26, + 130, 202, 11, 73, 1, 204, 206, 26, 126, 202, 11, 8, 6, 1, 237, 42, 251, + 164, 8, 4, 1, 237, 42, 251, 164, 8, 6, 1, 237, 42, 251, 194, 8, 4, 1, + 237, 42, 251, 194, 8, 6, 1, 232, 99, 8, 4, 1, 232, 99, 8, 6, 1, 200, 187, + 8, 4, 1, 200, 187, 8, 6, 1, 201, 184, 8, 4, 1, 201, 184, 8, 6, 1, 241, + 38, 8, 4, 1, 241, 38, 8, 6, 1, 241, 39, 3, 244, 159, 8, 4, 1, 241, 39, 3, + 244, 159, 8, 1, 4, 6, 236, 49, 8, 1, 4, 6, 209, 80, 8, 6, 1, 252, 168, 8, + 4, 1, 252, 168, 8, 6, 1, 251, 49, 8, 4, 1, 251, 49, 8, 6, 1, 250, 150, 8, + 4, 1, 250, 150, 8, 6, 1, 250, 133, 8, 4, 1, 250, 133, 8, 6, 1, 250, 134, + 3, 231, 155, 154, 8, 4, 1, 250, 134, 3, 231, 155, 154, 8, 6, 1, 250, 122, + 8, 4, 1, 250, 122, 8, 6, 1, 210, 89, 247, 208, 3, 238, 253, 8, 4, 1, 210, + 89, 247, 208, 3, 238, 253, 8, 6, 1, 225, 81, 3, 106, 8, 4, 1, 225, 81, 3, + 106, 8, 6, 1, 225, 81, 3, 239, 147, 106, 8, 4, 1, 225, 81, 3, 239, 147, + 106, 8, 6, 1, 225, 81, 3, 204, 196, 26, 239, 147, 106, 8, 4, 1, 225, 81, + 3, 204, 196, 26, 239, 147, 106, 8, 6, 1, 248, 33, 159, 8, 4, 1, 248, 33, + 159, 8, 6, 1, 223, 100, 3, 130, 106, 8, 4, 1, 223, 100, 3, 130, 106, 8, + 6, 1, 177, 3, 181, 204, 196, 214, 20, 8, 4, 1, 177, 3, 181, 204, 196, + 214, 20, 8, 6, 1, 177, 3, 221, 225, 8, 4, 1, 177, 3, 221, 225, 8, 6, 1, + 214, 102, 8, 4, 1, 214, 102, 8, 6, 1, 214, 4, 3, 204, 196, 202, 145, 239, + 195, 8, 4, 1, 214, 4, 3, 204, 196, 202, 145, 239, 195, 8, 6, 1, 214, 4, + 3, 235, 64, 8, 4, 1, 214, 4, 3, 235, 64, 8, 6, 1, 214, 4, 3, 205, 86, + 203, 135, 8, 4, 1, 214, 4, 3, 205, 86, 203, 135, 8, 6, 1, 211, 168, 3, + 204, 196, 202, 145, 239, 195, 8, 4, 1, 211, 168, 3, 204, 196, 202, 145, + 239, 195, 8, 6, 1, 211, 168, 3, 239, 147, 106, 8, 4, 1, 211, 168, 3, 239, + 147, 106, 8, 6, 1, 211, 32, 209, 188, 8, 4, 1, 211, 32, 209, 188, 8, 6, + 1, 209, 121, 209, 188, 8, 4, 1, 209, 121, 209, 188, 8, 6, 1, 199, 231, 3, + 239, 147, 106, 8, 4, 1, 199, 231, 3, 239, 147, 106, 8, 6, 1, 197, 207, 8, + 4, 1, 197, 207, 8, 6, 1, 199, 0, 195, 158, 8, 4, 1, 199, 0, 195, 158, 8, + 6, 1, 202, 163, 3, 106, 8, 4, 1, 202, 163, 3, 106, 8, 6, 1, 202, 163, 3, + 204, 196, 202, 145, 239, 195, 8, 4, 1, 202, 163, 3, 204, 196, 202, 145, + 239, 195, 8, 6, 1, 199, 107, 8, 4, 1, 199, 107, 8, 6, 1, 236, 128, 8, 4, + 1, 236, 128, 8, 6, 1, 225, 248, 8, 4, 1, 225, 248, 8, 6, 1, 241, 155, 8, + 4, 1, 241, 155, 73, 1, 200, 4, 8, 4, 1, 237, 190, 8, 4, 1, 221, 174, 8, + 4, 1, 218, 114, 8, 4, 1, 215, 145, 8, 4, 1, 209, 120, 8, 1, 4, 6, 209, + 120, 8, 4, 1, 201, 22, 8, 4, 1, 200, 79, 8, 6, 1, 226, 39, 240, 231, 8, + 4, 1, 226, 39, 240, 231, 8, 6, 1, 226, 39, 236, 49, 8, 4, 1, 226, 39, + 236, 49, 8, 6, 1, 226, 39, 234, 190, 8, 6, 1, 163, 226, 39, 234, 190, 8, + 4, 1, 163, 226, 39, 234, 190, 8, 6, 1, 163, 159, 8, 4, 1, 163, 159, 8, 6, + 1, 226, 39, 144, 8, 4, 1, 226, 39, 144, 8, 6, 1, 226, 39, 209, 80, 8, 4, + 1, 226, 39, 209, 80, 8, 6, 1, 226, 39, 203, 216, 8, 4, 1, 226, 39, 203, + 216, 73, 1, 126, 244, 241, 252, 22, 73, 1, 244, 168, 73, 1, 206, 182, + 236, 172, 55, 8, 6, 1, 208, 231, 8, 4, 1, 208, 231, 8, 6, 1, 163, 233, + 15, 8, 4, 1, 223, 100, 3, 210, 95, 231, 165, 26, 248, 225, 8, 1, 206, 55, + 238, 253, 8, 6, 1, 218, 56, 3, 239, 195, 8, 4, 1, 218, 56, 3, 239, 195, + 8, 6, 1, 247, 208, 3, 154, 8, 4, 1, 247, 208, 3, 154, 8, 4, 1, 247, 208, + 3, 213, 215, 122, 8, 4, 1, 233, 16, 3, 213, 215, 122, 8, 6, 1, 74, 3, + 235, 64, 8, 4, 1, 74, 3, 235, 64, 8, 6, 1, 236, 50, 3, 106, 8, 4, 1, 236, + 50, 3, 106, 8, 6, 1, 198, 240, 251, 245, 8, 4, 1, 198, 240, 251, 245, 8, + 6, 1, 198, 240, 214, 164, 8, 4, 1, 198, 240, 214, 164, 8, 6, 1, 198, 240, + 200, 99, 8, 4, 1, 198, 240, 200, 99, 8, 6, 1, 234, 191, 3, 214, 182, 106, + 8, 4, 1, 234, 191, 3, 214, 182, 106, 8, 6, 1, 225, 81, 3, 214, 182, 106, + 8, 4, 1, 225, 81, 3, 214, 182, 106, 8, 6, 1, 218, 56, 3, 214, 182, 106, + 8, 4, 1, 218, 56, 3, 214, 182, 106, 8, 6, 1, 211, 32, 3, 214, 182, 106, + 8, 4, 1, 211, 32, 3, 214, 182, 106, 8, 6, 1, 209, 81, 3, 214, 182, 106, + 8, 4, 1, 209, 81, 3, 214, 182, 106, 8, 6, 1, 233, 16, 3, 122, 8, 6, 1, + 210, 89, 192, 69, 8, 6, 1, 145, 234, 190, 8, 6, 1, 223, 100, 3, 248, 225, + 8, 6, 1, 4, 6, 68, 8, 1, 4, 6, 211, 167, 8, 6, 1, 163, 225, 80, 8, 6, 1, + 163, 203, 216, 8, 6, 1, 225, 218, 3, 241, 57, 8, 6, 1, 245, 75, 8, 6, 1, + 248, 206, 8, 4, 1, 248, 206, 8, 6, 1, 214, 124, 8, 4, 1, 214, 124, 8, 6, + 1, 118, 3, 106, 8, 4, 1, 118, 3, 106, 8, 6, 1, 233, 152, 63, 8, 4, 1, + 233, 152, 63, 8, 6, 1, 233, 152, 68, 8, 4, 1, 233, 152, 68, 8, 6, 1, 233, + 152, 66, 8, 4, 1, 233, 152, 66, 8, 6, 1, 251, 87, 197, 199, 8, 4, 1, 251, + 87, 197, 199, 8, 6, 1, 247, 208, 3, 213, 215, 122, 8, 6, 1, 209, 81, 3, + 122, 8, 6, 1, 195, 159, 3, 213, 215, 122, 8, 236, 177, 1, 206, 96, 68, + 73, 1, 6, 233, 16, 3, 106, 73, 1, 4, 33, 214, 164, 8, 1, 4, 6, 163, 221, + 136, 8, 236, 177, 1, 210, 89, 236, 49, 8, 236, 177, 1, 210, 89, 214, 3, + 8, 236, 177, 1, 226, 17, 221, 136, 8, 236, 177, 1, 230, 249, 221, 231, 8, + 236, 177, 1, 250, 251, 221, 136, 204, 41, 217, 232, 1, 63, 204, 41, 217, + 232, 1, 68, 204, 41, 217, 232, 2, 237, 168, 204, 41, 217, 232, 1, 66, + 204, 41, 217, 232, 1, 69, 204, 41, 217, 232, 1, 72, 204, 41, 217, 232, 2, + 232, 167, 204, 41, 217, 232, 1, 224, 11, 204, 41, 217, 232, 1, 224, 117, + 204, 41, 217, 232, 1, 233, 144, 204, 41, 217, 232, 1, 233, 202, 204, 41, + 217, 232, 2, 251, 51, 204, 41, 217, 232, 1, 244, 182, 204, 41, 217, 232, + 1, 245, 49, 204, 41, 217, 232, 1, 225, 129, 204, 41, 217, 232, 1, 225, + 174, 204, 41, 217, 232, 1, 201, 55, 204, 41, 217, 232, 1, 201, 61, 204, + 41, 217, 232, 1, 240, 11, 204, 41, 217, 232, 1, 240, 20, 204, 41, 217, + 232, 1, 149, 204, 41, 217, 232, 1, 202, 169, 204, 41, 217, 232, 1, 239, + 28, 204, 41, 217, 232, 1, 239, 156, 204, 41, 217, 232, 1, 216, 50, 204, + 41, 217, 232, 1, 212, 117, 204, 41, 217, 232, 1, 212, 234, 204, 41, 217, + 232, 1, 248, 116, 204, 41, 217, 232, 1, 248, 188, 204, 41, 217, 232, 1, + 218, 251, 204, 41, 217, 232, 1, 209, 232, 204, 41, 217, 232, 1, 222, 7, + 204, 41, 217, 232, 1, 209, 167, 204, 41, 217, 232, 1, 205, 200, 204, 41, + 217, 232, 1, 231, 193, 204, 41, 217, 232, 18, 2, 63, 204, 41, 217, 232, + 18, 2, 68, 204, 41, 217, 232, 18, 2, 66, 204, 41, 217, 232, 18, 2, 69, + 204, 41, 217, 232, 18, 2, 214, 102, 204, 41, 217, 232, 212, 112, 220, 28, + 204, 41, 217, 232, 212, 112, 220, 27, 204, 41, 217, 232, 212, 112, 220, + 26, 204, 41, 217, 232, 212, 112, 220, 25, 173, 226, 70, 191, 97, 211, 87, + 173, 226, 70, 191, 97, 232, 225, 173, 226, 70, 191, 115, 211, 85, 173, + 226, 70, 191, 97, 206, 21, 173, 226, 70, 191, 97, 237, 26, 173, 226, 70, + 191, 115, 206, 18, 173, 226, 70, 211, 88, 78, 173, 226, 70, 212, 148, 78, + 173, 226, 70, 209, 108, 78, 173, 226, 70, 211, 89, 78, 213, 2, 1, 155, + 213, 2, 1, 224, 146, 213, 2, 1, 234, 123, 213, 2, 1, 217, 71, 213, 2, 1, + 247, 174, 213, 2, 1, 247, 16, 213, 2, 1, 225, 214, 213, 2, 1, 215, 109, + 213, 2, 1, 189, 213, 2, 1, 202, 233, 213, 2, 1, 240, 136, 213, 2, 1, 176, + 213, 2, 1, 161, 213, 2, 1, 213, 6, 213, 2, 1, 249, 145, 213, 2, 1, 166, + 213, 2, 1, 201, 113, 213, 2, 1, 201, 103, 213, 2, 1, 237, 156, 213, 2, 1, + 197, 166, 213, 2, 1, 195, 74, 213, 2, 1, 195, 115, 213, 2, 1, 4, 63, 213, + 2, 1, 164, 213, 2, 1, 169, 213, 2, 1, 172, 213, 2, 1, 207, 50, 213, 2, 1, + 183, 213, 2, 1, 142, 213, 2, 1, 63, 213, 2, 1, 68, 213, 2, 1, 66, 213, 2, + 1, 69, 213, 2, 1, 72, 213, 2, 1, 211, 159, 213, 2, 1, 196, 208, 213, 2, + 1, 235, 239, 213, 2, 1, 234, 10, 213, 2, 1, 237, 54, 213, 2, 204, 152, 1, + 197, 166, 213, 2, 204, 152, 1, 164, 213, 2, 1, 201, 78, 213, 2, 1, 201, + 66, 213, 2, 1, 240, 41, 213, 2, 1, 216, 86, 213, 2, 1, 251, 131, 164, + 213, 2, 1, 198, 243, 207, 50, 213, 2, 1, 198, 244, 142, 213, 2, 1, 250, + 186, 235, 239, 213, 2, 204, 152, 1, 169, 213, 2, 204, 98, 1, 169, 213, 2, + 1, 247, 133, 213, 2, 206, 62, 232, 138, 78, 213, 2, 52, 232, 138, 78, + 213, 2, 117, 207, 42, 213, 2, 117, 52, 207, 42, 208, 188, 2, 251, 51, + 208, 188, 2, 199, 2, 208, 188, 1, 63, 208, 188, 1, 252, 168, 208, 188, 1, + 68, 208, 188, 1, 226, 120, 208, 188, 1, 66, 208, 188, 1, 199, 245, 208, + 188, 1, 110, 144, 208, 188, 1, 110, 209, 182, 208, 188, 1, 110, 159, 208, + 188, 1, 110, 222, 38, 208, 188, 1, 69, 208, 188, 1, 237, 54, 208, 188, 1, + 251, 200, 208, 188, 1, 72, 208, 188, 1, 214, 102, 208, 188, 1, 250, 150, + 208, 188, 1, 155, 208, 188, 1, 224, 146, 208, 188, 1, 234, 123, 208, 188, + 1, 233, 230, 208, 188, 1, 217, 71, 208, 188, 1, 247, 174, 208, 188, 1, + 247, 16, 208, 188, 1, 225, 214, 208, 188, 1, 225, 180, 208, 188, 1, 215, + 109, 208, 188, 1, 201, 78, 208, 188, 1, 201, 66, 208, 188, 1, 240, 41, + 208, 188, 1, 240, 25, 208, 188, 1, 216, 86, 208, 188, 1, 189, 208, 188, + 1, 202, 233, 208, 188, 1, 240, 136, 208, 188, 1, 239, 176, 208, 188, 1, + 176, 208, 188, 1, 161, 208, 188, 1, 213, 6, 208, 188, 1, 249, 145, 208, + 188, 1, 248, 197, 208, 188, 1, 166, 208, 188, 1, 164, 208, 188, 1, 169, + 208, 188, 1, 172, 208, 188, 1, 199, 152, 208, 188, 1, 207, 50, 208, 188, + 1, 205, 80, 208, 188, 1, 183, 208, 188, 1, 142, 208, 188, 1, 222, 37, + 208, 188, 108, 2, 232, 244, 208, 188, 18, 2, 252, 168, 208, 188, 18, 2, + 68, 208, 188, 18, 2, 226, 120, 208, 188, 18, 2, 66, 208, 188, 18, 2, 199, + 245, 208, 188, 18, 2, 110, 144, 208, 188, 18, 2, 110, 209, 182, 208, 188, + 18, 2, 110, 159, 208, 188, 18, 2, 110, 222, 38, 208, 188, 18, 2, 69, 208, + 188, 18, 2, 237, 54, 208, 188, 18, 2, 251, 200, 208, 188, 18, 2, 72, 208, + 188, 18, 2, 214, 102, 208, 188, 18, 2, 250, 150, 208, 188, 2, 199, 7, + 208, 188, 2, 247, 133, 208, 188, 240, 88, 208, 188, 52, 240, 88, 208, + 188, 17, 195, 79, 208, 188, 17, 100, 208, 188, 17, 102, 208, 188, 17, + 134, 208, 188, 17, 136, 208, 188, 17, 146, 208, 188, 17, 167, 208, 188, + 17, 178, 208, 188, 17, 171, 208, 188, 17, 182, 38, 101, 17, 195, 79, 38, + 101, 17, 100, 38, 101, 17, 102, 38, 101, 17, 134, 38, 101, 17, 136, 38, + 101, 17, 146, 38, 101, 17, 167, 38, 101, 17, 178, 38, 101, 17, 171, 38, + 101, 17, 182, 38, 101, 1, 63, 38, 101, 1, 66, 38, 101, 1, 155, 38, 101, + 1, 176, 38, 101, 1, 161, 38, 101, 1, 169, 38, 101, 1, 199, 34, 38, 101, + 2, 250, 132, 101, 2, 205, 147, 247, 133, 101, 2, 247, 134, 199, 7, 101, + 2, 52, 247, 134, 199, 7, 101, 2, 247, 134, 102, 101, 2, 247, 134, 134, + 101, 2, 247, 134, 250, 132, 101, 2, 211, 196, 101, 234, 87, 235, 134, + 101, 247, 110, 101, 232, 130, 101, 2, 206, 100, 101, 225, 206, 214, 127, + 101, 1, 250, 122, 101, 18, 2, 250, 122, 224, 215, 222, 110, 17, 195, 79, + 224, 215, 222, 110, 17, 100, 224, 215, 222, 110, 17, 102, 224, 215, 222, + 110, 17, 134, 224, 215, 222, 110, 17, 136, 224, 215, 222, 110, 17, 146, + 224, 215, 222, 110, 17, 167, 224, 215, 222, 110, 17, 178, 224, 215, 222, + 110, 17, 171, 224, 215, 222, 110, 17, 182, 224, 215, 222, 110, 1, 155, + 224, 215, 222, 110, 1, 224, 146, 224, 215, 222, 110, 1, 234, 123, 224, + 215, 222, 110, 1, 217, 71, 224, 215, 222, 110, 1, 183, 224, 215, 222, + 110, 1, 207, 50, 224, 215, 222, 110, 1, 195, 115, 224, 215, 222, 110, 1, + 215, 109, 224, 215, 222, 110, 1, 189, 224, 215, 222, 110, 1, 231, 79, + 224, 215, 222, 110, 1, 176, 224, 215, 222, 110, 1, 161, 224, 215, 222, + 110, 1, 213, 6, 224, 215, 222, 110, 1, 166, 224, 215, 222, 110, 1, 240, + 136, 224, 215, 222, 110, 1, 249, 145, 224, 215, 222, 110, 1, 169, 224, + 215, 222, 110, 1, 164, 224, 215, 222, 110, 1, 172, 224, 215, 222, 110, 1, + 197, 166, 224, 215, 222, 110, 1, 202, 233, 224, 215, 222, 110, 1, 142, + 224, 215, 222, 110, 1, 199, 152, 224, 215, 222, 110, 1, 247, 174, 224, + 215, 222, 110, 1, 63, 224, 215, 222, 110, 1, 214, 164, 224, 215, 222, + 110, 1, 68, 224, 215, 222, 110, 1, 214, 102, 224, 215, 222, 110, 18, 200, + 99, 224, 215, 222, 110, 18, 69, 224, 215, 222, 110, 18, 66, 224, 215, + 222, 110, 18, 237, 54, 224, 215, 222, 110, 18, 72, 224, 215, 222, 110, + 152, 212, 133, 224, 215, 222, 110, 152, 247, 149, 224, 215, 222, 110, + 152, 247, 150, 212, 133, 224, 215, 222, 110, 2, 240, 250, 224, 215, 222, + 110, 2, 206, 120, 210, 138, 1, 155, 210, 138, 1, 234, 123, 210, 138, 1, + 217, 71, 210, 138, 1, 189, 210, 138, 1, 240, 136, 210, 138, 1, 176, 210, + 138, 1, 161, 210, 138, 1, 249, 145, 210, 138, 1, 166, 210, 138, 1, 247, + 174, 210, 138, 1, 225, 214, 210, 138, 1, 215, 109, 210, 138, 1, 183, 210, + 138, 1, 169, 210, 138, 1, 172, 210, 138, 1, 164, 210, 138, 1, 197, 166, + 210, 138, 1, 142, 210, 138, 1, 219, 241, 210, 138, 1, 217, 50, 210, 138, + 1, 217, 159, 210, 138, 1, 215, 74, 210, 138, 1, 63, 210, 138, 18, 2, 68, + 210, 138, 18, 2, 66, 210, 138, 18, 2, 69, 210, 138, 18, 2, 251, 200, 210, + 138, 18, 2, 72, 210, 138, 18, 2, 250, 150, 210, 138, 18, 2, 236, 116, + 210, 138, 18, 2, 237, 82, 210, 138, 108, 2, 217, 73, 210, 138, 108, 2, + 218, 55, 210, 138, 108, 2, 144, 210, 138, 108, 2, 233, 15, 210, 138, 199, + 7, 210, 138, 208, 133, 78, 29, 137, 202, 93, 29, 137, 202, 92, 29, 137, + 202, 90, 29, 137, 202, 95, 29, 137, 210, 49, 29, 137, 210, 33, 29, 137, + 210, 28, 29, 137, 210, 30, 29, 137, 210, 46, 29, 137, 210, 39, 29, 137, + 210, 32, 29, 137, 210, 51, 29, 137, 210, 34, 29, 137, 210, 53, 29, 137, + 210, 50, 29, 137, 219, 52, 29, 137, 219, 43, 29, 137, 219, 46, 29, 137, + 212, 191, 29, 137, 212, 202, 29, 137, 212, 203, 29, 137, 205, 64, 29, + 137, 226, 133, 29, 137, 226, 140, 29, 137, 205, 75, 29, 137, 205, 62, 29, + 137, 212, 243, 29, 137, 232, 50, 29, 137, 205, 59, 225, 199, 2, 213, 169, + 225, 199, 2, 247, 54, 225, 199, 2, 222, 205, 225, 199, 2, 197, 55, 225, + 199, 1, 63, 225, 199, 1, 230, 249, 224, 219, 225, 199, 1, 68, 225, 199, + 1, 226, 120, 225, 199, 1, 66, 225, 199, 1, 213, 244, 247, 24, 225, 199, + 1, 217, 72, 222, 163, 225, 199, 1, 217, 72, 222, 164, 210, 199, 225, 199, + 1, 69, 225, 199, 1, 251, 200, 225, 199, 1, 72, 225, 199, 1, 155, 225, + 199, 1, 225, 70, 208, 201, 225, 199, 1, 225, 70, 218, 99, 225, 199, 1, + 234, 123, 225, 199, 1, 234, 124, 218, 99, 225, 199, 1, 217, 71, 225, 199, + 1, 247, 174, 225, 199, 1, 247, 175, 218, 99, 225, 199, 1, 225, 214, 225, + 199, 1, 215, 110, 218, 99, 225, 199, 1, 225, 215, 220, 85, 225, 199, 1, + 215, 109, 225, 199, 1, 201, 78, 225, 199, 1, 201, 79, 220, 85, 225, 199, + 1, 240, 41, 225, 199, 1, 240, 42, 220, 85, 225, 199, 1, 218, 1, 218, 99, + 225, 199, 1, 189, 225, 199, 1, 203, 169, 218, 99, 225, 199, 1, 240, 136, + 225, 199, 1, 240, 137, 220, 85, 225, 199, 1, 176, 225, 199, 1, 161, 225, + 199, 1, 213, 244, 218, 99, 225, 199, 1, 249, 145, 225, 199, 1, 249, 146, + 218, 99, 225, 199, 1, 166, 225, 199, 1, 164, 225, 199, 1, 169, 225, 199, + 1, 210, 252, 251, 210, 225, 199, 1, 172, 225, 199, 1, 197, 166, 225, 199, + 1, 209, 23, 218, 99, 225, 199, 1, 209, 23, 220, 85, 225, 199, 1, 183, + 225, 199, 1, 142, 225, 199, 2, 247, 55, 203, 27, 225, 199, 18, 2, 203, + 97, 225, 199, 18, 2, 202, 16, 225, 199, 18, 2, 196, 237, 225, 199, 18, 2, + 196, 238, 219, 175, 225, 199, 18, 2, 204, 121, 225, 199, 18, 2, 204, 122, + 219, 163, 225, 199, 18, 2, 203, 121, 225, 199, 18, 2, 239, 82, 218, 98, + 225, 199, 18, 2, 213, 48, 225, 199, 108, 2, 224, 175, 225, 199, 108, 2, + 213, 62, 225, 199, 108, 2, 247, 159, 225, 199, 213, 182, 225, 199, 50, + 210, 111, 225, 199, 53, 210, 111, 225, 199, 213, 232, 251, 99, 225, 199, + 213, 232, 220, 105, 225, 199, 213, 232, 221, 178, 225, 199, 213, 232, + 197, 48, 225, 199, 213, 232, 213, 183, 225, 199, 213, 232, 222, 67, 225, + 199, 213, 232, 221, 172, 225, 199, 213, 232, 252, 0, 225, 199, 213, 232, + 252, 1, 252, 0, 225, 199, 213, 232, 212, 159, 225, 199, 163, 213, 232, + 212, 159, 225, 199, 213, 178, 225, 199, 17, 195, 79, 225, 199, 17, 100, + 225, 199, 17, 102, 225, 199, 17, 134, 225, 199, 17, 136, 225, 199, 17, + 146, 225, 199, 17, 167, 225, 199, 17, 178, 225, 199, 17, 171, 225, 199, + 17, 182, 225, 199, 213, 232, 202, 59, 201, 19, 225, 199, 213, 232, 225, + 244, 75, 1, 207, 25, 233, 230, 75, 1, 207, 25, 247, 16, 75, 1, 207, 25, + 225, 180, 75, 1, 207, 25, 216, 86, 75, 1, 207, 25, 248, 197, 75, 2, 207, + 25, 208, 185, 75, 73, 1, 207, 25, 210, 156, 75, 1, 49, 223, 53, 215, 109, + 75, 1, 49, 223, 53, 235, 239, 75, 1, 49, 223, 53, 234, 123, 75, 1, 49, + 223, 53, 233, 230, 75, 1, 49, 223, 53, 225, 214, 75, 1, 49, 223, 53, 225, + 180, 75, 1, 49, 223, 53, 240, 41, 75, 1, 49, 223, 53, 240, 25, 75, 1, 49, + 223, 53, 216, 86, 75, 49, 223, 53, 17, 195, 79, 75, 49, 223, 53, 17, 100, + 75, 49, 223, 53, 17, 102, 75, 49, 223, 53, 17, 134, 75, 49, 223, 53, 17, + 136, 75, 49, 223, 53, 17, 146, 75, 49, 223, 53, 17, 167, 75, 49, 223, 53, + 17, 178, 75, 49, 223, 53, 17, 171, 75, 49, 223, 53, 17, 182, 75, 1, 49, + 223, 53, 222, 37, 75, 1, 49, 223, 53, 240, 136, 75, 1, 49, 223, 53, 239, + 176, 75, 1, 49, 223, 53, 249, 145, 75, 1, 49, 223, 53, 248, 197, 247, 9, + 1, 63, 247, 9, 1, 68, 247, 9, 1, 66, 247, 9, 1, 69, 247, 9, 1, 251, 200, + 247, 9, 1, 72, 247, 9, 1, 155, 247, 9, 1, 224, 146, 247, 9, 1, 234, 123, + 247, 9, 1, 233, 230, 247, 9, 1, 216, 236, 247, 9, 1, 217, 71, 247, 9, 1, + 247, 16, 247, 9, 1, 245, 77, 247, 9, 1, 225, 214, 247, 9, 1, 225, 180, + 247, 9, 1, 216, 225, 247, 9, 1, 216, 227, 247, 9, 1, 216, 226, 247, 9, 1, + 189, 247, 9, 1, 202, 233, 247, 9, 1, 240, 136, 247, 9, 1, 239, 176, 247, + 9, 1, 215, 152, 247, 9, 1, 176, 247, 9, 1, 240, 41, 247, 9, 1, 161, 247, + 9, 1, 212, 54, 247, 9, 1, 213, 6, 247, 9, 1, 249, 145, 247, 9, 1, 248, + 197, 247, 9, 1, 218, 133, 247, 9, 1, 166, 247, 9, 1, 249, 45, 247, 9, 1, + 164, 247, 9, 1, 169, 247, 9, 1, 172, 247, 9, 1, 199, 152, 247, 9, 1, 205, + 80, 247, 9, 1, 183, 247, 9, 1, 142, 247, 9, 18, 2, 252, 168, 247, 9, 18, + 2, 68, 247, 9, 18, 2, 226, 120, 247, 9, 18, 2, 237, 33, 247, 9, 18, 2, + 66, 247, 9, 18, 2, 214, 164, 247, 9, 18, 2, 72, 247, 9, 18, 2, 251, 200, + 247, 9, 18, 2, 250, 150, 247, 9, 18, 2, 200, 99, 247, 9, 108, 2, 164, + 247, 9, 108, 2, 169, 247, 9, 108, 2, 172, 247, 9, 108, 2, 197, 166, 247, + 9, 1, 48, 225, 80, 247, 9, 1, 48, 234, 190, 247, 9, 1, 48, 217, 73, 247, + 9, 108, 2, 48, 217, 73, 247, 9, 1, 48, 247, 18, 247, 9, 1, 48, 203, 216, + 247, 9, 1, 48, 218, 55, 247, 9, 1, 48, 214, 3, 247, 9, 1, 48, 196, 148, + 247, 9, 1, 48, 144, 247, 9, 1, 48, 159, 247, 9, 1, 48, 205, 83, 247, 9, + 108, 2, 48, 221, 136, 247, 9, 108, 2, 48, 233, 15, 247, 9, 17, 195, 79, + 247, 9, 17, 100, 247, 9, 17, 102, 247, 9, 17, 134, 247, 9, 17, 136, 247, + 9, 17, 146, 247, 9, 17, 167, 247, 9, 17, 178, 247, 9, 17, 171, 247, 9, + 17, 182, 247, 9, 211, 214, 205, 120, 247, 9, 211, 214, 240, 88, 247, 9, + 211, 214, 52, 240, 88, 247, 9, 211, 214, 201, 165, 240, 88, 75, 1, 224, + 139, 234, 123, 75, 1, 224, 139, 247, 174, 75, 1, 224, 139, 247, 16, 75, + 1, 224, 139, 225, 214, 75, 1, 224, 139, 225, 180, 75, 1, 224, 139, 215, + 109, 75, 1, 224, 139, 201, 78, 75, 1, 224, 139, 201, 66, 75, 1, 224, 139, + 240, 41, 75, 1, 224, 139, 240, 25, 75, 1, 224, 139, 239, 176, 75, 1, 224, + 139, 176, 75, 1, 224, 139, 183, 75, 1, 224, 139, 142, 75, 1, 224, 139, + 232, 80, 75, 1, 224, 139, 235, 239, 75, 73, 1, 224, 139, 210, 156, 75, 1, + 224, 139, 196, 208, 75, 1, 224, 139, 195, 115, 75, 1, 224, 139, 169, 75, + 221, 248, 224, 139, 214, 187, 75, 221, 248, 224, 139, 211, 110, 75, 221, + 248, 224, 139, 231, 248, 75, 16, 251, 186, 236, 89, 75, 16, 251, 186, + 100, 75, 16, 251, 186, 102, 75, 1, 251, 186, 169, 75, 2, 213, 165, 224, + 248, 202, 11, 75, 2, 49, 223, 53, 202, 9, 75, 2, 49, 223, 53, 202, 6, 75, + 1, 206, 128, 213, 212, 247, 16, 75, 1, 206, 128, 213, 212, 207, 50, 49, + 199, 24, 1, 126, 224, 11, 49, 199, 24, 1, 130, 224, 11, 49, 199, 24, 1, + 126, 224, 117, 49, 199, 24, 1, 130, 224, 117, 49, 199, 24, 1, 126, 224, + 126, 49, 199, 24, 1, 130, 224, 126, 49, 199, 24, 1, 126, 233, 144, 49, + 199, 24, 1, 130, 233, 144, 49, 199, 24, 1, 126, 216, 252, 49, 199, 24, 1, + 130, 216, 252, 49, 199, 24, 1, 126, 244, 182, 49, 199, 24, 1, 130, 244, + 182, 49, 199, 24, 1, 126, 245, 49, 49, 199, 24, 1, 130, 245, 49, 49, 199, + 24, 1, 126, 205, 200, 49, 199, 24, 1, 130, 205, 200, 49, 199, 24, 1, 126, + 215, 73, 49, 199, 24, 1, 130, 215, 73, 49, 199, 24, 1, 126, 239, 28, 49, + 199, 24, 1, 130, 239, 28, 49, 199, 24, 1, 126, 149, 49, 199, 24, 1, 130, + 149, 49, 199, 24, 1, 126, 202, 169, 49, 199, 24, 1, 130, 202, 169, 49, + 199, 24, 1, 126, 216, 50, 49, 199, 24, 1, 130, 216, 50, 49, 199, 24, 1, + 126, 248, 116, 49, 199, 24, 1, 130, 248, 116, 49, 199, 24, 1, 126, 212, + 117, 49, 199, 24, 1, 130, 212, 117, 49, 199, 24, 1, 126, 212, 234, 49, + 199, 24, 1, 130, 212, 234, 49, 199, 24, 1, 126, 235, 51, 49, 199, 24, 1, + 130, 235, 51, 49, 199, 24, 1, 126, 218, 251, 49, 199, 24, 1, 130, 218, + 251, 49, 199, 24, 1, 126, 196, 3, 49, 199, 24, 1, 130, 196, 3, 49, 199, + 24, 1, 126, 209, 232, 49, 199, 24, 1, 130, 209, 232, 49, 199, 24, 1, 126, + 222, 7, 49, 199, 24, 1, 130, 222, 7, 49, 199, 24, 1, 126, 198, 248, 49, + 199, 24, 1, 130, 198, 248, 49, 199, 24, 1, 126, 231, 193, 49, 199, 24, 1, + 130, 231, 193, 49, 199, 24, 1, 126, 72, 49, 199, 24, 1, 130, 72, 49, 199, + 24, 220, 82, 225, 13, 49, 199, 24, 18, 252, 168, 49, 199, 24, 18, 68, 49, + 199, 24, 18, 200, 99, 49, 199, 24, 18, 66, 49, 199, 24, 18, 69, 49, 199, + 24, 18, 72, 49, 199, 24, 220, 82, 224, 120, 49, 199, 24, 18, 230, 210, + 49, 199, 24, 18, 200, 98, 49, 199, 24, 18, 200, 114, 49, 199, 24, 18, + 250, 148, 49, 199, 24, 18, 250, 122, 49, 199, 24, 18, 251, 106, 49, 199, + 24, 18, 251, 123, 49, 199, 24, 152, 220, 82, 237, 14, 49, 199, 24, 152, + 220, 82, 215, 151, 49, 199, 24, 152, 220, 82, 202, 169, 49, 199, 24, 152, + 220, 82, 205, 173, 49, 199, 24, 16, 223, 245, 49, 199, 24, 16, 215, 151, + 49, 199, 24, 16, 208, 229, 49, 199, 24, 16, 231, 194, 231, 180, 49, 199, + 24, 16, 224, 0, 223, 255, 219, 182, 219, 248, 1, 69, 219, 182, 219, 248, + 1, 72, 219, 182, 219, 248, 1, 247, 16, 219, 182, 219, 248, 1, 215, 109, + 219, 182, 219, 248, 1, 201, 78, 219, 182, 219, 248, 1, 201, 66, 219, 182, + 219, 248, 1, 240, 41, 219, 182, 219, 248, 1, 240, 25, 219, 182, 219, 248, + 1, 216, 86, 219, 182, 219, 248, 1, 207, 50, 219, 182, 219, 248, 1, 205, + 80, 219, 182, 219, 248, 18, 2, 226, 120, 219, 182, 219, 248, 18, 2, 199, + 245, 219, 182, 219, 248, 18, 2, 252, 132, 219, 182, 219, 248, 18, 2, 250, + 150, 219, 182, 219, 248, 18, 2, 252, 124, 219, 182, 219, 248, 245, 92, + 219, 182, 219, 248, 251, 206, 224, 108, 219, 182, 219, 248, 251, 80, 219, + 182, 219, 248, 5, 210, 117, 78, 219, 182, 219, 248, 197, 9, 210, 117, 78, + 219, 182, 219, 248, 18, 2, 199, 2, 219, 182, 219, 248, 199, 7, 35, 5, + 201, 59, 35, 5, 201, 62, 35, 5, 201, 65, 35, 5, 201, 63, 35, 5, 201, 64, + 35, 5, 201, 61, 35, 5, 240, 19, 35, 5, 240, 21, 35, 5, 240, 24, 35, 5, + 240, 22, 35, 5, 240, 23, 35, 5, 240, 20, 35, 5, 237, 143, 35, 5, 237, + 147, 35, 5, 237, 155, 35, 5, 237, 152, 35, 5, 237, 153, 35, 5, 237, 144, + 35, 5, 247, 71, 35, 5, 247, 65, 35, 5, 247, 67, 35, 5, 247, 70, 35, 5, + 247, 68, 35, 5, 247, 69, 35, 5, 247, 66, 35, 5, 249, 45, 35, 5, 249, 24, + 35, 5, 249, 36, 35, 5, 249, 44, 35, 5, 249, 39, 35, 5, 249, 40, 35, 5, + 249, 28, 8, 4, 1, 249, 74, 251, 134, 8, 4, 1, 39, 210, 87, 8, 4, 1, 248, + 132, 69, 8, 4, 1, 249, 74, 69, 8, 4, 1, 237, 136, 3, 235, 64, 8, 4, 1, + 222, 149, 236, 49, 8, 4, 1, 145, 234, 191, 3, 241, 57, 8, 4, 1, 223, 100, + 3, 226, 17, 222, 204, 209, 80, 8, 4, 1, 223, 100, 3, 52, 112, 202, 84, 8, + 4, 1, 223, 100, 3, 112, 210, 2, 8, 4, 1, 221, 137, 3, 241, 57, 8, 4, 1, + 218, 56, 3, 241, 57, 8, 4, 1, 236, 216, 3, 241, 57, 8, 4, 1, 248, 132, + 72, 8, 4, 1, 248, 132, 177, 3, 106, 8, 4, 1, 192, 177, 3, 106, 8, 4, 1, + 226, 17, 214, 164, 8, 4, 1, 163, 214, 165, 3, 106, 8, 4, 1, 163, 214, + 165, 3, 231, 155, 106, 8, 4, 1, 163, 177, 214, 88, 8, 4, 1, 163, 177, + 214, 89, 3, 106, 8, 4, 1, 204, 231, 144, 8, 1, 4, 6, 211, 32, 3, 53, 222, + 172, 8, 4, 1, 211, 32, 197, 37, 232, 187, 8, 4, 1, 52, 144, 8, 4, 1, 211, + 32, 3, 241, 57, 8, 4, 1, 52, 211, 32, 3, 241, 57, 8, 4, 1, 145, 144, 8, + 4, 1, 145, 211, 32, 3, 210, 2, 8, 4, 1, 249, 64, 236, 141, 8, 4, 1, 118, + 3, 206, 182, 53, 222, 172, 8, 4, 1, 118, 249, 80, 3, 206, 182, 53, 222, + 172, 8, 4, 1, 200, 90, 8, 4, 1, 163, 200, 90, 8, 4, 1, 118, 3, 50, 122, + 8, 4, 1, 245, 75, 8, 4, 1, 245, 76, 3, 126, 53, 210, 2, 8, 4, 1, 245, 76, + 3, 126, 50, 207, 85, 8, 4, 1, 196, 223, 3, 126, 53, 210, 2, 8, 4, 1, 196, + 223, 3, 181, 50, 222, 172, 8, 4, 1, 196, 223, 3, 181, 50, 222, 173, 26, + 126, 53, 210, 2, 8, 4, 1, 196, 223, 3, 181, 50, 222, 173, 3, 207, 85, 8, + 4, 1, 196, 149, 3, 206, 182, 53, 222, 172, 73, 248, 48, 3, 226, 17, 248, + 47, 73, 1, 4, 232, 99, 73, 1, 4, 223, 100, 3, 226, 17, 222, 204, 209, 80, + 73, 1, 4, 223, 100, 3, 112, 202, 84, 73, 1, 4, 118, 3, 50, 122, 8, 4, 1, + 208, 246, 196, 84, 8, 4, 1, 226, 5, 69, 8, 4, 1, 192, 214, 164, 8, 4, 1, + 200, 41, 8, 4, 1, 226, 17, 251, 134, 32, 1, 4, 6, 214, 124, 8, 4, 1, 237, + 158, 239, 111, 3, 210, 95, 122, 8, 4, 1, 201, 115, 239, 111, 3, 210, 95, + 122, 95, 4, 1, 63, 95, 4, 1, 69, 95, 4, 1, 68, 95, 4, 1, 72, 95, 4, 1, + 66, 95, 4, 1, 199, 230, 95, 4, 1, 234, 123, 95, 4, 1, 155, 95, 4, 1, 234, + 48, 95, 4, 1, 233, 192, 95, 4, 1, 233, 144, 95, 4, 1, 233, 76, 95, 4, 1, + 233, 36, 95, 4, 1, 142, 95, 4, 1, 232, 147, 95, 4, 1, 232, 71, 95, 4, 1, + 231, 193, 95, 4, 1, 231, 75, 95, 4, 1, 231, 44, 95, 4, 1, 172, 95, 4, 1, + 222, 197, 95, 4, 1, 222, 109, 95, 4, 1, 222, 7, 95, 4, 1, 221, 191, 95, + 4, 1, 221, 160, 95, 4, 1, 166, 95, 4, 1, 219, 207, 95, 4, 1, 219, 78, 95, + 4, 1, 218, 251, 95, 4, 1, 218, 145, 95, 4, 1, 176, 95, 4, 1, 231, 217, + 95, 4, 1, 217, 231, 95, 4, 1, 217, 118, 95, 4, 1, 216, 223, 95, 4, 1, + 216, 50, 95, 4, 1, 215, 186, 95, 4, 1, 215, 120, 95, 4, 1, 211, 96, 95, + 4, 1, 211, 82, 95, 4, 1, 211, 75, 95, 4, 1, 211, 65, 95, 4, 1, 211, 54, + 95, 4, 1, 211, 52, 95, 4, 1, 183, 95, 4, 1, 209, 80, 95, 4, 1, 208, 147, + 95, 4, 1, 206, 112, 95, 4, 1, 205, 200, 95, 4, 1, 204, 172, 95, 4, 1, + 204, 72, 95, 4, 1, 240, 136, 95, 4, 1, 189, 95, 4, 1, 239, 252, 95, 4, 1, + 203, 68, 95, 4, 1, 239, 152, 95, 4, 1, 202, 122, 95, 4, 1, 239, 28, 95, + 4, 1, 237, 201, 95, 4, 1, 237, 170, 95, 4, 1, 239, 40, 95, 4, 1, 202, 47, + 95, 4, 1, 202, 46, 95, 4, 1, 202, 35, 95, 4, 1, 202, 34, 95, 4, 1, 202, + 33, 95, 4, 1, 202, 32, 95, 4, 1, 201, 113, 95, 4, 1, 201, 107, 95, 4, 1, + 201, 92, 95, 4, 1, 201, 90, 95, 4, 1, 201, 86, 95, 4, 1, 201, 85, 95, 4, + 1, 197, 166, 95, 4, 1, 197, 109, 95, 4, 1, 197, 70, 95, 4, 1, 197, 34, + 95, 4, 1, 196, 243, 95, 4, 1, 196, 230, 95, 4, 1, 164, 219, 182, 219, + 248, 1, 223, 252, 219, 182, 219, 248, 1, 208, 229, 219, 182, 219, 248, 1, + 223, 54, 219, 182, 219, 248, 1, 219, 6, 219, 182, 219, 248, 1, 161, 219, + 182, 219, 248, 1, 176, 219, 182, 219, 248, 1, 245, 67, 219, 182, 219, + 248, 1, 202, 86, 219, 182, 219, 248, 1, 224, 111, 219, 182, 219, 248, 1, + 216, 242, 219, 182, 219, 248, 1, 202, 161, 219, 182, 219, 248, 1, 197, + 154, 219, 182, 219, 248, 1, 196, 95, 219, 182, 219, 248, 1, 231, 64, 219, + 182, 219, 248, 1, 200, 72, 219, 182, 219, 248, 1, 68, 219, 182, 219, 248, + 1, 213, 0, 219, 182, 219, 248, 1, 250, 161, 219, 182, 219, 248, 1, 233, + 136, 219, 182, 219, 248, 1, 225, 178, 219, 182, 219, 248, 1, 210, 224, + 219, 182, 219, 248, 1, 249, 145, 219, 182, 219, 248, 1, 225, 162, 219, + 182, 219, 248, 1, 239, 109, 219, 182, 219, 248, 1, 233, 199, 219, 182, + 219, 248, 1, 239, 154, 219, 182, 219, 248, 1, 248, 194, 219, 182, 219, + 248, 1, 223, 253, 221, 230, 219, 182, 219, 248, 1, 223, 55, 221, 230, + 219, 182, 219, 248, 1, 219, 7, 221, 230, 219, 182, 219, 248, 1, 213, 244, + 221, 230, 219, 182, 219, 248, 1, 218, 1, 221, 230, 219, 182, 219, 248, 1, + 202, 87, 221, 230, 219, 182, 219, 248, 1, 216, 243, 221, 230, 219, 182, + 219, 248, 1, 230, 249, 221, 230, 219, 182, 219, 248, 18, 2, 214, 117, + 219, 182, 219, 248, 18, 2, 226, 84, 219, 182, 219, 248, 18, 2, 251, 104, + 219, 182, 219, 248, 18, 2, 196, 58, 219, 182, 219, 248, 18, 2, 205, 163, + 219, 182, 219, 248, 18, 2, 200, 69, 219, 182, 219, 248, 18, 2, 245, 90, + 219, 182, 219, 248, 18, 2, 215, 135, 219, 182, 219, 248, 245, 91, 219, + 182, 219, 248, 221, 175, 225, 223, 219, 182, 219, 248, 251, 19, 225, 223, + 219, 182, 219, 248, 17, 195, 79, 219, 182, 219, 248, 17, 100, 219, 182, + 219, 248, 17, 102, 219, 182, 219, 248, 17, 134, 219, 182, 219, 248, 17, + 136, 219, 182, 219, 248, 17, 146, 219, 182, 219, 248, 17, 167, 219, 182, + 219, 248, 17, 178, 219, 182, 219, 248, 17, 171, 219, 182, 219, 248, 17, + 182, 29, 225, 102, 215, 11, 29, 225, 102, 215, 16, 29, 225, 102, 195, + 252, 29, 225, 102, 195, 251, 29, 225, 102, 195, 250, 29, 225, 102, 200, + 164, 29, 225, 102, 200, 168, 29, 225, 102, 195, 211, 29, 225, 102, 195, + 207, 29, 225, 102, 236, 115, 29, 225, 102, 236, 113, 29, 225, 102, 236, + 114, 29, 225, 102, 236, 111, 29, 225, 102, 230, 235, 29, 225, 102, 230, + 234, 29, 225, 102, 230, 232, 29, 225, 102, 230, 233, 29, 225, 102, 230, + 238, 29, 225, 102, 230, 231, 29, 225, 102, 230, 230, 29, 225, 102, 230, + 240, 29, 225, 102, 251, 5, 29, 225, 102, 251, 4, 29, 116, 216, 201, 29, + 116, 216, 207, 29, 116, 205, 61, 29, 116, 205, 60, 29, 116, 202, 92, 29, + 116, 202, 90, 29, 116, 202, 89, 29, 116, 202, 95, 29, 116, 202, 96, 29, + 116, 202, 88, 29, 116, 210, 33, 29, 116, 210, 48, 29, 116, 205, 67, 29, + 116, 210, 45, 29, 116, 210, 35, 29, 116, 210, 37, 29, 116, 210, 24, 29, + 116, 210, 25, 29, 116, 224, 254, 29, 116, 219, 51, 29, 116, 219, 45, 29, + 116, 205, 71, 29, 116, 219, 48, 29, 116, 219, 54, 29, 116, 212, 187, 29, + 116, 212, 196, 29, 116, 212, 200, 29, 116, 205, 69, 29, 116, 212, 190, + 29, 116, 212, 204, 29, 116, 212, 205, 29, 116, 206, 44, 29, 116, 206, 47, + 29, 116, 205, 65, 29, 116, 205, 63, 29, 116, 206, 42, 29, 116, 206, 50, + 29, 116, 206, 51, 29, 116, 206, 36, 29, 116, 206, 49, 29, 116, 213, 172, + 29, 116, 213, 173, 29, 116, 196, 42, 29, 116, 196, 45, 29, 116, 245, 4, + 29, 116, 245, 3, 29, 116, 205, 76, 29, 116, 212, 241, 29, 116, 212, 240, + 12, 15, 228, 111, 12, 15, 228, 110, 12, 15, 228, 109, 12, 15, 228, 108, + 12, 15, 228, 107, 12, 15, 228, 106, 12, 15, 228, 105, 12, 15, 228, 104, + 12, 15, 228, 103, 12, 15, 228, 102, 12, 15, 228, 101, 12, 15, 228, 100, + 12, 15, 228, 99, 12, 15, 228, 98, 12, 15, 228, 97, 12, 15, 228, 96, 12, + 15, 228, 95, 12, 15, 228, 94, 12, 15, 228, 93, 12, 15, 228, 92, 12, 15, + 228, 91, 12, 15, 228, 90, 12, 15, 228, 89, 12, 15, 228, 88, 12, 15, 228, + 87, 12, 15, 228, 86, 12, 15, 228, 85, 12, 15, 228, 84, 12, 15, 228, 83, + 12, 15, 228, 82, 12, 15, 228, 81, 12, 15, 228, 80, 12, 15, 228, 79, 12, + 15, 228, 78, 12, 15, 228, 77, 12, 15, 228, 76, 12, 15, 228, 75, 12, 15, + 228, 74, 12, 15, 228, 73, 12, 15, 228, 72, 12, 15, 228, 71, 12, 15, 228, + 70, 12, 15, 228, 69, 12, 15, 228, 68, 12, 15, 228, 67, 12, 15, 228, 66, + 12, 15, 228, 65, 12, 15, 228, 64, 12, 15, 228, 63, 12, 15, 228, 62, 12, + 15, 228, 61, 12, 15, 228, 60, 12, 15, 228, 59, 12, 15, 228, 58, 12, 15, + 228, 57, 12, 15, 228, 56, 12, 15, 228, 55, 12, 15, 228, 54, 12, 15, 228, + 53, 12, 15, 228, 52, 12, 15, 228, 51, 12, 15, 228, 50, 12, 15, 228, 49, + 12, 15, 228, 48, 12, 15, 228, 47, 12, 15, 228, 46, 12, 15, 228, 45, 12, + 15, 228, 44, 12, 15, 228, 43, 12, 15, 228, 42, 12, 15, 228, 41, 12, 15, + 228, 40, 12, 15, 228, 39, 12, 15, 228, 38, 12, 15, 228, 37, 12, 15, 228, + 36, 12, 15, 228, 35, 12, 15, 228, 34, 12, 15, 228, 33, 12, 15, 228, 32, + 12, 15, 228, 31, 12, 15, 228, 30, 12, 15, 228, 29, 12, 15, 228, 28, 12, + 15, 228, 27, 12, 15, 228, 26, 12, 15, 228, 25, 12, 15, 228, 24, 12, 15, + 228, 23, 12, 15, 228, 22, 12, 15, 228, 21, 12, 15, 228, 20, 12, 15, 228, + 19, 12, 15, 228, 18, 12, 15, 228, 17, 12, 15, 228, 16, 12, 15, 228, 15, + 12, 15, 228, 14, 12, 15, 228, 13, 12, 15, 228, 12, 12, 15, 228, 11, 12, + 15, 228, 10, 12, 15, 228, 9, 12, 15, 228, 8, 12, 15, 228, 7, 12, 15, 228, + 6, 12, 15, 228, 5, 12, 15, 228, 4, 12, 15, 228, 3, 12, 15, 228, 2, 12, + 15, 228, 1, 12, 15, 228, 0, 12, 15, 227, 255, 12, 15, 227, 254, 12, 15, + 227, 253, 12, 15, 227, 252, 12, 15, 227, 251, 12, 15, 227, 250, 12, 15, + 227, 249, 12, 15, 227, 248, 12, 15, 227, 247, 12, 15, 227, 246, 12, 15, + 227, 245, 12, 15, 227, 244, 12, 15, 227, 243, 12, 15, 227, 242, 12, 15, + 227, 241, 12, 15, 227, 240, 12, 15, 227, 239, 12, 15, 227, 238, 12, 15, + 227, 237, 12, 15, 227, 236, 12, 15, 227, 235, 12, 15, 227, 234, 12, 15, + 227, 233, 12, 15, 227, 232, 12, 15, 227, 231, 12, 15, 227, 230, 12, 15, + 227, 229, 12, 15, 227, 228, 12, 15, 227, 227, 12, 15, 227, 226, 12, 15, + 227, 225, 12, 15, 227, 224, 12, 15, 227, 223, 12, 15, 227, 222, 12, 15, + 227, 221, 12, 15, 227, 220, 12, 15, 227, 219, 12, 15, 227, 218, 12, 15, + 227, 217, 12, 15, 227, 216, 12, 15, 227, 215, 12, 15, 227, 214, 12, 15, + 227, 213, 12, 15, 227, 212, 12, 15, 227, 211, 12, 15, 227, 210, 12, 15, + 227, 209, 12, 15, 227, 208, 12, 15, 227, 207, 12, 15, 227, 206, 12, 15, + 227, 205, 12, 15, 227, 204, 12, 15, 227, 203, 12, 15, 227, 202, 12, 15, + 227, 201, 12, 15, 227, 200, 12, 15, 227, 199, 12, 15, 227, 198, 12, 15, + 227, 197, 12, 15, 227, 196, 12, 15, 227, 195, 12, 15, 227, 194, 12, 15, + 227, 193, 12, 15, 227, 192, 12, 15, 227, 191, 12, 15, 227, 190, 12, 15, + 227, 189, 12, 15, 227, 188, 12, 15, 227, 187, 12, 15, 227, 186, 12, 15, + 227, 185, 12, 15, 227, 184, 12, 15, 227, 183, 12, 15, 227, 182, 12, 15, + 227, 181, 12, 15, 227, 180, 12, 15, 227, 179, 12, 15, 227, 178, 12, 15, + 227, 177, 12, 15, 227, 176, 12, 15, 227, 175, 12, 15, 227, 174, 12, 15, + 227, 173, 12, 15, 227, 172, 12, 15, 227, 171, 12, 15, 227, 170, 12, 15, + 227, 169, 12, 15, 227, 168, 12, 15, 227, 167, 12, 15, 227, 166, 12, 15, + 227, 165, 12, 15, 227, 164, 12, 15, 227, 163, 12, 15, 227, 162, 12, 15, + 227, 161, 12, 15, 227, 160, 12, 15, 227, 159, 12, 15, 227, 158, 12, 15, + 227, 157, 12, 15, 227, 156, 12, 15, 227, 155, 12, 15, 227, 154, 12, 15, + 227, 153, 12, 15, 227, 152, 12, 15, 227, 151, 12, 15, 227, 150, 12, 15, + 227, 149, 12, 15, 227, 148, 12, 15, 227, 147, 12, 15, 227, 146, 12, 15, + 227, 145, 12, 15, 227, 144, 12, 15, 227, 143, 12, 15, 227, 142, 12, 15, + 227, 141, 12, 15, 227, 140, 12, 15, 227, 139, 12, 15, 227, 138, 12, 15, + 227, 137, 12, 15, 227, 136, 12, 15, 227, 135, 12, 15, 227, 134, 12, 15, + 227, 133, 12, 15, 227, 132, 12, 15, 227, 131, 12, 15, 227, 130, 12, 15, + 227, 129, 12, 15, 227, 128, 12, 15, 227, 127, 12, 15, 227, 126, 12, 15, + 227, 125, 12, 15, 227, 124, 12, 15, 227, 123, 12, 15, 227, 122, 12, 15, + 227, 121, 12, 15, 227, 120, 12, 15, 227, 119, 12, 15, 227, 118, 12, 15, + 227, 117, 12, 15, 227, 116, 12, 15, 227, 115, 12, 15, 227, 114, 12, 15, + 227, 113, 12, 15, 227, 112, 12, 15, 227, 111, 12, 15, 227, 110, 12, 15, + 227, 109, 12, 15, 227, 108, 12, 15, 227, 107, 12, 15, 227, 106, 12, 15, + 227, 105, 12, 15, 227, 104, 12, 15, 227, 103, 12, 15, 227, 102, 12, 15, + 227, 101, 12, 15, 227, 100, 12, 15, 227, 99, 12, 15, 227, 98, 12, 15, + 227, 97, 12, 15, 227, 96, 12, 15, 227, 95, 12, 15, 227, 94, 12, 15, 227, + 93, 12, 15, 227, 92, 12, 15, 227, 91, 12, 15, 227, 90, 12, 15, 227, 89, + 12, 15, 227, 88, 12, 15, 227, 87, 12, 15, 227, 86, 12, 15, 227, 85, 12, + 15, 227, 84, 12, 15, 227, 83, 12, 15, 227, 82, 12, 15, 227, 81, 12, 15, + 227, 80, 12, 15, 227, 79, 12, 15, 227, 78, 12, 15, 227, 77, 12, 15, 227, + 76, 12, 15, 227, 75, 12, 15, 227, 74, 12, 15, 227, 73, 12, 15, 227, 72, + 12, 15, 227, 71, 12, 15, 227, 70, 12, 15, 227, 69, 12, 15, 227, 68, 12, + 15, 227, 67, 12, 15, 227, 66, 12, 15, 227, 65, 12, 15, 227, 64, 12, 15, + 227, 63, 12, 15, 227, 62, 12, 15, 227, 61, 12, 15, 227, 60, 12, 15, 227, + 59, 12, 15, 227, 58, 12, 15, 227, 57, 12, 15, 227, 56, 12, 15, 227, 55, + 12, 15, 227, 54, 12, 15, 227, 53, 12, 15, 227, 52, 12, 15, 227, 51, 12, + 15, 227, 50, 12, 15, 227, 49, 12, 15, 227, 48, 12, 15, 227, 47, 12, 15, + 227, 46, 12, 15, 227, 45, 12, 15, 227, 44, 12, 15, 227, 43, 12, 15, 227, + 42, 12, 15, 227, 41, 12, 15, 227, 40, 12, 15, 227, 39, 12, 15, 227, 38, + 12, 15, 227, 37, 12, 15, 227, 36, 12, 15, 227, 35, 12, 15, 227, 34, 12, + 15, 227, 33, 12, 15, 227, 32, 12, 15, 227, 31, 12, 15, 227, 30, 12, 15, + 227, 29, 12, 15, 227, 28, 12, 15, 227, 27, 12, 15, 227, 26, 12, 15, 227, + 25, 12, 15, 227, 24, 12, 15, 227, 23, 12, 15, 227, 22, 12, 15, 227, 21, + 12, 15, 227, 20, 12, 15, 227, 19, 12, 15, 227, 18, 12, 15, 227, 17, 12, + 15, 227, 16, 12, 15, 227, 15, 12, 15, 227, 14, 12, 15, 227, 13, 12, 15, + 227, 12, 12, 15, 227, 11, 12, 15, 227, 10, 12, 15, 227, 9, 12, 15, 227, + 8, 12, 15, 227, 7, 12, 15, 227, 6, 12, 15, 227, 5, 12, 15, 227, 4, 12, + 15, 227, 3, 12, 15, 227, 2, 12, 15, 227, 1, 12, 15, 227, 0, 12, 15, 226, + 255, 12, 15, 226, 254, 12, 15, 226, 253, 12, 15, 226, 252, 12, 15, 226, + 251, 12, 15, 226, 250, 12, 15, 226, 249, 12, 15, 226, 248, 12, 15, 226, + 247, 12, 15, 226, 246, 12, 15, 226, 245, 12, 15, 226, 244, 12, 15, 226, + 243, 12, 15, 226, 242, 12, 15, 226, 241, 12, 15, 226, 240, 12, 15, 226, + 239, 12, 15, 226, 238, 12, 15, 226, 237, 12, 15, 226, 236, 12, 15, 226, + 235, 12, 15, 226, 234, 12, 15, 226, 233, 12, 15, 226, 232, 12, 15, 226, + 231, 12, 15, 226, 230, 12, 15, 226, 229, 12, 15, 226, 228, 12, 15, 226, + 227, 12, 15, 226, 226, 12, 15, 226, 225, 12, 15, 226, 224, 12, 15, 226, + 223, 12, 15, 226, 222, 12, 15, 226, 221, 12, 15, 226, 220, 12, 15, 226, + 219, 12, 15, 226, 218, 12, 15, 226, 217, 12, 15, 226, 216, 12, 15, 226, + 215, 12, 15, 226, 214, 12, 15, 226, 213, 12, 15, 226, 212, 12, 15, 226, + 211, 12, 15, 226, 210, 12, 15, 226, 209, 12, 15, 226, 208, 12, 15, 226, + 207, 12, 15, 226, 206, 12, 15, 226, 205, 12, 15, 226, 204, 12, 15, 226, + 203, 12, 15, 226, 202, 12, 15, 226, 201, 12, 15, 226, 200, 12, 15, 226, + 199, 12, 15, 226, 198, 12, 15, 226, 197, 12, 15, 226, 196, 12, 15, 226, + 195, 12, 15, 226, 194, 12, 15, 226, 193, 12, 15, 226, 192, 12, 15, 226, + 191, 12, 15, 226, 190, 12, 15, 226, 189, 12, 15, 226, 188, 12, 15, 226, + 187, 12, 15, 226, 186, 12, 15, 226, 185, 12, 15, 226, 184, 12, 15, 226, + 183, 12, 15, 226, 182, 12, 15, 226, 181, 12, 15, 226, 180, 12, 15, 226, + 179, 12, 15, 226, 178, 12, 15, 226, 177, 12, 15, 226, 176, 12, 15, 226, + 175, 12, 15, 226, 174, 12, 15, 226, 173, 12, 15, 226, 172, 12, 15, 226, + 171, 12, 15, 226, 170, 12, 15, 226, 169, 12, 15, 226, 168, 12, 15, 226, + 167, 12, 15, 226, 166, 12, 15, 226, 165, 12, 15, 226, 164, 12, 15, 226, + 163, 12, 15, 226, 162, 12, 15, 226, 161, 12, 15, 226, 160, 12, 15, 226, + 159, 12, 15, 226, 158, 12, 15, 226, 157, 12, 15, 226, 156, 12, 15, 226, + 155, 12, 15, 226, 154, 12, 15, 226, 153, 12, 15, 226, 152, 8, 4, 33, 235, + 157, 8, 4, 33, 235, 153, 8, 4, 33, 235, 96, 8, 4, 33, 235, 156, 8, 4, 33, + 235, 155, 8, 4, 33, 181, 209, 81, 203, 216, 8, 4, 33, 205, 23, 250, 230, + 4, 33, 219, 165, 216, 4, 250, 230, 4, 33, 219, 165, 237, 60, 250, 230, 4, + 33, 219, 165, 226, 55, 250, 230, 4, 33, 199, 40, 216, 4, 250, 230, 4, 33, + 219, 165, 196, 200, 123, 1, 195, 242, 3, 232, 33, 123, 212, 111, 225, + 109, 199, 130, 123, 33, 196, 22, 195, 242, 195, 242, 213, 115, 123, 1, + 251, 126, 250, 117, 123, 1, 197, 62, 251, 164, 123, 1, 197, 62, 240, 101, + 123, 1, 197, 62, 232, 147, 123, 1, 197, 62, 225, 35, 123, 1, 197, 62, + 222, 241, 123, 1, 197, 62, 48, 219, 171, 123, 1, 197, 62, 210, 109, 123, + 1, 197, 62, 203, 85, 123, 1, 251, 126, 98, 55, 123, 1, 206, 212, 3, 206, + 212, 238, 253, 123, 1, 206, 212, 3, 206, 66, 238, 253, 123, 1, 206, 212, + 3, 240, 121, 26, 206, 212, 238, 253, 123, 1, 206, 212, 3, 240, 121, 26, + 206, 66, 238, 253, 123, 1, 151, 3, 213, 115, 123, 1, 151, 3, 211, 147, + 123, 1, 151, 3, 220, 42, 123, 1, 248, 209, 3, 240, 120, 123, 1, 233, 178, + 3, 240, 120, 123, 1, 240, 102, 3, 240, 120, 123, 1, 232, 148, 3, 220, 42, + 123, 1, 199, 123, 3, 240, 120, 123, 1, 195, 93, 3, 240, 120, 123, 1, 203, + 2, 3, 240, 120, 123, 1, 195, 242, 3, 240, 120, 123, 1, 48, 225, 36, 3, + 240, 120, 123, 1, 225, 36, 3, 240, 120, 123, 1, 222, 242, 3, 240, 120, + 123, 1, 219, 172, 3, 240, 120, 123, 1, 215, 139, 3, 240, 120, 123, 1, + 208, 226, 3, 240, 120, 123, 1, 48, 213, 93, 3, 240, 120, 123, 1, 213, 93, + 3, 240, 120, 123, 1, 201, 109, 3, 240, 120, 123, 1, 211, 107, 3, 240, + 120, 123, 1, 210, 110, 3, 240, 120, 123, 1, 206, 212, 3, 240, 120, 123, + 1, 203, 86, 3, 240, 120, 123, 1, 199, 123, 3, 231, 177, 123, 1, 248, 209, + 3, 210, 227, 123, 1, 225, 36, 3, 210, 227, 123, 1, 213, 93, 3, 210, 227, + 123, 33, 151, 222, 241, 9, 1, 151, 197, 135, 70, 20, 9, 1, 151, 197, 135, + 48, 20, 9, 1, 248, 250, 70, 20, 9, 1, 248, 250, 48, 20, 9, 1, 248, 250, + 84, 20, 9, 1, 248, 250, 219, 194, 20, 9, 1, 213, 73, 70, 20, 9, 1, 213, + 73, 48, 20, 9, 1, 213, 73, 84, 20, 9, 1, 213, 73, 219, 194, 20, 9, 1, + 248, 238, 70, 20, 9, 1, 248, 238, 48, 20, 9, 1, 248, 238, 84, 20, 9, 1, + 248, 238, 219, 194, 20, 9, 1, 201, 69, 70, 20, 9, 1, 201, 69, 48, 20, 9, + 1, 201, 69, 84, 20, 9, 1, 201, 69, 219, 194, 20, 9, 1, 203, 40, 70, 20, + 9, 1, 203, 40, 48, 20, 9, 1, 203, 40, 84, 20, 9, 1, 203, 40, 219, 194, + 20, 9, 1, 201, 71, 70, 20, 9, 1, 201, 71, 48, 20, 9, 1, 201, 71, 84, 20, + 9, 1, 201, 71, 219, 194, 20, 9, 1, 199, 112, 70, 20, 9, 1, 199, 112, 48, + 20, 9, 1, 199, 112, 84, 20, 9, 1, 199, 112, 219, 194, 20, 9, 1, 213, 71, + 70, 20, 9, 1, 213, 71, 48, 20, 9, 1, 213, 71, 84, 20, 9, 1, 213, 71, 219, + 194, 20, 9, 1, 237, 163, 70, 20, 9, 1, 237, 163, 48, 20, 9, 1, 237, 163, + 84, 20, 9, 1, 237, 163, 219, 194, 20, 9, 1, 215, 96, 70, 20, 9, 1, 215, + 96, 48, 20, 9, 1, 215, 96, 84, 20, 9, 1, 215, 96, 219, 194, 20, 9, 1, + 203, 73, 70, 20, 9, 1, 203, 73, 48, 20, 9, 1, 203, 73, 84, 20, 9, 1, 203, + 73, 219, 194, 20, 9, 1, 203, 71, 70, 20, 9, 1, 203, 71, 48, 20, 9, 1, + 203, 71, 84, 20, 9, 1, 203, 71, 219, 194, 20, 9, 1, 240, 39, 70, 20, 9, + 1, 240, 39, 48, 20, 9, 1, 240, 115, 70, 20, 9, 1, 240, 115, 48, 20, 9, 1, + 237, 192, 70, 20, 9, 1, 237, 192, 48, 20, 9, 1, 240, 37, 70, 20, 9, 1, + 240, 37, 48, 20, 9, 1, 225, 187, 70, 20, 9, 1, 225, 187, 48, 20, 9, 1, + 209, 174, 70, 20, 9, 1, 209, 174, 48, 20, 9, 1, 224, 192, 70, 20, 9, 1, + 224, 192, 48, 20, 9, 1, 224, 192, 84, 20, 9, 1, 224, 192, 219, 194, 20, + 9, 1, 234, 111, 70, 20, 9, 1, 234, 111, 48, 20, 9, 1, 234, 111, 84, 20, + 9, 1, 234, 111, 219, 194, 20, 9, 1, 233, 64, 70, 20, 9, 1, 233, 64, 48, + 20, 9, 1, 233, 64, 84, 20, 9, 1, 233, 64, 219, 194, 20, 9, 1, 216, 251, + 70, 20, 9, 1, 216, 251, 48, 20, 9, 1, 216, 251, 84, 20, 9, 1, 216, 251, + 219, 194, 20, 9, 1, 216, 32, 233, 197, 70, 20, 9, 1, 216, 32, 233, 197, + 48, 20, 9, 1, 209, 236, 70, 20, 9, 1, 209, 236, 48, 20, 9, 1, 209, 236, + 84, 20, 9, 1, 209, 236, 219, 194, 20, 9, 1, 232, 114, 3, 93, 90, 70, 20, + 9, 1, 232, 114, 3, 93, 90, 48, 20, 9, 1, 232, 114, 233, 142, 70, 20, 9, + 1, 232, 114, 233, 142, 48, 20, 9, 1, 232, 114, 233, 142, 84, 20, 9, 1, + 232, 114, 233, 142, 219, 194, 20, 9, 1, 232, 114, 239, 25, 70, 20, 9, 1, + 232, 114, 239, 25, 48, 20, 9, 1, 232, 114, 239, 25, 84, 20, 9, 1, 232, + 114, 239, 25, 219, 194, 20, 9, 1, 93, 249, 73, 70, 20, 9, 1, 93, 249, 73, + 48, 20, 9, 1, 93, 249, 73, 3, 232, 214, 90, 70, 20, 9, 1, 93, 249, 73, 3, + 232, 214, 90, 48, 20, 9, 16, 76, 57, 9, 16, 76, 60, 9, 16, 99, 238, 251, + 57, 9, 16, 99, 238, 251, 60, 9, 16, 115, 238, 251, 57, 9, 16, 115, 238, + 251, 60, 9, 16, 115, 238, 251, 212, 107, 237, 231, 57, 9, 16, 115, 238, + 251, 212, 107, 237, 231, 60, 9, 16, 235, 7, 238, 251, 57, 9, 16, 235, 7, + 238, 251, 60, 9, 16, 52, 83, 249, 80, 60, 9, 16, 99, 238, 251, 199, 50, + 57, 9, 16, 99, 238, 251, 199, 50, 60, 9, 16, 210, 2, 9, 16, 4, 203, 140, + 57, 9, 16, 4, 203, 140, 60, 9, 1, 217, 74, 70, 20, 9, 1, 217, 74, 48, 20, + 9, 1, 217, 74, 84, 20, 9, 1, 217, 74, 219, 194, 20, 9, 1, 118, 70, 20, 9, + 1, 118, 48, 20, 9, 1, 214, 165, 70, 20, 9, 1, 214, 165, 48, 20, 9, 1, + 195, 218, 70, 20, 9, 1, 195, 218, 48, 20, 9, 1, 118, 3, 232, 214, 90, 70, + 20, 9, 1, 199, 119, 70, 20, 9, 1, 199, 119, 48, 20, 9, 1, 224, 67, 214, + 165, 70, 20, 9, 1, 224, 67, 214, 165, 48, 20, 9, 1, 224, 67, 195, 218, + 70, 20, 9, 1, 224, 67, 195, 218, 48, 20, 9, 1, 237, 136, 70, 20, 9, 1, + 237, 136, 48, 20, 9, 1, 237, 136, 84, 20, 9, 1, 237, 136, 219, 194, 20, + 9, 1, 200, 89, 224, 213, 224, 67, 151, 220, 70, 84, 20, 9, 1, 200, 89, + 224, 213, 224, 67, 151, 220, 70, 219, 194, 20, 9, 33, 93, 3, 232, 214, + 90, 3, 151, 70, 20, 9, 33, 93, 3, 232, 214, 90, 3, 151, 48, 20, 9, 33, + 93, 3, 232, 214, 90, 3, 251, 246, 70, 20, 9, 33, 93, 3, 232, 214, 90, 3, + 251, 246, 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, 197, 118, 70, 20, 9, 33, + 93, 3, 232, 214, 90, 3, 197, 118, 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, + 118, 70, 20, 9, 33, 93, 3, 232, 214, 90, 3, 118, 48, 20, 9, 33, 93, 3, + 232, 214, 90, 3, 214, 165, 70, 20, 9, 33, 93, 3, 232, 214, 90, 3, 214, + 165, 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, 195, 218, 70, 20, 9, 33, 93, + 3, 232, 214, 90, 3, 195, 218, 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, 237, + 136, 70, 20, 9, 33, 93, 3, 232, 214, 90, 3, 237, 136, 48, 20, 9, 33, 93, + 3, 232, 214, 90, 3, 237, 136, 84, 20, 9, 33, 200, 89, 224, 67, 93, 3, + 232, 214, 90, 3, 151, 220, 70, 70, 20, 9, 33, 200, 89, 224, 67, 93, 3, + 232, 214, 90, 3, 151, 220, 70, 48, 20, 9, 33, 200, 89, 224, 67, 93, 3, + 232, 214, 90, 3, 151, 220, 70, 84, 20, 9, 1, 235, 204, 93, 70, 20, 9, 1, + 235, 204, 93, 48, 20, 9, 1, 235, 204, 93, 84, 20, 9, 1, 235, 204, 93, + 219, 194, 20, 9, 33, 93, 3, 232, 214, 90, 3, 225, 190, 70, 20, 9, 33, 93, + 3, 232, 214, 90, 3, 168, 70, 20, 9, 33, 93, 3, 232, 214, 90, 3, 87, 70, + 20, 9, 33, 93, 3, 232, 214, 90, 3, 151, 220, 70, 70, 20, 9, 33, 93, 3, + 232, 214, 90, 3, 93, 70, 20, 9, 33, 248, 240, 3, 225, 190, 70, 20, 9, 33, + 248, 240, 3, 168, 70, 20, 9, 33, 248, 240, 3, 224, 143, 70, 20, 9, 33, + 248, 240, 3, 87, 70, 20, 9, 33, 248, 240, 3, 151, 220, 70, 70, 20, 9, 33, + 248, 240, 3, 93, 70, 20, 9, 33, 203, 42, 3, 225, 190, 70, 20, 9, 33, 203, + 42, 3, 168, 70, 20, 9, 33, 203, 42, 3, 224, 143, 70, 20, 9, 33, 203, 42, + 3, 87, 70, 20, 9, 33, 203, 42, 3, 151, 220, 70, 70, 20, 9, 33, 203, 42, + 3, 93, 70, 20, 9, 33, 202, 214, 3, 225, 190, 70, 20, 9, 33, 202, 214, 3, + 87, 70, 20, 9, 33, 202, 214, 3, 151, 220, 70, 70, 20, 9, 33, 202, 214, 3, + 93, 70, 20, 9, 33, 225, 190, 3, 168, 70, 20, 9, 33, 225, 190, 3, 87, 70, + 20, 9, 33, 168, 3, 225, 190, 70, 20, 9, 33, 168, 3, 87, 70, 20, 9, 33, + 224, 143, 3, 225, 190, 70, 20, 9, 33, 224, 143, 3, 168, 70, 20, 9, 33, + 224, 143, 3, 87, 70, 20, 9, 33, 208, 126, 3, 225, 190, 70, 20, 9, 33, + 208, 126, 3, 168, 70, 20, 9, 33, 208, 126, 3, 224, 143, 70, 20, 9, 33, + 208, 126, 3, 87, 70, 20, 9, 33, 209, 9, 3, 168, 70, 20, 9, 33, 209, 9, 3, + 87, 70, 20, 9, 33, 240, 131, 3, 225, 190, 70, 20, 9, 33, 240, 131, 3, + 168, 70, 20, 9, 33, 240, 131, 3, 224, 143, 70, 20, 9, 33, 240, 131, 3, + 87, 70, 20, 9, 33, 203, 140, 3, 168, 70, 20, 9, 33, 203, 140, 3, 87, 70, + 20, 9, 33, 195, 110, 3, 87, 70, 20, 9, 33, 251, 195, 3, 225, 190, 70, 20, + 9, 33, 251, 195, 3, 87, 70, 20, 9, 33, 233, 226, 3, 225, 190, 70, 20, 9, + 33, 233, 226, 3, 87, 70, 20, 9, 33, 235, 177, 3, 225, 190, 70, 20, 9, 33, + 235, 177, 3, 168, 70, 20, 9, 33, 235, 177, 3, 224, 143, 70, 20, 9, 33, + 235, 177, 3, 87, 70, 20, 9, 33, 235, 177, 3, 151, 220, 70, 70, 20, 9, 33, + 235, 177, 3, 93, 70, 20, 9, 33, 211, 153, 3, 168, 70, 20, 9, 33, 211, + 153, 3, 87, 70, 20, 9, 33, 211, 153, 3, 151, 220, 70, 70, 20, 9, 33, 211, + 153, 3, 93, 70, 20, 9, 33, 225, 36, 3, 151, 70, 20, 9, 33, 225, 36, 3, + 225, 190, 70, 20, 9, 33, 225, 36, 3, 168, 70, 20, 9, 33, 225, 36, 3, 224, + 143, 70, 20, 9, 33, 225, 36, 3, 222, 250, 70, 20, 9, 33, 225, 36, 3, 87, + 70, 20, 9, 33, 225, 36, 3, 151, 220, 70, 70, 20, 9, 33, 225, 36, 3, 93, + 70, 20, 9, 33, 222, 250, 3, 225, 190, 70, 20, 9, 33, 222, 250, 3, 168, + 70, 20, 9, 33, 222, 250, 3, 224, 143, 70, 20, 9, 33, 222, 250, 3, 87, 70, + 20, 9, 33, 222, 250, 3, 151, 220, 70, 70, 20, 9, 33, 222, 250, 3, 93, 70, + 20, 9, 33, 87, 3, 225, 190, 70, 20, 9, 33, 87, 3, 168, 70, 20, 9, 33, 87, + 3, 224, 143, 70, 20, 9, 33, 87, 3, 87, 70, 20, 9, 33, 87, 3, 151, 220, + 70, 70, 20, 9, 33, 87, 3, 93, 70, 20, 9, 33, 216, 32, 3, 225, 190, 70, + 20, 9, 33, 216, 32, 3, 168, 70, 20, 9, 33, 216, 32, 3, 224, 143, 70, 20, + 9, 33, 216, 32, 3, 87, 70, 20, 9, 33, 216, 32, 3, 151, 220, 70, 70, 20, + 9, 33, 216, 32, 3, 93, 70, 20, 9, 33, 232, 114, 3, 225, 190, 70, 20, 9, + 33, 232, 114, 3, 87, 70, 20, 9, 33, 232, 114, 3, 151, 220, 70, 70, 20, 9, + 33, 232, 114, 3, 93, 70, 20, 9, 33, 93, 3, 225, 190, 70, 20, 9, 33, 93, + 3, 168, 70, 20, 9, 33, 93, 3, 224, 143, 70, 20, 9, 33, 93, 3, 87, 70, 20, + 9, 33, 93, 3, 151, 220, 70, 70, 20, 9, 33, 93, 3, 93, 70, 20, 9, 33, 202, + 226, 3, 204, 95, 151, 70, 20, 9, 33, 210, 143, 3, 204, 95, 151, 70, 20, + 9, 33, 151, 220, 70, 3, 204, 95, 151, 70, 20, 9, 33, 207, 41, 3, 240, 94, + 70, 20, 9, 33, 207, 41, 3, 224, 237, 70, 20, 9, 33, 207, 41, 3, 235, 201, + 70, 20, 9, 33, 207, 41, 3, 240, 96, 70, 20, 9, 33, 207, 41, 3, 224, 239, + 70, 20, 9, 33, 207, 41, 3, 204, 95, 151, 70, 20, 9, 33, 93, 3, 232, 214, + 90, 3, 210, 143, 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, 195, 107, 48, 20, + 9, 33, 93, 3, 232, 214, 90, 3, 87, 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, + 216, 32, 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, 151, 220, 70, 48, 20, 9, + 33, 93, 3, 232, 214, 90, 3, 93, 48, 20, 9, 33, 248, 240, 3, 210, 143, 48, + 20, 9, 33, 248, 240, 3, 195, 107, 48, 20, 9, 33, 248, 240, 3, 87, 48, 20, + 9, 33, 248, 240, 3, 216, 32, 48, 20, 9, 33, 248, 240, 3, 151, 220, 70, + 48, 20, 9, 33, 248, 240, 3, 93, 48, 20, 9, 33, 203, 42, 3, 210, 143, 48, + 20, 9, 33, 203, 42, 3, 195, 107, 48, 20, 9, 33, 203, 42, 3, 87, 48, 20, + 9, 33, 203, 42, 3, 216, 32, 48, 20, 9, 33, 203, 42, 3, 151, 220, 70, 48, + 20, 9, 33, 203, 42, 3, 93, 48, 20, 9, 33, 202, 214, 3, 210, 143, 48, 20, + 9, 33, 202, 214, 3, 195, 107, 48, 20, 9, 33, 202, 214, 3, 87, 48, 20, 9, + 33, 202, 214, 3, 216, 32, 48, 20, 9, 33, 202, 214, 3, 151, 220, 70, 48, + 20, 9, 33, 202, 214, 3, 93, 48, 20, 9, 33, 235, 177, 3, 151, 220, 70, 48, + 20, 9, 33, 235, 177, 3, 93, 48, 20, 9, 33, 211, 153, 3, 151, 220, 70, 48, + 20, 9, 33, 211, 153, 3, 93, 48, 20, 9, 33, 225, 36, 3, 151, 48, 20, 9, + 33, 225, 36, 3, 222, 250, 48, 20, 9, 33, 225, 36, 3, 87, 48, 20, 9, 33, + 225, 36, 3, 151, 220, 70, 48, 20, 9, 33, 225, 36, 3, 93, 48, 20, 9, 33, + 222, 250, 3, 87, 48, 20, 9, 33, 222, 250, 3, 151, 220, 70, 48, 20, 9, 33, + 222, 250, 3, 93, 48, 20, 9, 33, 87, 3, 151, 48, 20, 9, 33, 87, 3, 87, 48, + 20, 9, 33, 216, 32, 3, 210, 143, 48, 20, 9, 33, 216, 32, 3, 195, 107, 48, + 20, 9, 33, 216, 32, 3, 87, 48, 20, 9, 33, 216, 32, 3, 216, 32, 48, 20, 9, + 33, 216, 32, 3, 151, 220, 70, 48, 20, 9, 33, 216, 32, 3, 93, 48, 20, 9, + 33, 151, 220, 70, 3, 204, 95, 151, 48, 20, 9, 33, 93, 3, 210, 143, 48, + 20, 9, 33, 93, 3, 195, 107, 48, 20, 9, 33, 93, 3, 87, 48, 20, 9, 33, 93, + 3, 216, 32, 48, 20, 9, 33, 93, 3, 151, 220, 70, 48, 20, 9, 33, 93, 3, 93, + 48, 20, 9, 33, 93, 3, 232, 214, 90, 3, 225, 190, 84, 20, 9, 33, 93, 3, + 232, 214, 90, 3, 168, 84, 20, 9, 33, 93, 3, 232, 214, 90, 3, 224, 143, + 84, 20, 9, 33, 93, 3, 232, 214, 90, 3, 87, 84, 20, 9, 33, 93, 3, 232, + 214, 90, 3, 232, 114, 84, 20, 9, 33, 248, 240, 3, 225, 190, 84, 20, 9, + 33, 248, 240, 3, 168, 84, 20, 9, 33, 248, 240, 3, 224, 143, 84, 20, 9, + 33, 248, 240, 3, 87, 84, 20, 9, 33, 248, 240, 3, 232, 114, 84, 20, 9, 33, + 203, 42, 3, 225, 190, 84, 20, 9, 33, 203, 42, 3, 168, 84, 20, 9, 33, 203, + 42, 3, 224, 143, 84, 20, 9, 33, 203, 42, 3, 87, 84, 20, 9, 33, 203, 42, + 3, 232, 114, 84, 20, 9, 33, 202, 214, 3, 87, 84, 20, 9, 33, 225, 190, 3, + 168, 84, 20, 9, 33, 225, 190, 3, 87, 84, 20, 9, 33, 168, 3, 225, 190, 84, + 20, 9, 33, 168, 3, 87, 84, 20, 9, 33, 224, 143, 3, 225, 190, 84, 20, 9, + 33, 224, 143, 3, 87, 84, 20, 9, 33, 208, 126, 3, 225, 190, 84, 20, 9, 33, + 208, 126, 3, 168, 84, 20, 9, 33, 208, 126, 3, 224, 143, 84, 20, 9, 33, + 208, 126, 3, 87, 84, 20, 9, 33, 209, 9, 3, 168, 84, 20, 9, 33, 209, 9, 3, + 224, 143, 84, 20, 9, 33, 209, 9, 3, 87, 84, 20, 9, 33, 240, 131, 3, 225, + 190, 84, 20, 9, 33, 240, 131, 3, 168, 84, 20, 9, 33, 240, 131, 3, 224, + 143, 84, 20, 9, 33, 240, 131, 3, 87, 84, 20, 9, 33, 203, 140, 3, 168, 84, + 20, 9, 33, 195, 110, 3, 87, 84, 20, 9, 33, 251, 195, 3, 225, 190, 84, 20, + 9, 33, 251, 195, 3, 87, 84, 20, 9, 33, 233, 226, 3, 225, 190, 84, 20, 9, + 33, 233, 226, 3, 87, 84, 20, 9, 33, 235, 177, 3, 225, 190, 84, 20, 9, 33, + 235, 177, 3, 168, 84, 20, 9, 33, 235, 177, 3, 224, 143, 84, 20, 9, 33, + 235, 177, 3, 87, 84, 20, 9, 33, 211, 153, 3, 168, 84, 20, 9, 33, 211, + 153, 3, 87, 84, 20, 9, 33, 225, 36, 3, 225, 190, 84, 20, 9, 33, 225, 36, + 3, 168, 84, 20, 9, 33, 225, 36, 3, 224, 143, 84, 20, 9, 33, 225, 36, 3, + 222, 250, 84, 20, 9, 33, 225, 36, 3, 87, 84, 20, 9, 33, 222, 250, 3, 225, + 190, 84, 20, 9, 33, 222, 250, 3, 168, 84, 20, 9, 33, 222, 250, 3, 224, + 143, 84, 20, 9, 33, 222, 250, 3, 87, 84, 20, 9, 33, 222, 250, 3, 232, + 114, 84, 20, 9, 33, 87, 3, 225, 190, 84, 20, 9, 33, 87, 3, 168, 84, 20, + 9, 33, 87, 3, 224, 143, 84, 20, 9, 33, 87, 3, 87, 84, 20, 9, 33, 216, 32, + 3, 225, 190, 84, 20, 9, 33, 216, 32, 3, 168, 84, 20, 9, 33, 216, 32, 3, + 224, 143, 84, 20, 9, 33, 216, 32, 3, 87, 84, 20, 9, 33, 216, 32, 3, 232, + 114, 84, 20, 9, 33, 232, 114, 3, 225, 190, 84, 20, 9, 33, 232, 114, 3, + 87, 84, 20, 9, 33, 232, 114, 3, 204, 95, 151, 84, 20, 9, 33, 93, 3, 225, + 190, 84, 20, 9, 33, 93, 3, 168, 84, 20, 9, 33, 93, 3, 224, 143, 84, 20, + 9, 33, 93, 3, 87, 84, 20, 9, 33, 93, 3, 232, 114, 84, 20, 9, 33, 93, 3, + 232, 214, 90, 3, 87, 219, 194, 20, 9, 33, 93, 3, 232, 214, 90, 3, 232, + 114, 219, 194, 20, 9, 33, 248, 240, 3, 87, 219, 194, 20, 9, 33, 248, 240, + 3, 232, 114, 219, 194, 20, 9, 33, 203, 42, 3, 87, 219, 194, 20, 9, 33, + 203, 42, 3, 232, 114, 219, 194, 20, 9, 33, 202, 214, 3, 87, 219, 194, 20, + 9, 33, 202, 214, 3, 232, 114, 219, 194, 20, 9, 33, 208, 126, 3, 87, 219, + 194, 20, 9, 33, 208, 126, 3, 232, 114, 219, 194, 20, 9, 33, 206, 252, 3, + 87, 219, 194, 20, 9, 33, 206, 252, 3, 232, 114, 219, 194, 20, 9, 33, 225, + 36, 3, 222, 250, 219, 194, 20, 9, 33, 225, 36, 3, 87, 219, 194, 20, 9, + 33, 222, 250, 3, 87, 219, 194, 20, 9, 33, 216, 32, 3, 87, 219, 194, 20, + 9, 33, 216, 32, 3, 232, 114, 219, 194, 20, 9, 33, 93, 3, 87, 219, 194, + 20, 9, 33, 93, 3, 232, 114, 219, 194, 20, 9, 33, 207, 41, 3, 235, 201, + 219, 194, 20, 9, 33, 207, 41, 3, 240, 96, 219, 194, 20, 9, 33, 207, 41, + 3, 224, 239, 219, 194, 20, 9, 33, 203, 140, 3, 151, 220, 70, 70, 20, 9, + 33, 203, 140, 3, 93, 70, 20, 9, 33, 251, 195, 3, 151, 220, 70, 70, 20, 9, + 33, 251, 195, 3, 93, 70, 20, 9, 33, 233, 226, 3, 151, 220, 70, 70, 20, 9, + 33, 233, 226, 3, 93, 70, 20, 9, 33, 208, 126, 3, 151, 220, 70, 70, 20, 9, + 33, 208, 126, 3, 93, 70, 20, 9, 33, 206, 252, 3, 151, 220, 70, 70, 20, 9, + 33, 206, 252, 3, 93, 70, 20, 9, 33, 168, 3, 151, 220, 70, 70, 20, 9, 33, + 168, 3, 93, 70, 20, 9, 33, 225, 190, 3, 151, 220, 70, 70, 20, 9, 33, 225, + 190, 3, 93, 70, 20, 9, 33, 224, 143, 3, 151, 220, 70, 70, 20, 9, 33, 224, + 143, 3, 93, 70, 20, 9, 33, 209, 9, 3, 151, 220, 70, 70, 20, 9, 33, 209, + 9, 3, 93, 70, 20, 9, 33, 240, 131, 3, 151, 220, 70, 70, 20, 9, 33, 240, + 131, 3, 93, 70, 20, 9, 33, 206, 252, 3, 225, 190, 70, 20, 9, 33, 206, + 252, 3, 168, 70, 20, 9, 33, 206, 252, 3, 224, 143, 70, 20, 9, 33, 206, + 252, 3, 87, 70, 20, 9, 33, 206, 252, 3, 210, 143, 70, 20, 9, 33, 208, + 126, 3, 210, 143, 70, 20, 9, 33, 209, 9, 3, 210, 143, 70, 20, 9, 33, 240, + 131, 3, 210, 143, 70, 20, 9, 33, 203, 140, 3, 151, 220, 70, 48, 20, 9, + 33, 203, 140, 3, 93, 48, 20, 9, 33, 251, 195, 3, 151, 220, 70, 48, 20, 9, + 33, 251, 195, 3, 93, 48, 20, 9, 33, 233, 226, 3, 151, 220, 70, 48, 20, 9, + 33, 233, 226, 3, 93, 48, 20, 9, 33, 208, 126, 3, 151, 220, 70, 48, 20, 9, + 33, 208, 126, 3, 93, 48, 20, 9, 33, 206, 252, 3, 151, 220, 70, 48, 20, 9, + 33, 206, 252, 3, 93, 48, 20, 9, 33, 168, 3, 151, 220, 70, 48, 20, 9, 33, + 168, 3, 93, 48, 20, 9, 33, 225, 190, 3, 151, 220, 70, 48, 20, 9, 33, 225, + 190, 3, 93, 48, 20, 9, 33, 224, 143, 3, 151, 220, 70, 48, 20, 9, 33, 224, + 143, 3, 93, 48, 20, 9, 33, 209, 9, 3, 151, 220, 70, 48, 20, 9, 33, 209, + 9, 3, 93, 48, 20, 9, 33, 240, 131, 3, 151, 220, 70, 48, 20, 9, 33, 240, + 131, 3, 93, 48, 20, 9, 33, 206, 252, 3, 225, 190, 48, 20, 9, 33, 206, + 252, 3, 168, 48, 20, 9, 33, 206, 252, 3, 224, 143, 48, 20, 9, 33, 206, + 252, 3, 87, 48, 20, 9, 33, 206, 252, 3, 210, 143, 48, 20, 9, 33, 208, + 126, 3, 210, 143, 48, 20, 9, 33, 209, 9, 3, 210, 143, 48, 20, 9, 33, 240, + 131, 3, 210, 143, 48, 20, 9, 33, 206, 252, 3, 225, 190, 84, 20, 9, 33, + 206, 252, 3, 168, 84, 20, 9, 33, 206, 252, 3, 224, 143, 84, 20, 9, 33, + 206, 252, 3, 87, 84, 20, 9, 33, 208, 126, 3, 232, 114, 84, 20, 9, 33, + 206, 252, 3, 232, 114, 84, 20, 9, 33, 203, 140, 3, 87, 84, 20, 9, 33, + 208, 126, 3, 225, 190, 219, 194, 20, 9, 33, 208, 126, 3, 168, 219, 194, + 20, 9, 33, 208, 126, 3, 224, 143, 219, 194, 20, 9, 33, 206, 252, 3, 225, + 190, 219, 194, 20, 9, 33, 206, 252, 3, 168, 219, 194, 20, 9, 33, 206, + 252, 3, 224, 143, 219, 194, 20, 9, 33, 203, 140, 3, 87, 219, 194, 20, 9, + 33, 195, 110, 3, 87, 219, 194, 20, 9, 33, 151, 3, 235, 199, 48, 20, 9, + 33, 151, 3, 235, 199, 70, 20, 214, 57, 50, 213, 140, 214, 57, 53, 213, + 140, 9, 33, 203, 42, 3, 225, 190, 3, 87, 84, 20, 9, 33, 203, 42, 3, 168, + 3, 225, 190, 48, 20, 9, 33, 203, 42, 3, 168, 3, 225, 190, 84, 20, 9, 33, + 203, 42, 3, 168, 3, 87, 84, 20, 9, 33, 203, 42, 3, 224, 143, 3, 87, 84, + 20, 9, 33, 203, 42, 3, 87, 3, 225, 190, 84, 20, 9, 33, 203, 42, 3, 87, 3, + 168, 84, 20, 9, 33, 203, 42, 3, 87, 3, 224, 143, 84, 20, 9, 33, 225, 190, + 3, 87, 3, 168, 48, 20, 9, 33, 225, 190, 3, 87, 3, 168, 84, 20, 9, 33, + 168, 3, 87, 3, 93, 48, 20, 9, 33, 168, 3, 87, 3, 151, 220, 70, 48, 20, 9, + 33, 208, 126, 3, 168, 3, 225, 190, 84, 20, 9, 33, 208, 126, 3, 225, 190, + 3, 168, 84, 20, 9, 33, 208, 126, 3, 225, 190, 3, 151, 220, 70, 48, 20, 9, + 33, 208, 126, 3, 87, 3, 168, 48, 20, 9, 33, 208, 126, 3, 87, 3, 168, 84, + 20, 9, 33, 208, 126, 3, 87, 3, 225, 190, 84, 20, 9, 33, 208, 126, 3, 87, + 3, 87, 48, 20, 9, 33, 208, 126, 3, 87, 3, 87, 84, 20, 9, 33, 209, 9, 3, + 168, 3, 168, 48, 20, 9, 33, 209, 9, 3, 168, 3, 168, 84, 20, 9, 33, 209, + 9, 3, 87, 3, 87, 48, 20, 9, 33, 206, 252, 3, 168, 3, 87, 48, 20, 9, 33, + 206, 252, 3, 168, 3, 87, 84, 20, 9, 33, 206, 252, 3, 225, 190, 3, 93, 48, + 20, 9, 33, 206, 252, 3, 87, 3, 224, 143, 48, 20, 9, 33, 206, 252, 3, 87, + 3, 224, 143, 84, 20, 9, 33, 206, 252, 3, 87, 3, 87, 48, 20, 9, 33, 206, + 252, 3, 87, 3, 87, 84, 20, 9, 33, 240, 131, 3, 168, 3, 151, 220, 70, 48, + 20, 9, 33, 240, 131, 3, 224, 143, 3, 87, 48, 20, 9, 33, 240, 131, 3, 224, + 143, 3, 87, 84, 20, 9, 33, 203, 140, 3, 87, 3, 168, 48, 20, 9, 33, 203, + 140, 3, 87, 3, 168, 84, 20, 9, 33, 203, 140, 3, 87, 3, 87, 84, 20, 9, 33, + 203, 140, 3, 87, 3, 93, 48, 20, 9, 33, 251, 195, 3, 225, 190, 3, 87, 48, + 20, 9, 33, 251, 195, 3, 87, 3, 87, 48, 20, 9, 33, 251, 195, 3, 87, 3, 87, + 84, 20, 9, 33, 251, 195, 3, 87, 3, 151, 220, 70, 48, 20, 9, 33, 233, 226, + 3, 87, 3, 87, 48, 20, 9, 33, 233, 226, 3, 87, 3, 93, 48, 20, 9, 33, 233, + 226, 3, 87, 3, 151, 220, 70, 48, 20, 9, 33, 235, 177, 3, 224, 143, 3, 87, + 48, 20, 9, 33, 235, 177, 3, 224, 143, 3, 87, 84, 20, 9, 33, 211, 153, 3, + 87, 3, 168, 48, 20, 9, 33, 211, 153, 3, 87, 3, 87, 48, 20, 9, 33, 222, + 250, 3, 168, 3, 87, 48, 20, 9, 33, 222, 250, 3, 168, 3, 93, 48, 20, 9, + 33, 222, 250, 3, 168, 3, 151, 220, 70, 48, 20, 9, 33, 222, 250, 3, 225, + 190, 3, 225, 190, 84, 20, 9, 33, 222, 250, 3, 225, 190, 3, 225, 190, 48, + 20, 9, 33, 222, 250, 3, 224, 143, 3, 87, 48, 20, 9, 33, 222, 250, 3, 224, + 143, 3, 87, 84, 20, 9, 33, 222, 250, 3, 87, 3, 168, 48, 20, 9, 33, 222, + 250, 3, 87, 3, 168, 84, 20, 9, 33, 87, 3, 168, 3, 225, 190, 84, 20, 9, + 33, 87, 3, 168, 3, 87, 84, 20, 9, 33, 87, 3, 168, 3, 93, 48, 20, 9, 33, + 87, 3, 225, 190, 3, 168, 84, 20, 9, 33, 87, 3, 225, 190, 3, 87, 84, 20, + 9, 33, 87, 3, 224, 143, 3, 225, 190, 84, 20, 9, 33, 87, 3, 224, 143, 3, + 87, 84, 20, 9, 33, 87, 3, 225, 190, 3, 224, 143, 84, 20, 9, 33, 232, 114, + 3, 87, 3, 225, 190, 84, 20, 9, 33, 232, 114, 3, 87, 3, 87, 84, 20, 9, 33, + 216, 32, 3, 168, 3, 87, 84, 20, 9, 33, 216, 32, 3, 168, 3, 151, 220, 70, + 48, 20, 9, 33, 216, 32, 3, 225, 190, 3, 87, 48, 20, 9, 33, 216, 32, 3, + 225, 190, 3, 87, 84, 20, 9, 33, 216, 32, 3, 225, 190, 3, 151, 220, 70, + 48, 20, 9, 33, 216, 32, 3, 87, 3, 93, 48, 20, 9, 33, 216, 32, 3, 87, 3, + 151, 220, 70, 48, 20, 9, 33, 93, 3, 87, 3, 87, 48, 20, 9, 33, 93, 3, 87, + 3, 87, 84, 20, 9, 33, 248, 240, 3, 224, 143, 3, 93, 48, 20, 9, 33, 203, + 42, 3, 225, 190, 3, 93, 48, 20, 9, 33, 203, 42, 3, 225, 190, 3, 151, 220, + 70, 48, 20, 9, 33, 203, 42, 3, 224, 143, 3, 93, 48, 20, 9, 33, 203, 42, + 3, 224, 143, 3, 151, 220, 70, 48, 20, 9, 33, 203, 42, 3, 87, 3, 93, 48, + 20, 9, 33, 203, 42, 3, 87, 3, 151, 220, 70, 48, 20, 9, 33, 225, 190, 3, + 87, 3, 93, 48, 20, 9, 33, 225, 190, 3, 168, 3, 151, 220, 70, 48, 20, 9, + 33, 225, 190, 3, 87, 3, 151, 220, 70, 48, 20, 9, 33, 208, 126, 3, 224, + 143, 3, 151, 220, 70, 48, 20, 9, 33, 209, 9, 3, 168, 3, 93, 48, 20, 9, + 33, 206, 252, 3, 168, 3, 93, 48, 20, 9, 33, 240, 131, 3, 168, 3, 93, 48, + 20, 9, 33, 222, 250, 3, 225, 190, 3, 93, 48, 20, 9, 33, 222, 250, 3, 87, + 3, 93, 48, 20, 9, 33, 93, 3, 168, 3, 93, 48, 20, 9, 33, 93, 3, 225, 190, + 3, 93, 48, 20, 9, 33, 93, 3, 87, 3, 93, 48, 20, 9, 33, 87, 3, 87, 3, 93, + 48, 20, 9, 33, 211, 153, 3, 87, 3, 93, 48, 20, 9, 33, 216, 32, 3, 168, 3, + 93, 48, 20, 9, 33, 211, 153, 3, 87, 3, 168, 84, 20, 9, 33, 222, 250, 3, + 168, 3, 87, 84, 20, 9, 33, 251, 195, 3, 87, 3, 93, 48, 20, 9, 33, 225, + 36, 3, 87, 3, 93, 48, 20, 9, 33, 216, 32, 3, 225, 190, 3, 168, 84, 20, 9, + 33, 87, 3, 224, 143, 3, 93, 48, 20, 9, 33, 222, 250, 3, 225, 190, 3, 87, + 84, 20, 9, 33, 225, 36, 3, 87, 3, 87, 48, 20, 9, 33, 222, 250, 3, 225, + 190, 3, 87, 48, 20, 9, 33, 216, 32, 3, 225, 190, 3, 168, 48, 20, 9, 33, + 225, 190, 3, 168, 3, 93, 48, 20, 9, 33, 168, 3, 225, 190, 3, 93, 48, 20, + 9, 33, 87, 3, 225, 190, 3, 93, 48, 20, 9, 33, 235, 177, 3, 87, 3, 93, 48, + 20, 9, 33, 248, 240, 3, 168, 3, 93, 48, 20, 9, 33, 225, 36, 3, 87, 3, 87, + 84, 20, 9, 33, 251, 195, 3, 225, 190, 3, 87, 84, 20, 9, 33, 209, 9, 3, + 87, 3, 87, 84, 20, 9, 33, 208, 126, 3, 224, 143, 3, 93, 48, 20, 9, 33, + 216, 32, 3, 225, 190, 3, 93, 48, 20, 9, 33, 208, 236, 199, 255, 250, 203, + 223, 234, 204, 227, 2, 70, 20, 9, 33, 211, 149, 199, 255, 250, 203, 223, + 234, 204, 227, 2, 70, 20, 9, 33, 251, 145, 70, 20, 9, 33, 251, 178, 70, + 20, 9, 33, 218, 218, 70, 20, 9, 33, 208, 237, 70, 20, 9, 33, 210, 200, + 70, 20, 9, 33, 251, 167, 70, 20, 9, 33, 197, 137, 70, 20, 9, 33, 208, + 236, 70, 20, 9, 33, 208, 235, 251, 167, 197, 136, 9, 33, 225, 205, 210, + 64, 55, 9, 33, 248, 147, 251, 12, 251, 13, 62, 208, 113, 62, 208, 2, 62, + 207, 190, 62, 207, 179, 62, 207, 168, 62, 207, 157, 62, 207, 146, 62, + 207, 135, 62, 207, 124, 62, 208, 112, 62, 208, 101, 62, 208, 90, 62, 208, + 79, 62, 208, 68, 62, 208, 57, 62, 208, 46, 212, 25, 235, 24, 36, 83, 244, + 159, 212, 25, 235, 24, 36, 83, 143, 244, 159, 212, 25, 235, 24, 36, 83, + 143, 234, 217, 204, 226, 212, 25, 235, 24, 36, 83, 244, 168, 212, 25, + 235, 24, 36, 83, 207, 105, 212, 25, 235, 24, 36, 83, 236, 90, 78, 212, + 25, 235, 24, 36, 83, 211, 79, 78, 212, 25, 235, 24, 36, 83, 50, 59, 222, + 147, 179, 212, 25, 235, 24, 36, 83, 53, 59, 222, 147, 248, 59, 212, 25, + 235, 24, 36, 83, 231, 155, 236, 247, 38, 33, 50, 232, 225, 38, 33, 53, + 232, 225, 38, 52, 202, 85, 50, 232, 225, 38, 52, 202, 85, 53, 232, 225, + 38, 220, 115, 50, 232, 225, 38, 220, 115, 53, 232, 225, 38, 241, 143, + 220, 114, 38, 33, 50, 157, 60, 38, 33, 53, 157, 60, 38, 202, 85, 50, 157, + 60, 38, 202, 85, 53, 157, 60, 38, 220, 115, 50, 157, 60, 38, 220, 115, + 53, 157, 60, 38, 241, 143, 220, 115, 60, 38, 40, 202, 55, 50, 232, 225, + 38, 40, 202, 55, 53, 232, 225, 212, 25, 235, 24, 36, 83, 99, 76, 222, + 195, 212, 25, 235, 24, 36, 83, 236, 242, 240, 65, 212, 25, 235, 24, 36, + 83, 236, 231, 240, 65, 212, 25, 235, 24, 36, 83, 126, 222, 75, 212, 25, + 235, 24, 36, 83, 197, 119, 126, 222, 75, 212, 25, 235, 24, 36, 83, 50, + 213, 140, 212, 25, 235, 24, 36, 83, 53, 213, 140, 212, 25, 235, 24, 36, + 83, 50, 241, 18, 179, 212, 25, 235, 24, 36, 83, 53, 241, 18, 179, 212, + 25, 235, 24, 36, 83, 50, 201, 231, 206, 245, 179, 212, 25, 235, 24, 36, + 83, 53, 201, 231, 206, 245, 179, 212, 25, 235, 24, 36, 83, 50, 58, 222, + 147, 179, 212, 25, 235, 24, 36, 83, 53, 58, 222, 147, 179, 212, 25, 235, + 24, 36, 83, 50, 52, 251, 91, 179, 212, 25, 235, 24, 36, 83, 53, 52, 251, + 91, 179, 212, 25, 235, 24, 36, 83, 50, 251, 91, 179, 212, 25, 235, 24, + 36, 83, 53, 251, 91, 179, 212, 25, 235, 24, 36, 83, 50, 241, 102, 179, + 212, 25, 235, 24, 36, 83, 53, 241, 102, 179, 212, 25, 235, 24, 36, 83, + 50, 59, 241, 102, 179, 212, 25, 235, 24, 36, 83, 53, 59, 241, 102, 179, + 207, 80, 238, 253, 59, 207, 80, 238, 253, 212, 25, 235, 24, 36, 83, 50, + 47, 179, 212, 25, 235, 24, 36, 83, 53, 47, 179, 240, 64, 214, 19, 247, + 33, 214, 19, 197, 119, 214, 19, 52, 197, 119, 214, 19, 240, 64, 126, 222, + 75, 247, 33, 126, 222, 75, 197, 119, 126, 222, 75, 4, 244, 159, 4, 143, + 244, 159, 4, 234, 217, 204, 226, 4, 207, 105, 4, 244, 168, 4, 211, 79, + 78, 4, 236, 90, 78, 4, 236, 242, 240, 65, 4, 50, 213, 140, 4, 53, 213, + 140, 4, 50, 241, 18, 179, 4, 53, 241, 18, 179, 4, 50, 201, 231, 206, 245, + 179, 4, 53, 201, 231, 206, 245, 179, 4, 31, 55, 4, 251, 111, 4, 250, 179, + 4, 98, 55, 4, 231, 6, 4, 222, 140, 55, 4, 233, 94, 55, 4, 236, 172, 55, + 4, 210, 90, 205, 177, 4, 239, 10, 55, 4, 213, 45, 55, 4, 244, 157, 250, + 168, 9, 235, 199, 70, 20, 9, 203, 92, 3, 235, 199, 57, 9, 240, 94, 70, + 20, 9, 203, 136, 234, 253, 9, 224, 237, 70, 20, 9, 235, 201, 70, 20, 9, + 235, 201, 219, 194, 20, 9, 240, 96, 70, 20, 9, 240, 96, 219, 194, 20, 9, + 224, 239, 70, 20, 9, 224, 239, 219, 194, 20, 9, 207, 41, 70, 20, 9, 207, + 41, 219, 194, 20, 9, 204, 120, 70, 20, 9, 204, 120, 219, 194, 20, 9, 1, + 232, 214, 70, 20, 9, 1, 151, 3, 220, 110, 90, 70, 20, 9, 1, 151, 3, 220, + 110, 90, 48, 20, 9, 1, 151, 3, 232, 214, 90, 70, 20, 9, 1, 151, 3, 232, + 214, 90, 48, 20, 9, 1, 197, 118, 3, 232, 214, 90, 70, 20, 9, 1, 197, 118, + 3, 232, 214, 90, 48, 20, 9, 1, 151, 3, 232, 214, 248, 227, 70, 20, 9, 1, + 151, 3, 232, 214, 248, 227, 48, 20, 9, 1, 93, 3, 232, 214, 90, 70, 20, 9, + 1, 93, 3, 232, 214, 90, 48, 20, 9, 1, 93, 3, 232, 214, 90, 84, 20, 9, 1, + 93, 3, 232, 214, 90, 219, 194, 20, 9, 1, 151, 70, 20, 9, 1, 151, 48, 20, + 9, 1, 248, 240, 70, 20, 9, 1, 248, 240, 48, 20, 9, 1, 248, 240, 84, 20, + 9, 1, 248, 240, 219, 194, 20, 9, 1, 203, 42, 220, 36, 70, 20, 9, 1, 203, + 42, 220, 36, 48, 20, 9, 1, 203, 42, 70, 20, 9, 1, 203, 42, 48, 20, 9, 1, + 203, 42, 84, 20, 9, 1, 203, 42, 219, 194, 20, 9, 1, 202, 214, 70, 20, 9, + 1, 202, 214, 48, 20, 9, 1, 202, 214, 84, 20, 9, 1, 202, 214, 219, 194, + 20, 9, 1, 225, 190, 70, 20, 9, 1, 225, 190, 48, 20, 9, 1, 225, 190, 84, + 20, 9, 1, 225, 190, 219, 194, 20, 9, 1, 168, 70, 20, 9, 1, 168, 48, 20, + 9, 1, 168, 84, 20, 9, 1, 168, 219, 194, 20, 9, 1, 224, 143, 70, 20, 9, 1, + 224, 143, 48, 20, 9, 1, 224, 143, 84, 20, 9, 1, 224, 143, 219, 194, 20, + 9, 1, 240, 108, 70, 20, 9, 1, 240, 108, 48, 20, 9, 1, 202, 226, 70, 20, + 9, 1, 202, 226, 48, 20, 9, 1, 210, 143, 70, 20, 9, 1, 210, 143, 48, 20, + 9, 1, 195, 107, 70, 20, 9, 1, 195, 107, 48, 20, 9, 1, 208, 126, 70, 20, + 9, 1, 208, 126, 48, 20, 9, 1, 208, 126, 84, 20, 9, 1, 208, 126, 219, 194, + 20, 9, 1, 206, 252, 70, 20, 9, 1, 206, 252, 48, 20, 9, 1, 206, 252, 84, + 20, 9, 1, 206, 252, 219, 194, 20, 9, 1, 209, 9, 70, 20, 9, 1, 209, 9, 48, + 20, 9, 1, 209, 9, 84, 20, 9, 1, 209, 9, 219, 194, 20, 9, 1, 240, 131, 70, + 20, 9, 1, 240, 131, 48, 20, 9, 1, 240, 131, 84, 20, 9, 1, 240, 131, 219, + 194, 20, 9, 1, 203, 140, 70, 20, 9, 1, 203, 140, 48, 20, 9, 1, 203, 140, + 84, 20, 9, 1, 203, 140, 219, 194, 20, 9, 1, 195, 110, 70, 20, 9, 1, 195, + 110, 48, 20, 9, 1, 195, 110, 84, 20, 9, 1, 195, 110, 219, 194, 20, 9, 1, + 251, 195, 70, 20, 9, 1, 251, 195, 48, 20, 9, 1, 251, 195, 84, 20, 9, 1, + 251, 195, 219, 194, 20, 9, 1, 233, 226, 70, 20, 9, 1, 233, 226, 48, 20, + 9, 1, 233, 226, 84, 20, 9, 1, 233, 226, 219, 194, 20, 9, 1, 235, 177, 70, + 20, 9, 1, 235, 177, 48, 20, 9, 1, 235, 177, 84, 20, 9, 1, 235, 177, 219, + 194, 20, 9, 1, 211, 153, 70, 20, 9, 1, 211, 153, 48, 20, 9, 1, 211, 153, + 84, 20, 9, 1, 211, 153, 219, 194, 20, 9, 1, 225, 36, 70, 20, 9, 1, 225, + 36, 48, 20, 9, 1, 225, 36, 84, 20, 9, 1, 225, 36, 219, 194, 20, 9, 1, + 222, 250, 70, 20, 9, 1, 222, 250, 48, 20, 9, 1, 222, 250, 84, 20, 9, 1, + 222, 250, 219, 194, 20, 9, 1, 87, 70, 20, 9, 1, 87, 48, 20, 9, 1, 87, 84, + 20, 9, 1, 87, 219, 194, 20, 9, 1, 216, 32, 70, 20, 9, 1, 216, 32, 48, 20, + 9, 1, 216, 32, 84, 20, 9, 1, 216, 32, 219, 194, 20, 9, 1, 232, 114, 70, + 20, 9, 1, 232, 114, 48, 20, 9, 1, 232, 114, 84, 20, 9, 1, 232, 114, 219, + 194, 20, 9, 1, 197, 118, 70, 20, 9, 1, 197, 118, 48, 20, 9, 1, 151, 220, + 70, 70, 20, 9, 1, 151, 220, 70, 48, 20, 9, 1, 93, 70, 20, 9, 1, 93, 48, + 20, 9, 1, 93, 84, 20, 9, 1, 93, 219, 194, 20, 9, 33, 222, 250, 3, 151, 3, + 220, 110, 90, 70, 20, 9, 33, 222, 250, 3, 151, 3, 220, 110, 90, 48, 20, + 9, 33, 222, 250, 3, 151, 3, 232, 214, 90, 70, 20, 9, 33, 222, 250, 3, + 151, 3, 232, 214, 90, 48, 20, 9, 33, 222, 250, 3, 151, 3, 232, 214, 248, + 227, 70, 20, 9, 33, 222, 250, 3, 151, 3, 232, 214, 248, 227, 48, 20, 9, + 33, 222, 250, 3, 151, 70, 20, 9, 33, 222, 250, 3, 151, 48, 20, 195, 80, + 197, 59, 216, 44, 205, 148, 174, 236, 90, 78, 174, 211, 62, 78, 174, 31, + 55, 174, 239, 10, 55, 174, 213, 45, 55, 174, 251, 111, 174, 251, 30, 174, + 50, 213, 140, 174, 53, 213, 140, 174, 250, 179, 174, 98, 55, 174, 244, + 159, 174, 231, 6, 174, 234, 217, 204, 226, 174, 205, 177, 174, 17, 195, + 79, 174, 17, 100, 174, 17, 102, 174, 17, 134, 174, 17, 136, 174, 17, 146, + 174, 17, 167, 174, 17, 178, 174, 17, 171, 174, 17, 182, 174, 244, 168, + 174, 207, 105, 174, 222, 140, 55, 174, 236, 172, 55, 174, 233, 94, 55, + 174, 211, 79, 78, 174, 244, 157, 250, 168, 174, 8, 6, 1, 63, 174, 8, 6, + 1, 250, 112, 174, 8, 6, 1, 247, 207, 174, 8, 6, 1, 240, 231, 174, 8, 6, + 1, 69, 174, 8, 6, 1, 236, 49, 174, 8, 6, 1, 234, 190, 174, 8, 6, 1, 233, + 15, 174, 8, 6, 1, 68, 174, 8, 6, 1, 225, 217, 174, 8, 6, 1, 225, 80, 174, + 8, 6, 1, 159, 174, 8, 6, 1, 221, 136, 174, 8, 6, 1, 218, 55, 174, 8, 6, + 1, 72, 174, 8, 6, 1, 214, 3, 174, 8, 6, 1, 211, 167, 174, 8, 6, 1, 144, + 174, 8, 6, 1, 209, 80, 174, 8, 6, 1, 203, 216, 174, 8, 6, 1, 66, 174, 8, + 6, 1, 199, 230, 174, 8, 6, 1, 197, 199, 174, 8, 6, 1, 196, 222, 174, 8, + 6, 1, 196, 148, 174, 8, 6, 1, 195, 158, 174, 50, 47, 179, 174, 210, 90, + 205, 177, 174, 53, 47, 179, 174, 244, 241, 252, 22, 174, 126, 222, 75, + 174, 233, 101, 252, 22, 174, 8, 4, 1, 63, 174, 8, 4, 1, 250, 112, 174, 8, + 4, 1, 247, 207, 174, 8, 4, 1, 240, 231, 174, 8, 4, 1, 69, 174, 8, 4, 1, + 236, 49, 174, 8, 4, 1, 234, 190, 174, 8, 4, 1, 233, 15, 174, 8, 4, 1, 68, + 174, 8, 4, 1, 225, 217, 174, 8, 4, 1, 225, 80, 174, 8, 4, 1, 159, 174, 8, + 4, 1, 221, 136, 174, 8, 4, 1, 218, 55, 174, 8, 4, 1, 72, 174, 8, 4, 1, + 214, 3, 174, 8, 4, 1, 211, 167, 174, 8, 4, 1, 144, 174, 8, 4, 1, 209, 80, + 174, 8, 4, 1, 203, 216, 174, 8, 4, 1, 66, 174, 8, 4, 1, 199, 230, 174, 8, + 4, 1, 197, 199, 174, 8, 4, 1, 196, 222, 174, 8, 4, 1, 196, 148, 174, 8, + 4, 1, 195, 158, 174, 50, 241, 18, 179, 174, 83, 222, 75, 174, 53, 241, + 18, 179, 174, 202, 84, 174, 50, 59, 213, 140, 174, 53, 59, 213, 140, 138, + 143, 234, 217, 204, 226, 138, 50, 241, 102, 179, 138, 53, 241, 102, 179, + 138, 143, 244, 159, 138, 71, 112, 238, 253, 138, 71, 1, 197, 34, 138, 71, + 1, 4, 63, 138, 71, 1, 4, 68, 138, 71, 1, 4, 66, 138, 71, 1, 4, 69, 138, + 71, 1, 4, 72, 138, 71, 1, 4, 164, 138, 71, 1, 4, 195, 217, 138, 71, 1, 4, + 196, 3, 138, 71, 1, 4, 201, 40, 138, 224, 234, 211, 252, 205, 162, 78, + 138, 71, 1, 63, 138, 71, 1, 68, 138, 71, 1, 66, 138, 71, 1, 69, 138, 71, + 1, 72, 138, 71, 1, 155, 138, 71, 1, 224, 101, 138, 71, 1, 223, 187, 138, + 71, 1, 224, 209, 138, 71, 1, 224, 11, 138, 71, 1, 183, 138, 71, 1, 206, + 112, 138, 71, 1, 204, 172, 138, 71, 1, 208, 147, 138, 71, 1, 205, 200, + 138, 71, 1, 189, 138, 71, 1, 202, 122, 138, 71, 1, 201, 40, 138, 71, 1, + 203, 68, 138, 71, 1, 149, 138, 71, 1, 176, 138, 71, 1, 216, 223, 138, 71, + 1, 215, 186, 138, 71, 1, 217, 118, 138, 71, 1, 216, 50, 138, 71, 1, 142, + 138, 71, 1, 232, 71, 138, 71, 1, 231, 75, 138, 71, 1, 232, 147, 138, 71, + 1, 231, 193, 138, 71, 1, 166, 138, 71, 1, 219, 78, 138, 71, 1, 218, 145, + 138, 71, 1, 219, 207, 138, 71, 1, 218, 251, 138, 71, 1, 164, 138, 71, 1, + 195, 217, 138, 71, 1, 196, 3, 138, 71, 1, 169, 138, 71, 1, 210, 72, 138, + 71, 1, 209, 140, 138, 71, 1, 210, 183, 138, 71, 1, 209, 232, 138, 71, 1, + 197, 166, 138, 71, 1, 218, 55, 138, 71, 198, 244, 205, 162, 78, 138, 71, + 207, 110, 205, 162, 78, 138, 29, 235, 134, 138, 29, 1, 224, 48, 138, 29, + 1, 205, 72, 138, 29, 1, 224, 41, 138, 29, 1, 216, 208, 138, 29, 1, 216, + 206, 138, 29, 1, 216, 205, 138, 29, 1, 202, 97, 138, 29, 1, 205, 61, 138, + 29, 1, 210, 54, 138, 29, 1, 210, 49, 138, 29, 1, 210, 46, 138, 29, 1, + 210, 39, 138, 29, 1, 210, 34, 138, 29, 1, 210, 29, 138, 29, 1, 210, 40, + 138, 29, 1, 210, 52, 138, 29, 1, 219, 56, 138, 29, 1, 212, 206, 138, 29, + 1, 205, 69, 138, 29, 1, 212, 195, 138, 29, 1, 206, 52, 138, 29, 1, 205, + 66, 138, 29, 1, 226, 143, 138, 29, 1, 245, 6, 138, 29, 1, 205, 76, 138, + 29, 1, 245, 71, 138, 29, 1, 224, 122, 138, 29, 1, 202, 191, 138, 29, 1, + 212, 244, 138, 29, 1, 232, 55, 138, 29, 1, 63, 138, 29, 1, 251, 245, 138, + 29, 1, 164, 138, 29, 1, 196, 118, 138, 29, 1, 236, 192, 138, 29, 1, 69, + 138, 29, 1, 196, 56, 138, 29, 1, 196, 69, 138, 29, 1, 72, 138, 29, 1, + 197, 166, 138, 29, 1, 197, 157, 138, 29, 1, 214, 164, 138, 29, 1, 196, 3, + 138, 29, 1, 66, 138, 29, 1, 197, 91, 138, 29, 1, 197, 109, 138, 29, 1, + 197, 70, 138, 29, 1, 195, 217, 138, 29, 1, 236, 116, 138, 29, 1, 196, 24, + 138, 29, 1, 68, 174, 247, 39, 55, 174, 212, 63, 55, 174, 216, 19, 55, + 174, 220, 114, 174, 248, 33, 154, 174, 196, 60, 55, 174, 197, 17, 55, + 138, 235, 19, 175, 199, 100, 138, 107, 51, 138, 200, 24, 51, 138, 91, 51, + 138, 237, 231, 51, 138, 58, 205, 94, 138, 59, 244, 249, 226, 30, 251, 76, + 251, 102, 226, 30, 251, 76, 207, 90, 226, 30, 251, 76, 203, 8, 214, 183, + 210, 114, 246, 255, 210, 114, 246, 255, 30, 74, 5, 250, 96, 63, 30, 74, + 5, 250, 65, 69, 30, 74, 5, 250, 74, 68, 30, 74, 5, 250, 42, 72, 30, 74, + 5, 250, 92, 66, 30, 74, 5, 250, 111, 240, 136, 30, 74, 5, 250, 58, 239, + 252, 30, 74, 5, 250, 98, 239, 152, 30, 74, 5, 250, 88, 239, 28, 30, 74, + 5, 250, 52, 237, 201, 30, 74, 5, 250, 46, 225, 214, 30, 74, 5, 250, 57, + 225, 193, 30, 74, 5, 250, 67, 225, 129, 30, 74, 5, 250, 38, 225, 110, 30, + 74, 5, 250, 26, 155, 30, 74, 5, 250, 59, 224, 209, 30, 74, 5, 250, 36, + 224, 101, 30, 74, 5, 250, 33, 224, 11, 30, 74, 5, 250, 22, 223, 187, 30, + 74, 5, 250, 23, 166, 30, 74, 5, 250, 89, 219, 207, 30, 74, 5, 250, 30, + 219, 78, 30, 74, 5, 250, 87, 218, 251, 30, 74, 5, 250, 79, 218, 145, 30, + 74, 5, 250, 100, 176, 30, 74, 5, 250, 78, 217, 118, 30, 74, 5, 250, 72, + 216, 223, 30, 74, 5, 250, 51, 216, 50, 30, 74, 5, 250, 48, 215, 186, 30, + 74, 5, 250, 107, 161, 30, 74, 5, 250, 31, 213, 92, 30, 74, 5, 250, 64, + 212, 220, 30, 74, 5, 250, 91, 212, 117, 30, 74, 5, 250, 53, 211, 227, 30, + 74, 5, 250, 86, 211, 159, 30, 74, 5, 250, 25, 211, 139, 30, 74, 5, 250, + 81, 211, 121, 30, 74, 5, 250, 70, 211, 109, 30, 74, 5, 250, 43, 169, 30, + 74, 5, 250, 75, 210, 183, 30, 74, 5, 250, 50, 210, 72, 30, 74, 5, 250, + 109, 209, 232, 30, 74, 5, 250, 76, 209, 140, 30, 74, 5, 250, 71, 183, 30, + 74, 5, 250, 94, 208, 147, 30, 74, 5, 250, 62, 206, 112, 30, 74, 5, 250, + 90, 205, 200, 30, 74, 5, 250, 45, 204, 172, 30, 74, 5, 250, 44, 189, 30, + 74, 5, 250, 105, 203, 68, 30, 74, 5, 250, 66, 202, 122, 30, 74, 5, 250, + 103, 149, 30, 74, 5, 250, 34, 201, 40, 30, 74, 5, 250, 49, 197, 166, 30, + 74, 5, 250, 28, 197, 109, 30, 74, 5, 250, 63, 197, 70, 30, 74, 5, 250, + 61, 197, 34, 30, 74, 5, 250, 85, 195, 115, 30, 74, 5, 250, 29, 195, 88, + 30, 74, 5, 250, 82, 195, 11, 30, 74, 5, 250, 77, 254, 177, 30, 74, 5, + 250, 60, 254, 65, 30, 74, 5, 250, 19, 250, 150, 30, 74, 5, 250, 32, 237, + 166, 30, 74, 5, 250, 15, 237, 165, 30, 74, 5, 250, 55, 215, 118, 30, 74, + 5, 250, 73, 211, 225, 30, 74, 5, 250, 41, 211, 229, 30, 74, 5, 250, 27, + 210, 246, 30, 74, 5, 250, 69, 210, 245, 30, 74, 5, 250, 35, 209, 225, 30, + 74, 5, 250, 37, 203, 163, 30, 74, 5, 250, 17, 200, 243, 30, 74, 5, 250, + 14, 102, 30, 74, 16, 250, 84, 30, 74, 16, 250, 83, 30, 74, 16, 250, 80, + 30, 74, 16, 250, 68, 30, 74, 16, 250, 56, 30, 74, 16, 250, 54, 30, 74, + 16, 250, 47, 30, 74, 16, 250, 40, 30, 74, 16, 250, 39, 30, 74, 16, 250, + 24, 30, 74, 16, 250, 21, 30, 74, 16, 250, 20, 30, 74, 16, 250, 18, 30, + 74, 16, 250, 16, 30, 74, 147, 250, 13, 220, 62, 30, 74, 147, 250, 12, + 197, 21, 30, 74, 147, 250, 11, 239, 234, 30, 74, 147, 250, 10, 236, 169, + 30, 74, 147, 250, 9, 220, 29, 30, 74, 147, 250, 8, 205, 15, 30, 74, 147, + 250, 7, 236, 97, 30, 74, 147, 250, 6, 210, 210, 30, 74, 147, 250, 5, 206, + 254, 30, 74, 147, 250, 4, 232, 139, 30, 74, 147, 250, 3, 205, 156, 30, + 74, 147, 250, 2, 248, 114, 30, 74, 147, 250, 1, 241, 83, 30, 74, 147, + 250, 0, 248, 7, 30, 74, 147, 249, 255, 197, 79, 30, 74, 147, 249, 254, + 249, 76, 30, 74, 147, 249, 253, 214, 129, 30, 74, 147, 249, 252, 205, + 126, 30, 74, 147, 249, 251, 240, 239, 30, 74, 218, 205, 249, 250, 225, 4, + 30, 74, 218, 205, 249, 249, 225, 15, 30, 74, 147, 249, 248, 214, 144, 30, + 74, 147, 249, 247, 197, 46, 30, 74, 147, 249, 246, 30, 74, 218, 205, 249, + 245, 250, 244, 30, 74, 218, 205, 249, 244, 219, 156, 30, 74, 147, 249, + 243, 248, 32, 30, 74, 147, 249, 242, 233, 135, 30, 74, 147, 249, 241, 30, + 74, 147, 249, 240, 197, 12, 30, 74, 147, 249, 239, 30, 74, 147, 249, 238, + 30, 74, 147, 249, 237, 231, 102, 30, 74, 147, 249, 236, 30, 74, 147, 249, + 235, 30, 74, 147, 249, 234, 30, 74, 218, 205, 249, 232, 201, 2, 30, 74, + 147, 249, 231, 30, 74, 147, 249, 230, 30, 74, 147, 249, 229, 244, 197, + 30, 74, 147, 249, 228, 30, 74, 147, 249, 227, 30, 74, 147, 249, 226, 234, + 79, 30, 74, 147, 249, 225, 250, 229, 30, 74, 147, 249, 224, 30, 74, 147, + 249, 223, 30, 74, 147, 249, 222, 30, 74, 147, 249, 221, 30, 74, 147, 249, + 220, 30, 74, 147, 249, 219, 30, 74, 147, 249, 218, 30, 74, 147, 249, 217, + 30, 74, 147, 249, 216, 30, 74, 147, 249, 215, 218, 197, 30, 74, 147, 249, + 214, 30, 74, 147, 249, 213, 201, 190, 30, 74, 147, 249, 212, 30, 74, 147, + 249, 211, 30, 74, 147, 249, 210, 30, 74, 147, 249, 209, 30, 74, 147, 249, + 208, 30, 74, 147, 249, 207, 30, 74, 147, 249, 206, 30, 74, 147, 249, 205, + 30, 74, 147, 249, 204, 30, 74, 147, 249, 203, 30, 74, 147, 249, 202, 30, + 74, 147, 249, 201, 232, 103, 30, 74, 147, 249, 180, 235, 33, 30, 74, 147, + 249, 177, 249, 51, 30, 74, 147, 249, 172, 205, 134, 30, 74, 147, 249, + 171, 51, 30, 74, 147, 249, 170, 30, 74, 147, 249, 169, 204, 48, 30, 74, + 147, 249, 168, 30, 74, 147, 249, 167, 30, 74, 147, 249, 166, 197, 74, + 245, 112, 30, 74, 147, 249, 165, 245, 112, 30, 74, 147, 249, 164, 245, + 113, 234, 250, 30, 74, 147, 249, 163, 197, 77, 30, 74, 147, 249, 162, 30, + 74, 147, 249, 161, 30, 74, 218, 205, 249, 160, 239, 87, 30, 74, 147, 249, + 159, 30, 74, 147, 249, 158, 30, 74, 147, 249, 156, 30, 74, 147, 249, 155, + 30, 74, 147, 249, 154, 30, 74, 147, 249, 153, 240, 68, 30, 74, 147, 249, + 152, 30, 74, 147, 249, 151, 30, 74, 147, 249, 150, 30, 74, 147, 249, 149, + 30, 74, 147, 249, 148, 30, 74, 147, 199, 47, 249, 233, 30, 74, 147, 199, + 47, 249, 200, 30, 74, 147, 199, 47, 249, 199, 30, 74, 147, 199, 47, 249, + 198, 30, 74, 147, 199, 47, 249, 197, 30, 74, 147, 199, 47, 249, 196, 30, + 74, 147, 199, 47, 249, 195, 30, 74, 147, 199, 47, 249, 194, 30, 74, 147, + 199, 47, 249, 193, 30, 74, 147, 199, 47, 249, 192, 30, 74, 147, 199, 47, + 249, 191, 30, 74, 147, 199, 47, 249, 190, 30, 74, 147, 199, 47, 249, 189, + 30, 74, 147, 199, 47, 249, 188, 30, 74, 147, 199, 47, 249, 187, 30, 74, + 147, 199, 47, 249, 186, 30, 74, 147, 199, 47, 249, 185, 30, 74, 147, 199, + 47, 249, 184, 30, 74, 147, 199, 47, 249, 183, 30, 74, 147, 199, 47, 249, + 182, 30, 74, 147, 199, 47, 249, 181, 30, 74, 147, 199, 47, 249, 179, 30, + 74, 147, 199, 47, 249, 178, 30, 74, 147, 199, 47, 249, 176, 30, 74, 147, + 199, 47, 249, 175, 30, 74, 147, 199, 47, 249, 174, 30, 74, 147, 199, 47, + 249, 173, 30, 74, 147, 199, 47, 249, 157, 30, 74, 147, 199, 47, 249, 147, + 251, 238, 197, 9, 207, 91, 222, 75, 251, 238, 197, 9, 207, 91, 238, 253, + 251, 238, 245, 102, 78, 251, 238, 31, 100, 251, 238, 31, 102, 251, 238, + 31, 134, 251, 238, 31, 136, 251, 238, 31, 146, 251, 238, 31, 167, 251, + 238, 31, 178, 251, 238, 31, 171, 251, 238, 31, 182, 251, 238, 31, 203, + 23, 251, 238, 31, 200, 234, 251, 238, 31, 202, 177, 251, 238, 31, 235, + 14, 251, 238, 31, 235, 145, 251, 238, 31, 206, 13, 251, 238, 31, 207, 65, + 251, 238, 31, 237, 20, 251, 238, 31, 216, 174, 251, 238, 31, 97, 231, 57, + 251, 238, 31, 99, 231, 57, 251, 238, 31, 115, 231, 57, 251, 238, 31, 235, + 7, 231, 57, 251, 238, 31, 235, 101, 231, 57, 251, 238, 31, 206, 29, 231, + 57, 251, 238, 31, 207, 71, 231, 57, 251, 238, 31, 237, 31, 231, 57, 251, + 238, 31, 216, 179, 231, 57, 251, 238, 31, 97, 170, 251, 238, 31, 99, 170, + 251, 238, 31, 115, 170, 251, 238, 31, 235, 7, 170, 251, 238, 31, 235, + 101, 170, 251, 238, 31, 206, 29, 170, 251, 238, 31, 207, 71, 170, 251, + 238, 31, 237, 31, 170, 251, 238, 31, 216, 179, 170, 251, 238, 31, 203, + 24, 170, 251, 238, 31, 200, 235, 170, 251, 238, 31, 202, 178, 170, 251, + 238, 31, 235, 15, 170, 251, 238, 31, 235, 146, 170, 251, 238, 31, 206, + 14, 170, 251, 238, 31, 207, 66, 170, 251, 238, 31, 237, 21, 170, 251, + 238, 31, 216, 175, 170, 251, 238, 197, 94, 249, 67, 200, 49, 251, 238, + 197, 94, 235, 113, 204, 137, 251, 238, 197, 94, 208, 136, 204, 137, 251, + 238, 197, 94, 202, 185, 204, 137, 251, 238, 197, 94, 235, 0, 204, 137, + 251, 238, 237, 204, 219, 203, 235, 113, 204, 137, 251, 238, 222, 56, 219, + 203, 235, 113, 204, 137, 251, 238, 219, 203, 208, 136, 204, 137, 251, + 238, 219, 203, 202, 185, 204, 137, 32, 252, 13, 250, 152, 97, 211, 87, + 32, 252, 13, 250, 152, 97, 232, 225, 32, 252, 13, 250, 152, 97, 237, 227, + 32, 252, 13, 250, 152, 146, 32, 252, 13, 250, 152, 235, 145, 32, 252, 13, + 250, 152, 235, 101, 231, 57, 32, 252, 13, 250, 152, 235, 101, 170, 32, + 252, 13, 250, 152, 235, 146, 170, 32, 252, 13, 250, 152, 235, 101, 203, + 123, 32, 252, 13, 250, 152, 203, 24, 203, 123, 32, 252, 13, 250, 152, + 235, 146, 203, 123, 32, 252, 13, 250, 152, 97, 231, 58, 203, 123, 32, + 252, 13, 250, 152, 235, 101, 231, 58, 203, 123, 32, 252, 13, 250, 152, + 97, 202, 159, 203, 123, 32, 252, 13, 250, 152, 235, 101, 202, 159, 203, + 123, 32, 252, 13, 250, 152, 235, 101, 204, 255, 32, 252, 13, 250, 152, + 203, 24, 204, 255, 32, 252, 13, 250, 152, 235, 146, 204, 255, 32, 252, + 13, 250, 152, 97, 231, 58, 204, 255, 32, 252, 13, 250, 152, 235, 101, + 231, 58, 204, 255, 32, 252, 13, 250, 152, 97, 202, 159, 204, 255, 32, + 252, 13, 250, 152, 203, 24, 202, 159, 204, 255, 32, 252, 13, 250, 152, + 235, 146, 202, 159, 204, 255, 32, 252, 13, 250, 152, 203, 24, 218, 254, + 32, 252, 13, 232, 97, 97, 212, 135, 32, 252, 13, 202, 201, 100, 32, 252, + 13, 232, 93, 100, 32, 252, 13, 236, 178, 102, 32, 252, 13, 202, 201, 102, + 32, 252, 13, 240, 236, 99, 237, 226, 32, 252, 13, 236, 178, 99, 237, 226, + 32, 252, 13, 201, 156, 146, 32, 252, 13, 201, 156, 203, 23, 32, 252, 13, + 201, 156, 203, 24, 251, 131, 20, 32, 252, 13, 232, 93, 203, 23, 32, 252, + 13, 219, 145, 203, 23, 32, 252, 13, 202, 201, 203, 23, 32, 252, 13, 202, + 201, 202, 177, 32, 252, 13, 201, 156, 235, 145, 32, 252, 13, 201, 156, + 235, 146, 251, 131, 20, 32, 252, 13, 232, 93, 235, 145, 32, 252, 13, 202, + 201, 235, 145, 32, 252, 13, 202, 201, 97, 231, 57, 32, 252, 13, 202, 201, + 115, 231, 57, 32, 252, 13, 236, 178, 235, 101, 231, 57, 32, 252, 13, 201, + 156, 235, 101, 231, 57, 32, 252, 13, 202, 201, 235, 101, 231, 57, 32, + 252, 13, 247, 96, 235, 101, 231, 57, 32, 252, 13, 217, 196, 235, 101, + 231, 57, 32, 252, 13, 202, 201, 97, 170, 32, 252, 13, 202, 201, 235, 101, + 170, 32, 252, 13, 239, 215, 235, 101, 218, 254, 32, 252, 13, 204, 214, + 235, 146, 218, 254, 32, 97, 157, 55, 32, 97, 157, 2, 251, 131, 20, 32, + 99, 202, 182, 55, 32, 115, 211, 86, 55, 32, 196, 67, 55, 32, 203, 124, + 55, 32, 237, 228, 55, 32, 214, 180, 55, 32, 99, 214, 179, 55, 32, 115, + 214, 179, 55, 32, 235, 7, 214, 179, 55, 32, 235, 101, 214, 179, 55, 32, + 219, 139, 55, 32, 223, 108, 249, 67, 55, 32, 222, 49, 55, 32, 214, 36, + 55, 32, 196, 199, 55, 32, 250, 209, 55, 32, 250, 225, 55, 32, 233, 110, + 55, 32, 201, 116, 249, 67, 55, 32, 195, 80, 55, 32, 97, 211, 88, 55, 32, + 206, 54, 55, 32, 226, 67, 55, 216, 39, 55, 209, 208, 207, 62, 55, 209, + 208, 200, 65, 55, 209, 208, 207, 97, 55, 209, 208, 207, 60, 55, 209, 208, + 239, 102, 207, 60, 55, 209, 208, 206, 77, 55, 209, 208, 239, 211, 55, + 209, 208, 211, 71, 55, 209, 208, 207, 78, 55, 209, 208, 237, 180, 55, + 209, 208, 250, 203, 55, 209, 208, 247, 32, 55, 32, 16, 203, 90, 210, 74, + 213, 1, 239, 79, 2, 213, 81, 213, 1, 239, 79, 2, 212, 127, 232, 137, 213, + 1, 239, 79, 2, 203, 93, 232, 137, 213, 1, 239, 79, 2, 247, 119, 213, 1, + 239, 79, 2, 245, 66, 213, 1, 239, 79, 2, 197, 21, 213, 1, 239, 79, 2, + 232, 103, 213, 1, 239, 79, 2, 234, 71, 213, 1, 239, 79, 2, 202, 113, 213, + 1, 239, 79, 2, 51, 213, 1, 239, 79, 2, 248, 77, 213, 1, 239, 79, 2, 206, + 220, 213, 1, 239, 79, 2, 244, 190, 213, 1, 239, 79, 2, 220, 61, 213, 1, + 239, 79, 2, 220, 0, 213, 1, 239, 79, 2, 208, 185, 213, 1, 239, 79, 2, + 222, 104, 213, 1, 239, 79, 2, 248, 98, 213, 1, 239, 79, 2, 247, 103, 212, + 142, 213, 1, 239, 79, 2, 239, 11, 213, 1, 239, 79, 2, 244, 165, 213, 1, + 239, 79, 2, 205, 235, 213, 1, 239, 79, 2, 244, 166, 213, 1, 239, 79, 2, + 248, 248, 213, 1, 239, 79, 2, 206, 207, 213, 1, 239, 79, 2, 231, 102, + 213, 1, 239, 79, 2, 232, 61, 213, 1, 239, 79, 2, 248, 2, 222, 172, 213, + 1, 239, 79, 2, 247, 92, 213, 1, 239, 79, 2, 210, 210, 213, 1, 239, 79, 2, + 237, 79, 213, 1, 239, 79, 2, 237, 236, 213, 1, 239, 79, 2, 201, 18, 213, + 1, 239, 79, 2, 248, 251, 213, 1, 239, 79, 2, 212, 143, 201, 190, 213, 1, + 239, 79, 2, 199, 14, 213, 1, 239, 79, 2, 213, 158, 213, 1, 239, 79, 2, + 209, 197, 213, 1, 239, 79, 2, 222, 88, 213, 1, 239, 79, 2, 214, 14, 249, + 138, 213, 1, 239, 79, 2, 235, 58, 213, 1, 239, 79, 2, 233, 102, 213, 1, + 239, 79, 2, 204, 215, 213, 1, 239, 79, 2, 4, 250, 123, 213, 1, 239, 79, + 2, 197, 119, 249, 89, 213, 1, 239, 79, 2, 38, 214, 182, 106, 221, 149, 1, + 63, 221, 149, 1, 69, 221, 149, 1, 250, 112, 221, 149, 1, 248, 198, 221, + 149, 1, 234, 190, 221, 149, 1, 240, 231, 221, 149, 1, 68, 221, 149, 1, + 197, 199, 221, 149, 1, 195, 158, 221, 149, 1, 202, 235, 221, 149, 1, 225, + 217, 221, 149, 1, 225, 80, 221, 149, 1, 211, 167, 221, 149, 1, 159, 221, + 149, 1, 221, 136, 221, 149, 1, 218, 55, 221, 149, 1, 219, 0, 221, 149, 1, + 216, 87, 221, 149, 1, 66, 221, 149, 1, 214, 3, 221, 149, 1, 224, 37, 221, + 149, 1, 144, 221, 149, 1, 209, 80, 221, 149, 1, 203, 216, 221, 149, 1, + 201, 81, 221, 149, 1, 251, 106, 221, 149, 1, 236, 230, 221, 149, 1, 233, + 15, 221, 149, 1, 196, 222, 247, 109, 1, 63, 247, 109, 1, 213, 245, 247, + 109, 1, 240, 231, 247, 109, 1, 159, 247, 109, 1, 199, 243, 247, 109, 1, + 144, 247, 109, 1, 222, 201, 247, 109, 1, 254, 177, 247, 109, 1, 211, 167, + 247, 109, 1, 250, 112, 247, 109, 1, 221, 136, 247, 109, 1, 72, 247, 109, + 1, 240, 138, 247, 109, 1, 203, 216, 247, 109, 1, 207, 52, 247, 109, 1, + 207, 51, 247, 109, 1, 209, 80, 247, 109, 1, 247, 206, 247, 109, 1, 66, + 247, 109, 1, 216, 87, 247, 109, 1, 196, 222, 247, 109, 1, 218, 55, 247, + 109, 1, 201, 80, 247, 109, 1, 214, 3, 247, 109, 1, 205, 83, 247, 109, 1, + 68, 247, 109, 1, 69, 247, 109, 1, 199, 240, 247, 109, 1, 225, 80, 247, + 109, 1, 225, 71, 247, 109, 1, 217, 161, 247, 109, 1, 199, 245, 247, 109, + 1, 234, 190, 247, 109, 1, 234, 125, 247, 109, 1, 205, 23, 247, 109, 1, + 205, 22, 247, 109, 1, 217, 73, 247, 109, 1, 226, 120, 247, 109, 1, 247, + 205, 247, 109, 1, 201, 81, 247, 109, 1, 199, 242, 247, 109, 1, 209, 182, + 247, 109, 1, 219, 246, 247, 109, 1, 219, 245, 247, 109, 1, 219, 244, 247, + 109, 1, 219, 243, 247, 109, 1, 222, 200, 247, 109, 1, 237, 83, 247, 109, + 1, 199, 241, 88, 236, 181, 202, 158, 78, 88, 236, 181, 17, 100, 88, 236, + 181, 17, 102, 88, 236, 181, 17, 134, 88, 236, 181, 17, 136, 88, 236, 181, + 17, 146, 88, 236, 181, 17, 167, 88, 236, 181, 17, 178, 88, 236, 181, 17, + 171, 88, 236, 181, 17, 182, 88, 236, 181, 31, 203, 23, 88, 236, 181, 31, + 200, 234, 88, 236, 181, 31, 202, 177, 88, 236, 181, 31, 235, 14, 88, 236, + 181, 31, 235, 145, 88, 236, 181, 31, 206, 13, 88, 236, 181, 31, 207, 65, + 88, 236, 181, 31, 237, 20, 88, 236, 181, 31, 216, 174, 88, 236, 181, 31, + 97, 231, 57, 88, 236, 181, 31, 99, 231, 57, 88, 236, 181, 31, 115, 231, + 57, 88, 236, 181, 31, 235, 7, 231, 57, 88, 236, 181, 31, 235, 101, 231, + 57, 88, 236, 181, 31, 206, 29, 231, 57, 88, 236, 181, 31, 207, 71, 231, + 57, 88, 236, 181, 31, 237, 31, 231, 57, 88, 236, 181, 31, 216, 179, 231, + 57, 37, 41, 1, 63, 37, 41, 1, 249, 9, 37, 41, 1, 224, 209, 37, 41, 1, + 239, 252, 37, 41, 1, 69, 37, 41, 1, 199, 118, 37, 41, 1, 195, 88, 37, 41, + 1, 232, 147, 37, 41, 1, 202, 217, 37, 41, 1, 68, 37, 41, 1, 155, 37, 41, + 1, 237, 7, 37, 41, 1, 236, 241, 37, 41, 1, 236, 230, 37, 41, 1, 236, 141, + 37, 41, 1, 72, 37, 41, 1, 213, 92, 37, 41, 1, 206, 255, 37, 41, 1, 223, + 187, 37, 41, 1, 236, 163, 37, 41, 1, 236, 151, 37, 41, 1, 203, 68, 37, + 41, 1, 66, 37, 41, 1, 237, 10, 37, 41, 1, 212, 249, 37, 41, 1, 224, 131, + 37, 41, 1, 237, 47, 37, 41, 1, 236, 153, 37, 41, 1, 245, 103, 37, 41, 1, + 226, 120, 37, 41, 1, 199, 245, 37, 41, 1, 236, 134, 37, 41, 215, 142, + 100, 37, 41, 215, 142, 146, 37, 41, 215, 142, 203, 23, 37, 41, 215, 142, + 235, 145, 37, 41, 1, 196, 69, 37, 41, 1, 216, 23, 201, 107, 37, 41, 1, + 205, 157, 201, 107, 233, 120, 1, 251, 203, 233, 120, 1, 249, 109, 233, + 120, 1, 233, 189, 233, 120, 1, 240, 117, 233, 120, 1, 251, 198, 233, 120, + 1, 211, 150, 233, 120, 1, 225, 229, 233, 120, 1, 232, 238, 233, 120, 1, + 202, 171, 233, 120, 1, 237, 18, 233, 120, 1, 223, 146, 233, 120, 1, 223, + 58, 233, 120, 1, 220, 52, 233, 120, 1, 217, 198, 233, 120, 1, 225, 185, + 233, 120, 1, 200, 7, 233, 120, 1, 213, 218, 233, 120, 1, 216, 174, 233, + 120, 1, 210, 223, 233, 120, 1, 208, 189, 233, 120, 1, 203, 38, 233, 120, + 1, 197, 44, 233, 120, 1, 235, 219, 233, 120, 1, 226, 124, 233, 120, 1, + 231, 41, 233, 120, 1, 214, 48, 233, 120, 1, 216, 179, 231, 57, 37, 213, + 36, 1, 251, 106, 37, 213, 36, 1, 247, 244, 37, 213, 36, 1, 234, 107, 37, + 213, 36, 1, 239, 15, 37, 213, 36, 1, 69, 37, 213, 36, 1, 195, 56, 37, + 213, 36, 1, 237, 148, 37, 213, 36, 1, 195, 96, 37, 213, 36, 1, 237, 146, + 37, 213, 36, 1, 68, 37, 213, 36, 1, 223, 251, 37, 213, 36, 1, 222, 168, + 37, 213, 36, 1, 219, 162, 37, 213, 36, 1, 217, 99, 37, 213, 36, 1, 198, + 232, 37, 213, 36, 1, 213, 78, 37, 213, 36, 1, 210, 141, 37, 213, 36, 1, + 206, 84, 37, 213, 36, 1, 203, 137, 37, 213, 36, 1, 66, 37, 213, 36, 1, + 245, 84, 37, 213, 36, 1, 206, 189, 37, 213, 36, 1, 207, 1, 37, 213, 36, + 1, 195, 219, 37, 213, 36, 1, 196, 47, 37, 213, 36, 1, 72, 37, 213, 36, 1, + 214, 102, 37, 213, 36, 1, 237, 47, 37, 213, 36, 1, 142, 37, 213, 36, 1, + 201, 91, 37, 213, 36, 1, 199, 105, 37, 213, 36, 1, 196, 51, 37, 213, 36, + 1, 196, 49, 37, 213, 36, 1, 196, 84, 37, 213, 36, 1, 226, 147, 37, 213, + 36, 1, 195, 217, 37, 213, 36, 1, 164, 37, 213, 36, 1, 230, 210, 38, 37, + 213, 36, 1, 251, 106, 38, 37, 213, 36, 1, 239, 15, 38, 37, 213, 36, 1, + 195, 96, 38, 37, 213, 36, 1, 217, 99, 38, 37, 213, 36, 1, 206, 84, 200, + 93, 1, 251, 138, 200, 93, 1, 248, 206, 200, 93, 1, 234, 95, 200, 93, 1, + 224, 146, 200, 93, 1, 239, 212, 200, 93, 1, 231, 193, 200, 93, 1, 197, + 34, 200, 93, 1, 195, 78, 200, 93, 1, 231, 94, 200, 93, 1, 203, 1, 200, + 93, 1, 195, 241, 200, 93, 1, 225, 35, 200, 93, 1, 206, 211, 200, 93, 1, + 222, 245, 200, 93, 1, 219, 171, 200, 93, 1, 239, 172, 200, 93, 1, 215, + 138, 200, 93, 1, 194, 255, 200, 93, 1, 208, 224, 200, 93, 1, 251, 194, + 200, 93, 1, 211, 227, 200, 93, 1, 209, 7, 200, 93, 1, 211, 102, 200, 93, + 1, 210, 201, 200, 93, 1, 202, 221, 200, 93, 1, 233, 225, 200, 93, 1, 149, + 200, 93, 1, 68, 200, 93, 1, 66, 200, 93, 1, 205, 34, 200, 93, 197, 9, + 239, 59, 37, 213, 30, 2, 63, 37, 213, 30, 2, 68, 37, 213, 30, 2, 66, 37, + 213, 30, 2, 155, 37, 213, 30, 2, 223, 187, 37, 213, 30, 2, 234, 123, 37, + 213, 30, 2, 233, 76, 37, 213, 30, 2, 196, 208, 37, 213, 30, 2, 247, 174, + 37, 213, 30, 2, 225, 214, 37, 213, 30, 2, 225, 172, 37, 213, 30, 2, 189, + 37, 213, 30, 2, 201, 40, 37, 213, 30, 2, 240, 136, 37, 213, 30, 2, 239, + 152, 37, 213, 30, 2, 237, 201, 37, 213, 30, 2, 202, 233, 37, 213, 30, 2, + 161, 37, 213, 30, 2, 249, 145, 37, 213, 30, 2, 235, 239, 37, 213, 30, 2, + 176, 37, 213, 30, 2, 215, 186, 37, 213, 30, 2, 166, 37, 213, 30, 2, 219, + 78, 37, 213, 30, 2, 218, 145, 37, 213, 30, 2, 164, 37, 213, 30, 2, 199, + 152, 37, 213, 30, 2, 199, 34, 37, 213, 30, 2, 169, 37, 213, 30, 2, 209, + 140, 37, 213, 30, 2, 172, 37, 213, 30, 2, 183, 37, 213, 30, 2, 195, 115, + 37, 213, 30, 2, 207, 50, 37, 213, 30, 2, 205, 80, 37, 213, 30, 2, 142, + 37, 213, 30, 2, 250, 144, 37, 213, 30, 2, 250, 143, 37, 213, 30, 2, 250, + 142, 37, 213, 30, 2, 196, 178, 37, 213, 30, 2, 240, 113, 37, 213, 30, 2, + 240, 112, 37, 213, 30, 2, 249, 120, 37, 213, 30, 2, 247, 226, 37, 213, + 30, 197, 9, 239, 59, 37, 213, 30, 31, 100, 37, 213, 30, 31, 102, 37, 213, + 30, 31, 203, 23, 37, 213, 30, 31, 200, 234, 37, 213, 30, 31, 231, 57, + 239, 192, 6, 1, 181, 68, 239, 192, 6, 1, 181, 69, 239, 192, 6, 1, 181, + 63, 239, 192, 6, 1, 181, 251, 209, 239, 192, 6, 1, 181, 72, 239, 192, 6, + 1, 181, 214, 102, 239, 192, 6, 1, 206, 182, 68, 239, 192, 6, 1, 206, 182, + 69, 239, 192, 6, 1, 206, 182, 63, 239, 192, 6, 1, 206, 182, 251, 209, + 239, 192, 6, 1, 206, 182, 72, 239, 192, 6, 1, 206, 182, 214, 102, 239, + 192, 6, 1, 250, 122, 239, 192, 6, 1, 214, 16, 239, 192, 6, 1, 196, 243, + 239, 192, 6, 1, 196, 66, 239, 192, 6, 1, 233, 15, 239, 192, 6, 1, 213, + 79, 239, 192, 6, 1, 248, 251, 239, 192, 6, 1, 203, 48, 239, 192, 6, 1, + 239, 237, 239, 192, 6, 1, 245, 99, 239, 192, 6, 1, 225, 191, 239, 192, 6, + 1, 224, 216, 239, 192, 6, 1, 234, 69, 239, 192, 6, 1, 237, 47, 239, 192, + 6, 1, 199, 113, 239, 192, 6, 1, 236, 121, 239, 192, 6, 1, 202, 215, 239, + 192, 6, 1, 236, 151, 239, 192, 6, 1, 195, 85, 239, 192, 6, 1, 236, 141, + 239, 192, 6, 1, 195, 64, 239, 192, 6, 1, 236, 163, 239, 192, 6, 1, 237, + 7, 239, 192, 6, 1, 236, 241, 239, 192, 6, 1, 236, 230, 239, 192, 6, 1, + 236, 215, 239, 192, 6, 1, 214, 146, 239, 192, 6, 1, 236, 98, 239, 192, 4, + 1, 181, 68, 239, 192, 4, 1, 181, 69, 239, 192, 4, 1, 181, 63, 239, 192, + 4, 1, 181, 251, 209, 239, 192, 4, 1, 181, 72, 239, 192, 4, 1, 181, 214, + 102, 239, 192, 4, 1, 206, 182, 68, 239, 192, 4, 1, 206, 182, 69, 239, + 192, 4, 1, 206, 182, 63, 239, 192, 4, 1, 206, 182, 251, 209, 239, 192, 4, + 1, 206, 182, 72, 239, 192, 4, 1, 206, 182, 214, 102, 239, 192, 4, 1, 250, + 122, 239, 192, 4, 1, 214, 16, 239, 192, 4, 1, 196, 243, 239, 192, 4, 1, + 196, 66, 239, 192, 4, 1, 233, 15, 239, 192, 4, 1, 213, 79, 239, 192, 4, + 1, 248, 251, 239, 192, 4, 1, 203, 48, 239, 192, 4, 1, 239, 237, 239, 192, + 4, 1, 245, 99, 239, 192, 4, 1, 225, 191, 239, 192, 4, 1, 224, 216, 239, + 192, 4, 1, 234, 69, 239, 192, 4, 1, 237, 47, 239, 192, 4, 1, 199, 113, + 239, 192, 4, 1, 236, 121, 239, 192, 4, 1, 202, 215, 239, 192, 4, 1, 236, + 151, 239, 192, 4, 1, 195, 85, 239, 192, 4, 1, 236, 141, 239, 192, 4, 1, + 195, 64, 239, 192, 4, 1, 236, 163, 239, 192, 4, 1, 237, 7, 239, 192, 4, + 1, 236, 241, 239, 192, 4, 1, 236, 230, 239, 192, 4, 1, 236, 215, 239, + 192, 4, 1, 214, 146, 239, 192, 4, 1, 236, 98, 207, 6, 1, 213, 76, 207, 6, + 1, 201, 229, 207, 6, 1, 224, 89, 207, 6, 1, 235, 182, 207, 6, 1, 202, + 190, 207, 6, 1, 205, 200, 207, 6, 1, 204, 85, 207, 6, 1, 245, 22, 207, 6, + 1, 196, 68, 207, 6, 1, 231, 54, 207, 6, 1, 248, 183, 207, 6, 1, 239, 251, + 207, 6, 1, 234, 109, 207, 6, 1, 198, 227, 207, 6, 1, 202, 196, 207, 6, 1, + 195, 8, 207, 6, 1, 219, 202, 207, 6, 1, 225, 108, 207, 6, 1, 197, 25, + 207, 6, 1, 232, 248, 207, 6, 1, 221, 245, 207, 6, 1, 219, 24, 207, 6, 1, + 226, 127, 207, 6, 1, 237, 45, 207, 6, 1, 250, 195, 207, 6, 1, 251, 250, + 207, 6, 1, 214, 119, 207, 6, 1, 197, 12, 207, 6, 1, 214, 34, 207, 6, 1, + 251, 209, 207, 6, 1, 209, 223, 207, 6, 1, 215, 138, 207, 6, 1, 237, 65, + 207, 6, 1, 251, 214, 207, 6, 1, 230, 201, 207, 6, 1, 200, 36, 207, 6, 1, + 214, 188, 207, 6, 1, 214, 94, 207, 6, 1, 214, 144, 207, 6, 1, 250, 125, + 207, 6, 1, 250, 246, 207, 6, 1, 214, 72, 207, 6, 1, 251, 189, 207, 6, 1, + 236, 155, 207, 6, 1, 250, 222, 207, 6, 1, 237, 76, 207, 6, 1, 230, 209, + 207, 6, 1, 196, 30, 214, 50, 1, 251, 164, 214, 50, 1, 249, 145, 214, 50, + 1, 189, 214, 50, 1, 225, 214, 214, 50, 1, 196, 208, 214, 50, 1, 224, 146, + 214, 50, 1, 239, 236, 214, 50, 1, 169, 214, 50, 1, 183, 214, 50, 1, 206, + 217, 214, 50, 1, 239, 176, 214, 50, 1, 247, 82, 214, 50, 1, 234, 123, + 214, 50, 1, 235, 239, 214, 50, 1, 211, 157, 214, 50, 1, 225, 51, 214, 50, + 1, 223, 78, 214, 50, 1, 219, 38, 214, 50, 1, 215, 122, 214, 50, 1, 197, + 117, 214, 50, 1, 142, 214, 50, 1, 164, 214, 50, 1, 63, 214, 50, 1, 69, + 214, 50, 1, 68, 214, 50, 1, 72, 214, 50, 1, 66, 214, 50, 1, 252, 168, + 214, 50, 1, 237, 54, 214, 50, 1, 214, 102, 214, 50, 17, 195, 79, 214, 50, + 17, 100, 214, 50, 17, 102, 214, 50, 17, 134, 214, 50, 17, 136, 214, 50, + 17, 146, 214, 50, 17, 167, 214, 50, 17, 178, 214, 50, 17, 171, 214, 50, + 17, 182, 214, 52, 6, 1, 63, 214, 52, 6, 1, 251, 200, 214, 52, 6, 1, 251, + 194, 214, 52, 6, 1, 251, 209, 214, 52, 6, 1, 248, 64, 214, 52, 6, 1, 247, + 16, 214, 52, 6, 1, 237, 39, 214, 52, 6, 1, 69, 214, 52, 6, 1, 237, 19, + 214, 52, 6, 1, 142, 214, 52, 6, 1, 231, 11, 214, 52, 6, 1, 68, 214, 52, + 6, 1, 155, 214, 52, 6, 1, 237, 38, 214, 52, 6, 1, 223, 110, 214, 52, 6, + 1, 172, 214, 52, 6, 1, 166, 214, 52, 6, 1, 176, 214, 52, 6, 1, 72, 214, + 52, 6, 1, 214, 143, 214, 52, 6, 1, 161, 214, 52, 6, 1, 237, 37, 214, 52, + 6, 1, 183, 214, 52, 6, 1, 207, 50, 214, 52, 6, 1, 189, 214, 52, 6, 1, + 237, 36, 214, 52, 6, 1, 201, 113, 214, 52, 6, 1, 237, 35, 214, 52, 6, 1, + 201, 103, 214, 52, 6, 1, 239, 176, 214, 52, 6, 1, 66, 214, 52, 6, 1, 197, + 166, 214, 52, 6, 1, 224, 146, 214, 52, 6, 1, 233, 230, 214, 52, 6, 1, + 195, 115, 214, 52, 6, 1, 195, 74, 214, 52, 4, 1, 63, 214, 52, 4, 1, 251, + 200, 214, 52, 4, 1, 251, 194, 214, 52, 4, 1, 251, 209, 214, 52, 4, 1, + 248, 64, 214, 52, 4, 1, 247, 16, 214, 52, 4, 1, 237, 39, 214, 52, 4, 1, + 69, 214, 52, 4, 1, 237, 19, 214, 52, 4, 1, 142, 214, 52, 4, 1, 231, 11, + 214, 52, 4, 1, 68, 214, 52, 4, 1, 155, 214, 52, 4, 1, 237, 38, 214, 52, + 4, 1, 223, 110, 214, 52, 4, 1, 172, 214, 52, 4, 1, 166, 214, 52, 4, 1, + 176, 214, 52, 4, 1, 72, 214, 52, 4, 1, 214, 143, 214, 52, 4, 1, 161, 214, + 52, 4, 1, 237, 37, 214, 52, 4, 1, 183, 214, 52, 4, 1, 207, 50, 214, 52, + 4, 1, 189, 214, 52, 4, 1, 237, 36, 214, 52, 4, 1, 201, 113, 214, 52, 4, + 1, 237, 35, 214, 52, 4, 1, 201, 103, 214, 52, 4, 1, 239, 176, 214, 52, 4, + 1, 66, 214, 52, 4, 1, 197, 166, 214, 52, 4, 1, 224, 146, 214, 52, 4, 1, + 233, 230, 214, 52, 4, 1, 195, 115, 214, 52, 4, 1, 195, 74, 237, 3, 1, 63, + 237, 3, 1, 249, 9, 237, 3, 1, 247, 57, 237, 3, 1, 245, 103, 237, 3, 1, + 239, 252, 237, 3, 1, 217, 151, 237, 3, 1, 239, 167, 237, 3, 1, 237, 33, + 237, 3, 1, 69, 237, 3, 1, 235, 189, 237, 3, 1, 234, 48, 237, 3, 1, 233, + 161, 237, 3, 1, 232, 147, 237, 3, 1, 68, 237, 3, 1, 225, 193, 237, 3, 1, + 224, 209, 237, 3, 1, 222, 197, 237, 3, 1, 222, 32, 237, 3, 1, 219, 207, + 237, 3, 1, 217, 118, 237, 3, 1, 176, 237, 3, 1, 216, 157, 237, 3, 1, 72, + 237, 3, 1, 213, 92, 237, 3, 1, 211, 139, 237, 3, 1, 210, 183, 237, 3, 1, + 209, 176, 237, 3, 1, 208, 147, 237, 3, 1, 206, 255, 237, 3, 1, 203, 68, + 237, 3, 1, 202, 217, 237, 3, 1, 66, 237, 3, 1, 199, 118, 237, 3, 1, 196, + 202, 237, 3, 1, 196, 148, 237, 3, 1, 195, 88, 237, 3, 1, 195, 65, 237, 3, + 1, 233, 216, 237, 3, 1, 233, 222, 237, 3, 1, 224, 131, 247, 89, 251, 165, + 1, 251, 133, 247, 89, 251, 165, 1, 248, 208, 247, 89, 251, 165, 1, 233, + 179, 247, 89, 251, 165, 1, 240, 61, 247, 89, 251, 165, 1, 237, 64, 247, + 89, 251, 165, 1, 195, 99, 247, 89, 251, 165, 1, 236, 58, 247, 89, 251, + 165, 1, 195, 59, 247, 89, 251, 165, 1, 203, 96, 247, 89, 251, 165, 1, + 247, 16, 247, 89, 251, 165, 1, 195, 228, 247, 89, 251, 165, 1, 195, 74, + 247, 89, 251, 165, 1, 226, 0, 247, 89, 251, 165, 1, 207, 50, 247, 89, + 251, 165, 1, 222, 238, 247, 89, 251, 165, 1, 226, 13, 247, 89, 251, 165, + 1, 196, 198, 247, 89, 251, 165, 1, 237, 164, 247, 89, 251, 165, 1, 247, + 116, 247, 89, 251, 165, 1, 225, 173, 247, 89, 251, 165, 1, 224, 251, 247, + 89, 251, 165, 1, 221, 145, 247, 89, 251, 165, 1, 232, 82, 247, 89, 251, + 165, 1, 211, 140, 247, 89, 251, 165, 1, 251, 48, 247, 89, 251, 165, 1, + 245, 39, 247, 89, 251, 165, 1, 245, 75, 247, 89, 251, 165, 1, 240, 243, + 247, 89, 251, 165, 1, 220, 40, 247, 89, 251, 165, 1, 211, 144, 247, 89, + 251, 165, 1, 216, 3, 247, 89, 251, 165, 1, 237, 141, 247, 89, 251, 165, + 1, 207, 33, 247, 89, 251, 165, 1, 225, 194, 247, 89, 251, 165, 1, 214, + 119, 247, 89, 251, 165, 1, 200, 205, 247, 89, 251, 165, 1, 235, 212, 247, + 89, 251, 165, 1, 237, 154, 247, 89, 251, 165, 1, 245, 109, 247, 89, 251, + 165, 1, 213, 65, 247, 89, 251, 165, 1, 233, 206, 247, 89, 251, 165, 1, + 210, 198, 247, 89, 251, 165, 1, 207, 59, 247, 89, 251, 165, 1, 199, 37, + 247, 89, 251, 165, 1, 202, 50, 247, 89, 251, 165, 1, 206, 160, 247, 89, + 251, 165, 1, 225, 227, 247, 89, 251, 165, 1, 240, 244, 247, 89, 251, 165, + 1, 247, 82, 247, 89, 251, 165, 1, 196, 73, 247, 89, 251, 165, 1, 212, + 154, 247, 89, 251, 165, 1, 224, 52, 247, 89, 251, 165, 244, 237, 78, 30, + 39, 2, 252, 116, 30, 39, 2, 252, 115, 30, 39, 2, 252, 114, 30, 39, 2, + 252, 113, 30, 39, 2, 252, 112, 30, 39, 2, 252, 111, 30, 39, 2, 252, 110, + 30, 39, 2, 252, 109, 30, 39, 2, 252, 108, 30, 39, 2, 252, 107, 30, 39, 2, + 252, 106, 30, 39, 2, 252, 105, 30, 39, 2, 252, 104, 30, 39, 2, 252, 103, + 30, 39, 2, 252, 102, 30, 39, 2, 252, 101, 30, 39, 2, 252, 100, 30, 39, 2, + 252, 99, 30, 39, 2, 252, 98, 30, 39, 2, 252, 97, 30, 39, 2, 252, 96, 30, + 39, 2, 252, 95, 30, 39, 2, 252, 94, 30, 39, 2, 252, 93, 30, 39, 2, 252, + 92, 30, 39, 2, 252, 91, 30, 39, 2, 252, 90, 30, 39, 2, 255, 126, 30, 39, + 2, 252, 89, 30, 39, 2, 252, 88, 30, 39, 2, 252, 87, 30, 39, 2, 252, 86, + 30, 39, 2, 252, 85, 30, 39, 2, 252, 84, 30, 39, 2, 252, 83, 30, 39, 2, + 252, 82, 30, 39, 2, 252, 81, 30, 39, 2, 252, 80, 30, 39, 2, 252, 79, 30, + 39, 2, 252, 78, 30, 39, 2, 252, 77, 30, 39, 2, 252, 76, 30, 39, 2, 252, + 75, 30, 39, 2, 252, 74, 30, 39, 2, 252, 73, 30, 39, 2, 252, 72, 30, 39, + 2, 252, 71, 30, 39, 2, 252, 70, 30, 39, 2, 252, 69, 30, 39, 2, 252, 68, + 30, 39, 2, 252, 67, 30, 39, 2, 252, 66, 30, 39, 2, 252, 65, 30, 39, 2, + 252, 64, 30, 39, 2, 252, 63, 30, 39, 2, 252, 62, 30, 39, 2, 252, 61, 30, + 39, 2, 252, 60, 30, 39, 2, 252, 59, 30, 39, 2, 252, 58, 30, 39, 2, 252, + 57, 30, 39, 2, 252, 56, 30, 39, 2, 252, 55, 30, 39, 2, 252, 54, 30, 39, + 2, 252, 53, 30, 39, 2, 252, 52, 30, 39, 2, 252, 51, 30, 39, 2, 252, 50, + 30, 39, 2, 252, 49, 30, 39, 2, 252, 48, 30, 39, 2, 252, 47, 30, 39, 2, + 255, 39, 30, 39, 2, 252, 46, 30, 39, 2, 252, 45, 30, 39, 2, 255, 4, 30, + 39, 2, 252, 44, 30, 39, 2, 252, 43, 30, 39, 2, 252, 42, 30, 39, 2, 252, + 41, 30, 39, 2, 254, 247, 30, 39, 2, 252, 40, 30, 39, 2, 252, 39, 30, 39, + 2, 252, 38, 30, 39, 2, 252, 37, 30, 39, 2, 252, 36, 30, 39, 2, 254, 63, + 30, 39, 2, 254, 62, 30, 39, 2, 254, 61, 30, 39, 2, 254, 60, 30, 39, 2, + 254, 59, 30, 39, 2, 254, 58, 30, 39, 2, 254, 57, 30, 39, 2, 254, 56, 30, + 39, 2, 254, 54, 30, 39, 2, 254, 53, 30, 39, 2, 254, 52, 30, 39, 2, 254, + 51, 30, 39, 2, 254, 50, 30, 39, 2, 254, 49, 30, 39, 2, 254, 47, 30, 39, + 2, 254, 46, 30, 39, 2, 254, 45, 30, 39, 2, 254, 44, 30, 39, 2, 254, 43, + 30, 39, 2, 254, 42, 30, 39, 2, 254, 41, 30, 39, 2, 254, 40, 30, 39, 2, + 254, 39, 30, 39, 2, 254, 38, 30, 39, 2, 254, 37, 30, 39, 2, 254, 36, 30, + 39, 2, 254, 35, 30, 39, 2, 254, 34, 30, 39, 2, 254, 33, 30, 39, 2, 254, + 32, 30, 39, 2, 254, 31, 30, 39, 2, 254, 30, 30, 39, 2, 254, 29, 30, 39, + 2, 254, 27, 30, 39, 2, 254, 26, 30, 39, 2, 254, 25, 30, 39, 2, 254, 21, + 30, 39, 2, 254, 20, 30, 39, 2, 254, 19, 30, 39, 2, 254, 18, 30, 39, 2, + 254, 14, 30, 39, 2, 254, 13, 30, 39, 2, 254, 12, 30, 39, 2, 254, 11, 30, + 39, 2, 254, 10, 30, 39, 2, 254, 9, 30, 39, 2, 254, 8, 30, 39, 2, 254, 7, + 30, 39, 2, 254, 6, 30, 39, 2, 254, 5, 30, 39, 2, 254, 4, 30, 39, 2, 254, + 3, 30, 39, 2, 254, 2, 30, 39, 2, 254, 1, 30, 39, 2, 254, 0, 30, 39, 2, + 253, 255, 30, 39, 2, 253, 254, 30, 39, 2, 253, 253, 30, 39, 2, 253, 252, + 30, 39, 2, 253, 251, 30, 39, 2, 253, 250, 30, 39, 2, 253, 249, 30, 39, 2, + 253, 248, 30, 39, 2, 253, 246, 30, 39, 2, 253, 245, 30, 39, 2, 253, 244, + 30, 39, 2, 253, 243, 30, 39, 2, 253, 242, 30, 39, 2, 253, 240, 30, 39, 2, + 253, 239, 30, 39, 2, 253, 238, 30, 39, 2, 253, 237, 30, 39, 2, 253, 235, + 30, 39, 2, 253, 234, 30, 39, 2, 253, 233, 30, 39, 2, 253, 199, 30, 39, 2, + 253, 197, 30, 39, 2, 253, 195, 30, 39, 2, 253, 193, 30, 39, 2, 253, 191, + 30, 39, 2, 253, 189, 30, 39, 2, 253, 187, 30, 39, 2, 253, 185, 30, 39, 2, + 253, 183, 30, 39, 2, 253, 181, 30, 39, 2, 253, 179, 30, 39, 2, 253, 176, + 30, 39, 2, 253, 174, 30, 39, 2, 253, 172, 30, 39, 2, 253, 170, 30, 39, 2, + 253, 168, 30, 39, 2, 253, 166, 30, 39, 2, 253, 164, 30, 39, 2, 253, 162, + 30, 39, 2, 253, 80, 30, 39, 2, 253, 79, 30, 39, 2, 253, 78, 30, 39, 2, + 253, 77, 30, 39, 2, 253, 76, 30, 39, 2, 253, 75, 30, 39, 2, 253, 73, 30, + 39, 2, 253, 72, 30, 39, 2, 253, 71, 30, 39, 2, 253, 70, 30, 39, 2, 253, + 69, 30, 39, 2, 253, 68, 30, 39, 2, 253, 66, 30, 39, 2, 253, 65, 30, 39, + 2, 253, 61, 30, 39, 2, 253, 60, 30, 39, 2, 253, 58, 30, 39, 2, 253, 57, + 30, 39, 2, 253, 56, 30, 39, 2, 253, 55, 30, 39, 2, 253, 54, 30, 39, 2, + 253, 53, 30, 39, 2, 253, 52, 30, 39, 2, 253, 51, 30, 39, 2, 253, 50, 30, + 39, 2, 253, 49, 30, 39, 2, 253, 48, 30, 39, 2, 253, 47, 30, 39, 2, 253, + 46, 30, 39, 2, 253, 45, 30, 39, 2, 253, 44, 30, 39, 2, 253, 43, 30, 39, + 2, 253, 42, 30, 39, 2, 253, 41, 30, 39, 2, 253, 40, 30, 39, 2, 253, 39, + 30, 39, 2, 253, 38, 30, 39, 2, 253, 37, 30, 39, 2, 253, 36, 30, 39, 2, + 253, 35, 30, 39, 2, 253, 34, 30, 39, 2, 253, 33, 30, 39, 2, 253, 32, 30, + 39, 2, 253, 31, 30, 39, 2, 253, 30, 30, 39, 2, 253, 29, 30, 39, 2, 253, + 28, 30, 39, 2, 253, 27, 30, 39, 2, 253, 26, 30, 39, 2, 253, 25, 30, 39, + 2, 253, 24, 30, 39, 2, 253, 23, 30, 39, 2, 253, 22, 30, 39, 2, 253, 21, + 30, 39, 2, 253, 20, 30, 39, 2, 253, 19, 30, 39, 2, 253, 18, 30, 39, 2, + 253, 17, 30, 39, 2, 253, 16, 30, 39, 2, 253, 15, 30, 39, 2, 253, 14, 30, + 39, 2, 253, 13, 30, 39, 2, 253, 12, 30, 39, 2, 253, 11, 30, 39, 2, 253, + 10, 30, 39, 2, 253, 9, 30, 39, 2, 253, 8, 30, 39, 2, 253, 7, 30, 39, 2, + 253, 6, 30, 39, 2, 253, 5, 30, 39, 2, 253, 4, 30, 39, 2, 253, 3, 30, 39, + 2, 253, 2, 30, 39, 2, 253, 1, 30, 39, 2, 253, 0, 30, 39, 2, 252, 255, 30, + 39, 2, 252, 254, 30, 39, 2, 252, 253, 30, 39, 2, 252, 252, 30, 39, 2, + 252, 251, 30, 39, 2, 252, 250, 30, 39, 2, 252, 249, 30, 39, 2, 252, 248, + 30, 39, 2, 252, 247, 30, 39, 2, 252, 246, 30, 39, 2, 252, 245, 30, 39, 2, + 252, 244, 30, 39, 2, 252, 243, 30, 39, 2, 252, 242, 30, 39, 2, 252, 241, + 30, 39, 2, 252, 240, 30, 39, 2, 252, 239, 30, 39, 2, 252, 238, 30, 39, 2, + 252, 237, 30, 39, 2, 252, 236, 30, 39, 2, 252, 235, 30, 39, 2, 252, 234, + 30, 39, 2, 252, 233, 30, 39, 2, 252, 232, 30, 39, 2, 252, 231, 30, 39, 2, + 252, 230, 30, 39, 2, 252, 229, 30, 39, 2, 252, 228, 30, 39, 2, 252, 227, + 30, 39, 2, 252, 226, 30, 39, 2, 252, 225, 30, 39, 2, 252, 224, 30, 39, 2, + 252, 223, 30, 39, 2, 252, 222, 30, 39, 2, 252, 221, 30, 39, 2, 252, 220, + 30, 39, 2, 252, 219, 30, 39, 2, 252, 218, 30, 39, 2, 252, 217, 30, 39, 2, + 252, 216, 30, 39, 2, 252, 215, 30, 39, 2, 252, 214, 30, 39, 2, 252, 213, + 30, 39, 2, 252, 212, 30, 39, 2, 252, 211, 30, 39, 2, 252, 210, 30, 39, 2, + 252, 209, 30, 39, 2, 252, 208, 30, 39, 2, 252, 207, 30, 39, 2, 252, 206, + 30, 39, 2, 252, 205, 30, 39, 2, 252, 204, 30, 39, 2, 252, 203, 30, 39, 2, + 252, 202, 30, 39, 2, 252, 201, 30, 39, 2, 252, 200, 30, 39, 2, 252, 199, + 30, 39, 2, 252, 198, 63, 30, 39, 2, 252, 197, 250, 112, 30, 39, 2, 252, + 196, 240, 231, 30, 39, 2, 252, 195, 69, 30, 39, 2, 252, 194, 236, 49, 30, + 39, 2, 252, 193, 233, 15, 30, 39, 2, 252, 192, 225, 217, 30, 39, 2, 252, + 191, 225, 80, 30, 39, 2, 252, 190, 159, 30, 39, 2, 252, 189, 223, 87, 30, + 39, 2, 252, 188, 223, 86, 30, 39, 2, 252, 187, 223, 85, 30, 39, 2, 252, + 186, 223, 84, 30, 39, 2, 252, 185, 197, 199, 30, 39, 2, 252, 184, 196, + 222, 30, 39, 2, 252, 183, 196, 148, 30, 39, 2, 252, 182, 214, 124, 30, + 39, 2, 252, 181, 252, 31, 30, 39, 2, 252, 180, 249, 46, 30, 39, 2, 252, + 179, 240, 43, 30, 39, 2, 252, 178, 236, 57, 30, 39, 2, 252, 177, 225, + 193, 30, 39, 2, 252, 176, 30, 39, 2, 252, 175, 30, 39, 2, 252, 174, 30, + 39, 2, 252, 173, 30, 39, 2, 252, 172, 30, 39, 2, 252, 171, 30, 39, 2, + 252, 170, 30, 39, 2, 252, 169, 240, 238, 5, 63, 240, 238, 5, 69, 240, + 238, 5, 68, 240, 238, 5, 72, 240, 238, 5, 66, 240, 238, 5, 225, 214, 240, + 238, 5, 225, 129, 240, 238, 5, 155, 240, 238, 5, 224, 209, 240, 238, 5, + 224, 101, 240, 238, 5, 224, 11, 240, 238, 5, 223, 187, 240, 238, 5, 172, + 240, 238, 5, 222, 197, 240, 238, 5, 222, 109, 240, 238, 5, 222, 7, 240, + 238, 5, 221, 191, 240, 238, 5, 166, 240, 238, 5, 219, 207, 240, 238, 5, + 219, 78, 240, 238, 5, 218, 251, 240, 238, 5, 218, 145, 240, 238, 5, 176, + 240, 238, 5, 217, 118, 240, 238, 5, 216, 223, 240, 238, 5, 216, 50, 240, + 238, 5, 215, 186, 240, 238, 5, 161, 240, 238, 5, 213, 92, 240, 238, 5, + 212, 220, 240, 238, 5, 212, 117, 240, 238, 5, 211, 227, 240, 238, 5, 169, + 240, 238, 5, 210, 183, 240, 238, 5, 210, 72, 240, 238, 5, 209, 232, 240, + 238, 5, 209, 140, 240, 238, 5, 183, 240, 238, 5, 208, 147, 240, 238, 5, + 206, 112, 240, 238, 5, 205, 200, 240, 238, 5, 204, 172, 240, 238, 5, 189, + 240, 238, 5, 203, 68, 240, 238, 5, 202, 122, 240, 238, 5, 149, 240, 238, + 5, 201, 40, 240, 238, 5, 197, 166, 240, 238, 5, 197, 109, 240, 238, 5, + 197, 70, 240, 238, 5, 197, 34, 240, 238, 5, 196, 208, 240, 238, 5, 196, + 202, 240, 238, 5, 195, 115, 240, 238, 5, 195, 11, 226, 88, 250, 255, 1, + 251, 162, 226, 88, 250, 255, 1, 248, 205, 226, 88, 250, 255, 1, 233, 177, + 226, 88, 250, 255, 1, 240, 100, 226, 88, 250, 255, 1, 232, 147, 226, 88, + 250, 255, 1, 197, 117, 226, 88, 250, 255, 1, 195, 92, 226, 88, 250, 255, + 1, 232, 87, 226, 88, 250, 255, 1, 202, 253, 226, 88, 250, 255, 1, 195, + 240, 226, 88, 250, 255, 1, 225, 5, 226, 88, 250, 255, 1, 222, 240, 226, + 88, 250, 255, 1, 219, 171, 226, 88, 250, 255, 1, 215, 138, 226, 88, 250, + 255, 1, 208, 225, 226, 88, 250, 255, 1, 250, 117, 226, 88, 250, 255, 1, + 213, 92, 226, 88, 250, 255, 1, 209, 5, 226, 88, 250, 255, 1, 211, 101, + 226, 88, 250, 255, 1, 210, 109, 226, 88, 250, 255, 1, 206, 211, 226, 88, + 250, 255, 1, 203, 82, 226, 88, 250, 255, 208, 133, 55, 226, 88, 250, 255, + 31, 100, 226, 88, 250, 255, 31, 102, 226, 88, 250, 255, 31, 134, 226, 88, + 250, 255, 31, 203, 23, 226, 88, 250, 255, 31, 200, 234, 226, 88, 250, + 255, 31, 97, 231, 57, 226, 88, 250, 255, 31, 97, 170, 226, 88, 250, 255, + 31, 203, 24, 170, 213, 204, 1, 251, 162, 213, 204, 1, 248, 205, 213, 204, + 1, 233, 177, 213, 204, 1, 240, 100, 213, 204, 1, 232, 147, 213, 204, 1, + 197, 117, 213, 204, 1, 195, 92, 213, 204, 1, 232, 87, 213, 204, 1, 202, + 253, 213, 204, 1, 195, 240, 213, 204, 1, 225, 5, 213, 204, 1, 222, 240, + 213, 204, 1, 219, 171, 213, 204, 1, 48, 215, 138, 213, 204, 1, 215, 138, + 213, 204, 1, 208, 225, 213, 204, 1, 250, 117, 213, 204, 1, 213, 92, 213, + 204, 1, 209, 5, 213, 204, 1, 211, 101, 213, 204, 1, 210, 109, 213, 204, + 1, 206, 211, 213, 204, 1, 203, 82, 213, 204, 222, 179, 235, 77, 213, 204, + 210, 17, 235, 77, 213, 204, 31, 100, 213, 204, 31, 102, 213, 204, 31, + 134, 213, 204, 31, 136, 213, 204, 31, 146, 213, 204, 31, 203, 23, 213, + 204, 31, 200, 234, 217, 240, 1, 48, 251, 162, 217, 240, 1, 251, 162, 217, + 240, 1, 48, 248, 205, 217, 240, 1, 248, 205, 217, 240, 1, 233, 177, 217, + 240, 1, 240, 100, 217, 240, 1, 48, 232, 147, 217, 240, 1, 232, 147, 217, + 240, 1, 197, 117, 217, 240, 1, 195, 92, 217, 240, 1, 232, 87, 217, 240, + 1, 202, 253, 217, 240, 1, 48, 195, 240, 217, 240, 1, 195, 240, 217, 240, + 1, 48, 225, 5, 217, 240, 1, 225, 5, 217, 240, 1, 48, 222, 240, 217, 240, + 1, 222, 240, 217, 240, 1, 48, 219, 171, 217, 240, 1, 219, 171, 217, 240, + 1, 48, 215, 138, 217, 240, 1, 215, 138, 217, 240, 1, 208, 225, 217, 240, + 1, 250, 117, 217, 240, 1, 213, 92, 217, 240, 1, 209, 5, 217, 240, 1, 211, + 101, 217, 240, 1, 210, 109, 217, 240, 1, 48, 206, 211, 217, 240, 1, 206, + 211, 217, 240, 1, 203, 82, 217, 240, 31, 100, 217, 240, 31, 102, 217, + 240, 31, 134, 217, 240, 31, 136, 217, 240, 241, 47, 31, 136, 217, 240, + 31, 146, 217, 240, 31, 203, 23, 217, 240, 31, 200, 234, 217, 240, 31, 97, + 231, 57, 232, 160, 1, 251, 162, 232, 160, 1, 248, 205, 232, 160, 1, 233, + 177, 232, 160, 1, 240, 99, 232, 160, 1, 232, 147, 232, 160, 1, 197, 117, + 232, 160, 1, 195, 90, 232, 160, 1, 232, 87, 232, 160, 1, 202, 253, 232, + 160, 1, 195, 240, 232, 160, 1, 225, 5, 232, 160, 1, 222, 240, 232, 160, + 1, 219, 171, 232, 160, 1, 215, 138, 232, 160, 1, 208, 225, 232, 160, 1, + 250, 115, 232, 160, 1, 213, 92, 232, 160, 1, 209, 5, 232, 160, 1, 211, + 101, 232, 160, 1, 206, 211, 232, 160, 1, 203, 82, 232, 160, 31, 100, 232, + 160, 31, 146, 232, 160, 31, 203, 23, 232, 160, 31, 200, 234, 232, 160, + 31, 97, 231, 57, 212, 232, 1, 251, 159, 212, 232, 1, 248, 208, 212, 232, + 1, 234, 96, 212, 232, 1, 239, 214, 212, 232, 1, 232, 147, 212, 232, 1, + 197, 124, 212, 232, 1, 195, 108, 212, 232, 1, 232, 89, 212, 232, 1, 203, + 1, 212, 232, 1, 195, 241, 212, 232, 1, 225, 35, 212, 232, 1, 222, 246, + 212, 232, 1, 219, 171, 212, 232, 1, 215, 138, 212, 232, 1, 207, 99, 212, + 232, 1, 251, 194, 212, 232, 1, 213, 92, 212, 232, 1, 209, 7, 212, 232, 1, + 211, 106, 212, 232, 1, 209, 196, 212, 232, 1, 206, 211, 212, 232, 1, 203, + 89, 212, 232, 31, 100, 212, 232, 31, 203, 23, 212, 232, 31, 200, 234, + 212, 232, 31, 97, 231, 57, 212, 232, 31, 102, 212, 232, 31, 134, 212, + 232, 197, 9, 207, 90, 221, 148, 1, 63, 221, 148, 1, 250, 112, 221, 148, + 1, 234, 190, 221, 148, 1, 240, 231, 221, 148, 1, 69, 221, 148, 1, 199, + 230, 221, 148, 1, 68, 221, 148, 1, 196, 148, 221, 148, 1, 225, 80, 221, + 148, 1, 159, 221, 148, 1, 221, 136, 221, 148, 1, 218, 55, 221, 148, 1, + 72, 221, 148, 1, 144, 221, 148, 1, 205, 83, 221, 148, 1, 203, 216, 221, + 148, 1, 66, 221, 148, 1, 236, 49, 221, 148, 1, 211, 167, 221, 148, 1, + 209, 80, 221, 148, 1, 201, 81, 221, 148, 1, 251, 106, 221, 148, 1, 236, + 230, 221, 148, 1, 221, 151, 221, 148, 1, 216, 87, 221, 148, 1, 247, 207, + 221, 148, 201, 177, 78, 140, 232, 57, 1, 63, 140, 232, 57, 1, 69, 140, + 232, 57, 1, 68, 140, 232, 57, 1, 72, 140, 232, 57, 1, 164, 140, 232, 57, + 1, 197, 166, 140, 232, 57, 1, 249, 145, 140, 232, 57, 1, 249, 144, 140, + 232, 57, 1, 161, 140, 232, 57, 1, 166, 140, 232, 57, 1, 176, 140, 232, + 57, 1, 217, 255, 140, 232, 57, 1, 217, 118, 140, 232, 57, 1, 217, 116, + 140, 232, 57, 1, 169, 140, 232, 57, 1, 210, 250, 140, 232, 57, 1, 172, + 140, 232, 57, 1, 224, 146, 140, 232, 57, 1, 232, 80, 140, 232, 57, 1, + 183, 140, 232, 57, 1, 209, 21, 140, 232, 57, 1, 208, 147, 140, 232, 57, + 1, 155, 140, 232, 57, 1, 211, 159, 140, 232, 57, 1, 189, 140, 232, 57, 1, + 203, 167, 140, 232, 57, 1, 203, 68, 140, 232, 57, 1, 203, 66, 140, 232, + 57, 1, 149, 140, 232, 57, 1, 240, 136, 140, 232, 57, 16, 199, 28, 140, + 232, 57, 16, 199, 27, 140, 241, 13, 1, 63, 140, 241, 13, 1, 69, 140, 241, + 13, 1, 68, 140, 241, 13, 1, 72, 140, 241, 13, 1, 164, 140, 241, 13, 1, + 197, 166, 140, 241, 13, 1, 249, 145, 140, 241, 13, 1, 161, 140, 241, 13, + 1, 166, 140, 241, 13, 1, 176, 140, 241, 13, 1, 217, 118, 140, 241, 13, 1, + 169, 140, 241, 13, 1, 172, 140, 241, 13, 1, 224, 146, 140, 241, 13, 1, + 232, 80, 140, 241, 13, 1, 183, 140, 241, 13, 1, 250, 251, 183, 140, 241, + 13, 1, 208, 147, 140, 241, 13, 1, 155, 140, 241, 13, 1, 211, 159, 140, + 241, 13, 1, 189, 140, 241, 13, 1, 203, 68, 140, 241, 13, 1, 149, 140, + 241, 13, 1, 240, 136, 140, 241, 13, 191, 236, 253, 200, 241, 140, 241, + 13, 191, 97, 232, 225, 140, 241, 13, 221, 248, 209, 238, 140, 241, 13, + 221, 248, 226, 93, 140, 241, 13, 31, 100, 140, 241, 13, 31, 102, 140, + 241, 13, 31, 134, 140, 241, 13, 31, 136, 140, 241, 13, 31, 146, 140, 241, + 13, 31, 167, 140, 241, 13, 31, 178, 140, 241, 13, 31, 171, 140, 241, 13, + 31, 182, 140, 241, 13, 31, 203, 23, 140, 241, 13, 31, 200, 234, 140, 241, + 13, 31, 202, 177, 140, 241, 13, 31, 235, 14, 140, 241, 13, 31, 235, 145, + 140, 241, 13, 31, 206, 13, 140, 241, 13, 31, 207, 65, 140, 241, 13, 31, + 97, 231, 57, 140, 241, 13, 31, 99, 231, 57, 140, 241, 13, 31, 115, 231, + 57, 140, 241, 13, 31, 235, 7, 231, 57, 140, 241, 13, 31, 235, 101, 231, + 57, 140, 241, 13, 31, 206, 29, 231, 57, 140, 241, 13, 31, 207, 71, 231, + 57, 140, 241, 13, 31, 237, 31, 231, 57, 140, 241, 13, 31, 216, 179, 231, + 57, 140, 241, 13, 31, 97, 170, 140, 241, 13, 31, 99, 170, 140, 241, 13, + 31, 115, 170, 140, 241, 13, 31, 235, 7, 170, 140, 241, 13, 31, 235, 101, + 170, 140, 241, 13, 31, 206, 29, 170, 140, 241, 13, 31, 207, 71, 170, 140, + 241, 13, 31, 237, 31, 170, 140, 241, 13, 31, 216, 179, 170, 140, 241, 13, + 31, 203, 24, 170, 140, 241, 13, 31, 200, 235, 170, 140, 241, 13, 31, 202, + 178, 170, 140, 241, 13, 31, 235, 15, 170, 140, 241, 13, 31, 235, 146, + 170, 140, 241, 13, 31, 206, 14, 170, 140, 241, 13, 31, 207, 66, 170, 140, + 241, 13, 31, 237, 21, 170, 140, 241, 13, 31, 216, 175, 170, 140, 241, 13, + 31, 97, 231, 58, 170, 140, 241, 13, 31, 99, 231, 58, 170, 140, 241, 13, + 31, 115, 231, 58, 170, 140, 241, 13, 31, 235, 7, 231, 58, 170, 140, 241, + 13, 31, 235, 101, 231, 58, 170, 140, 241, 13, 31, 206, 29, 231, 58, 170, + 140, 241, 13, 31, 207, 71, 231, 58, 170, 140, 241, 13, 31, 237, 31, 231, + 58, 170, 140, 241, 13, 31, 216, 179, 231, 58, 170, 140, 241, 13, 191, 97, + 200, 242, 140, 241, 13, 191, 99, 200, 241, 140, 241, 13, 191, 115, 200, + 241, 140, 241, 13, 191, 235, 7, 200, 241, 140, 241, 13, 191, 235, 101, + 200, 241, 140, 241, 13, 191, 206, 29, 200, 241, 140, 241, 13, 191, 207, + 71, 200, 241, 140, 241, 13, 191, 237, 31, 200, 241, 140, 241, 13, 191, + 216, 179, 200, 241, 140, 241, 13, 191, 203, 24, 200, 241, 224, 133, 1, + 63, 224, 133, 18, 2, 68, 224, 133, 18, 2, 66, 224, 133, 18, 2, 110, 144, + 224, 133, 18, 2, 69, 224, 133, 18, 2, 72, 224, 133, 18, 222, 158, 78, + 224, 133, 2, 52, 210, 3, 60, 224, 133, 2, 251, 51, 224, 133, 2, 199, 2, + 224, 133, 1, 155, 224, 133, 1, 224, 146, 224, 133, 1, 234, 123, 224, 133, + 1, 233, 230, 224, 133, 1, 247, 174, 224, 133, 1, 247, 16, 224, 133, 1, + 225, 214, 224, 133, 1, 215, 109, 224, 133, 1, 201, 78, 224, 133, 1, 201, + 66, 224, 133, 1, 240, 41, 224, 133, 1, 240, 25, 224, 133, 1, 216, 86, + 224, 133, 1, 189, 224, 133, 1, 202, 233, 224, 133, 1, 240, 136, 224, 133, + 1, 239, 176, 224, 133, 1, 176, 224, 133, 1, 161, 224, 133, 1, 213, 6, + 224, 133, 1, 249, 145, 224, 133, 1, 248, 197, 224, 133, 1, 166, 224, 133, + 1, 164, 224, 133, 1, 169, 224, 133, 1, 172, 224, 133, 1, 199, 152, 224, + 133, 1, 207, 50, 224, 133, 1, 205, 80, 224, 133, 1, 183, 224, 133, 1, + 195, 115, 224, 133, 1, 142, 224, 133, 1, 224, 36, 224, 133, 1, 201, 46, + 224, 133, 1, 201, 47, 224, 133, 1, 199, 35, 224, 133, 2, 249, 80, 57, + 224, 133, 2, 247, 88, 224, 133, 2, 76, 60, 224, 133, 199, 7, 224, 133, + 17, 100, 224, 133, 17, 102, 224, 133, 17, 134, 224, 133, 17, 136, 224, + 133, 31, 203, 23, 224, 133, 31, 200, 234, 224, 133, 31, 97, 231, 57, 224, + 133, 31, 97, 170, 224, 133, 191, 97, 232, 225, 224, 133, 211, 214, 238, + 253, 224, 133, 211, 214, 4, 244, 249, 224, 133, 211, 214, 244, 249, 224, + 133, 211, 214, 241, 72, 154, 224, 133, 211, 214, 220, 55, 224, 133, 211, + 214, 221, 213, 224, 133, 211, 214, 240, 88, 224, 133, 211, 214, 52, 240, + 88, 224, 133, 211, 214, 222, 69, 37, 205, 159, 251, 10, 1, 232, 147, 37, + 205, 159, 251, 10, 1, 222, 240, 37, 205, 159, 251, 10, 1, 232, 87, 37, + 205, 159, 251, 10, 1, 219, 171, 37, 205, 159, 251, 10, 1, 211, 101, 37, + 205, 159, 251, 10, 1, 197, 117, 37, 205, 159, 251, 10, 1, 206, 211, 37, + 205, 159, 251, 10, 1, 210, 109, 37, 205, 159, 251, 10, 1, 248, 205, 37, + 205, 159, 251, 10, 1, 203, 82, 37, 205, 159, 251, 10, 1, 208, 199, 37, + 205, 159, 251, 10, 1, 225, 5, 37, 205, 159, 251, 10, 1, 215, 138, 37, + 205, 159, 251, 10, 1, 224, 128, 37, 205, 159, 251, 10, 1, 209, 5, 37, + 205, 159, 251, 10, 1, 208, 225, 37, 205, 159, 251, 10, 1, 235, 189, 37, + 205, 159, 251, 10, 1, 251, 164, 37, 205, 159, 251, 10, 1, 250, 115, 37, + 205, 159, 251, 10, 1, 239, 173, 37, 205, 159, 251, 10, 1, 233, 177, 37, + 205, 159, 251, 10, 1, 240, 100, 37, 205, 159, 251, 10, 1, 233, 218, 37, + 205, 159, 251, 10, 1, 202, 253, 37, 205, 159, 251, 10, 1, 195, 90, 37, + 205, 159, 251, 10, 1, 239, 170, 37, 205, 159, 251, 10, 1, 195, 240, 37, + 205, 159, 251, 10, 1, 202, 219, 37, 205, 159, 251, 10, 1, 202, 198, 37, + 205, 159, 251, 10, 31, 100, 37, 205, 159, 251, 10, 31, 235, 145, 37, 205, + 159, 251, 10, 156, 226, 68, 37, 173, 251, 10, 1, 232, 113, 37, 173, 251, + 10, 1, 222, 249, 37, 173, 251, 10, 1, 232, 236, 37, 173, 251, 10, 1, 219, + 185, 37, 173, 251, 10, 1, 211, 152, 37, 173, 251, 10, 1, 197, 117, 37, + 173, 251, 10, 1, 236, 149, 37, 173, 251, 10, 1, 210, 142, 37, 173, 251, + 10, 1, 248, 239, 37, 173, 251, 10, 1, 203, 41, 37, 173, 251, 10, 1, 236, + 150, 37, 173, 251, 10, 1, 225, 35, 37, 173, 251, 10, 1, 216, 31, 37, 173, + 251, 10, 1, 224, 142, 37, 173, 251, 10, 1, 209, 8, 37, 173, 251, 10, 1, + 236, 148, 37, 173, 251, 10, 1, 235, 176, 37, 173, 251, 10, 1, 251, 164, + 37, 173, 251, 10, 1, 251, 194, 37, 173, 251, 10, 1, 240, 130, 37, 173, + 251, 10, 1, 234, 39, 37, 173, 251, 10, 1, 240, 107, 37, 173, 251, 10, 1, + 233, 225, 37, 173, 251, 10, 1, 203, 139, 37, 173, 251, 10, 1, 195, 106, + 37, 173, 251, 10, 1, 202, 225, 37, 173, 251, 10, 1, 196, 64, 37, 173, + 251, 10, 1, 202, 213, 37, 173, 251, 10, 1, 195, 109, 37, 173, 251, 10, + 31, 100, 37, 173, 251, 10, 31, 203, 23, 37, 173, 251, 10, 31, 200, 234, + 220, 53, 1, 251, 162, 220, 53, 1, 248, 205, 220, 53, 1, 248, 190, 220, + 53, 1, 233, 177, 220, 53, 1, 233, 203, 220, 53, 1, 240, 100, 220, 53, 1, + 232, 147, 220, 53, 1, 197, 117, 220, 53, 2, 200, 104, 220, 53, 1, 195, + 92, 220, 53, 1, 195, 67, 220, 53, 1, 225, 195, 220, 53, 1, 225, 176, 220, + 53, 1, 232, 87, 220, 53, 1, 202, 253, 220, 53, 1, 195, 240, 220, 53, 1, + 225, 5, 220, 53, 1, 196, 205, 220, 53, 1, 224, 135, 220, 53, 1, 222, 240, + 220, 53, 1, 239, 169, 220, 53, 1, 202, 224, 220, 53, 1, 219, 171, 220, + 53, 1, 215, 138, 220, 53, 1, 208, 225, 220, 53, 1, 250, 117, 220, 53, 1, + 252, 120, 220, 53, 1, 213, 92, 220, 53, 1, 235, 189, 220, 53, 1, 209, 5, + 220, 53, 1, 211, 101, 220, 53, 1, 196, 182, 220, 53, 1, 211, 128, 220, + 53, 1, 210, 109, 220, 53, 1, 206, 211, 220, 53, 1, 205, 48, 220, 53, 1, + 203, 82, 220, 53, 252, 30, 117, 57, 220, 53, 252, 30, 117, 60, 220, 53, + 31, 100, 220, 53, 31, 146, 220, 53, 31, 203, 23, 220, 53, 31, 200, 234, + 220, 53, 31, 97, 231, 57, 220, 53, 211, 214, 205, 7, 220, 53, 211, 214, + 235, 77, 220, 53, 211, 214, 52, 76, 197, 39, 238, 253, 220, 53, 211, 214, + 76, 197, 39, 238, 253, 220, 53, 211, 214, 238, 253, 220, 53, 211, 214, + 99, 238, 250, 220, 53, 211, 214, 222, 76, 235, 134, 250, 129, 1, 63, 250, + 129, 1, 252, 168, 250, 129, 1, 251, 49, 250, 129, 1, 252, 126, 250, 129, + 1, 251, 106, 250, 129, 1, 252, 128, 250, 129, 1, 251, 245, 250, 129, 1, + 251, 241, 250, 129, 1, 69, 250, 129, 1, 237, 54, 250, 129, 1, 72, 250, + 129, 1, 214, 102, 250, 129, 1, 68, 250, 129, 1, 226, 120, 250, 129, 1, + 66, 250, 129, 1, 199, 245, 250, 129, 1, 224, 209, 250, 129, 1, 196, 202, + 250, 129, 1, 196, 162, 250, 129, 1, 196, 173, 250, 129, 1, 234, 48, 250, + 129, 1, 234, 5, 250, 129, 1, 233, 216, 250, 129, 1, 247, 57, 250, 129, 1, + 225, 193, 250, 129, 1, 203, 68, 250, 129, 1, 202, 217, 250, 129, 1, 239, + 252, 250, 129, 1, 239, 167, 250, 129, 1, 201, 73, 250, 129, 1, 213, 92, + 250, 129, 1, 235, 189, 250, 129, 1, 249, 9, 250, 129, 1, 248, 192, 250, + 129, 1, 217, 58, 250, 129, 1, 216, 229, 250, 129, 1, 216, 230, 250, 129, + 1, 217, 118, 250, 129, 1, 215, 98, 250, 129, 1, 216, 81, 250, 129, 1, + 219, 207, 250, 129, 1, 231, 243, 250, 129, 1, 195, 165, 250, 129, 1, 196, + 69, 250, 129, 1, 199, 118, 250, 129, 1, 210, 183, 250, 129, 1, 222, 197, + 250, 129, 1, 208, 147, 250, 129, 1, 195, 88, 250, 129, 1, 206, 255, 250, + 129, 1, 195, 65, 250, 129, 1, 206, 119, 250, 129, 1, 205, 49, 250, 129, + 1, 232, 147, 250, 129, 252, 30, 78, 202, 70, 99, 238, 251, 127, 97, 76, + 211, 213, 4, 99, 238, 251, 127, 97, 76, 211, 213, 222, 228, 99, 238, 251, + 127, 97, 76, 211, 213, 222, 228, 97, 76, 127, 99, 238, 251, 211, 213, + 222, 228, 99, 209, 255, 127, 97, 210, 3, 211, 213, 222, 228, 97, 210, 3, + 127, 99, 209, 255, 211, 213, 226, 46, 213, 133, 1, 251, 162, 226, 46, + 213, 133, 1, 248, 205, 226, 46, 213, 133, 1, 233, 177, 226, 46, 213, 133, + 1, 240, 100, 226, 46, 213, 133, 1, 232, 147, 226, 46, 213, 133, 1, 197, + 117, 226, 46, 213, 133, 1, 195, 92, 226, 46, 213, 133, 1, 232, 87, 226, + 46, 213, 133, 1, 202, 253, 226, 46, 213, 133, 1, 195, 240, 226, 46, 213, + 133, 1, 225, 5, 226, 46, 213, 133, 1, 222, 240, 226, 46, 213, 133, 1, + 219, 171, 226, 46, 213, 133, 1, 215, 138, 226, 46, 213, 133, 1, 208, 225, + 226, 46, 213, 133, 1, 250, 117, 226, 46, 213, 133, 1, 213, 92, 226, 46, + 213, 133, 1, 209, 5, 226, 46, 213, 133, 1, 211, 101, 226, 46, 213, 133, + 1, 210, 109, 226, 46, 213, 133, 1, 206, 211, 226, 46, 213, 133, 1, 203, + 82, 226, 46, 213, 133, 31, 100, 226, 46, 213, 133, 31, 102, 226, 46, 213, + 133, 31, 134, 226, 46, 213, 133, 31, 136, 226, 46, 213, 133, 31, 203, 23, + 226, 46, 213, 133, 31, 200, 234, 226, 46, 213, 133, 31, 97, 231, 57, 226, + 46, 213, 133, 31, 97, 170, 226, 46, 213, 222, 1, 251, 162, 226, 46, 213, + 222, 1, 248, 205, 226, 46, 213, 222, 1, 233, 177, 226, 46, 213, 222, 1, + 240, 100, 226, 46, 213, 222, 1, 232, 147, 226, 46, 213, 222, 1, 197, 116, + 226, 46, 213, 222, 1, 195, 92, 226, 46, 213, 222, 1, 232, 87, 226, 46, + 213, 222, 1, 202, 253, 226, 46, 213, 222, 1, 195, 240, 226, 46, 213, 222, + 1, 225, 5, 226, 46, 213, 222, 1, 222, 240, 226, 46, 213, 222, 1, 219, + 170, 226, 46, 213, 222, 1, 215, 138, 226, 46, 213, 222, 1, 208, 225, 226, + 46, 213, 222, 1, 213, 92, 226, 46, 213, 222, 1, 209, 5, 226, 46, 213, + 222, 1, 206, 211, 226, 46, 213, 222, 1, 203, 82, 226, 46, 213, 222, 31, + 100, 226, 46, 213, 222, 31, 102, 226, 46, 213, 222, 31, 134, 226, 46, + 213, 222, 31, 136, 226, 46, 213, 222, 31, 203, 23, 226, 46, 213, 222, 31, + 200, 234, 226, 46, 213, 222, 31, 97, 231, 57, 226, 46, 213, 222, 31, 97, + 170, 211, 239, 213, 222, 1, 251, 162, 211, 239, 213, 222, 1, 248, 205, + 211, 239, 213, 222, 1, 233, 177, 211, 239, 213, 222, 1, 240, 100, 211, + 239, 213, 222, 1, 232, 147, 211, 239, 213, 222, 1, 197, 116, 211, 239, + 213, 222, 1, 195, 92, 211, 239, 213, 222, 1, 232, 87, 211, 239, 213, 222, + 1, 195, 240, 211, 239, 213, 222, 1, 225, 5, 211, 239, 213, 222, 1, 222, + 240, 211, 239, 213, 222, 1, 219, 170, 211, 239, 213, 222, 1, 215, 138, + 211, 239, 213, 222, 1, 208, 225, 211, 239, 213, 222, 1, 213, 92, 211, + 239, 213, 222, 1, 209, 5, 211, 239, 213, 222, 1, 206, 211, 211, 239, 213, + 222, 1, 203, 82, 211, 239, 213, 222, 208, 133, 78, 211, 239, 213, 222, + 163, 208, 133, 78, 211, 239, 213, 222, 235, 7, 238, 251, 3, 241, 61, 211, + 239, 213, 222, 235, 7, 238, 251, 3, 238, 253, 211, 239, 213, 222, 31, + 100, 211, 239, 213, 222, 31, 102, 211, 239, 213, 222, 31, 134, 211, 239, + 213, 222, 31, 136, 211, 239, 213, 222, 31, 203, 23, 211, 239, 213, 222, + 31, 200, 234, 211, 239, 213, 222, 31, 97, 231, 57, 37, 201, 7, 1, 214, + 61, 63, 37, 201, 7, 1, 196, 57, 63, 37, 201, 7, 1, 196, 57, 251, 245, 37, + 201, 7, 1, 214, 61, 68, 37, 201, 7, 1, 196, 57, 68, 37, 201, 7, 1, 196, + 57, 69, 37, 201, 7, 1, 214, 61, 72, 37, 201, 7, 1, 214, 61, 214, 164, 37, + 201, 7, 1, 196, 57, 214, 164, 37, 201, 7, 1, 214, 61, 252, 117, 37, 201, + 7, 1, 196, 57, 252, 117, 37, 201, 7, 1, 214, 61, 251, 244, 37, 201, 7, 1, + 196, 57, 251, 244, 37, 201, 7, 1, 214, 61, 251, 217, 37, 201, 7, 1, 196, + 57, 251, 217, 37, 201, 7, 1, 214, 61, 251, 239, 37, 201, 7, 1, 196, 57, + 251, 239, 37, 201, 7, 1, 214, 61, 252, 6, 37, 201, 7, 1, 196, 57, 252, 6, + 37, 201, 7, 1, 214, 61, 251, 243, 37, 201, 7, 1, 214, 61, 236, 56, 37, + 201, 7, 1, 196, 57, 236, 56, 37, 201, 7, 1, 214, 61, 250, 122, 37, 201, + 7, 1, 196, 57, 250, 122, 37, 201, 7, 1, 214, 61, 251, 226, 37, 201, 7, 1, + 196, 57, 251, 226, 37, 201, 7, 1, 214, 61, 251, 237, 37, 201, 7, 1, 196, + 57, 251, 237, 37, 201, 7, 1, 214, 61, 214, 162, 37, 201, 7, 1, 196, 57, + 214, 162, 37, 201, 7, 1, 214, 61, 251, 173, 37, 201, 7, 1, 196, 57, 251, + 173, 37, 201, 7, 1, 214, 61, 251, 236, 37, 201, 7, 1, 214, 61, 236, 245, + 37, 201, 7, 1, 214, 61, 236, 241, 37, 201, 7, 1, 214, 61, 251, 106, 37, + 201, 7, 1, 214, 61, 251, 234, 37, 201, 7, 1, 196, 57, 251, 234, 37, 201, + 7, 1, 214, 61, 236, 207, 37, 201, 7, 1, 196, 57, 236, 207, 37, 201, 7, 1, + 214, 61, 236, 227, 37, 201, 7, 1, 196, 57, 236, 227, 37, 201, 7, 1, 214, + 61, 236, 193, 37, 201, 7, 1, 196, 57, 236, 193, 37, 201, 7, 1, 196, 57, + 251, 97, 37, 201, 7, 1, 214, 61, 236, 215, 37, 201, 7, 1, 196, 57, 251, + 233, 37, 201, 7, 1, 214, 61, 236, 183, 37, 201, 7, 1, 214, 61, 214, 93, + 37, 201, 7, 1, 214, 61, 230, 203, 37, 201, 7, 1, 214, 61, 237, 62, 37, + 201, 7, 1, 196, 57, 237, 62, 37, 201, 7, 1, 214, 61, 251, 18, 37, 201, 7, + 1, 196, 57, 251, 18, 37, 201, 7, 1, 214, 61, 226, 3, 37, 201, 7, 1, 196, + 57, 226, 3, 37, 201, 7, 1, 214, 61, 214, 74, 37, 201, 7, 1, 196, 57, 214, + 74, 37, 201, 7, 1, 214, 61, 251, 14, 37, 201, 7, 1, 196, 57, 251, 14, 37, + 201, 7, 1, 214, 61, 251, 232, 37, 201, 7, 1, 214, 61, 250, 202, 37, 201, + 7, 1, 214, 61, 251, 230, 37, 201, 7, 1, 214, 61, 250, 195, 37, 201, 7, 1, + 196, 57, 250, 195, 37, 201, 7, 1, 214, 61, 236, 141, 37, 201, 7, 1, 196, + 57, 236, 141, 37, 201, 7, 1, 214, 61, 250, 168, 37, 201, 7, 1, 196, 57, + 250, 168, 37, 201, 7, 1, 214, 61, 251, 227, 37, 201, 7, 1, 196, 57, 251, + 227, 37, 201, 7, 1, 214, 61, 214, 49, 37, 201, 7, 1, 214, 61, 249, 63, + 37, 160, 6, 1, 63, 37, 160, 6, 1, 252, 168, 37, 160, 6, 1, 237, 64, 37, + 160, 6, 1, 251, 118, 37, 160, 6, 1, 237, 62, 37, 160, 6, 1, 236, 227, 37, + 160, 6, 1, 237, 59, 37, 160, 6, 1, 237, 58, 37, 160, 6, 1, 251, 100, 37, + 160, 6, 1, 69, 37, 160, 6, 1, 244, 204, 69, 37, 160, 6, 1, 237, 54, 37, + 160, 6, 1, 237, 47, 37, 160, 6, 1, 237, 46, 37, 160, 6, 1, 237, 43, 37, + 160, 6, 1, 237, 40, 37, 160, 6, 1, 68, 37, 160, 6, 1, 226, 120, 37, 160, + 6, 1, 237, 17, 37, 160, 6, 1, 237, 14, 37, 160, 6, 1, 251, 181, 37, 160, + 6, 1, 200, 45, 37, 160, 6, 1, 237, 7, 37, 160, 6, 1, 236, 244, 37, 160, + 6, 1, 236, 241, 37, 160, 6, 1, 236, 230, 37, 160, 6, 1, 236, 193, 37, + 160, 6, 1, 72, 37, 160, 6, 1, 214, 102, 37, 160, 6, 1, 216, 186, 214, + 164, 37, 160, 6, 1, 209, 130, 214, 164, 37, 160, 6, 1, 214, 163, 37, 160, + 6, 1, 236, 183, 37, 160, 6, 1, 236, 235, 37, 160, 6, 1, 236, 163, 37, + 160, 6, 1, 206, 182, 236, 163, 37, 160, 6, 1, 236, 151, 37, 160, 6, 1, + 236, 130, 37, 160, 6, 1, 236, 128, 37, 160, 6, 1, 236, 207, 37, 160, 6, + 1, 236, 117, 37, 160, 6, 1, 237, 60, 37, 160, 6, 1, 66, 37, 160, 6, 1, + 199, 245, 37, 160, 6, 1, 216, 186, 200, 99, 37, 160, 6, 1, 209, 130, 200, + 99, 37, 160, 6, 1, 236, 104, 37, 160, 6, 1, 236, 56, 37, 160, 6, 1, 236, + 51, 37, 160, 6, 1, 236, 206, 55, 37, 160, 6, 1, 200, 4, 37, 160, 4, 1, + 63, 37, 160, 4, 1, 252, 168, 37, 160, 4, 1, 237, 64, 37, 160, 4, 1, 251, + 118, 37, 160, 4, 1, 237, 62, 37, 160, 4, 1, 236, 227, 37, 160, 4, 1, 237, + 59, 37, 160, 4, 1, 237, 58, 37, 160, 4, 1, 251, 100, 37, 160, 4, 1, 69, + 37, 160, 4, 1, 244, 204, 69, 37, 160, 4, 1, 237, 54, 37, 160, 4, 1, 237, + 47, 37, 160, 4, 1, 237, 46, 37, 160, 4, 1, 237, 43, 37, 160, 4, 1, 237, + 40, 37, 160, 4, 1, 68, 37, 160, 4, 1, 226, 120, 37, 160, 4, 1, 237, 17, + 37, 160, 4, 1, 237, 14, 37, 160, 4, 1, 251, 181, 37, 160, 4, 1, 200, 45, + 37, 160, 4, 1, 237, 7, 37, 160, 4, 1, 236, 244, 37, 160, 4, 1, 236, 241, + 37, 160, 4, 1, 236, 230, 37, 160, 4, 1, 236, 193, 37, 160, 4, 1, 72, 37, + 160, 4, 1, 214, 102, 37, 160, 4, 1, 216, 186, 214, 164, 37, 160, 4, 1, + 209, 130, 214, 164, 37, 160, 4, 1, 214, 163, 37, 160, 4, 1, 236, 183, 37, + 160, 4, 1, 236, 235, 37, 160, 4, 1, 236, 163, 37, 160, 4, 1, 206, 182, + 236, 163, 37, 160, 4, 1, 236, 151, 37, 160, 4, 1, 236, 130, 37, 160, 4, + 1, 236, 128, 37, 160, 4, 1, 236, 207, 37, 160, 4, 1, 236, 117, 37, 160, + 4, 1, 237, 60, 37, 160, 4, 1, 66, 37, 160, 4, 1, 199, 245, 37, 160, 4, 1, + 216, 186, 200, 99, 37, 160, 4, 1, 209, 130, 200, 99, 37, 160, 4, 1, 236, + 104, 37, 160, 4, 1, 236, 56, 37, 160, 4, 1, 236, 51, 37, 160, 4, 1, 236, + 206, 55, 37, 160, 4, 1, 200, 4, 37, 160, 31, 100, 37, 160, 31, 146, 37, + 160, 31, 203, 23, 37, 160, 31, 235, 145, 37, 160, 31, 97, 231, 57, 37, + 160, 31, 97, 170, 232, 180, 209, 214, 1, 63, 232, 180, 209, 214, 1, 249, + 145, 232, 180, 209, 214, 1, 161, 232, 180, 209, 214, 1, 189, 232, 180, + 209, 214, 1, 201, 78, 232, 180, 209, 214, 1, 225, 214, 232, 180, 209, + 214, 1, 247, 174, 232, 180, 209, 214, 1, 142, 232, 180, 209, 214, 1, 224, + 146, 232, 180, 209, 214, 1, 235, 239, 232, 180, 209, 214, 1, 240, 136, + 232, 180, 209, 214, 1, 240, 41, 232, 180, 209, 214, 1, 169, 232, 180, + 209, 214, 1, 209, 181, 232, 180, 209, 214, 1, 195, 115, 232, 180, 209, + 214, 1, 183, 232, 180, 209, 214, 1, 207, 50, 232, 180, 209, 214, 1, 155, + 232, 180, 209, 214, 1, 234, 123, 232, 180, 209, 214, 1, 172, 232, 180, + 209, 214, 1, 166, 232, 180, 209, 214, 1, 176, 232, 180, 209, 214, 1, 197, + 166, 232, 180, 209, 214, 1, 224, 72, 197, 166, 232, 180, 209, 214, 1, + 164, 232, 180, 209, 214, 1, 224, 72, 164, 232, 180, 209, 214, 1, 217, 71, + 232, 180, 209, 214, 1, 215, 109, 232, 180, 209, 214, 1, 199, 152, 232, + 180, 209, 214, 18, 63, 232, 180, 209, 214, 18, 68, 232, 180, 209, 214, + 18, 66, 232, 180, 209, 214, 18, 69, 232, 180, 209, 214, 18, 72, 232, 180, + 209, 214, 117, 208, 245, 232, 180, 209, 214, 117, 218, 1, 224, 113, 232, + 180, 209, 214, 2, 232, 174, 232, 180, 209, 214, 2, 203, 138, 232, 180, + 209, 214, 2, 203, 113, 232, 180, 209, 214, 2, 203, 95, 232, 180, 209, + 214, 17, 195, 79, 232, 180, 209, 214, 17, 100, 232, 180, 209, 214, 17, + 102, 232, 180, 209, 214, 17, 134, 232, 180, 209, 214, 17, 136, 232, 180, + 209, 214, 17, 146, 232, 180, 209, 214, 17, 167, 232, 180, 209, 214, 17, + 178, 232, 180, 209, 214, 17, 171, 232, 180, 209, 214, 17, 182, 209, 118, + 17, 100, 209, 118, 17, 102, 209, 118, 17, 134, 209, 118, 17, 136, 209, + 118, 17, 146, 209, 118, 17, 167, 209, 118, 17, 178, 209, 118, 17, 171, + 209, 118, 17, 182, 209, 118, 31, 203, 23, 209, 118, 31, 200, 234, 209, + 118, 31, 202, 177, 209, 118, 31, 235, 14, 209, 118, 31, 235, 145, 209, + 118, 31, 206, 13, 209, 118, 31, 207, 65, 209, 118, 31, 237, 20, 209, 118, + 31, 216, 174, 209, 118, 31, 97, 231, 57, 209, 118, 31, 99, 231, 57, 209, + 118, 31, 115, 231, 57, 209, 118, 31, 235, 7, 231, 57, 209, 118, 31, 235, + 101, 231, 57, 209, 118, 31, 206, 29, 231, 57, 209, 118, 31, 207, 71, 231, + 57, 209, 118, 31, 237, 31, 231, 57, 209, 118, 31, 216, 179, 231, 57, 209, + 118, 191, 97, 232, 225, 209, 118, 191, 97, 211, 87, 209, 118, 191, 97, + 202, 184, 209, 118, 191, 99, 202, 181, 37, 205, 182, 1, 251, 162, 37, + 205, 182, 1, 48, 251, 162, 37, 205, 182, 1, 248, 205, 37, 205, 182, 1, + 48, 248, 205, 37, 205, 182, 1, 233, 177, 37, 205, 182, 1, 232, 147, 37, + 205, 182, 1, 48, 232, 147, 37, 205, 182, 1, 197, 117, 37, 205, 182, 1, + 195, 92, 37, 205, 182, 1, 232, 87, 37, 205, 182, 1, 195, 240, 37, 205, + 182, 1, 225, 5, 37, 205, 182, 1, 222, 240, 37, 205, 182, 1, 219, 171, 37, + 205, 182, 1, 215, 138, 37, 205, 182, 1, 48, 215, 138, 37, 205, 182, 1, + 48, 215, 139, 3, 83, 203, 135, 37, 205, 182, 1, 208, 225, 37, 205, 182, + 1, 250, 117, 37, 205, 182, 1, 251, 131, 250, 117, 37, 205, 182, 1, 213, + 92, 37, 205, 182, 1, 209, 5, 37, 205, 182, 1, 48, 209, 5, 37, 205, 182, + 1, 48, 209, 6, 3, 83, 203, 135, 37, 205, 182, 1, 210, 107, 37, 205, 182, + 1, 206, 211, 37, 205, 182, 1, 203, 82, 37, 205, 182, 1, 48, 203, 82, 37, + 205, 182, 1, 48, 203, 83, 3, 83, 203, 135, 37, 205, 182, 31, 100, 37, + 205, 182, 31, 102, 37, 205, 182, 31, 134, 37, 205, 182, 31, 136, 37, 205, + 182, 31, 146, 37, 205, 182, 31, 203, 23, 37, 205, 182, 31, 200, 234, 37, + 205, 182, 31, 202, 177, 37, 205, 182, 31, 97, 231, 57, 37, 205, 182, 191, + 97, 232, 225, 37, 205, 182, 33, 250, 116, 205, 182, 1, 251, 162, 205, + 182, 1, 248, 205, 205, 182, 1, 233, 177, 205, 182, 1, 232, 147, 205, 182, + 1, 197, 117, 205, 182, 1, 195, 92, 205, 182, 1, 232, 87, 205, 182, 1, + 195, 240, 205, 182, 1, 225, 5, 205, 182, 1, 222, 240, 205, 182, 1, 219, + 171, 205, 182, 1, 215, 138, 205, 182, 1, 208, 225, 205, 182, 1, 250, 117, + 205, 182, 1, 213, 92, 205, 182, 1, 209, 5, 205, 182, 1, 210, 108, 205, + 182, 1, 206, 211, 205, 182, 1, 203, 82, 205, 182, 1, 235, 160, 205, 182, + 1, 222, 142, 205, 182, 226, 73, 206, 211, 205, 182, 38, 76, 60, 205, 182, + 38, 99, 238, 251, 60, 205, 182, 38, 76, 57, 205, 182, 38, 99, 238, 251, + 57, 205, 182, 38, 241, 12, 57, 205, 182, 38, 241, 12, 60, 205, 182, 38, + 231, 165, 57, 205, 182, 38, 231, 165, 60, 205, 182, 38, 181, 231, 165, + 60, 205, 182, 38, 210, 110, 60, 205, 182, 38, 204, 196, 60, 205, 182, 31, + 100, 205, 182, 31, 203, 23, 205, 182, 31, 200, 234, 205, 182, 31, 97, + 231, 57, 205, 182, 211, 214, 99, 83, 249, 68, 205, 182, 211, 214, 99, 83, + 249, 69, 3, 238, 250, 205, 182, 211, 214, 244, 250, 3, 238, 253, 205, + 182, 211, 214, 99, 244, 247, 3, 238, 250, 205, 182, 211, 214, 157, 244, + 250, 3, 238, 253, 236, 243, 1, 251, 162, 236, 243, 1, 248, 205, 236, 243, + 1, 233, 177, 236, 243, 1, 240, 100, 236, 243, 1, 232, 147, 236, 243, 1, + 197, 117, 236, 243, 1, 195, 92, 236, 243, 1, 232, 87, 236, 243, 1, 202, + 253, 236, 243, 1, 195, 240, 236, 243, 1, 225, 5, 236, 243, 1, 222, 240, + 236, 243, 1, 219, 171, 236, 243, 1, 215, 138, 236, 243, 1, 208, 225, 236, + 243, 1, 250, 117, 236, 243, 1, 213, 92, 236, 243, 1, 209, 5, 236, 243, 1, + 211, 101, 236, 243, 1, 210, 109, 236, 243, 1, 206, 211, 236, 243, 1, 203, + 82, 236, 243, 33, 195, 91, 158, 2, 247, 133, 158, 2, 251, 51, 158, 2, + 199, 2, 158, 2, 225, 165, 158, 2, 200, 34, 158, 1, 63, 158, 1, 252, 168, + 158, 1, 68, 158, 1, 226, 120, 158, 1, 66, 158, 1, 199, 245, 158, 1, 110, + 144, 158, 1, 110, 209, 182, 158, 1, 110, 159, 158, 1, 110, 222, 38, 158, + 1, 69, 158, 1, 251, 200, 158, 1, 72, 158, 1, 250, 150, 158, 1, 155, 158, + 1, 224, 146, 158, 1, 234, 123, 158, 1, 233, 230, 158, 1, 217, 71, 158, 1, + 247, 174, 158, 1, 247, 16, 158, 1, 225, 214, 158, 1, 225, 180, 158, 1, + 215, 109, 158, 1, 201, 78, 158, 1, 201, 66, 158, 1, 240, 41, 158, 1, 240, + 25, 158, 1, 216, 86, 158, 1, 189, 158, 1, 202, 233, 158, 1, 240, 136, + 158, 1, 239, 176, 158, 1, 176, 158, 1, 161, 158, 1, 213, 6, 158, 1, 249, + 145, 158, 1, 248, 197, 158, 1, 166, 158, 1, 164, 158, 1, 169, 158, 1, + 172, 158, 1, 199, 152, 158, 1, 207, 50, 158, 1, 205, 80, 158, 1, 183, + 158, 1, 142, 158, 1, 222, 37, 158, 1, 37, 42, 222, 26, 158, 1, 37, 42, + 209, 181, 158, 1, 37, 42, 216, 68, 158, 18, 2, 252, 168, 158, 18, 2, 248, + 193, 252, 168, 158, 18, 2, 68, 158, 18, 2, 226, 120, 158, 18, 2, 66, 158, + 18, 2, 199, 245, 158, 18, 2, 110, 144, 158, 18, 2, 110, 209, 182, 158, + 18, 2, 110, 159, 158, 18, 2, 110, 222, 38, 158, 18, 2, 69, 158, 18, 2, + 251, 200, 158, 18, 2, 72, 158, 18, 2, 250, 150, 158, 199, 7, 158, 240, + 88, 158, 52, 240, 88, 158, 211, 214, 238, 253, 158, 211, 214, 52, 238, + 253, 158, 211, 214, 222, 75, 158, 211, 214, 241, 72, 154, 158, 211, 214, + 221, 213, 158, 31, 100, 158, 31, 102, 158, 31, 134, 158, 31, 136, 158, + 31, 146, 158, 31, 167, 158, 31, 178, 158, 31, 171, 158, 31, 182, 158, 31, + 203, 23, 158, 31, 200, 234, 158, 31, 202, 177, 158, 31, 235, 14, 158, 31, + 235, 145, 158, 31, 206, 13, 158, 31, 207, 65, 158, 31, 237, 20, 158, 31, + 216, 174, 158, 31, 97, 231, 57, 158, 31, 97, 170, 158, 17, 195, 79, 158, + 17, 100, 158, 17, 102, 158, 17, 134, 158, 17, 136, 158, 17, 146, 158, 17, + 167, 158, 17, 178, 158, 17, 171, 158, 17, 182, 158, 31, 225, 124, 225, + 28, 2, 247, 133, 225, 28, 2, 251, 51, 225, 28, 2, 199, 2, 225, 28, 1, 63, + 225, 28, 1, 252, 168, 225, 28, 1, 68, 225, 28, 1, 226, 120, 225, 28, 1, + 66, 225, 28, 1, 199, 245, 225, 28, 1, 69, 225, 28, 1, 251, 200, 225, 28, + 1, 72, 225, 28, 1, 250, 150, 225, 28, 1, 155, 225, 28, 1, 224, 146, 225, + 28, 1, 234, 123, 225, 28, 1, 233, 230, 225, 28, 1, 217, 71, 225, 28, 1, + 247, 174, 225, 28, 1, 247, 16, 225, 28, 1, 225, 214, 225, 28, 1, 225, + 180, 225, 28, 1, 215, 109, 225, 28, 1, 201, 78, 225, 28, 1, 201, 66, 225, + 28, 1, 240, 41, 225, 28, 1, 240, 30, 225, 28, 1, 240, 25, 225, 28, 1, + 210, 77, 225, 28, 1, 216, 86, 225, 28, 1, 189, 225, 28, 1, 202, 233, 225, + 28, 1, 240, 136, 225, 28, 1, 239, 176, 225, 28, 1, 176, 225, 28, 1, 161, + 225, 28, 1, 213, 6, 225, 28, 1, 249, 145, 225, 28, 1, 248, 197, 225, 28, + 1, 166, 225, 28, 1, 164, 225, 28, 1, 169, 225, 28, 1, 172, 225, 28, 1, + 199, 152, 225, 28, 1, 207, 50, 225, 28, 1, 205, 80, 225, 28, 1, 183, 225, + 28, 1, 142, 225, 28, 18, 2, 252, 168, 225, 28, 18, 2, 68, 225, 28, 18, 2, + 226, 120, 225, 28, 18, 2, 66, 225, 28, 18, 2, 199, 245, 225, 28, 18, 2, + 69, 225, 28, 18, 2, 251, 200, 225, 28, 18, 2, 72, 225, 28, 18, 2, 250, + 150, 225, 28, 2, 199, 7, 225, 28, 2, 215, 149, 225, 28, 252, 30, 55, 225, + 28, 236, 196, 55, 225, 28, 31, 55, 225, 28, 208, 133, 78, 225, 28, 52, + 208, 133, 78, 225, 28, 240, 88, 225, 28, 52, 240, 88, 225, 28, 31, 2, 57, + 205, 167, 205, 175, 1, 208, 254, 205, 167, 205, 175, 1, 203, 139, 205, + 167, 205, 175, 1, 249, 115, 205, 167, 205, 175, 1, 247, 163, 205, 167, + 205, 175, 1, 240, 116, 205, 167, 205, 175, 1, 234, 108, 205, 167, 205, + 175, 1, 220, 89, 205, 167, 205, 175, 1, 217, 68, 205, 167, 205, 175, 1, + 223, 57, 205, 167, 205, 175, 1, 217, 231, 205, 167, 205, 175, 1, 199, + 148, 205, 167, 205, 175, 1, 213, 223, 205, 167, 205, 175, 1, 196, 110, + 205, 167, 205, 175, 1, 210, 226, 205, 167, 205, 175, 1, 232, 236, 205, + 167, 205, 175, 1, 225, 33, 205, 167, 205, 175, 1, 225, 208, 205, 167, + 205, 175, 1, 215, 106, 205, 167, 205, 175, 1, 251, 209, 205, 167, 205, + 175, 1, 237, 52, 205, 167, 205, 175, 1, 226, 121, 205, 167, 205, 175, 1, + 200, 92, 205, 167, 205, 175, 1, 214, 149, 205, 167, 205, 175, 1, 237, 40, + 205, 167, 205, 175, 1, 220, 104, 205, 167, 205, 175, 17, 195, 79, 205, + 167, 205, 175, 17, 100, 205, 167, 205, 175, 17, 102, 205, 167, 205, 175, + 17, 134, 205, 167, 205, 175, 17, 136, 205, 167, 205, 175, 17, 146, 205, + 167, 205, 175, 17, 167, 205, 167, 205, 175, 17, 178, 205, 167, 205, 175, + 17, 171, 205, 167, 205, 175, 17, 182, 247, 10, 2, 247, 133, 247, 10, 2, + 251, 51, 247, 10, 2, 199, 2, 247, 10, 1, 252, 168, 247, 10, 1, 68, 247, + 10, 1, 66, 247, 10, 1, 69, 247, 10, 1, 225, 55, 247, 10, 1, 224, 145, + 247, 10, 1, 234, 120, 247, 10, 1, 233, 229, 247, 10, 1, 217, 70, 247, 10, + 1, 247, 173, 247, 10, 1, 247, 15, 247, 10, 1, 225, 213, 247, 10, 1, 225, + 179, 247, 10, 1, 215, 108, 247, 10, 1, 201, 77, 247, 10, 1, 201, 65, 247, + 10, 1, 240, 40, 247, 10, 1, 240, 24, 247, 10, 1, 216, 85, 247, 10, 1, + 203, 162, 247, 10, 1, 202, 232, 247, 10, 1, 240, 135, 247, 10, 1, 239, + 175, 247, 10, 1, 217, 244, 247, 10, 1, 213, 243, 247, 10, 1, 213, 5, 247, + 10, 1, 249, 143, 247, 10, 1, 248, 196, 247, 10, 1, 220, 119, 247, 10, 1, + 195, 166, 247, 10, 1, 196, 129, 247, 10, 1, 210, 244, 247, 10, 1, 223, + 82, 247, 10, 1, 197, 160, 247, 10, 1, 209, 13, 247, 10, 1, 232, 246, 247, + 10, 18, 2, 63, 247, 10, 18, 2, 68, 247, 10, 18, 2, 226, 120, 247, 10, 18, + 2, 66, 247, 10, 18, 2, 199, 245, 247, 10, 18, 2, 69, 247, 10, 18, 2, 251, + 200, 247, 10, 18, 2, 72, 247, 10, 18, 2, 250, 150, 247, 10, 18, 2, 214, + 146, 247, 10, 177, 78, 247, 10, 250, 151, 78, 247, 10, 199, 7, 247, 10, + 220, 117, 247, 10, 17, 195, 79, 247, 10, 17, 100, 247, 10, 17, 102, 247, + 10, 17, 134, 247, 10, 17, 136, 247, 10, 17, 146, 247, 10, 17, 167, 247, + 10, 17, 178, 247, 10, 17, 171, 247, 10, 17, 182, 247, 10, 208, 133, 78, + 247, 10, 240, 88, 247, 10, 52, 240, 88, 247, 10, 211, 79, 78, 247, 10, 1, + 222, 121, 247, 10, 18, 2, 252, 168, 247, 10, 18, 2, 237, 33, 220, 87, 1, + 63, 220, 87, 1, 68, 220, 87, 1, 66, 220, 87, 1, 69, 220, 87, 1, 72, 220, + 87, 1, 155, 220, 87, 1, 224, 146, 220, 87, 1, 234, 123, 220, 87, 1, 233, + 230, 220, 87, 1, 247, 174, 220, 87, 1, 247, 16, 220, 87, 1, 225, 214, + 220, 87, 1, 225, 180, 220, 87, 1, 215, 109, 220, 87, 1, 201, 78, 220, 87, + 1, 201, 66, 220, 87, 1, 240, 41, 220, 87, 1, 240, 25, 220, 87, 1, 216, + 86, 220, 87, 1, 189, 220, 87, 1, 202, 233, 220, 87, 1, 240, 136, 220, 87, + 1, 239, 176, 220, 87, 1, 176, 220, 87, 1, 161, 220, 87, 1, 213, 6, 220, + 87, 1, 249, 145, 220, 87, 1, 248, 197, 220, 87, 1, 166, 220, 87, 1, 169, + 220, 87, 1, 172, 220, 87, 1, 199, 152, 220, 87, 1, 183, 220, 87, 1, 142, + 220, 87, 1, 209, 181, 220, 87, 2, 215, 149, 220, 87, 252, 30, 55, 220, + 87, 208, 133, 78, 220, 87, 33, 206, 159, 207, 15, 2, 247, 133, 207, 15, + 2, 251, 51, 207, 15, 2, 199, 2, 207, 15, 1, 63, 207, 15, 1, 252, 168, + 207, 15, 1, 68, 207, 15, 1, 226, 120, 207, 15, 1, 66, 207, 15, 1, 199, + 245, 207, 15, 1, 110, 144, 207, 15, 1, 110, 209, 182, 207, 15, 1, 110, + 159, 207, 15, 1, 110, 222, 38, 207, 15, 1, 69, 207, 15, 1, 251, 200, 207, + 15, 1, 72, 207, 15, 1, 250, 150, 207, 15, 1, 155, 207, 15, 1, 224, 146, + 207, 15, 1, 234, 123, 207, 15, 1, 233, 230, 207, 15, 1, 217, 71, 207, 15, + 1, 247, 174, 207, 15, 1, 247, 16, 207, 15, 1, 225, 214, 207, 15, 1, 225, + 180, 207, 15, 1, 215, 109, 207, 15, 1, 201, 78, 207, 15, 1, 201, 66, 207, + 15, 1, 240, 41, 207, 15, 1, 240, 25, 207, 15, 1, 216, 86, 207, 15, 1, + 189, 207, 15, 1, 202, 233, 207, 15, 1, 240, 136, 207, 15, 1, 239, 176, + 207, 15, 1, 176, 207, 15, 1, 161, 207, 15, 1, 213, 6, 207, 15, 1, 249, + 145, 207, 15, 1, 248, 197, 207, 15, 1, 166, 207, 15, 1, 164, 207, 15, 1, + 169, 207, 15, 1, 172, 207, 15, 1, 222, 37, 207, 15, 1, 199, 152, 207, 15, + 1, 207, 50, 207, 15, 1, 205, 80, 207, 15, 1, 183, 207, 15, 1, 142, 207, + 15, 18, 2, 252, 168, 207, 15, 18, 2, 68, 207, 15, 18, 2, 226, 120, 207, + 15, 18, 2, 66, 207, 15, 18, 2, 199, 245, 207, 15, 18, 2, 110, 144, 207, + 15, 18, 2, 110, 209, 182, 207, 15, 18, 2, 110, 159, 207, 15, 18, 2, 110, + 222, 38, 207, 15, 18, 2, 69, 207, 15, 18, 2, 251, 200, 207, 15, 18, 2, + 72, 207, 15, 18, 2, 250, 150, 207, 15, 2, 199, 7, 207, 15, 2, 250, 132, + 207, 15, 2, 225, 165, 207, 15, 2, 200, 34, 207, 15, 214, 127, 207, 15, + 240, 88, 207, 15, 52, 240, 88, 207, 15, 252, 30, 55, 207, 15, 207, 90, + 207, 15, 208, 215, 78, 207, 15, 2, 215, 149, 207, 15, 18, 73, 78, 207, + 15, 236, 75, 206, 182, 18, 78, 207, 15, 204, 75, 78, 207, 15, 17, 195, + 79, 207, 15, 17, 100, 207, 15, 17, 102, 207, 15, 17, 134, 207, 15, 17, + 136, 207, 15, 17, 146, 207, 15, 17, 167, 207, 15, 17, 178, 207, 15, 17, + 171, 207, 15, 17, 182, 207, 15, 237, 13, 207, 15, 2, 206, 100, 207, 15, + 232, 130, 207, 15, 241, 128, 55, 207, 15, 208, 133, 220, 28, 207, 15, + 208, 133, 220, 27, 153, 250, 251, 17, 100, 153, 250, 251, 17, 102, 153, + 250, 251, 17, 134, 153, 250, 251, 17, 136, 153, 250, 251, 17, 146, 153, + 250, 251, 17, 167, 153, 250, 251, 17, 178, 153, 250, 251, 17, 171, 153, + 250, 251, 17, 182, 153, 250, 251, 31, 203, 23, 153, 250, 251, 31, 200, + 234, 153, 250, 251, 31, 202, 177, 153, 250, 251, 31, 235, 14, 153, 250, + 251, 31, 235, 145, 153, 250, 251, 31, 206, 13, 153, 250, 251, 31, 207, + 65, 153, 250, 251, 31, 237, 20, 153, 250, 251, 31, 216, 174, 153, 250, + 251, 31, 97, 231, 57, 153, 250, 251, 31, 97, 170, 224, 116, 1, 63, 224, + 116, 1, 252, 168, 224, 116, 1, 68, 224, 116, 1, 66, 224, 116, 1, 69, 224, + 116, 1, 251, 200, 224, 116, 1, 72, 224, 116, 1, 250, 150, 224, 116, 1, + 155, 224, 116, 1, 224, 146, 224, 116, 1, 234, 123, 224, 116, 1, 234, 10, + 224, 116, 1, 233, 230, 224, 116, 1, 217, 71, 224, 116, 1, 247, 174, 224, + 116, 1, 247, 16, 224, 116, 1, 225, 214, 224, 116, 1, 225, 158, 224, 116, + 1, 215, 109, 224, 116, 1, 201, 78, 224, 116, 1, 201, 66, 224, 116, 1, + 240, 41, 224, 116, 1, 240, 25, 224, 116, 1, 216, 86, 224, 116, 1, 189, + 224, 116, 1, 202, 233, 224, 116, 1, 240, 136, 224, 116, 1, 240, 31, 224, + 116, 1, 239, 176, 224, 116, 1, 176, 224, 116, 1, 161, 224, 116, 1, 213, + 6, 224, 116, 1, 249, 145, 224, 116, 1, 249, 45, 224, 116, 1, 248, 197, + 224, 116, 1, 166, 224, 116, 1, 164, 224, 116, 1, 169, 224, 116, 1, 172, + 224, 116, 1, 199, 152, 224, 116, 1, 183, 224, 116, 1, 142, 224, 116, 1, + 222, 37, 224, 116, 18, 2, 252, 168, 224, 116, 18, 2, 68, 224, 116, 18, 2, + 226, 120, 224, 116, 18, 2, 66, 224, 116, 18, 2, 69, 224, 116, 18, 2, 251, + 200, 224, 116, 18, 2, 72, 224, 116, 18, 2, 250, 150, 224, 116, 2, 251, + 51, 224, 116, 2, 199, 7, 224, 116, 2, 215, 149, 224, 116, 2, 207, 40, + 224, 116, 240, 88, 224, 116, 52, 240, 88, 224, 116, 197, 9, 207, 90, 224, + 116, 208, 133, 78, 224, 116, 52, 208, 133, 78, 224, 116, 252, 30, 55, + 224, 116, 2, 204, 119, 218, 124, 1, 63, 218, 124, 1, 68, 218, 124, 1, 66, + 218, 124, 1, 69, 218, 124, 1, 155, 218, 124, 1, 224, 146, 218, 124, 1, + 234, 123, 218, 124, 1, 233, 230, 218, 124, 1, 247, 174, 218, 124, 1, 247, + 16, 218, 124, 1, 225, 214, 218, 124, 1, 225, 158, 218, 124, 1, 215, 109, + 218, 124, 1, 201, 78, 218, 124, 1, 201, 66, 218, 124, 1, 240, 41, 218, + 124, 1, 240, 31, 218, 124, 1, 240, 25, 218, 124, 1, 216, 86, 218, 124, 1, + 189, 218, 124, 1, 202, 233, 218, 124, 1, 240, 136, 218, 124, 1, 239, 176, + 218, 124, 1, 176, 218, 124, 1, 161, 218, 124, 1, 213, 6, 218, 124, 1, + 249, 145, 218, 124, 1, 248, 197, 218, 124, 1, 166, 218, 124, 1, 164, 218, + 124, 1, 169, 218, 124, 1, 172, 218, 124, 1, 199, 152, 218, 124, 1, 183, + 218, 124, 1, 142, 218, 124, 1, 209, 181, 218, 124, 1, 210, 77, 218, 124, + 208, 133, 78, 224, 107, 1, 63, 224, 107, 1, 252, 168, 224, 107, 1, 68, + 224, 107, 1, 226, 120, 224, 107, 1, 66, 224, 107, 1, 199, 245, 224, 107, + 1, 69, 224, 107, 1, 251, 200, 224, 107, 1, 72, 224, 107, 1, 250, 150, + 224, 107, 1, 155, 224, 107, 1, 224, 146, 224, 107, 1, 234, 123, 224, 107, + 1, 234, 10, 224, 107, 1, 233, 230, 224, 107, 1, 217, 71, 224, 107, 1, + 247, 174, 224, 107, 1, 247, 16, 224, 107, 1, 225, 214, 224, 107, 1, 225, + 158, 224, 107, 1, 225, 180, 224, 107, 1, 215, 109, 224, 107, 1, 201, 78, + 224, 107, 1, 201, 66, 224, 107, 1, 240, 41, 224, 107, 1, 240, 31, 224, + 107, 1, 209, 181, 224, 107, 1, 240, 25, 224, 107, 1, 216, 86, 224, 107, + 1, 189, 224, 107, 1, 202, 233, 224, 107, 1, 240, 136, 224, 107, 1, 239, + 176, 224, 107, 1, 176, 224, 107, 1, 161, 224, 107, 1, 213, 6, 224, 107, + 1, 249, 145, 224, 107, 1, 249, 45, 224, 107, 1, 248, 197, 224, 107, 1, + 166, 224, 107, 1, 164, 224, 107, 1, 169, 224, 107, 1, 172, 224, 107, 1, + 199, 152, 224, 107, 1, 207, 50, 224, 107, 1, 183, 224, 107, 1, 142, 224, + 107, 2, 251, 51, 224, 107, 18, 2, 252, 168, 224, 107, 18, 2, 68, 224, + 107, 18, 2, 226, 120, 224, 107, 18, 2, 66, 224, 107, 18, 2, 199, 245, + 224, 107, 18, 2, 69, 224, 107, 18, 2, 251, 200, 224, 107, 18, 2, 72, 224, + 107, 18, 2, 250, 150, 224, 107, 2, 215, 149, 224, 107, 2, 199, 7, 224, + 107, 17, 195, 79, 224, 107, 17, 100, 224, 107, 17, 102, 224, 107, 17, + 134, 224, 107, 17, 136, 224, 107, 17, 146, 224, 107, 17, 167, 224, 107, + 17, 178, 224, 107, 17, 171, 224, 107, 17, 182, 233, 109, 2, 38, 251, 52, + 57, 233, 109, 2, 247, 133, 233, 109, 2, 251, 51, 233, 109, 2, 199, 2, + 233, 109, 1, 63, 233, 109, 1, 252, 168, 233, 109, 1, 68, 233, 109, 1, + 226, 120, 233, 109, 1, 66, 233, 109, 1, 199, 245, 233, 109, 1, 110, 144, + 233, 109, 1, 110, 159, 233, 109, 1, 237, 54, 233, 109, 1, 251, 200, 233, + 109, 1, 214, 102, 233, 109, 1, 250, 150, 233, 109, 1, 155, 233, 109, 1, + 224, 146, 233, 109, 1, 234, 123, 233, 109, 1, 233, 230, 233, 109, 1, 217, + 71, 233, 109, 1, 247, 174, 233, 109, 1, 247, 16, 233, 109, 1, 225, 214, + 233, 109, 1, 225, 180, 233, 109, 1, 215, 109, 233, 109, 1, 201, 78, 233, + 109, 1, 201, 66, 233, 109, 1, 240, 41, 233, 109, 1, 240, 25, 233, 109, 1, + 216, 86, 233, 109, 1, 189, 233, 109, 1, 202, 233, 233, 109, 1, 240, 136, + 233, 109, 1, 239, 176, 233, 109, 1, 176, 233, 109, 1, 161, 233, 109, 1, + 213, 6, 233, 109, 1, 249, 145, 233, 109, 1, 248, 197, 233, 109, 1, 166, + 233, 109, 1, 164, 233, 109, 1, 169, 233, 109, 1, 172, 233, 109, 1, 222, + 37, 233, 109, 1, 199, 152, 233, 109, 1, 207, 50, 233, 109, 1, 205, 80, + 233, 109, 1, 183, 233, 109, 1, 142, 38, 248, 161, 60, 233, 109, 2, 215, + 149, 233, 109, 2, 250, 132, 233, 109, 18, 2, 252, 168, 233, 109, 18, 2, + 68, 233, 109, 18, 2, 226, 120, 233, 109, 18, 2, 66, 233, 109, 18, 2, 199, + 245, 233, 109, 18, 2, 110, 144, 233, 109, 18, 2, 110, 209, 182, 233, 109, + 18, 2, 237, 54, 233, 109, 18, 2, 251, 200, 233, 109, 18, 2, 214, 102, + 233, 109, 18, 2, 250, 150, 233, 109, 2, 199, 7, 233, 109, 214, 127, 233, + 109, 250, 151, 222, 158, 78, 233, 109, 2, 212, 123, 233, 109, 1, 199, + 115, 251, 51, 233, 109, 1, 199, 115, 52, 251, 51, 233, 109, 1, 110, 209, + 182, 233, 109, 1, 110, 222, 38, 233, 109, 18, 2, 110, 159, 233, 109, 18, + 2, 110, 222, 38, 38, 233, 109, 17, 195, 79, 38, 233, 109, 17, 100, 38, + 233, 109, 17, 102, 38, 233, 109, 17, 134, 38, 233, 109, 17, 136, 38, 233, + 109, 17, 146, 38, 233, 109, 17, 167, 38, 233, 109, 1, 63, 38, 233, 109, + 1, 155, 38, 233, 109, 1, 176, 38, 233, 109, 1, 199, 34, 38, 233, 109, 1, + 161, 217, 81, 1, 63, 217, 81, 1, 252, 168, 217, 81, 1, 68, 217, 81, 1, + 226, 120, 217, 81, 1, 66, 217, 81, 1, 199, 245, 217, 81, 1, 110, 144, + 217, 81, 1, 110, 209, 182, 217, 81, 1, 110, 159, 217, 81, 1, 110, 222, + 38, 217, 81, 1, 69, 217, 81, 1, 251, 200, 217, 81, 1, 72, 217, 81, 1, + 250, 150, 217, 81, 1, 155, 217, 81, 1, 224, 146, 217, 81, 1, 234, 123, + 217, 81, 1, 233, 230, 217, 81, 1, 217, 71, 217, 81, 1, 217, 20, 217, 81, + 1, 247, 174, 217, 81, 1, 247, 16, 217, 81, 1, 225, 214, 217, 81, 1, 225, + 180, 217, 81, 1, 215, 109, 217, 81, 1, 215, 91, 217, 81, 1, 201, 78, 217, + 81, 1, 201, 66, 217, 81, 1, 240, 41, 217, 81, 1, 240, 25, 217, 81, 1, + 216, 86, 217, 81, 1, 189, 217, 81, 1, 202, 233, 217, 81, 1, 240, 136, + 217, 81, 1, 239, 176, 217, 81, 1, 176, 217, 81, 1, 216, 227, 217, 81, 1, + 161, 217, 81, 1, 213, 6, 217, 81, 1, 249, 145, 217, 81, 1, 248, 197, 217, + 81, 1, 166, 217, 81, 1, 219, 81, 217, 81, 1, 164, 217, 81, 1, 169, 217, + 81, 1, 210, 77, 217, 81, 1, 172, 217, 81, 1, 222, 122, 217, 81, 1, 197, + 166, 217, 81, 1, 207, 50, 217, 81, 1, 205, 80, 217, 81, 1, 183, 217, 81, + 1, 142, 217, 81, 18, 2, 252, 168, 217, 81, 18, 2, 68, 217, 81, 18, 2, + 226, 120, 217, 81, 18, 2, 66, 217, 81, 18, 2, 199, 245, 217, 81, 18, 2, + 110, 144, 217, 81, 18, 2, 110, 209, 182, 217, 81, 18, 2, 110, 159, 217, + 81, 18, 2, 110, 222, 38, 217, 81, 18, 2, 69, 217, 81, 18, 2, 251, 200, + 217, 81, 18, 2, 72, 217, 81, 18, 2, 250, 150, 217, 81, 2, 199, 7, 217, + 81, 2, 247, 133, 217, 81, 2, 251, 51, 217, 81, 2, 199, 2, 217, 81, 2, + 215, 149, 217, 81, 2, 250, 132, 217, 81, 2, 48, 251, 51, 217, 81, 214, + 127, 217, 81, 206, 99, 217, 81, 240, 88, 217, 81, 52, 240, 88, 217, 81, + 244, 159, 217, 81, 234, 87, 235, 134, 217, 81, 252, 30, 55, 217, 81, 17, + 195, 79, 217, 81, 17, 100, 217, 81, 17, 102, 217, 81, 17, 134, 217, 81, + 17, 136, 217, 81, 17, 146, 217, 81, 17, 167, 217, 81, 17, 178, 217, 81, + 17, 171, 217, 81, 17, 182, 217, 81, 212, 148, 78, 217, 81, 226, 43, 55, + 217, 81, 208, 215, 78, 217, 81, 1, 199, 115, 251, 51, 202, 61, 251, 80, + 202, 61, 1, 63, 202, 61, 1, 252, 168, 202, 61, 1, 68, 202, 61, 1, 226, + 120, 202, 61, 1, 66, 202, 61, 1, 199, 245, 202, 61, 1, 110, 144, 202, 61, + 1, 110, 209, 182, 202, 61, 1, 110, 159, 202, 61, 1, 110, 222, 38, 202, + 61, 1, 69, 202, 61, 1, 251, 200, 202, 61, 1, 72, 202, 61, 1, 250, 150, + 202, 61, 1, 155, 202, 61, 1, 224, 146, 202, 61, 1, 234, 123, 202, 61, 1, + 233, 230, 202, 61, 1, 217, 71, 202, 61, 1, 247, 174, 202, 61, 1, 247, 16, + 202, 61, 1, 225, 214, 202, 61, 1, 225, 180, 202, 61, 1, 215, 109, 202, + 61, 1, 201, 78, 202, 61, 1, 201, 66, 202, 61, 1, 240, 41, 202, 61, 1, + 240, 25, 202, 61, 1, 216, 86, 202, 61, 1, 189, 202, 61, 1, 202, 233, 202, + 61, 1, 240, 136, 202, 61, 1, 239, 176, 202, 61, 1, 176, 202, 61, 1, 161, + 202, 61, 1, 213, 6, 202, 61, 1, 249, 145, 202, 61, 1, 248, 197, 202, 61, + 1, 166, 202, 61, 1, 164, 202, 61, 1, 169, 202, 61, 1, 172, 202, 61, 1, + 199, 152, 202, 61, 1, 207, 50, 202, 61, 1, 205, 80, 202, 61, 1, 183, 202, + 61, 1, 142, 202, 61, 18, 2, 252, 168, 202, 61, 18, 2, 68, 202, 61, 18, 2, + 226, 120, 202, 61, 18, 2, 66, 202, 61, 18, 2, 199, 245, 202, 61, 18, 2, + 110, 144, 202, 61, 18, 2, 110, 209, 182, 202, 61, 18, 2, 110, 159, 202, + 61, 18, 2, 110, 222, 38, 202, 61, 18, 2, 69, 202, 61, 18, 2, 206, 182, + 69, 202, 61, 18, 2, 251, 200, 202, 61, 18, 2, 72, 202, 61, 18, 2, 206, + 182, 72, 202, 61, 18, 2, 250, 150, 202, 61, 2, 247, 133, 202, 61, 2, 251, + 51, 202, 61, 2, 199, 2, 202, 61, 2, 199, 7, 202, 61, 2, 215, 149, 202, + 61, 2, 250, 132, 202, 61, 233, 35, 202, 61, 252, 30, 55, 202, 61, 214, + 127, 202, 61, 17, 195, 79, 202, 61, 17, 100, 202, 61, 17, 102, 202, 61, + 17, 134, 202, 61, 17, 136, 202, 61, 17, 146, 202, 61, 17, 167, 202, 61, + 17, 178, 202, 61, 17, 171, 202, 61, 17, 182, 206, 101, 1, 63, 206, 101, + 1, 252, 168, 206, 101, 1, 68, 206, 101, 1, 226, 120, 206, 101, 1, 66, + 206, 101, 1, 199, 245, 206, 101, 1, 110, 144, 206, 101, 1, 110, 209, 182, + 206, 101, 1, 110, 159, 206, 101, 1, 110, 222, 38, 206, 101, 1, 69, 206, + 101, 1, 251, 200, 206, 101, 1, 72, 206, 101, 1, 250, 150, 206, 101, 1, + 155, 206, 101, 1, 224, 146, 206, 101, 1, 234, 123, 206, 101, 1, 233, 230, + 206, 101, 1, 217, 71, 206, 101, 1, 247, 174, 206, 101, 1, 247, 16, 206, + 101, 1, 225, 214, 206, 101, 1, 225, 180, 206, 101, 1, 215, 109, 206, 101, + 1, 201, 78, 206, 101, 1, 201, 66, 206, 101, 1, 240, 41, 206, 101, 1, 240, + 25, 206, 101, 1, 216, 86, 206, 101, 1, 189, 206, 101, 1, 202, 233, 206, + 101, 1, 240, 136, 206, 101, 1, 239, 176, 206, 101, 1, 176, 206, 101, 1, + 161, 206, 101, 1, 213, 6, 206, 101, 1, 249, 145, 206, 101, 1, 248, 197, + 206, 101, 1, 166, 206, 101, 1, 164, 206, 101, 1, 169, 206, 101, 1, 172, + 206, 101, 1, 199, 152, 206, 101, 1, 207, 50, 206, 101, 1, 205, 80, 206, + 101, 1, 183, 206, 101, 1, 142, 206, 101, 18, 2, 252, 168, 206, 101, 18, + 2, 68, 206, 101, 18, 2, 226, 120, 206, 101, 18, 2, 66, 206, 101, 18, 2, + 199, 245, 206, 101, 18, 2, 110, 144, 206, 101, 18, 2, 110, 209, 182, 206, + 101, 18, 2, 69, 206, 101, 18, 2, 251, 200, 206, 101, 18, 2, 72, 206, 101, + 18, 2, 250, 150, 206, 101, 2, 247, 133, 206, 101, 2, 251, 51, 206, 101, + 2, 199, 2, 206, 101, 2, 199, 7, 206, 101, 2, 215, 149, 206, 101, 2, 206, + 100, 206, 101, 240, 88, 206, 101, 52, 240, 88, 206, 101, 207, 91, 238, + 253, 206, 101, 207, 91, 154, 206, 101, 210, 117, 220, 28, 206, 101, 210, + 117, 220, 27, 206, 101, 210, 117, 220, 26, 206, 101, 236, 222, 77, 202, + 238, 78, 206, 101, 208, 133, 117, 3, 201, 175, 26, 200, 167, 214, 58, + 206, 101, 208, 133, 117, 3, 201, 175, 26, 237, 250, 241, 70, 206, 101, + 208, 133, 117, 3, 210, 189, 26, 237, 250, 241, 70, 206, 101, 208, 133, + 117, 3, 210, 189, 26, 237, 250, 52, 241, 70, 206, 101, 208, 133, 117, 3, + 210, 189, 26, 237, 250, 201, 165, 241, 70, 206, 101, 208, 133, 117, 52, + 210, 2, 206, 101, 208, 133, 117, 52, 210, 3, 3, 210, 188, 206, 101, 208, + 133, 117, 3, 52, 241, 70, 206, 101, 208, 133, 117, 3, 201, 165, 241, 70, + 206, 101, 208, 133, 117, 3, 211, 90, 241, 70, 206, 101, 208, 133, 117, 3, + 207, 88, 241, 70, 206, 101, 208, 133, 117, 3, 244, 247, 26, 210, 188, + 206, 101, 208, 133, 117, 3, 244, 247, 26, 99, 236, 224, 206, 101, 208, + 133, 117, 3, 244, 247, 26, 235, 7, 236, 224, 206, 101, 1, 202, 155, 251, + 131, 68, 206, 101, 1, 200, 217, 251, 131, 68, 206, 101, 1, 200, 217, 251, + 131, 226, 120, 206, 101, 1, 251, 131, 66, 206, 101, 18, 2, 251, 131, 66, + 206, 101, 18, 2, 251, 131, 199, 245, 218, 236, 1, 63, 218, 236, 1, 252, + 168, 218, 236, 1, 68, 218, 236, 1, 226, 120, 218, 236, 1, 66, 218, 236, + 1, 199, 245, 218, 236, 1, 110, 144, 218, 236, 1, 110, 209, 182, 218, 236, + 1, 110, 159, 218, 236, 1, 110, 222, 38, 218, 236, 1, 69, 218, 236, 1, + 251, 200, 218, 236, 1, 72, 218, 236, 1, 250, 150, 218, 236, 1, 155, 218, + 236, 1, 224, 146, 218, 236, 1, 234, 123, 218, 236, 1, 233, 230, 218, 236, + 1, 217, 71, 218, 236, 1, 247, 174, 218, 236, 1, 247, 16, 218, 236, 1, + 225, 214, 218, 236, 1, 225, 180, 218, 236, 1, 215, 109, 218, 236, 1, 201, + 78, 218, 236, 1, 201, 66, 218, 236, 1, 240, 41, 218, 236, 1, 240, 25, + 218, 236, 1, 216, 86, 218, 236, 1, 189, 218, 236, 1, 202, 233, 218, 236, + 1, 240, 136, 218, 236, 1, 239, 176, 218, 236, 1, 176, 218, 236, 1, 161, + 218, 236, 1, 213, 6, 218, 236, 1, 249, 145, 218, 236, 1, 248, 197, 218, + 236, 1, 166, 218, 236, 1, 164, 218, 236, 1, 169, 218, 236, 1, 172, 218, + 236, 1, 199, 152, 218, 236, 1, 207, 50, 218, 236, 1, 205, 80, 218, 236, + 1, 183, 218, 236, 1, 142, 218, 236, 1, 222, 37, 218, 236, 18, 2, 252, + 168, 218, 236, 18, 2, 68, 218, 236, 18, 2, 226, 120, 218, 236, 18, 2, 66, + 218, 236, 18, 2, 199, 245, 218, 236, 18, 2, 110, 144, 218, 236, 18, 2, + 110, 209, 182, 218, 236, 18, 2, 110, 159, 218, 236, 18, 2, 110, 222, 38, + 218, 236, 18, 2, 69, 218, 236, 18, 2, 251, 200, 218, 236, 18, 2, 72, 218, + 236, 18, 2, 250, 150, 218, 236, 2, 251, 51, 218, 236, 2, 199, 2, 218, + 236, 2, 199, 7, 218, 236, 2, 250, 248, 218, 236, 240, 88, 218, 236, 52, + 240, 88, 218, 236, 252, 30, 55, 218, 236, 2, 231, 45, 218, 236, 17, 195, + 79, 218, 236, 17, 100, 218, 236, 17, 102, 218, 236, 17, 134, 218, 236, + 17, 136, 218, 236, 17, 146, 218, 236, 17, 167, 218, 236, 17, 178, 218, + 236, 17, 171, 218, 236, 17, 182, 96, 248, 155, 3, 214, 59, 96, 209, 194, + 248, 154, 96, 52, 248, 155, 3, 214, 59, 96, 201, 165, 248, 155, 3, 214, + 59, 96, 248, 155, 3, 52, 214, 59, 96, 209, 194, 248, 155, 3, 214, 59, 96, + 209, 194, 248, 155, 3, 52, 214, 59, 96, 226, 17, 248, 154, 96, 226, 17, + 248, 155, 3, 52, 214, 59, 96, 204, 51, 248, 154, 96, 204, 51, 248, 155, + 3, 214, 59, 96, 204, 51, 248, 155, 3, 52, 214, 59, 96, 163, 204, 51, 248, + 155, 3, 52, 214, 59, 203, 125, 1, 63, 203, 125, 1, 252, 168, 203, 125, 1, + 68, 203, 125, 1, 226, 120, 203, 125, 1, 66, 203, 125, 1, 199, 245, 203, + 125, 1, 69, 203, 125, 1, 251, 200, 203, 125, 1, 72, 203, 125, 1, 250, + 150, 203, 125, 1, 155, 203, 125, 1, 224, 146, 203, 125, 1, 234, 123, 203, + 125, 1, 233, 230, 203, 125, 1, 217, 71, 203, 125, 1, 247, 174, 203, 125, + 1, 247, 16, 203, 125, 1, 225, 214, 203, 125, 1, 225, 180, 203, 125, 1, + 215, 109, 203, 125, 1, 201, 78, 203, 125, 1, 201, 66, 203, 125, 1, 240, + 41, 203, 125, 1, 240, 25, 203, 125, 1, 216, 86, 203, 125, 1, 189, 203, + 125, 1, 202, 233, 203, 125, 1, 240, 136, 203, 125, 1, 239, 176, 203, 125, + 1, 176, 203, 125, 1, 161, 203, 125, 1, 213, 6, 203, 125, 1, 249, 145, + 203, 125, 1, 248, 197, 203, 125, 1, 166, 203, 125, 1, 164, 203, 125, 1, + 169, 203, 125, 1, 172, 203, 125, 1, 199, 152, 203, 125, 1, 207, 50, 203, + 125, 1, 183, 203, 125, 1, 142, 203, 125, 1, 209, 181, 203, 125, 2, 251, + 51, 203, 125, 2, 199, 2, 203, 125, 18, 2, 252, 168, 203, 125, 18, 2, 68, + 203, 125, 18, 2, 226, 120, 203, 125, 18, 2, 66, 203, 125, 18, 2, 199, + 245, 203, 125, 18, 2, 69, 203, 125, 18, 2, 251, 200, 203, 125, 18, 2, 72, + 203, 125, 18, 2, 250, 150, 203, 125, 2, 199, 7, 203, 125, 2, 215, 149, + 203, 125, 1, 250, 251, 224, 146, 203, 125, 17, 195, 79, 203, 125, 17, + 100, 203, 125, 17, 102, 203, 125, 17, 134, 203, 125, 17, 136, 203, 125, + 17, 146, 203, 125, 17, 167, 203, 125, 17, 178, 203, 125, 17, 171, 203, + 125, 17, 182, 251, 204, 1, 155, 251, 204, 1, 224, 146, 251, 204, 1, 217, + 71, 251, 204, 1, 176, 251, 204, 1, 189, 251, 204, 1, 251, 131, 189, 251, + 204, 1, 161, 251, 204, 1, 213, 6, 251, 204, 1, 249, 145, 251, 204, 1, + 166, 251, 204, 1, 225, 214, 251, 204, 1, 247, 16, 251, 204, 1, 202, 233, + 251, 204, 1, 169, 251, 204, 1, 172, 251, 204, 1, 183, 251, 204, 1, 215, + 109, 251, 204, 1, 142, 251, 204, 1, 63, 251, 204, 1, 240, 136, 251, 204, + 1, 239, 176, 251, 204, 1, 234, 123, 251, 204, 1, 251, 131, 234, 123, 251, + 204, 1, 233, 230, 251, 204, 1, 248, 197, 251, 204, 1, 225, 180, 251, 204, + 1, 251, 131, 249, 145, 251, 204, 108, 2, 219, 194, 172, 251, 204, 108, 2, + 219, 194, 169, 251, 204, 108, 2, 219, 194, 222, 96, 169, 251, 204, 18, 2, + 63, 251, 204, 18, 2, 252, 168, 251, 204, 18, 2, 68, 251, 204, 18, 2, 226, + 120, 251, 204, 18, 2, 66, 251, 204, 18, 2, 199, 245, 251, 204, 18, 2, 69, + 251, 204, 18, 2, 250, 127, 251, 204, 18, 2, 72, 251, 204, 18, 2, 251, + 200, 251, 204, 18, 2, 251, 123, 251, 204, 2, 224, 78, 251, 204, 17, 195, + 79, 251, 204, 17, 100, 251, 204, 17, 102, 251, 204, 17, 134, 251, 204, + 17, 136, 251, 204, 17, 146, 251, 204, 17, 167, 251, 204, 17, 178, 251, + 204, 17, 171, 251, 204, 17, 182, 251, 204, 31, 203, 23, 251, 204, 31, + 200, 234, 251, 204, 2, 4, 208, 132, 251, 204, 2, 208, 132, 251, 204, 2, + 209, 125, 251, 204, 16, 199, 34, 239, 16, 1, 63, 239, 16, 1, 252, 168, + 239, 16, 1, 68, 239, 16, 1, 226, 120, 239, 16, 1, 66, 239, 16, 1, 199, + 245, 239, 16, 1, 69, 239, 16, 1, 251, 200, 239, 16, 1, 72, 239, 16, 1, + 250, 150, 239, 16, 1, 155, 239, 16, 1, 224, 146, 239, 16, 1, 234, 123, + 239, 16, 1, 233, 230, 239, 16, 1, 217, 71, 239, 16, 1, 247, 174, 239, 16, + 1, 247, 16, 239, 16, 1, 225, 214, 239, 16, 1, 225, 180, 239, 16, 1, 215, + 109, 239, 16, 1, 201, 78, 239, 16, 1, 201, 66, 239, 16, 1, 240, 41, 239, + 16, 1, 240, 25, 239, 16, 1, 216, 86, 239, 16, 1, 189, 239, 16, 1, 202, + 233, 239, 16, 1, 240, 136, 239, 16, 1, 239, 176, 239, 16, 1, 176, 239, + 16, 1, 161, 239, 16, 1, 213, 6, 239, 16, 1, 249, 145, 239, 16, 1, 248, + 197, 239, 16, 1, 166, 239, 16, 1, 164, 239, 16, 1, 169, 239, 16, 1, 172, + 239, 16, 1, 199, 152, 239, 16, 1, 207, 50, 239, 16, 1, 205, 80, 239, 16, + 1, 183, 239, 16, 1, 142, 239, 16, 1, 209, 181, 239, 16, 18, 2, 252, 168, + 239, 16, 18, 2, 68, 239, 16, 18, 2, 226, 120, 239, 16, 18, 2, 66, 239, + 16, 18, 2, 199, 245, 239, 16, 18, 2, 110, 144, 239, 16, 18, 2, 110, 209, + 182, 239, 16, 18, 2, 69, 239, 16, 18, 2, 251, 200, 239, 16, 18, 2, 72, + 239, 16, 18, 2, 250, 150, 239, 16, 2, 251, 51, 239, 16, 2, 199, 2, 239, + 16, 2, 199, 7, 239, 16, 2, 215, 149, 239, 16, 252, 30, 55, 197, 139, 244, + 236, 6, 1, 217, 70, 197, 139, 244, 236, 6, 1, 63, 197, 139, 244, 236, 6, + 1, 197, 70, 197, 139, 244, 236, 6, 1, 195, 217, 197, 139, 244, 236, 6, 1, + 164, 197, 139, 244, 236, 6, 1, 196, 3, 197, 139, 244, 236, 6, 1, 226, + 120, 197, 139, 244, 236, 6, 1, 199, 245, 197, 139, 244, 236, 6, 1, 69, + 197, 139, 244, 236, 6, 1, 72, 197, 139, 244, 236, 6, 1, 251, 97, 197, + 139, 244, 236, 6, 1, 234, 123, 197, 139, 244, 236, 6, 1, 224, 11, 197, + 139, 244, 236, 6, 1, 236, 193, 197, 139, 244, 236, 6, 1, 195, 196, 197, + 139, 244, 236, 6, 1, 200, 106, 197, 139, 244, 236, 6, 1, 236, 212, 197, + 139, 244, 236, 6, 1, 214, 167, 197, 139, 244, 236, 6, 1, 201, 73, 197, + 139, 244, 236, 6, 1, 215, 135, 197, 139, 244, 236, 6, 1, 240, 136, 197, + 139, 244, 236, 6, 1, 250, 168, 197, 139, 244, 236, 6, 1, 251, 123, 197, + 139, 244, 236, 6, 1, 248, 21, 197, 139, 244, 236, 6, 1, 211, 227, 197, + 139, 244, 236, 6, 1, 232, 29, 197, 139, 244, 236, 6, 1, 231, 173, 197, + 139, 244, 236, 6, 1, 231, 100, 197, 139, 244, 236, 6, 1, 232, 175, 197, + 139, 244, 236, 6, 1, 205, 31, 197, 139, 244, 236, 6, 1, 206, 84, 197, + 139, 244, 236, 6, 1, 198, 249, 197, 139, 244, 236, 4, 1, 217, 70, 197, + 139, 244, 236, 4, 1, 63, 197, 139, 244, 236, 4, 1, 197, 70, 197, 139, + 244, 236, 4, 1, 195, 217, 197, 139, 244, 236, 4, 1, 164, 197, 139, 244, + 236, 4, 1, 196, 3, 197, 139, 244, 236, 4, 1, 226, 120, 197, 139, 244, + 236, 4, 1, 199, 245, 197, 139, 244, 236, 4, 1, 69, 197, 139, 244, 236, 4, + 1, 72, 197, 139, 244, 236, 4, 1, 251, 97, 197, 139, 244, 236, 4, 1, 234, + 123, 197, 139, 244, 236, 4, 1, 224, 11, 197, 139, 244, 236, 4, 1, 236, + 193, 197, 139, 244, 236, 4, 1, 195, 196, 197, 139, 244, 236, 4, 1, 200, + 106, 197, 139, 244, 236, 4, 1, 236, 212, 197, 139, 244, 236, 4, 1, 214, + 167, 197, 139, 244, 236, 4, 1, 201, 73, 197, 139, 244, 236, 4, 1, 215, + 135, 197, 139, 244, 236, 4, 1, 240, 136, 197, 139, 244, 236, 4, 1, 250, + 168, 197, 139, 244, 236, 4, 1, 251, 123, 197, 139, 244, 236, 4, 1, 248, + 21, 197, 139, 244, 236, 4, 1, 211, 227, 197, 139, 244, 236, 4, 1, 232, + 29, 197, 139, 244, 236, 4, 1, 231, 173, 197, 139, 244, 236, 4, 1, 231, + 100, 197, 139, 244, 236, 4, 1, 232, 175, 197, 139, 244, 236, 4, 1, 205, + 31, 197, 139, 244, 236, 4, 1, 206, 84, 197, 139, 244, 236, 4, 1, 198, + 249, 197, 139, 244, 236, 17, 195, 79, 197, 139, 244, 236, 17, 100, 197, + 139, 244, 236, 17, 102, 197, 139, 244, 236, 17, 134, 197, 139, 244, 236, + 17, 136, 197, 139, 244, 236, 17, 146, 197, 139, 244, 236, 17, 167, 197, + 139, 244, 236, 17, 178, 197, 139, 244, 236, 17, 171, 197, 139, 244, 236, + 17, 182, 197, 139, 244, 236, 31, 203, 23, 197, 139, 244, 236, 31, 200, + 234, 197, 139, 244, 236, 31, 202, 177, 197, 139, 244, 236, 31, 235, 14, + 197, 139, 244, 236, 31, 235, 145, 197, 139, 244, 236, 31, 206, 13, 197, + 139, 244, 236, 31, 207, 65, 197, 139, 244, 236, 31, 237, 20, 197, 139, + 244, 236, 31, 216, 174, 197, 139, 244, 236, 214, 127, 217, 218, 1, 63, + 217, 218, 1, 252, 168, 217, 218, 1, 68, 217, 218, 1, 226, 120, 217, 218, + 1, 66, 217, 218, 1, 199, 245, 217, 218, 1, 110, 144, 217, 218, 1, 110, + 209, 182, 217, 218, 1, 69, 217, 218, 1, 251, 200, 217, 218, 1, 72, 217, + 218, 1, 250, 150, 217, 218, 1, 155, 217, 218, 1, 224, 146, 217, 218, 1, + 234, 123, 217, 218, 1, 233, 230, 217, 218, 1, 217, 71, 217, 218, 1, 247, + 174, 217, 218, 1, 247, 16, 217, 218, 1, 225, 214, 217, 218, 1, 225, 180, + 217, 218, 1, 215, 109, 217, 218, 1, 201, 78, 217, 218, 1, 201, 66, 217, + 218, 1, 240, 41, 217, 218, 1, 240, 25, 217, 218, 1, 216, 86, 217, 218, 1, + 189, 217, 218, 1, 202, 233, 217, 218, 1, 240, 136, 217, 218, 1, 239, 176, + 217, 218, 1, 176, 217, 218, 1, 161, 217, 218, 1, 213, 6, 217, 218, 1, + 249, 145, 217, 218, 1, 248, 197, 217, 218, 1, 166, 217, 218, 1, 164, 217, + 218, 1, 169, 217, 218, 1, 172, 217, 218, 1, 199, 152, 217, 218, 1, 207, + 50, 217, 218, 1, 205, 80, 217, 218, 1, 183, 217, 218, 1, 142, 217, 218, + 1, 222, 37, 217, 218, 1, 209, 181, 217, 218, 18, 2, 252, 168, 217, 218, + 18, 2, 68, 217, 218, 18, 2, 226, 120, 217, 218, 18, 2, 66, 217, 218, 18, + 2, 199, 245, 217, 218, 18, 2, 110, 144, 217, 218, 18, 2, 110, 209, 182, + 217, 218, 18, 2, 69, 217, 218, 18, 2, 251, 200, 217, 218, 18, 2, 72, 217, + 218, 18, 2, 250, 150, 217, 218, 2, 251, 51, 217, 218, 2, 199, 2, 217, + 218, 2, 199, 7, 217, 218, 2, 250, 132, 217, 218, 2, 206, 100, 217, 218, + 232, 130, 217, 218, 18, 2, 212, 11, 69, 195, 102, 47, 1, 63, 195, 102, + 47, 18, 2, 68, 195, 102, 47, 18, 2, 200, 99, 195, 102, 47, 18, 2, 66, + 195, 102, 47, 18, 2, 69, 195, 102, 47, 18, 2, 214, 164, 195, 102, 47, 18, + 2, 72, 195, 102, 47, 18, 2, 251, 200, 195, 102, 47, 18, 2, 250, 150, 195, + 102, 47, 18, 2, 210, 89, 68, 195, 102, 47, 18, 222, 158, 78, 195, 102, + 47, 1, 155, 195, 102, 47, 1, 224, 146, 195, 102, 47, 1, 234, 123, 195, + 102, 47, 1, 233, 230, 195, 102, 47, 1, 217, 71, 195, 102, 47, 1, 247, + 174, 195, 102, 47, 1, 247, 16, 195, 102, 47, 1, 225, 214, 195, 102, 47, + 1, 215, 109, 195, 102, 47, 1, 201, 78, 195, 102, 47, 1, 201, 66, 195, + 102, 47, 1, 240, 41, 195, 102, 47, 1, 240, 25, 195, 102, 47, 1, 216, 86, + 195, 102, 47, 1, 189, 195, 102, 47, 1, 202, 233, 195, 102, 47, 1, 240, + 136, 195, 102, 47, 1, 239, 176, 195, 102, 47, 1, 176, 195, 102, 47, 1, + 161, 195, 102, 47, 1, 213, 6, 195, 102, 47, 1, 249, 145, 195, 102, 47, 1, + 248, 197, 195, 102, 47, 1, 166, 195, 102, 47, 1, 201, 113, 195, 102, 47, + 1, 201, 103, 195, 102, 47, 1, 237, 156, 195, 102, 47, 1, 237, 150, 195, + 102, 47, 1, 195, 74, 195, 102, 47, 1, 195, 115, 195, 102, 47, 1, 255, + 176, 195, 102, 47, 1, 164, 195, 102, 47, 1, 169, 195, 102, 47, 1, 172, + 195, 102, 47, 1, 199, 152, 195, 102, 47, 1, 207, 50, 195, 102, 47, 1, + 205, 80, 195, 102, 47, 1, 183, 195, 102, 47, 1, 142, 195, 102, 47, 1, + 223, 201, 195, 102, 47, 48, 108, 78, 195, 102, 47, 2, 199, 7, 195, 102, + 47, 2, 247, 133, 195, 102, 47, 2, 247, 134, 3, 214, 59, 195, 102, 47, 2, + 247, 136, 3, 214, 59, 195, 102, 47, 2, 251, 51, 195, 102, 47, 2, 199, 2, + 195, 102, 47, 244, 185, 1, 169, 195, 102, 47, 244, 186, 1, 164, 195, 102, + 47, 244, 186, 1, 169, 195, 102, 47, 244, 186, 1, 172, 195, 102, 47, 244, + 186, 1, 199, 152, 195, 102, 47, 84, 232, 138, 78, 195, 102, 47, 244, 199, + 232, 138, 78, 195, 102, 47, 117, 201, 98, 195, 102, 47, 117, 207, 42, + 195, 102, 47, 117, 52, 207, 42, 195, 102, 47, 117, 181, 201, 98, 195, + 102, 47, 84, 237, 242, 232, 138, 78, 195, 102, 47, 244, 199, 237, 242, + 232, 138, 78, 195, 102, 47, 204, 151, 205, 152, 1, 63, 205, 152, 18, 2, + 68, 205, 152, 18, 2, 200, 99, 205, 152, 18, 2, 66, 205, 152, 18, 2, 69, + 205, 152, 18, 2, 72, 205, 152, 18, 2, 214, 164, 205, 152, 18, 2, 251, + 200, 205, 152, 18, 2, 250, 150, 205, 152, 18, 2, 110, 144, 205, 152, 18, + 2, 110, 159, 205, 152, 18, 222, 158, 78, 205, 152, 1, 155, 205, 152, 1, + 224, 146, 205, 152, 1, 234, 123, 205, 152, 1, 233, 230, 205, 152, 1, 217, + 71, 205, 152, 1, 247, 174, 205, 152, 1, 247, 16, 205, 152, 1, 225, 214, + 205, 152, 1, 225, 180, 205, 152, 1, 215, 109, 205, 152, 1, 201, 78, 205, + 152, 1, 201, 66, 205, 152, 1, 240, 41, 205, 152, 1, 240, 25, 205, 152, 1, + 216, 86, 205, 152, 1, 189, 205, 152, 1, 202, 233, 205, 152, 1, 240, 136, + 205, 152, 1, 239, 176, 205, 152, 1, 176, 205, 152, 1, 161, 205, 152, 1, + 213, 6, 205, 152, 1, 249, 145, 205, 152, 1, 248, 197, 205, 152, 1, 166, + 205, 152, 1, 201, 113, 205, 152, 1, 201, 103, 205, 152, 1, 237, 156, 205, + 152, 1, 195, 74, 205, 152, 1, 195, 115, 205, 152, 1, 255, 176, 205, 152, + 1, 164, 205, 152, 1, 169, 205, 152, 1, 172, 205, 152, 1, 199, 152, 205, + 152, 1, 207, 50, 205, 152, 1, 205, 80, 205, 152, 1, 183, 205, 152, 1, + 142, 205, 152, 1, 223, 201, 205, 152, 2, 225, 165, 205, 152, 2, 200, 34, + 205, 152, 244, 185, 1, 169, 205, 152, 244, 185, 1, 172, 205, 152, 244, + 185, 1, 207, 50, 205, 152, 244, 185, 1, 183, 205, 152, 48, 108, 2, 234, + 190, 205, 152, 48, 108, 2, 225, 80, 205, 152, 48, 108, 2, 217, 73, 205, + 152, 48, 108, 2, 240, 231, 205, 152, 48, 108, 2, 218, 55, 205, 152, 48, + 108, 2, 250, 112, 205, 152, 48, 108, 2, 221, 136, 205, 152, 48, 108, 2, + 144, 205, 152, 48, 108, 2, 159, 205, 152, 48, 108, 2, 207, 52, 205, 152, + 48, 108, 2, 209, 80, 205, 152, 48, 108, 2, 255, 176, 205, 152, 2, 251, + 51, 205, 152, 2, 199, 2, 205, 152, 234, 36, 78, 205, 152, 204, 151, 205, + 152, 117, 201, 98, 205, 152, 117, 207, 42, 205, 152, 117, 52, 207, 42, + 205, 152, 117, 212, 123, 205, 152, 232, 138, 117, 3, 218, 190, 26, 204, + 112, 26, 201, 165, 235, 86, 205, 152, 232, 138, 117, 3, 218, 190, 26, + 204, 112, 26, 235, 86, 205, 152, 232, 138, 117, 3, 218, 190, 26, 204, + 111, 205, 152, 203, 9, 220, 28, 205, 152, 203, 9, 220, 27, 213, 109, 244, + 254, 232, 159, 1, 161, 213, 109, 244, 254, 232, 159, 1, 155, 213, 109, + 244, 254, 232, 159, 1, 172, 213, 109, 244, 254, 232, 159, 1, 166, 213, + 109, 244, 254, 232, 159, 1, 240, 136, 213, 109, 244, 254, 232, 159, 1, + 195, 115, 213, 109, 244, 254, 232, 159, 1, 199, 152, 213, 109, 244, 254, + 232, 159, 1, 217, 71, 213, 109, 244, 254, 232, 159, 1, 142, 213, 109, + 244, 254, 232, 159, 1, 234, 123, 213, 109, 244, 254, 232, 159, 1, 224, + 146, 213, 109, 244, 254, 232, 159, 1, 183, 213, 109, 244, 254, 232, 159, + 1, 249, 145, 213, 109, 244, 254, 232, 159, 1, 247, 174, 213, 109, 244, + 254, 232, 159, 1, 189, 213, 109, 244, 254, 232, 159, 1, 202, 233, 213, + 109, 244, 254, 232, 159, 1, 176, 213, 109, 244, 254, 232, 159, 1, 213, 6, + 213, 109, 244, 254, 232, 159, 1, 169, 213, 109, 244, 254, 232, 159, 1, + 235, 239, 213, 109, 244, 254, 232, 159, 1, 247, 16, 213, 109, 244, 254, + 232, 159, 1, 63, 213, 109, 244, 254, 232, 159, 1, 69, 213, 109, 244, 254, + 232, 159, 1, 68, 213, 109, 244, 254, 232, 159, 1, 72, 213, 109, 244, 254, + 232, 159, 1, 66, 213, 109, 244, 254, 232, 159, 1, 200, 114, 213, 109, + 244, 254, 232, 159, 1, 230, 210, 213, 109, 244, 254, 232, 159, 1, 48, + 214, 3, 213, 109, 244, 254, 232, 159, 1, 48, 225, 80, 213, 109, 244, 254, + 232, 159, 1, 48, 203, 216, 213, 109, 244, 254, 232, 159, 1, 48, 221, 136, + 213, 109, 244, 254, 232, 159, 1, 48, 218, 55, 213, 109, 244, 254, 232, + 159, 1, 48, 159, 213, 109, 244, 254, 232, 159, 1, 48, 197, 199, 213, 109, + 244, 254, 232, 159, 1, 48, 217, 73, 213, 109, 244, 254, 232, 159, 1, 48, + 196, 148, 213, 109, 244, 254, 232, 159, 209, 250, 152, 221, 240, 213, + 109, 244, 254, 232, 159, 209, 250, 202, 11, 213, 109, 244, 254, 232, 159, + 208, 215, 233, 152, 204, 226, 213, 109, 244, 254, 232, 159, 209, 250, + 152, 181, 235, 130, 213, 109, 244, 254, 232, 159, 209, 250, 152, 235, + 130, 213, 109, 244, 254, 232, 159, 208, 215, 233, 152, 204, 227, 235, + 130, 213, 109, 244, 254, 232, 159, 208, 215, 152, 221, 240, 213, 109, + 244, 254, 232, 159, 208, 215, 202, 11, 213, 109, 244, 254, 232, 159, 208, + 215, 152, 181, 235, 130, 213, 109, 244, 254, 232, 159, 208, 215, 152, + 235, 130, 213, 109, 244, 254, 232, 159, 219, 64, 202, 11, 213, 109, 244, + 254, 232, 159, 233, 152, 204, 227, 199, 131, 213, 109, 244, 254, 232, + 159, 219, 64, 152, 181, 235, 130, 213, 109, 244, 254, 232, 159, 219, 64, + 152, 235, 130, 213, 109, 244, 254, 232, 159, 221, 206, 152, 221, 240, + 213, 109, 244, 254, 232, 159, 221, 206, 202, 11, 213, 109, 244, 254, 232, + 159, 233, 152, 204, 226, 213, 109, 244, 254, 232, 159, 221, 206, 152, + 181, 235, 130, 213, 109, 244, 254, 232, 159, 221, 206, 152, 235, 130, + 213, 109, 244, 254, 232, 159, 233, 152, 204, 227, 235, 130, 248, 195, 1, + 63, 248, 195, 1, 252, 168, 248, 195, 1, 68, 248, 195, 1, 226, 120, 248, + 195, 1, 66, 248, 195, 1, 199, 245, 248, 195, 1, 110, 144, 248, 195, 1, + 110, 209, 182, 248, 195, 1, 110, 159, 248, 195, 1, 69, 248, 195, 1, 251, + 200, 248, 195, 1, 72, 248, 195, 1, 250, 150, 248, 195, 1, 155, 248, 195, + 1, 224, 146, 248, 195, 1, 234, 123, 248, 195, 1, 233, 230, 248, 195, 1, + 217, 71, 248, 195, 1, 247, 174, 248, 195, 1, 247, 16, 248, 195, 1, 225, + 214, 248, 195, 1, 225, 180, 248, 195, 1, 215, 109, 248, 195, 1, 201, 78, + 248, 195, 1, 201, 66, 248, 195, 1, 240, 41, 248, 195, 1, 240, 25, 248, + 195, 1, 216, 86, 248, 195, 1, 189, 248, 195, 1, 202, 233, 248, 195, 1, + 240, 136, 248, 195, 1, 239, 176, 248, 195, 1, 176, 248, 195, 1, 161, 248, + 195, 1, 213, 6, 248, 195, 1, 249, 145, 248, 195, 1, 248, 197, 248, 195, + 1, 166, 248, 195, 1, 164, 248, 195, 1, 169, 248, 195, 1, 172, 248, 195, + 1, 199, 152, 248, 195, 1, 207, 50, 248, 195, 1, 205, 80, 248, 195, 1, + 183, 248, 195, 1, 142, 248, 195, 18, 2, 252, 168, 248, 195, 18, 2, 68, + 248, 195, 18, 2, 226, 120, 248, 195, 18, 2, 66, 248, 195, 18, 2, 199, + 245, 248, 195, 18, 2, 110, 144, 248, 195, 18, 2, 110, 209, 182, 248, 195, + 18, 2, 110, 159, 248, 195, 18, 2, 69, 248, 195, 18, 2, 251, 200, 248, + 195, 18, 2, 72, 248, 195, 18, 2, 250, 150, 248, 195, 2, 247, 133, 248, + 195, 2, 251, 51, 248, 195, 2, 199, 2, 248, 195, 2, 199, 7, 248, 195, 2, + 250, 132, 248, 195, 240, 88, 248, 195, 52, 240, 88, 248, 195, 197, 9, + 207, 90, 248, 195, 234, 87, 235, 133, 248, 195, 234, 87, 235, 132, 248, + 195, 17, 195, 79, 248, 195, 17, 100, 248, 195, 17, 102, 248, 195, 17, + 134, 248, 195, 17, 136, 248, 195, 17, 146, 248, 195, 17, 167, 248, 195, + 17, 178, 248, 195, 17, 171, 248, 195, 17, 182, 248, 195, 31, 100, 248, + 195, 31, 102, 248, 195, 31, 134, 248, 195, 31, 136, 248, 195, 31, 146, + 248, 195, 31, 167, 248, 195, 31, 178, 248, 195, 31, 171, 248, 195, 31, + 182, 248, 195, 31, 203, 23, 248, 195, 31, 200, 234, 248, 195, 31, 202, + 177, 248, 195, 31, 235, 14, 248, 195, 31, 235, 145, 248, 195, 31, 206, + 13, 248, 195, 31, 207, 65, 248, 195, 31, 237, 20, 248, 195, 31, 216, 174, + 248, 195, 231, 56, 200, 50, 78, 220, 30, 232, 138, 78, 220, 30, 117, 207, + 42, 220, 30, 1, 155, 220, 30, 1, 224, 146, 220, 30, 1, 234, 123, 220, 30, + 1, 217, 71, 220, 30, 1, 247, 174, 220, 30, 1, 247, 16, 220, 30, 1, 225, + 214, 220, 30, 1, 215, 109, 220, 30, 1, 189, 220, 30, 1, 202, 233, 220, + 30, 1, 240, 136, 220, 30, 1, 176, 220, 30, 1, 161, 220, 30, 1, 213, 6, + 220, 30, 1, 249, 145, 220, 30, 1, 166, 220, 30, 1, 201, 113, 220, 30, 1, + 201, 103, 220, 30, 1, 237, 156, 220, 30, 1, 197, 166, 220, 30, 1, 195, + 74, 220, 30, 1, 195, 115, 220, 30, 1, 255, 176, 220, 30, 1, 164, 220, 30, + 1, 169, 220, 30, 1, 172, 220, 30, 1, 207, 50, 220, 30, 1, 183, 220, 30, + 1, 142, 220, 30, 1, 63, 220, 30, 204, 152, 1, 155, 220, 30, 204, 152, 1, + 224, 146, 220, 30, 204, 152, 1, 234, 123, 220, 30, 204, 152, 1, 217, 71, + 220, 30, 204, 152, 1, 247, 174, 220, 30, 204, 152, 1, 247, 16, 220, 30, + 204, 152, 1, 225, 214, 220, 30, 204, 152, 1, 215, 109, 220, 30, 204, 152, + 1, 189, 220, 30, 204, 152, 1, 202, 233, 220, 30, 204, 152, 1, 240, 136, + 220, 30, 204, 152, 1, 176, 220, 30, 204, 152, 1, 161, 220, 30, 204, 152, + 1, 213, 6, 220, 30, 204, 152, 1, 249, 145, 220, 30, 204, 152, 1, 166, + 220, 30, 204, 152, 1, 201, 113, 220, 30, 204, 152, 1, 201, 103, 220, 30, + 204, 152, 1, 237, 156, 220, 30, 204, 152, 1, 197, 166, 220, 30, 204, 152, + 1, 195, 74, 220, 30, 204, 152, 1, 195, 115, 220, 30, 204, 152, 1, 164, + 220, 30, 204, 152, 1, 169, 220, 30, 204, 152, 1, 172, 220, 30, 204, 152, + 1, 207, 50, 220, 30, 204, 152, 1, 183, 220, 30, 204, 152, 1, 142, 220, + 30, 204, 152, 1, 63, 220, 30, 18, 2, 252, 168, 220, 30, 18, 2, 68, 220, + 30, 18, 2, 66, 220, 30, 18, 2, 69, 220, 30, 18, 2, 72, 220, 30, 2, 251, + 51, 220, 30, 2, 247, 133, 220, 14, 121, 1, 63, 220, 14, 121, 1, 252, 168, + 220, 14, 121, 1, 68, 220, 14, 121, 1, 226, 120, 220, 14, 121, 1, 66, 220, + 14, 121, 1, 199, 245, 220, 14, 121, 1, 69, 220, 14, 121, 1, 251, 200, + 220, 14, 121, 1, 72, 220, 14, 121, 1, 250, 150, 220, 14, 121, 1, 155, + 220, 14, 121, 1, 224, 146, 220, 14, 121, 1, 234, 123, 220, 14, 121, 1, + 233, 230, 220, 14, 121, 1, 217, 71, 220, 14, 121, 1, 247, 174, 220, 14, + 121, 1, 247, 16, 220, 14, 121, 1, 225, 214, 220, 14, 121, 1, 225, 180, + 220, 14, 121, 1, 215, 109, 220, 14, 121, 1, 201, 78, 220, 14, 121, 1, + 201, 66, 220, 14, 121, 1, 240, 41, 220, 14, 121, 1, 240, 25, 220, 14, + 121, 1, 216, 86, 220, 14, 121, 1, 189, 220, 14, 121, 1, 202, 233, 220, + 14, 121, 1, 240, 136, 220, 14, 121, 1, 239, 176, 220, 14, 121, 1, 176, + 220, 14, 121, 1, 161, 220, 14, 121, 1, 213, 6, 220, 14, 121, 1, 249, 145, + 220, 14, 121, 1, 248, 197, 220, 14, 121, 1, 166, 220, 14, 121, 1, 164, + 220, 14, 121, 1, 169, 220, 14, 121, 1, 172, 220, 14, 121, 1, 199, 152, + 220, 14, 121, 1, 207, 50, 220, 14, 121, 1, 205, 80, 220, 14, 121, 1, 183, + 220, 14, 121, 1, 142, 220, 14, 121, 1, 222, 37, 220, 14, 121, 1, 223, + 201, 220, 14, 121, 1, 225, 130, 220, 14, 121, 1, 201, 217, 220, 14, 121, + 18, 2, 252, 168, 220, 14, 121, 18, 2, 68, 220, 14, 121, 18, 2, 226, 120, + 220, 14, 121, 18, 2, 66, 220, 14, 121, 18, 2, 199, 245, 220, 14, 121, 18, + 2, 110, 144, 220, 14, 121, 18, 2, 69, 220, 14, 121, 18, 2, 251, 200, 220, + 14, 121, 18, 2, 72, 220, 14, 121, 18, 2, 250, 150, 220, 14, 121, 2, 251, + 51, 220, 14, 121, 2, 199, 2, 220, 14, 121, 2, 215, 149, 220, 14, 121, 2, + 247, 135, 220, 14, 121, 2, 232, 227, 220, 14, 121, 199, 7, 220, 14, 121, + 210, 115, 220, 14, 121, 210, 247, 220, 14, 121, 17, 195, 79, 220, 14, + 121, 17, 100, 220, 14, 121, 17, 102, 220, 14, 121, 17, 134, 220, 14, 121, + 17, 136, 220, 14, 121, 17, 146, 220, 14, 121, 17, 167, 220, 14, 121, 17, + 178, 220, 14, 121, 17, 171, 220, 14, 121, 17, 182, 233, 54, 121, 1, 63, + 233, 54, 121, 1, 252, 168, 233, 54, 121, 1, 68, 233, 54, 121, 1, 226, + 120, 233, 54, 121, 1, 66, 233, 54, 121, 1, 199, 245, 233, 54, 121, 1, + 237, 54, 233, 54, 121, 1, 251, 200, 233, 54, 121, 1, 214, 102, 233, 54, + 121, 1, 250, 150, 233, 54, 121, 1, 164, 233, 54, 121, 1, 199, 152, 233, + 54, 121, 1, 249, 145, 233, 54, 121, 1, 248, 197, 233, 54, 121, 1, 166, + 233, 54, 121, 1, 155, 233, 54, 121, 1, 224, 146, 233, 54, 121, 1, 189, + 233, 54, 121, 1, 202, 233, 233, 54, 121, 1, 172, 233, 54, 121, 1, 234, + 123, 233, 54, 121, 1, 233, 230, 233, 54, 121, 1, 240, 136, 233, 54, 121, + 1, 239, 176, 233, 54, 121, 1, 176, 233, 54, 121, 1, 247, 174, 233, 54, + 121, 1, 247, 16, 233, 54, 121, 1, 201, 78, 233, 54, 121, 1, 201, 66, 233, + 54, 121, 1, 222, 37, 233, 54, 121, 1, 225, 214, 233, 54, 121, 1, 225, + 180, 233, 54, 121, 1, 240, 41, 233, 54, 121, 1, 240, 25, 233, 54, 121, 1, + 217, 71, 233, 54, 121, 1, 161, 233, 54, 121, 1, 213, 6, 233, 54, 121, 1, + 142, 233, 54, 121, 1, 169, 233, 54, 121, 1, 183, 233, 54, 121, 18, 2, + 252, 168, 233, 54, 121, 18, 2, 68, 233, 54, 121, 18, 2, 226, 120, 233, + 54, 121, 18, 2, 66, 233, 54, 121, 18, 2, 199, 245, 233, 54, 121, 18, 2, + 237, 54, 233, 54, 121, 18, 2, 251, 200, 233, 54, 121, 18, 2, 214, 102, + 233, 54, 121, 18, 2, 250, 150, 233, 54, 121, 2, 251, 51, 233, 54, 121, 2, + 199, 2, 233, 54, 121, 199, 7, 233, 54, 121, 214, 127, 233, 54, 121, 17, + 195, 79, 233, 54, 121, 17, 100, 233, 54, 121, 17, 102, 233, 54, 121, 17, + 134, 233, 54, 121, 17, 136, 233, 54, 121, 17, 146, 233, 54, 121, 17, 167, + 233, 54, 121, 17, 178, 233, 54, 121, 17, 171, 233, 54, 121, 17, 182, 220, + 71, 1, 155, 220, 71, 1, 234, 123, 220, 71, 1, 217, 71, 220, 71, 1, 161, + 220, 71, 1, 249, 145, 220, 71, 1, 166, 220, 71, 1, 189, 220, 71, 1, 240, + 136, 220, 71, 1, 176, 220, 71, 1, 247, 174, 220, 71, 1, 225, 214, 220, + 71, 1, 215, 109, 220, 71, 1, 164, 220, 71, 1, 169, 220, 71, 1, 172, 220, + 71, 1, 199, 152, 220, 71, 1, 183, 220, 71, 1, 63, 220, 71, 251, 93, 220, + 71, 18, 2, 68, 220, 71, 18, 2, 66, 220, 71, 18, 2, 69, 220, 71, 18, 2, + 72, 220, 71, 213, 121, 220, 71, 236, 222, 77, 208, 132, 42, 191, 97, 202, + 151, 42, 191, 97, 214, 115, 42, 191, 97, 237, 23, 42, 191, 97, 206, 11, + 42, 191, 97, 235, 17, 42, 191, 97, 202, 173, 42, 191, 115, 237, 22, 42, + 191, 115, 206, 10, 42, 191, 97, 200, 237, 42, 191, 97, 206, 20, 42, 191, + 97, 206, 19, 42, 191, 97, 203, 14, 42, 191, 97, 237, 26, 42, 191, 115, + 200, 236, 42, 191, 115, 206, 18, 42, 191, 97, 235, 148, 42, 191, 97, 211, + 87, 42, 191, 97, 232, 224, 42, 191, 97, 232, 223, 42, 191, 115, 211, 85, + 42, 191, 237, 233, 235, 223, 224, 79, 42, 2, 217, 102, 42, 2, 247, 21, + 42, 2, 252, 119, 42, 2, 199, 233, 42, 2, 218, 82, 42, 2, 223, 151, 42, 2, + 213, 112, 42, 2, 218, 126, 42, 2, 225, 52, 42, 2, 213, 189, 42, 2, 212, + 93, 42, 2, 199, 137, 42, 2, 213, 238, 42, 2, 223, 140, 42, 2, 199, 108, + 42, 197, 85, 241, 33, 55, 42, 237, 204, 241, 33, 55, 42, 222, 237, 55, + 42, 208, 234, 213, 192, 55, 42, 201, 212, 241, 74, 55, 42, 201, 212, 31, + 55, 42, 241, 16, 55, 42, 26, 214, 168, 55, 42, 205, 129, 55, 42, 201, + 228, 55, 42, 226, 87, 212, 76, 55, 42, 205, 1, 234, 235, 55, 42, 2, 218, + 86, 42, 2, 199, 145, 42, 211, 214, 236, 222, 77, 202, 237, 10, 2, 63, 10, + 2, 39, 24, 63, 10, 2, 39, 24, 249, 127, 10, 2, 39, 24, 234, 92, 203, 12, + 10, 2, 39, 24, 142, 10, 2, 39, 24, 226, 122, 10, 2, 39, 24, 223, 61, 233, + 52, 10, 2, 39, 24, 218, 93, 10, 2, 39, 24, 209, 1, 10, 2, 254, 177, 10, + 2, 252, 117, 10, 2, 252, 118, 24, 250, 193, 10, 2, 252, 118, 24, 237, + 187, 233, 52, 10, 2, 252, 118, 24, 234, 105, 10, 2, 252, 118, 24, 234, + 92, 203, 12, 10, 2, 252, 118, 24, 142, 10, 2, 252, 118, 24, 226, 123, + 233, 52, 10, 2, 252, 118, 24, 226, 96, 10, 2, 252, 118, 24, 223, 62, 10, + 2, 252, 118, 24, 206, 239, 10, 2, 252, 118, 24, 118, 98, 118, 98, 66, 10, + 2, 252, 118, 233, 52, 10, 2, 252, 34, 10, 2, 252, 35, 24, 249, 106, 10, + 2, 252, 35, 24, 234, 92, 203, 12, 10, 2, 252, 35, 24, 219, 208, 98, 236, + 230, 10, 2, 252, 35, 24, 207, 48, 10, 2, 252, 35, 24, 203, 129, 10, 2, + 252, 6, 10, 2, 251, 181, 10, 2, 251, 182, 24, 236, 157, 10, 2, 251, 182, + 24, 206, 201, 98, 233, 164, 10, 2, 251, 173, 10, 2, 251, 174, 24, 251, + 173, 10, 2, 251, 174, 24, 239, 105, 10, 2, 251, 174, 24, 233, 164, 10, 2, + 251, 174, 24, 142, 10, 2, 251, 174, 24, 225, 40, 10, 2, 251, 174, 24, + 224, 101, 10, 2, 251, 174, 24, 206, 255, 10, 2, 251, 174, 24, 199, 253, + 10, 2, 251, 170, 10, 2, 251, 162, 10, 2, 251, 119, 10, 2, 251, 120, 24, + 206, 255, 10, 2, 251, 106, 10, 2, 251, 107, 127, 251, 106, 10, 2, 251, + 107, 115, 202, 76, 10, 2, 251, 107, 98, 217, 235, 214, 79, 251, 107, 98, + 217, 234, 10, 2, 251, 107, 98, 217, 235, 205, 93, 10, 2, 251, 71, 10, 2, + 251, 41, 10, 2, 251, 7, 10, 2, 251, 8, 24, 223, 154, 10, 2, 250, 235, 10, + 2, 250, 200, 10, 2, 250, 195, 10, 2, 250, 196, 195, 29, 203, 12, 10, 2, + 250, 196, 225, 44, 203, 12, 10, 2, 250, 196, 127, 250, 196, 201, 29, 127, + 201, 29, 201, 29, 127, 201, 29, 213, 163, 10, 2, 250, 196, 127, 250, 196, + 127, 250, 195, 10, 2, 250, 196, 127, 250, 196, 127, 250, 196, 241, 55, + 250, 196, 127, 250, 196, 127, 250, 195, 10, 2, 250, 193, 10, 2, 250, 189, + 10, 2, 249, 145, 10, 2, 249, 127, 10, 2, 249, 121, 10, 2, 249, 113, 10, + 2, 249, 107, 10, 2, 249, 108, 127, 249, 107, 10, 2, 249, 106, 10, 2, 154, + 10, 2, 249, 79, 10, 2, 248, 184, 10, 2, 248, 185, 24, 63, 10, 2, 248, + 185, 24, 234, 83, 10, 2, 248, 185, 24, 226, 123, 233, 52, 10, 2, 248, 21, + 10, 2, 248, 22, 127, 248, 22, 252, 117, 10, 2, 248, 22, 127, 248, 22, + 200, 72, 10, 2, 248, 22, 241, 55, 248, 21, 10, 2, 247, 255, 10, 2, 248, + 0, 127, 247, 255, 10, 2, 247, 244, 10, 2, 247, 243, 10, 2, 240, 136, 10, + 2, 240, 126, 10, 2, 240, 127, 224, 60, 24, 39, 98, 220, 12, 10, 2, 240, + 127, 224, 60, 24, 251, 119, 10, 2, 240, 127, 224, 60, 24, 249, 106, 10, + 2, 240, 127, 224, 60, 24, 248, 184, 10, 2, 240, 127, 224, 60, 24, 234, + 123, 10, 2, 240, 127, 224, 60, 24, 234, 124, 98, 220, 12, 10, 2, 240, + 127, 224, 60, 24, 233, 192, 10, 2, 240, 127, 224, 60, 24, 233, 173, 10, + 2, 240, 127, 224, 60, 24, 233, 65, 10, 2, 240, 127, 224, 60, 24, 142, 10, + 2, 240, 127, 224, 60, 24, 226, 1, 10, 2, 240, 127, 224, 60, 24, 226, 2, + 98, 221, 191, 10, 2, 240, 127, 224, 60, 24, 225, 25, 10, 2, 240, 127, + 224, 60, 24, 172, 10, 2, 240, 127, 224, 60, 24, 221, 191, 10, 2, 240, + 127, 224, 60, 24, 221, 192, 98, 220, 11, 10, 2, 240, 127, 224, 60, 24, + 221, 174, 10, 2, 240, 127, 224, 60, 24, 217, 118, 10, 2, 240, 127, 224, + 60, 24, 213, 164, 98, 213, 163, 10, 2, 240, 127, 224, 60, 24, 206, 112, + 10, 2, 240, 127, 224, 60, 24, 203, 129, 10, 2, 240, 127, 224, 60, 24, + 200, 116, 98, 233, 173, 10, 2, 240, 127, 224, 60, 24, 199, 253, 10, 2, + 240, 98, 10, 2, 240, 75, 10, 2, 240, 74, 10, 2, 240, 73, 10, 2, 239, 152, + 10, 2, 239, 134, 10, 2, 239, 107, 10, 2, 239, 108, 24, 206, 255, 10, 2, + 239, 105, 10, 2, 239, 95, 10, 2, 239, 96, 224, 241, 118, 233, 53, 239, + 75, 10, 2, 239, 75, 10, 2, 237, 201, 10, 2, 237, 202, 127, 237, 201, 10, + 2, 237, 202, 233, 52, 10, 2, 237, 202, 206, 236, 10, 2, 237, 199, 10, 2, + 237, 200, 24, 236, 138, 10, 2, 237, 198, 10, 2, 237, 195, 10, 2, 237, + 194, 10, 2, 237, 193, 10, 2, 237, 188, 10, 2, 237, 186, 10, 2, 237, 187, + 233, 52, 10, 2, 237, 187, 233, 53, 233, 52, 10, 2, 237, 185, 10, 2, 237, + 178, 10, 2, 69, 10, 2, 237, 136, 24, 213, 163, 10, 2, 237, 136, 127, 237, + 136, 215, 139, 127, 215, 138, 10, 2, 237, 83, 10, 2, 237, 84, 24, 39, 98, + 233, 4, 98, 240, 136, 10, 2, 237, 84, 24, 234, 83, 10, 2, 237, 84, 24, + 219, 78, 10, 2, 237, 84, 24, 208, 241, 10, 2, 237, 84, 24, 206, 255, 10, + 2, 237, 84, 24, 66, 10, 2, 237, 56, 10, 2, 237, 44, 10, 2, 237, 7, 10, 2, + 236, 230, 10, 2, 236, 231, 24, 234, 91, 10, 2, 236, 231, 24, 234, 92, + 203, 12, 10, 2, 236, 231, 24, 219, 207, 10, 2, 236, 231, 241, 55, 236, + 230, 10, 2, 236, 231, 214, 79, 236, 230, 10, 2, 236, 231, 205, 93, 10, 2, + 236, 160, 10, 2, 236, 157, 10, 2, 236, 138, 10, 2, 236, 54, 10, 2, 236, + 55, 24, 63, 10, 2, 236, 55, 24, 39, 98, 222, 251, 10, 2, 236, 55, 24, 39, + 98, 222, 252, 24, 222, 251, 10, 2, 236, 55, 24, 251, 106, 10, 2, 236, 55, + 24, 249, 127, 10, 2, 236, 55, 24, 237, 187, 233, 52, 10, 2, 236, 55, 24, + 237, 187, 233, 53, 233, 52, 10, 2, 236, 55, 24, 142, 10, 2, 236, 55, 24, + 233, 4, 233, 52, 10, 2, 236, 55, 24, 226, 123, 233, 52, 10, 2, 236, 55, + 24, 224, 240, 10, 2, 236, 55, 24, 224, 241, 205, 93, 10, 2, 236, 55, 24, + 223, 178, 10, 2, 236, 55, 24, 172, 10, 2, 236, 55, 24, 222, 252, 24, 222, + 251, 10, 2, 236, 55, 24, 222, 109, 10, 2, 236, 55, 24, 221, 191, 10, 2, + 236, 55, 24, 200, 115, 10, 2, 236, 55, 24, 200, 104, 10, 2, 234, 123, 10, + 2, 234, 124, 233, 52, 10, 2, 234, 121, 10, 2, 234, 122, 24, 39, 98, 240, + 137, 98, 142, 10, 2, 234, 122, 24, 39, 98, 142, 10, 2, 234, 122, 24, 39, + 98, 226, 122, 10, 2, 234, 122, 24, 252, 35, 203, 13, 98, 203, 154, 10, 2, + 234, 122, 24, 251, 106, 10, 2, 234, 122, 24, 250, 195, 10, 2, 234, 122, + 24, 250, 194, 98, 234, 105, 10, 2, 234, 122, 24, 249, 127, 10, 2, 234, + 122, 24, 249, 80, 98, 169, 10, 2, 234, 122, 24, 247, 244, 10, 2, 234, + 122, 24, 247, 245, 98, 169, 10, 2, 234, 122, 24, 240, 136, 10, 2, 234, + 122, 24, 239, 152, 10, 2, 234, 122, 24, 239, 108, 24, 206, 255, 10, 2, + 234, 122, 24, 237, 199, 10, 2, 234, 122, 24, 237, 7, 10, 2, 234, 122, 24, + 237, 8, 98, 172, 10, 2, 234, 122, 24, 236, 230, 10, 2, 234, 122, 24, 236, + 231, 24, 234, 92, 203, 12, 10, 2, 234, 122, 24, 234, 92, 203, 12, 10, 2, + 234, 122, 24, 234, 83, 10, 2, 234, 122, 24, 233, 192, 10, 2, 234, 122, + 24, 233, 190, 10, 2, 234, 122, 24, 233, 191, 98, 63, 10, 2, 234, 122, 24, + 233, 174, 98, 204, 172, 10, 2, 234, 122, 24, 233, 4, 98, 221, 192, 98, + 236, 138, 10, 2, 234, 122, 24, 232, 228, 10, 2, 234, 122, 24, 232, 229, + 98, 172, 10, 2, 234, 122, 24, 232, 72, 98, 222, 109, 10, 2, 234, 122, 24, + 231, 67, 10, 2, 234, 122, 24, 226, 123, 233, 52, 10, 2, 234, 122, 24, + 225, 243, 98, 231, 76, 98, 250, 195, 10, 2, 234, 122, 24, 225, 25, 10, 2, + 234, 122, 24, 224, 240, 10, 2, 234, 122, 24, 224, 87, 10, 2, 234, 122, + 24, 224, 88, 98, 222, 251, 10, 2, 234, 122, 24, 223, 179, 98, 251, 106, + 10, 2, 234, 122, 24, 172, 10, 2, 234, 122, 24, 219, 208, 98, 236, 230, + 10, 2, 234, 122, 24, 219, 78, 10, 2, 234, 122, 24, 215, 138, 10, 2, 234, + 122, 24, 215, 139, 127, 215, 138, 10, 2, 234, 122, 24, 161, 10, 2, 234, + 122, 24, 208, 241, 10, 2, 234, 122, 24, 208, 204, 10, 2, 234, 122, 24, + 206, 255, 10, 2, 234, 122, 24, 207, 0, 98, 201, 10, 10, 2, 234, 122, 24, + 206, 221, 10, 2, 234, 122, 24, 204, 117, 10, 2, 234, 122, 24, 203, 129, + 10, 2, 234, 122, 24, 66, 10, 2, 234, 122, 24, 200, 104, 10, 2, 234, 122, + 24, 200, 105, 98, 237, 201, 10, 2, 234, 122, 127, 234, 121, 10, 2, 234, + 116, 10, 2, 234, 117, 241, 55, 234, 116, 10, 2, 234, 114, 10, 2, 234, + 115, 127, 234, 115, 234, 84, 127, 234, 83, 10, 2, 234, 105, 10, 2, 234, + 106, 234, 115, 127, 234, 115, 234, 84, 127, 234, 83, 10, 2, 234, 104, 10, + 2, 234, 102, 10, 2, 234, 93, 10, 2, 234, 91, 10, 2, 234, 92, 203, 12, 10, + 2, 234, 92, 127, 234, 91, 10, 2, 234, 92, 241, 55, 234, 91, 10, 2, 234, + 83, 10, 2, 234, 82, 10, 2, 234, 76, 10, 2, 234, 17, 10, 2, 234, 18, 24, + 223, 154, 10, 2, 233, 192, 10, 2, 233, 193, 24, 69, 10, 2, 233, 193, 24, + 66, 10, 2, 233, 193, 241, 55, 233, 192, 10, 2, 233, 190, 10, 2, 233, 191, + 127, 233, 190, 10, 2, 233, 191, 241, 55, 233, 190, 10, 2, 233, 187, 10, + 2, 233, 173, 10, 2, 233, 174, 233, 52, 10, 2, 233, 171, 10, 2, 233, 172, + 24, 39, 98, 226, 122, 10, 2, 233, 172, 24, 234, 92, 203, 12, 10, 2, 233, + 172, 24, 226, 122, 10, 2, 233, 172, 24, 221, 192, 98, 226, 122, 10, 2, + 233, 172, 24, 161, 10, 2, 233, 166, 10, 2, 233, 164, 10, 2, 233, 165, + 241, 55, 233, 164, 10, 2, 233, 165, 24, 249, 127, 10, 2, 233, 165, 24, + 203, 129, 10, 2, 233, 165, 203, 12, 10, 2, 233, 76, 10, 2, 233, 77, 241, + 55, 233, 76, 10, 2, 233, 74, 10, 2, 233, 75, 24, 225, 25, 10, 2, 233, 75, + 24, 225, 26, 24, 226, 123, 233, 52, 10, 2, 233, 75, 24, 215, 138, 10, 2, + 233, 75, 24, 208, 242, 98, 201, 28, 10, 2, 233, 75, 233, 52, 10, 2, 233, + 65, 10, 2, 233, 66, 24, 39, 98, 223, 154, 10, 2, 233, 66, 24, 223, 154, + 10, 2, 233, 66, 127, 233, 66, 221, 182, 10, 2, 233, 57, 10, 2, 233, 55, + 10, 2, 233, 56, 24, 206, 255, 10, 2, 233, 46, 10, 2, 233, 45, 10, 2, 233, + 41, 10, 2, 233, 40, 10, 2, 142, 10, 2, 233, 4, 203, 12, 10, 2, 233, 4, + 233, 52, 10, 2, 232, 228, 10, 2, 232, 71, 10, 2, 232, 72, 24, 250, 195, + 10, 2, 232, 72, 24, 250, 193, 10, 2, 232, 72, 24, 249, 127, 10, 2, 232, + 72, 24, 239, 75, 10, 2, 232, 72, 24, 234, 114, 10, 2, 232, 72, 24, 224, + 76, 10, 2, 232, 72, 24, 215, 138, 10, 2, 232, 72, 24, 206, 255, 10, 2, + 232, 72, 24, 66, 10, 2, 231, 75, 10, 2, 231, 67, 10, 2, 231, 68, 24, 251, + 106, 10, 2, 231, 68, 24, 232, 228, 10, 2, 231, 68, 24, 224, 240, 10, 2, + 231, 68, 24, 222, 53, 10, 2, 231, 68, 24, 200, 104, 10, 2, 231, 63, 10, + 2, 68, 10, 2, 230, 249, 63, 10, 2, 230, 205, 10, 2, 226, 150, 10, 2, 226, + 151, 127, 226, 151, 247, 244, 10, 2, 226, 151, 127, 226, 151, 205, 93, + 10, 2, 226, 125, 10, 2, 226, 122, 10, 2, 226, 123, 239, 134, 10, 2, 226, + 123, 210, 72, 10, 2, 226, 123, 127, 226, 123, 206, 205, 127, 206, 205, + 200, 105, 127, 200, 104, 10, 2, 226, 123, 233, 52, 10, 2, 226, 114, 10, + 2, 226, 115, 24, 234, 92, 203, 12, 10, 2, 226, 113, 10, 2, 226, 103, 10, + 2, 226, 104, 24, 203, 129, 10, 2, 226, 104, 241, 55, 226, 103, 10, 2, + 226, 104, 214, 79, 226, 103, 10, 2, 226, 104, 205, 93, 10, 2, 226, 96, + 10, 2, 226, 86, 10, 2, 226, 1, 10, 2, 225, 242, 10, 2, 155, 10, 2, 225, + 70, 24, 63, 10, 2, 225, 70, 24, 252, 6, 10, 2, 225, 70, 24, 252, 7, 98, + 223, 178, 10, 2, 225, 70, 24, 250, 193, 10, 2, 225, 70, 24, 249, 127, 10, + 2, 225, 70, 24, 249, 106, 10, 2, 225, 70, 24, 154, 10, 2, 225, 70, 24, + 248, 184, 10, 2, 225, 70, 24, 236, 157, 10, 2, 225, 70, 24, 236, 138, 10, + 2, 225, 70, 24, 234, 123, 10, 2, 225, 70, 24, 234, 105, 10, 2, 225, 70, + 24, 234, 92, 203, 12, 10, 2, 225, 70, 24, 234, 83, 10, 2, 225, 70, 24, + 234, 84, 98, 207, 49, 98, 63, 10, 2, 225, 70, 24, 233, 192, 10, 2, 225, + 70, 24, 233, 173, 10, 2, 225, 70, 24, 233, 165, 98, 208, 204, 10, 2, 225, + 70, 24, 233, 165, 241, 55, 233, 164, 10, 2, 225, 70, 24, 233, 76, 10, 2, + 225, 70, 24, 233, 45, 10, 2, 225, 70, 24, 226, 122, 10, 2, 225, 70, 24, + 226, 103, 10, 2, 225, 70, 24, 225, 25, 10, 2, 225, 70, 24, 224, 101, 10, + 2, 225, 70, 24, 224, 87, 10, 2, 225, 70, 24, 222, 109, 10, 2, 225, 70, + 24, 221, 191, 10, 2, 225, 70, 24, 219, 207, 10, 2, 225, 70, 24, 219, 208, + 98, 237, 201, 10, 2, 225, 70, 24, 219, 208, 98, 233, 192, 10, 2, 225, 70, + 24, 219, 208, 98, 203, 68, 10, 2, 225, 70, 24, 219, 78, 10, 2, 225, 70, + 24, 219, 79, 98, 215, 133, 10, 2, 225, 70, 24, 217, 118, 10, 2, 225, 70, + 24, 215, 138, 10, 2, 225, 70, 24, 212, 220, 10, 2, 225, 70, 24, 209, 140, + 10, 2, 225, 70, 24, 183, 10, 2, 225, 70, 24, 208, 204, 10, 2, 225, 70, + 24, 207, 50, 10, 2, 225, 70, 24, 206, 255, 10, 2, 225, 70, 24, 206, 221, + 10, 2, 225, 70, 24, 206, 151, 10, 2, 225, 70, 24, 206, 91, 10, 2, 225, + 70, 24, 204, 126, 10, 2, 225, 70, 24, 203, 101, 10, 2, 225, 70, 24, 66, + 10, 2, 225, 70, 24, 200, 115, 10, 2, 225, 70, 24, 200, 104, 10, 2, 225, + 70, 24, 200, 75, 24, 161, 10, 2, 225, 70, 24, 199, 253, 10, 2, 225, 70, + 24, 195, 33, 10, 2, 225, 56, 10, 2, 225, 57, 241, 55, 225, 56, 10, 2, + 225, 45, 10, 2, 225, 42, 10, 2, 225, 40, 10, 2, 225, 39, 10, 2, 225, 37, + 10, 2, 225, 38, 127, 225, 37, 10, 2, 225, 25, 10, 2, 225, 26, 24, 226, + 123, 233, 52, 10, 2, 225, 21, 10, 2, 225, 22, 24, 249, 127, 10, 2, 225, + 22, 241, 55, 225, 21, 10, 2, 225, 19, 10, 2, 225, 18, 10, 2, 224, 240, + 10, 2, 224, 241, 223, 63, 24, 118, 127, 223, 63, 24, 66, 10, 2, 224, 241, + 127, 224, 241, 223, 63, 24, 118, 127, 223, 63, 24, 66, 10, 2, 224, 173, + 10, 2, 224, 101, 10, 2, 224, 102, 24, 249, 127, 10, 2, 224, 102, 24, 66, + 10, 2, 224, 102, 24, 200, 104, 10, 2, 224, 87, 10, 2, 224, 76, 10, 2, + 224, 62, 10, 2, 224, 61, 10, 2, 224, 59, 10, 2, 224, 60, 127, 224, 59, + 10, 2, 223, 187, 10, 2, 223, 188, 127, 232, 72, 24, 250, 194, 223, 188, + 127, 232, 72, 24, 250, 193, 10, 2, 223, 178, 10, 2, 223, 176, 10, 2, 223, + 177, 199, 132, 20, 10, 2, 223, 175, 10, 2, 223, 167, 10, 2, 223, 168, + 233, 52, 10, 2, 223, 166, 10, 2, 223, 154, 10, 2, 223, 155, 214, 79, 223, + 154, 10, 2, 223, 147, 10, 2, 223, 124, 10, 2, 172, 10, 2, 223, 62, 10, 2, + 223, 63, 24, 63, 10, 2, 223, 63, 24, 39, 98, 240, 137, 98, 142, 10, 2, + 223, 63, 24, 39, 98, 234, 83, 10, 2, 223, 63, 24, 39, 98, 222, 251, 10, + 2, 223, 63, 24, 251, 173, 10, 2, 223, 63, 24, 251, 106, 10, 2, 223, 63, + 24, 250, 196, 195, 29, 203, 12, 10, 2, 223, 63, 24, 249, 127, 10, 2, 223, + 63, 24, 248, 184, 10, 2, 223, 63, 24, 240, 75, 10, 2, 223, 63, 24, 236, + 230, 10, 2, 223, 63, 24, 234, 123, 10, 2, 223, 63, 24, 234, 83, 10, 2, + 223, 63, 24, 233, 65, 10, 2, 223, 63, 24, 233, 66, 98, 233, 65, 10, 2, + 223, 63, 24, 142, 10, 2, 223, 63, 24, 232, 228, 10, 2, 223, 63, 24, 232, + 72, 24, 215, 138, 10, 2, 223, 63, 24, 226, 123, 233, 52, 10, 2, 223, 63, + 24, 226, 103, 10, 2, 223, 63, 24, 226, 104, 98, 142, 10, 2, 223, 63, 24, + 226, 104, 98, 221, 191, 10, 2, 223, 63, 24, 224, 101, 10, 2, 223, 63, 24, + 224, 76, 10, 2, 223, 63, 24, 223, 178, 10, 2, 223, 63, 24, 223, 167, 10, + 2, 223, 63, 24, 223, 168, 98, 232, 72, 98, 63, 10, 2, 223, 63, 24, 223, + 62, 10, 2, 223, 63, 24, 222, 53, 10, 2, 223, 63, 24, 221, 191, 10, 2, + 223, 63, 24, 221, 176, 10, 2, 223, 63, 24, 219, 207, 10, 2, 223, 63, 24, + 219, 208, 98, 236, 230, 10, 2, 223, 63, 24, 218, 93, 10, 2, 223, 63, 24, + 217, 118, 10, 2, 223, 63, 24, 207, 0, 98, 204, 117, 10, 2, 223, 63, 24, + 206, 201, 98, 233, 165, 98, 236, 157, 10, 2, 223, 63, 24, 206, 201, 98, + 233, 165, 203, 12, 10, 2, 223, 63, 24, 206, 149, 10, 2, 223, 63, 24, 206, + 150, 98, 206, 149, 10, 2, 223, 63, 24, 204, 117, 10, 2, 223, 63, 24, 203, + 143, 10, 2, 223, 63, 24, 203, 129, 10, 2, 223, 63, 24, 203, 69, 98, 39, + 98, 204, 173, 98, 176, 10, 2, 223, 63, 24, 66, 10, 2, 223, 63, 24, 118, + 98, 63, 10, 2, 223, 63, 24, 118, 98, 118, 98, 66, 10, 2, 223, 63, 24, + 200, 116, 98, 250, 195, 10, 2, 223, 63, 24, 200, 104, 10, 2, 223, 63, 24, + 199, 253, 10, 2, 223, 63, 205, 93, 10, 2, 223, 60, 10, 2, 223, 61, 24, + 206, 255, 10, 2, 223, 61, 24, 207, 0, 98, 204, 117, 10, 2, 223, 61, 233, + 52, 10, 2, 223, 61, 233, 53, 127, 223, 61, 233, 53, 206, 255, 10, 2, 223, + 56, 10, 2, 222, 251, 10, 2, 222, 252, 24, 222, 251, 10, 2, 222, 249, 10, + 2, 222, 250, 24, 223, 154, 10, 2, 222, 250, 24, 223, 155, 98, 209, 140, + 10, 2, 222, 109, 10, 2, 222, 90, 10, 2, 222, 78, 10, 2, 222, 53, 10, 2, + 221, 191, 10, 2, 221, 192, 24, 249, 127, 10, 2, 221, 189, 10, 2, 221, + 190, 24, 251, 173, 10, 2, 221, 190, 24, 249, 127, 10, 2, 221, 190, 24, + 236, 138, 10, 2, 221, 190, 24, 236, 139, 203, 12, 10, 2, 221, 190, 24, + 234, 92, 203, 12, 10, 2, 221, 190, 24, 232, 72, 24, 249, 127, 10, 2, 221, + 190, 24, 226, 103, 10, 2, 221, 190, 24, 225, 42, 10, 2, 221, 190, 24, + 225, 40, 10, 2, 221, 190, 24, 225, 41, 98, 250, 195, 10, 2, 221, 190, 24, + 224, 101, 10, 2, 221, 190, 24, 223, 83, 98, 250, 195, 10, 2, 221, 190, + 24, 223, 62, 10, 2, 221, 190, 24, 219, 208, 98, 236, 230, 10, 2, 221, + 190, 24, 217, 118, 10, 2, 221, 190, 24, 215, 186, 10, 2, 221, 190, 24, + 206, 113, 98, 250, 195, 10, 2, 221, 190, 24, 206, 83, 98, 248, 21, 10, 2, + 221, 190, 24, 201, 28, 10, 2, 221, 190, 203, 12, 10, 2, 221, 190, 241, + 55, 221, 189, 10, 2, 221, 190, 214, 79, 221, 189, 10, 2, 221, 190, 205, + 93, 10, 2, 221, 190, 206, 236, 10, 2, 221, 188, 10, 2, 221, 182, 10, 2, + 221, 183, 127, 221, 182, 10, 2, 221, 183, 214, 79, 221, 182, 10, 2, 221, + 183, 206, 236, 10, 2, 221, 179, 10, 2, 221, 176, 10, 2, 221, 174, 10, 2, + 221, 175, 127, 221, 174, 10, 2, 221, 175, 127, 221, 175, 234, 84, 127, + 234, 83, 10, 2, 166, 10, 2, 220, 128, 24, 203, 129, 10, 2, 220, 128, 233, + 52, 10, 2, 220, 120, 10, 2, 220, 89, 10, 2, 220, 37, 10, 2, 220, 12, 10, + 2, 220, 11, 10, 2, 219, 207, 10, 2, 219, 151, 10, 2, 219, 78, 10, 2, 219, + 23, 10, 2, 218, 145, 10, 2, 218, 146, 127, 218, 145, 10, 2, 218, 130, 10, + 2, 218, 131, 233, 52, 10, 2, 218, 111, 10, 2, 218, 97, 10, 2, 218, 93, + 10, 2, 218, 94, 24, 63, 10, 2, 218, 94, 24, 223, 154, 10, 2, 218, 94, 24, + 195, 115, 10, 2, 218, 94, 127, 218, 93, 10, 2, 218, 94, 127, 218, 94, 24, + 39, 98, 176, 10, 2, 218, 94, 241, 55, 218, 93, 10, 2, 218, 91, 10, 2, + 218, 92, 24, 63, 10, 2, 218, 92, 24, 39, 98, 239, 152, 10, 2, 218, 92, + 24, 239, 152, 10, 2, 218, 92, 233, 52, 10, 2, 176, 10, 2, 217, 247, 10, + 2, 217, 234, 10, 2, 217, 235, 226, 16, 10, 2, 217, 235, 24, 206, 152, + 203, 12, 10, 2, 217, 235, 214, 79, 217, 234, 10, 2, 217, 233, 10, 2, 217, + 226, 215, 124, 10, 2, 217, 225, 10, 2, 217, 224, 10, 2, 217, 118, 10, 2, + 217, 119, 24, 63, 10, 2, 217, 119, 24, 200, 104, 10, 2, 217, 119, 206, + 236, 10, 2, 216, 223, 10, 2, 216, 224, 24, 69, 10, 2, 216, 214, 10, 2, + 216, 184, 10, 2, 216, 185, 24, 234, 92, 203, 12, 10, 2, 216, 185, 24, + 234, 84, 98, 234, 92, 203, 12, 10, 2, 216, 180, 10, 2, 216, 181, 24, 251, + 106, 10, 2, 216, 181, 24, 250, 195, 10, 2, 216, 181, 24, 250, 196, 98, + 250, 195, 10, 2, 216, 181, 24, 233, 65, 10, 2, 216, 181, 24, 219, 208, + 98, 234, 92, 203, 12, 10, 2, 216, 181, 24, 217, 118, 10, 2, 216, 181, 24, + 215, 138, 10, 2, 216, 181, 24, 206, 255, 10, 2, 216, 181, 24, 207, 0, 98, + 39, 251, 106, 10, 2, 216, 181, 24, 207, 0, 98, 250, 195, 10, 2, 216, 181, + 24, 207, 0, 98, 250, 196, 98, 250, 195, 10, 2, 216, 181, 24, 200, 116, + 98, 250, 195, 10, 2, 216, 181, 24, 199, 253, 10, 2, 216, 169, 10, 2, 215, + 186, 10, 2, 215, 155, 10, 2, 215, 138, 10, 2, 215, 139, 223, 61, 24, 234, + 83, 10, 2, 215, 139, 223, 61, 24, 220, 12, 10, 2, 215, 139, 223, 61, 24, + 208, 241, 10, 2, 215, 139, 223, 61, 24, 208, 242, 127, 215, 139, 223, 61, + 24, 208, 241, 10, 2, 215, 139, 223, 61, 24, 199, 253, 10, 2, 215, 139, + 203, 12, 10, 2, 215, 139, 127, 215, 138, 10, 2, 215, 139, 241, 55, 215, + 138, 10, 2, 215, 139, 241, 55, 215, 139, 223, 61, 127, 223, 60, 10, 2, + 215, 133, 10, 2, 215, 134, 252, 35, 24, 250, 189, 10, 2, 215, 134, 252, + 35, 24, 248, 184, 10, 2, 215, 134, 252, 35, 24, 237, 195, 10, 2, 215, + 134, 252, 35, 24, 233, 65, 10, 2, 215, 134, 252, 35, 24, 226, 123, 233, + 52, 10, 2, 215, 134, 252, 35, 24, 225, 40, 10, 2, 215, 134, 252, 35, 24, + 172, 10, 2, 215, 134, 252, 35, 24, 217, 118, 10, 2, 215, 134, 252, 35, + 24, 206, 80, 10, 2, 215, 134, 252, 35, 24, 200, 115, 10, 2, 215, 134, + 224, 60, 24, 248, 184, 10, 2, 215, 134, 224, 60, 24, 248, 185, 66, 10, 2, + 161, 10, 2, 213, 233, 10, 2, 213, 191, 10, 2, 213, 163, 10, 2, 213, 21, + 10, 2, 212, 220, 10, 2, 212, 221, 24, 63, 10, 2, 212, 221, 24, 252, 117, + 10, 2, 212, 221, 24, 248, 184, 10, 2, 212, 221, 24, 248, 21, 10, 2, 212, + 221, 24, 69, 10, 2, 212, 221, 24, 68, 10, 2, 212, 221, 24, 230, 205, 10, + 2, 212, 221, 24, 66, 10, 2, 212, 221, 24, 200, 115, 10, 2, 212, 221, 241, + 55, 212, 220, 10, 2, 212, 161, 10, 2, 212, 162, 24, 225, 21, 10, 2, 212, + 162, 24, 200, 104, 10, 2, 212, 162, 24, 195, 115, 10, 2, 212, 162, 214, + 79, 212, 161, 10, 2, 169, 10, 2, 210, 242, 10, 2, 210, 72, 10, 2, 209, + 140, 10, 2, 183, 10, 2, 209, 2, 215, 124, 10, 2, 209, 1, 10, 2, 209, 2, + 24, 63, 10, 2, 209, 2, 24, 237, 201, 10, 2, 209, 2, 24, 237, 199, 10, 2, + 209, 2, 24, 142, 10, 2, 209, 2, 24, 225, 25, 10, 2, 209, 2, 24, 223, 154, + 10, 2, 209, 2, 24, 221, 174, 10, 2, 209, 2, 24, 219, 78, 10, 2, 209, 2, + 24, 215, 138, 10, 2, 209, 2, 24, 208, 241, 10, 2, 209, 2, 24, 206, 221, + 10, 2, 209, 2, 24, 203, 154, 10, 2, 209, 2, 24, 200, 115, 10, 2, 209, 2, + 24, 200, 110, 10, 2, 209, 2, 24, 200, 79, 10, 2, 209, 2, 24, 200, 21, 10, + 2, 209, 2, 24, 199, 253, 10, 2, 209, 2, 127, 209, 1, 10, 2, 209, 2, 233, + 52, 10, 2, 208, 241, 10, 2, 208, 242, 223, 63, 24, 250, 193, 10, 2, 208, + 213, 10, 2, 208, 204, 10, 2, 207, 50, 10, 2, 207, 48, 10, 2, 207, 49, 24, + 63, 10, 2, 207, 49, 24, 249, 127, 10, 2, 207, 49, 24, 233, 164, 10, 2, + 207, 49, 24, 217, 118, 10, 2, 207, 49, 24, 206, 149, 10, 2, 207, 49, 24, + 201, 10, 10, 2, 207, 49, 24, 66, 10, 2, 207, 49, 24, 118, 98, 63, 10, 2, + 207, 46, 10, 2, 207, 44, 10, 2, 207, 17, 10, 2, 206, 255, 10, 2, 207, 0, + 231, 75, 10, 2, 207, 0, 127, 207, 0, 234, 115, 127, 234, 115, 234, 84, + 127, 234, 83, 10, 2, 207, 0, 127, 207, 0, 203, 155, 127, 203, 155, 234, + 84, 127, 234, 83, 10, 2, 206, 248, 10, 2, 206, 243, 10, 2, 206, 239, 10, + 2, 206, 238, 10, 2, 206, 235, 10, 2, 206, 221, 10, 2, 206, 222, 24, 63, + 10, 2, 206, 222, 24, 226, 103, 10, 2, 206, 215, 10, 2, 206, 216, 24, 63, + 10, 2, 206, 216, 24, 249, 107, 10, 2, 206, 216, 24, 247, 255, 10, 2, 206, + 216, 24, 239, 95, 10, 2, 206, 216, 24, 234, 83, 10, 2, 206, 216, 24, 226, + 122, 10, 2, 206, 216, 24, 226, 123, 233, 52, 10, 2, 206, 216, 24, 223, + 147, 10, 2, 206, 216, 24, 221, 176, 10, 2, 206, 216, 24, 218, 130, 10, 2, + 206, 216, 24, 208, 241, 10, 2, 206, 209, 10, 2, 206, 204, 10, 2, 206, + 205, 203, 12, 10, 2, 206, 205, 127, 206, 205, 247, 245, 127, 247, 244, + 10, 2, 206, 200, 10, 2, 206, 151, 10, 2, 206, 152, 127, 226, 17, 206, + 151, 10, 2, 206, 149, 10, 2, 206, 147, 10, 2, 206, 112, 10, 2, 206, 113, + 233, 52, 10, 2, 206, 91, 10, 2, 206, 89, 10, 2, 206, 90, 127, 206, 90, + 206, 149, 10, 2, 206, 82, 10, 2, 206, 80, 10, 2, 204, 172, 10, 2, 204, + 173, 127, 204, 172, 10, 2, 204, 129, 10, 2, 204, 128, 10, 2, 204, 126, + 10, 2, 204, 117, 10, 2, 204, 116, 10, 2, 204, 88, 10, 2, 204, 87, 10, 2, + 189, 10, 2, 203, 169, 250, 179, 10, 2, 203, 169, 24, 232, 71, 10, 2, 203, + 169, 24, 219, 78, 10, 2, 203, 169, 233, 52, 10, 2, 203, 154, 10, 2, 203, + 155, 127, 203, 155, 216, 224, 127, 216, 224, 239, 76, 127, 239, 75, 10, + 2, 203, 155, 205, 93, 10, 2, 203, 143, 10, 2, 184, 24, 248, 184, 10, 2, + 184, 24, 233, 65, 10, 2, 184, 24, 206, 255, 10, 2, 184, 24, 206, 151, 10, + 2, 184, 24, 201, 28, 10, 2, 184, 24, 200, 104, 10, 2, 203, 129, 10, 2, + 203, 101, 10, 2, 203, 68, 10, 2, 203, 69, 233, 52, 10, 2, 202, 122, 10, + 2, 202, 123, 203, 12, 10, 2, 202, 86, 10, 2, 202, 63, 10, 2, 202, 64, 24, + 203, 129, 10, 2, 202, 64, 127, 202, 63, 10, 2, 202, 64, 127, 202, 64, + 234, 115, 127, 234, 115, 234, 84, 127, 234, 83, 10, 2, 201, 40, 10, 2, + 201, 28, 10, 2, 201, 26, 10, 2, 201, 22, 10, 2, 201, 10, 10, 2, 201, 11, + 127, 201, 11, 195, 116, 127, 195, 115, 10, 2, 66, 10, 2, 118, 233, 65, + 10, 2, 118, 118, 66, 10, 2, 118, 127, 118, 213, 244, 127, 213, 244, 234, + 84, 127, 234, 83, 10, 2, 118, 127, 118, 204, 89, 127, 204, 88, 10, 2, + 118, 127, 118, 118, 210, 89, 127, 118, 210, 88, 10, 2, 200, 115, 10, 2, + 200, 110, 10, 2, 200, 104, 10, 2, 200, 105, 223, 147, 10, 2, 200, 105, + 24, 249, 127, 10, 2, 200, 105, 24, 219, 78, 10, 2, 200, 105, 24, 118, 98, + 118, 98, 66, 10, 2, 200, 105, 24, 118, 98, 118, 98, 118, 233, 52, 10, 2, + 200, 105, 233, 52, 10, 2, 200, 105, 206, 236, 10, 2, 200, 105, 206, 237, + 24, 249, 127, 10, 2, 200, 100, 10, 2, 200, 79, 10, 2, 200, 80, 24, 223, + 62, 10, 2, 200, 80, 24, 219, 208, 98, 240, 136, 10, 2, 200, 80, 24, 207, + 48, 10, 2, 200, 80, 24, 66, 10, 2, 200, 78, 10, 2, 200, 74, 10, 2, 200, + 75, 24, 224, 240, 10, 2, 200, 75, 24, 161, 10, 2, 200, 72, 10, 2, 200, + 73, 233, 52, 10, 2, 200, 21, 10, 2, 200, 22, 241, 55, 200, 21, 10, 2, + 200, 22, 206, 236, 10, 2, 200, 19, 10, 2, 200, 20, 24, 39, 98, 142, 10, + 2, 200, 20, 24, 39, 98, 176, 10, 2, 200, 20, 24, 251, 173, 10, 2, 200, + 20, 24, 142, 10, 2, 200, 20, 24, 215, 138, 10, 2, 200, 20, 24, 200, 115, + 10, 2, 200, 20, 24, 200, 116, 98, 250, 195, 10, 2, 200, 20, 24, 200, 116, + 98, 248, 184, 10, 2, 200, 18, 10, 2, 200, 15, 10, 2, 200, 14, 10, 2, 200, + 10, 10, 2, 200, 11, 24, 63, 10, 2, 200, 11, 24, 250, 189, 10, 2, 200, 11, + 24, 154, 10, 2, 200, 11, 24, 237, 188, 10, 2, 200, 11, 24, 234, 123, 10, + 2, 200, 11, 24, 234, 105, 10, 2, 200, 11, 24, 234, 92, 203, 12, 10, 2, + 200, 11, 24, 234, 83, 10, 2, 200, 11, 24, 233, 76, 10, 2, 200, 11, 24, + 142, 10, 2, 200, 11, 24, 226, 122, 10, 2, 200, 11, 24, 226, 103, 10, 2, + 200, 11, 24, 225, 242, 10, 2, 200, 11, 24, 224, 101, 10, 2, 200, 11, 24, + 221, 174, 10, 2, 200, 11, 24, 219, 23, 10, 2, 200, 11, 24, 161, 10, 2, + 200, 11, 24, 206, 255, 10, 2, 200, 11, 24, 206, 89, 10, 2, 200, 11, 24, + 201, 40, 10, 2, 200, 11, 24, 118, 98, 233, 65, 10, 2, 200, 11, 24, 200, + 104, 10, 2, 200, 11, 24, 200, 8, 10, 2, 200, 8, 10, 2, 200, 9, 24, 66, + 10, 2, 199, 253, 10, 2, 199, 254, 24, 63, 10, 2, 199, 254, 24, 223, 187, + 10, 2, 199, 254, 24, 223, 154, 10, 2, 199, 254, 24, 203, 129, 10, 2, 199, + 249, 10, 2, 199, 252, 10, 2, 199, 250, 10, 2, 199, 246, 10, 2, 199, 234, + 10, 2, 199, 235, 24, 224, 240, 10, 2, 199, 232, 10, 2, 195, 115, 10, 2, + 195, 116, 203, 12, 10, 2, 195, 116, 103, 24, 223, 154, 10, 2, 195, 111, + 10, 2, 195, 103, 10, 2, 195, 87, 10, 2, 195, 33, 10, 2, 195, 34, 127, + 195, 33, 10, 2, 195, 32, 10, 2, 195, 30, 10, 2, 195, 31, 225, 44, 203, + 12, 10, 2, 195, 25, 10, 2, 195, 16, 10, 2, 194, 255, 10, 2, 194, 253, 10, + 2, 194, 254, 24, 63, 10, 2, 194, 252, 10, 2, 194, 251, 10, 2, 225, 9, + 237, 4, 10, 2, 252, 118, 24, 215, 138, 10, 2, 252, 35, 24, 63, 10, 2, + 251, 120, 24, 223, 169, 10, 2, 240, 127, 224, 60, 24, 200, 116, 98, 220, + 12, 10, 2, 240, 125, 10, 2, 239, 76, 98, 206, 151, 10, 2, 237, 200, 24, + 206, 255, 10, 2, 236, 55, 24, 233, 65, 10, 2, 236, 55, 24, 206, 255, 10, + 2, 234, 122, 24, 251, 107, 98, 225, 26, 98, 63, 10, 2, 234, 122, 24, 250, + 193, 10, 2, 234, 47, 10, 2, 233, 181, 10, 2, 231, 48, 10, 2, 225, 70, 24, + 251, 71, 10, 2, 225, 70, 24, 250, 192, 10, 2, 225, 70, 24, 233, 164, 10, + 2, 225, 70, 24, 233, 65, 10, 2, 225, 70, 24, 232, 72, 24, 250, 193, 10, + 2, 225, 70, 24, 221, 174, 10, 2, 225, 70, 24, 161, 10, 2, 225, 70, 24, + 206, 143, 10, 2, 225, 70, 24, 201, 40, 10, 2, 225, 70, 24, 200, 19, 10, + 2, 223, 63, 24, 233, 192, 10, 2, 221, 190, 206, 237, 24, 249, 127, 10, 2, + 221, 190, 24, 236, 139, 98, 222, 251, 10, 2, 221, 190, 24, 206, 151, 10, + 2, 219, 150, 10, 2, 218, 92, 24, 195, 115, 10, 2, 217, 246, 10, 2, 216, + 183, 10, 2, 216, 182, 10, 2, 216, 181, 24, 249, 107, 10, 2, 216, 181, 24, + 233, 192, 10, 2, 215, 156, 209, 194, 216, 175, 239, 230, 10, 2, 213, 22, + 250, 179, 10, 2, 212, 165, 10, 2, 209, 2, 24, 226, 123, 233, 52, 10, 2, + 202, 114, 10, 2, 200, 80, 24, 219, 207, 10, 2, 118, 66, 10, 156, 2, 99, + 250, 195, 10, 156, 2, 115, 250, 195, 10, 156, 2, 235, 7, 250, 195, 10, + 156, 2, 235, 101, 250, 195, 10, 156, 2, 206, 29, 250, 195, 10, 156, 2, + 207, 71, 250, 195, 10, 156, 2, 237, 31, 250, 195, 10, 156, 2, 216, 179, + 250, 195, 10, 156, 2, 115, 239, 75, 10, 156, 2, 235, 7, 239, 75, 10, 156, + 2, 235, 101, 239, 75, 10, 156, 2, 206, 29, 239, 75, 10, 156, 2, 207, 71, + 239, 75, 10, 156, 2, 237, 31, 239, 75, 10, 156, 2, 216, 179, 239, 75, 10, + 156, 2, 235, 7, 66, 10, 156, 2, 235, 101, 66, 10, 156, 2, 206, 29, 66, + 10, 156, 2, 207, 71, 66, 10, 156, 2, 237, 31, 66, 10, 156, 2, 216, 179, + 66, 10, 156, 2, 97, 234, 19, 10, 156, 2, 99, 234, 19, 10, 156, 2, 115, + 234, 19, 10, 156, 2, 235, 7, 234, 19, 10, 156, 2, 235, 101, 234, 19, 10, + 156, 2, 206, 29, 234, 19, 10, 156, 2, 207, 71, 234, 19, 10, 156, 2, 237, + 31, 234, 19, 10, 156, 2, 216, 179, 234, 19, 10, 156, 2, 97, 234, 16, 10, + 156, 2, 99, 234, 16, 10, 156, 2, 115, 234, 16, 10, 156, 2, 235, 7, 234, + 16, 10, 156, 2, 235, 101, 234, 16, 10, 156, 2, 99, 207, 17, 10, 156, 2, + 115, 207, 17, 10, 156, 2, 115, 207, 18, 199, 132, 20, 10, 156, 2, 235, 7, + 207, 17, 10, 156, 2, 235, 101, 207, 17, 10, 156, 2, 206, 29, 207, 17, 10, + 156, 2, 207, 71, 207, 17, 10, 156, 2, 237, 31, 207, 17, 10, 156, 2, 216, + 179, 207, 17, 10, 156, 2, 97, 207, 10, 10, 156, 2, 99, 207, 10, 10, 156, + 2, 115, 207, 10, 10, 156, 2, 115, 207, 11, 199, 132, 20, 10, 156, 2, 235, + 7, 207, 10, 10, 156, 2, 235, 101, 207, 10, 10, 156, 2, 207, 18, 24, 234, + 106, 98, 239, 75, 10, 156, 2, 207, 18, 24, 234, 106, 98, 219, 23, 10, + 156, 2, 97, 247, 240, 10, 156, 2, 99, 247, 240, 10, 156, 2, 115, 247, + 240, 10, 156, 2, 115, 247, 241, 199, 132, 20, 10, 156, 2, 235, 7, 247, + 240, 10, 156, 2, 235, 101, 247, 240, 10, 156, 2, 115, 199, 132, 235, 24, + 236, 140, 10, 156, 2, 115, 199, 132, 235, 24, 236, 137, 10, 156, 2, 235, + 7, 199, 132, 235, 24, 222, 79, 10, 156, 2, 235, 7, 199, 132, 235, 24, + 222, 77, 10, 156, 2, 235, 7, 199, 132, 235, 24, 222, 80, 63, 10, 156, 2, + 235, 7, 199, 132, 235, 24, 222, 80, 250, 112, 10, 156, 2, 206, 29, 199, + 132, 235, 24, 250, 191, 10, 156, 2, 207, 71, 199, 132, 235, 24, 226, 95, + 10, 156, 2, 207, 71, 199, 132, 235, 24, 226, 97, 63, 10, 156, 2, 207, 71, + 199, 132, 235, 24, 226, 97, 250, 112, 10, 156, 2, 237, 31, 199, 132, 235, + 24, 199, 248, 10, 156, 2, 237, 31, 199, 132, 235, 24, 199, 247, 10, 156, + 2, 216, 179, 199, 132, 235, 24, 226, 111, 10, 156, 2, 216, 179, 199, 132, + 235, 24, 226, 110, 10, 156, 2, 216, 179, 199, 132, 235, 24, 226, 109, 10, + 156, 2, 216, 179, 199, 132, 235, 24, 226, 112, 63, 10, 156, 2, 99, 250, + 196, 203, 12, 10, 156, 2, 115, 250, 196, 203, 12, 10, 156, 2, 235, 7, + 250, 196, 203, 12, 10, 156, 2, 235, 101, 250, 196, 203, 12, 10, 156, 2, + 206, 29, 250, 196, 203, 12, 10, 156, 2, 97, 249, 91, 10, 156, 2, 99, 249, + 91, 10, 156, 2, 115, 249, 91, 10, 156, 2, 235, 7, 249, 91, 10, 156, 2, + 235, 7, 249, 92, 199, 132, 20, 10, 156, 2, 235, 101, 249, 91, 10, 156, 2, + 235, 101, 249, 92, 199, 132, 20, 10, 156, 2, 216, 192, 10, 156, 2, 216, + 193, 10, 156, 2, 97, 236, 136, 10, 156, 2, 99, 236, 136, 10, 156, 2, 97, + 202, 185, 239, 75, 10, 156, 2, 99, 202, 182, 239, 75, 10, 156, 2, 235, + 101, 206, 16, 239, 75, 10, 156, 2, 97, 202, 185, 199, 132, 235, 24, 63, + 10, 156, 2, 99, 202, 182, 199, 132, 235, 24, 63, 10, 156, 2, 97, 237, 27, + 250, 195, 10, 156, 2, 97, 211, 88, 250, 195, 10, 156, 2, 37, 250, 182, + 97, 206, 17, 10, 156, 2, 37, 250, 182, 97, 211, 87, 10, 156, 2, 97, 211, + 88, 233, 46, 10, 156, 2, 97, 157, 233, 46, 10, 156, 2, 237, 5, 97, 202, + 184, 10, 156, 2, 237, 5, 99, 202, 181, 10, 156, 2, 237, 5, 235, 14, 10, + 156, 2, 237, 5, 235, 145, 10, 156, 2, 235, 7, 118, 199, 132, 20, 10, 156, + 2, 235, 101, 118, 199, 132, 20, 10, 156, 2, 206, 29, 118, 199, 132, 20, + 10, 156, 2, 207, 71, 118, 199, 132, 20, 10, 156, 2, 237, 31, 118, 199, + 132, 20, 10, 156, 2, 216, 179, 118, 199, 132, 20, 10, 211, 214, 2, 37, + 250, 182, 197, 9, 239, 59, 10, 211, 214, 2, 83, 244, 168, 10, 211, 214, + 2, 239, 147, 244, 168, 10, 211, 214, 2, 239, 147, 201, 176, 10, 211, 214, + 2, 239, 147, 211, 93, 10, 2, 252, 118, 24, 215, 139, 203, 12, 10, 2, 252, + 118, 24, 206, 149, 10, 2, 252, 7, 24, 236, 138, 10, 2, 249, 128, 24, 239, + 76, 203, 12, 10, 2, 249, 114, 24, 252, 34, 10, 2, 249, 114, 24, 216, 223, + 10, 2, 249, 114, 24, 195, 115, 10, 2, 248, 22, 127, 248, 22, 24, 217, + 247, 10, 2, 240, 137, 24, 203, 129, 10, 2, 240, 127, 24, 223, 154, 10, 2, + 239, 108, 24, 226, 122, 10, 2, 239, 108, 24, 118, 118, 66, 10, 2, 239, + 106, 24, 200, 104, 10, 2, 237, 196, 24, 251, 71, 10, 2, 237, 196, 24, + 250, 195, 10, 2, 237, 196, 24, 250, 196, 250, 169, 222, 184, 10, 2, 237, + 196, 24, 239, 95, 10, 2, 237, 196, 24, 237, 188, 10, 2, 237, 196, 24, + 236, 157, 10, 2, 237, 196, 24, 234, 123, 10, 2, 237, 196, 24, 233, 192, + 10, 2, 237, 196, 24, 233, 174, 233, 52, 10, 2, 237, 196, 24, 233, 164, + 10, 2, 237, 196, 24, 142, 10, 2, 237, 196, 24, 232, 71, 10, 2, 237, 196, + 24, 226, 123, 233, 52, 10, 2, 237, 196, 24, 224, 240, 10, 2, 237, 196, + 24, 223, 154, 10, 2, 237, 196, 24, 223, 147, 10, 2, 237, 196, 24, 223, + 148, 98, 224, 240, 10, 2, 237, 196, 24, 223, 50, 10, 2, 237, 196, 24, + 222, 249, 10, 2, 237, 196, 24, 222, 250, 24, 223, 154, 10, 2, 237, 196, + 24, 221, 180, 98, 233, 164, 10, 2, 237, 196, 24, 220, 12, 10, 2, 237, + 196, 24, 219, 151, 10, 2, 237, 196, 24, 219, 78, 10, 2, 237, 196, 24, + 216, 223, 10, 2, 237, 196, 24, 212, 220, 10, 2, 237, 196, 24, 206, 255, + 10, 2, 237, 196, 24, 206, 113, 233, 52, 10, 2, 237, 84, 24, 223, 154, 10, + 2, 237, 84, 24, 213, 163, 10, 2, 236, 158, 196, 222, 10, 2, 236, 139, + 241, 55, 236, 138, 10, 2, 236, 55, 206, 237, 24, 250, 195, 10, 2, 236, + 55, 206, 237, 24, 232, 71, 10, 2, 236, 55, 206, 237, 24, 226, 123, 233, + 52, 10, 2, 236, 55, 206, 237, 24, 172, 10, 2, 236, 55, 206, 237, 24, 222, + 251, 10, 2, 236, 55, 206, 237, 24, 219, 207, 10, 2, 236, 55, 206, 237, + 24, 219, 151, 10, 2, 236, 55, 206, 237, 24, 204, 172, 10, 2, 236, 55, 24, + 204, 172, 10, 2, 234, 122, 24, 249, 113, 10, 2, 234, 122, 24, 239, 108, + 233, 52, 10, 2, 234, 122, 24, 237, 196, 24, 226, 123, 233, 52, 10, 2, + 234, 122, 24, 237, 196, 24, 224, 240, 10, 2, 234, 122, 24, 236, 160, 10, + 2, 234, 122, 24, 234, 123, 10, 2, 234, 122, 24, 234, 84, 98, 239, 152, + 10, 2, 234, 122, 24, 234, 84, 98, 217, 118, 10, 2, 234, 122, 24, 233, 4, + 98, 63, 10, 2, 234, 122, 24, 223, 148, 98, 224, 240, 10, 2, 234, 122, 24, + 222, 249, 10, 2, 234, 122, 24, 222, 250, 24, 223, 154, 10, 2, 234, 122, + 24, 221, 179, 10, 2, 234, 122, 24, 218, 93, 10, 2, 234, 122, 24, 217, + 118, 10, 2, 234, 122, 24, 217, 119, 98, 237, 83, 10, 2, 234, 122, 24, + 217, 119, 98, 233, 192, 10, 2, 234, 122, 24, 206, 215, 10, 2, 234, 122, + 24, 195, 16, 10, 2, 234, 117, 209, 194, 216, 175, 239, 230, 10, 2, 234, + 18, 24, 66, 10, 2, 233, 165, 24, 233, 165, 241, 55, 233, 164, 10, 2, 233, + 75, 24, 226, 123, 233, 52, 10, 2, 233, 66, 98, 233, 165, 24, 203, 129, + 10, 2, 233, 4, 203, 13, 233, 52, 10, 2, 232, 72, 24, 250, 196, 127, 232, + 72, 24, 250, 195, 10, 2, 225, 70, 24, 248, 21, 10, 2, 225, 70, 24, 155, + 10, 2, 225, 70, 24, 118, 118, 66, 10, 2, 225, 70, 24, 200, 21, 10, 2, + 223, 63, 24, 195, 0, 127, 194, 255, 10, 2, 223, 51, 10, 2, 223, 49, 10, + 2, 223, 48, 10, 2, 223, 47, 10, 2, 223, 46, 10, 2, 223, 45, 10, 2, 223, + 44, 10, 2, 223, 43, 127, 223, 43, 233, 52, 10, 2, 223, 42, 10, 2, 223, + 41, 127, 223, 40, 10, 2, 223, 39, 10, 2, 223, 38, 10, 2, 223, 37, 10, 2, + 223, 36, 10, 2, 223, 35, 10, 2, 223, 34, 10, 2, 223, 33, 10, 2, 223, 32, + 10, 2, 223, 31, 10, 2, 223, 30, 10, 2, 223, 29, 10, 2, 223, 28, 10, 2, + 223, 27, 10, 2, 223, 26, 10, 2, 223, 25, 10, 2, 223, 24, 10, 2, 223, 23, + 10, 2, 223, 22, 10, 2, 223, 20, 10, 2, 223, 21, 24, 233, 76, 10, 2, 223, + 21, 24, 226, 122, 10, 2, 223, 21, 24, 213, 164, 98, 221, 188, 10, 2, 223, + 21, 24, 213, 164, 98, 213, 164, 98, 221, 188, 10, 2, 223, 21, 24, 200, + 116, 98, 249, 145, 10, 2, 223, 19, 10, 2, 223, 18, 10, 2, 223, 17, 10, 2, + 223, 16, 10, 2, 223, 15, 10, 2, 223, 14, 10, 2, 223, 13, 10, 2, 223, 12, + 10, 2, 223, 11, 10, 2, 223, 10, 10, 2, 223, 8, 10, 2, 223, 9, 24, 250, + 195, 10, 2, 223, 9, 24, 249, 127, 10, 2, 223, 9, 24, 237, 187, 233, 53, + 233, 52, 10, 2, 223, 9, 24, 223, 178, 10, 2, 223, 9, 24, 172, 10, 2, 223, + 9, 24, 203, 101, 10, 2, 223, 9, 24, 203, 68, 10, 2, 223, 9, 24, 200, 115, + 10, 2, 223, 9, 24, 200, 104, 10, 2, 223, 9, 24, 200, 8, 10, 2, 223, 7, + 10, 2, 223, 5, 10, 2, 223, 6, 24, 237, 199, 10, 2, 223, 6, 24, 234, 123, + 10, 2, 223, 6, 24, 226, 122, 10, 2, 223, 6, 24, 226, 123, 233, 52, 10, 2, + 223, 6, 24, 216, 223, 10, 2, 223, 6, 24, 213, 164, 98, 213, 164, 98, 221, + 188, 10, 2, 223, 6, 24, 206, 240, 98, 224, 101, 10, 2, 223, 6, 24, 200, + 104, 10, 2, 223, 6, 24, 200, 8, 10, 2, 223, 3, 10, 2, 223, 2, 10, 2, 221, + 190, 233, 53, 24, 250, 195, 10, 2, 221, 190, 24, 239, 75, 10, 2, 221, + 190, 24, 232, 228, 10, 2, 221, 190, 24, 213, 163, 10, 2, 221, 190, 24, + 213, 164, 98, 213, 164, 98, 221, 188, 10, 2, 221, 190, 24, 203, 129, 10, + 2, 219, 79, 98, 195, 114, 10, 2, 218, 94, 127, 218, 94, 24, 234, 123, 10, + 2, 218, 94, 127, 218, 94, 24, 225, 25, 10, 2, 216, 181, 24, 239, 108, + 233, 52, 10, 2, 216, 181, 24, 233, 164, 10, 2, 216, 181, 24, 233, 57, 10, + 2, 216, 181, 24, 232, 71, 10, 2, 216, 181, 24, 224, 173, 10, 2, 216, 181, + 24, 223, 46, 10, 2, 216, 181, 24, 220, 12, 10, 2, 216, 181, 24, 213, 164, + 98, 213, 163, 10, 2, 216, 181, 24, 66, 10, 2, 216, 181, 24, 118, 98, 66, + 10, 2, 216, 181, 24, 200, 8, 10, 2, 209, 2, 233, 53, 24, 142, 10, 2, 209, + 2, 24, 236, 230, 10, 2, 209, 2, 24, 207, 0, 250, 169, 222, 184, 10, 2, + 209, 2, 24, 203, 129, 10, 2, 207, 47, 203, 12, 10, 2, 207, 0, 127, 206, + 255, 10, 2, 207, 0, 98, 231, 67, 10, 2, 207, 0, 98, 217, 224, 10, 2, 207, + 0, 98, 208, 204, 10, 2, 206, 150, 98, 237, 196, 24, 216, 223, 10, 2, 206, + 150, 98, 237, 84, 24, 251, 106, 10, 2, 206, 113, 24, 203, 129, 10, 2, + 203, 130, 98, 209, 1, 10, 2, 201, 23, 24, 234, 92, 203, 12, 10, 2, 201, + 23, 24, 115, 239, 75, 10, 2, 200, 20, 226, 16, 10, 2, 200, 20, 24, 200, + 104, 10, 2, 200, 11, 24, 240, 74, 10, 2, 200, 11, 24, 223, 4, 10, 2, 200, + 11, 24, 221, 188, 10, 2, 195, 114, 10, 2, 195, 0, 127, 195, 0, 98, 208, + 204, 10, 2, 194, 254, 24, 115, 239, 76, 203, 12, 14, 7, 255, 161, 14, 7, + 255, 160, 14, 7, 255, 159, 14, 7, 255, 158, 14, 7, 255, 157, 14, 7, 255, + 156, 14, 7, 255, 155, 14, 7, 255, 154, 14, 7, 255, 153, 14, 7, 255, 152, + 14, 7, 255, 151, 14, 7, 255, 150, 14, 7, 255, 149, 14, 7, 255, 147, 14, + 7, 255, 146, 14, 7, 255, 145, 14, 7, 255, 144, 14, 7, 255, 143, 14, 7, + 255, 142, 14, 7, 255, 141, 14, 7, 255, 140, 14, 7, 255, 139, 14, 7, 255, + 138, 14, 7, 255, 137, 14, 7, 255, 136, 14, 7, 255, 135, 14, 7, 255, 134, + 14, 7, 255, 133, 14, 7, 255, 132, 14, 7, 255, 131, 14, 7, 255, 130, 14, + 7, 255, 128, 14, 7, 255, 127, 14, 7, 255, 125, 14, 7, 255, 124, 14, 7, + 255, 123, 14, 7, 255, 122, 14, 7, 255, 121, 14, 7, 255, 120, 14, 7, 255, + 119, 14, 7, 255, 118, 14, 7, 255, 117, 14, 7, 255, 116, 14, 7, 255, 115, + 14, 7, 255, 114, 14, 7, 255, 112, 14, 7, 255, 111, 14, 7, 255, 110, 14, + 7, 255, 108, 14, 7, 255, 107, 14, 7, 255, 106, 14, 7, 255, 105, 14, 7, + 255, 104, 14, 7, 255, 103, 14, 7, 255, 102, 14, 7, 255, 101, 14, 7, 255, + 98, 14, 7, 255, 97, 14, 7, 255, 96, 14, 7, 255, 95, 14, 7, 255, 94, 14, + 7, 255, 93, 14, 7, 255, 92, 14, 7, 255, 91, 14, 7, 255, 90, 14, 7, 255, + 89, 14, 7, 255, 88, 14, 7, 255, 87, 14, 7, 255, 86, 14, 7, 255, 85, 14, + 7, 255, 84, 14, 7, 255, 83, 14, 7, 255, 82, 14, 7, 255, 81, 14, 7, 255, + 80, 14, 7, 255, 79, 14, 7, 255, 75, 14, 7, 255, 74, 14, 7, 255, 73, 14, + 7, 255, 72, 14, 7, 250, 110, 14, 7, 250, 108, 14, 7, 250, 106, 14, 7, + 250, 104, 14, 7, 250, 102, 14, 7, 250, 101, 14, 7, 250, 99, 14, 7, 250, + 97, 14, 7, 250, 95, 14, 7, 250, 93, 14, 7, 247, 203, 14, 7, 247, 202, 14, + 7, 247, 201, 14, 7, 247, 200, 14, 7, 247, 199, 14, 7, 247, 198, 14, 7, + 247, 197, 14, 7, 247, 196, 14, 7, 247, 195, 14, 7, 247, 194, 14, 7, 247, + 193, 14, 7, 247, 192, 14, 7, 247, 191, 14, 7, 247, 190, 14, 7, 247, 189, + 14, 7, 247, 188, 14, 7, 247, 187, 14, 7, 247, 186, 14, 7, 247, 185, 14, + 7, 247, 184, 14, 7, 247, 183, 14, 7, 247, 182, 14, 7, 247, 181, 14, 7, + 247, 180, 14, 7, 247, 179, 14, 7, 247, 178, 14, 7, 247, 177, 14, 7, 247, + 176, 14, 7, 240, 230, 14, 7, 240, 229, 14, 7, 240, 228, 14, 7, 240, 227, + 14, 7, 240, 226, 14, 7, 240, 225, 14, 7, 240, 224, 14, 7, 240, 223, 14, + 7, 240, 222, 14, 7, 240, 221, 14, 7, 240, 220, 14, 7, 240, 219, 14, 7, + 240, 218, 14, 7, 240, 217, 14, 7, 240, 216, 14, 7, 240, 215, 14, 7, 240, + 214, 14, 7, 240, 213, 14, 7, 240, 212, 14, 7, 240, 211, 14, 7, 240, 210, + 14, 7, 240, 209, 14, 7, 240, 208, 14, 7, 240, 207, 14, 7, 240, 206, 14, + 7, 240, 205, 14, 7, 240, 204, 14, 7, 240, 203, 14, 7, 240, 202, 14, 7, + 240, 201, 14, 7, 240, 200, 14, 7, 240, 199, 14, 7, 240, 198, 14, 7, 240, + 197, 14, 7, 240, 196, 14, 7, 240, 195, 14, 7, 240, 194, 14, 7, 240, 193, + 14, 7, 240, 192, 14, 7, 240, 191, 14, 7, 240, 190, 14, 7, 240, 189, 14, + 7, 240, 188, 14, 7, 240, 187, 14, 7, 240, 186, 14, 7, 240, 185, 14, 7, + 240, 184, 14, 7, 240, 183, 14, 7, 240, 182, 14, 7, 240, 181, 14, 7, 240, + 180, 14, 7, 240, 179, 14, 7, 240, 178, 14, 7, 240, 177, 14, 7, 240, 176, + 14, 7, 240, 175, 14, 7, 240, 174, 14, 7, 240, 173, 14, 7, 240, 172, 14, + 7, 240, 171, 14, 7, 240, 170, 14, 7, 240, 169, 14, 7, 240, 168, 14, 7, + 240, 167, 14, 7, 240, 166, 14, 7, 240, 165, 14, 7, 240, 164, 14, 7, 240, + 163, 14, 7, 240, 162, 14, 7, 240, 161, 14, 7, 240, 160, 14, 7, 240, 159, + 14, 7, 240, 158, 14, 7, 240, 157, 14, 7, 240, 156, 14, 7, 240, 155, 14, + 7, 240, 154, 14, 7, 240, 153, 14, 7, 240, 152, 14, 7, 240, 151, 14, 7, + 240, 150, 14, 7, 240, 149, 14, 7, 240, 148, 14, 7, 240, 147, 14, 7, 240, + 146, 14, 7, 240, 145, 14, 7, 240, 144, 14, 7, 240, 143, 14, 7, 240, 142, + 14, 7, 240, 141, 14, 7, 240, 140, 14, 7, 240, 139, 14, 7, 237, 128, 14, + 7, 237, 127, 14, 7, 237, 126, 14, 7, 237, 125, 14, 7, 237, 124, 14, 7, + 237, 123, 14, 7, 237, 122, 14, 7, 237, 121, 14, 7, 237, 120, 14, 7, 237, + 119, 14, 7, 237, 118, 14, 7, 237, 117, 14, 7, 237, 116, 14, 7, 237, 115, + 14, 7, 237, 114, 14, 7, 237, 113, 14, 7, 237, 112, 14, 7, 237, 111, 14, + 7, 237, 110, 14, 7, 237, 109, 14, 7, 237, 108, 14, 7, 237, 107, 14, 7, + 237, 106, 14, 7, 237, 105, 14, 7, 237, 104, 14, 7, 237, 103, 14, 7, 237, + 102, 14, 7, 237, 101, 14, 7, 237, 100, 14, 7, 237, 99, 14, 7, 237, 98, + 14, 7, 237, 97, 14, 7, 237, 96, 14, 7, 237, 95, 14, 7, 237, 94, 14, 7, + 237, 93, 14, 7, 237, 92, 14, 7, 237, 91, 14, 7, 237, 90, 14, 7, 237, 89, + 14, 7, 237, 88, 14, 7, 237, 87, 14, 7, 237, 86, 14, 7, 237, 85, 14, 7, + 236, 48, 14, 7, 236, 47, 14, 7, 236, 46, 14, 7, 236, 45, 14, 7, 236, 44, + 14, 7, 236, 43, 14, 7, 236, 42, 14, 7, 236, 41, 14, 7, 236, 40, 14, 7, + 236, 39, 14, 7, 236, 38, 14, 7, 236, 37, 14, 7, 236, 36, 14, 7, 236, 35, + 14, 7, 236, 34, 14, 7, 236, 33, 14, 7, 236, 32, 14, 7, 236, 31, 14, 7, + 236, 30, 14, 7, 236, 29, 14, 7, 236, 28, 14, 7, 236, 27, 14, 7, 236, 26, + 14, 7, 236, 25, 14, 7, 236, 24, 14, 7, 236, 23, 14, 7, 236, 22, 14, 7, + 236, 21, 14, 7, 236, 20, 14, 7, 236, 19, 14, 7, 236, 18, 14, 7, 236, 17, + 14, 7, 236, 16, 14, 7, 236, 15, 14, 7, 236, 14, 14, 7, 236, 13, 14, 7, + 236, 12, 14, 7, 236, 11, 14, 7, 236, 10, 14, 7, 236, 9, 14, 7, 236, 8, + 14, 7, 236, 7, 14, 7, 236, 6, 14, 7, 236, 5, 14, 7, 236, 4, 14, 7, 236, + 3, 14, 7, 236, 2, 14, 7, 236, 1, 14, 7, 236, 0, 14, 7, 235, 255, 14, 7, + 235, 254, 14, 7, 235, 253, 14, 7, 235, 252, 14, 7, 235, 251, 14, 7, 235, + 250, 14, 7, 235, 249, 14, 7, 235, 248, 14, 7, 235, 247, 14, 7, 235, 246, + 14, 7, 235, 245, 14, 7, 235, 244, 14, 7, 235, 243, 14, 7, 235, 242, 14, + 7, 235, 241, 14, 7, 235, 240, 14, 7, 234, 189, 14, 7, 234, 188, 14, 7, + 234, 187, 14, 7, 234, 186, 14, 7, 234, 185, 14, 7, 234, 184, 14, 7, 234, + 183, 14, 7, 234, 182, 14, 7, 234, 181, 14, 7, 234, 180, 14, 7, 234, 179, + 14, 7, 234, 178, 14, 7, 234, 177, 14, 7, 234, 176, 14, 7, 234, 175, 14, + 7, 234, 174, 14, 7, 234, 173, 14, 7, 234, 172, 14, 7, 234, 171, 14, 7, + 234, 170, 14, 7, 234, 169, 14, 7, 234, 168, 14, 7, 234, 167, 14, 7, 234, + 166, 14, 7, 234, 165, 14, 7, 234, 164, 14, 7, 234, 163, 14, 7, 234, 162, + 14, 7, 234, 161, 14, 7, 234, 160, 14, 7, 234, 159, 14, 7, 234, 158, 14, + 7, 234, 157, 14, 7, 234, 156, 14, 7, 234, 155, 14, 7, 234, 154, 14, 7, + 234, 153, 14, 7, 234, 152, 14, 7, 234, 151, 14, 7, 234, 150, 14, 7, 234, + 149, 14, 7, 234, 148, 14, 7, 234, 147, 14, 7, 234, 146, 14, 7, 234, 145, + 14, 7, 234, 144, 14, 7, 234, 143, 14, 7, 234, 142, 14, 7, 234, 141, 14, + 7, 234, 140, 14, 7, 234, 139, 14, 7, 234, 138, 14, 7, 234, 137, 14, 7, + 234, 136, 14, 7, 234, 135, 14, 7, 234, 134, 14, 7, 234, 133, 14, 7, 234, + 132, 14, 7, 234, 131, 14, 7, 234, 130, 14, 7, 234, 129, 14, 7, 234, 128, + 14, 7, 234, 127, 14, 7, 234, 126, 14, 7, 233, 13, 14, 7, 233, 12, 14, 7, + 233, 11, 14, 7, 233, 10, 14, 7, 233, 9, 14, 7, 233, 8, 14, 7, 233, 7, 14, + 7, 233, 6, 14, 7, 233, 5, 14, 7, 230, 229, 14, 7, 230, 228, 14, 7, 230, + 227, 14, 7, 230, 226, 14, 7, 230, 225, 14, 7, 230, 224, 14, 7, 230, 223, + 14, 7, 230, 222, 14, 7, 230, 221, 14, 7, 230, 220, 14, 7, 230, 219, 14, + 7, 230, 218, 14, 7, 230, 217, 14, 7, 230, 216, 14, 7, 230, 215, 14, 7, + 230, 214, 14, 7, 230, 213, 14, 7, 230, 212, 14, 7, 230, 211, 14, 7, 225, + 79, 14, 7, 225, 78, 14, 7, 225, 77, 14, 7, 225, 76, 14, 7, 225, 75, 14, + 7, 225, 74, 14, 7, 225, 73, 14, 7, 225, 72, 14, 7, 223, 97, 14, 7, 223, + 96, 14, 7, 223, 95, 14, 7, 223, 94, 14, 7, 223, 93, 14, 7, 223, 92, 14, + 7, 223, 91, 14, 7, 223, 90, 14, 7, 223, 89, 14, 7, 223, 88, 14, 7, 221, + 134, 14, 7, 221, 133, 14, 7, 221, 132, 14, 7, 221, 130, 14, 7, 221, 128, + 14, 7, 221, 127, 14, 7, 221, 125, 14, 7, 221, 123, 14, 7, 221, 121, 14, + 7, 221, 119, 14, 7, 221, 117, 14, 7, 221, 115, 14, 7, 221, 113, 14, 7, + 221, 112, 14, 7, 221, 110, 14, 7, 221, 108, 14, 7, 221, 107, 14, 7, 221, + 106, 14, 7, 221, 105, 14, 7, 221, 104, 14, 7, 221, 103, 14, 7, 221, 102, + 14, 7, 221, 101, 14, 7, 221, 100, 14, 7, 221, 98, 14, 7, 221, 96, 14, 7, + 221, 94, 14, 7, 221, 93, 14, 7, 221, 91, 14, 7, 221, 90, 14, 7, 221, 88, + 14, 7, 221, 87, 14, 7, 221, 85, 14, 7, 221, 83, 14, 7, 221, 81, 14, 7, + 221, 79, 14, 7, 221, 77, 14, 7, 221, 76, 14, 7, 221, 74, 14, 7, 221, 72, + 14, 7, 221, 71, 14, 7, 221, 69, 14, 7, 221, 67, 14, 7, 221, 65, 14, 7, + 221, 63, 14, 7, 221, 62, 14, 7, 221, 60, 14, 7, 221, 58, 14, 7, 221, 56, + 14, 7, 221, 55, 14, 7, 221, 53, 14, 7, 221, 51, 14, 7, 221, 50, 14, 7, + 221, 49, 14, 7, 221, 47, 14, 7, 221, 45, 14, 7, 221, 43, 14, 7, 221, 41, + 14, 7, 221, 39, 14, 7, 221, 37, 14, 7, 221, 35, 14, 7, 221, 34, 14, 7, + 221, 32, 14, 7, 221, 30, 14, 7, 221, 28, 14, 7, 221, 26, 14, 7, 218, 50, + 14, 7, 218, 49, 14, 7, 218, 48, 14, 7, 218, 47, 14, 7, 218, 46, 14, 7, + 218, 45, 14, 7, 218, 44, 14, 7, 218, 43, 14, 7, 218, 42, 14, 7, 218, 41, + 14, 7, 218, 40, 14, 7, 218, 39, 14, 7, 218, 38, 14, 7, 218, 37, 14, 7, + 218, 36, 14, 7, 218, 35, 14, 7, 218, 34, 14, 7, 218, 33, 14, 7, 218, 32, + 14, 7, 218, 31, 14, 7, 218, 30, 14, 7, 218, 29, 14, 7, 218, 28, 14, 7, + 218, 27, 14, 7, 218, 26, 14, 7, 218, 25, 14, 7, 218, 24, 14, 7, 218, 23, + 14, 7, 218, 22, 14, 7, 218, 21, 14, 7, 218, 20, 14, 7, 218, 19, 14, 7, + 218, 18, 14, 7, 218, 17, 14, 7, 218, 16, 14, 7, 218, 15, 14, 7, 218, 14, + 14, 7, 218, 13, 14, 7, 218, 12, 14, 7, 218, 11, 14, 7, 218, 10, 14, 7, + 218, 9, 14, 7, 218, 8, 14, 7, 218, 7, 14, 7, 218, 6, 14, 7, 218, 5, 14, + 7, 218, 4, 14, 7, 218, 3, 14, 7, 218, 2, 14, 7, 216, 111, 14, 7, 216, + 110, 14, 7, 216, 109, 14, 7, 216, 108, 14, 7, 216, 107, 14, 7, 216, 106, + 14, 7, 216, 105, 14, 7, 216, 104, 14, 7, 216, 103, 14, 7, 216, 102, 14, + 7, 216, 101, 14, 7, 216, 100, 14, 7, 216, 99, 14, 7, 216, 98, 14, 7, 216, + 97, 14, 7, 216, 96, 14, 7, 216, 95, 14, 7, 216, 94, 14, 7, 216, 93, 14, + 7, 216, 92, 14, 7, 216, 91, 14, 7, 216, 90, 14, 7, 215, 182, 14, 7, 215, + 181, 14, 7, 215, 180, 14, 7, 215, 179, 14, 7, 215, 178, 14, 7, 215, 177, + 14, 7, 215, 176, 14, 7, 215, 175, 14, 7, 215, 174, 14, 7, 215, 173, 14, + 7, 215, 172, 14, 7, 215, 171, 14, 7, 215, 170, 14, 7, 215, 169, 14, 7, + 215, 168, 14, 7, 215, 167, 14, 7, 215, 166, 14, 7, 215, 165, 14, 7, 215, + 164, 14, 7, 215, 163, 14, 7, 215, 162, 14, 7, 215, 161, 14, 7, 215, 160, + 14, 7, 215, 159, 14, 7, 215, 158, 14, 7, 215, 157, 14, 7, 215, 10, 14, 7, + 215, 9, 14, 7, 215, 8, 14, 7, 215, 7, 14, 7, 215, 6, 14, 7, 215, 5, 14, + 7, 215, 4, 14, 7, 215, 3, 14, 7, 215, 2, 14, 7, 215, 1, 14, 7, 215, 0, + 14, 7, 214, 255, 14, 7, 214, 254, 14, 7, 214, 253, 14, 7, 214, 252, 14, + 7, 214, 251, 14, 7, 214, 250, 14, 7, 214, 249, 14, 7, 214, 248, 14, 7, + 214, 247, 14, 7, 214, 246, 14, 7, 214, 245, 14, 7, 214, 244, 14, 7, 214, + 243, 14, 7, 214, 242, 14, 7, 214, 241, 14, 7, 214, 240, 14, 7, 214, 239, + 14, 7, 214, 238, 14, 7, 214, 237, 14, 7, 214, 236, 14, 7, 214, 235, 14, + 7, 214, 234, 14, 7, 214, 233, 14, 7, 214, 232, 14, 7, 214, 231, 14, 7, + 214, 230, 14, 7, 214, 229, 14, 7, 214, 228, 14, 7, 214, 227, 14, 7, 214, + 226, 14, 7, 214, 225, 14, 7, 214, 224, 14, 7, 214, 223, 14, 7, 214, 222, + 14, 7, 214, 221, 14, 7, 214, 220, 14, 7, 214, 219, 14, 7, 214, 218, 14, + 7, 214, 217, 14, 7, 214, 216, 14, 7, 214, 215, 14, 7, 214, 214, 14, 7, + 214, 213, 14, 7, 214, 212, 14, 7, 214, 211, 14, 7, 214, 210, 14, 7, 214, + 209, 14, 7, 214, 208, 14, 7, 214, 207, 14, 7, 214, 206, 14, 7, 214, 205, + 14, 7, 214, 204, 14, 7, 214, 203, 14, 7, 214, 202, 14, 7, 214, 201, 14, + 7, 214, 200, 14, 7, 214, 199, 14, 7, 214, 198, 14, 7, 214, 197, 14, 7, + 214, 196, 14, 7, 214, 195, 14, 7, 214, 194, 14, 7, 214, 193, 14, 7, 214, + 192, 14, 7, 214, 2, 14, 7, 214, 1, 14, 7, 214, 0, 14, 7, 213, 255, 14, 7, + 213, 254, 14, 7, 213, 253, 14, 7, 213, 252, 14, 7, 213, 251, 14, 7, 213, + 250, 14, 7, 213, 249, 14, 7, 213, 248, 14, 7, 213, 247, 14, 7, 213, 246, + 14, 7, 211, 166, 14, 7, 211, 165, 14, 7, 211, 164, 14, 7, 211, 163, 14, + 7, 211, 162, 14, 7, 211, 161, 14, 7, 211, 160, 14, 7, 211, 30, 14, 7, + 211, 29, 14, 7, 211, 28, 14, 7, 211, 27, 14, 7, 211, 26, 14, 7, 211, 25, + 14, 7, 211, 24, 14, 7, 211, 23, 14, 7, 211, 22, 14, 7, 211, 21, 14, 7, + 211, 20, 14, 7, 211, 19, 14, 7, 211, 18, 14, 7, 211, 17, 14, 7, 211, 16, + 14, 7, 211, 15, 14, 7, 211, 14, 14, 7, 211, 13, 14, 7, 211, 12, 14, 7, + 211, 11, 14, 7, 211, 10, 14, 7, 211, 9, 14, 7, 211, 8, 14, 7, 211, 7, 14, + 7, 211, 6, 14, 7, 211, 5, 14, 7, 211, 4, 14, 7, 211, 3, 14, 7, 211, 2, + 14, 7, 211, 1, 14, 7, 211, 0, 14, 7, 210, 255, 14, 7, 210, 254, 14, 7, + 210, 253, 14, 7, 209, 77, 14, 7, 209, 76, 14, 7, 209, 75, 14, 7, 209, 74, + 14, 7, 209, 73, 14, 7, 209, 72, 14, 7, 209, 71, 14, 7, 209, 70, 14, 7, + 209, 69, 14, 7, 209, 68, 14, 7, 209, 67, 14, 7, 209, 66, 14, 7, 209, 65, + 14, 7, 209, 64, 14, 7, 209, 63, 14, 7, 209, 62, 14, 7, 209, 61, 14, 7, + 209, 60, 14, 7, 209, 59, 14, 7, 209, 58, 14, 7, 209, 57, 14, 7, 209, 56, + 14, 7, 209, 55, 14, 7, 209, 54, 14, 7, 209, 53, 14, 7, 209, 52, 14, 7, + 209, 51, 14, 7, 209, 50, 14, 7, 209, 49, 14, 7, 209, 48, 14, 7, 209, 47, + 14, 7, 209, 46, 14, 7, 209, 45, 14, 7, 209, 44, 14, 7, 209, 43, 14, 7, + 209, 42, 14, 7, 209, 41, 14, 7, 209, 40, 14, 7, 209, 39, 14, 7, 209, 38, + 14, 7, 209, 37, 14, 7, 209, 36, 14, 7, 209, 35, 14, 7, 209, 34, 14, 7, + 209, 33, 14, 7, 209, 32, 14, 7, 209, 31, 14, 7, 209, 30, 14, 7, 209, 29, + 14, 7, 209, 28, 14, 7, 209, 27, 14, 7, 209, 26, 14, 7, 209, 25, 14, 7, + 209, 24, 14, 7, 203, 213, 14, 7, 203, 212, 14, 7, 203, 211, 14, 7, 203, + 210, 14, 7, 203, 209, 14, 7, 203, 208, 14, 7, 203, 207, 14, 7, 203, 206, + 14, 7, 203, 205, 14, 7, 203, 204, 14, 7, 203, 203, 14, 7, 203, 202, 14, + 7, 203, 201, 14, 7, 203, 200, 14, 7, 203, 199, 14, 7, 203, 198, 14, 7, + 203, 197, 14, 7, 203, 196, 14, 7, 203, 195, 14, 7, 203, 194, 14, 7, 203, + 193, 14, 7, 203, 192, 14, 7, 203, 191, 14, 7, 203, 190, 14, 7, 203, 189, + 14, 7, 203, 188, 14, 7, 203, 187, 14, 7, 203, 186, 14, 7, 203, 185, 14, + 7, 203, 184, 14, 7, 203, 183, 14, 7, 203, 182, 14, 7, 203, 181, 14, 7, + 203, 180, 14, 7, 203, 179, 14, 7, 203, 178, 14, 7, 203, 177, 14, 7, 203, + 176, 14, 7, 203, 175, 14, 7, 203, 174, 14, 7, 203, 173, 14, 7, 203, 172, + 14, 7, 203, 171, 14, 7, 203, 170, 14, 7, 200, 163, 14, 7, 200, 162, 14, + 7, 200, 161, 14, 7, 200, 160, 14, 7, 200, 159, 14, 7, 200, 158, 14, 7, + 200, 157, 14, 7, 200, 156, 14, 7, 200, 155, 14, 7, 200, 154, 14, 7, 200, + 153, 14, 7, 200, 152, 14, 7, 200, 151, 14, 7, 200, 150, 14, 7, 200, 149, + 14, 7, 200, 148, 14, 7, 200, 147, 14, 7, 200, 146, 14, 7, 200, 145, 14, + 7, 200, 144, 14, 7, 200, 143, 14, 7, 200, 142, 14, 7, 200, 141, 14, 7, + 200, 140, 14, 7, 200, 139, 14, 7, 200, 138, 14, 7, 200, 137, 14, 7, 200, + 136, 14, 7, 200, 135, 14, 7, 200, 134, 14, 7, 200, 133, 14, 7, 200, 132, + 14, 7, 200, 131, 14, 7, 200, 130, 14, 7, 200, 129, 14, 7, 200, 128, 14, + 7, 200, 127, 14, 7, 200, 126, 14, 7, 200, 125, 14, 7, 200, 124, 14, 7, + 200, 123, 14, 7, 200, 122, 14, 7, 200, 121, 14, 7, 200, 120, 14, 7, 200, + 119, 14, 7, 200, 118, 14, 7, 200, 117, 14, 7, 199, 229, 14, 7, 199, 228, + 14, 7, 199, 227, 14, 7, 199, 226, 14, 7, 199, 225, 14, 7, 199, 224, 14, + 7, 199, 223, 14, 7, 199, 222, 14, 7, 199, 221, 14, 7, 199, 220, 14, 7, + 199, 219, 14, 7, 199, 218, 14, 7, 199, 217, 14, 7, 199, 216, 14, 7, 199, + 215, 14, 7, 199, 214, 14, 7, 199, 213, 14, 7, 199, 212, 14, 7, 199, 211, + 14, 7, 199, 210, 14, 7, 199, 209, 14, 7, 199, 208, 14, 7, 199, 207, 14, + 7, 199, 206, 14, 7, 199, 205, 14, 7, 199, 204, 14, 7, 199, 203, 14, 7, + 199, 202, 14, 7, 199, 201, 14, 7, 199, 200, 14, 7, 199, 199, 14, 7, 199, + 198, 14, 7, 199, 197, 14, 7, 199, 196, 14, 7, 199, 195, 14, 7, 199, 194, + 14, 7, 199, 193, 14, 7, 199, 192, 14, 7, 199, 191, 14, 7, 199, 190, 14, + 7, 199, 189, 14, 7, 199, 188, 14, 7, 199, 187, 14, 7, 199, 186, 14, 7, + 199, 185, 14, 7, 199, 184, 14, 7, 199, 183, 14, 7, 199, 182, 14, 7, 199, + 181, 14, 7, 199, 180, 14, 7, 199, 179, 14, 7, 199, 178, 14, 7, 199, 177, + 14, 7, 199, 176, 14, 7, 199, 175, 14, 7, 199, 174, 14, 7, 199, 173, 14, + 7, 199, 172, 14, 7, 199, 171, 14, 7, 199, 170, 14, 7, 199, 169, 14, 7, + 199, 168, 14, 7, 199, 167, 14, 7, 199, 166, 14, 7, 199, 165, 14, 7, 199, + 164, 14, 7, 199, 163, 14, 7, 199, 162, 14, 7, 199, 161, 14, 7, 199, 160, + 14, 7, 199, 159, 14, 7, 199, 158, 14, 7, 199, 157, 14, 7, 199, 156, 14, + 7, 199, 155, 14, 7, 199, 154, 14, 7, 199, 153, 14, 7, 197, 198, 14, 7, + 197, 197, 14, 7, 197, 196, 14, 7, 197, 195, 14, 7, 197, 194, 14, 7, 197, + 193, 14, 7, 197, 192, 14, 7, 197, 191, 14, 7, 197, 190, 14, 7, 197, 189, + 14, 7, 197, 188, 14, 7, 197, 187, 14, 7, 197, 186, 14, 7, 197, 185, 14, + 7, 197, 184, 14, 7, 197, 183, 14, 7, 197, 182, 14, 7, 197, 181, 14, 7, + 197, 180, 14, 7, 197, 179, 14, 7, 197, 178, 14, 7, 197, 177, 14, 7, 197, + 176, 14, 7, 197, 175, 14, 7, 197, 174, 14, 7, 197, 173, 14, 7, 197, 172, + 14, 7, 197, 171, 14, 7, 197, 170, 14, 7, 197, 169, 14, 7, 197, 168, 14, + 7, 197, 167, 14, 7, 196, 220, 14, 7, 196, 219, 14, 7, 196, 218, 14, 7, + 196, 217, 14, 7, 196, 216, 14, 7, 196, 215, 14, 7, 196, 214, 14, 7, 196, + 213, 14, 7, 196, 212, 14, 7, 196, 211, 14, 7, 196, 210, 14, 7, 196, 209, + 14, 7, 196, 146, 14, 7, 196, 145, 14, 7, 196, 144, 14, 7, 196, 143, 14, + 7, 196, 142, 14, 7, 196, 141, 14, 7, 196, 140, 14, 7, 196, 139, 14, 7, + 196, 138, 14, 7, 195, 157, 14, 7, 195, 156, 14, 7, 195, 155, 14, 7, 195, + 154, 14, 7, 195, 153, 14, 7, 195, 152, 14, 7, 195, 151, 14, 7, 195, 150, + 14, 7, 195, 149, 14, 7, 195, 148, 14, 7, 195, 147, 14, 7, 195, 146, 14, + 7, 195, 145, 14, 7, 195, 144, 14, 7, 195, 143, 14, 7, 195, 142, 14, 7, + 195, 141, 14, 7, 195, 140, 14, 7, 195, 139, 14, 7, 195, 138, 14, 7, 195, + 137, 14, 7, 195, 136, 14, 7, 195, 135, 14, 7, 195, 134, 14, 7, 195, 133, + 14, 7, 195, 132, 14, 7, 195, 131, 14, 7, 195, 130, 14, 7, 195, 129, 14, + 7, 195, 128, 14, 7, 195, 127, 14, 7, 195, 126, 14, 7, 195, 125, 14, 7, + 195, 124, 14, 7, 195, 123, 14, 7, 195, 122, 14, 7, 195, 121, 14, 7, 195, + 120, 14, 7, 195, 119, 14, 7, 195, 118, 14, 7, 195, 117, 14, 7, 252, 167, + 14, 7, 252, 166, 14, 7, 252, 165, 14, 7, 252, 164, 14, 7, 252, 163, 14, + 7, 252, 162, 14, 7, 252, 161, 14, 7, 252, 160, 14, 7, 252, 159, 14, 7, + 252, 158, 14, 7, 252, 157, 14, 7, 252, 156, 14, 7, 252, 155, 14, 7, 252, + 154, 14, 7, 252, 153, 14, 7, 252, 152, 14, 7, 252, 151, 14, 7, 252, 150, + 14, 7, 252, 149, 14, 7, 252, 148, 14, 7, 252, 147, 14, 7, 252, 146, 14, + 7, 252, 145, 14, 7, 252, 144, 14, 7, 252, 143, 14, 7, 252, 142, 14, 7, + 252, 141, 14, 7, 252, 140, 14, 7, 252, 139, 14, 7, 252, 138, 14, 7, 252, + 137, 14, 7, 252, 136, 14, 7, 252, 135, 14, 7, 252, 134, 14, 7, 83, 225, + 124, 14, 7, 231, 155, 225, 124, 14, 7, 226, 44, 250, 169, 201, 243, 205, + 2, 14, 7, 226, 44, 250, 169, 248, 85, 205, 2, 14, 7, 226, 44, 250, 169, + 201, 243, 236, 221, 14, 7, 226, 44, 250, 169, 248, 85, 236, 221, 14, 7, + 214, 21, 219, 63, 14, 7, 248, 243, 208, 122, 14, 7, 236, 222, 208, 122, + 28, 7, 255, 161, 28, 7, 255, 160, 28, 7, 255, 159, 28, 7, 255, 158, 28, + 7, 255, 157, 28, 7, 255, 155, 28, 7, 255, 152, 28, 7, 255, 151, 28, 7, + 255, 150, 28, 7, 255, 149, 28, 7, 255, 148, 28, 7, 255, 147, 28, 7, 255, + 146, 28, 7, 255, 145, 28, 7, 255, 144, 28, 7, 255, 142, 28, 7, 255, 141, + 28, 7, 255, 140, 28, 7, 255, 138, 28, 7, 255, 137, 28, 7, 255, 136, 28, + 7, 255, 135, 28, 7, 255, 134, 28, 7, 255, 133, 28, 7, 255, 132, 28, 7, + 255, 131, 28, 7, 255, 130, 28, 7, 255, 129, 28, 7, 255, 128, 28, 7, 255, + 127, 28, 7, 255, 125, 28, 7, 255, 124, 28, 7, 255, 123, 28, 7, 255, 122, + 28, 7, 255, 120, 28, 7, 255, 119, 28, 7, 255, 118, 28, 7, 255, 117, 28, + 7, 255, 116, 28, 7, 255, 115, 28, 7, 255, 114, 28, 7, 255, 113, 28, 7, + 255, 112, 28, 7, 255, 110, 28, 7, 255, 109, 28, 7, 255, 108, 28, 7, 255, + 106, 28, 7, 255, 104, 28, 7, 255, 103, 28, 7, 255, 102, 28, 7, 255, 101, + 28, 7, 255, 100, 28, 7, 255, 99, 28, 7, 255, 98, 28, 7, 255, 97, 28, 7, + 255, 96, 28, 7, 255, 95, 28, 7, 255, 94, 28, 7, 255, 93, 28, 7, 255, 92, + 28, 7, 255, 91, 28, 7, 255, 90, 28, 7, 255, 89, 28, 7, 255, 88, 28, 7, + 255, 87, 28, 7, 255, 86, 28, 7, 255, 85, 28, 7, 255, 84, 28, 7, 255, 83, + 28, 7, 255, 82, 28, 7, 255, 81, 28, 7, 255, 80, 28, 7, 255, 79, 28, 7, + 255, 78, 28, 7, 255, 77, 28, 7, 255, 76, 28, 7, 255, 75, 28, 7, 255, 74, + 28, 7, 255, 73, 28, 7, 255, 72, 28, 7, 255, 71, 28, 7, 255, 70, 28, 7, + 255, 69, 28, 7, 255, 68, 28, 7, 255, 67, 28, 7, 255, 66, 28, 7, 255, 65, + 28, 7, 255, 64, 28, 7, 255, 63, 28, 7, 255, 62, 28, 7, 255, 61, 28, 7, + 255, 60, 28, 7, 255, 59, 28, 7, 255, 58, 28, 7, 255, 57, 28, 7, 255, 56, + 28, 7, 255, 55, 28, 7, 255, 54, 28, 7, 255, 53, 28, 7, 255, 52, 28, 7, + 255, 51, 28, 7, 255, 50, 28, 7, 255, 49, 28, 7, 255, 48, 28, 7, 255, 47, + 28, 7, 255, 46, 28, 7, 255, 45, 28, 7, 255, 44, 28, 7, 255, 43, 28, 7, + 255, 42, 28, 7, 255, 41, 28, 7, 255, 40, 28, 7, 255, 38, 28, 7, 255, 37, + 28, 7, 255, 36, 28, 7, 255, 35, 28, 7, 255, 34, 28, 7, 255, 33, 28, 7, + 255, 32, 28, 7, 255, 31, 28, 7, 255, 30, 28, 7, 255, 29, 28, 7, 255, 28, + 28, 7, 255, 27, 28, 7, 255, 26, 28, 7, 255, 25, 28, 7, 255, 24, 28, 7, + 255, 23, 28, 7, 255, 22, 28, 7, 255, 21, 28, 7, 255, 20, 28, 7, 255, 19, + 28, 7, 255, 18, 28, 7, 255, 17, 28, 7, 255, 16, 28, 7, 255, 15, 28, 7, + 255, 14, 28, 7, 255, 13, 28, 7, 255, 12, 28, 7, 255, 11, 28, 7, 255, 10, + 28, 7, 255, 9, 28, 7, 255, 8, 28, 7, 255, 7, 28, 7, 255, 6, 28, 7, 255, + 5, 28, 7, 255, 3, 28, 7, 255, 2, 28, 7, 255, 1, 28, 7, 255, 0, 28, 7, + 254, 255, 28, 7, 254, 254, 28, 7, 254, 253, 28, 7, 254, 252, 28, 7, 254, + 251, 28, 7, 254, 250, 28, 7, 254, 249, 28, 7, 254, 248, 28, 7, 254, 246, + 28, 7, 254, 245, 28, 7, 254, 244, 28, 7, 254, 243, 28, 7, 254, 242, 28, + 7, 254, 241, 28, 7, 254, 240, 28, 7, 254, 239, 28, 7, 254, 238, 28, 7, + 254, 237, 28, 7, 254, 236, 28, 7, 254, 235, 28, 7, 254, 234, 28, 7, 254, + 233, 28, 7, 254, 232, 28, 7, 254, 231, 28, 7, 254, 230, 28, 7, 254, 229, + 28, 7, 254, 228, 28, 7, 254, 227, 28, 7, 254, 226, 28, 7, 254, 225, 28, + 7, 254, 224, 28, 7, 254, 223, 28, 7, 254, 222, 28, 7, 254, 221, 28, 7, + 254, 220, 28, 7, 254, 219, 28, 7, 254, 218, 28, 7, 254, 217, 28, 7, 254, + 216, 28, 7, 254, 215, 28, 7, 254, 214, 28, 7, 254, 213, 28, 7, 254, 212, + 28, 7, 254, 211, 28, 7, 254, 210, 28, 7, 254, 209, 28, 7, 254, 208, 28, + 7, 254, 207, 28, 7, 254, 206, 28, 7, 254, 205, 28, 7, 254, 204, 28, 7, + 254, 203, 28, 7, 254, 202, 28, 7, 254, 201, 28, 7, 254, 200, 28, 7, 254, + 199, 28, 7, 254, 198, 28, 7, 254, 197, 28, 7, 254, 196, 28, 7, 254, 195, + 28, 7, 254, 194, 28, 7, 254, 193, 28, 7, 254, 192, 28, 7, 254, 191, 28, + 7, 254, 190, 28, 7, 254, 189, 28, 7, 254, 188, 28, 7, 254, 187, 28, 7, + 254, 186, 28, 7, 254, 185, 28, 7, 254, 184, 28, 7, 254, 183, 28, 7, 254, + 182, 28, 7, 254, 181, 28, 7, 254, 180, 28, 7, 254, 179, 28, 7, 254, 178, + 28, 7, 254, 176, 28, 7, 254, 175, 28, 7, 254, 174, 28, 7, 254, 173, 28, + 7, 254, 172, 28, 7, 254, 171, 28, 7, 254, 170, 28, 7, 254, 169, 28, 7, + 254, 168, 28, 7, 254, 167, 28, 7, 254, 166, 28, 7, 254, 165, 28, 7, 254, + 164, 28, 7, 254, 163, 28, 7, 254, 162, 28, 7, 254, 161, 28, 7, 254, 160, + 28, 7, 254, 159, 28, 7, 254, 158, 28, 7, 254, 157, 28, 7, 254, 156, 28, + 7, 254, 155, 28, 7, 254, 154, 28, 7, 254, 153, 28, 7, 254, 152, 28, 7, + 254, 151, 28, 7, 254, 150, 28, 7, 254, 149, 28, 7, 254, 148, 28, 7, 254, + 147, 28, 7, 254, 146, 28, 7, 254, 145, 28, 7, 254, 144, 28, 7, 254, 143, + 28, 7, 254, 142, 28, 7, 254, 141, 28, 7, 254, 140, 28, 7, 254, 139, 28, + 7, 254, 138, 28, 7, 254, 137, 28, 7, 254, 136, 28, 7, 254, 135, 28, 7, + 254, 134, 28, 7, 254, 133, 28, 7, 254, 132, 28, 7, 254, 131, 28, 7, 254, + 130, 28, 7, 254, 129, 28, 7, 254, 128, 28, 7, 254, 127, 28, 7, 254, 126, + 28, 7, 254, 125, 28, 7, 254, 124, 28, 7, 254, 123, 28, 7, 254, 122, 28, + 7, 254, 121, 28, 7, 254, 120, 28, 7, 254, 119, 28, 7, 254, 118, 28, 7, + 254, 117, 28, 7, 254, 116, 28, 7, 254, 115, 28, 7, 254, 114, 28, 7, 254, + 113, 28, 7, 254, 112, 28, 7, 254, 111, 28, 7, 254, 110, 28, 7, 254, 109, + 28, 7, 254, 108, 28, 7, 254, 107, 28, 7, 254, 106, 28, 7, 254, 105, 28, + 7, 254, 104, 28, 7, 254, 103, 28, 7, 254, 102, 28, 7, 254, 101, 28, 7, + 254, 100, 28, 7, 254, 99, 28, 7, 254, 98, 28, 7, 254, 97, 28, 7, 254, 96, + 28, 7, 254, 95, 28, 7, 254, 94, 28, 7, 254, 93, 28, 7, 254, 92, 28, 7, + 254, 91, 28, 7, 254, 90, 28, 7, 254, 89, 28, 7, 254, 88, 28, 7, 254, 87, + 28, 7, 254, 86, 28, 7, 254, 85, 28, 7, 254, 84, 28, 7, 254, 83, 28, 7, + 254, 82, 28, 7, 254, 81, 28, 7, 254, 80, 28, 7, 254, 79, 28, 7, 254, 78, + 28, 7, 254, 77, 28, 7, 254, 76, 28, 7, 254, 75, 28, 7, 254, 74, 28, 7, + 254, 73, 28, 7, 254, 72, 28, 7, 254, 71, 28, 7, 254, 70, 28, 7, 254, 69, + 28, 7, 254, 68, 28, 7, 254, 67, 28, 7, 254, 66, 28, 7, 254, 64, 28, 7, + 254, 63, 28, 7, 254, 62, 28, 7, 254, 61, 28, 7, 254, 60, 28, 7, 254, 59, + 28, 7, 254, 58, 28, 7, 254, 57, 28, 7, 254, 56, 28, 7, 254, 55, 28, 7, + 254, 54, 28, 7, 254, 51, 28, 7, 254, 50, 28, 7, 254, 49, 28, 7, 254, 48, + 28, 7, 254, 44, 28, 7, 254, 43, 28, 7, 254, 42, 28, 7, 254, 41, 28, 7, + 254, 40, 28, 7, 254, 39, 28, 7, 254, 38, 28, 7, 254, 37, 28, 7, 254, 36, + 28, 7, 254, 35, 28, 7, 254, 34, 28, 7, 254, 33, 28, 7, 254, 32, 28, 7, + 254, 31, 28, 7, 254, 30, 28, 7, 254, 29, 28, 7, 254, 28, 28, 7, 254, 27, + 28, 7, 254, 26, 28, 7, 254, 24, 28, 7, 254, 23, 28, 7, 254, 22, 28, 7, + 254, 21, 28, 7, 254, 20, 28, 7, 254, 19, 28, 7, 254, 18, 28, 7, 254, 17, + 28, 7, 254, 16, 28, 7, 254, 15, 28, 7, 254, 14, 28, 7, 254, 13, 28, 7, + 254, 12, 28, 7, 254, 11, 28, 7, 254, 10, 28, 7, 254, 9, 28, 7, 254, 8, + 28, 7, 254, 7, 28, 7, 254, 6, 28, 7, 254, 5, 28, 7, 254, 4, 28, 7, 254, + 3, 28, 7, 254, 2, 28, 7, 254, 1, 28, 7, 254, 0, 28, 7, 253, 255, 28, 7, + 253, 254, 28, 7, 253, 253, 28, 7, 253, 252, 28, 7, 253, 251, 28, 7, 253, + 250, 28, 7, 253, 249, 28, 7, 253, 248, 28, 7, 253, 247, 28, 7, 253, 246, + 28, 7, 253, 245, 28, 7, 253, 244, 28, 7, 253, 243, 28, 7, 253, 242, 28, + 7, 253, 241, 28, 7, 253, 240, 28, 7, 253, 239, 28, 7, 253, 238, 28, 7, + 253, 237, 28, 7, 253, 236, 28, 7, 253, 235, 28, 7, 253, 234, 28, 7, 253, + 233, 28, 7, 253, 232, 28, 7, 253, 231, 28, 7, 253, 230, 28, 7, 253, 229, + 28, 7, 253, 228, 28, 7, 253, 227, 28, 7, 253, 226, 28, 7, 253, 225, 28, + 7, 253, 224, 28, 7, 253, 223, 28, 7, 253, 222, 28, 7, 253, 221, 28, 7, + 253, 220, 28, 7, 253, 219, 210, 252, 214, 73, 210, 72, 28, 7, 253, 218, + 28, 7, 253, 217, 28, 7, 253, 216, 28, 7, 253, 215, 28, 7, 253, 214, 28, + 7, 253, 213, 28, 7, 253, 212, 28, 7, 253, 211, 28, 7, 253, 210, 28, 7, + 253, 209, 28, 7, 253, 208, 28, 7, 253, 207, 171, 28, 7, 253, 206, 28, 7, + 253, 205, 28, 7, 253, 204, 28, 7, 253, 203, 28, 7, 253, 202, 28, 7, 253, + 201, 28, 7, 253, 200, 28, 7, 253, 198, 28, 7, 253, 196, 28, 7, 253, 194, + 28, 7, 253, 192, 28, 7, 253, 190, 28, 7, 253, 188, 28, 7, 253, 186, 28, + 7, 253, 184, 28, 7, 253, 182, 28, 7, 253, 180, 248, 243, 221, 248, 78, + 28, 7, 253, 178, 236, 222, 221, 248, 78, 28, 7, 253, 177, 28, 7, 253, + 175, 28, 7, 253, 173, 28, 7, 253, 171, 28, 7, 253, 169, 28, 7, 253, 167, + 28, 7, 253, 165, 28, 7, 253, 163, 28, 7, 253, 161, 28, 7, 253, 160, 28, + 7, 253, 159, 28, 7, 253, 158, 28, 7, 253, 157, 28, 7, 253, 156, 28, 7, + 253, 155, 28, 7, 253, 154, 28, 7, 253, 153, 28, 7, 253, 152, 28, 7, 253, + 151, 28, 7, 253, 150, 28, 7, 253, 149, 28, 7, 253, 148, 28, 7, 253, 147, + 28, 7, 253, 146, 28, 7, 253, 145, 28, 7, 253, 144, 28, 7, 253, 143, 28, + 7, 253, 142, 28, 7, 253, 141, 28, 7, 253, 140, 28, 7, 253, 139, 28, 7, + 253, 138, 28, 7, 253, 137, 28, 7, 253, 136, 28, 7, 253, 135, 28, 7, 253, + 134, 28, 7, 253, 133, 28, 7, 253, 132, 28, 7, 253, 131, 28, 7, 253, 130, + 28, 7, 253, 129, 28, 7, 253, 128, 28, 7, 253, 127, 28, 7, 253, 126, 28, + 7, 253, 125, 28, 7, 253, 124, 28, 7, 253, 123, 28, 7, 253, 122, 28, 7, + 253, 121, 28, 7, 253, 120, 28, 7, 253, 119, 28, 7, 253, 118, 28, 7, 253, + 117, 28, 7, 253, 116, 28, 7, 253, 115, 28, 7, 253, 114, 28, 7, 253, 113, + 28, 7, 253, 112, 28, 7, 253, 111, 28, 7, 253, 110, 28, 7, 253, 109, 28, + 7, 253, 108, 28, 7, 253, 107, 28, 7, 253, 106, 28, 7, 253, 105, 28, 7, + 253, 104, 28, 7, 253, 103, 28, 7, 253, 102, 28, 7, 253, 101, 28, 7, 253, + 100, 28, 7, 253, 99, 28, 7, 253, 98, 28, 7, 253, 97, 28, 7, 253, 96, 28, + 7, 253, 95, 28, 7, 253, 94, 28, 7, 253, 93, 28, 7, 253, 92, 28, 7, 253, + 91, 28, 7, 253, 90, 28, 7, 253, 89, 28, 7, 253, 88, 28, 7, 253, 87, 28, + 7, 253, 86, 28, 7, 253, 85, 28, 7, 253, 84, 28, 7, 253, 83, 28, 7, 253, + 82, 28, 7, 253, 81, 28, 7, 253, 80, 28, 7, 253, 79, 28, 7, 253, 78, 28, + 7, 253, 77, 28, 7, 253, 76, 28, 7, 253, 75, 28, 7, 253, 74, 28, 7, 253, + 73, 28, 7, 253, 72, 28, 7, 253, 71, 28, 7, 253, 70, 28, 7, 253, 69, 28, + 7, 253, 68, 28, 7, 253, 67, 28, 7, 253, 66, 28, 7, 253, 65, 28, 7, 253, + 64, 28, 7, 253, 63, 28, 7, 253, 62, 28, 7, 253, 61, 28, 7, 253, 60, 28, + 7, 253, 59, 28, 7, 253, 58, 28, 7, 253, 57, 28, 7, 253, 56, 28, 7, 253, + 55, 28, 7, 253, 54, 28, 7, 253, 53, 28, 7, 253, 52, 28, 7, 253, 51, 25, + 1, 212, 252, 217, 4, 219, 120, 25, 1, 212, 252, 234, 56, 235, 43, 25, 1, + 212, 252, 212, 94, 219, 121, 212, 167, 25, 1, 212, 252, 212, 94, 219, + 121, 212, 168, 25, 1, 212, 252, 217, 245, 219, 120, 25, 1, 212, 252, 206, + 146, 25, 1, 212, 252, 202, 56, 219, 120, 25, 1, 212, 252, 215, 55, 219, + 120, 25, 1, 212, 252, 206, 210, 213, 244, 216, 148, 25, 1, 212, 252, 212, + 94, 213, 244, 216, 149, 212, 167, 25, 1, 212, 252, 212, 94, 213, 244, + 216, 149, 212, 168, 25, 1, 212, 252, 220, 99, 25, 1, 212, 252, 201, 41, + 220, 100, 25, 1, 212, 252, 217, 65, 25, 1, 212, 252, 220, 96, 25, 1, 212, + 252, 220, 49, 25, 1, 212, 252, 218, 78, 25, 1, 212, 252, 207, 73, 25, 1, + 212, 252, 215, 195, 25, 1, 212, 252, 224, 165, 25, 1, 212, 252, 216, 115, + 25, 1, 212, 252, 204, 74, 25, 1, 212, 252, 217, 3, 25, 1, 212, 252, 222, + 230, 25, 1, 212, 252, 222, 137, 223, 145, 25, 1, 212, 252, 215, 205, 219, + 128, 25, 1, 212, 252, 220, 103, 25, 1, 212, 252, 213, 125, 25, 1, 212, + 252, 233, 211, 25, 1, 212, 252, 213, 195, 25, 1, 212, 252, 218, 216, 217, + 38, 25, 1, 212, 252, 215, 36, 219, 131, 25, 1, 212, 252, 118, 195, 187, + 217, 238, 25, 1, 212, 252, 233, 212, 25, 1, 212, 252, 215, 205, 215, 206, + 25, 1, 212, 252, 206, 32, 25, 1, 212, 252, 219, 113, 25, 1, 212, 252, + 219, 134, 25, 1, 212, 252, 218, 191, 25, 1, 212, 252, 225, 34, 25, 1, + 212, 252, 213, 244, 222, 185, 25, 1, 212, 252, 217, 160, 222, 185, 25, 1, + 212, 252, 213, 18, 25, 1, 212, 252, 220, 97, 25, 1, 212, 252, 216, 189, + 25, 1, 212, 252, 211, 206, 25, 1, 212, 252, 201, 33, 25, 1, 212, 252, + 221, 187, 25, 1, 212, 252, 205, 172, 25, 1, 212, 252, 202, 242, 25, 1, + 212, 252, 220, 94, 25, 1, 212, 252, 224, 172, 25, 1, 212, 252, 217, 156, + 25, 1, 212, 252, 223, 159, 25, 1, 212, 252, 218, 192, 25, 1, 212, 252, + 206, 142, 25, 1, 212, 252, 221, 241, 25, 1, 212, 252, 235, 114, 25, 1, + 212, 252, 209, 209, 25, 1, 212, 252, 223, 212, 25, 1, 212, 252, 205, 168, + 25, 1, 212, 252, 220, 44, 212, 210, 25, 1, 212, 252, 206, 203, 25, 1, + 212, 252, 215, 204, 25, 1, 212, 252, 206, 184, 215, 216, 195, 195, 25, 1, + 212, 252, 215, 77, 218, 212, 25, 1, 212, 252, 213, 239, 25, 1, 212, 252, + 216, 117, 25, 1, 212, 252, 200, 44, 25, 1, 212, 252, 217, 41, 25, 1, 212, + 252, 220, 93, 25, 1, 212, 252, 216, 160, 25, 1, 212, 252, 219, 236, 25, + 1, 212, 252, 215, 92, 25, 1, 212, 252, 202, 246, 25, 1, 212, 252, 205, + 165, 25, 1, 212, 252, 213, 240, 25, 1, 212, 252, 215, 220, 25, 1, 212, + 252, 220, 101, 25, 1, 212, 252, 215, 89, 25, 1, 212, 252, 224, 252, 25, + 1, 212, 252, 215, 223, 25, 1, 212, 252, 199, 113, 25, 1, 212, 252, 221, + 191, 25, 1, 212, 252, 217, 101, 25, 1, 212, 252, 217, 212, 25, 1, 212, + 252, 219, 235, 25, 1, 212, 251, 215, 218, 25, 1, 212, 251, 201, 41, 220, + 98, 25, 1, 212, 251, 206, 94, 25, 1, 212, 251, 207, 77, 201, 40, 25, 1, + 212, 251, 221, 243, 215, 201, 25, 1, 212, 251, 219, 242, 220, 102, 25, 1, + 212, 251, 224, 85, 25, 1, 212, 251, 196, 32, 25, 1, 212, 251, 219, 237, + 25, 1, 212, 251, 225, 20, 25, 1, 212, 251, 213, 75, 25, 1, 212, 251, 196, + 115, 222, 185, 25, 1, 212, 251, 222, 250, 215, 216, 215, 103, 25, 1, 212, + 251, 215, 198, 206, 229, 25, 1, 212, 251, 217, 127, 216, 163, 25, 1, 212, + 251, 233, 209, 25, 1, 212, 251, 212, 157, 25, 1, 212, 251, 201, 41, 215, + 214, 25, 1, 212, 251, 206, 234, 216, 158, 25, 1, 212, 251, 206, 230, 25, + 1, 212, 251, 219, 121, 202, 245, 25, 1, 212, 251, 219, 224, 219, 238, 25, + 1, 212, 251, 215, 90, 215, 201, 25, 1, 212, 251, 224, 161, 25, 1, 212, + 251, 233, 210, 25, 1, 212, 251, 224, 157, 25, 1, 212, 251, 223, 77, 25, + 1, 212, 251, 213, 128, 25, 1, 212, 251, 199, 42, 25, 1, 212, 251, 217, 5, + 218, 76, 25, 1, 212, 251, 217, 40, 219, 220, 25, 1, 212, 251, 196, 241, + 25, 1, 212, 251, 208, 247, 25, 1, 212, 251, 203, 158, 25, 1, 212, 251, + 219, 133, 25, 1, 212, 251, 217, 24, 25, 1, 212, 251, 217, 25, 222, 227, + 25, 1, 212, 251, 219, 123, 25, 1, 212, 251, 204, 127, 25, 1, 212, 251, + 219, 228, 25, 1, 212, 251, 218, 196, 25, 1, 212, 251, 215, 107, 25, 1, + 212, 251, 211, 210, 25, 1, 212, 251, 219, 132, 217, 42, 25, 1, 212, 251, + 235, 158, 25, 1, 212, 251, 219, 215, 25, 1, 212, 251, 235, 182, 25, 1, + 212, 251, 224, 169, 25, 1, 212, 251, 220, 128, 216, 152, 25, 1, 212, 251, + 220, 128, 216, 128, 25, 1, 212, 251, 222, 136, 25, 1, 212, 251, 217, 48, + 25, 1, 212, 251, 215, 225, 25, 1, 212, 251, 166, 25, 1, 212, 251, 224, + 68, 25, 1, 212, 251, 216, 249, 25, 1, 193, 217, 4, 220, 100, 25, 1, 193, + 215, 54, 25, 1, 193, 195, 195, 25, 1, 193, 197, 143, 25, 1, 193, 217, 41, + 25, 1, 193, 217, 148, 25, 1, 193, 217, 11, 25, 1, 193, 233, 219, 25, 1, + 193, 219, 232, 25, 1, 193, 234, 63, 25, 1, 193, 215, 79, 219, 4, 219, + 135, 25, 1, 193, 215, 192, 219, 223, 25, 1, 193, 219, 229, 25, 1, 193, + 212, 163, 25, 1, 193, 217, 133, 25, 1, 193, 219, 240, 247, 170, 25, 1, + 193, 224, 159, 25, 1, 193, 233, 220, 25, 1, 193, 224, 166, 25, 1, 193, + 195, 218, 218, 109, 25, 1, 193, 215, 48, 25, 1, 193, 219, 217, 25, 1, + 193, 215, 224, 25, 1, 193, 219, 223, 25, 1, 193, 196, 33, 25, 1, 193, + 223, 220, 25, 1, 193, 225, 55, 25, 1, 193, 207, 72, 25, 1, 193, 217, 142, + 25, 1, 193, 203, 156, 25, 1, 193, 216, 132, 25, 1, 193, 202, 56, 195, + 199, 25, 1, 193, 204, 159, 25, 1, 193, 217, 31, 215, 103, 25, 1, 193, + 199, 41, 25, 1, 193, 217, 215, 25, 1, 193, 220, 128, 224, 168, 25, 1, + 193, 215, 206, 25, 1, 193, 217, 26, 25, 1, 193, 222, 231, 25, 1, 193, + 219, 225, 25, 1, 193, 219, 112, 25, 1, 193, 215, 200, 25, 1, 193, 202, + 241, 25, 1, 193, 217, 28, 25, 1, 193, 234, 221, 25, 1, 193, 217, 147, 25, + 1, 193, 215, 226, 25, 1, 193, 215, 222, 25, 1, 193, 247, 253, 25, 1, 193, + 199, 43, 25, 1, 193, 219, 230, 25, 1, 193, 209, 140, 25, 1, 193, 216, + 162, 25, 1, 193, 222, 249, 25, 1, 193, 202, 53, 25, 1, 193, 215, 208, + 216, 249, 25, 1, 193, 216, 154, 25, 1, 193, 224, 172, 25, 1, 193, 217, + 33, 25, 1, 193, 220, 93, 25, 1, 193, 219, 218, 25, 1, 193, 221, 191, 25, + 1, 193, 223, 145, 25, 1, 193, 216, 160, 25, 1, 193, 216, 249, 25, 1, 193, + 196, 231, 25, 1, 193, 217, 29, 25, 1, 193, 215, 211, 25, 1, 193, 215, + 202, 25, 1, 193, 223, 161, 216, 117, 25, 1, 193, 215, 209, 25, 1, 193, + 217, 155, 25, 1, 193, 220, 128, 215, 214, 25, 1, 193, 196, 129, 25, 1, + 193, 217, 154, 25, 1, 193, 206, 145, 25, 1, 193, 207, 75, 25, 1, 193, + 219, 226, 25, 1, 193, 220, 100, 25, 1, 193, 219, 236, 25, 1, 193, 224, + 160, 25, 1, 193, 219, 227, 25, 1, 193, 224, 164, 25, 1, 193, 219, 240, + 212, 215, 25, 1, 193, 195, 178, 25, 1, 193, 216, 150, 25, 1, 193, 219, + 59, 25, 1, 193, 218, 139, 25, 1, 193, 206, 206, 25, 1, 193, 224, 183, + 222, 209, 25, 1, 193, 224, 183, 235, 195, 25, 1, 193, 217, 63, 25, 1, + 193, 217, 212, 25, 1, 193, 222, 57, 25, 1, 193, 212, 176, 25, 1, 193, + 213, 65, 25, 1, 193, 203, 1, 25, 1, 148, 219, 216, 25, 1, 148, 197, 141, + 25, 1, 148, 216, 148, 25, 1, 148, 219, 120, 25, 1, 148, 216, 146, 25, 1, + 148, 222, 102, 25, 1, 148, 216, 151, 25, 1, 148, 215, 221, 25, 1, 148, + 217, 47, 25, 1, 148, 215, 103, 25, 1, 148, 196, 242, 25, 1, 148, 217, 1, + 25, 1, 148, 206, 253, 25, 1, 148, 217, 12, 25, 1, 148, 224, 167, 25, 1, + 148, 202, 243, 25, 1, 148, 206, 232, 25, 1, 148, 216, 159, 25, 1, 148, + 204, 127, 25, 1, 148, 224, 172, 25, 1, 148, 196, 117, 25, 1, 148, 223, + 162, 25, 1, 148, 208, 207, 25, 1, 148, 219, 125, 25, 1, 148, 217, 146, + 25, 1, 148, 220, 65, 25, 1, 148, 219, 131, 25, 1, 148, 207, 74, 25, 1, + 148, 196, 59, 25, 1, 148, 216, 153, 25, 1, 148, 224, 163, 219, 219, 25, + 1, 148, 217, 8, 25, 1, 148, 201, 40, 25, 1, 148, 233, 229, 25, 1, 148, + 216, 254, 25, 1, 148, 235, 159, 25, 1, 148, 217, 150, 25, 1, 148, 219, + 104, 25, 1, 148, 222, 130, 25, 1, 148, 217, 132, 25, 1, 148, 218, 211, + 25, 1, 148, 219, 108, 25, 1, 148, 211, 190, 25, 1, 148, 219, 106, 25, 1, + 148, 219, 122, 25, 1, 148, 221, 174, 25, 1, 148, 215, 213, 25, 1, 148, + 219, 239, 25, 1, 148, 223, 134, 25, 1, 148, 215, 92, 25, 1, 148, 202, + 246, 25, 1, 148, 205, 165, 25, 1, 148, 195, 178, 25, 1, 148, 224, 164, + 25, 1, 148, 210, 228, 25, 1, 148, 203, 47, 25, 1, 148, 217, 9, 25, 1, + 148, 219, 127, 25, 1, 148, 215, 212, 25, 1, 148, 224, 162, 25, 1, 148, + 212, 169, 25, 1, 148, 213, 11, 25, 1, 148, 215, 65, 25, 1, 148, 222, 136, + 25, 1, 148, 217, 48, 25, 1, 148, 219, 124, 25, 1, 148, 217, 21, 25, 1, + 148, 195, 192, 25, 1, 148, 213, 163, 25, 1, 148, 195, 191, 25, 1, 148, + 217, 155, 25, 1, 148, 215, 201, 25, 1, 148, 204, 161, 25, 1, 148, 223, + 166, 25, 1, 148, 217, 37, 25, 1, 148, 217, 6, 25, 1, 148, 201, 15, 25, 1, + 148, 219, 135, 25, 1, 148, 223, 156, 25, 1, 148, 215, 210, 25, 1, 148, + 202, 244, 25, 1, 148, 220, 95, 25, 1, 148, 217, 46, 25, 1, 148, 222, 129, + 25, 1, 148, 217, 27, 25, 1, 148, 215, 215, 25, 1, 148, 216, 132, 25, 1, + 148, 233, 213, 25, 1, 148, 223, 187, 25, 1, 148, 210, 127, 214, 133, 25, + 1, 148, 203, 145, 25, 1, 148, 201, 239, 25, 1, 148, 215, 89, 25, 1, 148, + 210, 9, 25, 1, 148, 222, 187, 25, 1, 148, 219, 187, 25, 1, 148, 221, 136, + 25, 1, 148, 204, 74, 25, 1, 148, 218, 145, 25, 1, 148, 206, 218, 25, 1, + 148, 206, 228, 25, 1, 148, 223, 106, 25, 1, 148, 215, 186, 25, 1, 148, + 206, 151, 25, 1, 148, 215, 203, 25, 1, 148, 213, 79, 25, 1, 148, 216, + 223, 25, 1, 148, 206, 183, 25, 1, 148, 211, 205, 25, 1, 148, 218, 76, 25, + 1, 148, 221, 221, 25, 1, 148, 210, 127, 218, 134, 25, 1, 148, 202, 122, + 25, 1, 148, 215, 189, 25, 1, 148, 219, 240, 178, 25, 1, 148, 208, 205, + 25, 1, 148, 235, 238, 25, 1, 104, 217, 154, 25, 1, 104, 201, 245, 25, 1, + 104, 219, 229, 25, 1, 104, 222, 231, 25, 1, 104, 198, 235, 25, 1, 104, + 221, 227, 25, 1, 104, 213, 243, 25, 1, 104, 205, 176, 25, 1, 104, 210, + 202, 25, 1, 104, 215, 217, 25, 1, 104, 217, 125, 25, 1, 104, 211, 223, + 25, 1, 104, 203, 117, 25, 1, 104, 217, 14, 25, 1, 104, 223, 216, 25, 1, + 104, 196, 234, 25, 1, 104, 208, 129, 25, 1, 104, 217, 38, 25, 1, 104, + 213, 240, 25, 1, 104, 201, 247, 25, 1, 104, 223, 160, 25, 1, 104, 221, + 242, 25, 1, 104, 215, 220, 25, 1, 104, 216, 246, 25, 1, 104, 220, 101, + 25, 1, 104, 217, 7, 25, 1, 104, 216, 245, 25, 1, 104, 215, 219, 25, 1, + 104, 210, 6, 25, 1, 104, 216, 150, 25, 1, 104, 213, 77, 25, 1, 104, 209, + 13, 25, 1, 104, 217, 22, 25, 1, 104, 219, 114, 25, 1, 104, 233, 207, 25, + 1, 104, 217, 10, 25, 1, 104, 216, 161, 25, 1, 104, 220, 43, 25, 1, 104, + 221, 223, 25, 1, 104, 217, 43, 25, 1, 104, 217, 138, 25, 1, 104, 203, + 144, 215, 201, 25, 1, 104, 207, 76, 25, 1, 104, 211, 216, 25, 1, 104, + 217, 158, 205, 184, 25, 1, 104, 217, 30, 215, 103, 25, 1, 104, 196, 20, + 25, 1, 104, 233, 208, 25, 1, 104, 201, 34, 25, 1, 104, 196, 36, 25, 1, + 104, 212, 117, 25, 1, 104, 201, 21, 25, 1, 104, 224, 170, 25, 1, 104, + 204, 160, 25, 1, 104, 202, 245, 25, 1, 104, 199, 44, 25, 1, 104, 197, 84, + 25, 1, 104, 223, 80, 25, 1, 104, 211, 227, 25, 1, 104, 203, 157, 25, 1, + 104, 233, 228, 25, 1, 104, 217, 53, 25, 1, 104, 206, 231, 25, 1, 104, + 219, 109, 25, 1, 104, 219, 233, 25, 1, 104, 215, 52, 25, 1, 104, 216, + 113, 25, 1, 104, 234, 59, 25, 1, 104, 201, 22, 25, 1, 104, 223, 170, 25, + 1, 104, 196, 93, 25, 1, 104, 215, 90, 244, 220, 25, 1, 104, 196, 9, 25, + 1, 104, 219, 126, 25, 1, 104, 217, 143, 25, 1, 104, 212, 211, 25, 1, 104, + 195, 198, 25, 1, 104, 222, 131, 25, 1, 104, 234, 221, 25, 1, 104, 234, + 58, 25, 1, 104, 217, 0, 25, 1, 104, 224, 172, 25, 1, 104, 220, 104, 25, + 1, 104, 217, 13, 25, 1, 104, 233, 214, 25, 1, 104, 235, 239, 25, 1, 104, + 215, 190, 25, 1, 104, 213, 12, 25, 1, 104, 196, 34, 25, 1, 104, 217, 39, + 25, 1, 104, 215, 90, 248, 203, 25, 1, 104, 215, 32, 25, 1, 104, 212, 89, + 25, 1, 104, 219, 59, 25, 1, 104, 234, 219, 25, 1, 104, 217, 238, 25, 1, + 104, 218, 139, 25, 1, 104, 233, 213, 25, 1, 104, 234, 224, 68, 25, 1, + 104, 218, 77, 25, 1, 104, 211, 222, 25, 1, 104, 217, 2, 25, 1, 104, 223, + 145, 25, 1, 104, 212, 208, 25, 1, 104, 215, 204, 25, 1, 104, 196, 35, 25, + 1, 104, 217, 23, 25, 1, 104, 213, 244, 213, 51, 25, 1, 104, 234, 224, + 247, 152, 25, 1, 104, 235, 44, 25, 1, 104, 216, 155, 25, 1, 104, 63, 25, + 1, 104, 201, 239, 25, 1, 104, 72, 25, 1, 104, 68, 25, 1, 104, 222, 229, + 25, 1, 104, 213, 244, 212, 126, 25, 1, 104, 203, 162, 25, 1, 104, 203, + 102, 25, 1, 104, 217, 158, 218, 64, 231, 87, 25, 1, 104, 206, 206, 25, 1, + 104, 196, 31, 25, 1, 104, 216, 239, 25, 1, 104, 195, 203, 25, 1, 104, + 195, 235, 204, 53, 25, 1, 104, 195, 235, 241, 86, 25, 1, 104, 195, 186, + 25, 1, 104, 195, 194, 25, 1, 104, 224, 158, 25, 1, 104, 213, 10, 25, 1, + 104, 216, 156, 236, 176, 25, 1, 104, 211, 218, 25, 1, 104, 196, 240, 25, + 1, 104, 235, 182, 25, 1, 104, 199, 113, 25, 1, 104, 221, 191, 25, 1, 104, + 219, 78, 25, 1, 104, 210, 91, 25, 1, 104, 210, 229, 25, 1, 104, 216, 238, + 25, 1, 104, 217, 71, 25, 1, 104, 206, 198, 25, 1, 104, 206, 183, 25, 1, + 104, 234, 224, 210, 130, 25, 1, 104, 176, 25, 1, 104, 212, 220, 25, 1, + 104, 221, 221, 25, 1, 104, 224, 11, 25, 1, 104, 219, 164, 25, 1, 104, + 166, 25, 1, 104, 220, 40, 25, 1, 104, 202, 247, 25, 1, 104, 224, 101, 25, + 1, 104, 218, 215, 25, 1, 104, 203, 23, 25, 1, 104, 235, 206, 25, 1, 104, + 233, 201, 25, 1, 212, 250, 155, 25, 1, 212, 250, 66, 25, 1, 212, 250, + 223, 187, 25, 1, 212, 250, 237, 54, 25, 1, 212, 250, 210, 155, 25, 1, + 212, 250, 203, 145, 25, 1, 212, 250, 215, 89, 25, 1, 212, 250, 172, 25, + 1, 212, 250, 210, 9, 25, 1, 212, 250, 210, 57, 25, 1, 212, 250, 219, 187, + 25, 1, 212, 250, 203, 162, 25, 1, 212, 250, 217, 157, 25, 1, 212, 250, + 216, 162, 25, 1, 212, 250, 221, 136, 25, 1, 212, 250, 204, 74, 25, 1, + 212, 250, 206, 218, 25, 1, 212, 250, 206, 112, 25, 1, 212, 250, 207, 72, + 25, 1, 212, 250, 223, 106, 25, 1, 212, 250, 224, 172, 25, 1, 212, 250, + 215, 154, 25, 1, 212, 250, 215, 186, 25, 1, 212, 250, 216, 133, 25, 1, + 212, 250, 195, 234, 25, 1, 212, 250, 206, 151, 25, 1, 212, 250, 164, 25, + 1, 212, 250, 215, 223, 25, 1, 212, 250, 213, 10, 25, 1, 212, 250, 215, + 203, 25, 1, 212, 250, 196, 240, 25, 1, 212, 250, 213, 79, 25, 1, 212, + 250, 209, 140, 25, 1, 212, 250, 216, 223, 25, 1, 212, 250, 210, 91, 25, + 1, 212, 250, 224, 182, 25, 1, 212, 250, 216, 255, 25, 1, 212, 250, 217, + 50, 25, 1, 212, 250, 206, 198, 25, 1, 212, 250, 211, 223, 25, 1, 212, + 250, 235, 44, 25, 1, 212, 250, 197, 166, 25, 1, 212, 250, 222, 109, 25, + 1, 212, 250, 221, 221, 25, 1, 212, 250, 224, 11, 25, 1, 212, 250, 219, + 231, 25, 1, 212, 250, 210, 126, 25, 1, 212, 250, 166, 25, 1, 212, 250, + 218, 251, 25, 1, 212, 250, 219, 239, 25, 1, 212, 250, 203, 1, 25, 1, 212, + 250, 223, 223, 25, 1, 212, 250, 208, 227, 25, 1, 212, 250, 197, 219, 218, + 149, 1, 189, 218, 149, 1, 217, 19, 218, 149, 1, 196, 3, 218, 149, 1, 219, + 25, 218, 149, 1, 249, 145, 218, 149, 1, 240, 136, 218, 149, 1, 63, 218, + 149, 1, 212, 246, 218, 149, 1, 224, 141, 218, 149, 1, 232, 178, 218, 149, + 1, 240, 111, 218, 149, 1, 245, 30, 218, 149, 1, 224, 202, 218, 149, 1, + 214, 134, 218, 149, 1, 220, 101, 218, 149, 1, 216, 183, 218, 149, 1, 161, + 218, 149, 1, 214, 102, 218, 149, 1, 72, 218, 149, 1, 209, 232, 218, 149, + 1, 206, 223, 218, 149, 1, 202, 216, 218, 149, 1, 237, 82, 218, 149, 1, + 197, 166, 218, 149, 1, 69, 218, 149, 1, 224, 11, 218, 149, 1, 222, 238, + 218, 149, 1, 172, 218, 149, 1, 232, 235, 218, 149, 1, 210, 72, 218, 149, + 1, 203, 37, 218, 149, 17, 195, 79, 218, 149, 17, 100, 218, 149, 17, 102, + 218, 149, 17, 134, 218, 149, 17, 136, 218, 149, 17, 146, 218, 149, 17, + 167, 218, 149, 17, 178, 218, 149, 17, 171, 218, 149, 17, 182, 218, 149, + 240, 88, 218, 149, 52, 240, 88, 249, 59, 199, 149, 1, 236, 211, 249, 59, + 199, 149, 1, 155, 249, 59, 199, 149, 1, 208, 147, 249, 59, 199, 149, 1, + 235, 239, 249, 59, 199, 149, 1, 219, 234, 249, 59, 199, 149, 1, 196, 21, + 249, 59, 199, 149, 1, 234, 108, 249, 59, 199, 149, 1, 239, 157, 249, 59, + 199, 149, 1, 223, 222, 249, 59, 199, 149, 1, 225, 129, 249, 59, 199, 149, + 1, 231, 42, 249, 59, 199, 149, 1, 197, 166, 249, 59, 199, 149, 1, 195, + 11, 249, 59, 199, 149, 1, 234, 52, 249, 59, 199, 149, 1, 239, 28, 249, + 59, 199, 149, 1, 247, 57, 249, 59, 199, 149, 1, 199, 238, 249, 59, 199, + 149, 1, 149, 249, 59, 199, 149, 1, 249, 145, 249, 59, 199, 149, 1, 197, + 220, 249, 59, 199, 149, 1, 196, 63, 249, 59, 199, 149, 1, 161, 249, 59, + 199, 149, 1, 197, 158, 249, 59, 199, 149, 1, 63, 249, 59, 199, 149, 1, + 72, 249, 59, 199, 149, 1, 214, 102, 249, 59, 199, 149, 1, 66, 249, 59, + 199, 149, 1, 237, 54, 249, 59, 199, 149, 1, 69, 249, 59, 199, 149, 1, 68, + 249, 59, 199, 149, 38, 130, 202, 11, 249, 59, 199, 149, 38, 126, 202, 11, + 249, 59, 199, 149, 38, 219, 65, 202, 11, 249, 59, 199, 149, 38, 221, 205, + 202, 11, 249, 59, 199, 149, 38, 232, 46, 202, 11, 249, 59, 199, 149, 234, + 217, 204, 226, 133, 86, 18, 224, 199, 133, 86, 18, 224, 195, 133, 86, 18, + 224, 90, 133, 86, 18, 224, 53, 133, 86, 18, 224, 227, 133, 86, 18, 224, + 224, 133, 86, 18, 223, 171, 133, 86, 18, 223, 142, 133, 86, 18, 224, 201, + 133, 86, 18, 224, 156, 133, 86, 18, 225, 30, 133, 86, 18, 225, 27, 133, + 86, 18, 223, 241, 133, 86, 18, 223, 238, 133, 86, 18, 224, 220, 133, 86, + 18, 224, 218, 133, 86, 18, 223, 173, 133, 86, 18, 223, 172, 133, 86, 18, + 224, 4, 133, 86, 18, 223, 227, 133, 86, 18, 224, 92, 133, 86, 18, 224, + 91, 133, 86, 18, 225, 45, 133, 86, 18, 224, 223, 133, 86, 18, 223, 132, + 133, 86, 18, 223, 123, 133, 86, 18, 225, 54, 133, 86, 18, 225, 46, 133, + 86, 108, 199, 124, 133, 86, 108, 215, 193, 133, 86, 108, 222, 215, 133, + 86, 108, 232, 158, 133, 86, 108, 216, 89, 133, 86, 108, 210, 193, 133, + 86, 108, 216, 116, 133, 86, 108, 211, 133, 133, 86, 108, 196, 80, 133, + 86, 108, 232, 22, 133, 86, 108, 219, 255, 133, 86, 108, 245, 107, 133, + 86, 108, 217, 162, 133, 86, 108, 231, 214, 133, 86, 108, 212, 134, 133, + 86, 108, 215, 199, 133, 86, 108, 217, 202, 133, 86, 108, 250, 150, 133, + 86, 108, 196, 204, 133, 86, 108, 247, 90, 133, 86, 117, 244, 255, 201, + 31, 133, 86, 117, 244, 255, 205, 200, 133, 86, 117, 244, 255, 224, 174, + 133, 86, 117, 244, 255, 224, 132, 133, 86, 117, 244, 255, 204, 158, 133, + 86, 117, 244, 255, 231, 172, 133, 86, 117, 244, 255, 203, 88, 133, 86, 2, + 198, 230, 202, 166, 133, 86, 2, 198, 230, 201, 102, 247, 48, 133, 86, 2, + 244, 255, 245, 96, 133, 86, 2, 198, 230, 202, 194, 133, 86, 2, 198, 230, + 235, 179, 133, 86, 2, 196, 160, 215, 187, 133, 86, 2, 196, 160, 210, 74, + 133, 86, 2, 196, 160, 201, 222, 133, 86, 2, 196, 160, 235, 220, 133, 86, + 2, 198, 230, 208, 123, 133, 86, 2, 219, 186, 204, 162, 133, 86, 2, 198, + 230, 215, 239, 133, 86, 2, 230, 206, 196, 100, 133, 86, 2, 196, 203, 133, + 86, 2, 244, 255, 201, 89, 209, 215, 133, 86, 17, 195, 79, 133, 86, 17, + 100, 133, 86, 17, 102, 133, 86, 17, 134, 133, 86, 17, 136, 133, 86, 17, + 146, 133, 86, 17, 167, 133, 86, 17, 178, 133, 86, 17, 171, 133, 86, 17, + 182, 133, 86, 31, 203, 18, 133, 86, 31, 231, 55, 133, 86, 31, 203, 24, + 202, 157, 133, 86, 31, 219, 26, 133, 86, 31, 231, 58, 219, 26, 133, 86, + 31, 203, 24, 248, 165, 133, 86, 31, 201, 167, 133, 86, 2, 198, 230, 221, + 186, 133, 86, 2, 196, 157, 133, 86, 2, 232, 17, 133, 86, 2, 202, 183, + 232, 17, 133, 86, 2, 194, 240, 202, 227, 133, 86, 2, 231, 198, 133, 86, + 2, 215, 253, 133, 86, 2, 196, 195, 133, 86, 2, 215, 191, 133, 86, 2, 250, + 133, 133, 86, 2, 200, 209, 247, 47, 133, 86, 2, 219, 186, 201, 105, 133, + 86, 2, 203, 89, 133, 86, 2, 221, 218, 133, 86, 2, 218, 95, 133, 86, 2, + 244, 255, 232, 231, 221, 164, 215, 197, 215, 196, 133, 86, 2, 244, 255, + 241, 40, 201, 96, 133, 86, 2, 244, 255, 200, 207, 133, 86, 2, 244, 255, + 200, 208, 245, 18, 133, 86, 2, 244, 255, 211, 221, 240, 56, 133, 86, 2, + 244, 255, 215, 246, 201, 230, 133, 86, 244, 227, 2, 201, 100, 133, 86, + 244, 227, 2, 196, 65, 133, 86, 244, 227, 2, 222, 54, 133, 86, 244, 227, + 2, 222, 213, 133, 86, 244, 227, 2, 196, 156, 133, 86, 244, 227, 2, 223, + 242, 133, 86, 244, 227, 2, 232, 155, 133, 86, 244, 227, 2, 218, 137, 133, + 86, 244, 227, 2, 202, 167, 133, 86, 244, 227, 2, 201, 110, 133, 86, 244, + 227, 2, 213, 3, 133, 86, 244, 227, 2, 224, 144, 133, 86, 244, 227, 2, + 232, 219, 133, 86, 244, 227, 2, 199, 146, 133, 86, 244, 227, 2, 235, 216, + 133, 86, 244, 227, 2, 196, 107, 133, 86, 244, 227, 2, 201, 83, 133, 86, + 244, 227, 2, 223, 127, 133, 86, 244, 227, 2, 197, 208, 219, 195, 6, 1, + 221, 136, 219, 195, 6, 1, 209, 80, 219, 195, 6, 1, 199, 230, 219, 195, 6, + 1, 197, 199, 219, 195, 6, 1, 250, 162, 219, 195, 6, 1, 195, 158, 219, + 195, 6, 1, 223, 224, 219, 195, 6, 1, 214, 3, 219, 195, 6, 1, 203, 216, + 219, 195, 6, 1, 234, 190, 219, 195, 6, 1, 236, 49, 219, 195, 6, 1, 68, + 219, 195, 6, 1, 225, 80, 219, 195, 6, 1, 63, 219, 195, 6, 1, 225, 217, + 219, 195, 6, 1, 69, 219, 195, 6, 1, 250, 112, 219, 195, 6, 1, 247, 207, + 219, 195, 6, 1, 66, 219, 195, 6, 1, 195, 217, 219, 195, 6, 1, 159, 219, + 195, 6, 1, 211, 167, 219, 195, 6, 1, 231, 84, 219, 195, 6, 1, 215, 111, + 219, 195, 6, 1, 196, 222, 219, 195, 6, 1, 240, 231, 219, 195, 6, 1, 214, + 164, 219, 195, 6, 1, 218, 55, 219, 195, 6, 1, 144, 219, 195, 6, 1, 72, + 219, 195, 6, 1, 251, 200, 219, 195, 6, 1, 196, 148, 219, 195, 4, 1, 221, + 136, 219, 195, 4, 1, 209, 80, 219, 195, 4, 1, 199, 230, 219, 195, 4, 1, + 197, 199, 219, 195, 4, 1, 250, 162, 219, 195, 4, 1, 195, 158, 219, 195, + 4, 1, 223, 224, 219, 195, 4, 1, 214, 3, 219, 195, 4, 1, 203, 216, 219, + 195, 4, 1, 234, 190, 219, 195, 4, 1, 236, 49, 219, 195, 4, 1, 68, 219, + 195, 4, 1, 225, 80, 219, 195, 4, 1, 63, 219, 195, 4, 1, 225, 217, 219, + 195, 4, 1, 69, 219, 195, 4, 1, 250, 112, 219, 195, 4, 1, 247, 207, 219, + 195, 4, 1, 66, 219, 195, 4, 1, 195, 217, 219, 195, 4, 1, 159, 219, 195, + 4, 1, 211, 167, 219, 195, 4, 1, 231, 84, 219, 195, 4, 1, 215, 111, 219, + 195, 4, 1, 196, 222, 219, 195, 4, 1, 240, 231, 219, 195, 4, 1, 214, 164, + 219, 195, 4, 1, 218, 55, 219, 195, 4, 1, 144, 219, 195, 4, 1, 72, 219, + 195, 4, 1, 251, 200, 219, 195, 4, 1, 196, 148, 219, 195, 17, 195, 79, + 219, 195, 17, 100, 219, 195, 17, 102, 219, 195, 17, 134, 219, 195, 17, + 136, 219, 195, 17, 146, 219, 195, 17, 167, 219, 195, 17, 178, 219, 195, + 17, 171, 219, 195, 17, 182, 219, 195, 31, 203, 23, 219, 195, 31, 236, + 252, 219, 195, 31, 200, 239, 219, 195, 31, 202, 179, 219, 195, 31, 235, + 1, 219, 195, 31, 235, 149, 219, 195, 31, 206, 23, 219, 195, 31, 207, 68, + 219, 195, 31, 237, 28, 219, 195, 31, 216, 176, 219, 195, 17, 97, 251, + 131, 20, 219, 195, 17, 99, 251, 131, 20, 219, 195, 17, 115, 251, 131, 20, + 219, 195, 244, 159, 219, 195, 234, 217, 204, 226, 219, 195, 16, 251, 185, + 219, 195, 236, 90, 214, 149, 109, 1, 161, 109, 1, 249, 145, 109, 1, 11, + 161, 109, 1, 212, 150, 109, 1, 166, 109, 1, 219, 81, 109, 1, 250, 251, + 166, 109, 1, 235, 239, 109, 1, 199, 152, 109, 1, 199, 36, 109, 1, 189, + 109, 1, 240, 136, 109, 1, 11, 201, 78, 109, 1, 11, 189, 109, 1, 201, 78, + 109, 1, 240, 41, 109, 1, 176, 109, 1, 216, 227, 109, 1, 11, 216, 86, 109, + 1, 250, 251, 176, 109, 1, 216, 86, 109, 1, 216, 72, 109, 1, 172, 109, 1, + 221, 150, 109, 1, 222, 122, 109, 1, 222, 111, 109, 1, 202, 44, 109, 1, + 239, 37, 109, 1, 202, 36, 109, 1, 239, 36, 109, 1, 155, 109, 1, 234, 123, + 109, 1, 11, 155, 109, 1, 211, 159, 109, 1, 211, 136, 109, 1, 217, 71, + 109, 1, 217, 20, 109, 1, 250, 251, 217, 71, 109, 1, 142, 109, 1, 196, + 208, 109, 1, 233, 230, 109, 1, 233, 205, 109, 1, 201, 88, 109, 1, 237, + 139, 109, 1, 215, 109, 109, 1, 215, 91, 109, 1, 201, 103, 109, 1, 237, + 150, 109, 1, 11, 201, 103, 109, 1, 11, 237, 150, 109, 1, 210, 153, 201, + 103, 109, 1, 207, 50, 109, 1, 205, 80, 109, 1, 195, 74, 109, 1, 195, 1, + 109, 1, 201, 113, 109, 1, 237, 156, 109, 1, 11, 201, 113, 109, 1, 183, + 109, 1, 195, 115, 109, 1, 195, 2, 109, 1, 194, 228, 109, 1, 194, 208, + 109, 1, 250, 251, 194, 228, 109, 1, 194, 200, 109, 1, 194, 207, 109, 1, + 197, 166, 109, 1, 251, 209, 109, 1, 232, 80, 109, 1, 248, 43, 109, 1, + 204, 42, 109, 1, 237, 140, 109, 1, 203, 68, 109, 1, 201, 107, 109, 1, + 209, 143, 109, 2, 108, 73, 154, 109, 1, 217, 207, 109, 2, 250, 185, 109, + 2, 210, 153, 198, 242, 109, 2, 210, 153, 250, 185, 109, 18, 2, 63, 109, + 18, 2, 252, 168, 109, 18, 2, 251, 205, 109, 18, 2, 251, 106, 109, 18, 2, + 251, 97, 109, 18, 2, 72, 109, 18, 2, 214, 102, 109, 18, 2, 197, 34, 109, + 18, 2, 197, 199, 109, 18, 2, 69, 109, 18, 2, 236, 230, 109, 18, 2, 236, + 215, 109, 18, 2, 214, 160, 109, 18, 2, 68, 109, 18, 2, 230, 210, 109, 18, + 2, 230, 209, 109, 18, 2, 230, 208, 109, 18, 2, 226, 12, 109, 18, 2, 226, + 147, 109, 18, 2, 226, 120, 109, 18, 2, 225, 230, 109, 18, 2, 226, 60, + 109, 18, 2, 66, 109, 18, 2, 200, 114, 109, 18, 2, 200, 113, 109, 18, 2, + 200, 112, 109, 18, 2, 199, 245, 109, 18, 2, 200, 96, 109, 18, 2, 200, 56, + 109, 18, 2, 196, 148, 109, 18, 2, 196, 24, 109, 18, 2, 251, 245, 109, 18, + 2, 251, 241, 109, 18, 2, 236, 155, 109, 18, 2, 209, 185, 236, 155, 109, + 18, 2, 236, 163, 109, 18, 2, 209, 185, 236, 163, 109, 18, 2, 251, 200, + 109, 18, 2, 237, 33, 109, 18, 2, 250, 150, 109, 18, 2, 214, 39, 109, 18, + 2, 218, 55, 109, 18, 2, 217, 73, 109, 18, 2, 200, 40, 109, 18, 2, 195, + 197, 109, 18, 2, 214, 154, 109, 18, 2, 214, 161, 109, 18, 2, 197, 210, + 109, 18, 2, 226, 125, 109, 18, 2, 237, 82, 109, 18, 2, 226, 10, 109, 18, + 2, 200, 90, 109, 152, 210, 22, 109, 152, 201, 243, 210, 22, 109, 152, 57, + 109, 152, 60, 109, 1, 202, 9, 109, 1, 202, 8, 109, 1, 202, 7, 109, 1, + 202, 6, 109, 1, 202, 5, 109, 1, 202, 4, 109, 1, 202, 3, 109, 1, 210, 153, + 202, 10, 109, 1, 210, 153, 202, 9, 109, 1, 210, 153, 202, 7, 109, 1, 210, + 153, 202, 6, 109, 1, 210, 153, 202, 5, 109, 1, 210, 153, 202, 3, 19, 225, + 232, 78, 43, 225, 232, 78, 37, 245, 61, 231, 165, 78, 37, 245, 61, 225, + 232, 78, 19, 244, 148, 19, 244, 147, 19, 244, 146, 19, 244, 145, 19, 244, + 144, 19, 244, 143, 19, 244, 142, 19, 244, 141, 19, 244, 140, 19, 244, + 139, 19, 244, 138, 19, 244, 137, 19, 244, 136, 19, 244, 135, 19, 244, + 134, 19, 244, 133, 19, 244, 132, 19, 244, 131, 19, 244, 130, 19, 244, + 129, 19, 244, 128, 19, 244, 127, 19, 244, 126, 19, 244, 125, 19, 244, + 124, 19, 244, 123, 19, 244, 122, 19, 244, 121, 19, 244, 120, 19, 244, + 119, 19, 244, 118, 19, 244, 117, 19, 244, 116, 19, 244, 115, 19, 244, + 114, 19, 244, 113, 19, 244, 112, 19, 244, 111, 19, 244, 110, 19, 244, + 109, 19, 244, 108, 19, 244, 107, 19, 244, 106, 19, 244, 105, 19, 244, + 104, 19, 244, 103, 19, 244, 102, 19, 244, 101, 19, 244, 100, 19, 244, 99, + 19, 244, 98, 19, 244, 97, 19, 244, 96, 19, 244, 95, 19, 244, 94, 19, 244, + 93, 19, 244, 92, 19, 244, 91, 19, 244, 90, 19, 244, 89, 19, 244, 88, 19, + 244, 87, 19, 244, 86, 19, 244, 85, 19, 244, 84, 19, 244, 83, 19, 244, 82, + 19, 244, 81, 19, 244, 80, 19, 244, 79, 19, 244, 78, 19, 244, 77, 19, 244, + 76, 19, 244, 75, 19, 244, 74, 19, 244, 73, 19, 244, 72, 19, 244, 71, 19, + 244, 70, 19, 244, 69, 19, 244, 68, 19, 244, 67, 19, 244, 66, 19, 244, 65, + 19, 244, 64, 19, 244, 63, 19, 244, 62, 19, 244, 61, 19, 244, 60, 19, 244, + 59, 19, 244, 58, 19, 244, 57, 19, 244, 56, 19, 244, 55, 19, 244, 54, 19, + 244, 53, 19, 244, 52, 19, 244, 51, 19, 244, 50, 19, 244, 49, 19, 244, 48, + 19, 244, 47, 19, 244, 46, 19, 244, 45, 19, 244, 44, 19, 244, 43, 19, 244, + 42, 19, 244, 41, 19, 244, 40, 19, 244, 39, 19, 244, 38, 19, 244, 37, 19, + 244, 36, 19, 244, 35, 19, 244, 34, 19, 244, 33, 19, 244, 32, 19, 244, 31, + 19, 244, 30, 19, 244, 29, 19, 244, 28, 19, 244, 27, 19, 244, 26, 19, 244, + 25, 19, 244, 24, 19, 244, 23, 19, 244, 22, 19, 244, 21, 19, 244, 20, 19, + 244, 19, 19, 244, 18, 19, 244, 17, 19, 244, 16, 19, 244, 15, 19, 244, 14, + 19, 244, 13, 19, 244, 12, 19, 244, 11, 19, 244, 10, 19, 244, 9, 19, 244, + 8, 19, 244, 7, 19, 244, 6, 19, 244, 5, 19, 244, 4, 19, 244, 3, 19, 244, + 2, 19, 244, 1, 19, 244, 0, 19, 243, 255, 19, 243, 254, 19, 243, 253, 19, + 243, 252, 19, 243, 251, 19, 243, 250, 19, 243, 249, 19, 243, 248, 19, + 243, 247, 19, 243, 246, 19, 243, 245, 19, 243, 244, 19, 243, 243, 19, + 243, 242, 19, 243, 241, 19, 243, 240, 19, 243, 239, 19, 243, 238, 19, + 243, 237, 19, 243, 236, 19, 243, 235, 19, 243, 234, 19, 243, 233, 19, + 243, 232, 19, 243, 231, 19, 243, 230, 19, 243, 229, 19, 243, 228, 19, + 243, 227, 19, 243, 226, 19, 243, 225, 19, 243, 224, 19, 243, 223, 19, + 243, 222, 19, 243, 221, 19, 243, 220, 19, 243, 219, 19, 243, 218, 19, + 243, 217, 19, 243, 216, 19, 243, 215, 19, 243, 214, 19, 243, 213, 19, + 243, 212, 19, 243, 211, 19, 243, 210, 19, 243, 209, 19, 243, 208, 19, + 243, 207, 19, 243, 206, 19, 243, 205, 19, 243, 204, 19, 243, 203, 19, + 243, 202, 19, 243, 201, 19, 243, 200, 19, 243, 199, 19, 243, 198, 19, + 243, 197, 19, 243, 196, 19, 243, 195, 19, 243, 194, 19, 243, 193, 19, + 243, 192, 19, 243, 191, 19, 243, 190, 19, 243, 189, 19, 243, 188, 19, + 243, 187, 19, 243, 186, 19, 243, 185, 19, 243, 184, 19, 243, 183, 19, + 243, 182, 19, 243, 181, 19, 243, 180, 19, 243, 179, 19, 243, 178, 19, + 243, 177, 19, 243, 176, 19, 243, 175, 19, 243, 174, 19, 243, 173, 19, + 243, 172, 19, 243, 171, 19, 243, 170, 19, 243, 169, 19, 243, 168, 19, + 243, 167, 19, 243, 166, 19, 243, 165, 19, 243, 164, 19, 243, 163, 19, + 243, 162, 19, 243, 161, 19, 243, 160, 19, 243, 159, 19, 243, 158, 19, + 243, 157, 19, 243, 156, 19, 243, 155, 19, 243, 154, 19, 243, 153, 19, + 243, 152, 19, 243, 151, 19, 243, 150, 19, 243, 149, 19, 243, 148, 19, + 243, 147, 19, 243, 146, 19, 243, 145, 19, 243, 144, 19, 243, 143, 19, + 243, 142, 19, 243, 141, 19, 243, 140, 19, 243, 139, 19, 243, 138, 19, + 243, 137, 19, 243, 136, 19, 243, 135, 19, 243, 134, 19, 243, 133, 19, + 243, 132, 19, 243, 131, 19, 243, 130, 19, 243, 129, 19, 243, 128, 19, + 243, 127, 19, 243, 126, 19, 243, 125, 19, 243, 124, 19, 243, 123, 19, + 243, 122, 19, 243, 121, 19, 243, 120, 19, 243, 119, 19, 243, 118, 19, + 243, 117, 19, 243, 116, 19, 243, 115, 19, 243, 114, 19, 243, 113, 19, + 243, 112, 19, 243, 111, 19, 243, 110, 19, 243, 109, 19, 243, 108, 19, + 243, 107, 19, 243, 106, 19, 243, 105, 19, 243, 104, 19, 243, 103, 19, + 243, 102, 19, 243, 101, 19, 243, 100, 19, 243, 99, 19, 243, 98, 19, 243, + 97, 19, 243, 96, 19, 243, 95, 19, 243, 94, 19, 243, 93, 19, 243, 92, 19, + 243, 91, 19, 243, 90, 19, 243, 89, 19, 243, 88, 19, 243, 87, 19, 243, 86, + 19, 243, 85, 19, 243, 84, 19, 243, 83, 19, 243, 82, 19, 243, 81, 19, 243, + 80, 19, 243, 79, 19, 243, 78, 19, 243, 77, 19, 243, 76, 19, 243, 75, 19, + 243, 74, 19, 243, 73, 19, 243, 72, 19, 243, 71, 19, 243, 70, 19, 243, 69, + 19, 243, 68, 19, 243, 67, 19, 243, 66, 19, 243, 65, 19, 243, 64, 19, 243, + 63, 19, 243, 62, 19, 243, 61, 19, 243, 60, 19, 243, 59, 19, 243, 58, 19, + 243, 57, 19, 243, 56, 19, 243, 55, 19, 243, 54, 19, 243, 53, 19, 243, 52, + 19, 243, 51, 19, 243, 50, 19, 243, 49, 19, 243, 48, 19, 243, 47, 19, 243, + 46, 19, 243, 45, 19, 243, 44, 19, 243, 43, 19, 243, 42, 19, 243, 41, 19, + 243, 40, 19, 243, 39, 19, 243, 38, 19, 243, 37, 19, 243, 36, 19, 243, 35, + 19, 243, 34, 19, 243, 33, 19, 243, 32, 19, 243, 31, 19, 243, 30, 19, 243, + 29, 19, 243, 28, 19, 243, 27, 19, 243, 26, 19, 243, 25, 19, 243, 24, 19, + 243, 23, 19, 243, 22, 19, 243, 21, 19, 243, 20, 19, 243, 19, 19, 243, 18, + 19, 243, 17, 19, 243, 16, 19, 243, 15, 19, 243, 14, 19, 243, 13, 19, 243, + 12, 19, 243, 11, 19, 243, 10, 19, 243, 9, 19, 243, 8, 19, 243, 7, 19, + 243, 6, 19, 243, 5, 19, 243, 4, 19, 243, 3, 19, 243, 2, 19, 243, 1, 19, + 243, 0, 19, 242, 255, 19, 242, 254, 19, 242, 253, 19, 242, 252, 19, 242, + 251, 19, 242, 250, 19, 242, 249, 19, 242, 248, 19, 242, 247, 19, 242, + 246, 19, 242, 245, 19, 242, 244, 19, 242, 243, 19, 242, 242, 19, 242, + 241, 19, 242, 240, 19, 242, 239, 19, 242, 238, 19, 242, 237, 19, 242, + 236, 19, 242, 235, 19, 242, 234, 19, 242, 233, 19, 242, 232, 19, 242, + 231, 19, 242, 230, 19, 242, 229, 19, 242, 228, 19, 242, 227, 19, 242, + 226, 19, 242, 225, 19, 242, 224, 19, 242, 223, 19, 242, 222, 19, 242, + 221, 19, 242, 220, 19, 242, 219, 19, 242, 218, 19, 242, 217, 19, 242, + 216, 19, 242, 215, 19, 242, 214, 19, 242, 213, 19, 242, 212, 19, 242, + 211, 19, 242, 210, 19, 242, 209, 19, 242, 208, 19, 242, 207, 19, 242, + 206, 19, 242, 205, 19, 242, 204, 19, 242, 203, 19, 242, 202, 19, 242, + 201, 19, 242, 200, 19, 242, 199, 19, 242, 198, 19, 242, 197, 19, 242, + 196, 19, 242, 195, 19, 242, 194, 19, 242, 193, 19, 242, 192, 19, 242, + 191, 19, 242, 190, 19, 242, 189, 19, 242, 188, 19, 242, 187, 19, 242, + 186, 19, 242, 185, 19, 242, 184, 19, 242, 183, 19, 242, 182, 19, 242, + 181, 19, 242, 180, 19, 242, 179, 19, 242, 178, 19, 242, 177, 19, 242, + 176, 19, 242, 175, 19, 242, 174, 19, 242, 173, 19, 242, 172, 19, 242, + 171, 19, 242, 170, 19, 242, 169, 19, 242, 168, 19, 242, 167, 19, 242, + 166, 19, 242, 165, 19, 242, 164, 19, 242, 163, 19, 242, 162, 19, 242, + 161, 19, 242, 160, 19, 242, 159, 19, 242, 158, 19, 242, 157, 19, 242, + 156, 19, 242, 155, 19, 242, 154, 19, 242, 153, 19, 242, 152, 19, 242, + 151, 19, 242, 150, 19, 242, 149, 19, 242, 148, 19, 242, 147, 19, 242, + 146, 19, 242, 145, 19, 242, 144, 19, 242, 143, 19, 242, 142, 19, 242, + 141, 19, 242, 140, 19, 242, 139, 19, 242, 138, 19, 242, 137, 19, 242, + 136, 19, 242, 135, 19, 242, 134, 19, 242, 133, 19, 242, 132, 19, 242, + 131, 19, 242, 130, 19, 242, 129, 19, 242, 128, 19, 242, 127, 19, 242, + 126, 19, 242, 125, 19, 242, 124, 19, 242, 123, 19, 242, 122, 19, 242, + 121, 19, 242, 120, 19, 242, 119, 19, 242, 118, 19, 242, 117, 19, 242, + 116, 19, 242, 115, 19, 242, 114, 19, 242, 113, 19, 242, 112, 19, 242, + 111, 19, 242, 110, 19, 242, 109, 19, 242, 108, 19, 242, 107, 19, 242, + 106, 19, 242, 105, 19, 242, 104, 19, 242, 103, 19, 242, 102, 19, 242, + 101, 19, 242, 100, 19, 242, 99, 19, 242, 98, 19, 242, 97, 19, 242, 96, + 19, 242, 95, 19, 242, 94, 19, 242, 93, 19, 242, 92, 19, 242, 91, 19, 242, + 90, 19, 242, 89, 19, 242, 88, 19, 242, 87, 19, 242, 86, 19, 242, 85, 19, + 242, 84, 19, 242, 83, 19, 242, 82, 19, 242, 81, 19, 242, 80, 19, 242, 79, + 19, 242, 78, 19, 242, 77, 19, 242, 76, 19, 242, 75, 19, 242, 74, 19, 242, + 73, 19, 242, 72, 19, 242, 71, 19, 242, 70, 19, 242, 69, 19, 242, 68, 19, + 242, 67, 19, 242, 66, 19, 242, 65, 19, 242, 64, 19, 242, 63, 19, 242, 62, + 19, 242, 61, 19, 242, 60, 19, 242, 59, 19, 242, 58, 19, 242, 57, 19, 242, + 56, 19, 242, 55, 19, 242, 54, 19, 242, 53, 19, 242, 52, 19, 242, 51, 19, + 242, 50, 19, 242, 49, 19, 242, 48, 19, 242, 47, 19, 242, 46, 19, 242, 45, + 19, 242, 44, 19, 242, 43, 19, 242, 42, 19, 242, 41, 19, 242, 40, 19, 242, + 39, 19, 242, 38, 19, 242, 37, 19, 242, 36, 19, 242, 35, 19, 242, 34, 19, + 242, 33, 19, 242, 32, 19, 242, 31, 19, 242, 30, 19, 242, 29, 19, 242, 28, + 19, 242, 27, 19, 242, 26, 19, 242, 25, 19, 242, 24, 19, 242, 23, 19, 242, + 22, 19, 242, 21, 19, 242, 20, 19, 242, 19, 19, 242, 18, 19, 242, 17, 19, + 242, 16, 19, 242, 15, 19, 242, 14, 19, 242, 13, 19, 242, 12, 19, 242, 11, + 19, 242, 10, 19, 242, 9, 19, 242, 8, 19, 242, 7, 19, 242, 6, 19, 242, 5, + 19, 242, 4, 19, 242, 3, 19, 242, 2, 19, 242, 1, 19, 242, 0, 19, 241, 255, + 19, 241, 254, 19, 241, 253, 19, 241, 252, 19, 241, 251, 19, 241, 250, 19, + 241, 249, 19, 241, 248, 19, 241, 247, 19, 241, 246, 19, 241, 245, 19, + 241, 244, 19, 241, 243, 19, 241, 242, 19, 241, 241, 19, 241, 240, 19, + 241, 239, 19, 241, 238, 19, 241, 237, 19, 241, 236, 19, 241, 235, 19, + 241, 234, 19, 241, 233, 19, 241, 232, 19, 241, 231, 19, 241, 230, 19, + 241, 229, 19, 241, 228, 19, 241, 227, 19, 241, 226, 19, 241, 225, 19, + 241, 224, 19, 241, 223, 19, 241, 222, 19, 241, 221, 19, 241, 220, 19, + 241, 219, 19, 241, 218, 19, 241, 217, 19, 241, 216, 19, 241, 215, 19, + 241, 214, 19, 241, 213, 19, 241, 212, 19, 241, 211, 19, 241, 210, 19, + 241, 209, 19, 241, 208, 19, 241, 207, 19, 241, 206, 19, 241, 205, 19, + 241, 204, 19, 241, 203, 19, 241, 202, 19, 241, 201, 19, 241, 200, 19, + 241, 199, 19, 241, 198, 19, 241, 197, 19, 241, 196, 19, 241, 195, 19, + 241, 194, 19, 241, 193, 19, 241, 192, 19, 241, 191, 19, 241, 190, 19, + 241, 189, 19, 241, 188, 19, 241, 187, 19, 241, 186, 19, 241, 185, 19, + 241, 184, 19, 241, 183, 19, 241, 182, 19, 241, 181, 19, 241, 180, 19, + 241, 179, 19, 241, 178, 19, 241, 177, 19, 241, 176, 19, 241, 175, 19, + 241, 174, 19, 241, 173, 19, 241, 172, 19, 241, 171, 19, 241, 170, 19, + 241, 169, 19, 241, 168, 19, 241, 167, 19, 241, 166, 19, 241, 165, 19, + 241, 164, 19, 241, 163, 19, 241, 162, 71, 1, 250, 251, 69, 188, 1, 250, + 251, 196, 69, 56, 1, 255, 168, 56, 1, 255, 167, 56, 1, 255, 166, 56, 1, + 255, 162, 56, 1, 230, 248, 56, 1, 230, 247, 56, 1, 230, 246, 56, 1, 230, + 245, 56, 1, 200, 177, 56, 1, 200, 176, 56, 1, 200, 175, 56, 1, 200, 174, + 56, 1, 200, 173, 56, 1, 237, 134, 56, 1, 237, 133, 56, 1, 237, 132, 56, + 1, 237, 131, 56, 1, 237, 130, 56, 1, 215, 22, 56, 1, 215, 21, 56, 1, 215, + 20, 56, 1, 225, 69, 56, 1, 225, 66, 56, 1, 225, 65, 56, 1, 225, 64, 56, + 1, 225, 63, 56, 1, 225, 62, 56, 1, 225, 61, 56, 1, 225, 60, 56, 1, 225, + 59, 56, 1, 225, 68, 56, 1, 225, 67, 56, 1, 225, 58, 56, 1, 224, 100, 56, + 1, 224, 99, 56, 1, 224, 98, 56, 1, 224, 97, 56, 1, 224, 96, 56, 1, 224, + 95, 56, 1, 224, 94, 56, 1, 224, 93, 56, 1, 223, 186, 56, 1, 223, 185, 56, + 1, 223, 184, 56, 1, 223, 183, 56, 1, 223, 182, 56, 1, 223, 181, 56, 1, + 223, 180, 56, 1, 224, 208, 56, 1, 224, 207, 56, 1, 224, 206, 56, 1, 224, + 205, 56, 1, 224, 204, 56, 1, 224, 203, 56, 1, 224, 10, 56, 1, 224, 9, 56, + 1, 224, 8, 56, 1, 224, 7, 56, 1, 209, 22, 56, 1, 209, 21, 56, 1, 209, 20, + 56, 1, 209, 19, 56, 1, 209, 18, 56, 1, 209, 17, 56, 1, 209, 16, 56, 1, + 209, 15, 56, 1, 206, 111, 56, 1, 206, 110, 56, 1, 206, 109, 56, 1, 206, + 108, 56, 1, 206, 107, 56, 1, 206, 106, 56, 1, 204, 171, 56, 1, 204, 170, + 56, 1, 204, 169, 56, 1, 204, 168, 56, 1, 204, 167, 56, 1, 204, 166, 56, + 1, 204, 165, 56, 1, 204, 164, 56, 1, 208, 146, 56, 1, 208, 145, 56, 1, + 208, 144, 56, 1, 208, 143, 56, 1, 208, 142, 56, 1, 205, 199, 56, 1, 205, + 198, 56, 1, 205, 197, 56, 1, 205, 196, 56, 1, 205, 195, 56, 1, 205, 194, + 56, 1, 205, 193, 56, 1, 203, 168, 56, 1, 203, 167, 56, 1, 203, 166, 56, + 1, 203, 165, 56, 1, 202, 121, 56, 1, 202, 120, 56, 1, 202, 119, 56, 1, + 202, 118, 56, 1, 202, 117, 56, 1, 202, 116, 56, 1, 202, 115, 56, 1, 201, + 39, 56, 1, 201, 38, 56, 1, 201, 37, 56, 1, 201, 36, 56, 1, 201, 35, 56, + 1, 203, 67, 56, 1, 203, 66, 56, 1, 203, 65, 56, 1, 203, 64, 56, 1, 203, + 63, 56, 1, 203, 62, 56, 1, 203, 61, 56, 1, 203, 60, 56, 1, 203, 59, 56, + 1, 202, 29, 56, 1, 202, 28, 56, 1, 202, 27, 56, 1, 202, 26, 56, 1, 202, + 25, 56, 1, 202, 24, 56, 1, 202, 23, 56, 1, 218, 0, 56, 1, 217, 255, 56, + 1, 217, 254, 56, 1, 217, 253, 56, 1, 217, 252, 56, 1, 217, 251, 56, 1, + 217, 250, 56, 1, 217, 249, 56, 1, 217, 248, 56, 1, 216, 222, 56, 1, 216, + 221, 56, 1, 216, 220, 56, 1, 216, 219, 56, 1, 216, 218, 56, 1, 216, 217, + 56, 1, 216, 216, 56, 1, 216, 215, 56, 1, 215, 185, 56, 1, 215, 184, 56, + 1, 215, 183, 56, 1, 217, 117, 56, 1, 217, 116, 56, 1, 217, 115, 56, 1, + 217, 114, 56, 1, 217, 113, 56, 1, 217, 112, 56, 1, 217, 111, 56, 1, 216, + 49, 56, 1, 216, 48, 56, 1, 216, 47, 56, 1, 216, 46, 56, 1, 216, 45, 56, + 1, 233, 3, 56, 1, 233, 0, 56, 1, 232, 255, 56, 1, 232, 254, 56, 1, 232, + 253, 56, 1, 232, 252, 56, 1, 232, 251, 56, 1, 232, 250, 56, 1, 232, 249, + 56, 1, 233, 2, 56, 1, 233, 1, 56, 1, 232, 70, 56, 1, 232, 69, 56, 1, 232, + 68, 56, 1, 232, 67, 56, 1, 232, 66, 56, 1, 232, 65, 56, 1, 232, 64, 56, + 1, 231, 74, 56, 1, 231, 73, 56, 1, 231, 72, 56, 1, 232, 146, 56, 1, 232, + 145, 56, 1, 232, 144, 56, 1, 232, 143, 56, 1, 232, 142, 56, 1, 232, 141, + 56, 1, 232, 140, 56, 1, 231, 192, 56, 1, 231, 191, 56, 1, 231, 190, 56, + 1, 231, 189, 56, 1, 231, 188, 56, 1, 231, 187, 56, 1, 231, 186, 56, 1, + 231, 185, 56, 1, 220, 127, 56, 1, 220, 126, 56, 1, 220, 125, 56, 1, 220, + 124, 56, 1, 220, 123, 56, 1, 220, 122, 56, 1, 220, 121, 56, 1, 219, 77, + 56, 1, 219, 76, 56, 1, 219, 75, 56, 1, 219, 74, 56, 1, 219, 73, 56, 1, + 219, 72, 56, 1, 219, 71, 56, 1, 218, 144, 56, 1, 218, 143, 56, 1, 218, + 142, 56, 1, 218, 141, 56, 1, 219, 206, 56, 1, 219, 205, 56, 1, 219, 204, + 56, 1, 218, 250, 56, 1, 218, 249, 56, 1, 218, 248, 56, 1, 218, 247, 56, + 1, 218, 246, 56, 1, 218, 245, 56, 1, 196, 137, 56, 1, 196, 136, 56, 1, + 196, 135, 56, 1, 196, 134, 56, 1, 196, 133, 56, 1, 196, 130, 56, 1, 195, + 216, 56, 1, 195, 215, 56, 1, 195, 214, 56, 1, 195, 213, 56, 1, 196, 2, + 56, 1, 196, 1, 56, 1, 196, 0, 56, 1, 195, 255, 56, 1, 195, 254, 56, 1, + 195, 253, 56, 1, 210, 251, 56, 1, 210, 250, 56, 1, 210, 249, 56, 1, 210, + 248, 56, 1, 210, 71, 56, 1, 210, 70, 56, 1, 210, 69, 56, 1, 210, 68, 56, + 1, 210, 67, 56, 1, 210, 66, 56, 1, 210, 65, 56, 1, 209, 139, 56, 1, 209, + 138, 56, 1, 209, 137, 56, 1, 209, 136, 56, 1, 209, 135, 56, 1, 209, 134, + 56, 1, 210, 182, 56, 1, 210, 181, 56, 1, 210, 180, 56, 1, 210, 179, 56, + 1, 209, 231, 56, 1, 209, 230, 56, 1, 209, 229, 56, 1, 209, 228, 56, 1, + 209, 227, 56, 1, 209, 226, 56, 1, 197, 165, 56, 1, 197, 164, 56, 1, 197, + 163, 56, 1, 197, 162, 56, 1, 197, 161, 56, 1, 197, 69, 56, 1, 197, 68, + 56, 1, 197, 67, 56, 1, 197, 66, 56, 1, 197, 65, 56, 1, 197, 108, 56, 1, + 197, 107, 56, 1, 197, 106, 56, 1, 197, 105, 56, 1, 197, 33, 56, 1, 197, + 32, 56, 1, 197, 31, 56, 1, 197, 30, 56, 1, 197, 29, 56, 1, 197, 28, 56, + 1, 197, 27, 56, 1, 218, 52, 56, 1, 218, 51, 188, 1, 4, 197, 70, 188, 1, + 4, 197, 109, 188, 1, 4, 197, 34, 71, 1, 4, 197, 70, 71, 1, 4, 197, 109, + 71, 1, 4, 197, 34, 71, 1, 4, 218, 55, 43, 246, 254, 43, 246, 253, 43, + 246, 252, 43, 246, 251, 43, 246, 250, 43, 246, 249, 43, 246, 248, 43, + 246, 247, 43, 246, 246, 43, 246, 245, 43, 246, 244, 43, 246, 243, 43, + 246, 242, 43, 246, 241, 43, 246, 240, 43, 246, 239, 43, 246, 238, 43, + 246, 237, 43, 246, 236, 43, 246, 235, 43, 246, 234, 43, 246, 233, 43, + 246, 232, 43, 246, 231, 43, 246, 230, 43, 246, 229, 43, 246, 228, 43, + 246, 227, 43, 246, 226, 43, 246, 225, 43, 246, 224, 43, 246, 223, 43, + 246, 222, 43, 246, 221, 43, 246, 220, 43, 246, 219, 43, 246, 218, 43, + 246, 217, 43, 246, 216, 43, 246, 215, 43, 246, 214, 43, 246, 213, 43, + 246, 212, 43, 246, 211, 43, 246, 210, 43, 246, 209, 43, 246, 208, 43, + 246, 207, 43, 246, 206, 43, 246, 205, 43, 246, 204, 43, 246, 203, 43, + 246, 202, 43, 246, 201, 43, 246, 200, 43, 246, 199, 43, 246, 198, 43, + 246, 197, 43, 246, 196, 43, 246, 195, 43, 246, 194, 43, 246, 193, 43, + 246, 192, 43, 246, 191, 43, 246, 190, 43, 246, 189, 43, 246, 188, 43, + 246, 187, 43, 246, 186, 43, 246, 185, 43, 246, 184, 43, 246, 183, 43, + 246, 182, 43, 246, 181, 43, 246, 180, 43, 246, 179, 43, 246, 178, 43, + 246, 177, 43, 246, 176, 43, 246, 175, 43, 246, 174, 43, 246, 173, 43, + 246, 172, 43, 246, 171, 43, 246, 170, 43, 246, 169, 43, 246, 168, 43, + 246, 167, 43, 246, 166, 43, 246, 165, 43, 246, 164, 43, 246, 163, 43, + 246, 162, 43, 246, 161, 43, 246, 160, 43, 246, 159, 43, 246, 158, 43, + 246, 157, 43, 246, 156, 43, 246, 155, 43, 246, 154, 43, 246, 153, 43, + 246, 152, 43, 246, 151, 43, 246, 150, 43, 246, 149, 43, 246, 148, 43, + 246, 147, 43, 246, 146, 43, 246, 145, 43, 246, 144, 43, 246, 143, 43, + 246, 142, 43, 246, 141, 43, 246, 140, 43, 246, 139, 43, 246, 138, 43, + 246, 137, 43, 246, 136, 43, 246, 135, 43, 246, 134, 43, 246, 133, 43, + 246, 132, 43, 246, 131, 43, 246, 130, 43, 246, 129, 43, 246, 128, 43, + 246, 127, 43, 246, 126, 43, 246, 125, 43, 246, 124, 43, 246, 123, 43, + 246, 122, 43, 246, 121, 43, 246, 120, 43, 246, 119, 43, 246, 118, 43, + 246, 117, 43, 246, 116, 43, 246, 115, 43, 246, 114, 43, 246, 113, 43, + 246, 112, 43, 246, 111, 43, 246, 110, 43, 246, 109, 43, 246, 108, 43, + 246, 107, 43, 246, 106, 43, 246, 105, 43, 246, 104, 43, 246, 103, 43, + 246, 102, 43, 246, 101, 43, 246, 100, 43, 246, 99, 43, 246, 98, 43, 246, + 97, 43, 246, 96, 43, 246, 95, 43, 246, 94, 43, 246, 93, 43, 246, 92, 43, + 246, 91, 43, 246, 90, 43, 246, 89, 43, 246, 88, 43, 246, 87, 43, 246, 86, + 43, 246, 85, 43, 246, 84, 43, 246, 83, 43, 246, 82, 43, 246, 81, 43, 246, + 80, 43, 246, 79, 43, 246, 78, 43, 246, 77, 43, 246, 76, 43, 246, 75, 43, + 246, 74, 43, 246, 73, 43, 246, 72, 43, 246, 71, 43, 246, 70, 43, 246, 69, + 43, 246, 68, 43, 246, 67, 43, 246, 66, 43, 246, 65, 43, 246, 64, 43, 246, + 63, 43, 246, 62, 43, 246, 61, 43, 246, 60, 43, 246, 59, 43, 246, 58, 43, + 246, 57, 43, 246, 56, 43, 246, 55, 43, 246, 54, 43, 246, 53, 43, 246, 52, + 43, 246, 51, 43, 246, 50, 43, 246, 49, 43, 246, 48, 43, 246, 47, 43, 246, + 46, 43, 246, 45, 43, 246, 44, 43, 246, 43, 43, 246, 42, 43, 246, 41, 43, + 246, 40, 43, 246, 39, 43, 246, 38, 43, 246, 37, 43, 246, 36, 43, 246, 35, + 43, 246, 34, 43, 246, 33, 43, 246, 32, 43, 246, 31, 43, 246, 30, 43, 246, + 29, 43, 246, 28, 43, 246, 27, 43, 246, 26, 43, 246, 25, 43, 246, 24, 43, + 246, 23, 43, 246, 22, 43, 246, 21, 43, 246, 20, 43, 246, 19, 43, 246, 18, + 43, 246, 17, 43, 246, 16, 43, 246, 15, 43, 246, 14, 43, 246, 13, 43, 246, + 12, 43, 246, 11, 43, 246, 10, 43, 246, 9, 43, 246, 8, 43, 246, 7, 43, + 246, 6, 43, 246, 5, 43, 246, 4, 43, 246, 3, 43, 246, 2, 43, 246, 1, 43, + 246, 0, 43, 245, 255, 43, 245, 254, 43, 245, 253, 43, 245, 252, 43, 245, + 251, 43, 245, 250, 43, 245, 249, 43, 245, 248, 43, 245, 247, 43, 245, + 246, 43, 245, 245, 43, 245, 244, 43, 245, 243, 43, 245, 242, 43, 245, + 241, 43, 245, 240, 43, 245, 239, 43, 245, 238, 43, 245, 237, 43, 245, + 236, 43, 245, 235, 43, 245, 234, 43, 245, 233, 43, 245, 232, 43, 245, + 231, 43, 245, 230, 43, 245, 229, 43, 245, 228, 43, 245, 227, 43, 245, + 226, 43, 245, 225, 43, 245, 224, 43, 245, 223, 43, 245, 222, 43, 245, + 221, 43, 245, 220, 43, 245, 219, 43, 245, 218, 43, 245, 217, 43, 245, + 216, 43, 245, 215, 43, 245, 214, 43, 245, 213, 43, 245, 212, 43, 245, + 211, 43, 245, 210, 43, 245, 209, 43, 245, 208, 43, 245, 207, 43, 245, + 206, 43, 245, 205, 43, 245, 204, 43, 245, 203, 43, 245, 202, 43, 245, + 201, 43, 245, 200, 43, 245, 199, 43, 245, 198, 43, 245, 197, 43, 245, + 196, 43, 245, 195, 43, 245, 194, 43, 245, 193, 43, 245, 192, 43, 245, + 191, 43, 245, 190, 43, 245, 189, 43, 245, 188, 43, 245, 187, 43, 245, + 186, 43, 245, 185, 43, 245, 184, 43, 245, 183, 43, 245, 182, 43, 245, + 181, 43, 245, 180, 43, 245, 179, 43, 245, 178, 43, 245, 177, 43, 245, + 176, 43, 245, 175, 43, 245, 174, 43, 245, 173, 43, 245, 172, 43, 245, + 171, 43, 245, 170, 43, 245, 169, 43, 245, 168, 43, 245, 167, 43, 245, + 166, 43, 245, 165, 43, 245, 164, 43, 245, 163, 43, 245, 162, 43, 245, + 161, 43, 245, 160, 43, 245, 159, 43, 245, 158, 43, 245, 157, 43, 245, + 156, 43, 245, 155, 43, 245, 154, 43, 245, 153, 43, 245, 152, 43, 245, + 151, 43, 245, 150, 43, 245, 149, 43, 245, 148, 43, 245, 147, 43, 245, + 146, 43, 245, 145, 43, 245, 144, 43, 245, 143, 43, 245, 142, 43, 245, + 141, 43, 245, 140, 43, 245, 139, 43, 245, 138, 43, 245, 137, 43, 245, + 136, 43, 245, 135, 43, 245, 134, 43, 245, 133, 43, 245, 132, 43, 245, + 131, 43, 245, 130, 43, 245, 129, 43, 245, 128, 43, 245, 127, 43, 245, + 126, 43, 245, 125, 43, 245, 124, 43, 245, 123, 43, 245, 122, 43, 245, + 121, 43, 245, 120, 43, 245, 119, 43, 245, 118, 43, 245, 117, 43, 245, + 116, 43, 245, 115, 114, 1, 233, 15, 114, 1, 196, 222, 114, 1, 214, 3, + 114, 1, 203, 216, 114, 1, 236, 49, 114, 1, 225, 80, 114, 1, 159, 114, 1, + 250, 112, 114, 1, 240, 231, 114, 1, 199, 230, 114, 1, 234, 190, 114, 1, + 144, 114, 1, 214, 4, 218, 55, 114, 1, 240, 232, 209, 80, 114, 1, 236, 50, + 218, 55, 114, 1, 225, 81, 221, 136, 114, 1, 211, 32, 209, 80, 114, 1, + 202, 235, 114, 1, 205, 234, 239, 177, 114, 1, 239, 177, 114, 1, 224, 37, + 114, 1, 205, 234, 225, 217, 114, 1, 232, 26, 114, 1, 222, 123, 114, 1, + 210, 78, 114, 1, 221, 136, 114, 1, 218, 55, 114, 1, 225, 217, 114, 1, + 209, 80, 114, 1, 221, 137, 218, 55, 114, 1, 218, 56, 221, 136, 114, 1, + 225, 218, 221, 136, 114, 1, 209, 81, 225, 217, 114, 1, 221, 137, 3, 238, + 253, 114, 1, 218, 56, 3, 238, 253, 114, 1, 225, 218, 3, 238, 253, 114, 1, + 225, 218, 3, 238, 251, 226, 42, 26, 57, 114, 1, 209, 81, 3, 238, 253, + 114, 1, 209, 81, 3, 76, 60, 114, 1, 221, 137, 209, 80, 114, 1, 218, 56, + 209, 80, 114, 1, 225, 218, 209, 80, 114, 1, 209, 81, 209, 80, 114, 1, + 221, 137, 218, 56, 209, 80, 114, 1, 218, 56, 221, 137, 209, 80, 114, 1, + 225, 218, 221, 137, 209, 80, 114, 1, 209, 81, 225, 218, 209, 80, 114, 1, + 225, 218, 209, 81, 3, 238, 253, 114, 1, 225, 218, 218, 55, 114, 1, 225, + 218, 218, 56, 209, 80, 114, 1, 209, 81, 203, 216, 114, 1, 209, 81, 203, + 217, 144, 114, 1, 209, 81, 214, 3, 114, 1, 209, 81, 214, 4, 144, 114, 1, + 203, 217, 209, 80, 114, 1, 203, 217, 211, 32, 209, 80, 114, 1, 197, 199, + 114, 1, 197, 81, 114, 1, 197, 200, 144, 114, 1, 209, 81, 218, 55, 114, 1, + 209, 81, 221, 136, 114, 1, 225, 81, 211, 32, 209, 80, 114, 1, 234, 191, + 211, 32, 209, 80, 114, 1, 209, 81, 225, 80, 114, 1, 209, 81, 225, 81, + 144, 114, 1, 63, 114, 1, 205, 234, 214, 16, 114, 1, 214, 190, 114, 1, 72, + 114, 1, 251, 47, 114, 1, 68, 114, 1, 69, 114, 1, 226, 147, 114, 1, 206, + 182, 68, 114, 1, 200, 90, 114, 1, 237, 54, 114, 1, 205, 234, 237, 40, + 114, 1, 209, 207, 68, 114, 1, 205, 234, 237, 54, 114, 1, 181, 68, 114, 1, + 196, 69, 114, 1, 66, 114, 1, 236, 116, 114, 1, 196, 171, 114, 1, 118, + 218, 55, 114, 1, 181, 66, 114, 1, 209, 207, 66, 114, 1, 200, 92, 114, 1, + 205, 234, 66, 114, 1, 214, 99, 114, 1, 214, 16, 114, 1, 214, 39, 114, 1, + 197, 166, 114, 1, 197, 34, 114, 1, 197, 70, 114, 1, 197, 96, 114, 1, 197, + 1, 114, 1, 217, 209, 66, 114, 1, 217, 209, 72, 114, 1, 217, 209, 68, 114, + 1, 217, 209, 63, 114, 1, 213, 34, 251, 106, 114, 1, 213, 34, 251, 123, + 114, 1, 205, 234, 236, 230, 114, 1, 205, 234, 251, 106, 114, 1, 205, 234, + 214, 119, 114, 1, 110, 221, 136, 114, 251, 224, 50, 231, 155, 208, 137, + 114, 251, 224, 219, 65, 231, 155, 208, 137, 114, 251, 224, 53, 231, 155, + 208, 137, 114, 251, 224, 126, 83, 208, 137, 114, 251, 224, 219, 65, 83, + 208, 137, 114, 251, 224, 130, 83, 208, 137, 114, 251, 224, 250, 156, 208, + 137, 114, 251, 224, 250, 156, 222, 175, 208, 137, 114, 251, 224, 250, + 156, 203, 109, 114, 251, 224, 250, 156, 203, 135, 114, 251, 224, 250, + 156, 237, 136, 122, 114, 251, 224, 250, 156, 230, 249, 122, 114, 251, + 224, 250, 156, 203, 110, 122, 114, 251, 224, 130, 186, 114, 251, 224, + 130, 202, 101, 186, 114, 251, 224, 130, 233, 100, 114, 251, 224, 130, + 181, 233, 100, 114, 251, 224, 130, 238, 253, 114, 251, 224, 130, 244, + 249, 114, 251, 224, 130, 222, 75, 114, 251, 224, 130, 197, 122, 114, 251, + 224, 130, 199, 100, 114, 251, 224, 126, 186, 114, 251, 224, 126, 202, + 101, 186, 114, 251, 224, 126, 233, 100, 114, 251, 224, 126, 181, 233, + 100, 114, 251, 224, 126, 238, 253, 114, 251, 224, 126, 244, 249, 114, + 251, 224, 126, 222, 75, 114, 251, 224, 126, 197, 122, 114, 251, 224, 126, + 199, 100, 114, 251, 224, 126, 51, 114, 2, 177, 3, 241, 61, 114, 202, 193, + 1, 208, 114, 114, 52, 78, 114, 211, 214, 245, 59, 234, 217, 204, 226, + 206, 169, 235, 23, 1, 214, 23, 206, 169, 235, 23, 241, 127, 214, 23, 206, + 169, 235, 23, 135, 204, 241, 206, 169, 235, 23, 124, 204, 241, 67, 34, + 16, 211, 231, 67, 34, 16, 240, 67, 67, 34, 16, 213, 38, 67, 34, 16, 214, + 12, 237, 11, 67, 34, 16, 214, 12, 239, 90, 67, 34, 16, 199, 136, 237, 11, + 67, 34, 16, 199, 136, 239, 90, 67, 34, 16, 224, 230, 67, 34, 16, 203, + 233, 67, 34, 16, 213, 147, 67, 34, 16, 195, 223, 67, 34, 16, 195, 224, + 239, 90, 67, 34, 16, 223, 205, 67, 34, 16, 251, 42, 237, 11, 67, 34, 16, + 236, 84, 237, 11, 67, 34, 16, 203, 35, 67, 34, 16, 224, 178, 67, 34, 16, + 251, 31, 67, 34, 16, 251, 32, 239, 90, 67, 34, 16, 203, 240, 67, 34, 16, + 202, 172, 67, 34, 16, 214, 130, 250, 249, 67, 34, 16, 233, 127, 250, 249, + 67, 34, 16, 211, 230, 67, 34, 16, 247, 7, 67, 34, 16, 199, 125, 67, 34, + 16, 225, 239, 250, 249, 67, 34, 16, 224, 180, 250, 249, 67, 34, 16, 224, + 179, 250, 249, 67, 34, 16, 208, 182, 67, 34, 16, 213, 137, 67, 34, 16, + 204, 251, 251, 35, 67, 34, 16, 214, 11, 250, 249, 67, 34, 16, 199, 135, + 250, 249, 67, 34, 16, 251, 36, 250, 249, 67, 34, 16, 251, 29, 67, 34, 16, + 224, 27, 67, 34, 16, 210, 85, 67, 34, 16, 212, 218, 250, 249, 67, 34, 16, + 202, 74, 67, 34, 16, 251, 103, 67, 34, 16, 208, 117, 67, 34, 16, 203, + 244, 250, 249, 67, 34, 16, 203, 244, 219, 144, 204, 249, 67, 34, 16, 214, + 6, 250, 249, 67, 34, 16, 202, 211, 67, 34, 16, 222, 162, 67, 34, 16, 237, + 159, 67, 34, 16, 201, 182, 67, 34, 16, 203, 4, 67, 34, 16, 223, 208, 67, + 34, 16, 251, 42, 236, 84, 217, 97, 67, 34, 16, 234, 225, 250, 249, 67, + 34, 16, 226, 99, 67, 34, 16, 201, 151, 250, 249, 67, 34, 16, 224, 233, + 201, 150, 67, 34, 16, 213, 67, 67, 34, 16, 211, 235, 67, 34, 16, 223, + 243, 67, 34, 16, 245, 42, 250, 249, 67, 34, 16, 210, 203, 67, 34, 16, + 213, 150, 250, 249, 67, 34, 16, 213, 148, 250, 249, 67, 34, 16, 230, 199, + 67, 34, 16, 217, 220, 67, 34, 16, 213, 16, 67, 34, 16, 223, 244, 251, + 141, 67, 34, 16, 201, 151, 251, 141, 67, 34, 16, 204, 220, 67, 34, 16, + 233, 86, 67, 34, 16, 225, 239, 217, 97, 67, 34, 16, 214, 130, 217, 97, + 67, 34, 16, 214, 12, 217, 97, 67, 34, 16, 213, 15, 67, 34, 16, 223, 228, + 67, 34, 16, 213, 14, 67, 34, 16, 223, 207, 67, 34, 16, 213, 68, 217, 97, + 67, 34, 16, 224, 179, 217, 98, 251, 73, 67, 34, 16, 224, 180, 217, 98, + 251, 73, 67, 34, 16, 195, 221, 67, 34, 16, 251, 32, 217, 97, 67, 34, 16, + 251, 33, 203, 241, 217, 97, 67, 34, 16, 195, 222, 67, 34, 16, 223, 206, + 67, 34, 16, 237, 6, 67, 34, 16, 247, 8, 67, 34, 16, 219, 36, 225, 238, + 67, 34, 16, 199, 136, 217, 97, 67, 34, 16, 212, 218, 217, 97, 67, 34, 16, + 211, 236, 217, 97, 67, 34, 16, 214, 126, 67, 34, 16, 251, 60, 67, 34, 16, + 221, 147, 67, 34, 16, 213, 148, 217, 97, 67, 34, 16, 213, 150, 217, 97, + 67, 34, 16, 236, 122, 213, 149, 67, 34, 16, 223, 104, 67, 34, 16, 251, + 61, 67, 34, 16, 201, 151, 217, 97, 67, 34, 16, 237, 9, 67, 34, 16, 203, + 244, 217, 97, 67, 34, 16, 203, 234, 67, 34, 16, 245, 42, 217, 97, 67, 34, + 16, 236, 180, 67, 34, 16, 208, 118, 217, 97, 67, 34, 16, 196, 188, 224, + 27, 67, 34, 16, 201, 148, 67, 34, 16, 211, 237, 67, 34, 16, 201, 152, 67, + 34, 16, 201, 149, 67, 34, 16, 211, 234, 67, 34, 16, 201, 147, 67, 34, 16, + 211, 233, 67, 34, 16, 233, 126, 67, 34, 16, 250, 241, 67, 34, 16, 236, + 122, 250, 241, 67, 34, 16, 214, 6, 217, 97, 67, 34, 16, 202, 210, 236, + 135, 67, 34, 16, 202, 210, 236, 83, 67, 34, 16, 202, 212, 251, 37, 67, + 34, 16, 202, 204, 225, 32, 251, 28, 67, 34, 16, 224, 232, 67, 34, 16, + 236, 217, 67, 34, 16, 196, 28, 224, 229, 67, 34, 16, 196, 28, 251, 73, + 67, 34, 16, 204, 250, 67, 34, 16, 224, 28, 251, 73, 67, 34, 16, 239, 91, + 250, 249, 67, 34, 16, 223, 209, 250, 249, 67, 34, 16, 223, 209, 251, 141, + 67, 34, 16, 223, 209, 217, 97, 67, 34, 16, 251, 36, 217, 97, 67, 34, 16, + 251, 38, 67, 34, 16, 239, 90, 67, 34, 16, 201, 163, 67, 34, 16, 202, 250, + 67, 34, 16, 223, 232, 67, 34, 16, 222, 167, 236, 210, 245, 32, 67, 34, + 16, 222, 167, 237, 160, 245, 33, 67, 34, 16, 222, 167, 201, 166, 245, 33, + 67, 34, 16, 222, 167, 203, 6, 245, 33, 67, 34, 16, 222, 167, 226, 94, + 245, 32, 67, 34, 16, 233, 127, 217, 98, 251, 73, 67, 34, 16, 233, 127, + 213, 138, 250, 237, 67, 34, 16, 233, 127, 213, 138, 239, 181, 67, 34, 16, + 239, 115, 67, 34, 16, 239, 116, 213, 138, 250, 238, 224, 229, 67, 34, 16, + 239, 116, 213, 138, 250, 238, 251, 73, 67, 34, 16, 239, 116, 213, 138, + 239, 181, 67, 34, 16, 201, 171, 67, 34, 16, 250, 242, 67, 34, 16, 226, + 101, 67, 34, 16, 239, 138, 67, 34, 16, 251, 211, 212, 100, 250, 243, 67, + 34, 16, 251, 211, 250, 240, 67, 34, 16, 251, 211, 250, 243, 67, 34, 16, + 251, 211, 219, 138, 67, 34, 16, 251, 211, 219, 149, 67, 34, 16, 251, 211, + 233, 128, 67, 34, 16, 251, 211, 233, 125, 67, 34, 16, 251, 211, 212, 100, + 233, 128, 67, 34, 16, 220, 18, 211, 243, 230, 197, 67, 34, 16, 220, 18, + 251, 143, 211, 243, 230, 197, 67, 34, 16, 220, 18, 239, 180, 230, 197, + 67, 34, 16, 220, 18, 251, 143, 239, 180, 230, 197, 67, 34, 16, 220, 18, + 201, 158, 230, 197, 67, 34, 16, 220, 18, 201, 172, 67, 34, 16, 220, 18, + 202, 255, 230, 197, 67, 34, 16, 220, 18, 202, 255, 222, 171, 230, 197, + 67, 34, 16, 220, 18, 222, 171, 230, 197, 67, 34, 16, 220, 18, 212, 146, + 230, 197, 67, 34, 16, 225, 246, 203, 28, 230, 198, 67, 34, 16, 251, 33, + 203, 28, 230, 198, 67, 34, 16, 235, 209, 202, 252, 67, 34, 16, 235, 209, + 218, 206, 67, 34, 16, 235, 209, 239, 121, 67, 34, 16, 220, 18, 199, 129, + 230, 197, 67, 34, 16, 220, 18, 211, 242, 230, 197, 67, 34, 16, 220, 18, + 212, 146, 202, 255, 230, 197, 67, 34, 16, 233, 122, 218, 56, 251, 37, 67, + 34, 16, 233, 122, 218, 56, 239, 89, 67, 34, 16, 236, 228, 225, 32, 234, + 225, 198, 228, 67, 34, 16, 226, 100, 67, 34, 16, 226, 98, 67, 34, 16, + 234, 225, 250, 250, 239, 179, 230, 196, 67, 34, 16, 234, 225, 239, 136, + 161, 67, 34, 16, 234, 225, 239, 136, 217, 220, 67, 34, 16, 234, 225, 217, + 214, 230, 197, 67, 34, 16, 234, 225, 239, 136, 239, 152, 67, 34, 16, 234, + 225, 206, 0, 239, 135, 239, 152, 67, 34, 16, 234, 225, 239, 136, 224, + 209, 67, 34, 16, 234, 225, 239, 136, 195, 11, 67, 34, 16, 234, 225, 239, + 136, 216, 224, 224, 229, 67, 34, 16, 234, 225, 239, 136, 216, 224, 251, + 73, 67, 34, 16, 234, 225, 220, 68, 245, 34, 239, 121, 67, 34, 16, 234, + 225, 220, 68, 245, 34, 218, 206, 67, 34, 16, 235, 154, 206, 0, 245, 34, + 199, 128, 67, 34, 16, 234, 225, 206, 0, 245, 34, 203, 245, 67, 34, 16, + 234, 225, 217, 100, 67, 34, 16, 245, 35, 194, 234, 67, 34, 16, 245, 35, + 224, 26, 67, 34, 16, 245, 35, 205, 139, 67, 34, 16, 234, 225, 230, 249, + 196, 27, 203, 0, 67, 34, 16, 234, 225, 236, 229, 251, 62, 67, 34, 16, + 196, 27, 201, 159, 67, 34, 16, 239, 129, 201, 159, 67, 34, 16, 239, 129, + 203, 0, 67, 34, 16, 239, 129, 251, 39, 237, 160, 239, 20, 67, 34, 16, + 239, 129, 218, 204, 203, 5, 239, 20, 67, 34, 16, 239, 129, 239, 112, 236, + 96, 239, 20, 67, 34, 16, 239, 129, 201, 169, 214, 136, 239, 20, 67, 34, + 16, 196, 27, 251, 39, 237, 160, 239, 20, 67, 34, 16, 196, 27, 218, 204, + 203, 5, 239, 20, 67, 34, 16, 196, 27, 239, 112, 236, 96, 239, 20, 67, 34, + 16, 196, 27, 201, 169, 214, 136, 239, 20, 67, 34, 16, 234, 30, 239, 128, + 67, 34, 16, 234, 30, 196, 26, 67, 34, 16, 239, 137, 251, 39, 219, 37, 67, + 34, 16, 239, 137, 251, 39, 219, 179, 67, 34, 16, 239, 137, 239, 90, 67, + 34, 16, 239, 137, 202, 202, 67, 34, 16, 206, 72, 202, 202, 67, 34, 16, + 206, 72, 202, 203, 239, 74, 67, 34, 16, 206, 72, 202, 203, 201, 160, 67, + 34, 16, 206, 72, 202, 203, 202, 248, 67, 34, 16, 206, 72, 250, 211, 67, + 34, 16, 206, 72, 250, 212, 239, 74, 67, 34, 16, 206, 72, 250, 212, 201, + 160, 67, 34, 16, 206, 72, 250, 212, 202, 248, 67, 34, 16, 239, 113, 234, + 11, 67, 34, 16, 239, 120, 214, 39, 67, 34, 16, 204, 236, 67, 34, 16, 250, + 234, 161, 67, 34, 16, 250, 234, 198, 228, 67, 34, 16, 250, 234, 234, 123, + 67, 34, 16, 250, 234, 239, 152, 67, 34, 16, 250, 234, 224, 209, 67, 34, + 16, 250, 234, 195, 11, 67, 34, 16, 250, 234, 216, 223, 67, 34, 16, 224, + 179, 217, 98, 219, 148, 67, 34, 16, 224, 180, 217, 98, 219, 148, 67, 34, + 16, 224, 179, 217, 98, 224, 229, 67, 34, 16, 224, 180, 217, 98, 224, 229, + 67, 34, 16, 224, 28, 224, 229, 67, 34, 16, 233, 127, 217, 98, 224, 229, + 34, 16, 206, 62, 249, 75, 34, 16, 52, 249, 75, 34, 16, 48, 249, 75, 34, + 16, 210, 90, 48, 249, 75, 34, 16, 240, 64, 249, 75, 34, 16, 206, 182, + 249, 75, 34, 16, 50, 210, 120, 55, 34, 16, 53, 210, 120, 55, 34, 16, 210, + 120, 238, 250, 34, 16, 240, 108, 208, 121, 34, 16, 240, 137, 247, 122, + 34, 16, 208, 121, 34, 16, 244, 176, 34, 16, 210, 118, 235, 142, 34, 16, + 210, 118, 235, 141, 34, 16, 210, 118, 235, 140, 34, 16, 235, 164, 34, 16, + 235, 165, 60, 34, 16, 248, 49, 78, 34, 16, 247, 164, 34, 16, 248, 63, 34, + 16, 179, 34, 16, 214, 114, 205, 16, 34, 16, 200, 214, 205, 16, 34, 16, + 202, 149, 205, 16, 34, 16, 235, 6, 205, 16, 34, 16, 235, 100, 205, 16, + 34, 16, 206, 28, 205, 16, 34, 16, 206, 26, 234, 242, 34, 16, 235, 4, 234, + 242, 34, 16, 234, 191, 244, 218, 34, 16, 234, 191, 244, 219, 214, 43, + 251, 132, 34, 16, 234, 191, 244, 219, 214, 43, 249, 58, 34, 16, 247, 208, + 244, 218, 34, 16, 236, 50, 244, 218, 34, 16, 236, 50, 244, 219, 214, 43, + 251, 132, 34, 16, 236, 50, 244, 219, 214, 43, 249, 58, 34, 16, 237, 207, + 244, 217, 34, 16, 237, 207, 244, 216, 34, 16, 218, 120, 219, 203, 210, + 101, 34, 16, 52, 207, 12, 34, 16, 52, 235, 82, 34, 16, 235, 83, 200, 36, + 34, 16, 235, 83, 237, 235, 34, 16, 217, 203, 200, 36, 34, 16, 217, 203, + 237, 235, 34, 16, 207, 13, 200, 36, 34, 16, 207, 13, 237, 235, 34, 16, + 211, 88, 152, 207, 12, 34, 16, 211, 88, 152, 235, 82, 34, 16, 244, 156, + 202, 78, 34, 16, 241, 2, 202, 78, 34, 16, 214, 43, 251, 132, 34, 16, 214, + 43, 249, 58, 34, 16, 211, 69, 251, 132, 34, 16, 211, 69, 249, 58, 34, 16, + 218, 123, 210, 101, 34, 16, 197, 71, 210, 101, 34, 16, 157, 210, 101, 34, + 16, 211, 88, 210, 101, 34, 16, 237, 27, 210, 101, 34, 16, 206, 22, 210, + 101, 34, 16, 202, 174, 210, 101, 34, 16, 206, 12, 210, 101, 34, 16, 97, + 231, 58, 200, 232, 210, 101, 34, 16, 196, 223, 216, 9, 34, 16, 98, 216, + 9, 34, 16, 244, 250, 196, 223, 216, 9, 34, 16, 47, 216, 10, 197, 73, 34, + 16, 47, 216, 10, 248, 136, 34, 16, 201, 181, 216, 10, 124, 197, 73, 34, + 16, 201, 181, 216, 10, 124, 248, 136, 34, 16, 201, 181, 216, 10, 50, 197, + 73, 34, 16, 201, 181, 216, 10, 50, 248, 136, 34, 16, 201, 181, 216, 10, + 53, 197, 73, 34, 16, 201, 181, 216, 10, 53, 248, 136, 34, 16, 201, 181, + 216, 10, 135, 197, 73, 34, 16, 201, 181, 216, 10, 135, 248, 136, 34, 16, + 201, 181, 216, 10, 124, 53, 197, 73, 34, 16, 201, 181, 216, 10, 124, 53, + 248, 136, 34, 16, 218, 190, 216, 10, 197, 73, 34, 16, 218, 190, 216, 10, + 248, 136, 34, 16, 201, 178, 216, 10, 135, 197, 73, 34, 16, 201, 178, 216, + 10, 135, 248, 136, 34, 16, 213, 141, 216, 9, 34, 16, 198, 241, 216, 9, + 34, 16, 216, 10, 248, 136, 34, 16, 215, 147, 216, 9, 34, 16, 244, 187, + 216, 10, 197, 73, 34, 16, 244, 187, 216, 10, 248, 136, 34, 16, 248, 47, + 34, 16, 197, 71, 216, 13, 34, 16, 157, 216, 13, 34, 16, 211, 88, 216, 13, + 34, 16, 237, 27, 216, 13, 34, 16, 206, 22, 216, 13, 34, 16, 202, 174, + 216, 13, 34, 16, 206, 12, 216, 13, 34, 16, 97, 231, 58, 200, 232, 216, + 13, 34, 16, 38, 204, 243, 34, 16, 38, 205, 101, 204, 243, 34, 16, 38, + 201, 189, 34, 16, 38, 201, 188, 34, 16, 38, 201, 187, 34, 16, 235, 125, + 201, 189, 34, 16, 235, 125, 201, 188, 34, 16, 235, 125, 201, 187, 34, 16, + 38, 250, 147, 238, 253, 34, 16, 38, 235, 92, 34, 16, 38, 235, 91, 34, 16, + 38, 235, 90, 34, 16, 38, 235, 89, 34, 16, 38, 235, 88, 34, 16, 248, 243, + 249, 6, 34, 16, 236, 222, 249, 6, 34, 16, 248, 243, 202, 107, 34, 16, + 236, 222, 202, 107, 34, 16, 248, 243, 205, 225, 34, 16, 236, 222, 205, + 225, 34, 16, 248, 243, 212, 227, 34, 16, 236, 222, 212, 227, 34, 16, 38, + 252, 22, 34, 16, 38, 205, 20, 34, 16, 38, 203, 11, 34, 16, 38, 205, 21, + 34, 16, 38, 220, 33, 34, 16, 38, 220, 32, 34, 16, 38, 252, 21, 34, 16, + 38, 221, 210, 34, 16, 250, 223, 200, 36, 34, 16, 250, 223, 237, 235, 34, + 16, 38, 239, 13, 34, 16, 38, 209, 254, 34, 16, 38, 235, 71, 34, 16, 38, + 205, 221, 34, 16, 38, 248, 221, 34, 16, 38, 52, 201, 249, 34, 16, 38, + 201, 165, 201, 249, 34, 16, 210, 4, 34, 16, 204, 154, 34, 16, 195, 158, + 34, 16, 212, 219, 34, 16, 219, 129, 34, 16, 235, 18, 34, 16, 241, 73, 34, + 16, 239, 238, 34, 16, 233, 117, 216, 14, 205, 248, 34, 16, 233, 117, 216, + 14, 216, 51, 205, 248, 34, 16, 201, 218, 34, 16, 201, 4, 34, 16, 226, 17, + 201, 4, 34, 16, 201, 5, 205, 248, 34, 16, 201, 5, 200, 36, 34, 16, 214, + 60, 204, 195, 34, 16, 214, 60, 204, 192, 34, 16, 214, 60, 204, 191, 34, + 16, 214, 60, 204, 190, 34, 16, 214, 60, 204, 189, 34, 16, 214, 60, 204, + 188, 34, 16, 214, 60, 204, 187, 34, 16, 214, 60, 204, 186, 34, 16, 214, + 60, 204, 185, 34, 16, 214, 60, 204, 194, 34, 16, 214, 60, 204, 193, 34, + 16, 232, 157, 34, 16, 217, 110, 34, 16, 236, 222, 77, 204, 232, 34, 16, + 239, 231, 205, 248, 34, 16, 38, 135, 248, 77, 34, 16, 38, 124, 248, 77, + 34, 16, 38, 232, 170, 34, 16, 38, 205, 211, 212, 151, 34, 16, 213, 84, + 78, 34, 16, 213, 84, 124, 78, 34, 16, 157, 213, 84, 78, 34, 16, 233, 154, + 200, 36, 34, 16, 233, 154, 237, 235, 34, 16, 3, 235, 124, 34, 16, 240, + 91, 34, 16, 240, 92, 251, 146, 34, 16, 219, 253, 34, 16, 221, 231, 34, + 16, 248, 44, 34, 16, 207, 109, 197, 73, 34, 16, 207, 109, 248, 136, 34, + 16, 219, 19, 34, 16, 219, 20, 248, 136, 34, 16, 207, 103, 197, 73, 34, + 16, 207, 103, 248, 136, 34, 16, 234, 208, 197, 73, 34, 16, 234, 208, 248, + 136, 34, 16, 221, 232, 213, 43, 210, 101, 34, 16, 221, 232, 226, 91, 210, + 101, 34, 16, 248, 45, 210, 101, 34, 16, 207, 109, 210, 101, 34, 16, 219, + 20, 210, 101, 34, 16, 207, 103, 210, 101, 34, 16, 203, 25, 213, 41, 241, + 32, 211, 253, 213, 42, 34, 16, 203, 25, 213, 41, 241, 32, 211, 253, 226, + 90, 34, 16, 203, 25, 213, 41, 241, 32, 211, 253, 213, 43, 239, 100, 34, + 16, 203, 25, 226, 89, 241, 32, 211, 253, 213, 42, 34, 16, 203, 25, 226, + 89, 241, 32, 211, 253, 226, 90, 34, 16, 203, 25, 226, 89, 241, 32, 211, + 253, 226, 91, 239, 100, 34, 16, 203, 25, 226, 89, 241, 32, 211, 253, 226, + 91, 239, 99, 34, 16, 203, 25, 226, 89, 241, 32, 211, 253, 226, 91, 239, + 98, 34, 16, 241, 64, 34, 16, 233, 89, 247, 208, 244, 218, 34, 16, 233, + 89, 236, 50, 244, 218, 34, 16, 47, 250, 112, 34, 16, 199, 6, 34, 16, 212, + 114, 34, 16, 244, 208, 34, 16, 208, 172, 34, 16, 244, 213, 34, 16, 201, + 236, 34, 16, 212, 82, 34, 16, 212, 83, 235, 74, 34, 16, 208, 173, 235, + 74, 34, 16, 201, 237, 210, 98, 34, 16, 213, 24, 204, 144, 34, 16, 224, + 83, 247, 208, 244, 218, 34, 16, 224, 83, 236, 222, 77, 212, 212, 34, 16, + 224, 83, 48, 216, 13, 34, 16, 224, 83, 210, 170, 78, 34, 16, 224, 83, + 197, 71, 216, 13, 34, 16, 224, 83, 157, 216, 13, 34, 16, 224, 83, 211, + 88, 216, 14, 204, 244, 237, 235, 34, 16, 224, 83, 211, 88, 216, 14, 204, + 244, 200, 36, 34, 16, 224, 83, 237, 27, 216, 14, 204, 244, 237, 235, 34, + 16, 224, 83, 237, 27, 216, 14, 204, 244, 200, 36, 34, 16, 224, 83, 235, + 83, 55, 32, 198, 247, 216, 17, 204, 40, 32, 198, 247, 216, 17, 204, 29, + 32, 198, 247, 216, 17, 204, 19, 32, 198, 247, 216, 17, 204, 12, 32, 198, + 247, 216, 17, 204, 4, 32, 198, 247, 216, 17, 203, 254, 32, 198, 247, 216, + 17, 203, 253, 32, 198, 247, 216, 17, 203, 252, 32, 198, 247, 216, 17, + 203, 251, 32, 198, 247, 216, 17, 204, 39, 32, 198, 247, 216, 17, 204, 38, + 32, 198, 247, 216, 17, 204, 37, 32, 198, 247, 216, 17, 204, 36, 32, 198, + 247, 216, 17, 204, 35, 32, 198, 247, 216, 17, 204, 34, 32, 198, 247, 216, + 17, 204, 33, 32, 198, 247, 216, 17, 204, 32, 32, 198, 247, 216, 17, 204, + 31, 32, 198, 247, 216, 17, 204, 30, 32, 198, 247, 216, 17, 204, 28, 32, + 198, 247, 216, 17, 204, 27, 32, 198, 247, 216, 17, 204, 26, 32, 198, 247, + 216, 17, 204, 25, 32, 198, 247, 216, 17, 204, 24, 32, 198, 247, 216, 17, + 204, 3, 32, 198, 247, 216, 17, 204, 2, 32, 198, 247, 216, 17, 204, 1, 32, + 198, 247, 216, 17, 204, 0, 32, 198, 247, 216, 17, 203, 255, 32, 226, 40, + 216, 17, 204, 40, 32, 226, 40, 216, 17, 204, 29, 32, 226, 40, 216, 17, + 204, 12, 32, 226, 40, 216, 17, 204, 4, 32, 226, 40, 216, 17, 203, 253, + 32, 226, 40, 216, 17, 203, 252, 32, 226, 40, 216, 17, 204, 38, 32, 226, + 40, 216, 17, 204, 37, 32, 226, 40, 216, 17, 204, 36, 32, 226, 40, 216, + 17, 204, 35, 32, 226, 40, 216, 17, 204, 32, 32, 226, 40, 216, 17, 204, + 31, 32, 226, 40, 216, 17, 204, 30, 32, 226, 40, 216, 17, 204, 25, 32, + 226, 40, 216, 17, 204, 24, 32, 226, 40, 216, 17, 204, 23, 32, 226, 40, + 216, 17, 204, 22, 32, 226, 40, 216, 17, 204, 21, 32, 226, 40, 216, 17, + 204, 20, 32, 226, 40, 216, 17, 204, 18, 32, 226, 40, 216, 17, 204, 17, + 32, 226, 40, 216, 17, 204, 16, 32, 226, 40, 216, 17, 204, 15, 32, 226, + 40, 216, 17, 204, 14, 32, 226, 40, 216, 17, 204, 13, 32, 226, 40, 216, + 17, 204, 11, 32, 226, 40, 216, 17, 204, 10, 32, 226, 40, 216, 17, 204, 9, + 32, 226, 40, 216, 17, 204, 8, 32, 226, 40, 216, 17, 204, 7, 32, 226, 40, + 216, 17, 204, 6, 32, 226, 40, 216, 17, 204, 5, 32, 226, 40, 216, 17, 204, + 3, 32, 226, 40, 216, 17, 204, 2, 32, 226, 40, 216, 17, 204, 1, 32, 226, + 40, 216, 17, 204, 0, 32, 226, 40, 216, 17, 203, 255, 38, 32, 34, 201, + 161, 38, 32, 34, 202, 249, 38, 32, 34, 213, 53, 32, 34, 222, 166, 219, + 250, 215, 142, 195, 79, 219, 250, 215, 142, 100, 219, 250, 215, 142, 102, + 219, 250, 215, 142, 134, 219, 250, 215, 142, 136, 219, 250, 215, 142, + 146, 219, 250, 215, 142, 167, 219, 250, 215, 142, 178, 219, 250, 215, + 142, 171, 219, 250, 215, 142, 182, 219, 250, 215, 142, 203, 23, 219, 250, + 215, 142, 236, 252, 219, 250, 215, 142, 200, 239, 219, 250, 215, 142, + 202, 179, 219, 250, 215, 142, 235, 1, 219, 250, 215, 142, 235, 149, 219, + 250, 215, 142, 206, 23, 219, 250, 215, 142, 207, 68, 219, 250, 215, 142, + 237, 28, 219, 250, 215, 142, 216, 176, 218, 205, 36, 237, 72, 239, 114, + 36, 232, 121, 237, 72, 239, 114, 36, 231, 62, 237, 72, 239, 114, 36, 237, + 71, 232, 122, 239, 114, 36, 237, 71, 231, 61, 239, 114, 36, 237, 72, 202, + 251, 36, 247, 36, 202, 251, 36, 234, 217, 244, 249, 202, 251, 36, 219, + 11, 202, 251, 36, 249, 70, 202, 251, 36, 224, 197, 205, 224, 202, 251, + 36, 241, 122, 202, 251, 36, 250, 197, 202, 251, 36, 214, 78, 202, 251, + 36, 248, 55, 214, 34, 202, 251, 36, 239, 233, 214, 73, 239, 66, 202, 251, + 36, 239, 63, 202, 251, 36, 195, 229, 202, 251, 36, 226, 77, 202, 251, 36, + 213, 63, 202, 251, 36, 210, 178, 202, 251, 36, 241, 134, 202, 251, 36, + 231, 176, 249, 138, 202, 251, 36, 197, 152, 202, 251, 36, 235, 46, 202, + 251, 36, 251, 248, 202, 251, 36, 210, 133, 202, 251, 36, 210, 105, 202, + 251, 36, 237, 70, 202, 251, 36, 225, 113, 202, 251, 36, 241, 129, 202, + 251, 36, 236, 220, 202, 251, 36, 237, 172, 202, 251, 36, 247, 3, 202, + 251, 36, 239, 243, 202, 251, 36, 27, 210, 104, 202, 251, 36, 213, 234, + 202, 251, 36, 222, 170, 202, 251, 36, 244, 201, 202, 251, 36, 224, 71, + 202, 251, 36, 234, 72, 202, 251, 36, 204, 207, 202, 251, 36, 211, 202, + 202, 251, 36, 234, 216, 202, 251, 36, 210, 106, 202, 251, 36, 222, 210, + 214, 73, 218, 241, 202, 251, 36, 210, 102, 202, 251, 36, 233, 137, 202, + 30, 219, 183, 202, 251, 36, 236, 223, 202, 251, 36, 204, 221, 202, 251, + 36, 233, 92, 202, 251, 36, 236, 213, 202, 251, 36, 213, 110, 202, 251, + 36, 209, 247, 202, 251, 36, 235, 72, 202, 251, 36, 199, 127, 214, 73, + 197, 131, 202, 251, 36, 241, 139, 202, 251, 36, 219, 202, 202, 251, 36, + 236, 123, 202, 251, 36, 200, 47, 202, 251, 36, 239, 101, 202, 251, 36, + 244, 203, 218, 164, 202, 251, 36, 233, 68, 202, 251, 36, 234, 73, 226, + 86, 202, 251, 36, 220, 6, 202, 251, 36, 252, 17, 202, 251, 36, 236, 239, + 202, 251, 36, 237, 239, 202, 251, 36, 197, 129, 202, 251, 36, 206, 57, + 202, 251, 36, 226, 50, 202, 251, 36, 239, 200, 202, 251, 36, 240, 69, + 202, 251, 36, 239, 97, 202, 251, 36, 236, 87, 202, 251, 36, 207, 64, 202, + 251, 36, 204, 225, 202, 251, 36, 232, 172, 202, 251, 36, 244, 151, 202, + 251, 36, 244, 198, 202, 251, 36, 235, 218, 202, 251, 36, 251, 212, 202, + 251, 36, 244, 150, 202, 251, 36, 214, 120, 202, 218, 199, 103, 202, 251, + 36, 239, 123, 202, 251, 36, 223, 70, 202, 251, 36, 235, 10, 241, 88, 209, + 216, 200, 50, 17, 100, 241, 88, 209, 216, 200, 50, 17, 102, 241, 88, 209, + 216, 200, 50, 17, 134, 241, 88, 209, 216, 200, 50, 17, 136, 241, 88, 209, + 216, 200, 50, 17, 146, 241, 88, 209, 216, 200, 50, 17, 167, 241, 88, 209, + 216, 200, 50, 17, 178, 241, 88, 209, 216, 200, 50, 17, 171, 241, 88, 209, + 216, 200, 50, 17, 182, 241, 88, 209, 216, 203, 19, 17, 100, 241, 88, 209, + 216, 203, 19, 17, 102, 241, 88, 209, 216, 203, 19, 17, 134, 241, 88, 209, + 216, 203, 19, 17, 136, 241, 88, 209, 216, 203, 19, 17, 146, 241, 88, 209, + 216, 203, 19, 17, 167, 241, 88, 209, 216, 203, 19, 17, 178, 241, 88, 209, + 216, 203, 19, 17, 171, 241, 88, 209, 216, 203, 19, 17, 182, 143, 203, + 118, 117, 100, 143, 203, 118, 117, 102, 143, 203, 118, 117, 134, 143, + 203, 118, 117, 136, 143, 203, 118, 117, 146, 203, 118, 117, 100, 203, + 118, 117, 146, 13, 27, 6, 63, 13, 27, 6, 250, 112, 13, 27, 6, 247, 207, + 13, 27, 6, 240, 231, 13, 27, 6, 69, 13, 27, 6, 236, 49, 13, 27, 6, 234, + 190, 13, 27, 6, 233, 15, 13, 27, 6, 68, 13, 27, 6, 225, 217, 13, 27, 6, + 225, 80, 13, 27, 6, 159, 13, 27, 6, 221, 136, 13, 27, 6, 218, 55, 13, 27, + 6, 72, 13, 27, 6, 214, 3, 13, 27, 6, 211, 167, 13, 27, 6, 144, 13, 27, 6, + 209, 80, 13, 27, 6, 203, 216, 13, 27, 6, 66, 13, 27, 6, 199, 230, 13, 27, + 6, 197, 199, 13, 27, 6, 196, 222, 13, 27, 6, 196, 148, 13, 27, 6, 195, + 158, 13, 27, 4, 63, 13, 27, 4, 250, 112, 13, 27, 4, 247, 207, 13, 27, 4, + 240, 231, 13, 27, 4, 69, 13, 27, 4, 236, 49, 13, 27, 4, 234, 190, 13, 27, + 4, 233, 15, 13, 27, 4, 68, 13, 27, 4, 225, 217, 13, 27, 4, 225, 80, 13, + 27, 4, 159, 13, 27, 4, 221, 136, 13, 27, 4, 218, 55, 13, 27, 4, 72, 13, + 27, 4, 214, 3, 13, 27, 4, 211, 167, 13, 27, 4, 144, 13, 27, 4, 209, 80, + 13, 27, 4, 203, 216, 13, 27, 4, 66, 13, 27, 4, 199, 230, 13, 27, 4, 197, + 199, 13, 27, 4, 196, 222, 13, 27, 4, 196, 148, 13, 27, 4, 195, 158, 13, + 41, 6, 63, 13, 41, 6, 250, 112, 13, 41, 6, 247, 207, 13, 41, 6, 240, 231, + 13, 41, 6, 69, 13, 41, 6, 236, 49, 13, 41, 6, 234, 190, 13, 41, 6, 233, + 15, 13, 41, 6, 68, 13, 41, 6, 225, 217, 13, 41, 6, 225, 80, 13, 41, 6, + 159, 13, 41, 6, 221, 136, 13, 41, 6, 218, 55, 13, 41, 6, 72, 13, 41, 6, + 214, 3, 13, 41, 6, 211, 167, 13, 41, 6, 144, 13, 41, 6, 209, 80, 13, 41, + 6, 203, 216, 13, 41, 6, 66, 13, 41, 6, 199, 230, 13, 41, 6, 197, 199, 13, + 41, 6, 196, 222, 13, 41, 6, 196, 148, 13, 41, 6, 195, 158, 13, 41, 4, 63, + 13, 41, 4, 250, 112, 13, 41, 4, 247, 207, 13, 41, 4, 240, 231, 13, 41, 4, + 69, 13, 41, 4, 236, 49, 13, 41, 4, 234, 190, 13, 41, 4, 68, 13, 41, 4, + 225, 217, 13, 41, 4, 225, 80, 13, 41, 4, 159, 13, 41, 4, 221, 136, 13, + 41, 4, 218, 55, 13, 41, 4, 72, 13, 41, 4, 214, 3, 13, 41, 4, 211, 167, + 13, 41, 4, 144, 13, 41, 4, 209, 80, 13, 41, 4, 203, 216, 13, 41, 4, 66, + 13, 41, 4, 199, 230, 13, 41, 4, 197, 199, 13, 41, 4, 196, 222, 13, 41, 4, + 196, 148, 13, 41, 4, 195, 158, 13, 27, 41, 6, 63, 13, 27, 41, 6, 250, + 112, 13, 27, 41, 6, 247, 207, 13, 27, 41, 6, 240, 231, 13, 27, 41, 6, 69, + 13, 27, 41, 6, 236, 49, 13, 27, 41, 6, 234, 190, 13, 27, 41, 6, 233, 15, + 13, 27, 41, 6, 68, 13, 27, 41, 6, 225, 217, 13, 27, 41, 6, 225, 80, 13, + 27, 41, 6, 159, 13, 27, 41, 6, 221, 136, 13, 27, 41, 6, 218, 55, 13, 27, + 41, 6, 72, 13, 27, 41, 6, 214, 3, 13, 27, 41, 6, 211, 167, 13, 27, 41, 6, + 144, 13, 27, 41, 6, 209, 80, 13, 27, 41, 6, 203, 216, 13, 27, 41, 6, 66, + 13, 27, 41, 6, 199, 230, 13, 27, 41, 6, 197, 199, 13, 27, 41, 6, 196, + 222, 13, 27, 41, 6, 196, 148, 13, 27, 41, 6, 195, 158, 13, 27, 41, 4, 63, + 13, 27, 41, 4, 250, 112, 13, 27, 41, 4, 247, 207, 13, 27, 41, 4, 240, + 231, 13, 27, 41, 4, 69, 13, 27, 41, 4, 236, 49, 13, 27, 41, 4, 234, 190, + 13, 27, 41, 4, 233, 15, 13, 27, 41, 4, 68, 13, 27, 41, 4, 225, 217, 13, + 27, 41, 4, 225, 80, 13, 27, 41, 4, 159, 13, 27, 41, 4, 221, 136, 13, 27, + 41, 4, 218, 55, 13, 27, 41, 4, 72, 13, 27, 41, 4, 214, 3, 13, 27, 41, 4, + 211, 167, 13, 27, 41, 4, 144, 13, 27, 41, 4, 209, 80, 13, 27, 41, 4, 203, + 216, 13, 27, 41, 4, 66, 13, 27, 41, 4, 199, 230, 13, 27, 41, 4, 197, 199, + 13, 27, 41, 4, 196, 222, 13, 27, 41, 4, 196, 148, 13, 27, 41, 4, 195, + 158, 13, 145, 6, 63, 13, 145, 6, 247, 207, 13, 145, 6, 240, 231, 13, 145, + 6, 234, 190, 13, 145, 6, 225, 217, 13, 145, 6, 225, 80, 13, 145, 6, 218, + 55, 13, 145, 6, 72, 13, 145, 6, 214, 3, 13, 145, 6, 211, 167, 13, 145, 6, + 209, 80, 13, 145, 6, 203, 216, 13, 145, 6, 66, 13, 145, 6, 199, 230, 13, + 145, 6, 197, 199, 13, 145, 6, 196, 222, 13, 145, 6, 196, 148, 13, 145, 6, + 195, 158, 13, 145, 4, 63, 13, 145, 4, 250, 112, 13, 145, 4, 247, 207, 13, + 145, 4, 240, 231, 13, 145, 4, 236, 49, 13, 145, 4, 233, 15, 13, 145, 4, + 68, 13, 145, 4, 225, 217, 13, 145, 4, 225, 80, 13, 145, 4, 159, 13, 145, + 4, 221, 136, 13, 145, 4, 218, 55, 13, 145, 4, 214, 3, 13, 145, 4, 211, + 167, 13, 145, 4, 144, 13, 145, 4, 209, 80, 13, 145, 4, 203, 216, 13, 145, + 4, 66, 13, 145, 4, 199, 230, 13, 145, 4, 197, 199, 13, 145, 4, 196, 222, + 13, 145, 4, 196, 148, 13, 145, 4, 195, 158, 13, 27, 145, 6, 63, 13, 27, + 145, 6, 250, 112, 13, 27, 145, 6, 247, 207, 13, 27, 145, 6, 240, 231, 13, + 27, 145, 6, 69, 13, 27, 145, 6, 236, 49, 13, 27, 145, 6, 234, 190, 13, + 27, 145, 6, 233, 15, 13, 27, 145, 6, 68, 13, 27, 145, 6, 225, 217, 13, + 27, 145, 6, 225, 80, 13, 27, 145, 6, 159, 13, 27, 145, 6, 221, 136, 13, + 27, 145, 6, 218, 55, 13, 27, 145, 6, 72, 13, 27, 145, 6, 214, 3, 13, 27, + 145, 6, 211, 167, 13, 27, 145, 6, 144, 13, 27, 145, 6, 209, 80, 13, 27, + 145, 6, 203, 216, 13, 27, 145, 6, 66, 13, 27, 145, 6, 199, 230, 13, 27, + 145, 6, 197, 199, 13, 27, 145, 6, 196, 222, 13, 27, 145, 6, 196, 148, 13, + 27, 145, 6, 195, 158, 13, 27, 145, 4, 63, 13, 27, 145, 4, 250, 112, 13, + 27, 145, 4, 247, 207, 13, 27, 145, 4, 240, 231, 13, 27, 145, 4, 69, 13, + 27, 145, 4, 236, 49, 13, 27, 145, 4, 234, 190, 13, 27, 145, 4, 233, 15, + 13, 27, 145, 4, 68, 13, 27, 145, 4, 225, 217, 13, 27, 145, 4, 225, 80, + 13, 27, 145, 4, 159, 13, 27, 145, 4, 221, 136, 13, 27, 145, 4, 218, 55, + 13, 27, 145, 4, 72, 13, 27, 145, 4, 214, 3, 13, 27, 145, 4, 211, 167, 13, + 27, 145, 4, 144, 13, 27, 145, 4, 209, 80, 13, 27, 145, 4, 203, 216, 13, + 27, 145, 4, 66, 13, 27, 145, 4, 199, 230, 13, 27, 145, 4, 197, 199, 13, + 27, 145, 4, 196, 222, 13, 27, 145, 4, 196, 148, 13, 27, 145, 4, 195, 158, + 13, 187, 6, 63, 13, 187, 6, 250, 112, 13, 187, 6, 240, 231, 13, 187, 6, + 69, 13, 187, 6, 236, 49, 13, 187, 6, 234, 190, 13, 187, 6, 225, 217, 13, + 187, 6, 225, 80, 13, 187, 6, 159, 13, 187, 6, 221, 136, 13, 187, 6, 218, + 55, 13, 187, 6, 72, 13, 187, 6, 214, 3, 13, 187, 6, 211, 167, 13, 187, 6, + 209, 80, 13, 187, 6, 203, 216, 13, 187, 6, 66, 13, 187, 6, 199, 230, 13, + 187, 6, 197, 199, 13, 187, 6, 196, 222, 13, 187, 6, 196, 148, 13, 187, 4, + 63, 13, 187, 4, 250, 112, 13, 187, 4, 247, 207, 13, 187, 4, 240, 231, 13, + 187, 4, 69, 13, 187, 4, 236, 49, 13, 187, 4, 234, 190, 13, 187, 4, 233, + 15, 13, 187, 4, 68, 13, 187, 4, 225, 217, 13, 187, 4, 225, 80, 13, 187, + 4, 159, 13, 187, 4, 221, 136, 13, 187, 4, 218, 55, 13, 187, 4, 72, 13, + 187, 4, 214, 3, 13, 187, 4, 211, 167, 13, 187, 4, 144, 13, 187, 4, 209, + 80, 13, 187, 4, 203, 216, 13, 187, 4, 66, 13, 187, 4, 199, 230, 13, 187, + 4, 197, 199, 13, 187, 4, 196, 222, 13, 187, 4, 196, 148, 13, 187, 4, 195, + 158, 13, 237, 241, 6, 63, 13, 237, 241, 6, 250, 112, 13, 237, 241, 6, + 240, 231, 13, 237, 241, 6, 69, 13, 237, 241, 6, 236, 49, 13, 237, 241, 6, + 234, 190, 13, 237, 241, 6, 68, 13, 237, 241, 6, 225, 217, 13, 237, 241, + 6, 225, 80, 13, 237, 241, 6, 159, 13, 237, 241, 6, 221, 136, 13, 237, + 241, 6, 72, 13, 237, 241, 6, 209, 80, 13, 237, 241, 6, 203, 216, 13, 237, + 241, 6, 66, 13, 237, 241, 6, 199, 230, 13, 237, 241, 6, 197, 199, 13, + 237, 241, 6, 196, 222, 13, 237, 241, 6, 196, 148, 13, 237, 241, 4, 63, + 13, 237, 241, 4, 250, 112, 13, 237, 241, 4, 247, 207, 13, 237, 241, 4, + 240, 231, 13, 237, 241, 4, 69, 13, 237, 241, 4, 236, 49, 13, 237, 241, 4, + 234, 190, 13, 237, 241, 4, 233, 15, 13, 237, 241, 4, 68, 13, 237, 241, 4, + 225, 217, 13, 237, 241, 4, 225, 80, 13, 237, 241, 4, 159, 13, 237, 241, + 4, 221, 136, 13, 237, 241, 4, 218, 55, 13, 237, 241, 4, 72, 13, 237, 241, + 4, 214, 3, 13, 237, 241, 4, 211, 167, 13, 237, 241, 4, 144, 13, 237, 241, + 4, 209, 80, 13, 237, 241, 4, 203, 216, 13, 237, 241, 4, 66, 13, 237, 241, + 4, 199, 230, 13, 237, 241, 4, 197, 199, 13, 237, 241, 4, 196, 222, 13, + 237, 241, 4, 196, 148, 13, 237, 241, 4, 195, 158, 13, 27, 187, 6, 63, 13, + 27, 187, 6, 250, 112, 13, 27, 187, 6, 247, 207, 13, 27, 187, 6, 240, 231, + 13, 27, 187, 6, 69, 13, 27, 187, 6, 236, 49, 13, 27, 187, 6, 234, 190, + 13, 27, 187, 6, 233, 15, 13, 27, 187, 6, 68, 13, 27, 187, 6, 225, 217, + 13, 27, 187, 6, 225, 80, 13, 27, 187, 6, 159, 13, 27, 187, 6, 221, 136, + 13, 27, 187, 6, 218, 55, 13, 27, 187, 6, 72, 13, 27, 187, 6, 214, 3, 13, + 27, 187, 6, 211, 167, 13, 27, 187, 6, 144, 13, 27, 187, 6, 209, 80, 13, + 27, 187, 6, 203, 216, 13, 27, 187, 6, 66, 13, 27, 187, 6, 199, 230, 13, + 27, 187, 6, 197, 199, 13, 27, 187, 6, 196, 222, 13, 27, 187, 6, 196, 148, + 13, 27, 187, 6, 195, 158, 13, 27, 187, 4, 63, 13, 27, 187, 4, 250, 112, + 13, 27, 187, 4, 247, 207, 13, 27, 187, 4, 240, 231, 13, 27, 187, 4, 69, + 13, 27, 187, 4, 236, 49, 13, 27, 187, 4, 234, 190, 13, 27, 187, 4, 233, + 15, 13, 27, 187, 4, 68, 13, 27, 187, 4, 225, 217, 13, 27, 187, 4, 225, + 80, 13, 27, 187, 4, 159, 13, 27, 187, 4, 221, 136, 13, 27, 187, 4, 218, + 55, 13, 27, 187, 4, 72, 13, 27, 187, 4, 214, 3, 13, 27, 187, 4, 211, 167, + 13, 27, 187, 4, 144, 13, 27, 187, 4, 209, 80, 13, 27, 187, 4, 203, 216, + 13, 27, 187, 4, 66, 13, 27, 187, 4, 199, 230, 13, 27, 187, 4, 197, 199, + 13, 27, 187, 4, 196, 222, 13, 27, 187, 4, 196, 148, 13, 27, 187, 4, 195, + 158, 13, 45, 6, 63, 13, 45, 6, 250, 112, 13, 45, 6, 247, 207, 13, 45, 6, + 240, 231, 13, 45, 6, 69, 13, 45, 6, 236, 49, 13, 45, 6, 234, 190, 13, 45, + 6, 233, 15, 13, 45, 6, 68, 13, 45, 6, 225, 217, 13, 45, 6, 225, 80, 13, + 45, 6, 159, 13, 45, 6, 221, 136, 13, 45, 6, 218, 55, 13, 45, 6, 72, 13, + 45, 6, 214, 3, 13, 45, 6, 211, 167, 13, 45, 6, 144, 13, 45, 6, 209, 80, + 13, 45, 6, 203, 216, 13, 45, 6, 66, 13, 45, 6, 199, 230, 13, 45, 6, 197, + 199, 13, 45, 6, 196, 222, 13, 45, 6, 196, 148, 13, 45, 6, 195, 158, 13, + 45, 4, 63, 13, 45, 4, 250, 112, 13, 45, 4, 247, 207, 13, 45, 4, 240, 231, + 13, 45, 4, 69, 13, 45, 4, 236, 49, 13, 45, 4, 234, 190, 13, 45, 4, 233, + 15, 13, 45, 4, 68, 13, 45, 4, 225, 217, 13, 45, 4, 225, 80, 13, 45, 4, + 159, 13, 45, 4, 221, 136, 13, 45, 4, 218, 55, 13, 45, 4, 72, 13, 45, 4, + 214, 3, 13, 45, 4, 211, 167, 13, 45, 4, 144, 13, 45, 4, 209, 80, 13, 45, + 4, 203, 216, 13, 45, 4, 66, 13, 45, 4, 199, 230, 13, 45, 4, 197, 199, 13, + 45, 4, 196, 222, 13, 45, 4, 196, 148, 13, 45, 4, 195, 158, 13, 45, 27, 6, + 63, 13, 45, 27, 6, 250, 112, 13, 45, 27, 6, 247, 207, 13, 45, 27, 6, 240, + 231, 13, 45, 27, 6, 69, 13, 45, 27, 6, 236, 49, 13, 45, 27, 6, 234, 190, + 13, 45, 27, 6, 233, 15, 13, 45, 27, 6, 68, 13, 45, 27, 6, 225, 217, 13, + 45, 27, 6, 225, 80, 13, 45, 27, 6, 159, 13, 45, 27, 6, 221, 136, 13, 45, + 27, 6, 218, 55, 13, 45, 27, 6, 72, 13, 45, 27, 6, 214, 3, 13, 45, 27, 6, + 211, 167, 13, 45, 27, 6, 144, 13, 45, 27, 6, 209, 80, 13, 45, 27, 6, 203, + 216, 13, 45, 27, 6, 66, 13, 45, 27, 6, 199, 230, 13, 45, 27, 6, 197, 199, + 13, 45, 27, 6, 196, 222, 13, 45, 27, 6, 196, 148, 13, 45, 27, 6, 195, + 158, 13, 45, 27, 4, 63, 13, 45, 27, 4, 250, 112, 13, 45, 27, 4, 247, 207, + 13, 45, 27, 4, 240, 231, 13, 45, 27, 4, 69, 13, 45, 27, 4, 236, 49, 13, + 45, 27, 4, 234, 190, 13, 45, 27, 4, 233, 15, 13, 45, 27, 4, 68, 13, 45, + 27, 4, 225, 217, 13, 45, 27, 4, 225, 80, 13, 45, 27, 4, 159, 13, 45, 27, + 4, 221, 136, 13, 45, 27, 4, 218, 55, 13, 45, 27, 4, 72, 13, 45, 27, 4, + 214, 3, 13, 45, 27, 4, 211, 167, 13, 45, 27, 4, 144, 13, 45, 27, 4, 209, + 80, 13, 45, 27, 4, 203, 216, 13, 45, 27, 4, 66, 13, 45, 27, 4, 199, 230, + 13, 45, 27, 4, 197, 199, 13, 45, 27, 4, 196, 222, 13, 45, 27, 4, 196, + 148, 13, 45, 27, 4, 195, 158, 13, 45, 41, 6, 63, 13, 45, 41, 6, 250, 112, + 13, 45, 41, 6, 247, 207, 13, 45, 41, 6, 240, 231, 13, 45, 41, 6, 69, 13, + 45, 41, 6, 236, 49, 13, 45, 41, 6, 234, 190, 13, 45, 41, 6, 233, 15, 13, + 45, 41, 6, 68, 13, 45, 41, 6, 225, 217, 13, 45, 41, 6, 225, 80, 13, 45, + 41, 6, 159, 13, 45, 41, 6, 221, 136, 13, 45, 41, 6, 218, 55, 13, 45, 41, + 6, 72, 13, 45, 41, 6, 214, 3, 13, 45, 41, 6, 211, 167, 13, 45, 41, 6, + 144, 13, 45, 41, 6, 209, 80, 13, 45, 41, 6, 203, 216, 13, 45, 41, 6, 66, + 13, 45, 41, 6, 199, 230, 13, 45, 41, 6, 197, 199, 13, 45, 41, 6, 196, + 222, 13, 45, 41, 6, 196, 148, 13, 45, 41, 6, 195, 158, 13, 45, 41, 4, 63, + 13, 45, 41, 4, 250, 112, 13, 45, 41, 4, 247, 207, 13, 45, 41, 4, 240, + 231, 13, 45, 41, 4, 69, 13, 45, 41, 4, 236, 49, 13, 45, 41, 4, 234, 190, + 13, 45, 41, 4, 233, 15, 13, 45, 41, 4, 68, 13, 45, 41, 4, 225, 217, 13, + 45, 41, 4, 225, 80, 13, 45, 41, 4, 159, 13, 45, 41, 4, 221, 136, 13, 45, + 41, 4, 218, 55, 13, 45, 41, 4, 72, 13, 45, 41, 4, 214, 3, 13, 45, 41, 4, + 211, 167, 13, 45, 41, 4, 144, 13, 45, 41, 4, 209, 80, 13, 45, 41, 4, 203, + 216, 13, 45, 41, 4, 66, 13, 45, 41, 4, 199, 230, 13, 45, 41, 4, 197, 199, + 13, 45, 41, 4, 196, 222, 13, 45, 41, 4, 196, 148, 13, 45, 41, 4, 195, + 158, 13, 45, 27, 41, 6, 63, 13, 45, 27, 41, 6, 250, 112, 13, 45, 27, 41, + 6, 247, 207, 13, 45, 27, 41, 6, 240, 231, 13, 45, 27, 41, 6, 69, 13, 45, + 27, 41, 6, 236, 49, 13, 45, 27, 41, 6, 234, 190, 13, 45, 27, 41, 6, 233, + 15, 13, 45, 27, 41, 6, 68, 13, 45, 27, 41, 6, 225, 217, 13, 45, 27, 41, + 6, 225, 80, 13, 45, 27, 41, 6, 159, 13, 45, 27, 41, 6, 221, 136, 13, 45, + 27, 41, 6, 218, 55, 13, 45, 27, 41, 6, 72, 13, 45, 27, 41, 6, 214, 3, 13, + 45, 27, 41, 6, 211, 167, 13, 45, 27, 41, 6, 144, 13, 45, 27, 41, 6, 209, + 80, 13, 45, 27, 41, 6, 203, 216, 13, 45, 27, 41, 6, 66, 13, 45, 27, 41, + 6, 199, 230, 13, 45, 27, 41, 6, 197, 199, 13, 45, 27, 41, 6, 196, 222, + 13, 45, 27, 41, 6, 196, 148, 13, 45, 27, 41, 6, 195, 158, 13, 45, 27, 41, + 4, 63, 13, 45, 27, 41, 4, 250, 112, 13, 45, 27, 41, 4, 247, 207, 13, 45, + 27, 41, 4, 240, 231, 13, 45, 27, 41, 4, 69, 13, 45, 27, 41, 4, 236, 49, + 13, 45, 27, 41, 4, 234, 190, 13, 45, 27, 41, 4, 233, 15, 13, 45, 27, 41, + 4, 68, 13, 45, 27, 41, 4, 225, 217, 13, 45, 27, 41, 4, 225, 80, 13, 45, + 27, 41, 4, 159, 13, 45, 27, 41, 4, 221, 136, 13, 45, 27, 41, 4, 218, 55, + 13, 45, 27, 41, 4, 72, 13, 45, 27, 41, 4, 214, 3, 13, 45, 27, 41, 4, 211, + 167, 13, 45, 27, 41, 4, 144, 13, 45, 27, 41, 4, 209, 80, 13, 45, 27, 41, + 4, 203, 216, 13, 45, 27, 41, 4, 66, 13, 45, 27, 41, 4, 199, 230, 13, 45, + 27, 41, 4, 197, 199, 13, 45, 27, 41, 4, 196, 222, 13, 45, 27, 41, 4, 196, + 148, 13, 45, 27, 41, 4, 195, 158, 13, 218, 201, 6, 63, 13, 218, 201, 6, + 250, 112, 13, 218, 201, 6, 247, 207, 13, 218, 201, 6, 240, 231, 13, 218, + 201, 6, 69, 13, 218, 201, 6, 236, 49, 13, 218, 201, 6, 234, 190, 13, 218, + 201, 6, 233, 15, 13, 218, 201, 6, 68, 13, 218, 201, 6, 225, 217, 13, 218, + 201, 6, 225, 80, 13, 218, 201, 6, 159, 13, 218, 201, 6, 221, 136, 13, + 218, 201, 6, 218, 55, 13, 218, 201, 6, 72, 13, 218, 201, 6, 214, 3, 13, + 218, 201, 6, 211, 167, 13, 218, 201, 6, 144, 13, 218, 201, 6, 209, 80, + 13, 218, 201, 6, 203, 216, 13, 218, 201, 6, 66, 13, 218, 201, 6, 199, + 230, 13, 218, 201, 6, 197, 199, 13, 218, 201, 6, 196, 222, 13, 218, 201, + 6, 196, 148, 13, 218, 201, 6, 195, 158, 13, 218, 201, 4, 63, 13, 218, + 201, 4, 250, 112, 13, 218, 201, 4, 247, 207, 13, 218, 201, 4, 240, 231, + 13, 218, 201, 4, 69, 13, 218, 201, 4, 236, 49, 13, 218, 201, 4, 234, 190, + 13, 218, 201, 4, 233, 15, 13, 218, 201, 4, 68, 13, 218, 201, 4, 225, 217, + 13, 218, 201, 4, 225, 80, 13, 218, 201, 4, 159, 13, 218, 201, 4, 221, + 136, 13, 218, 201, 4, 218, 55, 13, 218, 201, 4, 72, 13, 218, 201, 4, 214, + 3, 13, 218, 201, 4, 211, 167, 13, 218, 201, 4, 144, 13, 218, 201, 4, 209, + 80, 13, 218, 201, 4, 203, 216, 13, 218, 201, 4, 66, 13, 218, 201, 4, 199, + 230, 13, 218, 201, 4, 197, 199, 13, 218, 201, 4, 196, 222, 13, 218, 201, + 4, 196, 148, 13, 218, 201, 4, 195, 158, 13, 41, 4, 238, 252, 68, 13, 41, + 4, 238, 252, 225, 217, 13, 27, 6, 251, 134, 13, 27, 6, 248, 206, 13, 27, + 6, 234, 94, 13, 27, 6, 239, 212, 13, 27, 6, 236, 174, 13, 27, 6, 195, 78, + 13, 27, 6, 236, 126, 13, 27, 6, 202, 199, 13, 27, 6, 226, 7, 13, 27, 6, + 225, 2, 13, 27, 6, 222, 245, 13, 27, 6, 218, 145, 13, 27, 6, 215, 186, + 13, 27, 6, 196, 196, 13, 27, 6, 214, 122, 13, 27, 6, 212, 220, 13, 27, 6, + 210, 74, 13, 27, 6, 202, 200, 105, 13, 27, 6, 206, 86, 13, 27, 6, 203, + 89, 13, 27, 6, 200, 28, 13, 27, 6, 212, 246, 13, 27, 6, 245, 75, 13, 27, + 6, 211, 238, 13, 27, 6, 214, 124, 13, 27, 217, 239, 13, 27, 4, 251, 134, + 13, 27, 4, 248, 206, 13, 27, 4, 234, 94, 13, 27, 4, 239, 212, 13, 27, 4, + 236, 174, 13, 27, 4, 195, 78, 13, 27, 4, 236, 126, 13, 27, 4, 202, 199, + 13, 27, 4, 226, 7, 13, 27, 4, 225, 2, 13, 27, 4, 222, 245, 13, 27, 4, + 218, 145, 13, 27, 4, 215, 186, 13, 27, 4, 196, 196, 13, 27, 4, 214, 122, + 13, 27, 4, 212, 220, 13, 27, 4, 210, 74, 13, 27, 4, 48, 206, 86, 13, 27, + 4, 206, 86, 13, 27, 4, 203, 89, 13, 27, 4, 200, 28, 13, 27, 4, 212, 246, + 13, 27, 4, 245, 75, 13, 27, 4, 211, 238, 13, 27, 4, 214, 124, 13, 27, + 213, 132, 239, 124, 13, 27, 236, 175, 105, 13, 27, 202, 200, 105, 13, 27, + 225, 3, 105, 13, 27, 212, 247, 105, 13, 27, 210, 75, 105, 13, 27, 212, + 221, 105, 13, 41, 6, 251, 134, 13, 41, 6, 248, 206, 13, 41, 6, 234, 94, + 13, 41, 6, 239, 212, 13, 41, 6, 236, 174, 13, 41, 6, 195, 78, 13, 41, 6, + 236, 126, 13, 41, 6, 202, 199, 13, 41, 6, 226, 7, 13, 41, 6, 225, 2, 13, + 41, 6, 222, 245, 13, 41, 6, 218, 145, 13, 41, 6, 215, 186, 13, 41, 6, + 196, 196, 13, 41, 6, 214, 122, 13, 41, 6, 212, 220, 13, 41, 6, 210, 74, + 13, 41, 6, 202, 200, 105, 13, 41, 6, 206, 86, 13, 41, 6, 203, 89, 13, 41, + 6, 200, 28, 13, 41, 6, 212, 246, 13, 41, 6, 245, 75, 13, 41, 6, 211, 238, + 13, 41, 6, 214, 124, 13, 41, 217, 239, 13, 41, 4, 251, 134, 13, 41, 4, + 248, 206, 13, 41, 4, 234, 94, 13, 41, 4, 239, 212, 13, 41, 4, 236, 174, + 13, 41, 4, 195, 78, 13, 41, 4, 236, 126, 13, 41, 4, 202, 199, 13, 41, 4, + 226, 7, 13, 41, 4, 225, 2, 13, 41, 4, 222, 245, 13, 41, 4, 218, 145, 13, + 41, 4, 215, 186, 13, 41, 4, 196, 196, 13, 41, 4, 214, 122, 13, 41, 4, + 212, 220, 13, 41, 4, 210, 74, 13, 41, 4, 48, 206, 86, 13, 41, 4, 206, 86, + 13, 41, 4, 203, 89, 13, 41, 4, 200, 28, 13, 41, 4, 212, 246, 13, 41, 4, + 245, 75, 13, 41, 4, 211, 238, 13, 41, 4, 214, 124, 13, 41, 213, 132, 239, + 124, 13, 41, 236, 175, 105, 13, 41, 202, 200, 105, 13, 41, 225, 3, 105, + 13, 41, 212, 247, 105, 13, 41, 210, 75, 105, 13, 41, 212, 221, 105, 13, + 27, 41, 6, 251, 134, 13, 27, 41, 6, 248, 206, 13, 27, 41, 6, 234, 94, 13, + 27, 41, 6, 239, 212, 13, 27, 41, 6, 236, 174, 13, 27, 41, 6, 195, 78, 13, + 27, 41, 6, 236, 126, 13, 27, 41, 6, 202, 199, 13, 27, 41, 6, 226, 7, 13, + 27, 41, 6, 225, 2, 13, 27, 41, 6, 222, 245, 13, 27, 41, 6, 218, 145, 13, + 27, 41, 6, 215, 186, 13, 27, 41, 6, 196, 196, 13, 27, 41, 6, 214, 122, + 13, 27, 41, 6, 212, 220, 13, 27, 41, 6, 210, 74, 13, 27, 41, 6, 202, 200, + 105, 13, 27, 41, 6, 206, 86, 13, 27, 41, 6, 203, 89, 13, 27, 41, 6, 200, + 28, 13, 27, 41, 6, 212, 246, 13, 27, 41, 6, 245, 75, 13, 27, 41, 6, 211, + 238, 13, 27, 41, 6, 214, 124, 13, 27, 41, 217, 239, 13, 27, 41, 4, 251, + 134, 13, 27, 41, 4, 248, 206, 13, 27, 41, 4, 234, 94, 13, 27, 41, 4, 239, + 212, 13, 27, 41, 4, 236, 174, 13, 27, 41, 4, 195, 78, 13, 27, 41, 4, 236, + 126, 13, 27, 41, 4, 202, 199, 13, 27, 41, 4, 226, 7, 13, 27, 41, 4, 225, + 2, 13, 27, 41, 4, 222, 245, 13, 27, 41, 4, 218, 145, 13, 27, 41, 4, 215, + 186, 13, 27, 41, 4, 196, 196, 13, 27, 41, 4, 214, 122, 13, 27, 41, 4, + 212, 220, 13, 27, 41, 4, 210, 74, 13, 27, 41, 4, 48, 206, 86, 13, 27, 41, + 4, 206, 86, 13, 27, 41, 4, 203, 89, 13, 27, 41, 4, 200, 28, 13, 27, 41, + 4, 212, 246, 13, 27, 41, 4, 245, 75, 13, 27, 41, 4, 211, 238, 13, 27, 41, + 4, 214, 124, 13, 27, 41, 213, 132, 239, 124, 13, 27, 41, 236, 175, 105, + 13, 27, 41, 202, 200, 105, 13, 27, 41, 225, 3, 105, 13, 27, 41, 212, 247, + 105, 13, 27, 41, 210, 75, 105, 13, 27, 41, 212, 221, 105, 13, 45, 27, 6, + 251, 134, 13, 45, 27, 6, 248, 206, 13, 45, 27, 6, 234, 94, 13, 45, 27, 6, + 239, 212, 13, 45, 27, 6, 236, 174, 13, 45, 27, 6, 195, 78, 13, 45, 27, 6, + 236, 126, 13, 45, 27, 6, 202, 199, 13, 45, 27, 6, 226, 7, 13, 45, 27, 6, + 225, 2, 13, 45, 27, 6, 222, 245, 13, 45, 27, 6, 218, 145, 13, 45, 27, 6, + 215, 186, 13, 45, 27, 6, 196, 196, 13, 45, 27, 6, 214, 122, 13, 45, 27, + 6, 212, 220, 13, 45, 27, 6, 210, 74, 13, 45, 27, 6, 202, 200, 105, 13, + 45, 27, 6, 206, 86, 13, 45, 27, 6, 203, 89, 13, 45, 27, 6, 200, 28, 13, + 45, 27, 6, 212, 246, 13, 45, 27, 6, 245, 75, 13, 45, 27, 6, 211, 238, 13, + 45, 27, 6, 214, 124, 13, 45, 27, 217, 239, 13, 45, 27, 4, 251, 134, 13, + 45, 27, 4, 248, 206, 13, 45, 27, 4, 234, 94, 13, 45, 27, 4, 239, 212, 13, + 45, 27, 4, 236, 174, 13, 45, 27, 4, 195, 78, 13, 45, 27, 4, 236, 126, 13, + 45, 27, 4, 202, 199, 13, 45, 27, 4, 226, 7, 13, 45, 27, 4, 225, 2, 13, + 45, 27, 4, 222, 245, 13, 45, 27, 4, 218, 145, 13, 45, 27, 4, 215, 186, + 13, 45, 27, 4, 196, 196, 13, 45, 27, 4, 214, 122, 13, 45, 27, 4, 212, + 220, 13, 45, 27, 4, 210, 74, 13, 45, 27, 4, 48, 206, 86, 13, 45, 27, 4, + 206, 86, 13, 45, 27, 4, 203, 89, 13, 45, 27, 4, 200, 28, 13, 45, 27, 4, + 212, 246, 13, 45, 27, 4, 245, 75, 13, 45, 27, 4, 211, 238, 13, 45, 27, 4, + 214, 124, 13, 45, 27, 213, 132, 239, 124, 13, 45, 27, 236, 175, 105, 13, + 45, 27, 202, 200, 105, 13, 45, 27, 225, 3, 105, 13, 45, 27, 212, 247, + 105, 13, 45, 27, 210, 75, 105, 13, 45, 27, 212, 221, 105, 13, 45, 27, 41, + 6, 251, 134, 13, 45, 27, 41, 6, 248, 206, 13, 45, 27, 41, 6, 234, 94, 13, + 45, 27, 41, 6, 239, 212, 13, 45, 27, 41, 6, 236, 174, 13, 45, 27, 41, 6, + 195, 78, 13, 45, 27, 41, 6, 236, 126, 13, 45, 27, 41, 6, 202, 199, 13, + 45, 27, 41, 6, 226, 7, 13, 45, 27, 41, 6, 225, 2, 13, 45, 27, 41, 6, 222, + 245, 13, 45, 27, 41, 6, 218, 145, 13, 45, 27, 41, 6, 215, 186, 13, 45, + 27, 41, 6, 196, 196, 13, 45, 27, 41, 6, 214, 122, 13, 45, 27, 41, 6, 212, + 220, 13, 45, 27, 41, 6, 210, 74, 13, 45, 27, 41, 6, 202, 200, 105, 13, + 45, 27, 41, 6, 206, 86, 13, 45, 27, 41, 6, 203, 89, 13, 45, 27, 41, 6, + 200, 28, 13, 45, 27, 41, 6, 212, 246, 13, 45, 27, 41, 6, 245, 75, 13, 45, + 27, 41, 6, 211, 238, 13, 45, 27, 41, 6, 214, 124, 13, 45, 27, 41, 217, + 239, 13, 45, 27, 41, 4, 251, 134, 13, 45, 27, 41, 4, 248, 206, 13, 45, + 27, 41, 4, 234, 94, 13, 45, 27, 41, 4, 239, 212, 13, 45, 27, 41, 4, 236, + 174, 13, 45, 27, 41, 4, 195, 78, 13, 45, 27, 41, 4, 236, 126, 13, 45, 27, + 41, 4, 202, 199, 13, 45, 27, 41, 4, 226, 7, 13, 45, 27, 41, 4, 225, 2, + 13, 45, 27, 41, 4, 222, 245, 13, 45, 27, 41, 4, 218, 145, 13, 45, 27, 41, + 4, 215, 186, 13, 45, 27, 41, 4, 196, 196, 13, 45, 27, 41, 4, 214, 122, + 13, 45, 27, 41, 4, 212, 220, 13, 45, 27, 41, 4, 210, 74, 13, 45, 27, 41, + 4, 48, 206, 86, 13, 45, 27, 41, 4, 206, 86, 13, 45, 27, 41, 4, 203, 89, + 13, 45, 27, 41, 4, 200, 28, 13, 45, 27, 41, 4, 212, 246, 13, 45, 27, 41, + 4, 245, 75, 13, 45, 27, 41, 4, 211, 238, 13, 45, 27, 41, 4, 214, 124, 13, + 45, 27, 41, 213, 132, 239, 124, 13, 45, 27, 41, 236, 175, 105, 13, 45, + 27, 41, 202, 200, 105, 13, 45, 27, 41, 225, 3, 105, 13, 45, 27, 41, 212, + 247, 105, 13, 45, 27, 41, 210, 75, 105, 13, 45, 27, 41, 212, 221, 105, + 13, 27, 6, 239, 118, 13, 27, 4, 239, 118, 13, 27, 17, 195, 79, 13, 27, + 17, 100, 13, 27, 17, 102, 13, 27, 17, 134, 13, 27, 17, 136, 13, 27, 17, + 146, 13, 27, 17, 167, 13, 27, 17, 178, 13, 27, 17, 171, 13, 27, 17, 182, + 13, 237, 241, 17, 195, 79, 13, 237, 241, 17, 100, 13, 237, 241, 17, 102, + 13, 237, 241, 17, 134, 13, 237, 241, 17, 136, 13, 237, 241, 17, 146, 13, + 237, 241, 17, 167, 13, 237, 241, 17, 178, 13, 237, 241, 17, 171, 13, 237, + 241, 17, 182, 13, 45, 17, 195, 79, 13, 45, 17, 100, 13, 45, 17, 102, 13, + 45, 17, 134, 13, 45, 17, 136, 13, 45, 17, 146, 13, 45, 17, 167, 13, 45, + 17, 178, 13, 45, 17, 171, 13, 45, 17, 182, 13, 45, 27, 17, 195, 79, 13, + 45, 27, 17, 100, 13, 45, 27, 17, 102, 13, 45, 27, 17, 134, 13, 45, 27, + 17, 136, 13, 45, 27, 17, 146, 13, 45, 27, 17, 167, 13, 45, 27, 17, 178, + 13, 45, 27, 17, 171, 13, 45, 27, 17, 182, 13, 218, 201, 17, 195, 79, 13, + 218, 201, 17, 100, 13, 218, 201, 17, 102, 13, 218, 201, 17, 134, 13, 218, + 201, 17, 136, 13, 218, 201, 17, 146, 13, 218, 201, 17, 167, 13, 218, 201, + 17, 178, 13, 218, 201, 17, 171, 13, 218, 201, 17, 182, 23, 139, 226, 72, + 23, 232, 206, 226, 72, 23, 232, 202, 226, 72, 23, 232, 191, 226, 72, 23, + 232, 195, 226, 72, 23, 232, 208, 226, 72, 23, 139, 132, 248, 217, 23, + 232, 206, 132, 248, 217, 23, 139, 162, 200, 64, 132, 248, 217, 23, 139, + 132, 210, 215, 224, 14, 23, 139, 132, 241, 23, 23, 139, 132, 232, 37, 23, + 139, 132, 232, 38, 221, 208, 23, 232, 206, 132, 232, 39, 23, 139, 132, + 219, 63, 23, 232, 206, 132, 219, 63, 23, 139, 132, 112, 248, 217, 23, + 139, 132, 112, 210, 215, 224, 13, 23, 139, 132, 112, 232, 37, 23, 139, + 132, 124, 112, 232, 37, 23, 139, 132, 232, 38, 112, 200, 36, 23, 139, + 132, 112, 241, 144, 23, 139, 132, 112, 241, 145, 132, 248, 217, 23, 139, + 132, 112, 241, 145, 112, 248, 217, 23, 139, 132, 112, 241, 145, 241, 23, + 23, 139, 132, 112, 241, 145, 232, 37, 23, 139, 132, 112, 241, 58, 23, + 232, 206, 132, 112, 241, 58, 23, 139, 112, 248, 218, 127, 226, 72, 23, + 139, 132, 248, 218, 127, 219, 63, 23, 139, 132, 112, 202, 141, 23, 232, + 206, 132, 112, 202, 141, 23, 139, 132, 112, 204, 218, 162, 248, 217, 23, + 139, 132, 112, 248, 218, 162, 204, 217, 23, 139, 132, 112, 162, 248, 217, + 23, 139, 132, 112, 232, 38, 205, 103, 162, 206, 97, 23, 139, 132, 124, + 112, 232, 38, 162, 206, 97, 23, 139, 132, 124, 112, 232, 38, 162, 241, + 144, 23, 139, 132, 232, 38, 112, 124, 162, 206, 97, 23, 139, 132, 112, + 124, 205, 103, 162, 235, 11, 23, 139, 132, 112, 162, 241, 23, 23, 139, + 132, 112, 162, 244, 248, 23, 139, 132, 112, 162, 231, 163, 23, 139, 132, + 112, 162, 232, 37, 23, 139, 162, 248, 204, 132, 112, 204, 217, 23, 139, + 132, 112, 241, 145, 162, 206, 97, 23, 139, 132, 112, 241, 145, 162, 206, + 98, 241, 144, 23, 139, 132, 112, 241, 145, 162, 206, 98, 248, 217, 23, + 139, 112, 162, 231, 164, 132, 200, 36, 23, 139, 132, 162, 231, 164, 112, + 200, 36, 23, 139, 132, 112, 241, 145, 232, 38, 162, 206, 97, 23, 139, + 132, 112, 241, 59, 162, 206, 97, 23, 139, 132, 112, 241, 145, 162, 235, + 11, 23, 139, 132, 112, 241, 145, 241, 24, 162, 235, 11, 23, 139, 112, + 162, 241, 24, 132, 200, 36, 23, 139, 132, 162, 241, 24, 112, 200, 36, 23, + 139, 112, 162, 46, 132, 200, 36, 23, 139, 112, 162, 46, 132, 232, 37, 23, + 139, 132, 162, 251, 89, 214, 35, 112, 200, 36, 23, 139, 132, 162, 251, + 89, 226, 87, 112, 200, 36, 23, 139, 132, 162, 46, 112, 200, 36, 23, 139, + 132, 112, 162, 241, 145, 232, 37, 23, 139, 132, 112, 162, 251, 89, 214, + 34, 23, 139, 132, 112, 162, 251, 88, 23, 139, 112, 162, 251, 89, 214, 35, + 132, 200, 36, 23, 139, 112, 162, 251, 89, 214, 35, 132, 241, 58, 23, 139, + 112, 162, 251, 89, 132, 200, 36, 23, 139, 132, 162, 231, 164, 112, 232, + 37, 23, 232, 197, 235, 7, 235, 122, 23, 232, 197, 235, 7, 235, 123, 248, + 217, 23, 232, 197, 235, 7, 235, 123, 232, 37, 23, 232, 197, 235, 7, 235, + 123, 241, 144, 23, 232, 197, 235, 7, 235, 123, 241, 145, 205, 112, 23, + 232, 204, 235, 7, 235, 123, 241, 144, 23, 139, 235, 7, 235, 123, 241, + 145, 248, 217, 23, 232, 195, 235, 7, 235, 123, 241, 144, 23, 232, 197, + 235, 101, 235, 123, 205, 102, 23, 232, 197, 232, 116, 235, 101, 235, 123, + 205, 102, 23, 232, 197, 235, 101, 235, 123, 205, 103, 235, 7, 248, 217, + 23, 232, 197, 232, 116, 235, 101, 235, 123, 205, 103, 235, 7, 248, 217, + 23, 232, 197, 235, 101, 235, 123, 205, 103, 248, 217, 23, 232, 197, 232, + 116, 235, 101, 235, 123, 205, 103, 248, 217, 23, 232, 197, 235, 101, 235, + 123, 205, 103, 162, 235, 11, 23, 232, 202, 235, 101, 235, 123, 205, 102, + 23, 232, 202, 235, 101, 235, 123, 205, 103, 214, 92, 23, 232, 195, 235, + 101, 235, 123, 205, 103, 214, 92, 23, 232, 191, 235, 101, 235, 123, 205, + 102, 23, 232, 197, 235, 101, 235, 123, 205, 103, 232, 37, 23, 232, 197, + 235, 101, 235, 123, 205, 103, 232, 38, 162, 206, 97, 23, 232, 197, 235, + 101, 235, 123, 205, 103, 232, 38, 216, 51, 202, 141, 23, 232, 196, 23, + 232, 197, 248, 204, 213, 207, 235, 225, 23, 232, 197, 232, 115, 23, 232, + 197, 162, 206, 97, 23, 232, 197, 232, 116, 162, 206, 97, 23, 232, 197, + 162, 248, 217, 23, 232, 197, 162, 235, 11, 23, 232, 197, 205, 113, 132, + 162, 206, 97, 23, 232, 197, 205, 113, 247, 36, 23, 232, 197, 205, 113, + 247, 37, 162, 206, 97, 23, 232, 197, 205, 113, 247, 37, 162, 206, 98, + 248, 217, 23, 232, 197, 205, 113, 222, 46, 23, 232, 203, 23, 232, 204, + 162, 206, 97, 23, 232, 204, 216, 51, 202, 141, 23, 232, 204, 162, 235, + 11, 23, 232, 193, 241, 20, 23, 232, 192, 23, 232, 202, 214, 92, 23, 232, + 201, 23, 232, 202, 192, 162, 206, 97, 23, 232, 202, 162, 206, 97, 23, + 232, 202, 192, 216, 51, 202, 141, 23, 232, 202, 216, 51, 202, 141, 23, + 232, 202, 192, 162, 235, 11, 23, 232, 202, 162, 235, 11, 23, 232, 200, + 214, 92, 23, 232, 199, 23, 232, 205, 23, 232, 190, 23, 232, 191, 162, + 206, 97, 23, 232, 191, 216, 51, 202, 141, 23, 232, 191, 162, 235, 11, 23, + 232, 195, 214, 92, 23, 232, 195, 192, 162, 235, 11, 23, 232, 194, 23, + 232, 195, 205, 224, 23, 232, 195, 192, 162, 206, 97, 23, 232, 195, 162, + 206, 97, 23, 232, 195, 192, 216, 51, 202, 141, 23, 232, 195, 216, 51, + 202, 141, 23, 232, 195, 162, 206, 98, 201, 225, 226, 72, 23, 232, 195, + 162, 248, 204, 112, 210, 2, 23, 232, 207, 23, 139, 132, 112, 210, 2, 23, + 232, 206, 132, 112, 210, 2, 23, 232, 195, 132, 112, 210, 2, 23, 232, 208, + 132, 112, 210, 2, 23, 232, 195, 222, 46, 23, 139, 132, 112, 210, 3, 248, + 217, 23, 139, 132, 112, 210, 3, 241, 144, 23, 232, 195, 132, 112, 210, 3, + 241, 144, 23, 139, 222, 47, 237, 235, 23, 139, 222, 47, 135, 209, 253, + 204, 217, 23, 139, 222, 47, 135, 209, 253, 241, 9, 23, 139, 222, 47, 135, + 214, 45, 244, 248, 23, 139, 222, 47, 200, 36, 23, 139, 162, 200, 64, 222, + 47, 200, 36, 23, 232, 206, 222, 47, 200, 36, 23, 232, 191, 222, 47, 200, + 36, 23, 232, 208, 222, 47, 200, 36, 23, 139, 222, 47, 210, 215, 224, 14, + 23, 139, 222, 47, 248, 217, 23, 139, 222, 47, 201, 226, 202, 141, 23, + 139, 222, 47, 202, 141, 23, 232, 195, 222, 47, 202, 141, 23, 139, 222, + 47, 132, 202, 141, 23, 232, 195, 222, 47, 132, 202, 141, 23, 232, 208, + 222, 47, 132, 162, 132, 162, 214, 34, 23, 232, 208, 222, 47, 132, 162, + 132, 202, 141, 23, 139, 222, 47, 226, 72, 23, 232, 206, 222, 47, 226, 72, + 23, 232, 195, 222, 47, 226, 72, 23, 232, 208, 222, 47, 226, 72, 23, 139, + 132, 112, 222, 46, 23, 232, 206, 132, 112, 222, 46, 23, 232, 195, 132, + 112, 222, 46, 23, 232, 195, 210, 2, 23, 232, 208, 132, 112, 222, 46, 23, + 139, 132, 112, 241, 62, 222, 46, 23, 232, 206, 132, 112, 241, 62, 222, + 46, 23, 139, 210, 3, 237, 235, 23, 232, 195, 210, 3, 135, 132, 162, 231, + 165, 219, 63, 23, 232, 208, 210, 3, 135, 112, 162, 132, 241, 61, 23, 139, + 210, 3, 200, 36, 23, 139, 210, 3, 210, 215, 224, 14, 23, 139, 210, 3, + 222, 46, 23, 232, 206, 210, 3, 222, 46, 23, 232, 191, 210, 3, 222, 46, + 23, 232, 208, 210, 3, 222, 46, 23, 139, 210, 3, 219, 63, 23, 139, 210, 3, + 112, 241, 144, 23, 139, 210, 3, 112, 210, 215, 224, 13, 23, 139, 210, 3, + 226, 72, 23, 139, 210, 3, 202, 141, 23, 232, 193, 210, 3, 202, 141, 23, + 139, 132, 210, 3, 222, 46, 23, 232, 206, 132, 210, 3, 222, 46, 23, 232, + 200, 132, 210, 3, 222, 47, 214, 119, 23, 232, 193, 132, 210, 3, 222, 47, + 214, 34, 23, 232, 193, 132, 210, 3, 222, 47, 226, 86, 23, 232, 193, 132, + 210, 3, 222, 47, 200, 63, 23, 232, 202, 132, 210, 3, 222, 46, 23, 232, + 195, 132, 210, 3, 222, 46, 23, 232, 208, 132, 210, 3, 222, 47, 214, 34, + 23, 232, 208, 132, 210, 3, 222, 46, 23, 139, 112, 237, 235, 23, 232, 195, + 219, 63, 23, 139, 112, 200, 36, 23, 232, 206, 112, 200, 36, 23, 139, 112, + 210, 215, 224, 14, 23, 139, 112, 124, 162, 206, 97, 23, 232, 193, 112, + 202, 141, 23, 139, 112, 162, 222, 46, 23, 139, 112, 222, 46, 23, 139, + 112, 210, 3, 222, 46, 23, 232, 206, 112, 210, 3, 222, 46, 23, 232, 200, + 112, 210, 3, 222, 47, 214, 119, 23, 232, 202, 112, 210, 3, 222, 46, 23, + 232, 195, 112, 210, 3, 222, 46, 23, 232, 208, 112, 210, 3, 222, 47, 214, + 34, 23, 232, 208, 112, 210, 3, 222, 47, 226, 86, 23, 232, 208, 112, 210, + 3, 222, 46, 23, 232, 206, 112, 210, 3, 222, 47, 248, 217, 23, 232, 204, + 112, 210, 3, 222, 47, 241, 144, 23, 232, 204, 112, 210, 3, 222, 47, 241, + 145, 206, 97, 23, 232, 193, 112, 210, 3, 222, 47, 241, 145, 214, 34, 23, + 232, 193, 112, 210, 3, 222, 47, 241, 145, 226, 86, 23, 232, 193, 112, + 210, 3, 222, 47, 241, 144, 23, 232, 195, 132, 232, 37, 23, 139, 132, 162, + 206, 97, 23, 232, 195, 132, 162, 206, 97, 23, 139, 132, 162, 206, 98, + 162, 239, 146, 23, 139, 132, 162, 206, 98, 162, 241, 144, 23, 139, 132, + 162, 206, 98, 162, 248, 217, 23, 139, 132, 162, 206, 98, 132, 248, 217, + 23, 139, 132, 162, 206, 98, 248, 88, 248, 217, 23, 139, 132, 162, 206, + 98, 132, 232, 39, 23, 139, 132, 162, 235, 12, 132, 204, 217, 23, 139, + 132, 162, 235, 12, 132, 248, 217, 23, 139, 132, 162, 122, 23, 139, 132, + 162, 241, 20, 23, 139, 132, 162, 241, 12, 162, 226, 41, 23, 232, 204, + 132, 162, 241, 12, 162, 226, 41, 23, 139, 132, 162, 241, 12, 162, 200, + 63, 23, 139, 132, 162, 244, 249, 23, 232, 202, 132, 202, 141, 23, 232, + 202, 132, 162, 214, 92, 23, 232, 195, 132, 162, 214, 92, 23, 232, 195, + 132, 162, 222, 227, 23, 232, 195, 132, 202, 141, 23, 232, 195, 132, 162, + 205, 224, 23, 232, 208, 132, 162, 214, 34, 23, 232, 208, 132, 162, 226, + 86, 23, 232, 208, 132, 202, 141, 23, 139, 202, 141, 23, 139, 162, 232, + 115, 23, 139, 162, 206, 98, 239, 146, 23, 139, 162, 206, 98, 241, 144, + 23, 139, 162, 206, 98, 248, 217, 23, 139, 162, 235, 11, 23, 139, 162, + 248, 204, 132, 219, 63, 23, 139, 162, 248, 204, 112, 210, 2, 23, 139, + 162, 248, 204, 210, 3, 222, 46, 23, 139, 162, 200, 64, 99, 235, 122, 23, + 139, 162, 127, 99, 235, 122, 23, 139, 162, 200, 64, 115, 235, 122, 23, + 139, 162, 200, 64, 235, 7, 235, 122, 23, 139, 162, 127, 235, 7, 210, 215, + 224, 13, 23, 232, 198, 23, 139, 232, 115, 23, 201, 227, 206, 61, 23, 201, + 227, 218, 119, 23, 201, 227, 248, 203, 23, 233, 105, 206, 61, 23, 233, + 105, 218, 119, 23, 233, 105, 248, 203, 23, 204, 201, 206, 61, 23, 204, + 201, 218, 119, 23, 204, 201, 248, 203, 23, 248, 29, 206, 61, 23, 248, 29, + 218, 119, 23, 248, 29, 248, 203, 23, 209, 132, 206, 61, 23, 209, 132, + 218, 119, 23, 209, 132, 248, 203, 23, 204, 84, 203, 249, 23, 204, 84, + 248, 203, 23, 205, 90, 222, 228, 206, 61, 23, 205, 90, 4, 206, 61, 23, + 205, 90, 222, 228, 218, 119, 23, 205, 90, 4, 218, 119, 23, 205, 90, 207, + 86, 23, 235, 73, 222, 228, 206, 61, 23, 235, 73, 4, 206, 61, 23, 235, 73, + 222, 228, 218, 119, 23, 235, 73, 4, 218, 119, 23, 235, 73, 207, 86, 23, + 205, 90, 235, 73, 251, 128, 23, 218, 157, 124, 135, 222, 227, 23, 218, + 157, 124, 135, 205, 224, 23, 218, 157, 124, 207, 86, 23, 218, 157, 135, + 207, 86, 23, 218, 157, 124, 135, 251, 129, 222, 227, 23, 218, 157, 124, + 135, 251, 129, 205, 224, 23, 218, 157, 206, 98, 202, 30, 206, 98, 208, + 161, 23, 218, 156, 235, 128, 241, 134, 23, 218, 158, 235, 128, 241, 134, + 23, 218, 156, 206, 62, 204, 218, 205, 224, 23, 218, 156, 206, 62, 204, + 218, 219, 189, 23, 218, 156, 206, 62, 204, 218, 222, 227, 23, 218, 156, + 206, 62, 204, 218, 222, 225, 23, 218, 156, 206, 62, 196, 247, 235, 76, + 23, 218, 156, 52, 204, 217, 23, 218, 156, 52, 196, 247, 235, 76, 23, 218, + 156, 52, 251, 128, 23, 218, 156, 52, 251, 129, 196, 247, 235, 76, 23, + 218, 156, 241, 61, 23, 218, 156, 201, 165, 204, 218, 218, 160, 23, 218, + 156, 201, 165, 196, 247, 235, 76, 23, 218, 156, 201, 165, 251, 128, 23, + 218, 156, 201, 165, 251, 129, 196, 247, 235, 76, 23, 218, 156, 248, 222, + 205, 224, 23, 218, 156, 248, 222, 219, 189, 23, 218, 156, 248, 222, 222, + 227, 23, 218, 156, 241, 102, 205, 224, 23, 218, 156, 241, 102, 219, 189, + 23, 218, 156, 241, 102, 222, 227, 23, 218, 156, 241, 102, 209, 192, 23, + 218, 156, 245, 102, 205, 224, 23, 218, 156, 245, 102, 219, 189, 23, 218, + 156, 245, 102, 222, 227, 23, 218, 156, 111, 205, 224, 23, 218, 156, 111, + 219, 189, 23, 218, 156, 111, 222, 227, 23, 218, 156, 195, 24, 205, 224, + 23, 218, 156, 195, 24, 219, 189, 23, 218, 156, 195, 24, 222, 227, 23, + 218, 156, 213, 87, 205, 224, 23, 218, 156, 213, 87, 219, 189, 23, 218, + 156, 213, 87, 222, 227, 23, 201, 195, 209, 190, 206, 61, 23, 201, 195, + 209, 190, 237, 245, 23, 201, 195, 209, 190, 251, 128, 23, 201, 195, 209, + 191, 206, 61, 23, 201, 195, 209, 191, 237, 245, 23, 201, 195, 209, 191, + 251, 128, 23, 201, 195, 207, 30, 23, 201, 195, 250, 232, 205, 121, 206, + 61, 23, 201, 195, 250, 232, 205, 121, 237, 245, 23, 201, 195, 250, 232, + 205, 121, 201, 164, 23, 218, 159, 250, 126, 205, 224, 23, 218, 159, 250, + 126, 219, 189, 23, 218, 159, 250, 126, 222, 227, 23, 218, 159, 250, 126, + 222, 225, 23, 218, 159, 201, 221, 205, 224, 23, 218, 159, 201, 221, 219, + 189, 23, 218, 159, 201, 221, 222, 227, 23, 218, 159, 201, 221, 222, 225, + 23, 218, 159, 248, 204, 250, 126, 205, 224, 23, 218, 159, 248, 204, 250, + 126, 219, 189, 23, 218, 159, 248, 204, 250, 126, 222, 227, 23, 218, 159, + 248, 204, 250, 126, 222, 225, 23, 218, 159, 248, 204, 201, 221, 205, 224, + 23, 218, 159, 248, 204, 201, 221, 219, 189, 23, 218, 159, 248, 204, 201, + 221, 222, 227, 23, 218, 159, 248, 204, 201, 221, 222, 225, 23, 218, 158, + 206, 62, 204, 218, 205, 224, 23, 218, 158, 206, 62, 204, 218, 219, 189, + 23, 218, 158, 206, 62, 204, 218, 222, 227, 23, 218, 158, 206, 62, 204, + 218, 222, 225, 23, 218, 158, 206, 62, 196, 247, 235, 76, 23, 218, 158, + 52, 204, 217, 23, 218, 158, 52, 196, 247, 235, 76, 23, 218, 158, 52, 251, + 128, 23, 218, 158, 52, 251, 129, 196, 247, 235, 76, 23, 218, 158, 241, + 61, 23, 218, 158, 201, 165, 204, 218, 218, 160, 23, 218, 158, 201, 165, + 196, 247, 235, 76, 23, 218, 158, 201, 165, 251, 129, 218, 160, 23, 218, + 158, 201, 165, 251, 129, 196, 247, 235, 76, 23, 218, 158, 248, 221, 23, + 218, 158, 241, 102, 205, 224, 23, 218, 158, 241, 102, 219, 189, 23, 218, + 158, 241, 102, 222, 227, 23, 218, 158, 245, 101, 23, 218, 158, 111, 205, + 224, 23, 218, 158, 111, 219, 189, 23, 218, 158, 111, 222, 227, 23, 218, + 158, 195, 24, 205, 224, 23, 218, 158, 195, 24, 219, 189, 23, 218, 158, + 195, 24, 222, 227, 23, 218, 158, 213, 87, 205, 224, 23, 218, 158, 213, + 87, 219, 189, 23, 218, 158, 213, 87, 222, 227, 23, 201, 196, 209, 191, + 206, 61, 23, 201, 196, 209, 191, 237, 245, 23, 201, 196, 209, 191, 251, + 128, 23, 201, 196, 209, 190, 206, 61, 23, 201, 196, 209, 190, 237, 245, + 23, 201, 196, 209, 190, 251, 128, 23, 201, 196, 207, 30, 23, 218, 156, + 241, 12, 211, 88, 205, 224, 23, 218, 156, 241, 12, 211, 88, 219, 189, 23, + 218, 156, 241, 12, 211, 88, 222, 227, 23, 218, 156, 241, 12, 211, 88, + 222, 225, 23, 218, 156, 241, 12, 232, 222, 205, 224, 23, 218, 156, 241, + 12, 232, 222, 219, 189, 23, 218, 156, 241, 12, 232, 222, 222, 227, 23, + 218, 156, 241, 12, 232, 222, 222, 225, 23, 218, 156, 241, 12, 202, 147, + 244, 250, 205, 224, 23, 218, 156, 241, 12, 202, 147, 244, 250, 219, 189, + 23, 218, 156, 231, 60, 205, 224, 23, 218, 156, 231, 60, 219, 189, 23, + 218, 156, 231, 60, 222, 227, 23, 218, 156, 221, 226, 205, 224, 23, 218, + 156, 221, 226, 219, 189, 23, 218, 156, 221, 226, 222, 227, 23, 218, 156, + 221, 226, 4, 237, 245, 23, 218, 156, 197, 123, 241, 12, 52, 205, 224, 23, + 218, 156, 197, 123, 241, 12, 52, 219, 189, 23, 218, 156, 197, 123, 241, + 12, 52, 222, 227, 23, 218, 156, 197, 123, 241, 12, 201, 165, 205, 224, + 23, 218, 156, 197, 123, 241, 12, 201, 165, 219, 189, 23, 218, 156, 197, + 123, 241, 12, 201, 165, 222, 227, 23, 218, 156, 241, 12, 202, 209, 204, + 217, 23, 218, 156, 241, 10, 241, 62, 205, 224, 23, 218, 156, 241, 10, + 241, 62, 219, 189, 23, 209, 190, 206, 61, 23, 209, 190, 237, 245, 23, + 209, 190, 251, 130, 23, 218, 156, 207, 30, 23, 218, 156, 241, 12, 232, + 30, 234, 234, 197, 148, 23, 218, 156, 231, 60, 232, 30, 234, 234, 197, + 148, 23, 218, 156, 221, 226, 232, 30, 234, 234, 197, 148, 23, 218, 156, + 197, 123, 232, 30, 234, 234, 197, 148, 23, 209, 190, 206, 62, 232, 30, + 234, 234, 197, 148, 23, 209, 190, 52, 232, 30, 234, 234, 197, 148, 23, + 209, 190, 251, 129, 232, 30, 234, 234, 197, 148, 23, 218, 156, 241, 12, + 232, 30, 245, 82, 23, 218, 156, 231, 60, 232, 30, 245, 82, 23, 218, 156, + 221, 226, 232, 30, 245, 82, 23, 218, 156, 197, 123, 232, 30, 245, 82, 23, + 209, 190, 206, 62, 232, 30, 245, 82, 23, 209, 190, 52, 232, 30, 245, 82, + 23, 209, 190, 251, 129, 232, 30, 245, 82, 23, 218, 156, 197, 123, 239, + 147, 213, 113, 205, 224, 23, 218, 156, 197, 123, 239, 147, 213, 113, 219, + 189, 23, 218, 156, 197, 123, 239, 147, 213, 113, 222, 227, 23, 218, 158, + 241, 12, 232, 30, 247, 46, 205, 224, 23, 218, 158, 241, 12, 232, 30, 247, + 46, 222, 227, 23, 218, 158, 231, 60, 232, 30, 247, 46, 4, 237, 245, 23, + 218, 158, 231, 60, 232, 30, 247, 46, 222, 228, 237, 245, 23, 218, 158, + 231, 60, 232, 30, 247, 46, 4, 201, 164, 23, 218, 158, 231, 60, 232, 30, + 247, 46, 222, 228, 201, 164, 23, 218, 158, 221, 226, 232, 30, 247, 46, 4, + 206, 61, 23, 218, 158, 221, 226, 232, 30, 247, 46, 222, 228, 206, 61, 23, + 218, 158, 221, 226, 232, 30, 247, 46, 4, 237, 245, 23, 218, 158, 221, + 226, 232, 30, 247, 46, 222, 228, 237, 245, 23, 218, 158, 197, 123, 232, + 30, 247, 46, 205, 224, 23, 218, 158, 197, 123, 232, 30, 247, 46, 222, + 227, 23, 209, 191, 206, 62, 232, 30, 247, 45, 23, 209, 191, 52, 232, 30, + 247, 45, 23, 209, 191, 251, 129, 232, 30, 247, 45, 23, 218, 158, 241, 12, + 232, 30, 235, 70, 205, 224, 23, 218, 158, 241, 12, 232, 30, 235, 70, 222, + 227, 23, 218, 158, 231, 60, 232, 30, 235, 70, 4, 237, 245, 23, 218, 158, + 231, 60, 232, 30, 235, 70, 222, 228, 237, 245, 23, 218, 158, 231, 60, + 232, 30, 235, 70, 201, 165, 4, 201, 164, 23, 218, 158, 231, 60, 232, 30, + 235, 70, 201, 165, 222, 228, 201, 164, 23, 218, 158, 221, 226, 232, 30, + 235, 70, 4, 206, 61, 23, 218, 158, 221, 226, 232, 30, 235, 70, 222, 228, + 206, 61, 23, 218, 158, 221, 226, 232, 30, 235, 70, 4, 237, 245, 23, 218, + 158, 221, 226, 232, 30, 235, 70, 222, 228, 237, 245, 23, 218, 158, 197, + 123, 232, 30, 235, 70, 205, 224, 23, 218, 158, 197, 123, 232, 30, 235, + 70, 222, 227, 23, 209, 191, 206, 62, 232, 30, 235, 69, 23, 209, 191, 52, + 232, 30, 235, 69, 23, 209, 191, 251, 129, 232, 30, 235, 69, 23, 218, 158, + 241, 12, 205, 224, 23, 218, 158, 241, 12, 219, 189, 23, 218, 158, 241, + 12, 222, 227, 23, 218, 158, 241, 12, 222, 225, 23, 218, 158, 241, 12, + 244, 163, 23, 218, 158, 231, 60, 205, 224, 23, 218, 158, 221, 226, 205, + 224, 23, 218, 158, 197, 123, 205, 212, 23, 218, 158, 197, 123, 205, 224, + 23, 218, 158, 197, 123, 222, 227, 23, 209, 191, 206, 61, 23, 209, 191, + 237, 245, 23, 209, 191, 251, 128, 23, 218, 158, 207, 31, 213, 145, 23, + 218, 156, 250, 232, 244, 250, 4, 206, 61, 23, 218, 156, 250, 232, 244, + 250, 219, 190, 206, 61, 23, 218, 156, 250, 232, 244, 250, 4, 237, 245, + 23, 218, 156, 250, 232, 244, 250, 219, 190, 237, 245, 23, 218, 158, 250, + 232, 244, 250, 232, 30, 197, 149, 4, 206, 61, 23, 218, 158, 250, 232, + 244, 250, 232, 30, 197, 149, 219, 190, 206, 61, 23, 218, 158, 250, 232, + 244, 250, 232, 30, 197, 149, 222, 228, 206, 61, 23, 218, 158, 250, 232, + 244, 250, 232, 30, 197, 149, 4, 237, 245, 23, 218, 158, 250, 232, 244, + 250, 232, 30, 197, 149, 219, 190, 237, 245, 23, 218, 158, 250, 232, 244, + 250, 232, 30, 197, 149, 222, 228, 237, 245, 23, 218, 156, 196, 247, 244, + 250, 234, 234, 206, 61, 23, 218, 156, 196, 247, 244, 250, 234, 234, 237, + 245, 23, 218, 158, 196, 247, 244, 250, 232, 30, 197, 149, 206, 61, 23, + 218, 158, 196, 247, 244, 250, 232, 30, 197, 149, 237, 245, 23, 218, 156, + 235, 128, 244, 247, 206, 61, 23, 218, 156, 235, 128, 244, 247, 237, 245, + 23, 218, 158, 235, 128, 244, 247, 232, 30, 197, 149, 206, 61, 23, 218, + 158, 235, 128, 244, 247, 232, 30, 197, 149, 237, 245, 23, 237, 161, 250, + 218, 205, 224, 23, 237, 161, 250, 218, 222, 227, 23, 237, 161, 235, 203, + 23, 237, 161, 205, 227, 23, 237, 161, 203, 16, 23, 237, 161, 210, 134, + 23, 237, 161, 206, 67, 23, 237, 161, 206, 68, 251, 128, 23, 237, 161, + 236, 99, 214, 46, 202, 78, 23, 237, 161, 233, 115, 23, 232, 137, 23, 232, + 138, 210, 7, 23, 232, 138, 218, 156, 204, 217, 23, 232, 138, 218, 156, + 202, 81, 23, 232, 138, 218, 158, 204, 217, 23, 232, 138, 218, 156, 241, + 11, 23, 232, 138, 218, 158, 241, 11, 23, 232, 138, 218, 161, 244, 249, + 23, 235, 234, 239, 85, 212, 79, 216, 21, 235, 12, 202, 79, 23, 235, 234, + 239, 85, 212, 79, 216, 21, 124, 214, 73, 237, 235, 23, 235, 234, 239, 85, + 212, 79, 216, 21, 124, 214, 73, 135, 202, 79, 23, 236, 65, 204, 218, 200, + 36, 23, 236, 65, 204, 218, 217, 84, 23, 236, 65, 204, 218, 237, 235, 23, + 237, 219, 236, 65, 217, 85, 237, 235, 23, 237, 219, 236, 65, 135, 217, + 84, 23, 237, 219, 236, 65, 124, 217, 84, 23, 237, 219, 236, 65, 217, 85, + 200, 36, 23, 235, 29, 217, 84, 23, 235, 29, 241, 134, 23, 235, 29, 196, + 250, 23, 236, 60, 214, 92, 23, 236, 60, 205, 89, 23, 236, 60, 244, 202, + 23, 236, 68, 248, 127, 206, 61, 23, 236, 68, 248, 127, 218, 119, 23, 236, + 60, 157, 214, 92, 23, 236, 60, 197, 62, 214, 92, 23, 236, 60, 157, 244, + 202, 23, 236, 60, 197, 60, 218, 160, 23, 236, 68, 197, 43, 23, 236, 61, + 200, 36, 23, 236, 61, 237, 235, 23, 236, 61, 235, 56, 23, 236, 63, 204, + 217, 23, 236, 63, 204, 218, 237, 245, 23, 236, 63, 204, 218, 251, 128, + 23, 236, 64, 204, 217, 23, 236, 64, 204, 218, 237, 245, 23, 236, 64, 204, + 218, 251, 128, 23, 236, 63, 241, 9, 23, 236, 64, 241, 9, 23, 236, 63, + 244, 244, 23, 245, 97, 211, 217, 23, 245, 97, 217, 84, 23, 245, 97, 204, + 131, 23, 203, 17, 245, 97, 232, 48, 23, 203, 17, 245, 97, 219, 63, 23, + 203, 17, 245, 97, 221, 208, 23, 237, 74, 23, 216, 21, 217, 84, 23, 216, + 21, 241, 134, 23, 216, 21, 196, 248, 23, 216, 21, 197, 57, 23, 251, 190, + 248, 120, 214, 34, 23, 251, 190, 204, 130, 226, 86, 23, 251, 190, 248, + 122, 4, 209, 189, 23, 251, 190, 204, 132, 4, 209, 189, 23, 248, 49, 226, + 58, 23, 248, 49, 236, 88, 23, 218, 165, 244, 203, 217, 84, 23, 218, 165, + 244, 203, 235, 11, 23, 218, 165, 244, 203, 241, 134, 23, 218, 165, 205, + 219, 23, 218, 165, 205, 220, 196, 250, 23, 218, 165, 205, 220, 214, 92, + 23, 218, 165, 234, 230, 23, 218, 165, 234, 231, 196, 250, 23, 218, 165, + 234, 231, 214, 92, 23, 218, 165, 192, 244, 249, 23, 218, 165, 192, 235, + 11, 23, 218, 165, 192, 196, 250, 23, 218, 165, 192, 214, 27, 23, 218, + 165, 192, 214, 28, 196, 250, 23, 218, 165, 192, 214, 28, 196, 77, 23, + 218, 165, 192, 210, 163, 23, 218, 165, 192, 210, 164, 196, 250, 23, 218, + 165, 192, 210, 164, 196, 77, 23, 218, 165, 224, 57, 23, 218, 165, 224, + 58, 235, 11, 23, 218, 165, 224, 58, 196, 250, 23, 218, 165, 203, 16, 23, + 218, 165, 203, 17, 235, 11, 23, 218, 165, 203, 17, 204, 131, 23, 222, 60, + 212, 23, 202, 19, 23, 222, 62, 221, 203, 127, 200, 32, 23, 222, 62, 200, + 33, 127, 221, 202, 23, 218, 165, 241, 100, 23, 218, 165, 196, 249, 206, + 61, 23, 218, 165, 196, 249, 237, 245, 23, 201, 250, 204, 237, 214, 35, + 235, 205, 23, 201, 250, 222, 105, 222, 59, 23, 201, 250, 202, 68, 248, + 204, 222, 59, 23, 201, 250, 202, 68, 201, 225, 226, 42, 218, 164, 23, + 201, 250, 226, 42, 218, 165, 210, 134, 23, 201, 250, 218, 155, 251, 215, + 245, 98, 23, 201, 250, 247, 37, 204, 237, 214, 34, 23, 201, 250, 247, 37, + 226, 42, 218, 164, 23, 203, 44, 23, 203, 45, 218, 160, 23, 203, 45, 214, + 120, 201, 249, 23, 203, 45, 214, 120, 201, 250, 218, 160, 23, 203, 45, + 214, 120, 222, 59, 23, 203, 45, 214, 120, 222, 60, 218, 160, 23, 203, 45, + 248, 143, 222, 59, 23, 218, 156, 225, 197, 23, 218, 158, 225, 197, 23, + 217, 109, 23, 232, 233, 23, 236, 91, 23, 206, 164, 232, 36, 205, 122, 23, + 206, 164, 232, 36, 212, 77, 23, 197, 147, 206, 164, 232, 36, 218, 163, + 23, 235, 68, 206, 164, 232, 36, 218, 163, 23, 206, 164, 202, 80, 234, + 235, 197, 153, 23, 201, 232, 204, 218, 204, 205, 23, 201, 232, 241, 10, + 248, 221, 23, 201, 233, 200, 218, 23, 200, 33, 248, 111, 202, 80, 234, + 235, 232, 36, 225, 123, 23, 222, 87, 244, 164, 23, 222, 87, 222, 157, 23, + 222, 87, 222, 156, 23, 222, 87, 222, 155, 23, 222, 87, 222, 154, 23, 222, + 87, 222, 153, 23, 222, 87, 222, 152, 23, 222, 87, 222, 151, 23, 235, 127, + 23, 222, 1, 205, 148, 23, 222, 2, 205, 148, 23, 222, 4, 232, 111, 23, + 222, 4, 197, 58, 23, 222, 4, 239, 199, 23, 222, 4, 232, 138, 217, 109, + 23, 222, 4, 201, 234, 23, 222, 4, 222, 86, 239, 117, 23, 244, 159, 23, + 234, 217, 204, 226, 23, 207, 105, 23, 244, 168, 23, 213, 140, 23, 235, + 137, 218, 227, 23, 235, 137, 218, 226, 23, 235, 137, 218, 225, 23, 235, + 137, 218, 224, 23, 235, 137, 218, 223, 23, 209, 193, 218, 227, 23, 209, + 193, 218, 226, 23, 209, 193, 218, 225, 23, 209, 193, 218, 224, 23, 209, + 193, 218, 223, 23, 209, 193, 218, 222, 23, 209, 193, 218, 221, 23, 209, + 193, 218, 220, 23, 209, 193, 218, 234, 23, 209, 193, 218, 233, 23, 209, + 193, 218, 232, 23, 209, 193, 218, 231, 23, 209, 193, 218, 230, 23, 209, + 193, 218, 229, 23, 209, 193, 218, 228, 38, 125, 1, 250, 113, 38, 125, 1, + 248, 9, 38, 125, 1, 199, 116, 38, 125, 1, 233, 159, 38, 125, 1, 239, 23, + 38, 125, 1, 196, 38, 38, 125, 1, 195, 58, 38, 125, 1, 195, 84, 38, 125, + 1, 225, 221, 38, 125, 1, 84, 225, 221, 38, 125, 1, 68, 38, 125, 1, 239, + 44, 38, 125, 1, 225, 23, 38, 125, 1, 222, 39, 38, 125, 1, 218, 59, 38, + 125, 1, 217, 206, 38, 125, 1, 214, 104, 38, 125, 1, 212, 104, 38, 125, 1, + 209, 249, 38, 125, 1, 205, 229, 38, 125, 1, 200, 246, 38, 125, 1, 200, + 83, 38, 125, 1, 234, 238, 38, 125, 1, 232, 91, 38, 125, 1, 206, 154, 38, + 125, 1, 201, 92, 38, 125, 1, 245, 36, 38, 125, 1, 207, 50, 38, 125, 1, + 196, 47, 38, 125, 1, 196, 49, 38, 125, 1, 196, 82, 38, 125, 1, 195, 217, + 38, 125, 1, 4, 195, 182, 38, 125, 1, 196, 3, 38, 125, 1, 226, 6, 4, 195, + 182, 38, 125, 1, 248, 171, 195, 182, 38, 125, 1, 226, 6, 248, 171, 195, + 182, 38, 125, 1, 235, 103, 215, 88, 211, 224, 86, 1, 166, 215, 88, 211, + 224, 86, 1, 201, 113, 215, 88, 211, 224, 86, 1, 215, 207, 215, 88, 211, + 224, 86, 1, 189, 215, 88, 211, 224, 86, 1, 142, 215, 88, 211, 224, 86, 1, + 176, 215, 88, 211, 224, 86, 1, 196, 208, 215, 88, 211, 224, 86, 1, 216, + 118, 215, 88, 211, 224, 86, 1, 247, 174, 215, 88, 211, 224, 86, 1, 172, + 215, 88, 211, 224, 86, 1, 183, 215, 88, 211, 224, 86, 1, 195, 115, 215, + 88, 211, 224, 86, 1, 217, 163, 215, 88, 211, 224, 86, 1, 215, 194, 215, + 88, 211, 224, 86, 1, 155, 215, 88, 211, 224, 86, 1, 240, 136, 215, 88, + 211, 224, 86, 1, 215, 109, 215, 88, 211, 224, 86, 1, 215, 252, 215, 88, + 211, 224, 86, 1, 199, 152, 215, 88, 211, 224, 86, 1, 215, 188, 215, 88, + 211, 224, 86, 1, 200, 210, 215, 88, 211, 224, 86, 1, 235, 239, 215, 88, + 211, 224, 86, 1, 169, 215, 88, 211, 224, 86, 1, 211, 159, 215, 88, 211, + 224, 86, 1, 164, 215, 88, 211, 224, 86, 1, 215, 254, 215, 88, 211, 224, + 86, 1, 161, 215, 88, 211, 224, 86, 1, 196, 164, 215, 88, 211, 224, 86, 1, + 216, 0, 215, 88, 211, 224, 86, 1, 239, 40, 215, 88, 211, 224, 86, 1, 215, + 255, 215, 88, 211, 224, 86, 1, 232, 236, 215, 88, 211, 224, 86, 1, 219, + 2, 215, 88, 211, 224, 86, 1, 212, 150, 215, 88, 211, 224, 86, 1, 234, + 123, 215, 88, 211, 224, 86, 1, 209, 181, 215, 88, 211, 224, 86, 1, 63, + 215, 88, 211, 224, 86, 1, 252, 168, 215, 88, 211, 224, 86, 1, 68, 215, + 88, 211, 224, 86, 1, 66, 215, 88, 211, 224, 86, 1, 72, 215, 88, 211, 224, + 86, 1, 214, 102, 215, 88, 211, 224, 86, 1, 69, 215, 88, 211, 224, 86, 1, + 237, 54, 215, 88, 211, 224, 86, 1, 197, 199, 215, 88, 211, 224, 86, 202, + 2, 215, 88, 211, 224, 86, 201, 254, 215, 88, 211, 224, 86, 201, 255, 215, + 88, 211, 224, 86, 201, 252, 215, 88, 211, 224, 86, 201, 253, 215, 88, + 211, 224, 86, 202, 0, 215, 88, 211, 224, 86, 202, 1, 215, 88, 211, 224, + 86, 2, 36, 213, 28, 215, 88, 211, 224, 86, 2, 36, 202, 187, 215, 88, 211, + 224, 86, 2, 36, 222, 3, 215, 88, 211, 224, 86, 2, 36, 251, 81, 215, 88, + 211, 224, 86, 2, 36, 226, 18, 215, 88, 211, 224, 86, 2, 196, 172, 196, + 171, 215, 88, 211, 224, 86, 5, 222, 150, 215, 88, 211, 224, 86, 17, 195, + 79, 215, 88, 211, 224, 86, 17, 100, 215, 88, 211, 224, 86, 17, 102, 215, + 88, 211, 224, 86, 17, 134, 215, 88, 211, 224, 86, 17, 136, 215, 88, 211, + 224, 86, 17, 146, 215, 88, 211, 224, 86, 17, 167, 215, 88, 211, 224, 86, + 17, 178, 215, 88, 211, 224, 86, 17, 171, 215, 88, 211, 224, 86, 17, 182, + 215, 88, 211, 224, 86, 221, 248, 215, 104, 215, 88, 211, 224, 86, 46, + 247, 174, 197, 145, 1, 252, 168, 197, 145, 1, 63, 197, 145, 1, 249, 145, + 197, 145, 1, 247, 174, 197, 145, 1, 240, 136, 197, 145, 1, 234, 123, 197, + 145, 1, 164, 197, 145, 1, 213, 6, 197, 145, 1, 172, 197, 145, 1, 176, + 197, 145, 1, 161, 197, 145, 1, 189, 197, 145, 1, 202, 233, 197, 145, 1, + 235, 239, 197, 145, 1, 183, 197, 145, 1, 207, 50, 197, 145, 1, 225, 214, + 197, 145, 1, 195, 115, 197, 145, 1, 197, 166, 197, 145, 1, 199, 152, 197, + 145, 1, 155, 197, 145, 1, 72, 197, 145, 1, 250, 150, 197, 145, 1, 169, + 197, 145, 1, 166, 197, 145, 1, 224, 146, 197, 145, 1, 142, 197, 145, 1, + 69, 197, 145, 1, 68, 197, 145, 1, 217, 71, 197, 145, 1, 66, 197, 145, 1, + 222, 30, 197, 145, 1, 201, 113, 197, 145, 1, 201, 217, 197, 145, 1, 214, + 109, 197, 145, 1, 252, 127, 197, 145, 1, 251, 97, 197, 145, 1, 226, 60, + 197, 145, 1, 214, 119, 197, 145, 1, 236, 230, 197, 145, 1, 252, 128, 197, + 145, 1, 215, 109, 197, 145, 1, 200, 95, 197, 145, 1, 196, 15, 197, 145, + 152, 201, 13, 197, 145, 152, 201, 12, 197, 145, 152, 223, 255, 197, 145, + 152, 223, 254, 197, 145, 17, 195, 79, 197, 145, 17, 100, 197, 145, 17, + 102, 197, 145, 17, 134, 197, 145, 17, 136, 197, 145, 17, 146, 197, 145, + 17, 167, 197, 145, 17, 178, 197, 145, 17, 171, 197, 145, 17, 182, 197, + 145, 216, 235, 55, 81, 80, 5, 221, 135, 224, 101, 81, 80, 5, 221, 131, + 155, 81, 80, 5, 221, 129, 223, 187, 81, 80, 5, 221, 5, 224, 200, 81, 80, + 5, 220, 231, 224, 209, 81, 80, 5, 220, 250, 223, 242, 81, 80, 5, 221, 22, + 224, 11, 81, 80, 5, 220, 147, 223, 174, 81, 80, 5, 221, 126, 197, 70, 81, + 80, 5, 221, 124, 197, 166, 81, 80, 5, 221, 122, 196, 243, 81, 80, 5, 220, + 200, 197, 98, 81, 80, 5, 220, 208, 197, 109, 81, 80, 5, 220, 212, 197, + 15, 81, 80, 5, 221, 25, 197, 34, 81, 80, 5, 220, 132, 196, 239, 81, 80, + 5, 220, 183, 197, 96, 81, 80, 5, 221, 9, 196, 227, 81, 80, 5, 221, 21, + 196, 229, 81, 80, 5, 220, 187, 196, 228, 81, 80, 5, 221, 120, 219, 23, + 81, 80, 5, 221, 118, 220, 62, 81, 80, 5, 221, 116, 218, 113, 81, 80, 5, + 221, 11, 219, 164, 81, 80, 5, 220, 232, 218, 215, 81, 80, 5, 220, 172, + 218, 138, 81, 80, 5, 220, 137, 218, 132, 81, 80, 5, 221, 114, 248, 184, + 81, 80, 5, 221, 111, 249, 145, 81, 80, 5, 221, 109, 248, 21, 81, 80, 5, + 220, 176, 248, 251, 81, 80, 5, 220, 229, 249, 9, 81, 80, 5, 220, 223, + 248, 103, 81, 80, 5, 220, 188, 248, 116, 81, 80, 5, 221, 99, 68, 81, 80, + 5, 221, 97, 63, 81, 80, 5, 221, 95, 66, 81, 80, 5, 220, 163, 237, 54, 81, + 80, 5, 220, 226, 69, 81, 80, 5, 220, 161, 214, 102, 81, 80, 5, 220, 179, + 72, 81, 80, 5, 220, 189, 237, 33, 81, 80, 5, 220, 195, 226, 86, 81, 80, + 5, 220, 191, 226, 86, 81, 80, 5, 220, 131, 251, 106, 81, 80, 5, 220, 148, + 236, 230, 81, 80, 5, 221, 84, 206, 112, 81, 80, 5, 221, 82, 183, 81, 80, + 5, 221, 80, 204, 172, 81, 80, 5, 220, 164, 208, 129, 81, 80, 5, 220, 210, + 208, 147, 81, 80, 5, 220, 190, 205, 171, 81, 80, 5, 220, 247, 205, 200, + 81, 80, 5, 220, 130, 206, 105, 81, 80, 5, 221, 70, 222, 109, 81, 80, 5, + 221, 68, 172, 81, 80, 5, 221, 66, 221, 191, 81, 80, 5, 220, 242, 222, + 188, 81, 80, 5, 220, 253, 222, 197, 81, 80, 5, 221, 16, 221, 229, 81, 80, + 5, 220, 173, 222, 7, 81, 80, 5, 220, 216, 181, 222, 197, 81, 80, 5, 221, + 92, 239, 152, 81, 80, 5, 221, 89, 240, 136, 81, 80, 5, 221, 86, 237, 201, + 81, 80, 5, 220, 237, 239, 237, 81, 80, 5, 220, 146, 239, 3, 81, 80, 5, + 220, 145, 239, 28, 81, 80, 5, 221, 78, 202, 122, 81, 80, 5, 221, 75, 189, + 81, 80, 5, 221, 73, 201, 40, 81, 80, 5, 220, 235, 203, 48, 81, 80, 5, + 221, 15, 203, 68, 81, 80, 5, 220, 222, 201, 247, 81, 80, 5, 221, 1, 149, + 81, 80, 5, 221, 64, 225, 172, 81, 80, 5, 221, 61, 225, 214, 81, 80, 5, + 221, 59, 225, 110, 81, 80, 5, 220, 169, 225, 191, 81, 80, 5, 220, 213, + 225, 193, 81, 80, 5, 220, 166, 225, 119, 81, 80, 5, 221, 7, 225, 129, 81, + 80, 5, 220, 151, 181, 225, 129, 81, 80, 5, 221, 57, 196, 24, 81, 80, 5, + 221, 54, 164, 81, 80, 5, 221, 52, 195, 217, 81, 80, 5, 220, 217, 196, 66, + 81, 80, 5, 220, 246, 196, 69, 81, 80, 5, 220, 185, 195, 237, 81, 80, 5, + 220, 205, 196, 3, 81, 80, 5, 221, 48, 235, 153, 81, 80, 5, 221, 46, 235, + 239, 81, 80, 5, 221, 44, 234, 223, 81, 80, 5, 220, 248, 235, 182, 81, 80, + 5, 220, 251, 235, 189, 81, 80, 5, 220, 193, 235, 40, 81, 80, 5, 220, 238, + 235, 51, 81, 80, 5, 220, 129, 234, 222, 81, 80, 5, 220, 225, 235, 210, + 81, 80, 5, 221, 42, 216, 183, 81, 80, 5, 221, 40, 217, 221, 81, 80, 5, + 221, 38, 215, 138, 81, 80, 5, 220, 209, 217, 101, 81, 80, 5, 220, 157, + 216, 38, 81, 80, 5, 220, 150, 232, 71, 81, 80, 5, 221, 33, 142, 81, 80, + 5, 220, 140, 231, 75, 81, 80, 5, 221, 36, 232, 118, 81, 80, 5, 220, 230, + 232, 147, 81, 80, 5, 221, 31, 231, 166, 81, 80, 5, 220, 186, 231, 193, + 81, 80, 5, 220, 243, 232, 117, 81, 80, 5, 220, 198, 231, 159, 81, 80, 5, + 221, 17, 232, 41, 81, 80, 5, 220, 196, 232, 212, 81, 80, 5, 220, 239, + 231, 59, 81, 80, 5, 221, 18, 232, 101, 81, 80, 5, 220, 133, 231, 169, 81, + 80, 5, 221, 24, 231, 71, 81, 80, 5, 220, 236, 217, 36, 81, 80, 5, 221, + 29, 217, 50, 81, 80, 5, 220, 244, 217, 33, 81, 80, 5, 220, 211, 217, 44, + 81, 80, 5, 220, 180, 217, 45, 81, 80, 5, 220, 170, 217, 34, 81, 80, 5, + 220, 206, 217, 35, 81, 80, 5, 220, 167, 217, 49, 81, 80, 5, 220, 199, + 217, 32, 81, 80, 5, 220, 240, 181, 217, 45, 81, 80, 5, 220, 220, 181, + 217, 34, 81, 80, 5, 220, 143, 181, 217, 35, 81, 80, 5, 220, 171, 233, + 192, 81, 80, 5, 220, 215, 234, 123, 81, 80, 5, 220, 158, 233, 76, 81, 80, + 5, 220, 136, 234, 40, 81, 80, 5, 220, 160, 233, 62, 81, 80, 5, 220, 159, + 233, 72, 81, 80, 5, 220, 142, 217, 55, 81, 80, 5, 221, 13, 216, 248, 81, + 80, 5, 220, 149, 216, 237, 81, 80, 5, 221, 2, 212, 220, 81, 80, 5, 220, + 227, 161, 81, 80, 5, 221, 20, 211, 227, 81, 80, 5, 220, 245, 213, 79, 81, + 80, 5, 221, 19, 213, 92, 81, 80, 5, 220, 224, 212, 91, 81, 80, 5, 221, 4, + 212, 117, 81, 80, 5, 220, 181, 219, 226, 81, 80, 5, 221, 8, 219, 241, 81, + 80, 5, 220, 204, 219, 220, 81, 80, 5, 221, 23, 219, 233, 81, 80, 5, 220, + 138, 219, 233, 81, 80, 5, 220, 254, 219, 234, 81, 80, 5, 220, 154, 219, + 221, 81, 80, 5, 220, 152, 219, 222, 81, 80, 5, 220, 139, 219, 214, 81, + 80, 5, 220, 165, 181, 219, 234, 81, 80, 5, 220, 221, 181, 219, 221, 81, + 80, 5, 220, 184, 181, 219, 222, 81, 80, 5, 220, 194, 223, 215, 81, 80, 5, + 220, 234, 223, 223, 81, 80, 5, 220, 252, 223, 211, 81, 80, 5, 221, 27, + 223, 218, 81, 80, 5, 220, 218, 223, 219, 81, 80, 5, 220, 214, 223, 213, + 81, 80, 5, 220, 168, 223, 214, 81, 80, 5, 220, 202, 234, 57, 81, 80, 5, + 221, 14, 234, 65, 81, 80, 5, 220, 178, 234, 52, 81, 80, 5, 220, 233, 234, + 61, 81, 80, 5, 220, 219, 234, 62, 81, 80, 5, 220, 255, 234, 53, 81, 80, + 5, 221, 0, 234, 55, 81, 80, 5, 220, 155, 169, 81, 80, 5, 220, 203, 217, + 144, 81, 80, 5, 220, 197, 217, 159, 81, 80, 5, 220, 201, 217, 126, 81, + 80, 5, 220, 135, 217, 150, 81, 80, 5, 220, 207, 217, 151, 81, 80, 5, 221, + 3, 217, 131, 81, 80, 5, 221, 6, 217, 135, 81, 80, 5, 220, 174, 216, 164, + 81, 80, 5, 220, 134, 216, 134, 81, 80, 5, 220, 177, 216, 155, 81, 80, 5, + 220, 192, 216, 138, 81, 80, 5, 220, 144, 199, 34, 81, 80, 5, 220, 141, + 199, 152, 81, 80, 5, 220, 175, 197, 220, 81, 80, 5, 220, 153, 199, 113, + 81, 80, 5, 220, 241, 199, 118, 81, 80, 5, 220, 182, 198, 233, 81, 80, 5, + 220, 249, 198, 248, 81, 80, 5, 220, 162, 215, 82, 81, 80, 5, 221, 12, + 215, 102, 81, 80, 5, 220, 156, 215, 64, 81, 80, 5, 220, 228, 215, 94, 81, + 80, 5, 221, 10, 215, 71, 81, 80, 17, 100, 81, 80, 17, 102, 81, 80, 17, + 134, 81, 80, 17, 136, 81, 80, 17, 146, 81, 80, 17, 167, 81, 80, 17, 178, + 81, 80, 17, 171, 81, 80, 17, 182, 81, 80, 38, 31, 203, 46, 81, 80, 38, + 31, 203, 18, 81, 80, 38, 31, 231, 55, 81, 80, 38, 31, 202, 157, 81, 80, + 38, 31, 203, 24, 202, 157, 81, 80, 38, 31, 231, 58, 202, 157, 81, 80, 38, + 31, 219, 26, 251, 253, 6, 1, 251, 152, 251, 253, 6, 1, 240, 133, 251, + 253, 6, 1, 223, 80, 251, 253, 6, 1, 219, 39, 251, 253, 6, 1, 249, 145, + 251, 253, 6, 1, 206, 56, 251, 253, 6, 1, 213, 92, 251, 253, 6, 1, 248, + 192, 251, 253, 6, 1, 169, 251, 253, 6, 1, 69, 251, 253, 6, 1, 235, 239, + 251, 253, 6, 1, 68, 251, 253, 6, 1, 72, 251, 253, 6, 1, 239, 176, 251, + 253, 6, 1, 196, 25, 251, 253, 6, 1, 197, 117, 251, 253, 6, 1, 215, 138, + 251, 253, 6, 1, 225, 35, 251, 253, 6, 1, 164, 251, 253, 6, 1, 66, 251, + 253, 6, 1, 225, 163, 251, 253, 6, 1, 245, 75, 251, 253, 6, 1, 142, 251, + 253, 6, 1, 211, 157, 251, 253, 6, 1, 234, 123, 251, 253, 6, 1, 215, 109, + 251, 253, 6, 1, 201, 40, 251, 253, 6, 1, 216, 227, 251, 253, 6, 1, 199, + 152, 251, 253, 6, 1, 224, 146, 251, 253, 6, 1, 234, 62, 251, 253, 6, 1, + 195, 104, 251, 253, 6, 1, 223, 214, 251, 253, 6, 1, 207, 50, 251, 253, 4, + 1, 251, 152, 251, 253, 4, 1, 240, 133, 251, 253, 4, 1, 223, 80, 251, 253, + 4, 1, 219, 39, 251, 253, 4, 1, 249, 145, 251, 253, 4, 1, 206, 56, 251, + 253, 4, 1, 213, 92, 251, 253, 4, 1, 248, 192, 251, 253, 4, 1, 169, 251, + 253, 4, 1, 69, 251, 253, 4, 1, 235, 239, 251, 253, 4, 1, 68, 251, 253, 4, + 1, 72, 251, 253, 4, 1, 239, 176, 251, 253, 4, 1, 196, 25, 251, 253, 4, 1, + 197, 117, 251, 253, 4, 1, 215, 138, 251, 253, 4, 1, 225, 35, 251, 253, 4, + 1, 164, 251, 253, 4, 1, 66, 251, 253, 4, 1, 225, 163, 251, 253, 4, 1, + 245, 75, 251, 253, 4, 1, 142, 251, 253, 4, 1, 211, 157, 251, 253, 4, 1, + 234, 123, 251, 253, 4, 1, 215, 109, 251, 253, 4, 1, 201, 40, 251, 253, 4, + 1, 216, 227, 251, 253, 4, 1, 199, 152, 251, 253, 4, 1, 224, 146, 251, + 253, 4, 1, 234, 62, 251, 253, 4, 1, 195, 104, 251, 253, 4, 1, 223, 214, + 251, 253, 4, 1, 207, 50, 251, 253, 251, 153, 222, 150, 251, 253, 18, 222, + 150, 251, 253, 234, 36, 78, 251, 253, 232, 213, 251, 253, 108, 218, 235, + 251, 253, 234, 37, 108, 218, 235, 251, 253, 215, 149, 251, 253, 217, 208, + 78, 251, 253, 17, 195, 79, 251, 253, 17, 100, 251, 253, 17, 102, 251, + 253, 17, 134, 251, 253, 17, 136, 251, 253, 17, 146, 251, 253, 17, 167, + 251, 253, 17, 178, 251, 253, 17, 171, 251, 253, 17, 182, 251, 253, 84, + 236, 90, 78, 251, 253, 84, 211, 79, 78, 226, 70, 128, 31, 100, 226, 70, + 128, 31, 102, 226, 70, 128, 31, 134, 226, 70, 128, 31, 136, 226, 70, 128, + 31, 146, 226, 70, 128, 31, 167, 226, 70, 128, 31, 178, 226, 70, 128, 31, + 171, 226, 70, 128, 31, 182, 226, 70, 128, 31, 203, 23, 226, 70, 128, 31, + 200, 234, 226, 70, 128, 31, 202, 177, 226, 70, 128, 31, 235, 14, 226, 70, + 128, 31, 235, 145, 226, 70, 128, 31, 206, 13, 226, 70, 128, 31, 207, 65, + 226, 70, 128, 31, 237, 20, 226, 70, 128, 31, 216, 174, 226, 70, 128, 31, + 97, 231, 57, 226, 70, 128, 31, 99, 231, 57, 226, 70, 128, 31, 115, 231, + 57, 226, 70, 128, 31, 235, 7, 231, 57, 226, 70, 128, 31, 235, 101, 231, + 57, 226, 70, 128, 31, 206, 29, 231, 57, 226, 70, 128, 31, 207, 71, 231, + 57, 226, 70, 128, 31, 237, 31, 231, 57, 226, 70, 128, 31, 216, 179, 231, + 57, 226, 70, 128, 31, 97, 170, 226, 70, 128, 31, 99, 170, 226, 70, 128, + 31, 115, 170, 226, 70, 128, 31, 235, 7, 170, 226, 70, 128, 31, 235, 101, + 170, 226, 70, 128, 31, 206, 29, 170, 226, 70, 128, 31, 207, 71, 170, 226, + 70, 128, 31, 237, 31, 170, 226, 70, 128, 31, 216, 179, 170, 226, 70, 128, + 31, 203, 24, 170, 226, 70, 128, 31, 200, 235, 170, 226, 70, 128, 31, 202, + 178, 170, 226, 70, 128, 31, 235, 15, 170, 226, 70, 128, 31, 235, 146, + 170, 226, 70, 128, 31, 206, 14, 170, 226, 70, 128, 31, 207, 66, 170, 226, + 70, 128, 31, 237, 21, 170, 226, 70, 128, 31, 216, 175, 170, 226, 70, 128, + 31, 222, 255, 226, 70, 128, 31, 222, 254, 226, 70, 128, 223, 0, 78, 226, + 70, 128, 31, 224, 246, 226, 70, 128, 31, 224, 245, 226, 70, 128, 31, 212, + 31, 100, 226, 70, 128, 31, 212, 31, 102, 226, 70, 128, 31, 212, 31, 134, + 226, 70, 128, 31, 212, 31, 136, 226, 70, 128, 31, 212, 31, 146, 226, 70, + 128, 31, 212, 31, 167, 226, 70, 128, 31, 212, 31, 178, 226, 70, 128, 31, + 212, 31, 171, 226, 70, 128, 31, 212, 31, 182, 226, 70, 128, 212, 147, + 226, 70, 128, 191, 97, 211, 87, 226, 70, 128, 191, 97, 232, 225, 226, 70, + 128, 191, 115, 211, 85, 226, 70, 128, 209, 108, 78, 226, 70, 128, 31, + 251, 131, 100, 226, 70, 128, 31, 251, 131, 102, 226, 70, 128, 31, 251, + 131, 203, 24, 170, 226, 70, 128, 251, 131, 223, 0, 78, 214, 41, 128, 31, + 100, 214, 41, 128, 31, 102, 214, 41, 128, 31, 134, 214, 41, 128, 31, 136, + 214, 41, 128, 31, 146, 214, 41, 128, 31, 167, 214, 41, 128, 31, 178, 214, + 41, 128, 31, 171, 214, 41, 128, 31, 182, 214, 41, 128, 31, 203, 23, 214, + 41, 128, 31, 200, 234, 214, 41, 128, 31, 202, 177, 214, 41, 128, 31, 235, + 14, 214, 41, 128, 31, 235, 145, 214, 41, 128, 31, 206, 13, 214, 41, 128, + 31, 207, 65, 214, 41, 128, 31, 237, 20, 214, 41, 128, 31, 216, 174, 214, + 41, 128, 31, 97, 231, 57, 214, 41, 128, 31, 99, 231, 57, 214, 41, 128, + 31, 115, 231, 57, 214, 41, 128, 31, 235, 7, 231, 57, 214, 41, 128, 31, + 235, 101, 231, 57, 214, 41, 128, 31, 206, 29, 231, 57, 214, 41, 128, 31, + 207, 71, 231, 57, 214, 41, 128, 31, 237, 31, 231, 57, 214, 41, 128, 31, + 216, 179, 231, 57, 214, 41, 128, 31, 97, 170, 214, 41, 128, 31, 99, 170, + 214, 41, 128, 31, 115, 170, 214, 41, 128, 31, 235, 7, 170, 214, 41, 128, + 31, 235, 101, 170, 214, 41, 128, 31, 206, 29, 170, 214, 41, 128, 31, 207, + 71, 170, 214, 41, 128, 31, 237, 31, 170, 214, 41, 128, 31, 216, 179, 170, + 214, 41, 128, 31, 203, 24, 170, 214, 41, 128, 31, 200, 235, 170, 214, 41, + 128, 31, 202, 178, 170, 214, 41, 128, 31, 235, 15, 170, 214, 41, 128, 31, + 235, 146, 170, 214, 41, 128, 31, 206, 14, 170, 214, 41, 128, 31, 207, 66, + 170, 214, 41, 128, 31, 237, 21, 170, 214, 41, 128, 31, 216, 175, 170, + 214, 41, 128, 220, 22, 214, 41, 128, 251, 131, 31, 102, 214, 41, 128, + 251, 131, 31, 134, 214, 41, 128, 251, 131, 31, 136, 214, 41, 128, 251, + 131, 31, 146, 214, 41, 128, 251, 131, 31, 167, 214, 41, 128, 251, 131, + 31, 178, 214, 41, 128, 251, 131, 31, 171, 214, 41, 128, 251, 131, 31, + 182, 214, 41, 128, 251, 131, 31, 203, 23, 214, 41, 128, 251, 131, 31, + 235, 7, 231, 57, 214, 41, 128, 251, 131, 31, 206, 29, 231, 57, 214, 41, + 128, 251, 131, 31, 99, 170, 214, 41, 128, 251, 131, 31, 203, 24, 170, + 214, 41, 128, 191, 97, 232, 225, 214, 41, 128, 191, 97, 206, 17, 9, 13, + 251, 164, 9, 13, 248, 239, 9, 13, 225, 189, 9, 13, 240, 107, 9, 13, 197, + 117, 9, 13, 195, 106, 9, 13, 232, 236, 9, 13, 203, 139, 9, 13, 196, 64, + 9, 13, 225, 35, 9, 13, 222, 249, 9, 13, 219, 185, 9, 13, 216, 31, 9, 13, + 208, 125, 9, 13, 251, 194, 9, 13, 235, 176, 9, 13, 209, 8, 9, 13, 211, + 152, 9, 13, 210, 142, 9, 13, 206, 251, 9, 13, 203, 41, 9, 13, 202, 213, + 9, 13, 224, 142, 9, 13, 202, 225, 9, 13, 240, 130, 9, 13, 195, 109, 9, + 13, 233, 225, 9, 13, 238, 252, 248, 239, 9, 13, 238, 252, 216, 31, 9, 13, + 238, 252, 235, 176, 9, 13, 238, 252, 211, 152, 9, 13, 84, 248, 239, 9, + 13, 84, 225, 189, 9, 13, 84, 232, 113, 9, 13, 84, 232, 236, 9, 13, 84, + 196, 64, 9, 13, 84, 225, 35, 9, 13, 84, 222, 249, 9, 13, 84, 219, 185, 9, + 13, 84, 216, 31, 9, 13, 84, 208, 125, 9, 13, 84, 251, 194, 9, 13, 84, + 235, 176, 9, 13, 84, 209, 8, 9, 13, 84, 211, 152, 9, 13, 84, 206, 251, 9, + 13, 84, 203, 41, 9, 13, 84, 202, 213, 9, 13, 84, 224, 142, 9, 13, 84, + 240, 130, 9, 13, 84, 233, 225, 9, 13, 203, 134, 225, 189, 9, 13, 203, + 134, 232, 236, 9, 13, 203, 134, 196, 64, 9, 13, 203, 134, 222, 249, 9, + 13, 203, 134, 216, 31, 9, 13, 203, 134, 208, 125, 9, 13, 203, 134, 251, + 194, 9, 13, 203, 134, 209, 8, 9, 13, 203, 134, 211, 152, 9, 13, 203, 134, + 206, 251, 9, 13, 203, 134, 224, 142, 9, 13, 203, 134, 240, 130, 9, 13, + 203, 134, 233, 225, 9, 13, 203, 134, 238, 252, 216, 31, 9, 13, 203, 134, + 238, 252, 211, 152, 9, 13, 204, 204, 248, 239, 9, 13, 204, 204, 225, 189, + 9, 13, 204, 204, 232, 113, 9, 13, 204, 204, 232, 236, 9, 13, 204, 204, + 203, 139, 9, 13, 204, 204, 196, 64, 9, 13, 204, 204, 225, 35, 9, 13, 204, + 204, 219, 185, 9, 13, 204, 204, 216, 31, 9, 13, 204, 204, 208, 125, 9, + 13, 204, 204, 251, 194, 9, 13, 204, 204, 235, 176, 9, 13, 204, 204, 209, + 8, 9, 13, 204, 204, 211, 152, 9, 13, 204, 204, 206, 251, 9, 13, 204, 204, + 203, 41, 9, 13, 204, 204, 202, 213, 9, 13, 204, 204, 224, 142, 9, 13, + 204, 204, 240, 130, 9, 13, 204, 204, 195, 109, 9, 13, 204, 204, 233, 225, + 9, 13, 204, 204, 238, 252, 248, 239, 9, 13, 204, 204, 238, 252, 235, 176, + 9, 13, 221, 224, 251, 164, 9, 13, 221, 224, 248, 239, 9, 13, 221, 224, + 225, 189, 9, 13, 221, 224, 240, 107, 9, 13, 221, 224, 232, 113, 9, 13, + 221, 224, 197, 117, 9, 13, 221, 224, 195, 106, 9, 13, 221, 224, 232, 236, + 9, 13, 221, 224, 203, 139, 9, 13, 221, 224, 196, 64, 9, 13, 221, 224, + 222, 249, 9, 13, 221, 224, 219, 185, 9, 13, 221, 224, 216, 31, 9, 13, + 221, 224, 208, 125, 9, 13, 221, 224, 251, 194, 9, 13, 221, 224, 235, 176, + 9, 13, 221, 224, 209, 8, 9, 13, 221, 224, 211, 152, 9, 13, 221, 224, 210, + 142, 9, 13, 221, 224, 206, 251, 9, 13, 221, 224, 203, 41, 9, 13, 221, + 224, 202, 213, 9, 13, 221, 224, 224, 142, 9, 13, 221, 224, 202, 225, 9, + 13, 221, 224, 240, 130, 9, 13, 221, 224, 195, 109, 9, 13, 221, 224, 233, + 225, 9, 13, 237, 241, 248, 239, 9, 13, 237, 241, 225, 189, 9, 13, 237, + 241, 240, 107, 9, 13, 237, 241, 197, 117, 9, 13, 237, 241, 195, 106, 9, + 13, 237, 241, 232, 236, 9, 13, 237, 241, 203, 139, 9, 13, 237, 241, 196, + 64, 9, 13, 237, 241, 222, 249, 9, 13, 237, 241, 219, 185, 9, 13, 237, + 241, 216, 31, 9, 13, 237, 241, 208, 125, 9, 13, 237, 241, 251, 194, 9, + 13, 237, 241, 235, 176, 9, 13, 237, 241, 209, 8, 9, 13, 237, 241, 211, + 152, 9, 13, 237, 241, 210, 142, 9, 13, 237, 241, 206, 251, 9, 13, 237, + 241, 203, 41, 9, 13, 237, 241, 202, 213, 9, 13, 237, 241, 224, 142, 9, + 13, 237, 241, 202, 225, 9, 13, 237, 241, 240, 130, 9, 13, 237, 241, 195, + 109, 9, 13, 237, 241, 233, 225, 9, 13, 214, 83, 87, 3, 168, 3, 203, 91, + 9, 13, 214, 83, 168, 3, 240, 107, 220, 83, 113, 237, 69, 197, 50, 220, + 83, 113, 205, 159, 197, 50, 220, 83, 113, 197, 89, 197, 50, 220, 83, 113, + 173, 197, 50, 220, 83, 113, 210, 158, 237, 223, 220, 83, 113, 233, 91, + 237, 223, 220, 83, 113, 59, 237, 223, 220, 83, 113, 97, 77, 245, 114, + 220, 83, 113, 99, 77, 245, 114, 220, 83, 113, 115, 77, 245, 114, 220, 83, + 113, 235, 7, 77, 245, 114, 220, 83, 113, 235, 101, 77, 245, 114, 220, 83, + 113, 206, 29, 77, 245, 114, 220, 83, 113, 207, 71, 77, 245, 114, 220, 83, + 113, 237, 31, 77, 245, 114, 220, 83, 113, 216, 179, 77, 245, 114, 220, + 83, 113, 97, 77, 249, 94, 220, 83, 113, 99, 77, 249, 94, 220, 83, 113, + 115, 77, 249, 94, 220, 83, 113, 235, 7, 77, 249, 94, 220, 83, 113, 235, + 101, 77, 249, 94, 220, 83, 113, 206, 29, 77, 249, 94, 220, 83, 113, 207, + 71, 77, 249, 94, 220, 83, 113, 237, 31, 77, 249, 94, 220, 83, 113, 216, + 179, 77, 249, 94, 220, 83, 113, 97, 77, 244, 246, 220, 83, 113, 99, 77, + 244, 246, 220, 83, 113, 115, 77, 244, 246, 220, 83, 113, 235, 7, 77, 244, + 246, 220, 83, 113, 235, 101, 77, 244, 246, 220, 83, 113, 206, 29, 77, + 244, 246, 220, 83, 113, 207, 71, 77, 244, 246, 220, 83, 113, 237, 31, 77, + 244, 246, 220, 83, 113, 216, 179, 77, 244, 246, 220, 83, 113, 212, 128, + 220, 83, 113, 214, 69, 220, 83, 113, 249, 95, 220, 83, 113, 245, 31, 220, + 83, 113, 205, 100, 220, 83, 113, 204, 113, 220, 83, 113, 250, 136, 220, + 83, 113, 197, 41, 220, 83, 113, 225, 122, 220, 83, 113, 249, 138, 185, + 113, 231, 155, 249, 138, 185, 113, 231, 153, 185, 113, 231, 152, 185, + 113, 231, 151, 185, 113, 231, 150, 185, 113, 231, 149, 185, 113, 231, + 148, 185, 113, 231, 147, 185, 113, 231, 146, 185, 113, 231, 145, 185, + 113, 231, 144, 185, 113, 231, 143, 185, 113, 231, 142, 185, 113, 231, + 141, 185, 113, 231, 140, 185, 113, 231, 139, 185, 113, 231, 138, 185, + 113, 231, 137, 185, 113, 231, 136, 185, 113, 231, 135, 185, 113, 231, + 134, 185, 113, 231, 133, 185, 113, 231, 132, 185, 113, 231, 131, 185, + 113, 231, 130, 185, 113, 231, 129, 185, 113, 231, 128, 185, 113, 231, + 127, 185, 113, 231, 126, 185, 113, 231, 125, 185, 113, 231, 124, 185, + 113, 231, 123, 185, 113, 231, 122, 185, 113, 231, 121, 185, 113, 231, + 120, 185, 113, 231, 119, 185, 113, 231, 118, 185, 113, 231, 117, 185, + 113, 231, 116, 185, 113, 231, 115, 185, 113, 231, 114, 185, 113, 231, + 113, 185, 113, 231, 112, 185, 113, 231, 111, 185, 113, 231, 110, 185, + 113, 231, 109, 185, 113, 231, 108, 185, 113, 231, 107, 185, 113, 231, + 106, 185, 113, 231, 105, 185, 113, 83, 249, 138, 185, 113, 199, 99, 185, + 113, 199, 98, 185, 113, 199, 97, 185, 113, 199, 96, 185, 113, 199, 95, + 185, 113, 199, 94, 185, 113, 199, 93, 185, 113, 199, 92, 185, 113, 199, + 91, 185, 113, 199, 90, 185, 113, 199, 89, 185, 113, 199, 88, 185, 113, + 199, 87, 185, 113, 199, 86, 185, 113, 199, 85, 185, 113, 199, 84, 185, + 113, 199, 83, 185, 113, 199, 82, 185, 113, 199, 81, 185, 113, 199, 80, + 185, 113, 199, 79, 185, 113, 199, 78, 185, 113, 199, 77, 185, 113, 199, + 76, 185, 113, 199, 75, 185, 113, 199, 74, 185, 113, 199, 73, 185, 113, + 199, 72, 185, 113, 199, 71, 185, 113, 199, 70, 185, 113, 199, 69, 185, + 113, 199, 68, 185, 113, 199, 67, 185, 113, 199, 66, 185, 113, 199, 65, + 185, 113, 199, 64, 185, 113, 199, 63, 185, 113, 199, 62, 185, 113, 199, + 61, 185, 113, 199, 60, 185, 113, 199, 59, 185, 113, 199, 58, 185, 113, + 199, 57, 185, 113, 199, 56, 185, 113, 199, 55, 185, 113, 199, 54, 185, + 113, 199, 53, 185, 113, 199, 52, 185, 113, 199, 51, 212, 138, 247, 115, + 249, 138, 212, 138, 247, 115, 252, 16, 77, 205, 145, 212, 138, 247, 115, + 99, 77, 205, 145, 212, 138, 247, 115, 115, 77, 205, 145, 212, 138, 247, + 115, 235, 7, 77, 205, 145, 212, 138, 247, 115, 235, 101, 77, 205, 145, + 212, 138, 247, 115, 206, 29, 77, 205, 145, 212, 138, 247, 115, 207, 71, + 77, 205, 145, 212, 138, 247, 115, 237, 31, 77, 205, 145, 212, 138, 247, + 115, 216, 179, 77, 205, 145, 212, 138, 247, 115, 203, 24, 77, 205, 145, + 212, 138, 247, 115, 225, 212, 77, 205, 145, 212, 138, 247, 115, 224, 20, + 77, 205, 145, 212, 138, 247, 115, 211, 81, 77, 205, 145, 212, 138, 247, + 115, 224, 74, 77, 205, 145, 212, 138, 247, 115, 252, 16, 77, 232, 124, + 212, 138, 247, 115, 99, 77, 232, 124, 212, 138, 247, 115, 115, 77, 232, + 124, 212, 138, 247, 115, 235, 7, 77, 232, 124, 212, 138, 247, 115, 235, + 101, 77, 232, 124, 212, 138, 247, 115, 206, 29, 77, 232, 124, 212, 138, + 247, 115, 207, 71, 77, 232, 124, 212, 138, 247, 115, 237, 31, 77, 232, + 124, 212, 138, 247, 115, 216, 179, 77, 232, 124, 212, 138, 247, 115, 203, + 24, 77, 232, 124, 212, 138, 247, 115, 225, 212, 77, 232, 124, 212, 138, + 247, 115, 224, 20, 77, 232, 124, 212, 138, 247, 115, 211, 81, 77, 232, + 124, 212, 138, 247, 115, 224, 74, 77, 232, 124, 212, 138, 247, 115, 210, + 158, 225, 122, 212, 138, 247, 115, 252, 16, 77, 239, 139, 212, 138, 247, + 115, 99, 77, 239, 139, 212, 138, 247, 115, 115, 77, 239, 139, 212, 138, + 247, 115, 235, 7, 77, 239, 139, 212, 138, 247, 115, 235, 101, 77, 239, + 139, 212, 138, 247, 115, 206, 29, 77, 239, 139, 212, 138, 247, 115, 207, + 71, 77, 239, 139, 212, 138, 247, 115, 237, 31, 77, 239, 139, 212, 138, + 247, 115, 216, 179, 77, 239, 139, 212, 138, 247, 115, 203, 24, 77, 239, + 139, 212, 138, 247, 115, 225, 212, 77, 239, 139, 212, 138, 247, 115, 224, + 20, 77, 239, 139, 212, 138, 247, 115, 211, 81, 77, 239, 139, 212, 138, + 247, 115, 224, 74, 77, 239, 139, 212, 138, 247, 115, 58, 225, 122, 212, + 138, 247, 115, 252, 16, 77, 244, 188, 212, 138, 247, 115, 99, 77, 244, + 188, 212, 138, 247, 115, 115, 77, 244, 188, 212, 138, 247, 115, 235, 7, + 77, 244, 188, 212, 138, 247, 115, 235, 101, 77, 244, 188, 212, 138, 247, + 115, 206, 29, 77, 244, 188, 212, 138, 247, 115, 207, 71, 77, 244, 188, + 212, 138, 247, 115, 237, 31, 77, 244, 188, 212, 138, 247, 115, 216, 179, + 77, 244, 188, 212, 138, 247, 115, 203, 24, 77, 244, 188, 212, 138, 247, + 115, 225, 212, 77, 244, 188, 212, 138, 247, 115, 224, 20, 77, 244, 188, + 212, 138, 247, 115, 211, 81, 77, 244, 188, 212, 138, 247, 115, 224, 74, + 77, 244, 188, 212, 138, 247, 115, 59, 225, 122, 212, 138, 247, 115, 235, + 38, 212, 138, 247, 115, 201, 141, 212, 138, 247, 115, 201, 130, 212, 138, + 247, 115, 201, 127, 212, 138, 247, 115, 201, 126, 212, 138, 247, 115, + 201, 125, 212, 138, 247, 115, 201, 124, 212, 138, 247, 115, 201, 123, + 212, 138, 247, 115, 201, 122, 212, 138, 247, 115, 201, 121, 212, 138, + 247, 115, 201, 140, 212, 138, 247, 115, 201, 139, 212, 138, 247, 115, + 201, 138, 212, 138, 247, 115, 201, 137, 212, 138, 247, 115, 201, 136, + 212, 138, 247, 115, 201, 135, 212, 138, 247, 115, 201, 134, 212, 138, + 247, 115, 201, 133, 212, 138, 247, 115, 201, 132, 212, 138, 247, 115, + 201, 131, 212, 138, 247, 115, 201, 129, 212, 138, 247, 115, 201, 128, 17, + 195, 80, 234, 217, 204, 226, 17, 195, 80, 244, 159, 17, 97, 244, 159, 17, + 99, 244, 159, 17, 115, 244, 159, 17, 235, 7, 244, 159, 17, 235, 101, 244, + 159, 17, 206, 29, 244, 159, 17, 207, 71, 244, 159, 17, 237, 31, 244, 159, + 17, 216, 179, 244, 159, 239, 93, 46, 45, 17, 195, 79, 239, 93, 217, 104, + 46, 45, 17, 195, 79, 119, 8, 6, 1, 63, 119, 8, 6, 1, 250, 112, 119, 8, 6, + 1, 247, 207, 119, 8, 6, 1, 240, 231, 119, 8, 6, 1, 69, 119, 8, 6, 1, 236, + 49, 119, 8, 6, 1, 234, 190, 119, 8, 6, 1, 233, 15, 119, 8, 6, 1, 68, 119, + 8, 6, 1, 225, 217, 119, 8, 6, 1, 225, 80, 119, 8, 6, 1, 159, 119, 8, 6, + 1, 221, 136, 119, 8, 6, 1, 218, 55, 119, 8, 6, 1, 72, 119, 8, 6, 1, 214, + 3, 119, 8, 6, 1, 211, 167, 119, 8, 6, 1, 144, 119, 8, 6, 1, 209, 80, 119, + 8, 6, 1, 203, 216, 119, 8, 6, 1, 66, 119, 8, 6, 1, 199, 230, 119, 8, 6, + 1, 197, 199, 119, 8, 6, 1, 196, 222, 119, 8, 6, 1, 196, 148, 119, 8, 6, + 1, 195, 158, 201, 231, 206, 245, 248, 61, 8, 6, 1, 209, 80, 46, 41, 8, 6, + 1, 247, 207, 46, 41, 8, 6, 1, 144, 46, 247, 58, 46, 196, 224, 241, 106, + 105, 103, 8, 6, 1, 63, 103, 8, 6, 1, 250, 112, 103, 8, 6, 1, 247, 207, + 103, 8, 6, 1, 240, 231, 103, 8, 6, 1, 69, 103, 8, 6, 1, 236, 49, 103, 8, + 6, 1, 234, 190, 103, 8, 6, 1, 233, 15, 103, 8, 6, 1, 68, 103, 8, 6, 1, + 225, 217, 103, 8, 6, 1, 225, 80, 103, 8, 6, 1, 159, 103, 8, 6, 1, 221, + 136, 103, 8, 6, 1, 218, 55, 103, 8, 6, 1, 72, 103, 8, 6, 1, 214, 3, 103, + 8, 6, 1, 211, 167, 103, 8, 6, 1, 144, 103, 8, 6, 1, 209, 80, 103, 8, 6, + 1, 203, 216, 103, 8, 6, 1, 66, 103, 8, 6, 1, 199, 230, 103, 8, 6, 1, 197, + 199, 103, 8, 6, 1, 196, 222, 103, 8, 6, 1, 196, 148, 103, 8, 6, 1, 195, + 158, 103, 231, 44, 103, 218, 79, 103, 208, 149, 103, 205, 83, 103, 212, + 52, 103, 197, 110, 217, 104, 46, 8, 6, 1, 63, 217, 104, 46, 8, 6, 1, 250, + 112, 217, 104, 46, 8, 6, 1, 247, 207, 217, 104, 46, 8, 6, 1, 240, 231, + 217, 104, 46, 8, 6, 1, 69, 217, 104, 46, 8, 6, 1, 236, 49, 217, 104, 46, + 8, 6, 1, 234, 190, 217, 104, 46, 8, 6, 1, 233, 15, 217, 104, 46, 8, 6, 1, + 68, 217, 104, 46, 8, 6, 1, 225, 217, 217, 104, 46, 8, 6, 1, 225, 80, 217, + 104, 46, 8, 6, 1, 159, 217, 104, 46, 8, 6, 1, 221, 136, 217, 104, 46, 8, + 6, 1, 218, 55, 217, 104, 46, 8, 6, 1, 72, 217, 104, 46, 8, 6, 1, 214, 3, + 217, 104, 46, 8, 6, 1, 211, 167, 217, 104, 46, 8, 6, 1, 144, 217, 104, + 46, 8, 6, 1, 209, 80, 217, 104, 46, 8, 6, 1, 203, 216, 217, 104, 46, 8, + 6, 1, 66, 217, 104, 46, 8, 6, 1, 199, 230, 217, 104, 46, 8, 6, 1, 197, + 199, 217, 104, 46, 8, 6, 1, 196, 222, 217, 104, 46, 8, 6, 1, 196, 148, + 217, 104, 46, 8, 6, 1, 195, 158, 210, 215, 219, 213, 55, 210, 215, 219, + 210, 55, 210, 215, 218, 150, 55, 217, 104, 103, 8, 6, 1, 63, 217, 104, + 103, 8, 6, 1, 250, 112, 217, 104, 103, 8, 6, 1, 247, 207, 217, 104, 103, + 8, 6, 1, 240, 231, 217, 104, 103, 8, 6, 1, 69, 217, 104, 103, 8, 6, 1, + 236, 49, 217, 104, 103, 8, 6, 1, 234, 190, 217, 104, 103, 8, 6, 1, 233, + 15, 217, 104, 103, 8, 6, 1, 68, 217, 104, 103, 8, 6, 1, 225, 217, 217, + 104, 103, 8, 6, 1, 225, 80, 217, 104, 103, 8, 6, 1, 159, 217, 104, 103, + 8, 6, 1, 221, 136, 217, 104, 103, 8, 6, 1, 218, 55, 217, 104, 103, 8, 6, + 1, 72, 217, 104, 103, 8, 6, 1, 214, 3, 217, 104, 103, 8, 6, 1, 211, 167, + 217, 104, 103, 8, 6, 1, 144, 217, 104, 103, 8, 6, 1, 209, 80, 217, 104, + 103, 8, 6, 1, 203, 216, 217, 104, 103, 8, 6, 1, 66, 217, 104, 103, 8, 6, + 1, 199, 230, 217, 104, 103, 8, 6, 1, 197, 199, 217, 104, 103, 8, 6, 1, + 196, 222, 217, 104, 103, 8, 6, 1, 196, 148, 217, 104, 103, 8, 6, 1, 195, + 158, 241, 59, 217, 104, 103, 8, 6, 1, 214, 3, 217, 104, 103, 230, 203, + 217, 104, 103, 161, 217, 104, 103, 183, 217, 104, 103, 252, 117, 217, + 104, 103, 197, 110, 47, 239, 48, 103, 244, 230, 103, 241, 113, 103, 234, + 245, 103, 230, 194, 103, 217, 82, 103, 217, 73, 103, 214, 139, 103, 205, + 166, 103, 124, 3, 236, 90, 78, 103, 198, 223, 103, 115, 240, 231, 103, + 208, 136, 208, 154, 103, 99, 225, 80, 103, 235, 7, 225, 80, 103, 237, 31, + 225, 80, 103, 235, 101, 212, 111, 100, 103, 207, 71, 212, 111, 100, 103, + 200, 223, 212, 111, 102, 103, 206, 14, 214, 3, 103, 97, 231, 58, 200, + 235, 214, 3, 103, 8, 4, 1, 240, 231, 103, 232, 150, 103, 232, 149, 103, + 232, 63, 103, 221, 217, 103, 206, 131, 103, 200, 91, 103, 198, 245, 210, + 150, 226, 69, 16, 1, 63, 210, 150, 226, 69, 16, 1, 250, 112, 210, 150, + 226, 69, 16, 1, 247, 207, 210, 150, 226, 69, 16, 1, 240, 231, 210, 150, + 226, 69, 16, 1, 69, 210, 150, 226, 69, 16, 1, 236, 49, 210, 150, 226, 69, + 16, 1, 234, 190, 210, 150, 226, 69, 16, 1, 233, 15, 210, 150, 226, 69, + 16, 1, 68, 210, 150, 226, 69, 16, 1, 225, 217, 210, 150, 226, 69, 16, 1, + 225, 80, 210, 150, 226, 69, 16, 1, 159, 210, 150, 226, 69, 16, 1, 221, + 136, 210, 150, 226, 69, 16, 1, 218, 55, 210, 150, 226, 69, 16, 1, 72, + 210, 150, 226, 69, 16, 1, 214, 3, 210, 150, 226, 69, 16, 1, 211, 167, + 210, 150, 226, 69, 16, 1, 144, 210, 150, 226, 69, 16, 1, 209, 80, 210, + 150, 226, 69, 16, 1, 203, 216, 210, 150, 226, 69, 16, 1, 66, 210, 150, + 226, 69, 16, 1, 199, 230, 210, 150, 226, 69, 16, 1, 197, 199, 210, 150, + 226, 69, 16, 1, 196, 222, 210, 150, 226, 69, 16, 1, 196, 148, 210, 150, + 226, 69, 16, 1, 195, 158, 47, 188, 231, 179, 103, 71, 223, 250, 103, 71, + 183, 103, 12, 200, 54, 228, 138, 103, 12, 200, 54, 228, 142, 103, 12, + 200, 54, 228, 150, 103, 71, 239, 252, 103, 12, 200, 54, 228, 157, 103, + 12, 200, 54, 228, 144, 103, 12, 200, 54, 228, 116, 103, 12, 200, 54, 228, + 143, 103, 12, 200, 54, 228, 156, 103, 12, 200, 54, 228, 130, 103, 12, + 200, 54, 228, 123, 103, 12, 200, 54, 228, 132, 103, 12, 200, 54, 228, + 153, 103, 12, 200, 54, 228, 139, 103, 12, 200, 54, 228, 155, 103, 12, + 200, 54, 228, 131, 103, 12, 200, 54, 228, 154, 103, 12, 200, 54, 228, + 117, 103, 12, 200, 54, 228, 122, 103, 12, 200, 54, 228, 115, 103, 12, + 200, 54, 228, 145, 103, 12, 200, 54, 228, 147, 103, 12, 200, 54, 228, + 125, 103, 12, 200, 54, 228, 136, 103, 12, 200, 54, 228, 134, 103, 12, + 200, 54, 228, 160, 103, 12, 200, 54, 228, 159, 103, 12, 200, 54, 228, + 113, 103, 12, 200, 54, 228, 140, 103, 12, 200, 54, 228, 158, 103, 12, + 200, 54, 228, 149, 103, 12, 200, 54, 228, 135, 103, 12, 200, 54, 228, + 114, 103, 12, 200, 54, 228, 137, 103, 12, 200, 54, 228, 119, 103, 12, + 200, 54, 228, 118, 103, 12, 200, 54, 228, 148, 103, 12, 200, 54, 228, + 126, 103, 12, 200, 54, 228, 128, 103, 12, 200, 54, 228, 129, 103, 12, + 200, 54, 228, 121, 103, 12, 200, 54, 228, 152, 103, 12, 200, 54, 228, + 146, 103, 12, 200, 54, 228, 112, 201, 231, 206, 245, 248, 61, 12, 200, + 54, 228, 127, 201, 231, 206, 245, 248, 61, 12, 200, 54, 228, 159, 201, + 231, 206, 245, 248, 61, 12, 200, 54, 228, 157, 201, 231, 206, 245, 248, + 61, 12, 200, 54, 228, 141, 201, 231, 206, 245, 248, 61, 12, 200, 54, 228, + 124, 201, 231, 206, 245, 248, 61, 12, 200, 54, 228, 137, 201, 231, 206, + 245, 248, 61, 12, 200, 54, 228, 120, 201, 231, 206, 245, 248, 61, 12, + 200, 54, 228, 151, 201, 231, 206, 245, 248, 61, 12, 200, 54, 228, 133, + 46, 230, 191, 251, 247, 46, 230, 191, 252, 20, 209, 185, 16, 36, 234, + 223, 209, 185, 16, 36, 221, 191, 209, 185, 16, 36, 206, 165, 209, 185, + 16, 36, 196, 196, 209, 185, 16, 36, 206, 148, 209, 185, 16, 36, 247, 162, + 240, 242, 235, 49, 244, 203, 200, 76, 216, 195, 3, 205, 4, 204, 106, 127, + 218, 168, 204, 105, 244, 234, 250, 169, 237, 174, 204, 104, 127, 248, 10, + 210, 216, 248, 40, 250, 169, 216, 194, 197, 128, 197, 122, 198, 239, 219, + 31, 197, 112, 237, 73, 233, 153, 236, 106, 237, 73, 233, 153, 251, 114, + 237, 73, 233, 153, 250, 188, 233, 153, 3, 219, 155, 217, 83, 218, 190, + 105, 197, 114, 241, 72, 218, 190, 105, 235, 113, 211, 88, 218, 190, 105, + 197, 114, 233, 188, 218, 190, 105, 234, 217, 218, 190, 105, 197, 142, + 233, 188, 218, 190, 105, 222, 221, 211, 88, 218, 190, 105, 197, 142, 241, + 72, 218, 190, 105, 241, 72, 218, 189, 217, 83, 218, 190, 3, 235, 233, + 235, 113, 211, 88, 218, 190, 3, 235, 233, 222, 221, 211, 88, 218, 190, 3, + 235, 233, 234, 217, 218, 190, 3, 235, 233, 204, 112, 3, 235, 233, 233, + 149, 205, 7, 206, 187, 205, 7, 202, 205, 58, 237, 209, 59, 204, 111, 59, + 204, 112, 3, 4, 244, 194, 59, 204, 112, 248, 236, 244, 194, 59, 204, 112, + 248, 236, 244, 195, 3, 210, 217, 244, 195, 3, 210, 217, 244, 195, 3, 205, + 206, 244, 195, 3, 222, 92, 244, 195, 3, 201, 235, 235, 50, 197, 51, 248, + 120, 235, 233, 231, 96, 239, 17, 203, 146, 247, 242, 245, 81, 208, 127, + 236, 100, 201, 190, 239, 245, 201, 190, 213, 207, 201, 190, 247, 167, + 231, 96, 213, 47, 201, 24, 245, 85, 248, 123, 209, 198, 232, 62, 204, + 109, 248, 123, 237, 77, 77, 220, 72, 237, 77, 77, 210, 60, 232, 96, 235, + 7, 222, 193, 244, 193, 220, 41, 222, 192, 235, 214, 222, 192, 222, 193, + 235, 57, 226, 87, 197, 50, 218, 90, 202, 15, 250, 149, 233, 108, 219, + 173, 197, 126, 203, 108, 222, 161, 249, 90, 212, 172, 210, 158, 251, 27, + 233, 91, 251, 27, 213, 85, 213, 89, 245, 86, 204, 209, 232, 218, 205, + 240, 77, 212, 152, 219, 200, 214, 120, 248, 104, 212, 64, 222, 172, 210, + 61, 241, 78, 210, 61, 249, 103, 241, 116, 210, 60, 241, 14, 26, 210, 60, + 204, 246, 248, 74, 205, 144, 248, 53, 234, 243, 234, 239, 209, 222, 204, + 59, 212, 66, 240, 85, 214, 166, 204, 78, 234, 240, 206, 157, 235, 112, + 247, 161, 3, 204, 51, 239, 188, 205, 186, 230, 202, 241, 76, 207, 7, 230, + 201, 230, 202, 241, 76, 237, 238, 241, 115, 245, 47, 154, 247, 132, 221, + 244, 241, 5, 231, 168, 212, 68, 206, 171, 248, 216, 248, 70, 212, 69, 77, + 235, 39, 241, 114, 235, 28, 26, 224, 21, 203, 57, 197, 37, 232, 187, 208, + 248, 248, 87, 26, 241, 27, 197, 47, 233, 157, 244, 178, 233, 157, 201, + 145, 237, 216, 248, 247, 218, 130, 244, 210, 248, 247, 218, 129, 249, + 141, 248, 86, 235, 28, 26, 224, 22, 3, 212, 139, 248, 87, 3, 212, 84, + 241, 103, 212, 86, 210, 62, 196, 254, 212, 26, 248, 153, 247, 160, 225, + 211, 245, 38, 201, 190, 235, 197, 245, 37, 235, 115, 235, 116, 205, 142, + 249, 101, 213, 129, 212, 85, 241, 152, 249, 103, 203, 112, 201, 190, 241, + 59, 235, 87, 212, 173, 239, 242, 225, 202, 239, 9, 247, 104, 204, 208, + 197, 51, 245, 63, 218, 190, 199, 21, 247, 23, 208, 167, 208, 197, 233, + 114, 247, 125, 232, 127, 3, 202, 68, 214, 120, 202, 218, 222, 184, 248, + 80, 77, 235, 61, 219, 33, 219, 196, 210, 129, 210, 62, 34, 224, 152, 3, + 225, 210, 204, 179, 219, 67, 222, 128, 205, 238, 241, 121, 224, 15, 249, + 5, 250, 198, 34, 216, 8, 249, 5, 239, 194, 34, 216, 8, 235, 131, 234, + 249, 251, 251, 202, 109, 247, 105, 231, 98, 235, 163, 197, 77, 209, 211, + 244, 180, 235, 107, 212, 102, 26, 235, 111, 219, 67, 218, 154, 247, 146, + 244, 253, 232, 133, 250, 207, 213, 211, 201, 243, 232, 165, 244, 239, + 203, 15, 202, 110, 244, 225, 248, 113, 213, 40, 250, 205, 199, 30, 234, + 97, 239, 86, 232, 31, 205, 231, 220, 116, 248, 166, 234, 98, 239, 132, + 248, 73, 235, 63, 212, 138, 247, 113, 34, 216, 13, 218, 120, 34, 216, 8, + 208, 181, 233, 59, 34, 224, 151, 201, 120, 199, 9, 34, 208, 159, 209, + 114, 206, 202, 3, 208, 200, 203, 20, 210, 236, 26, 249, 103, 206, 3, 26, + 206, 3, 248, 97, 249, 60, 26, 231, 161, 245, 87, 235, 93, 205, 205, 209, + 115, 204, 83, 205, 106, 219, 196, 201, 146, 231, 99, 210, 237, 251, 115, + 235, 36, 209, 128, 235, 36, 204, 54, 197, 94, 222, 97, 233, 134, 210, + 238, 218, 176, 210, 238, 247, 116, 241, 69, 249, 57, 26, 249, 103, 198, + 238, 235, 152, 231, 182, 204, 238, 26, 249, 103, 230, 202, 231, 182, 204, + 238, 26, 211, 219, 203, 153, 203, 20, 213, 230, 26, 249, 103, 205, 207, + 247, 121, 218, 169, 247, 144, 249, 8, 3, 200, 76, 248, 12, 241, 135, 231, + 88, 248, 10, 244, 233, 239, 198, 231, 88, 248, 11, 244, 223, 248, 11, + 239, 190, 239, 191, 225, 241, 217, 204, 213, 136, 205, 18, 231, 88, 248, + 11, 231, 88, 3, 234, 81, 214, 157, 248, 11, 225, 202, 212, 74, 214, 156, + 236, 105, 212, 74, 214, 156, 231, 97, 249, 84, 250, 138, 203, 29, 220, + 116, 231, 93, 221, 209, 231, 93, 241, 119, 204, 222, 208, 166, 239, 201, + 204, 222, 235, 222, 225, 222, 222, 233, 225, 202, 247, 94, 236, 105, 247, + 94, 59, 213, 59, 58, 213, 59, 197, 120, 59, 235, 93, 197, 120, 58, 235, + 93, 209, 197, 58, 209, 197, 223, 74, 249, 124, 210, 236, 26, 206, 134, + 248, 78, 26, 51, 251, 110, 236, 236, 73, 235, 102, 200, 199, 236, 236, + 73, 235, 102, 200, 196, 236, 236, 73, 235, 102, 200, 194, 236, 236, 73, + 235, 102, 200, 192, 236, 236, 73, 235, 102, 200, 190, 210, 198, 218, 166, + 214, 13, 197, 128, 248, 16, 241, 83, 202, 102, 222, 145, 210, 240, 247, + 92, 237, 223, 241, 67, 197, 80, 205, 214, 205, 212, 231, 98, 210, 210, + 233, 140, 206, 249, 218, 209, 209, 201, 245, 73, 239, 17, 212, 184, 248, + 114, 236, 255, 214, 169, 205, 121, 206, 244, 248, 15, 251, 69, 231, 167, + 223, 66, 248, 245, 235, 111, 201, 145, 235, 111, 248, 121, 201, 1, 232, + 163, 245, 74, 249, 141, 245, 74, 234, 233, 249, 141, 245, 74, 248, 156, + 213, 61, 224, 5, 212, 90, 237, 213, 247, 148, 249, 129, 247, 148, 239, 8, + 218, 167, 235, 233, 241, 84, 235, 233, 202, 103, 235, 233, 210, 241, 235, + 233, 247, 93, 235, 233, 237, 224, 235, 233, 205, 104, 197, 80, 231, 99, + 235, 233, 218, 210, 235, 233, 239, 18, 235, 233, 212, 185, 235, 233, 234, + 237, 235, 233, 232, 215, 235, 233, 197, 24, 235, 233, 249, 3, 235, 233, + 213, 187, 235, 233, 212, 185, 216, 20, 213, 105, 212, 12, 245, 58, 236, + 59, 236, 67, 237, 76, 216, 20, 218, 164, 201, 249, 59, 124, 212, 107, + 249, 136, 226, 72, 59, 135, 212, 107, 249, 136, 226, 72, 59, 50, 212, + 107, 249, 136, 226, 72, 59, 53, 212, 107, 249, 136, 226, 72, 235, 105, + 232, 210, 55, 197, 120, 232, 210, 55, 214, 140, 232, 210, 55, 202, 140, + 124, 55, 202, 140, 135, 55, 244, 224, 232, 185, 55, 192, 232, 185, 55, + 241, 53, 197, 20, 232, 165, 236, 62, 217, 108, 203, 214, 225, 192, 237, + 218, 224, 77, 248, 169, 197, 20, 244, 196, 211, 199, 232, 189, 212, 65, + 220, 50, 206, 194, 250, 164, 206, 194, 232, 47, 206, 194, 197, 20, 208, + 216, 197, 20, 248, 96, 235, 34, 247, 234, 226, 87, 206, 78, 247, 233, + 226, 87, 206, 78, 248, 68, 233, 169, 220, 62, 197, 21, 235, 211, 220, 63, + 26, 197, 22, 231, 176, 232, 184, 99, 219, 165, 231, 176, 232, 184, 99, + 197, 19, 231, 176, 232, 184, 212, 99, 214, 155, 197, 22, 3, 247, 252, + 237, 74, 248, 41, 3, 199, 109, 213, 29, 3, 248, 125, 232, 233, 220, 63, + 3, 233, 73, 212, 221, 220, 45, 220, 63, 3, 201, 9, 214, 132, 220, 62, + 214, 132, 197, 21, 249, 140, 241, 136, 197, 5, 212, 17, 225, 202, 214, + 150, 225, 202, 233, 139, 233, 200, 249, 141, 251, 95, 236, 72, 251, 154, + 251, 155, 218, 199, 226, 92, 205, 254, 226, 61, 239, 187, 213, 28, 233, + 67, 240, 90, 222, 58, 217, 229, 212, 98, 235, 234, 220, 7, 232, 232, 249, + 78, 212, 101, 203, 235, 212, 177, 224, 58, 78, 221, 209, 222, 135, 210, + 2, 234, 38, 204, 228, 224, 57, 248, 79, 241, 87, 3, 232, 126, 197, 101, + 248, 255, 232, 126, 248, 33, 232, 126, 99, 232, 124, 205, 140, 232, 126, + 233, 83, 232, 126, 232, 127, 3, 51, 248, 119, 232, 126, 233, 91, 232, + 126, 196, 62, 232, 126, 211, 200, 232, 126, 232, 127, 3, 210, 62, 210, + 83, 232, 124, 232, 127, 239, 242, 239, 141, 207, 21, 3, 39, 76, 226, 41, + 237, 2, 175, 248, 8, 251, 94, 105, 248, 105, 205, 243, 105, 244, 170, + 105, 205, 115, 204, 61, 105, 237, 209, 240, 66, 105, 212, 178, 77, 212, + 91, 235, 75, 248, 181, 239, 49, 105, 205, 132, 249, 101, 202, 160, 249, + 101, 59, 235, 62, 231, 58, 212, 105, 105, 218, 214, 249, 122, 241, 17, + 236, 92, 85, 239, 10, 55, 241, 74, 247, 114, 249, 83, 3, 196, 60, 55, + 249, 83, 3, 239, 10, 55, 249, 83, 3, 236, 108, 55, 249, 83, 3, 212, 63, + 55, 218, 214, 3, 197, 45, 245, 111, 3, 200, 24, 201, 186, 26, 196, 60, + 55, 208, 139, 213, 27, 241, 157, 248, 39, 219, 21, 235, 67, 239, 73, 214, + 76, 239, 78, 237, 169, 235, 138, 235, 47, 192, 235, 138, 235, 47, 213, + 228, 3, 241, 21, 213, 228, 235, 226, 200, 36, 247, 154, 203, 56, 247, + 154, 247, 115, 226, 72, 245, 111, 3, 200, 24, 201, 185, 245, 111, 3, 237, + 231, 201, 185, 249, 80, 245, 110, 244, 209, 211, 195, 209, 187, 211, 195, + 213, 160, 204, 218, 209, 122, 201, 177, 209, 122, 248, 101, 203, 151, + 222, 189, 216, 11, 216, 12, 3, 239, 241, 241, 86, 244, 203, 248, 102, + 192, 248, 102, 233, 91, 248, 102, 248, 119, 248, 102, 214, 71, 248, 102, + 248, 99, 217, 223, 249, 126, 208, 152, 219, 166, 203, 34, 210, 172, 213, + 226, 235, 194, 220, 116, 208, 196, 251, 66, 211, 220, 252, 3, 221, 211, + 245, 95, 219, 178, 214, 33, 201, 194, 226, 83, 201, 194, 213, 235, 237, + 129, 105, 226, 80, 236, 194, 236, 195, 3, 237, 231, 61, 57, 244, 203, + 220, 78, 3, 221, 201, 235, 93, 244, 203, 220, 78, 3, 210, 215, 235, 93, + 192, 220, 78, 3, 210, 215, 235, 93, 192, 220, 78, 3, 221, 201, 235, 93, + 212, 71, 212, 72, 231, 102, 217, 78, 218, 243, 212, 229, 218, 243, 212, + 230, 3, 91, 61, 250, 169, 222, 184, 199, 33, 218, 242, 218, 243, 212, + 230, 214, 158, 216, 51, 218, 243, 212, 228, 251, 67, 3, 249, 68, 247, + 146, 247, 147, 3, 235, 84, 199, 30, 247, 146, 203, 31, 210, 231, 199, 29, + 235, 131, 211, 254, 212, 81, 204, 240, 212, 40, 249, 7, 200, 219, 91, + 250, 214, 244, 205, 91, 26, 107, 192, 244, 250, 250, 214, 244, 205, 91, + 26, 107, 192, 244, 250, 250, 215, 3, 46, 97, 214, 20, 244, 205, 237, 231, + 26, 200, 24, 192, 244, 250, 250, 214, 251, 65, 237, 231, 26, 200, 24, + 192, 244, 250, 250, 214, 126, 248, 37, 105, 130, 248, 37, 105, 205, 137, + 3, 247, 139, 106, 205, 136, 205, 137, 3, 97, 205, 162, 197, 122, 205, + 137, 3, 115, 205, 162, 197, 121, 249, 50, 237, 2, 212, 130, 222, 179, + 220, 90, 233, 157, 210, 17, 220, 90, 233, 157, 221, 255, 3, 226, 53, 213, + 65, 244, 203, 221, 255, 3, 224, 153, 224, 153, 221, 254, 192, 221, 254, + 248, 229, 248, 230, 3, 247, 139, 106, 248, 100, 222, 66, 105, 210, 232, + 247, 227, 249, 139, 3, 107, 61, 57, 236, 222, 3, 107, 61, 57, 214, 120, + 3, 236, 90, 117, 3, 50, 53, 61, 57, 205, 170, 3, 91, 61, 57, 201, 243, 3, + 200, 24, 61, 57, 216, 51, 97, 200, 64, 237, 29, 105, 224, 150, 203, 23, + 226, 47, 16, 36, 8, 6, 222, 134, 226, 47, 16, 36, 8, 4, 222, 134, 226, + 47, 16, 36, 215, 143, 226, 47, 16, 36, 203, 249, 226, 47, 16, 36, 8, 222, + 134, 235, 118, 237, 2, 201, 238, 196, 252, 232, 216, 215, 126, 26, 248, + 107, 231, 183, 212, 158, 219, 66, 203, 32, 241, 43, 249, 103, 206, 29, + 212, 109, 205, 8, 3, 112, 238, 253, 225, 202, 16, 36, 248, 242, 201, 175, + 236, 238, 58, 47, 247, 227, 59, 47, 247, 227, 222, 228, 210, 158, 244, + 249, 222, 228, 248, 119, 244, 249, 222, 228, 214, 71, 239, 140, 222, 228, + 248, 119, 239, 140, 4, 214, 71, 239, 140, 4, 248, 119, 239, 140, 200, 35, + 210, 158, 201, 180, 237, 234, 210, 158, 201, 180, 200, 35, 4, 210, 158, + 201, 180, 237, 234, 4, 210, 158, 201, 180, 221, 203, 53, 207, 37, 59, + 244, 249, 200, 33, 53, 207, 37, 59, 244, 249, 46, 241, 62, 212, 95, 241, + 62, 212, 96, 3, 232, 222, 60, 241, 62, 212, 95, 216, 15, 50, 207, 108, 3, + 115, 238, 250, 216, 15, 53, 207, 108, 3, 115, 238, 250, 16, 36, 220, 23, + 247, 1, 59, 8, 241, 61, 85, 8, 241, 61, 247, 41, 241, 61, 214, 128, 105, + 237, 237, 77, 213, 90, 225, 53, 218, 182, 203, 243, 219, 161, 3, 216, + 179, 248, 56, 248, 75, 77, 231, 9, 244, 207, 235, 234, 97, 214, 175, 244, + 207, 235, 234, 99, 214, 175, 244, 207, 235, 234, 115, 214, 175, 244, 207, + 235, 234, 235, 7, 214, 175, 244, 207, 235, 234, 235, 101, 214, 175, 244, + 207, 235, 234, 206, 29, 214, 175, 244, 207, 235, 234, 207, 71, 214, 175, + 244, 207, 235, 234, 237, 31, 214, 175, 244, 207, 235, 234, 216, 179, 214, + 175, 244, 207, 235, 234, 203, 24, 214, 175, 244, 207, 235, 234, 236, 253, + 214, 175, 244, 207, 235, 234, 200, 240, 214, 175, 244, 207, 235, 234, + 214, 112, 244, 207, 235, 234, 200, 213, 244, 207, 235, 234, 202, 146, + 244, 207, 235, 234, 235, 3, 244, 207, 235, 234, 235, 99, 244, 207, 235, + 234, 206, 25, 244, 207, 235, 234, 207, 70, 244, 207, 235, 234, 237, 30, + 244, 207, 235, 234, 216, 178, 244, 207, 235, 234, 203, 22, 244, 207, 235, + 234, 236, 251, 244, 207, 235, 234, 200, 238, 53, 205, 136, 53, 205, 137, + 3, 97, 205, 162, 197, 122, 53, 205, 137, 3, 115, 205, 162, 197, 121, 248, + 3, 248, 4, 3, 205, 162, 197, 121, 210, 0, 248, 229, 248, 102, 247, 137, + 220, 47, 244, 206, 58, 205, 255, 26, 241, 60, 216, 51, 212, 164, 231, + 175, 220, 63, 226, 87, 247, 236, 204, 125, 222, 127, 205, 241, 214, 73, + 205, 95, 240, 71, 204, 107, 205, 124, 205, 125, 197, 102, 225, 111, 220, + 63, 240, 89, 50, 232, 210, 203, 34, 210, 172, 203, 34, 210, 173, 3, 213, + 227, 53, 232, 210, 203, 34, 210, 172, 59, 201, 224, 203, 33, 58, 201, + 224, 203, 33, 203, 34, 214, 120, 201, 243, 77, 218, 239, 244, 228, 218, + 243, 212, 229, 249, 139, 77, 236, 194, 205, 14, 236, 194, 236, 195, 3, + 222, 92, 235, 54, 236, 194, 213, 66, 127, 205, 14, 236, 194, 222, 65, + 213, 159, 58, 211, 195, 221, 203, 50, 213, 64, 221, 203, 50, 249, 97, + 213, 65, 221, 203, 50, 235, 9, 213, 65, 221, 203, 50, 213, 220, 221, 203, + 50, 241, 77, 50, 196, 246, 232, 209, 163, 214, 140, 232, 210, 55, 210, + 215, 232, 210, 3, 235, 123, 205, 114, 210, 89, 210, 215, 232, 210, 3, + 235, 123, 205, 114, 210, 89, 202, 140, 124, 55, 210, 89, 202, 140, 135, + 55, 210, 89, 199, 32, 232, 209, 210, 89, 232, 210, 3, 112, 235, 128, 236, + 78, 210, 215, 232, 210, 3, 213, 134, 248, 204, 112, 26, 210, 3, 235, 122, + 59, 135, 212, 107, 50, 232, 210, 226, 72, 206, 96, 59, 50, 212, 107, 226, + 72, 206, 96, 59, 53, 212, 107, 226, 72, 206, 96, 58, 50, 212, 107, 226, + 72, 206, 96, 58, 53, 212, 107, 226, 72, 58, 50, 212, 107, 249, 136, 226, + 72, 58, 53, 212, 107, 249, 136, 226, 72, 206, 96, 59, 124, 212, 107, 226, + 72, 206, 96, 59, 135, 212, 107, 226, 72, 206, 96, 58, 124, 212, 107, 226, + 72, 206, 96, 58, 135, 212, 107, 226, 72, 58, 124, 212, 107, 249, 136, + 226, 72, 58, 135, 212, 107, 249, 136, 226, 72, 58, 232, 126, 239, 186, + 241, 157, 224, 152, 26, 218, 166, 115, 217, 87, 241, 156, 212, 13, 212, + 115, 247, 156, 58, 232, 173, 206, 245, 235, 67, 239, 73, 59, 232, 173, + 206, 245, 235, 67, 239, 73, 205, 186, 206, 245, 235, 67, 239, 73, 203, + 104, 247, 98, 197, 40, 224, 151, 97, 247, 228, 218, 166, 99, 247, 228, + 218, 166, 115, 247, 228, 218, 166, 201, 215, 37, 213, 27, 241, 157, 232, + 173, 239, 73, 208, 154, 212, 14, 230, 195, 235, 194, 230, 195, 214, 76, + 239, 79, 230, 195, 239, 22, 3, 202, 237, 239, 22, 3, 202, 238, 26, 212, + 214, 239, 22, 3, 212, 214, 234, 251, 3, 212, 214, 234, 251, 3, 202, 82, + 234, 251, 3, 251, 107, 196, 222, 58, 235, 47, 235, 47, 192, 235, 47, 247, + 115, 132, 239, 58, 247, 115, 235, 138, 248, 70, 235, 138, 247, 169, 236, + 232, 216, 13, 236, 232, 216, 14, 213, 227, 236, 232, 216, 14, 213, 233, + 216, 13, 216, 14, 213, 227, 216, 14, 213, 233, 236, 232, 239, 21, 236, + 232, 213, 227, 236, 232, 213, 225, 239, 21, 213, 227, 213, 225, 197, 132, + 205, 121, 216, 14, 213, 233, 205, 121, 247, 155, 213, 233, 239, 186, 197, + 49, 219, 18, 219, 252, 214, 23, 244, 205, 53, 26, 50, 207, 108, 250, 214, + 247, 139, 196, 222, 226, 78, 235, 41, 206, 9, 105, 239, 240, 235, 41, + 206, 9, 105, 241, 158, 37, 224, 153, 209, 212, 217, 78, 213, 228, 3, 46, + 202, 237, 204, 230, 245, 110, 240, 119, 224, 21, 222, 59, 205, 135, 232, + 138, 226, 87, 206, 78, 115, 210, 189, 57, 115, 210, 189, 60, 115, 210, + 189, 222, 184, 115, 210, 189, 210, 22, 50, 205, 132, 248, 20, 53, 205, + 132, 248, 20, 99, 205, 132, 248, 19, 115, 205, 132, 248, 19, 50, 202, + 160, 248, 20, 53, 202, 160, 248, 20, 50, 251, 94, 248, 20, 53, 251, 94, + 248, 20, 218, 194, 248, 20, 222, 93, 218, 194, 248, 20, 222, 93, 218, + 193, 249, 99, 111, 3, 249, 98, 249, 99, 145, 196, 222, 249, 99, 111, 3, + 145, 196, 222, 249, 99, 27, 145, 196, 222, 249, 99, 111, 3, 27, 145, 196, + 222, 175, 245, 102, 78, 249, 99, 111, 3, 27, 245, 101, 197, 4, 220, 43, + 218, 171, 234, 218, 202, 17, 201, 220, 204, 253, 77, 222, 107, 206, 79, + 77, 225, 203, 218, 152, 233, 87, 235, 233, 233, 87, 235, 234, 3, 205, + 218, 236, 59, 235, 234, 3, 203, 52, 77, 225, 113, 205, 218, 235, 234, 3, + 192, 218, 164, 205, 218, 235, 234, 3, 192, 218, 165, 26, 205, 218, 236, + 59, 205, 218, 235, 234, 3, 192, 218, 165, 26, 244, 172, 204, 60, 205, + 218, 235, 234, 3, 192, 218, 165, 26, 202, 100, 236, 59, 205, 218, 235, + 234, 3, 232, 221, 205, 218, 235, 234, 3, 231, 101, 197, 42, 235, 233, + 205, 218, 235, 234, 3, 205, 218, 236, 59, 235, 234, 208, 186, 239, 220, + 235, 39, 210, 132, 235, 233, 205, 218, 235, 234, 3, 232, 125, 236, 59, + 205, 218, 235, 234, 3, 204, 107, 205, 217, 235, 233, 217, 85, 235, 233, + 236, 80, 235, 233, 200, 70, 235, 233, 235, 234, 3, 244, 172, 204, 60, + 213, 57, 235, 233, 241, 149, 235, 233, 241, 150, 235, 233, 224, 56, 235, + 233, 235, 234, 202, 143, 39, 224, 57, 224, 56, 235, 234, 3, 205, 218, + 236, 59, 224, 56, 235, 234, 3, 244, 203, 236, 59, 235, 234, 3, 204, 180, + 201, 249, 235, 234, 3, 204, 180, 201, 250, 26, 197, 42, 236, 67, 235, + 234, 3, 204, 180, 201, 250, 26, 202, 100, 236, 59, 239, 80, 235, 233, + 197, 3, 235, 233, 251, 86, 235, 233, 212, 62, 235, 233, 241, 45, 235, + 233, 213, 31, 235, 233, 235, 234, 3, 221, 228, 77, 201, 157, 239, 80, + 247, 232, 210, 132, 235, 233, 234, 229, 235, 234, 3, 192, 218, 164, 251, + 84, 235, 233, 235, 187, 235, 233, 197, 103, 235, 233, 205, 242, 235, 233, + 202, 62, 235, 233, 233, 88, 235, 233, 221, 212, 241, 45, 235, 233, 235, + 234, 3, 192, 218, 164, 231, 47, 235, 233, 235, 234, 3, 192, 218, 165, 26, + 244, 172, 204, 60, 235, 234, 208, 156, 226, 87, 235, 188, 250, 176, 235, + 233, 235, 59, 235, 233, 205, 243, 235, 233, 239, 49, 235, 233, 235, 234, + 197, 37, 218, 164, 235, 234, 3, 219, 193, 220, 9, 233, 87, 247, 93, 235, + 234, 3, 205, 218, 236, 59, 247, 93, 235, 234, 3, 203, 52, 77, 225, 113, + 205, 218, 247, 93, 235, 234, 3, 192, 218, 164, 205, 218, 247, 93, 235, + 234, 3, 232, 125, 236, 59, 247, 93, 235, 234, 3, 196, 244, 205, 219, 224, + 56, 247, 93, 235, 234, 3, 244, 203, 236, 59, 212, 62, 247, 93, 235, 233, + 241, 45, 247, 93, 235, 233, 197, 103, 247, 93, 235, 233, 205, 236, 234, + 229, 235, 233, 205, 236, 205, 218, 235, 233, 200, 30, 235, 233, 235, 234, + 3, 209, 210, 236, 59, 235, 234, 3, 216, 51, 233, 131, 234, 15, 235, 234, + 3, 214, 140, 234, 15, 213, 29, 248, 76, 239, 235, 208, 128, 218, 209, + 232, 129, 218, 209, 205, 138, 218, 209, 232, 176, 213, 29, 210, 213, 97, + 232, 209, 213, 29, 210, 213, 248, 88, 232, 185, 226, 87, 247, 43, 213, + 29, 234, 228, 213, 29, 3, 212, 62, 235, 233, 213, 29, 3, 235, 48, 232, + 184, 173, 197, 89, 212, 107, 222, 192, 205, 159, 197, 89, 212, 107, 222, + 192, 173, 237, 69, 212, 107, 222, 192, 205, 159, 237, 69, 212, 107, 222, + 192, 163, 173, 197, 89, 212, 107, 222, 192, 163, 205, 159, 197, 89, 212, + 107, 222, 192, 163, 173, 237, 69, 212, 107, 222, 192, 163, 205, 159, 237, + 69, 212, 107, 222, 192, 173, 197, 89, 212, 107, 199, 15, 222, 192, 205, + 159, 197, 89, 212, 107, 199, 15, 222, 192, 173, 237, 69, 212, 107, 199, + 15, 222, 192, 205, 159, 237, 69, 212, 107, 199, 15, 222, 192, 85, 173, + 197, 89, 212, 107, 199, 15, 222, 192, 85, 205, 159, 197, 89, 212, 107, + 199, 15, 222, 192, 85, 173, 237, 69, 212, 107, 199, 15, 222, 192, 85, + 205, 159, 237, 69, 212, 107, 199, 15, 222, 192, 173, 197, 89, 212, 107, + 248, 17, 205, 159, 197, 89, 212, 107, 248, 17, 173, 237, 69, 212, 107, + 248, 17, 205, 159, 237, 69, 212, 107, 248, 17, 85, 173, 197, 89, 212, + 107, 248, 17, 85, 205, 159, 197, 89, 212, 107, 248, 17, 85, 173, 237, 69, + 212, 107, 248, 17, 85, 205, 159, 237, 69, 212, 107, 248, 17, 231, 174, + 211, 72, 47, 214, 59, 231, 174, 211, 72, 47, 214, 60, 226, 87, 58, 205, + 94, 205, 179, 211, 72, 47, 214, 59, 205, 179, 211, 72, 47, 214, 60, 226, + 87, 58, 205, 94, 107, 209, 217, 200, 24, 209, 217, 91, 209, 217, 237, + 231, 209, 217, 145, 33, 236, 129, 214, 59, 85, 145, 33, 236, 129, 214, + 59, 33, 192, 236, 129, 214, 59, 85, 33, 192, 236, 129, 214, 59, 85, 251, + 112, 214, 59, 204, 63, 251, 112, 214, 59, 45, 85, 52, 163, 244, 160, 211, + 62, 117, 214, 59, 45, 85, 52, 244, 160, 211, 62, 117, 214, 59, 45, 85, + 126, 52, 244, 160, 211, 62, 117, 214, 59, 85, 226, 27, 214, 59, 45, 226, + 27, 214, 59, 85, 45, 226, 27, 214, 59, 199, 48, 85, 205, 177, 199, 48, + 85, 210, 90, 205, 177, 245, 100, 248, 113, 210, 90, 245, 100, 248, 113, + 209, 217, 232, 108, 204, 248, 221, 252, 210, 220, 247, 116, 232, 44, 201, + 207, 232, 44, 201, 208, 3, 248, 6, 216, 20, 201, 207, 219, 136, 175, 210, + 221, 204, 254, 201, 205, 201, 206, 247, 116, 247, 237, 214, 116, 247, + 237, 201, 153, 247, 238, 204, 226, 219, 22, 251, 116, 235, 119, 236, 214, + 212, 99, 247, 116, 214, 116, 212, 99, 247, 116, 203, 78, 214, 116, 203, + 78, 250, 137, 214, 116, 250, 137, 210, 165, 199, 110, 239, 216, 201, 144, + 250, 208, 221, 219, 201, 214, 218, 202, 218, 170, 210, 219, 204, 77, 210, + 219, 218, 170, 247, 168, 251, 231, 201, 204, 206, 207, 209, 184, 205, + 130, 231, 155, 201, 211, 222, 95, 83, 201, 211, 222, 95, 241, 136, 55, + 212, 99, 247, 100, 210, 83, 222, 95, 201, 177, 235, 94, 214, 120, 212, + 73, 239, 1, 216, 51, 236, 200, 55, 205, 216, 105, 216, 51, 205, 216, 105, + 211, 194, 222, 48, 226, 87, 225, 231, 212, 149, 105, 239, 29, 216, 19, + 222, 48, 105, 212, 67, 197, 128, 105, 216, 35, 197, 128, 105, 248, 180, + 216, 51, 248, 179, 248, 178, 218, 170, 248, 178, 213, 81, 216, 51, 213, + 80, 245, 65, 241, 54, 219, 160, 105, 197, 18, 105, 210, 99, 249, 141, + 105, 202, 18, 197, 128, 244, 200, 206, 162, 249, 53, 249, 51, 213, 118, + 241, 120, 241, 3, 249, 118, 244, 229, 50, 221, 181, 201, 181, 3, 209, + 185, 241, 100, 212, 1, 55, 46, 226, 61, 205, 160, 248, 67, 105, 233, 168, + 105, 241, 92, 26, 222, 239, 205, 243, 252, 19, 206, 185, 249, 117, 248, + 228, 248, 229, 248, 252, 212, 149, 77, 197, 2, 214, 172, 55, 206, 185, + 201, 154, 204, 176, 213, 224, 232, 40, 203, 26, 232, 217, 26, 196, 252, + 206, 220, 214, 145, 237, 206, 218, 174, 210, 220, 201, 216, 218, 177, + 248, 112, 200, 35, 219, 33, 251, 187, 200, 35, 251, 187, 200, 35, 4, 251, + 187, 4, 251, 187, 216, 24, 251, 187, 251, 188, 239, 200, 251, 188, 250, + 220, 208, 195, 214, 116, 235, 119, 236, 214, 239, 130, 221, 252, 213, + 122, 206, 207, 208, 160, 218, 177, 208, 160, 247, 127, 205, 245, 235, 54, + 208, 190, 206, 5, 250, 139, 210, 58, 150, 16, 36, 211, 68, 150, 16, 36, + 251, 189, 150, 16, 36, 235, 118, 150, 16, 36, 237, 72, 150, 16, 36, 197, + 127, 150, 16, 36, 251, 16, 150, 16, 36, 251, 17, 210, 152, 150, 16, 36, + 251, 17, 210, 151, 150, 16, 36, 251, 17, 198, 254, 150, 16, 36, 251, 17, + 198, 253, 150, 16, 36, 199, 12, 150, 16, 36, 199, 11, 150, 16, 36, 199, + 10, 150, 16, 36, 204, 118, 150, 16, 36, 212, 238, 204, 118, 150, 16, 36, + 58, 204, 118, 150, 16, 36, 219, 159, 204, 149, 150, 16, 36, 219, 159, + 204, 148, 150, 16, 36, 219, 159, 204, 147, 150, 16, 36, 244, 252, 150, + 16, 36, 208, 233, 150, 16, 36, 216, 167, 150, 16, 36, 198, 252, 150, 16, + 36, 198, 251, 150, 16, 36, 209, 218, 208, 233, 150, 16, 36, 209, 218, + 208, 232, 150, 16, 36, 233, 135, 150, 16, 36, 206, 75, 150, 16, 36, 225, + 254, 214, 66, 150, 16, 36, 225, 254, 214, 65, 150, 16, 36, 241, 66, 77, + 225, 253, 150, 16, 36, 210, 148, 77, 225, 253, 150, 16, 36, 241, 111, + 214, 66, 150, 16, 36, 225, 252, 214, 66, 150, 16, 36, 204, 150, 77, 241, + 110, 150, 16, 36, 241, 66, 77, 241, 110, 150, 16, 36, 241, 66, 77, 241, + 109, 150, 16, 36, 241, 111, 251, 59, 150, 16, 36, 208, 234, 77, 241, 111, + 251, 59, 150, 16, 36, 204, 150, 77, 208, 234, 77, 241, 110, 150, 16, 36, + 199, 104, 150, 16, 36, 202, 75, 214, 66, 150, 16, 36, 222, 196, 214, 66, + 150, 16, 36, 251, 58, 214, 66, 150, 16, 36, 204, 150, 77, 251, 57, 150, + 16, 36, 208, 234, 77, 251, 57, 150, 16, 36, 204, 150, 77, 208, 234, 77, + 251, 57, 150, 16, 36, 199, 13, 77, 251, 57, 150, 16, 36, 210, 148, 77, + 251, 57, 150, 16, 36, 210, 148, 77, 251, 56, 150, 16, 36, 210, 147, 150, + 16, 36, 210, 146, 150, 16, 36, 210, 145, 150, 16, 36, 210, 144, 150, 16, + 36, 251, 149, 150, 16, 36, 251, 148, 150, 16, 36, 220, 34, 150, 16, 36, + 208, 240, 150, 16, 36, 250, 213, 150, 16, 36, 210, 176, 150, 16, 36, 210, + 175, 150, 16, 36, 250, 141, 150, 16, 36, 248, 146, 214, 66, 150, 16, 36, + 203, 99, 150, 16, 36, 203, 98, 150, 16, 36, 211, 74, 222, 84, 150, 16, + 36, 248, 93, 150, 16, 36, 248, 92, 150, 16, 36, 248, 91, 150, 16, 36, + 251, 125, 150, 16, 36, 214, 144, 150, 16, 36, 205, 117, 150, 16, 36, 202, + 73, 150, 16, 36, 233, 55, 150, 16, 36, 197, 115, 150, 16, 36, 212, 61, + 150, 16, 36, 247, 151, 150, 16, 36, 200, 252, 150, 16, 36, 247, 118, 218, + 183, 150, 16, 36, 208, 170, 77, 225, 115, 150, 16, 36, 247, 165, 150, 16, + 36, 201, 174, 150, 16, 36, 205, 5, 201, 174, 150, 16, 36, 221, 251, 150, + 16, 36, 205, 191, 150, 16, 36, 200, 13, 150, 16, 36, 231, 99, 237, 184, + 150, 16, 36, 250, 190, 150, 16, 36, 212, 69, 250, 190, 150, 16, 36, 248, + 42, 150, 16, 36, 212, 60, 248, 42, 150, 16, 36, 251, 122, 150, 16, 36, + 204, 213, 204, 99, 204, 212, 150, 16, 36, 204, 213, 204, 99, 204, 211, + 150, 16, 36, 204, 146, 150, 16, 36, 212, 33, 150, 16, 36, 239, 68, 150, + 16, 36, 239, 70, 150, 16, 36, 239, 69, 150, 16, 36, 211, 203, 150, 16, + 36, 211, 192, 150, 16, 36, 241, 52, 150, 16, 36, 241, 51, 150, 16, 36, + 241, 50, 150, 16, 36, 241, 49, 150, 16, 36, 241, 48, 150, 16, 36, 251, + 163, 150, 16, 36, 249, 54, 77, 220, 15, 150, 16, 36, 249, 54, 77, 199, + 138, 150, 16, 36, 210, 97, 150, 16, 36, 231, 91, 150, 16, 36, 216, 194, + 150, 16, 36, 240, 53, 150, 16, 36, 218, 197, 150, 16, 36, 157, 237, 221, + 150, 16, 36, 157, 214, 37, 58, 222, 179, 225, 237, 53, 201, 180, 58, 200, + 35, 225, 237, 53, 201, 180, 58, 210, 17, 225, 237, 53, 201, 180, 58, 237, + 234, 225, 237, 53, 201, 180, 58, 205, 236, 4, 244, 249, 219, 190, 27, 59, + 244, 249, 27, 59, 244, 249, 85, 59, 244, 249, 199, 48, 85, 59, 244, 249, + 236, 71, 85, 59, 244, 249, 59, 244, 250, 241, 132, 58, 4, 244, 249, 209, + 187, 203, 100, 58, 202, 70, 205, 94, 58, 205, 236, 4, 205, 94, 175, 59, + 205, 94, 219, 190, 59, 205, 94, 27, 59, 205, 94, 85, 59, 205, 94, 199, + 48, 85, 59, 205, 94, 236, 71, 85, 59, 205, 94, 59, 47, 241, 132, 58, 199, + 48, 4, 205, 94, 59, 47, 241, 132, 58, 219, 190, 205, 94, 47, 203, 100, + 58, 202, 70, 239, 140, 58, 199, 48, 4, 239, 140, 58, 219, 190, 4, 239, + 140, 59, 239, 141, 241, 132, 58, 199, 48, 4, 239, 140, 59, 239, 141, 241, + 132, 58, 219, 190, 239, 140, 239, 141, 203, 100, 58, 202, 70, 221, 198, + 58, 199, 48, 4, 221, 198, 58, 219, 190, 4, 221, 198, 59, 221, 199, 241, + 132, 58, 4, 221, 198, 202, 188, 32, 241, 61, 175, 32, 241, 61, 219, 190, + 32, 241, 61, 27, 32, 241, 61, 199, 48, 27, 32, 241, 61, 199, 48, 85, 32, + 241, 61, 236, 71, 85, 32, 241, 61, 202, 188, 208, 230, 175, 208, 230, + 219, 190, 208, 230, 27, 208, 230, 85, 208, 230, 199, 48, 85, 208, 230, + 236, 71, 85, 208, 230, 175, 235, 101, 205, 110, 250, 179, 219, 190, 235, + 101, 205, 110, 250, 179, 27, 235, 101, 205, 110, 250, 179, 85, 235, 101, + 205, 110, 250, 179, 199, 48, 85, 235, 101, 205, 110, 250, 179, 236, 71, + 85, 235, 101, 205, 110, 250, 179, 175, 206, 29, 205, 110, 250, 179, 219, + 190, 206, 29, 205, 110, 250, 179, 27, 206, 29, 205, 110, 250, 179, 85, + 206, 29, 205, 110, 250, 179, 199, 48, 85, 206, 29, 205, 110, 250, 179, + 236, 71, 85, 206, 29, 205, 110, 250, 179, 175, 237, 31, 205, 110, 250, + 179, 219, 190, 237, 31, 205, 110, 250, 179, 27, 237, 31, 205, 110, 250, + 179, 85, 237, 31, 205, 110, 250, 179, 199, 48, 85, 237, 31, 205, 110, + 250, 179, 175, 115, 212, 109, 58, 205, 7, 219, 190, 115, 212, 109, 58, + 205, 7, 115, 212, 109, 58, 205, 7, 219, 190, 115, 212, 109, 212, 170, + 205, 7, 175, 235, 7, 212, 109, 58, 205, 7, 219, 190, 235, 7, 212, 109, + 58, 205, 7, 235, 7, 212, 109, 58, 205, 7, 219, 190, 235, 7, 212, 109, + 212, 170, 205, 7, 210, 90, 175, 235, 7, 212, 109, 212, 170, 205, 7, 175, + 235, 101, 212, 109, 58, 205, 7, 85, 235, 101, 212, 109, 58, 205, 7, 219, + 190, 206, 29, 212, 109, 58, 205, 7, 85, 206, 29, 212, 109, 58, 205, 7, + 206, 29, 212, 109, 212, 170, 205, 7, 219, 190, 237, 31, 212, 109, 58, + 205, 7, 85, 237, 31, 212, 109, 58, 205, 7, 199, 48, 85, 237, 31, 212, + 109, 58, 205, 7, 85, 237, 31, 212, 109, 212, 170, 205, 7, 175, 200, 240, + 212, 109, 58, 205, 7, 85, 200, 240, 212, 109, 58, 205, 7, 85, 200, 240, + 212, 109, 212, 170, 205, 7, 46, 201, 180, 217, 104, 46, 201, 180, 46, + 205, 94, 217, 104, 46, 205, 94, 222, 228, 214, 71, 244, 249, 222, 228, + 196, 62, 244, 249, 222, 228, 233, 91, 244, 249, 222, 228, 211, 200, 244, + 249, 222, 228, 248, 30, 244, 249, 222, 228, 210, 158, 205, 94, 222, 228, + 248, 119, 205, 94, 222, 228, 214, 71, 205, 94, 222, 228, 196, 62, 205, + 94, 222, 228, 233, 91, 205, 94, 222, 228, 211, 200, 205, 94, 222, 228, + 248, 30, 205, 94, 107, 61, 3, 4, 201, 181, 250, 217, 200, 24, 61, 3, 4, + 201, 181, 250, 217, 91, 61, 3, 4, 201, 181, 250, 217, 237, 231, 61, 3, 4, + 201, 181, 250, 217, 107, 61, 3, 219, 190, 201, 181, 250, 217, 200, 24, + 61, 3, 219, 190, 201, 181, 250, 217, 91, 61, 3, 219, 190, 201, 181, 250, + 217, 237, 231, 61, 3, 219, 190, 201, 181, 250, 217, 107, 61, 3, 222, 228, + 201, 181, 250, 217, 200, 24, 61, 3, 222, 228, 201, 181, 250, 217, 91, 61, + 3, 222, 228, 201, 181, 250, 217, 237, 231, 61, 3, 222, 228, 201, 181, + 250, 217, 107, 61, 3, 4, 236, 166, 250, 217, 200, 24, 61, 3, 4, 236, 166, + 250, 217, 91, 61, 3, 4, 236, 166, 250, 217, 237, 231, 61, 3, 4, 236, 166, + 250, 217, 107, 61, 3, 236, 166, 250, 217, 200, 24, 61, 3, 236, 166, 250, + 217, 91, 61, 3, 236, 166, 250, 217, 237, 231, 61, 3, 236, 166, 250, 217, + 85, 107, 61, 3, 236, 166, 250, 217, 85, 200, 24, 61, 3, 236, 166, 250, + 217, 85, 91, 61, 3, 236, 166, 250, 217, 85, 237, 231, 61, 3, 236, 166, + 250, 217, 85, 107, 61, 3, 222, 228, 236, 166, 250, 217, 85, 200, 24, 61, + 3, 222, 228, 236, 166, 250, 217, 85, 91, 61, 3, 222, 228, 236, 166, 250, + 217, 85, 237, 231, 61, 3, 222, 228, 236, 166, 250, 217, 107, 201, 179, + 61, 3, 217, 210, 207, 35, 200, 24, 201, 179, 61, 3, 217, 210, 207, 35, + 91, 201, 179, 61, 3, 217, 210, 207, 35, 237, 231, 201, 179, 61, 3, 217, + 210, 207, 35, 107, 201, 179, 61, 3, 219, 190, 207, 35, 200, 24, 201, 179, + 61, 3, 219, 190, 207, 35, 91, 201, 179, 61, 3, 219, 190, 207, 35, 237, + 231, 201, 179, 61, 3, 219, 190, 207, 35, 107, 201, 179, 61, 3, 27, 207, + 35, 200, 24, 201, 179, 61, 3, 27, 207, 35, 91, 201, 179, 61, 3, 27, 207, + 35, 237, 231, 201, 179, 61, 3, 27, 207, 35, 107, 201, 179, 61, 3, 85, + 207, 35, 200, 24, 201, 179, 61, 3, 85, 207, 35, 91, 201, 179, 61, 3, 85, + 207, 35, 237, 231, 201, 179, 61, 3, 85, 207, 35, 107, 201, 179, 61, 3, + 199, 48, 85, 207, 35, 200, 24, 201, 179, 61, 3, 199, 48, 85, 207, 35, 91, + 201, 179, 61, 3, 199, 48, 85, 207, 35, 237, 231, 201, 179, 61, 3, 199, + 48, 85, 207, 35, 107, 235, 126, 51, 200, 24, 235, 126, 51, 91, 235, 126, + 51, 237, 231, 235, 126, 51, 107, 103, 51, 200, 24, 103, 51, 91, 103, 51, + 237, 231, 103, 51, 107, 241, 159, 51, 200, 24, 241, 159, 51, 91, 241, + 159, 51, 237, 231, 241, 159, 51, 107, 85, 241, 159, 51, 200, 24, 85, 241, + 159, 51, 91, 85, 241, 159, 51, 237, 231, 85, 241, 159, 51, 107, 85, 51, + 200, 24, 85, 51, 91, 85, 51, 237, 231, 85, 51, 107, 45, 51, 200, 24, 45, + 51, 91, 45, 51, 237, 231, 45, 51, 173, 197, 89, 45, 51, 173, 237, 69, 45, + 51, 205, 159, 237, 69, 45, 51, 205, 159, 197, 89, 45, 51, 50, 53, 45, 51, + 124, 135, 45, 51, 197, 61, 107, 175, 165, 51, 197, 61, 200, 24, 175, 165, + 51, 197, 61, 91, 175, 165, 51, 197, 61, 237, 231, 175, 165, 51, 197, 61, + 173, 197, 89, 175, 165, 51, 197, 61, 173, 237, 69, 175, 165, 51, 197, 61, + 205, 159, 237, 69, 175, 165, 51, 197, 61, 205, 159, 197, 89, 175, 165, + 51, 197, 61, 107, 165, 51, 197, 61, 200, 24, 165, 51, 197, 61, 91, 165, + 51, 197, 61, 237, 231, 165, 51, 197, 61, 173, 197, 89, 165, 51, 197, 61, + 173, 237, 69, 165, 51, 197, 61, 205, 159, 237, 69, 165, 51, 197, 61, 205, + 159, 197, 89, 165, 51, 197, 61, 107, 219, 190, 165, 51, 197, 61, 200, 24, + 219, 190, 165, 51, 197, 61, 91, 219, 190, 165, 51, 197, 61, 237, 231, + 219, 190, 165, 51, 197, 61, 173, 197, 89, 219, 190, 165, 51, 197, 61, + 173, 237, 69, 219, 190, 165, 51, 197, 61, 205, 159, 237, 69, 219, 190, + 165, 51, 197, 61, 205, 159, 197, 89, 219, 190, 165, 51, 197, 61, 107, 85, + 165, 51, 197, 61, 200, 24, 85, 165, 51, 197, 61, 91, 85, 165, 51, 197, + 61, 237, 231, 85, 165, 51, 197, 61, 173, 197, 89, 85, 165, 51, 197, 61, + 173, 237, 69, 85, 165, 51, 197, 61, 205, 159, 237, 69, 85, 165, 51, 197, + 61, 205, 159, 197, 89, 85, 165, 51, 197, 61, 107, 199, 48, 85, 165, 51, + 197, 61, 200, 24, 199, 48, 85, 165, 51, 197, 61, 91, 199, 48, 85, 165, + 51, 197, 61, 237, 231, 199, 48, 85, 165, 51, 197, 61, 173, 197, 89, 199, + 48, 85, 165, 51, 197, 61, 173, 237, 69, 199, 48, 85, 165, 51, 197, 61, + 205, 159, 237, 69, 199, 48, 85, 165, 51, 197, 61, 205, 159, 197, 89, 199, + 48, 85, 165, 51, 107, 201, 181, 250, 217, 200, 24, 201, 181, 250, 217, + 91, 201, 181, 250, 217, 237, 231, 201, 181, 250, 217, 107, 59, 61, 197, + 39, 201, 181, 250, 217, 200, 24, 59, 61, 197, 39, 201, 181, 250, 217, 91, + 59, 61, 197, 39, 201, 181, 250, 217, 237, 231, 59, 61, 197, 39, 201, 181, + 250, 217, 107, 61, 3, 216, 15, 203, 135, 200, 24, 61, 3, 216, 15, 203, + 135, 91, 61, 3, 216, 15, 203, 135, 237, 231, 61, 3, 216, 15, 203, 135, + 85, 61, 207, 36, 197, 59, 100, 85, 61, 207, 36, 197, 59, 99, 202, 181, + 85, 61, 207, 36, 197, 59, 97, 232, 225, 85, 61, 207, 36, 197, 59, 97, + 202, 184, 107, 248, 82, 59, 51, 91, 248, 85, 207, 38, 59, 51, 107, 201, + 243, 207, 38, 59, 51, 91, 201, 243, 207, 38, 59, 51, 107, 222, 178, 59, + 51, 91, 210, 16, 59, 51, 107, 210, 16, 59, 51, 91, 222, 178, 59, 51, 107, + 249, 137, 207, 37, 59, 51, 91, 249, 137, 207, 37, 59, 51, 107, 234, 232, + 207, 37, 59, 51, 91, 234, 232, 207, 37, 59, 51, 59, 61, 207, 36, 197, 59, + 100, 59, 61, 207, 36, 197, 59, 99, 202, 181, 46, 241, 62, 235, 21, 3, + 235, 7, 238, 250, 46, 241, 62, 235, 21, 3, 99, 238, 250, 46, 241, 62, + 235, 20, 50, 157, 244, 250, 3, 235, 7, 238, 250, 50, 157, 244, 250, 3, + 115, 238, 250, 50, 157, 244, 250, 3, 99, 238, 250, 50, 157, 244, 250, 3, + 238, 253, 50, 157, 244, 249, 237, 232, 235, 226, 122, 237, 232, 235, 226, + 216, 15, 122, 237, 232, 235, 226, 231, 165, 3, 238, 253, 237, 232, 235, + 226, 216, 15, 231, 165, 3, 238, 253, 59, 232, 126, 248, 30, 232, 126, + 212, 174, 232, 209, 195, 20, 235, 233, 218, 213, 235, 233, 235, 234, 3, + 202, 205, 217, 92, 235, 233, 202, 186, 235, 233, 235, 234, 3, 232, 136, + 209, 220, 235, 233, 231, 66, 235, 233, 2, 77, 202, 218, 231, 101, 247, + 153, 219, 208, 232, 209, 210, 215, 249, 139, 77, 232, 209, 222, 183, 235, + 106, 210, 21, 235, 106, 232, 183, 232, 210, 3, 132, 26, 112, 235, 123, + 241, 58, 230, 249, 221, 209, 195, 231, 232, 210, 55, 235, 234, 3, 241, + 82, 232, 165, 244, 192, 235, 233, 217, 199, 235, 233, 209, 210, 214, 120, + 202, 218, 235, 70, 222, 214, 237, 212, 235, 233, 221, 146, 235, 233, 235, + 234, 213, 206, 205, 210, 235, 233, 235, 234, 3, 97, 236, 66, 210, 214, + 233, 87, 235, 234, 3, 205, 8, 236, 59, 233, 87, 235, 234, 3, 97, 222, + 228, 26, 97, 4, 236, 67, 235, 234, 3, 235, 128, 241, 85, 244, 203, 222, + 59, 207, 82, 235, 234, 3, 203, 250, 241, 85, 218, 164, 205, 218, 235, + 234, 3, 205, 218, 236, 60, 26, 232, 210, 241, 85, 218, 164, 235, 234, 3, + 192, 218, 165, 198, 234, 206, 196, 235, 234, 3, 236, 82, 232, 137, 212, + 30, 197, 21, 248, 50, 213, 205, 124, 202, 19, 207, 111, 212, 18, 220, 63, + 226, 87, 200, 248, 218, 179, 245, 37, 206, 155, 213, 29, 239, 14, 247, + 97, 225, 105, 235, 168, 218, 238, 213, 52, 196, 251, 197, 128, 212, 97, + 232, 188, 239, 55, 220, 9, 197, 53, 235, 62, 237, 207, 3, 237, 205, 244, + 210, 233, 156, 201, 20, 233, 157, 205, 107, 233, 142, 217, 88, 210, 23, + 235, 113, 212, 149, 219, 196, 208, 136, 212, 149, 219, 196, 202, 185, + 212, 149, 219, 196, 248, 69, 233, 151, 220, 19, 250, 206, 200, 53, 241, + 19, 204, 228, 223, 67, 204, 238, 26, 249, 103, 205, 185, 235, 54, 239, + 78, 241, 65, 250, 128, 241, 34, 249, 130, 212, 66, 247, 101, 249, 116, + 248, 53, 233, 91, 208, 238, 207, 28, 213, 192, 77, 235, 39, 204, 177, + 235, 81, 237, 45, 233, 158, 77, 219, 32, 213, 86, 224, 51, 213, 188, 237, + 189, 235, 16, 241, 115, 203, 127, 248, 70, 245, 43, 248, 75, 3, 205, 107, + 241, 28, 3, 204, 210, 244, 177, 248, 34, 212, 213, 212, 22, 241, 2, 77, + 219, 199, 208, 214, 247, 129, 235, 39, 222, 191, 233, 90, 220, 54, 218, + 190, 247, 160, 249, 119, 205, 218, 235, 234, 3, 205, 218, 236, 60, 26, + 115, 232, 124, 196, 76, 235, 233, 235, 234, 3, 213, 129, 231, 103, 26, + 213, 129, 232, 165, 235, 234, 3, 200, 57, 236, 60, 26, 197, 119, 218, + 164, 214, 25, 235, 233, 234, 244, 235, 233, 235, 234, 3, 212, 136, 236, + 59, 208, 202, 223, 76, 244, 179, 233, 138, 232, 42, 248, 97, 235, 83, + 206, 194, 241, 79, 222, 63, 235, 233, 208, 158, 201, 8, 200, 55, 235, + 233, 237, 79, 237, 197, 249, 56, 207, 14, 214, 15, 234, 255, 235, 233, + 247, 229, 239, 234, 233, 124, 222, 42, 210, 76, 206, 157, 205, 88, 233, + 170, 235, 233, 195, 86, 235, 233, 232, 119, 208, 187, 203, 215, 241, 68, + 225, 12, 222, 34, 213, 88, 232, 34, 213, 135, 210, 239, 222, 5, 218, 181, + 219, 68, 249, 125, 204, 65, 205, 230, 214, 42, 214, 70, 205, 253, 235, + 85, 214, 5, 233, 60, 239, 17, 212, 7, 247, 131, 236, 236, 244, 149, 210, + 158, 232, 233, 236, 236, 244, 149, 241, 18, 232, 233, 236, 236, 244, 149, + 249, 105, 236, 236, 244, 149, 59, 232, 233, 248, 104, 222, 172, 235, 37, + 201, 244, 204, 97, 204, 92, 209, 4, 199, 46, 237, 77, 3, 232, 128, 251, + 199, 218, 175, 197, 75, 220, 46, 197, 75, 219, 198, 250, 231, 219, 198, + 222, 172, 245, 94, 197, 100, 241, 26, 208, 234, 207, 32, 248, 202, 248, + 70, 234, 80, 214, 108, 235, 215, 197, 155, 247, 230, 220, 3, 237, 216, + 230, 202, 241, 36, 205, 10, 213, 28, 224, 23, 213, 28, 239, 250, 213, 28, + 235, 234, 3, 218, 208, 251, 249, 245, 66, 214, 132, 251, 249, 249, 1, + 213, 28, 213, 29, 3, 232, 132, 213, 29, 226, 87, 204, 245, 209, 202, 213, + 29, 244, 212, 213, 29, 226, 87, 221, 214, 212, 78, 220, 92, 235, 217, + 199, 141, 219, 152, 236, 250, 234, 31, 195, 9, 248, 60, 214, 71, 232, + 126, 248, 167, 247, 125, 208, 171, 233, 150, 244, 179, 205, 188, 210, + 158, 233, 182, 236, 194, 235, 117, 225, 166, 211, 188, 212, 212, 203, 3, + 201, 30, 213, 13, 239, 75, 239, 30, 52, 232, 107, 244, 154, 252, 33, 235, + 119, 236, 76, 201, 246, 248, 42, 220, 91, 221, 181, 221, 215, 248, 86, + 205, 108, 77, 202, 156, 249, 104, 77, 196, 89, 209, 4, 212, 176, 203, 51, + 249, 2, 248, 31, 249, 61, 209, 213, 77, 213, 161, 249, 80, 77, 205, 191, + 205, 109, 210, 174, 217, 193, 251, 108, 217, 85, 245, 83, 224, 73, 217, + 85, 245, 83, 211, 80, 217, 85, 245, 83, 209, 203, 217, 85, 245, 83, 248, + 148, 217, 85, 245, 83, 224, 19, 217, 85, 245, 83, 213, 103, 59, 245, 83, + 224, 20, 209, 194, 235, 13, 239, 230, 58, 245, 83, 224, 20, 209, 194, + 235, 13, 239, 230, 217, 85, 245, 83, 224, 20, 209, 194, 235, 13, 239, + 230, 59, 245, 83, 224, 74, 209, 194, 216, 175, 239, 230, 59, 245, 83, + 211, 81, 209, 194, 216, 175, 239, 230, 59, 245, 83, 209, 204, 209, 194, + 216, 175, 239, 230, 59, 245, 83, 248, 149, 209, 194, 216, 175, 239, 230, + 59, 245, 83, 224, 20, 209, 194, 216, 175, 239, 230, 59, 245, 83, 213, + 104, 209, 194, 216, 175, 239, 230, 58, 245, 83, 224, 74, 209, 194, 216, + 175, 239, 230, 58, 245, 83, 211, 81, 209, 194, 216, 175, 239, 230, 58, + 245, 83, 209, 204, 209, 194, 216, 175, 239, 230, 58, 245, 83, 248, 149, + 209, 194, 216, 175, 239, 230, 58, 245, 83, 224, 20, 209, 194, 216, 175, + 239, 230, 58, 245, 83, 213, 104, 209, 194, 216, 175, 239, 230, 217, 85, + 245, 83, 224, 74, 209, 194, 216, 175, 239, 230, 217, 85, 245, 83, 211, + 81, 209, 194, 216, 175, 239, 230, 217, 85, 245, 83, 209, 204, 209, 194, + 216, 175, 239, 230, 217, 85, 245, 83, 248, 149, 209, 194, 216, 175, 239, + 230, 217, 85, 245, 83, 224, 20, 209, 194, 216, 175, 239, 230, 217, 85, + 245, 83, 213, 104, 209, 194, 216, 175, 239, 230, 59, 245, 83, 224, 20, + 209, 194, 97, 231, 58, 202, 176, 239, 230, 58, 245, 83, 224, 20, 209, + 194, 97, 231, 58, 202, 176, 239, 230, 217, 85, 245, 83, 224, 20, 209, + 194, 97, 231, 58, 202, 176, 239, 230, 59, 245, 83, 163, 224, 73, 59, 245, + 83, 163, 211, 80, 59, 245, 83, 163, 209, 203, 59, 245, 83, 163, 248, 148, + 59, 245, 83, 163, 224, 19, 59, 245, 83, 163, 213, 103, 58, 245, 83, 163, + 224, 73, 58, 245, 83, 163, 211, 80, 58, 245, 83, 163, 209, 203, 58, 245, + 83, 163, 248, 148, 58, 245, 83, 163, 224, 19, 58, 245, 83, 163, 213, 103, + 217, 85, 245, 83, 163, 224, 73, 217, 85, 245, 83, 163, 211, 80, 217, 85, + 245, 83, 163, 209, 203, 217, 85, 245, 83, 163, 248, 148, 217, 85, 245, + 83, 163, 224, 19, 217, 85, 245, 83, 163, 213, 103, 59, 245, 83, 224, 20, + 209, 194, 99, 231, 58, 200, 231, 239, 230, 58, 245, 83, 224, 20, 209, + 194, 99, 231, 58, 200, 231, 239, 230, 217, 85, 245, 83, 224, 20, 209, + 194, 99, 231, 58, 200, 231, 239, 230, 59, 245, 83, 224, 74, 209, 194, 99, + 231, 58, 207, 66, 239, 230, 59, 245, 83, 211, 81, 209, 194, 99, 231, 58, + 207, 66, 239, 230, 59, 245, 83, 209, 204, 209, 194, 99, 231, 58, 207, 66, + 239, 230, 59, 245, 83, 248, 149, 209, 194, 99, 231, 58, 207, 66, 239, + 230, 59, 245, 83, 224, 20, 209, 194, 99, 231, 58, 207, 66, 239, 230, 59, + 245, 83, 213, 104, 209, 194, 99, 231, 58, 207, 66, 239, 230, 58, 245, 83, + 224, 74, 209, 194, 99, 231, 58, 207, 66, 239, 230, 58, 245, 83, 211, 81, + 209, 194, 99, 231, 58, 207, 66, 239, 230, 58, 245, 83, 209, 204, 209, + 194, 99, 231, 58, 207, 66, 239, 230, 58, 245, 83, 248, 149, 209, 194, 99, + 231, 58, 207, 66, 239, 230, 58, 245, 83, 224, 20, 209, 194, 99, 231, 58, + 207, 66, 239, 230, 58, 245, 83, 213, 104, 209, 194, 99, 231, 58, 207, 66, + 239, 230, 217, 85, 245, 83, 224, 74, 209, 194, 99, 231, 58, 207, 66, 239, + 230, 217, 85, 245, 83, 211, 81, 209, 194, 99, 231, 58, 207, 66, 239, 230, + 217, 85, 245, 83, 209, 204, 209, 194, 99, 231, 58, 207, 66, 239, 230, + 217, 85, 245, 83, 248, 149, 209, 194, 99, 231, 58, 207, 66, 239, 230, + 217, 85, 245, 83, 224, 20, 209, 194, 99, 231, 58, 207, 66, 239, 230, 217, + 85, 245, 83, 213, 104, 209, 194, 99, 231, 58, 207, 66, 239, 230, 59, 245, + 83, 224, 20, 209, 194, 115, 231, 58, 235, 150, 239, 230, 58, 245, 83, + 224, 20, 209, 194, 115, 231, 58, 235, 150, 239, 230, 217, 85, 245, 83, + 224, 20, 209, 194, 115, 231, 58, 235, 150, 239, 230, 59, 245, 83, 236, + 167, 58, 245, 83, 236, 167, 217, 85, 245, 83, 236, 167, 59, 245, 83, 236, + 168, 209, 194, 216, 175, 239, 230, 58, 245, 83, 236, 168, 209, 194, 216, + 175, 239, 230, 217, 85, 245, 83, 236, 168, 209, 194, 216, 175, 239, 230, + 59, 245, 83, 224, 17, 59, 245, 83, 224, 16, 59, 245, 83, 224, 18, 58, + 245, 83, 224, 17, 58, 245, 83, 224, 16, 58, 245, 83, 224, 18, 196, 194, + 210, 158, 234, 33, 196, 194, 210, 158, 220, 56, 196, 194, 210, 158, 236, + 255, 196, 194, 210, 158, 231, 98, 196, 194, 210, 158, 245, 112, 196, 194, + 210, 158, 247, 128, 196, 194, 210, 158, 205, 180, 196, 194, 58, 234, 33, + 196, 194, 58, 220, 56, 196, 194, 58, 236, 255, 196, 194, 58, 231, 98, + 196, 194, 58, 245, 112, 196, 194, 58, 247, 128, 196, 194, 58, 205, 180, + 249, 102, 206, 193, 214, 113, 204, 52, 248, 38, 206, 167, 237, 211, 77, + 248, 124, 251, 255, 249, 88, 204, 239, 195, 244, 224, 54, 213, 155, 210, + 1, 212, 141, 247, 11, 210, 187, 250, 123, 239, 50, 222, 239, 249, 86, 12, + 15, 230, 190, 12, 15, 230, 189, 12, 15, 230, 188, 12, 15, 230, 187, 12, + 15, 230, 186, 12, 15, 230, 185, 12, 15, 230, 184, 12, 15, 230, 183, 12, + 15, 230, 182, 12, 15, 230, 181, 12, 15, 230, 180, 12, 15, 230, 179, 12, + 15, 230, 178, 12, 15, 230, 177, 12, 15, 230, 176, 12, 15, 230, 175, 12, + 15, 230, 174, 12, 15, 230, 173, 12, 15, 230, 172, 12, 15, 230, 171, 12, + 15, 230, 170, 12, 15, 230, 169, 12, 15, 230, 168, 12, 15, 230, 167, 12, + 15, 230, 166, 12, 15, 230, 165, 12, 15, 230, 164, 12, 15, 230, 163, 12, + 15, 230, 162, 12, 15, 230, 161, 12, 15, 230, 160, 12, 15, 230, 159, 12, + 15, 230, 158, 12, 15, 230, 157, 12, 15, 230, 156, 12, 15, 230, 155, 12, + 15, 230, 154, 12, 15, 230, 153, 12, 15, 230, 152, 12, 15, 230, 151, 12, + 15, 230, 150, 12, 15, 230, 149, 12, 15, 230, 148, 12, 15, 230, 147, 12, + 15, 230, 146, 12, 15, 230, 145, 12, 15, 230, 144, 12, 15, 230, 143, 12, + 15, 230, 142, 12, 15, 230, 141, 12, 15, 230, 140, 12, 15, 230, 139, 12, + 15, 230, 138, 12, 15, 230, 137, 12, 15, 230, 136, 12, 15, 230, 135, 12, + 15, 230, 134, 12, 15, 230, 133, 12, 15, 230, 132, 12, 15, 230, 131, 12, + 15, 230, 130, 12, 15, 230, 129, 12, 15, 230, 128, 12, 15, 230, 127, 12, + 15, 230, 126, 12, 15, 230, 125, 12, 15, 230, 124, 12, 15, 230, 123, 12, + 15, 230, 122, 12, 15, 230, 121, 12, 15, 230, 120, 12, 15, 230, 119, 12, + 15, 230, 118, 12, 15, 230, 117, 12, 15, 230, 116, 12, 15, 230, 115, 12, + 15, 230, 114, 12, 15, 230, 113, 12, 15, 230, 112, 12, 15, 230, 111, 12, + 15, 230, 110, 12, 15, 230, 109, 12, 15, 230, 108, 12, 15, 230, 107, 12, + 15, 230, 106, 12, 15, 230, 105, 12, 15, 230, 104, 12, 15, 230, 103, 12, + 15, 230, 102, 12, 15, 230, 101, 12, 15, 230, 100, 12, 15, 230, 99, 12, + 15, 230, 98, 12, 15, 230, 97, 12, 15, 230, 96, 12, 15, 230, 95, 12, 15, + 230, 94, 12, 15, 230, 93, 12, 15, 230, 92, 12, 15, 230, 91, 12, 15, 230, + 90, 12, 15, 230, 89, 12, 15, 230, 88, 12, 15, 230, 87, 12, 15, 230, 86, + 12, 15, 230, 85, 12, 15, 230, 84, 12, 15, 230, 83, 12, 15, 230, 82, 12, + 15, 230, 81, 12, 15, 230, 80, 12, 15, 230, 79, 12, 15, 230, 78, 12, 15, + 230, 77, 12, 15, 230, 76, 12, 15, 230, 75, 12, 15, 230, 74, 12, 15, 230, + 73, 12, 15, 230, 72, 12, 15, 230, 71, 12, 15, 230, 70, 12, 15, 230, 69, + 12, 15, 230, 68, 12, 15, 230, 67, 12, 15, 230, 66, 12, 15, 230, 65, 12, + 15, 230, 64, 12, 15, 230, 63, 12, 15, 230, 62, 12, 15, 230, 61, 12, 15, + 230, 60, 12, 15, 230, 59, 12, 15, 230, 58, 12, 15, 230, 57, 12, 15, 230, + 56, 12, 15, 230, 55, 12, 15, 230, 54, 12, 15, 230, 53, 12, 15, 230, 52, + 12, 15, 230, 51, 12, 15, 230, 50, 12, 15, 230, 49, 12, 15, 230, 48, 12, + 15, 230, 47, 12, 15, 230, 46, 12, 15, 230, 45, 12, 15, 230, 44, 12, 15, + 230, 43, 12, 15, 230, 42, 12, 15, 230, 41, 12, 15, 230, 40, 12, 15, 230, + 39, 12, 15, 230, 38, 12, 15, 230, 37, 12, 15, 230, 36, 12, 15, 230, 35, + 12, 15, 230, 34, 12, 15, 230, 33, 12, 15, 230, 32, 12, 15, 230, 31, 12, + 15, 230, 30, 12, 15, 230, 29, 12, 15, 230, 28, 12, 15, 230, 27, 12, 15, + 230, 26, 12, 15, 230, 25, 12, 15, 230, 24, 12, 15, 230, 23, 12, 15, 230, + 22, 12, 15, 230, 21, 12, 15, 230, 20, 12, 15, 230, 19, 12, 15, 230, 18, + 12, 15, 230, 17, 12, 15, 230, 16, 12, 15, 230, 15, 12, 15, 230, 14, 12, + 15, 230, 13, 12, 15, 230, 12, 12, 15, 230, 11, 12, 15, 230, 10, 12, 15, + 230, 9, 12, 15, 230, 8, 12, 15, 230, 7, 12, 15, 230, 6, 12, 15, 230, 5, + 12, 15, 230, 4, 12, 15, 230, 3, 12, 15, 230, 2, 12, 15, 230, 1, 12, 15, + 230, 0, 12, 15, 229, 255, 12, 15, 229, 254, 12, 15, 229, 253, 12, 15, + 229, 252, 12, 15, 229, 251, 12, 15, 229, 250, 12, 15, 229, 249, 12, 15, + 229, 248, 12, 15, 229, 247, 12, 15, 229, 246, 12, 15, 229, 245, 12, 15, + 229, 244, 12, 15, 229, 243, 12, 15, 229, 242, 12, 15, 229, 241, 12, 15, + 229, 240, 12, 15, 229, 239, 12, 15, 229, 238, 12, 15, 229, 237, 12, 15, + 229, 236, 12, 15, 229, 235, 12, 15, 229, 234, 12, 15, 229, 233, 12, 15, + 229, 232, 12, 15, 229, 231, 12, 15, 229, 230, 12, 15, 229, 229, 12, 15, + 229, 228, 12, 15, 229, 227, 12, 15, 229, 226, 12, 15, 229, 225, 12, 15, + 229, 224, 12, 15, 229, 223, 12, 15, 229, 222, 12, 15, 229, 221, 12, 15, + 229, 220, 12, 15, 229, 219, 12, 15, 229, 218, 12, 15, 229, 217, 12, 15, + 229, 216, 12, 15, 229, 215, 12, 15, 229, 214, 12, 15, 229, 213, 12, 15, + 229, 212, 12, 15, 229, 211, 12, 15, 229, 210, 12, 15, 229, 209, 12, 15, + 229, 208, 12, 15, 229, 207, 12, 15, 229, 206, 12, 15, 229, 205, 12, 15, + 229, 204, 12, 15, 229, 203, 12, 15, 229, 202, 12, 15, 229, 201, 12, 15, + 229, 200, 12, 15, 229, 199, 12, 15, 229, 198, 12, 15, 229, 197, 12, 15, + 229, 196, 12, 15, 229, 195, 12, 15, 229, 194, 12, 15, 229, 193, 12, 15, + 229, 192, 12, 15, 229, 191, 12, 15, 229, 190, 12, 15, 229, 189, 12, 15, + 229, 188, 12, 15, 229, 187, 12, 15, 229, 186, 12, 15, 229, 185, 12, 15, + 229, 184, 12, 15, 229, 183, 12, 15, 229, 182, 12, 15, 229, 181, 12, 15, + 229, 180, 12, 15, 229, 179, 12, 15, 229, 178, 12, 15, 229, 177, 12, 15, + 229, 176, 12, 15, 229, 175, 12, 15, 229, 174, 12, 15, 229, 173, 12, 15, + 229, 172, 12, 15, 229, 171, 12, 15, 229, 170, 12, 15, 229, 169, 12, 15, + 229, 168, 12, 15, 229, 167, 12, 15, 229, 166, 12, 15, 229, 165, 12, 15, + 229, 164, 12, 15, 229, 163, 12, 15, 229, 162, 12, 15, 229, 161, 12, 15, + 229, 160, 12, 15, 229, 159, 12, 15, 229, 158, 12, 15, 229, 157, 12, 15, + 229, 156, 12, 15, 229, 155, 12, 15, 229, 154, 12, 15, 229, 153, 12, 15, + 229, 152, 12, 15, 229, 151, 12, 15, 229, 150, 12, 15, 229, 149, 12, 15, + 229, 148, 12, 15, 229, 147, 12, 15, 229, 146, 12, 15, 229, 145, 12, 15, + 229, 144, 12, 15, 229, 143, 12, 15, 229, 142, 12, 15, 229, 141, 12, 15, + 229, 140, 12, 15, 229, 139, 12, 15, 229, 138, 12, 15, 229, 137, 12, 15, + 229, 136, 12, 15, 229, 135, 12, 15, 229, 134, 12, 15, 229, 133, 12, 15, + 229, 132, 12, 15, 229, 131, 12, 15, 229, 130, 12, 15, 229, 129, 12, 15, + 229, 128, 12, 15, 229, 127, 12, 15, 229, 126, 12, 15, 229, 125, 12, 15, + 229, 124, 12, 15, 229, 123, 12, 15, 229, 122, 12, 15, 229, 121, 12, 15, + 229, 120, 12, 15, 229, 119, 12, 15, 229, 118, 12, 15, 229, 117, 12, 15, + 229, 116, 12, 15, 229, 115, 12, 15, 229, 114, 12, 15, 229, 113, 12, 15, + 229, 112, 12, 15, 229, 111, 12, 15, 229, 110, 12, 15, 229, 109, 12, 15, + 229, 108, 12, 15, 229, 107, 12, 15, 229, 106, 12, 15, 229, 105, 12, 15, + 229, 104, 12, 15, 229, 103, 12, 15, 229, 102, 12, 15, 229, 101, 12, 15, + 229, 100, 12, 15, 229, 99, 12, 15, 229, 98, 12, 15, 229, 97, 12, 15, 229, + 96, 12, 15, 229, 95, 12, 15, 229, 94, 12, 15, 229, 93, 12, 15, 229, 92, + 12, 15, 229, 91, 12, 15, 229, 90, 12, 15, 229, 89, 12, 15, 229, 88, 12, + 15, 229, 87, 12, 15, 229, 86, 12, 15, 229, 85, 12, 15, 229, 84, 12, 15, + 229, 83, 12, 15, 229, 82, 12, 15, 229, 81, 12, 15, 229, 80, 12, 15, 229, + 79, 12, 15, 229, 78, 12, 15, 229, 77, 12, 15, 229, 76, 12, 15, 229, 75, + 12, 15, 229, 74, 12, 15, 229, 73, 12, 15, 229, 72, 12, 15, 229, 71, 12, + 15, 229, 70, 12, 15, 229, 69, 12, 15, 229, 68, 12, 15, 229, 67, 12, 15, + 229, 66, 12, 15, 229, 65, 12, 15, 229, 64, 12, 15, 229, 63, 12, 15, 229, + 62, 12, 15, 229, 61, 12, 15, 229, 60, 12, 15, 229, 59, 12, 15, 229, 58, + 12, 15, 229, 57, 12, 15, 229, 56, 12, 15, 229, 55, 12, 15, 229, 54, 12, + 15, 229, 53, 12, 15, 229, 52, 12, 15, 229, 51, 12, 15, 229, 50, 12, 15, + 229, 49, 12, 15, 229, 48, 12, 15, 229, 47, 12, 15, 229, 46, 12, 15, 229, + 45, 12, 15, 229, 44, 12, 15, 229, 43, 12, 15, 229, 42, 12, 15, 229, 41, + 12, 15, 229, 40, 12, 15, 229, 39, 12, 15, 229, 38, 12, 15, 229, 37, 12, + 15, 229, 36, 12, 15, 229, 35, 12, 15, 229, 34, 12, 15, 229, 33, 12, 15, + 229, 32, 12, 15, 229, 31, 12, 15, 229, 30, 12, 15, 229, 29, 12, 15, 229, + 28, 12, 15, 229, 27, 12, 15, 229, 26, 12, 15, 229, 25, 12, 15, 229, 24, + 12, 15, 229, 23, 12, 15, 229, 22, 12, 15, 229, 21, 12, 15, 229, 20, 12, + 15, 229, 19, 12, 15, 229, 18, 12, 15, 229, 17, 12, 15, 229, 16, 12, 15, + 229, 15, 12, 15, 229, 14, 12, 15, 229, 13, 12, 15, 229, 12, 12, 15, 229, + 11, 12, 15, 229, 10, 12, 15, 229, 9, 12, 15, 229, 8, 12, 15, 229, 7, 12, + 15, 229, 6, 12, 15, 229, 5, 12, 15, 229, 4, 12, 15, 229, 3, 12, 15, 229, + 2, 12, 15, 229, 1, 12, 15, 229, 0, 12, 15, 228, 255, 12, 15, 228, 254, + 12, 15, 228, 253, 12, 15, 228, 252, 12, 15, 228, 251, 12, 15, 228, 250, + 12, 15, 228, 249, 12, 15, 228, 248, 12, 15, 228, 247, 12, 15, 228, 246, + 12, 15, 228, 245, 12, 15, 228, 244, 12, 15, 228, 243, 12, 15, 228, 242, + 12, 15, 228, 241, 12, 15, 228, 240, 12, 15, 228, 239, 12, 15, 228, 238, + 12, 15, 228, 237, 12, 15, 228, 236, 12, 15, 228, 235, 12, 15, 228, 234, + 12, 15, 228, 233, 12, 15, 228, 232, 12, 15, 228, 231, 12, 15, 228, 230, + 12, 15, 228, 229, 12, 15, 228, 228, 12, 15, 228, 227, 12, 15, 228, 226, + 12, 15, 228, 225, 12, 15, 228, 224, 12, 15, 228, 223, 12, 15, 228, 222, + 12, 15, 228, 221, 12, 15, 228, 220, 12, 15, 228, 219, 12, 15, 228, 218, + 12, 15, 228, 217, 12, 15, 228, 216, 12, 15, 228, 215, 12, 15, 228, 214, + 12, 15, 228, 213, 12, 15, 228, 212, 12, 15, 228, 211, 12, 15, 228, 210, + 12, 15, 228, 209, 12, 15, 228, 208, 12, 15, 228, 207, 12, 15, 228, 206, + 12, 15, 228, 205, 12, 15, 228, 204, 12, 15, 228, 203, 12, 15, 228, 202, + 12, 15, 228, 201, 12, 15, 228, 200, 12, 15, 228, 199, 12, 15, 228, 198, + 12, 15, 228, 197, 12, 15, 228, 196, 12, 15, 228, 195, 12, 15, 228, 194, + 12, 15, 228, 193, 12, 15, 228, 192, 12, 15, 228, 191, 12, 15, 228, 190, + 12, 15, 228, 189, 12, 15, 228, 188, 12, 15, 228, 187, 12, 15, 228, 186, + 12, 15, 228, 185, 12, 15, 228, 184, 12, 15, 228, 183, 12, 15, 228, 182, + 12, 15, 228, 181, 12, 15, 228, 180, 12, 15, 228, 179, 12, 15, 228, 178, + 12, 15, 228, 177, 12, 15, 228, 176, 12, 15, 228, 175, 12, 15, 228, 174, + 12, 15, 228, 173, 12, 15, 228, 172, 12, 15, 228, 171, 12, 15, 228, 170, + 12, 15, 228, 169, 12, 15, 228, 168, 12, 15, 228, 167, 12, 15, 228, 166, + 12, 15, 228, 165, 12, 15, 228, 164, 12, 15, 228, 163, 12, 15, 228, 162, + 12, 15, 228, 161, 222, 234, 203, 143, 184, 205, 148, 184, 236, 90, 78, + 184, 211, 62, 78, 184, 31, 55, 184, 239, 10, 55, 184, 213, 45, 55, 184, + 251, 111, 184, 251, 30, 184, 50, 213, 140, 184, 53, 213, 140, 184, 250, + 179, 184, 98, 55, 184, 244, 159, 184, 231, 6, 184, 234, 217, 204, 226, + 184, 205, 177, 184, 17, 195, 79, 184, 17, 100, 184, 17, 102, 184, 17, + 134, 184, 17, 136, 184, 17, 146, 184, 17, 167, 184, 17, 178, 184, 17, + 171, 184, 17, 182, 184, 244, 168, 184, 207, 105, 184, 222, 140, 55, 184, + 236, 172, 55, 184, 233, 94, 55, 184, 211, 79, 78, 184, 244, 157, 250, + 168, 184, 8, 6, 1, 63, 184, 8, 6, 1, 250, 112, 184, 8, 6, 1, 247, 207, + 184, 8, 6, 1, 240, 231, 184, 8, 6, 1, 69, 184, 8, 6, 1, 236, 49, 184, 8, + 6, 1, 234, 190, 184, 8, 6, 1, 233, 15, 184, 8, 6, 1, 68, 184, 8, 6, 1, + 225, 217, 184, 8, 6, 1, 225, 80, 184, 8, 6, 1, 159, 184, 8, 6, 1, 221, + 136, 184, 8, 6, 1, 218, 55, 184, 8, 6, 1, 72, 184, 8, 6, 1, 214, 3, 184, + 8, 6, 1, 211, 167, 184, 8, 6, 1, 144, 184, 8, 6, 1, 209, 80, 184, 8, 6, + 1, 203, 216, 184, 8, 6, 1, 66, 184, 8, 6, 1, 199, 230, 184, 8, 6, 1, 197, + 199, 184, 8, 6, 1, 196, 222, 184, 8, 6, 1, 196, 148, 184, 8, 6, 1, 195, + 158, 184, 50, 47, 179, 184, 210, 90, 205, 177, 184, 53, 47, 179, 184, + 244, 241, 252, 22, 184, 126, 222, 75, 184, 233, 101, 252, 22, 184, 8, 4, + 1, 63, 184, 8, 4, 1, 250, 112, 184, 8, 4, 1, 247, 207, 184, 8, 4, 1, 240, + 231, 184, 8, 4, 1, 69, 184, 8, 4, 1, 236, 49, 184, 8, 4, 1, 234, 190, + 184, 8, 4, 1, 233, 15, 184, 8, 4, 1, 68, 184, 8, 4, 1, 225, 217, 184, 8, + 4, 1, 225, 80, 184, 8, 4, 1, 159, 184, 8, 4, 1, 221, 136, 184, 8, 4, 1, + 218, 55, 184, 8, 4, 1, 72, 184, 8, 4, 1, 214, 3, 184, 8, 4, 1, 211, 167, + 184, 8, 4, 1, 144, 184, 8, 4, 1, 209, 80, 184, 8, 4, 1, 203, 216, 184, 8, + 4, 1, 66, 184, 8, 4, 1, 199, 230, 184, 8, 4, 1, 197, 199, 184, 8, 4, 1, + 196, 222, 184, 8, 4, 1, 196, 148, 184, 8, 4, 1, 195, 158, 184, 50, 241, + 18, 179, 184, 83, 222, 75, 184, 53, 241, 18, 179, 184, 202, 84, 247, 141, + 203, 143, 62, 208, 35, 62, 208, 24, 62, 208, 13, 62, 208, 1, 62, 207, + 246, 62, 207, 235, 62, 207, 224, 62, 207, 213, 62, 207, 202, 62, 207, + 194, 62, 207, 193, 62, 207, 192, 62, 207, 191, 62, 207, 189, 62, 207, + 188, 62, 207, 187, 62, 207, 186, 62, 207, 185, 62, 207, 184, 62, 207, + 183, 62, 207, 182, 62, 207, 181, 62, 207, 180, 62, 207, 178, 62, 207, + 177, 62, 207, 176, 62, 207, 175, 62, 207, 174, 62, 207, 173, 62, 207, + 172, 62, 207, 171, 62, 207, 170, 62, 207, 169, 62, 207, 167, 62, 207, + 166, 62, 207, 165, 62, 207, 164, 62, 207, 163, 62, 207, 162, 62, 207, + 161, 62, 207, 160, 62, 207, 159, 62, 207, 158, 62, 207, 156, 62, 207, + 155, 62, 207, 154, 62, 207, 153, 62, 207, 152, 62, 207, 151, 62, 207, + 150, 62, 207, 149, 62, 207, 148, 62, 207, 147, 62, 207, 145, 62, 207, + 144, 62, 207, 143, 62, 207, 142, 62, 207, 141, 62, 207, 140, 62, 207, + 139, 62, 207, 138, 62, 207, 137, 62, 207, 136, 62, 207, 134, 62, 207, + 133, 62, 207, 132, 62, 207, 131, 62, 207, 130, 62, 207, 129, 62, 207, + 128, 62, 207, 127, 62, 207, 126, 62, 207, 125, 62, 207, 123, 62, 207, + 122, 62, 207, 121, 62, 207, 120, 62, 207, 119, 62, 207, 118, 62, 207, + 117, 62, 207, 116, 62, 207, 115, 62, 207, 114, 62, 208, 111, 62, 208, + 110, 62, 208, 109, 62, 208, 108, 62, 208, 107, 62, 208, 106, 62, 208, + 105, 62, 208, 104, 62, 208, 103, 62, 208, 102, 62, 208, 100, 62, 208, 99, + 62, 208, 98, 62, 208, 97, 62, 208, 96, 62, 208, 95, 62, 208, 94, 62, 208, + 93, 62, 208, 92, 62, 208, 91, 62, 208, 89, 62, 208, 88, 62, 208, 87, 62, + 208, 86, 62, 208, 85, 62, 208, 84, 62, 208, 83, 62, 208, 82, 62, 208, 81, + 62, 208, 80, 62, 208, 78, 62, 208, 77, 62, 208, 76, 62, 208, 75, 62, 208, + 74, 62, 208, 73, 62, 208, 72, 62, 208, 71, 62, 208, 70, 62, 208, 69, 62, + 208, 67, 62, 208, 66, 62, 208, 65, 62, 208, 64, 62, 208, 63, 62, 208, 62, + 62, 208, 61, 62, 208, 60, 62, 208, 59, 62, 208, 58, 62, 208, 56, 62, 208, + 55, 62, 208, 54, 62, 208, 53, 62, 208, 52, 62, 208, 51, 62, 208, 50, 62, + 208, 49, 62, 208, 48, 62, 208, 47, 62, 208, 45, 62, 208, 44, 62, 208, 43, + 62, 208, 42, 62, 208, 41, 62, 208, 40, 62, 208, 39, 62, 208, 38, 62, 208, + 37, 62, 208, 36, 62, 208, 34, 62, 208, 33, 62, 208, 32, 62, 208, 31, 62, + 208, 30, 62, 208, 29, 62, 208, 28, 62, 208, 27, 62, 208, 26, 62, 208, 25, + 62, 208, 23, 62, 208, 22, 62, 208, 21, 62, 208, 20, 62, 208, 19, 62, 208, + 18, 62, 208, 17, 62, 208, 16, 62, 208, 15, 62, 208, 14, 62, 208, 12, 62, + 208, 11, 62, 208, 10, 62, 208, 9, 62, 208, 8, 62, 208, 7, 62, 208, 6, 62, + 208, 5, 62, 208, 4, 62, 208, 3, 62, 208, 0, 62, 207, 255, 62, 207, 254, + 62, 207, 253, 62, 207, 252, 62, 207, 251, 62, 207, 250, 62, 207, 249, 62, + 207, 248, 62, 207, 247, 62, 207, 245, 62, 207, 244, 62, 207, 243, 62, + 207, 242, 62, 207, 241, 62, 207, 240, 62, 207, 239, 62, 207, 238, 62, + 207, 237, 62, 207, 236, 62, 207, 234, 62, 207, 233, 62, 207, 232, 62, + 207, 231, 62, 207, 230, 62, 207, 229, 62, 207, 228, 62, 207, 227, 62, + 207, 226, 62, 207, 225, 62, 207, 223, 62, 207, 222, 62, 207, 221, 62, + 207, 220, 62, 207, 219, 62, 207, 218, 62, 207, 217, 62, 207, 216, 62, + 207, 215, 62, 207, 214, 62, 207, 212, 62, 207, 211, 62, 207, 210, 62, + 207, 209, 62, 207, 208, 62, 207, 207, 62, 207, 206, 62, 207, 205, 62, + 207, 204, 62, 207, 203, 62, 207, 201, 62, 207, 200, 62, 207, 199, 62, + 207, 198, 62, 207, 197, 62, 207, 196, 62, 207, 195, 215, 146, 215, 148, + 205, 3, 77, 232, 134, 205, 181, 205, 3, 77, 202, 237, 204, 174, 236, 222, + 77, 202, 237, 236, 118, 236, 222, 77, 201, 202, 236, 184, 236, 208, 236, + 209, 252, 14, 252, 15, 251, 161, 248, 232, 249, 132, 248, 27, 190, 203, + 149, 231, 155, 203, 149, 231, 80, 203, 154, 222, 76, 235, 180, 217, 83, + 222, 75, 236, 222, 77, 222, 75, 222, 124, 216, 112, 236, 187, 222, 76, + 203, 149, 83, 203, 149, 197, 222, 235, 24, 235, 180, 235, 157, 247, 102, + 210, 93, 241, 80, 206, 219, 214, 34, 221, 253, 100, 205, 200, 206, 219, + 226, 86, 221, 253, 195, 79, 206, 112, 240, 60, 222, 66, 236, 143, 239, + 39, 239, 183, 241, 121, 100, 240, 49, 239, 183, 241, 121, 102, 240, 48, + 239, 183, 241, 121, 134, 240, 47, 239, 183, 241, 121, 136, 240, 46, 217, + 104, 252, 14, 217, 227, 203, 242, 226, 149, 203, 246, 236, 222, 77, 201, + 203, 248, 126, 236, 125, 247, 140, 247, 142, 236, 222, 77, 219, 189, 236, + 185, 204, 139, 204, 157, 236, 143, 236, 144, 226, 61, 207, 91, 136, 235, + 138, 207, 90, 234, 227, 226, 61, 207, 91, 134, 233, 84, 207, 90, 233, 81, + 226, 61, 207, 91, 102, 210, 169, 207, 90, 209, 146, 226, 61, 207, 91, + 100, 200, 50, 207, 90, 200, 4, 205, 151, 239, 222, 239, 224, 213, 231, + 246, 255, 213, 233, 130, 214, 171, 212, 24, 231, 158, 248, 52, 213, 35, + 232, 95, 248, 66, 216, 51, 248, 52, 232, 95, 217, 188, 226, 72, 226, 74, + 217, 76, 222, 75, 217, 102, 205, 3, 77, 208, 116, 250, 245, 205, 80, 236, + 222, 77, 208, 116, 250, 245, 236, 146, 190, 203, 150, 207, 76, 231, 155, + 203, 150, 207, 76, 231, 77, 190, 203, 150, 3, 225, 92, 231, 155, 203, + 150, 3, 225, 92, 231, 78, 222, 76, 203, 150, 207, 76, 83, 203, 150, 207, + 76, 197, 221, 213, 132, 222, 76, 235, 11, 213, 132, 222, 76, 237, 235, + 212, 137, 213, 132, 222, 76, 249, 131, 213, 132, 222, 76, 200, 36, 212, + 131, 210, 90, 222, 76, 235, 180, 210, 90, 226, 72, 210, 72, 206, 62, 206, + 219, 102, 206, 59, 205, 82, 206, 62, 206, 219, 134, 206, 58, 205, 81, + 239, 183, 241, 121, 204, 198, 240, 44, 212, 9, 200, 3, 100, 212, 9, 200, + 1, 211, 226, 212, 9, 200, 3, 102, 212, 9, 200, 0, 211, 225, 207, 77, 201, + 201, 205, 0, 204, 181, 247, 141, 246, 255, 247, 76, 219, 147, 197, 152, + 218, 73, 205, 3, 77, 233, 69, 250, 245, 205, 3, 77, 211, 244, 250, 245, + 205, 150, 236, 222, 77, 233, 69, 250, 245, 236, 222, 77, 211, 244, 250, + 245, 236, 182, 205, 3, 77, 204, 198, 205, 166, 206, 62, 233, 106, 190, + 226, 20, 207, 55, 206, 62, 190, 226, 20, 208, 162, 241, 121, 207, 87, + 226, 20, 241, 42, 204, 199, 203, 8, 205, 23, 214, 84, 203, 231, 244, 158, + 214, 51, 212, 10, 219, 146, 212, 120, 251, 26, 212, 3, 244, 158, 251, 43, + 217, 176, 206, 121, 8, 6, 1, 233, 230, 8, 4, 1, 233, 230, 247, 19, 251, + 140, 203, 236, 204, 145, 244, 169, 206, 4, 222, 184, 225, 11, 1, 222, 26, + 222, 232, 1, 235, 52, 235, 43, 222, 232, 1, 235, 52, 235, 192, 222, 232, + 1, 209, 232, 222, 232, 1, 222, 7, 82, 117, 248, 138, 206, 192, 233, 193, + 219, 96, 210, 80, 29, 116, 196, 43, 29, 116, 196, 39, 29, 116, 205, 58, + 29, 116, 196, 44, 234, 204, 234, 203, 234, 202, 218, 75, 194, 236, 194, + 237, 194, 239, 221, 195, 209, 240, 221, 197, 209, 242, 213, 95, 221, 194, + 209, 239, 216, 82, 218, 255, 197, 36, 221, 196, 209, 241, 234, 226, 213, + 94, 197, 95, 236, 246, 234, 214, 219, 70, 214, 120, 200, 5, 105, 219, 70, + 240, 66, 105, 107, 201, 179, 61, 3, 52, 83, 106, 91, 201, 179, 61, 3, 52, + 83, 106, 11, 5, 225, 232, 78, 198, 222, 198, 111, 198, 43, 198, 32, 198, + 21, 198, 10, 197, 255, 197, 244, 197, 233, 198, 221, 198, 210, 198, 199, + 198, 188, 198, 177, 198, 166, 198, 155, 212, 25, 235, 24, 36, 83, 53, 59, + 222, 147, 179, 247, 212, 214, 68, 78, 248, 106, 194, 238, 10, 2, 215, + 156, 203, 12, 10, 2, 215, 156, 127, 215, 156, 247, 245, 127, 247, 244, + 219, 195, 6, 1, 233, 15, 219, 195, 6, 1, 217, 73, 219, 195, 4, 1, 233, + 15, 219, 195, 4, 1, 217, 73, 56, 1, 237, 135, 67, 34, 16, 234, 225, 206, + 0, 245, 34, 199, 128, 198, 144, 198, 133, 198, 122, 198, 110, 198, 99, + 198, 88, 198, 77, 198, 66, 198, 55, 198, 47, 198, 46, 198, 45, 198, 44, + 198, 42, 198, 41, 198, 40, 198, 39, 198, 38, 198, 37, 198, 36, 198, 35, + 198, 34, 198, 33, 198, 31, 198, 30, 198, 29, 198, 28, 198, 27, 198, 26, + 198, 25, 198, 24, 198, 23, 198, 22, 198, 20, 198, 19, 198, 18, 198, 17, + 198, 16, 198, 15, 198, 14, 198, 13, 198, 12, 198, 11, 198, 9, 198, 8, + 198, 7, 198, 6, 198, 5, 198, 4, 198, 3, 198, 2, 198, 1, 198, 0, 197, 254, + 197, 253, 197, 252, 197, 251, 197, 250, 197, 249, 197, 248, 197, 247, + 197, 246, 197, 245, 197, 243, 197, 242, 197, 241, 197, 240, 197, 239, + 197, 238, 197, 237, 197, 236, 197, 235, 197, 234, 197, 232, 197, 231, + 197, 230, 197, 229, 197, 228, 197, 227, 197, 226, 197, 225, 197, 224, + 197, 223, 198, 220, 198, 219, 198, 218, 198, 217, 198, 216, 198, 215, + 198, 214, 198, 213, 198, 212, 198, 211, 198, 209, 198, 208, 198, 207, + 198, 206, 198, 205, 198, 204, 198, 203, 198, 202, 198, 201, 198, 200, + 198, 198, 198, 197, 198, 196, 198, 195, 198, 194, 198, 193, 198, 192, + 198, 191, 198, 190, 198, 189, 198, 187, 198, 186, 198, 185, 198, 184, + 198, 183, 198, 182, 198, 181, 198, 180, 198, 179, 198, 178, 198, 176, + 198, 175, 198, 174, 198, 173, 198, 172, 198, 171, 198, 170, 198, 169, + 198, 168, 198, 167, 198, 165, 198, 164, 198, 163, 198, 162, 198, 161, + 198, 160, 198, 159, 198, 158, 198, 157, 198, 156, 198, 154, 198, 153, + 198, 152, 198, 151, 198, 150, 198, 149, 198, 148, 198, 147, 198, 146, + 198, 145, 198, 143, 198, 142, 198, 141, 198, 140, 198, 139, 198, 138, + 198, 137, 198, 136, 198, 135, 198, 134, 198, 132, 198, 131, 198, 130, + 198, 129, 198, 128, 198, 127, 198, 126, 198, 125, 198, 124, 198, 123, + 198, 121, 198, 120, 198, 119, 198, 118, 198, 117, 198, 116, 198, 115, + 198, 114, 198, 113, 198, 112, 198, 109, 198, 108, 198, 107, 198, 106, + 198, 105, 198, 104, 198, 103, 198, 102, 198, 101, 198, 100, 198, 98, 198, + 97, 198, 96, 198, 95, 198, 94, 198, 93, 198, 92, 198, 91, 198, 90, 198, + 89, 198, 87, 198, 86, 198, 85, 198, 84, 198, 83, 198, 82, 198, 81, 198, + 80, 198, 79, 198, 78, 198, 76, 198, 75, 198, 74, 198, 73, 198, 72, 198, + 71, 198, 70, 198, 69, 198, 68, 198, 67, 198, 65, 198, 64, 198, 63, 198, + 62, 198, 61, 198, 60, 198, 59, 198, 58, 198, 57, 198, 56, 198, 54, 198, + 53, 198, 52, 198, 51, 198, 50, 198, 49, 198, 48, 224, 150, 31, 55, 224, + 150, 250, 179, 224, 150, 17, 195, 79, 224, 150, 17, 100, 224, 150, 17, + 102, 224, 150, 17, 134, 224, 150, 17, 136, 224, 150, 17, 146, 224, 150, + 17, 167, 224, 150, 17, 178, 224, 150, 17, 171, 224, 150, 17, 182, 8, 6, + 1, 39, 3, 220, 115, 26, 233, 100, 8, 4, 1, 39, 3, 220, 115, 26, 233, 100, + 8, 6, 1, 237, 136, 3, 83, 222, 76, 60, 8, 4, 1, 237, 136, 3, 83, 222, 76, + 60, 8, 6, 1, 237, 136, 3, 83, 222, 76, 248, 227, 26, 233, 100, 8, 4, 1, + 237, 136, 3, 83, 222, 76, 248, 227, 26, 233, 100, 8, 6, 1, 237, 136, 3, + 83, 222, 76, 248, 227, 26, 186, 8, 4, 1, 237, 136, 3, 83, 222, 76, 248, + 227, 26, 186, 8, 6, 1, 237, 136, 3, 244, 241, 26, 220, 114, 8, 4, 1, 237, + 136, 3, 244, 241, 26, 220, 114, 8, 6, 1, 237, 136, 3, 244, 241, 26, 247, + 106, 8, 4, 1, 237, 136, 3, 244, 241, 26, 247, 106, 8, 6, 1, 230, 249, 3, + 220, 115, 26, 233, 100, 8, 4, 1, 230, 249, 3, 220, 115, 26, 233, 100, 8, + 4, 1, 230, 249, 3, 76, 90, 26, 186, 8, 4, 1, 217, 74, 3, 202, 85, 57, 8, + 6, 1, 177, 3, 83, 222, 76, 60, 8, 4, 1, 177, 3, 83, 222, 76, 60, 8, 6, 1, + 177, 3, 83, 222, 76, 248, 227, 26, 233, 100, 8, 4, 1, 177, 3, 83, 222, + 76, 248, 227, 26, 233, 100, 8, 6, 1, 177, 3, 83, 222, 76, 248, 227, 26, + 186, 8, 4, 1, 177, 3, 83, 222, 76, 248, 227, 26, 186, 8, 6, 1, 209, 81, + 3, 83, 222, 76, 60, 8, 4, 1, 209, 81, 3, 83, 222, 76, 60, 8, 6, 1, 118, + 3, 220, 115, 26, 233, 100, 8, 4, 1, 118, 3, 220, 115, 26, 233, 100, 8, 6, + 1, 39, 3, 214, 152, 26, 186, 8, 4, 1, 39, 3, 214, 152, 26, 186, 8, 6, 1, + 39, 3, 214, 152, 26, 202, 84, 8, 4, 1, 39, 3, 214, 152, 26, 202, 84, 8, + 6, 1, 237, 136, 3, 214, 152, 26, 186, 8, 4, 1, 237, 136, 3, 214, 152, 26, + 186, 8, 6, 1, 237, 136, 3, 214, 152, 26, 202, 84, 8, 4, 1, 237, 136, 3, + 214, 152, 26, 202, 84, 8, 6, 1, 237, 136, 3, 76, 90, 26, 186, 8, 4, 1, + 237, 136, 3, 76, 90, 26, 186, 8, 6, 1, 237, 136, 3, 76, 90, 26, 202, 84, + 8, 4, 1, 237, 136, 3, 76, 90, 26, 202, 84, 8, 4, 1, 230, 249, 3, 76, 90, + 26, 233, 100, 8, 4, 1, 230, 249, 3, 76, 90, 26, 202, 84, 8, 6, 1, 230, + 249, 3, 214, 152, 26, 186, 8, 4, 1, 230, 249, 3, 214, 152, 26, 76, 90, + 26, 186, 8, 6, 1, 230, 249, 3, 214, 152, 26, 202, 84, 8, 4, 1, 230, 249, + 3, 214, 152, 26, 76, 90, 26, 202, 84, 8, 6, 1, 225, 218, 3, 202, 84, 8, + 4, 1, 225, 218, 3, 76, 90, 26, 202, 84, 8, 6, 1, 223, 100, 3, 202, 84, 8, + 4, 1, 223, 100, 3, 202, 84, 8, 6, 1, 221, 137, 3, 202, 84, 8, 4, 1, 221, + 137, 3, 202, 84, 8, 6, 1, 211, 32, 3, 202, 84, 8, 4, 1, 211, 32, 3, 202, + 84, 8, 6, 1, 118, 3, 214, 152, 26, 186, 8, 4, 1, 118, 3, 214, 152, 26, + 186, 8, 6, 1, 118, 3, 214, 152, 26, 202, 84, 8, 4, 1, 118, 3, 214, 152, + 26, 202, 84, 8, 6, 1, 118, 3, 220, 115, 26, 186, 8, 4, 1, 118, 3, 220, + 115, 26, 186, 8, 6, 1, 118, 3, 220, 115, 26, 202, 84, 8, 4, 1, 118, 3, + 220, 115, 26, 202, 84, 8, 4, 1, 251, 246, 3, 233, 100, 8, 4, 1, 192, 177, + 3, 233, 100, 8, 4, 1, 192, 177, 3, 186, 8, 4, 1, 163, 199, 231, 3, 233, + 100, 8, 4, 1, 163, 199, 231, 3, 186, 8, 4, 1, 208, 164, 3, 233, 100, 8, + 4, 1, 208, 164, 3, 186, 8, 4, 1, 231, 164, 208, 164, 3, 233, 100, 8, 4, + 1, 231, 164, 208, 164, 3, 186, 9, 207, 87, 93, 3, 232, 214, 90, 3, 251, + 164, 9, 207, 87, 93, 3, 232, 214, 90, 3, 197, 117, 9, 207, 87, 93, 3, + 232, 214, 90, 3, 151, 220, 69, 9, 207, 87, 93, 3, 232, 214, 90, 3, 214, + 164, 9, 207, 87, 93, 3, 232, 214, 90, 3, 66, 9, 207, 87, 93, 3, 232, 214, + 90, 3, 195, 217, 9, 207, 87, 93, 3, 232, 214, 90, 3, 69, 9, 207, 87, 93, + 3, 232, 214, 90, 3, 251, 245, 9, 207, 87, 216, 32, 3, 224, 191, 248, 219, + 1, 224, 121, 42, 108, 225, 80, 42, 108, 217, 73, 42, 108, 247, 207, 42, + 108, 215, 111, 42, 108, 201, 81, 42, 108, 216, 87, 42, 108, 203, 216, 42, + 108, 218, 55, 42, 108, 214, 3, 42, 108, 221, 136, 42, 108, 196, 148, 42, + 108, 144, 42, 108, 159, 42, 108, 199, 230, 42, 108, 222, 27, 42, 108, + 222, 38, 42, 108, 209, 182, 42, 108, 216, 69, 42, 108, 225, 217, 42, 108, + 207, 52, 42, 108, 205, 83, 42, 108, 209, 80, 42, 108, 233, 15, 42, 108, + 223, 202, 42, 5, 225, 55, 42, 5, 224, 101, 42, 5, 224, 80, 42, 5, 223, + 187, 42, 5, 223, 144, 42, 5, 224, 209, 42, 5, 224, 200, 42, 5, 225, 31, + 42, 5, 224, 11, 42, 5, 223, 242, 42, 5, 224, 228, 42, 5, 217, 70, 42, 5, + 217, 19, 42, 5, 217, 15, 42, 5, 216, 240, 42, 5, 216, 231, 42, 5, 217, + 58, 42, 5, 217, 56, 42, 5, 217, 67, 42, 5, 216, 252, 42, 5, 216, 247, 42, + 5, 217, 60, 42, 5, 247, 173, 42, 5, 245, 11, 42, 5, 245, 1, 42, 5, 241, + 41, 42, 5, 241, 0, 42, 5, 247, 57, 42, 5, 247, 49, 42, 5, 247, 162, 42, + 5, 244, 182, 42, 5, 241, 117, 42, 5, 247, 90, 42, 5, 215, 108, 42, 5, + 215, 89, 42, 5, 215, 83, 42, 5, 215, 66, 42, 5, 215, 58, 42, 5, 215, 98, + 42, 5, 215, 97, 42, 5, 215, 105, 42, 5, 215, 73, 42, 5, 215, 70, 42, 5, + 215, 101, 42, 5, 201, 77, 42, 5, 201, 57, 42, 5, 201, 56, 42, 5, 201, 45, + 42, 5, 201, 42, 42, 5, 201, 73, 42, 5, 201, 72, 42, 5, 201, 76, 42, 5, + 201, 55, 42, 5, 201, 54, 42, 5, 201, 75, 42, 5, 216, 85, 42, 5, 216, 71, + 42, 5, 216, 70, 42, 5, 216, 54, 42, 5, 216, 53, 42, 5, 216, 81, 42, 5, + 216, 80, 42, 5, 216, 84, 42, 5, 216, 56, 42, 5, 216, 55, 42, 5, 216, 83, + 42, 5, 203, 162, 42, 5, 202, 122, 42, 5, 202, 99, 42, 5, 201, 40, 42, 5, + 200, 251, 42, 5, 203, 68, 42, 5, 203, 48, 42, 5, 203, 137, 42, 5, 149, + 42, 5, 201, 247, 42, 5, 203, 89, 42, 5, 217, 244, 42, 5, 216, 223, 42, 5, + 216, 190, 42, 5, 215, 186, 42, 5, 215, 123, 42, 5, 217, 118, 42, 5, 217, + 107, 42, 5, 217, 230, 42, 5, 216, 50, 42, 5, 216, 33, 42, 5, 217, 202, + 42, 5, 213, 243, 42, 5, 212, 220, 42, 5, 212, 182, 42, 5, 211, 227, 42, + 5, 211, 191, 42, 5, 213, 92, 42, 5, 213, 79, 42, 5, 213, 221, 42, 5, 212, + 117, 42, 5, 212, 91, 42, 5, 213, 108, 42, 5, 220, 119, 42, 5, 219, 78, + 42, 5, 219, 40, 42, 5, 218, 145, 42, 5, 218, 85, 42, 5, 219, 207, 42, 5, + 219, 188, 42, 5, 220, 81, 42, 5, 218, 251, 42, 5, 218, 195, 42, 5, 219, + 255, 42, 5, 196, 129, 42, 5, 196, 24, 42, 5, 196, 14, 42, 5, 195, 217, + 42, 5, 195, 180, 42, 5, 196, 69, 42, 5, 196, 66, 42, 5, 196, 108, 42, 5, + 196, 3, 42, 5, 195, 237, 42, 5, 196, 80, 42, 5, 210, 244, 42, 5, 210, 72, + 42, 5, 210, 9, 42, 5, 209, 140, 42, 5, 209, 101, 42, 5, 210, 183, 42, 5, + 210, 155, 42, 5, 210, 224, 42, 5, 209, 232, 42, 5, 209, 206, 42, 5, 210, + 193, 42, 5, 223, 82, 42, 5, 222, 109, 42, 5, 222, 91, 42, 5, 221, 191, + 42, 5, 221, 162, 42, 5, 222, 197, 42, 5, 222, 188, 42, 5, 223, 54, 42, 5, + 222, 7, 42, 5, 221, 229, 42, 5, 222, 215, 42, 5, 199, 151, 42, 5, 199, + 34, 42, 5, 199, 18, 42, 5, 197, 220, 42, 5, 197, 212, 42, 5, 199, 118, + 42, 5, 199, 113, 42, 5, 199, 147, 42, 5, 198, 248, 42, 5, 198, 233, 42, + 5, 199, 124, 42, 5, 222, 25, 42, 5, 222, 20, 42, 5, 222, 19, 42, 5, 222, + 16, 42, 5, 222, 15, 42, 5, 222, 22, 42, 5, 222, 21, 42, 5, 222, 24, 42, + 5, 222, 18, 42, 5, 222, 17, 42, 5, 222, 23, 42, 5, 222, 36, 42, 5, 222, + 29, 42, 5, 222, 28, 42, 5, 222, 12, 42, 5, 222, 11, 42, 5, 222, 32, 42, + 5, 222, 31, 42, 5, 222, 35, 42, 5, 222, 14, 42, 5, 222, 13, 42, 5, 222, + 33, 42, 5, 209, 180, 42, 5, 209, 169, 42, 5, 209, 168, 42, 5, 209, 161, + 42, 5, 209, 154, 42, 5, 209, 176, 42, 5, 209, 175, 42, 5, 209, 179, 42, + 5, 209, 167, 42, 5, 209, 166, 42, 5, 209, 178, 42, 5, 216, 67, 42, 5, + 216, 62, 42, 5, 216, 61, 42, 5, 216, 58, 42, 5, 216, 57, 42, 5, 216, 64, + 42, 5, 216, 63, 42, 5, 216, 66, 42, 5, 216, 60, 42, 5, 216, 59, 42, 5, + 216, 65, 42, 5, 225, 213, 42, 5, 225, 172, 42, 5, 225, 164, 42, 5, 225, + 110, 42, 5, 225, 90, 42, 5, 225, 193, 42, 5, 225, 191, 42, 5, 225, 207, + 42, 5, 225, 129, 42, 5, 225, 119, 42, 5, 225, 200, 42, 5, 207, 45, 42, 5, + 206, 223, 42, 5, 206, 218, 42, 5, 206, 151, 42, 5, 206, 133, 42, 5, 206, + 255, 42, 5, 206, 253, 42, 5, 207, 34, 42, 5, 206, 198, 42, 5, 206, 190, + 42, 5, 207, 8, 42, 5, 205, 79, 42, 5, 205, 47, 42, 5, 205, 43, 42, 5, + 205, 34, 42, 5, 205, 31, 42, 5, 205, 53, 42, 5, 205, 52, 42, 5, 205, 78, + 42, 5, 205, 39, 42, 5, 205, 38, 42, 5, 205, 55, 42, 5, 209, 13, 42, 5, + 206, 112, 42, 5, 206, 84, 42, 5, 204, 172, 42, 5, 204, 74, 42, 5, 208, + 147, 42, 5, 208, 129, 42, 5, 208, 253, 42, 5, 205, 200, 42, 5, 205, 171, + 42, 5, 208, 191, 42, 5, 232, 246, 42, 5, 232, 71, 42, 5, 232, 43, 42, 5, + 231, 75, 42, 5, 231, 46, 42, 5, 232, 147, 42, 5, 232, 118, 42, 5, 232, + 235, 42, 5, 231, 193, 42, 5, 231, 166, 42, 5, 232, 158, 42, 5, 223, 201, + 42, 5, 223, 200, 42, 5, 223, 195, 42, 5, 223, 194, 42, 5, 223, 191, 42, + 5, 223, 190, 42, 5, 223, 197, 42, 5, 223, 196, 42, 5, 223, 199, 42, 5, + 223, 193, 42, 5, 223, 192, 42, 5, 223, 198, 42, 5, 206, 158, 153, 108, 2, + 196, 94, 153, 108, 2, 210, 212, 153, 108, 2, 210, 121, 94, 1, 200, 170, + 89, 108, 2, 244, 175, 155, 89, 108, 2, 244, 175, 224, 146, 89, 108, 2, + 244, 175, 224, 11, 89, 108, 2, 244, 175, 224, 117, 89, 108, 2, 244, 175, + 216, 252, 89, 108, 2, 244, 175, 247, 174, 89, 108, 2, 244, 175, 247, 16, + 89, 108, 2, 244, 175, 244, 182, 89, 108, 2, 244, 175, 245, 49, 89, 108, + 2, 244, 175, 215, 73, 89, 108, 2, 244, 175, 240, 136, 89, 108, 2, 244, + 175, 201, 66, 89, 108, 2, 244, 175, 239, 28, 89, 108, 2, 244, 175, 201, + 61, 89, 108, 2, 244, 175, 176, 89, 108, 2, 244, 175, 189, 89, 108, 2, + 244, 175, 202, 233, 89, 108, 2, 244, 175, 149, 89, 108, 2, 244, 175, 202, + 169, 89, 108, 2, 244, 175, 216, 50, 89, 108, 2, 244, 175, 249, 145, 89, + 108, 2, 244, 175, 213, 6, 89, 108, 2, 244, 175, 212, 117, 89, 108, 2, + 244, 175, 212, 234, 89, 108, 2, 244, 175, 218, 251, 89, 108, 2, 244, 175, + 196, 3, 89, 108, 2, 244, 175, 209, 232, 89, 108, 2, 244, 175, 222, 7, 89, + 108, 2, 244, 175, 198, 248, 89, 108, 2, 244, 175, 207, 50, 89, 108, 2, + 244, 175, 205, 80, 89, 108, 2, 244, 175, 183, 89, 108, 2, 244, 175, 142, + 89, 108, 2, 244, 175, 172, 89, 18, 2, 244, 175, 211, 159, 89, 226, 73, + 18, 2, 244, 175, 211, 97, 89, 226, 73, 18, 2, 244, 175, 209, 89, 89, 226, + 73, 18, 2, 244, 175, 209, 82, 89, 226, 73, 18, 2, 244, 175, 211, 139, 89, + 18, 2, 214, 127, 89, 18, 2, 252, 129, 188, 1, 248, 177, 217, 71, 188, 1, + 248, 177, 217, 19, 188, 1, 248, 177, 216, 240, 188, 1, 248, 177, 217, 58, + 188, 1, 248, 177, 216, 252, 71, 1, 248, 177, 217, 71, 71, 1, 248, 177, + 217, 19, 71, 1, 248, 177, 216, 240, 71, 1, 248, 177, 217, 58, 71, 1, 248, + 177, 216, 252, 71, 1, 251, 192, 247, 57, 71, 1, 251, 192, 201, 40, 71, 1, + 251, 192, 149, 71, 1, 251, 192, 214, 3, 73, 1, 236, 74, 236, 73, 241, + 125, 152, 154, 73, 1, 236, 73, 236, 74, 241, 125, 152, 154, +}; + +static const unsigned short 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, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 105, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 130, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 104, 149, 150, 151, 152, 153, 154, 104, 155, 156, 157, 104, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 104, 169, 104, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 104, 179, 180, 104, 181, 182, + 183, 184, 104, 185, 186, 104, 187, 188, 189, 104, 104, 190, 191, 192, + 193, 104, 194, 104, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 216, 217, 218, 219, 220, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 221, 222, 223, 224, 225, + 226, 227, 228, 104, 104, 104, 104, 229, 230, 231, 232, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 233, 234, 235, 236, 237, 238, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 239, + 240, 241, 242, 243, 244, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 245, 246, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 247, 248, 249, 250, 251, 252, 253, + 104, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 268, 104, 269, + 104, 104, 270, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 271, + 272, 273, 104, 104, 104, 104, 104, 274, 275, 276, 104, 277, 278, 104, + 104, 279, 280, 281, 282, 283, 104, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 300, 301, 302, + 303, 304, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 305, 104, 306, 307, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 308, 309, 310, + 311, 312, 313, 314, 315, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, +}; + +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, + 423, 426, 429, 432, 436, 439, 442, 445, 447, 450, 456, 464, 470, 476, + 482, 487, 494, 500, 507, 514, 521, 529, 534, 542, 550, 557, 565, 573, + 581, 588, 596, 604, 609, 617, 624, 630, 637, 644, 651, 654, 660, 667, + 673, 680, 687, 694, 699, 706, 713, 719, 726, 733, 740, 748, 753, 761, + 769, 776, 784, 792, 800, 807, 815, 823, 828, 836, 843, 849, 856, 863, + 870, 873, 879, 886, 892, 899, 906, 913, 918, 926, 933, 940, 947, 954, + 961, 968, 975, 982, 990, 998, 1006, 1014, 1022, 1030, 1038, 1046, 1053, + 1060, 1068, 1076, 1084, 1092, 1100, 1108, 1116, 1124, 1132, 1140, 1148, + 1156, 1164, 1172, 1180, 1188, 1196, 1204, 1212, 1220, 1227, 1234, 1242, + 1250, 1258, 1266, 1274, 1282, 1290, 1298, 1306, 1312, 1317, 1322, 1330, + 1338, 1346, 1354, 1359, 1366, 1373, 1381, 1389, 1397, 1405, 1414, 1423, + 1430, 1437, 1444, 1451, 1459, 1467, 1475, 1483, 1494, 1499, 1504, 1511, + 1518, 1525, 1532, 1539, 1546, 1551, 1556, 1563, 1570, 1578, 1586, 1594, + 1602, 1609, 1616, 1624, 1632, 1640, 1648, 1656, 1664, 1672, 1680, 1688, + 1696, 1703, 1710, 1717, 1724, 1731, 1738, 1745, 1752, 1760, 1768, 1775, + 1782, 1789, 1796, 1804, 1812, 1820, 1828, 1836, 1843, 1850, 1858, 1866, + 1874, 1882, 1888, 1894, 1900, 1907, 1914, 1919, 1924, 1929, 1936, 1943, + 1950, 1957, 1965, 1973, 1979, 1985, 1990, 1995, 2002, 2009, 2016, 2021, + 2026, 2031, 2038, 2045, 2052, 2059, 2066, 2072, 2080, 2090, 2098, 2105, + 2112, 2117, 2122, 2129, 2136, 2140, 2145, 2150, 2155, 2163, 2172, 2179, + 2186, 2195, 2202, 2209, 2214, 2221, 2228, 2235, 2242, 2249, 2254, 2261, + 2268, 2276, 2281, 2286, 2291, 2301, 2305, 2311, 2317, 2323, 2329, 2337, + 2350, 2358, 2363, 2373, 2378, 2383, 2393, 2398, 2405, 2412, 2420, 2428, + 2435, 2442, 2449, 2456, 2466, 2476, 2485, 2494, 2504, 2514, 2524, 2534, + 2539, 2549, 2559, 2569, 2579, 2587, 2595, 2602, 2609, 2617, 2625, 2633, + 2641, 2648, 2655, 2665, 2675, 2683, 2691, 2699, 2704, 2714, 2719, 2726, + 2733, 2738, 2743, 2751, 2759, 2769, 2779, 2786, 2793, 2802, 2811, 2819, + 2827, 2836, 2845, 2854, 2863, 2873, 2883, 2892, 2901, 2911, 2921, 2929, + 2937, 2946, 2955, 2964, 2973, 2983, 2993, 3001, 3009, 3018, 3027, 3036, + 3045, 3054, 3063, 3068, 3073, 3081, 3089, 3099, 3107, 3112, 3117, 3124, + 3131, 3138, 3145, 3153, 3161, 3171, 3181, 3191, 3201, 3208, 3215, 3225, + 3235, 3243, 3251, 3259, 3267, 3275, 3282, 3289, 3296, 3302, 3309, 3316, + 3323, 3332, 3342, 3352, 3359, 3366, 3372, 3377, 3383, 3390, 3397, 3404, + 3411, 3422, 3432, 3439, 3446, 3453, 3460, 3465, 3470, 3476, 3482, 3487, + 3495, 3503, 3510, 3516, 3521, 3528, 3533, 3540, 3550, 3559, 3568, 3575, + 3581, 3587, 3592, 3599, 3605, 3612, 3619, 3626, 3631, 3636, 3645, 3653, + 3662, 3667, 3673, 3683, 3690, 3698, 3707, 3713, 3719, 3725, 3732, 3737, + 3742, 3752, 3760, 3769, 3777, 3785, 3795, 3800, 3807, 3814, 3819, 3831, + 3840, 3848, 3854, 3863, 3868, 3873, 3880, 3886, 3892, 3898, 3904, 3913, + 3921, 3926, 3934, 3940, 3948, 3956, 3962, 3968, 3974, 3981, 3989, 3995, + 4003, 4009, 4014, 4021, 4029, 4039, 4046, 4053, 4063, 4070, 4077, 4087, + 4094, 4101, 4108, 4114, 4120, 4129, 4141, 4146, 4153, 4158, 4162, 4167, + 4175, 4182, 4187, 4192, 4196, 4201, 4206, 4210, 4216, 4222, 4228, 4234, + 4242, 4247, 4252, 4257, 4262, 4268, 4270, 4275, 4279, 4285, 4291, 4297, + 4302, 4309, 4316, 4322, 4329, 4337, 4345, 4350, 4355, 4359, 4364, 4366, + 4368, 4371, 4373, 4376, 4381, 4386, 4392, 4397, 4401, 4406, 4411, 4420, + 4426, 4431, 4437, 4442, 4448, 4456, 4464, 4468, 4472, 4477, 4483, 4489, + 4495, 4501, 4506, 4513, 4521, 4529, 4534, 4540, 4547, 4554, 4561, 4568, + 4572, 4577, 4582, 4587, 4592, 4597, 4600, 4603, 4606, 4609, 4612, 4615, + 4619, 4623, 4629, 4632, 4637, 4643, 4649, 4652, 4657, 4662, 4666, 4672, + 4678, 4684, 4690, 4695, 4700, 4705, 4708, 4714, 4719, 4724, 4728, 4733, + 4739, 4745, 4748, 4752, 4756, 4760, 4763, 4766, 4771, 4775, 4782, 4786, + 4792, 4796, 4802, 4806, 4810, 4814, 4819, 4824, 4831, 4837, 4844, 4850, + 4856, 4862, 4865, 4869, 4873, 4877, 4881, 4886, 4891, 4895, 4899, 4905, + 4909, 4913, 4918, 4924, 4929, 4935, 4939, 4946, 4951, 4956, 4961, 4966, + 4972, 4975, 4979, 4984, 4989, 4998, 5004, 5009, 5013, 5018, 5022, 5027, + 5031, 5035, 5040, 5044, 5050, 5055, 5060, 5065, 5070, 5075, 5080, 5086, + 5092, 5098, 5104, 5109, 5115, 5121, 5127, 5132, 5137, 5144, 5151, 5155, + 5161, 5168, 0, 0, 5175, 5178, 5187, 5196, 5207, 5211, 0, 0, 0, 0, 5216, + 5219, 5224, 5232, 5237, 5245, 5253, 0, 5261, 0, 5269, 5277, 5285, 5296, + 5301, 5306, 5311, 5316, 5321, 5326, 5331, 5336, 5341, 5346, 5351, 5356, + 5361, 5366, 5371, 5376, 0, 5381, 5386, 5391, 5396, 5401, 5406, 5411, + 5416, 5424, 5432, 5440, 5448, 5456, 5464, 5475, 5480, 5485, 5490, 5495, + 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545, 5550, 5555, + 5560, 5566, 5571, 5576, 5581, 5586, 5591, 5596, 5601, 5609, 5617, 5625, + 5633, 5641, 5646, 5650, 5654, 5661, 5671, 5681, 5685, 5689, 5693, 5699, + 5706, 5710, 5715, 5719, 5724, 5728, 5733, 5737, 5742, 5747, 5752, 5757, + 5762, 5767, 5772, 5777, 5782, 5787, 5792, 5797, 5802, 5807, 5812, 5816, + 5820, 5826, 5830, 5835, 5841, 5849, 5854, 5859, 5866, 5871, 5876, 5883, + 5892, 5901, 5912, 5920, 5925, 5930, 5935, 5942, 5947, 5953, 5958, 5963, + 5968, 5973, 5978, 5983, 5991, 5997, 6002, 6006, 6011, 6016, 6021, 6026, + 6031, 6036, 6041, 6045, 6051, 6055, 6060, 6065, 6070, 6074, 6079, 6084, + 6089, 6094, 6098, 6103, 6107, 6112, 6117, 6122, 6127, 6133, 6138, 6144, + 6148, 6153, 6157, 6161, 6166, 6171, 6176, 6181, 6186, 6191, 6196, 6200, + 6206, 6210, 6215, 6220, 6225, 6229, 6234, 6239, 6244, 6249, 6253, 6258, + 6262, 6267, 6272, 6277, 6282, 6288, 6293, 6299, 6303, 6308, 6312, 6320, + 6325, 6330, 6335, 6342, 6347, 6353, 6358, 6363, 6368, 6373, 6378, 6383, + 6391, 6397, 6402, 6407, 6412, 6417, 6422, 6428, 6434, 6441, 6448, 6457, + 6466, 6473, 6480, 6489, 6498, 6503, 6508, 6513, 6518, 6523, 6528, 6533, + 6538, 6549, 6560, 6565, 6570, 6577, 6584, 6592, 6600, 6605, 6610, 6615, + 6620, 6624, 6628, 6632, 6638, 6644, 6648, 6655, 6660, 6670, 6680, 6686, + 6692, 6700, 6708, 6716, 6724, 6731, 6738, 6746, 6754, 6762, 6770, 6778, + 6786, 6794, 6802, 6810, 6818, 6825, 6832, 6838, 6844, 6852, 6860, 6867, + 6874, 6882, 6890, 6896, 6902, 6910, 6918, 6926, 6934, 6940, 6946, 6954, + 6962, 6970, 6978, 6985, 6992, 7000, 7008, 7016, 7024, 7029, 7034, 7041, + 7048, 7058, 7068, 7072, 7080, 7088, 7095, 7102, 7110, 7118, 7125, 7132, + 7140, 7148, 7155, 7162, 7170, 7178, 7183, 7190, 7197, 7204, 7211, 7217, + 7223, 7231, 7239, 7244, 7249, 7257, 7265, 7273, 7281, 7289, 7297, 7304, + 7311, 7319, 7327, 7335, 7343, 7350, 7357, 7363, 7369, 7378, 7387, 7395, + 7403, 7410, 7417, 7424, 7431, 7438, 7445, 7453, 7461, 7469, 7477, 7485, + 7493, 7503, 7513, 7520, 7527, 7534, 7541, 7548, 7555, 7562, 7569, 7576, + 7583, 7590, 7597, 7604, 7611, 7618, 7625, 7632, 7639, 7646, 7653, 7660, + 7667, 7674, 7681, 7686, 7691, 7696, 7701, 7706, 7711, 7716, 7721, 7726, + 7731, 7737, 7743, 7751, 7759, 7767, 7775, 7783, 7791, 7799, 7807, 7815, + 7823, 7828, 7833, 7838, 7843, 7851, 0, 7859, 7865, 7871, 7877, 7883, + 7889, 7895, 7901, 7907, 7912, 7918, 7924, 7930, 7936, 7942, 7948, 7954, + 7960, 7966, 7972, 7978, 7984, 7990, 7996, 8002, 8008, 8014, 8020, 8025, + 8031, 8037, 8043, 8049, 8055, 8061, 8067, 8073, 8079, 0, 0, 8085, 8093, + 8097, 8102, 8107, 8111, 8116, 8121, 8128, 8134, 8140, 8146, 8152, 8158, + 8164, 8170, 8176, 8181, 8187, 8193, 8199, 8205, 8211, 8217, 8223, 8229, + 8235, 8241, 8247, 8253, 8259, 8265, 8271, 8277, 8283, 8289, 8294, 8300, + 8306, 8312, 8318, 8324, 8330, 8336, 8342, 8348, 8354, 8362, 8369, 8375, + 0, 0, 8379, 8386, 8393, 0, 8398, 8403, 8408, 8413, 8420, 8427, 8432, + 8437, 8442, 8447, 8452, 8457, 8462, 8469, 8474, 8481, 8488, 8493, 8500, + 8505, 8510, 8515, 8522, 8527, 8532, 8539, 8548, 8553, 8558, 8563, 8568, + 8574, 8579, 8586, 8593, 8600, 8605, 8610, 8615, 8620, 8625, 8630, 8640, + 8645, 8654, 8659, 8664, 8669, 8674, 8681, 8688, 8695, 8701, 8707, 8714, + 0, 0, 0, 0, 0, 0, 0, 0, 8721, 8725, 8729, 8733, 8737, 8741, 8745, 8749, + 8753, 8757, 8761, 8766, 8770, 8774, 8779, 8783, 8788, 8792, 8796, 8800, + 8805, 8809, 8814, 8818, 8822, 8826, 8830, 0, 0, 0, 0, 8834, 8839, 8846, + 8854, 8861, 8866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8871, 8874, 8878, + 8883, 8887, 8891, 8895, 8901, 8907, 8910, 8917, 8926, 8929, 8932, 8937, + 8943, 8947, 8955, 8961, 8967, 8975, 8979, 8984, 8995, 9000, 9004, 9008, + 9012, 9015, 0, 9018, 9025, 9029, 9035, 9039, 9046, 9053, 9061, 9068, + 9075, 9079, 9083, 9089, 9093, 9097, 9101, 9105, 9109, 9113, 9117, 9121, + 9125, 9129, 9133, 9137, 9141, 9145, 9149, 9153, 9157, 9166, 9175, 9185, + 9195, 9205, 9208, 9212, 9216, 9220, 9224, 9228, 9232, 9236, 9240, 9245, + 9249, 9252, 9255, 9258, 9261, 9264, 9267, 9270, 9273, 9277, 9281, 9285, + 9290, 9295, 9301, 9304, 9311, 9320, 9325, 9330, 9337, 9343, 9348, 9352, + 9356, 9360, 9364, 9368, 9372, 9376, 9380, 9384, 9388, 9393, 9398, 9405, + 9411, 9417, 9423, 9428, 9437, 9446, 9451, 9458, 9465, 9472, 9479, 9483, + 9487, 9491, 9498, 9509, 9513, 9517, 9521, 9528, 9537, 9541, 9545, 9553, + 9557, 9561, 9565, 9572, 9579, 9591, 9595, 9599, 9603, 9614, 9624, 9628, + 9636, 9643, 9650, 9659, 9670, 9679, 9683, 9693, 9704, 9713, 9728, 9737, + 9746, 9755, 9764, 9770, 9779, 9786, 9790, 9799, 9803, 9810, 9819, 9823, + 9829, 9836, 9843, 9847, 9856, 9860, 9867, 9871, 9880, 9884, 9893, 9901, + 9908, 9917, 9926, 9933, 9939, 9943, 9950, 9959, 9965, 9972, 9979, 9985, + 9995, 10003, 10010, 10016, 10020, 10023, 10027, 10033, 10042, 10046, + 10052, 10058, 10065, 10072, 10075, 10083, 10088, 10097, 10102, 10106, + 10119, 10132, 10138, 10145, 10150, 10156, 10161, 10167, 10177, 10184, + 10193, 10203, 10209, 10214, 10219, 10223, 10227, 10232, 10237, 10243, + 10251, 10259, 10270, 10275, 10284, 10293, 10300, 10306, 10312, 10318, + 10324, 10330, 10336, 10342, 10348, 10354, 10361, 10368, 10375, 10381, + 10389, 10398, 10405, 10413, 10421, 10427, 10433, 10439, 10447, 10455, + 10465, 10475, 10479, 10485, 10491, 0, 10497, 10502, 10507, 10514, 10519, + 10524, 10531, 10536, 10545, 10550, 10555, 10560, 10565, 10570, 10577, + 10582, 10589, 10594, 10599, 10604, 10609, 10614, 10620, 10624, 10629, + 10636, 10641, 10646, 10651, 10656, 10661, 10668, 10675, 10682, 10687, + 10692, 10698, 10703, 10708, 10714, 10719, 10724, 10732, 10740, 10745, + 10750, 10756, 10761, 10766, 10770, 10776, 10780, 10784, 10791, 10798, + 10804, 10810, 10817, 10824, 10828, 0, 0, 10832, 10839, 10846, 10853, + 10864, 10877, 10890, 10909, 10922, 10933, 10941, 10949, 10961, 10977, + 10988, 10994, 11004, 11013, 11026, 11037, 11046, 11059, 11066, 11075, + 11088, 11094, 11100, 11109, 11117, 11125, 11131, 11142, 11150, 11161, + 11171, 11184, 11198, 11212, 11222, 11233, 11244, 11257, 11270, 11284, + 11296, 11308, 11321, 11334, 11346, 11359, 11368, 11377, 11382, 11387, + 11392, 11397, 11402, 11407, 11412, 11417, 11422, 11427, 11432, 11437, + 11442, 11447, 11452, 11457, 11462, 11467, 11472, 11477, 11482, 11487, + 11492, 11497, 11502, 11507, 11512, 11517, 11522, 11527, 11532, 11537, + 11541, 11546, 11551, 11556, 11561, 11566, 11570, 11574, 11578, 11582, + 11586, 11590, 11594, 11598, 11602, 11606, 11610, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11615, 11620, 11624, 11628, 11632, 11636, 11640, 11644, + 11648, 11652, 11656, 11660, 11665, 11669, 11673, 11677, 11682, 11686, + 11691, 11696, 11701, 11705, 11709, 11714, 11719, 11724, 11728, 11733, + 11737, 11742, 11747, 11751, 11755, 11762, 11766, 11771, 11775, 11779, + 11784, 11788, 11795, 11802, 11809, 11815, 11823, 11831, 11840, 11848, + 11855, 11862, 11870, 11876, 11882, 11888, 11894, 11901, 11906, 11910, + 11915, 0, 0, 11919, 11923, 11928, 11933, 11938, 11943, 11948, 11953, + 11958, 11963, 11968, 11973, 11978, 11983, 11988, 11993, 11998, 12003, + 12008, 12013, 12018, 12023, 12028, 12033, 12038, 12043, 12048, 12053, + 12058, 12063, 12071, 12078, 12084, 12089, 12097, 12104, 12110, 12117, + 12123, 12128, 12135, 12142, 12148, 12153, 12158, 12164, 12169, 12174, + 12180, 0, 0, 12185, 12191, 12197, 12203, 12209, 12215, 12221, 12226, + 12234, 12240, 12246, 12252, 12258, 12264, 12272, 0, 12278, 12283, 12288, + 12293, 12298, 12303, 12308, 12313, 12318, 12323, 12328, 12333, 12338, + 12343, 12348, 12353, 12358, 12363, 12368, 12373, 12378, 12383, 12388, + 12393, 12398, 12403, 12408, 12413, 0, 0, 12418, 0, 12422, 12428, 12434, + 12440, 12446, 12452, 12458, 12464, 12469, 12475, 12481, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12487, 12496, 12504, 12513, 12522, 12535, 12542, 12549, 12557, 12570, + 12582, 12589, 12597, 12603, 12608, 12617, 12626, 12634, 12640, 12650, + 12659, 0, 12666, 12674, 12682, 12691, 12700, 12714, 12720, 12726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12732, 12737, + 12744, 12749, 12754, 12759, 12767, 12775, 12782, 12789, 12796, 12803, + 12810, 12817, 12824, 12830, 12838, 12843, 12848, 12853, 12858, 12863, + 12868, 12873, 12878, 12884, 12889, 12894, 12900, 12905, 12909, 12913, + 12917, 12922, 12928, 12934, 12940, 12945, 12950, 12955, 12960, 12966, + 12975, 12983, 12989, 12997, 13003, 13007, 13011, 13015, 13020, 13023, + 13027, 13030, 13034, 13037, 13041, 13045, 13049, 13054, 13059, 13062, + 13066, 13071, 13076, 13079, 13083, 13086, 13090, 13094, 13098, 13102, + 13106, 13110, 13114, 13118, 13122, 13126, 13130, 13134, 13138, 13142, + 13145, 13149, 13153, 13157, 13160, 13164, 13167, 13171, 13175, 13179, + 13182, 13185, 13188, 13192, 13195, 13199, 13203, 13207, 13211, 13215, + 13218, 13221, 13226, 13231, 13235, 13239, 13244, 13248, 13253, 13257, + 13262, 13267, 13273, 13279, 13285, 13289, 13294, 13300, 13306, 13310, + 13315, 13319, 13325, 13330, 13333, 13339, 13345, 13350, 13355, 13362, + 13367, 13372, 13376, 13380, 13384, 13388, 13392, 13396, 13400, 13404, + 13409, 13414, 13419, 13425, 13428, 13432, 13436, 13439, 13442, 13445, + 13448, 13451, 13454, 13457, 13460, 13463, 13467, 13474, 13479, 13483, + 13487, 13491, 13495, 13499, 13505, 13509, 13513, 13517, 13521, 13527, + 13531, 13535, 13539, 13544, 13549, 0, 13554, 13558, 13563, 13567, 13572, + 13576, 13581, 13586, 0, 0, 13591, 13595, 0, 0, 13600, 13604, 13609, + 13613, 13618, 13623, 13628, 13633, 13638, 13643, 13648, 13653, 13658, + 13663, 13668, 13673, 13678, 13683, 13687, 13692, 13697, 13702, 0, 13706, + 13710, 13715, 13720, 13725, 13729, 13733, 0, 13737, 0, 0, 0, 13741, + 13746, 13751, 13755, 0, 0, 13759, 13764, 13769, 13775, 13780, 13786, + 13791, 13797, 13803, 0, 0, 13810, 13815, 0, 0, 13821, 13826, 13832, + 13837, 0, 0, 0, 0, 0, 0, 0, 0, 13843, 0, 0, 0, 0, 13850, 13855, 0, 13860, + 13865, 13871, 13877, 13883, 0, 0, 13890, 13895, 13899, 13903, 13907, + 13911, 13915, 13919, 13923, 13927, 13931, 13940, 13950, 13955, 13960, + 13967, 13974, 13981, 13988, 14003, 14011, 14015, 14020, 14027, 14032, 0, + 0, 14037, 14044, 14049, 0, 14054, 14058, 14063, 14067, 14072, 14076, 0, + 0, 0, 0, 14081, 14086, 0, 0, 14091, 14096, 14101, 14105, 14110, 14115, + 14120, 14125, 14130, 14135, 14140, 14145, 14150, 14155, 14160, 14165, + 14170, 14175, 14179, 14184, 14189, 14194, 0, 14198, 14202, 14207, 14212, + 14217, 14221, 14225, 0, 14229, 14233, 0, 14238, 14243, 0, 14248, 14252, + 0, 0, 14256, 0, 14261, 14267, 14272, 14278, 14283, 0, 0, 0, 0, 14289, + 14295, 0, 0, 14301, 14307, 14313, 0, 0, 0, 14318, 0, 0, 0, 0, 0, 0, 0, + 14323, 14328, 14333, 14338, 0, 14343, 0, 0, 0, 0, 0, 0, 0, 14348, 14353, + 14357, 14361, 14365, 14369, 14373, 14377, 14381, 14385, 14389, 14393, + 14397, 14401, 14405, 14411, 14416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14421, + 14426, 14431, 0, 14436, 14440, 14445, 14449, 14454, 14458, 14463, 14468, + 14473, 0, 14479, 14483, 14488, 0, 14494, 14498, 14503, 14507, 14512, + 14517, 14522, 14527, 14532, 14537, 14542, 14547, 14552, 14557, 14562, + 14567, 14572, 14577, 14581, 14586, 14591, 14596, 0, 14600, 14604, 14609, + 14614, 14619, 14623, 14627, 0, 14631, 14635, 0, 14640, 14645, 14650, + 14655, 14659, 0, 0, 14663, 14668, 14673, 14679, 14684, 14690, 14695, + 14701, 14707, 14714, 0, 14721, 14726, 14732, 0, 14739, 14744, 14750, 0, + 0, 14755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14759, 14765, + 14771, 14777, 0, 0, 14784, 14789, 14793, 14797, 14801, 14805, 14809, + 14813, 14817, 14821, 14825, 14830, 0, 0, 0, 0, 0, 0, 0, 14835, 14840, + 14845, 14850, 14855, 14863, 14871, 0, 14879, 14884, 14889, 0, 14894, + 14898, 14903, 14907, 14912, 14916, 14921, 14926, 0, 0, 14931, 14935, 0, + 0, 14940, 14944, 14949, 14953, 14958, 14963, 14968, 14973, 14978, 14983, + 14988, 14993, 14998, 15003, 15008, 15013, 15018, 15023, 15027, 15032, + 15037, 15042, 0, 15046, 15050, 15055, 15060, 15065, 15069, 15073, 0, + 15077, 15081, 0, 15086, 15091, 15096, 15101, 15105, 0, 0, 15109, 15114, + 15119, 15125, 15130, 15136, 15141, 15147, 15153, 0, 0, 15160, 15165, 0, + 0, 15171, 15176, 15182, 0, 0, 0, 0, 0, 0, 0, 0, 15187, 15194, 0, 0, 0, 0, + 15201, 15206, 0, 15211, 15216, 15222, 15228, 15234, 0, 0, 15241, 15246, + 15250, 15254, 15258, 15262, 15266, 15270, 15274, 15278, 15282, 15286, + 15291, 15297, 15303, 15309, 15315, 15321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15327, 15331, 0, 15335, 15338, 15342, 15345, 15349, 15352, 0, 0, 0, + 15356, 15359, 15363, 0, 15367, 15370, 15374, 15378, 0, 0, 0, 15381, + 15385, 0, 15389, 0, 15393, 15397, 0, 0, 0, 15401, 15405, 0, 0, 0, 15408, + 15411, 15415, 0, 0, 0, 15418, 15421, 15424, 15427, 15431, 15434, 15438, + 15442, 15446, 15450, 15454, 15457, 0, 0, 0, 0, 15460, 15465, 15469, + 15474, 15478, 0, 0, 0, 15483, 15487, 15492, 0, 15497, 15501, 15506, + 15511, 0, 0, 15515, 0, 0, 0, 0, 0, 0, 15518, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15524, 15528, 15531, 15534, 15537, 15540, 15543, 15546, + 15549, 15552, 15555, 15559, 15564, 15568, 15572, 15576, 15580, 15584, + 15588, 15593, 15597, 0, 0, 0, 0, 0, 15600, 15607, 15612, 15617, 15622, + 15629, 15633, 15638, 15642, 15647, 15651, 15656, 15661, 0, 15666, 15670, + 15675, 0, 15680, 15684, 15689, 15694, 15698, 15703, 15708, 15713, 15718, + 15723, 15728, 15733, 15738, 15743, 15748, 15753, 15758, 15763, 15768, + 15772, 15777, 15782, 15787, 0, 15791, 15795, 15800, 15805, 15810, 15814, + 15818, 15822, 15827, 15831, 15836, 15841, 15846, 15851, 15856, 15860, 0, + 0, 0, 15864, 15869, 15875, 15880, 15886, 15891, 15897, 15903, 0, 15910, + 15915, 15921, 0, 15927, 15932, 15938, 15944, 0, 0, 0, 0, 0, 0, 0, 15949, + 15954, 0, 15961, 15966, 15971, 0, 0, 0, 0, 0, 15976, 15982, 15988, 15994, + 0, 0, 16001, 16006, 16010, 16014, 16018, 16022, 16026, 16030, 16034, + 16038, 0, 0, 0, 0, 0, 0, 0, 16042, 16047, 16060, 16072, 16084, 16096, + 16108, 16120, 16132, 16137, 16144, 16149, 16154, 16159, 16164, 16168, + 16173, 16177, 16182, 16186, 16191, 16196, 0, 16201, 16205, 16210, 0, + 16215, 16219, 16224, 16229, 16233, 16238, 16243, 16248, 16253, 16258, + 16263, 16268, 16273, 16278, 16283, 16288, 16293, 16298, 16303, 16307, + 16312, 16317, 16322, 0, 16326, 16330, 16335, 16340, 16345, 16349, 16353, + 16357, 16362, 16366, 0, 16371, 16376, 16381, 16386, 16390, 0, 0, 16394, + 16399, 16404, 16410, 16415, 16421, 16426, 16432, 16438, 0, 16445, 16450, + 16456, 0, 16462, 16467, 16473, 16479, 0, 0, 0, 0, 0, 0, 0, 16484, 16489, + 0, 0, 0, 0, 0, 0, 0, 16496, 0, 16501, 16507, 16513, 16519, 0, 0, 16526, + 16531, 16535, 16539, 16543, 16547, 16551, 16555, 16559, 16563, 0, 16567, + 16572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16577, 16583, 16587, 16591, + 0, 16595, 16598, 16602, 16605, 16609, 16612, 16616, 16620, 0, 16624, + 16627, 16631, 0, 16635, 16638, 16642, 16646, 16649, 16653, 16657, 16661, + 16665, 16669, 16673, 16677, 16681, 16685, 16689, 16693, 16697, 16701, + 16705, 16708, 16712, 16716, 16720, 16723, 16727, 16730, 16734, 16738, + 16742, 16745, 16748, 16751, 16755, 16758, 16762, 16766, 16770, 16774, + 16778, 16781, 16784, 16788, 16795, 16801, 16805, 16810, 16814, 16819, + 16823, 16828, 16833, 0, 16839, 16843, 16848, 0, 16853, 16857, 16862, + 16867, 16871, 16876, 0, 0, 0, 0, 16880, 16886, 16892, 16898, 16904, + 16909, 16914, 16919, 16924, 16929, 16934, 16939, 16945, 16950, 16955, + 16960, 0, 0, 16966, 16970, 16973, 16976, 16979, 16982, 16985, 16988, + 16991, 16994, 16997, 17001, 17006, 17010, 17015, 17020, 17025, 17030, + 17035, 17040, 17044, 17050, 17056, 17062, 17067, 17073, 0, 0, 17079, + 17083, 0, 17087, 17091, 17095, 17099, 17103, 17107, 17111, 17115, 17119, + 17123, 17127, 17131, 17135, 17139, 17143, 17147, 17151, 17155, 0, 0, 0, + 17159, 17165, 17171, 17177, 17183, 17189, 17195, 17201, 17207, 17213, + 17219, 17225, 17233, 17239, 17245, 17251, 17257, 17263, 17269, 17275, + 17281, 17287, 17293, 17299, 0, 17305, 17311, 17317, 17323, 17329, 17335, + 17339, 17345, 17349, 0, 17353, 0, 0, 17359, 17363, 17369, 17375, 17381, + 17385, 17391, 0, 0, 0, 17395, 0, 0, 0, 0, 17399, 17404, 17411, 17418, + 17425, 17432, 0, 17439, 0, 17446, 17451, 17456, 17463, 17470, 17479, + 17490, 17499, 0, 0, 0, 0, 0, 0, 17504, 17510, 17515, 17520, 17525, 17530, + 17535, 17540, 17545, 17550, 0, 0, 17555, 17562, 17569, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 17623, + 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679, 17686, 17693, + 17700, 17707, 17714, 17721, 17728, 17735, 17742, 17749, 17756, 17763, + 17770, 17777, 17784, 17791, 17798, 17804, 17811, 17818, 17823, 17830, + 17835, 17842, 17849, 17856, 17863, 17870, 17877, 17883, 17890, 17895, + 17901, 17908, 17915, 17922, 17928, 17935, 17942, 17949, 17955, 17962, 0, + 0, 0, 0, 17967, 17974, 17980, 17987, 17993, 18002, 18011, 18016, 18021, + 18026, 18033, 18040, 18047, 18054, 18059, 18064, 18069, 18074, 18079, + 18083, 18087, 18091, 18095, 18099, 18103, 18107, 18111, 18115, 18120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18125, 18130, 0, 18137, 0, 18144, + 18151, 18156, 18161, 18168, 0, 18175, 18182, 18187, 18194, 18201, 18208, + 18215, 18222, 18229, 18234, 18238, 18245, 18252, 18259, 18264, 18269, + 18274, 18281, 18288, 18295, 18302, 18309, 18314, 18319, 0, 18326, 0, + 18333, 18338, 18345, 18352, 18359, 18366, 18373, 18377, 18384, 18388, + 18393, 18401, 18407, 18413, 18418, 18424, 18430, 18436, 18441, 18447, + 18454, 18462, 18469, 0, 0, 18476, 18481, 18487, 18492, 18498, 0, 18504, + 0, 18509, 18516, 18523, 18530, 18537, 18542, 0, 0, 18546, 18551, 18555, + 18559, 18563, 18567, 18571, 18575, 18579, 18583, 0, 0, 18587, 18593, + 18599, 18606, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18613, 18617, 18628, 18643, 18658, + 18668, 18679, 18692, 18703, 18709, 18717, 18727, 18733, 18741, 18745, + 18751, 18757, 18765, 18775, 18783, 18796, 18802, 18810, 18818, 18830, + 18837, 18845, 18853, 18861, 18869, 18877, 18885, 18895, 18899, 18902, + 18905, 18908, 18911, 18914, 18917, 18920, 18923, 18926, 18930, 18934, + 18938, 18942, 18946, 18950, 18954, 18958, 18962, 18967, 18973, 18983, + 18997, 19007, 19013, 19019, 19027, 19035, 19043, 19051, 19057, 19063, + 19066, 19070, 19074, 19078, 19082, 19086, 19090, 0, 19094, 19098, 19102, + 19106, 19110, 19114, 19118, 19121, 19125, 19129, 19133, 19136, 19139, + 19143, 19147, 19151, 19154, 19158, 19162, 19166, 19170, 19174, 19178, + 19182, 19186, 19189, 19192, 19195, 19199, 19203, 19206, 19209, 19212, + 19216, 19221, 19225, 0, 0, 0, 0, 19229, 19234, 19238, 19243, 19247, + 19252, 19257, 19263, 19268, 19274, 19278, 19283, 19287, 19292, 19302, + 19308, 19314, 19321, 19331, 19337, 19341, 19345, 19351, 19357, 19365, + 19371, 19379, 19387, 19395, 19405, 19413, 19423, 19428, 19434, 19440, + 19446, 19452, 19458, 19464, 0, 19470, 19476, 19482, 19488, 19494, 19500, + 19506, 19511, 19517, 19523, 19529, 19534, 19539, 19545, 19551, 19557, + 19562, 19568, 19574, 19580, 19586, 19592, 19598, 19604, 19610, 19615, + 19620, 19625, 19631, 19637, 19642, 19647, 19652, 19658, 19666, 19673, 0, + 19680, 19687, 19700, 19707, 19714, 19722, 19730, 19736, 19742, 19748, + 19758, 19763, 19769, 19779, 19789, 0, 19799, 19809, 19817, 19829, 19841, + 19847, 19861, 19876, 19881, 19886, 19894, 19902, 19910, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19918, 19921, 19925, 19929, 19933, 19937, 19941, + 19945, 19949, 19953, 19957, 19961, 19965, 19969, 19973, 19977, 19981, + 19984, 19988, 19992, 19996, 19999, 20002, 20006, 20010, 20014, 20017, + 20020, 20023, 20026, 20030, 20033, 20036, 20040, 20043, 20048, 20051, + 20055, 20058, 20062, 20065, 20070, 20073, 20077, 20084, 20089, 20093, + 20098, 20102, 20107, 20111, 20116, 20123, 20129, 20135, 20139, 20143, + 20147, 20151, 20155, 20161, 20167, 20174, 20180, 20185, 20189, 20192, + 20195, 20198, 20201, 20204, 20207, 20210, 20213, 20216, 20222, 20226, + 20230, 20234, 20238, 20242, 20246, 20250, 20254, 20259, 20263, 20268, + 20273, 20279, 20284, 20290, 20296, 20302, 20308, 20314, 20322, 20330, + 20338, 20346, 20355, 20364, 20375, 20385, 20395, 20406, 20417, 20427, + 20437, 20447, 20457, 20467, 20477, 20487, 20497, 20505, 20512, 20518, + 20525, 20530, 20536, 20542, 20548, 20554, 20560, 20566, 20571, 20577, + 20583, 20589, 20595, 20600, 20609, 20616, 20622, 20630, 20638, 20644, + 20650, 20656, 20662, 20670, 20678, 20688, 20696, 20704, 20710, 20715, + 20720, 20725, 20730, 20735, 20740, 20745, 20750, 20755, 20761, 20767, + 20773, 20780, 20785, 20791, 20796, 20801, 20806, 20811, 20816, 20821, + 20826, 20831, 20836, 20841, 20846, 20851, 20856, 20861, 20866, 20871, + 20876, 20881, 20886, 20891, 20896, 20901, 20906, 20911, 20916, 20921, + 20926, 20931, 20936, 20941, 20946, 20951, 20956, 20961, 20966, 20971, + 20976, 0, 20981, 0, 0, 0, 0, 0, 20986, 0, 0, 20991, 20995, 20999, 21003, + 21007, 21011, 21015, 21019, 21023, 21027, 21031, 21035, 21039, 21043, + 21047, 21051, 21055, 21059, 21063, 21067, 21071, 21075, 21079, 21083, + 21087, 21091, 21095, 21099, 21103, 21107, 21111, 21115, 21119, 21123, + 21127, 21131, 21135, 21139, 21143, 21147, 21151, 21155, 21160, 21164, + 21169, 21174, 21178, 21183, 21188, 21192, 21196, 21200, 21204, 21208, + 21212, 21216, 21220, 21224, 21228, 21232, 21236, 21240, 21244, 21248, + 21252, 21256, 21260, 21264, 21268, 21272, 21276, 21280, 21284, 21288, + 21292, 21296, 21300, 21304, 21308, 21312, 21316, 21320, 21324, 21328, + 21332, 21336, 21340, 21344, 21348, 21352, 21356, 21360, 21364, 21368, + 21372, 21376, 21380, 21384, 21388, 21392, 21396, 21400, 21404, 21408, + 21412, 21416, 21420, 21424, 21428, 21432, 21436, 21440, 21444, 21448, + 21452, 21456, 21460, 21464, 21468, 21472, 21476, 21480, 21484, 21488, + 21492, 21496, 21500, 21504, 21508, 21512, 21516, 21520, 21524, 21528, + 21532, 21536, 21540, 21544, 21548, 21552, 21556, 21560, 21564, 21568, + 21572, 21577, 21581, 21586, 21590, 21595, 21600, 21604, 21609, 21614, + 21618, 21623, 21628, 21633, 21638, 21642, 21647, 21652, 21657, 21662, + 21667, 21672, 21676, 21681, 21686, 21691, 21696, 21701, 21706, 21711, + 21716, 21721, 21726, 21731, 21736, 21741, 21746, 21751, 21756, 21761, + 21766, 21771, 21776, 21781, 21786, 21791, 21796, 21801, 21806, 21811, + 21816, 21821, 21826, 21831, 21836, 21841, 21846, 21851, 21856, 21861, + 21866, 21871, 21876, 21881, 21886, 21891, 21896, 21901, 21906, 21911, + 21916, 21921, 21926, 21930, 21934, 21938, 21942, 21946, 21950, 21954, + 21958, 21962, 21966, 21970, 21974, 21978, 21982, 21986, 21990, 21994, + 21998, 22002, 22006, 22010, 22014, 22018, 22022, 22026, 22030, 22034, + 22038, 22042, 22046, 22050, 22054, 22058, 22062, 22066, 22070, 22074, + 22078, 22082, 22086, 22090, 22094, 22098, 22102, 22106, 22110, 22114, + 22118, 22122, 22126, 22130, 22134, 22138, 22142, 22146, 22150, 22154, + 22158, 22162, 22166, 22170, 22174, 22178, 22182, 22186, 22190, 22194, + 22198, 22202, 22206, 22210, 22214, 22218, 22222, 22226, 22230, 22234, + 22238, 22242, 22246, 22250, 22254, 22258, 22262, 22266, 22270, 22274, + 22278, 22281, 22285, 22289, 22293, 22297, 22301, 22305, 22309, 22312, + 22316, 22320, 22324, 22328, 22332, 22336, 22340, 22344, 22348, 22352, + 22356, 22360, 22364, 22368, 22372, 22375, 22379, 22383, 22387, 22391, + 22395, 22399, 22403, 22407, 22411, 22415, 22419, 22423, 22427, 22431, + 22435, 22438, 22442, 22446, 22450, 22454, 22458, 22462, 22466, 22469, + 22473, 22477, 22481, 22485, 22489, 22493, 22497, 22501, 22505, 22509, + 22513, 22517, 22521, 22525, 22529, 22533, 22537, 22541, 22545, 22549, + 22553, 22557, 22561, 0, 22565, 22569, 22573, 22577, 0, 0, 22581, 22585, + 22589, 22593, 22597, 22601, 22605, 0, 22609, 0, 22613, 22617, 22621, + 22625, 0, 0, 22629, 22633, 22637, 22641, 22645, 22649, 22653, 22657, + 22661, 22665, 22669, 22673, 22677, 22681, 22685, 22689, 22693, 22696, + 22700, 22704, 22708, 22712, 22716, 22719, 22723, 22727, 22731, 22735, + 22739, 22743, 22747, 22751, 22755, 22759, 22763, 22767, 22771, 22775, + 22779, 22783, 22787, 0, 22791, 22795, 22799, 22803, 0, 0, 22807, 22810, + 22814, 22818, 22822, 22826, 22830, 22834, 22838, 22842, 22846, 22850, + 22854, 22858, 22862, 22866, 22870, 22875, 22880, 22885, 22891, 22897, + 22902, 22907, 22913, 22916, 22920, 22924, 22928, 22932, 22936, 22940, + 22944, 0, 22948, 22952, 22956, 22960, 0, 0, 22964, 22968, 22972, 22976, + 22980, 22984, 22988, 0, 22992, 0, 22996, 23000, 23004, 23008, 0, 0, + 23012, 23016, 23020, 23024, 23028, 23032, 23036, 23040, 23044, 23049, + 23054, 23059, 23065, 23071, 23076, 0, 23081, 23085, 23089, 23093, 23097, + 23101, 23105, 23109, 23113, 23117, 23121, 23125, 23129, 23133, 23137, + 23141, 23145, 23148, 23152, 23156, 23160, 23164, 23168, 23172, 23176, + 23180, 23184, 23188, 23192, 23196, 23200, 23204, 23208, 23212, 23216, + 23220, 23224, 23228, 23232, 23236, 23240, 23244, 23248, 23252, 23256, + 23260, 23264, 23268, 23272, 23276, 23280, 23284, 23288, 23292, 23296, + 23300, 23304, 0, 23308, 23312, 23316, 23320, 0, 0, 23324, 23328, 23332, + 23336, 23340, 23344, 23348, 23352, 23356, 23360, 23364, 23368, 23372, + 23376, 23380, 23384, 23388, 23392, 23396, 23400, 23404, 23408, 23412, + 23416, 23420, 23424, 23428, 23432, 23436, 23440, 23444, 23448, 23452, + 23456, 23460, 23464, 23468, 23472, 23476, 23480, 23484, 23488, 23492, + 23496, 23500, 23504, 23508, 23512, 23516, 23520, 23524, 23528, 23532, + 23536, 23540, 23544, 23548, 23551, 23555, 23559, 23563, 23567, 23571, + 23575, 23579, 23583, 23587, 0, 0, 23591, 23600, 23606, 23611, 23615, + 23618, 23623, 23626, 23629, 23632, 23637, 23641, 23646, 23649, 23652, + 23655, 23658, 23661, 23664, 23667, 23670, 23673, 23677, 23681, 23685, + 23689, 23693, 23697, 23701, 23705, 23709, 23713, 0, 0, 0, 23718, 23724, + 23728, 23732, 23736, 23742, 23746, 23750, 23754, 23760, 23764, 23768, + 23772, 23778, 23782, 23786, 23790, 23796, 23802, 23808, 23816, 23822, + 23828, 23834, 23840, 23846, 0, 0, 0, 0, 0, 0, 23852, 23855, 23858, 23861, + 23864, 23867, 23871, 23875, 23878, 23882, 23886, 23890, 23894, 23898, + 23901, 23905, 23909, 23913, 23917, 23921, 23924, 23928, 23932, 23936, + 23940, 23944, 23947, 23951, 23955, 23959, 23963, 23966, 23970, 23974, + 23978, 23982, 23986, 23990, 23994, 23998, 24002, 24006, 24010, 24014, + 24018, 24021, 24025, 24029, 24033, 24037, 24041, 24045, 24049, 24052, + 24056, 24060, 24064, 24068, 24072, 24076, 24080, 24084, 24088, 24092, + 24096, 24100, 24104, 24108, 24112, 24116, 24120, 24124, 24128, 24132, + 24136, 24140, 24144, 24148, 24152, 24156, 24159, 24163, 24167, 24171, + 24175, 24179, 0, 0, 24183, 24188, 24193, 24198, 24203, 24208, 0, 0, + 24213, 24217, 24220, 24224, 24227, 24231, 24234, 24238, 24244, 24249, + 24253, 24256, 24260, 24264, 24270, 24274, 24280, 24284, 24290, 24294, + 24300, 24304, 24310, 24316, 24320, 24326, 24330, 24336, 24342, 24346, + 24352, 24358, 24362, 24367, 24375, 24383, 24390, 24395, 24400, 24409, + 24415, 24423, 24428, 24434, 24438, 24442, 24446, 24450, 24454, 24458, + 24462, 24466, 24470, 24474, 24480, 24485, 24490, 24493, 24497, 24501, + 24507, 24511, 24517, 24521, 24527, 24531, 24537, 24541, 24547, 24551, + 24557, 24561, 24567, 24573, 24577, 24583, 24588, 24592, 24596, 24600, + 24604, 24607, 24611, 24617, 24622, 24627, 24630, 24634, 24638, 24644, + 24648, 24654, 24658, 24664, 24667, 24672, 24676, 24682, 24686, 24692, + 24696, 24702, 24708, 24712, 24716, 24720, 24724, 24728, 24732, 24736, + 24740, 24744, 24748, 24752, 24758, 24761, 24765, 24769, 24775, 24779, + 24785, 24789, 24795, 24799, 24805, 24809, 24815, 24819, 24825, 24829, + 24835, 24841, 24845, 24849, 24855, 24861, 24867, 24873, 24877, 24881, + 24885, 24889, 24893, 24897, 24903, 24907, 24911, 24915, 24921, 24925, + 24931, 24935, 24941, 24945, 24951, 24955, 24961, 24965, 24971, 24975, + 24981, 24987, 24991, 24997, 25001, 25005, 25009, 25013, 25017, 25021, + 25027, 25030, 25034, 25038, 25044, 25048, 25054, 25058, 25064, 25068, + 25074, 25078, 25084, 25088, 25094, 25098, 25104, 25110, 25114, 25120, + 25124, 25130, 25136, 25140, 25144, 25148, 25152, 25156, 25160, 25166, + 25169, 25173, 25177, 25183, 25187, 25193, 25197, 25203, 25209, 25213, + 25218, 25222, 25226, 25230, 25234, 25238, 25242, 25246, 25252, 25255, + 25259, 25263, 25269, 25273, 25279, 25283, 25289, 25293, 25299, 25303, + 25309, 25313, 25319, 25323, 25329, 25332, 25337, 25342, 25346, 25350, + 25354, 25358, 25362, 25366, 25372, 25375, 25379, 25383, 25389, 25393, + 25399, 25403, 25409, 25413, 25419, 25423, 25429, 25433, 25439, 25443, + 25449, 25455, 25459, 25465, 25469, 25475, 25481, 25487, 25493, 25499, + 25505, 25511, 25517, 25521, 25525, 25529, 25533, 25537, 25541, 25545, + 25549, 25555, 25559, 25565, 25569, 25575, 25579, 25585, 25589, 25595, + 25599, 25605, 25609, 25615, 25619, 25623, 25627, 25631, 25635, 25639, + 25643, 25649, 25652, 25656, 25660, 25666, 25670, 25676, 25680, 25686, + 25690, 25696, 25700, 25706, 25710, 25716, 25720, 25726, 25732, 25736, + 25742, 25748, 25754, 25758, 25764, 25770, 25774, 25778, 25782, 25786, + 25790, 25796, 25799, 25803, 25808, 25812, 25818, 25821, 25826, 25831, + 25835, 25839, 25843, 25847, 25851, 25855, 25859, 25863, 25867, 25873, + 25877, 25881, 25887, 25891, 25897, 25901, 25907, 25911, 25915, 25919, + 25923, 25927, 25933, 25937, 25941, 25945, 25949, 25953, 25957, 25961, + 25965, 25969, 25973, 25979, 25985, 25991, 25997, 26003, 26008, 26014, + 26020, 26026, 26030, 26034, 26038, 26042, 26046, 26050, 26054, 26058, + 26062, 26066, 26070, 26074, 26078, 26084, 26090, 26096, 26101, 26105, + 26109, 26113, 26117, 26121, 26125, 26129, 26133, 26137, 26143, 26149, + 26155, 26161, 26167, 26173, 26179, 26185, 26191, 26195, 26199, 26203, + 26207, 26211, 26215, 26219, 26225, 26231, 26237, 26243, 26249, 26255, + 26261, 26267, 26273, 26278, 26283, 26288, 26293, 26299, 26305, 26311, + 26317, 26323, 26329, 26335, 26340, 26346, 26352, 26358, 26363, 26369, + 26375, 26381, 26386, 26391, 26396, 26401, 26406, 26411, 26416, 26421, + 26426, 26431, 26436, 26441, 26445, 26450, 26455, 26460, 26465, 26470, + 26475, 26480, 26485, 26490, 26495, 26500, 26505, 26510, 26515, 26520, + 26525, 26530, 26535, 26540, 26545, 26550, 26555, 26560, 26565, 26570, + 26575, 26580, 26585, 26590, 26594, 26599, 26604, 26609, 26614, 26619, + 26624, 26629, 26634, 26639, 26644, 26649, 26654, 26659, 26664, 26669, + 26674, 26679, 26684, 26689, 26694, 26699, 26704, 26709, 26714, 26719, + 26723, 26728, 26733, 26738, 26743, 26748, 26752, 26757, 26762, 26767, + 26772, 26777, 26781, 26786, 26792, 26797, 26802, 26807, 26812, 26818, + 26823, 26828, 26833, 26838, 26843, 26848, 26853, 26858, 26863, 26868, + 26873, 26878, 26882, 26887, 26892, 26897, 26902, 26907, 26912, 26917, + 26922, 26927, 26932, 26937, 26942, 26947, 26952, 26957, 26962, 26967, + 26972, 26977, 26982, 26987, 26992, 26997, 27002, 27007, 27012, 27017, + 27022, 27027, 27032, 27037, 27043, 27048, 27053, 27058, 27063, 27068, + 27073, 27078, 27083, 27088, 27093, 27098, 27102, 27107, 27112, 27117, + 27122, 27127, 27132, 27137, 27142, 27147, 27152, 27157, 27162, 27167, + 27172, 27177, 27182, 27187, 27192, 27197, 27202, 27207, 27212, 27217, + 27222, 27227, 27232, 27238, 27242, 27246, 27250, 27254, 27258, 27262, + 27266, 27270, 27276, 27282, 27288, 27294, 27300, 27306, 27312, 27319, + 27325, 27330, 27335, 27340, 27345, 27350, 27355, 27360, 27365, 27370, + 27375, 27380, 27385, 27390, 27395, 27400, 27405, 27410, 27415, 27420, + 27425, 27430, 27435, 27440, 27445, 27450, 27455, 27460, 27465, 0, 0, 0, + 27472, 27483, 27488, 27496, 27501, 27506, 27511, 27520, 27525, 27531, + 27537, 27543, 27548, 27554, 27560, 27564, 27569, 27574, 27584, 27589, + 27594, 27601, 27606, 27611, 27620, 27625, 27634, 27641, 27648, 27655, + 27662, 27673, 27680, 27685, 27695, 27699, 27706, 27711, 27718, 27724, + 27731, 27740, 27747, 27754, 27763, 27770, 27775, 27780, 27791, 27798, + 27803, 27814, 27821, 27826, 27831, 27839, 27848, 27855, 27862, 27872, + 27877, 27882, 27887, 27896, 27904, 27909, 27914, 27919, 27924, 27929, + 27934, 27939, 27944, 27949, 27954, 27959, 27965, 27971, 27977, 27982, + 27987, 27992, 27997, 28002, 28007, 28016, 28025, 28034, 28043, 0, 0, 0, + 0, 0, 0, 0, 28052, 28056, 28060, 28064, 28068, 28073, 28078, 28082, + 28087, 28091, 28095, 28100, 28104, 0, 28108, 28112, 28117, 28121, 28125, + 28130, 28135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28140, 28144, 28148, + 28152, 28156, 28161, 28166, 28170, 28175, 28179, 28183, 28188, 28192, + 28196, 28200, 28204, 28209, 28213, 28217, 28222, 28227, 28232, 28238, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 28243, 28247, 28251, 28255, 28259, 28264, 28269, + 28273, 28278, 28282, 28286, 28291, 28295, 28299, 28303, 28307, 28312, + 28316, 28320, 28325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28330, 28334, + 28338, 28342, 28346, 28351, 28356, 28360, 28365, 28369, 28373, 28378, + 28382, 0, 28386, 28390, 28395, 0, 28399, 28404, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 28409, 28412, 28416, 28420, 28424, 28428, 28432, 28436, + 28440, 28444, 28448, 28452, 28456, 28460, 28464, 28468, 28471, 28475, + 28478, 28482, 28486, 28490, 28494, 28498, 28502, 28506, 28510, 28514, + 28518, 28522, 28526, 28530, 28533, 28536, 28539, 28543, 28549, 28555, + 28561, 28567, 28573, 28579, 28585, 28591, 28597, 28603, 28609, 28615, + 28621, 28627, 28636, 28645, 28651, 28657, 28663, 28668, 28672, 28677, + 28682, 28687, 28691, 28696, 28701, 28706, 28710, 28715, 28719, 28724, + 28729, 28734, 28739, 28743, 28747, 28751, 28755, 28759, 28763, 28767, + 28771, 28775, 28779, 28785, 28789, 28793, 28797, 28801, 28805, 28813, + 28819, 28823, 28829, 28833, 28839, 28843, 0, 0, 28847, 28851, 28854, + 28857, 28860, 28863, 28866, 28869, 28872, 28875, 0, 0, 0, 0, 0, 0, 28878, + 28886, 28894, 28902, 28910, 28918, 28926, 28934, 28942, 28950, 0, 0, 0, + 0, 0, 0, 28958, 28961, 28964, 28967, 28972, 28975, 28980, 28987, 28995, + 29000, 29007, 29010, 29017, 29024, 29031, 0, 29035, 29039, 29042, 29045, + 29048, 29051, 29054, 29057, 29060, 29063, 0, 0, 0, 0, 0, 0, 29066, 29069, + 29072, 29075, 29078, 29081, 29085, 29089, 29093, 29096, 29100, 29104, + 29107, 29111, 29115, 29118, 29121, 29124, 29128, 29131, 29135, 29139, + 29143, 29146, 29149, 29153, 29157, 29160, 29164, 29168, 29172, 29176, + 29180, 29184, 29188, 29192, 29199, 29204, 29209, 29214, 29219, 29225, + 29231, 29237, 29243, 29248, 29254, 29260, 29265, 29270, 29276, 29282, + 29288, 29294, 29299, 29305, 29310, 29316, 29322, 29328, 29334, 29340, + 29345, 29350, 29356, 29362, 29367, 29373, 29378, 29384, 29389, 29394, + 29400, 29405, 29411, 29417, 29423, 29429, 29435, 29441, 29447, 29453, + 29459, 29465, 29470, 29475, 29480, 29486, 29492, 0, 0, 0, 0, 0, 0, 0, + 29500, 29509, 29518, 29526, 29534, 29544, 29552, 29561, 29568, 29575, + 29582, 29590, 29598, 29606, 29614, 29622, 29630, 29637, 29645, 29652, + 29660, 29668, 29676, 29684, 29692, 29701, 29711, 29721, 29731, 29741, + 29751, 29761, 29771, 29780, 29790, 29800, 29810, 29820, 29830, 29838, + 29846, 29856, 29864, 0, 0, 0, 0, 0, 29874, 29878, 29882, 29886, 29890, + 29894, 29898, 29902, 29906, 29910, 29914, 29918, 29922, 29926, 29930, + 29934, 29938, 29942, 29946, 29950, 29954, 29958, 29962, 29966, 29972, + 29976, 29982, 29986, 29992, 29996, 30002, 30006, 30010, 30014, 30018, + 30022, 30026, 30032, 30038, 30044, 30050, 30056, 30062, 30068, 30074, + 30080, 30086, 30092, 30099, 30105, 30111, 30117, 30121, 30125, 30129, + 30133, 30137, 30141, 30145, 30151, 30157, 30163, 30168, 30175, 30180, + 30185, 30191, 30196, 30203, 30210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30217, + 30223, 30227, 30232, 30237, 30242, 30247, 30252, 30257, 30262, 30267, + 30272, 30276, 30281, 30286, 30291, 30295, 30299, 30304, 30309, 30314, + 30318, 30322, 30326, 30330, 30335, 30340, 30345, 30349, 30353, 30358, 0, + 30363, 30368, 30373, 30378, 30384, 30390, 30396, 30402, 30407, 30412, + 30418, 30424, 0, 0, 0, 0, 30431, 30436, 30442, 30448, 30453, 30458, + 30463, 30468, 30473, 30478, 30483, 30488, 0, 0, 0, 0, 30493, 0, 0, 0, + 30498, 30503, 30508, 30513, 30517, 30521, 30525, 30529, 30533, 30537, + 30541, 30545, 30549, 30554, 30560, 30566, 30572, 30577, 30582, 30587, + 30593, 30598, 30603, 30609, 30614, 30620, 30626, 30631, 30637, 30643, + 30649, 30654, 30659, 30664, 30670, 30676, 30681, 30687, 30692, 30698, + 30703, 30709, 0, 0, 30715, 30721, 30727, 30733, 30739, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30745, 30754, 30763, 30771, 30780, 30789, 30797, 30806, + 30815, 30824, 30832, 30840, 30849, 30857, 30865, 30873, 30882, 30890, + 30898, 30907, 30915, 30923, 30932, 30940, 30948, 30957, 30965, 30974, + 30983, 30991, 31000, 31009, 31017, 31025, 31034, 31043, 31051, 31060, + 31069, 31078, 31087, 31096, 31105, 31114, 0, 0, 0, 0, 31123, 31133, + 31142, 31151, 31159, 31168, 31176, 31185, 31193, 31202, 31211, 31220, + 31229, 31238, 31247, 31256, 31265, 31274, 31283, 31292, 31301, 31310, + 31319, 31328, 31337, 31345, 0, 0, 0, 0, 0, 0, 31353, 31361, 31368, 31375, + 31382, 31389, 31396, 31403, 31410, 31417, 31424, 0, 0, 0, 31432, 31440, + 31448, 31452, 31458, 31464, 31470, 31476, 31482, 31488, 31494, 31500, + 31506, 31512, 31518, 31524, 31530, 31536, 31542, 31546, 31552, 31558, + 31564, 31570, 31576, 31582, 31588, 31594, 31600, 31606, 31612, 31618, + 31624, 31630, 31636, 31640, 31645, 31650, 31655, 31659, 31664, 31668, + 31673, 31677, 31682, 31686, 31691, 31696, 31701, 31706, 31711, 31715, + 31719, 31723, 31728, 31732, 31736, 31740, 31745, 31750, 31755, 31760, 0, + 0, 31766, 31770, 31777, 31782, 31788, 31794, 31799, 31805, 31811, 31816, + 31822, 31828, 31834, 31839, 31845, 31850, 31855, 31861, 31866, 31872, + 31877, 31882, 31888, 31893, 31899, 31903, 31908, 31913, 31919, 31925, + 31930, 31936, 31942, 31946, 31951, 31956, 31960, 31965, 31969, 31974, + 31979, 31985, 31991, 31996, 32001, 32006, 32010, 32015, 32019, 32024, + 32028, 32033, 32038, 32043, 32048, 32054, 32061, 32068, 32078, 32087, + 32094, 32100, 32111, 32116, 32122, 0, 32127, 32132, 32137, 32145, 32151, + 32159, 32164, 32170, 32176, 32182, 32187, 32193, 32198, 32205, 32211, + 32216, 32222, 32228, 32234, 32241, 32248, 32255, 32260, 32265, 32272, + 32279, 32286, 32293, 32300, 0, 0, 32307, 32314, 32321, 32327, 32333, + 32339, 32345, 32351, 32357, 32363, 32369, 0, 0, 0, 0, 0, 0, 32375, 32381, + 32386, 32391, 32396, 32401, 32406, 32411, 32416, 32421, 0, 0, 0, 0, 0, 0, + 32426, 32431, 32436, 32441, 32446, 32451, 32456, 32465, 32472, 32477, + 32482, 32487, 32492, 32497, 0, 0, 32502, 32509, 32512, 32515, 32519, + 32524, 32528, 32534, 32538, 32543, 32550, 32558, 32562, 32567, 32571, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32576, 32582, 32588, + 32592, 32596, 32600, 32604, 32610, 32614, 32620, 32624, 32630, 32636, + 32644, 32650, 32658, 32662, 32666, 32670, 32676, 32679, 32685, 32689, + 32695, 32699, 32703, 32709, 32713, 32719, 32723, 32729, 32737, 32745, + 32753, 32759, 32762, 32768, 32772, 32778, 32781, 32784, 32790, 32794, + 32800, 32803, 32806, 32809, 32812, 32816, 32822, 32828, 32831, 32834, + 32838, 32843, 32848, 32855, 32860, 32867, 32874, 32883, 32890, 32899, + 32904, 32911, 32918, 32927, 32932, 32939, 32944, 32950, 32956, 32962, + 32968, 32974, 32980, 0, 0, 0, 0, 32986, 32990, 32993, 32996, 32999, + 33002, 33005, 33008, 33011, 33014, 33017, 33020, 33023, 33026, 33031, + 33036, 33041, 33044, 33049, 33054, 33059, 33064, 33071, 33076, 33081, + 33086, 33091, 33098, 33104, 33110, 33116, 33122, 33128, 33137, 33146, + 33152, 33158, 33166, 33174, 33183, 33192, 33200, 33208, 33217, 33226, 0, + 0, 0, 33234, 33239, 33244, 33249, 33253, 33257, 33261, 33266, 33270, + 33274, 33279, 33283, 33288, 33293, 33298, 33303, 33308, 33313, 33318, + 33322, 33327, 33331, 33335, 33340, 33345, 33350, 33354, 33358, 33362, + 33366, 33371, 33375, 33380, 33384, 33390, 33396, 33402, 33408, 33414, + 33420, 33426, 33432, 33438, 33443, 33448, 33455, 33463, 33468, 33473, + 33478, 33482, 33486, 33490, 33494, 33498, 33502, 33506, 33510, 33514, + 33518, 33523, 33528, 33533, 33539, 33545, 33549, 33555, 33559, 33565, + 33571, 33576, 33583, 33587, 33593, 33597, 33603, 33608, 33615, 33622, + 33627, 33634, 33639, 33644, 33648, 33654, 33658, 33664, 33670, 33676, + 33680, 33686, 33692, 33696, 33702, 33707, 33711, 33717, 33722, 33727, + 33732, 33737, 33741, 33745, 33750, 33755, 33762, 33768, 33773, 33780, + 33785, 33792, 33797, 33806, 33812, 33818, 33822, 0, 0, 0, 0, 0, 0, 0, 0, + 33826, 33835, 33842, 33849, 33856, 33860, 33865, 33870, 33875, 33880, + 33885, 33890, 33895, 33900, 33905, 33909, 33914, 33919, 33923, 33927, + 33932, 33937, 33942, 33947, 33952, 33957, 33961, 33966, 33971, 33976, + 33981, 33985, 33989, 33993, 33997, 34002, 34007, 34011, 34016, 34021, + 34025, 34031, 34037, 34043, 34048, 34053, 34059, 34064, 34070, 34075, + 34081, 34087, 34092, 34098, 34104, 34109, 34115, 34121, 34127, 34132, 0, + 0, 0, 34137, 34143, 34153, 34159, 34167, 34173, 34178, 34182, 34186, + 34190, 34194, 34198, 34202, 34206, 34210, 0, 0, 0, 34214, 34219, 34224, + 34229, 34236, 34242, 34248, 34254, 34260, 34266, 34272, 34278, 34284, + 34290, 34296, 34303, 34310, 34317, 34324, 34331, 34338, 34345, 34352, + 34359, 34366, 34373, 34380, 34387, 34394, 34401, 34408, 34415, 34422, + 34429, 34436, 34443, 34450, 34457, 34464, 34471, 34478, 34485, 34492, + 34499, 34507, 34515, 34523, 34529, 34535, 34541, 34549, 34558, 34565, + 34572, 34578, 34585, 34592, 34599, 34607, 34614, 0, 0, 0, 0, 0, 0, 0, + 34621, 34628, 34635, 34642, 34649, 34656, 34663, 34670, 34677, 34684, + 34691, 34698, 34705, 34712, 34719, 34726, 34733, 34740, 34747, 34754, + 34761, 34768, 34775, 34782, 34789, 34796, 34803, 34810, 34817, 34824, + 34831, 34838, 34845, 34852, 34859, 34866, 34873, 34880, 34887, 34894, + 34901, 34908, 34916, 0, 0, 34923, 34930, 34938, 34946, 34954, 34962, + 34970, 34978, 34988, 34998, 35008, 0, 0, 0, 0, 0, 0, 0, 0, 35018, 35023, + 35028, 35033, 35038, 35047, 35058, 35067, 35078, 35084, 35097, 35103, + 35110, 35117, 35122, 35129, 35136, 35147, 35156, 35163, 35170, 35179, + 35186, 35195, 35205, 35215, 35222, 35229, 35236, 35246, 35251, 35259, + 35265, 35273, 35282, 35287, 35294, 35300, 35305, 35310, 35315, 35321, + 35328, 0, 0, 0, 0, 0, 35336, 35341, 35347, 35353, 35361, 35367, 35373, + 35379, 35384, 35390, 35395, 35401, 35407, 35415, 35421, 35429, 35434, + 35440, 35446, 35453, 35461, 35467, 35473, 35480, 35487, 35493, 35500, + 35506, 35512, 35517, 35523, 35531, 35539, 35545, 35551, 35557, 35563, + 35571, 35575, 35581, 35587, 35593, 35599, 35605, 35611, 35615, 35620, + 35625, 35632, 35637, 35641, 35647, 35652, 35657, 35661, 35666, 35671, + 35675, 35680, 35685, 35692, 35696, 35701, 35706, 35710, 35715, 35719, + 35724, 35728, 35733, 35738, 35744, 35749, 35754, 35758, 35763, 35768, + 35774, 35779, 35784, 35789, 35794, 35799, 35803, 35808, 35815, 35822, + 35827, 35832, 35836, 35842, 35848, 35853, 35858, 35863, 35869, 35874, + 35880, 35885, 35891, 35897, 35903, 35910, 35917, 35924, 35931, 35938, + 35945, 35950, 35958, 35967, 35976, 35985, 35994, 36003, 36012, 36024, + 36033, 36042, 36051, 36057, 36062, 36069, 36077, 36085, 36092, 36099, + 36106, 36113, 36121, 36130, 36139, 36148, 36157, 36166, 36175, 36184, + 36193, 36202, 36211, 36220, 36229, 36238, 36247, 36255, 36264, 36275, + 36284, 36294, 36306, 36315, 36324, 36333, 36342, 36350, 36359, 36365, + 36370, 36378, 36383, 36390, 36395, 36404, 36410, 36416, 36423, 36428, + 36433, 36441, 36449, 36458, 36467, 36472, 36479, 36489, 36497, 36506, + 36512, 36518, 36523, 36530, 36535, 36544, 36549, 36554, 36559, 36566, + 36572, 36577, 36586, 36594, 36599, 36604, 36611, 36618, 36622, 36626, + 36629, 36632, 36635, 36638, 36641, 36644, 36651, 36654, 36657, 36662, + 36666, 36670, 36674, 36678, 36682, 36691, 36697, 36703, 36709, 36717, + 36725, 36731, 36737, 36744, 36750, 36755, 36761, 36768, 36774, 36781, + 36787, 36795, 36801, 36808, 36814, 36820, 36826, 36832, 36838, 36844, + 36855, 36865, 36871, 36877, 36887, 36893, 36901, 36909, 36917, 36922, + 36928, 36934, 36939, 0, 36947, 36951, 36958, 36965, 36970, 36979, 36987, + 36995, 37002, 37009, 37016, 37023, 37031, 37039, 37049, 37059, 37067, + 37075, 37083, 37091, 37100, 37109, 37117, 37125, 37134, 37143, 37154, + 37165, 37175, 37185, 37194, 37203, 37212, 37221, 37232, 37243, 37251, + 37259, 37267, 37275, 37283, 37291, 37299, 37307, 37315, 37323, 37331, + 37339, 37348, 37357, 37366, 37375, 37385, 37395, 37402, 37409, 37417, + 37425, 37434, 37443, 37451, 37459, 37471, 37483, 37492, 37501, 37510, + 37519, 37526, 37533, 37541, 37549, 37557, 37565, 37573, 37581, 37589, + 37597, 37606, 37615, 37624, 37633, 37642, 37651, 37661, 37671, 37681, + 37691, 37700, 37709, 37716, 37723, 37731, 37739, 37747, 37755, 37763, + 37771, 37783, 37795, 37804, 37813, 37821, 37829, 37837, 37845, 37856, + 37867, 37878, 37889, 37901, 37913, 37921, 37929, 37937, 37945, 37954, + 37963, 37972, 37981, 37989, 37997, 38005, 38013, 38021, 38029, 38038, + 38047, 38057, 38067, 38075, 38083, 38091, 38099, 38107, 38115, 38122, + 38129, 38137, 38145, 38153, 38161, 38169, 38177, 38185, 38193, 38201, + 38209, 38217, 38225, 38233, 38241, 38249, 38257, 38266, 38275, 38284, + 38292, 38301, 38310, 38319, 38328, 38338, 38347, 38354, 38359, 38366, + 38373, 38381, 38389, 38398, 38407, 38417, 38427, 38438, 38449, 38459, + 38469, 38479, 38489, 38498, 38507, 38517, 38527, 38538, 38549, 38559, + 38569, 38579, 38589, 38597, 38605, 38614, 38623, 38631, 38639, 38649, + 38659, 38670, 38681, 38693, 38705, 38716, 38727, 38738, 38749, 38758, + 38767, 38775, 38783, 38790, 38797, 38805, 38813, 38822, 38831, 38841, + 38851, 38862, 38873, 38883, 38893, 38903, 38913, 38922, 38931, 38941, + 38951, 38962, 38973, 38983, 38993, 39003, 39013, 39020, 39027, 39035, + 39043, 39052, 39061, 39071, 39081, 39092, 39103, 39113, 39123, 39133, + 39143, 39151, 39159, 39167, 39175, 39184, 39193, 39201, 39209, 39216, + 39223, 39230, 39237, 39245, 39253, 39261, 39269, 39280, 39291, 39302, + 39313, 39324, 39335, 39343, 39351, 39362, 39373, 39384, 39395, 39406, + 39417, 39425, 39433, 39444, 39455, 39466, 0, 0, 39477, 39485, 39493, + 39504, 39515, 39526, 0, 0, 39537, 39545, 39553, 39564, 39575, 39586, + 39597, 39608, 39619, 39627, 39635, 39646, 39657, 39668, 39679, 39690, + 39701, 39709, 39717, 39728, 39739, 39750, 39761, 39772, 39783, 39791, + 39799, 39810, 39821, 39832, 39843, 39854, 39865, 39873, 39881, 39892, + 39903, 39914, 0, 0, 39925, 39933, 39941, 39952, 39963, 39974, 0, 0, + 39985, 39993, 40001, 40012, 40023, 40034, 40045, 40056, 0, 40067, 0, + 40075, 0, 40086, 0, 40097, 40108, 40116, 40124, 40135, 40146, 40157, + 40168, 40179, 40190, 40198, 40206, 40217, 40228, 40239, 40250, 40261, + 40272, 40280, 40288, 40296, 40304, 40312, 40320, 40328, 40336, 40344, + 40352, 40360, 40368, 40376, 0, 0, 40384, 40395, 40406, 40420, 40434, + 40448, 40462, 40476, 40490, 40501, 40512, 40526, 40540, 40554, 40568, + 40582, 40596, 40607, 40618, 40632, 40646, 40660, 40674, 40688, 40702, + 40713, 40724, 40738, 40752, 40766, 40780, 40794, 40808, 40819, 40830, + 40844, 40858, 40872, 40886, 40900, 40914, 40925, 40936, 40950, 40964, + 40978, 40992, 41006, 41020, 41028, 41036, 41047, 41055, 0, 41066, 41074, + 41085, 41093, 41101, 41109, 41117, 41125, 41128, 41131, 41134, 41137, + 41143, 41154, 41162, 0, 41173, 41181, 41192, 41200, 41208, 41216, 41224, + 41232, 41238, 41244, 41250, 41258, 41266, 41277, 0, 0, 41288, 41296, + 41307, 41315, 41323, 41331, 0, 41339, 41345, 41351, 41357, 41365, 41373, + 41384, 41395, 41403, 41411, 41419, 41430, 41438, 41446, 41454, 41462, + 41470, 41476, 41482, 0, 0, 41485, 41496, 41504, 0, 41515, 41523, 41534, + 41542, 41550, 41558, 41566, 41574, 41577, 0, 41580, 41584, 41588, 41592, + 41596, 41600, 41604, 41608, 41612, 41616, 41620, 41624, 41630, 41636, + 41642, 41645, 41648, 41650, 41654, 41658, 41662, 41666, 41669, 41673, + 41677, 41683, 41689, 41696, 41703, 41708, 41713, 41719, 41725, 41727, + 41730, 41732, 41736, 41740, 41744, 41748, 41752, 41756, 41760, 41764, + 41768, 41774, 41778, 41782, 41788, 41793, 41800, 41802, 41805, 41809, + 41813, 41818, 41824, 41826, 41835, 41844, 41847, 41851, 41853, 41855, + 41857, 41860, 41866, 41868, 41872, 41875, 41882, 41889, 41893, 41898, + 41903, 41908, 41913, 41917, 41921, 41924, 41928, 41932, 41939, 41944, + 41948, 41952, 41957, 41961, 41965, 41970, 41975, 41979, 41983, 41987, + 41989, 41994, 41999, 42003, 42007, 42011, 42015, 0, 42019, 42023, 42027, + 42033, 42039, 42045, 42051, 42058, 42065, 42070, 42075, 42079, 0, 0, + 42085, 42088, 42091, 42094, 42097, 42100, 42103, 42107, 42111, 42116, + 42121, 42126, 42133, 42137, 42140, 42143, 42146, 42149, 42152, 42155, + 42158, 42161, 42164, 42168, 42172, 42177, 42182, 0, 42187, 42193, 42199, + 42205, 42212, 42219, 42226, 42233, 42239, 42246, 42253, 42260, 42267, 0, + 0, 0, 42274, 42277, 42280, 42283, 42288, 42291, 42294, 42297, 42300, + 42303, 42306, 42311, 42314, 42317, 42320, 42323, 42326, 42331, 42334, + 42337, 42340, 42343, 42346, 42351, 42354, 42357, 42362, 42367, 42371, + 42374, 42377, 42380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 42383, 42388, 42393, 42400, 42408, 42413, 42418, 42422, 42426, 42431, + 42438, 42445, 42450, 42456, 42461, 42466, 42471, 42478, 42483, 42488, + 42493, 42502, 42509, 42516, 42520, 42525, 42531, 42536, 42543, 42551, + 42559, 42563, 42567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42571, + 42575, 42583, 42588, 42592, 42597, 42601, 42605, 42609, 42611, 42615, + 42619, 42623, 42628, 42633, 42637, 42645, 42648, 42652, 42655, 42658, + 42664, 42669, 42672, 42678, 42682, 42687, 42692, 42695, 42699, 42703, + 42707, 42709, 42712, 42715, 42719, 42721, 42726, 42729, 42732, 42737, + 42742, 42748, 42751, 42754, 42758, 42763, 42766, 42769, 42772, 42776, + 42780, 42784, 42787, 42789, 42792, 42795, 42798, 42802, 42807, 42810, + 42815, 42820, 42825, 42830, 42836, 42841, 42845, 42850, 42855, 42861, + 42867, 42872, 42877, 42883, 42887, 42890, 42893, 42895, 42899, 42905, + 42911, 42917, 42923, 42929, 42935, 42941, 42947, 42953, 42960, 42966, + 42973, 42979, 42985, 42992, 42999, 43003, 43008, 43013, 43018, 43023, + 43028, 43033, 43038, 43043, 43048, 43054, 43060, 43066, 43072, 43079, + 43087, 43093, 43099, 43105, 43111, 43117, 43123, 43129, 43135, 43141, + 43147, 43154, 43161, 43168, 43175, 43183, 43192, 43199, 43210, 43217, + 43224, 43233, 43240, 43249, 43258, 43265, 43273, 43280, 43283, 0, 0, 0, + 0, 43286, 43288, 43291, 43293, 43296, 43299, 43302, 43306, 43310, 43315, + 43320, 43324, 43328, 43332, 43336, 43341, 43347, 43352, 43358, 43363, + 43368, 43373, 43379, 43384, 43390, 43396, 43400, 43404, 43409, 43414, + 43419, 43424, 43429, 43437, 43445, 43453, 43461, 43468, 43476, 43483, + 43490, 43498, 43510, 43516, 43522, 43529, 43536, 43544, 43552, 43559, + 43566, 43574, 43582, 43587, 43595, 43600, 43605, 43611, 43616, 43622, + 43629, 43636, 43641, 43647, 43652, 43655, 43659, 43662, 43666, 43670, + 43674, 43679, 43684, 43690, 43696, 43700, 43704, 43708, 43712, 43718, + 43724, 43728, 43733, 43737, 43742, 43747, 43752, 43755, 43759, 43762, + 43766, 43773, 43781, 43793, 43804, 43809, 43818, 43825, 43833, 43842, + 43846, 43852, 43860, 43864, 43869, 43874, 43880, 43886, 43892, 43899, + 43903, 43907, 43912, 43915, 43917, 43921, 43925, 43933, 43937, 43939, + 43941, 43945, 43953, 43958, 43964, 43974, 43981, 43986, 43990, 43994, + 43998, 44001, 44004, 44007, 44011, 44015, 44019, 44023, 44027, 44030, + 44034, 44038, 44041, 44043, 44046, 44048, 44052, 44056, 44058, 44064, + 44067, 44072, 44076, 44080, 44082, 44084, 44086, 44089, 44093, 44097, + 44101, 44105, 44109, 44115, 44121, 44123, 44125, 44127, 44129, 44132, + 44134, 44138, 44140, 44144, 44148, 44154, 44158, 44162, 44166, 44170, + 44174, 44180, 44184, 44194, 44204, 44208, 44214, 44221, 44225, 44229, + 44232, 44237, 44241, 44247, 44251, 44264, 44273, 44277, 44281, 44287, + 44291, 44294, 44296, 44299, 44303, 44307, 44314, 44318, 44322, 44326, + 44329, 44334, 44339, 44345, 44351, 44356, 44361, 44369, 44377, 44381, + 44385, 44387, 44392, 44396, 44400, 44408, 44416, 44423, 44430, 44439, + 44448, 44454, 44460, 44468, 44476, 44478, 44480, 44486, 44492, 44499, + 44506, 44512, 44518, 44522, 44526, 44533, 44540, 44547, 44554, 44564, + 44574, 44582, 44590, 44592, 44596, 44600, 44605, 44610, 44618, 44626, + 44629, 44632, 44635, 44638, 44641, 44646, 44650, 44655, 44660, 44663, + 44666, 44669, 44672, 44675, 44679, 44682, 44685, 44688, 44691, 44693, + 44695, 44697, 44699, 44707, 44715, 44721, 44725, 44731, 44741, 44747, + 44753, 44759, 44767, 44776, 44788, 44792, 44796, 44798, 44804, 44806, + 44808, 44810, 44812, 44818, 44821, 44827, 44833, 44837, 44841, 44845, + 44848, 44852, 44856, 44858, 44867, 44876, 44881, 44886, 44892, 44898, + 44904, 44907, 44910, 44913, 44916, 44918, 44923, 44928, 44933, 44939, + 44945, 44954, 44963, 44970, 44977, 44984, 44991, 45001, 45011, 45021, + 45031, 45041, 45051, 45060, 45069, 45078, 45087, 45095, 45107, 45118, + 45134, 45137, 45143, 45149, 45155, 45163, 45178, 45194, 45200, 45206, + 45213, 45219, 45228, 45235, 45249, 45264, 45269, 45275, 45283, 45286, + 45289, 45291, 45294, 45297, 45299, 45301, 45305, 45308, 45311, 45314, + 45317, 45322, 45327, 45332, 45337, 45342, 45345, 45347, 45349, 45351, + 45355, 45359, 45363, 45369, 45373, 45375, 45377, 45382, 45387, 45392, + 45397, 45402, 45407, 45409, 45411, 45421, 45425, 45433, 45442, 45444, + 45449, 45454, 45462, 45466, 45468, 45472, 45474, 45478, 45482, 45486, + 45488, 45490, 45492, 45499, 45508, 45517, 45526, 45535, 45544, 45553, + 45562, 45571, 45579, 45587, 45596, 45605, 45614, 45623, 45631, 45639, + 45648, 45657, 45666, 45676, 45685, 45695, 45704, 45714, 45723, 45733, + 45743, 45752, 45762, 45771, 45781, 45790, 45800, 45809, 45818, 45827, + 45836, 45845, 45855, 45864, 45873, 45882, 45892, 45901, 45910, 45919, + 45928, 45938, 45948, 45957, 45966, 45974, 45983, 45990, 45999, 46008, + 46019, 46028, 46038, 46048, 46055, 46062, 46069, 46078, 46087, 46096, + 46105, 46112, 46117, 46126, 46131, 46134, 46141, 46144, 46149, 46154, + 46157, 46160, 46168, 46171, 46176, 46179, 46187, 46192, 46200, 46203, + 46206, 46209, 46214, 46219, 46222, 46225, 46233, 46236, 46243, 46250, + 46254, 46258, 46263, 46268, 46274, 46279, 46285, 46291, 46296, 46302, + 46310, 46316, 46324, 46332, 46338, 46346, 46354, 46362, 46370, 46376, + 46384, 46392, 46400, 46404, 46410, 46424, 46438, 46442, 46446, 46450, + 46454, 46464, 46468, 46473, 46478, 46484, 46490, 46496, 46502, 46512, + 46522, 46530, 46541, 46552, 46560, 46571, 46582, 46590, 46601, 46612, + 46620, 46628, 46638, 46648, 46651, 46654, 46657, 46662, 46666, 46672, + 46679, 46686, 46694, 46701, 46705, 46709, 46713, 46717, 46719, 46723, + 46727, 46732, 46737, 46744, 46751, 46754, 46761, 46763, 46765, 46769, + 46773, 46778, 46784, 46790, 46796, 46802, 46811, 46820, 46829, 46833, + 46835, 46839, 46846, 46853, 46860, 46867, 46874, 46877, 46882, 46888, + 46891, 46896, 46901, 46906, 46911, 46915, 46922, 46929, 46936, 46943, + 46947, 46951, 46955, 46959, 46965, 46971, 46976, 46982, 46988, 46994, + 47000, 47008, 47015, 47022, 47029, 47036, 47042, 47048, 47057, 47061, + 47068, 47072, 47076, 47082, 47088, 47094, 47100, 47104, 47108, 47111, + 47114, 47118, 47125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 47132, 47135, 47139, 47143, 47149, 47155, 47161, + 47169, 47176, 47180, 47188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 47193, 47196, 47199, 47202, 47205, 47208, 47211, 47214, + 47217, 47220, 47224, 47228, 47232, 47236, 47240, 47244, 47248, 47252, + 47256, 47260, 47264, 47267, 47270, 47273, 47276, 47279, 47282, 47285, + 47288, 47291, 47295, 47299, 47303, 47307, 47311, 47315, 47319, 47323, + 47327, 47331, 47335, 47341, 47347, 47353, 47360, 47367, 47374, 47381, + 47388, 47395, 47402, 47409, 47416, 47423, 47430, 47437, 47444, 47451, + 47458, 47465, 47472, 47477, 47483, 47489, 47495, 47500, 47506, 47512, + 47518, 47523, 47529, 47535, 47540, 47546, 47552, 47557, 47563, 47569, + 47574, 47580, 47586, 47591, 47597, 47603, 47609, 47615, 47621, 47626, + 47632, 47638, 47644, 47649, 47655, 47661, 47667, 47672, 47678, 47684, + 47689, 47695, 47701, 47706, 47712, 47718, 47723, 47729, 47735, 47740, + 47746, 47752, 47758, 47764, 47770, 47775, 47781, 47787, 47793, 47798, + 47804, 47810, 47816, 47821, 47827, 47833, 47838, 47844, 47850, 47855, + 47861, 47867, 47872, 47878, 47884, 47889, 47895, 47901, 47907, 47913, + 47919, 47923, 47929, 47935, 47941, 47947, 47953, 47959, 47965, 47971, + 47977, 47983, 47987, 47991, 47995, 47999, 48003, 48007, 48011, 48015, + 48019, 48024, 48030, 48035, 48040, 48045, 48050, 48059, 48068, 48077, + 48086, 48095, 48104, 48113, 48122, 48129, 48137, 48145, 48152, 48159, + 48167, 48175, 48182, 48189, 48197, 48205, 48212, 48219, 48227, 48235, + 48242, 48249, 48257, 48266, 48275, 48283, 48292, 48301, 48308, 48315, + 48323, 48332, 48341, 48349, 48358, 48367, 48374, 48381, 48390, 48399, + 48408, 48417, 48426, 48435, 48442, 48449, 48458, 48467, 48476, 48485, + 48494, 48503, 48510, 48517, 48526, 48535, 48544, 48554, 48564, 48573, + 48583, 48593, 48603, 48613, 48623, 48633, 48642, 48651, 48658, 48666, + 48674, 48682, 48690, 48695, 48700, 48709, 48717, 48724, 48733, 48741, + 48748, 48757, 48765, 48772, 48781, 48789, 48796, 48805, 48813, 48820, + 48829, 48837, 48844, 48854, 48863, 48870, 48880, 48889, 48896, 48906, + 48915, 48922, 48931, 48940, 48949, 48958, 48972, 48986, 48993, 48998, + 49003, 49008, 49013, 49018, 49023, 49028, 49033, 49041, 49049, 49057, + 49065, 49070, 49077, 49084, 49091, 49096, 49104, 49111, 49119, 49123, + 49130, 49136, 49143, 49147, 49153, 49159, 49165, 49169, 49172, 49176, + 49180, 49187, 49193, 49199, 49205, 49211, 49225, 49235, 49249, 49263, + 49269, 49279, 49293, 49296, 49299, 49306, 49314, 49320, 49325, 49333, + 49345, 49357, 49365, 49369, 49373, 49376, 49379, 49383, 49387, 49390, + 49393, 49398, 49403, 49409, 49415, 49420, 49425, 49431, 49437, 49442, + 49447, 49452, 49457, 49463, 49469, 49474, 49479, 49485, 49491, 49496, + 49501, 49504, 49507, 49516, 49518, 49520, 49523, 49527, 49533, 49535, + 49538, 49545, 49552, 49560, 49568, 49578, 49592, 49597, 49602, 49606, + 49611, 49619, 49627, 49636, 49645, 49654, 49663, 49668, 49673, 49679, + 49685, 49691, 49697, 49700, 49706, 49712, 49722, 49732, 49740, 49748, + 49757, 49766, 49770, 49778, 49786, 49794, 49802, 49811, 49820, 49829, + 49838, 49843, 49848, 49853, 49858, 49863, 49869, 49875, 49880, 49886, + 49888, 49890, 49892, 49894, 49897, 49900, 49902, 49904, 49906, 49910, + 49914, 49916, 49918, 49921, 49924, 49928, 49934, 49940, 49942, 49949, + 49953, 49958, 49963, 49965, 49975, 49981, 49987, 49993, 49999, 50005, + 50011, 50016, 50019, 50022, 50025, 50027, 50029, 50033, 50037, 50042, + 50047, 50052, 50055, 50059, 50064, 50067, 50071, 50076, 50081, 50086, + 50091, 50096, 50101, 50106, 50111, 50116, 50121, 50126, 50131, 50137, + 50143, 50149, 50151, 50154, 50156, 50159, 50161, 50163, 50165, 50167, + 50169, 50171, 50173, 50175, 50177, 50179, 50181, 50183, 50185, 50187, + 50189, 50191, 50193, 50198, 50203, 50208, 50213, 50218, 50223, 50228, + 50233, 50238, 50243, 50248, 50253, 50258, 50263, 50268, 50273, 50278, + 50283, 50288, 50293, 50297, 50301, 50305, 50311, 50317, 50322, 50327, + 50332, 50338, 50344, 50349, 50357, 50365, 50373, 50381, 50389, 50397, + 50405, 50413, 50419, 50424, 50429, 50434, 50437, 50441, 50445, 50449, + 50453, 50457, 50461, 50468, 50475, 50483, 50491, 50496, 50501, 50508, + 50515, 50522, 50529, 50532, 50535, 50540, 50542, 50546, 50551, 50553, + 50555, 50557, 50559, 50564, 50567, 50569, 50574, 50581, 50588, 50591, + 50595, 50600, 50605, 50613, 50619, 50625, 50637, 50644, 50652, 50657, + 50662, 50668, 50671, 50674, 50679, 50681, 50685, 50687, 50689, 50691, + 50693, 50695, 50697, 50702, 50704, 50706, 50708, 50710, 50714, 50716, + 50719, 50724, 50729, 50734, 50739, 50745, 50751, 50753, 50756, 50763, + 50769, 50775, 50782, 50786, 50790, 50792, 50794, 50798, 50804, 50809, + 50811, 50815, 50824, 50832, 50840, 50846, 50852, 50857, 50863, 50868, + 50871, 50885, 50888, 50893, 50898, 50904, 50915, 50917, 50923, 50929, + 50933, 50940, 50944, 50946, 50948, 50952, 50958, 50963, 50969, 50971, + 50977, 50979, 50985, 50987, 50989, 50994, 50996, 51000, 51005, 51007, + 51012, 51017, 51021, 51028, 51038, 51043, 51049, 51052, 51058, 51061, + 51066, 51071, 51075, 51077, 51079, 51083, 51087, 51091, 51095, 51100, + 51102, 51107, 51110, 51113, 51116, 51120, 51124, 51129, 51133, 51138, + 51143, 51147, 51152, 51158, 51161, 51167, 51172, 51176, 51181, 51187, + 51193, 51200, 51206, 51213, 51220, 51222, 51229, 51233, 51239, 51245, + 51250, 51256, 51260, 51265, 51268, 51273, 51279, 51286, 51294, 51301, + 51310, 51320, 51327, 51333, 51337, 51344, 51349, 51358, 51361, 51364, + 51373, 51383, 51390, 51392, 51398, 51403, 51405, 51408, 51412, 51420, + 51429, 51432, 51437, 51443, 51451, 51459, 51467, 51475, 51481, 51487, + 51493, 51501, 51506, 51509, 51513, 51516, 51527, 51537, 51547, 51556, + 51567, 51577, 51586, 51592, 51600, 51604, 51612, 51616, 51624, 51631, + 51638, 51647, 51656, 51666, 51676, 51686, 51696, 51705, 51714, 51724, + 51734, 51743, 51752, 51759, 51766, 51773, 51780, 51787, 51794, 51801, + 51808, 51815, 51823, 51829, 51835, 51841, 51847, 51853, 51859, 51865, + 51871, 51877, 51884, 51892, 51900, 51908, 51916, 51924, 51932, 51940, + 51948, 51956, 51965, 51970, 51973, 51977, 51981, 51987, 51990, 51995, + 52001, 52006, 52010, 52015, 52021, 52028, 52031, 52038, 52045, 52049, + 52058, 52067, 52072, 52078, 52083, 52088, 52095, 52102, 52110, 52118, + 52127, 52131, 52140, 52145, 52149, 52156, 52160, 52166, 52174, 52179, + 52186, 52190, 52195, 52199, 52204, 52208, 52213, 52218, 52227, 52229, + 52232, 52235, 52242, 52249, 52255, 52263, 52269, 52276, 52281, 52284, + 52289, 52294, 52299, 52307, 52311, 52318, 52326, 52334, 52339, 52344, + 52350, 52355, 52360, 52366, 52371, 52374, 52378, 52382, 52389, 52399, + 52404, 52413, 52422, 52428, 52434, 52439, 52444, 52449, 52454, 52460, + 52466, 52474, 52482, 52488, 52494, 52499, 52504, 52511, 52518, 52524, + 52527, 52530, 52534, 52538, 52542, 52547, 52553, 52559, 52566, 52573, + 52578, 52582, 52586, 52590, 52594, 52598, 52602, 52606, 52610, 52614, + 52618, 52622, 52626, 52630, 52634, 52638, 52642, 52646, 52650, 52654, + 52658, 52662, 52666, 52670, 52674, 52678, 52682, 52686, 52690, 52694, + 52698, 52702, 52706, 52710, 52714, 52718, 52722, 52726, 52730, 52734, + 52738, 52742, 52746, 52750, 52754, 52758, 52762, 52766, 52770, 52774, + 52778, 52782, 52786, 52790, 52794, 52798, 52802, 52806, 52810, 52814, + 52818, 52822, 52826, 52830, 52834, 52838, 52842, 52846, 52850, 52854, + 52858, 52862, 52866, 52870, 52874, 52878, 52882, 52886, 52890, 52894, + 52898, 52902, 52906, 52910, 52914, 52918, 52922, 52926, 52930, 52934, + 52938, 52942, 52946, 52950, 52954, 52958, 52962, 52966, 52970, 52974, + 52978, 52982, 52986, 52990, 52994, 52998, 53002, 53006, 53010, 53014, + 53018, 53022, 53026, 53030, 53034, 53038, 53042, 53046, 53050, 53054, + 53058, 53062, 53066, 53070, 53074, 53078, 53082, 53086, 53090, 53094, + 53098, 53102, 53106, 53110, 53114, 53118, 53122, 53126, 53130, 53134, + 53138, 53142, 53146, 53150, 53154, 53158, 53162, 53166, 53170, 53174, + 53178, 53182, 53186, 53190, 53194, 53198, 53202, 53206, 53210, 53214, + 53218, 53222, 53226, 53230, 53234, 53238, 53242, 53246, 53250, 53254, + 53258, 53262, 53266, 53270, 53274, 53278, 53282, 53286, 53290, 53294, + 53298, 53302, 53306, 53310, 53314, 53318, 53322, 53326, 53330, 53334, + 53338, 53342, 53346, 53350, 53354, 53358, 53362, 53366, 53370, 53374, + 53378, 53382, 53386, 53390, 53394, 53398, 53402, 53406, 53410, 53414, + 53418, 53422, 53426, 53430, 53434, 53438, 53442, 53446, 53450, 53454, + 53458, 53462, 53466, 53470, 53474, 53478, 53482, 53486, 53490, 53494, + 53498, 53502, 53506, 53510, 53514, 53518, 53522, 53526, 53530, 53534, + 53538, 53542, 53546, 53550, 53554, 53558, 53562, 53566, 53570, 53574, + 53578, 53582, 53586, 53590, 53594, 53598, 53602, 53609, 53617, 53623, + 53629, 53636, 53643, 53649, 53655, 53662, 53669, 53674, 53679, 53684, + 53689, 53695, 53701, 53709, 53716, 53722, 53728, 53736, 53745, 53752, + 53762, 53773, 53776, 53779, 53783, 53787, 53794, 53801, 53812, 53823, + 53832, 53841, 53847, 53853, 53860, 53867, 53876, 53886, 53897, 53907, + 53917, 53927, 53938, 53949, 53959, 53970, 53980, 53990, 53999, 54009, + 54019, 54030, 54041, 54048, 54055, 54062, 54069, 54079, 54089, 54097, + 54105, 54112, 54119, 54126, 54133, 54140, 54145, 54150, 54156, 54164, + 54174, 54182, 54190, 54198, 54206, 54214, 54222, 54230, 54238, 54247, + 54256, 54266, 54276, 54285, 54294, 54304, 54314, 54323, 54332, 54342, + 54352, 54361, 54370, 54380, 54390, 54404, 54421, 54435, 54452, 54466, + 54480, 54494, 54508, 54518, 54529, 54539, 54550, 54567, 54584, 54592, + 54598, 54605, 54612, 54619, 54626, 54631, 54637, 54642, 54647, 54653, + 54658, 54663, 54668, 54673, 54678, 54685, 54691, 54699, 54704, 54709, + 54713, 54717, 54725, 54733, 54741, 54749, 54756, 54763, 54776, 54789, + 54802, 54815, 54823, 54831, 54837, 54843, 54850, 54857, 54864, 54871, + 54875, 54880, 54888, 54896, 54904, 54911, 54915, 54923, 54931, 54934, + 54938, 54943, 54950, 54958, 54966, 54985, 55004, 55023, 55042, 55061, + 55080, 55099, 55118, 55124, 55131, 55140, 55148, 55156, 55162, 55165, + 55168, 55173, 55176, 55196, 55203, 55209, 55215, 55219, 55222, 55225, + 55228, 55240, 55254, 55261, 55268, 55271, 55275, 55278, 55283, 55288, + 55293, 55299, 55308, 55315, 55322, 55330, 55337, 55344, 55347, 55353, + 55359, 55362, 55365, 55370, 55375, 55381, 55387, 55391, 55396, 55403, + 55407, 55413, 55417, 55421, 55429, 55441, 55450, 55454, 55456, 55465, + 55474, 55480, 55483, 55489, 55495, 55500, 55505, 55510, 55515, 55520, + 55525, 55527, 55533, 55538, 55546, 55550, 55556, 55559, 55563, 55570, + 55577, 55579, 55581, 55587, 55593, 55599, 55608, 55617, 55624, 55631, + 55637, 55644, 55649, 55654, 55659, 55665, 55671, 55676, 55683, 55687, + 55691, 55704, 55717, 55729, 55738, 55744, 55751, 55756, 55761, 55766, + 55771, 55776, 55778, 55785, 55793, 55801, 55809, 55816, 55824, 55830, + 55835, 55841, 55847, 55853, 55860, 55866, 55874, 55882, 55890, 55898, + 55906, 55912, 55918, 55927, 55931, 55940, 55949, 55958, 55966, 55970, + 55976, 55983, 55990, 55994, 56000, 56008, 56014, 56019, 56025, 56030, + 56035, 56042, 56049, 56054, 56059, 56067, 56075, 56085, 56095, 56102, + 56109, 56113, 56117, 56129, 56135, 56142, 56147, 56152, 56159, 56166, + 56172, 56178, 56188, 56195, 56203, 56211, 56220, 56227, 56233, 56240, + 56246, 56254, 56262, 56270, 56278, 56284, 56289, 56299, 56310, 56317, + 56326, 56332, 56337, 56342, 56352, 56359, 56365, 56371, 56379, 56384, + 56391, 56398, 56411, 56419, 56426, 56433, 56440, 56447, 56455, 56463, + 56476, 56489, 56501, 56513, 56527, 56541, 56547, 56553, 56562, 56571, + 56578, 56585, 56594, 56603, 56612, 56621, 56629, 56637, 56647, 56657, + 56671, 56685, 56694, 56703, 56716, 56729, 56738, 56747, 56758, 56769, + 56775, 56781, 56790, 56799, 56804, 56809, 56817, 56823, 56829, 56837, + 56845, 56858, 56871, 56875, 56879, 56887, 56895, 56902, 56910, 56918, + 56927, 56936, 56942, 56948, 56955, 56962, 56969, 56976, 56985, 56994, + 56997, 57000, 57005, 57010, 57016, 57022, 57029, 57036, 57047, 57058, + 57065, 57072, 57080, 57088, 57096, 57104, 57112, 57120, 57126, 57132, + 57136, 57140, 57148, 57156, 57161, 57166, 57171, 57176, 57182, 57196, + 57203, 57210, 57214, 57216, 57218, 57223, 57228, 57233, 57238, 57246, + 57253, 57260, 57268, 57280, 57288, 57296, 57307, 57311, 57315, 57321, + 57329, 57342, 57349, 57356, 57363, 57369, 57376, 57385, 57394, 57400, + 57406, 57412, 57422, 57432, 57440, 57449, 57454, 57457, 57462, 57467, + 57472, 57478, 57484, 57488, 57491, 57495, 57499, 57504, 57509, 57515, + 57521, 57525, 57529, 57536, 57543, 57550, 57557, 57564, 57571, 57581, + 57591, 57598, 57605, 57613, 57621, 57625, 57630, 57635, 57641, 57647, + 57650, 57653, 57656, 57659, 57664, 57669, 57674, 57679, 57684, 57689, + 57693, 57697, 57701, 57706, 57711, 57715, 57719, 57725, 57729, 57735, + 57740, 57747, 57755, 57762, 57770, 57777, 57785, 57794, 57801, 57811, + 57822, 57828, 57837, 57843, 57852, 57861, 57867, 57873, 57877, 57881, + 57890, 57899, 57906, 57913, 57922, 57931, 57938, 57944, 57951, 57956, + 57960, 57964, 57969, 57974, 57979, 57987, 57995, 57998, 58002, 58011, + 58021, 58030, 58040, 58052, 58066, 58070, 58075, 58079, 58084, 58089, + 58094, 58100, 58106, 58113, 58120, 58126, 58133, 58139, 58146, 58154, + 58162, 58169, 58177, 58184, 0, 0, 58192, 58201, 58210, 58220, 58230, + 58239, 58249, 58258, 58268, 58274, 58279, 58288, 58300, 58309, 58321, + 58328, 58336, 58343, 58351, 58356, 58362, 58367, 58373, 58381, 58390, + 58398, 58407, 58411, 58415, 58419, 58423, 58433, 0, 0, 58436, 58445, + 58455, 58464, 58474, 58480, 58487, 58493, 58500, 58511, 58522, 58533, + 58544, 58554, 58564, 58574, 58584, 58592, 58600, 58608, 58616, 58624, + 58632, 58640, 58648, 58654, 58660, 58666, 58672, 58678, 58684, 58690, + 58696, 58708, 58718, 58723, 58730, 58735, 58742, 58745, 58749, 58753, + 58758, 58762, 58767, 58770, 58779, 58788, 58797, 58806, 58811, 58817, + 58823, 58831, 58841, 58848, 58857, 58862, 58865, 58868, 58873, 58878, + 58883, 58888, 58890, 58892, 58894, 58896, 58898, 58900, 58905, 58912, + 58919, 58921, 58923, 58925, 58927, 58929, 58931, 58933, 58935, 58940, + 58945, 58952, 58959, 58968, 58978, 58987, 58997, 59002, 59007, 59009, + 59016, 59023, 59030, 59037, 59044, 59051, 59058, 59061, 59064, 59067, + 59070, 59075, 59080, 59085, 59090, 59095, 59100, 59105, 59110, 59115, + 59120, 59125, 59130, 59136, 59140, 59145, 59150, 59155, 59160, 59165, + 59170, 59175, 59180, 59185, 59190, 59195, 59200, 59205, 59210, 59215, + 59220, 59225, 59230, 59235, 59240, 59245, 59250, 59256, 59261, 59267, + 59276, 59281, 59289, 59296, 59305, 59310, 59315, 59320, 59326, 0, 59333, + 59338, 59343, 59348, 59353, 59358, 59363, 59368, 59373, 59378, 59383, + 59389, 59393, 59398, 59403, 59408, 59413, 59418, 59423, 59428, 59433, + 59438, 59443, 59448, 59453, 59458, 59463, 59468, 59473, 59478, 59483, + 59488, 59493, 59498, 59503, 59509, 59514, 59520, 59529, 59534, 59542, + 59549, 59558, 59563, 59568, 59573, 59579, 0, 59586, 59594, 59602, 59611, + 59618, 59626, 59632, 59641, 59649, 59657, 59665, 59673, 59681, 59689, + 59694, 59701, 59706, 59712, 59720, 59727, 59734, 59742, 59748, 59754, + 59761, 59769, 59778, 59788, 59794, 59801, 59806, 59816, 59826, 59831, + 59836, 59841, 59846, 59851, 59856, 59861, 59866, 59871, 59876, 59881, + 59886, 59891, 59896, 59901, 59906, 59911, 59916, 59921, 59926, 59931, + 59936, 59941, 59946, 59951, 59956, 59961, 59966, 59971, 59976, 59980, + 59984, 59989, 59994, 59999, 60004, 60009, 60014, 60019, 60024, 60029, + 60034, 60039, 60044, 60049, 60054, 60059, 60064, 60069, 60074, 60081, + 60088, 60095, 60102, 60109, 60116, 60123, 60130, 60137, 60144, 60151, + 60158, 60165, 60172, 60177, 60182, 60189, 60196, 60203, 60210, 60217, + 60224, 60231, 60238, 60245, 60252, 60259, 60266, 60272, 60278, 60284, + 60290, 60297, 60304, 60311, 60318, 60325, 60332, 60339, 60346, 60353, + 60360, 60368, 60376, 60384, 60392, 60400, 60408, 60416, 60424, 60428, + 60434, 60440, 60444, 60450, 60456, 60462, 60469, 60476, 60483, 60490, + 60495, 60501, 60507, 60514, 0, 0, 0, 0, 0, 60521, 60529, 60538, 60547, + 60555, 60560, 60565, 60570, 60575, 60580, 60585, 60590, 60595, 60600, + 60605, 60610, 60615, 60620, 60625, 60630, 60635, 60640, 60645, 60650, + 60655, 60660, 60665, 60670, 60675, 60680, 60685, 60690, 60695, 60700, + 60705, 60710, 60715, 60720, 60725, 60730, 60735, 60740, 60745, 60750, + 60755, 0, 60760, 0, 0, 0, 0, 0, 60765, 0, 0, 60770, 60774, 60779, 60784, + 60789, 60794, 60803, 60808, 60813, 60818, 60823, 60828, 60833, 60838, + 60843, 60850, 60855, 60860, 60869, 60876, 60881, 60886, 60891, 60898, + 60903, 60910, 60915, 60920, 60927, 60934, 60939, 60944, 60949, 60956, + 60963, 60968, 60973, 60978, 60983, 60988, 60995, 61002, 61007, 61012, + 61017, 61022, 61027, 61032, 61037, 61042, 61047, 61052, 61057, 61064, + 61069, 61074, 0, 0, 0, 0, 0, 0, 0, 61079, 61086, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 61091, 61096, 61100, 61104, 61108, 61112, 61116, 61120, + 61124, 61128, 61132, 61136, 61142, 61146, 61150, 61154, 61158, 61162, + 61166, 61170, 61174, 61178, 61182, 61186, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 61190, 61194, 61198, 61202, 61206, 61210, 61214, 0, 61218, 61222, 61226, + 61230, 61234, 61238, 61242, 0, 61246, 61250, 61254, 61258, 61262, 61266, + 61270, 0, 61274, 61278, 61282, 61286, 61290, 61294, 61298, 0, 61302, + 61306, 61310, 61314, 61318, 61322, 61326, 0, 61330, 61334, 61338, 61342, + 61346, 61350, 61354, 0, 61358, 61362, 61366, 61370, 61374, 61378, 61382, + 0, 61386, 61390, 61394, 61398, 61402, 61406, 61410, 0, 61414, 61419, + 61424, 61429, 61434, 61439, 61444, 61448, 61453, 61458, 61463, 61467, + 61472, 61477, 61482, 61487, 61491, 61496, 61501, 61506, 61511, 61516, + 61521, 61525, 61530, 61535, 61542, 61547, 61552, 61558, 61565, 61572, + 61581, 61588, 61597, 61601, 61605, 61611, 61617, 61623, 61631, 61637, + 61641, 61645, 61649, 61655, 61661, 61665, 61667, 61671, 61677, 61679, + 61683, 61687, 61691, 61697, 61702, 61706, 61710, 61715, 61721, 61726, + 61731, 61736, 61741, 61748, 61755, 61760, 61765, 61770, 61775, 61780, + 61785, 61789, 61793, 61801, 61809, 61815, 61819, 61824, 61827, 61831, + 61838, 61841, 61845, 61849, 61852, 61858, 61864, 61867, 61873, 61877, + 61881, 61887, 61892, 61897, 61899, 61902, 61906, 61912, 61918, 61922, + 61927, 61936, 61939, 61945, 61950, 61954, 61958, 61962, 61965, 61970, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 61976, 61980, 61984, 61989, 61994, 61999, 62003, 62007, 62011, 62016, + 62021, 62025, 62029, 62033, 62037, 62042, 62047, 62052, 62057, 62061, + 62065, 62070, 62075, 62080, 62085, 62089, 0, 62093, 62097, 62101, 62105, + 62109, 62113, 62117, 62122, 62127, 62131, 62136, 62141, 62150, 62154, + 62158, 62162, 62169, 62173, 62178, 62183, 62187, 62191, 62197, 62202, + 62207, 62212, 62217, 62221, 62225, 62229, 62233, 62237, 62242, 62247, + 62251, 62255, 62260, 62265, 62270, 62274, 62278, 62283, 62288, 62294, + 62300, 62304, 62310, 62316, 62320, 62326, 62332, 62337, 62342, 62346, + 62352, 62356, 62360, 62366, 62372, 62377, 62382, 62386, 62390, 62398, + 62404, 62410, 62416, 62421, 62426, 62431, 62437, 62441, 62447, 62451, + 62455, 62461, 62467, 62473, 62479, 62485, 62491, 62497, 62503, 62509, + 62515, 62521, 62527, 62531, 62537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62543, 62546, 62550, 62554, 62558, 62562, 62565, 62568, 62572, 62576, + 62580, 62584, 62587, 62592, 62596, 62600, 62604, 62609, 62613, 62617, + 62621, 62625, 62631, 62637, 62641, 62645, 62649, 62653, 62657, 62661, + 62665, 62669, 62673, 62677, 62681, 62687, 62691, 62695, 62699, 62703, + 62707, 62711, 62715, 62719, 62723, 62727, 62731, 62735, 62739, 62743, + 62747, 62751, 62757, 62763, 62768, 62773, 62777, 62781, 62785, 62789, + 62793, 62797, 62801, 62805, 62809, 62813, 62817, 62821, 62825, 62829, + 62833, 62837, 62841, 62845, 62849, 62853, 62857, 62861, 62865, 62869, + 62875, 62879, 62883, 62887, 62891, 62895, 62899, 62903, 62907, 62912, + 62919, 62923, 62927, 62931, 62935, 62939, 62943, 62947, 62951, 62955, + 62959, 62963, 62967, 62974, 62978, 62984, 62988, 62992, 62996, 63000, + 63004, 63007, 63011, 63015, 63019, 63023, 63027, 63031, 63035, 63039, + 63043, 63047, 63051, 63055, 63059, 63063, 63067, 63071, 63075, 63079, + 63083, 63087, 63091, 63095, 63099, 63103, 63107, 63111, 63115, 63119, + 63123, 63127, 63131, 63135, 63141, 63145, 63149, 63153, 63157, 63161, + 63165, 63169, 63173, 63177, 63181, 63185, 63189, 63193, 63197, 63201, + 63205, 63209, 63213, 63217, 63221, 63225, 63229, 63233, 63237, 63241, + 63245, 63249, 63257, 63261, 63265, 63269, 63273, 63277, 63283, 63287, + 63291, 63295, 63299, 63303, 63307, 63311, 63315, 63319, 63323, 63327, + 63331, 63335, 63341, 63345, 63349, 63353, 63357, 63361, 63365, 63369, + 63373, 63377, 63381, 63385, 63389, 63393, 63397, 63401, 63405, 63409, + 63413, 63417, 63421, 63425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63429, 63438, 63446, 63457, 63467, + 63475, 63484, 63493, 63503, 63515, 63527, 63539, 0, 0, 0, 0, 63545, + 63548, 63551, 63556, 63559, 63566, 63570, 63574, 63578, 63582, 63586, + 63591, 63596, 63600, 63604, 63609, 63614, 63619, 63624, 63627, 63630, + 63636, 63642, 63647, 63652, 63659, 63666, 63670, 63674, 63678, 63686, + 63692, 63699, 63704, 63709, 63714, 63719, 63724, 63729, 63734, 63739, + 63744, 63749, 63754, 63759, 63764, 63769, 63775, 63780, 63784, 63790, + 63801, 63811, 63826, 63836, 63840, 63850, 63856, 63862, 63868, 63873, + 63876, 63881, 63885, 0, 63891, 63895, 63898, 63902, 63905, 63909, 63912, + 63916, 63919, 63923, 63926, 63929, 63933, 63937, 63941, 63945, 63949, + 63953, 63957, 63961, 63965, 63968, 63972, 63976, 63980, 63984, 63988, + 63992, 63996, 64000, 64004, 64007, 64011, 64015, 64019, 64024, 64028, + 64032, 64036, 64040, 64043, 64047, 64050, 64054, 64058, 64062, 64066, + 64069, 64073, 64076, 64080, 64084, 64088, 64092, 64096, 64100, 64104, + 64108, 64112, 64116, 64120, 64124, 64127, 64131, 64135, 64139, 64143, + 64147, 64150, 64155, 64159, 64164, 64168, 64171, 64175, 64179, 64183, + 64187, 64192, 64196, 64200, 64204, 64208, 64212, 64216, 64220, 0, 0, + 64225, 64233, 64241, 64248, 64255, 64259, 64265, 64270, 64275, 64279, + 64282, 64286, 64289, 64293, 64296, 64300, 64303, 64307, 64310, 64313, + 64317, 64321, 64325, 64329, 64333, 64337, 64341, 64345, 64349, 64352, + 64356, 64360, 64364, 64368, 64372, 64376, 64380, 64384, 64388, 64391, + 64395, 64399, 64403, 64408, 64412, 64416, 64420, 64424, 64427, 64431, + 64434, 64438, 64442, 64446, 64450, 64453, 64457, 64460, 64464, 64468, + 64472, 64476, 64480, 64484, 64488, 64492, 64496, 64500, 64504, 64508, + 64511, 64515, 64519, 64523, 64527, 64531, 64534, 64539, 64543, 64548, + 64552, 64555, 64559, 64563, 64567, 64571, 64576, 64580, 64584, 64588, + 64592, 64596, 64600, 64604, 64609, 64613, 64617, 64621, 64625, 64629, + 64636, 64640, 64646, 0, 0, 0, 0, 0, 64651, 64656, 64661, 64666, 64671, + 64676, 64681, 64686, 64690, 64695, 64700, 64705, 64710, 64715, 64720, + 64725, 64730, 64735, 64739, 64744, 64749, 64754, 64758, 64762, 64766, + 64771, 64776, 64781, 64786, 64791, 64796, 64801, 64806, 64811, 64816, + 64820, 64824, 64829, 64834, 64839, 64844, 64849, 64856, 0, 64861, 64865, + 64869, 64873, 64877, 64881, 64885, 64889, 64893, 64897, 64901, 64905, + 64909, 64913, 64917, 64921, 64925, 64929, 64933, 64937, 64941, 64945, + 64949, 64953, 64957, 64961, 64965, 64969, 64973, 64977, 64981, 64984, + 64988, 64991, 64995, 64999, 65002, 65006, 65010, 65013, 65017, 65021, + 65025, 65029, 65032, 65036, 65040, 65044, 65048, 65052, 65056, 65059, + 65062, 65066, 65070, 65074, 65078, 65082, 65086, 65090, 65094, 65098, + 65102, 65106, 65110, 65114, 65118, 65122, 65126, 65130, 65134, 65138, + 65142, 65146, 65150, 65154, 65158, 65162, 65166, 65170, 65174, 65178, + 65182, 65186, 65190, 65194, 65198, 65202, 65206, 65210, 65214, 65218, + 65222, 65226, 0, 65230, 65236, 65242, 65247, 65252, 65257, 65263, 65269, + 65274, 65280, 65286, 65292, 65298, 65304, 65310, 65316, 65322, 65327, + 65332, 65337, 65342, 65347, 65352, 65357, 65362, 65367, 65372, 65377, + 65382, 65387, 65392, 65397, 65402, 65407, 65412, 65417, 65422, 65428, + 65434, 65440, 65446, 65451, 65456, 0, 0, 0, 0, 0, 65461, 65466, 65471, + 65476, 65481, 65486, 65491, 65496, 65501, 65506, 65511, 65516, 65521, + 65526, 65531, 65536, 65541, 65546, 65551, 65556, 65561, 65566, 65571, + 65576, 65581, 65586, 65591, 65596, 65601, 65606, 65611, 65616, 65621, + 65626, 65631, 65636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65641, 65646, + 65651, 65656, 65660, 65665, 65669, 65674, 65679, 65684, 65689, 65694, + 65698, 65703, 65708, 65713, 65718, 65722, 65726, 65730, 65734, 65738, + 65742, 65746, 65750, 65754, 65758, 65762, 65766, 65770, 65774, 65779, + 65784, 65789, 65794, 65799, 65804, 65809, 65814, 65819, 65824, 65829, + 65834, 65839, 65844, 65849, 65855, 0, 65862, 65866, 65870, 65874, 65878, + 65882, 65886, 65890, 65894, 65898, 65903, 65908, 65913, 65918, 65923, + 65928, 65933, 65938, 65943, 65948, 65953, 65958, 65963, 65968, 65973, + 65978, 65983, 65988, 65993, 65998, 66003, 66008, 66013, 66018, 66023, + 66028, 66033, 66038, 66043, 66048, 66053, 66062, 66071, 66080, 66089, + 66098, 66107, 66116, 66125, 66128, 66133, 66138, 66143, 66148, 66153, + 66158, 66163, 66168, 66173, 66177, 66182, 66187, 66192, 66197, 66202, + 66206, 66210, 66214, 66218, 66222, 66226, 66230, 66234, 66238, 66242, + 66246, 66250, 66254, 66258, 66263, 66268, 66273, 66278, 66283, 66288, + 66293, 66298, 66303, 66308, 66313, 66318, 66323, 66328, 66334, 66340, + 66345, 66350, 66354, 66358, 66362, 66366, 66370, 66374, 66378, 66382, + 66386, 66391, 66396, 66401, 66406, 66411, 66416, 66421, 66426, 66431, + 66436, 66441, 66446, 66451, 66456, 66461, 66466, 66471, 66476, 66481, + 66486, 66491, 66496, 66501, 66506, 66511, 66516, 66521, 66526, 66531, + 66536, 66541, 66546, 66551, 66556, 66561, 66566, 66571, 66576, 66581, + 66586, 66591, 66596, 66601, 66606, 66610, 66615, 66620, 66625, 66630, + 66635, 66640, 66645, 66650, 66655, 66659, 66666, 66673, 66680, 66687, + 66694, 66701, 66708, 66715, 66722, 66729, 66736, 66743, 66746, 66749, + 66752, 66757, 66760, 66763, 66766, 66769, 66772, 66775, 66779, 66783, + 66787, 66791, 66794, 66798, 66802, 66806, 66810, 66813, 66817, 66821, + 66825, 66828, 66831, 66835, 66839, 66843, 66847, 66850, 66854, 66858, + 66862, 66866, 66869, 66873, 66877, 66881, 66885, 66888, 66892, 66896, + 66899, 66903, 66907, 66911, 66915, 66919, 66923, 66927, 66931, 66938, + 66941, 66944, 66947, 66950, 66953, 66956, 66959, 66962, 66965, 66968, + 66971, 66974, 66977, 66980, 66983, 66986, 66989, 66992, 66995, 66998, + 67001, 67004, 67007, 67010, 67013, 67016, 67019, 67022, 67025, 67028, + 67031, 67034, 67037, 67040, 67043, 67046, 67049, 67052, 67055, 67058, + 67061, 67064, 67067, 67070, 67073, 67076, 67079, 67082, 67085, 67088, + 67091, 67094, 67097, 67100, 67103, 67106, 67109, 67112, 67115, 67118, + 67121, 67124, 67127, 67130, 67133, 67136, 67139, 67142, 67145, 67148, + 67151, 67154, 67157, 67160, 67163, 67166, 67169, 67172, 67175, 67178, + 67181, 67184, 67187, 67190, 67193, 67196, 67199, 67202, 67211, 67219, + 67227, 67235, 67243, 67251, 67259, 67267, 67275, 67283, 67292, 67301, + 67310, 67319, 67328, 67337, 67346, 67355, 67364, 67373, 67382, 67391, + 67400, 67409, 67418, 67421, 67424, 67427, 67429, 67432, 67435, 67438, + 67443, 67448, 67451, 67458, 67465, 67472, 67479, 67482, 67487, 67489, + 67493, 67495, 67497, 67500, 67503, 67506, 67509, 67512, 67515, 67518, + 67523, 67528, 67531, 67534, 67537, 67540, 67543, 67546, 67549, 67553, + 67556, 67559, 67562, 67565, 67568, 67573, 67576, 67579, 67582, 67587, + 67592, 67597, 67602, 67607, 67612, 67617, 67622, 67628, 67636, 67638, + 67641, 67644, 67647, 67650, 67656, 67664, 67667, 67670, 67675, 67678, + 67681, 67684, 67689, 67692, 67695, 67700, 67703, 67706, 67711, 67714, + 67717, 67722, 67727, 67732, 67735, 67738, 67741, 67744, 67750, 67753, + 67756, 67759, 67761, 67764, 67767, 67770, 67775, 67778, 67781, 67784, + 67787, 67790, 67795, 67798, 67801, 67804, 67807, 67810, 67813, 67816, + 67819, 67822, 67828, 67833, 67841, 67849, 67857, 67865, 67873, 67881, + 67889, 67897, 67905, 67914, 67923, 67932, 67941, 67950, 67959, 67968, + 67977, 67986, 67995, 68004, 68013, 68022, 68031, 68040, 68049, 68058, + 68067, 68076, 68085, 68094, 68103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68106, 68115, 68124, 68135, 68142, + 68147, 68152, 68159, 68166, 68172, 68177, 68182, 68187, 68192, 68199, + 68204, 68209, 68214, 68225, 68230, 68235, 68242, 68247, 68254, 68259, + 68264, 68271, 68278, 68285, 68294, 68303, 68308, 68313, 68318, 68325, + 68330, 68340, 68347, 68352, 68357, 68362, 68367, 68372, 68377, 68386, + 68393, 68400, 68405, 68412, 68417, 68424, 68433, 68444, 68449, 68458, + 68463, 68470, 68479, 68488, 68493, 68498, 68505, 68511, 68518, 68525, + 68529, 68533, 68536, 68540, 68544, 68548, 68552, 68556, 68560, 68564, + 68567, 68571, 68575, 68579, 68583, 68587, 68591, 68594, 68598, 68602, + 68605, 68609, 68613, 68617, 68621, 68625, 68629, 68633, 68637, 68641, + 68645, 68649, 68653, 68657, 68661, 68665, 68669, 68673, 68677, 68681, + 68685, 68689, 68693, 68697, 68701, 68705, 68709, 68713, 68717, 68721, + 68725, 68729, 68733, 68737, 68741, 68745, 68749, 68753, 68757, 68761, + 68765, 68769, 68773, 68777, 68781, 68784, 68788, 68792, 68796, 68800, + 68804, 68808, 68812, 68816, 68820, 68824, 68828, 68832, 68836, 68840, + 68844, 68848, 68852, 68856, 68860, 68864, 68868, 68872, 68876, 68880, + 68884, 68888, 68892, 68896, 68900, 68904, 68908, 68912, 68916, 68920, + 68924, 68928, 68932, 68936, 68940, 68944, 68948, 68952, 68956, 68960, + 68964, 68968, 68972, 68976, 68980, 68984, 68988, 68992, 68996, 69000, + 69004, 69008, 69012, 69016, 69020, 69024, 69028, 69032, 69036, 69040, + 69044, 69048, 69052, 69056, 69060, 69064, 69068, 69072, 69076, 69080, + 69084, 69088, 69092, 69096, 69100, 69104, 69108, 69112, 69116, 69120, + 69124, 69128, 69132, 69136, 69140, 69144, 69148, 69152, 69156, 69160, + 69164, 69168, 69172, 69176, 69180, 69184, 69188, 69192, 69196, 69200, + 69204, 69208, 69212, 69216, 69220, 69224, 69228, 69232, 69236, 69240, + 69244, 69248, 69252, 69255, 69259, 69263, 69267, 69271, 69275, 69279, + 69283, 69287, 69291, 69295, 69299, 69303, 69307, 69311, 69315, 69319, + 69323, 69327, 69331, 69335, 69339, 69343, 69347, 69351, 69355, 69359, + 69363, 69367, 69371, 69375, 69379, 69383, 69387, 69391, 69395, 69399, + 69403, 69407, 69411, 69415, 69419, 69423, 69427, 69431, 69435, 69439, + 69443, 69447, 69451, 69455, 69459, 69463, 69467, 69471, 69475, 69479, + 69483, 69487, 69491, 69495, 69499, 69503, 69507, 69511, 69515, 69519, + 69523, 69527, 69531, 69535, 69539, 69543, 69547, 69551, 69555, 69559, + 69563, 69567, 69571, 69575, 69579, 69583, 69587, 69591, 69595, 69599, + 69603, 69607, 69611, 69615, 69619, 69623, 69627, 69631, 69635, 69639, + 69643, 69647, 69651, 69655, 69659, 69663, 69667, 69671, 69675, 69679, + 69683, 69686, 69690, 69694, 69698, 69702, 69706, 69710, 69714, 69717, + 69721, 69725, 69729, 69733, 69737, 69741, 69745, 69749, 69753, 69757, + 69761, 69765, 69769, 69773, 69777, 69781, 69785, 69789, 69793, 69797, + 69801, 69805, 69809, 69813, 69817, 69821, 69825, 69829, 69833, 69837, + 69841, 69845, 69849, 69853, 69857, 69861, 69865, 69869, 69873, 69877, + 69881, 69885, 69889, 69893, 69897, 69901, 69905, 69909, 69913, 69917, + 69921, 69925, 69929, 69933, 69937, 69941, 69945, 69949, 69953, 69957, + 69961, 69965, 69969, 69973, 69977, 69981, 69985, 69989, 69993, 69997, + 70001, 70005, 70009, 70013, 70017, 70021, 70025, 70029, 70033, 70037, + 70041, 70045, 70049, 70053, 70057, 70061, 70065, 70069, 70073, 70076, + 70080, 70084, 70088, 70092, 70096, 70100, 70104, 70108, 70112, 70116, + 70120, 70124, 70128, 70132, 70136, 70140, 70144, 70148, 70152, 70156, + 70160, 70164, 70168, 70172, 70176, 70180, 70184, 70188, 70192, 70196, + 70200, 70204, 70208, 70212, 70216, 70220, 70224, 70228, 70232, 70236, + 70240, 70244, 70248, 70252, 70256, 70260, 70264, 70268, 70272, 70276, + 70280, 70284, 70288, 70292, 70296, 70300, 70304, 70308, 70312, 70315, + 70319, 70323, 70327, 70331, 70335, 70339, 70343, 70347, 70351, 70355, + 70359, 70363, 70367, 70371, 70375, 70379, 70383, 70387, 70391, 70395, + 70399, 70403, 70407, 70411, 70415, 70419, 70423, 70427, 70431, 70435, + 70439, 70443, 70447, 70451, 70455, 70459, 70463, 70467, 70471, 70475, + 70479, 70483, 70487, 70491, 70495, 70499, 70503, 70507, 70511, 70515, + 70519, 70523, 70527, 70531, 70535, 70539, 70543, 70547, 70551, 70555, + 70559, 70563, 70567, 70570, 70574, 70578, 70582, 70586, 70590, 70594, + 70598, 70602, 70606, 70610, 70614, 70618, 70622, 70626, 70630, 70634, + 70638, 70642, 70646, 70650, 70654, 70658, 70662, 70666, 70670, 70674, + 70678, 70682, 70686, 70690, 70694, 70698, 70702, 70706, 70710, 70714, + 70718, 70722, 70726, 70730, 70734, 70738, 70742, 70746, 70750, 70754, + 70758, 70762, 70766, 70770, 70774, 70778, 70782, 70786, 70790, 70794, + 70798, 70802, 70806, 70810, 70814, 70818, 70822, 70826, 70830, 70834, + 70838, 70842, 70846, 70850, 70854, 70858, 70862, 70866, 70870, 70874, + 70878, 70882, 70886, 70890, 70894, 70898, 70902, 70906, 70910, 70914, + 70918, 70922, 70926, 70930, 70934, 70938, 70942, 70946, 70950, 70954, + 70958, 70962, 70966, 70970, 70974, 70978, 70982, 70986, 70990, 70994, + 70998, 71002, 71006, 71010, 71014, 71018, 71022, 71025, 71029, 71033, + 71037, 71041, 71045, 71049, 71053, 71057, 71061, 71065, 71069, 71073, + 71077, 71081, 71085, 71089, 71093, 71097, 71101, 71105, 71109, 71113, + 71117, 71121, 71125, 71129, 71133, 71137, 71141, 71145, 71149, 71153, + 71157, 71161, 71165, 71169, 71173, 71177, 71181, 71185, 71189, 71193, + 71197, 71201, 71205, 71209, 71213, 71217, 71221, 71225, 71229, 71233, + 71237, 71241, 71245, 71249, 71253, 71257, 71261, 71265, 71269, 71273, + 71277, 71281, 71285, 71289, 71293, 71297, 71301, 71305, 71309, 71313, + 71317, 71321, 71325, 71329, 71333, 71337, 71341, 71345, 71349, 71353, + 71357, 71361, 71365, 71369, 71373, 71377, 71381, 71385, 71389, 71393, + 71397, 71401, 71405, 71409, 71413, 71417, 71421, 71425, 71429, 71433, + 71437, 71441, 71445, 71449, 71453, 71457, 71461, 71465, 71469, 71473, + 71477, 71481, 71485, 71489, 71493, 71497, 71501, 71505, 71509, 71513, + 71517, 71521, 71525, 71529, 71533, 71537, 71541, 71545, 71549, 71553, + 71557, 71561, 71565, 71569, 71573, 71577, 71581, 71585, 71589, 71593, + 71597, 71601, 71605, 71609, 71613, 71617, 71621, 71625, 71628, 71632, + 71636, 71640, 71644, 71648, 71652, 71656, 71659, 71663, 71667, 71671, + 71675, 71679, 71683, 71687, 71691, 71695, 71699, 71703, 71707, 71711, + 71715, 71719, 71723, 71727, 71731, 71735, 71739, 71743, 71747, 71751, + 71755, 71759, 71763, 71767, 71771, 71775, 71779, 71783, 71787, 71791, + 71795, 71799, 71803, 71807, 71811, 71815, 71819, 71823, 71827, 71831, + 71835, 71839, 71843, 71847, 71851, 71855, 71859, 71863, 71867, 71871, + 71875, 71879, 71883, 71887, 71891, 71895, 71899, 71903, 71907, 71911, + 71915, 71919, 71923, 71927, 71931, 71935, 71939, 71943, 71947, 71951, + 71955, 71959, 71963, 71967, 71971, 71975, 71979, 71983, 71987, 71991, + 71995, 71999, 72003, 72007, 72011, 72015, 72019, 72023, 72027, 72031, + 72035, 72039, 72043, 72047, 72051, 72055, 72059, 72063, 72067, 72071, + 72075, 72079, 72083, 72087, 72091, 72095, 72099, 72103, 72107, 72111, + 72115, 72119, 72123, 72127, 72131, 72135, 72139, 72143, 72147, 72151, + 72155, 72159, 72163, 72167, 72171, 72175, 72179, 72183, 72187, 72191, + 72195, 72199, 72203, 72207, 72211, 72215, 72219, 72223, 72227, 72231, + 72235, 72239, 72243, 72247, 72251, 72255, 72259, 72263, 72267, 72271, + 72275, 72279, 72283, 72287, 72291, 72295, 72299, 72303, 72307, 72311, + 72315, 72319, 72323, 72327, 72331, 72335, 72339, 72343, 72347, 72351, + 72355, 72359, 72363, 72367, 72371, 72375, 72379, 72383, 72386, 72390, + 72394, 72398, 72402, 72406, 72410, 72414, 72418, 72422, 72426, 72430, + 72434, 72438, 72442, 72446, 72450, 72454, 72458, 72462, 72466, 72470, + 72474, 72478, 72482, 72486, 72490, 72494, 72498, 72502, 72506, 72510, + 72514, 72518, 72522, 72526, 72530, 72534, 72538, 72542, 72546, 72550, + 72554, 72558, 72562, 72566, 72570, 72574, 72578, 72582, 72586, 72590, + 72594, 72598, 72602, 72606, 72610, 72614, 72618, 72622, 72626, 72630, + 72634, 72638, 72642, 72646, 72650, 72654, 72658, 72662, 72666, 72670, + 72674, 72678, 72682, 72686, 72690, 72694, 72698, 72702, 72706, 72710, + 72714, 72718, 72722, 72726, 72730, 72734, 72738, 72742, 72746, 72750, + 72754, 72758, 72762, 72766, 72770, 72774, 72778, 72782, 72786, 72790, + 72794, 72798, 72802, 72806, 72810, 72814, 72818, 72822, 72826, 72830, + 72834, 72838, 72842, 72846, 72850, 72854, 72858, 72862, 72866, 72870, + 72874, 72878, 72882, 72886, 72890, 72894, 72898, 72902, 72906, 72910, + 72914, 72918, 72922, 72926, 72930, 72934, 72938, 72942, 72946, 72950, + 72954, 72958, 72962, 72966, 72970, 72974, 72978, 72982, 72986, 72990, + 72994, 72998, 73002, 73006, 73010, 73014, 73018, 73022, 73026, 73030, + 73034, 73038, 73042, 73046, 73050, 73054, 73058, 73062, 73066, 73070, + 73074, 73078, 73082, 73086, 73090, 73094, 73098, 73102, 73106, 73110, + 73114, 73118, 73122, 73126, 73130, 73134, 73138, 73142, 73146, 73150, + 73154, 73158, 73162, 73166, 0, 0, 0, 73170, 73174, 73178, 73182, 73186, + 73190, 73194, 73198, 73202, 73206, 73210, 73214, 73218, 73222, 73226, + 73230, 73234, 73238, 73242, 73246, 73250, 73254, 73258, 73262, 73266, + 73270, 73274, 73278, 73282, 73286, 73290, 73294, 73298, 73302, 73306, + 73310, 73314, 73318, 73322, 73326, 73330, 73334, 73338, 73342, 73346, + 73350, 73354, 73358, 73362, 73366, 73370, 73374, 73378, 73382, 73386, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 73390, 73395, 73399, 73404, 73409, 73413, 73418, + 73423, 73427, 73432, 73437, 73442, 73447, 73452, 73457, 73462, 73466, + 73470, 73474, 73478, 73483, 73488, 73493, 73497, 73502, 73507, 73512, + 73517, 73522, 73526, 73531, 73535, 73540, 73544, 73549, 73553, 73557, + 73561, 73566, 73571, 73576, 73584, 73592, 73600, 73608, 73615, 73623, + 73629, 73637, 73641, 73645, 73649, 73653, 73657, 73661, 73665, 73669, + 73673, 73677, 73681, 73685, 73689, 73693, 73697, 73701, 73705, 73709, + 73713, 73717, 73721, 73725, 73729, 73733, 73737, 73741, 73745, 73749, + 73753, 73757, 73761, 73765, 73769, 73773, 73777, 73781, 73784, 73788, + 73792, 73796, 73800, 73804, 73808, 73812, 73816, 73820, 73824, 73828, + 73832, 73836, 73840, 73844, 73848, 73852, 73856, 73860, 73864, 73868, + 73872, 73876, 73880, 73884, 73888, 73892, 73896, 73900, 73904, 73908, + 73912, 73916, 73920, 73924, 73928, 73931, 73935, 73939, 73942, 73946, + 73950, 73954, 73957, 73961, 73965, 73969, 73973, 73977, 73981, 73985, + 73989, 73993, 73996, 74000, 74004, 74008, 74011, 74014, 74018, 74022, + 74025, 74029, 74033, 74037, 74041, 74045, 74049, 74052, 74055, 74059, + 74063, 74067, 74070, 74073, 74077, 74081, 74085, 74089, 74093, 74097, + 74101, 74105, 74109, 74113, 74117, 74121, 74125, 74129, 74133, 74137, + 74141, 74145, 74149, 74153, 74157, 74161, 74165, 74169, 74173, 74177, + 74181, 74185, 74189, 74193, 74197, 74201, 74205, 74209, 74213, 74217, + 74221, 74224, 74228, 74232, 74236, 74240, 74244, 74248, 74252, 74256, + 74260, 74264, 74268, 74272, 74276, 74280, 74284, 74288, 74292, 74296, + 74300, 74304, 74308, 74312, 74316, 74320, 74324, 74328, 74332, 74336, + 74340, 74344, 74348, 74352, 74356, 74360, 74364, 74368, 74371, 74375, + 74379, 74383, 74387, 74391, 74395, 74399, 74403, 74407, 74411, 74415, + 74419, 74423, 74427, 74431, 74435, 74438, 74442, 74446, 74450, 74454, + 74458, 74462, 74466, 74470, 74474, 74478, 74482, 74486, 74490, 74494, + 74498, 74502, 74506, 74510, 74514, 74518, 74522, 74525, 74529, 74533, + 74537, 74541, 74545, 74549, 74553, 74557, 74561, 74565, 74569, 74573, + 74577, 74581, 74585, 74589, 74593, 74597, 74601, 74605, 74609, 74613, + 74617, 74621, 74625, 74629, 74633, 74637, 74641, 74645, 74649, 74653, + 74657, 74661, 74665, 74669, 74673, 74677, 74681, 74685, 74689, 74693, + 74697, 74700, 74705, 74709, 74715, 74720, 74726, 74730, 74734, 74738, + 74742, 74746, 74750, 74754, 74758, 74762, 74766, 74770, 74774, 74778, + 74782, 74785, 74788, 74791, 74794, 74797, 74800, 74803, 74806, 74809, + 74814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74820, + 74825, 74830, 74835, 74840, 74847, 74854, 74859, 74864, 74869, 74874, + 74881, 74888, 74895, 74902, 74909, 74916, 74926, 74936, 74943, 74950, + 74957, 74964, 74970, 74976, 74985, 74994, 75001, 75008, 75019, 75030, + 75035, 75040, 75047, 75054, 75061, 75068, 75075, 75082, 75089, 75096, + 75102, 75108, 75114, 75120, 75127, 75134, 75139, 75143, 75150, 75157, + 75164, 75168, 75175, 75179, 75184, 75188, 75194, 75199, 75205, 75210, + 75214, 75218, 75221, 75224, 75229, 75234, 75239, 75244, 75249, 75254, + 75259, 75264, 75269, 75274, 75282, 75290, 75295, 75300, 75305, 75310, + 75315, 75320, 75325, 75330, 75335, 75340, 75345, 75350, 75355, 75360, + 75366, 75372, 75378, 75384, 75389, 75395, 75398, 75401, 75404, 75408, + 75412, 75416, 75420, 75423, 75427, 75430, 75433, 75436, 75440, 75444, + 75448, 75452, 75456, 75460, 75464, 75468, 75472, 75476, 75480, 75484, + 75488, 75492, 75496, 75500, 75504, 75508, 75512, 75516, 75520, 75524, + 75527, 75531, 75535, 75539, 75543, 75547, 75551, 75555, 75559, 75563, + 75567, 75571, 75575, 75579, 75583, 75587, 75591, 75595, 75599, 75603, + 75607, 75611, 75615, 75619, 75623, 75626, 75630, 75634, 75638, 75642, + 75646, 75650, 75654, 75657, 75661, 75665, 75669, 75673, 75677, 75681, + 75685, 75689, 75693, 75697, 75701, 75705, 75710, 75715, 75718, 75723, + 75726, 75729, 75732, 0, 0, 0, 0, 0, 0, 0, 0, 75736, 75745, 75754, 75763, + 75772, 75781, 75790, 75799, 75808, 75816, 75823, 75831, 75838, 75846, + 75856, 75865, 75875, 75884, 75894, 75902, 75909, 75917, 75924, 75932, + 75937, 75942, 75948, 75957, 75963, 75969, 75976, 75985, 75993, 76001, + 76009, 76016, 76023, 76030, 76037, 76042, 76047, 76052, 76057, 76062, + 76067, 76072, 76077, 76085, 76093, 76099, 76105, 76110, 76115, 76120, + 76125, 76130, 76135, 76140, 76145, 76154, 76163, 76168, 76173, 76183, + 76193, 76200, 76207, 76216, 76225, 76237, 76249, 76255, 76261, 76269, + 76277, 76287, 76297, 76304, 76311, 76316, 76321, 76333, 76345, 76353, + 76361, 76371, 76381, 76393, 76405, 76414, 76423, 76430, 76437, 76444, + 76451, 76460, 76469, 76474, 76479, 76486, 76493, 76500, 76507, 76519, + 76531, 76536, 76541, 76546, 76551, 76556, 76561, 76566, 76571, 76575, + 76580, 76585, 76590, 76595, 76600, 76606, 76611, 76616, 76623, 76630, + 76637, 76644, 76651, 76659, 76667, 76672, 76677, 76683, 76689, 76696, + 76703, 76710, 76717, 76724, 76728, 76735, 76740, 76745, 76751, 76764, + 76770, 76778, 76786, 76793, 76800, 76809, 76818, 76825, 76832, 76839, + 76846, 76853, 76860, 76867, 76874, 76881, 76888, 76897, 76906, 76915, + 76924, 76933, 76942, 76951, 76960, 76969, 76978, 76985, 76992, 76998, + 77006, 77012, 77018, 77024, 77030, 77038, 77043, 77048, 77053, 77058, + 77063, 77069, 77075, 77081, 77087, 77093, 77099, 77105, 0, 0, 77111, + 77118, 77125, 77134, 77141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 77150, 77157, 77164, 77170, 77177, 77185, + 77193, 77201, 77209, 77217, 77223, 77229, 77236, 77242, 77248, 77254, + 77261, 77268, 77275, 77282, 77289, 77296, 77303, 77310, 77317, 77324, + 77331, 77338, 77345, 77352, 77358, 77365, 77372, 77379, 77386, 77393, + 77400, 77407, 77414, 77421, 77428, 77435, 77442, 77449, 77456, 77463, + 77470, 77477, 77484, 77492, 77500, 77508, 77516, 0, 0, 0, 0, 77524, + 77531, 77538, 77545, 77552, 77559, 77566, 77572, 77578, 77584, 0, 0, 0, + 0, 0, 0, 77590, 77594, 77599, 77604, 77609, 77614, 77619, 77624, 77629, + 77633, 77638, 77643, 77647, 77651, 77656, 77661, 77665, 77670, 77675, + 77680, 77685, 77690, 77695, 77700, 77704, 77708, 77712, 77717, 77721, + 77725, 77729, 77733, 77737, 77741, 77745, 77750, 77755, 77760, 77765, + 77770, 77777, 77783, 77788, 77793, 77798, 77803, 77809, 77816, 77822, + 77829, 77835, 77841, 77846, 77853, 77859, 77864, 0, 0, 0, 0, 0, 0, 0, 0, + 77870, 77875, 77880, 77884, 77889, 77893, 77898, 77902, 77907, 77912, + 77918, 77923, 77929, 77933, 77938, 77943, 77947, 77952, 77957, 77961, + 77966, 77971, 77976, 77981, 77986, 77991, 77996, 78001, 78006, 78011, + 78016, 78021, 78026, 78031, 78035, 78040, 78045, 78050, 78054, 78058, + 78063, 78068, 78073, 78077, 78081, 78085, 78089, 78094, 78099, 78104, + 78108, 78112, 78117, 78123, 78129, 78134, 78140, 78145, 78151, 78157, + 78164, 78170, 78177, 78182, 78188, 78194, 78199, 78205, 78211, 78216, 0, + 0, 0, 0, 0, 0, 0, 0, 78221, 78225, 78230, 78235, 78239, 78243, 78247, + 78251, 78255, 78259, 78263, 78267, 0, 0, 0, 0, 0, 0, 78271, 78276, 78280, + 78284, 78288, 78292, 78296, 78300, 78304, 78308, 78312, 78316, 78320, + 78324, 78328, 78332, 78336, 78341, 78346, 78352, 78358, 78365, 78370, + 78375, 78381, 78385, 78390, 78393, 78396, 78400, 78405, 78409, 78414, + 78421, 78427, 78433, 78439, 78445, 78451, 78457, 78463, 78469, 78475, + 78481, 78488, 78495, 78502, 78508, 78515, 78522, 78529, 78535, 78542, + 78548, 78554, 78561, 78567, 78574, 78581, 78587, 78593, 78599, 78606, + 78613, 78619, 78626, 78633, 78639, 78646, 78652, 78659, 78666, 78672, + 78678, 78685, 78691, 78698, 78705, 78714, 78721, 78728, 78732, 78737, + 78742, 78746, 78751, 78755, 78759, 78764, 78768, 78773, 78778, 78783, + 78787, 78791, 78795, 78799, 78804, 78808, 78813, 78818, 78823, 78828, + 78832, 78837, 78842, 78847, 78853, 78858, 78864, 78870, 78876, 78882, + 78888, 78893, 78899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78903, 78908, + 78912, 78916, 78920, 78924, 78928, 78932, 78936, 78940, 78944, 78948, + 78952, 78956, 78960, 78964, 78968, 78972, 78976, 78980, 78984, 78988, + 78992, 78996, 79000, 79004, 79008, 79012, 79016, 79020, 0, 0, 0, 79024, + 79029, 79034, 79039, 79044, 79048, 79055, 79059, 79064, 79068, 79075, + 79082, 79091, 79095, 79100, 79104, 79108, 79115, 79122, 79127, 79134, + 79139, 79144, 79151, 79156, 79163, 79170, 79175, 79180, 79187, 79192, + 79199, 79206, 79210, 79217, 79222, 79229, 79233, 79237, 79244, 79249, + 79256, 79260, 79264, 79268, 79275, 79279, 79284, 79291, 79298, 79302, + 79306, 79313, 79319, 79325, 79331, 79339, 79345, 79353, 79359, 79367, + 79373, 79379, 79385, 79391, 79395, 79400, 79405, 79411, 79417, 79423, + 79429, 79435, 79441, 79447, 79453, 79461, 79467, 0, 79474, 79478, 79483, + 79487, 79491, 79495, 79499, 79503, 79507, 79511, 79515, 0, 0, 0, 0, + 79519, 79527, 79533, 79539, 79545, 79551, 79557, 79563, 79569, 79576, + 79583, 79590, 79597, 79604, 79611, 79618, 79625, 79632, 79639, 79646, + 79652, 79658, 79664, 79670, 79676, 79682, 79688, 79694, 79700, 79707, + 79714, 79721, 79728, 0, 79735, 79739, 79743, 79747, 79751, 79756, 79760, + 79764, 79769, 79774, 79779, 79784, 79789, 79794, 79799, 79804, 79809, + 79814, 79819, 79824, 79828, 79833, 79838, 79843, 79848, 79852, 79857, + 79861, 79866, 79871, 79876, 79881, 79886, 79890, 79895, 79899, 79903, + 79907, 79912, 79917, 79921, 79925, 79931, 79936, 79942, 79948, 79953, + 79959, 79964, 79970, 79976, 79982, 79987, 79992, 79997, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 80003, 80009, 80015, 80021, 80028, 80034, 80040, 80046, 80052, + 80058, 80063, 80068, 80074, 80081, 0, 0, 80088, 80093, 80097, 80101, + 80105, 80109, 80113, 80117, 80121, 80125, 0, 0, 80129, 80135, 80141, + 80148, 80156, 80162, 80168, 80174, 80180, 80186, 80192, 80198, 80204, + 80210, 80216, 80222, 80227, 80232, 80237, 80243, 80249, 80256, 80262, + 80268, 80273, 80280, 80287, 80294, 80300, 80305, 80310, 80315, 80323, + 80330, 80337, 80345, 80353, 80360, 80367, 80374, 80381, 80388, 80395, + 80402, 80409, 80416, 80423, 80430, 80437, 80444, 80451, 80458, 80465, + 80472, 80479, 80486, 80493, 80499, 80505, 80512, 80519, 80526, 80533, + 80540, 80547, 80554, 80561, 80568, 80575, 80582, 80589, 80596, 80603, + 80610, 80617, 80624, 80631, 80638, 80645, 80652, 80659, 80666, 80673, + 80679, 80685, 80692, 80698, 80703, 80709, 80714, 80719, 80724, 80731, + 80737, 80743, 80749, 80755, 80761, 80767, 80773, 80781, 80789, 80797, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80805, 80811, 80817, 80823, 80831, 80839, 80845, 80851, 80858, 80865, + 80872, 80879, 80886, 80893, 80900, 80907, 80914, 80922, 80930, 80938, + 80946, 80954, 80960, 80968, 80974, 80982, 80991, 80999, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 81005, 81009, 81013, 81017, 81021, 81025, 0, 0, 81029, 81033, + 81037, 81041, 81045, 81049, 0, 0, 81053, 81057, 81061, 81065, 81069, + 81073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81077, 81081, 81085, 81089, 81093, + 81097, 81101, 0, 81105, 81109, 81113, 81117, 81121, 81125, 81129, 0, + 81133, 81140, 81146, 81152, 81158, 81166, 81173, 81182, 81194, 81204, + 81213, 81221, 81229, 81237, 81243, 81251, 81258, 81265, 81273, 81283, + 81290, 81299, 81305, 81315, 81324, 81329, 81337, 81346, 81351, 81360, + 81367, 81377, 81389, 81394, 81400, 81407, 81412, 81422, 81432, 81442, + 81452, 81467, 81480, 81491, 81499, 81504, 81516, 81525, 81532, 81539, + 81545, 81551, 81556, 81563, 81569, 81580, 0, 0, 0, 0, 0, 0, 0, 0, 81591, + 81595, 81599, 81603, 81607, 81611, 81616, 81621, 81625, 81630, 81635, + 81640, 81645, 81650, 81654, 81659, 81664, 81669, 81674, 81679, 81683, + 81688, 81693, 81698, 81703, 81708, 81712, 81717, 81722, 81727, 81732, + 81736, 81741, 81746, 81751, 81756, 81761, 81766, 81771, 81776, 81781, + 81786, 81791, 81796, 81801, 81805, 81810, 81815, 81820, 81825, 81830, + 81835, 81840, 81844, 81849, 81854, 81859, 81864, 81869, 81874, 81879, + 81884, 81889, 81894, 81899, 81904, 81909, 81914, 81919, 81924, 81929, + 81934, 81939, 81944, 81949, 81954, 81959, 81964, 81969, 81974, 81978, + 81985, 81992, 81999, 82006, 82012, 82018, 82025, 82032, 82039, 82046, + 82053, 82060, 82067, 82074, 82081, 82087, 82094, 82101, 82108, 82115, + 82122, 82129, 82136, 82143, 82150, 82157, 82164, 82173, 82182, 82191, + 82200, 82209, 82218, 82227, 82236, 82244, 82252, 82260, 82268, 82276, + 82284, 82292, 82300, 82306, 82314, 0, 0, 82322, 82329, 82335, 82341, + 82347, 82353, 82359, 82365, 82371, 82377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82383, 82388, + 82393, 82398, 82403, 82408, 82413, 82418, 82423, 82428, 82433, 82438, + 82443, 82448, 82453, 82458, 82463, 82468, 82473, 82478, 82483, 82488, + 82493, 0, 0, 0, 0, 82498, 82502, 82506, 82510, 82514, 82518, 82522, + 82526, 82530, 82534, 82538, 82542, 82546, 82550, 82554, 82558, 82562, + 82566, 82570, 82574, 82578, 82582, 82586, 82590, 82594, 82598, 82602, + 82606, 82610, 82614, 82618, 82622, 82626, 82630, 82634, 82638, 82642, + 82646, 82650, 82654, 82658, 82662, 82666, 82670, 82674, 82678, 82682, + 82686, 82690, 0, 0, 0, 0, 82694, 82698, 82702, 82706, 82710, 82714, + 82718, 82722, 82726, 82730, 82734, 82738, 82742, 82746, 82750, 82754, + 82758, 82762, 82766, 82770, 82774, 82778, 82782, 82786, 82790, 82794, + 82798, 82802, 82806, 82810, 82814, 82818, 82822, 82826, 82830, 82834, + 82838, 82842, 82846, 82850, 82854, 82858, 82862, 82866, 82870, 82874, + 82878, 82882, 82886, 82890, 82894, 82898, 82902, 82906, 82910, 82914, + 82918, 82922, 82926, 82930, 82934, 82938, 82942, 82946, 82950, 82954, + 82958, 82962, 82966, 82970, 82974, 82978, 82982, 82986, 82990, 82994, + 82998, 83002, 83006, 83010, 83014, 83018, 83022, 83026, 83030, 83034, + 83038, 83042, 83046, 83050, 83054, 83058, 83062, 83066, 83070, 83074, + 83078, 83082, 83086, 83090, 83094, 83098, 83102, 83106, 83110, 83114, + 83118, 83122, 83126, 83130, 83134, 83138, 83142, 83146, 83150, 83154, + 83158, 83162, 83166, 83170, 83174, 83178, 83182, 83186, 83190, 83194, + 83198, 83202, 83206, 83210, 83214, 83218, 83222, 83226, 83230, 83234, + 83238, 83242, 83246, 83250, 83254, 83258, 83262, 83266, 83270, 83274, + 83278, 83282, 83286, 83290, 83294, 83298, 83302, 83306, 83310, 83314, + 83318, 83322, 83326, 83330, 83334, 83338, 83342, 83346, 83350, 83354, + 83358, 83362, 83366, 83370, 83374, 83378, 83382, 83386, 83390, 83394, + 83398, 83402, 83406, 83410, 83414, 83418, 83422, 83426, 83430, 83434, + 83438, 83442, 83446, 83450, 83454, 83458, 83462, 83466, 83470, 83474, + 83478, 83482, 83486, 83490, 83494, 83498, 83502, 83506, 83510, 83514, + 83518, 83522, 83526, 83530, 83534, 83538, 83542, 83546, 83550, 83554, + 83558, 83562, 83566, 83570, 83574, 83578, 83582, 83586, 83590, 83594, + 83598, 83602, 83606, 83610, 83614, 83618, 83622, 83626, 83630, 83634, + 83638, 83642, 83646, 83650, 83654, 83658, 83662, 83666, 83670, 83674, + 83678, 83682, 83686, 83690, 83694, 83698, 83702, 83706, 83710, 83714, + 83718, 83722, 83726, 83730, 83734, 83738, 83742, 83746, 83750, 83754, + 83758, 83762, 83766, 83770, 83774, 83778, 83782, 83786, 83790, 83794, + 83798, 83802, 83806, 83810, 83814, 83818, 83822, 83826, 83830, 83834, + 83838, 83842, 83846, 83850, 83854, 83858, 83862, 83866, 83870, 83874, + 83878, 83882, 83886, 83890, 83894, 83898, 83902, 83906, 83910, 83914, + 83918, 83922, 83926, 83930, 83934, 83938, 83942, 83946, 83950, 83954, + 83958, 83962, 83966, 83970, 83974, 83978, 83982, 83986, 83990, 83994, + 83998, 84002, 84006, 84010, 84014, 84018, 84022, 84026, 84030, 84034, + 84038, 84042, 84046, 84050, 84054, 84058, 84062, 84066, 84070, 84074, + 84078, 84082, 84086, 84090, 84094, 84098, 84102, 84106, 84110, 84114, + 84118, 84122, 84126, 84130, 84134, 84138, 84142, 84146, 84150, 84154, 0, + 0, 84158, 84162, 84166, 84170, 84174, 84178, 84182, 84186, 84190, 84194, + 84198, 84202, 84206, 84210, 84214, 84218, 84222, 84226, 84230, 84234, + 84238, 84242, 84246, 84250, 84254, 84258, 84262, 84266, 84270, 84274, + 84278, 84282, 84286, 84290, 84294, 84298, 84302, 84306, 84310, 84314, + 84318, 84322, 84326, 84330, 84334, 84338, 84342, 84346, 84350, 84354, + 84358, 84362, 84366, 84370, 84374, 84378, 84382, 84386, 84390, 84394, + 84398, 84402, 84406, 84410, 84414, 84418, 84422, 84426, 84430, 84434, + 84438, 84442, 84446, 84450, 84454, 84458, 84462, 84466, 84470, 84474, + 84478, 84482, 84486, 84490, 84494, 84498, 84502, 84506, 84510, 84514, + 84518, 84522, 84526, 84530, 84534, 84538, 84542, 84546, 84550, 84554, + 84558, 84562, 84566, 84570, 84574, 84578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84582, 84587, 84592, 84597, 84602, 84607, 84615, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 84620, 84628, 84636, 84644, 84652, 0, 0, 0, 0, 0, + 84660, 84667, 84674, 84684, 84690, 84696, 84702, 84708, 84714, 84720, + 84727, 84733, 84739, 84745, 84754, 84763, 84775, 84787, 84793, 84799, + 84805, 84812, 84819, 84826, 84833, 84840, 0, 84847, 84854, 84861, 84869, + 84876, 0, 84883, 0, 84890, 84897, 0, 84904, 84912, 0, 84919, 84926, + 84933, 84940, 84947, 84954, 84961, 84968, 84975, 84982, 84987, 84994, + 85001, 85007, 85013, 85019, 85026, 85032, 85038, 85044, 85051, 85057, + 85063, 85069, 85076, 85082, 85088, 85094, 85101, 85107, 85113, 85119, + 85126, 85132, 85138, 85144, 85151, 85157, 85163, 85169, 85176, 85182, + 85188, 85194, 85201, 85207, 85213, 85219, 85226, 85232, 85238, 85244, + 85251, 85257, 85263, 85269, 85276, 85282, 85288, 85294, 85301, 85307, + 85313, 85319, 85325, 85331, 85337, 85343, 85349, 85355, 85361, 85367, + 85373, 85379, 85385, 85391, 85398, 85404, 85410, 85416, 85423, 85429, + 85435, 85441, 85448, 85454, 85460, 85466, 85473, 85481, 85489, 85495, + 85501, 85507, 85514, 85523, 85532, 85540, 85548, 85556, 85565, 85573, + 85581, 85589, 85598, 85605, 85612, 85623, 85634, 85638, 85642, 85648, + 85654, 85660, 85666, 85676, 85686, 85693, 85700, 85707, 85715, 85723, + 85727, 85733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85739, + 85745, 85751, 85757, 85764, 85769, 85774, 85780, 85786, 85792, 85798, + 85807, 85813, 85819, 85827, 85835, 85843, 85851, 85857, 85863, 85869, + 85876, 85889, 85903, 85914, 85925, 85937, 85949, 85961, 85973, 85984, + 85995, 86007, 86019, 86031, 86043, 86055, 86067, 86079, 86096, 86113, + 86130, 86137, 86144, 86151, 86159, 86171, 86182, 86193, 86206, 86217, + 86226, 86234, 86243, 86251, 86261, 86269, 86278, 86286, 86295, 86303, + 86313, 86321, 86330, 86338, 86348, 86356, 86364, 86372, 86380, 86387, + 86396, 86404, 86412, 86421, 86429, 86438, 86446, 86454, 86462, 86471, + 86479, 86488, 86496, 86504, 86512, 86520, 86529, 86537, 86546, 86554, + 86563, 86571, 86580, 86588, 86598, 86606, 86614, 86622, 86632, 86640, + 86648, 86657, 86665, 86674, 86683, 86691, 86701, 86709, 86718, 86726, + 86735, 86743, 86753, 86761, 86769, 86776, 86784, 86791, 86800, 86807, + 86816, 86824, 86833, 86841, 86851, 86859, 86868, 86876, 86886, 86894, + 86902, 86909, 86917, 86924, 86933, 86940, 86950, 86960, 86971, 86980, + 86989, 86998, 87007, 87016, 87026, 87038, 87050, 87061, 87073, 87086, + 87097, 87106, 87115, 87123, 87132, 87142, 87150, 87159, 87168, 87176, + 87185, 87195, 87203, 87212, 87221, 87229, 87238, 87248, 87256, 87266, + 87274, 87284, 87292, 87300, 87309, 87317, 87327, 87335, 87343, 87353, + 87361, 87368, 87375, 87384, 87393, 87401, 87410, 87420, 87428, 87439, + 87447, 87455, 87462, 87470, 87479, 87486, 87498, 87509, 87521, 87532, + 87544, 87553, 87561, 87570, 87578, 87587, 87596, 87604, 87613, 87621, + 87630, 87638, 87646, 87654, 87662, 87669, 87678, 87686, 87695, 87703, + 87712, 87720, 87728, 87737, 87745, 87754, 87762, 87771, 87779, 87787, + 87795, 87804, 87812, 87821, 87829, 87838, 87846, 87855, 87863, 87871, + 87879, 87888, 87896, 87905, 87914, 87922, 87931, 87939, 87948, 87956, + 87965, 87973, 87980, 87988, 87995, 88004, 88012, 88021, 88029, 88038, + 88047, 88055, 88065, 88073, 88080, 88088, 88095, 88103, 88115, 88128, + 88137, 88147, 88156, 88166, 88175, 88185, 88194, 88204, 88213, 88223, + 88233, 88242, 88251, 88260, 88270, 88278, 88287, 88297, 88307, 88317, + 88327, 88335, 88345, 88353, 88363, 88371, 88381, 88389, 88399, 88407, + 88416, 88423, 88433, 88441, 88451, 88459, 88469, 88477, 88487, 88495, + 88504, 88512, 88521, 88529, 88538, 88547, 88556, 88565, 88575, 88583, + 88593, 88601, 88611, 88619, 88629, 88637, 88647, 88655, 88664, 88671, + 88681, 88689, 88699, 88707, 88717, 88725, 88735, 88743, 88752, 88760, + 88769, 88777, 88786, 88795, 88804, 88813, 88822, 88830, 88839, 88847, + 88856, 88865, 88873, 88883, 88892, 88902, 88912, 88921, 88931, 88940, + 88949, 88957, 88965, 88970, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 88975, 88986, 88997, 89008, 89018, 89029, 89040, 89050, 89061, 89071, + 89081, 89090, 89101, 89112, 89123, 89136, 89146, 89156, 89167, 89177, + 89187, 89197, 89207, 89217, 89227, 89237, 89248, 89259, 89270, 89280, + 89290, 89302, 89313, 89324, 89334, 89344, 89354, 89364, 89375, 89385, + 89395, 89407, 89417, 89427, 89439, 89450, 89461, 89471, 89481, 89491, + 89501, 89513, 89525, 89537, 89548, 89559, 89569, 89579, 89589, 89598, + 89607, 89617, 89627, 89638, 0, 0, 89648, 89659, 89670, 89680, 89690, + 89702, 89713, 89724, 89737, 89747, 89759, 89768, 89777, 89788, 89799, + 89812, 89823, 89836, 89846, 89858, 89868, 89880, 89892, 89905, 89915, + 89925, 89935, 89946, 89956, 89965, 89975, 89984, 89993, 90003, 90013, + 90023, 90033, 90043, 90053, 90064, 90074, 90085, 90095, 90106, 90117, + 90127, 90137, 90147, 90157, 90167, 90177, 90188, 90198, 90209, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90220, 90235, 90250, 90256, 90262, + 90268, 90274, 90280, 90286, 90292, 90298, 90306, 90310, 90313, 0, 0, + 90321, 90324, 90327, 90330, 90333, 90336, 90339, 90342, 90345, 90348, + 90351, 90354, 90357, 90360, 90363, 90366, 90369, 90377, 90386, 90397, + 90405, 90413, 90422, 90431, 90442, 90454, 0, 0, 0, 0, 0, 0, 90464, 90469, + 90474, 90481, 90488, 90494, 90500, 90505, 90510, 90515, 90521, 90527, + 90533, 90539, 90545, 90552, 90559, 90569, 90579, 90589, 90598, 90609, + 90618, 90627, 90637, 90647, 90659, 90671, 90682, 90693, 90704, 90715, + 90725, 90735, 90745, 90755, 90766, 90777, 90781, 90786, 90795, 90804, + 90808, 90812, 90816, 90821, 90826, 90831, 90836, 90839, 90843, 0, 90848, + 90851, 90854, 90858, 90862, 90867, 90871, 90875, 90880, 90885, 90892, + 90899, 90902, 90905, 90908, 90911, 90914, 90918, 90922, 0, 90926, 90931, + 90935, 90939, 0, 0, 0, 0, 90944, 90949, 90956, 90961, 90966, 0, 90971, + 90976, 90982, 90987, 90993, 90998, 91004, 91009, 91015, 91020, 91026, + 91032, 91041, 91050, 91059, 91068, 91078, 91088, 91098, 91108, 91117, + 91126, 91135, 91145, 91150, 91155, 91161, 91167, 91173, 91180, 91188, + 91196, 91202, 91208, 91214, 91221, 91227, 91233, 91239, 91246, 91252, + 91258, 91264, 91271, 91276, 91281, 91286, 91292, 91298, 91304, 91310, + 91317, 91323, 91329, 91335, 91341, 91347, 91353, 91359, 91365, 91371, + 91377, 91383, 91390, 91396, 91402, 91408, 91415, 91421, 91427, 91433, + 91440, 91446, 91452, 91458, 91465, 91471, 91477, 91483, 91490, 91496, + 91502, 91508, 91515, 91521, 91527, 91533, 91540, 91546, 91552, 91558, + 91565, 91571, 91577, 91583, 91590, 91596, 91602, 91608, 91615, 91621, + 91627, 91633, 91640, 91646, 91652, 91658, 91665, 91670, 91675, 91680, + 91686, 91692, 91698, 91704, 91711, 91717, 91723, 91729, 91736, 91742, + 91748, 91755, 91762, 91767, 91772, 91777, 91783, 91795, 91807, 91819, + 91831, 91844, 91857, 91865, 0, 0, 91873, 0, 91881, 91885, 91889, 91892, + 91896, 91900, 91903, 91906, 91910, 91914, 91917, 91920, 91923, 91926, + 91931, 91934, 91938, 91941, 91944, 91947, 91950, 91953, 91956, 91959, + 91962, 91965, 91968, 91971, 91975, 91979, 91983, 91987, 91992, 91997, + 92003, 92009, 92015, 92020, 92026, 92032, 92038, 92043, 92049, 92055, + 92060, 92066, 92072, 92077, 92083, 92089, 92094, 92100, 92106, 92111, + 92117, 92123, 92129, 92135, 92141, 92145, 92150, 92154, 92159, 92163, + 92168, 92173, 92179, 92185, 92191, 92196, 92202, 92208, 92214, 92219, + 92225, 92231, 92236, 92242, 92248, 92253, 92259, 92265, 92270, 92276, + 92282, 92287, 92293, 92299, 92305, 92311, 92317, 92322, 92326, 92331, + 92334, 92339, 92344, 92350, 92355, 92360, 92364, 92369, 92374, 92379, + 92384, 92389, 92394, 92399, 92404, 92410, 92416, 92422, 92430, 92434, + 92438, 92442, 92446, 92450, 92454, 92459, 92464, 92469, 92474, 92478, + 92483, 92488, 92493, 92498, 92502, 92507, 92512, 92517, 92521, 92525, + 92530, 92535, 92540, 92545, 92549, 92554, 92559, 92564, 92569, 92573, + 92578, 92583, 92588, 92593, 92597, 92602, 92607, 92611, 92616, 92621, + 92626, 92631, 92636, 92641, 92648, 92655, 92659, 92664, 92669, 92674, + 92679, 92684, 92689, 92694, 92699, 92704, 92709, 92714, 92719, 92724, + 92729, 92734, 92739, 92744, 92749, 92754, 92759, 92764, 92769, 92774, + 92779, 92784, 92789, 92794, 92799, 92804, 0, 0, 0, 92809, 92813, 92818, + 92822, 92827, 92832, 0, 0, 92836, 92841, 92846, 92850, 92855, 92860, 0, + 0, 92865, 92870, 92874, 92879, 92884, 92889, 0, 0, 92894, 92899, 92904, + 0, 0, 0, 92908, 92912, 92916, 92920, 92923, 92927, 92931, 0, 92935, + 92941, 92944, 92948, 92951, 92955, 92959, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92963, 92969, 92975, 92981, 92987, 0, 0, 92991, 92997, 93003, 93009, + 93015, 93021, 93028, 93035, 93042, 93049, 93056, 93063, 0, 93070, 93077, + 93084, 93090, 93097, 93104, 93111, 93118, 93124, 93131, 93138, 93145, + 93152, 93158, 93165, 93172, 93179, 93186, 93192, 93199, 93206, 93213, + 93220, 93227, 93234, 93241, 0, 93248, 93254, 93261, 93268, 93275, 93282, + 93288, 93295, 93302, 93309, 93316, 93322, 93329, 93336, 93342, 93349, + 93356, 93363, 93370, 0, 93377, 93384, 0, 93391, 93398, 93405, 93412, + 93419, 93426, 93433, 93440, 93447, 93454, 93461, 93468, 93475, 93482, + 93489, 0, 0, 93495, 93500, 93505, 93510, 93515, 93520, 93525, 93530, + 93535, 93540, 93545, 93550, 93555, 93560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 93565, 93572, 93579, 93586, 93593, 93600, 93607, 93614, 93621, 93628, + 93635, 93642, 93649, 93656, 93663, 93670, 93677, 93684, 93691, 93698, + 93706, 93714, 93721, 93728, 93733, 93741, 93749, 93756, 93763, 93768, + 93775, 93780, 93785, 93792, 93797, 93802, 93807, 93815, 93820, 93825, + 93832, 93837, 93842, 93849, 93856, 93861, 93866, 93871, 93876, 93881, + 93886, 93891, 93896, 93901, 93908, 93913, 93920, 93925, 93930, 93935, + 93940, 93945, 93950, 93955, 93960, 93965, 93970, 93975, 93982, 93989, + 93996, 94003, 94009, 94014, 94021, 94026, 94031, 94040, 94047, 94056, + 94063, 94068, 94073, 94081, 94086, 94091, 94096, 94101, 94106, 94113, + 94118, 94123, 94128, 94133, 94138, 94145, 94152, 94159, 94166, 94173, + 94180, 94187, 94194, 94201, 94208, 94215, 94222, 94229, 94236, 94243, + 94250, 94257, 94264, 94271, 94278, 94285, 94292, 94299, 94306, 94313, + 94320, 94327, 94334, 0, 0, 0, 0, 0, 94341, 94349, 94357, 0, 0, 0, 0, + 94362, 94366, 94370, 94374, 94378, 94382, 94386, 94390, 94394, 94398, + 94403, 94408, 94413, 94418, 94423, 94428, 94433, 94438, 94443, 94449, + 94455, 94461, 94468, 94475, 94482, 94489, 94496, 94503, 94508, 94513, + 94518, 94524, 94530, 94536, 94542, 94548, 94554, 94560, 94566, 94572, + 94578, 94584, 94590, 94596, 94602, 0, 0, 0, 94608, 94616, 94624, 94632, + 94640, 94648, 94658, 94668, 94676, 94684, 94692, 94700, 94708, 94714, + 94721, 94730, 94738, 94746, 94755, 94764, 94773, 94783, 94794, 94804, + 94815, 94824, 94833, 94842, 94852, 94863, 94873, 94884, 94895, 94904, + 94912, 94918, 94924, 94930, 94936, 94944, 94952, 94958, 94965, 94975, + 94982, 94989, 94996, 95003, 95010, 95020, 95027, 95034, 95042, 95050, + 95059, 95068, 95077, 95086, 95095, 95102, 95110, 95119, 95128, 95132, + 95139, 95144, 95149, 95153, 95157, 95161, 95165, 95170, 95175, 95181, + 95187, 95191, 95197, 95201, 95205, 95209, 95213, 95217, 95221, 95227, + 95231, 95236, 95240, 95244, 0, 95247, 95252, 95257, 95262, 95267, 95274, + 95279, 95284, 95289, 95294, 95299, 95304, 0, 0, 0, 0, 95309, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95315, 95322, + 95331, 95340, 95347, 95354, 95361, 95368, 95375, 95382, 95388, 95395, + 95402, 95409, 95416, 95423, 95430, 95437, 95444, 95453, 95460, 95467, + 95474, 95481, 95488, 95495, 95502, 95509, 95518, 95525, 95532, 95539, + 95546, 95553, 95560, 95569, 95576, 95583, 95590, 95597, 95606, 95613, + 95620, 95627, 95635, 95644, 0, 0, 95653, 95657, 95661, 95666, 95671, + 95676, 95681, 95685, 95690, 95695, 95700, 95705, 95710, 95715, 95719, + 95724, 95729, 95734, 95739, 95743, 95748, 95753, 95757, 95762, 95767, + 95772, 95777, 95782, 95787, 0, 0, 0, 95792, 95796, 95801, 95806, 95810, + 95815, 95819, 95824, 95829, 95834, 95839, 95844, 95848, 95853, 95858, + 95863, 95868, 95873, 95878, 95882, 95887, 95892, 95897, 95902, 95907, + 95912, 95916, 95920, 95925, 95930, 95935, 95940, 95945, 95950, 95955, + 95960, 95965, 95970, 95975, 95980, 95985, 95990, 95995, 96000, 96005, + 96010, 96015, 96020, 96025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 96030, 96036, 96041, 96046, 96051, 96056, 96061, 96066, 96071, 96076, + 96081, 96087, 96093, 96099, 96105, 96111, 96117, 96123, 96129, 96135, + 96142, 96149, 96156, 96164, 96172, 96180, 96188, 96196, 0, 0, 0, 0, + 96204, 96208, 96213, 96218, 96223, 96227, 96232, 96237, 96242, 96247, + 96251, 96255, 96260, 96265, 96270, 96275, 96279, 96284, 96289, 96294, + 96299, 96304, 96309, 96313, 96318, 96323, 96328, 96333, 96338, 96343, + 96348, 96353, 96358, 96363, 96368, 96374, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 96380, 96385, 96392, 96399, 96404, 96409, 96414, 96419, 96424, 96429, + 96434, 96439, 96444, 96449, 96454, 96459, 96464, 96469, 96474, 96479, + 96484, 96489, 96494, 96499, 96504, 96509, 96514, 96519, 96524, 96529, 0, + 0, 0, 0, 0, 96536, 96542, 96548, 96554, 96560, 96565, 96571, 96577, + 96583, 96589, 96594, 96600, 96606, 96612, 96618, 96624, 96630, 96636, + 96642, 96648, 96653, 96659, 96665, 96671, 96677, 96683, 96688, 96694, + 96700, 96705, 96711, 96717, 96723, 96729, 96735, 96741, 96747, 96752, + 96758, 96765, 96772, 96779, 96786, 0, 0, 0, 0, 0, 96793, 96798, 96803, + 96808, 96813, 96818, 96823, 96828, 96833, 96838, 96843, 96848, 96853, + 96858, 96863, 96868, 96873, 96878, 96883, 96888, 96893, 96898, 96903, + 96908, 96913, 96918, 96923, 96927, 96931, 96935, 0, 96940, 96946, 96951, + 96956, 96961, 96966, 96972, 96978, 96984, 96990, 96996, 97002, 97008, + 97013, 97019, 97025, 97031, 97037, 97043, 97048, 97054, 97060, 97065, + 97071, 97076, 97082, 97088, 97093, 97099, 97105, 97110, 97116, 97121, + 97126, 97132, 97138, 97144, 0, 0, 0, 0, 97149, 97155, 97161, 97167, + 97173, 97179, 97185, 97191, 97197, 97204, 97209, 97214, 97220, 97226, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97232, 97238, 97244, + 97250, 97257, 97263, 97270, 97277, 97284, 97291, 97299, 97306, 97314, + 97320, 97326, 97332, 97338, 97344, 97350, 97356, 97362, 97368, 97374, + 97380, 97386, 97392, 97398, 97404, 97410, 97416, 97422, 97428, 97434, + 97440, 97446, 97452, 97458, 97464, 97470, 97476, 97482, 97488, 97494, + 97500, 97507, 97513, 97520, 97527, 97534, 97541, 97549, 97556, 97564, + 97570, 97576, 97582, 97588, 97594, 97600, 97606, 97612, 97618, 97624, + 97630, 97636, 97642, 97648, 97654, 97660, 97666, 97672, 97678, 97684, + 97690, 97696, 97702, 97708, 97714, 97720, 97726, 97732, 97737, 97742, + 97747, 97752, 97757, 97762, 97767, 97772, 97777, 97782, 97787, 97792, + 97797, 97802, 97807, 97812, 97817, 97822, 97827, 97832, 97837, 97842, + 97847, 97852, 97857, 97862, 97867, 97872, 97877, 97882, 97887, 97892, + 97897, 97902, 97907, 97912, 97917, 97922, 97927, 97932, 97937, 97942, + 97947, 97952, 97957, 97962, 97967, 97972, 97977, 97982, 97986, 97991, + 97996, 98001, 98006, 98010, 98014, 98019, 98024, 98029, 98034, 98039, + 98044, 98049, 98054, 98059, 98064, 98069, 98073, 98077, 98081, 98085, + 98089, 98093, 98097, 98102, 98107, 0, 0, 98112, 98117, 98121, 98125, + 98129, 98133, 98137, 98141, 98145, 98149, 0, 0, 0, 0, 0, 0, 98153, 98158, + 98164, 98170, 98176, 98182, 98188, 98194, 98199, 98205, 98210, 98216, + 98221, 98226, 98232, 98238, 98243, 98248, 98253, 98258, 98264, 98269, + 98275, 98280, 98286, 98291, 98297, 98303, 98309, 98315, 98321, 98326, + 98332, 98338, 98344, 98350, 0, 0, 0, 0, 98356, 98361, 98367, 98373, + 98379, 98385, 98391, 98397, 98402, 98408, 98413, 98419, 98424, 98429, + 98435, 98441, 98446, 98451, 98456, 98461, 98467, 98472, 98478, 98483, + 98489, 98494, 98500, 98506, 98512, 98518, 98524, 98529, 98535, 98541, + 98547, 98553, 0, 0, 0, 0, 98559, 98563, 98568, 98573, 98578, 98583, + 98588, 98593, 98598, 98602, 98607, 98612, 98617, 98622, 98626, 98631, + 98636, 98641, 98646, 98651, 98656, 98660, 98665, 98669, 98674, 98679, + 98684, 98689, 98694, 98699, 98704, 98709, 98713, 98718, 98723, 98728, + 98733, 98738, 98743, 98748, 0, 0, 0, 0, 0, 0, 0, 0, 98753, 98760, 98767, + 98774, 98781, 98788, 98795, 98802, 98809, 98816, 98823, 98830, 98837, + 98844, 98851, 98858, 98865, 98872, 98879, 98886, 98893, 98900, 98907, + 98914, 98921, 98928, 98935, 98942, 98949, 98956, 98963, 98970, 98977, + 98984, 98991, 98998, 99005, 99012, 99019, 99026, 99033, 99040, 99047, + 99054, 99061, 99068, 99075, 99082, 99089, 99096, 99103, 99110, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 99117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 99124, 99129, 99134, 99139, 99144, 99149, 99154, 99159, 99164, + 99169, 99174, 99179, 99184, 99189, 99194, 99199, 99204, 99209, 99214, + 99219, 99224, 99229, 99234, 99239, 99244, 99249, 99254, 99259, 99264, + 99269, 99274, 99279, 99284, 99289, 99294, 99299, 99304, 99309, 99314, + 99319, 99324, 99329, 99334, 99339, 99344, 99349, 99354, 99359, 99364, + 99369, 99374, 99379, 99384, 99389, 99394, 99399, 99404, 99409, 99414, + 99419, 99424, 99429, 99434, 99439, 99444, 99449, 99454, 99459, 99464, + 99469, 99474, 99479, 99484, 99489, 99494, 99499, 99504, 99509, 99514, + 99519, 99524, 99529, 99534, 99539, 99544, 99549, 99554, 99559, 99564, + 99569, 99574, 99579, 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, 99714, + 99719, 99724, 99729, 99734, 99739, 99744, 99749, 99754, 99759, 99764, + 99769, 99774, 99779, 99784, 99789, 99794, 99799, 99804, 99809, 99814, + 99819, 99824, 99829, 99834, 99839, 99844, 99849, 99854, 99859, 99864, + 99869, 99874, 99879, 99884, 99889, 99894, 99899, 99904, 99909, 99914, + 99919, 99924, 99929, 99934, 99939, 99944, 99949, 99954, 99959, 99964, + 99969, 99974, 99979, 99984, 99989, 99994, 99999, 100004, 100009, 100014, + 100019, 100024, 100029, 100034, 100039, 100044, 100049, 100054, 100059, + 100064, 100069, 100074, 100079, 100084, 100089, 100094, 100099, 100104, + 100109, 100114, 100119, 100124, 100129, 100134, 100139, 100144, 100149, + 100154, 100159, 100164, 100169, 100174, 100179, 100184, 100189, 100194, + 100199, 100204, 100209, 100214, 100219, 100224, 100229, 100234, 100239, + 100244, 100249, 100254, 100259, 100264, 100269, 100274, 100279, 100284, + 100289, 100294, 100299, 100304, 100309, 100314, 100319, 100324, 100329, + 100334, 100339, 100344, 100349, 100354, 100359, 100364, 100369, 100374, + 100379, 100384, 100389, 100394, 100399, 100404, 100409, 100414, 100419, + 100424, 100429, 100434, 100439, 100444, 100449, 100454, 100459, 100464, + 100469, 100474, 100479, 100484, 100489, 100494, 100499, 100504, 100509, + 100514, 100519, 100524, 100529, 100534, 100539, 100544, 100549, 100554, + 100559, 100564, 100569, 100574, 100579, 100584, 100589, 100594, 100599, + 100604, 100609, 100614, 100619, 100624, 100629, 100634, 100639, 100644, + 100649, 100654, 100659, 100664, 100669, 100674, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 100679, 100685, 100692, 100699, 100705, 100712, 100719, 100726, + 100733, 100739, 100746, 100753, 100760, 100767, 100774, 100781, 100788, + 100795, 100802, 100809, 100816, 100823, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 100830, 100835, 100840, 100845, 100850, 100855, 100860, 100865, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100870, + 100874, 100878, 100882, 100886, 100890, 0, 0, 100895, 0, 100900, 100904, + 100909, 100914, 100919, 100924, 100928, 100933, 100938, 100943, 100948, + 100952, 100957, 100962, 100967, 100972, 100976, 100981, 100986, 100991, + 100996, 101000, 101005, 101010, 101015, 101020, 101024, 101029, 101034, + 101039, 101044, 101048, 101053, 101058, 101063, 101068, 101072, 101077, + 101082, 101086, 101091, 101096, 101101, 101106, 0, 101111, 101116, 0, 0, + 0, 101121, 0, 0, 101126, 101131, 101138, 101145, 101152, 101159, 101166, + 101173, 101180, 101187, 101194, 101201, 101208, 101215, 101222, 101229, + 101236, 101243, 101250, 101257, 101264, 101271, 101278, 0, 101285, + 101292, 101298, 101304, 101310, 101317, 101324, 101332, 101339, 101347, + 101352, 101357, 101362, 101367, 101372, 101377, 101382, 101387, 101392, + 101397, 101402, 101407, 101412, 101418, 101423, 101428, 101433, 101438, + 101443, 101448, 101453, 101458, 101463, 101469, 101475, 101479, 101483, + 101487, 101491, 101495, 101500, 101505, 101511, 101516, 101522, 101527, + 101532, 101537, 101543, 101548, 101553, 101558, 101563, 101568, 101574, + 101579, 101585, 101590, 101596, 101601, 101607, 101612, 101618, 101623, + 101628, 101633, 101638, 101643, 101648, 101653, 101659, 101664, 0, 0, 0, + 0, 0, 0, 0, 0, 101669, 101673, 101677, 101681, 101685, 101691, 101695, + 101700, 101705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 101711, 101716, 101721, 101726, 101731, 101736, 101741, + 101746, 101751, 101756, 101761, 101766, 101771, 101776, 101781, 101786, + 101791, 101796, 101801, 0, 101806, 101811, 0, 0, 0, 0, 0, 101816, 101820, + 101824, 101829, 101834, 101840, 101845, 101850, 101855, 101860, 101865, + 101870, 101875, 101880, 101885, 101890, 101895, 101900, 101905, 101910, + 101915, 101920, 101925, 101930, 101935, 101940, 101945, 101950, 101954, + 101959, 101964, 101970, 101974, 0, 0, 0, 101978, 101984, 101988, 101993, + 101998, 102003, 102007, 102012, 102016, 102021, 102026, 102030, 102035, + 102040, 102044, 102048, 102053, 102058, 102062, 102067, 102072, 102077, + 102082, 102087, 102092, 102097, 102102, 0, 0, 0, 0, 0, 102107, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102112, 102117, 102122, 102127, + 102132, 102137, 102143, 102149, 102155, 102160, 102165, 102170, 102176, + 102182, 102188, 102193, 102199, 102204, 102210, 102216, 102221, 102227, + 102233, 102238, 102244, 102249, 102255, 102261, 102267, 102272, 102278, + 102284, 102290, 102295, 102300, 102305, 102310, 102315, 102321, 102327, + 102332, 102337, 102342, 102348, 102353, 102358, 102364, 102370, 102375, + 102382, 102388, 102393, 102399, 102404, 102410, 102415, 0, 0, 0, 0, + 102421, 102429, 102436, 102443, 102450, 102455, 102460, 102465, 102470, + 102475, 102480, 102485, 102490, 102495, 102501, 102507, 102513, 102519, + 102525, 102531, 0, 0, 102537, 102544, 102551, 102558, 102566, 102574, + 102582, 102590, 102598, 102606, 102612, 102618, 102624, 102631, 102638, + 102645, 102652, 102659, 102666, 102673, 102680, 102687, 102694, 102701, + 102708, 102715, 102722, 102729, 102737, 102745, 102753, 102762, 102771, + 102780, 102789, 102798, 102807, 102814, 102821, 102828, 102836, 102844, + 102852, 102860, 102868, 102876, 102884, 102888, 102893, 102898, 0, + 102904, 102909, 0, 0, 0, 0, 0, 102914, 102920, 102927, 102932, 102937, + 102941, 102946, 102951, 0, 102956, 102961, 102966, 0, 102971, 102976, + 102981, 102986, 102991, 102996, 103001, 103005, 103010, 103015, 103020, + 103024, 103028, 103033, 103038, 103043, 103047, 103051, 103055, 103059, + 103064, 103069, 103074, 103078, 103083, 103087, 103092, 103097, 103102, + 0, 0, 103107, 103113, 103118, 0, 0, 0, 0, 103123, 103127, 103131, 103135, + 103139, 103143, 103148, 103153, 103159, 103164, 0, 0, 0, 0, 0, 0, 0, + 103170, 103176, 103183, 103189, 103196, 103202, 103208, 103214, 103221, + 0, 0, 0, 0, 0, 0, 0, 103227, 103235, 103243, 103251, 103259, 103267, + 103275, 103283, 103291, 103299, 103307, 103315, 103323, 103331, 103339, + 103347, 103355, 103363, 103371, 103379, 103387, 103395, 103403, 103411, + 103419, 103427, 103435, 103443, 103451, 103459, 103466, 103474, 103482, + 103489, 103496, 103503, 103510, 103517, 103524, 103531, 103538, 103545, + 103552, 103559, 103566, 103573, 103580, 103587, 103594, 103601, 103608, + 103615, 103622, 103629, 103636, 103643, 103650, 103657, 103664, 103671, + 103678, 103685, 103691, 103698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103705, 103710, + 103715, 103720, 103725, 103730, 103735, 103740, 103745, 103750, 103755, + 103760, 103765, 103770, 103775, 103780, 103785, 103790, 103795, 103800, + 103805, 103810, 103815, 103820, 103825, 103830, 103835, 103840, 103845, + 103850, 103855, 103860, 103865, 103870, 103875, 103880, 103885, 103890, + 103896, 0, 0, 0, 0, 103902, 103906, 103910, 103915, 103920, 103926, + 103932, 103938, 103948, 103957, 103963, 103970, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 103978, 103982, 103987, 103992, 103997, 104002, 104007, 104012, + 104017, 104021, 104026, 104030, 104035, 104039, 104044, 104048, 104053, + 104058, 104063, 104068, 104073, 104078, 104083, 104088, 104093, 104098, + 104103, 104108, 104113, 104118, 104123, 104128, 104133, 104138, 104143, + 104148, 104153, 104158, 104163, 104168, 104173, 104178, 104183, 104188, + 104193, 104198, 104203, 104208, 104213, 104218, 104223, 104228, 104233, + 104238, 0, 0, 0, 104243, 104248, 104258, 104267, 104277, 104287, 104298, + 104309, 104316, 104323, 104330, 104337, 104344, 104351, 104358, 104365, + 104372, 104379, 104386, 104393, 104400, 104407, 104414, 104421, 104428, + 104435, 104442, 104449, 104456, 0, 0, 104463, 104469, 104475, 104481, + 104487, 104494, 104501, 104509, 104516, 104523, 104530, 104537, 104544, + 104551, 104558, 104565, 104572, 104579, 104586, 104593, 104600, 104607, + 104614, 104621, 104628, 104635, 104642, 0, 0, 0, 0, 0, 104649, 104655, + 104661, 104667, 104673, 104680, 104687, 104695, 104702, 104709, 104716, + 104723, 104730, 104737, 104744, 104751, 104758, 104765, 104772, 104779, + 104786, 104793, 104800, 104807, 104814, 104821, 0, 0, 0, 0, 0, 0, 0, + 104828, 104835, 104843, 104854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 104865, 104871, 104877, 104883, 104889, 104896, 104903, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 104911, 104918, 104925, 104933, 104940, 104947, 104954, 104961, + 104969, 104977, 104985, 104993, 105001, 105009, 105017, 105025, 105033, + 105041, 105049, 105057, 105065, 105073, 105081, 105089, 105097, 105105, + 105113, 105121, 105129, 105137, 105145, 105153, 105161, 105169, 105177, + 105185, 105193, 105201, 105209, 105217, 105225, 105233, 105241, 105249, + 105257, 105265, 105273, 105281, 105289, 105297, 105305, 105313, 105321, + 105329, 105337, 105345, 105353, 105361, 105369, 105377, 105385, 105393, + 105401, 105409, 105417, 105425, 105433, 105441, 105449, 105457, 105465, + 105473, 105481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105489, 105494, 105500, 105506, + 105512, 105518, 105524, 105530, 105536, 105542, 105547, 105554, 105560, + 105566, 105572, 105578, 105584, 105589, 105595, 105601, 105607, 105613, + 105619, 105625, 105631, 105637, 105643, 105649, 105654, 105660, 105668, + 105676, 105682, 105688, 105694, 105700, 105708, 105714, 105720, 105726, + 105732, 105738, 105744, 105749, 105755, 105763, 105771, 105777, 105783, + 105789, 105796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105802, 105807, + 105813, 105819, 105825, 105831, 105837, 105843, 105849, 105855, 105860, + 105867, 105873, 105879, 105885, 105891, 105897, 105902, 105908, 105914, + 105920, 105926, 105932, 105938, 105944, 105950, 105956, 105962, 105967, + 105973, 105981, 105989, 105995, 106001, 106007, 106013, 106021, 106027, + 106033, 106039, 106045, 106051, 106057, 106062, 106068, 106076, 106084, + 106090, 106096, 106102, 106109, 0, 0, 0, 0, 0, 0, 0, 106115, 106119, + 106123, 106128, 106133, 106139, 106144, 106150, 106157, 106163, 106169, + 106176, 106183, 106190, 106196, 106203, 106210, 106217, 106224, 106230, + 106237, 106244, 106250, 106257, 106263, 106270, 106276, 106282, 106288, + 106295, 106304, 106310, 106318, 106325, 106332, 106339, 106345, 106351, + 106357, 106363, 106369, 106376, 106385, 106392, 106399, 106406, 0, 0, 0, + 0, 0, 0, 0, 0, 106413, 106420, 106426, 106432, 106438, 106444, 106450, + 106456, 106462, 106468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 106474, 106478, 106482, 106486, 106490, 106494, 106498, + 106502, 106506, 106510, 106515, 106520, 106525, 106530, 106535, 106540, + 106545, 106550, 106555, 106561, 106567, 106573, 106580, 106587, 106594, + 106601, 106608, 106615, 106621, 106627, 106633, 0, 106639, 106645, + 106652, 106658, 106665, 106671, 106677, 106684, 106690, 106696, 106702, + 106708, 106714, 106720, 106726, 106732, 106739, 106750, 106756, 106762, + 106770, 106776, 106782, 106789, 106800, 106806, 106812, 106818, 106825, + 106836, 106841, 106846, 106851, 106856, 106861, 106867, 106873, 106879, + 106886, 106893, 0, 0, 0, 0, 0, 0, 0, 0, 106899, 106904, 106909, 106914, + 106919, 106924, 106929, 106934, 106939, 106944, 106949, 106954, 106959, + 106964, 106969, 106974, 106979, 106984, 106989, 106994, 106999, 107004, + 107010, 107015, 107022, 107027, 107034, 107040, 107046, 107052, 107058, + 107065, 107071, 107077, 107081, 107086, 107091, 107097, 107105, 107116, + 107125, 107135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107145, 107150, + 107155, 107160, 107165, 107170, 107175, 107180, 107185, 107190, 107195, + 107200, 107205, 107210, 107215, 107220, 107225, 107230, 107235, 107240, + 107245, 107250, 107255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107260, 107264, + 107268, 107272, 107276, 107280, 107283, 107287, 107290, 107294, 107297, + 107301, 107305, 107310, 107314, 107319, 107322, 107326, 107329, 107333, + 107336, 107340, 107344, 107348, 107352, 107356, 107360, 107364, 107368, + 107372, 107376, 107380, 107384, 107388, 107392, 107395, 107399, 107403, + 107407, 107410, 107413, 107417, 107421, 107425, 107428, 107431, 107434, + 107437, 107441, 107445, 107449, 107452, 107455, 107459, 107465, 107471, + 107477, 107482, 107489, 107493, 107498, 107502, 107507, 107512, 107518, + 107523, 107529, 107533, 107538, 107542, 107547, 107550, 107553, 107557, + 107562, 107568, 107573, 107579, 0, 0, 0, 0, 107584, 107587, 107590, + 107593, 107596, 107599, 107602, 107605, 107608, 107611, 107615, 107619, + 107623, 107627, 107631, 107635, 107639, 107643, 107647, 107652, 107656, + 107660, 107663, 107666, 107669, 107672, 107675, 107678, 107681, 107684, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107687, 107691, 107696, + 107701, 107706, 107710, 107715, 107719, 107724, 107728, 107733, 107737, + 107742, 107746, 107751, 107755, 107760, 107765, 107770, 107775, 107780, + 107785, 107790, 107795, 107800, 107805, 107810, 107815, 107820, 107825, + 107830, 107835, 107839, 107844, 107849, 107854, 107858, 107862, 107867, + 107872, 107877, 107881, 107885, 107889, 107893, 107898, 107903, 107908, + 107912, 107916, 107922, 107927, 107933, 107938, 107944, 107949, 107955, + 107960, 107966, 107971, 107976, 107981, 107986, 107990, 107995, 108001, + 108005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108010, 0, 0, 108015, 108022, + 108029, 108036, 108043, 108050, 108057, 108064, 108071, 108078, 108085, + 108092, 108099, 108106, 108113, 108120, 108127, 108134, 108141, 108148, + 108155, 108162, 108169, 108176, 108183, 0, 0, 0, 0, 0, 0, 0, 108190, + 108197, 108203, 108209, 108215, 108221, 108227, 108233, 108239, 108245, + 0, 0, 0, 0, 0, 0, 108251, 108256, 108261, 108266, 108271, 108275, 108279, + 108283, 108288, 108293, 108298, 108303, 108308, 108313, 108318, 108323, + 108328, 108333, 108338, 108343, 108348, 108353, 108358, 108363, 108368, + 108373, 108378, 108383, 108388, 108393, 108398, 108403, 108408, 108413, + 108418, 108423, 108428, 108433, 108438, 108443, 108448, 108453, 108459, + 108464, 108470, 108475, 108481, 108486, 108492, 108498, 108502, 108507, + 108511, 0, 108515, 108520, 108524, 108528, 108532, 108536, 108540, + 108544, 108548, 108552, 108556, 108561, 108565, 108570, 108575, 108580, + 108586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108592, 108596, 108600, 108604, + 108608, 108612, 108616, 108621, 108626, 108631, 108636, 108641, 108646, + 108651, 108656, 108661, 108666, 108671, 108676, 108681, 108685, 108690, + 108695, 108700, 108704, 108708, 108713, 108718, 108723, 108727, 108731, + 108735, 108740, 108744, 108748, 108753, 108758, 108763, 108768, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108773, 108778, 108783, 108788, 108792, 108797, 108801, + 108806, 108810, 108815, 108820, 108826, 108831, 108837, 108841, 108846, + 108850, 108855, 108859, 108864, 108869, 108874, 108879, 108884, 108889, + 108894, 108899, 108904, 108909, 108914, 108919, 108924, 108929, 108933, + 108938, 108943, 108948, 108952, 108956, 108961, 108966, 108971, 108975, + 108979, 108983, 108987, 108992, 108997, 109002, 109007, 109011, 109015, + 109021, 109026, 109032, 109037, 109043, 109049, 109056, 109062, 109069, + 109074, 109080, 109085, 109091, 109096, 109101, 109106, 109111, 109115, + 109119, 109124, 109129, 109133, 109138, 109143, 109148, 109156, 0, 0, + 109161, 109166, 109170, 109174, 109178, 109182, 109186, 109190, 109194, + 109198, 109202, 109206, 109211, 109215, 109220, 109226, 0, 109232, + 109237, 109242, 109247, 109252, 109257, 109262, 109267, 109272, 109277, + 109283, 109289, 109295, 109301, 109307, 109313, 109319, 109325, 109331, + 109338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109344, 109348, 109353, 109357, + 109361, 109365, 109370, 109374, 109379, 109383, 109388, 109393, 109398, + 109403, 109408, 109413, 109418, 109423, 0, 109428, 109433, 109438, + 109443, 109448, 109453, 109458, 109462, 109467, 109472, 109477, 109482, + 109486, 109490, 109495, 109500, 109505, 109510, 109514, 109518, 109522, + 109526, 109531, 109535, 109539, 109544, 109550, 109555, 109561, 109566, + 109571, 109577, 109582, 109588, 109593, 109598, 109603, 109608, 109612, + 109617, 109623, 109628, 109634, 109639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 109644, 109648, 109652, 109656, 109660, 109664, 109669, + 0, 109674, 0, 109679, 109684, 109689, 109694, 0, 109699, 109704, 109709, + 109714, 109719, 109724, 109729, 109734, 109738, 109743, 109748, 109753, + 109757, 109761, 109766, 0, 109771, 109776, 109780, 109784, 109788, + 109792, 109797, 109801, 109805, 109810, 109815, 0, 0, 0, 0, 0, 0, 109820, + 109824, 109829, 109833, 109838, 109842, 109847, 109851, 109856, 109860, + 109865, 109869, 109874, 109879, 109884, 109889, 109894, 109899, 109904, + 109909, 109914, 109919, 109924, 109929, 109934, 109939, 109944, 109949, + 109954, 109959, 109963, 109968, 109973, 109978, 109982, 109986, 109991, + 109996, 110001, 110006, 110010, 110014, 110018, 110022, 110027, 110032, + 110036, 110040, 110045, 110051, 110056, 110062, 110067, 110073, 110078, + 110084, 110089, 110095, 110100, 0, 0, 0, 0, 0, 110105, 110110, 110114, + 110118, 110122, 110126, 110130, 110134, 110138, 110142, 0, 0, 0, 0, 0, 0, + 110146, 110153, 110158, 110163, 0, 110168, 110172, 110177, 110181, + 110186, 110190, 110195, 110200, 0, 0, 110205, 110210, 0, 0, 110215, + 110220, 110225, 110229, 110234, 110239, 110244, 110249, 110254, 110259, + 110264, 110269, 110274, 110279, 110284, 110289, 110294, 110299, 110303, + 110308, 110313, 110318, 0, 110322, 110326, 110331, 110336, 110341, + 110345, 110349, 0, 110353, 110357, 0, 110362, 110367, 110372, 110377, + 110381, 0, 110385, 110389, 110394, 110399, 110405, 110410, 110416, + 110421, 110427, 110433, 0, 0, 110440, 110446, 0, 0, 110452, 110458, + 110464, 0, 0, 110469, 0, 0, 0, 0, 0, 0, 110473, 0, 0, 0, 0, 0, 110480, + 110485, 110492, 110500, 110506, 110512, 110518, 0, 0, 110525, 110531, + 110536, 110541, 110546, 110551, 110556, 0, 0, 0, 110561, 110566, 110571, + 110576, 110582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110587, 110591, 110596, + 110600, 110605, 110609, 110614, 110619, 110625, 110630, 110636, 110640, + 110645, 110649, 110654, 110658, 110663, 110668, 110673, 110678, 110683, + 110688, 110693, 110698, 110703, 110708, 110713, 110718, 110723, 110728, + 110733, 110738, 110742, 110747, 110752, 110757, 110761, 110766, 110770, + 110775, 110780, 110785, 110789, 110794, 110798, 110802, 110807, 110811, + 110816, 110821, 110826, 110831, 110835, 110839, 110845, 110850, 110856, + 110861, 110867, 110873, 110880, 110886, 110893, 110898, 110904, 110909, + 110915, 110920, 110925, 110930, 110935, 110940, 110945, 110951, 110955, + 110959, 110963, 110968, 110972, 110978, 110983, 110988, 110992, 110996, + 111000, 111004, 111008, 111012, 111016, 111020, 0, 111024, 0, 111029, + 111034, 111039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111046, 111050, 111054, 111059, + 111063, 111068, 111072, 111077, 111082, 111088, 111093, 111099, 111103, + 111108, 111112, 111117, 111121, 111126, 111131, 111136, 111141, 111146, + 111151, 111156, 111161, 111166, 111171, 111176, 111181, 111186, 111191, + 111195, 111200, 111205, 111210, 111214, 111218, 111223, 111228, 111233, + 111237, 111241, 111245, 111249, 111254, 111259, 111264, 111268, 111272, + 111278, 111283, 111289, 111294, 111300, 111306, 111313, 111319, 111326, + 111331, 111338, 111344, 111349, 111356, 111362, 111367, 111372, 111377, + 111382, 111387, 111392, 111396, 111401, 0, 0, 0, 0, 0, 0, 0, 0, 111405, + 111410, 111414, 111418, 111422, 111426, 111430, 111434, 111438, 111442, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111446, 111450, 111455, 111459, + 111464, 111468, 111473, 111478, 111484, 111489, 111495, 111499, 111504, + 111508, 111513, 111517, 111522, 111527, 111532, 111537, 111542, 111547, + 111552, 111557, 111562, 111567, 111572, 111577, 111582, 111587, 111591, + 111596, 111601, 111606, 111610, 111614, 111619, 111624, 111629, 111633, + 111637, 111641, 111645, 111650, 111655, 111660, 111664, 111668, 111674, + 111679, 111685, 111690, 111696, 111702, 0, 0, 111709, 111714, 111720, + 111725, 111731, 111736, 111741, 111746, 111751, 111756, 111761, 111765, + 111770, 111776, 111781, 111787, 111793, 111799, 111807, 111820, 111833, + 111846, 111860, 111875, 111883, 111894, 111903, 111913, 111923, 111933, + 111944, 111956, 111969, 111977, 111985, 111994, 112000, 112007, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 112015, 112019, 112024, 112028, 112033, 112037, + 112042, 112047, 112053, 112058, 112064, 112068, 112073, 112077, 112082, + 112086, 112091, 112096, 112101, 112106, 112111, 112116, 112121, 112126, + 112131, 112136, 112141, 112146, 112151, 112156, 112160, 112165, 112170, + 112175, 112179, 112183, 112188, 112193, 112198, 112202, 112206, 112210, + 112214, 112219, 112224, 112229, 112233, 112237, 112242, 112248, 112253, + 112259, 112264, 112270, 112276, 112283, 112289, 112296, 112301, 112307, + 112312, 112318, 112323, 112328, 112333, 112338, 112342, 112347, 112352, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112357, 112362, 112366, 112370, 112374, + 112378, 112382, 112386, 112390, 112394, 0, 0, 0, 0, 0, 0, 112398, 112404, + 112409, 112416, 112424, 112431, 112439, 112448, 112453, 112462, 112467, + 112475, 112484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 112494, 112498, 112503, 112507, 112512, 112516, 112521, 112525, 112530, + 112534, 112539, 112543, 112548, 112553, 112558, 112563, 112568, 112573, + 112578, 112583, 112588, 112593, 112598, 112603, 112608, 112613, 112617, + 112622, 112627, 112632, 112636, 112640, 112645, 112650, 112655, 112659, + 112663, 112667, 112671, 112676, 112681, 112685, 112689, 112694, 112699, + 112704, 112710, 112715, 112721, 112726, 112732, 112737, 112743, 112748, + 112754, 112759, 112764, 0, 0, 0, 0, 0, 0, 0, 112771, 112776, 112780, + 112784, 112788, 112792, 112796, 112800, 112804, 112808, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 112812, 112816, 112821, 112826, 112830, 112834, 112840, 112844, 112849, + 112854, 112858, 112863, 112868, 112873, 112877, 112881, 112885, 112890, + 112894, 112898, 112903, 112908, 112913, 112920, 112925, 112930, 112935, + 0, 0, 112942, 112949, 112956, 112965, 112970, 112976, 112981, 112987, + 112992, 112998, 113003, 113009, 113014, 113020, 113026, 0, 0, 0, 0, + 113031, 113036, 113040, 113044, 113048, 113052, 113056, 113060, 113064, + 113068, 113072, 113077, 113082, 113088, 113093, 113098, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113103, 113107, 113112, 113116, 113121, + 113125, 113130, 113134, 113139, 113143, 113148, 113152, 113157, 113162, + 113167, 113172, 113177, 113182, 113187, 113192, 113197, 113202, 113207, + 113212, 113217, 113222, 113226, 113231, 113236, 113241, 113245, 113249, + 113254, 113259, 113264, 113268, 113272, 113276, 113280, 113285, 113290, + 113295, 113299, 113303, 113308, 113314, 113319, 113325, 113330, 113336, + 113342, 113349, 113354, 113360, 113365, 113371, 113376, 113381, 113386, + 113391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 113396, 113404, 113411, 113419, 113427, 113434, 113442, + 113450, 113458, 113465, 113472, 113480, 113488, 113496, 113504, 113512, + 113520, 113528, 113536, 113544, 113552, 113560, 113568, 113576, 113584, + 113592, 113600, 113608, 113616, 113624, 113632, 113640, 113648, 113656, + 113663, 113671, 113679, 113686, 113694, 113702, 113710, 113717, 113724, + 113732, 113740, 113748, 113756, 113764, 113772, 113780, 113788, 113796, + 113804, 113812, 113820, 113828, 113836, 113844, 113852, 113860, 113868, + 113876, 113884, 113892, 113900, 113907, 113913, 113919, 113925, 113931, + 113937, 113943, 113949, 113955, 113961, 113968, 113975, 113982, 113989, + 113996, 114003, 114010, 114017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 114024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114030, 114034, 114039, 114043, 114048, + 114052, 114057, 114062, 0, 0, 114068, 114072, 114077, 114081, 114086, + 114090, 114095, 114100, 114105, 114110, 114115, 114120, 114125, 114130, + 114135, 114140, 114145, 114150, 114155, 114160, 114164, 114169, 114174, + 114179, 114183, 114187, 114192, 114197, 114202, 114206, 114210, 114214, + 114218, 114223, 114228, 114233, 114237, 114241, 114246, 114251, 114257, + 114262, 114268, 114273, 114279, 114285, 0, 0, 114292, 114297, 114303, + 114308, 114314, 114319, 114324, 114329, 114334, 114339, 114343, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 114350, 114355, 114361, 114368, 114374, 114380, 114387, 114393, 114400, + 114407, 114415, 114422, 114427, 114433, 114439, 114445, 114451, 114457, + 114463, 114469, 114475, 114481, 114487, 114493, 114499, 114505, 114510, + 114516, 114522, 114528, 114533, 114538, 114544, 114550, 114556, 114561, + 114567, 114573, 114579, 114585, 114591, 114597, 114603, 114608, 114613, + 114618, 114624, 114630, 114636, 114641, 114646, 114652, 114658, 114664, + 114670, 114679, 114688, 114694, 114700, 114707, 114714, 114721, 114728, + 114736, 114743, 114751, 114757, 114763, 114770, 114777, 114786, 114796, + 0, 0, 0, 0, 0, 0, 0, 0, 114801, 114805, 114810, 114816, 114821, 114826, + 114831, 114837, 114843, 114849, 114855, 114861, 114867, 114871, 114876, + 114881, 114886, 114891, 114896, 114901, 114906, 114911, 114916, 114921, + 114926, 114931, 114936, 114941, 114945, 114950, 114955, 114960, 114964, + 114968, 114973, 114978, 114983, 114987, 114992, 114997, 115002, 115007, + 115012, 115017, 115021, 115025, 115029, 115034, 115039, 115044, 115048, + 115052, 115057, 115062, 115067, 115073, 115079, 115086, 115092, 115099, + 115106, 115113, 115120, 115127, 115134, 115141, 115147, 115153, 115160, + 115167, 115174, 115179, 115184, 115189, 115193, 115198, 115203, 115209, + 115214, 115230, 115244, 115255, 115261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115267, 115275, + 115283, 115291, 115299, 115308, 115317, 115326, 115335, 115343, 115352, + 115361, 115369, 115378, 115387, 115395, 115404, 115412, 115421, 115429, + 115438, 115447, 115455, 115463, 115471, 115479, 115487, 115496, 115505, + 115515, 115525, 115535, 115545, 115555, 115564, 115574, 115584, 115594, + 115605, 115615, 115627, 115639, 115650, 115664, 115675, 115685, 115697, + 115708, 115718, 115730, 115742, 115753, 115764, 115774, 115784, 115796, + 115807, 0, 0, 0, 0, 0, 0, 0, 115819, 115823, 115828, 115832, 115837, + 115841, 115846, 115851, 115857, 0, 115862, 115866, 115871, 115875, + 115880, 115884, 115889, 115894, 115899, 115904, 115909, 115914, 115919, + 115924, 115929, 115934, 115939, 115944, 115949, 115954, 115958, 115963, + 115968, 115973, 115977, 115981, 115986, 115991, 115996, 116000, 116004, + 116008, 116012, 116017, 116022, 116027, 116031, 116035, 116041, 116046, + 116052, 116057, 116063, 116069, 116076, 0, 116082, 116087, 116093, + 116098, 116104, 116109, 116114, 116119, 116124, 116129, 116133, 116138, + 116144, 116150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116156, 116161, 116165, + 116169, 116173, 116177, 116181, 116185, 116189, 116193, 116197, 116201, + 116205, 116209, 116213, 116217, 116221, 116225, 116229, 116233, 116238, + 116243, 116248, 116253, 116258, 116263, 116268, 116273, 116278, 0, 0, 0, + 116285, 116290, 116295, 116299, 116304, 116309, 116314, 116319, 116324, + 116329, 116334, 116338, 116343, 116348, 116352, 116356, 116361, 116366, + 116370, 116375, 116380, 116385, 116390, 116395, 116400, 116405, 116409, + 116413, 116417, 116422, 116426, 116430, 0, 0, 116434, 116440, 116447, + 116454, 116461, 116468, 116475, 116482, 116489, 116495, 116502, 116509, + 116515, 116521, 116528, 116535, 116541, 116548, 116555, 116562, 116569, + 116576, 0, 116583, 116589, 116595, 116601, 116608, 116614, 116620, + 116626, 116632, 116637, 116642, 116647, 116652, 116657, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116662, 116667, + 116673, 116678, 116684, 116689, 116695, 0, 116700, 116706, 0, 116711, + 116717, 116722, 116728, 116734, 116740, 116746, 116752, 116758, 116764, + 116770, 116776, 116782, 116788, 116794, 116800, 116806, 116811, 116817, + 116823, 116829, 116834, 116839, 116845, 116851, 116857, 116862, 116867, + 116872, 116877, 116883, 116889, 116895, 116900, 116905, 116911, 116917, + 116923, 116929, 116936, 116942, 116949, 116955, 116962, 0, 0, 0, 116969, + 0, 116975, 116982, 0, 116988, 116995, 117001, 117007, 117013, 117019, + 117025, 117030, 117035, 0, 0, 0, 0, 0, 0, 0, 0, 117040, 117046, 117051, + 117056, 117061, 117066, 117071, 117076, 117081, 117086, 0, 0, 0, 0, 0, 0, + 117091, 117096, 117102, 117107, 117113, 117118, 0, 117124, 117130, 0, + 117136, 117142, 117148, 117153, 117159, 117165, 117171, 117176, 117181, + 117187, 117192, 117198, 117203, 117209, 117215, 117221, 117227, 117232, + 117238, 117244, 117250, 117256, 117262, 117268, 117274, 117280, 117286, + 117292, 117297, 117303, 117308, 117313, 117318, 117325, 117331, 117338, + 117344, 0, 117351, 117358, 0, 117365, 117372, 117379, 117385, 117391, + 117396, 0, 0, 0, 0, 0, 0, 0, 117401, 117407, 117412, 117417, 117422, + 117427, 117432, 117437, 117442, 117447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 117452, 117456, 117461, 117466, 117470, 117475, 117479, 117483, + 117488, 117492, 117497, 117502, 117507, 117511, 117515, 117519, 117524, + 117528, 117532, 117536, 117541, 117546, 117551, 117556, 117560, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117567, + 117572, 117577, 117582, 117587, 117592, 117597, 117602, 117607, 117612, + 117617, 117622, 117627, 117632, 117637, 117642, 117647, 117652, 117657, + 117662, 117667, 117675, 117679, 117683, 117687, 117691, 117695, 117699, + 117703, 117707, 117711, 117715, 117719, 117723, 117727, 117731, 117735, + 117741, 117747, 117751, 117757, 117763, 117768, 117772, 117777, 117781, + 117785, 117791, 117797, 117801, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117805, 117813, 117816, 117821, 117827, 117835, 117840, 117846, 117854, + 117860, 117866, 117870, 117874, 117881, 117890, 117897, 117906, 117912, + 117921, 117928, 117935, 117942, 117952, 117958, 117962, 117969, 117978, + 117988, 117995, 118002, 118006, 118010, 118017, 118027, 118031, 118038, + 118045, 118052, 118058, 118065, 118072, 118079, 118086, 118090, 118094, + 118098, 118105, 118109, 118116, 118123, 118137, 118146, 118150, 118154, + 118158, 118165, 118169, 118173, 118177, 118185, 118193, 118212, 118222, + 118242, 118246, 118250, 118254, 118258, 118262, 118266, 118270, 118277, + 118281, 118284, 118288, 118292, 118298, 118305, 118314, 118318, 118327, + 118336, 118344, 118348, 118355, 118359, 118363, 118367, 118371, 118382, + 118391, 118400, 118409, 118418, 118430, 118439, 118448, 118457, 118465, + 118474, 118486, 118495, 118503, 118512, 118524, 118533, 118542, 118554, + 118563, 118572, 118584, 118593, 118597, 118601, 118605, 118609, 118613, + 118617, 118621, 118628, 118632, 118636, 118647, 118651, 118655, 118662, + 118668, 118674, 118678, 118685, 118689, 118693, 118697, 118701, 118705, + 118709, 118715, 118723, 118727, 118731, 118734, 118741, 118753, 118757, + 118769, 118776, 118783, 118790, 118797, 118803, 118807, 118811, 118815, + 118819, 118826, 118835, 118842, 118850, 118858, 118864, 118868, 118872, + 118876, 118880, 118886, 118895, 118907, 118914, 118921, 118930, 118941, + 118947, 118956, 118965, 118972, 118981, 118988, 118994, 119004, 119011, + 119018, 119025, 119032, 119036, 119042, 119046, 119057, 119065, 119074, + 119086, 119093, 119100, 119110, 119117, 119126, 119133, 119142, 119149, + 119156, 119166, 119173, 119180, 119189, 119196, 119208, 119217, 119224, + 119231, 119238, 119247, 119257, 119270, 119277, 119286, 119296, 119303, + 119312, 119325, 119332, 119339, 119346, 119356, 119366, 119372, 119382, + 119389, 119396, 119406, 119412, 119419, 119426, 119433, 119443, 119450, + 119457, 119464, 119470, 119477, 119487, 119494, 119498, 119506, 119510, + 119522, 119526, 119540, 119544, 119548, 119552, 119556, 119562, 119569, + 119577, 119581, 119585, 119589, 119593, 119600, 119604, 119610, 119616, + 119624, 119628, 119635, 119643, 119647, 119651, 119657, 119661, 119670, + 119679, 119686, 119696, 119702, 119706, 119710, 119718, 119725, 119732, + 119738, 119742, 119750, 119754, 119761, 119773, 119780, 119790, 119796, + 119800, 119809, 119816, 119825, 119829, 119833, 119840, 119844, 119848, + 119852, 119856, 119859, 119865, 119871, 119875, 119879, 119886, 119893, + 119900, 119907, 119914, 119921, 119928, 119935, 119941, 119945, 119949, + 119956, 119963, 119970, 119977, 119984, 119988, 119991, 119996, 120000, + 120004, 120013, 120022, 120026, 120030, 120036, 120042, 120059, 120065, + 120069, 120078, 120082, 120086, 120093, 120101, 120109, 120115, 120119, + 120123, 120127, 120131, 120134, 120140, 120147, 120157, 120164, 120171, + 120178, 120184, 120191, 120198, 120205, 120212, 120219, 120228, 120235, + 120247, 120254, 120261, 120271, 120282, 120289, 120296, 120303, 120310, + 120317, 120324, 120331, 120338, 120345, 120352, 120362, 120372, 120382, + 120389, 120399, 120406, 120413, 120420, 120427, 120433, 120440, 120447, + 120454, 120461, 120468, 120475, 120482, 120489, 120495, 120502, 120509, + 120518, 120525, 120532, 120536, 120544, 120548, 120552, 120556, 120560, + 120564, 120571, 120575, 120584, 120588, 120595, 120603, 120607, 120611, + 120615, 120628, 120644, 120648, 120652, 120659, 120665, 120672, 120676, + 120680, 120684, 120688, 120692, 120699, 120703, 120721, 120725, 120729, + 120736, 120740, 120744, 120750, 120754, 120758, 120766, 120770, 120774, + 120777, 120781, 120787, 120798, 120807, 120816, 120823, 120830, 120841, + 120848, 120855, 120862, 120869, 120876, 120883, 120890, 120900, 120906, + 120913, 120923, 120932, 120939, 120948, 120958, 120965, 120972, 120979, + 120986, 120998, 121005, 121012, 121019, 121026, 121033, 121043, 121050, + 121057, 121067, 121080, 121092, 121099, 121109, 121116, 121123, 121130, + 121144, 121150, 121158, 121168, 121178, 121185, 121192, 121198, 121202, + 121209, 121219, 121225, 121238, 121242, 121246, 121253, 121257, 121264, + 121274, 121278, 121282, 121286, 121290, 121294, 121301, 121305, 121312, + 121319, 121326, 121335, 121344, 121354, 121361, 121368, 121375, 121385, + 121392, 121402, 121409, 121419, 121426, 121433, 121443, 121453, 121460, + 121466, 121474, 121482, 121488, 121494, 121498, 121502, 121509, 121517, + 121523, 121527, 121531, 121535, 121542, 121554, 121557, 121564, 121570, + 121574, 121578, 121582, 121586, 121590, 121594, 121598, 121602, 121606, + 121610, 121617, 121621, 121627, 121631, 121635, 121639, 121645, 121652, + 121659, 121666, 121677, 121685, 121689, 121695, 121704, 121711, 121717, + 121720, 121724, 121728, 121734, 121743, 121751, 121755, 121761, 121765, + 121769, 121773, 121779, 121786, 121792, 121796, 121802, 121806, 121810, + 121819, 121831, 121835, 121842, 121849, 121859, 121866, 121878, 121885, + 121892, 121899, 121910, 121920, 121933, 121943, 121950, 121954, 121958, + 121962, 121966, 121975, 121984, 121993, 122010, 122019, 122025, 122032, + 122040, 122053, 122057, 122066, 122075, 122084, 122093, 122104, 122113, + 122121, 122130, 122139, 122148, 122157, 122167, 122170, 122174, 122178, + 122182, 122186, 122190, 122196, 122203, 122210, 122217, 122223, 122229, + 122236, 122242, 122249, 122257, 122261, 122268, 122275, 122282, 122290, + 122293, 122297, 122301, 122305, 122308, 122314, 122318, 122324, 122331, + 122338, 122344, 122351, 122358, 122365, 122372, 122379, 122386, 122393, + 122400, 122407, 122414, 122421, 122428, 122435, 122442, 122448, 122452, + 122461, 122465, 122469, 122473, 122477, 122483, 122490, 122497, 122504, + 122511, 122518, 122524, 122532, 122536, 122540, 122544, 122548, 122554, + 122571, 122588, 122592, 122596, 122600, 122604, 122608, 122612, 122618, + 122625, 122629, 122635, 122642, 122649, 122656, 122663, 122670, 122679, + 122686, 122693, 122700, 122707, 122711, 122715, 122721, 122733, 122737, + 122741, 122750, 122754, 122758, 122762, 122768, 122772, 122776, 122785, + 122789, 122793, 122797, 122804, 122808, 122812, 122816, 122820, 122824, + 122828, 122832, 122835, 122841, 122848, 122855, 122861, 122865, 122882, + 122888, 122892, 122898, 122904, 122910, 122916, 122922, 122928, 122932, + 122936, 122940, 122946, 122950, 122956, 122960, 122964, 122971, 122978, + 122995, 122999, 123003, 123007, 123011, 123015, 123027, 123030, 123035, + 123040, 123055, 123065, 123077, 123081, 123085, 123089, 123095, 123102, + 123109, 123119, 123131, 123137, 123143, 123152, 123156, 123160, 123167, + 123177, 123184, 123190, 123194, 123198, 123205, 123211, 123215, 123221, + 123225, 123233, 123239, 123243, 123251, 123259, 123266, 123272, 123279, + 123286, 123296, 123306, 123310, 123314, 123318, 123322, 123328, 123335, + 123341, 123348, 123355, 123362, 123371, 123378, 123385, 123391, 123398, + 123405, 123412, 123419, 123426, 123433, 123439, 123446, 123453, 123460, + 123469, 123476, 123483, 123487, 123493, 123497, 123503, 123510, 123517, + 123524, 123528, 123532, 123536, 123540, 123544, 123551, 123555, 123559, + 123565, 123573, 123577, 123581, 123585, 123589, 123596, 123600, 123604, + 123612, 123616, 123620, 123624, 123628, 123634, 123638, 123642, 123648, + 123655, 123661, 123668, 123680, 123684, 123691, 123698, 123705, 123712, + 123724, 123731, 123735, 123739, 123743, 123750, 123757, 123764, 123771, + 123781, 123788, 123794, 123801, 123808, 123815, 123822, 123831, 123841, + 123848, 123852, 123859, 123863, 123867, 123871, 123878, 123885, 123895, + 123901, 123905, 123914, 123918, 123925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123929, 123935, + 123941, 123948, 123955, 123962, 123969, 123976, 123983, 123989, 123996, + 124003, 124010, 124017, 124024, 124031, 124037, 124043, 124049, 124055, + 124061, 124067, 124073, 124079, 124085, 124092, 124099, 124106, 124113, + 124120, 124127, 124133, 124139, 124145, 124152, 124159, 124165, 124171, + 124180, 124187, 124194, 124201, 124208, 124215, 124222, 124228, 124234, + 124240, 124249, 124256, 124263, 124274, 124285, 124291, 124297, 124303, + 124312, 124319, 124326, 124336, 124346, 124357, 124368, 124380, 124393, + 124404, 124415, 124427, 124440, 124451, 124462, 124473, 124484, 124495, + 124507, 124515, 124523, 124532, 124541, 124550, 124556, 124562, 124568, + 124575, 124585, 124592, 124602, 124607, 124612, 124618, 124624, 124632, + 124640, 124649, 124660, 124671, 124679, 124687, 124696, 124705, 124713, + 124720, 124728, 124736, 124743, 124750, 124759, 124768, 124777, 124786, + 124795, 0, 124804, 124815, 124822, 124830, 124838, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 124846, 124855, 124862, 124869, 124878, 124885, 124892, + 124899, 124909, 124916, 124923, 124930, 124938, 124945, 124952, 124959, + 124970, 124977, 124984, 124991, 124998, 125005, 125014, 125021, 125027, + 125034, 125043, 125050, 125057, 125064, 125074, 125081, 125088, 125098, + 125108, 125115, 125122, 125129, 125136, 125143, 125150, 125159, 125166, + 125173, 125179, 125187, 125196, 125205, 125216, 125224, 125233, 125242, + 125251, 125260, 125267, 125274, 125283, 125295, 125305, 125312, 125319, + 125329, 125339, 125348, 125358, 125365, 125375, 125382, 125389, 125396, + 125406, 125416, 125423, 125430, 125440, 125446, 125457, 125466, 125476, + 125484, 125497, 125504, 125510, 125518, 125525, 125535, 125539, 125543, + 125547, 125551, 125555, 125559, 125563, 125572, 125576, 125583, 125587, + 125591, 125595, 125599, 125603, 125607, 125611, 125615, 125619, 125623, + 125627, 125631, 125635, 125639, 125643, 125647, 125651, 125655, 125659, + 125666, 125673, 125683, 125696, 125706, 125710, 125714, 125718, 125722, + 125726, 125730, 125734, 125738, 125742, 125746, 125750, 125757, 125764, + 125775, 125782, 125788, 125795, 125802, 125809, 125816, 125823, 125827, + 125831, 125838, 125845, 125852, 125861, 125868, 125881, 125891, 125898, + 125905, 125909, 125913, 125922, 125929, 125936, 125943, 125956, 125963, + 125970, 125980, 125990, 125999, 126006, 126013, 126020, 126027, 126034, + 126041, 126051, 126057, 126065, 126072, 126080, 126087, 126098, 126105, + 126111, 126118, 126125, 126132, 126139, 126149, 126159, 126166, 126173, + 126182, 126190, 126196, 126203, 126210, 126217, 126224, 126228, 126238, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126248, 126252, 126256, 126260, + 126264, 126268, 126272, 126276, 126280, 126284, 126288, 126292, 126296, + 126300, 126304, 126308, 126312, 126316, 126320, 126324, 126328, 126332, + 126336, 126340, 126344, 126348, 126352, 126356, 126360, 126364, 126368, + 126372, 126376, 126380, 126384, 126388, 126392, 126396, 126400, 126404, + 126408, 126412, 126416, 126420, 126424, 126428, 126432, 126436, 126440, + 126444, 126448, 126452, 126456, 126460, 126464, 126468, 126472, 126476, + 126480, 126484, 126488, 126492, 126496, 126500, 126504, 126508, 126512, + 126516, 126520, 126524, 126528, 126532, 126536, 126540, 126544, 126548, + 126552, 126556, 126560, 126564, 126568, 126572, 126576, 126580, 126584, + 126588, 126592, 126596, 126600, 126604, 126608, 126612, 126616, 126620, + 126624, 126628, 126632, 126636, 126640, 126644, 126648, 126652, 126656, + 126660, 126664, 126668, 126672, 126676, 126680, 126684, 126688, 126692, + 126696, 126700, 126704, 126708, 126712, 126716, 126720, 126724, 126728, + 126732, 126736, 126740, 126744, 126748, 126752, 126756, 126760, 126764, + 126768, 126772, 126776, 126780, 126784, 126788, 126792, 126796, 126800, + 126804, 126808, 126812, 126816, 126820, 126824, 126828, 126832, 126836, + 126840, 126844, 126848, 126852, 126856, 126860, 126864, 126868, 126872, + 126876, 126880, 126884, 126888, 126892, 126896, 126900, 126904, 126908, + 126912, 126916, 126920, 126924, 126928, 126932, 126936, 126940, 126944, + 126948, 126952, 126956, 126960, 126964, 126968, 126972, 126976, 126980, + 126984, 126988, 126992, 126996, 127000, 127004, 127008, 127012, 127016, + 127020, 127024, 127028, 127032, 127036, 127040, 127044, 127048, 127052, + 127056, 127060, 127064, 127068, 127072, 127076, 127080, 127084, 127088, + 127092, 127096, 127100, 127104, 127108, 127112, 127116, 127120, 127124, + 127128, 127132, 127136, 127140, 127144, 127148, 127152, 127156, 127160, + 127164, 127168, 127172, 127176, 127180, 127184, 127188, 127192, 127196, + 127200, 127204, 127208, 127212, 127216, 127220, 127224, 127228, 127232, + 127236, 127240, 127244, 127248, 127252, 127256, 127260, 127264, 127268, + 127272, 127276, 127280, 127284, 127288, 127292, 127296, 127300, 127304, + 127308, 127312, 127316, 127320, 127324, 127328, 127332, 127336, 127340, + 127344, 127348, 127352, 127356, 127360, 127364, 127368, 127372, 127376, + 127380, 127384, 127388, 127392, 127396, 127400, 127404, 127408, 127412, + 127416, 127420, 127424, 127428, 127432, 127436, 127440, 127444, 127448, + 127452, 127456, 127460, 127464, 127468, 127472, 127476, 127480, 127484, + 127488, 127492, 127496, 127500, 127504, 127508, 127512, 127516, 127520, + 127524, 127528, 127532, 127536, 127540, 127544, 127548, 127552, 127556, + 127560, 127564, 127568, 127572, 127576, 127580, 127584, 127588, 127592, + 127596, 127600, 127604, 127608, 127612, 127616, 127620, 127624, 127628, + 127632, 127636, 127640, 127644, 127648, 127652, 127656, 127660, 127664, + 127668, 127672, 127676, 127680, 127684, 127688, 127692, 127696, 127700, + 127704, 127708, 127712, 127716, 127720, 127724, 127728, 127732, 127736, + 127740, 127744, 127748, 127752, 127756, 127760, 127764, 127768, 127772, + 127776, 127780, 127784, 127788, 127792, 127796, 127800, 127804, 127808, + 127812, 127816, 127820, 127824, 127828, 127832, 127836, 127840, 127844, + 127848, 127852, 127856, 127860, 127864, 127868, 127872, 127876, 127880, + 127884, 127888, 127892, 127896, 127900, 127904, 127908, 127912, 127916, + 127920, 127924, 127928, 127932, 127936, 127940, 127944, 127948, 127952, + 127956, 127960, 127964, 127968, 127972, 127976, 127980, 127984, 127988, + 127992, 127996, 128000, 128004, 128008, 128012, 128016, 128020, 128024, + 128028, 128032, 128036, 128040, 128044, 128048, 128052, 128056, 128060, + 128064, 128068, 128072, 128076, 128080, 128084, 128088, 128092, 128096, + 128100, 128104, 128108, 128112, 128116, 128120, 128124, 128128, 128132, + 128136, 128140, 128144, 128148, 128152, 128156, 128160, 128164, 128168, + 128172, 128176, 128180, 128184, 128188, 128192, 128196, 128200, 128204, + 128208, 128212, 128216, 128220, 128224, 128228, 128232, 128236, 128240, + 128244, 128248, 128252, 128256, 128260, 128264, 128268, 128272, 128276, + 128280, 128284, 128288, 128292, 128296, 128300, 128304, 128308, 128312, + 128316, 128320, 128324, 128328, 128332, 128336, 128340, 128344, 128348, + 128352, 128356, 128360, 128364, 128368, 128372, 128376, 128380, 128384, + 128388, 128392, 128396, 128400, 128404, 128408, 128412, 128416, 128420, + 128424, 128428, 128432, 128436, 128440, 128444, 128448, 128452, 128456, + 128460, 128464, 128468, 128472, 128476, 128480, 128484, 128488, 128492, + 128496, 128500, 128504, 128508, 128512, 128516, 128520, 128524, 128528, + 128532, 128536, 128540, 128544, 128548, 128552, 128556, 128560, 128564, + 128568, 128572, 128576, 128580, 128584, 128588, 128592, 128596, 128600, + 128604, 128608, 128612, 128616, 128620, 128624, 128628, 128632, 128636, + 128640, 128644, 128648, 128652, 128656, 128660, 128664, 128668, 128672, + 128676, 128680, 128684, 128688, 128692, 128696, 128700, 128704, 128708, + 128712, 128716, 128720, 128724, 128728, 128732, 128736, 128740, 128744, + 128748, 128752, 128756, 128760, 128764, 128768, 128772, 128776, 128780, + 128784, 128788, 128792, 128796, 128800, 128804, 128808, 128812, 128816, + 128820, 128824, 128828, 128832, 128836, 128840, 128844, 128848, 128852, + 128856, 128860, 128864, 128868, 128872, 128876, 128880, 128884, 128888, + 128892, 128896, 128900, 128904, 128908, 128912, 128916, 128920, 128924, + 128928, 128932, 128936, 128940, 128944, 128948, 128952, 128956, 128960, + 128964, 128968, 128972, 128976, 128980, 128984, 128988, 128992, 128996, + 129000, 129004, 129008, 129012, 129016, 129020, 129024, 129028, 129032, + 129036, 129040, 129044, 129048, 129052, 129056, 129060, 129064, 129068, + 129072, 129076, 129080, 129084, 129088, 129092, 129096, 129100, 129104, + 129108, 129112, 129116, 129120, 129124, 129128, 129132, 129136, 129140, + 129144, 129148, 129152, 129156, 129160, 129164, 129168, 129172, 129176, + 129180, 129184, 129188, 129192, 129196, 129200, 129204, 129208, 129212, + 129216, 129220, 129224, 129228, 129232, 129236, 129240, 129244, 129248, + 129252, 129256, 129260, 129264, 129268, 129272, 129276, 129280, 129284, + 129288, 129292, 129296, 129300, 129304, 129308, 129312, 129316, 129320, + 129324, 129328, 129332, 129336, 129340, 129344, 129348, 129352, 129356, + 129360, 129364, 129368, 129372, 129376, 129380, 129384, 129388, 129392, + 129396, 129400, 129404, 129408, 129412, 129416, 129420, 129424, 129428, + 129432, 129436, 129440, 129444, 129448, 129452, 129456, 129460, 129464, + 129468, 129472, 129476, 129480, 129484, 129488, 129492, 129496, 129500, + 129504, 129508, 129512, 129516, 129520, 129524, 129528, 129532, 129536, + 129540, 129544, 129548, 129552, 129556, 129560, 129564, 129568, 129572, + 129576, 129580, 129584, 129588, 129592, 129596, 129600, 129604, 129608, + 129612, 129616, 129620, 129624, 129628, 129632, 129636, 129640, 129644, + 129648, 129652, 129656, 129660, 129664, 129668, 129672, 129676, 129680, + 129684, 129688, 129692, 129696, 129700, 129704, 129708, 129712, 129716, + 129720, 129724, 129728, 129732, 129736, 129740, 129744, 129748, 129752, + 129756, 129760, 129764, 129768, 129772, 129776, 129780, 129784, 129788, + 129792, 129796, 129800, 129804, 129808, 129812, 129816, 129820, 129824, + 129828, 129832, 129836, 129840, 129844, 129848, 129852, 129856, 129860, + 129864, 129868, 129872, 129876, 129880, 129884, 129888, 129892, 129896, + 129900, 129904, 129908, 129912, 129916, 129920, 129924, 129928, 129932, + 129936, 129940, 129944, 129948, 129952, 129956, 129960, 129964, 129968, + 129972, 129976, 129980, 129984, 129988, 129992, 129996, 130000, 130004, + 130008, 130012, 130016, 130020, 130024, 130028, 130032, 130036, 130040, + 130044, 130048, 130052, 130056, 130060, 130064, 130068, 130072, 130076, + 130080, 130084, 130088, 130092, 130096, 130100, 130104, 130108, 130112, + 130116, 130120, 130124, 130128, 130132, 130136, 130140, 130144, 130148, + 130152, 130156, 130160, 130164, 130168, 130172, 130176, 130180, 130184, + 130188, 130192, 130196, 130200, 130204, 130208, 130212, 130216, 130220, + 130224, 130228, 130232, 130236, 130240, 130244, 130248, 130252, 130256, + 130260, 130264, 130268, 130272, 130276, 130280, 130284, 130288, 130292, + 130296, 130300, 130304, 130308, 130312, 130316, 130320, 130324, 130328, + 130332, 130336, 130340, 130344, 130348, 130352, 130356, 130360, 130364, + 130368, 130372, 130376, 130380, 130384, 130388, 130392, 130396, 130400, + 130404, 130408, 130412, 130416, 130420, 130424, 130428, 130432, 130436, + 130440, 130444, 130448, 130452, 130456, 130460, 130464, 130468, 130472, + 130476, 130480, 130484, 130488, 130492, 130496, 130500, 130504, 130508, + 130512, 130516, 130520, 130524, 130528, 0, 130532, 130537, 130543, + 130553, 130563, 130573, 130583, 130589, 130595, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130601, 130605, 130609, + 130613, 130617, 130621, 130625, 130629, 130633, 130637, 130641, 130645, + 130649, 130653, 130657, 130661, 130665, 130669, 130673, 130677, 130681, + 130685, 130689, 130693, 130697, 130701, 130705, 130709, 130713, 130717, + 130721, 130725, 130729, 130733, 130737, 130741, 130745, 130749, 130753, + 130757, 130761, 130765, 130769, 130773, 130777, 130781, 130785, 130789, + 130793, 130797, 130801, 130805, 130809, 130813, 130817, 130821, 130825, + 130829, 130833, 130837, 130841, 130845, 130849, 130853, 130857, 130861, + 130865, 130869, 130873, 130877, 130881, 130885, 130889, 130893, 130897, + 130901, 130905, 130909, 130913, 130917, 130921, 130925, 130929, 130933, + 130937, 130941, 130945, 130949, 130953, 130957, 130961, 130965, 130969, + 130973, 130977, 130981, 130985, 130989, 130993, 130997, 131001, 131005, + 131009, 131013, 131017, 131021, 131025, 131029, 131033, 131037, 131041, + 131045, 131049, 131053, 131057, 131061, 131065, 131069, 131073, 131077, + 131081, 131085, 131089, 131093, 131097, 131101, 131105, 131109, 131113, + 131117, 131121, 131125, 131129, 131133, 131137, 131141, 131145, 131149, + 131153, 131157, 131161, 131165, 131169, 131173, 131177, 131181, 131185, + 131189, 131193, 131197, 131201, 131205, 131209, 131213, 131217, 131221, + 131225, 131229, 131233, 131237, 131241, 131245, 131249, 131253, 131257, + 131261, 131265, 131269, 131273, 131277, 131281, 131285, 131289, 131293, + 131297, 131301, 131305, 131309, 131313, 131317, 131321, 131325, 131329, + 131333, 131337, 131341, 131345, 131349, 131353, 131357, 131361, 131365, + 131369, 131373, 131377, 131381, 131385, 131389, 131393, 131397, 131401, + 131405, 131409, 131413, 131417, 131421, 131425, 131429, 131433, 131437, + 131441, 131445, 131449, 131453, 131457, 131461, 131465, 131469, 131473, + 131477, 131481, 131485, 131489, 131493, 131497, 131501, 131505, 131509, + 131513, 131517, 131521, 131525, 131529, 131533, 131537, 131541, 131545, + 131549, 131553, 131557, 131561, 131565, 131569, 131573, 131577, 131581, + 131585, 131589, 131593, 131597, 131601, 131605, 131609, 131613, 131617, + 131621, 131625, 131629, 131633, 131637, 131641, 131645, 131649, 131653, + 131657, 131661, 131665, 131669, 131673, 131677, 131681, 131685, 131689, + 131693, 131697, 131701, 131705, 131709, 131713, 131717, 131721, 131725, + 131729, 131733, 131737, 131741, 131745, 131749, 131753, 131757, 131761, + 131765, 131769, 131773, 131777, 131781, 131785, 131789, 131793, 131797, + 131801, 131805, 131809, 131813, 131817, 131821, 131825, 131829, 131833, + 131837, 131841, 131845, 131849, 131853, 131857, 131861, 131865, 131869, + 131873, 131877, 131881, 131885, 131889, 131893, 131897, 131901, 131905, + 131909, 131913, 131917, 131921, 131925, 131929, 131933, 131937, 131941, + 131945, 131949, 131953, 131957, 131961, 131965, 131969, 131973, 131977, + 131981, 131985, 131989, 131993, 131997, 132001, 132005, 132009, 132013, + 132017, 132021, 132025, 132029, 132033, 132037, 132041, 132045, 132049, + 132053, 132057, 132061, 132065, 132069, 132073, 132077, 132081, 132085, + 132089, 132093, 132097, 132101, 132105, 132109, 132113, 132117, 132121, + 132125, 132129, 132133, 132137, 132141, 132145, 132149, 132153, 132157, + 132161, 132165, 132169, 132173, 132177, 132181, 132185, 132189, 132193, + 132197, 132201, 132205, 132209, 132213, 132217, 132221, 132225, 132229, + 132233, 132237, 132241, 132245, 132249, 132253, 132257, 132261, 132265, + 132269, 132273, 132277, 132281, 132285, 132289, 132293, 132297, 132301, + 132305, 132309, 132313, 132317, 132321, 132325, 132329, 132333, 132343, + 132347, 132351, 132355, 132359, 132363, 132367, 132371, 132375, 132379, + 132383, 132387, 132392, 132396, 132400, 132404, 132408, 132412, 132416, + 132420, 132424, 132428, 132432, 132436, 132440, 132444, 132448, 132452, + 132456, 132465, 132474, 132478, 132482, 132486, 132490, 132494, 132498, + 132502, 132506, 132510, 132514, 132518, 132522, 132526, 132530, 132534, + 132538, 132542, 132546, 132550, 132554, 132558, 132562, 132566, 132570, + 132574, 132578, 132582, 132586, 132590, 132594, 132598, 132602, 132606, + 132610, 132614, 132618, 132622, 132626, 132630, 132634, 132638, 132642, + 132646, 132650, 132654, 132658, 132662, 132666, 132670, 132674, 132678, + 132682, 132686, 132690, 132694, 132698, 132702, 132706, 132710, 132714, + 132718, 132722, 132726, 132730, 132734, 132738, 132742, 132746, 132750, + 132754, 132758, 132762, 132766, 132770, 132774, 132778, 132782, 132786, + 132790, 132794, 132798, 132802, 132806, 132810, 132814, 132818, 132822, + 132826, 132830, 132834, 132838, 132842, 132846, 132850, 132854, 132858, + 132862, 132866, 132870, 132874, 132878, 132882, 132886, 132890, 132894, + 132898, 132902, 132906, 132910, 132914, 132918, 132922, 132926, 132930, + 132934, 132938, 132942, 132946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132950, 132958, + 132966, 132976, 132986, 132994, 133000, 133008, 133016, 133026, 133038, + 133050, 133056, 133064, 133070, 133076, 133082, 133088, 133094, 133100, + 133106, 133112, 133118, 133124, 133130, 133138, 133146, 133152, 133158, + 133164, 133170, 133178, 133186, 133195, 133201, 133209, 133215, 133221, + 133227, 133233, 133239, 133247, 133255, 133261, 133267, 133273, 133279, + 133285, 133291, 133297, 133303, 133309, 133315, 133321, 133327, 133333, + 133339, 133345, 133351, 133357, 133363, 133369, 133377, 133383, 133389, + 133399, 133407, 133413, 133419, 133425, 133431, 133437, 133443, 133449, + 133455, 133461, 133467, 133473, 133479, 133485, 133491, 133497, 133503, + 133509, 133515, 133521, 133527, 133533, 133539, 133547, 133553, 133561, + 133569, 133577, 133583, 133589, 133595, 133601, 133607, 133615, 133625, + 133633, 133641, 133647, 133653, 133661, 133669, 133675, 133683, 133691, + 133699, 133705, 133711, 133717, 133723, 133729, 133735, 133743, 133751, + 133757, 133763, 133769, 133775, 133781, 133789, 133795, 133801, 133807, + 133813, 133819, 133825, 133833, 133839, 133845, 133851, 133857, 133865, + 133873, 133879, 133885, 133891, 133896, 133902, 133908, 133915, 133920, + 133925, 133930, 133935, 133940, 133945, 133950, 133955, 133960, 133969, + 133976, 133981, 133986, 133991, 133998, 134003, 134008, 134013, 134020, + 134025, 134030, 134035, 134040, 134045, 134050, 134055, 134060, 134065, + 134070, 134075, 134082, 134087, 134094, 134099, 134104, 134111, 134116, + 134121, 134126, 134131, 134136, 134141, 134146, 134151, 134156, 134161, + 134166, 134171, 134176, 134181, 134186, 134191, 134196, 134201, 134206, + 134213, 134218, 134223, 134228, 134233, 134238, 134243, 134248, 134253, + 134258, 134263, 134268, 134273, 134278, 134285, 134290, 134295, 134302, + 134307, 134312, 134317, 134322, 134327, 134332, 134337, 134342, 134347, + 134352, 134359, 134364, 134369, 134374, 134379, 134384, 134391, 134398, + 134403, 134408, 134413, 134418, 134423, 134428, 134433, 134438, 134443, + 134448, 134453, 134458, 134463, 134468, 134473, 134478, 134483, 134488, + 134493, 134498, 134503, 134508, 134513, 134518, 134523, 134528, 134533, + 134538, 134543, 134548, 134553, 134558, 134563, 134568, 134573, 134578, + 134585, 134590, 134595, 134600, 134605, 134610, 134615, 134620, 134625, + 134630, 134635, 134640, 134645, 134650, 134655, 134660, 134665, 134670, + 134675, 134680, 134685, 134690, 134695, 134700, 134705, 134710, 134715, + 134720, 134725, 134730, 134735, 134740, 134745, 134750, 134755, 134760, + 134765, 134770, 134775, 134780, 134785, 134790, 134795, 134800, 134805, + 134810, 134815, 134820, 134825, 134830, 134835, 134840, 134845, 134850, + 134855, 134860, 134865, 134870, 134875, 134882, 134887, 134892, 134897, + 134902, 134907, 134912, 134917, 134922, 134927, 134932, 134937, 134942, + 134947, 134952, 134957, 134962, 134967, 134972, 134977, 134982, 134987, + 134994, 134999, 135004, 135010, 135015, 135020, 135025, 135030, 135035, + 135040, 135045, 135050, 135055, 135060, 135065, 135070, 135075, 135080, + 135085, 135090, 135095, 135100, 135105, 135110, 135115, 135120, 135125, + 135130, 135135, 135140, 135145, 135150, 135155, 135160, 135165, 135170, + 135175, 135180, 135185, 135190, 135195, 135200, 135205, 135210, 135215, + 135220, 135225, 135232, 135237, 135242, 135249, 135256, 135261, 135266, + 135271, 135276, 135281, 135286, 135291, 135296, 135301, 135306, 135311, + 135316, 135321, 135326, 135331, 135336, 135341, 135346, 135351, 135356, + 135361, 135366, 135371, 135376, 135381, 135388, 135393, 135398, 135403, + 135408, 135413, 135418, 135423, 135428, 135433, 135438, 135443, 135448, + 135453, 135458, 135463, 135468, 135473, 135478, 135485, 135490, 135495, + 135500, 135505, 135510, 135515, 135520, 135526, 135531, 135536, 135541, + 135546, 135551, 135556, 135561, 135566, 135573, 135580, 135585, 135590, + 135594, 135599, 135603, 135607, 135612, 135619, 135624, 135629, 135638, + 135643, 135648, 135653, 135658, 135665, 135672, 135677, 135682, 135687, + 135692, 135699, 135704, 135709, 135714, 135719, 135724, 135729, 135734, + 135739, 135744, 135749, 135754, 135759, 135766, 135770, 135775, 135780, + 135785, 135790, 135794, 135799, 135804, 135809, 135814, 135819, 135824, + 135829, 135834, 135839, 135845, 135851, 135857, 135863, 135869, 135874, + 135880, 135886, 135892, 135898, 135904, 135910, 135916, 135922, 135928, + 135934, 135940, 135946, 135952, 135958, 135964, 135970, 135976, 135982, + 135987, 135993, 135999, 136005, 136011, 136017, 136023, 136029, 136035, + 136041, 136047, 136053, 136059, 136065, 136071, 136077, 136083, 136089, + 136095, 136101, 136107, 136112, 136118, 136124, 136130, 136136, 136142, + 0, 0, 0, 0, 0, 0, 0, 136148, 136152, 136157, 136162, 136167, 136172, + 136177, 136181, 136186, 136191, 136196, 136201, 136206, 136211, 136216, + 136221, 136226, 136230, 136235, 136239, 136244, 136249, 136254, 136259, + 136264, 136268, 136273, 136278, 136282, 136287, 136292, 0, 136297, + 136302, 136306, 136310, 136314, 136318, 136322, 136326, 136330, 136334, + 0, 0, 0, 0, 136338, 136342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 136347, 136354, 136360, 136367, 136374, + 136381, 136388, 136395, 136402, 136409, 136416, 136423, 136430, 136437, + 136444, 136451, 136458, 136465, 136471, 136478, 136485, 136492, 136498, + 136505, 136511, 136517, 136524, 136530, 136537, 136543, 0, 0, 136549, + 136557, 136565, 136574, 136583, 136592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 136600, 136605, 136610, 136615, 136620, 136625, 136630, 136635, 136640, + 136645, 136650, 136655, 136660, 136665, 136670, 136675, 136680, 136685, + 136690, 136695, 136700, 136705, 136710, 136715, 136720, 136725, 136730, + 136735, 136740, 136745, 136750, 136755, 136760, 136765, 136770, 136775, + 136780, 136785, 136790, 136795, 136800, 136805, 136810, 136815, 136820, + 136825, 136830, 136835, 136840, 136847, 136854, 136861, 136868, 136875, + 136882, 136889, 136896, 136905, 136912, 136919, 136926, 136933, 136940, + 136947, 136954, 136961, 136968, 136975, 136982, 136987, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 136996, 137001, 137005, 137009, 137013, 137017, 137021, + 137025, 137029, 137033, 0, 137037, 137042, 137047, 137054, 137059, + 137066, 137073, 0, 137078, 137085, 137090, 137095, 137102, 137109, + 137114, 137119, 137124, 137129, 137134, 137141, 137148, 137153, 137158, + 137163, 137176, 137185, 137192, 137201, 137210, 0, 0, 0, 0, 0, 137219, + 137226, 137233, 137240, 137247, 137254, 137261, 137268, 137275, 137282, + 137289, 137296, 137303, 137310, 137317, 137324, 137331, 137338, 137345, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 137352, 137358, 137364, 137370, 137376, 137382, + 137388, 137394, 137400, 137406, 137412, 137418, 137423, 137429, 137434, + 137440, 137445, 137451, 137457, 137462, 137468, 137473, 137479, 137485, + 137491, 137497, 137503, 137509, 137515, 137520, 137525, 137531, 137537, + 137543, 137549, 137555, 137561, 137567, 137573, 137579, 137585, 137591, + 137597, 137603, 137608, 137614, 137619, 137625, 137630, 137636, 137642, + 137647, 137653, 137658, 137664, 137670, 137676, 137682, 137688, 137694, + 137700, 137705, 137710, 137716, 137722, 137727, 137731, 137735, 137739, + 137743, 137747, 137751, 137755, 137759, 137763, 137768, 137773, 137778, + 137783, 137788, 137793, 137798, 137803, 137808, 137813, 137820, 137827, + 137834, 137838, 137844, 137849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137855, 137858, 137862, + 137866, 137870, 137873, 137877, 137882, 137886, 137890, 137894, 137897, + 137901, 137906, 137910, 137914, 137918, 137921, 137925, 137930, 137935, + 137939, 137943, 137946, 137950, 137954, 137958, 137962, 137966, 137970, + 137974, 137977, 137981, 137985, 137989, 137993, 137997, 138001, 138007, + 138010, 138014, 138018, 138022, 138026, 138030, 138034, 138038, 138042, + 138046, 138051, 138056, 138062, 138066, 138070, 138074, 138078, 138082, + 138086, 138091, 138094, 138098, 138102, 138106, 138110, 138116, 138120, + 138124, 138128, 138132, 138136, 138140, 138144, 138148, 138152, 138156, + 0, 0, 0, 0, 138160, 138165, 138169, 138173, 138179, 138185, 138189, + 138194, 138199, 138204, 138209, 138213, 138218, 138223, 138228, 138232, + 138237, 138242, 138247, 138251, 138256, 138261, 138266, 138271, 138276, + 138281, 138286, 138291, 138295, 138300, 138305, 138310, 138315, 138320, + 138325, 138330, 138335, 138340, 138345, 138350, 138357, 138362, 138369, + 138374, 138379, 138384, 138389, 138394, 138399, 138404, 138409, 138414, + 138419, 138424, 138429, 138434, 138439, 0, 0, 0, 0, 0, 0, 0, 138444, + 138448, 138454, 138457, 138460, 138464, 138468, 138472, 138476, 138480, + 138484, 138488, 138494, 138500, 138506, 138512, 138518, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138524, 138528, 138532, 138538, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138544, 138547, 138550, 138553, 138556, 138559, 138562, 138565, 138568, + 138571, 138574, 138577, 138580, 138583, 138586, 138589, 138592, 138595, + 138598, 138601, 138604, 138607, 138610, 138613, 138616, 138619, 138622, + 138625, 138628, 138631, 138634, 138637, 138640, 138643, 138646, 138649, + 138652, 138655, 138658, 138661, 138664, 138667, 138670, 138673, 138676, + 138679, 138682, 138685, 138688, 138691, 138694, 138697, 138700, 138703, + 138706, 138709, 138712, 138715, 138718, 138721, 138724, 138727, 138730, + 138733, 138736, 138739, 138742, 138745, 138748, 138751, 138754, 138757, + 138760, 138763, 138766, 138769, 138772, 138775, 138778, 138781, 138784, + 138787, 138790, 138793, 138796, 138799, 138802, 138805, 138808, 138811, + 138814, 138817, 138820, 138823, 138826, 138829, 138832, 138835, 138838, + 138841, 138844, 138847, 138850, 138853, 138856, 138859, 138862, 138865, + 138868, 138871, 138874, 138877, 138880, 138883, 138886, 138889, 138892, + 138895, 138898, 138901, 138904, 138907, 138910, 138913, 138916, 138919, + 138922, 138925, 138928, 138931, 138934, 138937, 138940, 138943, 138946, + 138949, 138952, 138955, 138958, 138961, 138964, 138967, 138970, 138973, + 138976, 138979, 138982, 138985, 138988, 138991, 138994, 138997, 139000, + 139003, 139006, 139009, 139012, 139015, 139018, 139021, 139024, 139027, + 139030, 139033, 139036, 139039, 139042, 139045, 139048, 139051, 139054, + 139057, 139060, 139063, 139066, 139069, 139072, 139075, 139078, 139081, + 139084, 139087, 139090, 139093, 139096, 139099, 139102, 139105, 139108, + 139111, 139114, 139117, 139120, 139123, 139126, 139129, 139132, 139135, + 139138, 139141, 139144, 139147, 139150, 139153, 139156, 139159, 139162, + 139165, 139168, 139171, 139174, 139177, 139180, 139183, 139186, 139189, + 139192, 139195, 139198, 139201, 139204, 139207, 139210, 139213, 139216, + 139219, 139222, 139225, 139228, 139231, 139234, 139237, 139240, 139243, + 139246, 139249, 139252, 139255, 139258, 139261, 139264, 139267, 139270, + 139273, 139276, 139279, 139282, 139285, 139288, 139291, 139294, 139297, + 139300, 139303, 139306, 139309, 139312, 139315, 139318, 139321, 139324, + 139327, 139330, 139333, 139336, 139339, 139342, 139345, 139348, 139351, + 139354, 139357, 139360, 139363, 139366, 139369, 139372, 139375, 139378, + 139381, 139384, 139387, 139390, 139393, 139396, 139399, 139402, 139405, + 139408, 139411, 139414, 139417, 139420, 139423, 139426, 139429, 139432, + 139435, 139438, 139441, 139444, 139447, 139450, 139453, 139456, 139459, + 139462, 139465, 139468, 139471, 139474, 139477, 139480, 139483, 139486, + 139489, 139492, 139495, 139498, 139501, 139504, 139507, 139510, 139513, + 139516, 139519, 139522, 139525, 139528, 139531, 139534, 139537, 139540, + 139543, 139546, 139549, 139552, 139555, 139558, 139561, 139564, 139567, + 139570, 139573, 139576, 139579, 139582, 139585, 139588, 139591, 139594, + 139597, 139600, 139603, 139606, 139609, 139612, 139615, 139618, 139621, + 139624, 139627, 139630, 139633, 139636, 139639, 139642, 139645, 139648, + 139651, 139654, 139657, 139660, 139663, 139666, 139669, 139672, 139675, + 139678, 139681, 139684, 139687, 139690, 139693, 139696, 139699, 139702, + 139705, 139708, 139711, 139714, 139717, 139720, 139723, 139726, 139729, + 139732, 139735, 139738, 139741, 139744, 139747, 139750, 139753, 139756, + 139759, 139762, 139765, 139768, 139771, 139774, 139777, 139780, 139783, + 139786, 139789, 139792, 139795, 139798, 139801, 139804, 139807, 139810, + 139813, 139816, 139819, 139822, 139825, 139828, 139831, 139834, 139837, + 139840, 139843, 139846, 139849, 139852, 139855, 139858, 139861, 139864, + 139867, 139870, 139873, 139876, 139879, 139882, 139885, 139888, 139891, + 139894, 139897, 139900, 139903, 139906, 139909, 139912, 139915, 139918, + 139921, 139924, 139927, 139930, 139933, 139936, 139939, 139942, 139945, + 139948, 139951, 139954, 139957, 139960, 139963, 139966, 139969, 139972, + 139975, 139978, 139981, 139984, 139987, 139990, 139993, 139996, 139999, + 140002, 140005, 140008, 140011, 140014, 140017, 140020, 140023, 140026, + 140029, 140032, 140035, 140038, 140041, 140044, 140047, 140050, 140053, + 140056, 140059, 140062, 140065, 140068, 140071, 140074, 140077, 140080, + 140083, 140086, 140089, 140092, 140095, 140098, 140101, 140104, 140107, + 140110, 140113, 140116, 140119, 140122, 140125, 140128, 140131, 140134, + 140137, 140140, 140143, 140146, 140149, 140152, 140155, 140158, 140161, + 140164, 140167, 140170, 140173, 140176, 140179, 140182, 140185, 140188, + 140191, 140194, 140197, 140200, 140203, 140206, 140209, 140212, 140215, + 140218, 140221, 140224, 140227, 140230, 140233, 140236, 140239, 140242, + 140245, 140248, 140251, 140254, 140257, 140260, 140263, 140266, 140269, + 140272, 140275, 140278, 140281, 140284, 140287, 140290, 140293, 140296, + 140299, 140302, 140305, 140308, 140311, 140314, 140317, 140320, 140323, + 140326, 140329, 140332, 140335, 140338, 140341, 140344, 140347, 140350, + 140353, 140356, 140359, 140362, 140365, 140368, 140371, 140374, 140377, + 140380, 140383, 140386, 140389, 140392, 140395, 140398, 140401, 140404, + 140407, 140410, 140413, 140416, 140419, 140422, 140425, 140428, 140431, + 140434, 140437, 140440, 140443, 140446, 140449, 140452, 140455, 140458, + 140461, 140464, 140467, 140470, 140473, 140476, 140479, 140482, 140485, + 140488, 140491, 140494, 140497, 140500, 140503, 140506, 140509, 140512, + 140515, 140518, 140521, 140524, 140527, 140530, 140533, 140536, 140539, + 140542, 140545, 140548, 140551, 140554, 140557, 140560, 140563, 140566, + 140569, 140572, 140575, 140578, 140581, 140584, 140587, 140590, 140593, + 140596, 140599, 140602, 140605, 140608, 140611, 140614, 140617, 140620, + 140623, 140626, 140629, 140632, 140635, 140638, 140641, 140644, 140647, + 140650, 140653, 140656, 140659, 140662, 140665, 140668, 140671, 140674, + 140677, 140680, 140683, 140686, 140689, 140692, 140695, 140698, 140701, + 140704, 140707, 140710, 140713, 140716, 140719, 140722, 140725, 140728, + 140731, 140734, 140737, 140740, 140743, 140746, 140749, 140752, 140755, + 140758, 140761, 140764, 140767, 140770, 140773, 140776, 140779, 140782, + 140785, 140788, 140791, 140794, 140797, 140800, 140803, 140806, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140809, 140814, 140820, 140824, 140828, + 140832, 140836, 140840, 140844, 140848, 140852, 140856, 140860, 140864, + 140868, 140872, 140876, 140880, 140884, 140888, 140892, 140896, 140900, + 140904, 140908, 140912, 140916, 140920, 140924, 140928, 140932, 140936, + 140940, 140944, 140948, 140952, 140956, 140960, 140964, 140968, 140972, + 140976, 140980, 140984, 140988, 140992, 140996, 141000, 141004, 141008, + 141012, 141016, 141020, 141024, 141028, 141032, 141036, 141040, 141044, + 141048, 141052, 141056, 141060, 141064, 141068, 141072, 141076, 141080, + 141084, 141088, 141092, 141096, 141100, 141104, 141108, 141112, 141116, + 141120, 141124, 141128, 141132, 141136, 141140, 141144, 141148, 141152, + 141156, 141160, 141164, 141168, 141172, 141176, 141180, 141184, 141188, + 141192, 141196, 141200, 141204, 141208, 141212, 141216, 141220, 141224, + 141228, 141232, 141236, 141240, 141244, 141248, 141252, 141256, 141260, + 141264, 141268, 141272, 141276, 141280, 141284, 141288, 141292, 141296, + 141300, 141304, 141308, 141312, 141316, 141320, 141324, 141328, 141332, + 141336, 141340, 141344, 141348, 141352, 141356, 141360, 141364, 141368, + 141372, 141376, 141380, 141384, 141388, 141392, 141396, 141400, 141404, + 141408, 141412, 141416, 141420, 141424, 141428, 141432, 141436, 141440, + 141444, 141448, 141452, 141456, 141460, 141464, 141468, 141472, 141476, + 141480, 141484, 141488, 141492, 141496, 141500, 141504, 141508, 141512, + 141516, 141520, 141524, 141528, 141532, 141536, 141540, 141544, 141548, + 141552, 141556, 141560, 141564, 141568, 141572, 141576, 141580, 141584, + 141588, 141592, 141596, 141600, 141604, 141608, 141612, 141616, 141620, + 141624, 141628, 141632, 141636, 141640, 141644, 141648, 141652, 141656, + 141660, 141664, 141668, 141672, 141676, 141680, 141684, 141688, 141692, + 141696, 141700, 141704, 141708, 141712, 141716, 141720, 141724, 141728, + 141732, 141736, 141740, 141744, 141748, 141752, 141756, 141760, 141764, + 141768, 141772, 141776, 141780, 141784, 141788, 141792, 141796, 141800, + 141804, 141808, 141812, 141816, 141820, 141824, 141828, 141832, 141836, + 141840, 141844, 141848, 141852, 141856, 141860, 141864, 141868, 141872, + 141876, 141880, 141884, 141888, 141892, 141896, 141900, 141904, 141908, + 141912, 141916, 141920, 141924, 141928, 141932, 141936, 141940, 141944, + 141948, 141952, 141956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 141960, 141965, 141970, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141975, 141980, 141985, 141990, 0, 0, 0, 0, + 0, 0, 0, 0, 141995, 141998, 142001, 142004, 142007, 142010, 142013, + 142016, 142019, 142022, 142025, 142028, 142031, 142034, 142037, 142040, + 142043, 142046, 142049, 142052, 142055, 142058, 142061, 142064, 142067, + 142070, 142073, 142076, 142079, 142082, 142085, 142088, 142091, 142094, + 142097, 142100, 142103, 142106, 142109, 142112, 142115, 142118, 142121, + 142124, 142127, 142130, 142133, 142136, 142139, 142142, 142145, 142148, + 142151, 142154, 142157, 142160, 142163, 142166, 142169, 142172, 142175, + 142178, 142181, 142184, 142187, 142190, 142193, 142196, 142199, 142202, + 142205, 142208, 142211, 142214, 142217, 142220, 142223, 142226, 142229, + 142232, 142235, 142238, 142241, 142244, 142247, 142250, 142253, 142256, + 142259, 142262, 142265, 142268, 142271, 142274, 142277, 142280, 142283, + 142286, 142289, 142292, 142295, 142298, 142301, 142304, 142307, 142310, + 142313, 142316, 142319, 142322, 142325, 142328, 142331, 142334, 142337, + 142340, 142343, 142346, 142349, 142352, 142355, 142358, 142361, 142364, + 142367, 142370, 142373, 142376, 142379, 142382, 142385, 142388, 142391, + 142394, 142397, 142400, 142403, 142406, 142409, 142412, 142415, 142418, + 142421, 142424, 142427, 142430, 142433, 142436, 142439, 142442, 142445, + 142448, 142451, 142454, 142457, 142460, 142463, 142466, 142469, 142472, + 142475, 142478, 142481, 142484, 142487, 142490, 142493, 142496, 142499, + 142502, 142505, 142508, 142511, 142514, 142517, 142520, 142523, 142526, + 142529, 142532, 142535, 142538, 142541, 142544, 142547, 142550, 142553, + 142556, 142559, 142562, 142565, 142568, 142571, 142574, 142577, 142580, + 142583, 142586, 142589, 142592, 142595, 142598, 142601, 142604, 142607, + 142610, 142613, 142616, 142619, 142622, 142625, 142628, 142631, 142634, + 142637, 142640, 142643, 142646, 142649, 142652, 142655, 142658, 142661, + 142664, 142667, 142670, 142673, 142676, 142679, 142682, 142685, 142688, + 142691, 142694, 142697, 142700, 142703, 142706, 142709, 142712, 142715, + 142718, 142721, 142724, 142727, 142730, 142733, 142736, 142739, 142742, + 142745, 142748, 142751, 142754, 142757, 142760, 142763, 142766, 142769, + 142772, 142775, 142778, 142781, 142784, 142787, 142790, 142793, 142796, + 142799, 142802, 142805, 142808, 142811, 142814, 142817, 142820, 142823, + 142826, 142829, 142832, 142835, 142838, 142841, 142844, 142847, 142850, + 142853, 142856, 142859, 142862, 142865, 142868, 142871, 142874, 142877, + 142880, 142883, 142886, 142889, 142892, 142895, 142898, 142901, 142904, + 142907, 142910, 142913, 142916, 142919, 142922, 142925, 142928, 142931, + 142934, 142937, 142940, 142943, 142946, 142949, 142952, 142955, 142958, + 142961, 142964, 142967, 142970, 142973, 142976, 142979, 142982, 142985, + 142988, 142991, 142994, 142997, 143000, 143003, 143006, 143009, 143012, + 143015, 143018, 143021, 143024, 143027, 143030, 143033, 143036, 143039, + 143042, 143045, 143048, 143051, 143054, 143057, 143060, 143063, 143066, + 143069, 143072, 143075, 143078, 143081, 143084, 143087, 143090, 143093, + 143096, 143099, 143102, 143105, 143108, 143111, 143114, 143117, 143120, + 143123, 143126, 143129, 143132, 143135, 143138, 143141, 143144, 143147, + 143150, 143153, 143156, 143159, 143162, 143165, 143168, 143171, 143174, + 143177, 143180, 0, 0, 0, 0, 143183, 143187, 143191, 143195, 143199, + 143203, 143207, 143210, 143214, 143218, 143222, 143226, 143229, 143235, + 143241, 143247, 143253, 143259, 143263, 143269, 143273, 143277, 143283, + 143287, 143291, 143295, 143299, 143303, 143307, 143311, 143317, 143323, + 143329, 143335, 143342, 143349, 143356, 143367, 143374, 143381, 143387, + 143393, 143399, 143405, 143413, 143421, 143429, 143437, 143446, 143452, + 143460, 143466, 143473, 143479, 143486, 143492, 143500, 143504, 143508, + 143513, 143519, 143525, 143533, 143541, 143547, 143554, 143557, 143563, + 143567, 143570, 143574, 143577, 143580, 143584, 143589, 143593, 143597, + 143603, 143608, 143614, 143618, 143622, 143625, 143629, 143633, 143638, + 143642, 143647, 143651, 143656, 143660, 143664, 143668, 143672, 143676, + 143680, 143684, 143688, 143693, 143698, 143703, 143708, 143714, 143720, + 143726, 143732, 143738, 0, 0, 0, 0, 0, 143743, 143751, 143760, 143768, + 143775, 143783, 143790, 143797, 143806, 143813, 143820, 143828, 143836, + 0, 0, 0, 143844, 143849, 143856, 143862, 143869, 143875, 143881, 143887, + 143893, 0, 0, 0, 0, 0, 0, 0, 143899, 143904, 143911, 143917, 143924, + 143930, 143936, 143942, 143948, 143954, 0, 0, 143959, 143965, 143971, + 143974, 143983, 143990, 143998, 144005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 144012, 144017, 144022, 144027, 144034, + 144041, 144048, 144055, 144060, 144065, 144070, 144075, 144082, 144087, + 144094, 144101, 144106, 144111, 144116, 144123, 144128, 144133, 144140, + 144147, 144152, 144157, 144162, 144169, 144176, 144183, 144188, 144193, + 144200, 144207, 144214, 144221, 144226, 144231, 144236, 144243, 144248, + 144253, 144258, 144265, 144274, 144281, 144286, 144291, 144296, 144301, + 144306, 144311, 144320, 144327, 144332, 144339, 144346, 144351, 144356, + 144361, 144368, 144373, 144380, 144387, 144392, 144397, 144402, 144409, + 144416, 144421, 144426, 144433, 144440, 144447, 144452, 144457, 144462, + 144467, 144474, 144483, 144492, 144497, 144504, 144513, 144518, 144523, + 144528, 144533, 144540, 144547, 144554, 144561, 144566, 144571, 144576, + 144583, 144590, 144597, 144602, 144607, 144614, 144619, 144626, 144631, + 144638, 144643, 144650, 144657, 144662, 144667, 144672, 144677, 144682, + 144687, 144692, 144697, 144702, 144709, 144716, 144723, 144730, 144737, + 144746, 144751, 144756, 144763, 144770, 144775, 144782, 144789, 144796, + 144803, 144810, 144817, 144822, 144827, 144832, 144837, 144842, 144851, + 144860, 144869, 144878, 144887, 144896, 144905, 144914, 144919, 144930, + 144941, 144950, 144955, 144960, 144965, 144970, 144979, 144986, 144993, + 145000, 145007, 145014, 145021, 145030, 145039, 145050, 145059, 145070, + 145079, 145086, 145095, 145106, 145115, 145124, 145133, 145142, 145149, + 145156, 145163, 145172, 145181, 145192, 145201, 145210, 145221, 145226, + 145231, 145242, 145250, 145259, 145268, 145277, 145288, 145297, 145306, + 145317, 145328, 145339, 145350, 145361, 145372, 145379, 145386, 145393, + 145400, 145411, 145420, 145427, 145434, 145441, 145452, 145463, 145474, + 145485, 145496, 145507, 145518, 145529, 145536, 145543, 145552, 145561, + 145568, 145575, 145582, 145591, 145600, 145609, 145616, 145625, 145634, + 145643, 145650, 145657, 145662, 145668, 145675, 145682, 145689, 145696, + 145703, 145710, 145719, 145728, 145737, 145746, 145753, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 145762, 145768, 145773, 145778, 145785, 145791, 145797, + 145803, 145809, 145815, 145821, 145827, 145831, 145835, 145841, 145847, + 145853, 145857, 145862, 145867, 145871, 145875, 145878, 145884, 145890, + 145896, 145902, 145908, 145914, 145920, 145926, 145932, 145942, 145952, + 145958, 145964, 145974, 145984, 145990, 0, 0, 145996, 146004, 146009, + 146014, 146020, 146026, 146032, 146038, 146044, 146050, 146057, 146064, + 146070, 146076, 146082, 146088, 146094, 146100, 146106, 146112, 146117, + 146123, 146129, 146135, 146141, 146147, 146156, 146162, 146167, 146175, + 146182, 146189, 146198, 146207, 146216, 146225, 146234, 146243, 146252, + 146261, 146271, 146281, 146289, 146297, 146306, 146315, 146321, 146327, + 146333, 146339, 146347, 146355, 146359, 146365, 146370, 146376, 146382, + 146388, 146394, 146400, 146409, 146414, 146421, 146426, 146431, 146436, + 146442, 146448, 146454, 146461, 146466, 146471, 146476, 146481, 146486, + 146492, 146498, 146504, 146510, 146516, 146522, 146528, 146534, 146539, + 146544, 146549, 146554, 146559, 146564, 146569, 146574, 146580, 146586, + 146591, 146596, 146601, 146606, 146611, 146617, 146624, 146628, 146632, + 146636, 146640, 146644, 146648, 146652, 146656, 146664, 146674, 146678, + 146682, 146688, 146694, 146700, 146706, 146712, 146718, 146724, 146730, + 146736, 146742, 146748, 146754, 146760, 146766, 146770, 146774, 146781, + 146787, 146793, 146799, 146804, 146811, 146816, 146822, 146828, 146834, + 146840, 146845, 146849, 146855, 146859, 146863, 146867, 146873, 146879, + 146883, 146889, 146895, 146901, 146907, 146913, 146921, 146929, 146935, + 146941, 146947, 146953, 146965, 146977, 146991, 147003, 147015, 147029, + 147043, 147057, 147061, 147069, 147077, 147082, 147086, 147090, 147094, + 147098, 147102, 147106, 147110, 147116, 147122, 147128, 147134, 147142, + 147151, 147158, 147165, 147173, 147180, 147192, 147204, 147216, 147228, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 147235, 147242, 147249, 147256, 147263, 147270, 147277, 147284, 147291, + 147298, 147305, 147312, 147319, 147326, 147333, 147340, 147347, 147354, + 147361, 147368, 147375, 147382, 147389, 147396, 147403, 147410, 147417, + 147424, 147431, 147438, 147445, 147452, 147459, 147466, 147473, 147480, + 147487, 147494, 147501, 147508, 147515, 147522, 147529, 147536, 147543, + 147550, 147557, 147564, 147571, 147578, 147585, 147592, 147599, 147606, + 147613, 147620, 147627, 147634, 147641, 147648, 147655, 147662, 147669, + 147676, 147683, 147690, 147697, 147702, 147707, 147712, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 147716, 147722, 147727, 147732, 147737, 147742, 147747, + 147752, 147757, 147762, 147767, 147773, 147779, 147785, 147791, 147797, + 147803, 147809, 147815, 147821, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 147827, 147832, 147839, 147846, 147853, 147860, 147865, 147870, 147877, + 147882, 147887, 147894, 147899, 147904, 147909, 147916, 147925, 147930, + 147935, 147940, 147945, 147950, 147955, 147962, 147967, 147972, 147977, + 147982, 147987, 147992, 147997, 148002, 148007, 148012, 148017, 148022, + 148028, 148033, 148038, 148043, 148048, 148053, 148058, 148063, 148068, + 148073, 148082, 148087, 148096, 148101, 148106, 148111, 148116, 148121, + 148126, 148131, 148140, 148145, 148150, 148155, 148160, 148165, 148172, + 148177, 148184, 148189, 148194, 148199, 148204, 148209, 148214, 148219, + 148224, 148229, 148234, 148239, 148244, 148249, 148254, 148259, 148264, + 148269, 148274, 148279, 148288, 148293, 148298, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 148303, 148311, 148319, 148327, 148335, 148343, 148351, 148359, + 148367, 148375, 148383, 148391, 148399, 148407, 148415, 148423, 148431, + 148439, 148447, 148452, 148457, 148462, 148467, 148472, 148476, 0, 0, 0, + 0, 0, 0, 0, 148480, 148484, 148489, 148494, 148499, 148503, 148508, + 148513, 148518, 148522, 148527, 148532, 148536, 148541, 148546, 148550, + 148555, 148560, 148564, 148569, 148574, 148578, 148583, 148588, 148593, + 148598, 148603, 148607, 148612, 148617, 148622, 148626, 148631, 148636, + 148641, 148645, 148650, 148655, 148659, 148664, 148669, 148673, 148678, + 148683, 148687, 148692, 148697, 148701, 148706, 148711, 148716, 148721, + 148726, 148730, 148735, 148740, 148745, 148749, 148754, 148759, 148764, + 148768, 148773, 148778, 148782, 148787, 148792, 148796, 148801, 148806, + 148810, 148815, 148820, 148824, 148829, 148834, 148839, 148844, 148849, + 148853, 148858, 148863, 148868, 148872, 148877, 0, 148882, 148886, + 148891, 148896, 148900, 148905, 148910, 148914, 148919, 148924, 148928, + 148933, 148938, 148942, 148947, 148952, 148957, 148962, 148967, 148972, + 148978, 148984, 148990, 148995, 149001, 149007, 149013, 149018, 149024, + 149030, 149035, 149041, 149047, 149052, 149058, 149064, 149069, 149075, + 149081, 149086, 149092, 149098, 149104, 149110, 149116, 149121, 149127, + 149133, 149139, 149144, 149150, 149156, 149162, 149167, 149173, 149179, + 149184, 149190, 149196, 149201, 149207, 149213, 149218, 149224, 149230, + 149235, 149241, 149247, 149253, 149259, 149265, 0, 149269, 149274, 0, 0, + 149279, 0, 0, 149284, 149289, 0, 0, 149294, 149299, 149303, 149308, 0, + 149313, 149318, 149323, 149327, 149332, 149337, 149342, 149347, 149352, + 149356, 149361, 149366, 0, 149371, 0, 149376, 149381, 149385, 149390, + 149395, 149399, 149404, 0, 149409, 149414, 149419, 149423, 149428, + 149433, 149437, 149442, 149447, 149452, 149457, 149462, 149467, 149473, + 149479, 149485, 149490, 149496, 149502, 149508, 149513, 149519, 149525, + 149530, 149536, 149542, 149547, 149553, 149559, 149564, 149570, 149576, + 149581, 149587, 149593, 149599, 149605, 149611, 149616, 149622, 149628, + 149634, 149639, 149645, 149651, 149657, 149662, 149668, 149674, 149679, + 149685, 149691, 149696, 149702, 149708, 149713, 149719, 149725, 149730, + 149736, 149742, 149748, 149754, 149760, 149764, 0, 149769, 149774, + 149778, 149783, 0, 0, 149788, 149793, 149798, 149802, 149807, 149812, + 149816, 149821, 0, 149826, 149831, 149836, 149840, 149845, 149850, + 149855, 0, 149860, 149864, 149869, 149874, 149879, 149883, 149888, + 149893, 149898, 149902, 149907, 149912, 149916, 149921, 149926, 149930, + 149935, 149940, 149944, 149949, 149954, 149958, 149963, 149968, 149973, + 149978, 149983, 149988, 0, 149994, 150000, 150005, 150011, 0, 150017, + 150022, 150028, 150034, 150039, 0, 150045, 0, 0, 0, 150050, 150056, + 150062, 150067, 150073, 150079, 150085, 0, 150091, 150096, 150102, + 150108, 150114, 150119, 150125, 150131, 150137, 150142, 150148, 150154, + 150159, 150165, 150171, 150176, 150182, 150188, 150193, 150199, 150205, + 150210, 150216, 150222, 150228, 150234, 150240, 150245, 150251, 150257, + 150263, 150268, 150274, 150280, 150286, 150291, 150297, 150303, 150308, + 150314, 150320, 150325, 150331, 150337, 150342, 150348, 150354, 150359, + 150365, 150371, 150377, 150383, 150389, 150394, 150400, 150406, 150412, + 150417, 150423, 150429, 150435, 150440, 150446, 150452, 150457, 150463, + 150469, 150474, 150480, 150486, 150491, 150497, 150503, 150508, 150514, + 150520, 150526, 150532, 150538, 150542, 150547, 150552, 150557, 150561, + 150566, 150571, 150576, 150580, 150585, 150590, 150594, 150599, 150604, + 150608, 150613, 150618, 150622, 150627, 150632, 150636, 150641, 150646, + 150651, 150656, 150661, 150665, 150670, 150675, 150680, 150684, 150689, + 150694, 150699, 150703, 150708, 150713, 150717, 150722, 150727, 150731, + 150736, 150741, 150745, 150750, 150755, 150759, 150764, 150769, 150774, + 150779, 150784, 150789, 150795, 150801, 150807, 150812, 150818, 150824, + 150830, 150835, 150841, 150847, 150852, 150858, 150864, 150869, 150875, + 150881, 150886, 150892, 150898, 150903, 150909, 150915, 150921, 150927, + 150933, 150938, 150944, 150950, 150956, 150961, 150967, 150973, 150979, + 150984, 150990, 150996, 151001, 151007, 151013, 151018, 151024, 151030, + 151035, 151041, 151047, 151052, 151058, 151064, 151070, 151076, 151082, + 151087, 151093, 151099, 151105, 151110, 151116, 151122, 151128, 151133, + 151139, 151145, 151150, 151156, 151162, 151167, 151173, 151179, 151184, + 151190, 151196, 151201, 151207, 151213, 151219, 151225, 151231, 151236, + 151242, 151248, 151254, 151259, 151265, 151271, 151277, 151282, 151288, + 151294, 151299, 151305, 151311, 151316, 151322, 151328, 151333, 151339, + 151345, 151350, 151356, 151362, 151368, 151374, 151380, 151386, 151393, + 151400, 151407, 151413, 151420, 151427, 151434, 151440, 151447, 151454, + 151460, 151467, 151474, 151480, 151487, 151494, 151500, 151507, 151514, + 151520, 151527, 151534, 151541, 151548, 151555, 151561, 151568, 151575, + 151582, 151588, 151595, 151602, 151609, 151615, 151622, 151629, 151635, + 151642, 151649, 151655, 151662, 151669, 151675, 151682, 151689, 151695, + 151702, 151709, 151716, 151723, 151730, 151735, 151741, 151747, 151753, + 151758, 151764, 151770, 151776, 151781, 151787, 151793, 151798, 151804, + 151810, 151815, 151821, 151827, 151832, 151838, 151844, 151849, 151855, + 151861, 151867, 151873, 151879, 151884, 151890, 151896, 151902, 151907, + 151913, 151919, 151925, 151930, 151936, 151942, 151947, 151953, 151959, + 151964, 151970, 151976, 151981, 151987, 151993, 151998, 152004, 152010, + 152016, 152022, 152028, 152034, 0, 0, 152041, 152046, 152051, 152056, + 152061, 152066, 152071, 152076, 152081, 152086, 152091, 152096, 152101, + 152106, 152111, 152116, 152121, 152126, 152132, 152137, 152142, 152147, + 152152, 152157, 152162, 152167, 152171, 152176, 152181, 152186, 152191, + 152196, 152201, 152206, 152211, 152216, 152221, 152226, 152231, 152236, + 152241, 152246, 152251, 152256, 152262, 152267, 152272, 152277, 152282, + 152287, 152292, 152297, 152303, 152308, 152313, 152318, 152323, 152328, + 152333, 152338, 152343, 152348, 152353, 152358, 152363, 152368, 152373, + 152378, 152383, 152388, 152393, 152398, 152403, 152408, 152413, 152418, + 152424, 152429, 152434, 152439, 152444, 152449, 152454, 152459, 152463, + 152468, 152473, 152478, 152483, 152488, 152493, 152498, 152503, 152508, + 152513, 152518, 152523, 152528, 152533, 152538, 152543, 152548, 152554, + 152559, 152564, 152569, 152574, 152579, 152584, 152589, 152595, 152600, + 152605, 152610, 152615, 152620, 152625, 152631, 152637, 152643, 152649, + 152655, 152661, 152667, 152673, 152679, 152685, 152691, 152697, 152703, + 152709, 152715, 152721, 152727, 152734, 152740, 152746, 152752, 152758, + 152764, 152770, 152776, 152781, 152787, 152793, 152799, 152805, 152811, + 152817, 152823, 152829, 152835, 152841, 152847, 152853, 152859, 152865, + 152871, 152877, 152883, 152890, 152896, 152902, 152908, 152914, 152920, + 152926, 152932, 152939, 152945, 152951, 152957, 152963, 152969, 152975, + 152981, 152987, 152993, 152999, 153005, 153011, 153017, 153023, 153029, + 153035, 153041, 153047, 153053, 153059, 153065, 153071, 153077, 153084, + 153090, 153096, 153102, 153108, 153114, 153120, 153126, 153131, 153137, + 153143, 153149, 153155, 153161, 153167, 153173, 153179, 153185, 153191, + 153197, 153203, 153209, 153215, 153221, 153227, 153233, 153240, 153246, + 153252, 153258, 153264, 153270, 153276, 153282, 153289, 153295, 153301, + 153307, 153313, 153319, 153325, 153332, 153339, 153346, 153353, 153360, + 153367, 153374, 153381, 153388, 153395, 153402, 153409, 153416, 153423, + 153430, 153437, 153444, 153452, 153459, 153466, 153473, 153480, 153487, + 153494, 153501, 153507, 153514, 153521, 153528, 153535, 153542, 153549, + 153556, 153563, 153570, 153577, 153584, 153591, 153598, 153605, 153612, + 153619, 153626, 153634, 153641, 153648, 153655, 153662, 153669, 153676, + 153683, 153691, 153698, 153705, 153712, 153719, 153726, 153733, 153738, + 0, 0, 153743, 153748, 153752, 153756, 153760, 153764, 153768, 153772, + 153776, 153780, 153784, 153790, 153795, 153800, 153805, 153810, 153815, + 153820, 153825, 153830, 153835, 153840, 153844, 153848, 153852, 153856, + 153860, 153864, 153868, 153872, 153876, 153882, 153887, 153892, 153897, + 153902, 153907, 153912, 153917, 153922, 153927, 153933, 153938, 153943, + 153948, 153953, 153958, 153963, 153968, 153973, 153978, 153982, 153987, + 153992, 153997, 154002, 154007, 154012, 154018, 154026, 154033, 154038, + 154043, 154050, 154056, 154061, 154067, 154073, 154081, 154087, 154094, + 154102, 154108, 154117, 154126, 154134, 154142, 154148, 154155, 154163, + 154171, 154177, 154184, 154193, 154202, 154209, 154220, 154230, 154240, + 154250, 154260, 154267, 154274, 154281, 154288, 154297, 154306, 154317, + 154328, 154337, 154346, 154357, 154366, 154375, 154386, 154395, 154404, + 154412, 154420, 154431, 154442, 154450, 154459, 154468, 154475, 154486, + 154497, 154506, 154515, 154522, 154531, 154540, 154549, 154560, 154569, + 154579, 154588, 154597, 154608, 154621, 154636, 154647, 154660, 154672, + 154681, 154692, 154703, 154712, 154723, 154737, 154752, 154755, 154764, + 154769, 154775, 154783, 154789, 154795, 154804, 154811, 154821, 154833, + 154840, 154843, 154849, 154856, 154862, 154867, 154870, 154875, 154878, + 154885, 154891, 154899, 154906, 154913, 154919, 154924, 154927, 154930, + 154933, 154939, 154946, 154952, 154957, 154964, 154967, 154972, 154979, + 154985, 154993, 155000, 155010, 155019, 155022, 155028, 155035, 155042, + 155049, 155054, 155062, 155070, 155079, 155085, 155094, 155103, 155112, + 155118, 155127, 155134, 155141, 155148, 155156, 155162, 155170, 155176, + 155183, 155190, 155198, 155209, 155219, 155225, 155232, 155239, 155246, + 155252, 155259, 155266, 155271, 155278, 155286, 155295, 155301, 155313, + 155324, 155330, 155338, 155344, 155351, 155358, 155365, 155371, 155378, + 155387, 155393, 155399, 155406, 155413, 155421, 155431, 155441, 155451, + 155461, 155469, 155477, 155487, 155495, 155500, 155505, 155510, 155516, + 155523, 155530, 155536, 155542, 155547, 155554, 155562, 155572, 155580, + 155588, 155598, 155608, 155616, 155626, 155636, 155648, 155660, 155672, + 155682, 155688, 155694, 155701, 155710, 155719, 155728, 155737, 155747, + 155756, 155765, 155774, 155779, 155785, 155794, 155804, 155813, 155819, + 155825, 155832, 155839, 155846, 155852, 155859, 155866, 155873, 155879, + 155883, 155888, 155895, 155902, 155909, 155914, 155922, 155930, 155939, + 155947, 155954, 155962, 155971, 155981, 155984, 155988, 155993, 155998, + 156003, 156008, 156013, 156018, 156023, 156028, 156033, 156038, 156043, + 156048, 156053, 156058, 156063, 156068, 156073, 156080, 156086, 156093, + 156099, 156104, 156111, 156117, 156124, 156130, 156135, 156142, 156149, + 156156, 156162, 156168, 156177, 156186, 156197, 156204, 156211, 156220, + 156229, 156238, 156247, 156256, 156262, 156270, 156276, 156286, 156291, + 156300, 156309, 156316, 156327, 156334, 156341, 156348, 156355, 156362, + 156369, 156376, 156383, 156390, 156397, 156403, 156409, 156415, 156422, + 156429, 156436, 156443, 156450, 156457, 156464, 156471, 156478, 156485, + 156492, 156499, 156504, 156513, 156522, 156531, 156538, 156545, 156552, + 156559, 156566, 156573, 156580, 156587, 156596, 156605, 156614, 156623, + 156632, 156641, 156650, 156659, 156668, 156677, 156686, 156695, 156704, + 156710, 156718, 156724, 156734, 156739, 156748, 156757, 156766, 156777, + 156782, 156789, 156796, 156803, 156808, 156814, 156820, 156826, 156833, + 156840, 156847, 156854, 156861, 156868, 156875, 156882, 156889, 156896, + 156903, 156910, 156915, 156924, 156933, 156942, 156951, 156960, 156969, + 156978, 156987, 156998, 157009, 157016, 157023, 157030, 157037, 157044, + 157051, 157059, 157069, 157079, 157089, 157100, 157111, 157122, 157131, + 157140, 157149, 157154, 157159, 157164, 157169, 157180, 157191, 157202, + 157213, 157224, 157234, 157245, 157254, 157263, 157272, 157281, 157290, + 157298, 157307, 157318, 157329, 157340, 157351, 157362, 157374, 157387, + 157399, 157412, 157424, 157437, 157449, 157462, 157473, 157484, 157493, + 157501, 157510, 157521, 157532, 157544, 157557, 157571, 157586, 157598, + 157611, 157623, 157636, 157647, 157658, 157667, 157675, 157684, 157691, + 157698, 157705, 157712, 157719, 157726, 157733, 157740, 157747, 157754, + 157759, 157764, 157769, 157776, 157786, 157797, 157807, 157818, 157832, + 157847, 157862, 157876, 157891, 157906, 157917, 157928, 157941, 157954, + 157963, 157972, 157985, 157998, 158005, 158012, 158017, 158022, 158027, + 158032, 158037, 158044, 158053, 158058, 158061, 158066, 158073, 158080, + 158087, 158094, 158101, 158108, 158121, 158135, 158150, 158157, 158164, + 158171, 158180, 158188, 158196, 158205, 158210, 158215, 158220, 158225, + 158230, 158235, 158242, 158249, 158255, 158262, 158268, 158275, 158280, + 158285, 158290, 158295, 158300, 158307, 158314, 158319, 158326, 158333, + 158338, 158343, 158348, 158353, 158358, 158363, 158370, 158377, 158384, + 158387, 158392, 158397, 158402, 158407, 158414, 158421, 158429, 158437, + 158442, 158447, 158454, 158461, 158468, 158473, 158480, 158487, 158492, + 158499, 158506, 158512, 158518, 158524, 158530, 158538, 158546, 158552, + 158560, 158568, 158573, 158580, 158587, 158592, 158599, 158606, 158613, + 158621, 158629, 158634, 158641, 158648, 158657, 158664, 158673, 158684, + 158693, 158702, 158711, 158720, 158723, 158728, 158735, 158744, 158751, + 158760, 158767, 158772, 158777, 158780, 158783, 158786, 158793, 158800, + 158809, 158818, 158827, 158834, 158841, 158846, 158859, 158864, 158869, + 158874, 158879, 158884, 158889, 158894, 158899, 158902, 158907, 158912, + 158917, 158922, 158927, 158934, 158939, 158946, 158949, 158954, 158957, + 158960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158963, 158968, + 158973, 158978, 158983, 0, 158988, 158993, 158998, 159003, 159008, + 159013, 159018, 159023, 159028, 159033, 159038, 159043, 159048, 159053, + 159058, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159063, 159068, 159073, 159078, 159083, + 159088, 159093, 0, 159098, 159103, 159108, 159114, 159118, 159123, + 159128, 159133, 159138, 159143, 159148, 159153, 159158, 159163, 159168, + 159173, 159178, 0, 0, 159183, 159188, 159193, 159198, 159203, 159208, + 159213, 0, 159218, 159223, 0, 159229, 159234, 159242, 159249, 159258, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159263, 159270, 159278, 159286, + 159293, 159300, 159307, 159315, 159323, 159331, 159338, 159345, 159353, + 159361, 159369, 159376, 159384, 159392, 159400, 159408, 159416, 159424, + 159432, 159439, 159447, 159454, 159462, 159469, 159477, 159485, 159493, + 159501, 159509, 159517, 159525, 159533, 159541, 159548, 159556, 159563, + 159570, 159577, 159585, 159592, 159600, 0, 0, 0, 159608, 159615, 159622, + 159629, 159636, 159643, 159650, 159657, 159666, 159675, 159684, 159693, + 159702, 159712, 0, 0, 159720, 159728, 159735, 159742, 159749, 159756, + 159763, 159770, 159777, 159784, 0, 0, 0, 0, 159791, 159800, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159808, 159813, 159817, 159822, + 159827, 159832, 159837, 159841, 159846, 159850, 159854, 159858, 159862, + 159867, 159872, 159876, 159881, 159886, 159891, 159896, 159901, 159905, + 159909, 159914, 159918, 159922, 159927, 159931, 159935, 159939, 159944, + 159948, 159953, 159958, 159963, 159968, 159973, 159978, 159983, 159988, + 159993, 159998, 160003, 160008, 160013, 160018, 160023, 160028, 160033, + 160038, 160042, 160046, 160050, 160054, 160058, 160062, 160066, 160070, + 0, 0, 0, 0, 0, 160074, 160079, 160086, 160092, 160099, 160106, 160113, + 160120, 160127, 160134, 160141, 160148, 160155, 160162, 160169, 160176, + 160183, 160190, 160197, 160204, 160211, 160218, 160225, 160232, 160239, + 160246, 160253, 160260, 160267, 160274, 160281, 160288, 160295, 160302, + 160309, 160316, 160322, 160328, 160334, 160341, 160347, 160354, 160360, + 160367, 160374, 160381, 160388, 160395, 160402, 160408, 160415, 160422, + 160429, 160436, 160443, 160450, 160457, 160463, 160470, 160477, 160484, + 160491, 160498, 160506, 160513, 160520, 160527, 160534, 160541, 160548, + 160555, 160561, 160568, 160575, 160582, 160589, 160595, 160602, 160609, + 160616, 160623, 160630, 160637, 160644, 160652, 160659, 160665, 160672, + 160679, 160686, 160693, 160700, 160707, 160714, 160721, 160728, 160735, + 160742, 160749, 160756, 160763, 160770, 160777, 160784, 160791, 160798, + 160805, 160811, 160818, 160825, 160832, 160839, 160846, 160853, 160860, + 160867, 160874, 160881, 160888, 160895, 160902, 160909, 160916, 160923, + 160930, 160937, 160944, 160951, 160958, 160965, 160973, 160981, 160989, + 160996, 161003, 161010, 161017, 161024, 161031, 161038, 161045, 161052, + 161059, 161065, 161072, 161079, 161086, 161093, 161100, 161107, 161114, + 161121, 161128, 161135, 161142, 161149, 161156, 161163, 161171, 161179, + 161187, 161194, 161201, 161208, 161215, 161222, 161229, 161236, 161243, + 161250, 161257, 161264, 161271, 161278, 161285, 161291, 161298, 161305, + 161312, 161319, 161326, 161333, 161340, 161347, 161354, 161361, 161368, + 161375, 161382, 161389, 161396, 161403, 161410, 161417, 161424, 161431, + 161438, 161445, 0, 0, 161452, 161456, 161460, 161464, 161468, 161472, + 161476, 161480, 161484, 161488, 161494, 161500, 161506, 161512, 161520, + 161528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161534, 161540, + 161546, 161552, 161558, 161564, 161570, 161576, 161582, 161587, 161592, + 161598, 161603, 161608, 161614, 161620, 161626, 161632, 161638, 161643, + 161648, 161654, 161660, 161665, 161671, 161677, 161683, 161689, 161695, + 161701, 161707, 161713, 161719, 161725, 161731, 161737, 161743, 161749, + 161755, 161761, 161767, 161773, 161779, 161784, 161789, 161795, 161800, + 161805, 161811, 161817, 161823, 161829, 161835, 161840, 161845, 161851, + 161857, 161862, 161868, 161874, 161880, 161886, 161892, 161898, 161904, + 161910, 161916, 161922, 161928, 161934, 161939, 161944, 161948, 161953, + 161960, 161964, 0, 0, 0, 0, 161969, 161974, 161978, 161982, 161986, + 161990, 161994, 161998, 162002, 162006, 0, 0, 0, 0, 162010, 162016, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 162022, 162027, 162032, 162037, 162042, 162047, 162052, 162057, 162062, + 162067, 162073, 162079, 162085, 162091, 162097, 162103, 162109, 162115, + 162121, 162128, 162135, 162142, 162150, 162158, 162166, 162174, 162182, + 162190, 162196, 162202, 162208, 162215, 162222, 162229, 162236, 162243, + 162250, 162257, 162264, 162271, 162278, 162285, 162292, 162299, 162306, + 162313, 162319, 162325, 162331, 162337, 162343, 162350, 162357, 162364, + 162371, 162378, 162385, 162392, 162399, 162406, 162411, 162418, 162425, + 162432, 162438, 162445, 162452, 162461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162469, 162474, + 162479, 162484, 162489, 162494, 162499, 162504, 162509, 162514, 162520, + 162526, 162532, 162538, 162544, 162550, 162556, 162562, 162568, 162575, + 162582, 162589, 162597, 162605, 162613, 162621, 162629, 162637, 162643, + 162649, 162655, 162662, 162669, 162676, 162683, 162690, 162697, 162704, + 162711, 162718, 162725, 162732, 162739, 162746, 162753, 162760, 162765, + 162772, 162779, 162786, 162793, 162800, 162807, 162814, 162821, 162829, + 162839, 162849, 162857, 162866, 162873, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 162880, 162884, 162888, 162892, 0, 162896, 162900, + 162904, 162908, 162912, 162916, 162920, 162924, 162928, 162932, 162936, + 162940, 162944, 162948, 162952, 162956, 162960, 162964, 162968, 162972, + 162976, 162980, 162984, 162988, 162994, 163000, 163006, 0, 163012, + 163017, 0, 163022, 0, 0, 163027, 0, 163032, 163037, 163042, 163047, + 163052, 163057, 163062, 163067, 163072, 163077, 0, 163082, 163087, + 163092, 163097, 0, 163102, 0, 163107, 0, 0, 0, 0, 0, 0, 163112, 0, 0, 0, + 0, 163118, 0, 163124, 0, 163130, 0, 163136, 163142, 163148, 0, 163154, + 163160, 0, 163166, 0, 0, 163172, 0, 163178, 0, 163184, 0, 163190, 0, + 163198, 0, 163206, 163212, 0, 163218, 0, 0, 163224, 163230, 163236, + 163242, 0, 163248, 163254, 163260, 163266, 163272, 163278, 163284, 0, + 163290, 163296, 163302, 163308, 0, 163314, 163320, 163326, 163332, 0, + 163340, 0, 163348, 163354, 163360, 163366, 163372, 163378, 163384, + 163390, 163396, 163402, 0, 163408, 163414, 163420, 163426, 163432, + 163438, 163444, 163450, 163456, 163462, 163468, 163474, 163480, 163486, + 163492, 163498, 163504, 0, 0, 0, 0, 0, 163510, 163516, 163522, 0, 163528, + 163534, 163540, 163546, 163552, 0, 163558, 163564, 163570, 163576, + 163582, 163588, 163594, 163600, 163606, 163612, 163618, 163624, 163630, + 163636, 163642, 163648, 163654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163660, 163670, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 163678, 163685, 163692, 163699, 163705, + 163712, 163719, 163725, 163732, 163739, 163746, 163754, 163762, 163770, + 163778, 163786, 163794, 163801, 163808, 163815, 163823, 163831, 163839, + 163847, 163855, 163863, 163870, 163877, 163884, 163892, 163900, 163908, + 163916, 163924, 163932, 163937, 163942, 163947, 163952, 163957, 163962, + 163967, 163972, 163977, 0, 0, 0, 0, 163982, 163988, 163992, 163996, + 164000, 164004, 164008, 164012, 164016, 164020, 164024, 164028, 164032, + 164036, 164040, 164044, 164048, 164052, 164056, 164060, 164064, 164068, + 164072, 164076, 164080, 164084, 164088, 164092, 164096, 164100, 164104, + 164108, 164112, 164116, 164120, 164124, 164128, 164132, 164136, 164140, + 164144, 164148, 164152, 164156, 164160, 164164, 164168, 164172, 164176, + 164180, 164184, 164189, 164193, 164197, 164201, 164205, 164209, 164213, + 164217, 164221, 164225, 164229, 164233, 164237, 164241, 164245, 164249, + 164253, 164257, 164261, 164265, 164269, 164273, 164277, 164281, 164285, + 164289, 164293, 164297, 164301, 164305, 164309, 164313, 164317, 164321, + 164325, 164329, 164333, 164337, 164341, 164345, 164349, 164353, 164357, + 164361, 164365, 164369, 164373, 164377, 164381, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 164385, 164391, 164400, 164408, 164416, 164425, 164434, + 164443, 164452, 164461, 164470, 164479, 164488, 164497, 164506, 0, 0, + 164515, 164524, 164532, 164540, 164549, 164558, 164567, 164576, 164585, + 164594, 164603, 164612, 164621, 164630, 164639, 0, 164647, 164656, + 164664, 164672, 164681, 164690, 164699, 164708, 164717, 164726, 164735, + 164744, 164753, 164762, 164771, 0, 164778, 164787, 164795, 164803, + 164812, 164821, 164830, 164839, 164848, 164857, 164866, 164875, 164884, + 164893, 164902, 164909, 164915, 164921, 164927, 164933, 164939, 164945, + 164951, 164957, 164963, 164969, 164975, 164981, 164987, 164993, 164999, + 165005, 165011, 165017, 165023, 165029, 165035, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165041, 165048, 165053, 165057, 165061, 165065, 165070, 165075, + 165080, 165085, 165090, 165095, 165102, 0, 0, 0, 165111, 165116, 165122, + 165128, 165134, 165139, 165145, 165151, 165157, 165162, 165168, 165174, + 165179, 165185, 165191, 165196, 165202, 165208, 165213, 165219, 165225, + 165230, 165236, 165242, 165248, 165254, 165260, 165271, 165278, 165284, + 165287, 165290, 165293, 165298, 165304, 165310, 165316, 165321, 165327, + 165333, 165339, 165344, 165350, 165356, 165361, 165367, 165373, 165378, + 165384, 165390, 165395, 165401, 165407, 165412, 165418, 165424, 165430, + 165436, 165442, 165445, 165448, 165451, 165454, 165457, 165460, 165467, + 165475, 165483, 165491, 165498, 165506, 165514, 165522, 165529, 165537, + 165545, 165552, 165560, 165568, 165575, 165583, 165591, 165598, 165606, + 165614, 165621, 165629, 165637, 165645, 165653, 165661, 165666, 165671, + 0, 0, 0, 165676, 165683, 165691, 165699, 165707, 165714, 165722, 165730, + 165738, 165745, 165753, 165761, 165768, 165776, 165784, 165791, 165799, + 165807, 165814, 165822, 165830, 165837, 165845, 165853, 165861, 165869, + 165877, 165887, 165892, 165896, 165900, 165905, 165910, 165913, 165916, + 165919, 165922, 165925, 165928, 165931, 165934, 165937, 165943, 165946, + 165950, 165955, 165959, 165964, 165969, 165975, 165981, 165987, 165992, + 166000, 166006, 166009, 166012, 166015, 166018, 166021, 166024, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166027, 166034, 166042, 166050, 166058, 166065, 166073, + 166081, 166089, 166096, 166104, 166112, 166119, 166127, 166135, 166142, + 166150, 166158, 166165, 166173, 166181, 166188, 166196, 166204, 166212, + 166220, 166228, 166232, 166236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166239, 166245, 166251, 166257, 166261, 166267, 166273, 166279, 166285, + 166291, 166297, 166303, 166309, 166315, 166321, 166327, 166333, 166339, + 166345, 166351, 166357, 166363, 166369, 166375, 166381, 166387, 166393, + 166399, 166405, 166411, 166417, 166423, 166429, 166435, 166441, 166447, + 166453, 166459, 166465, 166471, 166477, 166483, 166489, 166495, 0, 0, 0, + 0, 166501, 166512, 166523, 166534, 166545, 166556, 166567, 166578, + 166589, 0, 0, 0, 0, 0, 0, 0, 166600, 166605, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166610, 166616, 166622, 166628, 166634, 166640, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 166646, 166648, 166650, 166654, 166659, 166664, 166666, 166672, 166677, + 166679, 166685, 166689, 166691, 166695, 166701, 166707, 166713, 166718, + 166723, 166730, 166737, 166744, 166749, 166756, 166763, 166770, 166774, + 166781, 166790, 166799, 166806, 166811, 166815, 166819, 166821, 166824, + 166827, 166834, 166841, 166851, 166856, 166861, 166866, 166871, 166873, + 166879, 166883, 166885, 166887, 166889, 166891, 166895, 166899, 166903, + 166905, 166909, 166911, 166915, 166917, 166919, 166921, 166923, 166928, + 166933, 166935, 166941, 166945, 166949, 166957, 166959, 166961, 166963, + 166965, 166967, 166969, 166971, 166973, 166975, 166977, 166981, 166985, + 166987, 166989, 166991, 166993, 166995, 167000, 167006, 167010, 167014, + 167018, 167022, 167027, 167031, 167033, 167035, 167039, 167045, 167047, + 167049, 167051, 167055, 167064, 167070, 167074, 167078, 167080, 167082, + 167085, 167087, 167089, 167091, 167095, 167097, 167101, 167106, 167108, + 167113, 167119, 167126, 167130, 167134, 167138, 167142, 167148, 167152, + 167160, 167167, 167169, 167171, 167175, 167179, 167181, 167185, 167189, + 167191, 167195, 167197, 167201, 167205, 167209, 167213, 167217, 167221, + 167225, 167229, 167235, 167239, 167243, 167254, 167259, 167263, 167267, + 167273, 167277, 167281, 167285, 167292, 167299, 167303, 167307, 167311, + 167315, 167319, 167326, 167328, 167332, 167334, 167336, 167340, 167344, + 167348, 167350, 167354, 167358, 167362, 167366, 167370, 167372, 167376, + 167378, 167384, 167387, 167392, 167394, 167396, 167399, 167401, 167403, + 167406, 167413, 167420, 167427, 167432, 167436, 167438, 167440, 167442, + 167446, 167448, 167452, 167456, 167460, 167462, 167466, 167468, 167472, + 167476, 167483, 167485, 167494, 167503, 167512, 167518, 167520, 167525, + 167529, 167533, 167535, 167541, 167545, 167547, 167551, 167555, 167557, + 167561, 167566, 167570, 167576, 167582, 167584, 167586, 167592, 167594, + 167598, 167602, 167604, 167608, 167610, 167614, 167618, 167622, 167625, + 167628, 167633, 167638, 167640, 167643, 167645, 167652, 167656, 167658, + 167665, 167672, 167679, 167686, 167693, 167695, 167697, 167699, 167703, + 167705, 167707, 167709, 167711, 167713, 167715, 167717, 167719, 167721, + 167723, 167725, 167727, 167729, 167731, 167733, 167735, 167737, 167739, + 167741, 167743, 167745, 167747, 167751, 167753, 167755, 167757, 167761, + 167763, 167767, 167769, 167771, 167775, 167779, 167785, 167787, 167789, + 167791, 167793, 167797, 167801, 167803, 167807, 167811, 167815, 167819, + 167823, 167827, 167831, 167835, 167839, 167843, 167847, 167851, 167855, + 167859, 167863, 167867, 167871, 167875, 167877, 167879, 167881, 167883, + 167885, 167887, 167889, 167897, 167905, 167913, 167921, 167926, 167931, + 167936, 167940, 167944, 167949, 167953, 167955, 167959, 167961, 167963, + 167965, 167967, 167969, 167971, 167973, 167977, 167979, 167981, 167983, + 167987, 167991, 167995, 167999, 168003, 168005, 168011, 168017, 168019, + 168021, 168023, 168025, 168027, 168036, 168043, 168050, 168054, 168061, + 168066, 168073, 168082, 168087, 168091, 168095, 168097, 168101, 168103, + 168107, 168111, 168113, 168117, 168121, 168125, 168127, 168129, 168135, + 168137, 168139, 168141, 168145, 168149, 168151, 168155, 168157, 168159, + 168162, 168166, 168168, 168172, 168174, 168176, 168181, 168183, 168187, + 168191, 168194, 168198, 168202, 168206, 168210, 168214, 168218, 168222, + 168227, 168231, 168235, 168244, 168249, 168252, 168254, 168257, 168260, + 168265, 168267, 168270, 168275, 168279, 168282, 168286, 168290, 168293, + 168298, 168302, 168306, 168310, 168314, 168320, 168326, 168332, 168338, + 168343, 168354, 168356, 168360, 168362, 168364, 168368, 168372, 168374, + 168378, 168383, 168388, 168394, 168396, 168400, 168404, 168411, 168418, + 168422, 168424, 168426, 168430, 168432, 168436, 168440, 168444, 168446, + 168448, 168455, 168459, 168462, 168466, 168470, 168474, 168476, 168480, + 168482, 168484, 168488, 168490, 168494, 168498, 168504, 168508, 168512, + 168516, 168518, 168521, 168525, 168532, 168541, 168550, 168558, 168566, + 168568, 168572, 168574, 168578, 168589, 168593, 168599, 168605, 168610, + 168612, 168617, 168621, 168623, 168625, 168627, 168631, 168635, 168639, + 168644, 168654, 168669, 168681, 168693, 168697, 168701, 168707, 168709, + 168717, 168725, 168727, 168731, 168737, 168743, 168750, 168757, 168759, + 168761, 168764, 168766, 168772, 168774, 168777, 168781, 168787, 168793, + 168804, 168810, 168817, 168825, 168829, 168837, 168845, 168851, 168857, + 168864, 168866, 168870, 168872, 168874, 168879, 168881, 168883, 168885, + 168887, 168891, 168901, 168907, 168911, 168915, 168919, 168925, 168931, + 168937, 168943, 168948, 168953, 168959, 168965, 168972, 168979, 168987, + 168995, 169000, 169008, 169012, 169021, 169030, 169036, 169040, 169044, + 169048, 169051, 169056, 169058, 169060, 169062, 169069, 169074, 169081, + 169088, 169095, 169103, 169111, 169119, 169127, 169135, 169143, 169151, + 169159, 169167, 169173, 169179, 169185, 169191, 169197, 169203, 169209, + 169215, 169221, 169227, 169233, 169239, 169242, 169251, 169260, 169262, + 169269, 169273, 169275, 169277, 169281, 169287, 169291, 169293, 169303, + 169309, 169313, 169315, 169319, 169321, 169325, 169332, 169339, 169346, + 169351, 169356, 169365, 169371, 169376, 169380, 169385, 169389, 169396, + 169400, 169403, 169408, 169415, 169422, 169427, 169432, 169437, 169443, + 169452, 169463, 169469, 169475, 169481, 169491, 169506, 169515, 169523, + 169531, 169539, 169547, 169555, 169563, 169571, 169579, 169587, 169595, + 169603, 169611, 169614, 169618, 169623, 169628, 169630, 169634, 169643, + 169652, 169660, 169664, 169668, 169673, 169678, 169683, 169685, 169690, + 169694, 169696, 169700, 169704, 169710, 169715, 169723, 169728, 169733, + 169738, 169745, 169748, 169750, 169753, 169758, 169764, 169768, 169772, + 169778, 169784, 169786, 169790, 169794, 169798, 169802, 169806, 169808, + 169810, 169812, 169814, 169820, 169826, 169830, 169832, 169834, 169836, + 169845, 169849, 169856, 169863, 169865, 169868, 169872, 169878, 169882, + 169886, 169888, 169896, 169900, 169904, 169909, 169914, 169919, 169924, + 169929, 169934, 169939, 169944, 169949, 169954, 169958, 169964, 169968, + 169974, 169979, 169986, 169992, 170000, 170004, 170011, 170015, 170019, + 170023, 170028, 170033, 170035, 170039, 170048, 170056, 170064, 170077, + 170090, 170103, 170110, 170117, 170121, 170130, 170138, 170142, 170151, + 170158, 170162, 170166, 170170, 170174, 170181, 170185, 170189, 170193, + 170197, 170204, 170213, 170222, 170229, 170241, 170253, 170257, 170261, + 170265, 170269, 170273, 170277, 170285, 170293, 170301, 170305, 170309, + 170313, 170317, 170321, 170325, 170331, 170337, 170341, 170352, 170360, + 170364, 170368, 170372, 170376, 170382, 170389, 170400, 170410, 170420, + 170431, 170440, 170451, 170457, 170463, 170469, 170475, 170481, 170485, + 170492, 170501, 170508, 170514, 170518, 170522, 170526, 170535, 170547, + 170551, 170558, 170565, 170572, 170580, 170587, 170595, 170603, 170612, + 170620, 170629, 170638, 170648, 170657, 170667, 170677, 170688, 170698, + 170709, 170716, 170724, 170731, 170739, 170747, 170756, 170764, 170773, + 170780, 170792, 170799, 170811, 170814, 170818, 170821, 170825, 170831, + 170838, 170844, 170851, 170856, 170862, 170873, 170883, 170894, 170899, + 170904, 170910, 170915, 170922, 170926, 170932, 170934, 170936, 170940, + 170944, 170948, 170957, 170959, 170961, 170964, 170966, 170968, 170972, + 170974, 170978, 170980, 170984, 170986, 170988, 170992, 170996, 171002, + 171004, 171008, 171010, 171014, 171018, 171022, 171026, 171028, 171030, + 171034, 171038, 171042, 171046, 171048, 171050, 171052, 171058, 171063, + 171066, 171074, 171082, 171084, 171089, 171092, 171097, 171108, 171115, + 171120, 171125, 171127, 171131, 171133, 171137, 171139, 171143, 171147, + 171150, 171153, 171155, 171158, 171160, 171164, 171166, 171168, 171170, + 171174, 171176, 171180, 171183, 171190, 171193, 171198, 171201, 171204, + 171209, 171213, 171217, 171221, 171223, 171228, 171231, 171235, 171237, + 171239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171243, 171248, 171250, 171254, + 171256, 171260, 171264, 171270, 171274, 171279, 171282, 171286, 171290, + 0, 0, 0, 171294, 171296, 171302, 171306, 171310, 171312, 171316, 171318, + 171320, 171324, 171326, 0, 0, 0, 0, 0, 171330, 171335, 171340, 171345, + 171350, 171355, 171360, 171367, 171374, 171381, 171388, 171393, 171398, + 171403, 171408, 171415, 171421, 171428, 171435, 171442, 171447, 171452, + 171457, 171462, 171467, 171474, 171481, 171486, 171491, 171498, 171505, + 171513, 171521, 171528, 171535, 171543, 171551, 171559, 171566, 171576, + 171587, 171592, 171599, 171606, 171613, 171621, 171629, 171640, 171648, + 171656, 171664, 171669, 171674, 171679, 171684, 171689, 171694, 171699, + 171704, 171709, 171714, 171719, 171724, 171731, 171736, 171741, 171748, + 171753, 171758, 171763, 171768, 171773, 171778, 171783, 171788, 171793, + 171798, 171803, 171808, 171815, 171823, 171828, 171833, 171840, 171845, + 171850, 171855, 171862, 171867, 171874, 171879, 171886, 171891, 171900, + 171909, 171914, 171919, 171924, 171929, 171934, 171939, 171944, 171949, + 171954, 171959, 171964, 171969, 171974, 171982, 171990, 171995, 172000, + 172005, 172010, 172015, 172021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 172027, 172035, 172043, 172051, 172059, 172065, 172071, 172075, 172079, + 172085, 172091, 172100, 172104, 172109, 172115, 172119, 172124, 172128, + 172132, 172138, 172144, 172154, 172163, 172166, 172171, 172177, 172183, + 172194, 172204, 172208, 172213, 172219, 172225, 172234, 172239, 172243, + 172248, 172252, 172258, 172264, 172270, 172274, 172277, 172281, 172284, + 172287, 172292, 172297, 172304, 172312, 172319, 172326, 172335, 172344, + 172351, 172359, 172366, 172373, 172382, 172391, 172398, 172406, 172413, + 172420, 172429, 172436, 172444, 172450, 172459, 172467, 172476, 172483, + 172493, 172504, 172512, 172520, 172529, 172537, 172545, 172554, 172562, + 172572, 172581, 172589, 172597, 172606, 172609, 172614, 172617, 0, 0, 0, + 0, 0, 0, 0, 172622, 172628, 172634, 172640, 172646, 172652, 172658, + 172664, 172670, 172676, 172682, 172688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 172694, 172702, 172711, 172719, 172728, + 172737, 172747, 172756, 172766, 172775, 172785, 172794, 0, 0, 0, 0, + 172804, 172812, 172821, 172829, 172838, 172845, 172853, 172860, 172868, + 172876, 172885, 172893, 172902, 172912, 172923, 172933, 172944, 172953, + 172963, 172972, 172982, 172991, 173001, 173010, 173020, 173028, 173037, + 173045, 173054, 173062, 173071, 173079, 173088, 173098, 173109, 173119, + 173130, 173134, 173139, 173143, 173148, 173151, 173155, 173158, 173162, + 173166, 173171, 173175, 173180, 173185, 173191, 173196, 173202, 173205, + 173209, 173212, 0, 0, 0, 0, 0, 0, 0, 0, 173216, 173219, 173223, 173226, + 173230, 173235, 173240, 173246, 173252, 173256, 0, 0, 0, 0, 0, 0, 173260, + 173266, 173273, 173279, 173286, 173294, 173302, 173311, 173320, 173325, + 173331, 173336, 173342, 173349, 173356, 173364, 173372, 173379, 173387, + 173394, 173402, 173411, 173420, 173430, 173440, 173446, 173453, 173459, + 173466, 173474, 173482, 173491, 173500, 173508, 173517, 173525, 173534, + 173544, 173554, 173565, 0, 0, 0, 0, 0, 0, 0, 0, 173576, 173581, 173587, + 173592, 173598, 173607, 173617, 173626, 173636, 173643, 173651, 173658, + 173666, 173673, 173682, 173691, 173700, 173705, 173712, 173719, 173726, + 173731, 173736, 173741, 173746, 173753, 173760, 173767, 173774, 173781, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173790, 173800, 173809, 173814, 173823, + 173831, 173839, 173846, 173850, 173855, 173862, 173871, 0, 173882, + 173885, 173889, 173893, 173897, 173901, 173906, 173910, 173914, 173919, + 173923, 173927, 173933, 173939, 173946, 173950, 173954, 173956, 173966, + 173975, 173982, 173986, 173990, 174000, 174004, 174008, 174012, 174016, + 174024, 174033, 174046, 174057, 174068, 174084, 174092, 174101, 174105, + 174107, 174112, 174114, 174116, 174122, 174126, 174128, 174134, 174136, + 174138, 174142, 174144, 174148, 174150, 174154, 174158, 174163, 174167, + 174171, 174173, 174177, 174179, 174185, 174191, 174197, 174201, 174207, + 174211, 174218, 174220, 174224, 174226, 174228, 174230, 174232, 174234, + 174236, 174240, 174244, 174251, 174255, 174257, 174262, 174264, 174266, + 174268, 174270, 174274, 174278, 174280, 174285, 174290, 174292, 174294, + 174296, 174298, 174303, 174305, 174309, 174313, 174315, 174319, 174321, + 174334, 0, 174338, 174350, 174362, 174366, 0, 0, 0, 174370, 174377, + 174379, 174383, 174385, 174389, 174393, 174395, 174399, 174401, 174403, + 174407, 174409, 174411, 174413, 174415, 174417, 174421, 174423, 174425, + 174427, 174429, 174431, 174433, 174435, 174439, 174443, 174445, 174447, + 174449, 174451, 174453, 174455, 174457, 174459, 174461, 174463, 174465, + 174467, 174469, 174471, 0, 0, 174473, 174475, 174477, 174479, 174481, + 174483, 0, 0, 0, 174485, 174489, 174493, 174501, 174509, 174515, 174522, + 174524, 174526, 174528, 174530, 174532, 174534, 174538, 174545, 174549, + 174553, 174557, 174561, 174565, 174567, 174571, 174575, 174577, 174579, + 174581, 174583, 174585, 174589, 0, 0, 174593, 174597, 174601, 174605, + 174610, 174612, 174614, 174618, 174622, 174627, 174635, 174639, 174647, + 174649, 174651, 174653, 174655, 174657, 174659, 174661, 174663, 174667, + 174671, 174673, 174675, 174677, 174679, 174685, 174687, 174693, 174697, + 174701, 174706, 174708, 174710, 174714, 174716, 174718, 174720, 174722, + 174726, 174731, 174736, 174740, 174744, 174746, 174748, 174753, 174758, + 174760, 174762, 174766, 174772, 174778, 174784, 174790, 174796, 174802, + 174813, 174824, 174836, 174847, 174858, 174869, 174880, 174891, 174902, + 174913, 174924, 174935, 174946, 174957, 174968, 174980, 174992, 175004, + 175016, 175028, 175040, 175054, 175068, 175083, 175089, 175095, 175101, + 175107, 175113, 175119, 175125, 175131, 175137, 175143, 175149, 175155, + 175162, 175169, 175176, 175183, 175190, 175197, 175211, 175225, 175240, + 175254, 175268, 175282, 175296, 175310, 175324, 175338, 175352, 175366, + 175380, 175394, 175408, 175423, 175438, 175453, 175468, 175483, 175498, + 175512, 175526, 175541, 175546, 175551, 175557, 175568, 175579, 175591, + 175596, 175601, 175606, 175611, 175616, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 175621, 175627, 175633, 175639, 175645, 175651, 175657, 175663, + 175668, 175673, 175678, 175683, 175688, 175693, 0, 0, 175698, 175702, + 175706, 175708, 0, 0, 0, 0, 175710, 175715, 175719, 0, 0, 0, 0, 0, + 175721, 175723, 175725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175727, + 175731, 175733, 175735, 175737, 175741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 175743, 175747, 175751, 175755, 175759, 175763, 175767, 175771, 175775, + 175779, 175783, 175787, 175791, 175795, 175799, 175803, 175807, 175811, + 175815, 175819, 175823, 175827, 175831, 175835, 175839, 175843, 175847, + 175851, 175855, 175859, 175863, 175867, 175871, 175875, 175879, 175883, + 175887, 175891, 175895, 175899, 175903, 175907, 175911, 175915, 175919, + 175923, 175927, 175931, 175935, 175939, 175943, 175947, 175951, 175955, + 175959, 175963, 175967, 175971, 175975, 175979, 175983, 175987, 175991, + 175995, 175999, 176003, 176007, 176011, 176015, 176019, 176023, 176027, + 176031, 176035, 176039, 176043, 176047, 176051, 176055, 176059, 176063, + 176067, 176071, 176075, 176079, 176083, 176087, 176091, 176095, 176099, + 176103, 176107, 176111, 176115, 176119, 176123, 176127, 176131, 176135, + 176139, 176143, 176147, 176151, 176155, 176159, 176163, 176167, 176171, + 176175, 176179, 176183, 176187, 176191, 176195, 176199, 176203, 176207, + 176211, 176215, 176219, 176223, 176227, 176231, 176235, 176239, 176243, + 176247, 176251, 176255, 176259, 176263, 176267, 176271, 176275, 176279, + 176283, 176287, 176291, 176295, 176299, 176303, 176307, 176311, 176315, + 176319, 176323, 176327, 176331, 176335, 176339, 176343, 176347, 176351, + 176355, 176359, 176363, 176367, 176371, 176375, 176379, 176383, 176387, + 176391, 176395, 176399, 176403, 176407, 176411, 176415, 176419, 176423, + 176427, 176431, 176435, 176439, 176443, 176447, 176451, 176455, 176459, + 176463, 176467, 176471, 176475, 176479, 176483, 176487, 176491, 176495, + 176499, 176503, 176507, 176511, 176515, 176519, 176523, 176527, 176531, + 176535, 176539, 176543, 176547, 176551, 176555, 176559, 176563, 176567, + 176571, 176575, 176579, 176583, 176587, 176591, 176595, 176599, 176603, + 176607, 176611, 176615, 176619, 176623, 176627, 176631, 176635, 176639, + 176643, 176647, 176651, 176655, 176659, 176663, 176667, 176671, 176675, + 176679, 176683, 176687, 176691, 176695, 176699, 176703, 176707, 176711, + 176715, 176719, 176723, 176727, 176731, 176735, 176739, 176743, 176747, + 176751, 176755, 176759, 176763, 176767, 176771, 176775, 176779, 176783, + 176787, 176791, 176795, 176799, 176803, 176807, 176811, 176815, 176819, + 176823, 176827, 176831, 176835, 176839, 176843, 176847, 176851, 176855, + 176859, 176863, 176867, 176871, 176875, 176879, 176883, 176887, 176891, + 176895, 176899, 176903, 176907, 176911, 176915, 176919, 176923, 176927, + 176931, 176935, 176939, 176943, 176947, 176951, 176955, 176959, 176963, + 176967, 176971, 176975, 176979, 176983, 176987, 176991, 176995, 176999, + 177003, 177007, 177011, 177015, 177019, 177023, 177027, 177031, 177035, + 177039, 177043, 177047, 177051, 177055, 177059, 177063, 177067, 177071, + 177075, 177079, 177083, 177087, 177091, 177095, 177099, 177103, 177107, + 177111, 177115, 177119, 177123, 177127, 177131, 177135, 177139, 177143, + 177147, 177151, 177155, 177159, 177163, 177167, 177171, 177175, 177179, + 177183, 177187, 177191, 177195, 177199, 177203, 177207, 177211, 177215, + 177219, 177223, 177227, 177231, 177235, 177239, 177243, 177247, 177251, + 177255, 177259, 177263, 177267, 177271, 177275, 177279, 177283, 177287, + 177291, 177295, 177299, 177303, 177307, 177311, 177315, 177319, 177323, + 177327, 177331, 177335, 177339, 177343, 177347, 177351, 177355, 177359, + 177363, 177367, 177371, 177375, 177379, 177383, 177387, 177391, 177395, + 177399, 177403, 177407, 177411, 177415, 177419, 177423, 177427, 177431, + 177435, 177439, 177443, 177447, 177451, 177455, 177459, 177463, 177467, + 177471, 177475, 177479, 177483, 177487, 177491, 177495, 177499, 177503, + 177507, 177511, 177515, 177519, 177523, 177527, 177531, 177535, 177539, + 177543, 177547, 177551, 177555, 177559, 177563, 177567, 177571, 177575, + 177579, 177583, 177587, 177591, 177595, 177599, 177603, 177607, 177611, + 177615, 177619, 177623, 177627, 177631, 177635, 177639, 177643, 177647, + 177651, 177655, 177659, 177663, 177667, 177671, 177675, 177679, 177683, + 177687, 177691, 177695, 177699, 177703, 177707, 177711, 177715, 177719, + 177723, 177727, 177731, 177735, 177739, 177743, 177747, 177751, 177755, + 177759, 177763, 177767, 177771, 177775, 177779, 177783, 177787, 177791, + 177795, 177799, 177803, 177807, 177811, 177815, 177819, 177823, 177827, + 177831, 177835, 177839, 177843, 177847, 177851, 177855, 177859, 177863, + 177867, 177871, 177875, 177879, 177883, 177887, 177891, 177895, 177899, + 177903, 177907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 177911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177915, 177918, 177922, + 177926, 177929, 177933, 177937, 177940, 177943, 177947, 177951, 177954, + 177957, 177960, 177963, 177968, 177971, 177975, 177978, 177981, 177984, + 177987, 177990, 177993, 177996, 177999, 178002, 178005, 178008, 178012, + 178016, 178020, 178024, 178029, 178034, 178040, 178046, 178052, 178057, + 178063, 178069, 178075, 178080, 178086, 178092, 178097, 178103, 178109, + 178114, 178120, 178126, 178131, 178137, 178143, 178148, 178154, 178160, + 178166, 178172, 178178, 178182, 178187, 178191, 178196, 178200, 178205, + 178210, 178216, 178222, 178228, 178233, 178239, 178245, 178251, 178256, + 178262, 178268, 178273, 178279, 178285, 178290, 178296, 178302, 178307, + 178313, 178319, 178324, 178330, 178336, 178342, 178348, 178354, 178359, + 178363, 178368, 178371, 178375, 178378, 178381, 178384, 178387, 178390, + 178393, 178396, 178399, 178402, 178405, 178408, 178411, 178414, 178417, + 178420, 178423, 178426, 178429, 178432, 178435, 178438, 178441, 178444, + 178447, 178450, 178453, 178456, 178459, 178462, 178465, 178468, 178471, + 178474, 178477, 178480, 178483, 178486, 178489, 178492, 178495, 178498, + 178501, 178504, 178507, 178510, 178513, 178516, 178519, 178522, 178525, + 178528, 178531, 178534, 178537, 178540, 178543, 178546, 178549, 178552, + 178555, 178558, 178561, 178564, 178567, 178570, 178573, 178576, 178579, + 178582, 178585, 178588, 178591, 178594, 178597, 178600, 178603, 178606, + 178609, 178612, 178615, 178618, 178621, 178624, 178627, 178630, 178633, + 178636, 178639, 178642, 178645, 178648, 178651, 178654, 178657, 178660, + 178663, 178666, 178669, 178672, 178675, 178678, 178681, 178684, 178687, + 178690, 178693, 178696, 178699, 178702, 178705, 178708, 178711, 178714, + 178717, 178720, 178723, 178726, 178729, 178732, 178735, 178738, 178741, + 178744, 178747, 178750, 178753, 178756, 178759, 178762, 178765, 178768, + 178771, 178774, 178777, 178780, 178783, 178786, 178789, 178792, 178795, + 178798, 178801, 178804, 178807, 178810, 178813, 178816, 178819, 178822, + 178825, 178828, 178831, 178834, 178837, 178840, 178843, 178846, 178849, + 178852, 178855, 178858, 178861, 178864, 178867, 178870, 178873, 178876, + 178879, 178882, 178885, 178888, 178891, 178894, 178897, 178900, 178903, + 178906, 178909, 178912, 178915, 178918, 178921, 178924, 178927, 178930, + 178933, 178936, 178939, 178942, 178945, 178948, 178951, 178954, 178957, + 178960, 178963, 178966, 178969, 178972, 178975, 178978, 178981, 178984, + 178987, 178990, 178993, 178996, 178999, 179002, 179005, 179008, 179011, + 179014, 179017, 179020, 179023, 179026, 179029, 179032, 179035, 179038, + 179041, 179044, 179047, 179050, 179053, 179056, 179059, 179062, 179065, + 179068, 179071, 179074, 179077, 179080, 179083, 179086, 179089, 179092, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179095, 179097, 179099, + 179104, 179106, 179111, 179113, 179118, 179120, 179125, 179127, 179129, + 179131, 179133, 179135, 179137, 179139, 179141, 179143, 179146, 179150, + 179152, 179154, 179158, 179162, 179167, 179169, 179171, 179173, 179177, + 179180, 179182, 179186, 179188, 179192, 179194, 179198, 179201, 179203, + 179207, 179211, 179213, 179219, 179221, 179226, 179228, 179233, 179235, + 179240, 179242, 179247, 179249, 179253, 179255, 179259, 179261, 179268, + 179270, 179272, 179274, 179279, 179281, 179283, 179285, 179287, 179289, + 179294, 179298, 179300, 179305, 179309, 179311, 179316, 179320, 179322, + 179327, 179331, 179333, 179335, 179337, 179339, 179343, 179345, 179350, + 179352, 179358, 179360, 179366, 179368, 179370, 179372, 179376, 179378, + 179385, 179387, 179394, 179396, 179401, 179407, 179409, 179415, 179422, + 179424, 179430, 179435, 179437, 179443, 179449, 179451, 179457, 179463, + 179465, 179471, 179475, 179477, 179482, 179484, 179486, 179491, 179493, + 179495, 179501, 179503, 179508, 179512, 179514, 179519, 179523, 179525, + 179531, 179533, 179537, 179539, 179543, 179545, 179552, 179559, 179561, + 179568, 179575, 179577, 179582, 179584, 179591, 179593, 179598, 179600, + 179606, 179608, 179612, 179614, 179620, 179622, 179626, 179628, 179634, + 179636, 179638, 179640, 179645, 179650, 179652, 179654, 179664, 179669, + 179676, 179683, 179688, 179693, 179705, 179709, 179713, 179717, 179721, + 179723, 179725, 179727, 179729, 179731, 179733, 179735, 179737, 179739, + 179741, 179743, 179745, 179747, 179749, 179751, 179753, 179755, 179757, + 179759, 179761, 179763, 179769, 179776, 179781, 179789, 179797, 179802, + 179804, 179806, 179808, 179810, 179812, 179814, 179816, 179818, 179820, + 179822, 179824, 179826, 179828, 179830, 179832, 179834, 179845, 179850, + 179852, 179854, 179860, 179872, 179878, 179884, 179890, 179896, 179900, + 179911, 179913, 179915, 179917, 179919, 179921, 179923, 179925, 179927, + 179929, 179931, 179933, 179935, 179937, 179939, 179941, 179943, 179945, + 179947, 179949, 179951, 179953, 179955, 179957, 179959, 179961, 179963, + 179965, 179967, 179969, 179971, 179973, 179975, 179977, 179979, 179981, + 179983, 179985, 179987, 179989, 179991, 179993, 179995, 179997, 179999, + 180001, 180003, 180005, 180007, 180009, 180011, 180013, 180015, 180017, + 180019, 180021, 180023, 180025, 180027, 180029, 180031, 180033, 180035, + 180037, 180039, 180041, 180043, 180045, 180047, 180049, 180051, 180053, + 180055, 180057, 180059, 180061, 180063, 180065, 180067, 180069, 180071, + 180073, 180075, 180077, 180079, 180081, 180083, 180085, 180087, 180089, + 180091, 180093, 180095, 180097, 180099, 180101, 180103, 180105, 180107, + 180109, 180111, 180113, 180115, 180117, 180119, 180121, 180123, 180125, + 180127, 180129, 180131, 180133, 180135, 180137, 180139, 180141, 180143, + 180145, 180147, 180149, 180151, 180153, 180155, 180157, 180159, 180161, + 180163, 180165, 180167, 180169, 180171, 180173, 180175, 180177, 180179, + 180181, 180183, 180185, 180187, 180189, 180191, 180193, 180195, 180197, + 180199, 180201, 180203, 180205, 180207, 180209, 180211, 180213, 180215, + 180217, 180219, 180221, 180223, 180225, 180227, 180229, 180231, 180233, + 180235, 180237, 180239, 180241, 180243, 180245, 180247, 180249, 180251, + 180253, 180255, 180257, 180259, 180261, 180263, 180265, 180267, 180269, + 180271, 180273, 180275, 180277, 180279, 180281, 180283, 180285, 180287, + 180289, 180291, 180293, 180295, 180297, 180299, 180301, 180303, 180305, + 180307, 180309, 180311, 180313, 180315, 180317, 180319, 180321, 180323, + 180325, 180327, 180329, 180331, 180333, 180335, 180337, 180339, 180341, + 180343, 180345, 180347, 180349, 180351, 180353, 180355, 180357, 180359, + 180361, 180363, 180365, 180367, 180369, 180371, 180373, 180375, 180377, + 180379, 180381, 180383, 180385, 180387, 180389, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180391, 180395, 180399, 180404, + 180408, 180412, 180416, 180420, 180424, 180428, 180432, 180436, 180440, + 180450, 180460, 180470, 180480, 180494, 180508, 180521, 180534, 180545, + 180556, 180567, 180578, 180589, 180600, 180610, 180619, 180628, 180637, + 180650, 180663, 180675, 180687, 180697, 180707, 180717, 180727, 180736, + 180745, 180755, 180765, 180775, 180785, 180796, 180807, 180817, 180827, + 180838, 180849, 180860, 180871, 180881, 180894, 180905, 180919, 180927, + 180938, 180946, 180954, 180962, 180970, 180978, 180986, 180995, 181004, + 181014, 181024, 181033, 181042, 181052, 181062, 181070, 181078, 181085, + 181094, 181102, 181110, 181117, 181127, 181136, 181147, 181158, 181170, + 181181, 181191, 181202, 181212, 181223, 181231, 181236, 181240, 181244, + 181248, 181252, 181256, 181260, 181264, 181268, 181272, 181276, 181280, + 181283, 181286, 181290, 181294, 181298, 181302, 181306, 181310, 181314, + 181318, 181322, 181326, 181330, 181334, 181338, 181342, 181346, 181350, + 181354, 181358, 181362, 181366, 181370, 181374, 181378, 181382, 181386, + 181390, 181394, 181398, 181402, 181406, 181410, 181414, 181418, 181422, + 181426, 181430, 181434, 181438, 181442, 181446, 181450, 181454, 181458, + 181462, 181466, 181470, 181474, 181478, 181482, 181486, 181490, 181494, + 181498, 181502, 181506, 181510, 181514, 181518, 181522, 181526, 181530, + 181534, 181538, 181542, 181546, 181550, 181554, 181558, 181562, 181566, + 181570, 181574, 181578, 181582, 181586, 181590, 181594, 181598, 181602, + 181606, 181610, 181614, 181618, 181622, 181626, 181629, 181633, 181637, + 181641, 181645, 181649, 181653, 181657, 181661, 181665, 181669, 181673, + 181677, 181681, 181685, 181689, 181693, 181697, 181701, 181705, 181709, + 181713, 181717, 181721, 181725, 181729, 181733, 181737, 181741, 181745, + 181749, 181753, 181757, 181761, 181765, 181769, 181773, 181777, 181781, + 181785, 181789, 181793, 181797, 181801, 181805, 181809, 181813, 181817, + 181821, 181825, 181829, 181833, 181837, 181841, 181845, 181849, 181853, + 181857, 181861, 181865, 181869, 181873, 181877, 181881, 181885, 181889, + 181893, 181897, 181901, 181905, 181909, 181913, 181917, 181921, 181925, + 181929, 181933, 181937, 181941, 181945, 181949, 181953, 181957, 181961, + 181965, 181969, 181973, 181977, 181981, 181985, 181989, 181993, 181997, + 182001, 182005, 182009, 182013, 182017, 182021, 182025, 182029, 182033, + 182037, 182041, 182045, 182049, 182053, 182057, 182061, 182065, 182069, + 182073, 182077, 182081, 182085, 182089, 182093, 182097, 182101, 182105, + 182109, 182113, 182117, 182121, 182125, 182129, 182133, 182137, 182141, + 182145, 182149, 182153, 182157, 182161, 182165, 182169, 182173, 182177, + 182181, 182185, 182189, 182193, 182197, 182201, 182205, 182209, 182213, + 182217, 182221, 182225, 182229, 182233, 182237, 182241, 182245, 182249, + 182253, 182257, 182261, 182265, 182269, 182273, 182277, 182281, 182285, + 182289, 182293, 182297, 182301, 182305, 182309, 182313, 182317, 182321, + 182325, 182329, 182333, 182337, 182341, 182345, 182349, 182353, 182357, + 182361, 182365, 182369, 182373, 182377, 182381, 182385, 182389, 182393, + 182398, 182403, 182408, 182412, 182418, 182425, 182432, 182439, 182446, + 182453, 182460, 182467, 182474, 182481, 182488, 182495, 182502, 182509, + 182515, 182521, 182528, 182534, 182541, 182548, 182555, 182562, 182569, + 182576, 182583, 182590, 182597, 182604, 182611, 182618, 182625, 182631, + 182637, 182643, 182650, 182659, 182668, 182677, 182686, 182691, 182696, + 182702, 182708, 182714, 182720, 182726, 182732, 182738, 182744, 182750, + 182756, 182762, 182768, 182773, 182779, 182789, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 */ +static const unsigned int code_hash[] = { + 74224, 4851, 0, 0, 0, 0, 7929, 0, 0, 0, 0, 127931, 0, 42833, 983091, + 12064, 0, 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, 41603, 9784, + 0, 9188, 41600, 0, 0, 0, 0, 3535, 0, 0, 0, 66797, 0, 74491, 0, 3404, + 100419, 0, 72411, 1759, 100417, 0, 100418, 69972, 11240, 121038, 100416, + 127764, 0, 0, 0, 0, 0, 69970, 0, 0, 9834, 43249, 2234, 983872, 0, 0, 0, + 0, 92417, 0, 74398, 12035, 0, 983074, 43548, 0, 0, 0, 0, 0, 64318, + 917549, 0, 3390, 74483, 43265, 0, 983865, 0, 0, 0, 3400, 0, 0, 11647, 0, + 0, 0, 0, 2121, 128741, 4043, 8712, 0, 983795, 0, 121172, 0, 129456, 0, 0, + 93042, 0, 0, 983856, 0, 0, 0, 11851, 0, 3181, 66002, 0, 69601, 0, 66021, + 0, 194588, 5457, 5440, 0, 93981, 65282, 2843, 5355, 0, 129333, 69971, + 5194, 11657, 128353, 0, 0, 0, 0, 0, 0, 100525, 0, 0, 74350, 0, 10682, + 110820, 10602, 800, 70044, 118883, 0, 0, 64930, 118940, 67853, 0, 0, 762, + 120485, 0, 0, 0, 10906, 1353, 6960, 0, 0, 5828, 8724, 0, 0, 0, 0, 0, + 7080, 0, 0, 0, 0, 72388, 0, 0, 0, 0, 68878, 0, 0, 0, 7240, 0, 556, 0, 0, + 0, 0, 0, 72397, 0, 0, 0, 0, 0, 0, 0, 0, 72986, 0, 0, 43931, 0, 11093, 0, + 0, 125016, 7341, 66801, 68527, 0, 1874, 0, 0, 129314, 0, 0, 0, 0, 0, 0, + 7688, 0, 0, 9036, 0, 0, 66389, 0, 121347, 0, 0, 10100, 0, 2725, 0, 0, + 43981, 42128, 0, 0, 68146, 0, 0, 0, 0, 71349, 7859, 1945, 0, 0, 0, 65918, + 7188, 9992, 0, 7389, 127008, 71341, 0, 0, 0, 528, 129681, 44017, 11429, + 71347, 0, 0, 120864, 0, 0, 0, 11530, 73102, 6188, 0, 0, 68208, 1823, 0, + 0, 92928, 0, 0, 7233, 92929, 0, 0, 6639, 0, 0, 123149, 0, 1176, 0, 0, + 8276, 128667, 0, 0, 68892, 42931, 0, 0, 0, 0, 0, 0, 0, 5388, 0, 0, 0, + 11310, 0, 123607, 0, 68888, 4199, 119264, 0, 119020, 0, 0, 9560, 0, 0, + 43869, 0, 0, 0, 83172, 0, 0, 0, 83173, 121256, 128875, 0, 0, 74327, 0, 0, + 0, 0, 0, 123623, 68886, 0, 0, 0, 8408, 64704, 0, 0, 0, 0, 0, 67999, 0, 0, + 0, 0, 43049, 0, 43050, 73028, 0, 0, 0, 0, 0, 127396, 0, 69847, 9322, 0, + 0, 129321, 68192, 120507, 983634, 0, 0, 0, 6199, 67249, 0, 0, 0, 0, + 11329, 66285, 0, 983086, 0, 0, 0, 0, 41335, 118866, 43401, 0, 41334, 0, + 0, 0, 983479, 0, 983478, 128114, 0, 42627, 0, 32, 6187, 0, 123619, + 983475, 3665, 121083, 42871, 983118, 41336, 0, 0, 983471, 0, 0, 0, 4412, + 0, 0, 0, 0, 119533, 0, 4181, 0, 0, 127589, 0, 0, 71453, 6181, 74755, + 917895, 0, 0, 0, 0, 121107, 0, 0, 10073, 0, 100738, 127186, 0, 42844, + 7498, 1098, 92565, 119530, 0, 0, 10207, 0, 983229, 0, 983555, 0, 9234, 0, + 6182, 0, 92552, 0, 0, 0, 0, 5471, 9461, 6697, 0, 5473, 0, 0, 0, 0, 0, 0, + 70073, 0, 0, 7767, 8304, 41339, 0, 983489, 69450, 0, 0, 983487, 43855, + 41337, 0, 0, 0, 0, 0, 0, 0, 72396, 0, 0, 0, 42633, 0, 0, 0, 0, 0, 0, 0, + 70005, 129506, 0, 0, 0, 129580, 69817, 128299, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1437, 41617, 0, 0, 0, 128853, 0, 0, 0, 0, 0, 128529, 12113, 0, 42772, 0, + 0, 7693, 10749, 0, 65210, 5773, 978, 128134, 0, 41619, 10239, 0, 0, 0, + 74328, 0, 9748, 0, 0, 0, 0, 0, 0, 0, 70681, 0, 72811, 0, 0, 0, 92776, 0, + 0, 2379, 11325, 0, 0, 67854, 0, 78547, 42209, 0, 120392, 2369, 0, 983984, + 983985, 0, 0, 73936, 7008, 69415, 122919, 0, 43841, 2367, 127827, 983869, + 0, 2375, 8060, 6194, 0, 0, 119084, 0, 0, 0, 0, 6961, 0, 0, 0, 68426, 0, + 42862, 0, 0, 6192, 127900, 42771, 0, 0, 11435, 128445, 118797, 120800, 0, + 12892, 0, 128621, 67149, 0, 0, 0, 0, 120707, 0, 0, 19954, 0, 121164, + 8983, 0, 0, 0, 0, 0, 6198, 121344, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 983507, 41323, 0, 0, 92289, 0, 0, 0, 983503, 41321, 12907, + 3048, 7752, 41320, 0, 0, 12819, 111247, 72127, 0, 0, 0, 0, 0, 72971, 0, + 0, 0, 0, 78650, 78649, 0, 41326, 0, 11806, 43167, 0, 1245, 0, 66463, 0, + 0, 0, 0, 0, 194619, 0, 0, 0, 0, 0, 0, 70403, 325, 12874, 0, 74178, 0, 0, + 119110, 0, 0, 0, 0, 0, 0, 983563, 92175, 0, 0, 0, 121049, 0, 0, 0, 0, 0, + 0, 110844, 11776, 0, 19908, 0, 0, 0, 8753, 0, 0, 0, 9511, 43493, 0, + 93032, 6205, 0, 0, 0, 0, 0, 0, 0, 0, 126577, 0, 41607, 0, 0, 120617, 0, + 0, 0, 7005, 41609, 9580, 0, 401, 0, 43779, 0, 127962, 0, 65486, 0, 12857, + 0, 11983, 0, 0, 0, 121371, 0, 194971, 74258, 0, 0, 0, 0, 0, 0, 8295, + 6200, 0, 127864, 0, 0, 71435, 0, 92523, 0, 128631, 0, 0, 125197, 0, 0, 0, + 127556, 0, 0, 0, 64775, 0, 68862, 120590, 0, 0, 0, 8074, 8199, 126641, + 1907, 127269, 4432, 127271, 10808, 120668, 127272, 127259, 3888, 127261, + 72724, 127263, 127262, 127265, 123169, 121195, 127250, 66879, 127252, + 100422, 66023, 67363, 7663, 0, 0, 0, 0, 66321, 0, 12814, 127248, 127169, + 0, 0, 194603, 7641, 92694, 0, 0, 0, 0, 74320, 120818, 120268, 0, 128475, + 0, 110627, 0, 9622, 128972, 120264, 0, 0, 0, 0, 68319, 0, 0, 71484, 0, 0, + 0, 69906, 0, 0, 947, 0, 194586, 129059, 10969, 119935, 7613, 119937, + 119936, 4795, 119930, 119933, 7376, 0, 0, 0, 0, 0, 0, 0, 0, 119919, 7216, + 119921, 7217, 119915, 7218, 119917, 7219, 119927, 119926, 119929, 119928, + 7213, 119922, 7214, 7215, 128622, 0, 8880, 7685, 128849, 0, 0, 119618, 0, + 8187, 119913, 12815, 7236, 7915, 71906, 0, 121284, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10468, 0, 0, 0, 0, 0, 0, 0, 0, 917909, 0, 110633, 1616, + 3795, 67732, 11529, 0, 126225, 0, 0, 1138, 194577, 12677, 0, 0, 3239, 0, + 0, 194809, 194583, 0, 42164, 0, 11778, 0, 43259, 0, 119073, 0, 0, 0, + 67094, 129638, 0, 78421, 128123, 78418, 0, 0, 0, 0, 43959, 43960, 0, + 72257, 0, 9359, 78416, 0, 0, 0, 6662, 0, 0, 3863, 0, 41329, 55266, 0, + 127822, 41328, 75026, 194569, 129516, 0, 0, 0, 119595, 569, 0, 0, 0, + 119085, 110669, 0, 0, 11610, 11368, 0, 194570, 41331, 1006, 127747, + 120883, 1550, 8201, 0, 0, 5499, 43956, 77908, 77910, 77906, 43957, 77904, + 77905, 128410, 0, 0, 129581, 100447, 43955, 77913, 0, 0, 5511, 0, 983702, + 0, 69241, 8255, 5512, 128560, 119560, 127858, 64313, 127928, 5906, 1119, + 128180, 67088, 983362, 0, 113798, 0, 66423, 0, 0, 0, 67089, 0, 0, 0, 0, + 128177, 983709, 0, 0, 0, 5821, 6186, 0, 128034, 19961, 0, 983700, 0, + 65138, 302, 41113, 41115, 0, 6637, 5907, 128789, 0, 43642, 0, 128625, 0, + 70345, 5513, 6666, 100567, 78442, 5510, 0, 0, 0, 983706, 78437, 0, 0, 0, + 110838, 0, 0, 0, 92710, 0, 0, 0, 0, 0, 74497, 92395, 120511, 6929, 69412, + 0, 110835, 64442, 0, 0, 74496, 0, 6674, 43397, 0, 1476, 0, 0, 72276, + 3233, 0, 0, 10164, 0, 0, 3530, 67243, 0, 111219, 6656, 0, 0, 74647, 8512, + 72275, 74261, 8967, 0, 0, 0, 72277, 7986, 73782, 120556, 9006, 983562, + 72273, 0, 7853, 0, 983355, 0, 0, 0, 0, 983952, 0, 0, 0, 0, 0, 0, 0, 0, + 127971, 67983, 13296, 517, 0, 0, 0, 41528, 19923, 65454, 0, 0, 0, 10531, + 7784, 41526, 71727, 0, 8057, 1126, 73895, 0, 0, 0, 119186, 4251, 8235, + 43142, 0, 489, 71733, 4250, 71731, 110721, 43151, 94177, 71725, 0, + 121238, 0, 0, 0, 110726, 0, 8711, 6183, 110722, 110723, 0, 0, 7623, 0, 0, + 9235, 12760, 74176, 0, 0, 0, 0, 3743, 11514, 11078, 74582, 0, 0, 126597, + 0, 0, 0, 0, 983888, 267, 3393, 127504, 2364, 0, 69233, 6958, 0, 6201, 0, + 42360, 0, 10652, 41612, 917802, 3402, 917801, 3398, 0, 0, 0, 3391, 70683, + 0, 92541, 128017, 126087, 126590, 0, 12767, 0, 983375, 64261, 0, 127537, + 70852, 70347, 0, 6673, 0, 0, 129346, 12438, 0, 0, 0, 71128, 0, 9053, + 43954, 74523, 0, 0, 0, 6195, 0, 6660, 0, 917760, 917793, 0, 12629, 0, 0, + 0, 0, 0, 127940, 0, 0, 0, 65448, 0, 0, 121084, 0, 43949, 0, 78099, 0, 0, + 0, 0, 0, 5741, 1131, 0, 0, 74862, 0, 43952, 42533, 119598, 78107, 0, 0, + 43950, 121297, 118990, 7691, 43951, 578, 0, 0, 0, 42514, 74547, 74196, + 120608, 74561, 0, 983957, 0, 0, 0, 0, 0, 0, 0, 0, 7241, 0, 93846, 119167, + 0, 12811, 78082, 3946, 0, 10998, 66807, 673, 0, 0, 0, 0, 119301, 0, + 68890, 0, 0, 78085, 10267, 0, 74560, 78083, 0, 8729, 0, 0, 0, 0, 0, 0, 0, + 119296, 0, 0, 0, 120853, 983458, 731, 0, 71904, 128316, 0, 0, 0, 1175, 0, + 68167, 0, 0, 10793, 0, 67644, 7723, 983453, 0, 0, 0, 0, 5273, 0, 5269, 0, + 69607, 2404, 5267, 124967, 0, 0, 5277, 0, 0, 6189, 65469, 1314, 0, 0, + 118873, 8785, 0, 0, 127527, 68414, 43535, 9204, 0, 3879, 0, 71696, 6197, + 9497, 0, 7567, 64484, 78128, 41390, 41379, 41882, 67647, 67279, 70085, 0, + 121413, 41388, 64446, 41392, 64288, 41387, 0, 8706, 10675, 0, 700, 0, + 5775, 0, 7088, 74756, 7499, 0, 78120, 78111, 67251, 126557, 0, 0, 128945, + 10311, 78115, 6665, 11115, 0, 7618, 10821, 11455, 0, 64632, 64447, 0, 0, + 78093, 78091, 0, 0, 65033, 0, 6668, 0, 0, 0, 656, 69686, 65037, 0, 0, 0, + 0, 0, 0, 0, 73014, 0, 0, 917774, 9702, 0, 92273, 66580, 118895, 66683, + 43640, 3417, 0, 6832, 0, 917768, 0, 917767, 0, 4935, 11906, 0, 0, 67296, + 92896, 3651, 0, 67294, 70848, 0, 67292, 0, 12983, 0, 55272, 0, 0, 1439, + 0, 74897, 0, 0, 0, 78373, 0, 42087, 3063, 0, 0, 7838, 0, 129282, 0, 0, + 67968, 0, 128582, 9078, 92446, 0, 0, 0, 0, 0, 0, 119586, 0, 7750, 128422, + 68237, 6190, 0, 0, 0, 72340, 9857, 7014, 9856, 0, 92620, 120547, 0, 8481, + 0, 6202, 0, 10920, 67970, 0, 0, 983292, 0, 7843, 65818, 66824, 0, 0, 0, + 0, 0, 0, 0, 6657, 207, 0, 69728, 74819, 0, 0, 0, 0, 0, 0, 0, 0, 41368, + 43974, 488, 0, 0, 71339, 10157, 0, 43034, 11982, 0, 0, 0, 0, 0, 41372, + 6669, 8504, 72103, 0, 41367, 129328, 119272, 0, 11726, 8261, 0, 304, 0, + 0, 0, 0, 113683, 983235, 238, 74522, 0, 0, 19905, 120577, 983469, 0, + 41044, 67640, 67302, 64814, 9912, 65939, 983465, 0, 0, 0, 0, 0, 0, 309, + 6622, 0, 10858, 0, 67636, 0, 72749, 0, 0, 0, 67637, 123138, 9712, 68680, + 43970, 0, 65165, 93047, 0, 0, 0, 0, 0, 0, 6191, 12944, 0, 0, 67634, + 43763, 0, 0, 67635, 9370, 41381, 0, 0, 123148, 118817, 0, 3222, 121439, + 0, 0, 66663, 0, 0, 0, 0, 0, 65732, 121144, 0, 0, 0, 0, 67309, 72192, + 41383, 64568, 0, 0, 0, 0, 983990, 66725, 0, 0, 0, 0, 0, 67306, 3632, + 128246, 0, 8376, 3648, 0, 74844, 67639, 3636, 0, 3650, 8837, 0, 0, 0, + 43250, 41562, 0, 0, 68839, 3640, 127190, 0, 11781, 0, 0, 0, 0, 0, 0, + 126649, 0, 42080, 2529, 0, 78004, 0, 42083, 0, 0, 120531, 67619, 0, 0, + 9634, 0, 0, 0, 0, 0, 0, 0, 68841, 0, 92545, 68874, 0, 0, 0, 41987, + 119667, 67623, 983760, 0, 925, 127156, 0, 41985, 64441, 9586, 120988, + 41984, 9217, 128372, 0, 0, 9186, 67620, 4016, 983815, 0, 381, 0, 0, + 42077, 0, 128777, 67622, 42078, 0, 10810, 0, 4585, 19943, 5860, 67633, 0, + 0, 812, 0, 0, 0, 92518, 0, 0, 0, 0, 67629, 0, 10692, 0, 67630, 0, 924, 0, + 67631, 42616, 0, 0, 0, 67317, 67632, 0, 12771, 12736, 12753, 0, 983734, + 67626, 67722, 0, 0, 0, 0, 12751, 74906, 8542, 0, 0, 3626, 66706, 0, 0, + 3883, 64388, 0, 0, 0, 0, 0, 0, 126268, 67624, 0, 10932, 0, 65585, 64338, + 806, 0, 41884, 110845, 1318, 128828, 0, 0, 0, 983789, 3465, 2405, 983390, + 0, 12756, 65259, 69381, 983793, 12752, 5833, 1432, 110843, 41883, 110841, + 9799, 0, 41886, 0, 0, 2062, 0, 0, 0, 0, 129376, 0, 124969, 0, 0, 120971, + 0, 118832, 0, 0, 0, 68005, 10622, 0, 0, 0, 6566, 71195, 0, 73780, 0, + 68865, 0, 0, 0, 8284, 0, 0, 0, 0, 0, 43023, 0, 983285, 6642, 3977, 72743, + 64729, 836, 983381, 92947, 0, 0, 0, 0, 0, 0, 125239, 917923, 0, 0, 0, 0, + 0, 0, 1374, 65149, 119014, 67720, 0, 2273, 0, 0, 0, 11234, 0, 0, 9630, + 12597, 0, 0, 0, 6661, 0, 113751, 0, 125015, 0, 0, 72151, 0, 73674, 7718, + 113755, 0, 0, 0, 0, 983758, 0, 0, 0, 127841, 6365, 1887, 0, 0, 8080, + 113681, 0, 0, 0, 0, 1544, 0, 0, 64677, 0, 0, 0, 0, 119019, 0, 0, 12812, + 7342, 0, 73784, 0, 7904, 0, 0, 120910, 0, 0, 0, 0, 9724, 0, 983785, 9524, + 0, 0, 0, 0, 0, 129344, 0, 471, 0, 0, 128302, 0, 0, 0, 983750, 0, 0, 6918, + 0, 0, 5156, 0, 128683, 10232, 10615, 10213, 0, 0, 42528, 0, 0, 0, 0, + 65311, 74935, 0, 13306, 10533, 7870, 0, 7625, 0, 120544, 0, 0, 128816, + 126098, 0, 0, 0, 0, 0, 92341, 0, 12978, 128533, 0, 0, 43836, 42675, 0, + 12845, 0, 19942, 0, 0, 0, 0, 0, 120000, 120008, 120001, 0, 194894, 0, 0, + 0, 0, 7186, 73107, 0, 70093, 445, 0, 0, 0, 0, 73047, 0, 0, 128442, 0, 0, + 0, 3902, 68913, 0, 0, 0, 1560, 43958, 0, 4584, 0, 67862, 0, 10866, 92905, + 1118, 92209, 74888, 0, 1081, 7436, 11147, 7252, 0, 121188, 0, 0, 0, + 41386, 5162, 0, 1330, 0, 121270, 0, 12047, 7675, 0, 0, 1848, 74528, + 983147, 64708, 0, 0, 194880, 0, 0, 0, 983753, 12715, 128349, 0, 0, 0, + 66672, 73710, 66685, 0, 0, 92464, 0, 68884, 0, 72835, 0, 70800, 70101, + 120725, 0, 194893, 9214, 43494, 0, 0, 120841, 0, 0, 6313, 65513, 0, 0, 0, + 0, 2345, 72975, 0, 0, 0, 0, 3117, 0, 71882, 0, 73100, 0, 0, 0, 0, 78415, + 983232, 100907, 0, 13248, 0, 120241, 129416, 128415, 0, 121009, 12382, + 71120, 0, 0, 0, 0, 1471, 0, 113747, 0, 12378, 0, 69664, 0, 12374, 121357, + 0, 0, 0, 0, 0, 0, 12376, 0, 0, 0, 12380, 10557, 0, 12520, 11122, 2024, + 127180, 0, 0, 74588, 0, 0, 70120, 3853, 0, 0, 0, 983744, 0, 0, 12090, 0, + 12474, 92579, 9503, 0, 0, 983271, 68318, 0, 110834, 0, 0, 0, 12470, 0, + 74189, 2742, 12476, 66370, 10946, 0, 12472, 0, 0, 0, 0, 8213, 43824, + 7771, 6161, 983275, 68010, 0, 0, 0, 68235, 0, 0, 0, 120985, 0, 0, 0, 0, + 73791, 0, 68871, 0, 0, 0, 0, 0, 73704, 12015, 128561, 8275, 0, 43459, + 120927, 127555, 0, 0, 0, 68881, 71215, 0, 118841, 0, 12516, 4444, 0, + 119017, 120506, 10892, 118828, 0, 6473, 0, 0, 71735, 3591, 0, 0, 0, 0, + 72345, 0, 0, 0, 127547, 0, 0, 0, 0, 128253, 0, 0, 0, 0, 94060, 687, 0, 0, + 983399, 0, 0, 68671, 0, 128526, 285, 0, 0, 0, 4459, 0, 0, 74917, 0, 0, + 126255, 0, 119248, 0, 9743, 0, 0, 126535, 0, 0, 73104, 0, 69659, 0, 0, + 3081, 74577, 42921, 0, 0, 0, 0, 0, 0, 0, 9125, 119023, 0, 120820, 0, + 65221, 0, 0, 64852, 0, 0, 0, 0, 66578, 5001, 41879, 0, 0, 5003, 884, 0, + 0, 4943, 5150, 73889, 74182, 0, 41876, 0, 0, 42448, 42299, 72804, 0, 0, + 0, 0, 8491, 0, 0, 983635, 4530, 42409, 7126, 119526, 66200, 0, 0, 19929, + 0, 0, 0, 4242, 0, 0, 0, 0, 66034, 65941, 124929, 64522, 10740, 8958, + 128257, 9754, 119102, 983246, 74222, 983244, 983243, 119064, 983241, + 983240, 0, 0, 0, 74518, 66026, 4306, 41468, 68432, 0, 0, 66667, 0, 0, + 983494, 42200, 0, 0, 0, 120236, 6948, 0, 8524, 0, 0, 12385, 0, 74926, 0, + 1386, 73996, 0, 0, 0, 121184, 12392, 0, 8064, 0, 0, 78216, 119004, 2080, + 710, 128491, 12390, 1666, 42091, 0, 12383, 92968, 42092, 68418, 0, + 128106, 0, 0, 42096, 0, 3362, 12377, 127878, 0, 0, 0, 0, 1244, 4401, + 73786, 12683, 10662, 0, 8112, 0, 119021, 121017, 12379, 73108, 120534, 0, + 42208, 0, 12381, 0, 0, 0, 4327, 0, 0, 128350, 0, 78232, 0, 584, 12933, 0, + 12373, 73105, 13000, 0, 2935, 129113, 12665, 0, 43081, 73098, 120505, + 12427, 0, 983625, 78227, 0, 0, 0, 0, 0, 74551, 0, 0, 12426, 0, 0, 0, + 12428, 0, 0, 0, 0, 0, 12429, 6727, 0, 0, 0, 3387, 0, 0, 0, 0, 0, 0, + 74427, 0, 3536, 120589, 9752, 92397, 6162, 0, 0, 10113, 0, 0, 0, 12422, + 0, 439, 3072, 0, 42207, 74549, 120830, 0, 0, 0, 0, 8308, 0, 70807, 0, 0, + 0, 13218, 0, 0, 8082, 12424, 0, 6819, 3539, 93838, 0, 0, 74539, 0, 68181, + 0, 72964, 0, 72969, 12420, 11371, 0, 4600, 0, 127810, 0, 0, 0, 72962, + 128552, 6704, 4591, 72966, 0, 0, 0, 72960, 120623, 561, 12159, 78223, 0, + 78224, 0, 71068, 11932, 7172, 42687, 8368, 0, 0, 93068, 0, 0, 75010, 0, + 0, 0, 0, 42463, 0, 2924, 67183, 0, 0, 0, 128958, 0, 0, 42330, 73079, + 3969, 0, 0, 7169, 1992, 9652, 0, 0, 42086, 0, 100865, 0, 0, 0, 0, 0, 327, + 0, 0, 0, 0, 0, 12433, 0, 0, 0, 12431, 0, 12434, 983434, 0, 0, 0, 7712, + 12432, 0, 69377, 129147, 100867, 0, 8212, 0, 128014, 0, 119066, 7333, 0, + 0, 0, 67407, 70006, 128461, 0, 12436, 0, 43160, 0, 74896, 92757, 71360, + 42350, 0, 0, 0, 100566, 0, 11348, 0, 0, 9194, 983184, 0, 55250, 0, + 100569, 0, 0, 0, 0, 0, 64746, 66012, 100565, 3444, 75029, 64651, 0, + 41503, 0, 0, 0, 0, 0, 0, 0, 120876, 0, 0, 129408, 65309, 12416, 0, 0, 0, + 0, 93024, 12418, 74111, 121046, 0, 0, 0, 0, 0, 4596, 66339, 12417, 66001, + 0, 126491, 12414, 8287, 0, 0, 0, 1143, 0, 0, 12415, 0, 0, 983242, 0, + 9021, 120783, 0, 11724, 0, 0, 0, 194794, 0, 0, 8027, 194796, 74257, + 127375, 11400, 74197, 194799, 66833, 194798, 0, 0, 983247, 0, 0, 1324, 0, + 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, + 0, 0, 8005, 12365, 0, 0, 3756, 12369, 10649, 0, 0, 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, + 0, 0, 0, 0, 0, 43414, 0, 0, 65675, 0, 67179, 67168, 12413, 0, 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, + 6631, 128923, 0, 74583, 42218, 0, 0, 0, 0, 0, 0, 71058, 0, 0, 0, 0, 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, 12177, 0, 0, 0, + 0, 0, 12395, 127874, 12878, 92630, 12396, 0, 0, 92537, 0, 43113, 0, 0, 0, + 9781, 0, 4927, 0, 0, 0, 0, 12397, 129089, 128910, 0, 12394, 0, 0, 0, 0, + 0, 72789, 10781, 1546, 0, 5010, 0, 10507, 127891, 128291, 0, 0, 0, 0, + 7267, 0, 0, 0, 0, 2819, 0, 0, 71063, 0, 7266, 128553, 7264, 7265, 0, + 1363, 0, 119581, 65080, 0, 0, 0, 0, 43336, 0, 0, 126263, 73776, 0, 43339, + 0, 9836, 0, 0, 0, 43335, 41276, 0, 73795, 43337, 817, 11211, 9922, + 128841, 41274, 11340, 42408, 42447, 74932, 0, 0, 12386, 0, 0, 0, 12389, + 128398, 0, 41996, 41686, 0, 8269, 1147, 43849, 120896, 1987, 128540, + 43195, 42001, 41990, 41999, 12391, 0, 0, 4939, 12384, 0, 0, 43243, 0, 0, + 0, 0, 0, 0, 0, 0, 8247, 0, 0, 7545, 0, 43643, 121445, 0, 10036, 0, + 119813, 10178, 119816, 0, 119815, 11762, 119818, 0, 92282, 120597, 0, 0, + 119819, 0, 0, 7719, 0, 2486, 0, 119808, 1507, 0, 129185, 70301, 9687, + 119826, 0, 119811, 66196, 0, 5262, 0, 74642, 12681, 0, 0, 12406, 12219, + 0, 127528, 42810, 110991, 0, 983673, 128144, 121027, 126096, 120753, + 12403, 2500, 0, 0, 12409, 0, 0, 0, 74113, 2343, 12412, 19946, 74112, + 125042, 13112, 0, 120603, 67866, 110634, 0, 66369, 5861, 110632, 11999, + 12400, 0, 0, 12645, 0, 11320, 68410, 6748, 65040, 0, 64184, 12974, 66927, + 67613, 120645, 0, 0, 0, 0, 0, 1928, 0, 67649, 0, 0, 67609, 11235, 0, 0, + 67610, 8241, 0, 0, 4206, 0, 0, 0, 128298, 110980, 0, 67238, 0, 0, 0, + 1422, 8357, 0, 7187, 0, 120641, 0, 0, 0, 0, 125022, 111064, 92539, 10120, + 12405, 0, 72997, 0, 13278, 0, 6366, 0, 7945, 0, 4402, 0, 12402, 129372, + 0, 74754, 12408, 0, 44007, 0, 0, 0, 12411, 0, 120824, 128306, 121092, 0, + 1575, 0, 0, 0, 73003, 119622, 0, 0, 12399, 0, 6833, 0, 0, 0, 71878, 9692, + 0, 0, 100615, 6750, 66855, 0, 0, 0, 0, 43527, 0, 727, 0, 0, 0, 0, 6726, + 0, 0, 12370, 44023, 0, 126592, 2280, 0, 12372, 120642, 0, 0, 0, 0, 12366, + 10963, 6066, 1329, 0, 3052, 72987, 0, 66029, 0, 10803, 0, 0, 0, 92473, 0, + 0, 0, 0, 1499, 0, 0, 42740, 0, 0, 0, 0, 12056, 126484, 0, 3660, 69404, + 42192, 74253, 0, 42223, 67617, 125254, 0, 0, 0, 0, 9941, 0, 0, 1933, 0, + 0, 0, 0, 73866, 0, 0, 2487, 67614, 7361, 1804, 0, 67615, 0, 0, 12220, + 67616, 0, 0, 0, 68200, 6675, 0, 0, 67592, 126582, 0, 64771, 0, 9132, 0, + 111004, 510, 0, 0, 0, 4561, 7711, 92769, 92944, 111007, 0, 41569, 121282, + 0, 8167, 66885, 0, 0, 0, 69992, 66403, 6967, 0, 0, 0, 0, 333, 0, 0, + 10566, 66409, 0, 121373, 0, 72965, 110999, 66388, 6678, 0, 0, 12621, 0, + 128775, 10227, 4764, 0, 9981, 0, 70278, 11589, 0, 0, 42202, 12754, 0, 0, + 0, 0, 67594, 2048, 0, 4050, 67595, 0, 0, 43221, 11184, 72709, 0, 0, + 64175, 0, 72746, 0, 0, 0, 65461, 9798, 0, 71210, 0, 69841, 0, 952, + 128235, 125107, 0, 70296, 6449, 72102, 0, 0, 43098, 64171, 8142, 64160, + 0, 0, 0, 0, 0, 0, 0, 0, 67597, 6676, 3930, 42615, 73124, 69991, 67598, 0, + 0, 0, 65591, 41581, 128056, 1453, 0, 0, 0, 8500, 42222, 0, 119270, 72992, + 69996, 0, 0, 64676, 0, 0, 67606, 66385, 0, 42217, 13102, 0, 67607, 6672, + 0, 0, 0, 0, 67608, 0, 9001, 0, 11274, 67601, 0, 64210, 6664, 0, 42056, + 67602, 0, 0, 0, 0, 1469, 67603, 65381, 69921, 4988, 42372, 0, 9598, 904, + 352, 42225, 0, 8061, 10673, 0, 0, 128276, 67600, 0, 0, 127293, 8575, + 127295, 127296, 127289, 127290, 127291, 127292, 127285, 127286, 127287, + 118877, 127281, 127282, 9460, 823, 11587, 0, 0, 0, 127305, 12387, 0, 0, + 127301, 126979, 42783, 69998, 64208, 127298, 127299, 66031, 0, 11606, + 64784, 0, 69973, 0, 0, 0, 5152, 11048, 0, 120121, 67605, 0, 69604, 0, + 70276, 194847, 0, 127052, 42587, 42214, 41394, 0, 4763, 0, 118935, 0, + 5260, 0, 94038, 326, 120131, 74119, 0, 10771, 42198, 194920, 194837, + 194925, 41398, 127079, 41393, 127077, 127076, 453, 41396, 0, 13159, + 11227, 9572, 0, 0, 194576, 128835, 127081, 0, 126617, 43144, 0, 72972, + 194887, 0, 0, 0, 0, 0, 64061, 0, 0, 64056, 70310, 0, 0, 0, 194864, 0, + 111084, 64301, 72998, 10464, 0, 128393, 72847, 0, 11528, 64024, 128072, + 679, 0, 0, 5850, 758, 7536, 0, 0, 43712, 0, 64006, 983579, 64005, 70298, + 0, 126487, 0, 0, 0, 0, 0, 72999, 0, 64027, 64029, 0, 0, 64000, 0, 194874, + 0, 42201, 12421, 194876, 0, 1852, 0, 0, 73744, 0, 64041, 129127, 0, 0, 0, + 92322, 12423, 12854, 0, 3496, 0, 110966, 0, 194823, 0, 0, 6158, 8327, + 74553, 0, 12419, 0, 11570, 0, 0, 123618, 0, 7844, 983801, 194909, 0, + 1682, 93039, 194911, 42756, 6765, 128178, 0, 0, 0, 11412, 6768, 0, + 194830, 71316, 0, 0, 0, 11577, 0, 194829, 1833, 11576, 74334, 0, 0, + 42854, 69438, 0, 70307, 0, 194856, 8085, 0, 194850, 0, 72996, 128778, + 1949, 11614, 7847, 120489, 120997, 64483, 0, 0, 0, 0, 0, 0, 0, 126651, + 42864, 0, 64667, 74624, 0, 0, 43261, 11484, 127535, 67840, 0, 0, 128965, + 0, 72974, 0, 110928, 128454, 3455, 0, 0, 9879, 0, 0, 4158, 128050, 0, 0, + 110929, 0, 0, 0, 332, 118808, 0, 0, 2407, 0, 42199, 92386, 110865, 0, + 77921, 55217, 123161, 125199, 70043, 0, 0, 0, 121093, 1834, 0, 0, 71315, + 0, 65249, 0, 8662, 0, 0, 123153, 0, 11539, 10784, 0, 67674, 0, 92233, 0, + 0, 118858, 0, 0, 0, 0, 0, 0, 12499, 6280, 0, 0, 0, 0, 0, 0, 43851, 6279, + 12508, 0, 12502, 9161, 0, 1620, 0, 3601, 0, 0, 67246, 609, 11555, 0, + 12496, 0, 74181, 120492, 12505, 0, 194902, 0, 43567, 239, 0, 127085, 0, + 0, 42671, 0, 0, 83095, 43565, 127082, 983936, 12696, 127753, 0, 94062, + 12929, 0, 712, 0, 4197, 0, 42818, 0, 70306, 0, 0, 983805, 0, 43562, 0, + 129034, 68076, 0, 111074, 64628, 0, 0, 0, 0, 7494, 0, 4924, 0, 0, 0, 0, + 127088, 0, 127087, 69987, 64796, 0, 0, 12033, 0, 0, 0, 0, 0, 0, 0, 70299, + 0, 0, 68324, 72420, 0, 0, 0, 0, 70309, 127000, 0, 0, 0, 72418, 72963, 0, + 5699, 0, 983879, 9488, 74410, 119112, 70477, 11170, 0, 0, 72312, 0, 5265, + 0, 0, 0, 0, 12464, 0, 43264, 72977, 0, 43345, 0, 0, 120592, 6807, 0, + 9829, 69997, 0, 0, 43346, 11393, 795, 0, 72412, 12462, 72416, 72415, 0, + 0, 64362, 0, 0, 120811, 0, 12468, 8607, 1008, 0, 120670, 0, 0, 67855, + 125018, 127177, 6758, 0, 0, 1820, 41112, 0, 11202, 195083, 0, 13223, 0, + 64595, 0, 0, 0, 0, 12616, 0, 0, 0, 74467, 0, 0, 0, 0, 0, 0, 67233, + 119060, 0, 83448, 19920, 69897, 0, 129057, 0, 1130, 0, 0, 0, 11823, 0, 0, + 118896, 0, 0, 13280, 0, 10747, 118925, 0, 43509, 0, 0, 8959, 0, 6747, 0, + 0, 8568, 0, 120870, 0, 120803, 83060, 42670, 0, 11621, 12460, 0, 0, 0, 0, + 111190, 0, 66570, 72989, 121305, 126476, 120582, 0, 0, 0, 111191, 70308, + 11594, 0, 68333, 69427, 10491, 0, 0, 0, 0, 0, 127506, 0, 194910, 4923, + 65086, 8981, 0, 42133, 0, 72244, 0, 70294, 0, 0, 12485, 0, 8642, 0, + 42766, 0, 2210, 11109, 0, 0, 0, 0, 0, 7398, 0, 0, 0, 8041, 1461, 0, + 119133, 0, 6749, 0, 0, 0, 71705, 0, 0, 68071, 0, 67668, 0, 0, 9193, 0, 0, + 0, 0, 73810, 0, 0, 64305, 0, 0, 623, 781, 670, 10660, 5769, 613, 7543, 0, + 477, 92633, 92521, 0, 592, 0, 12459, 0, 0, 0, 12465, 119578, 654, 11345, + 653, 652, 111250, 647, 0, 633, 120744, 0, 111262, 12480, 74354, 0, 39, + 12487, 0, 0, 74803, 12482, 0, 12489, 0, 128962, 5550, 129175, 0, 0, 0, 0, + 1813, 0, 41311, 111205, 0, 11229, 0, 70496, 1675, 69840, 129435, 0, + 119078, 10070, 10595, 111207, 119077, 111206, 121162, 0, 0, 0, 11222, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 71716, 917841, 0, 0, 270, 0, 0, 0, 0, 0, + 120899, 0, 69741, 0, 0, 68251, 0, 71721, 364, 9595, 0, 0, 0, 707, 0, 0, + 9282, 0, 224, 0, 68670, 9332, 65581, 68677, 0, 68644, 0, 11764, 68634, 0, + 10732, 68640, 850, 0, 0, 71123, 0, 68619, 44008, 68627, 0, 0, 0, 0, 0, 0, + 0, 0, 12507, 0, 0, 128311, 0, 120529, 4375, 0, 0, 0, 12198, 0, 67339, 0, + 0, 72994, 74293, 128434, 0, 0, 64546, 0, 71208, 0, 0, 0, 42334, 42502, 0, + 120887, 72961, 0, 0, 5767, 0, 0, 71710, 8353, 0, 0, 0, 121233, 0, 0, 0, + 0, 119920, 0, 0, 121186, 0, 0, 0, 72719, 64604, 0, 6096, 0, 10063, 0, 0, + 119630, 3485, 12987, 0, 127522, 0, 0, 0, 0, 0, 0, 0, 0, 127173, 0, 0, + 68249, 0, 0, 118923, 0, 64574, 128794, 0, 1640, 12495, 66691, 0, 3138, + 12504, 11171, 1922, 0, 12498, 0, 0, 69939, 0, 65543, 0, 0, 0, 66643, 0, + 120734, 0, 4228, 0, 10303, 0, 0, 0, 10335, 3520, 0, 12490, 0, 0, 0, + 12493, 121452, 64636, 1002, 12491, 0, 0, 92615, 2096, 0, 0, 0, 0, 11611, + 66228, 0, 11241, 66224, 66221, 66226, 66229, 66219, 66231, 66216, 0, + 66236, 66211, 66218, 0, 66240, 78041, 66233, 66217, 0, 7909, 66234, + 11605, 0, 0, 66208, 0, 0, 128282, 73875, 0, 12898, 12494, 120939, 12492, + 0, 0, 0, 74153, 0, 127391, 127489, 4882, 13040, 0, 120762, 4885, 194732, + 0, 13042, 4880, 128834, 2429, 0, 8647, 0, 0, 0, 0, 0, 0, 68896, 0, + 119101, 66693, 0, 1870, 78040, 470, 68893, 78035, 78036, 983581, 78034, + 110607, 110608, 0, 12511, 74453, 12514, 0, 128609, 7239, 7001, 11974, + 121214, 0, 0, 7378, 12512, 11615, 13041, 0, 0, 128057, 13038, 0, 0, + 71717, 70195, 120836, 12510, 127070, 13039, 75019, 12513, 0, 12471, + 110761, 0, 121385, 70193, 0, 0, 0, 71714, 0, 12477, 0, 12473, 7666, + 67362, 237, 6281, 0, 0, 0, 0, 1312, 0, 0, 12469, 0, 0, 64335, 12475, 0, + 69382, 0, 11524, 10367, 10431, 74368, 13017, 3388, 129547, 74372, 0, 0, + 128725, 4932, 0, 0, 13015, 0, 0, 65451, 8185, 0, 0, 43024, 129362, 74375, + 10129, 0, 7948, 9236, 0, 0, 0, 92726, 43473, 6289, 10484, 0, 0, 0, 12082, + 12521, 3147, 110643, 110644, 12524, 110642, 2310, 0, 0, 0, 0, 13013, 0, + 8596, 983852, 10804, 70497, 0, 0, 13014, 12444, 0, 71697, 13016, 0, 0, 0, + 0, 12331, 0, 0, 8744, 726, 121090, 983849, 4155, 0, 0, 0, 71690, 12522, + 73128, 0, 0, 127805, 0, 110647, 0, 0, 983853, 12525, 0, 12523, 2152, + 11969, 120596, 403, 0, 11021, 0, 0, 11030, 8610, 92567, 0, 0, 63998, 0, + 0, 0, 0, 0, 0, 0, 12506, 0, 11146, 71477, 12500, 0, 12509, 0, 0, 0, 0, + 6608, 0, 0, 0, 0, 0, 77995, 0, 3608, 0, 0, 1107, 0, 129658, 0, 0, 0, 0, + 983937, 43217, 66571, 13222, 118963, 0, 126514, 10463, 11553, 0, 63995, + 9043, 128634, 71722, 0, 0, 127751, 92974, 12529, 8042, 0, 2344, 12528, 0, + 0, 0, 69719, 120956, 0, 0, 66512, 0, 12530, 0, 0, 68917, 12658, 0, 71683, + 0, 983237, 0, 127526, 469, 0, 4363, 3313, 0, 0, 2023, 0, 72251, 78225, + 65706, 10051, 78219, 78220, 0, 9920, 12215, 0, 4931, 1951, 12497, 119363, + 0, 0, 119336, 0, 0, 0, 0, 0, 1491, 128578, 129169, 0, 0, 0, 0, 78898, + 94086, 41993, 0, 67379, 0, 0, 0, 0, 9738, 41995, 1075, 0, 12535, 41992, + 0, 0, 0, 0, 128117, 0, 9940, 0, 7692, 0, 9727, 41131, 330, 8566, 0, + 41133, 41117, 128482, 12532, 78550, 78546, 43177, 0, 43235, 0, 917542, + 78229, 78231, 13031, 12910, 67710, 78555, 13028, 78553, 12537, 0, 0, + 71692, 12536, 2350, 13029, 78233, 0, 0, 13030, 0, 4527, 71250, 12538, 0, + 0, 0, 0, 0, 0, 0, 12484, 4032, 71459, 194728, 0, 64344, 0, 66700, 66000, + 8412, 0, 43466, 1296, 2325, 0, 121020, 10149, 74118, 0, 0, 12481, 121280, + 12488, 0, 0, 0, 67972, 0, 2354, 42619, 0, 73027, 6295, 901, 0, 0, 0, 0, + 0, 128653, 11927, 66584, 78559, 78560, 78557, 78558, 0, 74649, 0, 126241, + 67220, 194726, 78568, 67226, 78565, 70190, 78563, 78564, 2352, 67219, + 78569, 78570, 11289, 1407, 67973, 0, 13026, 6762, 10399, 70192, 13023, + 78578, 9777, 67208, 1871, 0, 0, 0, 13024, 983835, 0, 9325, 6818, 6283, + 11738, 0, 0, 0, 11741, 0, 0, 9216, 8263, 11279, 0, 983837, 0, 13021, + 71922, 3136, 0, 983840, 0, 13022, 129143, 9956, 0, 0, 0, 42580, 0, 0, 0, + 13020, 10024, 0, 94013, 0, 0, 0, 43001, 8029, 0, 0, 0, 3335, 0, 9209, + 13048, 73126, 0, 0, 0, 3333, 119100, 0, 0, 3342, 78582, 78583, 73056, + 78581, 4156, 0, 0, 0, 78591, 1611, 73058, 13018, 78586, 78588, 78584, + 3337, 4537, 78593, 11736, 0, 0, 0, 4214, 73790, 0, 0, 13046, 0, 425, + 74763, 42066, 78595, 0, 2392, 13047, 0, 0, 12425, 13049, 0, 92243, 0, + 72715, 73944, 13050, 0, 0, 0, 0, 0, 0, 0, 8929, 0, 0, 0, 0, 983971, 0, + 13045, 0, 0, 7751, 0, 9726, 0, 3997, 0, 8768, 13044, 0, 0, 4024, 0, 0, + 2419, 9757, 69736, 0, 0, 0, 129500, 0, 0, 0, 72735, 0, 0, 0, 0, 0, 11911, + 124990, 0, 2346, 194691, 69931, 0, 9646, 3773, 43557, 68154, 42536, 0, + 70108, 13043, 92686, 92494, 0, 208, 0, 43766, 0, 0, 0, 10699, 0, 0, 7825, + 7110, 111275, 0, 111274, 41109, 2398, 111271, 0, 0, 0, 0, 0, 0, 72723, + 8294, 42912, 129343, 0, 0, 4876, 111316, 0, 111326, 111282, 0, 0, 0, + 73950, 13053, 9944, 0, 2811, 13051, 111313, 3143, 111246, 66374, 110759, + 0, 0, 13052, 0, 0, 63972, 119071, 7025, 0, 0, 100464, 74161, 4154, 9863, + 0, 0, 0, 63970, 1564, 0, 0, 0, 0, 0, 9942, 0, 0, 111227, 0, 128471, 0, + 63957, 0, 1626, 0, 63983, 0, 111232, 0, 0, 121275, 111292, 6254, 4910, + 69453, 0, 64753, 100458, 111303, 111298, 127404, 111297, 3229, 0, 42774, + 0, 0, 111218, 111286, 2331, 0, 7085, 6137, 0, 70411, 0, 126070, 0, + 128438, 0, 0, 65043, 0, 127588, 70412, 128921, 64721, 0, 0, 0, 0, 0, + 983770, 0, 0, 5311, 0, 965, 0, 11993, 78055, 11278, 128787, 0, 0, 0, + 121076, 120705, 0, 6294, 3144, 0, 0, 65019, 0, 0, 0, 0, 0, 63966, 2330, + 535, 3148, 12375, 110774, 0, 10556, 2475, 12388, 4889, 0, 67863, 0, 0, + 72750, 2342, 0, 0, 0, 4894, 0, 4890, 0, 0, 0, 4893, 128426, 6571, 0, + 4888, 4157, 78048, 78049, 78046, 11263, 0, 78045, 64895, 121437, 0, 0, 0, + 0, 0, 119041, 2332, 78063, 78060, 78061, 64932, 78059, 65125, 121098, 0, + 0, 0, 73941, 78066, 12203, 78064, 78065, 8913, 120390, 4875, 73678, + 120396, 120389, 71854, 0, 120394, 120386, 120395, 13104, 78076, 78077, + 120393, 78075, 0, 3134, 83096, 65696, 72432, 0, 0, 0, 8334, 0, 83207, + 3449, 0, 0, 83215, 0, 0, 0, 83204, 0, 0, 0, 69707, 0, 0, 10734, 0, 83198, + 83108, 7804, 121401, 83166, 8457, 83212, 0, 11367, 0, 78054, 0, 72762, 0, + 64285, 0, 5464, 0, 83100, 2361, 7971, 78072, 78073, 78070, 78071, 0, + 8086, 0, 6707, 0, 2312, 40977, 0, 40962, 0, 0, 74962, 40980, 0, 0, 0, + 40970, 92895, 110823, 0, 42438, 72752, 6288, 0, 127946, 5653, 42400, + 10891, 73946, 5658, 70401, 0, 0, 0, 0, 71060, 0, 0, 42326, 100482, 92191, + 92685, 42478, 2327, 0, 12959, 42287, 92883, 0, 83081, 917550, 0, 0, 2867, + 128562, 66312, 698, 0, 0, 0, 70017, 0, 8000, 12641, 83140, 0, 0, 129064, + 0, 72979, 83133, 0, 83134, 0, 0, 111011, 92960, 74356, 0, 74562, 0, + 72745, 0, 0, 120568, 0, 0, 0, 0, 0, 8703, 5462, 83195, 0, 10101, 0, + 70049, 0, 0, 128793, 0, 0, 66254, 120821, 0, 0, 123621, 0, 119194, 0, + 42651, 0, 0, 917847, 83227, 83218, 0, 75011, 0, 917846, 0, 64399, 0, + 12899, 74564, 0, 42206, 0, 72718, 71715, 83149, 983775, 83146, 12192, + 917826, 0, 0, 0, 0, 68056, 0, 67426, 128687, 0, 0, 0, 0, 0, 0, 67431, + 71718, 74357, 0, 121176, 43596, 6090, 0, 7812, 10534, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 43306, 0, 0, 0, 7930, 0, 2292, 0, 0, 72737, 0, 6130, 0, 0, + 0, 0, 0, 70463, 968, 0, 0, 0, 43304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11838, + 0, 0, 0, 42682, 0, 0, 0, 41227, 0, 71475, 0, 64848, 0, 78574, 0, 113792, + 0, 0, 129133, 0, 66015, 74614, 959, 8885, 0, 0, 0, 9469, 9632, 128211, + 74761, 64323, 100478, 0, 2266, 78575, 310, 0, 0, 68403, 100480, 72738, + 125279, 0, 0, 6497, 0, 0, 0, 19958, 0, 0, 74953, 0, 118998, 67332, 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, 983571, 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, 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, + 11414, 0, 2531, 13034, 0, 0, 0, 13036, 0, 70866, 70198, 10394, 0, 13037, + 0, 0, 0, 0, 100496, 120640, 41129, 0, 42850, 13035, 0, 0, 5466, 0, 0, 0, + 0, 4535, 0, 4271, 0, 0, 6769, 0, 0, 67350, 6767, 0, 66273, 0, 6755, + 73827, 9046, 67355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83235, 2563, 13033, 247, + 83229, 0, 12338, 0, 83231, 11270, 0, 0, 0, 0, 70107, 0, 0, 0, 0, 3752, + 83243, 68895, 0, 68897, 0, 0, 0, 0, 5009, 0, 0, 0, 0, 119521, 78823, + 78824, 70353, 68399, 3877, 0, 78825, 10145, 43566, 0, 0, 10236, 0, 43782, + 0, 127329, 0, 69652, 118921, 120612, 128058, 0, 43200, 43777, 71253, 0, + 83254, 0, 71866, 43203, 0, 68894, 0, 127326, 0, 43778, 119538, 0, 0, + 43781, 11303, 65547, 0, 7031, 0, 0, 67343, 83237, 83267, 0, 67341, 0, + 8535, 0, 0, 0, 66032, 0, 0, 120786, 42233, 0, 9946, 7667, 0, 11822, 0, + 43189, 120673, 100507, 2979, 1579, 0, 0, 0, 0, 0, 12635, 0, 0, 94055, 0, + 1285, 64882, 0, 0, 83113, 12640, 83112, 7401, 0, 12625, 0, 71296, 72744, + 0, 74286, 55260, 3396, 12642, 0, 110719, 0, 12630, 0, 0, 10153, 0, 6166, + 120516, 0, 110680, 0, 0, 0, 9285, 913, 42259, 83017, 0, 2142, 0, 0, + 94012, 7878, 0, 72733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128918, 5263, 74782, 0, + 41939, 43702, 0, 917856, 0, 10139, 980, 43698, 0, 2208, 0, 43701, 0, + 125132, 0, 100528, 0, 10085, 0, 0, 119989, 100529, 0, 71699, 0, 8072, 0, + 43700, 0, 7304, 7783, 66894, 12398, 0, 0, 0, 0, 0, 0, 120565, 0, 2217, 0, + 94015, 6367, 0, 66688, 0, 0, 0, 0, 0, 92199, 7808, 1829, 0, 41937, 0, + 43272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6627, 0, 6258, 10683, 0, 0, 0, + 5649, 0, 0, 0, 1643, 127898, 0, 127846, 67244, 0, 42452, 0, 0, 0, 0, + 64291, 0, 0, 0, 6576, 74773, 0, 0, 66309, 0, 9886, 55225, 11292, 0, + 72867, 55227, 0, 12632, 0, 194817, 0, 7680, 0, 92745, 120714, 12639, + 3380, 8123, 0, 12638, 42262, 4501, 0, 0, 0, 0, 125131, 1494, 983146, 0, + 0, 0, 0, 10494, 0, 65872, 0, 0, 0, 0, 0, 0, 983575, 0, 0, 0, 0, 0, 0, 0, + 71077, 0, 127335, 121128, 0, 5570, 1881, 7210, 0, 1012, 66630, 0, 128982, + 7208, 66442, 5569, 113723, 42339, 92655, 0, 0, 0, 0, 92378, 65602, 0, + 92375, 64727, 9160, 0, 0, 0, 124928, 10503, 0, 3423, 3870, 8483, 10162, + 0, 4319, 0, 0, 0, 0, 0, 983116, 0, 0, 0, 0, 0, 0, 0, 0, 5571, 7630, 9740, + 9121, 5568, 0, 0, 42085, 0, 0, 65056, 0, 589, 0, 0, 0, 10233, 66252, + 66251, 78734, 66253, 0, 0, 42645, 0, 128424, 8583, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 12204, 92436, 0, 0, 0, 0, 0, 0, 0, 70311, 0, 0, 128012, 41063, 0, + 10664, 0, 0, 0, 4551, 129090, 74759, 0, 0, 0, 0, 72806, 0, 0, 12517, + 7806, 0, 12034, 0, 6355, 12519, 41004, 0, 0, 93849, 0, 71707, 0, 121231, + 7332, 129075, 12111, 3927, 0, 12515, 1474, 68768, 0, 6923, 0, 0, 127802, + 0, 43990, 74639, 126229, 121007, 0, 92706, 0, 0, 0, 0, 0, 9645, 0, + 121026, 5853, 0, 10363, 120729, 12956, 0, 0, 0, 0, 127888, 0, 0, 0, 0, 0, + 10514, 65517, 0, 0, 71101, 0, 0, 0, 43570, 2969, 43420, 0, 0, 0, 92366, + 70809, 0, 0, 0, 0, 0, 0, 12125, 41124, 0, 1164, 128817, 0, 120466, 0, 0, + 65014, 66009, 74451, 128760, 983128, 7469, 0, 0, 0, 69988, 120671, 83171, + 41123, 11176, 0, 0, 41126, 9991, 41128, 0, 0, 110949, 0, 0, 42877, 7994, + 0, 6104, 983612, 0, 0, 0, 0, 0, 0, 74438, 128272, 121409, 41981, 0, 0, + 42904, 0, 0, 74435, 126640, 0, 0, 0, 127968, 92442, 12703, 9661, 67360, + 67359, 7455, 70732, 11473, 119217, 128512, 0, 92323, 0, 0, 129632, 67358, + 0, 0, 0, 0, 174, 121131, 883, 4161, 128033, 42603, 0, 0, 72256, 0, 0, + 128356, 0, 0, 0, 0, 3846, 8070, 6150, 128109, 4370, 0, 0, 0, 74587, 0, 0, + 0, 0, 4986, 12189, 917553, 67648, 120499, 0, 4257, 71695, 123620, 6220, + 0, 65561, 0, 0, 0, 0, 0, 0, 0, 0, 69684, 0, 0, 128452, 120873, 0, 0, + 74922, 0, 71897, 0, 0, 67368, 67367, 8871, 67366, 0, 0, 0, 0, 0, 67361, + 0, 0, 67365, 67364, 3427, 4240, 67376, 67375, 67374, 67373, 0, 0, 0, + 67377, 0, 71689, 0, 0, 67372, 67371, 67370, 67369, 0, 0, 0, 124962, 0, 0, + 0, 0, 65898, 0, 65312, 0, 0, 0, 0, 4010, 121208, 41106, 0, 0, 0, 41105, + 0, 64803, 83456, 0, 0, 0, 0, 0, 0, 0, 11008, 0, 0, 71351, 41110, 71681, + 64892, 9113, 1954, 41108, 0, 42878, 0, 67405, 0, 0, 0, 0, 0, 119539, + 69435, 73463, 0, 4586, 129342, 0, 0, 0, 0, 0, 125233, 92307, 0, 0, 0, + 67382, 0, 9500, 0, 4957, 0, 2422, 2212, 0, 67381, 67380, 11045, 67378, 0, + 0, 3890, 12168, 121328, 0, 0, 0, 41947, 0, 120828, 74946, 917901, 0, + 1571, 66461, 41949, 42805, 8270, 943, 41946, 0, 2073, 0, 41980, 0, 0, 0, + 0, 4429, 6272, 0, 1460, 6954, 128572, 41120, 0, 65733, 0, 41119, 0, + 127006, 0, 0, 0, 129168, 12895, 0, 0, 0, 69440, 0, 1985, 6296, 0, 0, 0, + 0, 0, 41122, 0, 2457, 0, 0, 0, 0, 0, 0, 8840, 8035, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8681, 0, 121505, 128747, 0, 0, 70102, 0, 124976, 9605, 0, 13220, + 0, 67354, 11312, 0, 9246, 67349, 0, 0, 0, 0, 10012, 12123, 0, 0, 0, 0, 0, + 0, 0, 0, 67817, 0, 1272, 0, 0, 0, 983582, 0, 1467, 0, 917806, 0, 0, 0, + 70312, 0, 124955, 0, 70400, 0, 0, 72817, 0, 19935, 0, 92162, 0, 0, 0, + 128406, 5275, 0, 0, 44006, 129082, 0, 3789, 128205, 0, 0, 0, 11474, 0, 0, + 0, 129050, 0, 92194, 129503, 9537, 4496, 0, 120443, 2605, 4500, 0, 55224, + 8600, 0, 0, 41646, 11667, 0, 0, 0, 917905, 4499, 41649, 0, 0, 0, 0, 0, 0, + 0, 65804, 0, 70034, 41866, 0, 0, 0, 11174, 0, 0, 0, 9559, 128773, 41940, + 8299, 41945, 0, 41941, 5455, 7190, 0, 0, 917810, 65266, 0, 41943, 10762, + 0, 41931, 0, 0, 8106, 4128, 0, 0, 4494, 0, 0, 72405, 0, 119567, 42068, + 917808, 0, 11004, 12794, 65072, 5271, 7317, 0, 0, 0, 0, 0, 0, 92281, 0, + 0, 0, 0, 71880, 3868, 71881, 983569, 128431, 7703, 0, 64390, 0, 7406, 0, + 93850, 0, 3985, 66425, 0, 66615, 10177, 0, 41853, 71873, 12809, 0, 12193, + 0, 10879, 0, 0, 9055, 0, 3851, 8132, 0, 0, 119263, 917908, 0, 0, 0, 0, 0, + 42657, 0, 7643, 0, 0, 0, 43568, 0, 11949, 7650, 43569, 64951, 7647, 7649, + 0, 7646, 0, 0, 9651, 125005, 3891, 0, 0, 2337, 77831, 77832, 67860, + 129288, 0, 0, 43561, 67706, 119669, 0, 1860, 0, 68835, 5812, 12784, 0, 0, + 0, 0, 0, 7727, 0, 0, 69818, 66444, 128665, 42719, 0, 1569, 0, 12534, + 12124, 7690, 194871, 12533, 0, 68383, 67997, 0, 6969, 0, 0, 0, 67974, + 63895, 128650, 0, 0, 0, 42144, 0, 0, 0, 0, 92211, 119043, 0, 0, 917545, + 0, 0, 12791, 0, 0, 0, 4447, 71065, 12793, 0, 0, 43385, 0, 0, 12790, + 120256, 0, 983821, 12792, 120254, 0, 0, 12789, 128489, 12317, 74934, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 127840, 41652, 2974, 78689, 11476, 0, 0, 0, 0, + 43871, 0, 10894, 119176, 74557, 65686, 0, 0, 3724, 67335, 67334, 67333, + 67338, 67337, 0, 67336, 0, 65306, 0, 128421, 0, 8646, 129593, 77829, 0, + 0, 74852, 0, 0, 0, 0, 0, 220, 120252, 43551, 0, 10044, 0, 0, 983828, + 68659, 110825, 5707, 71362, 0, 0, 0, 0, 0, 0, 10297, 0, 41308, 67331, 0, + 0, 0, 0, 2467, 0, 6003, 0, 0, 8040, 0, 0, 4182, 0, 11135, 120501, 0, 0, + 2510, 0, 10208, 0, 78302, 70829, 0, 0, 6837, 0, 0, 67348, 0, 0, 0, 0, + 1559, 67342, 11104, 67340, 67347, 67346, 67345, 67344, 0, 0, 67357, + 67356, 0, 0, 0, 0, 67352, 67351, 5516, 2845, 7717, 8036, 65161, 67353, + 5514, 12045, 6278, 0, 5515, 0, 0, 0, 0, 0, 65194, 100387, 5517, 70116, + 92774, 0, 67884, 0, 67890, 42094, 67880, 67881, 67882, 67883, 0, 0, + 67879, 120411, 1902, 67887, 67888, 12976, 126546, 12483, 12368, 41769, + 42726, 41765, 0, 12787, 67874, 7556, 67878, 74351, 67897, 989, 42677, + 67889, 0, 6060, 0, 4326, 11000, 64601, 68478, 0, 0, 6917, 0, 120837, 0, + 0, 0, 6148, 8605, 74205, 0, 0, 0, 42715, 0, 101047, 0, 68663, 0, 41796, + 1269, 42703, 64754, 101049, 101042, 5144, 12221, 42716, 71048, 5133, + 4331, 0, 128675, 0, 5279, 121362, 71046, 0, 0, 42701, 0, 0, 0, 121470, 0, + 0, 0, 0, 0, 983608, 121259, 42666, 12207, 1067, 255, 12131, 0, 0, 0, 0, + 0, 0, 0, 70728, 43460, 0, 42723, 125216, 0, 70427, 0, 12797, 0, 0, + 983703, 0, 67977, 12799, 0, 92504, 9746, 5135, 0, 12796, 0, 0, 0, 5139, + 346, 74303, 121134, 12795, 125109, 5168, 0, 43845, 983708, 0, 8253, 8817, + 1136, 983716, 43563, 127774, 129542, 0, 0, 0, 0, 0, 0, 983619, 0, 0, + 4041, 0, 2357, 43240, 12786, 0, 0, 0, 44004, 7142, 0, 67984, 0, 0, 0, 0, + 12785, 0, 0, 7770, 10712, 64853, 42679, 118916, 42375, 0, 983123, 94074, + 12119, 0, 11059, 10791, 0, 450, 0, 0, 0, 0, 5450, 64691, 0, 0, 44009, 0, + 0, 111097, 94085, 1839, 94004, 0, 10927, 1701, 0, 129610, 41749, 41761, + 5453, 8361, 66045, 41758, 5444, 41763, 0, 0, 0, 66349, 983137, 121274, 0, + 0, 8801, 0, 4340, 0, 0, 0, 0, 70001, 41824, 0, 0, 0, 0, 42700, 0, 127980, + 0, 0, 0, 0, 0, 0, 4493, 4336, 129171, 2314, 983061, 41808, 0, 0, 0, + 64638, 0, 65937, 4489, 71331, 0, 0, 5358, 42717, 0, 71236, 0, 0, 0, + 127042, 41813, 2712, 0, 127044, 1410, 0, 0, 0, 0, 0, 0, 0, 0, 128587, 0, + 0, 0, 4892, 0, 0, 0, 0, 0, 5777, 0, 759, 0, 2079, 65248, 12788, 0, 64552, + 0, 41803, 68043, 0, 0, 0, 0, 128785, 0, 68492, 67991, 75071, 2340, 0, + 120638, 0, 983883, 0, 0, 0, 64749, 0, 2321, 3587, 0, 67236, 9953, 9952, + 0, 0, 42714, 9951, 0, 0, 127902, 74150, 0, 0, 74757, 127554, 0, 983807, + 2395, 0, 9976, 0, 125128, 0, 0, 0, 42809, 42807, 0, 66290, 70854, 4150, + 64424, 8318, 41790, 67976, 65559, 2360, 41794, 0, 0, 120987, 0, 0, 2418, + 0, 2411, 0, 41783, 0, 41786, 65108, 0, 0, 41772, 42813, 2317, 0, 118980, + 0, 0, 0, 0, 0, 0, 78682, 7753, 2351, 6655, 64489, 0, 0, 0, 4443, 41697, + 230, 65793, 0, 65943, 42803, 0, 0, 5441, 0, 0, 127053, 0, 855, 0, 6109, + 101021, 0, 119116, 69989, 0, 0, 72146, 0, 101023, 0, 72148, 0, 19915, + 41892, 0, 0, 128901, 41887, 0, 67980, 9735, 0, 0, 120591, 13082, 0, 0, 0, + 0, 0, 0, 0, 0, 289, 0, 0, 64504, 0, 126130, 120514, 0, 92962, 0, 42724, + 69977, 0, 0, 0, 0, 67994, 0, 0, 0, 3565, 0, 0, 127553, 43035, 69898, 0, + 0, 0, 0, 4891, 0, 0, 4602, 0, 121065, 0, 0, 121157, 0, 43978, 8988, 0, 0, + 0, 0, 0, 119184, 121436, 73902, 69740, 0, 0, 72976, 0, 0, 8771, 0, 0, 0, + 119209, 74974, 71737, 0, 0, 67987, 0, 0, 0, 67989, 0, 10065, 8207, 0, + 983578, 0, 0, 662, 0, 41927, 0, 0, 0, 0, 0, 0, 0, 41929, 0, 0, 0, 41926, + 69994, 0, 0, 0, 126230, 68013, 1433, 64648, 6475, 0, 120983, 0, 73876, 0, + 0, 0, 67992, 78052, 0, 3978, 0, 0, 0, 0, 120761, 12281, 0, 0, 13241, 0, + 0, 0, 0, 11765, 42577, 0, 0, 2641, 7192, 0, 0, 118809, 101015, 0, 101016, + 128948, 101013, 6479, 64294, 121194, 0, 0, 0, 64334, 0, 0, 0, 92266, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9478, 127339, 124964, 0, 202, 0, 0, 1242, 0, + 121170, 0, 63940, 0, 0, 0, 63939, 11990, 92430, 67982, 0, 65440, 70068, + 0, 0, 64829, 0, 0, 0, 0, 0, 2858, 0, 63989, 0, 69239, 0, 121152, 0, + 77841, 0, 70078, 92574, 129519, 0, 0, 0, 128974, 0, 12922, 92498, 0, + 66424, 71124, 0, 0, 0, 2856, 0, 47, 0, 126986, 65858, 0, 0, 0, 0, 0, + 8417, 65903, 0, 0, 0, 4033, 128164, 0, 0, 0, 0, 64600, 1903, 12320, 0, + 120894, 0, 0, 8915, 0, 945, 0, 0, 0, 0, 111068, 0, 74828, 0, 0, 9531, 0, + 8505, 0, 119238, 0, 0, 65538, 0, 0, 0, 0, 0, 0, 63935, 0, 0, 0, 0, 0, + 64787, 111060, 0, 0, 110828, 0, 2230, 0, 0, 71886, 9843, 0, 92419, + 111062, 129337, 92715, 0, 1320, 0, 1673, 0, 92383, 0, 9338, 128355, 0, 0, + 0, 0, 11997, 0, 0, 0, 0, 0, 0, 43308, 0, 0, 0, 0, 0, 0, 0, 63920, 0, 0, + 0, 0, 0, 0, 3514, 78723, 0, 7492, 0, 0, 0, 7514, 0, 63924, 0, 7502, 7587, + 0, 0, 0, 0, 0, 7610, 0, 0, 120759, 692, 43588, 0, 0, 75056, 9688, 0, + 9535, 0, 0, 0, 64530, 0, 125251, 194861, 0, 72209, 7453, 0, 8013, 66396, + 0, 0, 8895, 5356, 0, 5458, 0, 2866, 0, 127860, 71732, 71724, 6700, 0, + 111081, 120583, 0, 110614, 0, 9641, 63830, 65294, 0, 0, 67969, 0, 7441, + 0, 63826, 0, 0, 0, 0, 2844, 983953, 0, 63824, 12139, 67971, 0, 0, 3358, + 65295, 0, 3104, 0, 0, 0, 0, 65772, 0, 0, 0, 0, 2862, 11326, 0, 0, 94001, + 3268, 66591, 0, 6552, 42367, 7035, 120558, 0, 0, 1814, 195092, 10240, + 195093, 0, 0, 0, 0, 0, 71454, 0, 0, 2837, 4341, 0, 0, 0, 125064, 0, 0, 0, + 0, 0, 72721, 863, 129125, 0, 0, 43323, 0, 0, 0, 68054, 0, 3654, 0, 0, 0, + 0, 0, 7653, 0, 0, 66587, 0, 0, 92401, 0, 0, 12927, 0, 0, 0, 13056, 0, 0, + 3056, 0, 0, 195101, 0, 0, 74506, 73770, 0, 0, 0, 0, 0, 0, 0, 0, 983681, + 0, 5811, 0, 0, 0, 66817, 983836, 0, 0, 128636, 129311, 0, 128041, 0, + 67739, 120965, 0, 0, 0, 0, 68375, 0, 0, 70300, 0, 0, 0, 983679, 111078, + 0, 11991, 128079, 0, 92943, 1502, 74117, 127988, 0, 129478, 121253, 0, + 67661, 0, 0, 125084, 120758, 0, 74057, 68639, 0, 42898, 120742, 0, 74388, + 74838, 120822, 0, 0, 0, 0, 69452, 43214, 5893, 0, 0, 92496, 0, 0, 119907, + 119900, 0, 0, 0, 0, 41950, 0, 0, 68610, 0, 68626, 894, 0, 0, 12306, + 73846, 0, 0, 0, 8636, 0, 121028, 42503, 0, 92942, 0, 121468, 119241, 0, + 126569, 5096, 5095, 2863, 127505, 0, 10454, 42530, 5094, 0, 0, 13156, 0, + 111035, 5093, 127178, 983414, 0, 5092, 10708, 11327, 0, 5091, 0, 0, 9153, + 4104, 78599, 78601, 2929, 42712, 75067, 12272, 9832, 0, 0, 111105, 0, 0, + 0, 0, 0, 0, 13106, 0, 0, 129111, 0, 0, 0, 0, 9074, 111111, 0, 111110, 0, + 8113, 11168, 92563, 1786, 111109, 0, 111108, 0, 74423, 0, 586, 74414, + 64359, 1267, 0, 127531, 0, 65731, 0, 0, 0, 92932, 0, 0, 0, 0, 0, 0, 1228, + 0, 42846, 0, 0, 70343, 1714, 74406, 0, 0, 0, 127389, 66225, 0, 0, 42660, + 0, 0, 3804, 0, 0, 0, 0, 2826, 0, 0, 0, 128396, 0, 0, 0, 0, 0, 0, 12206, + 5839, 0, 68524, 74065, 0, 0, 0, 126240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 67241, 917821, 7030, 0, 10479, 64959, 2852, 0, 121225, 0, 0, 128586, 0, + 6963, 0, 0, 0, 74786, 0, 0, 0, 0, 121281, 0, 0, 0, 0, 113815, 121360, 0, + 9994, 0, 2864, 64719, 1148, 0, 41677, 0, 0, 2765, 0, 128181, 0, 0, 0, + 92516, 74777, 0, 0, 65206, 0, 0, 0, 0, 69391, 0, 0, 983751, 0, 41839, + 129616, 983754, 0, 0, 6931, 0, 0, 7177, 125137, 0, 0, 0, 93020, 0, 10722, + 0, 0, 128186, 121050, 0, 0, 127207, 0, 750, 0, 0, 63912, 0, 0, 7032, 0, + 0, 4314, 128600, 0, 128409, 730, 0, 127866, 0, 0, 41380, 0, 0, 0, 69697, + 8240, 92939, 0, 41378, 0, 6938, 70026, 0, 0, 66246, 0, 0, 0, 0, 0, 0, + 983094, 0, 92754, 41470, 64805, 0, 0, 0, 0, 0, 0, 0, 0, 92938, 68370, 0, + 0, 73831, 0, 0, 0, 2872, 0, 0, 0, 0, 604, 41097, 0, 0, 0, 0, 0, 127488, + 0, 2836, 0, 0, 9707, 0, 43202, 0, 0, 0, 0, 0, 120916, 2832, 92702, 9670, + 12937, 0, 0, 0, 0, 2822, 0, 0, 92519, 0, 73752, 0, 0, 0, 1331, 92603, 0, + 0, 0, 129432, 5090, 5089, 0, 3200, 0, 0, 0, 5088, 0, 0, 9477, 0, 0, 5087, + 92325, 0, 96, 5086, 0, 0, 0, 5085, 64286, 0, 0, 43820, 0, 983722, 0, 0, + 119042, 0, 0, 0, 0, 0, 0, 0, 127241, 120891, 7601, 0, 591, 0, 118953, 0, + 0, 0, 0, 0, 10939, 7246, 6933, 67142, 67141, 0, 74600, 120695, 0, 67138, + 65574, 0, 78058, 67140, 73851, 74598, 67139, 128094, 0, 6372, 0, 0, 7963, + 6371, 0, 0, 125040, 0, 0, 0, 0, 0, 0, 0, 8258, 123591, 0, 0, 65148, + 118919, 42, 0, 0, 0, 0, 0, 0, 0, 0, 67135, 67134, 67133, 0, 0, 0, 0, + 67136, 67130, 74597, 11550, 0, 67132, 65868, 0, 12826, 127872, 0, 126235, + 9737, 92448, 0, 0, 0, 8878, 0, 0, 0, 0, 0, 72220, 9086, 0, 0, 0, 7437, + 7454, 0, 0, 0, 0, 9042, 0, 0, 0, 0, 3805, 0, 67128, 44001, 67126, 0, + 44022, 19949, 12200, 43522, 983045, 43525, 0, 0, 0, 64422, 67125, 67124, + 7602, 0, 0, 43521, 0, 0, 43711, 43523, 41447, 8424, 68483, 8704, 2397, 0, + 0, 0, 0, 0, 10916, 0, 129290, 93998, 0, 0, 0, 127800, 67686, 9961, + 123203, 0, 68842, 10792, 8889, 121402, 6951, 0, 68827, 917835, 74342, 0, + 0, 0, 68816, 129152, 0, 42909, 66597, 70092, 0, 0, 10481, 4559, 0, 1956, + 43138, 0, 0, 43490, 43148, 0, 0, 0, 43140, 0, 0, 0, 0, 73013, 8533, 0, 0, + 0, 0, 0, 4357, 0, 70289, 983156, 0, 42911, 0, 0, 0, 10941, 0, 6962, 0, 0, + 113808, 0, 11014, 0, 8942, 12000, 0, 0, 0, 0, 0, 0, 42650, 0, 75016, + 63975, 0, 66210, 0, 0, 129150, 0, 11193, 0, 0, 0, 0, 0, 0, 0, 43476, 0, + 11024, 74811, 72787, 10563, 92954, 0, 0, 2462, 92955, 0, 0, 66213, 6957, + 0, 120559, 0, 0, 0, 74594, 983419, 92347, 0, 110702, 110708, 110707, + 127119, 3109, 127117, 119909, 0, 121434, 0, 0, 4042, 0, 0, 0, 127123, + 127122, 127121, 0, 127999, 0, 3503, 74444, 68300, 6694, 127997, 0, 0, + 74306, 0, 983738, 7736, 0, 0, 0, 10521, 0, 42173, 9705, 0, 0, 6955, + 71467, 0, 6149, 3887, 19956, 1411, 2824, 0, 0, 0, 1403, 0, 1347, 66282, + 127996, 0, 0, 0, 0, 8640, 0, 1178, 1654, 0, 0, 129529, 43314, 0, 0, 0, 0, + 2873, 0, 0, 0, 67085, 10861, 0, 0, 70377, 0, 67082, 67081, 41391, 67084, + 0, 376, 6987, 983181, 119904, 0, 8823, 0, 12943, 65185, 100988, 42099, 0, + 0, 100990, 0, 8301, 0, 0, 1684, 0, 0, 0, 120620, 0, 0, 0, 42121, 0, + 66781, 78067, 42115, 0, 127998, 0, 67080, 1493, 42111, 67077, 4097, 0, + 983748, 0, 65808, 41642, 0, 0, 67076, 41636, 67074, 65095, 110660, 72254, + 121240, 41629, 12154, 75073, 0, 128179, 74084, 64380, 0, 0, 0, 0, 0, + 71193, 65371, 7078, 0, 0, 0, 74592, 0, 0, 43275, 0, 41434, 6062, 0, 0, + 19916, 0, 6950, 9606, 9842, 0, 65744, 0, 0, 128659, 0, 41615, 10105, 0, + 0, 41632, 7493, 0, 0, 41622, 0, 0, 0, 0, 7632, 983215, 983214, 9805, + 5990, 900, 0, 0, 0, 0, 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, 74373, 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, + 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, + 41982, 8860, 0, 0, 0, 0, 0, 9597, 0, 43172, 0, 10117, 0, 92297, 65865, 0, + 0, 128077, 0, 126065, 0, 187, 0, 65669, 0, 4963, 0, 0, 0, 8964, 0, 7775, + 0, 41948, 0, 0, 101010, 41942, 65449, 3160, 65922, 13226, 42665, 0, + 42663, 128210, 41766, 0, 78848, 78849, 41760, 1189, 905, 110620, 42658, + 78851, 67859, 9629, 6742, 0, 43625, 12952, 7888, 0, 3980, 0, 42656, 0, + 42055, 0, 0, 0, 64540, 0, 7867, 69218, 6236, 0, 0, 10505, 0, 12851, + 118948, 0, 5474, 128843, 3103, 0, 41753, 41733, 78051, 983472, 78844, + 78845, 41739, 78843, 70744, 10931, 41756, 43347, 68098, 122909, 41746, + 119147, 92591, 41259, 917848, 69930, 2691, 121338, 11231, 41244, 0, + 69800, 66364, 41262, 0, 0, 0, 41251, 0, 0, 11805, 0, 0, 68331, 94045, 0, + 0, 0, 74633, 41266, 126642, 0, 0, 0, 65741, 41737, 2275, 2666, 121232, + 41738, 4967, 419, 13126, 0, 0, 42822, 0, 6434, 74913, 0, 0, 6432, 0, + 69932, 128862, 769, 41742, 69927, 74805, 6433, 0, 547, 1943, 6439, 0, + 4994, 487, 0, 0, 3754, 0, 0, 0, 0, 74780, 0, 0, 1595, 92777, 74431, 0, 0, + 74860, 43267, 0, 0, 129083, 12185, 69406, 0, 0, 100984, 0, 42856, 0, 0, + 983746, 128319, 75057, 0, 0, 0, 65612, 0, 669, 0, 0, 0, 0, 0, 70445, + 100404, 69929, 0, 0, 460, 121513, 0, 0, 0, 120747, 0, 121519, 121518, 0, + 0, 121515, 121514, 65187, 9044, 78497, 11760, 78494, 7577, 78491, 41912, + 100412, 0, 100411, 0, 0, 100394, 78501, 0, 2933, 78500, 0, 66441, 100392, + 100397, 100391, 1549, 0, 100415, 0, 41755, 6206, 8670, 120587, 0, 69935, + 0, 0, 69768, 100952, 0, 0, 0, 0, 10552, 64342, 41922, 0, 917858, 0, + 917857, 2717, 0, 0, 0, 73664, 41908, 100722, 41916, 0, 0, 0, 92506, + 100723, 66664, 69803, 0, 100725, 0, 0, 43373, 0, 0, 8468, 100729, 121173, + 128297, 119210, 118952, 0, 0, 0, 100686, 0, 0, 0, 128703, 100670, 457, + 78502, 78503, 123180, 43006, 0, 8802, 113777, 0, 0, 0, 0, 126632, 0, + 41757, 0, 100657, 44000, 0, 0, 43534, 0, 0, 11961, 121316, 0, 0, 0, + 128736, 0, 0, 9499, 100695, 128330, 0, 0, 92260, 68184, 0, 0, 7256, + 983401, 983179, 0, 42161, 0, 119126, 128022, 65880, 0, 10802, 64861, 0, + 0, 0, 0, 0, 0, 73109, 0, 955, 0, 0, 5350, 64339, 0, 100705, 10875, 0, + 5477, 73121, 0, 0, 0, 67693, 69790, 0, 0, 3874, 0, 0, 0, 0, 83272, + 100674, 127397, 0, 100989, 0, 41038, 0, 9207, 42239, 0, 0, 0, 0, 74432, + 0, 0, 1455, 129680, 0, 11753, 119233, 0, 0, 127854, 100716, 69801, 0, 0, + 43520, 0, 119556, 0, 0, 0, 0, 100733, 10788, 6088, 0, 129587, 190, + 983341, 12593, 100737, 129308, 64408, 0, 4417, 128615, 74359, 41744, 0, + 0, 100435, 6965, 0, 0, 13201, 100430, 69896, 78868, 74382, 11841, 7918, + 92721, 0, 0, 0, 1728, 0, 0, 0, 0, 92679, 0, 0, 92711, 0, 0, 119536, 0, + 66679, 8382, 0, 0, 100381, 0, 917889, 42254, 68371, 100383, 0, 0, 0, + 9923, 0, 0, 11763, 100386, 120688, 0, 78187, 0, 0, 0, 0, 8333, 0, 0, 0, + 917805, 74464, 0, 92320, 74080, 0, 69911, 11910, 0, 74141, 8963, 0, 0, 0, + 121396, 0, 41747, 0, 0, 8968, 0, 0, 129110, 0, 0, 8836, 12315, 0, 8300, + 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, + 64328, 68219, 917894, 0, 8825, 0, 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, + 42405, 0, 0, 1632, 127982, 128326, 0, 0, 0, 121477, 42444, 0, 0, 215, + 41258, 128494, 64494, 1953, 10185, 0, 1256, 3910, 41260, 917903, 0, 0, + 41257, 0, 8675, 10700, 0, 0, 0, 9333, 0, 121471, 0, 0, 0, 0, 0, 499, 0, + 70729, 42915, 0, 101000, 0, 100999, 0, 0, 73111, 0, 122897, 0, 125006, 0, + 11118, 0, 128009, 0, 0, 128980, 9180, 0, 0, 0, 100986, 43438, 0, 0, 0, 0, + 0, 120669, 64782, 0, 0, 73969, 565, 42484, 118913, 201, 0, 42292, 69610, + 0, 0, 119625, 43518, 0, 0, 1022, 113788, 3880, 74247, 0, 0, 0, 0, 0, 0, + 0, 0, 72272, 100997, 0, 0, 0, 74255, 0, 0, 92598, 0, 9903, 118993, 0, + 68226, 0, 0, 0, 127788, 100955, 83280, 7892, 0, 10777, 0, 0, 65562, 0, + 101002, 0, 8039, 3363, 101009, 0, 0, 0, 12596, 70812, 0, 0, 0, 0, 0, + 92425, 74992, 64541, 0, 0, 10520, 12802, 0, 12998, 0, 83270, 42861, + 83273, 11415, 0, 7541, 125068, 65878, 822, 0, 0, 5774, 194746, 43252, 0, + 92619, 7672, 129281, 0, 0, 7463, 0, 0, 0, 0, 0, 0, 121411, 0, 0, 0, 0, 0, + 475, 0, 120586, 7329, 0, 0, 195088, 66291, 10645, 0, 6543, 0, 0, 0, + 119065, 0, 0, 0, 983233, 195095, 0, 8923, 1645, 0, 0, 0, 3196, 72404, 0, + 0, 43595, 0, 0, 0, 0, 0, 195076, 0, 0, 5258, 4328, 0, 0, 0, 405, 11454, + 0, 0, 0, 0, 75052, 41245, 0, 0, 4523, 11369, 0, 0, 0, 195079, 0, 0, + 983505, 0, 100961, 10480, 74610, 0, 0, 0, 12610, 0, 41247, 0, 7609, + 118837, 0, 0, 92253, 0, 984, 0, 92621, 0, 0, 0, 983501, 0, 0, 0, 43369, + 0, 0, 0, 983502, 6634, 0, 0, 0, 0, 74214, 0, 67709, 0, 0, 0, 71114, 9552, + 0, 0, 0, 12997, 0, 0, 0, 0, 129109, 12883, 10994, 10529, 55283, 0, 74618, + 0, 67736, 10661, 19951, 9614, 2428, 0, 121023, 0, 126224, 100966, 71127, + 0, 124996, 119162, 1952, 92181, 8455, 100958, 0, 93033, 119566, 100960, + 0, 12183, 100951, 0, 64929, 0, 0, 0, 128290, 42509, 73087, 3922, 9187, + 983626, 0, 0, 119057, 0, 3353, 9358, 0, 0, 66680, 0, 73975, 12879, 0, + 9795, 68380, 0, 0, 0, 0, 0, 41027, 0, 0, 0, 983631, 0, 70378, 0, 11751, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129356, 0, 0, 0, 0, 41029, 0, 126513, 0, 0, + 0, 11294, 0, 66665, 0, 0, 127750, 0, 0, 70105, 0, 0, 0, 67843, 0, 0, + 121167, 983876, 0, 8088, 129412, 0, 0, 0, 983973, 6926, 72423, 0, 129569, + 42369, 4350, 0, 65145, 9041, 43559, 0, 0, 0, 41263, 0, 0, 0, 65825, 9577, + 68199, 0, 0, 983121, 0, 6793, 0, 70409, 0, 0, 0, 0, 64669, 0, 0, 0, + 11200, 72725, 2995, 0, 0, 0, 7868, 72720, 983560, 11386, 1009, 70405, + 66871, 2333, 0, 0, 0, 0, 0, 70407, 128121, 0, 0, 0, 0, 0, 0, 0, 74968, 0, + 0, 110601, 0, 0, 41261, 0, 0, 0, 0, 118989, 6736, 917883, 0, 43010, + 127889, 0, 69635, 73011, 983697, 0, 0, 7293, 0, 0, 0, 0, 111332, 0, + 128245, 69928, 0, 0, 127072, 64445, 111336, 6635, 0, 0, 72707, 74936, 0, + 0, 917876, 0, 93025, 0, 0, 111329, 0, 0, 128045, 65219, 11925, 0, 92434, + 0, 0, 9845, 0, 7546, 0, 0, 11230, 4985, 13288, 672, 8098, 0, 0, 0, + 128126, 42655, 0, 0, 1577, 11772, 78327, 0, 66673, 0, 65911, 122908, 0, + 0, 129391, 92180, 0, 0, 0, 125140, 0, 0, 0, 119593, 1539, 0, 74969, + 42731, 0, 74970, 71066, 0, 3051, 0, 73783, 0, 0, 0, 0, 78777, 0, 983160, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3505, 8707, 0, 6725, 128013, 0, 92314, 0, + 66391, 5479, 0, 6686, 0, 0, 983313, 42754, 0, 0, 0, 0, 0, 0, 128523, 0, + 0, 4433, 41156, 0, 74971, 1443, 9339, 0, 0, 10926, 0, 43511, 0, 0, + 983319, 0, 126086, 72236, 10021, 0, 0, 0, 65914, 0, 66749, 0, 6721, 217, + 12466, 0, 0, 10443, 0, 68654, 0, 0, 0, 78334, 0, 41250, 0, 129532, 0, 0, + 0, 69232, 0, 41252, 66682, 0, 119637, 41249, 1366, 0, 0, 0, 0, 0, 4397, + 0, 0, 0, 9545, 121219, 0, 0, 0, 3511, 0, 92190, 0, 0, 126244, 760, 0, + 12088, 0, 0, 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, 0, 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, + 43811, 0, 128924, 0, 11062, 128748, 0, 0, 0, 78364, 0, 7865, 0, 78354, 0, + 78347, 0, 0, 0, 66363, 0, 0, 0, 74967, 7414, 0, 0, 92691, 0, 128507, 885, + 64772, 65180, 0, 71267, 852, 0, 0, 0, 78614, 121174, 129092, 67809, 9609, + 12156, 0, 0, 43586, 11035, 10411, 0, 13268, 6710, 0, 0, 0, 43853, 77949, + 4315, 0, 111104, 0, 43639, 43343, 0, 0, 0, 73074, 0, 65812, 43431, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 994, 125222, 127104, 127103, 73966, 66890, 0, + 65291, 0, 0, 0, 0, 0, 66873, 4186, 92531, 127106, 127105, 6718, 7330, + 4406, 0, 8480, 7319, 64373, 128699, 4413, 0, 0, 3198, 0, 0, 92469, + 111126, 0, 128591, 128681, 0, 0, 0, 0, 73023, 742, 0, 2893, 78738, 0, 0, + 0, 2553, 42294, 6756, 0, 73020, 8363, 0, 2993, 128381, 3916, 4301, 0, + 1141, 42407, 0, 0, 7572, 973, 0, 125077, 0, 2415, 0, 0, 9640, 42333, 0, + 0, 129546, 42486, 43381, 65390, 0, 69434, 1202, 0, 0, 0, 0, 68484, 0, 0, + 64542, 3260, 0, 65388, 43502, 69904, 0, 6738, 0, 0, 74193, 0, 0, 0, + 74641, 6312, 0, 74556, 12446, 0, 0, 128076, 8229, 1235, 0, 11472, 83064, + 0, 0, 0, 0, 0, 1740, 12872, 0, 985, 0, 0, 0, 12068, 0, 0, 0, 0, 0, 0, + 13133, 65071, 110780, 12655, 12134, 0, 92934, 0, 66915, 120349, 119572, + 0, 93030, 41572, 0, 0, 0, 41573, 0, 3931, 0, 74143, 0, 127034, 0, 0, 0, + 0, 83067, 0, 129303, 0, 0, 0, 0, 0, 0, 83068, 0, 72740, 128637, 72717, + 92935, 120291, 0, 1780, 6936, 0, 0, 819, 0, 9694, 125228, 0, 0, 0, 0, + 8343, 8342, 8345, 8344, 8346, 8338, 7523, 6922, 8348, 8347, 7525, 3346, + 8339, 125004, 72705, 69462, 268, 0, 0, 5754, 0, 0, 110684, 8336, 0, 0, 0, + 8337, 8341, 0, 11388, 7522, 0, 0, 0, 11090, 6953, 125240, 0, 74973, + 120708, 0, 0, 0, 0, 0, 110782, 0, 9038, 7887, 0, 0, 42534, 64347, 0, 0, + 67660, 120341, 0, 0, 0, 120878, 0, 0, 73999, 0, 64580, 0, 0, 64643, 0, 0, + 74975, 0, 92227, 129052, 0, 83071, 83072, 83073, 119154, 0, 119153, 0, 0, + 5349, 72440, 0, 917554, 7411, 0, 983220, 0, 0, 0, 42736, 70747, 5756, + 983225, 92946, 0, 42764, 0, 0, 119529, 5752, 120600, 0, 0, 0, 0, 0, + 78893, 0, 0, 0, 125242, 0, 0, 120331, 0, 0, 0, 72826, 0, 10080, 83056, + 12647, 0, 0, 0, 66882, 0, 0, 0, 0, 0, 128351, 72845, 0, 0, 0, 0, 0, + 74213, 0, 0, 0, 0, 0, 6302, 0, 0, 0, 0, 1417, 983222, 0, 9452, 0, 74393, + 0, 0, 110850, 0, 65391, 63789, 0, 78659, 78660, 41264, 78658, 6426, + 42398, 9179, 78654, 64906, 41255, 42036, 0, 41269, 0, 41267, 42436, + 67759, 42323, 42034, 0, 0, 42475, 42033, 0, 0, 68916, 43948, 0, 78673, + 78674, 1659, 919, 42784, 1671, 0, 6069, 9219, 0, 1661, 0, 0, 92690, + 10140, 9713, 78400, 0, 125236, 0, 2306, 0, 0, 6068, 10612, 0, 0, 121314, + 92561, 41462, 0, 0, 0, 0, 0, 0, 0, 128204, 10635, 0, 983221, 0, 0, 0, + 983231, 92251, 0, 121029, 983223, 0, 8100, 0, 78669, 78670, 13301, 78667, + 9667, 78665, 0, 0, 11003, 9904, 0, 0, 0, 0, 0, 0, 78680, 78681, 78677, + 78678, 0, 10313, 0, 0, 64320, 10265, 78686, 129404, 78684, 78685, 8945, + 78683, 70750, 41, 0, 0, 0, 0, 8655, 0, 0, 0, 0, 0, 0, 0, 2585, 0, 65254, + 3126, 0, 74136, 10957, 0, 11160, 0, 0, 0, 0, 0, 11408, 0, 7443, 0, 0, + 6997, 68004, 0, 0, 8739, 11075, 0, 65216, 0, 69795, 2593, 0, 0, 0, 0, + 125062, 0, 0, 0, 4411, 0, 72837, 0, 43442, 78799, 0, 0, 0, 66351, 0, 0, + 13061, 0, 78687, 78688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119925, 0, + 983637, 0, 0, 0, 0, 83399, 127541, 83398, 8022, 78808, 0, 73794, 0, 0, + 83414, 119918, 0, 0, 0, 0, 0, 0, 63799, 78427, 12063, 78425, 78424, 0, 0, + 0, 75025, 0, 297, 0, 0, 68326, 0, 78429, 78428, 7077, 2497, 128651, 0, + 983111, 0, 0, 0, 4292, 0, 74815, 10512, 0, 74814, 119931, 0, 72841, 2503, + 73778, 1762, 69794, 2495, 0, 71230, 94069, 77984, 0, 12654, 0, 1899, 0, + 2507, 0, 8726, 0, 65594, 0, 71272, 8892, 0, 0, 0, 0, 0, 420, 0, 0, + 125130, 10797, 74637, 0, 0, 0, 0, 63796, 0, 66581, 0, 119205, 0, 0, + 194840, 0, 120788, 0, 0, 92956, 0, 0, 0, 0, 119230, 0, 0, 83496, 7399, 0, + 66434, 42779, 0, 92220, 42197, 92543, 5380, 0, 0, 1155, 11365, 43126, 0, + 77971, 65684, 0, 5601, 0, 42765, 78258, 0, 7987, 72843, 0, 69799, 0, 0, + 78735, 119165, 0, 0, 4473, 0, 72426, 0, 65347, 65346, 65345, 0, 127384, + 0, 69802, 0, 73868, 0, 64826, 0, 0, 0, 0, 6218, 78422, 69676, 4555, 0, + 83459, 70071, 128670, 65190, 0, 0, 65244, 0, 0, 42519, 74472, 0, 0, + 83466, 0, 0, 0, 83468, 92581, 0, 0, 65370, 65369, 65368, 65367, 65366, + 65365, 41086, 65363, 65362, 65361, 65360, 43410, 11323, 65357, 65356, + 65355, 5345, 65353, 65352, 65351, 761, 65349, 19959, 69718, 0, 0, 0, 0, + 64647, 0, 0, 4699, 126077, 0, 0, 0, 0, 0, 68074, 0, 0, 0, 128347, 0, + 72829, 0, 69773, 121438, 0, 0, 0, 73980, 78255, 78254, 83453, 43157, 0, + 0, 0, 7946, 12541, 0, 74615, 69780, 0, 0, 0, 0, 9005, 1225, 0, 0, 0, 0, + 68011, 8847, 0, 0, 0, 8329, 74590, 43878, 0, 0, 0, 3127, 2595, 71040, + 69766, 129188, 0, 41089, 0, 0, 70292, 983613, 12112, 0, 74200, 0, 8764, + 0, 0, 0, 67273, 67272, 67271, 71044, 0, 0, 0, 71042, 67266, 67265, 0, + 67270, 67269, 67268, 67267, 67282, 67281, 67280, 3572, 10023, 4959, 0, 0, + 67275, 9729, 125110, 0, 67278, 67277, 0, 67276, 0, 7996, 9907, 0, 13304, + 83392, 0, 72830, 0, 11095, 11100, 0, 83358, 83387, 10142, 0, 0, 0, 0, + 68022, 0, 83363, 128292, 19955, 0, 83366, 69807, 125246, 70124, 0, 72230, + 83373, 83385, 0, 0, 0, 0, 68020, 0, 0, 261, 8406, 7791, 0, 7362, 0, + 10696, 0, 0, 9838, 118920, 0, 83477, 0, 0, 0, 6437, 68830, 83476, 0, 0, + 74177, 0, 0, 67288, 67287, 0, 67286, 0, 83470, 0, 67289, 67283, 83471, + 70002, 0, 0, 0, 67285, 11499, 67297, 7816, 67295, 55247, 68015, 10929, + 67298, 0, 68017, 9642, 10912, 0, 67293, 11387, 67291, 67290, 70792, 0, + 67715, 0, 0, 68099, 13287, 74430, 10836, 0, 75053, 69775, 0, 128746, + 7450, 0, 0, 119648, 9697, 3606, 0, 0, 0, 0, 125029, 0, 0, 121262, 0, + 128873, 1389, 128871, 0, 0, 0, 12941, 0, 83438, 121062, 0, 12301, 83440, + 0, 41102, 66604, 0, 0, 0, 0, 66600, 523, 92642, 71100, 74436, 0, 0, 0, + 8608, 83435, 72828, 128704, 0, 127402, 11307, 66707, 67301, 67300, 67299, + 0, 67304, 67303, 0, 0, 0, 0, 127212, 5908, 0, 0, 6744, 67310, 1699, + 67308, 67307, 67314, 67313, 6306, 67311, 983207, 72150, 69862, 3766, + 2389, 67305, 74569, 6611, 65700, 0, 0, 0, 42386, 0, 0, 2599, 917972, + 119131, 119049, 65717, 0, 0, 119654, 0, 0, 0, 74203, 3760, 1718, 68160, + 0, 3776, 7335, 0, 0, 67324, 69861, 0, 69792, 0, 0, 3778, 0, 9462, 7824, + 0, 78896, 3768, 68142, 765, 72822, 3764, 0, 0, 113822, 0, 12947, 0, 0, 0, + 118806, 73753, 0, 0, 0, 6829, 5225, 66901, 0, 0, 0, 0, 67319, 67318, + 3162, 67316, 67323, 67322, 67321, 67320, 0, 5353, 0, 74179, 67315, 0, + 1010, 0, 0, 67326, 67325, 127870, 6952, 67329, 67328, 67327, 2590, + 120036, 65552, 120034, 120039, 7183, 120037, 120038, 120027, 120028, + 120025, 120026, 120031, 970, 120029, 74611, 120019, 120020, 120017, + 67330, 120023, 120024, 120021, 10961, 113693, 11148, 0, 0, 0, 128448, 0, + 113703, 64378, 0, 0, 0, 68821, 119649, 11358, 71172, 69797, 0, 11065, + 126464, 0, 68864, 0, 5694, 120839, 66784, 0, 4325, 3047, 0, 43652, + 120962, 93029, 69764, 0, 0, 0, 0, 5431, 6652, 0, 67753, 71460, 0, 0, 0, + 1129, 65016, 0, 65900, 1986, 7846, 0, 8661, 75058, 0, 0, 3845, 0, 0, 0, + 74400, 1456, 7530, 121382, 0, 0, 0, 0, 120016, 0, 0, 0, 917863, 127772, + 119966, 0, 11002, 7026, 8145, 68216, 0, 12138, 71464, 0, 0, 0, 12323, 0, + 917869, 0, 0, 0, 92316, 68494, 0, 0, 129384, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 42205, 0, 236, 0, 78867, 0, 0, 113784, 0, 0, 983982, 0, 0, 0, 8097, 0, + 0, 68012, 72820, 11194, 0, 72824, 0, 127974, 0, 0, 110603, 0, 10416, + 68070, 3872, 127508, 0, 0, 0, 0, 2838, 917867, 0, 917866, 119589, 0, 0, + 0, 0, 11096, 83019, 10553, 83421, 0, 0, 0, 0, 0, 0, 73742, 6436, 10096, + 0, 0, 0, 113687, 0, 4463, 68018, 0, 78074, 0, 983591, 7184, 0, 0, 0, 0, + 0, 0, 93825, 12818, 12032, 0, 0, 0, 0, 10357, 121418, 8170, 0, 8556, 0, + 9659, 0, 0, 0, 9556, 0, 4503, 92700, 9647, 64004, 78185, 0, 0, 64002, + 78889, 0, 0, 118910, 0, 6438, 0, 9109, 78884, 0, 64599, 0, 68009, 0, 0, + 2447, 0, 0, 0, 126545, 0, 119002, 0, 0, 0, 19937, 0, 1322, 0, 119204, + 254, 0, 0, 69392, 42425, 0, 0, 65204, 42312, 0, 128519, 0, 42826, 0, + 42464, 120567, 0, 67155, 74796, 64400, 64693, 126212, 77861, 0, 0, 67154, + 0, 0, 0, 68008, 11785, 0, 119142, 41978, 0, 0, 43244, 10536, 0, 9901, + 7103, 0, 7102, 71428, 120748, 3140, 0, 0, 68007, 0, 67258, 10909, 0, + 1428, 0, 67254, 67253, 7699, 12393, 67257, 0, 67256, 67255, 0, 0, 69389, + 0, 0, 0, 0, 0, 67153, 0, 0, 127383, 69376, 64554, 0, 3878, 0, 42352, + 1752, 0, 0, 42506, 0, 10199, 0, 983463, 125231, 0, 0, 0, 720, 0, 0, 0, + 68831, 0, 1464, 128339, 0, 7974, 0, 125017, 68082, 0, 0, 0, 0, 74787, 0, + 78865, 92258, 0, 0, 78863, 0, 1302, 66288, 0, 0, 0, 67152, 0, 983611, + 983618, 0, 0, 3995, 0, 65608, 3714, 0, 0, 67262, 67261, 67260, 67259, + 43251, 67264, 67263, 0, 120557, 92346, 8672, 68006, 11964, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 92610, 0, 468, 0, 0, 0, 983470, 0, 0, 128544, 129397, + 65907, 983163, 0, 0, 0, 0, 0, 983468, 41743, 0, 0, 0, 74880, 0, 121001, + 820, 41741, 0, 120667, 0, 64684, 126992, 128604, 126082, 69934, 65177, + 6226, 353, 43645, 0, 119612, 120738, 67700, 0, 0, 0, 0, 42457, 120276, 0, + 120277, 1884, 129637, 42418, 113678, 41157, 0, 42305, 120279, 0, 0, + 41151, 0, 71430, 0, 42344, 0, 0, 0, 42497, 0, 194870, 72754, 69933, + 73703, 0, 42521, 8539, 128606, 0, 123609, 69957, 4788, 0, 68023, 0, 0, + 983053, 0, 0, 0, 0, 41590, 0, 113754, 0, 0, 118901, 68637, 41136, 64351, + 0, 128453, 41154, 113731, 127038, 4038, 41143, 68232, 64859, 0, 0, 0, + 5435, 0, 6734, 41343, 127035, 0, 0, 41359, 66761, 0, 119835, 41349, 0, 0, + 10374, 10310, 0, 0, 10254, 119836, 10278, 10262, 69858, 41363, 0, 0, 0, + 119840, 0, 41356, 10314, 10282, 0, 10378, 0, 40976, 10266, 0, 119848, + 40975, 0, 129554, 0, 40978, 0, 92945, 0, 0, 0, 119098, 119083, 0, 71437, + 119854, 69936, 0, 0, 3525, 6824, 0, 0, 119858, 128451, 0, 72239, 113738, + 0, 71424, 0, 0, 0, 0, 0, 10727, 7212, 129071, 120551, 0, 0, 0, 67156, + 808, 7207, 42387, 0, 0, 0, 0, 0, 0, 0, 0, 9225, 121149, 0, 9145, 128060, + 41018, 67841, 983158, 42300, 0, 3084, 983155, 125014, 41025, 6037, 0, + 194885, 0, 10290, 0, 3083, 10322, 111017, 129030, 0, 41036, 0, 0, 43321, + 65606, 0, 41032, 42388, 0, 64700, 0, 1445, 40961, 0, 0, 0, 40960, 0, + 67727, 0, 2223, 64952, 10402, 0, 0, 0, 10603, 0, 0, 71438, 0, 0, 0, + 128469, 0, 0, 0, 0, 0, 0, 42585, 65032, 10704, 65030, 4787, 0, 917556, 0, + 127015, 0, 128118, 0, 0, 9525, 0, 0, 68773, 0, 0, 0, 0, 40966, 0, 0, + 3998, 0, 0, 65919, 71433, 11792, 2690, 0, 42836, 127150, 41954, 194921, + 194923, 6737, 0, 64933, 0, 3487, 194873, 71427, 72758, 65426, 72756, + 66757, 0, 0, 41976, 9720, 74964, 11179, 41970, 0, 12116, 65024, 0, + 127912, 9048, 65028, 65027, 65026, 65025, 64757, 0, 41488, 0, 8527, 0, + 126480, 0, 41480, 41053, 3266, 0, 0, 12093, 41466, 122881, 78642, 1519, + 983906, 3638, 65887, 65429, 0, 0, 0, 0, 8633, 0, 0, 0, 125118, 0, 70375, + 0, 0, 6368, 128124, 0, 70369, 8078, 0, 0, 70373, 72876, 0, 7002, 121003, + 41430, 0, 41051, 41484, 0, 0, 41050, 8872, 0, 13099, 71445, 70371, 0, + 6435, 72154, 11362, 0, 0, 0, 0, 41420, 0, 3625, 74915, 41409, 71441, 0, + 0, 0, 9672, 0, 0, 43317, 0, 0, 0, 41424, 917598, 0, 0, 0, 0, 41417, 1261, + 0, 0, 12102, 119662, 41401, 0, 127538, 129518, 0, 124943, 72765, 3275, + 92472, 0, 0, 0, 0, 0, 0, 0, 0, 125129, 983140, 10598, 0, 128633, 6711, 0, + 2920, 0, 0, 0, 0, 19928, 0, 0, 3917, 0, 113756, 0, 0, 66588, 128078, 0, + 0, 113721, 113758, 0, 0, 0, 41184, 0, 232, 0, 0, 74170, 0, 0, 0, 0, 9094, + 0, 0, 92585, 0, 1064, 0, 0, 10115, 0, 0, 0, 7862, 0, 13224, 0, 0, 66650, + 0, 0, 72877, 1878, 0, 71434, 2911, 0, 41178, 5427, 0, 0, 0, 12617, 41174, + 0, 67148, 67147, 0, 42413, 41167, 2406, 0, 0, 0, 0, 0, 9618, 128668, 0, + 0, 0, 0, 41436, 9337, 126067, 0, 41456, 0, 119086, 11333, 0, 6703, 0, + 125071, 1613, 0, 0, 0, 983191, 0, 0, 74500, 41460, 78197, 0, 0, 194899, + 67144, 65841, 0, 121109, 74064, 111146, 111144, 120375, 0, 111122, 0, + 111121, 64687, 111120, 42592, 3871, 0, 128305, 9111, 111163, 0, 111156, + 120366, 121462, 11150, 111154, 111175, 111179, 0, 111168, 0, 120362, + 41587, 70391, 0, 74322, 0, 194908, 111166, 111133, 0, 71443, 194844, 0, + 111151, 0, 0, 7928, 111127, 111140, 41595, 0, 0, 65801, 983600, 0, 0, 0, + 73712, 0, 41598, 3993, 121269, 1545, 40971, 121286, 72874, 0, 0, 0, + 120767, 65286, 0, 0, 0, 0, 0, 0, 0, 5402, 0, 0, 74462, 73457, 0, 0, + 78194, 64326, 40969, 0, 128110, 983684, 40968, 0, 983148, 0, 0, 0, 0, + 128513, 8020, 0, 41012, 0, 0, 65805, 41006, 0, 0, 74605, 0, 118942, + 43432, 0, 0, 92900, 0, 0, 0, 120687, 0, 92958, 0, 0, 68332, 0, 40992, 0, + 0, 0, 0, 0, 42235, 0, 1741, 42370, 0, 0, 0, 11413, 126583, 0, 0, 128769, + 6470, 0, 74517, 0, 0, 120651, 40984, 0, 42742, 0, 12916, 6284, 0, 41663, + 0, 0, 68313, 72840, 70164, 41648, 0, 0, 2299, 41666, 0, 0, 2056, 41656, + 0, 0, 71917, 42219, 0, 0, 78112, 41676, 0, 0, 0, 41670, 0, 92590, 2796, + 0, 0, 9902, 0, 67988, 64785, 82995, 128822, 42631, 983040, 71890, 0, + 74164, 41238, 10049, 11405, 0, 64368, 0, 120925, 0, 397, 12299, 42139, 0, + 9590, 0, 0, 43661, 43819, 0, 6651, 3544, 0, 0, 9620, 0, 0, 0, 92229, + 1333, 7104, 0, 6425, 0, 0, 0, 0, 0, 0, 11976, 8554, 13055, 0, 110733, 0, + 110731, 41218, 0, 0, 128673, 1883, 0, 0, 70443, 41225, 70788, 42419, + 983688, 129450, 0, 127896, 0, 65809, 11837, 0, 129104, 7141, 0, 0, 0, 0, + 0, 42363, 0, 0, 0, 0, 69949, 119157, 64732, 0, 0, 126983, 0, 0, 983678, + 7140, 42051, 0, 4164, 118799, 0, 120569, 42049, 42042, 0, 0, 0, 120637, + 69938, 0, 42047, 0, 0, 8470, 11807, 128935, 0, 0, 194825, 74300, 126267, + 0, 120517, 0, 0, 0, 0, 8736, 0, 42643, 72753, 0, 0, 0, 71432, 0, 93023, + 110730, 72869, 110728, 0, 0, 0, 0, 68445, 0, 0, 2106, 0, 11273, 120986, + 43004, 0, 82988, 0, 961, 64307, 0, 0, 0, 67711, 110615, 0, 1696, 0, 9762, + 12105, 0, 110622, 110623, 3264, 110621, 110618, 43003, 110616, 110617, 0, + 120359, 0, 128660, 0, 2322, 0, 70831, 11449, 128187, 42868, 0, 0, 0, 0, + 113746, 983234, 0, 129583, 66398, 0, 0, 0, 0, 0, 111135, 119224, 0, 0, + 64421, 0, 113739, 0, 65823, 0, 11182, 0, 0, 0, 7766, 55268, 0, 4598, 0, + 65839, 0, 0, 0, 10851, 0, 6179, 92602, 6180, 129524, 11952, 0, 78648, + 78651, 78646, 78647, 78644, 78645, 3801, 78643, 6176, 120580, 0, 0, 6177, + 0, 78652, 78653, 6178, 0, 0, 0, 0, 2214, 8754, 0, 0, 2137, 0, 0, 0, 0, + 66889, 0, 0, 0, 8974, 2308, 0, 74579, 0, 2318, 122920, 0, 8198, 0, 0, 0, + 74307, 0, 119524, 0, 0, 6970, 0, 0, 0, 41159, 0, 120363, 6385, 0, 128403, + 0, 0, 126258, 0, 72785, 42053, 2075, 42057, 0, 42052, 0, 0, 67651, 0, + 9665, 0, 0, 13181, 0, 0, 69379, 0, 0, 0, 0, 73010, 0, 0, 0, 41145, 0, 0, + 0, 41148, 0, 7594, 113686, 75033, 119090, 10869, 43458, 41146, 0, 0, + 121456, 917630, 0, 0, 0, 0, 0, 65184, 11780, 0, 42796, 0, 69742, 0, + 65146, 66803, 0, 0, 0, 7358, 78241, 0, 7988, 0, 0, 3271, 0, 0, 0, 0, 0, + 0, 983103, 13070, 113736, 42044, 0, 1095, 0, 3599, 0, 0, 0, 129087, + 66390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42043, 43232, 67656, 121014, 42046, + 64355, 4036, 123601, 0, 0, 983062, 0, 11954, 0, 41191, 12986, 0, 194854, + 65441, 0, 72202, 0, 129338, 0, 0, 0, 12834, 0, 0, 0, 0, 0, 0, 0, 41190, + 0, 0, 4575, 41193, 0, 429, 119174, 124931, 194859, 0, 65792, 128754, + 78509, 0, 128866, 0, 0, 0, 66786, 0, 194862, 10590, 0, 0, 0, 0, 0, 0, + 6247, 10214, 65126, 68253, 0, 0, 0, 983680, 1617, 8050, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6352, 0, 0, 0, 0, 0, 0, 0, 0, 92335, 0, 0, 42926, 0, 0, 0, + 8689, 78750, 70067, 42896, 74147, 3559, 0, 0, 74526, 65850, 12327, 72763, + 119028, 0, 0, 72761, 0, 78903, 0, 0, 0, 0, 70079, 72751, 0, 12153, 0, 0, + 120654, 0, 0, 0, 0, 0, 0, 681, 129406, 703, 983461, 3272, 0, 0, 70077, 0, + 0, 70514, 78902, 92532, 71436, 42238, 124930, 3276, 0, 0, 65928, 0, 0, + 128949, 0, 0, 0, 78813, 78814, 3262, 78811, 42711, 0, 0, 0, 0, 92746, + 9995, 1655, 70131, 78818, 78815, 12479, 0, 0, 0, 70513, 42797, 0, 0, + 128371, 43112, 0, 43488, 0, 0, 0, 42684, 0, 0, 0, 0, 0, 128308, 0, 0, 0, + 0, 0, 0, 11031, 0, 0, 0, 70386, 10348, 10412, 0, 0, 74329, 0, 0, 0, + 129026, 0, 0, 0, 8810, 0, 686, 0, 0, 0, 0, 0, 110709, 0, 0, 12040, 0, 0, + 65118, 110704, 0, 118891, 110599, 0, 110598, 0, 120543, 983660, 0, 65455, + 74413, 94097, 0, 119129, 0, 0, 0, 78776, 0, 64467, 10300, 10161, 10396, + 0, 0, 0, 0, 78773, 0, 0, 0, 1458, 0, 0, 72429, 65120, 11479, 0, 0, 6350, + 0, 0, 71473, 1061, 69787, 9115, 43111, 0, 0, 0, 0, 983960, 0, 120907, + 1045, 0, 73913, 983564, 0, 0, 0, 0, 0, 0, 8486, 0, 0, 0, 4362, 0, 0, + 93054, 1025, 0, 0, 0, 0, 0, 92328, 128206, 0, 1774, 0, 122913, 0, 0, 0, + 11207, 0, 0, 3988, 0, 0, 983048, 0, 0, 8564, 983958, 0, 0, 0, 0, 0, 0, + 66513, 6256, 0, 579, 55218, 0, 0, 0, 127337, 0, 11814, 0, 4488, 128716, + 127336, 0, 10444, 118846, 78238, 0, 0, 127331, 4487, 127849, 42832, 1032, + 0, 43450, 0, 70155, 0, 614, 0, 127325, 0, 0, 128466, 0, 127323, 0, + 127322, 0, 0, 0, 1050, 7549, 127319, 0, 9314, 0, 0, 0, 0, 0, 70434, + 127314, 12527, 66504, 0, 0, 0, 0, 64333, 127312, 128547, 92594, 0, 0, 0, + 129316, 0, 124960, 10360, 6746, 0, 0, 0, 0, 13085, 9233, 0, 0, 0, 0, 0, + 0, 92766, 0, 121114, 983925, 74212, 42819, 10910, 0, 68044, 9896, 0, 0, + 120915, 0, 0, 7970, 0, 0, 0, 0, 113699, 9849, 0, 122910, 0, 0, 10487, + 69714, 0, 10103, 0, 4769, 0, 0, 0, 2283, 0, 0, 74785, 0, 0, 0, 110595, + 110596, 0, 110594, 64565, 4773, 0, 0, 0, 4770, 0, 0, 0, 65457, 69441, 0, + 0, 127338, 983593, 4774, 0, 68497, 2259, 0, 0, 10215, 0, 0, 0, 0, 0, + 74776, 92160, 4768, 0, 0, 4099, 0, 110699, 110700, 110697, 2225, 0, 0, 0, + 0, 125217, 11255, 42814, 880, 0, 0, 0, 0, 0, 67756, 65246, 0, 0, 129463, + 7095, 0, 0, 0, 0, 0, 0, 2427, 0, 7093, 0, 11585, 0, 9962, 0, 12223, 0, + 78211, 1434, 42939, 0, 11573, 0, 0, 0, 121257, 0, 0, 0, 0, 74437, 0, + 113711, 917596, 0, 8740, 0, 3782, 64331, 0, 65167, 1014, 0, 0, 0, 10835, + 0, 0, 0, 0, 0, 0, 118824, 7302, 0, 67707, 0, 1150, 10547, 0, 0, 68427, 0, + 0, 0, 0, 118788, 0, 0, 0, 42257, 8010, 0, 0, 0, 9643, 0, 0, 12864, 0, 0, + 0, 0, 0, 0, 0, 0, 1426, 68217, 0, 68447, 0, 0, 0, 0, 73701, 0, 0, 0, + 65383, 0, 0, 0, 0, 0, 0, 43196, 43194, 92549, 10744, 0, 990, 93772, 0, 0, + 0, 0, 0, 66470, 0, 0, 0, 3945, 0, 0, 0, 0, 0, 127546, 127746, 1020, + 73763, 92257, 0, 0, 64748, 0, 0, 10205, 0, 0, 10016, 0, 74051, 0, 43242, + 125096, 2667, 0, 125037, 0, 9911, 0, 0, 10097, 0, 0, 0, 118836, 0, 0, 0, + 0, 68889, 10159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983338, 92291, 0, 127973, + 72882, 0, 1041, 127182, 6354, 0, 65364, 0, 0, 0, 72884, 0, 128477, 0, + 65906, 127819, 72883, 0, 128470, 5375, 72881, 0, 8215, 0, 10074, 0, 0, 0, + 69899, 0, 0, 121426, 41382, 0, 0, 5173, 65348, 527, 0, 0, 0, 128250, 0, + 0, 0, 0, 0, 0, 42695, 0, 42250, 0, 11187, 113695, 0, 1568, 66806, 0, 0, + 113705, 0, 0, 129487, 0, 0, 128839, 9069, 6144, 0, 0, 0, 0, 66783, 0, + 74027, 118934, 66787, 74580, 0, 110790, 6364, 0, 66794, 43508, 0, 92612, + 0, 0, 0, 0, 128405, 66449, 0, 0, 0, 0, 70714, 0, 70716, 0, 1044, 42411, + 0, 0, 0, 0, 43239, 0, 0, 0, 0, 42450, 0, 0, 68479, 119237, 0, 0, 0, 0, 0, + 69956, 11537, 0, 121206, 0, 0, 0, 0, 1057, 566, 0, 0, 10907, 42274, + 43464, 0, 0, 0, 78472, 71207, 42636, 0, 123603, 0, 0, 0, 64659, 0, + 127749, 0, 6357, 6362, 0, 0, 2216, 9090, 0, 0, 0, 0, 68227, 0, 0, 0, 0, + 1053, 12830, 0, 0, 0, 1052, 1051, 459, 1060, 0, 66479, 0, 0, 0, 128061, + 42490, 689, 6508, 4163, 42298, 8639, 983333, 4246, 0, 43514, 42362, 0, + 42337, 64596, 0, 0, 0, 0, 0, 6359, 0, 43471, 0, 0, 0, 127274, 0, 6358, + 6361, 1926, 6356, 0, 7898, 0, 10935, 0, 127972, 121285, 0, 43685, 0, 0, + 42910, 0, 8693, 0, 0, 44010, 0, 120991, 121454, 0, 0, 0, 0, 129514, 0, 0, + 0, 0, 73947, 0, 129361, 92412, 0, 66477, 0, 0, 0, 43854, 71913, 0, 0, 0, + 0, 72227, 65899, 92275, 0, 0, 0, 68887, 0, 71057, 0, 0, 0, 0, 119183, + 2923, 10853, 0, 0, 0, 0, 72864, 0, 72773, 72772, 0, 120801, 65251, 0, + 68228, 0, 128548, 0, 0, 5370, 70465, 2931, 73848, 0, 10188, 0, 118848, 0, + 983923, 0, 0, 0, 72212, 0, 10844, 121016, 128195, 92424, 0, 0, 0, 286, 0, + 1062, 0, 0, 0, 7395, 0, 1070, 128993, 0, 6095, 0, 0, 0, 127796, 126465, + 64497, 0, 0, 0, 0, 70054, 8189, 78272, 0, 0, 0, 0, 0, 113783, 42102, + 78276, 0, 0, 42101, 0, 78402, 67427, 33, 67425, 67424, 10824, 67430, + 67429, 67428, 427, 64723, 0, 0, 0, 0, 1031, 0, 0, 42104, 0, 0, 2328, 0, + 1071, 42899, 128486, 0, 7673, 0, 0, 1047, 0, 0, 42908, 0, 0, 10651, 0, 0, + 0, 72433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13216, 0, 69716, 0, 0, 0, + 0, 0, 92411, 69654, 0, 0, 0, 2761, 194834, 0, 0, 0, 0, 8643, 0, 0, 94021, + 2757, 11067, 0, 74498, 8910, 10689, 0, 0, 0, 71173, 0, 9196, 71214, 0, 0, + 0, 0, 118911, 0, 0, 0, 0, 0, 0, 0, 0, 68130, 119616, 0, 0, 42477, 0, 0, + 4495, 0, 0, 0, 0, 70080, 10992, 0, 0, 0, 0, 9318, 0, 6002, 0, 73808, 0, + 92601, 42249, 7639, 43995, 0, 0, 5454, 0, 0, 0, 0, 0, 0, 0, 121189, 0, + 119173, 0, 9704, 120686, 0, 78436, 78435, 11204, 0, 0, 1731, 0, 92937, 0, + 67990, 0, 0, 0, 126576, 127018, 0, 55265, 0, 0, 0, 0, 127257, 73826, 0, + 3840, 0, 41432, 0, 0, 68430, 0, 43253, 128284, 0, 3371, 92936, 0, 0, + 1479, 0, 0, 1109, 77997, 0, 129154, 0, 92782, 0, 0, 8868, 399, 67978, + 74842, 0, 0, 194839, 0, 551, 0, 10156, 0, 92572, 0, 2544, 65074, 0, 0, 0, + 0, 0, 0, 0, 128713, 0, 0, 74268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68045, 0, + 0, 0, 3447, 0, 0, 121414, 2549, 110818, 0, 0, 43564, 8946, 0, 74411, + 66864, 0, 70480, 7980, 0, 113698, 0, 119653, 66489, 0, 64695, 128063, 0, + 0, 0, 0, 0, 0, 43452, 0, 92993, 0, 10919, 0, 67810, 0, 0, 0, 0, 6450, + 10055, 0, 0, 0, 0, 42720, 0, 9626, 0, 128055, 74447, 0, 125127, 92573, 0, + 0, 0, 119075, 0, 0, 66486, 0, 0, 0, 0, 0, 0, 75028, 983864, 74839, 0, 0, + 0, 0, 0, 55286, 0, 1055, 917628, 0, 0, 0, 70516, 12146, 0, 73956, 66488, + 0, 0, 0, 0, 0, 0, 42518, 0, 0, 0, 7407, 74978, 0, 0, 0, 0, 0, 0, 0, + 10231, 0, 66626, 0, 0, 92951, 0, 65927, 0, 0, 69696, 0, 92389, 0, 0, 0, + 68095, 92950, 0, 10555, 0, 0, 9091, 10798, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43222, 0, 74982, 0, 0, 120952, 0, 0, 2992, 7826, 74321, 0, 125103, 74981, + 92628, 0, 0, 128289, 128203, 4361, 129597, 1306, 78770, 1497, 983628, 0, + 0, 0, 8248, 0, 127253, 7973, 128706, 0, 0, 73122, 983930, 0, 0, 2963, + 120653, 0, 128554, 0, 0, 64258, 0, 0, 69677, 74983, 65103, 0, 0, 42625, + 0, 0, 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, + 6203, 4247, 0, 11920, 8274, 68240, 0, 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, + 0, 0, 0, 0, 1144, 0, 0, 0, 0, 0, 118972, 0, 65322, 0, 6441, 0, 0, 2547, + 66484, 43634, 0, 5871, 0, 0, 0, 0, 0, 0, 71204, 0, 0, 1865, 0, 0, 69950, + 0, 0, 73713, 0, 71199, 65826, 2069, 0, 119092, 43999, 2997, 0, 126588, 0, + 65319, 0, 12316, 0, 0, 123630, 8776, 0, 0, 66294, 13130, 0, 71191, + 126625, 0, 10030, 11709, 12364, 983834, 0, 11704, 0, 0, 68672, 0, 0, 0, + 0, 11706, 9710, 0, 82985, 0, 413, 65623, 0, 0, 0, 74446, 0, 1042, 0, + 128378, 12171, 119240, 0, 0, 4984, 0, 708, 11391, 0, 0, 0, 983911, 1308, + 0, 3673, 810, 0, 120933, 0, 0, 0, 1917, 3000, 0, 0, 0, 65628, 66387, + 74470, 0, 0, 0, 10027, 0, 0, 0, 0, 128831, 983167, 2980, 755, 0, 0, + 65622, 0, 121012, 7277, 121022, 0, 0, 0, 0, 8730, 0, 0, 0, 7274, 119250, + 0, 7275, 0, 935, 0, 0, 377, 42325, 121103, 0, 0, 127075, 0, 0, 0, 74911, + 2417, 0, 0, 19912, 0, 0, 0, 0, 0, 0, 0, 7248, 0, 0, 1781, 5496, 3627, 62, + 1649, 0, 964, 0, 0, 0, 0, 92897, 0, 0, 127364, 0, 43689, 127911, 66287, + 78812, 64389, 66575, 0, 73041, 0, 0, 0, 7677, 2991, 0, 0, 0, 0, 72201, 0, + 11341, 127049, 0, 65625, 9714, 11692, 0, 0, 120850, 6478, 10195, 43673, + 65237, 6241, 0, 0, 0, 6238, 0, 0, 0, 4409, 0, 0, 67170, 0, 0, 0, 94047, + 6237, 5461, 66851, 9176, 92882, 121341, 65231, 0, 0, 121182, 128468, 0, + 44018, 0, 64765, 0, 0, 0, 5685, 0, 2461, 0, 7091, 0, 0, 0, 68163, 0, + 73030, 0, 0, 73928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68506, 0, 0, 0, 0, 0, + 2542, 0, 0, 0, 128176, 5776, 0, 0, 0, 0, 0, 11987, 0, 0, 75036, 68744, 0, + 0, 10039, 42828, 0, 0, 0, 0, 0, 10721, 67664, 43433, 0, 0, 41875, 0, + 41870, 266, 129066, 0, 41873, 71271, 0, 0, 0, 0, 0, 0, 41871, 66186, + 3734, 7734, 43683, 8750, 110600, 66011, 92899, 0, 127937, 0, 0, 10572, 0, + 42906, 0, 64349, 7287, 0, 0, 0, 0, 11167, 69220, 0, 43429, 0, 1697, 0, 0, + 68633, 7286, 0, 128738, 10031, 78754, 0, 68645, 8620, 0, 42162, 0, 0, + 7285, 0, 119577, 0, 66842, 43677, 41583, 0, 65799, 129332, 0, 0, 0, 0, + 110806, 0, 3609, 0, 129448, 0, 125116, 126254, 128108, 73948, 0, 0, 0, 0, + 129189, 42732, 92699, 74984, 68620, 11691, 74985, 0, 0, 0, 0, 0, 6348, + 243, 74075, 0, 0, 92309, 123585, 0, 0, 10648, 8538, 43687, 0, 0, 0, + 70515, 0, 118954, 92886, 13307, 129573, 92891, 0, 120770, 983831, 0, 0, + 0, 0, 214, 0, 0, 0, 65893, 0, 120488, 128386, 0, 92893, 0, 2603, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 1016, 0, 0, 0, 3885, 92, 65456, 64608, + 0, 0, 0, 70656, 113742, 0, 0, 0, 128128, 983838, 0, 0, 6791, 983842, + 127960, 0, 0, 0, 118976, 0, 7328, 92358, 0, 7995, 8759, 43421, 0, 68029, + 0, 0, 125272, 0, 3197, 0, 0, 0, 983150, 0, 11595, 0, 0, 43435, 0, 0, 0, + 0, 0, 70660, 0, 741, 83291, 5494, 0, 70668, 1990, 11107, 4498, 0, 0, + 70658, 0, 0, 2960, 73779, 0, 8969, 0, 43424, 0, 0, 2950, 0, 0, 129035, + 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122900, 0, 0, 0, 0, 2964, 43663, 0, + 6344, 0, 0, 10144, 0, 8252, 729, 66016, 78446, 0, 0, 0, 78740, 43669, + 9032, 0, 0, 0, 0, 0, 0, 0, 0, 74612, 3761, 0, 0, 0, 0, 0, 0, 3850, 0, 0, + 128389, 0, 0, 0, 0, 8611, 0, 0, 0, 43691, 125032, 0, 41802, 120540, 0, 0, + 0, 0, 0, 3848, 0, 113800, 127536, 0, 0, 0, 983270, 663, 0, 0, 0, 0, 0, 0, + 0, 0, 13221, 0, 0, 0, 0, 0, 121348, 0, 65579, 12980, 68046, 12143, 0, + 128067, 0, 43441, 41804, 0, 0, 0, 0, 0, 0, 66329, 0, 72324, 0, 0, 125038, + 0, 129383, 0, 0, 0, 983871, 0, 0, 0, 0, 0, 1097, 129033, 0, 0, 0, 93828, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13110, 0, 983867, 68229, 1000, 0, 0, 0, + 1209, 0, 0, 0, 1073, 6321, 77878, 0, 0, 68213, 0, 12167, 0, 0, 0, 0, + 73673, 121500, 0, 121501, 0, 6587, 0, 0, 0, 9231, 0, 2959, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 42941, 0, 0, 68434, 0, 70742, 0, 0, 12290, 0, 0, 110801, + 0, 77873, 8205, 110803, 5131, 0, 0, 0, 0, 0, 0, 1944, 78453, 0, 0, + 119990, 119991, 12701, 78492, 11308, 119995, 0, 113702, 66836, 119999, + 74263, 92382, 120002, 120003, 7075, 120005, 120006, 120007, 41817, 75063, + 42275, 120011, 120012, 120013, 120014, 42943, 6041, 0, 41899, 0, 8002, 0, + 41902, 0, 0, 64332, 0, 7813, 119117, 0, 41900, 120633, 0, 7281, 78455, + 7279, 12041, 93027, 0, 12673, 0, 129123, 9660, 0, 72984, 0, 0, 0, 0, + 92901, 2970, 0, 0, 0, 77870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3486, 0, 0, 0, 0, + 127799, 0, 0, 0, 69920, 0, 66834, 0, 983987, 0, 68312, 0, 65673, 1019, + 78495, 4148, 0, 12289, 0, 4316, 0, 13119, 983913, 0, 0, 0, 0, 0, 0, + 43434, 41865, 128218, 9163, 8659, 9072, 5867, 13302, 7622, 7120, 0, 0, 0, + 0, 7400, 5416, 0, 0, 10817, 0, 0, 0, 0, 68162, 41855, 41867, 0, 983224, + 0, 11536, 0, 0, 7115, 0, 0, 5498, 7337, 41536, 0, 0, 92587, 7221, 8997, + 0, 0, 0, 0, 0, 0, 127814, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 121292, 0, + 43454, 63903, 63902, 63901, 0, 3971, 0, 0, 2952, 0, 11038, 10901, 63900, + 63899, 63898, 5198, 667, 43273, 63887, 63886, 128458, 78521, 66830, 0, + 92714, 4159, 0, 0, 63885, 63884, 63883, 63882, 63880, 8555, 63878, 63877, + 93057, 0, 0, 63881, 10746, 0, 118983, 0, 63876, 63875, 63874, 63873, + 7432, 1913, 41913, 63852, 0, 128971, 0, 983875, 0, 446, 41911, 0, 63851, + 63850, 41910, 0, 63846, 2972, 63844, 7262, 0, 63849, 63848, 63847, 72990, + 6570, 0, 7259, 63842, 4178, 63840, 121321, 41521, 63894, 63893, 63892, 0, + 0, 1105, 4180, 0, 7418, 0, 0, 63891, 63890, 63889, 63888, 0, 0, 0, 0, + 1678, 0, 66909, 0, 0, 0, 0, 11192, 128360, 128404, 9159, 70089, 63861, + 63860, 63859, 63858, 63865, 1615, 63863, 63862, 0, 0, 0, 0, 63857, 63856, + 71902, 0, 1077, 0, 65099, 0, 0, 0, 0, 0, 0, 42773, 121331, 0, 0, 119220, + 120912, 129564, 0, 1112, 119122, 8686, 0, 0, 65081, 0, 0, 0, 11077, 0, + 7260, 0, 5327, 0, 63870, 63869, 3847, 63867, 0, 2903, 0, 3001, 66762, 0, + 43746, 0, 63866, 0, 0, 0, 0, 0, 127785, 68420, 2990, 0, 128254, 0, 0, 0, + 0, 1117, 118987, 12212, 129003, 129151, 63836, 63835, 63834, 0, 0, 63839, + 63838, 63837, 0, 125095, 63833, 6042, 66360, 0, 74808, 0, 63821, 63820, + 63819, 63818, 0, 0, 9047, 63822, 128328, 6091, 0, 10691, 0, 74344, 8226, + 0, 63812, 63811, 63810, 63809, 2289, 63815, 63814, 63813, 6047, 0, 0, + 780, 63808, 77925, 77922, 65147, 63931, 63930, 2076, 1093, 9882, 63934, + 2082, 63932, 75050, 63929, 63928, 63927, 77934, 9806, 65566, 77933, + 63922, 63921, 2086, 0, 63926, 2984, 5968, 63923, 0, 0, 129458, 11137, + 13169, 5290, 2089, 0, 63827, 1088, 63825, 7268, 1084, 1085, 63829, 1083, + 10131, 7283, 0, 0, 0, 1092, 0, 7273, 983272, 44016, 43627, 0, 0, 0, + 11809, 0, 0, 0, 2965, 7258, 8808, 0, 1089, 7278, 63937, 63936, 43405, + 11106, 940, 5787, 10099, 63938, 0, 63897, 126123, 2994, 0, 0, 0, 121041, + 77939, 77940, 77937, 77938, 74343, 93043, 72704, 660, 10127, 666, 0, + 5532, 43667, 5533, 77941, 0, 0, 0, 979, 0, 0, 72706, 92652, 9108, 0, + 128374, 129403, 63951, 71685, 0, 0, 128782, 63946, 1707, 983824, 128612, + 63950, 63949, 63948, 63947, 63945, 6038, 63943, 63942, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 73884, 0, 1690, 63919, 63918, 63917, 70865, 43659, 0, 983829, + 0, 2054, 0, 78515, 63916, 9184, 63914, 69737, 63911, 63910, 63909, 63908, + 0, 0, 63913, 6044, 0, 0, 9061, 5534, 10672, 11653, 124932, 5531, 0, 0, 0, + 0, 0, 0, 11957, 0, 68668, 0, 0, 0, 10474, 43426, 0, 42354, 0, 0, 0, 0, 0, + 8413, 66841, 0, 7269, 7272, 0, 0, 0, 125008, 78460, 0, 0, 0, 0, 126639, + 0, 0, 0, 66840, 0, 0, 128441, 0, 0, 0, 92187, 7270, 0, 0, 6628, 1076, + 128700, 0, 0, 0, 0, 0, 0, 12807, 43413, 63906, 4548, 63904, 71187, 70393, + 41729, 44005, 1307, 0, 0, 0, 0, 0, 128268, 0, 8180, 0, 127778, 0, 0, + 5413, 43681, 123205, 3493, 0, 0, 0, 92544, 73937, 10517, 0, 4518, 10990, + 0, 5167, 4481, 3771, 0, 2710, 0, 66277, 0, 0, 43073, 0, 0, 0, 0, 0, 0, + 119659, 1628, 0, 0, 0, 65262, 66809, 10783, 11172, 0, 0, 70840, 113679, + 0, 119029, 0, 0, 41530, 66843, 4457, 0, 0, 0, 0, 0, 41529, 0, 0, 6031, + 65807, 70814, 0, 0, 0, 69705, 0, 0, 11926, 6033, 9656, 0, 0, 0, 68869, 0, + 128930, 0, 128100, 0, 42612, 43655, 0, 0, 0, 66468, 0, 0, 68623, 0, 0, 0, + 0, 120869, 983343, 0, 0, 1151, 0, 73709, 127544, 0, 71106, 0, 0, 0, 0, 0, + 0, 0, 11527, 118870, 0, 0, 11538, 127387, 0, 11020, 0, 66467, 0, 8087, + 71700, 0, 9894, 0, 0, 70824, 120854, 0, 78513, 8053, 0, 0, 0, 0, 120495, + 0, 0, 63845, 0, 0, 78602, 0, 13084, 70170, 8741, 0, 0, 0, 0, 64605, + 83051, 0, 473, 43415, 0, 0, 119271, 1087, 124966, 71275, 0, 0, 66439, + 43218, 0, 0, 7237, 0, 0, 0, 0, 0, 92261, 0, 121036, 4384, 74220, 983779, + 2058, 917561, 0, 0, 0, 0, 0, 3857, 0, 0, 0, 64630, 0, 0, 74168, 0, + 125088, 4421, 0, 0, 0, 66400, 0, 68431, 0, 0, 0, 83053, 0, 0, 69640, + 127861, 0, 437, 0, 0, 0, 0, 65236, 13290, 119180, 4997, 64306, 0, 0, + 4999, 0, 0, 0, 4711, 120769, 0, 2739, 0, 92915, 74834, 0, 127175, 0, 0, + 0, 0, 0, 1779, 6600, 6601, 0, 5325, 0, 128437, 13058, 0, 0, 0, 92186, 0, + 71845, 10575, 43399, 0, 0, 0, 1104, 0, 0, 10655, 0, 0, 0, 0, 1082, + 110878, 0, 67401, 0, 0, 0, 0, 6783, 0, 0, 42867, 69655, 44021, 6458, 0, + 0, 0, 0, 0, 0, 1273, 43407, 0, 0, 0, 0, 1313, 6322, 41720, 128627, 66433, + 0, 0, 0, 11216, 0, 0, 0, 43437, 93833, 0, 0, 0, 5122, 0, 72728, 129520, + 70161, 0, 0, 0, 0, 0, 8303, 0, 128926, 0, 10003, 0, 0, 0, 1686, 0, 0, + 42834, 3664, 0, 126088, 121346, 0, 0, 4324, 126, 0, 0, 0, 0, 0, 65166, 0, + 0, 0, 0, 43817, 0, 43822, 0, 0, 65600, 13002, 0, 0, 0, 1103, 0, 119575, + 0, 0, 13078, 0, 8116, 0, 2050, 0, 0, 1102, 0, 6555, 0, 0, 74003, 74794, + 0, 0, 42591, 127278, 0, 1111, 0, 75047, 4707, 0, 0, 0, 0, 43468, 4522, + 8645, 0, 74857, 0, 11352, 0, 0, 0, 2293, 0, 0, 0, 128265, 71709, 0, 0, 0, + 93827, 0, 0, 0, 128488, 0, 160, 2677, 0, 0, 120141, 0, 0, 70790, 0, + 42770, 0, 0, 0, 43821, 113769, 0, 0, 43816, 0, 0, 1079, 3867, 64817, 0, + 0, 0, 0, 64768, 0, 0, 4005, 983211, 0, 10991, 0, 92957, 917578, 917581, + 917580, 917575, 128314, 917577, 917576, 917571, 78534, 917573, 917572, 0, + 0, 128359, 73458, 0, 3339, 11448, 1106, 917591, 917590, 917593, 3340, + 917587, 917586, 917589, 917588, 917583, 10605, 1309, 74996, 120743, + 92650, 0, 0, 9485, 0, 0, 0, 0, 0, 125002, 92533, 128487, 0, 129285, 4338, + 11238, 0, 66825, 0, 0, 0, 0, 0, 0, 74128, 0, 0, 73680, 0, 129438, 9553, + 1590, 63777, 63776, 128677, 63782, 63781, 63780, 63779, 1583, 0, 0, 0, 0, + 128011, 0, 0, 41522, 0, 92168, 983784, 66759, 0, 983584, 0, 0, 0, 0, + 11394, 0, 983071, 0, 66823, 1334, 0, 4479, 0, 0, 120663, 0, 122883, + 10497, 0, 0, 983777, 66828, 0, 0, 0, 6809, 63786, 0, 0, 63791, 63790, + 1145, 63788, 119143, 63785, 63784, 63783, 10192, 65267, 0, 0, 8928, 0, 0, + 0, 0, 0, 74216, 66805, 0, 0, 63759, 63758, 3523, 1074, 0, 121340, 74077, + 0, 0, 0, 63757, 43145, 63755, 63754, 63752, 1349, 63750, 63749, 0, 0, 0, + 63753, 63802, 41084, 72784, 0, 41930, 63805, 63804, 11140, 63801, 41082, + 43843, 42787, 123197, 0, 0, 0, 63793, 63792, 0, 128241, 10201, 12238, + 63795, 42358, 92394, 43862, 0, 0, 41932, 66826, 0, 0, 0, 121136, 0, 7950, + 63772, 63771, 63770, 0, 63767, 63766, 2793, 63764, 0, 128501, 63769, + 9530, 0, 92398, 0, 128642, 63763, 63762, 4595, 63760, 792, 0, 0, 0, 8742, + 0, 0, 0, 63744, 0, 0, 120815, 63748, 63747, 63746, 63745, 5055, 0, 0, + 1090, 0, 125268, 11665, 127809, 4558, 0, 72211, 0, 0, 0, 11513, 0, 6157, + 63775, 63774, 63773, 0, 12170, 9067, 0, 0, 10872, 129643, 43891, 43893, + 43892, 0, 43933, 0, 128231, 0, 0, 0, 0, 0, 11063, 0, 43888, 0, 0, 128368, + 43889, 0, 73807, 983104, 7386, 0, 0, 70295, 0, 0, 0, 71201, 128460, 0, 0, + 0, 0, 69915, 2918, 66820, 65300, 0, 127859, 64726, 2790, 0, 3793, 42065, + 127829, 0, 129560, 0, 0, 0, 0, 0, 92712, 0, 12923, 5270, 0, 0, 0, 65813, + 0, 128499, 0, 75012, 0, 10888, 0, 93997, 0, 3330, 129417, 0, 0, 0, 0, 0, + 8220, 0, 0, 0, 0, 1627, 0, 0, 0, 5371, 118938, 0, 1826, 118794, 0, 0, + 70023, 0, 0, 0, 71108, 0, 0, 0, 0, 92207, 68125, 74898, 101069, 0, 0, + 71098, 70029, 0, 43116, 0, 70019, 64346, 0, 0, 66818, 0, 70031, 0, 12666, + 120413, 120420, 120414, 120406, 120428, 0, 120431, 0, 65509, 0, 7449, 0, + 0, 0, 7438, 0, 0, 9054, 971, 0, 0, 0, 65195, 64767, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 64303, 0, 2303, 0, 0, 0, 0, 65833, 0, 7271, 0, 0, 0, 0, 12229, 0, + 0, 43411, 73751, 0, 64813, 0, 0, 10476, 0, 0, 3932, 64958, 0, 0, 73989, + 0, 0, 0, 113816, 0, 0, 0, 0, 0, 0, 92645, 65474, 4796, 118892, 129357, + 65479, 0, 42895, 0, 65500, 0, 9899, 92608, 0, 404, 65484, 120639, 0, + 5788, 127852, 0, 65491, 1831, 66020, 0, 983993, 92588, 0, 1343, 120784, + 0, 0, 12018, 0, 0, 0, 0, 0, 4422, 4708, 3799, 119358, 119357, 0, 120510, + 0, 119361, 119360, 983095, 0, 1364, 0, 8038, 0, 0, 12868, 0, 70425, + 55223, 0, 64414, 110689, 0, 0, 0, 0, 0, 0, 118802, 0, 42855, 118856, + 42866, 0, 0, 0, 0, 66438, 0, 983977, 119356, 119355, 119354, 0, 983580, + 0, 0, 67685, 128062, 119350, 0, 64512, 10404, 10340, 119352, 1556, 5274, + 0, 0, 10017, 9733, 0, 129476, 0, 41373, 0, 0, 0, 0, 0, 349, 4863, 41371, + 0, 0, 0, 0, 72295, 4398, 8543, 65618, 128018, 0, 0, 0, 0, 12441, 0, + 119348, 119347, 4318, 10452, 0, 8032, 0, 119349, 119344, 0, 127844, + 121156, 0, 110729, 119345, 8597, 0, 110727, 9864, 0, 0, 0, 0, 0, 0, 0, + 7722, 0, 0, 0, 0, 0, 66590, 0, 0, 0, 0, 0, 0, 4965, 0, 917536, 0, 123196, + 0, 0, 0, 10436, 119342, 43147, 119340, 10356, 10420, 982, 2756, 0, + 983978, 0, 0, 11162, 119338, 0, 92914, 0, 65110, 0, 0, 983781, 78543, 0, + 118793, 0, 128112, 119179, 64476, 1694, 8216, 0, 0, 78539, 0, 65620, 0, + 78537, 0, 0, 42158, 65621, 69955, 120324, 120327, 120326, 120321, 120320, + 120323, 120322, 12314, 65616, 55221, 43825, 983553, 119337, 68060, + 119335, 0, 71874, 123628, 128537, 119332, 73089, 0, 41347, 0, 0, 8842, 0, + 0, 4379, 127393, 12692, 0, 0, 66353, 71875, 0, 0, 92907, 0, 0, 71877, + 120303, 65619, 9872, 0, 0, 1846, 120309, 120308, 119256, 71192, 120305, + 120304, 120307, 6442, 120317, 120316, 5379, 120318, 110717, 120312, + 120315, 71876, 0, 65934, 66497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6151, + 12110, 0, 0, 0, 0, 0, 0, 0, 0, 68335, 0, 0, 0, 0, 0, 0, 66041, 9676, + 10202, 0, 0, 0, 64575, 126637, 11965, 0, 124936, 0, 0, 0, 0, 0, 9698, + 66293, 0, 119651, 0, 0, 41921, 0, 0, 0, 119258, 0, 0, 0, 0, 0, 8012, + 12355, 12353, 0, 0, 74107, 0, 0, 41925, 0, 41920, 65444, 0, 0, 41923, + 12694, 0, 10112, 1294, 0, 120091, 0, 120092, 0, 0, 128474, 121400, 0, 0, + 0, 8718, 0, 10284, 10268, 10380, 10316, 92593, 0, 71850, 0, 0, 92889, 0, + 0, 0, 0, 9342, 12829, 0, 0, 0, 127978, 0, 0, 69428, 0, 73767, 72347, 0, + 7956, 598, 0, 72329, 93837, 0, 0, 128860, 0, 120041, 0, 0, 0, 0, 0, 847, + 0, 9529, 0, 0, 0, 0, 120035, 0, 0, 0, 67411, 0, 0, 0, 120040, 0, 128580, + 0, 9624, 0, 0, 0, 65463, 1554, 0, 0, 0, 0, 71879, 0, 0, 0, 121161, 19963, + 123625, 0, 72326, 92933, 71887, 10324, 10292, 65546, 0, 68141, 8372, 0, + 0, 83018, 120022, 10175, 10388, 42799, 0, 983180, 10568, 0, 127400, 0, 0, + 0, 983743, 0, 4366, 0, 983786, 0, 0, 42608, 0, 9884, 0, 0, 0, 0, 129180, + 0, 0, 0, 0, 1609, 0, 92773, 73448, 0, 11661, 0, 5818, 0, 0, 0, 9540, 0, + 2554, 5158, 0, 2213, 0, 0, 78522, 43079, 0, 0, 8264, 11175, 64553, + 120863, 42155, 0, 0, 0, 0, 0, 0, 8676, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, + 123167, 43609, 0, 0, 1440, 0, 0, 0, 127061, 11005, 0, 66656, 127063, 0, + 0, 0, 127065, 43393, 0, 120643, 0, 0, 0, 0, 120798, 0, 0, 0, 0, 0, 0, + 70435, 64356, 0, 0, 0, 383, 7154, 127815, 43495, 128809, 121448, 0, 0, 0, + 11286, 0, 0, 0, 0, 0, 0, 0, 42644, 0, 0, 0, 8292, 0, 4980, 113726, 92674, + 70130, 0, 0, 0, 0, 74912, 0, 10631, 83330, 100488, 68042, 0, 0, 7900, 0, + 0, 78779, 4198, 128555, 0, 0, 0, 123159, 0, 0, 12931, 0, 0, 0, 2088, 0, + 72164, 129284, 0, 0, 124951, 0, 0, 0, 69694, 0, 0, 8593, 0, 0, 0, 0, 0, + 0, 11798, 0, 100483, 0, 0, 0, 64211, 128865, 120494, 0, 0, 0, 121228, + 68901, 128788, 0, 0, 65162, 0, 0, 0, 0, 0, 128130, 0, 92264, 127153, 0, + 128818, 0, 0, 61, 0, 0, 92182, 119554, 0, 0, 12089, 0, 65834, 83281, + 119671, 128701, 0, 0, 42566, 42743, 0, 69824, 0, 92653, 0, 0, 42621, 0, + 0, 0, 0, 0, 43266, 0, 0, 0, 74843, 0, 0, 119103, 64417, 0, 0, 64737, 0, + 0, 8930, 0, 0, 66900, 10056, 1800, 0, 0, 0, 0, 121175, 7743, 0, 0, + 119528, 92640, 92453, 9034, 6039, 129139, 10075, 0, 0, 0, 10748, 0, 0, 0, + 0, 0, 92984, 0, 0, 128183, 129421, 0, 43064, 127558, 0, 7539, 0, 0, 0, 0, + 0, 0, 0, 92898, 42567, 0, 0, 73886, 0, 0, 12326, 0, 0, 0, 0, 11355, 0, 0, + 0, 0, 69437, 0, 0, 0, 119537, 72327, 43005, 65342, 118902, 0, 0, 8644, 0, + 0, 11186, 74296, 41909, 0, 128682, 2791, 0, 1891, 0, 0, 41907, 66647, 0, + 0, 41906, 0, 0, 10773, 70206, 0, 0, 0, 6412, 2061, 8520, 13146, 0, 0, + 83275, 65902, 2882, 0, 126232, 65852, 0, 983306, 0, 123627, 0, 0, 0, 0, + 0, 128098, 0, 0, 0, 70871, 0, 0, 0, 120087, 0, 0, 0, 93971, 0, 3844, + 6842, 0, 0, 6612, 0, 0, 0, 0, 0, 783, 0, 0, 0, 983064, 68032, 119225, 0, + 0, 68378, 4556, 67839, 68480, 78663, 120069, 120074, 67657, 10510, 4382, + 74218, 42194, 0, 0, 9177, 8902, 93958, 9839, 0, 120700, 0, 0, 63999, + 41904, 41917, 9788, 120973, 0, 1862, 0, 0, 0, 41915, 0, 41919, 63994, + 41914, 7981, 0, 0, 0, 0, 0, 0, 0, 120834, 0, 0, 0, 6784, 78788, 0, 0, 0, + 0, 127534, 127484, 127476, 0, 0, 983941, 64289, 65289, 0, 129539, 129575, + 64509, 0, 0, 126505, 11051, 0, 66635, 55259, 65885, 0, 128310, 0, 0, 0, + 0, 7500, 4506, 0, 0, 0, 0, 0, 126609, 4040, 128680, 6167, 0, 0, 0, 0, 0, + 0, 7830, 43036, 0, 0, 63990, 19947, 63988, 63987, 0, 63993, 10440, 9611, + 0, 71883, 0, 65260, 63986, 11446, 63984, 92641, 3435, 119652, 0, 119108, + 0, 128632, 0, 0, 12748, 0, 0, 92705, 0, 78790, 0, 0, 63956, 42458, 63954, + 63953, 63960, 63959, 63958, 11596, 0, 11469, 70025, 42306, 2723, 0, 0, + 70027, 0, 0, 0, 128093, 2880, 0, 0, 0, 0, 128506, 3498, 4378, 0, 0, 0, + 65551, 118928, 0, 43387, 0, 64415, 128898, 0, 0, 0, 0, 8161, 393, 12013, + 0, 92216, 126479, 63965, 63964, 63963, 42345, 0, 0, 63967, 42498, 0, + 2927, 0, 63961, 0, 0, 983927, 0, 69699, 0, 42340, 0, 0, 0, 10730, 0, + 69688, 0, 64187, 0, 0, 12437, 9813, 0, 42453, 1604, 9565, 0, 69701, + 69235, 42414, 110724, 129196, 0, 42301, 11372, 0, 917973, 0, 0, 63980, + 63979, 63978, 0, 128207, 12017, 63982, 63981, 73687, 0, 63977, 63976, + 72794, 0, 0, 0, 63971, 4347, 4416, 63968, 11009, 63974, 63973, 402, + 69390, 13147, 0, 0, 64646, 13228, 0, 0, 3515, 74252, 65261, 0, 0, 6259, + 0, 0, 0, 0, 0, 0, 74813, 74425, 0, 126998, 126114, 0, 0, 0, 0, 983698, 0, + 0, 74301, 0, 0, 0, 0, 74060, 0, 0, 66235, 5145, 0, 0, 128394, 0, 73120, + 0, 7402, 0, 0, 0, 7952, 7832, 43382, 66616, 0, 983931, 120852, 0, 127875, + 64866, 0, 0, 0, 78784, 74248, 0, 0, 983196, 0, 0, 0, 78656, 42390, 0, 0, + 983921, 0, 0, 0, 0, 9508, 0, 9544, 11520, 0, 0, 3377, 0, 129562, 0, 0, 0, + 0, 0, 66280, 0, 127198, 0, 0, 0, 1955, 119565, 0, 0, 3076, 0, 42168, + 73049, 66304, 0, 0, 8917, 42403, 301, 0, 0, 0, 0, 0, 0, 0, 0, 67819, + 92987, 0, 0, 0, 983204, 0, 69403, 3182, 0, 0, 0, 0, 0, 42169, 123162, + 74244, 0, 42329, 0, 66326, 6841, 0, 128913, 0, 1219, 3934, 71276, 11483, + 74510, 0, 0, 42442, 65470, 0, 0, 64622, 7759, 42482, 485, 0, 0, 42290, 0, + 0, 42280, 0, 0, 11655, 64379, 127913, 42431, 10126, 42318, 0, 119631, + 74397, 42470, 0, 68315, 0, 110829, 74041, 0, 0, 0, 5411, 0, 0, 0, 64205, + 0, 64206, 42393, 64478, 1310, 125007, 0, 12052, 10643, 55271, 72727, 0, + 121045, 0, 0, 118852, 0, 0, 0, 0, 113826, 0, 0, 64385, 0, 0, 0, 0, 0, 0, + 93848, 92560, 2713, 0, 9650, 0, 0, 120602, 1406, 0, 78174, 92659, 0, + 68223, 0, 0, 0, 0, 43475, 0, 65287, 1508, 127938, 8779, 10569, 75034, 0, + 0, 0, 0, 0, 0, 0, 70786, 0, 0, 128344, 9185, 0, 42932, 43403, 0, 0, 0, 0, + 0, 0, 0, 0, 12955, 0, 2888, 0, 0, 0, 0, 0, 0, 0, 2878, 0, 0, 0, 0, 0, 0, + 129028, 13203, 0, 10429, 10365, 0, 0, 127165, 7503, 0, 113676, 68381, + 119658, 0, 8986, 0, 10632, 11934, 11452, 1332, 0, 0, 0, 0, 73741, 1791, + 8850, 9288, 0, 2892, 0, 43394, 555, 0, 0, 0, 0, 64172, 118899, 0, 0, 0, + 0, 8854, 0, 5858, 73101, 10582, 0, 0, 1361, 0, 0, 7905, 0, 65256, 0, + 41210, 0, 0, 71884, 0, 0, 0, 6828, 0, 92302, 0, 1342, 68440, 0, 64161, + 10903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64381, 0, 0, 0, 42245, 126467, + 41972, 0, 0, 0, 9127, 0, 66619, 126489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11620, + 0, 1149, 68316, 0, 0, 0, 0, 0, 92492, 0, 118784, 0, 0, 0, 12838, 0, + 118819, 0, 0, 0, 0, 41087, 0, 0, 0, 0, 12036, 0, 0, 0, 0, 0, 64428, + 12227, 0, 0, 0, 0, 125248, 120964, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1743, + 0, 0, 0, 65186, 0, 0, 0, 0, 0, 64439, 0, 68062, 0, 111259, 111258, 43866, + 0, 111263, 3395, 9362, 111260, 0, 111257, 111256, 111255, 0, 0, 41091, + 3426, 1344, 111249, 111248, 126215, 4735, 11111, 6119, 111251, 42699, 0, + 0, 74818, 1423, 0, 0, 0, 0, 12039, 10559, 0, 0, 0, 9472, 67734, 11929, 0, + 0, 0, 0, 128826, 0, 11579, 0, 0, 128364, 0, 92185, 0, 0, 1004, 92584, 0, + 0, 0, 0, 0, 2556, 0, 0, 72790, 0, 0, 9686, 0, 0, 0, 70109, 111102, 0, + 10718, 13154, 111100, 9139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41708, 12860, + 41703, 0, 42090, 5403, 10352, 73917, 129144, 111096, 0, 5140, 3753, + 118785, 41704, 0, 43078, 127789, 111092, 129360, 0, 983205, 92362, 0, 0, + 2410, 92525, 0, 0, 0, 0, 0, 0, 0, 0, 119253, 0, 126601, 0, 2066, 74199, + 0, 43463, 10659, 119623, 68863, 0, 1336, 0, 0, 69463, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 983946, 128133, 0, 0, 124940, 0, 1190, + 42146, 1335, 42177, 43867, 0, 0, 10448, 0, 125041, 0, 0, 2099, 5120, + 2409, 7799, 0, 74424, 0, 126581, 4731, 0, 111199, 111198, 111197, 111196, + 11689, 0, 74977, 9913, 129430, 0, 0, 0, 111195, 111194, 11694, 0, 11690, + 111189, 111188, 111187, 11693, 111193, 111192, 43097, 11688, 0, 78797, + 194, 111186, 111185, 111184, 0, 0, 0, 11226, 4519, 70337, 10898, 43072, + 70205, 0, 0, 0, 73094, 10695, 0, 7540, 0, 110984, 41859, 6067, 0, 0, 0, + 110981, 13311, 0, 41857, 0, 8359, 121224, 12689, 0, 983131, 64577, + 111204, 111203, 68183, 111209, 111208, 6064, 110988, 0, 110979, 74142, 0, + 111201, 111200, 6051, 123613, 0, 0, 983369, 0, 0, 0, 0, 0, 110864, 10537, + 110862, 1276, 0, 6549, 6052, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1960, 0, 71232, + 66297, 0, 129313, 0, 0, 1345, 111213, 111212, 111211, 8956, 43083, 0, + 111215, 64682, 0, 6430, 0, 111210, 119814, 0, 0, 0, 119817, 0, 492, + 43087, 0, 0, 0, 0, 0, 2582, 0, 0, 7444, 72863, 0, 2297, 111243, 73837, 0, + 0, 65096, 197, 74183, 0, 71125, 111241, 111240, 0, 66515, 43550, 119829, + 111229, 111228, 93764, 111226, 0, 0, 111231, 111230, 71686, 1799, 0, + 42148, 74336, 0, 0, 65340, 111220, 110974, 2262, 111217, 111224, 74931, + 111222, 10896, 0, 0, 0, 0, 6338, 111003, 110997, 110994, 111006, 111002, + 111005, 0, 111279, 111278, 111277, 72133, 0, 111273, 111272, 110961, + 3171, 6623, 4961, 0, 886, 55216, 8654, 0, 111270, 74390, 64603, 111267, + 129283, 68122, 0, 43084, 0, 0, 0, 0, 69693, 8994, 10944, 65938, 111239, + 111238, 111237, 111236, 66279, 92890, 42510, 0, 0, 6804, 0, 1947, 0, 0, + 0, 42759, 0, 1705, 983345, 0, 0, 0, 0, 72722, 74036, 0, 0, 66720, 111281, + 111280, 0, 4909, 111285, 111284, 111283, 4904, 0, 43503, 1365, 9253, + 42757, 0, 7462, 0, 0, 0, 0, 119587, 0, 917579, 92526, 0, 125035, 0, + 111311, 111310, 0, 0, 0, 0, 93977, 0, 0, 0, 0, 3629, 0, 13005, 0, 3628, + 0, 111295, 0, 0, 0, 0, 111290, 64809, 2928, 4905, 111083, 851, 55233, + 111291, 111059, 43086, 9114, 43870, 42583, 9315, 4822, 4906, 121097, + 2847, 111028, 10330, 0, 1251, 7777, 41852, 125059, 111327, 111032, + 111325, 12646, 0, 10259, 0, 65821, 75046, 6018, 0, 111324, 111323, + 111322, 68372, 111319, 111318, 71893, 2558, 0, 64584, 111321, 111320, 0, + 0, 0, 0, 111309, 111308, 111307, 111306, 73987, 74599, 71895, 93012, 0, + 128715, 0, 12867, 111296, 0, 0, 11044, 111300, 111299, 8904, 11824, + 65857, 0, 128674, 129027, 4387, 0, 0, 0, 0, 0, 0, 0, 11842, 0, 0, 0, + 5136, 1968, 983041, 126627, 1337, 0, 0, 0, 0, 66506, 0, 0, 0, 0, 42314, + 121384, 0, 0, 6120, 0, 65670, 68128, 0, 43082, 6016, 0, 42284, 71894, + 4276, 111314, 3619, 41638, 69691, 0, 42322, 8853, 111043, 0, 490, 0, + 13231, 68384, 72310, 65350, 0, 0, 0, 68245, 42435, 6154, 0, 65354, 0, 0, + 42397, 334, 72732, 42416, 65359, 65273, 74634, 128227, 4442, 10364, 0, + 778, 41626, 42455, 7989, 0, 3227, 69907, 111053, 0, 2915, 11502, 983212, + 41702, 10309, 0, 0, 0, 0, 0, 0, 0, 127268, 127258, 127267, 65215, 64410, + 127260, 71175, 0, 0, 0, 0, 0, 0, 41700, 110651, 0, 126488, 0, 0, 42495, + 0, 0, 0, 10460, 43364, 0, 1356, 3728, 42713, 0, 0, 42342, 10914, 0, + 42489, 64310, 66896, 41861, 42297, 0, 0, 41860, 64862, 0, 0, 5289, 42336, + 128658, 0, 92529, 42410, 0, 120624, 0, 2649, 74493, 0, 126635, 0, 3382, + 42449, 9081, 1658, 11936, 93019, 113814, 11269, 0, 0, 43100, 69888, + 65508, 0, 0, 121451, 0, 0, 0, 0, 0, 4732, 128283, 0, 0, 0, 121113, 2236, + 126551, 0, 6048, 0, 0, 73965, 0, 0, 0, 0, 10151, 9681, 4475, 0, 64735, + 2100, 0, 0, 6035, 0, 123599, 10296, 0, 0, 0, 0, 0, 0, 0, 983307, 68488, + 10392, 10328, 0, 43462, 0, 0, 0, 8979, 0, 0, 983304, 0, 0, 0, 10977, 0, + 10344, 0, 65299, 10408, 0, 0, 121187, 66505, 0, 0, 0, 0, 0, 0, 43074, + 73799, 0, 0, 0, 0, 3446, 0, 0, 128692, 0, 0, 119582, 4474, 0, 43093, + 6282, 0, 0, 127372, 0, 0, 0, 0, 0, 0, 0, 0, 66910, 67811, 92277, 0, + 64948, 0, 74347, 0, 0, 0, 983962, 8194, 0, 121165, 11010, 0, 8893, 0, + 983969, 0, 0, 0, 983317, 7925, 0, 0, 113825, 0, 1352, 11069, 7707, 0, + 126486, 0, 0, 0, 0, 65605, 6040, 0, 10071, 0, 128156, 43750, 0, 8899, + 69873, 0, 0, 983311, 128208, 7820, 69615, 0, 0, 7746, 1492, 0, 0, 0, + 66866, 0, 11788, 65913, 0, 0, 43095, 0, 0, 92265, 2999, 0, 120720, 0, + 371, 0, 6023, 0, 0, 11708, 0, 0, 6323, 0, 0, 0, 8938, 6043, 65866, 0, 0, + 0, 72419, 0, 129480, 2589, 74332, 1689, 7802, 0, 0, 0, 0, 66704, 0, 0, 0, + 0, 128127, 6049, 0, 4027, 0, 0, 111334, 111333, 1503, 111331, 0, 111337, + 11951, 111335, 2387, 0, 0, 8289, 111330, 7326, 66514, 65514, 0, 64865, 0, + 9668, 0, 0, 0, 0, 93060, 6036, 92768, 4026, 74089, 127091, 0, 0, 75044, + 110821, 0, 110819, 0, 0, 0, 0, 6021, 0, 128288, 0, 43155, 0, 110822, 0, + 111343, 42691, 111341, 111340, 0, 166, 0, 0, 0, 10623, 408, 0, 111339, + 13298, 0, 7426, 43694, 0, 0, 8811, 0, 0, 0, 0, 0, 74134, 983054, 0, + 127811, 0, 0, 0, 6645, 646, 128813, 0, 42129, 0, 120880, 0, 8697, 0, + 120936, 0, 0, 0, 0, 5809, 1950, 0, 92432, 68339, 0, 42136, 0, 0, 0, 0, 0, + 0, 111354, 983965, 0, 0, 111349, 111348, 43330, 111346, 111353, 111352, + 41567, 111350, 0, 0, 0, 0, 111345, 111344, 8285, 0, 4509, 0, 128361, 0, + 0, 0, 0, 0, 41727, 0, 0, 0, 0, 0, 0, 0, 74512, 7027, 3886, 0, 74023, + 92888, 0, 0, 126092, 94058, 119855, 0, 121455, 11707, 119852, 0, 7939, + 10342, 92460, 72747, 121408, 917569, 0, 71198, 94077, 119847, 0, 0, 7201, + 0, 0, 120866, 983968, 1540, 0, 0, 0, 0, 0, 41718, 71177, 0, 0, 128001, 0, + 0, 119040, 0, 9619, 120840, 0, 0, 0, 0, 3560, 0, 6070, 129000, 0, 2922, + 6082, 70147, 65009, 983954, 0, 0, 0, 0, 0, 0, 3607, 65863, 0, 92487, + 42153, 121042, 0, 983843, 2032, 0, 0, 0, 0, 0, 0, 43085, 6057, 0, 0, 0, + 0, 0, 0, 0, 0, 638, 6083, 126976, 0, 0, 2305, 0, 0, 0, 6056, 10878, 0, 0, + 6085, 0, 0, 3915, 0, 0, 0, 0, 0, 0, 4028, 1787, 0, 43096, 0, 0, 1768, 0, + 0, 0, 128125, 0, 0, 583, 129137, 0, 0, 66004, 0, 0, 0, 0, 0, 55267, + 120810, 128995, 43075, 65049, 0, 74531, 0, 93009, 70694, 0, 0, 129375, + 9869, 128815, 1771, 0, 0, 0, 0, 0, 0, 119115, 113708, 0, 0, 74101, 0, 0, + 0, 0, 0, 0, 0, 0, 12539, 123631, 0, 0, 0, 73862, 69842, 9897, 0, 100561, + 0, 0, 0, 0, 0, 8931, 0, 1415, 8866, 74552, 0, 128312, 0, 983576, 43106, + 0, 71089, 1580, 92278, 68424, 0, 0, 7658, 3440, 78215, 1562, 0, 0, + 129031, 0, 0, 0, 0, 0, 0, 6028, 68900, 42892, 0, 111016, 0, 0, 0, 0, 0, + 128269, 0, 66776, 42946, 127276, 129124, 0, 0, 0, 11599, 0, 11602, 11591, + 11574, 11581, 11597, 11598, 6253, 11571, 11584, 70273, 11569, 0, 8906, 0, + 5755, 2636, 0, 10815, 11619, 129094, 0, 7815, 11616, 11617, 70064, 11618, + 11604, 7869, 11612, 0, 42152, 0, 0, 0, 92586, 126247, 0, 92173, 0, 0, + 6616, 0, 0, 120875, 391, 0, 0, 0, 42296, 11588, 0, 0, 0, 68397, 0, 0, + 42335, 983188, 0, 0, 7538, 94040, 0, 42491, 0, 0, 128088, 4576, 0, 0, + 43809, 4277, 0, 3563, 0, 42338, 368, 0, 0, 42412, 0, 78209, 0, 0, 43814, + 983616, 1849, 0, 9921, 42451, 4253, 0, 0, 0, 42404, 64657, 73919, 3618, + 78338, 0, 0, 0, 0, 0, 929, 6827, 42035, 0, 0, 0, 67847, 0, 0, 0, 0, 0, 0, + 0, 0, 4578, 64513, 0, 0, 0, 71049, 68090, 0, 43305, 0, 73462, 0, 0, + 42048, 10166, 0, 127095, 113810, 983127, 0, 983972, 0, 0, 42483, 0, 0, 0, + 42291, 0, 71047, 0, 6641, 525, 66404, 0, 8763, 125091, 0, 0, 0, 0, 0, + 42504, 42581, 74280, 6915, 42310, 0, 8559, 0, 983975, 125100, 0, 0, + 11666, 8679, 0, 1576, 42423, 0, 0, 73840, 983092, 11374, 0, 10889, + 129076, 0, 42462, 0, 77982, 0, 2718, 42424, 0, 0, 127166, 0, 1179, 0, 0, + 0, 363, 11015, 72229, 0, 43857, 0, 66692, 0, 0, 0, 11041, 0, 0, 0, 0, 0, + 125184, 0, 92520, 0, 9492, 66709, 9212, 12833, 0, 0, 1297, 0, 0, 0, 0, 0, + 0, 12924, 0, 0, 10090, 125249, 0, 42505, 0, 42507, 0, 42311, 92940, + 120919, 68401, 10759, 0, 0, 120924, 42351, 42919, 9398, 66292, 0, 9422, + 0, 0, 0, 0, 0, 129440, 92575, 1603, 0, 0, 0, 0, 0, 69703, 11250, 0, 0, + 10546, 0, 0, 11600, 0, 2797, 73821, 42427, 306, 714, 3058, 120154, 0, 0, + 0, 42395, 0, 11607, 0, 11198, 127512, 0, 72232, 129067, 0, 42433, 0, + 7603, 74063, 0, 42141, 0, 0, 0, 129085, 8244, 362, 125069, 0, 8037, 0, 0, + 0, 0, 41606, 66696, 77912, 0, 2093, 0, 0, 0, 41604, 0, 0, 0, 0, 10523, + 1446, 42320, 0, 0, 64773, 42472, 0, 0, 1722, 5581, 0, 64496, 0, 0, 64914, + 0, 42620, 128603, 124988, 0, 0, 10549, 0, 71190, 0, 0, 0, 0, 0, 71712, 0, + 0, 0, 0, 0, 0, 0, 7684, 66338, 0, 1174, 0, 0, 983621, 0, 0, 0, 42277, 0, + 42456, 65667, 0, 0, 0, 0, 42417, 0, 0, 120812, 42304, 0, 0, 0, 74443, + 127894, 0, 8313, 0, 0, 1316, 66690, 0, 0, 0, 0, 0, 0, 66844, 983696, 0, + 0, 0, 65200, 3383, 0, 0, 70063, 0, 0, 0, 42420, 119185, 0, 0, 983898, 0, + 121079, 0, 0, 42343, 124980, 42706, 1751, 42496, 65742, 13166, 0, 0, 0, + 0, 0, 42683, 12697, 0, 0, 0, 125047, 0, 42346, 0, 0, 3757, 0, 0, 121075, + 65869, 0, 9247, 74976, 3193, 0, 0, 42459, 7596, 7921, 0, 74095, 0, 42499, + 11590, 66006, 0, 42307, 0, 43953, 0, 0, 1023, 474, 0, 0, 0, 0, 42487, 0, + 0, 0, 42295, 0, 121474, 72237, 0, 9835, 0, 127782, 0, 12275, 0, 0, 8595, + 0, 0, 0, 0, 0, 10118, 0, 129156, 0, 0, 0, 0, 0, 0, 699, 0, 120923, 11601, + 0, 92941, 0, 7581, 0, 92530, 0, 0, 0, 7765, 65583, 0, 0, 64597, 43444, 0, + 92197, 0, 64279, 7036, 5823, 1937, 0, 917854, 65415, 13308, 65417, 0, + 65217, 0, 0, 11017, 0, 0, 7294, 0, 0, 0, 0, 42466, 65416, 68858, 0, + 71350, 65413, 92381, 126498, 12964, 42240, 1941, 0, 0, 1713, 0, 0, 0, + 11407, 42441, 128262, 6297, 0, 0, 0, 42481, 0, 0, 7179, 42289, 0, 120921, + 969, 0, 0, 0, 6165, 0, 0, 0, 0, 42402, 0, 0, 0, 129511, 0, 72234, 0, 0, + 64876, 92635, 6046, 0, 6208, 128870, 129309, 73749, 0, 0, 42422, 0, 0, + 128155, 73775, 338, 0, 121369, 0, 42328, 10767, 0, 8115, 0, 0, 0, 0, + 92687, 0, 0, 0, 0, 73029, 0, 0, 0, 71687, 4486, 128082, 0, 0, 10925, 0, + 0, 0, 0, 42309, 10257, 0, 10273, 7668, 10305, 42461, 74882, 42349, 8832, + 0, 0, 10644, 0, 129531, 42278, 0, 0, 69874, 0, 0, 42429, 0, 42316, 11223, + 0, 0, 42468, 0, 0, 0, 65402, 0, 0, 72235, 0, 0, 41963, 120990, 0, 0, + 125013, 6823, 42391, 1588, 65400, 0, 0, 0, 65398, 787, 0, 0, 0, 0, 2078, + 127239, 65399, 0, 0, 0, 65401, 0, 121196, 0, 0, 644, 0, 71335, 0, 3659, + 0, 0, 0, 13107, 92669, 0, 10502, 74457, 0, 11221, 41554, 0, 0, 0, 41557, + 11209, 0, 11070, 119221, 0, 0, 73858, 41555, 9514, 0, 66771, 64641, + 92447, 0, 7520, 73888, 77955, 0, 0, 0, 0, 0, 64527, 0, 0, 12723, 0, + 68776, 0, 0, 0, 78835, 4055, 78826, 77960, 65212, 0, 127353, 12319, 0, 0, + 983216, 7964, 65427, 0, 65424, 72217, 120966, 0, 65425, 74890, 128251, 0, + 0, 0, 3448, 10827, 0, 9866, 74527, 0, 0, 8625, 69783, 92304, 10477, 0, 0, + 0, 65423, 0, 0, 0, 0, 6152, 0, 0, 6629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11046, 11490, 0, 4485, 71126, 0, 0, 0, 0, 0, 5869, 0, 119633, 0, 7040, + 3588, 0, 12825, 0, 0, 128569, 0, 0, 0, 0, 0, 0, 0, 0, 128449, 64499, + 65245, 127367, 1171, 127368, 69717, 127365, 1805, 8772, 0, 127363, 9930, + 65247, 0, 0, 2338, 127362, 92695, 0, 0, 0, 69219, 0, 120104, 0, 120103, + 72221, 120106, 0, 118814, 8734, 4212, 0, 0, 66701, 0, 65862, 0, 120095, + 42903, 0, 0, 0, 126117, 426, 0, 120098, 8251, 0, 65436, 0, 2120, 43302, + 1224, 0, 65576, 0, 66876, 1764, 6074, 0, 12858, 0, 0, 65439, 6378, 74566, + 0, 41960, 0, 41644, 0, 2129, 0, 9222, 0, 0, 4259, 9092, 0, 41961, 0, 0, + 66357, 42331, 64935, 0, 0, 1293, 0, 2132, 0, 983589, 0, 2454, 0, 3613, + 128837, 71117, 0, 0, 69681, 10978, 10840, 0, 10668, 0, 127197, 9118, + 120164, 0, 0, 0, 1157, 64903, 8638, 0, 0, 0, 0, 0, 0, 0, 128981, 10086, + 0, 11128, 0, 0, 65430, 74013, 6079, 0, 10764, 127910, 64435, 128051, + 1339, 0, 65428, 1317, 8822, 0, 0, 0, 127143, 0, 0, 0, 43110, 0, 10428, 0, + 0, 0, 5742, 43076, 4692, 0, 0, 4007, 5004, 128781, 0, 751, 6595, 6596, 0, + 66373, 0, 0, 64908, 0, 6593, 72349, 12004, 119192, 74097, 43108, 0, 0, + 119333, 92188, 6598, 0, 6599, 0, 93031, 74194, 0, 121483, 66674, 6597, 0, + 73921, 0, 64745, 2281, 0, 0, 128996, 43790, 0, 2430, 41678, 0, 0, 43785, + 113716, 0, 121263, 0, 0, 1921, 0, 19927, 70390, 65406, 0, 43786, 4284, + 128346, 72210, 43789, 12841, 9229, 0, 42285, 0, 0, 0, 0, 3521, 0, 120888, + 8325, 0, 65403, 0, 1854, 0, 0, 0, 0, 0, 0, 0, 0, 4344, 0, 65433, 6076, 0, + 0, 74764, 12074, 0, 0, 0, 0, 12934, 119555, 65432, 128877, 0, 6071, + 65434, 0, 65435, 4053, 128623, 0, 0, 0, 0, 69823, 127463, 0, 121403, + 127473, 8421, 127472, 0, 43705, 502, 0, 65431, 0, 0, 0, 1303, 316, 7364, + 0, 2136, 0, 120796, 64365, 43480, 92639, 4860, 0, 127877, 0, 0, 9583, 0, + 5546, 0, 0, 0, 0, 0, 5544, 127475, 0, 70352, 5543, 128917, 72821, 12137, + 5548, 0, 0, 10007, 0, 127523, 6077, 0, 65452, 0, 119341, 11214, 65952, 0, + 72226, 0, 0, 1319, 74210, 65410, 67399, 92606, 0, 0, 119343, 0, 66716, + 83513, 4691, 128619, 9345, 621, 0, 0, 122889, 65411, 0, 74575, 121246, + 65408, 73899, 0, 9474, 2812, 119118, 65412, 3786, 65409, 8894, 83246, + 119611, 7923, 3716, 0, 0, 0, 0, 7012, 0, 128439, 9566, 0, 94176, 0, + 65012, 126242, 545, 9575, 0, 10050, 12718, 0, 8859, 6820, 0, 983979, + 120740, 0, 0, 9119, 2787, 0, 983981, 8507, 2012, 7985, 0, 0, 0, 0, + 194634, 0, 410, 0, 0, 120789, 120609, 0, 120378, 120379, 0, 0, 120374, + 72742, 120376, 120377, 120370, 120371, 120372, 120373, 3860, 120367, + 72205, 74031, 111131, 73685, 11748, 120365, 7941, 111134, 8749, 111132, + 12698, 111129, 361, 110793, 845, 0, 0, 0, 4562, 72241, 2926, 0, 4569, 0, + 110797, 43487, 0, 0, 0, 74287, 122885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6291, + 0, 0, 0, 9734, 0, 0, 0, 0, 127754, 7359, 83523, 43863, 0, 111150, 8769, + 111148, 111147, 111145, 4859, 111143, 111142, 0, 0, 0, 0, 12172, 111136, + 0, 127899, 111141, 64764, 4210, 111138, 0, 804, 0, 83520, 0, 70344, 0, 0, + 67202, 10091, 67200, 119257, 67206, 67205, 67204, 67203, 72302, 0, 0, 0, + 128959, 0, 1425, 92259, 119229, 11049, 0, 71480, 42649, 8482, 0, 0, + 66715, 67209, 11940, 67207, 664, 0, 0, 0, 70200, 127525, 0, 70194, 93061, + 111155, 68474, 111153, 6032, 67218, 67217, 7430, 194670, 70191, 0, 0, 0, + 0, 0, 41161, 0, 9765, 10993, 41162, 0, 70189, 1169, 111181, 0, 1905, + 6034, 41164, 64744, 43236, 0, 128800, 73110, 0, 0, 788, 0, 0, 111167, + 111128, 1663, 128976, 42901, 127237, 67211, 67210, 0, 0, 67215, 67214, + 67213, 67212, 111160, 111159, 111158, 111157, 0, 0, 0, 111161, 43612, 0, + 0, 0, 10855, 67223, 9355, 67221, 65198, 120355, 0, 221, 0, 0, 0, 121141, + 7191, 118930, 72208, 125212, 0, 0, 0, 0, 67228, 67227, 43333, 67225, 0, + 0, 0, 67229, 0, 7245, 0, 74405, 69922, 72219, 111178, 3873, 8367, 111174, + 111173, 111172, 43649, 0, 111177, 111176, 0, 11164, 0, 74403, 111171, + 111170, 111169, 7682, 74404, 1462, 10235, 0, 0, 0, 0, 0, 111130, 0, 0, + 74402, 0, 92299, 0, 0, 74052, 0, 126127, 120549, 0, 64295, 0, 0, 0, 0, 0, + 120662, 0, 0, 67231, 67230, 10755, 55257, 11155, 128568, 983136, 9470, 0, + 127540, 0, 69680, 64384, 0, 128607, 0, 0, 0, 0, 73764, 8204, 0, 0, 0, 0, + 0, 8728, 0, 10904, 73446, 19936, 7833, 0, 0, 0, 0, 92546, 0, 0, 0, 8537, + 0, 0, 0, 121244, 0, 0, 0, 128193, 0, 0, 0, 0, 3062, 0, 0, 0, 0, 0, 41160, + 41147, 41158, 0, 120777, 0, 41155, 111116, 111115, 111114, 0, 121332, + 111119, 111118, 111117, 0, 0, 129091, 0, 0, 0, 64594, 2456, 66867, 0, 0, + 0, 0, 3721, 0, 0, 1230, 2678, 0, 3597, 917795, 0, 0, 92215, 0, 67737, + 8352, 0, 0, 0, 64515, 121378, 0, 129128, 67846, 0, 0, 92466, 0, 0, 71338, + 0, 8660, 0, 0, 0, 0, 0, 4483, 0, 0, 0, 6080, 0, 0, 1746, 1315, 0, 70201, + 0, 13140, 74508, 0, 0, 4480, 0, 111113, 111112, 0, 67979, 0, 6360, 10897, + 111106, 605, 68302, 110737, 69875, 110735, 110736, 66681, 0, 0, 0, 0, 0, + 0, 0, 10877, 118868, 64885, 0, 0, 0, 0, 0, 0, 345, 0, 0, 64606, 9917, 0, + 0, 92196, 0, 1776, 8422, 43992, 0, 0, 0, 126543, 43328, 0, 0, 1295, 0, + 42869, 0, 0, 0, 0, 128772, 65123, 125210, 11293, 11288, 0, 0, 65666, 0, + 92369, 65420, 0, 0, 4252, 0, 0, 0, 706, 72800, 0, 0, 0, 65419, 92177, 0, + 8419, 65421, 0, 66702, 0, 12670, 0, 0, 0, 0, 72825, 65422, 83008, 0, 0, + 0, 0, 0, 0, 9736, 4184, 65418, 0, 0, 74035, 0, 0, 0, 0, 0, 0, 129447, 0, + 7962, 12211, 9837, 83505, 0, 0, 5719, 0, 0, 119068, 73777, 1857, 0, 9927, + 0, 983940, 0, 10037, 0, 73695, 78322, 78319, 7818, 0, 0, 127769, 0, 0, 0, + 65077, 0, 78325, 78326, 78323, 43327, 43989, 0, 65828, 0, 0, 83499, 0, + 68390, 0, 110687, 78336, 78339, 9543, 78335, 78332, 78333, 0, 127964, 0, + 129552, 983895, 0, 69448, 0, 71429, 0, 0, 0, 11914, 69431, 0, 0, 0, 9949, + 0, 0, 119215, 0, 12073, 0, 0, 0, 0, 0, 2260, 0, 0, 0, 0, 0, 0, 1939, 0, + 0, 0, 69903, 0, 0, 0, 0, 6643, 92477, 0, 0, 78330, 78331, 78328, 78329, + 0, 92551, 0, 0, 0, 0, 0, 72417, 0, 0, 0, 0, 78341, 78342, 120944, 78340, + 129513, 127529, 92350, 3784, 78350, 0, 78348, 78349, 78345, 43324, 78343, + 78344, 2231, 0, 0, 0, 42467, 0, 0, 42894, 78363, 13281, 78360, 78361, + 78356, 78358, 78353, 64899, 0, 41149, 0, 43162, 68096, 41150, 0, 10571, + 67162, 67161, 67160, 67159, 6947, 41152, 887, 9249, 6565, 64806, 74366, + 0, 67158, 67157, 0, 10831, 67175, 67174, 120232, 65827, 43325, 67178, + 10168, 67176, 0, 0, 9190, 128497, 9666, 41997, 0, 0, 0, 0, 0, 0, 129411, + 0, 78508, 0, 78351, 78352, 0, 0, 72839, 983730, 0, 126604, 0, 0, 0, + 983417, 0, 2270, 0, 0, 0, 78365, 0, 67189, 72818, 0, 0, 0, 0, 0, 0, 0, + 72833, 0, 78366, 78367, 0, 0, 0, 0, 10137, 6121, 10995, 0, 71050, 8119, + 0, 71052, 0, 0, 0, 0, 0, 0, 0, 1394, 0, 0, 128960, 0, 67184, 2998, 67182, + 67181, 67188, 67187, 67186, 67185, 0, 0, 0, 0, 67180, 42003, 0, 0, 67193, + 67192, 67191, 67190, 67197, 67196, 67195, 67194, 0, 72770, 43315, 71051, + 0, 1593, 0, 125120, 619, 4635, 0, 72875, 0, 128859, 0, 0, 0, 0, 67199, + 67198, 0, 42790, 42006, 0, 0, 0, 128998, 10757, 9347, 127767, 0, 0, + 74227, 78904, 0, 74116, 128423, 121073, 120860, 0, 92427, 0, 0, 0, 0, + 64590, 0, 4371, 0, 0, 92478, 0, 0, 73977, 0, 0, 127847, 0, 120862, 0, + 64550, 73745, 70451, 0, 121013, 0, 0, 0, 129286, 0, 0, 0, 0, 9131, 0, + 125214, 0, 0, 0, 64260, 0, 12606, 0, 0, 0, 0, 562, 0, 0, 129648, 66455, + 127533, 3219, 0, 0, 0, 1037, 0, 64491, 0, 983676, 78572, 78580, 4568, + 549, 0, 0, 0, 0, 0, 128095, 70851, 0, 0, 0, 0, 0, 0, 0, 10825, 8079, + 118962, 0, 0, 0, 128855, 0, 13071, 0, 0, 41049, 42840, 43614, 129341, + 74881, 74596, 127191, 5212, 0, 66402, 119191, 0, 9747, 0, 0, 0, 983989, + 41047, 1668, 0, 0, 0, 1187, 0, 74416, 0, 0, 0, 0, 3240, 128518, 9213, 0, + 0, 0, 127174, 69822, 0, 0, 0, 0, 1623, 0, 0, 0, 0, 0, 0, 11272, 0, 73914, + 65048, 1909, 42172, 0, 0, 10736, 11580, 72228, 7615, 0, 0, 4237, 66576, + 0, 65815, 68083, 0, 0, 0, 3489, 0, 0, 0, 0, 0, 0, 127146, 3796, 6800, 0, + 65582, 0, 129521, 0, 0, 68036, 0, 0, 64857, 121213, 126493, 0, 66308, 0, + 0, 64634, 127817, 0, 0, 0, 0, 3246, 0, 43972, 128643, 0, 0, 0, 0, 120751, + 0, 0, 0, 0, 1496, 42827, 0, 942, 2378, 119213, 0, 0, 0, 0, 9510, 1232, + 8139, 0, 0, 0, 11409, 0, 6382, 0, 66319, 121237, 0, 0, 0, 127887, 2374, + 0, 8475, 120844, 66313, 0, 0, 64879, 119298, 0, 0, 70869, 0, 0, 129025, + 0, 7705, 11942, 0, 0, 3309, 0, 0, 0, 83345, 983847, 0, 0, 1280, 6998, + 128104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74239, 983073, 0, 0, 0, 6078, + 121354, 0, 1475, 0, 9938, 6084, 0, 983976, 0, 0, 0, 3256, 0, 43973, 0, 0, + 0, 8727, 0, 0, 0, 110831, 110832, 10562, 110830, 0, 0, 0, 3248, 0, 0, + 9015, 0, 0, 3635, 64337, 0, 0, 43852, 7195, 0, 2007, 64431, 0, 0, 0, 0, + 0, 0, 0, 65613, 77909, 0, 0, 0, 0, 119218, 7984, 11670, 74434, 127770, + 4176, 0, 2034, 69442, 11154, 65891, 0, 0, 318, 2038, 0, 0, 0, 3649, + 13149, 42145, 42798, 3634, 0, 0, 128483, 0, 0, 0, 11402, 120954, 94032, + 74238, 0, 43313, 0, 0, 7938, 0, 1761, 0, 65379, 68386, 128185, 1159, + 71183, 0, 0, 0, 66687, 120851, 0, 41680, 0, 0, 0, 1514, 11668, 67891, + 9313, 0, 128490, 67877, 0, 41681, 0, 0, 12848, 69982, 67873, 0, 74278, 0, + 0, 12649, 0, 0, 1194, 3242, 9761, 9555, 8598, 0, 120524, 0, 1551, 65447, + 129414, 126211, 0, 0, 0, 67875, 0, 3495, 66648, 125079, 0, 73024, 983228, + 0, 0, 10641, 0, 0, 0, 77845, 0, 0, 0, 0, 0, 11131, 0, 0, 0, 0, 0, 42685, + 92354, 193, 0, 0, 0, 42667, 0, 0, 92318, 119661, 0, 1362, 9558, 0, 0, 0, + 7351, 73789, 0, 0, 4426, 0, 0, 0, 0, 7276, 42163, 5220, 0, 0, 67822, 0, + 0, 0, 0, 41692, 0, 72283, 0, 0, 3223, 65492, 0, 0, 4549, 983687, 0, 0, 0, + 10807, 0, 0, 0, 42182, 8688, 12866, 0, 3294, 0, 0, 128101, 0, 64514, 0, + 43329, 0, 0, 0, 0, 119061, 0, 43422, 0, 0, 128618, 0, 42729, 0, 3215, + 120982, 68880, 917564, 0, 0, 0, 65682, 0, 0, 65924, 0, 983804, 0, 1501, + 0, 118807, 0, 0, 9607, 0, 65794, 72243, 983046, 10989, 0, 74399, 0, 0, + 7152, 0, 0, 129530, 7483, 125083, 0, 8104, 70128, 7474, 0, 72233, 0, 0, + 0, 8141, 0, 42537, 69612, 0, 0, 0, 0, 0, 127307, 42934, 0, 0, 0, 0, 0, 0, + 64517, 0, 0, 1650, 0, 0, 128502, 7901, 3238, 0, 65556, 0, 0, 65158, + 43416, 74959, 0, 7527, 0, 43319, 0, 0, 45, 0, 0, 0, 0, 0, 7347, 0, 0, 0, + 13129, 0, 9084, 0, 8737, 0, 0, 0, 66808, 9639, 7912, 2620, 0, 3564, 0, 0, + 0, 0, 75049, 0, 2853, 0, 0, 0, 0, 0, 2850, 8084, 0, 0, 71446, 92284, + 43122, 0, 0, 0, 0, 72214, 0, 74767, 0, 7331, 110646, 0, 8245, 0, 3158, + 92396, 3983, 0, 923, 0, 69397, 292, 0, 126548, 0, 3221, 1763, 0, 0, 0, 0, + 7253, 0, 68391, 75002, 0, 3637, 12996, 0, 70461, 0, 0, 3228, 0, 0, 0, 0, + 0, 0, 120833, 118939, 0, 7696, 0, 0, 0, 0, 43316, 4177, 0, 9089, 0, + 128805, 72116, 64500, 68133, 0, 0, 1856, 100572, 0, 6379, 0, 0, 0, 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, + 0, 0, 983251, 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, 983281, 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, + 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, + 0, 119563, 0, 0, 0, 126638, 0, 0, 43322, 0, 0, 0, 0, 92698, 3226, 67695, + 0, 0, 983939, 10200, 0, 128779, 127821, 0, 65610, 0, 0, 0, 3585, 250, + 129598, 43320, 0, 0, 0, 0, 1152, 0, 1688, 0, 0, 0, 0, 0, 121040, 128340, + 0, 0, 0, 2107, 0, 129048, 0, 0, 0, 43868, 0, 0, 0, 128239, 0, 0, 127777, + 0, 6927, 42267, 42261, 11464, 3365, 0, 0, 0, 0, 0, 41869, 0, 0, 0, 43326, + 0, 11519, 0, 5530, 5210, 0, 983970, 0, 5208, 0, 128842, 0, 2424, 7976, 0, + 0, 3244, 5529, 0, 73894, 128852, 5432, 0, 5527, 0, 78484, 0, 5528, 0, 0, + 120281, 0, 0, 43545, 120282, 0, 0, 73686, 42565, 0, 0, 3206, 120278, 0, + 0, 0, 0, 0, 211, 3216, 83407, 0, 120998, 3220, 68750, 0, 0, 8951, 5214, + 0, 8118, 0, 10768, 8735, 0, 5852, 124952, 0, 0, 0, 0, 0, 2623, 0, 0, 0, + 127388, 4698, 66509, 0, 0, 4701, 0, 120289, 74225, 120284, 8267, 0, 1421, + 66426, 0, 0, 2625, 92724, 0, 74309, 0, 0, 0, 7850, 120296, 69639, 127032, + 0, 0, 43384, 12660, 110663, 0, 0, 110706, 110661, 0, 92380, 0, 0, 69649, + 0, 713, 41073, 0, 3990, 0, 0, 0, 5017, 128313, 120352, 0, 0, 1030, 0, + 983120, 9513, 0, 0, 0, 4668, 0, 120350, 0, 6339, 0, 0, 0, 64650, 0, 0, + 74766, 983850, 8908, 0, 0, 0, 0, 10752, 13003, 68769, 0, 41307, 8732, + 120336, 0, 41310, 0, 4696, 0, 983934, 0, 120334, 3641, 5419, 0, 0, 0, 0, + 120344, 128129, 0, 7320, 65230, 11808, 0, 93970, 936, 13289, 0, 69892, + 65774, 0, 65243, 0, 19953, 0, 126469, 121375, 127256, 12913, 70722, + 68759, 0, 0, 70203, 0, 4113, 0, 2372, 1819, 0, 128053, 12152, 0, 682, + 7655, 120330, 0, 0, 10593, 1703, 0, 0, 8033, 69953, 0, 9810, 0, 0, + 127949, 0, 119159, 10109, 0, 73898, 0, 71730, 126704, 0, 0, 917620, 1965, + 917621, 0, 0, 73887, 0, 0, 0, 6314, 0, 8501, 0, 0, 0, 41317, 0, 5417, + 983586, 0, 0, 9353, 68148, 41315, 0, 11161, 0, 41314, 194892, 0, 126562, + 119236, 634, 0, 0, 0, 69779, 4355, 12016, 0, 9654, 12856, 6924, 7660, 0, + 0, 0, 0, 0, 42692, 0, 74604, 0, 0, 0, 680, 6274, 0, 1181, 0, 3174, 67248, + 0, 0, 0, 0, 113776, 10650, 917603, 92295, 70672, 118965, 0, 64644, + 126981, 0, 0, 0, 0, 983942, 0, 65302, 40989, 68239, 68230, 68234, 0, 0, + 124989, 0, 40987, 4667, 0, 983944, 8828, 0, 0, 0, 4746, 0, 0, 2269, 4749, + 0, 100598, 65192, 4744, 7345, 0, 242, 100595, 0, 8217, 0, 68919, 0, 0, 0, + 0, 66790, 10850, 0, 0, 0, 0, 0, 0, 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, + 74468, 65160, 0, 0, 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, 55275, 0, + 11728, 65894, 0, 0, 0, 68741, 0, 0, 0, 43489, 4282, 983845, 0, 83497, + 70328, 128103, 70324, 0, 0, 127509, 0, 8456, 0, 0, 0, 0, 78250, 0, 70320, + 120722, 9792, 0, 70326, 0, 0, 83500, 70322, 10019, 71701, 123617, 6568, + 4365, 0, 0, 3647, 0, 41134, 128341, 0, 125043, 41135, 0, 0, 0, 0, 0, + 123616, 0, 41137, 41139, 0, 6545, 0, 125139, 7597, 10528, 75054, 0, 3732, + 73910, 0, 0, 0, 7312, 983639, 9062, 93840, 11853, 0, 0, 128324, 41538, 0, + 0, 0, 0, 194706, 41531, 1263, 3720, 0, 68028, 0, 41524, 64692, 119635, 0, + 41534, 0, 92193, 0, 41168, 0, 67398, 127347, 3524, 0, 8831, 127349, + 127357, 0, 127360, 127352, 0, 0, 0, 0, 0, 0, 5845, 0, 0, 0, 71909, 8200, + 0, 68460, 0, 43283, 5551, 0, 0, 0, 6340, 983552, 100602, 0, 0, 0, 0, 0, + 5422, 0, 0, 0, 2471, 0, 0, 2749, 0, 73774, 10913, 72122, 0, 8666, 675, + 74093, 0, 194986, 0, 0, 0, 0, 0, 10928, 0, 41153, 0, 0, 0, 3738, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42347, 12092, 9615, 7234, 74047, 0, 0, 0, + 123639, 0, 0, 2934, 0, 0, 0, 0, 74507, 0, 74461, 0, 0, 74290, 0, 64562, + 0, 64473, 0, 0, 73728, 0, 11212, 0, 12128, 6534, 0, 0, 1901, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 69940, 65459, 68293, 92290, 128808, 3770, 0, 0, 0, + 64579, 128511, 0, 0, 983332, 983340, 0, 0, 0, 5941, 0, 0, 65079, 0, 0, 0, + 73961, 983334, 0, 0, 0, 0, 0, 0, 10638, 0, 0, 0, 71486, 0, 0, 983349, 0, + 43840, 129495, 0, 5233, 983346, 64792, 71233, 0, 983324, 0, 0, 9847, 0, + 1685, 595, 0, 73971, 1292, 8940, 0, 11088, 0, 10004, 0, 0, 6541, 0, 0, 0, + 5603, 9014, 5606, 0, 538, 128705, 5602, 8467, 74391, 6547, 0, 0, 0, 0, + 8458, 129534, 8495, 0, 0, 917552, 10981, 78314, 0, 2465, 0, 0, 0, 9730, + 9280, 0, 0, 74155, 72766, 113690, 0, 504, 0, 120715, 0, 983606, 0, 0, 0, + 123141, 125024, 0, 0, 732, 3737, 0, 1548, 0, 0, 1832, 5604, 0, 41141, 0, + 5607, 72854, 41142, 3745, 0, 0, 128137, 0, 0, 3869, 11937, 5725, 0, + 66566, 7416, 5728, 0, 0, 0, 11918, 66567, 5724, 118829, 5727, 0, 0, 0, + 5723, 0, 128116, 0, 0, 0, 0, 42532, 0, 12303, 0, 11423, 0, 983115, 68303, + 74074, 0, 128267, 6559, 64557, 71348, 0, 66763, 43019, 0, 10238, 0, 0, + 43377, 0, 71346, 124937, 9783, 42704, 0, 71719, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 41144, 129465, 0, 0, 0, 72793, 92176, 0, 70682, 0, 8820, 0, 0, + 0, 11515, 526, 0, 0, 0, 0, 0, 0, 8635, 0, 0, 8288, 11815, 0, 0, 0, 1543, + 3713, 0, 0, 0, 68041, 127816, 0, 0, 64357, 0, 42082, 0, 0, 8987, 42081, + 0, 0, 0, 0, 0, 0, 6553, 0, 0, 11253, 0, 0, 5475, 0, 0, 0, 119334, 12990, + 1160, 42084, 0, 123152, 0, 0, 360, 0, 0, 128274, 5863, 3137, 0, 983315, + 0, 0, 10959, 3146, 0, 127374, 0, 68341, 13076, 3135, 983298, 0, 0, 3142, + 0, 94068, 10819, 128479, 0, 74635, 12877, 119867, 73967, 0, 70808, 0, 0, + 0, 0, 6163, 0, 113728, 0, 0, 0, 8603, 0, 0, 3306, 0, 43392, 0, 0, 5751, + 0, 0, 0, 0, 0, 7403, 0, 118933, 0, 0, 64783, 92658, 0, 0, 129592, 0, 0, + 65569, 7021, 0, 0, 0, 0, 0, 6540, 6974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43585, + 0, 6551, 983974, 0, 0, 0, 0, 0, 72216, 8977, 602, 120814, 0, 0, 0, 72119, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983624, 74812, 0, 0, 0, 9475, 0, 65105, 0, + 983219, 0, 43592, 7831, 66751, 0, 0, 73915, 0, 43593, 0, 43591, 43061, 0, + 0, 43589, 43584, 0, 13113, 0, 0, 43590, 8766, 9087, 0, 0, 41574, 78337, + 0, 42900, 6376, 0, 0, 0, 0, 9854, 0, 0, 0, 0, 0, 0, 0, 2909, 0, 0, 0, + 6529, 110930, 75004, 3751, 0, 0, 0, 1798, 0, 0, 1354, 0, 13152, 6557, + 12430, 0, 94098, 0, 0, 0, 68123, 128097, 0, 0, 0, 71264, 0, 11082, 0, + 65677, 8682, 42054, 92595, 42045, 9804, 0, 0, 3595, 0, 0, 0, 0, 42399, 0, + 0, 0, 65541, 0, 7324, 0, 0, 0, 8797, 77895, 0, 64888, 7167, 2356, 95, 0, + 0, 0, 42286, 0, 0, 69999, 0, 120877, 0, 0, 42324, 129359, 0, 0, 43492, 0, + 43406, 0, 0, 0, 0, 0, 43400, 0, 0, 71720, 0, 66435, 0, 0, 3201, 514, + 74502, 0, 43396, 0, 64493, 0, 43404, 11218, 0, 0, 43398, 0, 0, 41341, + 129485, 6564, 1463, 41342, 0, 5293, 0, 0, 3733, 0, 0, 41344, 0, 0, 0, 0, + 41346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983745, 0, 0, 0, 65272, 0, 0, 1270, + 1132, 0, 0, 0, 66655, 0, 0, 74314, 64761, 0, 110853, 8510, 0, 129600, 0, + 0, 0, 0, 0, 0, 69692, 0, 0, 42383, 69690, 0, 69700, 13141, 0, 92465, 0, + 0, 0, 41566, 0, 0, 129334, 127171, 0, 0, 0, 0, 0, 0, 0, 6308, 0, 0, 2611, + 0, 66881, 0, 65063, 0, 0, 0, 0, 4484, 8747, 110597, 128369, 0, 0, 0, 0, + 0, 0, 12902, 0, 0, 7299, 0, 0, 12107, 7100, 10905, 65010, 0, 125135, + 66018, 9284, 0, 0, 0, 0, 0, 0, 0, 12010, 0, 126093, 120949, 121032, 0, 0, + 0, 0, 0, 0, 0, 0, 6618, 3562, 66365, 0, 42234, 12648, 128039, 0, 0, 0, + 41309, 9764, 41316, 0, 0, 13230, 41299, 0, 0, 68365, 0, 0, 0, 0, 0, 0, + 4153, 0, 0, 128047, 0, 0, 42889, 0, 129322, 41578, 0, 41577, 0, 68092, 0, + 6533, 0, 41570, 0, 72414, 0, 41580, 74628, 0, 12901, 0, 0, 0, 0, 71461, + 41360, 0, 0, 4743, 0, 0, 0, 0, 68398, 110781, 5890, 110779, 111103, 3739, + 8695, 92514, 0, 3964, 8984, 111095, 68288, 0, 0, 70000, 111090, 111089, + 111088, 3956, 82952, 111093, 6563, 111091, 41305, 0, 0, 12067, 41312, 0, + 0, 0, 0, 0, 8175, 0, 3600, 0, 934, 0, 0, 173, 0, 0, 110784, 110785, 1750, + 110783, 41358, 68368, 1807, 0, 92298, 0, 5889, 0, 0, 0, 67127, 0, 0, + 121395, 6982, 1721, 0, 7891, 0, 42160, 67129, 4512, 983771, 69460, 0, 0, + 0, 0, 0, 120716, 0, 0, 0, 0, 0, 119140, 3975, 72253, 74087, 0, 12672, 0, + 0, 0, 0, 0, 0, 121100, 0, 0, 41095, 3962, 68242, 2932, 41101, 3954, 6457, + 4513, 0, 0, 0, 0, 1468, 0, 0, 55237, 128230, 0, 127244, 55238, 41080, 0, + 0, 4320, 74104, 0, 0, 0, 0, 77918, 0, 128384, 8256, 0, 72413, 0, 8879, 0, + 0, 8770, 0, 0, 92214, 0, 0, 128786, 4283, 0, 0, 68361, 0, 74826, 0, 0, 0, + 0, 127954, 65106, 42761, 121516, 4581, 8411, 0, 0, 72259, 0, 93037, 0, 0, + 0, 92452, 4392, 0, 10786, 69661, 0, 8184, 0, 0, 7396, 0, 0, 69788, 0, + 43512, 7965, 111039, 111038, 111037, 111036, 41350, 0, 0, 0, 2294, 64501, + 68034, 0, 68405, 111034, 0, 0, 111030, 111029, 71105, 111027, 0, 111033, + 92200, 111031, 0, 6764, 0, 0, 111026, 111025, 111024, 65203, 128010, 0, + 0, 0, 3210, 0, 0, 0, 0, 82958, 127970, 82957, 0, 68875, 10043, 82963, + 1186, 41571, 0, 5209, 9464, 82960, 66657, 5207, 65062, 5213, 0, 0, 41348, + 41568, 128803, 3253, 111045, 111044, 74067, 111042, 111049, 5596, 111047, + 111046, 0, 64887, 0, 5217, 111041, 72252, 0, 0, 0, 0, 2635, 92760, 0, 0, + 0, 92742, 0, 113672, 0, 0, 0, 64558, 0, 0, 67083, 0, 0, 0, 5784, 0, 0, 0, + 0, 4011, 0, 0, 0, 0, 4254, 0, 111054, 5600, 111052, 111051, 10447, 5598, + 1207, 111055, 0, 3501, 42582, 0, 111050, 0, 1124, 5597, 983496, 983497, + 9321, 129464, 75040, 983493, 0, 1719, 68356, 68354, 9671, 1125, 2721, 0, + 983498, 983499, 7631, 5488, 111082, 0, 0, 5491, 111086, 8937, 0, 3236, + 74187, 5490, 0, 5489, 8522, 68358, 111069, 6300, 111067, 111066, 0, 0, + 111071, 111070, 0, 9875, 7593, 111065, 0, 0, 43182, 0, 68379, 3311, + 111058, 111057, 3746, 11016, 65752, 111061, 0, 43423, 68775, 0, 111056, + 72225, 0, 0, 127120, 0, 2232, 0, 0, 0, 0, 0, 126555, 0, 0, 8656, 0, + 128358, 0, 0, 983485, 983486, 917563, 983484, 983481, 983482, 0, 0, 0, 0, + 0, 111183, 128043, 983490, 1036, 983488, 111075, 1723, 111073, 111072, + 111079, 41579, 111077, 111076, 10705, 0, 983480, 74486, 71693, 740, + 983476, 983477, 129645, 0, 0, 74846, 92255, 0, 0, 0, 0, 0, 10438, 74487, + 73798, 13285, 0, 0, 0, 5690, 0, 93992, 0, 0, 13095, 0, 127857, 121419, + 7321, 121203, 13254, 70176, 75070, 0, 0, 0, 0, 127845, 3247, 317, 0, 0, + 0, 0, 917543, 0, 10173, 0, 0, 0, 0, 0, 5223, 0, 0, 119564, 5226, 0, + 94044, 5880, 94065, 7758, 0, 0, 5224, 5487, 94041, 5692, 41725, 983462, + 0, 5695, 41711, 0, 43171, 0, 94049, 5691, 983467, 866, 1488, 983466, + 983452, 65665, 94036, 983451, 74797, 0, 0, 11039, 983460, 11145, 71211, + 983459, 983456, 983457, 983454, 983455, 42492, 43402, 125208, 3302, 0, + 72842, 68809, 0, 0, 120885, 121300, 0, 7856, 8690, 0, 73076, 0, 0, 0, + 73091, 0, 69925, 120635, 65153, 0, 0, 0, 0, 0, 0, 4540, 0, 0, 0, 0, + 11844, 121209, 8863, 0, 75061, 0, 6389, 0, 42371, 83205, 8790, 120911, 0, + 111125, 71168, 8869, 0, 0, 42060, 0, 9648, 111123, 71170, 10270, 10286, + 10318, 10382, 43529, 0, 0, 0, 0, 0, 70110, 43835, 119520, 70111, 127086, + 118815, 127084, 127083, 8767, 0, 0, 41281, 0, 5201, 0, 6215, 67072, 6214, + 13101, 0, 0, 65268, 67073, 0, 0, 127976, 72995, 127073, 10511, 42075, 0, + 127071, 129509, 0, 67115, 127069, 111293, 127068, 0, 127067, 0, 74845, 0, + 42071, 43156, 0, 0, 0, 0, 7954, 0, 0, 0, 8485, 4671, 0, 0, 4740, 0, 0, + 42618, 78294, 3064, 6212, 0, 0, 0, 9554, 0, 83044, 0, 126598, 0, 78291, + 0, 6213, 12885, 0, 129086, 64720, 0, 983907, 0, 0, 0, 11430, 0, 7518, + 9317, 0, 3729, 10406, 0, 119259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73825, 0, 0, + 129599, 8786, 10390, 0, 0, 917601, 93034, 0, 7924, 0, 43307, 0, 0, 0, 0, + 0, 0, 118843, 9623, 435, 0, 0, 12893, 8093, 9079, 0, 0, 0, 0, 0, 64430, + 0, 10294, 10326, 0, 0, 0, 0, 0, 0, 3623, 125188, 83378, 0, 43197, 0, 0, + 0, 78296, 0, 0, 0, 7914, 0, 92170, 0, 2624, 0, 0, 0, 120859, 67110, + 11058, 0, 67107, 0, 0, 0, 0, 120793, 0, 0, 6717, 10619, 0, 0, 0, 11832, + 128664, 0, 0, 0, 70202, 0, 0, 0, 3232, 73824, 74581, 0, 0, 0, 41889, 0, + 0, 1161, 41895, 74103, 9701, 0, 0, 129385, 73819, 120588, 5012, 0, 41362, + 0, 68507, 0, 0, 0, 0, 0, 41364, 0, 0, 41352, 41361, 0, 41366, 0, 70129, + 129065, 917, 0, 119934, 119923, 92421, 119912, 0, 119924, 119916, 0, + 71482, 0, 0, 0, 0, 128583, 0, 7022, 0, 4739, 0, 5802, 9816, 8615, 0, 0, + 491, 65837, 0, 0, 128644, 0, 8426, 11092, 9891, 0, 0, 0, 41881, 118823, + 3736, 7394, 42648, 0, 68448, 9095, 7741, 12684, 41885, 0, 0, 0, 0, 5815, + 0, 0, 0, 127392, 0, 0, 41878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120804, 0, 0, + 2267, 0, 78289, 78359, 78288, 0, 0, 78318, 65920, 0, 0, 7057, 9408, 9409, + 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, + 5897, 9423, 917933, 127107, 0, 127108, 917937, 127963, 8955, 9399, 9400, + 9401, 9402, 9403, 9404, 9405, 9406, 9407, 0, 128626, 42669, 73832, 78261, + 67683, 2631, 0, 78259, 0, 78260, 3996, 0, 119307, 0, 0, 0, 0, 0, 0, + 64825, 917916, 917913, 917914, 917919, 5899, 917917, 917918, 12085, 0, + 574, 917922, 77825, 73828, 9473, 77824, 118918, 73900, 41735, 42211, 0, + 4190, 77834, 77835, 77830, 77833, 3616, 77828, 77837, 77838, 7708, 77836, + 2228, 113765, 0, 0, 4191, 0, 77844, 73800, 77842, 77843, 77839, 77840, 0, + 78311, 83375, 0, 0, 10415, 74102, 0, 5896, 0, 10351, 67151, 0, 73829, 0, + 127159, 0, 73998, 41355, 42883, 70736, 71212, 8021, 0, 119150, 983713, + 41357, 8011, 42885, 42887, 41354, 0, 0, 10026, 5472, 120554, 1191, + 121110, 5470, 128784, 5476, 0, 0, 0, 0, 42874, 78281, 42876, 6304, 78283, + 0, 2675, 120690, 0, 0, 128954, 0, 0, 5478, 5904, 0, 0, 0, 7291, 77848, + 43761, 13067, 0, 0, 126249, 120360, 69731, 77856, 77857, 77854, 77855, + 77852, 77853, 77850, 10750, 43714, 77858, 0, 0, 0, 12887, 120364, 127745, + 77866, 77867, 77864, 77865, 9929, 5199, 77859, 1120, 0, 0, 0, 9486, 7554, + 0, 77868, 72832, 0, 0, 5894, 70069, 0, 0, 92511, 70358, 1323, 13162, + 120937, 0, 0, 0, 77881, 66022, 0, 72857, 0, 0, 0, 0, 0, 1142, 0, 8271, 0, + 0, 126645, 12903, 43622, 4002, 0, 10442, 10676, 120368, 0, 120369, 0, 0, + 0, 0, 66642, 1277, 0, 7871, 0, 0, 78853, 0, 119015, 0, 0, 11784, 0, + 78012, 4700, 0, 78858, 0, 78855, 0, 0, 92400, 77879, 19932, 77876, 77877, + 74804, 77874, 77869, 77871, 0, 71487, 43118, 0, 0, 6774, 6773, 0, 194684, + 10346, 10410, 78860, 118974, 0, 110613, 6108, 0, 110612, 0, 0, 0, 121309, + 74166, 124973, 0, 0, 0, 69407, 0, 70357, 0, 0, 74217, 0, 64698, 4192, + 9289, 0, 0, 128847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11603, 0, 0, 0, 82976, 0, + 0, 67812, 0, 0, 0, 42572, 0, 128300, 119146, 1963, 11622, 0, 43237, + 82981, 7550, 67100, 5903, 82984, 78009, 0, 9662, 0, 128391, 0, 0, 0, 0, + 11013, 0, 0, 0, 128433, 67090, 0, 0, 0, 0, 0, 11568, 983685, 43367, 0, 0, + 7852, 0, 0, 0, 0, 0, 194676, 0, 194675, 0, 0, 416, 0, 0, 73834, 0, 68921, + 10984, 0, 0, 0, 0, 0, 0, 127013, 92423, 0, 983256, 121199, 0, 0, 12540, + 0, 0, 0, 0, 11445, 0, 2112, 0, 0, 0, 1021, 0, 9507, 10210, 78005, 8023, + 93963, 78006, 78001, 43181, 78003, 9532, 119094, 0, 0, 0, 0, 0, 1885, + 43268, 0, 0, 120542, 121153, 392, 7894, 4391, 0, 8221, 119597, 77999, + 77998, 0, 0, 0, 92967, 0, 3558, 0, 3913, 70429, 121376, 0, 0, 1265, 0, + 6309, 0, 12969, 0, 0, 0, 0, 0, 0, 0, 41864, 0, 0, 74294, 0, 167, 0, + 917584, 0, 93983, 72354, 68477, 0, 0, 917594, 0, 2493, 0, 0, 0, 0, + 917570, 0, 0, 0, 406, 917592, 0, 0, 0, 0, 0, 0, 0, 127161, 0, 128597, 0, + 0, 0, 3421, 10561, 0, 8365, 0, 0, 127569, 120787, 128669, 0, 0, 0, 0, + 7834, 0, 0, 917574, 10298, 6624, 4908, 0, 1639, 120842, 0, 0, 6327, 6724, + 0, 0, 0, 69910, 4817, 0, 0, 0, 68059, 0, 11022, 0, 0, 0, 118888, 0, 0, + 7548, 64794, 0, 12291, 983165, 0, 0, 0, 0, 0, 0, 1134, 1838, 0, 2057, 0, + 0, 0, 0, 0, 0, 5206, 0, 0, 42523, 0, 0, 0, 0, 65550, 8570, 4816, 0, + 127926, 0, 4821, 0, 0, 0, 4818, 125257, 119974, 119977, 0, 0, 119970, + 119973, 0, 119983, 119982, 119985, 119984, 119979, 119978, 0, 119980, + 119670, 129297, 0, 11284, 119987, 70097, 65155, 119988, 0, 9363, 0, 0, 0, + 5900, 93990, 7889, 2722, 128770, 0, 0, 0, 0, 2282, 0, 0, 0, 68093, 0, 0, + 0, 0, 0, 70150, 0, 0, 0, 0, 129651, 70146, 983079, 119967, 71330, 70148, + 0, 0, 94006, 70144, 119964, 110677, 110678, 110675, 110676, 0, 110674, + 4226, 0, 123165, 5732, 71327, 0, 0, 65119, 0, 0, 92971, 64770, 0, 0, + 6093, 0, 0, 1395, 0, 0, 0, 121179, 786, 0, 43174, 64340, 0, 125269, 0, + 983643, 125138, 10132, 0, 0, 0, 0, 0, 93956, 0, 68444, 0, 92437, 123143, + 0, 0, 92656, 0, 0, 0, 1399, 121463, 0, 121465, 121464, 120808, 241, + 121469, 4907, 0, 0, 0, 0, 0, 0, 0, 0, 127904, 0, 0, 42780, 0, 0, 0, 4217, + 0, 0, 0, 0, 72158, 0, 0, 43099, 3965, 0, 0, 0, 13300, 0, 0, 43057, 0, 0, + 0, 0, 0, 65372, 0, 6410, 126073, 125252, 70468, 0, 0, 0, 119558, 0, 0, 0, + 0, 0, 0, 43188, 2626, 7762, 0, 0, 0, 127183, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 67726, 0, 126993, 1542, 0, 0, 92550, 0, 0, 74311, 0, 0, 10181, 2150, + 0, 0, 0, 0, 0, 68053, 6029, 72852, 0, 0, 0, 0, 8993, 0, 0, 0, 93968, 606, + 0, 0, 0, 0, 4311, 0, 6027, 126615, 4322, 0, 65207, 0, 0, 983901, 0, 0, + 2735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70806, 0, 0, 0, 92783, 0, 0, + 65817, 55288, 127934, 66564, 8530, 0, 7709, 0, 121202, 66560, 128528, + 917595, 12876, 66561, 0, 121430, 983938, 7789, 5855, 809, 0, 0, 72853, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64386, 0, 74909, 0, 120607, 66416, 83360, + 6532, 0, 0, 0, 0, 128224, 0, 0, 0, 0, 43091, 92287, 0, 0, 129312, 0, 0, + 0, 11361, 0, 0, 8153, 128105, 0, 10741, 0, 0, 0, 0, 0, 64706, 0, 0, 0, + 78870, 9466, 78866, 9824, 0, 0, 0, 120977, 915, 0, 0, 43865, 0, 0, 0, + 67131, 70096, 67137, 0, 129614, 78864, 6730, 78862, 68161, 0, 78861, + 126542, 0, 0, 94010, 983683, 0, 0, 66043, 0, 0, 43107, 0, 0, 92343, 0, + 73879, 0, 0, 0, 6103, 0, 0, 92470, 0, 12889, 0, 127137, 0, 0, 0, 0, 0, 0, + 119262, 83028, 0, 0, 0, 0, 0, 0, 0, 13118, 7700, 917537, 9690, 0, 0, + 68080, 512, 0, 72792, 0, 0, 77892, 632, 77890, 77891, 42529, 0, 0, 0, 0, + 0, 0, 0, 128273, 0, 0, 7379, 64581, 5386, 0, 0, 10633, 72316, 64488, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 124956, 71307, 0, 0, 0, 0, 0, 92370, 0, 0, 0, 0, + 0, 71314, 1801, 0, 0, 120867, 0, 0, 77888, 2085, 702, 77887, 77884, + 77885, 13074, 77883, 66299, 0, 0, 12106, 0, 0, 1755, 0, 77897, 77898, + 1163, 3102, 77893, 77894, 0, 0, 0, 0, 69227, 0, 77901, 77902, 77899, + 77900, 65171, 0, 0, 0, 70157, 0, 0, 0, 0, 2908, 0, 11177, 64902, 64950, + 0, 128740, 66906, 124959, 70499, 0, 0, 0, 64352, 0, 125031, 1007, 0, + 9199, 0, 127371, 118992, 41890, 0, 2730, 119072, 0, 5428, 0, 73771, 0, 0, + 0, 0, 71458, 0, 0, 0, 68089, 0, 44012, 0, 71456, 0, 9158, 66878, 69905, + 92440, 0, 0, 0, 484, 0, 0, 0, 194742, 0, 0, 0, 0, 572, 7041, 2736, 0, 0, + 93962, 0, 68628, 0, 0, 5438, 5222, 5381, 43114, 0, 5193, 5125, 5456, + 5509, 0, 120664, 113700, 0, 0, 0, 3430, 0, 42905, 0, 74929, 6050, 0, 0, + 129197, 0, 0, 10908, 0, 0, 0, 64617, 0, 0, 3957, 0, 0, 0, 674, 0, 0, + 2946, 5354, 5251, 5328, 5307, 3759, 72318, 8364, 5123, 0, 5281, 5469, + 5121, 0, 0, 0, 5130, 0, 129608, 0, 0, 0, 1221, 2733, 0, 0, 0, 72321, 0, + 0, 0, 0, 0, 0, 5939, 0, 0, 0, 71867, 68400, 128216, 10321, 10289, 0, + 10385, 123164, 0, 0, 0, 0, 118943, 0, 11411, 0, 5938, 0, 120865, 0, 0, + 10401, 10337, 0, 0, 0, 0, 0, 0, 0, 78277, 0, 0, 12165, 0, 0, 9885, 0, + 8077, 0, 127908, 0, 0, 0, 0, 129138, 4220, 10725, 10433, 0, 68395, 4987, + 64519, 0, 0, 0, 123626, 120356, 0, 11733, 0, 120792, 0, 127233, 0, 0, 0, + 92345, 68254, 983642, 77991, 0, 2724, 0, 0, 12313, 110619, 515, 119947, + 119944, 119945, 119942, 119943, 119940, 119941, 119938, 8606, 4046, 4589, + 4521, 0, 9141, 0, 0, 2741, 0, 0, 1370, 0, 0, 0, 0, 0, 0, 66880, 0, 66003, + 0, 68630, 0, 0, 69458, 0, 11593, 68669, 68666, 68660, 0, 0, 2744, 72285, + 68638, 0, 814, 0, 119962, 119963, 119960, 119961, 101106, 43029, 119956, + 11623, 119954, 11955, 119952, 119953, 41986, 119951, 0, 120497, 4847, + 110975, 0, 0, 0, 0, 1581, 64920, 93830, 12954, 963, 110973, 110972, + 110971, 110969, 5278, 110967, 68621, 92222, 983449, 68625, 983447, 68617, + 110960, 0, 0, 110965, 110964, 110963, 110962, 0, 0, 983439, 983440, + 983437, 983438, 983435, 92648, 127379, 0, 65137, 6483, 65392, 0, 4213, + 129649, 41303, 0, 0, 0, 41306, 983217, 2698, 0, 0, 0, 68396, 0, 41304, + 824, 0, 78011, 72315, 78894, 110982, 78892, 64804, 9820, 119820, 110985, + 110976, 0, 6739, 0, 5481, 3490, 110978, 110977, 71706, 69947, 67702, + 9124, 12688, 119833, 0, 0, 119822, 119821, 119824, 68367, 42575, 119825, + 119828, 119827, 119948, 0, 71087, 68658, 119946, 8025, 0, 127024, 68675, + 92445, 71097, 69613, 0, 0, 0, 0, 983430, 2745, 11797, 110990, 983426, + 9202, 983424, 983425, 0, 0, 0, 10525, 5436, 74584, 110987, 110986, + 121506, 43080, 121508, 121507, 983415, 6246, 119958, 10921, 9723, 6777, + 6776, 6775, 0, 0, 70287, 92384, 0, 8669, 0, 0, 65093, 0, 78881, 2716, 0, + 0, 11252, 0, 68369, 0, 11060, 12985, 2711, 78872, 78027, 78026, 7992, 0, + 0, 42938, 78033, 78032, 78877, 70724, 78029, 78028, 78031, 78030, 64535, + 110998, 10130, 110996, 0, 0, 111001, 111000, 127914, 983412, 78014, 5713, + 110995, 7570, 110993, 110992, 0, 11190, 0, 9026, 0, 74864, 7547, 78891, + 0, 10008, 10222, 0, 129543, 9744, 0, 127193, 983408, 119656, 983406, + 94070, 983404, 983405, 983402, 9045, 78888, 4225, 78886, 78887, 68757, + 78885, 78882, 78883, 983397, 983398, 8405, 983396, 10423, 10359, 983391, + 983392, 0, 129149, 4215, 9789, 0, 4321, 12309, 983400, 41313, 0, 5368, + 66886, 0, 0, 5366, 0, 5372, 0, 0, 0, 7720, 7390, 2696, 0, 0, 8268, 0, + 1790, 0, 0, 118977, 0, 0, 0, 5376, 1835, 72313, 78704, 128089, 0, 0, + 68655, 1180, 0, 0, 0, 0, 0, 0, 0, 9122, 0, 11928, 0, 65283, 0, 0, 5971, + 121171, 43500, 1268, 65097, 983218, 0, 0, 0, 1427, 128440, 0, 5970, 3431, + 72299, 983386, 983387, 983384, 983385, 983382, 2738, 125066, 10455, 0, + 74026, 0, 4222, 6240, 0, 119013, 983389, 68377, 6248, 983373, 67815, + 983371, 917907, 92582, 0, 128698, 125215, 0, 2728, 65549, 64563, 983377, + 983378, 0, 128145, 0, 10713, 7166, 119559, 2622, 0, 0, 0, 0, 8954, 0, + 94008, 2632, 42617, 10108, 1011, 42852, 12080, 2709, 0, 5716, 0, 0, 0, 0, + 127100, 69378, 0, 9515, 127098, 66465, 6451, 0, 127097, 8918, 983556, 0, + 0, 19950, 0, 0, 0, 44003, 0, 0, 0, 0, 0, 0, 983495, 74022, 0, 128795, + 68643, 67410, 0, 5721, 0, 0, 0, 121074, 11267, 983364, 66464, 5720, + 983363, 0, 4219, 5718, 8696, 5717, 0, 983370, 983878, 983368, 541, + 983366, 983367, 128237, 119089, 68389, 983352, 119949, 56, 4216, 10577, + 0, 0, 77849, 69620, 983357, 983358, 66899, 983356, 0, 0, 67628, 0, 0, + 7086, 0, 67998, 67621, 0, 2734, 69616, 0, 67627, 118937, 0, 67625, 0, 0, + 0, 42593, 0, 128217, 0, 0, 119939, 0, 68180, 0, 0, 71104, 7442, 43665, + 359, 41253, 68392, 6239, 120599, 41256, 0, 67740, 111023, 111022, 111021, + 9346, 69660, 41254, 0, 43291, 78002, 0, 0, 124993, 93841, 0, 0, 0, 4368, + 983500, 0, 68137, 0, 0, 41024, 0, 0, 121359, 121420, 0, 0, 0, 4223, 0, + 8574, 83502, 0, 0, 0, 0, 0, 92718, 983636, 70432, 128323, 68382, 0, 0, 0, + 0, 0, 4144, 0, 83193, 6245, 0, 2732, 92644, 0, 0, 0, 83501, 0, 0, 0, + 128005, 0, 0, 0, 0, 3097, 0, 0, 77996, 0, 0, 10863, 111020, 111019, + 111018, 0, 111015, 111014, 111013, 111012, 118964, 0, 10216, 64293, 0, 0, + 69393, 128331, 12325, 111010, 8717, 111008, 0, 0, 0, 0, 8700, 0, 0, + 68363, 10426, 0, 71091, 10362, 0, 1715, 0, 0, 64918, 0, 43278, 42635, 0, + 0, 65275, 0, 0, 0, 0, 0, 1607, 466, 118949, 0, 0, 127918, 6243, 983882, + 1350, 74195, 64420, 1993, 5362, 10666, 2708, 92471, 0, 13143, 234, 3199, + 0, 41268, 6334, 6250, 0, 0, 73750, 0, 73762, 10458, 0, 8576, 127136, 0, + 2704, 64953, 0, 68211, 8322, 0, 5753, 0, 2694, 0, 0, 2439, 65104, 69804, + 0, 303, 74625, 92622, 0, 2437, 0, 9817, 4844, 0, 0, 0, 0, 0, 121120, + 43292, 0, 2441, 0, 0, 0, 0, 0, 2451, 2714, 0, 0, 43379, 127984, 74541, + 753, 5849, 0, 43089, 0, 0, 119534, 0, 0, 0, 0, 2726, 3107, 0, 0, 64937, + 0, 78841, 1408, 0, 4607, 0, 181, 0, 67728, 9539, 0, 0, 65201, 121121, + 92973, 64185, 4142, 64183, 0, 0, 0, 9706, 64178, 64177, 64176, 0, 64182, + 64181, 64180, 64179, 11401, 125124, 0, 1822, 0, 128581, 68055, 3865, + 122918, 0, 10500, 129602, 119024, 0, 110732, 9830, 0, 0, 0, 65131, 0, 0, + 0, 0, 74608, 9567, 0, 9599, 8748, 0, 0, 9557, 0, 0, 0, 11494, 0, 0, + 10865, 0, 43279, 64186, 68521, 0, 64191, 64190, 8898, 64188, 129153, + 41030, 78836, 0, 0, 78820, 126100, 0, 78805, 78806, 78801, 78802, 6745, + 78800, 0, 0, 0, 110866, 0, 0, 73679, 67838, 41039, 78809, 0, 0, 0, 0, + 110869, 127045, 110867, 110868, 127039, 4400, 0, 64207, 10275, 8925, + 10371, 10307, 64202, 4248, 0, 72802, 4541, 6299, 64204, 64203, 64201, + 64200, 64199, 64198, 126471, 0, 0, 0, 64193, 64192, 0, 9943, 64197, + 64196, 64195, 64194, 13282, 42652, 64174, 64173, 83495, 846, 72337, 9965, + 74495, 72330, 83493, 83494, 2543, 12163, 64170, 83490, 64167, 64166, + 64165, 64164, 72333, 0, 64169, 64168, 64949, 0, 10251, 10247, 64163, + 64162, 2295, 43299, 43301, 129363, 0, 70791, 0, 0, 550, 9910, 0, 0, + 66579, 0, 0, 0, 9504, 0, 0, 10373, 0, 0, 10261, 10253, 7821, 10277, 0, + 74823, 1552, 0, 0, 129420, 0, 121435, 19910, 0, 0, 118849, 121150, 0, + 43985, 68051, 0, 69890, 121329, 78355, 983757, 0, 66405, 2431, 3744, + 66852, 1809, 0, 0, 0, 73759, 1264, 0, 78676, 11697, 121278, 9785, 64716, + 0, 0, 0, 0, 121307, 0, 0, 42609, 128388, 0, 66912, 127016, 0, 983885, + 74229, 0, 6487, 93798, 70743, 0, 0, 0, 83484, 83485, 83486, 83487, 83480, + 8355, 7854, 83483, 954, 64927, 0, 41045, 0, 41438, 0, 0, 10711, 0, 0, 0, + 0, 64774, 13309, 10947, 66727, 0, 0, 0, 66795, 0, 0, 0, 0, 0, 0, 0, + 120634, 69228, 0, 0, 0, 0, 0, 0, 3060, 83478, 9986, 0, 83473, 83474, + 11698, 77880, 83469, 9916, 11701, 83472, 42586, 0, 8320, 0, 119095, 0, 0, + 1477, 43289, 0, 74358, 10884, 69446, 9908, 0, 0, 0, 3414, 74304, 0, 0, 0, + 0, 2110, 0, 68306, 0, 74532, 0, 0, 0, 0, 7164, 0, 0, 0, 11950, 5392, + 42248, 65129, 68656, 5397, 129579, 0, 68136, 0, 0, 5395, 72870, 5393, + 354, 68615, 0, 0, 0, 0, 0, 126236, 0, 0, 626, 0, 5895, 0, 0, 5780, 0, + 66407, 10220, 0, 71121, 43297, 0, 0, 11468, 64436, 0, 0, 0, 73818, 3918, + 0, 3797, 72786, 0, 0, 4140, 0, 71254, 0, 9030, 813, 0, 68131, 4146, + 119957, 5360, 0, 129498, 0, 0, 6249, 0, 0, 0, 0, 0, 73092, 0, 4911, 988, + 0, 73125, 0, 42948, 0, 0, 0, 0, 74972, 0, 0, 0, 9825, 0, 0, 12803, + 126977, 11032, 67654, 6244, 0, 0, 68662, 0, 129351, 0, 72131, 4169, 0, 0, + 0, 0, 121410, 120657, 0, 0, 68657, 128943, 78496, 0, 0, 5898, 74540, 0, + 41856, 93056, 917865, 125000, 127373, 83424, 83425, 83426, 73736, 83420, + 68870, 6448, 6835, 0, 4831, 83418, 83419, 67731, 0, 0, 0, 0, 0, 0, 0, + 78499, 0, 0, 0, 43288, 0, 0, 0, 0, 0, 43418, 0, 0, 0, 7876, 68132, + 917872, 0, 917870, 43378, 0, 0, 120890, 5892, 43605, 0, 0, 0, 129058, 0, + 0, 6251, 83409, 83410, 83411, 83412, 126512, 0, 71092, 83408, 10114, 0, + 0, 5387, 0, 0, 0, 0, 65553, 78346, 1747, 917849, 65109, 69240, 917852, + 126509, 0, 0, 0, 0, 125065, 0, 9850, 0, 367, 1472, 917859, 6687, 0, 0, + 5905, 12339, 8919, 73953, 65680, 0, 0, 78664, 0, 9134, 0, 78666, 43011, + 0, 126626, 0, 0, 0, 43013, 10614, 0, 0, 83413, 66646, 83415, 83416, 0, + 73881, 43012, 121127, 83293, 54, 43009, 73885, 0, 6211, 0, 0, 83295, + 68119, 43008, 10758, 0, 0, 0, 0, 0, 70018, 0, 0, 0, 0, 12765, 0, 0, 0, 0, + 126580, 0, 0, 43657, 0, 0, 0, 983718, 0, 83405, 917843, 0, 0, 83401, + 83402, 83403, 83404, 83397, 11363, 12057, 83400, 1567, 0, 0, 83396, 0, + 8957, 4139, 0, 0, 129336, 0, 0, 12740, 0, 92195, 12761, 127793, 12759, 0, + 72304, 67169, 83467, 44002, 0, 83462, 83463, 83464, 12755, 12762, 41022, + 67690, 64217, 476, 0, 983715, 0, 64212, 41020, 1382, 64209, 64216, 64215, + 64214, 64213, 0, 0, 0, 67584, 8720, 3908, 0, 0, 0, 0, 129434, 129576, 0, + 0, 3849, 92324, 94026, 9778, 917906, 5891, 917912, 55, 917910, 917911, 0, + 0, 7935, 67586, 0, 1114, 92599, 67585, 78675, 0, 83447, 83449, 0, 0, 0, + 64717, 0, 0, 0, 66884, 6292, 65303, 0, 6452, 917886, 917887, 66249, + 917885, 917890, 917891, 917888, 719, 0, 0, 917892, 0, 0, 0, 94083, 10868, + 121333, 2349, 5902, 917896, 6335, 917902, 917899, 917900, 0, 64369, 0, 0, + 0, 69245, 0, 126564, 0, 0, 128565, 0, 0, 0, 0, 0, 6454, 1229, 83457, + 83458, 83450, 83451, 83452, 65100, 120508, 8224, 917873, 917874, 917879, + 917880, 917877, 917878, 128929, 0, 917881, 917882, 5365, 67836, 8901, 0, + 0, 0, 0, 0, 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, + 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, 0, 0, 0, 42038, 387, + 0, 12737, 0, 0, 43368, 0, 0, 0, 0, 0, 129449, 121295, 0, 69400, 127309, + 0, 375, 0, 0, 0, 983886, 0, 0, 119202, 119203, 0, 43120, 0, 0, 119196, + 119197, 0, 4529, 119200, 119201, 119198, 119199, 0, 0, 69698, 13150, + 64492, 0, 0, 0, 0, 0, 42891, 66327, 74298, 0, 0, 0, 2587, 42193, 0, 6455, + 0, 4241, 0, 0, 0, 0, 0, 0, 0, 118821, 0, 0, 0, 125030, 0, 128684, 129390, + 0, 5373, 0, 0, 119232, 10015, 0, 0, 0, 68642, 0, 120855, 42040, 128827, + 5779, 0, 42037, 83282, 0, 0, 93040, 83283, 0, 0, 127320, 6983, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 119588, 0, 92495, 74558, 0, 68138, 70163, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11144, 0, 2551, 0, 6453, 0, 6235, 0, 0, 129081, 72886, + 44020, 11826, 0, 7780, 5369, 118958, 0, 0, 5367, 66870, 0, 0, 5377, 0, + 68143, 128624, 78245, 5218, 0, 127333, 0, 0, 0, 0, 0, 1300, 0, 127334, + 64505, 0, 0, 119624, 1465, 0, 0, 0, 0, 0, 0, 0, 113694, 10729, 0, 0, + 8839, 119243, 0, 7785, 126530, 0, 0, 0, 0, 126603, 0, 0, 0, 3897, 0, + 92331, 74417, 113704, 0, 68127, 71425, 70688, 0, 0, 0, 0, 0, 3542, 0, + 120685, 7951, 68152, 118857, 0, 92972, 0, 0, 127311, 73683, 0, 65150, + 68031, 0, 0, 0, 0, 9985, 0, 127328, 0, 0, 0, 0, 10830, 0, 615, 64490, + 7574, 0, 0, 0, 12909, 73698, 64559, 127332, 73951, 0, 67996, 2020, 0, 0, + 0, 120701, 0, 983640, 0, 0, 0, 92991, 0, 0, 9070, 0, 68411, 11281, 42829, + 0, 1033, 0, 0, 0, 0, 0, 65226, 0, 0, 0, 0, 0, 3450, 0, 7397, 0, 0, 42778, + 10000, 41088, 449, 0, 0, 68458, 113725, 0, 0, 10738, 69634, 0, 0, 41085, + 0, 0, 0, 12764, 0, 93058, 3596, 7322, 0, 0, 0, 0, 0, 0, 0, 0, 2092, 0, 0, + 0, 121350, 10820, 0, 0, 126567, 1853, 0, 0, 93014, 0, 12770, 0, 0, + 124997, 0, 0, 0, 0, 0, 129053, 4828, 1258, 0, 2006, 0, 0, 74285, 127987, + 0, 120683, 122880, 983881, 983884, 8846, 128255, 0, 128091, 2650, 9182, + 1961, 121399, 11525, 0, 1959, 0, 55228, 11774, 41016, 0, 0, 128054, + 41017, 13109, 0, 10519, 66331, 3454, 19930, 0, 41019, 92894, 0, 0, 78362, + 41021, 0, 0, 0, 0, 0, 65531, 0, 0, 0, 0, 0, 0, 8865, 6402, 113827, 77923, + 0, 127924, 0, 7733, 0, 4998, 68493, 0, 0, 0, 4268, 0, 0, 0, 0, 128718, + 10881, 0, 0, 0, 0, 2014, 0, 71901, 0, 0, 195057, 0, 0, 78357, 65281, 0, + 0, 0, 0, 0, 2015, 0, 0, 71840, 66318, 74824, 0, 0, 0, 0, 0, 70061, 8094, + 10135, 0, 0, 794, 0, 0, 66335, 0, 121303, 4343, 0, 4833, 0, 0, 0, 0, 189, + 12611, 0, 72215, 0, 4838, 126214, 4834, 65078, 0, 126104, 4837, 118853, + 0, 121230, 4832, 128271, 0, 0, 127838, 0, 0, 0, 0, 0, 0, 0, 3976, 118995, + 128937, 0, 0, 0, 0, 0, 119010, 0, 121015, 0, 0, 0, 0, 2871, 0, 0, 999, 0, + 68177, 0, 0, 2017, 0, 67824, 0, 0, 0, 0, 0, 0, 4775, 12555, 12571, 12550, + 12583, 12560, 2019, 12556, 12584, 12586, 0, 12562, 12561, 12566, 12569, + 12554, 0, 83344, 0, 68882, 0, 12567, 1402, 0, 0, 83348, 125072, 83347, 0, + 83346, 0, 0, 0, 0, 64391, 0, 83341, 69602, 0, 1999, 0, 128141, 0, 0, 0, + 0, 0, 0, 0, 68873, 0, 0, 66913, 2377, 0, 0, 12572, 11318, 12557, 12559, + 9192, 12549, 12568, 2373, 9446, 9447, 9448, 9449, 0, 9480, 481, 0, 9438, + 9439, 9440, 9441, 9442, 9443, 9444, 9445, 9430, 9431, 9432, 9433, 9434, + 9435, 9436, 9437, 983097, 0, 9424, 9425, 9426, 9427, 9428, 7481, 0, 2362, + 9655, 0, 2004, 0, 9782, 0, 0, 0, 0, 0, 0, 0, 1108, 0, 92461, 0, 0, 0, + 64781, 0, 0, 0, 121126, 0, 1392, 0, 0, 917557, 0, 8065, 70710, 128739, 0, + 0, 0, 121068, 92418, 0, 0, 0, 43280, 0, 70718, 1812, 0, 73046, 0, 0, 0, + 0, 0, 6054, 10697, 3169, 0, 0, 70720, 11487, 70712, 0, 0, 0, 194716, 0, + 0, 41863, 0, 0, 2304, 0, 92326, 0, 118792, 0, 0, 64760, 11766, 0, 0, 0, + 0, 69236, 0, 0, 8773, 10733, 36, 0, 0, 0, 0, 0, 11074, 0, 64910, 983130, + 2009, 0, 0, 128036, 68114, 128906, 0, 0, 0, 0, 12852, 3031, 0, 0, 129088, + 0, 66414, 0, 0, 119950, 42613, 65933, 366, 0, 9892, 0, 11754, 0, 83329, + 65301, 44013, 83058, 67245, 10102, 0, 7739, 41026, 0, 0, 0, 0, 0, 0, 0, + 0, 78386, 129475, 71868, 113811, 13081, 10923, 129330, 0, 68145, 0, 0, + 74083, 0, 0, 128392, 83063, 83065, 0, 70706, 0, 0, 0, 70168, 66586, 4183, + 64967, 66250, 0, 92547, 0, 0, 113685, 0, 3792, 2011, 0, 0, 126503, 83332, + 0, 120595, 0, 68489, 41023, 0, 0, 11659, 7922, 12614, 2005, 8523, 0, 0, + 7513, 1863, 129436, 83337, 128969, 0, 120274, 120033, 0, 8144, 0, 73031, + 120269, 127524, 120270, 42241, 8783, 83326, 0, 0, 120735, 983959, 0, + 129367, 0, 10680, 0, 43293, 68771, 0, 119164, 83320, 92467, 10187, 0, 0, + 0, 83315, 0, 0, 0, 10968, 43296, 0, 0, 0, 0, 0, 1005, 43826, 120030, 0, + 2870, 0, 113759, 0, 0, 0, 0, 235, 1384, 0, 74887, 70494, 120409, 0, 9796, + 69895, 983812, 0, 0, 13186, 120407, 0, 0, 0, 0, 42527, 12911, 43427, + 1383, 0, 0, 0, 0, 6156, 68117, 0, 7993, 4288, 0, 0, 13238, 13244, 0, 0, + 120426, 13234, 120427, 0, 118904, 0, 11364, 0, 1380, 65617, 120253, + 120261, 13196, 13197, 120311, 120419, 9495, 0, 0, 120418, 0, 73976, + 128160, 0, 6941, 0, 13205, 13211, 5801, 0, 74271, 120319, 0, 120302, + 7670, 0, 68075, 983587, 0, 19957, 72314, 2021, 93811, 43877, 0, 0, 0, 0, + 3875, 0, 64341, 0, 9814, 43457, 13066, 3314, 7787, 0, 0, 0, 0, 0, 0, + 64531, 0, 0, 0, 0, 0, 0, 127138, 0, 0, 9742, 0, 0, 10800, 0, 8404, 0, + 92592, 0, 7089, 0, 78545, 0, 0, 0, 0, 0, 4772, 5771, 0, 0, 9841, 8843, 0, + 0, 0, 0, 120816, 0, 123137, 0, 0, 0, 0, 0, 0, 8849, 0, 0, 65112, 1796, 0, + 0, 69665, 8164, 41301, 3502, 0, 122884, 128387, 0, 983816, 5825, 0, 0, 0, + 0, 121322, 10983, 10354, 10418, 0, 2022, 0, 1409, 100789, 0, 0, 0, 0, + 1390, 0, 0, 10471, 65904, 5846, 126472, 0, 0, 0, 0, 0, 0, 66035, 0, 0, 0, + 0, 128190, 0, 3168, 67733, 0, 0, 2370, 0, 126243, 0, 195049, 0, 0, 1836, + 0, 121207, 119137, 118959, 125232, 0, 0, 0, 2390, 3944, 0, 0, 0, 0, + 69908, 125011, 0, 0, 123200, 0, 0, 8975, 64739, 0, 0, 0, 0, 64409, 0, 0, + 0, 0, 128564, 0, 0, 0, 0, 6204, 0, 0, 0, 10911, 64954, 119003, 74809, + 118903, 4267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92887, 0, 0, 0, 0, 121125, 0, + 128337, 5842, 0, 41439, 0, 0, 0, 9328, 0, 120980, 120917, 0, 0, 2285, 0, + 0, 0, 0, 0, 64555, 0, 0, 72162, 9541, 0, 0, 0, 41441, 0, 0, 0, 41040, + 2459, 0, 0, 41041, 0, 0, 0, 0, 0, 10450, 0, 41043, 0, 0, 43125, 0, 0, 0, + 0, 0, 121008, 68436, 128040, 0, 120649, 0, 0, 4312, 43927, 0, 0, 11923, + 42227, 0, 5763, 0, 4827, 74559, 42228, 64406, 0, 0, 0, 433, 119620, 0, + 2499, 67167, 67166, 0, 11973, 0, 4293, 42271, 42224, 0, 0, 66322, 42226, + 0, 0, 0, 74180, 0, 55277, 0, 0, 0, 983265, 0, 74632, 0, 0, 71103, 0, 0, + 0, 585, 2383, 0, 43263, 0, 4290, 0, 0, 68920, 0, 8511, 0, 0, 0, 119048, + 2380, 126119, 0, 71704, 2376, 0, 0, 0, 5197, 127046, 127047, 127048, + 2366, 127050, 127051, 73442, 0, 0, 0, 93835, 0, 93818, 0, 0, 74188, + 113813, 0, 0, 0, 983819, 0, 0, 0, 0, 1847, 0, 72771, 0, 42384, 0, 4227, + 74158, 0, 92501, 0, 0, 42365, 0, 128902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128563, 0, 983504, 127560, 2754, 0, 0, 128900, 0, 127867, 119638, 0, + 1711, 12984, 92365, 0, 6255, 0, 0, 0, 0, 0, 42063, 74184, 0, 0, 0, 0, 0, + 0, 0, 41035, 43274, 0, 11256, 119088, 0, 520, 0, 41037, 128162, 0, 0, + 41034, 0, 983810, 64815, 0, 0, 321, 41028, 0, 0, 0, 0, 0, 0, 0, 74191, 0, + 0, 72767, 1861, 0, 129666, 0, 0, 100770, 0, 0, 128530, 3859, 0, 41660, 0, + 70793, 0, 983737, 75014, 0, 127514, 41658, 0, 0, 0, 0, 0, 4414, 120766, + 0, 42632, 0, 0, 0, 0, 0, 1405, 0, 43220, 43341, 0, 0, 0, 0, 0, 983714, + 11199, 0, 3513, 0, 70341, 43342, 0, 65529, 0, 0, 0, 6485, 1397, 0, 0, + 92678, 0, 0, 0, 82961, 0, 82962, 0, 74270, 43287, 983712, 0, 0, 983719, + 0, 71914, 4317, 10490, 0, 0, 194867, 74463, 128952, 464, 41624, 0, 0, 0, + 1346, 128240, 917631, 64724, 128566, 423, 0, 0, 113748, 0, 128161, 0, 0, + 120563, 64960, 0, 0, 0, 0, 9584, 129106, 0, 125026, 0, 9718, 0, 42642, + 92977, 64750, 0, 0, 0, 0, 128333, 0, 3204, 64666, 0, 43530, 2752, 0, 0, + 119594, 0, 0, 0, 0, 92371, 0, 41983, 0, 7010, 0, 0, 41495, 92379, 5877, + 42252, 93070, 8009, 3305, 0, 0, 0, 0, 92293, 0, 0, 0, 100836, 0, 65915, + 1400, 75018, 10685, 75017, 2103, 0, 0, 43276, 0, 11169, 0, 6481, 0, 0, 0, + 100837, 72249, 100838, 74198, 0, 9116, 0, 0, 0, 0, 0, 0, 8129, 92994, 0, + 124992, 0, 11658, 0, 0, 3452, 41031, 0, 1385, 0, 0, 0, 43340, 11123, + 41033, 6493, 12758, 0, 0, 11426, 0, 1681, 100755, 1204, 11960, 69902, 0, + 69457, 0, 119322, 0, 7415, 43338, 0, 0, 67717, 64915, 0, 100759, 100850, + 41497, 65044, 0, 19960, 65358, 983601, 0, 0, 0, 73670, 0, 1789, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 64728, 0, 0, 0, 6506, 64312, 0, 2368, 0, 0, 0, 0, + 3439, 1825, 1192, 0, 73739, 10639, 0, 7790, 5430, 0, 0, 2848, 92981, 0, + 0, 7607, 0, 0, 0, 120658, 0, 0, 8883, 0, 728, 0, 0, 0, 0, 92931, 0, + 121372, 128348, 0, 68078, 8091, 11447, 0, 0, 126261, 0, 0, 70003, 0, 0, + 74419, 12335, 0, 0, 3443, 0, 0, 0, 127145, 0, 0, 0, 0, 11843, 0, 9205, + 8624, 128543, 92930, 43295, 0, 65445, 0, 6277, 41672, 0, 10010, 70186, + 983052, 0, 835, 71340, 0, 0, 0, 0, 0, 5426, 4258, 0, 64891, 5424, 0, + 8283, 0, 5434, 0, 0, 0, 0, 0, 11947, 0, 1404, 0, 11432, 0, 3464, 6486, + 4819, 0, 0, 570, 8095, 0, 0, 1498, 0, 0, 0, 431, 67820, 0, 0, 128096, 0, + 0, 13096, 0, 0, 43408, 0, 128538, 8835, 77875, 0, 0, 0, 0, 0, 0, 0, 0, + 3477, 227, 10488, 0, 382, 11418, 0, 5878, 0, 0, 0, 0, 6484, 92355, 66039, + 0, 0, 0, 78717, 0, 92662, 119665, 0, 0, 43290, 0, 0, 0, 0, 8782, 0, 0, + 4323, 128649, 0, 120903, 12094, 0, 0, 0, 0, 92953, 3856, 120970, 0, 5872, + 6495, 72306, 0, 0, 0, 67173, 67172, 67171, 3953, 0, 0, 93063, 11994, + 4339, 0, 92654, 0, 0, 0, 0, 128804, 0, 5228, 0, 9766, 0, 92741, 0, 0, 0, + 0, 68860, 0, 1162, 0, 2671, 0, 0, 92632, 92631, 72117, 0, 73811, 0, + 194895, 0, 68085, 0, 74331, 11424, 0, 10466, 121239, 0, 194890, 0, 4820, + 0, 0, 0, 194891, 0, 119212, 4896, 0, 4897, 42821, 64611, 0, 4438, 0, 0, + 1753, 11331, 6147, 0, 43282, 8833, 0, 0, 6504, 0, 0, 0, 0, 0, 1413, 0, 0, + 64353, 12141, 121138, 0, 0, 43163, 0, 72880, 64789, 127094, 838, 127092, + 120697, 127090, 5014, 0, 256, 0, 0, 42443, 42739, 0, 7542, 0, 70389, 0, + 6489, 10048, 74326, 0, 66573, 0, 125271, 78712, 11761, 126078, 129603, + 41094, 0, 0, 0, 0, 92689, 8453, 0, 0, 120942, 128184, 0, 11816, 0, 0, + 2930, 93845, 0, 41098, 92771, 41093, 0, 0, 6498, 41096, 0, 0, 1238, 200, + 0, 1660, 74476, 0, 0, 74362, 0, 0, 72301, 9224, 0, 0, 0, 0, 0, 0, 0, 0, + 72729, 43284, 0, 72110, 120561, 13183, 0, 0, 0, 1669, 10776, 0, 0, 0, 0, + 0, 1732, 4030, 0, 3963, 0, 0, 0, 6491, 0, 0, 914, 121394, 0, 0, 0, 78713, + 0, 92441, 74367, 0, 0, 0, 0, 0, 0, 0, 0, 65537, 0, 0, 43430, 5301, 0, + 92618, 0, 43285, 0, 0, 125186, 0, 0, 5876, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 11114, 74536, 0, 0, 0, 0, 983129, 0, 0, 0, 0, 10915, 983069, 12007, 0, + 0, 0, 0, 67655, 92604, 0, 8629, 0, 43168, 41872, 0, 0, 0, 42488, 0, 0, 0, + 0, 0, 64730, 70041, 0, 122895, 0, 0, 0, 92306, 11416, 4280, 128516, 8765, + 73451, 0, 1393, 0, 11157, 74386, 0, 0, 0, 0, 6683, 0, 93832, 12144, 0, + 74513, 13019, 74994, 0, 0, 0, 983267, 0, 6488, 357, 0, 41100, 0, 41104, + 0, 41099, 0, 71320, 0, 0, 0, 4434, 0, 0, 0, 74231, 83107, 0, 194914, 0, + 0, 72286, 68305, 0, 41759, 12757, 0, 0, 72769, 9790, 8995, 0, 121095, + 68209, 0, 41764, 0, 0, 72322, 2268, 0, 0, 0, 12743, 0, 6480, 0, 41779, 0, + 66601, 0, 74490, 10986, 66602, 0, 64807, 0, 0, 41767, 119629, 0, 0, 0, + 3955, 64571, 194918, 127089, 0, 70187, 69975, 9770, 12305, 12230, 0, + 78579, 0, 0, 74752, 0, 0, 123168, 128263, 74449, 0, 0, 69611, 0, 0, + 71131, 129505, 78573, 0, 0, 11116, 0, 5747, 0, 110667, 9802, 41092, + 120731, 0, 0, 0, 0, 0, 120733, 41090, 0, 0, 0, 11271, 57, 0, 0, 0, 0, + 71268, 121290, 43137, 0, 0, 0, 126221, 0, 0, 0, 0, 0, 277, 74385, 0, 0, + 0, 72155, 0, 13025, 8757, 0, 0, 1574, 0, 126124, 100800, 0, 5749, 0, 0, + 42824, 0, 1039, 9801, 0, 5745, 0, 41858, 0, 0, 120655, 0, 41862, 0, 0, 0, + 436, 4771, 194636, 42501, 0, 10573, 0, 0, 0, 917986, 9644, 0, 0, 0, 0, + 69837, 0, 0, 0, 0, 67409, 0, 0, 0, 125204, 11939, 0, 0, 0, 0, 0, 0, 0, + 3504, 0, 0, 0, 126209, 0, 10226, 65558, 0, 3594, 0, 0, 40, 0, 0, 0, 0, 0, + 74312, 72138, 74337, 0, 983667, 0, 0, 0, 70476, 0, 121143, 72317, 0, 0, + 4304, 0, 0, 78707, 0, 0, 0, 78597, 1348, 78596, 0, 0, 0, 70406, 92392, 0, + 7599, 0, 0, 13269, 0, 0, 0, 100804, 0, 74494, 6097, 7568, 43980, 4982, + 78592, 0, 0, 0, 0, 13270, 0, 0, 13138, 0, 9484, 0, 0, 71364, 0, 0, 0, + 9487, 0, 92913, 0, 71911, 78668, 73963, 6193, 0, 0, 0, 194848, 7228, + 10011, 194849, 194852, 194851, 11654, 194853, 126218, 194855, 0, 194857, + 3604, 0, 0, 0, 0, 0, 94110, 43740, 94109, 194860, 194863, 66750, 121021, + 0, 94111, 6995, 74173, 5437, 74174, 0, 8702, 7339, 194842, 0, 199, + 194843, 194846, 194845, 0, 126069, 0, 67818, 0, 7560, 0, 0, 0, 0, 6472, + 65814, 0, 128983, 70845, 0, 0, 9191, 0, 0, 0, 0, 0, 10196, 0, 0, 6585, 0, + 120750, 0, 0, 71872, 129129, 0, 0, 78590, 72308, 11382, 129499, 0, + 983651, 0, 194833, 194832, 194835, 129540, 94020, 194836, 42727, 194838, + 128252, 78585, 43874, 119610, 0, 0, 43248, 0, 194816, 0, 194818, 128845, + 194820, 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, + 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, 194926, 1931, 0, 0, 0, 128228, 0, + 12643, 8751, 123629, 0, 12294, 0, 78834, 9138, 78831, 78833, 12631, + 78829, 11080, 78821, 0, 0, 1239, 0, 121067, 0, 12636, 0, 0, 0, 0, 0, 0, + 8998, 0, 0, 9152, 0, 0, 0, 67589, 0, 64290, 0, 92393, 12615, 0, 129141, + 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, + 42788, 0, 64612, 194875, 10774, 194877, 0, 194879, 0, 0, 0, 997, 194901, + 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, 0, 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, + 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, + 0, 0, 118929, 0, 0, 72141, 0, 73459, 0, 0, 0, 73461, 9254, 66877, 194907, + 0, 92338, 5624, 126253, 0, 0, 0, 120472, 120464, 0, 0, 122915, 120462, 0, + 1872, 66508, 120467, 41079, 0, 5502, 119330, 41078, 194906, 0, 0, 4511, + 68449, 0, 0, 0, 0, 43245, 41083, 68861, 0, 0, 9003, 119959, 0, 5305, + 9653, 41081, 43146, 9546, 0, 0, 120478, 0, 65205, 71713, 64063, 120459, + 0, 0, 0, 64058, 43101, 43102, 0, 64062, 1028, 64060, 64059, 0, 10567, + 110816, 110817, 110814, 110815, 0, 2902, 64043, 64042, 43749, 10756, + 64047, 64046, 64045, 64044, 0, 10076, 64040, 64039, 0, 1034, 0, 0, 64034, + 64033, 64032, 42735, 64038, 64037, 64036, 64035, 4291, 0, 64015, 64014, + 83393, 83394, 83395, 983765, 0, 43090, 83391, 3476, 64013, 64012, 64011, + 64010, 64008, 64007, 2003, 7706, 0, 0, 119050, 64009, 204, 0, 0, 4430, + 8239, 64003, 10626, 64001, 64057, 13079, 64055, 64054, 0, 0, 43246, 9343, + 64049, 64048, 0, 1133, 64053, 64052, 64051, 64050, 0, 0, 0, 66415, 12329, + 0, 0, 0, 1942, 0, 0, 0, 128249, 0, 68291, 10760, 64023, 64022, 64021, + 64020, 43670, 77924, 64025, 41412, 78243, 78244, 0, 0, 64019, 64018, + 64017, 64016, 0, 0, 78251, 78252, 78248, 78249, 77914, 78247, 0, 917560, + 77919, 6788, 13094, 0, 7532, 41414, 0, 3179, 70745, 64769, 0, 0, 0, 0, + 10751, 0, 0, 0, 0, 0, 0, 0, 2008, 64031, 64030, 294, 41874, 83383, 83384, + 65929, 83376, 129063, 83379, 83380, 64028, 11396, 64026, 83374, 0, 0, + 118795, 71739, 43247, 0, 70153, 0, 0, 0, 0, 0, 0, 0, 0, 7801, 83359, + 83361, 128931, 0, 3297, 83356, 83357, 1135, 83350, 83351, 73696, 1995, + 7927, 71738, 110742, 2552, 83372, 60, 0, 8649, 83368, 83369, 83370, + 83371, 10541, 83365, 78679, 43833, 0, 0, 2013, 83362, 0, 110636, 0, 0, + 12832, 110638, 8081, 8362, 120188, 0, 9137, 0, 0, 0, 0, 3466, 0, 0, 1996, + 0, 3453, 3412, 0, 2002, 2000, 120176, 0, 0, 0, 0, 1998, 0, 1842, 0, 0, + 9628, 68446, 0, 9826, 64502, 1767, 3413, 0, 0, 0, 0, 0, 0, 13108, 44024, + 120204, 0, 92693, 0, 0, 0, 70291, 12650, 983208, 0, 68061, 0, 3592, 0, 0, + 0, 0, 983956, 0, 66417, 128792, 10742, 0, 0, 1994, 9281, 3296, 64475, + 1997, 1895, 128936, 72387, 0, 0, 123184, 72391, 0, 8999, 0, 983633, 0, + 66480, 0, 0, 0, 983083, 0, 596, 0, 0, 120216, 8651, 120217, 0, 0, 12995, + 0, 0, 70740, 0, 42930, 119955, 64810, 917834, 6825, 0, 917839, 120208, + 64275, 120889, 128069, 120210, 6384, 917840, 126477, 0, 67698, 0, 0, 0, + 120496, 0, 43412, 0, 0, 0, 0, 0, 120172, 0, 120763, 0, 0, 0, 128343, + 1457, 0, 0, 6381, 2815, 0, 65240, 129664, 0, 0, 119522, 70487, 0, 0, 0, + 0, 0, 120572, 0, 0, 0, 0, 0, 125253, 0, 0, 0, 120574, 0, 0, 0, 3055, + 9852, 0, 65288, 0, 11398, 0, 0, 93016, 0, 0, 603, 128557, 0, 0, 0, + 129366, 3350, 0, 0, 917828, 917827, 68428, 917825, 73045, 917831, 917830, + 917829, 0, 1919, 0, 110767, 83296, 83297, 83298, 66446, 64141, 8562, + 64139, 64138, 64136, 64135, 64134, 64133, 11297, 0, 0, 11966, 64128, + 66286, 0, 0, 64132, 10867, 64130, 64129, 0, 43374, 9779, 2764, 0, 0, + 9471, 0, 0, 0, 0, 66010, 0, 8857, 128771, 121423, 0, 69223, 0, 194660, + 983857, 0, 0, 43984, 0, 0, 0, 0, 0, 0, 10717, 64570, 5630, 0, 64143, + 64142, 83300, 67758, 83302, 0, 77930, 0, 0, 0, 11631, 64146, 64145, + 64144, 2384, 72801, 127380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122916, 8933, + 1601, 917803, 858, 917809, 64109, 64108, 8090, 0, 917812, 917811, 587, 0, + 82971, 0, 0, 0, 78214, 2750, 0, 9983, 64158, 64157, 83288, 83289, 83290, + 2760, 83284, 83285, 83286, 83287, 64156, 64155, 64154, 72109, 64151, + 64150, 12679, 10053, 10421, 0, 64153, 64152, 0, 0, 4839, 0, 0, 4435, + 119016, 0, 64126, 64125, 64124, 64123, 129287, 0, 0, 7007, 0, 65443, 0, + 0, 64122, 0, 0, 93834, 64117, 64116, 6287, 64114, 64121, 64120, 64119, + 64118, 110659, 127842, 1177, 65601, 12322, 64106, 92169, 110654, 64102, + 64101, 64100, 64099, 0, 10453, 64104, 64103, 7997, 0, 92534, 0, 8705, + 64097, 64096, 9571, 0, 110652, 127398, 12132, 0, 0, 0, 110624, 73841, + 83339, 83340, 9056, 0, 0, 0, 6155, 64068, 64067, 64066, 64065, 64072, + 64071, 63, 64069, 127382, 0, 93822, 7257, 64064, 0, 0, 0, 0, 0, 0, 78748, + 0, 0, 0, 120519, 0, 66242, 66232, 4333, 9855, 64112, 0, 0, 0, 0, 0, 0, 0, + 66222, 0, 0, 0, 0, 69816, 0, 118796, 0, 8708, 0, 64077, 64076, 8996, + 4992, 4471, 83343, 64079, 64078, 92179, 0, 0, 129120, 64615, 0, 0, 12075, + 42041, 0, 0, 0, 0, 127557, 3123, 0, 983735, 0, 0, 0, 83328, 0, 9223, 0, + 83321, 83322, 73797, 83327, 1116, 0, 83319, 7136, 0, 0, 0, 0, 75031, 0, + 0, 0, 64092, 43675, 10104, 83338, 83331, 64095, 64094, 8111, 66247, 0, + 64089, 64088, 0, 70106, 42236, 11434, 64083, 64082, 43216, 7737, 64087, + 64086, 64085, 64084, 0, 0, 0, 4118, 1797, 83312, 0, 0, 46, 83308, 83309, + 298, 83303, 72402, 83305, 83306, 0, 0, 0, 128905, 11495, 0, 0, 0, 127377, + 194828, 127370, 0, 0, 0, 66239, 74945, 64403, 0, 0, 83314, 0, 0, 65758, + 43536, 0, 8544, 0, 0, 0, 0, 194824, 0, 0, 0, 0, 0, 3639, 11242, 194822, + 0, 0, 0, 0, 0, 0, 68409, 0, 0, 0, 0, 0, 0, 0, 128654, 8789, 126248, 0, 0, + 0, 0, 0, 0, 0, 65058, 0, 78234, 68064, 0, 66227, 71694, 5573, 118936, 0, + 44, 0, 66244, 118907, 0, 66238, 12844, 0, 1622, 129190, 1900, 0, 11458, + 0, 0, 6581, 5576, 128303, 0, 126122, 0, 113680, 8947, 0, 113812, 0, 0, 0, + 7908, 0, 0, 6579, 0, 0, 0, 0, 2138, 6583, 7761, 0, 0, 0, 66802, 5058, 0, + 0, 0, 5057, 125256, 0, 74538, 5054, 0, 0, 0, 0, 0, 0, 658, 3497, 128509, + 0, 5061, 5060, 4235, 0, 0, 0, 127757, 4236, 4727, 0, 0, 0, 128791, 0, + 7488, 128693, 7476, 0, 125259, 120646, 0, 0, 0, 66209, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9341, 119596, 0, 0, 0, 64668, 0, 8125, + 0, 6743, 119175, 0, 129441, 83406, 0, 127966, 119235, 74092, 0, 0, 43660, + 0, 0, 127901, 0, 0, 0, 264, 0, 74954, 0, 0, 0, 0, 0, 6019, 0, 0, 129121, + 0, 0, 0, 8800, 0, 66376, 0, 120948, 0, 100744, 0, 0, 92333, 725, 68014, + 0, 0, 72099, 0, 0, 0, 0, 74899, 0, 0, 0, 110804, 0, 72142, 5074, 5073, 0, + 0, 0, 0, 70723, 5072, 128576, 13098, 72403, 0, 11040, 0, 0, 0, 4929, 0, + 0, 0, 0, 0, 0, 0, 0, 67754, 4934, 0, 0, 9758, 0, 0, 70181, 42584, 0, + 4329, 0, 4979, 8663, 74521, 0, 983042, 74418, 0, 0, 5071, 0, 3642, 0, + 5070, 10042, 0, 3987, 5068, 120211, 8909, 0, 0, 69917, 0, 73981, 983141, + 70749, 4531, 120212, 9105, 0, 4921, 121059, 4926, 65544, 113786, 69621, + 0, 0, 0, 83269, 0, 120790, 4922, 0, 992, 119568, 4925, 0, 0, 9526, 4920, + 128617, 948, 0, 0, 4930, 0, 0, 0, 4933, 0, 0, 0, 4928, 0, 0, 0, 0, + 128379, 722, 0, 127483, 127482, 127485, 82997, 127487, 1509, 0, 5468, + 66214, 127474, 127477, 1672, 127479, 10864, 127481, 72132, 127467, 72159, + 127469, 127468, 127471, 127470, 68336, 82999, 120115, 1679, 120116, 0, + 120113, 127462, 127465, 127464, 127110, 120119, 120112, 0, 120109, 6968, + 5761, 342, 8553, 0, 8143, 127115, 127114, 127113, 624, 127111, 4057, 0, + 5078, 0, 0, 0, 5076, 0, 0, 0, 120097, 685, 9025, 1524, 8003, 0, 5539, + 113727, 113795, 120102, 7138, 120552, 0, 0, 0, 113724, 0, 8058, 9732, 0, + 5080, 0, 5036, 5035, 0, 42604, 72118, 0, 0, 275, 13291, 69995, 0, 0, + 983908, 5033, 0, 0, 4836, 70184, 73792, 0, 0, 0, 120681, 43704, 0, 2274, + 119000, 124983, 0, 8858, 6409, 0, 119585, 0, 0, 0, 0, 0, 68442, 0, 3432, + 10218, 0, 6094, 11232, 0, 0, 0, 0, 1676, 129157, 0, 0, 5030, 0, 118810, + 0, 73869, 0, 0, 69944, 6787, 0, 0, 0, 983595, 10544, 12919, 69425, 92218, + 0, 0, 0, 129172, 0, 67703, 0, 0, 0, 0, 0, 72290, 0, 0, 0, 0, 7018, 66241, + 0, 0, 0, 0, 0, 74056, 0, 11833, 0, 67975, 65232, 40964, 251, 12686, 7895, + 4395, 43538, 0, 0, 0, 78042, 0, 0, 40967, 5879, 0, 0, 0, 0, 0, 65540, + 128590, 625, 0, 120194, 1113, 0, 13103, 3630, 67224, 8179, 74264, 67886, + 9316, 10980, 2489, 120958, 8150, 1359, 121353, 70464, 127330, 127327, + 5042, 5041, 42769, 12084, 11196, 127321, 92279, 72398, 120535, 127317, + 127318, 127315, 12283, 127313, 11453, 0, 8795, 66245, 0, 0, 0, 5037, + 118864, 0, 0, 67724, 0, 66893, 74006, 0, 8431, 0, 0, 0, 0, 12620, 6826, + 73773, 70169, 5040, 0, 0, 0, 0, 0, 5039, 0, 0, 0, 5038, 0, 0, 0, 0, 0, + 65908, 0, 0, 0, 0, 0, 65157, 0, 0, 70182, 0, 73909, 4835, 0, 0, 0, 4309, + 7127, 0, 0, 0, 1301, 0, 0, 12222, 0, 73813, 711, 92439, 7133, 0, 0, 0, 0, + 0, 0, 0, 7661, 72263, 129541, 0, 0, 70453, 7627, 0, 5031, 92340, 42738, + 65784, 0, 65782, 3758, 0, 65781, 67865, 0, 2440, 65780, 70795, 8449, + 121393, 121479, 0, 2118, 0, 12121, 0, 0, 129510, 2128, 2130, 2131, 2126, + 2133, 0, 121250, 2114, 2116, 2455, 0, 2122, 2123, 2124, 2125, 983787, + 8714, 0, 2113, 0, 2115, 0, 127907, 43713, 5052, 66220, 66653, 65777, + 65778, 65775, 5051, 65773, 1429, 42647, 5050, 65769, 388, 70685, 735, 0, + 0, 128035, 0, 12726, 0, 0, 0, 0, 0, 5109, 5053, 0, 0, 0, 0, 0, 2470, 0, + 0, 1925, 71251, 0, 10971, 113770, 5048, 5047, 0, 0, 194946, 92313, 0, 0, + 0, 8089, 0, 639, 0, 68179, 0, 70180, 0, 4599, 0, 0, 0, 0, 983798, 648, + 194948, 65819, 0, 0, 0, 0, 94017, 0, 11777, 9750, 983122, 0, 0, 92367, + 70175, 5046, 66255, 0, 0, 65253, 0, 5045, 0, 1916, 74069, 5044, 92348, 0, + 0, 5043, 0, 0, 0, 74004, 9669, 12341, 0, 8402, 0, 0, 70174, 0, 3586, + 64508, 92456, 0, 0, 119606, 0, 42628, 10069, 0, 0, 0, 0, 123, 120703, 0, + 121326, 0, 10719, 129409, 120444, 10829, 120593, 0, 12130, 0, 0, 0, 0, + 3925, 0, 0, 75065, 71112, 92372, 71110, 71111, 0, 120441, 120452, 983178, + 0, 0, 0, 0, 0, 0, 0, 0, 69879, 8509, 120449, 0, 0, 0, 120448, 0, 118889, + 194858, 0, 0, 0, 66445, 0, 71109, 0, 0, 72425, 0, 12136, 0, 0, 0, 0, 0, + 0, 19922, 41768, 74002, 0, 0, 0, 0, 2458, 0, 0, 0, 41074, 4266, 0, 0, + 41077, 0, 9050, 0, 0, 73693, 0, 0, 41075, 2476, 0, 0, 0, 69761, 0, 0, + 74202, 78745, 0, 121324, 70152, 66033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83106, + 0, 0, 0, 43693, 78753, 0, 12194, 66215, 0, 121273, 67216, 121499, 0, + 121118, 0, 78756, 0, 0, 55256, 0, 0, 0, 0, 43876, 0, 0, 0, 12948, 195003, + 195002, 195005, 195004, 195007, 195006, 0, 128320, 4287, 70183, 4902, + 74020, 0, 0, 0, 1816, 0, 0, 168, 0, 4898, 64298, 0, 78450, 4901, 1821, 0, + 43294, 3653, 0, 791, 9162, 6977, 121183, 0, 70160, 0, 73731, 8354, 0, 0, + 0, 7557, 0, 0, 8234, 194992, 78456, 194994, 194993, 194996, 194995, + 65925, 194997, 195000, 194999, 0, 195001, 0, 64397, 0, 0, 0, 71310, + 194977, 194976, 2448, 194978, 194981, 194980, 2452, 194982, 194985, + 194984, 78694, 72292, 7845, 0, 78692, 4408, 4122, 6772, 194988, 8723, + 72147, 194989, 119302, 67403, 119304, 119303, 2438, 119297, 119300, + 119299, 41953, 0, 42135, 373, 119172, 2119, 11457, 129618, 41955, 0, 0, + 0, 41952, 0, 0, 2127, 0, 128496, 5202, 0, 78765, 42823, 11291, 0, 0, + 12963, 0, 0, 4125, 41958, 12133, 0, 125099, 1271, 129427, 0, 66024, 0, + 3864, 127825, 0, 0, 0, 0, 4166, 0, 0, 0, 7459, 0, 119914, 5384, 0, 0, + 70154, 5759, 0, 0, 0, 0, 66744, 0, 120571, 0, 75066, 5552, 0, 0, 127192, + 5553, 0, 0, 0, 12906, 0, 0, 110787, 110792, 110788, 5554, 0, 12344, + 110786, 0, 0, 0, 0, 0, 8517, 0, 0, 0, 66017, 5555, 92317, 0, 983653, 0, + 0, 0, 9143, 0, 195067, 67995, 195069, 127162, 195071, 195070, 4577, + 64624, 0, 0, 125105, 983661, 4269, 983655, 983652, 983650, 0, 950, 0, + 983654, 983664, 983649, 0, 983656, 0, 119121, 0, 5098, 0, 0, 119099, + 5097, 0, 9848, 0, 10293, 983645, 72798, 0, 0, 70303, 983665, 5102, 5101, + 128370, 0, 8138, 4517, 1932, 5100, 195060, 195059, 1247, 10034, 195064, + 5099, 0, 1441, 0, 4724, 650, 0, 73954, 983266, 129348, 195040, 195043, + 9031, 195045, 195044, 195047, 8545, 66356, 195048, 0, 9154, 127243, 0, 0, + 2676, 2277, 0, 73812, 195051, 8599, 195053, 0, 195055, 65462, 0, 92524, + 195033, 71903, 0, 0, 41199, 0, 11399, 195035, 195034, 195037, 195036, + 195039, 195038, 5108, 5107, 0, 66019, 0, 0, 5541, 0, 0, 12613, 5284, 0, + 0, 128806, 4275, 74865, 854, 68147, 74381, 120918, 0, 5103, 124986, + 64348, 0, 0, 5221, 69811, 0, 0, 121163, 0, 0, 11438, 0, 0, 70158, 0, 0, + 5106, 195024, 110749, 65154, 69813, 195028, 5105, 195030, 69720, 195032, + 5104, 983761, 0, 3176, 0, 70149, 932, 0, 6567, 195009, 195008, 195011, + 195010, 70145, 43850, 195015, 195014, 195017, 195016, 0, 0, 0, 0, 10670, + 0, 13273, 0, 195020, 121370, 8803, 195021, 72431, 8151, 67145, 72436, 0, + 12553, 0, 0, 0, 0, 13065, 12570, 0, 0, 0, 983198, 124985, 0, 0, 66466, 0, + 0, 194595, 0, 194596, 11351, 43256, 0, 0, 0, 0, 41754, 0, 0, 2720, + 194975, 68462, 8232, 120760, 0, 0, 0, 0, 0, 0, 0, 93067, 10834, 0, 0, + 119266, 0, 0, 125025, 67679, 0, 75064, 7781, 0, 0, 126076, 0, 12077, 0, + 64586, 127164, 42396, 0, 3475, 0, 2479, 0, 0, 0, 120728, 0, 42434, + 194960, 194963, 194962, 110611, 67894, 42473, 194966, 110609, 1843, + 42283, 0, 0, 0, 0, 0, 194970, 0, 42321, 7284, 194974, 194973, 194950, + 194949, 194952, 194951, 0, 194953, 123614, 128645, 0, 0, 0, 0, 74952, + 194954, 194957, 194956, 66367, 194958, 41069, 67689, 9988, 0, 41068, 0, + 4295, 0, 0, 41951, 67835, 0, 785, 8236, 128647, 9027, 0, 194943, 0, 0, 0, + 0, 0, 0, 41071, 41059, 0, 92458, 129442, 0, 0, 0, 123612, 2067, 4310, 0, + 123611, 5180, 123605, 0, 73872, 0, 69880, 5184, 42385, 194947, 983755, + 128531, 0, 0, 119149, 0, 121334, 0, 983762, 0, 0, 5178, 194929, 120548, + 194931, 5188, 194933, 194932, 72245, 194934, 1166, 64429, 42639, 0, 0, 0, + 0, 128071, 2442, 10703, 194940, 194939, 194635, 42439, 0, 0, 0, 73933, + 983238, 42401, 0, 0, 0, 42288, 0, 0, 0, 13145, 0, 2468, 0, 42327, 0, 0, + 0, 42479, 0, 0, 0, 92580, 0, 74939, 120678, 0, 73733, 0, 0, 2715, 0, + 71257, 0, 74114, 0, 0, 0, 0, 0, 66325, 69603, 0, 9240, 0, 0, 129142, 0, + 0, 0, 9815, 0, 11246, 0, 73912, 42733, 0, 0, 2480, 0, 0, 0, 6494, 5537, + 0, 0, 0, 0, 1211, 0, 121379, 0, 0, 12318, 0, 113796, 0, 0, 0, 0, 0, + 64642, 0, 0, 0, 0, 64864, 0, 0, 0, 121212, 0, 0, 3589, 92719, 4035, 6492, + 92236, 4265, 6843, 0, 74186, 41778, 113764, 119216, 2488, 0, 4582, 0, + 71426, 41777, 12926, 72708, 7528, 10550, 113761, 0, 0, 11439, 0, 0, + 64878, 0, 0, 0, 0, 2286, 0, 0, 126646, 127909, 0, 400, 126500, 0, 0, 0, + 0, 0, 64827, 0, 74948, 390, 0, 71301, 0, 3473, 0, 0, 66742, 0, 55285, 0, + 0, 0, 92206, 0, 0, 8004, 0, 6763, 0, 0, 7006, 0, 0, 6757, 73707, 126648, + 0, 6766, 0, 0, 0, 6146, 0, 771, 0, 0, 41318, 0, 42272, 0, 0, 0, 0, 953, + 12917, 72287, 12300, 0, 11491, 68612, 0, 0, 71321, 7490, 11389, 7489, + 3379, 0, 7487, 72716, 7486, 7484, 7482, 6753, 7480, 7479, 7478, 7477, + 6501, 7475, 0, 7473, 7472, 2474, 7470, 7468, 124977, 0, 0, 0, 0, 71871, + 11834, 128376, 0, 6017, 0, 0, 0, 0, 0, 119365, 73949, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2472, 69945, 120699, 121133, 2139, 4256, 120776, 74380, 0, + 73847, 73844, 0, 0, 0, 0, 0, 0, 0, 0, 7083, 0, 8066, 7678, 0, 121124, 0, + 0, 0, 0, 0, 0, 0, 0, 120566, 0, 0, 0, 8330, 0, 0, 0, 0, 0, 0, 19934, 0, + 1770, 67091, 0, 128671, 129617, 110605, 110606, 73843, 110604, 0, 110602, + 67092, 0, 71334, 0, 0, 0, 0, 0, 8162, 0, 5996, 129644, 4903, 0, 0, 43063, + 0, 5172, 0, 7139, 0, 127385, 0, 0, 0, 0, 4334, 6324, 41975, 12186, 10674, + 12308, 0, 0, 0, 72807, 41977, 68002, 0, 126630, 2018, 121388, 41979, + 68003, 0, 68000, 0, 0, 126984, 68001, 9334, 0, 71440, 0, 7975, 0, 0, 0, + 66621, 4884, 70367, 983740, 0, 121010, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 0, + 69617, 6509, 5460, 0, 0, 0, 0, 42279, 0, 0, 0, 0, 0, 0, 0, 125027, 0, + 121119, 0, 0, 0, 5663, 0, 0, 0, 0, 2482, 66202, 0, 0, 42247, 65174, + 73925, 0, 100940, 0, 0, 126573, 0, 0, 2460, 0, 11944, 0, 0, 64679, + 120835, 127310, 0, 0, 0, 5870, 0, 0, 0, 100931, 539, 100933, 100932, + 100935, 9064, 100937, 100936, 100939, 100938, 0, 0, 0, 0, 0, 0, 41295, + 100941, 2478, 100943, 4162, 100945, 4260, 12953, 100950, 100949, 0, 0, 0, + 0, 0, 0, 0, 0, 5000, 0, 0, 0, 69672, 71439, 0, 74017, 0, 0, 6709, 0, 0, + 983720, 0, 0, 100922, 100921, 10301, 10333, 10397, 100925, 100928, + 100927, 0, 0, 0, 127830, 0, 4014, 12842, 0, 67413, 0, 0, 3893, 0, 0, + 12210, 0, 42147, 0, 983622, 74465, 0, 0, 0, 0, 0, 0, 0, 0, 110805, 8231, + 0, 69946, 41968, 100929, 41973, 12935, 41969, 0, 2453, 0, 0, 78807, + 122893, 0, 10349, 10413, 0, 41962, 3202, 119097, 0, 8316, 129174, 0, + 7314, 0, 0, 0, 0, 1840, 0, 0, 0, 4883, 100908, 4723, 70099, 100909, 0, 0, + 0, 0, 11089, 240, 19906, 0, 0, 0, 43600, 121004, 13134, 93065, 0, 65931, + 110649, 110650, 42634, 110648, 0, 121005, 11463, 0, 0, 0, 10445, 0, + 92969, 0, 2614, 0, 0, 1729, 0, 0, 100911, 0, 43334, 100912, 100915, + 100914, 66201, 100916, 69662, 100896, 100899, 100898, 4121, 100900, + 70272, 82954, 63879, 0, 70872, 0, 0, 4039, 643, 7726, 120082, 0, 120068, + 58, 0, 0, 0, 63872, 0, 0, 100891, 0, 10625, 100892, 100895, 100894, 1416, + 120073, 917761, 67393, 0, 0, 0, 6996, 4264, 0, 100902, 66179, 66768, + 100903, 13114, 72311, 0, 3094, 0, 0, 127074, 4437, 0, 0, 0, 55280, 42174, + 0, 42430, 0, 72246, 42355, 0, 0, 0, 0, 121251, 127401, 0, 0, 0, 0, 0, 0, + 100882, 100881, 74037, 100883, 0, 127099, 0, 0, 0, 0, 0, 69646, 65035, + 65034, 11480, 6116, 65039, 65038, 41180, 65036, 194565, 0, 12101, 5822, + 0, 0, 0, 0, 11663, 127873, 63854, 119657, 63853, 0, 0, 65810, 4289, + 100885, 63896, 100887, 100890, 43621, 0, 0, 0, 129613, 194560, 7461, + 73901, 0, 331, 0, 0, 0, 128029, 0, 0, 0, 74629, 0, 0, 0, 41964, 0, 63843, + 2084, 41965, 0, 100864, 100863, 100866, 63841, 78549, 41220, 13032, + 100869, 8383, 0, 78548, 126102, 0, 0, 1351, 983846, 8698, 100874, 100877, + 1930, 100879, 78554, 74360, 100880, 69859, 78551, 0, 0, 129433, 3657, 0, + 65202, 6000, 119206, 41901, 0, 0, 41740, 0, 41283, 0, 119267, 0, 0, + 100871, 9695, 100873, 7562, 100853, 5170, 100855, 100854, 676, 100856, + 100859, 100858, 9978, 100860, 0, 0, 64934, 0, 0, 0, 113714, 113706, + 41829, 65886, 5159, 0, 41832, 704, 43077, 0, 120532, 0, 68496, 65065, + 41830, 0, 917799, 917798, 917797, 917796, 0, 67864, 113696, 917800, + 12336, 4135, 69805, 341, 2727, 4129, 100862, 100861, 0, 64503, 7913, 0, + 0, 4131, 63868, 0, 63871, 4133, 63864, 210, 0, 0, 0, 4137, 78505, 78506, + 0, 78504, 78830, 0, 0, 43873, 0, 0, 0, 0, 11988, 78510, 195, 68321, + 41501, 0, 42031, 0, 13135, 0, 0, 0, 41499, 0, 0, 9680, 41498, 917794, + 42025, 78567, 78556, 0, 0, 0, 0, 0, 0, 101074, 120502, 92597, 0, 0, + 917784, 7864, 129001, 0, 917788, 121106, 917786, 917785, 917792, 67816, + 917790, 2219, 0, 0, 0, 0, 0, 0, 121277, 0, 917777, 917776, 917775, 69644, + 917781, 917780, 917779, 917778, 8668, 0, 121383, 917782, 5999, 0, 0, + 129195, 128243, 43653, 1726, 1015, 0, 0, 0, 0, 64919, 0, 0, 0, 128478, 0, + 69791, 927, 0, 0, 42010, 0, 42021, 0, 0, 1299, 12240, 64537, 0, 0, 0, 0, + 0, 0, 69454, 0, 0, 0, 122903, 19914, 12179, 0, 2296, 0, 0, 63832, 917773, + 0, 63816, 2594, 63823, 63817, 11178, 0, 0, 0, 11265, 68295, 0, 0, 0, + 10554, 3972, 0, 121198, 0, 917766, 10816, 917764, 119608, 74374, 917769, + 11210, 93069, 8586, 3882, 8532, 120183, 1573, 128648, 0, 69916, 0, + 101051, 67719, 0, 0, 0, 0, 0, 0, 0, 128821, 119169, 0, 0, 6626, 42763, 0, + 118884, 128613, 0, 83128, 0, 0, 0, 0, 0, 983561, 0, 0, 0, 9171, 0, 0, + 71305, 983900, 121146, 0, 0, 128881, 119604, 126596, 0, 0, 0, 128214, + 42368, 0, 983105, 2271, 41487, 12118, 74124, 68651, 110836, 110833, 3009, + 41476, 41489, 69825, 3007, 1448, 3018, 0, 41491, 8521, 5083, 5082, 0, 0, + 8519, 0, 3014, 5081, 73926, 0, 128549, 0, 69951, 5079, 0, 2557, 128086, + 65532, 11828, 0, 71297, 11105, 0, 0, 0, 8518, 10779, 0, 71303, 0, 0, + 42170, 110769, 0, 629, 1924, 0, 12037, 0, 5987, 8462, 127744, 0, 63933, + 69735, 110770, 128295, 63941, 67981, 5077, 0, 10880, 64849, 5075, 0, + 128152, 65075, 0, 11007, 983717, 0, 0, 0, 66684, 72331, 3434, 72338, + 1904, 0, 0, 72730, 0, 10499, 4507, 9578, 63925, 0, 7979, 0, 9831, 66689, + 0, 461, 0, 0, 4504, 0, 0, 6325, 0, 43021, 0, 0, 55236, 0, 0, 5177, 41324, + 12055, 63831, 0, 41327, 12591, 0, 4114, 409, 0, 0, 8948, 41325, 0, 721, + 10182, 0, 71311, 0, 0, 94052, 74963, 83503, 5998, 0, 0, 74825, 0, 12587, + 0, 78571, 74889, 71328, 128955, 0, 74121, 0, 78822, 0, 0, 5995, 0, 42568, + 0, 0, 63944, 73860, 0, 0, 4167, 0, 43175, 0, 74120, 0, 65076, 938, 73857, + 73854, 11737, 9721, 0, 0, 0, 11742, 0, 0, 11493, 12334, 128762, 0, 66623, + 0, 9173, 0, 11978, 0, 73982, 113750, 113741, 0, 6759, 0, 0, 0, 126222, 0, + 70388, 129093, 13027, 42777, 7683, 1167, 0, 4983, 0, 861, 0, 0, 68297, 0, + 43757, 92978, 129298, 0, 0, 0, 0, 70815, 9616, 0, 0, 12816, 43759, 0, + 12710, 68674, 12721, 4101, 66185, 0, 5992, 7616, 0, 0, 12577, 0, 0, 853, + 42693, 0, 121088, 0, 0, 917915, 0, 42835, 0, 0, 0, 0, 0, 12712, 7105, + 127807, 65060, 66875, 9900, 0, 0, 0, 121482, 119265, 0, 64778, 12585, 0, + 0, 0, 0, 0, 0, 77826, 0, 4900, 125245, 0, 0, 0, 4119, 74768, 8971, 0, 0, + 0, 78594, 41132, 9245, 73060, 0, 4138, 194841, 0, 0, 0, 77827, 0, 13054, + 0, 0, 128416, 110760, 0, 0, 3948, 128878, 0, 0, 0, 1680, 0, 78589, 0, 0, + 120032, 0, 0, 0, 0, 74833, 74190, 5993, 42709, 0, 12706, 77846, 1893, 0, + 63915, 0, 0, 110744, 0, 0, 63997, 120018, 63996, 3077, 0, 0, 1512, 0, + 12589, 41479, 0, 0, 0, 0, 11831, 120727, 0, 41481, 0, 118912, 0, 3090, 0, + 3086, 1664, 1850, 0, 3079, 0, 0, 94080, 127140, 0, 0, 74401, 0, 917555, + 0, 0, 0, 0, 0, 11526, 63985, 5864, 0, 63992, 0, 63991, 0, 5480, 7858, 0, + 4116, 78149, 0, 0, 0, 63907, 0, 0, 126131, 63905, 119601, 0, 983190, 0, + 119666, 0, 0, 7534, 507, 91, 2042, 120775, 0, 0, 66028, 118811, 41844, + 70680, 774, 0, 0, 0, 5994, 0, 0, 0, 0, 0, 72297, 0, 0, 0, 0, 6026, 0, 0, + 0, 162, 0, 125247, 78151, 78152, 983590, 92709, 0, 68304, 0, 0, 0, 66658, + 0, 0, 0, 0, 121511, 2226, 121512, 129349, 10492, 0, 121510, 0, 43119, 0, + 0, 0, 66192, 0, 0, 4899, 12729, 0, 0, 0, 0, 4103, 0, 0, 77851, 69429, + 129046, 0, 12859, 70087, 0, 0, 0, 0, 0, 0, 0, 0, 65264, 5146, 0, 194694, + 71684, 0, 0, 0, 983844, 0, 71688, 194693, 5147, 125019, 0, 74524, 71682, + 128435, 0, 194692, 5991, 3445, 0, 4976, 66193, 0, 0, 0, 0, 128309, 0, 0, + 0, 0, 63855, 0, 10138, 0, 0, 8897, 0, 75027, 0, 120931, 77862, 65836, 0, + 0, 77860, 0, 0, 1123, 4124, 41553, 77903, 0, 71680, 121386, 398, 0, 0, + 41551, 0, 0, 0, 41550, 9970, 0, 93062, 42392, 1305, 78901, 0, 0, 0, 7346, + 41464, 0, 0, 0, 41465, 983577, 8528, 9149, 0, 63955, 165, 3024, 11852, + 119163, 0, 9093, 0, 9147, 0, 0, 110989, 9148, 0, 4096, 53, 8296, 0, + 71352, 0, 9594, 0, 0, 63952, 0, 10997, 0, 0, 5805, 0, 0, 0, 42176, 71455, + 74601, 129604, 10591, 0, 0, 0, 0, 0, 0, 0, 0, 92475, 0, 0, 42379, 0, 0, + 9220, 0, 121425, 0, 0, 4132, 0, 0, 11239, 0, 0, 74837, 0, 66408, 0, 8055, + 0, 0, 0, 63962, 74042, 8924, 43123, 5988, 0, 63969, 0, 42718, 8788, 1357, + 77872, 65743, 0, 8774, 0, 0, 0, 0, 92748, 120598, 128234, 9564, 0, 0, + 119124, 0, 121241, 110983, 92975, 3121, 0, 0, 0, 70081, 0, 0, 0, 0, 0, + 64851, 0, 0, 73085, 119532, 0, 0, 0, 0, 1198, 0, 66708, 64619, 0, 64663, + 93991, 0, 0, 2101, 1398, 0, 92554, 0, 0, 92684, 11406, 0, 12127, 0, 840, + 0, 0, 7101, 120938, 0, 0, 12880, 0, 43104, 0, 0, 0, 2117, 0, 0, 0, 0, 0, + 0, 0, 7769, 0, 92413, 0, 0, 0, 0, 40986, 83117, 0, 0, 4127, 0, 0, 0, 0, + 0, 0, 70738, 0, 129466, 0, 0, 0, 0, 119081, 0, 10581, 0, 4533, 0, 128941, + 6490, 0, 12038, 0, 0, 68225, 0, 0, 69704, 0, 1948, 119007, 129607, + 128594, 0, 0, 0, 120802, 0, 9494, 0, 0, 0, 4843, 0, 74772, 4098, 0, 0, 0, + 3436, 0, 127279, 12817, 0, 126607, 0, 0, 0, 0, 74433, 0, 0, 0, 0, 121296, + 65916, 0, 0, 121458, 0, 129107, 93815, 0, 73743, 0, 0, 983132, 67676, 0, + 0, 74627, 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, 0, 128500, + 0, 0, 9613, 43425, 4526, 121415, 0, 64520, 71336, 0, 0, 55278, 10228, + 64957, 0, 0, 3807, 2081, 66640, 0, 0, 0, 0, 119269, 0, 128688, 0, 128142, + 1451, 0, 0, 4134, 0, 74847, 0, 74793, 0, 0, 74295, 9960, 1201, 0, 12846, + 121271, 0, 11919, 64962, 0, 43739, 0, 66358, 0, 0, 0, 43679, 72284, + 72289, 0, 129523, 1253, 983851, 65766, 500, 65764, 65765, 65762, 65763, + 65760, 65761, 70334, 983848, 9821, 11702, 110630, 110631, 110628, 110629, + 128481, 0, 7533, 66717, 92500, 92305, 0, 0, 0, 127758, 71332, 0, 0, 0, 0, + 11188, 0, 4112, 0, 0, 12890, 0, 0, 9915, 0, 68423, 0, 0, 2876, 0, 0, 0, + 0, 7382, 92415, 0, 128132, 0, 0, 0, 0, 0, 127915, 0, 7003, 0, 0, 7704, 0, + 0, 0, 4123, 0, 0, 9977, 0, 0, 65759, 0, 0, 128266, 9808, 0, 92611, 4126, + 0, 9521, 9589, 64755, 0, 0, 0, 69948, 0, 92368, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 93814, 0, 0, 92234, 0, 10693, 0, 0, 65897, 4058, 0, 0, 64660, 0, 0, 0, + 983711, 1139, 43298, 0, 71333, 8970, 0, 9934, 0, 11023, 128020, 42522, 0, + 0, 0, 78899, 3057, 128113, 7349, 121327, 128722, 68065, 110813, 0, + 128090, 67201, 0, 0, 0, 9528, 0, 0, 0, 9102, 627, 0, 6273, 129496, 0, 0, + 983210, 92966, 43300, 0, 983721, 11696, 0, 1018, 65554, 0, 74338, 0, + 7645, 0, 128321, 0, 0, 0, 0, 73814, 11544, 12563, 10728, 0, 0, 127340, + 43311, 64966, 0, 0, 0, 118946, 0, 0, 74779, 0, 185, 65085, 74533, 0, 0, + 7535, 0, 42525, 0, 9749, 41701, 6131, 0, 4117, 129062, 126988, 0, 92429, + 65693, 0, 73445, 0, 69695, 0, 0, 0, 0, 0, 0, 0, 1184, 0, 815, 0, 0, 0, 0, + 0, 71325, 0, 0, 64683, 983797, 0, 127959, 0, 0, 0, 0, 0, 0, 0, 68166, 0, + 0, 0, 0, 66799, 0, 128912, 0, 5142, 0, 69643, 0, 0, 83367, 93975, 0, 0, + 0, 123209, 0, 0, 0, 74855, 121330, 0, 0, 0, 0, 10940, 66030, 0, 70385, 0, + 0, 2652, 120527, 0, 0, 0, 126508, 0, 0, 0, 0, 0, 0, 1828, 0, 128357, 0, + 8531, 0, 74799, 12324, 72434, 65238, 68374, 0, 65573, 0, 68308, 68679, + 12904, 43445, 0, 0, 0, 11247, 0, 0, 41426, 0, 0, 0, 0, 0, 67250, 69451, + 83354, 71337, 0, 0, 0, 0, 0, 0, 637, 0, 0, 0, 121178, 0, 0, 74474, 71306, + 0, 7298, 128256, 0, 0, 0, 0, 8210, 0, 0, 0, 2046, 0, 0, 0, 70333, 0, + 1506, 69926, 0, 83353, 0, 12651, 0, 0, 0, 12058, 120626, 72111, 7803, 0, + 0, 65592, 118844, 0, 0, 355, 9719, 0, 118961, 0, 121077, 0, 0, 42178, 0, + 69760, 42571, 0, 0, 0, 0, 0, 0, 127176, 3178, 0, 0, 92704, 83381, 9080, + 120943, 67697, 0, 121342, 0, 0, 71485, 0, 917837, 0, 0, 78157, 0, 0, 0, + 0, 0, 71313, 0, 0, 128212, 0, 72238, 67858, 0, 0, 0, 0, 0, 0, 0, 10770, + 118994, 0, 465, 0, 0, 74348, 0, 0, 0, 0, 0, 0, 0, 10930, 0, 0, 0, 119091, + 69388, 983614, 0, 0, 0, 0, 0, 0, 10092, 0, 0, 0, 0, 0, 1766, 11282, + 11996, 66644, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120906, 4345, 0, 0, + 128947, 0, 0, 0, 0, 0, 5382, 0, 0, 0, 0, 0, 5406, 43127, 121139, 0, 3590, + 0, 0, 0, 0, 42016, 0, 0, 121002, 0, 7742, 0, 66562, 71323, 0, 0, 5310, 0, + 128173, 0, 43594, 0, 128260, 66723, 0, 73816, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1326, 128723, 0, 0, 74519, 0, 0, 0, 0, 71308, 0, 5410, 5783, 0, 8403, + 5400, 120526, 0, 128863, 0, 0, 0, 64412, 0, 0, 5587, 42865, 71858, 0, 0, + 0, 0, 113785, 0, 120755, 0, 69738, 0, 74867, 10461, 12103, 0, 0, 70701, + 0, 0, 0, 0, 0, 94009, 0, 0, 0, 8816, 41515, 0, 11802, 0, 7585, 910, 0, 0, + 0, 3658, 83386, 120525, 0, 7617, 0, 12888, 0, 0, 64631, 0, 41514, 11097, + 5703, 0, 41517, 41504, 41519, 0, 70104, 0, 65864, 0, 120533, 0, 121037, + 0, 0, 43553, 120774, 0, 0, 0, 0, 0, 1578, 0, 43449, 0, 0, 8225, 121191, + 94024, 72799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110655, 0, 110656, 121247, + 72213, 0, 110658, 0, 74997, 0, 3195, 10999, 983566, 7897, 0, 1203, 74396, + 0, 64544, 0, 0, 0, 2877, 0, 0, 0, 121112, 0, 0, 128977, 119607, 0, 0, 0, + 0, 983623, 0, 0, 0, 0, 0, 0, 0, 0, 983078, 0, 0, 0, 9939, 0, 0, 0, 0, 0, + 0, 0, 10714, 0, 0, 0, 0, 0, 67738, 0, 74038, 0, 42897, 0, 0, 0, 0, 0, 0, + 7730, 0, 0, 0, 11163, 0, 0, 0, 113701, 4966, 128802, 70674, 129468, + 123207, 3841, 0, 0, 983227, 77886, 0, 4972, 0, 64699, 0, 0, 0, 0, 0, + 12705, 10203, 9608, 0, 0, 11962, 121397, 0, 1196, 67684, 0, 777, 0, 0, + 65271, 0, 0, 0, 0, 64824, 983194, 0, 9454, 63778, 8658, 0, 0, 2705, 0, + 64894, 0, 0, 11986, 92636, 0, 8280, 0, 2701, 0, 0, 0, 0, 0, 9809, 0, 0, + 0, 0, 0, 63761, 1748, 0, 65719, 121078, 0, 0, 0, 55244, 3061, 0, 63765, + 63787, 0, 41520, 0, 7694, 0, 8896, 63768, 55282, 0, 127781, 0, 0, 63807, + 1591, 0, 6386, 119144, 0, 0, 0, 983199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68289, + 0, 0, 7624, 0, 10996, 92247, 10609, 0, 127181, 10987, 0, 70370, 3894, 0, + 0, 0, 0, 493, 0, 0, 1717, 12228, 479, 917941, 129347, 129473, 917935, + 917939, 917924, 917932, 92303, 64315, 0, 0, 83522, 6233, 42681, 83525, + 83518, 83519, 64911, 83521, 0, 0, 83516, 83517, 983081, 8378, 11632, 0, + 0, 7323, 0, 120771, 0, 0, 0, 0, 120904, 83526, 0, 128710, 92672, 0, 0, 0, + 0, 0, 0, 0, 63806, 63800, 0, 0, 0, 63798, 63803, 244, 11542, 0, 0, 73761, + 0, 12669, 120310, 0, 0, 0, 0, 120680, 71908, 0, 0, 8612, 0, 0, 0, 0, 0, + 64662, 125056, 1360, 248, 0, 63797, 0, 63794, 0, 7292, 983666, 63756, + 42786, 74957, 0, 12663, 0, 0, 0, 0, 0, 0, 0, 4579, 0, 0, 0, 0, 0, 0, + 71130, 65545, 9602, 8623, 0, 128052, 0, 0, 0, 0, 0, 0, 0, 659, 6098, 0, + 12234, 83511, 83512, 8311, 83514, 7669, 83508, 83509, 83510, 0, 0, 0, 0, + 983932, 0, 0, 2323, 0, 2319, 77917, 120900, 77916, 2311, 83077, 4415, + 1586, 68050, 0, 128724, 83020, 2309, 83022, 8173, 83013, 83014, 83015, + 83016, 0, 83010, 83011, 83012, 9397, 0, 9395, 9396, 9393, 9394, 9391, + 9392, 9389, 6209, 9387, 9388, 9385, 9386, 9383, 9384, 0, 0, 0, 0, 0, + 11259, 0, 0, 0, 2313, 0, 0, 0, 0, 0, 0, 10570, 65776, 110968, 0, 83006, + 83007, 11998, 83009, 83002, 83003, 83004, 66406, 0, 128780, 83000, 11818, + 9381, 9382, 9379, 9380, 9377, 9378, 9375, 9376, 1683, 9374, 0, 9372, 0, + 0, 0, 0, 127801, 0, 42029, 11079, 0, 43451, 42032, 0, 0, 0, 0, 5005, 0, + 0, 42030, 5007, 78828, 126210, 0, 4951, 110776, 0, 110775, 0, 43309, + 121222, 92172, 0, 92334, 0, 9548, 0, 119138, 71896, 0, 0, 0, 0, 0, 0, + 65691, 65580, 64361, 10496, 0, 0, 0, 917975, 0, 0, 41046, 0, 0, 0, 13177, + 0, 64703, 0, 43499, 3389, 10589, 0, 11208, 120719, 78395, 73964, 78393, + 78392, 78391, 11314, 8281, 113732, 113667, 113745, 9076, 8862, 69743, + 41052, 78397, 64766, 69821, 0, 0, 0, 82992, 82994, 10671, 82998, 82987, + 82989, 82990, 6303, 113664, 498, 64471, 82986, 0, 0, 9349, 0, 0, 0, 8031, + 2414, 0, 128999, 3231, 0, 6422, 0, 0, 119339, 2537, 78405, 41429, 78403, + 78401, 78399, 0, 0, 41433, 4719, 41431, 0, 78411, 5211, 41428, 78407, + 82983, 1772, 0, 0, 82979, 66850, 64812, 82982, 82975, 68767, 82977, + 82978, 0, 0, 0, 0, 41064, 70368, 9663, 66838, 129381, 12304, 125113, 0, + 41062, 66847, 0, 0, 41061, 70454, 0, 127187, 83049, 83050, 41509, 83054, + 83045, 83046, 83047, 83048, 0, 43184, 41507, 1958, 0, 66816, 41506, 0, 0, + 0, 120717, 0, 0, 0, 74349, 72113, 8008, 0, 0, 0, 65083, 6839, 0, 126517, + 73803, 127055, 127056, 3508, 127058, 127059, 78038, 0, 120932, 0, 6411, + 128115, 0, 0, 128832, 100930, 0, 0, 0, 0, 0, 0, 128546, 0, 0, 120914, 0, + 0, 0, 0, 917822, 128810, 983657, 65599, 0, 9966, 12607, 4948, 128070, 0, + 128149, 0, 0, 6207, 0, 6117, 73916, 0, 0, 0, 0, 68244, 41511, 0, 129489, + 127304, 0, 121289, 0, 0, 83031, 83032, 0, 41556, 0, 0, 0, 128571, 73766, + 0, 0, 0, 41510, 7953, 0, 0, 41513, 0, 0, 0, 83038, 83039, 83040, 83041, + 83034, 83035, 848, 9868, 983149, 6424, 0, 83033, 0, 0, 0, 0, 0, 0, 893, + 64576, 13299, 0, 0, 0, 71447, 0, 0, 0, 0, 8903, 0, 0, 0, 8099, 0, 0, 0, + 0, 0, 0, 0, 0, 113713, 0, 0, 0, 0, 0, 83027, 41483, 83029, 83030, 83023, + 83024, 69436, 83026, 194756, 41485, 194758, 194757, 194760, 41482, 42737, + 64588, 0, 127787, 0, 10014, 0, 0, 194763, 194762, 68785, 194764, 194767, + 194766, 0, 0, 0, 11377, 0, 0, 983792, 0, 0, 0, 9776, 0, 93824, 5215, + 194750, 13227, 8758, 194751, 128744, 0, 0, 5363, 12957, 0, 0, 129051, + 129526, 6421, 0, 0, 121304, 0, 0, 0, 0, 92625, 119070, 67895, 983943, 0, + 68608, 6482, 0, 0, 11945, 0, 0, 8838, 0, 4025, 10709, 0, 2108, 0, 73929, + 0, 0, 10617, 194737, 128031, 194739, 194738, 68614, 194740, 68611, 9924, + 194745, 194744, 0, 0, 0, 3277, 0, 4947, 41055, 0, 194722, 194721, 194724, + 194723, 64626, 194725, 42266, 194727, 8371, 194729, 127028, 12806, 41492, + 0, 0, 73930, 194731, 194730, 41054, 1078, 194735, 194734, 41057, 0, 0, 0, + 0, 0, 92210, 73009, 0, 41496, 0, 9165, 1572, 0, 917934, 0, 128635, 9215, + 9330, 0, 10032, 41745, 43183, 6401, 5831, 0, 0, 0, 8056, 0, 65681, 92377, + 0, 0, 0, 121048, 0, 118887, 6408, 0, 0, 5661, 82972, 82973, 3603, 0, + 82967, 3548, 82969, 82970, 0, 82964, 82965, 9918, 118787, 11321, 0, 0, 0, + 128992, 0, 0, 0, 0, 0, 0, 41558, 41471, 0, 8158, 41561, 41472, 0, 0, + 194672, 43762, 77927, 6701, 41559, 1896, 66256, 66248, 194680, 5665, 0, + 194681, 0, 0, 0, 74352, 0, 5664, 127895, 194682, 12310, 5662, 194687, + 194686, 73924, 1121, 82953, 82955, 0, 74378, 0, 0, 74966, 0, 71892, 0, + 69413, 194667, 8627, 194669, 10110, 194671, 42024, 6420, 42028, 0, 10509, + 2795, 73923, 0, 69231, 0, 6275, 93957, 917927, 124972, 194655, 127786, + 6423, 0, 0, 0, 68526, 12823, 0, 0, 42026, 42017, 0, 7524, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12691, 68072, 42722, 69877, 82956, 78655, 78661, 82959, + 78662, 41265, 41065, 1795, 0, 118791, 10587, 0, 983114, 0, 194640, 0, + 12946, 194641, 71921, 194643, 9169, 70372, 194648, 194647, 68202, 194649, + 73990, 65111, 0, 748, 41067, 6234, 194651, 9990, 72795, 194652, 194629, + 194628, 194631, 194630, 67896, 194632, 0, 3593, 82948, 82949, 82950, + 82951, 82944, 69729, 82946, 82947, 194638, 194637, 0, 581, 0, 42929, + 7944, 0, 0, 0, 0, 0, 0, 72143, 0, 10119, 6415, 42893, 0, 69702, 0, 0, + 11375, 0, 0, 0, 412, 92765, 42928, 42880, 43587, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65854, 92508, 65811, 75024, 194624, 194627, 9344, 8826, 92916, 0, + 125090, 74781, 0, 0, 0, 0, 0, 0, 127783, 0, 0, 0, 0, 10133, 92755, 0, 0, + 0, 0, 78414, 78413, 118950, 74011, 0, 0, 121080, 0, 1908, 127378, 4918, + 0, 0, 70709, 67825, 0, 0, 10811, 78412, 11339, 4914, 0, 0, 118971, 4917, + 70686, 0, 0, 4912, 69722, 73845, 0, 0, 129527, 0, 0, 0, 118986, 0, 0, + 74317, 0, 8319, 194714, 194717, 10960, 72196, 8305, 12573, 983620, 72193, + 0, 13202, 0, 12582, 0, 72198, 69856, 0, 0, 78598, 0, 72195, 0, 65802, + 74822, 7698, 12708, 74045, 0, 0, 70460, 4913, 127990, 0, 0, 0, 0, 12728, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 12588, 8821, 6153, 194705, 78900, 194707, + 194710, 194709, 194712, 194711, 118854, 194713, 651, 0, 0, 0, 0, 0, + 78468, 78469, 69433, 78467, 69614, 74905, 194695, 78461, 194697, 194696, + 0, 4716, 43277, 0, 78474, 78475, 128592, 120928, 194700, 55264, 194702, + 120676, 0, 12707, 0, 0, 0, 0, 121417, 8479, 4151, 0, 0, 0, 0, 0, 0, 0, 0, + 113799, 0, 74050, 0, 0, 0, 0, 0, 129467, 12278, 0, 129507, 0, 2700, + 12576, 7842, 0, 0, 0, 2699, 0, 0, 2985, 0, 126475, 0, 0, 119314, 0, + 119312, 9827, 119310, 119311, 119308, 119309, 119306, 11481, 0, 119305, + 0, 35, 78481, 78482, 66694, 78480, 78477, 78478, 0, 0, 64257, 0, 0, 0, + 78485, 78486, 78483, 4272, 0, 0, 40965, 0, 12704, 78487, 983588, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5244, 4189, 94108, 0, 127948, 4188, 1879, 0, 0, 0, + 43743, 0, 8873, 2279, 0, 0, 0, 12574, 0, 92749, 92753, 983902, 0, 0, + 75001, 0, 0, 0, 12578, 12720, 128628, 101088, 0, 12346, 128596, 101089, + 0, 0, 7251, 0, 0, 118850, 73025, 0, 0, 0, 0, 0, 12564, 66457, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 41564, 10976, 0, 121223, 0, 0, 10054, 9197, + 120618, 0, 9012, 65737, 74420, 0, 13215, 12730, 0, 0, 0, 0, 816, 0, + 129462, 0, 83191, 0, 0, 92752, 0, 4715, 94107, 94106, 71075, 0, 0, 0, + 67729, 0, 307, 0, 9585, 0, 0, 0, 0, 0, 125267, 0, 70727, 65567, 120498, + 75006, 120984, 983890, 0, 12236, 41419, 194618, 194621, 194620, 75003, + 194622, 73675, 120957, 41421, 75005, 4462, 0, 126599, 983892, 821, 0, + 2498, 5800, 100834, 100833, 1760, 94019, 4469, 64377, 100840, 100839, 0, + 757, 1185, 0, 100841, 0, 10628, 100842, 68849, 100844, 43971, 100846, + 100849, 64763, 0, 7713, 0, 0, 0, 4380, 194608, 128073, 194610, 194609, + 194612, 862, 65626, 194613, 65627, 65629, 5137, 194617, 0, 0, 0, 65069, + 7566, 64688, 67143, 194592, 100823, 100822, 100825, 4748, 92228, 100826, + 100829, 42260, 129494, 64107, 0, 0, 0, 0, 128189, 0, 194604, 13137, 8775, + 127945, 123633, 194607, 0, 8410, 4454, 194585, 0, 92542, 4449, 92330, + 127064, 75022, 92761, 70664, 194589, 339, 194591, 194590, 0, 70662, 0, + 100830, 41543, 0, 0, 0, 41542, 127066, 8916, 6705, 0, 129296, 0, 0, 0, 0, + 0, 41548, 6729, 119329, 0, 7348, 0, 0, 7537, 0, 11819, 0, 0, 123624, + 71269, 0, 7344, 100808, 129595, 9780, 0, 11117, 74993, 0, 194578, 10483, + 194580, 194579, 194582, 194581, 68781, 125114, 100820, 100819, 0, 4211, + 1259, 7517, 0, 0, 194561, 70827, 194563, 194562, 641, 5219, 94034, + 194566, 11064, 194568, 0, 0, 0, 0, 0, 0, 100812, 100811, 100814, 100813, + 100816, 100815, 100818, 100817, 100798, 100797, 41410, 100799, 64262, 0, + 41407, 75000, 0, 0, 93812, 0, 0, 72803, 74999, 78897, 0, 0, 67675, 0, 0, + 0, 0, 43647, 0, 0, 100792, 100791, 100794, 100793, 100796, 100795, 0, + 74630, 11933, 0, 0, 41903, 67892, 11001, 100801, 42255, 100803, 100802, + 100805, 41905, 100807, 100806, 10775, 9793, 0, 0, 74452, 0, 983063, + 42535, 0, 64529, 41408, 42853, 0, 0, 42674, 118915, 0, 0, 983788, 0, + 70838, 0, 0, 0, 64506, 0, 66738, 4747, 100783, 69844, 100785, 5832, 0, 0, + 5141, 42600, 0, 0, 0, 0, 0, 0, 93790, 0, 7657, 0, 71132, 74137, 0, + 128362, 73682, 73681, 859, 0, 0, 0, 6059, 126985, 55235, 0, 0, 0, 0, 0, + 100787, 11488, 72838, 100788, 0, 100790, 10558, 0, 0, 0, 126090, 71069, + 0, 0, 1788, 0, 0, 0, 0, 119571, 917961, 9028, 0, 69234, 73665, 0, 9905, + 128485, 41242, 70086, 0, 74109, 100765, 100764, 100767, 100766, 70830, + 83184, 70082, 3940, 0, 43754, 0, 128188, 8665, 0, 0, 0, 1653, 100775, + 42406, 100777, 100780, 70825, 120523, 0, 8815, 0, 65046, 0, 42445, 0, + 11180, 119318, 119315, 68454, 42485, 0, 0, 8211, 42293, 983602, 0, 0, 0, + 0, 65385, 100771, 42332, 100773, 78431, 78432, 78423, 78430, 78420, + 10022, 65387, 78419, 65384, 0, 0, 0, 65386, 0, 11248, 0, 43198, 64751, 0, + 0, 0, 0, 0, 0, 101102, 7363, 0, 0, 119323, 119324, 100752, 100751, 0, + 119320, 0, 983632, 0, 8237, 0, 0, 0, 0, 0, 0, 9914, 0, 100763, 100762, + 120009, 6351, 119993, 92740, 68766, 0, 120010, 41243, 0, 74108, 11467, + 120165, 119998, 4358, 0, 6353, 0, 0, 0, 93045, 1710, 0, 0, 92237, 0, 49, + 73871, 0, 78671, 0, 78672, 9741, 78443, 78444, 78441, 43443, 78439, + 78440, 69244, 78438, 3470, 0, 0, 0, 0, 0, 78445, 0, 1072, 78457, 78452, + 78454, 74230, 78451, 78447, 78449, 1080, 0, 74100, 0, 1101, 68404, 78458, + 78459, 71082, 0, 1086, 1869, 0, 0, 0, 65458, 0, 0, 41988, 0, 1091, 0, + 7977, 0, 67395, 0, 0, 0, 92758, 0, 0, 0, 0, 0, 71255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 64582, 0, 0, 70794, 0, 120989, 128495, 74106, 0, 66883, 0, 0, 0, + 0, 0, 0, 0, 92553, 43752, 110592, 0, 0, 120886, 0, 0, 0, 0, 6063, 100857, + 0, 917995, 6053, 74096, 0, 0, 74169, 13100, 0, 917999, 0, 917998, 0, + 70387, 6055, 7800, 4279, 8490, 120114, 120111, 64786, 8602, 120110, + 83389, 92204, 0, 0, 74961, 0, 120117, 120118, 120099, 120100, 65087, + 64402, 3674, 120096, 0, 120094, 120107, 120108, 120105, 10107, 42159, + 42870, 120101, 69632, 0, 0, 43281, 127078, 0, 74098, 0, 0, 126497, 74099, + 129056, 0, 0, 0, 121123, 5847, 125258, 0, 0, 0, 0, 0, 66592, 64469, + 71698, 19966, 0, 42561, 0, 129170, 66854, 8120, 75042, 0, 0, 0, 0, 0, 0, + 126068, 8369, 0, 0, 122912, 3369, 0, 121094, 0, 0, 69238, 10495, 121365, + 0, 557, 9457, 0, 0, 121054, 73880, 127220, 0, 74937, 74094, 0, 0, 0, + 92171, 127219, 128175, 127939, 120424, 0, 127214, 2109, 67893, 127211, + 69656, 127217, 10604, 127215, 0, 0, 0, 0, 126561, 0, 0, 0, 0, 1618, 0, 0, + 83175, 10430, 0, 0, 13063, 917585, 0, 92982, 113666, 0, 78390, 83489, + 12060, 0, 113669, 0, 6329, 0, 0, 0, 74395, 2707, 8309, 0, 127054, 78398, + 0, 2697, 0, 78396, 127057, 2695, 0, 0, 68334, 0, 0, 0, 72325, 2693, + 74091, 0, 0, 2703, 113729, 70283, 41918, 983168, 127542, 8687, 127543, + 12178, 43361, 92540, 64075, 110705, 5248, 110703, 120538, 6427, 0, 0, 0, + 0, 110710, 0, 74990, 74989, 70703, 127031, 0, 9873, 0, 0, 0, 64762, 2053, + 0, 6591, 9340, 0, 1589, 0, 296, 67712, 128315, 12766, 118931, 74370, + 120417, 8922, 128068, 43829, 111202, 74836, 0, 12579, 0, 12575, 6416, + 5656, 0, 13262, 65590, 5299, 0, 0, 5449, 1252, 0, 78404, 0, 74369, 65373, + 5295, 0, 121066, 1223, 1642, 78408, 0, 12158, 5303, 0, 120546, 41413, + 3212, 127025, 3211, 74810, 41425, 127029, 0, 74450, 9728, 0, 10924, + 74778, 6636, 0, 0, 0, 0, 0, 9519, 0, 0, 983928, 129439, 68780, 0, 0, 0, + 126260, 0, 12104, 77942, 77951, 9004, 0, 74249, 10230, 0, 0, 0, 77947, 0, + 69679, 121475, 9890, 125049, 12971, 0, 92556, 0, 67903, 70051, 983905, 0, + 0, 9635, 12600, 0, 0, 0, 0, 6469, 0, 0, 65304, 4679, 0, 64300, 64867, + 6531, 0, 101099, 101098, 0, 101100, 42916, 0, 0, 0, 0, 0, 0, 4445, 72296, + 0, 11533, 0, 3416, 129148, 0, 0, 0, 78566, 0, 0, 101091, 0, 101093, 5447, + 72140, 101094, 101097, 101096, 0, 0, 0, 64448, 0, 43920, 70677, 0, 6232, + 101101, 101104, 101103, 43608, 101105, 0, 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, + 0, 10862, 0, 0, 41416, 0, 4173, 0, 0, 0, 1906, 0, 41418, 74073, 101068, + 101067, 41415, 69622, 9582, 0, 64287, 0, 0, 11428, 1730, 0, 0, 19918, + 10469, 101076, 101079, 68088, 0, 101080, 72342, 0, 0, 0, 6129, 0, 0, 0, + 0, 7874, 0, 0, 11206, 13136, 0, 129305, 0, 64374, 74925, 0, 73892, 0, + 101073, 101072, 101075, 74960, 9228, 101054, 101057, 101056, 5240, 9811, + 0, 101060, 0, 0, 0, 74079, 65873, 0, 0, 0, 9501, 0, 68081, 72808, 65465, + 64654, 7467, 0, 0, 83460, 10040, 0, 3096, 0, 101053, 101052, 68820, + 83461, 0, 0, 0, 0, 0, 0, 0, 0, 68801, 0, 101062, 101061, 101064, 101063, + 0, 8637, 70741, 0, 77983, 77969, 11471, 43554, 0, 77968, 0, 0, 0, 2426, + 12042, 0, 0, 0, 3961, 12115, 129633, 0, 77972, 64561, 0, 4981, 74644, + 129558, 0, 0, 42686, 77976, 128776, 64686, 0, 77958, 7589, 0, 0, 3237, 0, + 68215, 0, 8541, 127157, 71067, 0, 0, 0, 0, 0, 0, 43555, 0, 0, 10060, + 111261, 100917, 0, 0, 0, 64877, 0, 0, 8614, 65220, 41493, 0, 0, 0, 43780, + 0, 0, 70689, 0, 0, 0, 0, 0, 0, 4012, 10395, 0, 0, 111253, 126511, 111254, + 125051, 695, 739, 696, 7611, 0, 42755, 68421, 9227, 7506, 7510, 69937, + 691, 738, 7511, 7512, 7515, 7501, 688, 41847, 690, 2548, 737, 974, 43386, + 0, 0, 0, 0, 0, 0, 65860, 0, 7051, 69777, 4682, 0, 983096, 6406, 4685, 0, + 0, 10347, 4680, 6341, 0, 0, 92607, 74325, 0, 0, 0, 0, 0, 0, 0, 0, 43505, + 92468, 11718, 42373, 11714, 0, 0, 129567, 11717, 0, 10594, 0, 11712, 0, + 0, 10967, 0, 0, 0, 66632, 0, 0, 0, 0, 1735, 0, 11134, 2363, 983135, 0, 0, + 70695, 128032, 0, 7491, 7495, 7580, 7496, 7497, 7584, 121478, 127853, 0, + 0, 128375, 0, 8498, 0, 8949, 3065, 0, 0, 0, 0, 0, 0, 11713, 0, 64939, 0, + 6418, 4543, 0, 0, 0, 74800, 0, 0, 0, 0, 0, 0, 0, 12282, 0, 0, 0, 64556, + 0, 9238, 0, 68063, 0, 0, 0, 65438, 0, 128525, 0, 119268, 0, 0, 12900, 0, + 10950, 0, 0, 0, 41400, 126636, 119664, 0, 42232, 0, 1744, 0, 41402, 0, 0, + 0, 41399, 0, 125028, 0, 0, 12690, 0, 0, 43672, 0, 0, 0, 100870, 11315, 0, + 278, 121204, 41405, 129345, 0, 10077, 129650, 70667, 0, 0, 0, 68210, 0, + 0, 11189, 70657, 0, 0, 0, 7934, 0, 93829, 120940, 0, 0, 0, 0, 0, 0, 6413, + 6550, 0, 1940, 2809, 43637, 70045, 0, 0, 10678, 0, 0, 0, 0, 78804, 6403, + 6556, 78803, 0, 0, 0, 0, 0, 0, 0, 0, 3742, 74408, 3959, 0, 0, 917969, 0, + 0, 128024, 0, 0, 127956, 0, 0, 0, 0, 4676, 983049, 9210, 0, 78143, + 983903, 0, 78168, 983100, 11540, 43546, 6692, 0, 0, 0, 0, 9083, 0, 0, + 78144, 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, + 69709, 78177, 63828, 0, 0, 0, 70282, 0, 0, 0, 64822, 0, 6530, 0, 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, + 74394, 0, 10653, 0, 0, 0, 0, 6560, 7016, 74274, 983627, 43556, 3929, + 123615, 6614, 2768, 0, 65609, 0, 11811, 0, 0, 0, 127513, 0, 6554, 0, + 6305, 66283, 4675, 118826, 78552, 0, 0, 74361, 0, 0, 68108, 0, 0, 92232, + 0, 93022, 7392, 8230, 9365, 983723, 0, 0, 0, 0, 42925, 0, 0, 0, 0, 229, + 43834, 119884, 0, 43552, 119881, 119880, 119883, 119882, 119877, 119876, + 119879, 119878, 119873, 119872, 119875, 119874, 0, 0, 0, 0, 0, 66352, 0, + 0, 0, 128663, 0, 12239, 0, 0, 10432, 12097, 0, 194815, 1233, 0, 0, + 127200, 0, 66395, 0, 0, 129504, 0, 0, 0, 0, 2388, 92555, 119868, 119871, + 119870, 119865, 895, 92668, 119866, 64889, 7143, 119863, 119862, 0, 0, + 69983, 0, 74376, 3053, 0, 0, 2047, 0, 0, 0, 121279, 67985, 194801, 92600, + 194803, 194802, 194805, 194804, 194807, 194806, 129134, 194808, 0, 0, 0, + 10473, 129331, 0, 194810, 0, 194812, 194811, 194814, 194813, 123195, + 43528, 69673, 194791, 0, 194793, 1912, 120779, 10306, 10370, 0, 0, 8867, + 10250, 10258, 10274, 1635, 120152, 0, 0, 0, 129379, 0, 0, 9919, 120148, + 559, 128157, 41825, 127975, 92989, 0, 74016, 194781, 6542, 41957, 7318, + 0, 0, 41956, 65749, 65750, 65751, 121323, 64487, 0, 0, 10223, 42062, + 100640, 0, 125044, 3668, 65754, 43560, 12226, 0, 93973, 194784, 41959, + 194786, 194785, 194788, 43618, 65747, 10937, 2962, 0, 2953, 10062, 65745, + 71457, 8921, 66013, 129370, 0, 194769, 194768, 43409, 194770, 2949, + 194772, 194775, 194774, 2958, 194776, 74868, 2300, 2951, 120061, 0, + 120043, 194778, 0, 120051, 194779, 120056, 120065, 70798, 120048, 0, + 120062, 120055, 78178, 100668, 0, 0, 92269, 0, 0, 70796, 127818, 0, 0, + 64890, 0, 43630, 11336, 799, 0, 10276, 10308, 10372, 917541, 0, 0, 10252, + 10260, 68220, 55284, 0, 0, 10384, 0, 0, 0, 64523, 0, 0, 65736, 0, 0, 0, + 0, 0, 0, 0, 0, 43549, 65738, 42150, 65739, 0, 78195, 10288, 10320, 0, + 10596, 0, 67673, 65045, 121283, 78198, 2049, 10098, 0, 122904, 127943, + 10264, 10280, 10312, 10376, 7013, 0, 0, 0, 0, 66375, 0, 4862, 0, 6537, 0, + 128335, 3914, 92178, 93976, 9065, 64816, 0, 72218, 73026, 0, 0, 72139, + 4694, 11420, 4690, 0, 0, 983209, 4693, 0, 0, 0, 4688, 0, 0, 0, 0, 8238, + 3110, 0, 983920, 0, 6528, 0, 0, 0, 218, 0, 1520, 129577, 70039, 0, + 983594, 0, 0, 78167, 10088, 6548, 100786, 0, 0, 0, 8888, 0, 124954, 0, 0, + 126593, 68876, 0, 0, 0, 0, 0, 0, 0, 4689, 43541, 77954, 120157, 0, + 120156, 78810, 120163, 0, 0, 0, 0, 78121, 0, 0, 11450, 0, 71900, 92613, + 0, 121317, 74622, 128720, 9244, 0, 0, 127763, 0, 0, 0, 0, 0, 0, 71084, 0, + 0, 0, 0, 10513, 0, 0, 0, 52, 119178, 0, 0, 93961, 0, 0, 4812, 0, 0, 0, 0, + 0, 0, 128425, 0, 120453, 0, 77959, 10170, 120450, 6544, 0, 0, 69782, + 121517, 0, 0, 65258, 10369, 0, 1585, 74014, 10249, 422, 1500, 2036, 986, + 0, 64394, 0, 5599, 917981, 2494, 0, 0, 74021, 983877, 78203, 127808, 0, + 72871, 65102, 8961, 74305, 10243, 10245, 128170, 0, 0, 0, 0, 0, 2508, + 129591, 120440, 0, 120439, 0, 0, 0, 0, 0, 0, 64533, 983186, 0, 0, 74008, + 0, 0, 43375, 0, 2504, 0, 121313, 0, 983922, 6943, 0, 5859, 100677, 0, 0, + 72873, 983926, 0, 0, 983904, 92390, 2753, 1936, 2153, 67701, 2751, 12662, + 2763, 8953, 0, 10731, 0, 7052, 0, 0, 0, 0, 119899, 0, 66675, 0, 119897, + 0, 71053, 0, 119903, 0, 67829, 7899, 119901, 71119, 43798, 7072, 119902, + 122898, 11260, 0, 71059, 0, 0, 212, 0, 12350, 0, 0, 0, 0, 0, 128402, + 2759, 0, 0, 93064, 0, 0, 0, 1291, 0, 0, 121318, 119911, 0, 119910, 0, + 12062, 0, 121216, 0, 0, 121044, 120611, 8246, 0, 0, 0, 0, 0, 0, 73962, 0, + 0, 43524, 0, 64426, 0, 0, 0, 0, 65664, 6693, 0, 0, 8674, 0, 128812, 0, + 11846, 70690, 121461, 69395, 4811, 0, 5986, 0, 3046, 74480, 5985, 0, 0, + 0, 0, 12187, 83148, 71041, 5984, 0, 93817, 4393, 126264, 120206, 917599, + 0, 0, 0, 93806, 93805, 0, 3491, 0, 67146, 0, 93819, 0, 72428, 0, 0, 0, + 124968, 41284, 126228, 0, 0, 41287, 0, 100689, 0, 0, 92189, 0, 0, 219, + 120874, 0, 0, 0, 68485, 119672, 43241, 0, 7147, 0, 0, 0, 0, 0, 0, 64610, + 11804, 0, 7149, 64808, 0, 0, 0, 92301, 73690, 0, 5253, 0, 0, 0, 0, + 129045, 983596, 11098, 68433, 0, 120484, 111009, 0, 0, 0, 0, 0, 70801, + 100779, 0, 128198, 9604, 0, 0, 0, 0, 118941, 64392, 0, 0, 0, 0, 41974, + 126262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983239, 5308, 0, 290, 0, 125278, + 128382, 2792, 0, 0, 120521, 0, 126237, 0, 126099, 0, 0, 0, 0, 128503, 0, + 0, 72816, 0, 0, 0, 92671, 0, 0, 42646, 7606, 2591, 73896, 0, 43513, + 64482, 0, 0, 65270, 0, 0, 983682, 9112, 0, 113763, 9490, 0, 0, 0, 0, 0, + 9071, 0, 0, 0, 0, 74607, 0, 2535, 65504, 43602, 0, 0, 71256, 0, 0, + 123147, 11845, 11006, 92315, 7807, 8073, 0, 10629, 0, 74088, 0, 10823, 0, + 113762, 8762, 0, 69689, 0, 43969, 65047, 10737, 3463, 72858, 129585, + 66645, 0, 4815, 0, 0, 12345, 983742, 0, 5195, 0, 0, 66639, 0, 0, 127316, + 0, 92759, 92385, 1262, 0, 6561, 19939, 0, 0, 100772, 123160, 0, 0, + 100774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5702, 3655, 0, 8430, 0, + 68807, 0, 0, 121137, 0, 0, 5254, 0, 0, 0, 0, 119107, 5129, 0, 70816, 0, + 92280, 5614, 0, 0, 11720, 0, 11721, 70804, 4798, 0, 120541, 66038, 4793, + 67851, 7352, 0, 0, 0, 0, 917600, 0, 300, 0, 0, 128575, 92660, 0, 0, 2562, + 70156, 120856, 0, 0, 92738, 0, 0, 127820, 71093, 0, 127969, 128221, 0, + 3424, 93843, 0, 0, 7074, 70873, 917926, 0, 0, 10832, 0, 0, 69852, 72430, + 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1215, 0, 5744, 0, 66440, 0, 0, 0, + 42881, 0, 8980, 118988, 67861, 8844, 7433, 0, 0, 4278, 0, 0, 0, 70821, + 9312, 4348, 0, 128401, 65946, 0, 7087, 5255, 0, 661, 0, 0, 0, 0, 0, 0, 0, + 129073, 73694, 0, 123154, 0, 73688, 0, 127179, 3621, 83325, 66666, 72968, + 0, 6562, 12928, 0, 73991, 0, 0, 11383, 0, 0, 65588, 120739, 0, 0, 0, 0, + 0, 0, 0, 0, 11436, 2070, 64, 110824, 0, 10291, 10323, 10387, 0, 0, 0, + 42008, 9708, 42710, 0, 42011, 0, 92164, 0, 0, 1702, 1240, 128383, 6286, + 9689, 111080, 0, 0, 0, 1765, 0, 0, 92373, 0, 0, 0, 8401, 72991, 42014, 0, + 67237, 0, 0, 0, 0, 0, 0, 0, 70819, 0, 0, 0, 0, 12667, 0, 0, 10147, 0, + 127568, 126483, 72812, 0, 0, 0, 0, 123139, 128968, 0, 64947, 0, 0, 0, 0, + 10435, 11462, 0, 7084, 0, 0, 0, 0, 0, 126084, 0, 66662, 0, 0, 0, 0, + 125134, 0, 0, 77990, 263, 983728, 41288, 0, 0, 78387, 74340, 70313, + 129140, 0, 0, 0, 42022, 71265, 0, 0, 0, 0, 0, 0, 42020, 123146, 0, 6992, + 42019, 0, 41290, 0, 12295, 126233, 71304, 0, 0, 71300, 120631, 5954, + 64931, 69385, 100699, 198, 68453, 78129, 0, 121351, 0, 70818, 13165, + 7107, 0, 42804, 678, 72850, 118960, 0, 72985, 42806, 42808, 0, 0, 2097, + 0, 120560, 70823, 0, 0, 3892, 68632, 0, 6712, 917959, 0, 0, 0, 0, 123158, + 69954, 0, 497, 12100, 5953, 92667, 7796, 0, 43254, 0, 0, 11072, 5952, + 1281, 43747, 0, 69380, 10677, 0, 0, 0, 1859, 0, 72856, 3425, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 65199, 1738, 0, 122911, 0, 0, 0, 11101, 0, 0, 0, 0, + 127002, 69651, 4436, 194683, 73984, 0, 70305, 64872, 128296, 0, 0, 0, + 121377, 0, 0, 0, 43686, 983108, 0, 119109, 0, 70826, 319, 0, 43479, + 73001, 0, 0, 12849, 0, 7640, 71083, 9673, 0, 0, 0, 92670, 0, 92665, + 113717, 41422, 0, 100708, 74941, 3772, 0, 120660, 5011, 0, 0, 126587, + 111315, 0, 0, 6677, 111312, 0, 41427, 64419, 129445, 92262, 0, 70799, 0, + 0, 0, 6106, 0, 41271, 6760, 983739, 4534, 41270, 128876, 0, 0, 119561, 0, + 0, 3671, 8976, 123177, 0, 41275, 0, 128084, 55261, 0, 42013, 0, 568, 0, + 41273, 0, 0, 6728, 0, 9715, 0, 0, 121058, 74820, 0, 92268, 0, 194564, + 11191, 43688, 128023, 0, 0, 0, 126266, 0, 0, 0, 11958, 11165, 0, 125087, + 0, 0, 66336, 127944, 0, 0, 0, 0, 42858, 11789, 72878, 5557, 0, 69444, + 7300, 0, 9467, 5558, 64486, 43844, 0, 0, 6706, 10146, 0, 127185, 64566, + 0, 0, 0, 0, 0, 0, 0, 4546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64528, 123136, + 6307, 128966, 0, 7544, 0, 43469, 111317, 0, 10152, 0, 65091, 0, 0, 0, 0, + 66652, 0, 0, 0, 0, 64823, 5559, 0, 70711, 6702, 5556, 0, 0, 0, 0, 0, + 11166, 0, 0, 5506, 0, 1911, 73021, 0, 12598, 8845, 66698, 0, 73012, + 123145, 0, 2098, 0, 0, 0, 66622, 194678, 0, 0, 0, 9898, 0, 0, 7552, 0, 0, + 0, 7223, 65723, 0, 0, 0, 7024, 65728, 127155, 1210, 0, 65175, 10184, + 65726, 43654, 0, 0, 0, 38, 65729, 66669, 0, 0, 0, 0, 0, 0, 0, 0, 74233, + 73018, 119843, 42860, 111301, 92576, 65721, 65722, 0, 0, 0, 0, 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, 0, 0, 126219, 0, 0, 1837, + 125086, 0, 0, 0, 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, + 65716, 10403, 127005, 0, 41449, 0, 74028, 127213, 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, + 0, 0, 0, 128270, 0, 0, 3115, 0, 10106, 127862, 118842, 0, 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, + 9221, 12590, 73048, 0, 0, 0, 67741, 111294, 12619, 0, 10154, 111266, + 74439, 2039, 0, 7446, 0, 111276, 10974, 458, 72831, 0, 0, 0, 11916, 0, 0, + 69671, 0, 121057, 12288, 0, 111288, 0, 111289, 983176, 0, 128199, 13080, + 0, 67828, 6610, 6030, 8059, 7508, 123170, 0, 0, 0, 0, 41278, 129393, 0, + 128192, 41277, 64658, 983983, 0, 6625, 983159, 19904, 0, 0, 0, 0, 0, 0, + 833, 0, 6369, 0, 0, 42664, 0, 0, 0, 0, 0, 0, 6913, 933, 1341, 68828, + 6720, 0, 0, 983604, 0, 0, 7405, 128025, 0, 0, 0, 0, 0, 0, 0, 70704, 0, 0, + 0, 0, 9716, 0, 0, 0, 70719, 0, 0, 0, 0, 72862, 70687, 0, 93987, 0, 0, 0, + 70721, 9573, 0, 0, 111245, 83225, 83226, 6949, 126482, 74061, 83222, + 83223, 83224, 0, 19962, 83219, 83220, 0, 111233, 0, 42830, 0, 111234, + 74236, 66276, 0, 546, 72861, 0, 70661, 0, 472, 11083, 10319, 10383, + 917971, 0, 83202, 83203, 3602, 83206, 41182, 83199, 83200, 69796, 41183, + 0, 10271, 10287, 684, 0, 0, 0, 83214, 4592, 83216, 83217, 83210, 11963, + 43620, 83213, 0, 0, 83208, 83209, 0, 92623, 128559, 3415, 0, 121267, 0, + 0, 123151, 43447, 0, 92212, 0, 418, 0, 0, 10295, 10327, 10391, 0, 83189, + 83190, 83192, 83194, 83185, 83186, 83187, 83188, 120879, 0, 41446, 70700, + 0, 0, 120809, 10599, 66892, 0, 0, 0, 0, 0, 0, 11437, 0, 0, 0, 0, 0, 0, + 12624, 0, 41185, 72865, 69439, 8159, 0, 11686, 71478, 65224, 0, 4655, 0, + 0, 92183, 0, 10343, 10407, 0, 0, 0, 111221, 0, 0, 0, 94057, 68201, + 129574, 0, 983568, 72156, 42792, 5743, 10424, 0, 0, 0, 0, 0, 8875, + 111225, 0, 917991, 13117, 12847, 4651, 118917, 0, 962, 0, 0, 64705, + 42564, 0, 1582, 0, 5508, 0, 0, 0, 10801, 123602, 118798, 73705, 0, 66911, + 10439, 66891, 0, 0, 7860, 0, 906, 917985, 0, 6405, 64722, 0, 83266, + 64694, 83268, 917990, 1153, 83263, 64788, 83265, 0, 12626, 83260, 83261, + 9964, 0, 0, 4642, 66574, 127886, 0, 0, 0, 0, 0, 9008, 100847, 0, 0, 0, + 83248, 917976, 917993, 123173, 42842, 83244, 83245, 83247, 83239, 83240, + 83241, 83242, 0, 11335, 92661, 83238, 3920, 0, 0, 0, 83255, 83256, 41967, + 83258, 83251, 83252, 83253, 8920, 0, 0, 83249, 83250, 0, 0, 43919, 0, 0, + 0, 0, 128021, 0, 68113, 65196, 0, 0, 128472, 0, 10111, 64875, 0, 83491, + 43998, 83232, 83233, 83234, 70691, 83228, 42149, 83230, 68508, 0, 0, 0, + 0, 0, 0, 0, 4110, 66005, 74034, 0, 0, 0, 66703, 0, 0, 983157, 6025, + 69242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70733, 0, 983043, 0, 0, 0, 68817, 0, 0, + 0, 0, 0, 0, 43286, 0, 68765, 0, 0, 0, 0, 983133, 65144, 0, 0, 83236, + 65840, 0, 0, 10081, 0, 0, 983893, 0, 0, 0, 127394, 65882, 0, 128758, 0, + 0, 3605, 10985, 0, 0, 128872, 93972, 1745, 0, 73835, 0, 0, 0, 0, 0, 0, + 8806, 7023, 0, 0, 0, 70702, 70304, 0, 0, 0, 0, 0, 0, 0, 0, 348, 10089, 0, + 9017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42515, 0, 0, 0, 0, 5391, 983236, 0, 0, + 0, 5561, 0, 9429, 0, 67150, 7933, 5562, 0, 0, 0, 0, 78039, 0, 0, 0, 0, + 3979, 71248, 0, 0, 0, 68847, 0, 0, 118847, 65847, 68836, 68838, 0, 10585, + 0, 92676, 7334, 0, 0, 0, 831, 0, 0, 10716, 0, 121325, 0, 12218, 0, 6939, + 70697, 65042, 0, 0, 916, 0, 0, 11968, 0, 0, 5563, 0, 0, 128830, 5560, + 41212, 41774, 0, 4497, 0, 0, 0, 9039, 70678, 41776, 0, 8716, 3567, + 119252, 0, 0, 74260, 0, 93954, 0, 0, 100827, 0, 128879, 70072, 68355, + 68357, 0, 0, 8634, 0, 0, 4209, 120702, 68832, 65879, 68825, 68819, 68822, + 0, 5679, 68813, 68815, 68811, 68812, 64697, 5678, 11821, 68802, 93969, 0, + 0, 0, 0, 70114, 0, 0, 0, 0, 0, 0, 0, 0, 7782, 0, 0, 0, 0, 0, 65711, + 65712, 1216, 0, 69409, 5792, 0, 0, 0, 0, 0, 12244, 0, 5683, 0, 120895, + 121336, 43448, 70670, 0, 0, 5682, 10242, 75043, 74520, 5680, 917568, + 10001, 0, 0, 1449, 10241, 0, 70708, 0, 0, 83180, 83182, 83183, 8584, + 83176, 5567, 83178, 83179, 0, 5564, 42886, 42884, 42882, 5565, 119022, + 120881, 0, 65708, 65709, 5566, 0, 65704, 65705, 11904, 42875, 0, 42873, + 5942, 0, 0, 10361, 10425, 65697, 65698, 65699, 0, 66598, 0, 64664, 10647, + 78702, 78703, 78690, 78700, 0, 65701, 1934, 0, 0, 0, 78710, 0, 78706, + 78709, 6087, 78705, 78716, 78719, 78711, 8043, 8950, 65694, 64485, 0, + 10457, 0, 78724, 78725, 78722, 72332, 78720, 78721, 0, 65515, 0, 10035, + 13069, 0, 0, 127773, 0, 0, 0, 125207, 0, 0, 1667, 0, 0, 42428, 110950, 0, + 0, 41750, 0, 0, 93999, 0, 8101, 3610, 113670, 41748, 110948, 0, 78394, + 119208, 0, 0, 113691, 64549, 68359, 0, 0, 65692, 92701, 0, 0, 12896, + 10456, 68298, 0, 0, 0, 0, 917962, 0, 0, 113665, 70502, 0, 65687, 0, 0, + 74009, 0, 113673, 8536, 70671, 0, 78726, 0, 724, 0, 113675, 78749, 9975, + 78746, 78747, 78744, 4175, 78741, 78743, 78751, 939, 0, 128799, 983119, + 0, 0, 0, 78763, 78764, 78760, 78761, 78758, 78759, 78755, 8425, 0, 0, 0, + 8188, 0, 0, 0, 0, 0, 6370, 0, 7827, 68441, 75008, 0, 917943, 0, 118863, + 0, 0, 0, 0, 121243, 73988, 0, 113668, 0, 11012, 0, 43764, 178, 12972, + 74620, 113671, 0, 113735, 0, 66764, 0, 0, 65690, 72339, 0, 0, 917950, + 9252, 0, 4652, 74259, 0, 917947, 0, 0, 0, 10806, 0, 0, 70016, 0, 6723, 0, + 0, 6993, 0, 0, 12855, 0, 0, 11390, 0, 0, 0, 92503, 0, 0, 983161, 125270, + 92627, 8278, 0, 4034, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12750, 9350, 66037, 0, + 0, 73700, 12747, 0, 0, 128064, 43153, 74640, 0, 0, 43150, 0, 983090, + 983088, 66779, 66777, 10813, 2592, 43139, 0, 0, 0, 0, 0, 71891, 0, 0, 0, + 0, 0, 0, 0, 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, + 100809, 0, 43467, 123636, 55290, 0, 1712, 5932, 0, 41762, 129389, 0, + 11967, 1775, 0, 75009, 0, 120398, 120387, 9458, 0, 126614, 0, 0, 43176, + 101032, 101031, 42782, 101033, 101036, 101035, 101038, 101037, 101040, + 101039, 0, 0, 0, 0, 101041, 5794, 92274, 2662, 101045, 101044, 8254, + 101046, 10975, 101048, 120625, 101050, 917977, 4108, 8478, 917982, + 194790, 0, 92263, 917980, 7507, 0, 43149, 0, 65031, 7961, 1636, 0, 65029, + 0, 129665, 70188, 9674, 0, 99, 98, 97, 101022, 92203, 4049, 101027, + 101026, 7090, 101028, 0, 101030, 66589, 0, 65310, 66593, 66599, 0, 0, 0, + 7447, 66594, 0, 0, 0, 73920, 66595, 66596, 42570, 5593, 0, 0, 0, 0, 6061, + 64854, 119, 118, 117, 116, 0, 122, 121, 120, 111, 110, 109, 108, 115, + 114, 113, 112, 103, 102, 101, 100, 107, 106, 105, 104, 128504, 73974, + 534, 0, 67713, 1536, 73973, 73970, 0, 0, 0, 6020, 12716, 0, 12744, 65143, + 0, 13266, 127813, 0, 0, 0, 127116, 0, 1212, 65560, 0, 8134, 42935, 12129, + 73870, 0, 1866, 0, 0, 0, 0, 65073, 12059, 66585, 121391, 0, 0, 0, 5935, + 1250, 0, 8174, 9787, 6733, 9859, 9858, 9861, 9860, 101012, 1882, 1892, + 6731, 10882, 10795, 101018, 73911, 101020, 101019, 41169, 8939, 0, + 120713, 41170, 1454, 0, 65130, 69732, 0, 0, 129611, 41172, 7855, 0, + 71472, 0, 0, 0, 71691, 65901, 0, 0, 645, 100992, 100991, 100994, 100993, + 100996, 100995, 100998, 65587, 0, 10688, 0, 0, 7729, 0, 101001, 120518, + 101003, 66722, 101005, 101004, 68415, 101006, 4538, 101008, 43141, 0, 0, + 73699, 0, 0, 0, 71918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2381, 983733, 0, + 0, 69857, 100981, 0, 100983, 100982, 100985, 10856, 100987, 55255, 41478, + 8582, 10064, 0, 0, 0, 0, 64896, 0, 74609, 0, 128048, 10082, 11575, 0, 0, + 0, 917505, 0, 6145, 75020, 0, 92433, 71916, 83279, 43186, 0, 0, 83274, + 83276, 83277, 83278, 10191, 83271, 69633, 72353, 0, 0, 0, 0, 120090, + 120089, 7931, 8558, 917946, 0, 0, 0, 119145, 120081, 120084, 120083, + 120086, 71449, 120088, 7366, 7019, 75021, 0, 917951, 120078, 120077, + 120080, 8657, 100967, 8594, 100969, 100968, 0, 100970, 120072, 120071, 0, + 0, 43154, 0, 0, 11332, 0, 7728, 100978, 100977, 100980, 100979, 7851, 0, + 8375, 128662, 0, 0, 126095, 9085, 0, 0, 9327, 6160, 0, 0, 0, 0, 70698, + 74012, 0, 0, 4439, 121151, 100972, 100971, 100974, 100973, 100976, + 100975, 100956, 42524, 71220, 100957, 10826, 100959, 11296, 0, 0, 0, + 7504, 43161, 127868, 0, 64670, 0, 78056, 0, 11295, 0, 78053, 0, 0, 0, + 10902, 0, 0, 0, 78068, 10472, 100954, 100953, 120215, 78062, 2371, 78069, + 118893, 259, 0, 0, 2402, 12157, 6440, 0, 100963, 100962, 100965, 100964, + 65380, 9103, 2278, 0, 0, 7301, 0, 10219, 0, 0, 0, 67718, 43178, 0, 0, + 119362, 917974, 8613, 0, 126121, 917978, 917979, 121449, 12005, 7353, 0, + 1890, 129130, 0, 0, 0, 42815, 7991, 0, 10578, 0, 0, 0, 0, 0, 0, 0, 0, + 120601, 42668, 9348, 0, 6164, 0, 0, 0, 7676, 0, 0, 0, 0, 0, 129422, + 83443, 71096, 0, 9175, 0, 78047, 9088, 73689, 0, 1396, 0, 0, 11461, + 71088, 127835, 92252, 0, 71090, 121185, 69872, 0, 0, 0, 0, 74043, 119632, + 0, 0, 0, 5928, 4525, 10658, 0, 1266, 10180, 64472, 0, 12622, 0, 0, 0, 0, + 127139, 13310, 773, 19933, 0, 0, 0, 0, 92205, 0, 0, 0, 0, 5862, 7823, 0, + 0, 0, 3250, 43991, 69687, 66649, 0, 0, 0, 0, 0, 64673, 917963, 917964, 0, + 0, 917967, 917968, 917965, 917966, 127791, 75041, 3471, 917970, 64573, + 882, 0, 119584, 0, 120772, 0, 0, 0, 92696, 0, 0, 72988, 0, 3225, 0, + 73729, 0, 0, 43173, 11752, 4381, 0, 0, 917945, 11756, 11757, 917944, + 917949, 42654, 127848, 917948, 0, 0, 5160, 1387, 0, 917953, 0, 128933, + 917956, 917957, 917954, 917955, 917960, 121082, 917958, 10789, 68314, 0, + 126521, 11143, 0, 0, 70669, 128904, 42179, 0, 5931, 11744, 11215, 70676, + 119245, 0, 0, 0, 77915, 10217, 64635, 128661, 83292, 0, 0, 0, 0, 0, + 41296, 11747, 41291, 0, 0, 0, 41294, 41282, 5923, 120610, 0, 0, 0, 0, + 66800, 5786, 68252, 42539, 119869, 119860, 0, 41474, 0, 0, 0, 5934, + 74572, 66583, 119231, 0, 94072, 64481, 0, 0, 0, 0, 67240, 0, 0, 123201, + 0, 5819, 0, 0, 0, 0, 0, 129387, 0, 0, 0, 67993, 1237, 0, 0, 0, 983557, 0, + 0, 0, 0, 0, 0, 0, 69789, 11266, 69845, 0, 10506, 194747, 0, 0, 0, 0, + 43185, 0, 100533, 100532, 100535, 10769, 100537, 100536, 100539, 9753, + 121035, 100540, 0, 0, 121433, 0, 100542, 6072, 100544, 100543, 100546, + 100545, 100548, 100547, 100550, 100549, 0, 113744, 0, 0, 7222, 10283, + 10315, 10379, 4996, 0, 129294, 66517, 0, 10087, 127833, 74938, 0, 0, + 83492, 7565, 42890, 0, 77931, 43180, 77928, 74891, 77929, 43982, 100526, + 622, 77926, 100527, 100530, 1602, 0, 0, 0, 129559, 12160, 0, 10212, + 77936, 194605, 12071, 43143, 77935, 917983, 917984, 917989, 77932, + 917987, 917988, 10255, 10263, 10279, 4194, 10375, 93035, 0, 0, 12644, + 127516, 917994, 75007, 110791, 67408, 110789, 11501, 41177, 0, 0, 71912, + 0, 0, 8715, 0, 41179, 0, 0, 0, 41176, 0, 41181, 0, 8452, 121006, 13161, + 0, 70503, 5921, 0, 2597, 0, 5922, 72128, 0, 74242, 0, 0, 0, 0, 0, 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, + 69605, 83159, 83160, 4554, 0, 83155, 83156, 83157, 83158, 0, 125123, 0, + 72258, 0, 0, 0, 0, 43179, 0, 0, 0, 717, 10754, 83168, 83169, 83162, + 83163, 83164, 83165, 78282, 0, 0, 83161, 68848, 10611, 72859, 126978, + 71474, 129426, 127871, 0, 0, 0, 12820, 0, 0, 7009, 70103, 0, 0, 67848, + 41173, 4574, 0, 0, 128338, 575, 78110, 43456, 8563, 100469, 0, 0, 65565, + 0, 5936, 7290, 78117, 78118, 74919, 308, 78113, 78114, 83151, 78123, + 83153, 83154, 0, 0, 0, 0, 78132, 5926, 68250, 78130, 78126, 78127, 78124, + 78125, 42513, 0, 0, 0, 11651, 13093, 78135, 0, 100471, 0, 100473, 100472, + 100475, 74048, 100477, 74783, 100457, 100456, 43703, 13097, 0, 100460, + 13283, 0, 0, 125073, 3488, 5933, 10033, 0, 0, 65570, 0, 12297, 0, 0, 0, + 128517, 42538, 0, 129293, 0, 100451, 0, 100453, 100452, 100455, 100454, + 121221, 0, 0, 7638, 0, 129193, 0, 43109, 7637, 0, 11213, 100461, 83355, + 100463, 100466, 100465, 0, 0, 7636, 0, 0, 0, 128848, 983087, 291, 0, 0, + 2027, 78141, 78142, 78136, 78137, 83481, 4640, 64713, 10224, 120429, + 11183, 83482, 120430, 0, 0, 0, 127148, 83479, 0, 0, 83488, 0, 0, 0, 0, + 68837, 5778, 0, 0, 0, 12680, 119130, 0, 67242, 93041, 0, 0, 0, 11552, 0, + 127855, 0, 70091, 0, 10172, 65453, 120408, 66014, 120410, 0, 4641, 11556, + 64819, 78269, 120416, 72341, 41469, 41467, 120412, 120415, 4646, 120425, + 865, 78275, 78274, 78273, 4645, 78271, 78270, 0, 983172, 7338, 0, 68840, + 0, 12565, 0, 0, 0, 195089, 119655, 195091, 195090, 2913, 13120, 128956, + 195094, 195097, 195096, 128019, 0, 71462, 0, 7916, 10485, 195098, 0, + 195100, 195099, 0, 67705, 195078, 195077, 195080, 129636, 129549, 195081, + 0, 0, 0, 10229, 10687, 826, 128081, 195082, 195085, 195084, 195087, + 195086, 0, 1808, 7848, 0, 0, 0, 0, 0, 0, 128897, 0, 42942, 67704, 0, 0, + 0, 0, 42940, 0, 9144, 0, 0, 92992, 9840, 0, 0, 0, 0, 0, 0, 74448, 83475, + 0, 10962, 66904, 113718, 983187, 0, 0, 74537, 195072, 1792, 195074, + 195073, 78266, 195075, 0, 0, 12066, 0, 385, 4152, 0, 0, 0, 67397, 0, 0, + 0, 0, 43258, 0, 0, 13157, 0, 0, 3570, 0, 0, 0, 67252, 0, 71218, 126631, + 7879, 68247, 128579, 0, 0, 70196, 0, 0, 8463, 7810, 917862, 7839, 983859, + 127768, 917860, 9691, 0, 129323, 0, 120385, 0, 917844, 0, 10066, 0, 0, 0, + 0, 0, 8016, 0, 983072, 64831, 0, 126103, 0, 119171, 1634, 68115, 0, + 11056, 0, 0, 0, 41165, 11328, 12450, 0, 41166, 0, 12456, 0, 171, 0, + 12452, 917544, 12458, 12531, 0, 917853, 0, 74162, 0, 0, 9969, 0, 12454, + 74160, 42132, 110755, 78878, 110753, 3230, 73711, 0, 0, 8932, 4399, 5810, + 64534, 8415, 0, 110756, 110757, 74159, 0, 0, 960, 74156, 6981, 92374, + 12938, 9201, 0, 983658, 74904, 0, 72866, 92270, 0, 0, 0, 0, 5851, 73833, + 5824, 0, 5844, 110848, 110849, 110846, 110847, 4663, 0, 0, 0, 0, 0, + 74085, 0, 0, 0, 0, 0, 92339, 0, 0, 5782, 0, 0, 0, 43796, 129639, 0, 0, + 125223, 128004, 0, 43861, 0, 0, 0, 92976, 0, 0, 0, 4659, 0, 0, 0, 0, + 129386, 0, 11129, 0, 329, 0, 92707, 121416, 0, 0, 0, 69943, 67692, 42167, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69618, 43671, 0, 64701, 0, 0, 0, 93055, + 1172, 125089, 6786, 43601, 0, 74126, 0, 0, 0, 0, 0, 0, 0, 0, 118804, 0, + 66741, 5347, 0, 983644, 0, 0, 10588, 0, 0, 0, 0, 5343, 0, 0, 0, 5341, 0, + 0, 74916, 5351, 0, 0, 917884, 0, 92692, 0, 121148, 128916, 0, 0, 66785, + 126256, 6638, 0, 0, 271, 0, 917904, 0, 0, 12653, 67588, 0, 0, 0, 0, + 128838, 11912, 128301, 983646, 0, 11800, 0, 0, 11103, 0, 7340, 0, 110695, + 0, 0, 0, 0, 2423, 0, 0, 0, 128136, 42705, 0, 0, 0, 11854, 0, 0, 0, 0, + 4916, 0, 380, 10958, 66563, 127790, 78284, 67587, 0, 12918, 0, 917897, 0, + 917898, 917893, 10684, 0, 125063, 92906, 0, 0, 8182, 0, 0, 0, 0, 0, 0, + 92904, 0, 6630, 100405, 0, 123191, 0, 0, 0, 65876, 5535, 0, 0, 0, 92609, + 0, 0, 6477, 43795, 92217, 129571, 72163, 0, 43848, 0, 0, 74256, 2665, + 11304, 43751, 0, 4970, 74353, 0, 8934, 0, 93996, 4492, 92908, 65011, 0, + 0, 92909, 1188, 7254, 1100, 0, 0, 0, 2912, 11749, 92643, 0, 0, 65057, 0, + 12343, 0, 78879, 0, 78880, 0, 0, 0, 70355, 0, 0, 11803, 0, 0, 41450, 0, + 100897, 0, 41451, 0, 0, 8273, 0, 3451, 0, 972, 41453, 68164, 78876, 0, + 92408, 73945, 43504, 2288, 78873, 9538, 78874, 128685, 0, 129095, 0, 0, + 0, 0, 11019, 0, 0, 121205, 0, 73007, 71365, 92716, 5927, 0, 0, 0, 0, + 128484, 0, 6073, 0, 0, 0, 6075, 93995, 282, 126510, 0, 74078, 121459, + 65861, 0, 0, 66791, 0, 3474, 0, 0, 0, 6081, 0, 127843, 74076, 0, 0, 0, + 128908, 0, 0, 0, 12623, 120273, 9120, 120275, 4665, 12628, 4670, 120271, + 120272, 0, 0, 121480, 958, 0, 0, 0, 4666, 0, 4915, 0, 4669, 0, 0, 0, + 4664, 0, 120550, 0, 0, 0, 0, 94023, 0, 917875, 8664, 11664, 0, 129327, + 11224, 0, 0, 1063, 120250, 120251, 9772, 7255, 8886, 0, 127932, 120257, + 120258, 120259, 120260, 42661, 71345, 120255, 119125, 120265, 120266, + 120267, 42721, 92407, 120262, 120263, 66788, 1017, 0, 0, 505, 1447, 0, 0, + 70340, 66793, 65115, 42789, 128443, 0, 0, 123634, 0, 119195, 0, 0, 11745, + 7919, 0, 1641, 0, 0, 8966, 0, 0, 8743, 71870, 0, 67813, 0, 0, 0, 123206, + 0, 0, 128505, 10169, 71324, 0, 10068, 0, 120457, 120456, 120455, 120454, + 257, 43170, 13153, 0, 0, 0, 0, 0, 0, 6496, 19917, 5930, 128354, 11033, 0, + 0, 5622, 120436, 8477, 8474, 120433, 120432, 0, 0, 0, 41435, 4352, 0, + 2435, 0, 5621, 0, 4201, 8450, 4203, 4202, 4205, 4204, 120447, 120446, + 120445, 66792, 41440, 120442, 8473, 6373, 8469, 120438, 0, 4564, 125206, + 0, 0, 0, 8374, 73669, 0, 0, 66796, 0, 0, 0, 0, 0, 92885, 0, 5626, 43507, + 11771, 0, 0, 0, 42614, 0, 5625, 0, 0, 0, 5623, 0, 0, 42623, 64277, 69942, + 0, 0, 120752, 0, 5817, 5629, 0, 7551, 10325, 5632, 69674, 0, 0, 124946, + 125194, 5628, 0, 5631, 0, 0, 2400, 5627, 0, 0, 118786, 74792, 0, 0, 0, + 203, 129084, 74365, 0, 0, 0, 0, 83382, 83422, 0, 0, 554, 0, 0, 0, 12182, + 0, 64569, 110840, 73891, 0, 0, 0, 7689, 69798, 9323, 10269, 10285, 10317, + 175, 0, 0, 0, 0, 0, 1243, 42154, 0, 92387, 0, 0, 43651, 0, 125021, 0, + 9075, 128774, 0, 64777, 128570, 0, 0, 0, 0, 65255, 0, 121142, 4490, 0, + 6649, 120698, 12181, 0, 11977, 7249, 8366, 0, 7756, 12342, 0, 51, 41516, + 69432, 0, 9568, 71318, 456, 0, 10437, 1168, 9251, 9082, 0, 0, 42781, + 3866, 0, 41512, 0, 0, 68121, 41494, 0, 4660, 0, 10405, 0, 0, 0, 0, 0, + 73918, 119627, 110686, 41454, 12605, 0, 126611, 41455, 917996, 983605, 0, + 8214, 0, 100413, 0, 41457, 0, 0, 1969, 127771, 0, 0, 7413, 0, 69426, + 10341, 43864, 78079, 5854, 0, 0, 0, 0, 72819, 0, 0, 0, 0, 0, 8429, 0, + 72328, 0, 6429, 0, 0, 0, 0, 110688, 83417, 0, 917864, 120813, 83423, + 1662, 129588, 0, 0, 917871, 917868, 0, 0, 66, 65, 68, 67, 70, 69, 72, 71, + 74, 73, 76, 75, 78, 77, 80, 79, 82, 81, 84, 83, 86, 85, 88, 87, 90, 89, + 0, 0, 7385, 70508, 1704, 12993, 0, 0, 0, 0, 0, 0, 0, 0, 11353, 72207, 0, + 0, 0, 0, 118831, 0, 0, 0, 0, 0, 0, 83364, 0, 0, 1289, 0, 0, 119583, 0, + 65507, 0, 0, 0, 128042, 0, 74409, 0, 0, 0, 0, 64793, 0, 0, 100843, 5675, + 119239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6972, 70735, 0, 121108, 126217, 0, + 0, 0, 0, 0, 110640, 67687, 0, 0, 119634, 0, 43977, 111252, 129105, 0, + 7412, 64671, 0, 1412, 4594, 1391, 0, 8067, 12478, 110639, 78375, 110637, + 10281, 110635, 0, 0, 7960, 43271, 0, 12518, 69846, 0, 3566, 0, 0, 69864, + 0, 0, 68021, 0, 0, 0, 8223, 0, 4261, 121460, 68918, 0, 0, 121294, 113712, + 0, 128046, 43419, 72748, 0, 10574, 0, 67691, 0, 0, 73785, 0, 78875, + 128541, 0, 127366, 0, 0, 0, 0, 6695, 65113, 324, 0, 128373, 40985, 0, 0, + 0, 0, 0, 72307, 43474, 0, 121190, 0, 0, 3420, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 110871, 9574, 120684, 110870, 0, 5204, 74774, 0, 11835, 0, 0, 983185, 0, + 0, 0, 0, 0, 0, 11750, 68898, 127004, 0, 0, 0, 0, 8130, 0, 0, 0, 121268, + 0, 0, 0, 68455, 42863, 73839, 0, 0, 0, 0, 0, 0, 0, 612, 110875, 110876, + 72231, 10538, 0, 1674, 0, 0, 0, 12280, 0, 540, 74550, 0, 66422, 8432, 0, + 11073, 0, 64316, 0, 0, 7388, 0, 0, 0, 0, 126107, 0, 3359, 0, 0, 67284, 0, + 0, 65482, 129589, 0, 64742, 129304, 0, 0, 74273, 0, 19941, 0, 0, 0, 0, + 9481, 65555, 0, 66628, 129126, 1195, 64898, 0, 0, 0, 2010, 0, 0, 0, 0, 0, + 0, 4360, 127009, 9739, 0, 72885, 0, 0, 0, 126265, 72200, 0, 0, 0, 72199, + 0, 0, 65734, 0, 0, 0, 13075, 0, 94063, 0, 43532, 10837, 2492, 74516, + 983075, 120882, 0, 0, 11813, 9649, 0, 119617, 5128, 7377, 0, 65604, 0, 0, + 6771, 1648, 7819, 0, 0, 0, 125192, 128131, 12709, 6986, 0, 0, 0, 0, 0, + 12581, 0, 5175, 0, 73806, 0, 128420, 0, 0, 77950, 0, 0, 607, 0, 0, + 128846, 119605, 0, 129528, 65477, 0, 121130, 0, 8265, 0, 0, 0, 5840, + 42838, 0, 0, 68366, 0, 119255, 0, 0, 0, 127929, 0, 2550, 121011, 6779, + 70059, 0, 0, 0, 0, 0, 0, 5619, 65822, 0, 0, 0, 129392, 5616, 11486, 0, 0, + 0, 0, 5615, 0, 121319, 42380, 127958, 0, 66451, 74407, 0, 11347, 0, 1026, + 5620, 0, 0, 11350, 5617, 0, 0, 64639, 0, 0, 0, 1338, 0, 0, 0, 4603, 0, + 70715, 92484, 0, 9002, 0, 3974, 78213, 0, 0, 0, 0, 0, 0, 75038, 66040, + 70455, 0, 0, 0, 72982, 0, 0, 0, 0, 0, 0, 0, 0, 119105, 0, 0, 0, 0, 0, + 128883, 0, 66897, 0, 0, 0, 42594, 0, 0, 0, 0, 6714, 10083, 0, 121019, 0, + 69976, 0, 0, 9073, 0, 64302, 0, 128286, 9725, 0, 0, 121288, 73769, + 121306, 0, 9570, 0, 11500, 2689, 917626, 0, 983794, 66740, 0, 0, 0, + 917623, 13286, 5500, 42598, 42596, 503, 0, 0, 917618, 0, 0, 0, 0, 917615, + 1652, 772, 6688, 8310, 0, 0, 72124, 0, 10194, 43542, 0, 125054, 0, 6468, + 68110, 0, 917606, 11767, 0, 0, 5836, 12358, 0, 0, 65624, 12180, 0, + 127994, 0, 43699, 0, 0, 72114, 43706, 0, 12362, 12435, 12360, 0, 9020, 0, + 12356, 8616, 0, 42924, 2227, 0, 0, 7315, 12354, 83097, 83098, 83099, + 2358, 83092, 83093, 83094, 0, 0, 83089, 83090, 0, 11759, 71723, 0, 72834, + 83109, 41423, 0, 83103, 83104, 83105, 42237, 110653, 70717, 72260, 83102, + 0, 67856, 0, 128534, 110657, 129354, 129194, 0, 64395, 0, 73008, 120897, + 74816, 0, 0, 0, 83088, 0, 0, 94064, 83083, 83085, 83086, 83087, 83079, + 83080, 2041, 9178, 0, 64870, 0, 83076, 74924, 0, 0, 0, 0, 0, 78739, 0, 0, + 0, 0, 0, 0, 3726, 0, 0, 0, 0, 0, 121432, 129457, 0, 0, 0, 0, 0, 74901, 0, + 0, 0, 0, 0, 124944, 113781, 0, 7410, 2669, 903, 0, 0, 0, 127232, 74603, + 0, 128264, 0, 128411, 0, 0, 11732, 0, 72797, 41448, 41461, 124934, 0, + 917558, 0, 8819, 0, 0, 74606, 0, 121412, 74835, 0, 9168, 65786, 0, 73691, + 0, 67665, 0, 11758, 68425, 0, 0, 0, 128044, 0, 19924, 67312, 0, 128755, + 64551, 0, 8516, 0, 0, 7561, 983980, 74018, 0, 0, 0, 0, 83074, 83075, 0, + 11233, 83062, 83066, 3787, 83070, 83055, 41458, 83059, 41463, 65308, + 41459, 8683, 775, 0, 65584, 69923, 0, 110798, 110799, 110796, 43440, 0, + 0, 0, 3656, 0, 0, 0, 67694, 1599, 83138, 83139, 8514, 8513, 83036, 83135, + 83136, 110794, 110795, 83131, 83132, 0, 0, 0, 11684, 10542, 9937, 83150, + 0, 75037, 83145, 65730, 83147, 0, 8427, 83142, 55246, 0, 0, 11497, 0, 0, + 0, 119222, 0, 983598, 0, 10621, 0, 0, 129295, 119111, 120745, 0, 0, 0, + 11648, 83126, 83127, 42118, 83129, 83122, 65512, 83124, 83125, 0, 0, 0, + 83121, 74530, 128456, 0, 0, 0, 65724, 0, 0, 0, 65727, 0, 0, 64963, 73830, + 66042, 0, 0, 7875, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, 0, 65173, 129122, 0, + 70331, 0, 0, 0, 0, 129419, 0, 0, 0, 1687, 0, 0, 0, 0, 0, 0, 10526, 0, + 8323, 0, 83301, 11731, 0, 0, 65460, 12242, 0, 0, 10843, 11554, 0, 0, + 8266, 0, 121101, 0, 0, 0, 0, 67667, 0, 119155, 0, 0, 119636, 67857, 0, 0, + 0, 11755, 66305, 0, 0, 10917, 93979, 113688, 0, 2040, 92596, 0, 0, 0, 0, + 1227, 83119, 83120, 0, 0, 83115, 83116, 11149, 4978, 83111, 1984, 11830, + 83114, 128934, 74548, 0, 9373, 0, 0, 0, 0, 0, 0, 0, 0, 9237, 9390, 0, 0, + 0, 0, 0, 1830, 0, 0, 0, 0, 0, 128577, 983820, 68086, 0, 0, 0, 983059, 0, + 983144, 0, 0, 0, 72197, 55291, 11683, 0, 0, 0, 11451, 0, 72714, 3731, + 2359, 0, 67844, 0, 121503, 548, 121502, 983245, 121405, 983248, 0, 66272, + 0, 64678, 0, 9547, 0, 0, 1614, 0, 0, 66307, 128092, 1358, 120871, 428, 0, + 1466, 0, 10982, 0, 0, 0, 407, 0, 0, 0, 0, 0, 0, 5804, 73464, 0, 0, 0, + 70167, 9057, 42446, 0, 125097, 0, 0, 8250, 10952, 8048, 0, 129155, 0, + 118955, 0, 0, 126586, 4407, 74648, 0, 0, 0, 8448, 92491, 0, 0, 12675, + 12659, 0, 0, 983280, 68077, 55273, 10766, 12012, 2386, 0, 9170, 0, 9123, + 128194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8709, 0, 983585, 0, 0, 0, 0, 0, + 0, 0, 128342, 0, 577, 128610, 0, 0, 124999, 68087, 74840, 126474, 127036, + 0, 0, 0, 1414, 124963, 9683, 43486, 92231, 0, 2536, 0, 66330, 0, 0, 0, 0, + 0, 0, 0, 66317, 0, 66315, 66316, 0, 0, 0, 0, 0, 0, 0, 0, 66323, 66324, 0, + 0, 3106, 65917, 0, 0, 0, 891, 0, 0, 42624, 0, 0, 8824, 65089, 0, 10936, + 0, 0, 0, 0, 92688, 0, 0, 0, 0, 12745, 0, 0, 41285, 3547, 0, 0, 0, 0, 0, + 6089, 0, 68490, 120578, 4170, 1029, 127761, 0, 0, 42374, 0, 744, 917624, + 0, 0, 0, 93046, 0, 3551, 0, 0, 4623, 0, 0, 12340, 0, 65136, 0, 0, 0, 0, + 0, 0, 0, 72291, 0, 0, 120778, 0, 11972, 0, 78757, 0, 122886, 177, 122894, + 0, 0, 0, 0, 55243, 0, 0, 0, 70172, 120249, 120242, 128027, 120243, 0, 0, + 0, 120237, 120245, 94079, 0, 0, 9136, 120240, 120614, 41280, 0, 0, 0, 0, + 74149, 128327, 0, 0, 66361, 12601, 72194, 64360, 65163, 0, 0, 0, 0, 0, 0, + 5404, 43332, 3667, 7936, 12925, 0, 0, 0, 0, 0, 10874, 65505, 0, 0, 0, 0, + 128920, 983662, 0, 0, 0, 0, 0, 0, 0, 0, 66677, 0, 0, 0, 70088, 74148, 0, + 0, 72868, 120230, 120224, 74172, 0, 0, 94096, 0, 128414, 120636, 0, + 127519, 917609, 917616, 0, 128652, 0, 0, 11441, 0, 3512, 0, 0, 43597, 0, + 0, 72734, 68153, 41563, 0, 0, 129352, 41544, 0, 0, 0, 0, 129177, 0, 0, 0, + 118908, 0, 78108, 67396, 73804, 64711, 0, 0, 917610, 0, 0, 0, 11557, + 127776, 0, 12079, 0, 0, 0, 0, 128861, 0, 0, 0, 0, 0, 983200, 8103, 72303, + 128174, 92486, 110698, 0, 64587, 0, 0, 124961, 0, 0, 0, 126481, 0, 0, 0, + 0, 0, 70348, 1450, 0, 1340, 0, 0, 128970, 0, 0, 125117, 0, 0, 0, 0, 6539, + 92948, 0, 128213, 125060, 0, 0, 0, 3973, 0, 70504, 121193, 7982, 0, 0, + 127194, 0, 0, 0, 128408, 118968, 6417, 120619, 0, 0, 0, 0, 129455, 4919, + 65121, 110872, 7755, 0, 0, 64548, 0, 1621, 0, 0, 0, 0, 0, 12188, 0, 0, 0, + 0, 5015, 0, 0, 42590, 70354, 1756, 0, 0, 0, 120694, 0, 0, 7555, 73874, + 5408, 2817, 1214, 69919, 0, 983125, 0, 0, 125055, 127195, 7957, 0, 0, + 1056, 74944, 0, 0, 0, 0, 7073, 74979, 0, 70853, 0, 110874, 0, 0, 2341, + 126644, 8484, 0, 0, 68322, 0, 8461, 67721, 42269, 0, 0, 43709, 43708, + 9451, 7571, 13073, 43847, 126647, 0, 983258, 0, 0, 0, 8781, 12894, 78134, + 0, 92288, 0, 0, 78184, 0, 11338, 120768, 0, 0, 0, 0, 0, 121367, 65021, + 64795, 74574, 0, 10047, 0, 0, 0, 0, 0, 0, 119181, 163, 576, 9895, 0, 0, + 74591, 0, 0, 66888, 0, 0, 0, 0, 0, 0, 7017, 128111, 0, 0, 0, 0, 41591, + 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, 0, 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, + 74127, 0, 0, 0, 78086, 73758, 2335, 10663, 0, 0, 0, 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, 0, + 127985, 0, 10206, 127167, 6375, 2673, 0, 0, 0, 43219, 129355, 0, 0, 0, 0, + 0, 11799, 0, 68466, 0, 0, 0, 0, 0, 120736, 0, 7203, 0, 0, 70361, 129077, + 120615, 127216, 0, 0, 0, 0, 43121, 0, 128366, 72161, 0, 0, 0, 121260, + 73781, 70365, 0, 68039, 70446, 10057, 0, 0, 0, 127399, 120963, 0, 2307, + 0, 0, 0, 0, 73873, 0, 94035, 0, 0, 0, 0, 0, 7327, 0, 0, 440, 0, 0, 68613, + 75059, 0, 0, 9957, 0, 0, 8046, 0, 119158, 0, 0, 68609, 0, 129405, 1521, + 129460, 92256, 65344, 0, 11850, 68737, 0, 0, 68914, 7303, 65770, 5243, 0, + 5239, 65771, 121429, 0, 5237, 0, 68756, 0, 5247, 0, 0, 0, 12873, 5764, 0, + 0, 3008, 118981, 128102, 0, 0, 55231, 41103, 0, 92756, 0, 0, 92717, + 70074, 7872, 74886, 917567, 8731, 65378, 0, 0, 11316, 128163, 126600, + 70360, 3019, 9997, 0, 0, 9456, 129545, 0, 0, 129555, 0, 0, 92682, 4281, + 0, 0, 0, 118982, 0, 69993, 78096, 0, 78095, 0, 78098, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2134, 0, 10116, 9877, 70679, 0, 0, 92723, 8379, 0, 6778, 0, 0, + 8243, 0, 0, 0, 0, 128008, 0, 0, 0, 983630, 119668, 0, 92722, 983098, + 5637, 125115, 0, 0, 120479, 0, 113730, 0, 0, 194990, 64432, 0, 70363, + 121368, 1156, 68052, 0, 0, 120482, 0, 68030, 0, 0, 0, 7634, 0, 0, 65536, + 0, 0, 0, 7702, 0, 78890, 0, 65779, 65783, 195066, 120961, 5700, 0, 0, + 92161, 2339, 92476, 5697, 0, 0, 0, 74923, 0, 5696, 92677, 0, 3862, 0, 0, + 0, 983055, 0, 0, 0, 0, 5701, 9722, 41490, 41370, 5698, 0, 0, 0, 42204, + 55270, 8571, 0, 0, 43859, 0, 78731, 0, 12184, 0, 0, 0, 0, 0, 5650, 0, + 64712, 120474, 0, 120458, 5647, 120473, 7387, 0, 92675, 11477, 5646, 0, + 11018, 0, 0, 0, 0, 0, 0, 0, 128459, 126128, 5651, 0, 0, 0, 5648, 0, + 120920, 0, 127517, 3545, 0, 6984, 0, 0, 0, 69414, 126613, 0, 10123, 0, 0, + 0, 0, 65020, 74885, 119166, 0, 0, 0, 0, 0, 1140, 78426, 0, 0, 0, 0, 8128, + 9889, 0, 0, 1815, 0, 890, 0, 3267, 0, 0, 0, 0, 4410, 125081, 10576, 8102, + 0, 580, 74232, 0, 0, 0, 0, 0, 19938, 0, 0, 0, 0, 3298, 6546, 0, 0, 0, 0, + 6134, 41246, 0, 0, 0, 917770, 0, 6264, 0, 0, 0, 0, 0, 0, 69445, 0, 0, 0, + 92697, 11915, 10377, 0, 10072, 0, 0, 2329, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 125136, 0, 11201, 92708, 74769, 0, 13263, 0, 0, 92404, 126066, 73822, 0, + 0, 64917, 0, 0, 494, 128026, 0, 65098, 0, 956, 125265, 129556, 0, 73740, + 0, 0, 0, 74281, 128638, 0, 0, 69217, 120930, 0, 0, 0, 0, 0, 43088, 0, + 126269, 100948, 0, 65229, 0, 0, 0, 0, 0, 0, 3907, 118833, 64526, 11829, + 68197, 0, 0, 11475, 70329, 3020, 42264, 0, 0, 0, 7098, 0, 0, 127967, 957, + 42696, 0, 3016, 0, 0, 0, 0, 0, 121248, 92510, 3006, 4620, 0, 0, 0, 0, + 129369, 129425, 0, 0, 0, 126246, 8626, 0, 128824, 0, 65377, 0, 983102, + 42920, 1698, 0, 64477, 0, 0, 43813, 100432, 100431, 100434, 100433, + 100436, 70321, 100438, 100437, 100440, 100439, 0, 121024, 0, 70327, + 100441, 55252, 100443, 100442, 100445, 100444, 66641, 100446, 100449, + 100448, 0, 100450, 113820, 74866, 64375, 0, 127850, 129477, 0, 0, 0, 0, + 983780, 0, 0, 120827, 0, 0, 123637, 0, 0, 0, 0, 8110, 100421, 0, 100423, + 5830, 100425, 100424, 100427, 100426, 100429, 100428, 42389, 78611, + 121398, 0, 0, 0, 0, 0, 0, 0, 83342, 983935, 0, 127147, 119187, 2135, + 11836, 0, 0, 78869, 42313, 5579, 0, 70384, 983082, 94002, 0, 5578, 11840, + 73006, 42023, 69849, 5669, 92559, 0, 0, 68833, 917845, 128275, 5583, 0, + 0, 42426, 5580, 42276, 0, 892, 2220, 42465, 74313, 73440, 5795, 194991, + 68774, 65702, 68770, 0, 65695, 0, 65710, 128399, 0, 0, 68783, 0, 0, 0, + 1638, 10966, 0, 917547, 0, 0, 0, 0, 0, 8172, 0, 0, 0, 0, 0, 0, 6374, 0, + 0, 120972, 0, 0, 0, 0, 0, 0, 0, 72204, 64900, 7153, 65785, 68826, 0, + 3015, 68743, 68740, 68738, 68805, 6400, 68749, 68748, 68760, 68758, + 11276, 68754, 100420, 372, 128829, 68761, 118874, 0, 41585, 128202, 0, + 74228, 276, 0, 74234, 0, 74226, 0, 9007, 0, 41588, 125001, 119189, 10763, + 0, 0, 0, 126097, 68525, 6257, 73112, 100393, 100396, 100395, 100398, + 92409, 100400, 100399, 0, 74848, 0, 983592, 100401, 66498, 100403, + 100402, 64790, 73454, 100407, 100406, 70356, 100408, 0, 100410, 66829, + 70817, 5711, 41633, 12098, 65571, 9166, 0, 5710, 0, 6790, 65213, 0, 0, 0, + 69726, 0, 73817, 0, 0, 5715, 0, 70408, 0, 5712, 100382, 41620, 100384, + 3074, 5722, 100389, 100388, 73768, 0, 118906, 0, 0, 0, 66419, 119992, 0, + 0, 0, 0, 128903, 78607, 0, 129074, 0, 0, 0, 0, 0, 0, 113682, 0, 11261, 0, + 0, 0, 8701, 0, 11236, 0, 129490, 100390, 0, 0, 0, 78293, 0, 0, 0, 64946, + 0, 0, 0, 70336, 0, 0, 93986, 68814, 42902, 0, 0, 0, 0, 92344, 0, 67845, + 42641, 71444, 0, 0, 70366, 0, 100369, 100368, 5084, 100370, 0, 118861, 0, + 733, 74646, 0, 0, 0, 125085, 0, 9218, 0, 100380, 100379, 71070, 0, 0, 0, + 0, 70323, 0, 0, 5155, 0, 0, 983756, 0, 0, 72351, 0, 0, 0, 122891, 0, 0, + 0, 100372, 100371, 100374, 100373, 100376, 100375, 100378, 100377, 4974, + 100357, 100360, 100359, 0, 0, 0, 12205, 0, 0, 64507, 0, 0, 0, 0, 0, 0, + 12149, 13088, 78290, 0, 12241, 0, 0, 0, 6932, 100352, 73676, 100354, + 100353, 100356, 351, 68764, 0, 0, 0, 0, 73443, 0, 0, 100361, 42377, + 100363, 100362, 100365, 100364, 100367, 9013, 4054, 0, 0, 113740, 0, + 120782, 5585, 65881, 0, 0, 0, 0, 5584, 8358, 128975, 121177, 0, 0, 0, + 41616, 0, 983796, 2218, 0, 5589, 0, 2664, 41613, 5586, 118890, 0, 11356, + 0, 0, 0, 78609, 0, 0, 0, 0, 0, 0, 0, 0, 8135, 129685, 0, 983791, 0, 0, 0, + 5657, 0, 12915, 121453, 0, 10179, 5654, 12939, 0, 120799, 0, 0, 5652, + 10945, 0, 0, 0, 113710, 0, 73449, 68069, 0, 70332, 0, 5659, 0, 0, 66729, + 5655, 0, 0, 0, 68806, 0, 128225, 66310, 73444, 0, 0, 70362, 0, 11609, 0, + 126990, 92949, 10272, 10304, 10368, 74511, 594, 10244, 10248, 10256, + 983899, 0, 0, 3467, 41010, 0, 3331, 946, 0, 1495, 13184, 74330, 128242, + 9562, 0, 123175, 0, 70036, 0, 0, 0, 123176, 0, 0, 0, 5666, 65227, 123174, + 68419, 0, 11796, 123178, 0, 0, 10186, 123172, 7732, 983736, 0, 0, 0, + 5668, 83334, 0, 74645, 5670, 0, 0, 12741, 126619, 123638, 5667, 19952, + 120807, 113766, 12749, 0, 67757, 2263, 0, 0, 119260, 129131, 9286, 83335, + 128457, 83336, 70359, 0, 3571, 13247, 5874, 78279, 73447, 68435, 78278, + 78267, 78268, 0, 78265, 553, 113768, 0, 93053, 5829, 0, 4587, 78285, + 78299, 0, 12746, 0, 70338, 0, 5633, 0, 94101, 94102, 94099, 94100, 94105, + 74856, 94103, 12742, 0, 983818, 0, 0, 0, 70330, 0, 983811, 0, 0, 0, + 12148, 0, 0, 0, 0, 0, 64938, 67234, 5634, 0, 0, 2146, 0, 118880, 2425, + 65182, 983813, 43636, 0, 0, 328, 0, 68736, 0, 5636, 123163, 5329, 0, + 5638, 0, 7940, 0, 43223, 43760, 5635, 3373, 72424, 78292, 74223, 73441, + 68763, 78287, 9833, 0, 74208, 41635, 0, 0, 43040, 78297, 68778, 78295, + 5639, 65603, 5660, 5640, 78303, 0, 78300, 0, 68301, 0, 0, 78312, 0, + 78310, 41625, 78308, 78309, 100731, 41780, 5642, 100732, 100735, 100734, + 4356, 100736, 100739, 12051, 70166, 100740, 5641, 8259, 0, 0, 0, 119570, + 0, 0, 121264, 983558, 0, 0, 0, 73890, 0, 0, 2800, 11220, 5645, 64964, + 8652, 83323, 0, 0, 121356, 5608, 128281, 119932, 0, 0, 0, 9000, 0, 83324, + 92673, 129176, 0, 5613, 74267, 100721, 100724, 5610, 100726, 92965, + 100728, 5612, 100730, 10787, 0, 3615, 123647, 5609, 78316, 78317, 78313, + 78315, 5875, 5808, 0, 8186, 0, 74269, 0, 70004, 65874, 72422, 5807, 0, + 66320, 5306, 12936, 0, 92970, 0, 0, 92583, 10211, 0, 0, 78871, 121063, 0, + 129512, 0, 0, 0, 0, 0, 74237, 0, 9133, 74262, 0, 0, 0, 64779, 0, 0, 6185, + 64776, 0, 121266, 6499, 0, 0, 0, 92720, 0, 93784, 93791, 2534, 0, 93768, + 93778, 93762, 71849, 71869, 93781, 64583, 93761, 93780, 93760, 93787, + 92443, 128714, 71848, 93774, 66411, 93785, 71841, 93770, 93769, 0, 0, 0, + 121168, 68443, 69774, 931, 0, 125052, 6363, 2748, 0, 0, 0, 983603, 44011, + 0, 0, 100711, 119009, 100713, 100712, 100715, 65896, 100717, 78298, + 100719, 100718, 128836, 100720, 11649, 0, 0, 0, 0, 0, 42341, 65284, 0, 0, + 12884, 0, 7907, 127255, 0, 0, 0, 0, 68779, 0, 68786, 0, 100691, 0, + 100693, 100692, 42851, 100694, 100697, 100696, 92276, 78226, 66393, + 100700, 0, 93773, 93776, 93777, 100702, 78301, 100704, 100703, 42415, + 78307, 4542, 69909, 94022, 100709, 0, 0, 0, 0, 42454, 11565, 7949, + 124939, 0, 0, 42494, 3073, 0, 0, 42302, 0, 126553, 70810, 0, 72401, 0, 0, + 0, 129319, 4877, 100681, 100684, 100683, 10548, 100685, 100688, 100687, + 100690, 64798, 70805, 5346, 0, 126570, 0, 4874, 0, 0, 0, 0, 0, 65884, 0, + 0, 0, 11378, 0, 42785, 0, 3251, 11203, 0, 0, 0, 0, 11052, 0, 5342, 8317, + 0, 0, 5340, 0, 0, 128599, 0, 129538, 0, 128395, 0, 128510, 0, 0, 9142, 0, + 0, 0, 10938, 0, 0, 1182, 127381, 4829, 0, 0, 72438, 529, 0, 0, 0, 10586, + 10790, 10839, 121427, 41593, 100669, 0, 0, 41594, 225, 66418, 0, 0, + 983950, 11376, 0, 41596, 0, 0, 0, 0, 11084, 3194, 0, 78306, 78305, 0, 0, + 0, 11324, 0, 0, 8420, 127756, 128844, 0, 41338, 129683, 11485, 0, 41322, + 66605, 100671, 0, 100673, 100672, 100675, 5161, 41330, 100676, 100679, + 100678, 100659, 100658, 0, 100660, 0, 100485, 12361, 0, 12359, 983559, + 41369, 66412, 12191, 0, 0, 0, 0, 78221, 41376, 0, 9870, 0, 41385, 65824, + 100651, 11938, 100653, 100652, 100655, 100654, 42678, 100656, 0, 64649, + 0, 0, 0, 0, 0, 983948, 100662, 100661, 100664, 66334, 100666, 70280, 832, + 100667, 0, 78473, 66007, 78471, 65703, 0, 0, 0, 12357, 0, 41395, 0, 0, 0, + 0, 0, 0, 0, 0, 41114, 65466, 0, 983825, 6024, 0, 9979, 0, 0, 0, 0, 0, 0, + 0, 4285, 0, 0, 4230, 0, 7367, 0, 92353, 7563, 42376, 0, 128532, 0, 0, 0, + 0, 0, 0, 78466, 0, 12208, 128138, 0, 66311, 71309, 0, 41130, 78286, 0, 0, + 70047, 0, 6022, 0, 0, 0, 0, 0, 41125, 0, 66453, 0, 41107, 0, 41121, 5300, + 0, 0, 0, 0, 74801, 70855, 2074, 73456, 0, 0, 12453, 0, 0, 0, 0, 68159, + 12457, 0, 0, 66278, 0, 0, 0, 0, 0, 66637, 12455, 0, 128473, 0, 12449, 0, + 71224, 0, 0, 66908, 0, 10165, 0, 0, 113715, 0, 128223, 0, 0, 0, 0, 4993, + 0, 6168, 74033, 4995, 0, 69459, 120522, 4639, 0, 72223, 0, 0, 0, 0, 0, 0, + 69734, 0, 0, 0, 0, 0, 0, 83310, 0, 0, 0, 0, 0, 0, 0, 0, 129594, 4953, 0, + 0, 0, 0, 83311, 0, 73453, 65688, 0, 10125, 3517, 0, 0, 0, 65094, 74791, + 78262, 10627, 66333, 78256, 78257, 83304, 78253, 0, 71317, 64923, 0, + 65208, 10608, 78263, 78264, 0, 0, 0, 65883, 0, 0, 74914, 0, 0, 0, 0, 0, + 12912, 119012, 0, 128191, 0, 0, 129586, 0, 1290, 0, 0, 0, 0, 113719, + 71442, 0, 0, 8978, 0, 119135, 120979, 10527, 71079, 0, 0, 0, 0, 0, 0, + 5336, 0, 0, 6934, 0, 10780, 0, 0, 78767, 0, 0, 0, 347, 0, 0, 78775, + 64675, 41582, 78774, 78771, 68094, 74903, 78769, 69221, 69657, 0, 0, + 11153, 120981, 78526, 0, 0, 0, 0, 41584, 0, 69464, 0, 0, 0, 0, 43510, + 66661, 0, 66306, 78791, 66384, 0, 6609, 0, 0, 11319, 0, 128964, 0, 41730, + 0, 0, 127920, 0, 65172, 41728, 41721, 0, 0, 0, 41203, 0, 0, 41726, 0, 0, + 5758, 0, 0, 41140, 2028, 78092, 0, 0, 0, 92739, 983195, 41138, 0, 0, 0, + 125082, 1115, 127060, 9794, 127062, 67671, 92238, 12237, 78787, 66314, + 78785, 9290, 73668, 78783, 78780, 78781, 127144, 7926, 0, 0, 0, 64398, + 100924, 71274, 12311, 0, 78796, 78798, 78794, 78795, 78792, 78793, 0, 0, + 0, 73455, 0, 0, 0, 42142, 9968, 11583, 0, 7092, 0, 9627, 78536, 73677, + 78535, 0, 0, 1248, 10148, 127755, 0, 0, 0, 0, 66447, 0, 0, 0, 0, 65305, + 0, 4031, 42794, 119986, 0, 8154, 0, 0, 128028, 126259, 0, 125220, 73452, + 0, 0, 0, 6696, 0, 119599, 0, 0, 0, 4364, 0, 0, 0, 120976, 0, 120922, 0, + 10124, 7526, 8601, 0, 68246, 0, 129318, 1418, 10885, 0, 0, 0, 0, 0, 0, + 4571, 0, 0, 0, 12078, 41597, 0, 10933, 0, 72129, 0, 0, 0, 41599, 0, 0, 0, + 12950, 119190, 10498, 0, 66782, 4239, 0, 0, 66511, 68066, 2637, 110685, + 8460, 110683, 8476, 110681, 0, 110679, 0, 127919, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5412, 66243, 9935, 122892, 0, 73864, 41734, 8206, 74081, 0, 3286, + 120730, 0, 0, 41732, 0, 41736, 983201, 41731, 0, 0, 70842, 0, 0, 0, 0, + 129329, 0, 66853, 0, 0, 78742, 72755, 11277, 65892, 0, 10620, 92272, 0, + 0, 0, 0, 73942, 0, 100479, 0, 119093, 3459, 0, 129398, 0, 0, 72130, + 92512, 0, 66377, 69781, 0, 0, 111304, 3161, 69981, 0, 0, 0, 0, 0, 9016, + 78153, 0, 0, 43641, 0, 121018, 0, 0, 0, 0, 0, 0, 0, 68342, 120950, 94043, + 0, 12332, 121310, 6086, 41722, 0, 120709, 0, 0, 111305, 0, 0, 128307, + 74288, 0, 74546, 0, 129178, 0, 0, 42460, 0, 0, 0, 0, 120941, 42421, 0, + 41723, 0, 64358, 11460, 983506, 0, 64718, 120838, 66869, 0, 42348, 0, + 6752, 452, 42500, 0, 128258, 0, 42308, 0, 0, 0, 12932, 0, 69968, 42950, + 66827, 917582, 0, 0, 8302, 0, 0, 0, 0, 7250, 13214, 10041, 8105, 65568, + 127780, 69969, 127759, 0, 0, 121467, 0, 121466, 73666, 0, 69878, 0, 5538, + 9987, 0, 118932, 129307, 0, 552, 0, 7357, 10785, 0, 0, 4557, 0, 0, 10171, + 68320, 0, 5540, 0, 0, 281, 0, 0, 42622, 0, 5536, 0, 0, 1388, 0, 0, 10504, + 0, 0, 11531, 74324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3663, 0, 121081, 70335, + 74859, 0, 5334, 0, 110738, 72319, 0, 11305, 0, 68456, 0, 66611, 0, 19907, + 64363, 3478, 7583, 7679, 74154, 0, 0, 1158, 0, 0, 73748, 0, 0, 1915, + 4846, 0, 120132, 118984, 120134, 120129, 120128, 805, 120130, 64438, + 120124, 8760, 120126, 72137, 120120, 120123, 94003, 0, 0, 0, 0, 0, 12225, + 0, 0, 0, 70173, 75045, 0, 129515, 8083, 0, 0, 0, 111094, 92626, 0, 0, 0, + 0, 0, 0, 110837, 0, 67699, 560, 5643, 0, 0, 0, 0, 0, 0, 0, 120144, 0, + 120661, 78304, 1597, 120143, 120142, 206, 70126, 120139, 120138, 8168, 0, + 73086, 0, 0, 0, 983827, 125036, 0, 0, 3546, 42573, 66811, 0, 0, 128397, + 8400, 0, 0, 0, 0, 0, 7903, 9287, 72791, 0, 0, 0, 0, 72134, 66603, 1695, + 917861, 0, 0, 111101, 0, 0, 0, 0, 0, 0, 0, 111099, 0, 111098, 4754, 0, + 69222, 128229, 0, 0, 7354, 7408, 0, 0, 121181, 0, 0, 0, 12739, 0, 1278, + 4187, 0, 42119, 42120, 0, 121158, 0, 12467, 0, 68902, 0, 12463, 0, 0, + 118827, 0, 9664, 70834, 74475, 0, 0, 0, 0, 0, 3661, 0, 0, 9022, 127955, + 0, 0, 126257, 0, 6118, 222, 126250, 3884, 0, 74151, 0, 6502, 0, 11085, + 121261, 0, 0, 0, 0, 0, 0, 0, 0, 12461, 0, 0, 0, 94059, 11254, 10860, + 64880, 0, 64685, 0, 0, 94087, 7776, 11219, 0, 0, 121339, 69730, 801, + 43165, 0, 78212, 0, 0, 13277, 0, 12951, 0, 9906, 5486, 2334, 128672, + 67680, 5483, 73732, 120884, 119128, 5484, 0, 127876, 2539, 0, 78507, + 5485, 195065, 42697, 0, 0, 113689, 4502, 68057, 253, 73672, 0, 0, 9203, + 0, 0, 0, 0, 0, 121242, 11127, 0, 0, 0, 13257, 0, 0, 0, 69645, 0, 0, 0, + 70431, 0, 5693, 64470, 0, 66610, 67678, 0, 983659, 0, 0, 0, 0, 0, 0, 0, + 94078, 0, 0, 66608, 3111, 0, 8804, 66607, 0, 0, 0, 66606, 0, 0, 0, 1436, + 0, 55226, 0, 111287, 7393, 41592, 0, 0, 1598, 78101, 0, 0, 65193, 4423, + 0, 113692, 10515, 41589, 0, 0, 0, 0, 1430, 0, 0, 120606, 0, 66223, 7619, + 3255, 128280, 74032, 11549, 10735, 93038, 100741, 6801, 100743, 100746, + 2148, 100748, 100747, 100750, 100749, 0, 121229, 0, 69243, 41724, 67716, + 69669, 41690, 111269, 983647, 8380, 100355, 983830, 0, 0, 0, 0, 0, 0, + 6333, 111264, 42315, 0, 129502, 111265, 0, 0, 5339, 74323, 0, 13004, 0, + 0, 0, 0, 0, 0, 5684, 0, 0, 0, 5689, 0, 0, 68464, 12633, 12870, 0, 65183, + 5688, 0, 0, 6310, 5686, 0, 0, 0, 120647, 70046, 50, 94095, 9871, 0, 0, + 121446, 0, 0, 0, 66905, 0, 4448, 0, 121406, 113734, 72125, 1321, 0, + 10640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12501, 0, 0, 0, 0, 8812, 0, + 69986, 8673, 0, 129024, 0, 0, 2105, 72101, 72712, 0, 0, 0, 0, 0, 4636, + 55262, 0, 4515, 2382, 0, 0, 7313, 0, 0, 0, 194626, 0, 0, 0, 0, 0, 0, 0, + 10197, 194719, 0, 0, 0, 194718, 0, 0, 0, 64189, 0, 1873, 0, 0, 0, 0, 0, + 983663, 0, 0, 0, 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, + 0, 41714, 0, 0, 0, 6343, 0, 0, 43996, 0, 8044, 0, 0, 41789, 0, 10809, 0, + 0, 0, 0, 8146, 11025, 0, 120513, 642, 0, 0, 0, 12875, 0, 0, 13229, 0, + 41788, 0, 0, 0, 41791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8428, 6569, 0, 0, 0, + 0, 10167, 0, 68248, 8049, 0, 0, 0, 0, 128882, 4761, 0, 4766, 64623, 0, + 121180, 194653, 118876, 0, 6912, 9232, 7033, 0, 0, 41545, 0, 0, 72160, + 72107, 0, 0, 0, 3484, 0, 0, 0, 8503, 41539, 41527, 0, 0, 983823, 0, 0, 0, + 41537, 0, 41541, 8282, 11817, 0, 128219, 0, 0, 126132, 0, 0, 70115, + 66609, 111235, 65921, 0, 0, 194664, 0, 129326, 77970, 42246, 75030, + 120605, 0, 65926, 7744, 68859, 94056, 74277, 126108, 0, 6966, 194633, + 8136, 0, 0, 0, 0, 0, 4762, 0, 0, 0, 4765, 69443, 983573, 0, 4760, 0, 0, + 10871, 43199, 0, 0, 93955, 0, 0, 11546, 0, 337, 0, 0, 0, 12279, 7768, 0, + 128352, 0, 69812, 10143, 7883, 121444, 7880, 64618, 13012, 5704, 13010, + 0, 0, 119531, 0, 0, 0, 0, 66654, 0, 0, 0, 13008, 0, 4385, 0, 13011, 0, + 92569, 119161, 13009, 74771, 70159, 0, 0, 41793, 0, 74221, 120996, 41792, + 111242, 94054, 126094, 0, 111244, 5709, 120689, 71076, 0, 0, 0, 0, 0, + 5708, 0, 0, 0, 5706, 66362, 5705, 8791, 41797, 0, 10237, 66436, 0, 0, 0, + 0, 128083, 13170, 0, 0, 0, 0, 41377, 0, 0, 10058, 125225, 0, 0, 0, 0, 0, + 0, 0, 129641, 119525, 0, 0, 72350, 0, 983572, 2144, 0, 120765, 0, 0, + 1754, 92226, 13246, 864, 0, 118926, 8972, 0, 7849, 0, 0, 13240, 0, 5192, + 0, 0, 10948, 0, 13199, 0, 1236, 13208, 13261, 13189, 13188, 93993, 0, + 7440, 0, 0, 0, 1844, 125229, 0, 13178, 0, 0, 0, 125230, 0, 0, 13260, + 4550, 121249, 125227, 0, 71071, 0, 0, 68523, 0, 0, 11354, 94071, 0, + 42795, 129317, 0, 0, 0, 125237, 0, 13194, 13274, 0, 0, 129533, 65586, + 68311, 0, 119193, 4601, 194661, 0, 194658, 0, 194659, 0, 121422, 128790, + 194657, 41717, 67402, 0, 121129, 41716, 127376, 7910, 0, 0, 754, 41944, + 0, 8183, 120741, 2037, 0, 0, 0, 125, 0, 0, 0, 983124, 127922, 41719, 0, + 7990, 12637, 13258, 9536, 71056, 0, 4427, 0, 71200, 0, 12217, 0, 41532, + 129315, 0, 0, 0, 0, 111063, 83349, 0, 0, 120622, 0, 0, 0, 0, 43632, 0, 0, + 8140, 0, 6260, 0, 0, 66765, 129657, 0, 3898, 0, 0, 13200, 0, 0, 66582, 0, + 0, 0, 0, 1068, 71178, 13259, 12945, 0, 42203, 0, 3124, 69411, 0, 4386, + 12224, 6973, 129563, 0, 0, 119535, 0, 121312, 0, 12232, 0, 0, 5681, + 64578, 75023, 0, 13209, 0, 0, 0, 0, 0, 11053, 0, 74902, 128107, 128942, + 7588, 0, 1693, 74942, 43204, 65831, 0, 0, 0, 68803, 111216, 111223, 0, 0, + 65685, 9523, 65070, 0, 0, 0, 0, 0, 0, 0, 0, 13191, 0, 3500, 3139, 100643, + 3170, 100645, 100644, 100647, 100646, 13006, 64433, 0, 100650, 941, 0, 0, + 120967, 3727, 0, 0, 0, 0, 0, 0, 0, 94039, 129299, 92455, 0, 0, 64444, 0, + 0, 43603, 94075, 65397, 288, 0, 0, 0, 10025, 73692, 0, 0, 68182, 0, 0, 0, + 92438, 65395, 0, 0, 0, 65393, 83078, 121111, 0, 0, 0, 0, 0, 65394, 11548, + 72305, 0, 65396, 0, 0, 13256, 1282, 0, 0, 0, 111085, 0, 0, 0, 111087, + 72115, 0, 0, 0, 0, 0, 3304, 0, 0, 0, 126595, 72437, 68353, 0, 0, 42113, + 0, 0, 0, 0, 0, 43094, 0, 0, 94037, 68317, 9035, 0, 0, 0, 0, 0, 70822, + 128467, 164, 68309, 94067, 94000, 100631, 100634, 100633, 100636, 100635, + 100638, 100637, 68808, 100639, 110665, 73893, 11099, 110664, 13175, + 13207, 0, 127552, 0, 74643, 5929, 0, 0, 129192, 0, 11306, 0, 119059, + 3180, 125102, 0, 0, 0, 13062, 0, 129551, 128707, 0, 0, 74428, 0, 128000, + 0, 11251, 70204, 0, 10045, 0, 13275, 0, 11057, 0, 13276, 125133, 41525, + 983084, 128015, 11444, 0, 129158, 0, 0, 41523, 127765, 0, 0, 0, 0, 0, 0, + 0, 3858, 0, 119573, 0, 0, 0, 0, 0, 0, 101014, 369, 74908, 41784, 0, + 120994, 0, 71180, 0, 0, 13210, 41782, 0, 0, 0, 41781, 10486, 74058, + 43002, 0, 0, 0, 0, 0, 3741, 0, 0, 0, 0, 41222, 0, 128317, 3982, 0, 4388, + 126105, 746, 0, 0, 0, 13131, 0, 0, 0, 0, 0, 10434, 8794, 0, 0, 0, 0, 0, + 0, 11700, 4374, 0, 0, 0, 0, 0, 0, 917597, 0, 69814, 0, 6735, 73979, + 13174, 73968, 13225, 0, 69808, 0, 0, 2365, 7841, 71476, 0, 120934, 66510, + 128099, 0, 0, 0, 41785, 41171, 0, 13173, 4372, 0, 0, 0, 0, 128939, 0, 0, + 12965, 384, 0, 0, 12685, 41473, 0, 13242, 13236, 0, 0, 0, 41787, 0, + 70684, 0, 68486, 13272, 0, 13232, 13233, 65838, 0, 0, 11656, 0, 126110, + 119885, 12861, 0, 13271, 0, 92737, 1096, 0, 0, 0, 0, 0, 0, 0, 5203, 0, + 92902, 0, 13243, 13237, 12719, 0, 0, 0, 64884, 78043, 0, 0, 0, 0, 12014, + 0, 120785, 0, 0, 13195, 41452, 64961, 41535, 0, 10459, 0, 124949, 0, 0, + 0, 41533, 66337, 0, 92184, 0, 126091, 0, 0, 73849, 0, 43638, 0, 0, 6261, + 0, 129568, 0, 1957, 0, 0, 0, 13292, 13206, 0, 0, 2925, 73809, 42576, + 127559, 13212, 43238, 0, 13190, 13187, 0, 13198, 0, 0, 5242, 0, 0, + 128146, 0, 0, 6770, 43331, 127539, 0, 0, 71074, 126466, 0, 41444, 0, 0, + 64799, 5246, 119106, 13185, 9709, 0, 0, 92751, 0, 5238, 0, 71085, 0, + 5236, 40979, 0, 74201, 8286, 0, 3936, 0, 11699, 0, 127249, 13235, 0, + 41248, 127264, 13245, 13239, 0, 7969, 127266, 74832, 127251, 0, 120509, + 0, 983874, 734, 127270, 0, 127254, 70297, 127273, 64921, 120969, 66631, + 41771, 120490, 0, 983171, 41770, 1670, 42560, 0, 121349, 129634, 0, + 41163, 0, 11136, 0, 11506, 0, 42841, 13267, 126109, 0, 41775, 0, 7130, + 41773, 0, 0, 0, 0, 0, 0, 0, 42673, 65572, 0, 65250, 13265, 13264, 64518, + 66798, 6100, 0, 0, 6740, 71080, 67814, 12967, 70028, 68101, 4583, 0, 0, + 68097, 0, 0, 0, 0, 119211, 0, 0, 42653, 83181, 68102, 0, 7814, 71045, 0, + 73702, 0, 0, 0, 9756, 6985, 0, 0, 74219, 0, 0, 129069, 124987, 5674, 0, + 66421, 0, 5677, 5588, 0, 0, 0, 0, 5673, 0, 5676, 0, 94048, 0, 5672, 6476, + 0, 0, 110951, 42511, 1727, 0, 0, 0, 0, 0, 0, 0, 3550, 736, 0, 4505, 5873, + 74090, 5826, 55232, 5813, 0, 120712, 5841, 5837, 55234, 0, 3105, 64370, + 5838, 5796, 0, 119592, 5793, 0, 5866, 5797, 41011, 5865, 0, 0, 71899, 0, + 71235, 5806, 0, 0, 9037, 5671, 0, 0, 0, 0, 71266, 126616, 7296, 0, 0, 0, + 0, 6980, 0, 72108, 0, 0, 0, 0, 0, 64613, 983891, 0, 0, 0, 0, 7114, 0, + 72100, 43190, 93842, 128666, 72096, 42611, 42563, 0, 125080, 0, 6792, + 43201, 72098, 0, 128719, 0, 72106, 0, 0, 5644, 0, 66627, 69727, 0, 0, 0, + 65116, 0, 0, 0, 0, 66410, 94104, 41013, 0, 0, 0, 2869, 0, 41015, 0, 2785, + 120616, 0, 73907, 194689, 0, 0, 0, 194688, 4759, 0, 0, 43192, 0, 1170, + 43365, 69810, 73908, 0, 902, 0, 0, 0, 0, 8122, 66420, 129642, 0, 3861, 0, + 11028, 0, 73820, 5714, 0, 0, 0, 807, 127001, 0, 0, 976, 113782, 0, 0, 0, + 0, 0, 128657, 118801, 71043, 0, 127017, 0, 0, 5582, 0, 0, 5798, 0, 0, 0, + 128521, 0, 0, 68058, 120553, 983183, 0, 0, 74933, 74283, 0, 0, 194698, + 66044, 0, 0, 0, 0, 0, 10094, 0, 0, 10857, 69225, 0, 0, 93, 0, 10954, 0, + 0, 0, 8171, 0, 0, 82996, 0, 0, 0, 119001, 92634, 0, 0, 5187, 120711, + 71086, 0, 0, 0, 0, 5232, 0, 41009, 0, 41005, 0, 43205, 0, 0, 0, 194708, + 0, 71054, 10028, 66478, 7076, 13182, 100385, 0, 0, 0, 0, 7972, 78786, 0, + 0, 0, 78789, 11309, 3806, 73985, 0, 0, 0, 78819, 0, 125218, 0, 127532, 0, + 0, 0, 78817, 0, 64366, 65156, 8814, 0, 0, 0, 0, 12836, 42725, 120079, 0, + 0, 0, 0, 0, 13255, 0, 0, 7464, 0, 93831, 0, 0, 0, 0, 13213, 0, 0, 64516, + 0, 0, 0, 41007, 983910, 0, 40995, 12209, 983914, 119136, 123635, 0, 0, 0, + 0, 0, 69384, 43558, 5522, 0, 71061, 0, 74105, 3633, 983912, 119364, + 41234, 41231, 0, 9771, 983917, 13251, 0, 0, 6262, 2784, 0, 71078, 8126, + 66483, 0, 0, 441, 0, 0, 0, 41002, 40999, 0, 0, 7108, 0, 10890, 0, 74445, + 8324, 0, 0, 74817, 2813, 119056, 74853, 983671, 0, 0, 0, 1193, 10462, + 65197, 13253, 13252, 7829, 120992, 0, 0, 0, 0, 77911, 0, 77907, 0, 10386, + 0, 41042, 0, 65944, 65683, 10338, 66469, 0, 0, 0, 0, 0, 41966, 0, 0, 0, + 68915, 0, 0, 911, 983870, 128932, 40963, 0, 65159, 0, 0, 0, 5520, 0, 0, + 0, 0, 0, 0, 0, 71081, 0, 0, 0, 0, 0, 983873, 0, 0, 66839, 0, 0, 0, 68647, + 0, 5857, 68135, 92727, 119120, 983675, 13171, 0, 0, 0, 120338, 0, 0, 0, + 13250, 69663, 0, 92201, 66397, 0, 0, 0, 8761, 12942, 5748, 92713, 92414, + 0, 83174, 8796, 0, 0, 0, 43633, 0, 72805, 71073, 0, 0, 0, 0, 0, 12843, + 4520, 0, 0, 73004, 983672, 0, 0, 194935, 110754, 64345, 0, 0, 110752, 0, + 0, 0, 110750, 110758, 110751, 0, 0, 10427, 0, 73859, 0, 9755, 1110, + 65239, 0, 0, 0, 0, 0, 0, 0, 194936, 0, 983802, 0, 70437, 3620, 0, 0, + 72855, 0, 0, 0, 74250, 0, 0, 11980, 0, 66482, 67823, 0, 128345, 110768, + 0, 0, 0, 0, 12891, 983767, 983648, 0, 2016, 0, 65668, 92311, 67696, + 10366, 70117, 9155, 120652, 9786, 65082, 0, 8579, 0, 0, 0, 0, 4508, + 64883, 0, 92522, 0, 0, 64592, 74276, 67688, 0, 0, 0, 69456, 0, 113821, 0, + 12147, 9024, 66378, 66472, 0, 0, 0, 0, 0, 71935, 0, 0, 113697, 0, 0, 0, + 0, 74275, 0, 122896, 127941, 41214, 0, 0, 0, 0, 0, 7773, 0, 0, 9963, + 68649, 0, 73734, 0, 0, 0, 0, 6594, 983752, 0, 0, 3624, 70342, 0, 64655, + 121481, 0, 0, 0, 0, 0, 65932, 0, 983790, 6803, 120968, 7738, 0, 0, + 120628, 0, 66614, 122921, 0, 43810, 7029, 0, 41292, 118898, 0, 43115, + 9517, 11518, 0, 0, 0, 0, 64423, 0, 0, 0, 12503, 9591, 4516, 0, 118845, 0, + 0, 129479, 43650, 983192, 0, 0, 0, 68079, 0, 11397, 2884, 0, 0, 12678, 0, + 0, 41014, 73730, 917539, 4270, 92254, 127836, 68205, 6633, 118947, 0, + 5230, 101055, 0, 0, 983230, 121392, 0, 92985, 0, 0, 0, 0, 415, 0, 0, 0, + 0, 5183, 1877, 0, 0, 0, 0, 0, 4472, 0, 0, 0, 128285, 110682, 78230, 4756, + 0, 7081, 0, 0, 0, 78606, 0, 42922, 42103, 8628, 74861, 0, 0, 0, 43059, + 10539, 0, 0, 0, 0, 0, 0, 0, 0, 64873, 11992, 0, 0, 0, 11801, 3622, 0, 0, + 983213, 0, 0, 11521, 0, 1966, 43628, 111048, 0, 0, 0, 0, 0, 0, 42098, + 66671, 10694, 128520, 0, 0, 0, 0, 42100, 0, 111040, 0, 42097, 0, 0, 0, 0, + 11302, 120893, 129145, 43395, 83259, 0, 0, 92351, 0, 0, 11299, 1561, 0, + 92359, 92725, 93021, 0, 194733, 0, 0, 0, 127893, 11280, 0, 0, 983783, 0, + 0, 72760, 0, 12486, 65018, 66516, 5409, 0, 0, 194720, 5399, 9685, 0, + 983694, 5401, 0, 0, 66832, 0, 0, 5405, 0, 0, 0, 0, 0, 2235, 0, 11330, + 983692, 64690, 3254, 0, 0, 0, 0, 43678, 0, 0, 983145, 0, 6388, 3355, 0, + 9867, 0, 55258, 5611, 0, 128527, 0, 0, 129181, 0, 78228, 0, 0, 119119, 0, + 0, 194959, 0, 0, 1379, 246, 0, 0, 64736, 0, 0, 0, 121227, 0, 0, 0, 0, 0, + 0, 11855, 0, 0, 0, 0, 10656, 0, 65214, 119242, 0, 0, 13163, 0, 120831, 0, + 0, 0, 0, 0, 0, 0, 0, 4755, 0, 127879, 11443, 0, 0, 0, 608, 600, 0, 8580, + 128712, 0, 43635, 0, 0, 74485, 43808, 0, 0, 0, 13160, 0, 129418, 42268, + 128006, 70505, 9828, 0, 0, 0, 0, 9351, 7778, 0, 0, 0, 6916, 1208, 0, 0, + 194754, 0, 0, 0, 0, 0, 83318, 83317, 0, 43539, 0, 0, 0, 0, 0, 9150, + 66831, 0, 128322, 0, 66848, 0, 0, 12166, 128492, 194685, 0, 2546, 0, 213, + 0, 65611, 83316, 0, 0, 74310, 70836, 0, 65285, 5452, 0, 0, 92772, 0, 0, + 0, 0, 65518, 129029, 12609, 194679, 125255, 123193, 0, 0, 0, 74638, + 194677, 125190, 4143, 110854, 110855, 65748, 4141, 9682, 110851, 118790, + 194674, 0, 0, 8725, 0, 66638, 0, 42263, 4145, 6380, 0, 66613, 0, 119207, + 0, 0, 9550, 100621, 0, 100623, 100622, 78050, 100624, 65753, 100626, + 65756, 72731, 0, 100630, 0, 0, 0, 0, 9657, 9019, 121154, 0, 0, 5390, 0, + 0, 194965, 72144, 194964, 0, 6328, 0, 0, 0, 0, 0, 983047, 0, 5235, 803, + 0, 0, 0, 127979, 43838, 0, 119562, 43544, 0, 0, 0, 0, 0, 70426, 9107, + 5191, 119113, 0, 0, 0, 121099, 0, 0, 0, 0, 0, 128150, 983067, 0, 7289, + 74055, 0, 0, 0, 0, 0, 0, 0, 1784, 124947, 0, 0, 0, 0, 64868, 0, 13158, 0, + 7211, 0, 9371, 129378, 0, 0, 1625, 7664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4482, 118886, 0, 0, 0, 0, 0, 0, 0, 100612, 66849, 100614, 100613, 100616, + 444, 100618, 100617, 100620, 100619, 0, 0, 0, 11349, 40991, 0, 0, 129324, + 0, 0, 1197, 0, 40993, 0, 0, 0, 40990, 43765, 0, 3492, 0, 127942, 0, 0, + 100592, 100591, 100594, 19948, 100596, 3099, 92239, 100597, 100600, + 100599, 0, 129042, 0, 0, 100601, 194969, 100603, 8152, 100605, 100604, + 100607, 100606, 100609, 12828, 0, 75015, 0, 0, 0, 0, 0, 75068, 127507, 0, + 92680, 0, 0, 0, 0, 0, 0, 0, 118820, 0, 0, 0, 0, 0, 100581, 0, 100583, + 100582, 100585, 100584, 100587, 100586, 100589, 7576, 11995, 100590, + 43260, 0, 0, 64830, 0, 125046, 0, 0, 43979, 8870, 0, 0, 42357, 0, 0, + 12822, 0, 0, 0, 118944, 0, 0, 42637, 0, 0, 70725, 0, 194748, 0, 71344, 0, + 0, 0, 194749, 7170, 9596, 8277, 194743, 43629, 110610, 0, 0, 983567, + 128691, 0, 66699, 64440, 0, 0, 0, 43234, 66008, 12627, 0, 0, 0, 43619, + 43303, 11300, 0, 0, 8745, 0, 7558, 71342, 100570, 0, 0, 127881, 3461, + 121258, 129471, 0, 0, 0, 0, 73877, 74335, 124982, 0, 0, 0, 64620, 74762, + 12069, 10838, 92548, 43616, 0, 10061, 0, 125057, 10508, 209, 0, 43193, + 120581, 0, 0, 128049, 0, 10899, 69855, 100571, 100574, 100573, 100576, + 993, 100578, 100577, 100580, 100579, 100560, 100559, 7232, 0, 0, 0, 0, 0, + 0, 10489, 42166, 0, 128588, 0, 0, 4224, 7671, 41518, 121311, 0, 0, 0, 0, + 64820, 92538, 12966, 100554, 100553, 100556, 100555, 100558, 100557, + 4263, 8793, 0, 0, 41502, 0, 983, 0, 100563, 100562, 13086, 4109, 4274, + 841, 5888, 100568, 68522, 0, 43481, 0, 120926, 0, 7209, 0, 41505, 0, + 78698, 127012, 0, 2147, 0, 0, 66629, 0, 0, 1255, 4149, 0, 0, 66633, 0, 0, + 92352, 0, 65101, 0, 0, 0, 0, 5835, 128797, 66625, 10842, 0, 42123, 0, 0, + 66634, 1094, 66636, 0, 0, 0, 0, 0, 9972, 73865, 129289, 6114, 0, 0, 0, 0, + 93960, 0, 0, 0, 0, 12070, 0, 881, 7857, 0, 65164, 0, 0, 0, 0, 0, 64404, + 64321, 0, 125187, 0, 0, 11245, 129395, 0, 71859, 0, 0, 0, 1287, 121509, + 0, 0, 0, 125264, 74152, 120504, 64545, 0, 69668, 8985, 0, 0, 0, 0, 0, 0, + 3652, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 1489, 125189, 0, 0, 3899, 0, 42124, + 43828, 42122, 0, 0, 0, 11985, 73755, 78600, 0, 0, 10988, 0, 0, 42138, + 78610, 0, 65768, 78608, 78604, 78605, 6285, 78603, 78612, 78613, 74339, + 65767, 8685, 0, 0, 0, 78622, 78623, 68475, 11470, 64538, 78618, 78615, + 78616, 0, 0, 0, 0, 2527, 0, 128209, 2799, 0, 0, 0, 9933, 0, 0, 767, 5524, + 7028, 0, 0, 0, 0, 0, 78633, 0, 0, 94011, 0, 6971, 0, 70731, 0, 0, 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, + 0, 0, 69650, 0, 0, 0, 43436, 983725, 0, 0, 0, 0, 66845, 0, 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, 69648, 9040, + 0, 64665, 119557, 0, 0, 0, 69638, 12602, 983068, 3852, 0, 67872, 12231, + 11317, 0, 119812, 0, 11410, 10964, 12274, 122890, 100524, 0, 119810, + 9865, 195019, 0, 0, 0, 0, 12276, 0, 0, 0, 0, 119613, 0, 111214, 10467, 0, + 2443, 10918, 0, 0, 1001, 9241, 1927, 0, 0, 0, 127885, 195022, 0, 113752, + 119830, 65678, 0, 0, 8260, 0, 7519, 11505, 119182, 0, 518, 0, 119832, 0, + 13204, 0, 857, 121252, 0, 0, 92336, 83177, 0, 0, 0, 0, 0, 0, 92762, 0, 0, + 120613, 67247, 1629, 0, 796, 0, 0, 74123, 72334, 127587, 72336, 43388, 0, + 43944, 72335, 478, 65151, 0, 128147, 0, 0, 0, 0, 0, 42933, 1206, 71209, + 43837, 0, 3843, 12011, 0, 3361, 0, 8121, 10715, 7578, 0, 0, 0, 10530, + 12348, 8653, 0, 0, 0, 9551, 0, 0, 784, 0, 0, 0, 0, 0, 0, 43937, 0, 0, + 43938, 43935, 73765, 66230, 0, 0, 0, 43936, 0, 43932, 11102, 0, 0, 42753, + 67165, 0, 78324, 0, 0, 6975, 917928, 5415, 12176, 0, 0, 3462, 43940, + 42629, 78691, 128016, 43942, 0, 9759, 0, 0, 78320, 8114, 78321, 78697, + 78696, 78695, 8710, 0, 118956, 0, 4051, 92657, 0, 71206, 0, 0, 0, 128857, + 0, 1619, 9703, 77986, 0, 42112, 0, 1875, 0, 42109, 0, 0, 71189, 121160, + 64907, 5396, 13144, 0, 0, 5575, 9675, 0, 5940, 226, 0, 6336, 0, 0, 0, + 5116, 64521, 0, 0, 0, 121390, 125048, 74138, 0, 74139, 128447, 92249, 0, + 0, 0, 0, 8935, 0, 0, 0, 0, 616, 78131, 65178, 4684, 78701, 983880, 74631, + 0, 0, 0, 74460, 42110, 0, 10870, 8557, 11054, 68664, 0, 0, 0, 0, 0, 0, 0, + 0, 65597, 0, 7651, 6846, 0, 0, 68868, 0, 0, 118966, 129302, 40997, + 127218, 0, 0, 40998, 0, 74488, 71182, 9800, 0, 0, 0, 41000, 0, 5114, + 55263, 3386, 70730, 42574, 0, 5115, 5394, 0, 128756, 5113, 0, 64855, 0, + 4425, 0, 0, 0, 43967, 0, 0, 0, 5112, 12173, 127037, 0, 0, 74998, 0, 0, 0, + 0, 0, 64874, 43964, 1587, 0, 0, 0, 0, 1369, 917931, 9959, 0, 43963, 4560, + 0, 0, 0, 0, 0, 0, 43961, 42601, 4514, 72149, 0, 0, 0, 65041, 10965, + 120905, 0, 0, 12542, 0, 65341, 0, 65829, 0, 0, 10475, 0, 0, 0, 0, 11795, + 0, 0, 0, 127102, 127101, 74956, 7099, 11275, 67681, 127096, 0, 9336, 0, + 42626, 43966, 7798, 64474, 64259, 0, 5730, 119809, 43018, 0, 93796, 0, 0, + 0, 69401, 0, 0, 5127, 11285, 0, 5495, 4273, 0, 74765, 10849, 6346, 5493, + 6342, 68636, 74319, 5492, 0, 0, 169, 5497, 125053, 0, 0, 68198, 0, 0, + 128417, 0, 0, 12738, 0, 983076, 5321, 0, 0, 0, 5323, 120732, 9773, + 125209, 4683, 74318, 0, 68823, 0, 0, 0, 0, 129553, 0, 0, 0, 0, 834, 0, + 1803, 0, 5733, 0, 0, 71312, 5731, 1381, 2891, 0, 0, 0, 64525, 0, 2881, + 92996, 93847, 9601, 2879, 0, 0, 73129, 5729, 0, 0, 0, 64881, 127905, + 9361, 0, 2887, 0, 3526, 6298, 0, 0, 0, 0, 0, 8572, 127863, 77896, 0, + 71174, 0, 0, 71197, 0, 12096, 0, 0, 0, 110745, 71176, 110746, 65279, 0, + 121236, 5734, 0, 0, 0, 0, 0, 41641, 12717, 0, 12552, 983615, 66713, 0, 0, + 41643, 110747, 0, 8713, 41640, 78657, 41645, 66712, 125196, 0, 66726, + 66711, 0, 93994, 0, 3472, 64863, 0, 121424, 0, 0, 0, 125203, 67837, 0, 0, + 0, 0, 0, 0, 121440, 0, 0, 129461, 119008, 92402, 65017, 0, 0, 66668, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121043, 66471, 12216, 0, + 40988, 0, 0, 0, 0, 0, 2396, 129078, 0, 0, 0, 64940, 0, 8321, 119823, + 128165, 100409, 83299, 996, 0, 0, 4249, 0, 83294, 92535, 8222, 0, 118875, + 71213, 0, 0, 0, 0, 8534, 72844, 40983, 0, 125195, 0, 12551, 73960, + 125193, 74469, 12558, 121039, 0, 10052, 40982, 129371, 0, 0, 0, 127403, + 0, 917559, 0, 0, 1563, 0, 0, 19911, 0, 0, 0, 71363, 0, 7797, 78708, + 10006, 0, 3308, 119134, 74940, 0, 0, 78488, 0, 0, 0, 0, 0, 128462, 9200, + 10046, 9612, 0, 8218, 66496, 0, 43742, 78489, 0, 0, 0, 0, 67826, 0, + 70056, 508, 128585, 0, 126539, 0, 0, 0, 0, 0, 0, 0, 124950, 0, 0, 0, 0, + 0, 0, 6659, 0, 0, 0, 0, 0, 0, 41634, 0, 41639, 71169, 11941, 0, 0, 0, + 42180, 68505, 43753, 3249, 41637, 93982, 12328, 501, 93985, 10601, 0, + 6503, 0, 92192, 0, 71181, 0, 6505, 74010, 0, 13064, 126112, 121105, 6500, + 5526, 0, 0, 0, 0, 92376, 0, 9678, 120832, 0, 41706, 0, 0, 0, 8936, 92964, + 119123, 4208, 0, 0, 0, 67742, 0, 74379, 128605, 0, 0, 92422, 983109, 0, + 66475, 0, 5027, 0, 0, 0, 5069, 0, 5028, 0, 0, 0, 5026, 0, 0, 6331, 0, 0, + 0, 0, 41076, 0, 74790, 0, 0, 0, 0, 5029, 0, 5317, 3598, 0, 41070, 92166, + 11185, 6663, 0, 6507, 0, 126079, 0, 1716, 983691, 0, 917824, 620, 41001, + 0, 917823, 43758, 0, 71116, 5024, 0, 41003, 0, 5025, 7297, 0, 75039, 0, + 119328, 65557, 0, 0, 983599, 0, 0, 0, 0, 43947, 43946, 0, 0, 128363, + 6105, 0, 119325, 983226, 0, 68203, 43945, 66491, 43939, 0, 68144, 78718, + 2301, 0, 0, 66490, 6979, 0, 7721, 0, 0, 1592, 0, 0, 121096, 41048, + 129358, 829, 0, 92406, 0, 120247, 0, 41056, 0, 0, 10953, 41066, 0, + 917813, 482, 0, 0, 0, 43606, 71185, 0, 0, 0, 72262, 110863, 72421, 12050, + 0, 5315, 917817, 0, 0, 42061, 917816, 0, 0, 68417, 917815, 0, 0, 42059, + 0, 0, 120723, 42058, 3960, 11043, 11337, 121358, 0, 0, 3958, 0, 0, + 917818, 0, 917819, 0, 0, 42064, 11959, 983695, 0, 0, 0, 0, 128498, 64336, + 10478, 92629, 70350, 120704, 0, 0, 42437, 1555, 0, 8691, 129656, 2215, + 41662, 119046, 0, 0, 0, 93952, 0, 66481, 41664, 0, 42578, 0, 41661, + 78715, 78714, 9356, 0, 129544, 0, 1286, 110701, 0, 0, 983206, 128925, + 42476, 0, 11156, 0, 0, 0, 0, 72123, 0, 10020, 43359, 72827, 0, 120946, + 41627, 0, 11979, 0, 41628, 533, 11931, 65225, 0, 125122, 0, 0, 68118, 0, + 4377, 0, 0, 8587, 72097, 13193, 64350, 68233, 0, 41924, 0, 7735, 0, + 127585, 120843, 0, 65820, 0, 0, 43461, 7757, 0, 0, 43787, 66493, 77943, + 4168, 43904, 73952, 0, 0, 121072, 4440, 43902, 77948, 66837, 77946, + 43903, 77944, 77945, 0, 120909, 120826, 120226, 66492, 43901, 64625, 0, + 0, 0, 0, 10013, 64434, 0, 983112, 0, 11782, 64382, 0, 0, 0, 0, 41630, + 630, 120960, 0, 0, 70165, 1043, 93017, 0, 0, 0, 124945, 313, 129590, 0, + 0, 65593, 7445, 43906, 5750, 42258, 0, 55222, 68222, 11268, 11225, 0, + 8526, 0, 0, 43894, 66495, 69990, 0, 92990, 0, 10707, 7863, 0, 0, 70692, + 631, 77952, 77953, 66443, 71171, 83313, 0, 0, 0, 13305, 77961, 43925, + 43924, 77956, 77957, 66903, 66328, 42381, 77962, 0, 0, 0, 0, 0, 0, 43899, + 66821, 77967, 9157, 77965, 77966, 77963, 77964, 0, 0, 180, 73904, 0, 0, + 66494, 12674, 43896, 0, 0, 43890, 43897, 0, 11535, 0, 66769, 5185, 7165, + 5521, 10334, 5519, 71329, 10302, 12351, 83333, 1027, 5181, 0, 5117, 0, + 5179, 73955, 6845, 991, 5189, 43676, 41647, 0, 73883, 92571, 77979, 3405, + 0, 0, 5523, 43915, 66487, 92459, 74943, 9549, 0, 125093, 43923, 0, 43682, + 74884, 120537, 0, 43921, 0, 71184, 0, 43922, 128709, 0, 10414, 9846, 0, + 10350, 0, 43918, 77981, 75075, 77978, 77980, 66485, 77977, 77973, 77974, + 78057, 43909, 73983, 12330, 0, 0, 0, 43910, 0, 3407, 6293, 0, 68149, + 43908, 129060, 0, 10209, 0, 4195, 0, 9010, 983686, 75072, 6332, 0, 0, + 65871, 0, 1736, 0, 3901, 0, 0, 65890, 128801, 10446, 0, 693, 9130, 314, + 78119, 64149, 0, 0, 0, 11026, 0, 5332, 6940, 0, 0, 127007, 119831, 0, + 273, 8165, 0, 83307, 0, 0, 12824, 43911, 4528, 5320, 6301, 43662, 6133, + 0, 9463, 73738, 127141, 10922, 121069, 0, 0, 0, 0, 0, 2569, 0, 2326, 0, + 2565, 0, 66401, 0, 0, 0, 0, 41848, 2567, 78620, 121145, 4044, 92646, 0, + 12233, 0, 9509, 0, 0, 127158, 7336, 0, 0, 0, 0, 0, 67235, 0, 0, 0, 0, + 2222, 66499, 0, 127170, 0, 10895, 0, 274, 983763, 1858, 0, 67849, 55251, + 0, 3133, 0, 71857, 0, 9610, 0, 8197, 0, 0, 0, 41665, 5868, 0, 0, 72120, + 0, 19940, 43668, 41667, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 6464, 92750, + 2996, 125221, 0, 68481, 41835, 4047, 41842, 0, 0, 129601, 0, 0, 0, 0, + 293, 0, 0, 64791, 41827, 0, 0, 10579, 8560, 0, 0, 118835, 4803, 73805, + 1739, 0, 3900, 128967, 73737, 0, 0, 73957, 0, 66474, 41971, 0, 0, 0, 0, + 0, 11716, 66473, 0, 121071, 0, 128080, 0, 0, 0, 0, 0, 0, 0, 6632, 73861, + 0, 74770, 0, 0, 8914, 0, 0, 3183, 1435, 0, 0, 0, 0, 0, 0, 5746, 67392, 0, + 0, 0, 83506, 0, 7082, 71481, 12618, 5059, 983597, 83524, 43604, 0, 0, 0, + 0, 0, 0, 8227, 0, 1218, 0, 64416, 65848, 92884, 0, 0, 0, 126987, 0, 0, 0, + 0, 0, 0, 83515, 83507, 0, 0, 42672, 71194, 43224, 0, 0, 0, 0, 0, 0, 0, + 65905, 0, 42662, 0, 121159, 0, 129536, 0, 7794, 0, 0, 6377, 0, 126080, + 3669, 3968, 0, 71319, 69658, 129550, 0, 66296, 0, 0, 0, 0, 124998, 6699, + 126120, 0, 0, 66678, 0, 0, 0, 8409, 119527, 19967, 0, 0, 9502, 0, 0, + 6115, 0, 41654, 0, 0, 0, 41655, 113779, 43975, 72427, 0, 0, 0, 0, 41657, + 10778, 0, 9533, 184, 1553, 128868, 0, 0, 0, 0, 0, 0, 0, 0, 73697, 0, + 92480, 0, 128938, 74292, 0, 5157, 4020, 0, 128154, 43788, 64818, 0, 0, 0, + 92979, 0, 0, 74377, 11029, 66651, 0, 0, 125202, 0, 0, 7877, 121070, 0, 0, + 127953, 2810, 9955, 0, 0, 42817, 0, 65122, 11715, 0, 0, 0, 71270, 0, 0, + 0, 0, 0, 70199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78222, 127981, 0, 0, 0, 0, + 0, 11290, 0, 0, 0, 0, 8315, 0, 0, 0, 74595, 0, 0, 0, 42531, 0, 0, 0, + 74589, 43993, 0, 0, 0, 0, 43690, 0, 119139, 42730, 0, 0, 0, 64926, 0, 0, + 43830, 65257, 0, 42728, 0, 128697, 123150, 0, 43540, 0, 0, 12725, 72993, + 78635, 127826, 223, 0, 69675, 0, 0, 0, 0, 0, 0, 42605, 0, 0, 0, 0, 0, 0, + 0, 0, 78621, 0, 78619, 119062, 0, 0, 0, 42676, 129353, 64800, 78617, + 83504, 68126, 1213, 0, 0, 797, 0, 0, 83021, 83005, 64387, 4115, 0, 0, 0, + 0, 10679, 83001, 121091, 0, 64276, 83498, 13168, 983710, 0, 10136, 0, 0, + 65088, 0, 4262, 0, 0, 0, 10701, 0, 3101, 0, 123204, 0, 0, 11373, 0, 0, 0, + 9117, 0, 0, 4539, 0, 0, 12727, 0, 0, 0, 43684, 74567, 68877, 983707, + 12724, 73940, 0, 0, 0, 0, 0, 7947, 12003, 0, 74593, 121140, 69653, 74807, + 42018, 0, 0, 0, 65888, 0, 0, 69683, 0, 120306, 0, 0, 12595, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 69848, 68307, 0, 4405, 0, 128336, 129032, 69216, 0, + 0, 0, 0, 6817, 67400, 120314, 0, 0, 998, 0, 13105, 120313, 64327, 1558, + 0, 1991, 7882, 0, 0, 0, 530, 0, 0, 0, 12002, 0, 68422, 0, 10979, 0, + 41823, 70696, 0, 0, 7896, 0, 66676, 0, 120325, 0, 0, 129407, 94033, 0, + 6311, 110725, 41698, 0, 12049, 78133, 0, 125020, 41705, 0, 0, 121298, 0, + 66822, 0, 65389, 0, 66027, 0, 0, 41699, 8340, 0, 69776, 0, 128639, 0, + 1988, 5407, 69978, 0, 65912, 93059, 0, 2336, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 126238, 0, 19913, 0, 113733, 0, 0, 74279, 0, 10956, 0, 41674, 19964, + 41679, 65084, 41675, 195031, 0, 0, 0, 0, 983089, 0, 10794, 128961, 13217, + 0, 0, 0, 5280, 0, 0, 12905, 41610, 11532, 0, 0, 768, 120545, 442, 0, 0, + 0, 64081, 41682, 0, 41693, 0, 77993, 77994, 0, 4804, 6994, 0, 0, 0, + 41696, 467, 983915, 0, 0, 0, 0, 8678, 0, 69682, 64801, 0, 0, 0, 0, 64093, + 12043, 0, 69666, 0, 2029, 65191, 119246, 42847, 0, 0, 0, 0, 0, 0, 0, + 70339, 126116, 0, 0, 8019, 73856, 0, 0, 0, 0, 2355, 12150, 65725, 77988, + 77989, 68033, 77987, 0, 77985, 0, 0, 68388, 0, 74171, 0, 0, 0, 11301, + 78013, 78008, 78010, 9874, 78007, 983326, 71064, 3050, 0, 0, 0, 78016, + 78017, 71852, 78015, 0, 0, 0, 92242, 0, 69642, 0, 0, 0, 0, 0, 0, 78025, + 0, 78023, 78024, 11847, 10545, 0, 10887, 0, 123179, 0, 0, 0, 83352, + 64942, 92363, 9996, 8508, 0, 0, 8195, 0, 42171, 0, 3722, 0, 63751, 0, 0, + 92637, 69670, 0, 41552, 69854, 0, 78639, 0, 0, 129374, 128978, 0, 0, 0, + 7920, 70285, 4021, 0, 0, 0, 119663, 0, 0, 78021, 78022, 78019, 78020, + 1802, 78018, 0, 74895, 41659, 41671, 1827, 0, 64396, 41668, 128524, + 41673, 0, 11422, 71846, 0, 11370, 0, 68412, 41345, 0, 0, 0, 0, 0, 0, + 65114, 0, 2104, 64858, 0, 0, 7553, 0, 41560, 11970, 0, 917920, 0, 68495, + 74131, 74130, 0, 0, 0, 611, 74129, 64871, 0, 0, 0, 0, 74854, 0, 70466, 0, + 0, 0, 121147, 0, 68487, 41669, 7094, 917921, 0, 123144, 74054, 0, 0, 0, + 839, 0, 7695, 0, 0, 0, 92202, 0, 121053, 123157, 67885, 0, 7206, 0, 6647, + 43986, 0, 0, 0, 0, 0, 0, 127936, 43748, 66746, 0, 12298, 110802, 983992, + 110800, 64924, 0, 73931, 9468, 74245, 0, 0, 74246, 0, 0, 118830, 0, + 71851, 1279, 0, 6224, 0, 92405, 128601, 0, 128997, 0, 0, 0, 5032, 0, 0, + 0, 0, 0, 5034, 0, 0, 72846, 42702, 0, 0, 13294, 0, 64869, 0, 67808, 9129, + 123632, 0, 0, 120819, 68387, 120168, 120169, 120170, 120171, 5518, 4174, + 120166, 120167, 120160, 120161, 120162, 434, 41437, 66212, 120158, + 120159, 0, 0, 118867, 0, 524, 0, 74029, 0, 126559, 0, 0, 0, 10355, 10419, + 74025, 77847, 0, 69725, 0, 120656, 0, 67876, 0, 0, 0, 74145, 74039, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5445, 0, 93779, 71855, 7391, 8989, 0, 74068, 0, + 0, 0, 0, 4962, 0, 8855, 0, 70820, 0, 0, 0, 0, 71847, 0, 0, 0, 10451, 0, + 67653, 120153, 12443, 120155, 9947, 120149, 120150, 120151, 13128, 0, + 120146, 120147, 0, 0, 0, 0, 0, 0, 74059, 74062, 6217, 74053, 43846, 0, + 74049, 0, 0, 0, 0, 0, 0, 0, 0, 42595, 0, 68112, 118860, 0, 0, 92497, + 74949, 128953, 126245, 0, 0, 0, 129684, 0, 119251, 0, 0, 0, 0, 0, 6216, + 0, 0, 9455, 127027, 8124, 128851, 0, 6944, 0, 0, 0, 2828, 128550, 531, + 42638, 0, 0, 0, 43428, 0, 3614, 2827, 9696, 0, 0, 0, 4354, 0, 78562, + 78561, 0, 120691, 0, 42599, 42597, 0, 68829, 125012, 0, 127277, 0, + 120421, 0, 983164, 0, 0, 10121, 120422, 74950, 123142, 69715, 0, 0, + 120423, 120630, 12608, 125244, 0, 74144, 9700, 12580, 0, 128911, 0, + 71864, 0, 74071, 0, 0, 12713, 0, 70402, 0, 0, 0, 1734, 0, 0, 0, 0, + 118951, 231, 0, 74167, 542, 0, 0, 0, 0, 128074, 0, 121343, 0, 4446, + 10584, 74235, 0, 4037, 0, 0, 0, 5687, 0, 0, 0, 0, 0, 0, 78434, 0, 0, + 113709, 74284, 0, 0, 0, 126495, 0, 0, 0, 74482, 93978, 1709, 69721, 9909, + 92286, 0, 0, 0, 55229, 8667, 0, 0, 0, 0, 0, 0, 0, 0, 127586, 1226, 6930, + 0, 71736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41500, 0, 311, 74282, 6221, 92988, + 0, 67682, 0, 120528, 122901, 74272, 0, 0, 0, 0, 69667, 0, 124933, 74456, + 74302, 42589, 0, 0, 0, 0, 0, 0, 0, 0, 41508, 0, 323, 125211, 0, 42698, + 8131, 0, 4625, 0, 4630, 0, 0, 0, 74316, 78417, 2668, 92483, 0, 42640, 0, + 2519, 0, 92474, 92479, 0, 983085, 5049, 42659, 119011, 0, 7754, 10854, + 8738, 74623, 0, 0, 0, 649, 0, 0, 0, 0, 0, 1013, 70707, 68212, 705, 0, 0, + 127803, 1183, 126519, 9320, 0, 0, 8157, 0, 0, 0, 0, 0, 0, 0, 11913, 0, + 42848, 0, 64925, 0, 0, 70693, 0, 0, 2051, 0, 0, 0, 0, 0, 0, 0, 8466, 0, + 4626, 8464, 8472, 68844, 4629, 8499, 0, 0, 4624, 194623, 0, 94025, 0, + 7805, 0, 94007, 6935, 0, 0, 0, 0, 0, 0, 0, 8492, 0, 8459, 0, 8497, 8496, + 0, 0, 0, 0, 0, 0, 0, 0, 65849, 0, 0, 0, 12451, 3328, 8684, 0, 6102, 0, + 5298, 0, 5294, 0, 129615, 0, 0, 0, 0, 43617, 0, 0, 0, 0, 0, 77863, + 128695, 0, 0, 0, 0, 0, 5292, 0, 0, 42688, 5302, 3970, 0, 0, 1793, 0, 0, + 0, 0, 0, 65263, 0, 0, 0, 0, 0, 0, 13219, 9569, 0, 74383, 0, 0, 72157, 0, + 42949, 0, 0, 0, 5322, 0, 0, 43631, 5324, 0, 128694, 41614, 65269, 6230, + 0, 0, 0, 3360, 0, 11523, 72726, 92488, 9926, 7197, 0, 68429, 126575, + 41821, 1249, 0, 127951, 0, 123641, 0, 0, 0, 74459, 41807, 0, 41815, 0, 0, + 0, 0, 0, 128248, 0, 66835, 0, 0, 72145, 41800, 0, 0, 0, 41811, 74466, + 93966, 6670, 77882, 0, 0, 43092, 0, 0, 0, 0, 0, 128655, 0, 0, 0, 0, + 74501, 74005, 0, 74387, 69860, 315, 12813, 128556, 72409, 0, 72408, 0, 0, + 73061, 0, 0, 1378, 0, 0, 0, 72407, 3066, 0, 0, 72406, 0, 0, 0, 8787, + 194615, 0, 41618, 0, 0, 0, 194614, 64652, 194611, 42088, 125226, 0, 0, 0, + 0, 7176, 43756, 0, 0, 74492, 0, 74534, 0, 0, 0, 127199, 0, 128630, 74525, + 0, 194594, 12930, 7168, 74514, 0, 74515, 0, 128919, 43962, 9527, 120659, + 70123, 12977, 69723, 0, 93783, 194598, 41236, 92235, 65168, 118838, + 41237, 5848, 0, 194600, 3670, 194601, 0, 0, 0, 7890, 0, 11298, 0, 0, + 6229, 0, 0, 0, 194593, 128907, 0, 0, 0, 4120, 65337, 65336, 0, 0, 0, 0, + 9366, 0, 0, 0, 65327, 65326, 65325, 65324, 65323, 42216, 65321, 65320, + 65335, 65334, 65333, 65332, 65331, 65330, 65329, 42689, 0, 43943, 118885, + 42073, 6785, 68491, 0, 42076, 7196, 65318, 2035, 65316, 4106, 65314, + 65313, 42074, 0, 41228, 0, 0, 41241, 93786, 41239, 43533, 0, 7189, + 194602, 0, 43941, 0, 42802, 0, 8487, 0, 0, 4615, 12695, 0, 0, 12175, + 100414, 0, 0, 7809, 0, 0, 0, 0, 6590, 69762, 0, 64738, 0, 0, 0, 0, 0, 0, + 2025, 0, 0, 0, 10637, 71860, 0, 1570, 43839, 2835, 83052, 10624, 43623, + 194587, 0, 78433, 0, 42812, 0, 2825, 0, 128287, 0, 2821, 0, 92327, 7365, + 83043, 0, 68296, 0, 2823, 0, 0, 0, 2831, 0, 0, 11465, 0, 0, 0, 0, 0, + 7181, 0, 41332, 0, 12333, 0, 0, 0, 0, 0, 9883, 127294, 73906, 70751, 0, + 71863, 0, 0, 0, 0, 0, 0, 43741, 0, 8166, 70739, 0, 0, 74535, 0, 65297, + 68294, 571, 0, 8752, 0, 5288, 118822, 1541, 0, 127284, 8864, 0, 0, 0, 0, + 0, 113778, 12151, 0, 66874, 0, 1035, 0, 0, 7881, 701, 65936, 128493, 0, + 70462, 0, 11403, 0, 0, 82991, 0, 983142, 70472, 3994, 11421, 121217, + 127297, 127242, 127300, 70659, 127303, 0, 125205, 2855, 127828, 0, 41621, + 68214, 0, 0, 10654, 82945, 119226, 12164, 41623, 7906, 0, 74297, 7182, 0, + 83069, 0, 0, 0, 0, 121115, 0, 0, 747, 0, 92463, 12019, 43136, 0, 110861, + 0, 0, 8001, 0, 0, 69394, 0, 0, 0, 68373, 0, 0, 0, 128279, 0, 71915, 0, 0, + 7282, 94066, 0, 0, 0, 0, 0, 5286, 83061, 0, 3718, 0, 83057, 0, 194584, + 71905, 0, 128480, 0, 0, 0, 0, 9206, 82980, 113824, 6802, 0, 41653, 0, + 1241, 0, 0, 0, 0, 68124, 41651, 42937, 0, 83042, 41650, 0, 83037, 0, + 12914, 2814, 0, 119552, 0, 0, 0, 118900, 0, 0, 0, 917546, 71862, 0, 0, 0, + 3494, 10189, 69784, 0, 0, 71861, 0, 0, 65875, 0, 0, 127762, 0, 74215, + 43065, 0, 0, 7200, 0, 3261, 0, 0, 0, 65889, 71888, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 129424, 0, 635, 0, 0, 74753, 0, 92420, 73997, 0, 0, 43905, 0, + 118834, 126125, 0, 6667, 0, 983263, 0, 0, 125200, 0, 0, 0, 0, 83137, 0, + 0, 0, 0, 0, 121104, 127856, 125112, 71885, 0, 120125, 7866, 194573, + 92770, 194574, 0, 120140, 126074, 2849, 0, 0, 42157, 12960, 0, 11812, 0, + 74509, 0, 69881, 0, 0, 0, 123156, 7178, 0, 0, 0, 0, 129041, 11534, 1967, + 0, 0, 71361, 7015, 120298, 72757, 0, 12989, 0, 9368, 983638, 1624, 43270, + 0, 0, 10818, 0, 83091, 0, 120908, 0, 0, 0, 0, 0, 0, 6169, 12871, 0, 2798, + 65176, 4958, 42752, 119025, 0, 0, 0, 70346, 66448, 0, 113780, 68364, 0, + 0, 0, 68360, 0, 73746, 120945, 68352, 0, 73787, 83110, 2154, 7199, 64955, + 0, 0, 0, 0, 0, 66507, 0, 69853, 0, 0, 0, 0, 0, 0, 0, 92517, 118882, + 120301, 13297, 0, 129446, 0, 0, 0, 0, 6658, 8045, 0, 0, 983854, 92319, + 83101, 0, 72126, 0, 0, 0, 2416, 3310, 0, 0, 379, 0, 43755, 0, 0, 0, + 68362, 1284, 0, 73756, 0, 0, 83141, 70784, 0, 0, 0, 0, 8515, 83144, + 83143, 0, 0, 0, 8529, 93782, 0, 7564, 0, 0, 0, 0, 73757, 73760, 42359, 0, + 2031, 0, 7202, 0, 12676, 0, 0, 128418, 0, 7710, 1610, 73801, 0, 0, 0, + 983607, 43917, 0, 9974, 228, 0, 10398, 0, 0, 0, 92241, 70062, 118927, + 42999, 1725, 65533, 8196, 9352, 0, 0, 66868, 0, 8502, 5762, 0, 0, 43898, + 0, 0, 0, 0, 43914, 0, 126507, 64598, 13001, 9326, 83082, 43916, 1557, 0, + 983860, 6330, 6805, 8631, 2545, 70052, 0, 0, 0, 0, 70410, 0, 42762, 0, + 42914, 126516, 262, 1637, 0, 83025, 129491, 0, 128757, 0, 0, 0, 128922, + 0, 43658, 0, 0, 129183, 6419, 0, 0, 0, 0, 93989, 0, 0, 7194, 5291, 0, + 43666, 0, 0, 0, 0, 128293, 0, 12881, 123596, 0, 73842, 0, 9011, 0, 0, 0, + 70436, 179, 43644, 0, 0, 64747, 0, 118813, 0, 0, 121389, 0, 126629, 0, + 73850, 2801, 119837, 42069, 119839, 119838, 119841, 42072, 92736, 119842, + 0, 0, 0, 8377, 0, 42070, 119313, 119834, 119853, 4389, 43656, 1633, + 119857, 119856, 119859, 11119, 119845, 119844, 9967, 119846, 119849, + 4612, 119851, 119850, 42913, 70456, 0, 0, 10782, 66898, 0, 119141, 0, 0, + 0, 11541, 69636, 0, 0, 119614, 2731, 0, 0, 0, 4102, 0, 73878, 0, 0, 0, 0, + 0, 11283, 0, 0, 0, 0, 0, 43674, 0, 0, 126705, 0, 0, 0, 0, 11142, 128304, + 0, 12975, 0, 123208, 0, 0, 74072, 0, 55269, 0, 0, 0, 78577, 78576, 0, 0, + 82966, 82974, 70448, 0, 0, 82968, 0, 0, 0, 0, 0, 113809, 0, 69399, 64909, + 0, 11790, 74019, 0, 128066, 0, 8561, 94076, 129481, 125045, 0, 65674, + 7230, 0, 0, 8778, 0, 0, 67725, 2071, 0, 6459, 68325, 7628, 65092, 73903, + 0, 11342, 129388, 0, 0, 93965, 94081, 0, 11810, 70057, 10723, 967, 0, + 121116, 73905, 0, 6387, 0, 12307, 43913, 121089, 0, 127584, 0, 1886, 0, + 43895, 870, 7648, 0, 7662, 7652, 876, 871, 877, 7665, 878, 42015, 879, + 43692, 4563, 0, 0, 0, 73072, 867, 9520, 872, 7656, 868, 873, 7642, 7659, + 869, 874, 7644, 0, 875, 790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68452, 0, + 0, 42067, 0, 0, 0, 12292, 0, 0, 0, 42012, 0, 0, 83388, 0, 0, 8494, 4611, + 0, 72344, 0, 9679, 0, 0, 0, 0, 93015, 0, 74364, 4628, 4245, 0, 0, 0, + 1851, 0, 127189, 0, 0, 0, 118897, 0, 64674, 124971, 983868, 8829, 983674, + 128864, 0, 0, 0, 0, 8809, 983677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7427, 0, + 4588, 43680, 72300, 74484, 0, 0, 0, 0, 113787, 74363, 129043, 0, 793, 0, + 11197, 0, 0, 0, 842, 0, 8208, 70833, 0, 1647, 0, 70841, 0, 0, 818, 0, 0, + 0, 0, 0, 0, 120594, 0, 0, 70179, 0, 13167, 66359, 0, 127172, 0, 4969, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2840, 0, 0, 0, 66887, 65877, 9068, 0, 68194, 0, + 0, 12991, 0, 2651, 68016, 983896, 0, 983259, 70835, 0, 70844, 43648, 0, + 0, 0, 0, 0, 0, 64372, 121064, 7458, 655, 752, 7457, 7456, 7452, 3285, + 74894, 11152, 73099, 0, 2391, 93766, 92271, 671, 7435, 7434, 618, 668, + 610, 42800, 7431, 7451, 42801, 640, 42927, 7448, 7439, 628, 3905, 100742, + 0, 0, 0, 67850, 0, 0, 0, 4605, 0, 100745, 43372, 65945, 72710, 0, 119590, + 0, 0, 70495, 987, 71229, 11572, 0, 0, 10002, 9971, 70673, 0, 0, 0, 0, 0, + 0, 11334, 0, 129493, 42364, 11503, 0, 0, 0, 4627, 70090, 127784, 0, 0, + 74046, 68872, 92562, 0, 0, 0, 0, 0, 0, 0, 42569, 64965, 0, 0, 10516, 0, + 12190, 0, 42140, 0, 0, 0, 0, 9887, 0, 4000, 7429, 7428, 665, 7424, 0, 0, + 7884, 0, 0, 0, 0, 0, 2509, 0, 120573, 0, 0, 92449, 0, 10690, 0, 119114, + 126226, 0, 0, 73080, 4590, 0, 74440, 0, 0, 0, 1708, 0, 0, 983609, 0, 0, + 69226, 69974, 8813, 0, 1066, 0, 0, 0, 127921, 70447, 0, 0, 0, 72343, 0, + 7516, 0, 0, 0, 8034, 0, 0, 3631, 110696, 0, 0, 8416, 110694, 0, 0, 0, + 110692, 74621, 0, 70185, 0, 74850, 0, 0, 12099, 70475, 0, 6252, 0, 0, 0, + 0, 0, 0, 66368, 0, 64956, 7071, 129070, 70457, 128159, 118800, 0, 0, 0, + 9357, 0, 1773, 0, 125092, 0, 68451, 7745, 9844, 0, 0, 94, 1880, 120929, + 0, 0, 0, 0, 0, 0, 0, 0, 11237, 0, 129173, 0, 0, 0, 1757, 6964, 42480, + 72823, 0, 120806, 0, 0, 7731, 0, 0, 127883, 0, 110810, 43988, 70423, + 74758, 0, 7592, 856, 74299, 0, 0, 0, 78138, 1459, 0, 0, 0, 0, 0, 1504, 0, + 0, 0, 0, 7529, 0, 0, 0, 0, 12594, 0, 0, 336, 0, 7509, 0, 0, 0, 0, 127882, + 0, 0, 0, 65859, 0, 983967, 43062, 124948, 0, 0, 0, 0, 12970, 0, 0, 0, 0, + 0, 0, 0, 119247, 0, 65068, 74291, 0, 7069, 0, 0, 0, 11130, 2087, 0, 0, 0, + 0, 0, 0, 92747, 0, 92614, 2091, 0, 2090, 0, 0, 7117, 2077, 72281, 0, + 77889, 2083, 0, 71196, 0, 0, 92649, 0, 0, 0, 0, 4165, 8746, 0, 0, 0, 0, + 129572, 7066, 0, 70415, 128135, 0, 0, 7786, 127766, 2233, 0, 124965, + 121122, 2302, 0, 0, 7056, 0, 0, 0, 0, 0, 0, 126506, 6920, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 983099, 70438, 2613, 0, 0, 110734, 0, 74571, 42760, 0, 0, + 0, 0, 0, 0, 71843, 0, 0, 70506, 1246, 74243, 0, 0, 41008, 0, 0, 0, 921, + 70048, 0, 12702, 0, 0, 1566, 8407, 0, 64653, 0, 74617, 0, 0, 72711, 5313, + 951, 0, 0, 0, 0, 0, 4009, 70277, 71844, 0, 83123, 0, 72250, 0, 119898, + 113760, 0, 0, 0, 0, 70024, 0, 0, 119892, 0, 0, 0, 119890, 2579, 119906, + 3177, 11357, 69224, 0, 0, 83130, 64734, 0, 9822, 110670, 70471, 110668, + 0, 110666, 0, 0, 0, 0, 9851, 983729, 110673, 9059, 110671, 110672, 0, + 41687, 129054, 0, 71842, 70178, 0, 0, 1777, 0, 10158, 69767, 0, 42366, + 70444, 0, 0, 0, 70127, 83377, 5989, 110716, 74636, 126999, 0, 41685, 0, + 0, 9769, 41684, 0, 6225, 111328, 11740, 0, 118840, 0, 2600, 0, 70416, 0, + 0, 3666, 70420, 0, 0, 0, 0, 74542, 69771, 0, 0, 0, 0, 0, 69765, 0, 252, + 0, 69769, 0, 194616, 0, 69763, 0, 0, 0, 0, 0, 0, 0, 120947, 0, 129410, 0, + 0, 0, 68323, 125219, 0, 119188, 0, 0, 121335, 0, 0, 0, 0, 0, 7764, + 983726, 11094, 120825, 0, 0, 92505, 8298, 0, 0, 0, 0, 0, 64449, 0, + 126650, 0, 0, 0, 70442, 0, 0, 0, 0, 7774, 10607, 0, 0, 0, 0, 0, 120764, + 0, 0, 0, 0, 3458, 0, 70053, 0, 120995, 0, 2602, 0, 0, 0, 74907, 0, 0, 0, + 0, 172, 0, 4971, 70419, 1889, 7238, 0, 0, 0, 8257, 0, 0, 0, 129570, 0, + 111342, 983855, 0, 43366, 43363, 9807, 0, 0, 0, 72247, 64479, 0, 0, 0, + 113707, 0, 10900, 121355, 0, 0, 12048, 0, 64292, 0, 0, 0, 6099, 94084, + 129486, 0, 0, 299, 0, 8525, 92356, 0, 0, 111338, 0, 92564, 3075, 0, + 94053, 0, 94050, 0, 0, 70440, 0, 123590, 0, 0, 0, 2581, 11395, 0, 0, 0, + 0, 128584, 0, 0, 129423, 0, 118855, 0, 0, 0, 7204, 70065, 2588, 2914, + 7011, 55281, 0, 7466, 0, 2883, 42253, 83118, 0, 0, 0, 123598, 0, 41230, + 68299, 0, 43571, 0, 6219, 0, 9980, 41232, 92245, 0, 66036, 41229, 118967, + 0, 120666, 94016, 0, 12711, 0, 0, 74289, 68472, 42857, 0, 0, 0, 0, + 127306, 119006, 0, 11380, 72348, 0, 0, 0, 0, 0, 0, 0, 983583, 12722, 0, + 922, 0, 0, 983126, 74958, 3218, 120471, 120470, 120469, 120476, 120475, + 8569, 11404, 70450, 120463, 3214, 120461, 120468, 74910, 3207, 120465, + 78729, 78728, 78727, 0, 120460, 7425, 3205, 0, 78737, 78736, 71729, + 43383, 78733, 78732, 2606, 78730, 73897, 0, 11496, 1173, 0, 0, 129135, 0, + 0, 0, 120737, 120953, 120872, 120629, 378, 2610, 0, 0, 0, 0, 0, 37, 7068, + 0, 120480, 70421, 3209, 120477, 0, 120483, 9768, 120481, 0, 0, 0, 0, 0, + 0, 65510, 0, 100625, 0, 0, 0, 100627, 0, 126633, 0, 7060, 100628, 0, + 127752, 0, 0, 70428, 71463, 0, 7380, 0, 0, 100593, 126997, 0, 128737, 0, + 71465, 121030, 3243, 0, 0, 0, 7050, 0, 70050, 0, 0, 0, 71466, 8203, + 71102, 68241, 0, 65211, 194599, 0, 0, 0, 779, 125061, 64367, 100906, + 69901, 8193, 55279, 0, 0, 0, 7065, 0, 4346, 0, 0, 908, 0, 0, 8982, 0, 0, + 0, 782, 0, 10883, 0, 0, 129396, 65542, 121302, 0, 68650, 100575, 92244, + 0, 0, 111351, 0, 4376, 0, 11787, 12961, 0, 0, 42888, 0, 100610, 6231, 0, + 65713, 100608, 1783, 0, 68238, 0, 0, 0, 194945, 0, 0, 0, 68653, 0, + 983051, 0, 764, 0, 0, 43531, 0, 9033, 0, 0, 6223, 11042, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 120648, 0, 0, 0, 0, 0, 0, 0, 0, 1478, 0, 11825, + 2607, 0, 0, 0, 74543, 0, 0, 100588, 6132, 0, 0, 0, 70058, 0, 0, 0, 43537, + 6761, 10093, 4369, 0, 0, 73735, 100564, 3947, 110778, 0, 0, 0, 0, 100942, + 0, 0, 0, 0, 0, 0, 7686, 0, 0, 0, 100934, 0, 100944, 66577, 41221, 0, + 42281, 0, 74024, 12293, 0, 94014, 11794, 0, 0, 1737, 0, 0, 0, 7205, 0, + 9335, 12850, 0, 2272, 7055, 0, 0, 0, 67751, 0, 0, 6780, 65067, 0, 1327, + 68393, 983570, 0, 41217, 0, 10018, 0, 0, 0, 100611, 68176, 41219, 0, + 4147, 983170, 41216, 983693, 2616, 70197, 68461, 65234, 0, 0, 0, 0, + 119660, 0, 0, 0, 0, 127930, 119580, 70675, 64943, 2608, 1470, 0, 0, 6227, + 0, 0, 74775, 0, 0, 72320, 101024, 0, 129535, 0, 0, 0, 0, 0, 10876, 92482, + 0, 0, 5834, 0, 6222, 0, 0, 12086, 0, 1600, 64309, 0, 0, 68883, 127957, + 93836, 0, 8882, 0, 129415, 2570, 0, 0, 194606, 0, 0, 1234, 0, 13115, + 110743, 110740, 100923, 5002, 110739, 41286, 100926, 127019, 0, 0, 0, 0, + 0, 0, 0, 41289, 0, 0, 75051, 41272, 0, 0, 0, 0, 0, 0, 0, 41279, 0, 0, 0, + 11081, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9637, 7112, 77975, 128984, 0, 10886, 0, + 8548, 983841, 0, 0, 0, 8076, 43048, 8290, 8291, 43051, 92570, 0, 2596, 0, + 0, 41293, 0, 0, 2393, 7058, 66432, 0, 68673, 0, 0, 0, 0, 0, 128558, 0, 0, + 0, 0, 0, 64696, 0, 0, 121086, 74165, 0, 0, 0, 0, 0, 0, 7063, 983182, + 64893, 73096, 0, 68038, 113757, 709, 0, 0, 1876, 0, 0, 120868, 8137, + 110662, 67752, 70850, 100832, 245, 100831, 11456, 41233, 7070, 0, 94046, + 6136, 100835, 0, 100781, 41235, 0, 0, 100782, 100642, 432, 0, 100784, + 65437, 0, 0, 128909, 0, 100641, 100649, 0, 100648, 0, 43215, 0, 0, 0, 0, + 9052, 0, 0, 110826, 110827, 74784, 10580, 0, 100845, 0, 64640, 983175, + 74455, 0, 0, 70035, 0, 12652, 12199, 127030, 0, 2566, 11971, 0, 0, 1065, + 0, 0, 0, 2576, 0, 66819, 0, 983986, 0, 0, 0, 983050, 983826, 0, 2921, + 119104, 0, 5772, 12968, 70055, 0, 0, 0, 2580, 983822, 0, 0, 70032, 0, 0, + 0, 128148, 0, 0, 121308, 11346, 0, 12054, 100824, 92426, 0, 0, 13091, 0, + 0, 100821, 100828, 0, 127026, 128334, 74821, 0, 66295, 68037, 68047, + 127865, 13090, 0, 0, 0, 118985, 0, 0, 0, 0, 0, 127824, 0, 0, 100776, + 119319, 42356, 42432, 100778, 119317, 0, 0, 0, 78752, 70030, 66914, 0, 0, + 7061, 0, 3854, 0, 70020, 68413, 0, 42319, 0, 0, 7067, 0, 0, 0, 0, 0, 0, + 127797, 9029, 43543, 0, 2353, 119316, 0, 100769, 0, 100768, 983177, 0, 0, + 43664, 0, 0, 0, 12277, 0, 78122, 11066, 65233, 0, 41224, 0, 0, 3747, + 10522, 0, 129582, 1691, 41226, 0, 917565, 0, 41223, 121135, 121299, 697, + 0, 121051, 4244, 0, 0, 0, 13121, 128573, 0, 0, 0, 0, 0, 0, 0, 0, 65816, + 68111, 0, 127933, 0, 0, 0, 0, 0, 0, 66895, 74602, 0, 7123, 70038, 5785, + 9198, 0, 100810, 0, 7383, 64656, 0, 0, 0, 0, 0, 0, 0, 0, 13122, 0, 191, + 70060, 8585, 126610, 64411, 0, 0, 64850, 41072, 118996, 0, 0, 0, 0, + 100754, 127010, 100753, 0, 100756, 683, 396, 0, 100758, 0, 100757, 43058, + 100760, 343, 7129, 42680, 0, 0, 0, 0, 0, 100761, 0, 74040, 0, 1724, 0, + 119321, 0, 0, 6263, 0, 0, 0, 6592, 0, 983044, 0, 0, 0, 0, 3730, 1778, 0, + 0, 128854, 121254, 0, 9018, 0, 0, 0, 0, 92763, 5547, 0, 0, 128950, 0, 0, + 284, 8108, 0, 0, 74001, 0, 66460, 7174, 92703, 126072, 0, 0, 4394, + 127480, 0, 0, 0, 101082, 66459, 0, 7180, 101084, 0, 101092, 68800, 42471, + 0, 0, 67232, 64304, 42243, 101095, 2583, 0, 127804, 0, 0, 0, 71702, 3855, + 0, 0, 0, 0, 0, 0, 0, 92416, 7132, 0, 92743, 0, 64756, 3798, 6578, 0, 0, + 92481, 9774, 1275, 0, 0, 983056, 0, 120515, 7873, 0, 0, 0, 0, 0, 0, + 73994, 73992, 0, 0, 0, 41851, 0, 41846, 126485, 92337, 7633, 41849, + 68385, 70726, 3224, 0, 69806, 0, 0, 0, 1510, 68129, 0, 0, 0, 0, 12109, 0, + 0, 0, 0, 0, 78377, 1910, 8671, 78374, 127118, 70290, 0, 0, 0, 2654, 7893, + 0, 0, 0, 72394, 0, 67394, 0, 118970, 70066, 78372, 78371, 78370, 78369, + 78368, 0, 0, 0, 1733, 0, 2568, 0, 0, 0, 0, 41486, 0, 127839, 7116, 0, 0, + 0, 7185, 0, 0, 0, 0, 0, 120575, 120829, 0, 0, 0, 0, 92489, 0, 0, 0, + 70022, 7171, 0, 340, 0, 0, 72980, 0, 128535, 0, 124979, 94073, 0, 0, 0, + 11392, 92509, 0, 0, 0, 0, 0, 0, 0, 100632, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11948, 0, 6999, 617, 983806, 0, 3675, 10600, 0, 0, 74616, 2617, 0, 0, 0, + 128446, 0, 0, 8630, 194771, 7288, 983809, 5545, 983799, 2586, 0, 0, + 73123, 983832, 0, 0, 0, 70847, 0, 0, 0, 0, 11195, 71708, 0, 7835, 70040, + 0, 0, 92285, 0, 0, 72973, 0, 0, 100852, 71118, 10029, 983166, 0, 0, + 70033, 124978, 0, 0, 194782, 0, 0, 118975, 0, 0, 3903, 100893, 983839, 0, + 120555, 0, 93036, 110645, 0, 983565, 0, 0, 194773, 0, 0, 0, 127238, + 983803, 100919, 0, 100918, 64752, 0, 983138, 100920, 0, 43045, 100904, 0, + 0, 0, 66394, 7128, 0, 0, 0, 0, 0, 43044, 2604, 0, 100851, 43046, 121421, + 69985, 11768, 43043, 10470, 0, 7122, 194789, 4390, 454, 41397, 194792, 0, + 78762, 0, 0, 120576, 64572, 0, 68091, 2394, 2575, 113749, 0, 0, 74802, + 100913, 129280, 0, 0, 11989, 0, 0, 128856, 0, 0, 8249, 128172, 0, 0, + 6640, 74806, 2598, 513, 0, 6586, 127521, 129301, 120710, 65008, 0, 0, + 92515, 0, 194795, 66755, 0, 126585, 0, 43152, 78637, 0, 194797, 0, 69893, + 6582, 0, 0, 12839, 0, 0, 0, 0, 2444, 128759, 66620, 0, 0, 0, 0, 69894, 0, + 0, 0, 0, 4238, 11071, 9459, 68437, 78140, 78139, 0, 10079, 0, 0, 0, 0, 0, + 11907, 43928, 0, 0, 0, 0, 92490, 43929, 0, 43926, 64498, 0, 9506, 6978, + 126234, 0, 0, 0, 0, 43934, 0, 1122, 65564, 0, 71055, 0, 0, 1920, 0, + 43930, 827, 0, 0, 0, 0, 6577, 1304, 64733, 0, 10606, 0, 0, 0, 9329, + 92997, 9239, 74422, 0, 129373, 1222, 11076, 0, 69229, 43615, 8262, 72280, + 64627, 19909, 983554, 72279, 0, 287, 0, 233, 0, 0, 42816, 0, 0, 65140, + 128158, 8830, 0, 0, 10524, 41175, 125033, 72294, 0, 5296, 0, 0, 0, 0, 0, + 127154, 74858, 6516, 6515, 6514, 6513, 6512, 0, 70870, 0, 0, 0, 12122, + 92462, 100868, 43976, 1785, 92507, 0, 0, 917771, 5138, 0, 0, 0, 100884, + 0, 0, 0, 0, 0, 5134, 69980, 322, 4643, 5132, 0, 194942, 0, 5143, 0, + 72309, 119628, 0, 0, 72112, 0, 0, 0, 0, 0, 0, 0, 0, 73097, 0, 0, 0, + 127923, 0, 0, 0, 0, 0, 3234, 0, 100886, 0, 100889, 118924, 0, 0, 100875, + 68231, 74489, 100872, 120746, 0, 100876, 0, 12714, 0, 64585, 93775, 0, 0, + 0, 129428, 0, 11027, 0, 10059, 0, 64524, 9767, 789, 1749, 0, 66766, + 983991, 320, 0, 0, 0, 3049, 0, 6471, 0, 74479, 9925, 127356, 127355, + 127358, 4960, 5549, 127359, 127346, 127345, 127348, 5418, 127350, 3351, + 120892, 127351, 10610, 5414, 0, 0, 4286, 5421, 127344, 67867, 0, 127794, + 0, 6653, 0, 0, 64510, 0, 41868, 0, 128823, 0, 0, 11613, 70737, 12603, + 7131, 11108, 4566, 0, 0, 0, 0, 0, 124938, 127369, 0, 0, 5200, 0, 0, 0, + 9183, 127361, 74458, 73075, 395, 5482, 1376, 4349, 0, 0, 5196, 0, 6113, + 42009, 5205, 0, 120530, 0, 118973, 70467, 0, 0, 0, 0, 9126, 70498, 0, 0, + 0, 0, 0, 3203, 192, 0, 3385, 125075, 128620, 5383, 0, 0, 0, 5738, 69449, + 3336, 0, 5361, 9633, 0, 0, 0, 0, 8581, 0, 1260, 3149, 5359, 12962, 74955, + 10441, 5357, 0, 0, 0, 5364, 0, 11431, 0, 9101, 0, 0, 0, 0, 78378, 121155, + 42917, 0, 129179, 0, 0, 0, 43360, 78385, 78384, 78383, 78382, 78381, + 78380, 78379, 9319, 7097, 0, 127748, 0, 0, 0, 120632, 0, 71205, 0, 0, 0, + 1720, 0, 0, 0, 8622, 0, 70430, 68772, 0, 0, 0, 73084, 0, 0, 11921, 0, + 11769, 68782, 0, 0, 0, 0, 194571, 41586, 0, 0, 0, 3356, 194572, 64709, + 194575, 0, 7134, 0, 78389, 0, 677, 0, 0, 0, 129474, 68747, 0, 68751, + 3349, 74125, 0, 8927, 0, 0, 0, 0, 0, 0, 0, 6806, 0, 10190, 68755, 0, 0, + 0, 0, 0, 0, 0, 7113, 7586, 0, 10852, 0, 0, 4606, 0, 0, 70084, 0, 0, 1046, + 7124, 121192, 68753, 0, 5171, 65539, 0, 0, 0, 42394, 0, 74849, 127823, 0, + 5169, 11935, 0, 0, 3175, 0, 1537, 0, 5176, 8905, 4136, 4871, 78388, 0, 0, + 0, 0, 1128, 0, 0, 0, 74066, 0, 73069, 0, 0, 3662, 113767, 3378, 0, 71298, + 0, 127995, 6320, 71302, 983162, 10163, 0, 5165, 5126, 0, 66902, 41389, 0, + 71368, 3374, 0, 0, 7119, 0, 0, 3507, 0, 7629, 983629, 19925, 0, 68463, + 183, 127208, 127209, 70811, 10636, 0, 128465, 0, 0, 78772, 0, 0, 0, + 78768, 6580, 4332, 123584, 0, 10726, 66686, 127203, 127204, 127205, + 127206, 0, 70813, 127201, 127202, 0, 0, 5448, 41058, 5446, 0, 0, 71369, + 5442, 7135, 0, 0, 5451, 0, 78470, 0, 0, 0, 0, 11243, 10859, 65867, 10345, + 10409, 123606, 0, 0, 0, 42181, 0, 0, 2060, 0, 7111, 0, 0, 0, 0, 72741, 0, + 205, 0, 72346, 93771, 0, 9862, 6588, 43257, 0, 0, 0, 5505, 93789, 5503, + 65376, 0, 7125, 9819, 0, 0, 0, 5507, 12044, 194567, 0, 0, 0, 7109, 0, 0, + 7911, 10329, 10393, 8991, 125104, 69778, 11133, 129619, 8550, 0, 5592, + 2919, 0, 0, 5595, 0, 0, 4367, 0, 0, 5591, 41060, 5594, 0, 0, 13142, 5590, + 0, 72274, 118909, 75069, 123586, 9731, 71225, 64633, 0, 0, 71217, 121361, + 71227, 0, 0, 0, 0, 7137, 0, 0, 0, 10551, 10710, 0, 0, 0, 120570, 0, + 92364, 9936, 3348, 0, 0, 1444, 119058, 0, 74206, 983106, 0, 1442, 129080, + 0, 120959, 0, 0, 0, 0, 0, 0, 0, 3334, 73068, 118803, 0, 0, 71219, 69770, + 1651, 0, 8861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43626, 0, 0, 3344, 0, 0, + 12920, 0, 0, 0, 71853, 3438, 128711, 0, 0, 0, 0, 129068, 0, 0, 65117, 0, + 0, 0, 0, 66366, 128915, 0, 69772, 0, 0, 0, 0, 4973, 8784, 0, 0, 0, 0, 0, + 0, 0, 125198, 983283, 0, 0, 66413, 0, 0, 0, 0, 0, 9243, 2464, 0, 0, 3372, + 0, 0, 0, 70364, 7121, 0, 0, 0, 92163, 0, 0, 0, 0, 0, 0, 0, 3354, 0, 0, 0, + 118999, 0, 3876, 0, 127983, 0, 43696, 43380, 0, 74240, 0, 0, 0, 983966, + 75074, 6589, 0, 0, 120993, 0, 0, 69609, 0, 121210, 0, 10630, 74827, 0, + 121293, 0, 0, 121287, 917942, 121337, 121215, 0, 0, 0, 0, 0, 917940, + 3366, 0, 917938, 0, 0, 0, 71062, 0, 121197, 0, 6925, 71856, 0, 917929, + 66780, 66274, 0, 72768, 0, 917930, 129482, 11138, 0, 6754, 7118, 0, + 64672, 65296, 0, 118957, 0, 0, 12296, 68457, 121320, 0, 5282, 0, 72278, + 0, 0, 0, 0, 0, 0, 66355, 0, 0, 68073, 64343, 0, 92744, 195058, 195029, 0, + 0, 195056, 195027, 0, 0, 128814, 195025, 6584, 195026, 10657, 0, 74544, + 0, 1200, 12243, 0, 195062, 0, 129300, 11545, 0, 120493, 3343, 4424, + 11047, 0, 69863, 3896, 0, 0, 2947, 0, 0, 42221, 0, 68139, 13059, 7942, 0, + 3381, 0, 0, 0, 0, 0, 0, 78235, 0, 0, 0, 7044, 65800, 78236, 0, 7045, + 7175, 7047, 127884, 11791, 0, 0, 3881, 0, 0, 127395, 0, 0, 67075, 7106, + 0, 0, 0, 74211, 41897, 92513, 0, 73040, 66745, 0, 0, 0, 0, 121245, 0, + 64354, 73083, 8777, 0, 129108, 8884, 2385, 73067, 92450, 0, 0, 0, 42027, + 12114, 0, 0, 64936, 0, 0, 0, 0, 0, 126605, 0, 0, 0, 0, 73064, 0, 0, 0, 0, + 0, 0, 0, 73057, 0, 123587, 0, 0, 0, 0, 0, 70803, 0, 0, 124953, 0, 0, 0, + 7048, 11087, 123600, 92536, 7043, 9600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42050, + 0, 55289, 0, 0, 657, 0, 195054, 4461, 92903, 0, 0, 126490, 0, 4468, 0, 0, + 0, 4456, 73070, 10720, 123588, 0, 127520, 0, 0, 0, 195046, 260, 7714, + 74163, 2045, 0, 65064, 4466, 0, 0, 128087, 0, 41403, 0, 0, 0, 41406, + 120692, 0, 0, 73939, 0, 0, 0, 41404, 1165, 0, 4451, 13087, 0, 11258, 0, + 73855, 0, 43014, 5439, 12061, 74586, 3375, 128869, 0, 0, 0, 0, 0, 0, 0, + 113823, 67078, 0, 67079, 0, 0, 0, 0, 68459, 0, 0, 0, 0, 0, 0, 7280, 0, 0, + 0, 4868, 8297, 0, 0, 42791, 0, 66737, 66739, 0, 0, 5182, 0, 0, 72764, 0, + 4465, 0, 12135, 0, 4464, 0, 0, 977, 4458, 43827, 0, 0, 0, 0, 344, 0, 0, + 0, 0, 0, 92240, 0, 64443, 126995, 73078, 129525, 0, 0, 0, 43026, 7612, + 119591, 64413, 0, 0, 0, 0, 0, 0, 0, 0, 123622, 0, 119160, 10204, 127947, + 73063, 0, 0, 127236, 0, 68746, 0, 8852, 0, 0, 0, 0, 128427, 123597, 7932, + 0, 128463, 0, 0, 0, 0, 0, 0, 0, 74893, 0, 0, 73095, 0, 8650, 0, 0, 0, + 69900, 118872, 0, 70868, 0, 6719, 0, 0, 0, 72836, 0, 0, 118991, 0, + 123594, 73815, 4420, 0, 10583, 7760, 0, 0, 128752, 71711, 0, 128407, 0, + 0, 0, 9066, 0, 74795, 0, 0, 0, 0, 0, 0, 0, 42825, 41854, 5304, 0, 124942, + 6919, 8619, 0, 10038, 66454, 9592, 129049, 0, 0, 110771, 110777, 110772, + 0, 0, 0, 0, 0, 78498, 110773, 43624, 0, 7779, 0, 0, 9479, 78493, 0, 0, + 2224, 0, 0, 0, 0, 0, 42378, 3368, 0, 66804, 7697, 69237, 0, 2030, 0, + 68236, 8370, 0, 127961, 0, 0, 983350, 127903, 983348, 983347, 5174, + 42831, 983344, 70439, 983342, 8881, 119047, 0, 70433, 0, 0, 0, 0, 0, 0, + 9576, 0, 3347, 4160, 5154, 0, 3794, 0, 0, 0, 0, 0, 127916, 73073, 8381, + 4572, 71129, 126101, 0, 0, 0, 0, 0, 0, 0, 92283, 0, 0, 5799, 983339, + 70100, 983337, 983336, 983335, 43031, 64425, 65128, 983331, 0, 73059, 0, + 68616, 0, 0, 0, 0, 0, 0, 0, 123604, 0, 0, 283, 68665, 0, 532, 0, 0, + 983808, 0, 0, 3370, 73077, 119132, 5443, 71431, 0, 0, 0, 0, 0, 2298, 0, + 0, 0, 983330, 983329, 983328, 983327, 7144, 983325, 119600, 983323, + 983322, 983321, 0, 78816, 128833, 0, 0, 0, 0, 0, 0, 0, 0, 73088, 0, + 123592, 983933, 0, 0, 0, 0, 5186, 7360, 127837, 0, 12108, 0, 65124, 0, 0, + 0, 6326, 43344, 0, 0, 42562, 0, 0, 0, 983320, 65495, 983318, 101066, + 983316, 101065, 983314, 65490, 983312, 125034, 0, 101070, 0, 55245, + 128927, 1630, 128232, 65483, 0, 0, 0, 65476, 0, 0, 119214, 9283, 10183, + 0, 0, 65499, 0, 64593, 66758, 3376, 0, 0, 0, 101077, 43872, 12940, 0, 0, + 78587, 101078, 5957, 0, 8926, 983310, 983309, 983308, 10745, 10174, + 983305, 113793, 983303, 983302, 983301, 0, 123593, 5056, 0, 0, 0, 120773, + 0, 9812, 0, 4460, 127792, 73066, 0, 128038, 0, 123608, 0, 64278, 0, 0, 0, + 66760, 0, 0, 70122, 0, 0, 917627, 0, 73823, 101071, 0, 2276, 0, 42579, 0, + 983300, 983299, 127831, 983297, 983296, 983295, 983294, 983293, 74207, + 121255, 10482, 12863, 73002, 2412, 0, 9522, 0, 983887, 120674, 101059, + 3384, 101058, 10702, 830, 0, 128166, 0, 8451, 0, 0, 121380, 69739, + 128957, 0, 0, 0, 0, 0, 0, 0, 4243, 92454, 73093, 0, 0, 4441, 0, 983290, + 983289, 66618, 983287, 125141, 411, 983284, 68068, 983282, 4056, 983894, + 0, 92666, 0, 983897, 983949, 0, 0, 3364, 42265, 64437, 0, 118816, 0, + 9684, 216, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 11126, 5768, 3191, 0, 0, 0, 0, + 0, 0, 65895, 0, 0, 3338, 73935, 983278, 983277, 983276, 129605, 983274, + 983273, 2794, 8807, 0, 0, 110720, 0, 8312, 0, 110718, 11953, 11662, 0, 0, + 0, 0, 9534, 66767, 129040, 0, 11113, 0, 0, 73082, 0, 981, 0, 4330, + 119244, 120536, 1824, 0, 0, 7034, 41683, 123166, 0, 73754, 0, 0, 74478, + 128259, 983268, 983255, 983254, 43831, 983252, 66752, 983250, 983249, 0, + 70288, 65343, 0, 0, 43225, 0, 0, 0, 0, 126129, 0, 128608, 0, 0, 0, + 120726, 0, 983833, 11746, 0, 5216, 0, 0, 0, 0, 3468, 127149, 9230, 65942, + 0, 0, 5803, 120677, 0, 0, 13124, 0, 0, 0, 42843, 0, 0, 0, 66753, 11739, + 128318, 0, 128444, 0, 0, 0, 12448, 0, 121441, 13057, 73852, 124994, 0, 0, + 0, 0, 0, 0, 126612, 0, 68903, 0, 129470, 0, 917992, 0, 0, 0, 0, 0, 0, 0, + 92457, 0, 0, 0, 0, 0, 0, 0, 0, 125078, 0, 0, 0, 10970, 92208, 0, 0, 0, + 19944, 0, 9009, 8551, 0, 0, 0, 7575, 0, 0, 128899, 0, 129609, 78847, 0, + 78846, 0, 0, 0, 0, 0, 0, 0, 9775, 100682, 129191, 119052, 68629, 194703, + 0, 0, 78850, 92880, 0, 0, 0, 0, 0, 0, 0, 71273, 6184, 41540, 3303, 66182, + 11786, 66180, 66203, 3422, 0, 68290, 43007, 4478, 66178, 0, 0, 126216, 0, + 4477, 0, 69608, 66184, 66183, 66204, 66194, 0, 66198, 41880, 66188, + 66197, 78148, 66195, 66190, 66191, 41111, 66189, 73788, 7788, 0, 0, 0, 0, + 0, 2221, 78163, 6535, 78161, 78162, 430, 78160, 78156, 78158, 0, 0, 4945, + 0, 4950, 0, 78165, 0, 67118, 0, 5964, 12908, 0, 0, 0, 74477, 83390, 0, + 4949, 0, 443, 0, 4944, 5467, 119603, 983260, 0, 9364, 0, 119148, 4946, 0, + 3788, 126106, 983699, 0, 120847, 0, 74441, 0, 0, 12072, 92248, 0, 983689, + 0, 128676, 12091, 0, 0, 0, 4673, 0, 4678, 0, 0, 65059, 43860, 0, 0, 0, + 128151, 1199, 0, 8356, 0, 0, 4677, 0, 0, 0, 4672, 78173, 78175, 78171, + 78172, 72255, 78170, 78166, 4674, 128450, 194944, 0, 124970, 0, 119579, + 0, 0, 1855, 0, 0, 127806, 0, 0, 68912, 72323, 0, 12988, 121000, 0, 0, 0, + 4654, 6840, 983427, 0, 73993, 0, 4649, 65209, 983889, 93839, 4648, 0, + 121169, 983431, 126231, 983422, 66846, 7828, 4650, 983421, 72879, 0, + 4653, 7822, 0, 0, 43187, 0, 983574, 6821, 0, 0, 0, 0, 0, 0, 66756, + 983428, 0, 0, 0, 8547, 0, 42165, 0, 119228, 6836, 0, 0, 4662, 0, 0, 0, + 9146, 599, 4657, 0, 120754, 0, 4656, 0, 0, 7811, 40994, 0, 6414, 5967, + 4658, 3725, 0, 5814, 4661, 127760, 194961, 0, 0, 64904, 0, 10833, 0, 0, + 4867, 128717, 0, 11459, 3054, 0, 40996, 0, 7605, 4622, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19926, 0, 0, 65307, 4617, 0, 0, 0, 4616, 10518, 0, 127160, 0, + 5958, 0, 983444, 4618, 0, 0, 120675, 4621, 0, 0, 522, 125213, 11139, + 65803, 194972, 0, 12201, 6135, 121060, 983420, 0, 983093, 0, 983418, + 983411, 983432, 4638, 983416, 0, 78242, 5965, 78240, 66569, 68646, 0, + 983450, 74392, 5335, 0, 0, 4633, 0, 119045, 983446, 4632, 0, 5542, 5333, + 0, 983423, 68648, 5331, 4634, 0, 0, 5338, 4637, 0, 0, 43477, 0, 42493, 0, + 42361, 0, 0, 73853, 0, 0, 0, 74204, 11343, 0, 10358, 10422, 4758, 0, + 1608, 5252, 0, 0, 4753, 78239, 11344, 78237, 0, 5231, 74384, 0, 0, 0, 0, + 0, 0, 0, 0, 5229, 4757, 0, 0, 5227, 4752, 0, 65235, 5234, 73044, 0, 0, 0, + 0, 0, 0, 7460, 0, 917936, 0, 0, 74760, 65189, 0, 92230, 0, 0, 5574, 0, 0, + 65139, 5577, 0, 0, 118871, 68641, 8965, 7635, 0, 5316, 70021, 5314, + 74555, 5572, 0, 5312, 0, 5525, 5330, 5319, 68292, 0, 65066, 0, 0, 983491, + 0, 0, 127851, 0, 74851, 0, 0, 64609, 0, 0, 128593, 0, 129339, 0, 8632, 0, + 0, 0, 195012, 5735, 195013, 1692, 0, 4610, 0, 4305, 0, 4609, 43478, 4614, + 0, 0, 5287, 5309, 5285, 0, 5961, 4647, 5283, 10743, 0, 71889, 601, 4613, + 0, 0, 9208, 4608, 74044, 71107, 5190, 0, 0, 92410, 43965, 2265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5960, 0, 8992, 65293, 0, 1782, 0, 0, 0, 0, 0, 5501, + 0, 42508, 69759, 120749, 0, 0, 195023, 983919, 43900, 128325, 0, 68134, + 111180, 74209, 0, 64740, 0, 0, 0, 983916, 3767, 5737, 0, 4865, 0, 5740, + 0, 5736, 7724, 0, 7193, 0, 0, 5739, 0, 4866, 0, 0, 0, 4869, 67093, 0, 0, + 128514, 6650, 983483, 0, 983474, 78376, 4870, 0, 68661, 6716, 983473, + 68667, 69786, 68676, 0, 10122, 4864, 66568, 0, 0, 0, 9603, 68652, 126213, + 42734, 745, 0, 0, 0, 4777, 0, 917925, 68631, 42775, 68196, 0, 0, 0, 0, + 5966, 0, 4778, 127890, 0, 0, 4781, 127196, 64407, 0, 74132, 8577, 71221, + 0, 71223, 0, 4782, 0, 0, 120757, 68618, 43472, 43056, 68622, 0, 92986, + 4776, 0, 11492, 0, 0, 13176, 0, 0, 0, 0, 0, 0, 0, 4849, 8242, 9561, + 73922, 0, 0, 0, 0, 5963, 0, 125201, 0, 4850, 72121, 0, 590, 4853, 0, + 4854, 0, 5164, 0, 1605, 5124, 0, 111165, 0, 8471, 0, 111164, 12445, 3785, + 0, 111162, 0, 0, 4848, 2530, 0, 2068, 1964, 0, 0, 10796, 0, 0, 0, 0, 0, + 4794, 0, 0, 0, 4797, 68040, 111152, 43465, 4792, 0, 0, 0, 0, 0, 110842, + 983101, 92963, 0, 0, 0, 4221, 92360, 118869, 0, 0, 0, 70042, 0, 0, 0, 0, + 10739, 65090, 0, 119327, 126541, 0, 0, 119326, 0, 0, 4937, 43376, 0, 0, + 10597, 0, 11722, 9248, 129566, 42879, 11725, 0, 0, 7579, 11141, 73958, + 4941, 0, 917538, 9140, 4936, 5261, 0, 0, 72298, 0, 4942, 0, 4938, 0, 0, + 5259, 9369, 983429, 111182, 5257, 0, 6844, 4964, 5264, 0, 0, 0, 41411, 0, + 121473, 73684, 128233, 9482, 4873, 41991, 64707, 42526, 127989, 64480, + 64725, 983442, 0, 0, 0, 0, 0, 0, 73043, 0, 389, 10893, 7521, 0, 4872, + 5463, 0, 3125, 111124, 0, 4878, 5459, 4604, 0, 0, 5465, 0, 0, 0, 0, 9563, + 0, 0, 128419, 125273, 0, 0, 0, 0, 67735, 0, 0, 0, 0, 0, 78179, 0, 917838, + 0, 917833, 0, 917836, 0, 0, 3082, 0, 0, 0, 0, 0, 7079, 5856, 917842, + 5163, 0, 0, 1817, 66724, 0, 0, 10564, 7763, 13077, 0, 0, 68140, 111137, + 0, 0, 0, 111139, 0, 111149, 121457, 0, 0, 0, 983189, 73081, 0, 0, 983117, + 983077, 0, 42156, 0, 0, 0, 983080, 0, 0, 0, 119254, 120693, 0, 69386, 0, + 118881, 0, 78189, 0, 78186, 78188, 0, 0, 0, 0, 110877, 0, 3108, 9745, 0, + 0, 0, 118825, 0, 0, 0, 0, 0, 10972, 0, 0, 42768, 715, 983113, 121117, + 9453, 5348, 10943, 0, 983169, 0, 0, 0, 983153, 0, 0, 11551, 128464, 0, 0, + 9051, 0, 71728, 0, 120791, 119523, 0, 6404, 66458, 68376, 11984, 9156, + 65222, 74454, 78180, 0, 3128, 4789, 5067, 5066, 0, 4784, 0, 8827, 1146, + 5065, 78196, 78192, 78193, 78190, 78191, 5064, 5326, 0, 9450, 5063, + 120361, 78200, 78201, 5062, 69733, 74146, 0, 0, 0, 0, 77992, 0, 3933, 0, + 0, 12337, 0, 125023, 0, 0, 0, 194759, 0, 0, 82993, 42130, 0, 5151, + 917832, 120357, 0, 93980, 0, 7620, 3800, 0, 0, 0, 127952, 0, 0, 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, + 0, 3937, 12312, 128261, 0, 0, 0, 912, 6349, 4536, 0, 0, 126594, 0, 0, 0, + 3935, 120665, 0, 0, 0, 0, 118859, 0, 0, 0, 0, 12046, 12599, 0, 0, 0, 0, + 7227, 0, 0, 0, 983066, 0, 0, 0, 113817, 0, 78246, 0, 0, 0, 0, 0, 0, 0, 0, + 128874, 43907, 0, 0, 0, 0, 4644, 8818, 0, 0, 0, 0, 93066, 66452, 126081, + 1644, 101043, 9658, 43744, 11385, 65947, 983173, 43983, 0, 0, 0, 8962, 0, + 0, 2466, 42039, 67669, 0, 0, 42117, 100698, 0, 0, 0, 0, 43745, 5318, 0, + 917807, 0, 0, 0, 7054, 64147, 0, 917804, 68195, 6698, 0, 0, 0, 70849, + 11981, 12202, 0, 121364, 0, 7059, 11608, 975, 0, 65843, 170, 0, 67239, + 42708, 0, 0, 6058, 0, 0, 0, 70507, 0, 0, 9818, 0, 0, 42106, 0, 983065, + 4738, 42105, 7062, 0, 4737, 11779, 4742, 120564, 92391, 0, 41374, 41375, + 983376, 6715, 12700, 7049, 983374, 0, 0, 0, 4741, 42108, 983365, 64159, + 4736, 64148, 0, 849, 0, 128247, 983361, 0, 120913, 917997, 0, 983379, + 9496, 66371, 983403, 0, 11322, 0, 93008, 3928, 983152, 0, 10706, 7198, 0, + 4842, 12053, 0, 0, 4841, 0, 4171, 12008, 68416, 3923, 1490, 0, 0, 983393, + 40972, 5245, 72288, 983395, 126578, 0, 4845, 8332, 40974, 0, 4840, 9077, + 0, 2408, 72851, 4825, 0, 0, 0, 0, 126251, 0, 0, 983353, 0, 983354, 0, + 4826, 42440, 0, 0, 1274, 0, 74315, 0, 120384, 0, 121200, 0, 0, 0, 4830, + 983388, 129044, 0, 0, 119082, 0, 64105, 0, 0, 4824, 120397, 0, 0, 1888, + 64127, 7861, 125111, 78524, 41836, 0, 10873, 72439, 0, 64098, 12214, 0, + 41834, 0, 358, 128120, 41833, 11442, 0, 0, 0, 0, 64115, 0, 0, 0, 120721, + 119053, 0, 119055, 119054, 0, 0, 0, 0, 4017, 12827, 5241, 0, 73042, + 41118, 3924, 0, 11366, 0, 0, 0, 0, 41116, 69455, 0, 0, 0, 0, 11917, 0, + 74000, 4721, 129635, 983918, 0, 0, 0, 0, 0, 0, 122907, 0, 128702, 4722, + 6816, 124974, 0, 4725, 67099, 4726, 0, 0, 123171, 0, 123194, 0, 0, 0, + 4015, 0, 8052, 78766, 0, 0, 128294, 0, 0, 4720, 73090, 125003, 0, 0, + 1656, 41831, 0, 0, 41843, 0, 0, 1452, 13111, 0, 0, 0, 8552, 64113, 41845, + 64073, 120354, 0, 0, 120066, 120067, 7064, 64070, 9948, 0, 0, 0, 0, 2420, + 0, 0, 0, 0, 120052, 120053, 120050, 74920, 3938, 120057, 120054, 119249, + 120060, 71920, 120058, 120059, 120064, 72203, 7955, 64074, 4713, 128196, + 983107, 0, 0, 0, 65152, 10198, 120044, 120045, 120042, 6713, 4532, + 120049, 120046, 120047, 4717, 7046, 0, 66450, 4712, 75055, 0, 121085, 0, + 8155, 4718, 3942, 4714, 9625, 0, 6383, 0, 12006, 0, 0, 0, 0, 0, 65414, 0, + 0, 129061, 66437, 66025, 74115, 0, 0, 11228, 4809, 0, 92221, 72352, 0, 0, + 0, 65405, 0, 0, 0, 73934, 4545, 0, 917566, 0, 4813, 78699, 0, 0, 4808, 0, + 0, 65475, 0, 0, 4814, 72240, 4810, 0, 0, 68784, 10761, 71249, 3522, 0, + 78693, 65404, 0, 0, 0, 0, 0, 6691, 70125, 0, 126223, 0, 0, 0, 43858, 0, + 0, 12992, 65407, 0, 0, 3919, 0, 0, 0, 0, 0, 0, 12235, 110748, 0, 0, + 64091, 68739, 64080, 0, 64090, 0, 0, 0, 0, 0, 8454, 0, 0, 983858, 0, 0, + 0, 4780, 0, 0, 92764, 64621, 6732, 0, 0, 0, 0, 121363, 0, 0, 120817, + 6976, 0, 119005, 0, 93809, 0, 0, 0, 12526, 120399, 2315, 0, 1938, 0, 0, + 0, 0, 0, 0, 0, 120358, 93794, 0, 0, 0, 93810, 0, 2291, 0, 0, 0, 0, + 129429, 0, 10799, 0, 0, 66372, 0, 4193, 0, 0, 983057, 7998, 0, 0, 0, 0, + 2316, 0, 0, 0, 0, 125241, 0, 0, 74140, 0, 0, 0, 0, 3762, 93813, 120672, + 93820, 0, 0, 0, 70098, 3780, 12808, 8163, 983154, 0, 0, 3906, 12349, 0, + 8326, 0, 65498, 3763, 0, 5618, 0, 3779, 0, 43613, 0, 128007, 0, 0, 0, 0, + 280, 0, 126252, 983448, 13072, 1894, 0, 0, 65478, 43310, 7231, 0, 11773, + 0, 0, 0, 0, 0, 0, 7559, 11652, 10009, 110765, 110766, 110763, 110764, + 4470, 110762, 0, 0, 983441, 0, 5249, 0, 0, 8756, 0, 0, 41694, 120585, + 92349, 0, 0, 0, 69685, 983768, 983445, 113794, 0, 6808, 41319, 13125, + 66332, 127977, 0, 2290, 0, 983413, 0, 0, 3943, 0, 41205, 0, 0, 0, 0, + 5352, 0, 0, 41207, 0, 7384, 69647, 41204, 0, 41209, 69637, 0, 43607, 0, + 0, 5420, 0, 10134, 0, 0, 4018, 7150, 0, 0, 0, 0, 0, 129606, 2561, 0, 0, + 7148, 12076, 0, 0, 0, 0, 6276, 1706, 0, 0, 7146, 0, 128277, 41819, 74991, + 0, 10847, 41822, 72248, 860, 0, 0, 0, 69641, 10753, 41820, 126118, 0, + 71898, 0, 92617, 128567, 0, 0, 43016, 0, 0, 92225, 0, 0, 0, 0, 4022, 0, + 0, 110807, 0, 41691, 0, 75060, 0, 0, 65292, 0, 110812, 0, 3911, 110811, + 110808, 110809, 0, 125191, 7000, 3904, 118997, 72261, 0, 0, 0, 13123, + 10846, 0, 0, 0, 0, 0, 74082, 0, 0, 0, 0, 3777, 128329, 0, 9636, 71726, 0, + 0, 9367, 593, 0, 3999, 0, 41713, 0, 0, 67677, 0, 0, 0, 9763, 120280, + 120283, 12347, 124, 12981, 41127, 92527, 0, 0, 0, 0, 0, 43987, 0, 0, + 1769, 41715, 2463, 2151, 0, 0, 71222, 1538, 93044, 0, 0, 0, 7795, 120300, + 0, 92493, 10955, 0, 0, 0, 78208, 9498, 78207, 127033, 78210, 120288, + 3939, 120290, 120285, 8943, 120287, 120286, 120297, 4491, 120299, 42602, + 120293, 120292, 120295, 120294, 0, 0, 0, 0, 0, 0, 1511, 9324, 0, 0, 0, 0, + 0, 64536, 0, 0, 0, 124935, 6822, 12862, 0, 0, 42143, 41828, 0, 917629, + 70864, 118879, 0, 0, 0, 41826, 128413, 0, 0, 13279, 7917, 0, 0, 0, 0, 0, + 0, 92332, 0, 0, 43515, 0, 0, 0, 4013, 0, 0, 0, 72224, 125266, 0, 68243, + 2432, 0, 0, 0, 0, 0, 69952, 0, 0, 0, 10949, 0, 0, 0, 0, 0, 0, 0, 128574, + 43233, 0, 42517, 0, 0, 0, 0, 0, 64468, 119359, 6474, 127275, 43497, + 12656, 128122, 119353, 0, 1665, 0, 0, 0, 119351, 0, 0, 5256, 0, 0, 0, + 2859, 0, 0, 0, 0, 0, 0, 128220, 0, 770, 0, 811, 0, 0, 917551, 42244, + 64427, 0, 72222, 0, 3895, 0, 74341, 12087, 0, 42859, 10193, 3116, 7747, + 0, 0, 43496, 0, 0, 0, 0, 41877, 0, 65382, 64614, 0, 64296, 0, 6345, 0, + 2663, 0, 121234, 0, 0, 10150, 0, 64308, 1522, 597, 0, 0, 41201, 64731, 0, + 0, 41198, 0, 71483, 3092, 0, 0, 4783, 71448, 0, 0, 0, 10812, 0, 0, 0, + 3078, 0, 0, 0, 0, 0, 71703, 394, 3088, 0, 0, 0, 3991, 0, 129072, 0, 424, + 67652, 74927, 0, 0, 0, 0, 0, 0, 42231, 2209, 128215, 72983, 0, 41840, + 129136, 5344, 1298, 0, 13155, 0, 128973, 41838, 0, 8488, 1003, 41837, 0, + 0, 0, 48, 0, 0, 8493, 0, 0, 0, 65487, 0, 8465, 10332, 13172, 0, 0, 10449, + 126989, 127014, 69606, 69447, 3984, 129159, 0, 0, 0, 0, 0, 0, 0, 0, + 64758, 0, 100947, 0, 0, 9096, 0, 0, 9172, 128545, 0, 0, 5955, 67666, 0, + 0, 0, 0, 0, 74426, 3926, 71734, 0, 8798, 100946, 92165, 0, 0, 120696, 0, + 0, 0, 118805, 10353, 10417, 0, 0, 0, 128629, 4019, 0, 0, 0, 8219, 68402, + 0, 0, 121301, 0, 0, 0, 0, 0, 0, 0, 0, 110625, 42474, 10642, 3909, 9950, + 0, 128139, 69619, 68678, 92917, 0, 1049, 43517, 65707, 11943, 41806, 0, + 68635, 3921, 0, 11775, 121352, 69820, 1038, 42303, 9823, 0, 2145, 4008, + 68624, 0, 121025, 0, 0, 5153, 41805, 0, 0, 763, 9211, 0, 0, 0, 0, 0, + 127142, 0, 0, 65179, 0, 8621, 0, 118878, 0, 0, 0, 0, 182, 0, 0, 0, 0, + 72978, 9058, 8489, 0, 71188, 5969, 65909, 10848, 4570, 0, 128614, 4255, + 0, 0, 41189, 4003, 69785, 68109, 13293, 41192, 0, 0, 42251, 0, 0, 126085, + 11287, 6128, 121315, 11034, 0, 68207, 0, 65506, 42382, 0, 0, 66872, 9932, + 43516, 0, 125098, 0, 41814, 0, 71234, 0, 12117, 127040, 127041, 10540, + 127043, 9063, 78000, 0, 0, 0, 12897, 0, 0, 0, 6065, 0, 0, 0, 8692, 41186, + 41816, 0, 41818, 41187, 0, 42196, 0, 110690, 110691, 126115, 0, 0, + 125235, 4710, 0, 5956, 7621, 110641, 92624, 4705, 716, 74918, 110693, + 4704, 0, 0, 127112, 161, 0, 0, 0, 4706, 0, 0, 0, 4709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1700, 119223, 0, 0, 128119, 4004, 0, 73071, 69383, 69914, 8506, + 0, 0, 126996, 2538, 937, 0, 4734, 0, 0, 0, 0, 0, 4729, 0, 0, 0, 4728, 0, + 72809, 120644, 0, 8109, 43105, 11249, 4730, 447, 0, 1513, 4733, 0, 0, 0, + 0, 0, 0, 0, 8565, 2469, 0, 6690, 0, 0, 43439, 78218, 43103, 78217, 2674, + 0, 11922, 0, 0, 3510, 0, 129368, 0, 5605, 42095, 126572, 0, 9098, 120512, + 0, 121272, 68891, 74570, 0, 67708, 0, 119346, 0, 5959, 0, 0, 66275, + 43371, 0, 0, 0, 0, 0, 12769, 69793, 0, 1283, 0, 4779, 0, 3719, 4006, 0, + 0, 71186, 68204, 124957, 0, 119331, 43028, 65493, 0, 125058, 5962, 65485, + 92616, 0, 43501, 5827, 0, 120951, 0, 65494, 0, 129365, 0, 0, 43879, 0, 0, + 0, 0, 983203, 65467, 0, 0, 0, 0, 521, 0, 0, 983909, 0, 0, 483, 7096, 0, + 0, 928, 0, 0, 0, 0, 92983, 3989, 73972, 0, 0, 0, 0, 12145, 0, 73932, 0, + 0, 3769, 0, 0, 0, 0, 0, 0, 65290, 92223, 0, 65855, 0, 0, 0, 0, 128811, 0, + 0, 0, 0, 0, 0, 73838, 0, 0, 13007, 68165, 0, 0, 12661, 7608, 75032, + 12213, 0, 0, 0, 0, 12195, 4001, 3112, 92647, 0, 7590, 0, 0, 421, 0, 0, 0, + 4130, 127775, 7595, 42588, 7600, 0, 0, 0, 0, 65851, 42607, 0, 92403, + 8680, 0, 42134, 0, 0, 2846, 92605, 0, 0, 0, 0, 12979, 0, 0, 92558, 3740, + 69843, 120437, 0, 120451, 65923, 120435, 0, 120434, 0, 93800, 3118, + 74265, 93795, 93816, 93823, 93797, 8127, 92912, 93792, 7943, 93821, + 93799, 10618, 2584, 93793, 0, 0, 9998, 0, 0, 0, 66350, 0, 0, 0, 121374, + 8279, 128169, 0, 4975, 70075, 0, 0, 1631, 0, 0, 0, 6290, 128994, 66386, + 0, 64645, 0, 0, 0, 0, 0, 9242, 93807, 93802, 93801, 983264, 93803, 3122, + 93804, 7793, 0, 0, 0, 0, 12604, 93808, 6615, 67650, 0, 3986, 44025, 0, + 8912, 0, 7409, 0, 0, 0, 0, 0, 0, 8540, 11498, 0, 0, 0, 0, 0, 13060, + 120682, 0, 0, 0, 0, 0, 121345, 0, 0, 7020, 120353, 3765, 92881, 0, 1606, + 120348, 120351, 3093, 110593, 0, 0, 0, 0, 0, 0, 92892, 120337, 69402, + 120339, 4023, 120333, 120332, 120335, 92250, 120345, 12810, 120347, + 120346, 4455, 120340, 120343, 120342, 66660, 0, 0, 0, 0, 113720, 13089, + 74355, 120329, 120328, 42758, 12196, 128429, 0, 0, 0, 0, 128867, 94179, + 0, 3120, 9797, 0, 0, 11086, 10389, 0, 101025, 4895, 128153, 124941, 4359, + 0, 0, 3509, 70037, 486, 0, 0, 0, 0, 0, 7004, 0, 0, 0, 0, 4855, 128200, 0, + 0, 0, 0, 0, 0, 10381, 70839, 0, 0, 0, 0, 125121, 70837, 125070, 129431, + 983372, 983360, 0, 983359, 0, 120063, 0, 0, 0, 75048, 0, 74900, 0, 0, + 120978, 12161, 983351, 0, 10339, 0, 0, 0, 0, 0, 0, 0, 43032, 125010, 0, + 983380, 12671, 11384, 0, 0, 120901, 64797, 0, 5820, 0, 0, 0, 0, 0, + 120650, 42137, 9893, 8851, 12664, 0, 0, 13192, 0, 41799, 65530, 0, 0, + 43039, 3114, 0, 0, 0, 0, 0, 926, 0, 0, 0, 0, 0, 0, 0, 43037, 41798, 0, 0, + 123214, 41801, 0, 0, 0, 4200, 12699, 8331, 70118, 3091, 92980, 66298, + 70293, 8360, 0, 78044, 0, 4229, 64543, 126227, 65563, 0, 129310, 2861, + 43793, 10095, 121428, 9195, 121381, 121132, 0, 129578, 0, 0, 43041, 0, + 43794, 0, 83167, 0, 43797, 8209, 0, 129132, 12973, 0, 0, 0, 0, 0, 121235, + 5760, 0, 743, 0, 0, 0, 0, 0, 0, 83170, 128589, 129537, 0, 119063, 0, 0, + 0, 19919, 0, 64532, 0, 43710, 0, 0, 9483, 71115, 0, 43697, 0, 0, 83211, + 0, 0, 0, 7247, 0, 0, 0, 0, 0, 113674, 0, 7471, 120823, 128743, 12682, 0, + 0, 65679, 983143, 0, 0, 83201, 1099, 74241, 0, 10501, 0, 0, 113743, 0, + 64743, 128476, 67663, 0, 0, 92219, 0, 83197, 64897, 9973, 1818, 0, 0, + 8272, 127812, 0, 4218, 3087, 0, 127234, 0, 0, 65181, 9954, 10465, 0, 0, + 0, 9106, 0, 67406, 0, 0, 0, 0, 43038, 0, 0, 265, 0, 0, 0, 0, 0, 0, 69405, + 0, 59, 0, 0, 0, 0, 126239, 41810, 0, 126492, 0, 41809, 41888, 0, 41795, + 0, 42213, 0, 0, 43033, 511, 129413, 0, 13127, 0, 0, 0, 0, 111107, 0, + 4467, 41812, 41215, 0, 41211, 917783, 4453, 983409, 0, 983174, 0, 983407, + 41213, 118812, 0, 0, 0, 0, 41841, 6617, 0, 0, 92995, 462, 0, 10493, 0, + 55248, 0, 0, 74471, 6644, 0, 0, 0, 983383, 100484, 9581, 67104, 3098, 0, + 0, 983410, 125250, 0, 120621, 0, 0, 0, 129584, 101011, 0, 118789, 74473, + 3755, 64661, 7748, 7235, 3966, 0, 0, 127510, 0, 0, 0, 5726, 66456, 42175, + 100486, 0, 42212, 92681, 121443, 2851, 43017, 0, 121056, 4373, 0, 0, + 9587, 0, 6671, 128840, 3100, 0, 0, 0, 0, 0, 917789, 73836, 8190, 12083, + 917791, 0, 6689, 64629, 0, 0, 0, 4419, 917787, 101017, 0, 69851, 0, 0, + 8891, 3080, 0, 2347, 0, 0, 8990, 0, 121201, 0, 92528, 249, 0, 0, 69424, + 0, 0, 0, 55253, 0, 0, 11173, 995, 0, 121047, 119861, 0, 73708, 0, 0, + 19945, 0, 558, 983394, 12273, 0, 983862, 0, 69912, 120861, 129492, 67274, + 94178, 0, 68019, 43030, 3129, 0, 2102, 0, 0, 121450, 0, 7725, 0, 11120, + 0, 126111, 69246, 0, 0, 0, 41894, 0, 41898, 0, 41893, 74921, 128678, + 3540, 11848, 0, 73005, 120848, 0, 0, 126113, 73959, 0, 0, 0, 120858, 0, + 0, 9699, 128656, 41896, 0, 83196, 69230, 74951, 0, 72736, 0, 0, 3095, + 983670, 11946, 983866, 0, 0, 0, 0, 0, 113677, 3672, 119864, 0, 0, 0, + 128539, 8890, 93826, 0, 128182, 0, 0, 0, 126568, 0, 0, 983617, 9516, + 983436, 0, 0, 42220, 0, 4450, 0, 11547, 43417, 128542, 356, 0, 0, 0, 0, + 64901, 0, 0, 0, 0, 0, 0, 111302, 65940, 2541, 71231, 0, 123215, 126470, + 3549, 0, 0, 0, 2743, 0, 0, 0, 9097, 128896, 43015, 0, 0, 776, 2524, 0, + 8573, 100665, 126494, 0, 0, 42694, 71122, 8952, 10814, 118818, 0, 43646, + 128598, 0, 0, 0, 128380, 100663, 0, 65853, 42707, 1897, 93071, 0, 0, + 71907, 69410, 0, 125106, 0, 0, 0, 68473, 66778, 43573, 92638, 0, 0, 0, + 120955, 73986, 0, 0, 43022, 0, 74841, 0, 67714, 0, 0, 0, 0, 0, 4553, 0, + 0, 0, 0, 0, 19921, 0, 0, 983668, 4567, 41891, 0, 983800, 55249, 194663, + 0, 194662, 0, 194665, 43042, 121291, 1377, 12869, 0, 0, 9250, 0, 0, 0, 0, + 125039, 194642, 0, 74995, 0, 194644, 0, 0, 0, 194668, 121166, 0, 70275, + 1898, 0, 0, 0, 802, 0, 0, 0, 6648, 0, 2528, 0, 0, 194646, 194625, 194645, + 68804, 844, 0, 68824, 0, 68818, 194650, 0, 0, 0, 983724, 65464, 0, 0, 0, + 0, 83221, 0, 0, 100680, 0, 0, 64371, 70665, 0, 194654, 0, 0, 0, 0, 0, + 6196, 6945, 0, 0, 0, 120491, 0, 68846, 6210, 0, 70274, 0, 0, 0, 68067, + 68834, 194715, 588, 9760, 129112, 0, 983704, 128798, 0, 127992, 0, 0, + 118905, 0, 0, 92485, 110839, 69396, 0, 3394, 70734, 194639, 0, 0, 0, 0, + 0, 0, 194656, 7817, 1841, 11055, 0, 194979, 194983, 127011, 119074, + 194987, 7701, 194998, 0, 0, 1946, 121404, 0, 0, 0, 0, 0, 10934, 0, 70376, + 0, 0, 8071, 3538, 0, 2287, 65328, 0, 0, 7614, 0, 0, 0, 12009, 43968, 0, + 67852, 0, 0, 10841, 123640, 0, 0, 0, 0, 8960, 0, 0, 65317, 0, 0, 0, + 70374, 0, 0, 0, 65315, 0, 0, 0, 0, 0, 119621, 0, 11849, 12447, 0, 0, + 110741, 0, 0, 0, 0, 42767, 0, 0, 0, 43695, 120520, 11975, 194941, 983443, + 0, 2555, 0, 128640, 70070, 42936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66714, + 0, 0, 70076, 65596, 121034, 66710, 67658, 0, 126994, 65338, 7792, 0, 0, + 67871, 119027, 0, 8233, 43572, 0, 0, 0, 3442, 0, 2841, 12543, 0, 1473, + 42820, 64329, 127832, 917772, 126126, 7937, 0, 1048, 0, 0, 983924, 0, + 3406, 1054, 100701, 1040, 65450, 0, 92329, 1069, 917763, 128367, 128940, + 0, 917765, 0, 983705, 9693, 110873, 0, 0, 0, 983929, 4353, 0, 1059, + 127530, 0, 0, 0, 127093, 118862, 120500, 10646, 0, 100710, 917762, 70424, + 74830, 0, 0, 983701, 10221, 100706, 68255, 0, 0, 74346, 119619, 100707, + 64945, 12921, 0, 0, 0, 0, 0, 983776, 43020, 0, 0, 74254, 0, 983766, 0, 0, + 983773, 0, 0, 0, 0, 0, 0, 0, 0, 120503, 70663, 0, 2755, 0, 0, 0, 4857, 0, + 4428, 0, 0, 983772, 0, 0, 0, 43842, 0, 122899, 0, 7978, 0, 70392, 127080, + 11924, 43812, 0, 65015, 0, 563, 68340, 0, 12798, 0, 100727, 0, 0, 0, + 74110, 0, 94051, 0, 694, 0, 9876, 0, 119168, 0, 0, 0, 92361, 0, 0, 7229, + 0, 0, 0, 0, 64811, 0, 119087, 126478, 0, 7381, 0, 2525, 4852, 11586, + 68465, 41605, 126089, 0, 11582, 7151, 10155, 92578, 188, 0, 11592, 0, + 74015, 0, 0, 4858, 0, 0, 0, 4861, 0, 2786, 121431, 4856, 8051, 0, 119609, + 0, 113797, 71133, 0, 78448, 0, 0, 67842, 68084, 0, 0, 0, 0, 0, 10234, + 5843, 0, 71865, 66728, 0, 3157, 0, 0, 75035, 72788, 983731, 0, 10822, + 5149, 129517, 0, 65142, 129454, 4565, 0, 0, 0, 12657, 0, 0, 386, 0, 8834, + 120974, 0, 43574, 0, 0, 0, 70113, 7220, 11839, 124984, 74883, 194752, 0, + 65241, 74503, 8160, 0, 194753, 0, 0, 0, 0, 0, 121265, 0, 13303, 0, 0, + 194755, 0, 118865, 0, 194761, 0, 0, 74505, 0, 0, 0, 100518, 0, 8780, + 100512, 0, 68745, 110626, 66697, 0, 2672, 3735, 983641, 0, 68752, 11205, + 10724, 41202, 0, 100714, 0, 0, 0, 0, 194765, 3842, 0, 78183, 12442, + 78182, 9791, 78181, 0, 42516, 67730, 64821, 195061, 78463, 0, 78464, + 119219, 78465, 127466, 194690, 195063, 0, 0, 0, 0, 78540, 78541, 78538, + 1962, 78490, 78476, 65930, 11660, 0, 2072, 0, 0, 78544, 194704, 78542, + 10669, 110859, 110860, 110857, 110858, 0, 110856, 4105, 0, 194699, 0, 0, + 0, 13148, 195068, 78479, 9226, 0, 0, 10765, 127486, 71919, 121218, + 195050, 0, 195041, 0, 0, 0, 0, 0, 0, 92312, 7886, 0, 6682, 0, 6680, + 195042, 126473, 195052, 6679, 74412, 0, 72206, 74421, 66281, 0, 0, + 127478, 0, 0, 0, 6681, 0, 12693, 0, 0, 0, 0, 0, 65442, 129055, 0, 9989, + 74415, 194673, 0, 0, 983769, 0, 0, 0, 0, 7042, 127240, 119026, 7968, 0, + 983749, 194741, 194736, 983774, 0, 69889, 74389, 128696, 0, 0, 128979, + 5781, 0, 78199, 0, 0, 11091, 0, 2719, 0, 0, 0, 64495, 0, 0, 0, 65169, + 42845, 0, 128551, 983747, 7505, 72435, 0, 0, 0, 917855, 66670, 0, 983690, + 0, 0, 0, 7902, 0, 65265, 0, 0, 0, 0, 0, 0, 0, 12994, 0, 10828, 983955, 0, + 4307, 3482, 0, 0, 72389, 0, 64299, 74573, 41194, 7343, 0, 0, 41195, 0, + 8169, 0, 8841, 66770, 516, 72981, 41197, 119051, 34, 128850, 120186, + 11504, 1612, 120187, 120182, 120181, 120184, 12001, 120178, 120177, + 120180, 120179, 120174, 120173, 7749, 120175, 0, 1758, 0, 10667, 0, + 120197, 0, 1935, 11517, 120193, 120196, 120195, 120190, 120189, 120192, + 120191, 1217, 64702, 128075, 825, 0, 0, 0, 0, 66748, 0, 11050, 0, 123187, + 0, 0, 74554, 0, 0, 8677, 123188, 11313, 123185, 3403, 0, 123186, 64364, + 92683, 0, 0, 0, 0, 123189, 0, 0, 983861, 0, 69408, 41850, 0, 3433, + 127965, 0, 1594, 65607, 0, 66392, 0, 129291, 74565, 41353, 125119, 0, 0, + 0, 0, 918, 127280, 41351, 0, 0, 12140, 0, 12668, 72395, 0, 128753, 0, + 127302, 0, 127288, 129497, 127235, 573, 0, 0, 11417, 0, 127283, 0, 0, 0, + 72410, 0, 11482, 0, 3981, 74345, 0, 0, 0, 0, 0, 0, 125238, 0, 0, 42195, + 0, 123190, 0, 64602, 0, 0, 121366, 0, 121061, 128690, 0, 8423, 0, 448, + 66907, 9717, 0, 0, 0, 0, 0, 0, 0, 71910, 0, 0, 0, 120679, 65013, 78169, + 0, 72390, 0, 0, 127917, 0, 74892, 0, 0, 127798, 0, 0, 71252, 0, 0, 0, + 12197, 125074, 0, 121447, 0, 0, 0, 0, 0, 0, 0, 74563, 64828, 11419, 0, + 8592, 0, 0, 0, 11381, 0, 0, 74529, 0, 0, 0, 0, 72796, 0, 83257, 0, 0, 0, + 129437, 65672, 0, 0, 0, 0, 0, 0, 0, 0, 9505, 0, 0, 756, 0, 125243, + 100358, 110852, 7261, 0, 0, 0, 0, 0, 64401, 65830, 41365, 0, 0, 0, + 127834, 0, 0, 0, 0, 0, 74626, 123155, 11578, 0, 0, 0, 0, 0, 0, 74568, 0, + 113684, 1794, 68310, 120218, 120219, 120220, 120221, 120222, 120223, + 3617, 120209, 64886, 94061, 78202, 120213, 120214, 10225, 983060, 0, + 65223, 983058, 0, 0, 4452, 127779, 0, 0, 0, 0, 0, 0, 11425, 0, 0, 1231, + 0, 0, 0, 0, 8192, 0, 0, 0, 10616, 8694, 0, 68867, 128332, 123595, 120200, + 120201, 120202, 120203, 9878, 120205, 119626, 120207, 0, 8799, 42131, 0, + 127163, 0, 120198, 120199, 837, 120015, 72384, 0, 983817, 0, 11427, 0, + 78154, 0, 70171, 0, 78150, 42606, 0, 119615, 78147, 64637, 78146, 43060, + 78145, 125009, 3392, 0, 194783, 119067, 119650, 65468, 43498, 126083, 0, + 0, 0, 194928, 194937, 194938, 64681, 194930, 83264, 92451, 0, 194955, + 83262, 983732, 8973, 0, 194967, 70177, 194968, 0, 4800, 195018, 0, 0, + 11820, 70151, 0, 0, 4802, 4111, 111268, 0, 4805, 127308, 68193, 7885, + 121220, 0, 0, 0, 4767, 0, 0, 0, 0, 0, 125234, 100366, 43453, 0, 41340, 0, + 0, 10005, 65856, 41333, 0, 9518, 0, 0, 0, 42520, 0, 0, 0, 917562, 100506, + 0, 0, 0, 0, 0, 0, 9167, 42151, 124958, 0, 2026, 100848, 0, 0, 100534, + 12768, 0, 7582, 0, 0, 0, 0, 129557, 0, 120539, 68879, 0, 43547, 0, 8546, + 126071, 78520, 7604, 78518, 78519, 78514, 78517, 78511, 78512, 73802, + 128140, 0, 6708, 10535, 0, 68218, 55274, 68221, 92296, 0, 0, 0, 0, 0, + 72385, 0, 0, 0, 73727, 0, 120706, 74442, 0, 0, 0, 4351, 0, 119887, + 119888, 0, 119886, 119891, 68866, 119889, 11433, 119895, 119896, 0, + 119894, 65578, 0, 0, 0, 983070, 10681, 0, 0, 0, 0, 983110, 0, 6722, + 129364, 0, 119997, 41546, 64860, 68394, 0, 41549, 0, 72386, 0, 0, 0, 0, + 64710, 41547, 0, 0, 0, 78530, 78532, 78528, 78529, 71343, 78527, 78523, + 78525, 3537, 119908, 119905, 7155, 2264, 0, 78533, 67755, 0, 0, 0, 0, 0, + 0, 0, 64715, 0, 0, 537, 0, 4179, 0, 0, 0, 0, 0, 0, 0, 0, 12081, 0, 0, + 4048, 7053, 0, 0, 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}}, + {2, {0x0045, 0x0329}}, + {2, {0x0065, 0x0329}}, + {2, {0x00C8, 0x0329}}, + {2, {0x00E8, 0x0329}}, + {2, {0x00C9, 0x0329}}, + {2, {0x00E9, 0x0329}}, + {2, {0x00CA, 0x0304}}, + {2, {0x00EA, 0x0304}}, + {2, {0x00CA, 0x030C}}, + {2, {0x00EA, 0x030C}}, + {2, {0x012A, 0x0300}}, + {2, {0x012B, 0x0300}}, + {3, {0x0069, 0x0307, 0x0301}}, + {3, {0x006E, 0x0360, 0x0067}}, + {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, {0x016A, 0x0300}}, + {2, {0x016B, 0x0300}}, + {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/python/Modules/winreparse.h b/python/Modules/winreparse.h new file mode 100755 index 0000000..f06f701 --- /dev/null +++ b/python/Modules/winreparse.h @@ -0,0 +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 ) + +// 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 */ diff --git a/python/Modules/xxlimited.c b/python/Modules/xxlimited.c new file mode 100755 index 0000000..ffc04e0 --- /dev/null +++ b/python/Modules/xxlimited.c @@ -0,0 +1,307 @@ + +/* Use this file as a template to start implementing a module that + also declares object types. All occurrences of 'Xxo' should be changed + to something reasonable for your objects. After that, all other + occurrences of 'xx' should be changed to something reasonable for your + module. If your module is named foo your sourcefile should be named + foomodule.c. + + You will probably want to delete all references to 'x_attr' and add + your own types of attributes instead. Maybe you want to name your + local variables other than 'self'. If your object type is needed in + other files, you'll have to create a file "foobarobject.h"; see + floatobject.h for an example. */ + +/* Xxo objects */ + +#include "Python.h" + +static PyObject *ErrorObject; + +typedef struct { + PyObject_HEAD + PyObject *x_attr; /* Attributes dictionary */ +} XxoObject; + +static PyObject *Xxo_Type; + +#define XxoObject_Check(v) (Py_TYPE(v) == Xxo_Type) + +static XxoObject * +newXxoObject(PyObject *arg) +{ + XxoObject *self; + self = PyObject_GC_New(XxoObject, (PyTypeObject*)Xxo_Type); + if (self == NULL) + return NULL; + self->x_attr = NULL; + return self; +} + +/* Xxo methods */ + +static int +Xxo_traverse(XxoObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->x_attr); + return 0; +} + +static void +Xxo_finalize(XxoObject *self) +{ + Py_CLEAR(self->x_attr); +} + +static PyObject * +Xxo_demo(XxoObject *self, PyObject *args) +{ + PyObject *o = NULL; + if (!PyArg_ParseTuple(args, "|O:demo", &o)) + return NULL; + /* Test availability of fast type checks */ + if (o != NULL && PyUnicode_Check(o)) { + Py_INCREF(o); + return o; + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef Xxo_methods[] = { + {"demo", (PyCFunction)Xxo_demo, METH_VARARGS, + PyDoc_STR("demo() -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +Xxo_getattro(XxoObject *self, PyObject *name) +{ + if (self->x_attr != NULL) { + PyObject *v = PyDict_GetItemWithError(self->x_attr, name); + if (v != NULL) { + Py_INCREF(v); + return v; + } + else if (PyErr_Occurred()) { + return NULL; + } + } + return PyObject_GenericGetAttr((PyObject *)self, name); +} + +static int +Xxo_setattr(XxoObject *self, const char *name, PyObject *v) +{ + if (self->x_attr == NULL) { + self->x_attr = PyDict_New(); + if (self->x_attr == NULL) + return -1; + } + if (v == NULL) { + int rv = PyDict_DelItemString(self->x_attr, name); + if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetString(PyExc_AttributeError, + "delete non-existing Xxo attribute"); + return rv; + } + else + return PyDict_SetItemString(self->x_attr, name, v); +} + +static PyType_Slot Xxo_Type_slots[] = { + {Py_tp_doc, "The Xxo type"}, + {Py_tp_traverse, Xxo_traverse}, + {Py_tp_finalize, Xxo_finalize}, + {Py_tp_getattro, Xxo_getattro}, + {Py_tp_setattr, Xxo_setattr}, + {Py_tp_methods, Xxo_methods}, + {0, 0}, +}; + +static PyType_Spec Xxo_Type_spec = { + "xxlimited.Xxo", + sizeof(XxoObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + Xxo_Type_slots +}; + +/* --------------------------------------------------------------------- */ + +/* Function of two integers returning integer */ + +PyDoc_STRVAR(xx_foo_doc, +"foo(i,j)\n\ +\n\ +Return the sum of i and j."); + +static PyObject * +xx_foo(PyObject *self, PyObject *args) +{ + long i, j; + long res; + if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) + return NULL; + res = i+j; /* XXX Do something here */ + return PyLong_FromLong(res); +} + + +/* Function of no arguments returning new Xxo object */ + +static PyObject * +xx_new(PyObject *self, PyObject *args) +{ + XxoObject *rv; + + if (!PyArg_ParseTuple(args, ":new")) + return NULL; + rv = newXxoObject(args); + if (rv == NULL) + return NULL; + return (PyObject *)rv; +} + +/* Test bad format character */ + +static PyObject * +xx_roj(PyObject *self, PyObject *args) +{ + PyObject *a; + long b; + if (!PyArg_ParseTuple(args, "O#:roj", &a, &b)) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + + +/* ---------- */ + +static PyType_Slot Str_Type_slots[] = { + {Py_tp_base, NULL}, /* filled out in module init function */ + {0, 0}, +}; + +static PyType_Spec Str_Type_spec = { + "xxlimited.Str", + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Str_Type_slots +}; + +/* ---------- */ + +static PyObject * +null_richcompare(PyObject *self, PyObject *other, int op) +{ + Py_RETURN_NOTIMPLEMENTED; +} + +static PyType_Slot Null_Type_slots[] = { + {Py_tp_base, NULL}, /* filled out in module init */ + {Py_tp_new, NULL}, + {Py_tp_richcompare, null_richcompare}, + {0, 0} +}; + +static PyType_Spec Null_Type_spec = { + "xxlimited.Null", + 0, /* basicsize */ + 0, /* itemsize */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Null_Type_slots +}; + +/* ---------- */ + +/* List of functions defined in the module */ + +static PyMethodDef xx_methods[] = { + {"roj", xx_roj, METH_VARARGS, + PyDoc_STR("roj(a,b) -> None")}, + {"foo", xx_foo, METH_VARARGS, + xx_foo_doc}, + {"new", xx_new, METH_VARARGS, + PyDoc_STR("new() -> new Xx object")}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, +"This is a template module just for instruction."); + +static int +xx_modexec(PyObject *m) +{ + PyObject *o; + + /* Due to cross platform compiler issues the slots must be filled + * here. It's required for portability to Windows without requiring + * C++. */ + Null_Type_slots[0].pfunc = &PyBaseObject_Type; + Null_Type_slots[1].pfunc = PyType_GenericNew; + Str_Type_slots[0].pfunc = &PyUnicode_Type; + + Xxo_Type = PyType_FromSpec(&Xxo_Type_spec); + if (Xxo_Type == NULL) + goto fail; + + /* Add some symbolic constants to the module */ + if (ErrorObject == NULL) { + ErrorObject = PyErr_NewException("xxlimited.error", NULL, NULL); + if (ErrorObject == NULL) + goto fail; + } + Py_INCREF(ErrorObject); + PyModule_AddObject(m, "error", ErrorObject); + + /* Add Xxo */ + o = PyType_FromSpec(&Xxo_Type_spec); + if (o == NULL) + goto fail; + PyModule_AddObject(m, "Xxo", o); + + /* Add Str */ + o = PyType_FromSpec(&Str_Type_spec); + if (o == NULL) + goto fail; + PyModule_AddObject(m, "Str", o); + + /* Add Null */ + o = PyType_FromSpec(&Null_Type_spec); + if (o == NULL) + goto fail; + PyModule_AddObject(m, "Null", o); + return 0; + fail: + Py_XDECREF(m); + return -1; +} + + +static PyModuleDef_Slot xx_slots[] = { + {Py_mod_exec, xx_modexec}, + {0, NULL} +}; + +static struct PyModuleDef xxmodule = { + PyModuleDef_HEAD_INIT, + "xxlimited", + module_doc, + 0, + xx_methods, + xx_slots, + NULL, + NULL, + NULL +}; + +/* Export function for the module (*must* be called PyInit_xx) */ + +PyMODINIT_FUNC +PyInit_xxlimited(void) +{ + return PyModuleDef_Init(&xxmodule); +} diff --git a/python/Modules/xxmodule.c b/python/Modules/xxmodule.c new file mode 100755 index 0000000..0250031 --- /dev/null +++ b/python/Modules/xxmodule.c @@ -0,0 +1,411 @@ + +/* Use this file as a template to start implementing a module that + also declares object types. All occurrences of 'Xxo' should be changed + to something reasonable for your objects. After that, all other + occurrences of 'xx' should be changed to something reasonable for your + module. If your module is named foo your sourcefile should be named + foomodule.c. + + You will probably want to delete all references to 'x_attr' and add + your own types of attributes instead. Maybe you want to name your + local variables other than 'self'. If your object type is needed in + other files, you'll have to create a file "foobarobject.h"; see + floatobject.h for an example. */ + +/* Xxo objects */ + +#include "Python.h" + +static PyObject *ErrorObject; + +typedef struct { + PyObject_HEAD + PyObject *x_attr; /* Attributes dictionary */ +} XxoObject; + +static PyTypeObject Xxo_Type; + +#define XxoObject_Check(v) (Py_TYPE(v) == &Xxo_Type) + +static XxoObject * +newXxoObject(PyObject *arg) +{ + XxoObject *self; + self = PyObject_New(XxoObject, &Xxo_Type); + if (self == NULL) + return NULL; + self->x_attr = NULL; + return self; +} + +/* Xxo methods */ + +static void +Xxo_dealloc(XxoObject *self) +{ + Py_XDECREF(self->x_attr); + PyObject_Del(self); +} + +static PyObject * +Xxo_demo(XxoObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":demo")) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef Xxo_methods[] = { + {"demo", (PyCFunction)Xxo_demo, METH_VARARGS, + PyDoc_STR("demo() -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +Xxo_getattro(XxoObject *self, PyObject *name) +{ + if (self->x_attr != NULL) { + PyObject *v = PyDict_GetItemWithError(self->x_attr, name); + if (v != NULL) { + Py_INCREF(v); + return v; + } + else if (PyErr_Occurred()) { + return NULL; + } + } + return PyObject_GenericGetAttr((PyObject *)self, name); +} + +static int +Xxo_setattr(XxoObject *self, const char *name, PyObject *v) +{ + if (self->x_attr == NULL) { + self->x_attr = PyDict_New(); + if (self->x_attr == NULL) + return -1; + } + if (v == NULL) { + int rv = PyDict_DelItemString(self->x_attr, name); + if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetString(PyExc_AttributeError, + "delete non-existing Xxo attribute"); + return rv; + } + else + return PyDict_SetItemString(self->x_attr, name, v); +} + +static PyTypeObject Xxo_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) + "xxmodule.Xxo", /*tp_name*/ + sizeof(XxoObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)Xxo_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + (getattrfunc)0, /*tp_getattr*/ + (setattrfunc)Xxo_setattr, /*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*/ + (getattrofunc)Xxo_getattro, /*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*/ + Xxo_methods, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; +/* --------------------------------------------------------------------- */ + +/* Function of two integers returning integer */ + +PyDoc_STRVAR(xx_foo_doc, +"foo(i,j)\n\ +\n\ +Return the sum of i and j."); + +static PyObject * +xx_foo(PyObject *self, PyObject *args) +{ + long i, j; + long res; + if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) + return NULL; + res = i+j; /* XXX Do something here */ + return PyLong_FromLong(res); +} + + +/* Function of no arguments returning new Xxo object */ + +static PyObject * +xx_new(PyObject *self, PyObject *args) +{ + XxoObject *rv; + + if (!PyArg_ParseTuple(args, ":new")) + return NULL; + rv = newXxoObject(args); + if (rv == NULL) + return NULL; + return (PyObject *)rv; +} + +/* Example with subtle bug from extensions manual ("Thin Ice"). */ + +static PyObject * +xx_bug(PyObject *self, PyObject *args) +{ + PyObject *list, *item; + + if (!PyArg_ParseTuple(args, "O:bug", &list)) + return NULL; + + item = PyList_GetItem(list, 0); + /* Py_INCREF(item); */ + PyList_SetItem(list, 1, PyLong_FromLong(0L)); + PyObject_Print(item, stdout, 0); + printf("\n"); + /* Py_DECREF(item); */ + + Py_INCREF(Py_None); + return Py_None; +} + +/* Test bad format character */ + +static PyObject * +xx_roj(PyObject *self, PyObject *args) +{ + PyObject *a; + long b; + if (!PyArg_ParseTuple(args, "O#:roj", &a, &b)) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + + +/* ---------- */ + +static PyTypeObject Str_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) + "xxmodule.Str", /*tp_name*/ + 0, /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + 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*/ + 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, /* see PyInit_xx */ /*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*/ +}; + +/* ---------- */ + +static PyObject * +null_richcompare(PyObject *self, PyObject *other, int op) +{ + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + +static PyTypeObject Null_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) + "xxmodule.Null", /*tp_name*/ + 0, /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + 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*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + null_richcompare, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /* see PyInit_xx */ /*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*/ + 0, /*tp_is_gc*/ +}; + + +/* ---------- */ + + +/* List of functions defined in the module */ + +static PyMethodDef xx_methods[] = { + {"roj", xx_roj, METH_VARARGS, + PyDoc_STR("roj(a,b) -> None")}, + {"foo", xx_foo, METH_VARARGS, + xx_foo_doc}, + {"new", xx_new, METH_VARARGS, + PyDoc_STR("new() -> new Xx object")}, + {"bug", xx_bug, METH_VARARGS, + PyDoc_STR("bug(o) -> None")}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, +"This is a template module just for instruction."); + + +static int +xx_exec(PyObject *m) +{ + /* Slot initialization is subject to the rules of initializing globals. + C99 requires the initializers to be "address constants". Function + designators like 'PyType_GenericNew', with implicit conversion to + a pointer, are valid C99 address constants. + + However, the unary '&' operator applied to a non-static variable + like 'PyBaseObject_Type' is not required to produce an address + constant. Compilers may support this (gcc does), MSVC does not. + + Both compilers are strictly standard conforming in this particular + behavior. + */ + Null_Type.tp_base = &PyBaseObject_Type; + Str_Type.tp_base = &PyUnicode_Type; + + /* Finalize the type object including setting type of the new type + * object; doing it here is required for portability, too. */ + if (PyType_Ready(&Xxo_Type) < 0) + goto fail; + + /* Add some symbolic constants to the module */ + if (ErrorObject == NULL) { + ErrorObject = PyErr_NewException("xx.error", NULL, NULL); + if (ErrorObject == NULL) + goto fail; + } + Py_INCREF(ErrorObject); + PyModule_AddObject(m, "error", ErrorObject); + + /* Add Str */ + if (PyType_Ready(&Str_Type) < 0) + goto fail; + PyModule_AddObject(m, "Str", (PyObject *)&Str_Type); + + /* Add Null */ + if (PyType_Ready(&Null_Type) < 0) + goto fail; + PyModule_AddObject(m, "Null", (PyObject *)&Null_Type); + return 0; + fail: + Py_XDECREF(m); + return -1; +} + +static struct PyModuleDef_Slot xx_slots[] = { + {Py_mod_exec, xx_exec}, + {0, NULL}, +}; + +static struct PyModuleDef xxmodule = { + PyModuleDef_HEAD_INIT, + "xx", + module_doc, + 0, + xx_methods, + xx_slots, + NULL, + NULL, + NULL +}; + +/* Export function for the module (*must* be called PyInit_xx) */ + +PyMODINIT_FUNC +PyInit_xx(void) +{ + return PyModuleDef_Init(&xxmodule); +} diff --git a/python/Modules/xxsubtype.c b/python/Modules/xxsubtype.c new file mode 100755 index 0000000..031005d --- /dev/null +++ b/python/Modules/xxsubtype.c @@ -0,0 +1,314 @@ +#include "Python.h" +#include "structmember.h" + +PyDoc_STRVAR(xxsubtype__doc__, +"xxsubtype is an example module showing how to subtype builtin types from C.\n" +"test_descr.py in the standard test suite requires it in order to complete.\n" +"If you don't care about the examples, and don't intend to run the Python\n" +"test suite, you can recompile Python without Modules/xxsubtype.c."); + +/* We link this module statically for convenience. If compiled as a shared + library instead, some compilers don't allow addresses of Python objects + defined in other libraries to be used in static initializers here. The + DEFERRED_ADDRESS macro is used to tag the slots where such addresses + appear; the module init function must fill in the tagged slots at runtime. + The argument is for documentation -- the macro ignores it. +*/ +#define DEFERRED_ADDRESS(ADDR) 0 + +/* spamlist -- a list subtype */ + +typedef struct { + PyListObject list; + int state; +} spamlistobject; + +static PyObject * +spamlist_getstate(spamlistobject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":getstate")) + return NULL; + return PyLong_FromLong(self->state); +} + +static PyObject * +spamlist_setstate(spamlistobject *self, PyObject *args) +{ + int state; + + if (!PyArg_ParseTuple(args, "i:setstate", &state)) + return NULL; + self->state = state; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *result = PyTuple_New(3); + + if (result != NULL) { + if (self == NULL) + self = Py_None; + if (kw == NULL) + kw = Py_None; + Py_INCREF(self); + PyTuple_SET_ITEM(result, 0, self); + Py_INCREF(args); + PyTuple_SET_ITEM(result, 1, args); + Py_INCREF(kw); + PyTuple_SET_ITEM(result, 2, kw); + } + return result; +} + +static PyMethodDef spamlist_methods[] = { + {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS, + PyDoc_STR("getstate() -> state")}, + {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS, + PyDoc_STR("setstate(state)")}, + /* These entries differ only in the flags; they are used by the tests + in test.test_descr. */ + {"classmeth", (PyCFunction)(void(*)(void))spamlist_specialmeth, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("classmeth(*args, **kw)")}, + {"staticmeth", (PyCFunction)(void(*)(void))spamlist_specialmeth, + METH_VARARGS | METH_KEYWORDS | METH_STATIC, + PyDoc_STR("staticmeth(*args, **kw)")}, + {NULL, NULL}, +}; + +static int +spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds) +{ + if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0) + return -1; + self->state = 0; + return 0; +} + +static PyObject * +spamlist_state_get(spamlistobject *self, void *Py_UNUSED(ignored)) +{ + return PyLong_FromLong(self->state); +} + +static PyGetSetDef spamlist_getsets[] = { + {"state", (getter)spamlist_state_get, NULL, + PyDoc_STR("an int variable for demonstration purposes")}, + {0} +}; + +static PyTypeObject spamlist_type = { + PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) + "xxsubtype.spamlist", + sizeof(spamlistobject), + 0, + 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 */ + 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 */ + spamlist_methods, /* tp_methods */ + 0, /* tp_members */ + spamlist_getsets, /* tp_getset */ + DEFERRED_ADDRESS(&PyList_Type), /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)spamlist_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/* spamdict -- a dict subtype */ + +typedef struct { + PyDictObject dict; + int state; +} spamdictobject; + +static PyObject * +spamdict_getstate(spamdictobject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":getstate")) + return NULL; + return PyLong_FromLong(self->state); +} + +static PyObject * +spamdict_setstate(spamdictobject *self, PyObject *args) +{ + int state; + + if (!PyArg_ParseTuple(args, "i:setstate", &state)) + return NULL; + self->state = state; + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef spamdict_methods[] = { + {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS, + PyDoc_STR("getstate() -> state")}, + {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS, + PyDoc_STR("setstate(state)")}, + {NULL, NULL}, +}; + +static int +spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds) +{ + if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) + return -1; + self->state = 0; + return 0; +} + +static PyMemberDef spamdict_members[] = { + {"state", T_INT, offsetof(spamdictobject, state), READONLY, + PyDoc_STR("an int variable for demonstration purposes")}, + {0} +}; + +static PyTypeObject spamdict_type = { + PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) + "xxsubtype.spamdict", + sizeof(spamdictobject), + 0, + 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 */ + 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 */ + spamdict_methods, /* tp_methods */ + spamdict_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 */ + (initproc)spamdict_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +static PyObject * +spam_bench(PyObject *self, PyObject *args) +{ + PyObject *obj, *name, *res; + int n = 1000; + time_t t0, t1; + + if (!PyArg_ParseTuple(args, "OU|i", &obj, &name, &n)) + return NULL; + t0 = clock(); + while (--n >= 0) { + res = PyObject_GetAttr(obj, name); + if (res == NULL) + return NULL; + Py_DECREF(res); + } + t1 = clock(); + return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC); +} + +static PyMethodDef xxsubtype_functions[] = { + {"bench", spam_bench, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + +static int +xxsubtype_exec(PyObject* m) +{ + /* Fill in deferred data addresses. This must be done before + PyType_Ready() is called. Note that PyType_Ready() automatically + initializes the ob.ob_type field to &PyType_Type if it's NULL, + so it's not necessary to fill in ob_type first. */ + spamdict_type.tp_base = &PyDict_Type; + if (PyType_Ready(&spamdict_type) < 0) + return -1; + + spamlist_type.tp_base = &PyList_Type; + if (PyType_Ready(&spamlist_type) < 0) + return -1; + + if (PyType_Ready(&spamlist_type) < 0) + return -1; + if (PyType_Ready(&spamdict_type) < 0) + return -1; + + Py_INCREF(&spamlist_type); + if (PyModule_AddObject(m, "spamlist", + (PyObject *) &spamlist_type) < 0) + return -1; + + Py_INCREF(&spamdict_type); + if (PyModule_AddObject(m, "spamdict", + (PyObject *) &spamdict_type) < 0) + return -1; + return 0; +} + +static struct PyModuleDef_Slot xxsubtype_slots[] = { + {Py_mod_exec, xxsubtype_exec}, + {0, NULL}, +}; + +static struct PyModuleDef xxsubtypemodule = { + PyModuleDef_HEAD_INIT, + "xxsubtype", + xxsubtype__doc__, + 0, + xxsubtype_functions, + xxsubtype_slots, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit_xxsubtype(void) +{ + return PyModuleDef_Init(&xxsubtypemodule); +} diff --git a/python/Modules/zlibmodule.c b/python/Modules/zlibmodule.c new file mode 100755 index 0000000..d6b6b01 --- /dev/null +++ b/python/Modules/zlibmodule.c @@ -0,0 +1,1461 @@ +/* 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" +#include "zlib.h" + + +#include "pythread.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 PyTypeObject Comptype; +static PyTypeObject Decomptype; + +static PyObject *ZlibError; + +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(ZlibError, "Error %d %s", err, msg); + else + PyErr_Format(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: + PyErr_SetString(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; + + /* 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; + } + + self = newcompobject(&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; + } + + self = newcompobject(&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 + PyErr_Format(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) +{ + PyThread_free_lock(self->lock); + Py_XDECREF(self->unused_data); + Py_XDECREF(self->unconsumed_tail); + Py_XDECREF(self->zdict); + PyObject_Del(self); +} + +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; + + 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); + } + + 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(&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] +zlib.Compress.__copy__ +[clinic start generated code]*/ + +static PyObject * +zlib_Compress___copy___impl(compobject *self) +/*[clinic end generated code: output=1875e6791975442e input=be97a05a788dfd83]*/ +{ + return zlib_Compress_copy_impl(self); +} + +/*[clinic input] +zlib.Compress.__deepcopy__ + + memo: object + / + +[clinic start generated code]*/ + +static PyObject * +zlib_Compress___deepcopy__(compobject *self, PyObject *memo) +/*[clinic end generated code: output=f47a2213282c9eb0 input=a9a8b0b40d83388e]*/ +{ + return zlib_Compress_copy_impl(self); +} + +/*[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; + + retval = newcompobject(&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; +} + +/*[clinic input] +zlib.Decompress.__copy__ +[clinic start generated code]*/ + +static PyObject * +zlib_Decompress___copy___impl(compobject *self) +/*[clinic end generated code: output=80bae8bc43498ad4 input=efcb98b5472c13d2]*/ +{ + return zlib_Decompress_copy_impl(self); +} + +/*[clinic input] +zlib.Decompress.__deepcopy__ + + memo: object + / + +[clinic start generated code]*/ + +static PyObject * +zlib_Decompress___deepcopy__(compobject *self, PyObject *memo) +/*[clinic end generated code: output=1f77286ab490124b input=6e99bd0ac4b9cd8b]*/ +{ + 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; + } + + if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1) + return NULL; + + ENTER_ZLIB(self); + + 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 + 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} +}; + +static PyTypeObject Comptype = { + PyVarObject_HEAD_INIT(0, 0) + "zlib.Compress", + sizeof(compobject), + 0, + (destructor)Comp_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*/ + comp_methods, /*tp_methods*/ +}; + +static PyTypeObject Decomptype = { + PyVarObject_HEAD_INIT(0, 0) + "zlib.Decompress", + sizeof(compobject), + 0, + (destructor)Decomp_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*/ + Decomp_methods, /*tp_methods*/ + Decomp_members, /*tp_members*/ +}; + +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()."); + +static struct PyModuleDef zlibmodule = { + PyModuleDef_HEAD_INIT, + "zlib", + zlib_module_documentation, + -1, + zlib_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_zlib(void) +{ + PyObject *m, *ver; + if (PyType_Ready(&Comptype) < 0) + return NULL; + if (PyType_Ready(&Decomptype) < 0) + return NULL; + m = PyModule_Create(&zlibmodule); + if (m == NULL) + return NULL; + + ZlibError = PyErr_NewException("zlib.error", NULL, NULL); + if (ZlibError != NULL) { + Py_INCREF(ZlibError); + PyModule_AddObject(m, "error", 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"); + + return m; +} diff --git a/python/Objects/README b/python/Objects/README new file mode 100755 index 0000000..854b103 --- /dev/null +++ b/python/Objects/README @@ -0,0 +1 @@ +Source files for various builtin objects diff --git a/python/Objects/abstract.c b/python/Objects/abstract.c new file mode 100755 index 0000000..9c42d81 --- /dev/null +++ b/python/Objects/abstract.c @@ -0,0 +1,2696 @@ +/* Abstract Object Interface (many thanks to Jim Fulton) */ + +#include "Python.h" +#include "pycore_pystate.h" +#include +#include "structmember.h" /* we need the offsetof() macro from there */ +#include "longintrepr.h" + + + +/* Shorthands to return certain errors */ + +static PyObject * +type_error(const char *msg, PyObject *obj) +{ + PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name); + return NULL; +} + +static PyObject * +null_error(void) +{ + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_SystemError, + "null argument to internal routine"); + return NULL; +} + +/* Operations on any object */ + +PyObject * +PyObject_Type(PyObject *o) +{ + PyObject *v; + + if (o == NULL) { + return null_error(); + } + + v = (PyObject *)o->ob_type; + Py_INCREF(v); + return v; +} + +Py_ssize_t +PyObject_Size(PyObject *o) +{ + PySequenceMethods *m; + + if (o == NULL) { + null_error(); + return -1; + } + + m = o->ob_type->tp_as_sequence; + if (m && m->sq_length) { + Py_ssize_t len = m->sq_length(o); + assert(len >= 0 || PyErr_Occurred()); + return len; + } + + return PyMapping_Size(o); +} + +#undef PyObject_Length +Py_ssize_t +PyObject_Length(PyObject *o) +{ + return PyObject_Size(o); +} +#define PyObject_Length PyObject_Size + +int +_PyObject_HasLen(PyObject *o) { + return (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_length) || + (Py_TYPE(o)->tp_as_mapping && Py_TYPE(o)->tp_as_mapping->mp_length); +} + +/* The length hint function returns a non-negative value from o.__len__() + or o.__length_hint__(). If those methods aren't found the defaultvalue is + returned. If one of the calls fails with an exception other than TypeError + this function returns -1. +*/ + +Py_ssize_t +PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) +{ + PyObject *hint, *result; + Py_ssize_t res; + _Py_IDENTIFIER(__length_hint__); + if (_PyObject_HasLen(o)) { + res = PyObject_Length(o); + if (res < 0) { + assert(PyErr_Occurred()); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) { + return -1; + } + PyErr_Clear(); + } + else { + return res; + } + } + hint = _PyObject_LookupSpecial(o, &PyId___length_hint__); + if (hint == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return defaultvalue; + } + result = _PyObject_CallNoArg(hint); + Py_DECREF(hint); + if (result == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + return defaultvalue; + } + return -1; + } + else if (result == Py_NotImplemented) { + Py_DECREF(result); + return defaultvalue; + } + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, "__length_hint__ must be an integer, not %.100s", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return -1; + } + res = PyLong_AsSsize_t(result); + Py_DECREF(result); + if (res < 0 && PyErr_Occurred()) { + return -1; + } + if (res < 0) { + PyErr_Format(PyExc_ValueError, "__length_hint__() should return >= 0"); + return -1; + } + return res; +} + +PyObject * +PyObject_GetItem(PyObject *o, PyObject *key) +{ + PyMappingMethods *m; + PySequenceMethods *ms; + + if (o == NULL || key == NULL) { + return null_error(); + } + + m = o->ob_type->tp_as_mapping; + if (m && m->mp_subscript) { + PyObject *item = m->mp_subscript(o, key); + assert((item != NULL) ^ (PyErr_Occurred() != NULL)); + return item; + } + + ms = o->ob_type->tp_as_sequence; + if (ms && ms->sq_item) { + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (key_value == -1 && PyErr_Occurred()) + return NULL; + return PySequence_GetItem(o, key_value); + } + else { + return type_error("sequence index must " + "be integer, not '%.200s'", key); + } + } + + if (PyType_Check(o)) { + PyObject *meth, *result, *stack[1] = {key}; + _Py_IDENTIFIER(__class_getitem__); + if (_PyObject_LookupAttrId(o, &PyId___class_getitem__, &meth) < 0) { + return NULL; + } + if (meth) { + result = _PyObject_FastCall(meth, stack, 1); + Py_DECREF(meth); + return result; + } + } + + return type_error("'%.200s' object is not subscriptable", o); +} + +int +PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) +{ + PyMappingMethods *m; + + if (o == NULL || key == NULL || value == NULL) { + null_error(); + return -1; + } + m = o->ob_type->tp_as_mapping; + if (m && m->mp_ass_subscript) + return m->mp_ass_subscript(o, key, value); + + if (o->ob_type->tp_as_sequence) { + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (key_value == -1 && PyErr_Occurred()) + return -1; + return PySequence_SetItem(o, key_value, value); + } + else if (o->ob_type->tp_as_sequence->sq_ass_item) { + type_error("sequence index must be " + "integer, not '%.200s'", key); + return -1; + } + } + + type_error("'%.200s' object does not support item assignment", o); + return -1; +} + +int +PyObject_DelItem(PyObject *o, PyObject *key) +{ + PyMappingMethods *m; + + if (o == NULL || key == NULL) { + null_error(); + return -1; + } + m = o->ob_type->tp_as_mapping; + if (m && m->mp_ass_subscript) + return m->mp_ass_subscript(o, key, (PyObject*)NULL); + + if (o->ob_type->tp_as_sequence) { + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (key_value == -1 && PyErr_Occurred()) + return -1; + return PySequence_DelItem(o, key_value); + } + else if (o->ob_type->tp_as_sequence->sq_ass_item) { + type_error("sequence index must be " + "integer, not '%.200s'", key); + return -1; + } + } + + type_error("'%.200s' object does not support item deletion", o); + return -1; +} + +int +PyObject_DelItemString(PyObject *o, const char *key) +{ + PyObject *okey; + int ret; + + if (o == NULL || key == NULL) { + null_error(); + return -1; + } + okey = PyUnicode_FromString(key); + if (okey == NULL) + return -1; + ret = PyObject_DelItem(o, okey); + Py_DECREF(okey); + return ret; +} + +/* We release the buffer right after use of this function which could + cause issues later on. Don't use these functions in new code. + */ +int +PyObject_CheckReadBuffer(PyObject *obj) +{ + PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + Py_buffer view; + + if (pb == NULL || + pb->bf_getbuffer == NULL) + return 0; + if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) { + PyErr_Clear(); + return 0; + } + PyBuffer_Release(&view); + return 1; +} + +static int +as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) +{ + Py_buffer view; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) + return -1; + + *buffer = view.buf; + *buffer_len = view.len; + PyBuffer_Release(&view); + return 0; +} + +int +PyObject_AsCharBuffer(PyObject *obj, + const char **buffer, + Py_ssize_t *buffer_len) +{ + return as_read_buffer(obj, (const void **)buffer, buffer_len); +} + +int PyObject_AsReadBuffer(PyObject *obj, + const void **buffer, + Py_ssize_t *buffer_len) +{ + return as_read_buffer(obj, buffer, buffer_len); +} + +int PyObject_AsWriteBuffer(PyObject *obj, + void **buffer, + Py_ssize_t *buffer_len) +{ + PyBufferProcs *pb; + Py_buffer view; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + pb = obj->ob_type->tp_as_buffer; + if (pb == NULL || + pb->bf_getbuffer == NULL || + ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { + PyErr_SetString(PyExc_TypeError, + "expected a writable bytes-like object"); + return -1; + } + + *buffer = view.buf; + *buffer_len = view.len; + PyBuffer_Release(&view); + return 0; +} + +/* Buffer C-API for Python 3.0 */ + +int +PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) +{ + PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + + if (pb == NULL || pb->bf_getbuffer == NULL) { + PyErr_Format(PyExc_TypeError, + "a bytes-like object is required, not '%.100s'", + Py_TYPE(obj)->tp_name); + return -1; + } + return (*pb->bf_getbuffer)(obj, view, flags); +} + +static int +_IsFortranContiguous(const Py_buffer *view) +{ + Py_ssize_t sd, dim; + int i; + + /* 1) len = product(shape) * itemsize + 2) itemsize > 0 + 3) len = 0 <==> exists i: shape[i] = 0 */ + if (view->len == 0) return 1; + if (view->strides == NULL) { /* C-contiguous by definition */ + /* Trivially F-contiguous */ + if (view->ndim <= 1) return 1; + + /* ndim > 1 implies shape != NULL */ + assert(view->shape != NULL); + + /* Effectively 1-d */ + sd = 0; + for (i=0; indim; i++) { + if (view->shape[i] > 1) sd += 1; + } + return sd <= 1; + } + + /* strides != NULL implies both of these */ + assert(view->ndim > 0); + assert(view->shape != NULL); + + sd = view->itemsize; + for (i=0; indim; i++) { + dim = view->shape[i]; + if (dim > 1 && view->strides[i] != sd) { + return 0; + } + sd *= dim; + } + return 1; +} + +static int +_IsCContiguous(const Py_buffer *view) +{ + Py_ssize_t sd, dim; + int i; + + /* 1) len = product(shape) * itemsize + 2) itemsize > 0 + 3) len = 0 <==> exists i: shape[i] = 0 */ + if (view->len == 0) return 1; + if (view->strides == NULL) return 1; /* C-contiguous by definition */ + + /* strides != NULL implies both of these */ + assert(view->ndim > 0); + assert(view->shape != NULL); + + sd = view->itemsize; + for (i=view->ndim-1; i>=0; i--) { + dim = view->shape[i]; + if (dim > 1 && view->strides[i] != sd) { + return 0; + } + sd *= dim; + } + return 1; +} + +int +PyBuffer_IsContiguous(const Py_buffer *view, char order) +{ + + if (view->suboffsets != NULL) return 0; + + if (order == 'C') + return _IsCContiguous(view); + else if (order == 'F') + return _IsFortranContiguous(view); + else if (order == 'A') + return (_IsCContiguous(view) || _IsFortranContiguous(view)); + return 0; +} + + +void* +PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices) +{ + char* pointer; + int i; + pointer = (char *)view->buf; + for (i = 0; i < view->ndim; i++) { + pointer += view->strides[i]*indices[i]; + if ((view->suboffsets != NULL) && (view->suboffsets[i] >= 0)) { + pointer = *((char**)pointer) + view->suboffsets[i]; + } + } + return (void*)pointer; +} + + +void +_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape) +{ + int k; + + for (k=0; k=0; k--) { + if (index[k] < shape[k]-1) { + index[k]++; + break; + } + else { + index[k] = 0; + } + } +} + +int +PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) +{ + int k; + void (*addone)(int, Py_ssize_t *, const Py_ssize_t *); + Py_ssize_t *indices, elements; + char *src, *ptr; + + if (len > view->len) { + len = view->len; + } + + if (PyBuffer_IsContiguous(view, fort)) { + /* simplest copy is all that is needed */ + memcpy(view->buf, buf, len); + return 0; + } + + /* Otherwise a more elaborate scheme is needed */ + + /* view->ndim <= 64 */ + indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); + if (indices == NULL) { + PyErr_NoMemory(); + return -1; + } + for (k=0; kndim;k++) { + indices[k] = 0; + } + + if (fort == 'F') { + addone = _Py_add_one_to_index_F; + } + else { + addone = _Py_add_one_to_index_C; + } + src = buf; + /* XXX : This is not going to be the fastest code in the world + several optimizations are possible. + */ + elements = len / view->itemsize; + while (elements--) { + ptr = PyBuffer_GetPointer(view, indices); + memcpy(ptr, src, view->itemsize); + src += view->itemsize; + addone(view->ndim, indices, view->shape); + } + + PyMem_Free(indices); + return 0; +} + +int PyObject_CopyData(PyObject *dest, PyObject *src) +{ + Py_buffer view_dest, view_src; + int k; + Py_ssize_t *indices, elements; + char *dptr, *sptr; + + if (!PyObject_CheckBuffer(dest) || + !PyObject_CheckBuffer(src)) { + PyErr_SetString(PyExc_TypeError, + "both destination and source must be "\ + "bytes-like objects"); + return -1; + } + + if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1; + if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) { + PyBuffer_Release(&view_dest); + return -1; + } + + if (view_dest.len < view_src.len) { + PyErr_SetString(PyExc_BufferError, + "destination is too small to receive data from source"); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); + return -1; + } + + if ((PyBuffer_IsContiguous(&view_dest, 'C') && + PyBuffer_IsContiguous(&view_src, 'C')) || + (PyBuffer_IsContiguous(&view_dest, 'F') && + PyBuffer_IsContiguous(&view_src, 'F'))) { + /* simplest copy is all that is needed */ + memcpy(view_dest.buf, view_src.buf, view_src.len); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); + return 0; + } + + /* Otherwise a more elaborate copy scheme is needed */ + + /* XXX(nnorwitz): need to check for overflow! */ + indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim); + if (indices == NULL) { + PyErr_NoMemory(); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); + return -1; + } + for (k=0; k=0; k--) { + strides[k] = sd; + sd *= shape[k]; + } + } + return; +} + +int +PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, + int readonly, int flags) +{ + if (view == NULL) { + PyErr_SetString(PyExc_BufferError, + "PyBuffer_FillInfo: view==NULL argument is obsolete"); + return -1; + } + + if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && + (readonly == 1)) { + PyErr_SetString(PyExc_BufferError, + "Object is not writable."); + return -1; + } + + view->obj = obj; + if (obj) + Py_INCREF(obj); + view->buf = buf; + view->len = len; + view->readonly = readonly; + view->itemsize = 1; + view->format = NULL; + if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) + view->format = "B"; + view->ndim = 1; + view->shape = NULL; + if ((flags & PyBUF_ND) == PyBUF_ND) + view->shape = &(view->len); + view->strides = NULL; + if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) + view->strides = &(view->itemsize); + view->suboffsets = NULL; + view->internal = NULL; + return 0; +} + +void +PyBuffer_Release(Py_buffer *view) +{ + PyObject *obj = view->obj; + PyBufferProcs *pb; + if (obj == NULL) + return; + pb = Py_TYPE(obj)->tp_as_buffer; + if (pb && pb->bf_releasebuffer) + pb->bf_releasebuffer(obj, view); + view->obj = NULL; + Py_DECREF(obj); +} + +PyObject * +PyObject_Format(PyObject *obj, PyObject *format_spec) +{ + PyObject *meth; + PyObject *empty = NULL; + PyObject *result = NULL; + _Py_IDENTIFIER(__format__); + + if (format_spec != NULL && !PyUnicode_Check(format_spec)) { + PyErr_Format(PyExc_SystemError, + "Format specifier must be a string, not %.200s", + Py_TYPE(format_spec)->tp_name); + return NULL; + } + + /* Fast path for common types. */ + if (format_spec == NULL || PyUnicode_GET_LENGTH(format_spec) == 0) { + if (PyUnicode_CheckExact(obj)) { + Py_INCREF(obj); + return obj; + } + if (PyLong_CheckExact(obj)) { + return PyObject_Str(obj); + } + } + + /* If no format_spec is provided, use an empty string */ + if (format_spec == NULL) { + empty = PyUnicode_New(0, 0); + format_spec = empty; + } + + /* Find the (unbound!) __format__ method */ + meth = _PyObject_LookupSpecial(obj, &PyId___format__); + if (meth == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); + goto done; + } + + /* And call it. */ + result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); + Py_DECREF(meth); + + if (result && !PyUnicode_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__format__ must return a str, not %.200s", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + result = NULL; + goto done; + } + +done: + Py_XDECREF(empty); + return result; +} +/* Operations on numbers */ + +int +PyNumber_Check(PyObject *o) +{ + return o && o->ob_type->tp_as_number && + (o->ob_type->tp_as_number->nb_index || + o->ob_type->tp_as_number->nb_int || + o->ob_type->tp_as_number->nb_float); +} + +/* Binary operators */ + +#define NB_SLOT(x) offsetof(PyNumberMethods, x) +#define NB_BINOP(nb_methods, slot) \ + (*(binaryfunc*)(& ((char*)nb_methods)[slot])) +#define NB_TERNOP(nb_methods, slot) \ + (*(ternaryfunc*)(& ((char*)nb_methods)[slot])) + +/* + Calling scheme used for binary operations: + + Order operations are tried until either a valid result or error: + w.op(v,w)[*], v.op(v,w), w.op(v,w) + + [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of + v->ob_type + */ + +static PyObject * +binary_op1(PyObject *v, PyObject *w, const int op_slot) +{ + PyObject *x; + binaryfunc slotv = NULL; + binaryfunc slotw = NULL; + + if (v->ob_type->tp_as_number != NULL) + slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot); + if (w->ob_type != v->ob_type && + w->ob_type->tp_as_number != NULL) { + slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot); + if (slotw == slotv) + slotw = NULL; + } + if (slotv) { + if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { + x = slotw(v, w); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + slotw = NULL; + } + x = slotv(v, w); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + } + if (slotw) { + x = slotw(v, w); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + } + Py_RETURN_NOTIMPLEMENTED; +} + +static PyObject * +binop_type_error(PyObject *v, PyObject *w, const char *op_name) +{ + PyErr_Format(PyExc_TypeError, + "unsupported operand type(s) for %.100s: " + "'%.100s' and '%.100s'", + op_name, + v->ob_type->tp_name, + w->ob_type->tp_name); + return NULL; +} + +static PyObject * +binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) +{ + PyObject *result = binary_op1(v, w, op_slot); + if (result == Py_NotImplemented) { + Py_DECREF(result); + + if (op_slot == NB_SLOT(nb_rshift) && + PyCFunction_Check(v) && + strcmp(((PyCFunctionObject *)v)->m_ml->ml_name, "print") == 0) + { + PyErr_Format(PyExc_TypeError, + "unsupported operand type(s) for %.100s: " + "'%.100s' and '%.100s'. Did you mean \"print(, " + "file=)\"?", + op_name, + v->ob_type->tp_name, + w->ob_type->tp_name); + return NULL; + } + + return binop_type_error(v, w, op_name); + } + return result; +} + + +/* + Calling scheme used for ternary operations: + + Order operations are tried until either a valid result or error: + v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) + */ + +static PyObject * +ternary_op(PyObject *v, + PyObject *w, + PyObject *z, + const int op_slot, + const char *op_name) +{ + PyNumberMethods *mv, *mw, *mz; + PyObject *x = NULL; + ternaryfunc slotv = NULL; + ternaryfunc slotw = NULL; + ternaryfunc slotz = NULL; + + mv = v->ob_type->tp_as_number; + mw = w->ob_type->tp_as_number; + if (mv != NULL) + slotv = NB_TERNOP(mv, op_slot); + if (w->ob_type != v->ob_type && + mw != NULL) { + slotw = NB_TERNOP(mw, op_slot); + if (slotw == slotv) + slotw = NULL; + } + if (slotv) { + if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { + x = slotw(v, w, z); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + slotw = NULL; + } + x = slotv(v, w, z); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + } + if (slotw) { + x = slotw(v, w, z); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + } + mz = z->ob_type->tp_as_number; + if (mz != NULL) { + slotz = NB_TERNOP(mz, op_slot); + if (slotz == slotv || slotz == slotw) + slotz = NULL; + if (slotz) { + x = slotz(v, w, z); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + } + } + + if (z == Py_None) + PyErr_Format( + PyExc_TypeError, + "unsupported operand type(s) for ** or pow(): " + "'%.100s' and '%.100s'", + v->ob_type->tp_name, + w->ob_type->tp_name); + else + PyErr_Format( + PyExc_TypeError, + "unsupported operand type(s) for pow(): " + "'%.100s', '%.100s', '%.100s'", + v->ob_type->tp_name, + w->ob_type->tp_name, + z->ob_type->tp_name); + return NULL; +} + +#define BINARY_FUNC(func, op, op_name) \ + PyObject * \ + func(PyObject *v, PyObject *w) { \ + return binary_op(v, w, NB_SLOT(op), op_name); \ + } + +BINARY_FUNC(PyNumber_Or, nb_or, "|") +BINARY_FUNC(PyNumber_Xor, nb_xor, "^") +BINARY_FUNC(PyNumber_And, nb_and, "&") +BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<") +BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>") +BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-") +BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()") + +PyObject * +PyNumber_Add(PyObject *v, PyObject *w) +{ + PyObject *result = binary_op1(v, w, NB_SLOT(nb_add)); + if (result == Py_NotImplemented) { + PySequenceMethods *m = v->ob_type->tp_as_sequence; + Py_DECREF(result); + if (m && m->sq_concat) { + return (*m->sq_concat)(v, w); + } + result = binop_type_error(v, w, "+"); + } + return result; +} + +static PyObject * +sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) +{ + Py_ssize_t count; + if (PyIndex_Check(n)) { + count = PyNumber_AsSsize_t(n, PyExc_OverflowError); + if (count == -1 && PyErr_Occurred()) + return NULL; + } + else { + return type_error("can't multiply sequence by " + "non-int of type '%.200s'", n); + } + return (*repeatfunc)(seq, count); +} + +PyObject * +PyNumber_Multiply(PyObject *v, PyObject *w) +{ + PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply)); + if (result == Py_NotImplemented) { + PySequenceMethods *mv = v->ob_type->tp_as_sequence; + PySequenceMethods *mw = w->ob_type->tp_as_sequence; + Py_DECREF(result); + if (mv && mv->sq_repeat) { + return sequence_repeat(mv->sq_repeat, v, w); + } + else if (mw && mw->sq_repeat) { + return sequence_repeat(mw->sq_repeat, w, v); + } + result = binop_type_error(v, w, "*"); + } + return result; +} + +PyObject * +PyNumber_MatrixMultiply(PyObject *v, PyObject *w) +{ + return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@"); +} + +PyObject * +PyNumber_FloorDivide(PyObject *v, PyObject *w) +{ + return binary_op(v, w, NB_SLOT(nb_floor_divide), "//"); +} + +PyObject * +PyNumber_TrueDivide(PyObject *v, PyObject *w) +{ + return binary_op(v, w, NB_SLOT(nb_true_divide), "/"); +} + +PyObject * +PyNumber_Remainder(PyObject *v, PyObject *w) +{ + return binary_op(v, w, NB_SLOT(nb_remainder), "%"); +} + +PyObject * +PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) +{ + return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()"); +} + +/* Binary in-place operators */ + +/* The in-place operators are defined to fall back to the 'normal', + non in-place operations, if the in-place methods are not in place. + + - If the left hand object has the appropriate struct members, and + they are filled, call the appropriate function and return the + result. No coercion is done on the arguments; the left-hand object + is the one the operation is performed on, and it's up to the + function to deal with the right-hand object. + + - Otherwise, in-place modification is not supported. Handle it exactly as + a non in-place operation of the same kind. + + */ + +static PyObject * +binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot) +{ + PyNumberMethods *mv = v->ob_type->tp_as_number; + if (mv != NULL) { + binaryfunc slot = NB_BINOP(mv, iop_slot); + if (slot) { + PyObject *x = (slot)(v, w); + if (x != Py_NotImplemented) { + return x; + } + Py_DECREF(x); + } + } + return binary_op1(v, w, op_slot); +} + +static PyObject * +binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot, + const char *op_name) +{ + PyObject *result = binary_iop1(v, w, iop_slot, op_slot); + if (result == Py_NotImplemented) { + Py_DECREF(result); + return binop_type_error(v, w, op_name); + } + return result; +} + +#define INPLACE_BINOP(func, iop, op, op_name) \ + PyObject * \ + func(PyObject *v, PyObject *w) { \ + return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \ + } + +INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=") +INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=") +INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=") +INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=") +INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=") +INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=") +INPLACE_BINOP(PyNumber_InMatrixMultiply, nb_inplace_matrix_multiply, nb_matrix_multiply, "@=") + +PyObject * +PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w) +{ + return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide), + NB_SLOT(nb_floor_divide), "//="); +} + +PyObject * +PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w) +{ + return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide), + NB_SLOT(nb_true_divide), "/="); +} + +PyObject * +PyNumber_InPlaceAdd(PyObject *v, PyObject *w) +{ + PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), + NB_SLOT(nb_add)); + if (result == Py_NotImplemented) { + PySequenceMethods *m = v->ob_type->tp_as_sequence; + Py_DECREF(result); + if (m != NULL) { + binaryfunc f = NULL; + f = m->sq_inplace_concat; + if (f == NULL) + f = m->sq_concat; + if (f != NULL) + return (*f)(v, w); + } + result = binop_type_error(v, w, "+="); + } + return result; +} + +PyObject * +PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) +{ + PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply), + NB_SLOT(nb_multiply)); + if (result == Py_NotImplemented) { + ssizeargfunc f = NULL; + PySequenceMethods *mv = v->ob_type->tp_as_sequence; + PySequenceMethods *mw = w->ob_type->tp_as_sequence; + Py_DECREF(result); + if (mv != NULL) { + f = mv->sq_inplace_repeat; + if (f == NULL) + f = mv->sq_repeat; + if (f != NULL) + return sequence_repeat(f, v, w); + } + else if (mw != NULL) { + /* Note that the right hand operand should not be + * mutated in this case so sq_inplace_repeat is not + * used. */ + if (mw->sq_repeat) + return sequence_repeat(mw->sq_repeat, w, v); + } + result = binop_type_error(v, w, "*="); + } + return result; +} + +PyObject * +PyNumber_InPlaceMatrixMultiply(PyObject *v, PyObject *w) +{ + return binary_iop(v, w, NB_SLOT(nb_inplace_matrix_multiply), + NB_SLOT(nb_matrix_multiply), "@="); +} + +PyObject * +PyNumber_InPlaceRemainder(PyObject *v, PyObject *w) +{ + return binary_iop(v, w, NB_SLOT(nb_inplace_remainder), + NB_SLOT(nb_remainder), "%="); +} + +PyObject * +PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) +{ + if (v->ob_type->tp_as_number && + v->ob_type->tp_as_number->nb_inplace_power != NULL) { + return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**="); + } + else { + return ternary_op(v, w, z, NB_SLOT(nb_power), "**="); + } +} + + +/* Unary operators and functions */ + +PyObject * +PyNumber_Negative(PyObject *o) +{ + PyNumberMethods *m; + + if (o == NULL) { + return null_error(); + } + + m = o->ob_type->tp_as_number; + if (m && m->nb_negative) + return (*m->nb_negative)(o); + + return type_error("bad operand type for unary -: '%.200s'", o); +} + +PyObject * +PyNumber_Positive(PyObject *o) +{ + PyNumberMethods *m; + + if (o == NULL) { + return null_error(); + } + + m = o->ob_type->tp_as_number; + if (m && m->nb_positive) + return (*m->nb_positive)(o); + + return type_error("bad operand type for unary +: '%.200s'", o); +} + +PyObject * +PyNumber_Invert(PyObject *o) +{ + PyNumberMethods *m; + + if (o == NULL) { + return null_error(); + } + + m = o->ob_type->tp_as_number; + if (m && m->nb_invert) + return (*m->nb_invert)(o); + + return type_error("bad operand type for unary ~: '%.200s'", o); +} + +PyObject * +PyNumber_Absolute(PyObject *o) +{ + PyNumberMethods *m; + + if (o == NULL) { + return null_error(); + } + + m = o->ob_type->tp_as_number; + if (m && m->nb_absolute) + return m->nb_absolute(o); + + return type_error("bad operand type for abs(): '%.200s'", o); +} + +#undef PyIndex_Check + +int +PyIndex_Check(PyObject *obj) +{ + return obj->ob_type->tp_as_number != NULL && + obj->ob_type->tp_as_number->nb_index != NULL; +} + +/* Return a Python int from the object item. + Raise TypeError if the result is not an int + or if the object cannot be interpreted as an index. +*/ +PyObject * +PyNumber_Index(PyObject *item) +{ + PyObject *result = NULL; + if (item == NULL) { + return null_error(); + } + + if (PyLong_Check(item)) { + Py_INCREF(item); + return item; + } + if (!PyIndex_Check(item)) { + PyErr_Format(PyExc_TypeError, + "'%.200s' object cannot be interpreted " + "as an integer", item->ob_type->tp_name); + return NULL; + } + result = item->ob_type->tp_as_number->nb_index(item); + if (!result || PyLong_CheckExact(result)) + return result; + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__index__ returned non-int (type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__index__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + result->ob_type->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; +} + +/* Return an error on Overflow only if err is not NULL*/ + +Py_ssize_t +PyNumber_AsSsize_t(PyObject *item, PyObject *err) +{ + Py_ssize_t result; + PyObject *runerr; + PyObject *value = PyNumber_Index(item); + if (value == NULL) + return -1; + + /* We're done if PyLong_AsSsize_t() returns without error. */ + result = PyLong_AsSsize_t(value); + if (result != -1 || !(runerr = PyErr_Occurred())) + goto finish; + + /* Error handling code -- only manage OverflowError differently */ + if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) + goto finish; + + PyErr_Clear(); + /* If no error-handling desired then the default clipping + is sufficient. + */ + if (!err) { + assert(PyLong_Check(value)); + /* Whether or not it is less than or equal to + zero is determined by the sign of ob_size + */ + if (_PyLong_Sign(value) < 0) + result = PY_SSIZE_T_MIN; + else + result = PY_SSIZE_T_MAX; + } + else { + /* Otherwise replace the error with caller's error object. */ + PyErr_Format(err, + "cannot fit '%.200s' into an index-sized integer", + item->ob_type->tp_name); + } + + finish: + Py_DECREF(value); + return result; +} + + +PyObject * +PyNumber_Long(PyObject *o) +{ + PyObject *result; + PyNumberMethods *m; + PyObject *trunc_func; + Py_buffer view; + _Py_IDENTIFIER(__trunc__); + + if (o == NULL) { + return null_error(); + } + + if (PyLong_CheckExact(o)) { + Py_INCREF(o); + return o; + } + m = o->ob_type->tp_as_number; + if (m && m->nb_int) { /* This should include subclasses of int */ + result = _PyLong_FromNbInt(o); + if (result != NULL && !PyLong_CheckExact(result)) { + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + } + return result; + } + if (m && m->nb_index) { + result = _PyLong_FromNbIndexOrNbInt(o); + if (result != NULL && !PyLong_CheckExact(result)) { + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + } + return result; + } + trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__); + if (trunc_func) { + result = _PyObject_CallNoArg(trunc_func); + Py_DECREF(trunc_func); + if (result == NULL || PyLong_CheckExact(result)) { + return result; + } + if (PyLong_Check(result)) { + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + return result; + } + /* __trunc__ is specified to return an Integral type, + but int() needs to return an int. */ + m = result->ob_type->tp_as_number; + if (m == NULL || (m->nb_index == NULL && m->nb_int == NULL)) { + PyErr_Format( + PyExc_TypeError, + "__trunc__ returned non-Integral (type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + Py_SETREF(result, _PyLong_FromNbIndexOrNbInt(result)); + if (result != NULL && !PyLong_CheckExact(result)) { + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + } + return result; + } + if (PyErr_Occurred()) + return NULL; + + if (PyUnicode_Check(o)) + /* The below check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicodeObject(o, 10); + + if (PyBytes_Check(o)) + /* need to do extra error checking that PyLong_FromString() + * doesn't do. In particular int('9\x005') must raise an + * exception, not truncate at the null. + */ + return _PyLong_FromBytes(PyBytes_AS_STRING(o), + PyBytes_GET_SIZE(o), 10); + + if (PyByteArray_Check(o)) + return _PyLong_FromBytes(PyByteArray_AS_STRING(o), + PyByteArray_GET_SIZE(o), 10); + + if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { + PyObject *bytes; + + /* Copy to NUL-terminated buffer. */ + bytes = PyBytes_FromStringAndSize((const char *)view.buf, view.len); + if (bytes == NULL) { + PyBuffer_Release(&view); + return NULL; + } + result = _PyLong_FromBytes(PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes), 10); + Py_DECREF(bytes); + PyBuffer_Release(&view); + return result; + } + + return type_error("int() argument must be a string, a bytes-like object " + "or a number, not '%.200s'", o); +} + +PyObject * +PyNumber_Float(PyObject *o) +{ + PyNumberMethods *m; + + if (o == NULL) { + return null_error(); + } + + if (PyFloat_CheckExact(o)) { + Py_INCREF(o); + return o; + } + m = o->ob_type->tp_as_number; + if (m && m->nb_float) { /* This should include subclasses of float */ + PyObject *res = m->nb_float(o); + double val; + if (!res || PyFloat_CheckExact(res)) { + return res; + } + if (!PyFloat_Check(res)) { + PyErr_Format(PyExc_TypeError, + "%.50s.__float__ returned non-float (type %.50s)", + o->ob_type->tp_name, res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + /* Issue #26983: warn if 'res' not of exact type float. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "%.50s.__float__ returned non-float (type %.50s). " + "The ability to return an instance of a strict subclass of float " + "is deprecated, and may be removed in a future version of Python.", + o->ob_type->tp_name, res->ob_type->tp_name)) { + Py_DECREF(res); + return NULL; + } + val = PyFloat_AS_DOUBLE(res); + Py_DECREF(res); + return PyFloat_FromDouble(val); + } + if (m && m->nb_index) { + PyObject *res = PyNumber_Index(o); + if (!res) { + return NULL; + } + double val = PyLong_AsDouble(res); + Py_DECREF(res); + if (val == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(val); + } + if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */ + return PyFloat_FromDouble(PyFloat_AS_DOUBLE(o)); + } + return PyFloat_FromString(o); +} + + +PyObject * +PyNumber_ToBase(PyObject *n, int base) +{ + if (!(base == 2 || base == 8 || base == 10 || base == 16)) { + PyErr_SetString(PyExc_SystemError, + "PyNumber_ToBase: base must be 2, 8, 10 or 16"); + return NULL; + } + PyObject *index = PyNumber_Index(n); + if (!index) + return NULL; + PyObject *res = _PyLong_Format(index, base); + Py_DECREF(index); + return res; +} + + +/* Operations on sequences */ + +int +PySequence_Check(PyObject *s) +{ + if (PyDict_Check(s)) + return 0; + return s->ob_type->tp_as_sequence && + s->ob_type->tp_as_sequence->sq_item != NULL; +} + +Py_ssize_t +PySequence_Size(PyObject *s) +{ + PySequenceMethods *m; + + if (s == NULL) { + null_error(); + return -1; + } + + m = s->ob_type->tp_as_sequence; + if (m && m->sq_length) { + Py_ssize_t len = m->sq_length(s); + assert(len >= 0 || PyErr_Occurred()); + return len; + } + + if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_length) { + type_error("%.200s is not a sequence", s); + return -1; + } + type_error("object of type '%.200s' has no len()", s); + return -1; +} + +#undef PySequence_Length +Py_ssize_t +PySequence_Length(PyObject *s) +{ + return PySequence_Size(s); +} +#define PySequence_Length PySequence_Size + +PyObject * +PySequence_Concat(PyObject *s, PyObject *o) +{ + PySequenceMethods *m; + + if (s == NULL || o == NULL) { + return null_error(); + } + + m = s->ob_type->tp_as_sequence; + if (m && m->sq_concat) + return m->sq_concat(s, o); + + /* Instances of user classes defining an __add__() method only + have an nb_add slot, not an sq_concat slot. So we fall back + to nb_add if both arguments appear to be sequences. */ + if (PySequence_Check(s) && PySequence_Check(o)) { + PyObject *result = binary_op1(s, o, NB_SLOT(nb_add)); + if (result != Py_NotImplemented) + return result; + Py_DECREF(result); + } + return type_error("'%.200s' object can't be concatenated", s); +} + +PyObject * +PySequence_Repeat(PyObject *o, Py_ssize_t count) +{ + PySequenceMethods *m; + + if (o == NULL) { + return null_error(); + } + + m = o->ob_type->tp_as_sequence; + if (m && m->sq_repeat) + return m->sq_repeat(o, count); + + /* Instances of user classes defining a __mul__() method only + have an nb_multiply slot, not an sq_repeat slot. so we fall back + to nb_multiply if o appears to be a sequence. */ + if (PySequence_Check(o)) { + PyObject *n, *result; + n = PyLong_FromSsize_t(count); + if (n == NULL) + return NULL; + result = binary_op1(o, n, NB_SLOT(nb_multiply)); + Py_DECREF(n); + if (result != Py_NotImplemented) + return result; + Py_DECREF(result); + } + return type_error("'%.200s' object can't be repeated", o); +} + +PyObject * +PySequence_InPlaceConcat(PyObject *s, PyObject *o) +{ + PySequenceMethods *m; + + if (s == NULL || o == NULL) { + return null_error(); + } + + m = s->ob_type->tp_as_sequence; + if (m && m->sq_inplace_concat) + return m->sq_inplace_concat(s, o); + if (m && m->sq_concat) + return m->sq_concat(s, o); + + if (PySequence_Check(s) && PySequence_Check(o)) { + PyObject *result = binary_iop1(s, o, NB_SLOT(nb_inplace_add), + NB_SLOT(nb_add)); + if (result != Py_NotImplemented) + return result; + Py_DECREF(result); + } + return type_error("'%.200s' object can't be concatenated", s); +} + +PyObject * +PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) +{ + PySequenceMethods *m; + + if (o == NULL) { + return null_error(); + } + + m = o->ob_type->tp_as_sequence; + if (m && m->sq_inplace_repeat) + return m->sq_inplace_repeat(o, count); + if (m && m->sq_repeat) + return m->sq_repeat(o, count); + + if (PySequence_Check(o)) { + PyObject *n, *result; + n = PyLong_FromSsize_t(count); + if (n == NULL) + return NULL; + result = binary_iop1(o, n, NB_SLOT(nb_inplace_multiply), + NB_SLOT(nb_multiply)); + Py_DECREF(n); + if (result != Py_NotImplemented) + return result; + Py_DECREF(result); + } + return type_error("'%.200s' object can't be repeated", o); +} + +PyObject * +PySequence_GetItem(PyObject *s, Py_ssize_t i) +{ + PySequenceMethods *m; + + if (s == NULL) { + return null_error(); + } + + m = s->ob_type->tp_as_sequence; + if (m && m->sq_item) { + if (i < 0) { + if (m->sq_length) { + Py_ssize_t l = (*m->sq_length)(s); + if (l < 0) { + assert(PyErr_Occurred()); + return NULL; + } + i += l; + } + } + return m->sq_item(s, i); + } + + if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_subscript) { + return type_error("%.200s is not a sequence", s); + } + return type_error("'%.200s' object does not support indexing", s); +} + +PyObject * +PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) +{ + PyMappingMethods *mp; + + if (!s) { + return null_error(); + } + + mp = s->ob_type->tp_as_mapping; + if (mp && mp->mp_subscript) { + PyObject *res; + PyObject *slice = _PySlice_FromIndices(i1, i2); + if (!slice) + return NULL; + res = mp->mp_subscript(s, slice); + Py_DECREF(slice); + return res; + } + + return type_error("'%.200s' object is unsliceable", s); +} + +int +PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) +{ + PySequenceMethods *m; + + if (s == NULL) { + null_error(); + return -1; + } + + m = s->ob_type->tp_as_sequence; + if (m && m->sq_ass_item) { + if (i < 0) { + if (m->sq_length) { + Py_ssize_t l = (*m->sq_length)(s); + if (l < 0) { + assert(PyErr_Occurred()); + return -1; + } + i += l; + } + } + return m->sq_ass_item(s, i, o); + } + + if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_ass_subscript) { + type_error("%.200s is not a sequence", s); + return -1; + } + type_error("'%.200s' object does not support item assignment", s); + return -1; +} + +int +PySequence_DelItem(PyObject *s, Py_ssize_t i) +{ + PySequenceMethods *m; + + if (s == NULL) { + null_error(); + return -1; + } + + m = s->ob_type->tp_as_sequence; + if (m && m->sq_ass_item) { + if (i < 0) { + if (m->sq_length) { + Py_ssize_t l = (*m->sq_length)(s); + if (l < 0) { + assert(PyErr_Occurred()); + return -1; + } + i += l; + } + } + return m->sq_ass_item(s, i, (PyObject *)NULL); + } + + if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_ass_subscript) { + type_error("%.200s is not a sequence", s); + return -1; + } + type_error("'%.200s' object doesn't support item deletion", s); + return -1; +} + +int +PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) +{ + PyMappingMethods *mp; + + if (s == NULL) { + null_error(); + return -1; + } + + mp = s->ob_type->tp_as_mapping; + if (mp && mp->mp_ass_subscript) { + int res; + PyObject *slice = _PySlice_FromIndices(i1, i2); + if (!slice) + return -1; + res = mp->mp_ass_subscript(s, slice, o); + Py_DECREF(slice); + return res; + } + + type_error("'%.200s' object doesn't support slice assignment", s); + return -1; +} + +int +PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) +{ + PyMappingMethods *mp; + + if (s == NULL) { + null_error(); + return -1; + } + + mp = s->ob_type->tp_as_mapping; + if (mp && mp->mp_ass_subscript) { + int res; + PyObject *slice = _PySlice_FromIndices(i1, i2); + if (!slice) + return -1; + res = mp->mp_ass_subscript(s, slice, NULL); + Py_DECREF(slice); + return res; + } + type_error("'%.200s' object doesn't support slice deletion", s); + return -1; +} + +PyObject * +PySequence_Tuple(PyObject *v) +{ + PyObject *it; /* iter(v) */ + Py_ssize_t n; /* guess for result tuple size */ + PyObject *result = NULL; + Py_ssize_t j; + + if (v == NULL) { + return null_error(); + } + + /* Special-case the common tuple and list cases, for efficiency. */ + if (PyTuple_CheckExact(v)) { + /* Note that we can't know whether it's safe to return + a tuple *subclass* instance as-is, hence the restriction + to exact tuples here. In contrast, lists always make + a copy, so there's no need for exactness below. */ + Py_INCREF(v); + return v; + } + if (PyList_CheckExact(v)) + return PyList_AsTuple(v); + + /* Get iterator. */ + it = PyObject_GetIter(v); + if (it == NULL) + return NULL; + + /* Guess result size and allocate space. */ + n = PyObject_LengthHint(v, 10); + if (n == -1) + goto Fail; + result = PyTuple_New(n); + if (result == NULL) + goto Fail; + + /* Fill the tuple. */ + for (j = 0; ; ++j) { + PyObject *item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) + goto Fail; + break; + } + if (j >= n) { + size_t newn = (size_t)n; + /* The over-allocation strategy can grow a bit faster + than for lists because unlike lists the + over-allocation isn't permanent -- we reclaim + the excess before the end of this routine. + So, grow by ten and then add 25%. + */ + newn += 10u; + newn += newn >> 2; + if (newn > PY_SSIZE_T_MAX) { + /* Check for overflow */ + PyErr_NoMemory(); + Py_DECREF(item); + goto Fail; + } + n = (Py_ssize_t)newn; + if (_PyTuple_Resize(&result, n) != 0) { + Py_DECREF(item); + goto Fail; + } + } + PyTuple_SET_ITEM(result, j, item); + } + + /* Cut tuple back if guess was too large. */ + if (j < n && + _PyTuple_Resize(&result, j) != 0) + goto Fail; + + Py_DECREF(it); + return result; + +Fail: + Py_XDECREF(result); + Py_DECREF(it); + return NULL; +} + +PyObject * +PySequence_List(PyObject *v) +{ + PyObject *result; /* result list */ + PyObject *rv; /* return value from PyList_Extend */ + + if (v == NULL) { + return null_error(); + } + + result = PyList_New(0); + if (result == NULL) + return NULL; + + rv = _PyList_Extend((PyListObject *)result, v); + if (rv == NULL) { + Py_DECREF(result); + return NULL; + } + Py_DECREF(rv); + return result; +} + +PyObject * +PySequence_Fast(PyObject *v, const char *m) +{ + PyObject *it; + + if (v == NULL) { + return null_error(); + } + + if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) { + Py_INCREF(v); + return v; + } + + it = PyObject_GetIter(v); + if (it == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_SetString(PyExc_TypeError, m); + return NULL; + } + + v = PySequence_List(it); + Py_DECREF(it); + + return v; +} + +/* Iterate over seq. Result depends on the operation: + PY_ITERSEARCH_COUNT: -1 if error, else # of times obj appears in seq. + PY_ITERSEARCH_INDEX: 0-based index of first occurrence of obj in seq; + set ValueError and return -1 if none found; also return -1 on error. + Py_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on error. +*/ +Py_ssize_t +_PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation) +{ + Py_ssize_t n; + int wrapped; /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */ + PyObject *it; /* iter(seq) */ + + if (seq == NULL || obj == NULL) { + null_error(); + return -1; + } + + it = PyObject_GetIter(seq); + if (it == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + type_error("argument of type '%.200s' is not iterable", seq); + } + return -1; + } + + n = wrapped = 0; + for (;;) { + int cmp; + PyObject *item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) + goto Fail; + break; + } + + cmp = PyObject_RichCompareBool(obj, item, Py_EQ); + Py_DECREF(item); + if (cmp < 0) + goto Fail; + if (cmp > 0) { + switch (operation) { + case PY_ITERSEARCH_COUNT: + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "count exceeds C integer size"); + goto Fail; + } + ++n; + break; + + case PY_ITERSEARCH_INDEX: + if (wrapped) { + PyErr_SetString(PyExc_OverflowError, + "index exceeds C integer size"); + goto Fail; + } + goto Done; + + case PY_ITERSEARCH_CONTAINS: + n = 1; + goto Done; + + default: + Py_UNREACHABLE(); + } + } + + if (operation == PY_ITERSEARCH_INDEX) { + if (n == PY_SSIZE_T_MAX) + wrapped = 1; + ++n; + } + } + + if (operation != PY_ITERSEARCH_INDEX) + goto Done; + + PyErr_SetString(PyExc_ValueError, + "sequence.index(x): x not in sequence"); + /* fall into failure code */ +Fail: + n = -1; + /* fall through */ +Done: + Py_DECREF(it); + return n; + +} + +/* Return # of times o appears in s. */ +Py_ssize_t +PySequence_Count(PyObject *s, PyObject *o) +{ + return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT); +} + +/* Return -1 if error; 1 if ob in seq; 0 if ob not in seq. + * Use sq_contains if possible, else defer to _PySequence_IterSearch(). + */ +int +PySequence_Contains(PyObject *seq, PyObject *ob) +{ + Py_ssize_t result; + PySequenceMethods *sqm = seq->ob_type->tp_as_sequence; + if (sqm != NULL && sqm->sq_contains != NULL) + return (*sqm->sq_contains)(seq, ob); + result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); + return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); +} + +/* Backwards compatibility */ +#undef PySequence_In +int +PySequence_In(PyObject *w, PyObject *v) +{ + return PySequence_Contains(w, v); +} + +Py_ssize_t +PySequence_Index(PyObject *s, PyObject *o) +{ + return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX); +} + +/* Operations on mappings */ + +int +PyMapping_Check(PyObject *o) +{ + return o && o->ob_type->tp_as_mapping && + o->ob_type->tp_as_mapping->mp_subscript; +} + +Py_ssize_t +PyMapping_Size(PyObject *o) +{ + PyMappingMethods *m; + + if (o == NULL) { + null_error(); + return -1; + } + + m = o->ob_type->tp_as_mapping; + if (m && m->mp_length) { + Py_ssize_t len = m->mp_length(o); + assert(len >= 0 || PyErr_Occurred()); + return len; + } + + if (o->ob_type->tp_as_sequence && o->ob_type->tp_as_sequence->sq_length) { + type_error("%.200s is not a mapping", o); + return -1; + } + /* PyMapping_Size() can be called from PyObject_Size(). */ + type_error("object of type '%.200s' has no len()", o); + return -1; +} + +#undef PyMapping_Length +Py_ssize_t +PyMapping_Length(PyObject *o) +{ + return PyMapping_Size(o); +} +#define PyMapping_Length PyMapping_Size + +PyObject * +PyMapping_GetItemString(PyObject *o, const char *key) +{ + PyObject *okey, *r; + + if (key == NULL) { + return null_error(); + } + + okey = PyUnicode_FromString(key); + if (okey == NULL) + return NULL; + r = PyObject_GetItem(o, okey); + Py_DECREF(okey); + return r; +} + +int +PyMapping_SetItemString(PyObject *o, const char *key, PyObject *value) +{ + PyObject *okey; + int r; + + if (key == NULL) { + null_error(); + return -1; + } + + okey = PyUnicode_FromString(key); + if (okey == NULL) + return -1; + r = PyObject_SetItem(o, okey, value); + Py_DECREF(okey); + return r; +} + +int +PyMapping_HasKeyString(PyObject *o, const char *key) +{ + PyObject *v; + + v = PyMapping_GetItemString(o, key); + if (v) { + Py_DECREF(v); + return 1; + } + PyErr_Clear(); + return 0; +} + +int +PyMapping_HasKey(PyObject *o, PyObject *key) +{ + PyObject *v; + + v = PyObject_GetItem(o, key); + if (v) { + Py_DECREF(v); + return 1; + } + PyErr_Clear(); + return 0; +} + +/* This function is quite similar to PySequence_Fast(), but specialized to be + a helper for PyMapping_Keys(), PyMapping_Items() and PyMapping_Values(). + */ +static PyObject * +method_output_as_list(PyObject *o, _Py_Identifier *meth_id) +{ + PyObject *it, *result, *meth_output; + + assert(o != NULL); + meth_output = _PyObject_CallMethodId(o, meth_id, NULL); + if (meth_output == NULL || PyList_CheckExact(meth_output)) { + return meth_output; + } + it = PyObject_GetIter(meth_output); + if (it == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%U() returned a non-iterable (type %.200s)", + Py_TYPE(o)->tp_name, + meth_id->object, + Py_TYPE(meth_output)->tp_name); + } + Py_DECREF(meth_output); + return NULL; + } + Py_DECREF(meth_output); + result = PySequence_List(it); + Py_DECREF(it); + return result; +} + +PyObject * +PyMapping_Keys(PyObject *o) +{ + _Py_IDENTIFIER(keys); + + if (o == NULL) { + return null_error(); + } + if (PyDict_CheckExact(o)) { + return PyDict_Keys(o); + } + return method_output_as_list(o, &PyId_keys); +} + +PyObject * +PyMapping_Items(PyObject *o) +{ + _Py_IDENTIFIER(items); + + if (o == NULL) { + return null_error(); + } + if (PyDict_CheckExact(o)) { + return PyDict_Items(o); + } + return method_output_as_list(o, &PyId_items); +} + +PyObject * +PyMapping_Values(PyObject *o) +{ + _Py_IDENTIFIER(values); + + if (o == NULL) { + return null_error(); + } + if (PyDict_CheckExact(o)) { + return PyDict_Values(o); + } + return method_output_as_list(o, &PyId_values); +} + +/* isinstance(), issubclass() */ + +/* abstract_get_bases() has logically 4 return states: + * + * 1. getattr(cls, '__bases__') could raise an AttributeError + * 2. getattr(cls, '__bases__') could raise some other exception + * 3. getattr(cls, '__bases__') could return a tuple + * 4. getattr(cls, '__bases__') could return something other than a tuple + * + * Only state #3 is a non-error state and only it returns a non-NULL object + * (it returns the retrieved tuple). + * + * Any raised AttributeErrors are masked by clearing the exception and + * returning NULL. If an object other than a tuple comes out of __bases__, + * then again, the return value is NULL. So yes, these two situations + * produce exactly the same results: NULL is returned and no error is set. + * + * If some exception other than AttributeError is raised, then NULL is also + * returned, but the exception is not cleared. That's because we want the + * exception to be propagated along. + * + * Callers are expected to test for PyErr_Occurred() when the return value + * is NULL to decide whether a valid exception should be propagated or not. + * When there's no exception to propagate, it's customary for the caller to + * set a TypeError. + */ +static PyObject * +abstract_get_bases(PyObject *cls) +{ + _Py_IDENTIFIER(__bases__); + PyObject *bases; + + (void)_PyObject_LookupAttrId(cls, &PyId___bases__, &bases); + if (bases != NULL && !PyTuple_Check(bases)) { + Py_DECREF(bases); + return NULL; + } + return bases; +} + + +static int +abstract_issubclass(PyObject *derived, PyObject *cls) +{ + PyObject *bases = NULL; + Py_ssize_t i, n; + int r = 0; + + while (1) { + if (derived == cls) { + Py_XDECREF(bases); /* See below comment */ + return 1; + } + /* Use XSETREF to drop bases reference *after* finishing with + derived; bases might be the only reference to it. + XSETREF is used instead of SETREF, because bases is NULL on the + first iteration of the loop. + */ + Py_XSETREF(bases, abstract_get_bases(derived)); + if (bases == NULL) { + if (PyErr_Occurred()) + return -1; + return 0; + } + n = PyTuple_GET_SIZE(bases); + if (n == 0) { + Py_DECREF(bases); + return 0; + } + /* Avoid recursivity in the single inheritance case */ + if (n == 1) { + derived = PyTuple_GET_ITEM(bases, 0); + continue; + } + for (i = 0; i < n; i++) { + r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls); + if (r != 0) + break; + } + Py_DECREF(bases); + return r; + } +} + +static int +check_class(PyObject *cls, const char *error) +{ + PyObject *bases = abstract_get_bases(cls); + if (bases == NULL) { + /* Do not mask errors. */ + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, error); + return 0; + } + Py_DECREF(bases); + return -1; +} + +static int +recursive_isinstance(PyObject *inst, PyObject *cls) +{ + PyObject *icls; + int retval; + _Py_IDENTIFIER(__class__); + + if (PyType_Check(cls)) { + retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); + if (retval == 0) { + retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls); + if (icls != NULL) { + if (icls != (PyObject *)(inst->ob_type) && PyType_Check(icls)) { + retval = PyType_IsSubtype( + (PyTypeObject *)icls, + (PyTypeObject *)cls); + } + else { + retval = 0; + } + Py_DECREF(icls); + } + } + } + else { + if (!check_class(cls, + "isinstance() arg 2 must be a type or tuple of types")) + return -1; + retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls); + if (icls != NULL) { + retval = abstract_issubclass(icls, cls); + Py_DECREF(icls); + } + } + + return retval; +} + +int +PyObject_IsInstance(PyObject *inst, PyObject *cls) +{ + _Py_IDENTIFIER(__instancecheck__); + PyObject *checker; + + /* Quick test for an exact match */ + if (Py_TYPE(inst) == (PyTypeObject *)cls) + return 1; + + /* We know what type's __instancecheck__ does. */ + if (PyType_CheckExact(cls)) { + return recursive_isinstance(inst, cls); + } + + if (PyTuple_Check(cls)) { + Py_ssize_t i; + Py_ssize_t n; + int r = 0; + + if (Py_EnterRecursiveCall(" in __instancecheck__")) + return -1; + n = PyTuple_GET_SIZE(cls); + for (i = 0; i < n; ++i) { + PyObject *item = PyTuple_GET_ITEM(cls, i); + r = PyObject_IsInstance(inst, item); + if (r != 0) + /* either found it, or got an error */ + break; + } + Py_LeaveRecursiveCall(); + return r; + } + + checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__); + if (checker != NULL) { + PyObject *res; + int ok = -1; + if (Py_EnterRecursiveCall(" in __instancecheck__")) { + Py_DECREF(checker); + return ok; + } + res = PyObject_CallFunctionObjArgs(checker, inst, NULL); + Py_LeaveRecursiveCall(); + Py_DECREF(checker); + if (res != NULL) { + ok = PyObject_IsTrue(res); + Py_DECREF(res); + } + return ok; + } + else if (PyErr_Occurred()) + return -1; + /* Probably never reached anymore. */ + return recursive_isinstance(inst, cls); +} + +static int +recursive_issubclass(PyObject *derived, PyObject *cls) +{ + if (PyType_Check(cls) && PyType_Check(derived)) { + /* Fast path (non-recursive) */ + return PyType_IsSubtype((PyTypeObject *)derived, (PyTypeObject *)cls); + } + if (!check_class(derived, + "issubclass() arg 1 must be a class")) + return -1; + if (!check_class(cls, + "issubclass() arg 2 must be a class" + " or tuple of classes")) + return -1; + + return abstract_issubclass(derived, cls); +} + +int +PyObject_IsSubclass(PyObject *derived, PyObject *cls) +{ + _Py_IDENTIFIER(__subclasscheck__); + PyObject *checker; + + /* We know what type's __subclasscheck__ does. */ + if (PyType_CheckExact(cls)) { + /* Quick test for an exact match */ + if (derived == cls) + return 1; + return recursive_issubclass(derived, cls); + } + + if (PyTuple_Check(cls)) { + Py_ssize_t i; + Py_ssize_t n; + int r = 0; + + if (Py_EnterRecursiveCall(" in __subclasscheck__")) + return -1; + n = PyTuple_GET_SIZE(cls); + for (i = 0; i < n; ++i) { + PyObject *item = PyTuple_GET_ITEM(cls, i); + r = PyObject_IsSubclass(derived, item); + if (r != 0) + /* either found it, or got an error */ + break; + } + Py_LeaveRecursiveCall(); + return r; + } + + checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__); + if (checker != NULL) { + PyObject *res; + int ok = -1; + if (Py_EnterRecursiveCall(" in __subclasscheck__")) { + Py_DECREF(checker); + return ok; + } + res = PyObject_CallFunctionObjArgs(checker, derived, NULL); + Py_LeaveRecursiveCall(); + Py_DECREF(checker); + if (res != NULL) { + ok = PyObject_IsTrue(res); + Py_DECREF(res); + } + return ok; + } + else if (PyErr_Occurred()) + return -1; + /* Probably never reached anymore. */ + return recursive_issubclass(derived, cls); +} + +int +_PyObject_RealIsInstance(PyObject *inst, PyObject *cls) +{ + return recursive_isinstance(inst, cls); +} + +int +_PyObject_RealIsSubclass(PyObject *derived, PyObject *cls) +{ + return recursive_issubclass(derived, cls); +} + + +PyObject * +PyObject_GetIter(PyObject *o) +{ + PyTypeObject *t = o->ob_type; + getiterfunc f; + + f = t->tp_iter; + if (f == NULL) { + if (PySequence_Check(o)) + return PySeqIter_New(o); + return type_error("'%.200s' object is not iterable", o); + } + else { + PyObject *res = (*f)(o); + if (res != NULL && !PyIter_Check(res)) { + PyErr_Format(PyExc_TypeError, + "iter() returned non-iterator " + "of type '%.100s'", + res->ob_type->tp_name); + Py_DECREF(res); + res = NULL; + } + return res; + } +} + +#undef PyIter_Check + +int PyIter_Check(PyObject *obj) +{ + return obj->ob_type->tp_iternext != NULL && + obj->ob_type->tp_iternext != &_PyObject_NextNotImplemented; +} + +/* Return next item. + * If an error occurs, return NULL. PyErr_Occurred() will be true. + * If the iteration terminates normally, return NULL and clear the + * PyExc_StopIteration exception (if it was set). PyErr_Occurred() + * will be false. + * Else return the next object. PyErr_Occurred() will be false. + */ +PyObject * +PyIter_Next(PyObject *iter) +{ + PyObject *result; + result = (*iter->ob_type->tp_iternext)(iter); + if (result == NULL && + PyErr_Occurred() && + PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + return result; +} + + +/* + * Flatten a sequence of bytes() objects into a C array of + * NULL terminated string pointers with a NULL char* terminating the array. + * (ie: an argv or env list) + * + * Memory allocated for the returned list is allocated using PyMem_Malloc() + * and MUST be freed by _Py_FreeCharPArray(). + */ +char *const * +_PySequence_BytesToCharpArray(PyObject* self) +{ + char **array; + Py_ssize_t i, argc; + PyObject *item = NULL; + Py_ssize_t size; + + argc = PySequence_Size(self); + if (argc == -1) + return NULL; + + assert(argc >= 0); + + if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) { + PyErr_NoMemory(); + return NULL; + } + + array = PyMem_Malloc((argc + 1) * sizeof(char *)); + if (array == NULL) { + PyErr_NoMemory(); + return NULL; + } + for (i = 0; i < argc; ++i) { + char *data; + item = PySequence_GetItem(self, i); + if (item == NULL) { + /* NULL terminate before freeing. */ + array[i] = NULL; + goto fail; + } + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(item, &data, NULL) < 0) { + /* NULL terminate before freeing. */ + array[i] = NULL; + goto fail; + } + size = PyBytes_GET_SIZE(item) + 1; + array[i] = PyMem_Malloc(size); + if (!array[i]) { + PyErr_NoMemory(); + goto fail; + } + memcpy(array[i], data, size); + Py_DECREF(item); + } + array[argc] = NULL; + + return array; + +fail: + Py_XDECREF(item); + _Py_FreeCharPArray(array); + return NULL; +} + + +/* Free's a NULL terminated char** array of C strings. */ +void +_Py_FreeCharPArray(char *const array[]) +{ + Py_ssize_t i; + for (i = 0; array[i] != NULL; ++i) { + PyMem_Free(array[i]); + } + PyMem_Free((void*)array); +} diff --git a/python/Objects/accu.c b/python/Objects/accu.c new file mode 100755 index 0000000..c8b5d38 --- /dev/null +++ b/python/Objects/accu.c @@ -0,0 +1,115 @@ +/* Accumulator struct implementation */ + +#include "Python.h" +#include "pycore_accu.h" + +static PyObject * +join_list_unicode(PyObject *lst) +{ + /* return ''.join(lst) */ + PyObject *sep, *ret; + sep = PyUnicode_FromStringAndSize("", 0); + ret = PyUnicode_Join(sep, lst); + Py_DECREF(sep); + return ret; +} + +int +_PyAccu_Init(_PyAccu *acc) +{ + /* Lazily allocated */ + acc->large = NULL; + acc->small = PyList_New(0); + if (acc->small == NULL) + return -1; + return 0; +} + +static int +flush_accumulator(_PyAccu *acc) +{ + Py_ssize_t nsmall = PyList_GET_SIZE(acc->small); + if (nsmall) { + int ret; + PyObject *joined; + if (acc->large == NULL) { + acc->large = PyList_New(0); + if (acc->large == NULL) + return -1; + } + joined = join_list_unicode(acc->small); + if (joined == NULL) + return -1; + if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) { + Py_DECREF(joined); + return -1; + } + ret = PyList_Append(acc->large, joined); + Py_DECREF(joined); + return ret; + } + return 0; +} + +int +_PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode) +{ + Py_ssize_t nsmall; + assert(PyUnicode_Check(unicode)); + + if (PyList_Append(acc->small, unicode)) + return -1; + nsmall = PyList_GET_SIZE(acc->small); + /* Each item in a list of unicode objects has an overhead (in 64-bit + * builds) of: + * - 8 bytes for the list slot + * - 56 bytes for the header of the unicode object + * that is, 64 bytes. 100000 such objects waste more than 6 MiB + * compared to a single concatenated string. + */ + if (nsmall < 100000) + return 0; + return flush_accumulator(acc); +} + +PyObject * +_PyAccu_FinishAsList(_PyAccu *acc) +{ + int ret; + PyObject *res; + + ret = flush_accumulator(acc); + Py_CLEAR(acc->small); + if (ret) { + Py_CLEAR(acc->large); + return NULL; + } + res = acc->large; + acc->large = NULL; + return res; +} + +PyObject * +_PyAccu_Finish(_PyAccu *acc) +{ + PyObject *list, *res; + if (acc->large == NULL) { + list = acc->small; + acc->small = NULL; + } + else { + list = _PyAccu_FinishAsList(acc); + if (!list) + return NULL; + } + res = join_list_unicode(list); + Py_DECREF(list); + return res; +} + +void +_PyAccu_Destroy(_PyAccu *acc) +{ + Py_CLEAR(acc->small); + Py_CLEAR(acc->large); +} diff --git a/python/Objects/boolobject.c b/python/Objects/boolobject.c new file mode 100755 index 0000000..720835b --- /dev/null +++ b/python/Objects/boolobject.c @@ -0,0 +1,185 @@ +/* Boolean type, a subtype of int */ + +#include "Python.h" +#include "longintrepr.h" + +/* We define bool_repr to return "False" or "True" */ + +static PyObject *false_str = NULL; +static PyObject *true_str = NULL; + +static PyObject * +bool_repr(PyObject *self) +{ + PyObject *s; + + if (self == Py_True) + s = true_str ? true_str : + (true_str = PyUnicode_InternFromString("True")); + else + s = false_str ? false_str : + (false_str = PyUnicode_InternFromString("False")); + Py_XINCREF(s); + return s; +} + +/* Function to return a bool from a C long */ + +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result; + + if (ok) + result = Py_True; + else + result = Py_False; + Py_INCREF(result); + return result; +} + +/* We define bool_new to always return either Py_True or Py_False */ + +static PyObject * +bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *x = Py_False; + long ok; + + if (!_PyArg_NoKeywords("bool", kwds)) + return NULL; + if (!PyArg_UnpackTuple(args, "bool", 0, 1, &x)) + return NULL; + ok = PyObject_IsTrue(x); + if (ok < 0) + return NULL; + return PyBool_FromLong(ok); +} + +/* Arithmetic operations redefined to return bool if both args are bool. */ + +static PyObject * +bool_and(PyObject *a, PyObject *b) +{ + if (!PyBool_Check(a) || !PyBool_Check(b)) + return PyLong_Type.tp_as_number->nb_and(a, b); + return PyBool_FromLong((a == Py_True) & (b == Py_True)); +} + +static PyObject * +bool_or(PyObject *a, PyObject *b) +{ + if (!PyBool_Check(a) || !PyBool_Check(b)) + return PyLong_Type.tp_as_number->nb_or(a, b); + return PyBool_FromLong((a == Py_True) | (b == Py_True)); +} + +static PyObject * +bool_xor(PyObject *a, PyObject *b) +{ + if (!PyBool_Check(a) || !PyBool_Check(b)) + return PyLong_Type.tp_as_number->nb_xor(a, b); + return PyBool_FromLong((a == Py_True) ^ (b == Py_True)); +} + +/* Doc string */ + +PyDoc_STRVAR(bool_doc, +"bool(x) -> bool\n\ +\n\ +Returns True when the argument x is true, False otherwise.\n\ +The builtins True and False are the only two instances of the class bool.\n\ +The class bool is a subclass of the class int, and cannot be subclassed."); + +/* Arithmetic methods -- only so we can override &, |, ^. */ + +static PyNumberMethods bool_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + bool_and, /* nb_and */ + bool_xor, /* nb_xor */ + bool_or, /* nb_or */ + 0, /* nb_int */ + 0, /* nb_reserved */ + 0, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; + +/* The type object for bool. Note that this cannot be subclassed! */ + +PyTypeObject PyBool_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bool", + sizeof(struct _longobject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + bool_repr, /* tp_repr */ + &bool_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 */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + bool_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyLong_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + bool_new, /* tp_new */ +}; + +/* The objects representing bool values False and True */ + +struct _longobject _Py_FalseStruct = { + PyVarObject_HEAD_INIT(&PyBool_Type, 0) + { 0 } +}; + +struct _longobject _Py_TrueStruct = { + PyVarObject_HEAD_INIT(&PyBool_Type, 1) + { 1 } +}; diff --git a/python/Objects/bytearrayobject.c b/python/Objects/bytearrayobject.c new file mode 100755 index 0000000..9812afd --- /dev/null +++ b/python/Objects/bytearrayobject.c @@ -0,0 +1,2467 @@ +/* PyByteArray (bytearray) implementation */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "structmember.h" +#include "bytes_methods.h" +#include "bytesobject.h" +#include "pystrhex.h" + +/*[clinic input] +class bytearray "PyByteArrayObject *" "&PyByteArray_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/ + +char _PyByteArray_empty_string[] = ""; + +/* end nullbytes support */ + +/* Helpers */ + +static int +_getbytevalue(PyObject* arg, int *value) +{ + long face_value; + + if (PyLong_Check(arg)) { + face_value = PyLong_AsLong(arg); + } else { + PyObject *index = PyNumber_Index(arg); + if (index == NULL) { + *value = -1; + return 0; + } + face_value = PyLong_AsLong(index); + Py_DECREF(index); + } + + if (face_value < 0 || face_value >= 256) { + /* this includes the OverflowError in case the long is too large */ + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + *value = -1; + return 0; + } + + *value = face_value; + return 1; +} + +static int +bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) +{ + void *ptr; + if (view == NULL) { + PyErr_SetString(PyExc_BufferError, + "bytearray_getbuffer: view==NULL argument is obsolete"); + return -1; + } + ptr = (void *) PyByteArray_AS_STRING(obj); + /* cannot fail if view != NULL and readonly == 0 */ + (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); + obj->ob_exports++; + return 0; +} + +static void +bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) +{ + obj->ob_exports--; +} + +static int +_canresize(PyByteArrayObject *self) +{ + if (self->ob_exports > 0) { + PyErr_SetString(PyExc_BufferError, + "Existing exports of data: object cannot be re-sized"); + return 0; + } + return 1; +} + +#include "clinic/bytearrayobject.c.h" + +/* Direct API functions */ + +PyObject * +PyByteArray_FromObject(PyObject *input) +{ + return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type, + input, NULL); +} + +static PyObject * +_PyByteArray_FromBufferObject(PyObject *obj) +{ + PyObject *result; + Py_buffer view; + + if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) { + return NULL; + } + result = PyByteArray_FromStringAndSize(NULL, view.len); + if (result != NULL && + PyBuffer_ToContiguous(PyByteArray_AS_STRING(result), + &view, view.len, 'C') < 0) + { + Py_CLEAR(result); + } + PyBuffer_Release(&view); + return result; +} + +PyObject * +PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) +{ + PyByteArrayObject *new; + Py_ssize_t alloc; + + if (size < 0) { + PyErr_SetString(PyExc_SystemError, + "Negative size passed to PyByteArray_FromStringAndSize"); + return NULL; + } + + /* Prevent buffer overflow when setting alloc to size+1. */ + if (size == PY_SSIZE_T_MAX) { + return PyErr_NoMemory(); + } + + new = PyObject_New(PyByteArrayObject, &PyByteArray_Type); + if (new == NULL) + return NULL; + + if (size == 0) { + new->ob_bytes = NULL; + alloc = 0; + } + else { + alloc = size + 1; + new->ob_bytes = PyObject_Malloc(alloc); + if (new->ob_bytes == NULL) { + Py_DECREF(new); + return PyErr_NoMemory(); + } + if (bytes != NULL && size > 0) + memcpy(new->ob_bytes, bytes, size); + new->ob_bytes[size] = '\0'; /* Trailing null byte */ + } + Py_SIZE(new) = size; + new->ob_alloc = alloc; + new->ob_start = new->ob_bytes; + new->ob_exports = 0; + + return (PyObject *)new; +} + +Py_ssize_t +PyByteArray_Size(PyObject *self) +{ + assert(self != NULL); + assert(PyByteArray_Check(self)); + + return PyByteArray_GET_SIZE(self); +} + +char * +PyByteArray_AsString(PyObject *self) +{ + assert(self != NULL); + assert(PyByteArray_Check(self)); + + return PyByteArray_AS_STRING(self); +} + +int +PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) +{ + void *sval; + PyByteArrayObject *obj = ((PyByteArrayObject *)self); + /* All computations are done unsigned to avoid integer overflows + (see issue #22335). */ + size_t alloc = (size_t) obj->ob_alloc; + size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes); + size_t size = (size_t) requested_size; + + assert(self != NULL); + assert(PyByteArray_Check(self)); + assert(logical_offset <= alloc); + assert(requested_size >= 0); + + if (requested_size == Py_SIZE(self)) { + return 0; + } + if (!_canresize(obj)) { + return -1; + } + + if (size + logical_offset + 1 <= alloc) { + /* Current buffer is large enough to host the requested size, + decide on a strategy. */ + if (size < alloc / 2) { + /* Major downsize; resize down to exact size */ + alloc = size + 1; + } + else { + /* Minor downsize; quick exit */ + Py_SIZE(self) = size; + PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */ + return 0; + } + } + else { + /* Need growing, decide on a strategy */ + 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_SSIZE_T_MAX) { + PyErr_NoMemory(); + return -1; + } + + if (logical_offset > 0) { + sval = PyObject_Malloc(alloc); + if (sval == NULL) { + PyErr_NoMemory(); + return -1; + } + memcpy(sval, PyByteArray_AS_STRING(self), + Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self))); + PyObject_Free(obj->ob_bytes); + } + else { + sval = PyObject_Realloc(obj->ob_bytes, alloc); + if (sval == NULL) { + PyErr_NoMemory(); + return -1; + } + } + + obj->ob_bytes = obj->ob_start = sval; + Py_SIZE(self) = size; + obj->ob_alloc = alloc; + obj->ob_bytes[size] = '\0'; /* Trailing null byte */ + + return 0; +} + +PyObject * +PyByteArray_Concat(PyObject *a, PyObject *b) +{ + Py_buffer va, vb; + PyByteArrayObject *result = NULL; + + va.len = -1; + vb.len = -1; + if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 || + PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", + Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name); + goto done; + } + + if (va.len > PY_SSIZE_T_MAX - vb.len) { + PyErr_NoMemory(); + goto done; + } + + result = (PyByteArrayObject *) \ + PyByteArray_FromStringAndSize(NULL, va.len + vb.len); + // result->ob_bytes is NULL if result is an empty string: + // if va.len + vb.len equals zero. + if (result != NULL && result->ob_bytes != NULL) { + memcpy(result->ob_bytes, va.buf, va.len); + memcpy(result->ob_bytes + va.len, vb.buf, vb.len); + } + + done: + if (va.len != -1) + PyBuffer_Release(&va); + if (vb.len != -1) + PyBuffer_Release(&vb); + return (PyObject *)result; +} + +/* Functions stuffed into the type object */ + +static Py_ssize_t +bytearray_length(PyByteArrayObject *self) +{ + return Py_SIZE(self); +} + +static PyObject * +bytearray_iconcat(PyByteArrayObject *self, PyObject *other) +{ + Py_ssize_t size; + Py_buffer vo; + + if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", + Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name); + return NULL; + } + + size = Py_SIZE(self); + if (size > PY_SSIZE_T_MAX - vo.len) { + PyBuffer_Release(&vo); + return PyErr_NoMemory(); + } + if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) { + PyBuffer_Release(&vo); + return NULL; + } + memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len); + PyBuffer_Release(&vo); + Py_INCREF(self); + return (PyObject *)self; +} + +static PyObject * +bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) +{ + PyByteArrayObject *result; + Py_ssize_t mysize; + Py_ssize_t size; + const char *buf; + + if (count < 0) + count = 0; + mysize = Py_SIZE(self); + if (count > 0 && mysize > PY_SSIZE_T_MAX / count) + return PyErr_NoMemory(); + size = mysize * count; + result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); + buf = PyByteArray_AS_STRING(self); + if (result != NULL && size != 0) { + if (mysize == 1) + memset(result->ob_bytes, buf[0], size); + else { + Py_ssize_t i; + for (i = 0; i < count; i++) + memcpy(result->ob_bytes + i*mysize, buf, mysize); + } + } + return (PyObject *)result; +} + +static PyObject * +bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) +{ + Py_ssize_t mysize; + Py_ssize_t size; + char *buf; + + if (count < 0) + count = 0; + mysize = Py_SIZE(self); + if (count > 0 && mysize > PY_SSIZE_T_MAX / count) + return PyErr_NoMemory(); + size = mysize * count; + if (PyByteArray_Resize((PyObject *)self, size) < 0) + return NULL; + + buf = PyByteArray_AS_STRING(self); + if (mysize == 1) + memset(buf, buf[0], size); + else { + Py_ssize_t i; + for (i = 1; i < count; i++) + memcpy(buf + i*mysize, buf, mysize); + } + + Py_INCREF(self); + return (PyObject *)self; +} + +static PyObject * +bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) +{ + if (i < 0) + i += Py_SIZE(self); + if (i < 0 || i >= Py_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); + return NULL; + } + return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i])); +} + +static PyObject * +bytearray_subscript(PyByteArrayObject *self, PyObject *index) +{ + if (PyIndex_Check(index)) { + Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); + + if (i == -1 && PyErr_Occurred()) + return NULL; + + if (i < 0) + i += PyByteArray_GET_SIZE(self); + + if (i < 0 || i >= Py_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); + return NULL; + } + return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i])); + } + else if (PySlice_Check(index)) { + Py_ssize_t start, stop, step, slicelength, i; + size_t cur; + if (PySlice_Unpack(index, &start, &stop, &step) < 0) { + return NULL; + } + slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), + &start, &stop, step); + + if (slicelength <= 0) + return PyByteArray_FromStringAndSize("", 0); + else if (step == 1) { + return PyByteArray_FromStringAndSize( + PyByteArray_AS_STRING(self) + start, slicelength); + } + else { + char *source_buf = PyByteArray_AS_STRING(self); + char *result_buf; + PyObject *result; + + result = PyByteArray_FromStringAndSize(NULL, slicelength); + if (result == NULL) + return NULL; + + result_buf = PyByteArray_AS_STRING(result); + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + result_buf[i] = source_buf[cur]; + } + return result; + } + } + else { + PyErr_Format(PyExc_TypeError, + "bytearray indices must be integers or slices, not %.200s", + Py_TYPE(index)->tp_name); + return NULL; + } +} + +static int +bytearray_setslice_linear(PyByteArrayObject *self, + Py_ssize_t lo, Py_ssize_t hi, + char *bytes, Py_ssize_t bytes_len) +{ + Py_ssize_t avail = hi - lo; + char *buf = PyByteArray_AS_STRING(self); + Py_ssize_t growth = bytes_len - avail; + int res = 0; + assert(avail >= 0); + + if (growth < 0) { + if (!_canresize(self)) + return -1; + + if (lo == 0) { + /* Shrink the buffer by advancing its logical start */ + self->ob_start -= growth; + /* + 0 lo hi old_size + | |<----avail----->|<-----tail------>| + | |<-bytes_len->|<-----tail------>| + 0 new_lo new_hi new_size + */ + } + else { + /* + 0 lo hi old_size + | |<----avail----->|<-----tomove------>| + | |<-bytes_len->|<-----tomove------>| + 0 lo new_hi new_size + */ + memmove(buf + lo + bytes_len, buf + hi, + Py_SIZE(self) - hi); + } + if (PyByteArray_Resize((PyObject *)self, + Py_SIZE(self) + growth) < 0) { + /* Issue #19578: Handling the memory allocation failure here is + tricky here because the bytearray object has already been + modified. Depending on growth and lo, the behaviour is + different. + + If growth < 0 and lo != 0, the operation is completed, but a + MemoryError is still raised and the memory block is not + shrunk. Otherwise, the bytearray is restored in its previous + state and a MemoryError is raised. */ + if (lo == 0) { + self->ob_start += growth; + return -1; + } + /* memmove() removed bytes, the bytearray object cannot be + restored in its previous state. */ + Py_SIZE(self) += growth; + res = -1; + } + buf = PyByteArray_AS_STRING(self); + } + else if (growth > 0) { + if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) { + PyErr_NoMemory(); + return -1; + } + + if (PyByteArray_Resize((PyObject *)self, + Py_SIZE(self) + growth) < 0) { + return -1; + } + buf = PyByteArray_AS_STRING(self); + /* Make the place for the additional bytes */ + /* + 0 lo hi old_size + | |<-avail->|<-----tomove------>| + | |<---bytes_len-->|<-----tomove------>| + 0 lo new_hi new_size + */ + memmove(buf + lo + bytes_len, buf + hi, + Py_SIZE(self) - lo - bytes_len); + } + + if (bytes_len > 0) + memcpy(buf + lo, bytes, bytes_len); + return res; +} + +static int +bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, + PyObject *values) +{ + Py_ssize_t needed; + void *bytes; + Py_buffer vbytes; + int res = 0; + + vbytes.len = -1; + if (values == (PyObject *)self) { + /* Make a copy and call this function recursively */ + int err; + values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values), + PyByteArray_GET_SIZE(values)); + if (values == NULL) + return -1; + err = bytearray_setslice(self, lo, hi, values); + Py_DECREF(values); + return err; + } + if (values == NULL) { + /* del b[lo:hi] */ + bytes = NULL; + needed = 0; + } + else { + if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, + "can't set bytearray slice from %.100s", + Py_TYPE(values)->tp_name); + return -1; + } + needed = vbytes.len; + bytes = vbytes.buf; + } + + if (lo < 0) + lo = 0; + if (hi < lo) + hi = lo; + if (hi > Py_SIZE(self)) + hi = Py_SIZE(self); + + res = bytearray_setslice_linear(self, lo, hi, bytes, needed); + if (vbytes.len != -1) + PyBuffer_Release(&vbytes); + return res; +} + +static int +bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) +{ + int ival; + + if (i < 0) + i += Py_SIZE(self); + + if (i < 0 || i >= Py_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); + return -1; + } + + if (value == NULL) + return bytearray_setslice(self, i, i+1, NULL); + + if (!_getbytevalue(value, &ival)) + return -1; + + PyByteArray_AS_STRING(self)[i] = ival; + return 0; +} + +static int +bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values) +{ + Py_ssize_t start, stop, step, slicelen, needed; + char *buf, *bytes; + buf = PyByteArray_AS_STRING(self); + + if (PyIndex_Check(index)) { + Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); + + if (i == -1 && PyErr_Occurred()) + return -1; + + if (i < 0) + i += PyByteArray_GET_SIZE(self); + + if (i < 0 || i >= Py_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); + return -1; + } + + if (values == NULL) { + /* Fall through to slice assignment */ + start = i; + stop = i + 1; + step = 1; + slicelen = 1; + } + else { + int ival; + if (!_getbytevalue(values, &ival)) + return -1; + buf[i] = (char)ival; + return 0; + } + } + else if (PySlice_Check(index)) { + if (PySlice_Unpack(index, &start, &stop, &step) < 0) { + return -1; + } + slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start, + &stop, step); + } + else { + PyErr_Format(PyExc_TypeError, + "bytearray indices must be integers or slices, not %.200s", + Py_TYPE(index)->tp_name); + return -1; + } + + if (values == NULL) { + bytes = NULL; + needed = 0; + } + else if (values == (PyObject *)self || !PyByteArray_Check(values)) { + int err; + if (PyNumber_Check(values) || PyUnicode_Check(values)) { + PyErr_SetString(PyExc_TypeError, + "can assign only bytes, buffers, or iterables " + "of ints in range(0, 256)"); + return -1; + } + /* Make a copy and call this function recursively */ + values = PyByteArray_FromObject(values); + if (values == NULL) + return -1; + err = bytearray_ass_subscript(self, index, values); + Py_DECREF(values); + return err; + } + else { + assert(PyByteArray_Check(values)); + bytes = PyByteArray_AS_STRING(values); + needed = Py_SIZE(values); + } + /* Make sure b[5:2] = ... inserts before 5, not before 2. */ + if ((step < 0 && start < stop) || + (step > 0 && start > stop)) + stop = start; + if (step == 1) { + return bytearray_setslice_linear(self, start, stop, bytes, needed); + } + else { + if (needed == 0) { + /* Delete slice */ + size_t cur; + Py_ssize_t i; + + if (!_canresize(self)) + return -1; + + if (slicelen == 0) + /* Nothing to do here. */ + return 0; + + if (step < 0) { + stop = start + 1; + start = stop + step * (slicelen - 1) - 1; + step = -step; + } + for (cur = start, i = 0; + i < slicelen; cur += step, i++) { + Py_ssize_t lim = step - 1; + + if (cur + step >= (size_t)PyByteArray_GET_SIZE(self)) + lim = PyByteArray_GET_SIZE(self) - cur - 1; + + memmove(buf + cur - i, + buf + cur + 1, lim); + } + /* Move the tail of the bytes, in one chunk */ + cur = start + (size_t)slicelen*step; + if (cur < (size_t)PyByteArray_GET_SIZE(self)) { + memmove(buf + cur - slicelen, + buf + cur, + PyByteArray_GET_SIZE(self) - cur); + } + if (PyByteArray_Resize((PyObject *)self, + PyByteArray_GET_SIZE(self) - slicelen) < 0) + return -1; + + return 0; + } + else { + /* Assign slice */ + Py_ssize_t i; + size_t cur; + + if (needed != slicelen) { + PyErr_Format(PyExc_ValueError, + "attempt to assign bytes of size %zd " + "to extended slice of size %zd", + needed, slicelen); + return -1; + } + for (cur = start, i = 0; i < slicelen; cur += step, i++) + buf[cur] = bytes[i]; + return 0; + } + } +} + +static int +bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"source", "encoding", "errors", 0}; + PyObject *arg = NULL; + const char *encoding = NULL; + const char *errors = NULL; + Py_ssize_t count; + PyObject *it; + PyObject *(*iternext)(PyObject *); + + if (Py_SIZE(self) != 0) { + /* Empty previous contents (yes, do this first of all!) */ + if (PyByteArray_Resize((PyObject *)self, 0) < 0) + return -1; + } + + /* Parse arguments */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist, + &arg, &encoding, &errors)) + return -1; + + /* Make a quick exit if no first argument */ + if (arg == NULL) { + if (encoding != NULL || errors != NULL) { + PyErr_SetString(PyExc_TypeError, + encoding != NULL ? + "encoding without a string argument" : + "errors without a string argument"); + return -1; + } + return 0; + } + + if (PyUnicode_Check(arg)) { + /* Encode via the codec registry */ + PyObject *encoded, *new; + if (encoding == NULL) { + PyErr_SetString(PyExc_TypeError, + "string argument without an encoding"); + return -1; + } + encoded = PyUnicode_AsEncodedString(arg, encoding, errors); + if (encoded == NULL) + return -1; + assert(PyBytes_Check(encoded)); + new = bytearray_iconcat(self, encoded); + Py_DECREF(encoded); + if (new == NULL) + return -1; + Py_DECREF(new); + return 0; + } + + /* If it's not unicode, there can't be encoding or errors */ + if (encoding != NULL || errors != NULL) { + PyErr_SetString(PyExc_TypeError, + encoding != NULL ? + "encoding without a string argument" : + "errors without a string argument"); + return -1; + } + + /* Is it an int? */ + if (PyIndex_Check(arg)) { + count = PyNumber_AsSsize_t(arg, PyExc_OverflowError); + if (count == -1 && PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return -1; + PyErr_Clear(); /* fall through */ + } + else { + if (count < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return -1; + } + if (count > 0) { + if (PyByteArray_Resize((PyObject *)self, count)) + return -1; + memset(PyByteArray_AS_STRING(self), 0, count); + } + return 0; + } + } + + /* Use the buffer API */ + if (PyObject_CheckBuffer(arg)) { + Py_ssize_t size; + Py_buffer view; + if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0) + return -1; + size = view.len; + if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail; + if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self), + &view, size, 'C') < 0) + goto fail; + PyBuffer_Release(&view); + return 0; + fail: + PyBuffer_Release(&view); + return -1; + } + + /* XXX Optimize this if the arguments is a list, tuple */ + + /* Get the iterator */ + it = PyObject_GetIter(arg); + if (it == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Format(PyExc_TypeError, + "cannot convert '%.200s' object to bytearray", + arg->ob_type->tp_name); + } + return -1; + } + iternext = *Py_TYPE(it)->tp_iternext; + + /* Run the iterator to exhaustion */ + for (;;) { + PyObject *item; + int rc, value; + + /* Get the next item */ + item = iternext(it); + if (item == NULL) { + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) + goto error; + PyErr_Clear(); + } + break; + } + + /* Interpret it as an int (__index__) */ + rc = _getbytevalue(item, &value); + Py_DECREF(item); + if (!rc) + goto error; + + /* Append the byte */ + if (Py_SIZE(self) + 1 < self->ob_alloc) { + Py_SIZE(self)++; + PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; + } + else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0) + goto error; + PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value; + } + + /* Clean up and return success */ + Py_DECREF(it); + return 0; + + error: + /* Error handling when it != NULL */ + Py_DECREF(it); + return -1; +} + +/* Mostly copied from string_repr, but without the + "smart quote" functionality. */ +static PyObject * +bytearray_repr(PyByteArrayObject *self) +{ + const char *className = _PyType_Name(Py_TYPE(self)); + const char *quote_prefix = "(b"; + const char *quote_postfix = ")"; + Py_ssize_t length = Py_SIZE(self); + /* 6 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */ + Py_ssize_t newsize; + PyObject *v; + Py_ssize_t i; + char *bytes; + char c; + char *p; + int quote; + char *test, *start; + char *buffer; + + newsize = strlen(className); + if (length > (PY_SSIZE_T_MAX - 6 - newsize) / 4) { + PyErr_SetString(PyExc_OverflowError, + "bytearray object is too large to make repr"); + return NULL; + } + + newsize += 6 + length * 4; + buffer = PyObject_Malloc(newsize); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + + /* Figure out which quote to use; single is preferred */ + quote = '\''; + start = PyByteArray_AS_STRING(self); + for (test = start; test < start+length; ++test) { + if (*test == '"') { + quote = '\''; /* back to single */ + break; + } + else if (*test == '\'') + quote = '"'; + } + + p = buffer; + while (*className) + *p++ = *className++; + while (*quote_prefix) + *p++ = *quote_prefix++; + *p++ = quote; + + bytes = PyByteArray_AS_STRING(self); + for (i = 0; i < length; i++) { + /* There's at least enough room for a hex escape + and a closing quote. */ + assert(newsize - (p - buffer) >= 5); + c = bytes[i]; + if (c == '\'' || c == '\\') + *p++ = '\\', *p++ = c; + else if (c == '\t') + *p++ = '\\', *p++ = 't'; + else if (c == '\n') + *p++ = '\\', *p++ = 'n'; + else if (c == '\r') + *p++ = '\\', *p++ = 'r'; + else if (c == 0) + *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0'; + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = Py_hexdigits[(c & 0xf0) >> 4]; + *p++ = Py_hexdigits[c & 0xf]; + } + else + *p++ = c; + } + assert(newsize - (p - buffer) >= 1); + *p++ = quote; + while (*quote_postfix) { + *p++ = *quote_postfix++; + } + + v = PyUnicode_FromStringAndSize(buffer, p - buffer); + PyObject_Free(buffer); + return v; +} + +static PyObject * +bytearray_str(PyObject *op) +{ + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + if (config->bytes_warning) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "str() on a bytearray instance", 1)) { + return NULL; + } + } + return bytearray_repr((PyByteArrayObject*)op); +} + +static PyObject * +bytearray_richcompare(PyObject *self, PyObject *other, int op) +{ + Py_ssize_t self_size, other_size; + Py_buffer self_bytes, other_bytes; + int cmp, rc; + + /* Bytes can be compared to anything that supports the (binary) + buffer API. Except that a comparison with Unicode is always an + error, even if the comparison is for equality. */ + rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); + if (!rc) + rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type); + if (rc < 0) + return NULL; + if (rc) { + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + if (config->bytes_warning && (op == Py_EQ || op == Py_NE)) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytearray and string", 1)) + return NULL; + } + + Py_RETURN_NOTIMPLEMENTED; + } + + if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) { + PyErr_Clear(); + Py_RETURN_NOTIMPLEMENTED; + } + self_size = self_bytes.len; + + if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) { + PyErr_Clear(); + PyBuffer_Release(&self_bytes); + Py_RETURN_NOTIMPLEMENTED; + } + other_size = other_bytes.len; + + if (self_size != other_size && (op == Py_EQ || op == Py_NE)) { + /* Shortcut: if the lengths differ, the objects differ */ + PyBuffer_Release(&self_bytes); + PyBuffer_Release(&other_bytes); + return PyBool_FromLong((op == Py_NE)); + } + else { + cmp = memcmp(self_bytes.buf, other_bytes.buf, + Py_MIN(self_size, other_size)); + /* In ISO C, memcmp() guarantees to use unsigned bytes! */ + + PyBuffer_Release(&self_bytes); + PyBuffer_Release(&other_bytes); + + if (cmp != 0) { + Py_RETURN_RICHCOMPARE(cmp, 0, op); + } + + Py_RETURN_RICHCOMPARE(self_size, other_size, op); + } + +} + +static void +bytearray_dealloc(PyByteArrayObject *self) +{ + if (self->ob_exports > 0) { + PyErr_SetString(PyExc_SystemError, + "deallocated bytearray object has exported buffers"); + PyErr_Print(); + } + if (self->ob_bytes != 0) { + PyObject_Free(self->ob_bytes); + } + Py_TYPE(self)->tp_free((PyObject *)self); +} + + +/* -------------------------------------------------------------------- */ +/* Methods */ + +#define FASTSEARCH fastsearch +#define STRINGLIB(F) stringlib_##F +#define STRINGLIB_CHAR char +#define STRINGLIB_SIZEOF_CHAR 1 +#define STRINGLIB_LEN PyByteArray_GET_SIZE +#define STRINGLIB_STR PyByteArray_AS_STRING +#define STRINGLIB_NEW PyByteArray_FromStringAndSize +#define STRINGLIB_ISSPACE Py_ISSPACE +#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) +#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact +#define STRINGLIB_MUTABLE 1 + +#include "stringlib/fastsearch.h" +#include "stringlib/count.h" +#include "stringlib/find.h" +#include "stringlib/join.h" +#include "stringlib/partition.h" +#include "stringlib/split.h" +#include "stringlib/ctype.h" +#include "stringlib/transmogrify.h" + + +static PyObject * +bytearray_find(PyByteArrayObject *self, PyObject *args) +{ + return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args); +} + +static PyObject * +bytearray_count(PyByteArrayObject *self, PyObject *args) +{ + return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args); +} + +/*[clinic input] +bytearray.clear + +Remove all items from the bytearray. +[clinic start generated code]*/ + +static PyObject * +bytearray_clear_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/ +{ + if (PyByteArray_Resize((PyObject *)self, 0) < 0) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +bytearray.copy + +Return a copy of B. +[clinic start generated code]*/ + +static PyObject * +bytearray_copy_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/ +{ + return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self), + PyByteArray_GET_SIZE(self)); +} + +static PyObject * +bytearray_index(PyByteArrayObject *self, PyObject *args) +{ + return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args); +} + +static PyObject * +bytearray_rfind(PyByteArrayObject *self, PyObject *args) +{ + return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args); +} + +static PyObject * +bytearray_rindex(PyByteArrayObject *self, PyObject *args) +{ + return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args); +} + +static int +bytearray_contains(PyObject *self, PyObject *arg) +{ + return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg); +} + +static PyObject * +bytearray_startswith(PyByteArrayObject *self, PyObject *args) +{ + return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args); +} + +static PyObject * +bytearray_endswith(PyByteArrayObject *self, PyObject *args) +{ + return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args); +} + + +/*[clinic input] +bytearray.translate + + table: object + Translation table, which must be a bytes object of length 256. + / + delete as deletechars: object(c_default="NULL") = b'' + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument delete are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ + +static PyObject * +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, + PyObject *deletechars) +/*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/ +{ + char *input, *output; + const char *table_chars; + Py_ssize_t i, c; + PyObject *input_obj = (PyObject*)self; + const char *output_start; + Py_ssize_t inlen; + PyObject *result = NULL; + int trans_table[256]; + Py_buffer vtable, vdel; + + if (table == Py_None) { + table_chars = NULL; + table = NULL; + } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) { + return NULL; + } else { + if (vtable.len != 256) { + PyErr_SetString(PyExc_ValueError, + "translation table must be 256 characters long"); + PyBuffer_Release(&vtable); + return NULL; + } + table_chars = (const char*)vtable.buf; + } + + if (deletechars != NULL) { + if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) { + if (table != NULL) + PyBuffer_Release(&vtable); + return NULL; + } + } + else { + vdel.buf = NULL; + vdel.len = 0; + } + + inlen = PyByteArray_GET_SIZE(input_obj); + result = PyByteArray_FromStringAndSize((char *)NULL, inlen); + if (result == NULL) + goto done; + output_start = output = PyByteArray_AS_STRING(result); + input = PyByteArray_AS_STRING(input_obj); + + if (vdel.len == 0 && table_chars != NULL) { + /* If no deletions are required, use faster code */ + for (i = inlen; --i >= 0; ) { + c = Py_CHARMASK(*input++); + *output++ = table_chars[c]; + } + goto done; + } + + if (table_chars == NULL) { + for (i = 0; i < 256; i++) + trans_table[i] = Py_CHARMASK(i); + } else { + for (i = 0; i < 256; i++) + trans_table[i] = Py_CHARMASK(table_chars[i]); + } + + for (i = 0; i < vdel.len; i++) + trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1; + + for (i = inlen; --i >= 0; ) { + c = Py_CHARMASK(*input++); + if (trans_table[c] != -1) + *output++ = (char)trans_table[c]; + } + /* Fix the size of the resulting string */ + if (inlen > 0) + if (PyByteArray_Resize(result, output - output_start) < 0) { + Py_CLEAR(result); + goto done; + } + +done: + if (table != NULL) + PyBuffer_Release(&vtable); + if (deletechars != NULL) + PyBuffer_Release(&vdel); + return result; +} + + +/*[clinic input] + +@staticmethod +bytearray.maketrans + + frm: Py_buffer + to: Py_buffer + / + +Return a translation table useable for the bytes or bytearray translate method. + +The returned table will be one where each byte in frm is mapped to the byte at +the same position in to. + +The bytes objects frm and to must be of the same length. +[clinic start generated code]*/ + +static PyObject * +bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to) +/*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/ +{ + return _Py_bytes_maketrans(frm, to); +} + + +/*[clinic input] +bytearray.replace + + old: Py_buffer + new: Py_buffer + count: Py_ssize_t = -1 + Maximum number of occurrences to replace. + -1 (the default value) means replace all occurrences. + / + +Return a copy with all occurrences of substring old replaced by new. + +If the optional argument count is given, only the first count occurrences are +replaced. +[clinic start generated code]*/ + +static PyObject * +bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, + Py_buffer *new, Py_ssize_t count) +/*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/ +{ + return stringlib_replace((PyObject *)self, + (const char *)old->buf, old->len, + (const char *)new->buf, new->len, count); +} + +/*[clinic input] +bytearray.split + + sep: object = None + The delimiter according which to split the bytearray. + None (the default value) means split on ASCII whitespace characters + (space, tab, return, newline, formfeed, vertical tab). + maxsplit: Py_ssize_t = -1 + Maximum number of splits to do. + -1 (the default value) means no limit. + +Return a list of the sections in the bytearray, using sep as the delimiter. +[clinic start generated code]*/ + +static PyObject * +bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, + Py_ssize_t maxsplit) +/*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/ +{ + Py_ssize_t len = PyByteArray_GET_SIZE(self), n; + const char *s = PyByteArray_AS_STRING(self), *sub; + PyObject *list; + Py_buffer vsub; + + if (maxsplit < 0) + maxsplit = PY_SSIZE_T_MAX; + + if (sep == Py_None) + return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); + + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) + return NULL; + sub = vsub.buf; + n = vsub.len; + + list = stringlib_split( + (PyObject*) self, s, len, sub, n, maxsplit + ); + PyBuffer_Release(&vsub); + return list; +} + +/*[clinic input] +bytearray.partition + + sep: object + / + +Partition the bytearray into three parts using the given separator. + +This will search for the separator sep in the bytearray. If the separator is +found, returns a 3-tuple containing the part before the separator, the +separator itself, and the part after it as new bytearray objects. + +If the separator is not found, returns a 3-tuple containing the copy of the +original bytearray object and two empty bytearray objects. +[clinic start generated code]*/ + +static PyObject * +bytearray_partition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/ +{ + PyObject *bytesep, *result; + + bytesep = _PyByteArray_FromBufferObject(sep); + if (! bytesep) + return NULL; + + result = stringlib_partition( + (PyObject*) self, + PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), + bytesep, + PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) + ); + + Py_DECREF(bytesep); + return result; +} + +/*[clinic input] +bytearray.rpartition + + sep: object + / + +Partition the bytearray into three parts using the given separator. + +This will search for the separator sep in the bytearray, starting at the end. +If the separator is found, returns a 3-tuple containing the part before the +separator, the separator itself, and the part after it as new bytearray +objects. + +If the separator is not found, returns a 3-tuple containing two empty bytearray +objects and the copy of the original bytearray object. +[clinic start generated code]*/ + +static PyObject * +bytearray_rpartition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/ +{ + PyObject *bytesep, *result; + + bytesep = _PyByteArray_FromBufferObject(sep); + if (! bytesep) + return NULL; + + result = stringlib_rpartition( + (PyObject*) self, + PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), + bytesep, + PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep) + ); + + Py_DECREF(bytesep); + return result; +} + +/*[clinic input] +bytearray.rsplit = bytearray.split + +Return a list of the sections in the bytearray, using sep as the delimiter. + +Splitting is done starting at the end of the bytearray and working to the front. +[clinic start generated code]*/ + +static PyObject * +bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, + Py_ssize_t maxsplit) +/*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/ +{ + Py_ssize_t len = PyByteArray_GET_SIZE(self), n; + const char *s = PyByteArray_AS_STRING(self), *sub; + PyObject *list; + Py_buffer vsub; + + if (maxsplit < 0) + maxsplit = PY_SSIZE_T_MAX; + + if (sep == Py_None) + return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); + + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) + return NULL; + sub = vsub.buf; + n = vsub.len; + + list = stringlib_rsplit( + (PyObject*) self, s, len, sub, n, maxsplit + ); + PyBuffer_Release(&vsub); + return list; +} + +/*[clinic input] +bytearray.reverse + +Reverse the order of the values in B in place. +[clinic start generated code]*/ + +static PyObject * +bytearray_reverse_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/ +{ + char swap, *head, *tail; + Py_ssize_t i, j, n = Py_SIZE(self); + + j = n / 2; + head = PyByteArray_AS_STRING(self); + tail = head + n - 1; + for (i = 0; i < j; i++) { + swap = *head; + *head++ = *tail; + *tail-- = swap; + } + + Py_RETURN_NONE; +} + + +/*[python input] +class bytesvalue_converter(CConverter): + type = 'int' + converter = '_getbytevalue' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/ + + +/*[clinic input] +bytearray.insert + + index: Py_ssize_t + The index where the value is to be inserted. + item: bytesvalue + The item to be inserted. + / + +Insert a single item into the bytearray before the given index. +[clinic start generated code]*/ + +static PyObject * +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item) +/*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/ +{ + Py_ssize_t n = Py_SIZE(self); + char *buf; + + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot add more objects to bytearray"); + return NULL; + } + if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) + return NULL; + buf = PyByteArray_AS_STRING(self); + + if (index < 0) { + index += n; + if (index < 0) + index = 0; + } + if (index > n) + index = n; + memmove(buf + index + 1, buf + index, n - index); + buf[index] = item; + + Py_RETURN_NONE; +} + +/*[clinic input] +bytearray.append + + item: bytesvalue + The item to be appended. + / + +Append a single item to the end of the bytearray. +[clinic start generated code]*/ + +static PyObject * +bytearray_append_impl(PyByteArrayObject *self, int item) +/*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/ +{ + Py_ssize_t n = Py_SIZE(self); + + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot add more objects to bytearray"); + return NULL; + } + if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) + return NULL; + + PyByteArray_AS_STRING(self)[n] = item; + + Py_RETURN_NONE; +} + +/*[clinic input] +bytearray.extend + + iterable_of_ints: object + The iterable of items to append. + / + +Append all the items from the iterator or sequence to the end of the bytearray. +[clinic start generated code]*/ + +static PyObject * +bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) +/*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/ +{ + PyObject *it, *item, *bytearray_obj; + Py_ssize_t buf_size = 0, len = 0; + int value; + char *buf; + + /* bytearray_setslice code only accepts something supporting PEP 3118. */ + if (PyObject_CheckBuffer(iterable_of_ints)) { + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1) + return NULL; + + Py_RETURN_NONE; + } + + it = PyObject_GetIter(iterable_of_ints); + if (it == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Format(PyExc_TypeError, + "can't extend bytearray with %.100s", + iterable_of_ints->ob_type->tp_name); + } + return NULL; + } + + /* Try to determine the length of the argument. 32 is arbitrary. */ + buf_size = PyObject_LengthHint(iterable_of_ints, 32); + if (buf_size == -1) { + Py_DECREF(it); + return NULL; + } + + bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size); + if (bytearray_obj == NULL) { + Py_DECREF(it); + return NULL; + } + buf = PyByteArray_AS_STRING(bytearray_obj); + + while ((item = PyIter_Next(it)) != NULL) { + if (! _getbytevalue(item, &value)) { + Py_DECREF(item); + Py_DECREF(it); + Py_DECREF(bytearray_obj); + return NULL; + } + buf[len++] = value; + Py_DECREF(item); + + if (len >= buf_size) { + Py_ssize_t addition; + if (len == PY_SSIZE_T_MAX) { + Py_DECREF(it); + Py_DECREF(bytearray_obj); + return PyErr_NoMemory(); + } + addition = len >> 1; + if (addition > PY_SSIZE_T_MAX - len - 1) + buf_size = PY_SSIZE_T_MAX; + else + buf_size = len + addition + 1; + if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) { + Py_DECREF(it); + Py_DECREF(bytearray_obj); + return NULL; + } + /* Recompute the `buf' pointer, since the resizing operation may + have invalidated it. */ + buf = PyByteArray_AS_STRING(bytearray_obj); + } + } + Py_DECREF(it); + + /* Resize down to exact size. */ + if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) { + Py_DECREF(bytearray_obj); + return NULL; + } + + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) { + Py_DECREF(bytearray_obj); + return NULL; + } + Py_DECREF(bytearray_obj); + + if (PyErr_Occurred()) { + return NULL; + } + + Py_RETURN_NONE; +} + +/*[clinic input] +bytearray.pop + + index: Py_ssize_t = -1 + The index from where to remove the item. + -1 (the default value) means remove the last item. + / + +Remove and return a single item from B. + +If no index argument is given, will pop the last item. +[clinic start generated code]*/ + +static PyObject * +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index) +/*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/ +{ + int value; + Py_ssize_t n = Py_SIZE(self); + char *buf; + + if (n == 0) { + PyErr_SetString(PyExc_IndexError, + "pop from empty bytearray"); + return NULL; + } + if (index < 0) + index += Py_SIZE(self); + if (index < 0 || index >= Py_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, "pop index out of range"); + return NULL; + } + if (!_canresize(self)) + return NULL; + + buf = PyByteArray_AS_STRING(self); + value = buf[index]; + memmove(buf + index, buf + index + 1, n - index); + if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) + return NULL; + + return PyLong_FromLong((unsigned char)value); +} + +/*[clinic input] +bytearray.remove + + value: bytesvalue + The value to remove. + / + +Remove the first occurrence of a value in the bytearray. +[clinic start generated code]*/ + +static PyObject * +bytearray_remove_impl(PyByteArrayObject *self, int value) +/*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/ +{ + Py_ssize_t where, n = Py_SIZE(self); + char *buf = PyByteArray_AS_STRING(self); + + where = stringlib_find_char(buf, n, value); + if (where < 0) { + PyErr_SetString(PyExc_ValueError, "value not found in bytearray"); + return NULL; + } + if (!_canresize(self)) + return NULL; + + memmove(buf + where, buf + where + 1, n - where); + if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) + return NULL; + + Py_RETURN_NONE; +} + +/* XXX These two helpers could be optimized if argsize == 1 */ + +static Py_ssize_t +lstrip_helper(const char *myptr, Py_ssize_t mysize, + const void *argptr, Py_ssize_t argsize) +{ + Py_ssize_t i = 0; + while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize)) + i++; + return i; +} + +static Py_ssize_t +rstrip_helper(const char *myptr, Py_ssize_t mysize, + const void *argptr, Py_ssize_t argsize) +{ + Py_ssize_t i = mysize - 1; + while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize)) + i--; + return i + 1; +} + +/*[clinic input] +bytearray.strip + + bytes: object = None + / + +Strip leading and trailing bytes contained in the argument. + +If the argument is omitted or None, strip leading and trailing ASCII whitespace. +[clinic start generated code]*/ + +static PyObject * +bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/ +{ + Py_ssize_t left, right, mysize, byteslen; + char *myptr; + const char *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; + } + else { + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) + return NULL; + bytesptr = (const char *) vbytes.buf; + byteslen = vbytes.len; + } + myptr = PyByteArray_AS_STRING(self); + mysize = Py_SIZE(self); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); + if (left == mysize) + right = left; + else + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); + return PyByteArray_FromStringAndSize(myptr + left, right - left); +} + +/*[clinic input] +bytearray.lstrip + + bytes: object = None + / + +Strip leading bytes contained in the argument. + +If the argument is omitted or None, strip leading ASCII whitespace. +[clinic start generated code]*/ + +static PyObject * +bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/ +{ + Py_ssize_t left, right, mysize, byteslen; + char *myptr; + const char *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; + } + else { + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) + return NULL; + bytesptr = (const char *) vbytes.buf; + byteslen = vbytes.len; + } + myptr = PyByteArray_AS_STRING(self); + mysize = Py_SIZE(self); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); + right = mysize; + if (bytes != Py_None) + PyBuffer_Release(&vbytes); + return PyByteArray_FromStringAndSize(myptr + left, right - left); +} + +/*[clinic input] +bytearray.rstrip + + bytes: object = None + / + +Strip trailing bytes contained in the argument. + +If the argument is omitted or None, strip trailing ASCII whitespace. +[clinic start generated code]*/ + +static PyObject * +bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/ +{ + Py_ssize_t right, mysize, byteslen; + char *myptr; + const char *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; + } + else { + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) + return NULL; + bytesptr = (const char *) vbytes.buf; + byteslen = vbytes.len; + } + myptr = PyByteArray_AS_STRING(self); + mysize = Py_SIZE(self); + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); + return PyByteArray_FromStringAndSize(myptr, right); +} + +/*[clinic input] +bytearray.decode + + encoding: str(c_default="NULL") = 'utf-8' + The encoding with which to decode the bytearray. + errors: str(c_default="NULL") = 'strict' + The error handling scheme to use for the handling of decoding errors. + The default is 'strict' meaning that decoding errors raise a + UnicodeDecodeError. Other possible values are 'ignore' and 'replace' + as well as any other name registered with codecs.register_error that + can handle UnicodeDecodeErrors. + +Decode the bytearray using the codec registered for encoding. +[clinic start generated code]*/ + +static PyObject * +bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, + const char *errors) +/*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/ +{ + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors); +} + +PyDoc_STRVAR(alloc_doc, +"B.__alloc__() -> int\n\ +\n\ +Return the number of bytes actually allocated."); + +static PyObject * +bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return PyLong_FromSsize_t(self->ob_alloc); +} + +/*[clinic input] +bytearray.join + + iterable_of_bytes: object + / + +Concatenate any number of bytes/bytearray objects. + +The bytearray whose method is called is inserted in between each pair. + +The result is returned as a new bytearray object. +[clinic start generated code]*/ + +static PyObject * +bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) +/*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/ +{ + return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); +} + +/*[clinic input] +bytearray.splitlines + + keepends: bool(accept={int}) = False + +Return a list of the lines in the bytearray, breaking at line boundaries. + +Line breaks are not included in the resulting list unless keepends is given and +true. +[clinic start generated code]*/ + +static PyObject * +bytearray_splitlines_impl(PyByteArrayObject *self, int keepends) +/*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/ +{ + return stringlib_splitlines( + (PyObject*) self, PyByteArray_AS_STRING(self), + PyByteArray_GET_SIZE(self), keepends + ); +} + +/*[clinic input] +@classmethod +bytearray.fromhex + + string: unicode + / + +Create a bytearray object from a string of hexadecimal numbers. + +Spaces between two numbers are accepted. +Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef') +[clinic start generated code]*/ + +static PyObject * +bytearray_fromhex_impl(PyTypeObject *type, PyObject *string) +/*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/ +{ + PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type); + if (type != &PyByteArray_Type && result != NULL) { + Py_SETREF(result, PyObject_CallFunctionObjArgs((PyObject *)type, + result, NULL)); + } + return result; +} + +/*[clinic input] +bytearray.hex + + 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. + +Create a str of hexadecimal numbers from a bytearray object. + +Example: +>>> value = bytearray([0xb9, 0x01, 0xef]) +>>> value.hex() +'b901ef' +>>> value.hex(':') +'b9:01:ef' +>>> value.hex(':', 2) +'b9:01ef' +>>> value.hex(':', -2) +'b901:ef' +[clinic start generated code]*/ + +static PyObject * +bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep) +/*[clinic end generated code: output=29c4e5ef72c565a0 input=814c15830ac8c4b5]*/ +{ + char* argbuf = PyByteArray_AS_STRING(self); + Py_ssize_t arglen = PyByteArray_GET_SIZE(self); + return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep); +} + +static PyObject * +_common_reduce(PyByteArrayObject *self, int proto) +{ + PyObject *dict; + _Py_IDENTIFIER(__dict__); + char *buf; + + if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) { + return NULL; + } + if (dict == NULL) { + dict = Py_None; + Py_INCREF(dict); + } + + buf = PyByteArray_AS_STRING(self); + if (proto < 3) { + /* use str based reduction for backwards compatibility with Python 2.x */ + PyObject *latin1; + if (Py_SIZE(self)) + latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL); + else + latin1 = PyUnicode_FromString(""); + return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict); + } + else { + /* use more efficient byte based reduction */ + if (Py_SIZE(self)) { + return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict); + } + else { + return Py_BuildValue("(O()N)", Py_TYPE(self), dict); + } + } +} + +/*[clinic input] +bytearray.__reduce__ as bytearray_reduce + +Return state information for pickling. +[clinic start generated code]*/ + +static PyObject * +bytearray_reduce_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/ +{ + return _common_reduce(self, 2); +} + +/*[clinic input] +bytearray.__reduce_ex__ as bytearray_reduce_ex + + proto: int = 0 + / + +Return state information for pickling. +[clinic start generated code]*/ + +static PyObject * +bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto) +/*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/ +{ + return _common_reduce(self, proto); +} + +/*[clinic input] +bytearray.__sizeof__ as bytearray_sizeof + +Returns the size of the bytearray object in memory, in bytes. +[clinic start generated code]*/ + +static PyObject * +bytearray_sizeof_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/ +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char); + return PyLong_FromSsize_t(res); +} + +static PySequenceMethods bytearray_as_sequence = { + (lenfunc)bytearray_length, /* sq_length */ + (binaryfunc)PyByteArray_Concat, /* sq_concat */ + (ssizeargfunc)bytearray_repeat, /* sq_repeat */ + (ssizeargfunc)bytearray_getitem, /* sq_item */ + 0, /* sq_slice */ + (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)bytearray_contains, /* sq_contains */ + (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */ + (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */ +}; + +static PyMappingMethods bytearray_as_mapping = { + (lenfunc)bytearray_length, + (binaryfunc)bytearray_subscript, + (objobjargproc)bytearray_ass_subscript, +}; + +static PyBufferProcs bytearray_as_buffer = { + (getbufferproc)bytearray_getbuffer, + (releasebufferproc)bytearray_releasebuffer, +}; + +static PyMethodDef +bytearray_methods[] = { + {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, + BYTEARRAY_REDUCE_METHODDEF + BYTEARRAY_REDUCE_EX_METHODDEF + BYTEARRAY_SIZEOF_METHODDEF + BYTEARRAY_APPEND_METHODDEF + {"capitalize", stringlib_capitalize, METH_NOARGS, + _Py_capitalize__doc__}, + STRINGLIB_CENTER_METHODDEF + BYTEARRAY_CLEAR_METHODDEF + BYTEARRAY_COPY_METHODDEF + {"count", (PyCFunction)bytearray_count, METH_VARARGS, + _Py_count__doc__}, + BYTEARRAY_DECODE_METHODDEF + {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, + _Py_endswith__doc__}, + STRINGLIB_EXPANDTABS_METHODDEF + BYTEARRAY_EXTEND_METHODDEF + {"find", (PyCFunction)bytearray_find, METH_VARARGS, + _Py_find__doc__}, + BYTEARRAY_FROMHEX_METHODDEF + BYTEARRAY_HEX_METHODDEF + {"index", (PyCFunction)bytearray_index, METH_VARARGS, _Py_index__doc__}, + BYTEARRAY_INSERT_METHODDEF + {"isalnum", stringlib_isalnum, METH_NOARGS, + _Py_isalnum__doc__}, + {"isalpha", stringlib_isalpha, METH_NOARGS, + _Py_isalpha__doc__}, + {"isascii", stringlib_isascii, METH_NOARGS, + _Py_isascii__doc__}, + {"isdigit", stringlib_isdigit, METH_NOARGS, + _Py_isdigit__doc__}, + {"islower", stringlib_islower, METH_NOARGS, + _Py_islower__doc__}, + {"isspace", stringlib_isspace, METH_NOARGS, + _Py_isspace__doc__}, + {"istitle", stringlib_istitle, METH_NOARGS, + _Py_istitle__doc__}, + {"isupper", stringlib_isupper, METH_NOARGS, + _Py_isupper__doc__}, + BYTEARRAY_JOIN_METHODDEF + STRINGLIB_LJUST_METHODDEF + {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__}, + BYTEARRAY_LSTRIP_METHODDEF + BYTEARRAY_MAKETRANS_METHODDEF + BYTEARRAY_PARTITION_METHODDEF + BYTEARRAY_POP_METHODDEF + BYTEARRAY_REMOVE_METHODDEF + BYTEARRAY_REPLACE_METHODDEF + BYTEARRAY_REVERSE_METHODDEF + {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, _Py_rfind__doc__}, + {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, _Py_rindex__doc__}, + STRINGLIB_RJUST_METHODDEF + BYTEARRAY_RPARTITION_METHODDEF + BYTEARRAY_RSPLIT_METHODDEF + BYTEARRAY_RSTRIP_METHODDEF + BYTEARRAY_SPLIT_METHODDEF + BYTEARRAY_SPLITLINES_METHODDEF + {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , + _Py_startswith__doc__}, + BYTEARRAY_STRIP_METHODDEF + {"swapcase", stringlib_swapcase, METH_NOARGS, + _Py_swapcase__doc__}, + {"title", stringlib_title, METH_NOARGS, _Py_title__doc__}, + BYTEARRAY_TRANSLATE_METHODDEF + {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__}, + STRINGLIB_ZFILL_METHODDEF + {NULL} +}; + +static PyObject * +bytearray_mod(PyObject *v, PyObject *w) +{ + if (!PyByteArray_Check(v)) + Py_RETURN_NOTIMPLEMENTED; + return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1); +} + +static PyNumberMethods bytearray_as_number = { + 0, /*nb_add*/ + 0, /*nb_subtract*/ + 0, /*nb_multiply*/ + bytearray_mod, /*nb_remainder*/ +}; + +PyDoc_STRVAR(bytearray_doc, +"bytearray(iterable_of_ints) -> bytearray\n\ +bytearray(string, encoding[, errors]) -> bytearray\n\ +bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\ +bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\ +bytearray() -> empty bytes array\n\ +\n\ +Construct a mutable bytearray object from:\n\ + - an iterable yielding integers in range(256)\n\ + - a text string encoded using the specified encoding\n\ + - a bytes or a buffer object\n\ + - any object implementing the buffer API.\n\ + - an integer"); + + +static PyObject *bytearray_iter(PyObject *seq); + +PyTypeObject PyByteArray_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bytearray", + sizeof(PyByteArrayObject), + 0, + (destructor)bytearray_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)bytearray_repr, /* tp_repr */ + &bytearray_as_number, /* tp_as_number */ + &bytearray_as_sequence, /* tp_as_sequence */ + &bytearray_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + bytearray_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &bytearray_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + bytearray_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)bytearray_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + bytearray_iter, /* tp_iter */ + 0, /* tp_iternext */ + bytearray_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)bytearray_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + +/*********************** Bytes Iterator ****************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */ +} bytesiterobject; + +static void +bytearrayiter_dealloc(bytesiterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +bytearrayiter_next(bytesiterobject *it) +{ + PyByteArrayObject *seq; + PyObject *item; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) + return NULL; + assert(PyByteArray_Check(seq)); + + if (it->it_index < PyByteArray_GET_SIZE(seq)) { + item = PyLong_FromLong( + (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]); + if (item != NULL) + ++it->it_index; + return item; + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len = 0; + if (it->it_seq) { + len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index; + if (len < 0) { + len = 0; + } + } + return PyLong_FromSsize_t(len); +} + +PyDoc_STRVAR(length_hint_doc, + "Private method returning an estimate of len(list(it))."); + +static PyObject * +bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + if (it->it_seq != NULL) { + return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + it->it_seq, it->it_index); + } else { + return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + } +} + +static PyObject * +bytearrayiter_setstate(bytesiterobject *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyByteArray_GET_SIZE(it->it_seq)) + index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */ + it->it_index = index; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef bytearrayiter_methods[] = { + {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS, + length_hint_doc}, + {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS, + bytearray_reduce__doc__}, + {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyByteArrayIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bytearray_iterator", /* tp_name */ + sizeof(bytesiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)bytearrayiter_dealloc, /* tp_dealloc */ + 0, /* tp_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, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)bytearrayiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)bytearrayiter_next, /* tp_iternext */ + bytearrayiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +bytearray_iter(PyObject *seq) +{ + bytesiterobject *it; + + if (!PyByteArray_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = (PyByteArrayObject *)seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} diff --git a/python/Objects/bytes_methods.c b/python/Objects/bytes_methods.c new file mode 100755 index 0000000..db030be --- /dev/null +++ b/python/Objects/bytes_methods.c @@ -0,0 +1,833 @@ +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "bytes_methods.h" + +PyDoc_STRVAR_shared(_Py_isspace__doc__, +"B.isspace() -> bool\n\ +\n\ +Return True if all characters in B are whitespace\n\ +and there is at least one character in B, False otherwise."); + +PyObject* +_Py_bytes_isspace(const char *cptr, Py_ssize_t len) +{ + const unsigned char *p + = (const unsigned char *) cptr; + const unsigned char *e; + + /* Shortcut for single character strings */ + if (len == 1 && Py_ISSPACE(*p)) + Py_RETURN_TRUE; + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + e = p + len; + for (; p < e; p++) { + if (!Py_ISSPACE(*p)) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + + +PyDoc_STRVAR_shared(_Py_isalpha__doc__, +"B.isalpha() -> bool\n\ +\n\ +Return True if all characters in B are alphabetic\n\ +and there is at least one character in B, False otherwise."); + +PyObject* +_Py_bytes_isalpha(const char *cptr, Py_ssize_t len) +{ + const unsigned char *p + = (const unsigned char *) cptr; + const unsigned char *e; + + /* Shortcut for single character strings */ + if (len == 1 && Py_ISALPHA(*p)) + Py_RETURN_TRUE; + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + e = p + len; + for (; p < e; p++) { + if (!Py_ISALPHA(*p)) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + + +PyDoc_STRVAR_shared(_Py_isalnum__doc__, +"B.isalnum() -> bool\n\ +\n\ +Return True if all characters in B are alphanumeric\n\ +and there is at least one character in B, False otherwise."); + +PyObject* +_Py_bytes_isalnum(const char *cptr, Py_ssize_t len) +{ + const unsigned char *p + = (const unsigned char *) cptr; + const unsigned char *e; + + /* Shortcut for single character strings */ + if (len == 1 && Py_ISALNUM(*p)) + Py_RETURN_TRUE; + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + e = p + len; + for (; p < e; p++) { + if (!Py_ISALNUM(*p)) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + + +PyDoc_STRVAR_shared(_Py_isascii__doc__, +"B.isascii() -> bool\n\ +\n\ +Return True if B is empty or all characters in B are ASCII,\n\ +False otherwise."); + +// Optimization is copied from ascii_decode in unicodeobject.c +/* Mask to quickly check whether a C 'long' contains a + non-ASCII, UTF8-encoded char. */ +#if (SIZEOF_LONG == 8) +# define ASCII_CHAR_MASK 0x8080808080808080UL +#elif (SIZEOF_LONG == 4) +# define ASCII_CHAR_MASK 0x80808080UL +#else +# error C 'long' size should be either 4 or 8! +#endif + +PyObject* +_Py_bytes_isascii(const char *cptr, Py_ssize_t len) +{ + const char *p = cptr; + const char *end = p + len; + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + + while (p < end) { + /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h + for an explanation. */ + if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + /* Help allocation */ + const char *_p = p; + while (_p < aligned_end) { + unsigned long value = *(const unsigned long *) _p; + if (value & ASCII_CHAR_MASK) { + Py_RETURN_FALSE; + } + _p += SIZEOF_LONG; + } + p = _p; + if (_p == end) + break; + } + if ((unsigned char)*p & 0x80) { + Py_RETURN_FALSE; + } + p++; + } + Py_RETURN_TRUE; +} + +#undef ASCII_CHAR_MASK + + +PyDoc_STRVAR_shared(_Py_isdigit__doc__, +"B.isdigit() -> bool\n\ +\n\ +Return True if all characters in B are digits\n\ +and there is at least one character in B, False otherwise."); + +PyObject* +_Py_bytes_isdigit(const char *cptr, Py_ssize_t len) +{ + const unsigned char *p + = (const unsigned char *) cptr; + const unsigned char *e; + + /* Shortcut for single character strings */ + if (len == 1 && Py_ISDIGIT(*p)) + Py_RETURN_TRUE; + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + e = p + len; + for (; p < e; p++) { + if (!Py_ISDIGIT(*p)) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + + +PyDoc_STRVAR_shared(_Py_islower__doc__, +"B.islower() -> bool\n\ +\n\ +Return True if all cased characters in B are lowercase and there is\n\ +at least one cased character in B, False otherwise."); + +PyObject* +_Py_bytes_islower(const char *cptr, Py_ssize_t len) +{ + const unsigned char *p + = (const unsigned char *) cptr; + const unsigned char *e; + int cased; + + /* Shortcut for single character strings */ + if (len == 1) + return PyBool_FromLong(Py_ISLOWER(*p)); + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + e = p + len; + cased = 0; + for (; p < e; p++) { + if (Py_ISUPPER(*p)) + Py_RETURN_FALSE; + else if (!cased && Py_ISLOWER(*p)) + cased = 1; + } + return PyBool_FromLong(cased); +} + + +PyDoc_STRVAR_shared(_Py_isupper__doc__, +"B.isupper() -> bool\n\ +\n\ +Return True if all cased characters in B are uppercase and there is\n\ +at least one cased character in B, False otherwise."); + +PyObject* +_Py_bytes_isupper(const char *cptr, Py_ssize_t len) +{ + const unsigned char *p + = (const unsigned char *) cptr; + const unsigned char *e; + int cased; + + /* Shortcut for single character strings */ + if (len == 1) + return PyBool_FromLong(Py_ISUPPER(*p)); + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + e = p + len; + cased = 0; + for (; p < e; p++) { + if (Py_ISLOWER(*p)) + Py_RETURN_FALSE; + else if (!cased && Py_ISUPPER(*p)) + cased = 1; + } + return PyBool_FromLong(cased); +} + + +PyDoc_STRVAR_shared(_Py_istitle__doc__, +"B.istitle() -> bool\n\ +\n\ +Return True if B is a titlecased string and there is at least one\n\ +character in B, i.e. uppercase characters may only follow uncased\n\ +characters and lowercase characters only cased ones. Return False\n\ +otherwise."); + +PyObject* +_Py_bytes_istitle(const char *cptr, Py_ssize_t len) +{ + const unsigned char *p + = (const unsigned char *) cptr; + const unsigned char *e; + int cased, previous_is_cased; + + /* Shortcut for single character strings */ + if (len == 1) + return PyBool_FromLong(Py_ISUPPER(*p)); + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + e = p + len; + cased = 0; + previous_is_cased = 0; + for (; p < e; p++) { + const unsigned char ch = *p; + + if (Py_ISUPPER(ch)) { + if (previous_is_cased) + Py_RETURN_FALSE; + previous_is_cased = 1; + cased = 1; + } + else if (Py_ISLOWER(ch)) { + if (!previous_is_cased) + Py_RETURN_FALSE; + previous_is_cased = 1; + cased = 1; + } + else + previous_is_cased = 0; + } + return PyBool_FromLong(cased); +} + + +PyDoc_STRVAR_shared(_Py_lower__doc__, +"B.lower() -> copy of B\n\ +\n\ +Return a copy of B with all ASCII characters converted to lowercase."); + +void +_Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len) +{ + Py_ssize_t i; + + for (i = 0; i < len; i++) { + result[i] = Py_TOLOWER((unsigned char) cptr[i]); + } +} + + +PyDoc_STRVAR_shared(_Py_upper__doc__, +"B.upper() -> copy of B\n\ +\n\ +Return a copy of B with all ASCII characters converted to uppercase."); + +void +_Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len) +{ + Py_ssize_t i; + + for (i = 0; i < len; i++) { + result[i] = Py_TOUPPER((unsigned char) cptr[i]); + } +} + + +PyDoc_STRVAR_shared(_Py_title__doc__, +"B.title() -> copy of B\n\ +\n\ +Return a titlecased version of B, i.e. ASCII words start with uppercase\n\ +characters, all remaining cased characters have lowercase."); + +void +_Py_bytes_title(char *result, const char *s, Py_ssize_t len) +{ + Py_ssize_t i; + int previous_is_cased = 0; + + for (i = 0; i < len; i++) { + int c = Py_CHARMASK(*s++); + if (Py_ISLOWER(c)) { + if (!previous_is_cased) + c = Py_TOUPPER(c); + previous_is_cased = 1; + } else if (Py_ISUPPER(c)) { + if (previous_is_cased) + c = Py_TOLOWER(c); + previous_is_cased = 1; + } else + previous_is_cased = 0; + *result++ = c; + } +} + + +PyDoc_STRVAR_shared(_Py_capitalize__doc__, +"B.capitalize() -> copy of B\n\ +\n\ +Return a copy of B with only its first character capitalized (ASCII)\n\ +and the rest lower-cased."); + +void +_Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len) +{ + if (len > 0) { + *result = Py_TOUPPER(*s); + _Py_bytes_lower(result + 1, s + 1, len - 1); + } +} + + +PyDoc_STRVAR_shared(_Py_swapcase__doc__, +"B.swapcase() -> copy of B\n\ +\n\ +Return a copy of B with uppercase ASCII characters converted\n\ +to lowercase ASCII and vice versa."); + +void +_Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len) +{ + Py_ssize_t i; + + for (i = 0; i < len; i++) { + int c = Py_CHARMASK(*s++); + if (Py_ISLOWER(c)) { + *result = Py_TOUPPER(c); + } + else if (Py_ISUPPER(c)) { + *result = Py_TOLOWER(c); + } + else + *result = c; + result++; + } +} + + +PyDoc_STRVAR_shared(_Py_maketrans__doc__, +"B.maketrans(frm, to) -> translation table\n\ +\n\ +Return a translation table (a bytes object of length 256) suitable\n\ +for use in the bytes or bytearray translate method where each byte\n\ +in frm is mapped to the byte at the same position in to.\n\ +The bytes objects frm and to must be of the same length."); + +PyObject * +_Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) +{ + PyObject *res = NULL; + Py_ssize_t i; + char *p; + + if (frm->len != to->len) { + PyErr_Format(PyExc_ValueError, + "maketrans arguments must have same length"); + return NULL; + } + res = PyBytes_FromStringAndSize(NULL, 256); + if (!res) + return NULL; + p = PyBytes_AS_STRING(res); + for (i = 0; i < 256; i++) + p[i] = (char) i; + for (i = 0; i < frm->len; i++) { + p[((unsigned char *)frm->buf)[i]] = ((char *)to->buf)[i]; + } + + return res; +} + +#define FASTSEARCH fastsearch +#define STRINGLIB(F) stringlib_##F +#define STRINGLIB_CHAR char +#define STRINGLIB_SIZEOF_CHAR 1 + +#include "stringlib/fastsearch.h" +#include "stringlib/count.h" +#include "stringlib/find.h" + +/* +Wraps stringlib_parse_args_finds() and additionally checks the first +argument type. + +In case the first argument is a bytes-like object, sets it to subobj, +and doesn't touch the byte parameter. +In case it is an integer in range(0, 256), writes the integer value +to byte, and sets subobj to NULL. + +The other parameters are similar to those of +stringlib_parse_args_finds(). +*/ + +Py_LOCAL_INLINE(int) +parse_args_finds_byte(const char *function_name, PyObject *args, + PyObject **subobj, char *byte, + Py_ssize_t *start, Py_ssize_t *end) +{ + PyObject *tmp_subobj; + Py_ssize_t ival; + + if(!stringlib_parse_args_finds(function_name, args, &tmp_subobj, + start, end)) + return 0; + + if (PyObject_CheckBuffer(tmp_subobj)) { + *subobj = tmp_subobj; + return 1; + } + + if (!PyIndex_Check(tmp_subobj)) { + PyErr_Format(PyExc_TypeError, + "argument should be integer or bytes-like object, " + "not '%.200s'", + Py_TYPE(tmp_subobj)->tp_name); + return 0; + } + + ival = PyNumber_AsSsize_t(tmp_subobj, NULL); + if (ival == -1 && PyErr_Occurred()) { + return 0; + } + if (ival < 0 || ival > 255) { + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return 0; + } + + *subobj = NULL; + *byte = (char)ival; + return 1; +} + +/* helper macro to fixup start/end slice values */ +#define ADJUST_INDICES(start, end, len) \ + if (end > len) \ + end = len; \ + else if (end < 0) { \ + end += len; \ + if (end < 0) \ + end = 0; \ + } \ + if (start < 0) { \ + start += len; \ + if (start < 0) \ + start = 0; \ + } + +Py_LOCAL_INLINE(Py_ssize_t) +find_internal(const char *str, Py_ssize_t len, + const char *function_name, PyObject *args, int dir) +{ + PyObject *subobj; + char byte; + Py_buffer subbuf; + const char *sub; + Py_ssize_t sub_len; + Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; + Py_ssize_t res; + + if (!parse_args_finds_byte(function_name, args, + &subobj, &byte, &start, &end)) + return -2; + + if (subobj) { + if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0) + return -2; + + sub = subbuf.buf; + sub_len = subbuf.len; + } + else { + sub = &byte; + sub_len = 1; + } + + ADJUST_INDICES(start, end, len); + if (end - start < sub_len) + res = -1; + else if (sub_len == 1) { + if (dir > 0) + res = stringlib_find_char( + str + start, end - start, + *sub); + else + res = stringlib_rfind_char( + str + start, end - start, + *sub); + if (res >= 0) + res += start; + } + else { + if (dir > 0) + res = stringlib_find_slice( + str, len, + sub, sub_len, start, end); + else + res = stringlib_rfind_slice( + str, len, + sub, sub_len, start, end); + } + + if (subobj) + PyBuffer_Release(&subbuf); + + return res; +} + +PyDoc_STRVAR_shared(_Py_find__doc__, +"B.find(sub[, start[, end]]) -> int\n\ +\n\ +Return the lowest index in B where subsection sub is found,\n\ +such that sub is contained within B[start,end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Return -1 on failure."); + +PyObject * +_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args) +{ + Py_ssize_t result = find_internal(str, len, "find", args, +1); + if (result == -2) + return NULL; + return PyLong_FromSsize_t(result); +} + +PyDoc_STRVAR_shared(_Py_index__doc__, +"B.index(sub[, start[, end]]) -> int\n\ +\n\ +Return the lowest index in B where subsection sub is found,\n\ +such that sub is contained within B[start,end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Raises ValueError when the subsection is not found."); + +PyObject * +_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args) +{ + Py_ssize_t result = find_internal(str, len, "index", args, +1); + if (result == -2) + return NULL; + if (result == -1) { + PyErr_SetString(PyExc_ValueError, + "subsection not found"); + return NULL; + } + return PyLong_FromSsize_t(result); +} + +PyDoc_STRVAR_shared(_Py_rfind__doc__, +"B.rfind(sub[, start[, end]]) -> int\n\ +\n\ +Return the highest index in B where subsection sub is found,\n\ +such that sub is contained within B[start,end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Return -1 on failure."); + +PyObject * +_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args) +{ + Py_ssize_t result = find_internal(str, len, "rfind", args, -1); + if (result == -2) + return NULL; + return PyLong_FromSsize_t(result); +} + +PyDoc_STRVAR_shared(_Py_rindex__doc__, +"B.rindex(sub[, start[, end]]) -> int\n\ +\n\ +Return the highest index in B where subsection sub is found,\n\ +such that sub is contained within B[start,end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Raise ValueError when the subsection is not found."); + +PyObject * +_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args) +{ + Py_ssize_t result = find_internal(str, len, "rindex", args, -1); + if (result == -2) + return NULL; + if (result == -1) { + PyErr_SetString(PyExc_ValueError, + "subsection not found"); + return NULL; + } + return PyLong_FromSsize_t(result); +} + +PyDoc_STRVAR_shared(_Py_count__doc__, +"B.count(sub[, start[, end]]) -> int\n\ +\n\ +Return the number of non-overlapping occurrences of subsection sub in\n\ +bytes B[start:end]. Optional arguments start and end are interpreted\n\ +as in slice notation."); + +PyObject * +_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args) +{ + PyObject *sub_obj; + const char *sub; + Py_ssize_t sub_len; + char byte; + Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; + + Py_buffer vsub; + PyObject *count_obj; + + if (!parse_args_finds_byte("count", args, + &sub_obj, &byte, &start, &end)) + return NULL; + + if (sub_obj) { + if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0) + return NULL; + + sub = vsub.buf; + sub_len = vsub.len; + } + else { + sub = &byte; + sub_len = 1; + } + + ADJUST_INDICES(start, end, len); + + count_obj = PyLong_FromSsize_t( + stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX) + ); + + if (sub_obj) + PyBuffer_Release(&vsub); + + return count_obj; +} + +int +_Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg) +{ + Py_ssize_t ival = PyNumber_AsSsize_t(arg, NULL); + if (ival == -1 && PyErr_Occurred()) { + Py_buffer varg; + Py_ssize_t pos; + PyErr_Clear(); + if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0) + return -1; + pos = stringlib_find(str, len, + varg.buf, varg.len, 0); + PyBuffer_Release(&varg); + return pos >= 0; + } + if (ival < 0 || ival >= 256) { + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; + } + + return memchr(str, (int) ival, len) != NULL; +} + + +/* Matches the end (direction >= 0) or start (direction < 0) of the buffer + * against substr, using the start and end arguments. Returns + * -1 on error, 0 if not found and 1 if found. + */ +static int +tailmatch(const char *str, Py_ssize_t len, PyObject *substr, + Py_ssize_t start, Py_ssize_t end, int direction) +{ + Py_buffer sub_view = {NULL, NULL}; + const char *sub; + Py_ssize_t slen; + + if (PyBytes_Check(substr)) { + sub = PyBytes_AS_STRING(substr); + slen = PyBytes_GET_SIZE(substr); + } + else { + if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0) + return -1; + sub = sub_view.buf; + slen = sub_view.len; + } + + ADJUST_INDICES(start, end, len); + + if (direction < 0) { + /* startswith */ + if (start > len - slen) + goto notfound; + } else { + /* endswith */ + if (end - start < slen || start > len) + goto notfound; + + if (end - slen > start) + start = end - slen; + } + if (end - start < slen) + goto notfound; + if (memcmp(str + start, sub, slen) != 0) + goto notfound; + + PyBuffer_Release(&sub_view); + return 1; + +notfound: + PyBuffer_Release(&sub_view); + return 0; +} + +static PyObject * +_Py_bytes_tailmatch(const char *str, Py_ssize_t len, + const char *function_name, PyObject *args, + int direction) +{ + Py_ssize_t start = 0; + Py_ssize_t end = PY_SSIZE_T_MAX; + PyObject *subobj; + int result; + + if (!stringlib_parse_args_finds(function_name, args, &subobj, &start, &end)) + return NULL; + if (PyTuple_Check(subobj)) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { + result = tailmatch(str, len, PyTuple_GET_ITEM(subobj, i), + start, end, direction); + if (result == -1) + return NULL; + else if (result) { + Py_RETURN_TRUE; + } + } + Py_RETURN_FALSE; + } + result = tailmatch(str, len, subobj, start, end, direction); + if (result == -1) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_Format(PyExc_TypeError, + "%s first arg must be bytes or a tuple of bytes, " + "not %s", + function_name, Py_TYPE(subobj)->tp_name); + return NULL; + } + else + return PyBool_FromLong(result); +} + +PyDoc_STRVAR_shared(_Py_startswith__doc__, +"B.startswith(prefix[, start[, end]]) -> bool\n\ +\n\ +Return True if B starts with the specified prefix, False otherwise.\n\ +With optional start, test B beginning at that position.\n\ +With optional end, stop comparing B at that position.\n\ +prefix can also be a tuple of bytes to try."); + +PyObject * +_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args) +{ + return _Py_bytes_tailmatch(str, len, "startswith", args, -1); +} + +PyDoc_STRVAR_shared(_Py_endswith__doc__, +"B.endswith(suffix[, start[, end]]) -> bool\n\ +\n\ +Return True if B ends with the specified suffix, False otherwise.\n\ +With optional start, test B beginning at that position.\n\ +With optional end, stop comparing B at that position.\n\ +suffix can also be a tuple of bytes to try."); + +PyObject * +_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args) +{ + return _Py_bytes_tailmatch(str, len, "endswith", args, +1); +} diff --git a/python/Objects/bytesobject.c b/python/Objects/bytesobject.c new file mode 100755 index 0000000..feeabcb --- /dev/null +++ b/python/Objects/bytesobject.c @@ -0,0 +1,3489 @@ +/* bytes object implementation */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" + +#include "bytes_methods.h" +#include "pystrhex.h" +#include + +/*[clinic input] +class bytes "PyBytesObject *" "&PyBytes_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7a238f965d64892b]*/ + +#include "clinic/bytesobject.c.h" + +#ifdef COUNT_ALLOCS +Py_ssize_t _Py_null_strings, _Py_one_strings; +#endif + +static PyBytesObject *characters[UCHAR_MAX + 1]; +static PyBytesObject *nullstring; + +/* PyBytesObject_SIZE gives the basic size of a string; any memory allocation + for a string of length n should request PyBytesObject_SIZE + n bytes. + + Using PyBytesObject_SIZE instead of sizeof(PyBytesObject) saves + 3 bytes per string allocation on a typical system. +*/ +#define PyBytesObject_SIZE (offsetof(PyBytesObject, ob_sval) + 1) + +/* Forward declaration */ +Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer, + char *str); + +/* + For PyBytes_FromString(), the parameter `str' points to a null-terminated + string containing exactly `size' bytes. + + For PyBytes_FromStringAndSize(), the parameter `str' is + either NULL or else points to a string containing at least `size' bytes. + For PyBytes_FromStringAndSize(), the string in the `str' parameter does + not have to be null-terminated. (Therefore it is safe to construct a + substring by calling `PyBytes_FromStringAndSize(origstring, substrlen)'.) + If `str' is NULL then PyBytes_FromStringAndSize() will allocate `size+1' + bytes (setting the last byte to the null terminating character) and you can + fill in the data yourself. If `str' is non-NULL then the resulting + PyBytes object must be treated as immutable and you must not fill in nor + alter the data yourself, since the strings may be shared. + + The PyObject member `op->ob_size', which denotes the number of "extra + items" in a variable-size object, will contain the number of bytes + allocated for string data, not counting the null terminating character. + It is therefore equal to the `size' parameter (for + PyBytes_FromStringAndSize()) or the length of the string in the `str' + parameter (for PyBytes_FromString()). +*/ +static PyObject * +_PyBytes_FromSize(Py_ssize_t size, int use_calloc) +{ + PyBytesObject *op; + assert(size >= 0); + + if (size == 0 && (op = nullstring) != NULL) { +#ifdef COUNT_ALLOCS + _Py_null_strings++; +#endif + Py_INCREF(op); + return (PyObject *)op; + } + + if ((size_t)size > (size_t)PY_SSIZE_T_MAX - PyBytesObject_SIZE) { + PyErr_SetString(PyExc_OverflowError, + "byte string is too large"); + return NULL; + } + + /* Inline PyObject_NewVar */ + if (use_calloc) + op = (PyBytesObject *)PyObject_Calloc(1, PyBytesObject_SIZE + size); + else + op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); + if (op == NULL) + return PyErr_NoMemory(); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + op->ob_shash = -1; + if (!use_calloc) + op->ob_sval[size] = '\0'; + /* empty byte string singleton */ + if (size == 0) { + nullstring = op; + Py_INCREF(op); + } + return (PyObject *) op; +} + +PyObject * +PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) +{ + PyBytesObject *op; + if (size < 0) { + PyErr_SetString(PyExc_SystemError, + "Negative size passed to PyBytes_FromStringAndSize"); + return NULL; + } + if (size == 1 && str != NULL && + (op = characters[*str & UCHAR_MAX]) != NULL) + { +#ifdef COUNT_ALLOCS + _Py_one_strings++; +#endif + Py_INCREF(op); + return (PyObject *)op; + } + + op = (PyBytesObject *)_PyBytes_FromSize(size, 0); + if (op == NULL) + return NULL; + if (str == NULL) + return (PyObject *) op; + + memcpy(op->ob_sval, str, size); + /* share short strings */ + if (size == 1) { + characters[*str & UCHAR_MAX] = op; + Py_INCREF(op); + } + return (PyObject *) op; +} + +PyObject * +PyBytes_FromString(const char *str) +{ + size_t size; + PyBytesObject *op; + + assert(str != NULL); + size = strlen(str); + if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { + PyErr_SetString(PyExc_OverflowError, + "byte string is too long"); + return NULL; + } + if (size == 0 && (op = nullstring) != NULL) { +#ifdef COUNT_ALLOCS + _Py_null_strings++; +#endif + Py_INCREF(op); + return (PyObject *)op; + } + if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) { +#ifdef COUNT_ALLOCS + _Py_one_strings++; +#endif + Py_INCREF(op); + return (PyObject *)op; + } + + /* Inline PyObject_NewVar */ + op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); + if (op == NULL) + return PyErr_NoMemory(); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + op->ob_shash = -1; + memcpy(op->ob_sval, str, size+1); + /* share short strings */ + if (size == 0) { + nullstring = op; + Py_INCREF(op); + } else if (size == 1) { + characters[*str & UCHAR_MAX] = op; + Py_INCREF(op); + } + return (PyObject *) op; +} + +PyObject * +PyBytes_FromFormatV(const char *format, va_list vargs) +{ + char *s; + const char *f; + const char *p; + Py_ssize_t prec; + int longflag; + int size_tflag; + /* Longest 64-bit formatted numbers: + - "18446744073709551615\0" (21 bytes) + - "-9223372036854775808\0" (21 bytes) + Decimal takes the most space (it isn't enough for octal.) + + Longest 64-bit pointer representation: + "0xffffffffffffffff\0" (19 bytes). */ + char buffer[21]; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + + s = _PyBytesWriter_Alloc(&writer, strlen(format)); + if (s == NULL) + return NULL; + writer.overallocate = 1; + +#define WRITE_BYTES(str) \ + do { \ + s = _PyBytesWriter_WriteBytes(&writer, s, (str), strlen(str)); \ + if (s == NULL) \ + goto error; \ + } while (0) + + for (f = format; *f; f++) { + if (*f != '%') { + *s++ = *f; + continue; + } + + p = f++; + + /* ignore the width (ex: 10 in "%10s") */ + while (Py_ISDIGIT(*f)) + f++; + + /* parse the precision (ex: 10 in "%.10s") */ + prec = 0; + if (*f == '.') { + f++; + for (; Py_ISDIGIT(*f); f++) { + prec = (prec * 10) + (*f - '0'); + } + } + + while (*f && *f != '%' && !Py_ISALPHA(*f)) + f++; + + /* handle the long flag ('l'), but only for %ld and %lu. + others can be added when necessary. */ + longflag = 0; + if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) { + longflag = 1; + ++f; + } + + /* handle the size_t flag ('z'). */ + size_tflag = 0; + if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { + size_tflag = 1; + ++f; + } + + /* subtract bytes preallocated for the format string + (ex: 2 for "%s") */ + writer.min_size -= (f - p + 1); + + switch (*f) { + case 'c': + { + int c = va_arg(vargs, int); + if (c < 0 || c > 255) { + PyErr_SetString(PyExc_OverflowError, + "PyBytes_FromFormatV(): %c format " + "expects an integer in range [0; 255]"); + goto error; + } + writer.min_size++; + *s++ = (unsigned char)c; + break; + } + + case 'd': + if (longflag) + sprintf(buffer, "%ld", va_arg(vargs, long)); + else if (size_tflag) + sprintf(buffer, "%" PY_FORMAT_SIZE_T "d", + va_arg(vargs, Py_ssize_t)); + else + sprintf(buffer, "%d", va_arg(vargs, int)); + assert(strlen(buffer) < sizeof(buffer)); + WRITE_BYTES(buffer); + break; + + case 'u': + if (longflag) + sprintf(buffer, "%lu", + va_arg(vargs, unsigned long)); + else if (size_tflag) + sprintf(buffer, "%" PY_FORMAT_SIZE_T "u", + va_arg(vargs, size_t)); + else + sprintf(buffer, "%u", + va_arg(vargs, unsigned int)); + assert(strlen(buffer) < sizeof(buffer)); + WRITE_BYTES(buffer); + break; + + case 'i': + sprintf(buffer, "%i", va_arg(vargs, int)); + assert(strlen(buffer) < sizeof(buffer)); + WRITE_BYTES(buffer); + break; + + case 'x': + sprintf(buffer, "%x", va_arg(vargs, int)); + assert(strlen(buffer) < sizeof(buffer)); + WRITE_BYTES(buffer); + break; + + case 's': + { + Py_ssize_t i; + + p = va_arg(vargs, const char*); + if (prec <= 0) { + i = strlen(p); + } + else { + i = 0; + while (i < prec && p[i]) { + i++; + } + } + s = _PyBytesWriter_WriteBytes(&writer, s, p, i); + if (s == NULL) + goto error; + break; + } + + case 'p': + sprintf(buffer, "%p", va_arg(vargs, void*)); + assert(strlen(buffer) < sizeof(buffer)); + /* %p is ill-defined: ensure leading 0x. */ + if (buffer[1] == 'X') + buffer[1] = 'x'; + else if (buffer[1] != 'x') { + memmove(buffer+2, buffer, strlen(buffer)+1); + buffer[0] = '0'; + buffer[1] = 'x'; + } + WRITE_BYTES(buffer); + break; + + case '%': + writer.min_size++; + *s++ = '%'; + break; + + default: + if (*f == 0) { + /* fix min_size if we reached the end of the format string */ + writer.min_size++; + } + + /* invalid format string: copy unformatted string and exit */ + WRITE_BYTES(p); + return _PyBytesWriter_Finish(&writer, s); + } + } + +#undef WRITE_BYTES + + return _PyBytesWriter_Finish(&writer, s); + + error: + _PyBytesWriter_Dealloc(&writer); + return NULL; +} + +PyObject * +PyBytes_FromFormat(const char *format, ...) +{ + PyObject* ret; + va_list vargs; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + ret = PyBytes_FromFormatV(format, vargs); + va_end(vargs); + return ret; +} + +/* Helpers for formatstring */ + +Py_LOCAL_INLINE(PyObject *) +getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx) +{ + Py_ssize_t argidx = *p_argidx; + if (argidx < arglen) { + (*p_argidx)++; + if (arglen < 0) + return args; + else + return PyTuple_GetItem(args, argidx); + } + PyErr_SetString(PyExc_TypeError, + "not enough arguments for format string"); + return NULL; +} + +/* Format codes + * F_LJUST '-' + * F_SIGN '+' + * F_BLANK ' ' + * F_ALT '#' + * F_ZERO '0' + */ +#define F_LJUST (1<<0) +#define F_SIGN (1<<1) +#define F_BLANK (1<<2) +#define F_ALT (1<<3) +#define F_ZERO (1<<4) + +/* Returns a new reference to a PyBytes object, or NULL on failure. */ + +static char* +formatfloat(PyObject *v, int flags, int prec, int type, + PyObject **p_result, _PyBytesWriter *writer, char *str) +{ + char *p; + PyObject *result; + double x; + size_t len; + + x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, "float argument required, " + "not %.200s", Py_TYPE(v)->tp_name); + return NULL; + } + + if (prec < 0) + prec = 6; + + p = PyOS_double_to_string(x, type, prec, + (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); + + if (p == NULL) + return NULL; + + len = strlen(p); + if (writer != NULL) { + str = _PyBytesWriter_Prepare(writer, str, len); + if (str == NULL) + return NULL; + memcpy(str, p, len); + PyMem_Free(p); + str += len; + return str; + } + + result = PyBytes_FromStringAndSize(p, len); + PyMem_Free(p); + *p_result = result; + return result != NULL ? str : NULL; +} + +static PyObject * +formatlong(PyObject *v, int flags, int prec, int type) +{ + PyObject *result, *iobj; + if (type == 'i') + type = 'd'; + if (PyLong_Check(v)) + return _PyUnicode_FormatLong(v, flags & F_ALT, prec, type); + if (PyNumber_Check(v)) { + /* make sure number is a type of integer for o, x, and X */ + if (type == 'o' || type == 'x' || type == 'X') + iobj = PyNumber_Index(v); + else + iobj = PyNumber_Long(v); + if (iobj == NULL) { + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return NULL; + } + else if (!PyLong_Check(iobj)) + Py_CLEAR(iobj); + if (iobj != NULL) { + result = _PyUnicode_FormatLong(iobj, flags & F_ALT, prec, type); + Py_DECREF(iobj); + return result; + } + } + PyErr_Format(PyExc_TypeError, + "%%%c format: %s is required, not %.200s", type, + (type == 'o' || type == 'x' || type == 'X') ? "an integer" + : "a number", + Py_TYPE(v)->tp_name); + return NULL; +} + +static int +byte_converter(PyObject *arg, char *p) +{ + if (PyBytes_Check(arg) && PyBytes_GET_SIZE(arg) == 1) { + *p = PyBytes_AS_STRING(arg)[0]; + return 1; + } + else if (PyByteArray_Check(arg) && PyByteArray_GET_SIZE(arg) == 1) { + *p = PyByteArray_AS_STRING(arg)[0]; + return 1; + } + else { + PyObject *iobj; + long ival; + int overflow; + /* make sure number is a type of integer */ + if (PyLong_Check(arg)) { + ival = PyLong_AsLongAndOverflow(arg, &overflow); + } + else { + iobj = PyNumber_Index(arg); + if (iobj == NULL) { + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return 0; + goto onError; + } + ival = PyLong_AsLongAndOverflow(iobj, &overflow); + Py_DECREF(iobj); + } + if (!overflow && ival == -1 && PyErr_Occurred()) + goto onError; + if (overflow || !(0 <= ival && ival <= 255)) { + PyErr_SetString(PyExc_OverflowError, + "%c arg not in range(256)"); + return 0; + } + *p = (char)ival; + return 1; + } + onError: + PyErr_SetString(PyExc_TypeError, + "%c requires an integer in range(256) or a single byte"); + return 0; +} + +static PyObject *_PyBytes_FromBuffer(PyObject *x); + +static PyObject * +format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) +{ + PyObject *func, *result; + _Py_IDENTIFIER(__bytes__); + /* is it a bytes object? */ + if (PyBytes_Check(v)) { + *pbuf = PyBytes_AS_STRING(v); + *plen = PyBytes_GET_SIZE(v); + Py_INCREF(v); + return v; + } + if (PyByteArray_Check(v)) { + *pbuf = PyByteArray_AS_STRING(v); + *plen = PyByteArray_GET_SIZE(v); + Py_INCREF(v); + return v; + } + /* does it support __bytes__? */ + func = _PyObject_LookupSpecial(v, &PyId___bytes__); + if (func != NULL) { + result = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (result == NULL) + return NULL; + if (!PyBytes_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__bytes__ returned non-bytes (type %.200s)", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + *pbuf = PyBytes_AS_STRING(result); + *plen = PyBytes_GET_SIZE(result); + return result; + } + /* does it support buffer protocol? */ + if (PyObject_CheckBuffer(v)) { + /* maybe we can avoid making a copy of the buffer object here? */ + result = _PyBytes_FromBuffer(v); + if (result == NULL) + return NULL; + *pbuf = PyBytes_AS_STRING(result); + *plen = PyBytes_GET_SIZE(result); + return result; + } + PyErr_Format(PyExc_TypeError, + "%%b requires a bytes-like object, " + "or an object that implements __bytes__, not '%.100s'", + Py_TYPE(v)->tp_name); + return NULL; +} + +/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */ + +PyObject * +_PyBytes_FormatEx(const char *format, Py_ssize_t format_len, + PyObject *args, int use_bytearray) +{ + const char *fmt; + char *res; + Py_ssize_t arglen, argidx; + Py_ssize_t fmtcnt; + int args_owned = 0; + PyObject *dict = NULL; + _PyBytesWriter writer; + + if (args == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + fmt = format; + fmtcnt = format_len; + + _PyBytesWriter_Init(&writer); + writer.use_bytearray = use_bytearray; + + res = _PyBytesWriter_Alloc(&writer, fmtcnt); + if (res == NULL) + return NULL; + if (!use_bytearray) + writer.overallocate = 1; + + if (PyTuple_Check(args)) { + arglen = PyTuple_GET_SIZE(args); + argidx = 0; + } + else { + arglen = -1; + argidx = -2; + } + if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript && + !PyTuple_Check(args) && !PyBytes_Check(args) && !PyUnicode_Check(args) && + !PyByteArray_Check(args)) { + dict = args; + } + + while (--fmtcnt >= 0) { + if (*fmt != '%') { + Py_ssize_t len; + char *pos; + + pos = (char *)memchr(fmt + 1, '%', fmtcnt); + if (pos != NULL) + len = pos - fmt; + else + len = fmtcnt + 1; + assert(len != 0); + + memcpy(res, fmt, len); + res += len; + fmt += len; + fmtcnt -= (len - 1); + } + else { + /* Got a format specifier */ + int flags = 0; + Py_ssize_t width = -1; + int prec = -1; + int c = '\0'; + int fill; + PyObject *v = NULL; + PyObject *temp = NULL; + const char *pbuf = NULL; + int sign; + Py_ssize_t len = 0; + char onechar; /* For byte_converter() */ + Py_ssize_t alloc; + + fmt++; + if (*fmt == '%') { + *res++ = '%'; + fmt++; + fmtcnt--; + continue; + } + if (*fmt == '(') { + const char *keystart; + Py_ssize_t keylen; + PyObject *key; + int pcount = 1; + + if (dict == NULL) { + PyErr_SetString(PyExc_TypeError, + "format requires a mapping"); + goto error; + } + ++fmt; + --fmtcnt; + keystart = fmt; + /* Skip over balanced parentheses */ + while (pcount > 0 && --fmtcnt >= 0) { + if (*fmt == ')') + --pcount; + else if (*fmt == '(') + ++pcount; + fmt++; + } + keylen = fmt - keystart - 1; + if (fmtcnt < 0 || pcount > 0) { + PyErr_SetString(PyExc_ValueError, + "incomplete format key"); + goto error; + } + key = PyBytes_FromStringAndSize(keystart, + keylen); + if (key == NULL) + goto error; + if (args_owned) { + Py_DECREF(args); + args_owned = 0; + } + args = PyObject_GetItem(dict, key); + Py_DECREF(key); + if (args == NULL) { + goto error; + } + args_owned = 1; + arglen = -1; + argidx = -2; + } + + /* Parse flags. Example: "%+i" => flags=F_SIGN. */ + while (--fmtcnt >= 0) { + switch (c = *fmt++) { + case '-': flags |= F_LJUST; continue; + case '+': flags |= F_SIGN; continue; + case ' ': flags |= F_BLANK; continue; + case '#': flags |= F_ALT; continue; + case '0': flags |= F_ZERO; continue; + } + break; + } + + /* Parse width. Example: "%10s" => width=10 */ + if (c == '*') { + v = getnextarg(args, arglen, &argidx); + if (v == NULL) + goto error; + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "* wants int"); + goto error; + } + width = PyLong_AsSsize_t(v); + if (width == -1 && PyErr_Occurred()) + goto error; + if (width < 0) { + flags |= F_LJUST; + width = -width; + } + if (--fmtcnt >= 0) + c = *fmt++; + } + else if (c >= 0 && isdigit(c)) { + width = c - '0'; + while (--fmtcnt >= 0) { + c = Py_CHARMASK(*fmt++); + if (!isdigit(c)) + break; + if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) { + PyErr_SetString( + PyExc_ValueError, + "width too big"); + goto error; + } + width = width*10 + (c - '0'); + } + } + + /* Parse precision. Example: "%.3f" => prec=3 */ + if (c == '.') { + prec = 0; + if (--fmtcnt >= 0) + c = *fmt++; + if (c == '*') { + v = getnextarg(args, arglen, &argidx); + if (v == NULL) + goto error; + if (!PyLong_Check(v)) { + PyErr_SetString( + PyExc_TypeError, + "* wants int"); + goto error; + } + prec = _PyLong_AsInt(v); + if (prec == -1 && PyErr_Occurred()) + goto error; + if (prec < 0) + prec = 0; + if (--fmtcnt >= 0) + c = *fmt++; + } + else if (c >= 0 && isdigit(c)) { + prec = c - '0'; + while (--fmtcnt >= 0) { + c = Py_CHARMASK(*fmt++); + if (!isdigit(c)) + break; + if (prec > (INT_MAX - ((int)c - '0')) / 10) { + PyErr_SetString( + PyExc_ValueError, + "prec too big"); + goto error; + } + prec = prec*10 + (c - '0'); + } + } + } /* prec */ + if (fmtcnt >= 0) { + if (c == 'h' || c == 'l' || c == 'L') { + if (--fmtcnt >= 0) + c = *fmt++; + } + } + if (fmtcnt < 0) { + PyErr_SetString(PyExc_ValueError, + "incomplete format"); + goto error; + } + v = getnextarg(args, arglen, &argidx); + if (v == NULL) + goto error; + + if (fmtcnt == 0) { + /* last write: disable writer overallocation */ + writer.overallocate = 0; + } + + sign = 0; + fill = ' '; + switch (c) { + case 'r': + // %r is only for 2/3 code; 3 only code should use %a + case 'a': + temp = PyObject_ASCII(v); + if (temp == NULL) + goto error; + assert(PyUnicode_IS_ASCII(temp)); + pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); + len = PyUnicode_GET_LENGTH(temp); + if (prec >= 0 && len > prec) + len = prec; + break; + + case 's': + // %s is only for 2/3 code; 3 only code should use %b + case 'b': + temp = format_obj(v, &pbuf, &len); + if (temp == NULL) + goto error; + if (prec >= 0 && len > prec) + len = prec; + break; + + case 'i': + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': + if (PyLong_CheckExact(v) + && width == -1 && prec == -1 + && !(flags & (F_SIGN | F_BLANK)) + && c != 'X') + { + /* Fast path */ + int alternate = flags & F_ALT; + int base; + + switch(c) + { + default: + Py_UNREACHABLE(); + case 'd': + case 'i': + case 'u': + base = 10; + break; + case 'o': + base = 8; + break; + case 'x': + case 'X': + base = 16; + break; + } + + /* Fast path */ + writer.min_size -= 2; /* size preallocated for "%d" */ + res = _PyLong_FormatBytesWriter(&writer, res, + v, base, alternate); + if (res == NULL) + goto error; + continue; + } + + temp = formatlong(v, flags, prec, c); + if (!temp) + goto error; + assert(PyUnicode_IS_ASCII(temp)); + pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); + len = PyUnicode_GET_LENGTH(temp); + sign = 1; + if (flags & F_ZERO) + fill = '0'; + break; + + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + if (width == -1 && prec == -1 + && !(flags & (F_SIGN | F_BLANK))) + { + /* Fast path */ + writer.min_size -= 2; /* size preallocated for "%f" */ + res = formatfloat(v, flags, prec, c, NULL, &writer, res); + if (res == NULL) + goto error; + continue; + } + + if (!formatfloat(v, flags, prec, c, &temp, NULL, res)) + goto error; + pbuf = PyBytes_AS_STRING(temp); + len = PyBytes_GET_SIZE(temp); + sign = 1; + if (flags & F_ZERO) + fill = '0'; + break; + + case 'c': + pbuf = &onechar; + len = byte_converter(v, &onechar); + if (!len) + goto error; + if (width == -1) { + /* Fast path */ + *res++ = onechar; + continue; + } + break; + + default: + PyErr_Format(PyExc_ValueError, + "unsupported format character '%c' (0x%x) " + "at index %zd", + c, c, + (Py_ssize_t)(fmt - 1 - format)); + goto error; + } + + if (sign) { + if (*pbuf == '-' || *pbuf == '+') { + sign = *pbuf++; + len--; + } + else if (flags & F_SIGN) + sign = '+'; + else if (flags & F_BLANK) + sign = ' '; + else + sign = 0; + } + if (width < len) + width = len; + + alloc = width; + if (sign != 0 && len == width) + alloc++; + /* 2: size preallocated for %s */ + if (alloc > 2) { + res = _PyBytesWriter_Prepare(&writer, res, alloc - 2); + if (res == NULL) + goto error; + } +#ifndef NDEBUG + char *before = res; +#endif + + /* Write the sign if needed */ + if (sign) { + if (fill != ' ') + *res++ = sign; + if (width > len) + width--; + } + + /* Write the numeric prefix for "x", "X" and "o" formats + if the alternate form is used. + For example, write "0x" for the "%#x" format. */ + if ((flags & F_ALT) && (c == 'o' || c == 'x' || c == 'X')) { + assert(pbuf[0] == '0'); + assert(pbuf[1] == c); + if (fill != ' ') { + *res++ = *pbuf++; + *res++ = *pbuf++; + } + width -= 2; + if (width < 0) + width = 0; + len -= 2; + } + + /* Pad left with the fill character if needed */ + if (width > len && !(flags & F_LJUST)) { + memset(res, fill, width - len); + res += (width - len); + width = len; + } + + /* If padding with spaces: write sign if needed and/or numeric + prefix if the alternate form is used */ + if (fill == ' ') { + if (sign) + *res++ = sign; + if ((flags & F_ALT) && (c == 'o' || c == 'x' || c == 'X')) { + assert(pbuf[0] == '0'); + assert(pbuf[1] == c); + *res++ = *pbuf++; + *res++ = *pbuf++; + } + } + + /* Copy bytes */ + memcpy(res, pbuf, len); + res += len; + + /* Pad right with the fill character if needed */ + if (width > len) { + memset(res, ' ', width - len); + res += (width - len); + } + + if (dict && (argidx < arglen)) { + PyErr_SetString(PyExc_TypeError, + "not all arguments converted during bytes formatting"); + Py_XDECREF(temp); + goto error; + } + Py_XDECREF(temp); + +#ifndef NDEBUG + /* check that we computed the exact size for this write */ + assert((res - before) == alloc); +#endif + } /* '%' */ + + /* If overallocation was disabled, ensure that it was the last + write. Otherwise, we missed an optimization */ + assert(writer.overallocate || fmtcnt == 0 || use_bytearray); + } /* until end */ + + if (argidx < arglen && !dict) { + PyErr_SetString(PyExc_TypeError, + "not all arguments converted during bytes formatting"); + goto error; + } + + if (args_owned) { + Py_DECREF(args); + } + return _PyBytesWriter_Finish(&writer, res); + + error: + _PyBytesWriter_Dealloc(&writer); + if (args_owned) { + Py_DECREF(args); + } + return NULL; +} + +/* Unescape a backslash-escaped string. If unicode is non-zero, + the string is a u-literal. If recode_encoding is non-zero, + the string is UTF-8 encoded and should be re-encoded in the + specified encoding. */ + +static char * +_PyBytes_DecodeEscapeRecode(const char **s, const char *end, + const char *errors, const char *recode_encoding, + _PyBytesWriter *writer, char *p) +{ + PyObject *u, *w; + const char* t; + + t = *s; + /* Decode non-ASCII bytes as UTF-8. */ + while (t < end && (*t & 0x80)) + t++; + u = PyUnicode_DecodeUTF8(*s, t - *s, errors); + if (u == NULL) + return NULL; + + /* Recode them in target encoding. */ + w = PyUnicode_AsEncodedString(u, recode_encoding, errors); + Py_DECREF(u); + if (w == NULL) + return NULL; + assert(PyBytes_Check(w)); + + /* Append bytes to output buffer. */ + writer->min_size--; /* subtract 1 preallocated byte */ + p = _PyBytesWriter_WriteBytes(writer, p, + PyBytes_AS_STRING(w), + PyBytes_GET_SIZE(w)); + Py_DECREF(w); + if (p == NULL) + return NULL; + + *s = t; + return p; +} + +PyObject *_PyBytes_DecodeEscape(const char *s, + Py_ssize_t len, + const char *errors, + Py_ssize_t unicode, + const char *recode_encoding, + const char **first_invalid_escape) +{ + int c; + char *p; + const char *end; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + + p = _PyBytesWriter_Alloc(&writer, len); + if (p == NULL) + return NULL; + writer.overallocate = 1; + + *first_invalid_escape = NULL; + + end = s + len; + while (s < end) { + if (*s != '\\') { + non_esc: + if (!(recode_encoding && (*s & 0x80))) { + *p++ = *s++; + } + else { + /* non-ASCII character and need to recode */ + p = _PyBytes_DecodeEscapeRecode(&s, end, + errors, recode_encoding, + &writer, p); + if (p == NULL) + goto failed; + } + continue; + } + + s++; + if (s == end) { + PyErr_SetString(PyExc_ValueError, + "Trailing \\ in string"); + goto failed; + } + + switch (*s++) { + /* XXX This assumes ASCII! */ + case '\n': break; + case '\\': *p++ = '\\'; break; + case '\'': *p++ = '\''; break; + case '\"': *p++ = '\"'; break; + case 'b': *p++ = '\b'; break; + case 'f': *p++ = '\014'; break; /* FF */ + case 't': *p++ = '\t'; break; + case 'n': *p++ = '\n'; break; + case 'r': *p++ = '\r'; break; + case 'v': *p++ = '\013'; break; /* VT */ + case 'a': *p++ = '\007'; break; /* BEL, not classic C */ + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c = s[-1] - '0'; + if (s < end && '0' <= *s && *s <= '7') { + c = (c<<3) + *s++ - '0'; + if (s < end && '0' <= *s && *s <= '7') + c = (c<<3) + *s++ - '0'; + } + *p++ = c; + break; + case 'x': + if (s+1 < end) { + int digit1, digit2; + digit1 = _PyLong_DigitValue[Py_CHARMASK(s[0])]; + digit2 = _PyLong_DigitValue[Py_CHARMASK(s[1])]; + if (digit1 < 16 && digit2 < 16) { + *p++ = (unsigned char)((digit1 << 4) + digit2); + s += 2; + break; + } + } + /* invalid hexadecimal digits */ + + if (!errors || strcmp(errors, "strict") == 0) { + PyErr_Format(PyExc_ValueError, + "invalid \\x escape at position %zd", + s - 2 - (end - len)); + goto failed; + } + if (strcmp(errors, "replace") == 0) { + *p++ = '?'; + } else if (strcmp(errors, "ignore") == 0) + /* do nothing */; + else { + PyErr_Format(PyExc_ValueError, + "decoding error; unknown " + "error handling code: %.400s", + errors); + goto failed; + } + /* skip \x */ + if (s < end && Py_ISXDIGIT(s[0])) + s++; /* and a hexdigit */ + break; + + default: + if (*first_invalid_escape == NULL) { + *first_invalid_escape = s-1; /* Back up one char, since we've + already incremented s. */ + } + *p++ = '\\'; + s--; + goto non_esc; /* an arbitrary number of unescaped + UTF-8 bytes may follow. */ + } + } + + return _PyBytesWriter_Finish(&writer, p); + + failed: + _PyBytesWriter_Dealloc(&writer); + return NULL; +} + +PyObject *PyBytes_DecodeEscape(const char *s, + Py_ssize_t len, + const char *errors, + Py_ssize_t unicode, + const char *recode_encoding) +{ + const char* first_invalid_escape; + PyObject *result = _PyBytes_DecodeEscape(s, len, errors, unicode, + recode_encoding, + &first_invalid_escape); + if (result == NULL) + return NULL; + if (first_invalid_escape != NULL) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid escape sequence '\\%c'", + (unsigned char)*first_invalid_escape) < 0) { + Py_DECREF(result); + return NULL; + } + } + return result; + +} +/* -------------------------------------------------------------------- */ +/* object api */ + +Py_ssize_t +PyBytes_Size(PyObject *op) +{ + if (!PyBytes_Check(op)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %.200s found", Py_TYPE(op)->tp_name); + return -1; + } + return Py_SIZE(op); +} + +char * +PyBytes_AsString(PyObject *op) +{ + if (!PyBytes_Check(op)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %.200s found", Py_TYPE(op)->tp_name); + return NULL; + } + return ((PyBytesObject *)op)->ob_sval; +} + +int +PyBytes_AsStringAndSize(PyObject *obj, + char **s, + Py_ssize_t *len) +{ + if (s == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (!PyBytes_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %.200s found", Py_TYPE(obj)->tp_name); + return -1; + } + + *s = PyBytes_AS_STRING(obj); + if (len != NULL) + *len = PyBytes_GET_SIZE(obj); + else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) { + PyErr_SetString(PyExc_ValueError, + "embedded null byte"); + return -1; + } + return 0; +} + +/* -------------------------------------------------------------------- */ +/* Methods */ + +#include "stringlib/stringdefs.h" + +#include "stringlib/fastsearch.h" +#include "stringlib/count.h" +#include "stringlib/find.h" +#include "stringlib/join.h" +#include "stringlib/partition.h" +#include "stringlib/split.h" +#include "stringlib/ctype.h" + +#include "stringlib/transmogrify.h" + +PyObject * +PyBytes_Repr(PyObject *obj, int smartquotes) +{ + PyBytesObject* op = (PyBytesObject*) obj; + Py_ssize_t i, length = Py_SIZE(op); + Py_ssize_t newsize, squotes, dquotes; + PyObject *v; + unsigned char quote, *s, *p; + + /* Compute size of output string */ + squotes = dquotes = 0; + newsize = 3; /* b'' */ + s = (unsigned char*)op->ob_sval; + for (i = 0; i < length; i++) { + Py_ssize_t incr = 1; + switch(s[i]) { + case '\'': squotes++; break; + case '"': dquotes++; break; + case '\\': case '\t': case '\n': case '\r': + incr = 2; break; /* \C */ + default: + if (s[i] < ' ' || s[i] >= 0x7f) + incr = 4; /* \xHH */ + } + if (newsize > PY_SSIZE_T_MAX - incr) + goto overflow; + newsize += incr; + } + quote = '\''; + if (smartquotes && squotes && !dquotes) + quote = '"'; + if (squotes && quote == '\'') { + if (newsize > PY_SSIZE_T_MAX - squotes) + goto overflow; + newsize += squotes; + } + + v = PyUnicode_New(newsize, 127); + if (v == NULL) { + return NULL; + } + p = PyUnicode_1BYTE_DATA(v); + + *p++ = 'b', *p++ = quote; + for (i = 0; i < length; i++) { + unsigned char c = op->ob_sval[i]; + if (c == quote || c == '\\') + *p++ = '\\', *p++ = c; + else if (c == '\t') + *p++ = '\\', *p++ = 't'; + else if (c == '\n') + *p++ = '\\', *p++ = 'n'; + else if (c == '\r') + *p++ = '\\', *p++ = 'r'; + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = Py_hexdigits[(c & 0xf0) >> 4]; + *p++ = Py_hexdigits[c & 0xf]; + } + else + *p++ = c; + } + *p++ = quote; + assert(_PyUnicode_CheckConsistency(v, 1)); + return v; + + overflow: + PyErr_SetString(PyExc_OverflowError, + "bytes object is too large to make repr"); + return NULL; +} + +static PyObject * +bytes_repr(PyObject *op) +{ + return PyBytes_Repr(op, 1); +} + +static PyObject * +bytes_str(PyObject *op) +{ + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + if (config->bytes_warning) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "str() on a bytes instance", 1)) { + return NULL; + } + } + return bytes_repr(op); +} + +static Py_ssize_t +bytes_length(PyBytesObject *a) +{ + return Py_SIZE(a); +} + +/* This is also used by PyBytes_Concat() */ +static PyObject * +bytes_concat(PyObject *a, PyObject *b) +{ + Py_buffer va, vb; + PyObject *result = NULL; + + va.len = -1; + vb.len = -1; + if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 || + PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", + Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name); + goto done; + } + + /* Optimize end cases */ + if (va.len == 0 && PyBytes_CheckExact(b)) { + result = b; + Py_INCREF(result); + goto done; + } + if (vb.len == 0 && PyBytes_CheckExact(a)) { + result = a; + Py_INCREF(result); + goto done; + } + + if (va.len > PY_SSIZE_T_MAX - vb.len) { + PyErr_NoMemory(); + goto done; + } + + result = PyBytes_FromStringAndSize(NULL, va.len + vb.len); + if (result != NULL) { + memcpy(PyBytes_AS_STRING(result), va.buf, va.len); + memcpy(PyBytes_AS_STRING(result) + va.len, vb.buf, vb.len); + } + + done: + if (va.len != -1) + PyBuffer_Release(&va); + if (vb.len != -1) + PyBuffer_Release(&vb); + return result; +} + +static PyObject * +bytes_repeat(PyBytesObject *a, Py_ssize_t n) +{ + Py_ssize_t i; + Py_ssize_t j; + Py_ssize_t size; + PyBytesObject *op; + size_t nbytes; + if (n < 0) + n = 0; + /* watch out for overflows: the size can overflow int, + * and the # of bytes needed can overflow size_t + */ + if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) { + PyErr_SetString(PyExc_OverflowError, + "repeated bytes are too long"); + return NULL; + } + size = Py_SIZE(a) * n; + if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { + Py_INCREF(a); + return (PyObject *)a; + } + nbytes = (size_t)size; + if (nbytes + PyBytesObject_SIZE <= nbytes) { + PyErr_SetString(PyExc_OverflowError, + "repeated bytes are too long"); + return NULL; + } + op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes); + if (op == NULL) + return PyErr_NoMemory(); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + op->ob_shash = -1; + op->ob_sval[size] = '\0'; + if (Py_SIZE(a) == 1 && n > 0) { + memset(op->ob_sval, a->ob_sval[0] , n); + return (PyObject *) op; + } + i = 0; + if (i < size) { + memcpy(op->ob_sval, a->ob_sval, Py_SIZE(a)); + i = Py_SIZE(a); + } + while (i < size) { + j = (i <= size-i) ? i : size-i; + memcpy(op->ob_sval+i, op->ob_sval, j); + i += j; + } + return (PyObject *) op; +} + +static int +bytes_contains(PyObject *self, PyObject *arg) +{ + return _Py_bytes_contains(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), arg); +} + +static PyObject * +bytes_item(PyBytesObject *a, Py_ssize_t i) +{ + if (i < 0 || i >= Py_SIZE(a)) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + return PyLong_FromLong((unsigned char)a->ob_sval[i]); +} + +static int +bytes_compare_eq(PyBytesObject *a, PyBytesObject *b) +{ + int cmp; + Py_ssize_t len; + + len = Py_SIZE(a); + if (Py_SIZE(b) != len) + return 0; + + if (a->ob_sval[0] != b->ob_sval[0]) + return 0; + + cmp = memcmp(a->ob_sval, b->ob_sval, len); + return (cmp == 0); +} + +static PyObject* +bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) +{ + int c; + Py_ssize_t len_a, len_b; + Py_ssize_t min_len; + int rc; + + /* Make sure both arguments are strings. */ + if (!(PyBytes_Check(a) && PyBytes_Check(b))) { + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + if (config->bytes_warning && (op == Py_EQ || op == Py_NE)) { + rc = PyObject_IsInstance((PyObject*)a, + (PyObject*)&PyUnicode_Type); + if (!rc) + rc = PyObject_IsInstance((PyObject*)b, + (PyObject*)&PyUnicode_Type); + if (rc < 0) + return NULL; + if (rc) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytes and string", 1)) + return NULL; + } + else { + rc = PyObject_IsInstance((PyObject*)a, + (PyObject*)&PyLong_Type); + if (!rc) + rc = PyObject_IsInstance((PyObject*)b, + (PyObject*)&PyLong_Type); + if (rc < 0) + return NULL; + if (rc) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytes and int", 1)) + return NULL; + } + } + } + Py_RETURN_NOTIMPLEMENTED; + } + else if (a == b) { + switch (op) { + case Py_EQ: + case Py_LE: + case Py_GE: + /* a string is equal to itself */ + Py_RETURN_TRUE; + case Py_NE: + case Py_LT: + case Py_GT: + Py_RETURN_FALSE; + default: + PyErr_BadArgument(); + return NULL; + } + } + else if (op == Py_EQ || op == Py_NE) { + int eq = bytes_compare_eq(a, b); + eq ^= (op == Py_NE); + return PyBool_FromLong(eq); + } + else { + len_a = Py_SIZE(a); + len_b = Py_SIZE(b); + min_len = Py_MIN(len_a, len_b); + if (min_len > 0) { + c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); + if (c == 0) + c = memcmp(a->ob_sval, b->ob_sval, min_len); + } + else + c = 0; + if (c != 0) + Py_RETURN_RICHCOMPARE(c, 0, op); + Py_RETURN_RICHCOMPARE(len_a, len_b, op); + } +} + +static Py_hash_t +bytes_hash(PyBytesObject *a) +{ + if (a->ob_shash == -1) { + /* Can't fail */ + a->ob_shash = _Py_HashBytes(a->ob_sval, Py_SIZE(a)); + } + return a->ob_shash; +} + +static PyObject* +bytes_subscript(PyBytesObject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += PyBytes_GET_SIZE(self); + if (i < 0 || i >= PyBytes_GET_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, + "index out of range"); + return NULL; + } + return PyLong_FromLong((unsigned char)self->ob_sval[i]); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength, i; + size_t cur; + char* source_buf; + char* result_buf; + PyObject* result; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelength = PySlice_AdjustIndices(PyBytes_GET_SIZE(self), &start, + &stop, step); + + if (slicelength <= 0) { + return PyBytes_FromStringAndSize("", 0); + } + else if (start == 0 && step == 1 && + slicelength == PyBytes_GET_SIZE(self) && + PyBytes_CheckExact(self)) { + Py_INCREF(self); + return (PyObject *)self; + } + else if (step == 1) { + return PyBytes_FromStringAndSize( + PyBytes_AS_STRING(self) + start, + slicelength); + } + else { + source_buf = PyBytes_AS_STRING(self); + result = PyBytes_FromStringAndSize(NULL, slicelength); + if (result == NULL) + return NULL; + + result_buf = PyBytes_AS_STRING(result); + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + result_buf[i] = source_buf[cur]; + } + + return result; + } + } + else { + PyErr_Format(PyExc_TypeError, + "byte indices must be integers or slices, not %.200s", + Py_TYPE(item)->tp_name); + return NULL; + } +} + +static int +bytes_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags) +{ + return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self), + 1, flags); +} + +static PySequenceMethods bytes_as_sequence = { + (lenfunc)bytes_length, /*sq_length*/ + (binaryfunc)bytes_concat, /*sq_concat*/ + (ssizeargfunc)bytes_repeat, /*sq_repeat*/ + (ssizeargfunc)bytes_item, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + (objobjproc)bytes_contains /*sq_contains*/ +}; + +static PyMappingMethods bytes_as_mapping = { + (lenfunc)bytes_length, + (binaryfunc)bytes_subscript, + 0, +}; + +static PyBufferProcs bytes_as_buffer = { + (getbufferproc)bytes_buffer_getbuffer, + NULL, +}; + + +#define LEFTSTRIP 0 +#define RIGHTSTRIP 1 +#define BOTHSTRIP 2 + +/*[clinic input] +bytes.split + + sep: object = None + The delimiter according which to split the bytes. + None (the default value) means split on ASCII whitespace characters + (space, tab, return, newline, formfeed, vertical tab). + maxsplit: Py_ssize_t = -1 + Maximum number of splits to do. + -1 (the default value) means no limit. + +Return a list of the sections in the bytes, using sep as the delimiter. +[clinic start generated code]*/ + +static PyObject * +bytes_split_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=52126b5844c1d8ef input=8b809b39074abbfa]*/ +{ + Py_ssize_t len = PyBytes_GET_SIZE(self), n; + const char *s = PyBytes_AS_STRING(self), *sub; + Py_buffer vsub; + PyObject *list; + + if (maxsplit < 0) + maxsplit = PY_SSIZE_T_MAX; + if (sep == Py_None) + return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) + return NULL; + sub = vsub.buf; + n = vsub.len; + + list = stringlib_split((PyObject*) self, s, len, sub, n, maxsplit); + PyBuffer_Release(&vsub); + return list; +} + +/*[clinic input] +bytes.partition + + sep: Py_buffer + / + +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytes. If the separator is found, +returns a 3-tuple containing the part before the separator, the separator +itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing the original bytes +object and two empty bytes objects. +[clinic start generated code]*/ + +static PyObject * +bytes_partition_impl(PyBytesObject *self, Py_buffer *sep) +/*[clinic end generated code: output=f532b392a17ff695 input=61cca95519406099]*/ +{ + return stringlib_partition( + (PyObject*) self, + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + sep->obj, (const char *)sep->buf, sep->len + ); +} + +/*[clinic input] +bytes.rpartition + + sep: Py_buffer + / + +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytes, starting at the end. If +the separator is found, returns a 3-tuple containing the part before the +separator, the separator itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing two empty bytes +objects and the original bytes object. +[clinic start generated code]*/ + +static PyObject * +bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep) +/*[clinic end generated code: output=191b114cbb028e50 input=d78db010c8cfdbe1]*/ +{ + return stringlib_rpartition( + (PyObject*) self, + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + sep->obj, (const char *)sep->buf, sep->len + ); +} + +/*[clinic input] +bytes.rsplit = bytes.split + +Return a list of the sections in the bytes, using sep as the delimiter. + +Splitting is done starting at the end of the bytes and working to the front. +[clinic start generated code]*/ + +static PyObject * +bytes_rsplit_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=ba698d9ea01e1c8f input=0f86c9f28f7d7b7b]*/ +{ + Py_ssize_t len = PyBytes_GET_SIZE(self), n; + const char *s = PyBytes_AS_STRING(self), *sub; + Py_buffer vsub; + PyObject *list; + + if (maxsplit < 0) + maxsplit = PY_SSIZE_T_MAX; + if (sep == Py_None) + return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) + return NULL; + sub = vsub.buf; + n = vsub.len; + + list = stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit); + PyBuffer_Release(&vsub); + return list; +} + + +/*[clinic input] +bytes.join + + iterable_of_bytes: object + / + +Concatenate any number of bytes objects. + +The bytes whose method is called is inserted in between each pair. + +The result is returned as a new bytes object. + +Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'. +[clinic start generated code]*/ + +static PyObject * +bytes_join(PyBytesObject *self, PyObject *iterable_of_bytes) +/*[clinic end generated code: output=a046f379f626f6f8 input=7fe377b95bd549d2]*/ +{ + return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); +} + +PyObject * +_PyBytes_Join(PyObject *sep, PyObject *x) +{ + assert(sep != NULL && PyBytes_Check(sep)); + assert(x != NULL); + return bytes_join((PyBytesObject*)sep, x); +} + +static PyObject * +bytes_find(PyBytesObject *self, PyObject *args) +{ + return _Py_bytes_find(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); +} + +static PyObject * +bytes_index(PyBytesObject *self, PyObject *args) +{ + return _Py_bytes_index(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); +} + + +static PyObject * +bytes_rfind(PyBytesObject *self, PyObject *args) +{ + return _Py_bytes_rfind(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); +} + + +static PyObject * +bytes_rindex(PyBytesObject *self, PyObject *args) +{ + return _Py_bytes_rindex(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); +} + + +Py_LOCAL_INLINE(PyObject *) +do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) +{ + Py_buffer vsep; + char *s = PyBytes_AS_STRING(self); + Py_ssize_t len = PyBytes_GET_SIZE(self); + char *sep; + Py_ssize_t seplen; + Py_ssize_t i, j; + + if (PyObject_GetBuffer(sepobj, &vsep, PyBUF_SIMPLE) != 0) + return NULL; + sep = vsep.buf; + seplen = vsep.len; + + i = 0; + if (striptype != RIGHTSTRIP) { + while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) { + i++; + } + } + + j = len; + if (striptype != LEFTSTRIP) { + do { + j--; + } while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen)); + j++; + } + + PyBuffer_Release(&vsep); + + if (i == 0 && j == len && PyBytes_CheckExact(self)) { + Py_INCREF(self); + return (PyObject*)self; + } + else + return PyBytes_FromStringAndSize(s+i, j-i); +} + + +Py_LOCAL_INLINE(PyObject *) +do_strip(PyBytesObject *self, int striptype) +{ + char *s = PyBytes_AS_STRING(self); + Py_ssize_t len = PyBytes_GET_SIZE(self), i, j; + + i = 0; + if (striptype != RIGHTSTRIP) { + while (i < len && Py_ISSPACE(s[i])) { + i++; + } + } + + j = len; + if (striptype != LEFTSTRIP) { + do { + j--; + } while (j >= i && Py_ISSPACE(s[j])); + j++; + } + + if (i == 0 && j == len && PyBytes_CheckExact(self)) { + Py_INCREF(self); + return (PyObject*)self; + } + else + return PyBytes_FromStringAndSize(s+i, j-i); +} + + +Py_LOCAL_INLINE(PyObject *) +do_argstrip(PyBytesObject *self, int striptype, PyObject *bytes) +{ + if (bytes != Py_None) { + return do_xstrip(self, striptype, bytes); + } + return do_strip(self, striptype); +} + +/*[clinic input] +bytes.strip + + bytes: object = None + / + +Strip leading and trailing bytes contained in the argument. + +If the argument is omitted or None, strip leading and trailing ASCII whitespace. +[clinic start generated code]*/ + +static PyObject * +bytes_strip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=c7c228d3bd104a1b input=8a354640e4e0b3ef]*/ +{ + return do_argstrip(self, BOTHSTRIP, bytes); +} + +/*[clinic input] +bytes.lstrip + + bytes: object = None + / + +Strip leading bytes contained in the argument. + +If the argument is omitted or None, strip leading ASCII whitespace. +[clinic start generated code]*/ + +static PyObject * +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=28602e586f524e82 input=9baff4398c3f6857]*/ +{ + return do_argstrip(self, LEFTSTRIP, bytes); +} + +/*[clinic input] +bytes.rstrip + + bytes: object = None + / + +Strip trailing bytes contained in the argument. + +If the argument is omitted or None, strip trailing ASCII whitespace. +[clinic start generated code]*/ + +static PyObject * +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=547e3815c95447da input=b78af445c727e32b]*/ +{ + return do_argstrip(self, RIGHTSTRIP, bytes); +} + + +static PyObject * +bytes_count(PyBytesObject *self, PyObject *args) +{ + return _Py_bytes_count(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); +} + + +/*[clinic input] +bytes.translate + + table: object + Translation table, which must be a bytes object of length 256. + / + delete as deletechars: object(c_default="NULL") = b'' + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument delete are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ + +static PyObject * +bytes_translate_impl(PyBytesObject *self, PyObject *table, + PyObject *deletechars) +/*[clinic end generated code: output=43be3437f1956211 input=0ecdf159f654233c]*/ +{ + char *input, *output; + Py_buffer table_view = {NULL, NULL}; + Py_buffer del_table_view = {NULL, NULL}; + const char *table_chars; + Py_ssize_t i, c, changed = 0; + PyObject *input_obj = (PyObject*)self; + const char *output_start, *del_table_chars=NULL; + Py_ssize_t inlen, tablen, dellen = 0; + PyObject *result; + int trans_table[256]; + + if (PyBytes_Check(table)) { + table_chars = PyBytes_AS_STRING(table); + tablen = PyBytes_GET_SIZE(table); + } + else if (table == Py_None) { + table_chars = NULL; + tablen = 256; + } + else { + if (PyObject_GetBuffer(table, &table_view, PyBUF_SIMPLE) != 0) + return NULL; + table_chars = table_view.buf; + tablen = table_view.len; + } + + if (tablen != 256) { + PyErr_SetString(PyExc_ValueError, + "translation table must be 256 characters long"); + PyBuffer_Release(&table_view); + return NULL; + } + + if (deletechars != NULL) { + if (PyBytes_Check(deletechars)) { + del_table_chars = PyBytes_AS_STRING(deletechars); + dellen = PyBytes_GET_SIZE(deletechars); + } + else { + if (PyObject_GetBuffer(deletechars, &del_table_view, PyBUF_SIMPLE) != 0) { + PyBuffer_Release(&table_view); + return NULL; + } + del_table_chars = del_table_view.buf; + dellen = del_table_view.len; + } + } + else { + del_table_chars = NULL; + dellen = 0; + } + + inlen = PyBytes_GET_SIZE(input_obj); + result = PyBytes_FromStringAndSize((char *)NULL, inlen); + if (result == NULL) { + PyBuffer_Release(&del_table_view); + PyBuffer_Release(&table_view); + return NULL; + } + output_start = output = PyBytes_AS_STRING(result); + input = PyBytes_AS_STRING(input_obj); + + if (dellen == 0 && table_chars != NULL) { + /* If no deletions are required, use faster code */ + for (i = inlen; --i >= 0; ) { + c = Py_CHARMASK(*input++); + if (Py_CHARMASK((*output++ = table_chars[c])) != c) + changed = 1; + } + if (!changed && PyBytes_CheckExact(input_obj)) { + Py_INCREF(input_obj); + Py_DECREF(result); + result = input_obj; + } + PyBuffer_Release(&del_table_view); + PyBuffer_Release(&table_view); + return result; + } + + if (table_chars == NULL) { + for (i = 0; i < 256; i++) + trans_table[i] = Py_CHARMASK(i); + } else { + for (i = 0; i < 256; i++) + trans_table[i] = Py_CHARMASK(table_chars[i]); + } + PyBuffer_Release(&table_view); + + for (i = 0; i < dellen; i++) + trans_table[(int) Py_CHARMASK(del_table_chars[i])] = -1; + PyBuffer_Release(&del_table_view); + + for (i = inlen; --i >= 0; ) { + c = Py_CHARMASK(*input++); + if (trans_table[c] != -1) + if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c) + continue; + changed = 1; + } + if (!changed && PyBytes_CheckExact(input_obj)) { + Py_DECREF(result); + Py_INCREF(input_obj); + return input_obj; + } + /* Fix the size of the resulting string */ + if (inlen > 0) + _PyBytes_Resize(&result, output - output_start); + return result; +} + + +/*[clinic input] + +@staticmethod +bytes.maketrans + + frm: Py_buffer + to: Py_buffer + / + +Return a translation table useable for the bytes or bytearray translate method. + +The returned table will be one where each byte in frm is mapped to the byte at +the same position in to. + +The bytes objects frm and to must be of the same length. +[clinic start generated code]*/ + +static PyObject * +bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to) +/*[clinic end generated code: output=a36f6399d4b77f6f input=de7a8fc5632bb8f1]*/ +{ + return _Py_bytes_maketrans(frm, to); +} + + +/*[clinic input] +bytes.replace + + old: Py_buffer + new: Py_buffer + count: Py_ssize_t = -1 + Maximum number of occurrences to replace. + -1 (the default value) means replace all occurrences. + / + +Return a copy with all occurrences of substring old replaced by new. + +If the optional argument count is given, only the first count occurrences are +replaced. +[clinic start generated code]*/ + +static PyObject * +bytes_replace_impl(PyBytesObject *self, Py_buffer *old, Py_buffer *new, + Py_ssize_t count) +/*[clinic end generated code: output=994fa588b6b9c104 input=b2fbbf0bf04de8e5]*/ +{ + return stringlib_replace((PyObject *)self, + (const char *)old->buf, old->len, + (const char *)new->buf, new->len, count); +} + +/** End DALKE **/ + + +static PyObject * +bytes_startswith(PyBytesObject *self, PyObject *args) +{ + return _Py_bytes_startswith(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); +} + +static PyObject * +bytes_endswith(PyBytesObject *self, PyObject *args) +{ + return _Py_bytes_endswith(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); +} + + +/*[clinic input] +bytes.decode + + encoding: str(c_default="NULL") = 'utf-8' + The encoding with which to decode the bytes. + errors: str(c_default="NULL") = 'strict' + The error handling scheme to use for the handling of decoding errors. + The default is 'strict' meaning that decoding errors raise a + UnicodeDecodeError. Other possible values are 'ignore' and 'replace' + as well as any other name registered with codecs.register_error that + can handle UnicodeDecodeErrors. + +Decode the bytes using the codec registered for encoding. +[clinic start generated code]*/ + +static PyObject * +bytes_decode_impl(PyBytesObject *self, const char *encoding, + const char *errors) +/*[clinic end generated code: output=5649a53dde27b314 input=958174769d2a40ca]*/ +{ + return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors); +} + + +/*[clinic input] +bytes.splitlines + + keepends: bool(accept={int}) = False + +Return a list of the lines in the bytes, breaking at line boundaries. + +Line breaks are not included in the resulting list unless keepends is given and +true. +[clinic start generated code]*/ + +static PyObject * +bytes_splitlines_impl(PyBytesObject *self, int keepends) +/*[clinic end generated code: output=3484149a5d880ffb input=a8b32eb01ff5a5ed]*/ +{ + return stringlib_splitlines( + (PyObject*) self, PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self), keepends + ); +} + +/*[clinic input] +@classmethod +bytes.fromhex + + string: unicode + / + +Create a bytes object from a string of hexadecimal numbers. + +Spaces between two numbers are accepted. +Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'. +[clinic start generated code]*/ + +static PyObject * +bytes_fromhex_impl(PyTypeObject *type, PyObject *string) +/*[clinic end generated code: output=0973acc63661bb2e input=bf4d1c361670acd3]*/ +{ + PyObject *result = _PyBytes_FromHex(string, 0); + if (type != &PyBytes_Type && result != NULL) { + Py_SETREF(result, PyObject_CallFunctionObjArgs((PyObject *)type, + result, NULL)); + } + return result; +} + +PyObject* +_PyBytes_FromHex(PyObject *string, int use_bytearray) +{ + char *buf; + Py_ssize_t hexlen, invalid_char; + unsigned int top, bot; + Py_UCS1 *str, *end; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + writer.use_bytearray = use_bytearray; + + assert(PyUnicode_Check(string)); + if (PyUnicode_READY(string)) + return NULL; + hexlen = PyUnicode_GET_LENGTH(string); + + if (!PyUnicode_IS_ASCII(string)) { + void *data = PyUnicode_DATA(string); + unsigned int kind = PyUnicode_KIND(string); + Py_ssize_t i; + + /* search for the first non-ASCII character */ + for (i = 0; i < hexlen; i++) { + if (PyUnicode_READ(kind, data, i) >= 128) + break; + } + invalid_char = i; + goto error; + } + + assert(PyUnicode_KIND(string) == PyUnicode_1BYTE_KIND); + str = PyUnicode_1BYTE_DATA(string); + + /* This overestimates if there are spaces */ + buf = _PyBytesWriter_Alloc(&writer, hexlen / 2); + if (buf == NULL) + return NULL; + + end = str + hexlen; + while (str < end) { + /* skip over spaces in the input */ + if (Py_ISSPACE(*str)) { + do { + str++; + } while (Py_ISSPACE(*str)); + if (str >= end) + break; + } + + top = _PyLong_DigitValue[*str]; + if (top >= 16) { + invalid_char = str - PyUnicode_1BYTE_DATA(string); + goto error; + } + str++; + + bot = _PyLong_DigitValue[*str]; + if (bot >= 16) { + invalid_char = str - PyUnicode_1BYTE_DATA(string); + goto error; + } + str++; + + *buf++ = (unsigned char)((top << 4) + bot); + } + + return _PyBytesWriter_Finish(&writer, buf); + + error: + PyErr_Format(PyExc_ValueError, + "non-hexadecimal number found in " + "fromhex() arg at position %zd", invalid_char); + _PyBytesWriter_Dealloc(&writer); + return NULL; +} + +/*[clinic input] +bytes.hex + + 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. + +Create a str of hexadecimal numbers from a bytes object. + +Example: +>>> value = b'\xb9\x01\xef' +>>> value.hex() +'b901ef' +>>> value.hex(':') +'b9:01:ef' +>>> value.hex(':', 2) +'b9:01ef' +>>> value.hex(':', -2) +'b901:ef' +[clinic start generated code]*/ + +static PyObject * +bytes_hex_impl(PyBytesObject *self, PyObject *sep, int bytes_per_sep) +/*[clinic end generated code: output=1f134da504064139 input=f1238d3455990218]*/ +{ + char* argbuf = PyBytes_AS_STRING(self); + Py_ssize_t arglen = PyBytes_GET_SIZE(self); + return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep); +} + +static PyObject * +bytes_getnewargs(PyBytesObject *v, PyObject *Py_UNUSED(ignored)) +{ + return Py_BuildValue("(y#)", v->ob_sval, Py_SIZE(v)); +} + + +static PyMethodDef +bytes_methods[] = { + {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, + {"capitalize", stringlib_capitalize, METH_NOARGS, + _Py_capitalize__doc__}, + STRINGLIB_CENTER_METHODDEF + {"count", (PyCFunction)bytes_count, METH_VARARGS, + _Py_count__doc__}, + BYTES_DECODE_METHODDEF + {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, + _Py_endswith__doc__}, + STRINGLIB_EXPANDTABS_METHODDEF + {"find", (PyCFunction)bytes_find, METH_VARARGS, + _Py_find__doc__}, + BYTES_FROMHEX_METHODDEF + BYTES_HEX_METHODDEF + {"index", (PyCFunction)bytes_index, METH_VARARGS, _Py_index__doc__}, + {"isalnum", stringlib_isalnum, METH_NOARGS, + _Py_isalnum__doc__}, + {"isalpha", stringlib_isalpha, METH_NOARGS, + _Py_isalpha__doc__}, + {"isascii", stringlib_isascii, METH_NOARGS, + _Py_isascii__doc__}, + {"isdigit", stringlib_isdigit, METH_NOARGS, + _Py_isdigit__doc__}, + {"islower", stringlib_islower, METH_NOARGS, + _Py_islower__doc__}, + {"isspace", stringlib_isspace, METH_NOARGS, + _Py_isspace__doc__}, + {"istitle", stringlib_istitle, METH_NOARGS, + _Py_istitle__doc__}, + {"isupper", stringlib_isupper, METH_NOARGS, + _Py_isupper__doc__}, + BYTES_JOIN_METHODDEF + STRINGLIB_LJUST_METHODDEF + {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__}, + BYTES_LSTRIP_METHODDEF + BYTES_MAKETRANS_METHODDEF + BYTES_PARTITION_METHODDEF + BYTES_REPLACE_METHODDEF + {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, _Py_rfind__doc__}, + {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, _Py_rindex__doc__}, + STRINGLIB_RJUST_METHODDEF + BYTES_RPARTITION_METHODDEF + BYTES_RSPLIT_METHODDEF + BYTES_RSTRIP_METHODDEF + BYTES_SPLIT_METHODDEF + BYTES_SPLITLINES_METHODDEF + {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, + _Py_startswith__doc__}, + BYTES_STRIP_METHODDEF + {"swapcase", stringlib_swapcase, METH_NOARGS, + _Py_swapcase__doc__}, + {"title", stringlib_title, METH_NOARGS, _Py_title__doc__}, + BYTES_TRANSLATE_METHODDEF + {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__}, + STRINGLIB_ZFILL_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +bytes_mod(PyObject *self, PyObject *arg) +{ + if (!PyBytes_Check(self)) { + Py_RETURN_NOTIMPLEMENTED; + } + return _PyBytes_FormatEx(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + arg, 0); +} + +static PyNumberMethods bytes_as_number = { + 0, /*nb_add*/ + 0, /*nb_subtract*/ + 0, /*nb_multiply*/ + bytes_mod, /*nb_remainder*/ +}; + +static PyObject * +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + +static PyObject * +bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *x = NULL; + const char *encoding = NULL; + const char *errors = NULL; + PyObject *new = NULL; + PyObject *func; + Py_ssize_t size; + static char *kwlist[] = {"source", "encoding", "errors", 0}; + _Py_IDENTIFIER(__bytes__); + + if (type != &PyBytes_Type) + return bytes_subtype_new(type, args, kwds); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, + &encoding, &errors)) + return NULL; + if (x == NULL) { + if (encoding != NULL || errors != NULL) { + PyErr_SetString(PyExc_TypeError, + encoding != NULL ? + "encoding without a string argument" : + "errors without a string argument"); + return NULL; + } + return PyBytes_FromStringAndSize(NULL, 0); + } + + if (encoding != NULL) { + /* Encode via the codec registry */ + if (!PyUnicode_Check(x)) { + PyErr_SetString(PyExc_TypeError, + "encoding without a string argument"); + return NULL; + } + new = PyUnicode_AsEncodedString(x, encoding, errors); + if (new == NULL) + return NULL; + assert(PyBytes_Check(new)); + return new; + } + + if (errors != NULL) { + PyErr_SetString(PyExc_TypeError, + PyUnicode_Check(x) ? + "string argument without an encoding" : + "errors without a string argument"); + return NULL; + } + + /* We'd like to call PyObject_Bytes here, but we need to check for an + integer argument before deferring to PyBytes_FromObject, something + PyObject_Bytes doesn't do. */ + func = _PyObject_LookupSpecial(x, &PyId___bytes__); + if (func != NULL) { + new = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (new == NULL) + return NULL; + if (!PyBytes_Check(new)) { + PyErr_Format(PyExc_TypeError, + "__bytes__ returned non-bytes (type %.200s)", + Py_TYPE(new)->tp_name); + Py_DECREF(new); + return NULL; + } + return new; + } + else if (PyErr_Occurred()) + return NULL; + + if (PyUnicode_Check(x)) { + PyErr_SetString(PyExc_TypeError, + "string argument without an encoding"); + return NULL; + } + /* Is it an integer? */ + if (PyIndex_Check(x)) { + size = PyNumber_AsSsize_t(x, PyExc_OverflowError); + if (size == -1 && PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return NULL; + PyErr_Clear(); /* fall through */ + } + else { + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + new = _PyBytes_FromSize(size, 1); + if (new == NULL) + return NULL; + return new; + } + } + + return PyBytes_FromObject(x); +} + +static PyObject* +_PyBytes_FromBuffer(PyObject *x) +{ + PyObject *new; + Py_buffer view; + + if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0) + return NULL; + + new = PyBytes_FromStringAndSize(NULL, view.len); + if (!new) + goto fail; + if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval, + &view, view.len, 'C') < 0) + goto fail; + PyBuffer_Release(&view); + return new; + +fail: + Py_XDECREF(new); + PyBuffer_Release(&view); + return NULL; +} + +static PyObject* +_PyBytes_FromList(PyObject *x) +{ + Py_ssize_t i, size = PyList_GET_SIZE(x); + Py_ssize_t value; + char *str; + PyObject *item; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + str = _PyBytesWriter_Alloc(&writer, size); + if (str == NULL) + return NULL; + writer.overallocate = 1; + size = writer.allocated; + + for (i = 0; i < PyList_GET_SIZE(x); i++) { + item = PyList_GET_ITEM(x, i); + Py_INCREF(item); + value = PyNumber_AsSsize_t(item, NULL); + Py_DECREF(item); + if (value == -1 && PyErr_Occurred()) + goto error; + + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + goto error; + } + + if (i >= size) { + str = _PyBytesWriter_Resize(&writer, str, size+1); + if (str == NULL) + return NULL; + size = writer.allocated; + } + *str++ = (char) value; + } + return _PyBytesWriter_Finish(&writer, str); + + error: + _PyBytesWriter_Dealloc(&writer); + return NULL; +} + +static PyObject* +_PyBytes_FromTuple(PyObject *x) +{ + PyObject *bytes; + Py_ssize_t i, size = PyTuple_GET_SIZE(x); + Py_ssize_t value; + char *str; + PyObject *item; + + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return NULL; + str = ((PyBytesObject *)bytes)->ob_sval; + + for (i = 0; i < size; i++) { + item = PyTuple_GET_ITEM(x, i); + value = PyNumber_AsSsize_t(item, NULL); + if (value == -1 && PyErr_Occurred()) + goto error; + + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + goto error; + } + *str++ = (char) value; + } + return bytes; + + error: + Py_DECREF(bytes); + return NULL; +} + +static PyObject * +_PyBytes_FromIterator(PyObject *it, PyObject *x) +{ + char *str; + Py_ssize_t i, size; + _PyBytesWriter writer; + + /* For iterator version, create a string object and resize as needed */ + size = PyObject_LengthHint(x, 64); + if (size == -1 && PyErr_Occurred()) + return NULL; + + _PyBytesWriter_Init(&writer); + str = _PyBytesWriter_Alloc(&writer, size); + if (str == NULL) + return NULL; + writer.overallocate = 1; + size = writer.allocated; + + /* Run the iterator to exhaustion */ + for (i = 0; ; i++) { + PyObject *item; + Py_ssize_t value; + + /* Get the next item */ + item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) + goto error; + break; + } + + /* Interpret it as an int (__index__) */ + value = PyNumber_AsSsize_t(item, NULL); + Py_DECREF(item); + if (value == -1 && PyErr_Occurred()) + goto error; + + /* Range check */ + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + goto error; + } + + /* Append the byte */ + if (i >= size) { + str = _PyBytesWriter_Resize(&writer, str, size+1); + if (str == NULL) + return NULL; + size = writer.allocated; + } + *str++ = (char) value; + } + + return _PyBytesWriter_Finish(&writer, str); + + error: + _PyBytesWriter_Dealloc(&writer); + return NULL; +} + +PyObject * +PyBytes_FromObject(PyObject *x) +{ + PyObject *it, *result; + + if (x == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + if (PyBytes_CheckExact(x)) { + Py_INCREF(x); + return x; + } + + /* Use the modern buffer interface */ + if (PyObject_CheckBuffer(x)) + return _PyBytes_FromBuffer(x); + + if (PyList_CheckExact(x)) + return _PyBytes_FromList(x); + + if (PyTuple_CheckExact(x)) + return _PyBytes_FromTuple(x); + + if (!PyUnicode_Check(x)) { + it = PyObject_GetIter(x); + if (it != NULL) { + result = _PyBytes_FromIterator(it, x); + Py_DECREF(it); + return result; + } + if (!PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } + } + + PyErr_Format(PyExc_TypeError, + "cannot convert '%.200s' object to bytes", + x->ob_type->tp_name); + return NULL; +} + +static PyObject * +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *tmp, *pnew; + Py_ssize_t n; + + assert(PyType_IsSubtype(type, &PyBytes_Type)); + tmp = bytes_new(&PyBytes_Type, args, kwds); + if (tmp == NULL) + return NULL; + assert(PyBytes_Check(tmp)); + n = PyBytes_GET_SIZE(tmp); + pnew = type->tp_alloc(type, n); + if (pnew != NULL) { + memcpy(PyBytes_AS_STRING(pnew), + PyBytes_AS_STRING(tmp), n+1); + ((PyBytesObject *)pnew)->ob_shash = + ((PyBytesObject *)tmp)->ob_shash; + } + Py_DECREF(tmp); + return pnew; +} + +PyDoc_STRVAR(bytes_doc, +"bytes(iterable_of_ints) -> bytes\n\ +bytes(string, encoding[, errors]) -> bytes\n\ +bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n\ +bytes(int) -> bytes object of size given by the parameter initialized with null bytes\n\ +bytes() -> empty bytes object\n\ +\n\ +Construct an immutable array of bytes from:\n\ + - an iterable yielding integers in range(256)\n\ + - a text string encoded using the specified encoding\n\ + - any object implementing the buffer API.\n\ + - an integer"); + +static PyObject *bytes_iter(PyObject *seq); + +PyTypeObject PyBytes_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bytes", + PyBytesObject_SIZE, + sizeof(char), + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)bytes_repr, /* tp_repr */ + &bytes_as_number, /* tp_as_number */ + &bytes_as_sequence, /* tp_as_sequence */ + &bytes_as_mapping, /* tp_as_mapping */ + (hashfunc)bytes_hash, /* tp_hash */ + 0, /* tp_call */ + bytes_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &bytes_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_BYTES_SUBCLASS, /* tp_flags */ + bytes_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)bytes_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + bytes_iter, /* tp_iter */ + 0, /* tp_iternext */ + bytes_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + bytes_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + +void +PyBytes_Concat(PyObject **pv, PyObject *w) +{ + assert(pv != NULL); + if (*pv == NULL) + return; + if (w == NULL) { + Py_CLEAR(*pv); + return; + } + + if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) { + /* Only one reference, so we can resize in place */ + Py_ssize_t oldsize; + Py_buffer wb; + + if (PyObject_GetBuffer(w, &wb, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", + Py_TYPE(w)->tp_name, Py_TYPE(*pv)->tp_name); + Py_CLEAR(*pv); + return; + } + + oldsize = PyBytes_GET_SIZE(*pv); + if (oldsize > PY_SSIZE_T_MAX - wb.len) { + PyErr_NoMemory(); + goto error; + } + if (_PyBytes_Resize(pv, oldsize + wb.len) < 0) + goto error; + + memcpy(PyBytes_AS_STRING(*pv) + oldsize, wb.buf, wb.len); + PyBuffer_Release(&wb); + return; + + error: + PyBuffer_Release(&wb); + Py_CLEAR(*pv); + return; + } + + else { + /* Multiple references, need to create new object */ + PyObject *v; + v = bytes_concat(*pv, w); + Py_SETREF(*pv, v); + } +} + +void +PyBytes_ConcatAndDel(PyObject **pv, PyObject *w) +{ + PyBytes_Concat(pv, w); + Py_XDECREF(w); +} + + +/* The following function breaks the notion that bytes are immutable: + it changes the size of a bytes object. We get away with this only if there + is only one module referencing the object. You can also think of it + as creating a new bytes object and destroying the old one, only + more efficiently. In any case, don't use this if the bytes object may + already be known to some other part of the code... + Note that if there's not enough memory to resize the bytes object, the + original bytes object at *pv is deallocated, *pv is set to NULL, an "out of + memory" exception is set, and -1 is returned. Else (on success) 0 is + returned, and the value in *pv may or may not be the same as on input. + As always, an extra byte is allocated for a trailing \0 byte (newsize + does *not* include that), and a trailing \0 byte is stored. +*/ + +int +_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) +{ + PyObject *v; + PyBytesObject *sv; + v = *pv; + if (!PyBytes_Check(v) || newsize < 0) { + goto error; + } + if (Py_SIZE(v) == newsize) { + /* return early if newsize equals to v->ob_size */ + return 0; + } + if (Py_SIZE(v) == 0) { + if (newsize == 0) { + return 0; + } + *pv = _PyBytes_FromSize(newsize, 0); + Py_DECREF(v); + return (*pv == NULL) ? -1 : 0; + } + if (Py_REFCNT(v) != 1) { + goto error; + } + if (newsize == 0) { + *pv = _PyBytes_FromSize(0, 0); + Py_DECREF(v); + return (*pv == NULL) ? -1 : 0; + } + /* XXX UNREF/NEWREF interface should be more symmetrical */ + _Py_DEC_REFTOTAL; + _Py_ForgetReference(v); + *pv = (PyObject *) + PyObject_REALLOC(v, PyBytesObject_SIZE + newsize); + if (*pv == NULL) { + PyObject_Del(v); + PyErr_NoMemory(); + return -1; + } + _Py_NewReference(*pv); + sv = (PyBytesObject *) *pv; + Py_SIZE(sv) = newsize; + sv->ob_sval[newsize] = '\0'; + sv->ob_shash = -1; /* invalidate cached hash value */ + return 0; +error: + *pv = 0; + Py_DECREF(v); + PyErr_BadInternalCall(); + return -1; +} + +void +PyBytes_Fini(void) +{ + int i; + for (i = 0; i < UCHAR_MAX + 1; i++) + Py_CLEAR(characters[i]); + Py_CLEAR(nullstring); +} + +/*********************** Bytes Iterator ****************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyBytesObject *it_seq; /* Set to NULL when iterator is exhausted */ +} striterobject; + +static void +striter_dealloc(striterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +striter_traverse(striterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +striter_next(striterobject *it) +{ + PyBytesObject *seq; + PyObject *item; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) + return NULL; + assert(PyBytes_Check(seq)); + + if (it->it_index < PyBytes_GET_SIZE(seq)) { + item = PyLong_FromLong( + (unsigned char)seq->ob_sval[it->it_index]); + if (item != NULL) + ++it->it_index; + return item; + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +striter_len(striterobject *it, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len = 0; + if (it->it_seq) + len = PyBytes_GET_SIZE(it->it_seq) - it->it_index; + return PyLong_FromSsize_t(len); +} + +PyDoc_STRVAR(length_hint_doc, + "Private method returning an estimate of len(list(it))."); + +static PyObject * +striter_reduce(striterobject *it, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + if (it->it_seq != NULL) { + return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + it->it_seq, it->it_index); + } else { + return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + } +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyObject * +striter_setstate(striterobject *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyBytes_GET_SIZE(it->it_seq)) + index = PyBytes_GET_SIZE(it->it_seq); /* iterator exhausted */ + it->it_index = index; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef striter_methods[] = { + {"__length_hint__", (PyCFunction)striter_len, METH_NOARGS, + length_hint_doc}, + {"__reduce__", (PyCFunction)striter_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)striter_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyBytesIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bytes_iterator", /* tp_name */ + sizeof(striterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)striter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)striter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)striter_next, /* tp_iternext */ + striter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +bytes_iter(PyObject *seq) +{ + striterobject *it; + + if (!PyBytes_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + it = PyObject_GC_New(striterobject, &PyBytesIter_Type); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = (PyBytesObject *)seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} + + +/* _PyBytesWriter API */ + +#ifdef MS_WINDOWS + /* On Windows, overallocate by 50% is the best factor */ +# define OVERALLOCATE_FACTOR 2 +#else + /* On Linux, overallocate by 25% is the best factor */ +# define OVERALLOCATE_FACTOR 4 +#endif + +void +_PyBytesWriter_Init(_PyBytesWriter *writer) +{ + /* Set all attributes before small_buffer to 0 */ + memset(writer, 0, offsetof(_PyBytesWriter, small_buffer)); +#ifndef NDEBUG + memset(writer->small_buffer, PYMEM_CLEANBYTE, + sizeof(writer->small_buffer)); +#endif +} + +void +_PyBytesWriter_Dealloc(_PyBytesWriter *writer) +{ + Py_CLEAR(writer->buffer); +} + +Py_LOCAL_INLINE(char*) +_PyBytesWriter_AsString(_PyBytesWriter *writer) +{ + if (writer->use_small_buffer) { + assert(writer->buffer == NULL); + return writer->small_buffer; + } + else if (writer->use_bytearray) { + assert(writer->buffer != NULL); + return PyByteArray_AS_STRING(writer->buffer); + } + else { + assert(writer->buffer != NULL); + return PyBytes_AS_STRING(writer->buffer); + } +} + +Py_LOCAL_INLINE(Py_ssize_t) +_PyBytesWriter_GetSize(_PyBytesWriter *writer, char *str) +{ + char *start = _PyBytesWriter_AsString(writer); + assert(str != NULL); + assert(str >= start); + assert(str - start <= writer->allocated); + return str - start; +} + +#ifndef NDEBUG +Py_LOCAL_INLINE(int) +_PyBytesWriter_CheckConsistency(_PyBytesWriter *writer, char *str) +{ + char *start, *end; + + if (writer->use_small_buffer) { + assert(writer->buffer == NULL); + } + else { + assert(writer->buffer != NULL); + if (writer->use_bytearray) + assert(PyByteArray_CheckExact(writer->buffer)); + else + assert(PyBytes_CheckExact(writer->buffer)); + assert(Py_REFCNT(writer->buffer) == 1); + } + + if (writer->use_bytearray) { + /* bytearray has its own overallocation algorithm, + writer overallocation must be disabled */ + assert(!writer->overallocate); + } + + assert(0 <= writer->allocated); + assert(0 <= writer->min_size && writer->min_size <= writer->allocated); + /* the last byte must always be null */ + start = _PyBytesWriter_AsString(writer); + assert(start[writer->allocated] == 0); + + end = start + writer->allocated; + assert(str != NULL); + assert(start <= str && str <= end); + return 1; +} +#endif + +void* +_PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size) +{ + Py_ssize_t allocated, pos; + + assert(_PyBytesWriter_CheckConsistency(writer, str)); + assert(writer->allocated < size); + + allocated = size; + if (writer->overallocate + && allocated <= (PY_SSIZE_T_MAX - allocated / OVERALLOCATE_FACTOR)) { + /* overallocate to limit the number of realloc() */ + allocated += allocated / OVERALLOCATE_FACTOR; + } + + pos = _PyBytesWriter_GetSize(writer, str); + if (!writer->use_small_buffer) { + if (writer->use_bytearray) { + if (PyByteArray_Resize(writer->buffer, allocated)) + goto error; + /* writer->allocated can be smaller than writer->buffer->ob_alloc, + but we cannot use ob_alloc because bytes may need to be moved + to use the whole buffer. bytearray uses an internal optimization + to avoid moving or copying bytes when bytes are removed at the + beginning (ex: del bytearray[:1]). */ + } + else { + if (_PyBytes_Resize(&writer->buffer, allocated)) + goto error; + } + } + else { + /* convert from stack buffer to bytes object buffer */ + assert(writer->buffer == NULL); + + if (writer->use_bytearray) + writer->buffer = PyByteArray_FromStringAndSize(NULL, allocated); + else + writer->buffer = PyBytes_FromStringAndSize(NULL, allocated); + if (writer->buffer == NULL) + goto error; + + if (pos != 0) { + char *dest; + if (writer->use_bytearray) + dest = PyByteArray_AS_STRING(writer->buffer); + else + dest = PyBytes_AS_STRING(writer->buffer); + memcpy(dest, + writer->small_buffer, + pos); + } + + writer->use_small_buffer = 0; +#ifndef NDEBUG + memset(writer->small_buffer, PYMEM_CLEANBYTE, + sizeof(writer->small_buffer)); +#endif + } + writer->allocated = allocated; + + str = _PyBytesWriter_AsString(writer) + pos; + assert(_PyBytesWriter_CheckConsistency(writer, str)); + return str; + +error: + _PyBytesWriter_Dealloc(writer); + return NULL; +} + +void* +_PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size) +{ + Py_ssize_t new_min_size; + + assert(_PyBytesWriter_CheckConsistency(writer, str)); + assert(size >= 0); + + if (size == 0) { + /* nothing to do */ + return str; + } + + if (writer->min_size > PY_SSIZE_T_MAX - size) { + PyErr_NoMemory(); + _PyBytesWriter_Dealloc(writer); + return NULL; + } + new_min_size = writer->min_size + size; + + if (new_min_size > writer->allocated) + str = _PyBytesWriter_Resize(writer, str, new_min_size); + + writer->min_size = new_min_size; + return str; +} + +/* Allocate the buffer to write size bytes. + Return the pointer to the beginning of buffer data. + Raise an exception and return NULL on error. */ +void* +_PyBytesWriter_Alloc(_PyBytesWriter *writer, Py_ssize_t size) +{ + /* ensure that _PyBytesWriter_Alloc() is only called once */ + assert(writer->min_size == 0 && writer->buffer == NULL); + assert(size >= 0); + + writer->use_small_buffer = 1; +#ifndef NDEBUG + writer->allocated = sizeof(writer->small_buffer) - 1; + /* In debug mode, don't use the full small buffer because it is less + efficient than bytes and bytearray objects to detect buffer underflow + and buffer overflow. Use 10 bytes of the small buffer to test also + code using the smaller buffer in debug mode. + + Don't modify the _PyBytesWriter structure (use a shorter small buffer) + in debug mode to also be able to detect stack overflow when running + tests in debug mode. The _PyBytesWriter is large (more than 512 bytes), + if Py_EnterRecursiveCall() is not used in deep C callback, we may hit a + stack overflow. */ + writer->allocated = Py_MIN(writer->allocated, 10); + /* _PyBytesWriter_CheckConsistency() requires the last byte to be 0, + to detect buffer overflow */ + writer->small_buffer[writer->allocated] = 0; +#else + writer->allocated = sizeof(writer->small_buffer); +#endif + return _PyBytesWriter_Prepare(writer, writer->small_buffer, size); +} + +PyObject * +_PyBytesWriter_Finish(_PyBytesWriter *writer, void *str) +{ + Py_ssize_t size; + PyObject *result; + + assert(_PyBytesWriter_CheckConsistency(writer, str)); + + size = _PyBytesWriter_GetSize(writer, str); + if (size == 0 && !writer->use_bytearray) { + Py_CLEAR(writer->buffer); + /* Get the empty byte string singleton */ + result = PyBytes_FromStringAndSize(NULL, 0); + } + else if (writer->use_small_buffer) { + if (writer->use_bytearray) { + result = PyByteArray_FromStringAndSize(writer->small_buffer, size); + } + else { + result = PyBytes_FromStringAndSize(writer->small_buffer, size); + } + } + else { + result = writer->buffer; + writer->buffer = NULL; + + if (size != writer->allocated) { + if (writer->use_bytearray) { + if (PyByteArray_Resize(result, size)) { + Py_DECREF(result); + return NULL; + } + } + else { + if (_PyBytes_Resize(&result, size)) { + assert(result == NULL); + return NULL; + } + } + } + } + return result; +} + +void* +_PyBytesWriter_WriteBytes(_PyBytesWriter *writer, void *ptr, + const void *bytes, Py_ssize_t size) +{ + char *str = (char *)ptr; + + str = _PyBytesWriter_Prepare(writer, str, size); + if (str == NULL) + return NULL; + + memcpy(str, bytes, size); + str += size; + + return str; +} diff --git a/python/Objects/call.c b/python/Objects/call.c new file mode 100755 index 0000000..9672be0 --- /dev/null +++ b/python/Objects/call.c @@ -0,0 +1,1354 @@ +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" +#include "frameobject.h" + + +static PyObject * +cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs); + + +static PyObject * +null_error(void) +{ + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_SystemError, + "null argument to internal routine"); + return NULL; +} + + +PyObject* +_Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where) +{ + int err_occurred = (PyErr_Occurred() != NULL); + + assert((callable != NULL) ^ (where != NULL)); + + if (result == NULL) { + if (!err_occurred) { + if (callable) + PyErr_Format(PyExc_SystemError, + "%R returned NULL without setting an error", + callable); + else + PyErr_Format(PyExc_SystemError, + "%s returned NULL without setting an error", + where); +#ifdef Py_DEBUG + /* Ensure that the bug is caught in debug mode */ + Py_FatalError("a function returned NULL without setting an error"); +#endif + return NULL; + } + } + else { + if (err_occurred) { + Py_DECREF(result); + + if (callable) { + _PyErr_FormatFromCause(PyExc_SystemError, + "%R returned a result with an error set", + callable); + } + else { + _PyErr_FormatFromCause(PyExc_SystemError, + "%s returned a result with an error set", + where); + } +#ifdef Py_DEBUG + /* Ensure that the bug is caught in debug mode */ + Py_FatalError("a function returned a result with an error set"); +#endif + return NULL; + } + } + return result; +} + + +/* --- Core PyObject call functions ------------------------------- */ + +PyObject * +_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwargs) +{ + /* _PyObject_FastCallDict() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + assert(callable != NULL); + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + assert(kwargs == NULL || PyDict_Check(kwargs)); + + vectorcallfunc func = _PyVectorcall_Function(callable); + if (func == NULL) { + /* Use tp_call instead */ + return _PyObject_MakeTpCall(callable, args, nargs, kwargs); + } + + PyObject *res; + if (kwargs == NULL) { + res = func(callable, args, nargsf, NULL); + } + else { + PyObject *kwnames; + PyObject *const *newargs; + if (_PyStack_UnpackDict(args, nargs, kwargs, &newargs, &kwnames) < 0) { + return NULL; + } + res = func(callable, newargs, nargs, kwnames); + if (kwnames != NULL) { + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames) + nargs; + for (i = 0; i < n; i++) { + Py_DECREF(newargs[i]); + } + PyMem_Free((PyObject **)newargs); + Py_DECREF(kwnames); + } + } + return _Py_CheckFunctionResult(callable, res, NULL); +} + + +PyObject * +_PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) +{ + /* Slow path: build a temporary tuple for positional arguments and a + * temporary dictionary for keyword arguments (if any) */ + ternaryfunc call = Py_TYPE(callable)->tp_call; + if (call == NULL) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", + Py_TYPE(callable)->tp_name); + return NULL; + } + + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); + PyObject *argstuple = _PyTuple_FromArray(args, nargs); + if (argstuple == NULL) { + return NULL; + } + + PyObject *kwdict; + if (keywords == NULL || PyDict_Check(keywords)) { + kwdict = keywords; + } + else { + if (PyTuple_GET_SIZE(keywords)) { + assert(args != NULL); + kwdict = _PyStack_AsDict(args + nargs, keywords); + if (kwdict == NULL) { + Py_DECREF(argstuple); + return NULL; + } + } + else { + keywords = kwdict = NULL; + } + } + + PyObject *result = NULL; + if (Py_EnterRecursiveCall(" while calling a Python object") == 0) + { + result = call(callable, argstuple, kwdict); + Py_LeaveRecursiveCall(); + } + + Py_DECREF(argstuple); + if (kwdict != keywords) { + Py_DECREF(kwdict); + } + + result = _Py_CheckFunctionResult(callable, result, NULL); + return result; +} + + +PyObject * +PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) +{ + /* get vectorcallfunc as in _PyVectorcall_Function, but without + * the _Py_TPFLAGS_HAVE_VECTORCALL check */ + vectorcallfunc func; + Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; + if (offset <= 0) { + PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", + Py_TYPE(callable)->tp_name); + return NULL; + } + memcpy(&func, (char *) callable + offset, sizeof(func)); + if (func == NULL) { + PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", + Py_TYPE(callable)->tp_name); + return NULL; + } + + /* Convert arguments & call */ + PyObject *const *args; + Py_ssize_t nargs = PyTuple_GET_SIZE(tuple); + PyObject *kwnames; + if (_PyStack_UnpackDict(_PyTuple_ITEMS(tuple), nargs, + kwargs, &args, &kwnames) < 0) { + return NULL; + } + PyObject *result = func(callable, args, nargs, kwnames); + if (kwnames != NULL) { + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames) + nargs; + for (i = 0; i < n; i++) { + Py_DECREF(args[i]); + } + PyMem_Free((PyObject **)args); + Py_DECREF(kwnames); + } + + return _Py_CheckFunctionResult(callable, result, NULL); +} + + +PyObject * +PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) +{ + ternaryfunc call; + PyObject *result; + + /* PyObject_Call() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + assert(PyTuple_Check(args)); + assert(kwargs == NULL || PyDict_Check(kwargs)); + + if (_PyVectorcall_Function(callable) != NULL) { + return PyVectorcall_Call(callable, args, kwargs); + } + else if (PyCFunction_Check(callable)) { + /* This must be a METH_VARARGS function, otherwise we would be + * in the previous case */ + return cfunction_call_varargs(callable, args, kwargs); + } + else { + call = callable->ob_type->tp_call; + if (call == NULL) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", + callable->ob_type->tp_name); + return NULL; + } + + if (Py_EnterRecursiveCall(" while calling a Python object")) + return NULL; + + result = (*call)(callable, args, kwargs); + + Py_LeaveRecursiveCall(); + + return _Py_CheckFunctionResult(callable, result, NULL); + } +} + + +/* --- PyFunction call functions ---------------------------------- */ + +static PyObject* _Py_HOT_FUNCTION +function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs, + PyObject *globals) +{ + PyFrameObject *f; + PyThreadState *tstate = _PyThreadState_GET(); + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + _PyFrame_New_NoTrack() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = _PyFrame_New_NoTrack(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + + fastlocals = f->f_localsplus; + + for (i = 0; i < nargs; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + + if (Py_REFCNT(f) > 1) { + Py_DECREF(f); + _PyObject_GC_TRACK(f); + } + else { + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + } + return result; +} + + +PyObject * +_PyFunction_FastCallDict(PyObject *func, PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs) +{ + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *kwdefs, *closure, *name, *qualname; + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd, nk; + PyObject *result; + + assert(func != NULL); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + assert(kwargs == NULL || PyDict_Check(kwargs)); + + if (co->co_kwonlyargcount == 0 && + (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) && + (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) + { + /* Fast paths */ + if (argdefs == NULL && co->co_argcount == nargs) { + return function_code_fastcall(co, args, nargs, globals); + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = _PyTuple_ITEMS(argdefs); + return function_code_fastcall(co, args, PyTuple_GET_SIZE(argdefs), + globals); + } + } + + nk = (kwargs != NULL) ? PyDict_GET_SIZE(kwargs) : 0; + if (nk != 0) { + Py_ssize_t pos, i; + + /* bpo-29318, bpo-27840: Caller and callee functions must not share + the dictionary: kwargs must be copied. */ + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + return NULL; + } + + k = _PyTuple_ITEMS(kwtuple); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + /* We must hold strong references because keyword arguments can be + indirectly modified while the function is called: + see issue #2016 and test_extcall */ + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + assert(i / 2 == nk); + } + else { + kwtuple = NULL; + k = NULL; + } + + kwdefs = PyFunction_GET_KW_DEFAULTS(func); + closure = PyFunction_GET_CLOSURE(func); + name = ((PyFunctionObject *)func) -> func_name; + qualname = ((PyFunctionObject *)func) -> func_qualname; + + if (argdefs != NULL) { + d = _PyTuple_ITEMS(argdefs); + nd = PyTuple_GET_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } + + result = _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL, + args, nargs, + k, k != NULL ? k + 1 : NULL, nk, 2, + d, nd, kwdefs, + closure, name, qualname); + Py_XDECREF(kwtuple); + return result; +} + + +PyObject * +_PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, + size_t nargsf, PyObject *kwnames) +{ + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *kwdefs, *closure, *name, *qualname; + PyObject **d; + Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); + Py_ssize_t nd; + + assert(PyFunction_Check(func)); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + assert(nargs >= 0); + assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); + assert((nargs == 0 && nkwargs == 0) || stack != NULL); + /* kwnames must only contains str strings, no subclass, and all keys must + be unique */ + + if (co->co_kwonlyargcount == 0 && nkwargs == 0 && + (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) + { + if (argdefs == NULL && co->co_argcount == nargs) { + return function_code_fastcall(co, stack, nargs, globals); + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + stack = _PyTuple_ITEMS(argdefs); + return function_code_fastcall(co, stack, PyTuple_GET_SIZE(argdefs), + globals); + } + } + + kwdefs = PyFunction_GET_KW_DEFAULTS(func); + closure = PyFunction_GET_CLOSURE(func); + name = ((PyFunctionObject *)func) -> func_name; + qualname = ((PyFunctionObject *)func) -> func_qualname; + + if (argdefs != NULL) { + d = _PyTuple_ITEMS(argdefs); + nd = PyTuple_GET_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } + return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL, + stack, nargs, + nkwargs ? _PyTuple_ITEMS(kwnames) : NULL, + stack + nargs, + nkwargs, 1, + d, (int)nd, kwdefs, + closure, name, qualname); +} + + +/* --- PyCFunction call functions --------------------------------- */ + +PyObject * +_PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs) +{ + /* _PyMethodDef_RawFastCallDict() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + + assert(method != NULL); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + assert(kwargs == NULL || PyDict_Check(kwargs)); + + PyCFunction meth = method->ml_meth; + int flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST); + PyObject *result = NULL; + + if (Py_EnterRecursiveCall(" while calling a Python object")) { + return NULL; + } + + switch (flags) + { + case METH_NOARGS: + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + goto no_keyword_error; + } + + if (nargs != 0) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", + method->ml_name, nargs); + goto exit; + } + + result = (*meth) (self, NULL); + break; + + case METH_O: + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + goto no_keyword_error; + } + + if (nargs != 1) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + method->ml_name, nargs); + goto exit; + } + + result = (*meth) (self, args[0]); + break; + + case METH_VARARGS: + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + goto no_keyword_error; + } + /* fall through */ + + case METH_VARARGS | METH_KEYWORDS: + { + /* Slow-path: create a temporary tuple for positional arguments */ + PyObject *argstuple = _PyTuple_FromArray(args, nargs); + if (argstuple == NULL) { + goto exit; + } + + if (flags & METH_KEYWORDS) { + result = (*(PyCFunctionWithKeywords)(void(*)(void))meth) (self, argstuple, kwargs); + } + else { + result = (*meth) (self, argstuple); + } + Py_DECREF(argstuple); + break; + } + + case METH_FASTCALL: + { + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + goto no_keyword_error; + } + + result = (*(_PyCFunctionFast)(void(*)(void))meth) (self, args, nargs); + break; + } + + case METH_FASTCALL | METH_KEYWORDS: + { + PyObject *const *stack; + PyObject *kwnames; + _PyCFunctionFastWithKeywords fastmeth = (_PyCFunctionFastWithKeywords)(void(*)(void))meth; + + if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) { + goto exit; + } + + result = (*fastmeth) (self, stack, nargs, kwnames); + if (kwnames != NULL) { + Py_ssize_t i, n = nargs + PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) { + Py_DECREF(stack[i]); + } + PyMem_Free((PyObject **)stack); + Py_DECREF(kwnames); + } + break; + } + + default: + PyErr_SetString(PyExc_SystemError, + "Bad call flags in _PyMethodDef_RawFastCallDict. " + "METH_OLDARGS is no longer supported!"); + goto exit; + } + + goto exit; + +no_keyword_error: + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", + method->ml_name); + +exit: + Py_LeaveRecursiveCall(); + return result; +} + + +PyObject * +_PyCFunction_FastCallDict(PyObject *func, + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs) +{ + PyObject *result; + + assert(func != NULL); + assert(PyCFunction_Check(func)); + + result = _PyMethodDef_RawFastCallDict(((PyCFunctionObject*)func)->m_ml, + PyCFunction_GET_SELF(func), + args, nargs, kwargs); + result = _Py_CheckFunctionResult(func, result, NULL); + return result; +} + + +PyObject * +_PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwnames) +{ + /* _PyMethodDef_RawFastCallKeywords() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + + assert(method != NULL); + assert(nargs >= 0); + assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); + /* kwnames must only contains str strings, no subclass, and all keys must + be unique */ + + PyCFunction meth = method->ml_meth; + int flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST); + Py_ssize_t nkwargs = kwnames == NULL ? 0 : PyTuple_GET_SIZE(kwnames); + PyObject *result = NULL; + + if (Py_EnterRecursiveCall(" while calling a Python object")) { + return NULL; + } + + switch (flags) + { + case METH_NOARGS: + if (nkwargs) { + goto no_keyword_error; + } + + if (nargs != 0) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", + method->ml_name, nargs); + goto exit; + } + + result = (*meth) (self, NULL); + break; + + case METH_O: + if (nkwargs) { + goto no_keyword_error; + } + + if (nargs != 1) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + method->ml_name, nargs); + goto exit; + } + + result = (*meth) (self, args[0]); + break; + + case METH_FASTCALL: + if (nkwargs) { + goto no_keyword_error; + } + result = ((_PyCFunctionFast)(void(*)(void))meth) (self, args, nargs); + break; + + case METH_FASTCALL | METH_KEYWORDS: + /* Fast-path: avoid temporary dict to pass keyword arguments */ + result = ((_PyCFunctionFastWithKeywords)(void(*)(void))meth) (self, args, nargs, kwnames); + break; + + case METH_VARARGS: + if (nkwargs) { + goto no_keyword_error; + } + /* fall through */ + + case METH_VARARGS | METH_KEYWORDS: + { + /* Slow-path: create a temporary tuple for positional arguments + and a temporary dict for keyword arguments */ + PyObject *argtuple; + + argtuple = _PyTuple_FromArray(args, nargs); + if (argtuple == NULL) { + goto exit; + } + + if (flags & METH_KEYWORDS) { + PyObject *kwdict; + + if (nkwargs > 0) { + kwdict = _PyStack_AsDict(args + nargs, kwnames); + if (kwdict == NULL) { + Py_DECREF(argtuple); + goto exit; + } + } + else { + kwdict = NULL; + } + + result = (*(PyCFunctionWithKeywords)(void(*)(void))meth) (self, argtuple, kwdict); + Py_XDECREF(kwdict); + } + else { + result = (*meth) (self, argtuple); + } + Py_DECREF(argtuple); + break; + } + + default: + PyErr_SetString(PyExc_SystemError, + "Bad call flags in _PyMethodDef_RawFastCallKeywords. " + "METH_OLDARGS is no longer supported!"); + goto exit; + } + + goto exit; + +no_keyword_error: + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", + method->ml_name); + +exit: + Py_LeaveRecursiveCall(); + return result; +} + + +static PyObject * +cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs) +{ + assert(!PyErr_Occurred()); + assert(kwargs == NULL || PyDict_Check(kwargs)); + + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + PyObject *result; + + assert(PyCFunction_GET_FLAGS(func) & METH_VARARGS); + if (PyCFunction_GET_FLAGS(func) & METH_KEYWORDS) { + if (Py_EnterRecursiveCall(" while calling a Python object")) { + return NULL; + } + + result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs); + + Py_LeaveRecursiveCall(); + } + else { + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + ((PyCFunctionObject*)func)->m_ml->ml_name); + return NULL; + } + + if (Py_EnterRecursiveCall(" while calling a Python object")) { + return NULL; + } + + result = (*meth)(self, args); + + Py_LeaveRecursiveCall(); + } + + return _Py_CheckFunctionResult(func, result, NULL); +} + + +PyObject * +PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs) +{ + /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer + * is NULL. This is intentional, since vectorcall would be slower. */ + if (PyCFunction_GET_FLAGS(func) & METH_VARARGS) { + return cfunction_call_varargs(func, args, kwargs); + } + return PyVectorcall_Call(func, args, kwargs); +} + + +/* --- More complex call functions -------------------------------- */ + +/* External interface to call any callable object. + The args must be a tuple or NULL. The kwargs must be a dict or NULL. */ +PyObject * +PyEval_CallObjectWithKeywords(PyObject *callable, + PyObject *args, PyObject *kwargs) +{ +#ifdef Py_DEBUG + /* PyEval_CallObjectWithKeywords() must not be called with an exception + set. It raises a new exception if parameters are invalid or if + PyTuple_New() fails, and so the original exception is lost. */ + assert(!PyErr_Occurred()); +#endif + + if (args != NULL && !PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "argument list must be a tuple"); + return NULL; + } + + if (kwargs != NULL && !PyDict_Check(kwargs)) { + PyErr_SetString(PyExc_TypeError, + "keyword list must be a dictionary"); + return NULL; + } + + if (args == NULL) { + return _PyObject_FastCallDict(callable, NULL, 0, kwargs); + } + else { + return PyObject_Call(callable, args, kwargs); + } +} + + +PyObject * +PyObject_CallObject(PyObject *callable, PyObject *args) +{ + return PyEval_CallObjectWithKeywords(callable, args, NULL); +} + + +/* Positional arguments are obj followed by args: + call callable(obj, *args, **kwargs) */ +PyObject * +_PyObject_FastCall_Prepend(PyObject *callable, PyObject *obj, + PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject **args2; + PyObject *result; + + nargs++; + if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { + args2 = small_stack; + } + else { + args2 = PyMem_Malloc(nargs * sizeof(PyObject *)); + if (args2 == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + + /* use borrowed references */ + args2[0] = obj; + if (nargs > 1) { + memcpy(&args2[1], args, (nargs - 1) * sizeof(PyObject *)); + } + + result = _PyObject_FastCall(callable, args2, nargs); + if (args2 != small_stack) { + PyMem_Free(args2); + } + return result; +} + + +/* Call callable(obj, *args, **kwargs). */ +PyObject * +_PyObject_Call_Prepend(PyObject *callable, + PyObject *obj, PyObject *args, PyObject *kwargs) +{ + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject **stack; + Py_ssize_t argcount; + PyObject *result; + + assert(PyTuple_Check(args)); + + argcount = PyTuple_GET_SIZE(args); + if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { + stack = small_stack; + } + else { + stack = PyMem_Malloc((argcount + 1) * sizeof(PyObject *)); + if (stack == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + + /* use borrowed references */ + stack[0] = obj; + memcpy(&stack[1], + _PyTuple_ITEMS(args), + argcount * sizeof(PyObject *)); + + result = _PyObject_FastCallDict(callable, + stack, argcount + 1, + kwargs); + if (stack != small_stack) { + PyMem_Free(stack); + } + return result; +} + + +/* --- Call with a format string ---------------------------------- */ + +static PyObject * +_PyObject_CallFunctionVa(PyObject *callable, const char *format, + va_list va, int is_size_t) +{ + PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; + const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); + PyObject **stack; + Py_ssize_t nargs, i; + PyObject *result; + + if (callable == NULL) { + return null_error(); + } + + if (!format || !*format) { + return _PyObject_CallNoArg(callable); + } + + if (is_size_t) { + stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, + format, va, &nargs); + } + else { + stack = _Py_VaBuildStack(small_stack, small_stack_len, + format, va, &nargs); + } + if (stack == NULL) { + return NULL; + } + + if (nargs == 1 && PyTuple_Check(stack[0])) { + /* Special cases for backward compatibility: + - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) + - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls + func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */ + PyObject *args = stack[0]; + result = _PyObject_FastCall(callable, + _PyTuple_ITEMS(args), + PyTuple_GET_SIZE(args)); + } + else { + result = _PyObject_FastCall(callable, stack, nargs); + } + + for (i = 0; i < nargs; ++i) { + Py_DECREF(stack[i]); + } + if (stack != small_stack) { + PyMem_Free(stack); + } + return result; +} + + +PyObject * +PyObject_CallFunction(PyObject *callable, const char *format, ...) +{ + va_list va; + PyObject *result; + + va_start(va, format); + result = _PyObject_CallFunctionVa(callable, format, va, 0); + va_end(va); + + return result; +} + + +/* PyEval_CallFunction is exact copy of PyObject_CallFunction. + * This function is kept for backward compatibility. + */ +PyObject * +PyEval_CallFunction(PyObject *callable, const char *format, ...) +{ + va_list va; + PyObject *result; + + va_start(va, format); + result = _PyObject_CallFunctionVa(callable, format, va, 0); + va_end(va); + + return result; +} + + +PyObject * +_PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) +{ + va_list va; + PyObject *result; + + va_start(va, format); + result = _PyObject_CallFunctionVa(callable, format, va, 1); + va_end(va); + + return result; +} + + +static PyObject* +callmethod(PyObject* callable, const char *format, va_list va, int is_size_t) +{ + assert(callable != NULL); + + if (!PyCallable_Check(callable)) { + PyErr_Format(PyExc_TypeError, + "attribute of type '%.200s' is not callable", + Py_TYPE(callable)->tp_name); + return NULL; + } + + return _PyObject_CallFunctionVa(callable, format, va, is_size_t); +} + + +PyObject * +PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) +{ + va_list va; + PyObject *callable, *retval; + + if (obj == NULL || name == NULL) { + return null_error(); + } + + callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) + return NULL; + + va_start(va, format); + retval = callmethod(callable, format, va, 0); + va_end(va); + + Py_DECREF(callable); + return retval; +} + + +/* PyEval_CallMethod is exact copy of PyObject_CallMethod. + * This function is kept for backward compatibility. + */ +PyObject * +PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) +{ + va_list va; + PyObject *callable, *retval; + + if (obj == NULL || name == NULL) { + return null_error(); + } + + callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) + return NULL; + + va_start(va, format); + retval = callmethod(callable, format, va, 0); + va_end(va); + + Py_DECREF(callable); + return retval; +} + + +PyObject * +_PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, + const char *format, ...) +{ + va_list va; + PyObject *callable, *retval; + + if (obj == NULL || name == NULL) { + return null_error(); + } + + callable = _PyObject_GetAttrId(obj, name); + if (callable == NULL) + return NULL; + + va_start(va, format); + retval = callmethod(callable, format, va, 0); + va_end(va); + + Py_DECREF(callable); + return retval; +} + + +PyObject * +_PyObject_CallMethod_SizeT(PyObject *obj, const char *name, + const char *format, ...) +{ + va_list va; + PyObject *callable, *retval; + + if (obj == NULL || name == NULL) { + return null_error(); + } + + callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) + return NULL; + + va_start(va, format); + retval = callmethod(callable, format, va, 1); + va_end(va); + + Py_DECREF(callable); + return retval; +} + + +PyObject * +_PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, + const char *format, ...) +{ + va_list va; + PyObject *callable, *retval; + + if (obj == NULL || name == NULL) { + return null_error(); + } + + callable = _PyObject_GetAttrId(obj, name); + if (callable == NULL) { + return NULL; + } + + va_start(va, format); + retval = callmethod(callable, format, va, 1); + va_end(va); + + Py_DECREF(callable); + return retval; +} + + +/* --- Call with "..." arguments ---------------------------------- */ + +static PyObject * +object_vacall(PyObject *base, PyObject *callable, va_list vargs) +{ + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject **stack; + Py_ssize_t nargs; + PyObject *result; + Py_ssize_t i; + va_list countva; + + if (callable == NULL) { + return null_error(); + } + + /* Count the number of arguments */ + va_copy(countva, vargs); + nargs = base ? 1 : 0; + while (1) { + PyObject *arg = va_arg(countva, PyObject *); + if (arg == NULL) { + break; + } + nargs++; + } + va_end(countva); + + /* Copy arguments */ + if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { + stack = small_stack; + } + else { + stack = PyMem_Malloc(nargs * sizeof(stack[0])); + if (stack == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + + i = 0; + if (base) { + stack[i++] = base; + } + + for (; i < nargs; ++i) { + stack[i] = va_arg(vargs, PyObject *); + } + + /* Call the function */ + result = _PyObject_FastCall(callable, stack, nargs); + + if (stack != small_stack) { + PyMem_Free(stack); + } + return result; +} + + +/* Private API for the LOAD_METHOD opcode. */ +extern int _PyObject_GetMethod(PyObject *, PyObject *, PyObject **); + +PyObject * +PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) +{ + if (obj == NULL || name == NULL) { + return null_error(); + } + + PyObject *callable = NULL; + int is_method = _PyObject_GetMethod(obj, name, &callable); + if (callable == NULL) { + return NULL; + } + obj = is_method ? obj : NULL; + + va_list vargs; + va_start(vargs, name); + PyObject *result = object_vacall(obj, callable, vargs); + va_end(vargs); + + Py_DECREF(callable); + return result; +} + + +PyObject * +_PyObject_CallMethodIdObjArgs(PyObject *obj, + struct _Py_Identifier *name, ...) +{ + if (obj == NULL || name == NULL) { + return null_error(); + } + + PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ + if (!oname) { + return NULL; + } + + PyObject *callable = NULL; + int is_method = _PyObject_GetMethod(obj, oname, &callable); + if (callable == NULL) { + return NULL; + } + obj = is_method ? obj : NULL; + + va_list vargs; + va_start(vargs, name); + PyObject *result = object_vacall(obj, callable, vargs); + va_end(vargs); + + Py_DECREF(callable); + return result; +} + + +PyObject * +PyObject_CallFunctionObjArgs(PyObject *callable, ...) +{ + va_list vargs; + PyObject *result; + + va_start(vargs, callable); + result = object_vacall(NULL, callable, vargs); + va_end(vargs); + + return result; +} + + +/* --- PyStack functions ------------------------------------------ */ + +PyObject * +_PyStack_AsDict(PyObject *const *values, PyObject *kwnames) +{ + Py_ssize_t nkwargs; + PyObject *kwdict; + Py_ssize_t i; + + assert(kwnames != NULL); + nkwargs = PyTuple_GET_SIZE(kwnames); + kwdict = _PyDict_NewPresized(nkwargs); + if (kwdict == NULL) { + return NULL; + } + + for (i = 0; i < nkwargs; i++) { + PyObject *key = PyTuple_GET_ITEM(kwnames, i); + PyObject *value = *values++; + /* If key already exists, replace it with the new value */ + if (PyDict_SetItem(kwdict, key, value)) { + Py_DECREF(kwdict); + return NULL; + } + } + return kwdict; +} + + +int +_PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, + PyObject *const **p_stack, PyObject **p_kwnames) +{ + PyObject **stack, **kwstack; + Py_ssize_t nkwargs; + Py_ssize_t pos, i; + PyObject *key, *value; + PyObject *kwnames; + + assert(nargs >= 0); + assert(kwargs == NULL || PyDict_CheckExact(kwargs)); + + if (kwargs == NULL || (nkwargs = PyDict_GET_SIZE(kwargs)) == 0) { + *p_stack = args; + *p_kwnames = NULL; + return 0; + } + + if ((size_t)nargs > PY_SSIZE_T_MAX / sizeof(stack[0]) - (size_t)nkwargs) { + PyErr_NoMemory(); + return -1; + } + + stack = PyMem_Malloc((nargs + nkwargs) * sizeof(stack[0])); + if (stack == NULL) { + PyErr_NoMemory(); + return -1; + } + + kwnames = PyTuple_New(nkwargs); + if (kwnames == NULL) { + PyMem_Free(stack); + return -1; + } + + /* Copy positional arguments */ + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + stack[i] = args[i]; + } + + kwstack = stack + nargs; + pos = i = 0; + /* This loop doesn't support lookup function mutating the dictionary + to change its size. It's a deliberate choice for speed, this function is + called in the performance critical hot code. */ + while (PyDict_Next(kwargs, &pos, &key, &value)) { + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwstack[i] = value; + i++; + } + + *p_stack = stack; + *p_kwnames = kwnames; + return 0; +} diff --git a/python/Objects/capsule.c b/python/Objects/capsule.c new file mode 100755 index 0000000..599893a --- /dev/null +++ b/python/Objects/capsule.c @@ -0,0 +1,324 @@ +/* Wrap void * pointers to be passed between C modules */ + +#include "Python.h" + +/* Internal structure of PyCapsule */ +typedef struct { + PyObject_HEAD + void *pointer; + const char *name; + void *context; + PyCapsule_Destructor destructor; +} PyCapsule; + + + +static int +_is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule) +{ + if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) { + PyErr_SetString(PyExc_ValueError, invalid_capsule); + return 0; + } + return 1; +} + +#define is_legal_capsule(capsule, name) \ + (_is_legal_capsule(capsule, \ + name " called with invalid PyCapsule object")) + + +static int +name_matches(const char *name1, const char *name2) { + /* if either is NULL, */ + if (!name1 || !name2) { + /* they're only the same if they're both NULL. */ + return name1 == name2; + } + return !strcmp(name1, name2); +} + + + +PyObject * +PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor) +{ + PyCapsule *capsule; + + if (!pointer) { + PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer"); + return NULL; + } + + capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type); + if (capsule == NULL) { + return NULL; + } + + capsule->pointer = pointer; + capsule->name = name; + capsule->context = NULL; + capsule->destructor = destructor; + + return (PyObject *)capsule; +} + + +int +PyCapsule_IsValid(PyObject *o, const char *name) +{ + PyCapsule *capsule = (PyCapsule *)o; + + return (capsule != NULL && + PyCapsule_CheckExact(capsule) && + capsule->pointer != NULL && + name_matches(capsule->name, name)); +} + + +void * +PyCapsule_GetPointer(PyObject *o, const char *name) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) { + return NULL; + } + + if (!name_matches(name, capsule->name)) { + PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name"); + return NULL; + } + + return capsule->pointer; +} + + +const char * +PyCapsule_GetName(PyObject *o) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!is_legal_capsule(capsule, "PyCapsule_GetName")) { + return NULL; + } + return capsule->name; +} + + +PyCapsule_Destructor +PyCapsule_GetDestructor(PyObject *o) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) { + return NULL; + } + return capsule->destructor; +} + + +void * +PyCapsule_GetContext(PyObject *o) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) { + return NULL; + } + return capsule->context; +} + + +int +PyCapsule_SetPointer(PyObject *o, void *pointer) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!pointer) { + PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer"); + return -1; + } + + if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) { + return -1; + } + + capsule->pointer = pointer; + return 0; +} + + +int +PyCapsule_SetName(PyObject *o, const char *name) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!is_legal_capsule(capsule, "PyCapsule_SetName")) { + return -1; + } + + capsule->name = name; + return 0; +} + + +int +PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) { + return -1; + } + + capsule->destructor = destructor; + return 0; +} + + +int +PyCapsule_SetContext(PyObject *o, void *context) +{ + PyCapsule *capsule = (PyCapsule *)o; + + if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) { + return -1; + } + + capsule->context = context; + return 0; +} + + +void * +PyCapsule_Import(const char *name, int no_block) +{ + PyObject *object = NULL; + void *return_value = NULL; + char *trace; + size_t name_length = (strlen(name) + 1) * sizeof(char); + char *name_dup = (char *)PyMem_MALLOC(name_length); + + if (!name_dup) { + return PyErr_NoMemory(); + } + + memcpy(name_dup, name, name_length); + + trace = name_dup; + while (trace) { + char *dot = strchr(trace, '.'); + if (dot) { + *dot++ = '\0'; + } + + if (object == NULL) { + if (no_block) { + object = PyImport_ImportModuleNoBlock(trace); + } else { + object = PyImport_ImportModule(trace); + if (!object) { + PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace); + } + } + } else { + PyObject *object2 = PyObject_GetAttrString(object, trace); + Py_DECREF(object); + object = object2; + } + if (!object) { + goto EXIT; + } + + trace = dot; + } + + /* compare attribute name to module.name by hand */ + if (PyCapsule_IsValid(object, name)) { + PyCapsule *capsule = (PyCapsule *)object; + return_value = capsule->pointer; + } else { + PyErr_Format(PyExc_AttributeError, + "PyCapsule_Import \"%s\" is not valid", + name); + } + +EXIT: + Py_XDECREF(object); + if (name_dup) { + PyMem_FREE(name_dup); + } + return return_value; +} + + +static void +capsule_dealloc(PyObject *o) +{ + PyCapsule *capsule = (PyCapsule *)o; + if (capsule->destructor) { + capsule->destructor(o); + } + PyObject_DEL(o); +} + + +static PyObject * +capsule_repr(PyObject *o) +{ + PyCapsule *capsule = (PyCapsule *)o; + const char *name; + const char *quote; + + if (capsule->name) { + quote = "\""; + name = capsule->name; + } else { + quote = ""; + name = "NULL"; + } + + return PyUnicode_FromFormat("", + quote, name, quote, capsule); +} + + + +PyDoc_STRVAR(PyCapsule_Type__doc__, +"Capsule objects let you wrap a C \"void *\" pointer in a Python\n\ +object. They're a way of passing data through the Python interpreter\n\ +without creating your own custom type.\n\ +\n\ +Capsules are used for communication between extension modules.\n\ +They provide a way for an extension module to export a C interface\n\ +to other extension modules, so that extension modules can use the\n\ +Python import mechanism to link to one another.\n\ +"); + +PyTypeObject PyCapsule_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "PyCapsule", /*tp_name*/ + sizeof(PyCapsule), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + capsule_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + capsule_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + 0, /*tp_flags*/ + PyCapsule_Type__doc__ /*tp_doc*/ +}; + + diff --git a/python/Objects/cellobject.c b/python/Objects/cellobject.c new file mode 100755 index 0000000..911cf52 --- /dev/null +++ b/python/Objects/cellobject.c @@ -0,0 +1,199 @@ +/* Cell object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" + +PyObject * +PyCell_New(PyObject *obj) +{ + PyCellObject *op; + + op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type); + if (op == NULL) + return NULL; + op->ob_ref = obj; + Py_XINCREF(obj); + + _PyObject_GC_TRACK(op); + return (PyObject *)op; +} + +PyDoc_STRVAR(cell_new_doc, +"cell([contents])\n" +"--\n" +"\n" +"Create a new cell object.\n" +"\n" +" contents\n" +" the contents of the cell. If not specified, the cell will be empty,\n" +" and \n further attempts to access its cell_contents attribute will\n" +" raise a ValueError."); + + +static PyObject * +cell_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *obj = NULL; + + if (!_PyArg_NoKeywords("cell", kwargs)) { + goto exit; + } + /* min = 0: we allow the cell to be empty */ + if (!PyArg_UnpackTuple(args, "cell", 0, 1, &obj)) { + goto exit; + } + return_value = PyCell_New(obj); + +exit: + return return_value; +} + +PyObject * +PyCell_Get(PyObject *op) +{ + if (!PyCell_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + Py_XINCREF(((PyCellObject*)op)->ob_ref); + return PyCell_GET(op); +} + +int +PyCell_Set(PyObject *op, PyObject *obj) +{ + PyObject* oldobj; + if (!PyCell_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + oldobj = PyCell_GET(op); + Py_XINCREF(obj); + PyCell_SET(op, obj); + Py_XDECREF(oldobj); + return 0; +} + +static void +cell_dealloc(PyCellObject *op) +{ + _PyObject_GC_UNTRACK(op); + Py_XDECREF(op->ob_ref); + PyObject_GC_Del(op); +} + +static PyObject * +cell_richcompare(PyObject *a, PyObject *b, int op) +{ + /* neither argument should be NULL, unless something's gone wrong */ + assert(a != NULL && b != NULL); + + /* both arguments should be instances of PyCellObject */ + if (!PyCell_Check(a) || !PyCell_Check(b)) { + Py_RETURN_NOTIMPLEMENTED; + } + + /* compare cells by contents; empty cells come before anything else */ + a = ((PyCellObject *)a)->ob_ref; + b = ((PyCellObject *)b)->ob_ref; + if (a != NULL && b != NULL) + return PyObject_RichCompare(a, b, op); + + Py_RETURN_RICHCOMPARE(b == NULL, a == NULL, op); +} + +static PyObject * +cell_repr(PyCellObject *op) +{ + if (op->ob_ref == NULL) + return PyUnicode_FromFormat("", op); + + return PyUnicode_FromFormat("", + op, op->ob_ref->ob_type->tp_name, + op->ob_ref); +} + +static int +cell_traverse(PyCellObject *op, visitproc visit, void *arg) +{ + Py_VISIT(op->ob_ref); + return 0; +} + +static int +cell_clear(PyCellObject *op) +{ + Py_CLEAR(op->ob_ref); + return 0; +} + +static PyObject * +cell_get_contents(PyCellObject *op, void *closure) +{ + if (op->ob_ref == NULL) + { + PyErr_SetString(PyExc_ValueError, "Cell is empty"); + return NULL; + } + Py_INCREF(op->ob_ref); + return op->ob_ref; +} + +static int +cell_set_contents(PyCellObject *op, PyObject *obj, void *Py_UNUSED(ignored)) +{ + Py_XINCREF(obj); + Py_XSETREF(op->ob_ref, obj); + return 0; +} + +static PyGetSetDef cell_getsetlist[] = { + {"cell_contents", (getter)cell_get_contents, + (setter)cell_set_contents, NULL}, + {NULL} /* sentinel */ +}; + +PyTypeObject PyCell_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "cell", + sizeof(PyCellObject), + 0, + (destructor)cell_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)cell_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + cell_new_doc, /* tp_doc */ + (traverseproc)cell_traverse, /* tp_traverse */ + (inquiry)cell_clear, /* tp_clear */ + cell_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + cell_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)cell_new, /* tp_new */ + 0, /* tp_free */ +}; diff --git a/python/Objects/classobject.c b/python/Objects/classobject.c new file mode 100755 index 0000000..12bb836 --- /dev/null +++ b/python/Objects/classobject.c @@ -0,0 +1,674 @@ +/* Class object implementation (dead now except for methods) */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "structmember.h" + +#define TP_DESCR_GET(t) ((t)->tp_descr_get) + +/* Free list for method objects to safe malloc/free overhead + * The im_self element is used to chain the elements. + */ +static PyMethodObject *free_list; +static int numfree = 0; +#ifndef PyMethod_MAXFREELIST +#define PyMethod_MAXFREELIST 256 +#endif + +_Py_IDENTIFIER(__name__); +_Py_IDENTIFIER(__qualname__); + +PyObject * +PyMethod_Function(PyObject *im) +{ + if (!PyMethod_Check(im)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyMethodObject *)im)->im_func; +} + +PyObject * +PyMethod_Self(PyObject *im) +{ + if (!PyMethod_Check(im)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyMethodObject *)im)->im_self; +} + + +static PyObject * +method_vectorcall(PyObject *method, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + assert(Py_TYPE(method) == &PyMethod_Type); + PyObject *self, *func, *result; + self = PyMethod_GET_SELF(method); + func = PyMethod_GET_FUNCTION(method); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + + if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { + /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */ + PyObject **newargs = (PyObject**)args - 1; + nargs += 1; + PyObject *tmp = newargs[0]; + newargs[0] = self; + result = _PyObject_Vectorcall(func, newargs, nargs, kwnames); + newargs[0] = tmp; + } + else { + Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); + Py_ssize_t totalargs = nargs + nkwargs; + if (totalargs == 0) { + return _PyObject_Vectorcall(func, &self, 1, NULL); + } + + PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject **newargs; + if (totalargs <= (Py_ssize_t)Py_ARRAY_LENGTH(newargs_stack) - 1) { + newargs = newargs_stack; + } + else { + newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); + if (newargs == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + /* use borrowed references */ + newargs[0] = self; + /* bpo-37138: since totalargs > 0, it's impossible that args is NULL. + * We need this, since calling memcpy() with a NULL pointer is + * undefined behaviour. */ + assert(args != NULL); + memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); + result = _PyObject_Vectorcall(func, newargs, nargs+1, kwnames); + if (newargs != newargs_stack) { + PyMem_Free(newargs); + } + } + return result; +} + + +/* Method objects are used for bound instance methods returned by + instancename.methodname. ClassName.methodname returns an ordinary + function. +*/ + +PyObject * +PyMethod_New(PyObject *func, PyObject *self) +{ + PyMethodObject *im; + if (self == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + im = free_list; + if (im != NULL) { + free_list = (PyMethodObject *)(im->im_self); + (void)PyObject_INIT(im, &PyMethod_Type); + numfree--; + } + else { + im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); + if (im == NULL) + return NULL; + } + im->im_weakreflist = NULL; + Py_INCREF(func); + im->im_func = func; + Py_XINCREF(self); + im->im_self = self; + im->vectorcall = method_vectorcall; + _PyObject_GC_TRACK(im); + return (PyObject *)im; +} + +static PyObject * +method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored)) +{ + PyObject *self = PyMethod_GET_SELF(im); + PyObject *func = PyMethod_GET_FUNCTION(im); + PyObject *funcname; + _Py_IDENTIFIER(getattr); + + funcname = _PyObject_GetAttrId(func, &PyId___name__); + if (funcname == NULL) { + return NULL; + } + return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr), + self, funcname); +} + +static PyMethodDef method_methods[] = { + {"__reduce__", (PyCFunction)method_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +/* Descriptors for PyMethod attributes */ + +/* im_func and im_self are stored in the PyMethod object */ + +#define MO_OFF(x) offsetof(PyMethodObject, x) + +static PyMemberDef method_memberlist[] = { + {"__func__", T_OBJECT, MO_OFF(im_func), READONLY|RESTRICTED, + "the function (or other callable) implementing a method"}, + {"__self__", T_OBJECT, MO_OFF(im_self), READONLY|RESTRICTED, + "the instance to which a method is bound"}, + {NULL} /* Sentinel */ +}; + +/* Christian Tismer argued convincingly that method attributes should + (nearly) always override function attributes. + The one exception is __doc__; there's a default __doc__ which + should only be used for the class, not for instances */ + +static PyObject * +method_get_doc(PyMethodObject *im, void *context) +{ + static PyObject *docstr; + if (docstr == NULL) { + docstr= PyUnicode_InternFromString("__doc__"); + if (docstr == NULL) + return NULL; + } + return PyObject_GetAttr(im->im_func, docstr); +} + +static PyGetSetDef method_getset[] = { + {"__doc__", (getter)method_get_doc, NULL, NULL}, + {0} +}; + +static PyObject * +method_getattro(PyObject *obj, PyObject *name) +{ + PyMethodObject *im = (PyMethodObject *)obj; + PyTypeObject *tp = obj->ob_type; + PyObject *descr = NULL; + + { + if (tp->tp_dict == NULL) { + if (PyType_Ready(tp) < 0) + return NULL; + } + descr = _PyType_Lookup(tp, name); + } + + if (descr != NULL) { + descrgetfunc f = TP_DESCR_GET(descr->ob_type); + if (f != NULL) + return f(descr, obj, (PyObject *)obj->ob_type); + else { + Py_INCREF(descr); + return descr; + } + } + + return PyObject_GetAttr(im->im_func, name); +} + +PyDoc_STRVAR(method_doc, +"method(function, instance)\n\ +\n\ +Create a bound instance method object."); + +static PyObject * +method_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + PyObject *func; + PyObject *self; + + if (!_PyArg_NoKeywords("method", kw)) + return NULL; + if (!PyArg_UnpackTuple(args, "method", 2, 2, + &func, &self)) + return NULL; + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable"); + return NULL; + } + if (self == NULL || self == Py_None) { + PyErr_SetString(PyExc_TypeError, + "self must not be None"); + return NULL; + } + + return PyMethod_New(func, self); +} + +static void +method_dealloc(PyMethodObject *im) +{ + _PyObject_GC_UNTRACK(im); + if (im->im_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)im); + Py_DECREF(im->im_func); + Py_XDECREF(im->im_self); + if (numfree < PyMethod_MAXFREELIST) { + im->im_self = (PyObject *)free_list; + free_list = im; + numfree++; + } + else { + PyObject_GC_Del(im); + } +} + +static PyObject * +method_richcompare(PyObject *self, PyObject *other, int op) +{ + PyMethodObject *a, *b; + PyObject *res; + int eq; + + if ((op != Py_EQ && op != Py_NE) || + !PyMethod_Check(self) || + !PyMethod_Check(other)) + { + Py_RETURN_NOTIMPLEMENTED; + } + a = (PyMethodObject *)self; + b = (PyMethodObject *)other; + eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); + if (eq == 1) { + eq = (a->im_self == b->im_self); + } + else if (eq < 0) + return NULL; + if (op == Py_EQ) + res = eq ? Py_True : Py_False; + else + res = eq ? Py_False : Py_True; + Py_INCREF(res); + return res; +} + +static PyObject * +method_repr(PyMethodObject *a) +{ + PyObject *self = a->im_self; + PyObject *func = a->im_func; + PyObject *funcname, *result; + const char *defname = "?"; + + if (_PyObject_LookupAttrId(func, &PyId___qualname__, &funcname) < 0 || + (funcname == NULL && + _PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0)) + { + return NULL; + } + + if (funcname != NULL && !PyUnicode_Check(funcname)) { + Py_DECREF(funcname); + funcname = NULL; + } + + /* XXX Shouldn't use repr()/%R here! */ + result = PyUnicode_FromFormat("", + funcname, defname, self); + + Py_XDECREF(funcname); + return result; +} + +static Py_hash_t +method_hash(PyMethodObject *a) +{ + Py_hash_t x, y; + x = _Py_HashPointer(a->im_self); + y = PyObject_Hash(a->im_func); + if (y == -1) + return -1; + x = x ^ y; + if (x == -1) + x = -2; + return x; +} + +static int +method_traverse(PyMethodObject *im, visitproc visit, void *arg) +{ + Py_VISIT(im->im_func); + Py_VISIT(im->im_self); + return 0; +} + +static PyObject * +method_call(PyObject *method, PyObject *args, PyObject *kwargs) +{ + PyObject *self, *func; + + self = PyMethod_GET_SELF(method); + func = PyMethod_GET_FUNCTION(method); + + return _PyObject_Call_Prepend(func, self, args, kwargs); +} + +static PyObject * +method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) +{ + Py_INCREF(meth); + return meth; +} + +PyTypeObject PyMethod_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "method", + sizeof(PyMethodObject), + 0, + (destructor)method_dealloc, /* tp_dealloc */ + offsetof(PyMethodObject, vectorcall), /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)method_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)method_hash, /* tp_hash */ + method_call, /* tp_call */ + 0, /* tp_str */ + method_getattro, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + method_doc, /* tp_doc */ + (traverseproc)method_traverse, /* tp_traverse */ + 0, /* tp_clear */ + method_richcompare, /* tp_richcompare */ + offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + method_methods, /* tp_methods */ + method_memberlist, /* tp_members */ + method_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + method_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + method_new, /* tp_new */ +}; + +/* Clear out the free list */ + +int +PyMethod_ClearFreeList(void) +{ + int freelist_size = numfree; + + while (free_list) { + PyMethodObject *im = free_list; + free_list = (PyMethodObject *)(im->im_self); + PyObject_GC_Del(im); + numfree--; + } + assert(numfree == 0); + return freelist_size; +} + +void +PyMethod_Fini(void) +{ + (void)PyMethod_ClearFreeList(); +} + +/* Print summary info about the state of the optimized allocator */ +void +_PyMethod_DebugMallocStats(FILE *out) +{ + _PyDebugAllocatorStats(out, + "free PyMethodObject", + numfree, sizeof(PyMethodObject)); +} + +/* ------------------------------------------------------------------------ + * instance method + */ + +PyObject * +PyInstanceMethod_New(PyObject *func) { + PyInstanceMethodObject *method; + method = PyObject_GC_New(PyInstanceMethodObject, + &PyInstanceMethod_Type); + if (method == NULL) return NULL; + Py_INCREF(func); + method->func = func; + _PyObject_GC_TRACK(method); + return (PyObject *)method; +} + +PyObject * +PyInstanceMethod_Function(PyObject *im) +{ + if (!PyInstanceMethod_Check(im)) { + PyErr_BadInternalCall(); + return NULL; + } + return PyInstanceMethod_GET_FUNCTION(im); +} + +#define IMO_OFF(x) offsetof(PyInstanceMethodObject, x) + +static PyMemberDef instancemethod_memberlist[] = { + {"__func__", T_OBJECT, IMO_OFF(func), READONLY|RESTRICTED, + "the function (or other callable) implementing a method"}, + {NULL} /* Sentinel */ +}; + +static PyObject * +instancemethod_get_doc(PyObject *self, void *context) +{ + static PyObject *docstr; + if (docstr == NULL) { + docstr = PyUnicode_InternFromString("__doc__"); + if (docstr == NULL) + return NULL; + } + return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr); +} + +static PyGetSetDef instancemethod_getset[] = { + {"__doc__", (getter)instancemethod_get_doc, NULL, NULL}, + {0} +}; + +static PyObject * +instancemethod_getattro(PyObject *self, PyObject *name) +{ + PyTypeObject *tp = self->ob_type; + PyObject *descr = NULL; + + if (tp->tp_dict == NULL) { + if (PyType_Ready(tp) < 0) + return NULL; + } + descr = _PyType_Lookup(tp, name); + + if (descr != NULL) { + descrgetfunc f = TP_DESCR_GET(descr->ob_type); + if (f != NULL) + return f(descr, self, (PyObject *)self->ob_type); + else { + Py_INCREF(descr); + return descr; + } + } + + return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name); +} + +static void +instancemethod_dealloc(PyObject *self) { + _PyObject_GC_UNTRACK(self); + Py_DECREF(PyInstanceMethod_GET_FUNCTION(self)); + PyObject_GC_Del(self); +} + +static int +instancemethod_traverse(PyObject *self, visitproc visit, void *arg) { + Py_VISIT(PyInstanceMethod_GET_FUNCTION(self)); + return 0; +} + +static PyObject * +instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw) +{ + return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw); +} + +static PyObject * +instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { + PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); + if (obj == NULL) { + Py_INCREF(func); + return func; + } + else + return PyMethod_New(func, obj); +} + +static PyObject * +instancemethod_richcompare(PyObject *self, PyObject *other, int op) +{ + PyInstanceMethodObject *a, *b; + PyObject *res; + int eq; + + if ((op != Py_EQ && op != Py_NE) || + !PyInstanceMethod_Check(self) || + !PyInstanceMethod_Check(other)) + { + Py_RETURN_NOTIMPLEMENTED; + } + a = (PyInstanceMethodObject *)self; + b = (PyInstanceMethodObject *)other; + eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ); + if (eq < 0) + return NULL; + if (op == Py_EQ) + res = eq ? Py_True : Py_False; + else + res = eq ? Py_False : Py_True; + Py_INCREF(res); + return res; +} + +static PyObject * +instancemethod_repr(PyObject *self) +{ + PyObject *func = PyInstanceMethod_Function(self); + PyObject *funcname, *result; + const char *defname = "?"; + + if (func == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + if (_PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0) { + return NULL; + } + if (funcname != NULL && !PyUnicode_Check(funcname)) { + Py_DECREF(funcname); + funcname = NULL; + } + + result = PyUnicode_FromFormat("", + funcname, defname, self); + + Py_XDECREF(funcname); + return result; +} + +/* +static long +instancemethod_hash(PyObject *self) +{ + long x, y; + x = (long)self; + y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self)); + if (y == -1) + return -1; + x = x ^ y; + if (x == -1) + x = -2; + return x; +} +*/ + +PyDoc_STRVAR(instancemethod_doc, +"instancemethod(function)\n\ +\n\ +Bind a function to a class."); + +static PyObject * +instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + PyObject *func; + + if (!_PyArg_NoKeywords("instancemethod", kw)) + return NULL; + if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func)) + return NULL; + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable"); + return NULL; + } + + return PyInstanceMethod_New(func); +} + +PyTypeObject PyInstanceMethod_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "instancemethod", /* tp_name */ + sizeof(PyInstanceMethodObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + instancemethod_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)instancemethod_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /*(hashfunc)instancemethod_hash, tp_hash */ + instancemethod_call, /* tp_call */ + 0, /* tp_str */ + instancemethod_getattro, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + instancemethod_doc, /* tp_doc */ + instancemethod_traverse, /* tp_traverse */ + 0, /* tp_clear */ + instancemethod_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + instancemethod_memberlist, /* tp_members */ + instancemethod_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + instancemethod_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + instancemethod_new, /* tp_new */ +}; diff --git a/python/Objects/clinic/bytearrayobject.c.h b/python/Objects/clinic/bytearrayobject.c.h new file mode 100755 index 0000000..0557707 --- /dev/null +++ b/python/Objects/clinic/bytearrayobject.c.h @@ -0,0 +1,1014 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from the bytearray."); + +#define BYTEARRAY_CLEAR_METHODDEF \ + {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, bytearray_clear__doc__}, + +static PyObject * +bytearray_clear_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_clear(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_clear_impl(self); +} + +PyDoc_STRVAR(bytearray_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of B."); + +#define BYTEARRAY_COPY_METHODDEF \ + {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, bytearray_copy__doc__}, + +static PyObject * +bytearray_copy_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_copy(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_copy_impl(self); +} + +PyDoc_STRVAR(bytearray_translate__doc__, +"translate($self, table, /, delete=b\'\')\n" +"--\n" +"\n" +"Return a copy with each character mapped by the given translation table.\n" +"\n" +" table\n" +" Translation table, which must be a bytes object of length 256.\n" +"\n" +"All characters occurring in the optional argument delete are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTEARRAY_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)(void(*)(void))bytearray_translate, METH_FASTCALL|METH_KEYWORDS, bytearray_translate__doc__}, + +static PyObject * +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, + PyObject *deletechars); + +static PyObject * +bytearray_translate(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "delete", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *table; + PyObject *deletechars = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + table = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + deletechars = args[1]; +skip_optional_pos: + return_value = bytearray_translate_impl(self, table, deletechars); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_maketrans__doc__, +"maketrans(frm, to, /)\n" +"--\n" +"\n" +"Return a translation table useable for the bytes or bytearray translate method.\n" +"\n" +"The returned table will be one where each byte in frm is mapped to the byte at\n" +"the same position in to.\n" +"\n" +"The bytes objects frm and to must be of the same length."); + +#define BYTEARRAY_MAKETRANS_METHODDEF \ + {"maketrans", (PyCFunction)(void(*)(void))bytearray_maketrans, METH_FASTCALL|METH_STATIC, bytearray_maketrans__doc__}, + +static PyObject * +bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to); + +static PyObject * +bytearray_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer frm = {NULL, NULL}; + Py_buffer to = {NULL, NULL}; + + if (!_PyArg_CheckPositional("maketrans", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &frm, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&frm, 'C')) { + _PyArg_BadArgument("maketrans", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &to, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&to, 'C')) { + _PyArg_BadArgument("maketrans", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + return_value = bytearray_maketrans_impl(&frm, &to); + +exit: + /* Cleanup for frm */ + if (frm.obj) { + PyBuffer_Release(&frm); + } + /* Cleanup for to */ + if (to.obj) { + PyBuffer_Release(&to); + } + + return return_value; +} + +PyDoc_STRVAR(bytearray_replace__doc__, +"replace($self, old, new, count=-1, /)\n" +"--\n" +"\n" +"Return a copy with all occurrences of substring old replaced by new.\n" +"\n" +" count\n" +" Maximum number of occurrences to replace.\n" +" -1 (the default value) means replace all occurrences.\n" +"\n" +"If the optional argument count is given, only the first count occurrences are\n" +"replaced."); + +#define BYTEARRAY_REPLACE_METHODDEF \ + {"replace", (PyCFunction)(void(*)(void))bytearray_replace, METH_FASTCALL, bytearray_replace__doc__}, + +static PyObject * +bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, + Py_buffer *new, Py_ssize_t count); + +static PyObject * +bytearray_replace(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer old = {NULL, NULL}; + Py_buffer new = {NULL, NULL}; + Py_ssize_t count = -1; + + if (!_PyArg_CheckPositional("replace", nargs, 2, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &old, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&old, 'C')) { + _PyArg_BadArgument("replace", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &new, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&new, 'C')) { + _PyArg_BadArgument("replace", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } +skip_optional: + return_value = bytearray_replace_impl(self, &old, &new, count); + +exit: + /* Cleanup for old */ + if (old.obj) { + PyBuffer_Release(&old); + } + /* Cleanup for new */ + if (new.obj) { + PyBuffer_Release(&new); + } + + return return_value; +} + +PyDoc_STRVAR(bytearray_split__doc__, +"split($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytearray, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytearray.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit."); + +#define BYTEARRAY_SPLIT_METHODDEF \ + {"split", (PyCFunction)(void(*)(void))bytearray_split, METH_FASTCALL|METH_KEYWORDS, bytearray_split__doc__}, + +static PyObject * +bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, + Py_ssize_t maxsplit); + +static PyObject * +bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + } + maxsplit = ival; + } +skip_optional_pos: + return_value = bytearray_split_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_partition__doc__, +"partition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytearray into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytearray. If the separator is\n" +"found, returns a 3-tuple containing the part before the separator, the\n" +"separator itself, and the part after it as new bytearray objects.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing the copy of the\n" +"original bytearray object and two empty bytearray objects."); + +#define BYTEARRAY_PARTITION_METHODDEF \ + {"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__}, + +PyDoc_STRVAR(bytearray_rpartition__doc__, +"rpartition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytearray into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytearray, starting at the end.\n" +"If the separator is found, returns a 3-tuple containing the part before the\n" +"separator, the separator itself, and the part after it as new bytearray\n" +"objects.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing two empty bytearray\n" +"objects and the copy of the original bytearray object."); + +#define BYTEARRAY_RPARTITION_METHODDEF \ + {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__}, + +PyDoc_STRVAR(bytearray_rsplit__doc__, +"rsplit($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytearray, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytearray.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit.\n" +"\n" +"Splitting is done starting at the end of the bytearray and working to the front."); + +#define BYTEARRAY_RSPLIT_METHODDEF \ + {"rsplit", (PyCFunction)(void(*)(void))bytearray_rsplit, METH_FASTCALL|METH_KEYWORDS, bytearray_rsplit__doc__}, + +static PyObject * +bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, + Py_ssize_t maxsplit); + +static PyObject * +bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + } + maxsplit = ival; + } +skip_optional_pos: + return_value = bytearray_rsplit_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_reverse__doc__, +"reverse($self, /)\n" +"--\n" +"\n" +"Reverse the order of the values in B in place."); + +#define BYTEARRAY_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, bytearray_reverse__doc__}, + +static PyObject * +bytearray_reverse_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_reverse(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_reverse_impl(self); +} + +PyDoc_STRVAR(bytearray_insert__doc__, +"insert($self, index, item, /)\n" +"--\n" +"\n" +"Insert a single item into the bytearray before the given index.\n" +"\n" +" index\n" +" The index where the value is to be inserted.\n" +" item\n" +" The item to be inserted."); + +#define BYTEARRAY_INSERT_METHODDEF \ + {"insert", (PyCFunction)(void(*)(void))bytearray_insert, METH_FASTCALL, bytearray_insert__doc__}, + +static PyObject * +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item); + +static PyObject * +bytearray_insert(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t index; + int item; + + if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + index = ival; + } + if (!_getbytevalue(args[1], &item)) { + goto exit; + } + return_value = bytearray_insert_impl(self, index, item); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_append__doc__, +"append($self, item, /)\n" +"--\n" +"\n" +"Append a single item to the end of the bytearray.\n" +"\n" +" item\n" +" The item to be appended."); + +#define BYTEARRAY_APPEND_METHODDEF \ + {"append", (PyCFunction)bytearray_append, METH_O, bytearray_append__doc__}, + +static PyObject * +bytearray_append_impl(PyByteArrayObject *self, int item); + +static PyObject * +bytearray_append(PyByteArrayObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int item; + + if (!_getbytevalue(arg, &item)) { + goto exit; + } + return_value = bytearray_append_impl(self, item); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_extend__doc__, +"extend($self, iterable_of_ints, /)\n" +"--\n" +"\n" +"Append all the items from the iterator or sequence to the end of the bytearray.\n" +"\n" +" iterable_of_ints\n" +" The iterable of items to append."); + +#define BYTEARRAY_EXTEND_METHODDEF \ + {"extend", (PyCFunction)bytearray_extend, METH_O, bytearray_extend__doc__}, + +PyDoc_STRVAR(bytearray_pop__doc__, +"pop($self, index=-1, /)\n" +"--\n" +"\n" +"Remove and return a single item from B.\n" +"\n" +" index\n" +" The index from where to remove the item.\n" +" -1 (the default value) means remove the last item.\n" +"\n" +"If no index argument is given, will pop the last item."); + +#define BYTEARRAY_POP_METHODDEF \ + {"pop", (PyCFunction)(void(*)(void))bytearray_pop, METH_FASTCALL, bytearray_pop__doc__}, + +static PyObject * +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index); + +static PyObject * +bytearray_pop(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t index = -1; + + if (!_PyArg_CheckPositional("pop", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + index = ival; + } +skip_optional: + return_value = bytearray_pop_impl(self, index); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_remove__doc__, +"remove($self, value, /)\n" +"--\n" +"\n" +"Remove the first occurrence of a value in the bytearray.\n" +"\n" +" value\n" +" The value to remove."); + +#define BYTEARRAY_REMOVE_METHODDEF \ + {"remove", (PyCFunction)bytearray_remove, METH_O, bytearray_remove__doc__}, + +static PyObject * +bytearray_remove_impl(PyByteArrayObject *self, int value); + +static PyObject * +bytearray_remove(PyByteArrayObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int value; + + if (!_getbytevalue(arg, &value)) { + goto exit; + } + return_value = bytearray_remove_impl(self, value); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_strip__doc__, +"strip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading and trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading and trailing ASCII whitespace."); + +#define BYTEARRAY_STRIP_METHODDEF \ + {"strip", (PyCFunction)(void(*)(void))bytearray_strip, METH_FASTCALL, bytearray_strip__doc__}, + +static PyObject * +bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes); + +static PyObject * +bytearray_strip(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!_PyArg_CheckPositional("strip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + bytes = args[0]; +skip_optional: + return_value = bytearray_strip_impl(self, bytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_lstrip__doc__, +"lstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading ASCII whitespace."); + +#define BYTEARRAY_LSTRIP_METHODDEF \ + {"lstrip", (PyCFunction)(void(*)(void))bytearray_lstrip, METH_FASTCALL, bytearray_lstrip__doc__}, + +static PyObject * +bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes); + +static PyObject * +bytearray_lstrip(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!_PyArg_CheckPositional("lstrip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + bytes = args[0]; +skip_optional: + return_value = bytearray_lstrip_impl(self, bytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_rstrip__doc__, +"rstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip trailing ASCII whitespace."); + +#define BYTEARRAY_RSTRIP_METHODDEF \ + {"rstrip", (PyCFunction)(void(*)(void))bytearray_rstrip, METH_FASTCALL, bytearray_rstrip__doc__}, + +static PyObject * +bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes); + +static PyObject * +bytearray_rstrip(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!_PyArg_CheckPositional("rstrip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + bytes = args[0]; +skip_optional: + return_value = bytearray_rstrip_impl(self, bytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_decode__doc__, +"decode($self, /, encoding=\'utf-8\', errors=\'strict\')\n" +"--\n" +"\n" +"Decode the bytearray using the codec registered for encoding.\n" +"\n" +" encoding\n" +" The encoding with which to decode the bytearray.\n" +" errors\n" +" The error handling scheme to use for the handling of decoding errors.\n" +" The default is \'strict\' meaning that decoding errors raise a\n" +" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n" +" as well as any other name registered with codecs.register_error that\n" +" can handle UnicodeDecodeErrors."); + +#define BYTEARRAY_DECODE_METHODDEF \ + {"decode", (PyCFunction)(void(*)(void))bytearray_decode, METH_FASTCALL|METH_KEYWORDS, bytearray_decode__doc__}, + +static PyObject * +bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, + const char *errors); + +static PyObject * +bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"encoding", "errors", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + const char *encoding = NULL; + const char *errors = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[0]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[0], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("decode", "argument 'errors'", "str", args[1]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_pos: + return_value = bytearray_decode_impl(self, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_join__doc__, +"join($self, iterable_of_bytes, /)\n" +"--\n" +"\n" +"Concatenate any number of bytes/bytearray objects.\n" +"\n" +"The bytearray whose method is called is inserted in between each pair.\n" +"\n" +"The result is returned as a new bytearray object."); + +#define BYTEARRAY_JOIN_METHODDEF \ + {"join", (PyCFunction)bytearray_join, METH_O, bytearray_join__doc__}, + +PyDoc_STRVAR(bytearray_splitlines__doc__, +"splitlines($self, /, keepends=False)\n" +"--\n" +"\n" +"Return a list of the lines in the bytearray, breaking at line boundaries.\n" +"\n" +"Line breaks are not included in the resulting list unless keepends is given and\n" +"true."); + +#define BYTEARRAY_SPLITLINES_METHODDEF \ + {"splitlines", (PyCFunction)(void(*)(void))bytearray_splitlines, METH_FASTCALL|METH_KEYWORDS, bytearray_splitlines__doc__}, + +static PyObject * +bytearray_splitlines_impl(PyByteArrayObject *self, int keepends); + +static PyObject * +bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"keepends", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int keepends = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + keepends = _PyLong_AsInt(args[0]); + if (keepends == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = bytearray_splitlines_impl(self, keepends); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_fromhex__doc__, +"fromhex($type, string, /)\n" +"--\n" +"\n" +"Create a bytearray object from a string of hexadecimal numbers.\n" +"\n" +"Spaces between two numbers are accepted.\n" +"Example: bytearray.fromhex(\'B9 01EF\') -> bytearray(b\'\\\\xb9\\\\x01\\\\xef\')"); + +#define BYTEARRAY_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)bytearray_fromhex, METH_O|METH_CLASS, bytearray_fromhex__doc__}, + +static PyObject * +bytearray_fromhex_impl(PyTypeObject *type, PyObject *string); + +static PyObject * +bytearray_fromhex(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *string; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("fromhex", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + string = arg; + return_value = bytearray_fromhex_impl(type, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_hex__doc__, +"hex($self, /, sep=, bytes_per_sep=1)\n" +"--\n" +"\n" +"Create a str of hexadecimal numbers from a bytearray object.\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" +"Example:\n" +">>> value = bytearray([0xb9, 0x01, 0xef])\n" +">>> value.hex()\n" +"\'b901ef\'\n" +">>> value.hex(\':\')\n" +"\'b9:01:ef\'\n" +">>> value.hex(\':\', 2)\n" +"\'b9:01ef\'\n" +">>> value.hex(\':\', -2)\n" +"\'b901:ef\'"); + +#define BYTEARRAY_HEX_METHODDEF \ + {"hex", (PyCFunction)(void(*)(void))bytearray_hex, METH_FASTCALL|METH_KEYWORDS, bytearray_hex__doc__}, + +static PyObject * +bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep); + +static PyObject * +bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[1]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = bytearray_hex_impl(self, sep, bytes_per_sep); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define BYTEARRAY_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, bytearray_reduce__doc__}, + +static PyObject * +bytearray_reduce_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_reduce(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_reduce_impl(self); +} + +PyDoc_STRVAR(bytearray_reduce_ex__doc__, +"__reduce_ex__($self, proto=0, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define BYTEARRAY_REDUCE_EX_METHODDEF \ + {"__reduce_ex__", (PyCFunction)(void(*)(void))bytearray_reduce_ex, METH_FASTCALL, bytearray_reduce_ex__doc__}, + +static PyObject * +bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto); + +static PyObject * +bytearray_reduce_ex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int proto = 0; + + if (!_PyArg_CheckPositional("__reduce_ex__", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + proto = _PyLong_AsInt(args[0]); + if (proto == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = bytearray_reduce_ex_impl(self, proto); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_sizeof__doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns the size of the bytearray object in memory, in bytes."); + +#define BYTEARRAY_SIZEOF_METHODDEF \ + {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, bytearray_sizeof__doc__}, + +static PyObject * +bytearray_sizeof_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_sizeof_impl(self); +} +/*[clinic end generated code: output=508dce79cf2dffcc input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/bytesobject.c.h b/python/Objects/clinic/bytesobject.c.h new file mode 100755 index 0000000..22024ab --- /dev/null +++ b/python/Objects/clinic/bytesobject.c.h @@ -0,0 +1,758 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_split__doc__, +"split($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytes, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytes.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit."); + +#define BYTES_SPLIT_METHODDEF \ + {"split", (PyCFunction)(void(*)(void))bytes_split, METH_FASTCALL|METH_KEYWORDS, bytes_split__doc__}, + +static PyObject * +bytes_split_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + } + maxsplit = ival; + } +skip_optional_pos: + return_value = bytes_split_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_partition__doc__, +"partition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytes into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytes. If the separator is found,\n" +"returns a 3-tuple containing the part before the separator, the separator\n" +"itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing the original bytes\n" +"object and two empty bytes objects."); + +#define BYTES_PARTITION_METHODDEF \ + {"partition", (PyCFunction)bytes_partition, METH_O, bytes_partition__doc__}, + +static PyObject * +bytes_partition_impl(PyBytesObject *self, Py_buffer *sep); + +static PyObject * +bytes_partition(PyBytesObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer sep = {NULL, NULL}; + + if (PyObject_GetBuffer(arg, &sep, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&sep, 'C')) { + _PyArg_BadArgument("partition", "argument", "contiguous buffer", arg); + goto exit; + } + return_value = bytes_partition_impl(self, &sep); + +exit: + /* Cleanup for sep */ + if (sep.obj) { + PyBuffer_Release(&sep); + } + + return return_value; +} + +PyDoc_STRVAR(bytes_rpartition__doc__, +"rpartition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytes into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytes, starting at the end. If\n" +"the separator is found, returns a 3-tuple containing the part before the\n" +"separator, the separator itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing two empty bytes\n" +"objects and the original bytes object."); + +#define BYTES_RPARTITION_METHODDEF \ + {"rpartition", (PyCFunction)bytes_rpartition, METH_O, bytes_rpartition__doc__}, + +static PyObject * +bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep); + +static PyObject * +bytes_rpartition(PyBytesObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer sep = {NULL, NULL}; + + if (PyObject_GetBuffer(arg, &sep, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&sep, 'C')) { + _PyArg_BadArgument("rpartition", "argument", "contiguous buffer", arg); + goto exit; + } + return_value = bytes_rpartition_impl(self, &sep); + +exit: + /* Cleanup for sep */ + if (sep.obj) { + PyBuffer_Release(&sep); + } + + return return_value; +} + +PyDoc_STRVAR(bytes_rsplit__doc__, +"rsplit($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytes, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytes.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit.\n" +"\n" +"Splitting is done starting at the end of the bytes and working to the front."); + +#define BYTES_RSPLIT_METHODDEF \ + {"rsplit", (PyCFunction)(void(*)(void))bytes_rsplit, METH_FASTCALL|METH_KEYWORDS, bytes_rsplit__doc__}, + +static PyObject * +bytes_rsplit_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + } + maxsplit = ival; + } +skip_optional_pos: + return_value = bytes_rsplit_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_join__doc__, +"join($self, iterable_of_bytes, /)\n" +"--\n" +"\n" +"Concatenate any number of bytes objects.\n" +"\n" +"The bytes whose method is called is inserted in between each pair.\n" +"\n" +"The result is returned as a new bytes object.\n" +"\n" +"Example: b\'.\'.join([b\'ab\', b\'pq\', b\'rs\']) -> b\'ab.pq.rs\'."); + +#define BYTES_JOIN_METHODDEF \ + {"join", (PyCFunction)bytes_join, METH_O, bytes_join__doc__}, + +PyDoc_STRVAR(bytes_strip__doc__, +"strip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading and trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading and trailing ASCII whitespace."); + +#define BYTES_STRIP_METHODDEF \ + {"strip", (PyCFunction)(void(*)(void))bytes_strip, METH_FASTCALL, bytes_strip__doc__}, + +static PyObject * +bytes_strip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_strip(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!_PyArg_CheckPositional("strip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + bytes = args[0]; +skip_optional: + return_value = bytes_strip_impl(self, bytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_lstrip__doc__, +"lstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading ASCII whitespace."); + +#define BYTES_LSTRIP_METHODDEF \ + {"lstrip", (PyCFunction)(void(*)(void))bytes_lstrip, METH_FASTCALL, bytes_lstrip__doc__}, + +static PyObject * +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_lstrip(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!_PyArg_CheckPositional("lstrip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + bytes = args[0]; +skip_optional: + return_value = bytes_lstrip_impl(self, bytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_rstrip__doc__, +"rstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip trailing ASCII whitespace."); + +#define BYTES_RSTRIP_METHODDEF \ + {"rstrip", (PyCFunction)(void(*)(void))bytes_rstrip, METH_FASTCALL, bytes_rstrip__doc__}, + +static PyObject * +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_rstrip(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!_PyArg_CheckPositional("rstrip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + bytes = args[0]; +skip_optional: + return_value = bytes_rstrip_impl(self, bytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_translate__doc__, +"translate($self, table, /, delete=b\'\')\n" +"--\n" +"\n" +"Return a copy with each character mapped by the given translation table.\n" +"\n" +" table\n" +" Translation table, which must be a bytes object of length 256.\n" +"\n" +"All characters occurring in the optional argument delete are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTES_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)(void(*)(void))bytes_translate, METH_FASTCALL|METH_KEYWORDS, bytes_translate__doc__}, + +static PyObject * +bytes_translate_impl(PyBytesObject *self, PyObject *table, + PyObject *deletechars); + +static PyObject * +bytes_translate(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "delete", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *table; + PyObject *deletechars = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + table = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + deletechars = args[1]; +skip_optional_pos: + return_value = bytes_translate_impl(self, table, deletechars); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_maketrans__doc__, +"maketrans(frm, to, /)\n" +"--\n" +"\n" +"Return a translation table useable for the bytes or bytearray translate method.\n" +"\n" +"The returned table will be one where each byte in frm is mapped to the byte at\n" +"the same position in to.\n" +"\n" +"The bytes objects frm and to must be of the same length."); + +#define BYTES_MAKETRANS_METHODDEF \ + {"maketrans", (PyCFunction)(void(*)(void))bytes_maketrans, METH_FASTCALL|METH_STATIC, bytes_maketrans__doc__}, + +static PyObject * +bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to); + +static PyObject * +bytes_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer frm = {NULL, NULL}; + Py_buffer to = {NULL, NULL}; + + if (!_PyArg_CheckPositional("maketrans", nargs, 2, 2)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &frm, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&frm, 'C')) { + _PyArg_BadArgument("maketrans", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &to, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&to, 'C')) { + _PyArg_BadArgument("maketrans", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + return_value = bytes_maketrans_impl(&frm, &to); + +exit: + /* Cleanup for frm */ + if (frm.obj) { + PyBuffer_Release(&frm); + } + /* Cleanup for to */ + if (to.obj) { + PyBuffer_Release(&to); + } + + return return_value; +} + +PyDoc_STRVAR(bytes_replace__doc__, +"replace($self, old, new, count=-1, /)\n" +"--\n" +"\n" +"Return a copy with all occurrences of substring old replaced by new.\n" +"\n" +" count\n" +" Maximum number of occurrences to replace.\n" +" -1 (the default value) means replace all occurrences.\n" +"\n" +"If the optional argument count is given, only the first count occurrences are\n" +"replaced."); + +#define BYTES_REPLACE_METHODDEF \ + {"replace", (PyCFunction)(void(*)(void))bytes_replace, METH_FASTCALL, bytes_replace__doc__}, + +static PyObject * +bytes_replace_impl(PyBytesObject *self, Py_buffer *old, Py_buffer *new, + Py_ssize_t count); + +static PyObject * +bytes_replace(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer old = {NULL, NULL}; + Py_buffer new = {NULL, NULL}; + Py_ssize_t count = -1; + + if (!_PyArg_CheckPositional("replace", nargs, 2, 3)) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &old, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&old, 'C')) { + _PyArg_BadArgument("replace", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (PyObject_GetBuffer(args[1], &new, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&new, 'C')) { + _PyArg_BadArgument("replace", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } +skip_optional: + return_value = bytes_replace_impl(self, &old, &new, count); + +exit: + /* Cleanup for old */ + if (old.obj) { + PyBuffer_Release(&old); + } + /* Cleanup for new */ + if (new.obj) { + PyBuffer_Release(&new); + } + + return return_value; +} + +PyDoc_STRVAR(bytes_decode__doc__, +"decode($self, /, encoding=\'utf-8\', errors=\'strict\')\n" +"--\n" +"\n" +"Decode the bytes using the codec registered for encoding.\n" +"\n" +" encoding\n" +" The encoding with which to decode the bytes.\n" +" errors\n" +" The error handling scheme to use for the handling of decoding errors.\n" +" The default is \'strict\' meaning that decoding errors raise a\n" +" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n" +" as well as any other name registered with codecs.register_error that\n" +" can handle UnicodeDecodeErrors."); + +#define BYTES_DECODE_METHODDEF \ + {"decode", (PyCFunction)(void(*)(void))bytes_decode, METH_FASTCALL|METH_KEYWORDS, bytes_decode__doc__}, + +static PyObject * +bytes_decode_impl(PyBytesObject *self, const char *encoding, + const char *errors); + +static PyObject * +bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"encoding", "errors", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + const char *encoding = NULL; + const char *errors = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[0]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[0], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("decode", "argument 'errors'", "str", args[1]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_pos: + return_value = bytes_decode_impl(self, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_splitlines__doc__, +"splitlines($self, /, keepends=False)\n" +"--\n" +"\n" +"Return a list of the lines in the bytes, breaking at line boundaries.\n" +"\n" +"Line breaks are not included in the resulting list unless keepends is given and\n" +"true."); + +#define BYTES_SPLITLINES_METHODDEF \ + {"splitlines", (PyCFunction)(void(*)(void))bytes_splitlines, METH_FASTCALL|METH_KEYWORDS, bytes_splitlines__doc__}, + +static PyObject * +bytes_splitlines_impl(PyBytesObject *self, int keepends); + +static PyObject * +bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"keepends", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int keepends = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + keepends = _PyLong_AsInt(args[0]); + if (keepends == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = bytes_splitlines_impl(self, keepends); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_fromhex__doc__, +"fromhex($type, string, /)\n" +"--\n" +"\n" +"Create a bytes object from a string of hexadecimal numbers.\n" +"\n" +"Spaces between two numbers are accepted.\n" +"Example: bytes.fromhex(\'B9 01EF\') -> b\'\\\\xb9\\\\x01\\\\xef\'."); + +#define BYTES_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)bytes_fromhex, METH_O|METH_CLASS, bytes_fromhex__doc__}, + +static PyObject * +bytes_fromhex_impl(PyTypeObject *type, PyObject *string); + +static PyObject * +bytes_fromhex(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *string; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("fromhex", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + string = arg; + return_value = bytes_fromhex_impl(type, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_hex__doc__, +"hex($self, /, sep=, bytes_per_sep=1)\n" +"--\n" +"\n" +"Create a str of hexadecimal numbers from a bytes object.\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" +"Example:\n" +">>> value = b\'\\xb9\\x01\\xef\'\n" +">>> value.hex()\n" +"\'b901ef\'\n" +">>> value.hex(\':\')\n" +"\'b9:01:ef\'\n" +">>> value.hex(\':\', 2)\n" +"\'b9:01ef\'\n" +">>> value.hex(\':\', -2)\n" +"\'b901:ef\'"); + +#define BYTES_HEX_METHODDEF \ + {"hex", (PyCFunction)(void(*)(void))bytes_hex, METH_FASTCALL|METH_KEYWORDS, bytes_hex__doc__}, + +static PyObject * +bytes_hex_impl(PyBytesObject *self, PyObject *sep, int bytes_per_sep); + +static PyObject * +bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[1]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = bytes_hex_impl(self, sep, bytes_per_sep); + +exit: + return return_value; +} +/*[clinic end generated code: output=ca60dfccf8d51e88 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/codeobject.c.h b/python/Objects/clinic/codeobject.c.h new file mode 100755 index 0000000..1dd8227 --- /dev/null +++ b/python/Objects/clinic/codeobject.c.h @@ -0,0 +1,256 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(code_replace__doc__, +"replace($self, /, *, co_argcount=-1, co_posonlyargcount=-1,\n" +" co_kwonlyargcount=-1, co_nlocals=-1, co_stacksize=-1,\n" +" co_flags=-1, co_firstlineno=-1, co_code=None, co_consts=None,\n" +" co_names=None, co_varnames=None, co_freevars=None,\n" +" co_cellvars=None, co_filename=None, co_name=None,\n" +" co_lnotab=None)\n" +"--\n" +"\n" +"Return a copy of the code object with new values for the specified fields."); + +#define CODE_REPLACE_METHODDEF \ + {"replace", (PyCFunction)(void(*)(void))code_replace, METH_FASTCALL|METH_KEYWORDS, code_replace__doc__}, + +static PyObject * +code_replace_impl(PyCodeObject *self, int co_argcount, + int co_posonlyargcount, int co_kwonlyargcount, + int co_nlocals, int co_stacksize, int co_flags, + int co_firstlineno, PyBytesObject *co_code, + PyObject *co_consts, PyObject *co_names, + PyObject *co_varnames, PyObject *co_freevars, + PyObject *co_cellvars, PyObject *co_filename, + PyObject *co_name, PyBytesObject *co_lnotab); + +static PyObject * +code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_lnotab", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + PyObject *argsbuf[16]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int co_argcount = self->co_argcount; + int co_posonlyargcount = self->co_posonlyargcount; + int co_kwonlyargcount = self->co_kwonlyargcount; + int co_nlocals = self->co_nlocals; + int co_stacksize = self->co_stacksize; + int co_flags = self->co_flags; + int co_firstlineno = self->co_firstlineno; + PyBytesObject *co_code = (PyBytesObject *)self->co_code; + PyObject *co_consts = self->co_consts; + PyObject *co_names = self->co_names; + PyObject *co_varnames = self->co_varnames; + PyObject *co_freevars = self->co_freevars; + PyObject *co_cellvars = self->co_cellvars; + PyObject *co_filename = self->co_filename; + PyObject *co_name = self->co_name; + PyBytesObject *co_lnotab = (PyBytesObject *)self->co_lnotab; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[0]) { + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_argcount = _PyLong_AsInt(args[0]); + if (co_argcount == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[1]) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_posonlyargcount = _PyLong_AsInt(args[1]); + if (co_posonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_kwonlyargcount = _PyLong_AsInt(args[2]); + if (co_kwonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_nlocals = _PyLong_AsInt(args[3]); + if (co_nlocals == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[4]) { + if (PyFloat_Check(args[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_stacksize = _PyLong_AsInt(args[4]); + if (co_stacksize == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[5]) { + if (PyFloat_Check(args[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_flags = _PyLong_AsInt(args[5]); + if (co_flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[6]) { + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_firstlineno = _PyLong_AsInt(args[6]); + if (co_firstlineno == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[7]) { + if (!PyBytes_Check(args[7])) { + _PyArg_BadArgument("replace", "argument 'co_code'", "bytes", args[7]); + goto exit; + } + co_code = (PyBytesObject *)args[7]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[8]) { + if (!PyTuple_Check(args[8])) { + _PyArg_BadArgument("replace", "argument 'co_consts'", "tuple", args[8]); + goto exit; + } + co_consts = args[8]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[9]) { + if (!PyTuple_Check(args[9])) { + _PyArg_BadArgument("replace", "argument 'co_names'", "tuple", args[9]); + goto exit; + } + co_names = args[9]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[10]) { + if (!PyTuple_Check(args[10])) { + _PyArg_BadArgument("replace", "argument 'co_varnames'", "tuple", args[10]); + goto exit; + } + co_varnames = args[10]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[11]) { + if (!PyTuple_Check(args[11])) { + _PyArg_BadArgument("replace", "argument 'co_freevars'", "tuple", args[11]); + goto exit; + } + co_freevars = args[11]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[12]) { + if (!PyTuple_Check(args[12])) { + _PyArg_BadArgument("replace", "argument 'co_cellvars'", "tuple", args[12]); + goto exit; + } + co_cellvars = args[12]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[13]) { + if (!PyUnicode_Check(args[13])) { + _PyArg_BadArgument("replace", "argument 'co_filename'", "str", args[13]); + goto exit; + } + if (PyUnicode_READY(args[13]) == -1) { + goto exit; + } + co_filename = args[13]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[14]) { + if (!PyUnicode_Check(args[14])) { + _PyArg_BadArgument("replace", "argument 'co_name'", "str", args[14]); + goto exit; + } + if (PyUnicode_READY(args[14]) == -1) { + goto exit; + } + co_name = args[14]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (!PyBytes_Check(args[15])) { + _PyArg_BadArgument("replace", "argument 'co_lnotab'", "bytes", args[15]); + goto exit; + } + co_lnotab = (PyBytesObject *)args[15]; +skip_optional_kwonly: + return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_lnotab); + +exit: + return return_value; +} +/*[clinic end generated code: output=27fe34e82106b220 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/complexobject.c.h b/python/Objects/clinic/complexobject.c.h new file mode 100755 index 0000000..8caa910 --- /dev/null +++ b/python/Objects/clinic/complexobject.c.h @@ -0,0 +1,49 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(complex_new__doc__, +"complex(real=0, imag=0)\n" +"--\n" +"\n" +"Create a complex number from a real part and an optional imaginary part.\n" +"\n" +"This is equivalent to (real + imag*1j) where imag defaults to 0."); + +static PyObject * +complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i); + +static PyObject * +complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"real", "imag", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "complex", 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 *r = _PyLong_Zero; + PyObject *i = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + r = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + i = fastargs[1]; +skip_optional_pos: + return_value = complex_new_impl(type, r, i); + +exit: + return return_value; +} +/*[clinic end generated code: output=a0fe23fdbdc9b06b input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/descrobject.c.h b/python/Objects/clinic/descrobject.c.h new file mode 100755 index 0000000..d248b91 --- /dev/null +++ b/python/Objects/clinic/descrobject.c.h @@ -0,0 +1,118 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static PyObject * +mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping); + +static PyObject * +mappingproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"mapping", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "mappingproxy", 0}; + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *mapping; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + mapping = fastargs[0]; + return_value = mappingproxy_new_impl(type, mapping); + +exit: + return return_value; +} + +PyDoc_STRVAR(property_init__doc__, +"property(fget=None, fset=None, fdel=None, doc=None)\n" +"--\n" +"\n" +"Property attribute.\n" +"\n" +" fget\n" +" function to be used for getting an attribute value\n" +" fset\n" +" function to be used for setting an attribute value\n" +" fdel\n" +" function to be used for del\'ing an attribute\n" +" doc\n" +" docstring\n" +"\n" +"Typical use is to define a managed attribute x:\n" +"\n" +"class C(object):\n" +" def getx(self): return self._x\n" +" def setx(self, value): self._x = value\n" +" def delx(self): del self._x\n" +" x = property(getx, setx, delx, \"I\'m the \'x\' property.\")\n" +"\n" +"Decorators make defining new properties or modifying existing ones easy:\n" +"\n" +"class C(object):\n" +" @property\n" +" def x(self):\n" +" \"I am the \'x\' property.\"\n" +" return self._x\n" +" @x.setter\n" +" def x(self, value):\n" +" self._x = value\n" +" @x.deleter\n" +" def x(self):\n" +" del self._x"); + +static int +property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, + PyObject *fdel, PyObject *doc); + +static int +property_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"fget", "fset", "fdel", "doc", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "property", 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) - 0; + PyObject *fget = NULL; + PyObject *fset = NULL; + PyObject *fdel = NULL; + PyObject *doc = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 4, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + fget = fastargs[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[1]) { + fset = fastargs[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + fdel = fastargs[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + doc = fastargs[3]; +skip_optional_pos: + return_value = property_init_impl((propertyobject *)self, fget, fset, fdel, doc); + +exit: + return return_value; +} +/*[clinic end generated code: output=916624e717862abc input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/dictobject.c.h b/python/Objects/clinic/dictobject.c.h new file mode 100755 index 0000000..8d54933 --- /dev/null +++ b/python/Objects/clinic/dictobject.c.h @@ -0,0 +1,157 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(dict_fromkeys__doc__, +"fromkeys($type, iterable, value=None, /)\n" +"--\n" +"\n" +"Create a new dictionary with keys from iterable and values set to value."); + +#define DICT_FROMKEYS_METHODDEF \ + {"fromkeys", (PyCFunction)(void(*)(void))dict_fromkeys, METH_FASTCALL|METH_CLASS, dict_fromkeys__doc__}, + +static PyObject * +dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value); + +static PyObject * +dict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *iterable; + PyObject *value = Py_None; + + if (!_PyArg_CheckPositional("fromkeys", nargs, 1, 2)) { + goto exit; + } + iterable = args[0]; + if (nargs < 2) { + goto skip_optional; + } + value = args[1]; +skip_optional: + return_value = dict_fromkeys_impl(type, iterable, value); + +exit: + return return_value; +} + +PyDoc_STRVAR(dict___contains____doc__, +"__contains__($self, key, /)\n" +"--\n" +"\n" +"True if the dictionary has the specified key, else False."); + +#define DICT___CONTAINS___METHODDEF \ + {"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__}, + +PyDoc_STRVAR(dict_get__doc__, +"get($self, key, default=None, /)\n" +"--\n" +"\n" +"Return the value for key if key is in the dictionary, else default."); + +#define DICT_GET_METHODDEF \ + {"get", (PyCFunction)(void(*)(void))dict_get, METH_FASTCALL, dict_get__doc__}, + +static PyObject * +dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value); + +static PyObject * +dict_get(PyDictObject *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; + } + key = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = dict_get_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(dict_setdefault__doc__, +"setdefault($self, key, default=None, /)\n" +"--\n" +"\n" +"Insert key with a value of default if key is not in the dictionary.\n" +"\n" +"Return the value for key if key is in the dictionary, else default."); + +#define DICT_SETDEFAULT_METHODDEF \ + {"setdefault", (PyCFunction)(void(*)(void))dict_setdefault, METH_FASTCALL, dict_setdefault__doc__}, + +static PyObject * +dict_setdefault_impl(PyDictObject *self, PyObject *key, + PyObject *default_value); + +static PyObject * +dict_setdefault(PyDictObject *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; + } + key = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = dict_setdefault_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(dict_popitem__doc__, +"popitem($self, /)\n" +"--\n" +"\n" +"Remove and return a (key, value) pair as a 2-tuple.\n" +"\n" +"Pairs are returned in LIFO (last-in, first-out) order.\n" +"Raises KeyError if the dict is empty."); + +#define DICT_POPITEM_METHODDEF \ + {"popitem", (PyCFunction)dict_popitem, METH_NOARGS, dict_popitem__doc__}, + +static PyObject * +dict_popitem_impl(PyDictObject *self); + +static PyObject * +dict_popitem(PyDictObject *self, PyObject *Py_UNUSED(ignored)) +{ + return dict_popitem_impl(self); +} + +PyDoc_STRVAR(dict___reversed____doc__, +"__reversed__($self, /)\n" +"--\n" +"\n" +"Return a reverse iterator over the dict keys."); + +#define DICT___REVERSED___METHODDEF \ + {"__reversed__", (PyCFunction)dict___reversed__, METH_NOARGS, dict___reversed____doc__}, + +static PyObject * +dict___reversed___impl(PyDictObject *self); + +static PyObject * +dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) +{ + return dict___reversed___impl(self); +} +/*[clinic end generated code: output=676532dcc941d399 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/enumobject.c.h b/python/Objects/clinic/enumobject.c.h new file mode 100755 index 0000000..09d4c87 --- /dev/null +++ b/python/Objects/clinic/enumobject.c.h @@ -0,0 +1,80 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(enum_new__doc__, +"enumerate(iterable, start=0)\n" +"--\n" +"\n" +"Return an enumerate object.\n" +"\n" +" iterable\n" +" an object supporting iteration\n" +"\n" +"The enumerate object yields pairs containing a count (from start, which\n" +"defaults to zero) and a value yielded by the iterable argument.\n" +"\n" +"enumerate is useful for obtaining an indexed list:\n" +" (0, seq[0]), (1, seq[1]), (2, seq[2]), ..."); + +static PyObject * +enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start); + +static PyObject * +enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"iterable", "start", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "enumerate", 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 *iterable; + PyObject *start = 0; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + iterable = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + start = fastargs[1]; +skip_optional_pos: + return_value = enum_new_impl(type, iterable, start); + +exit: + return return_value; +} + +PyDoc_STRVAR(reversed_new__doc__, +"reversed(sequence, /)\n" +"--\n" +"\n" +"Return a reverse iterator over the values of the given sequence."); + +static PyObject * +reversed_new_impl(PyTypeObject *type, PyObject *seq); + +static PyObject * +reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *seq; + + if ((type == &PyReversed_Type) && + !_PyArg_NoKeywords("reversed", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("reversed", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + seq = PyTuple_GET_ITEM(args, 0); + return_value = reversed_new_impl(type, seq); + +exit: + return return_value; +} +/*[clinic end generated code: output=e18c3fefcf914ec7 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/floatobject.c.h b/python/Objects/clinic/floatobject.c.h new file mode 100755 index 0000000..b684ba0 --- /dev/null +++ b/python/Objects/clinic/floatobject.c.h @@ -0,0 +1,354 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(float_is_integer__doc__, +"is_integer($self, /)\n" +"--\n" +"\n" +"Return True if the float is an integer."); + +#define FLOAT_IS_INTEGER_METHODDEF \ + {"is_integer", (PyCFunction)float_is_integer, METH_NOARGS, float_is_integer__doc__}, + +static PyObject * +float_is_integer_impl(PyObject *self); + +static PyObject * +float_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return float_is_integer_impl(self); +} + +PyDoc_STRVAR(float___trunc____doc__, +"__trunc__($self, /)\n" +"--\n" +"\n" +"Return the Integral closest to x between 0 and x."); + +#define FLOAT___TRUNC___METHODDEF \ + {"__trunc__", (PyCFunction)float___trunc__, METH_NOARGS, float___trunc____doc__}, + +static PyObject * +float___trunc___impl(PyObject *self); + +static PyObject * +float___trunc__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return float___trunc___impl(self); +} + +PyDoc_STRVAR(float___round____doc__, +"__round__($self, ndigits=None, /)\n" +"--\n" +"\n" +"Return the Integral closest to x, rounding half toward even.\n" +"\n" +"When an argument is passed, work like built-in round(x, ndigits)."); + +#define FLOAT___ROUND___METHODDEF \ + {"__round__", (PyCFunction)(void(*)(void))float___round__, METH_FASTCALL, float___round____doc__}, + +static PyObject * +float___round___impl(PyObject *self, PyObject *o_ndigits); + +static PyObject * +float___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *o_ndigits = Py_None; + + if (!_PyArg_CheckPositional("__round__", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + o_ndigits = args[0]; +skip_optional: + return_value = float___round___impl(self, o_ndigits); + +exit: + return return_value; +} + +PyDoc_STRVAR(float_conjugate__doc__, +"conjugate($self, /)\n" +"--\n" +"\n" +"Return self, the complex conjugate of any float."); + +#define FLOAT_CONJUGATE_METHODDEF \ + {"conjugate", (PyCFunction)float_conjugate, METH_NOARGS, float_conjugate__doc__}, + +static PyObject * +float_conjugate_impl(PyObject *self); + +static PyObject * +float_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return float_conjugate_impl(self); +} + +PyDoc_STRVAR(float_hex__doc__, +"hex($self, /)\n" +"--\n" +"\n" +"Return a hexadecimal representation of a floating-point number.\n" +"\n" +">>> (-0.1).hex()\n" +"\'-0x1.999999999999ap-4\'\n" +">>> 3.14159.hex()\n" +"\'0x1.921f9f01b866ep+1\'"); + +#define FLOAT_HEX_METHODDEF \ + {"hex", (PyCFunction)float_hex, METH_NOARGS, float_hex__doc__}, + +static PyObject * +float_hex_impl(PyObject *self); + +static PyObject * +float_hex(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return float_hex_impl(self); +} + +PyDoc_STRVAR(float_fromhex__doc__, +"fromhex($type, string, /)\n" +"--\n" +"\n" +"Create a floating-point number from a hexadecimal string.\n" +"\n" +">>> float.fromhex(\'0x1.ffffp10\')\n" +"2047.984375\n" +">>> float.fromhex(\'-0x1p-1074\')\n" +"-5e-324"); + +#define FLOAT_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)float_fromhex, METH_O|METH_CLASS, float_fromhex__doc__}, + +PyDoc_STRVAR(float_as_integer_ratio__doc__, +"as_integer_ratio($self, /)\n" +"--\n" +"\n" +"Return integer ratio.\n" +"\n" +"Return a pair of integers, whose ratio is exactly equal to the original float\n" +"and with a positive denominator.\n" +"\n" +"Raise OverflowError on infinities and a ValueError on NaNs.\n" +"\n" +">>> (10.0).as_integer_ratio()\n" +"(10, 1)\n" +">>> (0.0).as_integer_ratio()\n" +"(0, 1)\n" +">>> (-.25).as_integer_ratio()\n" +"(-1, 4)"); + +#define FLOAT_AS_INTEGER_RATIO_METHODDEF \ + {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, float_as_integer_ratio__doc__}, + +static PyObject * +float_as_integer_ratio_impl(PyObject *self); + +static PyObject * +float_as_integer_ratio(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return float_as_integer_ratio_impl(self); +} + +PyDoc_STRVAR(float_new__doc__, +"float(x=0, /)\n" +"--\n" +"\n" +"Convert a string or number to a floating point number, if possible."); + +static PyObject * +float_new_impl(PyTypeObject *type, PyObject *x); + +static PyObject * +float_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *x = _PyLong_Zero; + + if ((type == &PyFloat_Type) && + !_PyArg_NoKeywords("float", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("float", PyTuple_GET_SIZE(args), 0, 1)) { + goto exit; + } + if (PyTuple_GET_SIZE(args) < 1) { + goto skip_optional; + } + x = PyTuple_GET_ITEM(args, 0); +skip_optional: + return_value = float_new_impl(type, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(float___getnewargs____doc__, +"__getnewargs__($self, /)\n" +"--\n" +"\n"); + +#define FLOAT___GETNEWARGS___METHODDEF \ + {"__getnewargs__", (PyCFunction)float___getnewargs__, METH_NOARGS, float___getnewargs____doc__}, + +static PyObject * +float___getnewargs___impl(PyObject *self); + +static PyObject * +float___getnewargs__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return float___getnewargs___impl(self); +} + +PyDoc_STRVAR(float___getformat____doc__, +"__getformat__($type, typestr, /)\n" +"--\n" +"\n" +"You probably don\'t want to use this function.\n" +"\n" +" typestr\n" +" Must be \'double\' or \'float\'.\n" +"\n" +"It exists mainly to be used in Python\'s test suite.\n" +"\n" +"This function returns whichever of \'unknown\', \'IEEE, big-endian\' or \'IEEE,\n" +"little-endian\' best describes the format of floating point numbers used by the\n" +"C type named by typestr."); + +#define FLOAT___GETFORMAT___METHODDEF \ + {"__getformat__", (PyCFunction)float___getformat__, METH_O|METH_CLASS, float___getformat____doc__}, + +static PyObject * +float___getformat___impl(PyTypeObject *type, const char *typestr); + +static PyObject * +float___getformat__(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *typestr; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("__getformat__", "argument", "str", arg); + goto exit; + } + Py_ssize_t typestr_length; + typestr = PyUnicode_AsUTF8AndSize(arg, &typestr_length); + if (typestr == NULL) { + goto exit; + } + if (strlen(typestr) != (size_t)typestr_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = float___getformat___impl(type, typestr); + +exit: + return return_value; +} + +PyDoc_STRVAR(float___set_format____doc__, +"__set_format__($type, typestr, fmt, /)\n" +"--\n" +"\n" +"You probably don\'t want to use this function.\n" +"\n" +" typestr\n" +" Must be \'double\' or \'float\'.\n" +" fmt\n" +" Must be one of \'unknown\', \'IEEE, big-endian\' or \'IEEE, little-endian\',\n" +" and in addition can only be one of the latter two if it appears to\n" +" match the underlying C reality.\n" +"\n" +"It exists mainly to be used in Python\'s test suite.\n" +"\n" +"Override the automatic determination of C-level floating point type.\n" +"This affects how floats are converted to and from binary strings."); + +#define FLOAT___SET_FORMAT___METHODDEF \ + {"__set_format__", (PyCFunction)(void(*)(void))float___set_format__, METH_FASTCALL|METH_CLASS, float___set_format____doc__}, + +static PyObject * +float___set_format___impl(PyTypeObject *type, const char *typestr, + const char *fmt); + +static PyObject * +float___set_format__(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *typestr; + const char *fmt; + + if (!_PyArg_CheckPositional("__set_format__", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("__set_format__", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t typestr_length; + typestr = PyUnicode_AsUTF8AndSize(args[0], &typestr_length); + if (typestr == NULL) { + goto exit; + } + if (strlen(typestr) != (size_t)typestr_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("__set_format__", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t fmt_length; + fmt = PyUnicode_AsUTF8AndSize(args[1], &fmt_length); + if (fmt == NULL) { + goto exit; + } + if (strlen(fmt) != (size_t)fmt_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = float___set_format___impl(type, typestr, fmt); + +exit: + return return_value; +} + +PyDoc_STRVAR(float___format____doc__, +"__format__($self, format_spec, /)\n" +"--\n" +"\n" +"Formats the float according to format_spec."); + +#define FLOAT___FORMAT___METHODDEF \ + {"__format__", (PyCFunction)float___format__, METH_O, float___format____doc__}, + +static PyObject * +float___format___impl(PyObject *self, PyObject *format_spec); + +static PyObject * +float___format__(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *format_spec; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("__format__", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + format_spec = arg; + return_value = float___format___impl(self, format_spec); + +exit: + return return_value; +} +/*[clinic end generated code: output=1676433b9f04fbc9 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/funcobject.c.h b/python/Objects/clinic/funcobject.c.h new file mode 100755 index 0000000..17fb13f --- /dev/null +++ b/python/Objects/clinic/funcobject.c.h @@ -0,0 +1,78 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(func_new__doc__, +"function(code, globals, name=None, argdefs=None, closure=None)\n" +"--\n" +"\n" +"Create a function object.\n" +"\n" +" code\n" +" a code object\n" +" globals\n" +" the globals dictionary\n" +" name\n" +" a string that overrides the name from the code object\n" +" argdefs\n" +" a tuple that specifies the default argument values\n" +" closure\n" +" a tuple that supplies the bindings for free variables"); + +static PyObject * +func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, + PyObject *name, PyObject *defaults, PyObject *closure); + +static PyObject * +func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"code", "globals", "name", "argdefs", "closure", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "function", 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) - 2; + PyCodeObject *code; + PyObject *globals; + PyObject *name = Py_None; + PyObject *defaults = Py_None; + PyObject *closure = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 5, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyObject_TypeCheck(fastargs[0], &PyCode_Type)) { + _PyArg_BadArgument("function", "argument 'code'", (&PyCode_Type)->tp_name, fastargs[0]); + goto exit; + } + code = (PyCodeObject *)fastargs[0]; + if (!PyDict_Check(fastargs[1])) { + _PyArg_BadArgument("function", "argument 'globals'", "dict", fastargs[1]); + goto exit; + } + globals = fastargs[1]; + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[2]) { + name = fastargs[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[3]) { + defaults = fastargs[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + closure = fastargs[4]; +skip_optional_pos: + return_value = func_new_impl(type, code, globals, name, defaults, closure); + +exit: + return return_value; +} +/*[clinic end generated code: output=3d96afa3396e5c82 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/listobject.c.h b/python/Objects/clinic/listobject.c.h new file mode 100755 index 0000000..57f0a48 --- /dev/null +++ b/python/Objects/clinic/listobject.c.h @@ -0,0 +1,370 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(list_insert__doc__, +"insert($self, index, object, /)\n" +"--\n" +"\n" +"Insert object before index."); + +#define LIST_INSERT_METHODDEF \ + {"insert", (PyCFunction)(void(*)(void))list_insert, METH_FASTCALL, list_insert__doc__}, + +static PyObject * +list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object); + +static PyObject * +list_insert(PyListObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t index; + PyObject *object; + + if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + index = ival; + } + object = args[1]; + return_value = list_insert_impl(self, index, object); + +exit: + return return_value; +} + +PyDoc_STRVAR(list_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from list."); + +#define LIST_CLEAR_METHODDEF \ + {"clear", (PyCFunction)list_clear, METH_NOARGS, list_clear__doc__}, + +static PyObject * +list_clear_impl(PyListObject *self); + +static PyObject * +list_clear(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list_clear_impl(self); +} + +PyDoc_STRVAR(list_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a shallow copy of the list."); + +#define LIST_COPY_METHODDEF \ + {"copy", (PyCFunction)list_copy, METH_NOARGS, list_copy__doc__}, + +static PyObject * +list_copy_impl(PyListObject *self); + +static PyObject * +list_copy(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list_copy_impl(self); +} + +PyDoc_STRVAR(list_append__doc__, +"append($self, object, /)\n" +"--\n" +"\n" +"Append object to the end of the list."); + +#define LIST_APPEND_METHODDEF \ + {"append", (PyCFunction)list_append, METH_O, list_append__doc__}, + +PyDoc_STRVAR(list_extend__doc__, +"extend($self, iterable, /)\n" +"--\n" +"\n" +"Extend list by appending elements from the iterable."); + +#define LIST_EXTEND_METHODDEF \ + {"extend", (PyCFunction)list_extend, METH_O, list_extend__doc__}, + +PyDoc_STRVAR(list_pop__doc__, +"pop($self, index=-1, /)\n" +"--\n" +"\n" +"Remove and return item at index (default last).\n" +"\n" +"Raises IndexError if list is empty or index is out of range."); + +#define LIST_POP_METHODDEF \ + {"pop", (PyCFunction)(void(*)(void))list_pop, METH_FASTCALL, list_pop__doc__}, + +static PyObject * +list_pop_impl(PyListObject *self, Py_ssize_t index); + +static PyObject * +list_pop(PyListObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t index = -1; + + if (!_PyArg_CheckPositional("pop", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + index = ival; + } +skip_optional: + return_value = list_pop_impl(self, index); + +exit: + return return_value; +} + +PyDoc_STRVAR(list_sort__doc__, +"sort($self, /, *, key=None, reverse=False)\n" +"--\n" +"\n" +"Sort the list in ascending order and return None.\n" +"\n" +"The sort is in-place (i.e. the list itself is modified) and stable (i.e. the\n" +"order of two equal elements is maintained).\n" +"\n" +"If a key function is given, apply it once to each list item and sort them,\n" +"ascending or descending, according to their function values.\n" +"\n" +"The reverse flag can be set to sort in descending order."); + +#define LIST_SORT_METHODDEF \ + {"sort", (PyCFunction)(void(*)(void))list_sort, METH_FASTCALL|METH_KEYWORDS, list_sort__doc__}, + +static PyObject * +list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse); + +static PyObject * +list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"key", "reverse", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sort", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *keyfunc = Py_None; + int reverse = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[0]) { + keyfunc = args[0]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + reverse = _PyLong_AsInt(args[1]); + if (reverse == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_kwonly: + return_value = list_sort_impl(self, keyfunc, reverse); + +exit: + return return_value; +} + +PyDoc_STRVAR(list_reverse__doc__, +"reverse($self, /)\n" +"--\n" +"\n" +"Reverse *IN PLACE*."); + +#define LIST_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)list_reverse, METH_NOARGS, list_reverse__doc__}, + +static PyObject * +list_reverse_impl(PyListObject *self); + +static PyObject * +list_reverse(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list_reverse_impl(self); +} + +PyDoc_STRVAR(list_index__doc__, +"index($self, value, start=0, stop=sys.maxsize, /)\n" +"--\n" +"\n" +"Return first index of value.\n" +"\n" +"Raises ValueError if the value is not present."); + +#define LIST_INDEX_METHODDEF \ + {"index", (PyCFunction)(void(*)(void))list_index, METH_FASTCALL, list_index__doc__}, + +static PyObject * +list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start, + Py_ssize_t stop); + +static PyObject * +list_index(PyListObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *value; + Py_ssize_t start = 0; + Py_ssize_t stop = PY_SSIZE_T_MAX; + + if (!_PyArg_CheckPositional("index", nargs, 1, 3)) { + goto exit; + } + value = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (!_PyEval_SliceIndexNotNone(args[1], &start)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyEval_SliceIndexNotNone(args[2], &stop)) { + goto exit; + } +skip_optional: + return_value = list_index_impl(self, value, start, stop); + +exit: + return return_value; +} + +PyDoc_STRVAR(list_count__doc__, +"count($self, value, /)\n" +"--\n" +"\n" +"Return number of occurrences of value."); + +#define LIST_COUNT_METHODDEF \ + {"count", (PyCFunction)list_count, METH_O, list_count__doc__}, + +PyDoc_STRVAR(list_remove__doc__, +"remove($self, value, /)\n" +"--\n" +"\n" +"Remove first occurrence of value.\n" +"\n" +"Raises ValueError if the value is not present."); + +#define LIST_REMOVE_METHODDEF \ + {"remove", (PyCFunction)list_remove, METH_O, list_remove__doc__}, + +PyDoc_STRVAR(list___init____doc__, +"list(iterable=(), /)\n" +"--\n" +"\n" +"Built-in mutable sequence.\n" +"\n" +"If no argument is given, the constructor creates a new empty list.\n" +"The argument must be an iterable if specified."); + +static int +list___init___impl(PyListObject *self, PyObject *iterable); + +static int +list___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + PyObject *iterable = NULL; + + if ((Py_TYPE(self) == &PyList_Type) && + !_PyArg_NoKeywords("list", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("list", PyTuple_GET_SIZE(args), 0, 1)) { + goto exit; + } + if (PyTuple_GET_SIZE(args) < 1) { + goto skip_optional; + } + iterable = PyTuple_GET_ITEM(args, 0); +skip_optional: + return_value = list___init___impl((PyListObject *)self, iterable); + +exit: + return return_value; +} + +PyDoc_STRVAR(list___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Return the size of the list in memory, in bytes."); + +#define LIST___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)list___sizeof__, METH_NOARGS, list___sizeof____doc__}, + +static PyObject * +list___sizeof___impl(PyListObject *self); + +static PyObject * +list___sizeof__(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list___sizeof___impl(self); +} + +PyDoc_STRVAR(list___reversed____doc__, +"__reversed__($self, /)\n" +"--\n" +"\n" +"Return a reverse iterator over the list."); + +#define LIST___REVERSED___METHODDEF \ + {"__reversed__", (PyCFunction)list___reversed__, METH_NOARGS, list___reversed____doc__}, + +static PyObject * +list___reversed___impl(PyListObject *self); + +static PyObject * +list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list___reversed___impl(self); +} +/*[clinic end generated code: output=73718c0c33798c62 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/longobject.c.h b/python/Objects/clinic/longobject.c.h new file mode 100755 index 0000000..27e8dfe --- /dev/null +++ b/python/Objects/clinic/longobject.c.h @@ -0,0 +1,316 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static PyObject * +long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); + +static PyObject * +long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "base", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "int", 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 *x = NULL; + PyObject *obase = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + noptargs--; + x = fastargs[0]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_pos; + } + obase = fastargs[1]; +skip_optional_pos: + return_value = long_new_impl(type, x, obase); + +exit: + return return_value; +} + +PyDoc_STRVAR(int___getnewargs____doc__, +"__getnewargs__($self, /)\n" +"--\n" +"\n"); + +#define INT___GETNEWARGS___METHODDEF \ + {"__getnewargs__", (PyCFunction)int___getnewargs__, METH_NOARGS, int___getnewargs____doc__}, + +static PyObject * +int___getnewargs___impl(PyObject *self); + +static PyObject * +int___getnewargs__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int___getnewargs___impl(self); +} + +PyDoc_STRVAR(int___format____doc__, +"__format__($self, format_spec, /)\n" +"--\n" +"\n"); + +#define INT___FORMAT___METHODDEF \ + {"__format__", (PyCFunction)int___format__, METH_O, int___format____doc__}, + +static PyObject * +int___format___impl(PyObject *self, PyObject *format_spec); + +static PyObject * +int___format__(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *format_spec; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("__format__", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + format_spec = arg; + return_value = int___format___impl(self, format_spec); + +exit: + return return_value; +} + +PyDoc_STRVAR(int___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns size in memory, in bytes."); + +#define INT___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)int___sizeof__, METH_NOARGS, int___sizeof____doc__}, + +static Py_ssize_t +int___sizeof___impl(PyObject *self); + +static PyObject * +int___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = int___sizeof___impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(int_bit_length__doc__, +"bit_length($self, /)\n" +"--\n" +"\n" +"Number of bits necessary to represent self in binary.\n" +"\n" +">>> bin(37)\n" +"\'0b100101\'\n" +">>> (37).bit_length()\n" +"6"); + +#define INT_BIT_LENGTH_METHODDEF \ + {"bit_length", (PyCFunction)int_bit_length, METH_NOARGS, int_bit_length__doc__}, + +static PyObject * +int_bit_length_impl(PyObject *self); + +static PyObject * +int_bit_length(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_bit_length_impl(self); +} + +PyDoc_STRVAR(int_as_integer_ratio__doc__, +"as_integer_ratio($self, /)\n" +"--\n" +"\n" +"Return integer ratio.\n" +"\n" +"Return a pair of integers, whose ratio is exactly equal to the original int\n" +"and with a positive denominator.\n" +"\n" +">>> (10).as_integer_ratio()\n" +"(10, 1)\n" +">>> (-10).as_integer_ratio()\n" +"(-10, 1)\n" +">>> (0).as_integer_ratio()\n" +"(0, 1)"); + +#define INT_AS_INTEGER_RATIO_METHODDEF \ + {"as_integer_ratio", (PyCFunction)int_as_integer_ratio, METH_NOARGS, int_as_integer_ratio__doc__}, + +static PyObject * +int_as_integer_ratio_impl(PyObject *self); + +static PyObject * +int_as_integer_ratio(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_as_integer_ratio_impl(self); +} + +PyDoc_STRVAR(int_to_bytes__doc__, +"to_bytes($self, /, length, byteorder, *, signed=False)\n" +"--\n" +"\n" +"Return an array of bytes representing an integer.\n" +"\n" +" length\n" +" Length of bytes object to use. An OverflowError is raised if the\n" +" integer is not representable with the given number of bytes.\n" +" byteorder\n" +" The byte order used to represent the integer. If byteorder is \'big\',\n" +" the most significant byte is at the beginning of the byte array. If\n" +" byteorder is \'little\', the most significant byte is at the end of the\n" +" byte array. To request the native byte order of the host system, use\n" +" `sys.byteorder\' as the byte order value.\n" +" signed\n" +" Determines whether two\'s complement is used to represent the integer.\n" +" If signed is False and a negative integer is given, an OverflowError\n" +" is raised."); + +#define INT_TO_BYTES_METHODDEF \ + {"to_bytes", (PyCFunction)(void(*)(void))int_to_bytes, METH_FASTCALL|METH_KEYWORDS, int_to_bytes__doc__}, + +static PyObject * +int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder, + int is_signed); + +static PyObject * +int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"length", "byteorder", "signed", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "to_bytes", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + Py_ssize_t length; + PyObject *byteorder; + int is_signed = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + length = ival; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("to_bytes", "argument 'byteorder'", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + byteorder = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + is_signed = PyObject_IsTrue(args[2]); + if (is_signed < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = int_to_bytes_impl(self, length, byteorder, is_signed); + +exit: + return return_value; +} + +PyDoc_STRVAR(int_from_bytes__doc__, +"from_bytes($type, /, bytes, byteorder, *, signed=False)\n" +"--\n" +"\n" +"Return the integer represented by the given array of bytes.\n" +"\n" +" bytes\n" +" Holds the array of bytes to convert. The argument must either\n" +" support the buffer protocol or be an iterable object producing bytes.\n" +" Bytes and bytearray are examples of built-in objects that support the\n" +" buffer protocol.\n" +" byteorder\n" +" The byte order used to represent the integer. If byteorder is \'big\',\n" +" the most significant byte is at the beginning of the byte array. If\n" +" byteorder is \'little\', the most significant byte is at the end of the\n" +" byte array. To request the native byte order of the host system, use\n" +" `sys.byteorder\' as the byte order value.\n" +" signed\n" +" Indicates whether two\'s complement is used to represent the integer."); + +#define INT_FROM_BYTES_METHODDEF \ + {"from_bytes", (PyCFunction)(void(*)(void))int_from_bytes, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, int_from_bytes__doc__}, + +static PyObject * +int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj, + PyObject *byteorder, int is_signed); + +static PyObject * +int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"bytes", "byteorder", "signed", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "from_bytes", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *bytes_obj; + PyObject *byteorder; + int is_signed = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + bytes_obj = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("from_bytes", "argument 'byteorder'", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + byteorder = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + is_signed = PyObject_IsTrue(args[2]); + if (is_signed < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = int_from_bytes_impl(type, bytes_obj, byteorder, is_signed); + +exit: + return return_value; +} +/*[clinic end generated code: output=77bc3b2615822cb8 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/memoryobject.c.h b/python/Objects/clinic/memoryobject.c.h new file mode 100755 index 0000000..75ac201 --- /dev/null +++ b/python/Objects/clinic/memoryobject.c.h @@ -0,0 +1,74 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(memoryview_hex__doc__, +"hex($self, /, sep=, bytes_per_sep=1)\n" +"--\n" +"\n" +"Return the data in the buffer as a str of hexadecimal numbers.\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" +"Example:\n" +">>> value = memoryview(b\'\\xb9\\x01\\xef\')\n" +">>> value.hex()\n" +"\'b901ef\'\n" +">>> value.hex(\':\')\n" +"\'b9:01:ef\'\n" +">>> value.hex(\':\', 2)\n" +"\'b9:01ef\'\n" +">>> value.hex(\':\', -2)\n" +"\'b901:ef\'"); + +#define MEMORYVIEW_HEX_METHODDEF \ + {"hex", (PyCFunction)(void(*)(void))memoryview_hex, METH_FASTCALL|METH_KEYWORDS, memoryview_hex__doc__}, + +static PyObject * +memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep, + int bytes_per_sep); + +static PyObject * +memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[1]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = memoryview_hex_impl(self, sep, bytes_per_sep); + +exit: + return return_value; +} +/*[clinic end generated code: output=ee265a73f68b0077 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/moduleobject.c.h b/python/Objects/clinic/moduleobject.c.h new file mode 100755 index 0000000..c1534ea --- /dev/null +++ b/python/Objects/clinic/moduleobject.c.h @@ -0,0 +1,51 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(module___init____doc__, +"module(name, doc=None)\n" +"--\n" +"\n" +"Create a module object.\n" +"\n" +"The name must be a string; the optional doc argument can have any type."); + +static int +module___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc); + +static int +module___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"name", "doc", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "module", 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 *name; + PyObject *doc = Py_None; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("module", "argument 'name'", "str", fastargs[0]); + goto exit; + } + if (PyUnicode_READY(fastargs[0]) == -1) { + goto exit; + } + name = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + doc = fastargs[1]; +skip_optional_pos: + return_value = module___init___impl((PyModuleObject *)self, name, doc); + +exit: + return return_value; +} +/*[clinic end generated code: output=680276bc3a496d7a input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/odictobject.c.h b/python/Objects/clinic/odictobject.c.h new file mode 100755 index 0000000..f43bc14 --- /dev/null +++ b/python/Objects/clinic/odictobject.c.h @@ -0,0 +1,171 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(OrderedDict_fromkeys__doc__, +"fromkeys($type, /, iterable, value=None)\n" +"--\n" +"\n" +"Create a new ordered dictionary with keys from iterable and values set to value."); + +#define ORDEREDDICT_FROMKEYS_METHODDEF \ + {"fromkeys", (PyCFunction)(void(*)(void))OrderedDict_fromkeys, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, OrderedDict_fromkeys__doc__}, + +static PyObject * +OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value); + +static PyObject * +OrderedDict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"iterable", "value", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "fromkeys", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *seq; + PyObject *value = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + seq = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + value = args[1]; +skip_optional_pos: + return_value = OrderedDict_fromkeys_impl(type, seq, value); + +exit: + return return_value; +} + +PyDoc_STRVAR(OrderedDict_setdefault__doc__, +"setdefault($self, /, key, default=None)\n" +"--\n" +"\n" +"Insert key with a value of default if key is not in the dictionary.\n" +"\n" +"Return the value for key if key is in the dictionary, else default."); + +#define ORDEREDDICT_SETDEFAULT_METHODDEF \ + {"setdefault", (PyCFunction)(void(*)(void))OrderedDict_setdefault, METH_FASTCALL|METH_KEYWORDS, OrderedDict_setdefault__doc__}, + +static PyObject * +OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, + PyObject *default_value); + +static PyObject * +OrderedDict_setdefault(PyODictObject *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, "setdefault", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *key; + PyObject *default_value = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + key = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + default_value = args[1]; +skip_optional_pos: + return_value = OrderedDict_setdefault_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(OrderedDict_popitem__doc__, +"popitem($self, /, last=True)\n" +"--\n" +"\n" +"Remove and return a (key, value) pair from the dictionary.\n" +"\n" +"Pairs are returned in LIFO order if last is true or FIFO order if false."); + +#define ORDEREDDICT_POPITEM_METHODDEF \ + {"popitem", (PyCFunction)(void(*)(void))OrderedDict_popitem, METH_FASTCALL|METH_KEYWORDS, OrderedDict_popitem__doc__}, + +static PyObject * +OrderedDict_popitem_impl(PyODictObject *self, int last); + +static PyObject * +OrderedDict_popitem(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"last", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "popitem", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int last = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + last = PyObject_IsTrue(args[0]); + if (last < 0) { + goto exit; + } +skip_optional_pos: + return_value = OrderedDict_popitem_impl(self, last); + +exit: + return return_value; +} + +PyDoc_STRVAR(OrderedDict_move_to_end__doc__, +"move_to_end($self, /, key, last=True)\n" +"--\n" +"\n" +"Move an existing element to the end (or beginning if last is false).\n" +"\n" +"Raise KeyError if the element does not exist."); + +#define ORDEREDDICT_MOVE_TO_END_METHODDEF \ + {"move_to_end", (PyCFunction)(void(*)(void))OrderedDict_move_to_end, METH_FASTCALL|METH_KEYWORDS, OrderedDict_move_to_end__doc__}, + +static PyObject * +OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last); + +static PyObject * +OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"key", "last", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "move_to_end", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *key; + int last = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + key = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + last = PyObject_IsTrue(args[1]); + if (last < 0) { + goto exit; + } +skip_optional_pos: + return_value = OrderedDict_move_to_end_impl(self, key, last); + +exit: + return return_value; +} +/*[clinic end generated code: output=8eb1296df9142908 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/structseq.c.h b/python/Objects/clinic/structseq.c.h new file mode 100755 index 0000000..b3b4836 --- /dev/null +++ b/python/Objects/clinic/structseq.c.h @@ -0,0 +1,36 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +static PyObject * +structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict); + +static PyObject * +structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sequence", "dict", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "structseq", 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 *arg; + PyObject *dict = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + arg = fastargs[0]; + if (!noptargs) { + goto skip_optional_pos; + } + dict = fastargs[1]; +skip_optional_pos: + return_value = structseq_new_impl(type, arg, dict); + +exit: + return return_value; +} +/*[clinic end generated code: output=ed3019acf49b656c input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/tupleobject.c.h b/python/Objects/clinic/tupleobject.c.h new file mode 100755 index 0000000..fe2fae4 --- /dev/null +++ b/python/Objects/clinic/tupleobject.c.h @@ -0,0 +1,114 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(tuple_index__doc__, +"index($self, value, start=0, stop=sys.maxsize, /)\n" +"--\n" +"\n" +"Return first index of value.\n" +"\n" +"Raises ValueError if the value is not present."); + +#define TUPLE_INDEX_METHODDEF \ + {"index", (PyCFunction)(void(*)(void))tuple_index, METH_FASTCALL, tuple_index__doc__}, + +static PyObject * +tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start, + Py_ssize_t stop); + +static PyObject * +tuple_index(PyTupleObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *value; + Py_ssize_t start = 0; + Py_ssize_t stop = PY_SSIZE_T_MAX; + + if (!_PyArg_CheckPositional("index", nargs, 1, 3)) { + goto exit; + } + value = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (!_PyEval_SliceIndexNotNone(args[1], &start)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyEval_SliceIndexNotNone(args[2], &stop)) { + goto exit; + } +skip_optional: + return_value = tuple_index_impl(self, value, start, stop); + +exit: + return return_value; +} + +PyDoc_STRVAR(tuple_count__doc__, +"count($self, value, /)\n" +"--\n" +"\n" +"Return number of occurrences of value."); + +#define TUPLE_COUNT_METHODDEF \ + {"count", (PyCFunction)tuple_count, METH_O, tuple_count__doc__}, + +PyDoc_STRVAR(tuple_new__doc__, +"tuple(iterable=(), /)\n" +"--\n" +"\n" +"Built-in immutable sequence.\n" +"\n" +"If no argument is given, the constructor returns an empty tuple.\n" +"If iterable is specified the tuple is initialized from iterable\'s items.\n" +"\n" +"If the argument is a tuple, the return value is the same object."); + +static PyObject * +tuple_new_impl(PyTypeObject *type, PyObject *iterable); + +static PyObject * +tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *iterable = NULL; + + if ((type == &PyTuple_Type) && + !_PyArg_NoKeywords("tuple", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("tuple", PyTuple_GET_SIZE(args), 0, 1)) { + goto exit; + } + if (PyTuple_GET_SIZE(args) < 1) { + goto skip_optional; + } + iterable = PyTuple_GET_ITEM(args, 0); +skip_optional: + return_value = tuple_new_impl(type, iterable); + +exit: + return return_value; +} + +PyDoc_STRVAR(tuple___getnewargs____doc__, +"__getnewargs__($self, /)\n" +"--\n" +"\n"); + +#define TUPLE___GETNEWARGS___METHODDEF \ + {"__getnewargs__", (PyCFunction)tuple___getnewargs__, METH_NOARGS, tuple___getnewargs____doc__}, + +static PyObject * +tuple___getnewargs___impl(PyTupleObject *self); + +static PyObject * +tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored)) +{ + return tuple___getnewargs___impl(self); +} +/*[clinic end generated code: output=56fab9b7368aba49 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/typeobject.c.h b/python/Objects/clinic/typeobject.c.h new file mode 100755 index 0000000..357eb44 --- /dev/null +++ b/python/Objects/clinic/typeobject.c.h @@ -0,0 +1,251 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(type___instancecheck____doc__, +"__instancecheck__($self, instance, /)\n" +"--\n" +"\n" +"Check if an object is an instance."); + +#define TYPE___INSTANCECHECK___METHODDEF \ + {"__instancecheck__", (PyCFunction)type___instancecheck__, METH_O, type___instancecheck____doc__}, + +static int +type___instancecheck___impl(PyTypeObject *self, PyObject *instance); + +static PyObject * +type___instancecheck__(PyTypeObject *self, PyObject *instance) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = type___instancecheck___impl(self, instance); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(type___subclasscheck____doc__, +"__subclasscheck__($self, subclass, /)\n" +"--\n" +"\n" +"Check if a class is a subclass."); + +#define TYPE___SUBCLASSCHECK___METHODDEF \ + {"__subclasscheck__", (PyCFunction)type___subclasscheck__, METH_O, type___subclasscheck____doc__}, + +static int +type___subclasscheck___impl(PyTypeObject *self, PyObject *subclass); + +static PyObject * +type___subclasscheck__(PyTypeObject *self, PyObject *subclass) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = type___subclasscheck___impl(self, subclass); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(type_mro__doc__, +"mro($self, /)\n" +"--\n" +"\n" +"Return a type\'s method resolution order."); + +#define TYPE_MRO_METHODDEF \ + {"mro", (PyCFunction)type_mro, METH_NOARGS, type_mro__doc__}, + +static PyObject * +type_mro_impl(PyTypeObject *self); + +static PyObject * +type_mro(PyTypeObject *self, PyObject *Py_UNUSED(ignored)) +{ + return type_mro_impl(self); +} + +PyDoc_STRVAR(type___subclasses____doc__, +"__subclasses__($self, /)\n" +"--\n" +"\n" +"Return a list of immediate subclasses."); + +#define TYPE___SUBCLASSES___METHODDEF \ + {"__subclasses__", (PyCFunction)type___subclasses__, METH_NOARGS, type___subclasses____doc__}, + +static PyObject * +type___subclasses___impl(PyTypeObject *self); + +static PyObject * +type___subclasses__(PyTypeObject *self, PyObject *Py_UNUSED(ignored)) +{ + return type___subclasses___impl(self); +} + +PyDoc_STRVAR(type___dir____doc__, +"__dir__($self, /)\n" +"--\n" +"\n" +"Specialized __dir__ implementation for types."); + +#define TYPE___DIR___METHODDEF \ + {"__dir__", (PyCFunction)type___dir__, METH_NOARGS, type___dir____doc__}, + +static PyObject * +type___dir___impl(PyTypeObject *self); + +static PyObject * +type___dir__(PyTypeObject *self, PyObject *Py_UNUSED(ignored)) +{ + return type___dir___impl(self); +} + +PyDoc_STRVAR(type___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Return memory consumption of the type object."); + +#define TYPE___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)type___sizeof__, METH_NOARGS, type___sizeof____doc__}, + +static PyObject * +type___sizeof___impl(PyTypeObject *self); + +static PyObject * +type___sizeof__(PyTypeObject *self, PyObject *Py_UNUSED(ignored)) +{ + return type___sizeof___impl(self); +} + +PyDoc_STRVAR(object___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Helper for pickle."); + +#define OBJECT___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)object___reduce__, METH_NOARGS, object___reduce____doc__}, + +static PyObject * +object___reduce___impl(PyObject *self); + +static PyObject * +object___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return object___reduce___impl(self); +} + +PyDoc_STRVAR(object___reduce_ex____doc__, +"__reduce_ex__($self, protocol, /)\n" +"--\n" +"\n" +"Helper for pickle."); + +#define OBJECT___REDUCE_EX___METHODDEF \ + {"__reduce_ex__", (PyCFunction)object___reduce_ex__, METH_O, object___reduce_ex____doc__}, + +static PyObject * +object___reduce_ex___impl(PyObject *self, int protocol); + +static PyObject * +object___reduce_ex__(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int protocol; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + protocol = _PyLong_AsInt(arg); + if (protocol == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = object___reduce_ex___impl(self, protocol); + +exit: + return return_value; +} + +PyDoc_STRVAR(object___format____doc__, +"__format__($self, format_spec, /)\n" +"--\n" +"\n" +"Default object formatter."); + +#define OBJECT___FORMAT___METHODDEF \ + {"__format__", (PyCFunction)object___format__, METH_O, object___format____doc__}, + +static PyObject * +object___format___impl(PyObject *self, PyObject *format_spec); + +static PyObject * +object___format__(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *format_spec; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("__format__", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + format_spec = arg; + return_value = object___format___impl(self, format_spec); + +exit: + return return_value; +} + +PyDoc_STRVAR(object___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Size of object in memory, in bytes."); + +#define OBJECT___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)object___sizeof__, METH_NOARGS, object___sizeof____doc__}, + +static PyObject * +object___sizeof___impl(PyObject *self); + +static PyObject * +object___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return object___sizeof___impl(self); +} + +PyDoc_STRVAR(object___dir____doc__, +"__dir__($self, /)\n" +"--\n" +"\n" +"Default dir() implementation."); + +#define OBJECT___DIR___METHODDEF \ + {"__dir__", (PyCFunction)object___dir__, METH_NOARGS, object___dir____doc__}, + +static PyObject * +object___dir___impl(PyObject *self); + +static PyObject * +object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return object___dir___impl(self); +} +/*[clinic end generated code: output=7a6d272d282308f3 input=a9049054013a1b77]*/ diff --git a/python/Objects/clinic/unicodeobject.c.h b/python/Objects/clinic/unicodeobject.c.h new file mode 100755 index 0000000..0d13406 --- /dev/null +++ b/python/Objects/clinic/unicodeobject.c.h @@ -0,0 +1,1235 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(unicode_title__doc__, +"title($self, /)\n" +"--\n" +"\n" +"Return a version of the string where each word is titlecased.\n" +"\n" +"More specifically, words start with uppercased characters and all remaining\n" +"cased characters have lower case."); + +#define UNICODE_TITLE_METHODDEF \ + {"title", (PyCFunction)unicode_title, METH_NOARGS, unicode_title__doc__}, + +static PyObject * +unicode_title_impl(PyObject *self); + +static PyObject * +unicode_title(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_title_impl(self); +} + +PyDoc_STRVAR(unicode_capitalize__doc__, +"capitalize($self, /)\n" +"--\n" +"\n" +"Return a capitalized version of the string.\n" +"\n" +"More specifically, make the first character have upper case and the rest lower\n" +"case."); + +#define UNICODE_CAPITALIZE_METHODDEF \ + {"capitalize", (PyCFunction)unicode_capitalize, METH_NOARGS, unicode_capitalize__doc__}, + +static PyObject * +unicode_capitalize_impl(PyObject *self); + +static PyObject * +unicode_capitalize(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_capitalize_impl(self); +} + +PyDoc_STRVAR(unicode_casefold__doc__, +"casefold($self, /)\n" +"--\n" +"\n" +"Return a version of the string suitable for caseless comparisons."); + +#define UNICODE_CASEFOLD_METHODDEF \ + {"casefold", (PyCFunction)unicode_casefold, METH_NOARGS, unicode_casefold__doc__}, + +static PyObject * +unicode_casefold_impl(PyObject *self); + +static PyObject * +unicode_casefold(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_casefold_impl(self); +} + +PyDoc_STRVAR(unicode_center__doc__, +"center($self, width, fillchar=\' \', /)\n" +"--\n" +"\n" +"Return a centered string of length width.\n" +"\n" +"Padding is done using the specified fill character (default is a space)."); + +#define UNICODE_CENTER_METHODDEF \ + {"center", (PyCFunction)(void(*)(void))unicode_center, METH_FASTCALL, unicode_center__doc__}, + +static PyObject * +unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar); + +static PyObject * +unicode_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + Py_UCS4 fillchar = ' '; + + if (!_PyArg_CheckPositional("center", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (!convert_uc(args[1], &fillchar)) { + goto exit; + } +skip_optional: + return_value = unicode_center_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_encode__doc__, +"encode($self, /, encoding=\'utf-8\', errors=\'strict\')\n" +"--\n" +"\n" +"Encode the string using the codec registered for encoding.\n" +"\n" +" encoding\n" +" The encoding in which to encode the string.\n" +" errors\n" +" The error handling scheme to use for encoding errors.\n" +" The default is \'strict\' meaning that encoding errors raise a\n" +" UnicodeEncodeError. Other possible values are \'ignore\', \'replace\' and\n" +" \'xmlcharrefreplace\' as well as any other name registered with\n" +" codecs.register_error that can handle UnicodeEncodeErrors."); + +#define UNICODE_ENCODE_METHODDEF \ + {"encode", (PyCFunction)(void(*)(void))unicode_encode, METH_FASTCALL|METH_KEYWORDS, unicode_encode__doc__}, + +static PyObject * +unicode_encode_impl(PyObject *self, const char *encoding, const char *errors); + +static PyObject * +unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"encoding", "errors", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + const char *encoding = NULL; + const char *errors = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("encode", "argument 'encoding'", "str", args[0]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[0], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("encode", "argument 'errors'", "str", args[1]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_pos: + return_value = unicode_encode_impl(self, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_expandtabs__doc__, +"expandtabs($self, /, tabsize=8)\n" +"--\n" +"\n" +"Return a copy where all tab characters are expanded using spaces.\n" +"\n" +"If tabsize is not given, a tab size of 8 characters is assumed."); + +#define UNICODE_EXPANDTABS_METHODDEF \ + {"expandtabs", (PyCFunction)(void(*)(void))unicode_expandtabs, METH_FASTCALL|METH_KEYWORDS, unicode_expandtabs__doc__}, + +static PyObject * +unicode_expandtabs_impl(PyObject *self, int tabsize); + +static PyObject * +unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"tabsize", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int tabsize = 8; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + tabsize = _PyLong_AsInt(args[0]); + if (tabsize == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = unicode_expandtabs_impl(self, tabsize); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_isascii__doc__, +"isascii($self, /)\n" +"--\n" +"\n" +"Return True if all characters in the string are ASCII, False otherwise.\n" +"\n" +"ASCII characters have code points in the range U+0000-U+007F.\n" +"Empty string is ASCII too."); + +#define UNICODE_ISASCII_METHODDEF \ + {"isascii", (PyCFunction)unicode_isascii, METH_NOARGS, unicode_isascii__doc__}, + +static PyObject * +unicode_isascii_impl(PyObject *self); + +static PyObject * +unicode_isascii(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isascii_impl(self); +} + +PyDoc_STRVAR(unicode_islower__doc__, +"islower($self, /)\n" +"--\n" +"\n" +"Return True if the string is a lowercase string, False otherwise.\n" +"\n" +"A string is lowercase if all cased characters in the string are lowercase and\n" +"there is at least one cased character in the string."); + +#define UNICODE_ISLOWER_METHODDEF \ + {"islower", (PyCFunction)unicode_islower, METH_NOARGS, unicode_islower__doc__}, + +static PyObject * +unicode_islower_impl(PyObject *self); + +static PyObject * +unicode_islower(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_islower_impl(self); +} + +PyDoc_STRVAR(unicode_isupper__doc__, +"isupper($self, /)\n" +"--\n" +"\n" +"Return True if the string is an uppercase string, False otherwise.\n" +"\n" +"A string is uppercase if all cased characters in the string are uppercase and\n" +"there is at least one cased character in the string."); + +#define UNICODE_ISUPPER_METHODDEF \ + {"isupper", (PyCFunction)unicode_isupper, METH_NOARGS, unicode_isupper__doc__}, + +static PyObject * +unicode_isupper_impl(PyObject *self); + +static PyObject * +unicode_isupper(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isupper_impl(self); +} + +PyDoc_STRVAR(unicode_istitle__doc__, +"istitle($self, /)\n" +"--\n" +"\n" +"Return True if the string is a title-cased string, False otherwise.\n" +"\n" +"In a title-cased string, upper- and title-case characters may only\n" +"follow uncased characters and lowercase characters only cased ones."); + +#define UNICODE_ISTITLE_METHODDEF \ + {"istitle", (PyCFunction)unicode_istitle, METH_NOARGS, unicode_istitle__doc__}, + +static PyObject * +unicode_istitle_impl(PyObject *self); + +static PyObject * +unicode_istitle(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_istitle_impl(self); +} + +PyDoc_STRVAR(unicode_isspace__doc__, +"isspace($self, /)\n" +"--\n" +"\n" +"Return True if the string is a whitespace string, False otherwise.\n" +"\n" +"A string is whitespace if all characters in the string are whitespace and there\n" +"is at least one character in the string."); + +#define UNICODE_ISSPACE_METHODDEF \ + {"isspace", (PyCFunction)unicode_isspace, METH_NOARGS, unicode_isspace__doc__}, + +static PyObject * +unicode_isspace_impl(PyObject *self); + +static PyObject * +unicode_isspace(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isspace_impl(self); +} + +PyDoc_STRVAR(unicode_isalpha__doc__, +"isalpha($self, /)\n" +"--\n" +"\n" +"Return True if the string is an alphabetic string, False otherwise.\n" +"\n" +"A string is alphabetic if all characters in the string are alphabetic and there\n" +"is at least one character in the string."); + +#define UNICODE_ISALPHA_METHODDEF \ + {"isalpha", (PyCFunction)unicode_isalpha, METH_NOARGS, unicode_isalpha__doc__}, + +static PyObject * +unicode_isalpha_impl(PyObject *self); + +static PyObject * +unicode_isalpha(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isalpha_impl(self); +} + +PyDoc_STRVAR(unicode_isalnum__doc__, +"isalnum($self, /)\n" +"--\n" +"\n" +"Return True if the string is an alpha-numeric string, False otherwise.\n" +"\n" +"A string is alpha-numeric if all characters in the string are alpha-numeric and\n" +"there is at least one character in the string."); + +#define UNICODE_ISALNUM_METHODDEF \ + {"isalnum", (PyCFunction)unicode_isalnum, METH_NOARGS, unicode_isalnum__doc__}, + +static PyObject * +unicode_isalnum_impl(PyObject *self); + +static PyObject * +unicode_isalnum(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isalnum_impl(self); +} + +PyDoc_STRVAR(unicode_isdecimal__doc__, +"isdecimal($self, /)\n" +"--\n" +"\n" +"Return True if the string is a decimal string, False otherwise.\n" +"\n" +"A string is a decimal string if all characters in the string are decimal and\n" +"there is at least one character in the string."); + +#define UNICODE_ISDECIMAL_METHODDEF \ + {"isdecimal", (PyCFunction)unicode_isdecimal, METH_NOARGS, unicode_isdecimal__doc__}, + +static PyObject * +unicode_isdecimal_impl(PyObject *self); + +static PyObject * +unicode_isdecimal(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isdecimal_impl(self); +} + +PyDoc_STRVAR(unicode_isdigit__doc__, +"isdigit($self, /)\n" +"--\n" +"\n" +"Return True if the string is a digit string, False otherwise.\n" +"\n" +"A string is a digit string if all characters in the string are digits and there\n" +"is at least one character in the string."); + +#define UNICODE_ISDIGIT_METHODDEF \ + {"isdigit", (PyCFunction)unicode_isdigit, METH_NOARGS, unicode_isdigit__doc__}, + +static PyObject * +unicode_isdigit_impl(PyObject *self); + +static PyObject * +unicode_isdigit(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isdigit_impl(self); +} + +PyDoc_STRVAR(unicode_isnumeric__doc__, +"isnumeric($self, /)\n" +"--\n" +"\n" +"Return True if the string is a numeric string, False otherwise.\n" +"\n" +"A string is numeric if all characters in the string are numeric and there is at\n" +"least one character in the string."); + +#define UNICODE_ISNUMERIC_METHODDEF \ + {"isnumeric", (PyCFunction)unicode_isnumeric, METH_NOARGS, unicode_isnumeric__doc__}, + +static PyObject * +unicode_isnumeric_impl(PyObject *self); + +static PyObject * +unicode_isnumeric(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isnumeric_impl(self); +} + +PyDoc_STRVAR(unicode_isidentifier__doc__, +"isidentifier($self, /)\n" +"--\n" +"\n" +"Return True if the string is a valid Python identifier, False otherwise.\n" +"\n" +"Call keyword.iskeyword(s) to test whether string s is a reserved identifier,\n" +"such as \"def\" or \"class\"."); + +#define UNICODE_ISIDENTIFIER_METHODDEF \ + {"isidentifier", (PyCFunction)unicode_isidentifier, METH_NOARGS, unicode_isidentifier__doc__}, + +static PyObject * +unicode_isidentifier_impl(PyObject *self); + +static PyObject * +unicode_isidentifier(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isidentifier_impl(self); +} + +PyDoc_STRVAR(unicode_isprintable__doc__, +"isprintable($self, /)\n" +"--\n" +"\n" +"Return True if the string is printable, False otherwise.\n" +"\n" +"A string is printable if all of its characters are considered printable in\n" +"repr() or if it is empty."); + +#define UNICODE_ISPRINTABLE_METHODDEF \ + {"isprintable", (PyCFunction)unicode_isprintable, METH_NOARGS, unicode_isprintable__doc__}, + +static PyObject * +unicode_isprintable_impl(PyObject *self); + +static PyObject * +unicode_isprintable(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_isprintable_impl(self); +} + +PyDoc_STRVAR(unicode_join__doc__, +"join($self, iterable, /)\n" +"--\n" +"\n" +"Concatenate any number of strings.\n" +"\n" +"The string whose method is called is inserted in between each given string.\n" +"The result is returned as a new string.\n" +"\n" +"Example: \'.\'.join([\'ab\', \'pq\', \'rs\']) -> \'ab.pq.rs\'"); + +#define UNICODE_JOIN_METHODDEF \ + {"join", (PyCFunction)unicode_join, METH_O, unicode_join__doc__}, + +PyDoc_STRVAR(unicode_ljust__doc__, +"ljust($self, width, fillchar=\' \', /)\n" +"--\n" +"\n" +"Return a left-justified string of length width.\n" +"\n" +"Padding is done using the specified fill character (default is a space)."); + +#define UNICODE_LJUST_METHODDEF \ + {"ljust", (PyCFunction)(void(*)(void))unicode_ljust, METH_FASTCALL, unicode_ljust__doc__}, + +static PyObject * +unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar); + +static PyObject * +unicode_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + Py_UCS4 fillchar = ' '; + + if (!_PyArg_CheckPositional("ljust", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (!convert_uc(args[1], &fillchar)) { + goto exit; + } +skip_optional: + return_value = unicode_ljust_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_lower__doc__, +"lower($self, /)\n" +"--\n" +"\n" +"Return a copy of the string converted to lowercase."); + +#define UNICODE_LOWER_METHODDEF \ + {"lower", (PyCFunction)unicode_lower, METH_NOARGS, unicode_lower__doc__}, + +static PyObject * +unicode_lower_impl(PyObject *self); + +static PyObject * +unicode_lower(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_lower_impl(self); +} + +PyDoc_STRVAR(unicode_strip__doc__, +"strip($self, chars=None, /)\n" +"--\n" +"\n" +"Return a copy of the string with leading and trailing whitespace removed.\n" +"\n" +"If chars is given and not None, remove characters in chars instead."); + +#define UNICODE_STRIP_METHODDEF \ + {"strip", (PyCFunction)(void(*)(void))unicode_strip, METH_FASTCALL, unicode_strip__doc__}, + +static PyObject * +unicode_strip_impl(PyObject *self, PyObject *chars); + +static PyObject * +unicode_strip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *chars = Py_None; + + if (!_PyArg_CheckPositional("strip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + chars = args[0]; +skip_optional: + return_value = unicode_strip_impl(self, chars); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_lstrip__doc__, +"lstrip($self, chars=None, /)\n" +"--\n" +"\n" +"Return a copy of the string with leading whitespace removed.\n" +"\n" +"If chars is given and not None, remove characters in chars instead."); + +#define UNICODE_LSTRIP_METHODDEF \ + {"lstrip", (PyCFunction)(void(*)(void))unicode_lstrip, METH_FASTCALL, unicode_lstrip__doc__}, + +static PyObject * +unicode_lstrip_impl(PyObject *self, PyObject *chars); + +static PyObject * +unicode_lstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *chars = Py_None; + + if (!_PyArg_CheckPositional("lstrip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + chars = args[0]; +skip_optional: + return_value = unicode_lstrip_impl(self, chars); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_rstrip__doc__, +"rstrip($self, chars=None, /)\n" +"--\n" +"\n" +"Return a copy of the string with trailing whitespace removed.\n" +"\n" +"If chars is given and not None, remove characters in chars instead."); + +#define UNICODE_RSTRIP_METHODDEF \ + {"rstrip", (PyCFunction)(void(*)(void))unicode_rstrip, METH_FASTCALL, unicode_rstrip__doc__}, + +static PyObject * +unicode_rstrip_impl(PyObject *self, PyObject *chars); + +static PyObject * +unicode_rstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *chars = Py_None; + + if (!_PyArg_CheckPositional("rstrip", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + chars = args[0]; +skip_optional: + return_value = unicode_rstrip_impl(self, chars); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_replace__doc__, +"replace($self, old, new, count=-1, /)\n" +"--\n" +"\n" +"Return a copy with all occurrences of substring old replaced by new.\n" +"\n" +" count\n" +" Maximum number of occurrences to replace.\n" +" -1 (the default value) means replace all occurrences.\n" +"\n" +"If the optional argument count is given, only the first count occurrences are\n" +"replaced."); + +#define UNICODE_REPLACE_METHODDEF \ + {"replace", (PyCFunction)(void(*)(void))unicode_replace, METH_FASTCALL, unicode_replace__doc__}, + +static PyObject * +unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new, + Py_ssize_t count); + +static PyObject * +unicode_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *old; + PyObject *new; + Py_ssize_t count = -1; + + if (!_PyArg_CheckPositional("replace", nargs, 2, 3)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("replace", "argument 1", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + old = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("replace", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + new = args[1]; + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + 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; + } +skip_optional: + return_value = unicode_replace_impl(self, old, new, count); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_rjust__doc__, +"rjust($self, width, fillchar=\' \', /)\n" +"--\n" +"\n" +"Return a right-justified string of length width.\n" +"\n" +"Padding is done using the specified fill character (default is a space)."); + +#define UNICODE_RJUST_METHODDEF \ + {"rjust", (PyCFunction)(void(*)(void))unicode_rjust, METH_FASTCALL, unicode_rjust__doc__}, + +static PyObject * +unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar); + +static PyObject * +unicode_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + Py_UCS4 fillchar = ' '; + + if (!_PyArg_CheckPositional("rjust", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (!convert_uc(args[1], &fillchar)) { + goto exit; + } +skip_optional: + return_value = unicode_rjust_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_split__doc__, +"split($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the words in the string, using sep as the delimiter string.\n" +"\n" +" sep\n" +" The delimiter according which to split the string.\n" +" None (the default value) means split according to any whitespace,\n" +" and discard empty strings from the result.\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit."); + +#define UNICODE_SPLIT_METHODDEF \ + {"split", (PyCFunction)(void(*)(void))unicode_split, METH_FASTCALL|METH_KEYWORDS, unicode_split__doc__}, + +static PyObject * +unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + } + maxsplit = ival; + } +skip_optional_pos: + return_value = unicode_split_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_partition__doc__, +"partition($self, sep, /)\n" +"--\n" +"\n" +"Partition the string into three parts using the given separator.\n" +"\n" +"This will search for the separator in the string. If the separator is found,\n" +"returns a 3-tuple containing the part before the separator, the separator\n" +"itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing the original string\n" +"and two empty strings."); + +#define UNICODE_PARTITION_METHODDEF \ + {"partition", (PyCFunction)unicode_partition, METH_O, unicode_partition__doc__}, + +PyDoc_STRVAR(unicode_rpartition__doc__, +"rpartition($self, sep, /)\n" +"--\n" +"\n" +"Partition the string into three parts using the given separator.\n" +"\n" +"This will search for the separator in the string, starting at the end. If\n" +"the separator is found, returns a 3-tuple containing the part before the\n" +"separator, the separator itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing two empty strings\n" +"and the original string."); + +#define UNICODE_RPARTITION_METHODDEF \ + {"rpartition", (PyCFunction)unicode_rpartition, METH_O, unicode_rpartition__doc__}, + +PyDoc_STRVAR(unicode_rsplit__doc__, +"rsplit($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the words in the string, using sep as the delimiter string.\n" +"\n" +" sep\n" +" The delimiter according which to split the string.\n" +" None (the default value) means split according to any whitespace,\n" +" and discard empty strings from the result.\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit.\n" +"\n" +"Splits are done starting at the end of the string and working to the front."); + +#define UNICODE_RSPLIT_METHODDEF \ + {"rsplit", (PyCFunction)(void(*)(void))unicode_rsplit, METH_FASTCALL|METH_KEYWORDS, unicode_rsplit__doc__}, + +static PyObject * +unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + 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; + } + maxsplit = ival; + } +skip_optional_pos: + return_value = unicode_rsplit_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_splitlines__doc__, +"splitlines($self, /, keepends=False)\n" +"--\n" +"\n" +"Return a list of the lines in the string, breaking at line boundaries.\n" +"\n" +"Line breaks are not included in the resulting list unless keepends is given and\n" +"true."); + +#define UNICODE_SPLITLINES_METHODDEF \ + {"splitlines", (PyCFunction)(void(*)(void))unicode_splitlines, METH_FASTCALL|METH_KEYWORDS, unicode_splitlines__doc__}, + +static PyObject * +unicode_splitlines_impl(PyObject *self, int keepends); + +static PyObject * +unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"keepends", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int keepends = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + keepends = _PyLong_AsInt(args[0]); + if (keepends == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = unicode_splitlines_impl(self, keepends); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_swapcase__doc__, +"swapcase($self, /)\n" +"--\n" +"\n" +"Convert uppercase characters to lowercase and lowercase characters to uppercase."); + +#define UNICODE_SWAPCASE_METHODDEF \ + {"swapcase", (PyCFunction)unicode_swapcase, METH_NOARGS, unicode_swapcase__doc__}, + +static PyObject * +unicode_swapcase_impl(PyObject *self); + +static PyObject * +unicode_swapcase(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_swapcase_impl(self); +} + +PyDoc_STRVAR(unicode_maketrans__doc__, +"maketrans(x, y=, z=, /)\n" +"--\n" +"\n" +"Return a translation table usable for str.translate().\n" +"\n" +"If there is only one argument, it must be a dictionary mapping Unicode\n" +"ordinals (integers) or characters to Unicode ordinals, strings or None.\n" +"Character keys will be then converted to ordinals.\n" +"If there are two arguments, they must be strings of equal length, and\n" +"in the resulting dictionary, each character in x will be mapped to the\n" +"character at the same position in y. If there is a third argument, it\n" +"must be a string, whose characters will be mapped to None in the result."); + +#define UNICODE_MAKETRANS_METHODDEF \ + {"maketrans", (PyCFunction)(void(*)(void))unicode_maketrans, METH_FASTCALL|METH_STATIC, unicode_maketrans__doc__}, + +static PyObject * +unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z); + +static PyObject * +unicode_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *x; + PyObject *y = NULL; + PyObject *z = NULL; + + if (!_PyArg_CheckPositional("maketrans", nargs, 1, 3)) { + goto exit; + } + x = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("maketrans", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + y = args[1]; + if (nargs < 3) { + goto skip_optional; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("maketrans", "argument 3", "str", args[2]); + goto exit; + } + if (PyUnicode_READY(args[2]) == -1) { + goto exit; + } + z = args[2]; +skip_optional: + return_value = unicode_maketrans_impl(x, y, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_translate__doc__, +"translate($self, table, /)\n" +"--\n" +"\n" +"Replace each character in the string using the given translation table.\n" +"\n" +" table\n" +" Translation table, which must be a mapping of Unicode ordinals to\n" +" Unicode ordinals, strings, or None.\n" +"\n" +"The table must implement lookup/indexing via __getitem__, for instance a\n" +"dictionary or list. If this operation raises LookupError, the character is\n" +"left untouched. Characters mapped to None are deleted."); + +#define UNICODE_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)unicode_translate, METH_O, unicode_translate__doc__}, + +PyDoc_STRVAR(unicode_upper__doc__, +"upper($self, /)\n" +"--\n" +"\n" +"Return a copy of the string converted to uppercase."); + +#define UNICODE_UPPER_METHODDEF \ + {"upper", (PyCFunction)unicode_upper, METH_NOARGS, unicode_upper__doc__}, + +static PyObject * +unicode_upper_impl(PyObject *self); + +static PyObject * +unicode_upper(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_upper_impl(self); +} + +PyDoc_STRVAR(unicode_zfill__doc__, +"zfill($self, width, /)\n" +"--\n" +"\n" +"Pad a numeric string with zeros on the left, to fill a field of the given width.\n" +"\n" +"The string is never truncated."); + +#define UNICODE_ZFILL_METHODDEF \ + {"zfill", (PyCFunction)unicode_zfill, METH_O, unicode_zfill__doc__}, + +static PyObject * +unicode_zfill_impl(PyObject *self, Py_ssize_t width); + +static PyObject * +unicode_zfill(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + return_value = unicode_zfill_impl(self, width); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode___format____doc__, +"__format__($self, format_spec, /)\n" +"--\n" +"\n" +"Return a formatted version of the string as described by format_spec."); + +#define UNICODE___FORMAT___METHODDEF \ + {"__format__", (PyCFunction)unicode___format__, METH_O, unicode___format____doc__}, + +static PyObject * +unicode___format___impl(PyObject *self, PyObject *format_spec); + +static PyObject * +unicode___format__(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *format_spec; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("__format__", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + format_spec = arg; + return_value = unicode___format___impl(self, format_spec); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_sizeof__doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Return the size of the string in memory, in bytes."); + +#define UNICODE_SIZEOF_METHODDEF \ + {"__sizeof__", (PyCFunction)unicode_sizeof, METH_NOARGS, unicode_sizeof__doc__}, + +static PyObject * +unicode_sizeof_impl(PyObject *self); + +static PyObject * +unicode_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return unicode_sizeof_impl(self); +} +/*[clinic end generated code: output=e4ed33400979c7e8 input=a9049054013a1b77]*/ diff --git a/python/Objects/codeobject.c b/python/Objects/codeobject.c new file mode 100755 index 0000000..522e1a9 --- /dev/null +++ b/python/Objects/codeobject.c @@ -0,0 +1,1092 @@ +#include + +#include "Python.h" +#include "code.h" +#include "opcode.h" +#include "structmember.h" +#include "pycore_code.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" +#include "clinic/codeobject.c.h" + +/* Holder for co_extra information */ +typedef struct { + Py_ssize_t ce_size; + void *ce_extras[1]; +} _PyCodeObjectExtra; + +/*[clinic input] +class code "PyCodeObject *" "&PyCode_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78aa5d576683bb4b]*/ + +/* all_name_chars(s): true iff s matches [a-zA-Z0-9_]* */ +static int +all_name_chars(PyObject *o) +{ + const unsigned char *s, *e; + + if (!PyUnicode_IS_ASCII(o)) + return 0; + + s = PyUnicode_1BYTE_DATA(o); + e = s + PyUnicode_GET_LENGTH(o); + for (; s != e; s++) { + if (!Py_ISALNUM(*s) && *s != '_') + return 0; + } + return 1; +} + +static void +intern_strings(PyObject *tuple) +{ + Py_ssize_t i; + + for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { + PyObject *v = PyTuple_GET_ITEM(tuple, i); + if (v == NULL || !PyUnicode_CheckExact(v)) { + Py_FatalError("non-string found in code slot"); + } + PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]); + } +} + +/* Intern selected string constants */ +static int +intern_string_constants(PyObject *tuple) +{ + int modified = 0; + Py_ssize_t i; + + for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { + PyObject *v = PyTuple_GET_ITEM(tuple, i); + if (PyUnicode_CheckExact(v)) { + if (PyUnicode_READY(v) == -1) { + PyErr_Clear(); + continue; + } + if (all_name_chars(v)) { + PyObject *w = v; + PyUnicode_InternInPlace(&v); + if (w != v) { + PyTuple_SET_ITEM(tuple, i, v); + modified = 1; + } + } + } + else if (PyTuple_CheckExact(v)) { + intern_string_constants(v); + } + else if (PyFrozenSet_CheckExact(v)) { + PyObject *w = v; + PyObject *tmp = PySequence_Tuple(v); + if (tmp == NULL) { + PyErr_Clear(); + continue; + } + if (intern_string_constants(tmp)) { + v = PyFrozenSet_New(tmp); + if (v == NULL) { + PyErr_Clear(); + } + else { + PyTuple_SET_ITEM(tuple, i, v); + Py_DECREF(w); + modified = 1; + } + } + Py_DECREF(tmp); + } + } + return modified; +} + +PyCodeObject * +PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, + int nlocals, int stacksize, int flags, + PyObject *code, PyObject *consts, PyObject *names, + PyObject *varnames, PyObject *freevars, PyObject *cellvars, + PyObject *filename, PyObject *name, int firstlineno, + PyObject *lnotab) +{ + PyCodeObject *co; + Py_ssize_t *cell2arg = NULL; + Py_ssize_t i, n_cellvars, n_varnames, total_args; + + /* Check argument types */ + if (argcount < posonlyargcount || posonlyargcount < 0 || + kwonlyargcount < 0 || nlocals < 0 || + stacksize < 0 || flags < 0 || + code == NULL || !PyBytes_Check(code) || + consts == NULL || !PyTuple_Check(consts) || + names == NULL || !PyTuple_Check(names) || + varnames == NULL || !PyTuple_Check(varnames) || + freevars == NULL || !PyTuple_Check(freevars) || + cellvars == NULL || !PyTuple_Check(cellvars) || + name == NULL || !PyUnicode_Check(name) || + filename == NULL || !PyUnicode_Check(filename) || + lnotab == NULL || !PyBytes_Check(lnotab)) { + PyErr_BadInternalCall(); + return NULL; + } + + /* Ensure that strings are ready Unicode string */ + if (PyUnicode_READY(name) < 0) { + return NULL; + } + if (PyUnicode_READY(filename) < 0) { + return NULL; + } + + intern_strings(names); + intern_strings(varnames); + intern_strings(freevars); + intern_strings(cellvars); + intern_string_constants(consts); + + /* Check for any inner or outer closure references */ + n_cellvars = PyTuple_GET_SIZE(cellvars); + if (!n_cellvars && !PyTuple_GET_SIZE(freevars)) { + flags |= CO_NOFREE; + } else { + flags &= ~CO_NOFREE; + } + + n_varnames = PyTuple_GET_SIZE(varnames); + if (argcount <= n_varnames && kwonlyargcount <= n_varnames) { + /* Never overflows. */ + total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount + + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); + } + else { + total_args = n_varnames + 1; + } + if (total_args > n_varnames) { + PyErr_SetString(PyExc_ValueError, "code: varnames is too small"); + return NULL; + } + + /* Create mapping between cells and arguments if needed. */ + if (n_cellvars) { + bool used_cell2arg = false; + cell2arg = PyMem_NEW(Py_ssize_t, n_cellvars); + if (cell2arg == NULL) { + PyErr_NoMemory(); + return NULL; + } + /* Find cells which are also arguments. */ + for (i = 0; i < n_cellvars; i++) { + Py_ssize_t j; + PyObject *cell = PyTuple_GET_ITEM(cellvars, i); + cell2arg[i] = CO_CELL_NOT_AN_ARG; + for (j = 0; j < total_args; j++) { + PyObject *arg = PyTuple_GET_ITEM(varnames, j); + int cmp = PyUnicode_Compare(cell, arg); + if (cmp == -1 && PyErr_Occurred()) { + PyMem_FREE(cell2arg); + return NULL; + } + if (cmp == 0) { + cell2arg[i] = j; + used_cell2arg = true; + break; + } + } + } + if (!used_cell2arg) { + PyMem_FREE(cell2arg); + cell2arg = NULL; + } + } + co = PyObject_NEW(PyCodeObject, &PyCode_Type); + if (co == NULL) { + if (cell2arg) + PyMem_FREE(cell2arg); + return NULL; + } + co->co_argcount = argcount; + co->co_posonlyargcount = posonlyargcount; + co->co_kwonlyargcount = kwonlyargcount; + co->co_nlocals = nlocals; + co->co_stacksize = stacksize; + co->co_flags = flags; + Py_INCREF(code); + co->co_code = code; + Py_INCREF(consts); + co->co_consts = consts; + Py_INCREF(names); + co->co_names = names; + Py_INCREF(varnames); + co->co_varnames = varnames; + Py_INCREF(freevars); + co->co_freevars = freevars; + Py_INCREF(cellvars); + co->co_cellvars = cellvars; + co->co_cell2arg = cell2arg; + Py_INCREF(filename); + co->co_filename = filename; + Py_INCREF(name); + co->co_name = name; + co->co_firstlineno = firstlineno; + Py_INCREF(lnotab); + co->co_lnotab = lnotab; + co->co_zombieframe = NULL; + co->co_weakreflist = NULL; + co->co_extra = NULL; + + co->co_opcache_map = NULL; + co->co_opcache = NULL; + co->co_opcache_flag = 0; + co->co_opcache_size = 0; + return co; +} + +PyCodeObject * +PyCode_New(int argcount, int kwonlyargcount, + int nlocals, int stacksize, int flags, + PyObject *code, PyObject *consts, PyObject *names, + PyObject *varnames, PyObject *freevars, PyObject *cellvars, + PyObject *filename, PyObject *name, int firstlineno, + PyObject *lnotab) +{ + return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals, + stacksize, flags, code, consts, names, + varnames, freevars, cellvars, filename, + name, firstlineno, lnotab); +} + +int +_PyCode_InitOpcache(PyCodeObject *co) +{ + Py_ssize_t co_size = PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT); + co->co_opcache_map = (unsigned char *)PyMem_Calloc(co_size, 1); + if (co->co_opcache_map == NULL) { + return -1; + } + + _Py_CODEUNIT *opcodes = (_Py_CODEUNIT*)PyBytes_AS_STRING(co->co_code); + Py_ssize_t opts = 0; + + for (Py_ssize_t i = 0; i < co_size;) { + unsigned char opcode = _Py_OPCODE(opcodes[i]); + i++; // 'i' is now aligned to (next_instr - first_instr) + + // TODO: LOAD_METHOD, LOAD_ATTR + if (opcode == LOAD_GLOBAL) { + opts++; + co->co_opcache_map[i] = (unsigned char)opts; + if (opts > 254) { + break; + } + } + } + + if (opts) { + co->co_opcache = (_PyOpcache *)PyMem_Calloc(opts, sizeof(_PyOpcache)); + if (co->co_opcache == NULL) { + PyMem_FREE(co->co_opcache_map); + return -1; + } + } + else { + PyMem_FREE(co->co_opcache_map); + co->co_opcache_map = NULL; + co->co_opcache = NULL; + } + + co->co_opcache_size = (unsigned char)opts; + return 0; +} + +PyCodeObject * +PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) +{ + static PyObject *emptystring = NULL; + static PyObject *nulltuple = NULL; + PyObject *filename_ob = NULL; + PyObject *funcname_ob = NULL; + PyCodeObject *result = NULL; + if (emptystring == NULL) { + emptystring = PyBytes_FromString(""); + if (emptystring == NULL) + goto failed; + } + if (nulltuple == NULL) { + nulltuple = PyTuple_New(0); + if (nulltuple == NULL) + goto failed; + } + funcname_ob = PyUnicode_FromString(funcname); + if (funcname_ob == NULL) + goto failed; + filename_ob = PyUnicode_DecodeFSDefault(filename); + if (filename_ob == NULL) + goto failed; + + result = PyCode_NewWithPosOnlyArgs( + 0, /* argcount */ + 0, /* posonlyargcount */ + 0, /* kwonlyargcount */ + 0, /* nlocals */ + 0, /* stacksize */ + 0, /* flags */ + emptystring, /* code */ + nulltuple, /* consts */ + nulltuple, /* names */ + nulltuple, /* varnames */ + nulltuple, /* freevars */ + nulltuple, /* cellvars */ + filename_ob, /* filename */ + funcname_ob, /* name */ + firstlineno, /* firstlineno */ + emptystring /* lnotab */ + ); + +failed: + Py_XDECREF(funcname_ob); + Py_XDECREF(filename_ob); + return result; +} + +#define OFF(x) offsetof(PyCodeObject, x) + +static PyMemberDef code_memberlist[] = { + {"co_argcount", T_INT, OFF(co_argcount), READONLY}, + {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, + {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, + {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, + {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, + {"co_flags", T_INT, OFF(co_flags), READONLY}, + {"co_code", T_OBJECT, OFF(co_code), READONLY}, + {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, + {"co_names", T_OBJECT, OFF(co_names), READONLY}, + {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY}, + {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY}, + {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, + {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, + {"co_name", T_OBJECT, OFF(co_name), READONLY}, + {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, + {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY}, + {NULL} /* Sentinel */ +}; + +/* Helper for code_new: return a shallow copy of a tuple that is + guaranteed to contain exact strings, by converting string subclasses + to exact strings and complaining if a non-string is found. */ +static PyObject* +validate_and_copy_tuple(PyObject *tup) +{ + PyObject *newtuple; + PyObject *item; + Py_ssize_t i, len; + + len = PyTuple_GET_SIZE(tup); + newtuple = PyTuple_New(len); + if (newtuple == NULL) + return NULL; + + for (i = 0; i < len; i++) { + item = PyTuple_GET_ITEM(tup, i); + if (PyUnicode_CheckExact(item)) { + Py_INCREF(item); + } + else if (!PyUnicode_Check(item)) { + PyErr_Format( + PyExc_TypeError, + "name tuples must contain only " + "strings, not '%.500s'", + item->ob_type->tp_name); + Py_DECREF(newtuple); + return NULL; + } + else { + item = _PyUnicode_Copy(item); + if (item == NULL) { + Py_DECREF(newtuple); + return NULL; + } + } + PyTuple_SET_ITEM(newtuple, i, item); + } + + return newtuple; +} + +PyDoc_STRVAR(code_doc, +"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n\ + flags, codestring, constants, names, varnames, filename, name,\n\ + firstlineno, lnotab[, freevars[, cellvars]])\n\ +\n\ +Create a code object. Not for the faint of heart."); + +static PyObject * +code_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + int argcount; + int posonlyargcount; + int kwonlyargcount; + int nlocals; + int stacksize; + int flags; + PyObject *co = NULL; + PyObject *code; + PyObject *consts; + PyObject *names, *ournames = NULL; + PyObject *varnames, *ourvarnames = NULL; + PyObject *freevars = NULL, *ourfreevars = NULL; + PyObject *cellvars = NULL, *ourcellvars = NULL; + PyObject *filename; + PyObject *name; + int firstlineno; + PyObject *lnotab; + + if (!PyArg_ParseTuple(args, "iiiiiiSO!O!O!UUiS|O!O!:code", + &argcount, &posonlyargcount, &kwonlyargcount, + &nlocals, &stacksize, &flags, + &code, + &PyTuple_Type, &consts, + &PyTuple_Type, &names, + &PyTuple_Type, &varnames, + &filename, &name, + &firstlineno, &lnotab, + &PyTuple_Type, &freevars, + &PyTuple_Type, &cellvars)) + return NULL; + + if (PySys_Audit("code.__new__", "OOOiiiiii", + code, filename, name, argcount, posonlyargcount, + kwonlyargcount, nlocals, stacksize, flags) < 0) { + goto cleanup; + } + + if (argcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: argcount must not be negative"); + goto cleanup; + } + + if (posonlyargcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: posonlyargcount must not be negative"); + goto cleanup; + } + + if (kwonlyargcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: kwonlyargcount must not be negative"); + goto cleanup; + } + if (nlocals < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: nlocals must not be negative"); + goto cleanup; + } + + ournames = validate_and_copy_tuple(names); + if (ournames == NULL) + goto cleanup; + ourvarnames = validate_and_copy_tuple(varnames); + if (ourvarnames == NULL) + goto cleanup; + if (freevars) + ourfreevars = validate_and_copy_tuple(freevars); + else + ourfreevars = PyTuple_New(0); + if (ourfreevars == NULL) + goto cleanup; + if (cellvars) + ourcellvars = validate_and_copy_tuple(cellvars); + else + ourcellvars = PyTuple_New(0); + if (ourcellvars == NULL) + goto cleanup; + + co = (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount, + kwonlyargcount, + nlocals, stacksize, flags, + code, consts, ournames, + ourvarnames, ourfreevars, + ourcellvars, filename, + name, firstlineno, lnotab); + cleanup: + Py_XDECREF(ournames); + Py_XDECREF(ourvarnames); + Py_XDECREF(ourfreevars); + Py_XDECREF(ourcellvars); + return co; +} + +static void +code_dealloc(PyCodeObject *co) +{ + if (co->co_opcache != NULL) { + PyMem_FREE(co->co_opcache); + } + if (co->co_opcache_map != NULL) { + PyMem_FREE(co->co_opcache_map); + } + co->co_opcache_flag = 0; + co->co_opcache_size = 0; + + if (co->co_extra != NULL) { + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + _PyCodeObjectExtra *co_extra = co->co_extra; + + for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) { + freefunc free_extra = interp->co_extra_freefuncs[i]; + + if (free_extra != NULL) { + free_extra(co_extra->ce_extras[i]); + } + } + + PyMem_Free(co_extra); + } + + Py_XDECREF(co->co_code); + Py_XDECREF(co->co_consts); + Py_XDECREF(co->co_names); + Py_XDECREF(co->co_varnames); + Py_XDECREF(co->co_freevars); + Py_XDECREF(co->co_cellvars); + Py_XDECREF(co->co_filename); + Py_XDECREF(co->co_name); + Py_XDECREF(co->co_lnotab); + if (co->co_cell2arg != NULL) + PyMem_FREE(co->co_cell2arg); + if (co->co_zombieframe != NULL) + PyObject_GC_Del(co->co_zombieframe); + if (co->co_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject*)co); + PyObject_DEL(co); +} + +static PyObject * +code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) +{ + Py_ssize_t res = _PyObject_SIZE(Py_TYPE(co)); + _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra; + + if (co->co_cell2arg != NULL && co->co_cellvars != NULL) { + res += PyTuple_GET_SIZE(co->co_cellvars) * sizeof(Py_ssize_t); + } + if (co_extra != NULL) { + res += sizeof(_PyCodeObjectExtra) + + (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]); + } + if (co->co_opcache != NULL) { + assert(co->co_opcache_map != NULL); + // co_opcache_map + res += PyBytes_GET_SIZE(co->co_code) / sizeof(_Py_CODEUNIT); + // co_opcache + res += co->co_opcache_size * sizeof(_PyOpcache); + } + return PyLong_FromSsize_t(res); +} + +/*[clinic input] +code.replace + + * + co_argcount: int(c_default="self->co_argcount") = -1 + co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1 + co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1 + co_nlocals: int(c_default="self->co_nlocals") = -1 + co_stacksize: int(c_default="self->co_stacksize") = -1 + co_flags: int(c_default="self->co_flags") = -1 + co_firstlineno: int(c_default="self->co_firstlineno") = -1 + co_code: PyBytesObject(c_default="(PyBytesObject *)self->co_code") = None + co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None + co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None + co_varnames: object(subclass_of="&PyTuple_Type", c_default="self->co_varnames") = None + co_freevars: object(subclass_of="&PyTuple_Type", c_default="self->co_freevars") = None + co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None + co_filename: unicode(c_default="self->co_filename") = None + co_name: unicode(c_default="self->co_name") = None + co_lnotab: PyBytesObject(c_default="(PyBytesObject *)self->co_lnotab") = None + +Return a copy of the code object with new values for the specified fields. +[clinic start generated code]*/ + +static PyObject * +code_replace_impl(PyCodeObject *self, int co_argcount, + int co_posonlyargcount, int co_kwonlyargcount, + int co_nlocals, int co_stacksize, int co_flags, + int co_firstlineno, PyBytesObject *co_code, + PyObject *co_consts, PyObject *co_names, + PyObject *co_varnames, PyObject *co_freevars, + PyObject *co_cellvars, PyObject *co_filename, + PyObject *co_name, PyBytesObject *co_lnotab) +/*[clinic end generated code: output=25c8e303913bcace input=d9051bc8f24e6b28]*/ +{ +#define CHECK_INT_ARG(ARG) \ + if (ARG < 0) { \ + PyErr_SetString(PyExc_ValueError, \ + #ARG " must be a positive integer"); \ + return NULL; \ + } + + CHECK_INT_ARG(co_argcount); + CHECK_INT_ARG(co_posonlyargcount); + CHECK_INT_ARG(co_kwonlyargcount); + CHECK_INT_ARG(co_nlocals); + CHECK_INT_ARG(co_stacksize); + CHECK_INT_ARG(co_flags); + CHECK_INT_ARG(co_firstlineno); + +#undef CHECK_INT_ARG + + if (PySys_Audit("code.__new__", "OOOiiiiii", + co_code, co_filename, co_name, co_argcount, + co_posonlyargcount, co_kwonlyargcount, co_nlocals, + co_stacksize, co_flags) < 0) { + return NULL; + } + + return (PyObject *)PyCode_NewWithPosOnlyArgs( + co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, + co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, + co_varnames, co_freevars, co_cellvars, co_filename, co_name, + co_firstlineno, (PyObject*)co_lnotab); +} + +static PyObject * +code_repr(PyCodeObject *co) +{ + int lineno; + if (co->co_firstlineno != 0) + lineno = co->co_firstlineno; + else + lineno = -1; + if (co->co_filename && PyUnicode_Check(co->co_filename)) { + return PyUnicode_FromFormat( + "", + co->co_name, co, co->co_filename, lineno); + } else { + return PyUnicode_FromFormat( + "", + co->co_name, co, lineno); + } +} + +PyObject* +_PyCode_ConstantKey(PyObject *op) +{ + PyObject *key; + + /* Py_None and Py_Ellipsis are singletons. */ + if (op == Py_None || op == Py_Ellipsis + || PyLong_CheckExact(op) + || PyUnicode_CheckExact(op) + /* code_richcompare() uses _PyCode_ConstantKey() internally */ + || PyCode_Check(op)) + { + /* Objects of these types are always different from object of other + * type and from tuples. */ + Py_INCREF(op); + key = op; + } + else if (PyBool_Check(op) || PyBytes_CheckExact(op)) { + /* Make booleans different from integers 0 and 1. + * Avoid BytesWarning from comparing bytes with strings. */ + key = PyTuple_Pack(2, Py_TYPE(op), op); + } + else if (PyFloat_CheckExact(op)) { + double d = PyFloat_AS_DOUBLE(op); + /* all we need is to make the tuple different in either the 0.0 + * or -0.0 case from all others, just to avoid the "coercion". + */ + if (d == 0.0 && copysign(1.0, d) < 0.0) + key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None); + else + key = PyTuple_Pack(2, Py_TYPE(op), op); + } + else if (PyComplex_CheckExact(op)) { + Py_complex z; + int real_negzero, imag_negzero; + /* For the complex case we must make complex(x, 0.) + different from complex(x, -0.) and complex(0., y) + different from complex(-0., y), for any x and y. + All four complex zeros must be distinguished.*/ + z = PyComplex_AsCComplex(op); + real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; + imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; + /* use True, False and None singleton as tags for the real and imag + * sign, to make tuples different */ + if (real_negzero && imag_negzero) { + key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True); + } + else if (imag_negzero) { + key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False); + } + else if (real_negzero) { + key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None); + } + else { + key = PyTuple_Pack(2, Py_TYPE(op), op); + } + } + else if (PyTuple_CheckExact(op)) { + Py_ssize_t i, len; + PyObject *tuple; + + len = PyTuple_GET_SIZE(op); + tuple = PyTuple_New(len); + if (tuple == NULL) + return NULL; + + for (i=0; i < len; i++) { + PyObject *item, *item_key; + + item = PyTuple_GET_ITEM(op, i); + item_key = _PyCode_ConstantKey(item); + if (item_key == NULL) { + Py_DECREF(tuple); + return NULL; + } + + PyTuple_SET_ITEM(tuple, i, item_key); + } + + key = PyTuple_Pack(2, tuple, op); + Py_DECREF(tuple); + } + else if (PyFrozenSet_CheckExact(op)) { + Py_ssize_t pos = 0; + PyObject *item; + Py_hash_t hash; + Py_ssize_t i, len; + PyObject *tuple, *set; + + len = PySet_GET_SIZE(op); + tuple = PyTuple_New(len); + if (tuple == NULL) + return NULL; + + i = 0; + while (_PySet_NextEntry(op, &pos, &item, &hash)) { + PyObject *item_key; + + item_key = _PyCode_ConstantKey(item); + if (item_key == NULL) { + Py_DECREF(tuple); + return NULL; + } + + assert(i < len); + PyTuple_SET_ITEM(tuple, i, item_key); + i++; + } + set = PyFrozenSet_New(tuple); + Py_DECREF(tuple); + if (set == NULL) + return NULL; + + key = PyTuple_Pack(2, set, op); + Py_DECREF(set); + return key; + } + else { + /* for other types, use the object identifier as a unique identifier + * to ensure that they are seen as unequal. */ + PyObject *obj_id = PyLong_FromVoidPtr(op); + if (obj_id == NULL) + return NULL; + + key = PyTuple_Pack(2, obj_id, op); + Py_DECREF(obj_id); + } + return key; +} + +static PyObject * +code_richcompare(PyObject *self, PyObject *other, int op) +{ + PyCodeObject *co, *cp; + int eq; + PyObject *consts1, *consts2; + PyObject *res; + + if ((op != Py_EQ && op != Py_NE) || + !PyCode_Check(self) || + !PyCode_Check(other)) { + Py_RETURN_NOTIMPLEMENTED; + } + + co = (PyCodeObject *)self; + cp = (PyCodeObject *)other; + + eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ); + if (!eq) goto unequal; + eq = co->co_argcount == cp->co_argcount; + if (!eq) goto unequal; + eq = co->co_posonlyargcount == cp->co_posonlyargcount; + if (!eq) goto unequal; + eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; + if (!eq) goto unequal; + eq = co->co_nlocals == cp->co_nlocals; + if (!eq) goto unequal; + eq = co->co_flags == cp->co_flags; + if (!eq) goto unequal; + eq = co->co_firstlineno == cp->co_firstlineno; + if (!eq) goto unequal; + eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ); + if (eq <= 0) goto unequal; + + /* compare constants */ + consts1 = _PyCode_ConstantKey(co->co_consts); + if (!consts1) + return NULL; + consts2 = _PyCode_ConstantKey(cp->co_consts); + if (!consts2) { + Py_DECREF(consts1); + return NULL; + } + eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ); + Py_DECREF(consts1); + Py_DECREF(consts2); + if (eq <= 0) goto unequal; + + eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ); + if (eq <= 0) goto unequal; + eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ); + if (eq <= 0) goto unequal; + eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ); + if (eq <= 0) goto unequal; + eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ); + if (eq <= 0) goto unequal; + + if (op == Py_EQ) + res = Py_True; + else + res = Py_False; + goto done; + + unequal: + if (eq < 0) + return NULL; + if (op == Py_NE) + res = Py_True; + else + res = Py_False; + + done: + Py_INCREF(res); + return res; +} + +static Py_hash_t +code_hash(PyCodeObject *co) +{ + Py_hash_t h, h0, h1, h2, h3, h4, h5, h6; + h0 = PyObject_Hash(co->co_name); + if (h0 == -1) return -1; + h1 = PyObject_Hash(co->co_code); + if (h1 == -1) return -1; + h2 = PyObject_Hash(co->co_consts); + if (h2 == -1) return -1; + h3 = PyObject_Hash(co->co_names); + if (h3 == -1) return -1; + h4 = PyObject_Hash(co->co_varnames); + if (h4 == -1) return -1; + h5 = PyObject_Hash(co->co_freevars); + if (h5 == -1) return -1; + h6 = PyObject_Hash(co->co_cellvars); + if (h6 == -1) return -1; + h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^ + co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ + co->co_nlocals ^ co->co_flags; + if (h == -1) h = -2; + return h; +} + +/* XXX code objects need to participate in GC? */ + +static struct PyMethodDef code_methods[] = { + {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS}, + CODE_REPLACE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyCode_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "code", + sizeof(PyCodeObject), + 0, + (destructor)code_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)code_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)code_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + code_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + code_richcompare, /* tp_richcompare */ + offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + code_methods, /* tp_methods */ + code_memberlist, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + code_new, /* tp_new */ +}; + +/* Use co_lnotab to compute the line number from a bytecode index, addrq. See + lnotab_notes.txt for the details of the lnotab representation. +*/ + +int +PyCode_Addr2Line(PyCodeObject *co, int addrq) +{ + Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2; + unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab); + int line = co->co_firstlineno; + int addr = 0; + while (--size >= 0) { + addr += *p++; + if (addr > addrq) + break; + line += (signed char)*p; + p++; + } + return line; +} + +/* Update *bounds to describe the first and one-past-the-last instructions in + the same line as lasti. Return the number of that line. */ +int +_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) +{ + Py_ssize_t size; + int addr, line; + unsigned char* p; + + p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab); + size = PyBytes_GET_SIZE(co->co_lnotab) / 2; + + addr = 0; + line = co->co_firstlineno; + assert(line > 0); + + /* possible optimization: if f->f_lasti == instr_ub + (likely to be a common case) then we already know + instr_lb -- if we stored the matching value of p + somewhere we could skip the first while loop. */ + + /* See lnotab_notes.txt for the description of + co_lnotab. A point to remember: increments to p + come in (addr, line) pairs. */ + + bounds->ap_lower = 0; + while (size > 0) { + if (addr + *p > lasti) + break; + addr += *p++; + if ((signed char)*p) + bounds->ap_lower = addr; + line += (signed char)*p; + p++; + --size; + } + + if (size > 0) { + while (--size >= 0) { + addr += *p++; + if ((signed char)*p) + break; + p++; + } + bounds->ap_upper = addr; + } + else { + bounds->ap_upper = INT_MAX; + } + + return line; +} + + +int +_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) +{ + if (!PyCode_Check(code)) { + PyErr_BadInternalCall(); + return -1; + } + + PyCodeObject *o = (PyCodeObject*) code; + _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra; + + if (co_extra == NULL || co_extra->ce_size <= index) { + *extra = NULL; + return 0; + } + + *extra = co_extra->ce_extras[index]; + return 0; +} + + +int +_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + + if (!PyCode_Check(code) || index < 0 || + index >= interp->co_extra_user_count) { + PyErr_BadInternalCall(); + return -1; + } + + PyCodeObject *o = (PyCodeObject*) code; + _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra; + + if (co_extra == NULL || co_extra->ce_size <= index) { + Py_ssize_t i = (co_extra == NULL ? 0 : co_extra->ce_size); + co_extra = PyMem_Realloc( + co_extra, + sizeof(_PyCodeObjectExtra) + + (interp->co_extra_user_count-1) * sizeof(void*)); + if (co_extra == NULL) { + return -1; + } + for (; i < interp->co_extra_user_count; i++) { + co_extra->ce_extras[i] = NULL; + } + co_extra->ce_size = interp->co_extra_user_count; + o->co_extra = co_extra; + } + + if (co_extra->ce_extras[index] != NULL) { + freefunc free = interp->co_extra_freefuncs[index]; + if (free != NULL) { + free(co_extra->ce_extras[index]); + } + } + + co_extra->ce_extras[index] = extra; + return 0; +} diff --git a/python/Objects/complexobject.c b/python/Objects/complexobject.c new file mode 100755 index 0000000..e01409b --- /dev/null +++ b/python/Objects/complexobject.c @@ -0,0 +1,1137 @@ + +/* Complex object implementation */ + +/* Borrows heavily from floatobject.c */ + +/* Submitted by Jim Hugunin */ + +#include "Python.h" +#include "structmember.h" + +/*[clinic input] +class complex "PyComplexObject *" "&PyComplex_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=819e057d2d10f5ec]*/ + +#include "clinic/complexobject.c.h" + +/* elementary operations on complex numbers */ + +static Py_complex c_1 = {1., 0.}; + +Py_complex +_Py_c_sum(Py_complex a, Py_complex b) +{ + Py_complex r; + r.real = a.real + b.real; + r.imag = a.imag + b.imag; + return r; +} + +Py_complex +_Py_c_diff(Py_complex a, Py_complex b) +{ + Py_complex r; + r.real = a.real - b.real; + r.imag = a.imag - b.imag; + return r; +} + +Py_complex +_Py_c_neg(Py_complex a) +{ + Py_complex r; + r.real = -a.real; + r.imag = -a.imag; + return r; +} + +Py_complex +_Py_c_prod(Py_complex a, Py_complex b) +{ + Py_complex r; + r.real = a.real*b.real - a.imag*b.imag; + r.imag = a.real*b.imag + a.imag*b.real; + return r; +} + +/* Avoid bad optimization on Windows ARM64 until the compiler is fixed */ +#ifdef _M_ARM64 +#pragma optimize("", off) +#endif +Py_complex +_Py_c_quot(Py_complex a, Py_complex b) +{ + /****************************************************************** + This was the original algorithm. It's grossly prone to spurious + overflow and underflow errors. It also merrily divides by 0 despite + checking for that(!). The code still serves a doc purpose here, as + the algorithm following is a simple by-cases transformation of this + one: + + Py_complex r; + double d = b.real*b.real + b.imag*b.imag; + if (d == 0.) + errno = EDOM; + r.real = (a.real*b.real + a.imag*b.imag)/d; + r.imag = (a.imag*b.real - a.real*b.imag)/d; + return r; + ******************************************************************/ + + /* This algorithm is better, and is pretty obvious: first divide the + * numerators and denominator by whichever of {b.real, b.imag} has + * larger magnitude. The earliest reference I found was to CACM + * Algorithm 116 (Complex Division, Robert L. Smith, Stanford + * University). As usual, though, we're still ignoring all IEEE + * endcases. + */ + Py_complex r; /* the result */ + const double abs_breal = b.real < 0 ? -b.real : b.real; + const double abs_bimag = b.imag < 0 ? -b.imag : b.imag; + + if (abs_breal >= abs_bimag) { + /* divide tops and bottom by b.real */ + if (abs_breal == 0.0) { + errno = EDOM; + r.real = r.imag = 0.0; + } + else { + const double ratio = b.imag / b.real; + const double denom = b.real + b.imag * ratio; + r.real = (a.real + a.imag * ratio) / denom; + r.imag = (a.imag - a.real * ratio) / denom; + } + } + else if (abs_bimag >= abs_breal) { + /* divide tops and bottom by b.imag */ + const double ratio = b.real / b.imag; + const double denom = b.real * ratio + b.imag; + assert(b.imag != 0.0); + r.real = (a.real * ratio + a.imag) / denom; + r.imag = (a.imag * ratio - a.real) / denom; + } + else { + /* At least one of b.real or b.imag is a NaN */ + r.real = r.imag = Py_NAN; + } + return r; +} +#ifdef _M_ARM64 +#pragma optimize("", on) +#endif + +Py_complex +_Py_c_pow(Py_complex a, Py_complex b) +{ + Py_complex r; + double vabs,len,at,phase; + if (b.real == 0. && b.imag == 0.) { + r.real = 1.; + r.imag = 0.; + } + else if (a.real == 0. && a.imag == 0.) { + if (b.imag != 0. || b.real < 0.) + errno = EDOM; + r.real = 0.; + r.imag = 0.; + } + else { + vabs = hypot(a.real,a.imag); + len = pow(vabs,b.real); + at = atan2(a.imag, a.real); + phase = at*b.real; + if (b.imag != 0.0) { + len /= exp(at*b.imag); + phase += b.imag*log(vabs); + } + r.real = len*cos(phase); + r.imag = len*sin(phase); + } + return r; +} + +static Py_complex +c_powu(Py_complex x, long n) +{ + Py_complex r, p; + long mask = 1; + r = c_1; + p = x; + while (mask > 0 && n >= mask) { + if (n & mask) + r = _Py_c_prod(r,p); + mask <<= 1; + p = _Py_c_prod(p,p); + } + return r; +} + +static Py_complex +c_powi(Py_complex x, long n) +{ + Py_complex cn; + + if (n > 100 || n < -100) { + cn.real = (double) n; + cn.imag = 0.; + return _Py_c_pow(x,cn); + } + else if (n > 0) + return c_powu(x,n); + else + return _Py_c_quot(c_1, c_powu(x,-n)); + +} + +double +_Py_c_abs(Py_complex z) +{ + /* sets errno = ERANGE on overflow; otherwise errno = 0 */ + double result; + + if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { + /* C99 rules: if either the real or the imaginary part is an + infinity, return infinity, even if the other part is a + NaN. */ + if (Py_IS_INFINITY(z.real)) { + result = fabs(z.real); + errno = 0; + return result; + } + if (Py_IS_INFINITY(z.imag)) { + result = fabs(z.imag); + errno = 0; + return result; + } + /* either the real or imaginary part is a NaN, + and neither is infinite. Result should be NaN. */ + return Py_NAN; + } + result = hypot(z.real, z.imag); + if (!Py_IS_FINITE(result)) + errno = ERANGE; + else + errno = 0; + return result; +} + +static PyObject * +complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval) +{ + PyObject *op; + + op = type->tp_alloc(type, 0); + if (op != NULL) + ((PyComplexObject *)op)->cval = cval; + return op; +} + +PyObject * +PyComplex_FromCComplex(Py_complex cval) +{ + PyComplexObject *op; + + /* Inline PyObject_New */ + op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); + if (op == NULL) + return PyErr_NoMemory(); + (void)PyObject_INIT(op, &PyComplex_Type); + op->cval = cval; + return (PyObject *) op; +} + +static PyObject * +complex_subtype_from_doubles(PyTypeObject *type, double real, double imag) +{ + Py_complex c; + c.real = real; + c.imag = imag; + return complex_subtype_from_c_complex(type, c); +} + +PyObject * +PyComplex_FromDoubles(double real, double imag) +{ + Py_complex c; + c.real = real; + c.imag = imag; + return PyComplex_FromCComplex(c); +} + +double +PyComplex_RealAsDouble(PyObject *op) +{ + if (PyComplex_Check(op)) { + return ((PyComplexObject *)op)->cval.real; + } + else { + return PyFloat_AsDouble(op); + } +} + +double +PyComplex_ImagAsDouble(PyObject *op) +{ + if (PyComplex_Check(op)) { + return ((PyComplexObject *)op)->cval.imag; + } + else { + return 0.0; + } +} + +static PyObject * +try_complex_special_method(PyObject *op) +{ + PyObject *f; + _Py_IDENTIFIER(__complex__); + + f = _PyObject_LookupSpecial(op, &PyId___complex__); + if (f) { + PyObject *res = _PyObject_CallNoArg(f); + Py_DECREF(f); + if (!res || PyComplex_CheckExact(res)) { + return res; + } + if (!PyComplex_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__complex__ returned non-complex (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + /* Issue #29894: warn if 'res' not of exact type complex. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__complex__ returned non-complex (type %.200s). " + "The ability to return an instance of a strict subclass of complex " + "is deprecated, and may be removed in a future version of Python.", + res->ob_type->tp_name)) { + Py_DECREF(res); + return NULL; + } + return res; + } + return NULL; +} + +Py_complex +PyComplex_AsCComplex(PyObject *op) +{ + Py_complex cv; + PyObject *newop = NULL; + + assert(op); + /* If op is already of type PyComplex_Type, return its value */ + if (PyComplex_Check(op)) { + return ((PyComplexObject *)op)->cval; + } + /* If not, use op's __complex__ method, if it exists */ + + /* return -1 on failure */ + cv.real = -1.; + cv.imag = 0.; + + newop = try_complex_special_method(op); + + if (newop) { + cv = ((PyComplexObject *)newop)->cval; + Py_DECREF(newop); + return cv; + } + else if (PyErr_Occurred()) { + return cv; + } + /* If neither of the above works, interpret op as a float giving the + real part of the result, and fill in the imaginary part as 0. */ + else { + /* PyFloat_AsDouble will return -1 on failure */ + cv.real = PyFloat_AsDouble(op); + return cv; + } +} + +static PyObject * +complex_repr(PyComplexObject *v) +{ + int precision = 0; + char format_code = 'r'; + PyObject *result = NULL; + + /* If these are non-NULL, they'll need to be freed. */ + char *pre = NULL; + char *im = NULL; + + /* These do not need to be freed. re is either an alias + for pre or a pointer to a constant. lead and tail + are pointers to constants. */ + const char *re = NULL; + const char *lead = ""; + const char *tail = ""; + + if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { + /* Real part is +0: just output the imaginary part and do not + include parens. */ + re = ""; + im = PyOS_double_to_string(v->cval.imag, format_code, + precision, 0, NULL); + if (!im) { + PyErr_NoMemory(); + goto done; + } + } else { + /* Format imaginary part with sign, real part without. Include + parens in the result. */ + pre = PyOS_double_to_string(v->cval.real, format_code, + precision, 0, NULL); + if (!pre) { + PyErr_NoMemory(); + goto done; + } + re = pre; + + im = PyOS_double_to_string(v->cval.imag, format_code, + precision, Py_DTSF_SIGN, NULL); + if (!im) { + PyErr_NoMemory(); + goto done; + } + lead = "("; + tail = ")"; + } + result = PyUnicode_FromFormat("%s%s%sj%s", lead, re, im, tail); + done: + PyMem_Free(im); + PyMem_Free(pre); + + return result; +} + +static Py_hash_t +complex_hash(PyComplexObject *v) +{ + Py_uhash_t hashreal, hashimag, combined; + hashreal = (Py_uhash_t)_Py_HashDouble(v->cval.real); + if (hashreal == (Py_uhash_t)-1) + return -1; + hashimag = (Py_uhash_t)_Py_HashDouble(v->cval.imag); + if (hashimag == (Py_uhash_t)-1) + return -1; + /* Note: if the imaginary part is 0, hashimag is 0 now, + * so the following returns hashreal unchanged. This is + * important because numbers of different types that + * compare equal must have the same hash value, so that + * hash(x + 0*j) must equal hash(x). + */ + combined = hashreal + _PyHASH_IMAG * hashimag; + if (combined == (Py_uhash_t)-1) + combined = (Py_uhash_t)-2; + return (Py_hash_t)combined; +} + +/* This macro may return! */ +#define TO_COMPLEX(obj, c) \ + if (PyComplex_Check(obj)) \ + c = ((PyComplexObject *)(obj))->cval; \ + else if (to_complex(&(obj), &(c)) < 0) \ + return (obj) + +static int +to_complex(PyObject **pobj, Py_complex *pc) +{ + PyObject *obj = *pobj; + + pc->real = pc->imag = 0.0; + if (PyLong_Check(obj)) { + pc->real = PyLong_AsDouble(obj); + if (pc->real == -1.0 && PyErr_Occurred()) { + *pobj = NULL; + return -1; + } + return 0; + } + if (PyFloat_Check(obj)) { + pc->real = PyFloat_AsDouble(obj); + return 0; + } + Py_INCREF(Py_NotImplemented); + *pobj = Py_NotImplemented; + return -1; +} + + +static PyObject * +complex_add(PyObject *v, PyObject *w) +{ + Py_complex result; + Py_complex a, b; + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); + PyFPE_START_PROTECT("complex_add", return 0) + result = _Py_c_sum(a, b); + PyFPE_END_PROTECT(result) + return PyComplex_FromCComplex(result); +} + +static PyObject * +complex_sub(PyObject *v, PyObject *w) +{ + Py_complex result; + Py_complex a, b; + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); + PyFPE_START_PROTECT("complex_sub", return 0) + result = _Py_c_diff(a, b); + PyFPE_END_PROTECT(result) + return PyComplex_FromCComplex(result); +} + +static PyObject * +complex_mul(PyObject *v, PyObject *w) +{ + Py_complex result; + Py_complex a, b; + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); + PyFPE_START_PROTECT("complex_mul", return 0) + result = _Py_c_prod(a, b); + PyFPE_END_PROTECT(result) + return PyComplex_FromCComplex(result); +} + +static PyObject * +complex_div(PyObject *v, PyObject *w) +{ + Py_complex quot; + Py_complex a, b; + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); + PyFPE_START_PROTECT("complex_div", return 0) + errno = 0; + quot = _Py_c_quot(a, b); + PyFPE_END_PROTECT(quot) + if (errno == EDOM) { + PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero"); + return NULL; + } + return PyComplex_FromCComplex(quot); +} + +static PyObject * +complex_remainder(PyObject *v, PyObject *w) +{ + PyErr_SetString(PyExc_TypeError, + "can't mod complex numbers."); + return NULL; +} + + +static PyObject * +complex_divmod(PyObject *v, PyObject *w) +{ + PyErr_SetString(PyExc_TypeError, + "can't take floor or mod of complex number."); + return NULL; +} + +static PyObject * +complex_pow(PyObject *v, PyObject *w, PyObject *z) +{ + Py_complex p; + Py_complex exponent; + long int_exponent; + Py_complex a, b; + TO_COMPLEX(v, a); + TO_COMPLEX(w, b); + + if (z != Py_None) { + PyErr_SetString(PyExc_ValueError, "complex modulo"); + return NULL; + } + PyFPE_START_PROTECT("complex_pow", return 0) + errno = 0; + exponent = b; + int_exponent = (long)exponent.real; + if (exponent.imag == 0. && exponent.real == int_exponent) + p = c_powi(a, int_exponent); + else + p = _Py_c_pow(a, exponent); + + PyFPE_END_PROTECT(p) + Py_ADJUST_ERANGE2(p.real, p.imag); + if (errno == EDOM) { + PyErr_SetString(PyExc_ZeroDivisionError, + "0.0 to a negative or complex power"); + return NULL; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, + "complex exponentiation"); + return NULL; + } + return PyComplex_FromCComplex(p); +} + +static PyObject * +complex_int_div(PyObject *v, PyObject *w) +{ + PyErr_SetString(PyExc_TypeError, + "can't take floor of complex number."); + return NULL; +} + +static PyObject * +complex_neg(PyComplexObject *v) +{ + Py_complex neg; + neg.real = -v->cval.real; + neg.imag = -v->cval.imag; + return PyComplex_FromCComplex(neg); +} + +static PyObject * +complex_pos(PyComplexObject *v) +{ + if (PyComplex_CheckExact(v)) { + Py_INCREF(v); + return (PyObject *)v; + } + else + return PyComplex_FromCComplex(v->cval); +} + +static PyObject * +complex_abs(PyComplexObject *v) +{ + double result; + + PyFPE_START_PROTECT("complex_abs", return 0) + result = _Py_c_abs(v->cval); + PyFPE_END_PROTECT(result) + + if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, + "absolute value too large"); + return NULL; + } + return PyFloat_FromDouble(result); +} + +static int +complex_bool(PyComplexObject *v) +{ + return v->cval.real != 0.0 || v->cval.imag != 0.0; +} + +static PyObject * +complex_richcompare(PyObject *v, PyObject *w, int op) +{ + PyObject *res; + Py_complex i; + int equal; + + if (op != Py_EQ && op != Py_NE) { + goto Unimplemented; + } + + assert(PyComplex_Check(v)); + TO_COMPLEX(v, i); + + if (PyLong_Check(w)) { + /* Check for 0.0 imaginary part first to avoid the rich + * comparison when possible. + */ + if (i.imag == 0.0) { + PyObject *j, *sub_res; + j = PyFloat_FromDouble(i.real); + if (j == NULL) + return NULL; + + sub_res = PyObject_RichCompare(j, w, op); + Py_DECREF(j); + return sub_res; + } + else { + equal = 0; + } + } + else if (PyFloat_Check(w)) { + equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0); + } + else if (PyComplex_Check(w)) { + Py_complex j; + + TO_COMPLEX(w, j); + equal = (i.real == j.real && i.imag == j.imag); + } + else { + goto Unimplemented; + } + + if (equal == (op == Py_EQ)) + res = Py_True; + else + res = Py_False; + + Py_INCREF(res); + return res; + +Unimplemented: + Py_RETURN_NOTIMPLEMENTED; +} + +static PyObject * +complex_int(PyObject *v) +{ + PyErr_SetString(PyExc_TypeError, + "can't convert complex to int"); + return NULL; +} + +static PyObject * +complex_float(PyObject *v) +{ + PyErr_SetString(PyExc_TypeError, + "can't convert complex to float"); + return NULL; +} + +static PyObject * +complex_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + Py_complex c; + c = ((PyComplexObject *)self)->cval; + c.imag = -c.imag; + return PyComplex_FromCComplex(c); +} + +PyDoc_STRVAR(complex_conjugate_doc, +"complex.conjugate() -> complex\n" +"\n" +"Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j."); + +static PyObject * +complex_getnewargs(PyComplexObject *v, PyObject *Py_UNUSED(ignored)) +{ + Py_complex c = v->cval; + return Py_BuildValue("(dd)", c.real, c.imag); +} + +PyDoc_STRVAR(complex__format__doc, +"complex.__format__() -> str\n" +"\n" +"Convert to a string according to format_spec."); + +static PyObject * +complex__format__(PyObject* self, PyObject* args) +{ + PyObject *format_spec; + _PyUnicodeWriter writer; + int ret; + + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + + _PyUnicodeWriter_Init(&writer); + ret = _PyComplex_FormatAdvancedWriter( + &writer, + self, + format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); + if (ret == -1) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + return _PyUnicodeWriter_Finish(&writer); +} + +static PyMethodDef complex_methods[] = { + {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS, + complex_conjugate_doc}, + {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, + {"__format__", (PyCFunction)complex__format__, + METH_VARARGS, complex__format__doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef complex_members[] = { + {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY, + "the real part of a complex number"}, + {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY, + "the imaginary part of a complex number"}, + {0}, +}; + +static PyObject * +complex_from_string_inner(const char *s, Py_ssize_t len, void *type) +{ + double x=0.0, y=0.0, z; + int got_bracket=0; + const char *start; + char *end; + + /* position on first nonblank */ + start = s; + while (Py_ISSPACE(*s)) + s++; + if (*s == '(') { + /* Skip over possible bracket from repr(). */ + got_bracket = 1; + s++; + while (Py_ISSPACE(*s)) + s++; + } + + /* a valid complex string usually takes one of the three forms: + + - real part only + j - imaginary part only + j - real and imaginary parts + + where represents any numeric string that's accepted by the + float constructor (including 'nan', 'inf', 'infinity', etc.), and + is any string of the form whose first + character is '+' or '-'. + + For backwards compatibility, the extra forms + + j + j + j + + are also accepted, though support for these forms may be removed from + a future version of Python. + */ + + /* first look for forms starting with */ + z = PyOS_string_to_double(s, &end, NULL); + if (z == -1.0 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_ValueError)) + PyErr_Clear(); + else + return NULL; + } + if (end != s) { + /* all 4 forms starting with land here */ + s = end; + if (*s == '+' || *s == '-') { + /* j | j */ + x = z; + y = PyOS_string_to_double(s, &end, NULL); + if (y == -1.0 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_ValueError)) + PyErr_Clear(); + else + return NULL; + } + if (end != s) + /* j */ + s = end; + else { + /* j */ + y = *s == '+' ? 1.0 : -1.0; + s++; + } + if (!(*s == 'j' || *s == 'J')) + goto parse_error; + s++; + } + else if (*s == 'j' || *s == 'J') { + /* j */ + s++; + y = z; + } + else + /* */ + x = z; + } + else { + /* not starting with ; must be j or j */ + if (*s == '+' || *s == '-') { + /* j */ + y = *s == '+' ? 1.0 : -1.0; + s++; + } + else + /* j */ + y = 1.0; + if (!(*s == 'j' || *s == 'J')) + goto parse_error; + s++; + } + + /* trailing whitespace and closing bracket */ + while (Py_ISSPACE(*s)) + s++; + if (got_bracket) { + /* if there was an opening parenthesis, then the corresponding + closing parenthesis should be right here */ + if (*s != ')') + goto parse_error; + s++; + while (Py_ISSPACE(*s)) + s++; + } + + /* we should now be at the end of the string */ + if (s-start != len) + goto parse_error; + + return complex_subtype_from_doubles((PyTypeObject *)type, x, y); + + parse_error: + PyErr_SetString(PyExc_ValueError, + "complex() arg is a malformed string"); + return NULL; +} + +static PyObject * +complex_subtype_from_string(PyTypeObject *type, PyObject *v) +{ + const char *s; + PyObject *s_buffer = NULL, *result = NULL; + Py_ssize_t len; + + if (PyUnicode_Check(v)) { + s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); + if (s_buffer == NULL) { + return NULL; + } + assert(PyUnicode_IS_ASCII(s_buffer)); + /* Simply get a pointer to existing ASCII characters. */ + s = PyUnicode_AsUTF8AndSize(s_buffer, &len); + assert(s != NULL); + } + else { + PyErr_Format(PyExc_TypeError, + "complex() argument must be a string or a number, not '%.200s'", + Py_TYPE(v)->tp_name); + return NULL; + } + + result = _Py_string_to_number_with_underscores(s, len, "complex", v, type, + complex_from_string_inner); + Py_DECREF(s_buffer); + return result; +} + +/*[clinic input] +@classmethod +complex.__new__ as complex_new + real as r: object(c_default="_PyLong_Zero") = 0 + imag as i: object(c_default="NULL") = 0 + +Create a complex number from a real part and an optional imaginary part. + +This is equivalent to (real + imag*1j) where imag defaults to 0. +[clinic start generated code]*/ + +static PyObject * +complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) +/*[clinic end generated code: output=b6c7dd577b537dc1 input=6f6b0bedba29bcb5]*/ +{ + PyObject *tmp; + PyNumberMethods *nbr, *nbi = NULL; + Py_complex cr, ci; + int own_r = 0; + int cr_is_complex = 0; + int ci_is_complex = 0; + + /* Special-case for a single argument when type(arg) is complex. */ + if (PyComplex_CheckExact(r) && i == NULL && + type == &PyComplex_Type) { + /* Note that we can't know whether it's safe to return + a complex *subclass* instance as-is, hence the restriction + to exact complexes here. If either the input or the + output is a complex subclass, it will be handled below + as a non-orthogonal vector. */ + Py_INCREF(r); + return r; + } + if (PyUnicode_Check(r)) { + if (i != NULL) { + PyErr_SetString(PyExc_TypeError, + "complex() can't take second arg" + " if first is a string"); + return NULL; + } + return complex_subtype_from_string(type, r); + } + if (i != NULL && PyUnicode_Check(i)) { + PyErr_SetString(PyExc_TypeError, + "complex() second arg can't be a string"); + return NULL; + } + + tmp = try_complex_special_method(r); + if (tmp) { + r = tmp; + own_r = 1; + } + else if (PyErr_Occurred()) { + return NULL; + } + + nbr = r->ob_type->tp_as_number; + if (nbr == NULL || (nbr->nb_float == NULL && nbr->nb_index == NULL)) { + PyErr_Format(PyExc_TypeError, + "complex() first argument must be a string or a number, " + "not '%.200s'", + Py_TYPE(r)->tp_name); + if (own_r) { + Py_DECREF(r); + } + return NULL; + } + if (i != NULL) { + nbi = i->ob_type->tp_as_number; + if (nbi == NULL || (nbi->nb_float == NULL && nbi->nb_index == NULL)) { + PyErr_Format(PyExc_TypeError, + "complex() second argument must be a number, " + "not '%.200s'", + Py_TYPE(i)->tp_name); + if (own_r) { + Py_DECREF(r); + } + return NULL; + } + } + + /* If we get this far, then the "real" and "imag" parts should + both be treated as numbers, and the constructor should return a + complex number equal to (real + imag*1j). + + Note that we do NOT assume the input to already be in canonical + form; the "real" and "imag" parts might themselves be complex + numbers, which slightly complicates the code below. */ + if (PyComplex_Check(r)) { + /* Note that if r is of a complex subtype, we're only + retaining its real & imag parts here, and the return + value is (properly) of the builtin complex type. */ + cr = ((PyComplexObject*)r)->cval; + cr_is_complex = 1; + if (own_r) { + Py_DECREF(r); + } + } + else { + /* The "real" part really is entirely real, and contributes + nothing in the imaginary direction. + Just treat it as a double. */ + tmp = PyNumber_Float(r); + if (own_r) { + /* r was a newly created complex number, rather + than the original "real" argument. */ + Py_DECREF(r); + } + if (tmp == NULL) + return NULL; + assert(PyFloat_Check(tmp)); + cr.real = PyFloat_AsDouble(tmp); + cr.imag = 0.0; + Py_DECREF(tmp); + } + if (i == NULL) { + ci.real = cr.imag; + } + else if (PyComplex_Check(i)) { + ci = ((PyComplexObject*)i)->cval; + ci_is_complex = 1; + } else { + /* The "imag" part really is entirely imaginary, and + contributes nothing in the real direction. + Just treat it as a double. */ + tmp = PyNumber_Float(i); + if (tmp == NULL) + return NULL; + ci.real = PyFloat_AsDouble(tmp); + Py_DECREF(tmp); + } + /* If the input was in canonical form, then the "real" and "imag" + parts are real numbers, so that ci.imag and cr.imag are zero. + We need this correction in case they were not real numbers. */ + + if (ci_is_complex) { + cr.real -= ci.imag; + } + if (cr_is_complex && i != NULL) { + ci.real += cr.imag; + } + return complex_subtype_from_doubles(type, cr.real, ci.real); +} + +static PyNumberMethods complex_as_number = { + (binaryfunc)complex_add, /* nb_add */ + (binaryfunc)complex_sub, /* nb_subtract */ + (binaryfunc)complex_mul, /* nb_multiply */ + (binaryfunc)complex_remainder, /* nb_remainder */ + (binaryfunc)complex_divmod, /* nb_divmod */ + (ternaryfunc)complex_pow, /* nb_power */ + (unaryfunc)complex_neg, /* nb_negative */ + (unaryfunc)complex_pos, /* nb_positive */ + (unaryfunc)complex_abs, /* nb_absolute */ + (inquiry)complex_bool, /* nb_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + complex_int, /* nb_int */ + 0, /* nb_reserved */ + complex_float, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply*/ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + (binaryfunc)complex_int_div, /* nb_floor_divide */ + (binaryfunc)complex_div, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ +}; + +PyTypeObject PyComplex_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "complex", + sizeof(PyComplexObject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)complex_repr, /* tp_repr */ + &complex_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)complex_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + complex_new__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + complex_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + complex_methods, /* tp_methods */ + complex_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + complex_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; diff --git a/python/Objects/descrobject.c b/python/Objects/descrobject.c new file mode 100755 index 0000000..729f42c --- /dev/null +++ b/python/Objects/descrobject.c @@ -0,0 +1,1792 @@ +/* Descriptors -- a new, flexible way to describe attributes */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" +#include "structmember.h" /* Why is this not included in Python.h? */ + +/*[clinic input] +class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type" +class property "propertyobject *" "&PyProperty_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/ + +static void +descr_dealloc(PyDescrObject *descr) +{ + _PyObject_GC_UNTRACK(descr); + Py_XDECREF(descr->d_type); + Py_XDECREF(descr->d_name); + Py_XDECREF(descr->d_qualname); + PyObject_GC_Del(descr); +} + +static PyObject * +descr_name(PyDescrObject *descr) +{ + if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) + return descr->d_name; + return NULL; +} + +static PyObject * +descr_repr(PyDescrObject *descr, const char *format) +{ + PyObject *name = NULL; + if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) + name = descr->d_name; + + return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name); +} + +static PyObject * +method_repr(PyMethodDescrObject *descr) +{ + return descr_repr((PyDescrObject *)descr, + ""); +} + +static PyObject * +member_repr(PyMemberDescrObject *descr) +{ + return descr_repr((PyDescrObject *)descr, + ""); +} + +static PyObject * +getset_repr(PyGetSetDescrObject *descr) +{ + return descr_repr((PyDescrObject *)descr, + ""); +} + +static PyObject * +wrapperdescr_repr(PyWrapperDescrObject *descr) +{ + return descr_repr((PyDescrObject *)descr, + ""); +} + +static int +descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) +{ + if (obj == NULL) { + Py_INCREF(descr); + *pres = (PyObject *)descr; + return 1; + } + if (!PyObject_TypeCheck(obj, descr->d_type)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' for '%.100s' objects " + "doesn't apply to a '%.100s' object", + descr_name((PyDescrObject *)descr), "?", + descr->d_type->tp_name, + obj->ob_type->tp_name); + *pres = NULL; + return 1; + } + return 0; +} + +static PyObject * +classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) +{ + /* Ensure a valid type. Class methods ignore obj. */ + if (type == NULL) { + if (obj != NULL) + type = (PyObject *)obj->ob_type; + else { + /* Wot - no type?! */ + PyErr_Format(PyExc_TypeError, + "descriptor '%V' for type '%.100s' " + "needs either an object or a type", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; + } + } + if (!PyType_Check(type)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' for type '%.100s' " + "needs a type, not a '%.100s' as arg 2", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + type->ob_type->tp_name); + return NULL; + } + if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' requires a subtype of '%.100s' " + "but received '%.100s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + ((PyTypeObject *)type)->tp_name); + return NULL; + } + return PyCFunction_NewEx(descr->d_method, type, NULL); +} + +static PyObject * +method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) +{ + PyObject *res; + + if (descr_check((PyDescrObject *)descr, obj, &res)) + return res; + return PyCFunction_NewEx(descr->d_method, obj, NULL); +} + +static PyObject * +member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) +{ + PyObject *res; + + if (descr_check((PyDescrObject *)descr, obj, &res)) + return res; + + if (descr->d_member->flags & READ_RESTRICTED) { + if (PySys_Audit("object.__getattr__", "Os", + obj ? obj : Py_None, descr->d_member->name) < 0) { + return NULL; + } + } + + return PyMember_GetOne((char *)obj, descr->d_member); +} + +static PyObject * +getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) +{ + PyObject *res; + + if (descr_check((PyDescrObject *)descr, obj, &res)) + return res; + if (descr->d_getset->get != NULL) + return descr->d_getset->get(obj, descr->d_getset->closure); + PyErr_Format(PyExc_AttributeError, + "attribute '%V' of '%.100s' objects is not readable", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; +} + +static PyObject * +wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) +{ + PyObject *res; + + if (descr_check((PyDescrObject *)descr, obj, &res)) + return res; + return PyWrapper_New((PyObject *)descr, obj); +} + +static int +descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, + int *pres) +{ + assert(obj != NULL); + if (!PyObject_TypeCheck(obj, descr->d_type)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' for '%.100s' objects " + "doesn't apply to a '%.100s' object", + descr_name(descr), "?", + descr->d_type->tp_name, + obj->ob_type->tp_name); + *pres = -1; + return 1; + } + return 0; +} + +static int +member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value) +{ + int res; + + if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) + return res; + return PyMember_SetOne((char *)obj, descr->d_member, value); +} + +static int +getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) +{ + int res; + + if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) + return res; + if (descr->d_getset->set != NULL) + return descr->d_getset->set(obj, value, + descr->d_getset->closure); + PyErr_Format(PyExc_AttributeError, + "attribute '%V' of '%.100s' objects is not writable", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return -1; +} + + +/* Vectorcall functions for each of the PyMethodDescr calling conventions. + * + * First, common helpers + */ +static const char * +get_name(PyObject *func) { + assert(PyObject_TypeCheck(func, &PyMethodDescr_Type)); + return ((PyMethodDescrObject *)func)->d_method->ml_name; +} + +typedef void (*funcptr)(void); + +static inline int +method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + assert(!PyErr_Occurred()); + assert(PyObject_TypeCheck(func, &PyMethodDescr_Type)); + if (nargs < 1) { + PyErr_Format(PyExc_TypeError, + "descriptor '%.200s' of '%.100s' " + "object needs an argument", + get_name(func), PyDescr_TYPE(func)->tp_name); + return -1; + } + PyObject *self = args[0]; + if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)PyDescr_TYPE(func))) + { + PyErr_Format(PyExc_TypeError, + "descriptor '%.200s' for '%.100s' objects " + "doesn't apply to a '%.100s' object", + get_name(func), PyDescr_TYPE(func)->tp_name, + Py_TYPE(self)->tp_name); + return -1; + } + if (kwnames && PyTuple_GET_SIZE(kwnames)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", get_name(func)); + return -1; + } + return 0; +} + +static inline funcptr +method_enter_call(PyObject *func) +{ + if (Py_EnterRecursiveCall(" while calling a Python object")) { + return NULL; + } + return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth; +} + +/* Now the actual vectorcall functions */ +static PyObject * +method_vectorcall_VARARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); + if (argstuple == NULL) { + return NULL; + } + PyCFunction meth = (PyCFunction)method_enter_call(func); + if (meth == NULL) { + Py_DECREF(argstuple); + return NULL; + } + PyObject *result = meth(args[0], argstuple); + Py_DECREF(argstuple); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +method_vectorcall_VARARGS_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, NULL)) { + return NULL; + } + PyObject *argstuple = _PyTuple_FromArray(args+1, nargs-1); + if (argstuple == NULL) { + return NULL; + } + PyObject *result = NULL; + /* Create a temporary dict for keyword arguments */ + PyObject *kwdict = NULL; + if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) > 0) { + kwdict = _PyStack_AsDict(args + nargs, kwnames); + if (kwdict == NULL) { + goto exit; + } + } + PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords) + method_enter_call(func); + if (meth == NULL) { + goto exit; + } + result = meth(args[0], argstuple, kwdict); + Py_LeaveRecursiveCall(); +exit: + Py_DECREF(argstuple); + Py_XDECREF(kwdict); + return result; +} + +static PyObject * +method_vectorcall_FASTCALL( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + _PyCFunctionFast meth = (_PyCFunctionFast) + method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args+1, nargs-1); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +method_vectorcall_FASTCALL_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, NULL)) { + return NULL; + } + _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) + method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args+1, nargs-1, kwnames); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +method_vectorcall_NOARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + if (nargs != 1) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", get_name(func), nargs-1); + return NULL; + } + PyCFunction meth = (PyCFunction)method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], NULL); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +method_vectorcall_O( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (method_check_args(func, args, nargs, kwnames)) { + return NULL; + } + if (nargs != 2) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + get_name(func), nargs-1); + return NULL; + } + PyCFunction meth = (PyCFunction)method_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(args[0], args[1]); + Py_LeaveRecursiveCall(); + return result; +} + + +static PyObject * +classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, + PyObject *kwds) +{ + Py_ssize_t argc; + PyObject *self, *result; + + /* Make sure that the first argument is acceptable as 'self' */ + assert(PyTuple_Check(args)); + argc = PyTuple_GET_SIZE(args); + if (argc < 1) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' of '%.100s' " + "object needs an argument", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; + } + self = PyTuple_GET_ITEM(args, 0); + if (!PyType_Check(self)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' requires a type " + "but received a '%.100s' instance", + descr_name((PyDescrObject *)descr), "?", + self->ob_type->tp_name); + return NULL; + } + if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' requires a subtype of '%.100s' " + "but received '%.100s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + ((PyTypeObject*)self)->tp_name); + return NULL; + } + + result = _PyMethodDef_RawFastCallDict(descr->d_method, self, + &_PyTuple_ITEMS(args)[1], argc - 1, + kwds); + result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); + return result; +} + +Py_LOCAL_INLINE(PyObject *) +wrapperdescr_raw_call(PyWrapperDescrObject *descr, PyObject *self, + PyObject *args, PyObject *kwds) +{ + wrapperfunc wrapper = descr->d_base->wrapper; + + if (descr->d_base->flags & PyWrapperFlag_KEYWORDS) { + wrapperfunc_kwds wk = (wrapperfunc_kwds)(void(*)(void))wrapper; + return (*wk)(self, args, descr->d_wrapped, kwds); + } + + if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) { + PyErr_Format(PyExc_TypeError, + "wrapper %s() takes no keyword arguments", + descr->d_base->name); + return NULL; + } + return (*wrapper)(self, args, descr->d_wrapped); +} + +static PyObject * +wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) +{ + Py_ssize_t argc; + PyObject *self, *result; + + /* Make sure that the first argument is acceptable as 'self' */ + assert(PyTuple_Check(args)); + argc = PyTuple_GET_SIZE(args); + if (argc < 1) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' of '%.100s' " + "object needs an argument", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; + } + self = PyTuple_GET_ITEM(args, 0); + if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' " + "requires a '%.100s' object " + "but received a '%.100s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + self->ob_type->tp_name); + return NULL; + } + + args = PyTuple_GetSlice(args, 1, argc); + if (args == NULL) { + return NULL; + } + result = wrapperdescr_raw_call(descr, self, args, kwds); + Py_DECREF(args); + return result; +} + + +static PyObject * +method_get_doc(PyMethodDescrObject *descr, void *closure) +{ + return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc); +} + +static PyObject * +method_get_text_signature(PyMethodDescrObject *descr, void *closure) +{ + return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc); +} + +static PyObject * +calculate_qualname(PyDescrObject *descr) +{ + PyObject *type_qualname, *res; + _Py_IDENTIFIER(__qualname__); + + if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) { + PyErr_SetString(PyExc_TypeError, + ".__name__ is not a unicode object"); + return NULL; + } + + type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type, + &PyId___qualname__); + if (type_qualname == NULL) + return NULL; + + if (!PyUnicode_Check(type_qualname)) { + PyErr_SetString(PyExc_TypeError, ".__objclass__." + "__qualname__ is not a unicode object"); + Py_XDECREF(type_qualname); + return NULL; + } + + res = PyUnicode_FromFormat("%S.%S", type_qualname, descr->d_name); + Py_DECREF(type_qualname); + return res; +} + +static PyObject * +descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored)) +{ + if (descr->d_qualname == NULL) + descr->d_qualname = calculate_qualname(descr); + Py_XINCREF(descr->d_qualname); + return descr->d_qualname; +} + +static PyObject * +descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(getattr); + return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), + PyDescr_TYPE(descr), PyDescr_NAME(descr)); +} + +static PyMethodDef descr_methods[] = { + {"__reduce__", (PyCFunction)descr_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +static PyMemberDef descr_members[] = { + {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, + {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, + {0} +}; + +static PyGetSetDef method_getset[] = { + {"__doc__", (getter)method_get_doc}, + {"__qualname__", (getter)descr_get_qualname}, + {"__text_signature__", (getter)method_get_text_signature}, + {0} +}; + +static PyObject * +member_get_doc(PyMemberDescrObject *descr, void *closure) +{ + if (descr->d_member->doc == NULL) { + Py_RETURN_NONE; + } + return PyUnicode_FromString(descr->d_member->doc); +} + +static PyGetSetDef member_getset[] = { + {"__doc__", (getter)member_get_doc}, + {"__qualname__", (getter)descr_get_qualname}, + {0} +}; + +static PyObject * +getset_get_doc(PyGetSetDescrObject *descr, void *closure) +{ + if (descr->d_getset->doc == NULL) { + Py_RETURN_NONE; + } + return PyUnicode_FromString(descr->d_getset->doc); +} + +static PyGetSetDef getset_getset[] = { + {"__doc__", (getter)getset_get_doc}, + {"__qualname__", (getter)descr_get_qualname}, + {0} +}; + +static PyObject * +wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) +{ + return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc); +} + +static PyObject * +wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure) +{ + return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc); +} + +static PyGetSetDef wrapperdescr_getset[] = { + {"__doc__", (getter)wrapperdescr_get_doc}, + {"__qualname__", (getter)descr_get_qualname}, + {"__text_signature__", (getter)wrapperdescr_get_text_signature}, + {0} +}; + +static int +descr_traverse(PyObject *self, visitproc visit, void *arg) +{ + PyDescrObject *descr = (PyDescrObject *)self; + Py_VISIT(descr->d_type); + return 0; +} + +PyTypeObject PyMethodDescr_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "method_descriptor", + sizeof(PyMethodDescrObject), + 0, + (destructor)descr_dealloc, /* tp_dealloc */ + offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)method_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + PyVectorcall_Call, /* 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_HAVE_VECTORCALL | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ + 0, /* tp_doc */ + descr_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + descr_methods, /* tp_methods */ + descr_members, /* tp_members */ + method_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + (descrgetfunc)method_get, /* tp_descr_get */ + 0, /* tp_descr_set */ +}; + +/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ +PyTypeObject PyClassMethodDescr_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "classmethod_descriptor", + sizeof(PyMethodDescrObject), + 0, + (destructor)descr_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)method_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)classmethoddescr_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + descr_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + descr_methods, /* tp_methods */ + descr_members, /* tp_members */ + method_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + (descrgetfunc)classmethod_get, /* tp_descr_get */ + 0, /* tp_descr_set */ +}; + +PyTypeObject PyMemberDescr_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "member_descriptor", + sizeof(PyMemberDescrObject), + 0, + (destructor)descr_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)member_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + descr_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + descr_methods, /* tp_methods */ + descr_members, /* tp_members */ + member_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + (descrgetfunc)member_get, /* tp_descr_get */ + (descrsetfunc)member_set, /* tp_descr_set */ +}; + +PyTypeObject PyGetSetDescr_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "getset_descriptor", + sizeof(PyGetSetDescrObject), + 0, + (destructor)descr_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)getset_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + descr_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + descr_members, /* tp_members */ + getset_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + (descrgetfunc)getset_get, /* tp_descr_get */ + (descrsetfunc)getset_set, /* tp_descr_set */ +}; + +PyTypeObject PyWrapperDescr_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "wrapper_descriptor", + sizeof(PyWrapperDescrObject), + 0, + (destructor)descr_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)wrapperdescr_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)wrapperdescr_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ + 0, /* tp_doc */ + descr_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + descr_methods, /* tp_methods */ + descr_members, /* tp_members */ + wrapperdescr_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ +}; + +static PyDescrObject * +descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) +{ + PyDescrObject *descr; + + descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); + if (descr != NULL) { + Py_XINCREF(type); + descr->d_type = type; + descr->d_name = PyUnicode_InternFromString(name); + if (descr->d_name == NULL) { + Py_DECREF(descr); + descr = NULL; + } + else { + descr->d_qualname = NULL; + } + } + return descr; +} + +PyObject * +PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) +{ + /* Figure out correct vectorcall function to use */ + vectorcallfunc vectorcall; + switch (method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS)) + { + case METH_VARARGS: + vectorcall = method_vectorcall_VARARGS; + break; + case METH_VARARGS | METH_KEYWORDS: + vectorcall = method_vectorcall_VARARGS_KEYWORDS; + break; + case METH_FASTCALL: + vectorcall = method_vectorcall_FASTCALL; + break; + case METH_FASTCALL | METH_KEYWORDS: + vectorcall = method_vectorcall_FASTCALL_KEYWORDS; + break; + case METH_NOARGS: + vectorcall = method_vectorcall_NOARGS; + break; + case METH_O: + vectorcall = method_vectorcall_O; + break; + default: + PyErr_Format(PyExc_SystemError, + "%s() method: bad call flags", method->ml_name); + return NULL; + } + + PyMethodDescrObject *descr; + + descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, + type, method->ml_name); + if (descr != NULL) { + descr->d_method = method; + descr->vectorcall = vectorcall; + } + return (PyObject *)descr; +} + +PyObject * +PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) +{ + PyMethodDescrObject *descr; + + descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type, + type, method->ml_name); + if (descr != NULL) + descr->d_method = method; + return (PyObject *)descr; +} + +PyObject * +PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) +{ + PyMemberDescrObject *descr; + + descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type, + type, member->name); + if (descr != NULL) + descr->d_member = member; + return (PyObject *)descr; +} + +PyObject * +PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset) +{ + PyGetSetDescrObject *descr; + + descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, + type, getset->name); + if (descr != NULL) + descr->d_getset = getset; + return (PyObject *)descr; +} + +PyObject * +PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) +{ + PyWrapperDescrObject *descr; + + descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type, + type, base->name); + if (descr != NULL) { + descr->d_base = base; + descr->d_wrapped = wrapped; + } + return (PyObject *)descr; +} + + +/* --- mappingproxy: read-only proxy for mappings --- */ + +/* This has no reason to be in this file except that adding new files is a + bit of a pain */ + +typedef struct { + PyObject_HEAD + PyObject *mapping; +} mappingproxyobject; + +static Py_ssize_t +mappingproxy_len(mappingproxyobject *pp) +{ + return PyObject_Size(pp->mapping); +} + +static PyObject * +mappingproxy_getitem(mappingproxyobject *pp, PyObject *key) +{ + return PyObject_GetItem(pp->mapping, key); +} + +static PyMappingMethods mappingproxy_as_mapping = { + (lenfunc)mappingproxy_len, /* mp_length */ + (binaryfunc)mappingproxy_getitem, /* mp_subscript */ + 0, /* mp_ass_subscript */ +}; + +static int +mappingproxy_contains(mappingproxyobject *pp, PyObject *key) +{ + if (PyDict_CheckExact(pp->mapping)) + return PyDict_Contains(pp->mapping, key); + else + return PySequence_Contains(pp->mapping, key); +} + +static PySequenceMethods mappingproxy_as_sequence = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)mappingproxy_contains, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + +static PyObject * +mappingproxy_get(mappingproxyobject *pp, PyObject *args) +{ + PyObject *key, *def = Py_None; + _Py_IDENTIFIER(get); + + if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) + return NULL; + return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get, + key, def, NULL); +} + +static PyObject * +mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(keys); + return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL); +} + +static PyObject * +mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(values); + return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL); +} + +static PyObject * +mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(items); + return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL); +} + +static PyObject * +mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(copy); + return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL); +} + +/* WARNING: mappingproxy methods must not give access + to the underlying mapping */ + +static PyMethodDef mappingproxy_methods[] = { + {"get", (PyCFunction)mappingproxy_get, METH_VARARGS, + PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d." + " d defaults to None.")}, + {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS, + PyDoc_STR("D.keys() -> list of D's keys")}, + {"values", (PyCFunction)mappingproxy_values, METH_NOARGS, + PyDoc_STR("D.values() -> list of D's values")}, + {"items", (PyCFunction)mappingproxy_items, METH_NOARGS, + PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")}, + {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS, + PyDoc_STR("D.copy() -> a shallow copy of D")}, + {0} +}; + +static void +mappingproxy_dealloc(mappingproxyobject *pp) +{ + _PyObject_GC_UNTRACK(pp); + Py_DECREF(pp->mapping); + PyObject_GC_Del(pp); +} + +static PyObject * +mappingproxy_getiter(mappingproxyobject *pp) +{ + return PyObject_GetIter(pp->mapping); +} + +static PyObject * +mappingproxy_str(mappingproxyobject *pp) +{ + return PyObject_Str(pp->mapping); +} + +static PyObject * +mappingproxy_repr(mappingproxyobject *pp) +{ + return PyUnicode_FromFormat("mappingproxy(%R)", pp->mapping); +} + +static int +mappingproxy_traverse(PyObject *self, visitproc visit, void *arg) +{ + mappingproxyobject *pp = (mappingproxyobject *)self; + Py_VISIT(pp->mapping); + return 0; +} + +static PyObject * +mappingproxy_richcompare(mappingproxyobject *v, PyObject *w, int op) +{ + return PyObject_RichCompare(v->mapping, w, op); +} + +static int +mappingproxy_check_mapping(PyObject *mapping) +{ + if (!PyMapping_Check(mapping) + || PyList_Check(mapping) + || PyTuple_Check(mapping)) { + PyErr_Format(PyExc_TypeError, + "mappingproxy() argument must be a mapping, not %s", + Py_TYPE(mapping)->tp_name); + return -1; + } + return 0; +} + +/*[clinic input] +@classmethod +mappingproxy.__new__ as mappingproxy_new + + mapping: object + +[clinic start generated code]*/ + +static PyObject * +mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping) +/*[clinic end generated code: output=65f27f02d5b68fa7 input=d2d620d4f598d4f8]*/ +{ + mappingproxyobject *mappingproxy; + + if (mappingproxy_check_mapping(mapping) == -1) + return NULL; + + mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); + if (mappingproxy == NULL) + return NULL; + Py_INCREF(mapping); + mappingproxy->mapping = mapping; + _PyObject_GC_TRACK(mappingproxy); + return (PyObject *)mappingproxy; +} + +PyObject * +PyDictProxy_New(PyObject *mapping) +{ + mappingproxyobject *pp; + + if (mappingproxy_check_mapping(mapping) == -1) + return NULL; + + pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); + if (pp != NULL) { + Py_INCREF(mapping); + pp->mapping = mapping; + _PyObject_GC_TRACK(pp); + } + return (PyObject *)pp; +} + + +/* --- Wrapper object for "slot" methods --- */ + +/* This has no reason to be in this file except that adding new files is a + bit of a pain */ + +typedef struct { + PyObject_HEAD + PyWrapperDescrObject *descr; + PyObject *self; +} wrapperobject; + +#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type) + +static void +wrapper_dealloc(wrapperobject *wp) +{ + PyObject_GC_UnTrack(wp); + Py_TRASHCAN_BEGIN(wp, wrapper_dealloc) + Py_XDECREF(wp->descr); + Py_XDECREF(wp->self); + PyObject_GC_Del(wp); + Py_TRASHCAN_END +} + +static PyObject * +wrapper_richcompare(PyObject *a, PyObject *b, int op) +{ + wrapperobject *wa, *wb; + int eq; + + assert(a != NULL && b != NULL); + + /* both arguments should be wrapperobjects */ + if ((op != Py_EQ && op != Py_NE) + || !Wrapper_Check(a) || !Wrapper_Check(b)) + { + Py_RETURN_NOTIMPLEMENTED; + } + + wa = (wrapperobject *)a; + wb = (wrapperobject *)b; + eq = (wa->descr == wb->descr && wa->self == wb->self); + if (eq == (op == Py_EQ)) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +static Py_hash_t +wrapper_hash(wrapperobject *wp) +{ + Py_hash_t x, y; + x = _Py_HashPointer(wp->self); + y = _Py_HashPointer(wp->descr); + x = x ^ y; + if (x == -1) + x = -2; + return x; +} + +static PyObject * +wrapper_repr(wrapperobject *wp) +{ + return PyUnicode_FromFormat("", + wp->descr->d_base->name, + wp->self->ob_type->tp_name, + wp->self); +} + +static PyObject * +wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(getattr); + return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), + wp->self, PyDescr_NAME(wp->descr)); +} + +static PyMethodDef wrapper_methods[] = { + {"__reduce__", (PyCFunction)wrapper_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +static PyMemberDef wrapper_members[] = { + {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY}, + {0} +}; + +static PyObject * +wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored)) +{ + PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); + + Py_INCREF(c); + return c; +} + +static PyObject * +wrapper_name(wrapperobject *wp, void *Py_UNUSED(ignored)) +{ + const char *s = wp->descr->d_base->name; + + return PyUnicode_FromString(s); +} + +static PyObject * +wrapper_doc(wrapperobject *wp, void *Py_UNUSED(ignored)) +{ + return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); +} + +static PyObject * +wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored)) +{ + return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); +} + +static PyObject * +wrapper_qualname(wrapperobject *wp, void *Py_UNUSED(ignored)) +{ + return descr_get_qualname((PyDescrObject *)wp->descr, NULL); +} + +static PyGetSetDef wrapper_getsets[] = { + {"__objclass__", (getter)wrapper_objclass}, + {"__name__", (getter)wrapper_name}, + {"__qualname__", (getter)wrapper_qualname}, + {"__doc__", (getter)wrapper_doc}, + {"__text_signature__", (getter)wrapper_text_signature}, + {0} +}; + +static PyObject * +wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) +{ + return wrapperdescr_raw_call(wp->descr, wp->self, args, kwds); +} + +static int +wrapper_traverse(PyObject *self, visitproc visit, void *arg) +{ + wrapperobject *wp = (wrapperobject *)self; + Py_VISIT(wp->descr); + Py_VISIT(wp->self); + return 0; +} + +PyTypeObject _PyMethodWrapper_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "method-wrapper", /* tp_name */ + sizeof(wrapperobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)wrapper_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)wrapper_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)wrapper_hash, /* tp_hash */ + (ternaryfunc)wrapper_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + wrapper_traverse, /* tp_traverse */ + 0, /* tp_clear */ + wrapper_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + wrapper_methods, /* tp_methods */ + wrapper_members, /* tp_members */ + wrapper_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ +}; + +PyObject * +PyWrapper_New(PyObject *d, PyObject *self) +{ + wrapperobject *wp; + PyWrapperDescrObject *descr; + + assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); + descr = (PyWrapperDescrObject *)d; + assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), + (PyObject *)PyDescr_TYPE(descr))); + + wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type); + if (wp != NULL) { + Py_INCREF(descr); + wp->descr = descr; + Py_INCREF(self); + wp->self = self; + _PyObject_GC_TRACK(wp); + } + return (PyObject *)wp; +} + + +/* A built-in 'property' type */ + +/* +class property(object): + + def __init__(self, fget=None, fset=None, fdel=None, doc=None): + if doc is None and fget is not None and hasattr(fget, "__doc__"): + doc = fget.__doc__ + self.__get = fget + self.__set = fset + self.__del = fdel + self.__doc__ = doc + + def __get__(self, inst, type=None): + if inst is None: + return self + if self.__get is None: + raise AttributeError, "unreadable attribute" + return self.__get(inst) + + def __set__(self, inst, value): + if self.__set is None: + raise AttributeError, "can't set attribute" + return self.__set(inst, value) + + def __delete__(self, inst): + if self.__del is None: + raise AttributeError, "can't delete attribute" + return self.__del(inst) + +*/ + +typedef struct { + PyObject_HEAD + PyObject *prop_get; + PyObject *prop_set; + PyObject *prop_del; + PyObject *prop_doc; + int getter_doc; +} propertyobject; + +static PyObject * property_copy(PyObject *, PyObject *, PyObject *, + PyObject *); + +static PyMemberDef property_members[] = { + {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, + {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, + {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, + {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0}, + {0} +}; + + +PyDoc_STRVAR(getter_doc, + "Descriptor to change the getter on a property."); + +static PyObject * +property_getter(PyObject *self, PyObject *getter) +{ + return property_copy(self, getter, NULL, NULL); +} + + +PyDoc_STRVAR(setter_doc, + "Descriptor to change the setter on a property."); + +static PyObject * +property_setter(PyObject *self, PyObject *setter) +{ + return property_copy(self, NULL, setter, NULL); +} + + +PyDoc_STRVAR(deleter_doc, + "Descriptor to change the deleter on a property."); + +static PyObject * +property_deleter(PyObject *self, PyObject *deleter) +{ + return property_copy(self, NULL, NULL, deleter); +} + + +static PyMethodDef property_methods[] = { + {"getter", property_getter, METH_O, getter_doc}, + {"setter", property_setter, METH_O, setter_doc}, + {"deleter", property_deleter, METH_O, deleter_doc}, + {0} +}; + + +static void +property_dealloc(PyObject *self) +{ + propertyobject *gs = (propertyobject *)self; + + _PyObject_GC_UNTRACK(self); + Py_XDECREF(gs->prop_get); + Py_XDECREF(gs->prop_set); + Py_XDECREF(gs->prop_del); + Py_XDECREF(gs->prop_doc); + self->ob_type->tp_free(self); +} + +static PyObject * +property_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + if (obj == NULL || obj == Py_None) { + Py_INCREF(self); + return self; + } + + propertyobject *gs = (propertyobject *)self; + if (gs->prop_get == NULL) { + PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); + return NULL; + } + + PyObject *args[1] = {obj}; + return _PyObject_FastCall(gs->prop_get, args, 1); +} + +static int +property_descr_set(PyObject *self, PyObject *obj, PyObject *value) +{ + propertyobject *gs = (propertyobject *)self; + PyObject *func, *res; + + if (value == NULL) + func = gs->prop_del; + else + func = gs->prop_set; + if (func == NULL) { + PyErr_SetString(PyExc_AttributeError, + value == NULL ? + "can't delete attribute" : + "can't set attribute"); + return -1; + } + if (value == NULL) + res = PyObject_CallFunctionObjArgs(func, obj, NULL); + else + res = PyObject_CallFunctionObjArgs(func, obj, value, NULL); + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +static PyObject * +property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) +{ + propertyobject *pold = (propertyobject *)old; + PyObject *new, *type, *doc; + + type = PyObject_Type(old); + if (type == NULL) + return NULL; + + if (get == NULL || get == Py_None) { + Py_XDECREF(get); + get = pold->prop_get ? pold->prop_get : Py_None; + } + if (set == NULL || set == Py_None) { + Py_XDECREF(set); + set = pold->prop_set ? pold->prop_set : Py_None; + } + if (del == NULL || del == Py_None) { + Py_XDECREF(del); + del = pold->prop_del ? pold->prop_del : Py_None; + } + if (pold->getter_doc && get != Py_None) { + /* make _init use __doc__ from getter */ + doc = Py_None; + } + else { + doc = pold->prop_doc ? pold->prop_doc : Py_None; + } + + new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL); + Py_DECREF(type); + if (new == NULL) + return NULL; + return new; +} + +/*[clinic input] +property.__init__ as property_init + + fget: object(c_default="NULL") = None + function to be used for getting an attribute value + fset: object(c_default="NULL") = None + function to be used for setting an attribute value + fdel: object(c_default="NULL") = None + function to be used for del'ing an attribute + doc: object(c_default="NULL") = None + docstring + +Property attribute. + +Typical use is to define a managed attribute x: + +class C(object): + def getx(self): return self._x + def setx(self, value): self._x = value + def delx(self): del self._x + x = property(getx, setx, delx, "I'm the 'x' property.") + +Decorators make defining new properties or modifying existing ones easy: + +class C(object): + @property + def x(self): + "I am the 'x' property." + return self._x + @x.setter + def x(self, value): + self._x = value + @x.deleter + def x(self): + del self._x +[clinic start generated code]*/ + +static int +property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, + PyObject *fdel, PyObject *doc) +/*[clinic end generated code: output=01a960742b692b57 input=dfb5dbbffc6932d5]*/ +{ + if (fget == Py_None) + fget = NULL; + if (fset == Py_None) + fset = NULL; + if (fdel == Py_None) + fdel = NULL; + + Py_XINCREF(fget); + Py_XINCREF(fset); + Py_XINCREF(fdel); + Py_XINCREF(doc); + + Py_XSETREF(self->prop_get, fget); + Py_XSETREF(self->prop_set, fset); + Py_XSETREF(self->prop_del, fdel); + Py_XSETREF(self->prop_doc, doc); + self->getter_doc = 0; + + /* if no docstring given and the getter has one, use that one */ + if ((doc == NULL || doc == Py_None) && fget != NULL) { + _Py_IDENTIFIER(__doc__); + PyObject *get_doc; + int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc); + if (rc <= 0) { + return rc; + } + if (Py_TYPE(self) == &PyProperty_Type) { + Py_XSETREF(self->prop_doc, get_doc); + } + else { + /* If this is a property subclass, put __doc__ + in dict of the subclass instance instead, + otherwise it gets shadowed by __doc__ in the + class's dict. */ + int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc); + Py_DECREF(get_doc); + if (err < 0) + return -1; + } + self->getter_doc = 1; + } + + return 0; +} + +static PyObject * +property_get___isabstractmethod__(propertyobject *prop, void *closure) +{ + int res = _PyObject_IsAbstract(prop->prop_get); + if (res == -1) { + return NULL; + } + else if (res) { + Py_RETURN_TRUE; + } + + res = _PyObject_IsAbstract(prop->prop_set); + if (res == -1) { + return NULL; + } + else if (res) { + Py_RETURN_TRUE; + } + + res = _PyObject_IsAbstract(prop->prop_del); + if (res == -1) { + return NULL; + } + else if (res) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static PyGetSetDef property_getsetlist[] = { + {"__isabstractmethod__", + (getter)property_get___isabstractmethod__, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static int +property_traverse(PyObject *self, visitproc visit, void *arg) +{ + propertyobject *pp = (propertyobject *)self; + Py_VISIT(pp->prop_get); + Py_VISIT(pp->prop_set); + Py_VISIT(pp->prop_del); + Py_VISIT(pp->prop_doc); + return 0; +} + +static int +property_clear(PyObject *self) +{ + propertyobject *pp = (propertyobject *)self; + Py_CLEAR(pp->prop_doc); + return 0; +} + +#include "clinic/descrobject.c.h" + +PyTypeObject PyDictProxy_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "mappingproxy", /* tp_name */ + sizeof(mappingproxyobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)mappingproxy_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)mappingproxy_repr, /* tp_repr */ + 0, /* tp_as_number */ + &mappingproxy_as_sequence, /* tp_as_sequence */ + &mappingproxy_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)mappingproxy_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + mappingproxy_traverse, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)mappingproxy_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)mappingproxy_getiter, /* tp_iter */ + 0, /* tp_iternext */ + mappingproxy_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 */ + mappingproxy_new, /* tp_new */ +}; + +PyTypeObject PyProperty_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "property", /* tp_name */ + sizeof(propertyobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + property_dealloc, /* tp_dealloc */ + 0, /* tp_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 */ + property_init__doc__, /* tp_doc */ + property_traverse, /* tp_traverse */ + (inquiry)property_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + property_methods, /* tp_methods */ + property_members, /* tp_members */ + property_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + property_descr_get, /* tp_descr_get */ + property_descr_set, /* tp_descr_set */ + 0, /* tp_dictoffset */ + property_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; diff --git a/python/Objects/dict-common.h b/python/Objects/dict-common.h new file mode 100755 index 0000000..71d6b02 --- /dev/null +++ b/python/Objects/dict-common.h @@ -0,0 +1,68 @@ +#ifndef Py_DICT_COMMON_H +#define Py_DICT_COMMON_H + +typedef struct { + /* Cached hash code of me_key. */ + Py_hash_t me_hash; + PyObject *me_key; + PyObject *me_value; /* This field is only meaningful for combined tables */ +} PyDictKeyEntry; + +/* dict_lookup_func() returns index of entry which can be used like DK_ENTRIES(dk)[index]. + * -1 when no entry found, -3 when compare raises error. + */ +typedef Py_ssize_t (*dict_lookup_func) + (PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); + +#define DKIX_EMPTY (-1) +#define DKIX_DUMMY (-2) /* Used internally */ +#define DKIX_ERROR (-3) + +/* See dictobject.c for actual layout of DictKeysObject */ +struct _dictkeysobject { + Py_ssize_t dk_refcnt; + + /* Size of the hash table (dk_indices). It must be a power of 2. */ + Py_ssize_t dk_size; + + /* Function to lookup in the hash table (dk_indices): + + - lookdict(): general-purpose, and may return DKIX_ERROR if (and + only if) a comparison raises an exception. + + - lookdict_unicode(): specialized to Unicode string keys, comparison of + which can never raise an exception; that function can never return + DKIX_ERROR. + + - lookdict_unicode_nodummy(): similar to lookdict_unicode() but further + specialized for Unicode string keys that cannot be the value. + + - lookdict_split(): Version of lookdict() for split tables. */ + dict_lookup_func dk_lookup; + + /* Number of usable entries in dk_entries. */ + Py_ssize_t dk_usable; + + /* Number of used entries in dk_entries. */ + Py_ssize_t dk_nentries; + + /* Actual hash table of dk_size entries. It holds indices in dk_entries, + or DKIX_EMPTY(-1) or DKIX_DUMMY(-2). + + Indices must be: 0 <= indice < USABLE_FRACTION(dk_size). + + The size in bytes of an indice depends on dk_size: + + - 1 byte if dk_size <= 0xff (char*) + - 2 bytes if dk_size <= 0xffff (int16_t*) + - 4 bytes if dk_size <= 0xffffffff (int32_t*) + - 8 bytes otherwise (int64_t*) + + Dynamically sized, SIZEOF_VOID_P is minimum. */ + char dk_indices[]; /* char is required to avoid strict aliasing. */ + + /* "PyDictKeyEntry dk_entries[dk_usable];" array follows: + see the DK_ENTRIES() macro */ +}; + +#endif diff --git a/python/Objects/dictnotes.txt b/python/Objects/dictnotes.txt new file mode 100755 index 0000000..f89720c --- /dev/null +++ b/python/Objects/dictnotes.txt @@ -0,0 +1,149 @@ +NOTES ON DICTIONARIES +================================ + +Principal Use Cases for Dictionaries +------------------------------------ + +Passing keyword arguments + Typically, one read and one write for 1 to 3 elements. + Occurs frequently in normal python code. + +Class method lookup + Dictionaries vary in size with 8 to 16 elements being common. + Usually written once with many lookups. + When base classes are used, there are many failed lookups + followed by a lookup in a base class. + +Instance attribute lookup and Global variables + Dictionaries vary in size. 4 to 10 elements are common. + Both reads and writes are common. + +Builtins + Frequent reads. Almost never written. + About 150 interned strings (as of Py3.3). + A few keys are accessed much more frequently than others. + +Uniquification + Dictionaries of any size. Bulk of work is in creation. + Repeated writes to a smaller set of keys. + Single read of each key. + Some use cases have two consecutive accesses to the same key. + + * Removing duplicates from a sequence. + dict.fromkeys(seqn).keys() + + * Counting elements in a sequence. + for e in seqn: + d[e] = d.get(e,0) + 1 + + * Accumulating references in a dictionary of lists: + + for pagenumber, page in enumerate(pages): + for word in page: + d.setdefault(word, []).append(pagenumber) + + Note, the second example is a use case characterized by a get and set + to the same key. There are similar use cases with a __contains__ + followed by a get, set, or del to the same key. Part of the + justification for d.setdefault is combining the two lookups into one. + +Membership Testing + Dictionaries of any size. Created once and then rarely changes. + Single write to each key. + Many calls to __contains__() or has_key(). + Similar access patterns occur with replacement dictionaries + such as with the % formatting operator. + +Dynamic Mappings + Characterized by deletions interspersed with adds and replacements. + Performance benefits greatly from the re-use of dummy entries. + +Data Layout +----------- + +Dictionaries are composed of 3 components: +The dictobject struct itself +A dict-keys object (keys & hashes) +A values array + + +Tunable Dictionary Parameters +----------------------------- + +See comments for PyDict_MINSIZE_SPLIT, PyDict_MINSIZE_COMBINED, +USABLE_FRACTION and GROWTH_RATE in dictobject.c + +Tune-ups should be measured across a broad range of applications and +use cases. A change to any parameter will help in some situations and +hurt in others. The key is to find settings that help the most common +cases and do the least damage to the less common cases. Results will +vary dramatically depending on the exact number of keys, whether the +keys are all strings, whether reads or writes dominate, the exact +hash values of the keys (some sets of values have fewer collisions than +others). Any one test or benchmark is likely to prove misleading. + +While making a dictionary more sparse reduces collisions, it impairs +iteration and key listing. Those methods loop over every potential +entry. Doubling the size of dictionary results in twice as many +non-overlapping memory accesses for keys(), items(), values(), +__iter__(), iterkeys(), iteritems(), itervalues(), and update(). +Also, every dictionary iterates at least twice, once for the memset() +when it is created and once by dealloc(). + +Dictionary operations involving only a single key can be O(1) unless +resizing is possible. By checking for a resize only when the +dictionary can grow (and may *require* resizing), other operations +remain O(1), and the odds of resize thrashing or memory fragmentation +are reduced. In particular, an algorithm that empties a dictionary +by repeatedly invoking .pop will see no resizing, which might +not be necessary at all because the dictionary is eventually +discarded entirely. + +The key differences between this implementation and earlier versions are: + 1. The table can be split into two parts, the keys and the values. + + 2. There is an additional key-value combination: (key, NULL). + Unlike (, NULL) which represents a deleted value, (key, NULL) + represented a yet to be inserted value. This combination can only occur + when the table is split. + + 3. No small table embedded in the dict, + as this would make sharing of key-tables impossible. + + +These changes have the following consequences. + 1. General dictionaries are slightly larger. + + 2. All object dictionaries of a single class can share a single key-table, + saving about 60% memory for such cases. + +Results of Cache Locality Experiments +-------------------------------------- + +Experiments on an earlier design of dictionary, in which all tables were +combined, showed the following: + + When an entry is retrieved from memory, several adjacent entries are also + retrieved into a cache line. Since accessing items in cache is *much* + cheaper than a cache miss, an enticing idea is to probe the adjacent + entries as a first step in collision resolution. Unfortunately, the + introduction of any regularity into collision searches results in more + collisions than the current random chaining approach. + + Exploiting cache locality at the expense of additional collisions fails + to payoff when the entries are already loaded in cache (the expense + is paid with no compensating benefit). This occurs in small dictionaries + where the whole dictionary fits into a pair of cache lines. It also + occurs frequently in large dictionaries which have a common access pattern + where some keys are accessed much more frequently than others. The + more popular entries *and* their collision chains tend to remain in cache. + + To exploit cache locality, change the collision resolution section + in lookdict() and lookdict_string(). Set i^=1 at the top of the + loop and move the i = (i << 2) + i + perturb + 1 to an unrolled + version of the loop. + +For split tables, the above will apply to the keys, but the value will +always be in a different cache line from the key. + + diff --git a/python/Objects/dictobject.c b/python/Objects/dictobject.c new file mode 100755 index 0000000..edc0237 --- /dev/null +++ b/python/Objects/dictobject.c @@ -0,0 +1,4708 @@ +/* Dictionary object implementation using a hash table */ + +/* The distribution includes a separate file, Objects/dictnotes.txt, + describing explorations into dictionary design and optimization. + It covers typical dictionary use patterns, the parameters for + tuning dictionaries, and several ideas for possible optimizations. +*/ + +/* PyDictKeysObject + +This implements the dictionary's hashtable. + +As of Python 3.6, this is compact and ordered. Basic idea is described here: +* https://mail.python.org/pipermail/python-dev/2012-December/123028.html +* https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html + +layout: + ++---------------+ +| dk_refcnt | +| dk_size | +| dk_lookup | +| dk_usable | +| dk_nentries | ++---------------+ +| dk_indices | +| | ++---------------+ +| dk_entries | +| | ++---------------+ + +dk_indices is actual hashtable. It holds index in entries, or DKIX_EMPTY(-1) +or DKIX_DUMMY(-2). +Size of indices is dk_size. Type of each index in indices is vary on dk_size: + +* int8 for dk_size <= 128 +* int16 for 256 <= dk_size <= 2**15 +* int32 for 2**16 <= dk_size <= 2**31 +* int64 for 2**32 <= dk_size + +dk_entries is array of PyDictKeyEntry. Its size is USABLE_FRACTION(dk_size). +DK_ENTRIES(dk) can be used to get pointer to entries. + +NOTE: Since negative value is used for DKIX_EMPTY and DKIX_DUMMY, type of +dk_indices entry is signed integer and int16 is used for table which +dk_size == 256. +*/ + + +/* +The DictObject can be in one of two forms. + +Either: + A combined table: + ma_values == NULL, dk_refcnt == 1. + Values are stored in the me_value field of the PyDictKeysObject. +Or: + A split table: + ma_values != NULL, dk_refcnt >= 1 + Values are stored in the ma_values array. + Only string (unicode) keys are allowed. + All dicts sharing same key must have same insertion order. + +There are four kinds of slots in the table (slot is index, and +DK_ENTRIES(keys)[index] if index >= 0): + +1. Unused. index == DKIX_EMPTY + Does not hold an active (key, value) pair now and never did. Unused can + transition to Active upon key insertion. This is each slot's initial state. + +2. Active. index >= 0, me_key != NULL and me_value != NULL + Holds an active (key, value) pair. Active can transition to Dummy or + Pending upon key deletion (for combined and split tables respectively). + This is the only case in which me_value != NULL. + +3. Dummy. index == DKIX_DUMMY (combined only) + Previously held an active (key, value) pair, but that was deleted and an + active pair has not yet overwritten the slot. Dummy can transition to + Active upon key insertion. Dummy slots cannot be made Unused again + else the probe sequence in case of collision would have no way to know + they were once active. + +4. Pending. index >= 0, key != NULL, and value == NULL (split only) + Not yet inserted in split-table. +*/ + +/* +Preserving insertion order + +It's simple for combined table. Since dk_entries is mostly append only, we can +get insertion order by just iterating dk_entries. + +One exception is .popitem(). It removes last item in dk_entries and decrement +dk_nentries to achieve amortized O(1). Since there are DKIX_DUMMY remains in +dk_indices, we can't increment dk_usable even though dk_nentries is +decremented. + +In split table, inserting into pending entry is allowed only for dk_entries[ix] +where ix == mp->ma_used. Inserting into other index and deleting item cause +converting the dict to the combined table. +*/ + +/* PyDict_MINSIZE is the starting size for any new dict. + * 8 allows dicts with no more than 5 active entries; experiments suggested + * this suffices for the majority of dicts (consisting mostly of usually-small + * dicts created to pass keyword arguments). + * Making this 8, rather than 4 reduces the number of resizes for most + * dictionaries, without any significant extra memory use. + */ +#define PyDict_MINSIZE 8 + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "dict-common.h" +#include "stringlib/eq.h" /* to get unicode_eq() */ + +/*[clinic input] +class dict "PyDictObject *" "&PyDict_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/ + + +/* +To ensure the lookup algorithm terminates, there must be at least one Unused +slot (NULL key) in the table. +To avoid slowing down lookups on a near-full table, we resize the table when +it's USABLE_FRACTION (currently two-thirds) full. +*/ + +#define PERTURB_SHIFT 5 + +/* +Major subtleties ahead: Most hash schemes depend on having a "good" hash +function, in the sense of simulating randomness. Python doesn't: its most +important hash functions (for ints) are very regular in common +cases: + + >>>[hash(i) for i in range(4)] + [0, 1, 2, 3] + +This isn't necessarily bad! To the contrary, in a table of size 2**i, taking +the low-order i bits as the initial table index is extremely fast, and there +are no collisions at all for dicts indexed by a contiguous range of ints. So +this gives better-than-random behavior in common cases, and that's very +desirable. + +OTOH, when collisions occur, the tendency to fill contiguous slices of the +hash table makes a good collision resolution strategy crucial. Taking only +the last i bits of the hash code is also vulnerable: for example, consider +the list [i << 16 for i in range(20000)] as a set of keys. Since ints are +their own hash codes, and this fits in a dict of size 2**15, the last 15 bits + of every hash code are all 0: they *all* map to the same table index. + +But catering to unusual cases should not slow the usual ones, so we just take +the last i bits anyway. It's up to collision resolution to do the rest. If +we *usually* find the key we're looking for on the first try (and, it turns +out, we usually do -- the table load factor is kept under 2/3, so the odds +are solidly in our favor), then it makes best sense to keep the initial index +computation dirt cheap. + +The first half of collision resolution is to visit table indices via this +recurrence: + + j = ((5*j) + 1) mod 2**i + +For any initial j in range(2**i), repeating that 2**i times generates each +int in range(2**i) exactly once (see any text on random-number generation for +proof). By itself, this doesn't help much: like linear probing (setting +j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed +order. This would be bad, except that's not the only thing we do, and it's +actually *good* in the common cases where hash keys are consecutive. In an +example that's really too small to make this entirely clear, for a table of +size 2**3 the order of indices is: + + 0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating] + +If two things come in at index 5, the first place we look after is index 2, +not 6, so if another comes in at index 6 the collision at 5 didn't hurt it. +Linear probing is deadly in this case because there the fixed probe order +is the *same* as the order consecutive keys are likely to arrive. But it's +extremely unlikely hash codes will follow a 5*j+1 recurrence by accident, +and certain that consecutive hash codes do not. + +The other half of the strategy is to get the other bits of the hash code +into play. This is done by initializing a (unsigned) vrbl "perturb" to the +full hash code, and changing the recurrence to: + + perturb >>= PERTURB_SHIFT; + j = (5*j) + 1 + perturb; + use j % 2**i as the next table index; + +Now the probe sequence depends (eventually) on every bit in the hash code, +and the pseudo-scrambling property of recurring on 5*j+1 is more valuable, +because it quickly magnifies small differences in the bits that didn't affect +the initial index. Note that because perturb is unsigned, if the recurrence +is executed often enough perturb eventually becomes and remains 0. At that +point (very rarely reached) the recurrence is on (just) 5*j+1 again, and +that's certain to find an empty slot eventually (since it generates every int +in range(2**i), and we make sure there's always at least one empty slot). + +Selecting a good value for PERTURB_SHIFT is a balancing act. You want it +small so that the high bits of the hash code continue to affect the probe +sequence across iterations; but you want it large so that in really bad cases +the high-order hash bits have an effect on early iterations. 5 was "the +best" in minimizing total collisions across experiments Tim Peters ran (on +both normal and pathological cases), but 4 and 6 weren't significantly worse. + +Historical: Reimer Behrends contributed the idea of using a polynomial-based +approach, using repeated multiplication by x in GF(2**n) where an irreducible +polynomial for each table size was chosen such that x was a primitive root. +Christian Tismer later extended that to use division by x instead, as an +efficient way to get the high bits of the hash code into play. This scheme +also gave excellent collision statistics, but was more expensive: two +if-tests were required inside the loop; computing "the next" index took about +the same number of operations but without as much potential parallelism +(e.g., computing 5*j can go on at the same time as computing 1+perturb in the +above, and then shifting perturb can be done while the table index is being +masked); and the PyDictObject struct required a member to hold the table's +polynomial. In Tim's experiments the current scheme ran faster, produced +equally good collision statistics, needed less code & used less memory. + +*/ + +/* forward declarations */ +static Py_ssize_t lookdict(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr); +static Py_ssize_t lookdict_unicode(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr); +static Py_ssize_t +lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr); +static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr); + +static int dictresize(PyDictObject *mp, Py_ssize_t minused); + +static PyObject* dict_iter(PyDictObject *dict); + +/*Global counter used to set ma_version_tag field of dictionary. + * It is incremented each time that a dictionary is created and each + * time that a dictionary is modified. */ +static uint64_t pydict_global_version = 0; + +#define DICT_NEXT_VERSION() (++pydict_global_version) + +/* Dictionary reuse scheme to save calls to malloc and free */ +#ifndef PyDict_MAXFREELIST +#define PyDict_MAXFREELIST 80 +#endif +static PyDictObject *free_list[PyDict_MAXFREELIST]; +static int numfree = 0; +static PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; +static int numfreekeys = 0; + +#include "clinic/dictobject.c.h" + +int +PyDict_ClearFreeList(void) +{ + PyDictObject *op; + int ret = numfree + numfreekeys; + while (numfree) { + op = free_list[--numfree]; + assert(PyDict_CheckExact(op)); + PyObject_GC_Del(op); + } + while (numfreekeys) { + PyObject_FREE(keys_free_list[--numfreekeys]); + } + return ret; +} + +/* Print summary info about the state of the optimized allocator */ +void +_PyDict_DebugMallocStats(FILE *out) +{ + _PyDebugAllocatorStats(out, + "free PyDictObject", numfree, sizeof(PyDictObject)); +} + + +void +PyDict_Fini(void) +{ + PyDict_ClearFreeList(); +} + +#define DK_SIZE(dk) ((dk)->dk_size) +#if SIZEOF_VOID_P > 4 +#define DK_IXSIZE(dk) \ + (DK_SIZE(dk) <= 0xff ? \ + 1 : DK_SIZE(dk) <= 0xffff ? \ + 2 : DK_SIZE(dk) <= 0xffffffff ? \ + 4 : sizeof(int64_t)) +#else +#define DK_IXSIZE(dk) \ + (DK_SIZE(dk) <= 0xff ? \ + 1 : DK_SIZE(dk) <= 0xffff ? \ + 2 : sizeof(int32_t)) +#endif +#define DK_ENTRIES(dk) \ + ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)])) + +#define DK_MASK(dk) (((dk)->dk_size)-1) +#define IS_POWER_OF_2(x) (((x) & (x-1)) == 0) + +static void free_keys_object(PyDictKeysObject *keys); + +static inline void +dictkeys_incref(PyDictKeysObject *dk) +{ + _Py_INC_REFTOTAL; + dk->dk_refcnt++; +} + +static inline void +dictkeys_decref(PyDictKeysObject *dk) +{ + assert(dk->dk_refcnt > 0); + _Py_DEC_REFTOTAL; + if (--dk->dk_refcnt == 0) { + free_keys_object(dk); + } +} + +/* lookup indices. returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */ +static inline Py_ssize_t +dictkeys_get_index(PyDictKeysObject *keys, Py_ssize_t i) +{ + Py_ssize_t s = DK_SIZE(keys); + Py_ssize_t ix; + + if (s <= 0xff) { + int8_t *indices = (int8_t*)(keys->dk_indices); + ix = indices[i]; + } + else if (s <= 0xffff) { + int16_t *indices = (int16_t*)(keys->dk_indices); + ix = indices[i]; + } +#if SIZEOF_VOID_P > 4 + else if (s > 0xffffffff) { + int64_t *indices = (int64_t*)(keys->dk_indices); + ix = indices[i]; + } +#endif + else { + int32_t *indices = (int32_t*)(keys->dk_indices); + ix = indices[i]; + } + assert(ix >= DKIX_DUMMY); + return ix; +} + +/* write to indices. */ +static inline void +dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) +{ + Py_ssize_t s = DK_SIZE(keys); + + assert(ix >= DKIX_DUMMY); + + if (s <= 0xff) { + int8_t *indices = (int8_t*)(keys->dk_indices); + assert(ix <= 0x7f); + indices[i] = (char)ix; + } + else if (s <= 0xffff) { + int16_t *indices = (int16_t*)(keys->dk_indices); + assert(ix <= 0x7fff); + indices[i] = (int16_t)ix; + } +#if SIZEOF_VOID_P > 4 + else if (s > 0xffffffff) { + int64_t *indices = (int64_t*)(keys->dk_indices); + indices[i] = ix; + } +#endif + else { + int32_t *indices = (int32_t*)(keys->dk_indices); + assert(ix <= 0x7fffffff); + indices[i] = (int32_t)ix; + } +} + + +/* USABLE_FRACTION is the maximum dictionary load. + * Increasing this ratio makes dictionaries more dense resulting in more + * collisions. Decreasing it improves sparseness at the expense of spreading + * indices over more cache lines and at the cost of total memory consumed. + * + * USABLE_FRACTION must obey the following: + * (0 < USABLE_FRACTION(n) < n) for all n >= 2 + * + * USABLE_FRACTION should be quick to calculate. + * Fractions around 1/2 to 2/3 seem to work well in practice. + */ +#define USABLE_FRACTION(n) (((n) << 1)/3) + +/* ESTIMATE_SIZE is reverse function of USABLE_FRACTION. + * This can be used to reserve enough size to insert n entries without + * resizing. + */ +#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1) + +/* Alternative fraction that is otherwise close enough to 2n/3 to make + * little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10. + * 32 * 2/3 = 21, 32 * 5/8 = 20. + * Its advantage is that it is faster to compute on machines with slow division. + * #define USABLE_FRACTION(n) (((n) >> 1) + ((n) >> 2) - ((n) >> 3)) + */ + +/* GROWTH_RATE. Growth rate upon hitting maximum load. + * Currently set to used*3. + * This means that dicts double in size when growing without deletions, + * but have more head room when the number of deletions is on a par with the + * number of insertions. See also bpo-17563 and bpo-33205. + * + * GROWTH_RATE was set to used*4 up to version 3.2. + * GROWTH_RATE was set to used*2 in version 3.3.0 + * GROWTH_RATE was set to used*2 + capacity/2 in 3.4.0-3.6.0. + */ +#define GROWTH_RATE(d) ((d)->ma_used*3) + +#define ENSURE_ALLOWS_DELETIONS(d) \ + if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \ + (d)->ma_keys->dk_lookup = lookdict_unicode; \ + } + +/* This immutable, empty PyDictKeysObject is used for PyDict_Clear() + * (which cannot fail and thus can do no allocation). + */ +static PyDictKeysObject empty_keys_struct = { + 1, /* dk_refcnt */ + 1, /* dk_size */ + lookdict_split, /* dk_lookup */ + 0, /* dk_usable (immutable) */ + 0, /* dk_nentries */ + {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, + DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */ +}; + +static PyObject *empty_values[1] = { NULL }; + +#define Py_EMPTY_KEYS &empty_keys_struct + +/* Uncomment to check the dict content in _PyDict_CheckConsistency() */ +/* #define DEBUG_PYDICT */ + +#ifdef DEBUG_PYDICT +# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1)) +#else +# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 0)) +#endif + + +int +_PyDict_CheckConsistency(PyObject *op, int check_content) +{ +#define CHECK(expr) \ + do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) + + assert(op != NULL); + CHECK(PyDict_Check(op)); + PyDictObject *mp = (PyDictObject *)op; + + PyDictKeysObject *keys = mp->ma_keys; + int splitted = _PyDict_HasSplitTable(mp); + Py_ssize_t usable = USABLE_FRACTION(keys->dk_size); + + CHECK(0 <= mp->ma_used && mp->ma_used <= usable); + CHECK(IS_POWER_OF_2(keys->dk_size)); + CHECK(0 <= keys->dk_usable && keys->dk_usable <= usable); + CHECK(0 <= keys->dk_nentries && keys->dk_nentries <= usable); + CHECK(keys->dk_usable + keys->dk_nentries <= usable); + + if (!splitted) { + /* combined table */ + CHECK(keys->dk_refcnt == 1); + } + + if (check_content) { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + Py_ssize_t i; + + for (i=0; i < keys->dk_size; i++) { + Py_ssize_t ix = dictkeys_get_index(keys, i); + CHECK(DKIX_DUMMY <= ix && ix <= usable); + } + + for (i=0; i < usable; i++) { + PyDictKeyEntry *entry = &entries[i]; + PyObject *key = entry->me_key; + + if (key != NULL) { + if (PyUnicode_CheckExact(key)) { + Py_hash_t hash = ((PyASCIIObject *)key)->hash; + CHECK(hash != -1); + CHECK(entry->me_hash == hash); + } + else { + /* test_dict fails if PyObject_Hash() is called again */ + CHECK(entry->me_hash != -1); + } + if (!splitted) { + CHECK(entry->me_value != NULL); + } + } + + if (splitted) { + CHECK(entry->me_value == NULL); + } + } + + if (splitted) { + /* splitted table */ + for (i=0; i < mp->ma_used; i++) { + CHECK(mp->ma_values[i] != NULL); + } + } + } + return 1; + +#undef CHECK +} + + +static PyDictKeysObject *new_keys_object(Py_ssize_t size) +{ + PyDictKeysObject *dk; + Py_ssize_t es, usable; + + assert(size >= PyDict_MINSIZE); + assert(IS_POWER_OF_2(size)); + + usable = USABLE_FRACTION(size); + if (size <= 0xff) { + es = 1; + } + else if (size <= 0xffff) { + es = 2; + } +#if SIZEOF_VOID_P > 4 + else if (size <= 0xffffffff) { + es = 4; + } +#endif + else { + es = sizeof(Py_ssize_t); + } + + if (size == PyDict_MINSIZE && numfreekeys > 0) { + dk = keys_free_list[--numfreekeys]; + } + else { + dk = PyObject_MALLOC(sizeof(PyDictKeysObject) + + es * size + + sizeof(PyDictKeyEntry) * usable); + if (dk == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + _Py_INC_REFTOTAL; + dk->dk_refcnt = 1; + dk->dk_size = size; + dk->dk_usable = usable; + dk->dk_lookup = lookdict_unicode_nodummy; + dk->dk_nentries = 0; + memset(&dk->dk_indices[0], 0xff, es * size); + memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable); + return dk; +} + +static void +free_keys_object(PyDictKeysObject *keys) +{ + PyDictKeyEntry *entries = DK_ENTRIES(keys); + Py_ssize_t i, n; + for (i = 0, n = keys->dk_nentries; i < n; i++) { + Py_XDECREF(entries[i].me_key); + Py_XDECREF(entries[i].me_value); + } + if (keys->dk_size == PyDict_MINSIZE && numfreekeys < PyDict_MAXFREELIST) { + keys_free_list[numfreekeys++] = keys; + return; + } + PyObject_FREE(keys); +} + +#define new_values(size) PyMem_NEW(PyObject *, size) +#define free_values(values) PyMem_FREE(values) + +/* Consumes a reference to the keys object */ +static PyObject * +new_dict(PyDictKeysObject *keys, PyObject **values) +{ + PyDictObject *mp; + assert(keys != NULL); + if (numfree) { + mp = free_list[--numfree]; + assert (mp != NULL); + assert (Py_TYPE(mp) == &PyDict_Type); + _Py_NewReference((PyObject *)mp); + } + else { + mp = PyObject_GC_New(PyDictObject, &PyDict_Type); + if (mp == NULL) { + dictkeys_decref(keys); + if (values != empty_values) { + free_values(values); + } + return NULL; + } + } + mp->ma_keys = keys; + mp->ma_values = values; + mp->ma_used = 0; + mp->ma_version_tag = DICT_NEXT_VERSION(); + ASSERT_CONSISTENT(mp); + return (PyObject *)mp; +} + +/* Consumes a reference to the keys object */ +static PyObject * +new_dict_with_shared_keys(PyDictKeysObject *keys) +{ + PyObject **values; + Py_ssize_t i, size; + + size = USABLE_FRACTION(DK_SIZE(keys)); + values = new_values(size); + if (values == NULL) { + dictkeys_decref(keys); + return PyErr_NoMemory(); + } + for (i = 0; i < size; i++) { + values[i] = NULL; + } + return new_dict(keys, values); +} + + +static PyObject * +clone_combined_dict(PyDictObject *orig) +{ + assert(PyDict_CheckExact(orig)); + assert(orig->ma_values == NULL); + assert(orig->ma_keys->dk_refcnt == 1); + + Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys); + PyDictKeysObject *keys = PyObject_Malloc(keys_size); + if (keys == NULL) { + PyErr_NoMemory(); + return NULL; + } + + memcpy(keys, orig->ma_keys, keys_size); + + /* After copying key/value pairs, we need to incref all + keys and values and they are about to be co-owned by a + new dict object. */ + PyDictKeyEntry *ep0 = DK_ENTRIES(keys); + Py_ssize_t n = keys->dk_nentries; + for (Py_ssize_t i = 0; i < n; i++) { + PyDictKeyEntry *entry = &ep0[i]; + PyObject *value = entry->me_value; + if (value != NULL) { + Py_INCREF(value); + Py_INCREF(entry->me_key); + } + } + + PyDictObject *new = (PyDictObject *)new_dict(keys, NULL); + if (new == NULL) { + /* In case of an error, `new_dict()` takes care of + cleaning up `keys`. */ + return NULL; + } + new->ma_used = orig->ma_used; + ASSERT_CONSISTENT(new); + if (_PyObject_GC_IS_TRACKED(orig)) { + /* Maintain tracking. */ + _PyObject_GC_TRACK(new); + } + + /* Since we copied the keys table we now have an extra reference + in the system. Manually call _Py_INC_REFTOTAL to signal that + we have it now; calling dictkeys_incref would be an error as + keys->dk_refcnt is already set to 1 (after memcpy). */ + _Py_INC_REFTOTAL; + + return (PyObject *)new; +} + +PyObject * +PyDict_New(void) +{ + dictkeys_incref(Py_EMPTY_KEYS); + return new_dict(Py_EMPTY_KEYS, empty_values); +} + +/* Search index of hash table from offset of entry table */ +static Py_ssize_t +lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index) +{ + size_t mask = DK_MASK(k); + size_t perturb = (size_t)hash; + size_t i = (size_t)hash & mask; + + for (;;) { + Py_ssize_t ix = dictkeys_get_index(k, i); + if (ix == index) { + return i; + } + if (ix == DKIX_EMPTY) { + return DKIX_EMPTY; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + +/* +The basic lookup function used by all operations. +This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4. +Open addressing is preferred over chaining since the link overhead for +chaining would be substantial (100% with typical malloc overhead). + +The initial probe index is computed as hash mod the table size. Subsequent +probe indices are computed as explained earlier. + +All arithmetic on hash should ignore overflow. + +The details in this version are due to Tim Peters, building on many past +contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and +Christian Tismer. + +lookdict() is general-purpose, and may return DKIX_ERROR if (and only if) a +comparison raises an exception. +lookdict_unicode() below is specialized to string keys, comparison of which can +never raise an exception; that function can never return DKIX_ERROR when key +is string. Otherwise, it falls back to lookdict(). +lookdict_unicode_nodummy is further specialized for string keys that cannot be +the value. +For both, when the key isn't found a DKIX_EMPTY is returned. +*/ +static Py_ssize_t _Py_HOT_FUNCTION +lookdict(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr) +{ + size_t i, mask, perturb; + PyDictKeysObject *dk; + PyDictKeyEntry *ep0; + +top: + dk = mp->ma_keys; + ep0 = DK_ENTRIES(dk); + mask = DK_MASK(dk); + perturb = hash; + i = (size_t)hash & mask; + + for (;;) { + Py_ssize_t ix = dictkeys_get_index(dk, i); + if (ix == DKIX_EMPTY) { + *value_addr = NULL; + return ix; + } + if (ix >= 0) { + PyDictKeyEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + if (ep->me_key == key) { + *value_addr = ep->me_value; + return ix; + } + if (ep->me_hash == hash) { + PyObject *startkey = ep->me_key; + Py_INCREF(startkey); + int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) { + *value_addr = NULL; + return DKIX_ERROR; + } + if (dk == mp->ma_keys && ep->me_key == startkey) { + if (cmp > 0) { + *value_addr = ep->me_value; + return ix; + } + } + else { + /* The dict was mutated, restart */ + goto top; + } + } + } + perturb >>= PERTURB_SHIFT; + i = (i*5 + perturb + 1) & mask; + } + Py_UNREACHABLE(); +} + +/* Specialized version for string-only keys */ +static Py_ssize_t _Py_HOT_FUNCTION +lookdict_unicode(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr) +{ + assert(mp->ma_values == NULL); + /* Make sure this function doesn't have to handle non-unicode keys, + including subclasses of str; e.g., one reason to subclass + unicodes is to override __eq__, and for speed we don't cater to + that here. */ + if (!PyUnicode_CheckExact(key)) { + mp->ma_keys->dk_lookup = lookdict; + return lookdict(mp, key, hash, value_addr); + } + + PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys); + size_t mask = DK_MASK(mp->ma_keys); + size_t perturb = (size_t)hash; + size_t i = (size_t)hash & mask; + + for (;;) { + Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i); + if (ix == DKIX_EMPTY) { + *value_addr = NULL; + return DKIX_EMPTY; + } + if (ix >= 0) { + PyDictKeyEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + assert(PyUnicode_CheckExact(ep->me_key)); + if (ep->me_key == key || + (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { + *value_addr = ep->me_value; + return ix; + } + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + +/* Faster version of lookdict_unicode when it is known that no keys + * will be present. */ +static Py_ssize_t _Py_HOT_FUNCTION +lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr) +{ + assert(mp->ma_values == NULL); + /* Make sure this function doesn't have to handle non-unicode keys, + including subclasses of str; e.g., one reason to subclass + unicodes is to override __eq__, and for speed we don't cater to + that here. */ + if (!PyUnicode_CheckExact(key)) { + mp->ma_keys->dk_lookup = lookdict; + return lookdict(mp, key, hash, value_addr); + } + + PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys); + size_t mask = DK_MASK(mp->ma_keys); + size_t perturb = (size_t)hash; + size_t i = (size_t)hash & mask; + + for (;;) { + Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i); + assert (ix != DKIX_DUMMY); + if (ix == DKIX_EMPTY) { + *value_addr = NULL; + return DKIX_EMPTY; + } + PyDictKeyEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + assert(PyUnicode_CheckExact(ep->me_key)); + if (ep->me_key == key || + (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { + *value_addr = ep->me_value; + return ix; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + +/* Version of lookdict for split tables. + * All split tables and only split tables use this lookup function. + * Split tables only contain unicode keys and no dummy keys, + * so algorithm is the same as lookdict_unicode_nodummy. + */ +static Py_ssize_t _Py_HOT_FUNCTION +lookdict_split(PyDictObject *mp, PyObject *key, + Py_hash_t hash, PyObject **value_addr) +{ + /* mp must split table */ + assert(mp->ma_values != NULL); + if (!PyUnicode_CheckExact(key)) { + Py_ssize_t ix = lookdict(mp, key, hash, value_addr); + if (ix >= 0) { + *value_addr = mp->ma_values[ix]; + } + return ix; + } + + PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys); + size_t mask = DK_MASK(mp->ma_keys); + size_t perturb = (size_t)hash; + size_t i = (size_t)hash & mask; + + for (;;) { + Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i); + assert (ix != DKIX_DUMMY); + if (ix == DKIX_EMPTY) { + *value_addr = NULL; + return DKIX_EMPTY; + } + PyDictKeyEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + assert(PyUnicode_CheckExact(ep->me_key)); + if (ep->me_key == key || + (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { + *value_addr = mp->ma_values[ix]; + return ix; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + +int +_PyDict_HasOnlyStringKeys(PyObject *dict) +{ + Py_ssize_t pos = 0; + PyObject *key, *value; + assert(PyDict_Check(dict)); + /* Shortcut */ + if (((PyDictObject *)dict)->ma_keys->dk_lookup != lookdict) + return 1; + while (PyDict_Next(dict, &pos, &key, &value)) + if (!PyUnicode_Check(key)) + return 0; + return 1; +} + +#define MAINTAIN_TRACKING(mp, key, value) \ + do { \ + if (!_PyObject_GC_IS_TRACKED(mp)) { \ + if (_PyObject_GC_MAY_BE_TRACKED(key) || \ + _PyObject_GC_MAY_BE_TRACKED(value)) { \ + _PyObject_GC_TRACK(mp); \ + } \ + } \ + } while(0) + +void +_PyDict_MaybeUntrack(PyObject *op) +{ + PyDictObject *mp; + PyObject *value; + Py_ssize_t i, numentries; + PyDictKeyEntry *ep0; + + if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op)) + return; + + mp = (PyDictObject *) op; + ep0 = DK_ENTRIES(mp->ma_keys); + numentries = mp->ma_keys->dk_nentries; + if (_PyDict_HasSplitTable(mp)) { + for (i = 0; i < numentries; i++) { + if ((value = mp->ma_values[i]) == NULL) + continue; + if (_PyObject_GC_MAY_BE_TRACKED(value)) { + assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)); + return; + } + } + } + else { + for (i = 0; i < numentries; i++) { + if ((value = ep0[i].me_value) == NULL) + continue; + if (_PyObject_GC_MAY_BE_TRACKED(value) || + _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)) + return; + } + } + _PyObject_GC_UNTRACK(op); +} + +/* Internal function to find slot for an item from its hash + when it is known that the key is not present in the dict. + + The dict must be combined. */ +static Py_ssize_t +find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash) +{ + assert(keys != NULL); + + const size_t mask = DK_MASK(keys); + size_t i = hash & mask; + Py_ssize_t ix = dictkeys_get_index(keys, i); + for (size_t perturb = hash; ix >= 0;) { + perturb >>= PERTURB_SHIFT; + i = (i*5 + perturb + 1) & mask; + ix = dictkeys_get_index(keys, i); + } + return i; +} + +static int +insertion_resize(PyDictObject *mp) +{ + return dictresize(mp, GROWTH_RATE(mp)); +} + +/* +Internal routine to insert a new item into the table. +Used both by the internal resize routine and by the public insert routine. +Returns -1 if an error occurred, or 0 on success. +*/ +static int +insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) +{ + PyObject *old_value; + PyDictKeyEntry *ep; + + Py_INCREF(key); + Py_INCREF(value); + if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { + if (insertion_resize(mp) < 0) + goto Fail; + } + + Py_ssize_t ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value); + if (ix == DKIX_ERROR) + goto Fail; + + assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); + MAINTAIN_TRACKING(mp, key, value); + + /* When insertion order is different from shared key, we can't share + * the key anymore. Convert this instance to combine table. + */ + if (_PyDict_HasSplitTable(mp) && + ((ix >= 0 && old_value == NULL && mp->ma_used != ix) || + (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) { + if (insertion_resize(mp) < 0) + goto Fail; + ix = DKIX_EMPTY; + } + + if (ix == DKIX_EMPTY) { + /* Insert into new slot. */ + assert(old_value == NULL); + if (mp->ma_keys->dk_usable <= 0) { + /* Need to resize. */ + if (insertion_resize(mp) < 0) + goto Fail; + } + Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); + ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); + ep->me_key = key; + ep->me_hash = hash; + if (mp->ma_values) { + assert (mp->ma_values[mp->ma_keys->dk_nentries] == NULL); + mp->ma_values[mp->ma_keys->dk_nentries] = value; + } + else { + ep->me_value = value; + } + mp->ma_used++; + mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_keys->dk_usable--; + mp->ma_keys->dk_nentries++; + assert(mp->ma_keys->dk_usable >= 0); + ASSERT_CONSISTENT(mp); + return 0; + } + + if (old_value != value) { + if (_PyDict_HasSplitTable(mp)) { + mp->ma_values[ix] = value; + if (old_value == NULL) { + /* pending state */ + assert(ix == mp->ma_used); + mp->ma_used++; + } + } + else { + assert(old_value != NULL); + DK_ENTRIES(mp->ma_keys)[ix].me_value = value; + } + mp->ma_version_tag = DICT_NEXT_VERSION(); + } + Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ + ASSERT_CONSISTENT(mp); + Py_DECREF(key); + return 0; + +Fail: + Py_DECREF(value); + Py_DECREF(key); + return -1; +} + +// Same to insertdict but specialized for ma_keys = Py_EMPTY_KEYS. +static int +insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, + PyObject *value) +{ + assert(mp->ma_keys == Py_EMPTY_KEYS); + + PyDictKeysObject *newkeys = new_keys_object(PyDict_MINSIZE); + if (newkeys == NULL) { + return -1; + } + if (!PyUnicode_CheckExact(key)) { + newkeys->dk_lookup = lookdict; + } + dictkeys_decref(Py_EMPTY_KEYS); + mp->ma_keys = newkeys; + mp->ma_values = NULL; + + Py_INCREF(key); + Py_INCREF(value); + MAINTAIN_TRACKING(mp, key, value); + + size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1); + PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys); + dictkeys_set_index(mp->ma_keys, hashpos, 0); + ep->me_key = key; + ep->me_hash = hash; + ep->me_value = value; + mp->ma_used++; + mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_keys->dk_usable--; + mp->ma_keys->dk_nentries++; + return 0; +} + +/* +Internal routine used by dictresize() to build a hashtable of entries. +*/ +static void +build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) +{ + size_t mask = (size_t)DK_SIZE(keys) - 1; + for (Py_ssize_t ix = 0; ix != n; ix++, ep++) { + Py_hash_t hash = ep->me_hash; + size_t i = hash & mask; + for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) { + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + dictkeys_set_index(keys, i, ix); + } +} + +/* +Restructure the table by allocating a new table and reinserting all +items again. When entries have been deleted, the new table may +actually be smaller than the old one. +If a table is split (its keys and hashes are shared, its values are not), +then the values are temporarily copied into the table, it is resized as +a combined table, then the me_value slots in the old table are NULLed out. +After resizing a table is always combined, +but can be resplit by make_keys_shared(). +*/ +static int +dictresize(PyDictObject *mp, Py_ssize_t minsize) +{ + Py_ssize_t newsize, numentries; + PyDictKeysObject *oldkeys; + PyObject **oldvalues; + PyDictKeyEntry *oldentries, *newentries; + + /* Find the smallest table size > minused. */ + for (newsize = PyDict_MINSIZE; + newsize < minsize && newsize > 0; + newsize <<= 1) + ; + if (newsize <= 0) { + PyErr_NoMemory(); + return -1; + } + + oldkeys = mp->ma_keys; + + /* NOTE: Current odict checks mp->ma_keys to detect resize happen. + * So we can't reuse oldkeys even if oldkeys->dk_size == newsize. + * TODO: Try reusing oldkeys when reimplement odict. + */ + + /* Allocate a new table. */ + mp->ma_keys = new_keys_object(newsize); + if (mp->ma_keys == NULL) { + mp->ma_keys = oldkeys; + return -1; + } + // New table must be large enough. + assert(mp->ma_keys->dk_usable >= mp->ma_used); + if (oldkeys->dk_lookup == lookdict) + mp->ma_keys->dk_lookup = lookdict; + + numentries = mp->ma_used; + oldentries = DK_ENTRIES(oldkeys); + newentries = DK_ENTRIES(mp->ma_keys); + oldvalues = mp->ma_values; + if (oldvalues != NULL) { + /* Convert split table into new combined table. + * We must incref keys; we can transfer values. + * Note that values of split table is always dense. + */ + for (Py_ssize_t i = 0; i < numentries; i++) { + assert(oldvalues[i] != NULL); + PyDictKeyEntry *ep = &oldentries[i]; + PyObject *key = ep->me_key; + Py_INCREF(key); + newentries[i].me_key = key; + newentries[i].me_hash = ep->me_hash; + newentries[i].me_value = oldvalues[i]; + } + + dictkeys_decref(oldkeys); + mp->ma_values = NULL; + if (oldvalues != empty_values) { + free_values(oldvalues); + } + } + else { // combined table. + if (oldkeys->dk_nentries == numentries) { + memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry)); + } + else { + PyDictKeyEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i] = *ep++; + } + } + + assert(oldkeys->dk_lookup != lookdict_split); + assert(oldkeys->dk_refcnt == 1); + if (oldkeys->dk_size == PyDict_MINSIZE && + numfreekeys < PyDict_MAXFREELIST) { + _Py_DEC_REFTOTAL; + keys_free_list[numfreekeys++] = oldkeys; + } + else { + _Py_DEC_REFTOTAL; + PyObject_FREE(oldkeys); + } + } + + build_indices(mp->ma_keys, newentries, numentries); + mp->ma_keys->dk_usable -= numentries; + mp->ma_keys->dk_nentries = numentries; + return 0; +} + +/* Returns NULL if unable to split table. + * A NULL return does not necessarily indicate an error */ +static PyDictKeysObject * +make_keys_shared(PyObject *op) +{ + Py_ssize_t i; + Py_ssize_t size; + PyDictObject *mp = (PyDictObject *)op; + + if (!PyDict_CheckExact(op)) + return NULL; + if (!_PyDict_HasSplitTable(mp)) { + PyDictKeyEntry *ep0; + PyObject **values; + assert(mp->ma_keys->dk_refcnt == 1); + if (mp->ma_keys->dk_lookup == lookdict) { + return NULL; + } + else if (mp->ma_keys->dk_lookup == lookdict_unicode) { + /* Remove dummy keys */ + if (dictresize(mp, DK_SIZE(mp->ma_keys))) + return NULL; + } + assert(mp->ma_keys->dk_lookup == lookdict_unicode_nodummy); + /* Copy values into a new array */ + ep0 = DK_ENTRIES(mp->ma_keys); + size = USABLE_FRACTION(DK_SIZE(mp->ma_keys)); + values = new_values(size); + if (values == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Not enough memory to allocate new values array"); + return NULL; + } + for (i = 0; i < size; i++) { + values[i] = ep0[i].me_value; + ep0[i].me_value = NULL; + } + mp->ma_keys->dk_lookup = lookdict_split; + mp->ma_values = values; + } + dictkeys_incref(mp->ma_keys); + return mp->ma_keys; +} + +PyObject * +_PyDict_NewPresized(Py_ssize_t minused) +{ + const Py_ssize_t max_presize = 128 * 1024; + Py_ssize_t newsize; + PyDictKeysObject *new_keys; + + if (minused <= USABLE_FRACTION(PyDict_MINSIZE)) { + return PyDict_New(); + } + /* There are no strict guarantee that returned dict can contain minused + * items without resize. So we create medium size dict instead of very + * large dict or MemoryError. + */ + if (minused > USABLE_FRACTION(max_presize)) { + newsize = max_presize; + } + else { + Py_ssize_t minsize = ESTIMATE_SIZE(minused); + newsize = PyDict_MINSIZE*2; + while (newsize < minsize) { + newsize <<= 1; + } + } + assert(IS_POWER_OF_2(newsize)); + + new_keys = new_keys_object(newsize); + if (new_keys == NULL) + return NULL; + return new_dict(new_keys, NULL); +} + +/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors + * that may occur (originally dicts supported only string keys, and exceptions + * weren't possible). So, while the original intent was that a NULL return + * meant the key wasn't present, in reality it can mean that, or that an error + * (suppressed) occurred while computing the key's hash, or that some error + * (suppressed) occurred when comparing keys in the dict's internal probe + * sequence. A nasty example of the latter is when a Python-coded comparison + * function hits a stack-depth error, which can cause this to return NULL + * even if the key is present. + */ +PyObject * +PyDict_GetItem(PyObject *op, PyObject *key) +{ + Py_hash_t hash; + Py_ssize_t ix; + PyDictObject *mp = (PyDictObject *)op; + PyThreadState *tstate; + PyObject *value; + + if (!PyDict_Check(op)) + return NULL; + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) { + PyErr_Clear(); + return NULL; + } + } + + /* We can arrive here with a NULL tstate during initialization: try + running "python -Wi" for an example related to string interning. + Let's just hope that no exception occurs then... This must be + _PyThreadState_GET() and not PyThreadState_Get() because the latter + abort Python if tstate is NULL. */ + tstate = _PyThreadState_GET(); + if (tstate != NULL && tstate->curexc_type != NULL) { + /* preserve the existing exception */ + PyObject *err_type, *err_value, *err_tb; + PyErr_Fetch(&err_type, &err_value, &err_tb); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + /* ignore errors */ + PyErr_Restore(err_type, err_value, err_tb); + if (ix < 0) + return NULL; + } + else { + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix < 0) { + PyErr_Clear(); + return NULL; + } + } + return value; +} + +/* Same as PyDict_GetItemWithError() but with hash supplied by caller. + This returns NULL *with* an exception set if an exception occurred. + It returns NULL *without* an exception set if the key wasn't present. +*/ +PyObject * +_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) +{ + Py_ssize_t ix; + PyDictObject *mp = (PyDictObject *)op; + PyObject *value; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix < 0) { + return NULL; + } + return value; +} + +/* Variant of PyDict_GetItem() that doesn't suppress exceptions. + This returns NULL *with* an exception set if an exception occurred. + It returns NULL *without* an exception set if the key wasn't present. +*/ +PyObject * +PyDict_GetItemWithError(PyObject *op, PyObject *key) +{ + Py_ssize_t ix; + Py_hash_t hash; + PyDictObject*mp = (PyDictObject *)op; + PyObject *value; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) { + return NULL; + } + } + + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix < 0) + return NULL; + return value; +} + +PyObject * +_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key) +{ + PyObject *kv; + kv = _PyUnicode_FromId(key); /* borrowed */ + if (kv == NULL) + return NULL; + return PyDict_GetItemWithError(dp, kv); +} + +PyObject * +_PyDict_GetItemStringWithError(PyObject *v, const char *key) +{ + PyObject *kv, *rv; + kv = PyUnicode_FromString(key); + if (kv == NULL) { + return NULL; + } + rv = PyDict_GetItemWithError(v, kv); + Py_DECREF(kv); + return rv; +} + +/* Fast version of global value lookup (LOAD_GLOBAL). + * Lookup in globals, then builtins. + * + * Raise an exception and return NULL if an error occurred (ex: computing the + * key hash failed, key comparison failed, ...). Return NULL if the key doesn't + * exist. Return the value if the key exists. + */ +PyObject * +_PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key) +{ + Py_ssize_t ix; + Py_hash_t hash; + PyObject *value; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + } + + /* namespace 1: globals */ + ix = globals->ma_keys->dk_lookup(globals, key, hash, &value); + if (ix == DKIX_ERROR) + return NULL; + if (ix != DKIX_EMPTY && value != NULL) + return value; + + /* namespace 2: builtins */ + ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value); + if (ix < 0) + return NULL; + return value; +} + +/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the + * dictionary if it's merely replacing the value for an existing key. + * This means that it's safe to loop over a dictionary with PyDict_Next() + * and occasionally replace a value -- but you can't insert new keys or + * remove them. + */ +int +PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) +{ + PyDictObject *mp; + Py_hash_t hash; + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + assert(value); + mp = (PyDictObject *)op; + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + } + + if (mp->ma_keys == Py_EMPTY_KEYS) { + return insert_to_emptydict(mp, key, hash, value); + } + /* insertdict() handles any resizing that might be necessary */ + return insertdict(mp, key, hash, value); +} + +int +_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, + Py_hash_t hash) +{ + PyDictObject *mp; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + assert(value); + assert(hash != -1); + mp = (PyDictObject *)op; + + if (mp->ma_keys == Py_EMPTY_KEYS) { + return insert_to_emptydict(mp, key, hash, value); + } + /* insertdict() handles any resizing that might be necessary */ + return insertdict(mp, key, hash, value); +} + +static int +delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, + PyObject *old_value) +{ + PyObject *old_key; + PyDictKeyEntry *ep; + + Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix); + assert(hashpos >= 0); + + mp->ma_used--; + mp->ma_version_tag = DICT_NEXT_VERSION(); + ep = &DK_ENTRIES(mp->ma_keys)[ix]; + dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); + ENSURE_ALLOWS_DELETIONS(mp); + old_key = ep->me_key; + ep->me_key = NULL; + ep->me_value = NULL; + Py_DECREF(old_key); + Py_DECREF(old_value); + + ASSERT_CONSISTENT(mp); + return 0; +} + +int +PyDict_DelItem(PyObject *op, PyObject *key) +{ + Py_hash_t hash; + assert(key); + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + } + + return _PyDict_DelItem_KnownHash(op, key, hash); +} + +int +_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) +{ + Py_ssize_t ix; + PyDictObject *mp; + PyObject *old_value; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + assert(hash != -1); + mp = (PyDictObject *)op; + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); + if (ix == DKIX_ERROR) + return -1; + if (ix == DKIX_EMPTY || old_value == NULL) { + _PyErr_SetKeyError(key); + return -1; + } + + // Split table doesn't allow deletion. Combine it. + if (_PyDict_HasSplitTable(mp)) { + if (dictresize(mp, DK_SIZE(mp->ma_keys))) { + return -1; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); + assert(ix >= 0); + } + + return delitem_common(mp, hash, ix, old_value); +} + +/* This function promises that the predicate -> deletion sequence is atomic + * (i.e. protected by the GIL), assuming the predicate itself doesn't + * release the GIL. + */ +int +_PyDict_DelItemIf(PyObject *op, PyObject *key, + int (*predicate)(PyObject *value)) +{ + Py_ssize_t hashpos, ix; + PyDictObject *mp; + Py_hash_t hash; + PyObject *old_value; + int res; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + mp = (PyDictObject *)op; + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); + if (ix == DKIX_ERROR) + return -1; + if (ix == DKIX_EMPTY || old_value == NULL) { + _PyErr_SetKeyError(key); + return -1; + } + + // Split table doesn't allow deletion. Combine it. + if (_PyDict_HasSplitTable(mp)) { + if (dictresize(mp, DK_SIZE(mp->ma_keys))) { + return -1; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); + assert(ix >= 0); + } + + res = predicate(old_value); + if (res == -1) + return -1; + + hashpos = lookdict_index(mp->ma_keys, hash, ix); + assert(hashpos >= 0); + + if (res > 0) + return delitem_common(mp, hashpos, ix, old_value); + else + return 0; +} + + +void +PyDict_Clear(PyObject *op) +{ + PyDictObject *mp; + PyDictKeysObject *oldkeys; + PyObject **oldvalues; + Py_ssize_t i, n; + + if (!PyDict_Check(op)) + return; + mp = ((PyDictObject *)op); + oldkeys = mp->ma_keys; + oldvalues = mp->ma_values; + if (oldvalues == empty_values) + return; + /* Empty the dict... */ + dictkeys_incref(Py_EMPTY_KEYS); + mp->ma_keys = Py_EMPTY_KEYS; + mp->ma_values = empty_values; + mp->ma_used = 0; + mp->ma_version_tag = DICT_NEXT_VERSION(); + /* ...then clear the keys and values */ + if (oldvalues != NULL) { + n = oldkeys->dk_nentries; + for (i = 0; i < n; i++) + Py_CLEAR(oldvalues[i]); + free_values(oldvalues); + dictkeys_decref(oldkeys); + } + else { + assert(oldkeys->dk_refcnt == 1); + dictkeys_decref(oldkeys); + } + ASSERT_CONSISTENT(mp); +} + +/* Internal version of PyDict_Next that returns a hash value in addition + * to the key and value. + * Return 1 on success, return 0 when the reached the end of the dictionary + * (or if op is not a dictionary) + */ +int +_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, + PyObject **pvalue, Py_hash_t *phash) +{ + Py_ssize_t i; + PyDictObject *mp; + PyDictKeyEntry *entry_ptr; + PyObject *value; + + if (!PyDict_Check(op)) + return 0; + mp = (PyDictObject *)op; + i = *ppos; + if (mp->ma_values) { + if (i < 0 || i >= mp->ma_used) + return 0; + /* values of split table is always dense */ + entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; + value = mp->ma_values[i]; + assert(value != NULL); + } + else { + Py_ssize_t n = mp->ma_keys->dk_nentries; + if (i < 0 || i >= n) + return 0; + entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + return 0; + value = entry_ptr->me_value; + } + *ppos = i+1; + if (pkey) + *pkey = entry_ptr->me_key; + if (phash) + *phash = entry_ptr->me_hash; + if (pvalue) + *pvalue = value; + return 1; +} + +/* + * Iterate over a dict. Use like so: + * + * Py_ssize_t i; + * PyObject *key, *value; + * i = 0; # important! i should not otherwise be changed by you + * while (PyDict_Next(yourdict, &i, &key, &value)) { + * Refer to borrowed references in key and value. + * } + * + * Return 1 on success, return 0 when the reached the end of the dictionary + * (or if op is not a dictionary) + * + * CAUTION: In general, it isn't safe to use PyDict_Next in a loop that + * mutates the dict. One exception: it is safe if the loop merely changes + * the values associated with the keys (but doesn't insert new keys or + * delete keys), via PyDict_SetItem(). + */ +int +PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) +{ + return _PyDict_Next(op, ppos, pkey, pvalue, NULL); +} + +/* Internal version of dict.pop(). */ +PyObject * +_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt) +{ + Py_ssize_t ix, hashpos; + PyObject *old_value, *old_key; + PyDictKeyEntry *ep; + PyDictObject *mp; + + assert(PyDict_Check(dict)); + mp = (PyDictObject *)dict; + + if (mp->ma_used == 0) { + if (deflt) { + Py_INCREF(deflt); + return deflt; + } + _PyErr_SetKeyError(key); + return NULL; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); + if (ix == DKIX_ERROR) + return NULL; + if (ix == DKIX_EMPTY || old_value == NULL) { + if (deflt) { + Py_INCREF(deflt); + return deflt; + } + _PyErr_SetKeyError(key); + return NULL; + } + + // Split table doesn't allow deletion. Combine it. + if (_PyDict_HasSplitTable(mp)) { + if (dictresize(mp, DK_SIZE(mp->ma_keys))) { + return NULL; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value); + assert(ix >= 0); + } + + hashpos = lookdict_index(mp->ma_keys, hash, ix); + assert(hashpos >= 0); + assert(old_value != NULL); + mp->ma_used--; + mp->ma_version_tag = DICT_NEXT_VERSION(); + dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); + ep = &DK_ENTRIES(mp->ma_keys)[ix]; + ENSURE_ALLOWS_DELETIONS(mp); + old_key = ep->me_key; + ep->me_key = NULL; + ep->me_value = NULL; + Py_DECREF(old_key); + + ASSERT_CONSISTENT(mp); + return old_value; +} + +PyObject * +_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) +{ + Py_hash_t hash; + + if (((PyDictObject *)dict)->ma_used == 0) { + if (deflt) { + Py_INCREF(deflt); + return deflt; + } + _PyErr_SetKeyError(key); + return NULL; + } + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + } + return _PyDict_Pop_KnownHash(dict, key, hash, deflt); +} + +/* Internal version of dict.from_keys(). It is subclass-friendly. */ +PyObject * +_PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) +{ + PyObject *it; /* iter(iterable) */ + PyObject *key; + PyObject *d; + int status; + + d = _PyObject_CallNoArg(cls); + if (d == NULL) + return NULL; + + if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) { + if (PyDict_CheckExact(iterable)) { + PyDictObject *mp = (PyDictObject *)d; + PyObject *oldvalue; + Py_ssize_t pos = 0; + PyObject *key; + Py_hash_t hash; + + if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(iterable)))) { + Py_DECREF(d); + return NULL; + } + + while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) { + if (insertdict(mp, key, hash, value)) { + Py_DECREF(d); + return NULL; + } + } + return d; + } + if (PyAnySet_CheckExact(iterable)) { + PyDictObject *mp = (PyDictObject *)d; + Py_ssize_t pos = 0; + PyObject *key; + Py_hash_t hash; + + if (dictresize(mp, ESTIMATE_SIZE(PySet_GET_SIZE(iterable)))) { + Py_DECREF(d); + return NULL; + } + + while (_PySet_NextEntry(iterable, &pos, &key, &hash)) { + if (insertdict(mp, key, hash, value)) { + Py_DECREF(d); + return NULL; + } + } + return d; + } + } + + it = PyObject_GetIter(iterable); + if (it == NULL){ + Py_DECREF(d); + return NULL; + } + + if (PyDict_CheckExact(d)) { + while ((key = PyIter_Next(it)) != NULL) { + status = PyDict_SetItem(d, key, value); + Py_DECREF(key); + if (status < 0) + goto Fail; + } + } else { + while ((key = PyIter_Next(it)) != NULL) { + status = PyObject_SetItem(d, key, value); + Py_DECREF(key); + if (status < 0) + goto Fail; + } + } + + if (PyErr_Occurred()) + goto Fail; + Py_DECREF(it); + return d; + +Fail: + Py_DECREF(it); + Py_DECREF(d); + return NULL; +} + +/* Methods */ + +static void +dict_dealloc(PyDictObject *mp) +{ + PyObject **values = mp->ma_values; + PyDictKeysObject *keys = mp->ma_keys; + Py_ssize_t i, n; + + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(mp); + Py_TRASHCAN_BEGIN(mp, dict_dealloc) + if (values != NULL) { + if (values != empty_values) { + for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) { + Py_XDECREF(values[i]); + } + free_values(values); + } + dictkeys_decref(keys); + } + else if (keys != NULL) { + assert(keys->dk_refcnt == 1); + dictkeys_decref(keys); + } + if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type) + free_list[numfree++] = mp; + else + Py_TYPE(mp)->tp_free((PyObject *)mp); + Py_TRASHCAN_END +} + + +static PyObject * +dict_repr(PyDictObject *mp) +{ + Py_ssize_t i; + PyObject *key = NULL, *value = NULL; + _PyUnicodeWriter writer; + int first; + + i = Py_ReprEnter((PyObject *)mp); + if (i != 0) { + return i > 0 ? PyUnicode_FromString("{...}") : NULL; + } + + if (mp->ma_used == 0) { + Py_ReprLeave((PyObject *)mp); + return PyUnicode_FromString("{}"); + } + + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */ + writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1; + + if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0) + goto error; + + /* Do repr() on each key+value pair, and insert ": " between them. + Note that repr may mutate the dict. */ + i = 0; + first = 1; + while (PyDict_Next((PyObject *)mp, &i, &key, &value)) { + PyObject *s; + int res; + + /* Prevent repr from deleting key or value during key format. */ + Py_INCREF(key); + Py_INCREF(value); + + if (!first) { + if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) + goto error; + } + first = 0; + + s = PyObject_Repr(key); + if (s == NULL) + goto error; + res = _PyUnicodeWriter_WriteStr(&writer, s); + Py_DECREF(s); + if (res < 0) + goto error; + + if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0) + goto error; + + s = PyObject_Repr(value); + if (s == NULL) + goto error; + res = _PyUnicodeWriter_WriteStr(&writer, s); + Py_DECREF(s); + if (res < 0) + goto error; + + Py_CLEAR(key); + Py_CLEAR(value); + } + + writer.overallocate = 0; + if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0) + goto error; + + Py_ReprLeave((PyObject *)mp); + + return _PyUnicodeWriter_Finish(&writer); + +error: + Py_ReprLeave((PyObject *)mp); + _PyUnicodeWriter_Dealloc(&writer); + Py_XDECREF(key); + Py_XDECREF(value); + return NULL; +} + +static Py_ssize_t +dict_length(PyDictObject *mp) +{ + return mp->ma_used; +} + +static PyObject * +dict_subscript(PyDictObject *mp, PyObject *key) +{ + Py_ssize_t ix; + Py_hash_t hash; + PyObject *value; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix == DKIX_ERROR) + return NULL; + if (ix == DKIX_EMPTY || value == NULL) { + if (!PyDict_CheckExact(mp)) { + /* Look up __missing__ method if we're a subclass. */ + PyObject *missing, *res; + _Py_IDENTIFIER(__missing__); + missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__); + if (missing != NULL) { + res = PyObject_CallFunctionObjArgs(missing, + key, NULL); + Py_DECREF(missing); + return res; + } + else if (PyErr_Occurred()) + return NULL; + } + _PyErr_SetKeyError(key); + return NULL; + } + Py_INCREF(value); + return value; +} + +static int +dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w) +{ + if (w == NULL) + return PyDict_DelItem((PyObject *)mp, v); + else + return PyDict_SetItem((PyObject *)mp, v, w); +} + +static PyMappingMethods dict_as_mapping = { + (lenfunc)dict_length, /*mp_length*/ + (binaryfunc)dict_subscript, /*mp_subscript*/ + (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/ +}; + +static PyObject * +dict_keys(PyDictObject *mp) +{ + PyObject *v; + Py_ssize_t i, j; + PyDictKeyEntry *ep; + Py_ssize_t n, offset; + PyObject **value_ptr; + + again: + n = mp->ma_used; + v = PyList_New(n); + if (v == NULL) + return NULL; + if (n != mp->ma_used) { + /* Durnit. The allocations caused the dict to resize. + * Just start over, this shouldn't normally happen. + */ + Py_DECREF(v); + goto again; + } + ep = DK_ENTRIES(mp->ma_keys); + if (mp->ma_values) { + value_ptr = mp->ma_values; + offset = sizeof(PyObject *); + } + else { + value_ptr = &ep[0].me_value; + offset = sizeof(PyDictKeyEntry); + } + for (i = 0, j = 0; j < n; i++) { + if (*value_ptr != NULL) { + PyObject *key = ep[i].me_key; + Py_INCREF(key); + PyList_SET_ITEM(v, j, key); + j++; + } + value_ptr = (PyObject **)(((char *)value_ptr) + offset); + } + assert(j == n); + return v; +} + +static PyObject * +dict_values(PyDictObject *mp) +{ + PyObject *v; + Py_ssize_t i, j; + PyDictKeyEntry *ep; + Py_ssize_t n, offset; + PyObject **value_ptr; + + again: + n = mp->ma_used; + v = PyList_New(n); + if (v == NULL) + return NULL; + if (n != mp->ma_used) { + /* Durnit. The allocations caused the dict to resize. + * Just start over, this shouldn't normally happen. + */ + Py_DECREF(v); + goto again; + } + ep = DK_ENTRIES(mp->ma_keys); + if (mp->ma_values) { + value_ptr = mp->ma_values; + offset = sizeof(PyObject *); + } + else { + value_ptr = &ep[0].me_value; + offset = sizeof(PyDictKeyEntry); + } + for (i = 0, j = 0; j < n; i++) { + PyObject *value = *value_ptr; + value_ptr = (PyObject **)(((char *)value_ptr) + offset); + if (value != NULL) { + Py_INCREF(value); + PyList_SET_ITEM(v, j, value); + j++; + } + } + assert(j == n); + return v; +} + +static PyObject * +dict_items(PyDictObject *mp) +{ + PyObject *v; + Py_ssize_t i, j, n; + Py_ssize_t offset; + PyObject *item, *key; + PyDictKeyEntry *ep; + PyObject **value_ptr; + + /* Preallocate the list of tuples, to avoid allocations during + * the loop over the items, which could trigger GC, which + * could resize the dict. :-( + */ + again: + n = mp->ma_used; + v = PyList_New(n); + if (v == NULL) + return NULL; + for (i = 0; i < n; i++) { + item = PyTuple_New(2); + if (item == NULL) { + Py_DECREF(v); + return NULL; + } + PyList_SET_ITEM(v, i, item); + } + if (n != mp->ma_used) { + /* Durnit. The allocations caused the dict to resize. + * Just start over, this shouldn't normally happen. + */ + Py_DECREF(v); + goto again; + } + /* Nothing we do below makes any function calls. */ + ep = DK_ENTRIES(mp->ma_keys); + if (mp->ma_values) { + value_ptr = mp->ma_values; + offset = sizeof(PyObject *); + } + else { + value_ptr = &ep[0].me_value; + offset = sizeof(PyDictKeyEntry); + } + for (i = 0, j = 0; j < n; i++) { + PyObject *value = *value_ptr; + value_ptr = (PyObject **)(((char *)value_ptr) + offset); + if (value != NULL) { + key = ep[i].me_key; + item = PyList_GET_ITEM(v, j); + Py_INCREF(key); + PyTuple_SET_ITEM(item, 0, key); + Py_INCREF(value); + PyTuple_SET_ITEM(item, 1, value); + j++; + } + } + assert(j == n); + return v; +} + +/*[clinic input] +@classmethod +dict.fromkeys + iterable: object + value: object=None + / + +Create a new dictionary with keys from iterable and values set to value. +[clinic start generated code]*/ + +static PyObject * +dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value) +/*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/ +{ + return _PyDict_FromKeys((PyObject *)type, iterable, value); +} + +static int +dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, + const char *methname) +{ + PyObject *arg = NULL; + int result = 0; + + if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) { + result = -1; + } + else if (arg != NULL) { + _Py_IDENTIFIER(keys); + PyObject *func; + if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) { + result = -1; + } + else if (func != NULL) { + Py_DECREF(func); + result = PyDict_Merge(self, arg, 1); + } + else { + result = PyDict_MergeFromSeq2(self, arg, 1); + } + } + + if (result == 0 && kwds != NULL) { + if (PyArg_ValidateKeywordArguments(kwds)) + result = PyDict_Merge(self, kwds, 1); + else + result = -1; + } + return result; +} + +/* Note: dict.update() uses the METH_VARARGS|METH_KEYWORDS calling convention. + Using METH_FASTCALL|METH_KEYWORDS would make dict.update(**dict2) calls + slower, see the issue #29312. */ +static PyObject * +dict_update(PyObject *self, PyObject *args, PyObject *kwds) +{ + if (dict_update_common(self, args, kwds, "update") != -1) + Py_RETURN_NONE; + return NULL; +} + +/* Update unconditionally replaces existing items. + Merge has a 3rd argument 'override'; if set, it acts like Update, + otherwise it leaves existing items unchanged. + + PyDict_{Update,Merge} update/merge from a mapping object. + + PyDict_MergeFromSeq2 updates/merges from any iterable object + producing iterable objects of length 2. +*/ + +int +PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) +{ + PyObject *it; /* iter(seq2) */ + Py_ssize_t i; /* index into seq2 of current element */ + PyObject *item; /* seq2[i] */ + PyObject *fast; /* item as a 2-tuple or 2-list */ + + assert(d != NULL); + assert(PyDict_Check(d)); + assert(seq2 != NULL); + + it = PyObject_GetIter(seq2); + if (it == NULL) + return -1; + + for (i = 0; ; ++i) { + PyObject *key, *value; + Py_ssize_t n; + + fast = NULL; + item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) + goto Fail; + break; + } + + /* Convert item to sequence, and verify length 2. */ + fast = PySequence_Fast(item, ""); + if (fast == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_Format(PyExc_TypeError, + "cannot convert dictionary update " + "sequence element #%zd to a sequence", + i); + goto Fail; + } + n = PySequence_Fast_GET_SIZE(fast); + if (n != 2) { + PyErr_Format(PyExc_ValueError, + "dictionary update sequence element #%zd " + "has length %zd; 2 is required", + i, n); + goto Fail; + } + + /* Update/merge with this (key, value) pair. */ + key = PySequence_Fast_GET_ITEM(fast, 0); + value = PySequence_Fast_GET_ITEM(fast, 1); + Py_INCREF(key); + Py_INCREF(value); + if (override) { + if (PyDict_SetItem(d, key, value) < 0) { + Py_DECREF(key); + Py_DECREF(value); + goto Fail; + } + } + else if (PyDict_GetItemWithError(d, key) == NULL) { + if (PyErr_Occurred() || PyDict_SetItem(d, key, value) < 0) { + Py_DECREF(key); + Py_DECREF(value); + goto Fail; + } + } + + Py_DECREF(key); + Py_DECREF(value); + Py_DECREF(fast); + Py_DECREF(item); + } + + i = 0; + ASSERT_CONSISTENT(d); + goto Return; +Fail: + Py_XDECREF(item); + Py_XDECREF(fast); + i = -1; +Return: + Py_DECREF(it); + return Py_SAFE_DOWNCAST(i, Py_ssize_t, int); +} + +static int +dict_merge(PyObject *a, PyObject *b, int override) +{ + PyDictObject *mp, *other; + Py_ssize_t i, n; + PyDictKeyEntry *entry, *ep0; + + assert(0 <= override && override <= 2); + + /* We accept for the argument either a concrete dictionary object, + * or an abstract "mapping" object. For the former, we can do + * things quite efficiently. For the latter, we only require that + * PyMapping_Keys() and PyObject_GetItem() be supported. + */ + if (a == NULL || !PyDict_Check(a) || b == NULL) { + PyErr_BadInternalCall(); + return -1; + } + mp = (PyDictObject*)a; + if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == (getiterfunc)dict_iter)) { + other = (PyDictObject*)b; + if (other == mp || other->ma_used == 0) + /* a.update(a) or a.update({}); nothing to do */ + return 0; + if (mp->ma_used == 0) + /* Since the target dict is empty, PyDict_GetItem() + * always returns NULL. Setting override to 1 + * skips the unnecessary test. + */ + override = 1; + /* Do one big resize at the start, rather than + * incrementally resizing as we insert new items. Expect + * that there will be no (or few) overlapping keys. + */ + if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) { + if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) { + return -1; + } + } + ep0 = DK_ENTRIES(other->ma_keys); + for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) { + PyObject *key, *value; + Py_hash_t hash; + entry = &ep0[i]; + key = entry->me_key; + hash = entry->me_hash; + if (other->ma_values) + value = other->ma_values[i]; + else + value = entry->me_value; + + if (value != NULL) { + int err = 0; + Py_INCREF(key); + Py_INCREF(value); + if (override == 1) + err = insertdict(mp, key, hash, value); + else if (_PyDict_GetItem_KnownHash(a, key, hash) == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(value); + Py_DECREF(key); + return -1; + } + err = insertdict(mp, key, hash, value); + } + else if (override != 0) { + _PyErr_SetKeyError(key); + Py_DECREF(value); + Py_DECREF(key); + return -1; + } + Py_DECREF(value); + Py_DECREF(key); + if (err != 0) + return -1; + + if (n != other->ma_keys->dk_nentries) { + PyErr_SetString(PyExc_RuntimeError, + "dict mutated during update"); + return -1; + } + } + } + } + else { + /* Do it the generic, slower way */ + PyObject *keys = PyMapping_Keys(b); + PyObject *iter; + PyObject *key, *value; + int status; + + if (keys == NULL) + /* Docstring says this is equivalent to E.keys() so + * if E doesn't have a .keys() method we want + * AttributeError to percolate up. Might as well + * do the same for any other error. + */ + return -1; + + iter = PyObject_GetIter(keys); + Py_DECREF(keys); + if (iter == NULL) + return -1; + + for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { + if (override != 1) { + if (PyDict_GetItemWithError(a, key) != NULL) { + if (override != 0) { + _PyErr_SetKeyError(key); + Py_DECREF(key); + Py_DECREF(iter); + return -1; + } + Py_DECREF(key); + continue; + } + else if (PyErr_Occurred()) { + Py_DECREF(key); + Py_DECREF(iter); + return -1; + } + } + value = PyObject_GetItem(b, key); + if (value == NULL) { + Py_DECREF(iter); + Py_DECREF(key); + return -1; + } + status = PyDict_SetItem(a, key, value); + Py_DECREF(key); + Py_DECREF(value); + if (status < 0) { + Py_DECREF(iter); + return -1; + } + } + Py_DECREF(iter); + if (PyErr_Occurred()) + /* Iterator completed, via error */ + return -1; + } + ASSERT_CONSISTENT(a); + return 0; +} + +int +PyDict_Update(PyObject *a, PyObject *b) +{ + return dict_merge(a, b, 1); +} + +int +PyDict_Merge(PyObject *a, PyObject *b, int override) +{ + /* XXX Deprecate override not in (0, 1). */ + return dict_merge(a, b, override != 0); +} + +int +_PyDict_MergeEx(PyObject *a, PyObject *b, int override) +{ + return dict_merge(a, b, override); +} + +static PyObject * +dict_copy(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) +{ + return PyDict_Copy((PyObject*)mp); +} + +PyObject * +PyDict_Copy(PyObject *o) +{ + PyObject *copy; + PyDictObject *mp; + Py_ssize_t i, n; + + if (o == NULL || !PyDict_Check(o)) { + PyErr_BadInternalCall(); + return NULL; + } + + mp = (PyDictObject *)o; + if (mp->ma_used == 0) { + /* The dict is empty; just return a new dict. */ + return PyDict_New(); + } + + if (_PyDict_HasSplitTable(mp)) { + PyDictObject *split_copy; + Py_ssize_t size = USABLE_FRACTION(DK_SIZE(mp->ma_keys)); + PyObject **newvalues; + newvalues = new_values(size); + if (newvalues == NULL) + return PyErr_NoMemory(); + split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type); + if (split_copy == NULL) { + free_values(newvalues); + return NULL; + } + split_copy->ma_values = newvalues; + split_copy->ma_keys = mp->ma_keys; + split_copy->ma_used = mp->ma_used; + split_copy->ma_version_tag = DICT_NEXT_VERSION(); + dictkeys_incref(mp->ma_keys); + for (i = 0, n = size; i < n; i++) { + PyObject *value = mp->ma_values[i]; + Py_XINCREF(value); + split_copy->ma_values[i] = value; + } + if (_PyObject_GC_IS_TRACKED(mp)) + _PyObject_GC_TRACK(split_copy); + return (PyObject *)split_copy; + } + + if (PyDict_CheckExact(mp) && mp->ma_values == NULL && + (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3)) + { + /* Use fast-copy if: + + (1) 'mp' is an instance of a subclassed dict; and + + (2) 'mp' is not a split-dict; and + + (3) if 'mp' is non-compact ('del' operation does not resize dicts), + do fast-copy only if it has at most 1/3 non-used keys. + + The last condition (3) is important to guard against a pathological + case when a large dict is almost emptied with multiple del/pop + operations and copied after that. In cases like this, we defer to + PyDict_Merge, which produces a compacted copy. + */ + return clone_combined_dict(mp); + } + + copy = PyDict_New(); + if (copy == NULL) + return NULL; + if (PyDict_Merge(copy, o, 1) == 0) + return copy; + Py_DECREF(copy); + return NULL; +} + +Py_ssize_t +PyDict_Size(PyObject *mp) +{ + if (mp == NULL || !PyDict_Check(mp)) { + PyErr_BadInternalCall(); + return -1; + } + return ((PyDictObject *)mp)->ma_used; +} + +PyObject * +PyDict_Keys(PyObject *mp) +{ + if (mp == NULL || !PyDict_Check(mp)) { + PyErr_BadInternalCall(); + return NULL; + } + return dict_keys((PyDictObject *)mp); +} + +PyObject * +PyDict_Values(PyObject *mp) +{ + if (mp == NULL || !PyDict_Check(mp)) { + PyErr_BadInternalCall(); + return NULL; + } + return dict_values((PyDictObject *)mp); +} + +PyObject * +PyDict_Items(PyObject *mp) +{ + if (mp == NULL || !PyDict_Check(mp)) { + PyErr_BadInternalCall(); + return NULL; + } + return dict_items((PyDictObject *)mp); +} + +/* Return 1 if dicts equal, 0 if not, -1 if error. + * Gets out as soon as any difference is detected. + * Uses only Py_EQ comparison. + */ +static int +dict_equal(PyDictObject *a, PyDictObject *b) +{ + Py_ssize_t i; + + if (a->ma_used != b->ma_used) + /* can't be equal if # of entries differ */ + return 0; + /* Same # of entries -- check all of 'em. Exit early on any diff. */ + for (i = 0; i < a->ma_keys->dk_nentries; i++) { + PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i]; + PyObject *aval; + if (a->ma_values) + aval = a->ma_values[i]; + else + aval = ep->me_value; + if (aval != NULL) { + int cmp; + PyObject *bval; + PyObject *key = ep->me_key; + /* temporarily bump aval's refcount to ensure it stays + alive until we're done with it */ + Py_INCREF(aval); + /* ditto for key */ + Py_INCREF(key); + /* reuse the known hash value */ + b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval); + if (bval == NULL) { + Py_DECREF(key); + Py_DECREF(aval); + if (PyErr_Occurred()) + return -1; + return 0; + } + Py_INCREF(bval); + cmp = PyObject_RichCompareBool(aval, bval, Py_EQ); + Py_DECREF(key); + Py_DECREF(aval); + Py_DECREF(bval); + if (cmp <= 0) /* error or not equal */ + return cmp; + } + } + return 1; +} + +static PyObject * +dict_richcompare(PyObject *v, PyObject *w, int op) +{ + int cmp; + PyObject *res; + + if (!PyDict_Check(v) || !PyDict_Check(w)) { + res = Py_NotImplemented; + } + else if (op == Py_EQ || op == Py_NE) { + cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w); + if (cmp < 0) + return NULL; + res = (cmp == (op == Py_EQ)) ? Py_True : Py_False; + } + else + res = Py_NotImplemented; + Py_INCREF(res); + return res; +} + +/*[clinic input] + +@coexist +dict.__contains__ + + key: object + / + +True if the dictionary has the specified key, else False. +[clinic start generated code]*/ + +static PyObject * +dict___contains__(PyDictObject *self, PyObject *key) +/*[clinic end generated code: output=a3d03db709ed6e6b input=fe1cb42ad831e820]*/ +{ + register PyDictObject *mp = self; + Py_hash_t hash; + Py_ssize_t ix; + PyObject *value; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix == DKIX_ERROR) + return NULL; + if (ix == DKIX_EMPTY || value == NULL) + Py_RETURN_FALSE; + Py_RETURN_TRUE; +} + +/*[clinic input] +dict.get + + key: object + default: object = None + / + +Return the value for key if key is in the dictionary, else default. +[clinic start generated code]*/ + +static PyObject * +dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) +/*[clinic end generated code: output=bba707729dee05bf input=279ddb5790b6b107]*/ +{ + PyObject *val = NULL; + Py_hash_t hash; + Py_ssize_t ix; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + } + ix = (self->ma_keys->dk_lookup) (self, key, hash, &val); + if (ix == DKIX_ERROR) + return NULL; + if (ix == DKIX_EMPTY || val == NULL) { + val = default_value; + } + Py_INCREF(val); + return val; +} + +PyObject * +PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) +{ + PyDictObject *mp = (PyDictObject *)d; + PyObject *value; + Py_hash_t hash; + + if (!PyDict_Check(d)) { + PyErr_BadInternalCall(); + return NULL; + } + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + } + if (mp->ma_keys == Py_EMPTY_KEYS) { + if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) { + return NULL; + } + return defaultobj; + } + + if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { + if (insertion_resize(mp) < 0) + return NULL; + } + + Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix == DKIX_ERROR) + return NULL; + + if (_PyDict_HasSplitTable(mp) && + ((ix >= 0 && value == NULL && mp->ma_used != ix) || + (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) { + if (insertion_resize(mp) < 0) { + return NULL; + } + ix = DKIX_EMPTY; + } + + if (ix == DKIX_EMPTY) { + PyDictKeyEntry *ep, *ep0; + value = defaultobj; + if (mp->ma_keys->dk_usable <= 0) { + if (insertion_resize(mp) < 0) { + return NULL; + } + } + Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); + ep0 = DK_ENTRIES(mp->ma_keys); + ep = &ep0[mp->ma_keys->dk_nentries]; + dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); + Py_INCREF(key); + Py_INCREF(value); + MAINTAIN_TRACKING(mp, key, value); + ep->me_key = key; + ep->me_hash = hash; + if (_PyDict_HasSplitTable(mp)) { + assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL); + mp->ma_values[mp->ma_keys->dk_nentries] = value; + } + else { + ep->me_value = value; + } + mp->ma_used++; + mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_keys->dk_usable--; + mp->ma_keys->dk_nentries++; + assert(mp->ma_keys->dk_usable >= 0); + } + else if (value == NULL) { + value = defaultobj; + assert(_PyDict_HasSplitTable(mp)); + assert(ix == mp->ma_used); + Py_INCREF(value); + MAINTAIN_TRACKING(mp, key, value); + mp->ma_values[ix] = value; + mp->ma_used++; + mp->ma_version_tag = DICT_NEXT_VERSION(); + } + + ASSERT_CONSISTENT(mp); + return value; +} + +/*[clinic input] +dict.setdefault + + key: object + default: object = None + / + +Insert key with a value of default if key is not in the dictionary. + +Return the value for key if key is in the dictionary, else default. +[clinic start generated code]*/ + +static PyObject * +dict_setdefault_impl(PyDictObject *self, PyObject *key, + PyObject *default_value) +/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/ +{ + PyObject *val; + + val = PyDict_SetDefault((PyObject *)self, key, default_value); + Py_XINCREF(val); + return val; +} + +static PyObject * +dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) +{ + PyDict_Clear((PyObject *)mp); + Py_RETURN_NONE; +} + +/* +We don't use Argument Clinic for dict.pop because it doesn't support +custom signature for now. +*/ +PyDoc_STRVAR(dict_pop__doc__, +"D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\ +If key is not found, d is returned if given, otherwise KeyError is raised"); + +#define DICT_POP_METHODDEF \ + {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__doc__}, + +static PyObject * +dict_pop(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) { + goto exit; + } + key = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = _PyDict_Pop((PyObject*)self, key, default_value); + +exit: + return return_value; +} + +/*[clinic input] +dict.popitem + +Remove and return a (key, value) pair as a 2-tuple. + +Pairs are returned in LIFO (last-in, first-out) order. +Raises KeyError if the dict is empty. +[clinic start generated code]*/ + +static PyObject * +dict_popitem_impl(PyDictObject *self) +/*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/ +{ + Py_ssize_t i, j; + PyDictKeyEntry *ep0, *ep; + PyObject *res; + + /* Allocate the result tuple before checking the size. Believe it + * or not, this allocation could trigger a garbage collection which + * could empty the dict, so if we checked the size first and that + * happened, the result would be an infinite loop (searching for an + * entry that no longer exists). Note that the usual popitem() + * idiom is "while d: k, v = d.popitem()". so needing to throw the + * tuple away if the dict *is* empty isn't a significant + * inefficiency -- possible, but unlikely in practice. + */ + res = PyTuple_New(2); + if (res == NULL) + return NULL; + if (self->ma_used == 0) { + Py_DECREF(res); + PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty"); + return NULL; + } + /* Convert split table to combined table */ + if (self->ma_keys->dk_lookup == lookdict_split) { + if (dictresize(self, DK_SIZE(self->ma_keys))) { + Py_DECREF(res); + return NULL; + } + } + ENSURE_ALLOWS_DELETIONS(self); + + /* Pop last item */ + ep0 = DK_ENTRIES(self->ma_keys); + i = self->ma_keys->dk_nentries - 1; + while (i >= 0 && ep0[i].me_value == NULL) { + i--; + } + assert(i >= 0); + + ep = &ep0[i]; + j = lookdict_index(self->ma_keys, ep->me_hash, i); + assert(j >= 0); + assert(dictkeys_get_index(self->ma_keys, j) == i); + dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY); + + PyTuple_SET_ITEM(res, 0, ep->me_key); + PyTuple_SET_ITEM(res, 1, ep->me_value); + ep->me_key = NULL; + ep->me_value = NULL; + /* We can't dk_usable++ since there is DKIX_DUMMY in indices */ + self->ma_keys->dk_nentries = i; + self->ma_used--; + self->ma_version_tag = DICT_NEXT_VERSION(); + ASSERT_CONSISTENT(self); + return res; +} + +static int +dict_traverse(PyObject *op, visitproc visit, void *arg) +{ + PyDictObject *mp = (PyDictObject *)op; + PyDictKeysObject *keys = mp->ma_keys; + PyDictKeyEntry *entries = DK_ENTRIES(keys); + Py_ssize_t i, n = keys->dk_nentries; + + if (keys->dk_lookup == lookdict) { + for (i = 0; i < n; i++) { + if (entries[i].me_value != NULL) { + Py_VISIT(entries[i].me_value); + Py_VISIT(entries[i].me_key); + } + } + } + else { + if (mp->ma_values != NULL) { + for (i = 0; i < n; i++) { + Py_VISIT(mp->ma_values[i]); + } + } + else { + for (i = 0; i < n; i++) { + Py_VISIT(entries[i].me_value); + } + } + } + return 0; +} + +static int +dict_tp_clear(PyObject *op) +{ + PyDict_Clear(op); + return 0; +} + +static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); + +Py_ssize_t +_PyDict_SizeOf(PyDictObject *mp) +{ + Py_ssize_t size, usable, res; + + size = DK_SIZE(mp->ma_keys); + usable = USABLE_FRACTION(size); + + res = _PyObject_SIZE(Py_TYPE(mp)); + if (mp->ma_values) + res += usable * sizeof(PyObject*); + /* If the dictionary is split, the keys portion is accounted-for + in the type object. */ + if (mp->ma_keys->dk_refcnt == 1) + res += (sizeof(PyDictKeysObject) + + DK_IXSIZE(mp->ma_keys) * size + + sizeof(PyDictKeyEntry) * usable); + return res; +} + +Py_ssize_t +_PyDict_KeysSize(PyDictKeysObject *keys) +{ + return (sizeof(PyDictKeysObject) + + DK_IXSIZE(keys) * DK_SIZE(keys) + + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry)); +} + +static PyObject * +dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored)) +{ + return PyLong_FromSsize_t(_PyDict_SizeOf(mp)); +} + +PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); + +PyDoc_STRVAR(sizeof__doc__, +"D.__sizeof__() -> size of D in memory, in bytes"); + +PyDoc_STRVAR(update__doc__, +"D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n\ +If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\ +If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\ +In either case, this is followed by: for k in F: D[k] = F[k]"); + +PyDoc_STRVAR(clear__doc__, +"D.clear() -> None. Remove all items from D."); + +PyDoc_STRVAR(copy__doc__, +"D.copy() -> a shallow copy of D"); + +/* Forward */ +static PyObject *dictkeys_new(PyObject *, PyObject *); +static PyObject *dictitems_new(PyObject *, PyObject *); +static PyObject *dictvalues_new(PyObject *, PyObject *); + +PyDoc_STRVAR(keys__doc__, + "D.keys() -> a set-like object providing a view on D's keys"); +PyDoc_STRVAR(items__doc__, + "D.items() -> a set-like object providing a view on D's items"); +PyDoc_STRVAR(values__doc__, + "D.values() -> an object providing a view on D's values"); + +static PyMethodDef mapp_methods[] = { + DICT___CONTAINS___METHODDEF + {"__getitem__", (PyCFunction)(void(*)(void))dict_subscript, METH_O | METH_COEXIST, + getitem__doc__}, + {"__sizeof__", (PyCFunction)(void(*)(void))dict_sizeof, METH_NOARGS, + sizeof__doc__}, + DICT_GET_METHODDEF + DICT_SETDEFAULT_METHODDEF + DICT_POP_METHODDEF + DICT_POPITEM_METHODDEF + {"keys", dictkeys_new, METH_NOARGS, + keys__doc__}, + {"items", dictitems_new, METH_NOARGS, + items__doc__}, + {"values", dictvalues_new, METH_NOARGS, + values__doc__}, + {"update", (PyCFunction)(void(*)(void))dict_update, METH_VARARGS | METH_KEYWORDS, + update__doc__}, + DICT_FROMKEYS_METHODDEF + {"clear", (PyCFunction)dict_clear, METH_NOARGS, + clear__doc__}, + {"copy", (PyCFunction)dict_copy, METH_NOARGS, + copy__doc__}, + DICT___REVERSED___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */ +int +PyDict_Contains(PyObject *op, PyObject *key) +{ + Py_hash_t hash; + Py_ssize_t ix; + PyDictObject *mp = (PyDictObject *)op; + PyObject *value; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + } + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix == DKIX_ERROR) + return -1; + return (ix != DKIX_EMPTY && value != NULL); +} + +/* Internal version of PyDict_Contains used when the hash value is already known */ +int +_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash) +{ + PyDictObject *mp = (PyDictObject *)op; + PyObject *value; + Py_ssize_t ix; + + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + if (ix == DKIX_ERROR) + return -1; + return (ix != DKIX_EMPTY && value != NULL); +} + +/* Hack to implement "key in dict" */ +static PySequenceMethods dict_as_sequence = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + PyDict_Contains, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + +static PyObject * +dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *self; + PyDictObject *d; + + assert(type != NULL && type->tp_alloc != NULL); + self = type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + d = (PyDictObject *)self; + + /* The object has been implicitly tracked by tp_alloc */ + if (type == &PyDict_Type) + _PyObject_GC_UNTRACK(d); + + d->ma_used = 0; + d->ma_version_tag = DICT_NEXT_VERSION(); + d->ma_keys = new_keys_object(PyDict_MINSIZE); + if (d->ma_keys == NULL) { + Py_DECREF(self); + return NULL; + } + ASSERT_CONSISTENT(d); + return self; +} + +static int +dict_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + return dict_update_common(self, args, kwds, "dict"); +} + +static PyObject * +dict_iter(PyDictObject *dict) +{ + return dictiter_new(dict, &PyDictIterKey_Type); +} + +PyDoc_STRVAR(dictionary_doc, +"dict() -> new empty dictionary\n" +"dict(mapping) -> new dictionary initialized from a mapping object's\n" +" (key, value) pairs\n" +"dict(iterable) -> new dictionary initialized as if via:\n" +" d = {}\n" +" for k, v in iterable:\n" +" d[k] = v\n" +"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n" +" in the keyword argument list. For example: dict(one=1, two=2)"); + +PyTypeObject PyDict_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict", + sizeof(PyDictObject), + 0, + (destructor)dict_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)dict_repr, /* tp_repr */ + 0, /* tp_as_number */ + &dict_as_sequence, /* tp_as_sequence */ + &dict_as_mapping, /* 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_HAVE_GC | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS, /* tp_flags */ + dictionary_doc, /* tp_doc */ + dict_traverse, /* tp_traverse */ + dict_tp_clear, /* tp_clear */ + dict_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)dict_iter, /* tp_iter */ + 0, /* tp_iternext */ + mapp_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + dict_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + dict_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +PyObject * +_PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key) +{ + PyObject *kv; + kv = _PyUnicode_FromId(key); /* borrowed */ + if (kv == NULL) { + PyErr_Clear(); + return NULL; + } + return PyDict_GetItem(dp, kv); +} + +/* For backward compatibility with old dictionary interface */ + +PyObject * +PyDict_GetItemString(PyObject *v, const char *key) +{ + PyObject *kv, *rv; + kv = PyUnicode_FromString(key); + if (kv == NULL) { + PyErr_Clear(); + return NULL; + } + rv = PyDict_GetItem(v, kv); + Py_DECREF(kv); + return rv; +} + +int +_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item) +{ + PyObject *kv; + kv = _PyUnicode_FromId(key); /* borrowed */ + if (kv == NULL) + return -1; + return PyDict_SetItem(v, kv, item); +} + +int +PyDict_SetItemString(PyObject *v, const char *key, PyObject *item) +{ + PyObject *kv; + int err; + kv = PyUnicode_FromString(key); + if (kv == NULL) + return -1; + PyUnicode_InternInPlace(&kv); /* XXX Should we really? */ + err = PyDict_SetItem(v, kv, item); + Py_DECREF(kv); + return err; +} + +int +_PyDict_DelItemId(PyObject *v, _Py_Identifier *key) +{ + PyObject *kv = _PyUnicode_FromId(key); /* borrowed */ + if (kv == NULL) + return -1; + return PyDict_DelItem(v, kv); +} + +int +PyDict_DelItemString(PyObject *v, const char *key) +{ + PyObject *kv; + int err; + kv = PyUnicode_FromString(key); + if (kv == NULL) + return -1; + err = PyDict_DelItem(v, kv); + Py_DECREF(kv); + return err; +} + +/* Dictionary iterator types */ + +typedef struct { + PyObject_HEAD + PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */ + Py_ssize_t di_used; + Py_ssize_t di_pos; + PyObject* di_result; /* reusable result tuple for iteritems */ + Py_ssize_t len; +} dictiterobject; + +static PyObject * +dictiter_new(PyDictObject *dict, PyTypeObject *itertype) +{ + dictiterobject *di; + di = PyObject_GC_New(dictiterobject, itertype); + if (di == NULL) { + return NULL; + } + Py_INCREF(dict); + di->di_dict = dict; + di->di_used = dict->ma_used; + di->len = dict->ma_used; + if (itertype == &PyDictRevIterKey_Type || + itertype == &PyDictRevIterItem_Type || + itertype == &PyDictRevIterValue_Type) { + if (dict->ma_values) { + di->di_pos = dict->ma_used - 1; + } + else { + di->di_pos = dict->ma_keys->dk_nentries - 1; + } + } + else { + di->di_pos = 0; + } + if (itertype == &PyDictIterItem_Type || + itertype == &PyDictRevIterItem_Type) { + di->di_result = PyTuple_Pack(2, Py_None, Py_None); + if (di->di_result == NULL) { + Py_DECREF(di); + return NULL; + } + } + else { + di->di_result = NULL; + } + _PyObject_GC_TRACK(di); + return (PyObject *)di; +} + +static void +dictiter_dealloc(dictiterobject *di) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + _PyObject_GC_UNTRACK(di); + Py_XDECREF(di->di_dict); + Py_XDECREF(di->di_result); + PyObject_GC_Del(di); +} + +static int +dictiter_traverse(dictiterobject *di, visitproc visit, void *arg) +{ + Py_VISIT(di->di_dict); + Py_VISIT(di->di_result); + return 0; +} + +static PyObject * +dictiter_len(dictiterobject *di, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len = 0; + if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used) + len = di->len; + return PyLong_FromSize_t(len); +} + +PyDoc_STRVAR(length_hint_doc, + "Private method returning an estimate of len(list(it))."); + +static PyObject * +dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)); + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyMethodDef dictiter_methods[] = { + {"__length_hint__", (PyCFunction)(void(*)(void))dictiter_len, METH_NOARGS, + length_hint_doc}, + {"__reduce__", (PyCFunction)(void(*)(void))dictiter_reduce, METH_NOARGS, + reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +dictiter_iternextkey(dictiterobject *di) +{ + PyObject *key; + Py_ssize_t i; + PyDictKeysObject *k; + PyDictObject *d = di->di_dict; + + if (d == NULL) + return NULL; + assert (PyDict_Check(d)); + + if (di->di_used != d->ma_used) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary changed size during iteration"); + di->di_used = -1; /* Make this state sticky */ + return NULL; + } + + i = di->di_pos; + k = d->ma_keys; + assert(i >= 0); + if (d->ma_values) { + if (i >= d->ma_used) + goto fail; + key = DK_ENTRIES(k)[i].me_key; + assert(d->ma_values[i] != NULL); + } + else { + Py_ssize_t n = k->dk_nentries; + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + } + // We found an element (key), but did not expect it + if (di->len == 0) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary keys changed during iteration"); + goto fail; + } + di->di_pos = i+1; + di->len--; + Py_INCREF(key); + return key; + +fail: + di->di_dict = NULL; + Py_DECREF(d); + return NULL; +} + +PyTypeObject PyDictIterKey_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_keyiterator", /* tp_name */ + sizeof(dictiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dictiter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dictiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dictiter_iternextkey, /* tp_iternext */ + dictiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +dictiter_iternextvalue(dictiterobject *di) +{ + PyObject *value; + Py_ssize_t i; + PyDictObject *d = di->di_dict; + + if (d == NULL) + return NULL; + assert (PyDict_Check(d)); + + if (di->di_used != d->ma_used) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary changed size during iteration"); + di->di_used = -1; /* Make this state sticky */ + return NULL; + } + + i = di->di_pos; + assert(i >= 0); + if (d->ma_values) { + if (i >= d->ma_used) + goto fail; + value = d->ma_values[i]; + assert(value != NULL); + } + else { + Py_ssize_t n = d->ma_keys->dk_nentries; + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + value = entry_ptr->me_value; + } + // We found an element, but did not expect it + if (di->len == 0) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary keys changed during iteration"); + goto fail; + } + di->di_pos = i+1; + di->len--; + Py_INCREF(value); + return value; + +fail: + di->di_dict = NULL; + Py_DECREF(d); + return NULL; +} + +PyTypeObject PyDictIterValue_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_valueiterator", /* tp_name */ + sizeof(dictiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dictiter_dealloc, /* tp_dealloc */ + 0, /* tp_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, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dictiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dictiter_iternextvalue, /* tp_iternext */ + dictiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +dictiter_iternextitem(dictiterobject *di) +{ + PyObject *key, *value, *result; + Py_ssize_t i; + PyDictObject *d = di->di_dict; + + if (d == NULL) + return NULL; + assert (PyDict_Check(d)); + + if (di->di_used != d->ma_used) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary changed size during iteration"); + di->di_used = -1; /* Make this state sticky */ + return NULL; + } + + i = di->di_pos; + assert(i >= 0); + if (d->ma_values) { + if (i >= d->ma_used) + goto fail; + key = DK_ENTRIES(d->ma_keys)[i].me_key; + value = d->ma_values[i]; + assert(value != NULL); + } + else { + Py_ssize_t n = d->ma_keys->dk_nentries; + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + value = entry_ptr->me_value; + } + // We found an element, but did not expect it + if (di->len == 0) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary keys changed during iteration"); + goto fail; + } + di->di_pos = i+1; + di->len--; + Py_INCREF(key); + Py_INCREF(value); + result = di->di_result; + if (Py_REFCNT(result) == 1) { + PyObject *oldkey = PyTuple_GET_ITEM(result, 0); + PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + Py_INCREF(result); + Py_DECREF(oldkey); + Py_DECREF(oldvalue); + // 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(2); + if (result == NULL) + return NULL; + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + } + return result; + +fail: + di->di_dict = NULL; + Py_DECREF(d); + return NULL; +} + +PyTypeObject PyDictIterItem_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_itemiterator", /* tp_name */ + sizeof(dictiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dictiter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dictiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dictiter_iternextitem, /* tp_iternext */ + dictiter_methods, /* tp_methods */ + 0, +}; + + +/* dictreviter */ + +static PyObject * +dictreviter_iternext(dictiterobject *di) +{ + PyDictObject *d = di->di_dict; + + if (d == NULL) { + return NULL; + } + assert (PyDict_Check(d)); + + if (di->di_used != d->ma_used) { + PyErr_SetString(PyExc_RuntimeError, + "dictionary changed size during iteration"); + di->di_used = -1; /* Make this state sticky */ + return NULL; + } + + Py_ssize_t i = di->di_pos; + PyDictKeysObject *k = d->ma_keys; + PyObject *key, *value, *result; + + if (i < 0) { + goto fail; + } + if (d->ma_values) { + key = DK_ENTRIES(k)[i].me_key; + value = d->ma_values[i]; + assert (value != NULL); + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; + while (entry_ptr->me_value == NULL) { + if (--i < 0) { + goto fail; + } + entry_ptr--; + } + key = entry_ptr->me_key; + value = entry_ptr->me_value; + } + di->di_pos = i-1; + di->len--; + + if (Py_TYPE(di) == &PyDictRevIterKey_Type) { + Py_INCREF(key); + return key; + } + else if (Py_TYPE(di) == &PyDictRevIterValue_Type) { + Py_INCREF(value); + return value; + } + else if (Py_TYPE(di) == &PyDictRevIterItem_Type) { + Py_INCREF(key); + Py_INCREF(value); + result = di->di_result; + if (Py_REFCNT(result) == 1) { + PyObject *oldkey = PyTuple_GET_ITEM(result, 0); + PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + Py_INCREF(result); + Py_DECREF(oldkey); + Py_DECREF(oldvalue); + // 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(2); + if (result == NULL) { + return NULL; + } + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + } + return result; + } + else { + Py_UNREACHABLE(); + } + +fail: + di->di_dict = NULL; + Py_DECREF(d); + return NULL; +} + +PyTypeObject PyDictRevIterKey_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_reversekeyiterator", + sizeof(dictiterobject), + .tp_dealloc = (destructor)dictiter_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)dictiter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)dictreviter_iternext, + .tp_methods = dictiter_methods +}; + + +/*[clinic input] +dict.__reversed__ + +Return a reverse iterator over the dict keys. +[clinic start generated code]*/ + +static PyObject * +dict___reversed___impl(PyDictObject *self) +/*[clinic end generated code: output=e674483336d1ed51 input=23210ef3477d8c4d]*/ +{ + assert (PyDict_Check(self)); + return dictiter_new(self, &PyDictRevIterKey_Type); +} + +static PyObject * +dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + /* copy the iterator state */ + dictiterobject tmp = *di; + Py_XINCREF(tmp.di_dict); + + PyObject *list = PySequence_List((PyObject*)&tmp); + Py_XDECREF(tmp.di_dict); + if (list == NULL) { + return NULL; + } + return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); +} + +PyTypeObject PyDictRevIterItem_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_reverseitemiterator", + sizeof(dictiterobject), + .tp_dealloc = (destructor)dictiter_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)dictiter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)dictreviter_iternext, + .tp_methods = dictiter_methods +}; + +PyTypeObject PyDictRevIterValue_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_reversevalueiterator", + sizeof(dictiterobject), + .tp_dealloc = (destructor)dictiter_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)dictiter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)dictreviter_iternext, + .tp_methods = dictiter_methods +}; + +/***********************************************/ +/* View objects for keys(), items(), values(). */ +/***********************************************/ + +/* The instance lay-out is the same for all three; but the type differs. */ + +static void +dictview_dealloc(_PyDictViewObject *dv) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + _PyObject_GC_UNTRACK(dv); + Py_XDECREF(dv->dv_dict); + PyObject_GC_Del(dv); +} + +static int +dictview_traverse(_PyDictViewObject *dv, visitproc visit, void *arg) +{ + Py_VISIT(dv->dv_dict); + return 0; +} + +static Py_ssize_t +dictview_len(_PyDictViewObject *dv) +{ + Py_ssize_t len = 0; + if (dv->dv_dict != NULL) + len = dv->dv_dict->ma_used; + return len; +} + +PyObject * +_PyDictView_New(PyObject *dict, PyTypeObject *type) +{ + _PyDictViewObject *dv; + if (dict == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + if (!PyDict_Check(dict)) { + /* XXX Get rid of this restriction later */ + PyErr_Format(PyExc_TypeError, + "%s() requires a dict argument, not '%s'", + type->tp_name, dict->ob_type->tp_name); + return NULL; + } + dv = PyObject_GC_New(_PyDictViewObject, type); + if (dv == NULL) + return NULL; + Py_INCREF(dict); + dv->dv_dict = (PyDictObject *)dict; + _PyObject_GC_TRACK(dv); + return (PyObject *)dv; +} + +/* TODO(guido): The views objects are not complete: + + * support more set operations + * support arbitrary mappings? + - either these should be static or exported in dictobject.h + - if public then they should probably be in builtins +*/ + +/* Return 1 if self is a subset of other, iterating over self; + 0 if not; -1 if an error occurred. */ +static int +all_contained_in(PyObject *self, PyObject *other) +{ + PyObject *iter = PyObject_GetIter(self); + int ok = 1; + + if (iter == NULL) + return -1; + for (;;) { + PyObject *next = PyIter_Next(iter); + if (next == NULL) { + if (PyErr_Occurred()) + ok = -1; + break; + } + ok = PySequence_Contains(other, next); + Py_DECREF(next); + if (ok <= 0) + break; + } + Py_DECREF(iter); + return ok; +} + +static PyObject * +dictview_richcompare(PyObject *self, PyObject *other, int op) +{ + Py_ssize_t len_self, len_other; + int ok; + PyObject *result; + + assert(self != NULL); + assert(PyDictViewSet_Check(self)); + assert(other != NULL); + + if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; + + len_self = PyObject_Size(self); + if (len_self < 0) + return NULL; + len_other = PyObject_Size(other); + if (len_other < 0) + return NULL; + + ok = 0; + switch(op) { + + case Py_NE: + case Py_EQ: + if (len_self == len_other) + ok = all_contained_in(self, other); + if (op == Py_NE && ok >= 0) + ok = !ok; + break; + + case Py_LT: + if (len_self < len_other) + ok = all_contained_in(self, other); + break; + + case Py_LE: + if (len_self <= len_other) + ok = all_contained_in(self, other); + break; + + case Py_GT: + if (len_self > len_other) + ok = all_contained_in(other, self); + break; + + case Py_GE: + if (len_self >= len_other) + ok = all_contained_in(other, self); + break; + + } + if (ok < 0) + return NULL; + result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} + +static PyObject * +dictview_repr(_PyDictViewObject *dv) +{ + PyObject *seq; + PyObject *result = NULL; + Py_ssize_t rc; + + rc = Py_ReprEnter((PyObject *)dv); + if (rc != 0) { + return rc > 0 ? PyUnicode_FromString("...") : NULL; + } + seq = PySequence_List((PyObject *)dv); + if (seq == NULL) { + goto Done; + } + result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq); + Py_DECREF(seq); + +Done: + Py_ReprLeave((PyObject *)dv); + return result; +} + +/*** dict_keys ***/ + +static PyObject * +dictkeys_iter(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return dictiter_new(dv->dv_dict, &PyDictIterKey_Type); +} + +static int +dictkeys_contains(_PyDictViewObject *dv, PyObject *obj) +{ + if (dv->dv_dict == NULL) + return 0; + return PyDict_Contains((PyObject *)dv->dv_dict, obj); +} + +static PySequenceMethods dictkeys_as_sequence = { + (lenfunc)dictview_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)dictkeys_contains, /* sq_contains */ +}; + +static PyObject* +dictviews_sub(PyObject* self, PyObject *other) +{ + PyObject *result = PySet_New(self); + PyObject *tmp; + _Py_IDENTIFIER(difference_update); + + if (result == NULL) + return NULL; + + tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_difference_update, other, NULL); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } + + Py_DECREF(tmp); + return result; +} + +PyObject* +_PyDictView_Intersect(PyObject* self, PyObject *other) +{ + PyObject *result = PySet_New(self); + PyObject *tmp; + _Py_IDENTIFIER(intersection_update); + + if (result == NULL) + return NULL; + + tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_intersection_update, other, NULL); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } + + Py_DECREF(tmp); + return result; +} + +static PyObject* +dictviews_or(PyObject* self, PyObject *other) +{ + PyObject *result = PySet_New(self); + PyObject *tmp; + _Py_IDENTIFIER(update); + + if (result == NULL) + return NULL; + + tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_update, other, NULL); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } + + Py_DECREF(tmp); + return result; +} + +static PyObject* +dictviews_xor(PyObject* self, PyObject *other) +{ + PyObject *result = PySet_New(self); + PyObject *tmp; + _Py_IDENTIFIER(symmetric_difference_update); + + if (result == NULL) + return NULL; + + tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_symmetric_difference_update, other, NULL); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } + + Py_DECREF(tmp); + return result; +} + +static PyNumberMethods dictviews_as_number = { + 0, /*nb_add*/ + (binaryfunc)dictviews_sub, /*nb_subtract*/ + 0, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + 0, /*nb_negative*/ + 0, /*nb_positive*/ + 0, /*nb_absolute*/ + 0, /*nb_bool*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + (binaryfunc)_PyDictView_Intersect, /*nb_and*/ + (binaryfunc)dictviews_xor, /*nb_xor*/ + (binaryfunc)dictviews_or, /*nb_or*/ +}; + +static PyObject* +dictviews_isdisjoint(PyObject *self, PyObject *other) +{ + PyObject *it; + PyObject *item = NULL; + + if (self == other) { + if (dictview_len((_PyDictViewObject *)self) == 0) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + /* Iterate over the shorter object (only if other is a set, + * because PySequence_Contains may be expensive otherwise): */ + if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) { + Py_ssize_t len_self = dictview_len((_PyDictViewObject *)self); + Py_ssize_t len_other = PyObject_Size(other); + if (len_other == -1) + return NULL; + + if ((len_other > len_self)) { + PyObject *tmp = other; + other = self; + self = tmp; + } + } + + it = PyObject_GetIter(other); + if (it == NULL) + return NULL; + + while ((item = PyIter_Next(it)) != NULL) { + int contains = PySequence_Contains(self, item); + Py_DECREF(item); + if (contains == -1) { + Py_DECREF(it); + return NULL; + } + + if (contains) { + Py_DECREF(it); + Py_RETURN_FALSE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) + return NULL; /* PyIter_Next raised an exception. */ + Py_RETURN_TRUE; +} + +PyDoc_STRVAR(isdisjoint_doc, +"Return True if the view and the given iterable have a null intersection."); + +static PyObject* dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)); + +PyDoc_STRVAR(reversed_keys_doc, +"Return a reverse iterator over the dict keys."); + +static PyMethodDef dictkeys_methods[] = { + {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O, + isdisjoint_doc}, + {"__reversed__", (PyCFunction)(void(*)(void))dictkeys_reversed, METH_NOARGS, + reversed_keys_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyDictKeys_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_keys", /* tp_name */ + sizeof(_PyDictViewObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dictview_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)dictview_repr, /* tp_repr */ + &dictviews_as_number, /* tp_as_number */ + &dictkeys_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dictview_traverse, /* tp_traverse */ + 0, /* tp_clear */ + dictview_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)dictkeys_iter, /* tp_iter */ + 0, /* tp_iternext */ + dictkeys_methods, /* tp_methods */ + 0, +}; + +static PyObject * +dictkeys_new(PyObject *dict, PyObject *Py_UNUSED(ignored)) +{ + return _PyDictView_New(dict, &PyDictKeys_Type); +} + +static PyObject * +dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return dictiter_new(dv->dv_dict, &PyDictRevIterKey_Type); +} + +/*** dict_items ***/ + +static PyObject * +dictitems_iter(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return dictiter_new(dv->dv_dict, &PyDictIterItem_Type); +} + +static int +dictitems_contains(_PyDictViewObject *dv, PyObject *obj) +{ + int result; + PyObject *key, *value, *found; + if (dv->dv_dict == NULL) + return 0; + if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2) + return 0; + key = PyTuple_GET_ITEM(obj, 0); + value = PyTuple_GET_ITEM(obj, 1); + found = PyDict_GetItemWithError((PyObject *)dv->dv_dict, key); + if (found == NULL) { + if (PyErr_Occurred()) + return -1; + return 0; + } + Py_INCREF(found); + result = PyObject_RichCompareBool(value, found, Py_EQ); + Py_DECREF(found); + return result; +} + +static PySequenceMethods dictitems_as_sequence = { + (lenfunc)dictview_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)dictitems_contains, /* sq_contains */ +}; + +static PyObject* dictitems_reversed(_PyDictViewObject *dv); + +PyDoc_STRVAR(reversed_items_doc, +"Return a reverse iterator over the dict items."); + +static PyMethodDef dictitems_methods[] = { + {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O, + isdisjoint_doc}, + {"__reversed__", (PyCFunction)(void(*)(void))dictitems_reversed, METH_NOARGS, + reversed_items_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyDictItems_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_items", /* tp_name */ + sizeof(_PyDictViewObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dictview_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)dictview_repr, /* tp_repr */ + &dictviews_as_number, /* tp_as_number */ + &dictitems_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dictview_traverse, /* tp_traverse */ + 0, /* tp_clear */ + dictview_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)dictitems_iter, /* tp_iter */ + 0, /* tp_iternext */ + dictitems_methods, /* tp_methods */ + 0, +}; + +static PyObject * +dictitems_new(PyObject *dict, PyObject *Py_UNUSED(ignored)) +{ + return _PyDictView_New(dict, &PyDictItems_Type); +} + +static PyObject * +dictitems_reversed(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return dictiter_new(dv->dv_dict, &PyDictRevIterItem_Type); +} + +/*** dict_values ***/ + +static PyObject * +dictvalues_iter(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return dictiter_new(dv->dv_dict, &PyDictIterValue_Type); +} + +static PySequenceMethods dictvalues_as_sequence = { + (lenfunc)dictview_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)0, /* sq_contains */ +}; + +static PyObject* dictvalues_reversed(_PyDictViewObject *dv); + +PyDoc_STRVAR(reversed_values_doc, +"Return a reverse iterator over the dict values."); + +static PyMethodDef dictvalues_methods[] = { + {"__reversed__", (PyCFunction)(void(*)(void))dictvalues_reversed, METH_NOARGS, + reversed_values_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyDictValues_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_values", /* tp_name */ + sizeof(_PyDictViewObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dictview_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)dictview_repr, /* tp_repr */ + 0, /* tp_as_number */ + &dictvalues_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dictview_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)dictvalues_iter, /* tp_iter */ + 0, /* tp_iternext */ + dictvalues_methods, /* tp_methods */ + 0, +}; + +static PyObject * +dictvalues_new(PyObject *dict, PyObject *Py_UNUSED(ignored)) +{ + return _PyDictView_New(dict, &PyDictValues_Type); +} + +static PyObject * +dictvalues_reversed(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return dictiter_new(dv->dv_dict, &PyDictRevIterValue_Type); +} + + +/* Returns NULL if cannot allocate a new PyDictKeysObject, + but does not set an error */ +PyDictKeysObject * +_PyDict_NewKeysForClass(void) +{ + PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE); + if (keys == NULL) + PyErr_Clear(); + else + keys->dk_lookup = lookdict_split; + return keys; +} + +#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys) + +PyObject * +PyObject_GenericGetDict(PyObject *obj, void *context) +{ + PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj); + if (dictptr == NULL) { + PyErr_SetString(PyExc_AttributeError, + "This object has no __dict__"); + return NULL; + } + dict = *dictptr; + if (dict == NULL) { + PyTypeObject *tp = Py_TYPE(obj); + if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { + dictkeys_incref(CACHED_KEYS(tp)); + *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + } + else { + *dictptr = dict = PyDict_New(); + } + } + Py_XINCREF(dict); + return dict; +} + +int +_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, + PyObject *key, PyObject *value) +{ + PyObject *dict; + int res; + PyDictKeysObject *cached; + + assert(dictptr != NULL); + if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) { + assert(dictptr != NULL); + dict = *dictptr; + if (dict == NULL) { + dictkeys_incref(cached); + dict = new_dict_with_shared_keys(cached); + if (dict == NULL) + return -1; + *dictptr = dict; + } + if (value == NULL) { + res = PyDict_DelItem(dict, key); + // Since key sharing dict doesn't allow deletion, PyDict_DelItem() + // always converts dict to combined form. + if ((cached = CACHED_KEYS(tp)) != NULL) { + CACHED_KEYS(tp) = NULL; + dictkeys_decref(cached); + } + } + else { + int was_shared = (cached == ((PyDictObject *)dict)->ma_keys); + res = PyDict_SetItem(dict, key, value); + if (was_shared && + (cached = CACHED_KEYS(tp)) != NULL && + cached != ((PyDictObject *)dict)->ma_keys) { + /* PyDict_SetItem() may call dictresize and convert split table + * into combined table. In such case, convert it to split + * table again and update type's shared key only when this is + * the only dict sharing key with the type. + * + * This is to allow using shared key in class like this: + * + * class C: + * def __init__(self): + * # one dict resize happens + * self.a, self.b, self.c = 1, 2, 3 + * self.d, self.e, self.f = 4, 5, 6 + * a = C() + */ + if (cached->dk_refcnt == 1) { + CACHED_KEYS(tp) = make_keys_shared(dict); + } + else { + CACHED_KEYS(tp) = NULL; + } + dictkeys_decref(cached); + if (CACHED_KEYS(tp) == NULL && PyErr_Occurred()) + return -1; + } + } + } else { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + if (dict == NULL) + return -1; + *dictptr = dict; + } + if (value == NULL) { + res = PyDict_DelItem(dict, key); + } else { + res = PyDict_SetItem(dict, key, value); + } + } + return res; +} + +void +_PyDictKeys_DecRef(PyDictKeysObject *keys) +{ + dictkeys_decref(keys); +} diff --git a/python/Objects/enumobject.c b/python/Objects/enumobject.c new file mode 100755 index 0000000..478a9dd --- /dev/null +++ b/python/Objects/enumobject.c @@ -0,0 +1,457 @@ +/* enumerate object */ + +#include "Python.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() + +#include "clinic/enumobject.c.h" + +/*[clinic input] +class enumerate "enumobject *" "&PyEnum_Type" +class reversed "reversedobject *" "&PyReversed_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d2dfdf1a88c88975]*/ + +typedef struct { + PyObject_HEAD + Py_ssize_t en_index; /* current index of enumeration */ + PyObject* en_sit; /* secondary iterator of enumeration */ + PyObject* en_result; /* result tuple */ + PyObject* en_longindex; /* index for sequences >= PY_SSIZE_T_MAX */ +} enumobject; + + +/*[clinic input] +@classmethod +enumerate.__new__ as enum_new + + iterable: object + an object supporting iteration + start: object = 0 + +Return an enumerate object. + +The enumerate object yields pairs containing a count (from start, which +defaults to zero) and a value yielded by the iterable argument. + +enumerate is useful for obtaining an indexed list: + (0, seq[0]), (1, seq[1]), (2, seq[2]), ... +[clinic start generated code]*/ + +static PyObject * +enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start) +/*[clinic end generated code: output=e95e6e439f812c10 input=782e4911efcb8acf]*/ +{ + enumobject *en; + + en = (enumobject *)type->tp_alloc(type, 0); + if (en == NULL) + return NULL; + if (start != NULL) { + start = PyNumber_Index(start); + if (start == NULL) { + Py_DECREF(en); + return NULL; + } + assert(PyLong_Check(start)); + en->en_index = PyLong_AsSsize_t(start); + if (en->en_index == -1 && PyErr_Occurred()) { + PyErr_Clear(); + en->en_index = PY_SSIZE_T_MAX; + en->en_longindex = start; + } else { + en->en_longindex = NULL; + Py_DECREF(start); + } + } else { + en->en_index = 0; + en->en_longindex = NULL; + } + en->en_sit = PyObject_GetIter(iterable); + if (en->en_sit == NULL) { + Py_DECREF(en); + return NULL; + } + en->en_result = PyTuple_Pack(2, Py_None, Py_None); + if (en->en_result == NULL) { + Py_DECREF(en); + return NULL; + } + return (PyObject *)en; +} + +static void +enum_dealloc(enumobject *en) +{ + PyObject_GC_UnTrack(en); + Py_XDECREF(en->en_sit); + Py_XDECREF(en->en_result); + Py_XDECREF(en->en_longindex); + Py_TYPE(en)->tp_free(en); +} + +static int +enum_traverse(enumobject *en, visitproc visit, void *arg) +{ + Py_VISIT(en->en_sit); + Py_VISIT(en->en_result); + Py_VISIT(en->en_longindex); + return 0; +} + +static PyObject * +enum_next_long(enumobject *en, PyObject* next_item) +{ + PyObject *result = en->en_result; + PyObject *next_index; + PyObject *stepped_up; + PyObject *old_index; + PyObject *old_item; + + if (en->en_longindex == NULL) { + en->en_longindex = PyLong_FromSsize_t(PY_SSIZE_T_MAX); + if (en->en_longindex == NULL) { + Py_DECREF(next_item); + return NULL; + } + } + next_index = en->en_longindex; + assert(next_index != NULL); + stepped_up = PyNumber_Add(next_index, _PyLong_One); + if (stepped_up == NULL) { + Py_DECREF(next_item); + return NULL; + } + en->en_longindex = stepped_up; + + if (result->ob_refcnt == 1) { + Py_INCREF(result); + old_index = PyTuple_GET_ITEM(result, 0); + old_item = PyTuple_GET_ITEM(result, 1); + PyTuple_SET_ITEM(result, 0, next_index); + PyTuple_SET_ITEM(result, 1, next_item); + Py_DECREF(old_index); + Py_DECREF(old_item); + // 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); + } + return result; + } + result = PyTuple_New(2); + if (result == NULL) { + Py_DECREF(next_index); + Py_DECREF(next_item); + return NULL; + } + PyTuple_SET_ITEM(result, 0, next_index); + PyTuple_SET_ITEM(result, 1, next_item); + return result; +} + +static PyObject * +enum_next(enumobject *en) +{ + PyObject *next_index; + PyObject *next_item; + PyObject *result = en->en_result; + PyObject *it = en->en_sit; + PyObject *old_index; + PyObject *old_item; + + next_item = (*Py_TYPE(it)->tp_iternext)(it); + if (next_item == NULL) + return NULL; + + if (en->en_index == PY_SSIZE_T_MAX) + return enum_next_long(en, next_item); + + next_index = PyLong_FromSsize_t(en->en_index); + if (next_index == NULL) { + Py_DECREF(next_item); + return NULL; + } + en->en_index++; + + if (result->ob_refcnt == 1) { + Py_INCREF(result); + old_index = PyTuple_GET_ITEM(result, 0); + old_item = PyTuple_GET_ITEM(result, 1); + PyTuple_SET_ITEM(result, 0, next_index); + PyTuple_SET_ITEM(result, 1, next_item); + Py_DECREF(old_index); + Py_DECREF(old_item); + // 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); + } + return result; + } + result = PyTuple_New(2); + if (result == NULL) { + Py_DECREF(next_index); + Py_DECREF(next_item); + return NULL; + } + PyTuple_SET_ITEM(result, 0, next_index); + PyTuple_SET_ITEM(result, 1, next_item); + return result; +} + +static PyObject * +enum_reduce(enumobject *en, PyObject *Py_UNUSED(ignored)) +{ + if (en->en_longindex != NULL) + return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex); + else + return Py_BuildValue("O(On)", Py_TYPE(en), en->en_sit, en->en_index); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyMethodDef enum_methods[] = { + {"__reduce__", (PyCFunction)enum_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyEnum_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "enumerate", /* tp_name */ + sizeof(enumobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)enum_dealloc, /* tp_dealloc */ + 0, /* tp_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 */ + enum_new__doc__, /* tp_doc */ + (traverseproc)enum_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)enum_next, /* tp_iternext */ + enum_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 */ + enum_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +/* Reversed Object ***************************************************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t index; + PyObject* seq; +} reversedobject; + +/*[clinic input] +@classmethod +reversed.__new__ as reversed_new + + sequence as seq: object + / + +Return a reverse iterator over the values of the given sequence. +[clinic start generated code]*/ + +static PyObject * +reversed_new_impl(PyTypeObject *type, PyObject *seq) +/*[clinic end generated code: output=f7854cc1df26f570 input=aeb720361e5e3f1d]*/ +{ + Py_ssize_t n; + PyObject *reversed_meth; + reversedobject *ro; + _Py_IDENTIFIER(__reversed__); + + reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__); + if (reversed_meth == Py_None) { + Py_DECREF(reversed_meth); + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not reversible", + Py_TYPE(seq)->tp_name); + return NULL; + } + if (reversed_meth != NULL) { + PyObject *res = _PyObject_CallNoArg(reversed_meth); + Py_DECREF(reversed_meth); + return res; + } + else if (PyErr_Occurred()) + return NULL; + + if (!PySequence_Check(seq)) { + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not reversible", + Py_TYPE(seq)->tp_name); + return NULL; + } + + n = PySequence_Size(seq); + if (n == -1) + return NULL; + + ro = (reversedobject *)type->tp_alloc(type, 0); + if (ro == NULL) + return NULL; + + ro->index = n-1; + Py_INCREF(seq); + ro->seq = seq; + return (PyObject *)ro; +} + +static void +reversed_dealloc(reversedobject *ro) +{ + PyObject_GC_UnTrack(ro); + Py_XDECREF(ro->seq); + Py_TYPE(ro)->tp_free(ro); +} + +static int +reversed_traverse(reversedobject *ro, visitproc visit, void *arg) +{ + Py_VISIT(ro->seq); + return 0; +} + +static PyObject * +reversed_next(reversedobject *ro) +{ + PyObject *item; + Py_ssize_t index = ro->index; + + if (index >= 0) { + item = PySequence_GetItem(ro->seq, index); + if (item != NULL) { + ro->index--; + return item; + } + if (PyErr_ExceptionMatches(PyExc_IndexError) || + PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + } + ro->index = -1; + Py_CLEAR(ro->seq); + return NULL; +} + +static PyObject * +reversed_len(reversedobject *ro, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t position, seqsize; + + if (ro->seq == NULL) + return PyLong_FromLong(0); + seqsize = PySequence_Size(ro->seq); + if (seqsize == -1) + return NULL; + position = ro->index + 1; + return PyLong_FromSsize_t((seqsize < position) ? 0 : position); +} + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); + +static PyObject * +reversed_reduce(reversedobject *ro, PyObject *Py_UNUSED(ignored)) +{ + if (ro->seq) + return Py_BuildValue("O(O)n", Py_TYPE(ro), ro->seq, ro->index); + else + return Py_BuildValue("O(())", Py_TYPE(ro)); +} + +static PyObject * +reversed_setstate(reversedobject *ro, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (ro->seq != 0) { + Py_ssize_t n = PySequence_Size(ro->seq); + if (n < 0) + return NULL; + if (index < -1) + index = -1; + else if (index > n-1) + index = n-1; + ro->index = index; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef reversediter_methods[] = { + {"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)reversed_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)reversed_setstate, METH_O, setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyReversed_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "reversed", /* tp_name */ + sizeof(reversedobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)reversed_dealloc, /* tp_dealloc */ + 0, /* tp_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 */ + reversed_new__doc__, /* tp_doc */ + (traverseproc)reversed_traverse,/* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)reversed_next, /* tp_iternext */ + reversediter_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + reversed_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; diff --git a/python/Objects/exceptions.c b/python/Objects/exceptions.c new file mode 100755 index 0000000..d22ed6f --- /dev/null +++ b/python/Objects/exceptions.c @@ -0,0 +1,3064 @@ +/* + * New exceptions.c written in Iceland by Richard Jones and Georg Brandl. + * + * Thanks go to Tim Peters and Michael Hudson for debugging. + */ + +#define PY_SSIZE_T_CLEAN +#include +#include "pycore_initconfig.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "structmember.h" +#include "osdefs.h" + + +/* Compatibility aliases */ +PyObject *PyExc_EnvironmentError = NULL; +PyObject *PyExc_IOError = NULL; +#ifdef MS_WINDOWS +PyObject *PyExc_WindowsError = NULL; +#endif + +/* The dict map from errno codes to OSError subclasses */ +static PyObject *errnomap = NULL; + + +/* NOTE: If the exception class hierarchy changes, don't forget to update + * Lib/test/exception_hierarchy.txt + */ + +/* + * BaseException + */ +static PyObject * +BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyBaseExceptionObject *self; + + self = (PyBaseExceptionObject *)type->tp_alloc(type, 0); + if (!self) + return NULL; + /* the dict is created on the fly in PyObject_GenericSetAttr */ + self->dict = NULL; + self->traceback = self->cause = self->context = NULL; + self->suppress_context = 0; + + if (args) { + self->args = args; + Py_INCREF(args); + return (PyObject *)self; + } + + self->args = PyTuple_New(0); + if (!self->args) { + Py_DECREF(self); + return NULL; + } + + return (PyObject *)self; +} + +static int +BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) +{ + if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) + return -1; + + Py_INCREF(args); + Py_XSETREF(self->args, args); + + return 0; +} + +static int +BaseException_clear(PyBaseExceptionObject *self) +{ + Py_CLEAR(self->dict); + Py_CLEAR(self->args); + Py_CLEAR(self->traceback); + Py_CLEAR(self->cause); + Py_CLEAR(self->context); + return 0; +} + +static void +BaseException_dealloc(PyBaseExceptionObject *self) +{ + _PyObject_GC_UNTRACK(self); + BaseException_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + Py_VISIT(self->args); + Py_VISIT(self->traceback); + Py_VISIT(self->cause); + Py_VISIT(self->context); + return 0; +} + +static PyObject * +BaseException_str(PyBaseExceptionObject *self) +{ + switch (PyTuple_GET_SIZE(self->args)) { + case 0: + return PyUnicode_FromString(""); + case 1: + return PyObject_Str(PyTuple_GET_ITEM(self->args, 0)); + default: + return PyObject_Str(self->args); + } +} + +static PyObject * +BaseException_repr(PyBaseExceptionObject *self) +{ + const char *name = _PyType_Name(Py_TYPE(self)); + if (PyTuple_GET_SIZE(self->args) == 1) + return PyUnicode_FromFormat("%s(%R)", name, + PyTuple_GET_ITEM(self->args, 0)); + else + return PyUnicode_FromFormat("%s%R", name, self->args); +} + +/* Pickling support */ +static PyObject * +BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored)) +{ + if (self->args && self->dict) + return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict); + else + return PyTuple_Pack(2, Py_TYPE(self), self->args); +} + +/* + * Needed for backward compatibility, since exceptions used to store + * all their attributes in the __dict__. Code is taken from cPickle's + * load_build function. + */ +static PyObject * +BaseException_setstate(PyObject *self, PyObject *state) +{ + PyObject *d_key, *d_value; + Py_ssize_t i = 0; + + if (state != Py_None) { + if (!PyDict_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state is not a dictionary"); + return NULL; + } + while (PyDict_Next(state, &i, &d_key, &d_value)) { + if (PyObject_SetAttr(self, d_key, d_value) < 0) + return NULL; + } + } + Py_RETURN_NONE; +} + +static PyObject * +BaseException_with_traceback(PyObject *self, PyObject *tb) { + if (PyException_SetTraceback(self, tb)) + return NULL; + + Py_INCREF(self); + return self; +} + +PyDoc_STRVAR(with_traceback_doc, +"Exception.with_traceback(tb) --\n\ + set self.__traceback__ to tb and return self."); + + +static PyMethodDef BaseException_methods[] = { + {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS }, + {"__setstate__", (PyCFunction)BaseException_setstate, METH_O }, + {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O, + with_traceback_doc}, + {NULL, NULL, 0, NULL}, +}; + +static PyObject * +BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) +{ + if (self->args == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(self->args); + return self->args; +} + +static int +BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored)) +{ + PyObject *seq; + if (val == NULL) { + PyErr_SetString(PyExc_TypeError, "args may not be deleted"); + return -1; + } + seq = PySequence_Tuple(val); + if (!seq) + return -1; + Py_XSETREF(self->args, seq); + return 0; +} + +static PyObject * +BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) +{ + if (self->traceback == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(self->traceback); + return self->traceback; +} + +static int +BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored)) +{ + if (tb == NULL) { + PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted"); + return -1; + } + else if (!(tb == Py_None || PyTraceBack_Check(tb))) { + PyErr_SetString(PyExc_TypeError, + "__traceback__ must be a traceback or None"); + return -1; + } + + Py_INCREF(tb); + Py_XSETREF(self->traceback, tb); + return 0; +} + +static PyObject * +BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored)) +{ + PyObject *res = PyException_GetContext(self); + if (res) + return res; /* new reference already returned above */ + Py_RETURN_NONE; +} + +static int +BaseException_set_context(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored)) +{ + if (arg == NULL) { + PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted"); + return -1; + } else if (arg == Py_None) { + arg = NULL; + } else if (!PyExceptionInstance_Check(arg)) { + PyErr_SetString(PyExc_TypeError, "exception context must be None " + "or derive from BaseException"); + return -1; + } else { + /* PyException_SetContext steals this reference */ + Py_INCREF(arg); + } + PyException_SetContext(self, arg); + return 0; +} + +static PyObject * +BaseException_get_cause(PyObject *self, void *Py_UNUSED(ignored)) +{ + PyObject *res = PyException_GetCause(self); + if (res) + return res; /* new reference already returned above */ + Py_RETURN_NONE; +} + +static int +BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored)) +{ + if (arg == NULL) { + PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted"); + return -1; + } else if (arg == Py_None) { + arg = NULL; + } else if (!PyExceptionInstance_Check(arg)) { + PyErr_SetString(PyExc_TypeError, "exception cause must be None " + "or derive from BaseException"); + return -1; + } else { + /* PyException_SetCause steals this reference */ + Py_INCREF(arg); + } + PyException_SetCause(self, arg); + return 0; +} + + +static PyGetSetDef BaseException_getset[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {"args", (getter)BaseException_get_args, (setter)BaseException_set_args}, + {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb}, + {"__context__", BaseException_get_context, + BaseException_set_context, PyDoc_STR("exception context")}, + {"__cause__", BaseException_get_cause, + BaseException_set_cause, PyDoc_STR("exception cause")}, + {NULL}, +}; + + +PyObject * +PyException_GetTraceback(PyObject *self) { + PyBaseExceptionObject *base_self = (PyBaseExceptionObject *)self; + Py_XINCREF(base_self->traceback); + return base_self->traceback; +} + + +int +PyException_SetTraceback(PyObject *self, PyObject *tb) { + return BaseException_set_tb((PyBaseExceptionObject *)self, tb, NULL); +} + +PyObject * +PyException_GetCause(PyObject *self) { + PyObject *cause = ((PyBaseExceptionObject *)self)->cause; + Py_XINCREF(cause); + return cause; +} + +/* Steals a reference to cause */ +void +PyException_SetCause(PyObject *self, PyObject *cause) +{ + ((PyBaseExceptionObject *)self)->suppress_context = 1; + Py_XSETREF(((PyBaseExceptionObject *)self)->cause, cause); +} + +PyObject * +PyException_GetContext(PyObject *self) { + PyObject *context = ((PyBaseExceptionObject *)self)->context; + Py_XINCREF(context); + return context; +} + +/* Steals a reference to context */ +void +PyException_SetContext(PyObject *self, PyObject *context) +{ + Py_XSETREF(((PyBaseExceptionObject *)self)->context, context); +} + +#undef PyExceptionClass_Name + +const char * +PyExceptionClass_Name(PyObject *ob) +{ + return ((PyTypeObject*)ob)->tp_name; +} + +static struct PyMemberDef BaseException_members[] = { + {"__suppress_context__", T_BOOL, + offsetof(PyBaseExceptionObject, suppress_context)}, + {NULL} +}; + + +static PyTypeObject _PyExc_BaseException = { + PyVarObject_HEAD_INIT(NULL, 0) + "BaseException", /*tp_name*/ + sizeof(PyBaseExceptionObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)BaseException_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + (reprfunc)BaseException_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + (reprfunc)BaseException_str, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + PyObject_GenericSetAttr, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/ + PyDoc_STR("Common base class for all exceptions"), /* tp_doc */ + (traverseproc)BaseException_traverse, /* tp_traverse */ + (inquiry)BaseException_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BaseException_methods, /* tp_methods */ + BaseException_members, /* tp_members */ + BaseException_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */ + (initproc)BaseException_init, /* tp_init */ + 0, /* tp_alloc */ + BaseException_new, /* tp_new */ +}; +/* the CPython API expects exceptions to be (PyObject *) - both a hold-over +from the previous implmentation and also allowing Python objects to be used +in the API */ +PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException; + +/* note these macros omit the last semicolon so the macro invocation may + * include it and not look strange. + */ +#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \ +static PyTypeObject _PyExc_ ## EXCNAME = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + # EXCNAME, \ + sizeof(PyBaseExceptionObject), \ + 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, \ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ + PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \ + (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ + 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \ + (initproc)BaseException_init, 0, BaseException_new,\ +}; \ +PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME + +#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \ +static PyTypeObject _PyExc_ ## EXCNAME = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + # EXCNAME, \ + sizeof(Py ## EXCSTORE ## Object), \ + 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, \ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ + PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ + (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ + 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ + (initproc)EXCSTORE ## _init, 0, 0, \ +}; \ +PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME + +#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \ + EXCMETHODS, EXCMEMBERS, EXCGETSET, \ + EXCSTR, EXCDOC) \ +static PyTypeObject _PyExc_ ## EXCNAME = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + # EXCNAME, \ + sizeof(Py ## EXCSTORE ## Object), 0, \ + (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + (reprfunc)EXCSTR, 0, 0, 0, \ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ + PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ + (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \ + EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \ + 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ + (initproc)EXCSTORE ## _init, 0, EXCNEW,\ +}; \ +PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME + + +/* + * Exception extends BaseException + */ +SimpleExtendsException(PyExc_BaseException, Exception, + "Common base class for all non-exit exceptions."); + + +/* + * TypeError extends Exception + */ +SimpleExtendsException(PyExc_Exception, TypeError, + "Inappropriate argument type."); + + +/* + * StopAsyncIteration extends Exception + */ +SimpleExtendsException(PyExc_Exception, StopAsyncIteration, + "Signal the end from iterator.__anext__()."); + + +/* + * StopIteration extends Exception + */ + +static PyMemberDef StopIteration_members[] = { + {"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0, + PyDoc_STR("generator return value")}, + {NULL} /* Sentinel */ +}; + +static int +StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds) +{ + Py_ssize_t size = PyTuple_GET_SIZE(args); + PyObject *value; + + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + return -1; + Py_CLEAR(self->value); + if (size > 0) + value = PyTuple_GET_ITEM(args, 0); + else + value = Py_None; + Py_INCREF(value); + self->value = value; + return 0; +} + +static int +StopIteration_clear(PyStopIterationObject *self) +{ + Py_CLEAR(self->value); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +StopIteration_dealloc(PyStopIterationObject *self) +{ + _PyObject_GC_UNTRACK(self); + StopIteration_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->value); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +ComplexExtendsException( + PyExc_Exception, /* base */ + StopIteration, /* name */ + StopIteration, /* prefix for *_init, etc */ + 0, /* new */ + 0, /* methods */ + StopIteration_members, /* members */ + 0, /* getset */ + 0, /* str */ + "Signal the end from iterator.__next__()." +); + + +/* + * GeneratorExit extends BaseException + */ +SimpleExtendsException(PyExc_BaseException, GeneratorExit, + "Request that a generator exit."); + + +/* + * SystemExit extends BaseException + */ + +static int +SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds) +{ + Py_ssize_t size = PyTuple_GET_SIZE(args); + + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + return -1; + + if (size == 0) + return 0; + if (size == 1) { + Py_INCREF(PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0)); + } + else { /* size > 1 */ + Py_INCREF(args); + Py_XSETREF(self->code, args); + } + return 0; +} + +static int +SystemExit_clear(PySystemExitObject *self) +{ + Py_CLEAR(self->code); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +SystemExit_dealloc(PySystemExitObject *self) +{ + _PyObject_GC_UNTRACK(self); + SystemExit_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->code); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +static PyMemberDef SystemExit_members[] = { + {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0, + PyDoc_STR("exception code")}, + {NULL} /* Sentinel */ +}; + +ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit, + 0, 0, SystemExit_members, 0, 0, + "Request to exit from the interpreter."); + +/* + * KeyboardInterrupt extends BaseException + */ +SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, + "Program interrupted by user."); + + +/* + * ImportError extends Exception + */ + +static int +ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"name", "path", 0}; + PyObject *empty_tuple; + PyObject *msg = NULL; + PyObject *name = NULL; + PyObject *path = NULL; + + if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) + return -1; + + empty_tuple = PyTuple_New(0); + if (!empty_tuple) + return -1; + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist, + &name, &path)) { + Py_DECREF(empty_tuple); + return -1; + } + Py_DECREF(empty_tuple); + + Py_XINCREF(name); + Py_XSETREF(self->name, name); + + Py_XINCREF(path); + Py_XSETREF(self->path, path); + + if (PyTuple_GET_SIZE(args) == 1) { + msg = PyTuple_GET_ITEM(args, 0); + Py_INCREF(msg); + } + Py_XSETREF(self->msg, msg); + + return 0; +} + +static int +ImportError_clear(PyImportErrorObject *self) +{ + Py_CLEAR(self->msg); + Py_CLEAR(self->name); + Py_CLEAR(self->path); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +ImportError_dealloc(PyImportErrorObject *self) +{ + _PyObject_GC_UNTRACK(self); + ImportError_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->msg); + Py_VISIT(self->name); + Py_VISIT(self->path); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +static PyObject * +ImportError_str(PyImportErrorObject *self) +{ + if (self->msg && PyUnicode_CheckExact(self->msg)) { + Py_INCREF(self->msg); + return self->msg; + } + else { + return BaseException_str((PyBaseExceptionObject *)self); + } +} + +static PyObject * +ImportError_getstate(PyImportErrorObject *self) +{ + PyObject *dict = ((PyBaseExceptionObject *)self)->dict; + if (self->name || self->path) { + _Py_IDENTIFIER(name); + _Py_IDENTIFIER(path); + dict = dict ? PyDict_Copy(dict) : PyDict_New(); + if (dict == NULL) + return NULL; + if (self->name && _PyDict_SetItemId(dict, &PyId_name, self->name) < 0) { + Py_DECREF(dict); + return NULL; + } + if (self->path && _PyDict_SetItemId(dict, &PyId_path, self->path) < 0) { + Py_DECREF(dict); + return NULL; + } + return dict; + } + else if (dict) { + Py_INCREF(dict); + return dict; + } + else { + Py_RETURN_NONE; + } +} + +/* Pickling support */ +static PyObject * +ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *res; + PyObject *args; + PyObject *state = ImportError_getstate(self); + if (state == NULL) + return NULL; + args = ((PyBaseExceptionObject *)self)->args; + if (state == Py_None) + res = PyTuple_Pack(2, Py_TYPE(self), args); + else + res = PyTuple_Pack(3, Py_TYPE(self), args, state); + Py_DECREF(state); + return res; +} + +static PyMemberDef ImportError_members[] = { + {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0, + PyDoc_STR("exception message")}, + {"name", T_OBJECT, offsetof(PyImportErrorObject, name), 0, + PyDoc_STR("module name")}, + {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0, + PyDoc_STR("module path")}, + {NULL} /* Sentinel */ +}; + +static PyMethodDef ImportError_methods[] = { + {"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS}, + {NULL} +}; + +ComplexExtendsException(PyExc_Exception, ImportError, + ImportError, 0 /* new */, + ImportError_methods, ImportError_members, + 0 /* getset */, ImportError_str, + "Import can't find module, or can't find name in " + "module."); + +/* + * ModuleNotFoundError extends ImportError + */ + +MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError, + "Module not found."); + +/* + * OSError extends Exception + */ + +#ifdef MS_WINDOWS +#include "errmap.h" +#endif + +/* Where a function has a single filename, such as open() or some + * of the os module functions, PyErr_SetFromErrnoWithFilename() is + * called, giving a third argument which is the filename. But, so + * that old code using in-place unpacking doesn't break, e.g.: + * + * except OSError, (errno, strerror): + * + * we hack args so that it only contains two items. This also + * means we need our own __str__() which prints out the filename + * when it was supplied. + * + * (If a function has two filenames, such as rename(), symlink(), + * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called, + * which allows passing in a second filename.) + */ + +/* This function doesn't cleanup on error, the caller should */ +static int +oserror_parse_args(PyObject **p_args, + PyObject **myerrno, PyObject **strerror, + PyObject **filename, PyObject **filename2 +#ifdef MS_WINDOWS + , PyObject **winerror +#endif + ) +{ + Py_ssize_t nargs; + PyObject *args = *p_args; +#ifndef MS_WINDOWS + /* + * ignored on non-Windows platforms, + * but parsed so OSError has a consistent signature + */ + PyObject *_winerror = NULL; + PyObject **winerror = &_winerror; +#endif /* MS_WINDOWS */ + + nargs = PyTuple_GET_SIZE(args); + + if (nargs >= 2 && nargs <= 5) { + if (!PyArg_UnpackTuple(args, "OSError", 2, 5, + myerrno, strerror, + filename, winerror, filename2)) + return -1; +#ifdef MS_WINDOWS + if (*winerror && PyLong_Check(*winerror)) { + long errcode, winerrcode; + PyObject *newargs; + Py_ssize_t i; + + winerrcode = PyLong_AsLong(*winerror); + if (winerrcode == -1 && PyErr_Occurred()) + return -1; + /* Set errno to the corresponding POSIX errno (overriding + first argument). Windows Socket error codes (>= 10000) + have the same value as their POSIX counterparts. + */ + if (winerrcode < 10000) + errcode = winerror_to_errno(winerrcode); + else + errcode = winerrcode; + *myerrno = PyLong_FromLong(errcode); + if (!*myerrno) + return -1; + newargs = PyTuple_New(nargs); + if (!newargs) + return -1; + PyTuple_SET_ITEM(newargs, 0, *myerrno); + for (i = 1; i < nargs; i++) { + PyObject *val = PyTuple_GET_ITEM(args, i); + Py_INCREF(val); + PyTuple_SET_ITEM(newargs, i, val); + } + Py_DECREF(args); + args = *p_args = newargs; + } +#endif /* MS_WINDOWS */ + } + + return 0; +} + +static int +oserror_init(PyOSErrorObject *self, PyObject **p_args, + PyObject *myerrno, PyObject *strerror, + PyObject *filename, PyObject *filename2 +#ifdef MS_WINDOWS + , PyObject *winerror +#endif + ) +{ + PyObject *args = *p_args; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + + /* self->filename will remain Py_None otherwise */ + if (filename && filename != Py_None) { + if (Py_TYPE(self) == (PyTypeObject *) PyExc_BlockingIOError && + PyNumber_Check(filename)) { + /* BlockingIOError's 3rd argument can be the number of + * characters written. + */ + self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError); + if (self->written == -1 && PyErr_Occurred()) + return -1; + } + else { + Py_INCREF(filename); + self->filename = filename; + + if (filename2 && filename2 != Py_None) { + Py_INCREF(filename2); + self->filename2 = filename2; + } + + if (nargs >= 2 && nargs <= 5) { + /* filename, filename2, and winerror are removed from the args tuple + (for compatibility purposes, see test_exceptions.py) */ + PyObject *subslice = PyTuple_GetSlice(args, 0, 2); + if (!subslice) + return -1; + + Py_DECREF(args); /* replacing args */ + *p_args = args = subslice; + } + } + } + Py_XINCREF(myerrno); + self->myerrno = myerrno; + + Py_XINCREF(strerror); + self->strerror = strerror; + +#ifdef MS_WINDOWS + Py_XINCREF(winerror); + self->winerror = winerror; +#endif + + /* Steals the reference to args */ + Py_XSETREF(self->args, args); + *p_args = args = NULL; + + return 0; +} + +static PyObject * +OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static int +OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds); + +static int +oserror_use_init(PyTypeObject *type) +{ + /* When __init__ is defined in an OSError subclass, we want any + extraneous argument to __new__ to be ignored. The only reasonable + solution, given __new__ takes a variable number of arguments, + is to defer arg parsing and initialization to __init__. + + But when __new__ is overridden as well, it should call our __new__ + with the right arguments. + + (see http://bugs.python.org/issue12555#msg148829 ) + */ + if (type->tp_init != (initproc) OSError_init && + type->tp_new == (newfunc) OSError_new) { + assert((PyObject *) type != PyExc_OSError); + return 1; + } + return 0; +} + +static PyObject * +OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyOSErrorObject *self = NULL; + PyObject *myerrno = NULL, *strerror = NULL; + PyObject *filename = NULL, *filename2 = NULL; +#ifdef MS_WINDOWS + PyObject *winerror = NULL; +#endif + + Py_INCREF(args); + + if (!oserror_use_init(type)) { + if (!_PyArg_NoKeywords(type->tp_name, kwds)) + goto error; + + if (oserror_parse_args(&args, &myerrno, &strerror, + &filename, &filename2 +#ifdef MS_WINDOWS + , &winerror +#endif + )) + goto error; + + if (myerrno && PyLong_Check(myerrno) && + errnomap && (PyObject *) type == PyExc_OSError) { + PyObject *newtype; + newtype = PyDict_GetItemWithError(errnomap, myerrno); + if (newtype) { + assert(PyType_Check(newtype)); + type = (PyTypeObject *) newtype; + } + else if (PyErr_Occurred()) + goto error; + } + } + + self = (PyOSErrorObject *) type->tp_alloc(type, 0); + if (!self) + goto error; + + self->dict = NULL; + self->traceback = self->cause = self->context = NULL; + self->written = -1; + + if (!oserror_use_init(type)) { + if (oserror_init(self, &args, myerrno, strerror, filename, filename2 +#ifdef MS_WINDOWS + , winerror +#endif + )) + goto error; + } + else { + self->args = PyTuple_New(0); + if (self->args == NULL) + goto error; + } + + Py_XDECREF(args); + return (PyObject *) self; + +error: + Py_XDECREF(args); + Py_XDECREF(self); + return NULL; +} + +static int +OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *myerrno = NULL, *strerror = NULL; + PyObject *filename = NULL, *filename2 = NULL; +#ifdef MS_WINDOWS + PyObject *winerror = NULL; +#endif + + if (!oserror_use_init(Py_TYPE(self))) + /* Everything already done in OSError_new */ + return 0; + + if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) + return -1; + + Py_INCREF(args); + if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2 +#ifdef MS_WINDOWS + , &winerror +#endif + )) + goto error; + + if (oserror_init(self, &args, myerrno, strerror, filename, filename2 +#ifdef MS_WINDOWS + , winerror +#endif + )) + goto error; + + return 0; + +error: + Py_DECREF(args); + return -1; +} + +static int +OSError_clear(PyOSErrorObject *self) +{ + Py_CLEAR(self->myerrno); + Py_CLEAR(self->strerror); + Py_CLEAR(self->filename); + Py_CLEAR(self->filename2); +#ifdef MS_WINDOWS + Py_CLEAR(self->winerror); +#endif + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +OSError_dealloc(PyOSErrorObject *self) +{ + _PyObject_GC_UNTRACK(self); + OSError_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +OSError_traverse(PyOSErrorObject *self, visitproc visit, + void *arg) +{ + Py_VISIT(self->myerrno); + Py_VISIT(self->strerror); + Py_VISIT(self->filename); + Py_VISIT(self->filename2); +#ifdef MS_WINDOWS + Py_VISIT(self->winerror); +#endif + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +static PyObject * +OSError_str(PyOSErrorObject *self) +{ +#define OR_NONE(x) ((x)?(x):Py_None) +#ifdef MS_WINDOWS + /* If available, winerror has the priority over myerrno */ + if (self->winerror && self->filename) { + if (self->filename2) { + return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R", + OR_NONE(self->winerror), + OR_NONE(self->strerror), + self->filename, + self->filename2); + } else { + return PyUnicode_FromFormat("[WinError %S] %S: %R", + OR_NONE(self->winerror), + OR_NONE(self->strerror), + self->filename); + } + } + if (self->winerror && self->strerror) + return PyUnicode_FromFormat("[WinError %S] %S", + self->winerror ? self->winerror: Py_None, + self->strerror ? self->strerror: Py_None); +#endif + if (self->filename) { + if (self->filename2) { + return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R", + OR_NONE(self->myerrno), + OR_NONE(self->strerror), + self->filename, + self->filename2); + } else { + return PyUnicode_FromFormat("[Errno %S] %S: %R", + OR_NONE(self->myerrno), + OR_NONE(self->strerror), + self->filename); + } + } + if (self->myerrno && self->strerror) + return PyUnicode_FromFormat("[Errno %S] %S", + self->myerrno, self->strerror); + return BaseException_str((PyBaseExceptionObject *)self); +} + +static PyObject * +OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *args = self->args; + PyObject *res = NULL, *tmp; + + /* self->args is only the first two real arguments if there was a + * file name given to OSError. */ + if (PyTuple_GET_SIZE(args) == 2 && self->filename) { + Py_ssize_t size = self->filename2 ? 5 : 3; + args = PyTuple_New(size); + if (!args) + return NULL; + + tmp = PyTuple_GET_ITEM(self->args, 0); + Py_INCREF(tmp); + PyTuple_SET_ITEM(args, 0, tmp); + + tmp = PyTuple_GET_ITEM(self->args, 1); + Py_INCREF(tmp); + PyTuple_SET_ITEM(args, 1, tmp); + + Py_INCREF(self->filename); + PyTuple_SET_ITEM(args, 2, self->filename); + + if (self->filename2) { + /* + * This tuple is essentially used as OSError(*args). + * So, to recreate filename2, we need to pass in + * winerror as well. + */ + Py_INCREF(Py_None); + PyTuple_SET_ITEM(args, 3, Py_None); + + /* filename2 */ + Py_INCREF(self->filename2); + PyTuple_SET_ITEM(args, 4, self->filename2); + } + } else + Py_INCREF(args); + + if (self->dict) + res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict); + else + res = PyTuple_Pack(2, Py_TYPE(self), args); + Py_DECREF(args); + return res; +} + +static PyObject * +OSError_written_get(PyOSErrorObject *self, void *context) +{ + if (self->written == -1) { + PyErr_SetString(PyExc_AttributeError, "characters_written"); + return NULL; + } + return PyLong_FromSsize_t(self->written); +} + +static int +OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context) +{ + if (arg == NULL) { + if (self->written == -1) { + PyErr_SetString(PyExc_AttributeError, "characters_written"); + return -1; + } + self->written = -1; + return 0; + } + Py_ssize_t n; + n = PyNumber_AsSsize_t(arg, PyExc_ValueError); + if (n == -1 && PyErr_Occurred()) + return -1; + self->written = n; + return 0; +} + +static PyMemberDef OSError_members[] = { + {"errno", T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0, + PyDoc_STR("POSIX exception code")}, + {"strerror", T_OBJECT, offsetof(PyOSErrorObject, strerror), 0, + PyDoc_STR("exception strerror")}, + {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0, + PyDoc_STR("exception filename")}, + {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0, + PyDoc_STR("second exception filename")}, +#ifdef MS_WINDOWS + {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0, + PyDoc_STR("Win32 exception code")}, +#endif + {NULL} /* Sentinel */ +}; + +static PyMethodDef OSError_methods[] = { + {"__reduce__", (PyCFunction)OSError_reduce, METH_NOARGS}, + {NULL} +}; + +static PyGetSetDef OSError_getset[] = { + {"characters_written", (getter) OSError_written_get, + (setter) OSError_written_set, NULL}, + {NULL} +}; + + +ComplexExtendsException(PyExc_Exception, OSError, + OSError, OSError_new, + OSError_methods, OSError_members, OSError_getset, + OSError_str, + "Base class for I/O related errors."); + + +/* + * Various OSError subclasses + */ +MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError, + "I/O operation would block."); +MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError, + "Connection error."); +MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError, + "Child process error."); +MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError, + "Broken pipe."); +MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError, + "Connection aborted."); +MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError, + "Connection refused."); +MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError, + "Connection reset."); +MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError, + "File already exists."); +MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError, + "File not found."); +MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError, + "Operation doesn't work on directories."); +MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError, + "Operation only works on directories."); +MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError, + "Interrupted by signal."); +MiddlingExtendsException(PyExc_OSError, PermissionError, OSError, + "Not enough permissions."); +MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError, + "Process not found."); +MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError, + "Timeout expired."); + +/* + * EOFError extends Exception + */ +SimpleExtendsException(PyExc_Exception, EOFError, + "Read beyond end of file."); + + +/* + * RuntimeError extends Exception + */ +SimpleExtendsException(PyExc_Exception, RuntimeError, + "Unspecified run-time error."); + +/* + * RecursionError extends RuntimeError + */ +SimpleExtendsException(PyExc_RuntimeError, RecursionError, + "Recursion limit exceeded."); + +/* + * NotImplementedError extends RuntimeError + */ +SimpleExtendsException(PyExc_RuntimeError, NotImplementedError, + "Method or function hasn't been implemented yet."); + +/* + * NameError extends Exception + */ +SimpleExtendsException(PyExc_Exception, NameError, + "Name not found globally."); + +/* + * UnboundLocalError extends NameError + */ +SimpleExtendsException(PyExc_NameError, UnboundLocalError, + "Local name referenced but not bound to a value."); + +/* + * AttributeError extends Exception + */ +SimpleExtendsException(PyExc_Exception, AttributeError, + "Attribute not found."); + + +/* + * SyntaxError extends Exception + */ + +/* Helper function to customize error message for some syntax errors */ +static int _report_missing_parentheses(PySyntaxErrorObject *self); + +static int +SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *info = NULL; + Py_ssize_t lenargs = PyTuple_GET_SIZE(args); + + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + return -1; + + if (lenargs >= 1) { + Py_INCREF(PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0)); + } + if (lenargs == 2) { + info = PyTuple_GET_ITEM(args, 1); + info = PySequence_Tuple(info); + if (!info) + return -1; + + if (PyTuple_GET_SIZE(info) != 4) { + /* not a very good error message, but it's what Python 2.4 gives */ + PyErr_SetString(PyExc_IndexError, "tuple index out of range"); + Py_DECREF(info); + return -1; + } + + Py_INCREF(PyTuple_GET_ITEM(info, 0)); + Py_XSETREF(self->filename, PyTuple_GET_ITEM(info, 0)); + + Py_INCREF(PyTuple_GET_ITEM(info, 1)); + Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1)); + + Py_INCREF(PyTuple_GET_ITEM(info, 2)); + Py_XSETREF(self->offset, PyTuple_GET_ITEM(info, 2)); + + Py_INCREF(PyTuple_GET_ITEM(info, 3)); + Py_XSETREF(self->text, PyTuple_GET_ITEM(info, 3)); + + Py_DECREF(info); + + /* + * Issue #21669: Custom error for 'print' & 'exec' as statements + * + * Only applies to SyntaxError instances, not to subclasses such + * as TabError or IndentationError (see issue #31161) + */ + if ((PyObject*)Py_TYPE(self) == PyExc_SyntaxError && + self->text && PyUnicode_Check(self->text) && + _report_missing_parentheses(self) < 0) { + return -1; + } + } + return 0; +} + +static int +SyntaxError_clear(PySyntaxErrorObject *self) +{ + Py_CLEAR(self->msg); + Py_CLEAR(self->filename); + Py_CLEAR(self->lineno); + Py_CLEAR(self->offset); + Py_CLEAR(self->text); + Py_CLEAR(self->print_file_and_line); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +SyntaxError_dealloc(PySyntaxErrorObject *self) +{ + _PyObject_GC_UNTRACK(self); + SyntaxError_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->msg); + Py_VISIT(self->filename); + Py_VISIT(self->lineno); + Py_VISIT(self->offset); + Py_VISIT(self->text); + Py_VISIT(self->print_file_and_line); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +/* This is called "my_basename" instead of just "basename" to avoid name + conflicts with glibc; basename is already prototyped if _GNU_SOURCE is + defined, and Python does define that. */ +static PyObject* +my_basename(PyObject *name) +{ + Py_ssize_t i, size, offset; + int kind; + void *data; + + if (PyUnicode_READY(name)) + return NULL; + kind = PyUnicode_KIND(name); + data = PyUnicode_DATA(name); + size = PyUnicode_GET_LENGTH(name); + offset = 0; + for(i=0; i < size; i++) { + if (PyUnicode_READ(kind, data, i) == SEP) + offset = i + 1; + } + if (offset != 0) + return PyUnicode_Substring(name, offset, size); + else { + Py_INCREF(name); + return name; + } +} + + +static PyObject * +SyntaxError_str(PySyntaxErrorObject *self) +{ + int have_lineno = 0; + PyObject *filename; + PyObject *result; + /* Below, we always ignore overflow errors, just printing -1. + Still, we cannot allow an OverflowError to be raised, so + we need to call PyLong_AsLongAndOverflow. */ + int overflow; + + /* XXX -- do all the additional formatting with filename and + lineno here */ + + if (self->filename && PyUnicode_Check(self->filename)) { + filename = my_basename(self->filename); + if (filename == NULL) + return NULL; + } else { + filename = NULL; + } + have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno); + + if (!filename && !have_lineno) + return PyObject_Str(self->msg ? self->msg : Py_None); + + if (filename && have_lineno) + result = PyUnicode_FromFormat("%S (%U, line %ld)", + self->msg ? self->msg : Py_None, + filename, + PyLong_AsLongAndOverflow(self->lineno, &overflow)); + else if (filename) + result = PyUnicode_FromFormat("%S (%U)", + self->msg ? self->msg : Py_None, + filename); + else /* only have_lineno */ + result = PyUnicode_FromFormat("%S (line %ld)", + self->msg ? self->msg : Py_None, + PyLong_AsLongAndOverflow(self->lineno, &overflow)); + Py_XDECREF(filename); + return result; +} + +static PyMemberDef SyntaxError_members[] = { + {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0, + PyDoc_STR("exception msg")}, + {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0, + PyDoc_STR("exception filename")}, + {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0, + PyDoc_STR("exception lineno")}, + {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0, + PyDoc_STR("exception offset")}, + {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0, + PyDoc_STR("exception text")}, + {"print_file_and_line", T_OBJECT, + offsetof(PySyntaxErrorObject, print_file_and_line), 0, + PyDoc_STR("exception print_file_and_line")}, + {NULL} /* Sentinel */ +}; + +ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError, + 0, 0, SyntaxError_members, 0, + SyntaxError_str, "Invalid syntax."); + + +/* + * IndentationError extends SyntaxError + */ +MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError, + "Improper indentation."); + + +/* + * TabError extends IndentationError + */ +MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError, + "Improper mixture of spaces and tabs."); + + +/* + * LookupError extends Exception + */ +SimpleExtendsException(PyExc_Exception, LookupError, + "Base class for lookup errors."); + + +/* + * IndexError extends LookupError + */ +SimpleExtendsException(PyExc_LookupError, IndexError, + "Sequence index out of range."); + + +/* + * KeyError extends LookupError + */ +static PyObject * +KeyError_str(PyBaseExceptionObject *self) +{ + /* If args is a tuple of exactly one item, apply repr to args[0]. + This is done so that e.g. the exception raised by {}[''] prints + KeyError: '' + rather than the confusing + KeyError + alone. The downside is that if KeyError is raised with an explanatory + string, that string will be displayed in quotes. Too bad. + If args is anything else, use the default BaseException__str__(). + */ + if (PyTuple_GET_SIZE(self->args) == 1) { + return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0)); + } + return BaseException_str(self); +} + +ComplexExtendsException(PyExc_LookupError, KeyError, BaseException, + 0, 0, 0, 0, KeyError_str, "Mapping key not found."); + + +/* + * ValueError extends Exception + */ +SimpleExtendsException(PyExc_Exception, ValueError, + "Inappropriate argument value (of correct type)."); + +/* + * UnicodeError extends ValueError + */ + +SimpleExtendsException(PyExc_ValueError, UnicodeError, + "Unicode related error."); + +static PyObject * +get_string(PyObject *attr, const char *name) +{ + if (!attr) { + PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name); + return NULL; + } + + if (!PyBytes_Check(attr)) { + PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name); + return NULL; + } + Py_INCREF(attr); + return attr; +} + +static PyObject * +get_unicode(PyObject *attr, const char *name) +{ + if (!attr) { + PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name); + return NULL; + } + + if (!PyUnicode_Check(attr)) { + PyErr_Format(PyExc_TypeError, + "%.200s attribute must be unicode", name); + return NULL; + } + Py_INCREF(attr); + return attr; +} + +static int +set_unicodefromstring(PyObject **attr, const char *value) +{ + PyObject *obj = PyUnicode_FromString(value); + if (!obj) + return -1; + Py_XSETREF(*attr, obj); + return 0; +} + +PyObject * +PyUnicodeEncodeError_GetEncoding(PyObject *exc) +{ + return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding"); +} + +PyObject * +PyUnicodeDecodeError_GetEncoding(PyObject *exc) +{ + return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding"); +} + +PyObject * +PyUnicodeEncodeError_GetObject(PyObject *exc) +{ + return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object"); +} + +PyObject * +PyUnicodeDecodeError_GetObject(PyObject *exc) +{ + return get_string(((PyUnicodeErrorObject *)exc)->object, "object"); +} + +PyObject * +PyUnicodeTranslateError_GetObject(PyObject *exc) +{ + return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object"); +} + +int +PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start) +{ + Py_ssize_t size; + PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object, + "object"); + if (!obj) + return -1; + *start = ((PyUnicodeErrorObject *)exc)->start; + size = PyUnicode_GET_LENGTH(obj); + if (*start<0) + *start = 0; /*XXX check for values <0*/ + if (*start>=size) + *start = size-1; + Py_DECREF(obj); + return 0; +} + + +int +PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start) +{ + Py_ssize_t size; + PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object"); + if (!obj) + return -1; + size = PyBytes_GET_SIZE(obj); + *start = ((PyUnicodeErrorObject *)exc)->start; + if (*start<0) + *start = 0; + if (*start>=size) + *start = size-1; + Py_DECREF(obj); + return 0; +} + + +int +PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start) +{ + return PyUnicodeEncodeError_GetStart(exc, start); +} + + +int +PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start) +{ + ((PyUnicodeErrorObject *)exc)->start = start; + return 0; +} + + +int +PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start) +{ + ((PyUnicodeErrorObject *)exc)->start = start; + return 0; +} + + +int +PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start) +{ + ((PyUnicodeErrorObject *)exc)->start = start; + return 0; +} + + +int +PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end) +{ + Py_ssize_t size; + PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object, + "object"); + if (!obj) + return -1; + *end = ((PyUnicodeErrorObject *)exc)->end; + size = PyUnicode_GET_LENGTH(obj); + if (*end<1) + *end = 1; + if (*end>size) + *end = size; + Py_DECREF(obj); + return 0; +} + + +int +PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end) +{ + Py_ssize_t size; + PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object"); + if (!obj) + return -1; + size = PyBytes_GET_SIZE(obj); + *end = ((PyUnicodeErrorObject *)exc)->end; + if (*end<1) + *end = 1; + if (*end>size) + *end = size; + Py_DECREF(obj); + return 0; +} + + +int +PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end) +{ + return PyUnicodeEncodeError_GetEnd(exc, end); +} + + +int +PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end) +{ + ((PyUnicodeErrorObject *)exc)->end = end; + return 0; +} + + +int +PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end) +{ + ((PyUnicodeErrorObject *)exc)->end = end; + return 0; +} + + +int +PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end) +{ + ((PyUnicodeErrorObject *)exc)->end = end; + return 0; +} + +PyObject * +PyUnicodeEncodeError_GetReason(PyObject *exc) +{ + return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason"); +} + + +PyObject * +PyUnicodeDecodeError_GetReason(PyObject *exc) +{ + return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason"); +} + + +PyObject * +PyUnicodeTranslateError_GetReason(PyObject *exc) +{ + return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason"); +} + + +int +PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason) +{ + return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason, + reason); +} + + +int +PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason) +{ + return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason, + reason); +} + + +int +PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason) +{ + return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason, + reason); +} + + +static int +UnicodeError_clear(PyUnicodeErrorObject *self) +{ + Py_CLEAR(self->encoding); + Py_CLEAR(self->object); + Py_CLEAR(self->reason); + return BaseException_clear((PyBaseExceptionObject *)self); +} + +static void +UnicodeError_dealloc(PyUnicodeErrorObject *self) +{ + _PyObject_GC_UNTRACK(self); + UnicodeError_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->encoding); + Py_VISIT(self->object); + Py_VISIT(self->reason); + return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); +} + +static PyMemberDef UnicodeError_members[] = { + {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0, + PyDoc_STR("exception encoding")}, + {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0, + PyDoc_STR("exception object")}, + {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0, + PyDoc_STR("exception start")}, + {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0, + PyDoc_STR("exception end")}, + {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0, + PyDoc_STR("exception reason")}, + {NULL} /* Sentinel */ +}; + + +/* + * UnicodeEncodeError extends UnicodeError + */ + +static int +UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyUnicodeErrorObject *err; + + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + return -1; + + err = (PyUnicodeErrorObject *)self; + + Py_CLEAR(err->encoding); + Py_CLEAR(err->object); + Py_CLEAR(err->reason); + + if (!PyArg_ParseTuple(args, "UUnnU", + &err->encoding, &err->object, + &err->start, &err->end, &err->reason)) { + err->encoding = err->object = err->reason = NULL; + return -1; + } + + Py_INCREF(err->encoding); + Py_INCREF(err->object); + Py_INCREF(err->reason); + + return 0; +} + +static PyObject * +UnicodeEncodeError_str(PyObject *self) +{ + PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self; + PyObject *result = NULL; + PyObject *reason_str = NULL; + PyObject *encoding_str = NULL; + + if (!uself->object) + /* Not properly initialized. */ + return PyUnicode_FromString(""); + + /* Get reason and encoding as strings, which they might not be if + they've been modified after we were constructed. */ + reason_str = PyObject_Str(uself->reason); + if (reason_str == NULL) + goto done; + encoding_str = PyObject_Str(uself->encoding); + if (encoding_str == NULL) + goto done; + + if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) { + Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start); + const char *fmt; + if (badchar <= 0xff) + fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U"; + else if (badchar <= 0xffff) + fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U"; + else + fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U"; + result = PyUnicode_FromFormat( + fmt, + encoding_str, + (int)badchar, + uself->start, + reason_str); + } + else { + result = PyUnicode_FromFormat( + "'%U' codec can't encode characters in position %zd-%zd: %U", + encoding_str, + uself->start, + uself->end-1, + reason_str); + } +done: + Py_XDECREF(reason_str); + Py_XDECREF(encoding_str); + return result; +} + +static PyTypeObject _PyExc_UnicodeEncodeError = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnicodeEncodeError", + sizeof(PyUnicodeErrorObject), 0, + (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + (reprfunc)UnicodeEncodeError_str, 0, 0, 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse, + (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members, + 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict), + (initproc)UnicodeEncodeError_init, 0, BaseException_new, +}; +PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError; + +PyObject * +PyUnicodeEncodeError_Create( + const char *encoding, const Py_UNICODE *object, Py_ssize_t length, + Py_ssize_t start, Py_ssize_t end, const char *reason) +{ + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns", + encoding, object, length, start, end, reason); +} + + +/* + * UnicodeDecodeError extends UnicodeError + */ + +static int +UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyUnicodeErrorObject *ude; + + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + return -1; + + ude = (PyUnicodeErrorObject *)self; + + Py_CLEAR(ude->encoding); + Py_CLEAR(ude->object); + Py_CLEAR(ude->reason); + + if (!PyArg_ParseTuple(args, "UOnnU", + &ude->encoding, &ude->object, + &ude->start, &ude->end, &ude->reason)) { + ude->encoding = ude->object = ude->reason = NULL; + return -1; + } + + Py_INCREF(ude->encoding); + Py_INCREF(ude->object); + Py_INCREF(ude->reason); + + if (!PyBytes_Check(ude->object)) { + Py_buffer view; + if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0) + goto error; + Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len)); + PyBuffer_Release(&view); + if (!ude->object) + goto error; + } + return 0; + +error: + Py_CLEAR(ude->encoding); + Py_CLEAR(ude->object); + Py_CLEAR(ude->reason); + return -1; +} + +static PyObject * +UnicodeDecodeError_str(PyObject *self) +{ + PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self; + PyObject *result = NULL; + PyObject *reason_str = NULL; + PyObject *encoding_str = NULL; + + if (!uself->object) + /* Not properly initialized. */ + return PyUnicode_FromString(""); + + /* Get reason and encoding as strings, which they might not be if + they've been modified after we were constructed. */ + reason_str = PyObject_Str(uself->reason); + if (reason_str == NULL) + goto done; + encoding_str = PyObject_Str(uself->encoding); + if (encoding_str == NULL) + goto done; + + if (uself->start < PyBytes_GET_SIZE(uself->object) && uself->end == uself->start+1) { + int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff); + result = PyUnicode_FromFormat( + "'%U' codec can't decode byte 0x%02x in position %zd: %U", + encoding_str, + byte, + uself->start, + reason_str); + } + else { + result = PyUnicode_FromFormat( + "'%U' codec can't decode bytes in position %zd-%zd: %U", + encoding_str, + uself->start, + uself->end-1, + reason_str + ); + } +done: + Py_XDECREF(reason_str); + Py_XDECREF(encoding_str); + return result; +} + +static PyTypeObject _PyExc_UnicodeDecodeError = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnicodeDecodeError", + sizeof(PyUnicodeErrorObject), 0, + (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + (reprfunc)UnicodeDecodeError_str, 0, 0, 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse, + (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members, + 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict), + (initproc)UnicodeDecodeError_init, 0, BaseException_new, +}; +PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError; + +PyObject * +PyUnicodeDecodeError_Create( + const char *encoding, const char *object, Py_ssize_t length, + Py_ssize_t start, Py_ssize_t end, const char *reason) +{ + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", + encoding, object, length, start, end, reason); +} + + +/* + * UnicodeTranslateError extends UnicodeError + */ + +static int +UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args, + PyObject *kwds) +{ + if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) + return -1; + + Py_CLEAR(self->object); + Py_CLEAR(self->reason); + + if (!PyArg_ParseTuple(args, "UnnU", + &self->object, + &self->start, &self->end, &self->reason)) { + self->object = self->reason = NULL; + return -1; + } + + Py_INCREF(self->object); + Py_INCREF(self->reason); + + return 0; +} + + +static PyObject * +UnicodeTranslateError_str(PyObject *self) +{ + PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self; + PyObject *result = NULL; + PyObject *reason_str = NULL; + + if (!uself->object) + /* Not properly initialized. */ + return PyUnicode_FromString(""); + + /* Get reason as a string, which it might not be if it's been + modified after we were constructed. */ + reason_str = PyObject_Str(uself->reason); + if (reason_str == NULL) + goto done; + + if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) { + Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start); + const char *fmt; + if (badchar <= 0xff) + fmt = "can't translate character '\\x%02x' in position %zd: %U"; + else if (badchar <= 0xffff) + fmt = "can't translate character '\\u%04x' in position %zd: %U"; + else + fmt = "can't translate character '\\U%08x' in position %zd: %U"; + result = PyUnicode_FromFormat( + fmt, + (int)badchar, + uself->start, + reason_str + ); + } else { + result = PyUnicode_FromFormat( + "can't translate characters in position %zd-%zd: %U", + uself->start, + uself->end-1, + reason_str + ); + } +done: + Py_XDECREF(reason_str); + return result; +} + +static PyTypeObject _PyExc_UnicodeTranslateError = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnicodeTranslateError", + sizeof(PyUnicodeErrorObject), 0, + (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + (reprfunc)UnicodeTranslateError_str, 0, 0, 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse, + (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members, + 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict), + (initproc)UnicodeTranslateError_init, 0, BaseException_new, +}; +PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError; + +/* Deprecated. */ +PyObject * +PyUnicodeTranslateError_Create( + const Py_UNICODE *object, Py_ssize_t length, + Py_ssize_t start, Py_ssize_t end, const char *reason) +{ + return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns", + object, length, start, end, reason); +} + +PyObject * +_PyUnicodeTranslateError_Create( + PyObject *object, + Py_ssize_t start, Py_ssize_t end, const char *reason) +{ + return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns", + object, start, end, reason); +} + +/* + * AssertionError extends Exception + */ +SimpleExtendsException(PyExc_Exception, AssertionError, + "Assertion failed."); + + +/* + * ArithmeticError extends Exception + */ +SimpleExtendsException(PyExc_Exception, ArithmeticError, + "Base class for arithmetic errors."); + + +/* + * FloatingPointError extends ArithmeticError + */ +SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError, + "Floating point operation failed."); + + +/* + * OverflowError extends ArithmeticError + */ +SimpleExtendsException(PyExc_ArithmeticError, OverflowError, + "Result too large to be represented."); + + +/* + * ZeroDivisionError extends ArithmeticError + */ +SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError, + "Second argument to a division or modulo operation was zero."); + + +/* + * SystemError extends Exception + */ +SimpleExtendsException(PyExc_Exception, SystemError, + "Internal error in the Python interpreter.\n" + "\n" + "Please report this to the Python maintainer, along with the traceback,\n" + "the Python version, and the hardware/OS platform and version."); + + +/* + * ReferenceError extends Exception + */ +SimpleExtendsException(PyExc_Exception, ReferenceError, + "Weak ref proxy used after referent went away."); + + +/* + * MemoryError extends Exception + */ + +#define MEMERRORS_SAVE 16 +static PyBaseExceptionObject *memerrors_freelist = NULL; +static int memerrors_numfree = 0; + +static PyObject * +MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyBaseExceptionObject *self; + + /* If this is a subclass of MemoryError, don't use the freelist + * and just return a fresh object */ + if (type != (PyTypeObject *) PyExc_MemoryError) { + return BaseException_new(type, args, kwds); + } + + if (memerrors_freelist == NULL) + return BaseException_new(type, args, kwds); + /* Fetch object from freelist and revive it */ + self = memerrors_freelist; + self->args = PyTuple_New(0); + /* This shouldn't happen since the empty tuple is persistent */ + if (self->args == NULL) + return NULL; + memerrors_freelist = (PyBaseExceptionObject *) self->dict; + memerrors_numfree--; + self->dict = NULL; + _Py_NewReference((PyObject *)self); + _PyObject_GC_TRACK(self); + return (PyObject *)self; +} + +static void +MemoryError_dealloc(PyBaseExceptionObject *self) +{ + BaseException_clear(self); + + if (Py_TYPE(self) != (PyTypeObject *)PyExc_MemoryError) { + Py_TYPE(self)->tp_free((PyObject *)self); + return; + } + + _PyObject_GC_UNTRACK(self); + + if (memerrors_numfree >= MEMERRORS_SAVE) + Py_TYPE(self)->tp_free((PyObject *)self); + else { + self->dict = (PyObject *) memerrors_freelist; + memerrors_freelist = self; + memerrors_numfree++; + } +} + +static int +preallocate_memerrors(void) +{ + /* We create enough MemoryErrors and then decref them, which will fill + up the freelist. */ + int i; + PyObject *errors[MEMERRORS_SAVE]; + for (i = 0; i < MEMERRORS_SAVE; i++) { + errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError, + NULL, NULL); + if (!errors[i]) { + return -1; + } + } + for (i = 0; i < MEMERRORS_SAVE; i++) { + Py_DECREF(errors[i]); + } + return 0; +} + +static void +free_preallocated_memerrors(void) +{ + while (memerrors_freelist != NULL) { + PyObject *self = (PyObject *) memerrors_freelist; + memerrors_freelist = (PyBaseExceptionObject *) memerrors_freelist->dict; + Py_TYPE(self)->tp_free((PyObject *)self); + } +} + + +static PyTypeObject _PyExc_MemoryError = { + PyVarObject_HEAD_INIT(NULL, 0) + "MemoryError", + sizeof(PyBaseExceptionObject), + 0, (destructor)MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + PyDoc_STR("Out of memory."), (traverseproc)BaseException_traverse, + (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception, + 0, 0, 0, offsetof(PyBaseExceptionObject, dict), + (initproc)BaseException_init, 0, MemoryError_new +}; +PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError; + + +/* + * BufferError extends Exception + */ +SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error."); + + +/* Warning category docstrings */ + +/* + * Warning extends Exception + */ +SimpleExtendsException(PyExc_Exception, Warning, + "Base class for warning categories."); + + +/* + * UserWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, UserWarning, + "Base class for warnings generated by user code."); + + +/* + * DeprecationWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, DeprecationWarning, + "Base class for warnings about deprecated features."); + + +/* + * PendingDeprecationWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning, + "Base class for warnings about features which will be deprecated\n" + "in the future."); + + +/* + * SyntaxWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, SyntaxWarning, + "Base class for warnings about dubious syntax."); + + +/* + * RuntimeWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, RuntimeWarning, + "Base class for warnings about dubious runtime behavior."); + + +/* + * FutureWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, FutureWarning, + "Base class for warnings about constructs that will change semantically\n" + "in the future."); + + +/* + * ImportWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, ImportWarning, + "Base class for warnings about probable mistakes in module imports"); + + +/* + * UnicodeWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, UnicodeWarning, + "Base class for warnings about Unicode related problems, mostly\n" + "related to conversion problems."); + + +/* + * BytesWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, BytesWarning, + "Base class for warnings about bytes and buffer related problems, mostly\n" + "related to conversion from str or comparing to str."); + + +/* + * ResourceWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, ResourceWarning, + "Base class for warnings about resource usage."); + + + +#ifdef MS_WINDOWS +#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 + +#if defined(WSAEALREADY) && !defined(EALREADY) +#define EALREADY WSAEALREADY +#endif +#if defined(WSAECONNABORTED) && !defined(ECONNABORTED) +#define ECONNABORTED WSAECONNABORTED +#endif +#if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED) +#define ECONNREFUSED WSAECONNREFUSED +#endif +#if defined(WSAECONNRESET) && !defined(ECONNRESET) +#define ECONNRESET WSAECONNRESET +#endif +#if defined(WSAEINPROGRESS) && !defined(EINPROGRESS) +#define EINPROGRESS WSAEINPROGRESS +#endif +#if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN) +#define ESHUTDOWN WSAESHUTDOWN +#endif +#if defined(WSAETIMEDOUT) && !defined(ETIMEDOUT) +#define ETIMEDOUT WSAETIMEDOUT +#endif +#if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK) +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif +#endif /* MS_WINDOWS */ + +PyStatus +_PyExc_Init(void) +{ +#define PRE_INIT(TYPE) \ + if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ + if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \ + return _PyStatus_ERR("exceptions bootstrapping error."); \ + } \ + Py_INCREF(PyExc_ ## TYPE); \ + } + +#define ADD_ERRNO(TYPE, CODE) \ + do { \ + PyObject *_code = PyLong_FromLong(CODE); \ + assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \ + if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) { \ + Py_XDECREF(_code); \ + return _PyStatus_ERR("errmap insertion problem."); \ + } \ + Py_DECREF(_code); \ + } while (0) + + PRE_INIT(BaseException); + PRE_INIT(Exception); + PRE_INIT(TypeError); + PRE_INIT(StopAsyncIteration); + PRE_INIT(StopIteration); + PRE_INIT(GeneratorExit); + PRE_INIT(SystemExit); + PRE_INIT(KeyboardInterrupt); + PRE_INIT(ImportError); + PRE_INIT(ModuleNotFoundError); + PRE_INIT(OSError); + PRE_INIT(EOFError); + PRE_INIT(RuntimeError); + PRE_INIT(RecursionError); + PRE_INIT(NotImplementedError); + PRE_INIT(NameError); + PRE_INIT(UnboundLocalError); + PRE_INIT(AttributeError); + PRE_INIT(SyntaxError); + PRE_INIT(IndentationError); + PRE_INIT(TabError); + PRE_INIT(LookupError); + PRE_INIT(IndexError); + PRE_INIT(KeyError); + PRE_INIT(ValueError); + PRE_INIT(UnicodeError); + PRE_INIT(UnicodeEncodeError); + PRE_INIT(UnicodeDecodeError); + PRE_INIT(UnicodeTranslateError); + PRE_INIT(AssertionError); + PRE_INIT(ArithmeticError); + PRE_INIT(FloatingPointError); + PRE_INIT(OverflowError); + PRE_INIT(ZeroDivisionError); + PRE_INIT(SystemError); + PRE_INIT(ReferenceError); + PRE_INIT(MemoryError); + PRE_INIT(BufferError); + PRE_INIT(Warning); + PRE_INIT(UserWarning); + PRE_INIT(DeprecationWarning); + PRE_INIT(PendingDeprecationWarning); + PRE_INIT(SyntaxWarning); + PRE_INIT(RuntimeWarning); + PRE_INIT(FutureWarning); + PRE_INIT(ImportWarning); + PRE_INIT(UnicodeWarning); + PRE_INIT(BytesWarning); + PRE_INIT(ResourceWarning); + + /* OSError subclasses */ + PRE_INIT(ConnectionError); + + PRE_INIT(BlockingIOError); + PRE_INIT(BrokenPipeError); + PRE_INIT(ChildProcessError); + PRE_INIT(ConnectionAbortedError); + PRE_INIT(ConnectionRefusedError); + PRE_INIT(ConnectionResetError); + PRE_INIT(FileExistsError); + PRE_INIT(FileNotFoundError); + PRE_INIT(IsADirectoryError); + PRE_INIT(NotADirectoryError); + PRE_INIT(InterruptedError); + PRE_INIT(PermissionError); + PRE_INIT(ProcessLookupError); + PRE_INIT(TimeoutError); + + if (preallocate_memerrors() < 0) { + return _PyStatus_ERR("Could not preallocate MemoryError object"); + } + + /* Add exceptions to errnomap */ + if (!errnomap) { + errnomap = PyDict_New(); + if (!errnomap) { + return _PyStatus_ERR("Cannot allocate map from errnos to OSError subclasses"); + } + } + + ADD_ERRNO(BlockingIOError, EAGAIN); + ADD_ERRNO(BlockingIOError, EALREADY); + ADD_ERRNO(BlockingIOError, EINPROGRESS); + ADD_ERRNO(BlockingIOError, EWOULDBLOCK); + ADD_ERRNO(BrokenPipeError, EPIPE); +#ifdef ESHUTDOWN + ADD_ERRNO(BrokenPipeError, ESHUTDOWN); +#endif + ADD_ERRNO(ChildProcessError, ECHILD); + ADD_ERRNO(ConnectionAbortedError, ECONNABORTED); + ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED); + ADD_ERRNO(ConnectionResetError, ECONNRESET); + ADD_ERRNO(FileExistsError, EEXIST); + ADD_ERRNO(FileNotFoundError, ENOENT); + ADD_ERRNO(IsADirectoryError, EISDIR); + ADD_ERRNO(NotADirectoryError, ENOTDIR); + ADD_ERRNO(InterruptedError, EINTR); + ADD_ERRNO(PermissionError, EACCES); + ADD_ERRNO(PermissionError, EPERM); + ADD_ERRNO(ProcessLookupError, ESRCH); + ADD_ERRNO(TimeoutError, ETIMEDOUT); + + return _PyStatus_OK(); + +#undef PRE_INIT +#undef ADD_ERRNO +} + + +/* Add exception types to the builtins module */ +PyStatus +_PyBuiltins_AddExceptions(PyObject *bltinmod) +{ +#define POST_INIT(TYPE) \ + if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \ + return _PyStatus_ERR("Module dictionary insertion problem."); \ + } + +#define INIT_ALIAS(NAME, TYPE) \ + do { \ + Py_INCREF(PyExc_ ## TYPE); \ + Py_XDECREF(PyExc_ ## NAME); \ + PyExc_ ## NAME = PyExc_ ## TYPE; \ + if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \ + return _PyStatus_ERR("Module dictionary insertion problem."); \ + } \ + } while (0) + + PyObject *bdict; + + bdict = PyModule_GetDict(bltinmod); + if (bdict == NULL) { + return _PyStatus_ERR("exceptions bootstrapping error."); + } + + POST_INIT(BaseException); + POST_INIT(Exception); + POST_INIT(TypeError); + POST_INIT(StopAsyncIteration); + POST_INIT(StopIteration); + POST_INIT(GeneratorExit); + POST_INIT(SystemExit); + POST_INIT(KeyboardInterrupt); + POST_INIT(ImportError); + POST_INIT(ModuleNotFoundError); + POST_INIT(OSError); + INIT_ALIAS(EnvironmentError, OSError); + INIT_ALIAS(IOError, OSError); +#ifdef MS_WINDOWS + INIT_ALIAS(WindowsError, OSError); +#endif + POST_INIT(EOFError); + POST_INIT(RuntimeError); + POST_INIT(RecursionError); + POST_INIT(NotImplementedError); + POST_INIT(NameError); + POST_INIT(UnboundLocalError); + POST_INIT(AttributeError); + POST_INIT(SyntaxError); + POST_INIT(IndentationError); + POST_INIT(TabError); + POST_INIT(LookupError); + POST_INIT(IndexError); + POST_INIT(KeyError); + POST_INIT(ValueError); + POST_INIT(UnicodeError); + POST_INIT(UnicodeEncodeError); + POST_INIT(UnicodeDecodeError); + POST_INIT(UnicodeTranslateError); + POST_INIT(AssertionError); + POST_INIT(ArithmeticError); + POST_INIT(FloatingPointError); + POST_INIT(OverflowError); + POST_INIT(ZeroDivisionError); + POST_INIT(SystemError); + POST_INIT(ReferenceError); + POST_INIT(MemoryError); + POST_INIT(BufferError); + POST_INIT(Warning); + POST_INIT(UserWarning); + POST_INIT(DeprecationWarning); + POST_INIT(PendingDeprecationWarning); + POST_INIT(SyntaxWarning); + POST_INIT(RuntimeWarning); + POST_INIT(FutureWarning); + POST_INIT(ImportWarning); + POST_INIT(UnicodeWarning); + POST_INIT(BytesWarning); + POST_INIT(ResourceWarning); + + /* OSError subclasses */ + POST_INIT(ConnectionError); + + POST_INIT(BlockingIOError); + POST_INIT(BrokenPipeError); + POST_INIT(ChildProcessError); + POST_INIT(ConnectionAbortedError); + POST_INIT(ConnectionRefusedError); + POST_INIT(ConnectionResetError); + POST_INIT(FileExistsError); + POST_INIT(FileNotFoundError); + POST_INIT(IsADirectoryError); + POST_INIT(NotADirectoryError); + POST_INIT(InterruptedError); + POST_INIT(PermissionError); + POST_INIT(ProcessLookupError); + POST_INIT(TimeoutError); + + return _PyStatus_OK(); + +#undef POST_INIT +#undef INIT_ALIAS +} + +void +_PyExc_Fini(void) +{ + free_preallocated_memerrors(); + Py_CLEAR(errnomap); +} + +/* Helper to do the equivalent of "raise X from Y" in C, but always using + * the current exception rather than passing one in. + * + * We currently limit this to *only* exceptions that use the BaseException + * tp_init and tp_new methods, since we can be reasonably sure we can wrap + * those correctly without losing data and without losing backwards + * compatibility. + * + * We also aim to rule out *all* exceptions that might be storing additional + * state, whether by having a size difference relative to BaseException, + * additional arguments passed in during construction or by having a + * non-empty instance dict. + * + * We need to be very careful with what we wrap, since changing types to + * a broader exception type would be backwards incompatible for + * existing codecs, and with different init or new method implementations + * may either not support instantiation with PyErr_Format or lose + * information when instantiated that way. + * + * XXX (ncoghlan): This could be made more comprehensive by exploiting the + * fact that exceptions are expected to support pickling. If more builtin + * exceptions (e.g. AttributeError) start to be converted to rich + * exceptions with additional attributes, that's probably a better approach + * to pursue over adding special cases for particular stateful subclasses. + * + * Returns a borrowed reference to the new exception (if any), NULL if the + * existing exception was left in place. + */ +PyObject * +_PyErr_TrySetFromCause(const char *format, ...) +{ + PyObject* msg_prefix; + PyObject *exc, *val, *tb; + PyTypeObject *caught_type; + PyObject **dictptr; + PyObject *instance_args; + Py_ssize_t num_args, caught_type_size, base_exc_size; + PyObject *new_exc, *new_val, *new_tb; + va_list vargs; + int same_basic_size; + + PyErr_Fetch(&exc, &val, &tb); + caught_type = (PyTypeObject *)exc; + /* Ensure type info indicates no extra state is stored at the C level + * and that the type can be reinstantiated using PyErr_Format + */ + caught_type_size = caught_type->tp_basicsize; + base_exc_size = _PyExc_BaseException.tp_basicsize; + same_basic_size = ( + caught_type_size == base_exc_size || + (PyType_SUPPORTS_WEAKREFS(caught_type) && + (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *)) + ) + ); + if (caught_type->tp_init != (initproc)BaseException_init || + caught_type->tp_new != BaseException_new || + !same_basic_size || + caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) { + /* We can't be sure we can wrap this safely, since it may contain + * more state than just the exception type. Accordingly, we just + * leave it alone. + */ + PyErr_Restore(exc, val, tb); + return NULL; + } + + /* Check the args are empty or contain a single string */ + PyErr_NormalizeException(&exc, &val, &tb); + instance_args = ((PyBaseExceptionObject *)val)->args; + num_args = PyTuple_GET_SIZE(instance_args); + if (num_args > 1 || + (num_args == 1 && + !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) { + /* More than 1 arg, or the one arg we do have isn't a string + */ + PyErr_Restore(exc, val, tb); + return NULL; + } + + /* Ensure the instance dict is also empty */ + dictptr = _PyObject_GetDictPtr(val); + if (dictptr != NULL && *dictptr != NULL && + PyDict_GET_SIZE(*dictptr) > 0) { + /* While we could potentially copy a non-empty instance dictionary + * to the replacement exception, for now we take the more + * conservative path of leaving exceptions with attributes set + * alone. + */ + PyErr_Restore(exc, val, tb); + return NULL; + } + + /* For exceptions that we can wrap safely, we chain the original + * exception to a new one of the exact same type with an + * error message that mentions the additional details and the + * original exception. + * + * It would be nice to wrap OSError and various other exception + * types as well, but that's quite a bit trickier due to the extra + * state potentially stored on OSError instances. + */ + /* Ensure the traceback is set correctly on the existing exception */ + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + msg_prefix = PyUnicode_FromFormatV(format, vargs); + va_end(vargs); + if (msg_prefix == NULL) { + Py_DECREF(exc); + Py_DECREF(val); + return NULL; + } + + PyErr_Format(exc, "%U (%s: %S)", + msg_prefix, Py_TYPE(val)->tp_name, val); + Py_DECREF(exc); + Py_DECREF(msg_prefix); + PyErr_Fetch(&new_exc, &new_val, &new_tb); + PyErr_NormalizeException(&new_exc, &new_val, &new_tb); + PyException_SetCause(new_val, val); + PyErr_Restore(new_exc, new_val, new_tb); + return new_val; +} + + +/* To help with migration from Python 2, SyntaxError.__init__ applies some + * heuristics to try to report a more meaningful exception when print and + * exec are used like statements. + * + * The heuristics are currently expected to detect the following cases: + * - top level statement + * - statement in a nested suite + * - trailing section of a one line complex statement + * + * They're currently known not to trigger: + * - after a semi-colon + * + * The error message can be a bit odd in cases where the "arguments" are + * completely illegal syntactically, but that isn't worth the hassle of + * fixing. + * + * We also can't do anything about cases that are legal Python 3 syntax + * but mean something entirely different from what they did in Python 2 + * (omitting the arguments entirely, printing items preceded by a unary plus + * or minus, using the stream redirection syntax). + */ + + +// Static helper for setting legacy print error message +static int +_set_legacy_print_statement_msg(PySyntaxErrorObject *self, Py_ssize_t start) +{ + // PRINT_OFFSET is to remove the `print ` prefix from the data. + const int PRINT_OFFSET = 6; + const int STRIP_BOTH = 2; + Py_ssize_t start_pos = start + PRINT_OFFSET; + Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text); + Py_UCS4 semicolon = ';'; + Py_ssize_t end_pos = PyUnicode_FindChar(self->text, semicolon, + start_pos, text_len, 1); + if (end_pos < -1) { + return -1; + } else if (end_pos == -1) { + end_pos = text_len; + } + + PyObject *data = PyUnicode_Substring(self->text, start_pos, end_pos); + if (data == NULL) { + return -1; + } + + PyObject *strip_sep_obj = PyUnicode_FromString(" \t\r\n"); + if (strip_sep_obj == NULL) { + Py_DECREF(data); + return -1; + } + + PyObject *new_data = _PyUnicode_XStrip(data, STRIP_BOTH, strip_sep_obj); + Py_DECREF(data); + Py_DECREF(strip_sep_obj); + if (new_data == NULL) { + return -1; + } + // gets the modified text_len after stripping `print ` + text_len = PyUnicode_GET_LENGTH(new_data); + const char *maybe_end_arg = ""; + if (text_len > 0 && PyUnicode_READ_CHAR(new_data, text_len-1) == ',') { + maybe_end_arg = " end=\" \""; + } + PyObject *error_msg = PyUnicode_FromFormat( + "Missing parentheses in call to 'print'. Did you mean print(%U%s)?", + new_data, maybe_end_arg + ); + Py_DECREF(new_data); + if (error_msg == NULL) + return -1; + + Py_XSETREF(self->msg, error_msg); + return 1; +} + +static int +_check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start) +{ + /* Return values: + * -1: an error occurred + * 0: nothing happened + * 1: the check triggered & the error message was changed + */ + static PyObject *print_prefix = NULL; + static PyObject *exec_prefix = NULL; + Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text), match; + int kind = PyUnicode_KIND(self->text); + void *data = PyUnicode_DATA(self->text); + + /* Ignore leading whitespace */ + while (start < text_len) { + Py_UCS4 ch = PyUnicode_READ(kind, data, start); + if (!Py_UNICODE_ISSPACE(ch)) + break; + start++; + } + /* Checking against an empty or whitespace-only part of the string */ + if (start == text_len) { + return 0; + } + + /* Check for legacy print statements */ + if (print_prefix == NULL) { + print_prefix = PyUnicode_InternFromString("print "); + if (print_prefix == NULL) { + return -1; + } + } + match = PyUnicode_Tailmatch(self->text, print_prefix, + start, text_len, -1); + if (match == -1) { + return -1; + } + if (match) { + return _set_legacy_print_statement_msg(self, start); + } + + /* Check for legacy exec statements */ + if (exec_prefix == NULL) { + exec_prefix = PyUnicode_InternFromString("exec "); + if (exec_prefix == NULL) { + return -1; + } + } + match = PyUnicode_Tailmatch(self->text, exec_prefix, start, text_len, -1); + if (match == -1) { + return -1; + } + if (match) { + PyObject *msg = PyUnicode_FromString("Missing parentheses in call " + "to 'exec'"); + if (msg == NULL) { + return -1; + } + Py_XSETREF(self->msg, msg); + return 1; + } + /* Fall back to the default error message */ + return 0; +} + +static int +_report_missing_parentheses(PySyntaxErrorObject *self) +{ + Py_UCS4 left_paren = 40; + Py_ssize_t left_paren_index; + Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text); + int legacy_check_result = 0; + + /* Skip entirely if there is an opening parenthesis */ + left_paren_index = PyUnicode_FindChar(self->text, left_paren, + 0, text_len, 1); + if (left_paren_index < -1) { + return -1; + } + if (left_paren_index != -1) { + /* Use default error message for any line with an opening paren */ + return 0; + } + /* Handle the simple statement case */ + legacy_check_result = _check_for_legacy_statements(self, 0); + if (legacy_check_result < 0) { + return -1; + + } + if (legacy_check_result == 0) { + /* Handle the one-line complex statement case */ + Py_UCS4 colon = 58; + Py_ssize_t colon_index; + colon_index = PyUnicode_FindChar(self->text, colon, + 0, text_len, 1); + if (colon_index < -1) { + return -1; + } + if (colon_index >= 0 && colon_index < text_len) { + /* Check again, starting from just after the colon */ + if (_check_for_legacy_statements(self, colon_index+1) < 0) { + return -1; + } + } + } + return 0; +} diff --git a/python/Objects/fileobject.c b/python/Objects/fileobject.c new file mode 100755 index 0000000..dd42d51 --- /dev/null +++ b/python/Objects/fileobject.c @@ -0,0 +1,589 @@ +/* File object implementation (what's left of it -- see io.py) */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "pycore_pystate.h" + +#if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER) +/* clang MemorySanitizer doesn't yet understand getc_unlocked. */ +#define GETC(f) getc_unlocked(f) +#define FLOCKFILE(f) flockfile(f) +#define FUNLOCKFILE(f) funlockfile(f) +#else +#define GETC(f) getc(f) +#define FLOCKFILE(f) +#define FUNLOCKFILE(f) +#endif + +/* Newline flags */ +#define NEWLINE_UNKNOWN 0 /* No newline seen, yet */ +#define NEWLINE_CR 1 /* \r newline seen */ +#define NEWLINE_LF 2 /* \n newline seen */ +#define NEWLINE_CRLF 4 /* \r\n newline seen */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* External C interface */ + +PyObject * +PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, + const char *errors, const char *newline, int closefd) +{ + PyObject *io, *stream; + _Py_IDENTIFIER(open); + + /* import _io in case we are being used to open io.py */ + io = PyImport_ImportModule("_io"); + if (io == NULL) + return NULL; + stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode, + buffering, encoding, errors, + newline, closefd); + Py_DECREF(io); + if (stream == NULL) + return NULL; + /* ignore name attribute because the name attribute of _BufferedIOMixin + and TextIOWrapper is read only */ + return stream; +} + +PyObject * +PyFile_GetLine(PyObject *f, int n) +{ + _Py_IDENTIFIER(readline); + PyObject *result; + + if (f == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + if (n <= 0) { + result = _PyObject_CallMethodIdObjArgs(f, &PyId_readline, NULL); + } + else { + result = _PyObject_CallMethodId(f, &PyId_readline, "i", n); + } + if (result != NULL && !PyBytes_Check(result) && + !PyUnicode_Check(result)) { + Py_DECREF(result); + result = NULL; + PyErr_SetString(PyExc_TypeError, + "object.readline() returned non-string"); + } + + if (n < 0 && result != NULL && PyBytes_Check(result)) { + char *s = PyBytes_AS_STRING(result); + Py_ssize_t len = PyBytes_GET_SIZE(result); + if (len == 0) { + Py_DECREF(result); + result = NULL; + PyErr_SetString(PyExc_EOFError, + "EOF when reading a line"); + } + else if (s[len-1] == '\n') { + if (result->ob_refcnt == 1) + _PyBytes_Resize(&result, len-1); + else { + PyObject *v; + v = PyBytes_FromStringAndSize(s, len-1); + Py_DECREF(result); + result = v; + } + } + } + if (n < 0 && result != NULL && PyUnicode_Check(result)) { + Py_ssize_t len = PyUnicode_GET_LENGTH(result); + if (len == 0) { + Py_DECREF(result); + result = NULL; + PyErr_SetString(PyExc_EOFError, + "EOF when reading a line"); + } + else if (PyUnicode_READ_CHAR(result, len-1) == '\n') { + PyObject *v; + v = PyUnicode_Substring(result, 0, len-1); + Py_DECREF(result); + result = v; + } + } + return result; +} + +/* Interfaces to write objects/strings to file-like objects */ + +int +PyFile_WriteObject(PyObject *v, PyObject *f, int flags) +{ + PyObject *writer, *value, *result; + _Py_IDENTIFIER(write); + + if (f == NULL) { + PyErr_SetString(PyExc_TypeError, "writeobject with NULL file"); + return -1; + } + writer = _PyObject_GetAttrId(f, &PyId_write); + if (writer == NULL) + return -1; + if (flags & Py_PRINT_RAW) { + value = PyObject_Str(v); + } + else + value = PyObject_Repr(v); + if (value == NULL) { + Py_DECREF(writer); + return -1; + } + result = PyObject_CallFunctionObjArgs(writer, value, NULL); + Py_DECREF(value); + Py_DECREF(writer); + if (result == NULL) + return -1; + Py_DECREF(result); + return 0; +} + +int +PyFile_WriteString(const char *s, PyObject *f) +{ + if (f == NULL) { + /* Should be caused by a pre-existing error */ + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_SystemError, + "null file for PyFile_WriteString"); + return -1; + } + else if (!PyErr_Occurred()) { + PyObject *v = PyUnicode_FromString(s); + int err; + if (v == NULL) + return -1; + err = PyFile_WriteObject(v, f, Py_PRINT_RAW); + Py_DECREF(v); + return err; + } + else + return -1; +} + +/* Try to get a file-descriptor from a Python object. If the object + is an integer, its value is returned. If not, the + object's fileno() method is called if it exists; the method must return + an integer, which is returned as the file descriptor value. + -1 is returned on failure. +*/ + +int +PyObject_AsFileDescriptor(PyObject *o) +{ + int fd; + PyObject *meth; + _Py_IDENTIFIER(fileno); + + if (PyLong_Check(o)) { + fd = _PyLong_AsInt(o); + } + else if (_PyObject_LookupAttrId(o, &PyId_fileno, &meth) < 0) { + return -1; + } + else if (meth != NULL) { + PyObject *fno = _PyObject_CallNoArg(meth); + Py_DECREF(meth); + if (fno == NULL) + return -1; + + if (PyLong_Check(fno)) { + fd = _PyLong_AsInt(fno); + Py_DECREF(fno); + } + else { + PyErr_SetString(PyExc_TypeError, + "fileno() returned a non-integer"); + Py_DECREF(fno); + return -1; + } + } + else { + PyErr_SetString(PyExc_TypeError, + "argument must be an int, or have a fileno() method."); + return -1; + } + + if (fd == -1 && PyErr_Occurred()) + return -1; + if (fd < 0) { + PyErr_Format(PyExc_ValueError, + "file descriptor cannot be a negative integer (%i)", + fd); + return -1; + } + return fd; +} + +/* +** Py_UniversalNewlineFgets is an fgets variation that understands +** all of \r, \n and \r\n conventions. +** The stream should be opened in binary mode. +** If fobj is NULL the routine always does newline conversion, and +** it may peek one char ahead to gobble the second char in \r\n. +** If fobj is non-NULL it must be a PyFileObject. In this case there +** is no readahead but in stead a flag is used to skip a following +** \n on the next read. Also, if the file is open in binary mode +** the whole conversion is skipped. Finally, the routine keeps track of +** the different types of newlines seen. +** Note that we need no error handling: fgets() treats error and eof +** identically. +*/ +char * +Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) +{ + char *p = buf; + int c; + int newlinetypes = 0; + int skipnextlf = 0; + + if (fobj) { + errno = ENXIO; /* What can you do... */ + return NULL; + } + FLOCKFILE(stream); + c = 'x'; /* Shut up gcc warning */ + while (--n > 0 && (c = GETC(stream)) != EOF ) { + if (skipnextlf ) { + skipnextlf = 0; + if (c == '\n') { + /* Seeing a \n here with skipnextlf true + ** means we saw a \r before. + */ + newlinetypes |= NEWLINE_CRLF; + c = GETC(stream); + if (c == EOF) break; + } else { + /* + ** Note that c == EOF also brings us here, + ** so we're okay if the last char in the file + ** is a CR. + */ + newlinetypes |= NEWLINE_CR; + } + } + if (c == '\r') { + /* A \r is translated into a \n, and we skip + ** an adjacent \n, if any. We don't set the + ** newlinetypes flag until we've seen the next char. + */ + skipnextlf = 1; + c = '\n'; + } else if ( c == '\n') { + newlinetypes |= NEWLINE_LF; + } + *p++ = c; + if (c == '\n') break; + } + /* if ( c == EOF && skipnextlf ) + newlinetypes |= NEWLINE_CR; */ + FUNLOCKFILE(stream); + *p = '\0'; + if ( skipnextlf ) { + /* If we have no file object we cannot save the + ** skipnextlf flag. We have to readahead, which + ** will cause a pause if we're reading from an + ** interactive stream, but that is very unlikely + ** unless we're doing something silly like + ** exec(open("/dev/tty").read()). + */ + c = GETC(stream); + if ( c != '\n' ) + ungetc(c, stream); + } + if (p == buf) + return NULL; + return buf; +} + +/* **************************** std printer **************************** + * The stdprinter is used during the boot strapping phase as a preliminary + * file like object for sys.stderr. + */ + +typedef struct { + PyObject_HEAD + int fd; +} PyStdPrinter_Object; + +static PyObject * +stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews) +{ + PyStdPrinter_Object *self; + + assert(type != NULL && type->tp_alloc != NULL); + + self = (PyStdPrinter_Object *) type->tp_alloc(type, 0); + if (self != NULL) { + self->fd = -1; + } + + return (PyObject *) self; +} + +static int +stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyErr_SetString(PyExc_TypeError, + "cannot create 'stderrprinter' instances"); + return -1; +} + +PyObject * +PyFile_NewStdPrinter(int fd) +{ + PyStdPrinter_Object *self; + + if (fd != fileno(stdout) && fd != fileno(stderr)) { + /* not enough infrastructure for PyErr_BadInternalCall() */ + return NULL; + } + + self = PyObject_New(PyStdPrinter_Object, + &PyStdPrinter_Type); + if (self != NULL) { + self->fd = fd; + } + return (PyObject*)self; +} + +static PyObject * +stdprinter_write(PyStdPrinter_Object *self, PyObject *args) +{ + PyObject *unicode; + PyObject *bytes = NULL; + const char *str; + Py_ssize_t n; + int err; + + /* The function can clear the current exception */ + assert(!PyErr_Occurred()); + + if (self->fd < 0) { + /* fd might be invalid on Windows + * I can't raise an exception here. It may lead to an + * unlimited recursion in the case stderr is invalid. + */ + Py_RETURN_NONE; + } + + if (!PyArg_ParseTuple(args, "U", &unicode)) { + return NULL; + } + + /* Encode Unicode to UTF-8/surrogateescape */ + str = PyUnicode_AsUTF8AndSize(unicode, &n); + if (str == NULL) { + PyErr_Clear(); + bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace"); + if (bytes == NULL) + return NULL; + str = PyBytes_AS_STRING(bytes); + n = PyBytes_GET_SIZE(bytes); + } + + n = _Py_write(self->fd, str, n); + /* save errno, it can be modified indirectly by Py_XDECREF() */ + err = errno; + + Py_XDECREF(bytes); + + if (n == -1) { + if (err == EAGAIN) { + PyErr_Clear(); + Py_RETURN_NONE; + } + return NULL; + } + + return PyLong_FromSsize_t(n); +} + +static PyObject * +stdprinter_fileno(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) +{ + return PyLong_FromLong((long) self->fd); +} + +static PyObject * +stdprinter_repr(PyStdPrinter_Object *self) +{ + return PyUnicode_FromFormat("", + self->fd, self); +} + +static PyObject * +stdprinter_noop(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) +{ + Py_RETURN_NONE; +} + +static PyObject * +stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) +{ + long res; + if (self->fd < 0) { + Py_RETURN_FALSE; + } + + Py_BEGIN_ALLOW_THREADS + res = isatty(self->fd); + Py_END_ALLOW_THREADS + + return PyBool_FromLong(res); +} + +static PyMethodDef stdprinter_methods[] = { + {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""}, + {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""}, + {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""}, + {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""}, + {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""}, + {NULL, NULL} /*sentinel */ +}; + +static PyObject * +get_closed(PyStdPrinter_Object *self, void *closure) +{ + Py_RETURN_FALSE; +} + +static PyObject * +get_mode(PyStdPrinter_Object *self, void *closure) +{ + return PyUnicode_FromString("w"); +} + +static PyObject * +get_encoding(PyStdPrinter_Object *self, void *closure) +{ + Py_RETURN_NONE; +} + +static PyGetSetDef stdprinter_getsetlist[] = { + {"closed", (getter)get_closed, NULL, "True if the file is closed"}, + {"encoding", (getter)get_encoding, NULL, "Encoding of the file"}, + {"mode", (getter)get_mode, NULL, "String giving the file mode"}, + {0}, +}; + +PyTypeObject PyStdPrinter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "stderrprinter", /* tp_name */ + sizeof(PyStdPrinter_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)stdprinter_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + stdprinter_methods, /* tp_methods */ + 0, /* tp_members */ + stdprinter_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + stdprinter_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + stdprinter_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + +/* ************************** open_code hook *************************** + * The open_code hook allows embedders to override the method used to + * open files that are going to be used by the runtime to execute code + */ + +int +PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) { + if (Py_IsInitialized() && + PySys_Audit("setopencodehook", NULL) < 0) { + return -1; + } + + if (_PyRuntime.open_code_hook) { + if (Py_IsInitialized()) { + PyErr_SetString(PyExc_SystemError, + "failed to change existing open_code hook"); + } + return -1; + } + + _PyRuntime.open_code_hook = hook; + _PyRuntime.open_code_userdata = userData; + return 0; +} + +PyObject * +PyFile_OpenCodeObject(PyObject *path) +{ + PyObject *iomod, *f = NULL; + _Py_IDENTIFIER(open); + + if (!PyUnicode_Check(path)) { + PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'", + Py_TYPE(path)->tp_name); + return NULL; + } + + Py_OpenCodeHookFunction hook = _PyRuntime.open_code_hook; + if (hook) { + f = hook(path, _PyRuntime.open_code_userdata); + } else { + iomod = PyImport_ImportModule("_io"); + if (iomod) { + f = _PyObject_CallMethodId(iomod, &PyId_open, "Os", + path, "rb"); + Py_DECREF(iomod); + } + } + + return f; +} + +PyObject * +PyFile_OpenCode(const char *utf8path) +{ + PyObject *pathobj = PyUnicode_FromString(utf8path); + PyObject *f; + if (!pathobj) { + return NULL; + } + f = PyFile_OpenCodeObject(pathobj); + Py_DECREF(pathobj); + return f; +} + + +#ifdef __cplusplus +} +#endif diff --git a/python/Objects/floatobject.c b/python/Objects/floatobject.c new file mode 100755 index 0000000..609f66f --- /dev/null +++ b/python/Objects/floatobject.c @@ -0,0 +1,2604 @@ +/* Float object implementation */ + +/* XXX There should be overflow checks here, but it's hard to check + for any kind of float exception without losing portability. */ + +#include "Python.h" + +#include +#include + +/*[clinic input] +class float "PyObject *" "&PyFloat_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd0003f68f144284]*/ + +#include "clinic/floatobject.c.h" + +/* Special free list + free_list is a singly-linked list of available PyFloatObjects, linked + via abuse of their ob_type members. +*/ + +#ifndef PyFloat_MAXFREELIST +#define PyFloat_MAXFREELIST 100 +#endif +static int numfree = 0; +static PyFloatObject *free_list = NULL; + +double +PyFloat_GetMax(void) +{ + return DBL_MAX; +} + +double +PyFloat_GetMin(void) +{ + return DBL_MIN; +} + +static PyTypeObject FloatInfoType; + +PyDoc_STRVAR(floatinfo__doc__, +"sys.float_info\n\ +\n\ +A named tuple holding information about the float type. It contains low level\n\ +information about the precision and internal representation. Please study\n\ +your system's :file:`float.h` for more information."); + +static PyStructSequence_Field floatinfo_fields[] = { + {"max", "DBL_MAX -- maximum representable finite float"}, + {"max_exp", "DBL_MAX_EXP -- maximum int e such that radix**(e-1) " + "is representable"}, + {"max_10_exp", "DBL_MAX_10_EXP -- maximum int e such that 10**e " + "is representable"}, + {"min", "DBL_MIN -- Minimum positive normalized float"}, + {"min_exp", "DBL_MIN_EXP -- minimum int e such that radix**(e-1) " + "is a normalized float"}, + {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is " + "a normalized"}, + {"dig", "DBL_DIG -- digits"}, + {"mant_dig", "DBL_MANT_DIG -- mantissa digits"}, + {"epsilon", "DBL_EPSILON -- Difference between 1 and the next " + "representable float"}, + {"radix", "FLT_RADIX -- radix of exponent"}, + {"rounds", "FLT_ROUNDS -- rounding mode"}, + {0} +}; + +static PyStructSequence_Desc floatinfo_desc = { + "sys.float_info", /* name */ + floatinfo__doc__, /* doc */ + floatinfo_fields, /* fields */ + 11 +}; + +PyObject * +PyFloat_GetInfo(void) +{ + PyObject* floatinfo; + int pos = 0; + + floatinfo = PyStructSequence_New(&FloatInfoType); + if (floatinfo == NULL) { + return NULL; + } + +#define SetIntFlag(flag) \ + PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag)) +#define SetDblFlag(flag) \ + PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag)) + + SetDblFlag(DBL_MAX); + SetIntFlag(DBL_MAX_EXP); + SetIntFlag(DBL_MAX_10_EXP); + SetDblFlag(DBL_MIN); + SetIntFlag(DBL_MIN_EXP); + SetIntFlag(DBL_MIN_10_EXP); + SetIntFlag(DBL_DIG); + SetIntFlag(DBL_MANT_DIG); + SetDblFlag(DBL_EPSILON); + SetIntFlag(FLT_RADIX); + SetIntFlag(FLT_ROUNDS); +#undef SetIntFlag +#undef SetDblFlag + + if (PyErr_Occurred()) { + Py_CLEAR(floatinfo); + return NULL; + } + return floatinfo; +} + +PyObject * +PyFloat_FromDouble(double fval) +{ + PyFloatObject *op = free_list; + if (op != NULL) { + free_list = (PyFloatObject *) Py_TYPE(op); + numfree--; + } else { + op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject)); + if (!op) + return PyErr_NoMemory(); + } + /* Inline PyObject_New */ + (void)PyObject_INIT(op, &PyFloat_Type); + op->ob_fval = fval; + return (PyObject *) op; +} + +static PyObject * +float_from_string_inner(const char *s, Py_ssize_t len, void *obj) +{ + double x; + const char *end; + const char *last = s + len; + /* strip space */ + while (s < last && Py_ISSPACE(*s)) { + s++; + } + + while (s < last - 1 && Py_ISSPACE(last[-1])) { + last--; + } + + /* We don't care about overflow or underflow. If the platform + * supports them, infinities and signed zeroes (on underflow) are + * fine. */ + x = PyOS_string_to_double(s, (char **)&end, NULL); + if (end != last) { + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "%R", obj); + return NULL; + } + else if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } + else { + return PyFloat_FromDouble(x); + } +} + +PyObject * +PyFloat_FromString(PyObject *v) +{ + const char *s; + PyObject *s_buffer = NULL; + Py_ssize_t len; + Py_buffer view = {NULL, NULL}; + PyObject *result = NULL; + + if (PyUnicode_Check(v)) { + s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); + if (s_buffer == NULL) + return NULL; + assert(PyUnicode_IS_ASCII(s_buffer)); + /* Simply get a pointer to existing ASCII characters. */ + s = PyUnicode_AsUTF8AndSize(s_buffer, &len); + assert(s != NULL); + } + else if (PyBytes_Check(v)) { + s = PyBytes_AS_STRING(v); + len = PyBytes_GET_SIZE(v); + } + else if (PyByteArray_Check(v)) { + s = PyByteArray_AS_STRING(v); + len = PyByteArray_GET_SIZE(v); + } + else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { + s = (const char *)view.buf; + len = view.len; + /* Copy to NUL-terminated buffer. */ + s_buffer = PyBytes_FromStringAndSize(s, len); + if (s_buffer == NULL) { + PyBuffer_Release(&view); + return NULL; + } + s = PyBytes_AS_STRING(s_buffer); + } + else { + PyErr_Format(PyExc_TypeError, + "float() argument must be a string or a number, not '%.200s'", + Py_TYPE(v)->tp_name); + return NULL; + } + result = _Py_string_to_number_with_underscores(s, len, "float", v, v, + float_from_string_inner); + PyBuffer_Release(&view); + Py_XDECREF(s_buffer); + return result; +} + +static void +float_dealloc(PyFloatObject *op) +{ + if (PyFloat_CheckExact(op)) { + if (numfree >= PyFloat_MAXFREELIST) { + PyObject_FREE(op); + return; + } + numfree++; + Py_TYPE(op) = (struct _typeobject *)free_list; + free_list = op; + } + else + Py_TYPE(op)->tp_free((PyObject *)op); +} + +double +PyFloat_AsDouble(PyObject *op) +{ + PyNumberMethods *nb; + PyObject *res; + double val; + + if (op == NULL) { + PyErr_BadArgument(); + return -1; + } + + if (PyFloat_Check(op)) { + return PyFloat_AS_DOUBLE(op); + } + + nb = Py_TYPE(op)->tp_as_number; + if (nb == NULL || nb->nb_float == NULL) { + if (nb && nb->nb_index) { + PyObject *res = PyNumber_Index(op); + if (!res) { + return -1; + } + double val = PyLong_AsDouble(res); + Py_DECREF(res); + return val; + } + PyErr_Format(PyExc_TypeError, "must be real number, not %.50s", + op->ob_type->tp_name); + return -1; + } + + res = (*nb->nb_float) (op); + if (res == NULL) { + return -1; + } + if (!PyFloat_CheckExact(res)) { + if (!PyFloat_Check(res)) { + PyErr_Format(PyExc_TypeError, + "%.50s.__float__ returned non-float (type %.50s)", + op->ob_type->tp_name, res->ob_type->tp_name); + Py_DECREF(res); + return -1; + } + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "%.50s.__float__ returned non-float (type %.50s). " + "The ability to return an instance of a strict subclass of float " + "is deprecated, and may be removed in a future version of Python.", + op->ob_type->tp_name, res->ob_type->tp_name)) { + Py_DECREF(res); + return -1; + } + } + + val = PyFloat_AS_DOUBLE(res); + Py_DECREF(res); + return val; +} + +/* Macro and helper that convert PyObject obj to a C double and store + the value in dbl. If conversion to double raises an exception, obj is + set to NULL, and the function invoking this macro returns NULL. If + obj is not of float or int type, Py_NotImplemented is incref'ed, + stored in obj, and returned from the function invoking this macro. +*/ +#define CONVERT_TO_DOUBLE(obj, dbl) \ + if (PyFloat_Check(obj)) \ + dbl = PyFloat_AS_DOUBLE(obj); \ + else if (convert_to_double(&(obj), &(dbl)) < 0) \ + return obj; + +/* Methods */ + +static int +convert_to_double(PyObject **v, double *dbl) +{ + PyObject *obj = *v; + + if (PyLong_Check(obj)) { + *dbl = PyLong_AsDouble(obj); + if (*dbl == -1.0 && PyErr_Occurred()) { + *v = NULL; + return -1; + } + } + else { + Py_INCREF(Py_NotImplemented); + *v = Py_NotImplemented; + return -1; + } + return 0; +} + +static PyObject * +float_repr(PyFloatObject *v) +{ + PyObject *result; + char *buf; + + buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), + 'r', 0, + Py_DTSF_ADD_DOT_0, + NULL); + if (!buf) + return PyErr_NoMemory(); + result = _PyUnicode_FromASCII(buf, strlen(buf)); + PyMem_Free(buf); + return result; +} + +/* Comparison is pretty much a nightmare. When comparing float to float, + * we do it as straightforwardly (and long-windedly) as conceivable, so + * that, e.g., Python x == y delivers the same result as the platform + * C x == y when x and/or y is a NaN. + * When mixing float with an integer type, there's no good *uniform* approach. + * Converting the double to an integer obviously doesn't work, since we + * may lose info from fractional bits. Converting the integer to a double + * also has two failure modes: (1) an int may trigger overflow (too + * large to fit in the dynamic range of a C double); (2) even a C long may have + * more bits than fit in a C double (e.g., on a 64-bit box long may have + * 63 bits of precision, but a C double probably has only 53), and then + * we can falsely claim equality when low-order integer bits are lost by + * coercion to double. So this part is painful too. + */ + +static PyObject* +float_richcompare(PyObject *v, PyObject *w, int op) +{ + double i, j; + int r = 0; + + assert(PyFloat_Check(v)); + i = PyFloat_AS_DOUBLE(v); + + /* Switch on the type of w. Set i and j to doubles to be compared, + * and op to the richcomp to use. + */ + if (PyFloat_Check(w)) + j = PyFloat_AS_DOUBLE(w); + + else if (!Py_IS_FINITE(i)) { + if (PyLong_Check(w)) + /* If i is an infinity, its magnitude exceeds any + * finite integer, so it doesn't matter which int we + * compare i with. If i is a NaN, similarly. + */ + j = 0.0; + else + goto Unimplemented; + } + + else if (PyLong_Check(w)) { + int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1; + int wsign = _PyLong_Sign(w); + size_t nbits; + int exponent; + + if (vsign != wsign) { + /* Magnitudes are irrelevant -- the signs alone + * determine the outcome. + */ + i = (double)vsign; + j = (double)wsign; + goto Compare; + } + /* The signs are the same. */ + /* Convert w to a double if it fits. In particular, 0 fits. */ + nbits = _PyLong_NumBits(w); + if (nbits == (size_t)-1 && PyErr_Occurred()) { + /* This long is so large that size_t isn't big enough + * to hold the # of bits. Replace with little doubles + * that give the same outcome -- w is so large that + * its magnitude must exceed the magnitude of any + * finite float. + */ + PyErr_Clear(); + i = (double)vsign; + assert(wsign != 0); + j = wsign * 2.0; + goto Compare; + } + if (nbits <= 48) { + j = PyLong_AsDouble(w); + /* It's impossible that <= 48 bits overflowed. */ + assert(j != -1.0 || ! PyErr_Occurred()); + goto Compare; + } + assert(wsign != 0); /* else nbits was 0 */ + assert(vsign != 0); /* if vsign were 0, then since wsign is + * not 0, we would have taken the + * vsign != wsign branch at the start */ + /* We want to work with non-negative numbers. */ + if (vsign < 0) { + /* "Multiply both sides" by -1; this also swaps the + * comparator. + */ + i = -i; + op = _Py_SwappedOp[op]; + } + assert(i > 0.0); + (void) frexp(i, &exponent); + /* exponent is the # of bits in v before the radix point; + * we know that nbits (the # of bits in w) > 48 at this point + */ + if (exponent < 0 || (size_t)exponent < nbits) { + i = 1.0; + j = 2.0; + goto Compare; + } + if ((size_t)exponent > nbits) { + i = 2.0; + j = 1.0; + goto Compare; + } + /* v and w have the same number of bits before the radix + * point. Construct two ints that have the same comparison + * outcome. + */ + { + double fracpart; + double intpart; + PyObject *result = NULL; + PyObject *vv = NULL; + PyObject *ww = w; + + if (wsign < 0) { + ww = PyNumber_Negative(w); + if (ww == NULL) + goto Error; + } + else + Py_INCREF(ww); + + fracpart = modf(i, &intpart); + vv = PyLong_FromDouble(intpart); + if (vv == NULL) + goto Error; + + if (fracpart != 0.0) { + /* Shift left, and or a 1 bit into vv + * to represent the lost fraction. + */ + PyObject *temp; + + temp = _PyLong_Lshift(ww, 1); + if (temp == NULL) + goto Error; + Py_DECREF(ww); + ww = temp; + + temp = _PyLong_Lshift(vv, 1); + if (temp == NULL) + goto Error; + Py_DECREF(vv); + vv = temp; + + temp = PyNumber_Or(vv, _PyLong_One); + if (temp == NULL) + goto Error; + Py_DECREF(vv); + vv = temp; + } + + r = PyObject_RichCompareBool(vv, ww, op); + if (r < 0) + goto Error; + result = PyBool_FromLong(r); + Error: + Py_XDECREF(vv); + Py_XDECREF(ww); + return result; + } + } /* else if (PyLong_Check(w)) */ + + else /* w isn't float or int */ + goto Unimplemented; + + Compare: + PyFPE_START_PROTECT("richcompare", return NULL) + switch (op) { + case Py_EQ: + r = i == j; + break; + case Py_NE: + r = i != j; + break; + case Py_LE: + r = i <= j; + break; + case Py_GE: + r = i >= j; + break; + case Py_LT: + r = i < j; + break; + case Py_GT: + r = i > j; + break; + } + PyFPE_END_PROTECT(r) + return PyBool_FromLong(r); + + Unimplemented: + Py_RETURN_NOTIMPLEMENTED; +} + +static Py_hash_t +float_hash(PyFloatObject *v) +{ + return _Py_HashDouble(v->ob_fval); +} + +static PyObject * +float_add(PyObject *v, PyObject *w) +{ + double a,b; + CONVERT_TO_DOUBLE(v, a); + CONVERT_TO_DOUBLE(w, b); + PyFPE_START_PROTECT("add", return 0) + a = a + b; + PyFPE_END_PROTECT(a) + return PyFloat_FromDouble(a); +} + +static PyObject * +float_sub(PyObject *v, PyObject *w) +{ + double a,b; + CONVERT_TO_DOUBLE(v, a); + CONVERT_TO_DOUBLE(w, b); + PyFPE_START_PROTECT("subtract", return 0) + a = a - b; + PyFPE_END_PROTECT(a) + return PyFloat_FromDouble(a); +} + +static PyObject * +float_mul(PyObject *v, PyObject *w) +{ + double a,b; + CONVERT_TO_DOUBLE(v, a); + CONVERT_TO_DOUBLE(w, b); + PyFPE_START_PROTECT("multiply", return 0) + a = a * b; + PyFPE_END_PROTECT(a) + return PyFloat_FromDouble(a); +} + +static PyObject * +float_div(PyObject *v, PyObject *w) +{ + double a,b; + CONVERT_TO_DOUBLE(v, a); + CONVERT_TO_DOUBLE(w, b); + if (b == 0.0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "float division by zero"); + return NULL; + } + PyFPE_START_PROTECT("divide", return 0) + a = a / b; + PyFPE_END_PROTECT(a) + return PyFloat_FromDouble(a); +} + +static PyObject * +float_rem(PyObject *v, PyObject *w) +{ + double vx, wx; + double mod; + CONVERT_TO_DOUBLE(v, vx); + CONVERT_TO_DOUBLE(w, wx); + if (wx == 0.0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "float modulo"); + return NULL; + } + PyFPE_START_PROTECT("modulo", return 0) + mod = fmod(vx, wx); + if (mod) { + /* ensure the remainder has the same sign as the denominator */ + if ((wx < 0) != (mod < 0)) { + mod += wx; + } + } + else { + /* the remainder is zero, and in the presence of signed zeroes + fmod returns different results across platforms; ensure + it has the same sign as the denominator. */ + mod = copysign(0.0, wx); + } + PyFPE_END_PROTECT(mod) + return PyFloat_FromDouble(mod); +} + +static PyObject * +float_divmod(PyObject *v, PyObject *w) +{ + double vx, wx; + double div, mod, floordiv; + CONVERT_TO_DOUBLE(v, vx); + CONVERT_TO_DOUBLE(w, wx); + if (wx == 0.0) { + PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); + return NULL; + } + PyFPE_START_PROTECT("divmod", return 0) + mod = fmod(vx, wx); + /* fmod is typically exact, so vx-mod is *mathematically* an + exact multiple of wx. But this is fp arithmetic, and fp + vx - mod is an approximation; the result is that div may + not be an exact integral value after the division, although + it will always be very close to one. + */ + div = (vx - mod) / wx; + if (mod) { + /* ensure the remainder has the same sign as the denominator */ + if ((wx < 0) != (mod < 0)) { + mod += wx; + div -= 1.0; + } + } + else { + /* the remainder is zero, and in the presence of signed zeroes + fmod returns different results across platforms; ensure + it has the same sign as the denominator. */ + mod = copysign(0.0, wx); + } + /* snap quotient to nearest integral value */ + if (div) { + floordiv = floor(div); + if (div - floordiv > 0.5) + floordiv += 1.0; + } + else { + /* div is zero - get the same sign as the true quotient */ + floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */ + } + PyFPE_END_PROTECT(floordiv) + return Py_BuildValue("(dd)", floordiv, mod); +} + +static PyObject * +float_floor_div(PyObject *v, PyObject *w) +{ + PyObject *t, *r; + + t = float_divmod(v, w); + if (t == NULL || t == Py_NotImplemented) + return t; + assert(PyTuple_CheckExact(t)); + r = PyTuple_GET_ITEM(t, 0); + Py_INCREF(r); + Py_DECREF(t); + return r; +} + +/* determine whether x is an odd integer or not; assumes that + x is not an infinity or nan. */ +#define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0) + +static PyObject * +float_pow(PyObject *v, PyObject *w, PyObject *z) +{ + double iv, iw, ix; + int negate_result = 0; + + if ((PyObject *)z != Py_None) { + PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not " + "allowed unless all arguments are integers"); + return NULL; + } + + CONVERT_TO_DOUBLE(v, iv); + CONVERT_TO_DOUBLE(w, iw); + + /* Sort out special cases here instead of relying on pow() */ + if (iw == 0) { /* v**0 is 1, even 0**0 */ + return PyFloat_FromDouble(1.0); + } + if (Py_IS_NAN(iv)) { /* nan**w = nan, unless w == 0 */ + return PyFloat_FromDouble(iv); + } + if (Py_IS_NAN(iw)) { /* v**nan = nan, unless v == 1; 1**nan = 1 */ + return PyFloat_FromDouble(iv == 1.0 ? 1.0 : iw); + } + if (Py_IS_INFINITY(iw)) { + /* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if + * abs(v) > 1 (including case where v infinite) + * + * v**-inf is: inf if abs(v) < 1; 1.0 if abs(v) == 1; 0.0 if + * abs(v) > 1 (including case where v infinite) + */ + iv = fabs(iv); + if (iv == 1.0) + return PyFloat_FromDouble(1.0); + else if ((iw > 0.0) == (iv > 1.0)) + return PyFloat_FromDouble(fabs(iw)); /* return inf */ + else + return PyFloat_FromDouble(0.0); + } + if (Py_IS_INFINITY(iv)) { + /* (+-inf)**w is: inf for w positive, 0 for w negative; in + * both cases, we need to add the appropriate sign if w is + * an odd integer. + */ + int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw); + if (iw > 0.0) + return PyFloat_FromDouble(iw_is_odd ? iv : fabs(iv)); + else + return PyFloat_FromDouble(iw_is_odd ? + copysign(0.0, iv) : 0.0); + } + if (iv == 0.0) { /* 0**w is: 0 for w positive, 1 for w zero + (already dealt with above), and an error + if w is negative. */ + int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw); + if (iw < 0.0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "0.0 cannot be raised to a " + "negative power"); + return NULL; + } + /* use correct sign if iw is odd */ + return PyFloat_FromDouble(iw_is_odd ? iv : 0.0); + } + + if (iv < 0.0) { + /* Whether this is an error is a mess, and bumps into libm + * bugs so we have to figure it out ourselves. + */ + if (iw != floor(iw)) { + /* Negative numbers raised to fractional powers + * become complex. + */ + return PyComplex_Type.tp_as_number->nb_power(v, w, z); + } + /* iw is an exact integer, albeit perhaps a very large + * one. Replace iv by its absolute value and remember + * to negate the pow result if iw is odd. + */ + iv = -iv; + negate_result = DOUBLE_IS_ODD_INTEGER(iw); + } + + if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */ + /* (-1) ** large_integer also ends up here. Here's an + * extract from the comments for the previous + * implementation explaining why this special case is + * necessary: + * + * -1 raised to an exact integer should never be exceptional. + * Alas, some libms (chiefly glibc as of early 2003) return + * NaN and set EDOM on pow(-1, large_int) if the int doesn't + * happen to be representable in a *C* integer. That's a + * bug. + */ + return PyFloat_FromDouble(negate_result ? -1.0 : 1.0); + } + + /* Now iv and iw are finite, iw is nonzero, and iv is + * positive and not equal to 1.0. We finally allow + * the platform pow to step in and do the rest. + */ + errno = 0; + PyFPE_START_PROTECT("pow", return NULL) + ix = pow(iv, iw); + PyFPE_END_PROTECT(ix) + Py_ADJUST_ERANGE1(ix); + if (negate_result) + ix = -ix; + + if (errno != 0) { + /* We don't expect any errno value other than ERANGE, but + * the range of libm bugs appears unbounded. + */ + PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError : + PyExc_ValueError); + return NULL; + } + return PyFloat_FromDouble(ix); +} + +#undef DOUBLE_IS_ODD_INTEGER + +static PyObject * +float_neg(PyFloatObject *v) +{ + return PyFloat_FromDouble(-v->ob_fval); +} + +static PyObject * +float_abs(PyFloatObject *v) +{ + return PyFloat_FromDouble(fabs(v->ob_fval)); +} + +static int +float_bool(PyFloatObject *v) +{ + return v->ob_fval != 0.0; +} + +/*[clinic input] +float.is_integer + +Return True if the float is an integer. +[clinic start generated code]*/ + +static PyObject * +float_is_integer_impl(PyObject *self) +/*[clinic end generated code: output=7112acf95a4d31ea input=311810d3f777e10d]*/ +{ + double x = PyFloat_AsDouble(self); + PyObject *o; + + if (x == -1.0 && PyErr_Occurred()) + return NULL; + if (!Py_IS_FINITE(x)) + Py_RETURN_FALSE; + errno = 0; + PyFPE_START_PROTECT("is_integer", return NULL) + o = (floor(x) == x) ? Py_True : Py_False; + PyFPE_END_PROTECT(x) + if (errno != 0) { + PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError : + PyExc_ValueError); + return NULL; + } + Py_INCREF(o); + return o; +} + +/*[clinic input] +float.__trunc__ + +Return the Integral closest to x between 0 and x. +[clinic start generated code]*/ + +static PyObject * +float___trunc___impl(PyObject *self) +/*[clinic end generated code: output=dd3e289dd4c6b538 input=591b9ba0d650fdff]*/ +{ + double x = PyFloat_AsDouble(self); + double wholepart; /* integral portion of x, rounded toward 0 */ + + (void)modf(x, &wholepart); + /* Try to get out cheap if this fits in a Python int. The attempt + * to cast to long must be protected, as C doesn't define what + * happens if the double is too big to fit in a long. Some rare + * systems raise an exception then (RISCOS was mentioned as one, + * and someone using a non-default option on Sun also bumped into + * that). Note that checking for >= and <= LONG_{MIN,MAX} would + * still be vulnerable: if a long has more bits of precision than + * a double, casting MIN/MAX to double may yield an approximation, + * and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would + * yield true from the C expression wholepart<=LONG_MAX, despite + * that wholepart is actually greater than LONG_MAX. + */ + if (LONG_MIN < wholepart && wholepart < LONG_MAX) { + const long aslong = (long)wholepart; + return PyLong_FromLong(aslong); + } + return PyLong_FromDouble(wholepart); +} + +/* double_round: rounds a finite double to the closest multiple of + 10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <= + ndigits <= 323). Returns a Python float, or sets a Python error and + returns NULL on failure (OverflowError and memory errors are possible). */ + +#ifndef PY_NO_SHORT_FLOAT_REPR +/* version of double_round that uses the correctly-rounded string<->double + conversions from Python/dtoa.c */ + +static PyObject * +double_round(double x, int ndigits) { + + double rounded; + Py_ssize_t buflen, mybuflen=100; + char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf; + int decpt, sign; + PyObject *result = NULL; + _Py_SET_53BIT_PRECISION_HEADER; + + /* round to a decimal string */ + _Py_SET_53BIT_PRECISION_START; + buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end); + _Py_SET_53BIT_PRECISION_END; + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + + /* Get new buffer if shortbuf is too small. Space needed <= buf_end - + buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0'). */ + buflen = buf_end - buf; + if (buflen + 8 > mybuflen) { + mybuflen = buflen+8; + mybuf = (char *)PyMem_Malloc(mybuflen); + if (mybuf == NULL) { + PyErr_NoMemory(); + goto exit; + } + } + /* copy buf to mybuf, adding exponent, sign and leading 0 */ + PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""), + buf, decpt - (int)buflen); + + /* and convert the resulting string back to a double */ + errno = 0; + _Py_SET_53BIT_PRECISION_START; + rounded = _Py_dg_strtod(mybuf, NULL); + _Py_SET_53BIT_PRECISION_END; + if (errno == ERANGE && fabs(rounded) >= 1.) + PyErr_SetString(PyExc_OverflowError, + "rounded value too large to represent"); + else + result = PyFloat_FromDouble(rounded); + + /* done computing value; now clean up */ + if (mybuf != shortbuf) + PyMem_Free(mybuf); + exit: + _Py_dg_freedtoa(buf); + return result; +} + +#else /* PY_NO_SHORT_FLOAT_REPR */ + +/* fallback version, to be used when correctly rounded binary<->decimal + conversions aren't available */ + +static PyObject * +double_round(double x, int ndigits) { + double pow1, pow2, y, z; + if (ndigits >= 0) { + if (ndigits > 22) { + /* pow1 and pow2 are each safe from overflow, but + pow1*pow2 ~= pow(10.0, ndigits) might overflow */ + pow1 = pow(10.0, (double)(ndigits-22)); + pow2 = 1e22; + } + else { + pow1 = pow(10.0, (double)ndigits); + pow2 = 1.0; + } + y = (x*pow1)*pow2; + /* if y overflows, then rounded value is exactly x */ + if (!Py_IS_FINITE(y)) + return PyFloat_FromDouble(x); + } + else { + pow1 = pow(10.0, (double)-ndigits); + pow2 = 1.0; /* unused; silences a gcc compiler warning */ + y = x / pow1; + } + + z = round(y); + if (fabs(y-z) == 0.5) + /* halfway between two integers; use round-half-even */ + z = 2.0*round(y/2.0); + + if (ndigits >= 0) + z = (z / pow2) / pow1; + else + z *= pow1; + + /* if computation resulted in overflow, raise OverflowError */ + if (!Py_IS_FINITE(z)) { + PyErr_SetString(PyExc_OverflowError, + "overflow occurred during round"); + return NULL; + } + + return PyFloat_FromDouble(z); +} + +#endif /* PY_NO_SHORT_FLOAT_REPR */ + +/* round a Python float v to the closest multiple of 10**-ndigits */ + +/*[clinic input] +float.__round__ + + ndigits as o_ndigits: object = None + / + +Return the Integral closest to x, rounding half toward even. + +When an argument is passed, work like built-in round(x, ndigits). +[clinic start generated code]*/ + +static PyObject * +float___round___impl(PyObject *self, PyObject *o_ndigits) +/*[clinic end generated code: output=374c36aaa0f13980 input=fc0fe25924fbc9ed]*/ +{ + double x, rounded; + Py_ssize_t ndigits; + + x = PyFloat_AsDouble(self); + if (o_ndigits == Py_None) { + /* single-argument round or with None ndigits: + * round to nearest integer */ + rounded = round(x); + if (fabs(x-rounded) == 0.5) + /* halfway case: round to even */ + rounded = 2.0*round(x/2.0); + return PyLong_FromDouble(rounded); + } + + /* interpret second argument as a Py_ssize_t; clips on overflow */ + ndigits = PyNumber_AsSsize_t(o_ndigits, NULL); + if (ndigits == -1 && PyErr_Occurred()) + return NULL; + + /* nans and infinities round to themselves */ + if (!Py_IS_FINITE(x)) + return PyFloat_FromDouble(x); + + /* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x + always rounds to itself. For ndigits < NDIGITS_MIN, x always + rounds to +-0.0. Here 0.30103 is an upper bound for log10(2). */ +#define NDIGITS_MAX ((int)((DBL_MANT_DIG-DBL_MIN_EXP) * 0.30103)) +#define NDIGITS_MIN (-(int)((DBL_MAX_EXP + 1) * 0.30103)) + if (ndigits > NDIGITS_MAX) + /* return x */ + return PyFloat_FromDouble(x); + else if (ndigits < NDIGITS_MIN) + /* return 0.0, but with sign of x */ + return PyFloat_FromDouble(0.0*x); + else + /* finite x, and ndigits is not unreasonably large */ + return double_round(x, (int)ndigits); +#undef NDIGITS_MAX +#undef NDIGITS_MIN +} + +static PyObject * +float_float(PyObject *v) +{ + if (PyFloat_CheckExact(v)) + Py_INCREF(v); + else + v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); + return v; +} + +/*[clinic input] +float.conjugate + +Return self, the complex conjugate of any float. +[clinic start generated code]*/ + +static PyObject * +float_conjugate_impl(PyObject *self) +/*[clinic end generated code: output=8ca292c2479194af input=82ba6f37a9ff91dd]*/ +{ + return float_float(self); +} + +/* turn ASCII hex characters into integer values and vice versa */ + +static char +char_from_hex(int x) +{ + assert(0 <= x && x < 16); + return Py_hexdigits[x]; +} + +static int +hex_from_char(char c) { + int x; + switch(c) { + case '0': + x = 0; + break; + case '1': + x = 1; + break; + case '2': + x = 2; + break; + case '3': + x = 3; + break; + case '4': + x = 4; + break; + case '5': + x = 5; + break; + case '6': + x = 6; + break; + case '7': + x = 7; + break; + case '8': + x = 8; + break; + case '9': + x = 9; + break; + case 'a': + case 'A': + x = 10; + break; + case 'b': + case 'B': + x = 11; + break; + case 'c': + case 'C': + x = 12; + break; + case 'd': + case 'D': + x = 13; + break; + case 'e': + case 'E': + x = 14; + break; + case 'f': + case 'F': + x = 15; + break; + default: + x = -1; + break; + } + return x; +} + +/* convert a float to a hexadecimal string */ + +/* TOHEX_NBITS is DBL_MANT_DIG rounded up to the next integer + of the form 4k+1. */ +#define TOHEX_NBITS DBL_MANT_DIG + 3 - (DBL_MANT_DIG+2)%4 + +/*[clinic input] +float.hex + +Return a hexadecimal representation of a floating-point number. + +>>> (-0.1).hex() +'-0x1.999999999999ap-4' +>>> 3.14159.hex() +'0x1.921f9f01b866ep+1' +[clinic start generated code]*/ + +static PyObject * +float_hex_impl(PyObject *self) +/*[clinic end generated code: output=0ebc9836e4d302d4 input=bec1271a33d47e67]*/ +{ + double x, m; + int e, shift, i, si, esign; + /* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the + trailing NUL byte. */ + char s[(TOHEX_NBITS-1)/4+3]; + + CONVERT_TO_DOUBLE(self, x); + + if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) + return float_repr((PyFloatObject *)self); + + if (x == 0.0) { + if (copysign(1.0, x) == -1.0) + return PyUnicode_FromString("-0x0.0p+0"); + else + return PyUnicode_FromString("0x0.0p+0"); + } + + m = frexp(fabs(x), &e); + shift = 1 - Py_MAX(DBL_MIN_EXP - e, 0); + m = ldexp(m, shift); + e -= shift; + + si = 0; + s[si] = char_from_hex((int)m); + si++; + m -= (int)m; + s[si] = '.'; + si++; + for (i=0; i < (TOHEX_NBITS-1)/4; i++) { + m *= 16.0; + s[si] = char_from_hex((int)m); + si++; + m -= (int)m; + } + s[si] = '\0'; + + if (e < 0) { + esign = (int)'-'; + e = -e; + } + else + esign = (int)'+'; + + if (x < 0.0) + return PyUnicode_FromFormat("-0x%sp%c%d", s, esign, e); + else + return PyUnicode_FromFormat("0x%sp%c%d", s, esign, e); +} + +/* Convert a hexadecimal string to a float. */ + +/*[clinic input] +@classmethod +float.fromhex + + string: object + / + +Create a floating-point number from a hexadecimal string. + +>>> float.fromhex('0x1.ffffp10') +2047.984375 +>>> float.fromhex('-0x1p-1074') +-5e-324 +[clinic start generated code]*/ + +static PyObject * +float_fromhex(PyTypeObject *type, PyObject *string) +/*[clinic end generated code: output=46c0274d22b78e82 input=0407bebd354bca89]*/ +{ + PyObject *result; + double x; + long exp, top_exp, lsb, key_digit; + const char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end; + int half_eps, digit, round_up, negate=0; + Py_ssize_t length, ndigits, fdigits, i; + + /* + * For the sake of simplicity and correctness, we impose an artificial + * limit on ndigits, the total number of hex digits in the coefficient + * The limit is chosen to ensure that, writing exp for the exponent, + * + * (1) if exp > LONG_MAX/2 then the value of the hex string is + * guaranteed to overflow (provided it's nonzero) + * + * (2) if exp < LONG_MIN/2 then the value of the hex string is + * guaranteed to underflow to 0. + * + * (3) if LONG_MIN/2 <= exp <= LONG_MAX/2 then there's no danger of + * overflow in the calculation of exp and top_exp below. + * + * More specifically, ndigits is assumed to satisfy the following + * inequalities: + * + * 4*ndigits <= DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2 + * 4*ndigits <= LONG_MAX/2 + 1 - DBL_MAX_EXP + * + * If either of these inequalities is not satisfied, a ValueError is + * raised. Otherwise, write x for the value of the hex string, and + * assume x is nonzero. Then + * + * 2**(exp-4*ndigits) <= |x| < 2**(exp+4*ndigits). + * + * Now if exp > LONG_MAX/2 then: + * + * exp - 4*ndigits >= LONG_MAX/2 + 1 - (LONG_MAX/2 + 1 - DBL_MAX_EXP) + * = DBL_MAX_EXP + * + * so |x| >= 2**DBL_MAX_EXP, which is too large to be stored in C + * double, so overflows. If exp < LONG_MIN/2, then + * + * exp + 4*ndigits <= LONG_MIN/2 - 1 + ( + * DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2) + * = DBL_MIN_EXP - DBL_MANT_DIG - 1 + * + * and so |x| < 2**(DBL_MIN_EXP-DBL_MANT_DIG-1), hence underflows to 0 + * when converted to a C double. + * + * It's easy to show that if LONG_MIN/2 <= exp <= LONG_MAX/2 then both + * exp+4*ndigits and exp-4*ndigits are within the range of a long. + */ + + s = PyUnicode_AsUTF8AndSize(string, &length); + if (s == NULL) + return NULL; + s_end = s + length; + + /******************** + * Parse the string * + ********************/ + + /* leading whitespace */ + while (Py_ISSPACE(*s)) + s++; + + /* infinities and nans */ + x = _Py_parse_inf_or_nan(s, (char **)&coeff_end); + if (coeff_end != s) { + s = coeff_end; + goto finished; + } + + /* optional sign */ + if (*s == '-') { + s++; + negate = 1; + } + else if (*s == '+') + s++; + + /* [0x] */ + s_store = s; + if (*s == '0') { + s++; + if (*s == 'x' || *s == 'X') + s++; + else + s = s_store; + } + + /* coefficient: [. ] */ + coeff_start = s; + while (hex_from_char(*s) >= 0) + s++; + s_store = s; + if (*s == '.') { + s++; + while (hex_from_char(*s) >= 0) + s++; + coeff_end = s-1; + } + else + coeff_end = s; + + /* ndigits = total # of hex digits; fdigits = # after point */ + ndigits = coeff_end - coeff_start; + fdigits = coeff_end - s_store; + if (ndigits == 0) + goto parse_error; + if (ndigits > Py_MIN(DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2, + LONG_MAX/2 + 1 - DBL_MAX_EXP)/4) + goto insane_length_error; + + /* [p ] */ + if (*s == 'p' || *s == 'P') { + s++; + exp_start = s; + if (*s == '-' || *s == '+') + s++; + if (!('0' <= *s && *s <= '9')) + goto parse_error; + s++; + while ('0' <= *s && *s <= '9') + s++; + exp = strtol(exp_start, NULL, 10); + } + else + exp = 0; + +/* for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit */ +#define HEX_DIGIT(j) hex_from_char(*((j) < fdigits ? \ + coeff_end-(j) : \ + coeff_end-1-(j))) + + /******************************************* + * Compute rounded value of the hex string * + *******************************************/ + + /* Discard leading zeros, and catch extreme overflow and underflow */ + while (ndigits > 0 && HEX_DIGIT(ndigits-1) == 0) + ndigits--; + if (ndigits == 0 || exp < LONG_MIN/2) { + x = 0.0; + goto finished; + } + if (exp > LONG_MAX/2) + goto overflow_error; + + /* Adjust exponent for fractional part. */ + exp = exp - 4*((long)fdigits); + + /* top_exp = 1 more than exponent of most sig. bit of coefficient */ + top_exp = exp + 4*((long)ndigits - 1); + for (digit = HEX_DIGIT(ndigits-1); digit != 0; digit /= 2) + top_exp++; + + /* catch almost all nonextreme cases of overflow and underflow here */ + if (top_exp < DBL_MIN_EXP - DBL_MANT_DIG) { + x = 0.0; + goto finished; + } + if (top_exp > DBL_MAX_EXP) + goto overflow_error; + + /* lsb = exponent of least significant bit of the *rounded* value. + This is top_exp - DBL_MANT_DIG unless result is subnormal. */ + lsb = Py_MAX(top_exp, (long)DBL_MIN_EXP) - DBL_MANT_DIG; + + x = 0.0; + if (exp >= lsb) { + /* no rounding required */ + for (i = ndigits-1; i >= 0; i--) + x = 16.0*x + HEX_DIGIT(i); + x = ldexp(x, (int)(exp)); + goto finished; + } + /* rounding required. key_digit is the index of the hex digit + containing the first bit to be rounded away. */ + half_eps = 1 << (int)((lsb - exp - 1) % 4); + key_digit = (lsb - exp - 1) / 4; + for (i = ndigits-1; i > key_digit; i--) + x = 16.0*x + HEX_DIGIT(i); + digit = HEX_DIGIT(key_digit); + x = 16.0*x + (double)(digit & (16-2*half_eps)); + + /* round-half-even: round up if bit lsb-1 is 1 and at least one of + bits lsb, lsb-2, lsb-3, lsb-4, ... is 1. */ + if ((digit & half_eps) != 0) { + round_up = 0; + if ((digit & (3*half_eps-1)) != 0 || + (half_eps == 8 && (HEX_DIGIT(key_digit+1) & 1) != 0)) + round_up = 1; + else + for (i = key_digit-1; i >= 0; i--) + if (HEX_DIGIT(i) != 0) { + round_up = 1; + break; + } + if (round_up) { + x += 2*half_eps; + if (top_exp == DBL_MAX_EXP && + x == ldexp((double)(2*half_eps), DBL_MANT_DIG)) + /* overflow corner case: pre-rounded value < + 2**DBL_MAX_EXP; rounded=2**DBL_MAX_EXP. */ + goto overflow_error; + } + } + x = ldexp(x, (int)(exp+4*key_digit)); + + finished: + /* optional trailing whitespace leading to the end of the string */ + while (Py_ISSPACE(*s)) + s++; + if (s != s_end) + goto parse_error; + result = PyFloat_FromDouble(negate ? -x : x); + if (type != &PyFloat_Type && result != NULL) { + Py_SETREF(result, PyObject_CallFunctionObjArgs((PyObject *)type, result, NULL)); + } + return result; + + overflow_error: + PyErr_SetString(PyExc_OverflowError, + "hexadecimal value too large to represent as a float"); + return NULL; + + parse_error: + PyErr_SetString(PyExc_ValueError, + "invalid hexadecimal floating-point string"); + return NULL; + + insane_length_error: + PyErr_SetString(PyExc_ValueError, + "hexadecimal string too long to convert"); + return NULL; +} + +/*[clinic input] +float.as_integer_ratio + +Return integer ratio. + +Return a pair of integers, whose ratio is exactly equal to the original float +and with a positive denominator. + +Raise OverflowError on infinities and a ValueError on NaNs. + +>>> (10.0).as_integer_ratio() +(10, 1) +>>> (0.0).as_integer_ratio() +(0, 1) +>>> (-.25).as_integer_ratio() +(-1, 4) +[clinic start generated code]*/ + +static PyObject * +float_as_integer_ratio_impl(PyObject *self) +/*[clinic end generated code: output=65f25f0d8d30a712 input=e21d08b4630c2e44]*/ +{ + double self_double; + double float_part; + int exponent; + int i; + + PyObject *py_exponent = NULL; + PyObject *numerator = NULL; + PyObject *denominator = NULL; + PyObject *result_pair = NULL; + PyNumberMethods *long_methods = PyLong_Type.tp_as_number; + + CONVERT_TO_DOUBLE(self, self_double); + + if (Py_IS_INFINITY(self_double)) { + PyErr_SetString(PyExc_OverflowError, + "cannot convert Infinity to integer ratio"); + return NULL; + } + if (Py_IS_NAN(self_double)) { + PyErr_SetString(PyExc_ValueError, + "cannot convert NaN to integer ratio"); + return NULL; + } + + PyFPE_START_PROTECT("as_integer_ratio", goto error); + float_part = frexp(self_double, &exponent); /* self_double == float_part * 2**exponent exactly */ + PyFPE_END_PROTECT(float_part); + + for (i=0; i<300 && float_part != floor(float_part) ; i++) { + float_part *= 2.0; + exponent--; + } + /* self == float_part * 2**exponent exactly and float_part is integral. + If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part + to be truncated by PyLong_FromDouble(). */ + + numerator = PyLong_FromDouble(float_part); + if (numerator == NULL) + goto error; + denominator = PyLong_FromLong(1); + if (denominator == NULL) + goto error; + py_exponent = PyLong_FromLong(Py_ABS(exponent)); + if (py_exponent == NULL) + goto error; + + /* fold in 2**exponent */ + if (exponent > 0) { + Py_SETREF(numerator, + long_methods->nb_lshift(numerator, py_exponent)); + if (numerator == NULL) + goto error; + } + else { + Py_SETREF(denominator, + long_methods->nb_lshift(denominator, py_exponent)); + if (denominator == NULL) + goto error; + } + + result_pair = PyTuple_Pack(2, numerator, denominator); + +error: + Py_XDECREF(py_exponent); + Py_XDECREF(denominator); + Py_XDECREF(numerator); + return result_pair; +} + +static PyObject * +float_subtype_new(PyTypeObject *type, PyObject *x); + +/*[clinic input] +@classmethod +float.__new__ as float_new + x: object(c_default="_PyLong_Zero") = 0 + / + +Convert a string or number to a floating point number, if possible. +[clinic start generated code]*/ + +static PyObject * +float_new_impl(PyTypeObject *type, PyObject *x) +/*[clinic end generated code: output=ccf1e8dc460ba6ba input=540ee77c204ff87a]*/ +{ + if (type != &PyFloat_Type) + return float_subtype_new(type, x); /* Wimp out */ + /* If it's a string, but not a string subclass, use + PyFloat_FromString. */ + if (PyUnicode_CheckExact(x)) + return PyFloat_FromString(x); + return PyNumber_Float(x); +} + +/* Wimpy, slow approach to tp_new calls for subtypes of float: + first create a regular float from whatever arguments we got, + then allocate a subtype instance and initialize its ob_fval + from the regular float. The regular float is then thrown away. +*/ +static PyObject * +float_subtype_new(PyTypeObject *type, PyObject *x) +{ + PyObject *tmp, *newobj; + + assert(PyType_IsSubtype(type, &PyFloat_Type)); + tmp = float_new_impl(&PyFloat_Type, x); + if (tmp == NULL) + return NULL; + assert(PyFloat_Check(tmp)); + newobj = type->tp_alloc(type, 0); + if (newobj == NULL) { + Py_DECREF(tmp); + return NULL; + } + ((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval; + Py_DECREF(tmp); + return newobj; +} + +/*[clinic input] +float.__getnewargs__ +[clinic start generated code]*/ + +static PyObject * +float___getnewargs___impl(PyObject *self) +/*[clinic end generated code: output=873258c9d206b088 input=002279d1d77891e6]*/ +{ + return Py_BuildValue("(d)", ((PyFloatObject *)self)->ob_fval); +} + +/* this is for the benefit of the pack/unpack routines below */ + +typedef enum { + unknown_format, ieee_big_endian_format, ieee_little_endian_format +} float_format_type; + +static float_format_type double_format, float_format; +static float_format_type detected_double_format, detected_float_format; + +/*[clinic input] +@classmethod +float.__getformat__ + + typestr: str + Must be 'double' or 'float'. + / + +You probably don't want to use this function. + +It exists mainly to be used in Python's test suite. + +This function returns whichever of 'unknown', 'IEEE, big-endian' or 'IEEE, +little-endian' best describes the format of floating point numbers used by the +C type named by typestr. +[clinic start generated code]*/ + +static PyObject * +float___getformat___impl(PyTypeObject *type, const char *typestr) +/*[clinic end generated code: output=2bfb987228cc9628 input=d5a52600f835ad67]*/ +{ + float_format_type r; + + if (strcmp(typestr, "double") == 0) { + r = double_format; + } + else if (strcmp(typestr, "float") == 0) { + r = float_format; + } + else { + PyErr_SetString(PyExc_ValueError, + "__getformat__() argument 1 must be " + "'double' or 'float'"); + return NULL; + } + + switch (r) { + case unknown_format: + return PyUnicode_FromString("unknown"); + case ieee_little_endian_format: + return PyUnicode_FromString("IEEE, little-endian"); + case ieee_big_endian_format: + return PyUnicode_FromString("IEEE, big-endian"); + default: + Py_FatalError("insane float_format or double_format"); + return NULL; + } +} + +/*[clinic input] +@classmethod +float.__set_format__ + + typestr: str + Must be 'double' or 'float'. + fmt: str + Must be one of 'unknown', 'IEEE, big-endian' or 'IEEE, little-endian', + and in addition can only be one of the latter two if it appears to + match the underlying C reality. + / + +You probably don't want to use this function. + +It exists mainly to be used in Python's test suite. + +Override the automatic determination of C-level floating point type. +This affects how floats are converted to and from binary strings. +[clinic start generated code]*/ + +static PyObject * +float___set_format___impl(PyTypeObject *type, const char *typestr, + const char *fmt) +/*[clinic end generated code: output=504460f5dc85acbd input=5306fa2b81a997e4]*/ +{ + float_format_type f; + float_format_type detected; + float_format_type *p; + + if (strcmp(typestr, "double") == 0) { + p = &double_format; + detected = detected_double_format; + } + else if (strcmp(typestr, "float") == 0) { + p = &float_format; + detected = detected_float_format; + } + else { + PyErr_SetString(PyExc_ValueError, + "__setformat__() argument 1 must " + "be 'double' or 'float'"); + return NULL; + } + + if (strcmp(fmt, "unknown") == 0) { + f = unknown_format; + } + else if (strcmp(fmt, "IEEE, little-endian") == 0) { + f = ieee_little_endian_format; + } + else if (strcmp(fmt, "IEEE, big-endian") == 0) { + f = ieee_big_endian_format; + } + else { + PyErr_SetString(PyExc_ValueError, + "__setformat__() argument 2 must be " + "'unknown', 'IEEE, little-endian' or " + "'IEEE, big-endian'"); + return NULL; + + } + + if (f != unknown_format && f != detected) { + PyErr_Format(PyExc_ValueError, + "can only set %s format to 'unknown' or the " + "detected platform value", typestr); + return NULL; + } + + *p = f; + Py_RETURN_NONE; +} + +static PyObject * +float_getreal(PyObject *v, void *closure) +{ + return float_float(v); +} + +static PyObject * +float_getimag(PyObject *v, void *closure) +{ + return PyFloat_FromDouble(0.0); +} + +/*[clinic input] +float.__format__ + + format_spec: unicode + / + +Formats the float according to format_spec. +[clinic start generated code]*/ + +static PyObject * +float___format___impl(PyObject *self, PyObject *format_spec) +/*[clinic end generated code: output=b260e52a47eade56 input=2ece1052211fd0e6]*/ +{ + _PyUnicodeWriter writer; + int ret; + + _PyUnicodeWriter_Init(&writer); + ret = _PyFloat_FormatAdvancedWriter( + &writer, + self, + format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); + if (ret == -1) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + return _PyUnicodeWriter_Finish(&writer); +} + +static PyMethodDef float_methods[] = { + FLOAT_CONJUGATE_METHODDEF + FLOAT___TRUNC___METHODDEF + FLOAT___ROUND___METHODDEF + FLOAT_AS_INTEGER_RATIO_METHODDEF + FLOAT_FROMHEX_METHODDEF + FLOAT_HEX_METHODDEF + FLOAT_IS_INTEGER_METHODDEF + FLOAT___GETNEWARGS___METHODDEF + FLOAT___GETFORMAT___METHODDEF + FLOAT___SET_FORMAT___METHODDEF + FLOAT___FORMAT___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyGetSetDef float_getset[] = { + {"real", + float_getreal, (setter)NULL, + "the real part of a complex number", + NULL}, + {"imag", + float_getimag, (setter)NULL, + "the imaginary part of a complex number", + NULL}, + {NULL} /* Sentinel */ +}; + + +static PyNumberMethods float_as_number = { + float_add, /* nb_add */ + float_sub, /* nb_subtract */ + float_mul, /* nb_multiply */ + float_rem, /* nb_remainder */ + float_divmod, /* nb_divmod */ + float_pow, /* nb_power */ + (unaryfunc)float_neg, /* nb_negative */ + float_float, /* nb_positive */ + (unaryfunc)float_abs, /* nb_absolute */ + (inquiry)float_bool, /* nb_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + float___trunc___impl, /* nb_int */ + 0, /* nb_reserved */ + float_float, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + float_floor_div, /* nb_floor_divide */ + float_div, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ +}; + +PyTypeObject PyFloat_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "float", + sizeof(PyFloatObject), + 0, + (destructor)float_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)float_repr, /* tp_repr */ + &float_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)float_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + float_new__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + float_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + float_methods, /* tp_methods */ + 0, /* tp_members */ + float_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + float_new, /* tp_new */ +}; + +int +_PyFloat_Init(void) +{ + /* We attempt to determine if this machine is using IEEE + floating point formats by peering at the bits of some + carefully chosen values. If it looks like we are on an + IEEE platform, the float packing/unpacking routines can + just copy bits, if not they resort to arithmetic & shifts + and masks. The shifts & masks approach works on all finite + values, but what happens to infinities, NaNs and signed + zeroes on packing is an accident, and attempting to unpack + a NaN or an infinity will raise an exception. + + Note that if we're on some whacked-out platform which uses + IEEE formats but isn't strictly little-endian or big- + endian, we will fall back to the portable shifts & masks + method. */ + +#if SIZEOF_DOUBLE == 8 + { + double x = 9006104071832581.0; + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) + detected_double_format = ieee_big_endian_format; + else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) + detected_double_format = ieee_little_endian_format; + else + detected_double_format = unknown_format; + } +#else + detected_double_format = unknown_format; +#endif + +#if SIZEOF_FLOAT == 4 + { + float y = 16711938.0; + if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) + detected_float_format = ieee_big_endian_format; + else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) + detected_float_format = ieee_little_endian_format; + else + detected_float_format = unknown_format; + } +#else + detected_float_format = unknown_format; +#endif + + double_format = detected_double_format; + float_format = detected_float_format; + + /* Init float info */ + if (FloatInfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { + return 0; + } + } + return 1; +} + +int +PyFloat_ClearFreeList(void) +{ + PyFloatObject *f = free_list, *next; + int i = numfree; + while (f) { + next = (PyFloatObject*) Py_TYPE(f); + PyObject_FREE(f); + f = next; + } + free_list = NULL; + numfree = 0; + return i; +} + +void +PyFloat_Fini(void) +{ + (void)PyFloat_ClearFreeList(); +} + +/* Print summary info about the state of the optimized allocator */ +void +_PyFloat_DebugMallocStats(FILE *out) +{ + _PyDebugAllocatorStats(out, + "free PyFloatObject", + numfree, sizeof(PyFloatObject)); +} + + +/*---------------------------------------------------------------------------- + * _PyFloat_{Pack,Unpack}{2,4,8}. See floatobject.h. + * To match the NPY_HALF_ROUND_TIES_TO_EVEN behavior in: + * https://github.com/numpy/numpy/blob/master/numpy/core/src/npymath/halffloat.c + * We use: + * bits = (unsigned short)f; Note the truncation + * if ((f - bits > 0.5) || (f - bits == 0.5 && bits % 2)) { + * bits++; + * } + */ + +int +_PyFloat_Pack2(double x, unsigned char *p, int le) +{ + unsigned char sign; + int e; + double f; + unsigned short bits; + int incr = 1; + + if (x == 0.0) { + sign = (copysign(1.0, x) == -1.0); + e = 0; + bits = 0; + } + else if (Py_IS_INFINITY(x)) { + sign = (x < 0.0); + e = 0x1f; + bits = 0; + } + else if (Py_IS_NAN(x)) { + /* There are 2046 distinct half-precision NaNs (1022 signaling and + 1024 quiet), but there are only two quiet NaNs that don't arise by + quieting a signaling NaN; we get those by setting the topmost bit + of the fraction field and clearing all other fraction bits. We + choose the one with the appropriate sign. */ + sign = (copysign(1.0, x) == -1.0); + e = 0x1f; + bits = 512; + } + else { + sign = (x < 0.0); + if (sign) { + x = -x; + } + + f = frexp(x, &e); + if (f < 0.5 || f >= 1.0) { + PyErr_SetString(PyExc_SystemError, + "frexp() result out of range"); + return -1; + } + + /* Normalize f to be in the range [1.0, 2.0) */ + f *= 2.0; + e--; + + if (e >= 16) { + goto Overflow; + } + else if (e < -25) { + /* |x| < 2**-25. Underflow to zero. */ + f = 0.0; + e = 0; + } + else if (e < -14) { + /* |x| < 2**-14. Gradual underflow */ + f = ldexp(f, 14 + e); + e = 0; + } + else /* if (!(e == 0 && f == 0.0)) */ { + e += 15; + f -= 1.0; /* Get rid of leading 1 */ + } + + f *= 1024.0; /* 2**10 */ + /* Round to even */ + bits = (unsigned short)f; /* Note the truncation */ + assert(bits < 1024); + assert(e < 31); + if ((f - bits > 0.5) || ((f - bits == 0.5) && (bits % 2 == 1))) { + ++bits; + if (bits == 1024) { + /* The carry propagated out of a string of 10 1 bits. */ + bits = 0; + ++e; + if (e == 31) + goto Overflow; + } + } + } + + bits |= (e << 10) | (sign << 15); + + /* Write out result. */ + if (le) { + p += 1; + incr = -1; + } + + /* First byte */ + *p = (unsigned char)((bits >> 8) & 0xFF); + p += incr; + + /* Second byte */ + *p = (unsigned char)(bits & 0xFF); + + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with e format"); + return -1; +} + +int +_PyFloat_Pack4(double x, unsigned char *p, int le) +{ + if (float_format == unknown_format) { + unsigned char sign; + int e; + double f; + unsigned int fbits; + int incr = 1; + + if (le) { + p += 3; + incr = -1; + } + + if (x < 0) { + sign = 1; + x = -x; + } + else + sign = 0; + + f = frexp(x, &e); + + /* Normalize f to be in the range [1.0, 2.0) */ + if (0.5 <= f && f < 1.0) { + f *= 2.0; + e--; + } + else if (f == 0.0) + e = 0; + else { + PyErr_SetString(PyExc_SystemError, + "frexp() result out of range"); + return -1; + } + + if (e >= 128) + goto Overflow; + else if (e < -126) { + /* Gradual underflow */ + f = ldexp(f, 126 + e); + e = 0; + } + else if (!(e == 0 && f == 0.0)) { + e += 127; + f -= 1.0; /* Get rid of leading 1 */ + } + + f *= 8388608.0; /* 2**23 */ + fbits = (unsigned int)(f + 0.5); /* Round */ + assert(fbits <= 8388608); + if (fbits >> 23) { + /* The carry propagated out of a string of 23 1 bits. */ + fbits = 0; + ++e; + if (e >= 255) + goto Overflow; + } + + /* First byte */ + *p = (sign << 7) | (e >> 1); + p += incr; + + /* Second byte */ + *p = (char) (((e & 1) << 7) | (fbits >> 16)); + p += incr; + + /* Third byte */ + *p = (fbits >> 8) & 0xFF; + p += incr; + + /* Fourth byte */ + *p = fbits & 0xFF; + + /* Done */ + return 0; + + } + else { + float y = (float)x; + int i, incr = 1; + + if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x)) + goto Overflow; + + unsigned char s[sizeof(float)]; + memcpy(s, &y, sizeof(float)); + + if ((float_format == ieee_little_endian_format && !le) + || (float_format == ieee_big_endian_format && le)) { + p += 3; + incr = -1; + } + + for (i = 0; i < 4; i++) { + *p = s[i]; + p += incr; + } + return 0; + } + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with f format"); + return -1; +} + +int +_PyFloat_Pack8(double x, unsigned char *p, int le) +{ + if (double_format == unknown_format) { + unsigned char sign; + int e; + double f; + unsigned int fhi, flo; + int incr = 1; + + if (le) { + p += 7; + incr = -1; + } + + if (x < 0) { + sign = 1; + x = -x; + } + else + sign = 0; + + f = frexp(x, &e); + + /* Normalize f to be in the range [1.0, 2.0) */ + if (0.5 <= f && f < 1.0) { + f *= 2.0; + e--; + } + else if (f == 0.0) + e = 0; + else { + PyErr_SetString(PyExc_SystemError, + "frexp() result out of range"); + return -1; + } + + if (e >= 1024) + goto Overflow; + else if (e < -1022) { + /* Gradual underflow */ + f = ldexp(f, 1022 + e); + e = 0; + } + else if (!(e == 0 && f == 0.0)) { + e += 1023; + f -= 1.0; /* Get rid of leading 1 */ + } + + /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ + f *= 268435456.0; /* 2**28 */ + fhi = (unsigned int)f; /* Truncate */ + assert(fhi < 268435456); + + f -= (double)fhi; + f *= 16777216.0; /* 2**24 */ + flo = (unsigned int)(f + 0.5); /* Round */ + assert(flo <= 16777216); + if (flo >> 24) { + /* The carry propagated out of a string of 24 1 bits. */ + flo = 0; + ++fhi; + if (fhi >> 28) { + /* And it also progagated out of the next 28 bits. */ + fhi = 0; + ++e; + if (e >= 2047) + goto Overflow; + } + } + + /* First byte */ + *p = (sign << 7) | (e >> 4); + p += incr; + + /* Second byte */ + *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); + p += incr; + + /* Third byte */ + *p = (fhi >> 16) & 0xFF; + p += incr; + + /* Fourth byte */ + *p = (fhi >> 8) & 0xFF; + p += incr; + + /* Fifth byte */ + *p = fhi & 0xFF; + p += incr; + + /* Sixth byte */ + *p = (flo >> 16) & 0xFF; + p += incr; + + /* Seventh byte */ + *p = (flo >> 8) & 0xFF; + p += incr; + + /* Eighth byte */ + *p = flo & 0xFF; + /* p += incr; */ + + /* Done */ + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with d format"); + return -1; + } + else { + const unsigned char *s = (unsigned char*)&x; + int i, incr = 1; + + if ((double_format == ieee_little_endian_format && !le) + || (double_format == ieee_big_endian_format && le)) { + p += 7; + incr = -1; + } + + for (i = 0; i < 8; i++) { + *p = *s++; + p += incr; + } + return 0; + } +} + +double +_PyFloat_Unpack2(const unsigned char *p, int le) +{ + unsigned char sign; + int e; + unsigned int f; + double x; + int incr = 1; + + if (le) { + p += 1; + incr = -1; + } + + /* First byte */ + sign = (*p >> 7) & 1; + e = (*p & 0x7C) >> 2; + f = (*p & 0x03) << 8; + p += incr; + + /* Second byte */ + f |= *p; + + if (e == 0x1f) { +#ifdef PY_NO_SHORT_FLOAT_REPR + if (f == 0) { + /* Infinity */ + return sign ? -Py_HUGE_VAL : Py_HUGE_VAL; + } + else { + /* NaN */ +#ifdef Py_NAN + return sign ? -Py_NAN : Py_NAN; +#else + PyErr_SetString( + PyExc_ValueError, + "can't unpack IEEE 754 NaN " + "on platform that does not support NaNs"); + return -1; +#endif /* #ifdef Py_NAN */ + } +#else + if (f == 0) { + /* Infinity */ + return _Py_dg_infinity(sign); + } + else { + /* NaN */ + return _Py_dg_stdnan(sign); + } +#endif /* #ifdef PY_NO_SHORT_FLOAT_REPR */ + } + + x = (double)f / 1024.0; + + if (e == 0) { + e = -14; + } + else { + x += 1.0; + e -= 15; + } + x = ldexp(x, e); + + if (sign) + x = -x; + + return x; +} + +double +_PyFloat_Unpack4(const unsigned char *p, int le) +{ + if (float_format == unknown_format) { + unsigned char sign; + int e; + unsigned int f; + double x; + int incr = 1; + + if (le) { + p += 3; + incr = -1; + } + + /* First byte */ + sign = (*p >> 7) & 1; + e = (*p & 0x7F) << 1; + p += incr; + + /* Second byte */ + e |= (*p >> 7) & 1; + f = (*p & 0x7F) << 16; + p += incr; + + if (e == 255) { + PyErr_SetString( + PyExc_ValueError, + "can't unpack IEEE 754 special value " + "on non-IEEE platform"); + return -1; + } + + /* Third byte */ + f |= *p << 8; + p += incr; + + /* Fourth byte */ + f |= *p; + + x = (double)f / 8388608.0; + + /* XXX This sadly ignores Inf/NaN issues */ + if (e == 0) + e = -126; + else { + x += 1.0; + e -= 127; + } + x = ldexp(x, e); + + if (sign) + x = -x; + + return x; + } + else { + float x; + + if ((float_format == ieee_little_endian_format && !le) + || (float_format == ieee_big_endian_format && le)) { + char buf[4]; + char *d = &buf[3]; + int i; + + for (i = 0; i < 4; i++) { + *d-- = *p++; + } + memcpy(&x, buf, 4); + } + else { + memcpy(&x, p, 4); + } + + return x; + } +} + +double +_PyFloat_Unpack8(const unsigned char *p, int le) +{ + if (double_format == unknown_format) { + unsigned char sign; + int e; + unsigned int fhi, flo; + double x; + int incr = 1; + + if (le) { + p += 7; + incr = -1; + } + + /* First byte */ + sign = (*p >> 7) & 1; + e = (*p & 0x7F) << 4; + + p += incr; + + /* Second byte */ + e |= (*p >> 4) & 0xF; + fhi = (*p & 0xF) << 24; + p += incr; + + if (e == 2047) { + PyErr_SetString( + PyExc_ValueError, + "can't unpack IEEE 754 special value " + "on non-IEEE platform"); + return -1.0; + } + + /* Third byte */ + fhi |= *p << 16; + p += incr; + + /* Fourth byte */ + fhi |= *p << 8; + p += incr; + + /* Fifth byte */ + fhi |= *p; + p += incr; + + /* Sixth byte */ + flo = *p << 16; + p += incr; + + /* Seventh byte */ + flo |= *p << 8; + p += incr; + + /* Eighth byte */ + flo |= *p; + + x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ + x /= 268435456.0; /* 2**28 */ + + if (e == 0) + e = -1022; + else { + x += 1.0; + e -= 1023; + } + x = ldexp(x, e); + + if (sign) + x = -x; + + return x; + } + else { + double x; + + if ((double_format == ieee_little_endian_format && !le) + || (double_format == ieee_big_endian_format && le)) { + char buf[8]; + char *d = &buf[7]; + int i; + + for (i = 0; i < 8; i++) { + *d-- = *p++; + } + memcpy(&x, buf, 8); + } + else { + memcpy(&x, p, 8); + } + + return x; + } +} diff --git a/python/Objects/frameobject.c b/python/Objects/frameobject.c new file mode 100755 index 0000000..a796a59 --- /dev/null +++ b/python/Objects/frameobject.c @@ -0,0 +1,1013 @@ +/* Frame object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" + +#include "code.h" +#include "frameobject.h" +#include "opcode.h" +#include "structmember.h" + +#define OFF(x) offsetof(PyFrameObject, x) + +static PyMemberDef frame_memberlist[] = { + {"f_back", T_OBJECT, OFF(f_back), READONLY}, + {"f_code", T_OBJECT, OFF(f_code), READONLY}, + {"f_builtins", T_OBJECT, OFF(f_builtins), READONLY}, + {"f_globals", T_OBJECT, OFF(f_globals), READONLY}, + {"f_lasti", T_INT, OFF(f_lasti), READONLY}, + {"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0}, + {"f_trace_opcodes", T_BOOL, OFF(f_trace_opcodes), 0}, + {NULL} /* Sentinel */ +}; + +static PyObject * +frame_getlocals(PyFrameObject *f, void *closure) +{ + if (PyFrame_FastToLocalsWithError(f) < 0) + return NULL; + Py_INCREF(f->f_locals); + return f->f_locals; +} + +int +PyFrame_GetLineNumber(PyFrameObject *f) +{ + if (f->f_trace) + return f->f_lineno; + else + return PyCode_Addr2Line(f->f_code, f->f_lasti); +} + +static PyObject * +frame_getlineno(PyFrameObject *f, void *closure) +{ + return PyLong_FromLong(PyFrame_GetLineNumber(f)); +} + + +/* Given the index of the effective opcode, + scan back to construct the oparg with EXTENDED_ARG */ +static unsigned int +get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) +{ + _Py_CODEUNIT word; + unsigned int oparg = _Py_OPARG(codestr[i]); + if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 8; + if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 16; + if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 24; + } + } + } + return oparg; +} + + +/* Setter for f_lineno - you can set f_lineno from within a trace function in + * order to jump to a given line of code, subject to some restrictions. Most + * lines are OK to jump to because they don't make any assumptions about the + * state of the stack (obvious because you could remove the line and the code + * would still work without any stack errors), but there are some constructs + * that limit jumping: + * + * o Lines with an 'except' statement on them can't be jumped to, because + * they expect an exception to be on the top of the stack. + * o Lines that live in a 'finally' block can't be jumped from or to, since + * the END_FINALLY expects to clean up the stack after the 'try' block. + * o 'try', 'with' and 'async with' blocks can't be jumped into because + * the blockstack needs to be set up before their code runs. + * o 'for' and 'async for' loops can't be jumped into because the + * iterator needs to be on the stack. + * o Jumps cannot be made from within a trace function invoked with a + * 'return' or 'exception' event since the eval loop has been exited at + * that time. + */ +static int +frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignored)) +{ + int new_lineno = 0; /* The new value of f_lineno */ + long l_new_lineno; + int overflow; + int new_lasti = 0; /* The new value of f_lasti */ + unsigned char *code = NULL; /* The bytecode for the frame... */ + Py_ssize_t code_len = 0; /* ...and its length */ + unsigned char *lnotab = NULL; /* Iterating over co_lnotab */ + Py_ssize_t lnotab_len = 0; /* (ditto) */ + int offset = 0; /* (ditto) */ + int line = 0; /* (ditto) */ + int addr = 0; /* (ditto) */ + int delta_iblock = 0; /* Scanning the SETUPs and POPs */ + int delta = 0; + int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ + int blockstack_top = 0; /* (ditto) */ + + if (p_new_lineno == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + /* f_lineno must be an integer. */ + if (!PyLong_CheckExact(p_new_lineno)) { + PyErr_SetString(PyExc_ValueError, + "lineno must be an integer"); + return -1; + } + + /* Upon the 'call' trace event of a new frame, f->f_lasti is -1 and + * f->f_trace is NULL, check first on the first condition. + * Forbidding jumps from the 'call' event of a new frame is a side effect + * of allowing to set f_lineno only from trace functions. */ + if (f->f_lasti == -1) { + PyErr_Format(PyExc_ValueError, + "can't jump from the 'call' trace event of a new frame"); + return -1; + } + + /* You can only do this from within a trace function, not via + * _getframe or similar hackery. */ + if (!f->f_trace) { + PyErr_Format(PyExc_ValueError, + "f_lineno can only be set by a trace function"); + return -1; + } + + /* Forbid jumps upon a 'return' trace event (except after executing a + * YIELD_VALUE or YIELD_FROM opcode, f_stacktop is not NULL in that case) + * and upon an 'exception' trace event. + * Jumps from 'call' trace events have already been forbidden above for new + * frames, so this check does not change anything for 'call' events. */ + if (f->f_stacktop == NULL) { + PyErr_SetString(PyExc_ValueError, + "can only jump from a 'line' trace event"); + return -1; + } + + /* Fail if the line comes before the start of the code block. */ + l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow); + if (overflow +#if SIZEOF_LONG > SIZEOF_INT + || l_new_lineno > INT_MAX + || l_new_lineno < INT_MIN +#endif + ) { + PyErr_SetString(PyExc_ValueError, + "lineno out of range"); + return -1; + } + new_lineno = (int)l_new_lineno; + + if (new_lineno < f->f_code->co_firstlineno) { + PyErr_Format(PyExc_ValueError, + "line %d comes before the current code block", + new_lineno); + return -1; + } + else if (new_lineno == f->f_code->co_firstlineno) { + new_lasti = 0; + new_lineno = f->f_code->co_firstlineno; + } + else { + /* Find the bytecode offset for the start of the given + * line, or the first code-owning line after it. */ + char *tmp; + PyBytes_AsStringAndSize(f->f_code->co_lnotab, + &tmp, &lnotab_len); + lnotab = (unsigned char *) tmp; + addr = 0; + line = f->f_code->co_firstlineno; + new_lasti = -1; + for (offset = 0; offset < lnotab_len; offset += 2) { + addr += lnotab[offset]; + line += (signed char)lnotab[offset+1]; + if (line >= new_lineno) { + new_lasti = addr; + new_lineno = line; + break; + } + } + } + + /* If we didn't reach the requested line, return an error. */ + if (new_lasti == -1) { + PyErr_Format(PyExc_ValueError, + "line %d comes after the current code block", + new_lineno); + return -1; + } + + /* We're now ready to look at the bytecode. */ + PyBytes_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len); + + /* The trace function is called with a 'return' trace event after the + * execution of a yield statement. */ + assert(f->f_lasti != -1); + if (code[f->f_lasti] == YIELD_VALUE || code[f->f_lasti] == YIELD_FROM) { + PyErr_SetString(PyExc_ValueError, + "can't jump from a yield statement"); + return -1; + } + + /* You can't jump onto a line with an 'except' statement on it - + * they expect to have an exception on the top of the stack, which + * won't be true if you jump to them. They always start with code + * that either pops the exception using POP_TOP (plain 'except:' + * lines do this) or duplicates the exception on the stack using + * DUP_TOP (if there's an exception type specified). See compile.c, + * 'com_try_except' for the full details. There aren't any other + * cases (AFAIK) where a line's code can start with DUP_TOP or + * POP_TOP, but if any ever appear, they'll be subject to the same + * restriction (but with a different error message). */ + if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) { + PyErr_SetString(PyExc_ValueError, + "can't jump to 'except' line as there's no exception"); + return -1; + } + + /* You can't jump into or out of a 'finally' block because the 'try' + * block leaves something on the stack for the END_FINALLY to clean up. + * So we walk the bytecode, maintaining a simulated blockstack. + * 'blockstack' is a stack of the bytecode addresses of the starts of + * the 'finally' blocks. */ + memset(blockstack, '\0', sizeof(blockstack)); + blockstack_top = 0; + unsigned char prevop = NOP; + for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) { + unsigned char op = code[addr]; + switch (op) { + case SETUP_FINALLY: + case SETUP_WITH: + case SETUP_ASYNC_WITH: + case FOR_ITER: { + unsigned int oparg = get_arg((const _Py_CODEUNIT *)code, + addr / sizeof(_Py_CODEUNIT)); + int target_addr = addr + oparg + sizeof(_Py_CODEUNIT); + assert(target_addr < code_len); + /* Police block-jumping (you can't jump into the middle of a block) + * and ensure that the blockstack finishes up in a sensible state (by + * popping any blocks we're jumping out of). We look at all the + * blockstack operations between the current position and the new + * one, and keep track of how many blocks we drop out of on the way. + * By also keeping track of the lowest blockstack position we see, we + * can tell whether the jump goes into any blocks without coming out + * again - in that case we raise an exception below. */ + int first_in = addr < f->f_lasti && f->f_lasti < target_addr; + int second_in = addr < new_lasti && new_lasti < target_addr; + if (!first_in && second_in) { + PyErr_SetString(PyExc_ValueError, + "can't jump into the middle of a block"); + return -1; + } + int in_for_loop = op == FOR_ITER || code[target_addr] == END_ASYNC_FOR; + if (first_in && !second_in) { + if (!delta_iblock) { + if (in_for_loop) { + /* Pop the iterators of any 'for' and 'async for' loop + * we're jumping out of. */ + delta++; + } + else if (prevop == LOAD_CONST) { + /* Pops None pushed before SETUP_FINALLY. */ + delta++; + } + } + if (!in_for_loop) { + delta_iblock++; + } + } + if (!in_for_loop) { + blockstack[blockstack_top++] = target_addr; + } + break; + } + + case END_FINALLY: { + assert(blockstack_top > 0); + int target_addr = blockstack[--blockstack_top]; + assert(target_addr <= addr); + int first_in = target_addr <= f->f_lasti && f->f_lasti <= addr; + int second_in = target_addr <= new_lasti && new_lasti <= addr; + if (first_in != second_in) { + op = code[target_addr]; + PyErr_Format(PyExc_ValueError, + "can't jump %s %s block", + second_in ? "into" : "out of", + (op == DUP_TOP || op == POP_TOP) ? + "an 'except'" : "a 'finally'"); + return -1; + } + break; + } + } + prevop = op; + } + + /* Verify that the blockstack tracking code didn't get lost. */ + assert(blockstack_top == 0); + + /* Pop any blocks that we're jumping out of. */ + if (delta_iblock > 0) { + f->f_iblock -= delta_iblock; + PyTryBlock *b = &f->f_blockstack[f->f_iblock]; + delta += (int)(f->f_stacktop - f->f_valuestack) - b->b_level; + if (b->b_type == SETUP_FINALLY && + code[b->b_handler] == WITH_CLEANUP_START) + { + /* Pop the exit function. */ + delta++; + } + } + while (delta > 0) { + PyObject *v = (*--f->f_stacktop); + Py_DECREF(v); + delta--; + } + + /* Finally set the new f_lineno and f_lasti and return OK. */ + f->f_lineno = new_lineno; + f->f_lasti = new_lasti; + return 0; +} + +static PyObject * +frame_gettrace(PyFrameObject *f, void *closure) +{ + PyObject* trace = f->f_trace; + + if (trace == NULL) + trace = Py_None; + + Py_INCREF(trace); + + return trace; +} + +static int +frame_settrace(PyFrameObject *f, PyObject* v, void *closure) +{ + /* We rely on f_lineno being accurate when f_trace is set. */ + f->f_lineno = PyFrame_GetLineNumber(f); + + if (v == Py_None) + v = NULL; + Py_XINCREF(v); + Py_XSETREF(f->f_trace, v); + + return 0; +} + + +static PyGetSetDef frame_getsetlist[] = { + {"f_locals", (getter)frame_getlocals, NULL, NULL}, + {"f_lineno", (getter)frame_getlineno, + (setter)frame_setlineno, NULL}, + {"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL}, + {0} +}; + +/* Stack frames are allocated and deallocated at a considerable rate. + In an attempt to improve the speed of function calls, we: + + 1. Hold a single "zombie" frame on each code object. This retains + the allocated and initialised frame object from an invocation of + the code object. The zombie is reanimated the next time we need a + frame object for that code object. Doing this saves the malloc/ + realloc required when using a free_list frame that isn't the + correct size. It also saves some field initialisation. + + In zombie mode, no field of PyFrameObject holds a reference, but + the following fields are still valid: + + * ob_type, ob_size, f_code, f_valuestack; + + * f_locals, f_trace are NULL; + + * f_localsplus does not require re-allocation and + the local variables in f_localsplus are NULL. + + 2. We also maintain a separate free list of stack frames (just like + floats are allocated in a special way -- see floatobject.c). When + a stack frame is on the free list, only the following members have + a meaning: + ob_type == &Frametype + f_back next item on free list, or NULL + f_stacksize size of value stack + ob_size size of localsplus + Note that the value and block stacks are preserved -- this can save + another malloc() call or two (and two free() calls as well!). + Also note that, unlike for integers, each frame object is a + malloc'ed object in its own right -- it is only the actual calls to + malloc() that we are trying to save here, not the administration. + After all, while a typical program may make millions of calls, a + call depth of more than 20 or 30 is probably already exceptional + unless the program contains run-away recursion. I hope. + + Later, PyFrame_MAXFREELIST was added to bound the # of frames saved on + free_list. Else programs creating lots of cyclic trash involving + frames could provoke free_list into growing without bound. +*/ + +static PyFrameObject *free_list = NULL; +static int numfree = 0; /* number of frames currently in free_list */ +/* max value for numfree */ +#define PyFrame_MAXFREELIST 200 + +static void _Py_HOT_FUNCTION +frame_dealloc(PyFrameObject *f) +{ + PyObject **p, **valuestack; + PyCodeObject *co; + + if (_PyObject_GC_IS_TRACKED(f)) + _PyObject_GC_UNTRACK(f); + + Py_TRASHCAN_SAFE_BEGIN(f) + /* Kill all local variables */ + valuestack = f->f_valuestack; + for (p = f->f_localsplus; p < valuestack; p++) + Py_CLEAR(*p); + + /* Free stack */ + if (f->f_stacktop != NULL) { + for (p = valuestack; p < f->f_stacktop; p++) + Py_XDECREF(*p); + } + + Py_XDECREF(f->f_back); + Py_DECREF(f->f_builtins); + Py_DECREF(f->f_globals); + Py_CLEAR(f->f_locals); + Py_CLEAR(f->f_trace); + + co = f->f_code; + if (co->co_zombieframe == NULL) + co->co_zombieframe = f; + else if (numfree < PyFrame_MAXFREELIST) { + ++numfree; + f->f_back = free_list; + free_list = f; + } + else + PyObject_GC_Del(f); + + Py_DECREF(co); + Py_TRASHCAN_SAFE_END(f) +} + +static int +frame_traverse(PyFrameObject *f, visitproc visit, void *arg) +{ + PyObject **fastlocals, **p; + Py_ssize_t i, slots; + + Py_VISIT(f->f_back); + Py_VISIT(f->f_code); + Py_VISIT(f->f_builtins); + Py_VISIT(f->f_globals); + Py_VISIT(f->f_locals); + Py_VISIT(f->f_trace); + + /* locals */ + slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars); + fastlocals = f->f_localsplus; + for (i = slots; --i >= 0; ++fastlocals) + Py_VISIT(*fastlocals); + + /* stack */ + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) + Py_VISIT(*p); + } + return 0; +} + +static int +frame_tp_clear(PyFrameObject *f) +{ + PyObject **fastlocals, **p, **oldtop; + Py_ssize_t i, slots; + + /* Before anything else, make sure that this frame is clearly marked + * as being defunct! Else, e.g., a generator reachable from this + * frame may also point to this frame, believe itself to still be + * active, and try cleaning up this frame again. + */ + oldtop = f->f_stacktop; + f->f_stacktop = NULL; + f->f_executing = 0; + + Py_CLEAR(f->f_trace); + + /* locals */ + slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars); + fastlocals = f->f_localsplus; + for (i = slots; --i >= 0; ++fastlocals) + Py_CLEAR(*fastlocals); + + /* stack */ + if (oldtop != NULL) { + for (p = f->f_valuestack; p < oldtop; p++) + Py_CLEAR(*p); + } + return 0; +} + +static PyObject * +frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) +{ + if (f->f_executing) { + PyErr_SetString(PyExc_RuntimeError, + "cannot clear an executing frame"); + return NULL; + } + if (f->f_gen) { + _PyGen_Finalize(f->f_gen); + assert(f->f_gen == NULL); + } + (void)frame_tp_clear(f); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(clear__doc__, +"F.clear(): clear most references held by the frame"); + +static PyObject * +frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t res, extras, ncells, nfrees; + + ncells = PyTuple_GET_SIZE(f->f_code->co_cellvars); + nfrees = PyTuple_GET_SIZE(f->f_code->co_freevars); + extras = f->f_code->co_stacksize + f->f_code->co_nlocals + + ncells + nfrees; + /* subtract one as it is already included in PyFrameObject */ + res = sizeof(PyFrameObject) + (extras-1) * sizeof(PyObject *); + + return PyLong_FromSsize_t(res); +} + +PyDoc_STRVAR(sizeof__doc__, +"F.__sizeof__() -> size of F in memory, in bytes"); + +static PyObject * +frame_repr(PyFrameObject *f) +{ + int lineno = PyFrame_GetLineNumber(f); + return PyUnicode_FromFormat( + "", + f, f->f_code->co_filename, lineno, f->f_code->co_name); +} + +static PyMethodDef frame_methods[] = { + {"clear", (PyCFunction)frame_clear, METH_NOARGS, + clear__doc__}, + {"__sizeof__", (PyCFunction)frame_sizeof, METH_NOARGS, + sizeof__doc__}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyFrame_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "frame", + sizeof(PyFrameObject), + sizeof(PyObject *), + (destructor)frame_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)frame_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)frame_traverse, /* tp_traverse */ + (inquiry)frame_tp_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + frame_methods, /* tp_methods */ + frame_memberlist, /* tp_members */ + frame_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ +}; + +_Py_IDENTIFIER(__builtins__); + +PyFrameObject* _Py_HOT_FUNCTION +_PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code, + PyObject *globals, PyObject *locals) +{ + PyFrameObject *back = tstate->frame; + PyFrameObject *f; + PyObject *builtins; + Py_ssize_t i; + +#ifdef Py_DEBUG + if (code == NULL || globals == NULL || !PyDict_Check(globals) || + (locals != NULL && !PyMapping_Check(locals))) { + PyErr_BadInternalCall(); + return NULL; + } +#endif + if (back == NULL || back->f_globals != globals) { + builtins = _PyDict_GetItemIdWithError(globals, &PyId___builtins__); + if (builtins) { + if (PyModule_Check(builtins)) { + builtins = PyModule_GetDict(builtins); + assert(builtins != NULL); + } + } + if (builtins == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + /* No builtins! Make up a minimal one + Give them 'None', at least. */ + builtins = PyDict_New(); + if (builtins == NULL || + PyDict_SetItemString( + builtins, "None", Py_None) < 0) + return NULL; + } + else + Py_INCREF(builtins); + + } + else { + /* If we share the globals, we share the builtins. + Save a lookup and a call. */ + builtins = back->f_builtins; + assert(builtins != NULL); + Py_INCREF(builtins); + } + if (code->co_zombieframe != NULL) { + f = code->co_zombieframe; + code->co_zombieframe = NULL; + _Py_NewReference((PyObject *)f); + assert(f->f_code == code); + } + else { + Py_ssize_t extras, ncells, nfrees; + ncells = PyTuple_GET_SIZE(code->co_cellvars); + nfrees = PyTuple_GET_SIZE(code->co_freevars); + extras = code->co_stacksize + code->co_nlocals + ncells + + nfrees; + if (free_list == NULL) { + f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, + extras); + if (f == NULL) { + Py_DECREF(builtins); + return NULL; + } + } + else { + assert(numfree > 0); + --numfree; + f = free_list; + free_list = free_list->f_back; + if (Py_SIZE(f) < extras) { + PyFrameObject *new_f = PyObject_GC_Resize(PyFrameObject, f, extras); + if (new_f == NULL) { + PyObject_GC_Del(f); + Py_DECREF(builtins); + return NULL; + } + f = new_f; + } + _Py_NewReference((PyObject *)f); + } + + f->f_code = code; + extras = code->co_nlocals + ncells + nfrees; + f->f_valuestack = f->f_localsplus + extras; + for (i=0; if_localsplus[i] = NULL; + f->f_locals = NULL; + f->f_trace = NULL; + } + f->f_stacktop = f->f_valuestack; + f->f_builtins = builtins; + Py_XINCREF(back); + f->f_back = back; + Py_INCREF(code); + Py_INCREF(globals); + f->f_globals = globals; + /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */ + if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) == + (CO_NEWLOCALS | CO_OPTIMIZED)) + ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */ + else if (code->co_flags & CO_NEWLOCALS) { + locals = PyDict_New(); + if (locals == NULL) { + Py_DECREF(f); + return NULL; + } + f->f_locals = locals; + } + else { + if (locals == NULL) + locals = globals; + Py_INCREF(locals); + f->f_locals = locals; + } + + f->f_lasti = -1; + f->f_lineno = code->co_firstlineno; + f->f_iblock = 0; + f->f_executing = 0; + f->f_gen = NULL; + f->f_trace_opcodes = 0; + f->f_trace_lines = 1; + + return f; +} + +PyFrameObject* +PyFrame_New(PyThreadState *tstate, PyCodeObject *code, + PyObject *globals, PyObject *locals) +{ + PyFrameObject *f = _PyFrame_New_NoTrack(tstate, code, globals, locals); + if (f) + _PyObject_GC_TRACK(f); + return f; +} + + +/* Block management */ + +void +PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level) +{ + PyTryBlock *b; + if (f->f_iblock >= CO_MAXBLOCKS) + Py_FatalError("XXX block stack overflow"); + b = &f->f_blockstack[f->f_iblock++]; + b->b_type = type; + b->b_level = level; + b->b_handler = handler; +} + +PyTryBlock * +PyFrame_BlockPop(PyFrameObject *f) +{ + PyTryBlock *b; + if (f->f_iblock <= 0) + Py_FatalError("XXX block stack underflow"); + b = &f->f_blockstack[--f->f_iblock]; + return b; +} + +/* Convert between "fast" version of locals and dictionary version. + + map and values are input arguments. map is a tuple of strings. + values is an array of PyObject*. At index i, map[i] is the name of + the variable with value values[i]. The function copies the first + nmap variable from map/values into dict. If values[i] is NULL, + the variable is deleted from dict. + + If deref is true, then the values being copied are cell variables + and the value is extracted from the cell variable before being put + in dict. + */ + +static int +map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, + int deref) +{ + Py_ssize_t j; + assert(PyTuple_Check(map)); + assert(PyDict_Check(dict)); + assert(PyTuple_Size(map) >= nmap); + for (j=0; j < nmap; j++) { + PyObject *key = PyTuple_GET_ITEM(map, j); + PyObject *value = values[j]; + assert(PyUnicode_Check(key)); + if (deref && value != NULL) { + assert(PyCell_Check(value)); + value = PyCell_GET(value); + } + if (value == NULL) { + if (PyObject_DelItem(dict, key) != 0) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); + else + return -1; + } + } + else { + if (PyObject_SetItem(dict, key, value) != 0) + return -1; + } + } + return 0; +} + +/* Copy values from the "locals" dict into the fast locals. + + dict is an input argument containing string keys representing + variables names and arbitrary PyObject* as values. + + map and values are input arguments. map is a tuple of strings. + values is an array of PyObject*. At index i, map[i] is the name of + the variable with value values[i]. The function copies the first + nmap variable from map/values into dict. If values[i] is NULL, + the variable is deleted from dict. + + If deref is true, then the values being copied are cell variables + and the value is extracted from the cell variable before being put + in dict. If clear is true, then variables in map but not in dict + are set to NULL in map; if clear is false, variables missing in + dict are ignored. + + Exceptions raised while modifying the dict are silently ignored, + because there is no good way to report them. +*/ + +static void +dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, + int deref, int clear) +{ + Py_ssize_t j; + assert(PyTuple_Check(map)); + assert(PyDict_Check(dict)); + assert(PyTuple_Size(map) >= nmap); + for (j=0; j < nmap; j++) { + PyObject *key = PyTuple_GET_ITEM(map, j); + PyObject *value = PyObject_GetItem(dict, key); + assert(PyUnicode_Check(key)); + /* We only care about NULLs if clear is true. */ + if (value == NULL) { + PyErr_Clear(); + if (!clear) + continue; + } + if (deref) { + assert(PyCell_Check(values[j])); + if (PyCell_GET(values[j]) != value) { + if (PyCell_Set(values[j], value) < 0) + PyErr_Clear(); + } + } else if (values[j] != value) { + Py_XINCREF(value); + Py_XSETREF(values[j], value); + } + Py_XDECREF(value); + } +} + +int +PyFrame_FastToLocalsWithError(PyFrameObject *f) +{ + /* Merge fast locals into f->f_locals */ + PyObject *locals, *map; + PyObject **fast; + PyCodeObject *co; + Py_ssize_t j; + Py_ssize_t ncells, nfreevars; + + if (f == NULL) { + PyErr_BadInternalCall(); + return -1; + } + locals = f->f_locals; + if (locals == NULL) { + locals = f->f_locals = PyDict_New(); + if (locals == NULL) + return -1; + } + co = f->f_code; + map = co->co_varnames; + if (!PyTuple_Check(map)) { + PyErr_Format(PyExc_SystemError, + "co_varnames must be a tuple, not %s", + Py_TYPE(map)->tp_name); + return -1; + } + fast = f->f_localsplus; + j = PyTuple_GET_SIZE(map); + if (j > co->co_nlocals) + j = co->co_nlocals; + if (co->co_nlocals) { + if (map_to_dict(map, j, locals, fast, 0) < 0) + return -1; + } + ncells = PyTuple_GET_SIZE(co->co_cellvars); + nfreevars = PyTuple_GET_SIZE(co->co_freevars); + if (ncells || nfreevars) { + if (map_to_dict(co->co_cellvars, ncells, + locals, fast + co->co_nlocals, 1)) + return -1; + + /* If the namespace is unoptimized, then one of the + following cases applies: + 1. It does not contain free variables, because it + uses import * or is a top-level namespace. + 2. It is a class namespace. + We don't want to accidentally copy free variables + into the locals dict used by the class. + */ + if (co->co_flags & CO_OPTIMIZED) { + if (map_to_dict(co->co_freevars, nfreevars, + locals, fast + co->co_nlocals + ncells, 1) < 0) + return -1; + } + } + return 0; +} + +void +PyFrame_FastToLocals(PyFrameObject *f) +{ + int res; + + assert(!PyErr_Occurred()); + + res = PyFrame_FastToLocalsWithError(f); + if (res < 0) + PyErr_Clear(); +} + +void +PyFrame_LocalsToFast(PyFrameObject *f, int clear) +{ + /* Merge f->f_locals into fast locals */ + PyObject *locals, *map; + PyObject **fast; + PyObject *error_type, *error_value, *error_traceback; + PyCodeObject *co; + Py_ssize_t j; + Py_ssize_t ncells, nfreevars; + if (f == NULL) + return; + locals = f->f_locals; + co = f->f_code; + map = co->co_varnames; + if (locals == NULL) + return; + if (!PyTuple_Check(map)) + return; + PyErr_Fetch(&error_type, &error_value, &error_traceback); + fast = f->f_localsplus; + j = PyTuple_GET_SIZE(map); + if (j > co->co_nlocals) + j = co->co_nlocals; + if (co->co_nlocals) + dict_to_map(co->co_varnames, j, locals, fast, 0, clear); + ncells = PyTuple_GET_SIZE(co->co_cellvars); + nfreevars = PyTuple_GET_SIZE(co->co_freevars); + if (ncells || nfreevars) { + dict_to_map(co->co_cellvars, ncells, + locals, fast + co->co_nlocals, 1, clear); + /* Same test as in PyFrame_FastToLocals() above. */ + if (co->co_flags & CO_OPTIMIZED) { + dict_to_map(co->co_freevars, nfreevars, + locals, fast + co->co_nlocals + ncells, 1, + clear); + } + } + PyErr_Restore(error_type, error_value, error_traceback); +} + +/* Clear out the free list */ +int +PyFrame_ClearFreeList(void) +{ + int freelist_size = numfree; + + while (free_list != NULL) { + PyFrameObject *f = free_list; + free_list = free_list->f_back; + PyObject_GC_Del(f); + --numfree; + } + assert(numfree == 0); + return freelist_size; +} + +void +PyFrame_Fini(void) +{ + (void)PyFrame_ClearFreeList(); +} + +/* Print summary info about the state of the optimized allocator */ +void +_PyFrame_DebugMallocStats(FILE *out) +{ + _PyDebugAllocatorStats(out, + "free PyFrameObject", + numfree, sizeof(PyFrameObject)); +} + diff --git a/python/Objects/funcobject.c b/python/Objects/funcobject.c new file mode 100755 index 0000000..0fc4e12 --- /dev/null +++ b/python/Objects/funcobject.c @@ -0,0 +1,1057 @@ + +/* Function object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" +#include "code.h" +#include "structmember.h" + +PyObject * +PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname) +{ + PyFunctionObject *op; + PyObject *doc, *consts, *module; + static PyObject *__name__ = NULL; + + if (__name__ == NULL) { + __name__ = PyUnicode_InternFromString("__name__"); + if (__name__ == NULL) + return NULL; + } + + /* __module__: If module name is in globals, use it. + Otherwise, use None. */ + module = PyDict_GetItemWithError(globals, __name__); + if (module) { + Py_INCREF(module); + } + else if (PyErr_Occurred()) { + return NULL; + } + + op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); + if (op == NULL) { + Py_XDECREF(module); + return NULL; + } + /* Note: No failures from this point on, since func_dealloc() does not + expect a partially-created object. */ + + op->func_weakreflist = NULL; + Py_INCREF(code); + op->func_code = code; + Py_INCREF(globals); + op->func_globals = globals; + op->func_name = ((PyCodeObject *)code)->co_name; + Py_INCREF(op->func_name); + op->func_defaults = NULL; /* No default arguments */ + op->func_kwdefaults = NULL; /* No keyword only defaults */ + op->func_closure = NULL; + op->vectorcall = _PyFunction_Vectorcall; + op->func_module = module; + + consts = ((PyCodeObject *)code)->co_consts; + if (PyTuple_Size(consts) >= 1) { + doc = PyTuple_GetItem(consts, 0); + if (!PyUnicode_Check(doc)) + doc = Py_None; + } + else + doc = Py_None; + Py_INCREF(doc); + op->func_doc = doc; + + op->func_dict = NULL; + op->func_annotations = NULL; + + if (qualname) + op->func_qualname = qualname; + else + op->func_qualname = op->func_name; + Py_INCREF(op->func_qualname); + + _PyObject_GC_TRACK(op); + return (PyObject *)op; +} + +PyObject * +PyFunction_New(PyObject *code, PyObject *globals) +{ + return PyFunction_NewWithQualName(code, globals, NULL); +} + +PyObject * +PyFunction_GetCode(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_code; +} + +PyObject * +PyFunction_GetGlobals(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_globals; +} + +PyObject * +PyFunction_GetModule(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_module; +} + +PyObject * +PyFunction_GetDefaults(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_defaults; +} + +int +PyFunction_SetDefaults(PyObject *op, PyObject *defaults) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + if (defaults == Py_None) + defaults = NULL; + else if (defaults && PyTuple_Check(defaults)) { + Py_INCREF(defaults); + } + else { + PyErr_SetString(PyExc_SystemError, "non-tuple default args"); + return -1; + } + Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults); + return 0; +} + +PyObject * +PyFunction_GetKwDefaults(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_kwdefaults; +} + +int +PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + if (defaults == Py_None) + defaults = NULL; + else if (defaults && PyDict_Check(defaults)) { + Py_INCREF(defaults); + } + else { + PyErr_SetString(PyExc_SystemError, + "non-dict keyword only default args"); + return -1; + } + Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults); + return 0; +} + +PyObject * +PyFunction_GetClosure(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_closure; +} + +int +PyFunction_SetClosure(PyObject *op, PyObject *closure) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + if (closure == Py_None) + closure = NULL; + else if (PyTuple_Check(closure)) { + Py_INCREF(closure); + } + else { + PyErr_Format(PyExc_SystemError, + "expected tuple for closure, got '%.100s'", + closure->ob_type->tp_name); + return -1; + } + Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure); + return 0; +} + +PyObject * +PyFunction_GetAnnotations(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_annotations; +} + +int +PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + if (annotations == Py_None) + annotations = NULL; + else if (annotations && PyDict_Check(annotations)) { + Py_INCREF(annotations); + } + else { + PyErr_SetString(PyExc_SystemError, + "non-dict annotations"); + return -1; + } + Py_XSETREF(((PyFunctionObject *)op)->func_annotations, annotations); + return 0; +} + +/* Methods */ + +#define OFF(x) offsetof(PyFunctionObject, x) + +static PyMemberDef func_memberlist[] = { + {"__closure__", T_OBJECT, OFF(func_closure), + RESTRICTED|READONLY}, + {"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED}, + {"__globals__", T_OBJECT, OFF(func_globals), + RESTRICTED|READONLY}, + {"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED}, + {NULL} /* Sentinel */ +}; + +static PyObject * +func_get_code(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + if (PySys_Audit("object.__getattr__", "Os", op, "__code__") < 0) { + return NULL; + } + + Py_INCREF(op->func_code); + return op->func_code; +} + +static int +func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + Py_ssize_t nfree, nclosure; + + /* Not legal to del f.func_code or to set it to anything + * other than a code object. */ + if (value == NULL || !PyCode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__code__ must be set to a code object"); + return -1; + } + + if (PySys_Audit("object.__setattr__", "OsO", + op, "__code__", value) < 0) { + return -1; + } + + nfree = PyCode_GetNumFree((PyCodeObject *)value); + nclosure = (op->func_closure == NULL ? 0 : + PyTuple_GET_SIZE(op->func_closure)); + if (nclosure != nfree) { + PyErr_Format(PyExc_ValueError, + "%U() requires a code object with %zd free vars," + " not %zd", + op->func_name, + nclosure, nfree); + return -1; + } + Py_INCREF(value); + Py_XSETREF(op->func_code, value); + return 0; +} + +static PyObject * +func_get_name(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + Py_INCREF(op->func_name); + return op->func_name; +} + +static int +func_set_name(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + /* Not legal to del f.func_name or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + Py_XSETREF(op->func_name, value); + return 0; +} + +static PyObject * +func_get_qualname(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + Py_INCREF(op->func_qualname); + return op->func_qualname; +} + +static int +func_set_qualname(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + /* Not legal to del f.__qualname__ or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + Py_XSETREF(op->func_qualname, value); + return 0; +} + +static PyObject * +func_get_defaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + if (PySys_Audit("object.__getattr__", "Os", op, "__defaults__") < 0) { + return NULL; + } + if (op->func_defaults == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(op->func_defaults); + return op->func_defaults; +} + +static int +func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + /* Legal to del f.func_defaults. + * Can only set func_defaults to NULL or a tuple. */ + if (value == Py_None) + value = NULL; + if (value != NULL && !PyTuple_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + if (value) { + if (PySys_Audit("object.__setattr__", "OsO", + op, "__defaults__", value) < 0) { + return -1; + } + } else if (PySys_Audit("object.__delattr__", "Os", + op, "__defaults__") < 0) { + return -1; + } + + Py_XINCREF(value); + Py_XSETREF(op->func_defaults, value); + return 0; +} + +static PyObject * +func_get_kwdefaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + if (PySys_Audit("object.__getattr__", "Os", + op, "__kwdefaults__") < 0) { + return NULL; + } + if (op->func_kwdefaults == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(op->func_kwdefaults); + return op->func_kwdefaults; +} + +static int +func_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + if (value == Py_None) + value = NULL; + /* Legal to del f.func_kwdefaults. + * Can only set func_kwdefaults to NULL or a dict. */ + if (value != NULL && !PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + if (value) { + if (PySys_Audit("object.__setattr__", "OsO", + op, "__kwdefaults__", value) < 0) { + return -1; + } + } else if (PySys_Audit("object.__delattr__", "Os", + op, "__kwdefaults__") < 0) { + return -1; + } + + Py_XINCREF(value); + Py_XSETREF(op->func_kwdefaults, value); + return 0; +} + +static PyObject * +func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + if (op->func_annotations == NULL) { + op->func_annotations = PyDict_New(); + if (op->func_annotations == NULL) + return NULL; + } + Py_INCREF(op->func_annotations); + return op->func_annotations; +} + +static int +func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + if (value == Py_None) + value = NULL; + /* Legal to del f.func_annotations. + * Can only set func_annotations to NULL (through C api) + * or a dict. */ + if (value != NULL && !PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + Py_XSETREF(op->func_annotations, value); + return 0; +} + +static PyGetSetDef func_getsetlist[] = { + {"__code__", (getter)func_get_code, (setter)func_set_code}, + {"__defaults__", (getter)func_get_defaults, + (setter)func_set_defaults}, + {"__kwdefaults__", (getter)func_get_kwdefaults, + (setter)func_set_kwdefaults}, + {"__annotations__", (getter)func_get_annotations, + (setter)func_set_annotations}, + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {"__name__", (getter)func_get_name, (setter)func_set_name}, + {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname}, + {NULL} /* Sentinel */ +}; + +/*[clinic input] +class function "PyFunctionObject *" "&PyFunction_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70af9c90aa2e71b0]*/ + +#include "clinic/funcobject.c.h" + +/* function.__new__() maintains the following invariants for closures. + The closure must correspond to the free variables of the code object. + + if len(code.co_freevars) == 0: + closure = NULL + else: + len(closure) == len(code.co_freevars) + for every elt in closure, type(elt) == cell +*/ + +/*[clinic input] +@classmethod +function.__new__ as func_new + code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") + a code object + globals: object(subclass_of="&PyDict_Type") + the globals dictionary + name: object = None + a string that overrides the name from the code object + argdefs as defaults: object = None + a tuple that specifies the default argument values + closure: object = None + a tuple that supplies the bindings for free variables + +Create a function object. +[clinic start generated code]*/ + +static PyObject * +func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, + PyObject *name, PyObject *defaults, PyObject *closure) +/*[clinic end generated code: output=99c6d9da3a24e3be input=93611752fc2daf11]*/ +{ + PyFunctionObject *newfunc; + Py_ssize_t nfree, nclosure; + + if (name != Py_None && !PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, + "arg 3 (name) must be None or string"); + return NULL; + } + if (defaults != Py_None && !PyTuple_Check(defaults)) { + PyErr_SetString(PyExc_TypeError, + "arg 4 (defaults) must be None or tuple"); + return NULL; + } + nfree = PyTuple_GET_SIZE(code->co_freevars); + if (!PyTuple_Check(closure)) { + if (nfree && closure == Py_None) { + PyErr_SetString(PyExc_TypeError, + "arg 5 (closure) must be tuple"); + return NULL; + } + else if (closure != Py_None) { + PyErr_SetString(PyExc_TypeError, + "arg 5 (closure) must be None or tuple"); + return NULL; + } + } + + /* check that the closure is well-formed */ + nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure); + if (nfree != nclosure) + return PyErr_Format(PyExc_ValueError, + "%U requires closure of length %zd, not %zd", + code->co_name, nfree, nclosure); + if (nclosure) { + Py_ssize_t i; + for (i = 0; i < nclosure; i++) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + if (!PyCell_Check(o)) { + return PyErr_Format(PyExc_TypeError, + "arg 5 (closure) expected cell, found %s", + o->ob_type->tp_name); + } + } + } + if (PySys_Audit("function.__new__", "O", code) < 0) { + return NULL; + } + + newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code, + globals); + if (newfunc == NULL) + return NULL; + + if (name != Py_None) { + Py_INCREF(name); + Py_SETREF(newfunc->func_name, name); + } + if (defaults != Py_None) { + Py_INCREF(defaults); + newfunc->func_defaults = defaults; + } + if (closure != Py_None) { + Py_INCREF(closure); + newfunc->func_closure = closure; + } + + return (PyObject *)newfunc; +} + +static int +func_clear(PyFunctionObject *op) +{ + Py_CLEAR(op->func_code); + Py_CLEAR(op->func_globals); + Py_CLEAR(op->func_module); + Py_CLEAR(op->func_name); + Py_CLEAR(op->func_defaults); + Py_CLEAR(op->func_kwdefaults); + Py_CLEAR(op->func_doc); + Py_CLEAR(op->func_dict); + Py_CLEAR(op->func_closure); + Py_CLEAR(op->func_annotations); + Py_CLEAR(op->func_qualname); + return 0; +} + +static void +func_dealloc(PyFunctionObject *op) +{ + _PyObject_GC_UNTRACK(op); + if (op->func_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject *) op); + } + (void)func_clear(op); + PyObject_GC_Del(op); +} + +static PyObject* +func_repr(PyFunctionObject *op) +{ + return PyUnicode_FromFormat("", + op->func_qualname, op); +} + +static int +func_traverse(PyFunctionObject *f, visitproc visit, void *arg) +{ + Py_VISIT(f->func_code); + Py_VISIT(f->func_globals); + Py_VISIT(f->func_module); + Py_VISIT(f->func_defaults); + Py_VISIT(f->func_kwdefaults); + Py_VISIT(f->func_doc); + Py_VISIT(f->func_name); + Py_VISIT(f->func_dict); + Py_VISIT(f->func_closure); + Py_VISIT(f->func_annotations); + Py_VISIT(f->func_qualname); + return 0; +} + +static PyObject * +function_call(PyObject *func, PyObject *args, PyObject *kwargs) +{ + PyObject **stack; + Py_ssize_t nargs; + + stack = _PyTuple_ITEMS(args); + nargs = PyTuple_GET_SIZE(args); + return _PyFunction_FastCallDict(func, stack, nargs, kwargs); +} + +/* Bind a function to an object */ +static PyObject * +func_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + if (obj == Py_None || obj == NULL) { + Py_INCREF(func); + return func; + } + return PyMethod_New(func, obj); +} + +PyTypeObject PyFunction_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "function", + sizeof(PyFunctionObject), + 0, + (destructor)func_dealloc, /* tp_dealloc */ + offsetof(PyFunctionObject, vectorcall), /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)func_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + function_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + _Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ + func_new__doc__, /* tp_doc */ + (traverseproc)func_traverse, /* tp_traverse */ + (inquiry)func_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + func_memberlist, /* tp_members */ + func_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + func_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + func_new, /* tp_new */ +}; + + +/* Class method object */ + +/* A class method receives the class as implicit first argument, + just like an instance method receives the instance. + To declare a class method, use this idiom: + + class C: + @classmethod + def f(cls, arg1, arg2, ...): + ... + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()); the instance is ignored except for its class. + If a class method is called for a derived class, the derived class + object is passed as the implied first argument. + + Class methods are different than C++ or Java static methods. + If you want those, see static methods below. +*/ + +typedef struct { + PyObject_HEAD + PyObject *cm_callable; + PyObject *cm_dict; +} classmethod; + +static void +cm_dealloc(classmethod *cm) +{ + _PyObject_GC_UNTRACK((PyObject *)cm); + Py_XDECREF(cm->cm_callable); + Py_XDECREF(cm->cm_dict); + Py_TYPE(cm)->tp_free((PyObject *)cm); +} + +static int +cm_traverse(classmethod *cm, visitproc visit, void *arg) +{ + Py_VISIT(cm->cm_callable); + Py_VISIT(cm->cm_dict); + return 0; +} + +static int +cm_clear(classmethod *cm) +{ + Py_CLEAR(cm->cm_callable); + Py_CLEAR(cm->cm_dict); + return 0; +} + + +static PyObject * +cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + classmethod *cm = (classmethod *)self; + + if (cm->cm_callable == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "uninitialized classmethod object"); + return NULL; + } + if (type == NULL) + type = (PyObject *)(Py_TYPE(obj)); + return PyMethod_New(cm->cm_callable, type); +} + +static int +cm_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + classmethod *cm = (classmethod *)self; + PyObject *callable; + + if (!_PyArg_NoKeywords("classmethod", kwds)) + return -1; + if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) + return -1; + Py_INCREF(callable); + Py_XSETREF(cm->cm_callable, callable); + return 0; +} + +static PyMemberDef cm_memberlist[] = { + {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyObject * +cm_get___isabstractmethod__(classmethod *cm, void *closure) +{ + int res = _PyObject_IsAbstract(cm->cm_callable); + if (res == -1) { + return NULL; + } + else if (res) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static PyGetSetDef cm_getsetlist[] = { + {"__isabstractmethod__", + (getter)cm_get___isabstractmethod__, NULL, + NULL, + NULL}, + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL}, + {NULL} /* Sentinel */ +}; + +PyDoc_STRVAR(classmethod_doc, +"classmethod(function) -> method\n\ +\n\ +Convert a function to be a class method.\n\ +\n\ +A class method receives the class as implicit first argument,\n\ +just like an instance method receives the instance.\n\ +To declare a class method, use this idiom:\n\ +\n\ + class C:\n\ + @classmethod\n\ + def f(cls, arg1, arg2, ...):\n\ + ...\n\ +\n\ +It can be called either on the class (e.g. C.f()) or on an instance\n\ +(e.g. C().f()). The instance is ignored except for its class.\n\ +If a class method is called for a derived class, the derived class\n\ +object is passed as the implied first argument.\n\ +\n\ +Class methods are different than C++ or Java static methods.\n\ +If you want those, see the staticmethod builtin."); + +PyTypeObject PyClassMethod_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "classmethod", + sizeof(classmethod), + 0, + (destructor)cm_dealloc, /* tp_dealloc */ + 0, /* tp_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, + classmethod_doc, /* tp_doc */ + (traverseproc)cm_traverse, /* tp_traverse */ + (inquiry)cm_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + cm_memberlist, /* tp_members */ + cm_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + cm_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(classmethod, cm_dict), /* tp_dictoffset */ + cm_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +PyObject * +PyClassMethod_New(PyObject *callable) +{ + classmethod *cm = (classmethod *) + PyType_GenericAlloc(&PyClassMethod_Type, 0); + if (cm != NULL) { + Py_INCREF(callable); + cm->cm_callable = callable; + } + return (PyObject *)cm; +} + + +/* Static method object */ + +/* A static method does not receive an implicit first argument. + To declare a static method, use this idiom: + + class C: + @staticmethod + def f(arg1, arg2, ...): + ... + + It can be called either on the class (e.g. C.f()) or on an instance + (e.g. C().f()). Both the class and the instance are ignored, and + neither is passed implicitly as the first argument to the method. + + Static methods in Python are similar to those found in Java or C++. + For a more advanced concept, see class methods above. +*/ + +typedef struct { + PyObject_HEAD + PyObject *sm_callable; + PyObject *sm_dict; +} staticmethod; + +static void +sm_dealloc(staticmethod *sm) +{ + _PyObject_GC_UNTRACK((PyObject *)sm); + Py_XDECREF(sm->sm_callable); + Py_XDECREF(sm->sm_dict); + Py_TYPE(sm)->tp_free((PyObject *)sm); +} + +static int +sm_traverse(staticmethod *sm, visitproc visit, void *arg) +{ + Py_VISIT(sm->sm_callable); + Py_VISIT(sm->sm_dict); + return 0; +} + +static int +sm_clear(staticmethod *sm) +{ + Py_CLEAR(sm->sm_callable); + Py_CLEAR(sm->sm_dict); + return 0; +} + +static PyObject * +sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + staticmethod *sm = (staticmethod *)self; + + if (sm->sm_callable == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "uninitialized staticmethod object"); + return NULL; + } + Py_INCREF(sm->sm_callable); + return sm->sm_callable; +} + +static int +sm_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + staticmethod *sm = (staticmethod *)self; + PyObject *callable; + + if (!_PyArg_NoKeywords("staticmethod", kwds)) + return -1; + if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) + return -1; + Py_INCREF(callable); + Py_XSETREF(sm->sm_callable, callable); + return 0; +} + +static PyMemberDef sm_memberlist[] = { + {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyObject * +sm_get___isabstractmethod__(staticmethod *sm, void *closure) +{ + int res = _PyObject_IsAbstract(sm->sm_callable); + if (res == -1) { + return NULL; + } + else if (res) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static PyGetSetDef sm_getsetlist[] = { + {"__isabstractmethod__", + (getter)sm_get___isabstractmethod__, NULL, + NULL, + NULL}, + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict, NULL, NULL}, + {NULL} /* Sentinel */ +}; + +PyDoc_STRVAR(staticmethod_doc, +"staticmethod(function) -> method\n\ +\n\ +Convert a function to be a static method.\n\ +\n\ +A static method does not receive an implicit first argument.\n\ +To declare a static method, use this idiom:\n\ +\n\ + class C:\n\ + @staticmethod\n\ + def f(arg1, arg2, ...):\n\ + ...\n\ +\n\ +It can be called either on the class (e.g. C.f()) or on an instance\n\ +(e.g. C().f()). Both the class and the instance are ignored, and\n\ +neither is passed implicitly as the first argument to the method.\n\ +\n\ +Static methods in Python are similar to those found in Java or C++.\n\ +For a more advanced concept, see the classmethod builtin."); + +PyTypeObject PyStaticMethod_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "staticmethod", + sizeof(staticmethod), + 0, + (destructor)sm_dealloc, /* tp_dealloc */ + 0, /* tp_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, + staticmethod_doc, /* tp_doc */ + (traverseproc)sm_traverse, /* tp_traverse */ + (inquiry)sm_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + sm_memberlist, /* tp_members */ + sm_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + sm_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(staticmethod, sm_dict), /* tp_dictoffset */ + sm_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +PyObject * +PyStaticMethod_New(PyObject *callable) +{ + staticmethod *sm = (staticmethod *) + PyType_GenericAlloc(&PyStaticMethod_Type, 0); + if (sm != NULL) { + Py_INCREF(callable); + sm->sm_callable = callable; + } + return (PyObject *)sm; +} diff --git a/python/Objects/genobject.c b/python/Objects/genobject.c new file mode 100755 index 0000000..ce7dd48 --- /dev/null +++ b/python/Objects/genobject.c @@ -0,0 +1,2069 @@ +/* Generator object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "frameobject.h" +#include "structmember.h" +#include "opcode.h" + +static PyObject *gen_close(PyGenObject *, PyObject *); +static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *); +static PyObject *async_gen_athrow_new(PyAsyncGenObject *, PyObject *); + +static const char *NON_INIT_CORO_MSG = "can't send non-None value to a " + "just-started coroutine"; + +static const char *ASYNC_GEN_IGNORED_EXIT_MSG = + "async generator ignored GeneratorExit"; + +static inline int +exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg) +{ + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); + return 0; +} + +static int +gen_traverse(PyGenObject *gen, visitproc visit, void *arg) +{ + Py_VISIT((PyObject *)gen->gi_frame); + Py_VISIT(gen->gi_code); + Py_VISIT(gen->gi_name); + Py_VISIT(gen->gi_qualname); + /* No need to visit cr_origin, because it's just tuples/str/int, so can't + participate in a reference cycle. */ + return exc_state_traverse(&gen->gi_exc_state, visit, arg); +} + +void +_PyGen_Finalize(PyObject *self) +{ + PyGenObject *gen = (PyGenObject *)self; + PyObject *res = NULL; + PyObject *error_type, *error_value, *error_traceback; + + if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) { + /* Generator isn't paused, so no need to close */ + return; + } + + if (PyAsyncGen_CheckExact(self)) { + PyAsyncGenObject *agen = (PyAsyncGenObject*)self; + PyObject *finalizer = agen->ag_finalizer; + if (finalizer && !agen->ag_closed) { + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + res = PyObject_CallFunctionObjArgs(finalizer, self, NULL); + + if (res == NULL) { + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); + return; + } + } + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + /* If `gen` is a coroutine, and if it was never awaited on, + issue a RuntimeWarning. */ + if (gen->gi_code != NULL && + ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE && + gen->gi_frame->f_lasti == -1) + { + _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); + } + else { + res = gen_close(gen, NULL); + } + + if (res == NULL) { + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(self); + } + } + else { + Py_DECREF(res); + } + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static inline void +exc_state_clear(_PyErr_StackItem *exc_state) +{ + PyObject *t, *v, *tb; + t = exc_state->exc_type; + v = exc_state->exc_value; + tb = exc_state->exc_traceback; + exc_state->exc_type = NULL; + exc_state->exc_value = NULL; + exc_state->exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); +} + +static void +gen_dealloc(PyGenObject *gen) +{ + PyObject *self = (PyObject *) gen; + + _PyObject_GC_UNTRACK(gen); + + if (gen->gi_weakreflist != NULL) + PyObject_ClearWeakRefs(self); + + _PyObject_GC_TRACK(self); + + if (PyObject_CallFinalizerFromDealloc(self)) + return; /* resurrected. :( */ + + _PyObject_GC_UNTRACK(self); + if (PyAsyncGen_CheckExact(gen)) { + /* We have to handle this case for asynchronous generators + right here, because this code has to be between UNTRACK + and GC_Del. */ + Py_CLEAR(((PyAsyncGenObject*)gen)->ag_finalizer); + } + if (gen->gi_frame != NULL) { + gen->gi_frame->f_gen = NULL; + Py_CLEAR(gen->gi_frame); + } + if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) { + Py_CLEAR(((PyCoroObject *)gen)->cr_origin); + } + Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); + exc_state_clear(&gen->gi_exc_state); + PyObject_GC_Del(gen); +} + +static PyObject * +gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *f = gen->gi_frame; + PyObject *result; + + if (gen->gi_running) { + const char *msg = "generator already executing"; + if (PyCoro_CheckExact(gen)) { + msg = "coroutine already executing"; + } + else if (PyAsyncGen_CheckExact(gen)) { + msg = "async generator already executing"; + } + PyErr_SetString(PyExc_ValueError, msg); + return NULL; + } + if (f == NULL || f->f_stacktop == NULL) { + if (PyCoro_CheckExact(gen) && !closing) { + /* `gen` is an exhausted coroutine: raise an error, + except when called from gen_close(), which should + always be a silent method. */ + PyErr_SetString( + PyExc_RuntimeError, + "cannot reuse already awaited coroutine"); + } + else if (arg && !exc) { + /* `gen` is an exhausted generator: + only set exception if called from send(). */ + if (PyAsyncGen_CheckExact(gen)) { + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else { + PyErr_SetNone(PyExc_StopIteration); + } + } + return NULL; + } + + if (f->f_lasti == -1) { + if (arg && arg != Py_None) { + const char *msg = "can't send non-None value to a " + "just-started generator"; + if (PyCoro_CheckExact(gen)) { + msg = NON_INIT_CORO_MSG; + } + else if (PyAsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a " + "just-started async generator"; + } + PyErr_SetString(PyExc_TypeError, msg); + return NULL; + } + } else { + /* Push arg onto the frame's value stack */ + result = arg ? arg : Py_None; + Py_INCREF(result); + *(f->f_stacktop++) = result; + } + + /* Generators always return to their most recent caller, not + * necessarily their creator. */ + Py_XINCREF(tstate->frame); + assert(f->f_back == NULL); + f->f_back = tstate->frame; + + gen->gi_running = 1; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + result = PyEval_EvalFrameEx(f, exc); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + gen->gi_running = 0; + + /* Don't keep the reference to f_back any longer than necessary. It + * may keep a chain of frames alive or it could create a reference + * cycle. */ + assert(f->f_back == tstate->frame); + Py_CLEAR(f->f_back); + + /* If the generator just returned (as opposed to yielding), signal + * that the generator is exhausted. */ + if (result && f->f_stacktop == NULL) { + if (result == Py_None) { + /* Delay exception instantiation if we can */ + if (PyAsyncGen_CheckExact(gen)) { + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else { + PyErr_SetNone(PyExc_StopIteration); + } + } + else { + /* Async generators cannot return anything but None */ + assert(!PyAsyncGen_CheckExact(gen)); + _PyGen_SetStopIterationValue(result); + } + Py_CLEAR(result); + } + else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) { + const char *msg = "generator raised StopIteration"; + if (PyCoro_CheckExact(gen)) { + msg = "coroutine raised StopIteration"; + } + else if PyAsyncGen_CheckExact(gen) { + msg = "async generator raised StopIteration"; + } + _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); + + } + else if (!result && PyAsyncGen_CheckExact(gen) && + PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) + { + /* code in `gen` raised a StopAsyncIteration error: + raise a RuntimeError. + */ + const char *msg = "async generator raised StopAsyncIteration"; + _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); + } + + if (!result || f->f_stacktop == NULL) { + /* generator can't be rerun, so release the frame */ + /* first clean reference cycle through stored exception traceback */ + exc_state_clear(&gen->gi_exc_state); + gen->gi_frame->f_gen = NULL; + gen->gi_frame = NULL; + Py_DECREF(f); + } + + return result; +} + +PyDoc_STRVAR(send_doc, +"send(arg) -> send 'arg' into generator,\n\ +return next yielded value or raise StopIteration."); + +PyObject * +_PyGen_Send(PyGenObject *gen, PyObject *arg) +{ + return gen_send_ex(gen, arg, 0, 0); +} + +PyDoc_STRVAR(close_doc, +"close() -> raise GeneratorExit inside generator."); + +/* + * This helper function is used by gen_close and gen_throw to + * close a subiterator being delegated to by yield-from. + */ + +static int +gen_close_iter(PyObject *yf) +{ + PyObject *retval = NULL; + _Py_IDENTIFIER(close); + + if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { + retval = gen_close((PyGenObject *)yf, NULL); + if (retval == NULL) + return -1; + } + else { + PyObject *meth; + if (_PyObject_LookupAttrId(yf, &PyId_close, &meth) < 0) { + PyErr_WriteUnraisable(yf); + } + if (meth) { + retval = _PyObject_CallNoArg(meth); + Py_DECREF(meth); + if (retval == NULL) + return -1; + } + } + Py_XDECREF(retval); + return 0; +} + +PyObject * +_PyGen_yf(PyGenObject *gen) +{ + PyObject *yf = NULL; + PyFrameObject *f = gen->gi_frame; + + if (f && f->f_stacktop) { + PyObject *bytecode = f->f_code->co_code; + unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode); + + if (f->f_lasti < 0) { + /* Return immediately if the frame didn't start yet. YIELD_FROM + always come after LOAD_CONST: a code object should not start + with YIELD_FROM */ + assert(code[0] != YIELD_FROM); + return NULL; + } + + if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM) + return NULL; + yf = f->f_stacktop[-1]; + Py_INCREF(yf); + } + + return yf; +} + +static PyObject * +gen_close(PyGenObject *gen, PyObject *args) +{ + PyObject *retval; + PyObject *yf = _PyGen_yf(gen); + int err = 0; + + if (yf) { + gen->gi_running = 1; + err = gen_close_iter(yf); + gen->gi_running = 0; + Py_DECREF(yf); + } + if (err == 0) + PyErr_SetNone(PyExc_GeneratorExit); + retval = gen_send_ex(gen, Py_None, 1, 1); + if (retval) { + const char *msg = "generator ignored GeneratorExit"; + if (PyCoro_CheckExact(gen)) { + msg = "coroutine ignored GeneratorExit"; + } else if (PyAsyncGen_CheckExact(gen)) { + msg = ASYNC_GEN_IGNORED_EXIT_MSG; + } + Py_DECREF(retval); + PyErr_SetString(PyExc_RuntimeError, msg); + return NULL; + } + if (PyErr_ExceptionMatches(PyExc_StopIteration) + || PyErr_ExceptionMatches(PyExc_GeneratorExit)) { + PyErr_Clear(); /* ignore these errors */ + Py_RETURN_NONE; + } + return NULL; +} + + +PyDoc_STRVAR(throw_doc, +"throw(typ[,val[,tb]]) -> raise exception in generator,\n\ +return next yielded value or raise StopIteration."); + +static PyObject * +_gen_throw(PyGenObject *gen, int close_on_genexit, + PyObject *typ, PyObject *val, PyObject *tb) +{ + PyObject *yf = _PyGen_yf(gen); + _Py_IDENTIFIER(throw); + + if (yf) { + PyObject *ret; + int err; + if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && + close_on_genexit + ) { + /* Asynchronous generators *should not* be closed right away. + We have to allow some awaits to work it through, hence the + `close_on_genexit` parameter here. + */ + gen->gi_running = 1; + err = gen_close_iter(yf); + gen->gi_running = 0; + Py_DECREF(yf); + if (err < 0) + return gen_send_ex(gen, Py_None, 1, 0); + goto throw_here; + } + if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { + /* `yf` is a generator or a coroutine. */ + gen->gi_running = 1; + /* Close the generator that we are currently iterating with + 'yield from' or awaiting on with 'await'. */ + ret = _gen_throw((PyGenObject *)yf, close_on_genexit, + typ, val, tb); + gen->gi_running = 0; + } else { + /* `yf` is an iterator or a coroutine-like object. */ + PyObject *meth; + if (_PyObject_LookupAttrId(yf, &PyId_throw, &meth) < 0) { + Py_DECREF(yf); + return NULL; + } + if (meth == NULL) { + Py_DECREF(yf); + goto throw_here; + } + gen->gi_running = 1; + ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL); + gen->gi_running = 0; + Py_DECREF(meth); + } + Py_DECREF(yf); + if (!ret) { + PyObject *val; + /* Pop subiterator from stack */ + ret = *(--gen->gi_frame->f_stacktop); + assert(ret == yf); + Py_DECREF(ret); + /* Termination repetition of YIELD_FROM */ + assert(gen->gi_frame->f_lasti >= 0); + gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT); + if (_PyGen_FetchStopIterationValue(&val) == 0) { + ret = gen_send_ex(gen, val, 0, 0); + Py_DECREF(val); + } else { + ret = gen_send_ex(gen, Py_None, 1, 0); + } + } + return ret; + } + +throw_here: + /* First, check the traceback argument, replacing None with + NULL. */ + if (tb == Py_None) { + tb = NULL; + } + else if (tb != NULL && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "throw() third argument must be a traceback object"); + return NULL; + } + + Py_INCREF(typ); + Py_XINCREF(val); + Py_XINCREF(tb); + + if (PyExceptionClass_Check(typ)) + PyErr_NormalizeException(&typ, &val, &tb); + + else if (PyExceptionInstance_Check(typ)) { + /* Raising an instance. The value should be a dummy. */ + if (val && val != Py_None) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto failed_throw; + } + else { + /* Normalize to raise , */ + Py_XDECREF(val); + val = typ; + typ = PyExceptionInstance_Class(typ); + Py_INCREF(typ); + + if (tb == NULL) + /* Returns NULL if there's no traceback */ + tb = PyException_GetTraceback(val); + } + } + else { + /* Not something you can raise. throw() fails. */ + PyErr_Format(PyExc_TypeError, + "exceptions must be classes or instances " + "deriving from BaseException, not %s", + Py_TYPE(typ)->tp_name); + goto failed_throw; + } + + PyErr_Restore(typ, val, tb); + return gen_send_ex(gen, Py_None, 1, 0); + +failed_throw: + /* Didn't use our arguments, so restore their original refcounts */ + Py_DECREF(typ); + Py_XDECREF(val); + Py_XDECREF(tb); + return NULL; +} + + +static PyObject * +gen_throw(PyGenObject *gen, PyObject *args) +{ + PyObject *typ; + PyObject *tb = NULL; + PyObject *val = NULL; + + if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb)) { + return NULL; + } + + return _gen_throw(gen, 1, typ, val, tb); +} + + +static PyObject * +gen_iternext(PyGenObject *gen) +{ + return gen_send_ex(gen, NULL, 0, 0); +} + +/* + * Set StopIteration with specified value. Value can be arbitrary object + * or NULL. + * + * Returns 0 if StopIteration is set and -1 if any other exception is set. + */ +int +_PyGen_SetStopIterationValue(PyObject *value) +{ + PyObject *e; + + if (value == NULL || + (!PyTuple_Check(value) && !PyExceptionInstance_Check(value))) + { + /* Delay exception instantiation if we can */ + PyErr_SetObject(PyExc_StopIteration, value); + return 0; + } + /* Construct an exception instance manually with + * PyObject_CallFunctionObjArgs and pass it to PyErr_SetObject. + * + * We do this to handle a situation when "value" is a tuple, in which + * case PyErr_SetObject would set the value of StopIteration to + * the first element of the tuple. + * + * (See PyErr_SetObject/_PyErr_CreateException code for details.) + */ + e = PyObject_CallFunctionObjArgs(PyExc_StopIteration, value, NULL); + if (e == NULL) { + return -1; + } + PyErr_SetObject(PyExc_StopIteration, e); + Py_DECREF(e); + return 0; +} + +/* + * If StopIteration exception is set, fetches its 'value' + * attribute if any, otherwise sets pvalue to None. + * + * Returns 0 if no exception or StopIteration is set. + * If any other exception is set, returns -1 and leaves + * pvalue unchanged. + */ + +int +_PyGen_FetchStopIterationValue(PyObject **pvalue) +{ + PyObject *et, *ev, *tb; + PyObject *value = NULL; + + if (PyErr_ExceptionMatches(PyExc_StopIteration)) { + PyErr_Fetch(&et, &ev, &tb); + if (ev) { + /* exception will usually be normalised already */ + if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) { + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) { + /* Avoid normalisation and take ev as value. + * + * Normalization is required if the value is a tuple, in + * that case the value of StopIteration would be set to + * the first element of the tuple. + * + * (See _PyErr_CreateException code for details.) + */ + value = ev; + } else { + /* normalisation required */ + PyErr_NormalizeException(&et, &ev, &tb); + if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) { + PyErr_Restore(et, ev, tb); + return -1; + } + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } + } + Py_XDECREF(et); + Py_XDECREF(tb); + } else if (PyErr_Occurred()) { + return -1; + } + if (value == NULL) { + value = Py_None; + Py_INCREF(value); + } + *pvalue = value; + return 0; +} + +static PyObject * +gen_repr(PyGenObject *gen) +{ + return PyUnicode_FromFormat("", + gen->gi_qualname, gen); +} + +static PyObject * +gen_get_name(PyGenObject *op, void *Py_UNUSED(ignored)) +{ + Py_INCREF(op->gi_name); + return op->gi_name; +} + +static int +gen_set_name(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + /* Not legal to del gen.gi_name or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + Py_XSETREF(op->gi_name, value); + return 0; +} + +static PyObject * +gen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored)) +{ + Py_INCREF(op->gi_qualname); + return op->gi_qualname; +} + +static int +gen_set_qualname(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + /* Not legal to del gen.__qualname__ or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + Py_XSETREF(op->gi_qualname, value); + return 0; +} + +static PyObject * +gen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + PyObject *yf = _PyGen_yf(gen); + if (yf == NULL) + Py_RETURN_NONE; + return yf; +} + +static PyGetSetDef gen_getsetlist[] = { + {"__name__", (getter)gen_get_name, (setter)gen_set_name, + PyDoc_STR("name of the generator")}, + {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname, + PyDoc_STR("qualified name of the generator")}, + {"gi_yieldfrom", (getter)gen_getyieldfrom, NULL, + PyDoc_STR("object being iterated by yield from, or None")}, + {NULL} /* Sentinel */ +}; + +static PyMemberDef gen_memberlist[] = { + {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY}, + {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY}, + {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyMethodDef gen_methods[] = { + {"send",(PyCFunction)_PyGen_Send, METH_O, send_doc}, + {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc}, + {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc}, + {NULL, NULL} /* Sentinel */ +}; + +PyTypeObject PyGen_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "generator", /* tp_name */ + sizeof(PyGenObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)gen_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)gen_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)gen_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)gen_iternext, /* tp_iternext */ + gen_methods, /* tp_methods */ + gen_memberlist, /* tp_members */ + gen_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + _PyGen_Finalize, /* tp_finalize */ +}; + +static PyObject * +gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, + PyObject *name, PyObject *qualname) +{ + PyGenObject *gen = PyObject_GC_New(PyGenObject, type); + if (gen == NULL) { + Py_DECREF(f); + return NULL; + } + gen->gi_frame = f; + f->f_gen = (PyObject *) gen; + Py_INCREF(f->f_code); + gen->gi_code = (PyObject *)(f->f_code); + gen->gi_running = 0; + gen->gi_weakreflist = NULL; + gen->gi_exc_state.exc_type = NULL; + gen->gi_exc_state.exc_value = NULL; + gen->gi_exc_state.exc_traceback = NULL; + gen->gi_exc_state.previous_item = NULL; + if (name != NULL) + gen->gi_name = name; + else + gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name; + Py_INCREF(gen->gi_name); + if (qualname != NULL) + gen->gi_qualname = qualname; + else + gen->gi_qualname = gen->gi_name; + Py_INCREF(gen->gi_qualname); + _PyObject_GC_TRACK(gen); + return (PyObject *)gen; +} + +PyObject * +PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname) +{ + return gen_new_with_qualname(&PyGen_Type, f, name, qualname); +} + +PyObject * +PyGen_New(PyFrameObject *f) +{ + return gen_new_with_qualname(&PyGen_Type, f, NULL, NULL); +} + +int +PyGen_NeedsFinalizing(PyGenObject *gen) +{ + PyFrameObject *f = gen->gi_frame; + + if (f == NULL || f->f_stacktop == NULL) + return 0; /* no frame or empty blockstack == no finalization */ + + /* Any (exception-handling) block type requires cleanup. */ + if (f->f_iblock > 0) + return 1; + + /* No blocks, it's safe to skip finalization. */ + return 0; +} + +/* Coroutine Object */ + +typedef struct { + PyObject_HEAD + PyCoroObject *cw_coroutine; +} PyCoroWrapper; + +static int +gen_is_coroutine(PyObject *o) +{ + if (PyGen_CheckExact(o)) { + PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code; + if (code->co_flags & CO_ITERABLE_COROUTINE) { + return 1; + } + } + return 0; +} + +/* + * This helper function returns an awaitable for `o`: + * - `o` if `o` is a coroutine-object; + * - `type(o)->tp_as_async->am_await(o)` + * + * Raises a TypeError if it's not possible to return + * an awaitable and returns NULL. + */ +PyObject * +_PyCoro_GetAwaitableIter(PyObject *o) +{ + unaryfunc getter = NULL; + PyTypeObject *ot; + + if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) { + /* 'o' is a coroutine. */ + Py_INCREF(o); + return o; + } + + ot = Py_TYPE(o); + if (ot->tp_as_async != NULL) { + getter = ot->tp_as_async->am_await; + } + if (getter != NULL) { + PyObject *res = (*getter)(o); + if (res != NULL) { + if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) { + /* __await__ must return an *iterator*, not + a coroutine or another awaitable (see PEP 492) */ + PyErr_SetString(PyExc_TypeError, + "__await__() returned a coroutine"); + Py_CLEAR(res); + } else if (!PyIter_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__await__() returned non-iterator " + "of type '%.100s'", + Py_TYPE(res)->tp_name); + Py_CLEAR(res); + } + } + return res; + } + + PyErr_Format(PyExc_TypeError, + "object %.100s can't be used in 'await' expression", + ot->tp_name); + return NULL; +} + +static PyObject * +coro_repr(PyCoroObject *coro) +{ + return PyUnicode_FromFormat("", + coro->cr_qualname, coro); +} + +static PyObject * +coro_await(PyCoroObject *coro) +{ + PyCoroWrapper *cw = PyObject_GC_New(PyCoroWrapper, &_PyCoroWrapper_Type); + if (cw == NULL) { + return NULL; + } + Py_INCREF(coro); + cw->cw_coroutine = coro; + _PyObject_GC_TRACK(cw); + return (PyObject *)cw; +} + +static PyObject * +coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored)) +{ + PyObject *yf = _PyGen_yf((PyGenObject *) coro); + if (yf == NULL) + Py_RETURN_NONE; + return yf; +} + +static PyGetSetDef coro_getsetlist[] = { + {"__name__", (getter)gen_get_name, (setter)gen_set_name, + PyDoc_STR("name of the coroutine")}, + {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname, + PyDoc_STR("qualified name of the coroutine")}, + {"cr_await", (getter)coro_get_cr_await, NULL, + PyDoc_STR("object being awaited on, or None")}, + {NULL} /* Sentinel */ +}; + +static PyMemberDef coro_memberlist[] = { + {"cr_frame", T_OBJECT, offsetof(PyCoroObject, cr_frame), READONLY}, + {"cr_running", T_BOOL, offsetof(PyCoroObject, cr_running), READONLY}, + {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY}, + {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin), READONLY}, + {NULL} /* Sentinel */ +}; + +PyDoc_STRVAR(coro_send_doc, +"send(arg) -> send 'arg' into coroutine,\n\ +return next iterated value or raise StopIteration."); + +PyDoc_STRVAR(coro_throw_doc, +"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\ +return next iterated value or raise StopIteration."); + +PyDoc_STRVAR(coro_close_doc, +"close() -> raise GeneratorExit inside coroutine."); + +static PyMethodDef coro_methods[] = { + {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc}, + {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc}, + {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc}, + {NULL, NULL} /* Sentinel */ +}; + +static PyAsyncMethods coro_as_async = { + (unaryfunc)coro_await, /* am_await */ + 0, /* am_aiter */ + 0 /* am_anext */ +}; + +PyTypeObject PyCoro_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "coroutine", /* tp_name */ + sizeof(PyCoroObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)gen_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &coro_as_async, /* tp_as_async */ + (reprfunc)coro_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)gen_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyCoroObject, cr_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + coro_methods, /* tp_methods */ + coro_memberlist, /* tp_members */ + coro_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + _PyGen_Finalize, /* tp_finalize */ +}; + +static void +coro_wrapper_dealloc(PyCoroWrapper *cw) +{ + _PyObject_GC_UNTRACK((PyObject *)cw); + Py_CLEAR(cw->cw_coroutine); + PyObject_GC_Del(cw); +} + +static PyObject * +coro_wrapper_iternext(PyCoroWrapper *cw) +{ + return gen_send_ex((PyGenObject *)cw->cw_coroutine, NULL, 0, 0); +} + +static PyObject * +coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg) +{ + return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 0, 0); +} + +static PyObject * +coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args) +{ + return gen_throw((PyGenObject *)cw->cw_coroutine, args); +} + +static PyObject * +coro_wrapper_close(PyCoroWrapper *cw, PyObject *args) +{ + return gen_close((PyGenObject *)cw->cw_coroutine, args); +} + +static int +coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg) +{ + Py_VISIT((PyObject *)cw->cw_coroutine); + return 0; +} + +static PyMethodDef coro_wrapper_methods[] = { + {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc}, + {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc}, + {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc}, + {NULL, NULL} /* Sentinel */ +}; + +PyTypeObject _PyCoroWrapper_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "coroutine_wrapper", + sizeof(PyCoroWrapper), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)coro_wrapper_dealloc, /* destructor 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, /* tp_flags */ + "A wrapper object implementing __await__ for coroutines.", + (traverseproc)coro_wrapper_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)coro_wrapper_iternext, /* tp_iternext */ + coro_wrapper_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 */ +}; + +static PyObject * +compute_cr_origin(int origin_depth) +{ + PyFrameObject *frame = PyEval_GetFrame(); + /* First count how many frames we have */ + int frame_count = 0; + for (; frame && frame_count < origin_depth; ++frame_count) { + frame = frame->f_back; + } + + /* Now collect them */ + PyObject *cr_origin = PyTuple_New(frame_count); + if (cr_origin == NULL) { + return NULL; + } + frame = PyEval_GetFrame(); + for (int i = 0; i < frame_count; ++i) { + PyObject *frameinfo = Py_BuildValue( + "OiO", + frame->f_code->co_filename, + PyFrame_GetLineNumber(frame), + frame->f_code->co_name); + if (!frameinfo) { + Py_DECREF(cr_origin); + return NULL; + } + PyTuple_SET_ITEM(cr_origin, i, frameinfo); + frame = frame->f_back; + } + + return cr_origin; +} + +PyObject * +PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname) +{ + PyObject *coro = gen_new_with_qualname(&PyCoro_Type, f, name, qualname); + if (!coro) { + return NULL; + } + + PyThreadState *tstate = _PyThreadState_GET(); + int origin_depth = tstate->coroutine_origin_tracking_depth; + + if (origin_depth == 0) { + ((PyCoroObject *)coro)->cr_origin = NULL; + } else { + PyObject *cr_origin = compute_cr_origin(origin_depth); + ((PyCoroObject *)coro)->cr_origin = cr_origin; + if (!cr_origin) { + Py_DECREF(coro); + return NULL; + } + } + + return coro; +} + + +/* ========= Asynchronous Generators ========= */ + + +typedef enum { + AWAITABLE_STATE_INIT, /* new awaitable, has not yet been iterated */ + AWAITABLE_STATE_ITER, /* being iterated */ + AWAITABLE_STATE_CLOSED, /* closed */ +} AwaitableState; + + +typedef struct { + PyObject_HEAD + PyAsyncGenObject *ags_gen; + + /* Can be NULL, when in the __anext__() mode + (equivalent of "asend(None)") */ + PyObject *ags_sendval; + + AwaitableState ags_state; +} PyAsyncGenASend; + + +typedef struct { + PyObject_HEAD + PyAsyncGenObject *agt_gen; + + /* Can be NULL, when in the "aclose()" mode + (equivalent of "athrow(GeneratorExit)") */ + PyObject *agt_args; + + AwaitableState agt_state; +} PyAsyncGenAThrow; + + +typedef struct { + PyObject_HEAD + PyObject *agw_val; +} _PyAsyncGenWrappedValue; + + +#ifndef _PyAsyncGen_MAXFREELIST +#define _PyAsyncGen_MAXFREELIST 80 +#endif + +/* Freelists boost performance 6-10%; they also reduce memory + fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend + are short-living objects that are instantiated for every + __anext__ call. +*/ + +static _PyAsyncGenWrappedValue *ag_value_freelist[_PyAsyncGen_MAXFREELIST]; +static int ag_value_freelist_free = 0; + +static PyAsyncGenASend *ag_asend_freelist[_PyAsyncGen_MAXFREELIST]; +static int ag_asend_freelist_free = 0; + +#define _PyAsyncGenWrappedValue_CheckExact(o) \ + (Py_TYPE(o) == &_PyAsyncGenWrappedValue_Type) + +#define PyAsyncGenASend_CheckExact(o) \ + (Py_TYPE(o) == &_PyAsyncGenASend_Type) + + +static int +async_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg) +{ + Py_VISIT(gen->ag_finalizer); + return gen_traverse((PyGenObject*)gen, visit, arg); +} + + +static PyObject * +async_gen_repr(PyAsyncGenObject *o) +{ + return PyUnicode_FromFormat("", + o->ag_qualname, o); +} + + +static int +async_gen_init_hooks(PyAsyncGenObject *o) +{ + PyThreadState *tstate; + PyObject *finalizer; + PyObject *firstiter; + + if (o->ag_hooks_inited) { + return 0; + } + + o->ag_hooks_inited = 1; + + tstate = _PyThreadState_GET(); + + finalizer = tstate->async_gen_finalizer; + if (finalizer) { + Py_INCREF(finalizer); + o->ag_finalizer = finalizer; + } + + firstiter = tstate->async_gen_firstiter; + if (firstiter) { + PyObject *res; + + Py_INCREF(firstiter); + res = PyObject_CallFunctionObjArgs(firstiter, o, NULL); + Py_DECREF(firstiter); + if (res == NULL) { + return 1; + } + Py_DECREF(res); + } + + return 0; +} + + +static PyObject * +async_gen_anext(PyAsyncGenObject *o) +{ + if (async_gen_init_hooks(o)) { + return NULL; + } + return async_gen_asend_new(o, NULL); +} + + +static PyObject * +async_gen_asend(PyAsyncGenObject *o, PyObject *arg) +{ + if (async_gen_init_hooks(o)) { + return NULL; + } + return async_gen_asend_new(o, arg); +} + + +static PyObject * +async_gen_aclose(PyAsyncGenObject *o, PyObject *arg) +{ + if (async_gen_init_hooks(o)) { + return NULL; + } + return async_gen_athrow_new(o, NULL); +} + +static PyObject * +async_gen_athrow(PyAsyncGenObject *o, PyObject *args) +{ + if (async_gen_init_hooks(o)) { + return NULL; + } + return async_gen_athrow_new(o, args); +} + + +static PyGetSetDef async_gen_getsetlist[] = { + {"__name__", (getter)gen_get_name, (setter)gen_set_name, + PyDoc_STR("name of the async generator")}, + {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname, + PyDoc_STR("qualified name of the async generator")}, + {"ag_await", (getter)coro_get_cr_await, NULL, + PyDoc_STR("object being awaited on, or None")}, + {NULL} /* Sentinel */ +}; + +static PyMemberDef async_gen_memberlist[] = { + {"ag_frame", T_OBJECT, offsetof(PyAsyncGenObject, ag_frame), READONLY}, + {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), + READONLY}, + {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY}, + {NULL} /* Sentinel */ +}; + +PyDoc_STRVAR(async_aclose_doc, +"aclose() -> raise GeneratorExit inside generator."); + +PyDoc_STRVAR(async_asend_doc, +"asend(v) -> send 'v' in generator."); + +PyDoc_STRVAR(async_athrow_doc, +"athrow(typ[,val[,tb]]) -> raise exception in generator."); + +static PyMethodDef async_gen_methods[] = { + {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc}, + {"athrow",(PyCFunction)async_gen_athrow, METH_VARARGS, async_athrow_doc}, + {"aclose", (PyCFunction)async_gen_aclose, METH_NOARGS, async_aclose_doc}, + {NULL, NULL} /* Sentinel */ +}; + + +static PyAsyncMethods async_gen_as_async = { + 0, /* am_await */ + PyObject_SelfIter, /* am_aiter */ + (unaryfunc)async_gen_anext /* am_anext */ +}; + + +PyTypeObject PyAsyncGen_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "async_generator", /* tp_name */ + sizeof(PyAsyncGenObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)gen_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &async_gen_as_async, /* tp_as_async */ + (reprfunc)async_gen_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)async_gen_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyAsyncGenObject, ag_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + async_gen_methods, /* tp_methods */ + async_gen_memberlist, /* tp_members */ + async_gen_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + _PyGen_Finalize, /* tp_finalize */ +}; + + +PyObject * +PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) +{ + PyAsyncGenObject *o; + o = (PyAsyncGenObject *)gen_new_with_qualname( + &PyAsyncGen_Type, f, name, qualname); + if (o == NULL) { + return NULL; + } + o->ag_finalizer = NULL; + o->ag_closed = 0; + o->ag_hooks_inited = 0; + o->ag_running_async = 0; + return (PyObject*)o; +} + + +int +PyAsyncGen_ClearFreeLists(void) +{ + int ret = ag_value_freelist_free + ag_asend_freelist_free; + + while (ag_value_freelist_free) { + _PyAsyncGenWrappedValue *o; + o = ag_value_freelist[--ag_value_freelist_free]; + assert(_PyAsyncGenWrappedValue_CheckExact(o)); + PyObject_GC_Del(o); + } + + while (ag_asend_freelist_free) { + PyAsyncGenASend *o; + o = ag_asend_freelist[--ag_asend_freelist_free]; + assert(Py_TYPE(o) == &_PyAsyncGenASend_Type); + PyObject_GC_Del(o); + } + + return ret; +} + +void +PyAsyncGen_Fini(void) +{ + PyAsyncGen_ClearFreeLists(); +} + + +static PyObject * +async_gen_unwrap_value(PyAsyncGenObject *gen, PyObject *result) +{ + if (result == NULL) { + if (!PyErr_Occurred()) { + PyErr_SetNone(PyExc_StopAsyncIteration); + } + + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) + || PyErr_ExceptionMatches(PyExc_GeneratorExit) + ) { + gen->ag_closed = 1; + } + + gen->ag_running_async = 0; + return NULL; + } + + if (_PyAsyncGenWrappedValue_CheckExact(result)) { + /* async yield */ + _PyGen_SetStopIterationValue(((_PyAsyncGenWrappedValue*)result)->agw_val); + Py_DECREF(result); + gen->ag_running_async = 0; + return NULL; + } + + return result; +} + + +/* ---------- Async Generator ASend Awaitable ------------ */ + + +static void +async_gen_asend_dealloc(PyAsyncGenASend *o) +{ + _PyObject_GC_UNTRACK((PyObject *)o); + Py_CLEAR(o->ags_gen); + Py_CLEAR(o->ags_sendval); + if (ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST) { + assert(PyAsyncGenASend_CheckExact(o)); + ag_asend_freelist[ag_asend_freelist_free++] = o; + } else { + PyObject_GC_Del(o); + } +} + +static int +async_gen_asend_traverse(PyAsyncGenASend *o, visitproc visit, void *arg) +{ + Py_VISIT(o->ags_gen); + Py_VISIT(o->ags_sendval); + return 0; +} + + +static PyObject * +async_gen_asend_send(PyAsyncGenASend *o, PyObject *arg) +{ + PyObject *result; + + if (o->ags_state == AWAITABLE_STATE_CLOSED) { + PyErr_SetString( + PyExc_RuntimeError, + "cannot reuse already awaited __anext__()/asend()"); + return NULL; + } + + if (o->ags_state == AWAITABLE_STATE_INIT) { + if (o->ags_gen->ag_running_async) { + PyErr_SetString( + PyExc_RuntimeError, + "anext(): asynchronous generator is already running"); + return NULL; + } + + if (arg == NULL || arg == Py_None) { + arg = o->ags_sendval; + } + o->ags_state = AWAITABLE_STATE_ITER; + } + + o->ags_gen->ag_running_async = 1; + result = gen_send_ex((PyGenObject*)o->ags_gen, arg, 0, 0); + result = async_gen_unwrap_value(o->ags_gen, result); + + if (result == NULL) { + o->ags_state = AWAITABLE_STATE_CLOSED; + } + + return result; +} + + +static PyObject * +async_gen_asend_iternext(PyAsyncGenASend *o) +{ + return async_gen_asend_send(o, NULL); +} + + +static PyObject * +async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args) +{ + PyObject *result; + + if (o->ags_state == AWAITABLE_STATE_CLOSED) { + PyErr_SetString( + PyExc_RuntimeError, + "cannot reuse already awaited __anext__()/asend()"); + return NULL; + } + + result = gen_throw((PyGenObject*)o->ags_gen, args); + result = async_gen_unwrap_value(o->ags_gen, result); + + if (result == NULL) { + o->ags_state = AWAITABLE_STATE_CLOSED; + } + + return result; +} + + +static PyObject * +async_gen_asend_close(PyAsyncGenASend *o, PyObject *args) +{ + o->ags_state = AWAITABLE_STATE_CLOSED; + Py_RETURN_NONE; +} + + +static PyMethodDef async_gen_asend_methods[] = { + {"send", (PyCFunction)async_gen_asend_send, METH_O, send_doc}, + {"throw", (PyCFunction)async_gen_asend_throw, METH_VARARGS, throw_doc}, + {"close", (PyCFunction)async_gen_asend_close, METH_NOARGS, close_doc}, + {NULL, NULL} /* Sentinel */ +}; + + +static PyAsyncMethods async_gen_asend_as_async = { + PyObject_SelfIter, /* am_await */ + 0, /* am_aiter */ + 0 /* am_anext */ +}; + + +PyTypeObject _PyAsyncGenASend_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "async_generator_asend", /* tp_name */ + sizeof(PyAsyncGenASend), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)async_gen_asend_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &async_gen_asend_as_async, /* 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)async_gen_asend_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)async_gen_asend_iternext, /* tp_iternext */ + async_gen_asend_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 */ +}; + + +static PyObject * +async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) +{ + PyAsyncGenASend *o; + if (ag_asend_freelist_free) { + ag_asend_freelist_free--; + o = ag_asend_freelist[ag_asend_freelist_free]; + _Py_NewReference((PyObject *)o); + } else { + o = PyObject_GC_New(PyAsyncGenASend, &_PyAsyncGenASend_Type); + if (o == NULL) { + return NULL; + } + } + + Py_INCREF(gen); + o->ags_gen = gen; + + Py_XINCREF(sendval); + o->ags_sendval = sendval; + + o->ags_state = AWAITABLE_STATE_INIT; + + _PyObject_GC_TRACK((PyObject*)o); + return (PyObject*)o; +} + + +/* ---------- Async Generator Value Wrapper ------------ */ + + +static void +async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o) +{ + _PyObject_GC_UNTRACK((PyObject *)o); + Py_CLEAR(o->agw_val); + if (ag_value_freelist_free < _PyAsyncGen_MAXFREELIST) { + assert(_PyAsyncGenWrappedValue_CheckExact(o)); + ag_value_freelist[ag_value_freelist_free++] = o; + } else { + PyObject_GC_Del(o); + } +} + + +static int +async_gen_wrapped_val_traverse(_PyAsyncGenWrappedValue *o, + visitproc visit, void *arg) +{ + Py_VISIT(o->agw_val); + return 0; +} + + +PyTypeObject _PyAsyncGenWrappedValue_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "async_generator_wrapped_value", /* tp_name */ + sizeof(_PyAsyncGenWrappedValue), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)async_gen_wrapped_val_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, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)async_gen_wrapped_val_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 */ +}; + + +PyObject * +_PyAsyncGenValueWrapperNew(PyObject *val) +{ + _PyAsyncGenWrappedValue *o; + assert(val); + + if (ag_value_freelist_free) { + ag_value_freelist_free--; + o = ag_value_freelist[ag_value_freelist_free]; + assert(_PyAsyncGenWrappedValue_CheckExact(o)); + _Py_NewReference((PyObject*)o); + } else { + o = PyObject_GC_New(_PyAsyncGenWrappedValue, + &_PyAsyncGenWrappedValue_Type); + if (o == NULL) { + return NULL; + } + } + o->agw_val = val; + Py_INCREF(val); + _PyObject_GC_TRACK((PyObject*)o); + return (PyObject*)o; +} + + +/* ---------- Async Generator AThrow awaitable ------------ */ + + +static void +async_gen_athrow_dealloc(PyAsyncGenAThrow *o) +{ + _PyObject_GC_UNTRACK((PyObject *)o); + Py_CLEAR(o->agt_gen); + Py_CLEAR(o->agt_args); + PyObject_GC_Del(o); +} + + +static int +async_gen_athrow_traverse(PyAsyncGenAThrow *o, visitproc visit, void *arg) +{ + Py_VISIT(o->agt_gen); + Py_VISIT(o->agt_args); + return 0; +} + + +static PyObject * +async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) +{ + PyGenObject *gen = (PyGenObject*)o->agt_gen; + PyFrameObject *f = gen->gi_frame; + PyObject *retval; + + if (o->agt_state == AWAITABLE_STATE_CLOSED) { + PyErr_SetString( + PyExc_RuntimeError, + "cannot reuse already awaited aclose()/athrow()"); + return NULL; + } + + if (f == NULL || f->f_stacktop == NULL) { + o->agt_state = AWAITABLE_STATE_CLOSED; + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + if (o->agt_state == AWAITABLE_STATE_INIT) { + if (o->agt_gen->ag_running_async) { + o->agt_state = AWAITABLE_STATE_CLOSED; + if (o->agt_args == NULL) { + PyErr_SetString( + PyExc_RuntimeError, + "aclose(): asynchronous generator is already running"); + } + else { + PyErr_SetString( + PyExc_RuntimeError, + "athrow(): asynchronous generator is already running"); + } + return NULL; + } + + if (o->agt_gen->ag_closed) { + o->agt_state = AWAITABLE_STATE_CLOSED; + PyErr_SetNone(PyExc_StopAsyncIteration); + return NULL; + } + + if (arg != Py_None) { + PyErr_SetString(PyExc_RuntimeError, NON_INIT_CORO_MSG); + return NULL; + } + + o->agt_state = AWAITABLE_STATE_ITER; + o->agt_gen->ag_running_async = 1; + + if (o->agt_args == NULL) { + /* aclose() mode */ + o->agt_gen->ag_closed = 1; + + retval = _gen_throw((PyGenObject *)gen, + 0, /* Do not close generator when + PyExc_GeneratorExit is passed */ + PyExc_GeneratorExit, NULL, NULL); + + if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { + Py_DECREF(retval); + goto yield_close; + } + } else { + PyObject *typ; + PyObject *tb = NULL; + PyObject *val = NULL; + + if (!PyArg_UnpackTuple(o->agt_args, "athrow", 1, 3, + &typ, &val, &tb)) { + return NULL; + } + + retval = _gen_throw((PyGenObject *)gen, + 0, /* Do not close generator when + PyExc_GeneratorExit is passed */ + typ, val, tb); + retval = async_gen_unwrap_value(o->agt_gen, retval); + } + if (retval == NULL) { + goto check_error; + } + return retval; + } + + assert(o->agt_state == AWAITABLE_STATE_ITER); + + retval = gen_send_ex((PyGenObject *)gen, arg, 0, 0); + if (o->agt_args) { + return async_gen_unwrap_value(o->agt_gen, retval); + } else { + /* aclose() mode */ + if (retval) { + if (_PyAsyncGenWrappedValue_CheckExact(retval)) { + Py_DECREF(retval); + goto yield_close; + } + else { + return retval; + } + } + else { + goto check_error; + } + } + +yield_close: + o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; + PyErr_SetString( + PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); + return NULL; + +check_error: + o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || + PyErr_ExceptionMatches(PyExc_GeneratorExit)) + { + if (o->agt_args == NULL) { + /* when aclose() is called we don't want to propagate + StopAsyncIteration or GeneratorExit; just raise + StopIteration, signalling that this 'aclose()' await + is done. + */ + PyErr_Clear(); + PyErr_SetNone(PyExc_StopIteration); + } + } + return NULL; +} + + +static PyObject * +async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) +{ + PyObject *retval; + + if (o->agt_state == AWAITABLE_STATE_CLOSED) { + PyErr_SetString( + PyExc_RuntimeError, + "cannot reuse already awaited aclose()/athrow()"); + return NULL; + } + + retval = gen_throw((PyGenObject*)o->agt_gen, args); + if (o->agt_args) { + return async_gen_unwrap_value(o->agt_gen, retval); + } else { + /* aclose() mode */ + if (retval && _PyAsyncGenWrappedValue_CheckExact(retval)) { + o->agt_gen->ag_running_async = 0; + o->agt_state = AWAITABLE_STATE_CLOSED; + Py_DECREF(retval); + PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); + return NULL; + } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || + PyErr_ExceptionMatches(PyExc_GeneratorExit)) + { + /* when aclose() is called we don't want to propagate + StopAsyncIteration or GeneratorExit; just raise + StopIteration, signalling that this 'aclose()' await + is done. + */ + PyErr_Clear(); + PyErr_SetNone(PyExc_StopIteration); + } + return retval; + } +} + + +static PyObject * +async_gen_athrow_iternext(PyAsyncGenAThrow *o) +{ + return async_gen_athrow_send(o, Py_None); +} + + +static PyObject * +async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args) +{ + o->agt_state = AWAITABLE_STATE_CLOSED; + Py_RETURN_NONE; +} + + +static PyMethodDef async_gen_athrow_methods[] = { + {"send", (PyCFunction)async_gen_athrow_send, METH_O, send_doc}, + {"throw", (PyCFunction)async_gen_athrow_throw, METH_VARARGS, throw_doc}, + {"close", (PyCFunction)async_gen_athrow_close, METH_NOARGS, close_doc}, + {NULL, NULL} /* Sentinel */ +}; + + +static PyAsyncMethods async_gen_athrow_as_async = { + PyObject_SelfIter, /* am_await */ + 0, /* am_aiter */ + 0 /* am_anext */ +}; + + +PyTypeObject _PyAsyncGenAThrow_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "async_generator_athrow", /* tp_name */ + sizeof(PyAsyncGenAThrow), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)async_gen_athrow_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &async_gen_athrow_as_async, /* 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)async_gen_athrow_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)async_gen_athrow_iternext, /* tp_iternext */ + async_gen_athrow_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 */ +}; + + +static PyObject * +async_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args) +{ + PyAsyncGenAThrow *o; + o = PyObject_GC_New(PyAsyncGenAThrow, &_PyAsyncGenAThrow_Type); + if (o == NULL) { + return NULL; + } + o->agt_gen = gen; + o->agt_args = args; + o->agt_state = AWAITABLE_STATE_INIT; + Py_INCREF(gen); + Py_XINCREF(args); + _PyObject_GC_TRACK((PyObject*)o); + return (PyObject*)o; +} diff --git a/python/Objects/interpreteridobject.c b/python/Objects/interpreteridobject.c new file mode 100755 index 0000000..19e86a2 --- /dev/null +++ b/python/Objects/interpreteridobject.c @@ -0,0 +1,293 @@ +/* InterpreterID object */ + +#include "Python.h" +#include "internal/pycore_pystate.h" +#include "interpreteridobject.h" + + +typedef struct interpid { + PyObject_HEAD + int64_t id; +} interpid; + +static interpid * +newinterpid(PyTypeObject *cls, int64_t id, int force) +{ + PyInterpreterState *interp = _PyInterpreterState_LookUpID(id); + if (interp == NULL) { + if (force) { + PyErr_Clear(); + } + else { + return NULL; + } + } + + if (interp != NULL) { + if (_PyInterpreterState_IDIncref(interp) < 0) { + return NULL; + } + } + + interpid *self = PyObject_New(interpid, cls); + if (self == NULL) { + if (interp != NULL) { + _PyInterpreterState_IDDecref(interp); + } + return NULL; + } + self->id = id; + + return self; +} + +static int +interp_id_converter(PyObject *arg, void *ptr) +{ + int64_t id; + if (PyObject_TypeCheck(arg, &_PyInterpreterID_Type)) { + id = ((interpid *)arg)->id; + } + else if (PyIndex_Check(arg)) { + id = PyLong_AsLongLong(arg); + if (id == -1 && PyErr_Occurred()) { + return 0; + } + if (id < 0) { + PyErr_Format(PyExc_ValueError, + "interpreter ID must be a non-negative int, got %R", arg); + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "interpreter ID must be an int, got %.100s", + arg->ob_type->tp_name); + return 0; + } + *(int64_t *)ptr = id; + return 1; +} + +static PyObject * +interpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", "force", NULL}; + int64_t id; + int force = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&|$p:InterpreterID.__init__", kwlist, + interp_id_converter, &id, &force)) { + return NULL; + } + + return (PyObject *)newinterpid(cls, id, force); +} + +static void +interpid_dealloc(PyObject *v) +{ + int64_t id = ((interpid *)v)->id; + PyInterpreterState *interp = _PyInterpreterState_LookUpID(id); + if (interp != NULL) { + _PyInterpreterState_IDDecref(interp); + } + else { + // already deleted + PyErr_Clear(); + } + Py_TYPE(v)->tp_free(v); +} + +static PyObject * +interpid_repr(PyObject *self) +{ + PyTypeObject *type = Py_TYPE(self); + const char *name = _PyType_Name(type); + interpid *id = (interpid *)self; + return PyUnicode_FromFormat("%s(%" PRId64 ")", name, id->id); +} + +static PyObject * +interpid_str(PyObject *self) +{ + interpid *id = (interpid *)self; + return PyUnicode_FromFormat("%" PRId64 "", id->id); +} + +static PyObject * +interpid_int(PyObject *self) +{ + interpid *id = (interpid *)self; + return PyLong_FromLongLong(id->id); +} + +static PyNumberMethods interpid_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + (unaryfunc)interpid_int, /* nb_int */ + 0, /* nb_reserved */ + 0, /* nb_float */ + + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + + (unaryfunc)interpid_int, /* nb_index */ +}; + +static Py_hash_t +interpid_hash(PyObject *self) +{ + interpid *id = (interpid *)self; + PyObject *obj = PyLong_FromLongLong(id->id); + if (obj == NULL) { + return -1; + } + Py_hash_t hash = PyObject_Hash(obj); + Py_DECREF(obj); + return hash; +} + +static PyObject * +interpid_richcompare(PyObject *self, PyObject *other, int op) +{ + if (op != Py_EQ && op != Py_NE) { + Py_RETURN_NOTIMPLEMENTED; + } + + if (!PyObject_TypeCheck(self, &_PyInterpreterID_Type)) { + Py_RETURN_NOTIMPLEMENTED; + } + + interpid *id = (interpid *)self; + int equal; + if (PyObject_TypeCheck(other, &_PyInterpreterID_Type)) { + interpid *otherid = (interpid *)other; + equal = (id->id == otherid->id); + } + else if (PyLong_CheckExact(other)) { + /* Fast path */ + int overflow; + long long otherid = PyLong_AsLongLongAndOverflow(other, &overflow); + if (otherid == -1 && PyErr_Occurred()) { + return NULL; + } + equal = !overflow && (otherid >= 0) && (id->id == otherid); + } + else if (PyNumber_Check(other)) { + PyObject *pyid = PyLong_FromLongLong(id->id); + if (pyid == NULL) { + return NULL; + } + PyObject *res = PyObject_RichCompare(pyid, other, op); + Py_DECREF(pyid); + return res; + } + else { + Py_RETURN_NOTIMPLEMENTED; + } + + if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(interpid_doc, +"A interpreter ID identifies a interpreter and may be used as an int."); + +PyTypeObject _PyInterpreterID_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "InterpreterID", /* tp_name */ + sizeof(interpid), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)interpid_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)interpid_repr, /* tp_repr */ + &interpid_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + interpid_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)interpid_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + interpid_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + interpid_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + interpid_new, /* tp_new */ +}; + +PyObject *_PyInterpreterID_New(int64_t id) +{ + return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0); +} + +PyObject * +_PyInterpreterState_GetIDObject(PyInterpreterState *interp) +{ + if (_PyInterpreterState_IDInitref(interp) != 0) { + return NULL; + }; + PY_INT64_T id = PyInterpreterState_GetID(interp); + if (id < 0) { + return NULL; + } + return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0); +} + +PyInterpreterState * +_PyInterpreterID_LookUp(PyObject *requested_id) +{ + int64_t id; + if (!interp_id_converter(requested_id, &id)) { + return NULL; + } + return _PyInterpreterState_LookUpID(id); +} diff --git a/python/Objects/iterobject.c b/python/Objects/iterobject.c new file mode 100755 index 0000000..da89298 --- /dev/null +++ b/python/Objects/iterobject.c @@ -0,0 +1,292 @@ +/* Iterator objects */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyObject *it_seq; /* Set to NULL when iterator is exhausted */ +} seqiterobject; + +PyObject * +PySeqIter_New(PyObject *seq) +{ + seqiterobject *it; + + if (!PySequence_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + it = PyObject_GC_New(seqiterobject, &PySeqIter_Type); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} + +static void +iter_dealloc(seqiterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +iter_traverse(seqiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +iter_iternext(PyObject *iterator) +{ + seqiterobject *it; + PyObject *seq; + PyObject *result; + + assert(PySeqIter_Check(iterator)); + it = (seqiterobject *)iterator; + seq = it->it_seq; + if (seq == NULL) + return NULL; + if (it->it_index == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "iter index too large"); + return NULL; + } + + result = PySequence_GetItem(seq, it->it_index); + if (result != NULL) { + it->it_index++; + return result; + } + if (PyErr_ExceptionMatches(PyExc_IndexError) || + PyErr_ExceptionMatches(PyExc_StopIteration)) + { + PyErr_Clear(); + it->it_seq = NULL; + Py_DECREF(seq); + } + return NULL; +} + +static PyObject * +iter_len(seqiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t seqsize, len; + + if (it->it_seq) { + if (_PyObject_HasLen(it->it_seq)) { + seqsize = PySequence_Size(it->it_seq); + if (seqsize == -1) + return NULL; + } + else { + Py_RETURN_NOTIMPLEMENTED; + } + len = seqsize - it->it_index; + if (len >= 0) + return PyLong_FromSsize_t(len); + } + return PyLong_FromLong(0); +} + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); + +static PyObject * +iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + if (it->it_seq != NULL) + return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + it->it_seq, it->it_index); + else + return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyObject * +iter_setstate(seqiterobject *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + it->it_index = index; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef seqiter_methods[] = { + {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)iter_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)iter_setstate, METH_O, setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PySeqIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "iterator", /* tp_name */ + sizeof(seqiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)iter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)iter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + iter_iternext, /* tp_iternext */ + seqiter_methods, /* tp_methods */ + 0, /* tp_members */ +}; + +/* -------------------------------------- */ + +typedef struct { + PyObject_HEAD + PyObject *it_callable; /* Set to NULL when iterator is exhausted */ + PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */ +} calliterobject; + +PyObject * +PyCallIter_New(PyObject *callable, PyObject *sentinel) +{ + calliterobject *it; + it = PyObject_GC_New(calliterobject, &PyCallIter_Type); + if (it == NULL) + return NULL; + Py_INCREF(callable); + it->it_callable = callable; + Py_INCREF(sentinel); + it->it_sentinel = sentinel; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} +static void +calliter_dealloc(calliterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_callable); + Py_XDECREF(it->it_sentinel); + PyObject_GC_Del(it); +} + +static int +calliter_traverse(calliterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_callable); + Py_VISIT(it->it_sentinel); + return 0; +} + +static PyObject * +calliter_iternext(calliterobject *it) +{ + PyObject *result; + + if (it->it_callable == NULL) { + return NULL; + } + + result = _PyObject_CallNoArg(it->it_callable); + if (result != NULL) { + int ok; + + ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ); + if (ok == 0) { + return result; /* Common case, fast path */ + } + + Py_DECREF(result); + if (ok > 0) { + Py_CLEAR(it->it_callable); + Py_CLEAR(it->it_sentinel); + } + } + else if (PyErr_ExceptionMatches(PyExc_StopIteration)) { + PyErr_Clear(); + Py_CLEAR(it->it_callable); + Py_CLEAR(it->it_sentinel); + } + return NULL; +} + +static PyObject * +calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + if (it->it_callable != NULL && it->it_sentinel != NULL) + return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_iter), + it->it_callable, it->it_sentinel); + else + return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); +} + +static PyMethodDef calliter_methods[] = { + {"__reduce__", (PyCFunction)calliter_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyCallIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "callable_iterator", /* tp_name */ + sizeof(calliterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)calliter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)calliter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)calliter_iternext, /* tp_iternext */ + calliter_methods, /* tp_methods */ +}; + + diff --git a/python/Objects/listobject.c b/python/Objects/listobject.c new file mode 100755 index 0000000..3044408 --- /dev/null +++ b/python/Objects/listobject.c @@ -0,0 +1,3403 @@ +/* List object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" +#include "pycore_accu.h" + +#ifdef STDC_HEADERS +#include +#else +#include /* For size_t */ +#endif + +/*[clinic input] +class list "PyListObject *" "&PyList_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f9b222678f9f71e0]*/ + +#include "clinic/listobject.c.h" + +/* Ensure ob_item has room for at least newsize elements, and set + * ob_size to newsize. If newsize > ob_size on entry, the content + * of the new slots at exit is undefined heap trash; it's the caller's + * responsibility to overwrite them with sane values. + * The number of allocated elements may grow, shrink, or stay the same. + * Failure is impossible if newsize <= self.allocated on entry, although + * that partly relies on an assumption that the system realloc() never + * fails when passed a number of bytes <= the number of bytes last + * allocated (the C standard doesn't guarantee this, but it's hard to + * imagine a realloc implementation where it wouldn't be true). + * Note that self->ob_item may change, and even if newsize is less + * than ob_size on entry. + */ +static int +list_resize(PyListObject *self, Py_ssize_t newsize) +{ + PyObject **items; + size_t new_allocated, num_allocated_bytes; + Py_ssize_t allocated = self->allocated; + + /* Bypass realloc() when a previous overallocation is large enough + to accommodate the newsize. If the newsize falls lower than half + the allocated size, then proceed with the realloc() to shrink the list. + */ + if (allocated >= newsize && newsize >= (allocated >> 1)) { + assert(self->ob_item != NULL || newsize == 0); + Py_SIZE(self) = newsize; + return 0; + } + + /* This over-allocates proportional to the list size, making room + * for additional growth. The over-allocation is mild, but is + * enough to give linear-time amortized behavior over a long + * sequence of appends() in the presence of a poorly-performing + * system realloc(). + * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... + * Note: new_allocated won't overflow because the largest possible value + * is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t. + */ + new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6); + if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) { + PyErr_NoMemory(); + return -1; + } + + if (newsize == 0) + new_allocated = 0; + num_allocated_bytes = new_allocated * sizeof(PyObject *); + items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes); + if (items == NULL) { + PyErr_NoMemory(); + return -1; + } + self->ob_item = items; + Py_SIZE(self) = newsize; + self->allocated = new_allocated; + return 0; +} + +static int +list_preallocate_exact(PyListObject *self, Py_ssize_t size) +{ + assert(self->ob_item == NULL); + assert(size > 0); + + PyObject **items = PyMem_New(PyObject*, size); + if (items == NULL) { + PyErr_NoMemory(); + return -1; + } + self->ob_item = items; + self->allocated = size; + return 0; +} + +/* Debug statistic to compare allocations with reuse through the free list */ +#undef SHOW_ALLOC_COUNT +#ifdef SHOW_ALLOC_COUNT +static size_t count_alloc = 0; +static size_t count_reuse = 0; + +static void +show_alloc(void) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (!interp->config.show_alloc_count) { + return; + } + + fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n", + count_alloc); + fprintf(stderr, "List reuse through freelist: %" PY_FORMAT_SIZE_T + "d\n", count_reuse); + fprintf(stderr, "%.2f%% reuse rate\n\n", + (100.0*count_reuse/(count_alloc+count_reuse))); +} +#endif + +/* Empty list reuse scheme to save calls to malloc and free */ +#ifndef PyList_MAXFREELIST +#define PyList_MAXFREELIST 80 +#endif +static PyListObject *free_list[PyList_MAXFREELIST]; +static int numfree = 0; + +int +PyList_ClearFreeList(void) +{ + PyListObject *op; + int ret = numfree; + while (numfree) { + op = free_list[--numfree]; + assert(PyList_CheckExact(op)); + PyObject_GC_Del(op); + } + return ret; +} + +void +PyList_Fini(void) +{ + PyList_ClearFreeList(); +} + +/* Print summary info about the state of the optimized allocator */ +void +_PyList_DebugMallocStats(FILE *out) +{ + _PyDebugAllocatorStats(out, + "free PyListObject", + numfree, sizeof(PyListObject)); +} + +PyObject * +PyList_New(Py_ssize_t size) +{ + PyListObject *op; +#ifdef SHOW_ALLOC_COUNT + static int initialized = 0; + if (!initialized) { + Py_AtExit(show_alloc); + initialized = 1; + } +#endif + + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } + if (numfree) { + numfree--; + op = free_list[numfree]; + _Py_NewReference((PyObject *)op); +#ifdef SHOW_ALLOC_COUNT + count_reuse++; +#endif + } else { + op = PyObject_GC_New(PyListObject, &PyList_Type); + if (op == NULL) + return NULL; +#ifdef SHOW_ALLOC_COUNT + count_alloc++; +#endif + } + if (size <= 0) + op->ob_item = NULL; + else { + op->ob_item = (PyObject **) PyMem_Calloc(size, sizeof(PyObject *)); + if (op->ob_item == NULL) { + Py_DECREF(op); + return PyErr_NoMemory(); + } + } + Py_SIZE(op) = size; + op->allocated = size; + _PyObject_GC_TRACK(op); + return (PyObject *) op; +} + +static PyObject * +list_new_prealloc(Py_ssize_t size) +{ + PyListObject *op = (PyListObject *) PyList_New(0); + if (size == 0 || op == NULL) { + return (PyObject *) op; + } + assert(op->ob_item == NULL); + op->ob_item = PyMem_New(PyObject *, size); + if (op->ob_item == NULL) { + Py_DECREF(op); + return PyErr_NoMemory(); + } + op->allocated = size; + return (PyObject *) op; +} + +Py_ssize_t +PyList_Size(PyObject *op) +{ + if (!PyList_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + else + return Py_SIZE(op); +} + +static inline 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. + + See: Section 14.2 "Bounds Checking" in the Agner Fog + optimization manual found at: + https://www.agner.org/optimize/optimizing_cpp.pdf + */ + return (size_t) i < (size_t) limit; +} + +static PyObject *indexerr = NULL; + +PyObject * +PyList_GetItem(PyObject *op, Py_ssize_t i) +{ + if (!PyList_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + if (!valid_index(i, Py_SIZE(op))) { + if (indexerr == NULL) { + indexerr = PyUnicode_FromString( + "list index out of range"); + if (indexerr == NULL) + return NULL; + } + PyErr_SetObject(PyExc_IndexError, indexerr); + return NULL; + } + return ((PyListObject *)op) -> ob_item[i]; +} + +int +PyList_SetItem(PyObject *op, Py_ssize_t i, + PyObject *newitem) +{ + PyObject **p; + if (!PyList_Check(op)) { + Py_XDECREF(newitem); + PyErr_BadInternalCall(); + return -1; + } + if (!valid_index(i, Py_SIZE(op))) { + Py_XDECREF(newitem); + PyErr_SetString(PyExc_IndexError, + "list assignment index out of range"); + return -1; + } + p = ((PyListObject *)op) -> ob_item + i; + Py_XSETREF(*p, newitem); + return 0; +} + +static int +ins1(PyListObject *self, Py_ssize_t where, PyObject *v) +{ + Py_ssize_t i, n = Py_SIZE(self); + PyObject **items; + if (v == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot add more objects to list"); + return -1; + } + + if (list_resize(self, n+1) < 0) + return -1; + + if (where < 0) { + where += n; + if (where < 0) + where = 0; + } + if (where > n) + where = n; + items = self->ob_item; + for (i = n; --i >= where; ) + items[i+1] = items[i]; + Py_INCREF(v); + items[where] = v; + return 0; +} + +int +PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem) +{ + if (!PyList_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + return ins1((PyListObject *)op, where, newitem); +} + +static int +app1(PyListObject *self, PyObject *v) +{ + Py_ssize_t n = PyList_GET_SIZE(self); + + assert (v != NULL); + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot add more objects to list"); + return -1; + } + + if (list_resize(self, n+1) < 0) + return -1; + + Py_INCREF(v); + PyList_SET_ITEM(self, n, v); + return 0; +} + +int +PyList_Append(PyObject *op, PyObject *newitem) +{ + if (PyList_Check(op) && (newitem != NULL)) + return app1((PyListObject *)op, newitem); + PyErr_BadInternalCall(); + return -1; +} + +/* Methods */ + +static void +list_dealloc(PyListObject *op) +{ + Py_ssize_t i; + PyObject_GC_UnTrack(op); + Py_TRASHCAN_BEGIN(op, list_dealloc) + if (op->ob_item != NULL) { + /* Do it backwards, for Christian Tismer. + There's a simple test case where somehow this reduces + thrashing when a *very* large list is created and + immediately deleted. */ + i = Py_SIZE(op); + while (--i >= 0) { + Py_XDECREF(op->ob_item[i]); + } + PyMem_FREE(op->ob_item); + } + if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) + free_list[numfree++] = op; + else + Py_TYPE(op)->tp_free((PyObject *)op); + Py_TRASHCAN_END +} + +static PyObject * +list_repr(PyListObject *v) +{ + Py_ssize_t i; + PyObject *s; + _PyUnicodeWriter writer; + + if (Py_SIZE(v) == 0) { + return PyUnicode_FromString("[]"); + } + + i = Py_ReprEnter((PyObject*)v); + if (i != 0) { + return i > 0 ? PyUnicode_FromString("[...]") : NULL; + } + + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + /* "[" + "1" + ", 2" * (len - 1) + "]" */ + writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1; + + if (_PyUnicodeWriter_WriteChar(&writer, '[') < 0) + goto error; + + /* Do repr() on each element. Note that this may mutate the list, + so must refetch the list size on each iteration. */ + for (i = 0; i < Py_SIZE(v); ++i) { + if (i > 0) { + if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) + goto error; + } + + s = PyObject_Repr(v->ob_item[i]); + if (s == NULL) + goto error; + + if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) { + Py_DECREF(s); + goto error; + } + Py_DECREF(s); + } + + writer.overallocate = 0; + if (_PyUnicodeWriter_WriteChar(&writer, ']') < 0) + goto error; + + Py_ReprLeave((PyObject *)v); + return _PyUnicodeWriter_Finish(&writer); + +error: + _PyUnicodeWriter_Dealloc(&writer); + Py_ReprLeave((PyObject *)v); + return NULL; +} + +static Py_ssize_t +list_length(PyListObject *a) +{ + return Py_SIZE(a); +} + +static int +list_contains(PyListObject *a, PyObject *el) +{ + PyObject *item; + Py_ssize_t i; + int cmp; + + for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) { + item = PyList_GET_ITEM(a, i); + Py_INCREF(item); + cmp = PyObject_RichCompareBool(el, item, Py_EQ); + Py_DECREF(item); + } + return cmp; +} + +static PyObject * +list_item(PyListObject *a, Py_ssize_t i) +{ + if (!valid_index(i, Py_SIZE(a))) { + if (indexerr == NULL) { + indexerr = PyUnicode_FromString( + "list index out of range"); + if (indexerr == NULL) + return NULL; + } + PyErr_SetObject(PyExc_IndexError, indexerr); + return NULL; + } + Py_INCREF(a->ob_item[i]); + return a->ob_item[i]; +} + +static PyObject * +list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) +{ + PyListObject *np; + PyObject **src, **dest; + Py_ssize_t i, len; + len = ihigh - ilow; + np = (PyListObject *) list_new_prealloc(len); + if (np == NULL) + return NULL; + + src = a->ob_item + ilow; + dest = np->ob_item; + for (i = 0; i < len; i++) { + PyObject *v = src[i]; + Py_INCREF(v); + dest[i] = v; + } + Py_SIZE(np) = len; + return (PyObject *)np; +} + +PyObject * +PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) +{ + if (!PyList_Check(a)) { + PyErr_BadInternalCall(); + return NULL; + } + if (ilow < 0) { + ilow = 0; + } + else if (ilow > Py_SIZE(a)) { + ilow = Py_SIZE(a); + } + if (ihigh < ilow) { + ihigh = ilow; + } + else if (ihigh > Py_SIZE(a)) { + ihigh = Py_SIZE(a); + } + return list_slice((PyListObject *)a, ilow, ihigh); +} + +static PyObject * +list_concat(PyListObject *a, PyObject *bb) +{ + Py_ssize_t size; + Py_ssize_t i; + PyObject **src, **dest; + PyListObject *np; + if (!PyList_Check(bb)) { + PyErr_Format(PyExc_TypeError, + "can only concatenate list (not \"%.200s\") to list", + bb->ob_type->tp_name); + return NULL; + } +#define b ((PyListObject *)bb) + if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) + return PyErr_NoMemory(); + size = Py_SIZE(a) + Py_SIZE(b); + np = (PyListObject *) list_new_prealloc(size); + if (np == NULL) { + return NULL; + } + src = a->ob_item; + dest = np->ob_item; + for (i = 0; i < Py_SIZE(a); i++) { + PyObject *v = src[i]; + Py_INCREF(v); + dest[i] = v; + } + src = b->ob_item; + dest = np->ob_item + Py_SIZE(a); + for (i = 0; i < Py_SIZE(b); i++) { + PyObject *v = src[i]; + Py_INCREF(v); + dest[i] = v; + } + Py_SIZE(np) = size; + return (PyObject *)np; +#undef b +} + +static PyObject * +list_repeat(PyListObject *a, Py_ssize_t n) +{ + Py_ssize_t i, j; + Py_ssize_t size; + PyListObject *np; + PyObject **p, **items; + PyObject *elem; + if (n < 0) + n = 0; + if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) + return PyErr_NoMemory(); + size = Py_SIZE(a) * n; + if (size == 0) + return PyList_New(0); + np = (PyListObject *) list_new_prealloc(size); + if (np == NULL) + return NULL; + + if (Py_SIZE(a) == 1) { + items = np->ob_item; + elem = a->ob_item[0]; + for (i = 0; i < n; i++) { + items[i] = elem; + Py_INCREF(elem); + } + } + else { + p = np->ob_item; + items = a->ob_item; + for (i = 0; i < n; i++) { + for (j = 0; j < Py_SIZE(a); j++) { + *p = items[j]; + Py_INCREF(*p); + p++; + } + } + } + Py_SIZE(np) = size; + return (PyObject *) np; +} + +static int +_list_clear(PyListObject *a) +{ + Py_ssize_t i; + PyObject **item = a->ob_item; + if (item != NULL) { + /* Because XDECREF can recursively invoke operations on + this list, we make it empty first. */ + i = Py_SIZE(a); + Py_SIZE(a) = 0; + a->ob_item = NULL; + a->allocated = 0; + while (--i >= 0) { + Py_XDECREF(item[i]); + } + PyMem_FREE(item); + } + /* Never fails; the return value can be ignored. + Note that there is no guarantee that the list is actually empty + at this point, because XDECREF may have populated it again! */ + return 0; +} + +/* a[ilow:ihigh] = v if v != NULL. + * del a[ilow:ihigh] if v == NULL. + * + * Special speed gimmick: when v is NULL and ihigh - ilow <= 8, it's + * guaranteed the call cannot fail. + */ +static int +list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) +{ + /* Because [X]DECREF can recursively invoke list operations on + this list, we must postpone all [X]DECREF activity until + after the list is back in its canonical shape. Therefore + we must allocate an additional array, 'recycle', into which + we temporarily copy the items that are deleted from the + list. :-( */ + PyObject *recycle_on_stack[8]; + PyObject **recycle = recycle_on_stack; /* will allocate more if needed */ + PyObject **item; + PyObject **vitem = NULL; + PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */ + Py_ssize_t n; /* # of elements in replacement list */ + Py_ssize_t norig; /* # of elements in list getting replaced */ + Py_ssize_t d; /* Change in size */ + Py_ssize_t k; + size_t s; + int result = -1; /* guilty until proved innocent */ +#define b ((PyListObject *)v) + if (v == NULL) + n = 0; + else { + if (a == b) { + /* Special case "a[i:j] = a" -- copy b first */ + v = list_slice(b, 0, Py_SIZE(b)); + if (v == NULL) + return result; + result = list_ass_slice(a, ilow, ihigh, v); + Py_DECREF(v); + return result; + } + v_as_SF = PySequence_Fast(v, "can only assign an iterable"); + if(v_as_SF == NULL) + goto Error; + n = PySequence_Fast_GET_SIZE(v_as_SF); + vitem = PySequence_Fast_ITEMS(v_as_SF); + } + if (ilow < 0) + ilow = 0; + else if (ilow > Py_SIZE(a)) + ilow = Py_SIZE(a); + + if (ihigh < ilow) + ihigh = ilow; + else if (ihigh > Py_SIZE(a)) + ihigh = Py_SIZE(a); + + norig = ihigh - ilow; + assert(norig >= 0); + d = n - norig; + if (Py_SIZE(a) + d == 0) { + Py_XDECREF(v_as_SF); + return _list_clear(a); + } + item = a->ob_item; + /* recycle the items that we are about to remove */ + s = norig * sizeof(PyObject *); + /* If norig == 0, item might be NULL, in which case we may not memcpy from it. */ + if (s) { + if (s > sizeof(recycle_on_stack)) { + recycle = (PyObject **)PyMem_MALLOC(s); + if (recycle == NULL) { + PyErr_NoMemory(); + goto Error; + } + } + memcpy(recycle, &item[ilow], s); + } + + if (d < 0) { /* Delete -d items */ + Py_ssize_t tail; + tail = (Py_SIZE(a) - ihigh) * sizeof(PyObject *); + memmove(&item[ihigh+d], &item[ihigh], tail); + if (list_resize(a, Py_SIZE(a) + d) < 0) { + memmove(&item[ihigh], &item[ihigh+d], tail); + memcpy(&item[ilow], recycle, s); + goto Error; + } + item = a->ob_item; + } + else if (d > 0) { /* Insert d items */ + k = Py_SIZE(a); + if (list_resize(a, k+d) < 0) + goto Error; + item = a->ob_item; + memmove(&item[ihigh+d], &item[ihigh], + (k - ihigh)*sizeof(PyObject *)); + } + for (k = 0; k < n; k++, ilow++) { + PyObject *w = vitem[k]; + Py_XINCREF(w); + item[ilow] = w; + } + for (k = norig - 1; k >= 0; --k) + Py_XDECREF(recycle[k]); + result = 0; + Error: + if (recycle != recycle_on_stack) + PyMem_FREE(recycle); + Py_XDECREF(v_as_SF); + return result; +#undef b +} + +int +PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) +{ + if (!PyList_Check(a)) { + PyErr_BadInternalCall(); + return -1; + } + return list_ass_slice((PyListObject *)a, ilow, ihigh, v); +} + +static PyObject * +list_inplace_repeat(PyListObject *self, Py_ssize_t n) +{ + PyObject **items; + Py_ssize_t size, i, j, p; + + + size = PyList_GET_SIZE(self); + if (size == 0 || n == 1) { + Py_INCREF(self); + return (PyObject *)self; + } + + if (n < 1) { + (void)_list_clear(self); + Py_INCREF(self); + return (PyObject *)self; + } + + if (size > PY_SSIZE_T_MAX / n) { + return PyErr_NoMemory(); + } + + if (list_resize(self, size*n) < 0) + return NULL; + + p = size; + items = self->ob_item; + for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */ + for (j = 0; j < size; j++) { + PyObject *o = items[j]; + Py_INCREF(o); + items[p++] = o; + } + } + Py_INCREF(self); + return (PyObject *)self; +} + +static int +list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v) +{ + if (!valid_index(i, Py_SIZE(a))) { + PyErr_SetString(PyExc_IndexError, + "list assignment index out of range"); + return -1; + } + if (v == NULL) + return list_ass_slice(a, i, i+1, v); + Py_INCREF(v); + Py_SETREF(a->ob_item[i], v); + return 0; +} + +/*[clinic input] +list.insert + + index: Py_ssize_t + object: object + / + +Insert object before index. +[clinic start generated code]*/ + +static PyObject * +list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object) +/*[clinic end generated code: output=7f35e32f60c8cb78 input=858514cf894c7eab]*/ +{ + if (ins1(self, index, object) == 0) + Py_RETURN_NONE; + return NULL; +} + +/*[clinic input] +list.clear + +Remove all items from list. +[clinic start generated code]*/ + +static PyObject * +list_clear_impl(PyListObject *self) +/*[clinic end generated code: output=67a1896c01f74362 input=ca3c1646856742f6]*/ +{ + _list_clear(self); + Py_RETURN_NONE; +} + +/*[clinic input] +list.copy + +Return a shallow copy of the list. +[clinic start generated code]*/ + +static PyObject * +list_copy_impl(PyListObject *self) +/*[clinic end generated code: output=ec6b72d6209d418e input=6453ab159e84771f]*/ +{ + return list_slice(self, 0, Py_SIZE(self)); +} + +/*[clinic input] +list.append + + object: object + / + +Append object to the end of the list. +[clinic start generated code]*/ + +static PyObject * +list_append(PyListObject *self, PyObject *object) +/*[clinic end generated code: output=7c096003a29c0eae input=43a3fe48a7066e91]*/ +{ + if (app1(self, object) == 0) + Py_RETURN_NONE; + return NULL; +} + +/*[clinic input] +list.extend + + iterable: object + / + +Extend list by appending elements from the iterable. +[clinic start generated code]*/ + +static PyObject * +list_extend(PyListObject *self, PyObject *iterable) +/*[clinic end generated code: output=630fb3bca0c8e789 input=9ec5ba3a81be3a4d]*/ +{ + PyObject *it; /* iter(v) */ + Py_ssize_t m; /* size of self */ + Py_ssize_t n; /* guess for size of iterable */ + Py_ssize_t mn; /* m + n */ + Py_ssize_t i; + PyObject *(*iternext)(PyObject *); + + /* Special cases: + 1) lists and tuples which can use PySequence_Fast ops + 2) extending self to self requires making a copy first + */ + if (PyList_CheckExact(iterable) || PyTuple_CheckExact(iterable) || + (PyObject *)self == iterable) { + PyObject **src, **dest; + iterable = PySequence_Fast(iterable, "argument must be iterable"); + if (!iterable) + return NULL; + n = PySequence_Fast_GET_SIZE(iterable); + if (n == 0) { + /* short circuit when iterable is empty */ + Py_DECREF(iterable); + Py_RETURN_NONE; + } + m = Py_SIZE(self); + /* It should not be possible to allocate a list large enough to cause + an overflow on any relevant platform */ + assert(m < PY_SSIZE_T_MAX - n); + if (list_resize(self, m + n) < 0) { + Py_DECREF(iterable); + return NULL; + } + /* note that we may still have self == iterable here for the + * situation a.extend(a), but the following code works + * in that case too. Just make sure to resize self + * before calling PySequence_Fast_ITEMS. + */ + /* populate the end of self with iterable's items */ + src = PySequence_Fast_ITEMS(iterable); + dest = self->ob_item + m; + for (i = 0; i < n; i++) { + PyObject *o = src[i]; + Py_INCREF(o); + dest[i] = o; + } + Py_DECREF(iterable); + Py_RETURN_NONE; + } + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + iternext = *it->ob_type->tp_iternext; + + /* Guess a result list size. */ + n = PyObject_LengthHint(iterable, 8); + if (n < 0) { + Py_DECREF(it); + return NULL; + } + m = Py_SIZE(self); + if (m > PY_SSIZE_T_MAX - n) { + /* m + n overflowed; on the chance that n lied, and there really + * is enough room, ignore it. If n was telling the truth, we'll + * eventually run out of memory during the loop. + */ + } + else { + mn = m + n; + /* Make room. */ + if (list_resize(self, mn) < 0) + goto error; + /* Make the list sane again. */ + Py_SIZE(self) = m; + } + + /* Run iterator to exhaustion. */ + for (;;) { + PyObject *item = iternext(it); + if (item == NULL) { + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + goto error; + } + break; + } + if (Py_SIZE(self) < self->allocated) { + /* steals ref */ + PyList_SET_ITEM(self, Py_SIZE(self), item); + ++Py_SIZE(self); + } + else { + int status = app1(self, item); + Py_DECREF(item); /* append creates a new ref */ + if (status < 0) + goto error; + } + } + + /* Cut back result list if initial guess was too large. */ + if (Py_SIZE(self) < self->allocated) { + if (list_resize(self, Py_SIZE(self)) < 0) + goto error; + } + + Py_DECREF(it); + Py_RETURN_NONE; + + error: + Py_DECREF(it); + return NULL; +} + +PyObject * +_PyList_Extend(PyListObject *self, PyObject *iterable) +{ + return list_extend(self, iterable); +} + +static PyObject * +list_inplace_concat(PyListObject *self, PyObject *other) +{ + PyObject *result; + + result = list_extend(self, other); + if (result == NULL) + return result; + Py_DECREF(result); + Py_INCREF(self); + return (PyObject *)self; +} + +/*[clinic input] +list.pop + + index: Py_ssize_t = -1 + / + +Remove and return item at index (default last). + +Raises IndexError if list is empty or index is out of range. +[clinic start generated code]*/ + +static PyObject * +list_pop_impl(PyListObject *self, Py_ssize_t index) +/*[clinic end generated code: output=6bd69dcb3f17eca8 input=b83675976f329e6f]*/ +{ + PyObject *v; + int status; + + if (Py_SIZE(self) == 0) { + /* Special-case most common failure cause */ + PyErr_SetString(PyExc_IndexError, "pop from empty list"); + return NULL; + } + if (index < 0) + index += Py_SIZE(self); + if (!valid_index(index, Py_SIZE(self))) { + PyErr_SetString(PyExc_IndexError, "pop index out of range"); + return NULL; + } + v = self->ob_item[index]; + if (index == Py_SIZE(self) - 1) { + status = list_resize(self, Py_SIZE(self) - 1); + if (status >= 0) + return v; /* and v now owns the reference the list had */ + else + return NULL; + } + Py_INCREF(v); + status = list_ass_slice(self, index, index+1, (PyObject *)NULL); + if (status < 0) { + Py_DECREF(v); + return NULL; + } + return v; +} + +/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ +static void +reverse_slice(PyObject **lo, PyObject **hi) +{ + assert(lo && hi); + + --hi; + while (lo < hi) { + PyObject *t = *lo; + *lo = *hi; + *hi = t; + ++lo; + --hi; + } +} + +/* Lots of code for an adaptive, stable, natural mergesort. There are many + * pieces to this algorithm; read listsort.txt for overviews and details. + */ + +/* A sortslice contains a pointer to an array of keys and a pointer to + * an array of corresponding values. In other words, keys[i] + * corresponds with values[i]. If values == NULL, then the keys are + * also the values. + * + * Several convenience routines are provided here, so that keys and + * values are always moved in sync. + */ + +typedef struct { + PyObject **keys; + PyObject **values; +} sortslice; + +Py_LOCAL_INLINE(void) +sortslice_copy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j) +{ + s1->keys[i] = s2->keys[j]; + if (s1->values != NULL) + s1->values[i] = s2->values[j]; +} + +Py_LOCAL_INLINE(void) +sortslice_copy_incr(sortslice *dst, sortslice *src) +{ + *dst->keys++ = *src->keys++; + if (dst->values != NULL) + *dst->values++ = *src->values++; +} + +Py_LOCAL_INLINE(void) +sortslice_copy_decr(sortslice *dst, sortslice *src) +{ + *dst->keys-- = *src->keys--; + if (dst->values != NULL) + *dst->values-- = *src->values--; +} + + +Py_LOCAL_INLINE(void) +sortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, + Py_ssize_t n) +{ + memcpy(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); + if (s1->values != NULL) + memcpy(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); +} + +Py_LOCAL_INLINE(void) +sortslice_memmove(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, + Py_ssize_t n) +{ + memmove(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); + if (s1->values != NULL) + memmove(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); +} + +Py_LOCAL_INLINE(void) +sortslice_advance(sortslice *slice, Py_ssize_t n) +{ + slice->keys += n; + if (slice->values != NULL) + slice->values += n; +} + +/* Comparison function: ms->key_compare, which is set at run-time in + * listsort_impl to optimize for various special cases. + * Returns -1 on error, 1 if x < y, 0 if x >= y. + */ + +#define ISLT(X, Y) (*(ms->key_compare))(X, Y, ms) + +/* Compare X to Y via "<". Goto "fail" if the comparison raises an + error. Else "k" is set to true iff X. X and Y are PyObject*s. +*/ +#define IFLT(X, Y) if ((k = ISLT(X, Y)) < 0) goto fail; \ + if (k) + +/* The maximum number of entries in a MergeState's pending-runs stack. + * This is enough to sort arrays of size up to about + * 32 * phi ** MAX_MERGE_PENDING + * where phi ~= 1.618. 85 is ridiculouslylarge enough, good for an array + * with 2**64 elements. + */ +#define MAX_MERGE_PENDING 85 + +/* When we get into galloping mode, we stay there until both runs win less + * often than MIN_GALLOP consecutive times. See listsort.txt for more info. + */ +#define MIN_GALLOP 7 + +/* Avoid malloc for small temp arrays. */ +#define MERGESTATE_TEMP_SIZE 256 + +/* One MergeState exists on the stack per invocation of mergesort. It's just + * a convenient way to pass state around among the helper functions. + */ +struct s_slice { + sortslice base; + Py_ssize_t len; +}; + +typedef struct s_MergeState MergeState; +struct s_MergeState { + /* This controls when we get *into* galloping mode. It's initialized + * to MIN_GALLOP. merge_lo and merge_hi tend to nudge it higher for + * random data, and lower for highly structured data. + */ + Py_ssize_t min_gallop; + + /* 'a' is temp storage to help with merges. It contains room for + * alloced entries. + */ + sortslice a; /* may point to temparray below */ + Py_ssize_t alloced; + + /* A stack of n pending runs yet to be merged. Run #i starts at + * address base[i] and extends for len[i] elements. It's always + * true (so long as the indices are in bounds) that + * + * pending[i].base + pending[i].len == pending[i+1].base + * + * so we could cut the storage for this, but it's a minor amount, + * and keeping all the info explicit simplifies the code. + */ + int n; + struct s_slice pending[MAX_MERGE_PENDING]; + + /* 'a' points to this when possible, rather than muck with malloc. */ + PyObject *temparray[MERGESTATE_TEMP_SIZE]; + + /* This is the function we will use to compare two keys, + * even when none of our special cases apply and we have to use + * safe_object_compare. */ + int (*key_compare)(PyObject *, PyObject *, MergeState *); + + /* This function is used by unsafe_object_compare to optimize comparisons + * when we know our list is type-homogeneous but we can't assume anything else. + * In the pre-sort check it is set equal to key->ob_type->tp_richcompare */ + PyObject *(*key_richcompare)(PyObject *, PyObject *, int); + + /* This function is used by unsafe_tuple_compare to compare the first elements + * of tuples. It may be set to safe_object_compare, but the idea is that hopefully + * we can assume more, and use one of the special-case compares. */ + int (*tuple_elem_compare)(PyObject *, PyObject *, MergeState *); +}; + +/* binarysort is the best method for sorting small arrays: it does + few compares, but can do data movement quadratic in the number of + elements. + [lo, hi) is a contiguous slice of a list, and is sorted via + binary insertion. This sort is stable. + On entry, must have lo <= start <= hi, and that [lo, start) is already + sorted (pass start == lo if you don't know!). + If islt() complains return -1, else 0. + Even in case of error, the output slice will be some permutation of + the input (nothing is lost or duplicated). +*/ +static int +binarysort(MergeState *ms, sortslice lo, PyObject **hi, PyObject **start) +{ + Py_ssize_t k; + PyObject **l, **p, **r; + PyObject *pivot; + + assert(lo.keys <= start && start <= hi); + /* assert [lo, start) is sorted */ + if (lo.keys == start) + ++start; + for (; start < hi; ++start) { + /* set l to where *start belongs */ + l = lo.keys; + r = start; + pivot = *r; + /* Invariants: + * pivot >= all in [lo, l). + * pivot < all in [r, start). + * The second is vacuously true at the start. + */ + assert(l < r); + do { + p = l + ((r - l) >> 1); + IFLT(pivot, *p) + r = p; + else + l = p+1; + } while (l < r); + assert(l == r); + /* The invariants still hold, so pivot >= all in [lo, l) and + pivot < all in [l, start), so pivot belongs at l. Note + that if there are elements equal to pivot, l points to the + first slot after them -- that's why this sort is stable. + Slide over to make room. + Caution: using memmove is much slower under MSVC 5; + we're not usually moving many slots. */ + for (p = start; p > l; --p) + *p = *(p-1); + *l = pivot; + if (lo.values != NULL) { + Py_ssize_t offset = lo.values - lo.keys; + p = start + offset; + pivot = *p; + l += offset; + for (p = start + offset; p > l; --p) + *p = *(p-1); + *l = pivot; + } + } + return 0; + + fail: + return -1; +} + +/* +Return the length of the run beginning at lo, in the slice [lo, hi). lo < hi +is required on entry. "A run" is the longest ascending sequence, with + + lo[0] <= lo[1] <= lo[2] <= ... + +or the longest descending sequence, with + + lo[0] > lo[1] > lo[2] > ... + +Boolean *descending is set to 0 in the former case, or to 1 in the latter. +For its intended use in a stable mergesort, the strictness of the defn of +"descending" is needed so that the caller can safely reverse a descending +sequence without violating stability (strict > ensures there are no equal +elements to get out of order). + +Returns -1 in case of error. +*/ +static Py_ssize_t +count_run(MergeState *ms, PyObject **lo, PyObject **hi, int *descending) +{ + Py_ssize_t k; + Py_ssize_t n; + + assert(lo < hi); + *descending = 0; + ++lo; + if (lo == hi) + return 1; + + n = 2; + IFLT(*lo, *(lo-1)) { + *descending = 1; + for (lo = lo+1; lo < hi; ++lo, ++n) { + IFLT(*lo, *(lo-1)) + ; + else + break; + } + } + else { + for (lo = lo+1; lo < hi; ++lo, ++n) { + IFLT(*lo, *(lo-1)) + break; + } + } + + return n; +fail: + return -1; +} + +/* +Locate the proper position of key in a sorted vector; if the vector contains +an element equal to key, return the position immediately to the left of +the leftmost equal element. [gallop_right() does the same except returns +the position to the right of the rightmost equal element (if any).] + +"a" is a sorted vector with n elements, starting at a[0]. n must be > 0. + +"hint" is an index at which to begin the search, 0 <= hint < n. The closer +hint is to the final result, the faster this runs. + +The return value is the int k in 0..n such that + + a[k-1] < key <= a[k] + +pretending that *(a-1) is minus infinity and a[n] is plus infinity. IOW, +key belongs at index k; or, IOW, the first k elements of a should precede +key, and the last n-k should follow key. + +Returns -1 on error. See listsort.txt for info on the method. +*/ +static Py_ssize_t +gallop_left(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint) +{ + Py_ssize_t ofs; + Py_ssize_t lastofs; + Py_ssize_t k; + + assert(key && a && n > 0 && hint >= 0 && hint < n); + + a += hint; + lastofs = 0; + ofs = 1; + IFLT(*a, key) { + /* a[hint] < key -- gallop right, until + * a[hint + lastofs] < key <= a[hint + ofs] + */ + const Py_ssize_t maxofs = n - hint; /* &a[n-1] is highest */ + while (ofs < maxofs) { + IFLT(a[ofs], key) { + lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); + ofs = (ofs << 1) + 1; + } + else /* key <= a[hint + ofs] */ + break; + } + if (ofs > maxofs) + ofs = maxofs; + /* Translate back to offsets relative to &a[0]. */ + lastofs += hint; + ofs += hint; + } + else { + /* key <= a[hint] -- gallop left, until + * a[hint - ofs] < key <= a[hint - lastofs] + */ + const Py_ssize_t maxofs = hint + 1; /* &a[0] is lowest */ + while (ofs < maxofs) { + IFLT(*(a-ofs), key) + break; + /* key <= a[hint - ofs] */ + lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); + ofs = (ofs << 1) + 1; + } + if (ofs > maxofs) + ofs = maxofs; + /* Translate back to positive offsets relative to &a[0]. */ + k = lastofs; + lastofs = hint - ofs; + ofs = hint - k; + } + a -= hint; + + assert(-1 <= lastofs && lastofs < ofs && ofs <= n); + /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the + * right of lastofs but no farther right than ofs. Do a binary + * search, with invariant a[lastofs-1] < key <= a[ofs]. + */ + ++lastofs; + while (lastofs < ofs) { + Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1); + + IFLT(a[m], key) + lastofs = m+1; /* a[m] < key */ + else + ofs = m; /* key <= a[m] */ + } + assert(lastofs == ofs); /* so a[ofs-1] < key <= a[ofs] */ + return ofs; + +fail: + return -1; +} + +/* +Exactly like gallop_left(), except that if key already exists in a[0:n], +finds the position immediately to the right of the rightmost equal value. + +The return value is the int k in 0..n such that + + a[k-1] <= key < a[k] + +or -1 if error. + +The code duplication is massive, but this is enough different given that +we're sticking to "<" comparisons that it's much harder to follow if +written as one routine with yet another "left or right?" flag. +*/ +static Py_ssize_t +gallop_right(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint) +{ + Py_ssize_t ofs; + Py_ssize_t lastofs; + Py_ssize_t k; + + assert(key && a && n > 0 && hint >= 0 && hint < n); + + a += hint; + lastofs = 0; + ofs = 1; + IFLT(key, *a) { + /* key < a[hint] -- gallop left, until + * a[hint - ofs] <= key < a[hint - lastofs] + */ + const Py_ssize_t maxofs = hint + 1; /* &a[0] is lowest */ + while (ofs < maxofs) { + IFLT(key, *(a-ofs)) { + lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); + ofs = (ofs << 1) + 1; + } + else /* a[hint - ofs] <= key */ + break; + } + if (ofs > maxofs) + ofs = maxofs; + /* Translate back to positive offsets relative to &a[0]. */ + k = lastofs; + lastofs = hint - ofs; + ofs = hint - k; + } + else { + /* a[hint] <= key -- gallop right, until + * a[hint + lastofs] <= key < a[hint + ofs] + */ + const Py_ssize_t maxofs = n - hint; /* &a[n-1] is highest */ + while (ofs < maxofs) { + IFLT(key, a[ofs]) + break; + /* a[hint + ofs] <= key */ + lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); + ofs = (ofs << 1) + 1; + } + if (ofs > maxofs) + ofs = maxofs; + /* Translate back to offsets relative to &a[0]. */ + lastofs += hint; + ofs += hint; + } + a -= hint; + + assert(-1 <= lastofs && lastofs < ofs && ofs <= n); + /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the + * right of lastofs but no farther right than ofs. Do a binary + * search, with invariant a[lastofs-1] <= key < a[ofs]. + */ + ++lastofs; + while (lastofs < ofs) { + Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1); + + IFLT(key, a[m]) + ofs = m; /* key < a[m] */ + else + lastofs = m+1; /* a[m] <= key */ + } + assert(lastofs == ofs); /* so a[ofs-1] <= key < a[ofs] */ + return ofs; + +fail: + return -1; +} + +/* Conceptually a MergeState's constructor. */ +static void +merge_init(MergeState *ms, Py_ssize_t list_size, int has_keyfunc) +{ + assert(ms != NULL); + if (has_keyfunc) { + /* The temporary space for merging will need at most half the list + * size rounded up. Use the minimum possible space so we can use the + * rest of temparray for other things. In particular, if there is + * enough extra space, listsort() will use it to store the keys. + */ + ms->alloced = (list_size + 1) / 2; + + /* ms->alloced describes how many keys will be stored at + ms->temparray, but we also need to store the values. Hence, + ms->alloced is capped at half of MERGESTATE_TEMP_SIZE. */ + if (MERGESTATE_TEMP_SIZE / 2 < ms->alloced) + ms->alloced = MERGESTATE_TEMP_SIZE / 2; + ms->a.values = &ms->temparray[ms->alloced]; + } + else { + ms->alloced = MERGESTATE_TEMP_SIZE; + ms->a.values = NULL; + } + ms->a.keys = ms->temparray; + ms->n = 0; + ms->min_gallop = MIN_GALLOP; +} + +/* Free all the temp memory owned by the MergeState. This must be called + * when you're done with a MergeState, and may be called before then if + * you want to free the temp memory early. + */ +static void +merge_freemem(MergeState *ms) +{ + assert(ms != NULL); + if (ms->a.keys != ms->temparray) + PyMem_Free(ms->a.keys); +} + +/* Ensure enough temp memory for 'need' array slots is available. + * Returns 0 on success and -1 if the memory can't be gotten. + */ +static int +merge_getmem(MergeState *ms, Py_ssize_t need) +{ + int multiplier; + + assert(ms != NULL); + if (need <= ms->alloced) + return 0; + + multiplier = ms->a.values != NULL ? 2 : 1; + + /* Don't realloc! That can cost cycles to copy the old data, but + * we don't care what's in the block. + */ + merge_freemem(ms); + if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject *) / multiplier) { + PyErr_NoMemory(); + return -1; + } + ms->a.keys = (PyObject **)PyMem_Malloc(multiplier * need + * sizeof(PyObject *)); + if (ms->a.keys != NULL) { + ms->alloced = need; + if (ms->a.values != NULL) + ms->a.values = &ms->a.keys[need]; + return 0; + } + PyErr_NoMemory(); + return -1; +} +#define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 : \ + merge_getmem(MS, NEED)) + +/* Merge the na elements starting at ssa with the nb elements starting at + * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0. + * Must also have that ssa.keys[na-1] belongs at the end of the merge, and + * should have na <= nb. See listsort.txt for more info. Return 0 if + * successful, -1 if error. + */ +static Py_ssize_t +merge_lo(MergeState *ms, sortslice ssa, Py_ssize_t na, + sortslice ssb, Py_ssize_t nb) +{ + Py_ssize_t k; + sortslice dest; + int result = -1; /* guilty until proved innocent */ + Py_ssize_t min_gallop; + + assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0); + assert(ssa.keys + na == ssb.keys); + if (MERGE_GETMEM(ms, na) < 0) + return -1; + sortslice_memcpy(&ms->a, 0, &ssa, 0, na); + dest = ssa; + ssa = ms->a; + + sortslice_copy_incr(&dest, &ssb); + --nb; + if (nb == 0) + goto Succeed; + if (na == 1) + goto CopyB; + + min_gallop = ms->min_gallop; + for (;;) { + Py_ssize_t acount = 0; /* # of times A won in a row */ + Py_ssize_t bcount = 0; /* # of times B won in a row */ + + /* Do the straightforward thing until (if ever) one run + * appears to win consistently. + */ + for (;;) { + assert(na > 1 && nb > 0); + k = ISLT(ssb.keys[0], ssa.keys[0]); + if (k) { + if (k < 0) + goto Fail; + sortslice_copy_incr(&dest, &ssb); + ++bcount; + acount = 0; + --nb; + if (nb == 0) + goto Succeed; + if (bcount >= min_gallop) + break; + } + else { + sortslice_copy_incr(&dest, &ssa); + ++acount; + bcount = 0; + --na; + if (na == 1) + goto CopyB; + if (acount >= min_gallop) + break; + } + } + + /* One run is winning so consistently that galloping may + * be a huge win. So try that, and continue galloping until + * (if ever) neither run appears to be winning consistently + * anymore. + */ + ++min_gallop; + do { + assert(na > 1 && nb > 0); + min_gallop -= min_gallop > 1; + ms->min_gallop = min_gallop; + k = gallop_right(ms, ssb.keys[0], ssa.keys, na, 0); + acount = k; + if (k) { + if (k < 0) + goto Fail; + sortslice_memcpy(&dest, 0, &ssa, 0, k); + sortslice_advance(&dest, k); + sortslice_advance(&ssa, k); + na -= k; + if (na == 1) + goto CopyB; + /* na==0 is impossible now if the comparison + * function is consistent, but we can't assume + * that it is. + */ + if (na == 0) + goto Succeed; + } + sortslice_copy_incr(&dest, &ssb); + --nb; + if (nb == 0) + goto Succeed; + + k = gallop_left(ms, ssa.keys[0], ssb.keys, nb, 0); + bcount = k; + if (k) { + if (k < 0) + goto Fail; + sortslice_memmove(&dest, 0, &ssb, 0, k); + sortslice_advance(&dest, k); + sortslice_advance(&ssb, k); + nb -= k; + if (nb == 0) + goto Succeed; + } + sortslice_copy_incr(&dest, &ssa); + --na; + if (na == 1) + goto CopyB; + } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP); + ++min_gallop; /* penalize it for leaving galloping mode */ + ms->min_gallop = min_gallop; + } +Succeed: + result = 0; +Fail: + if (na) + sortslice_memcpy(&dest, 0, &ssa, 0, na); + return result; +CopyB: + assert(na == 1 && nb > 0); + /* The last element of ssa belongs at the end of the merge. */ + sortslice_memmove(&dest, 0, &ssb, 0, nb); + sortslice_copy(&dest, nb, &ssa, 0); + return 0; +} + +/* Merge the na elements starting at pa with the nb elements starting at + * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0. + * Must also have that ssa.keys[na-1] belongs at the end of the merge, and + * should have na >= nb. See listsort.txt for more info. Return 0 if + * successful, -1 if error. + */ +static Py_ssize_t +merge_hi(MergeState *ms, sortslice ssa, Py_ssize_t na, + sortslice ssb, Py_ssize_t nb) +{ + Py_ssize_t k; + sortslice dest, basea, baseb; + int result = -1; /* guilty until proved innocent */ + Py_ssize_t min_gallop; + + assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0); + assert(ssa.keys + na == ssb.keys); + if (MERGE_GETMEM(ms, nb) < 0) + return -1; + dest = ssb; + sortslice_advance(&dest, nb-1); + sortslice_memcpy(&ms->a, 0, &ssb, 0, nb); + basea = ssa; + baseb = ms->a; + ssb.keys = ms->a.keys + nb - 1; + if (ssb.values != NULL) + ssb.values = ms->a.values + nb - 1; + sortslice_advance(&ssa, na - 1); + + sortslice_copy_decr(&dest, &ssa); + --na; + if (na == 0) + goto Succeed; + if (nb == 1) + goto CopyA; + + min_gallop = ms->min_gallop; + for (;;) { + Py_ssize_t acount = 0; /* # of times A won in a row */ + Py_ssize_t bcount = 0; /* # of times B won in a row */ + + /* Do the straightforward thing until (if ever) one run + * appears to win consistently. + */ + for (;;) { + assert(na > 0 && nb > 1); + k = ISLT(ssb.keys[0], ssa.keys[0]); + if (k) { + if (k < 0) + goto Fail; + sortslice_copy_decr(&dest, &ssa); + ++acount; + bcount = 0; + --na; + if (na == 0) + goto Succeed; + if (acount >= min_gallop) + break; + } + else { + sortslice_copy_decr(&dest, &ssb); + ++bcount; + acount = 0; + --nb; + if (nb == 1) + goto CopyA; + if (bcount >= min_gallop) + break; + } + } + + /* One run is winning so consistently that galloping may + * be a huge win. So try that, and continue galloping until + * (if ever) neither run appears to be winning consistently + * anymore. + */ + ++min_gallop; + do { + assert(na > 0 && nb > 1); + min_gallop -= min_gallop > 1; + ms->min_gallop = min_gallop; + k = gallop_right(ms, ssb.keys[0], basea.keys, na, na-1); + if (k < 0) + goto Fail; + k = na - k; + acount = k; + if (k) { + sortslice_advance(&dest, -k); + sortslice_advance(&ssa, -k); + sortslice_memmove(&dest, 1, &ssa, 1, k); + na -= k; + if (na == 0) + goto Succeed; + } + sortslice_copy_decr(&dest, &ssb); + --nb; + if (nb == 1) + goto CopyA; + + k = gallop_left(ms, ssa.keys[0], baseb.keys, nb, nb-1); + if (k < 0) + goto Fail; + k = nb - k; + bcount = k; + if (k) { + sortslice_advance(&dest, -k); + sortslice_advance(&ssb, -k); + sortslice_memcpy(&dest, 1, &ssb, 1, k); + nb -= k; + if (nb == 1) + goto CopyA; + /* nb==0 is impossible now if the comparison + * function is consistent, but we can't assume + * that it is. + */ + if (nb == 0) + goto Succeed; + } + sortslice_copy_decr(&dest, &ssa); + --na; + if (na == 0) + goto Succeed; + } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP); + ++min_gallop; /* penalize it for leaving galloping mode */ + ms->min_gallop = min_gallop; + } +Succeed: + result = 0; +Fail: + if (nb) + sortslice_memcpy(&dest, -(nb-1), &baseb, 0, nb); + return result; +CopyA: + assert(nb == 1 && na > 0); + /* The first element of ssb belongs at the front of the merge. */ + sortslice_memmove(&dest, 1-na, &ssa, 1-na, na); + sortslice_advance(&dest, -na); + sortslice_advance(&ssa, -na); + sortslice_copy(&dest, 0, &ssb, 0); + return 0; +} + +/* Merge the two runs at stack indices i and i+1. + * Returns 0 on success, -1 on error. + */ +static Py_ssize_t +merge_at(MergeState *ms, Py_ssize_t i) +{ + sortslice ssa, ssb; + Py_ssize_t na, nb; + Py_ssize_t k; + + assert(ms != NULL); + assert(ms->n >= 2); + assert(i >= 0); + assert(i == ms->n - 2 || i == ms->n - 3); + + ssa = ms->pending[i].base; + na = ms->pending[i].len; + ssb = ms->pending[i+1].base; + nb = ms->pending[i+1].len; + assert(na > 0 && nb > 0); + assert(ssa.keys + na == ssb.keys); + + /* Record the length of the combined runs; if i is the 3rd-last + * run now, also slide over the last run (which isn't involved + * in this merge). The current run i+1 goes away in any case. + */ + ms->pending[i].len = na + nb; + if (i == ms->n - 3) + ms->pending[i+1] = ms->pending[i+2]; + --ms->n; + + /* Where does b start in a? Elements in a before that can be + * ignored (already in place). + */ + k = gallop_right(ms, *ssb.keys, ssa.keys, na, 0); + if (k < 0) + return -1; + sortslice_advance(&ssa, k); + na -= k; + if (na == 0) + return 0; + + /* Where does a end in b? Elements in b after that can be + * ignored (already in place). + */ + nb = gallop_left(ms, ssa.keys[na-1], ssb.keys, nb, nb-1); + if (nb <= 0) + return nb; + + /* Merge what remains of the runs, using a temp array with + * min(na, nb) elements. + */ + if (na <= nb) + return merge_lo(ms, ssa, na, ssb, nb); + else + return merge_hi(ms, ssa, na, ssb, nb); +} + +/* Examine the stack of runs waiting to be merged, merging adjacent runs + * until the stack invariants are re-established: + * + * 1. len[-3] > len[-2] + len[-1] + * 2. len[-2] > len[-1] + * + * See listsort.txt for more info. + * + * Returns 0 on success, -1 on error. + */ +static int +merge_collapse(MergeState *ms) +{ + struct s_slice *p = ms->pending; + + assert(ms); + while (ms->n > 1) { + Py_ssize_t n = ms->n - 2; + if ((n > 0 && p[n-1].len <= p[n].len + p[n+1].len) || + (n > 1 && p[n-2].len <= p[n-1].len + p[n].len)) { + if (p[n-1].len < p[n+1].len) + --n; + if (merge_at(ms, n) < 0) + return -1; + } + else if (p[n].len <= p[n+1].len) { + if (merge_at(ms, n) < 0) + return -1; + } + else + break; + } + return 0; +} + +/* Regardless of invariants, merge all runs on the stack until only one + * remains. This is used at the end of the mergesort. + * + * Returns 0 on success, -1 on error. + */ +static int +merge_force_collapse(MergeState *ms) +{ + struct s_slice *p = ms->pending; + + assert(ms); + while (ms->n > 1) { + Py_ssize_t n = ms->n - 2; + if (n > 0 && p[n-1].len < p[n+1].len) + --n; + if (merge_at(ms, n) < 0) + return -1; + } + return 0; +} + +/* Compute a good value for the minimum run length; natural runs shorter + * than this are boosted artificially via binary insertion. + * + * If n < 64, return n (it's too small to bother with fancy stuff). + * Else if n is an exact power of 2, return 32. + * Else return an int k, 32 <= k <= 64, such that n/k is close to, but + * strictly less than, an exact power of 2. + * + * See listsort.txt for more info. + */ +static Py_ssize_t +merge_compute_minrun(Py_ssize_t n) +{ + Py_ssize_t r = 0; /* becomes 1 if any 1 bits are shifted off */ + + assert(n >= 0); + while (n >= 64) { + r |= n & 1; + n >>= 1; + } + return n + r; +} + +static void +reverse_sortslice(sortslice *s, Py_ssize_t n) +{ + reverse_slice(s->keys, &s->keys[n]); + if (s->values != NULL) + reverse_slice(s->values, &s->values[n]); +} + +/* Here we define custom comparison functions to optimize for the cases one commonly + * encounters in practice: homogeneous lists, often of one of the basic types. */ + +/* This struct holds the comparison function and helper functions + * selected in the pre-sort check. */ + +/* These are the special case compare functions. + * ms->key_compare will always point to one of these: */ + +/* Heterogeneous compare: default, always safe to fall back on. */ +static int +safe_object_compare(PyObject *v, PyObject *w, MergeState *ms) +{ + /* No assumptions necessary! */ + return PyObject_RichCompareBool(v, w, Py_LT); +} + +/* Homogeneous compare: safe for any two compareable objects of the same type. + * (ms->key_richcompare is set to ob_type->tp_richcompare in the + * pre-sort check.) + */ +static int +unsafe_object_compare(PyObject *v, PyObject *w, MergeState *ms) +{ + PyObject *res_obj; int res; + + /* No assumptions, because we check first: */ + if (v->ob_type->tp_richcompare != ms->key_richcompare) + return PyObject_RichCompareBool(v, w, Py_LT); + + assert(ms->key_richcompare != NULL); + res_obj = (*(ms->key_richcompare))(v, w, Py_LT); + + if (res_obj == Py_NotImplemented) { + Py_DECREF(res_obj); + return PyObject_RichCompareBool(v, w, Py_LT); + } + if (res_obj == NULL) + return -1; + + if (PyBool_Check(res_obj)) { + res = (res_obj == Py_True); + } + else { + res = PyObject_IsTrue(res_obj); + } + Py_DECREF(res_obj); + + /* Note that we can't assert + * res == PyObject_RichCompareBool(v, w, Py_LT); + * because of evil compare functions like this: + * lambda a, b: int(random.random() * 3) - 1) + * (which is actually in test_sort.py) */ + return res; +} + +/* Latin string compare: safe for any two latin (one byte per char) strings. */ +static int +unsafe_latin_compare(PyObject *v, PyObject *w, MergeState *ms) +{ + Py_ssize_t len; + int res; + + /* Modified from Objects/unicodeobject.c:unicode_compare, assuming: */ + assert(v->ob_type == w->ob_type); + assert(v->ob_type == &PyUnicode_Type); + assert(PyUnicode_KIND(v) == PyUnicode_KIND(w)); + assert(PyUnicode_KIND(v) == PyUnicode_1BYTE_KIND); + + len = Py_MIN(PyUnicode_GET_LENGTH(v), PyUnicode_GET_LENGTH(w)); + res = memcmp(PyUnicode_DATA(v), PyUnicode_DATA(w), len); + + res = (res != 0 ? + res < 0 : + PyUnicode_GET_LENGTH(v) < PyUnicode_GET_LENGTH(w)); + + assert(res == PyObject_RichCompareBool(v, w, Py_LT));; + return res; +} + +/* Bounded int compare: compare any two longs that fit in a single machine word. */ +static int +unsafe_long_compare(PyObject *v, PyObject *w, MergeState *ms) +{ + PyLongObject *vl, *wl; sdigit v0, w0; int res; + + /* Modified from Objects/longobject.c:long_compare, assuming: */ + assert(v->ob_type == w->ob_type); + assert(v->ob_type == &PyLong_Type); + assert(Py_ABS(Py_SIZE(v)) <= 1); + assert(Py_ABS(Py_SIZE(w)) <= 1); + + vl = (PyLongObject*)v; + wl = (PyLongObject*)w; + + v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0]; + w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0]; + + if (Py_SIZE(vl) < 0) + v0 = -v0; + if (Py_SIZE(wl) < 0) + w0 = -w0; + + res = v0 < w0; + assert(res == PyObject_RichCompareBool(v, w, Py_LT)); + return res; +} + +/* Float compare: compare any two floats. */ +static int +unsafe_float_compare(PyObject *v, PyObject *w, MergeState *ms) +{ + int res; + + /* Modified from Objects/floatobject.c:float_richcompare, assuming: */ + assert(v->ob_type == w->ob_type); + assert(v->ob_type == &PyFloat_Type); + + res = PyFloat_AS_DOUBLE(v) < PyFloat_AS_DOUBLE(w); + assert(res == PyObject_RichCompareBool(v, w, Py_LT)); + return res; +} + +/* Tuple compare: compare *any* two tuples, using + * ms->tuple_elem_compare to compare the first elements, which is set + * using the same pre-sort check as we use for ms->key_compare, + * but run on the list [x[0] for x in L]. This allows us to optimize compares + * on two levels (as long as [x[0] for x in L] is type-homogeneous.) The idea is + * that most tuple compares don't involve x[1:]. */ +static int +unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms) +{ + PyTupleObject *vt, *wt; + Py_ssize_t i, vlen, wlen; + int k; + + /* Modified from Objects/tupleobject.c:tuplerichcompare, assuming: */ + assert(v->ob_type == w->ob_type); + assert(v->ob_type == &PyTuple_Type); + assert(Py_SIZE(v) > 0); + assert(Py_SIZE(w) > 0); + + vt = (PyTupleObject *)v; + wt = (PyTupleObject *)w; + + vlen = Py_SIZE(vt); + wlen = Py_SIZE(wt); + + for (i = 0; i < vlen && i < wlen; i++) { + k = PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_EQ); + if (k < 0) + return -1; + if (!k) + break; + } + + if (i >= vlen || i >= wlen) + return vlen < wlen; + + if (i == 0) + return ms->tuple_elem_compare(vt->ob_item[i], wt->ob_item[i], ms); + else + return PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_LT); +} + +/* An adaptive, stable, natural mergesort. See listsort.txt. + * Returns Py_None on success, NULL on error. Even in case of error, the + * list will be some permutation of its input state (nothing is lost or + * duplicated). + */ +/*[clinic input] +list.sort + + * + key as keyfunc: object = None + reverse: bool(accept={int}) = False + +Sort the list in ascending order and return None. + +The sort is in-place (i.e. the list itself is modified) and stable (i.e. the +order of two equal elements is maintained). + +If a key function is given, apply it once to each list item and sort them, +ascending or descending, according to their function values. + +The reverse flag can be set to sort in descending order. +[clinic start generated code]*/ + +static PyObject * +list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) +/*[clinic end generated code: output=57b9f9c5e23fbe42 input=cb56cd179a713060]*/ +{ + MergeState ms; + Py_ssize_t nremaining; + Py_ssize_t minrun; + sortslice lo; + Py_ssize_t saved_ob_size, saved_allocated; + PyObject **saved_ob_item; + PyObject **final_ob_item; + PyObject *result = NULL; /* guilty until proved innocent */ + Py_ssize_t i; + PyObject **keys; + + assert(self != NULL); + assert(PyList_Check(self)); + if (keyfunc == Py_None) + keyfunc = NULL; + + /* The list is temporarily made empty, so that mutations performed + * by comparison functions can't affect the slice of memory we're + * sorting (allowing mutations during sorting is a core-dump + * factory, since ob_item may change). + */ + saved_ob_size = Py_SIZE(self); + saved_ob_item = self->ob_item; + saved_allocated = self->allocated; + Py_SIZE(self) = 0; + self->ob_item = NULL; + self->allocated = -1; /* any operation will reset it to >= 0 */ + + if (keyfunc == NULL) { + keys = NULL; + lo.keys = saved_ob_item; + lo.values = NULL; + } + else { + if (saved_ob_size < MERGESTATE_TEMP_SIZE/2) + /* Leverage stack space we allocated but won't otherwise use */ + keys = &ms.temparray[saved_ob_size+1]; + else { + keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size); + if (keys == NULL) { + PyErr_NoMemory(); + goto keyfunc_fail; + } + } + + for (i = 0; i < saved_ob_size ; i++) { + keys[i] = PyObject_CallFunctionObjArgs(keyfunc, saved_ob_item[i], + NULL); + if (keys[i] == NULL) { + for (i=i-1 ; i>=0 ; i--) + Py_DECREF(keys[i]); + if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) + PyMem_FREE(keys); + goto keyfunc_fail; + } + } + + lo.keys = keys; + lo.values = saved_ob_item; + } + + + /* The pre-sort check: here's where we decide which compare function to use. + * How much optimization is safe? We test for homogeneity with respect to + * several properties that are expensive to check at compare-time, and + * set ms appropriately. */ + if (saved_ob_size > 1) { + /* Assume the first element is representative of the whole list. */ + int keys_are_in_tuples = (lo.keys[0]->ob_type == &PyTuple_Type && + Py_SIZE(lo.keys[0]) > 0); + + PyTypeObject* key_type = (keys_are_in_tuples ? + PyTuple_GET_ITEM(lo.keys[0], 0)->ob_type : + lo.keys[0]->ob_type); + + int keys_are_all_same_type = 1; + int strings_are_latin = 1; + int ints_are_bounded = 1; + + /* Prove that assumption by checking every key. */ + for (i=0; i < saved_ob_size; i++) { + + if (keys_are_in_tuples && + !(lo.keys[i]->ob_type == &PyTuple_Type && Py_SIZE(lo.keys[i]) != 0)) { + keys_are_in_tuples = 0; + keys_are_all_same_type = 0; + break; + } + + /* Note: for lists of tuples, key is the first element of the tuple + * lo.keys[i], not lo.keys[i] itself! We verify type-homogeneity + * for lists of tuples in the if-statement directly above. */ + PyObject *key = (keys_are_in_tuples ? + PyTuple_GET_ITEM(lo.keys[i], 0) : + lo.keys[i]); + + if (key->ob_type != key_type) { + keys_are_all_same_type = 0; + /* If keys are in tuple we must loop over the whole list to make + sure all items are tuples */ + if (!keys_are_in_tuples) { + break; + } + } + + if (keys_are_all_same_type) { + if (key_type == &PyLong_Type && + ints_are_bounded && + Py_ABS(Py_SIZE(key)) > 1) { + + ints_are_bounded = 0; + } + else if (key_type == &PyUnicode_Type && + strings_are_latin && + PyUnicode_KIND(key) != PyUnicode_1BYTE_KIND) { + + strings_are_latin = 0; + } + } + } + + /* Choose the best compare, given what we now know about the keys. */ + if (keys_are_all_same_type) { + + if (key_type == &PyUnicode_Type && strings_are_latin) { + ms.key_compare = unsafe_latin_compare; + } + else if (key_type == &PyLong_Type && ints_are_bounded) { + ms.key_compare = unsafe_long_compare; + } + else if (key_type == &PyFloat_Type) { + ms.key_compare = unsafe_float_compare; + } + else if ((ms.key_richcompare = key_type->tp_richcompare) != NULL) { + ms.key_compare = unsafe_object_compare; + } + else { + ms.key_compare = safe_object_compare; + } + } + else { + ms.key_compare = safe_object_compare; + } + + if (keys_are_in_tuples) { + /* Make sure we're not dealing with tuples of tuples + * (remember: here, key_type refers list [key[0] for key in keys]) */ + if (key_type == &PyTuple_Type) { + ms.tuple_elem_compare = safe_object_compare; + } + else { + ms.tuple_elem_compare = ms.key_compare; + } + + ms.key_compare = unsafe_tuple_compare; + } + } + /* End of pre-sort check: ms is now set properly! */ + + merge_init(&ms, saved_ob_size, keys != NULL); + + nremaining = saved_ob_size; + if (nremaining < 2) + goto succeed; + + /* Reverse sort stability achieved by initially reversing the list, + applying a stable forward sort, then reversing the final result. */ + if (reverse) { + if (keys != NULL) + reverse_slice(&keys[0], &keys[saved_ob_size]); + reverse_slice(&saved_ob_item[0], &saved_ob_item[saved_ob_size]); + } + + /* March over the array once, left to right, finding natural runs, + * and extending short natural runs to minrun elements. + */ + minrun = merge_compute_minrun(nremaining); + do { + int descending; + Py_ssize_t n; + + /* Identify next run. */ + n = count_run(&ms, lo.keys, lo.keys + nremaining, &descending); + if (n < 0) + goto fail; + if (descending) + reverse_sortslice(&lo, n); + /* If short, extend to min(minrun, nremaining). */ + if (n < minrun) { + const Py_ssize_t force = nremaining <= minrun ? + nremaining : minrun; + if (binarysort(&ms, lo, lo.keys + force, lo.keys + n) < 0) + goto fail; + n = force; + } + /* Push run onto pending-runs stack, and maybe merge. */ + assert(ms.n < MAX_MERGE_PENDING); + ms.pending[ms.n].base = lo; + ms.pending[ms.n].len = n; + ++ms.n; + if (merge_collapse(&ms) < 0) + goto fail; + /* Advance to find next run. */ + sortslice_advance(&lo, n); + nremaining -= n; + } while (nremaining); + + if (merge_force_collapse(&ms) < 0) + goto fail; + assert(ms.n == 1); + assert(keys == NULL + ? ms.pending[0].base.keys == saved_ob_item + : ms.pending[0].base.keys == &keys[0]); + assert(ms.pending[0].len == saved_ob_size); + lo = ms.pending[0].base; + +succeed: + result = Py_None; +fail: + if (keys != NULL) { + for (i = 0; i < saved_ob_size; i++) + Py_DECREF(keys[i]); + if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) + PyMem_FREE(keys); + } + + if (self->allocated != -1 && result != NULL) { + /* The user mucked with the list during the sort, + * and we don't already have another error to report. + */ + PyErr_SetString(PyExc_ValueError, "list modified during sort"); + result = NULL; + } + + if (reverse && saved_ob_size > 1) + reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size); + + merge_freemem(&ms); + +keyfunc_fail: + final_ob_item = self->ob_item; + i = Py_SIZE(self); + Py_SIZE(self) = saved_ob_size; + self->ob_item = saved_ob_item; + self->allocated = saved_allocated; + if (final_ob_item != NULL) { + /* we cannot use _list_clear() for this because it does not + guarantee that the list is really empty when it returns */ + while (--i >= 0) { + Py_XDECREF(final_ob_item[i]); + } + PyMem_FREE(final_ob_item); + } + Py_XINCREF(result); + return result; +} +#undef IFLT +#undef ISLT + +int +PyList_Sort(PyObject *v) +{ + if (v == NULL || !PyList_Check(v)) { + PyErr_BadInternalCall(); + return -1; + } + v = list_sort_impl((PyListObject *)v, NULL, 0); + if (v == NULL) + return -1; + Py_DECREF(v); + return 0; +} + +/*[clinic input] +list.reverse + +Reverse *IN PLACE*. +[clinic start generated code]*/ + +static PyObject * +list_reverse_impl(PyListObject *self) +/*[clinic end generated code: output=482544fc451abea9 input=eefd4c3ae1bc9887]*/ +{ + if (Py_SIZE(self) > 1) + reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self)); + Py_RETURN_NONE; +} + +int +PyList_Reverse(PyObject *v) +{ + PyListObject *self = (PyListObject *)v; + + if (v == NULL || !PyList_Check(v)) { + PyErr_BadInternalCall(); + return -1; + } + if (Py_SIZE(self) > 1) + reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self)); + return 0; +} + +PyObject * +PyList_AsTuple(PyObject *v) +{ + if (v == NULL || !PyList_Check(v)) { + PyErr_BadInternalCall(); + return NULL; + } + return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v)); +} + +/*[clinic input] +list.index + + value: object + start: slice_index(accept={int}) = 0 + stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize + / + +Return first index of value. + +Raises ValueError if the value is not present. +[clinic start generated code]*/ + +static PyObject * +list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start, + Py_ssize_t stop) +/*[clinic end generated code: output=ec51b88787e4e481 input=40ec5826303a0eb1]*/ +{ + Py_ssize_t i; + + if (start < 0) { + start += Py_SIZE(self); + if (start < 0) + start = 0; + } + if (stop < 0) { + stop += Py_SIZE(self); + if (stop < 0) + stop = 0; + } + for (i = start; i < stop && i < Py_SIZE(self); i++) { + PyObject *obj = self->ob_item[i]; + Py_INCREF(obj); + int cmp = PyObject_RichCompareBool(obj, value, Py_EQ); + Py_DECREF(obj); + if (cmp > 0) + return PyLong_FromSsize_t(i); + else if (cmp < 0) + return NULL; + } + PyErr_Format(PyExc_ValueError, "%R is not in list", value); + return NULL; +} + +/*[clinic input] +list.count + + value: object + / + +Return number of occurrences of value. +[clinic start generated code]*/ + +static PyObject * +list_count(PyListObject *self, PyObject *value) +/*[clinic end generated code: output=b1f5d284205ae714 input=3bdc3a5e6f749565]*/ +{ + Py_ssize_t count = 0; + Py_ssize_t i; + + for (i = 0; i < Py_SIZE(self); i++) { + PyObject *obj = self->ob_item[i]; + if (obj == value) { + count++; + continue; + } + Py_INCREF(obj); + int cmp = PyObject_RichCompareBool(obj, value, Py_EQ); + Py_DECREF(obj); + if (cmp > 0) + count++; + else if (cmp < 0) + return NULL; + } + return PyLong_FromSsize_t(count); +} + +/*[clinic input] +list.remove + + value: object + / + +Remove first occurrence of value. + +Raises ValueError if the value is not present. +[clinic start generated code]*/ + +static PyObject * +list_remove(PyListObject *self, PyObject *value) +/*[clinic end generated code: output=f087e1951a5e30d1 input=2dc2ba5bb2fb1f82]*/ +{ + Py_ssize_t i; + + for (i = 0; i < Py_SIZE(self); i++) { + PyObject *obj = self->ob_item[i]; + Py_INCREF(obj); + int cmp = PyObject_RichCompareBool(obj, value, Py_EQ); + Py_DECREF(obj); + if (cmp > 0) { + if (list_ass_slice(self, i, i+1, + (PyObject *)NULL) == 0) + Py_RETURN_NONE; + return NULL; + } + else if (cmp < 0) + return NULL; + } + PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list"); + return NULL; +} + +static int +list_traverse(PyListObject *o, visitproc visit, void *arg) +{ + Py_ssize_t i; + + for (i = Py_SIZE(o); --i >= 0; ) + Py_VISIT(o->ob_item[i]); + return 0; +} + +static PyObject * +list_richcompare(PyObject *v, PyObject *w, int op) +{ + PyListObject *vl, *wl; + Py_ssize_t i; + + if (!PyList_Check(v) || !PyList_Check(w)) + Py_RETURN_NOTIMPLEMENTED; + + vl = (PyListObject *)v; + wl = (PyListObject *)w; + + if (Py_SIZE(vl) != Py_SIZE(wl) && (op == Py_EQ || op == Py_NE)) { + /* Shortcut: if the lengths differ, the lists differ */ + if (op == Py_EQ) + Py_RETURN_FALSE; + else + Py_RETURN_TRUE; + } + + /* Search for the first index where items are different */ + for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) { + PyObject *vitem = vl->ob_item[i]; + PyObject *witem = wl->ob_item[i]; + if (vitem == witem) { + continue; + } + + Py_INCREF(vitem); + Py_INCREF(witem); + int k = PyObject_RichCompareBool(vl->ob_item[i], + wl->ob_item[i], Py_EQ); + Py_DECREF(vitem); + Py_DECREF(witem); + if (k < 0) + return NULL; + if (!k) + break; + } + + if (i >= Py_SIZE(vl) || i >= Py_SIZE(wl)) { + /* No more items to compare -- compare sizes */ + Py_RETURN_RICHCOMPARE(Py_SIZE(vl), Py_SIZE(wl), op); + } + + /* We have an item that differs -- shortcuts for EQ/NE */ + if (op == Py_EQ) { + Py_RETURN_FALSE; + } + if (op == Py_NE) { + Py_RETURN_TRUE; + } + + /* Compare the final item again using the proper operator */ + return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op); +} + +/*[clinic input] +list.__init__ + + iterable: object(c_default="NULL") = () + / + +Built-in mutable sequence. + +If no argument is given, the constructor creates a new empty list. +The argument must be an iterable if specified. +[clinic start generated code]*/ + +static int +list___init___impl(PyListObject *self, PyObject *iterable) +/*[clinic end generated code: output=0f3c21379d01de48 input=b3f3fe7206af8f6b]*/ +{ + /* Verify list invariants established by PyType_GenericAlloc() */ + assert(0 <= Py_SIZE(self)); + assert(Py_SIZE(self) <= self->allocated || self->allocated == -1); + assert(self->ob_item != NULL || + self->allocated == 0 || self->allocated == -1); + + /* Empty previous contents */ + if (self->ob_item != NULL) { + (void)_list_clear(self); + } + if (iterable != NULL) { + if (_PyObject_HasLen(iterable)) { + Py_ssize_t iter_len = PyObject_Size(iterable); + if (iter_len == -1) { + if (!PyErr_ExceptionMatches(PyExc_TypeError)) { + return -1; + } + PyErr_Clear(); + } + if (iter_len > 0 && self->ob_item == NULL + && list_preallocate_exact(self, iter_len)) { + return -1; + } + } + PyObject *rv = list_extend(self, iterable); + if (rv == NULL) + return -1; + Py_DECREF(rv); + } + return 0; +} + +/*[clinic input] +list.__sizeof__ + +Return the size of the list in memory, in bytes. +[clinic start generated code]*/ + +static PyObject * +list___sizeof___impl(PyListObject *self) +/*[clinic end generated code: output=3417541f95f9a53e input=b8030a5d5ce8a187]*/ +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*); + return PyLong_FromSsize_t(res); +} + +static PyObject *list_iter(PyObject *seq); +static PyObject *list_subscript(PyListObject*, PyObject*); + +static PyMethodDef list_methods[] = { + {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, "x.__getitem__(y) <==> x[y]"}, + LIST___REVERSED___METHODDEF + LIST___SIZEOF___METHODDEF + LIST_CLEAR_METHODDEF + LIST_COPY_METHODDEF + LIST_APPEND_METHODDEF + LIST_INSERT_METHODDEF + LIST_EXTEND_METHODDEF + LIST_POP_METHODDEF + LIST_REMOVE_METHODDEF + LIST_INDEX_METHODDEF + LIST_COUNT_METHODDEF + LIST_REVERSE_METHODDEF + LIST_SORT_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PySequenceMethods list_as_sequence = { + (lenfunc)list_length, /* sq_length */ + (binaryfunc)list_concat, /* sq_concat */ + (ssizeargfunc)list_repeat, /* sq_repeat */ + (ssizeargfunc)list_item, /* sq_item */ + 0, /* sq_slice */ + (ssizeobjargproc)list_ass_item, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)list_contains, /* sq_contains */ + (binaryfunc)list_inplace_concat, /* sq_inplace_concat */ + (ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */ +}; + +static PyObject * +list_subscript(PyListObject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += PyList_GET_SIZE(self); + return list_item(self, i); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength, cur, i; + PyObject* result; + PyObject* it; + PyObject **src, **dest; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); + + if (slicelength <= 0) { + return PyList_New(0); + } + else if (step == 1) { + return list_slice(self, start, stop); + } + else { + result = list_new_prealloc(slicelength); + if (!result) return NULL; + + src = self->ob_item; + dest = ((PyListObject *)result)->ob_item; + for (cur = start, i = 0; i < slicelength; + cur += (size_t)step, i++) { + it = src[cur]; + Py_INCREF(it); + dest[i] = it; + } + Py_SIZE(result) = slicelength; + return result; + } + } + else { + PyErr_Format(PyExc_TypeError, + "list indices must be integers or slices, not %.200s", + item->ob_type->tp_name); + return NULL; + } +} + +static int +list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += PyList_GET_SIZE(self); + return list_ass_item(self, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return -1; + } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); + + if (step == 1) + return list_ass_slice(self, start, stop, value); + + /* Make sure s[5:2] = [..] inserts at the right place: + before 5, not before 2. */ + if ((step < 0 && start < stop) || + (step > 0 && start > stop)) + stop = start; + + if (value == NULL) { + /* delete slice */ + PyObject **garbage; + size_t cur; + Py_ssize_t i; + int res; + + if (slicelength <= 0) + return 0; + + if (step < 0) { + stop = start + 1; + start = stop + step*(slicelength - 1) - 1; + step = -step; + } + + garbage = (PyObject**) + PyMem_MALLOC(slicelength*sizeof(PyObject*)); + if (!garbage) { + PyErr_NoMemory(); + return -1; + } + + /* drawing pictures might help understand these for + loops. Basically, we memmove the parts of the + list that are *not* part of the slice: step-1 + items for each item that is part of the slice, + and then tail end of the list that was not + covered by the slice */ + for (cur = start, i = 0; + cur < (size_t)stop; + cur += step, i++) { + Py_ssize_t lim = step - 1; + + garbage[i] = PyList_GET_ITEM(self, cur); + + if (cur + step >= (size_t)Py_SIZE(self)) { + lim = Py_SIZE(self) - cur - 1; + } + + memmove(self->ob_item + cur - i, + self->ob_item + cur + 1, + lim * sizeof(PyObject *)); + } + cur = start + (size_t)slicelength * step; + if (cur < (size_t)Py_SIZE(self)) { + memmove(self->ob_item + cur - slicelength, + self->ob_item + cur, + (Py_SIZE(self) - cur) * + sizeof(PyObject *)); + } + + Py_SIZE(self) -= slicelength; + res = list_resize(self, Py_SIZE(self)); + + for (i = 0; i < slicelength; i++) { + Py_DECREF(garbage[i]); + } + PyMem_FREE(garbage); + + return res; + } + else { + /* assign slice */ + PyObject *ins, *seq; + PyObject **garbage, **seqitems, **selfitems; + Py_ssize_t cur, i; + + /* protect against a[::-1] = a */ + if (self == (PyListObject*)value) { + seq = list_slice((PyListObject*)value, 0, + PyList_GET_SIZE(value)); + } + else { + seq = PySequence_Fast(value, + "must assign iterable " + "to extended slice"); + } + if (!seq) + return -1; + + if (PySequence_Fast_GET_SIZE(seq) != slicelength) { + PyErr_Format(PyExc_ValueError, + "attempt to assign sequence of " + "size %zd to extended slice of " + "size %zd", + PySequence_Fast_GET_SIZE(seq), + slicelength); + Py_DECREF(seq); + return -1; + } + + if (!slicelength) { + Py_DECREF(seq); + return 0; + } + + garbage = (PyObject**) + PyMem_MALLOC(slicelength*sizeof(PyObject*)); + if (!garbage) { + Py_DECREF(seq); + PyErr_NoMemory(); + return -1; + } + + selfitems = self->ob_item; + seqitems = PySequence_Fast_ITEMS(seq); + for (cur = start, i = 0; i < slicelength; + cur += (size_t)step, i++) { + garbage[i] = selfitems[cur]; + ins = seqitems[i]; + Py_INCREF(ins); + selfitems[cur] = ins; + } + + for (i = 0; i < slicelength; i++) { + Py_DECREF(garbage[i]); + } + + PyMem_FREE(garbage); + Py_DECREF(seq); + + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "list indices must be integers or slices, not %.200s", + item->ob_type->tp_name); + return -1; + } +} + +static PyMappingMethods list_as_mapping = { + (lenfunc)list_length, + (binaryfunc)list_subscript, + (objobjargproc)list_ass_subscript +}; + +PyTypeObject PyList_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list", + sizeof(PyListObject), + 0, + (destructor)list_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)list_repr, /* tp_repr */ + 0, /* tp_as_number */ + &list_as_sequence, /* tp_as_sequence */ + &list_as_mapping, /* 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_HAVE_GC | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */ + list___init____doc__, /* tp_doc */ + (traverseproc)list_traverse, /* tp_traverse */ + (inquiry)_list_clear, /* tp_clear */ + list_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + list_iter, /* tp_iter */ + 0, /* tp_iternext */ + list_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)list___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +/*********************** List Iterator **************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ +} listiterobject; + +static void listiter_dealloc(listiterobject *); +static int listiter_traverse(listiterobject *, visitproc, void *); +static PyObject *listiter_next(listiterobject *); +static PyObject *listiter_len(listiterobject *, PyObject *); +static PyObject *listiter_reduce_general(void *_it, int forward); +static PyObject *listiter_reduce(listiterobject *, PyObject *); +static PyObject *listiter_setstate(listiterobject *, PyObject *state); + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef listiter_methods[] = { + {"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)listiter_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)listiter_setstate, METH_O, setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyListIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list_iterator", /* tp_name */ + sizeof(listiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)listiter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)listiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)listiter_next, /* tp_iternext */ + listiter_methods, /* tp_methods */ + 0, /* tp_members */ +}; + + +static PyObject * +list_iter(PyObject *seq) +{ + listiterobject *it; + + if (!PyList_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + it = PyObject_GC_New(listiterobject, &PyListIter_Type); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = (PyListObject *)seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} + +static void +listiter_dealloc(listiterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +listiter_traverse(listiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +listiter_next(listiterobject *it) +{ + PyListObject *seq; + PyObject *item; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) + return NULL; + assert(PyList_Check(seq)); + + if (it->it_index < PyList_GET_SIZE(seq)) { + item = PyList_GET_ITEM(seq, it->it_index); + ++it->it_index; + Py_INCREF(item); + return item; + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len; + if (it->it_seq) { + len = PyList_GET_SIZE(it->it_seq) - it->it_index; + if (len >= 0) + return PyLong_FromSsize_t(len); + } + return PyLong_FromLong(0); +} + +static PyObject * +listiter_reduce(listiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + return listiter_reduce_general(it, 1); +} + +static PyObject * +listiter_setstate(listiterobject *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyList_GET_SIZE(it->it_seq)) + index = PyList_GET_SIZE(it->it_seq); /* iterator exhausted */ + it->it_index = index; + } + Py_RETURN_NONE; +} + +/*********************** List Reverse Iterator **************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ +} listreviterobject; + +static void listreviter_dealloc(listreviterobject *); +static int listreviter_traverse(listreviterobject *, visitproc, void *); +static PyObject *listreviter_next(listreviterobject *); +static PyObject *listreviter_len(listreviterobject *, PyObject *); +static PyObject *listreviter_reduce(listreviterobject *, PyObject *); +static PyObject *listreviter_setstate(listreviterobject *, PyObject *); + +static PyMethodDef listreviter_methods[] = { + {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)listreviter_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)listreviter_setstate, METH_O, setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyListRevIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list_reverseiterator", /* tp_name */ + sizeof(listreviterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)listreviter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)listreviter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)listreviter_next, /* tp_iternext */ + listreviter_methods, /* tp_methods */ + 0, +}; + +/*[clinic input] +list.__reversed__ + +Return a reverse iterator over the list. +[clinic start generated code]*/ + +static PyObject * +list___reversed___impl(PyListObject *self) +/*[clinic end generated code: output=b166f073208c888c input=eadb6e17f8a6a280]*/ +{ + listreviterobject *it; + + it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type); + if (it == NULL) + return NULL; + assert(PyList_Check(self)); + it->it_index = PyList_GET_SIZE(self) - 1; + Py_INCREF(self); + it->it_seq = self; + PyObject_GC_Track(it); + return (PyObject *)it; +} + +static void +listreviter_dealloc(listreviterobject *it) +{ + PyObject_GC_UnTrack(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +listreviter_traverse(listreviterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +listreviter_next(listreviterobject *it) +{ + PyObject *item; + Py_ssize_t index; + PyListObject *seq; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) { + return NULL; + } + assert(PyList_Check(seq)); + + index = it->it_index; + if (index>=0 && index < PyList_GET_SIZE(seq)) { + item = PyList_GET_ITEM(seq, index); + it->it_index--; + Py_INCREF(item); + return item; + } + it->it_index = -1; + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +listreviter_len(listreviterobject *it, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len = it->it_index + 1; + if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len) + len = 0; + return PyLong_FromSsize_t(len); +} + +static PyObject * +listreviter_reduce(listreviterobject *it, PyObject *Py_UNUSED(ignored)) +{ + return listiter_reduce_general(it, 0); +} + +static PyObject * +listreviter_setstate(listreviterobject *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < -1) + index = -1; + else if (index > PyList_GET_SIZE(it->it_seq) - 1) + index = PyList_GET_SIZE(it->it_seq) - 1; + it->it_index = index; + } + Py_RETURN_NONE; +} + +/* common pickling support */ + +static PyObject * +listiter_reduce_general(void *_it, int forward) +{ + _Py_IDENTIFIER(iter); + _Py_IDENTIFIER(reversed); + PyObject *list; + + /* the objects are not the same, index is of different types! */ + if (forward) { + listiterobject *it = (listiterobject *)_it; + if (it->it_seq) + return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + it->it_seq, it->it_index); + } else { + listreviterobject *it = (listreviterobject *)_it; + if (it->it_seq) + return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_reversed), + it->it_seq, it->it_index); + } + /* empty iterator, create an empty list */ + list = PyList_New(0); + if (list == NULL) + return NULL; + return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); +} diff --git a/python/Objects/listsort.txt b/python/Objects/listsort.txt new file mode 100755 index 0000000..174777a --- /dev/null +++ b/python/Objects/listsort.txt @@ -0,0 +1,763 @@ +Intro +----- +This describes an adaptive, stable, natural mergesort, modestly called +timsort (hey, I earned it ). It has supernatural performance on many +kinds of partially ordered arrays (less than lg(N!) comparisons needed, and +as few as N-1), yet as fast as Python's previous highly tuned samplesort +hybrid on random arrays. + +In a nutshell, the main routine marches over the array once, left to right, +alternately identifying the next run, then merging it into the previous +runs "intelligently". Everything else is complication for speed, and some +hard-won measure of memory efficiency. + + +Comparison with Python's Samplesort Hybrid +------------------------------------------ ++ timsort can require a temp array containing as many as N//2 pointers, + which means as many as 2*N extra bytes on 32-bit boxes. It can be + expected to require a temp array this large when sorting random data; on + data with significant structure, it may get away without using any extra + heap memory. This appears to be the strongest argument against it, but + compared to the size of an object, 2 temp bytes worst-case (also expected- + case for random data) doesn't scare me much. + + It turns out that Perl is moving to a stable mergesort, and the code for + that appears always to require a temp array with room for at least N + pointers. (Note that I wouldn't want to do that even if space weren't an + issue; I believe its efforts at memory frugality also save timsort + significant pointer-copying costs, and allow it to have a smaller working + set.) + ++ Across about four hours of generating random arrays, and sorting them + under both methods, samplesort required about 1.5% more comparisons + (the program is at the end of this file). + ++ In real life, this may be faster or slower on random arrays than + samplesort was, depending on platform quirks. Since it does fewer + comparisons on average, it can be expected to do better the more + expensive a comparison function is. OTOH, it does more data movement + (pointer copying) than samplesort, and that may negate its small + comparison advantage (depending on platform quirks) unless comparison + is very expensive. + ++ On arrays with many kinds of pre-existing order, this blows samplesort out + of the water. It's significantly faster than samplesort even on some + cases samplesort was special-casing the snot out of. I believe that lists + very often do have exploitable partial order in real life, and this is the + strongest argument in favor of timsort (indeed, samplesort's special cases + for extreme partial order are appreciated by real users, and timsort goes + much deeper than those, in particular naturally covering every case where + someone has suggested "and it would be cool if list.sort() had a special + case for this too ... and for that ..."). + ++ Here are exact comparison counts across all the tests in sortperf.py, + when run with arguments "15 20 1". + + Column Key: + *sort: random data + \sort: descending data + /sort: ascending data + 3sort: ascending, then 3 random exchanges + +sort: ascending, then 10 random at the end + %sort: ascending, then randomly replace 1% of elements w/ random values + ~sort: many duplicates + =sort: all equal + !sort: worst case scenario + + First the trivial cases, trivial for samplesort because it special-cased + them, and trivial for timsort because it naturally works on runs. Within + an "n" block, the first line gives the # of compares done by samplesort, + the second line by timsort, and the third line is the percentage by + which the samplesort count exceeds the timsort count: + + n \sort /sort =sort +------- ------ ------ ------ + 32768 32768 32767 32767 samplesort + 32767 32767 32767 timsort + 0.00% 0.00% 0.00% (samplesort - timsort) / timsort + + 65536 65536 65535 65535 + 65535 65535 65535 + 0.00% 0.00% 0.00% + + 131072 131072 131071 131071 + 131071 131071 131071 + 0.00% 0.00% 0.00% + + 262144 262144 262143 262143 + 262143 262143 262143 + 0.00% 0.00% 0.00% + + 524288 524288 524287 524287 + 524287 524287 524287 + 0.00% 0.00% 0.00% + +1048576 1048576 1048575 1048575 + 1048575 1048575 1048575 + 0.00% 0.00% 0.00% + + The algorithms are effectively identical in these cases, except that + timsort does one less compare in \sort. + + Now for the more interesting cases. Where lg(x) is the logarithm of x to + the base 2 (e.g., lg(8)=3), lg(n!) is the information-theoretic limit for + the best any comparison-based sorting algorithm can do on average (across + all permutations). When a method gets significantly below that, it's + either astronomically lucky, or is finding exploitable structure in the + data. + + + n lg(n!) *sort 3sort +sort %sort ~sort !sort +------- ------- ------ ------- ------- ------ ------- -------- + 32768 444255 453096 453614 32908 452871 130491 469141 old + 448885 33016 33007 50426 182083 65534 new + 0.94% 1273.92% -0.30% 798.09% -28.33% 615.87% %ch from new + + 65536 954037 972699 981940 65686 973104 260029 1004607 + 962991 65821 65808 101667 364341 131070 + 1.01% 1391.83% -0.19% 857.15% -28.63% 666.47% + + 131072 2039137 2101881 2091491 131232 2092894 554790 2161379 + 2057533 131410 131361 206193 728871 262142 + 2.16% 1491.58% -0.10% 915.02% -23.88% 724.51% + + 262144 4340409 4464460 4403233 262314 4445884 1107842 4584560 + 4377402 262437 262459 416347 1457945 524286 + 1.99% 1577.82% -0.06% 967.83% -24.01% 774.44% + + 524288 9205096 9453356 9408463 524468 9441930 2218577 9692015 + 9278734 524580 524633 837947 2916107 1048574 + 1.88% 1693.52% -0.03% 1026.79% -23.92% 824.30% + +1048576 19458756 19950272 19838588 1048766 19912134 4430649 20434212 + 19606028 1048958 1048941 1694896 5832445 2097150 + 1.76% 1791.27% -0.02% 1074.83% -24.03% 874.38% + + Discussion of cases: + + *sort: There's no structure in random data to exploit, so the theoretical + limit is lg(n!). Both methods get close to that, and timsort is hugging + it (indeed, in a *marginal* sense, it's a spectacular improvement -- + there's only about 1% left before hitting the wall, and timsort knows + darned well it's doing compares that won't pay on random data -- but so + does the samplesort hybrid). For contrast, Hoare's original random-pivot + quicksort does about 39% more compares than the limit, and the median-of-3 + variant about 19% more. + + 3sort, %sort, and !sort: No contest; there's structure in this data, but + not of the specific kinds samplesort special-cases. Note that structure + in !sort wasn't put there on purpose -- it was crafted as a worst case for + a previous quicksort implementation. That timsort nails it came as a + surprise to me (although it's obvious in retrospect). + + +sort: samplesort special-cases this data, and does a few less compares + than timsort. However, timsort runs this case significantly faster on all + boxes we have timings for, because timsort is in the business of merging + runs efficiently, while samplesort does much more data movement in this + (for it) special case. + + ~sort: samplesort's special cases for large masses of equal elements are + extremely effective on ~sort's specific data pattern, and timsort just + isn't going to get close to that, despite that it's clearly getting a + great deal of benefit out of the duplicates (the # of compares is much less + than lg(n!)). ~sort has a perfectly uniform distribution of just 4 + distinct values, and as the distribution gets more skewed, samplesort's + equal-element gimmicks become less effective, while timsort's adaptive + strategies find more to exploit; in a database supplied by Kevin Altis, a + sort on its highly skewed "on which stock exchange does this company's + stock trade?" field ran over twice as fast under timsort. + + However, despite that timsort does many more comparisons on ~sort, and + that on several platforms ~sort runs highly significantly slower under + timsort, on other platforms ~sort runs highly significantly faster under + timsort. No other kind of data has shown this wild x-platform behavior, + and we don't have an explanation for it. The only thing I can think of + that could transform what "should be" highly significant slowdowns into + highly significant speedups on some boxes are catastrophic cache effects + in samplesort. + + But timsort "should be" slower than samplesort on ~sort, so it's hard + to count that it isn't on some boxes as a strike against it . + ++ Here's the highwater mark for the number of heap-based temp slots (4 + bytes each on this box) needed by each test, again with arguments + "15 20 1": + + 2**i *sort \sort /sort 3sort +sort %sort ~sort =sort !sort + 32768 16384 0 0 6256 0 10821 12288 0 16383 + 65536 32766 0 0 21652 0 31276 24576 0 32767 + 131072 65534 0 0 17258 0 58112 49152 0 65535 + 262144 131072 0 0 35660 0 123561 98304 0 131071 + 524288 262142 0 0 31302 0 212057 196608 0 262143 +1048576 524286 0 0 312438 0 484942 393216 0 524287 + + Discussion: The tests that end up doing (close to) perfectly balanced + merges (*sort, !sort) need all N//2 temp slots (or almost all). ~sort + also ends up doing balanced merges, but systematically benefits a lot from + the preliminary pre-merge searches described under "Merge Memory" later. + %sort approaches having a balanced merge at the end because the random + selection of elements to replace is expected to produce an out-of-order + element near the midpoint. \sort, /sort, =sort are the trivial one-run + cases, needing no merging at all. +sort ends up having one very long run + and one very short, and so gets all the temp space it needs from the small + temparray member of the MergeState struct (note that the same would be + true if the new random elements were prefixed to the sorted list instead, + but not if they appeared "in the middle"). 3sort approaches N//3 temp + slots twice, but the run lengths that remain after 3 random exchanges + clearly has very high variance. + + +A detailed description of timsort follows. + +Runs +---- +count_run() returns the # of elements in the next run. A run is either +"ascending", which means non-decreasing: + + a0 <= a1 <= a2 <= ... + +or "descending", which means strictly decreasing: + + a0 > a1 > a2 > ... + +Note that a run is always at least 2 long, unless we start at the array's +last element. + +The definition of descending is strict, because the main routine reverses +a descending run in-place, transforming a descending run into an ascending +run. Reversal is done via the obvious fast "swap elements starting at each +end, and converge at the middle" method, and that can violate stability if +the slice contains any equal elements. Using a strict definition of +descending ensures that a descending run contains distinct elements. + +If an array is random, it's very unlikely we'll see long runs. If a natural +run contains less than minrun elements (see next section), the main loop +artificially boosts it to minrun elements, via a stable binary insertion sort +applied to the right number of array elements following the short natural +run. In a random array, *all* runs are likely to be minrun long as a +result. This has two primary good effects: + +1. Random data strongly tends then toward perfectly balanced (both runs have + the same length) merges, which is the most efficient way to proceed when + data is random. + +2. Because runs are never very short, the rest of the code doesn't make + heroic efforts to shave a few cycles off per-merge overheads. For + example, reasonable use of function calls is made, rather than trying to + inline everything. Since there are no more than N/minrun runs to begin + with, a few "extra" function calls per merge is barely measurable. + + +Computing minrun +---------------- +If N < 64, minrun is N. IOW, binary insertion sort is used for the whole +array then; it's hard to beat that given the overheads of trying something +fancier (see note BINSORT). + +When N is a power of 2, testing on random data showed that minrun values of +16, 32, 64 and 128 worked about equally well. At 256 the data-movement cost +in binary insertion sort clearly hurt, and at 8 the increase in the number +of function calls clearly hurt. Picking *some* power of 2 is important +here, so that the merges end up perfectly balanced (see next section). We +pick 32 as a good value in the sweet range; picking a value at the low end +allows the adaptive gimmicks more opportunity to exploit shorter natural +runs. + +Because sortperf.py only tries powers of 2, it took a long time to notice +that 32 isn't a good choice for the general case! Consider N=2112: + +>>> divmod(2112, 32) +(66, 0) +>>> + +If the data is randomly ordered, we're very likely to end up with 66 runs +each of length 32. The first 64 of these trigger a sequence of perfectly +balanced merges (see next section), leaving runs of lengths 2048 and 64 to +merge at the end. The adaptive gimmicks can do that with fewer than 2048+64 +compares, but it's still more compares than necessary, and-- mergesort's +bugaboo relative to samplesort --a lot more data movement (O(N) copies just +to get 64 elements into place). + +If we take minrun=33 in this case, then we're very likely to end up with 64 +runs each of length 33, and then all merges are perfectly balanced. Better! + +What we want to avoid is picking minrun such that in + + q, r = divmod(N, minrun) + +q is a power of 2 and r>0 (then the last merge only gets r elements into +place, and r < minrun is small compared to N), or q a little larger than a +power of 2 regardless of r (then we've got a case similar to "2112", again +leaving too little work for the last merge to do). + +Instead we pick a minrun in range(32, 65) such that N/minrun is exactly a +power of 2, or if that isn't possible, is close to, but strictly less than, +a power of 2. This is easier to do than it may sound: take the first 6 +bits of N, and add 1 if any of the remaining bits are set. In fact, that +rule covers every case in this section, including small N and exact powers +of 2; merge_compute_minrun() is a deceptively simple function. + + +The Merge Pattern +----------------- +In order to exploit regularities in the data, we're merging on natural +run lengths, and they can become wildly unbalanced. That's a Good Thing +for this sort! It means we have to find a way to manage an assortment of +potentially very different run lengths, though. + +Stability constrains permissible merging patterns. For example, if we have +3 consecutive runs of lengths + + A:10000 B:20000 C:10000 + +we dare not merge A with C first, because if A, B and C happen to contain +a common element, it would get out of order wrt its occurrence(s) in B. The +merging must be done as (A+B)+C or A+(B+C) instead. + +So merging is always done on two consecutive runs at a time, and in-place, +although this may require some temp memory (more on that later). + +When a run is identified, its base address and length are pushed on a stack +in the MergeState struct. merge_collapse() is then called to potentially +merge runs on that stack. We would like to delay merging as long as possible +in order to exploit patterns that may come up later, but we like even more to +do merging as soon as possible to exploit that the run just found is still +high in the memory hierarchy. We also can't delay merging "too long" because +it consumes memory to remember the runs that are still unmerged, and the +stack has a fixed size. + +What turned out to be a good compromise maintains two invariants on the +stack entries, where A, B and C are the lengths of the three rightmost not-yet +merged slices: + +1. A > B+C +2. B > C + +Note that, by induction, #2 implies the lengths of pending runs form a +decreasing sequence. #1 implies that, reading the lengths right to left, +the pending-run lengths grow at least as fast as the Fibonacci numbers. +Therefore the stack can never grow larger than about log_base_phi(N) entries, +where phi = (1+sqrt(5))/2 ~= 1.618. Thus a small # of stack slots suffice +for very large arrays. + +If A <= B+C, the smaller of A and C is merged with B (ties favor C, for the +freshness-in-cache reason), and the new run replaces the A,B or B,C entries; +e.g., if the last 3 entries are + + A:30 B:20 C:10 + +then B is merged with C, leaving + + A:30 BC:30 + +on the stack. Or if they were + + A:500 B:400: C:1000 + +then A is merged with B, leaving + + AB:900 C:1000 + +on the stack. + +In both examples, the stack configuration after the merge still violates +invariant #2, and merge_collapse() goes on to continue merging runs until +both invariants are satisfied. As an extreme case, suppose we didn't do the +minrun gimmick, and natural runs were of lengths 128, 64, 32, 16, 8, 4, 2, +and 2. Nothing would get merged until the final 2 was seen, and that would +trigger 7 perfectly balanced merges. + +The thrust of these rules when they trigger merging is to balance the run +lengths as closely as possible, while keeping a low bound on the number of +runs we have to remember. This is maximally effective for random data, +where all runs are likely to be of (artificially forced) length minrun, and +then we get a sequence of perfectly balanced merges (with, perhaps, some +oddballs at the end). + +OTOH, one reason this sort is so good for partly ordered data has to do +with wildly unbalanced run lengths. + + +Merge Memory +------------ +Merging adjacent runs of lengths A and B in-place, and in linear time, is +difficult. Theoretical constructions are known that can do it, but they're +too difficult and slow for practical use. But if we have temp memory equal +to min(A, B), it's easy. + +If A is smaller (function merge_lo), copy A to a temp array, leave B alone, +and then we can do the obvious merge algorithm left to right, from the temp +area and B, starting the stores into where A used to live. There's always a +free area in the original area comprising a number of elements equal to the +number not yet merged from the temp array (trivially true at the start; +proceed by induction). The only tricky bit is that if a comparison raises an +exception, we have to remember to copy the remaining elements back in from +the temp area, lest the array end up with duplicate entries from B. But +that's exactly the same thing we need to do if we reach the end of B first, +so the exit code is pleasantly common to both the normal and error cases. + +If B is smaller (function merge_hi, which is merge_lo's "mirror image"), +much the same, except that we need to merge right to left, copying B into a +temp array and starting the stores at the right end of where B used to live. + +A refinement: When we're about to merge adjacent runs A and B, we first do +a form of binary search (more on that later) to see where B[0] should end up +in A. Elements in A preceding that point are already in their final +positions, effectively shrinking the size of A. Likewise we also search to +see where A[-1] should end up in B, and elements of B after that point can +also be ignored. This cuts the amount of temp memory needed by the same +amount. + +These preliminary searches may not pay off, and can be expected *not* to +repay their cost if the data is random. But they can win huge in all of +time, copying, and memory savings when they do pay, so this is one of the +"per-merge overheads" mentioned above that we're happy to endure because +there is at most one very short run. It's generally true in this algorithm +that we're willing to gamble a little to win a lot, even though the net +expectation is negative for random data. + + +Merge Algorithms +---------------- +merge_lo() and merge_hi() are where the bulk of the time is spent. merge_lo +deals with runs where A <= B, and merge_hi where A > B. They don't know +whether the data is clustered or uniform, but a lovely thing about merging +is that many kinds of clustering "reveal themselves" by how many times in a +row the winning merge element comes from the same run. We'll only discuss +merge_lo here; merge_hi is exactly analogous. + +Merging begins in the usual, obvious way, comparing the first element of A +to the first of B, and moving B[0] to the merge area if it's less than A[0], +else moving A[0] to the merge area. Call that the "one pair at a time" +mode. The only twist here is keeping track of how many times in a row "the +winner" comes from the same run. + +If that count reaches MIN_GALLOP, we switch to "galloping mode". Here +we *search* B for where A[0] belongs, and move over all the B's before +that point in one chunk to the merge area, then move A[0] to the merge +area. Then we search A for where B[0] belongs, and similarly move a +slice of A in one chunk. Then back to searching B for where A[0] belongs, +etc. We stay in galloping mode until both searches find slices to copy +less than MIN_GALLOP elements long, at which point we go back to one-pair- +at-a-time mode. + +A refinement: The MergeState struct contains the value of min_gallop that +controls when we enter galloping mode, initialized to MIN_GALLOP. +merge_lo() and merge_hi() adjust this higher when galloping isn't paying +off, and lower when it is. + + +Galloping +--------- +Still without loss of generality, assume A is the shorter run. In galloping +mode, we first look for A[0] in B. We do this via "galloping", comparing +A[0] in turn to B[0], B[1], B[3], B[7], ..., B[2**j - 1], ..., until finding +the k such that B[2**(k-1) - 1] < A[0] <= B[2**k - 1]. This takes at most +roughly lg(B) comparisons, and, unlike a straight binary search, favors +finding the right spot early in B (more on that later). + +After finding such a k, the region of uncertainty is reduced to 2**(k-1) - 1 +consecutive elements, and a straight binary search requires exactly k-1 +additional comparisons to nail it (see note REGION OF UNCERTAINTY). Then we +copy all the B's up to that point in one chunk, and then copy A[0]. Note +that no matter where A[0] belongs in B, the combination of galloping + binary +search finds it in no more than about 2*lg(B) comparisons. + +If we did a straight binary search, we could find it in no more than +ceiling(lg(B+1)) comparisons -- but straight binary search takes that many +comparisons no matter where A[0] belongs. Straight binary search thus loses +to galloping unless the run is quite long, and we simply can't guess +whether it is in advance. + +If data is random and runs have the same length, A[0] belongs at B[0] half +the time, at B[1] a quarter of the time, and so on: a consecutive winning +sub-run in B of length k occurs with probability 1/2**(k+1). So long +winning sub-runs are extremely unlikely in random data, and guessing that a +winning sub-run is going to be long is a dangerous game. + +OTOH, if data is lopsided or lumpy or contains many duplicates, long +stretches of winning sub-runs are very likely, and cutting the number of +comparisons needed to find one from O(B) to O(log B) is a huge win. + +Galloping compromises by getting out fast if there isn't a long winning +sub-run, yet finding such very efficiently when they exist. + +I first learned about the galloping strategy in a related context; see: + + "Adaptive Set Intersections, Unions, and Differences" (2000) + Erik D. Demaine, Alejandro López-Ortiz, J. Ian Munro + +and its followup(s). An earlier paper called the same strategy +"exponential search": + + "Optimistic Sorting and Information Theoretic Complexity" + Peter McIlroy + SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms), pp + 467-474, Austin, Texas, 25-27 January 1993. + +and it probably dates back to an earlier paper by Bentley and Yao. The +McIlroy paper in particular has good analysis of a mergesort that's +probably strongly related to this one in its galloping strategy. + + +Galloping with a Broken Leg +--------------------------- +So why don't we always gallop? Because it can lose, on two counts: + +1. While we're willing to endure small per-merge overheads, per-comparison + overheads are a different story. Calling Yet Another Function per + comparison is expensive, and gallop_left() and gallop_right() are + too long-winded for sane inlining. + +2. Galloping can-- alas --require more comparisons than linear one-at-time + search, depending on the data. + +#2 requires details. If A[0] belongs before B[0], galloping requires 1 +compare to determine that, same as linear search, except it costs more +to call the gallop function. If A[0] belongs right before B[1], galloping +requires 2 compares, again same as linear search. On the third compare, +galloping checks A[0] against B[3], and if it's <=, requires one more +compare to determine whether A[0] belongs at B[2] or B[3]. That's a total +of 4 compares, but if A[0] does belong at B[2], linear search would have +discovered that in only 3 compares, and that's a huge loss! Really. It's +an increase of 33% in the number of compares needed, and comparisons are +expensive in Python. + +index in B where # compares linear # gallop # binary gallop +A[0] belongs search needs compares compares total +---------------- ----------------- -------- -------- ------ + 0 1 1 0 1 + + 1 2 2 0 2 + + 2 3 3 1 4 + 3 4 3 1 4 + + 4 5 4 2 6 + 5 6 4 2 6 + 6 7 4 2 6 + 7 8 4 2 6 + + 8 9 5 3 8 + 9 10 5 3 8 + 10 11 5 3 8 + 11 12 5 3 8 + ... + +In general, if A[0] belongs at B[i], linear search requires i+1 comparisons +to determine that, and galloping a total of 2*floor(lg(i))+2 comparisons. +The advantage of galloping is unbounded as i grows, but it doesn't win at +all until i=6. Before then, it loses twice (at i=2 and i=4), and ties +at the other values. At and after i=6, galloping always wins. + +We can't guess in advance when it's going to win, though, so we do one pair +at a time until the evidence seems strong that galloping may pay. MIN_GALLOP +is 7, and that's pretty strong evidence. However, if the data is random, it +simply will trigger galloping mode purely by luck every now and again, and +it's quite likely to hit one of the losing cases next. On the other hand, +in cases like ~sort, galloping always pays, and MIN_GALLOP is larger than it +"should be" then. So the MergeState struct keeps a min_gallop variable +that merge_lo and merge_hi adjust: the longer we stay in galloping mode, +the smaller min_gallop gets, making it easier to transition back to +galloping mode (if we ever leave it in the current merge, and at the +start of the next merge). But whenever the gallop loop doesn't pay, +min_gallop is increased by one, making it harder to transition back +to galloping mode (and again both within a merge and across merges). For +random data, this all but eliminates the gallop penalty: min_gallop grows +large enough that we almost never get into galloping mode. And for cases +like ~sort, min_gallop can fall to as low as 1. This seems to work well, +but in all it's a minor improvement over using a fixed MIN_GALLOP value. + + +Galloping Complication +---------------------- +The description above was for merge_lo. merge_hi has to merge "from the +other end", and really needs to gallop starting at the last element in a run +instead of the first. Galloping from the first still works, but does more +comparisons than it should (this is significant -- I timed it both ways). For +this reason, the gallop_left() and gallop_right() (see note LEFT OR RIGHT) +functions have a "hint" argument, which is the index at which galloping +should begin. So galloping can actually start at any index, and proceed at +offsets of 1, 3, 7, 15, ... or -1, -3, -7, -15, ... from the starting index. + +In the code as I type it's always called with either 0 or n-1 (where n is +the # of elements in a run). It's tempting to try to do something fancier, +melding galloping with some form of interpolation search; for example, if +we're merging a run of length 1 with a run of length 10000, index 5000 is +probably a better guess at the final result than either 0 or 9999. But +it's unclear how to generalize that intuition usefully, and merging of +wildly unbalanced runs already enjoys excellent performance. + +~sort is a good example of when balanced runs could benefit from a better +hint value: to the extent possible, this would like to use a starting +offset equal to the previous value of acount/bcount. Doing so saves about +10% of the compares in ~sort. However, doing so is also a mixed bag, +hurting other cases. + + +Comparing Average # of Compares on Random Arrays +------------------------------------------------ +[NOTE: This was done when the new algorithm used about 0.1% more compares + on random data than does its current incarnation.] + +Here list.sort() is samplesort, and list.msort() this sort: + +""" +import random +from time import clock as now + +def fill(n): + from random import random + return [random() for i in range(n)] + +def mycmp(x, y): + global ncmp + ncmp += 1 + return cmp(x, y) + +def timeit(values, method): + global ncmp + X = values[:] + bound = getattr(X, method) + ncmp = 0 + t1 = now() + bound(mycmp) + t2 = now() + return t2-t1, ncmp + +format = "%5s %9.2f %11d" +f2 = "%5s %9.2f %11.2f" + +def drive(): + count = sst = sscmp = mst = mscmp = nelts = 0 + while True: + n = random.randrange(100000) + nelts += n + x = fill(n) + + t, c = timeit(x, 'sort') + sst += t + sscmp += c + + t, c = timeit(x, 'msort') + mst += t + mscmp += c + + count += 1 + if count % 10: + continue + + print "count", count, "nelts", nelts + print format % ("sort", sst, sscmp) + print format % ("msort", mst, mscmp) + print f2 % ("", (sst-mst)*1e2/mst, (sscmp-mscmp)*1e2/mscmp) + +drive() +""" + +I ran this on Windows and kept using the computer lightly while it was +running. time.clock() is wall-clock time on Windows, with better than +microsecond resolution. samplesort started with a 1.52% #-of-comparisons +disadvantage, fell quickly to 1.48%, and then fluctuated within that small +range. Here's the last chunk of output before I killed the job: + +count 2630 nelts 130906543 + sort 6110.80 1937887573 +msort 6002.78 1909389381 + 1.80 1.49 + +We've done nearly 2 billion comparisons apiece at Python speed there, and +that's enough . + +For random arrays of size 2 (yes, there are only 2 interesting ones), +samplesort has a 50%(!) comparison disadvantage. This is a consequence of +samplesort special-casing at most one ascending run at the start, then +falling back to the general case if it doesn't find an ascending run +immediately. The consequence is that it ends up using two compares to sort +[2, 1]. Gratifyingly, timsort doesn't do any special-casing, so had to be +taught how to deal with mixtures of ascending and descending runs +efficiently in all cases. + + +NOTES +----- + +BINSORT +A "binary insertion sort" is just like a textbook insertion sort, but instead +of locating the correct position of the next item via linear (one at a time) +search, an equivalent to Python's bisect.bisect_right is used to find the +correct position in logarithmic time. Most texts don't mention this +variation, and those that do usually say it's not worth the bother: insertion +sort remains quadratic (expected and worst cases) either way. Speeding the +search doesn't reduce the quadratic data movement costs. + +But in CPython's case, comparisons are extraordinarily expensive compared to +moving data, and the details matter. Moving objects is just copying +pointers. Comparisons can be arbitrarily expensive (can invoke arbitrary +user-supplied Python code), but even in simple cases (like 3 < 4) _all_ +decisions are made at runtime: what's the type of the left comparand? the +type of the right? do they need to be coerced to a common type? where's the +code to compare these types? And so on. Even the simplest Python comparison +triggers a large pile of C-level pointer dereferences, conditionals, and +function calls. + +So cutting the number of compares is almost always measurably helpful in +CPython, and the savings swamp the quadratic-time data movement costs for +reasonable minrun values. + + +LEFT OR RIGHT +gallop_left() and gallop_right() are akin to the Python bisect module's +bisect_left() and bisect_right(): they're the same unless the slice they're +searching contains a (at least one) value equal to the value being searched +for. In that case, gallop_left() returns the position immediately before the +leftmost equal value, and gallop_right() the position immediately after the +rightmost equal value. The distinction is needed to preserve stability. In +general, when merging adjacent runs A and B, gallop_left is used to search +thru B for where an element from A belongs, and gallop_right to search thru A +for where an element from B belongs. + + +REGION OF UNCERTAINTY +Two kinds of confusion seem to be common about the claim that after finding +a k such that + + B[2**(k-1) - 1] < A[0] <= B[2**k - 1] + +then a binary search requires exactly k-1 tries to find A[0]'s proper +location. For concreteness, say k=3, so B[3] < A[0] <= B[7]. + +The first confusion takes the form "OK, then the region of uncertainty is at +indices 3, 4, 5, 6 and 7: that's 5 elements, not the claimed 2**(k-1) - 1 = +3"; or the region is viewed as a Python slice and the objection is "but that's +the slice B[3:7], so has 7-3 = 4 elements". Resolution: we've already +compared A[0] against B[3] and against B[7], so A[0]'s correct location is +already known wrt _both_ endpoints. What remains is to find A[0]'s correct +location wrt B[4], B[5] and B[6], which spans 3 elements. Or in general, the +slice (leaving off both endpoints) (2**(k-1)-1)+1 through (2**k-1)-1 +inclusive = 2**(k-1) through (2**k-1)-1 inclusive, which has + (2**k-1)-1 - 2**(k-1) + 1 = + 2**k-1 - 2**(k-1) = + 2*2**(k-1)-1 - 2**(k-1) = + (2-1)*2**(k-1) - 1 = + 2**(k-1) - 1 +elements. + +The second confusion: "k-1 = 2 binary searches can find the correct location +among 2**(k-1) = 4 elements, but you're only applying it to 3 elements: we +could make this more efficient by arranging for the region of uncertainty to +span 2**(k-1) elements." Resolution: that confuses "elements" with +"locations". In a slice with N elements, there are N+1 _locations_. In the +example, with the region of uncertainty B[4], B[5], B[6], there are 4 +locations: before B[4], between B[4] and B[5], between B[5] and B[6], and +after B[6]. In general, across 2**(k-1)-1 elements, there are 2**(k-1) +locations. That's why k-1 binary searches are necessary and sufficient. + +OPTIMIZATION OF INDIVIDUAL COMPARISONS +As noted above, even the simplest Python comparison triggers a large pile of +C-level pointer dereferences, conditionals, and function calls. This can be +partially mitigated by pre-scanning the data to determine whether the data is +homogenous with respect to type. If so, it is sometimes possible to +substitute faster type-specific comparisons for the slower, generic +PyObject_RichCompareBool. diff --git a/python/Objects/lnotab_notes.txt b/python/Objects/lnotab_notes.txt new file mode 100755 index 0000000..71a2979 --- /dev/null +++ b/python/Objects/lnotab_notes.txt @@ -0,0 +1,137 @@ +All about co_lnotab, the line number table. + +Code objects store a field named co_lnotab. This is an array of unsigned bytes +disguised as a Python bytes object. It is used to map bytecode offsets to +source code line #s for tracebacks and to identify line number boundaries for +line tracing. Because of internals of the peephole optimizer, it's possible +for lnotab to contain bytecode offsets that are no longer valid (for example +if the optimizer removed the last line in a function). + +The array is conceptually a compressed list of + (bytecode offset increment, line number increment) +pairs. The details are important and delicate, best illustrated by example: + + byte code offset source code line number + 0 1 + 6 2 + 50 7 + 350 207 + 361 208 + +Instead of storing these numbers literally, we compress the list by storing only +the difference from one row to the next. Conceptually, the stored list might +look like: + + 0, 1, 6, 1, 44, 5, 300, 200, 11, 1 + +The above doesn't really work, but it's a start. An unsigned byte (byte code +offset) can't hold negative values, or values larger than 255, a signed byte +(line number) can't hold values larger than 127 or less than -128, and the +above example contains two such values. (Note that before 3.6, line number +was also encoded by an unsigned byte.) So we make two tweaks: + + (a) there's a deep assumption that byte code offsets increase monotonically, + and + (b) if byte code offset jumps by more than 255 from one row to the next, or if + source code line number jumps by more than 127 or less than -128 from one row + to the next, more than one pair is written to the table. In case #b, + there's no way to know from looking at the table later how many were written. + That's the delicate part. A user of co_lnotab desiring to find the source + line number corresponding to a bytecode address A should do something like + this: + + lineno = addr = 0 + for addr_incr, line_incr in co_lnotab: + addr += addr_incr + if addr > A: + return lineno + if line_incr >= 0x80: + line_incr -= 0x100 + lineno += line_incr + +(In C, this is implemented by PyCode_Addr2Line().) In order for this to work, +when the addr field increments by more than 255, the line # increment in each +pair generated must be 0 until the remaining addr increment is < 256. So, in +the example above, assemble_lnotab in compile.c should not (as was actually done +until 2.2) expand 300, 200 to + 255, 255, 45, 45, +but to + 255, 0, 45, 127, 0, 73. + +The above is sufficient to reconstruct line numbers for tracebacks, but not for +line tracing. Tracing is handled by PyCode_CheckLineNumber() in codeobject.c +and maybe_call_line_trace() in ceval.c. + +*** Tracing *** + +To a first approximation, we want to call the tracing function when the line +number of the current instruction changes. Re-computing the current line for +every instruction is a little slow, though, so each time we compute the line +number we save the bytecode indices where it's valid: + + *instr_lb <= frame->f_lasti < *instr_ub + +is true so long as execution does not change lines. That is, *instr_lb holds +the first bytecode index of the current line, and *instr_ub holds the first +bytecode index of the next line. As long as the above expression is true, +maybe_call_line_trace() does not need to call PyCode_CheckLineNumber(). Note +that the same line may appear multiple times in the lnotab, either because the +bytecode jumped more than 255 indices between line number changes or because +the compiler inserted the same line twice. Even in that case, *instr_ub holds +the first index of the next line. + +However, we don't *always* want to call the line trace function when the above +test fails. + +Consider this code: + +1: def f(a): +2: while a: +3: print(1) +4: break +5: else: +6: print(2) + +which compiles to this: + + 2 0 SETUP_LOOP 26 (to 28) + >> 2 LOAD_FAST 0 (a) + 4 POP_JUMP_IF_FALSE 18 + + 3 6 LOAD_GLOBAL 0 (print) + 8 LOAD_CONST 1 (1) + 10 CALL_FUNCTION 1 + 12 POP_TOP + + 4 14 BREAK_LOOP + 16 JUMP_ABSOLUTE 2 + >> 18 POP_BLOCK + + 6 20 LOAD_GLOBAL 0 (print) + 22 LOAD_CONST 2 (2) + 24 CALL_FUNCTION 1 + 26 POP_TOP + >> 28 LOAD_CONST 0 (None) + 30 RETURN_VALUE + +If 'a' is false, execution will jump to the POP_BLOCK instruction at offset 18 +and the co_lnotab will claim that execution has moved to line 4, which is wrong. +In this case, we could instead associate the POP_BLOCK with line 5, but that +would break jumps around loops without else clauses. + +We fix this by only calling the line trace function for a forward jump if the +co_lnotab indicates we have jumped to the *start* of a line, i.e. if the current +instruction offset matches the offset given for the start of a line by the +co_lnotab. For backward jumps, however, we always call the line trace function, +which lets a debugger stop on every evaluation of a loop guard (which usually +won't be the first opcode in a line). + +Why do we set f_lineno when tracing, and only just before calling the trace +function? Well, consider the code above when 'a' is true. If stepping through +this with 'n' in pdb, you would stop at line 1 with a "call" type event, then +line events on lines 2, 3, and 4, then a "return" type event -- but because the +code for the return actually falls in the range of the "line 6" opcodes, you +would be shown line 6 during this event. This is a change from the behaviour in +2.2 and before, and I've found it confusing in practice. By setting and using +f_lineno when tracing, one can report a line number different from that +suggested by f_lasti on this one occasion where it's desirable. diff --git a/python/Objects/longobject.c b/python/Objects/longobject.c new file mode 100755 index 0000000..67dce97 --- /dev/null +++ b/python/Objects/longobject.c @@ -0,0 +1,5863 @@ +/* Long (arbitrary precision) integer object implementation */ + +/* XXX The functional organization of this file is terrible */ + +#include "Python.h" +#include "longintrepr.h" + +#include +#include +#include + +#include "clinic/longobject.c.h" +/*[clinic input] +class int "PyObject *" "&PyLong_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/ + +#ifndef NSMALLPOSINTS +#define NSMALLPOSINTS 257 +#endif +#ifndef NSMALLNEGINTS +#define NSMALLNEGINTS 5 +#endif + +_Py_IDENTIFIER(little); +_Py_IDENTIFIER(big); + +/* convert a PyLong of size 1, 0 or -1 to an sdigit */ +#define MEDIUM_VALUE(x) (assert(-1 <= Py_SIZE(x) && Py_SIZE(x) <= 1), \ + Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ + (Py_SIZE(x) == 0 ? (sdigit)0 : \ + (sdigit)(x)->ob_digit[0])) + +PyObject *_PyLong_Zero = NULL; +PyObject *_PyLong_One = NULL; + +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 +/* Small integers are preallocated in this array so that they + can be shared. + The integers that are preallocated are those in the range + -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive). +*/ +static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS]; +#ifdef COUNT_ALLOCS +Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs; +#endif + +static PyObject * +get_small_int(sdigit ival) +{ + PyObject *v; + assert(-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS); + v = (PyObject *)&small_ints[ival + NSMALLNEGINTS]; + Py_INCREF(v); +#ifdef COUNT_ALLOCS + if (ival >= 0) + _Py_quick_int_allocs++; + else + _Py_quick_neg_int_allocs++; +#endif + return v; +} +#define CHECK_SMALL_INT(ival) \ + do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \ + return get_small_int((sdigit)ival); \ + } while(0) + +static PyLongObject * +maybe_small_long(PyLongObject *v) +{ + if (v && Py_ABS(Py_SIZE(v)) <= 1) { + sdigit ival = MEDIUM_VALUE(v); + if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { + Py_DECREF(v); + return (PyLongObject *)get_small_int(ival); + } + } + return v; +} +#else +#define CHECK_SMALL_INT(ival) +#define maybe_small_long(val) (val) +#endif + +/* If a freshly-allocated int is already shared, it must + be a small integer, so negating it must go to PyLong_FromLong */ +Py_LOCAL_INLINE(void) +_PyLong_Negate(PyLongObject **x_p) +{ + PyLongObject *x; + + x = (PyLongObject *)*x_p; + if (Py_REFCNT(x) == 1) { + Py_SIZE(x) = -Py_SIZE(x); + return; + } + + *x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x)); + Py_DECREF(x); +} + +/* For int multiplication, use the O(N**2) school algorithm unless + * both operands contain more than KARATSUBA_CUTOFF digits (this + * being an internal Python int digit, in base BASE). + */ +#define KARATSUBA_CUTOFF 70 +#define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF) + +/* For exponentiation, use the binary left-to-right algorithm + * unless the exponent contains more than FIVEARY_CUTOFF digits. + * In that case, do 5 bits at a time. The potential drawback is that + * a table of 2**5 intermediate results is computed. + */ +#define FIVEARY_CUTOFF 8 + +#define SIGCHECK(PyTryBlock) \ + do { \ + if (PyErr_CheckSignals()) PyTryBlock \ + } while(0) + +/* Normalize (remove leading zeros from) an int object. + Doesn't attempt to free the storage--in most cases, due to the nature + of the algorithms used, this could save at most be one word anyway. */ + +static PyLongObject * +long_normalize(PyLongObject *v) +{ + Py_ssize_t j = Py_ABS(Py_SIZE(v)); + Py_ssize_t i = j; + + while (i > 0 && v->ob_digit[i-1] == 0) + --i; + if (i != j) + Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i; + return v; +} + +/* _PyLong_FromNbInt: Convert the given object to a PyLongObject + using the nb_int slot, if available. Raise TypeError if either the + nb_int slot is not available or the result of the call to nb_int + returns something not of type int. +*/ +PyObject * +_PyLong_FromNbInt(PyObject *integral) +{ + PyNumberMethods *nb; + PyObject *result; + + /* Fast path for the case that we already have an int. */ + if (PyLong_CheckExact(integral)) { + Py_INCREF(integral); + return integral; + } + + nb = Py_TYPE(integral)->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_Format(PyExc_TypeError, + "an integer is required (got type %.200s)", + Py_TYPE(integral)->tp_name); + return NULL; + } + + /* Convert using the nb_int slot, which should return something + of exact type int. */ + result = nb->nb_int(integral); + if (!result || PyLong_CheckExact(result)) + return result; + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + result->ob_type->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; +} + +/* Convert the given object to a PyLongObject using the nb_index or + nb_int slots, if available (the latter is deprecated). + Raise TypeError if either nb_index and nb_int slots are not + available or the result of the call to nb_index or nb_int + returns something not of type int. + Should be replaced with PyNumber_Index after the end of the + deprecation period. +*/ +PyObject * +_PyLong_FromNbIndexOrNbInt(PyObject *integral) +{ + PyNumberMethods *nb; + PyObject *result; + + /* Fast path for the case that we already have an int. */ + if (PyLong_CheckExact(integral)) { + Py_INCREF(integral); + return integral; + } + + nb = Py_TYPE(integral)->tp_as_number; + if (nb == NULL || (nb->nb_index == NULL && nb->nb_int == NULL)) { + PyErr_Format(PyExc_TypeError, + "an integer is required (got type %.200s)", + Py_TYPE(integral)->tp_name); + return NULL; + } + + if (nb->nb_index) { + /* Convert using the nb_index slot, which should return something + of exact type int. */ + result = nb->nb_index(integral); + if (!result || PyLong_CheckExact(result)) + return result; + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__index__ returned non-int (type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__index__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + result->ob_type->tp_name)) + { + Py_DECREF(result); + return NULL; + } + return result; + } + + result = _PyLong_FromNbInt(integral); + if (result && PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "an integer is required (got type %.200s). " + "Implicit conversion to integers using __int__ is deprecated, " + "and may be removed in a future version of Python.", + Py_TYPE(integral)->tp_name)) + { + Py_DECREF(result); + return NULL; + } + return result; +} + + +/* Allocate a new int object with size digits. + Return NULL and set exception if we run out of memory. */ + +#define MAX_LONG_DIGITS \ + ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) + +PyLongObject * +_PyLong_New(Py_ssize_t size) +{ + PyLongObject *result; + /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + + sizeof(digit)*size. Previous incarnations of this code used + sizeof(PyVarObject) instead of the offsetof, but this risks being + incorrect in the presence of padding between the PyVarObject header + and the digits. */ + if (size > (Py_ssize_t)MAX_LONG_DIGITS) { + PyErr_SetString(PyExc_OverflowError, + "too many digits in integer"); + return NULL; + } + result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + + size*sizeof(digit)); + if (!result) { + PyErr_NoMemory(); + return NULL; + } + return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); +} + +PyObject * +_PyLong_Copy(PyLongObject *src) +{ + PyLongObject *result; + Py_ssize_t i; + + assert(src != NULL); + i = Py_SIZE(src); + if (i < 0) + i = -(i); + if (i < 2) { + sdigit ival = MEDIUM_VALUE(src); + CHECK_SMALL_INT(ival); + } + result = _PyLong_New(i); + if (result != NULL) { + Py_SIZE(result) = Py_SIZE(src); + while (--i >= 0) + result->ob_digit[i] = src->ob_digit[i]; + } + return (PyObject *)result; +} + +/* Create a new int object from a C long int */ + +PyObject * +PyLong_FromLong(long ival) +{ + PyLongObject *v; + unsigned long abs_ival; + unsigned long t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int sign; + + CHECK_SMALL_INT(ival); + + if (ival < 0) { + /* negate: can't write this as abs_ival = -ival since that + invokes undefined behaviour when ival is LONG_MIN */ + abs_ival = 0U-(unsigned long)ival; + sign = -1; + } + else { + abs_ival = (unsigned long)ival; + sign = ival == 0 ? 0 : 1; + } + + /* Fast path for single-digit ints */ + if (!(abs_ival >> PyLong_SHIFT)) { + v = _PyLong_New(1); + if (v) { + Py_SIZE(v) = sign; + v->ob_digit[0] = Py_SAFE_DOWNCAST( + abs_ival, unsigned long, digit); + } + return (PyObject*)v; + } + +#if PyLong_SHIFT==15 + /* 2 digits */ + if (!(abs_ival >> 2*PyLong_SHIFT)) { + v = _PyLong_New(2); + if (v) { + Py_SIZE(v) = 2*sign; + v->ob_digit[0] = Py_SAFE_DOWNCAST( + abs_ival & PyLong_MASK, unsigned long, digit); + v->ob_digit[1] = Py_SAFE_DOWNCAST( + abs_ival >> PyLong_SHIFT, unsigned long, digit); + } + return (PyObject*)v; + } +#endif + + /* Larger numbers: loop to determine number of digits */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits*sign; + t = abs_ival; + while (t) { + *p++ = Py_SAFE_DOWNCAST( + t & PyLong_MASK, unsigned long, digit); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +/* Create a new int object from a C unsigned long int */ + +PyObject * +PyLong_FromUnsignedLong(unsigned long ival) +{ + PyLongObject *v; + unsigned long t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong(ival); + /* Count the number of Python digits. */ + t = ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +/* Create a new int object from a C double */ + +PyObject * +PyLong_FromDouble(double dval) +{ + PyLongObject *v; + double frac; + int i, ndig, expo, neg; + neg = 0; + if (Py_IS_INFINITY(dval)) { + PyErr_SetString(PyExc_OverflowError, + "cannot convert float infinity to integer"); + return NULL; + } + if (Py_IS_NAN(dval)) { + PyErr_SetString(PyExc_ValueError, + "cannot convert float NaN to integer"); + return NULL; + } + if (dval < 0.0) { + neg = 1; + dval = -dval; + } + frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */ + if (expo <= 0) + return PyLong_FromLong(0L); + ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */ + v = _PyLong_New(ndig); + if (v == NULL) + return NULL; + frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1); + for (i = ndig; --i >= 0; ) { + digit bits = (digit)frac; + v->ob_digit[i] = bits; + frac = frac - (double)bits; + frac = ldexp(frac, PyLong_SHIFT); + } + if (neg) + Py_SIZE(v) = -(Py_SIZE(v)); + return (PyObject *)v; +} + +/* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define + * anything about what happens when a signed integer operation overflows, + * and some compilers think they're doing you a favor by being "clever" + * then. The bit pattern for the largest positive signed long is + * (unsigned long)LONG_MAX, and for the smallest negative signed long + * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN. + * However, some other compilers warn about applying unary minus to an + * unsigned operand. Hence the weird "0-". + */ +#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) +#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN) + +/* Get a C long int from an int object or any object that has an __int__ + method. + + On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of + the result. Otherwise *overflow is 0. + + For other errors (e.g., TypeError), return -1 and set an error condition. + In this case *overflow will be 0. +*/ + +long +PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) +{ + /* This version by Tim Peters */ + PyLongObject *v; + unsigned long x, prev; + long res; + Py_ssize_t i; + int sign; + int do_decref = 0; /* if nb_int was called */ + + *overflow = 0; + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(vv); + if (v == NULL) + return -1; + do_decref = 1; + } + + res = -1; + i = Py_SIZE(v); + + switch (i) { + case -1: + res = -(sdigit)v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + *overflow = sign; + goto exit; + } + } + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ + if (x <= (unsigned long)LONG_MAX) { + res = (long)x * sign; + } + else if (sign < 0 && x == PY_ABS_LONG_MIN) { + res = LONG_MIN; + } + else { + *overflow = sign; + /* res is already set to -1 */ + } + } + exit: + if (do_decref) { + Py_DECREF(v); + } + return res; +} + +/* Get a C long int from an int object or any object that has an __int__ + method. Return -1 and set an error if overflow occurs. */ + +long +PyLong_AsLong(PyObject *obj) +{ + int overflow; + long result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow) { + /* XXX: could be cute and give a different + message for overflow == -1 */ + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + } + return result; +} + +/* Get a C int from an int object or any object that has an __int__ + method. Return -1 and set an error if overflow occurs. */ + +int +_PyLong_AsInt(PyObject *obj) +{ + int overflow; + long result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow || result > INT_MAX || result < INT_MIN) { + /* XXX: could be cute and give a different + message for overflow == -1 */ + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int"); + return -1; + } + return (int)result; +} + +/* Get a Py_ssize_t from an int object. + Returns -1 and sets an error condition if overflow occurs. */ + +Py_ssize_t +PyLong_AsSsize_t(PyObject *vv) { + PyLongObject *v; + size_t x, prev; + Py_ssize_t i; + int sign; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + + v = (PyLongObject *)vv; + i = Py_SIZE(v); + switch (i) { + case -1: return -(sdigit)v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) + goto overflow; + } + /* Haven't lost any bits, but casting to a signed type requires + * extra care (see comment above). + */ + if (x <= (size_t)PY_SSIZE_T_MAX) { + return (Py_ssize_t)x * sign; + } + else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) { + return PY_SSIZE_T_MIN; + } + /* else overflow */ + + overflow: + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C ssize_t"); + return -1; +} + +/* Get a C unsigned long int from an int object. + Returns -1 and sets an error condition if overflow occurs. */ + +unsigned long +PyLong_AsUnsignedLong(PyObject *vv) +{ + PyLongObject *v; + unsigned long x, prev; + Py_ssize_t i; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return (unsigned long)-1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned long)-1; + } + + v = (PyLongObject *)vv; + i = Py_SIZE(v); + x = 0; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned int"); + return (unsigned long) -1; + } + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert " + "to C unsigned long"); + return (unsigned long) -1; + } + } + return x; +} + +/* Get a C size_t from an int object. Returns (size_t)-1 and sets + an error condition if overflow occurs. */ + +size_t +PyLong_AsSize_t(PyObject *vv) +{ + PyLongObject *v; + size_t x, prev; + Py_ssize_t i; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return (size_t) -1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (size_t)-1; + } + + v = (PyLongObject *)vv; + i = Py_SIZE(v); + x = 0; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to size_t"); + return (size_t) -1; + } + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C size_t"); + return (size_t) -1; + } + } + return x; +} + +/* Get a C unsigned long int from an int object, ignoring the high bits. + Returns -1 and sets an error condition if an error occurs. */ + +static unsigned long +_PyLong_AsUnsignedLongMask(PyObject *vv) +{ + PyLongObject *v; + unsigned long x; + Py_ssize_t i; + int sign; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long) -1; + } + v = (PyLongObject *)vv; + i = Py_SIZE(v); + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -i; + } + while (--i >= 0) { + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + } + return x * sign; +} + +unsigned long +PyLong_AsUnsignedLongMask(PyObject *op) +{ + PyLongObject *lo; + unsigned long val; + + if (op == NULL) { + PyErr_BadInternalCall(); + return (unsigned long)-1; + } + + if (PyLong_Check(op)) { + return _PyLong_AsUnsignedLongMask(op); + } + + lo = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(op); + if (lo == NULL) + return (unsigned long)-1; + + val = _PyLong_AsUnsignedLongMask((PyObject *)lo); + Py_DECREF(lo); + return val; +} + +int +_PyLong_Sign(PyObject *vv) +{ + PyLongObject *v = (PyLongObject *)vv; + + assert(v != NULL); + assert(PyLong_Check(v)); + + return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); +} + +/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d < + 2**k if d is nonzero, else 0. */ + +static const unsigned char BitLengthTable[32] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 +}; + +static int +bits_in_digit(digit d) +{ + int d_bits = 0; + while (d >= 32) { + d_bits += 6; + d >>= 6; + } + d_bits += (int)BitLengthTable[d]; + return d_bits; +} + +size_t +_PyLong_NumBits(PyObject *vv) +{ + PyLongObject *v = (PyLongObject *)vv; + size_t result = 0; + Py_ssize_t ndigits; + int msd_bits; + + assert(v != NULL); + assert(PyLong_Check(v)); + ndigits = Py_ABS(Py_SIZE(v)); + assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + if (ndigits > 0) { + digit msd = v->ob_digit[ndigits - 1]; + if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT) + goto Overflow; + result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; + msd_bits = bits_in_digit(msd); + if (SIZE_MAX - msd_bits < result) + goto Overflow; + result += msd_bits; + } + return result; + + Overflow: + PyErr_SetString(PyExc_OverflowError, "int has too many bits " + "to express in a platform size_t"); + return (size_t)-1; +} + +PyObject * +_PyLong_FromByteArray(const unsigned char* bytes, size_t n, + int little_endian, int is_signed) +{ + const unsigned char* pstartbyte; /* LSB of bytes */ + int incr; /* direction to move pstartbyte */ + const unsigned char* pendbyte; /* MSB of bytes */ + size_t numsignificantbytes; /* number of bytes that matter */ + Py_ssize_t ndigits; /* number of Python int digits */ + PyLongObject* v; /* result */ + Py_ssize_t idigit = 0; /* next free index in v->ob_digit */ + + if (n == 0) + return PyLong_FromLong(0L); + + if (little_endian) { + pstartbyte = bytes; + pendbyte = bytes + n - 1; + incr = 1; + } + else { + pstartbyte = bytes + n - 1; + pendbyte = bytes; + incr = -1; + } + + if (is_signed) + is_signed = *pendbyte >= 0x80; + + /* Compute numsignificantbytes. This consists of finding the most + significant byte. Leading 0 bytes are insignificant if the number + is positive, and leading 0xff bytes if negative. */ + { + size_t i; + const unsigned char* p = pendbyte; + const int pincr = -incr; /* search MSB to LSB */ + const unsigned char insignificant = is_signed ? 0xff : 0x00; + + for (i = 0; i < n; ++i, p += pincr) { + if (*p != insignificant) + break; + } + numsignificantbytes = n - i; + /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so + actually has 2 significant bytes. OTOH, 0xff0001 == + -0x00ffff, so we wouldn't *need* to bump it there; but we + do for 0xffff = -0x0001. To be safe without bothering to + check every case, bump it regardless. */ + if (is_signed && numsignificantbytes < n) + ++numsignificantbytes; + } + + /* How many Python int digits do we need? We have + 8*numsignificantbytes bits, and each Python int digit has + PyLong_SHIFT bits, so it's the ceiling of the quotient. */ + /* catch overflow before it happens */ + if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) { + PyErr_SetString(PyExc_OverflowError, + "byte array too long to convert to int"); + return NULL; + } + ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT; + v = _PyLong_New(ndigits); + if (v == NULL) + return NULL; + + /* Copy the bits over. The tricky parts are computing 2's-comp on + the fly for signed numbers, and dealing with the mismatch between + 8-bit bytes and (probably) 15-bit Python digits.*/ + { + size_t i; + twodigits carry = 1; /* for 2's-comp calculation */ + twodigits accum = 0; /* sliding register */ + unsigned int accumbits = 0; /* number of bits in accum */ + const unsigned char* p = pstartbyte; + + for (i = 0; i < numsignificantbytes; ++i, p += incr) { + twodigits thisbyte = *p; + /* Compute correction for 2's comp, if needed. */ + if (is_signed) { + thisbyte = (0xff ^ thisbyte) + carry; + carry = thisbyte >> 8; + thisbyte &= 0xff; + } + /* Because we're going LSB to MSB, thisbyte is + more significant than what's already in accum, + so needs to be prepended to accum. */ + accum |= thisbyte << accumbits; + accumbits += 8; + if (accumbits >= PyLong_SHIFT) { + /* There's enough to fill a Python digit. */ + assert(idigit < ndigits); + v->ob_digit[idigit] = (digit)(accum & PyLong_MASK); + ++idigit; + accum >>= PyLong_SHIFT; + accumbits -= PyLong_SHIFT; + assert(accumbits < PyLong_SHIFT); + } + } + assert(accumbits < PyLong_SHIFT); + if (accumbits) { + assert(idigit < ndigits); + v->ob_digit[idigit] = (digit)accum; + ++idigit; + } + } + + Py_SIZE(v) = is_signed ? -idigit : idigit; + return (PyObject *)long_normalize(v); +} + +int +_PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed) +{ + Py_ssize_t i; /* index into v->ob_digit */ + Py_ssize_t ndigits; /* |v->ob_size| */ + twodigits accum; /* sliding register */ + unsigned int accumbits; /* # bits in accum */ + int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ + digit carry; /* for computing 2's-comp */ + size_t j; /* # bytes filled */ + unsigned char* p; /* pointer to next byte in bytes */ + int pincr; /* direction to move p */ + + assert(v != NULL && PyLong_Check(v)); + + if (Py_SIZE(v) < 0) { + ndigits = -(Py_SIZE(v)); + if (!is_signed) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative int to unsigned"); + return -1; + } + do_twos_comp = 1; + } + else { + ndigits = Py_SIZE(v); + do_twos_comp = 0; + } + + if (little_endian) { + p = bytes; + pincr = 1; + } + else { + p = bytes + n - 1; + pincr = -1; + } + + /* Copy over all the Python digits. + It's crucial that every Python digit except for the MSD contribute + exactly PyLong_SHIFT bits to the total, so first assert that the int is + normalized. */ + assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + j = 0; + accum = 0; + accumbits = 0; + carry = do_twos_comp ? 1 : 0; + for (i = 0; i < ndigits; ++i) { + digit thisdigit = v->ob_digit[i]; + if (do_twos_comp) { + thisdigit = (thisdigit ^ PyLong_MASK) + carry; + carry = thisdigit >> PyLong_SHIFT; + thisdigit &= PyLong_MASK; + } + /* Because we're going LSB to MSB, thisdigit is more + significant than what's already in accum, so needs to be + prepended to accum. */ + accum |= (twodigits)thisdigit << accumbits; + + /* The most-significant digit may be (probably is) at least + partly empty. */ + if (i == ndigits - 1) { + /* Count # of sign bits -- they needn't be stored, + * although for signed conversion we need later to + * make sure at least one sign bit gets stored. */ + digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit; + while (s != 0) { + s >>= 1; + accumbits++; + } + } + else + accumbits += PyLong_SHIFT; + + /* Store as many bytes as possible. */ + while (accumbits >= 8) { + if (j >= n) + goto Overflow; + ++j; + *p = (unsigned char)(accum & 0xff); + p += pincr; + accumbits -= 8; + accum >>= 8; + } + } + + /* Store the straggler (if any). */ + assert(accumbits < 8); + assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ + if (accumbits > 0) { + if (j >= n) + goto Overflow; + ++j; + if (do_twos_comp) { + /* Fill leading bits of the byte with sign bits + (appropriately pretending that the int had an + infinite supply of sign bits). */ + accum |= (~(twodigits)0) << accumbits; + } + *p = (unsigned char)(accum & 0xff); + p += pincr; + } + else if (j == n && n > 0 && is_signed) { + /* The main loop filled the byte array exactly, so the code + just above didn't get to ensure there's a sign bit, and the + loop below wouldn't add one either. Make sure a sign bit + exists. */ + unsigned char msb = *(p - pincr); + int sign_bit_set = msb >= 0x80; + assert(accumbits == 0); + if (sign_bit_set == do_twos_comp) + return 0; + else + goto Overflow; + } + + /* Fill remaining bytes with copies of the sign bit. */ + { + unsigned char signbyte = do_twos_comp ? 0xffU : 0U; + for ( ; j < n; ++j, p += pincr) + *p = signbyte; + } + + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, "int too big to convert"); + return -1; + +} + +/* Create a new int object from a C pointer */ + +PyObject * +PyLong_FromVoidPtr(void *p) +{ +#if SIZEOF_VOID_P <= SIZEOF_LONG + return PyLong_FromUnsignedLong((unsigned long)(uintptr_t)p); +#else + +#if SIZEOF_LONG_LONG < SIZEOF_VOID_P +# error "PyLong_FromVoidPtr: sizeof(long long) < sizeof(void*)" +#endif + return PyLong_FromUnsignedLongLong((unsigned long long)(uintptr_t)p); +#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ + +} + +/* Get a C pointer from an int object. */ + +void * +PyLong_AsVoidPtr(PyObject *vv) +{ +#if SIZEOF_VOID_P <= SIZEOF_LONG + long x; + + if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + x = PyLong_AsLong(vv); + else + x = PyLong_AsUnsignedLong(vv); +#else + +#if SIZEOF_LONG_LONG < SIZEOF_VOID_P +# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)" +#endif + long long x; + + if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + x = PyLong_AsLongLong(vv); + else + x = PyLong_AsUnsignedLongLong(vv); + +#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ + + if (x == -1 && PyErr_Occurred()) + return NULL; + return (void *)x; +} + +/* Initial long long support by Chris Herborth (chrish@qnx.com), later + * rewritten to use the newer PyLong_{As,From}ByteArray API. + */ + +#define PY_ABS_LLONG_MIN (0-(unsigned long long)PY_LLONG_MIN) + +/* Create a new int object from a C long long int. */ + +PyObject * +PyLong_FromLongLong(long long ival) +{ + PyLongObject *v; + unsigned long long abs_ival; + unsigned long long t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int negative = 0; + + CHECK_SMALL_INT(ival); + if (ival < 0) { + /* avoid signed overflow on negation; see comments + in PyLong_FromLong above. */ + abs_ival = (unsigned long long)(-1-ival) + 1; + negative = 1; + } + else { + abs_ival = (unsigned long long)ival; + } + + /* Count the number of Python digits. + We used to pick 5 ("big enough for anything"), but that's a + waste of time and space given that 5*15 = 75 bits are rarely + needed. */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = negative ? -ndigits : ndigits; + t = abs_ival; + while (t) { + *p++ = (digit)(t & PyLong_MASK); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +/* Create a new int object from a C unsigned long long int. */ + +PyObject * +PyLong_FromUnsignedLongLong(unsigned long long ival) +{ + PyLongObject *v; + unsigned long long t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong((long)ival); + /* Count the number of Python digits. */ + t = ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +/* Create a new int object from a C Py_ssize_t. */ + +PyObject * +PyLong_FromSsize_t(Py_ssize_t ival) +{ + PyLongObject *v; + size_t abs_ival; + size_t t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int negative = 0; + + CHECK_SMALL_INT(ival); + if (ival < 0) { + /* avoid signed overflow when ival = SIZE_T_MIN */ + abs_ival = (size_t)(-1-ival)+1; + negative = 1; + } + else { + abs_ival = (size_t)ival; + } + + /* Count the number of Python digits. */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = negative ? -ndigits : ndigits; + t = abs_ival; + while (t) { + *p++ = (digit)(t & PyLong_MASK); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +/* Create a new int object from a C size_t. */ + +PyObject * +PyLong_FromSize_t(size_t ival) +{ + PyLongObject *v; + size_t t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong((long)ival); + /* Count the number of Python digits. */ + t = ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +/* Get a C long long int from an int object or any object that has an + __int__ method. Return -1 and set an error if overflow occurs. */ + +long long +PyLong_AsLongLong(PyObject *vv) +{ + PyLongObject *v; + long long bytes; + int res; + int do_decref = 0; /* if nb_int was called */ + + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(vv); + if (v == NULL) + return -1; + do_decref = 1; + } + + res = 0; + switch(Py_SIZE(v)) { + case -1: + bytes = -(sdigit)v->ob_digit[0]; + break; + case 0: + bytes = 0; + break; + case 1: + bytes = v->ob_digit[0]; + break; + default: + res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes, + SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); + } + if (do_decref) { + Py_DECREF(v); + } + + /* Plan 9 can't handle long long in ? : expressions */ + if (res < 0) + return (long long)-1; + else + return bytes; +} + +/* Get a C unsigned long long int from an int object. + Return -1 and set an error if overflow occurs. */ + +unsigned long long +PyLong_AsUnsignedLongLong(PyObject *vv) +{ + PyLongObject *v; + unsigned long long bytes; + int res; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return (unsigned long long)-1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned long long)-1; + } + + v = (PyLongObject*)vv; + switch(Py_SIZE(v)) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + + res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, + SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 0); + + /* Plan 9 can't handle long long in ? : expressions */ + if (res < 0) + return (unsigned long long)res; + else + return bytes; +} + +/* Get a C unsigned long int from an int object, ignoring the high bits. + Returns -1 and sets an error condition if an error occurs. */ + +static unsigned long long +_PyLong_AsUnsignedLongLongMask(PyObject *vv) +{ + PyLongObject *v; + unsigned long long x; + Py_ssize_t i; + int sign; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long long) -1; + } + v = (PyLongObject *)vv; + switch(Py_SIZE(v)) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + i = Py_SIZE(v); + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -i; + } + while (--i >= 0) { + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + } + return x * sign; +} + +unsigned long long +PyLong_AsUnsignedLongLongMask(PyObject *op) +{ + PyLongObject *lo; + unsigned long long val; + + if (op == NULL) { + PyErr_BadInternalCall(); + return (unsigned long long)-1; + } + + if (PyLong_Check(op)) { + return _PyLong_AsUnsignedLongLongMask(op); + } + + lo = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(op); + if (lo == NULL) + return (unsigned long long)-1; + + val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); + Py_DECREF(lo); + return val; +} + +/* Get a C long long int from an int object or any object that has an + __int__ method. + + On overflow, return -1 and set *overflow to 1 or -1 depending on the sign of + the result. Otherwise *overflow is 0. + + For other errors (e.g., TypeError), return -1 and set an error condition. + In this case *overflow will be 0. +*/ + +long long +PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) +{ + /* This version by Tim Peters */ + PyLongObject *v; + unsigned long long x, prev; + long long res; + Py_ssize_t i; + int sign; + int do_decref = 0; /* if nb_int was called */ + + *overflow = 0; + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = (PyLongObject *)_PyLong_FromNbIndexOrNbInt(vv); + if (v == NULL) + return -1; + do_decref = 1; + } + + res = -1; + i = Py_SIZE(v); + + switch (i) { + case -1: + res = -(sdigit)v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) + v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + *overflow = sign; + goto exit; + } + } + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ + if (x <= (unsigned long long)PY_LLONG_MAX) { + res = (long long)x * sign; + } + else if (sign < 0 && x == PY_ABS_LLONG_MIN) { + res = PY_LLONG_MIN; + } + else { + *overflow = sign; + /* res is already set to -1 */ + } + } + exit: + if (do_decref) { + Py_DECREF(v); + } + return res; +} + +int +_PyLong_UnsignedShort_Converter(PyObject *obj, void *ptr) +{ + unsigned long uval; + + if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + PyErr_SetString(PyExc_ValueError, "value must be positive"); + return 0; + } + uval = PyLong_AsUnsignedLong(obj); + if (uval == (unsigned long)-1 && PyErr_Occurred()) + return 0; + if (uval > USHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned short"); + return 0; + } + + *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short); + return 1; +} + +int +_PyLong_UnsignedInt_Converter(PyObject *obj, void *ptr) +{ + unsigned long uval; + + if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + PyErr_SetString(PyExc_ValueError, "value must be positive"); + return 0; + } + uval = PyLong_AsUnsignedLong(obj); + if (uval == (unsigned long)-1 && PyErr_Occurred()) + return 0; + if (uval > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned int"); + return 0; + } + + *(unsigned int *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned int); + return 1; +} + +int +_PyLong_UnsignedLong_Converter(PyObject *obj, void *ptr) +{ + unsigned long uval; + + if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + PyErr_SetString(PyExc_ValueError, "value must be positive"); + return 0; + } + uval = PyLong_AsUnsignedLong(obj); + if (uval == (unsigned long)-1 && PyErr_Occurred()) + return 0; + + *(unsigned long *)ptr = uval; + return 1; +} + +int +_PyLong_UnsignedLongLong_Converter(PyObject *obj, void *ptr) +{ + unsigned long long uval; + + if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + PyErr_SetString(PyExc_ValueError, "value must be positive"); + return 0; + } + uval = PyLong_AsUnsignedLongLong(obj); + if (uval == (unsigned long long)-1 && PyErr_Occurred()) + return 0; + + *(unsigned long long *)ptr = uval; + return 1; +} + +int +_PyLong_Size_t_Converter(PyObject *obj, void *ptr) +{ + size_t uval; + + if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + PyErr_SetString(PyExc_ValueError, "value must be positive"); + return 0; + } + uval = PyLong_AsSize_t(obj); + if (uval == (size_t)-1 && PyErr_Occurred()) + return 0; + + *(size_t *)ptr = uval; + return 1; +} + + +#define CHECK_BINOP(v,w) \ + do { \ + if (!PyLong_Check(v) || !PyLong_Check(w)) \ + Py_RETURN_NOTIMPLEMENTED; \ + } while(0) + +/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n] + * is modified in place, by adding y to it. Carries are propagated as far as + * x[m-1], and the remaining carry (0 or 1) is returned. + */ +static digit +v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) +{ + Py_ssize_t i; + digit carry = 0; + + assert(m >= n); + for (i = 0; i < n; ++i) { + carry += x[i] + y[i]; + x[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + assert((carry & 1) == carry); + } + for (; carry && i < m; ++i) { + carry += x[i]; + x[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + assert((carry & 1) == carry); + } + return carry; +} + +/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n] + * is modified in place, by subtracting y from it. Borrows are propagated as + * far as x[m-1], and the remaining borrow (0 or 1) is returned. + */ +static digit +v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) +{ + Py_ssize_t i; + digit borrow = 0; + + assert(m >= n); + for (i = 0; i < n; ++i) { + borrow = x[i] - y[i] - borrow; + x[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; /* keep only 1 sign bit */ + } + for (; borrow && i < m; ++i) { + borrow = x[i] - borrow; + x[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; + } + return borrow; +} + +/* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT. Put + * result in z[0:m], and return the d bits shifted out of the top. + */ +static digit +v_lshift(digit *z, digit *a, Py_ssize_t m, int d) +{ + Py_ssize_t i; + digit carry = 0; + + assert(0 <= d && d < PyLong_SHIFT); + for (i=0; i < m; i++) { + twodigits acc = (twodigits)a[i] << d | carry; + z[i] = (digit)acc & PyLong_MASK; + carry = (digit)(acc >> PyLong_SHIFT); + } + return carry; +} + +/* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put + * result in z[0:m], and return the d bits shifted out of the bottom. + */ +static digit +v_rshift(digit *z, digit *a, Py_ssize_t m, int d) +{ + Py_ssize_t i; + digit carry = 0; + digit mask = ((digit)1 << d) - 1U; + + assert(0 <= d && d < PyLong_SHIFT); + for (i=m; i-- > 0;) { + twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i]; + carry = (digit)acc & mask; + z[i] = (digit)(acc >> d); + } + return carry; +} + +/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient + in pout, and returning the remainder. pin and pout point at the LSD. + It's OK for pin == pout on entry, which saves oodles of mallocs/frees in + _PyLong_Format, but that should be done with great care since ints are + immutable. */ + +static digit +inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) +{ + twodigits rem = 0; + + assert(n > 0 && n <= PyLong_MASK); + pin += size; + pout += size; + while (--size >= 0) { + digit hi; + rem = (rem << PyLong_SHIFT) | *--pin; + *--pout = hi = (digit)(rem / n); + rem -= (twodigits)hi * n; + } + return (digit)rem; +} + +/* Divide an integer by a digit, returning both the quotient + (as function result) and the remainder (through *prem). + The sign of a is ignored; n should not be zero. */ + +static PyLongObject * +divrem1(PyLongObject *a, digit n, digit *prem) +{ + const Py_ssize_t size = Py_ABS(Py_SIZE(a)); + PyLongObject *z; + + assert(n > 0 && n <= PyLong_MASK); + z = _PyLong_New(size); + if (z == NULL) + return NULL; + *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); + return long_normalize(z); +} + +/* Convert an integer to a base 10 string. Returns a new non-shared + string. (Return value is non-shared so that callers can modify the + returned value if necessary.) */ + +static int +long_to_decimal_string_internal(PyObject *aa, + PyObject **p_output, + _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, + char **bytes_str) +{ + PyLongObject *scratch, *a; + PyObject *str = NULL; + Py_ssize_t size, strlen, size_a, i, j; + digit *pout, *pin, rem, tenpow; + int negative; + int d; + enum PyUnicode_Kind kind; + + a = (PyLongObject *)aa; + if (a == NULL || !PyLong_Check(a)) { + PyErr_BadInternalCall(); + return -1; + } + size_a = Py_ABS(Py_SIZE(a)); + negative = Py_SIZE(a) < 0; + + /* quick and dirty upper bound for the number of digits + required to express a in base _PyLong_DECIMAL_BASE: + + #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE)) + + But log2(a) < size_a * PyLong_SHIFT, and + log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT + > 3.3 * _PyLong_DECIMAL_SHIFT + + size_a * PyLong_SHIFT / (3.3 * _PyLong_DECIMAL_SHIFT) = + size_a + size_a / d < size_a + size_a / floor(d), + where d = (3.3 * _PyLong_DECIMAL_SHIFT) / + (PyLong_SHIFT - 3.3 * _PyLong_DECIMAL_SHIFT) + */ + d = (33 * _PyLong_DECIMAL_SHIFT) / + (10 * PyLong_SHIFT - 33 * _PyLong_DECIMAL_SHIFT); + assert(size_a < PY_SSIZE_T_MAX/2); + size = 1 + size_a + size_a / d; + scratch = _PyLong_New(size); + if (scratch == NULL) + return -1; + + /* convert array of base _PyLong_BASE digits in pin to an array of + base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, + Volume 2 (3rd edn), section 4.4, Method 1b). */ + pin = a->ob_digit; + pout = scratch->ob_digit; + size = 0; + for (i = size_a; --i >= 0; ) { + digit hi = pin[i]; + for (j = 0; j < size; j++) { + twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi; + hi = (digit)(z / _PyLong_DECIMAL_BASE); + pout[j] = (digit)(z - (twodigits)hi * + _PyLong_DECIMAL_BASE); + } + while (hi) { + pout[size++] = hi % _PyLong_DECIMAL_BASE; + hi /= _PyLong_DECIMAL_BASE; + } + /* check for keyboard interrupt */ + SIGCHECK({ + Py_DECREF(scratch); + return -1; + }); + } + /* pout should have at least one digit, so that the case when a = 0 + works correctly */ + if (size == 0) + pout[size++] = 0; + + /* calculate exact length of output string, and allocate */ + strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT; + tenpow = 10; + rem = pout[size-1]; + while (rem >= tenpow) { + tenpow *= 10; + strlen++; + } + if (writer) { + if (_PyUnicodeWriter_Prepare(writer, strlen, '9') == -1) { + Py_DECREF(scratch); + return -1; + } + kind = writer->kind; + } + else if (bytes_writer) { + *bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, strlen); + if (*bytes_str == NULL) { + Py_DECREF(scratch); + return -1; + } + } + else { + str = PyUnicode_New(strlen, '9'); + if (str == NULL) { + Py_DECREF(scratch); + return -1; + } + kind = PyUnicode_KIND(str); + } + +#define WRITE_DIGITS(p) \ + do { \ + /* pout[0] through pout[size-2] contribute exactly \ + _PyLong_DECIMAL_SHIFT digits each */ \ + for (i=0; i < size - 1; i++) { \ + rem = pout[i]; \ + for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) { \ + *--p = '0' + rem % 10; \ + rem /= 10; \ + } \ + } \ + /* pout[size-1]: always produce at least one decimal digit */ \ + rem = pout[i]; \ + do { \ + *--p = '0' + rem % 10; \ + rem /= 10; \ + } while (rem != 0); \ + \ + /* and sign */ \ + if (negative) \ + *--p = '-'; \ + } while (0) + +#define WRITE_UNICODE_DIGITS(TYPE) \ + do { \ + if (writer) \ + p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + strlen; \ + else \ + p = (TYPE*)PyUnicode_DATA(str) + strlen; \ + \ + WRITE_DIGITS(p); \ + \ + /* check we've counted correctly */ \ + if (writer) \ + assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \ + else \ + assert(p == (TYPE*)PyUnicode_DATA(str)); \ + } while (0) + + /* fill the string right-to-left */ + if (bytes_writer) { + char *p = *bytes_str + strlen; + WRITE_DIGITS(p); + assert(p == *bytes_str); + } + else if (kind == PyUnicode_1BYTE_KIND) { + Py_UCS1 *p; + WRITE_UNICODE_DIGITS(Py_UCS1); + } + else if (kind == PyUnicode_2BYTE_KIND) { + Py_UCS2 *p; + WRITE_UNICODE_DIGITS(Py_UCS2); + } + else { + Py_UCS4 *p; + assert (kind == PyUnicode_4BYTE_KIND); + WRITE_UNICODE_DIGITS(Py_UCS4); + } +#undef WRITE_DIGITS +#undef WRITE_UNICODE_DIGITS + + Py_DECREF(scratch); + if (writer) { + writer->pos += strlen; + } + else if (bytes_writer) { + (*bytes_str) += strlen; + } + else { + assert(_PyUnicode_CheckConsistency(str, 1)); + *p_output = (PyObject *)str; + } + return 0; +} + +static PyObject * +long_to_decimal_string(PyObject *aa) +{ + PyObject *v; + if (long_to_decimal_string_internal(aa, &v, NULL, NULL, NULL) == -1) + return NULL; + return v; +} + +/* Convert an int object to a string, using a given conversion base, + which should be one of 2, 8 or 16. Return a string object. + If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x' + if alternate is nonzero. */ + +static int +long_format_binary(PyObject *aa, int base, int alternate, + PyObject **p_output, _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, char **bytes_str) +{ + PyLongObject *a = (PyLongObject *)aa; + PyObject *v = NULL; + Py_ssize_t sz; + Py_ssize_t size_a; + enum PyUnicode_Kind kind; + int negative; + int bits; + + assert(base == 2 || base == 8 || base == 16); + if (a == NULL || !PyLong_Check(a)) { + PyErr_BadInternalCall(); + return -1; + } + size_a = Py_ABS(Py_SIZE(a)); + negative = Py_SIZE(a) < 0; + + /* Compute a rough upper bound for the length of the string */ + switch (base) { + case 16: + bits = 4; + break; + case 8: + bits = 3; + break; + case 2: + bits = 1; + break; + default: + Py_UNREACHABLE(); + } + + /* Compute exact length 'sz' of output string. */ + if (size_a == 0) { + sz = 1; + } + else { + Py_ssize_t size_a_in_bits; + /* Ensure overflow doesn't occur during computation of sz. */ + if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) { + PyErr_SetString(PyExc_OverflowError, + "int too large to format"); + return -1; + } + size_a_in_bits = (size_a - 1) * PyLong_SHIFT + + bits_in_digit(a->ob_digit[size_a - 1]); + /* Allow 1 character for a '-' sign. */ + sz = negative + (size_a_in_bits + (bits - 1)) / bits; + } + if (alternate) { + /* 2 characters for prefix */ + sz += 2; + } + + if (writer) { + if (_PyUnicodeWriter_Prepare(writer, sz, 'x') == -1) + return -1; + kind = writer->kind; + } + else if (bytes_writer) { + *bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, sz); + if (*bytes_str == NULL) + return -1; + } + else { + v = PyUnicode_New(sz, 'x'); + if (v == NULL) + return -1; + kind = PyUnicode_KIND(v); + } + +#define WRITE_DIGITS(p) \ + do { \ + if (size_a == 0) { \ + *--p = '0'; \ + } \ + else { \ + /* JRH: special case for power-of-2 bases */ \ + twodigits accum = 0; \ + int accumbits = 0; /* # of bits in accum */ \ + Py_ssize_t i; \ + for (i = 0; i < size_a; ++i) { \ + accum |= (twodigits)a->ob_digit[i] << accumbits; \ + accumbits += PyLong_SHIFT; \ + assert(accumbits >= bits); \ + do { \ + char cdigit; \ + cdigit = (char)(accum & (base - 1)); \ + cdigit += (cdigit < 10) ? '0' : 'a'-10; \ + *--p = cdigit; \ + accumbits -= bits; \ + accum >>= bits; \ + } while (i < size_a-1 ? accumbits >= bits : accum > 0); \ + } \ + } \ + \ + if (alternate) { \ + if (base == 16) \ + *--p = 'x'; \ + else if (base == 8) \ + *--p = 'o'; \ + else /* (base == 2) */ \ + *--p = 'b'; \ + *--p = '0'; \ + } \ + if (negative) \ + *--p = '-'; \ + } while (0) + +#define WRITE_UNICODE_DIGITS(TYPE) \ + do { \ + if (writer) \ + p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + sz; \ + else \ + p = (TYPE*)PyUnicode_DATA(v) + sz; \ + \ + WRITE_DIGITS(p); \ + \ + if (writer) \ + assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \ + else \ + assert(p == (TYPE*)PyUnicode_DATA(v)); \ + } while (0) + + if (bytes_writer) { + char *p = *bytes_str + sz; + WRITE_DIGITS(p); + assert(p == *bytes_str); + } + else if (kind == PyUnicode_1BYTE_KIND) { + Py_UCS1 *p; + WRITE_UNICODE_DIGITS(Py_UCS1); + } + else if (kind == PyUnicode_2BYTE_KIND) { + Py_UCS2 *p; + WRITE_UNICODE_DIGITS(Py_UCS2); + } + else { + Py_UCS4 *p; + assert (kind == PyUnicode_4BYTE_KIND); + WRITE_UNICODE_DIGITS(Py_UCS4); + } +#undef WRITE_DIGITS +#undef WRITE_UNICODE_DIGITS + + if (writer) { + writer->pos += sz; + } + else if (bytes_writer) { + (*bytes_str) += sz; + } + else { + assert(_PyUnicode_CheckConsistency(v, 1)); + *p_output = v; + } + return 0; +} + +PyObject * +_PyLong_Format(PyObject *obj, int base) +{ + PyObject *str; + int err; + if (base == 10) + err = long_to_decimal_string_internal(obj, &str, NULL, NULL, NULL); + else + err = long_format_binary(obj, base, 1, &str, NULL, NULL, NULL); + if (err == -1) + return NULL; + return str; +} + +int +_PyLong_FormatWriter(_PyUnicodeWriter *writer, + PyObject *obj, + int base, int alternate) +{ + if (base == 10) + return long_to_decimal_string_internal(obj, NULL, writer, + NULL, NULL); + else + return long_format_binary(obj, base, alternate, NULL, writer, + NULL, NULL); +} + +char* +_PyLong_FormatBytesWriter(_PyBytesWriter *writer, char *str, + PyObject *obj, + int base, int alternate) +{ + char *str2; + int res; + str2 = str; + if (base == 10) + res = long_to_decimal_string_internal(obj, NULL, NULL, + writer, &str2); + else + res = long_format_binary(obj, base, alternate, NULL, NULL, + writer, &str2); + if (res < 0) + return NULL; + assert(str2 != NULL); + return str2; +} + +/* Table of digit values for 8-bit string -> integer conversion. + * '0' maps to 0, ..., '9' maps to 9. + * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35. + * All other indices map to 37. + * Note that when converting a base B string, a char c is a legitimate + * base B digit iff _PyLong_DigitValue[Py_CHARPyLong_MASK(c)] < B. + */ +unsigned char _PyLong_DigitValue[256] = { + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37, + 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37, + 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, +}; + +/* *str points to the first digit in a string of base `base` digits. base + * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first + * non-digit (which may be *str!). A normalized int is returned. + * The point to this routine is that it takes time linear in the number of + * string characters. + * + * Return values: + * -1 on syntax error (exception needs to be set, *res is untouched) + * 0 else (exception may be set, in that case *res is set to NULL) + */ +static int +long_from_binary_base(const char **str, int base, PyLongObject **res) +{ + const char *p = *str; + const char *start = p; + char prev = 0; + Py_ssize_t digits = 0; + int bits_per_char; + Py_ssize_t n; + PyLongObject *z; + twodigits accum; + int bits_in_accum; + digit *pdigit; + + assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0); + n = base; + for (bits_per_char = -1; n; ++bits_per_char) { + n >>= 1; + } + /* count digits and set p to end-of-string */ + while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') { + if (*p == '_') { + if (prev == '_') { + *str = p - 1; + return -1; + } + } else { + ++digits; + } + prev = *p; + ++p; + } + if (prev == '_') { + /* Trailing underscore not allowed. */ + *str = p - 1; + return -1; + } + + *str = p; + /* n <- the number of Python digits needed, + = ceiling((digits * bits_per_char) / PyLong_SHIFT). */ + if (digits > (PY_SSIZE_T_MAX - (PyLong_SHIFT - 1)) / bits_per_char) { + PyErr_SetString(PyExc_ValueError, + "int string too large to convert"); + *res = NULL; + return 0; + } + n = (digits * bits_per_char + PyLong_SHIFT - 1) / PyLong_SHIFT; + z = _PyLong_New(n); + if (z == NULL) { + *res = NULL; + return 0; + } + /* Read string from right, and fill in int from left; i.e., + * from least to most significant in both. + */ + accum = 0; + bits_in_accum = 0; + pdigit = z->ob_digit; + while (--p >= start) { + int k; + if (*p == '_') { + continue; + } + k = (int)_PyLong_DigitValue[Py_CHARMASK(*p)]; + assert(k >= 0 && k < base); + accum |= (twodigits)k << bits_in_accum; + bits_in_accum += bits_per_char; + if (bits_in_accum >= PyLong_SHIFT) { + *pdigit++ = (digit)(accum & PyLong_MASK); + assert(pdigit - z->ob_digit <= n); + accum >>= PyLong_SHIFT; + bits_in_accum -= PyLong_SHIFT; + assert(bits_in_accum < PyLong_SHIFT); + } + } + if (bits_in_accum) { + assert(bits_in_accum <= PyLong_SHIFT); + *pdigit++ = (digit)accum; + assert(pdigit - z->ob_digit <= n); + } + while (pdigit - z->ob_digit < n) + *pdigit++ = 0; + *res = long_normalize(z); + return 0; +} + +/* Parses an int from a bytestring. Leading and trailing whitespace will be + * ignored. + * + * If successful, a PyLong object will be returned and 'pend' will be pointing + * to the first unused byte unless it's NULL. + * + * If unsuccessful, NULL will be returned. + */ +PyObject * +PyLong_FromString(const char *str, char **pend, int base) +{ + int sign = 1, error_if_nonzero = 0; + const char *start, *orig_str = str; + PyLongObject *z = NULL; + PyObject *strobj; + Py_ssize_t slen; + + if ((base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); + return NULL; + } + while (*str != '\0' && Py_ISSPACE(Py_CHARMASK(*str))) { + str++; + } + if (*str == '+') { + ++str; + } + else if (*str == '-') { + ++str; + sign = -1; + } + if (base == 0) { + if (str[0] != '0') { + base = 10; + } + else if (str[1] == 'x' || str[1] == 'X') { + base = 16; + } + else if (str[1] == 'o' || str[1] == 'O') { + base = 8; + } + else if (str[1] == 'b' || str[1] == 'B') { + base = 2; + } + else { + /* "old" (C-style) octal literal, now invalid. + it might still be zero though */ + error_if_nonzero = 1; + base = 10; + } + } + if (str[0] == '0' && + ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || + (base == 8 && (str[1] == 'o' || str[1] == 'O')) || + (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { + str += 2; + /* One underscore allowed here. */ + if (*str == '_') { + ++str; + } + } + if (str[0] == '_') { + /* May not start with underscores. */ + goto onError; + } + + start = str; + if ((base & (base - 1)) == 0) { + int res = long_from_binary_base(&str, base, &z); + if (res < 0) { + /* Syntax error. */ + goto onError; + } + } + else { +/*** +Binary bases can be converted in time linear in the number of digits, because +Python's representation base is binary. Other bases (including decimal!) use +the simple quadratic-time algorithm below, complicated by some speed tricks. + +First some math: the largest integer that can be expressed in N base-B digits +is B**N-1. Consequently, if we have an N-digit input in base B, the worst- +case number of Python digits needed to hold it is the smallest integer n s.t. + + BASE**n-1 >= B**N-1 [or, adding 1 to both sides] + BASE**n >= B**N [taking logs to base BASE] + n >= log(B**N)/log(BASE) = N * log(B)/log(BASE) + +The static array log_base_BASE[base] == log(base)/log(BASE) so we can compute +this quickly. A Python int with that much space is reserved near the start, +and the result is computed into it. + +The input string is actually treated as being in base base**i (i.e., i digits +are processed at a time), where two more static arrays hold: + + convwidth_base[base] = the largest integer i such that base**i <= BASE + convmultmax_base[base] = base ** convwidth_base[base] + +The first of these is the largest i such that i consecutive input digits +must fit in a single Python digit. The second is effectively the input +base we're really using. + +Viewing the input as a sequence of digits in base +convmultmax_base[base], the result is "simply" + + (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1 + +where B = convmultmax_base[base]. + +Error analysis: as above, the number of Python digits `n` needed is worst- +case + + n >= N * log(B)/log(BASE) + +where `N` is the number of input digits in base `B`. This is computed via + + size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1; + +below. Two numeric concerns are how much space this can waste, and whether +the computed result can be too small. To be concrete, assume BASE = 2**15, +which is the default (and it's unlikely anyone changes that). + +Waste isn't a problem: provided the first input digit isn't 0, the difference +between the worst-case input with N digits and the smallest input with N +digits is about a factor of B, but B is small compared to BASE so at most +one allocated Python digit can remain unused on that count. If +N*log(B)/log(BASE) is mathematically an exact integer, then truncating that +and adding 1 returns a result 1 larger than necessary. However, that can't +happen: whenever B is a power of 2, long_from_binary_base() is called +instead, and it's impossible for B**i to be an integer power of 2**15 when +B is not a power of 2 (i.e., it's impossible for N*log(B)/log(BASE) to be +an exact integer when B is not a power of 2, since B**i has a prime factor +other than 2 in that case, but (2**15)**j's only prime factor is 2). + +The computed result can be too small if the true value of N*log(B)/log(BASE) +is a little bit larger than an exact integer, but due to roundoff errors (in +computing log(B), log(BASE), their quotient, and/or multiplying that by N) +yields a numeric result a little less than that integer. Unfortunately, "how +close can a transcendental function get to an integer over some range?" +questions are generally theoretically intractable. Computer analysis via +continued fractions is practical: expand log(B)/log(BASE) via continued +fractions, giving a sequence i/j of "the best" rational approximations. Then +j*log(B)/log(BASE) is approximately equal to (the integer) i. This shows that +we can get very close to being in trouble, but very rarely. For example, +76573 is a denominator in one of the continued-fraction approximations to +log(10)/log(2**15), and indeed: + + >>> log(10)/log(2**15)*76573 + 16958.000000654003 + +is very close to an integer. If we were working with IEEE single-precision, +rounding errors could kill us. Finding worst cases in IEEE double-precision +requires better-than-double-precision log() functions, and Tim didn't bother. +Instead the code checks to see whether the allocated space is enough as each +new Python digit is added, and copies the whole thing to a larger int if not. +This should happen extremely rarely, and in fact I don't have a test case +that triggers it(!). Instead the code was tested by artificially allocating +just 1 digit at the start, so that the copying code was exercised for every +digit beyond the first. +***/ + twodigits c; /* current input character */ + Py_ssize_t size_z; + Py_ssize_t digits = 0; + int i; + int convwidth; + twodigits convmultmax, convmult; + digit *pz, *pzstop; + const char *scan, *lastdigit; + char prev = 0; + + static double log_base_BASE[37] = {0.0e0,}; + static int convwidth_base[37] = {0,}; + static twodigits convmultmax_base[37] = {0,}; + + if (log_base_BASE[base] == 0.0) { + twodigits convmax = base; + int i = 1; + + log_base_BASE[base] = (log((double)base) / + log((double)PyLong_BASE)); + for (;;) { + twodigits next = convmax * base; + if (next > PyLong_BASE) { + break; + } + convmax = next; + ++i; + } + convmultmax_base[base] = convmax; + assert(i > 0); + convwidth_base[base] = i; + } + + /* Find length of the string of numeric characters. */ + scan = str; + lastdigit = str; + + while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base || *scan == '_') { + if (*scan == '_') { + if (prev == '_') { + /* Only one underscore allowed. */ + str = lastdigit + 1; + goto onError; + } + } + else { + ++digits; + lastdigit = scan; + } + prev = *scan; + ++scan; + } + if (prev == '_') { + /* Trailing underscore not allowed. */ + /* Set error pointer to first underscore. */ + str = lastdigit + 1; + goto onError; + } + + /* Create an int object that can contain the largest possible + * integer with this base and length. Note that there's no + * need to initialize z->ob_digit -- no slot is read up before + * being stored into. + */ + double fsize_z = (double)digits * log_base_BASE[base] + 1.0; + if (fsize_z > (double)MAX_LONG_DIGITS) { + /* The same exception as in _PyLong_New(). */ + PyErr_SetString(PyExc_OverflowError, + "too many digits in integer"); + return NULL; + } + size_z = (Py_ssize_t)fsize_z; + /* Uncomment next line to test exceedingly rare copy code */ + /* size_z = 1; */ + assert(size_z > 0); + z = _PyLong_New(size_z); + if (z == NULL) { + return NULL; + } + Py_SIZE(z) = 0; + + /* `convwidth` consecutive input digits are treated as a single + * digit in base `convmultmax`. + */ + convwidth = convwidth_base[base]; + convmultmax = convmultmax_base[base]; + + /* Work ;-) */ + while (str < scan) { + if (*str == '_') { + str++; + continue; + } + /* grab up to convwidth digits from the input string */ + c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; + for (i = 1; i < convwidth && str != scan; ++str) { + if (*str == '_') { + continue; + } + i++; + c = (twodigits)(c * base + + (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); + assert(c < PyLong_BASE); + } + + convmult = convmultmax; + /* Calculate the shift only if we couldn't get + * convwidth digits. + */ + if (i != convwidth) { + convmult = base; + for ( ; i > 1; --i) { + convmult *= base; + } + } + + /* Multiply z by convmult, and add c. */ + pz = z->ob_digit; + pzstop = pz + Py_SIZE(z); + for (; pz < pzstop; ++pz) { + c += (twodigits)*pz * convmult; + *pz = (digit)(c & PyLong_MASK); + c >>= PyLong_SHIFT; + } + /* carry off the current end? */ + if (c) { + assert(c < PyLong_BASE); + if (Py_SIZE(z) < size_z) { + *pz = (digit)c; + ++Py_SIZE(z); + } + else { + PyLongObject *tmp; + /* Extremely rare. Get more space. */ + assert(Py_SIZE(z) == size_z); + tmp = _PyLong_New(size_z + 1); + if (tmp == NULL) { + Py_DECREF(z); + return NULL; + } + memcpy(tmp->ob_digit, + z->ob_digit, + sizeof(digit) * size_z); + Py_DECREF(z); + z = tmp; + z->ob_digit[size_z] = (digit)c; + ++size_z; + } + } + } + } + if (z == NULL) { + return NULL; + } + if (error_if_nonzero) { + /* reset the base to 0, else the exception message + doesn't make too much sense */ + base = 0; + if (Py_SIZE(z) != 0) { + goto onError; + } + /* there might still be other problems, therefore base + remains zero here for the same reason */ + } + if (str == start) { + goto onError; + } + if (sign < 0) { + Py_SIZE(z) = -(Py_SIZE(z)); + } + while (*str && Py_ISSPACE(Py_CHARMASK(*str))) { + str++; + } + if (*str != '\0') { + goto onError; + } + long_normalize(z); + z = maybe_small_long(z); + if (z == NULL) { + return NULL; + } + if (pend != NULL) { + *pend = (char *)str; + } + return (PyObject *) z; + + onError: + if (pend != NULL) { + *pend = (char *)str; + } + Py_XDECREF(z); + slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200; + strobj = PyUnicode_FromStringAndSize(orig_str, slen); + if (strobj == NULL) { + return NULL; + } + PyErr_Format(PyExc_ValueError, + "invalid literal for int() with base %d: %.200R", + base, strobj); + Py_DECREF(strobj); + return NULL; +} + +/* Since PyLong_FromString doesn't have a length parameter, + * check here for possible NULs in the string. + * + * Reports an invalid literal as a bytes object. + */ +PyObject * +_PyLong_FromBytes(const char *s, Py_ssize_t len, int base) +{ + PyObject *result, *strobj; + char *end = NULL; + + result = PyLong_FromString(s, &end, base); + if (end == NULL || (result != NULL && end == s + len)) + return result; + Py_XDECREF(result); + strobj = PyBytes_FromStringAndSize(s, Py_MIN(len, 200)); + if (strobj != NULL) { + PyErr_Format(PyExc_ValueError, + "invalid literal for int() with base %d: %.200R", + base, strobj); + Py_DECREF(strobj); + } + return NULL; +} + +PyObject * +PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) +{ + PyObject *v, *unicode = PyUnicode_FromWideChar(u, length); + if (unicode == NULL) + return NULL; + v = PyLong_FromUnicodeObject(unicode, base); + Py_DECREF(unicode); + return v; +} + +PyObject * +PyLong_FromUnicodeObject(PyObject *u, int base) +{ + PyObject *result, *asciidig; + const char *buffer; + char *end = NULL; + Py_ssize_t buflen; + + asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u); + if (asciidig == NULL) + return NULL; + assert(PyUnicode_IS_ASCII(asciidig)); + /* Simply get a pointer to existing ASCII characters. */ + buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen); + assert(buffer != NULL); + + result = PyLong_FromString(buffer, &end, base); + if (end == NULL || (result != NULL && end == buffer + buflen)) { + Py_DECREF(asciidig); + return result; + } + Py_DECREF(asciidig); + Py_XDECREF(result); + PyErr_Format(PyExc_ValueError, + "invalid literal for int() with base %d: %.200R", + base, u); + return NULL; +} + +/* forward */ +static PyLongObject *x_divrem + (PyLongObject *, PyLongObject *, PyLongObject **); +static PyObject *long_long(PyObject *v); + +/* Int division with remainder, top-level routine */ + +static int +long_divrem(PyLongObject *a, PyLongObject *b, + PyLongObject **pdiv, PyLongObject **prem) +{ + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + PyLongObject *z; + + if (size_b == 0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "integer division or modulo by zero"); + return -1; + } + if (size_a < size_b || + (size_a == size_b && + a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + /* |a| < |b|. */ + *prem = (PyLongObject *)long_long((PyObject *)a); + if (*prem == NULL) { + return -1; + } + Py_INCREF(_PyLong_Zero); + *pdiv = (PyLongObject*)_PyLong_Zero; + return 0; + } + if (size_b == 1) { + digit rem = 0; + z = divrem1(a, b->ob_digit[0], &rem); + if (z == NULL) + return -1; + *prem = (PyLongObject *) PyLong_FromLong((long)rem); + if (*prem == NULL) { + Py_DECREF(z); + return -1; + } + } + else { + z = x_divrem(a, b, prem); + if (z == NULL) + return -1; + } + /* Set the signs. + The quotient z has the sign of a*b; + the remainder r has the sign of a, + so a = b*z + r. */ + if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) { + _PyLong_Negate(&z); + if (z == NULL) { + Py_CLEAR(*prem); + return -1; + } + } + if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { + _PyLong_Negate(prem); + if (*prem == NULL) { + Py_DECREF(z); + Py_CLEAR(*prem); + return -1; + } + } + *pdiv = maybe_small_long(z); + return 0; +} + +/* Unsigned int division with remainder -- the algorithm. The arguments v1 + and w1 should satisfy 2 <= Py_ABS(Py_SIZE(w1)) <= Py_ABS(Py_SIZE(v1)). */ + +static PyLongObject * +x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) +{ + PyLongObject *v, *w, *a; + Py_ssize_t i, k, size_v, size_w; + int d; + digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak; + twodigits vv; + sdigit zhi; + stwodigits z; + + /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd + edn.), section 4.3.1, Algorithm D], except that we don't explicitly + handle the special case when the initial estimate q for a quotient + digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and + that won't overflow a digit. */ + + /* allocate space; w will also be used to hold the final remainder */ + size_v = Py_ABS(Py_SIZE(v1)); + size_w = Py_ABS(Py_SIZE(w1)); + assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ + v = _PyLong_New(size_v+1); + if (v == NULL) { + *prem = NULL; + return NULL; + } + w = _PyLong_New(size_w); + if (w == NULL) { + Py_DECREF(v); + *prem = NULL; + return NULL; + } + + /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. + shift v1 left by the same amount. Results go into w and v. */ + d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]); + carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); + assert(carry == 0); + carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); + if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) { + v->ob_digit[size_v] = carry; + size_v++; + } + + /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has + at most (and usually exactly) k = size_v - size_w digits. */ + k = size_v - size_w; + assert(k >= 0); + a = _PyLong_New(k); + if (a == NULL) { + Py_DECREF(w); + Py_DECREF(v); + *prem = NULL; + return NULL; + } + v0 = v->ob_digit; + w0 = w->ob_digit; + wm1 = w0[size_w-1]; + wm2 = w0[size_w-2]; + for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) { + /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving + single-digit quotient q, remainder in vk[0:size_w]. */ + + SIGCHECK({ + Py_DECREF(a); + Py_DECREF(w); + Py_DECREF(v); + *prem = NULL; + return NULL; + }); + + /* estimate quotient digit q; may overestimate by 1 (rare) */ + vtop = vk[size_w]; + assert(vtop <= wm1); + vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1]; + q = (digit)(vv / wm1); + r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */ + while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT) + | vk[size_w-2])) { + --q; + r += wm1; + if (r >= PyLong_BASE) + break; + } + assert(q <= PyLong_BASE); + + /* subtract q*w0[0:size_w] from vk[0:size_w+1] */ + zhi = 0; + for (i = 0; i < size_w; ++i) { + /* invariants: -PyLong_BASE <= -q <= zhi <= 0; + -PyLong_BASE * q <= z < PyLong_BASE */ + z = (sdigit)vk[i] + zhi - + (stwodigits)q * (stwodigits)w0[i]; + vk[i] = (digit)z & PyLong_MASK; + zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, + z, PyLong_SHIFT); + } + + /* add w back if q was too large (this branch taken rarely) */ + assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0); + if ((sdigit)vtop + zhi < 0) { + carry = 0; + for (i = 0; i < size_w; ++i) { + carry += vk[i] + w0[i]; + vk[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + --q; + } + + /* store quotient digit */ + assert(q < PyLong_BASE); + *--ak = q; + } + + /* unshift remainder; we reuse w to store the result */ + carry = v_rshift(w0, v0, size_w, d); + assert(carry==0); + Py_DECREF(v); + + *prem = long_normalize(w); + return long_normalize(a); +} + +/* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <= + abs(x) < 1.0 and e >= 0; return x and put e in *e. Here x is + rounded to DBL_MANT_DIG significant bits using round-half-to-even. + If a == 0, return 0.0 and set *e = 0. If the resulting exponent + e is larger than PY_SSIZE_T_MAX, raise OverflowError and return + -1.0. */ + +/* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */ +#if DBL_MANT_DIG == 53 +#define EXP2_DBL_MANT_DIG 9007199254740992.0 +#else +#define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG)) +#endif + +double +_PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) +{ + Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size; + /* See below for why x_digits is always large enough. */ + digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT]; + double dx; + /* Correction term for round-half-to-even rounding. For a digit x, + "x + half_even_correction[x & 7]" gives x rounded to the nearest + multiple of 4, rounding ties to a multiple of 8. */ + static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; + + a_size = Py_ABS(Py_SIZE(a)); + if (a_size == 0) { + /* Special case for 0: significand 0.0, exponent 0. */ + *e = 0; + return 0.0; + } + a_bits = bits_in_digit(a->ob_digit[a_size-1]); + /* The following is an overflow-free version of the check + "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ + if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && + (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 || + a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1)) + goto overflow; + a_bits = (a_size - 1) * PyLong_SHIFT + a_bits; + + /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size] + (shifting left if a_bits <= DBL_MANT_DIG + 2). + + Number of digits needed for result: write // for floor division. + Then if shifting left, we end up using + + 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT + + digits. If shifting right, we use + + a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT + + digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with + the inequalities + + m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT + m // PyLong_SHIFT - n // PyLong_SHIFT <= + 1 + (m - n - 1) // PyLong_SHIFT, + + valid for any integers m and n, we find that x_size satisfies + + x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT + + in both cases. + */ + if (a_bits <= DBL_MANT_DIG + 2) { + shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; + shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; + x_size = 0; + while (x_size < shift_digits) + x_digits[x_size++] = 0; + rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, + (int)shift_bits); + x_size += a_size; + x_digits[x_size++] = rem; + } + else { + shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; + shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; + rem = v_rshift(x_digits, a->ob_digit + shift_digits, + a_size - shift_digits, (int)shift_bits); + x_size = a_size - shift_digits; + /* For correct rounding below, we need the least significant + bit of x to be 'sticky' for this shift: if any of the bits + shifted out was nonzero, we set the least significant bit + of x. */ + if (rem) + x_digits[0] |= 1; + else + while (shift_digits > 0) + if (a->ob_digit[--shift_digits]) { + x_digits[0] |= 1; + break; + } + } + assert(1 <= x_size && x_size <= (Py_ssize_t)Py_ARRAY_LENGTH(x_digits)); + + /* Round, and convert to double. */ + x_digits[0] += half_even_correction[x_digits[0] & 7]; + dx = x_digits[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x_digits[--x_size]; + + /* Rescale; make correction if result is 1.0. */ + dx /= 4.0 * EXP2_DBL_MANT_DIG; + if (dx == 1.0) { + if (a_bits == PY_SSIZE_T_MAX) + goto overflow; + dx = 0.5; + a_bits += 1; + } + + *e = a_bits; + return Py_SIZE(a) < 0 ? -dx : dx; + + overflow: + /* exponent > PY_SSIZE_T_MAX */ + PyErr_SetString(PyExc_OverflowError, + "huge integer: number of bits overflows a Py_ssize_t"); + *e = 0; + return -1.0; +} + +/* Get a C double from an int object. Rounds to the nearest double, + using the round-half-to-even rule in the case of a tie. */ + +double +PyLong_AsDouble(PyObject *v) +{ + Py_ssize_t exponent; + double x; + + if (v == NULL) { + PyErr_BadInternalCall(); + return -1.0; + } + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1.0; + } + if (Py_ABS(Py_SIZE(v)) <= 1) { + /* Fast path; single digit long (31 bits) will cast safely + to double. This improves performance of FP/long operations + by 20%. + */ + return (double)MEDIUM_VALUE((PyLongObject *)v); + } + x = _PyLong_Frexp((PyLongObject *)v, &exponent); + if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) { + PyErr_SetString(PyExc_OverflowError, + "int too large to convert to float"); + return -1.0; + } + return ldexp(x, (int)exponent); +} + +/* Methods */ + +static int +long_compare(PyLongObject *a, PyLongObject *b) +{ + Py_ssize_t sign; + + if (Py_SIZE(a) != Py_SIZE(b)) { + sign = Py_SIZE(a) - Py_SIZE(b); + } + else { + Py_ssize_t i = Py_ABS(Py_SIZE(a)); + while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + ; + if (i < 0) + sign = 0; + else { + sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; + if (Py_SIZE(a) < 0) + sign = -sign; + } + } + return sign < 0 ? -1 : sign > 0 ? 1 : 0; +} + +static PyObject * +long_richcompare(PyObject *self, PyObject *other, int op) +{ + int result; + CHECK_BINOP(self, other); + if (self == other) + result = 0; + else + result = long_compare((PyLongObject*)self, (PyLongObject*)other); + Py_RETURN_RICHCOMPARE(result, 0, op); +} + +static Py_hash_t +long_hash(PyLongObject *v) +{ + Py_uhash_t x; + Py_ssize_t i; + int sign; + + i = Py_SIZE(v); + switch(i) { + case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we + want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo + _PyHASH_MODULUS. + + The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS + amounts to a rotation of the bits of x. To see this, write + + x * 2**PyLong_SHIFT = y * 2**_PyHASH_BITS + z + + where y = x >> (_PyHASH_BITS - PyLong_SHIFT) gives the top + PyLong_SHIFT bits of x (those that are shifted out of the + original _PyHASH_BITS bits, and z = (x << PyLong_SHIFT) & + _PyHASH_MODULUS gives the bottom _PyHASH_BITS - PyLong_SHIFT + bits of x, shifted up. Then since 2**_PyHASH_BITS is + congruent to 1 modulo _PyHASH_MODULUS, y*2**_PyHASH_BITS is + congruent to y modulo _PyHASH_MODULUS. So + + x * 2**PyLong_SHIFT = y + z (mod _PyHASH_MODULUS). + + The right-hand side is just the result of rotating the + _PyHASH_BITS bits of x left by PyLong_SHIFT places; since + not all _PyHASH_BITS bits of x are 1s, the same is true + after rotation, so 0 <= y+z < _PyHASH_MODULUS and y + z is + the reduction of x*2**PyLong_SHIFT modulo + _PyHASH_MODULUS. */ + x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | + (x >> (_PyHASH_BITS - PyLong_SHIFT)); + x += v->ob_digit[i]; + if (x >= _PyHASH_MODULUS) + x -= _PyHASH_MODULUS; + } + x = x * sign; + if (x == (Py_uhash_t)-1) + x = (Py_uhash_t)-2; + return (Py_hash_t)x; +} + + +/* Add the absolute values of two integers. */ + +static PyLongObject * +x_add(PyLongObject *a, PyLongObject *b) +{ + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + PyLongObject *z; + Py_ssize_t i; + digit carry = 0; + + /* Ensure a is the larger of the two: */ + if (size_a < size_b) { + { PyLongObject *temp = a; a = b; b = temp; } + { Py_ssize_t size_temp = size_a; + size_a = size_b; + size_b = size_temp; } + } + z = _PyLong_New(size_a+1); + if (z == NULL) + return NULL; + for (i = 0; i < size_b; ++i) { + carry += a->ob_digit[i] + b->ob_digit[i]; + z->ob_digit[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + for (; i < size_a; ++i) { + carry += a->ob_digit[i]; + z->ob_digit[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + z->ob_digit[i] = carry; + return long_normalize(z); +} + +/* Subtract the absolute values of two integers. */ + +static PyLongObject * +x_sub(PyLongObject *a, PyLongObject *b) +{ + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + PyLongObject *z; + Py_ssize_t i; + int sign = 1; + digit borrow = 0; + + /* Ensure a is the larger of the two: */ + if (size_a < size_b) { + sign = -1; + { PyLongObject *temp = a; a = b; b = temp; } + { Py_ssize_t size_temp = size_a; + size_a = size_b; + size_b = size_temp; } + } + else if (size_a == size_b) { + /* Find highest digit where a and b differ: */ + i = size_a; + while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + ; + if (i < 0) + return (PyLongObject *)PyLong_FromLong(0); + if (a->ob_digit[i] < b->ob_digit[i]) { + sign = -1; + { PyLongObject *temp = a; a = b; b = temp; } + } + size_a = size_b = i+1; + } + z = _PyLong_New(size_a); + if (z == NULL) + return NULL; + for (i = 0; i < size_b; ++i) { + /* The following assumes unsigned arithmetic + works module 2**N for some N>PyLong_SHIFT. */ + borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; + z->ob_digit[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; /* Keep only one sign bit */ + } + for (; i < size_a; ++i) { + borrow = a->ob_digit[i] - borrow; + z->ob_digit[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; /* Keep only one sign bit */ + } + assert(borrow == 0); + if (sign < 0) { + Py_SIZE(z) = -Py_SIZE(z); + } + return long_normalize(z); +} + +static PyObject * +long_add(PyLongObject *a, PyLongObject *b) +{ + PyLongObject *z; + + CHECK_BINOP(a, b); + + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { + return PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b)); + } + if (Py_SIZE(a) < 0) { + if (Py_SIZE(b) < 0) { + z = x_add(a, b); + if (z != NULL) { + /* x_add received at least one multiple-digit int, + and thus z must be a multiple-digit int. + That also means z is not an element of + small_ints, so negating it in-place is safe. */ + assert(Py_REFCNT(z) == 1); + Py_SIZE(z) = -(Py_SIZE(z)); + } + } + else + z = x_sub(b, a); + } + else { + if (Py_SIZE(b) < 0) + z = x_sub(a, b); + else + z = x_add(a, b); + } + return (PyObject *)z; +} + +static PyObject * +long_sub(PyLongObject *a, PyLongObject *b) +{ + PyLongObject *z; + + CHECK_BINOP(a, b); + + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { + return PyLong_FromLong(MEDIUM_VALUE(a) - MEDIUM_VALUE(b)); + } + if (Py_SIZE(a) < 0) { + if (Py_SIZE(b) < 0) + z = x_sub(a, b); + else + z = x_add(a, b); + if (z != NULL) { + assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); + Py_SIZE(z) = -(Py_SIZE(z)); + } + } + else { + if (Py_SIZE(b) < 0) + z = x_add(a, b); + else + z = x_sub(a, b); + } + return (PyObject *)z; +} + +/* Grade school multiplication, ignoring the signs. + * Returns the absolute value of the product, or NULL if error. + */ +static PyLongObject * +x_mul(PyLongObject *a, PyLongObject *b) +{ + PyLongObject *z; + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)); + Py_ssize_t size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t i; + + z = _PyLong_New(size_a + size_b); + if (z == NULL) + return NULL; + + memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit)); + if (a == b) { + /* Efficient squaring per HAC, Algorithm 14.16: + * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + * Gives slightly less than a 2x speedup when a == b, + * via exploiting that each entry in the multiplication + * pyramid appears twice (except for the size_a squares). + */ + for (i = 0; i < size_a; ++i) { + twodigits carry; + twodigits f = a->ob_digit[i]; + digit *pz = z->ob_digit + (i << 1); + digit *pa = a->ob_digit + i + 1; + digit *paend = a->ob_digit + size_a; + + SIGCHECK({ + Py_DECREF(z); + return NULL; + }); + + carry = *pz + f * f; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + assert(carry <= PyLong_MASK); + + /* Now f is added in twice in each column of the + * pyramid it appears. Same as adding f<<1 once. + */ + f <<= 1; + while (pa < paend) { + carry += *pz + *pa++ * f; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + assert(carry <= (PyLong_MASK << 1)); + } + if (carry) { + carry += *pz; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + } + if (carry) + *pz += (digit)(carry & PyLong_MASK); + assert((carry >> PyLong_SHIFT) == 0); + } + } + else { /* a is not the same as b -- gradeschool int mult */ + for (i = 0; i < size_a; ++i) { + twodigits carry = 0; + twodigits f = a->ob_digit[i]; + digit *pz = z->ob_digit + i; + digit *pb = b->ob_digit; + digit *pbend = b->ob_digit + size_b; + + SIGCHECK({ + Py_DECREF(z); + return NULL; + }); + + while (pb < pbend) { + carry += *pz + *pb++ * f; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + assert(carry <= PyLong_MASK); + } + if (carry) + *pz += (digit)(carry & PyLong_MASK); + assert((carry >> PyLong_SHIFT) == 0); + } + } + return long_normalize(z); +} + +/* A helper for Karatsuba multiplication (k_mul). + Takes an int "n" and an integer "size" representing the place to + split, and sets low and high such that abs(n) == (high << size) + low, + viewing the shift as being by digits. The sign bit is ignored, and + the return values are >= 0. + Returns 0 on success, -1 on failure. +*/ +static int +kmul_split(PyLongObject *n, + Py_ssize_t size, + PyLongObject **high, + PyLongObject **low) +{ + PyLongObject *hi, *lo; + Py_ssize_t size_lo, size_hi; + const Py_ssize_t size_n = Py_ABS(Py_SIZE(n)); + + size_lo = Py_MIN(size_n, size); + size_hi = size_n - size_lo; + + if ((hi = _PyLong_New(size_hi)) == NULL) + return -1; + if ((lo = _PyLong_New(size_lo)) == NULL) { + Py_DECREF(hi); + return -1; + } + + memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit)); + memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit)); + + *high = long_normalize(hi); + *low = long_normalize(lo); + return 0; +} + +static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b); + +/* Karatsuba multiplication. Ignores the input signs, and returns the + * absolute value of the product (or NULL if error). + * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295). + */ +static PyLongObject * +k_mul(PyLongObject *a, PyLongObject *b) +{ + Py_ssize_t asize = Py_ABS(Py_SIZE(a)); + Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); + PyLongObject *ah = NULL; + PyLongObject *al = NULL; + PyLongObject *bh = NULL; + PyLongObject *bl = NULL; + PyLongObject *ret = NULL; + PyLongObject *t1, *t2, *t3; + Py_ssize_t shift; /* the number of digits we split off */ + Py_ssize_t i; + + /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl + * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl + * Then the original product is + * ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl + * By picking X to be a power of 2, "*X" is just shifting, and it's + * been reduced to 3 multiplies on numbers half the size. + */ + + /* We want to split based on the larger number; fiddle so that b + * is largest. + */ + if (asize > bsize) { + t1 = a; + a = b; + b = t1; + + i = asize; + asize = bsize; + bsize = i; + } + + /* Use gradeschool math when either number is too small. */ + i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF; + if (asize <= i) { + if (asize == 0) + return (PyLongObject *)PyLong_FromLong(0); + else + return x_mul(a, b); + } + + /* If a is small compared to b, splitting on b gives a degenerate + * case with ah==0, and Karatsuba may be (even much) less efficient + * than "grade school" then. However, we can still win, by viewing + * b as a string of "big digits", each of width a->ob_size. That + * leads to a sequence of balanced calls to k_mul. + */ + if (2 * asize <= bsize) + return k_lopsided_mul(a, b); + + /* Split a & b into hi & lo pieces. */ + shift = bsize >> 1; + if (kmul_split(a, shift, &ah, &al) < 0) goto fail; + assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */ + + if (a == b) { + bh = ah; + bl = al; + Py_INCREF(bh); + Py_INCREF(bl); + } + else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail; + + /* The plan: + * 1. Allocate result space (asize + bsize digits: that's always + * enough). + * 2. Compute ah*bh, and copy into result at 2*shift. + * 3. Compute al*bl, and copy into result at 0. Note that this + * can't overlap with #2. + * 4. Subtract al*bl from the result, starting at shift. This may + * underflow (borrow out of the high digit), but we don't care: + * we're effectively doing unsigned arithmetic mod + * BASE**(sizea + sizeb), and so long as the *final* result fits, + * borrows and carries out of the high digit can be ignored. + * 5. Subtract ah*bh from the result, starting at shift. + * 6. Compute (ah+al)*(bh+bl), and add it into the result starting + * at shift. + */ + + /* 1. Allocate result space. */ + ret = _PyLong_New(asize + bsize); + if (ret == NULL) goto fail; +#ifdef Py_DEBUG + /* Fill with trash, to catch reference to uninitialized digits. */ + memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit)); +#endif + + /* 2. t1 <- ah*bh, and copy into high digits of result. */ + if ((t1 = k_mul(ah, bh)) == NULL) goto fail; + assert(Py_SIZE(t1) >= 0); + assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret)); + memcpy(ret->ob_digit + 2*shift, t1->ob_digit, + Py_SIZE(t1) * sizeof(digit)); + + /* Zero-out the digits higher than the ah*bh copy. */ + i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1); + if (i) + memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0, + i * sizeof(digit)); + + /* 3. t2 <- al*bl, and copy into the low digits. */ + if ((t2 = k_mul(al, bl)) == NULL) { + Py_DECREF(t1); + goto fail; + } + assert(Py_SIZE(t2) >= 0); + assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */ + memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit)); + + /* Zero out remaining digits. */ + i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */ + if (i) + memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); + + /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first + * because it's fresher in cache. + */ + i = Py_SIZE(ret) - shift; /* # digits after shift */ + (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); + Py_DECREF(t2); + + (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); + Py_DECREF(t1); + + /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ + if ((t1 = x_add(ah, al)) == NULL) goto fail; + Py_DECREF(ah); + Py_DECREF(al); + ah = al = NULL; + + if (a == b) { + t2 = t1; + Py_INCREF(t2); + } + else if ((t2 = x_add(bh, bl)) == NULL) { + Py_DECREF(t1); + goto fail; + } + Py_DECREF(bh); + Py_DECREF(bl); + bh = bl = NULL; + + t3 = k_mul(t1, t2); + Py_DECREF(t1); + Py_DECREF(t2); + if (t3 == NULL) goto fail; + assert(Py_SIZE(t3) >= 0); + + /* Add t3. It's not obvious why we can't run out of room here. + * See the (*) comment after this function. + */ + (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); + Py_DECREF(t3); + + return long_normalize(ret); + + fail: + Py_XDECREF(ret); + Py_XDECREF(ah); + Py_XDECREF(al); + Py_XDECREF(bh); + Py_XDECREF(bl); + return NULL; +} + +/* (*) Why adding t3 can't "run out of room" above. + +Let f(x) mean the floor of x and c(x) mean the ceiling of x. Some facts +to start with: + +1. For any integer i, i = c(i/2) + f(i/2). In particular, + bsize = c(bsize/2) + f(bsize/2). +2. shift = f(bsize/2) +3. asize <= bsize +4. Since we call k_lopsided_mul if asize*2 <= bsize, asize*2 > bsize in this + routine, so asize > bsize/2 >= f(bsize/2) in this routine. + +We allocated asize + bsize result digits, and add t3 into them at an offset +of shift. This leaves asize+bsize-shift allocated digit positions for t3 +to fit into, = (by #1 and #2) asize + f(bsize/2) + c(bsize/2) - f(bsize/2) = +asize + c(bsize/2) available digit positions. + +bh has c(bsize/2) digits, and bl at most f(size/2) digits. So bh+hl has +at most c(bsize/2) digits + 1 bit. + +If asize == bsize, ah has c(bsize/2) digits, else ah has at most f(bsize/2) +digits, and al has at most f(bsize/2) digits in any case. So ah+al has at +most (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 1 bit. + +The product (ah+al)*(bh+bl) therefore has at most + + c(bsize/2) + (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits + +and we have asize + c(bsize/2) available digit positions. We need to show +this is always enough. An instance of c(bsize/2) cancels out in both, so +the question reduces to whether asize digits is enough to hold +(asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits. If asize < bsize, +then we're asking whether asize digits >= f(bsize/2) digits + 2 bits. By #4, +asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1 +digit is enough to hold 2 bits. This is so since PyLong_SHIFT=15 >= 2. If +asize == bsize, then we're asking whether bsize digits is enough to hold +c(bsize/2) digits + 2 bits, or equivalently (by #1) whether f(bsize/2) digits +is enough to hold 2 bits. This is so if bsize >= 2, which holds because +bsize >= KARATSUBA_CUTOFF >= 2. + +Note that since there's always enough room for (ah+al)*(bh+bl), and that's +clearly >= each of ah*bh and al*bl, there's always enough room to subtract +ah*bh and al*bl too. +*/ + +/* b has at least twice the digits of a, and a is big enough that Karatsuba + * would pay off *if* the inputs had balanced sizes. View b as a sequence + * of slices, each with a->ob_size digits, and multiply the slices by a, + * one at a time. This gives k_mul balanced inputs to work with, and is + * also cache-friendly (we compute one double-width slice of the result + * at a time, then move on, never backtracking except for the helpful + * single-width slice overlap between successive partial sums). + */ +static PyLongObject * +k_lopsided_mul(PyLongObject *a, PyLongObject *b) +{ + const Py_ssize_t asize = Py_ABS(Py_SIZE(a)); + Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); + Py_ssize_t nbdone; /* # of b digits already multiplied */ + PyLongObject *ret; + PyLongObject *bslice = NULL; + + assert(asize > KARATSUBA_CUTOFF); + assert(2 * asize <= bsize); + + /* Allocate result space, and zero it out. */ + ret = _PyLong_New(asize + bsize); + if (ret == NULL) + return NULL; + memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); + + /* Successive slices of b are copied into bslice. */ + bslice = _PyLong_New(asize); + if (bslice == NULL) + goto fail; + + nbdone = 0; + while (bsize > 0) { + PyLongObject *product; + const Py_ssize_t nbtouse = Py_MIN(bsize, asize); + + /* Multiply the next slice of b by a. */ + memcpy(bslice->ob_digit, b->ob_digit + nbdone, + nbtouse * sizeof(digit)); + Py_SIZE(bslice) = nbtouse; + product = k_mul(a, bslice); + if (product == NULL) + goto fail; + + /* Add into result. */ + (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, + product->ob_digit, Py_SIZE(product)); + Py_DECREF(product); + + bsize -= nbtouse; + nbdone += nbtouse; + } + + Py_DECREF(bslice); + return long_normalize(ret); + + fail: + Py_DECREF(ret); + Py_XDECREF(bslice); + return NULL; +} + +static PyObject * +long_mul(PyLongObject *a, PyLongObject *b) +{ + PyLongObject *z; + + CHECK_BINOP(a, b); + + /* fast path for single-digit multiplication */ + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { + stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); + return PyLong_FromLongLong((long long)v); + } + + z = k_mul(a, b); + /* Negate if exactly one of the inputs is negative. */ + if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) { + _PyLong_Negate(&z); + if (z == NULL) + return NULL; + } + return (PyObject *)z; +} + +/* Fast modulo division for single-digit longs. */ +static PyObject * +fast_mod(PyLongObject *a, PyLongObject *b) +{ + sdigit left = a->ob_digit[0]; + sdigit right = b->ob_digit[0]; + sdigit mod; + + assert(Py_ABS(Py_SIZE(a)) == 1); + assert(Py_ABS(Py_SIZE(b)) == 1); + + if (Py_SIZE(a) == Py_SIZE(b)) { + /* 'a' and 'b' have the same sign. */ + mod = left % right; + } + else { + /* Either 'a' or 'b' is negative. */ + mod = right - 1 - (left - 1) % right; + } + + return PyLong_FromLong(mod * (sdigit)Py_SIZE(b)); +} + +/* Fast floor division for single-digit longs. */ +static PyObject * +fast_floor_div(PyLongObject *a, PyLongObject *b) +{ + sdigit left = a->ob_digit[0]; + sdigit right = b->ob_digit[0]; + sdigit div; + + assert(Py_ABS(Py_SIZE(a)) == 1); + assert(Py_ABS(Py_SIZE(b)) == 1); + + if (Py_SIZE(a) == Py_SIZE(b)) { + /* 'a' and 'b' have the same sign. */ + div = left / right; + } + else { + /* Either 'a' or 'b' is negative. */ + div = -1 - (left - 1) / right; + } + + return PyLong_FromLong(div); +} + +/* The / and % operators are now defined in terms of divmod(). + The expression a mod b has the value a - b*floor(a/b). + The long_divrem function gives the remainder after division of + |a| by |b|, with the sign of a. This is also expressed + as a - b*trunc(a/b), if trunc truncates towards zero. + Some examples: + a b a rem b a mod b + 13 10 3 3 + -13 10 -3 7 + 13 -10 3 -7 + -13 -10 -3 -3 + So, to get from rem to mod, we have to add b if a and b + have different signs. We then subtract one from the 'div' + part of the outcome to keep the invariant intact. */ + +/* Compute + * *pdiv, *pmod = divmod(v, w) + * NULL can be passed for pdiv or pmod, in which case that part of + * the result is simply thrown away. The caller owns a reference to + * each of these it requests (does not pass NULL for). + */ +static int +l_divmod(PyLongObject *v, PyLongObject *w, + PyLongObject **pdiv, PyLongObject **pmod) +{ + PyLongObject *div, *mod; + + if (Py_ABS(Py_SIZE(v)) == 1 && Py_ABS(Py_SIZE(w)) == 1) { + /* Fast path for single-digit longs */ + div = NULL; + if (pdiv != NULL) { + div = (PyLongObject *)fast_floor_div(v, w); + if (div == NULL) { + return -1; + } + } + if (pmod != NULL) { + mod = (PyLongObject *)fast_mod(v, w); + if (mod == NULL) { + Py_XDECREF(div); + return -1; + } + *pmod = mod; + } + if (pdiv != NULL) { + /* We only want to set `*pdiv` when `*pmod` is + set successfully. */ + *pdiv = div; + } + return 0; + } + if (long_divrem(v, w, &div, &mod) < 0) + return -1; + if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || + (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { + PyLongObject *temp; + temp = (PyLongObject *) long_add(mod, w); + Py_DECREF(mod); + mod = temp; + if (mod == NULL) { + Py_DECREF(div); + return -1; + } + temp = (PyLongObject *) long_sub(div, (PyLongObject *)_PyLong_One); + if (temp == NULL) { + Py_DECREF(mod); + Py_DECREF(div); + return -1; + } + Py_DECREF(div); + div = temp; + } + if (pdiv != NULL) + *pdiv = div; + else + Py_DECREF(div); + + if (pmod != NULL) + *pmod = mod; + else + Py_DECREF(mod); + + return 0; +} + +static PyObject * +long_div(PyObject *a, PyObject *b) +{ + PyLongObject *div; + + CHECK_BINOP(a, b); + + if (Py_ABS(Py_SIZE(a)) == 1 && Py_ABS(Py_SIZE(b)) == 1) { + return fast_floor_div((PyLongObject*)a, (PyLongObject*)b); + } + + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, NULL) < 0) + div = NULL; + return (PyObject *)div; +} + +/* PyLong/PyLong -> float, with correctly rounded result. */ + +#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT) +#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT) + +static PyObject * +long_true_divide(PyObject *v, PyObject *w) +{ + PyLongObject *a, *b, *x; + Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; + digit mask, low; + int inexact, negate, a_is_small, b_is_small; + double dx, result; + + CHECK_BINOP(v, w); + a = (PyLongObject *)v; + b = (PyLongObject *)w; + + /* + Method in a nutshell: + + 0. reduce to case a, b > 0; filter out obvious underflow/overflow + 1. choose a suitable integer 'shift' + 2. use integer arithmetic to compute x = floor(2**-shift*a/b) + 3. adjust x for correct rounding + 4. convert x to a double dx with the same value + 5. return ldexp(dx, shift). + + In more detail: + + 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b + returns either 0.0 or -0.0, depending on the sign of b. For a and + b both nonzero, ignore signs of a and b, and add the sign back in + at the end. Now write a_bits and b_bits for the bit lengths of a + and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise + for b). Then + + 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1). + + So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and + so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP - + DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of + the way, we can assume that + + DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP. + + 1. The integer 'shift' is chosen so that x has the right number of + bits for a double, plus two or three extra bits that will be used + in the rounding decisions. Writing a_bits and b_bits for the + number of significant bits in a and b respectively, a + straightforward formula for shift is: + + shift = a_bits - b_bits - DBL_MANT_DIG - 2 + + This is fine in the usual case, but if a/b is smaller than the + smallest normal float then it can lead to double rounding on an + IEEE 754 platform, giving incorrectly rounded results. So we + adjust the formula slightly. The actual formula used is: + + shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2 + + 2. The quantity x is computed by first shifting a (left -shift bits + if shift <= 0, right shift bits if shift > 0) and then dividing by + b. For both the shift and the division, we keep track of whether + the result is inexact, in a flag 'inexact'; this information is + needed at the rounding stage. + + With the choice of shift above, together with our assumption that + a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows + that x >= 1. + + 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace + this with an exactly representable float of the form + + round(x/2**extra_bits) * 2**(extra_bits+shift). + + For float representability, we need x/2**extra_bits < + 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP - + DBL_MANT_DIG. This translates to the condition: + + extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG + + To round, we just modify the bottom digit of x in-place; this can + end up giving a digit with value > PyLONG_MASK, but that's not a + problem since digits can hold values up to 2*PyLONG_MASK+1. + + With the original choices for shift above, extra_bits will always + be 2 or 3. Then rounding under the round-half-to-even rule, we + round up iff the most significant of the extra bits is 1, and + either: (a) the computation of x in step 2 had an inexact result, + or (b) at least one other of the extra bits is 1, or (c) the least + significant bit of x (above those to be rounded) is 1. + + 4. Conversion to a double is straightforward; all floating-point + operations involved in the conversion are exact, so there's no + danger of rounding errors. + + 5. Use ldexp(x, shift) to compute x*2**shift, the final result. + The result will always be exactly representable as a double, except + in the case that it overflows. To avoid dependence on the exact + behaviour of ldexp on overflow, we check for overflow before + applying ldexp. The result of ldexp is adjusted for sign before + returning. + */ + + /* Reduce to case where a and b are both positive. */ + a_size = Py_ABS(Py_SIZE(a)); + b_size = Py_ABS(Py_SIZE(b)); + negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); + if (b_size == 0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "division by zero"); + goto error; + } + if (a_size == 0) + goto underflow_or_zero; + + /* Fast path for a and b small (exactly representable in a double). + Relies on floating-point division being correctly rounded; results + may be subject to double rounding on x86 machines that operate with + the x87 FPU set to 64-bit precision. */ + a_is_small = a_size <= MANT_DIG_DIGITS || + (a_size == MANT_DIG_DIGITS+1 && + a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b_is_small = b_size <= MANT_DIG_DIGITS || + (b_size == MANT_DIG_DIGITS+1 && + b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + if (a_is_small && b_is_small) { + double da, db; + da = a->ob_digit[--a_size]; + while (a_size > 0) + da = da * PyLong_BASE + a->ob_digit[--a_size]; + db = b->ob_digit[--b_size]; + while (b_size > 0) + db = db * PyLong_BASE + b->ob_digit[--b_size]; + result = da / db; + goto success; + } + + /* Catch obvious cases of underflow and overflow */ + diff = a_size - b_size; + if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1) + /* Extreme overflow */ + goto overflow; + else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT) + /* Extreme underflow */ + goto underflow_or_zero; + /* Next line is now safe from overflowing a Py_ssize_t */ + diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) - + bits_in_digit(b->ob_digit[b_size - 1]); + /* Now diff = a_bits - b_bits. */ + if (diff > DBL_MAX_EXP) + goto overflow; + else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1) + goto underflow_or_zero; + + /* Choose value for shift; see comments for step 1 above. */ + shift = Py_MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; + + inexact = 0; + + /* x = abs(a * 2**-shift) */ + if (shift <= 0) { + Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT; + digit rem; + /* x = a << -shift */ + if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) { + /* In practice, it's probably impossible to end up + here. Both a and b would have to be enormous, + using close to SIZE_T_MAX bytes of memory each. */ + PyErr_SetString(PyExc_OverflowError, + "intermediate overflow during division"); + goto error; + } + x = _PyLong_New(a_size + shift_digits + 1); + if (x == NULL) + goto error; + for (i = 0; i < shift_digits; i++) + x->ob_digit[i] = 0; + rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + a_size, -shift % PyLong_SHIFT); + x->ob_digit[a_size + shift_digits] = rem; + } + else { + Py_ssize_t shift_digits = shift / PyLong_SHIFT; + digit rem; + /* x = a >> shift */ + assert(a_size >= shift_digits); + x = _PyLong_New(a_size - shift_digits); + if (x == NULL) + goto error; + rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + a_size - shift_digits, shift % PyLong_SHIFT); + /* set inexact if any of the bits shifted out is nonzero */ + if (rem) + inexact = 1; + while (!inexact && shift_digits > 0) + if (a->ob_digit[--shift_digits]) + inexact = 1; + } + long_normalize(x); + x_size = Py_SIZE(x); + + /* x //= b. If the remainder is nonzero, set inexact. We own the only + reference to x, so it's safe to modify it in-place. */ + if (b_size == 1) { + digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, + b->ob_digit[0]); + long_normalize(x); + if (rem) + inexact = 1; + } + else { + PyLongObject *div, *rem; + div = x_divrem(x, b, &rem); + Py_DECREF(x); + x = div; + if (x == NULL) + goto error; + if (Py_SIZE(rem)) + inexact = 1; + Py_DECREF(rem); + } + x_size = Py_ABS(Py_SIZE(x)); + assert(x_size > 0); /* result of division is never zero */ + x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); + + /* The number of extra bits that have to be rounded away. */ + extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; + assert(extra_bits == 2 || extra_bits == 3); + + /* Round by directly modifying the low digit of x. */ + mask = (digit)1 << (extra_bits - 1); + low = x->ob_digit[0] | inexact; + if ((low & mask) && (low & (3U*mask-1U))) + low += mask; + x->ob_digit[0] = low & ~(2U*mask-1U); + + /* Convert x to a double dx; the conversion is exact. */ + dx = x->ob_digit[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + Py_DECREF(x); + + /* Check whether ldexp result will overflow a double. */ + if (shift + x_bits >= DBL_MAX_EXP && + (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits))) + goto overflow; + result = ldexp(dx, (int)shift); + + success: + return PyFloat_FromDouble(negate ? -result : result); + + underflow_or_zero: + return PyFloat_FromDouble(negate ? -0.0 : 0.0); + + overflow: + PyErr_SetString(PyExc_OverflowError, + "integer division result too large for a float"); + error: + return NULL; +} + +static PyObject * +long_mod(PyObject *a, PyObject *b) +{ + PyLongObject *mod; + + CHECK_BINOP(a, b); + + if (Py_ABS(Py_SIZE(a)) == 1 && Py_ABS(Py_SIZE(b)) == 1) { + return fast_mod((PyLongObject*)a, (PyLongObject*)b); + } + + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, NULL, &mod) < 0) + mod = NULL; + return (PyObject *)mod; +} + +static PyObject * +long_divmod(PyObject *a, PyObject *b) +{ + PyLongObject *div, *mod; + PyObject *z; + + CHECK_BINOP(a, b); + + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, &mod) < 0) { + return NULL; + } + z = PyTuple_New(2); + if (z != NULL) { + PyTuple_SET_ITEM(z, 0, (PyObject *) div); + PyTuple_SET_ITEM(z, 1, (PyObject *) mod); + } + else { + Py_DECREF(div); + Py_DECREF(mod); + } + return z; +} + + +/* Compute an inverse to a modulo n, or raise ValueError if a is not + invertible modulo n. Assumes n is positive. The inverse returned + is whatever falls out of the extended Euclidean algorithm: it may + be either positive or negative, but will be smaller than n in + absolute value. + + Pure Python equivalent for long_invmod: + + def invmod(a, n): + b, c = 1, 0 + while n: + q, r = divmod(a, n) + a, b, c, n = n, c, b - q*c, r + + # at this point a is the gcd of the original inputs + if a == 1: + return b + raise ValueError("Not invertible") +*/ + +static PyLongObject * +long_invmod(PyLongObject *a, PyLongObject *n) +{ + PyLongObject *b, *c; + + /* Should only ever be called for positive n */ + assert(Py_SIZE(n) > 0); + + b = (PyLongObject *)PyLong_FromLong(1L); + if (b == NULL) { + return NULL; + } + c = (PyLongObject *)PyLong_FromLong(0L); + if (c == NULL) { + Py_DECREF(b); + return NULL; + } + Py_INCREF(a); + Py_INCREF(n); + + /* references now owned: a, b, c, n */ + while (Py_SIZE(n) != 0) { + PyLongObject *q, *r, *s, *t; + + if (l_divmod(a, n, &q, &r) == -1) { + goto Error; + } + Py_DECREF(a); + a = n; + n = r; + t = (PyLongObject *)long_mul(q, c); + Py_DECREF(q); + if (t == NULL) { + goto Error; + } + s = (PyLongObject *)long_sub(b, t); + Py_DECREF(t); + if (s == NULL) { + goto Error; + } + Py_DECREF(b); + b = c; + c = s; + } + /* references now owned: a, b, c, n */ + + Py_DECREF(c); + Py_DECREF(n); + if (long_compare(a, (PyLongObject *)_PyLong_One)) { + /* a != 1; we don't have an inverse. */ + Py_DECREF(a); + Py_DECREF(b); + PyErr_SetString(PyExc_ValueError, + "base is not invertible for the given modulus"); + return NULL; + } + else { + /* a == 1; b gives an inverse modulo n */ + Py_DECREF(a); + return b; + } + + Error: + Py_DECREF(a); + Py_DECREF(b); + Py_DECREF(c); + Py_DECREF(n); + return NULL; +} + + +/* pow(v, w, x) */ +static PyObject * +long_pow(PyObject *v, PyObject *w, PyObject *x) +{ + PyLongObject *a, *b, *c; /* a,b,c = v,w,x */ + int negativeOutput = 0; /* if x<0 return negative output */ + + PyLongObject *z = NULL; /* accumulated result */ + Py_ssize_t i, j, k; /* counters */ + PyLongObject *temp = NULL; + + /* 5-ary values. If the exponent is large enough, table is + * precomputed so that table[i] == a**i % c for i in range(32). + */ + PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + /* a, b, c = v, w, x */ + CHECK_BINOP(v, w); + a = (PyLongObject*)v; Py_INCREF(a); + b = (PyLongObject*)w; Py_INCREF(b); + if (PyLong_Check(x)) { + c = (PyLongObject *)x; + Py_INCREF(x); + } + else if (x == Py_None) + c = NULL; + else { + Py_DECREF(a); + Py_DECREF(b); + Py_RETURN_NOTIMPLEMENTED; + } + + if (Py_SIZE(b) < 0 && c == NULL) { + /* if exponent is negative and there's no modulus: + return a float. This works because we know + that this calls float_pow() which converts its + arguments to double. */ + Py_DECREF(a); + Py_DECREF(b); + return PyFloat_Type.tp_as_number->nb_power(v, w, x); + } + + if (c) { + /* if modulus == 0: + raise ValueError() */ + if (Py_SIZE(c) == 0) { + PyErr_SetString(PyExc_ValueError, + "pow() 3rd argument cannot be 0"); + goto Error; + } + + /* if modulus < 0: + negativeOutput = True + modulus = -modulus */ + if (Py_SIZE(c) < 0) { + negativeOutput = 1; + temp = (PyLongObject *)_PyLong_Copy(c); + if (temp == NULL) + goto Error; + Py_DECREF(c); + c = temp; + temp = NULL; + _PyLong_Negate(&c); + if (c == NULL) + goto Error; + } + + /* if modulus == 1: + return 0 */ + if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) { + z = (PyLongObject *)PyLong_FromLong(0L); + goto Done; + } + + /* if exponent is negative, negate the exponent and + replace the base with a modular inverse */ + if (Py_SIZE(b) < 0) { + temp = (PyLongObject *)_PyLong_Copy(b); + if (temp == NULL) + goto Error; + Py_DECREF(b); + b = temp; + temp = NULL; + _PyLong_Negate(&b); + if (b == NULL) + goto Error; + + temp = long_invmod(a, c); + if (temp == NULL) + goto Error; + Py_DECREF(a); + a = temp; + } + + /* Reduce base by modulus in some cases: + 1. If base < 0. Forcing the base non-negative makes things easier. + 2. If base is obviously larger than the modulus. The "small + exponent" case later can multiply directly by base repeatedly, + while the "large exponent" case multiplies directly by base 31 + times. It can be unboundedly faster to multiply by + base % modulus instead. + We could _always_ do this reduction, but l_divmod() isn't cheap, + so we only do it when it buys something. */ + if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) { + if (l_divmod(a, c, NULL, &temp) < 0) + goto Error; + Py_DECREF(a); + a = temp; + temp = NULL; + } + } + + /* At this point a, b, and c are guaranteed non-negative UNLESS + c is NULL, in which case a may be negative. */ + + z = (PyLongObject *)PyLong_FromLong(1L); + if (z == NULL) + goto Error; + + /* Perform a modular reduction, X = X % c, but leave X alone if c + * is NULL. + */ +#define REDUCE(X) \ + do { \ + if (c != NULL) { \ + if (l_divmod(X, c, NULL, &temp) < 0) \ + goto Error; \ + Py_XDECREF(X); \ + X = temp; \ + temp = NULL; \ + } \ + } while(0) + + /* Multiply two values, then reduce the result: + result = X*Y % c. If c is NULL, skip the mod. */ +#define MULT(X, Y, result) \ + do { \ + temp = (PyLongObject *)long_mul(X, Y); \ + if (temp == NULL) \ + goto Error; \ + Py_XDECREF(result); \ + result = temp; \ + temp = NULL; \ + REDUCE(result); \ + } while(0) + + if (Py_SIZE(b) <= FIVEARY_CUTOFF) { + /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */ + /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */ + for (i = Py_SIZE(b) - 1; i >= 0; --i) { + digit bi = b->ob_digit[i]; + + for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) { + MULT(z, z, z); + if (bi & j) + MULT(z, a, z); + } + } + } + else { + /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */ + Py_INCREF(z); /* still holds 1L */ + table[0] = z; + for (i = 1; i < 32; ++i) + MULT(table[i-1], a, table[i]); + + for (i = Py_SIZE(b) - 1; i >= 0; --i) { + const digit bi = b->ob_digit[i]; + + for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) { + const int index = (bi >> j) & 0x1f; + for (k = 0; k < 5; ++k) + MULT(z, z, z); + if (index) + MULT(z, table[index], z); + } + } + } + + if (negativeOutput && (Py_SIZE(z) != 0)) { + temp = (PyLongObject *)long_sub(z, c); + if (temp == NULL) + goto Error; + Py_DECREF(z); + z = temp; + temp = NULL; + } + goto Done; + + Error: + Py_CLEAR(z); + /* fall through */ + Done: + if (Py_SIZE(b) > FIVEARY_CUTOFF) { + for (i = 0; i < 32; ++i) + Py_XDECREF(table[i]); + } + Py_DECREF(a); + Py_DECREF(b); + Py_XDECREF(c); + Py_XDECREF(temp); + return (PyObject *)z; +} + +static PyObject * +long_invert(PyLongObject *v) +{ + /* Implement ~x as -(x+1) */ + PyLongObject *x; + if (Py_ABS(Py_SIZE(v)) <=1) + return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); + x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_One); + if (x == NULL) + return NULL; + _PyLong_Negate(&x); + /* No need for maybe_small_long here, since any small + longs will have been caught in the Py_SIZE <= 1 fast path. */ + return (PyObject *)x; +} + +static PyObject * +long_neg(PyLongObject *v) +{ + PyLongObject *z; + if (Py_ABS(Py_SIZE(v)) <= 1) + return PyLong_FromLong(-MEDIUM_VALUE(v)); + z = (PyLongObject *)_PyLong_Copy(v); + if (z != NULL) + Py_SIZE(z) = -(Py_SIZE(v)); + return (PyObject *)z; +} + +static PyObject * +long_abs(PyLongObject *v) +{ + if (Py_SIZE(v) < 0) + return long_neg(v); + else + return long_long((PyObject *)v); +} + +static int +long_bool(PyLongObject *v) +{ + return Py_SIZE(v) != 0; +} + +/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ +static int +divmod_shift(PyObject *shiftby, Py_ssize_t *wordshift, digit *remshift) +{ + assert(PyLong_Check(shiftby)); + assert(Py_SIZE(shiftby) >= 0); + Py_ssize_t lshiftby = PyLong_AsSsize_t((PyObject *)shiftby); + if (lshiftby >= 0) { + *wordshift = lshiftby / PyLong_SHIFT; + *remshift = lshiftby % PyLong_SHIFT; + return 0; + } + /* PyLong_Check(shiftby) is true and Py_SIZE(shiftby) >= 0, so it must + be that PyLong_AsSsize_t raised an OverflowError. */ + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_Clear(); + PyLongObject *wordshift_obj = divrem1((PyLongObject *)shiftby, PyLong_SHIFT, remshift); + if (wordshift_obj == NULL) { + return -1; + } + *wordshift = PyLong_AsSsize_t((PyObject *)wordshift_obj); + Py_DECREF(wordshift_obj); + if (*wordshift >= 0 && *wordshift < PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(digit)) { + return 0; + } + PyErr_Clear(); + /* Clip the value. With such large wordshift the right shift + returns 0 and the left shift raises an error in _PyLong_New(). */ + *wordshift = PY_SSIZE_T_MAX / sizeof(digit); + *remshift = 0; + return 0; +} + +static PyObject * +long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) +{ + PyLongObject *z = NULL; + Py_ssize_t newsize, hishift, i, j; + digit lomask, himask; + + if (Py_SIZE(a) < 0) { + /* Right shifting negative numbers is harder */ + PyLongObject *a1, *a2; + a1 = (PyLongObject *) long_invert(a); + if (a1 == NULL) + return NULL; + a2 = (PyLongObject *) long_rshift1(a1, wordshift, remshift); + Py_DECREF(a1); + if (a2 == NULL) + return NULL; + z = (PyLongObject *) long_invert(a2); + Py_DECREF(a2); + } + else { + newsize = Py_SIZE(a) - wordshift; + if (newsize <= 0) + return PyLong_FromLong(0); + hishift = PyLong_SHIFT - remshift; + lomask = ((digit)1 << hishift) - 1; + himask = PyLong_MASK ^ lomask; + z = _PyLong_New(newsize); + if (z == NULL) + return NULL; + for (i = 0, j = wordshift; i < newsize; i++, j++) { + z->ob_digit[i] = (a->ob_digit[j] >> remshift) & lomask; + if (i+1 < newsize) + z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask; + } + z = maybe_small_long(long_normalize(z)); + } + return (PyObject *)z; +} + +static PyObject * +long_rshift(PyObject *a, PyObject *b) +{ + Py_ssize_t wordshift; + digit remshift; + + CHECK_BINOP(a, b); + + if (Py_SIZE(b) < 0) { + PyErr_SetString(PyExc_ValueError, "negative shift count"); + return NULL; + } + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + if (divmod_shift(b, &wordshift, &remshift) < 0) + return NULL; + return long_rshift1((PyLongObject *)a, wordshift, remshift); +} + +/* Return a >> shiftby. */ +PyObject * +_PyLong_Rshift(PyObject *a, size_t shiftby) +{ + Py_ssize_t wordshift; + digit remshift; + + assert(PyLong_Check(a)); + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + wordshift = shiftby / PyLong_SHIFT; + remshift = shiftby % PyLong_SHIFT; + return long_rshift1((PyLongObject *)a, wordshift, remshift); +} + +static PyObject * +long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) +{ + /* This version due to Tim Peters */ + PyLongObject *z = NULL; + Py_ssize_t oldsize, newsize, i, j; + twodigits accum; + + oldsize = Py_ABS(Py_SIZE(a)); + newsize = oldsize + wordshift; + if (remshift) + ++newsize; + z = _PyLong_New(newsize); + if (z == NULL) + return NULL; + if (Py_SIZE(a) < 0) { + assert(Py_REFCNT(z) == 1); + Py_SIZE(z) = -Py_SIZE(z); + } + for (i = 0; i < wordshift; i++) + z->ob_digit[i] = 0; + accum = 0; + for (i = wordshift, j = 0; j < oldsize; i++, j++) { + accum |= (twodigits)a->ob_digit[j] << remshift; + z->ob_digit[i] = (digit)(accum & PyLong_MASK); + accum >>= PyLong_SHIFT; + } + if (remshift) + z->ob_digit[newsize-1] = (digit)accum; + else + assert(!accum); + z = long_normalize(z); + return (PyObject *) maybe_small_long(z); +} + +static PyObject * +long_lshift(PyObject *a, PyObject *b) +{ + Py_ssize_t wordshift; + digit remshift; + + CHECK_BINOP(a, b); + + if (Py_SIZE(b) < 0) { + PyErr_SetString(PyExc_ValueError, "negative shift count"); + return NULL; + } + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + if (divmod_shift(b, &wordshift, &remshift) < 0) + return NULL; + return long_lshift1((PyLongObject *)a, wordshift, remshift); +} + +/* Return a << shiftby. */ +PyObject * +_PyLong_Lshift(PyObject *a, size_t shiftby) +{ + Py_ssize_t wordshift; + digit remshift; + + assert(PyLong_Check(a)); + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + wordshift = shiftby / PyLong_SHIFT; + remshift = shiftby % PyLong_SHIFT; + return long_lshift1((PyLongObject *)a, wordshift, remshift); +} + +/* Compute two's complement of digit vector a[0:m], writing result to + z[0:m]. The digit vector a need not be normalized, but should not + be entirely zero. a and z may point to the same digit vector. */ + +static void +v_complement(digit *z, digit *a, Py_ssize_t m) +{ + Py_ssize_t i; + digit carry = 1; + for (i = 0; i < m; ++i) { + carry += a[i] ^ PyLong_MASK; + z[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + assert(carry == 0); +} + +/* Bitwise and/xor/or operations */ + +static PyObject * +long_bitwise(PyLongObject *a, + char op, /* '&', '|', '^' */ + PyLongObject *b) +{ + int nega, negb, negz; + Py_ssize_t size_a, size_b, size_z, i; + PyLongObject *z; + + /* Bitwise operations for negative numbers operate as though + on a two's complement representation. So convert arguments + from sign-magnitude to two's complement, and convert the + result back to sign-magnitude at the end. */ + + /* If a is negative, replace it by its two's complement. */ + size_a = Py_ABS(Py_SIZE(a)); + nega = Py_SIZE(a) < 0; + if (nega) { + z = _PyLong_New(size_a); + if (z == NULL) + return NULL; + v_complement(z->ob_digit, a->ob_digit, size_a); + a = z; + } + else + /* Keep reference count consistent. */ + Py_INCREF(a); + + /* Same for b. */ + size_b = Py_ABS(Py_SIZE(b)); + negb = Py_SIZE(b) < 0; + if (negb) { + z = _PyLong_New(size_b); + if (z == NULL) { + Py_DECREF(a); + return NULL; + } + v_complement(z->ob_digit, b->ob_digit, size_b); + b = z; + } + else + Py_INCREF(b); + + /* Swap a and b if necessary to ensure size_a >= size_b. */ + if (size_a < size_b) { + z = a; a = b; b = z; + size_z = size_a; size_a = size_b; size_b = size_z; + negz = nega; nega = negb; negb = negz; + } + + /* JRH: The original logic here was to allocate the result value (z) + as the longer of the two operands. However, there are some cases + where the result is guaranteed to be shorter than that: AND of two + positives, OR of two negatives: use the shorter number. AND with + mixed signs: use the positive number. OR with mixed signs: use the + negative number. + */ + switch (op) { + case '^': + negz = nega ^ negb; + size_z = size_a; + break; + case '&': + negz = nega & negb; + size_z = negb ? size_a : size_b; + break; + case '|': + negz = nega | negb; + size_z = negb ? size_b : size_a; + break; + default: + Py_UNREACHABLE(); + } + + /* We allow an extra digit if z is negative, to make sure that + the final two's complement of z doesn't overflow. */ + z = _PyLong_New(size_z + negz); + if (z == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + + /* Compute digits for overlap of a and b. */ + switch(op) { + case '&': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; + break; + case '|': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; + break; + case '^': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; + break; + default: + Py_UNREACHABLE(); + } + + /* Copy any remaining digits of a, inverting if necessary. */ + if (op == '^' && negb) + for (; i < size_z; ++i) + z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; + else if (i < size_z) + memcpy(&z->ob_digit[i], &a->ob_digit[i], + (size_z-i)*sizeof(digit)); + + /* Complement result if negative. */ + if (negz) { + Py_SIZE(z) = -(Py_SIZE(z)); + z->ob_digit[size_z] = PyLong_MASK; + v_complement(z->ob_digit, z->ob_digit, size_z+1); + } + + Py_DECREF(a); + Py_DECREF(b); + return (PyObject *)maybe_small_long(long_normalize(z)); +} + +static PyObject * +long_and(PyObject *a, PyObject *b) +{ + PyObject *c; + CHECK_BINOP(a, b); + c = long_bitwise((PyLongObject*)a, '&', (PyLongObject*)b); + return c; +} + +static PyObject * +long_xor(PyObject *a, PyObject *b) +{ + PyObject *c; + CHECK_BINOP(a, b); + c = long_bitwise((PyLongObject*)a, '^', (PyLongObject*)b); + return c; +} + +static PyObject * +long_or(PyObject *a, PyObject *b) +{ + PyObject *c; + CHECK_BINOP(a, b); + c = long_bitwise((PyLongObject*)a, '|', (PyLongObject*)b); + return c; +} + +static PyObject * +long_long(PyObject *v) +{ + if (PyLong_CheckExact(v)) + Py_INCREF(v); + else + v = _PyLong_Copy((PyLongObject *)v); + return v; +} + +PyObject * +_PyLong_GCD(PyObject *aarg, PyObject *barg) +{ + PyLongObject *a, *b, *c = NULL, *d = NULL, *r; + stwodigits x, y, q, s, t, c_carry, d_carry; + stwodigits A, B, C, D, T; + int nbits, k; + Py_ssize_t size_a, size_b, alloc_a, alloc_b; + digit *a_digit, *b_digit, *c_digit, *d_digit, *a_end, *b_end; + + a = (PyLongObject *)aarg; + b = (PyLongObject *)barg; + size_a = Py_SIZE(a); + size_b = Py_SIZE(b); + if (-2 <= size_a && size_a <= 2 && -2 <= size_b && size_b <= 2) { + Py_INCREF(a); + Py_INCREF(b); + goto simple; + } + + /* Initial reduction: make sure that 0 <= b <= a. */ + a = (PyLongObject *)long_abs(a); + if (a == NULL) + return NULL; + b = (PyLongObject *)long_abs(b); + if (b == NULL) { + Py_DECREF(a); + return NULL; + } + if (long_compare(a, b) < 0) { + r = a; + a = b; + b = r; + } + /* We now own references to a and b */ + + alloc_a = Py_SIZE(a); + alloc_b = Py_SIZE(b); + /* reduce until a fits into 2 digits */ + while ((size_a = Py_SIZE(a)) > 2) { + nbits = bits_in_digit(a->ob_digit[size_a-1]); + /* extract top 2*PyLong_SHIFT bits of a into x, along with + corresponding bits of b into y */ + size_b = Py_SIZE(b); + assert(size_b <= size_a); + if (size_b == 0) { + if (size_a < alloc_a) { + r = (PyLongObject *)_PyLong_Copy(a); + Py_DECREF(a); + } + else + r = a; + Py_DECREF(b); + Py_XDECREF(c); + Py_XDECREF(d); + return (PyObject *)r; + } + x = (((twodigits)a->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) | + ((twodigits)a->ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) | + (a->ob_digit[size_a-3] >> nbits)); + + y = ((size_b >= size_a - 2 ? b->ob_digit[size_a-3] >> nbits : 0) | + (size_b >= size_a - 1 ? (twodigits)b->ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) | + (size_b >= size_a ? (twodigits)b->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0)); + + /* inner loop of Lehmer's algorithm; A, B, C, D never grow + larger than PyLong_MASK during the algorithm. */ + A = 1; B = 0; C = 0; D = 1; + for (k=0;; k++) { + if (y-C == 0) + break; + q = (x+(A-1))/(y-C); + s = B+q*D; + t = x-q*y; + if (s > t) + break; + x = y; y = t; + t = A+q*C; A = D; B = C; C = s; D = t; + } + + if (k == 0) { + /* no progress; do a Euclidean step */ + if (l_divmod(a, b, NULL, &r) < 0) + goto error; + Py_DECREF(a); + a = b; + b = r; + alloc_a = alloc_b; + alloc_b = Py_SIZE(b); + continue; + } + + /* + a, b = A*b-B*a, D*a-C*b if k is odd + a, b = A*a-B*b, D*b-C*a if k is even + */ + if (k&1) { + T = -A; A = -B; B = T; + T = -C; C = -D; D = T; + } + if (c != NULL) + Py_SIZE(c) = size_a; + else if (Py_REFCNT(a) == 1) { + Py_INCREF(a); + c = a; + } + else { + alloc_a = size_a; + c = _PyLong_New(size_a); + if (c == NULL) + goto error; + } + + if (d != NULL) + Py_SIZE(d) = size_a; + else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) { + Py_INCREF(b); + d = b; + Py_SIZE(d) = size_a; + } + else { + alloc_b = size_a; + d = _PyLong_New(size_a); + if (d == NULL) + goto error; + } + a_end = a->ob_digit + size_a; + b_end = b->ob_digit + size_b; + + /* compute new a and new b in parallel */ + a_digit = a->ob_digit; + b_digit = b->ob_digit; + c_digit = c->ob_digit; + d_digit = d->ob_digit; + c_carry = 0; + d_carry = 0; + while (b_digit < b_end) { + c_carry += (A * *a_digit) - (B * *b_digit); + d_carry += (D * *b_digit++) - (C * *a_digit++); + *c_digit++ = (digit)(c_carry & PyLong_MASK); + *d_digit++ = (digit)(d_carry & PyLong_MASK); + c_carry >>= PyLong_SHIFT; + d_carry >>= PyLong_SHIFT; + } + while (a_digit < a_end) { + c_carry += A * *a_digit; + d_carry -= C * *a_digit++; + *c_digit++ = (digit)(c_carry & PyLong_MASK); + *d_digit++ = (digit)(d_carry & PyLong_MASK); + c_carry >>= PyLong_SHIFT; + d_carry >>= PyLong_SHIFT; + } + assert(c_carry == 0); + assert(d_carry == 0); + + Py_INCREF(c); + Py_INCREF(d); + Py_DECREF(a); + Py_DECREF(b); + a = long_normalize(c); + b = long_normalize(d); + } + Py_XDECREF(c); + Py_XDECREF(d); + +simple: + assert(Py_REFCNT(a) > 0); + assert(Py_REFCNT(b) > 0); +/* Issue #24999: use two shifts instead of ">> 2*PyLong_SHIFT" to avoid + undefined behaviour when LONG_MAX type is smaller than 60 bits */ +#if LONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT + /* a fits into a long, so b must too */ + x = PyLong_AsLong((PyObject *)a); + y = PyLong_AsLong((PyObject *)b); +#elif PY_LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT + x = PyLong_AsLongLong((PyObject *)a); + y = PyLong_AsLongLong((PyObject *)b); +#else +# error "_PyLong_GCD" +#endif + x = Py_ABS(x); + y = Py_ABS(y); + Py_DECREF(a); + Py_DECREF(b); + + /* usual Euclidean algorithm for longs */ + while (y != 0) { + t = y; + y = x % y; + x = t; + } +#if LONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT + return PyLong_FromLong(x); +#elif PY_LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT + return PyLong_FromLongLong(x); +#else +# error "_PyLong_GCD" +#endif + +error: + Py_DECREF(a); + Py_DECREF(b); + Py_XDECREF(c); + Py_XDECREF(d); + return NULL; +} + +static PyObject * +long_float(PyObject *v) +{ + double result; + result = PyLong_AsDouble(v); + if (result == -1.0 && PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble(result); +} + +static PyObject * +long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase); + +/*[clinic input] +@classmethod +int.__new__ as long_new + x: object(c_default="NULL") = 0 + / + base as obase: object(c_default="NULL") = 10 +[clinic start generated code]*/ + +static PyObject * +long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase) +/*[clinic end generated code: output=e47cfe777ab0f24c input=81c98f418af9eb6f]*/ +{ + Py_ssize_t base; + + if (type != &PyLong_Type) + return long_subtype_new(type, x, obase); /* Wimp out */ + if (x == NULL) { + if (obase != NULL) { + PyErr_SetString(PyExc_TypeError, + "int() missing string argument"); + return NULL; + } + return PyLong_FromLong(0L); + } + if (obase == NULL) + return PyNumber_Long(x); + + base = PyNumber_AsSsize_t(obase, NULL); + if (base == -1 && PyErr_Occurred()) + return NULL; + if ((base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() base must be >= 2 and <= 36, or 0"); + return NULL; + } + + if (PyUnicode_Check(x)) + return PyLong_FromUnicodeObject(x, (int)base); + else if (PyByteArray_Check(x) || PyBytes_Check(x)) { + char *string; + if (PyByteArray_Check(x)) + string = PyByteArray_AS_STRING(x); + else + string = PyBytes_AS_STRING(x); + return _PyLong_FromBytes(string, Py_SIZE(x), (int)base); + } + else { + PyErr_SetString(PyExc_TypeError, + "int() can't convert non-string with explicit base"); + return NULL; + } +} + +/* Wimpy, slow approach to tp_new calls for subtypes of int: + first create a regular int from whatever arguments we got, + then allocate a subtype instance and initialize it from + the regular int. The regular int is then thrown away. +*/ +static PyObject * +long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) +{ + PyLongObject *tmp, *newobj; + Py_ssize_t i, n; + + assert(PyType_IsSubtype(type, &PyLong_Type)); + tmp = (PyLongObject *)long_new_impl(&PyLong_Type, x, obase); + if (tmp == NULL) + return NULL; + assert(PyLong_Check(tmp)); + n = Py_SIZE(tmp); + if (n < 0) + n = -n; + newobj = (PyLongObject *)type->tp_alloc(type, n); + if (newobj == NULL) { + Py_DECREF(tmp); + return NULL; + } + assert(PyLong_Check(newobj)); + Py_SIZE(newobj) = Py_SIZE(tmp); + for (i = 0; i < n; i++) + newobj->ob_digit[i] = tmp->ob_digit[i]; + Py_DECREF(tmp); + return (PyObject *)newobj; +} + +/*[clinic input] +int.__getnewargs__ +[clinic start generated code]*/ + +static PyObject * +int___getnewargs___impl(PyObject *self) +/*[clinic end generated code: output=839a49de3f00b61b input=5904770ab1fb8c75]*/ +{ + return Py_BuildValue("(N)", _PyLong_Copy((PyLongObject *)self)); +} + +static PyObject * +long_get0(PyObject *Py_UNUSED(self), void *Py_UNUSED(context)) +{ + return PyLong_FromLong(0L); +} + +static PyObject * +long_get1(PyObject *Py_UNUSED(self), void *Py_UNUSED(ignored)) +{ + return PyLong_FromLong(1L); +} + +/*[clinic input] +int.__format__ + + format_spec: unicode + / +[clinic start generated code]*/ + +static PyObject * +int___format___impl(PyObject *self, PyObject *format_spec) +/*[clinic end generated code: output=b4929dee9ae18689 input=e31944a9b3e428b7]*/ +{ + _PyUnicodeWriter writer; + int ret; + + _PyUnicodeWriter_Init(&writer); + ret = _PyLong_FormatAdvancedWriter( + &writer, + self, + format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); + if (ret == -1) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + return _PyUnicodeWriter_Finish(&writer); +} + +/* Return a pair (q, r) such that a = b * q + r, and + abs(r) <= abs(b)/2, with equality possible only if q is even. + In other words, q == a / b, rounded to the nearest integer using + round-half-to-even. */ + +PyObject * +_PyLong_DivmodNear(PyObject *a, PyObject *b) +{ + PyLongObject *quo = NULL, *rem = NULL; + PyObject *twice_rem, *result, *temp; + int cmp, quo_is_odd, quo_is_neg; + + /* Equivalent Python code: + + def divmod_near(a, b): + q, r = divmod(a, b) + # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. + # The expression r / b > 0.5 is equivalent to 2 * r > b if b is + # positive, 2 * r < b if b negative. + greater_than_half = 2*r > b if b > 0 else 2*r < b + exactly_half = 2*r == b + if greater_than_half or exactly_half and q % 2 == 1: + q += 1 + r -= b + return q, r + + */ + if (!PyLong_Check(a) || !PyLong_Check(b)) { + PyErr_SetString(PyExc_TypeError, + "non-integer arguments in division"); + return NULL; + } + + /* Do a and b have different signs? If so, quotient is negative. */ + quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0); + + if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0) + goto error; + + /* compare twice the remainder with the divisor, to see + if we need to adjust the quotient and remainder */ + twice_rem = long_lshift((PyObject *)rem, _PyLong_One); + if (twice_rem == NULL) + goto error; + if (quo_is_neg) { + temp = long_neg((PyLongObject*)twice_rem); + Py_DECREF(twice_rem); + twice_rem = temp; + if (twice_rem == NULL) + goto error; + } + cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); + Py_DECREF(twice_rem); + + quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); + if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { + /* fix up quotient */ + if (quo_is_neg) + temp = long_sub(quo, (PyLongObject *)_PyLong_One); + else + temp = long_add(quo, (PyLongObject *)_PyLong_One); + Py_DECREF(quo); + quo = (PyLongObject *)temp; + if (quo == NULL) + goto error; + /* and remainder */ + if (quo_is_neg) + temp = long_add(rem, (PyLongObject *)b); + else + temp = long_sub(rem, (PyLongObject *)b); + Py_DECREF(rem); + rem = (PyLongObject *)temp; + if (rem == NULL) + goto error; + } + + result = PyTuple_New(2); + if (result == NULL) + goto error; + + /* PyTuple_SET_ITEM steals references */ + PyTuple_SET_ITEM(result, 0, (PyObject *)quo); + PyTuple_SET_ITEM(result, 1, (PyObject *)rem); + return result; + + error: + Py_XDECREF(quo); + Py_XDECREF(rem); + return NULL; +} + +static PyObject * +long_round(PyObject *self, PyObject *args) +{ + PyObject *o_ndigits=NULL, *temp, *result, *ndigits; + + /* To round an integer m to the nearest 10**n (n positive), we make use of + * the divmod_near operation, defined by: + * + * divmod_near(a, b) = (q, r) + * + * where q is the nearest integer to the quotient a / b (the + * nearest even integer in the case of a tie) and r == a - q * b. + * Hence q * b = a - r is the nearest multiple of b to a, + * preferring even multiples in the case of a tie. + * + * So the nearest multiple of 10**n to m is: + * + * m - divmod_near(m, 10**n)[1]. + */ + if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) + return NULL; + if (o_ndigits == NULL) + return long_long(self); + + ndigits = PyNumber_Index(o_ndigits); + if (ndigits == NULL) + return NULL; + + /* if ndigits >= 0 then no rounding is necessary; return self unchanged */ + if (Py_SIZE(ndigits) >= 0) { + Py_DECREF(ndigits); + return long_long(self); + } + + /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ + temp = long_neg((PyLongObject*)ndigits); + Py_DECREF(ndigits); + ndigits = temp; + if (ndigits == NULL) + return NULL; + + result = PyLong_FromLong(10L); + if (result == NULL) { + Py_DECREF(ndigits); + return NULL; + } + + temp = long_pow(result, ndigits, Py_None); + Py_DECREF(ndigits); + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; + + temp = _PyLong_DivmodNear(self, result); + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; + + temp = long_sub((PyLongObject *)self, + (PyLongObject *)PyTuple_GET_ITEM(result, 1)); + Py_DECREF(result); + result = temp; + + return result; +} + +/*[clinic input] +int.__sizeof__ -> Py_ssize_t + +Returns size in memory, in bytes. +[clinic start generated code]*/ + +static Py_ssize_t +int___sizeof___impl(PyObject *self) +/*[clinic end generated code: output=3303f008eaa6a0a5 input=9b51620c76fc4507]*/ +{ + Py_ssize_t res; + + res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(self))*sizeof(digit); + return res; +} + +/*[clinic input] +int.bit_length + +Number of bits necessary to represent self in binary. + +>>> bin(37) +'0b100101' +>>> (37).bit_length() +6 +[clinic start generated code]*/ + +static PyObject * +int_bit_length_impl(PyObject *self) +/*[clinic end generated code: output=fc1977c9353d6a59 input=e4eb7a587e849a32]*/ +{ + PyLongObject *result, *x, *y; + Py_ssize_t ndigits; + int msd_bits; + digit msd; + + assert(self != NULL); + assert(PyLong_Check(self)); + + ndigits = Py_ABS(Py_SIZE(self)); + if (ndigits == 0) + return PyLong_FromLong(0); + + msd = ((PyLongObject *)self)->ob_digit[ndigits-1]; + msd_bits = bits_in_digit(msd); + + if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) + return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits); + + /* expression above may overflow; use Python integers instead */ + result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1); + if (result == NULL) + return NULL; + x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT); + if (x == NULL) + goto error; + y = (PyLongObject *)long_mul(result, x); + Py_DECREF(x); + if (y == NULL) + goto error; + Py_DECREF(result); + result = y; + + x = (PyLongObject *)PyLong_FromLong((long)msd_bits); + if (x == NULL) + goto error; + y = (PyLongObject *)long_add(result, x); + Py_DECREF(x); + if (y == NULL) + goto error; + Py_DECREF(result); + result = y; + + return (PyObject *)result; + + error: + Py_DECREF(result); + return NULL; +} + + +/*[clinic input] +int.as_integer_ratio + +Return integer ratio. + +Return a pair of integers, whose ratio is exactly equal to the original int +and with a positive denominator. + +>>> (10).as_integer_ratio() +(10, 1) +>>> (-10).as_integer_ratio() +(-10, 1) +>>> (0).as_integer_ratio() +(0, 1) +[clinic start generated code]*/ + +static PyObject * +int_as_integer_ratio_impl(PyObject *self) +/*[clinic end generated code: output=e60803ae1cc8621a input=55ce3058e15de393]*/ +{ + PyObject *ratio_tuple; + PyObject *numerator = long_long(self); + if (numerator == NULL) { + return NULL; + } + ratio_tuple = PyTuple_Pack(2, numerator, _PyLong_One); + Py_DECREF(numerator); + return ratio_tuple; +} + +/*[clinic input] +int.to_bytes + + length: Py_ssize_t + Length of bytes object to use. An OverflowError is raised if the + integer is not representable with the given number of bytes. + byteorder: unicode + The byte order used to represent the integer. If byteorder is 'big', + the most significant byte is at the beginning of the byte array. If + byteorder is 'little', the most significant byte is at the end of the + byte array. To request the native byte order of the host system, use + `sys.byteorder' as the byte order value. + * + signed as is_signed: bool = False + Determines whether two's complement is used to represent the integer. + If signed is False and a negative integer is given, an OverflowError + is raised. + +Return an array of bytes representing an integer. +[clinic start generated code]*/ + +static PyObject * +int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder, + int is_signed) +/*[clinic end generated code: output=89c801df114050a3 input=ddac63f4c7bf414c]*/ +{ + int little_endian; + PyObject *bytes; + + if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little)) + little_endian = 1; + else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_big)) + little_endian = 0; + else { + PyErr_SetString(PyExc_ValueError, + "byteorder must be either 'little' or 'big'"); + return NULL; + } + + if (length < 0) { + PyErr_SetString(PyExc_ValueError, + "length argument must be non-negative"); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(NULL, length); + if (bytes == NULL) + return NULL; + + if (_PyLong_AsByteArray((PyLongObject *)self, + (unsigned char *)PyBytes_AS_STRING(bytes), + length, little_endian, is_signed) < 0) { + Py_DECREF(bytes); + return NULL; + } + + return bytes; +} + +/*[clinic input] +@classmethod +int.from_bytes + + bytes as bytes_obj: object + Holds the array of bytes to convert. The argument must either + support the buffer protocol or be an iterable object producing bytes. + Bytes and bytearray are examples of built-in objects that support the + buffer protocol. + byteorder: unicode + The byte order used to represent the integer. If byteorder is 'big', + the most significant byte is at the beginning of the byte array. If + byteorder is 'little', the most significant byte is at the end of the + byte array. To request the native byte order of the host system, use + `sys.byteorder' as the byte order value. + * + signed as is_signed: bool = False + Indicates whether two's complement is used to represent the integer. + +Return the integer represented by the given array of bytes. +[clinic start generated code]*/ + +static PyObject * +int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj, + PyObject *byteorder, int is_signed) +/*[clinic end generated code: output=efc5d68e31f9314f input=cdf98332b6a821b0]*/ +{ + int little_endian; + PyObject *long_obj, *bytes; + + if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little)) + little_endian = 1; + else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_big)) + little_endian = 0; + else { + PyErr_SetString(PyExc_ValueError, + "byteorder must be either 'little' or 'big'"); + return NULL; + } + + bytes = PyObject_Bytes(bytes_obj); + if (bytes == NULL) + return NULL; + + long_obj = _PyLong_FromByteArray( + (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes), + little_endian, is_signed); + Py_DECREF(bytes); + + if (long_obj != NULL && type != &PyLong_Type) { + Py_SETREF(long_obj, PyObject_CallFunctionObjArgs((PyObject *)type, + long_obj, NULL)); + } + + return long_obj; +} + +static PyObject * +long_long_meth(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return long_long(self); +} + +static PyMethodDef long_methods[] = { + {"conjugate", long_long_meth, METH_NOARGS, + "Returns self, the complex conjugate of any int."}, + INT_BIT_LENGTH_METHODDEF + INT_TO_BYTES_METHODDEF + INT_FROM_BYTES_METHODDEF + INT_AS_INTEGER_RATIO_METHODDEF + {"__trunc__", long_long_meth, METH_NOARGS, + "Truncating an Integral returns itself."}, + {"__floor__", long_long_meth, METH_NOARGS, + "Flooring an Integral returns itself."}, + {"__ceil__", long_long_meth, METH_NOARGS, + "Ceiling of an Integral returns itself."}, + {"__round__", (PyCFunction)long_round, METH_VARARGS, + "Rounding an Integral returns itself.\n" + "Rounding with an ndigits argument also returns an integer."}, + INT___GETNEWARGS___METHODDEF + INT___FORMAT___METHODDEF + INT___SIZEOF___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyGetSetDef long_getset[] = { + {"real", + (getter)long_long_meth, (setter)NULL, + "the real part of a complex number", + NULL}, + {"imag", + long_get0, (setter)NULL, + "the imaginary part of a complex number", + NULL}, + {"numerator", + (getter)long_long_meth, (setter)NULL, + "the numerator of a rational number in lowest terms", + NULL}, + {"denominator", + long_get1, (setter)NULL, + "the denominator of a rational number in lowest terms", + NULL}, + {NULL} /* Sentinel */ +}; + +PyDoc_STRVAR(long_doc, +"int([x]) -> integer\n\ +int(x, base=10) -> integer\n\ +\n\ +Convert a number or string to an integer, or return 0 if no arguments\n\ +are given. If x is a number, return x.__int__(). For floating point\n\ +numbers, this truncates towards zero.\n\ +\n\ +If x is not a number or if base is given, then x must be a string,\n\ +bytes, or bytearray instance representing an integer literal in the\n\ +given base. The literal can be preceded by '+' or '-' and be surrounded\n\ +by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\n\ +Base 0 means to interpret the base from the string as an integer literal.\n\ +>>> int('0b100', base=0)\n\ +4"); + +static PyNumberMethods long_as_number = { + (binaryfunc)long_add, /*nb_add*/ + (binaryfunc)long_sub, /*nb_subtract*/ + (binaryfunc)long_mul, /*nb_multiply*/ + long_mod, /*nb_remainder*/ + long_divmod, /*nb_divmod*/ + long_pow, /*nb_power*/ + (unaryfunc)long_neg, /*nb_negative*/ + long_long, /*tp_positive*/ + (unaryfunc)long_abs, /*tp_absolute*/ + (inquiry)long_bool, /*tp_bool*/ + (unaryfunc)long_invert, /*nb_invert*/ + long_lshift, /*nb_lshift*/ + long_rshift, /*nb_rshift*/ + long_and, /*nb_and*/ + long_xor, /*nb_xor*/ + long_or, /*nb_or*/ + long_long, /*nb_int*/ + 0, /*nb_reserved*/ + long_float, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + long_div, /* nb_floor_divide */ + long_true_divide, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + long_long, /* nb_index */ +}; + +PyTypeObject PyLong_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "int", /* tp_name */ + offsetof(PyLongObject, ob_digit), /* tp_basicsize */ + sizeof(digit), /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + long_to_decimal_string, /* tp_repr */ + &long_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)long_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ + long_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + long_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + long_methods, /* tp_methods */ + 0, /* tp_members */ + long_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + long_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + +static PyTypeObject Int_InfoType; + +PyDoc_STRVAR(int_info__doc__, +"sys.int_info\n\ +\n\ +A named tuple that holds information about Python's\n\ +internal representation of integers. The attributes are read only."); + +static PyStructSequence_Field int_info_fields[] = { + {"bits_per_digit", "size of a digit in bits"}, + {"sizeof_digit", "size in bytes of the C type used to represent a digit"}, + {NULL, NULL} +}; + +static PyStructSequence_Desc int_info_desc = { + "sys.int_info", /* name */ + int_info__doc__, /* doc */ + int_info_fields, /* fields */ + 2 /* number of fields */ +}; + +PyObject * +PyLong_GetInfo(void) +{ + PyObject* int_info; + int field = 0; + int_info = PyStructSequence_New(&Int_InfoType); + if (int_info == NULL) + return NULL; + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(PyLong_SHIFT)); + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(sizeof(digit))); + if (PyErr_Occurred()) { + Py_CLEAR(int_info); + return NULL; + } + return int_info; +} + +int +_PyLong_Init(void) +{ +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 + int ival, size; + PyLongObject *v = small_ints; + + for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { + size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); + if (Py_TYPE(v) == &PyLong_Type) { + /* The element is already initialized, most likely + * the Python interpreter was initialized before. + */ + Py_ssize_t refcnt; + PyObject* op = (PyObject*)v; + + refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op); + _Py_NewReference(op); + /* _Py_NewReference sets the ref count to 1 but + * the ref count might be larger. Set the refcnt + * to the original refcnt + 1 */ + Py_REFCNT(op) = refcnt + 1; + assert(Py_SIZE(op) == size); + assert(v->ob_digit[0] == (digit)abs(ival)); + } + else { + (void)PyObject_INIT(v, &PyLong_Type); + } + Py_SIZE(v) = size; + v->ob_digit[0] = (digit)abs(ival); + } +#endif + _PyLong_Zero = PyLong_FromLong(0); + if (_PyLong_Zero == NULL) + return 0; + _PyLong_One = PyLong_FromLong(1); + if (_PyLong_One == NULL) + return 0; + + /* initialize int_info */ + if (Int_InfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { + return 0; + } + } + + return 1; +} + +void +PyLong_Fini(void) +{ + /* Integers are currently statically allocated. Py_DECREF is not + needed, but Python must forget about the reference or multiple + reinitializations will fail. */ + Py_CLEAR(_PyLong_One); + Py_CLEAR(_PyLong_Zero); +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 + int i; + PyLongObject *v = small_ints; + for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { + _Py_DEC_REFTOTAL; + _Py_ForgetReference((PyObject*)v); + } +#endif +} diff --git a/python/Objects/memoryobject.c b/python/Objects/memoryobject.c new file mode 100755 index 0000000..0bbcbb2 --- /dev/null +++ b/python/Objects/memoryobject.c @@ -0,0 +1,3201 @@ +/* + * Memoryview object implementation + * -------------------------------- + * + * This implementation is a complete rewrite contributed by Stefan Krah in + * Python 3.3. Substantial credit goes to Antoine Pitrou (who had already + * fortified and rewritten the previous implementation) and Nick Coghlan + * (who came up with the idea of the ManagedBuffer) for analyzing the complex + * ownership rules. + * + */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "pystrhex.h" +#include + +/*[clinic input] +class memoryview "PyMemoryViewObject *" "&PyMemoryView_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e2e49d2192835219]*/ + +#include "clinic/memoryobject.c.h" + +/****************************************************************************/ +/* ManagedBuffer Object */ +/****************************************************************************/ + +/* + ManagedBuffer Object: + --------------------- + + The purpose of this object is to facilitate the handling of chained + memoryviews that have the same underlying exporting object. PEP-3118 + allows the underlying object to change while a view is exported. This + could lead to unexpected results when constructing a new memoryview + from an existing memoryview. + + Rather than repeatedly redirecting buffer requests to the original base + object, all chained memoryviews use a single buffer snapshot. This + snapshot is generated by the constructor _PyManagedBuffer_FromObject(). + + Ownership rules: + ---------------- + + The master buffer inside a managed buffer is filled in by the original + base object. shape, strides, suboffsets and format are read-only for + all consumers. + + A memoryview's buffer is a private copy of the exporter's buffer. shape, + strides and suboffsets belong to the memoryview and are thus writable. + + If a memoryview itself exports several buffers via memory_getbuf(), all + buffer copies share shape, strides and suboffsets. In this case, the + arrays are NOT writable. + + Reference count assumptions: + ---------------------------- + + The 'obj' member of a Py_buffer must either be NULL or refer to the + exporting base object. In the Python codebase, all getbufferprocs + return a new reference to view.obj (example: bytes_buffer_getbuffer()). + + PyBuffer_Release() decrements view.obj (if non-NULL), so the + releasebufferprocs must NOT decrement view.obj. +*/ + + +#define CHECK_MBUF_RELEASED(mbuf) \ + if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \ + PyErr_SetString(PyExc_ValueError, \ + "operation forbidden on released memoryview object"); \ + return NULL; \ + } + + +static inline _PyManagedBufferObject * +mbuf_alloc(void) +{ + _PyManagedBufferObject *mbuf; + + mbuf = (_PyManagedBufferObject *) + PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type); + if (mbuf == NULL) + return NULL; + mbuf->flags = 0; + mbuf->exports = 0; + mbuf->master.obj = NULL; + _PyObject_GC_TRACK(mbuf); + + return mbuf; +} + +static PyObject * +_PyManagedBuffer_FromObject(PyObject *base) +{ + _PyManagedBufferObject *mbuf; + + mbuf = mbuf_alloc(); + if (mbuf == NULL) + return NULL; + + if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) { + mbuf->master.obj = NULL; + Py_DECREF(mbuf); + return NULL; + } + + return (PyObject *)mbuf; +} + +static void +mbuf_release(_PyManagedBufferObject *self) +{ + if (self->flags&_Py_MANAGED_BUFFER_RELEASED) + return; + + /* NOTE: at this point self->exports can still be > 0 if this function + is called from mbuf_clear() to break up a reference cycle. */ + self->flags |= _Py_MANAGED_BUFFER_RELEASED; + + /* PyBuffer_Release() decrements master->obj and sets it to NULL. */ + _PyObject_GC_UNTRACK(self); + PyBuffer_Release(&self->master); +} + +static void +mbuf_dealloc(_PyManagedBufferObject *self) +{ + assert(self->exports == 0); + mbuf_release(self); + if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT) + PyMem_Free(self->master.format); + PyObject_GC_Del(self); +} + +static int +mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->master.obj); + return 0; +} + +static int +mbuf_clear(_PyManagedBufferObject *self) +{ + assert(self->exports >= 0); + mbuf_release(self); + return 0; +} + +PyTypeObject _PyManagedBuffer_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "managedbuffer", + sizeof(_PyManagedBufferObject), + 0, + (destructor)mbuf_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, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)mbuf_traverse, /* tp_traverse */ + (inquiry)mbuf_clear /* tp_clear */ +}; + + +/****************************************************************************/ +/* MemoryView Object */ +/****************************************************************************/ + +/* In the process of breaking reference cycles mbuf_release() can be + called before memory_release(). */ +#define BASE_INACCESSIBLE(mv) \ + (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \ + ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED) + +#define CHECK_RELEASED(mv) \ + if (BASE_INACCESSIBLE(mv)) { \ + PyErr_SetString(PyExc_ValueError, \ + "operation forbidden on released memoryview object"); \ + return NULL; \ + } + +#define CHECK_RELEASED_INT(mv) \ + if (BASE_INACCESSIBLE(mv)) { \ + PyErr_SetString(PyExc_ValueError, \ + "operation forbidden on released memoryview object"); \ + return -1; \ + } + +#define CHECK_LIST_OR_TUPLE(v) \ + if (!PyList_Check(v) && !PyTuple_Check(v)) { \ + PyErr_SetString(PyExc_TypeError, \ + #v " must be a list or a tuple"); \ + return NULL; \ + } + +#define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view) + +/* Check for the presence of suboffsets in the first dimension. */ +#define HAVE_PTR(suboffsets, dim) (suboffsets && suboffsets[dim] >= 0) +/* Adjust ptr if suboffsets are present. */ +#define ADJUST_PTR(ptr, suboffsets, dim) \ + (HAVE_PTR(suboffsets, dim) ? *((char**)ptr) + suboffsets[dim] : ptr) + +/* Memoryview buffer properties */ +#define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C)) +#define MV_F_CONTIGUOUS(flags) \ + (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN)) +#define MV_ANY_CONTIGUOUS(flags) \ + (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN)) + +/* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */ +#define MV_CONTIGUOUS_NDIM1(view) \ + ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize) + +/* getbuffer() requests */ +#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT) +#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) +#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) +#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS) +#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES) +#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND) +#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE) +#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT) + + +PyDoc_STRVAR(memory_doc, +"memoryview(object)\n--\n\ +\n\ +Create a new memoryview object which references the given object."); + + +/**************************************************************************/ +/* Copy memoryview buffers */ +/**************************************************************************/ + +/* The functions in this section take a source and a destination buffer + with the same logical structure: format, itemsize, ndim and shape + are identical, with ndim > 0. + + NOTE: All buffers are assumed to have PyBUF_FULL information, which + is the case for memoryviews! */ + + +/* Assumptions: ndim >= 1. The macro tests for a corner case that should + perhaps be explicitly forbidden in the PEP. */ +#define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \ + (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0) + +static inline int +last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src) +{ + assert(dest->ndim > 0 && src->ndim > 0); + return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) && + !HAVE_SUBOFFSETS_IN_LAST_DIM(src) && + dest->strides[dest->ndim-1] == dest->itemsize && + src->strides[src->ndim-1] == src->itemsize); +} + +/* This is not a general function for determining format equivalence. + It is used in copy_single() and copy_buffer() to weed out non-matching + formats. Skipping the '@' character is specifically used in slice + assignments, where the lvalue is already known to have a single character + format. This is a performance hack that could be rewritten (if properly + benchmarked). */ +static inline int +equiv_format(const Py_buffer *dest, const Py_buffer *src) +{ + const char *dfmt, *sfmt; + + assert(dest->format && src->format); + dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format; + sfmt = src->format[0] == '@' ? src->format+1 : src->format; + + if (strcmp(dfmt, sfmt) != 0 || + dest->itemsize != src->itemsize) { + return 0; + } + + return 1; +} + +/* Two shapes are equivalent if they are either equal or identical up + to a zero element at the same position. For example, in NumPy arrays + the shapes [1, 0, 5] and [1, 0, 7] are equivalent. */ +static inline int +equiv_shape(const Py_buffer *dest, const Py_buffer *src) +{ + int i; + + if (dest->ndim != src->ndim) + return 0; + + for (i = 0; i < dest->ndim; i++) { + if (dest->shape[i] != src->shape[i]) + return 0; + if (dest->shape[i] == 0) + break; + } + + return 1; +} + +/* Check that the logical structure of the destination and source buffers + is identical. */ +static int +equiv_structure(const Py_buffer *dest, const Py_buffer *src) +{ + if (!equiv_format(dest, src) || + !equiv_shape(dest, src)) { + PyErr_SetString(PyExc_ValueError, + "memoryview assignment: lvalue and rvalue have different " + "structures"); + return 0; + } + + return 1; +} + +/* Base case for recursive multi-dimensional copying. Contiguous arrays are + copied with very little overhead. Assumptions: ndim == 1, mem == NULL or + sizeof(mem) == shape[0] * itemsize. */ +static void +copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize, + char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets, + char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets, + char *mem) +{ + if (mem == NULL) { /* contiguous */ + Py_ssize_t size = shape[0] * itemsize; + if (dptr + size < sptr || sptr + size < dptr) + memcpy(dptr, sptr, size); /* no overlapping */ + else + memmove(dptr, sptr, size); + } + else { + char *p; + Py_ssize_t i; + for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) { + char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0); + memcpy(p, xsptr, itemsize); + } + for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) { + char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0); + memcpy(xdptr, p, itemsize); + } + } + +} + +/* Recursively copy a source buffer to a destination buffer. The two buffers + have the same ndim, shape and itemsize. */ +static void +copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize, + char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets, + char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets, + char *mem) +{ + Py_ssize_t i; + + assert(ndim >= 1); + + if (ndim == 1) { + copy_base(shape, itemsize, + dptr, dstrides, dsuboffsets, + sptr, sstrides, ssuboffsets, + mem); + return; + } + + for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) { + char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0); + char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0); + + copy_rec(shape+1, ndim-1, itemsize, + xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL, + xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL, + mem); + } +} + +/* Faster copying of one-dimensional arrays. */ +static int +copy_single(Py_buffer *dest, Py_buffer *src) +{ + char *mem = NULL; + + assert(dest->ndim == 1); + + if (!equiv_structure(dest, src)) + return -1; + + if (!last_dim_is_contiguous(dest, src)) { + mem = PyMem_Malloc(dest->shape[0] * dest->itemsize); + if (mem == NULL) { + PyErr_NoMemory(); + return -1; + } + } + + copy_base(dest->shape, dest->itemsize, + dest->buf, dest->strides, dest->suboffsets, + src->buf, src->strides, src->suboffsets, + mem); + + if (mem) + PyMem_Free(mem); + + return 0; +} + +/* Recursively copy src to dest. Both buffers must have the same basic + structure. Copying is atomic, the function never fails with a partial + copy. */ +static int +copy_buffer(Py_buffer *dest, Py_buffer *src) +{ + char *mem = NULL; + + assert(dest->ndim > 0); + + if (!equiv_structure(dest, src)) + return -1; + + if (!last_dim_is_contiguous(dest, src)) { + mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize); + if (mem == NULL) { + PyErr_NoMemory(); + return -1; + } + } + + copy_rec(dest->shape, dest->ndim, dest->itemsize, + dest->buf, dest->strides, dest->suboffsets, + src->buf, src->strides, src->suboffsets, + mem); + + if (mem) + PyMem_Free(mem); + + return 0; +} + +/* Initialize strides for a C-contiguous array. */ +static inline void +init_strides_from_shape(Py_buffer *view) +{ + Py_ssize_t i; + + assert(view->ndim > 0); + + view->strides[view->ndim-1] = view->itemsize; + for (i = view->ndim-2; i >= 0; i--) + view->strides[i] = view->strides[i+1] * view->shape[i+1]; +} + +/* Initialize strides for a Fortran-contiguous array. */ +static inline void +init_fortran_strides_from_shape(Py_buffer *view) +{ + Py_ssize_t i; + + assert(view->ndim > 0); + + view->strides[0] = view->itemsize; + for (i = 1; i < view->ndim; i++) + view->strides[i] = view->strides[i-1] * view->shape[i-1]; +} + +/* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran) + or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1, + len(mem) == src->len. */ +static int +buffer_to_contiguous(char *mem, Py_buffer *src, char order) +{ + Py_buffer dest; + Py_ssize_t *strides; + int ret; + + assert(src->ndim >= 1); + assert(src->shape != NULL); + assert(src->strides != NULL); + + strides = PyMem_Malloc(src->ndim * (sizeof *src->strides)); + if (strides == NULL) { + PyErr_NoMemory(); + return -1; + } + + /* initialize dest */ + dest = *src; + dest.buf = mem; + /* shape is constant and shared: the logical representation of the + array is unaltered. */ + + /* The physical representation determined by strides (and possibly + suboffsets) may change. */ + dest.strides = strides; + if (order == 'C' || order == 'A') { + init_strides_from_shape(&dest); + } + else { + init_fortran_strides_from_shape(&dest); + } + + dest.suboffsets = NULL; + + ret = copy_buffer(&dest, src); + + PyMem_Free(strides); + return ret; +} + + +/****************************************************************************/ +/* Constructors */ +/****************************************************************************/ + +/* Initialize values that are shared with the managed buffer. */ +static inline void +init_shared_values(Py_buffer *dest, const Py_buffer *src) +{ + dest->obj = src->obj; + dest->buf = src->buf; + dest->len = src->len; + dest->itemsize = src->itemsize; + dest->readonly = src->readonly; + dest->format = src->format ? src->format : "B"; + dest->internal = src->internal; +} + +/* Copy shape and strides. Reconstruct missing values. */ +static void +init_shape_strides(Py_buffer *dest, const Py_buffer *src) +{ + Py_ssize_t i; + + if (src->ndim == 0) { + dest->shape = NULL; + dest->strides = NULL; + return; + } + if (src->ndim == 1) { + dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize; + dest->strides[0] = src->strides ? src->strides[0] : src->itemsize; + return; + } + + for (i = 0; i < src->ndim; i++) + dest->shape[i] = src->shape[i]; + if (src->strides) { + for (i = 0; i < src->ndim; i++) + dest->strides[i] = src->strides[i]; + } + else { + init_strides_from_shape(dest); + } +} + +static inline void +init_suboffsets(Py_buffer *dest, const Py_buffer *src) +{ + Py_ssize_t i; + + if (src->suboffsets == NULL) { + dest->suboffsets = NULL; + return; + } + for (i = 0; i < src->ndim; i++) + dest->suboffsets[i] = src->suboffsets[i]; +} + +/* len = product(shape) * itemsize */ +static inline void +init_len(Py_buffer *view) +{ + Py_ssize_t i, len; + + len = 1; + for (i = 0; i < view->ndim; i++) + len *= view->shape[i]; + len *= view->itemsize; + + view->len = len; +} + +/* Initialize memoryview buffer properties. */ +static void +init_flags(PyMemoryViewObject *mv) +{ + const Py_buffer *view = &mv->view; + int flags = 0; + + switch (view->ndim) { + case 0: + flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C| + _Py_MEMORYVIEW_FORTRAN); + break; + case 1: + if (MV_CONTIGUOUS_NDIM1(view)) + flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN); + break; + default: + if (PyBuffer_IsContiguous(view, 'C')) + flags |= _Py_MEMORYVIEW_C; + if (PyBuffer_IsContiguous(view, 'F')) + flags |= _Py_MEMORYVIEW_FORTRAN; + break; + } + + if (view->suboffsets) { + flags |= _Py_MEMORYVIEW_PIL; + flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN); + } + + mv->flags = flags; +} + +/* Allocate a new memoryview and perform basic initialization. New memoryviews + are exclusively created through the mbuf_add functions. */ +static inline PyMemoryViewObject * +memory_alloc(int ndim) +{ + PyMemoryViewObject *mv; + + mv = (PyMemoryViewObject *) + PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim); + if (mv == NULL) + return NULL; + + mv->mbuf = NULL; + mv->hash = -1; + mv->flags = 0; + mv->exports = 0; + mv->view.ndim = ndim; + mv->view.shape = mv->ob_array; + mv->view.strides = mv->ob_array + ndim; + mv->view.suboffsets = mv->ob_array + 2 * ndim; + mv->weakreflist = NULL; + + _PyObject_GC_TRACK(mv); + return mv; +} + +/* + Return a new memoryview that is registered with mbuf. If src is NULL, + use mbuf->master as the underlying buffer. Otherwise, use src. + + The new memoryview has full buffer information: shape and strides + are always present, suboffsets as needed. Arrays are copied to + the memoryview's ob_array field. + */ +static PyObject * +mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src) +{ + PyMemoryViewObject *mv; + Py_buffer *dest; + + if (src == NULL) + src = &mbuf->master; + + if (src->ndim > PyBUF_MAX_NDIM) { + PyErr_SetString(PyExc_ValueError, + "memoryview: number of dimensions must not exceed " + Py_STRINGIFY(PyBUF_MAX_NDIM)); + return NULL; + } + + mv = memory_alloc(src->ndim); + if (mv == NULL) + return NULL; + + dest = &mv->view; + init_shared_values(dest, src); + init_shape_strides(dest, src); + init_suboffsets(dest, src); + init_flags(mv); + + mv->mbuf = mbuf; + Py_INCREF(mbuf); + mbuf->exports++; + + return (PyObject *)mv; +} + +/* Register an incomplete view: shape, strides, suboffsets and flags still + need to be initialized. Use 'ndim' instead of src->ndim to determine the + size of the memoryview's ob_array. + + Assumption: ndim <= PyBUF_MAX_NDIM. */ +static PyObject * +mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src, + int ndim) +{ + PyMemoryViewObject *mv; + Py_buffer *dest; + + if (src == NULL) + src = &mbuf->master; + + assert(ndim <= PyBUF_MAX_NDIM); + + mv = memory_alloc(ndim); + if (mv == NULL) + return NULL; + + dest = &mv->view; + init_shared_values(dest, src); + + mv->mbuf = mbuf; + Py_INCREF(mbuf); + mbuf->exports++; + + return (PyObject *)mv; +} + +/* Expose a raw memory area as a view of contiguous bytes. flags can be + PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes). + The memoryview has complete buffer information. */ +PyObject * +PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags) +{ + _PyManagedBufferObject *mbuf; + PyObject *mv; + int readonly; + + assert(mem != NULL); + assert(flags == PyBUF_READ || flags == PyBUF_WRITE); + + mbuf = mbuf_alloc(); + if (mbuf == NULL) + return NULL; + + readonly = (flags == PyBUF_WRITE) ? 0 : 1; + (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly, + PyBUF_FULL_RO); + + mv = mbuf_add_view(mbuf, NULL); + Py_DECREF(mbuf); + + return mv; +} + +/* Create a memoryview from a given Py_buffer. For simple byte views, + PyMemoryView_FromMemory() should be used instead. + This function is the only entry point that can create a master buffer + without full information. Because of this fact init_shape_strides() + must be able to reconstruct missing values. */ +PyObject * +PyMemoryView_FromBuffer(Py_buffer *info) +{ + _PyManagedBufferObject *mbuf; + PyObject *mv; + + if (info->buf == NULL) { + PyErr_SetString(PyExc_ValueError, + "PyMemoryView_FromBuffer(): info->buf must not be NULL"); + return NULL; + } + + mbuf = mbuf_alloc(); + if (mbuf == NULL) + return NULL; + + /* info->obj is either NULL or a borrowed reference. This reference + should not be decremented in PyBuffer_Release(). */ + mbuf->master = *info; + mbuf->master.obj = NULL; + + mv = mbuf_add_view(mbuf, NULL); + Py_DECREF(mbuf); + + return mv; +} + +/* Create a memoryview from an object that implements the buffer protocol. + If the object is a memoryview, the new memoryview must be registered + with the same managed buffer. Otherwise, a new managed buffer is created. */ +PyObject * +PyMemoryView_FromObject(PyObject *v) +{ + _PyManagedBufferObject *mbuf; + + if (PyMemoryView_Check(v)) { + PyMemoryViewObject *mv = (PyMemoryViewObject *)v; + CHECK_RELEASED(mv); + return mbuf_add_view(mv->mbuf, &mv->view); + } + else if (PyObject_CheckBuffer(v)) { + PyObject *ret; + mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v); + if (mbuf == NULL) + return NULL; + ret = mbuf_add_view(mbuf, NULL); + Py_DECREF(mbuf); + return ret; + } + + PyErr_Format(PyExc_TypeError, + "memoryview: a bytes-like object is required, not '%.200s'", + Py_TYPE(v)->tp_name); + return NULL; +} + +/* Copy the format string from a base object that might vanish. */ +static int +mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt) +{ + if (fmt != NULL) { + char *cp = PyMem_Malloc(strlen(fmt)+1); + if (cp == NULL) { + PyErr_NoMemory(); + return -1; + } + mbuf->master.format = strcpy(cp, fmt); + mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT; + } + + return 0; +} + +/* + Return a memoryview that is based on a contiguous copy of src. + Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0. + + Ownership rules: + 1) As usual, the returned memoryview has a private copy + of src->shape, src->strides and src->suboffsets. + 2) src->format is copied to the master buffer and released + in mbuf_dealloc(). The releasebufferproc of the bytes + object is NULL, so it does not matter that mbuf_release() + passes the altered format pointer to PyBuffer_Release(). +*/ +static PyObject * +memory_from_contiguous_copy(Py_buffer *src, char order) +{ + _PyManagedBufferObject *mbuf; + PyMemoryViewObject *mv; + PyObject *bytes; + Py_buffer *dest; + int i; + + assert(src->ndim > 0); + assert(src->shape != NULL); + + bytes = PyBytes_FromStringAndSize(NULL, src->len); + if (bytes == NULL) + return NULL; + + mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes); + Py_DECREF(bytes); + if (mbuf == NULL) + return NULL; + + if (mbuf_copy_format(mbuf, src->format) < 0) { + Py_DECREF(mbuf); + return NULL; + } + + mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim); + Py_DECREF(mbuf); + if (mv == NULL) + return NULL; + + dest = &mv->view; + + /* shared values are initialized correctly except for itemsize */ + dest->itemsize = src->itemsize; + + /* shape and strides */ + for (i = 0; i < src->ndim; i++) { + dest->shape[i] = src->shape[i]; + } + if (order == 'C' || order == 'A') { + init_strides_from_shape(dest); + } + else { + init_fortran_strides_from_shape(dest); + } + /* suboffsets */ + dest->suboffsets = NULL; + + /* flags */ + init_flags(mv); + + if (copy_buffer(dest, src) < 0) { + Py_DECREF(mv); + return NULL; + } + + return (PyObject *)mv; +} + +/* + Return a new memoryview object based on a contiguous exporter with + buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}. + The logical structure of the input and output buffers is the same + (i.e. tolist(input) == tolist(output)), but the physical layout in + memory can be explicitly chosen. + + As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable, + otherwise it may be writable or read-only. + + If the exporter is already contiguous with the desired target order, + the memoryview will be directly based on the exporter. + + Otherwise, if the buffertype is PyBUF_READ, the memoryview will be + based on a new bytes object. If order={'C', 'A'ny}, use 'C' order, + 'F'ortran order otherwise. +*/ +PyObject * +PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order) +{ + PyMemoryViewObject *mv; + PyObject *ret; + Py_buffer *view; + + assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE); + assert(order == 'C' || order == 'F' || order == 'A'); + + mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj); + if (mv == NULL) + return NULL; + + view = &mv->view; + if (buffertype == PyBUF_WRITE && view->readonly) { + PyErr_SetString(PyExc_BufferError, + "underlying buffer is not writable"); + Py_DECREF(mv); + return NULL; + } + + if (PyBuffer_IsContiguous(view, order)) + return (PyObject *)mv; + + if (buffertype == PyBUF_WRITE) { + PyErr_SetString(PyExc_BufferError, + "writable contiguous buffer requested " + "for a non-contiguous object."); + Py_DECREF(mv); + return NULL; + } + + ret = memory_from_contiguous_copy(view, order); + Py_DECREF(mv); + return ret; +} + + +static PyObject * +memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + static char *kwlist[] = {"object", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist, + &obj)) { + return NULL; + } + + return PyMemoryView_FromObject(obj); +} + + +/****************************************************************************/ +/* Previously in abstract.c */ +/****************************************************************************/ + +typedef struct { + Py_buffer view; + Py_ssize_t array[1]; +} Py_buffer_full; + +int +PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order) +{ + Py_buffer_full *fb = NULL; + int ret; + + assert(order == 'C' || order == 'F' || order == 'A'); + + if (len != src->len) { + PyErr_SetString(PyExc_ValueError, + "PyBuffer_ToContiguous: len != view->len"); + return -1; + } + + if (PyBuffer_IsContiguous(src, order)) { + memcpy((char *)buf, src->buf, len); + return 0; + } + + /* buffer_to_contiguous() assumes PyBUF_FULL */ + fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array)); + if (fb == NULL) { + PyErr_NoMemory(); + return -1; + } + fb->view.ndim = src->ndim; + fb->view.shape = fb->array; + fb->view.strides = fb->array + src->ndim; + fb->view.suboffsets = fb->array + 2 * src->ndim; + + init_shared_values(&fb->view, src); + init_shape_strides(&fb->view, src); + init_suboffsets(&fb->view, src); + + src = &fb->view; + + ret = buffer_to_contiguous(buf, src, order); + PyMem_Free(fb); + return ret; +} + + +/****************************************************************************/ +/* Release/GC management */ +/****************************************************************************/ + +/* Inform the managed buffer that this particular memoryview will not access + the underlying buffer again. If no other memoryviews are registered with + the managed buffer, the underlying buffer is released instantly and + marked as inaccessible for both the memoryview and the managed buffer. + + This function fails if the memoryview itself has exported buffers. */ +static int +_memory_release(PyMemoryViewObject *self) +{ + if (self->flags & _Py_MEMORYVIEW_RELEASED) + return 0; + + if (self->exports == 0) { + self->flags |= _Py_MEMORYVIEW_RELEASED; + assert(self->mbuf->exports > 0); + if (--self->mbuf->exports == 0) + mbuf_release(self->mbuf); + return 0; + } + if (self->exports > 0) { + PyErr_Format(PyExc_BufferError, + "memoryview has %zd exported buffer%s", self->exports, + self->exports==1 ? "" : "s"); + return -1; + } + + Py_FatalError("_memory_release(): negative export count"); + return -1; +} + +static PyObject * +memory_release(PyMemoryViewObject *self, PyObject *noargs) +{ + if (_memory_release(self) < 0) + return NULL; + Py_RETURN_NONE; +} + +static void +memory_dealloc(PyMemoryViewObject *self) +{ + assert(self->exports == 0); + _PyObject_GC_UNTRACK(self); + (void)_memory_release(self); + Py_CLEAR(self->mbuf); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + PyObject_GC_Del(self); +} + +static int +memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->mbuf); + return 0; +} + +static int +memory_clear(PyMemoryViewObject *self) +{ + (void)_memory_release(self); + Py_CLEAR(self->mbuf); + return 0; +} + +static PyObject * +memory_enter(PyObject *self, PyObject *args) +{ + CHECK_RELEASED(self); + Py_INCREF(self); + return self; +} + +static PyObject * +memory_exit(PyObject *self, PyObject *args) +{ + return memory_release((PyMemoryViewObject *)self, NULL); +} + + +/****************************************************************************/ +/* Casting format and shape */ +/****************************************************************************/ + +#define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c') + +static inline Py_ssize_t +get_native_fmtchar(char *result, const char *fmt) +{ + Py_ssize_t size = -1; + + if (fmt[0] == '@') fmt++; + + switch (fmt[0]) { + case 'c': case 'b': case 'B': size = sizeof(char); break; + case 'h': case 'H': size = sizeof(short); break; + case 'i': case 'I': size = sizeof(int); break; + case 'l': case 'L': size = sizeof(long); break; + case 'q': case 'Q': size = sizeof(long long); break; + case 'n': case 'N': size = sizeof(Py_ssize_t); break; + case 'f': size = sizeof(float); break; + case 'd': size = sizeof(double); break; + case '?': size = sizeof(_Bool); break; + case 'P': size = sizeof(void *); break; + } + + if (size > 0 && fmt[1] == '\0') { + *result = fmt[0]; + return size; + } + + return -1; +} + +static inline const char * +get_native_fmtstr(const char *fmt) +{ + int at = 0; + + if (fmt[0] == '@') { + at = 1; + fmt++; + } + if (fmt[0] == '\0' || fmt[1] != '\0') { + return NULL; + } + +#define RETURN(s) do { return at ? "@" s : s; } while (0) + + switch (fmt[0]) { + case 'c': RETURN("c"); + case 'b': RETURN("b"); + case 'B': RETURN("B"); + case 'h': RETURN("h"); + case 'H': RETURN("H"); + case 'i': RETURN("i"); + case 'I': RETURN("I"); + case 'l': RETURN("l"); + case 'L': RETURN("L"); + case 'q': RETURN("q"); + case 'Q': RETURN("Q"); + case 'n': RETURN("n"); + case 'N': RETURN("N"); + case 'f': RETURN("f"); + case 'd': RETURN("d"); + case '?': RETURN("?"); + case 'P': RETURN("P"); + } + + return NULL; +} + + +/* Cast a memoryview's data type to 'format'. The input array must be + C-contiguous. At least one of input-format, output-format must have + byte size. The output array is 1-D, with the same byte length as the + input array. Thus, view->len must be a multiple of the new itemsize. */ +static int +cast_to_1D(PyMemoryViewObject *mv, PyObject *format) +{ + Py_buffer *view = &mv->view; + PyObject *asciifmt; + char srcchar, destchar; + Py_ssize_t itemsize; + int ret = -1; + + assert(view->ndim >= 1); + assert(Py_SIZE(mv) == 3*view->ndim); + assert(view->shape == mv->ob_array); + assert(view->strides == mv->ob_array + view->ndim); + assert(view->suboffsets == mv->ob_array + 2*view->ndim); + + asciifmt = PyUnicode_AsASCIIString(format); + if (asciifmt == NULL) + return ret; + + itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt)); + if (itemsize < 0) { + PyErr_SetString(PyExc_ValueError, + "memoryview: destination format must be a native single " + "character format prefixed with an optional '@'"); + goto out; + } + + if ((get_native_fmtchar(&srcchar, view->format) < 0 || + !IS_BYTE_FORMAT(srcchar)) && !IS_BYTE_FORMAT(destchar)) { + PyErr_SetString(PyExc_TypeError, + "memoryview: cannot cast between two non-byte formats"); + goto out; + } + if (view->len % itemsize) { + PyErr_SetString(PyExc_TypeError, + "memoryview: length is not a multiple of itemsize"); + goto out; + } + + view->format = (char *)get_native_fmtstr(PyBytes_AS_STRING(asciifmt)); + if (view->format == NULL) { + /* NOT_REACHED: get_native_fmtchar() already validates the format. */ + PyErr_SetString(PyExc_RuntimeError, + "memoryview: internal error"); + goto out; + } + view->itemsize = itemsize; + + view->ndim = 1; + view->shape[0] = view->len / view->itemsize; + view->strides[0] = view->itemsize; + view->suboffsets = NULL; + + init_flags(mv); + + ret = 0; + +out: + Py_DECREF(asciifmt); + return ret; +} + +/* The memoryview must have space for 3*len(seq) elements. */ +static Py_ssize_t +copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim, + Py_ssize_t itemsize) +{ + Py_ssize_t x, i; + Py_ssize_t len = itemsize; + + for (i = 0; i < ndim; i++) { + PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i); + if (!PyLong_Check(tmp)) { + PyErr_SetString(PyExc_TypeError, + "memoryview.cast(): elements of shape must be integers"); + return -1; + } + x = PyLong_AsSsize_t(tmp); + if (x == -1 && PyErr_Occurred()) { + return -1; + } + if (x <= 0) { + /* In general elements of shape may be 0, but not for casting. */ + PyErr_Format(PyExc_ValueError, + "memoryview.cast(): elements of shape must be integers > 0"); + return -1; + } + if (x > PY_SSIZE_T_MAX / len) { + PyErr_Format(PyExc_ValueError, + "memoryview.cast(): product(shape) > SSIZE_MAX"); + return -1; + } + len *= x; + shape[i] = x; + } + + return len; +} + +/* Cast a 1-D array to a new shape. The result array will be C-contiguous. + If the result array does not have exactly the same byte length as the + input array, raise ValueError. */ +static int +cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim) +{ + Py_buffer *view = &mv->view; + Py_ssize_t len; + + assert(view->ndim == 1); /* ndim from cast_to_1D() */ + assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */ + assert(view->shape == mv->ob_array); + assert(view->strides == mv->ob_array + (ndim==0?1:ndim)); + assert(view->suboffsets == NULL); + + view->ndim = ndim; + if (view->ndim == 0) { + view->shape = NULL; + view->strides = NULL; + len = view->itemsize; + } + else { + len = copy_shape(view->shape, shape, ndim, view->itemsize); + if (len < 0) + return -1; + init_strides_from_shape(view); + } + + if (view->len != len) { + PyErr_SetString(PyExc_TypeError, + "memoryview: product(shape) * itemsize != buffer size"); + return -1; + } + + init_flags(mv); + + return 0; +} + +static int +zero_in_shape(PyMemoryViewObject *mv) +{ + Py_buffer *view = &mv->view; + Py_ssize_t i; + + for (i = 0; i < view->ndim; i++) + if (view->shape[i] == 0) + return 1; + + return 0; +} + +/* + Cast a copy of 'self' to a different view. The input view must + be C-contiguous. The function always casts the input view to a + 1-D output according to 'format'. At least one of input-format, + output-format must have byte size. + + If 'shape' is given, the 1-D view from the previous step will + be cast to a C-contiguous view with new shape and strides. + + All casts must result in views that will have the exact byte + size of the original input. Otherwise, an error is raised. +*/ +static PyObject * +memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"format", "shape", NULL}; + PyMemoryViewObject *mv = NULL; + PyObject *shape = NULL; + PyObject *format; + Py_ssize_t ndim = 1; + + CHECK_RELEASED(self); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, + &format, &shape)) { + return NULL; + } + if (!PyUnicode_Check(format)) { + PyErr_SetString(PyExc_TypeError, + "memoryview: format argument must be a string"); + return NULL; + } + if (!MV_C_CONTIGUOUS(self->flags)) { + PyErr_SetString(PyExc_TypeError, + "memoryview: casts are restricted to C-contiguous views"); + return NULL; + } + if ((shape || self->view.ndim != 1) && zero_in_shape(self)) { + PyErr_SetString(PyExc_TypeError, + "memoryview: cannot cast view with zeros in shape or strides"); + return NULL; + } + if (shape) { + CHECK_LIST_OR_TUPLE(shape) + ndim = PySequence_Fast_GET_SIZE(shape); + if (ndim > PyBUF_MAX_NDIM) { + PyErr_SetString(PyExc_ValueError, + "memoryview: number of dimensions must not exceed " + Py_STRINGIFY(PyBUF_MAX_NDIM)); + return NULL; + } + if (self->view.ndim != 1 && ndim != 1) { + PyErr_SetString(PyExc_TypeError, + "memoryview: cast must be 1D -> ND or ND -> 1D"); + return NULL; + } + } + + mv = (PyMemoryViewObject *) + mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim); + if (mv == NULL) + return NULL; + + if (cast_to_1D(mv, format) < 0) + goto error; + if (shape && cast_to_ND(mv, shape, (int)ndim) < 0) + goto error; + + return (PyObject *)mv; + +error: + Py_DECREF(mv); + return NULL; +} + +static PyObject * +memory_toreadonly(PyMemoryViewObject *self, PyObject *noargs) +{ + CHECK_RELEASED(self); + /* Even if self is already readonly, we still need to create a new + * object for .release() to work correctly. + */ + self = (PyMemoryViewObject *) mbuf_add_view(self->mbuf, &self->view); + if (self != NULL) { + self->view.readonly = 1; + }; + return (PyObject *) self; +} + + +/**************************************************************************/ +/* getbuffer */ +/**************************************************************************/ + +static int +memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) +{ + Py_buffer *base = &self->view; + int baseflags = self->flags; + + CHECK_RELEASED_INT(self); + + /* start with complete information */ + *view = *base; + view->obj = NULL; + + if (REQ_WRITABLE(flags) && base->readonly) { + PyErr_SetString(PyExc_BufferError, + "memoryview: underlying buffer is not writable"); + return -1; + } + if (!REQ_FORMAT(flags)) { + /* NULL indicates that the buffer's data type has been cast to 'B'. + view->itemsize is the _previous_ itemsize. If shape is present, + the equality product(shape) * itemsize = len still holds at this + point. The equality calcsize(format) = itemsize does _not_ hold + from here on! */ + view->format = NULL; + } + + if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "memoryview: underlying buffer is not C-contiguous"); + return -1; + } + if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "memoryview: underlying buffer is not Fortran contiguous"); + return -1; + } + if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "memoryview: underlying buffer is not contiguous"); + return -1; + } + if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) { + PyErr_SetString(PyExc_BufferError, + "memoryview: underlying buffer requires suboffsets"); + return -1; + } + if (!REQ_STRIDES(flags)) { + if (!MV_C_CONTIGUOUS(baseflags)) { + PyErr_SetString(PyExc_BufferError, + "memoryview: underlying buffer is not C-contiguous"); + return -1; + } + view->strides = NULL; + } + if (!REQ_SHAPE(flags)) { + /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous, + so base->buf = ndbuf->data. */ + if (view->format != NULL) { + /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do + not make sense. */ + PyErr_Format(PyExc_BufferError, + "memoryview: cannot cast to unsigned bytes if the format flag " + "is present"); + return -1; + } + /* product(shape) * itemsize = len and calcsize(format) = itemsize + do _not_ hold from here on! */ + view->ndim = 1; + view->shape = NULL; + } + + + view->obj = (PyObject *)self; + Py_INCREF(view->obj); + self->exports++; + + return 0; +} + +static void +memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) +{ + self->exports--; + return; + /* PyBuffer_Release() decrements view->obj after this function returns. */ +} + +/* Buffer methods */ +static PyBufferProcs memory_as_buffer = { + (getbufferproc)memory_getbuf, /* bf_getbuffer */ + (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */ +}; + + +/****************************************************************************/ +/* Optimized pack/unpack for all native format specifiers */ +/****************************************************************************/ + +/* + Fix exceptions: + 1) Include format string in the error message. + 2) OverflowError -> ValueError. + 3) The error message from PyNumber_Index() is not ideal. +*/ +static int +type_error_int(const char *fmt) +{ + PyErr_Format(PyExc_TypeError, + "memoryview: invalid type for format '%s'", fmt); + return -1; +} + +static int +value_error_int(const char *fmt) +{ + PyErr_Format(PyExc_ValueError, + "memoryview: invalid value for format '%s'", fmt); + return -1; +} + +static int +fix_error_int(const char *fmt) +{ + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + return type_error_int(fmt); + } + else if (PyErr_ExceptionMatches(PyExc_OverflowError) || + PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + return value_error_int(fmt); + } + + return -1; +} + +/* Accept integer objects or objects with an __index__() method. */ +static long +pylong_as_ld(PyObject *item) +{ + PyObject *tmp; + long ld; + + tmp = PyNumber_Index(item); + if (tmp == NULL) + return -1; + + ld = PyLong_AsLong(tmp); + Py_DECREF(tmp); + return ld; +} + +static unsigned long +pylong_as_lu(PyObject *item) +{ + PyObject *tmp; + unsigned long lu; + + tmp = PyNumber_Index(item); + if (tmp == NULL) + return (unsigned long)-1; + + lu = PyLong_AsUnsignedLong(tmp); + Py_DECREF(tmp); + return lu; +} + +static long long +pylong_as_lld(PyObject *item) +{ + PyObject *tmp; + long long lld; + + tmp = PyNumber_Index(item); + if (tmp == NULL) + return -1; + + lld = PyLong_AsLongLong(tmp); + Py_DECREF(tmp); + return lld; +} + +static unsigned long long +pylong_as_llu(PyObject *item) +{ + PyObject *tmp; + unsigned long long llu; + + tmp = PyNumber_Index(item); + if (tmp == NULL) + return (unsigned long long)-1; + + llu = PyLong_AsUnsignedLongLong(tmp); + Py_DECREF(tmp); + return llu; +} + +static Py_ssize_t +pylong_as_zd(PyObject *item) +{ + PyObject *tmp; + Py_ssize_t zd; + + tmp = PyNumber_Index(item); + if (tmp == NULL) + return -1; + + zd = PyLong_AsSsize_t(tmp); + Py_DECREF(tmp); + return zd; +} + +static size_t +pylong_as_zu(PyObject *item) +{ + PyObject *tmp; + size_t zu; + + tmp = PyNumber_Index(item); + if (tmp == NULL) + return (size_t)-1; + + zu = PyLong_AsSize_t(tmp); + Py_DECREF(tmp); + return zu; +} + +/* Timings with the ndarray from _testbuffer.c indicate that using the + struct module is around 15x slower than the two functions below. */ + +#define UNPACK_SINGLE(dest, ptr, type) \ + do { \ + type x; \ + memcpy((char *)&x, ptr, sizeof x); \ + dest = x; \ + } while (0) + +/* Unpack a single item. 'fmt' can be any native format character in struct + module syntax. This function is very sensitive to small changes. With this + layout gcc automatically generates a fast jump table. */ +static inline PyObject * +unpack_single(const char *ptr, const char *fmt) +{ + unsigned long long llu; + unsigned long lu; + size_t zu; + long long lld; + long ld; + Py_ssize_t zd; + double d; + unsigned char uc; + void *p; + + switch (fmt[0]) { + + /* signed integers and fast path for 'B' */ + case 'B': uc = *((const unsigned char *)ptr); goto convert_uc; + case 'b': ld = *((const signed char *)ptr); goto convert_ld; + case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld; + case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld; + case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld; + + /* boolean */ + case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool; + + /* unsigned integers */ + case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu; + case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu; + case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu; + + /* native 64-bit */ + case 'q': UNPACK_SINGLE(lld, ptr, long long); goto convert_lld; + case 'Q': UNPACK_SINGLE(llu, ptr, unsigned long long); goto convert_llu; + + /* ssize_t and size_t */ + case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd; + case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu; + + /* floats */ + case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double; + case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double; + + /* bytes object */ + case 'c': goto convert_bytes; + + /* pointer */ + case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer; + + /* default */ + default: goto err_format; + } + +convert_uc: + /* PyLong_FromUnsignedLong() is slower */ + return PyLong_FromLong(uc); +convert_ld: + return PyLong_FromLong(ld); +convert_lu: + return PyLong_FromUnsignedLong(lu); +convert_lld: + return PyLong_FromLongLong(lld); +convert_llu: + return PyLong_FromUnsignedLongLong(llu); +convert_zd: + return PyLong_FromSsize_t(zd); +convert_zu: + return PyLong_FromSize_t(zu); +convert_double: + return PyFloat_FromDouble(d); +convert_bool: + return PyBool_FromLong(ld); +convert_bytes: + return PyBytes_FromStringAndSize(ptr, 1); +convert_pointer: + return PyLong_FromVoidPtr(p); +err_format: + PyErr_Format(PyExc_NotImplementedError, + "memoryview: format %s not supported", fmt); + return NULL; +} + +#define PACK_SINGLE(ptr, src, type) \ + do { \ + type x; \ + x = (type)src; \ + memcpy(ptr, (char *)&x, sizeof x); \ + } while (0) + +/* Pack a single item. 'fmt' can be any native format character in + struct module syntax. */ +static int +pack_single(char *ptr, PyObject *item, const char *fmt) +{ + unsigned long long llu; + unsigned long lu; + size_t zu; + long long lld; + long ld; + Py_ssize_t zd; + double d; + void *p; + + switch (fmt[0]) { + /* signed integers */ + case 'b': case 'h': case 'i': case 'l': + ld = pylong_as_ld(item); + if (ld == -1 && PyErr_Occurred()) + goto err_occurred; + switch (fmt[0]) { + case 'b': + if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range; + *((signed char *)ptr) = (signed char)ld; break; + case 'h': + if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range; + PACK_SINGLE(ptr, ld, short); break; + case 'i': + if (ld < INT_MIN || ld > INT_MAX) goto err_range; + PACK_SINGLE(ptr, ld, int); break; + default: /* 'l' */ + PACK_SINGLE(ptr, ld, long); break; + } + break; + + /* unsigned integers */ + case 'B': case 'H': case 'I': case 'L': + lu = pylong_as_lu(item); + if (lu == (unsigned long)-1 && PyErr_Occurred()) + goto err_occurred; + switch (fmt[0]) { + case 'B': + if (lu > UCHAR_MAX) goto err_range; + *((unsigned char *)ptr) = (unsigned char)lu; break; + case 'H': + if (lu > USHRT_MAX) goto err_range; + PACK_SINGLE(ptr, lu, unsigned short); break; + case 'I': + if (lu > UINT_MAX) goto err_range; + PACK_SINGLE(ptr, lu, unsigned int); break; + default: /* 'L' */ + PACK_SINGLE(ptr, lu, unsigned long); break; + } + break; + + /* native 64-bit */ + case 'q': + lld = pylong_as_lld(item); + if (lld == -1 && PyErr_Occurred()) + goto err_occurred; + PACK_SINGLE(ptr, lld, long long); + break; + case 'Q': + llu = pylong_as_llu(item); + if (llu == (unsigned long long)-1 && PyErr_Occurred()) + goto err_occurred; + PACK_SINGLE(ptr, llu, unsigned long long); + break; + + /* ssize_t and size_t */ + case 'n': + zd = pylong_as_zd(item); + if (zd == -1 && PyErr_Occurred()) + goto err_occurred; + PACK_SINGLE(ptr, zd, Py_ssize_t); + break; + case 'N': + zu = pylong_as_zu(item); + if (zu == (size_t)-1 && PyErr_Occurred()) + goto err_occurred; + PACK_SINGLE(ptr, zu, size_t); + break; + + /* floats */ + case 'f': case 'd': + d = PyFloat_AsDouble(item); + if (d == -1.0 && PyErr_Occurred()) + goto err_occurred; + if (fmt[0] == 'f') { + PACK_SINGLE(ptr, d, float); + } + else { + PACK_SINGLE(ptr, d, double); + } + break; + + /* bool */ + case '?': + ld = PyObject_IsTrue(item); + if (ld < 0) + return -1; /* preserve original error */ + PACK_SINGLE(ptr, ld, _Bool); + break; + + /* bytes object */ + case 'c': + if (!PyBytes_Check(item)) + return type_error_int(fmt); + if (PyBytes_GET_SIZE(item) != 1) + return value_error_int(fmt); + *ptr = PyBytes_AS_STRING(item)[0]; + break; + + /* pointer */ + case 'P': + p = PyLong_AsVoidPtr(item); + if (p == NULL && PyErr_Occurred()) + goto err_occurred; + PACK_SINGLE(ptr, p, void *); + break; + + /* default */ + default: goto err_format; + } + + return 0; + +err_occurred: + return fix_error_int(fmt); +err_range: + return value_error_int(fmt); +err_format: + PyErr_Format(PyExc_NotImplementedError, + "memoryview: format %s not supported", fmt); + return -1; +} + + +/****************************************************************************/ +/* unpack using the struct module */ +/****************************************************************************/ + +/* For reasonable performance it is necessary to cache all objects required + for unpacking. An unpacker can handle the format passed to unpack_from(). + Invariant: All pointer fields of the struct should either be NULL or valid + pointers. */ +struct unpacker { + PyObject *unpack_from; /* Struct.unpack_from(format) */ + PyObject *mview; /* cached memoryview */ + char *item; /* buffer for mview */ + Py_ssize_t itemsize; /* len(item) */ +}; + +static struct unpacker * +unpacker_new(void) +{ + struct unpacker *x = PyMem_Malloc(sizeof *x); + + if (x == NULL) { + PyErr_NoMemory(); + return NULL; + } + + x->unpack_from = NULL; + x->mview = NULL; + x->item = NULL; + x->itemsize = 0; + + return x; +} + +static void +unpacker_free(struct unpacker *x) +{ + if (x) { + Py_XDECREF(x->unpack_from); + Py_XDECREF(x->mview); + PyMem_Free(x->item); + PyMem_Free(x); + } +} + +/* Return a new unpacker for the given format. */ +static struct unpacker * +struct_get_unpacker(const char *fmt, Py_ssize_t itemsize) +{ + PyObject *structmodule; /* XXX cache these two */ + PyObject *Struct = NULL; /* XXX in globals? */ + PyObject *structobj = NULL; + PyObject *format = NULL; + struct unpacker *x = NULL; + + structmodule = PyImport_ImportModule("struct"); + if (structmodule == NULL) + return NULL; + + Struct = PyObject_GetAttrString(structmodule, "Struct"); + Py_DECREF(structmodule); + if (Struct == NULL) + return NULL; + + x = unpacker_new(); + if (x == NULL) + goto error; + + format = PyBytes_FromString(fmt); + if (format == NULL) + goto error; + + structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL); + if (structobj == NULL) + goto error; + + x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from"); + if (x->unpack_from == NULL) + goto error; + + x->item = PyMem_Malloc(itemsize); + if (x->item == NULL) { + PyErr_NoMemory(); + goto error; + } + x->itemsize = itemsize; + + x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE); + if (x->mview == NULL) + goto error; + + +out: + Py_XDECREF(Struct); + Py_XDECREF(format); + Py_XDECREF(structobj); + return x; + +error: + unpacker_free(x); + x = NULL; + goto out; +} + +/* unpack a single item */ +static PyObject * +struct_unpack_single(const char *ptr, struct unpacker *x) +{ + PyObject *v; + + memcpy(x->item, ptr, x->itemsize); + v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL); + if (v == NULL) + return NULL; + + if (PyTuple_GET_SIZE(v) == 1) { + PyObject *tmp = PyTuple_GET_ITEM(v, 0); + Py_INCREF(tmp); + Py_DECREF(v); + return tmp; + } + + return v; +} + + +/****************************************************************************/ +/* Representations */ +/****************************************************************************/ + +/* allow explicit form of native format */ +static inline const char * +adjust_fmt(const Py_buffer *view) +{ + const char *fmt; + + fmt = (view->format[0] == '@') ? view->format+1 : view->format; + if (fmt[0] && fmt[1] == '\0') + return fmt; + + PyErr_Format(PyExc_NotImplementedError, + "memoryview: unsupported format %s", view->format); + return NULL; +} + +/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */ +static PyObject * +tolist_base(const char *ptr, const Py_ssize_t *shape, + const Py_ssize_t *strides, const Py_ssize_t *suboffsets, + const char *fmt) +{ + PyObject *lst, *item; + Py_ssize_t i; + + lst = PyList_New(shape[0]); + if (lst == NULL) + return NULL; + + for (i = 0; i < shape[0]; ptr+=strides[0], i++) { + const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); + item = unpack_single(xptr, fmt); + if (item == NULL) { + Py_DECREF(lst); + return NULL; + } + PyList_SET_ITEM(lst, i, item); + } + + return lst; +} + +/* Unpack a multi-dimensional array into a nested list. + Assumption: ndim >= 1. */ +static PyObject * +tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, + const Py_ssize_t *strides, const Py_ssize_t *suboffsets, + const char *fmt) +{ + PyObject *lst, *item; + Py_ssize_t i; + + assert(ndim >= 1); + assert(shape != NULL); + assert(strides != NULL); + + if (ndim == 1) + return tolist_base(ptr, shape, strides, suboffsets, fmt); + + lst = PyList_New(shape[0]); + if (lst == NULL) + return NULL; + + for (i = 0; i < shape[0]; ptr+=strides[0], i++) { + const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); + item = tolist_rec(xptr, ndim-1, shape+1, + strides+1, suboffsets ? suboffsets+1 : NULL, + fmt); + if (item == NULL) { + Py_DECREF(lst); + return NULL; + } + PyList_SET_ITEM(lst, i, item); + } + + return lst; +} + +/* Return a list representation of the memoryview. Currently only buffers + with native format strings are supported. */ +static PyObject * +memory_tolist(PyMemoryViewObject *mv, PyObject *noargs) +{ + const Py_buffer *view = &(mv->view); + const char *fmt; + + CHECK_RELEASED(mv); + + fmt = adjust_fmt(view); + if (fmt == NULL) + return NULL; + if (view->ndim == 0) { + return unpack_single(view->buf, fmt); + } + else if (view->ndim == 1) { + return tolist_base(view->buf, view->shape, + view->strides, view->suboffsets, + fmt); + } + else { + return tolist_rec(view->buf, view->ndim, view->shape, + view->strides, view->suboffsets, + fmt); + } +} + +static PyObject * +memory_tobytes(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"order", NULL}; + Py_buffer *src = VIEW_ADDR(self); + char *order = NULL; + char ord = 'C'; + PyObject *bytes; + + CHECK_RELEASED(self); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|z", kwlist, &order)) { + return NULL; + } + + if (order) { + if (strcmp(order, "F") == 0) { + ord = 'F'; + } + else if (strcmp(order, "A") == 0) { + ord = 'A'; + } + else if (strcmp(order, "C") != 0) { + PyErr_SetString(PyExc_ValueError, + "order must be 'C', 'F' or 'A'"); + return NULL; + } + } + + bytes = PyBytes_FromStringAndSize(NULL, src->len); + if (bytes == NULL) + return NULL; + + if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, ord) < 0) { + Py_DECREF(bytes); + return NULL; + } + + return bytes; +} + +/*[clinic input] +memoryview.hex + + 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. + +Return the data in the buffer as a str of hexadecimal numbers. + +Example: +>>> value = memoryview(b'\xb9\x01\xef') +>>> value.hex() +'b901ef' +>>> value.hex(':') +'b9:01:ef' +>>> value.hex(':', 2) +'b9:01ef' +>>> value.hex(':', -2) +'b901:ef' +[clinic start generated code]*/ + +static PyObject * +memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep, + int bytes_per_sep) +/*[clinic end generated code: output=430ca760f94f3ca7 input=539f6a3a5fb56946]*/ +{ + Py_buffer *src = VIEW_ADDR(self); + PyObject *bytes; + PyObject *ret; + + CHECK_RELEASED(self); + + if (MV_C_CONTIGUOUS(self->flags)) { + return _Py_strhex_with_sep(src->buf, src->len, sep, bytes_per_sep); + } + + bytes = PyBytes_FromStringAndSize(NULL, src->len); + if (bytes == NULL) + return NULL; + + if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, 'C') < 0) { + Py_DECREF(bytes); + return NULL; + } + + ret = _Py_strhex_with_sep( + PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes), + sep, bytes_per_sep); + Py_DECREF(bytes); + + return ret; +} + +static PyObject * +memory_repr(PyMemoryViewObject *self) +{ + if (self->flags & _Py_MEMORYVIEW_RELEASED) + return PyUnicode_FromFormat("", self); + else + return PyUnicode_FromFormat("", self); +} + + +/**************************************************************************/ +/* Indexing and slicing */ +/**************************************************************************/ + +static char * +lookup_dimension(Py_buffer *view, char *ptr, int dim, Py_ssize_t index) +{ + Py_ssize_t nitems; /* items in the given dimension */ + + assert(view->shape); + assert(view->strides); + + nitems = view->shape[dim]; + if (index < 0) { + index += nitems; + } + if (index < 0 || index >= nitems) { + PyErr_Format(PyExc_IndexError, + "index out of bounds on dimension %d", dim + 1); + return NULL; + } + + ptr += view->strides[dim] * index; + + ptr = ADJUST_PTR(ptr, view->suboffsets, dim); + + return ptr; +} + +/* Get the pointer to the item at index. */ +static char * +ptr_from_index(Py_buffer *view, Py_ssize_t index) +{ + char *ptr = (char *)view->buf; + return lookup_dimension(view, ptr, 0, index); +} + +/* Get the pointer to the item at tuple. */ +static char * +ptr_from_tuple(Py_buffer *view, PyObject *tup) +{ + char *ptr = (char *)view->buf; + Py_ssize_t dim, nindices = PyTuple_GET_SIZE(tup); + + if (nindices > view->ndim) { + PyErr_Format(PyExc_TypeError, + "cannot index %zd-dimension view with %zd-element tuple", + view->ndim, nindices); + return NULL; + } + + for (dim = 0; dim < nindices; dim++) { + Py_ssize_t index; + index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(tup, dim), + PyExc_IndexError); + if (index == -1 && PyErr_Occurred()) + return NULL; + ptr = lookup_dimension(view, ptr, (int)dim, index); + if (ptr == NULL) + return NULL; + } + return ptr; +} + +/* Return the item at index. In a one-dimensional view, this is an object + with the type specified by view->format. Otherwise, the item is a sub-view. + The function is used in memory_subscript() and memory_as_sequence. */ +static PyObject * +memory_item(PyMemoryViewObject *self, Py_ssize_t index) +{ + Py_buffer *view = &(self->view); + const char *fmt; + + CHECK_RELEASED(self); + + fmt = adjust_fmt(view); + if (fmt == NULL) + return NULL; + + if (view->ndim == 0) { + PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory"); + return NULL; + } + if (view->ndim == 1) { + char *ptr = ptr_from_index(view, index); + if (ptr == NULL) + return NULL; + return unpack_single(ptr, fmt); + } + + PyErr_SetString(PyExc_NotImplementedError, + "multi-dimensional sub-views are not implemented"); + return NULL; +} + +/* Return the item at position *key* (a tuple of indices). */ +static PyObject * +memory_item_multi(PyMemoryViewObject *self, PyObject *tup) +{ + Py_buffer *view = &(self->view); + const char *fmt; + Py_ssize_t nindices = PyTuple_GET_SIZE(tup); + char *ptr; + + CHECK_RELEASED(self); + + fmt = adjust_fmt(view); + if (fmt == NULL) + return NULL; + + if (nindices < view->ndim) { + PyErr_SetString(PyExc_NotImplementedError, + "sub-views are not implemented"); + return NULL; + } + ptr = ptr_from_tuple(view, tup); + if (ptr == NULL) + return NULL; + return unpack_single(ptr, fmt); +} + +static inline int +init_slice(Py_buffer *base, PyObject *key, int dim) +{ + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_Unpack(key, &start, &stop, &step) < 0) { + return -1; + } + slicelength = PySlice_AdjustIndices(base->shape[dim], &start, &stop, step); + + + if (base->suboffsets == NULL || dim == 0) { + adjust_buf: + base->buf = (char *)base->buf + base->strides[dim] * start; + } + else { + Py_ssize_t n = dim-1; + while (n >= 0 && base->suboffsets[n] < 0) + n--; + if (n < 0) + goto adjust_buf; /* all suboffsets are negative */ + base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start; + } + base->shape[dim] = slicelength; + base->strides[dim] = base->strides[dim] * step; + + return 0; +} + +static int +is_multislice(PyObject *key) +{ + Py_ssize_t size, i; + + if (!PyTuple_Check(key)) + return 0; + size = PyTuple_GET_SIZE(key); + if (size == 0) + return 0; + + for (i = 0; i < size; i++) { + PyObject *x = PyTuple_GET_ITEM(key, i); + if (!PySlice_Check(x)) + return 0; + } + return 1; +} + +static Py_ssize_t +is_multiindex(PyObject *key) +{ + Py_ssize_t size, i; + + if (!PyTuple_Check(key)) + return 0; + size = PyTuple_GET_SIZE(key); + for (i = 0; i < size; i++) { + PyObject *x = PyTuple_GET_ITEM(key, i); + if (!PyIndex_Check(x)) + return 0; + } + return 1; +} + +/* mv[obj] returns an object holding the data for one element if obj + fully indexes the memoryview or another memoryview object if it + does not. + + 0-d memoryview objects can be referenced using mv[...] or mv[()] + but not with anything else. */ +static PyObject * +memory_subscript(PyMemoryViewObject *self, PyObject *key) +{ + Py_buffer *view; + view = &(self->view); + + CHECK_RELEASED(self); + + if (view->ndim == 0) { + if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) { + const char *fmt = adjust_fmt(view); + if (fmt == NULL) + return NULL; + return unpack_single(view->buf, fmt); + } + else if (key == Py_Ellipsis) { + Py_INCREF(self); + return (PyObject *)self; + } + else { + PyErr_SetString(PyExc_TypeError, + "invalid indexing of 0-dim memory"); + return NULL; + } + } + + if (PyIndex_Check(key)) { + Py_ssize_t index; + index = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (index == -1 && PyErr_Occurred()) + return NULL; + return memory_item(self, index); + } + else if (PySlice_Check(key)) { + PyMemoryViewObject *sliced; + + sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view); + if (sliced == NULL) + return NULL; + + if (init_slice(&sliced->view, key, 0) < 0) { + Py_DECREF(sliced); + return NULL; + } + init_len(&sliced->view); + init_flags(sliced); + + return (PyObject *)sliced; + } + else if (is_multiindex(key)) { + return memory_item_multi(self, key); + } + else if (is_multislice(key)) { + PyErr_SetString(PyExc_NotImplementedError, + "multi-dimensional slicing is not implemented"); + return NULL; + } + + PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key"); + return NULL; +} + +static int +memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) +{ + Py_buffer *view = &(self->view); + Py_buffer src; + const char *fmt; + char *ptr; + + CHECK_RELEASED_INT(self); + + fmt = adjust_fmt(view); + if (fmt == NULL) + return -1; + + if (view->readonly) { + PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory"); + return -1; + } + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "cannot delete memory"); + return -1; + } + if (view->ndim == 0) { + if (key == Py_Ellipsis || + (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) { + ptr = (char *)view->buf; + return pack_single(ptr, value, fmt); + } + else { + PyErr_SetString(PyExc_TypeError, + "invalid indexing of 0-dim memory"); + return -1; + } + } + + if (PyIndex_Check(key)) { + Py_ssize_t index; + if (1 < view->ndim) { + PyErr_SetString(PyExc_NotImplementedError, + "sub-views are not implemented"); + return -1; + } + index = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (index == -1 && PyErr_Occurred()) + return -1; + ptr = ptr_from_index(view, index); + if (ptr == NULL) + return -1; + return pack_single(ptr, value, fmt); + } + /* one-dimensional: fast path */ + if (PySlice_Check(key) && view->ndim == 1) { + Py_buffer dest; /* sliced view */ + Py_ssize_t arrays[3]; + int ret = -1; + + /* rvalue must be an exporter */ + if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0) + return ret; + + dest = *view; + dest.shape = &arrays[0]; dest.shape[0] = view->shape[0]; + dest.strides = &arrays[1]; dest.strides[0] = view->strides[0]; + if (view->suboffsets) { + dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0]; + } + + if (init_slice(&dest, key, 0) < 0) + goto end_block; + dest.len = dest.shape[0] * dest.itemsize; + + ret = copy_single(&dest, &src); + + end_block: + PyBuffer_Release(&src); + return ret; + } + if (is_multiindex(key)) { + char *ptr; + if (PyTuple_GET_SIZE(key) < view->ndim) { + PyErr_SetString(PyExc_NotImplementedError, + "sub-views are not implemented"); + return -1; + } + ptr = ptr_from_tuple(view, key); + if (ptr == NULL) + return -1; + return pack_single(ptr, value, fmt); + } + if (PySlice_Check(key) || is_multislice(key)) { + /* Call memory_subscript() to produce a sliced lvalue, then copy + rvalue into lvalue. This is already implemented in _testbuffer.c. */ + PyErr_SetString(PyExc_NotImplementedError, + "memoryview slice assignments are currently restricted " + "to ndim = 1"); + return -1; + } + + PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key"); + return -1; +} + +static Py_ssize_t +memory_length(PyMemoryViewObject *self) +{ + CHECK_RELEASED_INT(self); + return self->view.ndim == 0 ? 1 : self->view.shape[0]; +} + +/* As mapping */ +static PyMappingMethods memory_as_mapping = { + (lenfunc)memory_length, /* mp_length */ + (binaryfunc)memory_subscript, /* mp_subscript */ + (objobjargproc)memory_ass_sub, /* mp_ass_subscript */ +}; + +/* As sequence */ +static PySequenceMethods memory_as_sequence = { + (lenfunc)memory_length, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)memory_item, /* sq_item */ +}; + + +/**************************************************************************/ +/* Comparisons */ +/**************************************************************************/ + +#define MV_COMPARE_EX -1 /* exception */ +#define MV_COMPARE_NOT_IMPL -2 /* not implemented */ + +/* Translate a StructError to "not equal". Preserve other exceptions. */ +static int +fix_struct_error_int(void) +{ + assert(PyErr_Occurred()); + /* XXX Cannot get at StructError directly? */ + if (PyErr_ExceptionMatches(PyExc_ImportError) || + PyErr_ExceptionMatches(PyExc_MemoryError)) { + return MV_COMPARE_EX; + } + /* StructError: invalid or unknown format -> not equal */ + PyErr_Clear(); + return 0; +} + +/* Unpack and compare single items of p and q using the struct module. */ +static int +struct_unpack_cmp(const char *p, const char *q, + struct unpacker *unpack_p, struct unpacker *unpack_q) +{ + PyObject *v, *w; + int ret; + + /* At this point any exception from the struct module should not be + StructError, since both formats have been accepted already. */ + v = struct_unpack_single(p, unpack_p); + if (v == NULL) + return MV_COMPARE_EX; + + w = struct_unpack_single(q, unpack_q); + if (w == NULL) { + Py_DECREF(v); + return MV_COMPARE_EX; + } + + /* MV_COMPARE_EX == -1: exceptions are preserved */ + ret = PyObject_RichCompareBool(v, w, Py_EQ); + Py_DECREF(v); + Py_DECREF(w); + + return ret; +} + +/* Unpack and compare single items of p and q. If both p and q have the same + single element native format, the comparison uses a fast path (gcc creates + a jump table and converts memcpy into simple assignments on x86/x64). + + Otherwise, the comparison is delegated to the struct module, which is + 30-60x slower. */ +#define CMP_SINGLE(p, q, type) \ + do { \ + type x; \ + type y; \ + memcpy((char *)&x, p, sizeof x); \ + memcpy((char *)&y, q, sizeof y); \ + equal = (x == y); \ + } while (0) + +static inline int +unpack_cmp(const char *p, const char *q, char fmt, + struct unpacker *unpack_p, struct unpacker *unpack_q) +{ + int equal; + + switch (fmt) { + + /* signed integers and fast path for 'B' */ + case 'B': return *((const unsigned char *)p) == *((const unsigned char *)q); + case 'b': return *((const signed char *)p) == *((const signed char *)q); + case 'h': CMP_SINGLE(p, q, short); return equal; + case 'i': CMP_SINGLE(p, q, int); return equal; + case 'l': CMP_SINGLE(p, q, long); return equal; + + /* boolean */ + case '?': CMP_SINGLE(p, q, _Bool); return equal; + + /* unsigned integers */ + case 'H': CMP_SINGLE(p, q, unsigned short); return equal; + case 'I': CMP_SINGLE(p, q, unsigned int); return equal; + case 'L': CMP_SINGLE(p, q, unsigned long); return equal; + + /* native 64-bit */ + case 'q': CMP_SINGLE(p, q, long long); return equal; + case 'Q': CMP_SINGLE(p, q, unsigned long long); return equal; + + /* ssize_t and size_t */ + case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal; + case 'N': CMP_SINGLE(p, q, size_t); return equal; + + /* floats */ + /* XXX DBL_EPSILON? */ + case 'f': CMP_SINGLE(p, q, float); return equal; + case 'd': CMP_SINGLE(p, q, double); return equal; + + /* bytes object */ + case 'c': return *p == *q; + + /* pointer */ + case 'P': CMP_SINGLE(p, q, void *); return equal; + + /* use the struct module */ + case '_': + assert(unpack_p); + assert(unpack_q); + return struct_unpack_cmp(p, q, unpack_p, unpack_q); + } + + /* NOT REACHED */ + PyErr_SetString(PyExc_RuntimeError, + "memoryview: internal error in richcompare"); + return MV_COMPARE_EX; +} + +/* Base case for recursive array comparisons. Assumption: ndim == 1. */ +static int +cmp_base(const char *p, const char *q, const Py_ssize_t *shape, + const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets, + const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets, + char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q) +{ + Py_ssize_t i; + int equal; + + for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) { + const char *xp = ADJUST_PTR(p, psuboffsets, 0); + const char *xq = ADJUST_PTR(q, qsuboffsets, 0); + equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q); + if (equal <= 0) + return equal; + } + + return 1; +} + +/* Recursively compare two multi-dimensional arrays that have the same + logical structure. Assumption: ndim >= 1. */ +static int +cmp_rec(const char *p, const char *q, + Py_ssize_t ndim, const Py_ssize_t *shape, + const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets, + const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets, + char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q) +{ + Py_ssize_t i; + int equal; + + assert(ndim >= 1); + assert(shape != NULL); + assert(pstrides != NULL); + assert(qstrides != NULL); + + if (ndim == 1) { + return cmp_base(p, q, shape, + pstrides, psuboffsets, + qstrides, qsuboffsets, + fmt, unpack_p, unpack_q); + } + + for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) { + const char *xp = ADJUST_PTR(p, psuboffsets, 0); + const char *xq = ADJUST_PTR(q, qsuboffsets, 0); + equal = cmp_rec(xp, xq, ndim-1, shape+1, + pstrides+1, psuboffsets ? psuboffsets+1 : NULL, + qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL, + fmt, unpack_p, unpack_q); + if (equal <= 0) + return equal; + } + + return 1; +} + +static PyObject * +memory_richcompare(PyObject *v, PyObject *w, int op) +{ + PyObject *res; + Py_buffer wbuf, *vv; + Py_buffer *ww = NULL; + struct unpacker *unpack_v = NULL; + struct unpacker *unpack_w = NULL; + char vfmt, wfmt; + int equal = MV_COMPARE_NOT_IMPL; + + if (op != Py_EQ && op != Py_NE) + goto result; /* Py_NotImplemented */ + + assert(PyMemoryView_Check(v)); + if (BASE_INACCESSIBLE(v)) { + equal = (v == w); + goto result; + } + vv = VIEW_ADDR(v); + + if (PyMemoryView_Check(w)) { + if (BASE_INACCESSIBLE(w)) { + equal = (v == w); + goto result; + } + ww = VIEW_ADDR(w); + } + else { + if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) { + PyErr_Clear(); + goto result; /* Py_NotImplemented */ + } + ww = &wbuf; + } + + if (!equiv_shape(vv, ww)) { + PyErr_Clear(); + equal = 0; + goto result; + } + + /* Use fast unpacking for identical primitive C type formats. */ + if (get_native_fmtchar(&vfmt, vv->format) < 0) + vfmt = '_'; + if (get_native_fmtchar(&wfmt, ww->format) < 0) + wfmt = '_'; + if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) { + /* Use struct module unpacking. NOTE: Even for equal format strings, + memcmp() cannot be used for item comparison since it would give + incorrect results in the case of NaNs or uninitialized padding + bytes. */ + vfmt = '_'; + unpack_v = struct_get_unpacker(vv->format, vv->itemsize); + if (unpack_v == NULL) { + equal = fix_struct_error_int(); + goto result; + } + unpack_w = struct_get_unpacker(ww->format, ww->itemsize); + if (unpack_w == NULL) { + equal = fix_struct_error_int(); + goto result; + } + } + + if (vv->ndim == 0) { + equal = unpack_cmp(vv->buf, ww->buf, + vfmt, unpack_v, unpack_w); + } + else if (vv->ndim == 1) { + equal = cmp_base(vv->buf, ww->buf, vv->shape, + vv->strides, vv->suboffsets, + ww->strides, ww->suboffsets, + vfmt, unpack_v, unpack_w); + } + else { + equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape, + vv->strides, vv->suboffsets, + ww->strides, ww->suboffsets, + vfmt, unpack_v, unpack_w); + } + +result: + if (equal < 0) { + if (equal == MV_COMPARE_NOT_IMPL) + res = Py_NotImplemented; + else /* exception */ + res = NULL; + } + else if ((equal && op == Py_EQ) || (!equal && op == Py_NE)) + res = Py_True; + else + res = Py_False; + + if (ww == &wbuf) + PyBuffer_Release(ww); + + unpacker_free(unpack_v); + unpacker_free(unpack_w); + + Py_XINCREF(res); + return res; +} + +/**************************************************************************/ +/* Hash */ +/**************************************************************************/ + +static Py_hash_t +memory_hash(PyMemoryViewObject *self) +{ + if (self->hash == -1) { + Py_buffer *view = &self->view; + char *mem = view->buf; + Py_ssize_t ret; + char fmt; + + CHECK_RELEASED_INT(self); + + if (!view->readonly) { + PyErr_SetString(PyExc_ValueError, + "cannot hash writable memoryview object"); + return -1; + } + ret = get_native_fmtchar(&fmt, view->format); + if (ret < 0 || !IS_BYTE_FORMAT(fmt)) { + PyErr_SetString(PyExc_ValueError, + "memoryview: hashing is restricted to formats 'B', 'b' or 'c'"); + return -1; + } + if (view->obj != NULL && PyObject_Hash(view->obj) == -1) { + /* Keep the original error message */ + return -1; + } + + if (!MV_C_CONTIGUOUS(self->flags)) { + mem = PyMem_Malloc(view->len); + if (mem == NULL) { + PyErr_NoMemory(); + return -1; + } + if (buffer_to_contiguous(mem, view, 'C') < 0) { + PyMem_Free(mem); + return -1; + } + } + + /* Can't fail */ + self->hash = _Py_HashBytes(mem, view->len); + + if (mem != view->buf) + PyMem_Free(mem); + } + + return self->hash; +} + + +/**************************************************************************/ +/* getters */ +/**************************************************************************/ + +static PyObject * +_IntTupleFromSsizet(int len, Py_ssize_t *vals) +{ + int i; + PyObject *o; + PyObject *intTuple; + + if (vals == NULL) + return PyTuple_New(0); + + intTuple = PyTuple_New(len); + if (!intTuple) + return NULL; + for (i=0; iview; + + CHECK_RELEASED(self); + if (view->obj == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(view->obj); + return view->obj; +} + +static PyObject * +memory_nbytes_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return PyLong_FromSsize_t(self->view.len); +} + +static PyObject * +memory_format_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return PyUnicode_FromString(self->view.format); +} + +static PyObject * +memory_itemsize_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return PyLong_FromSsize_t(self->view.itemsize); +} + +static PyObject * +memory_shape_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return _IntTupleFromSsizet(self->view.ndim, self->view.shape); +} + +static PyObject * +memory_strides_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return _IntTupleFromSsizet(self->view.ndim, self->view.strides); +} + +static PyObject * +memory_suboffsets_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets); +} + +static PyObject * +memory_readonly_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return PyBool_FromLong(self->view.readonly); +} + +static PyObject * +memory_ndim_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +{ + CHECK_RELEASED(self); + return PyLong_FromLong(self->view.ndim); +} + +static PyObject * +memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy) +{ + CHECK_RELEASED(self); + return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags)); +} + +static PyObject * +memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy) +{ + CHECK_RELEASED(self); + return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags)); +} + +static PyObject * +memory_contiguous(PyMemoryViewObject *self, PyObject *dummy) +{ + CHECK_RELEASED(self); + return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags)); +} + +PyDoc_STRVAR(memory_obj_doc, + "The underlying object of the memoryview."); +PyDoc_STRVAR(memory_nbytes_doc, + "The amount of space in bytes that the array would use in\n" + " a contiguous representation."); +PyDoc_STRVAR(memory_readonly_doc, + "A bool indicating whether the memory is read only."); +PyDoc_STRVAR(memory_itemsize_doc, + "The size in bytes of each element of the memoryview."); +PyDoc_STRVAR(memory_format_doc, + "A string containing the format (in struct module style)\n" + " for each element in the view."); +PyDoc_STRVAR(memory_ndim_doc, + "An integer indicating how many dimensions of a multi-dimensional\n" + " array the memory represents."); +PyDoc_STRVAR(memory_shape_doc, + "A tuple of ndim integers giving the shape of the memory\n" + " as an N-dimensional array."); +PyDoc_STRVAR(memory_strides_doc, + "A tuple of ndim integers giving the size in bytes to access\n" + " each element for each dimension of the array."); +PyDoc_STRVAR(memory_suboffsets_doc, + "A tuple of integers used internally for PIL-style arrays."); +PyDoc_STRVAR(memory_c_contiguous_doc, + "A bool indicating whether the memory is C contiguous."); +PyDoc_STRVAR(memory_f_contiguous_doc, + "A bool indicating whether the memory is Fortran contiguous."); +PyDoc_STRVAR(memory_contiguous_doc, + "A bool indicating whether the memory is contiguous."); + + +static PyGetSetDef memory_getsetlist[] = { + {"obj", (getter)memory_obj_get, NULL, memory_obj_doc}, + {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc}, + {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc}, + {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc}, + {"format", (getter)memory_format_get, NULL, memory_format_doc}, + {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc}, + {"shape", (getter)memory_shape_get, NULL, memory_shape_doc}, + {"strides", (getter)memory_strides_get, NULL, memory_strides_doc}, + {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc}, + {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc}, + {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc}, + {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc}, + {NULL, NULL, NULL, NULL}, +}; + +PyDoc_STRVAR(memory_release_doc, +"release($self, /)\n--\n\ +\n\ +Release the underlying buffer exposed by the memoryview object."); +PyDoc_STRVAR(memory_tobytes_doc, +"tobytes($self, /, order=None)\n--\n\ +\n\ +Return the data in the buffer as a byte string. Order can be {'C', 'F', 'A'}.\n\ +When order is 'C' or 'F', the data of the original array is converted to C or\n\ +Fortran order. For contiguous views, 'A' returns an exact copy of the physical\n\ +memory. In particular, in-memory Fortran order is preserved. For non-contiguous\n\ +views, the data is converted to C first. order=None is the same as order='C'."); +PyDoc_STRVAR(memory_tolist_doc, +"tolist($self, /)\n--\n\ +\n\ +Return the data in the buffer as a list of elements."); +PyDoc_STRVAR(memory_cast_doc, +"cast($self, /, format, *, shape)\n--\n\ +\n\ +Cast a memoryview to a new format or shape."); +PyDoc_STRVAR(memory_toreadonly_doc, +"toreadonly($self, /)\n--\n\ +\n\ +Return a readonly version of the memoryview."); + +static PyMethodDef memory_methods[] = { + {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc}, + {"tobytes", (PyCFunction)(void(*)(void))memory_tobytes, METH_VARARGS|METH_KEYWORDS, memory_tobytes_doc}, + MEMORYVIEW_HEX_METHODDEF + {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc}, + {"cast", (PyCFunction)(void(*)(void))memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc}, + {"toreadonly", (PyCFunction)memory_toreadonly, METH_NOARGS, memory_toreadonly_doc}, + {"__enter__", memory_enter, METH_NOARGS, NULL}, + {"__exit__", memory_exit, METH_VARARGS, NULL}, + {NULL, NULL} +}; + + +PyTypeObject PyMemoryView_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "memoryview", /* tp_name */ + offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */ + sizeof(Py_ssize_t), /* tp_itemsize */ + (destructor)memory_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)memory_repr, /* tp_repr */ + 0, /* tp_as_number */ + &memory_as_sequence, /* tp_as_sequence */ + &memory_as_mapping, /* tp_as_mapping */ + (hashfunc)memory_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &memory_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + memory_doc, /* tp_doc */ + (traverseproc)memory_traverse, /* tp_traverse */ + (inquiry)memory_clear, /* tp_clear */ + memory_richcompare, /* tp_richcompare */ + offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + memory_methods, /* tp_methods */ + 0, /* tp_members */ + memory_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + memory_new, /* tp_new */ +}; diff --git a/python/Objects/methodobject.c b/python/Objects/methodobject.c new file mode 100755 index 0000000..3604a55 --- /dev/null +++ b/python/Objects/methodobject.c @@ -0,0 +1,485 @@ + +/* Method object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "structmember.h" + +/* Free list for method objects to safe malloc/free overhead + * The m_self element is used to chain the objects. + */ +static PyCFunctionObject *free_list = NULL; +static int numfree = 0; +#ifndef PyCFunction_MAXFREELIST +#define PyCFunction_MAXFREELIST 256 +#endif + +/* undefine macro trampoline to PyCFunction_NewEx */ +#undef PyCFunction_New + +/* Forward declarations */ +static PyObject * cfunction_vectorcall_FASTCALL( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * cfunction_vectorcall_NOARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * cfunction_vectorcall_O( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); + + +PyObject * +PyCFunction_New(PyMethodDef *ml, PyObject *self) +{ + return PyCFunction_NewEx(ml, self, NULL); +} + +PyObject * +PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) +{ + /* Figure out correct vectorcall function to use */ + vectorcallfunc vectorcall; + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS)) + { + case METH_VARARGS: + case METH_VARARGS | METH_KEYWORDS: + /* For METH_VARARGS functions, it's more efficient to use tp_call + * instead of vectorcall. */ + vectorcall = NULL; + break; + case METH_FASTCALL: + vectorcall = cfunction_vectorcall_FASTCALL; + break; + case METH_FASTCALL | METH_KEYWORDS: + vectorcall = cfunction_vectorcall_FASTCALL_KEYWORDS; + break; + case METH_NOARGS: + vectorcall = cfunction_vectorcall_NOARGS; + break; + case METH_O: + vectorcall = cfunction_vectorcall_O; + break; + default: + PyErr_Format(PyExc_SystemError, + "%s() method: bad call flags", ml->ml_name); + return NULL; + } + + PyCFunctionObject *op; + op = free_list; + if (op != NULL) { + free_list = (PyCFunctionObject *)(op->m_self); + (void)PyObject_INIT(op, &PyCFunction_Type); + numfree--; + } + else { + op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type); + if (op == NULL) + return NULL; + } + op->m_weakreflist = NULL; + op->m_ml = ml; + Py_XINCREF(self); + op->m_self = self; + Py_XINCREF(module); + op->m_module = module; + op->vectorcall = vectorcall; + _PyObject_GC_TRACK(op); + return (PyObject *)op; +} + +PyCFunction +PyCFunction_GetFunction(PyObject *op) +{ + if (!PyCFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return PyCFunction_GET_FUNCTION(op); +} + +PyObject * +PyCFunction_GetSelf(PyObject *op) +{ + if (!PyCFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return PyCFunction_GET_SELF(op); +} + +int +PyCFunction_GetFlags(PyObject *op) +{ + if (!PyCFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + return PyCFunction_GET_FLAGS(op); +} + +/* Methods (the standard built-in methods, that is) */ + +static void +meth_dealloc(PyCFunctionObject *m) +{ + _PyObject_GC_UNTRACK(m); + if (m->m_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*) m); + } + Py_XDECREF(m->m_self); + Py_XDECREF(m->m_module); + if (numfree < PyCFunction_MAXFREELIST) { + m->m_self = (PyObject *)free_list; + free_list = m; + numfree++; + } + else { + PyObject_GC_Del(m); + } +} + +static PyObject * +meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(getattr); + + if (m->m_self == NULL || PyModule_Check(m->m_self)) + return PyUnicode_FromString(m->m_ml->ml_name); + + return Py_BuildValue("N(Os)", _PyEval_GetBuiltinId(&PyId_getattr), + m->m_self, m->m_ml->ml_name); +} + +static PyMethodDef meth_methods[] = { + {"__reduce__", (PyCFunction)meth_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +static PyObject * +meth_get__text_signature__(PyCFunctionObject *m, void *closure) +{ + return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); +} + +static PyObject * +meth_get__doc__(PyCFunctionObject *m, void *closure) +{ + return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); +} + +static PyObject * +meth_get__name__(PyCFunctionObject *m, void *closure) +{ + return PyUnicode_FromString(m->m_ml->ml_name); +} + +static PyObject * +meth_get__qualname__(PyCFunctionObject *m, void *closure) +{ + /* If __self__ is a module or NULL, return m.__name__ + (e.g. len.__qualname__ == 'len') + + If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__ + (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys') + + Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__ + (e.g. [].append.__qualname__ == 'list.append') */ + PyObject *type, *type_qualname, *res; + _Py_IDENTIFIER(__qualname__); + + if (m->m_self == NULL || PyModule_Check(m->m_self)) + return PyUnicode_FromString(m->m_ml->ml_name); + + type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self); + + type_qualname = _PyObject_GetAttrId(type, &PyId___qualname__); + if (type_qualname == NULL) + return NULL; + + if (!PyUnicode_Check(type_qualname)) { + PyErr_SetString(PyExc_TypeError, ".__class__." + "__qualname__ is not a unicode object"); + Py_XDECREF(type_qualname); + return NULL; + } + + res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name); + Py_DECREF(type_qualname); + return res; +} + +static int +meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->m_self); + Py_VISIT(m->m_module); + return 0; +} + +static PyObject * +meth_get__self__(PyCFunctionObject *m, void *closure) +{ + PyObject *self; + + self = PyCFunction_GET_SELF(m); + if (self == NULL) + self = Py_None; + Py_INCREF(self); + return self; +} + +static PyGetSetDef meth_getsets [] = { + {"__doc__", (getter)meth_get__doc__, NULL, NULL}, + {"__name__", (getter)meth_get__name__, NULL, NULL}, + {"__qualname__", (getter)meth_get__qualname__, NULL, NULL}, + {"__self__", (getter)meth_get__self__, NULL, NULL}, + {"__text_signature__", (getter)meth_get__text_signature__, NULL, NULL}, + {0} +}; + +#define OFF(x) offsetof(PyCFunctionObject, x) + +static PyMemberDef meth_members[] = { + {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED}, + {NULL} +}; + +static PyObject * +meth_repr(PyCFunctionObject *m) +{ + if (m->m_self == NULL || PyModule_Check(m->m_self)) + return PyUnicode_FromFormat("", + m->m_ml->ml_name); + return PyUnicode_FromFormat("", + m->m_ml->ml_name, + m->m_self->ob_type->tp_name, + m->m_self); +} + +static PyObject * +meth_richcompare(PyObject *self, PyObject *other, int op) +{ + PyCFunctionObject *a, *b; + PyObject *res; + int eq; + + if ((op != Py_EQ && op != Py_NE) || + !PyCFunction_Check(self) || + !PyCFunction_Check(other)) + { + Py_RETURN_NOTIMPLEMENTED; + } + a = (PyCFunctionObject *)self; + b = (PyCFunctionObject *)other; + eq = a->m_self == b->m_self; + if (eq) + eq = a->m_ml->ml_meth == b->m_ml->ml_meth; + if (op == Py_EQ) + res = eq ? Py_True : Py_False; + else + res = eq ? Py_False : Py_True; + Py_INCREF(res); + return res; +} + +static Py_hash_t +meth_hash(PyCFunctionObject *a) +{ + Py_hash_t x, y; + x = _Py_HashPointer(a->m_self); + y = _Py_HashPointer((void*)(a->m_ml->ml_meth)); + x ^= y; + if (x == -1) + x = -2; + return x; +} + + +PyTypeObject PyCFunction_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "builtin_function_or_method", + sizeof(PyCFunctionObject), + 0, + (destructor)meth_dealloc, /* tp_dealloc */ + offsetof(PyCFunctionObject, vectorcall), /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)meth_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)meth_hash, /* tp_hash */ + PyCFunction_Call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)meth_traverse, /* tp_traverse */ + 0, /* tp_clear */ + meth_richcompare, /* tp_richcompare */ + offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + meth_methods, /* tp_methods */ + meth_members, /* tp_members */ + meth_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ +}; + +/* Clear out the free list */ + +int +PyCFunction_ClearFreeList(void) +{ + int freelist_size = numfree; + + while (free_list) { + PyCFunctionObject *v = free_list; + free_list = (PyCFunctionObject *)(v->m_self); + PyObject_GC_Del(v); + numfree--; + } + assert(numfree == 0); + return freelist_size; +} + +void +PyCFunction_Fini(void) +{ + (void)PyCFunction_ClearFreeList(); +} + +/* Print summary info about the state of the optimized allocator */ +void +_PyCFunction_DebugMallocStats(FILE *out) +{ + _PyDebugAllocatorStats(out, + "free PyCFunctionObject", + numfree, sizeof(PyCFunctionObject)); +} + + +/* Vectorcall functions for each of the PyCFunction calling conventions, + * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which + * doesn't use vectorcall. + * + * First, common helpers + */ +static const char * +get_name(PyObject *func) +{ + assert(PyCFunction_Check(func)); + PyMethodDef *method = ((PyCFunctionObject *)func)->m_ml; + return method->ml_name; +} + +typedef void (*funcptr)(void); + +static inline int +cfunction_check_kwargs(PyObject *func, PyObject *kwnames) +{ + assert(!PyErr_Occurred()); + assert(PyCFunction_Check(func)); + if (kwnames && PyTuple_GET_SIZE(kwnames)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", get_name(func)); + return -1; + } + return 0; +} + +static inline funcptr +cfunction_enter_call(PyObject *func) +{ + if (Py_EnterRecursiveCall(" while calling a Python object")) { + return NULL; + } + return (funcptr)PyCFunction_GET_FUNCTION(func); +} + +/* Now the actual vectorcall functions */ +static PyObject * +cfunction_vectorcall_FASTCALL( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + if (cfunction_check_kwargs(func, kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + _PyCFunctionFast meth = (_PyCFunctionFast) + cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +cfunction_vectorcall_FASTCALL_KEYWORDS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) + cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +cfunction_vectorcall_NOARGS( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + if (cfunction_check_kwargs(func, kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs != 0) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", get_name(func), nargs); + return NULL; + } + PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), NULL); + Py_LeaveRecursiveCall(); + return result; +} + +static PyObject * +cfunction_vectorcall_O( + PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + if (cfunction_check_kwargs(func, kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs != 1) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + get_name(func), nargs); + return NULL; + } + PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + if (meth == NULL) { + return NULL; + } + PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]); + Py_LeaveRecursiveCall(); + return result; +} diff --git a/python/Objects/moduleobject.c b/python/Objects/moduleobject.c new file mode 100755 index 0000000..85134c7 --- /dev/null +++ b/python/Objects/moduleobject.c @@ -0,0 +1,873 @@ + +/* Module object implementation */ + +#include "Python.h" +#include "pycore_pystate.h" +#include "structmember.h" + +static Py_ssize_t max_module_number; + +typedef struct { + PyObject_HEAD + PyObject *md_dict; + struct PyModuleDef *md_def; + void *md_state; + PyObject *md_weaklist; + PyObject *md_name; /* for logging purposes after md_dict is cleared */ +} PyModuleObject; + +static PyMemberDef module_members[] = { + {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, + {0} +}; + + +/* Helper for sanity check for traverse not handling m_state == NULL + * Issue #32374 */ +#ifdef Py_DEBUG +static int +bad_traverse_test(PyObject *self, void *arg) { + assert(self != NULL); + return 0; +} +#endif + +PyTypeObject PyModuleDef_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "moduledef", /* tp_name */ + sizeof(struct PyModuleDef), /* tp_basicsize */ + 0, /* tp_itemsize */ +}; + + +PyObject* +PyModuleDef_Init(struct PyModuleDef* def) +{ + if (PyType_Ready(&PyModuleDef_Type) < 0) + return NULL; + if (def->m_base.m_index == 0) { + max_module_number++; + Py_REFCNT(def) = 1; + Py_TYPE(def) = &PyModuleDef_Type; + def->m_base.m_index = max_module_number; + } + return (PyObject*)def; +} + +static int +module_init_dict(PyModuleObject *mod, PyObject *md_dict, + PyObject *name, PyObject *doc) +{ + _Py_IDENTIFIER(__name__); + _Py_IDENTIFIER(__doc__); + _Py_IDENTIFIER(__package__); + _Py_IDENTIFIER(__loader__); + _Py_IDENTIFIER(__spec__); + + if (md_dict == NULL) + return -1; + if (doc == NULL) + doc = Py_None; + + if (_PyDict_SetItemId(md_dict, &PyId___name__, name) != 0) + return -1; + if (_PyDict_SetItemId(md_dict, &PyId___doc__, doc) != 0) + return -1; + if (_PyDict_SetItemId(md_dict, &PyId___package__, Py_None) != 0) + return -1; + if (_PyDict_SetItemId(md_dict, &PyId___loader__, Py_None) != 0) + return -1; + if (_PyDict_SetItemId(md_dict, &PyId___spec__, Py_None) != 0) + return -1; + if (PyUnicode_CheckExact(name)) { + Py_INCREF(name); + Py_XSETREF(mod->md_name, name); + } + + return 0; +} + + +PyObject * +PyModule_NewObject(PyObject *name) +{ + PyModuleObject *m; + m = PyObject_GC_New(PyModuleObject, &PyModule_Type); + if (m == NULL) + return NULL; + m->md_def = NULL; + m->md_state = NULL; + m->md_weaklist = NULL; + m->md_name = NULL; + m->md_dict = PyDict_New(); + if (module_init_dict(m, m->md_dict, name, NULL) != 0) + goto fail; + PyObject_GC_Track(m); + return (PyObject *)m; + + fail: + Py_DECREF(m); + return NULL; +} + +PyObject * +PyModule_New(const char *name) +{ + PyObject *nameobj, *module; + nameobj = PyUnicode_FromString(name); + if (nameobj == NULL) + return NULL; + module = PyModule_NewObject(nameobj); + Py_DECREF(nameobj); + return module; +} + +/* Check API/ABI version + * Issues a warning on mismatch, which is usually not fatal. + * Returns 0 if an exception is raised. + */ +static int +check_api_version(const char *name, int module_api_version) +{ + if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) { + int err; + err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "Python C API version mismatch for module %.100s: " + "This Python has API version %d, module %.100s has version %d.", + name, + PYTHON_API_VERSION, name, module_api_version); + if (err) + return 0; + } + return 1; +} + +static int +_add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions) +{ + PyObject *func; + PyMethodDef *fdef; + + for (fdef = functions; fdef->ml_name != NULL; fdef++) { + if ((fdef->ml_flags & METH_CLASS) || + (fdef->ml_flags & METH_STATIC)) { + PyErr_SetString(PyExc_ValueError, + "module functions cannot set" + " METH_CLASS or METH_STATIC"); + return -1; + } + func = PyCFunction_NewEx(fdef, (PyObject*)module, name); + if (func == NULL) { + return -1; + } + if (PyObject_SetAttrString(module, fdef->ml_name, func) != 0) { + Py_DECREF(func); + return -1; + } + Py_DECREF(func); + } + + return 0; +} + +PyObject * +PyModule_Create2(struct PyModuleDef* module, int module_api_version) +{ + if (!_PyImport_IsInitialized(_PyInterpreterState_Get())) + Py_FatalError("Python import machinery not initialized"); + return _PyModule_CreateInitialized(module, module_api_version); +} + +PyObject * +_PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version) +{ + const char* name; + PyModuleObject *m; + + if (!PyModuleDef_Init(module)) + return NULL; + name = module->m_name; + if (!check_api_version(name, module_api_version)) { + return NULL; + } + if (module->m_slots) { + PyErr_Format( + PyExc_SystemError, + "module %s: PyModule_Create is incompatible with m_slots", name); + return NULL; + } + /* Make sure name is fully qualified. + + This is a bit of a hack: when the shared library is loaded, + the module name is "package.module", but the module calls + PyModule_Create*() with just "module" for the name. The shared + library loader squirrels away the true name of the module in + _Py_PackageContext, and PyModule_Create*() will substitute this + (if the name actually matches). + */ + if (_Py_PackageContext != NULL) { + const char *p = strrchr(_Py_PackageContext, '.'); + if (p != NULL && strcmp(module->m_name, p+1) == 0) { + name = _Py_PackageContext; + _Py_PackageContext = NULL; + } + } + if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) + return NULL; + + if (module->m_size > 0) { + m->md_state = PyMem_MALLOC(module->m_size); + if (!m->md_state) { + PyErr_NoMemory(); + Py_DECREF(m); + return NULL; + } + memset(m->md_state, 0, module->m_size); + } + + if (module->m_methods != NULL) { + if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) { + Py_DECREF(m); + return NULL; + } + } + if (module->m_doc != NULL) { + if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) { + Py_DECREF(m); + return NULL; + } + } + m->md_def = module; + return (PyObject*)m; +} + +PyObject * +PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api_version) +{ + PyModuleDef_Slot* cur_slot; + PyObject *(*create)(PyObject *, PyModuleDef*) = NULL; + PyObject *nameobj; + PyObject *m = NULL; + int has_execution_slots = 0; + const char *name; + int ret; + + PyModuleDef_Init(def); + + nameobj = PyObject_GetAttrString(spec, "name"); + if (nameobj == NULL) { + return NULL; + } + name = PyUnicode_AsUTF8(nameobj); + if (name == NULL) { + goto error; + } + + if (!check_api_version(name, module_api_version)) { + goto error; + } + + if (def->m_size < 0) { + PyErr_Format( + PyExc_SystemError, + "module %s: m_size may not be negative for multi-phase initialization", + name); + goto error; + } + + for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) { + if (cur_slot->slot == Py_mod_create) { + if (create) { + PyErr_Format( + PyExc_SystemError, + "module %s has multiple create slots", + name); + goto error; + } + create = cur_slot->value; + } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) { + PyErr_Format( + PyExc_SystemError, + "module %s uses unknown slot ID %i", + name, cur_slot->slot); + goto error; + } else { + has_execution_slots = 1; + } + } + + if (create) { + m = create(spec, def); + if (m == NULL) { + if (!PyErr_Occurred()) { + PyErr_Format( + PyExc_SystemError, + "creation of module %s failed without setting an exception", + name); + } + goto error; + } else { + if (PyErr_Occurred()) { + PyErr_Format(PyExc_SystemError, + "creation of module %s raised unreported exception", + name); + goto error; + } + } + } else { + m = PyModule_NewObject(nameobj); + if (m == NULL) { + goto error; + } + } + + if (PyModule_Check(m)) { + ((PyModuleObject*)m)->md_state = NULL; + ((PyModuleObject*)m)->md_def = def; + } else { + if (def->m_size > 0 || def->m_traverse || def->m_clear || def->m_free) { + PyErr_Format( + PyExc_SystemError, + "module %s is not a module object, but requests module state", + name); + goto error; + } + if (has_execution_slots) { + PyErr_Format( + PyExc_SystemError, + "module %s specifies execution slots, but did not create " + "a ModuleType instance", + name); + goto error; + } + } + + if (def->m_methods != NULL) { + ret = _add_methods_to_object(m, nameobj, def->m_methods); + if (ret != 0) { + goto error; + } + } + + if (def->m_doc != NULL) { + ret = PyModule_SetDocString(m, def->m_doc); + if (ret != 0) { + goto error; + } + } + + /* Sanity check for traverse not handling m_state == NULL + * This doesn't catch all possible cases, but in many cases it should + * make many cases of invalid code crash or raise Valgrind issues + * sooner than they would otherwise. + * Issue #32374 */ +#ifdef Py_DEBUG + if (def->m_traverse != NULL) { + def->m_traverse(m, bad_traverse_test, NULL); + } +#endif + Py_DECREF(nameobj); + return m; + +error: + Py_DECREF(nameobj); + Py_XDECREF(m); + return NULL; +} + +int +PyModule_ExecDef(PyObject *module, PyModuleDef *def) +{ + PyModuleDef_Slot *cur_slot; + const char *name; + int ret; + + name = PyModule_GetName(module); + if (name == NULL) { + return -1; + } + + if (def->m_size >= 0) { + PyModuleObject *md = (PyModuleObject*)module; + if (md->md_state == NULL) { + /* Always set a state pointer; this serves as a marker to skip + * multiple initialization (importlib.reload() is no-op) */ + md->md_state = PyMem_MALLOC(def->m_size); + if (!md->md_state) { + PyErr_NoMemory(); + return -1; + } + memset(md->md_state, 0, def->m_size); + } + } + + if (def->m_slots == NULL) { + return 0; + } + + for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) { + switch (cur_slot->slot) { + case Py_mod_create: + /* handled in PyModule_FromDefAndSpec2 */ + break; + case Py_mod_exec: + ret = ((int (*)(PyObject *))cur_slot->value)(module); + if (ret != 0) { + if (!PyErr_Occurred()) { + PyErr_Format( + PyExc_SystemError, + "execution of module %s failed without setting an exception", + name); + } + return -1; + } + if (PyErr_Occurred()) { + PyErr_Format( + PyExc_SystemError, + "execution of module %s raised unreported exception", + name); + return -1; + } + break; + default: + PyErr_Format( + PyExc_SystemError, + "module %s initialized with unknown slot %i", + name, cur_slot->slot); + return -1; + } + } + return 0; +} + +int +PyModule_AddFunctions(PyObject *m, PyMethodDef *functions) +{ + int res; + PyObject *name = PyModule_GetNameObject(m); + if (name == NULL) { + return -1; + } + + res = _add_methods_to_object(m, name, functions); + Py_DECREF(name); + return res; +} + +int +PyModule_SetDocString(PyObject *m, const char *doc) +{ + PyObject *v; + _Py_IDENTIFIER(__doc__); + + v = PyUnicode_FromString(doc); + if (v == NULL || _PyObject_SetAttrId(m, &PyId___doc__, v) != 0) { + Py_XDECREF(v); + return -1; + } + Py_DECREF(v); + return 0; +} + +PyObject * +PyModule_GetDict(PyObject *m) +{ + PyObject *d; + if (!PyModule_Check(m)) { + PyErr_BadInternalCall(); + return NULL; + } + d = ((PyModuleObject *)m) -> md_dict; + assert(d != NULL); + return d; +} + +PyObject* +PyModule_GetNameObject(PyObject *m) +{ + _Py_IDENTIFIER(__name__); + PyObject *d; + PyObject *name; + if (!PyModule_Check(m)) { + PyErr_BadArgument(); + return NULL; + } + d = ((PyModuleObject *)m)->md_dict; + if (d == NULL || + (name = _PyDict_GetItemId(d, &PyId___name__)) == NULL || + !PyUnicode_Check(name)) + { + PyErr_SetString(PyExc_SystemError, "nameless module"); + return NULL; + } + Py_INCREF(name); + return name; +} + +const char * +PyModule_GetName(PyObject *m) +{ + PyObject *name = PyModule_GetNameObject(m); + if (name == NULL) + return NULL; + Py_DECREF(name); /* module dict has still a reference */ + return PyUnicode_AsUTF8(name); +} + +PyObject* +PyModule_GetFilenameObject(PyObject *m) +{ + _Py_IDENTIFIER(__file__); + PyObject *d; + PyObject *fileobj; + if (!PyModule_Check(m)) { + PyErr_BadArgument(); + return NULL; + } + d = ((PyModuleObject *)m)->md_dict; + if (d == NULL || + (fileobj = _PyDict_GetItemId(d, &PyId___file__)) == NULL || + !PyUnicode_Check(fileobj)) + { + PyErr_SetString(PyExc_SystemError, "module filename missing"); + return NULL; + } + Py_INCREF(fileobj); + return fileobj; +} + +const char * +PyModule_GetFilename(PyObject *m) +{ + PyObject *fileobj; + const char *utf8; + fileobj = PyModule_GetFilenameObject(m); + if (fileobj == NULL) + return NULL; + utf8 = PyUnicode_AsUTF8(fileobj); + Py_DECREF(fileobj); /* module dict has still a reference */ + return utf8; +} + +PyModuleDef* +PyModule_GetDef(PyObject* m) +{ + if (!PyModule_Check(m)) { + PyErr_BadArgument(); + return NULL; + } + return ((PyModuleObject *)m)->md_def; +} + +void* +PyModule_GetState(PyObject* m) +{ + if (!PyModule_Check(m)) { + PyErr_BadArgument(); + return NULL; + } + return ((PyModuleObject *)m)->md_state; +} + +void +_PyModule_Clear(PyObject *m) +{ + PyObject *d = ((PyModuleObject *)m)->md_dict; + if (d != NULL) + _PyModule_ClearDict(d); +} + +void +_PyModule_ClearDict(PyObject *d) +{ + /* To make the execution order of destructors for global + objects a bit more predictable, we first zap all objects + whose name starts with a single underscore, before we clear + the entire dictionary. We zap them by replacing them with + None, rather than deleting them from the dictionary, to + avoid rehashing the dictionary (to some extent). */ + + Py_ssize_t pos; + PyObject *key, *value; + + int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose; + + /* First, clear only names starting with a single underscore */ + pos = 0; + while (PyDict_Next(d, &pos, &key, &value)) { + if (value != Py_None && PyUnicode_Check(key)) { + if (PyUnicode_READ_CHAR(key, 0) == '_' && + PyUnicode_READ_CHAR(key, 1) != '_') { + if (verbose > 1) { + const char *s = PyUnicode_AsUTF8(key); + if (s != NULL) + PySys_WriteStderr("# clear[1] %s\n", s); + else + PyErr_Clear(); + } + if (PyDict_SetItem(d, key, Py_None) != 0) { + PyErr_WriteUnraisable(NULL); + } + } + } + } + + /* Next, clear all names except for __builtins__ */ + pos = 0; + while (PyDict_Next(d, &pos, &key, &value)) { + if (value != Py_None && PyUnicode_Check(key)) { + if (PyUnicode_READ_CHAR(key, 0) != '_' || + !_PyUnicode_EqualToASCIIString(key, "__builtins__")) + { + if (verbose > 1) { + const char *s = PyUnicode_AsUTF8(key); + if (s != NULL) + PySys_WriteStderr("# clear[2] %s\n", s); + else + PyErr_Clear(); + } + if (PyDict_SetItem(d, key, Py_None) != 0) { + PyErr_WriteUnraisable(NULL); + } + } + } + } + + /* Note: we leave __builtins__ in place, so that destructors + of non-global objects defined in this module can still use + builtins, in particularly 'None'. */ + +} + +/*[clinic input] +class module "PyModuleObject *" "&PyModule_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3e35d4f708ecb6af]*/ + +#include "clinic/moduleobject.c.h" + +/* Methods */ + +/*[clinic input] +module.__init__ + name: unicode + doc: object = None + +Create a module object. + +The name must be a string; the optional doc argument can have any type. +[clinic start generated code]*/ + +static int +module___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc) +/*[clinic end generated code: output=e7e721c26ce7aad7 input=57f9e177401e5e1e]*/ +{ + PyObject *dict = self->md_dict; + if (dict == NULL) { + dict = PyDict_New(); + if (dict == NULL) + return -1; + self->md_dict = dict; + } + if (module_init_dict(self, dict, name, doc) < 0) + return -1; + return 0; +} + +static void +module_dealloc(PyModuleObject *m) +{ + int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose; + + PyObject_GC_UnTrack(m); + if (verbose && m->md_name) { + PySys_FormatStderr("# destroy %S\n", m->md_name); + } + if (m->md_weaklist != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + if (m->md_def && m->md_def->m_free) + m->md_def->m_free(m); + Py_XDECREF(m->md_dict); + Py_XDECREF(m->md_name); + if (m->md_state != NULL) + PyMem_FREE(m->md_state); + Py_TYPE(m)->tp_free((PyObject *)m); +} + +static PyObject * +module_repr(PyModuleObject *m) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + + return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m); +} + +/* Check if the "_initializing" attribute of the module spec is set to true. + Clear the exception and return 0 if spec is NULL. + */ +int +_PyModuleSpec_IsInitializing(PyObject *spec) +{ + if (spec != NULL) { + _Py_IDENTIFIER(_initializing); + PyObject *value = _PyObject_GetAttrId(spec, &PyId__initializing); + if (value != NULL) { + int initializing = PyObject_IsTrue(value); + Py_DECREF(value); + if (initializing >= 0) { + return initializing; + } + } + } + PyErr_Clear(); + return 0; +} + +static PyObject* +module_getattro(PyModuleObject *m, PyObject *name) +{ + PyObject *attr, *mod_name, *getattr; + attr = PyObject_GenericGetAttr((PyObject *)m, name); + if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) { + return attr; + } + PyErr_Clear(); + if (m->md_dict) { + _Py_IDENTIFIER(__getattr__); + getattr = _PyDict_GetItemId(m->md_dict, &PyId___getattr__); + if (getattr) { + PyObject* stack[1] = {name}; + return _PyObject_FastCall(getattr, stack, 1); + } + _Py_IDENTIFIER(__name__); + mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__); + if (mod_name && PyUnicode_Check(mod_name)) { + _Py_IDENTIFIER(__spec__); + Py_INCREF(mod_name); + PyObject *spec = _PyDict_GetItemId(m->md_dict, &PyId___spec__); + Py_XINCREF(spec); + if (_PyModuleSpec_IsInitializing(spec)) { + PyErr_Format(PyExc_AttributeError, + "partially initialized " + "module '%U' has no attribute '%U' " + "(most likely due to a circular import)", + mod_name, name); + } + else { + PyErr_Format(PyExc_AttributeError, + "module '%U' has no attribute '%U'", + mod_name, name); + } + Py_XDECREF(spec); + Py_DECREF(mod_name); + return NULL; + } + } + PyErr_Format(PyExc_AttributeError, + "module has no attribute '%U'", name); + return NULL; +} + +static int +module_traverse(PyModuleObject *m, visitproc visit, void *arg) +{ + if (m->md_def && m->md_def->m_traverse) { + int res = m->md_def->m_traverse((PyObject*)m, visit, arg); + if (res) + return res; + } + Py_VISIT(m->md_dict); + return 0; +} + +static int +module_clear(PyModuleObject *m) +{ + if (m->md_def && m->md_def->m_clear) { + int res = m->md_def->m_clear((PyObject*)m); + if (res) + return res; + } + Py_CLEAR(m->md_dict); + return 0; +} + +static PyObject * +module_dir(PyObject *self, PyObject *args) +{ + _Py_IDENTIFIER(__dict__); + _Py_IDENTIFIER(__dir__); + PyObject *result = NULL; + PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__); + + if (dict != NULL) { + if (PyDict_Check(dict)) { + PyObject *dirfunc = _PyDict_GetItemIdWithError(dict, &PyId___dir__); + if (dirfunc) { + result = _PyObject_CallNoArg(dirfunc); + } + else if (!PyErr_Occurred()) { + result = PyDict_Keys(dict); + } + } + else { + const char *name = PyModule_GetName(self); + if (name) + PyErr_Format(PyExc_TypeError, + "%.200s.__dict__ is not a dictionary", + name); + } + } + + Py_XDECREF(dict); + return result; +} + +static PyMethodDef module_methods[] = { + {"__dir__", module_dir, METH_NOARGS, + PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")}, + {0} +}; + +PyTypeObject PyModule_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "module", /* tp_name */ + sizeof(PyModuleObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)module_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)module_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + (getattrofunc)module_getattro, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + module___init____doc__, /* tp_doc */ + (traverseproc)module_traverse, /* tp_traverse */ + (inquiry)module_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyModuleObject, md_weaklist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + module_methods, /* tp_methods */ + module_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(PyModuleObject, md_dict), /* tp_dictoffset */ + module___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; diff --git a/python/Objects/namespaceobject.c b/python/Objects/namespaceobject.c new file mode 100755 index 0000000..ddad39a --- /dev/null +++ b/python/Objects/namespaceobject.c @@ -0,0 +1,263 @@ +// namespace object implementation + +#include "Python.h" +#include "structmember.h" + + +typedef struct { + PyObject_HEAD + PyObject *ns_dict; +} _PyNamespaceObject; + + +static PyMemberDef namespace_members[] = { + {"__dict__", T_OBJECT, offsetof(_PyNamespaceObject, ns_dict), READONLY}, + {NULL} +}; + + +// Methods + +static PyObject * +namespace_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *self; + + assert(type != NULL && type->tp_alloc != NULL); + self = type->tp_alloc(type, 0); + if (self != NULL) { + _PyNamespaceObject *ns = (_PyNamespaceObject *)self; + ns->ns_dict = PyDict_New(); + if (ns->ns_dict == NULL) { + Py_DECREF(ns); + return NULL; + } + } + return self; +} + + +static int +namespace_init(_PyNamespaceObject *ns, PyObject *args, PyObject *kwds) +{ + if (PyTuple_GET_SIZE(args) != 0) { + PyErr_Format(PyExc_TypeError, "no positional arguments expected"); + return -1; + } + if (kwds == NULL) { + return 0; + } + if (!PyArg_ValidateKeywordArguments(kwds)) { + return -1; + } + return PyDict_Update(ns->ns_dict, kwds); +} + + +static void +namespace_dealloc(_PyNamespaceObject *ns) +{ + PyObject_GC_UnTrack(ns); + Py_CLEAR(ns->ns_dict); + Py_TYPE(ns)->tp_free((PyObject *)ns); +} + + +static PyObject * +namespace_repr(PyObject *ns) +{ + int i, loop_error = 0; + PyObject *pairs = NULL, *d = NULL, *keys = NULL, *keys_iter = NULL; + PyObject *key; + PyObject *separator, *pairsrepr, *repr = NULL; + const char * name; + + name = (Py_TYPE(ns) == &_PyNamespace_Type) ? "namespace" + : ns->ob_type->tp_name; + + i = Py_ReprEnter(ns); + if (i != 0) { + return i > 0 ? PyUnicode_FromFormat("%s(...)", name) : NULL; + } + + pairs = PyList_New(0); + if (pairs == NULL) + goto error; + + d = ((_PyNamespaceObject *)ns)->ns_dict; + assert(d != NULL); + Py_INCREF(d); + + keys = PyDict_Keys(d); + if (keys == NULL) + goto error; + if (PyList_Sort(keys) != 0) + goto error; + + keys_iter = PyObject_GetIter(keys); + if (keys_iter == NULL) + goto error; + + while ((key = PyIter_Next(keys_iter)) != NULL) { + if (PyUnicode_Check(key) && PyUnicode_GET_LENGTH(key) > 0) { + PyObject *value, *item; + + value = PyDict_GetItemWithError(d, key); + if (value != NULL) { + item = PyUnicode_FromFormat("%U=%R", key, value); + if (item == NULL) { + loop_error = 1; + } + else { + loop_error = PyList_Append(pairs, item); + Py_DECREF(item); + } + } + else if (PyErr_Occurred()) { + loop_error = 1; + } + } + + Py_DECREF(key); + if (loop_error) + goto error; + } + + separator = PyUnicode_FromString(", "); + if (separator == NULL) + goto error; + + pairsrepr = PyUnicode_Join(separator, pairs); + Py_DECREF(separator); + if (pairsrepr == NULL) + goto error; + + repr = PyUnicode_FromFormat("%s(%S)", name, pairsrepr); + Py_DECREF(pairsrepr); + +error: + Py_XDECREF(pairs); + Py_XDECREF(d); + Py_XDECREF(keys); + Py_XDECREF(keys_iter); + Py_ReprLeave(ns); + + return repr; +} + + +static int +namespace_traverse(_PyNamespaceObject *ns, visitproc visit, void *arg) +{ + Py_VISIT(ns->ns_dict); + return 0; +} + + +static int +namespace_clear(_PyNamespaceObject *ns) +{ + Py_CLEAR(ns->ns_dict); + return 0; +} + + +static PyObject * +namespace_richcompare(PyObject *self, PyObject *other, int op) +{ + if (PyObject_TypeCheck(self, &_PyNamespace_Type) && + PyObject_TypeCheck(other, &_PyNamespace_Type)) + return PyObject_RichCompare(((_PyNamespaceObject *)self)->ns_dict, + ((_PyNamespaceObject *)other)->ns_dict, op); + Py_RETURN_NOTIMPLEMENTED; +} + + +PyDoc_STRVAR(namespace_reduce__doc__, "Return state information for pickling"); + +static PyObject * +namespace_reduce(_PyNamespaceObject *ns, PyObject *Py_UNUSED(ignored)) +{ + PyObject *result, *args = PyTuple_New(0); + + if (!args) + return NULL; + + result = PyTuple_Pack(3, (PyObject *)Py_TYPE(ns), args, ns->ns_dict); + Py_DECREF(args); + return result; +} + + +static PyMethodDef namespace_methods[] = { + {"__reduce__", (PyCFunction)namespace_reduce, METH_NOARGS, + namespace_reduce__doc__}, + {NULL, NULL} // sentinel +}; + + +PyDoc_STRVAR(namespace_doc, +"A simple attribute-based namespace.\n\ +\n\ +SimpleNamespace(**kwargs)"); + +PyTypeObject _PyNamespace_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "types.SimpleNamespace", /* tp_name */ + sizeof(_PyNamespaceObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)namespace_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)namespace_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + namespace_doc, /* tp_doc */ + (traverseproc)namespace_traverse, /* tp_traverse */ + (inquiry)namespace_clear, /* tp_clear */ + namespace_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + namespace_methods, /* tp_methods */ + namespace_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(_PyNamespaceObject, ns_dict), /* tp_dictoffset */ + (initproc)namespace_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + (newfunc)namespace_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +PyObject * +_PyNamespace_New(PyObject *kwds) +{ + PyObject *ns = namespace_new(&_PyNamespace_Type, NULL, NULL); + if (ns == NULL) + return NULL; + + if (kwds == NULL) + return ns; + if (PyDict_Update(((_PyNamespaceObject *)ns)->ns_dict, kwds) != 0) { + Py_DECREF(ns); + return NULL; + } + + return (PyObject *)ns; +} diff --git a/python/Objects/object.c b/python/Objects/object.c new file mode 100755 index 0000000..74b1b15 --- /dev/null +++ b/python/Objects/object.c @@ -0,0 +1,2220 @@ + +/* Generic object operations; and implementation of None */ + +#include "Python.h" +#include "pycore_initconfig.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "pycore_context.h" +#include "frameobject.h" +#include "interpreteridobject.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined in tracemalloc.c */ +extern void _PyMem_DumpTraceback(int fd, const void *ptr); + +_Py_IDENTIFIER(Py_Repr); +_Py_IDENTIFIER(__bytes__); +_Py_IDENTIFIER(__dir__); +_Py_IDENTIFIER(__isabstractmethod__); + + +int +_PyObject_CheckConsistency(PyObject *op, int check_content) +{ +#define CHECK(expr) \ + do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) + + CHECK(!_PyObject_IsFreed(op)); + CHECK(Py_REFCNT(op) >= 1); + + CHECK(op->ob_type != NULL); + _PyType_CheckConsistency(op->ob_type); + + if (PyUnicode_Check(op)) { + _PyUnicode_CheckConsistency(op, check_content); + } + else if (PyDict_Check(op)) { + _PyDict_CheckConsistency(op, check_content); + } + return 1; + +#undef CHECK +} + + +#ifdef Py_REF_DEBUG +Py_ssize_t _Py_RefTotal; + +Py_ssize_t +_Py_GetRefTotal(void) +{ + PyObject *o; + Py_ssize_t total = _Py_RefTotal; + o = _PySet_Dummy; + if (o != NULL) + total -= o->ob_refcnt; + return total; +} + +void +_PyDebug_PrintTotalRefs(void) { + fprintf(stderr, + "[%" PY_FORMAT_SIZE_T "d refs, " + "%" PY_FORMAT_SIZE_T "d blocks]\n", + _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); +} +#endif /* Py_REF_DEBUG */ + +/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros. + These are used by the individual routines for object creation. + Do not call them otherwise, they do not initialize the object! */ + +#ifdef Py_TRACE_REFS +/* Head of circular doubly-linked list of all objects. These are linked + * together via the _ob_prev and _ob_next members of a PyObject, which + * exist only in a Py_TRACE_REFS build. + */ +static PyObject refchain = {&refchain, &refchain}; + +/* Insert op at the front of the list of all objects. If force is true, + * op is added even if _ob_prev and _ob_next are non-NULL already. If + * force is false amd _ob_prev or _ob_next are non-NULL, do nothing. + * force should be true if and only if op points to freshly allocated, + * uninitialized memory, or you've unlinked op from the list and are + * relinking it into the front. + * Note that objects are normally added to the list via _Py_NewReference, + * which is called by PyObject_Init. Not all objects are initialized that + * way, though; exceptions include statically allocated type objects, and + * statically allocated singletons (like Py_True and Py_None). + */ +void +_Py_AddToAllObjects(PyObject *op, int force) +{ +#ifdef Py_DEBUG + if (!force) { + /* If it's initialized memory, op must be in or out of + * the list unambiguously. + */ + _PyObject_ASSERT(op, (op->_ob_prev == NULL) == (op->_ob_next == NULL)); + } +#endif + if (force || op->_ob_prev == NULL) { + op->_ob_next = refchain._ob_next; + op->_ob_prev = &refchain; + refchain._ob_next->_ob_prev = op; + refchain._ob_next = op; + } +} +#endif /* Py_TRACE_REFS */ + +#ifdef COUNT_ALLOCS +static PyTypeObject *type_list; +/* All types are added to type_list, at least when + they get one object created. That makes them + immortal, which unfortunately contributes to + garbage itself. If unlist_types_without_objects + is set, they will be removed from the type_list + once the last object is deallocated. */ +static int unlist_types_without_objects; +extern Py_ssize_t _Py_tuple_zero_allocs, _Py_fast_tuple_allocs; +extern Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs; +extern Py_ssize_t _Py_null_strings, _Py_one_strings; +void +_Py_dump_counts(FILE* f) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (!interp->config.show_alloc_count) { + return; + } + + PyTypeObject *tp; + for (tp = type_list; tp; tp = tp->tp_next) + fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, " + "freed: %" PY_FORMAT_SIZE_T "d, " + "max in use: %" PY_FORMAT_SIZE_T "d\n", + tp->tp_name, tp->tp_allocs, tp->tp_frees, + tp->tp_maxalloc); + fprintf(f, "fast tuple allocs: %" PY_FORMAT_SIZE_T "d, " + "empty: %" PY_FORMAT_SIZE_T "d\n", + _Py_fast_tuple_allocs, _Py_tuple_zero_allocs); + fprintf(f, "fast int allocs: pos: %" PY_FORMAT_SIZE_T "d, " + "neg: %" PY_FORMAT_SIZE_T "d\n", + _Py_quick_int_allocs, _Py_quick_neg_int_allocs); + fprintf(f, "null strings: %" PY_FORMAT_SIZE_T "d, " + "1-strings: %" PY_FORMAT_SIZE_T "d\n", + _Py_null_strings, _Py_one_strings); +} + +PyObject * +_Py_get_counts(void) +{ + PyTypeObject *tp; + PyObject *result; + PyObject *v; + + result = PyList_New(0); + if (result == NULL) + return NULL; + for (tp = type_list; tp; tp = tp->tp_next) { + v = Py_BuildValue("(snnn)", tp->tp_name, tp->tp_allocs, + tp->tp_frees, tp->tp_maxalloc); + if (v == NULL) { + Py_DECREF(result); + return NULL; + } + if (PyList_Append(result, v) < 0) { + Py_DECREF(v); + Py_DECREF(result); + return NULL; + } + Py_DECREF(v); + } + return result; +} + +void +_Py_inc_count(PyTypeObject *tp) +{ + if (tp->tp_next == NULL && tp->tp_prev == NULL) { + /* first time; insert in linked list */ + if (tp->tp_next != NULL) /* sanity check */ + Py_FatalError("XXX _Py_inc_count sanity check"); + if (type_list) + type_list->tp_prev = tp; + tp->tp_next = type_list; + /* Note that as of Python 2.2, heap-allocated type objects + * can go away, but this code requires that they stay alive + * until program exit. That's why we're careful with + * refcounts here. type_list gets a new reference to tp, + * while ownership of the reference type_list used to hold + * (if any) was transferred to tp->tp_next in the line above. + * tp is thus effectively immortal after this. + */ + Py_INCREF(tp); + type_list = tp; +#ifdef Py_TRACE_REFS + /* Also insert in the doubly-linked list of all objects, + * if not already there. + */ + _Py_AddToAllObjects((PyObject *)tp, 0); +#endif + } + tp->tp_allocs++; + if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc) + tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees; +} + +void _Py_dec_count(PyTypeObject *tp) +{ + tp->tp_frees++; + if (unlist_types_without_objects && + tp->tp_allocs == tp->tp_frees) { + /* unlink the type from type_list */ + if (tp->tp_prev) + tp->tp_prev->tp_next = tp->tp_next; + else + type_list = tp->tp_next; + if (tp->tp_next) + tp->tp_next->tp_prev = tp->tp_prev; + tp->tp_next = tp->tp_prev = NULL; + Py_DECREF(tp); + } +} + +#endif + +#ifdef Py_REF_DEBUG +/* Log a fatal error; doesn't return. */ +void +_Py_NegativeRefcount(const char *filename, int lineno, PyObject *op) +{ + _PyObject_AssertFailed(op, NULL, "object has negative ref count", + filename, lineno, __func__); +} + +#endif /* Py_REF_DEBUG */ + +void +Py_IncRef(PyObject *o) +{ + Py_XINCREF(o); +} + +void +Py_DecRef(PyObject *o) +{ + Py_XDECREF(o); +} + +PyObject * +PyObject_Init(PyObject *op, PyTypeObject *tp) +{ + if (op == NULL) + return PyErr_NoMemory(); + /* Any changes should be reflected in PyObject_INIT (objimpl.h) */ + Py_TYPE(op) = tp; + if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(tp); + } + _Py_NewReference(op); + return op; +} + +PyVarObject * +PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) +{ + if (op == NULL) + return (PyVarObject *) PyErr_NoMemory(); + /* Any changes should be reflected in PyObject_INIT_VAR */ + Py_SIZE(op) = size; + PyObject_Init((PyObject *)op, tp); + return op; +} + +PyObject * +_PyObject_New(PyTypeObject *tp) +{ + PyObject *op; + op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp)); + if (op == NULL) + return PyErr_NoMemory(); + return PyObject_INIT(op, tp); +} + +PyVarObject * +_PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems) +{ + PyVarObject *op; + const size_t size = _PyObject_VAR_SIZE(tp, nitems); + op = (PyVarObject *) PyObject_MALLOC(size); + if (op == NULL) + return (PyVarObject *)PyErr_NoMemory(); + return PyObject_INIT_VAR(op, tp, nitems); +} + +void +PyObject_CallFinalizer(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + + if (tp->tp_finalize == NULL) + return; + /* tp_finalize should only be called once. */ + if (PyType_IS_GC(tp) && _PyGC_FINALIZED(self)) + return; + + tp->tp_finalize(self); + if (PyType_IS_GC(tp)) { + _PyGC_SET_FINALIZED(self); + } +} + +int +PyObject_CallFinalizerFromDealloc(PyObject *self) +{ + Py_ssize_t refcnt; + + /* Temporarily resurrect the object. */ + if (self->ob_refcnt != 0) { + Py_FatalError("PyObject_CallFinalizerFromDealloc called on " + "object with a non-zero refcount"); + } + self->ob_refcnt = 1; + + PyObject_CallFinalizer(self); + + /* Undo the temporary resurrection; can't use DECREF here, it would + * cause a recursive call. + */ + _PyObject_ASSERT_WITH_MSG(self, + self->ob_refcnt > 0, + "refcount is too small"); + if (--self->ob_refcnt == 0) + return 0; /* this is the normal path out */ + + /* tp_finalize resurrected it! Make it look like the original Py_DECREF + * never happened. + */ + refcnt = self->ob_refcnt; + _Py_NewReference(self); + self->ob_refcnt = refcnt; + + _PyObject_ASSERT(self, + (!PyType_IS_GC(Py_TYPE(self)) + || _PyObject_GC_IS_TRACKED(self))); + /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so + * we need to undo that. */ + _Py_DEC_REFTOTAL; + /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object + * chain, so no more to do there. + * If COUNT_ALLOCS, the original decref bumped tp_frees, and + * _Py_NewReference bumped tp_allocs: both of those need to be + * undone. + */ +#ifdef COUNT_ALLOCS + --Py_TYPE(self)->tp_frees; + --Py_TYPE(self)->tp_allocs; +#endif + return -1; +} + +int +PyObject_Print(PyObject *op, FILE *fp, int flags) +{ + int ret = 0; + if (PyErr_CheckSignals()) + return -1; +#ifdef USE_STACKCHECK + if (PyOS_CheckStack()) { + PyErr_SetString(PyExc_MemoryError, "stack overflow"); + return -1; + } +#endif + clearerr(fp); /* Clear any previous error condition */ + if (op == NULL) { + Py_BEGIN_ALLOW_THREADS + fprintf(fp, ""); + Py_END_ALLOW_THREADS + } + else { + if (op->ob_refcnt <= 0) { + /* XXX(twouters) cast refcount to long until %zd is + universally available */ + Py_BEGIN_ALLOW_THREADS + fprintf(fp, "", + (long)op->ob_refcnt, (void *)op); + Py_END_ALLOW_THREADS + } + else { + PyObject *s; + if (flags & Py_PRINT_RAW) + s = PyObject_Str(op); + else + s = PyObject_Repr(op); + if (s == NULL) + ret = -1; + else if (PyBytes_Check(s)) { + fwrite(PyBytes_AS_STRING(s), 1, + PyBytes_GET_SIZE(s), fp); + } + else if (PyUnicode_Check(s)) { + PyObject *t; + t = PyUnicode_AsEncodedString(s, "utf-8", "backslashreplace"); + if (t == NULL) { + ret = -1; + } + else { + fwrite(PyBytes_AS_STRING(t), 1, + PyBytes_GET_SIZE(t), fp); + Py_DECREF(t); + } + } + else { + PyErr_Format(PyExc_TypeError, + "str() or repr() returned '%.100s'", + s->ob_type->tp_name); + ret = -1; + } + Py_XDECREF(s); + } + } + if (ret == 0) { + if (ferror(fp)) { + PyErr_SetFromErrno(PyExc_OSError); + clearerr(fp); + ret = -1; + } + } + return ret; +} + +/* For debugging convenience. Set a breakpoint here and call it from your DLL */ +void +_Py_BreakPoint(void) +{ +} + + +/* Heuristic checking if the object memory is uninitialized or deallocated. + Rely on the debug hooks on Python memory allocators: + see _PyMem_IsPtrFreed(). + + The function can be used to prevent segmentation fault on dereferencing + pointers like 0xDDDDDDDDDDDDDDDD. */ +int +_PyObject_IsFreed(PyObject *op) +{ + if (_PyMem_IsPtrFreed(op) || _PyMem_IsPtrFreed(op->ob_type)) { + return 1; + } + /* ignore op->ob_ref: its value can have be modified + by Py_INCREF() and Py_DECREF(). */ +#ifdef Py_TRACE_REFS + if (op->_ob_next != NULL && _PyMem_IsPtrFreed(op->_ob_next)) { + return 1; + } + if (op->_ob_prev != NULL && _PyMem_IsPtrFreed(op->_ob_prev)) { + return 1; + } +#endif + return 0; +} + + +/* For debugging convenience. See Misc/gdbinit for some useful gdb hooks */ +void +_PyObject_Dump(PyObject* op) +{ + if (_PyObject_IsFreed(op)) { + /* It seems like the object memory has been freed: + don't access it to prevent a segmentation fault. */ + fprintf(stderr, "\n", op); + fflush(stderr); + return; + } + + /* first, write fields which are the least likely to crash */ + fprintf(stderr, "object address : %p\n", (void *)op); + /* XXX(twouters) cast refcount to long until %zd is + universally available */ + fprintf(stderr, "object refcount : %ld\n", (long)op->ob_refcnt); + fflush(stderr); + + PyTypeObject *type = Py_TYPE(op); + fprintf(stderr, "object type : %p\n", type); + fprintf(stderr, "object type name: %s\n", + type==NULL ? "NULL" : type->tp_name); + + /* the most dangerous part */ + fprintf(stderr, "object repr : "); + fflush(stderr); + + PyGILState_STATE gil = PyGILState_Ensure(); + PyObject *error_type, *error_value, *error_traceback; + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + (void)PyObject_Print(op, stderr, 0); + fflush(stderr); + + PyErr_Restore(error_type, error_value, error_traceback); + PyGILState_Release(gil); + + fprintf(stderr, "\n"); + fflush(stderr); +} + +PyObject * +PyObject_Repr(PyObject *v) +{ + PyObject *res; + if (PyErr_CheckSignals()) + return NULL; +#ifdef USE_STACKCHECK + if (PyOS_CheckStack()) { + PyErr_SetString(PyExc_MemoryError, "stack overflow"); + return NULL; + } +#endif + if (v == NULL) + return PyUnicode_FromString(""); + if (Py_TYPE(v)->tp_repr == NULL) + return PyUnicode_FromFormat("<%s object at %p>", + v->ob_type->tp_name, v); + +#ifdef Py_DEBUG + /* PyObject_Repr() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); +#endif + + /* It is possible for a type to have a tp_repr representation that loops + infinitely. */ + if (Py_EnterRecursiveCall(" while getting the repr of an object")) + return NULL; + res = (*v->ob_type->tp_repr)(v); + Py_LeaveRecursiveCall(); + if (res == NULL) + return NULL; + if (!PyUnicode_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__repr__ returned non-string (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } +#ifndef Py_DEBUG + if (PyUnicode_READY(res) < 0) + return NULL; +#endif + return res; +} + +PyObject * +PyObject_Str(PyObject *v) +{ + PyObject *res; + if (PyErr_CheckSignals()) + return NULL; +#ifdef USE_STACKCHECK + if (PyOS_CheckStack()) { + PyErr_SetString(PyExc_MemoryError, "stack overflow"); + return NULL; + } +#endif + if (v == NULL) + return PyUnicode_FromString(""); + if (PyUnicode_CheckExact(v)) { +#ifndef Py_DEBUG + if (PyUnicode_READY(v) < 0) + return NULL; +#endif + Py_INCREF(v); + return v; + } + if (Py_TYPE(v)->tp_str == NULL) + return PyObject_Repr(v); + +#ifdef Py_DEBUG + /* PyObject_Str() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); +#endif + + /* It is possible for a type to have a tp_str representation that loops + infinitely. */ + if (Py_EnterRecursiveCall(" while getting the str of an object")) + return NULL; + res = (*Py_TYPE(v)->tp_str)(v); + Py_LeaveRecursiveCall(); + if (res == NULL) + return NULL; + if (!PyUnicode_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__str__ returned non-string (type %.200s)", + Py_TYPE(res)->tp_name); + Py_DECREF(res); + return NULL; + } +#ifndef Py_DEBUG + if (PyUnicode_READY(res) < 0) + return NULL; +#endif + assert(_PyUnicode_CheckConsistency(res, 1)); + return res; +} + +PyObject * +PyObject_ASCII(PyObject *v) +{ + PyObject *repr, *ascii, *res; + + repr = PyObject_Repr(v); + if (repr == NULL) + return NULL; + + if (PyUnicode_IS_ASCII(repr)) + return repr; + + /* repr is guaranteed to be a PyUnicode object by PyObject_Repr */ + ascii = _PyUnicode_AsASCIIString(repr, "backslashreplace"); + Py_DECREF(repr); + if (ascii == NULL) + return NULL; + + res = PyUnicode_DecodeASCII( + PyBytes_AS_STRING(ascii), + PyBytes_GET_SIZE(ascii), + NULL); + + Py_DECREF(ascii); + return res; +} + +PyObject * +PyObject_Bytes(PyObject *v) +{ + PyObject *result, *func; + + if (v == NULL) + return PyBytes_FromString(""); + + if (PyBytes_CheckExact(v)) { + Py_INCREF(v); + return v; + } + + func = _PyObject_LookupSpecial(v, &PyId___bytes__); + if (func != NULL) { + result = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (result == NULL) + return NULL; + if (!PyBytes_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__bytes__ returned non-bytes (type %.200s)", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + return result; + } + else if (PyErr_Occurred()) + return NULL; + return PyBytes_FromObject(v); +} + +/* For Python 3.0.1 and later, the old three-way comparison has been + completely removed in favour of rich comparisons. PyObject_Compare() and + PyObject_Cmp() are gone, and the builtin cmp function no longer exists. + The old tp_compare slot has been renamed to tp_as_async, and should no + longer be used. Use tp_richcompare instead. + + See (*) below for practical amendments. + + tp_richcompare gets called with a first argument of the appropriate type + and a second object of an arbitrary type. We never do any kind of + coercion. + + The tp_richcompare slot should return an object, as follows: + + NULL if an exception occurred + NotImplemented if the requested comparison is not implemented + any other false value if the requested comparison is false + any other true value if the requested comparison is true + + The PyObject_RichCompare[Bool]() wrappers raise TypeError when they get + NotImplemented. + + (*) Practical amendments: + + - If rich comparison returns NotImplemented, == and != are decided by + comparing the object pointer (i.e. falling back to the base object + implementation). + +*/ + +/* Map rich comparison operators to their swapped version, e.g. LT <--> GT */ +int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE}; + +static const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="}; + +/* Perform a rich comparison, raising TypeError when the requested comparison + operator is not supported. */ +static PyObject * +do_richcompare(PyObject *v, PyObject *w, int op) +{ + richcmpfunc f; + PyObject *res; + int checked_reverse_op = 0; + + if (v->ob_type != w->ob_type && + PyType_IsSubtype(w->ob_type, v->ob_type) && + (f = w->ob_type->tp_richcompare) != NULL) { + checked_reverse_op = 1; + res = (*f)(w, v, _Py_SwappedOp[op]); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } + if ((f = v->ob_type->tp_richcompare) != NULL) { + res = (*f)(v, w, op); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } + if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) { + res = (*f)(w, v, _Py_SwappedOp[op]); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } + /* If neither object implements it, provide a sensible default + for == and !=, but raise an exception for ordering. */ + switch (op) { + case Py_EQ: + res = (v == w) ? Py_True : Py_False; + break; + case Py_NE: + res = (v != w) ? Py_True : Py_False; + break; + default: + PyErr_Format(PyExc_TypeError, + "'%s' not supported between instances of '%.100s' and '%.100s'", + opstrings[op], + v->ob_type->tp_name, + w->ob_type->tp_name); + return NULL; + } + Py_INCREF(res); + return res; +} + +/* Perform a rich comparison with object result. This wraps do_richcompare() + with a check for NULL arguments and a recursion check. */ + +PyObject * +PyObject_RichCompare(PyObject *v, PyObject *w, int op) +{ + PyObject *res; + + assert(Py_LT <= op && op <= Py_GE); + if (v == NULL || w == NULL) { + if (!PyErr_Occurred()) + PyErr_BadInternalCall(); + return NULL; + } + if (Py_EnterRecursiveCall(" in comparison")) + return NULL; + res = do_richcompare(v, w, op); + Py_LeaveRecursiveCall(); + return res; +} + +/* Perform a rich comparison with integer result. This wraps + PyObject_RichCompare(), returning -1 for error, 0 for false, 1 for true. */ +int +PyObject_RichCompareBool(PyObject *v, PyObject *w, int op) +{ + PyObject *res; + int ok; + + /* Quick result when objects are the same. + Guarantees that identity implies equality. */ + if (v == w) { + if (op == Py_EQ) + return 1; + else if (op == Py_NE) + return 0; + } + + res = PyObject_RichCompare(v, w, op); + if (res == NULL) + return -1; + if (PyBool_Check(res)) + ok = (res == Py_True); + else + ok = PyObject_IsTrue(res); + Py_DECREF(res); + return ok; +} + +Py_hash_t +PyObject_HashNotImplemented(PyObject *v) +{ + PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", + Py_TYPE(v)->tp_name); + return -1; +} + +Py_hash_t +PyObject_Hash(PyObject *v) +{ + PyTypeObject *tp = Py_TYPE(v); + if (tp->tp_hash != NULL) + return (*tp->tp_hash)(v); + /* To keep to the general practice that inheriting + * solely from object in C code should work without + * an explicit call to PyType_Ready, we implicitly call + * PyType_Ready here and then check the tp_hash slot again + */ + if (tp->tp_dict == NULL) { + if (PyType_Ready(tp) < 0) + return -1; + if (tp->tp_hash != NULL) + return (*tp->tp_hash)(v); + } + /* Otherwise, the object can't be hashed */ + return PyObject_HashNotImplemented(v); +} + +PyObject * +PyObject_GetAttrString(PyObject *v, const char *name) +{ + PyObject *w, *res; + + if (Py_TYPE(v)->tp_getattr != NULL) + return (*Py_TYPE(v)->tp_getattr)(v, (char*)name); + w = PyUnicode_FromString(name); + if (w == NULL) + return NULL; + res = PyObject_GetAttr(v, w); + Py_DECREF(w); + return res; +} + +int +PyObject_HasAttrString(PyObject *v, const char *name) +{ + PyObject *res = PyObject_GetAttrString(v, name); + if (res != NULL) { + Py_DECREF(res); + return 1; + } + PyErr_Clear(); + return 0; +} + +int +PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w) +{ + PyObject *s; + int res; + + if (Py_TYPE(v)->tp_setattr != NULL) + return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w); + s = PyUnicode_InternFromString(name); + if (s == NULL) + return -1; + res = PyObject_SetAttr(v, s, w); + Py_XDECREF(s); + return res; +} + +int +_PyObject_IsAbstract(PyObject *obj) +{ + int res; + PyObject* isabstract; + + if (obj == NULL) + return 0; + + res = _PyObject_LookupAttrId(obj, &PyId___isabstractmethod__, &isabstract); + if (res > 0) { + res = PyObject_IsTrue(isabstract); + Py_DECREF(isabstract); + } + return res; +} + +PyObject * +_PyObject_GetAttrId(PyObject *v, _Py_Identifier *name) +{ + PyObject *result; + PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ + if (!oname) + return NULL; + result = PyObject_GetAttr(v, oname); + return result; +} + +int +_PyObject_HasAttrId(PyObject *v, _Py_Identifier *name) +{ + int result; + PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ + if (!oname) + return -1; + result = PyObject_HasAttr(v, oname); + return result; +} + +int +_PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w) +{ + int result; + PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ + if (!oname) + return -1; + result = PyObject_SetAttr(v, oname, w); + return result; +} + +PyObject * +PyObject_GetAttr(PyObject *v, PyObject *name) +{ + PyTypeObject *tp = Py_TYPE(v); + + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return NULL; + } + if (tp->tp_getattro != NULL) + return (*tp->tp_getattro)(v, name); + if (tp->tp_getattr != NULL) { + const char *name_str = PyUnicode_AsUTF8(name); + if (name_str == NULL) + return NULL; + return (*tp->tp_getattr)(v, (char *)name_str); + } + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); + return NULL; +} + +int +_PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result) +{ + PyTypeObject *tp = Py_TYPE(v); + + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + *result = NULL; + return -1; + } + + if (tp->tp_getattro == PyObject_GenericGetAttr) { + *result = _PyObject_GenericGetAttrWithDict(v, name, NULL, 1); + if (*result != NULL) { + return 1; + } + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + if (tp->tp_getattro != NULL) { + *result = (*tp->tp_getattro)(v, name); + } + else if (tp->tp_getattr != NULL) { + const char *name_str = PyUnicode_AsUTF8(name); + if (name_str == NULL) { + *result = NULL; + return -1; + } + *result = (*tp->tp_getattr)(v, (char *)name_str); + } + else { + *result = NULL; + return 0; + } + + if (*result != NULL) { + return 1; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + return -1; + } + PyErr_Clear(); + return 0; +} + +int +_PyObject_LookupAttrId(PyObject *v, _Py_Identifier *name, PyObject **result) +{ + PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ + if (!oname) { + *result = NULL; + return -1; + } + return _PyObject_LookupAttr(v, oname, result); +} + +int +PyObject_HasAttr(PyObject *v, PyObject *name) +{ + PyObject *res; + if (_PyObject_LookupAttr(v, name, &res) < 0) { + PyErr_Clear(); + return 0; + } + if (res == NULL) { + return 0; + } + Py_DECREF(res); + return 1; +} + +int +PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) +{ + PyTypeObject *tp = Py_TYPE(v); + int err; + + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return -1; + } + Py_INCREF(name); + + PyUnicode_InternInPlace(&name); + if (tp->tp_setattro != NULL) { + err = (*tp->tp_setattro)(v, name, value); + Py_DECREF(name); + return err; + } + if (tp->tp_setattr != NULL) { + const char *name_str = PyUnicode_AsUTF8(name); + if (name_str == NULL) { + Py_DECREF(name); + return -1; + } + err = (*tp->tp_setattr)(v, (char *)name_str, value); + Py_DECREF(name); + return err; + } + Py_DECREF(name); + _PyObject_ASSERT(name, name->ob_refcnt >= 1); + if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) + PyErr_Format(PyExc_TypeError, + "'%.100s' object has no attributes " + "(%s .%U)", + tp->tp_name, + value==NULL ? "del" : "assign to", + name); + else + PyErr_Format(PyExc_TypeError, + "'%.100s' object has only read-only attributes " + "(%s .%U)", + tp->tp_name, + value==NULL ? "del" : "assign to", + name); + return -1; +} + +/* Helper to get a pointer to an object's __dict__ slot, if any */ + +PyObject ** +_PyObject_GetDictPtr(PyObject *obj) +{ + Py_ssize_t dictoffset; + PyTypeObject *tp = Py_TYPE(obj); + + dictoffset = tp->tp_dictoffset; + if (dictoffset == 0) + return NULL; + if (dictoffset < 0) { + Py_ssize_t tsize; + size_t size; + + tsize = ((PyVarObject *)obj)->ob_size; + if (tsize < 0) + tsize = -tsize; + size = _PyObject_VAR_SIZE(tp, tsize); + + dictoffset += (long)size; + _PyObject_ASSERT(obj, dictoffset > 0); + _PyObject_ASSERT(obj, dictoffset % SIZEOF_VOID_P == 0); + } + return (PyObject **) ((char *)obj + dictoffset); +} + +PyObject * +PyObject_SelfIter(PyObject *obj) +{ + Py_INCREF(obj); + return obj; +} + +/* Helper used when the __next__ method is removed from a type: + tp_iternext is never NULL and can be safely called without checking + on every iteration. + */ + +PyObject * +_PyObject_NextNotImplemented(PyObject *self) +{ + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not iterable", + Py_TYPE(self)->tp_name); + return NULL; +} + + +/* Specialized version of _PyObject_GenericGetAttrWithDict + specifically for the LOAD_METHOD opcode. + + Return 1 if a method is found, 0 if it's a regular attribute + from __dict__ or something returned by using a descriptor + protocol. + + `method` will point to the resolved attribute or NULL. In the + latter case, an error will be set. +*/ +int +_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) +{ + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + PyObject *attr; + int meth_found = 0; + + assert(*method == NULL); + + if (Py_TYPE(obj)->tp_getattro != PyObject_GenericGetAttr + || !PyUnicode_Check(name)) { + *method = PyObject_GetAttr(obj, name); + return 0; + } + + if (tp->tp_dict == NULL && PyType_Ready(tp) < 0) + return 0; + + descr = _PyType_Lookup(tp, name); + if (descr != NULL) { + Py_INCREF(descr); + if (PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) { + meth_found = 1; + } else { + f = descr->ob_type->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + *method = f(descr, obj, (PyObject *)obj->ob_type); + Py_DECREF(descr); + return 0; + } + } + } + + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = PyDict_GetItemWithError(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + *method = attr; + Py_DECREF(dict); + Py_XDECREF(descr); + return 0; + } + else { + Py_DECREF(dict); + if (PyErr_Occurred()) { + Py_XDECREF(descr); + return 0; + } + } + } + + if (meth_found) { + *method = descr; + return 1; + } + + if (f != NULL) { + *method = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + return 0; + } + + if (descr != NULL) { + *method = descr; + return 0; + } + + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); + return 0; +} + +/* Generic GetAttr functions - put these in your tp_[gs]etattro slot. */ + +PyObject * +_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, + PyObject *dict, int suppress) +{ + /* Make sure the logic of _PyObject_GetMethod is in sync with + this method. + + When suppress=1, this function suppress AttributeError. + */ + + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr = NULL; + PyObject *res = NULL; + descrgetfunc f; + Py_ssize_t dictoffset; + PyObject **dictptr; + + if (!PyUnicode_Check(name)){ + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return NULL; + } + Py_INCREF(name); + + if (tp->tp_dict == NULL) { + if (PyType_Ready(tp) < 0) + goto done; + } + + descr = _PyType_Lookup(tp, name); + + f = NULL; + if (descr != NULL) { + Py_INCREF(descr); + f = descr->ob_type->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + res = f(descr, obj, (PyObject *)obj->ob_type); + if (res == NULL && suppress && + PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + goto done; + } + } + + if (dict == NULL) { + /* Inline _PyObject_GetDictPtr */ + dictoffset = tp->tp_dictoffset; + if (dictoffset != 0) { + if (dictoffset < 0) { + Py_ssize_t tsize; + size_t size; + + tsize = ((PyVarObject *)obj)->ob_size; + if (tsize < 0) + tsize = -tsize; + size = _PyObject_VAR_SIZE(tp, tsize); + _PyObject_ASSERT(obj, size <= PY_SSIZE_T_MAX); + + dictoffset += (Py_ssize_t)size; + _PyObject_ASSERT(obj, dictoffset > 0); + _PyObject_ASSERT(obj, dictoffset % SIZEOF_VOID_P == 0); + } + dictptr = (PyObject **) ((char *)obj + dictoffset); + dict = *dictptr; + } + } + if (dict != NULL) { + Py_INCREF(dict); + res = PyDict_GetItemWithError(dict, name); + if (res != NULL) { + Py_INCREF(res); + Py_DECREF(dict); + goto done; + } + else { + Py_DECREF(dict); + if (PyErr_Occurred()) { + if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + else { + goto done; + } + } + } + } + + if (f != NULL) { + res = f(descr, obj, (PyObject *)Py_TYPE(obj)); + if (res == NULL && suppress && + PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + goto done; + } + + if (descr != NULL) { + res = descr; + descr = NULL; + goto done; + } + + if (!suppress) { + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); + } + done: + Py_XDECREF(descr); + Py_DECREF(name); + return res; +} + +PyObject * +PyObject_GenericGetAttr(PyObject *obj, PyObject *name) +{ + return _PyObject_GenericGetAttrWithDict(obj, name, NULL, 0); +} + +int +_PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, + PyObject *value, PyObject *dict) +{ + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrsetfunc f; + PyObject **dictptr; + int res = -1; + + if (!PyUnicode_Check(name)){ + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return -1; + } + + if (tp->tp_dict == NULL && PyType_Ready(tp) < 0) + return -1; + + Py_INCREF(name); + + descr = _PyType_Lookup(tp, name); + + if (descr != NULL) { + Py_INCREF(descr); + f = descr->ob_type->tp_descr_set; + if (f != NULL) { + res = f(descr, obj, value); + goto done; + } + } + + /* XXX [Steve Dower] These are really noisy - worth it? */ + /*if (PyType_Check(obj) || PyModule_Check(obj)) { + if (value && PySys_Audit("object.__setattr__", "OOO", obj, name, value) < 0) + return -1; + if (!value && PySys_Audit("object.__delattr__", "OO", obj, name) < 0) + return -1; + }*/ + + if (dict == NULL) { + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr == NULL) { + if (descr == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); + } + else { + PyErr_Format(PyExc_AttributeError, + "'%.50s' object attribute '%U' is read-only", + tp->tp_name, name); + } + goto done; + } + res = _PyObjectDict_SetItem(tp, dictptr, name, value); + } + else { + Py_INCREF(dict); + if (value == NULL) + res = PyDict_DelItem(dict, name); + else + res = PyDict_SetItem(dict, name, value); + Py_DECREF(dict); + } + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetObject(PyExc_AttributeError, name); + + done: + Py_XDECREF(descr); + Py_DECREF(name); + return res; +} + +int +PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) +{ + return _PyObject_GenericSetAttrWithDict(obj, name, value, NULL); +} + +int +PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) +{ + PyObject **dictptr = _PyObject_GetDictPtr(obj); + if (dictptr == NULL) { + PyErr_SetString(PyExc_AttributeError, + "This object has no __dict__"); + return -1; + } + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "cannot delete __dict__"); + return -1; + } + if (!PyDict_Check(value)) { + PyErr_Format(PyExc_TypeError, + "__dict__ must be set to a dictionary, " + "not a '%.200s'", Py_TYPE(value)->tp_name); + return -1; + } + Py_INCREF(value); + Py_XSETREF(*dictptr, value); + return 0; +} + + +/* Test a value used as condition, e.g., in a for or if statement. + Return -1 if an error occurred */ + +int +PyObject_IsTrue(PyObject *v) +{ + Py_ssize_t res; + if (v == Py_True) + return 1; + if (v == Py_False) + return 0; + if (v == Py_None) + return 0; + else if (v->ob_type->tp_as_number != NULL && + v->ob_type->tp_as_number->nb_bool != NULL) + res = (*v->ob_type->tp_as_number->nb_bool)(v); + else if (v->ob_type->tp_as_mapping != NULL && + v->ob_type->tp_as_mapping->mp_length != NULL) + res = (*v->ob_type->tp_as_mapping->mp_length)(v); + else if (v->ob_type->tp_as_sequence != NULL && + v->ob_type->tp_as_sequence->sq_length != NULL) + res = (*v->ob_type->tp_as_sequence->sq_length)(v); + else + return 1; + /* if it is negative, it should be either -1 or -2 */ + return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int); +} + +/* equivalent of 'not v' + Return -1 if an error occurred */ + +int +PyObject_Not(PyObject *v) +{ + int res; + res = PyObject_IsTrue(v); + if (res < 0) + return res; + return res == 0; +} + +/* Test whether an object can be called */ + +int +PyCallable_Check(PyObject *x) +{ + if (x == NULL) + return 0; + return x->ob_type->tp_call != NULL; +} + + +/* Helper for PyObject_Dir without arguments: returns the local scope. */ +static PyObject * +_dir_locals(void) +{ + PyObject *names; + PyObject *locals; + + locals = PyEval_GetLocals(); + if (locals == NULL) + return NULL; + + names = PyMapping_Keys(locals); + if (!names) + return NULL; + if (!PyList_Check(names)) { + PyErr_Format(PyExc_TypeError, + "dir(): expected keys() of locals to be a list, " + "not '%.200s'", Py_TYPE(names)->tp_name); + Py_DECREF(names); + return NULL; + } + if (PyList_Sort(names)) { + Py_DECREF(names); + return NULL; + } + /* the locals don't need to be DECREF'd */ + return names; +} + +/* Helper for PyObject_Dir: object introspection. */ +static PyObject * +_dir_object(PyObject *obj) +{ + PyObject *result, *sorted; + PyObject *dirfunc = _PyObject_LookupSpecial(obj, &PyId___dir__); + + assert(obj != NULL); + if (dirfunc == NULL) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, "object does not provide __dir__"); + return NULL; + } + /* use __dir__ */ + result = _PyObject_CallNoArg(dirfunc); + Py_DECREF(dirfunc); + if (result == NULL) + return NULL; + /* return sorted(result) */ + sorted = PySequence_List(result); + Py_DECREF(result); + if (sorted == NULL) + return NULL; + if (PyList_Sort(sorted)) { + Py_DECREF(sorted); + return NULL; + } + return sorted; +} + +/* Implementation of dir() -- if obj is NULL, returns the names in the current + (local) scope. Otherwise, performs introspection of the object: returns a + sorted list of attribute names (supposedly) accessible from the object +*/ +PyObject * +PyObject_Dir(PyObject *obj) +{ + return (obj == NULL) ? _dir_locals() : _dir_object(obj); +} + +/* +None is a non-NULL undefined value. +There is (and should be!) no way to create other objects of this type, +so there is exactly one (which is indestructible, by the way). +*/ + +/* ARGSUSED */ +static PyObject * +none_repr(PyObject *op) +{ + return PyUnicode_FromString("None"); +} + +/* ARGUSED */ +static void +none_dealloc(PyObject* ignore) +{ + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref None out of existence. + */ + Py_FatalError("deallocating None"); +} + +static PyObject * +none_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { + PyErr_SetString(PyExc_TypeError, "NoneType takes no arguments"); + return NULL; + } + Py_RETURN_NONE; +} + +static int +none_bool(PyObject *v) +{ + return 0; +} + +static PyNumberMethods none_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)none_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 */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ +}; + +PyTypeObject _PyNone_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "NoneType", + 0, + 0, + none_dealloc, /*tp_dealloc*/ /*never called*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + none_repr, /*tp_repr*/ + &none_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 */ + 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 */ + 0, /*tp_init */ + 0, /*tp_alloc */ + none_new, /*tp_new */ +}; + +PyObject _Py_NoneStruct = { + _PyObject_EXTRA_INIT + 1, &_PyNone_Type +}; + +/* NotImplemented is an object that can be used to signal that an + operation is not implemented for the given type combination. */ + +static PyObject * +NotImplemented_repr(PyObject *op) +{ + return PyUnicode_FromString("NotImplemented"); +} + +static PyObject * +NotImplemented_reduce(PyObject *op, PyObject *Py_UNUSED(ignored)) +{ + return PyUnicode_FromString("NotImplemented"); +} + +static PyMethodDef notimplemented_methods[] = { + {"__reduce__", NotImplemented_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +static PyObject * +notimplemented_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { + PyErr_SetString(PyExc_TypeError, "NotImplementedType takes no arguments"); + return NULL; + } + Py_RETURN_NOTIMPLEMENTED; +} + +static void +notimplemented_dealloc(PyObject* ignore) +{ + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref NotImplemented out of existence. + */ + Py_FatalError("deallocating NotImplemented"); +} + +PyTypeObject _PyNotImplemented_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "NotImplementedType", + 0, + 0, + notimplemented_dealloc, /*tp_dealloc*/ /*never called*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + NotImplemented_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 */ + notimplemented_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 */ + notimplemented_new, /*tp_new */ +}; + +PyObject _Py_NotImplementedStruct = { + _PyObject_EXTRA_INIT + 1, &_PyNotImplemented_Type +}; + +PyStatus +_PyTypes_Init(void) +{ +#define INIT_TYPE(TYPE, NAME) \ + do { \ + if (PyType_Ready(TYPE) < 0) { \ + return _PyStatus_ERR("Can't initialize " NAME " type"); \ + } \ + } while (0) + + INIT_TYPE(&PyBaseObject_Type, "object"); + INIT_TYPE(&PyType_Type, "type"); + INIT_TYPE(&_PyWeakref_RefType, "weakref"); + INIT_TYPE(&_PyWeakref_CallableProxyType, "callable weakref proxy"); + INIT_TYPE(&_PyWeakref_ProxyType, "weakref proxy"); + INIT_TYPE(&PyLong_Type, "int"); + INIT_TYPE(&PyBool_Type, "bool"); + INIT_TYPE(&PyByteArray_Type, "bytearray"); + INIT_TYPE(&PyBytes_Type, "str"); + INIT_TYPE(&PyList_Type, "list"); + INIT_TYPE(&_PyNone_Type, "None"); + INIT_TYPE(&_PyNotImplemented_Type, "NotImplemented"); + INIT_TYPE(&PyTraceBack_Type, "traceback"); + INIT_TYPE(&PySuper_Type, "super"); + INIT_TYPE(&PyRange_Type, "range"); + INIT_TYPE(&PyDict_Type, "dict"); + INIT_TYPE(&PyDictKeys_Type, "dict keys"); + INIT_TYPE(&PyDictValues_Type, "dict values"); + INIT_TYPE(&PyDictItems_Type, "dict items"); + INIT_TYPE(&PyDictRevIterKey_Type, "reversed dict keys"); + INIT_TYPE(&PyDictRevIterValue_Type, "reversed dict values"); + INIT_TYPE(&PyDictRevIterItem_Type, "reversed dict items"); + INIT_TYPE(&PyODict_Type, "OrderedDict"); + INIT_TYPE(&PyODictKeys_Type, "odict_keys"); + INIT_TYPE(&PyODictItems_Type, "odict_items"); + INIT_TYPE(&PyODictValues_Type, "odict_values"); + INIT_TYPE(&PyODictIter_Type, "odict_keyiterator"); + INIT_TYPE(&PySet_Type, "set"); + INIT_TYPE(&PyUnicode_Type, "str"); + INIT_TYPE(&PySlice_Type, "slice"); + INIT_TYPE(&PyStaticMethod_Type, "static method"); + INIT_TYPE(&PyComplex_Type, "complex"); + INIT_TYPE(&PyFloat_Type, "float"); + INIT_TYPE(&PyFrozenSet_Type, "frozenset"); + INIT_TYPE(&PyProperty_Type, "property"); + INIT_TYPE(&_PyManagedBuffer_Type, "managed buffer"); + INIT_TYPE(&PyMemoryView_Type, "memoryview"); + INIT_TYPE(&PyTuple_Type, "tuple"); + INIT_TYPE(&PyEnum_Type, "enumerate"); + INIT_TYPE(&PyReversed_Type, "reversed"); + INIT_TYPE(&PyStdPrinter_Type, "StdPrinter"); + INIT_TYPE(&PyCode_Type, "code"); + INIT_TYPE(&PyFrame_Type, "frame"); + INIT_TYPE(&PyCFunction_Type, "builtin function"); + INIT_TYPE(&PyMethod_Type, "method"); + INIT_TYPE(&PyFunction_Type, "function"); + INIT_TYPE(&PyDictProxy_Type, "dict proxy"); + INIT_TYPE(&PyGen_Type, "generator"); + INIT_TYPE(&PyGetSetDescr_Type, "get-set descriptor"); + INIT_TYPE(&PyWrapperDescr_Type, "wrapper"); + INIT_TYPE(&_PyMethodWrapper_Type, "method wrapper"); + INIT_TYPE(&PyEllipsis_Type, "ellipsis"); + INIT_TYPE(&PyMemberDescr_Type, "member descriptor"); + INIT_TYPE(&_PyNamespace_Type, "namespace"); + INIT_TYPE(&PyCapsule_Type, "capsule"); + INIT_TYPE(&PyLongRangeIter_Type, "long range iterator"); + INIT_TYPE(&PyCell_Type, "cell"); + INIT_TYPE(&PyInstanceMethod_Type, "instance method"); + INIT_TYPE(&PyClassMethodDescr_Type, "class method descr"); + INIT_TYPE(&PyMethodDescr_Type, "method descr"); + INIT_TYPE(&PyCallIter_Type, "call iter"); + INIT_TYPE(&PySeqIter_Type, "sequence iterator"); + INIT_TYPE(&PyPickleBuffer_Type, "pickle.PickleBuffer"); + INIT_TYPE(&PyCoro_Type, "coroutine"); + INIT_TYPE(&_PyCoroWrapper_Type, "coroutine wrapper"); + INIT_TYPE(&_PyInterpreterID_Type, "interpreter ID"); + return _PyStatus_OK(); + +#undef INIT_TYPE +} + + +#ifdef Py_TRACE_REFS + +void +_Py_NewReference(PyObject *op) +{ + if (_Py_tracemalloc_config.tracing) { + _PyTraceMalloc_NewReference(op); + } + _Py_INC_REFTOTAL; + op->ob_refcnt = 1; + _Py_AddToAllObjects(op, 1); + _Py_INC_TPALLOCS(op); +} + +void +_Py_ForgetReference(PyObject *op) +{ +#ifdef SLOW_UNREF_CHECK + PyObject *p; +#endif + if (op->ob_refcnt < 0) + Py_FatalError("UNREF negative refcnt"); + if (op == &refchain || + op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) { + fprintf(stderr, "* ob\n"); + _PyObject_Dump(op); + fprintf(stderr, "* op->_ob_prev->_ob_next\n"); + _PyObject_Dump(op->_ob_prev->_ob_next); + fprintf(stderr, "* op->_ob_next->_ob_prev\n"); + _PyObject_Dump(op->_ob_next->_ob_prev); + Py_FatalError("UNREF invalid object"); + } +#ifdef SLOW_UNREF_CHECK + for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) { + if (p == op) + break; + } + if (p == &refchain) /* Not found */ + Py_FatalError("UNREF unknown object"); +#endif + op->_ob_next->_ob_prev = op->_ob_prev; + op->_ob_prev->_ob_next = op->_ob_next; + op->_ob_next = op->_ob_prev = NULL; + _Py_INC_TPFREES(op); +} + +/* Print all live objects. Because PyObject_Print is called, the + * interpreter must be in a healthy state. + */ +void +_Py_PrintReferences(FILE *fp) +{ + PyObject *op; + fprintf(fp, "Remaining objects:\n"); + for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { + fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, op->ob_refcnt); + if (PyObject_Print(op, fp, 0) != 0) + PyErr_Clear(); + putc('\n', fp); + } +} + +/* Print the addresses of all live objects. Unlike _Py_PrintReferences, this + * doesn't make any calls to the Python C API, so is always safe to call. + */ +void +_Py_PrintReferenceAddresses(FILE *fp) +{ + PyObject *op; + fprintf(fp, "Remaining object addresses:\n"); + for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) + fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", (void *)op, + op->ob_refcnt, Py_TYPE(op)->tp_name); +} + +PyObject * +_Py_GetObjects(PyObject *self, PyObject *args) +{ + int i, n; + PyObject *t = NULL; + PyObject *res, *op; + + if (!PyArg_ParseTuple(args, "i|O", &n, &t)) + return NULL; + op = refchain._ob_next; + res = PyList_New(0); + if (res == NULL) + return NULL; + for (i = 0; (n == 0 || i < n) && op != &refchain; i++) { + while (op == self || op == args || op == res || op == t || + (t != NULL && Py_TYPE(op) != (PyTypeObject *) t)) { + op = op->_ob_next; + if (op == &refchain) + return res; + } + if (PyList_Append(res, op) < 0) { + Py_DECREF(res); + return NULL; + } + op = op->_ob_next; + } + return res; +} + +#endif + + +/* Hack to force loading of abstract.o */ +Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size; + + +void +_PyObject_DebugTypeStats(FILE *out) +{ + _PyCFunction_DebugMallocStats(out); + _PyDict_DebugMallocStats(out); + _PyFloat_DebugMallocStats(out); + _PyFrame_DebugMallocStats(out); + _PyList_DebugMallocStats(out); + _PyMethod_DebugMallocStats(out); + _PyTuple_DebugMallocStats(out); +} + +/* These methods are used to control infinite recursion in repr, str, print, + etc. Container objects that may recursively contain themselves, + e.g. builtin dictionaries and lists, should use Py_ReprEnter() and + Py_ReprLeave() to avoid infinite recursion. + + Py_ReprEnter() returns 0 the first time it is called for a particular + object and 1 every time thereafter. It returns -1 if an exception + occurred. Py_ReprLeave() has no return value. + + See dictobject.c and listobject.c for examples of use. +*/ + +int +Py_ReprEnter(PyObject *obj) +{ + PyObject *dict; + PyObject *list; + Py_ssize_t i; + + dict = PyThreadState_GetDict(); + /* Ignore a missing thread-state, so that this function can be called + early on startup. */ + if (dict == NULL) + return 0; + list = _PyDict_GetItemIdWithError(dict, &PyId_Py_Repr); + if (list == NULL) { + if (PyErr_Occurred()) { + return -1; + } + list = PyList_New(0); + if (list == NULL) + return -1; + if (_PyDict_SetItemId(dict, &PyId_Py_Repr, list) < 0) + return -1; + Py_DECREF(list); + } + i = PyList_GET_SIZE(list); + while (--i >= 0) { + if (PyList_GET_ITEM(list, i) == obj) + return 1; + } + if (PyList_Append(list, obj) < 0) + return -1; + return 0; +} + +void +Py_ReprLeave(PyObject *obj) +{ + PyObject *dict; + PyObject *list; + Py_ssize_t i; + PyObject *error_type, *error_value, *error_traceback; + + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + dict = PyThreadState_GetDict(); + if (dict == NULL) + goto finally; + + list = _PyDict_GetItemIdWithError(dict, &PyId_Py_Repr); + if (list == NULL || !PyList_Check(list)) + goto finally; + + i = PyList_GET_SIZE(list); + /* Count backwards because we always expect obj to be list[-1] */ + while (--i >= 0) { + if (PyList_GET_ITEM(list, i) == obj) { + PyList_SetSlice(list, i, i + 1, NULL); + break; + } + } + +finally: + /* ignore exceptions because there is no way to report them. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +/* Trashcan support. */ + +/* Add op to the _PyTrash_delete_later list. Called when the current + * call-stack depth gets large. op must be a currently untracked gc'ed + * object, with refcount 0. Py_DECREF must already have been called on it. + */ +void +_PyTrash_deposit_object(PyObject *op) +{ + _PyObject_ASSERT(op, PyObject_IS_GC(op)); + _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); + _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyGCHead_SET_PREV(_Py_AS_GC(op), _PyRuntime.gc.trash_delete_later); + _PyRuntime.gc.trash_delete_later = op; +} + +/* The equivalent API, using per-thread state recursion info */ +void +_PyTrash_thread_deposit_object(PyObject *op) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyObject_ASSERT(op, PyObject_IS_GC(op)); + _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); + _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later); + tstate->trash_delete_later = op; +} + +/* Dealloccate all the objects in the _PyTrash_delete_later list. Called when + * the call-stack unwinds again. + */ +void +_PyTrash_destroy_chain(void) +{ + while (_PyRuntime.gc.trash_delete_later) { + PyObject *op = _PyRuntime.gc.trash_delete_later; + destructor dealloc = Py_TYPE(op)->tp_dealloc; + + _PyRuntime.gc.trash_delete_later = + (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op)); + + /* Call the deallocator directly. This used to try to + * fool Py_DECREF into calling it indirectly, but + * Py_DECREF was already called on this object, and in + * assorted non-release builds calling Py_DECREF again ends + * up distorting allocation statistics. + */ + _PyObject_ASSERT(op, op->ob_refcnt == 0); + ++_PyRuntime.gc.trash_delete_nesting; + (*dealloc)(op); + --_PyRuntime.gc.trash_delete_nesting; + } +} + +/* The equivalent API, using per-thread state recursion info */ +void +_PyTrash_thread_destroy_chain(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + /* We need to increase trash_delete_nesting here, otherwise, + _PyTrash_thread_destroy_chain will be called recursively + and then possibly crash. An example that may crash without + increase: + N = 500000 # need to be large enough + ob = object() + tups = [(ob,) for i in range(N)] + for i in range(49): + tups = [(tup,) for tup in tups] + del tups + */ + assert(tstate->trash_delete_nesting == 0); + ++tstate->trash_delete_nesting; + while (tstate->trash_delete_later) { + PyObject *op = tstate->trash_delete_later; + destructor dealloc = Py_TYPE(op)->tp_dealloc; + + tstate->trash_delete_later = + (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op)); + + /* Call the deallocator directly. This used to try to + * fool Py_DECREF into calling it indirectly, but + * Py_DECREF was already called on this object, and in + * assorted non-release builds calling Py_DECREF again ends + * up distorting allocation statistics. + */ + _PyObject_ASSERT(op, op->ob_refcnt == 0); + (*dealloc)(op); + assert(tstate->trash_delete_nesting == 1); + } + --tstate->trash_delete_nesting; +} + + +void +_PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, + const char *file, int line, const char *function) +{ + fprintf(stderr, "%s:%d: ", file, line); + if (function) { + fprintf(stderr, "%s: ", function); + } + fflush(stderr); + + if (expr) { + fprintf(stderr, "Assertion \"%s\" failed", expr); + } + else { + fprintf(stderr, "Assertion failed"); + } + fflush(stderr); + + if (msg) { + fprintf(stderr, ": %s", msg); + } + fprintf(stderr, "\n"); + fflush(stderr); + + if (_PyObject_IsFreed(obj)) { + /* It seems like the object memory has been freed: + don't access it to prevent a segmentation fault. */ + fprintf(stderr, "\n", obj); + fflush(stderr); + } + else { + /* Display the traceback where the object has been allocated. + Do it before dumping repr(obj), since repr() is more likely + to crash than dumping the traceback. */ + void *ptr; + PyTypeObject *type = Py_TYPE(obj); + if (PyType_IS_GC(type)) { + ptr = (void *)((char *)obj - sizeof(PyGC_Head)); + } + else { + ptr = (void *)obj; + } + _PyMem_DumpTraceback(fileno(stderr), ptr); + + /* This might succeed or fail, but we're about to abort, so at least + try to provide any extra info we can: */ + _PyObject_Dump(obj); + + fprintf(stderr, "\n"); + fflush(stderr); + } + + Py_FatalError("_PyObject_AssertFailed"); +} + + +#undef _Py_Dealloc + +void +_Py_Dealloc(PyObject *op) +{ + destructor dealloc = Py_TYPE(op)->tp_dealloc; +#ifdef Py_TRACE_REFS + _Py_ForgetReference(op); +#else + _Py_INC_TPFREES(op); +#endif + (*dealloc)(op); +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Objects/obmalloc.c b/python/Objects/obmalloc.c new file mode 100755 index 0000000..c483ff3 --- /dev/null +++ b/python/Objects/obmalloc.c @@ -0,0 +1,2722 @@ +#include "Python.h" +#include "pycore_pymem.h" + +#include + + +/* Defined in tracemalloc.c */ +extern void _PyMem_DumpTraceback(int fd, const void *ptr); + + +/* Python's malloc wrappers (see pymem.h) */ + +#undef uint +#define uint unsigned int /* assuming >= 16 bits */ + +/* Forward declaration */ +static void* _PyMem_DebugRawMalloc(void *ctx, size_t size); +static void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize); +static void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size); +static void _PyMem_DebugRawFree(void *ctx, void *ptr); + +static void* _PyMem_DebugMalloc(void *ctx, size_t size); +static void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); +static void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); +static void _PyMem_DebugFree(void *ctx, void *p); + +static void _PyObject_DebugDumpAddress(const void *p); +static void _PyMem_DebugCheckAddress(char api_id, const void *p); + +static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain); + +#if defined(__has_feature) /* Clang */ +# if __has_feature(address_sanitizer) /* is ASAN enabled? */ +# define _Py_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize("address"))) +# endif +# if __has_feature(thread_sanitizer) /* is TSAN enabled? */ +# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +# endif +# if __has_feature(memory_sanitizer) /* is MSAN enabled? */ +# define _Py_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +# endif +#elif defined(__GNUC__) +# if defined(__SANITIZE_ADDRESS__) /* GCC 4.8+, is ASAN enabled? */ +# define _Py_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize_address)) +# endif + // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro + // is provided only since GCC 7. +# if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) +# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +# endif +#endif + +#ifndef _Py_NO_SANITIZE_ADDRESS +# define _Py_NO_SANITIZE_ADDRESS +#endif +#ifndef _Py_NO_SANITIZE_THREAD +# define _Py_NO_SANITIZE_THREAD +#endif +#ifndef _Py_NO_SANITIZE_MEMORY +# define _Py_NO_SANITIZE_MEMORY +#endif + +#ifdef WITH_PYMALLOC + +#ifdef MS_WINDOWS +# include +#elif defined(HAVE_MMAP) +# include +# ifdef MAP_ANONYMOUS +# define ARENAS_USE_MMAP +# endif +#endif + +/* Forward declaration */ +static void* _PyObject_Malloc(void *ctx, size_t size); +static void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); +static void _PyObject_Free(void *ctx, void *p); +static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); +#endif + + +/* bpo-35053: Declare tracemalloc configuration here rather than + Modules/_tracemalloc.c because _tracemalloc can be compiled as dynamic + library, whereas _Py_NewReference() requires it. */ +struct _PyTraceMalloc_Config _Py_tracemalloc_config = _PyTraceMalloc_Config_INIT; + + +static void * +_PyMem_RawMalloc(void *ctx, size_t size) +{ + /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL + for malloc(0), which would be treated as an error. Some platforms would + return a pointer with no memory behind it, which would break pymalloc. + To solve these problems, allocate an extra byte. */ + if (size == 0) + size = 1; + return malloc(size); +} + +static void * +_PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) +{ + /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL + for calloc(0, 0), which would be treated as an error. Some platforms + would return a pointer with no memory behind it, which would break + pymalloc. To solve these problems, allocate an extra byte. */ + if (nelem == 0 || elsize == 0) { + nelem = 1; + elsize = 1; + } + return calloc(nelem, elsize); +} + +static void * +_PyMem_RawRealloc(void *ctx, void *ptr, size_t size) +{ + if (size == 0) + size = 1; + return realloc(ptr, size); +} + +static void +_PyMem_RawFree(void *ctx, void *ptr) +{ + free(ptr); +} + + +#ifdef MS_WINDOWS +static void * +_PyObject_ArenaVirtualAlloc(void *ctx, size_t size) +{ + return VirtualAlloc(NULL, size, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +} + +static void +_PyObject_ArenaVirtualFree(void *ctx, void *ptr, size_t size) +{ + VirtualFree(ptr, 0, MEM_RELEASE); +} + +#elif defined(ARENAS_USE_MMAP) +static void * +_PyObject_ArenaMmap(void *ctx, size_t size) +{ + void *ptr; + ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (ptr == MAP_FAILED) + return NULL; + assert(ptr != NULL); + return ptr; +} + +static void +_PyObject_ArenaMunmap(void *ctx, void *ptr, size_t size) +{ + munmap(ptr, size); +} + +#else +static void * +_PyObject_ArenaMalloc(void *ctx, size_t size) +{ + return malloc(size); +} + +static void +_PyObject_ArenaFree(void *ctx, void *ptr, size_t size) +{ + free(ptr); +} +#endif + +#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} +#ifdef WITH_PYMALLOC +# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +#endif + +#define PYRAW_ALLOC MALLOC_ALLOC +#ifdef WITH_PYMALLOC +# define PYOBJ_ALLOC PYMALLOC_ALLOC +#else +# define PYOBJ_ALLOC MALLOC_ALLOC +#endif +#define PYMEM_ALLOC PYOBJ_ALLOC + +typedef struct { + /* We tag each block with an API ID in order to tag API violations */ + char api_id; + PyMemAllocatorEx alloc; +} debug_alloc_api_t; +static struct { + debug_alloc_api_t raw; + debug_alloc_api_t mem; + debug_alloc_api_t obj; +} _PyMem_Debug = { + {'r', PYRAW_ALLOC}, + {'m', PYMEM_ALLOC}, + {'o', PYOBJ_ALLOC} + }; + +#define PYDBGRAW_ALLOC \ + {&_PyMem_Debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} +#define PYDBGMEM_ALLOC \ + {&_PyMem_Debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define PYDBGOBJ_ALLOC \ + {&_PyMem_Debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} + +#ifdef Py_DEBUG +static PyMemAllocatorEx _PyMem_Raw = PYDBGRAW_ALLOC; +static PyMemAllocatorEx _PyMem = PYDBGMEM_ALLOC; +static PyMemAllocatorEx _PyObject = PYDBGOBJ_ALLOC; +#else +static PyMemAllocatorEx _PyMem_Raw = PYRAW_ALLOC; +static PyMemAllocatorEx _PyMem = PYMEM_ALLOC; +static PyMemAllocatorEx _PyObject = PYOBJ_ALLOC; +#endif + + +static int +pymem_set_default_allocator(PyMemAllocatorDomain domain, int debug, + PyMemAllocatorEx *old_alloc) +{ + if (old_alloc != NULL) { + PyMem_GetAllocator(domain, old_alloc); + } + + + PyMemAllocatorEx new_alloc; + switch(domain) + { + case PYMEM_DOMAIN_RAW: + new_alloc = (PyMemAllocatorEx)PYRAW_ALLOC; + break; + case PYMEM_DOMAIN_MEM: + new_alloc = (PyMemAllocatorEx)PYMEM_ALLOC; + break; + case PYMEM_DOMAIN_OBJ: + new_alloc = (PyMemAllocatorEx)PYOBJ_ALLOC; + break; + default: + /* unknown domain */ + return -1; + } + PyMem_SetAllocator(domain, &new_alloc); + if (debug) { + _PyMem_SetupDebugHooksDomain(domain); + } + return 0; +} + + +int +_PyMem_SetDefaultAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *old_alloc) +{ +#ifdef Py_DEBUG + const int debug = 1; +#else + const int debug = 0; +#endif + return pymem_set_default_allocator(domain, debug, old_alloc); +} + + +int +_PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator) +{ + if (name == NULL || *name == '\0') { + /* PYTHONMALLOC is empty or is not set or ignored (-E/-I command line + nameions): use default memory allocators */ + *allocator = PYMEM_ALLOCATOR_DEFAULT; + } + else if (strcmp(name, "default") == 0) { + *allocator = PYMEM_ALLOCATOR_DEFAULT; + } + else if (strcmp(name, "debug") == 0) { + *allocator = PYMEM_ALLOCATOR_DEBUG; + } +#ifdef WITH_PYMALLOC + else if (strcmp(name, "pymalloc") == 0) { + *allocator = PYMEM_ALLOCATOR_PYMALLOC; + } + else if (strcmp(name, "pymalloc_debug") == 0) { + *allocator = PYMEM_ALLOCATOR_PYMALLOC_DEBUG; + } +#endif + else if (strcmp(name, "malloc") == 0) { + *allocator = PYMEM_ALLOCATOR_MALLOC; + } + else if (strcmp(name, "malloc_debug") == 0) { + *allocator = PYMEM_ALLOCATOR_MALLOC_DEBUG; + } + else { + /* unknown allocator */ + return -1; + } + return 0; +} + + +int +_PyMem_SetupAllocators(PyMemAllocatorName allocator) +{ + switch (allocator) { + case PYMEM_ALLOCATOR_NOT_SET: + /* do nothing */ + break; + + case PYMEM_ALLOCATOR_DEFAULT: + (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, NULL); + (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_MEM, NULL); + (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_OBJ, NULL); + break; + + case PYMEM_ALLOCATOR_DEBUG: + (void)pymem_set_default_allocator(PYMEM_DOMAIN_RAW, 1, NULL); + (void)pymem_set_default_allocator(PYMEM_DOMAIN_MEM, 1, NULL); + (void)pymem_set_default_allocator(PYMEM_DOMAIN_OBJ, 1, NULL); + break; + +#ifdef WITH_PYMALLOC + case PYMEM_ALLOCATOR_PYMALLOC: + case PYMEM_ALLOCATOR_PYMALLOC_DEBUG: + { + PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &malloc_alloc); + + PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC; + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &pymalloc); + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &pymalloc); + + if (allocator == PYMEM_ALLOCATOR_PYMALLOC_DEBUG) { + PyMem_SetupDebugHooks(); + } + break; + } +#endif + + case PYMEM_ALLOCATOR_MALLOC: + case PYMEM_ALLOCATOR_MALLOC_DEBUG: + { + PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &malloc_alloc); + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &malloc_alloc); + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &malloc_alloc); + + if (allocator == PYMEM_ALLOCATOR_MALLOC_DEBUG) { + PyMem_SetupDebugHooks(); + } + break; + } + + default: + /* unknown allocator */ + return -1; + } + return 0; +} + + +static int +pymemallocator_eq(PyMemAllocatorEx *a, PyMemAllocatorEx *b) +{ + return (memcmp(a, b, sizeof(PyMemAllocatorEx)) == 0); +} + + +const char* +_PyMem_GetCurrentAllocatorName(void) +{ + PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; +#ifdef WITH_PYMALLOC + PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC; +#endif + + if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) && + pymemallocator_eq(&_PyMem, &malloc_alloc) && + pymemallocator_eq(&_PyObject, &malloc_alloc)) + { + return "malloc"; + } +#ifdef WITH_PYMALLOC + if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) && + pymemallocator_eq(&_PyMem, &pymalloc) && + pymemallocator_eq(&_PyObject, &pymalloc)) + { + return "pymalloc"; + } +#endif + + PyMemAllocatorEx dbg_raw = PYDBGRAW_ALLOC; + PyMemAllocatorEx dbg_mem = PYDBGMEM_ALLOC; + PyMemAllocatorEx dbg_obj = PYDBGOBJ_ALLOC; + + if (pymemallocator_eq(&_PyMem_Raw, &dbg_raw) && + pymemallocator_eq(&_PyMem, &dbg_mem) && + pymemallocator_eq(&_PyObject, &dbg_obj)) + { + /* Debug hooks installed */ + if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) && + pymemallocator_eq(&_PyMem_Debug.mem.alloc, &malloc_alloc) && + pymemallocator_eq(&_PyMem_Debug.obj.alloc, &malloc_alloc)) + { + return "malloc_debug"; + } +#ifdef WITH_PYMALLOC + if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) && + pymemallocator_eq(&_PyMem_Debug.mem.alloc, &pymalloc) && + pymemallocator_eq(&_PyMem_Debug.obj.alloc, &pymalloc)) + { + return "pymalloc_debug"; + } +#endif + } + return NULL; +} + + +#undef MALLOC_ALLOC +#undef PYMALLOC_ALLOC +#undef PYRAW_ALLOC +#undef PYMEM_ALLOC +#undef PYOBJ_ALLOC +#undef PYDBGRAW_ALLOC +#undef PYDBGMEM_ALLOC +#undef PYDBGOBJ_ALLOC + + +static PyObjectArenaAllocator _PyObject_Arena = {NULL, +#ifdef MS_WINDOWS + _PyObject_ArenaVirtualAlloc, _PyObject_ArenaVirtualFree +#elif defined(ARENAS_USE_MMAP) + _PyObject_ArenaMmap, _PyObject_ArenaMunmap +#else + _PyObject_ArenaMalloc, _PyObject_ArenaFree +#endif + }; + +#ifdef WITH_PYMALLOC +static int +_PyMem_DebugEnabled(void) +{ + return (_PyObject.malloc == _PyMem_DebugMalloc); +} + +static int +_PyMem_PymallocEnabled(void) +{ + if (_PyMem_DebugEnabled()) { + return (_PyMem_Debug.obj.alloc.malloc == _PyObject_Malloc); + } + else { + return (_PyObject.malloc == _PyObject_Malloc); + } +} +#endif + + +static void +_PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain) +{ + PyMemAllocatorEx alloc; + + if (domain == PYMEM_DOMAIN_RAW) { + if (_PyMem_Raw.malloc == _PyMem_DebugRawMalloc) { + return; + } + + PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &_PyMem_Debug.raw.alloc); + alloc.ctx = &_PyMem_Debug.raw; + alloc.malloc = _PyMem_DebugRawMalloc; + alloc.calloc = _PyMem_DebugRawCalloc; + alloc.realloc = _PyMem_DebugRawRealloc; + alloc.free = _PyMem_DebugRawFree; + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); + } + else if (domain == PYMEM_DOMAIN_MEM) { + if (_PyMem.malloc == _PyMem_DebugMalloc) { + return; + } + + PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &_PyMem_Debug.mem.alloc); + alloc.ctx = &_PyMem_Debug.mem; + alloc.malloc = _PyMem_DebugMalloc; + alloc.calloc = _PyMem_DebugCalloc; + alloc.realloc = _PyMem_DebugRealloc; + alloc.free = _PyMem_DebugFree; + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); + } + else if (domain == PYMEM_DOMAIN_OBJ) { + if (_PyObject.malloc == _PyMem_DebugMalloc) { + return; + } + + PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &_PyMem_Debug.obj.alloc); + alloc.ctx = &_PyMem_Debug.obj; + alloc.malloc = _PyMem_DebugMalloc; + alloc.calloc = _PyMem_DebugCalloc; + alloc.realloc = _PyMem_DebugRealloc; + alloc.free = _PyMem_DebugFree; + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); + } +} + + +void +PyMem_SetupDebugHooks(void) +{ + _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_RAW); + _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_MEM); + _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_OBJ); +} + +void +PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +{ + switch(domain) + { + case PYMEM_DOMAIN_RAW: *allocator = _PyMem_Raw; break; + case PYMEM_DOMAIN_MEM: *allocator = _PyMem; break; + case PYMEM_DOMAIN_OBJ: *allocator = _PyObject; break; + default: + /* unknown domain: set all attributes to NULL */ + allocator->ctx = NULL; + allocator->malloc = NULL; + allocator->calloc = NULL; + allocator->realloc = NULL; + allocator->free = NULL; + } +} + +void +PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +{ + switch(domain) + { + case PYMEM_DOMAIN_RAW: _PyMem_Raw = *allocator; break; + case PYMEM_DOMAIN_MEM: _PyMem = *allocator; break; + case PYMEM_DOMAIN_OBJ: _PyObject = *allocator; break; + /* ignore unknown domain */ + } +} + +void +PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator) +{ + *allocator = _PyObject_Arena; +} + +void +PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) +{ + _PyObject_Arena = *allocator; +} + +void * +PyMem_RawMalloc(size_t size) +{ + /* + * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes. + * Most python internals blindly use a signed Py_ssize_t to track + * things without checking for overflows or negatives. + * As size_t is unsigned, checking for size < 0 is not required. + */ + if (size > (size_t)PY_SSIZE_T_MAX) + return NULL; + return _PyMem_Raw.malloc(_PyMem_Raw.ctx, size); +} + +void * +PyMem_RawCalloc(size_t nelem, size_t elsize) +{ + /* see PyMem_RawMalloc() */ + if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) + return NULL; + return _PyMem_Raw.calloc(_PyMem_Raw.ctx, nelem, elsize); +} + +void* +PyMem_RawRealloc(void *ptr, size_t new_size) +{ + /* see PyMem_RawMalloc() */ + if (new_size > (size_t)PY_SSIZE_T_MAX) + return NULL; + return _PyMem_Raw.realloc(_PyMem_Raw.ctx, ptr, new_size); +} + +void PyMem_RawFree(void *ptr) +{ + _PyMem_Raw.free(_PyMem_Raw.ctx, ptr); +} + + +void * +PyMem_Malloc(size_t size) +{ + /* see PyMem_RawMalloc() */ + if (size > (size_t)PY_SSIZE_T_MAX) + return NULL; + return _PyMem.malloc(_PyMem.ctx, size); +} + +void * +PyMem_Calloc(size_t nelem, size_t elsize) +{ + /* see PyMem_RawMalloc() */ + if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) + return NULL; + return _PyMem.calloc(_PyMem.ctx, nelem, elsize); +} + +void * +PyMem_Realloc(void *ptr, size_t new_size) +{ + /* see PyMem_RawMalloc() */ + if (new_size > (size_t)PY_SSIZE_T_MAX) + return NULL; + return _PyMem.realloc(_PyMem.ctx, ptr, new_size); +} + +void +PyMem_Free(void *ptr) +{ + _PyMem.free(_PyMem.ctx, ptr); +} + + +wchar_t* +_PyMem_RawWcsdup(const wchar_t *str) +{ + assert(str != NULL); + + size_t len = wcslen(str); + if (len > (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { + return NULL; + } + + size_t size = (len + 1) * sizeof(wchar_t); + wchar_t *str2 = PyMem_RawMalloc(size); + if (str2 == NULL) { + return NULL; + } + + memcpy(str2, str, size); + return str2; +} + +char * +_PyMem_RawStrdup(const char *str) +{ + assert(str != NULL); + size_t size = strlen(str) + 1; + char *copy = PyMem_RawMalloc(size); + if (copy == NULL) { + return NULL; + } + memcpy(copy, str, size); + return copy; +} + +char * +_PyMem_Strdup(const char *str) +{ + assert(str != NULL); + size_t size = strlen(str) + 1; + char *copy = PyMem_Malloc(size); + if (copy == NULL) { + return NULL; + } + memcpy(copy, str, size); + return copy; +} + +void * +PyObject_Malloc(size_t size) +{ + /* see PyMem_RawMalloc() */ + if (size > (size_t)PY_SSIZE_T_MAX) + return NULL; + return _PyObject.malloc(_PyObject.ctx, size); +} + +void * +PyObject_Calloc(size_t nelem, size_t elsize) +{ + /* see PyMem_RawMalloc() */ + if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) + return NULL; + return _PyObject.calloc(_PyObject.ctx, nelem, elsize); +} + +void * +PyObject_Realloc(void *ptr, size_t new_size) +{ + /* see PyMem_RawMalloc() */ + if (new_size > (size_t)PY_SSIZE_T_MAX) + return NULL; + return _PyObject.realloc(_PyObject.ctx, ptr, new_size); +} + +void +PyObject_Free(void *ptr) +{ + _PyObject.free(_PyObject.ctx, ptr); +} + + +#ifdef WITH_PYMALLOC + +#ifdef WITH_VALGRIND +#include + +/* If we're using GCC, use __builtin_expect() to reduce overhead of + the valgrind checks */ +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +# define UNLIKELY(value) __builtin_expect((value), 0) +#else +# define UNLIKELY(value) (value) +#endif + +/* -1 indicates that we haven't checked that we're running on valgrind yet. */ +static int running_on_valgrind = -1; +#endif + + +/* An object allocator for Python. + + Here is an introduction to the layers of the Python memory architecture, + showing where the object allocator is actually used (layer +2), It is + called for every object allocation and deallocation (PyObject_New/Del), + unless the object-specific allocators implement a proprietary allocation + scheme (ex.: ints use a simple free list). This is also the place where + the cyclic garbage collector operates selectively on container objects. + + + Object-specific allocators + _____ ______ ______ ________ + [ int ] [ dict ] [ list ] ... [ string ] Python core | ++3 | <----- Object-specific memory -----> | <-- Non-object memory --> | + _______________________________ | | + [ Python's object allocator ] | | ++2 | ####### Object memory ####### | <------ Internal buffers ------> | + ______________________________________________________________ | + [ Python's raw memory allocator (PyMem_ API) ] | ++1 | <----- Python memory (under PyMem manager's control) ------> | | + __________________________________________________________________ + [ Underlying general-purpose allocator (ex: C library malloc) ] + 0 | <------ Virtual memory allocated for the python process -------> | + + ========================================================================= + _______________________________________________________________________ + [ OS-specific Virtual Memory Manager (VMM) ] +-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> | + __________________________________ __________________________________ + [ ] [ ] +-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> | + +*/ +/*==========================================================================*/ + +/* A fast, special-purpose memory allocator for small blocks, to be used + on top of a general-purpose malloc -- heavily based on previous art. */ + +/* Vladimir Marangozov -- August 2000 */ + +/* + * "Memory management is where the rubber meets the road -- if we do the wrong + * thing at any level, the results will not be good. And if we don't make the + * levels work well together, we are in serious trouble." (1) + * + * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles, + * "Dynamic Storage Allocation: A Survey and Critical Review", + * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995. + */ + +/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ + +/*==========================================================================*/ + +/* + * Allocation strategy abstract: + * + * For small requests, the allocator sub-allocates blocks of memory. + * Requests greater than SMALL_REQUEST_THRESHOLD bytes are routed to the + * system's allocator. + * + * Small requests are grouped in size classes spaced 8 bytes apart, due + * to the required valid alignment of the returned address. Requests of + * a particular size are serviced from memory pools of 4K (one VMM page). + * Pools are fragmented on demand and contain free lists of blocks of one + * particular size class. In other words, there is a fixed-size allocator + * for each size class. Free pools are shared by the different allocators + * thus minimizing the space reserved for a particular size class. + * + * This allocation strategy is a variant of what is known as "simple + * segregated storage based on array of free lists". The main drawback of + * simple segregated storage is that we might end up with lot of reserved + * memory for the different free lists, which degenerate in time. To avoid + * this, we partition each free list in pools and we share dynamically the + * reserved space between all free lists. This technique is quite efficient + * for memory intensive programs which allocate mainly small-sized blocks. + * + * For small requests we have the following table: + * + * Request in bytes Size of allocated block Size class idx + * ---------------------------------------------------------------- + * 1-8 8 0 + * 9-16 16 1 + * 17-24 24 2 + * 25-32 32 3 + * 33-40 40 4 + * 41-48 48 5 + * 49-56 56 6 + * 57-64 64 7 + * 65-72 72 8 + * ... ... ... + * 497-504 504 62 + * 505-512 512 63 + * + * 0, SMALL_REQUEST_THRESHOLD + 1 and up: routed to the underlying + * allocator. + */ + +/*==========================================================================*/ + +/* + * -- Main tunable settings section -- + */ + +/* + * Alignment of addresses returned to the user. 8-bytes alignment works + * on most current architectures (with 32-bit or 64-bit address busses). + * The alignment value is also used for grouping small requests in size + * classes spaced ALIGNMENT bytes apart. + * + * You shouldn't change this unless you know what you are doing. + */ + +#if SIZEOF_VOID_P > 4 +#define ALIGNMENT 16 /* must be 2^N */ +#define ALIGNMENT_SHIFT 4 +#else +#define ALIGNMENT 8 /* must be 2^N */ +#define ALIGNMENT_SHIFT 3 +#endif + +/* Return the number of bytes in size class I, as a uint. */ +#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT) + +/* + * Max size threshold below which malloc requests are considered to be + * small enough in order to use preallocated memory pools. You can tune + * this value according to your application behaviour and memory needs. + * + * Note: a size threshold of 512 guarantees that newly created dictionaries + * will be allocated from preallocated memory pools on 64-bit. + * + * The following invariants must hold: + * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 512 + * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT + * + * Although not required, for better performance and space efficiency, + * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2. + */ +#define SMALL_REQUEST_THRESHOLD 512 +#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) + +/* + * The system's VMM page size can be obtained on most unices with a + * getpagesize() call or deduced from various header files. To make + * things simpler, we assume that it is 4K, which is OK for most systems. + * It is probably better if this is the native page size, but it doesn't + * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page + * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation + * violation fault. 4K is apparently OK for all the platforms that python + * currently targets. + */ +#define SYSTEM_PAGE_SIZE (4 * 1024) +#define SYSTEM_PAGE_SIZE_MASK (SYSTEM_PAGE_SIZE - 1) + +/* + * Maximum amount of memory managed by the allocator for small requests. + */ +#ifdef WITH_MEMORY_LIMITS +#ifndef SMALL_MEMORY_LIMIT +#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */ +#endif +#endif + +/* + * The allocator sub-allocates blocks of memory (called arenas) aligned + * on a page boundary. This is a reserved virtual address space for the + * current process (obtained through a malloc()/mmap() call). In no way this + * means that the memory arenas will be used entirely. A malloc() is + * usually an address range reservation for bytes, unless all pages within + * this space are referenced subsequently. So malloc'ing big blocks and not + * using them does not mean "wasting memory". It's an addressable range + * wastage... + * + * Arenas are allocated with mmap() on systems supporting anonymous memory + * mappings to reduce heap fragmentation. + */ +#define ARENA_SIZE (256 << 10) /* 256KB */ + +#ifdef WITH_MEMORY_LIMITS +#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE) +#endif + +/* + * Size of the pools used for small blocks. Should be a power of 2, + * between 1K and SYSTEM_PAGE_SIZE, that is: 1k, 2k, 4k. + */ +#define POOL_SIZE SYSTEM_PAGE_SIZE /* must be 2^N */ +#define POOL_SIZE_MASK SYSTEM_PAGE_SIZE_MASK + +#define MAX_POOLS_IN_ARENA (ARENA_SIZE / POOL_SIZE) +#if MAX_POOLS_IN_ARENA * POOL_SIZE != ARENA_SIZE +# error "arena size not an exact multiple of pool size" +#endif + +/* + * -- End of tunable settings section -- + */ + +/*==========================================================================*/ + +/* When you say memory, my mind reasons in terms of (pointers to) blocks */ +typedef uint8_t block; + +/* Pool for small blocks. */ +struct pool_header { + union { block *_padding; + uint count; } ref; /* number of allocated blocks */ + block *freeblock; /* pool's free list head */ + struct pool_header *nextpool; /* next pool of this size class */ + struct pool_header *prevpool; /* previous pool "" */ + uint arenaindex; /* index into arenas of base adr */ + uint szidx; /* block size class index */ + uint nextoffset; /* bytes to virgin block */ + uint maxnextoffset; /* largest valid nextoffset */ +}; + +typedef struct pool_header *poolp; + +/* Record keeping for arenas. */ +struct arena_object { + /* The address of the arena, as returned by malloc. Note that 0 + * will never be returned by a successful malloc, and is used + * here to mark an arena_object that doesn't correspond to an + * allocated arena. + */ + uintptr_t address; + + /* Pool-aligned pointer to the next pool to be carved off. */ + block* pool_address; + + /* The number of available pools in the arena: free pools + never- + * allocated pools. + */ + uint nfreepools; + + /* The total number of pools in the arena, whether or not available. */ + uint ntotalpools; + + /* Singly-linked list of available pools. */ + struct pool_header* freepools; + + /* Whenever this arena_object is not associated with an allocated + * arena, the nextarena member is used to link all unassociated + * arena_objects in the singly-linked `unused_arena_objects` list. + * The prevarena member is unused in this case. + * + * When this arena_object is associated with an allocated arena + * with at least one available pool, both members are used in the + * doubly-linked `usable_arenas` list, which is maintained in + * increasing order of `nfreepools` values. + * + * Else this arena_object is associated with an allocated arena + * all of whose pools are in use. `nextarena` and `prevarena` + * are both meaningless in this case. + */ + struct arena_object* nextarena; + struct arena_object* prevarena; +}; + +#define POOL_OVERHEAD _Py_SIZE_ROUND_UP(sizeof(struct pool_header), ALIGNMENT) + +#define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ + +/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ +#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) + +/* Return total number of blocks in pool of size index I, as a uint. */ +#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) + +/*==========================================================================*/ + +/* + * Pool table -- headed, circular, doubly-linked lists of partially used pools. + +This is involved. For an index i, usedpools[i+i] is the header for a list of +all partially used pools holding small blocks with "size class idx" i. So +usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size +16, and so on: index 2*i <-> blocks of size (i+1)<freeblock points to +the start of a singly-linked list of free blocks within the pool. When a +block is freed, it's inserted at the front of its pool's freeblock list. Note +that the available blocks in a pool are *not* linked all together when a pool +is initialized. Instead only "the first two" (lowest addresses) blocks are +set up, returning the first such block, and setting pool->freeblock to a +one-block list holding the second such block. This is consistent with that +pymalloc strives at all levels (arena, pool, and block) never to touch a piece +of memory until it's actually needed. + +So long as a pool is in the used state, we're certain there *is* a block +available for allocating, and pool->freeblock is not NULL. If pool->freeblock +points to the end of the free list before we've carved the entire pool into +blocks, that means we simply haven't yet gotten to one of the higher-address +blocks. The offset from the pool_header to the start of "the next" virgin +block is stored in the pool_header nextoffset member, and the largest value +of nextoffset that makes sense is stored in the maxnextoffset member when a +pool is initialized. All the blocks in a pool have been passed out at least +once when and only when nextoffset > maxnextoffset. + + +Major obscurity: While the usedpools vector is declared to have poolp +entries, it doesn't really. It really contains two pointers per (conceptual) +poolp entry, the nextpool and prevpool members of a pool_header. The +excruciating initialization code below fools C so that + + usedpool[i+i] + +"acts like" a genuine poolp, but only so long as you only reference its +nextpool and prevpool members. The "- 2*sizeof(block *)" gibberish is +compensating for that a pool_header's nextpool and prevpool members +immediately follow a pool_header's first two members: + + union { block *_padding; + uint count; } ref; + block *freeblock; + +each of which consume sizeof(block *) bytes. So what usedpools[i+i] really +contains is a fudged-up pointer p such that *if* C believes it's a poolp +pointer, then p->nextpool and p->prevpool are both p (meaning that the headed +circular list is empty). + +It's unclear why the usedpools setup is so convoluted. It could be to +minimize the amount of cache required to hold this heavily-referenced table +(which only *needs* the two interpool pointer members of a pool_header). OTOH, +referencing code has to remember to "double the index" and doing so isn't +free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying +on that C doesn't insert any padding anywhere in a pool_header at or before +the prevpool member. +**************************************************************************** */ + +#define PTA(x) ((poolp )((uint8_t *)&(usedpools[2*(x)]) - 2*sizeof(block *))) +#define PT(x) PTA(x), PTA(x) + +static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = { + PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7) +#if NB_SMALL_SIZE_CLASSES > 8 + , PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15) +#if NB_SMALL_SIZE_CLASSES > 16 + , PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23) +#if NB_SMALL_SIZE_CLASSES > 24 + , PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31) +#if NB_SMALL_SIZE_CLASSES > 32 + , PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39) +#if NB_SMALL_SIZE_CLASSES > 40 + , PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47) +#if NB_SMALL_SIZE_CLASSES > 48 + , PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55) +#if NB_SMALL_SIZE_CLASSES > 56 + , PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63) +#if NB_SMALL_SIZE_CLASSES > 64 +#error "NB_SMALL_SIZE_CLASSES should be less than 64" +#endif /* NB_SMALL_SIZE_CLASSES > 64 */ +#endif /* NB_SMALL_SIZE_CLASSES > 56 */ +#endif /* NB_SMALL_SIZE_CLASSES > 48 */ +#endif /* NB_SMALL_SIZE_CLASSES > 40 */ +#endif /* NB_SMALL_SIZE_CLASSES > 32 */ +#endif /* NB_SMALL_SIZE_CLASSES > 24 */ +#endif /* NB_SMALL_SIZE_CLASSES > 16 */ +#endif /* NB_SMALL_SIZE_CLASSES > 8 */ +}; + +/*========================================================================== +Arena management. + +`arenas` is a vector of arena_objects. It contains maxarenas entries, some of +which may not be currently used (== they're arena_objects that aren't +currently associated with an allocated arena). Note that arenas proper are +separately malloc'ed. + +Prior to Python 2.5, arenas were never free()'ed. Starting with Python 2.5, +we do try to free() arenas, and use some mild heuristic strategies to increase +the likelihood that arenas eventually can be freed. + +unused_arena_objects + + This is a singly-linked list of the arena_objects that are currently not + being used (no arena is associated with them). Objects are taken off the + head of the list in new_arena(), and are pushed on the head of the list in + PyObject_Free() when the arena is empty. Key invariant: an arena_object + is on this list if and only if its .address member is 0. + +usable_arenas + + This is a doubly-linked list of the arena_objects associated with arenas + that have pools available. These pools are either waiting to be reused, + or have not been used before. The list is sorted to have the most- + allocated arenas first (ascending order based on the nfreepools member). + This means that the next allocation will come from a heavily used arena, + which gives the nearly empty arenas a chance to be returned to the system. + In my unscientific tests this dramatically improved the number of arenas + that could be freed. + +Note that an arena_object associated with an arena all of whose pools are +currently in use isn't on either list. + +Changed in Python 3.8: keeping usable_arenas sorted by number of free pools +used to be done by one-at-a-time linear search when an arena's number of +free pools changed. That could, overall, consume time quadratic in the +number of arenas. That didn't really matter when there were only a few +hundred arenas (typical!), but could be a timing disaster when there were +hundreds of thousands. See bpo-37029. + +Now we have a vector of "search fingers" to eliminate the need to search: +nfp2lasta[nfp] returns the last ("rightmost") arena in usable_arenas +with nfp free pools. This is NULL if and only if there is no arena with +nfp free pools in usable_arenas. +*/ + +/* Array of objects used to track chunks of memory (arenas). */ +static struct arena_object* arenas = NULL; +/* Number of slots currently allocated in the `arenas` vector. */ +static uint maxarenas = 0; + +/* The head of the singly-linked, NULL-terminated list of available + * arena_objects. + */ +static struct arena_object* unused_arena_objects = NULL; + +/* The head of the doubly-linked, NULL-terminated at each end, list of + * arena_objects associated with arenas that have pools available. + */ +static struct arena_object* usable_arenas = NULL; + +/* nfp2lasta[nfp] is the last arena in usable_arenas with nfp free pools */ +static struct arena_object* nfp2lasta[MAX_POOLS_IN_ARENA + 1] = { NULL }; + +/* How many arena_objects do we initially allocate? + * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the + * `arenas` vector. + */ +#define INITIAL_ARENA_OBJECTS 16 + +/* Number of arenas allocated that haven't been free()'d. */ +static size_t narenas_currently_allocated = 0; + +/* Total number of times malloc() called to allocate an arena. */ +static size_t ntimes_arena_allocated = 0; +/* High water mark (max value ever seen) for narenas_currently_allocated. */ +static size_t narenas_highwater = 0; + +static Py_ssize_t _Py_AllocatedBlocks = 0; + +Py_ssize_t +_Py_GetAllocatedBlocks(void) +{ + return _Py_AllocatedBlocks; +} + + +/* Allocate a new arena. If we run out of memory, return NULL. Else + * allocate a new arena, and return the address of an arena_object + * describing the new arena. It's expected that the caller will set + * `usable_arenas` to the return value. + */ +static struct arena_object* +new_arena(void) +{ + struct arena_object* arenaobj; + uint excess; /* number of bytes above pool alignment */ + void *address; + static int debug_stats = -1; + + if (debug_stats == -1) { + const char *opt = Py_GETENV("PYTHONMALLOCSTATS"); + debug_stats = (opt != NULL && *opt != '\0'); + } + if (debug_stats) + _PyObject_DebugMallocStats(stderr); + + if (unused_arena_objects == NULL) { + uint i; + uint numarenas; + size_t nbytes; + + /* Double the number of arena objects on each allocation. + * Note that it's possible for `numarenas` to overflow. + */ + numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS; + if (numarenas <= maxarenas) + return NULL; /* overflow */ +#if SIZEOF_SIZE_T <= SIZEOF_INT + if (numarenas > SIZE_MAX / sizeof(*arenas)) + return NULL; /* overflow */ +#endif + nbytes = numarenas * sizeof(*arenas); + arenaobj = (struct arena_object *)PyMem_RawRealloc(arenas, nbytes); + if (arenaobj == NULL) + return NULL; + arenas = arenaobj; + + /* We might need to fix pointers that were copied. However, + * new_arena only gets called when all the pages in the + * previous arenas are full. Thus, there are *no* pointers + * into the old array. Thus, we don't have to worry about + * invalid pointers. Just to be sure, some asserts: + */ + assert(usable_arenas == NULL); + assert(unused_arena_objects == NULL); + + /* Put the new arenas on the unused_arena_objects list. */ + for (i = maxarenas; i < numarenas; ++i) { + arenas[i].address = 0; /* mark as unassociated */ + arenas[i].nextarena = i < numarenas - 1 ? + &arenas[i+1] : NULL; + } + + /* Update globals. */ + unused_arena_objects = &arenas[maxarenas]; + maxarenas = numarenas; + } + + /* Take the next available arena object off the head of the list. */ + assert(unused_arena_objects != NULL); + arenaobj = unused_arena_objects; + unused_arena_objects = arenaobj->nextarena; + assert(arenaobj->address == 0); + address = _PyObject_Arena.alloc(_PyObject_Arena.ctx, ARENA_SIZE); + if (address == NULL) { + /* The allocation failed: return NULL after putting the + * arenaobj back. + */ + arenaobj->nextarena = unused_arena_objects; + unused_arena_objects = arenaobj; + return NULL; + } + arenaobj->address = (uintptr_t)address; + + ++narenas_currently_allocated; + ++ntimes_arena_allocated; + if (narenas_currently_allocated > narenas_highwater) + narenas_highwater = narenas_currently_allocated; + arenaobj->freepools = NULL; + /* pool_address <- first pool-aligned address in the arena + nfreepools <- number of whole pools that fit after alignment */ + arenaobj->pool_address = (block*)arenaobj->address; + arenaobj->nfreepools = MAX_POOLS_IN_ARENA; + excess = (uint)(arenaobj->address & POOL_SIZE_MASK); + if (excess != 0) { + --arenaobj->nfreepools; + arenaobj->pool_address += POOL_SIZE - excess; + } + arenaobj->ntotalpools = arenaobj->nfreepools; + + return arenaobj; +} + + +/* +address_in_range(P, POOL) + +Return true if and only if P is an address that was allocated by pymalloc. +POOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P) +(the caller is asked to compute this because the macro expands POOL more than +once, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a +variable and pass the latter to the macro; because address_in_range is +called on every alloc/realloc/free, micro-efficiency is important here). + +Tricky: Let B be the arena base address associated with the pool, B = +arenas[(POOL)->arenaindex].address. Then P belongs to the arena if and only if + + B <= P < B + ARENA_SIZE + +Subtracting B throughout, this is true iff + + 0 <= P-B < ARENA_SIZE + +By using unsigned arithmetic, the "0 <=" half of the test can be skipped. + +Obscure: A PyMem "free memory" function can call the pymalloc free or realloc +before the first arena has been allocated. `arenas` is still NULL in that +case. We're relying on that maxarenas is also 0 in that case, so that +(POOL)->arenaindex < maxarenas must be false, saving us from trying to index +into a NULL arenas. + +Details: given P and POOL, the arena_object corresponding to P is AO = +arenas[(POOL)->arenaindex]. Suppose obmalloc controls P. Then (barring wild +stores, etc), POOL is the correct address of P's pool, AO.address is the +correct base address of the pool's arena, and P must be within ARENA_SIZE of +AO.address. In addition, AO.address is not 0 (no arena can start at address 0 +(NULL)). Therefore address_in_range correctly reports that obmalloc +controls P. + +Now suppose obmalloc does not control P (e.g., P was obtained via a direct +call to the system malloc() or realloc()). (POOL)->arenaindex may be anything +in this case -- it may even be uninitialized trash. If the trash arenaindex +is >= maxarenas, the macro correctly concludes at once that obmalloc doesn't +control P. + +Else arenaindex is < maxarena, and AO is read up. If AO corresponds to an +allocated arena, obmalloc controls all the memory in slice AO.address : +AO.address+ARENA_SIZE. By case assumption, P is not controlled by obmalloc, +so P doesn't lie in that slice, so the macro correctly reports that P is not +controlled by obmalloc. + +Finally, if P is not controlled by obmalloc and AO corresponds to an unused +arena_object (one not currently associated with an allocated arena), +AO.address is 0, and the second test in the macro reduces to: + + P < ARENA_SIZE + +If P >= ARENA_SIZE (extremely likely), the macro again correctly concludes +that P is not controlled by obmalloc. However, if P < ARENA_SIZE, this part +of the test still passes, and the third clause (AO.address != 0) is necessary +to get the correct result: AO.address is 0 in this case, so the macro +correctly reports that P is not controlled by obmalloc (despite that P lies in +slice AO.address : AO.address + ARENA_SIZE). + +Note: The third (AO.address != 0) clause was added in Python 2.5. Before +2.5, arenas were never free()'ed, and an arenaindex < maxarena always +corresponded to a currently-allocated arena, so the "P is not controlled by +obmalloc, AO corresponds to an unused arena_object, and P < ARENA_SIZE" case +was impossible. + +Note that the logic is excruciating, and reading up possibly uninitialized +memory when P is not controlled by obmalloc (to get at (POOL)->arenaindex) +creates problems for some memory debuggers. The overwhelming advantage is +that this test determines whether an arbitrary address is controlled by +obmalloc in a small constant time, independent of the number of arenas +obmalloc controls. Since this test is needed at every entry point, it's +extremely desirable that it be this fast. +*/ + +static bool _Py_NO_SANITIZE_ADDRESS + _Py_NO_SANITIZE_THREAD + _Py_NO_SANITIZE_MEMORY +address_in_range(void *p, poolp pool) +{ + // Since address_in_range may be reading from memory which was not allocated + // by Python, it is important that pool->arenaindex is read only once, as + // another thread may be concurrently modifying the value without holding + // the GIL. The following dance forces the compiler to read pool->arenaindex + // only once. + uint arenaindex = *((volatile uint *)&pool->arenaindex); + return arenaindex < maxarenas && + (uintptr_t)p - arenas[arenaindex].address < ARENA_SIZE && + arenas[arenaindex].address != 0; +} + + +/*==========================================================================*/ + +/* pymalloc allocator + + The basic blocks are ordered by decreasing execution frequency, + which minimizes the number of jumps in the most common cases, + improves branching prediction and instruction scheduling (small + block allocations typically result in a couple of instructions). + Unless the optimizer reorders everything, being too smart... + + Return a pointer to newly allocated memory if pymalloc allocated memory. + + Return NULL if pymalloc failed to allocate the memory block: on bigger + requests, on error in the code below (as a last chance to serve the request) + or when the max memory limit has been reached. */ +static void* +pymalloc_alloc(void *ctx, size_t nbytes) +{ + block *bp; + poolp pool; + poolp next; + uint size; + +#ifdef WITH_VALGRIND + if (UNLIKELY(running_on_valgrind == -1)) { + running_on_valgrind = RUNNING_ON_VALGRIND; + } + if (UNLIKELY(running_on_valgrind)) { + return NULL; + } +#endif + + if (nbytes == 0) { + return NULL; + } + if (nbytes > SMALL_REQUEST_THRESHOLD) { + return NULL; + } + + /* + * Most frequent paths first + */ + size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT; + pool = usedpools[size + size]; + if (pool != pool->nextpool) { + /* + * There is a used pool for this size class. + * Pick up the head block of its free list. + */ + ++pool->ref.count; + bp = pool->freeblock; + assert(bp != NULL); + if ((pool->freeblock = *(block **)bp) != NULL) { + goto success; + } + + /* + * Reached the end of the free list, try to extend it. + */ + if (pool->nextoffset <= pool->maxnextoffset) { + /* There is room for another block. */ + pool->freeblock = (block*)pool + + pool->nextoffset; + pool->nextoffset += INDEX2SIZE(size); + *(block **)(pool->freeblock) = NULL; + goto success; + } + + /* Pool is full, unlink from used pools. */ + next = pool->nextpool; + pool = pool->prevpool; + next->prevpool = pool; + pool->nextpool = next; + goto success; + } + + /* There isn't a pool of the right size class immediately + * available: use a free pool. + */ + if (usable_arenas == NULL) { + /* No arena has a free pool: allocate a new arena. */ +#ifdef WITH_MEMORY_LIMITS + if (narenas_currently_allocated >= MAX_ARENAS) { + goto failed; + } +#endif + usable_arenas = new_arena(); + if (usable_arenas == NULL) { + goto failed; + } + usable_arenas->nextarena = + usable_arenas->prevarena = NULL; + assert(nfp2lasta[usable_arenas->nfreepools] == NULL); + nfp2lasta[usable_arenas->nfreepools] = usable_arenas; + } + assert(usable_arenas->address != 0); + + /* This arena already had the smallest nfreepools value, so decreasing + * nfreepools doesn't change that, and we don't need to rearrange the + * usable_arenas list. However, if the arena becomes wholly allocated, + * we need to remove its arena_object from usable_arenas. + */ + assert(usable_arenas->nfreepools > 0); + if (nfp2lasta[usable_arenas->nfreepools] == usable_arenas) { + /* It's the last of this size, so there won't be any. */ + nfp2lasta[usable_arenas->nfreepools] = NULL; + } + /* If any free pools will remain, it will be the new smallest. */ + if (usable_arenas->nfreepools > 1) { + assert(nfp2lasta[usable_arenas->nfreepools - 1] == NULL); + nfp2lasta[usable_arenas->nfreepools - 1] = usable_arenas; + } + + /* Try to get a cached free pool. */ + pool = usable_arenas->freepools; + if (pool != NULL) { + /* Unlink from cached pools. */ + usable_arenas->freepools = pool->nextpool; + --usable_arenas->nfreepools; + if (usable_arenas->nfreepools == 0) { + /* Wholly allocated: remove. */ + assert(usable_arenas->freepools == NULL); + assert(usable_arenas->nextarena == NULL || + usable_arenas->nextarena->prevarena == + usable_arenas); + usable_arenas = usable_arenas->nextarena; + if (usable_arenas != NULL) { + usable_arenas->prevarena = NULL; + assert(usable_arenas->address != 0); + } + } + else { + /* nfreepools > 0: it must be that freepools + * isn't NULL, or that we haven't yet carved + * off all the arena's pools for the first + * time. + */ + assert(usable_arenas->freepools != NULL || + usable_arenas->pool_address <= + (block*)usable_arenas->address + + ARENA_SIZE - POOL_SIZE); + } + + init_pool: + /* Frontlink to used pools. */ + next = usedpools[size + size]; /* == prev */ + pool->nextpool = next; + pool->prevpool = next; + next->nextpool = pool; + next->prevpool = pool; + pool->ref.count = 1; + if (pool->szidx == size) { + /* Luckily, this pool last contained blocks + * of the same size class, so its header + * and free list are already initialized. + */ + bp = pool->freeblock; + assert(bp != NULL); + pool->freeblock = *(block **)bp; + goto success; + } + /* + * Initialize the pool header, set up the free list to + * contain just the second block, and return the first + * block. + */ + pool->szidx = size; + size = INDEX2SIZE(size); + bp = (block *)pool + POOL_OVERHEAD; + pool->nextoffset = POOL_OVERHEAD + (size << 1); + pool->maxnextoffset = POOL_SIZE - size; + pool->freeblock = bp + size; + *(block **)(pool->freeblock) = NULL; + goto success; + } + + /* Carve off a new pool. */ + assert(usable_arenas->nfreepools > 0); + assert(usable_arenas->freepools == NULL); + pool = (poolp)usable_arenas->pool_address; + assert((block*)pool <= (block*)usable_arenas->address + + ARENA_SIZE - POOL_SIZE); + pool->arenaindex = (uint)(usable_arenas - arenas); + assert(&arenas[pool->arenaindex] == usable_arenas); + pool->szidx = DUMMY_SIZE_IDX; + usable_arenas->pool_address += POOL_SIZE; + --usable_arenas->nfreepools; + + if (usable_arenas->nfreepools == 0) { + assert(usable_arenas->nextarena == NULL || + usable_arenas->nextarena->prevarena == + usable_arenas); + /* Unlink the arena: it is completely allocated. */ + usable_arenas = usable_arenas->nextarena; + if (usable_arenas != NULL) { + usable_arenas->prevarena = NULL; + assert(usable_arenas->address != 0); + } + } + + goto init_pool; + +success: + assert(bp != NULL); + return (void *)bp; + +failed: + return NULL; +} + + +static void * +_PyObject_Malloc(void *ctx, size_t nbytes) +{ + void* ptr = pymalloc_alloc(ctx, nbytes); + if (ptr != NULL) { + _Py_AllocatedBlocks++; + return ptr; + } + + ptr = PyMem_RawMalloc(nbytes); + if (ptr != NULL) { + _Py_AllocatedBlocks++; + } + return ptr; +} + + +static void * +_PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) +{ + assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize); + size_t nbytes = nelem * elsize; + + void *ptr = pymalloc_alloc(ctx, nbytes); + if (ptr != NULL) { + memset(ptr, 0, nbytes); + _Py_AllocatedBlocks++; + return ptr; + } + + ptr = PyMem_RawCalloc(nelem, elsize); + if (ptr != NULL) { + _Py_AllocatedBlocks++; + } + return ptr; +} + + +/* Free a memory block allocated by pymalloc_alloc(). + Return 1 if it was freed. + Return 0 if the block was not allocated by pymalloc_alloc(). */ +static int +pymalloc_free(void *ctx, void *p) +{ + poolp pool; + block *lastfree; + poolp next, prev; + uint size; + + assert(p != NULL); + +#ifdef WITH_VALGRIND + if (UNLIKELY(running_on_valgrind > 0)) { + return 0; + } +#endif + + pool = POOL_ADDR(p); + if (!address_in_range(p, pool)) { + return 0; + } + /* We allocated this address. */ + + /* Link p to the start of the pool's freeblock list. Since + * the pool had at least the p block outstanding, the pool + * wasn't empty (so it's already in a usedpools[] list, or + * was full and is in no list -- it's not in the freeblocks + * list in any case). + */ + assert(pool->ref.count > 0); /* else it was empty */ + *(block **)p = lastfree = pool->freeblock; + pool->freeblock = (block *)p; + if (!lastfree) { + /* Pool was full, so doesn't currently live in any list: + * link it to the front of the appropriate usedpools[] list. + * This mimics LRU pool usage for new allocations and + * targets optimal filling when several pools contain + * blocks of the same size class. + */ + --pool->ref.count; + assert(pool->ref.count > 0); /* else the pool is empty */ + size = pool->szidx; + next = usedpools[size + size]; + prev = next->prevpool; + + /* insert pool before next: prev <-> pool <-> next */ + pool->nextpool = next; + pool->prevpool = prev; + next->prevpool = pool; + prev->nextpool = pool; + goto success; + } + + struct arena_object* ao; + uint nf; /* ao->nfreepools */ + + /* freeblock wasn't NULL, so the pool wasn't full, + * and the pool is in a usedpools[] list. + */ + if (--pool->ref.count != 0) { + /* pool isn't empty: leave it in usedpools */ + goto success; + } + /* Pool is now empty: unlink from usedpools, and + * link to the front of freepools. This ensures that + * previously freed pools will be allocated later + * (being not referenced, they are perhaps paged out). + */ + next = pool->nextpool; + prev = pool->prevpool; + next->prevpool = prev; + prev->nextpool = next; + + /* Link the pool to freepools. This is a singly-linked + * list, and pool->prevpool isn't used there. + */ + ao = &arenas[pool->arenaindex]; + pool->nextpool = ao->freepools; + ao->freepools = pool; + nf = ao->nfreepools; + /* If this is the rightmost arena with this number of free pools, + * nfp2lasta[nf] needs to change. Caution: if nf is 0, there + * are no arenas in usable_arenas with that value. + */ + struct arena_object* lastnf = nfp2lasta[nf]; + assert((nf == 0 && lastnf == NULL) || + (nf > 0 && + lastnf != NULL && + lastnf->nfreepools == nf && + (lastnf->nextarena == NULL || + nf < lastnf->nextarena->nfreepools))); + if (lastnf == ao) { /* it is the rightmost */ + struct arena_object* p = ao->prevarena; + nfp2lasta[nf] = (p != NULL && p->nfreepools == nf) ? p : NULL; + } + ao->nfreepools = ++nf; + + /* All the rest is arena management. We just freed + * a pool, and there are 4 cases for arena mgmt: + * 1. If all the pools are free, return the arena to + * the system free(). + * 2. If this is the only free pool in the arena, + * add the arena back to the `usable_arenas` list. + * 3. If the "next" arena has a smaller count of free + * pools, we have to "slide this arena right" to + * restore that usable_arenas is sorted in order of + * nfreepools. + * 4. Else there's nothing more to do. + */ + if (nf == ao->ntotalpools) { + /* Case 1. First unlink ao from usable_arenas. + */ + assert(ao->prevarena == NULL || + ao->prevarena->address != 0); + assert(ao ->nextarena == NULL || + ao->nextarena->address != 0); + + /* Fix the pointer in the prevarena, or the + * usable_arenas pointer. + */ + if (ao->prevarena == NULL) { + usable_arenas = ao->nextarena; + assert(usable_arenas == NULL || + usable_arenas->address != 0); + } + else { + assert(ao->prevarena->nextarena == ao); + ao->prevarena->nextarena = + ao->nextarena; + } + /* Fix the pointer in the nextarena. */ + if (ao->nextarena != NULL) { + assert(ao->nextarena->prevarena == ao); + ao->nextarena->prevarena = + ao->prevarena; + } + /* Record that this arena_object slot is + * available to be reused. + */ + ao->nextarena = unused_arena_objects; + unused_arena_objects = ao; + + /* Free the entire arena. */ + _PyObject_Arena.free(_PyObject_Arena.ctx, + (void *)ao->address, ARENA_SIZE); + ao->address = 0; /* mark unassociated */ + --narenas_currently_allocated; + + goto success; + } + + if (nf == 1) { + /* Case 2. Put ao at the head of + * usable_arenas. Note that because + * ao->nfreepools was 0 before, ao isn't + * currently on the usable_arenas list. + */ + ao->nextarena = usable_arenas; + ao->prevarena = NULL; + if (usable_arenas) + usable_arenas->prevarena = ao; + usable_arenas = ao; + assert(usable_arenas->address != 0); + if (nfp2lasta[1] == NULL) { + nfp2lasta[1] = ao; + } + + goto success; + } + + /* If this arena is now out of order, we need to keep + * the list sorted. The list is kept sorted so that + * the "most full" arenas are used first, which allows + * the nearly empty arenas to be completely freed. In + * a few un-scientific tests, it seems like this + * approach allowed a lot more memory to be freed. + */ + /* If this is the only arena with nf, record that. */ + if (nfp2lasta[nf] == NULL) { + nfp2lasta[nf] = ao; + } /* else the rightmost with nf doesn't change */ + /* If this was the rightmost of the old size, it remains in place. */ + if (ao == lastnf) { + /* Case 4. Nothing to do. */ + goto success; + } + /* If ao were the only arena in the list, the last block would have + * gotten us out. + */ + assert(ao->nextarena != NULL); + + /* Case 3: We have to move the arena towards the end of the list, + * because it has more free pools than the arena to its right. It needs + * to move to follow lastnf. + * First unlink ao from usable_arenas. + */ + if (ao->prevarena != NULL) { + /* ao isn't at the head of the list */ + assert(ao->prevarena->nextarena == ao); + ao->prevarena->nextarena = ao->nextarena; + } + else { + /* ao is at the head of the list */ + assert(usable_arenas == ao); + usable_arenas = ao->nextarena; + } + ao->nextarena->prevarena = ao->prevarena; + /* And insert after lastnf. */ + ao->prevarena = lastnf; + ao->nextarena = lastnf->nextarena; + if (ao->nextarena != NULL) { + ao->nextarena->prevarena = ao; + } + lastnf->nextarena = ao; + /* Verify that the swaps worked. */ + assert(ao->nextarena == NULL || nf <= ao->nextarena->nfreepools); + assert(ao->prevarena == NULL || nf > ao->prevarena->nfreepools); + assert(ao->nextarena == NULL || ao->nextarena->prevarena == ao); + assert((usable_arenas == ao && ao->prevarena == NULL) + || ao->prevarena->nextarena == ao); + + goto success; + +success: + return 1; +} + + +static void +_PyObject_Free(void *ctx, void *p) +{ + /* PyObject_Free(NULL) has no effect */ + if (p == NULL) { + return; + } + + _Py_AllocatedBlocks--; + if (!pymalloc_free(ctx, p)) { + /* pymalloc didn't allocate this address */ + PyMem_RawFree(p); + } +} + + +/* pymalloc realloc. + + If nbytes==0, then as the Python docs promise, we do not treat this like + free(p), and return a non-NULL result. + + Return 1 if pymalloc reallocated memory and wrote the new pointer into + newptr_p. + + Return 0 if pymalloc didn't allocated p. */ +static int +pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) +{ + void *bp; + poolp pool; + size_t size; + + assert(p != NULL); + +#ifdef WITH_VALGRIND + /* Treat running_on_valgrind == -1 the same as 0 */ + if (UNLIKELY(running_on_valgrind > 0)) { + return 0; + } +#endif + + pool = POOL_ADDR(p); + if (!address_in_range(p, pool)) { + /* pymalloc is not managing this block. + + If nbytes <= SMALL_REQUEST_THRESHOLD, it's tempting to try to take + over this block. However, if we do, we need to copy the valid data + from the C-managed block to one of our blocks, and there's no + portable way to know how much of the memory space starting at p is + valid. + + As bug 1185883 pointed out the hard way, it's possible that the + C-managed block is "at the end" of allocated VM space, so that a + memory fault can occur if we try to copy nbytes bytes starting at p. + Instead we punt: let C continue to manage this block. */ + return 0; + } + + /* pymalloc is in charge of this block */ + size = INDEX2SIZE(pool->szidx); + if (nbytes <= size) { + /* The block is staying the same or shrinking. + + If it's shrinking, there's a tradeoff: it costs cycles to copy the + block to a smaller size class, but it wastes memory not to copy it. + + The compromise here is to copy on shrink only if at least 25% of + size can be shaved off. */ + if (4 * nbytes > 3 * size) { + /* It's the same, or shrinking and new/old > 3/4. */ + *newptr_p = p; + return 1; + } + size = nbytes; + } + + bp = _PyObject_Malloc(ctx, nbytes); + if (bp != NULL) { + memcpy(bp, p, size); + _PyObject_Free(ctx, p); + } + *newptr_p = bp; + return 1; +} + + +static void * +_PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) +{ + void *ptr2; + + if (ptr == NULL) { + return _PyObject_Malloc(ctx, nbytes); + } + + if (pymalloc_realloc(ctx, &ptr2, ptr, nbytes)) { + return ptr2; + } + + return PyMem_RawRealloc(ptr, nbytes); +} + +#else /* ! WITH_PYMALLOC */ + +/*==========================================================================*/ +/* pymalloc not enabled: Redirect the entry points to malloc. These will + * only be used by extensions that are compiled with pymalloc enabled. */ + +Py_ssize_t +_Py_GetAllocatedBlocks(void) +{ + return 0; +} + +#endif /* WITH_PYMALLOC */ + + +/*==========================================================================*/ +/* A x-platform debugging allocator. This doesn't manage memory directly, + * it wraps a real allocator, adding extra debugging info to the memory blocks. + */ + +/* Uncomment this define to add the "serialno" field */ +/* #define PYMEM_DEBUG_SERIALNO */ + +#ifdef PYMEM_DEBUG_SERIALNO +static size_t serialno = 0; /* incremented on each debug {m,re}alloc */ + +/* serialno is always incremented via calling this routine. The point is + * to supply a single place to set a breakpoint. + */ +static void +bumpserialno(void) +{ + ++serialno; +} +#endif + +#define SST SIZEOF_SIZE_T + +#ifdef PYMEM_DEBUG_SERIALNO +# define PYMEM_DEBUG_EXTRA_BYTES 4 * SST +#else +# define PYMEM_DEBUG_EXTRA_BYTES 3 * SST +#endif + +/* Read sizeof(size_t) bytes at p as a big-endian size_t. */ +static size_t +read_size_t(const void *p) +{ + const uint8_t *q = (const uint8_t *)p; + size_t result = *q++; + int i; + + for (i = SST; --i > 0; ++q) + result = (result << 8) | *q; + return result; +} + +/* Write n as a big-endian size_t, MSB at address p, LSB at + * p + sizeof(size_t) - 1. + */ +static void +write_size_t(void *p, size_t n) +{ + uint8_t *q = (uint8_t *)p + SST - 1; + int i; + + for (i = SST; --i >= 0; --q) { + *q = (uint8_t)(n & 0xff); + n >>= 8; + } +} + +/* Let S = sizeof(size_t). The debug malloc asks for 4 * S extra bytes and + fills them with useful stuff, here calling the underlying malloc's result p: + +p[0: S] + Number of bytes originally asked for. This is a size_t, big-endian (easier + to read in a memory dump). +p[S] + API ID. See PEP 445. This is a character, but seems undocumented. +p[S+1: 2*S] + Copies of PYMEM_FORBIDDENBYTE. Used to catch under- writes and reads. +p[2*S: 2*S+n] + The requested memory, filled with copies of PYMEM_CLEANBYTE. + Used to catch reference to uninitialized memory. + &p[2*S] is returned. Note that this is 8-byte aligned if pymalloc + handled the request itself. +p[2*S+n: 2*S+n+S] + Copies of PYMEM_FORBIDDENBYTE. Used to catch over- writes and reads. +p[2*S+n+S: 2*S+n+2*S] + A serial number, incremented by 1 on each call to _PyMem_DebugMalloc + and _PyMem_DebugRealloc. + This is a big-endian size_t. + If "bad memory" is detected later, the serial number gives an + excellent way to set a breakpoint on the next run, to capture the + instant at which this block was passed out. + +If PYMEM_DEBUG_SERIALNO is not defined (default), the debug malloc only asks +for 3 * S extra bytes, and omits the last serialno field. +*/ + +static void * +_PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) +{ + debug_alloc_api_t *api = (debug_alloc_api_t *)ctx; + uint8_t *p; /* base address of malloc'ed pad block */ + uint8_t *data; /* p + 2*SST == pointer to data bytes */ + uint8_t *tail; /* data + nbytes == pointer to tail pad bytes */ + size_t total; /* nbytes + PYMEM_DEBUG_EXTRA_BYTES */ + + if (nbytes > (size_t)PY_SSIZE_T_MAX - PYMEM_DEBUG_EXTRA_BYTES) { + /* integer overflow: can't represent total as a Py_ssize_t */ + return NULL; + } + total = nbytes + PYMEM_DEBUG_EXTRA_BYTES; + + /* Layout: [SSSS IFFF CCCC...CCCC FFFF NNNN] + ^--- p ^--- data ^--- tail + S: nbytes stored as size_t + I: API identifier (1 byte) + F: Forbidden bytes (size_t - 1 bytes before, size_t bytes after) + C: Clean bytes used later to store actual data + N: Serial number stored as size_t + + If PYMEM_DEBUG_SERIALNO is not defined (default), the last NNNN field + is omitted. */ + + if (use_calloc) { + p = (uint8_t *)api->alloc.calloc(api->alloc.ctx, 1, total); + } + else { + p = (uint8_t *)api->alloc.malloc(api->alloc.ctx, total); + } + if (p == NULL) { + return NULL; + } + data = p + 2*SST; + +#ifdef PYMEM_DEBUG_SERIALNO + bumpserialno(); +#endif + + /* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */ + write_size_t(p, nbytes); + p[SST] = (uint8_t)api->api_id; + memset(p + SST + 1, PYMEM_FORBIDDENBYTE, SST-1); + + if (nbytes > 0 && !use_calloc) { + memset(data, PYMEM_CLEANBYTE, nbytes); + } + + /* at tail, write pad (SST bytes) and serialno (SST bytes) */ + tail = data + nbytes; + memset(tail, PYMEM_FORBIDDENBYTE, SST); +#ifdef PYMEM_DEBUG_SERIALNO + write_size_t(tail + SST, serialno); +#endif + + return data; +} + +static void * +_PyMem_DebugRawMalloc(void *ctx, size_t nbytes) +{ + return _PyMem_DebugRawAlloc(0, ctx, nbytes); +} + +static void * +_PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) +{ + size_t nbytes; + assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize); + nbytes = nelem * elsize; + return _PyMem_DebugRawAlloc(1, ctx, nbytes); +} + + +/* The debug free first checks the 2*SST bytes on each end for sanity (in + particular, that the FORBIDDENBYTEs with the api ID are still intact). + Then fills the original bytes with PYMEM_DEADBYTE. + Then calls the underlying free. +*/ +static void +_PyMem_DebugRawFree(void *ctx, void *p) +{ + /* PyMem_Free(NULL) has no effect */ + if (p == NULL) { + return; + } + + debug_alloc_api_t *api = (debug_alloc_api_t *)ctx; + uint8_t *q = (uint8_t *)p - 2*SST; /* address returned from malloc */ + size_t nbytes; + + _PyMem_DebugCheckAddress(api->api_id, p); + nbytes = read_size_t(q); + nbytes += PYMEM_DEBUG_EXTRA_BYTES; + memset(q, PYMEM_DEADBYTE, nbytes); + api->alloc.free(api->alloc.ctx, q); +} + + +static void * +_PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) +{ + if (p == NULL) { + return _PyMem_DebugRawAlloc(0, ctx, nbytes); + } + + debug_alloc_api_t *api = (debug_alloc_api_t *)ctx; + uint8_t *head; /* base address of malloc'ed pad block */ + uint8_t *data; /* pointer to data bytes */ + uint8_t *r; + uint8_t *tail; /* data + nbytes == pointer to tail pad bytes */ + size_t total; /* 2 * SST + nbytes + 2 * SST */ + size_t original_nbytes; +#define ERASED_SIZE 64 + uint8_t save[2*ERASED_SIZE]; /* A copy of erased bytes. */ + + _PyMem_DebugCheckAddress(api->api_id, p); + + data = (uint8_t *)p; + head = data - 2*SST; + original_nbytes = read_size_t(head); + if (nbytes > (size_t)PY_SSIZE_T_MAX - PYMEM_DEBUG_EXTRA_BYTES) { + /* integer overflow: can't represent total as a Py_ssize_t */ + return NULL; + } + total = nbytes + PYMEM_DEBUG_EXTRA_BYTES; + + tail = data + original_nbytes; +#ifdef PYMEM_DEBUG_SERIALNO + size_t block_serialno = read_size_t(tail + SST); +#endif + /* Mark the header, the trailer, ERASED_SIZE bytes at the begin and + ERASED_SIZE bytes at the end as dead and save the copy of erased bytes. + */ + if (original_nbytes <= sizeof(save)) { + memcpy(save, data, original_nbytes); + memset(data - 2 * SST, PYMEM_DEADBYTE, + original_nbytes + PYMEM_DEBUG_EXTRA_BYTES); + } + else { + memcpy(save, data, ERASED_SIZE); + memset(head, PYMEM_DEADBYTE, ERASED_SIZE + 2 * SST); + memcpy(&save[ERASED_SIZE], tail - ERASED_SIZE, ERASED_SIZE); + memset(tail - ERASED_SIZE, PYMEM_DEADBYTE, + ERASED_SIZE + PYMEM_DEBUG_EXTRA_BYTES - 2 * SST); + } + + /* Resize and add decorations. */ + r = (uint8_t *)api->alloc.realloc(api->alloc.ctx, head, total); + if (r == NULL) { + /* if realloc() failed: rewrite header and footer which have + just been erased */ + nbytes = original_nbytes; + } + else { + head = r; +#ifdef PYMEM_DEBUG_SERIALNO + bumpserialno(); + block_serialno = serialno; +#endif + } + data = head + 2*SST; + + write_size_t(head, nbytes); + head[SST] = (uint8_t)api->api_id; + memset(head + SST + 1, PYMEM_FORBIDDENBYTE, SST-1); + + tail = data + nbytes; + memset(tail, PYMEM_FORBIDDENBYTE, SST); +#ifdef PYMEM_DEBUG_SERIALNO + write_size_t(tail + SST, block_serialno); +#endif + + /* Restore saved bytes. */ + if (original_nbytes <= sizeof(save)) { + memcpy(data, save, Py_MIN(nbytes, original_nbytes)); + } + else { + size_t i = original_nbytes - ERASED_SIZE; + memcpy(data, save, Py_MIN(nbytes, ERASED_SIZE)); + if (nbytes > i) { + memcpy(data + i, &save[ERASED_SIZE], + Py_MIN(nbytes - i, ERASED_SIZE)); + } + } + + if (r == NULL) { + return NULL; + } + + if (nbytes > original_nbytes) { + /* growing: mark new extra memory clean */ + memset(data + original_nbytes, PYMEM_CLEANBYTE, + nbytes - original_nbytes); + } + + return data; +} + +static void +_PyMem_DebugCheckGIL(void) +{ + if (!PyGILState_Check()) + Py_FatalError("Python memory allocator called " + "without holding the GIL"); +} + +static void * +_PyMem_DebugMalloc(void *ctx, size_t nbytes) +{ + _PyMem_DebugCheckGIL(); + return _PyMem_DebugRawMalloc(ctx, nbytes); +} + +static void * +_PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) +{ + _PyMem_DebugCheckGIL(); + return _PyMem_DebugRawCalloc(ctx, nelem, elsize); +} + + +static void +_PyMem_DebugFree(void *ctx, void *ptr) +{ + _PyMem_DebugCheckGIL(); + _PyMem_DebugRawFree(ctx, ptr); +} + + +static void * +_PyMem_DebugRealloc(void *ctx, void *ptr, size_t nbytes) +{ + _PyMem_DebugCheckGIL(); + return _PyMem_DebugRawRealloc(ctx, ptr, nbytes); +} + +/* Check the forbidden bytes on both ends of the memory allocated for p. + * If anything is wrong, print info to stderr via _PyObject_DebugDumpAddress, + * and call Py_FatalError to kill the program. + * The API id, is also checked. + */ +static void +_PyMem_DebugCheckAddress(char api, const void *p) +{ + const uint8_t *q = (const uint8_t *)p; + char msgbuf[64]; + const char *msg; + size_t nbytes; + const uint8_t *tail; + int i; + char id; + + if (p == NULL) { + msg = "didn't expect a NULL pointer"; + goto error; + } + + /* Check the API id */ + id = (char)q[-SST]; + if (id != api) { + msg = msgbuf; + snprintf(msgbuf, sizeof(msgbuf), "bad ID: Allocated using API '%c', verified using API '%c'", id, api); + msgbuf[sizeof(msgbuf)-1] = 0; + goto error; + } + + /* Check the stuff at the start of p first: if there's underwrite + * corruption, the number-of-bytes field may be nuts, and checking + * the tail could lead to a segfault then. + */ + for (i = SST-1; i >= 1; --i) { + if (*(q-i) != PYMEM_FORBIDDENBYTE) { + msg = "bad leading pad byte"; + goto error; + } + } + + nbytes = read_size_t(q - 2*SST); + tail = q + nbytes; + for (i = 0; i < SST; ++i) { + if (tail[i] != PYMEM_FORBIDDENBYTE) { + msg = "bad trailing pad byte"; + goto error; + } + } + + return; + +error: + _PyObject_DebugDumpAddress(p); + Py_FatalError(msg); +} + +/* Display info to stderr about the memory block at p. */ +static void +_PyObject_DebugDumpAddress(const void *p) +{ + const uint8_t *q = (const uint8_t *)p; + const uint8_t *tail; + size_t nbytes; + int i; + int ok; + char id; + + fprintf(stderr, "Debug memory block at address p=%p:", p); + if (p == NULL) { + fprintf(stderr, "\n"); + return; + } + id = (char)q[-SST]; + fprintf(stderr, " API '%c'\n", id); + + nbytes = read_size_t(q - 2*SST); + fprintf(stderr, " %" PY_FORMAT_SIZE_T "u bytes originally " + "requested\n", nbytes); + + /* In case this is nuts, check the leading pad bytes first. */ + fprintf(stderr, " The %d pad bytes at p-%d are ", SST-1, SST-1); + ok = 1; + for (i = 1; i <= SST-1; ++i) { + if (*(q-i) != PYMEM_FORBIDDENBYTE) { + ok = 0; + break; + } + } + if (ok) + fputs("FORBIDDENBYTE, as expected.\n", stderr); + else { + fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n", + PYMEM_FORBIDDENBYTE); + for (i = SST-1; i >= 1; --i) { + const uint8_t byte = *(q-i); + fprintf(stderr, " at p-%d: 0x%02x", i, byte); + if (byte != PYMEM_FORBIDDENBYTE) + fputs(" *** OUCH", stderr); + fputc('\n', stderr); + } + + fputs(" Because memory is corrupted at the start, the " + "count of bytes requested\n" + " may be bogus, and checking the trailing pad " + "bytes may segfault.\n", stderr); + } + + tail = q + nbytes; + fprintf(stderr, " The %d pad bytes at tail=%p are ", SST, (void *)tail); + ok = 1; + for (i = 0; i < SST; ++i) { + if (tail[i] != PYMEM_FORBIDDENBYTE) { + ok = 0; + break; + } + } + if (ok) + fputs("FORBIDDENBYTE, as expected.\n", stderr); + else { + fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n", + PYMEM_FORBIDDENBYTE); + for (i = 0; i < SST; ++i) { + const uint8_t byte = tail[i]; + fprintf(stderr, " at tail+%d: 0x%02x", + i, byte); + if (byte != PYMEM_FORBIDDENBYTE) + fputs(" *** OUCH", stderr); + fputc('\n', stderr); + } + } + +#ifdef PYMEM_DEBUG_SERIALNO + size_t serial = read_size_t(tail + SST); + fprintf(stderr, " The block was made by call #%" PY_FORMAT_SIZE_T + "u to debug malloc/realloc.\n", serial); +#endif + + if (nbytes > 0) { + i = 0; + fputs(" Data at p:", stderr); + /* print up to 8 bytes at the start */ + while (q < tail && i < 8) { + fprintf(stderr, " %02x", *q); + ++i; + ++q; + } + /* and up to 8 at the end */ + if (q < tail) { + if (tail - q > 8) { + fputs(" ...", stderr); + q = tail - 8; + } + while (q < tail) { + fprintf(stderr, " %02x", *q); + ++q; + } + } + fputc('\n', stderr); + } + fputc('\n', stderr); + + fflush(stderr); + _PyMem_DumpTraceback(fileno(stderr), p); +} + + +static size_t +printone(FILE *out, const char* msg, size_t value) +{ + int i, k; + char buf[100]; + size_t origvalue = value; + + fputs(msg, out); + for (i = (int)strlen(msg); i < 35; ++i) + fputc(' ', out); + fputc('=', out); + + /* Write the value with commas. */ + i = 22; + buf[i--] = '\0'; + buf[i--] = '\n'; + k = 3; + do { + size_t nextvalue = value / 10; + unsigned int digit = (unsigned int)(value - nextvalue * 10); + value = nextvalue; + buf[i--] = (char)(digit + '0'); + --k; + if (k == 0 && value && i >= 0) { + k = 3; + buf[i--] = ','; + } + } while (value && i >= 0); + + while (i >= 0) + buf[i--] = ' '; + fputs(buf, out); + + return origvalue; +} + +void +_PyDebugAllocatorStats(FILE *out, + const char *block_name, int num_blocks, size_t sizeof_block) +{ + char buf1[128]; + char buf2[128]; + PyOS_snprintf(buf1, sizeof(buf1), + "%d %ss * %" PY_FORMAT_SIZE_T "d bytes each", + num_blocks, block_name, sizeof_block); + PyOS_snprintf(buf2, sizeof(buf2), + "%48s ", buf1); + (void)printone(out, buf2, num_blocks * sizeof_block); +} + + +#ifdef WITH_PYMALLOC + +#ifdef Py_DEBUG +/* Is target in the list? The list is traversed via the nextpool pointers. + * The list may be NULL-terminated, or circular. Return 1 if target is in + * list, else 0. + */ +static int +pool_is_in_list(const poolp target, poolp list) +{ + poolp origlist = list; + assert(target != NULL); + if (list == NULL) + return 0; + do { + if (target == list) + return 1; + list = list->nextpool; + } while (list != NULL && list != origlist); + return 0; +} +#endif + +/* Print summary info to "out" about the state of pymalloc's structures. + * In Py_DEBUG mode, also perform some expensive internal consistency + * checks. + * + * Return 0 if the memory debug hooks are not installed or no statistics was + * written into out, return 1 otherwise. + */ +int +_PyObject_DebugMallocStats(FILE *out) +{ + if (!_PyMem_PymallocEnabled()) { + return 0; + } + + uint i; + const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT; + /* # of pools, allocated blocks, and free blocks per class index */ + size_t numpools[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT]; + size_t numblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT]; + size_t numfreeblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT]; + /* total # of allocated bytes in used and full pools */ + size_t allocated_bytes = 0; + /* total # of available bytes in used pools */ + size_t available_bytes = 0; + /* # of free pools + pools not yet carved out of current arena */ + uint numfreepools = 0; + /* # of bytes for arena alignment padding */ + size_t arena_alignment = 0; + /* # of bytes in used and full pools used for pool_headers */ + size_t pool_header_bytes = 0; + /* # of bytes in used and full pools wasted due to quantization, + * i.e. the necessarily leftover space at the ends of used and + * full pools. + */ + size_t quantization = 0; + /* # of arenas actually allocated. */ + size_t narenas = 0; + /* running total -- should equal narenas * ARENA_SIZE */ + size_t total; + char buf[128]; + + fprintf(out, "Small block threshold = %d, in %u size classes.\n", + SMALL_REQUEST_THRESHOLD, numclasses); + + for (i = 0; i < numclasses; ++i) + numpools[i] = numblocks[i] = numfreeblocks[i] = 0; + + /* Because full pools aren't linked to from anything, it's easiest + * to march over all the arenas. If we're lucky, most of the memory + * will be living in full pools -- would be a shame to miss them. + */ + for (i = 0; i < maxarenas; ++i) { + uint j; + uintptr_t base = arenas[i].address; + + /* Skip arenas which are not allocated. */ + if (arenas[i].address == (uintptr_t)NULL) + continue; + narenas += 1; + + numfreepools += arenas[i].nfreepools; + + /* round up to pool alignment */ + if (base & (uintptr_t)POOL_SIZE_MASK) { + arena_alignment += POOL_SIZE; + base &= ~(uintptr_t)POOL_SIZE_MASK; + base += POOL_SIZE; + } + + /* visit every pool in the arena */ + assert(base <= (uintptr_t) arenas[i].pool_address); + for (j = 0; base < (uintptr_t) arenas[i].pool_address; + ++j, base += POOL_SIZE) { + poolp p = (poolp)base; + const uint sz = p->szidx; + uint freeblocks; + + if (p->ref.count == 0) { + /* currently unused */ +#ifdef Py_DEBUG + assert(pool_is_in_list(p, arenas[i].freepools)); +#endif + continue; + } + ++numpools[sz]; + numblocks[sz] += p->ref.count; + freeblocks = NUMBLOCKS(sz) - p->ref.count; + numfreeblocks[sz] += freeblocks; +#ifdef Py_DEBUG + if (freeblocks > 0) + assert(pool_is_in_list(p, usedpools[sz + sz])); +#endif + } + } + assert(narenas == narenas_currently_allocated); + + fputc('\n', out); + fputs("class size num pools blocks in use avail blocks\n" + "----- ---- --------- ------------- ------------\n", + out); + + for (i = 0; i < numclasses; ++i) { + size_t p = numpools[i]; + size_t b = numblocks[i]; + size_t f = numfreeblocks[i]; + uint size = INDEX2SIZE(i); + if (p == 0) { + assert(b == 0 && f == 0); + continue; + } + fprintf(out, "%5u %6u " + "%11" PY_FORMAT_SIZE_T "u " + "%15" PY_FORMAT_SIZE_T "u " + "%13" PY_FORMAT_SIZE_T "u\n", + i, size, p, b, f); + allocated_bytes += b * size; + available_bytes += f * size; + pool_header_bytes += p * POOL_OVERHEAD; + quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size); + } + fputc('\n', out); +#ifdef PYMEM_DEBUG_SERIALNO + if (_PyMem_DebugEnabled()) { + (void)printone(out, "# times object malloc called", serialno); + } +#endif + (void)printone(out, "# arenas allocated total", ntimes_arena_allocated); + (void)printone(out, "# arenas reclaimed", ntimes_arena_allocated - narenas); + (void)printone(out, "# arenas highwater mark", narenas_highwater); + (void)printone(out, "# arenas allocated current", narenas); + + PyOS_snprintf(buf, sizeof(buf), + "%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena", + narenas, ARENA_SIZE); + (void)printone(out, buf, narenas * ARENA_SIZE); + + fputc('\n', out); + + total = printone(out, "# bytes in allocated blocks", allocated_bytes); + total += printone(out, "# bytes in available blocks", available_bytes); + + PyOS_snprintf(buf, sizeof(buf), + "%u unused pools * %d bytes", numfreepools, POOL_SIZE); + total += printone(out, buf, (size_t)numfreepools * POOL_SIZE); + + total += printone(out, "# bytes lost to pool headers", pool_header_bytes); + total += printone(out, "# bytes lost to quantization", quantization); + total += printone(out, "# bytes lost to arena alignment", arena_alignment); + (void)printone(out, "Total", total); + return 1; +} + +#endif /* #ifdef WITH_PYMALLOC */ diff --git a/python/Objects/odictobject.c b/python/Objects/odictobject.c new file mode 100755 index 0000000..6076b03 --- /dev/null +++ b/python/Objects/odictobject.c @@ -0,0 +1,2304 @@ +/* Ordered Dictionary object implementation. + +This implementation is necessarily explicitly equivalent to the pure Python +OrderedDict class in Lib/collections/__init__.py. The strategy there +involves using a doubly-linked-list to capture the order. We keep to that +strategy, using a lower-level linked-list. + +About the Linked-List +===================== + +For the linked list we use a basic doubly-linked-list. Using a circularly- +linked-list does have some benefits, but they don't apply so much here +since OrderedDict is focused on the ends of the list (for the most part). +Furthermore, there are some features of generic linked-lists that we simply +don't need for OrderedDict. Thus a simple custom implementation meets our +needs. Alternatives to our simple approach include the QCIRCLE_* +macros from BSD's queue.h, and the linux's list.h. + +Getting O(1) Node Lookup +------------------------ + +One invariant of Python's OrderedDict is that it preserves time complexity +of dict's methods, particularly the O(1) operations. Simply adding a +linked-list on top of dict is not sufficient here; operations for nodes in +the middle of the linked-list implicitly require finding the node first. +With a simple linked-list like we're using, that is an O(n) operation. +Consequently, methods like __delitem__() would change from O(1) to O(n), +which is unacceptable. + +In order to preserve O(1) performance for node removal (finding nodes), we +must do better than just looping through the linked-list. Here are options +we've considered: + +1. use a second dict to map keys to nodes (a la the pure Python version). +2. keep a simple hash table mirroring the order of dict's, mapping each key + to the corresponding node in the linked-list. +3. use a version of shared keys (split dict) that allows non-unicode keys. +4. have the value stored for each key be a (value, node) pair, and adjust + __getitem__(), get(), etc. accordingly. + +The approach with the least performance impact (time and space) is #2, +mirroring the key order of dict's dk_entries with an array of node pointers. +While lookdict() and friends (dk_lookup) don't give us the index into the +array, we make use of pointer arithmetic to get that index. An alternative +would be to refactor lookdict() to provide the index, explicitly exposing +the implementation detail. We could even just use a custom lookup function +for OrderedDict that facilitates our need. However, both approaches are +significantly more complicated than just using pointer arithmetic. + +The catch with mirroring the hash table ordering is that we have to keep +the ordering in sync through any dict resizes. However, that order only +matters during node lookup. We can simply defer any potential resizing +until we need to do a lookup. + +Linked-List Nodes +----------------- + +The current implementation stores a pointer to the associated key only. +One alternative would be to store a pointer to the PyDictKeyEntry instead. +This would save one pointer de-reference per item, which is nice during +calls to values() and items(). However, it adds unnecessary overhead +otherwise, so we stick with just the key. + +Linked-List API +--------------- + +As noted, the linked-list implemented here does not have all the bells and +whistles. However, we recognize that the implementation may need to +change to accommodate performance improvements or extra functionality. To +that end, we use a simple API to interact with the linked-list. Here's a +summary of the methods/macros: + +Node info: + +* _odictnode_KEY(node) +* _odictnode_VALUE(od, node) +* _odictnode_PREV(node) +* _odictnode_NEXT(node) + +Linked-List info: + +* _odict_FIRST(od) +* _odict_LAST(od) +* _odict_EMPTY(od) +* _odict_FOREACH(od, node) - used in place of `for (node=...)` + +For adding nodes: + +* _odict_add_head(od, node) +* _odict_add_tail(od, node) +* _odict_add_new_node(od, key, hash) + +For removing nodes: + +* _odict_clear_node(od, node, key, hash) +* _odict_clear_nodes(od, clear_each) + +Others: + +* _odict_find_node_hash(od, key, hash) +* _odict_find_node(od, key) +* _odict_keys_equal(od1, od2) + +And here's a look at how the linked-list relates to the OrderedDict API: + +============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === === +method key val prev next mem 1st last empty iter find add rmv clr keq +============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === === +__del__ ~ X +__delitem__ free ~ node +__eq__ ~ X +__iter__ X X +__new__ X X +__reduce__ X ~ X +__repr__ X X X +__reversed__ X X +__setitem__ key +__sizeof__ size X +clear ~ ~ X +copy X X X +items X X X +keys X X +move_to_end X X X ~ h/t key +pop free key +popitem X X free X X node +setdefault ~ ? ~ +values X X +============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === === + +__delitem__ is the only method that directly relies on finding an arbitrary +node in the linked-list. Everything else is iteration or relates to the +ends of the linked-list. + +Situation that Endangers Consistency +------------------------------------ +Using a raw linked-list for OrderedDict exposes a key situation that can +cause problems. If a node is stored in a variable, there is a chance that +the node may have been deallocated before the variable gets used, thus +potentially leading to a segmentation fault. A key place where this shows +up is during iteration through the linked list (via _odict_FOREACH or +otherwise). + +A number of solutions are available to resolve this situation: + +* defer looking up the node until as late as possible and certainly after + any code that could possibly result in a deletion; +* if the node is needed both before and after a point where the node might + be removed, do a check before using the node at the "after" location to + see if the node is still valid; +* like the last one, but simply pull the node again to ensure it's right; +* keep the key in the variable instead of the node and then look up the + node using the key at the point where the node is needed (this is what + we do for the iterators). + +Another related problem, preserving consistent ordering during iteration, +is described below. That one is not exclusive to using linked-lists. + + +Challenges from Subclassing dict +================================ + +OrderedDict subclasses dict, which is an unusual relationship between two +builtin types (other than the base object type). Doing so results in +some complication and deserves further explanation. There are two things +to consider here. First, in what circumstances or with what adjustments +can OrderedDict be used as a drop-in replacement for dict (at the C level)? +Second, how can the OrderedDict implementation leverage the dict +implementation effectively without introducing unnecessary coupling or +inefficiencies? + +This second point is reflected here and in the implementation, so the +further focus is on the first point. It is worth noting that for +overridden methods, the dict implementation is deferred to as much as +possible. Furthermore, coupling is limited to as little as is reasonable. + +Concrete API Compatibility +-------------------------- + +Use of the concrete C-API for dict (PyDict_*) with OrderedDict is +problematic. (See http://bugs.python.org/issue10977.) The concrete API +has a number of hard-coded assumptions tied to the dict implementation. +This is, in part, due to performance reasons, which is understandable +given the part dict plays in Python. + +Any attempt to replace dict with OrderedDict for any role in the +interpreter (e.g. **kwds) faces a challenge. Such any effort must +recognize that the instances in affected locations currently interact with +the concrete API. + +Here are some ways to address this challenge: + +1. Change the relevant usage of the concrete API in CPython and add + PyDict_CheckExact() calls to each of the concrete API functions. +2. Adjust the relevant concrete API functions to explicitly accommodate + OrderedDict. +3. As with #1, add the checks, but improve the abstract API with smart fast + paths for dict and OrderedDict, and refactor CPython to use the abstract + API. Improvements to the abstract API would be valuable regardless. + +Adding the checks to the concrete API would help make any interpreter +switch to OrderedDict less painful for extension modules. However, this +won't work. The equivalent C API call to `dict.__setitem__(obj, k, v)` +is 'PyDict_SetItem(obj, k, v)`. This illustrates how subclasses in C call +the base class's methods, since there is no equivalent of super() in the +C API. Calling into Python for parent class API would work, but some +extension modules already rely on this feature of the concrete API. + +For reference, here is a breakdown of some of the dict concrete API: + +========================== ============= ======================= +concrete API uses abstract API +========================== ============= ======================= +PyDict_Check PyMapping_Check +(PyDict_CheckExact) - +(PyDict_New) - +(PyDictProxy_New) - +PyDict_Clear - +PyDict_Contains PySequence_Contains +PyDict_Copy - +PyDict_SetItem PyObject_SetItem +PyDict_SetItemString PyMapping_SetItemString +PyDict_DelItem PyMapping_DelItem +PyDict_DelItemString PyMapping_DelItemString +PyDict_GetItem - +PyDict_GetItemWithError PyObject_GetItem +_PyDict_GetItemIdWithError - +PyDict_GetItemString PyMapping_GetItemString +PyDict_Items PyMapping_Items +PyDict_Keys PyMapping_Keys +PyDict_Values PyMapping_Values +PyDict_Size PyMapping_Size + PyMapping_Length +PyDict_Next PyIter_Next +_PyDict_Next - +PyDict_Merge - +PyDict_Update - +PyDict_MergeFromSeq2 - +PyDict_ClearFreeList - +- PyMapping_HasKeyString +- PyMapping_HasKey +========================== ============= ======================= + + +The dict Interface Relative to OrderedDict +========================================== + +Since OrderedDict subclasses dict, understanding the various methods and +attributes of dict is important for implementing OrderedDict. + +Relevant Type Slots +------------------- + +================= ================ =================== ================ +slot attribute object dict +================= ================ =================== ================ +tp_dealloc - object_dealloc dict_dealloc +tp_repr __repr__ object_repr dict_repr +sq_contains __contains__ - dict_contains +mp_length __len__ - dict_length +mp_subscript __getitem__ - dict_subscript +mp_ass_subscript __setitem__ - dict_ass_sub + __delitem__ +tp_hash __hash__ _Py_HashPointer ..._HashNotImpl +tp_str __str__ object_str - +tp_getattro __getattribute__ ..._GenericGetAttr (repeated) + __getattr__ +tp_setattro __setattr__ ..._GenericSetAttr (disabled) +tp_doc __doc__ (literal) dictionary_doc +tp_traverse - - dict_traverse +tp_clear - - dict_tp_clear +tp_richcompare __eq__ object_richcompare dict_richcompare + __ne__ +tp_weaklistoffset (__weakref__) - - +tp_iter __iter__ - dict_iter +tp_dictoffset (__dict__) - - +tp_init __init__ object_init dict_init +tp_alloc - PyType_GenericAlloc (repeated) +tp_new __new__ object_new dict_new +tp_free - PyObject_Del PyObject_GC_Del +================= ================ =================== ================ + +Relevant Methods +---------------- + +================ =================== =============== +method object dict +================ =================== =============== +__reduce__ object_reduce - +__sizeof__ object_sizeof dict_sizeof +clear - dict_clear +copy - dict_copy +fromkeys - dict_fromkeys +get - dict_get +items - dictitems_new +keys - dictkeys_new +pop - dict_pop +popitem - dict_popitem +setdefault - dict_setdefault +update - dict_update +values - dictvalues_new +================ =================== =============== + + +Pure Python OrderedDict +======================= + +As already noted, compatibility with the pure Python OrderedDict +implementation is a key goal of this C implementation. To further that +goal, here's a summary of how OrderedDict-specific methods are implemented +in collections/__init__.py. Also provided is an indication of which +methods directly mutate or iterate the object, as well as any relationship +with the underlying linked-list. + +============= ============== == ================ === === ==== +method impl used ll uses inq mut iter +============= ============== == ================ === === ==== +__contains__ dict - - X +__delitem__ OrderedDict Y dict.__delitem__ X +__eq__ OrderedDict N OrderedDict ~ + dict.__eq__ + __iter__ +__getitem__ dict - - X +__iter__ OrderedDict Y - X +__init__ OrderedDict N update +__len__ dict - - X +__ne__ MutableMapping - __eq__ ~ +__reduce__ OrderedDict N OrderedDict ~ + __iter__ + __getitem__ +__repr__ OrderedDict N __class__ ~ + items +__reversed__ OrderedDict Y - X +__setitem__ OrderedDict Y __contains__ X + dict.__setitem__ +__sizeof__ OrderedDict Y __len__ ~ + __dict__ +clear OrderedDict Y dict.clear X +copy OrderedDict N __class__ + __init__ +fromkeys OrderedDict N __setitem__ +get dict - - ~ +items MutableMapping - ItemsView X +keys MutableMapping - KeysView X +move_to_end OrderedDict Y - X +pop OrderedDict N __contains__ X + __getitem__ + __delitem__ +popitem OrderedDict Y dict.pop X +setdefault OrderedDict N __contains__ ~ + __getitem__ + __setitem__ +update MutableMapping - __setitem__ ~ +values MutableMapping - ValuesView X +============= ============== == ================ === === ==== + +__reversed__ and move_to_end are both exclusive to OrderedDict. + + +C OrderedDict Implementation +============================ + +================= ================ +slot impl +================= ================ +tp_dealloc odict_dealloc +tp_repr odict_repr +mp_ass_subscript odict_ass_sub +tp_doc odict_doc +tp_traverse odict_traverse +tp_clear odict_tp_clear +tp_richcompare odict_richcompare +tp_weaklistoffset (offset) +tp_iter odict_iter +tp_dictoffset (offset) +tp_init odict_init +tp_alloc (repeated) +================= ================ + +================= ================ +method impl +================= ================ +__reduce__ odict_reduce +__sizeof__ odict_sizeof +clear odict_clear +copy odict_copy +fromkeys odict_fromkeys +items odictitems_new +keys odictkeys_new +pop odict_pop +popitem odict_popitem +setdefault odict_setdefault +update odict_update +values odictvalues_new +================= ================ + +Inherited unchanged from object/dict: + +================ ========================== +method type field +================ ========================== +- tp_free +__contains__ tp_as_sequence.sq_contains +__getattr__ tp_getattro +__getattribute__ tp_getattro +__getitem__ tp_as_mapping.mp_subscript +__hash__ tp_hash +__len__ tp_as_mapping.mp_length +__setattr__ tp_setattro +__str__ tp_str +get - +================ ========================== + + +Other Challenges +================ + +Preserving Ordering During Iteration +------------------------------------ +During iteration through an OrderedDict, it is possible that items could +get added, removed, or reordered. For a linked-list implementation, as +with some other implementations, that situation may lead to undefined +behavior. The documentation for dict mentions this in the `iter()` section +of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects. +In this implementation we follow dict's lead (as does the pure Python +implementation) for __iter__(), keys(), values(), and items(). + +For internal iteration (using _odict_FOREACH or not), there is still the +risk that not all nodes that we expect to be seen in the loop actually get +seen. Thus, we are careful in each of those places to ensure that they +are. This comes, of course, at a small price at each location. The +solutions are much the same as those detailed in the `Situation that +Endangers Consistency` section above. + + +Potential Optimizations +======================= + +* Allocate the nodes as a block via od_fast_nodes instead of individually. + - Set node->key to NULL to indicate the node is not-in-use. + - Add _odict_EXISTS()? + - How to maintain consistency across resizes? Existing node pointers + would be invalidated after a resize, which is particularly problematic + for the iterators. +* Use a more stream-lined implementation of update() and, likely indirectly, + __init__(). + +*/ + +/* TODO + +sooner: +- reentrancy (make sure everything is at a thread-safe state when calling + into Python). I've already checked this multiple times, but want to + make one more pass. +- add unit tests for reentrancy? + +later: +- make the dict views support the full set API (the pure Python impl does) +- implement a fuller MutableMapping API in C? +- move the MutableMapping implementation to abstract.c? +- optimize mutablemapping_update +- use PyObject_MALLOC (small object allocator) for odict nodes? +- support subclasses better (e.g. in odict_richcompare) + +*/ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "structmember.h" +#include "dict-common.h" +#include + +#include "clinic/odictobject.c.h" + +/*[clinic input] +class OrderedDict "PyODictObject *" "&PyODict_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ca0641cf6143d4af]*/ + + +typedef struct _odictnode _ODictNode; + +/* PyODictObject */ +struct _odictobject { + PyDictObject od_dict; /* the underlying dict */ + _ODictNode *od_first; /* first node in the linked list, if any */ + _ODictNode *od_last; /* last node in the linked list, if any */ + /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed + * by _odict_resize(). + * Note that we rely on implementation details of dict for both. */ + _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */ + Py_ssize_t od_fast_nodes_size; + void *od_resize_sentinel; /* changes if odict should be resized */ + + size_t od_state; /* incremented whenever the LL changes */ + PyObject *od_inst_dict; /* OrderedDict().__dict__ */ + PyObject *od_weakreflist; /* holds weakrefs to the odict */ +}; + + +/* ---------------------------------------------- + * odict keys (a simple doubly-linked list) + */ + +struct _odictnode { + PyObject *key; + Py_hash_t hash; + _ODictNode *next; + _ODictNode *prev; +}; + +#define _odictnode_KEY(node) \ + (node->key) +#define _odictnode_HASH(node) \ + (node->hash) +/* borrowed reference */ +#define _odictnode_VALUE(node, od) \ + PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node)) +#define _odictnode_PREV(node) (node->prev) +#define _odictnode_NEXT(node) (node->next) + +#define _odict_FIRST(od) (((PyODictObject *)od)->od_first) +#define _odict_LAST(od) (((PyODictObject *)od)->od_last) +#define _odict_EMPTY(od) (_odict_FIRST(od) == NULL) +#define _odict_FOREACH(od, node) \ + for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node)) + +/* Return the index into the hash table, regardless of a valid node. */ +static Py_ssize_t +_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash) +{ + PyObject *value = NULL; + PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys; + Py_ssize_t ix; + + ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value); + if (ix == DKIX_EMPTY) { + return keys->dk_nentries; /* index of new entry */ + } + if (ix < 0) + return -1; + /* We use pointer arithmetic to get the entry's index into the table. */ + return ix; +} + +/* Replace od->od_fast_nodes with a new table matching the size of dict's. */ +static int +_odict_resize(PyODictObject *od) +{ + Py_ssize_t size, i; + _ODictNode **fast_nodes, *node; + + /* Initialize a new "fast nodes" table. */ + size = ((PyDictObject *)od)->ma_keys->dk_size; + fast_nodes = PyMem_NEW(_ODictNode *, size); + if (fast_nodes == NULL) { + PyErr_NoMemory(); + return -1; + } + for (i = 0; i < size; i++) + fast_nodes[i] = NULL; + + /* Copy the current nodes into the table. */ + _odict_FOREACH(od, node) { + i = _odict_get_index_raw(od, _odictnode_KEY(node), + _odictnode_HASH(node)); + if (i < 0) { + PyMem_FREE(fast_nodes); + return -1; + } + fast_nodes[i] = node; + } + + /* Replace the old fast nodes table. */ + PyMem_FREE(od->od_fast_nodes); + od->od_fast_nodes = fast_nodes; + od->od_fast_nodes_size = size; + od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys; + return 0; +} + +/* Return the index into the hash table, regardless of a valid node. */ +static Py_ssize_t +_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash) +{ + PyDictKeysObject *keys; + + assert(key != NULL); + keys = ((PyDictObject *)od)->ma_keys; + + /* Ensure od_fast_nodes and dk_entries are in sync. */ + if (od->od_resize_sentinel != keys || + od->od_fast_nodes_size != keys->dk_size) { + int resize_res = _odict_resize(od); + if (resize_res < 0) + return -1; + } + + return _odict_get_index_raw(od, key, hash); +} + +/* Returns NULL if there was some error or the key was not found. */ +static _ODictNode * +_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash) +{ + Py_ssize_t index; + + if (_odict_EMPTY(od)) + return NULL; + index = _odict_get_index(od, key, hash); + if (index < 0) + return NULL; + assert(od->od_fast_nodes != NULL); + return od->od_fast_nodes[index]; +} + +static _ODictNode * +_odict_find_node(PyODictObject *od, PyObject *key) +{ + Py_ssize_t index; + Py_hash_t hash; + + if (_odict_EMPTY(od)) + return NULL; + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + index = _odict_get_index(od, key, hash); + if (index < 0) + return NULL; + assert(od->od_fast_nodes != NULL); + return od->od_fast_nodes[index]; +} + +static void +_odict_add_head(PyODictObject *od, _ODictNode *node) +{ + _odictnode_PREV(node) = NULL; + _odictnode_NEXT(node) = _odict_FIRST(od); + if (_odict_FIRST(od) == NULL) + _odict_LAST(od) = node; + else + _odictnode_PREV(_odict_FIRST(od)) = node; + _odict_FIRST(od) = node; + od->od_state++; +} + +static void +_odict_add_tail(PyODictObject *od, _ODictNode *node) +{ + _odictnode_PREV(node) = _odict_LAST(od); + _odictnode_NEXT(node) = NULL; + if (_odict_LAST(od) == NULL) + _odict_FIRST(od) = node; + else + _odictnode_NEXT(_odict_LAST(od)) = node; + _odict_LAST(od) = node; + od->od_state++; +} + +/* adds the node to the end of the list */ +static int +_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash) +{ + Py_ssize_t i; + _ODictNode *node; + + Py_INCREF(key); + i = _odict_get_index(od, key, hash); + if (i < 0) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + Py_DECREF(key); + return -1; + } + assert(od->od_fast_nodes != NULL); + if (od->od_fast_nodes[i] != NULL) { + /* We already have a node for the key so there's no need to add one. */ + Py_DECREF(key); + return 0; + } + + /* must not be added yet */ + node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode)); + if (node == NULL) { + Py_DECREF(key); + PyErr_NoMemory(); + return -1; + } + + _odictnode_KEY(node) = key; + _odictnode_HASH(node) = hash; + _odict_add_tail(od, node); + od->od_fast_nodes[i] = node; + return 0; +} + +/* Putting the decref after the free causes problems. */ +#define _odictnode_DEALLOC(node) \ + do { \ + Py_DECREF(_odictnode_KEY(node)); \ + PyMem_FREE((void *)node); \ + } while (0) + +/* Repeated calls on the same node are no-ops. */ +static void +_odict_remove_node(PyODictObject *od, _ODictNode *node) +{ + if (_odict_FIRST(od) == node) + _odict_FIRST(od) = _odictnode_NEXT(node); + else if (_odictnode_PREV(node) != NULL) + _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node); + + if (_odict_LAST(od) == node) + _odict_LAST(od) = _odictnode_PREV(node); + else if (_odictnode_NEXT(node) != NULL) + _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node); + + _odictnode_PREV(node) = NULL; + _odictnode_NEXT(node) = NULL; + od->od_state++; +} + +/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll + get all sorts of problems here. In PyODict_DelItem we make sure to + call _odict_clear_node first. + + This matters in the case of colliding keys. Suppose we add 3 keys: + [A, B, C], where the hash of C collides with A and the next possible + index in the hash table is occupied by B. If we remove B then for C + the dict's looknode func will give us the old index of B instead of + the index we got before deleting B. However, the node for C in + od_fast_nodes is still at the old dict index of C. Thus to be sure + things don't get out of sync, we clear the node in od_fast_nodes + *before* calling PyDict_DelItem. + + The same must be done for any other OrderedDict operations where + we modify od_fast_nodes. +*/ +static int +_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key, + Py_hash_t hash) +{ + Py_ssize_t i; + + assert(key != NULL); + if (_odict_EMPTY(od)) { + /* Let later code decide if this is a KeyError. */ + return 0; + } + + i = _odict_get_index(od, key, hash); + if (i < 0) + return PyErr_Occurred() ? -1 : 0; + + assert(od->od_fast_nodes != NULL); + if (node == NULL) + node = od->od_fast_nodes[i]; + assert(node == od->od_fast_nodes[i]); + if (node == NULL) { + /* Let later code decide if this is a KeyError. */ + return 0; + } + + // Now clear the node. + od->od_fast_nodes[i] = NULL; + _odict_remove_node(od, node); + _odictnode_DEALLOC(node); + return 0; +} + +static void +_odict_clear_nodes(PyODictObject *od) +{ + _ODictNode *node, *next; + + PyMem_FREE(od->od_fast_nodes); + od->od_fast_nodes = NULL; + od->od_fast_nodes_size = 0; + od->od_resize_sentinel = NULL; + + node = _odict_FIRST(od); + _odict_FIRST(od) = NULL; + _odict_LAST(od) = NULL; + while (node != NULL) { + next = _odictnode_NEXT(node); + _odictnode_DEALLOC(node); + node = next; + } +} + +/* There isn't any memory management of nodes past this point. */ +#undef _odictnode_DEALLOC + +static int +_odict_keys_equal(PyODictObject *a, PyODictObject *b) +{ + _ODictNode *node_a, *node_b; + + node_a = _odict_FIRST(a); + node_b = _odict_FIRST(b); + while (1) { + if (node_a == NULL && node_b == NULL) + /* success: hit the end of each at the same time */ + return 1; + else if (node_a == NULL || node_b == NULL) + /* unequal length */ + return 0; + else { + int res = PyObject_RichCompareBool( + (PyObject *)_odictnode_KEY(node_a), + (PyObject *)_odictnode_KEY(node_b), + Py_EQ); + if (res < 0) + return res; + else if (res == 0) + return 0; + + /* otherwise it must match, so move on to the next one */ + node_a = _odictnode_NEXT(node_a); + node_b = _odictnode_NEXT(node_b); + } + } +} + + +/* ---------------------------------------------- + * OrderedDict mapping methods + */ + +/* mp_ass_subscript: __setitem__() and __delitem__() */ + +static int +odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w) +{ + if (w == NULL) + return PyODict_DelItem((PyObject *)od, v); + else + return PyODict_SetItem((PyObject *)od, v, w); +} + +/* tp_as_mapping */ + +static PyMappingMethods odict_as_mapping = { + 0, /*mp_length*/ + 0, /*mp_subscript*/ + (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/ +}; + + +/* ---------------------------------------------- + * OrderedDict methods + */ + +/* fromkeys() */ + +/*[clinic input] +@classmethod +OrderedDict.fromkeys + + iterable as seq: object + value: object = None + +Create a new ordered dictionary with keys from iterable and values set to value. +[clinic start generated code]*/ + +static PyObject * +OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value) +/*[clinic end generated code: output=c10390d452d78d6d input=1a0476c229c597b3]*/ +{ + return _PyDict_FromKeys((PyObject *)type, seq, value); +} + +/* __sizeof__() */ + +/* OrderedDict.__sizeof__() does not have a docstring. */ +PyDoc_STRVAR(odict_sizeof__doc__, ""); + +static PyObject * +odict_sizeof(PyODictObject *od, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od); + res += sizeof(_ODictNode *) * od->od_fast_nodes_size; /* od_fast_nodes */ + if (!_odict_EMPTY(od)) { + res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */ + } + return PyLong_FromSsize_t(res); +} + +/* __reduce__() */ + +PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling"); + +static PyObject * +odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(__dict__); + _Py_IDENTIFIER(items); + PyObject *dict = NULL, *result = NULL; + PyObject *items_iter, *items, *args = NULL; + + /* capture any instance state */ + dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__); + if (dict == NULL) + goto Done; + else { + /* od.__dict__ isn't necessarily a dict... */ + Py_ssize_t dict_len = PyObject_Length(dict); + if (dict_len == -1) + goto Done; + if (!dict_len) { + /* nothing to pickle in od.__dict__ */ + Py_CLEAR(dict); + } + } + + /* build the result */ + args = PyTuple_New(0); + if (args == NULL) + goto Done; + + items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL); + if (items == NULL) + goto Done; + + items_iter = PyObject_GetIter(items); + Py_DECREF(items); + if (items_iter == NULL) + goto Done; + + result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter); + Py_DECREF(items_iter); + +Done: + Py_XDECREF(dict); + Py_XDECREF(args); + + return result; +} + +/* setdefault(): Skips __missing__() calls. */ + + +/*[clinic input] +OrderedDict.setdefault + + key: object + default: object = None + +Insert key with a value of default if key is not in the dictionary. + +Return the value for key if key is in the dictionary, else default. +[clinic start generated code]*/ + +static PyObject * +OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, + PyObject *default_value) +/*[clinic end generated code: output=97537cb7c28464b6 input=38e098381c1efbc6]*/ +{ + PyObject *result = NULL; + + if (PyODict_CheckExact(self)) { + result = PyODict_GetItemWithError(self, key); /* borrowed */ + if (result == NULL) { + if (PyErr_Occurred()) + return NULL; + assert(_odict_find_node(self, key) == NULL); + if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) { + result = default_value; + Py_INCREF(result); + } + } + else { + Py_INCREF(result); + } + } + else { + int exists = PySequence_Contains((PyObject *)self, key); + if (exists < 0) { + return NULL; + } + else if (exists) { + result = PyObject_GetItem((PyObject *)self, key); + } + else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) { + result = default_value; + Py_INCREF(result); + } + } + + return result; +} + +/* pop() */ + +PyDoc_STRVAR(odict_pop__doc__, +"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\ + value. If key is not found, d is returned if given, otherwise KeyError\n\ + is raised.\n\ +\n\ + "); + +/* forward */ +static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *); + +/* Skips __missing__() calls. */ +static PyObject * +odict_pop(PyObject *od, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"key", "default", 0}; + PyObject *key, *failobj = NULL; + + /* borrowed */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist, + &key, &failobj)) { + return NULL; + } + + return _odict_popkey(od, key, failobj); +} + +static PyObject * +_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj, + Py_hash_t hash) +{ + _ODictNode *node; + PyObject *value = NULL; + + /* Pop the node first to avoid a possible dict resize (due to + eval loop reentrancy) and complications due to hash collision + resolution. */ + node = _odict_find_node_hash((PyODictObject *)od, key, hash); + if (node == NULL) { + if (PyErr_Occurred()) + return NULL; + } + else { + int res = _odict_clear_node((PyODictObject *)od, node, key, hash); + if (res < 0) { + return NULL; + } + } + + /* Now delete the value from the dict. */ + if (PyODict_CheckExact(od)) { + if (node != NULL) { + value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */ + if (value != NULL) { + Py_INCREF(value); + if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) { + Py_DECREF(value); + return NULL; + } + } + } + } + else { + int exists = PySequence_Contains(od, key); + if (exists < 0) + return NULL; + if (exists) { + value = PyObject_GetItem(od, key); + if (value != NULL) { + if (PyObject_DelItem(od, key) == -1) { + Py_CLEAR(value); + } + } + } + } + + /* Apply the fallback value, if necessary. */ + if (value == NULL && !PyErr_Occurred()) { + if (failobj) { + value = failobj; + Py_INCREF(failobj); + } + else { + PyErr_SetObject(PyExc_KeyError, key); + } + } + + return value; +} + +static PyObject * +_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj) +{ + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + + return _odict_popkey_hash(od, key, failobj, hash); +} + + +/* popitem() */ + +/*[clinic input] +OrderedDict.popitem + + last: bool = True + +Remove and return a (key, value) pair from the dictionary. + +Pairs are returned in LIFO order if last is true or FIFO order if false. +[clinic start generated code]*/ + +static PyObject * +OrderedDict_popitem_impl(PyODictObject *self, int last) +/*[clinic end generated code: output=98e7d986690d49eb input=d992ac5ee8305e1a]*/ +{ + PyObject *key, *value, *item = NULL; + _ODictNode *node; + + /* pull the item */ + + if (_odict_EMPTY(self)) { + PyErr_SetString(PyExc_KeyError, "dictionary is empty"); + return NULL; + } + + node = last ? _odict_LAST(self) : _odict_FIRST(self); + key = _odictnode_KEY(node); + Py_INCREF(key); + value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node)); + if (value == NULL) + return NULL; + item = PyTuple_Pack(2, key, value); + Py_DECREF(key); + Py_DECREF(value); + return item; +} + +/* keys() */ + +/* MutableMapping.keys() does not have a docstring. */ +PyDoc_STRVAR(odict_keys__doc__, ""); + +static PyObject * odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */ + +/* values() */ + +/* MutableMapping.values() does not have a docstring. */ +PyDoc_STRVAR(odict_values__doc__, ""); + +static PyObject * odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */ + +/* items() */ + +/* MutableMapping.items() does not have a docstring. */ +PyDoc_STRVAR(odict_items__doc__, ""); + +static PyObject * odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */ + +/* update() */ + +/* MutableMapping.update() does not have a docstring. */ +PyDoc_STRVAR(odict_update__doc__, ""); + +/* forward */ +static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *); + +#define odict_update mutablemapping_update + +/* clear() */ + +PyDoc_STRVAR(odict_clear__doc__, + "od.clear() -> None. Remove all items from od."); + +static PyObject * +odict_clear(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) +{ + PyDict_Clear((PyObject *)od); + _odict_clear_nodes(od); + Py_RETURN_NONE; +} + +/* copy() */ + +/* forward */ +static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *, + Py_hash_t); + +PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od"); + +static PyObject * +odict_copy(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) +{ + _ODictNode *node; + PyObject *od_copy; + + if (PyODict_CheckExact(od)) + od_copy = PyODict_New(); + else + od_copy = _PyObject_CallNoArg((PyObject *)Py_TYPE(od)); + if (od_copy == NULL) + return NULL; + + if (PyODict_CheckExact(od)) { + _odict_FOREACH(od, node) { + PyObject *key = _odictnode_KEY(node); + PyObject *value = _odictnode_VALUE(node, od); + if (value == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + goto fail; + } + if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value, + _odictnode_HASH(node)) != 0) + goto fail; + } + } + else { + _odict_FOREACH(od, node) { + int res; + PyObject *value = PyObject_GetItem((PyObject *)od, + _odictnode_KEY(node)); + if (value == NULL) + goto fail; + res = PyObject_SetItem((PyObject *)od_copy, + _odictnode_KEY(node), value); + Py_DECREF(value); + if (res != 0) + goto fail; + } + } + return od_copy; + +fail: + Py_DECREF(od_copy); + return NULL; +} + +/* __reversed__() */ + +PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)"); + +#define _odict_ITER_REVERSED 1 +#define _odict_ITER_KEYS 2 +#define _odict_ITER_VALUES 4 + +/* forward */ +static PyObject * odictiter_new(PyODictObject *, int); + +static PyObject * +odict_reversed(PyODictObject *od, PyObject *Py_UNUSED(ignored)) +{ + return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED); +} + + +/* move_to_end() */ + +/*[clinic input] +OrderedDict.move_to_end + + key: object + last: bool = True + +Move an existing element to the end (or beginning if last is false). + +Raise KeyError if the element does not exist. +[clinic start generated code]*/ + +static PyObject * +OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last) +/*[clinic end generated code: output=fafa4c5cc9b92f20 input=d6ceff7132a2fcd7]*/ +{ + _ODictNode *node; + + if (_odict_EMPTY(self)) { + PyErr_SetObject(PyExc_KeyError, key); + return NULL; + } + node = last ? _odict_LAST(self) : _odict_FIRST(self); + if (key != _odictnode_KEY(node)) { + node = _odict_find_node(self, key); + if (node == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + return NULL; + } + if (last) { + /* Only move if not already the last one. */ + if (node != _odict_LAST(self)) { + _odict_remove_node(self, node); + _odict_add_tail(self, node); + } + } + else { + /* Only move if not already the first one. */ + if (node != _odict_FIRST(self)) { + _odict_remove_node(self, node); + _odict_add_head(self, node); + } + } + } + Py_RETURN_NONE; +} + + +/* tp_methods */ + +static PyMethodDef odict_methods[] = { + + /* overridden dict methods */ + ORDEREDDICT_FROMKEYS_METHODDEF + {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS, + odict_sizeof__doc__}, + {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS, + odict_reduce__doc__}, + ORDEREDDICT_SETDEFAULT_METHODDEF + {"pop", (PyCFunction)(void(*)(void))odict_pop, + METH_VARARGS | METH_KEYWORDS, odict_pop__doc__}, + ORDEREDDICT_POPITEM_METHODDEF + {"keys", odictkeys_new, METH_NOARGS, + odict_keys__doc__}, + {"values", odictvalues_new, METH_NOARGS, + odict_values__doc__}, + {"items", odictitems_new, METH_NOARGS, + odict_items__doc__}, + {"update", (PyCFunction)(void(*)(void))odict_update, METH_VARARGS | METH_KEYWORDS, + odict_update__doc__}, + {"clear", (PyCFunction)odict_clear, METH_NOARGS, + odict_clear__doc__}, + {"copy", (PyCFunction)odict_copy, METH_NOARGS, + odict_copy__doc__}, + + /* new methods */ + {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS, + odict_reversed__doc__}, + ORDEREDDICT_MOVE_TO_END_METHODDEF + + {NULL, NULL} /* sentinel */ +}; + + +/* ---------------------------------------------- + * OrderedDict members + */ + +/* tp_getset */ + +static PyGetSetDef odict_getset[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} +}; + +/* ---------------------------------------------- + * OrderedDict type slot methods + */ + +/* tp_dealloc */ + +static void +odict_dealloc(PyODictObject *self) +{ + PyObject_GC_UnTrack(self); + Py_TRASHCAN_BEGIN(self, odict_dealloc) + + Py_XDECREF(self->od_inst_dict); + if (self->od_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)self); + + _odict_clear_nodes(self); + PyDict_Type.tp_dealloc((PyObject *)self); + + Py_TRASHCAN_END +} + +/* tp_repr */ + +static PyObject * +odict_repr(PyODictObject *self) +{ + int i; + _Py_IDENTIFIER(items); + PyObject *pieces = NULL, *result = NULL; + + if (PyODict_SIZE(self) == 0) + return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self))); + + i = Py_ReprEnter((PyObject *)self); + if (i != 0) { + return i > 0 ? PyUnicode_FromString("...") : NULL; + } + + if (PyODict_CheckExact(self)) { + Py_ssize_t count = 0; + _ODictNode *node; + pieces = PyList_New(PyODict_SIZE(self)); + if (pieces == NULL) + goto Done; + + _odict_FOREACH(self, node) { + PyObject *pair; + PyObject *key = _odictnode_KEY(node); + PyObject *value = _odictnode_VALUE(node, self); + if (value == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + goto Done; + } + pair = PyTuple_Pack(2, key, value); + if (pair == NULL) + goto Done; + + if (count < PyList_GET_SIZE(pieces)) + PyList_SET_ITEM(pieces, count, pair); /* steals reference */ + else { + if (PyList_Append(pieces, pair) < 0) { + Py_DECREF(pair); + goto Done; + } + Py_DECREF(pair); + } + count++; + } + if (count < PyList_GET_SIZE(pieces)) + Py_SIZE(pieces) = count; + } + else { + PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self, + &PyId_items, NULL); + if (items == NULL) + goto Done; + pieces = PySequence_List(items); + Py_DECREF(items); + if (pieces == NULL) + goto Done; + } + + result = PyUnicode_FromFormat("%s(%R)", + _PyType_Name(Py_TYPE(self)), pieces); + +Done: + Py_XDECREF(pieces); + Py_ReprLeave((PyObject *)self); + return result; +} + +/* tp_doc */ + +PyDoc_STRVAR(odict_doc, + "Dictionary that remembers insertion order"); + +/* tp_traverse */ + +static int +odict_traverse(PyODictObject *od, visitproc visit, void *arg) +{ + _ODictNode *node; + + Py_VISIT(od->od_inst_dict); + _odict_FOREACH(od, node) { + Py_VISIT(_odictnode_KEY(node)); + } + return PyDict_Type.tp_traverse((PyObject *)od, visit, arg); +} + +/* tp_clear */ + +static int +odict_tp_clear(PyODictObject *od) +{ + Py_CLEAR(od->od_inst_dict); + PyDict_Clear((PyObject *)od); + _odict_clear_nodes(od); + return 0; +} + +/* tp_richcompare */ + +static PyObject * +odict_richcompare(PyObject *v, PyObject *w, int op) +{ + if (!PyODict_Check(v) || !PyDict_Check(w)) { + Py_RETURN_NOTIMPLEMENTED; + } + + if (op == Py_EQ || op == Py_NE) { + PyObject *res, *cmp; + int eq; + + cmp = PyDict_Type.tp_richcompare(v, w, op); + if (cmp == NULL) + return NULL; + if (!PyODict_Check(w)) + return cmp; + if (op == Py_EQ && cmp == Py_False) + return cmp; + if (op == Py_NE && cmp == Py_True) + return cmp; + Py_DECREF(cmp); + + /* Try comparing odict keys. */ + eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w); + if (eq < 0) + return NULL; + + res = (eq == (op == Py_EQ)) ? Py_True : Py_False; + Py_INCREF(res); + return res; + } else { + Py_RETURN_NOTIMPLEMENTED; + } +} + +/* tp_iter */ + +static PyObject * +odict_iter(PyODictObject *od) +{ + return odictiter_new(od, _odict_ITER_KEYS); +} + +/* tp_init */ + +static int +odict_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *res; + Py_ssize_t len = PyObject_Length(args); + + if (len == -1) + return -1; + if (len > 1) { + const char *msg = "expected at most 1 arguments, got %zd"; + PyErr_Format(PyExc_TypeError, msg, len); + return -1; + } + + /* __init__() triggering update() is just the way things are! */ + res = odict_update(self, args, kwds); + if (res == NULL) { + return -1; + } else { + Py_DECREF(res); + return 0; + } +} + +/* PyODict_Type */ + +PyTypeObject PyODict_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "collections.OrderedDict", /* tp_name */ + sizeof(PyODictObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)odict_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)odict_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + &odict_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 | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + odict_doc, /* tp_doc */ + (traverseproc)odict_traverse, /* tp_traverse */ + (inquiry)odict_tp_clear, /* tp_clear */ + (richcmpfunc)odict_richcompare, /* tp_richcompare */ + offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */ + (getiterfunc)odict_iter, /* tp_iter */ + 0, /* tp_iternext */ + odict_methods, /* tp_methods */ + 0, /* tp_members */ + odict_getset, /* tp_getset */ + &PyDict_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */ + (initproc)odict_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ +}; + + +/* ---------------------------------------------- + * the public OrderedDict API + */ + +PyObject * +PyODict_New(void) +{ + return PyDict_Type.tp_new(&PyODict_Type, NULL, NULL); +} + +static int +_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value, + Py_hash_t hash) +{ + int res = _PyDict_SetItem_KnownHash(od, key, value, hash); + if (res == 0) { + res = _odict_add_new_node((PyODictObject *)od, key, hash); + if (res < 0) { + /* Revert setting the value on the dict */ + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + (void) _PyDict_DelItem_KnownHash(od, key, hash); + _PyErr_ChainExceptions(exc, val, tb); + } + } + return res; +} + +int +PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value) +{ + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return -1; + return _PyODict_SetItem_KnownHash(od, key, value, hash); +} + +int +PyODict_DelItem(PyObject *od, PyObject *key) +{ + int res; + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return -1; + res = _odict_clear_node((PyODictObject *)od, NULL, key, hash); + if (res < 0) + return -1; + return _PyDict_DelItem_KnownHash(od, key, hash); +} + + +/* ------------------------------------------- + * The OrderedDict views (keys/values/items) + */ + +typedef struct { + PyObject_HEAD + int kind; + PyODictObject *di_odict; + Py_ssize_t di_size; + size_t di_state; + PyObject *di_current; + PyObject *di_result; /* reusable result tuple for iteritems */ +} odictiterobject; + +static void +odictiter_dealloc(odictiterobject *di) +{ + _PyObject_GC_UNTRACK(di); + Py_XDECREF(di->di_odict); + Py_XDECREF(di->di_current); + if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) { + Py_DECREF(di->di_result); + } + PyObject_GC_Del(di); +} + +static int +odictiter_traverse(odictiterobject *di, visitproc visit, void *arg) +{ + Py_VISIT(di->di_odict); + Py_VISIT(di->di_current); /* A key could be any type, not just str. */ + Py_VISIT(di->di_result); + return 0; +} + +/* In order to protect against modifications during iteration, we track + * the current key instead of the current node. */ +static PyObject * +odictiter_nextkey(odictiterobject *di) +{ + PyObject *key = NULL; + _ODictNode *node; + int reversed = di->kind & _odict_ITER_REVERSED; + + if (di->di_odict == NULL) + return NULL; + if (di->di_current == NULL) + goto done; /* We're already done. */ + + /* Check for unsupported changes. */ + if (di->di_odict->od_state != di->di_state) { + PyErr_SetString(PyExc_RuntimeError, + "OrderedDict mutated during iteration"); + goto done; + } + if (di->di_size != PyODict_SIZE(di->di_odict)) { + PyErr_SetString(PyExc_RuntimeError, + "OrderedDict changed size during iteration"); + di->di_size = -1; /* Make this state sticky */ + return NULL; + } + + /* Get the key. */ + node = _odict_find_node(di->di_odict, di->di_current); + if (node == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, di->di_current); + /* Must have been deleted. */ + Py_CLEAR(di->di_current); + return NULL; + } + key = di->di_current; + + /* Advance to the next key. */ + node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node); + if (node == NULL) { + /* Reached the end. */ + di->di_current = NULL; + } + else { + di->di_current = _odictnode_KEY(node); + Py_INCREF(di->di_current); + } + + return key; + +done: + Py_CLEAR(di->di_odict); + return key; +} + +static PyObject * +odictiter_iternext(odictiterobject *di) +{ + PyObject *result, *value; + PyObject *key = odictiter_nextkey(di); /* new reference */ + + if (key == NULL) + return NULL; + + /* Handle the keys case. */ + if (! (di->kind & _odict_ITER_VALUES)) { + return key; + } + + value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */ + if (value == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + Py_DECREF(key); + goto done; + } + Py_INCREF(value); + + /* Handle the values case. */ + if (!(di->kind & _odict_ITER_KEYS)) { + Py_DECREF(key); + return value; + } + + /* Handle the items case. */ + result = di->di_result; + + if (Py_REFCNT(result) == 1) { + /* not in use so we can reuse it + * (the common case during iteration) */ + Py_INCREF(result); + Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */ + Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */ + // 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(2); + if (result == NULL) { + Py_DECREF(key); + Py_DECREF(value); + goto done; + } + } + + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + return result; + +done: + Py_CLEAR(di->di_current); + Py_CLEAR(di->di_odict); + return NULL; +} + +/* No need for tp_clear because odictiterobject is not mutable. */ + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling"); + +static PyObject * +odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + /* copy the iterator state */ + odictiterobject tmp = *di; + Py_XINCREF(tmp.di_odict); + Py_XINCREF(tmp.di_current); + + /* iterate the temporary into a list */ + PyObject *list = PySequence_List((PyObject*)&tmp); + Py_XDECREF(tmp.di_odict); + Py_XDECREF(tmp.di_current); + if (list == NULL) { + return NULL; + } + return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); +} + +static PyMethodDef odictiter_methods[] = { + {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyODictIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "odict_iterator", /* tp_name */ + sizeof(odictiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)odictiter_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, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)odictiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)odictiter_iternext, /* tp_iternext */ + odictiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +odictiter_new(PyODictObject *od, int kind) +{ + odictiterobject *di; + _ODictNode *node; + int reversed = kind & _odict_ITER_REVERSED; + + di = PyObject_GC_New(odictiterobject, &PyODictIter_Type); + if (di == NULL) + return NULL; + + if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){ + di->di_result = PyTuple_Pack(2, Py_None, Py_None); + if (di->di_result == NULL) { + Py_DECREF(di); + return NULL; + } + } + else + di->di_result = NULL; + + di->kind = kind; + node = reversed ? _odict_LAST(od) : _odict_FIRST(od); + di->di_current = node ? _odictnode_KEY(node) : NULL; + Py_XINCREF(di->di_current); + di->di_size = PyODict_SIZE(od); + di->di_state = od->od_state; + di->di_odict = od; + Py_INCREF(od); + + _PyObject_GC_TRACK(di); + return (PyObject *)di; +} + +/* keys() */ + +static PyObject * +odictkeys_iter(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return odictiter_new((PyODictObject *)dv->dv_dict, + _odict_ITER_KEYS); +} + +static PyObject * +odictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return odictiter_new((PyODictObject *)dv->dv_dict, + _odict_ITER_KEYS|_odict_ITER_REVERSED); +} + +static PyMethodDef odictkeys_methods[] = { + {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyODictKeys_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "odict_keys", /* 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 */ + 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 */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)odictkeys_iter, /* tp_iter */ + 0, /* tp_iternext */ + odictkeys_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyDictKeys_Type, /* tp_base */ +}; + +static PyObject * +odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored)) +{ + return _PyDictView_New(od, &PyODictKeys_Type); +} + +/* items() */ + +static PyObject * +odictitems_iter(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return odictiter_new((PyODictObject *)dv->dv_dict, + _odict_ITER_KEYS|_odict_ITER_VALUES); +} + +static PyObject * +odictitems_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return odictiter_new((PyODictObject *)dv->dv_dict, + _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED); +} + +static PyMethodDef odictitems_methods[] = { + {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyODictItems_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "odict_items", /* 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 */ + 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 */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)odictitems_iter, /* tp_iter */ + 0, /* tp_iternext */ + odictitems_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyDictItems_Type, /* tp_base */ +}; + +static PyObject * +odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored)) +{ + return _PyDictView_New(od, &PyODictItems_Type); +} + +/* values() */ + +static PyObject * +odictvalues_iter(_PyDictViewObject *dv) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return odictiter_new((PyODictObject *)dv->dv_dict, + _odict_ITER_VALUES); +} + +static PyObject * +odictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) +{ + if (dv->dv_dict == NULL) { + Py_RETURN_NONE; + } + return odictiter_new((PyODictObject *)dv->dv_dict, + _odict_ITER_VALUES|_odict_ITER_REVERSED); +} + +static PyMethodDef odictvalues_methods[] = { + {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyODictValues_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "odict_values", /* 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 */ + 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 */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)odictvalues_iter, /* tp_iter */ + 0, /* tp_iternext */ + odictvalues_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyDictValues_Type, /* tp_base */ +}; + +static PyObject * +odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored)) +{ + return _PyDictView_New(od, &PyODictValues_Type); +} + + +/* ---------------------------------------------- + MutableMapping implementations + +Mapping: + +============ =========== +method uses +============ =========== +__contains__ __getitem__ +__eq__ items +__getitem__ + +__iter__ + +__len__ + +__ne__ __eq__ +get __getitem__ +items ItemsView +keys KeysView +values ValuesView +============ =========== + +ItemsView uses __len__, __iter__, and __getitem__. +KeysView uses __len__, __iter__, and __contains__. +ValuesView uses __len__, __iter__, and __getitem__. + +MutableMapping: + +============ =========== +method uses +============ =========== +__delitem__ + +__setitem__ + +clear popitem +pop __getitem__ + __delitem__ +popitem __iter__ + _getitem__ + __delitem__ +setdefault __getitem__ + __setitem__ +update __setitem__ +============ =========== +*/ + +static int +mutablemapping_add_pairs(PyObject *self, PyObject *pairs) +{ + PyObject *pair, *iterator, *unexpected; + int res = 0; + + iterator = PyObject_GetIter(pairs); + if (iterator == NULL) + return -1; + PyErr_Clear(); + + while ((pair = PyIter_Next(iterator)) != NULL) { + /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */ + PyObject *key = NULL, *value = NULL; + PyObject *pair_iterator = PyObject_GetIter(pair); + if (pair_iterator == NULL) + goto Done; + + key = PyIter_Next(pair_iterator); + if (key == NULL) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_ValueError, + "need more than 0 values to unpack"); + goto Done; + } + + value = PyIter_Next(pair_iterator); + if (value == NULL) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_ValueError, + "need more than 1 value to unpack"); + goto Done; + } + + unexpected = PyIter_Next(pair_iterator); + if (unexpected != NULL) { + Py_DECREF(unexpected); + PyErr_SetString(PyExc_ValueError, + "too many values to unpack (expected 2)"); + goto Done; + } + else if (PyErr_Occurred()) + goto Done; + + res = PyObject_SetItem(self, key, value); + +Done: + Py_DECREF(pair); + Py_XDECREF(pair_iterator); + Py_XDECREF(key); + Py_XDECREF(value); + if (PyErr_Occurred()) + break; + } + Py_DECREF(iterator); + + if (res < 0 || PyErr_Occurred() != NULL) + return -1; + else + return 0; +} + +static PyObject * +mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int res = 0; + Py_ssize_t len; + _Py_IDENTIFIER(items); + _Py_IDENTIFIER(keys); + + /* first handle args, if any */ + assert(args == NULL || PyTuple_Check(args)); + len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0; + if (len > 1) { + const char *msg = "update() takes at most 1 positional argument (%zd given)"; + PyErr_Format(PyExc_TypeError, msg, len); + return NULL; + } + + if (len) { + PyObject *func; + PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */ + assert(other != NULL); + Py_INCREF(other); + if (PyDict_CheckExact(other)) { + PyObject *items = PyDict_Items(other); + Py_DECREF(other); + if (items == NULL) + return NULL; + res = mutablemapping_add_pairs(self, items); + Py_DECREF(items); + if (res == -1) + return NULL; + goto handle_kwargs; + } + + if (_PyObject_LookupAttrId(other, &PyId_keys, &func) < 0) { + Py_DECREF(other); + return NULL; + } + if (func != NULL) { + PyObject *keys, *iterator, *key; + keys = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (keys == NULL) { + Py_DECREF(other); + return NULL; + } + iterator = PyObject_GetIter(keys); + Py_DECREF(keys); + if (iterator == NULL) { + Py_DECREF(other); + return NULL; + } + while (res == 0 && (key = PyIter_Next(iterator))) { + PyObject *value = PyObject_GetItem(other, key); + if (value != NULL) { + res = PyObject_SetItem(self, key, value); + Py_DECREF(value); + } + else { + res = -1; + } + Py_DECREF(key); + } + Py_DECREF(other); + Py_DECREF(iterator); + if (res != 0 || PyErr_Occurred()) + return NULL; + goto handle_kwargs; + } + + if (_PyObject_LookupAttrId(other, &PyId_items, &func) < 0) { + Py_DECREF(other); + return NULL; + } + if (func != NULL) { + PyObject *items; + Py_DECREF(other); + items = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (items == NULL) + return NULL; + res = mutablemapping_add_pairs(self, items); + Py_DECREF(items); + if (res == -1) + return NULL; + goto handle_kwargs; + } + + res = mutablemapping_add_pairs(self, other); + Py_DECREF(other); + if (res != 0) + return NULL; + } + + handle_kwargs: + /* now handle kwargs */ + assert(kwargs == NULL || PyDict_Check(kwargs)); + if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) { + PyObject *items = PyDict_Items(kwargs); + if (items == NULL) + return NULL; + res = mutablemapping_add_pairs(self, items); + Py_DECREF(items); + if (res == -1) + return NULL; + } + + Py_RETURN_NONE; +} diff --git a/python/Objects/picklebufobject.c b/python/Objects/picklebufobject.c new file mode 100755 index 0000000..a135e55 --- /dev/null +++ b/python/Objects/picklebufobject.c @@ -0,0 +1,219 @@ +/* PickleBuffer object implementation */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include + +typedef struct { + PyObject_HEAD + /* The view exported by the original object */ + Py_buffer view; + PyObject *weakreflist; +} PyPickleBufferObject; + +/* C API */ + +PyObject * +PyPickleBuffer_FromObject(PyObject *base) +{ + PyTypeObject *type = &PyPickleBuffer_Type; + PyPickleBufferObject *self; + + self = (PyPickleBufferObject *) type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + self->view.obj = NULL; + self->weakreflist = NULL; + if (PyObject_GetBuffer(base, &self->view, PyBUF_FULL_RO) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *) self; +} + +const Py_buffer * +PyPickleBuffer_GetBuffer(PyObject *obj) +{ + PyPickleBufferObject *self = (PyPickleBufferObject *) obj; + + if (!PyPickleBuffer_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "expected PickleBuffer, %.200s found", + Py_TYPE(obj)->tp_name); + return NULL; + } + if (self->view.obj == NULL) { + PyErr_SetString(PyExc_ValueError, + "operation forbidden on released PickleBuffer object"); + return NULL; + } + return &self->view; +} + +int +PyPickleBuffer_Release(PyObject *obj) +{ + PyPickleBufferObject *self = (PyPickleBufferObject *) obj; + + if (!PyPickleBuffer_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "expected PickleBuffer, %.200s found", + Py_TYPE(obj)->tp_name); + return -1; + } + PyBuffer_Release(&self->view); + return 0; +} + +static PyObject * +picklebuf_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyPickleBufferObject *self; + PyObject *base; + char *keywords[] = {"", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PickleBuffer", + keywords, &base)) { + return NULL; + } + + self = (PyPickleBufferObject *) type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + self->view.obj = NULL; + self->weakreflist = NULL; + if (PyObject_GetBuffer(base, &self->view, PyBUF_FULL_RO) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *) self; +} + +static int +picklebuf_traverse(PyPickleBufferObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->view.obj); + return 0; +} + +static int +picklebuf_clear(PyPickleBufferObject *self) +{ + PyBuffer_Release(&self->view); + return 0; +} + +static void +picklebuf_dealloc(PyPickleBufferObject *self) +{ + PyObject_GC_UnTrack(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + PyBuffer_Release(&self->view); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +/* Buffer API */ + +static int +picklebuf_getbuf(PyPickleBufferObject *self, Py_buffer *view, int flags) +{ + if (self->view.obj == NULL) { + PyErr_SetString(PyExc_ValueError, + "operation forbidden on released PickleBuffer object"); + return -1; + } + return PyObject_GetBuffer(self->view.obj, view, flags); +} + +static void +picklebuf_releasebuf(PyPickleBufferObject *self, Py_buffer *view) +{ + /* Since our bf_getbuffer redirects to the original object, this + * implementation is never called. It only exists to signal that + * buffers exported by PickleBuffer have non-trivial releasing + * behaviour (see check in Python/getargs.c). + */ +} + +static PyBufferProcs picklebuf_as_buffer = { + .bf_getbuffer = (getbufferproc) picklebuf_getbuf, + .bf_releasebuffer = (releasebufferproc) picklebuf_releasebuf, +}; + +/* Methods */ + +static PyObject * +picklebuf_raw(PyPickleBufferObject *self, PyObject *Py_UNUSED(ignored)) +{ + if (self->view.obj == NULL) { + PyErr_SetString(PyExc_ValueError, + "operation forbidden on released PickleBuffer object"); + return NULL; + } + if (self->view.suboffsets != NULL + || !PyBuffer_IsContiguous(&self->view, 'A')) { + PyErr_SetString(PyExc_BufferError, + "cannot extract raw buffer from non-contiguous buffer"); + return NULL; + } + PyObject *m = PyMemoryView_FromObject((PyObject *) self); + if (m == NULL) { + return NULL; + } + PyMemoryViewObject *mv = (PyMemoryViewObject *) m; + assert(mv->view.suboffsets == NULL); + /* Mutate memoryview instance to make it a "raw" memoryview */ + mv->view.format = "B"; + mv->view.ndim = 1; + mv->view.itemsize = 1; + /* shape = (length,) */ + mv->view.shape = &mv->view.len; + /* strides = (1,) */ + mv->view.strides = &mv->view.itemsize; + /* Fix memoryview state flags */ + /* XXX Expose memoryobject.c's init_flags() instead? */ + mv->flags = _Py_MEMORYVIEW_C | _Py_MEMORYVIEW_FORTRAN; + return m; +} + +PyDoc_STRVAR(picklebuf_raw_doc, +"raw($self, /)\n--\n\ +\n\ +Return a memoryview of the raw memory underlying this buffer.\n\ +Will raise BufferError is the buffer isn't contiguous."); + +static PyObject * +picklebuf_release(PyPickleBufferObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyBuffer_Release(&self->view); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(picklebuf_release_doc, +"release($self, /)\n--\n\ +\n\ +Release the underlying buffer exposed by the PickleBuffer object."); + +static PyMethodDef picklebuf_methods[] = { + {"raw", (PyCFunction) picklebuf_raw, METH_NOARGS, picklebuf_raw_doc}, + {"release", (PyCFunction) picklebuf_release, METH_NOARGS, picklebuf_release_doc}, + {NULL, NULL} +}; + +PyTypeObject PyPickleBuffer_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "pickle.PickleBuffer", + .tp_doc = "Wrapper for potentially out-of-band buffers", + .tp_basicsize = sizeof(PyPickleBufferObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_new = picklebuf_new, + .tp_dealloc = (destructor) picklebuf_dealloc, + .tp_traverse = (traverseproc) picklebuf_traverse, + .tp_clear = (inquiry) picklebuf_clear, + .tp_weaklistoffset = offsetof(PyPickleBufferObject, weakreflist), + .tp_as_buffer = &picklebuf_as_buffer, + .tp_methods = picklebuf_methods, +}; diff --git a/python/Objects/rangeobject.c b/python/Objects/rangeobject.c new file mode 100755 index 0000000..239ace6 --- /dev/null +++ b/python/Objects/rangeobject.c @@ -0,0 +1,1193 @@ +/* Range object implementation */ + +#include "Python.h" +#include "structmember.h" + +/* Support objects whose length is > PY_SSIZE_T_MAX. + + This could be sped up for small PyLongs if they fit in a Py_ssize_t. + This only matters on Win64. Though we could use long long which + would presumably help perf. +*/ + +typedef struct { + PyObject_HEAD + PyObject *start; + PyObject *stop; + PyObject *step; + PyObject *length; +} rangeobject; + +/* Helper function for validating step. Always returns a new reference or + NULL on error. +*/ +static PyObject * +validate_step(PyObject *step) +{ + /* No step specified, use a step of 1. */ + if (!step) + return PyLong_FromLong(1); + + step = PyNumber_Index(step); + if (step && _PyLong_Sign(step) == 0) { + PyErr_SetString(PyExc_ValueError, + "range() arg 3 must not be zero"); + Py_CLEAR(step); + } + + return step; +} + +static PyObject * +compute_range_length(PyObject *start, PyObject *stop, PyObject *step); + +static rangeobject * +make_range_object(PyTypeObject *type, PyObject *start, + PyObject *stop, PyObject *step) +{ + rangeobject *obj = NULL; + PyObject *length; + length = compute_range_length(start, stop, step); + if (length == NULL) { + return NULL; + } + obj = PyObject_New(rangeobject, type); + if (obj == NULL) { + Py_DECREF(length); + return NULL; + } + obj->start = start; + obj->stop = stop; + obj->step = step; + obj->length = length; + return obj; +} + +/* XXX(nnorwitz): should we error check if the user passes any empty ranges? + range(-10) + range(0, -5) + range(0, 5, -1) +*/ +static PyObject * +range_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + rangeobject *obj; + PyObject *start = NULL, *stop = NULL, *step = NULL; + + if (!_PyArg_NoKeywords("range", kw)) + return NULL; + + if (PyTuple_Size(args) <= 1) { + if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop)) + return NULL; + stop = PyNumber_Index(stop); + if (!stop) + return NULL; + Py_INCREF(_PyLong_Zero); + start = _PyLong_Zero; + Py_INCREF(_PyLong_One); + step = _PyLong_One; + } + else { + if (!PyArg_UnpackTuple(args, "range", 2, 3, + &start, &stop, &step)) + return NULL; + + /* Convert borrowed refs to owned refs */ + start = PyNumber_Index(start); + if (!start) + return NULL; + stop = PyNumber_Index(stop); + if (!stop) { + Py_DECREF(start); + return NULL; + } + step = validate_step(step); /* Caution, this can clear exceptions */ + if (!step) { + Py_DECREF(start); + Py_DECREF(stop); + return NULL; + } + } + + obj = make_range_object(type, start, stop, step); + if (obj != NULL) + return (PyObject *) obj; + + /* Failed to create object, release attributes */ + Py_DECREF(start); + Py_DECREF(stop); + Py_DECREF(step); + return NULL; +} + +PyDoc_STRVAR(range_doc, +"range(stop) -> range object\n\ +range(start, stop[, step]) -> range object\n\ +\n\ +Return an object that produces a sequence of integers from start (inclusive)\n\ +to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\ +start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\ +These are exactly the valid indices for a list of 4 elements.\n\ +When step is given, it specifies the increment (or decrement)."); + +static void +range_dealloc(rangeobject *r) +{ + Py_DECREF(r->start); + Py_DECREF(r->stop); + Py_DECREF(r->step); + Py_DECREF(r->length); + PyObject_Del(r); +} + +/* Return number of items in range (lo, hi, step) as a PyLong object, + * when arguments are PyLong objects. Arguments MUST return 1 with + * PyLong_Check(). Return NULL when there is an error. + */ +static PyObject* +compute_range_length(PyObject *start, PyObject *stop, PyObject *step) +{ + /* ------------------------------------------------------------- + Algorithm is equal to that of get_len_of_range(), but it operates + on PyObjects (which are assumed to be PyLong objects). + ---------------------------------------------------------------*/ + int cmp_result; + PyObject *lo, *hi; + PyObject *diff = NULL; + PyObject *tmp1 = NULL, *tmp2 = NULL, *result; + /* holds sub-expression evaluations */ + + cmp_result = PyObject_RichCompareBool(step, _PyLong_Zero, Py_GT); + if (cmp_result == -1) + return NULL; + + if (cmp_result == 1) { + lo = start; + hi = stop; + Py_INCREF(step); + } else { + lo = stop; + hi = start; + step = PyNumber_Negative(step); + if (!step) + return NULL; + } + + /* if (lo >= hi), return length of 0. */ + cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE); + if (cmp_result != 0) { + Py_DECREF(step); + if (cmp_result < 0) + return NULL; + return PyLong_FromLong(0); + } + + if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) + goto Fail; + + if ((diff = PyNumber_Subtract(tmp1, _PyLong_One)) == NULL) + goto Fail; + + if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL) + goto Fail; + + if ((result = PyNumber_Add(tmp2, _PyLong_One)) == NULL) + goto Fail; + + Py_DECREF(tmp2); + Py_DECREF(diff); + Py_DECREF(step); + Py_DECREF(tmp1); + return result; + + Fail: + Py_DECREF(step); + Py_XDECREF(tmp2); + Py_XDECREF(diff); + Py_XDECREF(tmp1); + return NULL; +} + +static Py_ssize_t +range_length(rangeobject *r) +{ + return PyLong_AsSsize_t(r->length); +} + +static PyObject * +compute_item(rangeobject *r, PyObject *i) +{ + PyObject *incr, *result; + /* PyLong equivalent to: + * return r->start + (i * r->step) + */ + incr = PyNumber_Multiply(i, r->step); + if (!incr) + return NULL; + result = PyNumber_Add(r->start, incr); + Py_DECREF(incr); + return result; +} + +static PyObject * +compute_range_item(rangeobject *r, PyObject *arg) +{ + int cmp_result; + PyObject *i, *result; + + /* PyLong equivalent to: + * if (arg < 0) { + * i = r->length + arg + * } else { + * i = arg + * } + */ + cmp_result = PyObject_RichCompareBool(arg, _PyLong_Zero, Py_LT); + if (cmp_result == -1) { + return NULL; + } + if (cmp_result == 1) { + i = PyNumber_Add(r->length, arg); + if (!i) { + return NULL; + } + } else { + i = arg; + Py_INCREF(i); + } + + /* PyLong equivalent to: + * if (i < 0 || i >= r->length) { + * + * } + */ + cmp_result = PyObject_RichCompareBool(i, _PyLong_Zero, Py_LT); + if (cmp_result == 0) { + cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE); + } + if (cmp_result == -1) { + Py_DECREF(i); + return NULL; + } + if (cmp_result == 1) { + Py_DECREF(i); + PyErr_SetString(PyExc_IndexError, + "range object index out of range"); + return NULL; + } + + result = compute_item(r, i); + Py_DECREF(i); + return result; +} + +static PyObject * +range_item(rangeobject *r, Py_ssize_t i) +{ + PyObject *res, *arg = PyLong_FromSsize_t(i); + if (!arg) { + return NULL; + } + res = compute_range_item(r, arg); + Py_DECREF(arg); + return res; +} + +static PyObject * +compute_slice(rangeobject *r, PyObject *_slice) +{ + PySliceObject *slice = (PySliceObject *) _slice; + rangeobject *result; + PyObject *start = NULL, *stop = NULL, *step = NULL; + PyObject *substart = NULL, *substop = NULL, *substep = NULL; + int error; + + error = _PySlice_GetLongIndices(slice, r->length, &start, &stop, &step); + if (error == -1) + return NULL; + + substep = PyNumber_Multiply(r->step, step); + if (substep == NULL) goto fail; + Py_CLEAR(step); + + substart = compute_item(r, start); + if (substart == NULL) goto fail; + Py_CLEAR(start); + + substop = compute_item(r, stop); + if (substop == NULL) goto fail; + Py_CLEAR(stop); + + result = make_range_object(Py_TYPE(r), substart, substop, substep); + if (result != NULL) { + return (PyObject *) result; + } +fail: + Py_XDECREF(start); + Py_XDECREF(stop); + Py_XDECREF(step); + Py_XDECREF(substart); + Py_XDECREF(substop); + Py_XDECREF(substep); + return NULL; +} + +/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */ +static int +range_contains_long(rangeobject *r, PyObject *ob) +{ + int cmp1, cmp2, cmp3; + PyObject *tmp1 = NULL; + PyObject *tmp2 = NULL; + int result = -1; + + /* Check if the value can possibly be in the range. */ + + cmp1 = PyObject_RichCompareBool(r->step, _PyLong_Zero, Py_GT); + if (cmp1 == -1) + goto end; + if (cmp1 == 1) { /* positive steps: start <= ob < stop */ + cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE); + cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT); + } + else { /* negative steps: stop < ob <= start */ + cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE); + cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT); + } + + if (cmp2 == -1 || cmp3 == -1) /* TypeError */ + goto end; + if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */ + result = 0; + goto end; + } + + /* Check that the stride does not invalidate ob's membership. */ + tmp1 = PyNumber_Subtract(ob, r->start); + if (tmp1 == NULL) + goto end; + tmp2 = PyNumber_Remainder(tmp1, r->step); + if (tmp2 == NULL) + goto end; + /* result = ((int(ob) - start) % step) == 0 */ + result = PyObject_RichCompareBool(tmp2, _PyLong_Zero, Py_EQ); + end: + Py_XDECREF(tmp1); + Py_XDECREF(tmp2); + return result; +} + +static int +range_contains(rangeobject *r, PyObject *ob) +{ + if (PyLong_CheckExact(ob) || PyBool_Check(ob)) + return range_contains_long(r, ob); + + return (int)_PySequence_IterSearch((PyObject*)r, ob, + PY_ITERSEARCH_CONTAINS); +} + +/* Compare two range objects. Return 1 for equal, 0 for not equal + and -1 on error. The algorithm is roughly the C equivalent of + + if r0 is r1: + return True + if len(r0) != len(r1): + return False + if not len(r0): + return True + if r0.start != r1.start: + return False + if len(r0) == 1: + return True + return r0.step == r1.step +*/ +static int +range_equals(rangeobject *r0, rangeobject *r1) +{ + int cmp_result; + + if (r0 == r1) + return 1; + cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ); + /* Return False or error to the caller. */ + if (cmp_result != 1) + return cmp_result; + cmp_result = PyObject_Not(r0->length); + /* Return True or error to the caller. */ + if (cmp_result != 0) + return cmp_result; + cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ); + /* Return False or error to the caller. */ + if (cmp_result != 1) + return cmp_result; + cmp_result = PyObject_RichCompareBool(r0->length, _PyLong_One, Py_EQ); + /* Return True or error to the caller. */ + if (cmp_result != 0) + return cmp_result; + return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ); +} + +static PyObject * +range_richcompare(PyObject *self, PyObject *other, int op) +{ + int result; + + if (!PyRange_Check(other)) + Py_RETURN_NOTIMPLEMENTED; + switch (op) { + case Py_NE: + case Py_EQ: + result = range_equals((rangeobject*)self, (rangeobject*)other); + if (result == -1) + return NULL; + if (op == Py_NE) + result = !result; + if (result) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + case Py_LE: + case Py_GE: + case Py_LT: + case Py_GT: + Py_RETURN_NOTIMPLEMENTED; + default: + PyErr_BadArgument(); + return NULL; + } +} + +/* Hash function for range objects. Rough C equivalent of + + if not len(r): + return hash((len(r), None, None)) + if len(r) == 1: + return hash((len(r), r.start, None)) + return hash((len(r), r.start, r.step)) +*/ +static Py_hash_t +range_hash(rangeobject *r) +{ + PyObject *t; + Py_hash_t result = -1; + int cmp_result; + + t = PyTuple_New(3); + if (!t) + return -1; + Py_INCREF(r->length); + PyTuple_SET_ITEM(t, 0, r->length); + cmp_result = PyObject_Not(r->length); + if (cmp_result == -1) + goto end; + if (cmp_result == 1) { + Py_INCREF(Py_None); + Py_INCREF(Py_None); + PyTuple_SET_ITEM(t, 1, Py_None); + PyTuple_SET_ITEM(t, 2, Py_None); + } + else { + Py_INCREF(r->start); + PyTuple_SET_ITEM(t, 1, r->start); + cmp_result = PyObject_RichCompareBool(r->length, _PyLong_One, Py_EQ); + if (cmp_result == -1) + goto end; + if (cmp_result == 1) { + Py_INCREF(Py_None); + PyTuple_SET_ITEM(t, 2, Py_None); + } + else { + Py_INCREF(r->step); + PyTuple_SET_ITEM(t, 2, r->step); + } + } + result = PyObject_Hash(t); + end: + Py_DECREF(t); + return result; +} + +static PyObject * +range_count(rangeobject *r, PyObject *ob) +{ + if (PyLong_CheckExact(ob) || PyBool_Check(ob)) { + int result = range_contains_long(r, ob); + if (result == -1) + return NULL; + return PyLong_FromLong(result); + } else { + Py_ssize_t count; + count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT); + if (count == -1) + return NULL; + return PyLong_FromSsize_t(count); + } +} + +static PyObject * +range_index(rangeobject *r, PyObject *ob) +{ + int contains; + + if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) { + Py_ssize_t index; + index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX); + if (index == -1) + return NULL; + return PyLong_FromSsize_t(index); + } + + contains = range_contains_long(r, ob); + if (contains == -1) + return NULL; + + if (contains) { + PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start); + if (tmp == NULL) + return NULL; + /* idx = (ob - r.start) // r.step */ + idx = PyNumber_FloorDivide(tmp, r->step); + Py_DECREF(tmp); + return idx; + } + + /* object is not in the range */ + PyErr_Format(PyExc_ValueError, "%R is not in range", ob); + return NULL; +} + +static PySequenceMethods range_as_sequence = { + (lenfunc)range_length, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)range_item, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)range_contains, /* sq_contains */ +}; + +static PyObject * +range_repr(rangeobject *r) +{ + Py_ssize_t istep; + + /* Check for special case values for printing. We don't always + need the step value. We don't care about overflow. */ + istep = PyNumber_AsSsize_t(r->step, NULL); + if (istep == -1 && PyErr_Occurred()) { + assert(!PyErr_ExceptionMatches(PyExc_OverflowError)); + return NULL; + } + + if (istep == 1) + return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop); + else + return PyUnicode_FromFormat("range(%R, %R, %R)", + r->start, r->stop, r->step); +} + +/* Pickling support */ +static PyObject * +range_reduce(rangeobject *r, PyObject *args) +{ + return Py_BuildValue("(O(OOO))", Py_TYPE(r), + r->start, r->stop, r->step); +} + +static PyObject * +range_subscript(rangeobject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + PyObject *i, *result; + i = PyNumber_Index(item); + if (!i) + return NULL; + result = compute_range_item(self, i); + Py_DECREF(i); + return result; + } + if (PySlice_Check(item)) { + return compute_slice(self, item); + } + PyErr_Format(PyExc_TypeError, + "range indices must be integers or slices, not %.200s", + item->ob_type->tp_name); + return NULL; +} + + +static PyMappingMethods range_as_mapping = { + (lenfunc)range_length, /* mp_length */ + (binaryfunc)range_subscript, /* mp_subscript */ + (objobjargproc)0, /* mp_ass_subscript */ +}; + +static int +range_bool(rangeobject* self) +{ + return PyObject_IsTrue(self->length); +} + +static PyNumberMethods range_as_number = { + .nb_bool = (inquiry)range_bool, +}; + +static PyObject * range_iter(PyObject *seq); +static PyObject * range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored)); + +PyDoc_STRVAR(reverse_doc, +"Return a reverse iterator."); + +PyDoc_STRVAR(count_doc, +"rangeobject.count(value) -> integer -- return number of occurrences of value"); + +PyDoc_STRVAR(index_doc, +"rangeobject.index(value) -> integer -- return index of value.\n" +"Raise ValueError if the value is not present."); + +static PyMethodDef range_methods[] = { + {"__reversed__", range_reverse, METH_NOARGS, reverse_doc}, + {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS}, + {"count", (PyCFunction)range_count, METH_O, count_doc}, + {"index", (PyCFunction)range_index, METH_O, index_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef range_members[] = { + {"start", T_OBJECT_EX, offsetof(rangeobject, start), READONLY}, + {"stop", T_OBJECT_EX, offsetof(rangeobject, stop), READONLY}, + {"step", T_OBJECT_EX, offsetof(rangeobject, step), READONLY}, + {0} +}; + +PyTypeObject PyRange_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "range", /* Name of this type */ + sizeof(rangeobject), /* Basic object size */ + 0, /* Item size for varobject */ + (destructor)range_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)range_repr, /* tp_repr */ + &range_as_number, /* tp_as_number */ + &range_as_sequence, /* tp_as_sequence */ + &range_as_mapping, /* tp_as_mapping */ + (hashfunc)range_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + range_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + range_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + range_iter, /* tp_iter */ + 0, /* tp_iternext */ + range_methods, /* tp_methods */ + range_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 */ + range_new, /* tp_new */ +}; + +/*********************** range Iterator **************************/ + +/* There are 2 types of iterators, one for C longs, the other for + Python ints (ie, PyObjects). This should make iteration fast + in the normal case, but possible for any numeric value. +*/ + +typedef struct { + PyObject_HEAD + long index; + long start; + long step; + long len; +} rangeiterobject; + +static PyObject * +rangeiter_next(rangeiterobject *r) +{ + if (r->index < r->len) + /* cast to unsigned to avoid possible signed overflow + in intermediate calculations. */ + return PyLong_FromLong((long)(r->start + + (unsigned long)(r->index++) * r->step)); + return NULL; +} + +static PyObject * +rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +{ + return PyLong_FromLong(r->len - r->index); +} + +PyDoc_STRVAR(length_hint_doc, + "Private method returning an estimate of len(list(it))."); + +static PyObject * +rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + PyObject *start=NULL, *stop=NULL, *step=NULL; + PyObject *range; + + /* create a range object for pickling */ + start = PyLong_FromLong(r->start); + if (start == NULL) + goto err; + stop = PyLong_FromLong(r->start + r->len * r->step); + if (stop == NULL) + goto err; + step = PyLong_FromLong(r->step); + if (step == NULL) + goto err; + range = (PyObject*)make_range_object(&PyRange_Type, + start, stop, step); + if (range == NULL) + goto err; + /* return the result */ + return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter), + range, r->index); +err: + Py_XDECREF(start); + Py_XDECREF(stop); + Py_XDECREF(step); + return NULL; +} + +static PyObject * +rangeiter_setstate(rangeiterobject *r, PyObject *state) +{ + long index = PyLong_AsLong(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + /* silently clip the index value */ + if (index < 0) + index = 0; + else if (index > r->len) + index = r->len; /* exhausted iterator */ + r->index = index; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef rangeiter_methods[] = { + {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, + length_hint_doc}, + {"__reduce__", (PyCFunction)rangeiter_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)rangeiter_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyRangeIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "range_iterator", /* tp_name */ + sizeof(rangeiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)PyObject_Del, /* tp_dealloc */ + 0, /* tp_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 */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)rangeiter_next, /* tp_iternext */ + rangeiter_methods, /* tp_methods */ + 0, /* tp_members */ +}; + +/* Return number of items in range (lo, hi, step). step != 0 + * required. The result always fits in an unsigned long. + */ +static unsigned long +get_len_of_range(long lo, long hi, long step) +{ + /* ------------------------------------------------------------- + If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty. + Else for step > 0, if n values are in the range, the last one is + lo + (n-1)*step, which must be <= hi-1. Rearranging, + n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives + the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so + the RHS is non-negative and so truncation is the same as the + floor. Letting M be the largest positive long, the worst case + for the RHS numerator is hi=M, lo=-M-1, and then + hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough + precision to compute the RHS exactly. The analysis for step < 0 + is similar. + ---------------------------------------------------------------*/ + assert(step != 0); + if (step > 0 && lo < hi) + return 1UL + (hi - 1UL - lo) / step; + else if (step < 0 && lo > hi) + return 1UL + (lo - 1UL - hi) / (0UL - step); + else + return 0UL; +} + +/* Initialize a rangeiter object. If the length of the rangeiter object + is not representable as a C long, OverflowError is raised. */ + +static PyObject * +fast_range_iter(long start, long stop, long step) +{ + rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); + unsigned long ulen; + if (it == NULL) + return NULL; + it->start = start; + it->step = step; + ulen = get_len_of_range(start, stop, step); + if (ulen > (unsigned long)LONG_MAX) { + Py_DECREF(it); + PyErr_SetString(PyExc_OverflowError, + "range too large to represent as a range_iterator"); + return NULL; + } + it->len = (long)ulen; + it->index = 0; + return (PyObject *)it; +} + +typedef struct { + PyObject_HEAD + PyObject *index; + PyObject *start; + PyObject *step; + PyObject *len; +} longrangeiterobject; + +static PyObject * +longrangeiter_len(longrangeiterobject *r, PyObject *no_args) +{ + return PyNumber_Subtract(r->len, r->index); +} + +static PyObject * +longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + PyObject *product, *stop=NULL; + PyObject *range; + + /* create a range object for pickling. Must calculate the "stop" value */ + product = PyNumber_Multiply(r->len, r->step); + if (product == NULL) + return NULL; + stop = PyNumber_Add(r->start, product); + Py_DECREF(product); + if (stop == NULL) + return NULL; + Py_INCREF(r->start); + Py_INCREF(r->step); + range = (PyObject*)make_range_object(&PyRange_Type, + r->start, stop, r->step); + if (range == NULL) { + Py_DECREF(r->start); + Py_DECREF(stop); + Py_DECREF(r->step); + return NULL; + } + + /* return the result */ + return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter), + range, r->index); +} + +static PyObject * +longrangeiter_setstate(longrangeiterobject *r, PyObject *state) +{ + int cmp; + + /* clip the value */ + cmp = PyObject_RichCompareBool(state, _PyLong_Zero, Py_LT); + if (cmp < 0) + return NULL; + if (cmp > 0) { + state = _PyLong_Zero; + } + else { + cmp = PyObject_RichCompareBool(r->len, state, Py_LT); + if (cmp < 0) + return NULL; + if (cmp > 0) + state = r->len; + } + Py_INCREF(state); + Py_XSETREF(r->index, state); + Py_RETURN_NONE; +} + +static PyMethodDef longrangeiter_methods[] = { + {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS, + length_hint_doc}, + {"__reduce__", (PyCFunction)longrangeiter_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)longrangeiter_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +static void +longrangeiter_dealloc(longrangeiterobject *r) +{ + Py_XDECREF(r->index); + Py_XDECREF(r->start); + Py_XDECREF(r->step); + Py_XDECREF(r->len); + PyObject_Del(r); +} + +static PyObject * +longrangeiter_next(longrangeiterobject *r) +{ + PyObject *product, *new_index, *result; + if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) + return NULL; + + new_index = PyNumber_Add(r->index, _PyLong_One); + if (!new_index) + return NULL; + + product = PyNumber_Multiply(r->index, r->step); + if (!product) { + Py_DECREF(new_index); + return NULL; + } + + result = PyNumber_Add(r->start, product); + Py_DECREF(product); + if (result) { + Py_SETREF(r->index, new_index); + } + else { + Py_DECREF(new_index); + } + + return result; +} + +PyTypeObject PyLongRangeIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "longrange_iterator", /* tp_name */ + sizeof(longrangeiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)longrangeiter_dealloc, /* tp_dealloc */ + 0, /* tp_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 */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)longrangeiter_next, /* tp_iternext */ + longrangeiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +range_iter(PyObject *seq) +{ + rangeobject *r = (rangeobject *)seq; + longrangeiterobject *it; + long lstart, lstop, lstep; + PyObject *int_it; + + assert(PyRange_Check(seq)); + + /* If all three fields and the length convert to long, use the int + * version */ + lstart = PyLong_AsLong(r->start); + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstop = PyLong_AsLong(r->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstep = PyLong_AsLong(r->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + int_it = fast_range_iter(lstart, lstop, lstep); + if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Clear(); + goto long_range; + } + return (PyObject *)int_it; + + long_range: + it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); + if (it == NULL) + return NULL; + + it->start = r->start; + it->step = r->step; + it->len = r->length; + it->index = _PyLong_Zero; + Py_INCREF(it->start); + Py_INCREF(it->step); + Py_INCREF(it->len); + Py_INCREF(it->index); + return (PyObject *)it; +} + +static PyObject * +range_reverse(PyObject *seq, PyObject *Py_UNUSED(ignored)) +{ + rangeobject *range = (rangeobject*) seq; + longrangeiterobject *it; + PyObject *sum, *diff, *product; + long lstart, lstop, lstep, new_start, new_stop; + unsigned long ulen; + + assert(PyRange_Check(seq)); + + /* reversed(range(start, stop, step)) can be expressed as + range(start+(n-1)*step, start-step, -step), where n is the number of + integers in the range. + + If each of start, stop, step, -step, start-step, and the length + of the iterator is representable as a C long, use the int + version. This excludes some cases where the reversed range is + representable as a range_iterator, but it's good enough for + common cases and it makes the checks simple. */ + + lstart = PyLong_AsLong(range->start); + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstop = PyLong_AsLong(range->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstep = PyLong_AsLong(range->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + /* check for possible overflow of -lstep */ + if (lstep == LONG_MIN) + goto long_range; + + /* check for overflow of lstart - lstep: + + for lstep > 0, need only check whether lstart - lstep < LONG_MIN. + for lstep < 0, need only check whether lstart - lstep > LONG_MAX + + Rearrange these inequalities as: + + lstart - LONG_MIN < lstep (lstep > 0) + LONG_MAX - lstart < -lstep (lstep < 0) + + and compute both sides as unsigned longs, to avoid the + possibility of undefined behaviour due to signed overflow. */ + + if (lstep > 0) { + if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep) + goto long_range; + } + else { + if (LONG_MAX - (unsigned long)lstart < 0UL - lstep) + goto long_range; + } + + ulen = get_len_of_range(lstart, lstop, lstep); + if (ulen > (unsigned long)LONG_MAX) + goto long_range; + + new_stop = lstart - lstep; + new_start = (long)(new_stop + ulen * lstep); + return fast_range_iter(new_start, new_stop, -lstep); + +long_range: + it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); + if (it == NULL) + return NULL; + it->index = it->start = it->step = NULL; + + /* start + (len - 1) * step */ + it->len = range->length; + Py_INCREF(it->len); + + diff = PyNumber_Subtract(it->len, _PyLong_One); + if (!diff) + goto create_failure; + + product = PyNumber_Multiply(diff, range->step); + Py_DECREF(diff); + if (!product) + goto create_failure; + + sum = PyNumber_Add(range->start, product); + Py_DECREF(product); + it->start = sum; + if (!it->start) + goto create_failure; + + it->step = PyNumber_Negative(range->step); + if (!it->step) + goto create_failure; + + it->index = _PyLong_Zero; + Py_INCREF(it->index); + return (PyObject *)it; + +create_failure: + Py_DECREF(it); + return NULL; +} diff --git a/python/Objects/setobject.c b/python/Objects/setobject.c new file mode 100755 index 0000000..f8ae0c0 --- /dev/null +++ b/python/Objects/setobject.c @@ -0,0 +1,2549 @@ + +/* set object implementation + + Written and maintained by Raymond D. Hettinger + Derived from Lib/sets.py and Objects/dictobject.c. + + The basic lookup function used by all operations. + This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4. + + The initial probe index is computed as hash mod the table size. + Subsequent probe indices are computed as explained in Objects/dictobject.c. + + To improve cache locality, each probe inspects a series of consecutive + nearby entries before moving on to probes elsewhere in memory. This leaves + us with a hybrid of linear probing and randomized probing. The linear probing + reduces the cost of hash collisions because consecutive memory accesses + tend to be much cheaper than scattered probes. After LINEAR_PROBES steps, + we then use more of the upper bits from the hash value and apply a simple + linear congruential random number genearator. This helps break-up long + chains of collisions. + + All arithmetic on hash should ignore overflow. + + Unlike the dictionary implementation, the lookkey function can return + NULL if the rich comparison returns an error. + + Use cases for sets differ considerably from dictionaries where looked-up + keys are more likely to be present. In contrast, sets are primarily + about membership testing where the presence of an element is not known in + advance. Accordingly, the set implementation needs to optimize for both + the found and not-found case. +*/ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "structmember.h" + +/* Object used as dummy key to fill deleted entries */ +static PyObject _dummy_struct; + +#define dummy (&_dummy_struct) + + +/* ======================================================================== */ +/* ======= Begin logic for probing the hash table ========================= */ + +/* Set this to zero to turn-off linear probing */ +#ifndef LINEAR_PROBES +#define LINEAR_PROBES 9 +#endif + +/* This must be >= 1 */ +#define PERTURB_SHIFT 5 + +static setentry * +set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) +{ + setentry *table; + setentry *entry; + size_t perturb; + size_t mask = so->mask; + size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */ + size_t j; + int cmp; + + entry = &so->table[i]; + if (entry->key == NULL) + return entry; + + perturb = hash; + + while (1) { + if (entry->hash == hash) { + PyObject *startkey = entry->key; + /* startkey cannot be a dummy because the dummy hash field is -1 */ + assert(startkey != dummy); + if (startkey == key) + return entry; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && _PyUnicode_EQ(startkey, key)) + return entry; + table = so->table; + Py_INCREF(startkey); + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) /* unlikely */ + return NULL; + if (table != so->table || entry->key != startkey) /* unlikely */ + return set_lookkey(so, key, hash); + if (cmp > 0) /* likely */ + return entry; + mask = so->mask; /* help avoid a register spill */ + } + + if (i + LINEAR_PROBES <= mask) { + for (j = 0 ; j < LINEAR_PROBES ; j++) { + entry++; + if (entry->hash == 0 && entry->key == NULL) + return entry; + if (entry->hash == hash) { + PyObject *startkey = entry->key; + assert(startkey != dummy); + if (startkey == key) + return entry; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && _PyUnicode_EQ(startkey, key)) + return entry; + table = so->table; + Py_INCREF(startkey); + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) + return NULL; + if (table != so->table || entry->key != startkey) + return set_lookkey(so, key, hash); + if (cmp > 0) + return entry; + mask = so->mask; + } + } + } + + perturb >>= PERTURB_SHIFT; + i = (i * 5 + 1 + perturb) & mask; + + entry = &so->table[i]; + if (entry->key == NULL) + return entry; + } +} + +static int set_table_resize(PySetObject *, Py_ssize_t); + +static int +set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) +{ + setentry *table; + setentry *freeslot; + setentry *entry; + size_t perturb; + size_t mask; + size_t i; /* Unsigned for defined overflow behavior */ + size_t j; + int cmp; + + /* Pre-increment is necessary to prevent arbitrary code in the rich + comparison from deallocating the key just before the insertion. */ + Py_INCREF(key); + + restart: + + mask = so->mask; + i = (size_t)hash & mask; + + entry = &so->table[i]; + if (entry->key == NULL) + goto found_unused; + + freeslot = NULL; + perturb = hash; + + while (1) { + if (entry->hash == hash) { + PyObject *startkey = entry->key; + /* startkey cannot be a dummy because the dummy hash field is -1 */ + assert(startkey != dummy); + if (startkey == key) + goto found_active; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && _PyUnicode_EQ(startkey, key)) + goto found_active; + table = so->table; + Py_INCREF(startkey); + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp > 0) /* likely */ + goto found_active; + if (cmp < 0) + goto comparison_error; + /* Continuing the search from the current entry only makes + sense if the table and entry are unchanged; otherwise, + we have to restart from the beginning */ + if (table != so->table || entry->key != startkey) + goto restart; + mask = so->mask; /* help avoid a register spill */ + } + else if (entry->hash == -1) + freeslot = entry; + + if (i + LINEAR_PROBES <= mask) { + for (j = 0 ; j < LINEAR_PROBES ; j++) { + entry++; + if (entry->hash == 0 && entry->key == NULL) + goto found_unused_or_dummy; + if (entry->hash == hash) { + PyObject *startkey = entry->key; + assert(startkey != dummy); + if (startkey == key) + goto found_active; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && _PyUnicode_EQ(startkey, key)) + goto found_active; + table = so->table; + Py_INCREF(startkey); + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp > 0) + goto found_active; + if (cmp < 0) + goto comparison_error; + if (table != so->table || entry->key != startkey) + goto restart; + mask = so->mask; + } + else if (entry->hash == -1) + freeslot = entry; + } + } + + perturb >>= PERTURB_SHIFT; + i = (i * 5 + 1 + perturb) & mask; + + entry = &so->table[i]; + if (entry->key == NULL) + goto found_unused_or_dummy; + } + + found_unused_or_dummy: + if (freeslot == NULL) + goto found_unused; + so->used++; + freeslot->key = key; + freeslot->hash = hash; + return 0; + + found_unused: + so->fill++; + so->used++; + entry->key = key; + entry->hash = hash; + if ((size_t)so->fill*5 < mask*3) + return 0; + return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4); + + found_active: + Py_DECREF(key); + return 0; + + comparison_error: + Py_DECREF(key); + return -1; +} + +/* +Internal routine used by set_table_resize() to insert an item which is +known to be absent from the set. This routine also assumes that +the set contains no deleted entries. Besides the performance benefit, +there is also safety benefit since using set_add_entry() risks making +a callback in the middle of a set_table_resize(), see issue 1456209. +The caller is responsible for updating the key's reference count and +the setobject's fill and used fields. +*/ +static void +set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash) +{ + setentry *entry; + size_t perturb = hash; + size_t i = (size_t)hash & mask; + size_t j; + + while (1) { + entry = &table[i]; + if (entry->key == NULL) + goto found_null; + if (i + LINEAR_PROBES <= mask) { + for (j = 0; j < LINEAR_PROBES; j++) { + entry++; + if (entry->key == NULL) + goto found_null; + } + } + perturb >>= PERTURB_SHIFT; + i = (i * 5 + 1 + perturb) & mask; + } + found_null: + entry->key = key; + entry->hash = hash; +} + +/* ======== End logic for probing the hash table ========================== */ +/* ======================================================================== */ + +/* +Restructure the table by allocating a new table and reinserting all +keys again. When entries have been deleted, the new table may +actually be smaller than the old one. +*/ +static int +set_table_resize(PySetObject *so, Py_ssize_t minused) +{ + setentry *oldtable, *newtable, *entry; + Py_ssize_t oldmask = so->mask; + size_t newmask; + int is_oldtable_malloced; + setentry small_copy[PySet_MINSIZE]; + + assert(minused >= 0); + + /* Find the smallest table size > minused. */ + /* XXX speed-up with intrinsics */ + size_t newsize = PySet_MINSIZE; + while (newsize <= (size_t)minused) { + newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1. + } + + /* Get space for a new table. */ + oldtable = so->table; + assert(oldtable != NULL); + is_oldtable_malloced = oldtable != so->smalltable; + + if (newsize == PySet_MINSIZE) { + /* A large table is shrinking, or we can't get any smaller. */ + newtable = so->smalltable; + if (newtable == oldtable) { + if (so->fill == so->used) { + /* No dummies, so no point doing anything. */ + return 0; + } + /* We're not going to resize it, but rebuild the + table anyway to purge old dummy entries. + Subtle: This is *necessary* if fill==size, + as set_lookkey needs at least one virgin slot to + terminate failing searches. If fill < size, it's + merely desirable, as dummies slow searches. */ + assert(so->fill > so->used); + memcpy(small_copy, oldtable, sizeof(small_copy)); + oldtable = small_copy; + } + } + else { + newtable = PyMem_NEW(setentry, newsize); + if (newtable == NULL) { + PyErr_NoMemory(); + return -1; + } + } + + /* Make the set empty, using the new table. */ + assert(newtable != oldtable); + memset(newtable, 0, sizeof(setentry) * newsize); + so->mask = newsize - 1; + so->table = newtable; + + /* Copy the data over; this is refcount-neutral for active entries; + dummy entries aren't copied over, of course */ + newmask = (size_t)so->mask; + if (so->fill == so->used) { + for (entry = oldtable; entry <= oldtable + oldmask; entry++) { + if (entry->key != NULL) { + set_insert_clean(newtable, newmask, entry->key, entry->hash); + } + } + } else { + so->fill = so->used; + for (entry = oldtable; entry <= oldtable + oldmask; entry++) { + if (entry->key != NULL && entry->key != dummy) { + set_insert_clean(newtable, newmask, entry->key, entry->hash); + } + } + } + + if (is_oldtable_malloced) + PyMem_DEL(oldtable); + return 0; +} + +static int +set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash) +{ + setentry *entry; + + entry = set_lookkey(so, key, hash); + if (entry != NULL) + return entry->key != NULL; + return -1; +} + +#define DISCARD_NOTFOUND 0 +#define DISCARD_FOUND 1 + +static int +set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash) +{ + setentry *entry; + PyObject *old_key; + + entry = set_lookkey(so, key, hash); + if (entry == NULL) + return -1; + if (entry->key == NULL) + return DISCARD_NOTFOUND; + old_key = entry->key; + entry->key = dummy; + entry->hash = -1; + so->used--; + Py_DECREF(old_key); + return DISCARD_FOUND; +} + +static int +set_add_key(PySetObject *so, PyObject *key) +{ + Py_hash_t hash; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + } + return set_add_entry(so, key, hash); +} + +static int +set_contains_key(PySetObject *so, PyObject *key) +{ + Py_hash_t hash; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + } + return set_contains_entry(so, key, hash); +} + +static int +set_discard_key(PySetObject *so, PyObject *key) +{ + Py_hash_t hash; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + } + return set_discard_entry(so, key, hash); +} + +static void +set_empty_to_minsize(PySetObject *so) +{ + memset(so->smalltable, 0, sizeof(so->smalltable)); + so->fill = 0; + so->used = 0; + so->mask = PySet_MINSIZE - 1; + so->table = so->smalltable; + so->hash = -1; +} + +static int +set_clear_internal(PySetObject *so) +{ + setentry *entry; + setentry *table = so->table; + Py_ssize_t fill = so->fill; + Py_ssize_t used = so->used; + int table_is_malloced = table != so->smalltable; + setentry small_copy[PySet_MINSIZE]; + + assert (PyAnySet_Check(so)); + assert(table != NULL); + + /* This is delicate. During the process of clearing the set, + * decrefs can cause the set to mutate. To avoid fatal confusion + * (voice of experience), we have to make the set empty before + * clearing the slots, and never refer to anything via so->ref while + * clearing. + */ + if (table_is_malloced) + set_empty_to_minsize(so); + + else if (fill > 0) { + /* It's a small table with something that needs to be cleared. + * Afraid the only safe way is to copy the set entries into + * another small table first. + */ + memcpy(small_copy, table, sizeof(small_copy)); + table = small_copy; + set_empty_to_minsize(so); + } + /* else it's a small table that's already empty */ + + /* Now we can finally clear things. If C had refcounts, we could + * assert that the refcount on table is 1 now, i.e. that this function + * has unique access to it, so decref side-effects can't alter it. + */ + for (entry = table; used > 0; entry++) { + if (entry->key && entry->key != dummy) { + used--; + Py_DECREF(entry->key); + } + } + + if (table_is_malloced) + PyMem_DEL(table); + return 0; +} + +/* + * Iterate over a set table. Use like so: + * + * Py_ssize_t pos; + * setentry *entry; + * pos = 0; # important! pos should not otherwise be changed by you + * while (set_next(yourset, &pos, &entry)) { + * Refer to borrowed reference in entry->key. + * } + * + * CAUTION: In general, it isn't safe to use set_next in a loop that + * mutates the table. + */ +static int +set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr) +{ + Py_ssize_t i; + Py_ssize_t mask; + setentry *entry; + + assert (PyAnySet_Check(so)); + i = *pos_ptr; + assert(i >= 0); + mask = so->mask; + entry = &so->table[i]; + while (i <= mask && (entry->key == NULL || entry->key == dummy)) { + i++; + entry++; + } + *pos_ptr = i+1; + if (i > mask) + return 0; + assert(entry != NULL); + *entry_ptr = entry; + return 1; +} + +static void +set_dealloc(PySetObject *so) +{ + setentry *entry; + Py_ssize_t used = so->used; + + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(so); + Py_TRASHCAN_BEGIN(so, set_dealloc) + if (so->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) so); + + for (entry = so->table; used > 0; entry++) { + if (entry->key && entry->key != dummy) { + used--; + Py_DECREF(entry->key); + } + } + if (so->table != so->smalltable) + PyMem_DEL(so->table); + Py_TYPE(so)->tp_free(so); + Py_TRASHCAN_END +} + +static PyObject * +set_repr(PySetObject *so) +{ + PyObject *result=NULL, *keys, *listrepr, *tmp; + int status = Py_ReprEnter((PyObject*)so); + + if (status != 0) { + if (status < 0) + return NULL; + return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name); + } + + /* shortcut for the empty set */ + if (!so->used) { + Py_ReprLeave((PyObject*)so); + return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name); + } + + keys = PySequence_List((PyObject *)so); + if (keys == NULL) + goto done; + + /* repr(keys)[1:-1] */ + listrepr = PyObject_Repr(keys); + Py_DECREF(keys); + if (listrepr == NULL) + goto done; + tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1); + Py_DECREF(listrepr); + if (tmp == NULL) + goto done; + listrepr = tmp; + + if (Py_TYPE(so) != &PySet_Type) + result = PyUnicode_FromFormat("%s({%U})", + Py_TYPE(so)->tp_name, + listrepr); + else + result = PyUnicode_FromFormat("{%U}", listrepr); + Py_DECREF(listrepr); +done: + Py_ReprLeave((PyObject*)so); + return result; +} + +static Py_ssize_t +set_len(PyObject *so) +{ + return ((PySetObject *)so)->used; +} + +static int +set_merge(PySetObject *so, PyObject *otherset) +{ + PySetObject *other; + PyObject *key; + Py_ssize_t i; + setentry *so_entry; + setentry *other_entry; + + assert (PyAnySet_Check(so)); + assert (PyAnySet_Check(otherset)); + + other = (PySetObject*)otherset; + if (other == so || other->used == 0) + /* a.update(a) or a.update(set()); nothing to do */ + return 0; + /* Do one big resize at the start, rather than + * incrementally resizing as we insert new keys. Expect + * that there will be no (or few) overlapping keys. + */ + if ((so->fill + other->used)*5 >= so->mask*3) { + if (set_table_resize(so, (so->used + other->used)*2) != 0) + return -1; + } + so_entry = so->table; + other_entry = other->table; + + /* If our table is empty, and both tables have the same size, and + there are no dummies to eliminate, then just copy the pointers. */ + if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) { + for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) { + key = other_entry->key; + if (key != NULL) { + assert(so_entry->key == NULL); + Py_INCREF(key); + so_entry->key = key; + so_entry->hash = other_entry->hash; + } + } + so->fill = other->fill; + so->used = other->used; + return 0; + } + + /* If our table is empty, we can use set_insert_clean() */ + if (so->fill == 0) { + setentry *newtable = so->table; + size_t newmask = (size_t)so->mask; + so->fill = other->used; + so->used = other->used; + for (i = other->mask + 1; i > 0 ; i--, other_entry++) { + key = other_entry->key; + if (key != NULL && key != dummy) { + Py_INCREF(key); + set_insert_clean(newtable, newmask, key, other_entry->hash); + } + } + return 0; + } + + /* We can't assure there are no duplicates, so do normal insertions */ + for (i = 0; i <= other->mask; i++) { + other_entry = &other->table[i]; + key = other_entry->key; + if (key != NULL && key != dummy) { + if (set_add_entry(so, key, other_entry->hash)) + return -1; + } + } + return 0; +} + +static PyObject * +set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored)) +{ + /* Make sure the search finger is in bounds */ + setentry *entry = so->table + (so->finger & so->mask); + setentry *limit = so->table + so->mask; + PyObject *key; + + if (so->used == 0) { + PyErr_SetString(PyExc_KeyError, "pop from an empty set"); + return NULL; + } + while (entry->key == NULL || entry->key==dummy) { + entry++; + if (entry > limit) + entry = so->table; + } + key = entry->key; + entry->key = dummy; + entry->hash = -1; + so->used--; + so->finger = entry - so->table + 1; /* next place to start */ + return key; +} + +PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\ +Raises KeyError if the set is empty."); + +static int +set_traverse(PySetObject *so, visitproc visit, void *arg) +{ + Py_ssize_t pos = 0; + setentry *entry; + + while (set_next(so, &pos, &entry)) + Py_VISIT(entry->key); + return 0; +} + +/* Work to increase the bit dispersion for closely spaced hash values. + This is important because some use cases have many combinations of a + small number of elements with nearby hashes so that many distinct + combinations collapse to only a handful of distinct hash values. */ + +static Py_uhash_t +_shuffle_bits(Py_uhash_t h) +{ + return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL; +} + +/* Most of the constants in this hash algorithm are randomly chosen + large primes with "interesting bit patterns" and that passed tests + for good collision statistics on a variety of problematic datasets + including powersets and graph structures (such as David Eppstein's + graph recipes in Lib/test/test_set.py) */ + +static Py_hash_t +frozenset_hash(PyObject *self) +{ + PySetObject *so = (PySetObject *)self; + Py_uhash_t hash = 0; + setentry *entry; + + if (so->hash != -1) + return so->hash; + + /* Xor-in shuffled bits from every entry's hash field because xor is + commutative and a frozenset hash should be independent of order. + + For speed, include null entries and dummy entries and then + subtract out their effect afterwards so that the final hash + depends only on active entries. This allows the code to be + vectorized by the compiler and it saves the unpredictable + branches that would arise when trying to exclude null and dummy + entries on every iteration. */ + + for (entry = so->table; entry <= &so->table[so->mask]; entry++) + hash ^= _shuffle_bits(entry->hash); + + /* Remove the effect of an odd number of NULL entries */ + if ((so->mask + 1 - so->fill) & 1) + hash ^= _shuffle_bits(0); + + /* Remove the effect of an odd number of dummy entries */ + if ((so->fill - so->used) & 1) + hash ^= _shuffle_bits(-1); + + /* Factor in the number of active entries */ + hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL; + + /* Disperse patterns arising in nested frozensets */ + hash ^= (hash >> 11) ^ (hash >> 25); + hash = hash * 69069U + 907133923UL; + + /* -1 is reserved as an error code */ + if (hash == (Py_uhash_t)-1) + hash = 590923713UL; + + so->hash = hash; + return hash; +} + +/***** Set iterator type ***********************************************/ + +typedef struct { + PyObject_HEAD + PySetObject *si_set; /* Set to NULL when iterator is exhausted */ + Py_ssize_t si_used; + Py_ssize_t si_pos; + Py_ssize_t len; +} setiterobject; + +static void +setiter_dealloc(setiterobject *si) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + _PyObject_GC_UNTRACK(si); + Py_XDECREF(si->si_set); + PyObject_GC_Del(si); +} + +static int +setiter_traverse(setiterobject *si, visitproc visit, void *arg) +{ + Py_VISIT(si->si_set); + return 0; +} + +static PyObject * +setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len = 0; + if (si->si_set != NULL && si->si_used == si->si_set->used) + len = si->len; + return PyLong_FromSsize_t(len); +} + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); + +static PyObject *setiter_iternext(setiterobject *si); + +static PyObject * +setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + /* copy the iterator state */ + setiterobject tmp = *si; + Py_XINCREF(tmp.si_set); + + /* iterate the temporary into a list */ + PyObject *list = PySequence_List((PyObject*)&tmp); + Py_XDECREF(tmp.si_set); + if (list == NULL) { + return NULL; + } + return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyMethodDef setiter_methods[] = { + {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject *setiter_iternext(setiterobject *si) +{ + PyObject *key; + Py_ssize_t i, mask; + setentry *entry; + PySetObject *so = si->si_set; + + if (so == NULL) + return NULL; + assert (PyAnySet_Check(so)); + + if (si->si_used != so->used) { + PyErr_SetString(PyExc_RuntimeError, + "Set changed size during iteration"); + si->si_used = -1; /* Make this state sticky */ + return NULL; + } + + i = si->si_pos; + assert(i>=0); + entry = so->table; + mask = so->mask; + while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy)) + i++; + si->si_pos = i+1; + if (i > mask) + goto fail; + si->len--; + key = entry[i].key; + Py_INCREF(key); + return key; + +fail: + si->si_set = NULL; + Py_DECREF(so); + return NULL; +} + +PyTypeObject PySetIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "set_iterator", /* tp_name */ + sizeof(setiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)setiter_dealloc, /* tp_dealloc */ + 0, /* tp_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, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)setiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)setiter_iternext, /* tp_iternext */ + setiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +set_iter(PySetObject *so) +{ + setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type); + if (si == NULL) + return NULL; + Py_INCREF(so); + si->si_set = so; + si->si_used = so->used; + si->si_pos = 0; + si->len = so->used; + _PyObject_GC_TRACK(si); + return (PyObject *)si; +} + +static int +set_update_internal(PySetObject *so, PyObject *other) +{ + PyObject *key, *it; + + if (PyAnySet_Check(other)) + return set_merge(so, other); + + if (PyDict_CheckExact(other)) { + PyObject *value; + Py_ssize_t pos = 0; + Py_hash_t hash; + Py_ssize_t dictsize = PyDict_GET_SIZE(other); + + /* Do one big resize at the start, rather than + * incrementally resizing as we insert new keys. Expect + * that there will be no (or few) overlapping keys. + */ + if (dictsize < 0) + return -1; + if ((so->fill + dictsize)*5 >= so->mask*3) { + if (set_table_resize(so, (so->used + dictsize)*2) != 0) + return -1; + } + while (_PyDict_Next(other, &pos, &key, &value, &hash)) { + if (set_add_entry(so, key, hash)) + return -1; + } + return 0; + } + + it = PyObject_GetIter(other); + if (it == NULL) + return -1; + + while ((key = PyIter_Next(it)) != NULL) { + if (set_add_key(so, key)) { + Py_DECREF(it); + Py_DECREF(key); + return -1; + } + Py_DECREF(key); + } + Py_DECREF(it); + if (PyErr_Occurred()) + return -1; + return 0; +} + +static PyObject * +set_update(PySetObject *so, PyObject *args) +{ + Py_ssize_t i; + + for (i=0 ; itp_alloc(type, 0); + if (so == NULL) + return NULL; + + so->fill = 0; + so->used = 0; + so->mask = PySet_MINSIZE - 1; + so->table = so->smalltable; + so->hash = -1; + so->finger = 0; + so->weakreflist = NULL; + + if (iterable != NULL) { + if (set_update_internal(so, iterable)) { + Py_DECREF(so); + return NULL; + } + } + + return (PyObject *)so; +} + +static PyObject * +make_new_set_basetype(PyTypeObject *type, PyObject *iterable) +{ + if (type != &PySet_Type && type != &PyFrozenSet_Type) { + if (PyType_IsSubtype(type, &PySet_Type)) + type = &PySet_Type; + else + type = &PyFrozenSet_Type; + } + return make_new_set(type, iterable); +} + +/* The empty frozenset is a singleton */ +static PyObject *emptyfrozenset = NULL; + +static PyObject * +frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *iterable = NULL, *result; + + if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds)) + return NULL; + + if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) + return NULL; + + if (type != &PyFrozenSet_Type) + return make_new_set(type, iterable); + + if (iterable != NULL) { + /* frozenset(f) is idempotent */ + if (PyFrozenSet_CheckExact(iterable)) { + Py_INCREF(iterable); + return iterable; + } + result = make_new_set(type, iterable); + if (result == NULL || PySet_GET_SIZE(result)) + return result; + Py_DECREF(result); + } + /* The empty frozenset is a singleton */ + if (emptyfrozenset == NULL) + emptyfrozenset = make_new_set(type, NULL); + Py_XINCREF(emptyfrozenset); + return emptyfrozenset; +} + +static PyObject * +set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return make_new_set(type, NULL); +} + +/* set_swap_bodies() switches the contents of any two sets by moving their + internal data pointers and, if needed, copying the internal smalltables. + Semantically equivalent to: + + t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t + + The function always succeeds and it leaves both objects in a stable state. + Useful for operations that update in-place (by allowing an intermediate + result to be swapped into one of the original inputs). +*/ + +static void +set_swap_bodies(PySetObject *a, PySetObject *b) +{ + Py_ssize_t t; + setentry *u; + setentry tab[PySet_MINSIZE]; + Py_hash_t h; + + t = a->fill; a->fill = b->fill; b->fill = t; + t = a->used; a->used = b->used; b->used = t; + t = a->mask; a->mask = b->mask; b->mask = t; + + u = a->table; + if (a->table == a->smalltable) + u = b->smalltable; + a->table = b->table; + if (b->table == b->smalltable) + a->table = a->smalltable; + b->table = u; + + if (a->table == a->smalltable || b->table == b->smalltable) { + memcpy(tab, a->smalltable, sizeof(tab)); + memcpy(a->smalltable, b->smalltable, sizeof(tab)); + memcpy(b->smalltable, tab, sizeof(tab)); + } + + if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) && + PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) { + h = a->hash; a->hash = b->hash; b->hash = h; + } else { + a->hash = -1; + b->hash = -1; + } +} + +static PyObject * +set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored)) +{ + return make_new_set_basetype(Py_TYPE(so), (PyObject *)so); +} + +static PyObject * +frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored)) +{ + if (PyFrozenSet_CheckExact(so)) { + Py_INCREF(so); + return (PyObject *)so; + } + return set_copy(so, NULL); +} + +PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set."); + +static PyObject * +set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored)) +{ + set_clear_internal(so); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(clear_doc, "Remove all elements from this set."); + +static PyObject * +set_union(PySetObject *so, PyObject *args) +{ + PySetObject *result; + PyObject *other; + Py_ssize_t i; + + result = (PySetObject *)set_copy(so, NULL); + if (result == NULL) + return NULL; + + for (i=0 ; i PySet_GET_SIZE(so)) { + tmp = (PyObject *)so; + so = (PySetObject *)other; + other = tmp; + } + + while (set_next((PySetObject *)other, &pos, &entry)) { + key = entry->key; + hash = entry->hash; + rv = set_contains_entry(so, key, hash); + if (rv < 0) { + Py_DECREF(result); + return NULL; + } + if (rv) { + if (set_add_entry(result, key, hash)) { + Py_DECREF(result); + return NULL; + } + } + } + return (PyObject *)result; + } + + it = PyObject_GetIter(other); + if (it == NULL) { + Py_DECREF(result); + return NULL; + } + + while ((key = PyIter_Next(it)) != NULL) { + hash = PyObject_Hash(key); + if (hash == -1) + goto error; + rv = set_contains_entry(so, key, hash); + if (rv < 0) + goto error; + if (rv) { + if (set_add_entry(result, key, hash)) + goto error; + } + Py_DECREF(key); + } + Py_DECREF(it); + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + return (PyObject *)result; + error: + Py_DECREF(it); + Py_DECREF(result); + Py_DECREF(key); + return NULL; +} + +static PyObject * +set_intersection_multi(PySetObject *so, PyObject *args) +{ + Py_ssize_t i; + PyObject *result = (PyObject *)so; + + if (PyTuple_GET_SIZE(args) == 0) + return set_copy(so, NULL); + + Py_INCREF(so); + for (i=0 ; i PySet_GET_SIZE(so)) { + tmp = (PyObject *)so; + so = (PySetObject *)other; + other = tmp; + } + while (set_next((PySetObject *)other, &pos, &entry)) { + rv = set_contains_entry(so, entry->key, entry->hash); + if (rv < 0) + return NULL; + if (rv) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; + } + + it = PyObject_GetIter(other); + if (it == NULL) + return NULL; + + while ((key = PyIter_Next(it)) != NULL) { + Py_hash_t hash = PyObject_Hash(key); + + if (hash == -1) { + Py_DECREF(key); + Py_DECREF(it); + return NULL; + } + rv = set_contains_entry(so, key, hash); + Py_DECREF(key); + if (rv < 0) { + Py_DECREF(it); + return NULL; + } + if (rv) { + Py_DECREF(it); + Py_RETURN_FALSE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_TRUE; +} + +PyDoc_STRVAR(isdisjoint_doc, +"Return True if two sets have a null intersection."); + +static int +set_difference_update_internal(PySetObject *so, PyObject *other) +{ + if ((PyObject *)so == other) + return set_clear_internal(so); + + if (PyAnySet_Check(other)) { + setentry *entry; + Py_ssize_t pos = 0; + + while (set_next((PySetObject *)other, &pos, &entry)) + if (set_discard_entry(so, entry->key, entry->hash) < 0) + return -1; + } else { + PyObject *key, *it; + it = PyObject_GetIter(other); + if (it == NULL) + return -1; + + while ((key = PyIter_Next(it)) != NULL) { + if (set_discard_key(so, key) < 0) { + Py_DECREF(it); + Py_DECREF(key); + return -1; + } + Py_DECREF(key); + } + Py_DECREF(it); + if (PyErr_Occurred()) + return -1; + } + /* If more than 1/4th are dummies, then resize them away. */ + if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4) + return 0; + return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4); +} + +static PyObject * +set_difference_update(PySetObject *so, PyObject *args) +{ + Py_ssize_t i; + + for (i=0 ; i> 2) > other_size) { + return set_copy_and_difference(so, other); + } + + result = make_new_set_basetype(Py_TYPE(so), NULL); + if (result == NULL) + return NULL; + + if (PyDict_CheckExact(other)) { + while (set_next(so, &pos, &entry)) { + key = entry->key; + hash = entry->hash; + rv = _PyDict_Contains(other, key, hash); + if (rv < 0) { + Py_DECREF(result); + return NULL; + } + if (!rv) { + if (set_add_entry((PySetObject *)result, key, hash)) { + Py_DECREF(result); + return NULL; + } + } + } + return result; + } + + /* Iterate over so, checking for common elements in other. */ + while (set_next(so, &pos, &entry)) { + key = entry->key; + hash = entry->hash; + rv = set_contains_entry((PySetObject *)other, key, hash); + if (rv < 0) { + Py_DECREF(result); + return NULL; + } + if (!rv) { + if (set_add_entry((PySetObject *)result, key, hash)) { + Py_DECREF(result); + return NULL; + } + } + } + return result; +} + +static PyObject * +set_difference_multi(PySetObject *so, PyObject *args) +{ + Py_ssize_t i; + PyObject *result, *other; + + if (PyTuple_GET_SIZE(args) == 0) + return set_copy(so, NULL); + + other = PyTuple_GET_ITEM(args, 0); + result = set_difference(so, other); + if (result == NULL) + return NULL; + + for (i=1 ; ikey; + hash = entry->hash; + rv = set_discard_entry(so, key, hash); + if (rv < 0) { + Py_DECREF(otherset); + return NULL; + } + if (rv == DISCARD_NOTFOUND) { + if (set_add_entry(so, key, hash)) { + Py_DECREF(otherset); + return NULL; + } + } + } + Py_DECREF(otherset); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(symmetric_difference_update_doc, +"Update a set with the symmetric difference of itself and another."); + +static PyObject * +set_symmetric_difference(PySetObject *so, PyObject *other) +{ + PyObject *rv; + PySetObject *otherset; + + otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other); + if (otherset == NULL) + return NULL; + rv = set_symmetric_difference_update(otherset, (PyObject *)so); + if (rv == NULL) { + Py_DECREF(otherset); + return NULL; + } + Py_DECREF(rv); + return (PyObject *)otherset; +} + +PyDoc_STRVAR(symmetric_difference_doc, +"Return the symmetric difference of two sets as a new set.\n\ +\n\ +(i.e. all elements that are in exactly one of the sets.)"); + +static PyObject * +set_xor(PySetObject *so, PyObject *other) +{ + if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; + return set_symmetric_difference(so, other); +} + +static PyObject * +set_ixor(PySetObject *so, PyObject *other) +{ + PyObject *result; + + if (!PyAnySet_Check(other)) + Py_RETURN_NOTIMPLEMENTED; + result = set_symmetric_difference_update(so, other); + if (result == NULL) + return NULL; + Py_DECREF(result); + Py_INCREF(so); + return (PyObject *)so; +} + +static PyObject * +set_issubset(PySetObject *so, PyObject *other) +{ + setentry *entry; + Py_ssize_t pos = 0; + int rv; + + if (!PyAnySet_Check(other)) { + PyObject *tmp, *result; + tmp = make_new_set(&PySet_Type, other); + if (tmp == NULL) + return NULL; + result = set_issubset(so, tmp); + Py_DECREF(tmp); + return result; + } + if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other)) + Py_RETURN_FALSE; + + while (set_next(so, &pos, &entry)) { + rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash); + if (rv < 0) + return NULL; + if (!rv) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + +PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set."); + +static PyObject * +set_issuperset(PySetObject *so, PyObject *other) +{ + PyObject *tmp, *result; + + if (!PyAnySet_Check(other)) { + tmp = make_new_set(&PySet_Type, other); + if (tmp == NULL) + return NULL; + result = set_issuperset(so, tmp); + Py_DECREF(tmp); + return result; + } + return set_issubset((PySetObject *)other, (PyObject *)so); +} + +PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set."); + +static PyObject * +set_richcompare(PySetObject *v, PyObject *w, int op) +{ + PyObject *r1; + int r2; + + if(!PyAnySet_Check(w)) + Py_RETURN_NOTIMPLEMENTED; + + switch (op) { + case Py_EQ: + if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w)) + Py_RETURN_FALSE; + if (v->hash != -1 && + ((PySetObject *)w)->hash != -1 && + v->hash != ((PySetObject *)w)->hash) + Py_RETURN_FALSE; + return set_issubset(v, w); + case Py_NE: + r1 = set_richcompare(v, w, Py_EQ); + if (r1 == NULL) + return NULL; + r2 = PyObject_IsTrue(r1); + Py_DECREF(r1); + if (r2 < 0) + return NULL; + return PyBool_FromLong(!r2); + case Py_LE: + return set_issubset(v, w); + case Py_GE: + return set_issuperset(v, w); + case Py_LT: + if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w)) + Py_RETURN_FALSE; + return set_issubset(v, w); + case Py_GT: + if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w)) + Py_RETURN_FALSE; + return set_issuperset(v, w); + } + Py_RETURN_NOTIMPLEMENTED; +} + +static PyObject * +set_add(PySetObject *so, PyObject *key) +{ + if (set_add_key(so, key)) + return NULL; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(add_doc, +"Add an element to a set.\n\ +\n\ +This has no effect if the element is already present."); + +static int +set_contains(PySetObject *so, PyObject *key) +{ + PyObject *tmpkey; + int rv; + + rv = set_contains_key(so, key); + if (rv < 0) { + if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) + return -1; + PyErr_Clear(); + tmpkey = make_new_set(&PyFrozenSet_Type, key); + if (tmpkey == NULL) + return -1; + rv = set_contains_key(so, tmpkey); + Py_DECREF(tmpkey); + } + return rv; +} + +static PyObject * +set_direct_contains(PySetObject *so, PyObject *key) +{ + long result; + + result = set_contains(so, key); + if (result < 0) + return NULL; + return PyBool_FromLong(result); +} + +PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x."); + +static PyObject * +set_remove(PySetObject *so, PyObject *key) +{ + PyObject *tmpkey; + int rv; + + rv = set_discard_key(so, key); + if (rv < 0) { + if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) + return NULL; + PyErr_Clear(); + tmpkey = make_new_set(&PyFrozenSet_Type, key); + if (tmpkey == NULL) + return NULL; + rv = set_discard_key(so, tmpkey); + Py_DECREF(tmpkey); + if (rv < 0) + return NULL; + } + + if (rv == DISCARD_NOTFOUND) { + _PyErr_SetKeyError(key); + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(remove_doc, +"Remove an element from a set; it must be a member.\n\ +\n\ +If the element is not a member, raise a KeyError."); + +static PyObject * +set_discard(PySetObject *so, PyObject *key) +{ + PyObject *tmpkey; + int rv; + + rv = set_discard_key(so, key); + if (rv < 0) { + if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) + return NULL; + PyErr_Clear(); + tmpkey = make_new_set(&PyFrozenSet_Type, key); + if (tmpkey == NULL) + return NULL; + rv = set_discard_key(so, tmpkey); + Py_DECREF(tmpkey); + if (rv < 0) + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(discard_doc, +"Remove an element from a set if it is a member.\n\ +\n\ +If the element is not a member, do nothing."); + +static PyObject * +set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored)) +{ + PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL; + _Py_IDENTIFIER(__dict__); + + keys = PySequence_List((PyObject *)so); + if (keys == NULL) + goto done; + args = PyTuple_Pack(1, keys); + if (args == NULL) + goto done; + if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) { + goto done; + } + if (dict == NULL) { + dict = Py_None; + Py_INCREF(dict); + } + result = PyTuple_Pack(3, Py_TYPE(so), args, dict); +done: + Py_XDECREF(args); + Py_XDECREF(keys); + Py_XDECREF(dict); + return result; +} + +static PyObject * +set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(so)); + if (so->table != so->smalltable) + res = res + (so->mask + 1) * sizeof(setentry); + return PyLong_FromSsize_t(res); +} + +PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes"); +static int +set_init(PySetObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *iterable = NULL; + + if (!_PyArg_NoKeywords("set", kwds)) + return -1; + if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable)) + return -1; + if (self->fill) + set_clear_internal(self); + self->hash = -1; + if (iterable == NULL) + return 0; + return set_update_internal(self, iterable); +} + +static PySequenceMethods set_as_sequence = { + set_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)set_contains, /* sq_contains */ +}; + +/* set object ********************************************************/ + +#ifdef Py_DEBUG +static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored)); + +PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\ +All is well if assertions don't fail."); +#endif + +static PyMethodDef set_methods[] = { + {"add", (PyCFunction)set_add, METH_O, + add_doc}, + {"clear", (PyCFunction)set_clear, METH_NOARGS, + clear_doc}, + {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST, + contains_doc}, + {"copy", (PyCFunction)set_copy, METH_NOARGS, + copy_doc}, + {"discard", (PyCFunction)set_discard, METH_O, + discard_doc}, + {"difference", (PyCFunction)set_difference_multi, METH_VARARGS, + difference_doc}, + {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS, + difference_update_doc}, + {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS, + intersection_doc}, + {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS, + intersection_update_doc}, + {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O, + isdisjoint_doc}, + {"issubset", (PyCFunction)set_issubset, METH_O, + issubset_doc}, + {"issuperset", (PyCFunction)set_issuperset, METH_O, + issuperset_doc}, + {"pop", (PyCFunction)set_pop, METH_NOARGS, + pop_doc}, + {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS, + reduce_doc}, + {"remove", (PyCFunction)set_remove, METH_O, + remove_doc}, + {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS, + sizeof_doc}, + {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O, + symmetric_difference_doc}, + {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O, + symmetric_difference_update_doc}, +#ifdef Py_DEBUG + {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS, + test_c_api_doc}, +#endif + {"union", (PyCFunction)set_union, METH_VARARGS, + union_doc}, + {"update", (PyCFunction)set_update, METH_VARARGS, + update_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyNumberMethods set_as_number = { + 0, /*nb_add*/ + (binaryfunc)set_sub, /*nb_subtract*/ + 0, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + 0, /*nb_negative*/ + 0, /*nb_positive*/ + 0, /*nb_absolute*/ + 0, /*nb_bool*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + (binaryfunc)set_and, /*nb_and*/ + (binaryfunc)set_xor, /*nb_xor*/ + (binaryfunc)set_or, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + 0, /*nb_inplace_add*/ + (binaryfunc)set_isub, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + 0, /*nb_inplace_remainder*/ + 0, /*nb_inplace_power*/ + 0, /*nb_inplace_lshift*/ + 0, /*nb_inplace_rshift*/ + (binaryfunc)set_iand, /*nb_inplace_and*/ + (binaryfunc)set_ixor, /*nb_inplace_xor*/ + (binaryfunc)set_ior, /*nb_inplace_or*/ +}; + +PyDoc_STRVAR(set_doc, +"set() -> new empty set object\n\ +set(iterable) -> new set object\n\ +\n\ +Build an unordered collection of unique elements."); + +PyTypeObject PySet_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "set", /* tp_name */ + sizeof(PySetObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)set_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)set_repr, /* tp_repr */ + &set_as_number, /* tp_as_number */ + &set_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_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + set_doc, /* tp_doc */ + (traverseproc)set_traverse, /* tp_traverse */ + (inquiry)set_clear_internal, /* tp_clear */ + (richcmpfunc)set_richcompare, /* tp_richcompare */ + offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)set_iter, /* tp_iter */ + 0, /* tp_iternext */ + set_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)set_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + set_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +/* frozenset object ********************************************************/ + + +static PyMethodDef frozenset_methods[] = { + {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST, + contains_doc}, + {"copy", (PyCFunction)frozenset_copy, METH_NOARGS, + copy_doc}, + {"difference", (PyCFunction)set_difference_multi, METH_VARARGS, + difference_doc}, + {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS, + intersection_doc}, + {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O, + isdisjoint_doc}, + {"issubset", (PyCFunction)set_issubset, METH_O, + issubset_doc}, + {"issuperset", (PyCFunction)set_issuperset, METH_O, + issuperset_doc}, + {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS, + reduce_doc}, + {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS, + sizeof_doc}, + {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O, + symmetric_difference_doc}, + {"union", (PyCFunction)set_union, METH_VARARGS, + union_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyNumberMethods frozenset_as_number = { + 0, /*nb_add*/ + (binaryfunc)set_sub, /*nb_subtract*/ + 0, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + 0, /*nb_negative*/ + 0, /*nb_positive*/ + 0, /*nb_absolute*/ + 0, /*nb_bool*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + (binaryfunc)set_and, /*nb_and*/ + (binaryfunc)set_xor, /*nb_xor*/ + (binaryfunc)set_or, /*nb_or*/ +}; + +PyDoc_STRVAR(frozenset_doc, +"frozenset() -> empty frozenset object\n\ +frozenset(iterable) -> frozenset object\n\ +\n\ +Build an immutable unordered collection of unique elements."); + +PyTypeObject PyFrozenSet_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "frozenset", /* tp_name */ + sizeof(PySetObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)set_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)set_repr, /* tp_repr */ + &frozenset_as_number, /* tp_as_number */ + &set_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + frozenset_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + frozenset_doc, /* tp_doc */ + (traverseproc)set_traverse, /* tp_traverse */ + (inquiry)set_clear_internal, /* tp_clear */ + (richcmpfunc)set_richcompare, /* tp_richcompare */ + offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)set_iter, /* tp_iter */ + 0, /* tp_iternext */ + frozenset_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + frozenset_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/***** C API functions *************************************************/ + +PyObject * +PySet_New(PyObject *iterable) +{ + return make_new_set(&PySet_Type, iterable); +} + +PyObject * +PyFrozenSet_New(PyObject *iterable) +{ + return make_new_set(&PyFrozenSet_Type, iterable); +} + +Py_ssize_t +PySet_Size(PyObject *anyset) +{ + if (!PyAnySet_Check(anyset)) { + PyErr_BadInternalCall(); + return -1; + } + return PySet_GET_SIZE(anyset); +} + +int +PySet_Clear(PyObject *set) +{ + if (!PySet_Check(set)) { + PyErr_BadInternalCall(); + return -1; + } + return set_clear_internal((PySetObject *)set); +} + +int +PySet_Contains(PyObject *anyset, PyObject *key) +{ + if (!PyAnySet_Check(anyset)) { + PyErr_BadInternalCall(); + return -1; + } + return set_contains_key((PySetObject *)anyset, key); +} + +int +PySet_Discard(PyObject *set, PyObject *key) +{ + if (!PySet_Check(set)) { + PyErr_BadInternalCall(); + return -1; + } + return set_discard_key((PySetObject *)set, key); +} + +int +PySet_Add(PyObject *anyset, PyObject *key) +{ + if (!PySet_Check(anyset) && + (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) { + PyErr_BadInternalCall(); + return -1; + } + return set_add_key((PySetObject *)anyset, key); +} + +int +PySet_ClearFreeList(void) +{ + return 0; +} + +void +PySet_Fini(void) +{ + Py_CLEAR(emptyfrozenset); +} + +int +_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash) +{ + setentry *entry; + + if (!PyAnySet_Check(set)) { + PyErr_BadInternalCall(); + return -1; + } + if (set_next((PySetObject *)set, pos, &entry) == 0) + return 0; + *key = entry->key; + *hash = entry->hash; + return 1; +} + +PyObject * +PySet_Pop(PyObject *set) +{ + if (!PySet_Check(set)) { + PyErr_BadInternalCall(); + return NULL; + } + return set_pop((PySetObject *)set, NULL); +} + +int +_PySet_Update(PyObject *set, PyObject *iterable) +{ + if (!PySet_Check(set)) { + PyErr_BadInternalCall(); + return -1; + } + return set_update_internal((PySetObject *)set, iterable); +} + +/* Exported for the gdb plugin's benefit. */ +PyObject *_PySet_Dummy = dummy; + +#ifdef Py_DEBUG + +/* Test code to be called with any three element set. + Returns True and original set is restored. */ + +#define assertRaises(call_return_value, exception) \ + do { \ + assert(call_return_value); \ + assert(PyErr_ExceptionMatches(exception)); \ + PyErr_Clear(); \ + } while(0) + +static PyObject * +test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t count; + const char *s; + Py_ssize_t i; + PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL; + PyObject *ob = (PyObject *)so; + Py_hash_t hash; + PyObject *str; + + /* Verify preconditions */ + assert(PyAnySet_Check(ob)); + assert(PyAnySet_CheckExact(ob)); + assert(!PyFrozenSet_CheckExact(ob)); + + /* so.clear(); so |= set("abc"); */ + str = PyUnicode_FromString("abc"); + if (str == NULL) + return NULL; + set_clear_internal(so); + if (set_update_internal(so, str)) { + Py_DECREF(str); + return NULL; + } + Py_DECREF(str); + + /* Exercise type/size checks */ + assert(PySet_Size(ob) == 3); + assert(PySet_GET_SIZE(ob) == 3); + + /* Raise TypeError for non-iterable constructor arguments */ + assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError); + assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError); + + /* Raise TypeError for unhashable key */ + dup = PySet_New(ob); + assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError); + assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError); + assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError); + + /* Exercise successful pop, contains, add, and discard */ + elem = PySet_Pop(ob); + assert(PySet_Contains(ob, elem) == 0); + assert(PySet_GET_SIZE(ob) == 2); + assert(PySet_Add(ob, elem) == 0); + assert(PySet_Contains(ob, elem) == 1); + assert(PySet_GET_SIZE(ob) == 3); + assert(PySet_Discard(ob, elem) == 1); + assert(PySet_GET_SIZE(ob) == 2); + assert(PySet_Discard(ob, elem) == 0); + assert(PySet_GET_SIZE(ob) == 2); + + /* Exercise clear */ + dup2 = PySet_New(dup); + assert(PySet_Clear(dup2) == 0); + assert(PySet_Size(dup2) == 0); + Py_DECREF(dup2); + + /* Raise SystemError on clear or update of frozen set */ + f = PyFrozenSet_New(dup); + assertRaises(PySet_Clear(f) == -1, PyExc_SystemError); + assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError); + assert(PySet_Add(f, elem) == 0); + Py_INCREF(f); + assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError); + Py_DECREF(f); + Py_DECREF(f); + + /* Exercise direct iteration */ + i = 0, count = 0; + while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) { + s = PyUnicode_AsUTF8(x); + assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c')); + count++; + } + assert(count == 3); + + /* Exercise updates */ + dup2 = PySet_New(NULL); + assert(_PySet_Update(dup2, dup) == 0); + assert(PySet_Size(dup2) == 3); + assert(_PySet_Update(dup2, dup) == 0); + assert(PySet_Size(dup2) == 3); + Py_DECREF(dup2); + + /* Raise SystemError when self argument is not a set or frozenset. */ + t = PyTuple_New(0); + assertRaises(PySet_Size(t) == -1, PyExc_SystemError); + assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError); + Py_DECREF(t); + + /* Raise SystemError when self argument is not a set. */ + f = PyFrozenSet_New(dup); + assert(PySet_Size(f) == 3); + assert(PyFrozenSet_CheckExact(f)); + assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError); + assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError); + Py_DECREF(f); + + /* Raise KeyError when popping from an empty set */ + assert(PyNumber_InPlaceSubtract(ob, ob) == ob); + Py_DECREF(ob); + assert(PySet_GET_SIZE(ob) == 0); + assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError); + + /* Restore the set from the copy using the PyNumber API */ + assert(PyNumber_InPlaceOr(ob, dup) == ob); + Py_DECREF(ob); + + /* Verify constructors accept NULL arguments */ + f = PySet_New(NULL); + assert(f != NULL); + assert(PySet_GET_SIZE(f) == 0); + Py_DECREF(f); + f = PyFrozenSet_New(NULL); + assert(f != NULL); + assert(PyFrozenSet_CheckExact(f)); + assert(PySet_GET_SIZE(f) == 0); + Py_DECREF(f); + + Py_DECREF(elem); + Py_DECREF(dup); + Py_RETURN_TRUE; +} + +#undef assertRaises + +#endif + +/***** Dummy Struct *************************************************/ + +static PyObject * +dummy_repr(PyObject *op) +{ + return PyUnicode_FromString(""); +} + +static void +dummy_dealloc(PyObject* ignore) +{ + Py_FatalError("deallocating "); +} + +static PyTypeObject _PySetDummy_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + " type", + 0, + 0, + dummy_dealloc, /*tp_dealloc*/ /*never called*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + dummy_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 */ +}; + +static PyObject _dummy_struct = { + _PyObject_EXTRA_INIT + 2, &_PySetDummy_Type +}; + diff --git a/python/Objects/sliceobject.c b/python/Objects/sliceobject.c new file mode 100755 index 0000000..7c10eb6 --- /dev/null +++ b/python/Objects/sliceobject.c @@ -0,0 +1,661 @@ +/* +Written by Jim Hugunin and Chris Chase. + +This includes both the singular ellipsis object and slice objects. + +Guido, feel free to do whatever you want in the way of copyrights +for this file. +*/ + +/* +Py_Ellipsis encodes the '...' rubber index token. It is similar to +the Py_NoneStruct in that there is no way to create other objects of +this type and there is exactly one in existence. +*/ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "structmember.h" + +static PyObject * +ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { + PyErr_SetString(PyExc_TypeError, "EllipsisType takes no arguments"); + return NULL; + } + Py_INCREF(Py_Ellipsis); + return Py_Ellipsis; +} + +static PyObject * +ellipsis_repr(PyObject *op) +{ + return PyUnicode_FromString("Ellipsis"); +} + +static PyObject * +ellipsis_reduce(PyObject *op, PyObject *Py_UNUSED(ignored)) +{ + return PyUnicode_FromString("Ellipsis"); +} + +static PyMethodDef ellipsis_methods[] = { + {"__reduce__", ellipsis_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +PyTypeObject PyEllipsis_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "ellipsis", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /*never called*/ /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + ellipsis_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ellipsis_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 */ + ellipsis_new, /* tp_new */ +}; + +PyObject _Py_EllipsisObject = { + _PyObject_EXTRA_INIT + 1, &PyEllipsis_Type +}; + + +/* Slice object implementation */ + +/* Using a cache is very effective since typically only a single slice is + * created and then deleted again + */ +static PySliceObject *slice_cache = NULL; +void PySlice_Fini(void) +{ + PySliceObject *obj = slice_cache; + if (obj != NULL) { + slice_cache = NULL; + PyObject_GC_Del(obj); + } +} + +/* start, stop, and step are python objects with None indicating no + index is present. +*/ + +PyObject * +PySlice_New(PyObject *start, PyObject *stop, PyObject *step) +{ + PySliceObject *obj; + if (slice_cache != NULL) { + obj = slice_cache; + slice_cache = NULL; + _Py_NewReference((PyObject *)obj); + } else { + obj = PyObject_GC_New(PySliceObject, &PySlice_Type); + if (obj == NULL) + return NULL; + } + + if (step == NULL) step = Py_None; + Py_INCREF(step); + if (start == NULL) start = Py_None; + Py_INCREF(start); + if (stop == NULL) stop = Py_None; + Py_INCREF(stop); + + obj->step = step; + obj->start = start; + obj->stop = stop; + + _PyObject_GC_TRACK(obj); + return (PyObject *) obj; +} + +PyObject * +_PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop) +{ + PyObject *start, *end, *slice; + start = PyLong_FromSsize_t(istart); + if (!start) + return NULL; + end = PyLong_FromSsize_t(istop); + if (!end) { + Py_DECREF(start); + return NULL; + } + + slice = PySlice_New(start, end, NULL); + Py_DECREF(start); + Py_DECREF(end); + return slice; +} + +int +PySlice_GetIndices(PyObject *_r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) +{ + PySliceObject *r = (PySliceObject*)_r; + /* XXX support long ints */ + if (r->step == Py_None) { + *step = 1; + } else { + if (!PyLong_Check(r->step)) return -1; + *step = PyLong_AsSsize_t(r->step); + } + if (r->start == Py_None) { + *start = *step < 0 ? length-1 : 0; + } else { + if (!PyLong_Check(r->start)) return -1; + *start = PyLong_AsSsize_t(r->start); + if (*start < 0) *start += length; + } + if (r->stop == Py_None) { + *stop = *step < 0 ? -1 : length; + } else { + if (!PyLong_Check(r->stop)) return -1; + *stop = PyLong_AsSsize_t(r->stop); + if (*stop < 0) *stop += length; + } + if (*stop > length) return -1; + if (*start >= length) return -1; + if (*step == 0) return -1; + return 0; +} + +int +PySlice_Unpack(PyObject *_r, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) +{ + PySliceObject *r = (PySliceObject*)_r; + /* this is harder to get right than you might think */ + + Py_BUILD_ASSERT(PY_SSIZE_T_MIN + 1 <= -PY_SSIZE_T_MAX); + + if (r->step == Py_None) { + *step = 1; + } + else { + if (!_PyEval_SliceIndex(r->step, step)) return -1; + if (*step == 0) { + PyErr_SetString(PyExc_ValueError, + "slice step cannot be zero"); + return -1; + } + /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it + * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it + * guards against later undefined behaviour resulting from code that + * does "step = -step" as part of a slice reversal. + */ + if (*step < -PY_SSIZE_T_MAX) + *step = -PY_SSIZE_T_MAX; + } + + if (r->start == Py_None) { + *start = *step < 0 ? PY_SSIZE_T_MAX : 0; + } + else { + if (!_PyEval_SliceIndex(r->start, start)) return -1; + } + + if (r->stop == Py_None) { + *stop = *step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX; + } + else { + if (!_PyEval_SliceIndex(r->stop, stop)) return -1; + } + + return 0; +} + +Py_ssize_t +PySlice_AdjustIndices(Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t step) +{ + /* this is harder to get right than you might think */ + + assert(step != 0); + assert(step >= -PY_SSIZE_T_MAX); + + if (*start < 0) { + *start += length; + if (*start < 0) { + *start = (step < 0) ? -1 : 0; + } + } + else if (*start >= length) { + *start = (step < 0) ? length - 1 : length; + } + + if (*stop < 0) { + *stop += length; + if (*stop < 0) { + *stop = (step < 0) ? -1 : 0; + } + } + else if (*stop >= length) { + *stop = (step < 0) ? length - 1 : length; + } + + if (step < 0) { + if (*stop < *start) { + return (*start - *stop - 1) / (-step) + 1; + } + } + else { + if (*start < *stop) { + return (*stop - *start - 1) / step + 1; + } + } + return 0; +} + +#undef PySlice_GetIndicesEx + +int +PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, + Py_ssize_t *slicelength) +{ + if (PySlice_Unpack(_r, start, stop, step) < 0) + return -1; + *slicelength = PySlice_AdjustIndices(length, start, stop, *step); + return 0; +} + +static PyObject * +slice_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *start, *stop, *step; + + start = stop = step = NULL; + + if (!_PyArg_NoKeywords("slice", kw)) + return NULL; + + if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step)) + return NULL; + + /* This swapping of stop and start is to maintain similarity with + range(). */ + if (stop == NULL) { + stop = start; + start = NULL; + } + return PySlice_New(start, stop, step); +} + +PyDoc_STRVAR(slice_doc, +"slice(stop)\n\ +slice(start, stop[, step])\n\ +\n\ +Create a slice object. This is used for extended slicing (e.g. a[0:10:2])."); + +static void +slice_dealloc(PySliceObject *r) +{ + _PyObject_GC_UNTRACK(r); + Py_DECREF(r->step); + Py_DECREF(r->start); + Py_DECREF(r->stop); + if (slice_cache == NULL) + slice_cache = r; + else + PyObject_GC_Del(r); +} + +static PyObject * +slice_repr(PySliceObject *r) +{ + return PyUnicode_FromFormat("slice(%R, %R, %R)", r->start, r->stop, r->step); +} + +static PyMemberDef slice_members[] = { + {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, + {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, + {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY}, + {0} +}; + +/* Helper function to convert a slice argument to a PyLong, and raise TypeError + with a suitable message on failure. */ + +static PyObject* +evaluate_slice_index(PyObject *v) +{ + if (PyIndex_Check(v)) { + return PyNumber_Index(v); + } + else { + PyErr_SetString(PyExc_TypeError, + "slice indices must be integers or " + "None or have an __index__ method"); + return NULL; + } +} + +/* Compute slice indices given a slice and length. Return -1 on failure. Used + by slice.indices and rangeobject slicing. Assumes that `len` is a + nonnegative instance of PyLong. */ + +int +_PySlice_GetLongIndices(PySliceObject *self, PyObject *length, + PyObject **start_ptr, PyObject **stop_ptr, + PyObject **step_ptr) +{ + PyObject *start=NULL, *stop=NULL, *step=NULL; + PyObject *upper=NULL, *lower=NULL; + int step_is_negative, cmp_result; + + /* Convert step to an integer; raise for zero step. */ + if (self->step == Py_None) { + step = _PyLong_One; + Py_INCREF(step); + step_is_negative = 0; + } + else { + int step_sign; + step = evaluate_slice_index(self->step); + if (step == NULL) + goto error; + step_sign = _PyLong_Sign(step); + if (step_sign == 0) { + PyErr_SetString(PyExc_ValueError, + "slice step cannot be zero"); + goto error; + } + step_is_negative = step_sign < 0; + } + + /* Find lower and upper bounds for start and stop. */ + if (step_is_negative) { + lower = PyLong_FromLong(-1L); + if (lower == NULL) + goto error; + + upper = PyNumber_Add(length, lower); + if (upper == NULL) + goto error; + } + else { + lower = _PyLong_Zero; + Py_INCREF(lower); + upper = length; + Py_INCREF(upper); + } + + /* Compute start. */ + if (self->start == Py_None) { + start = step_is_negative ? upper : lower; + Py_INCREF(start); + } + else { + start = evaluate_slice_index(self->start); + if (start == NULL) + goto error; + + if (_PyLong_Sign(start) < 0) { + /* start += length */ + PyObject *tmp = PyNumber_Add(start, length); + Py_DECREF(start); + start = tmp; + if (start == NULL) + goto error; + + cmp_result = PyObject_RichCompareBool(start, lower, Py_LT); + if (cmp_result < 0) + goto error; + if (cmp_result) { + Py_INCREF(lower); + Py_DECREF(start); + start = lower; + } + } + else { + cmp_result = PyObject_RichCompareBool(start, upper, Py_GT); + if (cmp_result < 0) + goto error; + if (cmp_result) { + Py_INCREF(upper); + Py_DECREF(start); + start = upper; + } + } + } + + /* Compute stop. */ + if (self->stop == Py_None) { + stop = step_is_negative ? lower : upper; + Py_INCREF(stop); + } + else { + stop = evaluate_slice_index(self->stop); + if (stop == NULL) + goto error; + + if (_PyLong_Sign(stop) < 0) { + /* stop += length */ + PyObject *tmp = PyNumber_Add(stop, length); + Py_DECREF(stop); + stop = tmp; + if (stop == NULL) + goto error; + + cmp_result = PyObject_RichCompareBool(stop, lower, Py_LT); + if (cmp_result < 0) + goto error; + if (cmp_result) { + Py_INCREF(lower); + Py_DECREF(stop); + stop = lower; + } + } + else { + cmp_result = PyObject_RichCompareBool(stop, upper, Py_GT); + if (cmp_result < 0) + goto error; + if (cmp_result) { + Py_INCREF(upper); + Py_DECREF(stop); + stop = upper; + } + } + } + + *start_ptr = start; + *stop_ptr = stop; + *step_ptr = step; + Py_DECREF(upper); + Py_DECREF(lower); + return 0; + + error: + *start_ptr = *stop_ptr = *step_ptr = NULL; + Py_XDECREF(start); + Py_XDECREF(stop); + Py_XDECREF(step); + Py_XDECREF(upper); + Py_XDECREF(lower); + return -1; +} + +/* Implementation of slice.indices. */ + +static PyObject* +slice_indices(PySliceObject* self, PyObject* len) +{ + PyObject *start, *stop, *step; + PyObject *length; + int error; + + /* Convert length to an integer if necessary; raise for negative length. */ + length = PyNumber_Index(len); + if (length == NULL) + return NULL; + + if (_PyLong_Sign(length) < 0) { + PyErr_SetString(PyExc_ValueError, + "length should not be negative"); + Py_DECREF(length); + return NULL; + } + + error = _PySlice_GetLongIndices(self, length, &start, &stop, &step); + Py_DECREF(length); + if (error == -1) + return NULL; + else + return Py_BuildValue("(NNN)", start, stop, step); +} + +PyDoc_STRVAR(slice_indices_doc, +"S.indices(len) -> (start, stop, stride)\n\ +\n\ +Assuming a sequence of length len, calculate the start and stop\n\ +indices, and the stride length of the extended slice described by\n\ +S. Out of bounds indices are clipped in a manner consistent with the\n\ +handling of normal slices."); + +static PyObject * +slice_reduce(PySliceObject* self, PyObject *Py_UNUSED(ignored)) +{ + return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyMethodDef slice_methods[] = { + {"indices", (PyCFunction)slice_indices, + METH_O, slice_indices_doc}, + {"__reduce__", (PyCFunction)slice_reduce, + METH_NOARGS, reduce_doc}, + {NULL, NULL} +}; + +static PyObject * +slice_richcompare(PyObject *v, PyObject *w, int op) +{ + if (!PySlice_Check(v) || !PySlice_Check(w)) + Py_RETURN_NOTIMPLEMENTED; + + if (v == w) { + PyObject *res; + /* XXX Do we really need this shortcut? + There's a unit test for it, but is that fair? */ + switch (op) { + case Py_EQ: + case Py_LE: + case Py_GE: + res = Py_True; + break; + default: + res = Py_False; + break; + } + Py_INCREF(res); + return res; + } + + + PyObject *t1 = PyTuple_Pack(3, + ((PySliceObject *)v)->start, + ((PySliceObject *)v)->stop, + ((PySliceObject *)v)->step); + if (t1 == NULL) { + return NULL; + } + + PyObject *t2 = PyTuple_Pack(3, + ((PySliceObject *)w)->start, + ((PySliceObject *)w)->stop, + ((PySliceObject *)w)->step); + if (t2 == NULL) { + Py_DECREF(t1); + return NULL; + } + + PyObject *res = PyObject_RichCompare(t1, t2, op); + Py_DECREF(t1); + Py_DECREF(t2); + return res; +} + +static int +slice_traverse(PySliceObject *v, visitproc visit, void *arg) +{ + Py_VISIT(v->start); + Py_VISIT(v->stop); + Py_VISIT(v->step); + return 0; +} + +PyTypeObject PySlice_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "slice", /* Name of this type */ + sizeof(PySliceObject), /* Basic object size */ + 0, /* Item size for varobject */ + (destructor)slice_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)slice_repr, /* 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 */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + slice_doc, /* tp_doc */ + (traverseproc)slice_traverse, /* tp_traverse */ + 0, /* tp_clear */ + slice_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + slice_methods, /* tp_methods */ + slice_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + slice_new, /* tp_new */ +}; diff --git a/python/Objects/stringlib/README.txt b/python/Objects/stringlib/README.txt new file mode 100755 index 0000000..8ff6ad8 --- /dev/null +++ b/python/Objects/stringlib/README.txt @@ -0,0 +1,40 @@ +bits shared by the bytesobject and unicodeobject implementations (and +possibly other modules, in a not too distant future). + +the stuff in here is included into relevant places; see the individual +source files for details. + +-------------------------------------------------------------------- +the following defines used by the different modules: + +STRINGLIB_CHAR + + the type used to hold a character (char or Py_UNICODE) + +STRINGLIB_EMPTY + + a PyObject representing the empty string, only to be used if + STRINGLIB_MUTABLE is 0 + +Py_ssize_t STRINGLIB_LEN(PyObject*) + + returns the length of the given string object (which must be of the + right type) + +PyObject* STRINGLIB_NEW(STRINGLIB_CHAR*, Py_ssize_t) + + creates a new string object + +STRINGLIB_CHAR* STRINGLIB_STR(PyObject*) + + returns the pointer to the character data for the given string + object (which must be of the right type) + +int STRINGLIB_CHECK_EXACT(PyObject *) + + returns true if the object is an instance of our type, not a subclass + +STRINGLIB_MUTABLE + + must be 0 or 1 to tell the cpp macros in stringlib code if the object + being operated on is mutable or not diff --git a/python/Objects/stringlib/asciilib.h b/python/Objects/stringlib/asciilib.h new file mode 100755 index 0000000..8f83614 --- /dev/null +++ b/python/Objects/stringlib/asciilib.h @@ -0,0 +1,29 @@ +/* this is sort of a hack. there's at least one place (formatting + floats) where some stringlib code takes a different path if it's + compiled as unicode. */ +#define STRINGLIB_IS_UNICODE 1 + +#define FASTSEARCH asciilib_fastsearch +#define STRINGLIB(F) asciilib_##F +#define STRINGLIB_OBJECT PyUnicodeObject +#define STRINGLIB_SIZEOF_CHAR 1 +#define STRINGLIB_MAX_CHAR 0x7Fu +#define STRINGLIB_CHAR Py_UCS1 +#define STRINGLIB_TYPE_NAME "unicode" +#define STRINGLIB_PARSE_CODE "U" +#define STRINGLIB_EMPTY unicode_empty +#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE +#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK +#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL +#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL +#define STRINGLIB_STR PyUnicode_1BYTE_DATA +#define STRINGLIB_LEN PyUnicode_GET_LENGTH +#define STRINGLIB_NEW(STR,LEN) _PyUnicode_FromASCII((const char*)(STR),(LEN)) +#define STRINGLIB_CHECK PyUnicode_Check +#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact + +#define STRINGLIB_TOSTR PyObject_Str +#define STRINGLIB_TOASCII PyObject_ASCII + +#define _Py_InsertThousandsGrouping _PyUnicode_ascii_InsertThousandsGrouping + diff --git a/python/Objects/stringlib/clinic/transmogrify.h.h b/python/Objects/stringlib/clinic/transmogrify.h.h new file mode 100755 index 0000000..8a3a060 --- /dev/null +++ b/python/Objects/stringlib/clinic/transmogrify.h.h @@ -0,0 +1,277 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(stringlib_expandtabs__doc__, +"expandtabs($self, /, tabsize=8)\n" +"--\n" +"\n" +"Return a copy where all tab characters are expanded using spaces.\n" +"\n" +"If tabsize is not given, a tab size of 8 characters is assumed."); + +#define STRINGLIB_EXPANDTABS_METHODDEF \ + {"expandtabs", (PyCFunction)(void(*)(void))stringlib_expandtabs, METH_FASTCALL|METH_KEYWORDS, stringlib_expandtabs__doc__}, + +static PyObject * +stringlib_expandtabs_impl(PyObject *self, int tabsize); + +static PyObject * +stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"tabsize", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int tabsize = 8; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + tabsize = _PyLong_AsInt(args[0]); + if (tabsize == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = stringlib_expandtabs_impl(self, tabsize); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_ljust__doc__, +"ljust($self, width, fillchar=b\' \', /)\n" +"--\n" +"\n" +"Return a left-justified string of length width.\n" +"\n" +"Padding is done using the specified fill character."); + +#define STRINGLIB_LJUST_METHODDEF \ + {"ljust", (PyCFunction)(void(*)(void))stringlib_ljust, METH_FASTCALL, stringlib_ljust__doc__}, + +static PyObject * +stringlib_ljust_impl(PyObject *self, Py_ssize_t width, char fillchar); + +static PyObject * +stringlib_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + char fillchar = ' '; + + if (!_PyArg_CheckPositional("ljust", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyBytes_Check(args[1]) && PyBytes_GET_SIZE(args[1]) == 1) { + fillchar = PyBytes_AS_STRING(args[1])[0]; + } + else if (PyByteArray_Check(args[1]) && PyByteArray_GET_SIZE(args[1]) == 1) { + fillchar = PyByteArray_AS_STRING(args[1])[0]; + } + else { + _PyArg_BadArgument("ljust", "argument 2", "a byte string of length 1", args[1]); + goto exit; + } +skip_optional: + return_value = stringlib_ljust_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_rjust__doc__, +"rjust($self, width, fillchar=b\' \', /)\n" +"--\n" +"\n" +"Return a right-justified string of length width.\n" +"\n" +"Padding is done using the specified fill character."); + +#define STRINGLIB_RJUST_METHODDEF \ + {"rjust", (PyCFunction)(void(*)(void))stringlib_rjust, METH_FASTCALL, stringlib_rjust__doc__}, + +static PyObject * +stringlib_rjust_impl(PyObject *self, Py_ssize_t width, char fillchar); + +static PyObject * +stringlib_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + char fillchar = ' '; + + if (!_PyArg_CheckPositional("rjust", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyBytes_Check(args[1]) && PyBytes_GET_SIZE(args[1]) == 1) { + fillchar = PyBytes_AS_STRING(args[1])[0]; + } + else if (PyByteArray_Check(args[1]) && PyByteArray_GET_SIZE(args[1]) == 1) { + fillchar = PyByteArray_AS_STRING(args[1])[0]; + } + else { + _PyArg_BadArgument("rjust", "argument 2", "a byte string of length 1", args[1]); + goto exit; + } +skip_optional: + return_value = stringlib_rjust_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_center__doc__, +"center($self, width, fillchar=b\' \', /)\n" +"--\n" +"\n" +"Return a centered string of length width.\n" +"\n" +"Padding is done using the specified fill character."); + +#define STRINGLIB_CENTER_METHODDEF \ + {"center", (PyCFunction)(void(*)(void))stringlib_center, METH_FASTCALL, stringlib_center__doc__}, + +static PyObject * +stringlib_center_impl(PyObject *self, Py_ssize_t width, char fillchar); + +static PyObject * +stringlib_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + char fillchar = ' '; + + if (!_PyArg_CheckPositional("center", nargs, 1, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyBytes_Check(args[1]) && PyBytes_GET_SIZE(args[1]) == 1) { + fillchar = PyBytes_AS_STRING(args[1])[0]; + } + else if (PyByteArray_Check(args[1]) && PyByteArray_GET_SIZE(args[1]) == 1) { + fillchar = PyByteArray_AS_STRING(args[1])[0]; + } + else { + _PyArg_BadArgument("center", "argument 2", "a byte string of length 1", args[1]); + goto exit; + } +skip_optional: + return_value = stringlib_center_impl(self, width, fillchar); + +exit: + return return_value; +} + +PyDoc_STRVAR(stringlib_zfill__doc__, +"zfill($self, width, /)\n" +"--\n" +"\n" +"Pad a numeric string with zeros on the left, to fill a field of the given width.\n" +"\n" +"The original string is never truncated."); + +#define STRINGLIB_ZFILL_METHODDEF \ + {"zfill", (PyCFunction)stringlib_zfill, METH_O, stringlib_zfill__doc__}, + +static PyObject * +stringlib_zfill_impl(PyObject *self, Py_ssize_t width); + +static PyObject * +stringlib_zfill(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t width; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + width = ival; + } + return_value = stringlib_zfill_impl(self, width); + +exit: + return return_value; +} +/*[clinic end generated code: output=15be047aef999b4e input=a9049054013a1b77]*/ diff --git a/python/Objects/stringlib/codecs.h b/python/Objects/stringlib/codecs.h new file mode 100755 index 0000000..269a558 --- /dev/null +++ b/python/Objects/stringlib/codecs.h @@ -0,0 +1,822 @@ +/* stringlib: codec implementations */ + +#if !STRINGLIB_IS_UNICODE +# error "codecs.h is specific to Unicode" +#endif + +/* Mask to quickly check whether a C 'long' contains a + non-ASCII, UTF8-encoded char. */ +#if (SIZEOF_LONG == 8) +# define ASCII_CHAR_MASK 0x8080808080808080UL +#elif (SIZEOF_LONG == 4) +# define ASCII_CHAR_MASK 0x80808080UL +#else +# error C 'long' size should be either 4 or 8! +#endif + +/* 10xxxxxx */ +#define IS_CONTINUATION_BYTE(ch) ((ch) >= 0x80 && (ch) < 0xC0) + +Py_LOCAL_INLINE(Py_UCS4) +STRINGLIB(utf8_decode)(const char **inptr, const char *end, + STRINGLIB_CHAR *dest, + Py_ssize_t *outpos) +{ + Py_UCS4 ch; + const char *s = *inptr; + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + STRINGLIB_CHAR *p = dest + *outpos; + + while (s < end) { + ch = (unsigned char)*s; + + if (ch < 0x80) { + /* Fast path for runs of ASCII characters. Given that common UTF-8 + input will consist of an overwhelming majority of ASCII + characters, we try to optimize for this case by checking + as many characters as a C 'long' can contain. + First, check if we can do an aligned read, as most CPUs have + a penalty for unaligned reads. + */ + if (_Py_IS_ALIGNED(s, SIZEOF_LONG)) { + /* Help register allocation */ + const char *_s = s; + STRINGLIB_CHAR *_p = p; + while (_s < aligned_end) { + /* Read a whole long at a time (either 4 or 8 bytes), + and do a fast unrolled copy if it only contains ASCII + characters. */ + unsigned long value = *(const unsigned long *) _s; + if (value & ASCII_CHAR_MASK) + break; +#if PY_LITTLE_ENDIAN + _p[0] = (STRINGLIB_CHAR)(value & 0xFFu); + _p[1] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu); + _p[2] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu); + _p[3] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu); +# if SIZEOF_LONG == 8 + _p[4] = (STRINGLIB_CHAR)((value >> 32) & 0xFFu); + _p[5] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); + _p[6] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); + _p[7] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); +# endif +#else +# if SIZEOF_LONG == 8 + _p[0] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); + _p[1] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); + _p[2] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); + _p[3] = (STRINGLIB_CHAR)((value >> 32) & 0xFFu); + _p[4] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu); + _p[5] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu); + _p[6] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu); + _p[7] = (STRINGLIB_CHAR)(value & 0xFFu); +# else + _p[0] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu); + _p[1] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu); + _p[2] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu); + _p[3] = (STRINGLIB_CHAR)(value & 0xFFu); +# endif +#endif + _s += SIZEOF_LONG; + _p += SIZEOF_LONG; + } + s = _s; + p = _p; + if (s == end) + break; + ch = (unsigned char)*s; + } + if (ch < 0x80) { + s++; + *p++ = ch; + continue; + } + } + + if (ch < 0xE0) { + /* \xC2\x80-\xDF\xBF -- 0080-07FF */ + Py_UCS4 ch2; + if (ch < 0xC2) { + /* invalid sequence + \x80-\xBF -- continuation byte + \xC0-\xC1 -- fake 0000-007F */ + goto InvalidStart; + } + if (end - s < 2) { + /* unexpected end of data: the caller will decide whether + it's an error or not */ + break; + } + ch2 = (unsigned char)s[1]; + if (!IS_CONTINUATION_BYTE(ch2)) + /* invalid continuation byte */ + goto InvalidContinuation1; + ch = (ch << 6) + ch2 - + ((0xC0 << 6) + 0x80); + assert ((ch > 0x007F) && (ch <= 0x07FF)); + s += 2; + if (STRINGLIB_MAX_CHAR <= 0x007F || + (STRINGLIB_MAX_CHAR < 0x07FF && ch > STRINGLIB_MAX_CHAR)) + /* Out-of-range */ + goto Return; + *p++ = ch; + continue; + } + + if (ch < 0xF0) { + /* \xE0\xA0\x80-\xEF\xBF\xBF -- 0800-FFFF */ + Py_UCS4 ch2, ch3; + if (end - s < 3) { + /* unexpected end of data: the caller will decide whether + it's an error or not */ + if (end - s < 2) + break; + ch2 = (unsigned char)s[1]; + if (!IS_CONTINUATION_BYTE(ch2) || + (ch2 < 0xA0 ? ch == 0xE0 : ch == 0xED)) + /* for clarification see comments below */ + goto InvalidContinuation1; + break; + } + ch2 = (unsigned char)s[1]; + ch3 = (unsigned char)s[2]; + if (!IS_CONTINUATION_BYTE(ch2)) { + /* invalid continuation byte */ + goto InvalidContinuation1; + } + if (ch == 0xE0) { + if (ch2 < 0xA0) + /* invalid sequence + \xE0\x80\x80-\xE0\x9F\xBF -- fake 0000-0800 */ + goto InvalidContinuation1; + } else if (ch == 0xED && ch2 >= 0xA0) { + /* Decoding UTF-8 sequences in range \xED\xA0\x80-\xED\xBF\xBF + will result in surrogates in range D800-DFFF. Surrogates are + not valid UTF-8 so they are rejected. + See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */ + goto InvalidContinuation1; + } + if (!IS_CONTINUATION_BYTE(ch3)) { + /* invalid continuation byte */ + goto InvalidContinuation2; + } + ch = (ch << 12) + (ch2 << 6) + ch3 - + ((0xE0 << 12) + (0x80 << 6) + 0x80); + assert ((ch > 0x07FF) && (ch <= 0xFFFF)); + s += 3; + if (STRINGLIB_MAX_CHAR <= 0x07FF || + (STRINGLIB_MAX_CHAR < 0xFFFF && ch > STRINGLIB_MAX_CHAR)) + /* Out-of-range */ + goto Return; + *p++ = ch; + continue; + } + + if (ch < 0xF5) { + /* \xF0\x90\x80\x80-\xF4\x8F\xBF\xBF -- 10000-10FFFF */ + Py_UCS4 ch2, ch3, ch4; + if (end - s < 4) { + /* unexpected end of data: the caller will decide whether + it's an error or not */ + if (end - s < 2) + break; + ch2 = (unsigned char)s[1]; + if (!IS_CONTINUATION_BYTE(ch2) || + (ch2 < 0x90 ? ch == 0xF0 : ch == 0xF4)) + /* for clarification see comments below */ + goto InvalidContinuation1; + if (end - s < 3) + break; + ch3 = (unsigned char)s[2]; + if (!IS_CONTINUATION_BYTE(ch3)) + goto InvalidContinuation2; + break; + } + ch2 = (unsigned char)s[1]; + ch3 = (unsigned char)s[2]; + ch4 = (unsigned char)s[3]; + if (!IS_CONTINUATION_BYTE(ch2)) { + /* invalid continuation byte */ + goto InvalidContinuation1; + } + if (ch == 0xF0) { + if (ch2 < 0x90) + /* invalid sequence + \xF0\x80\x80\x80-\xF0\x8F\xBF\xBF -- fake 0000-FFFF */ + goto InvalidContinuation1; + } else if (ch == 0xF4 && ch2 >= 0x90) { + /* invalid sequence + \xF4\x90\x80\x80- -- 110000- overflow */ + goto InvalidContinuation1; + } + if (!IS_CONTINUATION_BYTE(ch3)) { + /* invalid continuation byte */ + goto InvalidContinuation2; + } + if (!IS_CONTINUATION_BYTE(ch4)) { + /* invalid continuation byte */ + goto InvalidContinuation3; + } + ch = (ch << 18) + (ch2 << 12) + (ch3 << 6) + ch4 - + ((0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80); + assert ((ch > 0xFFFF) && (ch <= 0x10FFFF)); + s += 4; + if (STRINGLIB_MAX_CHAR <= 0xFFFF || + (STRINGLIB_MAX_CHAR < 0x10FFFF && ch > STRINGLIB_MAX_CHAR)) + /* Out-of-range */ + goto Return; + *p++ = ch; + continue; + } + goto InvalidStart; + } + ch = 0; +Return: + *inptr = s; + *outpos = p - dest; + return ch; +InvalidStart: + ch = 1; + goto Return; +InvalidContinuation1: + ch = 2; + goto Return; +InvalidContinuation2: + ch = 3; + goto Return; +InvalidContinuation3: + ch = 4; + goto Return; +} + +#undef ASCII_CHAR_MASK + + +/* UTF-8 encoder specialized for a Unicode kind to avoid the slow + PyUnicode_READ() macro. Delete some parts of the code depending on the kind: + UCS-1 strings don't need to handle surrogates for example. */ +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(utf8_encoder)(PyObject *unicode, + STRINGLIB_CHAR *data, + Py_ssize_t size, + _Py_error_handler error_handler, + const char *errors) +{ + Py_ssize_t i; /* index into data of next input character */ + char *p; /* next free byte in output buffer */ +#if STRINGLIB_SIZEOF_CHAR > 1 + PyObject *error_handler_obj = NULL; + PyObject *exc = NULL; + PyObject *rep = NULL; +#endif +#if STRINGLIB_SIZEOF_CHAR == 1 + const Py_ssize_t max_char_size = 2; +#elif STRINGLIB_SIZEOF_CHAR == 2 + const Py_ssize_t max_char_size = 3; +#else /* STRINGLIB_SIZEOF_CHAR == 4 */ + const Py_ssize_t max_char_size = 4; +#endif + _PyBytesWriter writer; + + assert(size >= 0); + _PyBytesWriter_Init(&writer); + + if (size > PY_SSIZE_T_MAX / max_char_size) { + /* integer overflow */ + return PyErr_NoMemory(); + } + + p = _PyBytesWriter_Alloc(&writer, size * max_char_size); + if (p == NULL) + return NULL; + + for (i = 0; i < size;) { + Py_UCS4 ch = data[i++]; + + if (ch < 0x80) { + /* Encode ASCII */ + *p++ = (char) ch; + + } + else +#if STRINGLIB_SIZEOF_CHAR > 1 + if (ch < 0x0800) +#endif + { + /* Encode Latin-1 */ + *p++ = (char)(0xc0 | (ch >> 6)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } +#if STRINGLIB_SIZEOF_CHAR > 1 + else if (Py_UNICODE_IS_SURROGATE(ch)) { + Py_ssize_t startpos, endpos, newpos; + Py_ssize_t k; + if (error_handler == _Py_ERROR_UNKNOWN) { + error_handler = _Py_GetErrorHandler(errors); + } + + startpos = i-1; + endpos = startpos+1; + + while ((endpos < size) && Py_UNICODE_IS_SURROGATE(data[endpos])) + endpos++; + + /* Only overallocate the buffer if it's not the last write */ + writer.overallocate = (endpos < size); + + switch (error_handler) + { + case _Py_ERROR_REPLACE: + memset(p, '?', endpos - startpos); + p += (endpos - startpos); + /* fall through */ + case _Py_ERROR_IGNORE: + i += (endpos - startpos - 1); + break; + + case _Py_ERROR_SURROGATEPASS: + for (k=startpos; k> 12)); + *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } + i += (endpos - startpos - 1); + break; + + case _Py_ERROR_BACKSLASHREPLACE: + /* subtract preallocated bytes */ + writer.min_size -= max_char_size * (endpos - startpos); + p = backslashreplace(&writer, p, + unicode, startpos, endpos); + if (p == NULL) + goto error; + i += (endpos - startpos - 1); + break; + + case _Py_ERROR_XMLCHARREFREPLACE: + /* subtract preallocated bytes */ + writer.min_size -= max_char_size * (endpos - startpos); + p = xmlcharrefreplace(&writer, p, + unicode, startpos, endpos); + if (p == NULL) + goto error; + i += (endpos - startpos - 1); + break; + + case _Py_ERROR_SURROGATEESCAPE: + for (k=startpos; k= endpos) { + i += (endpos - startpos - 1); + break; + } + startpos = k; + assert(startpos < endpos); + /* fall through */ + default: + rep = unicode_encode_call_errorhandler( + errors, &error_handler_obj, "utf-8", "surrogates not allowed", + unicode, &exc, startpos, endpos, &newpos); + if (!rep) + goto error; + + /* subtract preallocated bytes */ + writer.min_size -= max_char_size * (newpos - startpos); + + if (PyBytes_Check(rep)) { + p = _PyBytesWriter_WriteBytes(&writer, p, + PyBytes_AS_STRING(rep), + PyBytes_GET_SIZE(rep)); + } + else { + /* rep is unicode */ + if (PyUnicode_READY(rep) < 0) + goto error; + + if (!PyUnicode_IS_ASCII(rep)) { + raise_encode_exception(&exc, "utf-8", unicode, + startpos, endpos, + "surrogates not allowed"); + goto error; + } + + p = _PyBytesWriter_WriteBytes(&writer, p, + PyUnicode_DATA(rep), + PyUnicode_GET_LENGTH(rep)); + } + + if (p == NULL) + goto error; + Py_CLEAR(rep); + + i = newpos; + } + + /* If overallocation was disabled, ensure that it was the last + write. Otherwise, we missed an optimization */ + assert(writer.overallocate || i == size); + } + else +#if STRINGLIB_SIZEOF_CHAR > 2 + if (ch < 0x10000) +#endif + { + *p++ = (char)(0xe0 | (ch >> 12)); + *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } +#if STRINGLIB_SIZEOF_CHAR > 2 + else /* ch >= 0x10000 */ + { + assert(ch <= MAX_UNICODE); + /* Encode UCS4 Unicode ordinals */ + *p++ = (char)(0xf0 | (ch >> 18)); + *p++ = (char)(0x80 | ((ch >> 12) & 0x3f)); + *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } +#endif /* STRINGLIB_SIZEOF_CHAR > 2 */ +#endif /* STRINGLIB_SIZEOF_CHAR > 1 */ + } + +#if STRINGLIB_SIZEOF_CHAR > 1 + Py_XDECREF(error_handler_obj); + Py_XDECREF(exc); +#endif + return _PyBytesWriter_Finish(&writer, p); + +#if STRINGLIB_SIZEOF_CHAR > 1 + error: + Py_XDECREF(rep); + Py_XDECREF(error_handler_obj); + Py_XDECREF(exc); + _PyBytesWriter_Dealloc(&writer); + return NULL; +#endif +} + +/* The pattern for constructing UCS2-repeated masks. */ +#if SIZEOF_LONG == 8 +# define UCS2_REPEAT_MASK 0x0001000100010001ul +#elif SIZEOF_LONG == 4 +# define UCS2_REPEAT_MASK 0x00010001ul +#else +# error C 'long' size should be either 4 or 8! +#endif + +/* The mask for fast checking. */ +#if STRINGLIB_SIZEOF_CHAR == 1 +/* The mask for fast checking of whether a C 'long' contains a + non-ASCII or non-Latin1 UTF16-encoded characters. */ +# define FAST_CHAR_MASK (UCS2_REPEAT_MASK * (0xFFFFu & ~STRINGLIB_MAX_CHAR)) +#else +/* The mask for fast checking of whether a C 'long' may contain + UTF16-encoded surrogate characters. This is an efficient heuristic, + assuming that non-surrogate characters with a code point >= 0x8000 are + rare in most input. +*/ +# define FAST_CHAR_MASK (UCS2_REPEAT_MASK * 0x8000u) +#endif +/* The mask for fast byte-swapping. */ +#define STRIPPED_MASK (UCS2_REPEAT_MASK * 0x00FFu) +/* Swap bytes. */ +#define SWAB(value) ((((value) >> 8) & STRIPPED_MASK) | \ + (((value) & STRIPPED_MASK) << 8)) + +Py_LOCAL_INLINE(Py_UCS4) +STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, + STRINGLIB_CHAR *dest, Py_ssize_t *outpos, + int native_ordering) +{ + Py_UCS4 ch; + const unsigned char *aligned_end = + (const unsigned char *) _Py_ALIGN_DOWN(e, SIZEOF_LONG); + const unsigned char *q = *inptr; + STRINGLIB_CHAR *p = dest + *outpos; + /* Offsets from q for retrieving byte pairs in the right order. */ +#if PY_LITTLE_ENDIAN + int ihi = !!native_ordering, ilo = !native_ordering; +#else + int ihi = !native_ordering, ilo = !!native_ordering; +#endif + --e; + + while (q < e) { + Py_UCS4 ch2; + /* First check for possible aligned read of a C 'long'. Unaligned + reads are more expensive, better to defer to another iteration. */ + if (_Py_IS_ALIGNED(q, SIZEOF_LONG)) { + /* Fast path for runs of in-range non-surrogate chars. */ + const unsigned char *_q = q; + while (_q < aligned_end) { + unsigned long block = * (const unsigned long *) _q; + if (native_ordering) { + /* Can use buffer directly */ + if (block & FAST_CHAR_MASK) + break; + } + else { + /* Need to byte-swap */ + if (block & SWAB(FAST_CHAR_MASK)) + break; +#if STRINGLIB_SIZEOF_CHAR == 1 + block >>= 8; +#else + block = SWAB(block); +#endif + } +#if PY_LITTLE_ENDIAN +# if SIZEOF_LONG == 4 + p[0] = (STRINGLIB_CHAR)(block & 0xFFFFu); + p[1] = (STRINGLIB_CHAR)(block >> 16); +# elif SIZEOF_LONG == 8 + p[0] = (STRINGLIB_CHAR)(block & 0xFFFFu); + p[1] = (STRINGLIB_CHAR)((block >> 16) & 0xFFFFu); + p[2] = (STRINGLIB_CHAR)((block >> 32) & 0xFFFFu); + p[3] = (STRINGLIB_CHAR)(block >> 48); +# endif +#else +# if SIZEOF_LONG == 4 + p[0] = (STRINGLIB_CHAR)(block >> 16); + p[1] = (STRINGLIB_CHAR)(block & 0xFFFFu); +# elif SIZEOF_LONG == 8 + p[0] = (STRINGLIB_CHAR)(block >> 48); + p[1] = (STRINGLIB_CHAR)((block >> 32) & 0xFFFFu); + p[2] = (STRINGLIB_CHAR)((block >> 16) & 0xFFFFu); + p[3] = (STRINGLIB_CHAR)(block & 0xFFFFu); +# endif +#endif + _q += SIZEOF_LONG; + p += SIZEOF_LONG / 2; + } + q = _q; + if (q >= e) + break; + } + + ch = (q[ihi] << 8) | q[ilo]; + q += 2; + if (!Py_UNICODE_IS_SURROGATE(ch)) { +#if STRINGLIB_SIZEOF_CHAR < 2 + if (ch > STRINGLIB_MAX_CHAR) + /* Out-of-range */ + goto Return; +#endif + *p++ = (STRINGLIB_CHAR)ch; + continue; + } + + /* UTF-16 code pair: */ + if (!Py_UNICODE_IS_HIGH_SURROGATE(ch)) + goto IllegalEncoding; + if (q >= e) + goto UnexpectedEnd; + ch2 = (q[ihi] << 8) | q[ilo]; + q += 2; + if (!Py_UNICODE_IS_LOW_SURROGATE(ch2)) + goto IllegalSurrogate; + ch = Py_UNICODE_JOIN_SURROGATES(ch, ch2); +#if STRINGLIB_SIZEOF_CHAR < 4 + /* Out-of-range */ + goto Return; +#else + *p++ = (STRINGLIB_CHAR)ch; +#endif + } + ch = 0; +Return: + *inptr = q; + *outpos = p - dest; + return ch; +UnexpectedEnd: + ch = 1; + goto Return; +IllegalEncoding: + ch = 2; + goto Return; +IllegalSurrogate: + ch = 3; + goto Return; +} +#undef UCS2_REPEAT_MASK +#undef FAST_CHAR_MASK +#undef STRIPPED_MASK +#undef SWAB + + +#if STRINGLIB_MAX_CHAR >= 0x80 +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(utf16_encode)(const STRINGLIB_CHAR *in, + Py_ssize_t len, + unsigned short **outptr, + int native_ordering) +{ + unsigned short *out = *outptr; + const STRINGLIB_CHAR *end = in + len; +#if STRINGLIB_SIZEOF_CHAR == 1 + if (native_ordering) { + const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4); + while (in < unrolled_end) { + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + in += 4; out += 4; + } + while (in < end) { + *out++ = *in++; + } + } else { +# define SWAB2(CH) ((CH) << 8) /* high byte is zero */ + const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4); + while (in < unrolled_end) { + out[0] = SWAB2(in[0]); + out[1] = SWAB2(in[1]); + out[2] = SWAB2(in[2]); + out[3] = SWAB2(in[3]); + in += 4; out += 4; + } + while (in < end) { + Py_UCS4 ch = *in++; + *out++ = SWAB2((Py_UCS2)ch); + } +#undef SWAB2 + } + *outptr = out; + return len; +#else + if (native_ordering) { +#if STRINGLIB_MAX_CHAR < 0x10000 + const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4); + while (in < unrolled_end) { + /* check if any character is a surrogate character */ + if (((in[0] ^ 0xd800) & + (in[1] ^ 0xd800) & + (in[2] ^ 0xd800) & + (in[3] ^ 0xd800) & 0xf800) == 0) + break; + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + in += 4; out += 4; + } +#endif + while (in < end) { + Py_UCS4 ch; + ch = *in++; + if (ch < 0xd800) + *out++ = ch; + else if (ch < 0xe000) + /* reject surrogate characters (U+D800-U+DFFF) */ + goto fail; +#if STRINGLIB_MAX_CHAR >= 0x10000 + else if (ch >= 0x10000) { + out[0] = Py_UNICODE_HIGH_SURROGATE(ch); + out[1] = Py_UNICODE_LOW_SURROGATE(ch); + out += 2; + } +#endif + else + *out++ = ch; + } + } else { +#define SWAB2(CH) (((CH) << 8) | ((CH) >> 8)) +#if STRINGLIB_MAX_CHAR < 0x10000 + const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4); + while (in < unrolled_end) { + /* check if any character is a surrogate character */ + if (((in[0] ^ 0xd800) & + (in[1] ^ 0xd800) & + (in[2] ^ 0xd800) & + (in[3] ^ 0xd800) & 0xf800) == 0) + break; + out[0] = SWAB2(in[0]); + out[1] = SWAB2(in[1]); + out[2] = SWAB2(in[2]); + out[3] = SWAB2(in[3]); + in += 4; out += 4; + } +#endif + while (in < end) { + Py_UCS4 ch = *in++; + if (ch < 0xd800) + *out++ = SWAB2((Py_UCS2)ch); + else if (ch < 0xe000) + /* reject surrogate characters (U+D800-U+DFFF) */ + goto fail; +#if STRINGLIB_MAX_CHAR >= 0x10000 + else if (ch >= 0x10000) { + Py_UCS2 ch1 = Py_UNICODE_HIGH_SURROGATE(ch); + Py_UCS2 ch2 = Py_UNICODE_LOW_SURROGATE(ch); + out[0] = SWAB2(ch1); + out[1] = SWAB2(ch2); + out += 2; + } +#endif + else + *out++ = SWAB2((Py_UCS2)ch); + } +#undef SWAB2 + } + *outptr = out; + return len; + fail: + *outptr = out; + return len - (end - in + 1); +#endif +} + +#if STRINGLIB_SIZEOF_CHAR == 1 +# define SWAB4(CH, tmp) ((CH) << 24) /* high bytes are zero */ +#elif STRINGLIB_SIZEOF_CHAR == 2 +# define SWAB4(CH, tmp) (tmp = (CH), \ + ((tmp & 0x00FFu) << 24) + ((tmp & 0xFF00u) << 8)) + /* high bytes are zero */ +#else +# define SWAB4(CH, tmp) (tmp = (CH), \ + tmp = ((tmp & 0x00FF00FFu) << 8) + ((tmp >> 8) & 0x00FF00FFu), \ + ((tmp & 0x0000FFFFu) << 16) + ((tmp >> 16) & 0x0000FFFFu)) +#endif +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(utf32_encode)(const STRINGLIB_CHAR *in, + Py_ssize_t len, + PY_UINT32_T **outptr, + int native_ordering) +{ + PY_UINT32_T *out = *outptr; + const STRINGLIB_CHAR *end = in + len; + if (native_ordering) { + const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4); + while (in < unrolled_end) { +#if STRINGLIB_SIZEOF_CHAR > 1 + /* check if any character is a surrogate character */ + if (((in[0] ^ 0xd800) & + (in[1] ^ 0xd800) & + (in[2] ^ 0xd800) & + (in[3] ^ 0xd800) & 0xf800) == 0) + break; +#endif + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + in += 4; out += 4; + } + while (in < end) { + Py_UCS4 ch; + ch = *in++; +#if STRINGLIB_SIZEOF_CHAR > 1 + if (Py_UNICODE_IS_SURROGATE(ch)) { + /* reject surrogate characters (U+D800-U+DFFF) */ + goto fail; + } +#endif + *out++ = ch; + } + } else { + const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4); + while (in < unrolled_end) { +#if STRINGLIB_SIZEOF_CHAR > 1 + Py_UCS4 ch1, ch2, ch3, ch4; + /* check if any character is a surrogate character */ + if (((in[0] ^ 0xd800) & + (in[1] ^ 0xd800) & + (in[2] ^ 0xd800) & + (in[3] ^ 0xd800) & 0xf800) == 0) + break; +#endif + out[0] = SWAB4(in[0], ch1); + out[1] = SWAB4(in[1], ch2); + out[2] = SWAB4(in[2], ch3); + out[3] = SWAB4(in[3], ch4); + in += 4; out += 4; + } + while (in < end) { + Py_UCS4 ch = *in++; +#if STRINGLIB_SIZEOF_CHAR > 1 + if (Py_UNICODE_IS_SURROGATE(ch)) { + /* reject surrogate characters (U+D800-U+DFFF) */ + goto fail; + } +#endif + *out++ = SWAB4(ch, ch); + } + } + *outptr = out; + return len; +#if STRINGLIB_SIZEOF_CHAR > 1 + fail: + *outptr = out; + return len - (end - in + 1); +#endif +} +#undef SWAB4 + +#endif diff --git a/python/Objects/stringlib/count.h b/python/Objects/stringlib/count.h new file mode 100755 index 0000000..f48500b --- /dev/null +++ b/python/Objects/stringlib/count.h @@ -0,0 +1,27 @@ +/* stringlib: count implementation */ + +#ifndef STRINGLIB_FASTSEARCH_H +#error must include "stringlib/fastsearch.h" before including this module +#endif + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(count)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, + Py_ssize_t maxcount) +{ + Py_ssize_t count; + + if (str_len < 0) + return 0; /* start > len(str) */ + if (sub_len == 0) + return (str_len < maxcount) ? str_len + 1 : maxcount; + + count = FASTSEARCH(str, str_len, sub, sub_len, maxcount, FAST_COUNT); + + if (count < 0) + return 0; /* no match */ + + return count; +} + + diff --git a/python/Objects/stringlib/ctype.h b/python/Objects/stringlib/ctype.h new file mode 100755 index 0000000..843cfa2 --- /dev/null +++ b/python/Objects/stringlib/ctype.h @@ -0,0 +1,116 @@ +#if STRINGLIB_IS_UNICODE +# error "ctype.h only compatible with byte-wise strings" +#endif + +#include "bytes_methods.h" + +static PyObject* +stringlib_isspace(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_isspace(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +static PyObject* +stringlib_isalpha(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_isalpha(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +static PyObject* +stringlib_isalnum(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_isalnum(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +static PyObject* +stringlib_isascii(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_isascii(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +static PyObject* +stringlib_isdigit(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_isdigit(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +static PyObject* +stringlib_islower(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_islower(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +static PyObject* +stringlib_isupper(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_isupper(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +static PyObject* +stringlib_istitle(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _Py_bytes_istitle(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + + +/* functions that return a new object partially translated by ctype funcs: */ + +static PyObject* +stringlib_lower(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject* newobj; + newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); + if (!newobj) + return NULL; + _Py_bytes_lower(STRINGLIB_STR(newobj), STRINGLIB_STR(self), + STRINGLIB_LEN(self)); + return newobj; +} + +static PyObject* +stringlib_upper(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject* newobj; + newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); + if (!newobj) + return NULL; + _Py_bytes_upper(STRINGLIB_STR(newobj), STRINGLIB_STR(self), + STRINGLIB_LEN(self)); + return newobj; +} + +static PyObject* +stringlib_title(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject* newobj; + newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); + if (!newobj) + return NULL; + _Py_bytes_title(STRINGLIB_STR(newobj), STRINGLIB_STR(self), + STRINGLIB_LEN(self)); + return newobj; +} + +static PyObject* +stringlib_capitalize(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject* newobj; + newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); + if (!newobj) + return NULL; + _Py_bytes_capitalize(STRINGLIB_STR(newobj), STRINGLIB_STR(self), + STRINGLIB_LEN(self)); + return newobj; +} + +static PyObject* +stringlib_swapcase(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject* newobj; + newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self)); + if (!newobj) + return NULL; + _Py_bytes_swapcase(STRINGLIB_STR(newobj), STRINGLIB_STR(self), + STRINGLIB_LEN(self)); + return newobj; +} diff --git a/python/Objects/stringlib/eq.h b/python/Objects/stringlib/eq.h new file mode 100755 index 0000000..ff22f91 --- /dev/null +++ b/python/Objects/stringlib/eq.h @@ -0,0 +1,24 @@ +/* Fast unicode equal function optimized for dictobject.c and setobject.c */ + +/* Return 1 if two unicode objects are equal, 0 if not. + * unicode_eq() is called when the hash of two unicode objects is equal. + */ +Py_LOCAL_INLINE(int) +unicode_eq(PyObject *aa, PyObject *bb) +{ + PyUnicodeObject *a = (PyUnicodeObject *)aa; + PyUnicodeObject *b = (PyUnicodeObject *)bb; + + if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) { + Py_UNREACHABLE(); + } + + if (PyUnicode_GET_LENGTH(a) != PyUnicode_GET_LENGTH(b)) + return 0; + if (PyUnicode_GET_LENGTH(a) == 0) + return 1; + if (PyUnicode_KIND(a) != PyUnicode_KIND(b)) + return 0; + return memcmp(PyUnicode_1BYTE_DATA(a), PyUnicode_1BYTE_DATA(b), + PyUnicode_GET_LENGTH(a) * PyUnicode_KIND(a)) == 0; +} diff --git a/python/Objects/stringlib/fastsearch.h b/python/Objects/stringlib/fastsearch.h new file mode 100755 index 0000000..56a4467 --- /dev/null +++ b/python/Objects/stringlib/fastsearch.h @@ -0,0 +1,283 @@ +/* stringlib: fastsearch implementation */ + +#define STRINGLIB_FASTSEARCH_H + +/* fast search/count implementation, based on a mix between boyer- + moore and horspool, with a few more bells and whistles on the top. + for some more background, see: http://effbot.org/zone/stringlib.htm */ + +/* note: fastsearch may access s[n], which isn't a problem when using + Python's ordinary string types, but may cause problems if you're + using this code in other contexts. also, the count mode returns -1 + if there cannot possible be a match in the target string, and 0 if + it has actually checked for matches, but didn't find any. callers + beware! */ + +#define FAST_COUNT 0 +#define FAST_SEARCH 1 +#define FAST_RSEARCH 2 + +#if LONG_BIT >= 128 +#define STRINGLIB_BLOOM_WIDTH 128 +#elif LONG_BIT >= 64 +#define STRINGLIB_BLOOM_WIDTH 64 +#elif LONG_BIT >= 32 +#define STRINGLIB_BLOOM_WIDTH 32 +#else +#error "LONG_BIT is smaller than 32" +#endif + +#define STRINGLIB_BLOOM_ADD(mask, ch) \ + ((mask |= (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) +#define STRINGLIB_BLOOM(mask, ch) \ + ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) + +#if STRINGLIB_SIZEOF_CHAR == 1 +# define MEMCHR_CUT_OFF 15 +#else +# define MEMCHR_CUT_OFF 40 +#endif + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) +{ + const STRINGLIB_CHAR *p, *e; + + p = s; + e = s + n; + if (n > MEMCHR_CUT_OFF) { +#if STRINGLIB_SIZEOF_CHAR == 1 + p = memchr(s, ch, n); + if (p != NULL) + return (p - s); + return -1; +#else + /* use memchr if we can choose a needle without too many likely + false positives */ + const STRINGLIB_CHAR *s1, *e1; + unsigned char needle = ch & 0xff; + /* If looking for a multiple of 256, we'd have too + many false positives looking for the '\0' byte in UCS2 + and UCS4 representations. */ + if (needle != 0) { + do { + void *candidate = memchr(p, needle, + (e - p) * sizeof(STRINGLIB_CHAR)); + if (candidate == NULL) + return -1; + s1 = p; + p = (const STRINGLIB_CHAR *) + _Py_ALIGN_DOWN(candidate, sizeof(STRINGLIB_CHAR)); + if (*p == ch) + return (p - s); + /* False positive */ + p++; + if (p - s1 > MEMCHR_CUT_OFF) + continue; + if (e - p <= MEMCHR_CUT_OFF) + break; + e1 = p + MEMCHR_CUT_OFF; + while (p != e1) { + if (*p == ch) + return (p - s); + p++; + } + } + while (e - p > MEMCHR_CUT_OFF); + } +#endif + } + while (p < e) { + if (*p == ch) + return (p - s); + p++; + } + return -1; +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) +{ + const STRINGLIB_CHAR *p; +#ifdef HAVE_MEMRCHR + /* memrchr() is a GNU extension, available since glibc 2.1.91. + it doesn't seem as optimized as memchr(), but is still quite + faster than our hand-written loop below */ + + if (n > MEMCHR_CUT_OFF) { +#if STRINGLIB_SIZEOF_CHAR == 1 + p = memrchr(s, ch, n); + if (p != NULL) + return (p - s); + return -1; +#else + /* use memrchr if we can choose a needle without too many likely + false positives */ + const STRINGLIB_CHAR *s1; + Py_ssize_t n1; + unsigned char needle = ch & 0xff; + /* If looking for a multiple of 256, we'd have too + many false positives looking for the '\0' byte in UCS2 + and UCS4 representations. */ + if (needle != 0) { + do { + void *candidate = memrchr(s, needle, + n * sizeof(STRINGLIB_CHAR)); + if (candidate == NULL) + return -1; + n1 = n; + p = (const STRINGLIB_CHAR *) + _Py_ALIGN_DOWN(candidate, sizeof(STRINGLIB_CHAR)); + n = p - s; + if (*p == ch) + return n; + /* False positive */ + if (n1 - n > MEMCHR_CUT_OFF) + continue; + if (n <= MEMCHR_CUT_OFF) + break; + s1 = p - MEMCHR_CUT_OFF; + while (p > s1) { + p--; + if (*p == ch) + return (p - s); + } + n = p - s; + } + while (n > MEMCHR_CUT_OFF); + } +#endif + } +#endif /* HAVE_MEMRCHR */ + p = s + n; + while (p > s) { + p--; + if (*p == ch) + return (p - s); + } + return -1; +} + +#undef MEMCHR_CUT_OFF + +Py_LOCAL_INLINE(Py_ssize_t) +FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n, + const STRINGLIB_CHAR* p, Py_ssize_t m, + Py_ssize_t maxcount, int mode) +{ + unsigned long mask; + Py_ssize_t skip, count = 0; + Py_ssize_t i, j, mlast, w; + + w = n - m; + + if (w < 0 || (mode == FAST_COUNT && maxcount == 0)) + return -1; + + /* look for special cases */ + if (m <= 1) { + if (m <= 0) + return -1; + /* use special case for 1-character strings */ + if (mode == FAST_SEARCH) + return STRINGLIB(find_char)(s, n, p[0]); + else if (mode == FAST_RSEARCH) + return STRINGLIB(rfind_char)(s, n, p[0]); + else { /* FAST_COUNT */ + for (i = 0; i < n; i++) + if (s[i] == p[0]) { + count++; + if (count == maxcount) + return maxcount; + } + return count; + } + } + + mlast = m - 1; + skip = mlast - 1; + mask = 0; + + if (mode != FAST_RSEARCH) { + const STRINGLIB_CHAR *ss = s + m - 1; + const STRINGLIB_CHAR *pp = p + m - 1; + + /* create compressed boyer-moore delta 1 table */ + + /* process pattern[:-1] */ + for (i = 0; i < mlast; i++) { + STRINGLIB_BLOOM_ADD(mask, p[i]); + if (p[i] == p[mlast]) + skip = mlast - i - 1; + } + /* process pattern[-1] outside the loop */ + STRINGLIB_BLOOM_ADD(mask, p[mlast]); + + for (i = 0; i <= w; i++) { + /* note: using mlast in the skip path slows things down on x86 */ + if (ss[i] == pp[0]) { + /* candidate match */ + for (j = 0; j < mlast; j++) + if (s[i+j] != p[j]) + break; + if (j == mlast) { + /* got a match! */ + if (mode != FAST_COUNT) + return i; + count++; + if (count == maxcount) + return maxcount; + i = i + mlast; + continue; + } + /* miss: check if next character is part of pattern */ + if (!STRINGLIB_BLOOM(mask, ss[i+1])) + i = i + m; + else + i = i + skip; + } else { + /* skip: check if next character is part of pattern */ + if (!STRINGLIB_BLOOM(mask, ss[i+1])) + i = i + m; + } + } + } else { /* FAST_RSEARCH */ + + /* create compressed boyer-moore delta 1 table */ + + /* process pattern[0] outside the loop */ + STRINGLIB_BLOOM_ADD(mask, p[0]); + /* process pattern[:0:-1] */ + for (i = mlast; i > 0; i--) { + STRINGLIB_BLOOM_ADD(mask, p[i]); + if (p[i] == p[0]) + skip = i - 1; + } + + for (i = w; i >= 0; i--) { + if (s[i] == p[0]) { + /* candidate match */ + for (j = mlast; j > 0; j--) + if (s[i+j] != p[j]) + break; + if (j == 0) + /* got a match! */ + return i; + /* miss: check if previous character is part of pattern */ + if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1])) + i = i - m; + else + i = i - skip; + } else { + /* skip: check if previous character is part of pattern */ + if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1])) + i = i - m; + } + } + } + + if (mode != FAST_COUNT) + return -1; + return count; +} + diff --git a/python/Objects/stringlib/find.h b/python/Objects/stringlib/find.h new file mode 100755 index 0000000..509b929 --- /dev/null +++ b/python/Objects/stringlib/find.h @@ -0,0 +1,119 @@ +/* stringlib: find/index implementation */ + +#ifndef STRINGLIB_FASTSEARCH_H +#error must include "stringlib/fastsearch.h" before including this module +#endif + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(find)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, + Py_ssize_t offset) +{ + Py_ssize_t pos; + + assert(str_len >= 0); + if (sub_len == 0) + return offset; + + pos = FASTSEARCH(str, str_len, sub, sub_len, -1, FAST_SEARCH); + + if (pos >= 0) + pos += offset; + + return pos; +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(rfind)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, + Py_ssize_t offset) +{ + Py_ssize_t pos; + + assert(str_len >= 0); + if (sub_len == 0) + return str_len + offset; + + pos = FASTSEARCH(str, str_len, sub, sub_len, -1, FAST_RSEARCH); + + if (pos >= 0) + pos += offset; + + return pos; +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(find_slice)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, + Py_ssize_t start, Py_ssize_t end) +{ + return STRINGLIB(find)(str + start, end - start, sub, sub_len, start); +} + +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(rfind_slice)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, + Py_ssize_t start, Py_ssize_t end) +{ + return STRINGLIB(rfind)(str + start, end - start, sub, sub_len, start); +} + +#ifdef STRINGLIB_WANT_CONTAINS_OBJ + +Py_LOCAL_INLINE(int) +STRINGLIB(contains_obj)(PyObject* str, PyObject* sub) +{ + return STRINGLIB(find)( + STRINGLIB_STR(str), STRINGLIB_LEN(str), + STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0 + ) != -1; +} + +#endif /* STRINGLIB_WANT_CONTAINS_OBJ */ + +/* +This function is a helper for the "find" family (find, rfind, index, +rindex) and for count, startswith and endswith, because they all have +the same behaviour for the arguments. + +It does not touch the variables received until it knows everything +is ok. +*/ + +#define FORMAT_BUFFER_SIZE 50 + +Py_LOCAL_INLINE(int) +STRINGLIB(parse_args_finds)(const char * function_name, PyObject *args, + PyObject **subobj, + Py_ssize_t *start, Py_ssize_t *end) +{ + PyObject *tmp_subobj; + Py_ssize_t tmp_start = 0; + Py_ssize_t tmp_end = PY_SSIZE_T_MAX; + PyObject *obj_start=Py_None, *obj_end=Py_None; + char format[FORMAT_BUFFER_SIZE] = "O|OO:"; + size_t len = strlen(format); + + strncpy(format + len, function_name, FORMAT_BUFFER_SIZE - len - 1); + format[FORMAT_BUFFER_SIZE - 1] = '\0'; + + if (!PyArg_ParseTuple(args, format, &tmp_subobj, &obj_start, &obj_end)) + return 0; + + /* To support None in "start" and "end" arguments, meaning + the same as if they were not passed. + */ + if (obj_start != Py_None) + if (!_PyEval_SliceIndex(obj_start, &tmp_start)) + return 0; + if (obj_end != Py_None) + if (!_PyEval_SliceIndex(obj_end, &tmp_end)) + return 0; + + *start = tmp_start; + *end = tmp_end; + *subobj = tmp_subobj; + return 1; +} + +#undef FORMAT_BUFFER_SIZE diff --git a/python/Objects/stringlib/find_max_char.h b/python/Objects/stringlib/find_max_char.h new file mode 100755 index 0000000..f4e0a77 --- /dev/null +++ b/python/Objects/stringlib/find_max_char.h @@ -0,0 +1,134 @@ +/* Finding the optimal width of unicode characters in a buffer */ + +#if !STRINGLIB_IS_UNICODE +# error "find_max_char.h is specific to Unicode" +#endif + +/* Mask to quickly check whether a C 'long' contains a + non-ASCII, UTF8-encoded char. */ +#if (SIZEOF_LONG == 8) +# define UCS1_ASCII_CHAR_MASK 0x8080808080808080UL +#elif (SIZEOF_LONG == 4) +# define UCS1_ASCII_CHAR_MASK 0x80808080UL +#else +# error C 'long' size should be either 4 or 8! +#endif + +#if STRINGLIB_SIZEOF_CHAR == 1 + +Py_LOCAL_INLINE(Py_UCS4) +STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) +{ + const unsigned char *p = (const unsigned char *) begin; + const unsigned char *aligned_end = + (const unsigned char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + + while (p < end) { + if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + /* Help register allocation */ + const unsigned char *_p = p; + while (_p < aligned_end) { + unsigned long value = *(const unsigned long *) _p; + if (value & UCS1_ASCII_CHAR_MASK) + return 255; + _p += SIZEOF_LONG; + } + p = _p; + if (p == end) + break; + } + if (*p++ & 0x80) + return 255; + } + return 127; +} + +#undef ASCII_CHAR_MASK + +#else /* STRINGLIB_SIZEOF_CHAR == 1 */ + +#define MASK_ASCII 0xFFFFFF80 +#define MASK_UCS1 0xFFFFFF00 +#define MASK_UCS2 0xFFFF0000 + +#define MAX_CHAR_ASCII 0x7f +#define MAX_CHAR_UCS1 0xff +#define MAX_CHAR_UCS2 0xffff +#define MAX_CHAR_UCS4 0x10ffff + +Py_LOCAL_INLINE(Py_UCS4) +STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) +{ +#if STRINGLIB_SIZEOF_CHAR == 2 + const Py_UCS4 mask_limit = MASK_UCS1; + const Py_UCS4 max_char_limit = MAX_CHAR_UCS2; +#elif STRINGLIB_SIZEOF_CHAR == 4 + const Py_UCS4 mask_limit = MASK_UCS2; + const Py_UCS4 max_char_limit = MAX_CHAR_UCS4; +#else +#error Invalid STRINGLIB_SIZEOF_CHAR (must be 1, 2 or 4) +#endif + Py_UCS4 mask; + Py_ssize_t n = end - begin; + const STRINGLIB_CHAR *p = begin; + const STRINGLIB_CHAR *unrolled_end = begin + _Py_SIZE_ROUND_DOWN(n, 4); + Py_UCS4 max_char; + + max_char = MAX_CHAR_ASCII; + mask = MASK_ASCII; + while (p < unrolled_end) { + STRINGLIB_CHAR bits = p[0] | p[1] | p[2] | p[3]; + if (bits & mask) { + if (mask == mask_limit) { + /* Limit reached */ + return max_char_limit; + } + if (mask == MASK_ASCII) { + max_char = MAX_CHAR_UCS1; + mask = MASK_UCS1; + } + else { + /* mask can't be MASK_UCS2 because of mask_limit above */ + assert(mask == MASK_UCS1); + max_char = MAX_CHAR_UCS2; + mask = MASK_UCS2; + } + /* We check the new mask on the same chars in the next iteration */ + continue; + } + p += 4; + } + while (p < end) { + if (p[0] & mask) { + if (mask == mask_limit) { + /* Limit reached */ + return max_char_limit; + } + if (mask == MASK_ASCII) { + max_char = MAX_CHAR_UCS1; + mask = MASK_UCS1; + } + else { + /* mask can't be MASK_UCS2 because of mask_limit above */ + assert(mask == MASK_UCS1); + max_char = MAX_CHAR_UCS2; + mask = MASK_UCS2; + } + /* We check the new mask on the same chars in the next iteration */ + continue; + } + p++; + } + return max_char; +} + +#undef MASK_ASCII +#undef MASK_UCS1 +#undef MASK_UCS2 +#undef MAX_CHAR_ASCII +#undef MAX_CHAR_UCS1 +#undef MAX_CHAR_UCS2 +#undef MAX_CHAR_UCS4 + +#endif /* STRINGLIB_SIZEOF_CHAR == 1 */ + diff --git a/python/Objects/stringlib/join.h b/python/Objects/stringlib/join.h new file mode 100755 index 0000000..6f314e1 --- /dev/null +++ b/python/Objects/stringlib/join.h @@ -0,0 +1,140 @@ +/* stringlib: bytes joining implementation */ + +#if STRINGLIB_IS_UNICODE +#error join.h only compatible with byte-wise strings +#endif + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) +{ + char *sepstr = STRINGLIB_STR(sep); + const Py_ssize_t seplen = STRINGLIB_LEN(sep); + PyObject *res = NULL; + char *p; + Py_ssize_t seqlen = 0; + Py_ssize_t sz = 0; + Py_ssize_t i, nbufs; + PyObject *seq, *item; + Py_buffer *buffers = NULL; +#define NB_STATIC_BUFFERS 10 + Py_buffer static_buffers[NB_STATIC_BUFFERS]; + + seq = PySequence_Fast(iterable, "can only join an iterable"); + if (seq == NULL) { + return NULL; + } + + seqlen = PySequence_Fast_GET_SIZE(seq); + if (seqlen == 0) { + Py_DECREF(seq); + return STRINGLIB_NEW(NULL, 0); + } +#ifndef STRINGLIB_MUTABLE + if (seqlen == 1) { + item = PySequence_Fast_GET_ITEM(seq, 0); + if (STRINGLIB_CHECK_EXACT(item)) { + Py_INCREF(item); + Py_DECREF(seq); + return item; + } + } +#endif + if (seqlen > NB_STATIC_BUFFERS) { + buffers = PyMem_NEW(Py_buffer, seqlen); + if (buffers == NULL) { + Py_DECREF(seq); + PyErr_NoMemory(); + return NULL; + } + } + else { + buffers = static_buffers; + } + + /* Here is the general case. Do a pre-pass to figure out the total + * amount of space we'll need (sz), and see whether all arguments are + * bytes-like. + */ + for (i = 0, nbufs = 0; i < seqlen; i++) { + Py_ssize_t itemlen; + item = PySequence_Fast_GET_ITEM(seq, i); + if (PyBytes_CheckExact(item)) { + /* Fast path. */ + Py_INCREF(item); + buffers[i].obj = item; + buffers[i].buf = PyBytes_AS_STRING(item); + buffers[i].len = PyBytes_GET_SIZE(item); + } + else if (PyObject_GetBuffer(item, &buffers[i], PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, + "sequence item %zd: expected a bytes-like object, " + "%.80s found", + i, Py_TYPE(item)->tp_name); + goto error; + } + nbufs = i + 1; /* for error cleanup */ + itemlen = buffers[i].len; + if (itemlen > PY_SSIZE_T_MAX - sz) { + PyErr_SetString(PyExc_OverflowError, + "join() result is too long"); + goto error; + } + sz += itemlen; + if (i != 0) { + if (seplen > PY_SSIZE_T_MAX - sz) { + PyErr_SetString(PyExc_OverflowError, + "join() result is too long"); + goto error; + } + sz += seplen; + } + if (seqlen != PySequence_Fast_GET_SIZE(seq)) { + PyErr_SetString(PyExc_RuntimeError, + "sequence changed size during iteration"); + goto error; + } + } + + /* Allocate result space. */ + res = STRINGLIB_NEW(NULL, sz); + if (res == NULL) + goto error; + + /* Catenate everything. */ + p = STRINGLIB_STR(res); + if (!seplen) { + /* fast path */ + for (i = 0; i < nbufs; i++) { + Py_ssize_t n = buffers[i].len; + char *q = buffers[i].buf; + memcpy(p, q, n); + p += n; + } + goto done; + } + for (i = 0; i < nbufs; i++) { + Py_ssize_t n; + char *q; + if (i) { + memcpy(p, sepstr, seplen); + p += seplen; + } + n = buffers[i].len; + q = buffers[i].buf; + memcpy(p, q, n); + p += n; + } + goto done; + +error: + res = NULL; +done: + Py_DECREF(seq); + for (i = 0; i < nbufs; i++) + PyBuffer_Release(&buffers[i]); + if (buffers != static_buffers) + PyMem_FREE(buffers); + return res; +} + +#undef NB_STATIC_BUFFERS diff --git a/python/Objects/stringlib/localeutil.h b/python/Objects/stringlib/localeutil.h new file mode 100755 index 0000000..bd16e0a --- /dev/null +++ b/python/Objects/stringlib/localeutil.h @@ -0,0 +1,82 @@ +/* _PyUnicode_InsertThousandsGrouping() helper functions */ + +typedef struct { + const char *grouping; + char previous; + Py_ssize_t i; /* Where we're currently pointing in grouping. */ +} GroupGenerator; + + +static void +GroupGenerator_init(GroupGenerator *self, const char *grouping) +{ + self->grouping = grouping; + self->i = 0; + self->previous = 0; +} + + +/* Returns the next grouping, or 0 to signify end. */ +static Py_ssize_t +GroupGenerator_next(GroupGenerator *self) +{ + /* Note that we don't really do much error checking here. If a + grouping string contains just CHAR_MAX, for example, then just + terminate the generator. That shouldn't happen, but at least we + fail gracefully. */ + switch (self->grouping[self->i]) { + case 0: + return self->previous; + case CHAR_MAX: + /* Stop the generator. */ + return 0; + default: { + char ch = self->grouping[self->i]; + self->previous = ch; + self->i++; + return (Py_ssize_t)ch; + } + } +} + + +/* Fill in some digits, leading zeros, and thousands separator. All + are optional, depending on when we're called. */ +static void +InsertThousandsGrouping_fill(_PyUnicodeWriter *writer, Py_ssize_t *buffer_pos, + PyObject *digits, Py_ssize_t *digits_pos, + Py_ssize_t n_chars, Py_ssize_t n_zeros, + PyObject *thousands_sep, Py_ssize_t thousands_sep_len, + Py_UCS4 *maxchar) +{ + if (!writer) { + /* if maxchar > 127, maxchar is already set */ + if (*maxchar == 127 && thousands_sep) { + Py_UCS4 maxchar2 = PyUnicode_MAX_CHAR_VALUE(thousands_sep); + *maxchar = Py_MAX(*maxchar, maxchar2); + } + return; + } + + if (thousands_sep) { + *buffer_pos -= thousands_sep_len; + + /* Copy the thousands_sep chars into the buffer. */ + _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, + thousands_sep, 0, + thousands_sep_len); + } + + *buffer_pos -= n_chars; + *digits_pos -= n_chars; + _PyUnicode_FastCopyCharacters(writer->buffer, *buffer_pos, + digits, *digits_pos, + n_chars); + + if (n_zeros) { + *buffer_pos -= n_zeros; + enum PyUnicode_Kind kind = PyUnicode_KIND(writer->buffer); + void *data = PyUnicode_DATA(writer->buffer); + unicode_fill(kind, data, '0', *buffer_pos, n_zeros); + } +} diff --git a/python/Objects/stringlib/partition.h b/python/Objects/stringlib/partition.h new file mode 100755 index 0000000..ed32a6f --- /dev/null +++ b/python/Objects/stringlib/partition.h @@ -0,0 +1,116 @@ +/* stringlib: partition implementation */ + +#ifndef STRINGLIB_FASTSEARCH_H +#error must include "stringlib/fastsearch.h" before including this module +#endif + +Py_LOCAL_INLINE(PyObject*) +STRINGLIB(partition)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + PyObject* sep_obj, + const STRINGLIB_CHAR* sep, Py_ssize_t sep_len) +{ + PyObject* out; + Py_ssize_t pos; + + if (sep_len == 0) { + PyErr_SetString(PyExc_ValueError, "empty separator"); + return NULL; + } + + out = PyTuple_New(3); + if (!out) + return NULL; + + pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_SEARCH); + + if (pos < 0) { +#if STRINGLIB_MUTABLE + PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len)); + PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0)); + PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0)); + + if (PyErr_Occurred()) { + Py_DECREF(out); + return NULL; + } +#else + Py_INCREF(str_obj); + PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj); + Py_INCREF(STRINGLIB_EMPTY); + PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY); + Py_INCREF(STRINGLIB_EMPTY); + PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY); +#endif + return out; + } + + PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos)); + Py_INCREF(sep_obj); + PyTuple_SET_ITEM(out, 1, sep_obj); + pos += sep_len; + PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos)); + + if (PyErr_Occurred()) { + Py_DECREF(out); + return NULL; + } + + return out; +} + +Py_LOCAL_INLINE(PyObject*) +STRINGLIB(rpartition)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + PyObject* sep_obj, + const STRINGLIB_CHAR* sep, Py_ssize_t sep_len) +{ + PyObject* out; + Py_ssize_t pos; + + if (sep_len == 0) { + PyErr_SetString(PyExc_ValueError, "empty separator"); + return NULL; + } + + out = PyTuple_New(3); + if (!out) + return NULL; + + pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_RSEARCH); + + if (pos < 0) { +#if STRINGLIB_MUTABLE + PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0)); + PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0)); + PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len)); + + if (PyErr_Occurred()) { + Py_DECREF(out); + return NULL; + } +#else + Py_INCREF(STRINGLIB_EMPTY); + PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY); + Py_INCREF(STRINGLIB_EMPTY); + PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY); + Py_INCREF(str_obj); + PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj); +#endif + return out; + } + + PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos)); + Py_INCREF(sep_obj); + PyTuple_SET_ITEM(out, 1, sep_obj); + pos += sep_len; + PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos)); + + if (PyErr_Occurred()) { + Py_DECREF(out); + return NULL; + } + + return out; +} + diff --git a/python/Objects/stringlib/replace.h b/python/Objects/stringlib/replace.h new file mode 100755 index 0000000..ef318ed --- /dev/null +++ b/python/Objects/stringlib/replace.h @@ -0,0 +1,53 @@ +/* stringlib: replace implementation */ + +#ifndef STRINGLIB_FASTSEARCH_H +#error must include "stringlib/fastsearch.h" before including this module +#endif + +Py_LOCAL_INLINE(void) +STRINGLIB(replace_1char_inplace)(STRINGLIB_CHAR* s, STRINGLIB_CHAR* end, + Py_UCS4 u1, Py_UCS4 u2, Py_ssize_t maxcount) +{ + *s = u2; + while (--maxcount && ++s != end) { + /* Find the next character to be replaced. + + If it occurs often, it is faster to scan for it using an inline + loop. If it occurs seldom, it is faster to scan for it using a + function call; the overhead of the function call is amortized + across the many characters that call covers. We start with an + inline loop and use a heuristic to determine whether to fall back + to a function call. */ + if (*s != u1) { + int attempts = 10; + /* search u1 in a dummy loop */ + while (1) { + if (++s == end) + return; + if (*s == u1) + break; + if (!--attempts) { + /* if u1 was not found for attempts iterations, + use FASTSEARCH() or memchr() */ +#if STRINGLIB_SIZEOF_CHAR == 1 + s++; + s = memchr(s, u1, end - s); + if (s == NULL) + return; +#else + Py_ssize_t i; + STRINGLIB_CHAR ch1 = (STRINGLIB_CHAR) u1; + s++; + i = FASTSEARCH(s, end - s, &ch1, 1, 0, FAST_SEARCH); + if (i < 0) + return; + s += i; +#endif + /* restart the dummy loop */ + break; + } + } + } + *s = u2; + } +} diff --git a/python/Objects/stringlib/split.h b/python/Objects/stringlib/split.h new file mode 100755 index 0000000..31f77a7 --- /dev/null +++ b/python/Objects/stringlib/split.h @@ -0,0 +1,390 @@ +/* stringlib: split implementation */ + +#ifndef STRINGLIB_FASTSEARCH_H +#error must include "stringlib/fastsearch.h" before including this module +#endif + +/* Overallocate the initial list to reduce the number of reallocs for small + split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three + resizes, to sizes 4, 8, then 16. Most observed string splits are for human + text (roughly 11 words per line) and field delimited data (usually 1-10 + fields). For large strings the split algorithms are bandwidth limited + so increasing the preallocation likely will not improve things.*/ + +#define MAX_PREALLOC 12 + +/* 5 splits gives 6 elements */ +#define PREALLOC_SIZE(maxsplit) \ + (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1) + +#define SPLIT_APPEND(data, left, right) \ + sub = STRINGLIB_NEW((data) + (left), \ + (right) - (left)); \ + if (sub == NULL) \ + goto onError; \ + if (PyList_Append(list, sub)) { \ + Py_DECREF(sub); \ + goto onError; \ + } \ + else \ + Py_DECREF(sub); + +#define SPLIT_ADD(data, left, right) { \ + sub = STRINGLIB_NEW((data) + (left), \ + (right) - (left)); \ + if (sub == NULL) \ + goto onError; \ + if (count < MAX_PREALLOC) { \ + PyList_SET_ITEM(list, count, sub); \ + } else { \ + if (PyList_Append(list, sub)) { \ + Py_DECREF(sub); \ + goto onError; \ + } \ + else \ + Py_DECREF(sub); \ + } \ + count++; } + + +/* Always force the list to the expected size. */ +#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(split_whitespace)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + Py_ssize_t maxcount) +{ + Py_ssize_t i, j, count=0; + PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); + PyObject *sub; + + if (list == NULL) + return NULL; + + i = j = 0; + while (maxcount-- > 0) { + while (i < str_len && STRINGLIB_ISSPACE(str[i])) + i++; + if (i == str_len) break; + j = i; i++; + while (i < str_len && !STRINGLIB_ISSPACE(str[i])) + i++; +#ifndef STRINGLIB_MUTABLE + if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) { + /* No whitespace in str_obj, so just use it as list[0] */ + Py_INCREF(str_obj); + PyList_SET_ITEM(list, 0, (PyObject *)str_obj); + count++; + break; + } +#endif + SPLIT_ADD(str, j, i); + } + + if (i < str_len) { + /* Only occurs when maxcount was reached */ + /* Skip any remaining whitespace and copy to end of string */ + while (i < str_len && STRINGLIB_ISSPACE(str[i])) + i++; + if (i != str_len) + SPLIT_ADD(str, i, str_len); + } + FIX_PREALLOC_SIZE(list); + return list; + + onError: + Py_DECREF(list); + return NULL; +} + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(split_char)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR ch, + Py_ssize_t maxcount) +{ + Py_ssize_t i, j, count=0; + PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); + PyObject *sub; + + if (list == NULL) + return NULL; + + i = j = 0; + while ((j < str_len) && (maxcount-- > 0)) { + for(; j < str_len; j++) { + /* I found that using memchr makes no difference */ + if (str[j] == ch) { + SPLIT_ADD(str, i, j); + i = j = j + 1; + break; + } + } + } +#ifndef STRINGLIB_MUTABLE + if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { + /* ch not in str_obj, so just use str_obj as list[0] */ + Py_INCREF(str_obj); + PyList_SET_ITEM(list, 0, (PyObject *)str_obj); + count++; + } else +#endif + if (i <= str_len) { + SPLIT_ADD(str, i, str_len); + } + FIX_PREALLOC_SIZE(list); + return list; + + onError: + Py_DECREF(list); + return NULL; +} + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(split)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR* sep, Py_ssize_t sep_len, + Py_ssize_t maxcount) +{ + Py_ssize_t i, j, pos, count=0; + PyObject *list, *sub; + + if (sep_len == 0) { + PyErr_SetString(PyExc_ValueError, "empty separator"); + return NULL; + } + else if (sep_len == 1) + return STRINGLIB(split_char)(str_obj, str, str_len, sep[0], maxcount); + + list = PyList_New(PREALLOC_SIZE(maxcount)); + if (list == NULL) + return NULL; + + i = j = 0; + while (maxcount-- > 0) { + pos = FASTSEARCH(str+i, str_len-i, sep, sep_len, -1, FAST_SEARCH); + if (pos < 0) + break; + j = i + pos; + SPLIT_ADD(str, i, j); + i = j + sep_len; + } +#ifndef STRINGLIB_MUTABLE + if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { + /* No match in str_obj, so just use it as list[0] */ + Py_INCREF(str_obj); + PyList_SET_ITEM(list, 0, (PyObject *)str_obj); + count++; + } else +#endif + { + SPLIT_ADD(str, i, str_len); + } + FIX_PREALLOC_SIZE(list); + return list; + + onError: + Py_DECREF(list); + return NULL; +} + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(rsplit_whitespace)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + Py_ssize_t maxcount) +{ + Py_ssize_t i, j, count=0; + PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); + PyObject *sub; + + if (list == NULL) + return NULL; + + i = j = str_len - 1; + while (maxcount-- > 0) { + while (i >= 0 && STRINGLIB_ISSPACE(str[i])) + i--; + if (i < 0) break; + j = i; i--; + while (i >= 0 && !STRINGLIB_ISSPACE(str[i])) + i--; +#ifndef STRINGLIB_MUTABLE + if (j == str_len - 1 && i < 0 && STRINGLIB_CHECK_EXACT(str_obj)) { + /* No whitespace in str_obj, so just use it as list[0] */ + Py_INCREF(str_obj); + PyList_SET_ITEM(list, 0, (PyObject *)str_obj); + count++; + break; + } +#endif + SPLIT_ADD(str, i + 1, j + 1); + } + + if (i >= 0) { + /* Only occurs when maxcount was reached */ + /* Skip any remaining whitespace and copy to beginning of string */ + while (i >= 0 && STRINGLIB_ISSPACE(str[i])) + i--; + if (i >= 0) + SPLIT_ADD(str, 0, i + 1); + } + FIX_PREALLOC_SIZE(list); + if (PyList_Reverse(list) < 0) + goto onError; + return list; + + onError: + Py_DECREF(list); + return NULL; +} + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(rsplit_char)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR ch, + Py_ssize_t maxcount) +{ + Py_ssize_t i, j, count=0; + PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); + PyObject *sub; + + if (list == NULL) + return NULL; + + i = j = str_len - 1; + while ((i >= 0) && (maxcount-- > 0)) { + for(; i >= 0; i--) { + if (str[i] == ch) { + SPLIT_ADD(str, i + 1, j + 1); + j = i = i - 1; + break; + } + } + } +#ifndef STRINGLIB_MUTABLE + if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { + /* ch not in str_obj, so just use str_obj as list[0] */ + Py_INCREF(str_obj); + PyList_SET_ITEM(list, 0, (PyObject *)str_obj); + count++; + } else +#endif + if (j >= -1) { + SPLIT_ADD(str, 0, j + 1); + } + FIX_PREALLOC_SIZE(list); + if (PyList_Reverse(list) < 0) + goto onError; + return list; + + onError: + Py_DECREF(list); + return NULL; +} + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(rsplit)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + const STRINGLIB_CHAR* sep, Py_ssize_t sep_len, + Py_ssize_t maxcount) +{ + Py_ssize_t j, pos, count=0; + PyObject *list, *sub; + + if (sep_len == 0) { + PyErr_SetString(PyExc_ValueError, "empty separator"); + return NULL; + } + else if (sep_len == 1) + return STRINGLIB(rsplit_char)(str_obj, str, str_len, sep[0], maxcount); + + list = PyList_New(PREALLOC_SIZE(maxcount)); + if (list == NULL) + return NULL; + + j = str_len; + while (maxcount-- > 0) { + pos = FASTSEARCH(str, j, sep, sep_len, -1, FAST_RSEARCH); + if (pos < 0) + break; + SPLIT_ADD(str, pos + sep_len, j); + j = pos; + } +#ifndef STRINGLIB_MUTABLE + if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { + /* No match in str_obj, so just use it as list[0] */ + Py_INCREF(str_obj); + PyList_SET_ITEM(list, 0, (PyObject *)str_obj); + count++; + } else +#endif + { + SPLIT_ADD(str, 0, j); + } + FIX_PREALLOC_SIZE(list); + if (PyList_Reverse(list) < 0) + goto onError; + return list; + + onError: + Py_DECREF(list); + return NULL; +} + +Py_LOCAL_INLINE(PyObject *) +STRINGLIB(splitlines)(PyObject* str_obj, + const STRINGLIB_CHAR* str, Py_ssize_t str_len, + int keepends) +{ + /* This does not use the preallocated list because splitlines is + usually run with hundreds of newlines. The overhead of + switching between PyList_SET_ITEM and append causes about a + 2-3% slowdown for that common case. A smarter implementation + could move the if check out, so the SET_ITEMs are done first + and the appends only done when the prealloc buffer is full. + That's too much work for little gain.*/ + + Py_ssize_t i; + Py_ssize_t j; + PyObject *list = PyList_New(0); + PyObject *sub; + + if (list == NULL) + return NULL; + + for (i = j = 0; i < str_len; ) { + Py_ssize_t eol; + + /* Find a line and append it */ + while (i < str_len && !STRINGLIB_ISLINEBREAK(str[i])) + i++; + + /* Skip the line break reading CRLF as one line break */ + eol = i; + if (i < str_len) { + if (str[i] == '\r' && i + 1 < str_len && str[i+1] == '\n') + i += 2; + else + i++; + if (keepends) + eol = i; + } +#ifndef STRINGLIB_MUTABLE + if (j == 0 && eol == str_len && STRINGLIB_CHECK_EXACT(str_obj)) { + /* No linebreak in str_obj, so just use it as list[0] */ + if (PyList_Append(list, str_obj)) + goto onError; + break; + } +#endif + SPLIT_APPEND(str, j, eol); + j = i; + } + return list; + + onError: + Py_DECREF(list); + return NULL; +} + diff --git a/python/Objects/stringlib/stringdefs.h b/python/Objects/stringlib/stringdefs.h new file mode 100755 index 0000000..ce27f3e --- /dev/null +++ b/python/Objects/stringlib/stringdefs.h @@ -0,0 +1,28 @@ +#ifndef STRINGLIB_STRINGDEFS_H +#define STRINGLIB_STRINGDEFS_H + +/* this is sort of a hack. there's at least one place (formatting + floats) where some stringlib code takes a different path if it's + compiled as unicode. */ +#define STRINGLIB_IS_UNICODE 0 + +#define FASTSEARCH fastsearch +#define STRINGLIB(F) stringlib_##F +#define STRINGLIB_OBJECT PyBytesObject +#define STRINGLIB_SIZEOF_CHAR 1 +#define STRINGLIB_CHAR char +#define STRINGLIB_TYPE_NAME "string" +#define STRINGLIB_PARSE_CODE "S" +#define STRINGLIB_EMPTY nullstring +#define STRINGLIB_ISSPACE Py_ISSPACE +#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) +#define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9')) +#define STRINGLIB_TODECIMAL(x) (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1) +#define STRINGLIB_STR PyBytes_AS_STRING +#define STRINGLIB_LEN PyBytes_GET_SIZE +#define STRINGLIB_NEW PyBytes_FromStringAndSize +#define STRINGLIB_CHECK PyBytes_Check +#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact +#define STRINGLIB_TOSTR PyObject_Str +#define STRINGLIB_TOASCII PyObject_Repr +#endif /* !STRINGLIB_STRINGDEFS_H */ diff --git a/python/Objects/stringlib/transmogrify.h b/python/Objects/stringlib/transmogrify.h new file mode 100755 index 0000000..9506019 --- /dev/null +++ b/python/Objects/stringlib/transmogrify.h @@ -0,0 +1,743 @@ +#if STRINGLIB_IS_UNICODE +# error "transmogrify.h only compatible with byte-wise strings" +#endif + +/* the more complicated methods. parts of these should be pulled out into the + shared code in bytes_methods.c to cut down on duplicate code bloat. */ + +/*[clinic input] +class B "PyObject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2935558188d97c76]*/ + +#include "clinic/transmogrify.h.h" + +static inline PyObject * +return_self(PyObject *self) +{ +#if !STRINGLIB_MUTABLE + if (STRINGLIB_CHECK_EXACT(self)) { + Py_INCREF(self); + return self; + } +#endif + return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); +} + +/*[clinic input] +B.expandtabs as stringlib_expandtabs + + tabsize: int = 8 + +Return a copy where all tab characters are expanded using spaces. + +If tabsize is not given, a tab size of 8 characters is assumed. +[clinic start generated code]*/ + +static PyObject * +stringlib_expandtabs_impl(PyObject *self, int tabsize) +/*[clinic end generated code: output=069cb7fae72e4c2b input=3c6d3b12aa3ccbea]*/ +{ + const char *e, *p; + char *q; + Py_ssize_t i, j; + PyObject *u; + + /* First pass: determine size of output string */ + i = j = 0; + e = STRINGLIB_STR(self) + STRINGLIB_LEN(self); + for (p = STRINGLIB_STR(self); p < e; p++) { + if (*p == '\t') { + if (tabsize > 0) { + Py_ssize_t incr = tabsize - (j % tabsize); + if (j > PY_SSIZE_T_MAX - incr) + goto overflow; + j += incr; + } + } + else { + if (j > PY_SSIZE_T_MAX - 1) + goto overflow; + j++; + if (*p == '\n' || *p == '\r') { + if (i > PY_SSIZE_T_MAX - j) + goto overflow; + i += j; + j = 0; + } + } + } + + if (i > PY_SSIZE_T_MAX - j) + goto overflow; + + /* Second pass: create output string and fill it */ + u = STRINGLIB_NEW(NULL, i + j); + if (!u) + return NULL; + + j = 0; + q = STRINGLIB_STR(u); + + for (p = STRINGLIB_STR(self); p < e; p++) { + if (*p == '\t') { + if (tabsize > 0) { + i = tabsize - (j % tabsize); + j += i; + while (i--) + *q++ = ' '; + } + } + else { + j++; + *q++ = *p; + if (*p == '\n' || *p == '\r') + j = 0; + } + } + + return u; + overflow: + PyErr_SetString(PyExc_OverflowError, "result too long"); + return NULL; +} + +static inline PyObject * +pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill) +{ + PyObject *u; + + if (left < 0) + left = 0; + if (right < 0) + right = 0; + + if (left == 0 && right == 0) { + return return_self(self); + } + + u = STRINGLIB_NEW(NULL, left + STRINGLIB_LEN(self) + right); + if (u) { + if (left) + memset(STRINGLIB_STR(u), fill, left); + memcpy(STRINGLIB_STR(u) + left, + STRINGLIB_STR(self), + STRINGLIB_LEN(self)); + if (right) + memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self), + fill, right); + } + + return u; +} + +/*[clinic input] +B.ljust as stringlib_ljust + + width: Py_ssize_t + fillchar: char = b' ' + / + +Return a left-justified string of length width. + +Padding is done using the specified fill character. +[clinic start generated code]*/ + +static PyObject * +stringlib_ljust_impl(PyObject *self, Py_ssize_t width, char fillchar) +/*[clinic end generated code: output=c79ca173c5ff8337 input=eff2d014bc7d80df]*/ +{ + if (STRINGLIB_LEN(self) >= width) { + return return_self(self); + } + + return pad(self, 0, width - STRINGLIB_LEN(self), fillchar); +} + + +/*[clinic input] +B.rjust as stringlib_rjust + + width: Py_ssize_t + fillchar: char = b' ' + / + +Return a right-justified string of length width. + +Padding is done using the specified fill character. +[clinic start generated code]*/ + +static PyObject * +stringlib_rjust_impl(PyObject *self, Py_ssize_t width, char fillchar) +/*[clinic end generated code: output=7df5d728a5439570 input=218b0bd31308955d]*/ +{ + if (STRINGLIB_LEN(self) >= width) { + return return_self(self); + } + + return pad(self, width - STRINGLIB_LEN(self), 0, fillchar); +} + + +/*[clinic input] +B.center as stringlib_center + + width: Py_ssize_t + fillchar: char = b' ' + / + +Return a centered string of length width. + +Padding is done using the specified fill character. +[clinic start generated code]*/ + +static PyObject * +stringlib_center_impl(PyObject *self, Py_ssize_t width, char fillchar) +/*[clinic end generated code: output=d8da2e055288b4c2 input=3776fd278765d89b]*/ +{ + Py_ssize_t marg, left; + + if (STRINGLIB_LEN(self) >= width) { + return return_self(self); + } + + marg = width - STRINGLIB_LEN(self); + left = marg / 2 + (marg & width & 1); + + return pad(self, left, marg - left, fillchar); +} + +/*[clinic input] +B.zfill as stringlib_zfill + + width: Py_ssize_t + / + +Pad a numeric string with zeros on the left, to fill a field of the given width. + +The original string is never truncated. +[clinic start generated code]*/ + +static PyObject * +stringlib_zfill_impl(PyObject *self, Py_ssize_t width) +/*[clinic end generated code: output=0b3c684a7f1b2319 input=2da6d7b8e9bcb19a]*/ +{ + Py_ssize_t fill; + PyObject *s; + char *p; + + if (STRINGLIB_LEN(self) >= width) { + return return_self(self); + } + + fill = width - STRINGLIB_LEN(self); + + s = pad(self, fill, 0, '0'); + + if (s == NULL) + return NULL; + + p = STRINGLIB_STR(s); + if (p[fill] == '+' || p[fill] == '-') { + /* move sign to beginning of string */ + p[0] = p[fill]; + p[fill] = '0'; + } + + return s; +} + + +/* find and count characters and substrings */ + +#define findchar(target, target_len, c) \ + ((char *)memchr((const void *)(target), c, target_len)) + + +static Py_ssize_t +countchar(const char *target, Py_ssize_t target_len, char c, + Py_ssize_t maxcount) +{ + Py_ssize_t count = 0; + const char *start = target; + const char *end = target + target_len; + + while ((start = findchar(start, end - start, c)) != NULL) { + count++; + if (count >= maxcount) + break; + start += 1; + } + return count; +} + + +/* Algorithms for different cases of string replacement */ + +/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */ +static PyObject * +stringlib_replace_interleave(PyObject *self, + const char *to_s, Py_ssize_t to_len, + Py_ssize_t maxcount) +{ + const char *self_s; + char *result_s; + Py_ssize_t self_len, result_len; + Py_ssize_t count, i; + PyObject *result; + + self_len = STRINGLIB_LEN(self); + + /* 1 at the end plus 1 after every character; + count = min(maxcount, self_len + 1) */ + if (maxcount <= self_len) { + count = maxcount; + } + else { + /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */ + count = self_len + 1; + } + + /* Check for overflow */ + /* result_len = count * to_len + self_len; */ + assert(count > 0); + if (to_len > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, + "replace bytes is too long"); + return NULL; + } + result_len = count * to_len + self_len; + result = STRINGLIB_NEW(NULL, result_len); + if (result == NULL) { + return NULL; + } + + self_s = STRINGLIB_STR(self); + result_s = STRINGLIB_STR(result); + + if (to_len > 1) { + /* Lay the first one down (guaranteed this will occur) */ + memcpy(result_s, to_s, to_len); + result_s += to_len; + count -= 1; + + for (i = 0; i < count; i++) { + *result_s++ = *self_s++; + memcpy(result_s, to_s, to_len); + result_s += to_len; + } + } + else { + result_s[0] = to_s[0]; + result_s += to_len; + count -= 1; + for (i = 0; i < count; i++) { + *result_s++ = *self_s++; + result_s[0] = to_s[0]; + result_s += to_len; + } + } + + /* Copy the rest of the original string */ + memcpy(result_s, self_s, self_len - i); + + return result; +} + +/* Special case for deleting a single character */ +/* len(self)>=1, len(from)==1, to="", maxcount>=1 */ +static PyObject * +stringlib_replace_delete_single_character(PyObject *self, + char from_c, Py_ssize_t maxcount) +{ + const char *self_s, *start, *next, *end; + char *result_s; + Py_ssize_t self_len, result_len; + Py_ssize_t count; + PyObject *result; + + self_len = STRINGLIB_LEN(self); + self_s = STRINGLIB_STR(self); + + count = countchar(self_s, self_len, from_c, maxcount); + if (count == 0) { + return return_self(self); + } + + result_len = self_len - count; /* from_len == 1 */ + assert(result_len>=0); + + result = STRINGLIB_NEW(NULL, result_len); + if (result == NULL) { + return NULL; + } + result_s = STRINGLIB_STR(result); + + start = self_s; + end = self_s + self_len; + while (count-- > 0) { + next = findchar(start, end - start, from_c); + if (next == NULL) + break; + memcpy(result_s, start, next - start); + result_s += (next - start); + start = next + 1; + } + memcpy(result_s, start, end - start); + + return result; +} + +/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */ + +static PyObject * +stringlib_replace_delete_substring(PyObject *self, + const char *from_s, Py_ssize_t from_len, + Py_ssize_t maxcount) +{ + const char *self_s, *start, *next, *end; + char *result_s; + Py_ssize_t self_len, result_len; + Py_ssize_t count, offset; + PyObject *result; + + self_len = STRINGLIB_LEN(self); + self_s = STRINGLIB_STR(self); + + count = stringlib_count(self_s, self_len, + from_s, from_len, + maxcount); + + if (count == 0) { + /* no matches */ + return return_self(self); + } + + result_len = self_len - (count * from_len); + assert (result_len>=0); + + result = STRINGLIB_NEW(NULL, result_len); + if (result == NULL) { + return NULL; + } + result_s = STRINGLIB_STR(result); + + start = self_s; + end = self_s + self_len; + while (count-- > 0) { + offset = stringlib_find(start, end - start, + from_s, from_len, + 0); + if (offset == -1) + break; + next = start + offset; + + memcpy(result_s, start, next - start); + + result_s += (next - start); + start = next + from_len; + } + memcpy(result_s, start, end - start); + return result; +} + +/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */ +static PyObject * +stringlib_replace_single_character_in_place(PyObject *self, + char from_c, char to_c, + Py_ssize_t maxcount) +{ + const char *self_s, *end; + char *result_s, *start, *next; + Py_ssize_t self_len; + PyObject *result; + + /* The result string will be the same size */ + self_s = STRINGLIB_STR(self); + self_len = STRINGLIB_LEN(self); + + next = findchar(self_s, self_len, from_c); + + if (next == NULL) { + /* No matches; return the original bytes */ + return return_self(self); + } + + /* Need to make a new bytes */ + result = STRINGLIB_NEW(NULL, self_len); + if (result == NULL) { + return NULL; + } + result_s = STRINGLIB_STR(result); + memcpy(result_s, self_s, self_len); + + /* change everything in-place, starting with this one */ + start = result_s + (next - self_s); + *start = to_c; + start++; + end = result_s + self_len; + + while (--maxcount > 0) { + next = findchar(start, end - start, from_c); + if (next == NULL) + break; + *next = to_c; + start = next + 1; + } + + return result; +} + +/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ +static PyObject * +stringlib_replace_substring_in_place(PyObject *self, + const char *from_s, Py_ssize_t from_len, + const char *to_s, Py_ssize_t to_len, + Py_ssize_t maxcount) +{ + const char *self_s, *end; + char *result_s, *start; + Py_ssize_t self_len, offset; + PyObject *result; + + /* The result bytes will be the same size */ + + self_s = STRINGLIB_STR(self); + self_len = STRINGLIB_LEN(self); + + offset = stringlib_find(self_s, self_len, + from_s, from_len, + 0); + if (offset == -1) { + /* No matches; return the original bytes */ + return return_self(self); + } + + /* Need to make a new bytes */ + result = STRINGLIB_NEW(NULL, self_len); + if (result == NULL) { + return NULL; + } + result_s = STRINGLIB_STR(result); + memcpy(result_s, self_s, self_len); + + /* change everything in-place, starting with this one */ + start = result_s + offset; + memcpy(start, to_s, from_len); + start += from_len; + end = result_s + self_len; + + while ( --maxcount > 0) { + offset = stringlib_find(start, end - start, + from_s, from_len, + 0); + if (offset == -1) + break; + memcpy(start + offset, to_s, from_len); + start += offset + from_len; + } + + return result; +} + +/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */ +static PyObject * +stringlib_replace_single_character(PyObject *self, + char from_c, + const char *to_s, Py_ssize_t to_len, + Py_ssize_t maxcount) +{ + const char *self_s, *start, *next, *end; + char *result_s; + Py_ssize_t self_len, result_len; + Py_ssize_t count; + PyObject *result; + + self_s = STRINGLIB_STR(self); + self_len = STRINGLIB_LEN(self); + + count = countchar(self_s, self_len, from_c, maxcount); + if (count == 0) { + /* no matches, return unchanged */ + return return_self(self); + } + + /* use the difference between current and new, hence the "-1" */ + /* result_len = self_len + count * (to_len-1) */ + assert(count > 0); + if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } + result_len = self_len + count * (to_len - 1); + + result = STRINGLIB_NEW(NULL, result_len); + if (result == NULL) { + return NULL; + } + result_s = STRINGLIB_STR(result); + + start = self_s; + end = self_s + self_len; + while (count-- > 0) { + next = findchar(start, end - start, from_c); + if (next == NULL) + break; + + if (next == start) { + /* replace with the 'to' */ + memcpy(result_s, to_s, to_len); + result_s += to_len; + start += 1; + } else { + /* copy the unchanged old then the 'to' */ + memcpy(result_s, start, next - start); + result_s += (next - start); + memcpy(result_s, to_s, to_len); + result_s += to_len; + start = next + 1; + } + } + /* Copy the remainder of the remaining bytes */ + memcpy(result_s, start, end - start); + + return result; +} + +/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */ +static PyObject * +stringlib_replace_substring(PyObject *self, + const char *from_s, Py_ssize_t from_len, + const char *to_s, Py_ssize_t to_len, + Py_ssize_t maxcount) +{ + const char *self_s, *start, *next, *end; + char *result_s; + Py_ssize_t self_len, result_len; + Py_ssize_t count, offset; + PyObject *result; + + self_s = STRINGLIB_STR(self); + self_len = STRINGLIB_LEN(self); + + count = stringlib_count(self_s, self_len, + from_s, from_len, + maxcount); + + if (count == 0) { + /* no matches, return unchanged */ + return return_self(self); + } + + /* Check for overflow */ + /* result_len = self_len + count * (to_len-from_len) */ + assert(count > 0); + if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } + result_len = self_len + count * (to_len - from_len); + + result = STRINGLIB_NEW(NULL, result_len); + if (result == NULL) { + return NULL; + } + result_s = STRINGLIB_STR(result); + + start = self_s; + end = self_s + self_len; + while (count-- > 0) { + offset = stringlib_find(start, end - start, + from_s, from_len, + 0); + if (offset == -1) + break; + next = start + offset; + if (next == start) { + /* replace with the 'to' */ + memcpy(result_s, to_s, to_len); + result_s += to_len; + start += from_len; + } else { + /* copy the unchanged old then the 'to' */ + memcpy(result_s, start, next - start); + result_s += (next - start); + memcpy(result_s, to_s, to_len); + result_s += to_len; + start = next + from_len; + } + } + /* Copy the remainder of the remaining bytes */ + memcpy(result_s, start, end - start); + + return result; +} + + +static PyObject * +stringlib_replace(PyObject *self, + const char *from_s, Py_ssize_t from_len, + const char *to_s, Py_ssize_t to_len, + Py_ssize_t maxcount) +{ + if (maxcount < 0) { + maxcount = PY_SSIZE_T_MAX; + } else if (maxcount == 0 || STRINGLIB_LEN(self) == 0) { + /* nothing to do; return the original bytes */ + return return_self(self); + } + + /* Handle zero-length special cases */ + if (from_len == 0) { + if (to_len == 0) { + /* nothing to do; return the original bytes */ + return return_self(self); + } + /* insert the 'to' bytes everywhere. */ + /* >>> b"Python".replace(b"", b".") */ + /* b'.P.y.t.h.o.n.' */ + return stringlib_replace_interleave(self, to_s, to_len, maxcount); + } + + /* Except for b"".replace(b"", b"A") == b"A" there is no way beyond this */ + /* point for an empty self bytes to generate a non-empty bytes */ + /* Special case so the remaining code always gets a non-empty bytes */ + if (STRINGLIB_LEN(self) == 0) { + return return_self(self); + } + + if (to_len == 0) { + /* delete all occurrences of 'from' bytes */ + if (from_len == 1) { + return stringlib_replace_delete_single_character( + self, from_s[0], maxcount); + } else { + return stringlib_replace_delete_substring( + self, from_s, from_len, maxcount); + } + } + + /* Handle special case where both bytes have the same length */ + + if (from_len == to_len) { + if (from_len == 1) { + return stringlib_replace_single_character_in_place( + self, from_s[0], to_s[0], maxcount); + } else { + return stringlib_replace_substring_in_place( + self, from_s, from_len, to_s, to_len, maxcount); + } + } + + /* Otherwise use the more generic algorithms */ + if (from_len == 1) { + return stringlib_replace_single_character( + self, from_s[0], to_s, to_len, maxcount); + } else { + /* len('from')>=2, len('to')>=1 */ + return stringlib_replace_substring( + self, from_s, from_len, to_s, to_len, maxcount); + } +} + +#undef findchar diff --git a/python/Objects/stringlib/ucs1lib.h b/python/Objects/stringlib/ucs1lib.h new file mode 100755 index 0000000..ce1eb57 --- /dev/null +++ b/python/Objects/stringlib/ucs1lib.h @@ -0,0 +1,30 @@ +/* this is sort of a hack. there's at least one place (formatting + floats) where some stringlib code takes a different path if it's + compiled as unicode. */ +#define STRINGLIB_IS_UNICODE 1 + +#define FASTSEARCH ucs1lib_fastsearch +#define STRINGLIB(F) ucs1lib_##F +#define STRINGLIB_OBJECT PyUnicodeObject +#define STRINGLIB_SIZEOF_CHAR 1 +#define STRINGLIB_MAX_CHAR 0xFFu +#define STRINGLIB_CHAR Py_UCS1 +#define STRINGLIB_TYPE_NAME "unicode" +#define STRINGLIB_PARSE_CODE "U" +#define STRINGLIB_EMPTY unicode_empty +#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE +#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK +#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL +#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL +#define STRINGLIB_STR PyUnicode_1BYTE_DATA +#define STRINGLIB_LEN PyUnicode_GET_LENGTH +#define STRINGLIB_NEW _PyUnicode_FromUCS1 +#define STRINGLIB_CHECK PyUnicode_Check +#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact + +#define STRINGLIB_TOSTR PyObject_Str +#define STRINGLIB_TOASCII PyObject_ASCII + +#define _Py_InsertThousandsGrouping _PyUnicode_ucs1_InsertThousandsGrouping + + diff --git a/python/Objects/stringlib/ucs2lib.h b/python/Objects/stringlib/ucs2lib.h new file mode 100755 index 0000000..f900cb6 --- /dev/null +++ b/python/Objects/stringlib/ucs2lib.h @@ -0,0 +1,29 @@ +/* this is sort of a hack. there's at least one place (formatting + floats) where some stringlib code takes a different path if it's + compiled as unicode. */ +#define STRINGLIB_IS_UNICODE 1 + +#define FASTSEARCH ucs2lib_fastsearch +#define STRINGLIB(F) ucs2lib_##F +#define STRINGLIB_OBJECT PyUnicodeObject +#define STRINGLIB_SIZEOF_CHAR 2 +#define STRINGLIB_MAX_CHAR 0xFFFFu +#define STRINGLIB_CHAR Py_UCS2 +#define STRINGLIB_TYPE_NAME "unicode" +#define STRINGLIB_PARSE_CODE "U" +#define STRINGLIB_EMPTY unicode_empty +#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE +#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK +#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL +#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL +#define STRINGLIB_STR PyUnicode_2BYTE_DATA +#define STRINGLIB_LEN PyUnicode_GET_LENGTH +#define STRINGLIB_NEW _PyUnicode_FromUCS2 +#define STRINGLIB_CHECK PyUnicode_Check +#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact + +#define STRINGLIB_TOSTR PyObject_Str +#define STRINGLIB_TOASCII PyObject_ASCII + +#define _Py_InsertThousandsGrouping _PyUnicode_ucs2_InsertThousandsGrouping + diff --git a/python/Objects/stringlib/ucs4lib.h b/python/Objects/stringlib/ucs4lib.h new file mode 100755 index 0000000..86a480f --- /dev/null +++ b/python/Objects/stringlib/ucs4lib.h @@ -0,0 +1,29 @@ +/* this is sort of a hack. there's at least one place (formatting + floats) where some stringlib code takes a different path if it's + compiled as unicode. */ +#define STRINGLIB_IS_UNICODE 1 + +#define FASTSEARCH ucs4lib_fastsearch +#define STRINGLIB(F) ucs4lib_##F +#define STRINGLIB_OBJECT PyUnicodeObject +#define STRINGLIB_SIZEOF_CHAR 4 +#define STRINGLIB_MAX_CHAR 0x10FFFFu +#define STRINGLIB_CHAR Py_UCS4 +#define STRINGLIB_TYPE_NAME "unicode" +#define STRINGLIB_PARSE_CODE "U" +#define STRINGLIB_EMPTY unicode_empty +#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE +#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK +#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL +#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL +#define STRINGLIB_STR PyUnicode_4BYTE_DATA +#define STRINGLIB_LEN PyUnicode_GET_LENGTH +#define STRINGLIB_NEW _PyUnicode_FromUCS4 +#define STRINGLIB_CHECK PyUnicode_Check +#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact + +#define STRINGLIB_TOSTR PyObject_Str +#define STRINGLIB_TOASCII PyObject_ASCII + +#define _Py_InsertThousandsGrouping _PyUnicode_ucs4_InsertThousandsGrouping + diff --git a/python/Objects/stringlib/undef.h b/python/Objects/stringlib/undef.h new file mode 100755 index 0000000..f9d3f1d --- /dev/null +++ b/python/Objects/stringlib/undef.h @@ -0,0 +1,11 @@ +#undef FASTSEARCH +#undef STRINGLIB +#undef STRINGLIB_SIZEOF_CHAR +#undef STRINGLIB_MAX_CHAR +#undef STRINGLIB_CHAR +#undef STRINGLIB_STR +#undef STRINGLIB_LEN +#undef STRINGLIB_NEW +#undef _Py_InsertThousandsGrouping +#undef STRINGLIB_IS_UNICODE + diff --git a/python/Objects/stringlib/unicode_format.h b/python/Objects/stringlib/unicode_format.h new file mode 100755 index 0000000..ddf1e26 --- /dev/null +++ b/python/Objects/stringlib/unicode_format.h @@ -0,0 +1,1291 @@ +/* + unicode_format.h -- implementation of str.format(). +*/ + +/************************************************************************/ +/*********** Global data structures and forward declarations *********/ +/************************************************************************/ + +/* + A SubString consists of the characters between two string or + unicode pointers. +*/ +typedef struct { + PyObject *str; /* borrowed reference */ + Py_ssize_t start, end; +} SubString; + + +typedef enum { + ANS_INIT, + ANS_AUTO, + ANS_MANUAL +} AutoNumberState; /* Keep track if we're auto-numbering fields */ + +/* Keeps track of our auto-numbering state, and which number field we're on */ +typedef struct { + AutoNumberState an_state; + int an_field_number; +} AutoNumber; + + +/* forward declaration for recursion */ +static PyObject * +build_string(SubString *input, PyObject *args, PyObject *kwargs, + int recursion_depth, AutoNumber *auto_number); + + + +/************************************************************************/ +/************************** Utility functions ************************/ +/************************************************************************/ + +static void +AutoNumber_Init(AutoNumber *auto_number) +{ + auto_number->an_state = ANS_INIT; + auto_number->an_field_number = 0; +} + +/* fill in a SubString from a pointer and length */ +Py_LOCAL_INLINE(void) +SubString_init(SubString *str, PyObject *s, Py_ssize_t start, Py_ssize_t end) +{ + str->str = s; + str->start = start; + str->end = end; +} + +/* return a new string. if str->str is NULL, return None */ +Py_LOCAL_INLINE(PyObject *) +SubString_new_object(SubString *str) +{ + if (str->str == NULL) + Py_RETURN_NONE; + return PyUnicode_Substring(str->str, str->start, str->end); +} + +/* return a new string. if str->str is NULL, return a new empty string */ +Py_LOCAL_INLINE(PyObject *) +SubString_new_object_or_empty(SubString *str) +{ + if (str->str == NULL) { + return PyUnicode_New(0, 0); + } + return SubString_new_object(str); +} + +/* Return 1 if an error has been detected switching between automatic + field numbering and manual field specification, else return 0. Set + ValueError on error. */ +static int +autonumber_state_error(AutoNumberState state, int field_name_is_empty) +{ + if (state == ANS_MANUAL) { + if (field_name_is_empty) { + PyErr_SetString(PyExc_ValueError, "cannot switch from " + "manual field specification to " + "automatic field numbering"); + return 1; + } + } + else { + if (!field_name_is_empty) { + PyErr_SetString(PyExc_ValueError, "cannot switch from " + "automatic field numbering to " + "manual field specification"); + return 1; + } + } + return 0; +} + + +/************************************************************************/ +/*********** Format string parsing -- integers and identifiers *********/ +/************************************************************************/ + +static Py_ssize_t +get_integer(const SubString *str) +{ + Py_ssize_t accumulator = 0; + Py_ssize_t digitval; + Py_ssize_t i; + + /* empty string is an error */ + if (str->start >= str->end) + return -1; + + for (i = str->start; i < str->end; i++) { + digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ_CHAR(str->str, i)); + if (digitval < 0) + return -1; + /* + Detect possible overflow before it happens: + + accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if + accumulator > (PY_SSIZE_T_MAX - digitval) / 10. + */ + if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) { + PyErr_Format(PyExc_ValueError, + "Too many decimal digits in format string"); + return -1; + } + accumulator = accumulator * 10 + digitval; + } + return accumulator; +} + +/************************************************************************/ +/******** Functions to get field objects and specification strings ******/ +/************************************************************************/ + +/* do the equivalent of obj.name */ +static PyObject * +getattr(PyObject *obj, SubString *name) +{ + PyObject *newobj; + PyObject *str = SubString_new_object(name); + if (str == NULL) + return NULL; + newobj = PyObject_GetAttr(obj, str); + Py_DECREF(str); + return newobj; +} + +/* do the equivalent of obj[idx], where obj is a sequence */ +static PyObject * +getitem_sequence(PyObject *obj, Py_ssize_t idx) +{ + return PySequence_GetItem(obj, idx); +} + +/* do the equivalent of obj[idx], where obj is not a sequence */ +static PyObject * +getitem_idx(PyObject *obj, Py_ssize_t idx) +{ + PyObject *newobj; + PyObject *idx_obj = PyLong_FromSsize_t(idx); + if (idx_obj == NULL) + return NULL; + newobj = PyObject_GetItem(obj, idx_obj); + Py_DECREF(idx_obj); + return newobj; +} + +/* do the equivalent of obj[name] */ +static PyObject * +getitem_str(PyObject *obj, SubString *name) +{ + PyObject *newobj; + PyObject *str = SubString_new_object(name); + if (str == NULL) + return NULL; + newobj = PyObject_GetItem(obj, str); + Py_DECREF(str); + return newobj; +} + +typedef struct { + /* the entire string we're parsing. we assume that someone else + is managing its lifetime, and that it will exist for the + lifetime of the iterator. can be empty */ + SubString str; + + /* index to where we are inside field_name */ + Py_ssize_t index; +} FieldNameIterator; + + +static int +FieldNameIterator_init(FieldNameIterator *self, PyObject *s, + Py_ssize_t start, Py_ssize_t end) +{ + SubString_init(&self->str, s, start, end); + self->index = start; + return 1; +} + +static int +_FieldNameIterator_attr(FieldNameIterator *self, SubString *name) +{ + Py_UCS4 c; + + name->str = self->str.str; + name->start = self->index; + + /* return everything until '.' or '[' */ + while (self->index < self->str.end) { + c = PyUnicode_READ_CHAR(self->str.str, self->index++); + switch (c) { + case '[': + case '.': + /* backup so that we this character will be seen next time */ + self->index--; + break; + default: + continue; + } + break; + } + /* end of string is okay */ + name->end = self->index; + return 1; +} + +static int +_FieldNameIterator_item(FieldNameIterator *self, SubString *name) +{ + int bracket_seen = 0; + Py_UCS4 c; + + name->str = self->str.str; + name->start = self->index; + + /* return everything until ']' */ + while (self->index < self->str.end) { + c = PyUnicode_READ_CHAR(self->str.str, self->index++); + switch (c) { + case ']': + bracket_seen = 1; + break; + default: + continue; + } + break; + } + /* make sure we ended with a ']' */ + if (!bracket_seen) { + PyErr_SetString(PyExc_ValueError, "Missing ']' in format string"); + return 0; + } + + /* end of string is okay */ + /* don't include the ']' */ + name->end = self->index-1; + return 1; +} + +/* returns 0 on error, 1 on non-error termination, and 2 if it returns a value */ +static int +FieldNameIterator_next(FieldNameIterator *self, int *is_attribute, + Py_ssize_t *name_idx, SubString *name) +{ + /* check at end of input */ + if (self->index >= self->str.end) + return 1; + + switch (PyUnicode_READ_CHAR(self->str.str, self->index++)) { + case '.': + *is_attribute = 1; + if (_FieldNameIterator_attr(self, name) == 0) + return 0; + *name_idx = -1; + break; + case '[': + *is_attribute = 0; + if (_FieldNameIterator_item(self, name) == 0) + return 0; + *name_idx = get_integer(name); + if (*name_idx == -1 && PyErr_Occurred()) + return 0; + break; + default: + /* Invalid character follows ']' */ + PyErr_SetString(PyExc_ValueError, "Only '.' or '[' may " + "follow ']' in format field specifier"); + return 0; + } + + /* empty string is an error */ + if (name->start == name->end) { + PyErr_SetString(PyExc_ValueError, "Empty attribute in format string"); + return 0; + } + + return 2; +} + + +/* input: field_name + output: 'first' points to the part before the first '[' or '.' + 'first_idx' is -1 if 'first' is not an integer, otherwise + it's the value of first converted to an integer + 'rest' is an iterator to return the rest +*/ +static int +field_name_split(PyObject *str, Py_ssize_t start, Py_ssize_t end, SubString *first, + Py_ssize_t *first_idx, FieldNameIterator *rest, + AutoNumber *auto_number) +{ + Py_UCS4 c; + Py_ssize_t i = start; + int field_name_is_empty; + int using_numeric_index; + + /* find the part up until the first '.' or '[' */ + while (i < end) { + switch (c = PyUnicode_READ_CHAR(str, i++)) { + case '[': + case '.': + /* backup so that we this character is available to the + "rest" iterator */ + i--; + break; + default: + continue; + } + break; + } + + /* set up the return values */ + SubString_init(first, str, start, i); + FieldNameIterator_init(rest, str, i, end); + + /* see if "first" is an integer, in which case it's used as an index */ + *first_idx = get_integer(first); + if (*first_idx == -1 && PyErr_Occurred()) + return 0; + + field_name_is_empty = first->start >= first->end; + + /* If the field name is omitted or if we have a numeric index + specified, then we're doing numeric indexing into args. */ + using_numeric_index = field_name_is_empty || *first_idx != -1; + + /* We always get here exactly one time for each field we're + processing. And we get here in field order (counting by left + braces). So this is the perfect place to handle automatic field + numbering if the field name is omitted. */ + + /* Check if we need to do the auto-numbering. It's not needed if + we're called from string.Format routines, because it's handled + in that class by itself. */ + if (auto_number) { + /* Initialize our auto numbering state if this is the first + time we're either auto-numbering or manually numbering. */ + if (auto_number->an_state == ANS_INIT && using_numeric_index) + auto_number->an_state = field_name_is_empty ? + ANS_AUTO : ANS_MANUAL; + + /* Make sure our state is consistent with what we're doing + this time through. Only check if we're using a numeric + index. */ + if (using_numeric_index) + if (autonumber_state_error(auto_number->an_state, + field_name_is_empty)) + return 0; + /* Zero length field means we want to do auto-numbering of the + fields. */ + if (field_name_is_empty) + *first_idx = (auto_number->an_field_number)++; + } + + return 1; +} + + +/* + get_field_object returns the object inside {}, before the + format_spec. It handles getindex and getattr lookups and consumes + the entire input string. +*/ +static PyObject * +get_field_object(SubString *input, PyObject *args, PyObject *kwargs, + AutoNumber *auto_number) +{ + PyObject *obj = NULL; + int ok; + int is_attribute; + SubString name; + SubString first; + Py_ssize_t index; + FieldNameIterator rest; + + if (!field_name_split(input->str, input->start, input->end, &first, + &index, &rest, auto_number)) { + goto error; + } + + if (index == -1) { + /* look up in kwargs */ + PyObject *key = SubString_new_object(&first); + if (key == NULL) { + goto error; + } + if (kwargs == NULL) { + PyErr_SetObject(PyExc_KeyError, key); + Py_DECREF(key); + goto error; + } + /* Use PyObject_GetItem instead of PyDict_GetItem because this + code is no longer just used with kwargs. It might be passed + a non-dict when called through format_map. */ + obj = PyObject_GetItem(kwargs, key); + Py_DECREF(key); + if (obj == NULL) { + goto error; + } + } + else { + /* If args is NULL, we have a format string with a positional field + with only kwargs to retrieve it from. This can only happen when + used with format_map(), where positional arguments are not + allowed. */ + if (args == NULL) { + PyErr_SetString(PyExc_ValueError, "Format string contains " + "positional fields"); + goto error; + } + + /* look up in args */ + obj = PySequence_GetItem(args, index); + if (obj == NULL) { + PyErr_Format(PyExc_IndexError, + "Replacement index %zd out of range for positional " + "args tuple", + index); + goto error; + } + } + + /* iterate over the rest of the field_name */ + while ((ok = FieldNameIterator_next(&rest, &is_attribute, &index, + &name)) == 2) { + PyObject *tmp; + + if (is_attribute) + /* getattr lookup "." */ + tmp = getattr(obj, &name); + else + /* getitem lookup "[]" */ + if (index == -1) + tmp = getitem_str(obj, &name); + else + if (PySequence_Check(obj)) + tmp = getitem_sequence(obj, index); + else + /* not a sequence */ + tmp = getitem_idx(obj, index); + if (tmp == NULL) + goto error; + + /* assign to obj */ + Py_DECREF(obj); + obj = tmp; + } + /* end of iterator, this is the non-error case */ + if (ok == 1) + return obj; +error: + Py_XDECREF(obj); + return NULL; +} + +/************************************************************************/ +/***************** Field rendering functions **************************/ +/************************************************************************/ + +/* + render_field() is the main function in this section. It takes the + field object and field specification string generated by + get_field_and_spec, and renders the field into the output string. + + render_field calls fieldobj.__format__(format_spec) method, and + appends to the output. +*/ +static int +render_field(PyObject *fieldobj, SubString *format_spec, _PyUnicodeWriter *writer) +{ + int ok = 0; + PyObject *result = NULL; + PyObject *format_spec_object = NULL; + int (*formatter) (_PyUnicodeWriter*, PyObject *, PyObject *, Py_ssize_t, Py_ssize_t) = NULL; + int err; + + /* If we know the type exactly, skip the lookup of __format__ and just + call the formatter directly. */ + if (PyUnicode_CheckExact(fieldobj)) + formatter = _PyUnicode_FormatAdvancedWriter; + else if (PyLong_CheckExact(fieldobj)) + formatter = _PyLong_FormatAdvancedWriter; + else if (PyFloat_CheckExact(fieldobj)) + formatter = _PyFloat_FormatAdvancedWriter; + else if (PyComplex_CheckExact(fieldobj)) + formatter = _PyComplex_FormatAdvancedWriter; + + if (formatter) { + /* we know exactly which formatter will be called when __format__ is + looked up, so call it directly, instead. */ + err = formatter(writer, fieldobj, format_spec->str, + format_spec->start, format_spec->end); + return (err == 0); + } + else { + /* We need to create an object out of the pointers we have, because + __format__ takes a string/unicode object for format_spec. */ + if (format_spec->str) + format_spec_object = PyUnicode_Substring(format_spec->str, + format_spec->start, + format_spec->end); + else + format_spec_object = PyUnicode_New(0, 0); + if (format_spec_object == NULL) + goto done; + + result = PyObject_Format(fieldobj, format_spec_object); + } + if (result == NULL) + goto done; + + if (_PyUnicodeWriter_WriteStr(writer, result) == -1) + goto done; + ok = 1; + +done: + Py_XDECREF(format_spec_object); + Py_XDECREF(result); + return ok; +} + +static int +parse_field(SubString *str, SubString *field_name, SubString *format_spec, + int *format_spec_needs_expanding, Py_UCS4 *conversion) +{ + /* Note this function works if the field name is zero length, + which is good. Zero length field names are handled later, in + field_name_split. */ + + Py_UCS4 c = 0; + + /* initialize these, as they may be empty */ + *conversion = '\0'; + SubString_init(format_spec, NULL, 0, 0); + + /* Search for the field name. it's terminated by the end of + the string, or a ':' or '!' */ + field_name->str = str->str; + field_name->start = str->start; + while (str->start < str->end) { + switch ((c = PyUnicode_READ_CHAR(str->str, str->start++))) { + case '{': + PyErr_SetString(PyExc_ValueError, "unexpected '{' in field name"); + return 0; + case '[': + for (; str->start < str->end; str->start++) + if (PyUnicode_READ_CHAR(str->str, str->start) == ']') + break; + continue; + case '}': + case ':': + case '!': + break; + default: + continue; + } + break; + } + + field_name->end = str->start - 1; + if (c == '!' || c == ':') { + Py_ssize_t count; + /* we have a format specifier and/or a conversion */ + /* don't include the last character */ + + /* see if there's a conversion specifier */ + if (c == '!') { + /* there must be another character present */ + if (str->start >= str->end) { + PyErr_SetString(PyExc_ValueError, + "end of string while looking for conversion " + "specifier"); + return 0; + } + *conversion = PyUnicode_READ_CHAR(str->str, str->start++); + + if (str->start < str->end) { + c = PyUnicode_READ_CHAR(str->str, str->start++); + if (c == '}') + return 1; + if (c != ':') { + PyErr_SetString(PyExc_ValueError, + "expected ':' after conversion specifier"); + return 0; + } + } + } + format_spec->str = str->str; + format_spec->start = str->start; + count = 1; + while (str->start < str->end) { + switch ((c = PyUnicode_READ_CHAR(str->str, str->start++))) { + case '{': + *format_spec_needs_expanding = 1; + count++; + break; + case '}': + count--; + if (count == 0) { + format_spec->end = str->start - 1; + return 1; + } + break; + default: + break; + } + } + + PyErr_SetString(PyExc_ValueError, "unmatched '{' in format spec"); + return 0; + } + else if (c != '}') { + PyErr_SetString(PyExc_ValueError, "expected '}' before end of string"); + return 0; + } + + return 1; +} + +/************************************************************************/ +/******* Output string allocation and escape-to-markup processing ******/ +/************************************************************************/ + +/* MarkupIterator breaks the string into pieces of either literal + text, or things inside {} that need to be marked up. it is + designed to make it easy to wrap a Python iterator around it, for + use with the Formatter class */ + +typedef struct { + SubString str; +} MarkupIterator; + +static int +MarkupIterator_init(MarkupIterator *self, PyObject *str, + Py_ssize_t start, Py_ssize_t end) +{ + SubString_init(&self->str, str, start, end); + return 1; +} + +/* returns 0 on error, 1 on non-error termination, and 2 if it got a + string (or something to be expanded) */ +static int +MarkupIterator_next(MarkupIterator *self, SubString *literal, + int *field_present, SubString *field_name, + SubString *format_spec, Py_UCS4 *conversion, + int *format_spec_needs_expanding) +{ + int at_end; + Py_UCS4 c = 0; + Py_ssize_t start; + Py_ssize_t len; + int markup_follows = 0; + + /* initialize all of the output variables */ + SubString_init(literal, NULL, 0, 0); + SubString_init(field_name, NULL, 0, 0); + SubString_init(format_spec, NULL, 0, 0); + *conversion = '\0'; + *format_spec_needs_expanding = 0; + *field_present = 0; + + /* No more input, end of iterator. This is the normal exit + path. */ + if (self->str.start >= self->str.end) + return 1; + + start = self->str.start; + + /* First read any literal text. Read until the end of string, an + escaped '{' or '}', or an unescaped '{'. In order to never + allocate memory and so I can just pass pointers around, if + there's an escaped '{' or '}' then we'll return the literal + including the brace, but no format object. The next time + through, we'll return the rest of the literal, skipping past + the second consecutive brace. */ + while (self->str.start < self->str.end) { + switch (c = PyUnicode_READ_CHAR(self->str.str, self->str.start++)) { + case '{': + case '}': + markup_follows = 1; + break; + default: + continue; + } + break; + } + + at_end = self->str.start >= self->str.end; + len = self->str.start - start; + + if ((c == '}') && (at_end || + (c != PyUnicode_READ_CHAR(self->str.str, + self->str.start)))) { + PyErr_SetString(PyExc_ValueError, "Single '}' encountered " + "in format string"); + return 0; + } + if (at_end && c == '{') { + PyErr_SetString(PyExc_ValueError, "Single '{' encountered " + "in format string"); + return 0; + } + if (!at_end) { + if (c == PyUnicode_READ_CHAR(self->str.str, self->str.start)) { + /* escaped } or {, skip it in the input. there is no + markup object following us, just this literal text */ + self->str.start++; + markup_follows = 0; + } + else + len--; + } + + /* record the literal text */ + literal->str = self->str.str; + literal->start = start; + literal->end = start + len; + + if (!markup_follows) + return 2; + + /* this is markup; parse the field */ + *field_present = 1; + if (!parse_field(&self->str, field_name, format_spec, + format_spec_needs_expanding, conversion)) + return 0; + return 2; +} + + +/* do the !r or !s conversion on obj */ +static PyObject * +do_conversion(PyObject *obj, Py_UCS4 conversion) +{ + /* XXX in pre-3.0, do we need to convert this to unicode, since it + might have returned a string? */ + switch (conversion) { + case 'r': + return PyObject_Repr(obj); + case 's': + return PyObject_Str(obj); + case 'a': + return PyObject_ASCII(obj); + default: + if (conversion > 32 && conversion < 127) { + /* It's the ASCII subrange; casting to char is safe + (assuming the execution character set is an ASCII + superset). */ + PyErr_Format(PyExc_ValueError, + "Unknown conversion specifier %c", + (char)conversion); + } else + PyErr_Format(PyExc_ValueError, + "Unknown conversion specifier \\x%x", + (unsigned int)conversion); + return NULL; + } +} + +/* given: + + {field_name!conversion:format_spec} + + compute the result and write it to output. + format_spec_needs_expanding is an optimization. if it's false, + just output the string directly, otherwise recursively expand the + format_spec string. + + field_name is allowed to be zero length, in which case we + are doing auto field numbering. +*/ + +static int +output_markup(SubString *field_name, SubString *format_spec, + int format_spec_needs_expanding, Py_UCS4 conversion, + _PyUnicodeWriter *writer, PyObject *args, PyObject *kwargs, + int recursion_depth, AutoNumber *auto_number) +{ + PyObject *tmp = NULL; + PyObject *fieldobj = NULL; + SubString expanded_format_spec; + SubString *actual_format_spec; + int result = 0; + + /* convert field_name to an object */ + fieldobj = get_field_object(field_name, args, kwargs, auto_number); + if (fieldobj == NULL) + goto done; + + if (conversion != '\0') { + tmp = do_conversion(fieldobj, conversion); + if (tmp == NULL || PyUnicode_READY(tmp) == -1) + goto done; + + /* do the assignment, transferring ownership: fieldobj = tmp */ + Py_DECREF(fieldobj); + fieldobj = tmp; + tmp = NULL; + } + + /* if needed, recurively compute the format_spec */ + if (format_spec_needs_expanding) { + tmp = build_string(format_spec, args, kwargs, recursion_depth-1, + auto_number); + if (tmp == NULL || PyUnicode_READY(tmp) == -1) + goto done; + + /* note that in the case we're expanding the format string, + tmp must be kept around until after the call to + render_field. */ + SubString_init(&expanded_format_spec, tmp, 0, PyUnicode_GET_LENGTH(tmp)); + actual_format_spec = &expanded_format_spec; + } + else + actual_format_spec = format_spec; + + if (render_field(fieldobj, actual_format_spec, writer) == 0) + goto done; + + result = 1; + +done: + Py_XDECREF(fieldobj); + Py_XDECREF(tmp); + + return result; +} + +/* + do_markup is the top-level loop for the format() method. It + searches through the format string for escapes to markup codes, and + calls other functions to move non-markup text to the output, + and to perform the markup to the output. +*/ +static int +do_markup(SubString *input, PyObject *args, PyObject *kwargs, + _PyUnicodeWriter *writer, int recursion_depth, AutoNumber *auto_number) +{ + MarkupIterator iter; + int format_spec_needs_expanding; + int result; + int field_present; + SubString literal; + SubString field_name; + SubString format_spec; + Py_UCS4 conversion; + + MarkupIterator_init(&iter, input->str, input->start, input->end); + while ((result = MarkupIterator_next(&iter, &literal, &field_present, + &field_name, &format_spec, + &conversion, + &format_spec_needs_expanding)) == 2) { + if (literal.end != literal.start) { + if (!field_present && iter.str.start == iter.str.end) + writer->overallocate = 0; + if (_PyUnicodeWriter_WriteSubstring(writer, literal.str, + literal.start, literal.end) < 0) + return 0; + } + + if (field_present) { + if (iter.str.start == iter.str.end) + writer->overallocate = 0; + if (!output_markup(&field_name, &format_spec, + format_spec_needs_expanding, conversion, writer, + args, kwargs, recursion_depth, auto_number)) + return 0; + } + } + return result; +} + + +/* + build_string allocates the output string and then + calls do_markup to do the heavy lifting. +*/ +static PyObject * +build_string(SubString *input, PyObject *args, PyObject *kwargs, + int recursion_depth, AutoNumber *auto_number) +{ + _PyUnicodeWriter writer; + + /* check the recursion level */ + if (recursion_depth <= 0) { + PyErr_SetString(PyExc_ValueError, + "Max string recursion exceeded"); + return NULL; + } + + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + writer.min_length = PyUnicode_GET_LENGTH(input->str) + 100; + + if (!do_markup(input, args, kwargs, &writer, recursion_depth, + auto_number)) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + + return _PyUnicodeWriter_Finish(&writer); +} + +/************************************************************************/ +/*********** main routine ***********************************************/ +/************************************************************************/ + +/* this is the main entry point */ +static PyObject * +do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) +{ + SubString input; + + /* PEP 3101 says only 2 levels, so that + "{0:{1}}".format('abc', 's') # works + "{0:{1:{2}}}".format('abc', 's', '') # fails + */ + int recursion_depth = 2; + + AutoNumber auto_number; + + if (PyUnicode_READY(self) == -1) + return NULL; + + AutoNumber_Init(&auto_number); + SubString_init(&input, self, 0, PyUnicode_GET_LENGTH(self)); + return build_string(&input, args, kwargs, recursion_depth, &auto_number); +} + +static PyObject * +do_string_format_map(PyObject *self, PyObject *obj) +{ + return do_string_format(self, NULL, obj); +} + + +/************************************************************************/ +/*********** formatteriterator ******************************************/ +/************************************************************************/ + +/* This is used to implement string.Formatter.vparse(). It exists so + Formatter can share code with the built in unicode.format() method. + It's really just a wrapper around MarkupIterator that is callable + from Python. */ + +typedef struct { + PyObject_HEAD + PyObject *str; + MarkupIterator it_markup; +} formatteriterobject; + +static void +formatteriter_dealloc(formatteriterobject *it) +{ + Py_XDECREF(it->str); + PyObject_FREE(it); +} + +/* returns a tuple: + (literal, field_name, format_spec, conversion) + + literal is any literal text to output. might be zero length + field_name is the string before the ':'. might be None + format_spec is the string after the ':'. mibht be None + conversion is either None, or the string after the '!' +*/ +static PyObject * +formatteriter_next(formatteriterobject *it) +{ + SubString literal; + SubString field_name; + SubString format_spec; + Py_UCS4 conversion; + int format_spec_needs_expanding; + int field_present; + int result = MarkupIterator_next(&it->it_markup, &literal, &field_present, + &field_name, &format_spec, &conversion, + &format_spec_needs_expanding); + + /* all of the SubString objects point into it->str, so no + memory management needs to be done on them */ + assert(0 <= result && result <= 2); + if (result == 0 || result == 1) + /* if 0, error has already been set, if 1, iterator is empty */ + return NULL; + else { + PyObject *literal_str = NULL; + PyObject *field_name_str = NULL; + PyObject *format_spec_str = NULL; + PyObject *conversion_str = NULL; + PyObject *tuple = NULL; + + literal_str = SubString_new_object(&literal); + if (literal_str == NULL) + goto done; + + field_name_str = SubString_new_object(&field_name); + if (field_name_str == NULL) + goto done; + + /* if field_name is non-zero length, return a string for + format_spec (even if zero length), else return None */ + format_spec_str = (field_present ? + SubString_new_object_or_empty : + SubString_new_object)(&format_spec); + if (format_spec_str == NULL) + goto done; + + /* if the conversion is not specified, return a None, + otherwise create a one length string with the conversion + character */ + if (conversion == '\0') { + conversion_str = Py_None; + Py_INCREF(conversion_str); + } + else + conversion_str = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, + &conversion, 1); + if (conversion_str == NULL) + goto done; + + tuple = PyTuple_Pack(4, literal_str, field_name_str, format_spec_str, + conversion_str); + done: + Py_XDECREF(literal_str); + Py_XDECREF(field_name_str); + Py_XDECREF(format_spec_str); + Py_XDECREF(conversion_str); + return tuple; + } +} + +static PyMethodDef formatteriter_methods[] = { + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject PyFormatterIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "formatteriterator", /* tp_name */ + sizeof(formatteriterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)formatteriter_dealloc, /* tp_dealloc */ + 0, /* tp_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 */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)formatteriter_next, /* tp_iternext */ + formatteriter_methods, /* tp_methods */ + 0, +}; + +/* unicode_formatter_parser is used to implement + string.Formatter.vformat. it parses a string and returns tuples + describing the parsed elements. It's a wrapper around + stringlib/string_format.h's MarkupIterator */ +static PyObject * +formatter_parser(PyObject *ignored, PyObject *self) +{ + formatteriterobject *it; + + if (!PyUnicode_Check(self)) { + PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name); + return NULL; + } + + if (PyUnicode_READY(self) == -1) + return NULL; + + it = PyObject_New(formatteriterobject, &PyFormatterIter_Type); + if (it == NULL) + return NULL; + + /* take ownership, give the object to the iterator */ + Py_INCREF(self); + it->str = self; + + /* initialize the contained MarkupIterator */ + MarkupIterator_init(&it->it_markup, (PyObject*)self, 0, PyUnicode_GET_LENGTH(self)); + return (PyObject *)it; +} + + +/************************************************************************/ +/*********** fieldnameiterator ******************************************/ +/************************************************************************/ + + +/* This is used to implement string.Formatter.vparse(). It parses the + field name into attribute and item values. It's a Python-callable + wrapper around FieldNameIterator */ + +typedef struct { + PyObject_HEAD + PyObject *str; + FieldNameIterator it_field; +} fieldnameiterobject; + +static void +fieldnameiter_dealloc(fieldnameiterobject *it) +{ + Py_XDECREF(it->str); + PyObject_FREE(it); +} + +/* returns a tuple: + (is_attr, value) + is_attr is true if we used attribute syntax (e.g., '.foo') + false if we used index syntax (e.g., '[foo]') + value is an integer or string +*/ +static PyObject * +fieldnameiter_next(fieldnameiterobject *it) +{ + int result; + int is_attr; + Py_ssize_t idx; + SubString name; + + result = FieldNameIterator_next(&it->it_field, &is_attr, + &idx, &name); + if (result == 0 || result == 1) + /* if 0, error has already been set, if 1, iterator is empty */ + return NULL; + else { + PyObject* result = NULL; + PyObject* is_attr_obj = NULL; + PyObject* obj = NULL; + + is_attr_obj = PyBool_FromLong(is_attr); + if (is_attr_obj == NULL) + goto done; + + /* either an integer or a string */ + if (idx != -1) + obj = PyLong_FromSsize_t(idx); + else + obj = SubString_new_object(&name); + if (obj == NULL) + goto done; + + /* return a tuple of values */ + result = PyTuple_Pack(2, is_attr_obj, obj); + + done: + Py_XDECREF(is_attr_obj); + Py_XDECREF(obj); + return result; + } +} + +static PyMethodDef fieldnameiter_methods[] = { + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject PyFieldNameIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "fieldnameiterator", /* tp_name */ + sizeof(fieldnameiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)fieldnameiter_dealloc, /* tp_dealloc */ + 0, /* tp_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 */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)fieldnameiter_next, /* tp_iternext */ + fieldnameiter_methods, /* tp_methods */ + 0}; + +/* unicode_formatter_field_name_split is used to implement + string.Formatter.vformat. it takes a PEP 3101 "field name", and + returns a tuple of (first, rest): "first", the part before the + first '.' or '['; and "rest", an iterator for the rest of the field + name. it's a wrapper around stringlib/string_format.h's + field_name_split. The iterator it returns is a + FieldNameIterator */ +static PyObject * +formatter_field_name_split(PyObject *ignored, PyObject *self) +{ + SubString first; + Py_ssize_t first_idx; + fieldnameiterobject *it; + + PyObject *first_obj = NULL; + PyObject *result = NULL; + + if (!PyUnicode_Check(self)) { + PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name); + return NULL; + } + + if (PyUnicode_READY(self) == -1) + return NULL; + + it = PyObject_New(fieldnameiterobject, &PyFieldNameIter_Type); + if (it == NULL) + return NULL; + + /* take ownership, give the object to the iterator. this is + just to keep the field_name alive */ + Py_INCREF(self); + it->str = self; + + /* Pass in auto_number = NULL. We'll return an empty string for + first_obj in that case. */ + if (!field_name_split((PyObject*)self, 0, PyUnicode_GET_LENGTH(self), + &first, &first_idx, &it->it_field, NULL)) + goto done; + + /* first becomes an integer, if possible; else a string */ + if (first_idx != -1) + first_obj = PyLong_FromSsize_t(first_idx); + else + /* convert "first" into a string object */ + first_obj = SubString_new_object(&first); + if (first_obj == NULL) + goto done; + + /* return a tuple of values */ + result = PyTuple_Pack(2, first_obj, it); + +done: + Py_XDECREF(it); + Py_XDECREF(first_obj); + return result; +} diff --git a/python/Objects/stringlib/unicodedefs.h b/python/Objects/stringlib/unicodedefs.h new file mode 100755 index 0000000..3db5629 --- /dev/null +++ b/python/Objects/stringlib/unicodedefs.h @@ -0,0 +1,32 @@ +#ifndef STRINGLIB_UNICODEDEFS_H +#define STRINGLIB_UNICODEDEFS_H + +/* this is sort of a hack. there's at least one place (formatting + floats) where some stringlib code takes a different path if it's + compiled as unicode. */ +#define STRINGLIB_IS_UNICODE 1 + +#define FASTSEARCH fastsearch +#define STRINGLIB(F) stringlib_##F +#define STRINGLIB_OBJECT PyUnicodeObject +#define STRINGLIB_SIZEOF_CHAR Py_UNICODE_SIZE +#define STRINGLIB_CHAR Py_UNICODE +#define STRINGLIB_TYPE_NAME "unicode" +#define STRINGLIB_PARSE_CODE "U" +#define STRINGLIB_EMPTY unicode_empty +#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE +#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK +#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL +#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL +#define STRINGLIB_STR PyUnicode_AS_UNICODE +#define STRINGLIB_LEN PyUnicode_GET_SIZE +#define STRINGLIB_NEW PyUnicode_FromUnicode +#define STRINGLIB_CHECK PyUnicode_Check +#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact + +#define STRINGLIB_TOSTR PyObject_Str +#define STRINGLIB_TOASCII PyObject_ASCII + +#define STRINGLIB_WANT_CONTAINS_OBJ 1 + +#endif /* !STRINGLIB_UNICODEDEFS_H */ diff --git a/python/Objects/structseq.c b/python/Objects/structseq.c new file mode 100755 index 0000000..c158afc --- /dev/null +++ b/python/Objects/structseq.c @@ -0,0 +1,512 @@ +/* Implementation helper: a struct that looks like a tuple. + See timemodule and posixmodule for example uses. + + The structseq helper is considered an internal CPython implementation + detail. Docs for modules using structseqs should call them + "named tuples" (be sure to include a space between the two + words and add a link back to the term in Docs/glossary.rst). +*/ + +#include "Python.h" +#include "pycore_tupleobject.h" +#include "pycore_object.h" +#include "structmember.h" + +static const char visible_length_key[] = "n_sequence_fields"; +static const char real_length_key[] = "n_fields"; +static const char unnamed_fields_key[] = "n_unnamed_fields"; + +/* Fields with this name have only a field index, not a field name. + They are only allowed for indices < n_visible_fields. */ +char *PyStructSequence_UnnamedField = "unnamed field"; +_Py_IDENTIFIER(n_sequence_fields); +_Py_IDENTIFIER(n_fields); +_Py_IDENTIFIER(n_unnamed_fields); + +#define VISIBLE_SIZE(op) Py_SIZE(op) +#define VISIBLE_SIZE_TP(tp) PyLong_AsSsize_t( \ + _PyDict_GetItemId((tp)->tp_dict, &PyId_n_sequence_fields)) + +#define REAL_SIZE_TP(tp) PyLong_AsSsize_t( \ + _PyDict_GetItemId((tp)->tp_dict, &PyId_n_fields)) +#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op)) + +#define UNNAMED_FIELDS_TP(tp) PyLong_AsSsize_t( \ + _PyDict_GetItemId((tp)->tp_dict, &PyId_n_unnamed_fields)) +#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op)) + + +PyObject * +PyStructSequence_New(PyTypeObject *type) +{ + PyStructSequence *obj; + Py_ssize_t size = REAL_SIZE_TP(type), i; + + obj = PyObject_GC_NewVar(PyStructSequence, type, size); + if (obj == NULL) + return NULL; + /* Hack the size of the variable object, so invisible fields don't appear + to Python code. */ + Py_SIZE(obj) = VISIBLE_SIZE_TP(type); + for (i = 0; i < size; i++) + obj->ob_item[i] = NULL; + + return (PyObject*)obj; +} + +void +PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v) +{ + PyStructSequence_SET_ITEM(op, i, v); +} + +PyObject* +PyStructSequence_GetItem(PyObject* op, Py_ssize_t i) +{ + return PyStructSequence_GET_ITEM(op, i); +} + + +static int +structseq_traverse(PyStructSequence *obj, visitproc visit, void *arg) +{ + Py_ssize_t i, size; + size = REAL_SIZE(obj); + for (i = 0; i < size; ++i) { + Py_VISIT(obj->ob_item[i]); + } + return 0; +} + +static void +structseq_dealloc(PyStructSequence *obj) +{ + Py_ssize_t i, size; + PyTypeObject *tp; + PyObject_GC_UnTrack(obj); + + tp = (PyTypeObject *) Py_TYPE(obj); + size = REAL_SIZE(obj); + for (i = 0; i < size; ++i) { + Py_XDECREF(obj->ob_item[i]); + } + PyObject_GC_Del(obj); + if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + Py_DECREF(tp); + } +} + +/*[clinic input] +class structseq "PyStructSequence *" "NULL" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9d781c6922c77752]*/ + +#include "clinic/structseq.c.h" + +/*[clinic input] +@classmethod +structseq.__new__ as structseq_new + sequence as arg: object + dict: object(c_default="NULL") = {} +[clinic start generated code]*/ + +static PyObject * +structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) +/*[clinic end generated code: output=baa082e788b171da input=90532511101aa3fb]*/ +{ + PyObject *ob; + PyStructSequence *res = NULL; + Py_ssize_t len, min_len, max_len, i, n_unnamed_fields; + + arg = PySequence_Fast(arg, "constructor requires a sequence"); + + if (!arg) { + return NULL; + } + + if (dict && !PyDict_Check(dict)) { + PyErr_Format(PyExc_TypeError, + "%.500s() takes a dict as second arg, if any", + type->tp_name); + Py_DECREF(arg); + return NULL; + } + + len = PySequence_Fast_GET_SIZE(arg); + min_len = VISIBLE_SIZE_TP(type); + max_len = REAL_SIZE_TP(type); + n_unnamed_fields = UNNAMED_FIELDS_TP(type); + + if (min_len != max_len) { + if (len < min_len) { + PyErr_Format(PyExc_TypeError, + "%.500s() takes an at least %zd-sequence (%zd-sequence given)", + type->tp_name, min_len, len); + Py_DECREF(arg); + return NULL; + } + + if (len > max_len) { + PyErr_Format(PyExc_TypeError, + "%.500s() takes an at most %zd-sequence (%zd-sequence given)", + type->tp_name, max_len, len); + Py_DECREF(arg); + return NULL; + } + } + else { + if (len != min_len) { + PyErr_Format(PyExc_TypeError, + "%.500s() takes a %zd-sequence (%zd-sequence given)", + type->tp_name, min_len, len); + Py_DECREF(arg); + return NULL; + } + } + + res = (PyStructSequence*) PyStructSequence_New(type); + if (res == NULL) { + Py_DECREF(arg); + return NULL; + } + for (i = 0; i < len; ++i) { + PyObject *v = PySequence_Fast_GET_ITEM(arg, i); + Py_INCREF(v); + res->ob_item[i] = v; + } + for (; i < max_len; ++i) { + if (dict && (ob = PyDict_GetItemString( + dict, type->tp_members[i-n_unnamed_fields].name))) { + } + else { + ob = Py_None; + } + Py_INCREF(ob); + res->ob_item[i] = ob; + } + + Py_DECREF(arg); + _PyObject_GC_TRACK(res); + return (PyObject*) res; +} + + +static PyObject * +structseq_repr(PyStructSequence *obj) +{ + PyTypeObject *typ = Py_TYPE(obj); + _PyUnicodeWriter writer; + + /* Write "typename(" */ + PyObject *type_name = PyUnicode_DecodeUTF8(typ->tp_name, + strlen(typ->tp_name), + NULL); + if (type_name == NULL) { + return NULL; + } + + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + /* count 5 characters per item: "x=1, " */ + writer.min_length = (PyUnicode_GET_LENGTH(type_name) + 1 + + VISIBLE_SIZE(obj) * 5 + 1); + + if (_PyUnicodeWriter_WriteStr(&writer, type_name) < 0) { + Py_DECREF(type_name); + goto error; + } + Py_DECREF(type_name); + + if (_PyUnicodeWriter_WriteChar(&writer, '(') < 0) { + goto error; + } + + for (Py_ssize_t i=0; i < VISIBLE_SIZE(obj); i++) { + if (i > 0) { + /* Write ", " */ + if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) { + goto error; + } + } + + /* Write "name=repr" */ + const char *name_utf8 = typ->tp_members[i].name; + if (name_utf8 == NULL) { + PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %zd name is NULL" + " for type %.500s", i, typ->tp_name); + goto error; + } + + PyObject *name = PyUnicode_DecodeUTF8(name_utf8, strlen(name_utf8), NULL); + if (name == NULL) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(&writer, name) < 0) { + Py_DECREF(name); + goto error; + } + Py_DECREF(name); + + if (_PyUnicodeWriter_WriteChar(&writer, '=') < 0) { + goto error; + } + + PyObject *value = PyStructSequence_GET_ITEM(obj, i); + assert(value != NULL); + PyObject *repr = PyObject_Repr(value); + if (repr == NULL) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(&writer, repr) < 0) { + Py_DECREF(repr); + goto error; + } + Py_DECREF(repr); + } + + if (_PyUnicodeWriter_WriteChar(&writer, ')') < 0) { + goto error; + } + + return _PyUnicodeWriter_Finish(&writer); + +error: + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + + +static PyObject * +structseq_reduce(PyStructSequence* self, PyObject *Py_UNUSED(ignored)) +{ + PyObject* tup = NULL; + PyObject* dict = NULL; + PyObject* result; + Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields, i; + + n_fields = REAL_SIZE(self); + n_visible_fields = VISIBLE_SIZE(self); + n_unnamed_fields = UNNAMED_FIELDS(self); + tup = _PyTuple_FromArray(self->ob_item, n_visible_fields); + if (!tup) + goto error; + + dict = PyDict_New(); + if (!dict) + goto error; + + for (i = n_visible_fields; i < n_fields; i++) { + const char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name; + if (PyDict_SetItemString(dict, n, self->ob_item[i]) < 0) + goto error; + } + + result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict); + + Py_DECREF(tup); + Py_DECREF(dict); + + return result; + +error: + Py_XDECREF(tup); + Py_XDECREF(dict); + return NULL; +} + +static PyMethodDef structseq_methods[] = { + {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL}, + {NULL, NULL} +}; + +static Py_ssize_t +count_members(PyStructSequence_Desc *desc, Py_ssize_t *n_unnamed_members) { + Py_ssize_t i; + + *n_unnamed_members = 0; + for (i = 0; desc->fields[i].name != NULL; ++i) { + if (desc->fields[i].name == PyStructSequence_UnnamedField) { + (*n_unnamed_members)++; + } + } + return i; +} + +static int +initialize_structseq_dict(PyStructSequence_Desc *desc, PyObject* dict, + Py_ssize_t n_members, Py_ssize_t n_unnamed_members) { + PyObject *v; + +#define SET_DICT_FROM_SIZE(key, value) \ + do { \ + v = PyLong_FromSsize_t(value); \ + if (v == NULL) { \ + return -1; \ + } \ + if (PyDict_SetItemString(dict, key, v) < 0) { \ + Py_DECREF(v); \ + return -1; \ + } \ + Py_DECREF(v); \ + } while (0) + + SET_DICT_FROM_SIZE(visible_length_key, desc->n_in_sequence); + SET_DICT_FROM_SIZE(real_length_key, n_members); + SET_DICT_FROM_SIZE(unnamed_fields_key, n_unnamed_members); + return 0; +} + +static void +initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, + Py_ssize_t n_members) { + Py_ssize_t i, k; + + for (i = k = 0; i < n_members; ++i) { + if (desc->fields[i].name == PyStructSequence_UnnamedField) { + continue; + } + + /* The names and docstrings in these MemberDefs are statically */ + /* allocated so it is expected that they'll outlive the MemberDef */ + members[k].name = desc->fields[i].name; + members[k].type = T_OBJECT; + members[k].offset = offsetof(PyStructSequence, ob_item) + + i * sizeof(PyObject*); + members[k].flags = READONLY; + members[k].doc = desc->fields[i].doc; + k++; + } + members[k].name = NULL; +} + +int +PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) +{ + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + +#ifdef Py_TRACE_REFS + /* if the type object was chained, unchain it first + before overwriting its storage */ + if (type->ob_base.ob_base._ob_next) { + _Py_ForgetReference((PyObject *)type); + } +#endif + + /* PyTypeObject has already been initialized */ + if (Py_REFCNT(type) != 0) { + PyErr_BadInternalCall(); + return -1; + } + + type->tp_name = desc->name; + type->tp_basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); + type->tp_itemsize = sizeof(PyObject *); + type->tp_dealloc = (destructor)structseq_dealloc; + type->tp_repr = (reprfunc)structseq_repr; + type->tp_doc = desc->doc; + type->tp_base = &PyTuple_Type; + type->tp_methods = structseq_methods; + type->tp_new = structseq_new; + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC; + type->tp_traverse = (traverseproc) structseq_traverse; + + n_members = count_members(desc, &n_unnamed_members); + members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + if (members == NULL) { + PyErr_NoMemory(); + return -1; + } + initialize_members(desc, members, n_members); + type->tp_members = members; + + if (PyType_Ready(type) < 0) { + PyMem_FREE(members); + return -1; + } + Py_INCREF(type); + + if (initialize_structseq_dict( + desc, type->tp_dict, n_members, n_unnamed_members) < 0) { + PyMem_FREE(members); + Py_DECREF(type); + return -1; + } + + return 0; +} + +void +PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) +{ + (void)PyStructSequence_InitType2(type, desc); +} + +PyTypeObject * +PyStructSequence_NewType(PyStructSequence_Desc *desc) +{ + PyMemberDef *members; + PyObject *bases; + PyTypeObject *type; + PyType_Slot slots[8]; + PyType_Spec spec; + Py_ssize_t n_members, n_unnamed_members; + + /* Initialize MemberDefs */ + n_members = count_members(desc, &n_unnamed_members); + members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + if (members == NULL) { + PyErr_NoMemory(); + return NULL; + } + initialize_members(desc, members, n_members); + + /* Initialize Slots */ + slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc}; + slots[1] = (PyType_Slot){Py_tp_repr, (reprfunc)structseq_repr}; + slots[2] = (PyType_Slot){Py_tp_doc, (void *)desc->doc}; + slots[3] = (PyType_Slot){Py_tp_methods, structseq_methods}; + slots[4] = (PyType_Slot){Py_tp_new, structseq_new}; + slots[5] = (PyType_Slot){Py_tp_members, members}; + slots[6] = (PyType_Slot){Py_tp_traverse, (traverseproc)structseq_traverse}; + slots[7] = (PyType_Slot){0, 0}; + + /* Initialize Spec */ + /* The name in this PyType_Spec is statically allocated so it is */ + /* expected that it'll outlive the PyType_Spec */ + spec.name = desc->name; + spec.basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); + spec.itemsize = sizeof(PyObject *); + spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC; + spec.slots = slots; + + bases = PyTuple_Pack(1, &PyTuple_Type); + if (bases == NULL) { + PyMem_FREE(members); + return NULL; + } + type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, bases); + Py_DECREF(bases); + PyMem_FREE(members); + if (type == NULL) { + return NULL; + } + + if (initialize_structseq_dict( + desc, type->tp_dict, n_members, n_unnamed_members) < 0) { + Py_DECREF(type); + return NULL; + } + + return type; +} + +int _PyStructSequence_Init(void) +{ + if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL + || _PyUnicode_FromId(&PyId_n_fields) == NULL + || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL) + return -1; + + return 0; +} diff --git a/python/Objects/tupleobject.c b/python/Objects/tupleobject.c new file mode 100755 index 0000000..bd58094 --- /dev/null +++ b/python/Objects/tupleobject.c @@ -0,0 +1,1115 @@ + +/* Tuple object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "pycore_accu.h" + +/*[clinic input] +class tuple "PyTupleObject *" "&PyTuple_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f051ba3cfdf9a189]*/ + +#include "clinic/tupleobject.c.h" + +/* Speed optimization to avoid frequent malloc/free of small tuples */ +#ifndef PyTuple_MAXSAVESIZE +#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */ +#endif +#ifndef PyTuple_MAXFREELIST +#define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */ +#endif + +#if PyTuple_MAXSAVESIZE > 0 +/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty + tuple () of which at most one instance will be allocated. +*/ +static PyTupleObject *free_list[PyTuple_MAXSAVESIZE]; +static int numfree[PyTuple_MAXSAVESIZE]; +#endif +#ifdef COUNT_ALLOCS +Py_ssize_t _Py_fast_tuple_allocs; +Py_ssize_t _Py_tuple_zero_allocs; +#endif + +/* Debug statistic to count GC tracking of tuples. + Please note that tuples are only untracked when considered by the GC, and + many of them will be dead before. Therefore, a tracking rate close to 100% + does not necessarily prove that the heuristic is inefficient. +*/ +#ifdef SHOW_TRACK_COUNT +static Py_ssize_t count_untracked = 0; +static Py_ssize_t count_tracked = 0; + +static void +show_track(void) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (!interp->config.show_alloc_count) { + return; + } + + fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n", + count_tracked + count_untracked); + fprintf(stderr, "Tuples tracked by the GC: %" PY_FORMAT_SIZE_T + "d\n", count_tracked); + fprintf(stderr, "%.2f%% tuple tracking rate\n\n", + (100.0*count_tracked/(count_untracked+count_tracked))); +} +#endif + +/* Print summary info about the state of the optimized allocator */ +void +_PyTuple_DebugMallocStats(FILE *out) +{ +#if PyTuple_MAXSAVESIZE > 0 + int i; + char buf[128]; + for (i = 1; i < PyTuple_MAXSAVESIZE; i++) { + PyOS_snprintf(buf, sizeof(buf), + "free %d-sized PyTupleObject", i); + _PyDebugAllocatorStats(out, + buf, + numfree[i], _PyObject_VAR_SIZE(&PyTuple_Type, i)); + } +#endif +} + +PyObject * +PyTuple_New(Py_ssize_t size) +{ + PyTupleObject *op; + Py_ssize_t i; + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } +#if PyTuple_MAXSAVESIZE > 0 + if (size == 0 && free_list[0]) { + op = free_list[0]; + Py_INCREF(op); +#ifdef COUNT_ALLOCS + _Py_tuple_zero_allocs++; +#endif + return (PyObject *) op; + } + if (size < PyTuple_MAXSAVESIZE && (op = free_list[size]) != NULL) { + free_list[size] = (PyTupleObject *) op->ob_item[0]; + numfree[size]--; +#ifdef COUNT_ALLOCS + _Py_fast_tuple_allocs++; +#endif + /* Inline PyObject_InitVar */ +#ifdef Py_TRACE_REFS + Py_SIZE(op) = size; + Py_TYPE(op) = &PyTuple_Type; +#endif + _Py_NewReference((PyObject *)op); + } + else +#endif + { + /* Check for overflow */ + if ((size_t)size > ((size_t)PY_SSIZE_T_MAX - sizeof(PyTupleObject) - + sizeof(PyObject *)) / sizeof(PyObject *)) { + return PyErr_NoMemory(); + } + op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size); + if (op == NULL) + return NULL; + } + for (i=0; i < size; i++) + op->ob_item[i] = NULL; +#if PyTuple_MAXSAVESIZE > 0 + if (size == 0) { + free_list[0] = op; + ++numfree[0]; + Py_INCREF(op); /* extra INCREF so that this is never freed */ + } +#endif +#ifdef SHOW_TRACK_COUNT + count_tracked++; +#endif + _PyObject_GC_TRACK(op); + return (PyObject *) op; +} + +Py_ssize_t +PyTuple_Size(PyObject *op) +{ + if (!PyTuple_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + else + return Py_SIZE(op); +} + +PyObject * +PyTuple_GetItem(PyObject *op, Py_ssize_t i) +{ + if (!PyTuple_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + if (i < 0 || i >= Py_SIZE(op)) { + PyErr_SetString(PyExc_IndexError, "tuple index out of range"); + return NULL; + } + return ((PyTupleObject *)op) -> ob_item[i]; +} + +int +PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) +{ + PyObject **p; + if (!PyTuple_Check(op) || op->ob_refcnt != 1) { + Py_XDECREF(newitem); + PyErr_BadInternalCall(); + return -1; + } + if (i < 0 || i >= Py_SIZE(op)) { + Py_XDECREF(newitem); + PyErr_SetString(PyExc_IndexError, + "tuple assignment index out of range"); + return -1; + } + p = ((PyTupleObject *)op) -> ob_item + i; + Py_XSETREF(*p, newitem); + return 0; +} + +void +_PyTuple_MaybeUntrack(PyObject *op) +{ + PyTupleObject *t; + Py_ssize_t i, n; + + if (!PyTuple_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op)) + return; + t = (PyTupleObject *) op; + n = Py_SIZE(t); + for (i = 0; i < n; i++) { + PyObject *elt = PyTuple_GET_ITEM(t, i); + /* Tuple with NULL elements aren't + fully constructed, don't untrack + them yet. */ + if (!elt || + _PyObject_GC_MAY_BE_TRACKED(elt)) + return; + } +#ifdef SHOW_TRACK_COUNT + count_tracked--; + count_untracked++; +#endif + _PyObject_GC_UNTRACK(op); +} + +PyObject * +PyTuple_Pack(Py_ssize_t n, ...) +{ + Py_ssize_t i; + PyObject *o; + PyObject *result; + PyObject **items; + va_list vargs; + + va_start(vargs, n); + result = PyTuple_New(n); + if (result == NULL) { + va_end(vargs); + return NULL; + } + items = ((PyTupleObject *)result)->ob_item; + for (i = 0; i < n; i++) { + o = va_arg(vargs, PyObject *); + Py_INCREF(o); + items[i] = o; + } + va_end(vargs); + return result; +} + + +/* Methods */ + +static void +tupledealloc(PyTupleObject *op) +{ + Py_ssize_t i; + Py_ssize_t len = Py_SIZE(op); + PyObject_GC_UnTrack(op); + Py_TRASHCAN_BEGIN(op, tupledealloc) + if (len > 0) { + i = len; + while (--i >= 0) + Py_XDECREF(op->ob_item[i]); +#if PyTuple_MAXSAVESIZE > 0 + if (len < PyTuple_MAXSAVESIZE && + numfree[len] < PyTuple_MAXFREELIST && + Py_TYPE(op) == &PyTuple_Type) + { + op->ob_item[0] = (PyObject *) free_list[len]; + numfree[len]++; + free_list[len] = op; + goto done; /* return */ + } +#endif + } + Py_TYPE(op)->tp_free((PyObject *)op); +done: + Py_TRASHCAN_END +} + +static PyObject * +tuplerepr(PyTupleObject *v) +{ + Py_ssize_t i, n; + _PyUnicodeWriter writer; + + n = Py_SIZE(v); + if (n == 0) + return PyUnicode_FromString("()"); + + /* While not mutable, it is still possible to end up with a cycle in a + tuple through an object that stores itself within a tuple (and thus + infinitely asks for the repr of itself). This should only be + possible within a type. */ + i = Py_ReprEnter((PyObject *)v); + if (i != 0) { + return i > 0 ? PyUnicode_FromString("(...)") : NULL; + } + + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + if (Py_SIZE(v) > 1) { + /* "(" + "1" + ", 2" * (len - 1) + ")" */ + writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1; + } + else { + /* "(1,)" */ + writer.min_length = 4; + } + + if (_PyUnicodeWriter_WriteChar(&writer, '(') < 0) + goto error; + + /* Do repr() on each element. */ + for (i = 0; i < n; ++i) { + PyObject *s; + + if (i > 0) { + if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) + goto error; + } + + s = PyObject_Repr(v->ob_item[i]); + if (s == NULL) + goto error; + + if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) { + Py_DECREF(s); + goto error; + } + Py_DECREF(s); + } + + writer.overallocate = 0; + if (n > 1) { + if (_PyUnicodeWriter_WriteChar(&writer, ')') < 0) + goto error; + } + else { + if (_PyUnicodeWriter_WriteASCIIString(&writer, ",)", 2) < 0) + goto error; + } + + Py_ReprLeave((PyObject *)v); + return _PyUnicodeWriter_Finish(&writer); + +error: + _PyUnicodeWriter_Dealloc(&writer); + Py_ReprLeave((PyObject *)v); + return NULL; +} + + +/* Hash for tuples. This is a slightly simplified version of the xxHash + non-cryptographic hash: + - we do not use any parallellism, there is only 1 accumulator. + - we drop the final mixing since this is just a permutation of the + output space: it does not help against collisions. + - at the end, we mangle the length with a single constant. + For the xxHash specification, see + https://github.com/Cyan4973/xxHash/blob/master/doc/xxhash_spec.md + + Below are the official constants from the xxHash specification. Optimizing + compilers should emit a single "rotate" instruction for the + _PyHASH_XXROTATE() expansion. If that doesn't happen for some important + platform, the macro could be changed to expand to a platform-specific rotate + spelling instead. +*/ +#if SIZEOF_PY_UHASH_T > 4 +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL) +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL) +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL) +#define _PyHASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */ +#else +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL) +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL) +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL) +#define _PyHASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */ +#endif + +/* Tests have shown that it's not worth to cache the hash value, see + https://bugs.python.org/issue9685 */ +static Py_hash_t +tuplehash(PyTupleObject *v) +{ + Py_ssize_t i, len = Py_SIZE(v); + PyObject **item = v->ob_item; + + Py_uhash_t acc = _PyHASH_XXPRIME_5; + for (i = 0; i < len; i++) { + Py_uhash_t lane = PyObject_Hash(item[i]); + if (lane == (Py_uhash_t)-1) { + return -1; + } + acc += lane * _PyHASH_XXPRIME_2; + acc = _PyHASH_XXROTATE(acc); + acc *= _PyHASH_XXPRIME_1; + } + + /* Add input length, mangled to keep the historical value of hash(()). */ + acc += len ^ (_PyHASH_XXPRIME_5 ^ 3527539UL); + + if (acc == (Py_uhash_t)-1) { + return 1546275796; + } + return acc; +} + +static Py_ssize_t +tuplelength(PyTupleObject *a) +{ + return Py_SIZE(a); +} + +static int +tuplecontains(PyTupleObject *a, PyObject *el) +{ + Py_ssize_t i; + int cmp; + + for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) + cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i), + Py_EQ); + return cmp; +} + +static PyObject * +tupleitem(PyTupleObject *a, Py_ssize_t i) +{ + if (i < 0 || i >= Py_SIZE(a)) { + PyErr_SetString(PyExc_IndexError, "tuple index out of range"); + return NULL; + } + Py_INCREF(a->ob_item[i]); + return a->ob_item[i]; +} + +PyObject * +_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyTupleObject *tuple = (PyTupleObject *)PyTuple_New(n); + if (tuple == NULL) { + return NULL; + } + PyObject **dst = tuple->ob_item; + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *item = src[i]; + Py_INCREF(item); + dst[i] = item; + } + return (PyObject *)tuple; +} + +static PyObject * +tupleslice(PyTupleObject *a, Py_ssize_t ilow, + Py_ssize_t ihigh) +{ + if (ilow < 0) + ilow = 0; + if (ihigh > Py_SIZE(a)) + ihigh = Py_SIZE(a); + if (ihigh < ilow) + ihigh = ilow; + if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) { + Py_INCREF(a); + return (PyObject *)a; + } + return _PyTuple_FromArray(a->ob_item + ilow, ihigh - ilow); +} + +PyObject * +PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j) +{ + if (op == NULL || !PyTuple_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return tupleslice((PyTupleObject *)op, i, j); +} + +static PyObject * +tupleconcat(PyTupleObject *a, PyObject *bb) +{ + Py_ssize_t size; + Py_ssize_t i; + PyObject **src, **dest; + PyTupleObject *np; + if (Py_SIZE(a) == 0 && PyTuple_CheckExact(bb)) { + Py_INCREF(bb); + return bb; + } + if (!PyTuple_Check(bb)) { + PyErr_Format(PyExc_TypeError, + "can only concatenate tuple (not \"%.200s\") to tuple", + Py_TYPE(bb)->tp_name); + return NULL; + } +#define b ((PyTupleObject *)bb) + if (Py_SIZE(b) == 0 && PyTuple_CheckExact(a)) { + Py_INCREF(a); + return (PyObject *)a; + } + if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) + return PyErr_NoMemory(); + size = Py_SIZE(a) + Py_SIZE(b); + np = (PyTupleObject *) PyTuple_New(size); + if (np == NULL) { + return NULL; + } + src = a->ob_item; + dest = np->ob_item; + for (i = 0; i < Py_SIZE(a); i++) { + PyObject *v = src[i]; + Py_INCREF(v); + dest[i] = v; + } + src = b->ob_item; + dest = np->ob_item + Py_SIZE(a); + for (i = 0; i < Py_SIZE(b); i++) { + PyObject *v = src[i]; + Py_INCREF(v); + dest[i] = v; + } + return (PyObject *)np; +#undef b +} + +static PyObject * +tuplerepeat(PyTupleObject *a, Py_ssize_t n) +{ + Py_ssize_t i, j; + Py_ssize_t size; + PyTupleObject *np; + PyObject **p, **items; + if (n < 0) + n = 0; + if (Py_SIZE(a) == 0 || n == 1) { + if (PyTuple_CheckExact(a)) { + /* Since tuples are immutable, we can return a shared + copy in this case */ + Py_INCREF(a); + return (PyObject *)a; + } + if (Py_SIZE(a) == 0) + return PyTuple_New(0); + } + if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) + return PyErr_NoMemory(); + size = Py_SIZE(a) * n; + np = (PyTupleObject *) PyTuple_New(size); + if (np == NULL) + return NULL; + p = np->ob_item; + items = a->ob_item; + for (i = 0; i < n; i++) { + for (j = 0; j < Py_SIZE(a); j++) { + *p = items[j]; + Py_INCREF(*p); + p++; + } + } + return (PyObject *) np; +} + +/*[clinic input] +tuple.index + + value: object + start: slice_index(accept={int}) = 0 + stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize + / + +Return first index of value. + +Raises ValueError if the value is not present. +[clinic start generated code]*/ + +static PyObject * +tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start, + Py_ssize_t stop) +/*[clinic end generated code: output=07b6f9f3cb5c33eb input=fb39e9874a21fe3f]*/ +{ + Py_ssize_t i; + + if (start < 0) { + start += Py_SIZE(self); + if (start < 0) + start = 0; + } + if (stop < 0) { + stop += Py_SIZE(self); + } + else if (stop > Py_SIZE(self)) { + stop = Py_SIZE(self); + } + for (i = start; i < stop; i++) { + int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ); + if (cmp > 0) + return PyLong_FromSsize_t(i); + else if (cmp < 0) + return NULL; + } + PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in tuple"); + return NULL; +} + +/*[clinic input] +tuple.count + + value: object + / + +Return number of occurrences of value. +[clinic start generated code]*/ + +static PyObject * +tuple_count(PyTupleObject *self, PyObject *value) +/*[clinic end generated code: output=aa927affc5a97605 input=531721aff65bd772]*/ +{ + Py_ssize_t count = 0; + Py_ssize_t i; + + for (i = 0; i < Py_SIZE(self); i++) { + int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ); + if (cmp > 0) + count++; + else if (cmp < 0) + return NULL; + } + return PyLong_FromSsize_t(count); +} + +static int +tupletraverse(PyTupleObject *o, visitproc visit, void *arg) +{ + Py_ssize_t i; + + for (i = Py_SIZE(o); --i >= 0; ) + Py_VISIT(o->ob_item[i]); + return 0; +} + +static PyObject * +tuplerichcompare(PyObject *v, PyObject *w, int op) +{ + PyTupleObject *vt, *wt; + Py_ssize_t i; + Py_ssize_t vlen, wlen; + + if (!PyTuple_Check(v) || !PyTuple_Check(w)) + Py_RETURN_NOTIMPLEMENTED; + + vt = (PyTupleObject *)v; + wt = (PyTupleObject *)w; + + vlen = Py_SIZE(vt); + wlen = Py_SIZE(wt); + + /* Note: the corresponding code for lists has an "early out" test + * here when op is EQ or NE and the lengths differ. That pays there, + * but Tim was unable to find any real code where EQ/NE tuple + * compares don't have the same length, so testing for it here would + * have cost without benefit. + */ + + /* Search for the first index where items are different. + * Note that because tuples are immutable, it's safe to reuse + * vlen and wlen across the comparison calls. + */ + for (i = 0; i < vlen && i < wlen; i++) { + int k = PyObject_RichCompareBool(vt->ob_item[i], + wt->ob_item[i], Py_EQ); + if (k < 0) + return NULL; + if (!k) + break; + } + + if (i >= vlen || i >= wlen) { + /* No more items to compare -- compare sizes */ + Py_RETURN_RICHCOMPARE(vlen, wlen, op); + } + + /* We have an item that differs -- shortcuts for EQ/NE */ + if (op == Py_EQ) { + Py_RETURN_FALSE; + } + if (op == Py_NE) { + Py_RETURN_TRUE; + } + + /* Compare the final item again using the proper operator */ + return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op); +} + +static PyObject * +tuple_subtype_new(PyTypeObject *type, PyObject *iterable); + +/*[clinic input] +@classmethod +tuple.__new__ as tuple_new + iterable: object(c_default="NULL") = () + / + +Built-in immutable sequence. + +If no argument is given, the constructor returns an empty tuple. +If iterable is specified the tuple is initialized from iterable's items. + +If the argument is a tuple, the return value is the same object. +[clinic start generated code]*/ + +static PyObject * +tuple_new_impl(PyTypeObject *type, PyObject *iterable) +/*[clinic end generated code: output=4546d9f0d469bce7 input=86963bcde633b5a2]*/ +{ + if (type != &PyTuple_Type) + return tuple_subtype_new(type, iterable); + + if (iterable == NULL) + return PyTuple_New(0); + else + return PySequence_Tuple(iterable); +} + +static PyObject * +tuple_subtype_new(PyTypeObject *type, PyObject *iterable) +{ + PyObject *tmp, *newobj, *item; + Py_ssize_t i, n; + + assert(PyType_IsSubtype(type, &PyTuple_Type)); + tmp = tuple_new_impl(&PyTuple_Type, iterable); + if (tmp == NULL) + return NULL; + assert(PyTuple_Check(tmp)); + newobj = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp)); + if (newobj == NULL) { + Py_DECREF(tmp); + return NULL; + } + for (i = 0; i < n; i++) { + item = PyTuple_GET_ITEM(tmp, i); + Py_INCREF(item); + PyTuple_SET_ITEM(newobj, i, item); + } + Py_DECREF(tmp); + return newobj; +} + +static PySequenceMethods tuple_as_sequence = { + (lenfunc)tuplelength, /* sq_length */ + (binaryfunc)tupleconcat, /* sq_concat */ + (ssizeargfunc)tuplerepeat, /* sq_repeat */ + (ssizeargfunc)tupleitem, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)tuplecontains, /* sq_contains */ +}; + +static PyObject* +tuplesubscript(PyTupleObject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += PyTuple_GET_SIZE(self); + return tupleitem(self, i); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength, i; + size_t cur; + PyObject* result; + PyObject* it; + PyObject **src, **dest; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelength = PySlice_AdjustIndices(PyTuple_GET_SIZE(self), &start, + &stop, step); + + if (slicelength <= 0) { + return PyTuple_New(0); + } + else if (start == 0 && step == 1 && + slicelength == PyTuple_GET_SIZE(self) && + PyTuple_CheckExact(self)) { + Py_INCREF(self); + return (PyObject *)self; + } + else { + result = PyTuple_New(slicelength); + if (!result) return NULL; + + src = self->ob_item; + dest = ((PyTupleObject *)result)->ob_item; + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + it = src[cur]; + Py_INCREF(it); + dest[i] = it; + } + + return result; + } + } + else { + PyErr_Format(PyExc_TypeError, + "tuple indices must be integers or slices, not %.200s", + Py_TYPE(item)->tp_name); + return NULL; + } +} + +/*[clinic input] +tuple.__getnewargs__ +[clinic start generated code]*/ + +static PyObject * +tuple___getnewargs___impl(PyTupleObject *self) +/*[clinic end generated code: output=25e06e3ee56027e2 input=1aeb4b286a21639a]*/ +{ + return Py_BuildValue("(N)", tupleslice(self, 0, Py_SIZE(self))); +} + +static PyMethodDef tuple_methods[] = { + TUPLE___GETNEWARGS___METHODDEF + TUPLE_INDEX_METHODDEF + TUPLE_COUNT_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyMappingMethods tuple_as_mapping = { + (lenfunc)tuplelength, + (binaryfunc)tuplesubscript, + 0 +}; + +static PyObject *tuple_iter(PyObject *seq); + +PyTypeObject PyTuple_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "tuple", + sizeof(PyTupleObject) - sizeof(PyObject *), + sizeof(PyObject *), + (destructor)tupledealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)tuplerepr, /* tp_repr */ + 0, /* tp_as_number */ + &tuple_as_sequence, /* tp_as_sequence */ + &tuple_as_mapping, /* tp_as_mapping */ + (hashfunc)tuplehash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */ + tuple_new__doc__, /* tp_doc */ + (traverseproc)tupletraverse, /* tp_traverse */ + 0, /* tp_clear */ + tuplerichcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + tuple_iter, /* tp_iter */ + 0, /* tp_iternext */ + tuple_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + tuple_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +/* The following function breaks the notion that tuples are immutable: + it changes the size of a tuple. We get away with this only if there + is only one module referencing the object. You can also think of it + as creating a new tuple object and destroying the old one, only more + efficiently. In any case, don't use this if the tuple may already be + known to some other part of the code. */ + +int +_PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) +{ + PyTupleObject *v; + PyTupleObject *sv; + Py_ssize_t i; + Py_ssize_t oldsize; + + v = (PyTupleObject *) *pv; + if (v == NULL || Py_TYPE(v) != &PyTuple_Type || + (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) { + *pv = 0; + Py_XDECREF(v); + PyErr_BadInternalCall(); + return -1; + } + oldsize = Py_SIZE(v); + if (oldsize == newsize) + return 0; + + if (oldsize == 0) { + /* Empty tuples are often shared, so we should never + resize them in-place even if we do own the only + (current) reference */ + Py_DECREF(v); + *pv = PyTuple_New(newsize); + return *pv == NULL ? -1 : 0; + } + + /* XXX UNREF/NEWREF interface should be more symmetrical */ + _Py_DEC_REFTOTAL; + if (_PyObject_GC_IS_TRACKED(v)) + _PyObject_GC_UNTRACK(v); + _Py_ForgetReference((PyObject *) v); + /* DECREF items deleted by shrinkage */ + for (i = newsize; i < oldsize; i++) { + Py_CLEAR(v->ob_item[i]); + } + sv = PyObject_GC_Resize(PyTupleObject, v, newsize); + if (sv == NULL) { + *pv = NULL; + PyObject_GC_Del(v); + return -1; + } + _Py_NewReference((PyObject *) sv); + /* Zero out items added by growing */ + if (newsize > oldsize) + memset(&sv->ob_item[oldsize], 0, + sizeof(*sv->ob_item) * (newsize - oldsize)); + *pv = (PyObject *) sv; + _PyObject_GC_TRACK(sv); + return 0; +} + +int +PyTuple_ClearFreeList(void) +{ + int freelist_size = 0; +#if PyTuple_MAXSAVESIZE > 0 + int i; + for (i = 1; i < PyTuple_MAXSAVESIZE; i++) { + PyTupleObject *p, *q; + p = free_list[i]; + freelist_size += numfree[i]; + free_list[i] = NULL; + numfree[i] = 0; + while (p) { + q = p; + p = (PyTupleObject *)(p->ob_item[0]); + PyObject_GC_Del(q); + } + } +#endif + return freelist_size; +} + +void +PyTuple_Fini(void) +{ +#if PyTuple_MAXSAVESIZE > 0 + /* empty tuples are used all over the place and applications may + * rely on the fact that an empty tuple is a singleton. */ + Py_CLEAR(free_list[0]); + + (void)PyTuple_ClearFreeList(); +#endif +#ifdef SHOW_TRACK_COUNT + show_track(); +#endif +} + +/*********************** Tuple Iterator **************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ +} tupleiterobject; + +static void +tupleiter_dealloc(tupleiterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +tupleiter_next(tupleiterobject *it) +{ + PyTupleObject *seq; + PyObject *item; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) + return NULL; + assert(PyTuple_Check(seq)); + + if (it->it_index < PyTuple_GET_SIZE(seq)) { + item = PyTuple_GET_ITEM(seq, it->it_index); + ++it->it_index; + Py_INCREF(item); + return item; + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len = 0; + if (it->it_seq) + len = PyTuple_GET_SIZE(it->it_seq) - it->it_index; + return PyLong_FromSsize_t(len); +} + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); + +static PyObject * +tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + if (it->it_seq) + return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + it->it_seq, it->it_index); + else + return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); +} + +static PyObject * +tupleiter_setstate(tupleiterobject *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyTuple_GET_SIZE(it->it_seq)) + index = PyTuple_GET_SIZE(it->it_seq); /* exhausted iterator */ + it->it_index = index; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef tupleiter_methods[] = { + {"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)tupleiter_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)tupleiter_setstate, METH_O, setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyTupleIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "tuple_iterator", /* tp_name */ + sizeof(tupleiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)tupleiter_dealloc, /* tp_dealloc */ + 0, /* tp_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)tupleiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)tupleiter_next, /* tp_iternext */ + tupleiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +tuple_iter(PyObject *seq) +{ + tupleiterobject *it; + + if (!PyTuple_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = (PyTupleObject *)seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} diff --git a/python/Objects/typeobject.c b/python/Objects/typeobject.c new file mode 100755 index 0000000..6fbeac2 --- /dev/null +++ b/python/Objects/typeobject.c @@ -0,0 +1,8026 @@ +/* Type object implementation */ + +#include "Python.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "frameobject.h" +#include "structmember.h" + +#include + +/*[clinic input] +class type "PyTypeObject *" "&PyType_Type" +class object "PyObject *" "&PyBaseObject_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b94608d231c434b]*/ + +#include "clinic/typeobject.c.h" + +/* Support type attribute cache */ + +/* The cache can keep references to the names alive for longer than + they normally would. This is why the maximum size is limited to + MCACHE_MAX_ATTR_SIZE, since it might be a problem if very large + strings are used as attribute names. */ +#define MCACHE_MAX_ATTR_SIZE 100 +#define MCACHE_SIZE_EXP 12 +#define MCACHE_HASH(version, name_hash) \ + (((unsigned int)(version) ^ (unsigned int)(name_hash)) \ + & ((1 << MCACHE_SIZE_EXP) - 1)) + +#define MCACHE_HASH_METHOD(type, name) \ + MCACHE_HASH((type)->tp_version_tag, \ + ((PyASCIIObject *)(name))->hash) +#define MCACHE_CACHEABLE_NAME(name) \ + PyUnicode_CheckExact(name) && \ + PyUnicode_IS_READY(name) && \ + PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE + +struct method_cache_entry { + unsigned int version; + PyObject *name; /* reference to exactly a str or None */ + PyObject *value; /* borrowed */ +}; + +static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP]; +static unsigned int next_version_tag = 0; + +#define MCACHE_STATS 0 + +#if MCACHE_STATS +static size_t method_cache_hits = 0; +static size_t method_cache_misses = 0; +static size_t method_cache_collisions = 0; +#endif + +/* alphabetical order */ +_Py_IDENTIFIER(__abstractmethods__); +_Py_IDENTIFIER(__class__); +_Py_IDENTIFIER(__class_getitem__); +_Py_IDENTIFIER(__delitem__); +_Py_IDENTIFIER(__dict__); +_Py_IDENTIFIER(__doc__); +_Py_IDENTIFIER(__getattribute__); +_Py_IDENTIFIER(__getitem__); +_Py_IDENTIFIER(__hash__); +_Py_IDENTIFIER(__init_subclass__); +_Py_IDENTIFIER(__len__); +_Py_IDENTIFIER(__module__); +_Py_IDENTIFIER(__name__); +_Py_IDENTIFIER(__new__); +_Py_IDENTIFIER(__set_name__); +_Py_IDENTIFIER(__setitem__); +_Py_IDENTIFIER(builtins); + +static PyObject * +slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + +static void +clear_slotdefs(void); + +static PyObject * +lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound); + +static int +slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value); + +/* + * finds the beginning of the docstring's introspection signature. + * if present, returns a pointer pointing to the first '('. + * otherwise returns NULL. + * + * doesn't guarantee that the signature is valid, only that it + * has a valid prefix. (the signature must also pass skip_signature.) + */ +static const char * +find_signature(const char *name, const char *doc) +{ + const char *dot; + size_t length; + + if (!doc) + return NULL; + + assert(name != NULL); + + /* for dotted names like classes, only use the last component */ + dot = strrchr(name, '.'); + if (dot) + name = dot + 1; + + length = strlen(name); + if (strncmp(doc, name, length)) + return NULL; + doc += length; + if (*doc != '(') + return NULL; + return doc; +} + +#define SIGNATURE_END_MARKER ")\n--\n\n" +#define SIGNATURE_END_MARKER_LENGTH 6 +/* + * skips past the end of the docstring's introspection signature. + * (assumes doc starts with a valid signature prefix.) + */ +static const char * +skip_signature(const char *doc) +{ + while (*doc) { + if ((*doc == *SIGNATURE_END_MARKER) && + !strncmp(doc, SIGNATURE_END_MARKER, SIGNATURE_END_MARKER_LENGTH)) + return doc + SIGNATURE_END_MARKER_LENGTH; + if ((*doc == '\n') && (doc[1] == '\n')) + return NULL; + doc++; + } + return NULL; +} + +int +_PyType_CheckConsistency(PyTypeObject *type) +{ +#define CHECK(expr) \ + do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG((PyObject *)type, Py_STRINGIFY(expr)); } } while (0) + + CHECK(!_PyObject_IsFreed((PyObject *)type)); + + if (!(type->tp_flags & Py_TPFLAGS_READY)) { + /* don't check static types before PyType_Ready() */ + return 1; + } + + CHECK(Py_REFCNT(type) >= 1); + CHECK(PyType_Check(type)); + + CHECK(!(type->tp_flags & Py_TPFLAGS_READYING)); + CHECK(type->tp_dict != NULL); + + return 1; +#undef CHECK +} + +static const char * +_PyType_DocWithoutSignature(const char *name, const char *internal_doc) +{ + const char *doc = find_signature(name, internal_doc); + + if (doc) { + doc = skip_signature(doc); + if (doc) + return doc; + } + return internal_doc; +} + +PyObject * +_PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc) +{ + const char *doc = _PyType_DocWithoutSignature(name, internal_doc); + + if (!doc || *doc == '\0') { + Py_RETURN_NONE; + } + + return PyUnicode_FromString(doc); +} + +PyObject * +_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc) +{ + const char *start = find_signature(name, internal_doc); + const char *end; + + if (start) + end = skip_signature(start); + else + end = NULL; + if (!end) { + Py_RETURN_NONE; + } + + /* back "end" up until it points just past the final ')' */ + end -= SIGNATURE_END_MARKER_LENGTH - 1; + assert((end - start) >= 2); /* should be "()" at least */ + assert(end[-1] == ')'); + assert(end[0] == '\n'); + return PyUnicode_FromStringAndSize(start, end - start); +} + +unsigned int +PyType_ClearCache(void) +{ + Py_ssize_t i; + unsigned int cur_version_tag = next_version_tag - 1; + +#if MCACHE_STATS + size_t total = method_cache_hits + method_cache_collisions + method_cache_misses; + fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n", + method_cache_hits, (int) (100.0 * method_cache_hits / total)); + fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n", + method_cache_misses, (int) (100.0 * method_cache_misses / total)); + fprintf(stderr, "-- Method cache collisions = %zd (%d%%)\n", + method_cache_collisions, (int) (100.0 * method_cache_collisions / total)); + fprintf(stderr, "-- Method cache size = %zd KiB\n", + sizeof(method_cache) / 1024); +#endif + + for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { + method_cache[i].version = 0; + Py_CLEAR(method_cache[i].name); + method_cache[i].value = NULL; + } + next_version_tag = 0; + /* mark all version tags as invalid */ + PyType_Modified(&PyBaseObject_Type); + return cur_version_tag; +} + +void +_PyType_Fini(void) +{ + PyType_ClearCache(); + clear_slotdefs(); +} + +void +PyType_Modified(PyTypeObject *type) +{ + /* Invalidate any cached data for the specified type and all + subclasses. This function is called after the base + classes, mro, or attributes of the type are altered. + + Invariants: + + - Py_TPFLAGS_VALID_VERSION_TAG is never set if + Py_TPFLAGS_HAVE_VERSION_TAG is not set (in case of a + bizarre MRO, see type_mro_modified()). + + - before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type, + it must first be set on all super types. + + This function clears the Py_TPFLAGS_VALID_VERSION_TAG of a + type (so it must first clear it on all subclasses). The + tp_version_tag value is meaningless unless this flag is set. + We don't assign new version tags eagerly, but only as + needed. + */ + PyObject *raw, *ref; + Py_ssize_t i; + + if (!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + return; + + raw = type->tp_subclasses; + if (raw != NULL) { + assert(PyDict_CheckExact(raw)); + i = 0; + while (PyDict_Next(raw, &i, NULL, &ref)) { + assert(PyWeakref_CheckRef(ref)); + ref = PyWeakref_GET_OBJECT(ref); + if (ref != Py_None) { + PyType_Modified((PyTypeObject *)ref); + } + } + } + type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; +} + +static void +type_mro_modified(PyTypeObject *type, PyObject *bases) { + /* + Check that all base classes or elements of the MRO of type are + able to be cached. This function is called after the base + classes or mro of the type are altered. + + Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type + has a custom MRO that includes a type which is not officially + super type, or if the type implements its own mro() method. + + Called from mro_internal, which will subsequently be called on + each subclass when their mro is recursively updated. + */ + Py_ssize_t i, n; + int custom = (Py_TYPE(type) != &PyType_Type); + int unbound; + PyObject *mro_meth = NULL; + PyObject *type_mro_meth = NULL; + + if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) + return; + + if (custom) { + _Py_IDENTIFIER(mro); + mro_meth = lookup_maybe_method( + (PyObject *)type, &PyId_mro, &unbound); + if (mro_meth == NULL) + goto clear; + type_mro_meth = lookup_maybe_method( + (PyObject *)&PyType_Type, &PyId_mro, &unbound); + if (type_mro_meth == NULL) + goto clear; + if (mro_meth != type_mro_meth) + goto clear; + Py_XDECREF(mro_meth); + Py_XDECREF(type_mro_meth); + } + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + PyTypeObject *cls; + + assert(PyType_Check(b)); + cls = (PyTypeObject *)b; + + if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) || + !PyType_IsSubtype(type, cls)) { + goto clear; + } + } + return; + clear: + Py_XDECREF(mro_meth); + Py_XDECREF(type_mro_meth); + type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG| + Py_TPFLAGS_VALID_VERSION_TAG); +} + +static int +assign_version_tag(PyTypeObject *type) +{ + /* Ensure that the tp_version_tag is valid and set + Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this + must first be done on all super classes. Return 0 if this + cannot be done, 1 if Py_TPFLAGS_VALID_VERSION_TAG. + */ + Py_ssize_t i, n; + PyObject *bases; + + if (PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + return 1; + if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) + return 0; + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + return 0; + + type->tp_version_tag = next_version_tag++; + /* for stress-testing: next_version_tag &= 0xFF; */ + + if (type->tp_version_tag == 0) { + /* wrap-around or just starting Python - clear the whole + cache by filling names with references to Py_None. + Values are also set to NULL for added protection, as they + are borrowed reference */ + for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { + method_cache[i].value = NULL; + Py_INCREF(Py_None); + Py_XSETREF(method_cache[i].name, Py_None); + } + /* mark all version tags as invalid */ + PyType_Modified(&PyBaseObject_Type); + return 1; + } + bases = type->tp_bases; + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + assert(PyType_Check(b)); + if (!assign_version_tag((PyTypeObject *)b)) + return 0; + } + type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; + return 1; +} + + +static PyMemberDef type_members[] = { + {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, + {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY}, + {"__flags__", T_ULONG, offsetof(PyTypeObject, tp_flags), READONLY}, + {"__weakrefoffset__", T_PYSSIZET, + offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, + {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY}, + {"__dictoffset__", T_PYSSIZET, + offsetof(PyTypeObject, tp_dictoffset), READONLY}, + {"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY}, + {0} +}; + +static int +check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *name) +{ + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_TypeError, + "can't set %s.%s", type->tp_name, name); + return 0; + } + if (!value) { + PyErr_Format(PyExc_TypeError, + "can't delete %s.%s", type->tp_name, name); + return 0; + } + + if (PySys_Audit("object.__setattr__", "OsO", + type, name, value) < 0) { + return 0; + } + + return 1; +} + +const char * +_PyType_Name(PyTypeObject *type) +{ + const char *s = strrchr(type->tp_name, '.'); + if (s == NULL) { + s = type->tp_name; + } + else { + s++; + } + return s; +} + +static PyObject * +type_name(PyTypeObject *type, void *context) +{ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + PyHeapTypeObject* et = (PyHeapTypeObject*)type; + + Py_INCREF(et->ht_name); + return et->ht_name; + } + else { + return PyUnicode_FromString(_PyType_Name(type)); + } +} + +static PyObject * +type_qualname(PyTypeObject *type, void *context) +{ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + PyHeapTypeObject* et = (PyHeapTypeObject*)type; + Py_INCREF(et->ht_qualname); + return et->ht_qualname; + } + else { + return PyUnicode_FromString(_PyType_Name(type)); + } +} + +static int +type_set_name(PyTypeObject *type, PyObject *value, void *context) +{ + const char *tp_name; + Py_ssize_t name_size; + + if (!check_set_special_type_attr(type, value, "__name__")) + return -1; + if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "can only assign string to %s.__name__, not '%s'", + type->tp_name, Py_TYPE(value)->tp_name); + return -1; + } + + tp_name = PyUnicode_AsUTF8AndSize(value, &name_size); + if (tp_name == NULL) + return -1; + if (strlen(tp_name) != (size_t)name_size) { + PyErr_SetString(PyExc_ValueError, + "type name must not contain null characters"); + return -1; + } + + type->tp_name = tp_name; + Py_INCREF(value); + Py_SETREF(((PyHeapTypeObject*)type)->ht_name, value); + + return 0; +} + +static int +type_set_qualname(PyTypeObject *type, PyObject *value, void *context) +{ + PyHeapTypeObject* et; + + if (!check_set_special_type_attr(type, value, "__qualname__")) + return -1; + if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "can only assign string to %s.__qualname__, not '%s'", + type->tp_name, Py_TYPE(value)->tp_name); + return -1; + } + + et = (PyHeapTypeObject*)type; + Py_INCREF(value); + Py_SETREF(et->ht_qualname, value); + return 0; +} + +static PyObject * +type_module(PyTypeObject *type, void *context) +{ + PyObject *mod; + + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + mod = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___module__); + if (mod == NULL) { + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, "__module__"); + } + return NULL; + } + Py_INCREF(mod); + } + else { + const char *s = strrchr(type->tp_name, '.'); + if (s != NULL) { + mod = PyUnicode_FromStringAndSize( + type->tp_name, (Py_ssize_t)(s - type->tp_name)); + if (mod != NULL) + PyUnicode_InternInPlace(&mod); + } + else { + mod = _PyUnicode_FromId(&PyId_builtins); + Py_XINCREF(mod); + } + } + return mod; +} + +static int +type_set_module(PyTypeObject *type, PyObject *value, void *context) +{ + if (!check_set_special_type_attr(type, value, "__module__")) + return -1; + + PyType_Modified(type); + + return _PyDict_SetItemId(type->tp_dict, &PyId___module__, value); +} + +static PyObject * +type_abstractmethods(PyTypeObject *type, void *context) +{ + PyObject *mod = NULL; + /* type itself has an __abstractmethods__ descriptor (this). Don't return + that. */ + if (type != &PyType_Type) + mod = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___abstractmethods__); + if (!mod) { + if (!PyErr_Occurred()) { + PyObject *message = _PyUnicode_FromId(&PyId___abstractmethods__); + if (message) + PyErr_SetObject(PyExc_AttributeError, message); + } + return NULL; + } + Py_INCREF(mod); + return mod; +} + +static int +type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) +{ + /* __abstractmethods__ should only be set once on a type, in + abc.ABCMeta.__new__, so this function doesn't do anything + special to update subclasses. + */ + int abstract, res; + if (value != NULL) { + abstract = PyObject_IsTrue(value); + if (abstract < 0) + return -1; + res = _PyDict_SetItemId(type->tp_dict, &PyId___abstractmethods__, value); + } + else { + abstract = 0; + res = _PyDict_DelItemId(type->tp_dict, &PyId___abstractmethods__); + if (res && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyObject *message = _PyUnicode_FromId(&PyId___abstractmethods__); + if (message) + PyErr_SetObject(PyExc_AttributeError, message); + return -1; + } + } + if (res == 0) { + PyType_Modified(type); + if (abstract) + type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT; + else + type->tp_flags &= ~Py_TPFLAGS_IS_ABSTRACT; + } + return res; +} + +static PyObject * +type_get_bases(PyTypeObject *type, void *context) +{ + Py_INCREF(type->tp_bases); + return type->tp_bases; +} + +static PyTypeObject *best_base(PyObject *); +static int mro_internal(PyTypeObject *, PyObject **); +static int type_is_subtype_base_chain(PyTypeObject *, PyTypeObject *); +static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, const char *); +static int add_subclass(PyTypeObject*, PyTypeObject*); +static int add_all_subclasses(PyTypeObject *type, PyObject *bases); +static void remove_subclass(PyTypeObject *, PyTypeObject *); +static void remove_all_subclasses(PyTypeObject *type, PyObject *bases); +static void update_all_slots(PyTypeObject *); + +typedef int (*update_callback)(PyTypeObject *, void *); +static int update_subclasses(PyTypeObject *type, PyObject *name, + update_callback callback, void *data); +static int recurse_down_subclasses(PyTypeObject *type, PyObject *name, + update_callback callback, void *data); + +static int +mro_hierarchy(PyTypeObject *type, PyObject *temp) +{ + int res; + PyObject *new_mro, *old_mro; + PyObject *tuple; + PyObject *subclasses; + Py_ssize_t i, n; + + res = mro_internal(type, &old_mro); + if (res <= 0) + /* error / reentrance */ + return res; + new_mro = type->tp_mro; + + if (old_mro != NULL) + tuple = PyTuple_Pack(3, type, new_mro, old_mro); + else + tuple = PyTuple_Pack(2, type, new_mro); + + if (tuple != NULL) + res = PyList_Append(temp, tuple); + else + res = -1; + Py_XDECREF(tuple); + + if (res < 0) { + type->tp_mro = old_mro; + Py_DECREF(new_mro); + return -1; + } + Py_XDECREF(old_mro); + + /* Obtain a copy of subclasses list to iterate over. + + Otherwise type->tp_subclasses might be altered + in the middle of the loop, for example, through a custom mro(), + by invoking type_set_bases on some subclass of the type + which in turn calls remove_subclass/add_subclass on this type. + + Finally, this makes things simple avoiding the need to deal + with dictionary iterators and weak references. + */ + subclasses = type___subclasses___impl(type); + if (subclasses == NULL) + return -1; + n = PyList_GET_SIZE(subclasses); + for (i = 0; i < n; i++) { + PyTypeObject *subclass; + subclass = (PyTypeObject *)PyList_GET_ITEM(subclasses, i); + res = mro_hierarchy(subclass, temp); + if (res < 0) + break; + } + Py_DECREF(subclasses); + + return res; +} + +static int +type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) +{ + int res = 0; + PyObject *temp; + PyObject *old_bases; + PyTypeObject *new_base, *old_base; + Py_ssize_t i; + + if (!check_set_special_type_attr(type, new_bases, "__bases__")) + return -1; + if (!PyTuple_Check(new_bases)) { + PyErr_Format(PyExc_TypeError, + "can only assign tuple to %s.__bases__, not %s", + type->tp_name, Py_TYPE(new_bases)->tp_name); + return -1; + } + if (PyTuple_GET_SIZE(new_bases) == 0) { + PyErr_Format(PyExc_TypeError, + "can only assign non-empty tuple to %s.__bases__, not ()", + type->tp_name); + return -1; + } + for (i = 0; i < PyTuple_GET_SIZE(new_bases); i++) { + PyObject *ob; + PyTypeObject *base; + + ob = PyTuple_GET_ITEM(new_bases, i); + if (!PyType_Check(ob)) { + PyErr_Format(PyExc_TypeError, + "%s.__bases__ must be tuple of classes, not '%s'", + type->tp_name, Py_TYPE(ob)->tp_name); + return -1; + } + + base = (PyTypeObject*)ob; + if (PyType_IsSubtype(base, type) || + /* In case of reentering here again through a custom mro() + the above check is not enough since it relies on + base->tp_mro which would gonna be updated inside + mro_internal only upon returning from the mro(). + + However, base->tp_base has already been assigned (see + below), which in turn may cause an inheritance cycle + through tp_base chain. And this is definitely + not what you want to ever happen. */ + (base->tp_mro != NULL && type_is_subtype_base_chain(base, type))) { + + PyErr_SetString(PyExc_TypeError, + "a __bases__ item causes an inheritance cycle"); + return -1; + } + } + + new_base = best_base(new_bases); + if (new_base == NULL) + return -1; + + if (!compatible_for_assignment(type->tp_base, new_base, "__bases__")) + return -1; + + Py_INCREF(new_bases); + Py_INCREF(new_base); + + old_bases = type->tp_bases; + old_base = type->tp_base; + + type->tp_bases = new_bases; + type->tp_base = new_base; + + temp = PyList_New(0); + if (temp == NULL) + goto bail; + if (mro_hierarchy(type, temp) < 0) + goto undo; + Py_DECREF(temp); + + /* Take no action in case if type->tp_bases has been replaced + through reentrance. */ + if (type->tp_bases == new_bases) { + /* any base that was in __bases__ but now isn't, we + need to remove |type| from its tp_subclasses. + conversely, any class now in __bases__ that wasn't + needs to have |type| added to its subclasses. */ + + /* for now, sod that: just remove from all old_bases, + add to all new_bases */ + remove_all_subclasses(type, old_bases); + res = add_all_subclasses(type, new_bases); + update_all_slots(type); + } + + Py_DECREF(old_bases); + Py_DECREF(old_base); + + assert(_PyType_CheckConsistency(type)); + return res; + + undo: + for (i = PyList_GET_SIZE(temp) - 1; i >= 0; i--) { + PyTypeObject *cls; + PyObject *new_mro, *old_mro = NULL; + + PyArg_UnpackTuple(PyList_GET_ITEM(temp, i), + "", 2, 3, &cls, &new_mro, &old_mro); + /* Do not rollback if cls has a newer version of MRO. */ + if (cls->tp_mro == new_mro) { + Py_XINCREF(old_mro); + cls->tp_mro = old_mro; + Py_DECREF(new_mro); + } + } + Py_DECREF(temp); + + bail: + if (type->tp_bases == new_bases) { + assert(type->tp_base == new_base); + + type->tp_bases = old_bases; + type->tp_base = old_base; + + Py_DECREF(new_bases); + Py_DECREF(new_base); + } + else { + Py_DECREF(old_bases); + Py_DECREF(old_base); + } + + assert(_PyType_CheckConsistency(type)); + return -1; +} + +static PyObject * +type_dict(PyTypeObject *type, void *context) +{ + if (type->tp_dict == NULL) { + Py_RETURN_NONE; + } + return PyDictProxy_New(type->tp_dict); +} + +static PyObject * +type_get_doc(PyTypeObject *type, void *context) +{ + PyObject *result; + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { + return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); + } + result = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___doc__); + if (result == NULL) { + if (!PyErr_Occurred()) { + result = Py_None; + Py_INCREF(result); + } + } + else if (Py_TYPE(result)->tp_descr_get) { + result = Py_TYPE(result)->tp_descr_get(result, NULL, + (PyObject *)type); + } + else { + Py_INCREF(result); + } + return result; +} + +static PyObject * +type_get_text_signature(PyTypeObject *type, void *context) +{ + return _PyType_GetTextSignatureFromInternalDoc(type->tp_name, type->tp_doc); +} + +static int +type_set_doc(PyTypeObject *type, PyObject *value, void *context) +{ + if (!check_set_special_type_attr(type, value, "__doc__")) + return -1; + PyType_Modified(type); + return _PyDict_SetItemId(type->tp_dict, &PyId___doc__, value); +} + +/*[clinic input] +type.__instancecheck__ -> bool + + instance: object + / + +Check if an object is an instance. +[clinic start generated code]*/ + +static int +type___instancecheck___impl(PyTypeObject *self, PyObject *instance) +/*[clinic end generated code: output=08b6bf5f591c3618 input=cdbfeaee82c01a0f]*/ +{ + return _PyObject_RealIsInstance(instance, (PyObject *)self); +} + +/*[clinic input] +type.__subclasscheck__ -> bool + + subclass: object + / + +Check if a class is a subclass. +[clinic start generated code]*/ + +static int +type___subclasscheck___impl(PyTypeObject *self, PyObject *subclass) +/*[clinic end generated code: output=97a4e51694500941 input=071b2ca9e03355f4]*/ +{ + return _PyObject_RealIsSubclass(subclass, (PyObject *)self); +} + + +static PyGetSetDef type_getsets[] = { + {"__name__", (getter)type_name, (setter)type_set_name, NULL}, + {"__qualname__", (getter)type_qualname, (setter)type_set_qualname, NULL}, + {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL}, + {"__module__", (getter)type_module, (setter)type_set_module, NULL}, + {"__abstractmethods__", (getter)type_abstractmethods, + (setter)type_set_abstractmethods, NULL}, + {"__dict__", (getter)type_dict, NULL, NULL}, + {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL}, + {"__text_signature__", (getter)type_get_text_signature, NULL, NULL}, + {0} +}; + +static PyObject * +type_repr(PyTypeObject *type) +{ + PyObject *mod, *name, *rtn; + + mod = type_module(type, NULL); + if (mod == NULL) + PyErr_Clear(); + else if (!PyUnicode_Check(mod)) { + Py_DECREF(mod); + mod = NULL; + } + name = type_qualname(type, NULL); + if (name == NULL) { + Py_XDECREF(mod); + return NULL; + } + + if (mod != NULL && !_PyUnicode_EqualToASCIIId(mod, &PyId_builtins)) + rtn = PyUnicode_FromFormat("", mod, name); + else + rtn = PyUnicode_FromFormat("", type->tp_name); + + Py_XDECREF(mod); + Py_DECREF(name); + return rtn; +} + +static PyObject * +type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if (type->tp_new == NULL) { + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", + type->tp_name); + return NULL; + } + +#ifdef Py_DEBUG + /* type_call() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); +#endif + + obj = type->tp_new(type, args, kwds); + obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL); + if (obj == NULL) + return NULL; + + /* Ugly exception: when the call was type(something), + don't call tp_init on the result. */ + if (type == &PyType_Type && + PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && + (kwds == NULL || + (PyDict_Check(kwds) && PyDict_GET_SIZE(kwds) == 0))) + return obj; + + /* If the returned object is not an instance of type, + it won't be initialized. */ + if (!PyType_IsSubtype(Py_TYPE(obj), type)) + return obj; + + type = Py_TYPE(obj); + if (type->tp_init != NULL) { + int res = type->tp_init(obj, args, kwds); + if (res < 0) { + assert(PyErr_Occurred()); + Py_DECREF(obj); + obj = NULL; + } + else { + assert(!PyErr_Occurred()); + } + } + return obj; +} + +PyObject * +PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) +{ + PyObject *obj; + const size_t size = _PyObject_VAR_SIZE(type, nitems+1); + /* note that we need to add one, for the sentinel */ + + if (PyType_IS_GC(type)) + obj = _PyObject_GC_Malloc(size); + else + obj = (PyObject *)PyObject_MALLOC(size); + + if (obj == NULL) + return PyErr_NoMemory(); + + memset(obj, '\0', size); + + if (type->tp_itemsize == 0) + (void)PyObject_INIT(obj, type); + else + (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); + + if (PyType_IS_GC(type)) + _PyObject_GC_TRACK(obj); + return obj; +} + +PyObject * +PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return type->tp_alloc(type, 0); +} + +/* Helpers for subtyping */ + +static int +traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg) +{ + Py_ssize_t i, n; + PyMemberDef *mp; + + n = Py_SIZE(type); + mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); + for (i = 0; i < n; i++, mp++) { + if (mp->type == T_OBJECT_EX) { + char *addr = (char *)self + mp->offset; + PyObject *obj = *(PyObject **)addr; + if (obj != NULL) { + int err = visit(obj, arg); + if (err) + return err; + } + } + } + return 0; +} + +static int +subtype_traverse(PyObject *self, visitproc visit, void *arg) +{ + PyTypeObject *type, *base; + traverseproc basetraverse; + + /* Find the nearest base with a different tp_traverse, + and traverse slots while we're at it */ + type = Py_TYPE(self); + base = type; + while ((basetraverse = base->tp_traverse) == subtype_traverse) { + if (Py_SIZE(base)) { + int err = traverse_slots(base, self, visit, arg); + if (err) + return err; + } + base = base->tp_base; + assert(base); + } + + if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_GetDictPtr(self); + if (dictptr && *dictptr) + Py_VISIT(*dictptr); + } + + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) + /* For a heaptype, the instances count as references + to the type. Traverse the type so the collector + can find cycles involving this link. */ + Py_VISIT(type); + + if (basetraverse) + return basetraverse(self, visit, arg); + return 0; +} + +static void +clear_slots(PyTypeObject *type, PyObject *self) +{ + Py_ssize_t i, n; + PyMemberDef *mp; + + n = Py_SIZE(type); + mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); + for (i = 0; i < n; i++, mp++) { + if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { + char *addr = (char *)self + mp->offset; + PyObject *obj = *(PyObject **)addr; + if (obj != NULL) { + *(PyObject **)addr = NULL; + Py_DECREF(obj); + } + } + } +} + +static int +subtype_clear(PyObject *self) +{ + PyTypeObject *type, *base; + inquiry baseclear; + + /* Find the nearest base with a different tp_clear + and clear slots while we're at it */ + type = Py_TYPE(self); + base = type; + while ((baseclear = base->tp_clear) == subtype_clear) { + if (Py_SIZE(base)) + clear_slots(base, self); + base = base->tp_base; + assert(base); + } + + /* Clear the instance dict (if any), to break cycles involving only + __dict__ slots (as in the case 'self.__dict__ is self'). */ + if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_GetDictPtr(self); + if (dictptr && *dictptr) + Py_CLEAR(*dictptr); + } + + if (baseclear) + return baseclear(self); + return 0; +} + +static void +subtype_dealloc(PyObject *self) +{ + PyTypeObject *type, *base; + destructor basedealloc; + int has_finalizer; + + /* Extract the type; we expect it to be a heap type */ + type = Py_TYPE(self); + _PyObject_ASSERT((PyObject *)type, type->tp_flags & Py_TPFLAGS_HEAPTYPE); + + /* Test whether the type has GC exactly once */ + + if (!PyType_IS_GC(type)) { + /* A non GC dynamic type allows certain simplifications: + there's no need to call clear_slots(), or DECREF the dict, + or clear weakrefs. */ + + /* Maybe call finalizer; exit early if resurrected */ + if (type->tp_finalize) { + if (PyObject_CallFinalizerFromDealloc(self) < 0) + return; + } + if (type->tp_del) { + type->tp_del(self); + if (self->ob_refcnt > 0) + return; + } + + /* Find the nearest base with a different tp_dealloc */ + base = type; + while ((basedealloc = base->tp_dealloc) == subtype_dealloc) { + base = base->tp_base; + assert(base); + } + + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + + /* Call the base tp_dealloc() */ + assert(basedealloc); + basedealloc(self); + + /* Only decref if the base type is not already a heap allocated type. + Otherwise, basedealloc should have decref'd it already */ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE)) + Py_DECREF(type); + + /* Done */ + return; + } + + /* We get here only if the type has GC */ + + /* UnTrack and re-Track around the trashcan macro, alas */ + /* See explanation at end of function for full disclosure */ + PyObject_GC_UnTrack(self); + Py_TRASHCAN_BEGIN(self, subtype_dealloc); + + /* Find the nearest base with a different tp_dealloc */ + base = type; + while ((/*basedealloc =*/ base->tp_dealloc) == subtype_dealloc) { + base = base->tp_base; + assert(base); + } + + has_finalizer = type->tp_finalize || type->tp_del; + + if (type->tp_finalize) { + _PyObject_GC_TRACK(self); + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + /* Resurrected */ + goto endlabel; + } + _PyObject_GC_UNTRACK(self); + } + /* + If we added a weaklist, we clear it. Do this *before* calling tp_del, + clearing slots, or clearing the instance dict. + + GC tracking must be off at this point. weakref callbacks (if any, and + whether directly here or indirectly in something we call) may trigger GC, + and if self is tracked at that point, it will look like trash to GC and GC + will try to delete self again. + */ + if (type->tp_weaklistoffset && !base->tp_weaklistoffset) + PyObject_ClearWeakRefs(self); + + if (type->tp_del) { + _PyObject_GC_TRACK(self); + type->tp_del(self); + if (self->ob_refcnt > 0) { + /* Resurrected */ + goto endlabel; + } + _PyObject_GC_UNTRACK(self); + } + if (has_finalizer) { + /* New weakrefs could be created during the finalizer call. + If this occurs, clear them out without calling their + finalizers since they might rely on part of the object + being finalized that has already been destroyed. */ + if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { + /* Modeled after GET_WEAKREFS_LISTPTR() */ + PyWeakReference **list = (PyWeakReference **) \ + PyObject_GET_WEAKREFS_LISTPTR(self); + while (*list) + _PyWeakref_ClearRef(*list); + } + } + + /* Clear slots up to the nearest base with a different tp_dealloc */ + base = type; + while ((basedealloc = base->tp_dealloc) == subtype_dealloc) { + if (Py_SIZE(base)) + clear_slots(base, self); + base = base->tp_base; + assert(base); + } + + /* If we added a dict, DECREF it */ + if (type->tp_dictoffset && !base->tp_dictoffset) { + PyObject **dictptr = _PyObject_GetDictPtr(self); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict != NULL) { + Py_DECREF(dict); + *dictptr = NULL; + } + } + } + + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + + /* Call the base tp_dealloc(); first retrack self if + * basedealloc knows about gc. + */ + if (PyType_IS_GC(base)) + _PyObject_GC_TRACK(self); + assert(basedealloc); + basedealloc(self); + + /* Can't reference self beyond this point. It's possible tp_del switched + our type from a HEAPTYPE to a non-HEAPTYPE, so be careful about + reference counting. Only decref if the base type is not already a heap + allocated type. Otherwise, basedealloc should have decref'd it already */ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE)) + Py_DECREF(type); + + endlabel: + Py_TRASHCAN_END + + /* Explanation of the weirdness around the trashcan macros: + + Q. What do the trashcan macros do? + + A. Read the comment titled "Trashcan mechanism" in object.h. + For one, this explains why there must be a call to GC-untrack + before the trashcan begin macro. Without understanding the + trashcan code, the answers to the following questions don't make + sense. + + Q. Why do we GC-untrack before the trashcan and then immediately + GC-track again afterward? + + A. In the case that the base class is GC-aware, the base class + probably GC-untracks the object. If it does that using the + UNTRACK macro, this will crash when the object is already + untracked. Because we don't know what the base class does, the + only safe thing is to make sure the object is tracked when we + call the base class dealloc. But... The trashcan begin macro + requires that the object is *untracked* before it is called. So + the dance becomes: + + GC untrack + trashcan begin + GC track + + Q. Why did the last question say "immediately GC-track again"? + It's nowhere near immediately. + + A. Because the code *used* to re-track immediately. Bad Idea. + self has a refcount of 0, and if gc ever gets its hands on it + (which can happen if any weakref callback gets invoked), it + looks like trash to gc too, and gc also tries to delete self + then. But we're already deleting self. Double deallocation is + a subtle disaster. + */ +} + +static PyTypeObject *solid_base(PyTypeObject *type); + +/* type test with subclassing support */ + +static int +type_is_subtype_base_chain(PyTypeObject *a, PyTypeObject *b) +{ + do { + if (a == b) + return 1; + a = a->tp_base; + } while (a != NULL); + + return (b == &PyBaseObject_Type); +} + +int +PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) +{ + PyObject *mro; + + mro = a->tp_mro; + if (mro != NULL) { + /* Deal with multiple inheritance without recursion + by walking the MRO tuple */ + Py_ssize_t i, n; + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + else + /* a is not completely initilized yet; follow tp_base */ + return type_is_subtype_base_chain(a, b); +} + +/* Routines to do a method lookup in the type without looking in the + instance dictionary (so we can't use PyObject_GetAttr) but still + binding it to the instance. + + Variants: + + - _PyObject_LookupSpecial() returns NULL without raising an exception + when the _PyType_Lookup() call fails; + + - lookup_maybe_method() and lookup_method() are internal routines similar + to _PyObject_LookupSpecial(), but can return unbound PyFunction + to avoid temporary method object. Pass self as first argument when + unbound == 1. +*/ + +PyObject * +_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid) +{ + PyObject *res; + + res = _PyType_LookupId(Py_TYPE(self), attrid); + if (res != NULL) { + descrgetfunc f; + if ((f = Py_TYPE(res)->tp_descr_get) == NULL) + Py_INCREF(res); + else + res = f(res, self, (PyObject *)(Py_TYPE(self))); + } + return res; +} + +static PyObject * +lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound) +{ + PyObject *res = _PyType_LookupId(Py_TYPE(self), attrid); + if (res == NULL) { + return NULL; + } + + if (PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) { + /* Avoid temporary PyMethodObject */ + *unbound = 1; + Py_INCREF(res); + } + else { + *unbound = 0; + descrgetfunc f = Py_TYPE(res)->tp_descr_get; + if (f == NULL) { + Py_INCREF(res); + } + else { + res = f(res, self, (PyObject *)(Py_TYPE(self))); + } + } + return res; +} + +static PyObject * +lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound) +{ + PyObject *res = lookup_maybe_method(self, attrid, unbound); + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetObject(PyExc_AttributeError, attrid->object); + } + return res; +} + +static PyObject* +call_unbound(int unbound, PyObject *func, PyObject *self, + PyObject **args, Py_ssize_t nargs) +{ + if (unbound) { + return _PyObject_FastCall_Prepend(func, self, args, nargs); + } + else { + return _PyObject_FastCall(func, args, nargs); + } +} + +static PyObject* +call_unbound_noarg(int unbound, PyObject *func, PyObject *self) +{ + if (unbound) { + PyObject *args[1] = {self}; + return _PyObject_FastCall(func, args, 1); + } + else { + return _PyObject_CallNoArg(func); + } +} + +/* A variation of PyObject_CallMethod* that uses lookup_maybe_method() + instead of PyObject_GetAttrString(). */ +static PyObject * +call_method(PyObject *obj, _Py_Identifier *name, + PyObject **args, Py_ssize_t nargs) +{ + int unbound; + PyObject *func, *retval; + + func = lookup_method(obj, name, &unbound); + if (func == NULL) { + return NULL; + } + retval = call_unbound(unbound, func, obj, args, nargs); + Py_DECREF(func); + return retval; +} + +/* Clone of call_method() that returns NotImplemented when the lookup fails. */ + +static PyObject * +call_maybe(PyObject *obj, _Py_Identifier *name, + PyObject **args, Py_ssize_t nargs) +{ + int unbound; + PyObject *func, *retval; + + func = lookup_maybe_method(obj, name, &unbound); + if (func == NULL) { + if (!PyErr_Occurred()) + Py_RETURN_NOTIMPLEMENTED; + return NULL; + } + + retval = call_unbound(unbound, func, obj, args, nargs); + Py_DECREF(func); + return retval; +} + +/* + Method resolution order algorithm C3 described in + "A Monotonic Superclass Linearization for Dylan", + by Kim Barrett, Bob Cassel, Paul Haahr, + David A. Moon, Keith Playford, and P. Tucker Withington. + (OOPSLA 1996) + + Some notes about the rules implied by C3: + + No duplicate bases. + It isn't legal to repeat a class in a list of base classes. + + The next three properties are the 3 constraints in "C3". + + Local precedence order. + If A precedes B in C's MRO, then A will precede B in the MRO of all + subclasses of C. + + Monotonicity. + The MRO of a class must be an extension without reordering of the + MRO of each of its superclasses. + + Extended Precedence Graph (EPG). + Linearization is consistent if there is a path in the EPG from + each class to all its successors in the linearization. See + the paper for definition of EPG. + */ + +static int +tail_contains(PyObject *tuple, int whence, PyObject *o) +{ + Py_ssize_t j, size; + size = PyTuple_GET_SIZE(tuple); + + for (j = whence+1; j < size; j++) { + if (PyTuple_GET_ITEM(tuple, j) == o) + return 1; + } + return 0; +} + +static PyObject * +class_name(PyObject *cls) +{ + PyObject *name; + if (_PyObject_LookupAttrId(cls, &PyId___name__, &name) == 0) { + name = PyObject_Repr(cls); + } + return name; +} + +static int +check_duplicates(PyObject *tuple) +{ + Py_ssize_t i, j, n; + /* Let's use a quadratic time algorithm, + assuming that the bases tuples is short. + */ + n = PyTuple_GET_SIZE(tuple); + for (i = 0; i < n; i++) { + PyObject *o = PyTuple_GET_ITEM(tuple, i); + for (j = i + 1; j < n; j++) { + if (PyTuple_GET_ITEM(tuple, j) == o) { + o = class_name(o); + if (o != NULL) { + if (PyUnicode_Check(o)) { + PyErr_Format(PyExc_TypeError, + "duplicate base class %U", o); + } + else { + PyErr_SetString(PyExc_TypeError, + "duplicate base class"); + } + Py_DECREF(o); + } + return -1; + } + } + } + return 0; +} + +/* Raise a TypeError for an MRO order disagreement. + + It's hard to produce a good error message. In the absence of better + insight into error reporting, report the classes that were candidates + to be put next into the MRO. There is some conflict between the + order in which they should be put in the MRO, but it's hard to + diagnose what constraint can't be satisfied. +*/ + +static void +set_mro_error(PyObject **to_merge, Py_ssize_t to_merge_size, int *remain) +{ + Py_ssize_t i, n, off; + char buf[1000]; + PyObject *k, *v; + PyObject *set = PyDict_New(); + if (!set) return; + + for (i = 0; i < to_merge_size; i++) { + PyObject *L = to_merge[i]; + if (remain[i] < PyTuple_GET_SIZE(L)) { + PyObject *c = PyTuple_GET_ITEM(L, remain[i]); + if (PyDict_SetItem(set, c, Py_None) < 0) { + Py_DECREF(set); + return; + } + } + } + n = PyDict_GET_SIZE(set); + + off = PyOS_snprintf(buf, sizeof(buf), "Cannot create a \ +consistent method resolution\norder (MRO) for bases"); + i = 0; + while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) { + PyObject *name = class_name(k); + const char *name_str = NULL; + if (name != NULL) { + if (PyUnicode_Check(name)) { + name_str = PyUnicode_AsUTF8(name); + } + else { + name_str = "?"; + } + } + if (name_str == NULL) { + Py_XDECREF(name); + Py_DECREF(set); + return; + } + off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s", name_str); + Py_XDECREF(name); + if (--n && (size_t)(off+1) < sizeof(buf)) { + buf[off++] = ','; + buf[off] = '\0'; + } + } + PyErr_SetString(PyExc_TypeError, buf); + Py_DECREF(set); +} + +static int +pmerge(PyObject *acc, PyObject **to_merge, Py_ssize_t to_merge_size) +{ + int res = 0; + Py_ssize_t i, j, empty_cnt; + int *remain; + + /* remain stores an index into each sublist of to_merge. + remain[i] is the index of the next base in to_merge[i] + that is not included in acc. + */ + remain = PyMem_New(int, to_merge_size); + if (remain == NULL) { + PyErr_NoMemory(); + return -1; + } + for (i = 0; i < to_merge_size; i++) + remain[i] = 0; + + again: + empty_cnt = 0; + for (i = 0; i < to_merge_size; i++) { + PyObject *candidate; + + PyObject *cur_tuple = to_merge[i]; + + if (remain[i] >= PyTuple_GET_SIZE(cur_tuple)) { + empty_cnt++; + continue; + } + + /* Choose next candidate for MRO. + + The input sequences alone can determine the choice. + If not, choose the class which appears in the MRO + of the earliest direct superclass of the new class. + */ + + candidate = PyTuple_GET_ITEM(cur_tuple, remain[i]); + for (j = 0; j < to_merge_size; j++) { + PyObject *j_lst = to_merge[j]; + if (tail_contains(j_lst, remain[j], candidate)) + goto skip; /* continue outer loop */ + } + res = PyList_Append(acc, candidate); + if (res < 0) + goto out; + + for (j = 0; j < to_merge_size; j++) { + PyObject *j_lst = to_merge[j]; + if (remain[j] < PyTuple_GET_SIZE(j_lst) && + PyTuple_GET_ITEM(j_lst, remain[j]) == candidate) { + remain[j]++; + } + } + goto again; + skip: ; + } + + if (empty_cnt != to_merge_size) { + set_mro_error(to_merge, to_merge_size, remain); + res = -1; + } + + out: + PyMem_Del(remain); + + return res; +} + +static PyObject * +mro_implementation(PyTypeObject *type) +{ + PyObject *result; + PyObject *bases; + PyObject **to_merge; + Py_ssize_t i, n; + + if (type->tp_dict == NULL) { + if (PyType_Ready(type) < 0) + return NULL; + } + + bases = type->tp_bases; + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + if (base->tp_mro == NULL) { + PyErr_Format(PyExc_TypeError, + "Cannot extend an incomplete type '%.100s'", + base->tp_name); + return NULL; + } + assert(PyTuple_Check(base->tp_mro)); + } + + if (n == 1) { + /* Fast path: if there is a single base, constructing the MRO + * is trivial. + */ + PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); + Py_ssize_t k = PyTuple_GET_SIZE(base->tp_mro); + result = PyTuple_New(k + 1); + if (result == NULL) { + return NULL; + } + Py_INCREF(type); + PyTuple_SET_ITEM(result, 0, (PyObject *) type); + for (i = 0; i < k; i++) { + PyObject *cls = PyTuple_GET_ITEM(base->tp_mro, i); + Py_INCREF(cls); + PyTuple_SET_ITEM(result, i + 1, cls); + } + return result; + } + + /* This is just a basic sanity check. */ + if (check_duplicates(bases) < 0) { + return NULL; + } + + /* Find a superclass linearization that honors the constraints + of the explicit tuples of bases and the constraints implied by + each base class. + + to_merge is an array of tuples, where each tuple is a superclass + linearization implied by a base class. The last element of + to_merge is the declared tuple of bases. + */ + + to_merge = PyMem_New(PyObject *, n + 1); + if (to_merge == NULL) { + PyErr_NoMemory(); + return NULL; + } + + for (i = 0; i < n; i++) { + PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + to_merge[i] = base->tp_mro; + } + to_merge[n] = bases; + + result = PyList_New(1); + if (result == NULL) { + PyMem_Del(to_merge); + return NULL; + } + + Py_INCREF(type); + PyList_SET_ITEM(result, 0, (PyObject *)type); + if (pmerge(result, to_merge, n + 1) < 0) { + Py_CLEAR(result); + } + + PyMem_Del(to_merge); + return result; +} + +/*[clinic input] +type.mro + +Return a type's method resolution order. +[clinic start generated code]*/ + +static PyObject * +type_mro_impl(PyTypeObject *self) +/*[clinic end generated code: output=bffc4a39b5b57027 input=28414f4e156db28d]*/ +{ + PyObject *seq; + seq = mro_implementation(self); + if (seq != NULL && !PyList_Check(seq)) { + Py_SETREF(seq, PySequence_List(seq)); + } + return seq; +} + +static int +mro_check(PyTypeObject *type, PyObject *mro) +{ + PyTypeObject *solid; + Py_ssize_t i, n; + + solid = solid_base(type); + + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyTypeObject *base; + PyObject *tmp; + + tmp = PyTuple_GET_ITEM(mro, i); + if (!PyType_Check(tmp)) { + PyErr_Format( + PyExc_TypeError, + "mro() returned a non-class ('%.500s')", + Py_TYPE(tmp)->tp_name); + return -1; + } + + base = (PyTypeObject*)tmp; + if (!PyType_IsSubtype(solid, solid_base(base))) { + PyErr_Format( + PyExc_TypeError, + "mro() returned base with unsuitable layout ('%.500s')", + base->tp_name); + return -1; + } + } + + return 0; +} + +/* Lookups an mcls.mro method, invokes it and checks the result (if needed, + in case of a custom mro() implementation). + + Keep in mind that during execution of this function type->tp_mro + can be replaced due to possible reentrance (for example, + through type_set_bases): + + - when looking up the mcls.mro attribute (it could be + a user-provided descriptor); + + - from inside a custom mro() itself; + + - through a finalizer of the return value of mro(). +*/ +static PyObject * +mro_invoke(PyTypeObject *type) +{ + PyObject *mro_result; + PyObject *new_mro; + int custom = (Py_TYPE(type) != &PyType_Type); + + if (custom) { + _Py_IDENTIFIER(mro); + int unbound; + PyObject *mro_meth = lookup_method((PyObject *)type, &PyId_mro, + &unbound); + if (mro_meth == NULL) + return NULL; + mro_result = call_unbound_noarg(unbound, mro_meth, (PyObject *)type); + Py_DECREF(mro_meth); + } + else { + mro_result = mro_implementation(type); + } + if (mro_result == NULL) + return NULL; + + new_mro = PySequence_Tuple(mro_result); + Py_DECREF(mro_result); + if (new_mro == NULL) + return NULL; + + if (custom && mro_check(type, new_mro) < 0) { + Py_DECREF(new_mro); + return NULL; + } + + return new_mro; +} + +/* Calculates and assigns a new MRO to type->tp_mro. + Return values and invariants: + + - Returns 1 if a new MRO value has been set to type->tp_mro due to + this call of mro_internal (no tricky reentrancy and no errors). + + In case if p_old_mro argument is not NULL, a previous value + of type->tp_mro is put there, and the ownership of this + reference is transferred to a caller. + Otherwise, the previous value (if any) is decref'ed. + + - Returns 0 in case when type->tp_mro gets changed because of + reentering here through a custom mro() (see a comment to mro_invoke). + + In this case, a refcount of an old type->tp_mro is adjusted + somewhere deeper in the call stack (by the innermost mro_internal + or its caller) and may become zero upon returning from here. + This also implies that the whole hierarchy of subclasses of the type + has seen the new value and updated their MRO accordingly. + + - Returns -1 in case of an error. +*/ +static int +mro_internal(PyTypeObject *type, PyObject **p_old_mro) +{ + PyObject *new_mro, *old_mro; + int reent; + + /* Keep a reference to be able to do a reentrancy check below. + Don't let old_mro be GC'ed and its address be reused for + another object, like (suddenly!) a new tp_mro. */ + old_mro = type->tp_mro; + Py_XINCREF(old_mro); + new_mro = mro_invoke(type); /* might cause reentrance */ + reent = (type->tp_mro != old_mro); + Py_XDECREF(old_mro); + if (new_mro == NULL) + return -1; + + if (reent) { + Py_DECREF(new_mro); + return 0; + } + + type->tp_mro = new_mro; + + type_mro_modified(type, type->tp_mro); + /* corner case: the super class might have been hidden + from the custom MRO */ + type_mro_modified(type, type->tp_bases); + + PyType_Modified(type); + + if (p_old_mro != NULL) + *p_old_mro = old_mro; /* transfer the ownership */ + else + Py_XDECREF(old_mro); + + return 1; +} + + +/* Calculate the best base amongst multiple base classes. + This is the first one that's on the path to the "solid base". */ + +static PyTypeObject * +best_base(PyObject *bases) +{ + Py_ssize_t i, n; + PyTypeObject *base, *winner, *candidate, *base_i; + PyObject *base_proto; + + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + assert(n > 0); + base = NULL; + winner = NULL; + for (i = 0; i < n; i++) { + base_proto = PyTuple_GET_ITEM(bases, i); + if (!PyType_Check(base_proto)) { + PyErr_SetString( + PyExc_TypeError, + "bases must be types"); + return NULL; + } + base_i = (PyTypeObject *)base_proto; + if (base_i->tp_dict == NULL) { + if (PyType_Ready(base_i) < 0) + return NULL; + } + if (!PyType_HasFeature(base_i, Py_TPFLAGS_BASETYPE)) { + PyErr_Format(PyExc_TypeError, + "type '%.100s' is not an acceptable base type", + base_i->tp_name); + return NULL; + } + candidate = solid_base(base_i); + if (winner == NULL) { + winner = candidate; + base = base_i; + } + else if (PyType_IsSubtype(winner, candidate)) + ; + else if (PyType_IsSubtype(candidate, winner)) { + winner = candidate; + base = base_i; + } + else { + PyErr_SetString( + PyExc_TypeError, + "multiple bases have " + "instance lay-out conflict"); + return NULL; + } + } + assert (base != NULL); + + return base; +} + +static int +extra_ivars(PyTypeObject *type, PyTypeObject *base) +{ + size_t t_size = type->tp_basicsize; + size_t b_size = base->tp_basicsize; + + assert(t_size >= b_size); /* Else type smaller than base! */ + if (type->tp_itemsize || base->tp_itemsize) { + /* If itemsize is involved, stricter rules */ + return t_size != b_size || + type->tp_itemsize != base->tp_itemsize; + } + if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 && + type->tp_weaklistoffset + sizeof(PyObject *) == t_size && + type->tp_flags & Py_TPFLAGS_HEAPTYPE) + t_size -= sizeof(PyObject *); + if (type->tp_dictoffset && base->tp_dictoffset == 0 && + type->tp_dictoffset + sizeof(PyObject *) == t_size && + type->tp_flags & Py_TPFLAGS_HEAPTYPE) + t_size -= sizeof(PyObject *); + + return t_size != b_size; +} + +static PyTypeObject * +solid_base(PyTypeObject *type) +{ + PyTypeObject *base; + + if (type->tp_base) + base = solid_base(type->tp_base); + else + base = &PyBaseObject_Type; + if (extra_ivars(type, base)) + return type; + else + return base; +} + +static void object_dealloc(PyObject *); +static int object_init(PyObject *, PyObject *, PyObject *); +static int update_slot(PyTypeObject *, PyObject *); +static void fixup_slot_dispatchers(PyTypeObject *); +static int set_names(PyTypeObject *); +static int init_subclass(PyTypeObject *, PyObject *); + +/* + * Helpers for __dict__ descriptor. We don't want to expose the dicts + * inherited from various builtin types. The builtin base usually provides + * its own __dict__ descriptor, so we use that when we can. + */ +static PyTypeObject * +get_builtin_base_with_dict(PyTypeObject *type) +{ + while (type->tp_base != NULL) { + if (type->tp_dictoffset != 0 && + !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + return type; + type = type->tp_base; + } + return NULL; +} + +static PyObject * +get_dict_descriptor(PyTypeObject *type) +{ + PyObject *descr; + + descr = _PyType_LookupId(type, &PyId___dict__); + if (descr == NULL || !PyDescr_IsData(descr)) + return NULL; + + return descr; +} + +static void +raise_dict_descr_error(PyObject *obj) +{ + PyErr_Format(PyExc_TypeError, + "this __dict__ descriptor does not support " + "'%.200s' objects", Py_TYPE(obj)->tp_name); +} + +static PyObject * +subtype_dict(PyObject *obj, void *context) +{ + PyTypeObject *base; + + base = get_builtin_base_with_dict(Py_TYPE(obj)); + if (base != NULL) { + descrgetfunc func; + PyObject *descr = get_dict_descriptor(base); + if (descr == NULL) { + raise_dict_descr_error(obj); + return NULL; + } + func = Py_TYPE(descr)->tp_descr_get; + if (func == NULL) { + raise_dict_descr_error(obj); + return NULL; + } + return func(descr, obj, (PyObject *)(Py_TYPE(obj))); + } + return PyObject_GenericGetDict(obj, context); +} + +static int +subtype_setdict(PyObject *obj, PyObject *value, void *context) +{ + PyObject **dictptr; + PyTypeObject *base; + + base = get_builtin_base_with_dict(Py_TYPE(obj)); + if (base != NULL) { + descrsetfunc func; + PyObject *descr = get_dict_descriptor(base); + if (descr == NULL) { + raise_dict_descr_error(obj); + return -1; + } + func = Py_TYPE(descr)->tp_descr_set; + if (func == NULL) { + raise_dict_descr_error(obj); + return -1; + } + return func(descr, obj, value); + } + /* Almost like PyObject_GenericSetDict, but allow __dict__ to be deleted. */ + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr == NULL) { + PyErr_SetString(PyExc_AttributeError, + "This object has no __dict__"); + return -1; + } + if (value != NULL && !PyDict_Check(value)) { + PyErr_Format(PyExc_TypeError, + "__dict__ must be set to a dictionary, " + "not a '%.200s'", Py_TYPE(value)->tp_name); + return -1; + } + Py_XINCREF(value); + Py_XSETREF(*dictptr, value); + return 0; +} + +static PyObject * +subtype_getweakref(PyObject *obj, void *context) +{ + PyObject **weaklistptr; + PyObject *result; + PyTypeObject *type = Py_TYPE(obj); + + if (type->tp_weaklistoffset == 0) { + PyErr_SetString(PyExc_AttributeError, + "This object has no __weakref__"); + return NULL; + } + _PyObject_ASSERT((PyObject *)type, + type->tp_weaklistoffset > 0); + _PyObject_ASSERT((PyObject *)type, + ((type->tp_weaklistoffset + sizeof(PyObject *)) + <= (size_t)(type->tp_basicsize))); + weaklistptr = (PyObject **)((char *)obj + type->tp_weaklistoffset); + if (*weaklistptr == NULL) + result = Py_None; + else + result = *weaklistptr; + Py_INCREF(result); + return result; +} + +/* Three variants on the subtype_getsets list. */ + +static PyGetSetDef subtype_getsets_full[] = { + {"__dict__", subtype_dict, subtype_setdict, + PyDoc_STR("dictionary for instance variables (if defined)")}, + {"__weakref__", subtype_getweakref, NULL, + PyDoc_STR("list of weak references to the object (if defined)")}, + {0} +}; + +static PyGetSetDef subtype_getsets_dict_only[] = { + {"__dict__", subtype_dict, subtype_setdict, + PyDoc_STR("dictionary for instance variables (if defined)")}, + {0} +}; + +static PyGetSetDef subtype_getsets_weakref_only[] = { + {"__weakref__", subtype_getweakref, NULL, + PyDoc_STR("list of weak references to the object (if defined)")}, + {0} +}; + +static int +valid_identifier(PyObject *s) +{ + if (!PyUnicode_Check(s)) { + PyErr_Format(PyExc_TypeError, + "__slots__ items must be strings, not '%.200s'", + Py_TYPE(s)->tp_name); + return 0; + } + if (!PyUnicode_IsIdentifier(s)) { + PyErr_SetString(PyExc_TypeError, + "__slots__ must be identifiers"); + return 0; + } + return 1; +} + +/* Forward */ +static int +object_init(PyObject *self, PyObject *args, PyObject *kwds); + +static int +type_init(PyObject *cls, PyObject *args, PyObject *kwds) +{ + int res; + + assert(args != NULL && PyTuple_Check(args)); + assert(kwds == NULL || PyDict_Check(kwds)); + + if (kwds != NULL && PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && + PyDict_Check(kwds) && PyDict_GET_SIZE(kwds) != 0) { + PyErr_SetString(PyExc_TypeError, + "type.__init__() takes no keyword arguments"); + return -1; + } + + if (args != NULL && PyTuple_Check(args) && + (PyTuple_GET_SIZE(args) != 1 && PyTuple_GET_SIZE(args) != 3)) { + PyErr_SetString(PyExc_TypeError, + "type.__init__() takes 1 or 3 arguments"); + return -1; + } + + /* Call object.__init__(self) now. */ + /* XXX Could call super(type, cls).__init__() but what's the point? */ + args = PyTuple_GetSlice(args, 0, 0); + if (args == NULL) { + return -1; + } + res = object_init(cls, args, NULL); + Py_DECREF(args); + return res; +} + +unsigned long +PyType_GetFlags(PyTypeObject *type) +{ + return type->tp_flags; +} + +/* Determine the most derived metatype. */ +PyTypeObject * +_PyType_CalculateMetaclass(PyTypeObject *metatype, PyObject *bases) +{ + Py_ssize_t i, nbases; + PyTypeObject *winner; + PyObject *tmp; + PyTypeObject *tmptype; + + /* Determine the proper metatype to deal with this, + and check for metatype conflicts while we're at it. + Note that if some other metatype wins to contract, + it's possible that its instances are not types. */ + + nbases = PyTuple_GET_SIZE(bases); + winner = metatype; + for (i = 0; i < nbases; i++) { + tmp = PyTuple_GET_ITEM(bases, i); + tmptype = Py_TYPE(tmp); + if (PyType_IsSubtype(winner, tmptype)) + continue; + if (PyType_IsSubtype(tmptype, winner)) { + winner = tmptype; + continue; + } + /* else: */ + PyErr_SetString(PyExc_TypeError, + "metaclass conflict: " + "the metaclass of a derived class " + "must be a (non-strict) subclass " + "of the metaclasses of all its bases"); + return NULL; + } + return winner; +} + +static PyObject * +type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) +{ + PyObject *name, *bases = NULL, *orig_dict, *dict = NULL; + PyObject *qualname, *slots = NULL, *tmp, *newslots, *cell; + PyTypeObject *type = NULL, *base, *tmptype, *winner; + PyHeapTypeObject *et; + PyMemberDef *mp; + Py_ssize_t i, nbases, nslots, slotoffset, name_size; + int j, may_add_dict, may_add_weak, add_dict, add_weak; + _Py_IDENTIFIER(__qualname__); + _Py_IDENTIFIER(__slots__); + _Py_IDENTIFIER(__classcell__); + + assert(args != NULL && PyTuple_Check(args)); + assert(kwds == NULL || PyDict_Check(kwds)); + + /* Special case: type(x) should return x->ob_type */ + /* We only want type itself to accept the one-argument form (#27157) + Note: We don't call PyType_CheckExact as that also allows subclasses */ + if (metatype == &PyType_Type) { + const Py_ssize_t nargs = PyTuple_GET_SIZE(args); + const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_GET_SIZE(kwds); + + if (nargs == 1 && nkwds == 0) { + PyObject *x = PyTuple_GET_ITEM(args, 0); + Py_INCREF(Py_TYPE(x)); + return (PyObject *) Py_TYPE(x); + } + + /* SF bug 475327 -- if that didn't trigger, we need 3 + arguments. but PyArg_ParseTuple below may give + a msg saying type() needs exactly 3. */ + if (nargs != 3) { + PyErr_SetString(PyExc_TypeError, + "type() takes 1 or 3 arguments"); + return NULL; + } + } + + /* Check arguments: (name, bases, dict) */ + if (!PyArg_ParseTuple(args, "UO!O!:type.__new__", &name, &PyTuple_Type, + &bases, &PyDict_Type, &orig_dict)) + return NULL; + + /* Adjust for empty tuple bases */ + nbases = PyTuple_GET_SIZE(bases); + if (nbases == 0) { + base = &PyBaseObject_Type; + bases = PyTuple_Pack(1, base); + if (bases == NULL) + return NULL; + nbases = 1; + } + else { + _Py_IDENTIFIER(__mro_entries__); + for (i = 0; i < nbases; i++) { + tmp = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(tmp)) { + continue; + } + if (_PyObject_LookupAttrId(tmp, &PyId___mro_entries__, &tmp) < 0) { + return NULL; + } + if (tmp != NULL) { + PyErr_SetString(PyExc_TypeError, + "type() doesn't support MRO entry resolution; " + "use types.new_class()"); + Py_DECREF(tmp); + return NULL; + } + } + /* Search the bases for the proper metatype to deal with this: */ + winner = _PyType_CalculateMetaclass(metatype, bases); + if (winner == NULL) { + return NULL; + } + + if (winner != metatype) { + if (winner->tp_new != type_new) /* Pass it to the winner */ + return winner->tp_new(winner, args, kwds); + metatype = winner; + } + + /* Calculate best base, and check that all bases are type objects */ + base = best_base(bases); + if (base == NULL) { + return NULL; + } + + Py_INCREF(bases); + } + + /* Use "goto error" from this point on as we now own the reference to "bases". */ + + dict = PyDict_Copy(orig_dict); + if (dict == NULL) + goto error; + + /* Check for a __slots__ sequence variable in dict, and count it */ + slots = _PyDict_GetItemIdWithError(dict, &PyId___slots__); + nslots = 0; + add_dict = 0; + add_weak = 0; + may_add_dict = base->tp_dictoffset == 0; + may_add_weak = base->tp_weaklistoffset == 0 && base->tp_itemsize == 0; + if (slots == NULL) { + if (PyErr_Occurred()) { + goto error; + } + if (may_add_dict) { + add_dict++; + } + if (may_add_weak) { + add_weak++; + } + } + else { + /* Have slots */ + + /* Make it into a tuple */ + if (PyUnicode_Check(slots)) + slots = PyTuple_Pack(1, slots); + else + slots = PySequence_Tuple(slots); + if (slots == NULL) + goto error; + assert(PyTuple_Check(slots)); + + /* Are slots allowed? */ + nslots = PyTuple_GET_SIZE(slots); + if (nslots > 0 && base->tp_itemsize != 0) { + PyErr_Format(PyExc_TypeError, + "nonempty __slots__ " + "not supported for subtype of '%s'", + base->tp_name); + goto error; + } + + /* Check for valid slot names and two special cases */ + for (i = 0; i < nslots; i++) { + PyObject *tmp = PyTuple_GET_ITEM(slots, i); + if (!valid_identifier(tmp)) + goto error; + assert(PyUnicode_Check(tmp)); + if (_PyUnicode_EqualToASCIIId(tmp, &PyId___dict__)) { + if (!may_add_dict || add_dict) { + PyErr_SetString(PyExc_TypeError, + "__dict__ slot disallowed: " + "we already got one"); + goto error; + } + add_dict++; + } + if (_PyUnicode_EqualToASCIIString(tmp, "__weakref__")) { + if (!may_add_weak || add_weak) { + PyErr_SetString(PyExc_TypeError, + "__weakref__ slot disallowed: " + "either we already got one, " + "or __itemsize__ != 0"); + goto error; + } + add_weak++; + } + } + + /* Copy slots into a list, mangle names and sort them. + Sorted names are needed for __class__ assignment. + Convert them back to tuple at the end. + */ + newslots = PyList_New(nslots - add_dict - add_weak); + if (newslots == NULL) + goto error; + for (i = j = 0; i < nslots; i++) { + tmp = PyTuple_GET_ITEM(slots, i); + if ((add_dict && + _PyUnicode_EqualToASCIIId(tmp, &PyId___dict__)) || + (add_weak && + _PyUnicode_EqualToASCIIString(tmp, "__weakref__"))) + continue; + tmp =_Py_Mangle(name, tmp); + if (!tmp) { + Py_DECREF(newslots); + goto error; + } + PyList_SET_ITEM(newslots, j, tmp); + if (PyDict_GetItemWithError(dict, tmp)) { + /* CPython inserts __qualname__ and __classcell__ (when needed) + into the namespace when creating a class. They will be deleted + below so won't act as class variables. */ + if (!_PyUnicode_EqualToASCIIId(tmp, &PyId___qualname__) && + !_PyUnicode_EqualToASCIIId(tmp, &PyId___classcell__)) { + PyErr_Format(PyExc_ValueError, + "%R in __slots__ conflicts with class variable", + tmp); + Py_DECREF(newslots); + goto error; + } + } + else if (PyErr_Occurred()) { + Py_DECREF(newslots); + goto error; + } + j++; + } + assert(j == nslots - add_dict - add_weak); + nslots = j; + Py_CLEAR(slots); + if (PyList_Sort(newslots) == -1) { + Py_DECREF(newslots); + goto error; + } + slots = PyList_AsTuple(newslots); + Py_DECREF(newslots); + if (slots == NULL) + goto error; + + /* Secondary bases may provide weakrefs or dict */ + if (nbases > 1 && + ((may_add_dict && !add_dict) || + (may_add_weak && !add_weak))) { + for (i = 0; i < nbases; i++) { + tmp = PyTuple_GET_ITEM(bases, i); + if (tmp == (PyObject *)base) + continue; /* Skip primary base */ + assert(PyType_Check(tmp)); + tmptype = (PyTypeObject *)tmp; + if (may_add_dict && !add_dict && + tmptype->tp_dictoffset != 0) + add_dict++; + if (may_add_weak && !add_weak && + tmptype->tp_weaklistoffset != 0) + add_weak++; + if (may_add_dict && !add_dict) + continue; + if (may_add_weak && !add_weak) + continue; + /* Nothing more to check */ + break; + } + } + } + + /* Allocate the type object */ + type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots); + if (type == NULL) + goto error; + + /* Keep name and slots alive in the extended type object */ + et = (PyHeapTypeObject *)type; + Py_INCREF(name); + et->ht_name = name; + et->ht_slots = slots; + slots = NULL; + + /* Initialize tp_flags */ + // All heap types need GC, since we can create a reference cycle by storing + // an instance on one of its parents: + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC; + + /* Initialize essential fields */ + type->tp_as_async = &et->as_async; + type->tp_as_number = &et->as_number; + type->tp_as_sequence = &et->as_sequence; + type->tp_as_mapping = &et->as_mapping; + type->tp_as_buffer = &et->as_buffer; + type->tp_name = PyUnicode_AsUTF8AndSize(name, &name_size); + if (!type->tp_name) + goto error; + if (strlen(type->tp_name) != (size_t)name_size) { + PyErr_SetString(PyExc_ValueError, + "type name must not contain null characters"); + goto error; + } + + /* Set tp_base and tp_bases */ + type->tp_bases = bases; + bases = NULL; + Py_INCREF(base); + type->tp_base = base; + + /* Initialize tp_dict from passed-in dict */ + Py_INCREF(dict); + type->tp_dict = dict; + + /* Set __module__ in the dict */ + if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) { + if (PyErr_Occurred()) { + goto error; + } + tmp = PyEval_GetGlobals(); + if (tmp != NULL) { + tmp = _PyDict_GetItemIdWithError(tmp, &PyId___name__); + if (tmp != NULL) { + if (_PyDict_SetItemId(dict, &PyId___module__, + tmp) < 0) + goto error; + } + else if (PyErr_Occurred()) { + goto error; + } + } + } + + /* Set ht_qualname to dict['__qualname__'] if available, else to + __name__. The __qualname__ accessor will look for ht_qualname. + */ + qualname = _PyDict_GetItemIdWithError(dict, &PyId___qualname__); + if (qualname != NULL) { + if (!PyUnicode_Check(qualname)) { + PyErr_Format(PyExc_TypeError, + "type __qualname__ must be a str, not %s", + Py_TYPE(qualname)->tp_name); + goto error; + } + } + else if (PyErr_Occurred()) { + goto error; + } + et->ht_qualname = qualname ? qualname : et->ht_name; + Py_INCREF(et->ht_qualname); + if (qualname != NULL && _PyDict_DelItemId(dict, &PyId___qualname__) < 0) + goto error; + + /* Set tp_doc to a copy of dict['__doc__'], if the latter is there + and is a string. The __doc__ accessor will first look for tp_doc; + if that fails, it will still look into __dict__. + */ + { + PyObject *doc = _PyDict_GetItemIdWithError(dict, &PyId___doc__); + if (doc != NULL && PyUnicode_Check(doc)) { + Py_ssize_t len; + const char *doc_str; + char *tp_doc; + + doc_str = PyUnicode_AsUTF8(doc); + if (doc_str == NULL) + goto error; + /* Silently truncate the docstring if it contains null bytes. */ + len = strlen(doc_str); + tp_doc = (char *)PyObject_MALLOC(len + 1); + if (tp_doc == NULL) { + PyErr_NoMemory(); + goto error; + } + memcpy(tp_doc, doc_str, len + 1); + type->tp_doc = tp_doc; + } + else if (doc == NULL && PyErr_Occurred()) { + goto error; + } + } + + /* Special-case __new__: if it's a plain function, + make it a static function */ + tmp = _PyDict_GetItemIdWithError(dict, &PyId___new__); + if (tmp != NULL && PyFunction_Check(tmp)) { + tmp = PyStaticMethod_New(tmp); + if (tmp == NULL) + goto error; + if (_PyDict_SetItemId(dict, &PyId___new__, tmp) < 0) { + Py_DECREF(tmp); + goto error; + } + Py_DECREF(tmp); + } + else if (tmp == NULL && PyErr_Occurred()) { + goto error; + } + + /* Special-case __init_subclass__ and __class_getitem__: + if they are plain functions, make them classmethods */ + tmp = _PyDict_GetItemIdWithError(dict, &PyId___init_subclass__); + if (tmp != NULL && PyFunction_Check(tmp)) { + tmp = PyClassMethod_New(tmp); + if (tmp == NULL) + goto error; + if (_PyDict_SetItemId(dict, &PyId___init_subclass__, tmp) < 0) { + Py_DECREF(tmp); + goto error; + } + Py_DECREF(tmp); + } + else if (tmp == NULL && PyErr_Occurred()) { + goto error; + } + + tmp = _PyDict_GetItemIdWithError(dict, &PyId___class_getitem__); + if (tmp != NULL && PyFunction_Check(tmp)) { + tmp = PyClassMethod_New(tmp); + if (tmp == NULL) + goto error; + if (_PyDict_SetItemId(dict, &PyId___class_getitem__, tmp) < 0) { + Py_DECREF(tmp); + goto error; + } + Py_DECREF(tmp); + } + else if (tmp == NULL && PyErr_Occurred()) { + goto error; + } + + /* Add descriptors for custom slots from __slots__, or for __dict__ */ + mp = PyHeapType_GET_MEMBERS(et); + slotoffset = base->tp_basicsize; + if (et->ht_slots != NULL) { + for (i = 0; i < nslots; i++, mp++) { + mp->name = PyUnicode_AsUTF8( + PyTuple_GET_ITEM(et->ht_slots, i)); + if (mp->name == NULL) + goto error; + mp->type = T_OBJECT_EX; + mp->offset = slotoffset; + + /* __dict__ and __weakref__ are already filtered out */ + assert(strcmp(mp->name, "__dict__") != 0); + assert(strcmp(mp->name, "__weakref__") != 0); + + slotoffset += sizeof(PyObject *); + } + } + if (add_dict) { + if (base->tp_itemsize) + type->tp_dictoffset = -(long)sizeof(PyObject *); + else + type->tp_dictoffset = slotoffset; + slotoffset += sizeof(PyObject *); + } + if (add_weak) { + assert(!base->tp_itemsize); + type->tp_weaklistoffset = slotoffset; + slotoffset += sizeof(PyObject *); + } + type->tp_basicsize = slotoffset; + type->tp_itemsize = base->tp_itemsize; + type->tp_members = PyHeapType_GET_MEMBERS(et); + + if (type->tp_weaklistoffset && type->tp_dictoffset) + type->tp_getset = subtype_getsets_full; + else if (type->tp_weaklistoffset && !type->tp_dictoffset) + type->tp_getset = subtype_getsets_weakref_only; + else if (!type->tp_weaklistoffset && type->tp_dictoffset) + type->tp_getset = subtype_getsets_dict_only; + else + type->tp_getset = NULL; + + /* Special case some slots */ + if (type->tp_dictoffset != 0 || nslots > 0) { + if (base->tp_getattr == NULL && base->tp_getattro == NULL) + type->tp_getattro = PyObject_GenericGetAttr; + if (base->tp_setattr == NULL && base->tp_setattro == NULL) + type->tp_setattro = PyObject_GenericSetAttr; + } + type->tp_dealloc = subtype_dealloc; + + /* Always override allocation strategy to use regular heap */ + type->tp_alloc = PyType_GenericAlloc; + type->tp_free = PyObject_GC_Del; + type->tp_traverse = subtype_traverse; + type->tp_clear = subtype_clear; + + /* store type in class' cell if one is supplied */ + cell = _PyDict_GetItemIdWithError(dict, &PyId___classcell__); + if (cell != NULL) { + /* At least one method requires a reference to its defining class */ + if (!PyCell_Check(cell)) { + PyErr_Format(PyExc_TypeError, + "__classcell__ must be a nonlocal cell, not %.200R", + Py_TYPE(cell)); + goto error; + } + PyCell_Set(cell, (PyObject *) type); + if (_PyDict_DelItemId(dict, &PyId___classcell__) < 0) { + goto error; + } + } + else if (PyErr_Occurred()) { + goto error; + } + + /* Initialize the rest */ + if (PyType_Ready(type) < 0) + goto error; + + /* Put the proper slots in place */ + fixup_slot_dispatchers(type); + + if (type->tp_dictoffset) { + et->ht_cached_keys = _PyDict_NewKeysForClass(); + } + + if (set_names(type) < 0) + goto error; + + if (init_subclass(type, kwds) < 0) + goto error; + + Py_DECREF(dict); + return (PyObject *)type; + +error: + Py_XDECREF(dict); + Py_XDECREF(bases); + Py_XDECREF(slots); + Py_XDECREF(type); + return NULL; +} + +static const short slotoffsets[] = { + -1, /* invalid slot */ +#include "typeslots.inc" +}; + +PyObject * +PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +{ + PyHeapTypeObject *res; + PyMemberDef *memb; + PyObject *modname; + PyTypeObject *type, *base; + + PyType_Slot *slot; + Py_ssize_t nmembers; + char *s, *res_start; + + nmembers = 0; + for (slot = spec->slots; slot->slot; slot++) { + if (slot->slot == Py_tp_members) { + nmembers = 0; + for (memb = slot->pfunc; memb->name != NULL; memb++) { + nmembers++; + } + } + } + + res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, nmembers); + if (res == NULL) + return NULL; + res_start = (char*)res; + + if (spec->name == NULL) { + PyErr_SetString(PyExc_SystemError, + "Type spec does not define the name field."); + goto fail; + } + + /* Set the type name and qualname */ + s = strrchr(spec->name, '.'); + if (s == NULL) + s = (char*)spec->name; + else + s++; + + type = &res->ht_type; + /* The flags must be initialized early, before the GC traverses us */ + type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; + res->ht_name = PyUnicode_FromString(s); + if (!res->ht_name) + goto fail; + res->ht_qualname = res->ht_name; + Py_INCREF(res->ht_qualname); + type->tp_name = spec->name; + + /* Adjust for empty tuple bases */ + if (!bases) { + base = &PyBaseObject_Type; + /* See whether Py_tp_base(s) was specified */ + for (slot = spec->slots; slot->slot; slot++) { + if (slot->slot == Py_tp_base) + base = slot->pfunc; + else if (slot->slot == Py_tp_bases) { + bases = slot->pfunc; + } + } + if (!bases) { + bases = PyTuple_Pack(1, base); + if (!bases) + goto fail; + } + else if (!PyTuple_Check(bases)) { + PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); + goto fail; + } + else { + Py_INCREF(bases); + } + } + else if (!PyTuple_Check(bases)) { + PyErr_SetString(PyExc_SystemError, "bases is not a tuple"); + goto fail; + } + else { + Py_INCREF(bases); + } + + /* Calculate best base, and check that all bases are type objects */ + base = best_base(bases); + if (base == NULL) { + Py_DECREF(bases); + goto fail; + } + if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { + PyErr_Format(PyExc_TypeError, + "type '%.100s' is not an acceptable base type", + base->tp_name); + Py_DECREF(bases); + goto fail; + } + + /* Initialize essential fields */ + type->tp_as_async = &res->as_async; + type->tp_as_number = &res->as_number; + type->tp_as_sequence = &res->as_sequence; + type->tp_as_mapping = &res->as_mapping; + type->tp_as_buffer = &res->as_buffer; + /* Set tp_base and tp_bases */ + type->tp_bases = bases; + Py_INCREF(base); + type->tp_base = base; + + type->tp_basicsize = spec->basicsize; + type->tp_itemsize = spec->itemsize; + + for (slot = spec->slots; slot->slot; slot++) { + if (slot->slot < 0 + || (size_t)slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) { + PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); + goto fail; + } + else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) { + /* Processed above */ + continue; + } + else if (slot->slot == Py_tp_doc) { + /* For the docstring slot, which usually points to a static string + literal, we need to make a copy */ + const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); + size_t len = strlen(old_doc)+1; + char *tp_doc = PyObject_MALLOC(len); + if (tp_doc == NULL) { + type->tp_doc = NULL; + PyErr_NoMemory(); + goto fail; + } + memcpy(tp_doc, old_doc, len); + type->tp_doc = tp_doc; + } + else if (slot->slot == Py_tp_members) { + /* Move the slots to the heap type itself */ + size_t len = Py_TYPE(type)->tp_itemsize * nmembers; + memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len); + type->tp_members = PyHeapType_GET_MEMBERS(res); + } + else { + /* Copy other slots directly */ + *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; + } + } + if (type->tp_dealloc == NULL) { + /* It's a heap type, so needs the heap types' dealloc. + subtype_dealloc will call the base type's tp_dealloc, if + necessary. */ + type->tp_dealloc = subtype_dealloc; + } + + if (PyType_Ready(type) < 0) + goto fail; + + if (type->tp_dictoffset) { + res->ht_cached_keys = _PyDict_NewKeysForClass(); + } + + /* Set type.__module__ */ + s = strrchr(spec->name, '.'); + if (s != NULL) { + int err; + modname = PyUnicode_FromStringAndSize( + spec->name, (Py_ssize_t)(s - spec->name)); + if (modname == NULL) { + goto fail; + } + err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); + Py_DECREF(modname); + if (err != 0) + goto fail; + } else { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "builtin type %.200s has no __module__ attribute", + spec->name)) + goto fail; + } + + return (PyObject*)res; + + fail: + Py_DECREF(res); + return NULL; +} + +PyObject * +PyType_FromSpec(PyType_Spec *spec) +{ + return PyType_FromSpecWithBases(spec, NULL); +} + +void * +PyType_GetSlot(PyTypeObject *type, int slot) +{ + if (!PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) || slot < 0) { + PyErr_BadInternalCall(); + return NULL; + } + if ((size_t)slot >= Py_ARRAY_LENGTH(slotoffsets)) { + /* Extension module requesting slot from a future version */ + return NULL; + } + return *(void**)(((char*)type) + slotoffsets[slot]); +} + +/* Internal API to look for a name through the MRO, bypassing the method cache. + This returns a borrowed reference, and might set an exception. + 'error' is set to: -1: error with exception; 1: error without exception; 0: ok */ +static PyObject * +find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) +{ + Py_ssize_t i, n; + PyObject *mro, *res, *base, *dict; + Py_hash_t hash; + + if (!PyUnicode_CheckExact(name) || + (hash = ((PyASCIIObject *) name)->hash) == -1) + { + hash = PyObject_Hash(name); + if (hash == -1) { + *error = -1; + return NULL; + } + } + + /* Look in tp_dict of types in MRO */ + mro = type->tp_mro; + + if (mro == NULL) { + if ((type->tp_flags & Py_TPFLAGS_READYING) == 0) { + if (PyType_Ready(type) < 0) { + *error = -1; + return NULL; + } + mro = type->tp_mro; + } + if (mro == NULL) { + *error = 1; + return NULL; + } + } + + res = NULL; + /* Keep a strong reference to mro because type->tp_mro can be replaced + during dict lookup, e.g. when comparing to non-string keys. */ + Py_INCREF(mro); + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + base = PyTuple_GET_ITEM(mro, i); + assert(PyType_Check(base)); + dict = ((PyTypeObject *)base)->tp_dict; + assert(dict && PyDict_Check(dict)); + res = _PyDict_GetItem_KnownHash(dict, name, hash); + if (res != NULL) + break; + if (PyErr_Occurred()) { + *error = -1; + goto done; + } + } + *error = 0; +done: + Py_DECREF(mro); + return res; +} + +/* Internal API to look for a name through the MRO. + This returns a borrowed reference, and doesn't set an exception! */ +PyObject * +_PyType_Lookup(PyTypeObject *type, PyObject *name) +{ + PyObject *res; + int error; + unsigned int h; + + if (MCACHE_CACHEABLE_NAME(name) && + PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) { + /* fast path */ + h = MCACHE_HASH_METHOD(type, name); + if (method_cache[h].version == type->tp_version_tag && + method_cache[h].name == name) { +#if MCACHE_STATS + method_cache_hits++; +#endif + return method_cache[h].value; + } + } + + /* We may end up clearing live exceptions below, so make sure it's ours. */ + assert(!PyErr_Occurred()); + + res = find_name_in_mro(type, name, &error); + /* Only put NULL results into cache if there was no error. */ + if (error) { + /* It's not ideal to clear the error condition, + but this function is documented as not setting + an exception, and I don't want to change that. + E.g., when PyType_Ready() can't proceed, it won't + set the "ready" flag, so future attempts to ready + the same type will call it again -- hopefully + in a context that propagates the exception out. + */ + if (error == -1) { + PyErr_Clear(); + } + return NULL; + } + + if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(type)) { + h = MCACHE_HASH_METHOD(type, name); + method_cache[h].version = type->tp_version_tag; + method_cache[h].value = res; /* borrowed */ + Py_INCREF(name); + assert(((PyASCIIObject *)(name))->hash != -1); +#if MCACHE_STATS + if (method_cache[h].name != Py_None && method_cache[h].name != name) + method_cache_collisions++; + else + method_cache_misses++; +#endif + Py_SETREF(method_cache[h].name, name); + } + return res; +} + +PyObject * +_PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name) +{ + PyObject *oname; + oname = _PyUnicode_FromId(name); /* borrowed */ + if (oname == NULL) + return NULL; + return _PyType_Lookup(type, oname); +} + +/* Check if the "readied" PyUnicode name + is a double-underscore special name. */ +static int +is_dunder_name(PyObject *name) +{ + Py_ssize_t length = PyUnicode_GET_LENGTH(name); + int kind = PyUnicode_KIND(name); + /* Special names contain at least "__x__" and are always ASCII. */ + if (length > 4 && kind == PyUnicode_1BYTE_KIND) { + Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name); + return ( + ((characters[length-2] == '_') && (characters[length-1] == '_')) && + ((characters[0] == '_') && (characters[1] == '_')) + ); + } + return 0; +} + +/* This is similar to PyObject_GenericGetAttr(), + but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ +static PyObject * +type_getattro(PyTypeObject *type, PyObject *name) +{ + PyTypeObject *metatype = Py_TYPE(type); + PyObject *meta_attribute, *attribute; + descrgetfunc meta_get; + PyObject* res; + + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return NULL; + } + + /* Initialize this type (we'll assume the metatype is initialized) */ + if (type->tp_dict == NULL) { + if (PyType_Ready(type) < 0) + return NULL; + } + + /* No readable descriptor found yet */ + meta_get = NULL; + + /* Look for the attribute in the metatype */ + meta_attribute = _PyType_Lookup(metatype, name); + + if (meta_attribute != NULL) { + Py_INCREF(meta_attribute); + meta_get = Py_TYPE(meta_attribute)->tp_descr_get; + + if (meta_get != NULL && PyDescr_IsData(meta_attribute)) { + /* Data descriptors implement tp_descr_set to intercept + * writes. Assume the attribute is not overridden in + * type's tp_dict (and bases): call the descriptor now. + */ + res = meta_get(meta_attribute, (PyObject *)type, + (PyObject *)metatype); + Py_DECREF(meta_attribute); + return res; + } + } + + /* No data descriptor found on metatype. Look in tp_dict of this + * type and its bases */ + attribute = _PyType_Lookup(type, name); + if (attribute != NULL) { + /* Implement descriptor functionality, if any */ + Py_INCREF(attribute); + descrgetfunc local_get = Py_TYPE(attribute)->tp_descr_get; + + Py_XDECREF(meta_attribute); + + if (local_get != NULL) { + /* NULL 2nd argument indicates the descriptor was + * found on the target object itself (or a base) */ + res = local_get(attribute, (PyObject *)NULL, + (PyObject *)type); + Py_DECREF(attribute); + return res; + } + + return attribute; + } + + /* No attribute found in local __dict__ (or bases): use the + * descriptor from the metatype, if any */ + if (meta_get != NULL) { + PyObject *res; + res = meta_get(meta_attribute, (PyObject *)type, + (PyObject *)metatype); + Py_DECREF(meta_attribute); + return res; + } + + /* If an ordinary attribute was found on the metatype, return it now */ + if (meta_attribute != NULL) { + return meta_attribute; + } + + /* Give up */ + PyErr_Format(PyExc_AttributeError, + "type object '%.50s' has no attribute '%U'", + type->tp_name, name); + return NULL; +} + +static int +type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) +{ + int res; + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format( + PyExc_TypeError, + "can't set attributes of built-in/extension type '%s'", + type->tp_name); + return -1; + } + if (PyUnicode_Check(name)) { + if (PyUnicode_CheckExact(name)) { + if (PyUnicode_READY(name) == -1) + return -1; + Py_INCREF(name); + } + else { + name = _PyUnicode_Copy(name); + if (name == NULL) + return -1; + } + if (!PyUnicode_CHECK_INTERNED(name)) { + PyUnicode_InternInPlace(&name); + if (!PyUnicode_CHECK_INTERNED(name)) { + PyErr_SetString(PyExc_MemoryError, + "Out of memory interning an attribute name"); + Py_DECREF(name); + return -1; + } + } + } + else { + /* Will fail in _PyObject_GenericSetAttrWithDict. */ + Py_INCREF(name); + } + res = _PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL); + if (res == 0) { + /* Clear the VALID_VERSION flag of 'type' and all its + subclasses. This could possibly be unified with the + update_subclasses() recursion in update_slot(), but carefully: + they each have their own conditions on which to stop + recursing into subclasses. */ + PyType_Modified(type); + + if (is_dunder_name(name)) { + res = update_slot(type, name); + } + assert(_PyType_CheckConsistency(type)); + } + Py_DECREF(name); + return res; +} + +extern void +_PyDictKeys_DecRef(PyDictKeysObject *keys); + +static void +type_dealloc(PyTypeObject *type) +{ + PyHeapTypeObject *et; + PyObject *tp, *val, *tb; + + /* Assert this is a heap-allocated type object */ + _PyObject_ASSERT((PyObject *)type, type->tp_flags & Py_TPFLAGS_HEAPTYPE); + _PyObject_GC_UNTRACK(type); + PyErr_Fetch(&tp, &val, &tb); + remove_all_subclasses(type, type->tp_bases); + PyErr_Restore(tp, val, tb); + PyObject_ClearWeakRefs((PyObject *)type); + et = (PyHeapTypeObject *)type; + Py_XDECREF(type->tp_base); + Py_XDECREF(type->tp_dict); + Py_XDECREF(type->tp_bases); + Py_XDECREF(type->tp_mro); + Py_XDECREF(type->tp_cache); + Py_XDECREF(type->tp_subclasses); + /* A type's tp_doc is heap allocated, unlike the tp_doc slots + * of most other objects. It's okay to cast it to char *. + */ + PyObject_Free((char *)type->tp_doc); + Py_XDECREF(et->ht_name); + Py_XDECREF(et->ht_qualname); + Py_XDECREF(et->ht_slots); + if (et->ht_cached_keys) + _PyDictKeys_DecRef(et->ht_cached_keys); + Py_TYPE(type)->tp_free((PyObject *)type); +} + +/*[clinic input] +type.__subclasses__ + +Return a list of immediate subclasses. +[clinic start generated code]*/ + +static PyObject * +type___subclasses___impl(PyTypeObject *self) +/*[clinic end generated code: output=eb5eb54485942819 input=5af66132436f9a7b]*/ +{ + PyObject *list, *raw, *ref; + Py_ssize_t i; + + list = PyList_New(0); + if (list == NULL) + return NULL; + raw = self->tp_subclasses; + if (raw == NULL) + return list; + assert(PyDict_CheckExact(raw)); + i = 0; + while (PyDict_Next(raw, &i, NULL, &ref)) { + assert(PyWeakref_CheckRef(ref)); + ref = PyWeakref_GET_OBJECT(ref); + if (ref != Py_None) { + if (PyList_Append(list, ref) < 0) { + Py_DECREF(list); + return NULL; + } + } + } + return list; +} + +static PyObject * +type_prepare(PyObject *self, PyObject *const *args, Py_ssize_t nargs, + PyObject *kwnames) +{ + return PyDict_New(); +} + +/* + Merge the __dict__ of aclass into dict, and recursively also all + the __dict__s of aclass's base classes. The order of merging isn't + defined, as it's expected that only the final set of dict keys is + interesting. + Return 0 on success, -1 on error. +*/ + +static int +merge_class_dict(PyObject *dict, PyObject *aclass) +{ + PyObject *classdict; + PyObject *bases; + _Py_IDENTIFIER(__bases__); + + assert(PyDict_Check(dict)); + assert(aclass); + + /* Merge in the type's dict (if any). */ + if (_PyObject_LookupAttrId(aclass, &PyId___dict__, &classdict) < 0) { + return -1; + } + if (classdict != NULL) { + int status = PyDict_Update(dict, classdict); + Py_DECREF(classdict); + if (status < 0) + return -1; + } + + /* Recursively merge in the base types' (if any) dicts. */ + if (_PyObject_LookupAttrId(aclass, &PyId___bases__, &bases) < 0) { + return -1; + } + if (bases != NULL) { + /* We have no guarantee that bases is a real tuple */ + Py_ssize_t i, n; + n = PySequence_Size(bases); /* This better be right */ + if (n < 0) { + Py_DECREF(bases); + return -1; + } + else { + for (i = 0; i < n; i++) { + int status; + PyObject *base = PySequence_GetItem(bases, i); + if (base == NULL) { + Py_DECREF(bases); + return -1; + } + status = merge_class_dict(dict, base); + Py_DECREF(base); + if (status < 0) { + Py_DECREF(bases); + return -1; + } + } + } + Py_DECREF(bases); + } + return 0; +} + +/* __dir__ for type objects: returns __dict__ and __bases__. + We deliberately don't suck up its __class__, as methods belonging to the + metaclass would probably be more confusing than helpful. +*/ +/*[clinic input] +type.__dir__ + +Specialized __dir__ implementation for types. +[clinic start generated code]*/ + +static PyObject * +type___dir___impl(PyTypeObject *self) +/*[clinic end generated code: output=69d02fe92c0f15fa input=7733befbec645968]*/ +{ + PyObject *result = NULL; + PyObject *dict = PyDict_New(); + + if (dict != NULL && merge_class_dict(dict, (PyObject *)self) == 0) + result = PyDict_Keys(dict); + + Py_XDECREF(dict); + return result; +} + +/*[clinic input] +type.__sizeof__ + +Return memory consumption of the type object. +[clinic start generated code]*/ + +static PyObject * +type___sizeof___impl(PyTypeObject *self) +/*[clinic end generated code: output=766f4f16cd3b1854 input=99398f24b9cf45d6]*/ +{ + Py_ssize_t size; + if (self->tp_flags & Py_TPFLAGS_HEAPTYPE) { + PyHeapTypeObject* et = (PyHeapTypeObject*)self; + size = sizeof(PyHeapTypeObject); + if (et->ht_cached_keys) + size += _PyDict_KeysSize(et->ht_cached_keys); + } + else + size = sizeof(PyTypeObject); + return PyLong_FromSsize_t(size); +} + +static PyMethodDef type_methods[] = { + TYPE_MRO_METHODDEF + TYPE___SUBCLASSES___METHODDEF + {"__prepare__", (PyCFunction)(void(*)(void))type_prepare, + METH_FASTCALL | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("__prepare__() -> dict\n" + "used to create the namespace for the class statement")}, + TYPE___INSTANCECHECK___METHODDEF + TYPE___SUBCLASSCHECK___METHODDEF + TYPE___DIR___METHODDEF + TYPE___SIZEOF___METHODDEF + {0} +}; + +PyDoc_STRVAR(type_doc, +/* this text signature cannot be accurate yet. will fix. --larry */ +"type(object_or_name, bases, dict)\n" +"type(object) -> the object's type\n" +"type(name, bases, dict) -> a new type"); + +static int +type_traverse(PyTypeObject *type, visitproc visit, void *arg) +{ + /* Because of type_is_gc(), the collector only calls this + for heaptypes. */ + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + char msg[200]; + sprintf(msg, "type_traverse() called for non-heap type '%.100s'", + type->tp_name); + Py_FatalError(msg); + } + + Py_VISIT(type->tp_dict); + Py_VISIT(type->tp_cache); + Py_VISIT(type->tp_mro); + Py_VISIT(type->tp_bases); + Py_VISIT(type->tp_base); + + /* There's no need to visit type->tp_subclasses or + ((PyHeapTypeObject *)type)->ht_slots, because they can't be involved + in cycles; tp_subclasses is a list of weak references, + and slots is a tuple of strings. */ + + return 0; +} + +static int +type_clear(PyTypeObject *type) +{ + PyDictKeysObject *cached_keys; + /* Because of type_is_gc(), the collector only calls this + for heaptypes. */ + _PyObject_ASSERT((PyObject *)type, type->tp_flags & Py_TPFLAGS_HEAPTYPE); + + /* We need to invalidate the method cache carefully before clearing + the dict, so that other objects caught in a reference cycle + don't start calling destroyed methods. + + Otherwise, the only field we need to clear is tp_mro, which is + part of a hard cycle (its first element is the class itself) that + won't be broken otherwise (it's a tuple and tuples don't have a + tp_clear handler). None of the other fields need to be + cleared, and here's why: + + tp_cache: + Not used; if it were, it would be a dict. + + tp_bases, tp_base: + If these are involved in a cycle, there must be at least + one other, mutable object in the cycle, e.g. a base + class's dict; the cycle will be broken that way. + + tp_subclasses: + A dict of weak references can't be part of a cycle; and + dicts have their own tp_clear. + + slots (in PyHeapTypeObject): + A tuple of strings can't be part of a cycle. + */ + + PyType_Modified(type); + cached_keys = ((PyHeapTypeObject *)type)->ht_cached_keys; + if (cached_keys != NULL) { + ((PyHeapTypeObject *)type)->ht_cached_keys = NULL; + _PyDictKeys_DecRef(cached_keys); + } + if (type->tp_dict) + PyDict_Clear(type->tp_dict); + Py_CLEAR(type->tp_mro); + + return 0; +} + +static int +type_is_gc(PyTypeObject *type) +{ + return type->tp_flags & Py_TPFLAGS_HEAPTYPE; +} + +PyTypeObject PyType_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "type", /* tp_name */ + sizeof(PyHeapTypeObject), /* tp_basicsize */ + sizeof(PyMemberDef), /* tp_itemsize */ + (destructor)type_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)type_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)type_call, /* tp_call */ + 0, /* tp_str */ + (getattrofunc)type_getattro, /* tp_getattro */ + (setattrofunc)type_setattro, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS, /* tp_flags */ + type_doc, /* tp_doc */ + (traverseproc)type_traverse, /* tp_traverse */ + (inquiry)type_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyTypeObject, tp_weaklist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + type_methods, /* tp_methods */ + type_members, /* tp_members */ + type_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ + type_init, /* tp_init */ + 0, /* tp_alloc */ + type_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + (inquiry)type_is_gc, /* tp_is_gc */ +}; + + +/* The base type of all types (eventually)... except itself. */ + +/* You may wonder why object.__new__() only complains about arguments + when object.__init__() is not overridden, and vice versa. + + Consider the use cases: + + 1. When neither is overridden, we want to hear complaints about + excess (i.e., any) arguments, since their presence could + indicate there's a bug. + + 2. When defining an Immutable type, we are likely to override only + __new__(), since __init__() is called too late to initialize an + Immutable object. Since __new__() defines the signature for the + type, it would be a pain to have to override __init__() just to + stop it from complaining about excess arguments. + + 3. When defining a Mutable type, we are likely to override only + __init__(). So here the converse reasoning applies: we don't + want to have to override __new__() just to stop it from + complaining. + + 4. When __init__() is overridden, and the subclass __init__() calls + object.__init__(), the latter should complain about excess + arguments; ditto for __new__(). + + Use cases 2 and 3 make it unattractive to unconditionally check for + excess arguments. The best solution that addresses all four use + cases is as follows: __init__() complains about excess arguments + unless __new__() is overridden and __init__() is not overridden + (IOW, if __init__() is overridden or __new__() is not overridden); + symmetrically, __new__() complains about excess arguments unless + __init__() is overridden and __new__() is not overridden + (IOW, if __new__() is overridden or __init__() is not overridden). + + However, for backwards compatibility, this breaks too much code. + Therefore, in 2.6, we'll *warn* about excess arguments when both + methods are overridden; for all other cases we'll use the above + rules. + +*/ + +/* Forward */ +static PyObject * +object_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + +static int +excess_args(PyObject *args, PyObject *kwds) +{ + return PyTuple_GET_SIZE(args) || + (kwds && PyDict_Check(kwds) && PyDict_GET_SIZE(kwds)); +} + +static int +object_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyTypeObject *type = Py_TYPE(self); + if (excess_args(args, kwds)) { + if (type->tp_init != object_init) { + PyErr_SetString(PyExc_TypeError, + "object.__init__() takes exactly one argument (the instance to initialize)"); + return -1; + } + if (type->tp_new == object_new) { + PyErr_Format(PyExc_TypeError, + "%.200s.__init__() takes exactly one argument (the instance to initialize)", + type->tp_name); + return -1; + } + } + return 0; +} + +static PyObject * +object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + if (excess_args(args, kwds)) { + if (type->tp_new != object_new) { + PyErr_SetString(PyExc_TypeError, + "object.__new__() takes exactly one argument (the type to instantiate)"); + return NULL; + } + if (type->tp_init == object_init) { + PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments", + type->tp_name); + return NULL; + } + } + + if (type->tp_flags & Py_TPFLAGS_IS_ABSTRACT) { + PyObject *abstract_methods; + PyObject *sorted_methods; + PyObject *joined; + PyObject *comma; + _Py_static_string(comma_id, ", "); + + /* Compute ", ".join(sorted(type.__abstractmethods__)) + into joined. */ + abstract_methods = type_abstractmethods(type, NULL); + if (abstract_methods == NULL) + return NULL; + sorted_methods = PySequence_List(abstract_methods); + Py_DECREF(abstract_methods); + if (sorted_methods == NULL) + return NULL; + if (PyList_Sort(sorted_methods)) { + Py_DECREF(sorted_methods); + return NULL; + } + comma = _PyUnicode_FromId(&comma_id); + if (comma == NULL) { + Py_DECREF(sorted_methods); + return NULL; + } + joined = PyUnicode_Join(comma, sorted_methods); + Py_DECREF(sorted_methods); + if (joined == NULL) + return NULL; + + PyErr_Format(PyExc_TypeError, + "Can't instantiate abstract class %s " + "with abstract methods %U", + type->tp_name, + joined); + Py_DECREF(joined); + return NULL; + } + return type->tp_alloc(type, 0); +} + +static void +object_dealloc(PyObject *self) +{ + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +object_repr(PyObject *self) +{ + PyTypeObject *type; + PyObject *mod, *name, *rtn; + + type = Py_TYPE(self); + mod = type_module(type, NULL); + if (mod == NULL) + PyErr_Clear(); + else if (!PyUnicode_Check(mod)) { + Py_DECREF(mod); + mod = NULL; + } + name = type_qualname(type, NULL); + if (name == NULL) { + Py_XDECREF(mod); + return NULL; + } + if (mod != NULL && !_PyUnicode_EqualToASCIIId(mod, &PyId_builtins)) + rtn = PyUnicode_FromFormat("<%U.%U object at %p>", mod, name, self); + else + rtn = PyUnicode_FromFormat("<%s object at %p>", + type->tp_name, self); + Py_XDECREF(mod); + Py_DECREF(name); + return rtn; +} + +static PyObject * +object_str(PyObject *self) +{ + unaryfunc f; + + f = Py_TYPE(self)->tp_repr; + if (f == NULL) + f = object_repr; + return f(self); +} + +static PyObject * +object_richcompare(PyObject *self, PyObject *other, int op) +{ + PyObject *res; + + switch (op) { + + case Py_EQ: + /* Return NotImplemented instead of False, so if two + objects are compared, both get a chance at the + comparison. See issue #1393. */ + res = (self == other) ? Py_True : Py_NotImplemented; + Py_INCREF(res); + break; + + case Py_NE: + /* By default, __ne__() delegates to __eq__() and inverts the result, + unless the latter returns NotImplemented. */ + if (self->ob_type->tp_richcompare == NULL) { + res = Py_NotImplemented; + Py_INCREF(res); + break; + } + res = (*self->ob_type->tp_richcompare)(self, other, Py_EQ); + if (res != NULL && res != Py_NotImplemented) { + int ok = PyObject_IsTrue(res); + Py_DECREF(res); + if (ok < 0) + res = NULL; + else { + if (ok) + res = Py_False; + else + res = Py_True; + Py_INCREF(res); + } + } + break; + + default: + res = Py_NotImplemented; + Py_INCREF(res); + break; + } + + return res; +} + +static PyObject * +object_get_class(PyObject *self, void *closure) +{ + Py_INCREF(Py_TYPE(self)); + return (PyObject *)(Py_TYPE(self)); +} + +static int +compatible_with_tp_base(PyTypeObject *child) +{ + PyTypeObject *parent = child->tp_base; + return (parent != NULL && + child->tp_basicsize == parent->tp_basicsize && + child->tp_itemsize == parent->tp_itemsize && + child->tp_dictoffset == parent->tp_dictoffset && + child->tp_weaklistoffset == parent->tp_weaklistoffset && + ((child->tp_flags & Py_TPFLAGS_HAVE_GC) == + (parent->tp_flags & Py_TPFLAGS_HAVE_GC)) && + (child->tp_dealloc == subtype_dealloc || + child->tp_dealloc == parent->tp_dealloc)); +} + +static int +same_slots_added(PyTypeObject *a, PyTypeObject *b) +{ + PyTypeObject *base = a->tp_base; + Py_ssize_t size; + PyObject *slots_a, *slots_b; + + assert(base == b->tp_base); + size = base->tp_basicsize; + if (a->tp_dictoffset == size && b->tp_dictoffset == size) + size += sizeof(PyObject *); + if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size) + size += sizeof(PyObject *); + + /* Check slots compliance */ + if (!(a->tp_flags & Py_TPFLAGS_HEAPTYPE) || + !(b->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + return 0; + } + slots_a = ((PyHeapTypeObject *)a)->ht_slots; + slots_b = ((PyHeapTypeObject *)b)->ht_slots; + if (slots_a && slots_b) { + if (PyObject_RichCompareBool(slots_a, slots_b, Py_EQ) != 1) + return 0; + size += sizeof(PyObject *) * PyTuple_GET_SIZE(slots_a); + } + return size == a->tp_basicsize && size == b->tp_basicsize; +} + +static int +compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* attr) +{ + PyTypeObject *newbase, *oldbase; + + if (newto->tp_free != oldto->tp_free) { + PyErr_Format(PyExc_TypeError, + "%s assignment: " + "'%s' deallocator differs from '%s'", + attr, + newto->tp_name, + oldto->tp_name); + return 0; + } + /* + It's tricky to tell if two arbitrary types are sufficiently compatible as + to be interchangeable; e.g., even if they have the same tp_basicsize, they + might have totally different struct fields. It's much easier to tell if a + type and its supertype are compatible; e.g., if they have the same + tp_basicsize, then that means they have identical fields. So to check + whether two arbitrary types are compatible, we first find the highest + supertype that each is compatible with, and then if those supertypes are + compatible then the original types must also be compatible. + */ + newbase = newto; + oldbase = oldto; + while (compatible_with_tp_base(newbase)) + newbase = newbase->tp_base; + while (compatible_with_tp_base(oldbase)) + oldbase = oldbase->tp_base; + if (newbase != oldbase && + (newbase->tp_base != oldbase->tp_base || + !same_slots_added(newbase, oldbase))) { + PyErr_Format(PyExc_TypeError, + "%s assignment: " + "'%s' object layout differs from '%s'", + attr, + newto->tp_name, + oldto->tp_name); + return 0; + } + + return 1; +} + +static int +object_set_class(PyObject *self, PyObject *value, void *closure) +{ + PyTypeObject *oldto = Py_TYPE(self); + PyTypeObject *newto; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete __class__ attribute"); + return -1; + } + if (!PyType_Check(value)) { + PyErr_Format(PyExc_TypeError, + "__class__ must be set to a class, not '%s' object", + Py_TYPE(value)->tp_name); + return -1; + } + if (PySys_Audit("object.__setattr__", "OsO", + self, "__class__", value) < 0) { + return -1; + } + + newto = (PyTypeObject *)value; + /* In versions of CPython prior to 3.5, the code in + compatible_for_assignment was not set up to correctly check for memory + layout / slot / etc. compatibility for non-HEAPTYPE classes, so we just + disallowed __class__ assignment in any case that wasn't HEAPTYPE -> + HEAPTYPE. + + During the 3.5 development cycle, we fixed the code in + compatible_for_assignment to correctly check compatibility between + arbitrary types, and started allowing __class__ assignment in all cases + where the old and new types did in fact have compatible slots and + memory layout (regardless of whether they were implemented as HEAPTYPEs + or not). + + Just before 3.5 was released, though, we discovered that this led to + problems with immutable types like int, where the interpreter assumes + they are immutable and interns some values. Formerly this wasn't a + problem, because they really were immutable -- in particular, all the + types where the interpreter applied this interning trick happened to + also be statically allocated, so the old HEAPTYPE rules were + "accidentally" stopping them from allowing __class__ assignment. But + with the changes to __class__ assignment, we started allowing code like + + class MyInt(int): + ... + # Modifies the type of *all* instances of 1 in the whole program, + # including future instances (!), because the 1 object is interned. + (1).__class__ = MyInt + + (see https://bugs.python.org/issue24912). + + In theory the proper fix would be to identify which classes rely on + this invariant and somehow disallow __class__ assignment only for them, + perhaps via some mechanism like a new Py_TPFLAGS_IMMUTABLE flag (a + "blacklisting" approach). But in practice, since this problem wasn't + noticed late in the 3.5 RC cycle, we're taking the conservative + approach and reinstating the same HEAPTYPE->HEAPTYPE check that we used + to have, plus a "whitelist". For now, the whitelist consists only of + ModuleType subtypes, since those are the cases that motivated the patch + in the first place -- see https://bugs.python.org/issue22986 -- and + since module objects are mutable we can be sure that they are + definitely not being interned. So now we allow HEAPTYPE->HEAPTYPE *or* + ModuleType subtype -> ModuleType subtype. + + So far as we know, all the code beyond the following 'if' statement + will correctly handle non-HEAPTYPE classes, and the HEAPTYPE check is + needed only to protect that subset of non-HEAPTYPE classes for which + the interpreter has baked in the assumption that all instances are + truly immutable. + */ + if (!(PyType_IsSubtype(newto, &PyModule_Type) && + PyType_IsSubtype(oldto, &PyModule_Type)) && + (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) || + !(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE))) { + PyErr_Format(PyExc_TypeError, + "__class__ assignment only supported for heap types " + "or ModuleType subclasses"); + return -1; + } + + if (compatible_for_assignment(oldto, newto, "__class__")) { + if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_INCREF(newto); + Py_TYPE(self) = newto; + if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_DECREF(oldto); + return 0; + } + else { + return -1; + } +} + +static PyGetSetDef object_getsets[] = { + {"__class__", object_get_class, object_set_class, + PyDoc_STR("the object's class")}, + {0} +}; + + +/* Stuff to implement __reduce_ex__ for pickle protocols >= 2. + We fall back to helpers in copyreg for: + - pickle protocols < 2 + - calculating the list of slot names (done only once per class) + - the __newobj__ function (which is used as a token but never called) +*/ + +static PyObject * +import_copyreg(void) +{ + PyObject *copyreg_str; + PyObject *copyreg_module; + _Py_IDENTIFIER(copyreg); + + copyreg_str = _PyUnicode_FromId(&PyId_copyreg); + if (copyreg_str == NULL) { + return NULL; + } + /* Try to fetch cached copy of copyreg from sys.modules first in an + attempt to avoid the import overhead. Previously this was implemented + by storing a reference to the cached module in a static variable, but + this broke when multiple embedded interpreters were in use (see issue + #17408 and #19088). */ + copyreg_module = PyImport_GetModule(copyreg_str); + if (copyreg_module != NULL) { + return copyreg_module; + } + if (PyErr_Occurred()) { + return NULL; + } + return PyImport_Import(copyreg_str); +} + +static PyObject * +_PyType_GetSlotNames(PyTypeObject *cls) +{ + PyObject *copyreg; + PyObject *slotnames; + _Py_IDENTIFIER(__slotnames__); + _Py_IDENTIFIER(_slotnames); + + assert(PyType_Check(cls)); + + /* Get the slot names from the cache in the class if possible. */ + slotnames = _PyDict_GetItemIdWithError(cls->tp_dict, &PyId___slotnames__); + if (slotnames != NULL) { + if (slotnames != Py_None && !PyList_Check(slotnames)) { + PyErr_Format(PyExc_TypeError, + "%.200s.__slotnames__ should be a list or None, " + "not %.200s", + cls->tp_name, Py_TYPE(slotnames)->tp_name); + return NULL; + } + Py_INCREF(slotnames); + return slotnames; + } + else { + if (PyErr_Occurred()) { + return NULL; + } + /* The class does not have the slot names cached yet. */ + } + + copyreg = import_copyreg(); + if (copyreg == NULL) + return NULL; + + /* Use _slotnames function from the copyreg module to find the slots + by this class and its bases. This function will cache the result + in __slotnames__. */ + slotnames = _PyObject_CallMethodIdObjArgs(copyreg, &PyId__slotnames, + cls, NULL); + Py_DECREF(copyreg); + if (slotnames == NULL) + return NULL; + + if (slotnames != Py_None && !PyList_Check(slotnames)) { + PyErr_SetString(PyExc_TypeError, + "copyreg._slotnames didn't return a list or None"); + Py_DECREF(slotnames); + return NULL; + } + + return slotnames; +} + +static PyObject * +_PyObject_GetState(PyObject *obj, int required) +{ + PyObject *state; + PyObject *getstate; + _Py_IDENTIFIER(__getstate__); + + if (_PyObject_LookupAttrId(obj, &PyId___getstate__, &getstate) < 0) { + return NULL; + } + if (getstate == NULL) { + PyObject *slotnames; + + if (required && obj->ob_type->tp_itemsize) { + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.200s' object", + Py_TYPE(obj)->tp_name); + return NULL; + } + + { + PyObject **dict; + dict = _PyObject_GetDictPtr(obj); + /* It is possible that the object's dict is not initialized + yet. In this case, we will return None for the state. + We also return None if the dict is empty to make the behavior + consistent regardless whether the dict was initialized or not. + This make unit testing easier. */ + if (dict != NULL && *dict != NULL && PyDict_GET_SIZE(*dict)) { + state = *dict; + } + else { + state = Py_None; + } + Py_INCREF(state); + } + + slotnames = _PyType_GetSlotNames(Py_TYPE(obj)); + if (slotnames == NULL) { + Py_DECREF(state); + return NULL; + } + + assert(slotnames == Py_None || PyList_Check(slotnames)); + if (required) { + Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize; + if (obj->ob_type->tp_dictoffset) + basicsize += sizeof(PyObject *); + if (obj->ob_type->tp_weaklistoffset) + basicsize += sizeof(PyObject *); + if (slotnames != Py_None) + basicsize += sizeof(PyObject *) * PyList_GET_SIZE(slotnames); + if (obj->ob_type->tp_basicsize > basicsize) { + Py_DECREF(slotnames); + Py_DECREF(state); + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.200s' object", + Py_TYPE(obj)->tp_name); + return NULL; + } + } + + if (slotnames != Py_None && PyList_GET_SIZE(slotnames) > 0) { + PyObject *slots; + Py_ssize_t slotnames_size, i; + + slots = PyDict_New(); + if (slots == NULL) { + Py_DECREF(slotnames); + Py_DECREF(state); + return NULL; + } + + slotnames_size = PyList_GET_SIZE(slotnames); + for (i = 0; i < slotnames_size; i++) { + PyObject *name, *value; + + name = PyList_GET_ITEM(slotnames, i); + Py_INCREF(name); + if (_PyObject_LookupAttr(obj, name, &value) < 0) { + goto error; + } + if (value == NULL) { + Py_DECREF(name); + /* It is not an error if the attribute is not present. */ + } + else { + int err = PyDict_SetItem(slots, name, value); + Py_DECREF(name); + Py_DECREF(value); + if (err) { + goto error; + } + } + + /* The list is stored on the class so it may mutate while we + iterate over it */ + if (slotnames_size != PyList_GET_SIZE(slotnames)) { + PyErr_Format(PyExc_RuntimeError, + "__slotsname__ changed size during iteration"); + goto error; + } + + /* We handle errors within the loop here. */ + if (0) { + error: + Py_DECREF(slotnames); + Py_DECREF(slots); + Py_DECREF(state); + return NULL; + } + } + + /* If we found some slot attributes, pack them in a tuple along + the original attribute dictionary. */ + if (PyDict_GET_SIZE(slots) > 0) { + PyObject *state2; + + state2 = PyTuple_Pack(2, state, slots); + Py_DECREF(state); + if (state2 == NULL) { + Py_DECREF(slotnames); + Py_DECREF(slots); + return NULL; + } + state = state2; + } + Py_DECREF(slots); + } + Py_DECREF(slotnames); + } + else { /* getstate != NULL */ + state = _PyObject_CallNoArg(getstate); + Py_DECREF(getstate); + if (state == NULL) + return NULL; + } + + return state; +} + +static int +_PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) +{ + PyObject *getnewargs, *getnewargs_ex; + _Py_IDENTIFIER(__getnewargs_ex__); + _Py_IDENTIFIER(__getnewargs__); + + if (args == NULL || kwargs == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + /* We first attempt to fetch the arguments for __new__ by calling + __getnewargs_ex__ on the object. */ + getnewargs_ex = _PyObject_LookupSpecial(obj, &PyId___getnewargs_ex__); + if (getnewargs_ex != NULL) { + PyObject *newargs = _PyObject_CallNoArg(getnewargs_ex); + Py_DECREF(getnewargs_ex); + if (newargs == NULL) { + return -1; + } + if (!PyTuple_Check(newargs)) { + PyErr_Format(PyExc_TypeError, + "__getnewargs_ex__ should return a tuple, " + "not '%.200s'", Py_TYPE(newargs)->tp_name); + Py_DECREF(newargs); + return -1; + } + if (PyTuple_GET_SIZE(newargs) != 2) { + PyErr_Format(PyExc_ValueError, + "__getnewargs_ex__ should return a tuple of " + "length 2, not %zd", PyTuple_GET_SIZE(newargs)); + Py_DECREF(newargs); + return -1; + } + *args = PyTuple_GET_ITEM(newargs, 0); + Py_INCREF(*args); + *kwargs = PyTuple_GET_ITEM(newargs, 1); + Py_INCREF(*kwargs); + Py_DECREF(newargs); + + /* XXX We should perhaps allow None to be passed here. */ + if (!PyTuple_Check(*args)) { + PyErr_Format(PyExc_TypeError, + "first item of the tuple returned by " + "__getnewargs_ex__ must be a tuple, not '%.200s'", + Py_TYPE(*args)->tp_name); + Py_CLEAR(*args); + Py_CLEAR(*kwargs); + return -1; + } + if (!PyDict_Check(*kwargs)) { + PyErr_Format(PyExc_TypeError, + "second item of the tuple returned by " + "__getnewargs_ex__ must be a dict, not '%.200s'", + Py_TYPE(*kwargs)->tp_name); + Py_CLEAR(*args); + Py_CLEAR(*kwargs); + return -1; + } + return 0; + } else if (PyErr_Occurred()) { + return -1; + } + + /* The object does not have __getnewargs_ex__ so we fallback on using + __getnewargs__ instead. */ + getnewargs = _PyObject_LookupSpecial(obj, &PyId___getnewargs__); + if (getnewargs != NULL) { + *args = _PyObject_CallNoArg(getnewargs); + Py_DECREF(getnewargs); + if (*args == NULL) { + return -1; + } + if (!PyTuple_Check(*args)) { + PyErr_Format(PyExc_TypeError, + "__getnewargs__ should return a tuple, " + "not '%.200s'", Py_TYPE(*args)->tp_name); + Py_CLEAR(*args); + return -1; + } + *kwargs = NULL; + return 0; + } else if (PyErr_Occurred()) { + return -1; + } + + /* The object does not have __getnewargs_ex__ and __getnewargs__. This may + mean __new__ does not takes any arguments on this object, or that the + object does not implement the reduce protocol for pickling or + copying. */ + *args = NULL; + *kwargs = NULL; + return 0; +} + +static int +_PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, + PyObject **dictitems) +{ + if (listitems == NULL || dictitems == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (!PyList_Check(obj)) { + *listitems = Py_None; + Py_INCREF(*listitems); + } + else { + *listitems = PyObject_GetIter(obj); + if (*listitems == NULL) + return -1; + } + + if (!PyDict_Check(obj)) { + *dictitems = Py_None; + Py_INCREF(*dictitems); + } + else { + PyObject *items; + _Py_IDENTIFIER(items); + + items = _PyObject_CallMethodIdObjArgs(obj, &PyId_items, NULL); + if (items == NULL) { + Py_CLEAR(*listitems); + return -1; + } + *dictitems = PyObject_GetIter(items); + Py_DECREF(items); + if (*dictitems == NULL) { + Py_CLEAR(*listitems); + return -1; + } + } + + assert(*listitems != NULL && *dictitems != NULL); + + return 0; +} + +static PyObject * +reduce_newobj(PyObject *obj) +{ + PyObject *args = NULL, *kwargs = NULL; + PyObject *copyreg; + PyObject *newobj, *newargs, *state, *listitems, *dictitems; + PyObject *result; + int hasargs; + + if (Py_TYPE(obj)->tp_new == NULL) { + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.200s' object", + Py_TYPE(obj)->tp_name); + return NULL; + } + if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) + return NULL; + + copyreg = import_copyreg(); + if (copyreg == NULL) { + Py_XDECREF(args); + Py_XDECREF(kwargs); + return NULL; + } + hasargs = (args != NULL); + if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { + _Py_IDENTIFIER(__newobj__); + PyObject *cls; + Py_ssize_t i, n; + + Py_XDECREF(kwargs); + newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj__); + Py_DECREF(copyreg); + if (newobj == NULL) { + Py_XDECREF(args); + return NULL; + } + n = args ? PyTuple_GET_SIZE(args) : 0; + newargs = PyTuple_New(n+1); + if (newargs == NULL) { + Py_XDECREF(args); + Py_DECREF(newobj); + return NULL; + } + cls = (PyObject *) Py_TYPE(obj); + Py_INCREF(cls); + PyTuple_SET_ITEM(newargs, 0, cls); + for (i = 0; i < n; i++) { + PyObject *v = PyTuple_GET_ITEM(args, i); + Py_INCREF(v); + PyTuple_SET_ITEM(newargs, i+1, v); + } + Py_XDECREF(args); + } + else if (args != NULL) { + _Py_IDENTIFIER(__newobj_ex__); + + newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj_ex__); + Py_DECREF(copyreg); + if (newobj == NULL) { + Py_DECREF(args); + Py_DECREF(kwargs); + return NULL; + } + newargs = PyTuple_Pack(3, Py_TYPE(obj), args, kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); + if (newargs == NULL) { + Py_DECREF(newobj); + return NULL; + } + } + else { + /* args == NULL */ + Py_DECREF(kwargs); + PyErr_BadInternalCall(); + return NULL; + } + + state = _PyObject_GetState(obj, + !hasargs && !PyList_Check(obj) && !PyDict_Check(obj)); + if (state == NULL) { + Py_DECREF(newobj); + Py_DECREF(newargs); + return NULL; + } + if (_PyObject_GetItemsIter(obj, &listitems, &dictitems) < 0) { + Py_DECREF(newobj); + Py_DECREF(newargs); + Py_DECREF(state); + return NULL; + } + + result = PyTuple_Pack(5, newobj, newargs, state, listitems, dictitems); + Py_DECREF(newobj); + Py_DECREF(newargs); + Py_DECREF(state); + Py_DECREF(listitems); + Py_DECREF(dictitems); + return result; +} + +/* + * There were two problems when object.__reduce__ and object.__reduce_ex__ + * were implemented in the same function: + * - trying to pickle an object with a custom __reduce__ method that + * fell back to object.__reduce__ in certain circumstances led to + * infinite recursion at Python level and eventual RecursionError. + * - Pickling objects that lied about their type by overwriting the + * __class__ descriptor could lead to infinite recursion at C level + * and eventual segfault. + * + * Because of backwards compatibility, the two methods still have to + * behave in the same way, even if this is not required by the pickle + * protocol. This common functionality was moved to the _common_reduce + * function. + */ +static PyObject * +_common_reduce(PyObject *self, int proto) +{ + PyObject *copyreg, *res; + + if (proto >= 2) + return reduce_newobj(self); + + copyreg = import_copyreg(); + if (!copyreg) + return NULL; + + res = PyObject_CallMethod(copyreg, "_reduce_ex", "Oi", self, proto); + Py_DECREF(copyreg); + + return res; +} + +/*[clinic input] +object.__reduce__ + +Helper for pickle. +[clinic start generated code]*/ + +static PyObject * +object___reduce___impl(PyObject *self) +/*[clinic end generated code: output=d4ca691f891c6e2f input=11562e663947e18b]*/ +{ + return _common_reduce(self, 0); +} + +/*[clinic input] +object.__reduce_ex__ + + protocol: int + / + +Helper for pickle. +[clinic start generated code]*/ + +static PyObject * +object___reduce_ex___impl(PyObject *self, int protocol) +/*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/ +{ + static PyObject *objreduce; + PyObject *reduce, *res; + _Py_IDENTIFIER(__reduce__); + + if (objreduce == NULL) { + objreduce = _PyDict_GetItemId(PyBaseObject_Type.tp_dict, + &PyId___reduce__); + } + + if (_PyObject_LookupAttrId(self, &PyId___reduce__, &reduce) < 0) { + return NULL; + } + if (reduce != NULL) { + PyObject *cls, *clsreduce; + int override; + + cls = (PyObject *) Py_TYPE(self); + clsreduce = _PyObject_GetAttrId(cls, &PyId___reduce__); + if (clsreduce == NULL) { + Py_DECREF(reduce); + return NULL; + } + override = (clsreduce != objreduce); + Py_DECREF(clsreduce); + if (override) { + res = _PyObject_CallNoArg(reduce); + Py_DECREF(reduce); + return res; + } + else + Py_DECREF(reduce); + } + + return _common_reduce(self, protocol); +} + +static PyObject * +object_subclasshook(PyObject *cls, PyObject *args) +{ + Py_RETURN_NOTIMPLEMENTED; +} + +PyDoc_STRVAR(object_subclasshook_doc, +"Abstract classes can override this to customize issubclass().\n" +"\n" +"This is invoked early on by abc.ABCMeta.__subclasscheck__().\n" +"It should return True, False or NotImplemented. If it returns\n" +"NotImplemented, the normal algorithm is used. Otherwise, it\n" +"overrides the normal algorithm (and the outcome is cached).\n"); + +static PyObject * +object_init_subclass(PyObject *cls, PyObject *arg) +{ + Py_RETURN_NONE; +} + +PyDoc_STRVAR(object_init_subclass_doc, +"This method is called when a class is subclassed.\n" +"\n" +"The default implementation does nothing. It may be\n" +"overridden to extend subclasses.\n"); + +/*[clinic input] +object.__format__ + + format_spec: unicode + / + +Default object formatter. +[clinic start generated code]*/ + +static PyObject * +object___format___impl(PyObject *self, PyObject *format_spec) +/*[clinic end generated code: output=34897efb543a974b input=7c3b3bc53a6fb7fa]*/ +{ + /* Issue 7994: If we're converting to a string, we + should reject format specifications */ + if (PyUnicode_GET_LENGTH(format_spec) > 0) { + PyErr_Format(PyExc_TypeError, + "unsupported format string passed to %.200s.__format__", + self->ob_type->tp_name); + return NULL; + } + return PyObject_Str(self); +} + +/*[clinic input] +object.__sizeof__ + +Size of object in memory, in bytes. +[clinic start generated code]*/ + +static PyObject * +object___sizeof___impl(PyObject *self) +/*[clinic end generated code: output=73edab332f97d550 input=1200ff3dfe485306]*/ +{ + Py_ssize_t res, isize; + + res = 0; + isize = self->ob_type->tp_itemsize; + if (isize > 0) + res = Py_SIZE(self) * isize; + res += self->ob_type->tp_basicsize; + + return PyLong_FromSsize_t(res); +} + +/* __dir__ for generic objects: returns __dict__, __class__, + and recursively up the __class__.__bases__ chain. +*/ +/*[clinic input] +object.__dir__ + +Default dir() implementation. +[clinic start generated code]*/ + +static PyObject * +object___dir___impl(PyObject *self) +/*[clinic end generated code: output=66dd48ea62f26c90 input=0a89305bec669b10]*/ +{ + PyObject *result = NULL; + PyObject *dict = NULL; + PyObject *itsclass = NULL; + + /* Get __dict__ (which may or may not be a real dict...) */ + if (_PyObject_LookupAttrId(self, &PyId___dict__, &dict) < 0) { + return NULL; + } + if (dict == NULL) { + dict = PyDict_New(); + } + else if (!PyDict_Check(dict)) { + Py_DECREF(dict); + dict = PyDict_New(); + } + else { + /* Copy __dict__ to avoid mutating it. */ + PyObject *temp = PyDict_Copy(dict); + Py_DECREF(dict); + dict = temp; + } + + if (dict == NULL) + goto error; + + /* Merge in attrs reachable from its class. */ + if (_PyObject_LookupAttrId(self, &PyId___class__, &itsclass) < 0) { + goto error; + } + /* XXX(tomer): Perhaps fall back to obj->ob_type if no + __class__ exists? */ + if (itsclass != NULL && merge_class_dict(dict, itsclass) < 0) + goto error; + + result = PyDict_Keys(dict); + /* fall through */ +error: + Py_XDECREF(itsclass); + Py_XDECREF(dict); + return result; +} + +static PyMethodDef object_methods[] = { + OBJECT___REDUCE_EX___METHODDEF + OBJECT___REDUCE___METHODDEF + {"__subclasshook__", object_subclasshook, METH_CLASS | METH_VARARGS, + object_subclasshook_doc}, + {"__init_subclass__", object_init_subclass, METH_CLASS | METH_NOARGS, + object_init_subclass_doc}, + OBJECT___FORMAT___METHODDEF + OBJECT___SIZEOF___METHODDEF + OBJECT___DIR___METHODDEF + {0} +}; + +PyDoc_STRVAR(object_doc, +"object()\n--\n\n" +"The base class of the class hierarchy.\n\n" +"When called, it accepts no arguments and returns a new featureless\n" +"instance that has no instance attributes and cannot be given any.\n"); + +PyTypeObject PyBaseObject_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "object", /* tp_name */ + sizeof(PyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + object_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + object_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)_Py_HashPointer, /* tp_hash */ + 0, /* tp_call */ + object_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + object_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + object_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + object_methods, /* tp_methods */ + 0, /* tp_members */ + object_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + object_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + object_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + +/* Add the methods from tp_methods to the __dict__ in a type object */ + +static int +add_methods(PyTypeObject *type, PyMethodDef *meth) +{ + PyObject *dict = type->tp_dict; + PyObject *name; + + for (; meth->ml_name != NULL; meth++) { + PyObject *descr; + int err; + int isdescr = 1; + if (meth->ml_flags & METH_CLASS) { + if (meth->ml_flags & METH_STATIC) { + PyErr_SetString(PyExc_ValueError, + "method cannot be both class and static"); + return -1; + } + descr = PyDescr_NewClassMethod(type, meth); + } + else if (meth->ml_flags & METH_STATIC) { + PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, NULL); + if (cfunc == NULL) + return -1; + descr = PyStaticMethod_New(cfunc); + isdescr = 0; // PyStaticMethod is not PyDescrObject + Py_DECREF(cfunc); + } + else { + descr = PyDescr_NewMethod(type, meth); + } + if (descr == NULL) + return -1; + + if (isdescr) { + name = PyDescr_NAME(descr); + } + else { + name = PyUnicode_FromString(meth->ml_name); + if (name == NULL) { + Py_DECREF(descr); + return -1; + } + } + + if (!(meth->ml_flags & METH_COEXIST)) { + if (PyDict_GetItemWithError(dict, name)) { + if (!isdescr) { + Py_DECREF(name); + } + Py_DECREF(descr); + continue; + } + else if (PyErr_Occurred()) { + if (!isdescr) { + Py_DECREF(name); + } + return -1; + } + } + err = PyDict_SetItem(dict, name, descr); + if (!isdescr) { + Py_DECREF(name); + } + Py_DECREF(descr); + if (err < 0) + return -1; + } + return 0; +} + +static int +add_members(PyTypeObject *type, PyMemberDef *memb) +{ + PyObject *dict = type->tp_dict; + + for (; memb->name != NULL; memb++) { + PyObject *descr = PyDescr_NewMember(type, memb); + if (descr == NULL) + return -1; + + if (PyDict_GetItemWithError(dict, PyDescr_NAME(descr))) { + Py_DECREF(descr); + continue; + } + else if (PyErr_Occurred()) { + Py_DECREF(descr); + return -1; + } + if (PyDict_SetItem(dict, PyDescr_NAME(descr), 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 = PyDescr_NewGetSet(type, gsp); + if (descr == NULL) + return -1; + + if (PyDict_GetItemWithError(dict, PyDescr_NAME(descr))) { + Py_DECREF(descr); + continue; + } + else if (PyErr_Occurred()) { + Py_DECREF(descr); + return -1; + } + if (PyDict_SetItem(dict, PyDescr_NAME(descr), descr) < 0) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + } + return 0; +} + +static void +inherit_special(PyTypeObject *type, PyTypeObject *base) +{ + + /* Copying tp_traverse and tp_clear is connected to the GC flags */ + if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) && + (base->tp_flags & Py_TPFLAGS_HAVE_GC) && + (!type->tp_traverse && !type->tp_clear)) { + type->tp_flags |= Py_TPFLAGS_HAVE_GC; + if (type->tp_traverse == NULL) + type->tp_traverse = base->tp_traverse; + if (type->tp_clear == NULL) + type->tp_clear = base->tp_clear; + } + { + /* The condition below could use some explanation. + It appears that tp_new is not inherited for static types + whose base class is 'object'; this seems to be a precaution + so that old extension types don't suddenly become + callable (object.__new__ wouldn't insure the invariants + that the extension type's own factory function ensures). + Heap types, of course, are under our control, so they do + inherit tp_new; static extension types that specify some + other built-in type as the default also + inherit object.__new__. */ + if (base != &PyBaseObject_Type || + (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (type->tp_new == NULL) + type->tp_new = base->tp_new; + } + } + if (type->tp_basicsize == 0) + type->tp_basicsize = base->tp_basicsize; + + /* Copy other non-function slots */ + +#undef COPYVAL +#define COPYVAL(SLOT) \ + if (type->SLOT == 0) type->SLOT = base->SLOT + + COPYVAL(tp_itemsize); + COPYVAL(tp_weaklistoffset); + COPYVAL(tp_dictoffset); + + /* Setup fast subclass flags */ + if (PyType_IsSubtype(base, (PyTypeObject*)PyExc_BaseException)) + type->tp_flags |= Py_TPFLAGS_BASE_EXC_SUBCLASS; + else if (PyType_IsSubtype(base, &PyType_Type)) + type->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS; + else if (PyType_IsSubtype(base, &PyLong_Type)) + type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS; + else if (PyType_IsSubtype(base, &PyBytes_Type)) + type->tp_flags |= Py_TPFLAGS_BYTES_SUBCLASS; + else if (PyType_IsSubtype(base, &PyUnicode_Type)) + type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS; + else if (PyType_IsSubtype(base, &PyTuple_Type)) + type->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS; + else if (PyType_IsSubtype(base, &PyList_Type)) + type->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS; + else if (PyType_IsSubtype(base, &PyDict_Type)) + type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; +} + +static int +overrides_hash(PyTypeObject *type) +{ + PyObject *dict = type->tp_dict; + _Py_IDENTIFIER(__eq__); + + assert(dict != NULL); + if (_PyDict_GetItemId(dict, &PyId___eq__) != NULL) + return 1; + if (_PyDict_GetItemId(dict, &PyId___hash__) != NULL) + return 1; + return 0; +} + +static void +inherit_slots(PyTypeObject *type, PyTypeObject *base) +{ + PyTypeObject *basebase; + +#undef SLOTDEFINED +#undef COPYSLOT +#undef COPYNUM +#undef COPYSEQ +#undef COPYMAP +#undef COPYBUF + +#define SLOTDEFINED(SLOT) \ + (base->SLOT != 0 && \ + (basebase == NULL || base->SLOT != basebase->SLOT)) + +#define COPYSLOT(SLOT) \ + if (!type->SLOT && SLOTDEFINED(SLOT)) type->SLOT = base->SLOT + +#define COPYASYNC(SLOT) COPYSLOT(tp_as_async->SLOT) +#define COPYNUM(SLOT) COPYSLOT(tp_as_number->SLOT) +#define COPYSEQ(SLOT) COPYSLOT(tp_as_sequence->SLOT) +#define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT) +#define COPYBUF(SLOT) COPYSLOT(tp_as_buffer->SLOT) + + /* This won't inherit indirect slots (from tp_as_number etc.) + if type doesn't provide the space. */ + + if (type->tp_as_number != NULL && base->tp_as_number != NULL) { + basebase = base->tp_base; + if (basebase->tp_as_number == NULL) + basebase = NULL; + COPYNUM(nb_add); + COPYNUM(nb_subtract); + COPYNUM(nb_multiply); + COPYNUM(nb_remainder); + COPYNUM(nb_divmod); + COPYNUM(nb_power); + COPYNUM(nb_negative); + COPYNUM(nb_positive); + COPYNUM(nb_absolute); + COPYNUM(nb_bool); + COPYNUM(nb_invert); + COPYNUM(nb_lshift); + COPYNUM(nb_rshift); + COPYNUM(nb_and); + COPYNUM(nb_xor); + COPYNUM(nb_or); + COPYNUM(nb_int); + COPYNUM(nb_float); + COPYNUM(nb_inplace_add); + COPYNUM(nb_inplace_subtract); + COPYNUM(nb_inplace_multiply); + COPYNUM(nb_inplace_remainder); + COPYNUM(nb_inplace_power); + COPYNUM(nb_inplace_lshift); + COPYNUM(nb_inplace_rshift); + COPYNUM(nb_inplace_and); + COPYNUM(nb_inplace_xor); + COPYNUM(nb_inplace_or); + COPYNUM(nb_true_divide); + COPYNUM(nb_floor_divide); + COPYNUM(nb_inplace_true_divide); + COPYNUM(nb_inplace_floor_divide); + COPYNUM(nb_index); + COPYNUM(nb_matrix_multiply); + COPYNUM(nb_inplace_matrix_multiply); + } + + if (type->tp_as_async != NULL && base->tp_as_async != NULL) { + basebase = base->tp_base; + if (basebase->tp_as_async == NULL) + basebase = NULL; + COPYASYNC(am_await); + COPYASYNC(am_aiter); + COPYASYNC(am_anext); + } + + if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) { + basebase = base->tp_base; + if (basebase->tp_as_sequence == NULL) + basebase = NULL; + COPYSEQ(sq_length); + COPYSEQ(sq_concat); + COPYSEQ(sq_repeat); + COPYSEQ(sq_item); + COPYSEQ(sq_ass_item); + COPYSEQ(sq_contains); + COPYSEQ(sq_inplace_concat); + COPYSEQ(sq_inplace_repeat); + } + + if (type->tp_as_mapping != NULL && base->tp_as_mapping != NULL) { + basebase = base->tp_base; + if (basebase->tp_as_mapping == NULL) + basebase = NULL; + COPYMAP(mp_length); + COPYMAP(mp_subscript); + COPYMAP(mp_ass_subscript); + } + + if (type->tp_as_buffer != NULL && base->tp_as_buffer != NULL) { + basebase = base->tp_base; + if (basebase->tp_as_buffer == NULL) + basebase = NULL; + COPYBUF(bf_getbuffer); + COPYBUF(bf_releasebuffer); + } + + basebase = base->tp_base; + + COPYSLOT(tp_dealloc); + if (type->tp_getattr == NULL && type->tp_getattro == NULL) { + type->tp_getattr = base->tp_getattr; + type->tp_getattro = base->tp_getattro; + } + if (type->tp_setattr == NULL && type->tp_setattro == NULL) { + type->tp_setattr = base->tp_setattr; + type->tp_setattro = base->tp_setattro; + } + COPYSLOT(tp_repr); + /* tp_hash see tp_richcompare */ + { + /* Always inherit tp_vectorcall_offset to support PyVectorcall_Call(). + * If _Py_TPFLAGS_HAVE_VECTORCALL is not inherited, then vectorcall + * won't be used automatically. */ + COPYSLOT(tp_vectorcall_offset); + + /* Inherit _Py_TPFLAGS_HAVE_VECTORCALL for non-heap types + * if tp_call is not overridden */ + if (!type->tp_call && + (base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && + !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + { + type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; + } + COPYSLOT(tp_call); + } + COPYSLOT(tp_str); + { + /* Copy comparison-related slots only when + not overriding them anywhere */ + if (type->tp_richcompare == NULL && + type->tp_hash == NULL && + !overrides_hash(type)) + { + type->tp_richcompare = base->tp_richcompare; + type->tp_hash = base->tp_hash; + } + } + { + COPYSLOT(tp_iter); + COPYSLOT(tp_iternext); + } + { + COPYSLOT(tp_descr_get); + /* Inherit Py_TPFLAGS_METHOD_DESCRIPTOR if tp_descr_get was inherited, + * but only for extension types */ + if (base->tp_descr_get && + type->tp_descr_get == base->tp_descr_get && + !(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && + (base->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR)) + { + type->tp_flags |= Py_TPFLAGS_METHOD_DESCRIPTOR; + } + COPYSLOT(tp_descr_set); + COPYSLOT(tp_dictoffset); + COPYSLOT(tp_init); + COPYSLOT(tp_alloc); + COPYSLOT(tp_is_gc); + COPYSLOT(tp_finalize); + if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) == + (base->tp_flags & Py_TPFLAGS_HAVE_GC)) { + /* They agree about gc. */ + COPYSLOT(tp_free); + } + else if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) && + type->tp_free == NULL && + base->tp_free == PyObject_Free) { + /* A bit of magic to plug in the correct default + * tp_free function when a derived class adds gc, + * didn't define tp_free, and the base uses the + * default non-gc tp_free. + */ + type->tp_free = PyObject_GC_Del; + } + /* else they didn't agree about gc, and there isn't something + * obvious to be done -- the type is on its own. + */ + } +} + +static int add_operators(PyTypeObject *); + +int +PyType_Ready(PyTypeObject *type) +{ + PyObject *dict, *bases; + PyTypeObject *base; + Py_ssize_t i, n; + + if (type->tp_flags & Py_TPFLAGS_READY) { + assert(_PyType_CheckConsistency(type)); + return 0; + } + _PyObject_ASSERT((PyObject *)type, + (type->tp_flags & Py_TPFLAGS_READYING) == 0); + + /* Consistency checks for PEP 590: + * - Py_TPFLAGS_METHOD_DESCRIPTOR requires tp_descr_get + * - _Py_TPFLAGS_HAVE_VECTORCALL requires tp_call and + * tp_vectorcall_offset > 0 + * To avoid mistakes, we require this before inheriting. + */ + if (type->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) { + _PyObject_ASSERT((PyObject *)type, type->tp_descr_get != NULL); + } + if (type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) { + _PyObject_ASSERT((PyObject *)type, type->tp_vectorcall_offset > 0); + _PyObject_ASSERT((PyObject *)type, type->tp_call != NULL); + } + + type->tp_flags |= Py_TPFLAGS_READYING; + +#ifdef Py_TRACE_REFS + /* PyType_Ready is the closest thing we have to a choke point + * for type objects, so is the best place I can think of to try + * to get type objects into the doubly-linked list of all objects. + * Still, not all type objects go through PyType_Ready. + */ + _Py_AddToAllObjects((PyObject *)type, 0); +#endif + + if (type->tp_name == NULL) { + PyErr_Format(PyExc_SystemError, + "Type does not define the tp_name field."); + goto error; + } + + /* Initialize tp_base (defaults to BaseObject unless that's us) */ + base = type->tp_base; + if (base == NULL && type != &PyBaseObject_Type) { + base = type->tp_base = &PyBaseObject_Type; + Py_INCREF(base); + } + + /* Now the only way base can still be NULL is if type is + * &PyBaseObject_Type. + */ + + /* Initialize the base class */ + if (base != NULL && base->tp_dict == NULL) { + if (PyType_Ready(base) < 0) + goto error; + } + + /* Initialize ob_type if NULL. This means extensions that want to be + compilable separately on Windows can call PyType_Ready() instead of + initializing the ob_type field of their type objects. */ + /* The test for base != NULL is really unnecessary, since base is only + NULL when type is &PyBaseObject_Type, and we know its ob_type is + not NULL (it's initialized to &PyType_Type). But coverity doesn't + know that. */ + if (Py_TYPE(type) == NULL && base != NULL) + Py_TYPE(type) = Py_TYPE(base); + + /* Initialize tp_bases */ + bases = type->tp_bases; + if (bases == NULL) { + if (base == NULL) + bases = PyTuple_New(0); + else + bases = PyTuple_Pack(1, base); + if (bases == NULL) + goto error; + type->tp_bases = bases; + } + + /* Initialize tp_dict */ + dict = type->tp_dict; + if (dict == NULL) { + dict = PyDict_New(); + if (dict == NULL) + goto error; + type->tp_dict = dict; + } + + /* Add type-specific descriptors to tp_dict */ + if (add_operators(type) < 0) + goto error; + if (type->tp_methods != NULL) { + if (add_methods(type, type->tp_methods) < 0) + goto error; + } + if (type->tp_members != NULL) { + if (add_members(type, type->tp_members) < 0) + goto error; + } + if (type->tp_getset != NULL) { + if (add_getset(type, type->tp_getset) < 0) + goto error; + } + + /* Calculate method resolution order */ + if (mro_internal(type, NULL) < 0) + goto error; + + /* Inherit special flags from dominant base */ + if (type->tp_base != NULL) + inherit_special(type, type->tp_base); + + /* Initialize tp_dict properly */ + bases = type->tp_mro; + assert(bases != NULL); + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + for (i = 1; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(b)) + inherit_slots(type, (PyTypeObject *)b); + } + + /* All bases of statically allocated type should be statically allocated */ + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(b) && + (((PyTypeObject *)b)->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_TypeError, + "type '%.100s' is not dynamically allocated but " + "its base type '%.100s' is dynamically allocated", + type->tp_name, ((PyTypeObject *)b)->tp_name); + goto error; + } + } + + /* Sanity check for tp_free. */ + if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) && + (type->tp_free == NULL || type->tp_free == PyObject_Del)) { + /* This base class needs to call tp_free, but doesn't have + * one, or its tp_free is for non-gc'ed objects. + */ + PyErr_Format(PyExc_TypeError, "type '%.100s' participates in " + "gc and is a base type but has inappropriate " + "tp_free slot", + type->tp_name); + goto error; + } + + /* if the type dictionary doesn't contain a __doc__, set it from + the tp_doc slot. + */ + if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___doc__) == NULL) { + if (PyErr_Occurred()) { + goto error; + } + if (type->tp_doc != NULL) { + const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, + type->tp_doc); + PyObject *doc = PyUnicode_FromString(old_doc); + if (doc == NULL) + goto error; + if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) { + Py_DECREF(doc); + goto error; + } + Py_DECREF(doc); + } else { + if (_PyDict_SetItemId(type->tp_dict, + &PyId___doc__, Py_None) < 0) + goto error; + } + } + + /* Hack for tp_hash and __hash__. + If after all that, tp_hash is still NULL, and __hash__ is not in + tp_dict, set tp_hash to PyObject_HashNotImplemented and + tp_dict['__hash__'] equal to None. + This signals that __hash__ is not inherited. + */ + if (type->tp_hash == NULL) { + if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___hash__) == NULL) { + if (PyErr_Occurred() || + _PyDict_SetItemId(type->tp_dict, &PyId___hash__, Py_None) < 0) + { + goto error; + } + type->tp_hash = PyObject_HashNotImplemented; + } + } + + /* Some more special stuff */ + base = type->tp_base; + if (base != NULL) { + if (type->tp_as_async == NULL) + type->tp_as_async = base->tp_as_async; + if (type->tp_as_number == NULL) + type->tp_as_number = base->tp_as_number; + if (type->tp_as_sequence == NULL) + type->tp_as_sequence = base->tp_as_sequence; + if (type->tp_as_mapping == NULL) + type->tp_as_mapping = base->tp_as_mapping; + if (type->tp_as_buffer == NULL) + type->tp_as_buffer = base->tp_as_buffer; + } + + /* Link into each base class's list of subclasses */ + bases = type->tp_bases; + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(b) && + add_subclass((PyTypeObject *)b, type) < 0) + goto error; + } + + /* All done -- set the ready flag */ + type->tp_flags = + (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; + assert(_PyType_CheckConsistency(type)); + return 0; + + error: + type->tp_flags &= ~Py_TPFLAGS_READYING; + return -1; +} + +static int +add_subclass(PyTypeObject *base, PyTypeObject *type) +{ + int result = -1; + PyObject *dict, *key, *newobj; + + dict = base->tp_subclasses; + if (dict == NULL) { + base->tp_subclasses = dict = PyDict_New(); + if (dict == NULL) + return -1; + } + assert(PyDict_CheckExact(dict)); + key = PyLong_FromVoidPtr((void *) type); + if (key == NULL) + return -1; + newobj = PyWeakref_NewRef((PyObject *)type, NULL); + if (newobj != NULL) { + result = PyDict_SetItem(dict, key, newobj); + Py_DECREF(newobj); + } + Py_DECREF(key); + return result; +} + +static int +add_all_subclasses(PyTypeObject *type, PyObject *bases) +{ + int res = 0; + + if (bases) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(bases); i++) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(base) && + add_subclass((PyTypeObject*)base, type) < 0) + res = -1; + } + } + + return res; +} + +static void +remove_subclass(PyTypeObject *base, PyTypeObject *type) +{ + PyObject *dict, *key; + + dict = base->tp_subclasses; + if (dict == NULL) { + return; + } + assert(PyDict_CheckExact(dict)); + key = PyLong_FromVoidPtr((void *) type); + if (key == NULL || PyDict_DelItem(dict, key)) { + /* This can happen if the type initialization errored out before + the base subclasses were updated (e.g. a non-str __qualname__ + was passed in the type dict). */ + PyErr_Clear(); + } + Py_XDECREF(key); +} + +static void +remove_all_subclasses(PyTypeObject *type, PyObject *bases) +{ + if (bases) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(bases); i++) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(base)) + remove_subclass((PyTypeObject*) base, type); + } + } +} + +static int +check_num_args(PyObject *ob, int n) +{ + if (!PyTuple_CheckExact(ob)) { + PyErr_SetString(PyExc_SystemError, + "PyArg_UnpackTuple() argument list is not a tuple"); + return 0; + } + if (n == PyTuple_GET_SIZE(ob)) + return 1; + PyErr_Format( + PyExc_TypeError, + "expected %d argument%s, got %zd", n, n == 1 ? "" : "s", PyTuple_GET_SIZE(ob)); + return 0; +} + +/* Generic wrappers for overloadable 'operators' such as __getitem__ */ + +/* There's a wrapper *function* for each distinct function typedef used + for type object slots (e.g. binaryfunc, ternaryfunc, etc.). There's a + wrapper *table* for each distinct operation (e.g. __len__, __add__). + Most tables have only one entry; the tables for binary operators have two + entries, one regular and one with reversed arguments. */ + +static PyObject * +wrap_lenfunc(PyObject *self, PyObject *args, void *wrapped) +{ + lenfunc func = (lenfunc)wrapped; + Py_ssize_t res; + + if (!check_num_args(args, 0)) + return NULL; + res = (*func)(self); + if (res == -1 && PyErr_Occurred()) + return NULL; + return PyLong_FromSsize_t(res); +} + +static PyObject * +wrap_inquirypred(PyObject *self, PyObject *args, void *wrapped) +{ + inquiry func = (inquiry)wrapped; + int res; + + if (!check_num_args(args, 0)) + return NULL; + res = (*func)(self); + if (res == -1 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)res); +} + +static PyObject * +wrap_binaryfunc(PyObject *self, PyObject *args, void *wrapped) +{ + binaryfunc func = (binaryfunc)wrapped; + PyObject *other; + + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + return (*func)(self, other); +} + +static PyObject * +wrap_binaryfunc_l(PyObject *self, PyObject *args, void *wrapped) +{ + binaryfunc func = (binaryfunc)wrapped; + PyObject *other; + + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + return (*func)(self, other); +} + +static PyObject * +wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped) +{ + binaryfunc func = (binaryfunc)wrapped; + PyObject *other; + + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + return (*func)(other, self); +} + +static PyObject * +wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped) +{ + ternaryfunc func = (ternaryfunc)wrapped; + PyObject *other; + PyObject *third = Py_None; + + /* Note: This wrapper only works for __pow__() */ + + if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third)) + return NULL; + return (*func)(self, other, third); +} + +static PyObject * +wrap_ternaryfunc_r(PyObject *self, PyObject *args, void *wrapped) +{ + ternaryfunc func = (ternaryfunc)wrapped; + PyObject *other; + PyObject *third = Py_None; + + /* Note: This wrapper only works for __pow__() */ + + if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third)) + return NULL; + return (*func)(other, self, third); +} + +static PyObject * +wrap_unaryfunc(PyObject *self, PyObject *args, void *wrapped) +{ + unaryfunc func = (unaryfunc)wrapped; + + if (!check_num_args(args, 0)) + return NULL; + return (*func)(self); +} + +static PyObject * +wrap_indexargfunc(PyObject *self, PyObject *args, void *wrapped) +{ + ssizeargfunc func = (ssizeargfunc)wrapped; + PyObject* o; + Py_ssize_t i; + + if (!PyArg_UnpackTuple(args, "", 1, 1, &o)) + return NULL; + i = PyNumber_AsSsize_t(o, PyExc_OverflowError); + if (i == -1 && PyErr_Occurred()) + return NULL; + return (*func)(self, i); +} + +static Py_ssize_t +getindex(PyObject *self, PyObject *arg) +{ + Py_ssize_t i; + + i = PyNumber_AsSsize_t(arg, PyExc_OverflowError); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) { + PySequenceMethods *sq = Py_TYPE(self)->tp_as_sequence; + if (sq && sq->sq_length) { + Py_ssize_t n = (*sq->sq_length)(self); + if (n < 0) { + assert(PyErr_Occurred()); + return -1; + } + i += n; + } + } + return i; +} + +static PyObject * +wrap_sq_item(PyObject *self, PyObject *args, void *wrapped) +{ + ssizeargfunc func = (ssizeargfunc)wrapped; + PyObject *arg; + Py_ssize_t i; + + if (PyTuple_GET_SIZE(args) == 1) { + arg = PyTuple_GET_ITEM(args, 0); + i = getindex(self, arg); + if (i == -1 && PyErr_Occurred()) + return NULL; + return (*func)(self, i); + } + check_num_args(args, 1); + assert(PyErr_Occurred()); + return NULL; +} + +static PyObject * +wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped) +{ + ssizeobjargproc func = (ssizeobjargproc)wrapped; + Py_ssize_t i; + int res; + PyObject *arg, *value; + + if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value)) + return NULL; + i = getindex(self, arg); + if (i == -1 && PyErr_Occurred()) + return NULL; + res = (*func)(self, i, value); + if (res == -1 && PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped) +{ + ssizeobjargproc func = (ssizeobjargproc)wrapped; + Py_ssize_t i; + int res; + PyObject *arg; + + if (!check_num_args(args, 1)) + return NULL; + arg = PyTuple_GET_ITEM(args, 0); + i = getindex(self, arg); + if (i == -1 && PyErr_Occurred()) + return NULL; + res = (*func)(self, i, NULL); + if (res == -1 && PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +/* XXX objobjproc is a misnomer; should be objargpred */ +static PyObject * +wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped) +{ + objobjproc func = (objobjproc)wrapped; + int res; + PyObject *value; + + if (!check_num_args(args, 1)) + return NULL; + value = PyTuple_GET_ITEM(args, 0); + res = (*func)(self, value); + if (res == -1 && PyErr_Occurred()) + return NULL; + else + return PyBool_FromLong(res); +} + +static PyObject * +wrap_objobjargproc(PyObject *self, PyObject *args, void *wrapped) +{ + objobjargproc func = (objobjargproc)wrapped; + int res; + PyObject *key, *value; + + if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value)) + return NULL; + res = (*func)(self, key, value); + if (res == -1 && PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +wrap_delitem(PyObject *self, PyObject *args, void *wrapped) +{ + objobjargproc func = (objobjargproc)wrapped; + int res; + PyObject *key; + + if (!check_num_args(args, 1)) + return NULL; + key = PyTuple_GET_ITEM(args, 0); + res = (*func)(self, key, NULL); + if (res == -1 && PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +/* Helper to check for object.__setattr__ or __delattr__ applied to a type. + This is called the Carlo Verre hack after its discoverer. See + https://mail.python.org/pipermail/python-dev/2003-April/034535.html + */ +static int +hackcheck(PyObject *self, setattrofunc func, const char *what) +{ + PyTypeObject *type = Py_TYPE(self); + PyObject *mro = type->tp_mro; + if (!mro) { + /* Probably ok not to check the call in this case. */ + return 1; + } + assert(PyTuple_Check(mro)); + + /* Find the (base) type that defined the type's slot function. */ + PyTypeObject *defining_type = type; + Py_ssize_t i; + for (i = PyTuple_GET_SIZE(mro) - 1; i >= 0; i--) { + PyTypeObject *base = (PyTypeObject*) PyTuple_GET_ITEM(mro, i); + if (base->tp_setattro == slot_tp_setattro) { + /* Ignore Python classes: + they never define their own C-level setattro. */ + } + else if (base->tp_setattro == type->tp_setattro) { + defining_type = base; + break; + } + } + + /* Reject calls that jump over intermediate C-level overrides. */ + for (PyTypeObject *base = defining_type; base; base = base->tp_base) { + if (base->tp_setattro == func) { + /* 'func' is the right slot function to call. */ + break; + } + else if (base->tp_setattro != slot_tp_setattro) { + /* 'base' is not a Python class and overrides 'func'. + Its tp_setattro should be called instead. */ + PyErr_Format(PyExc_TypeError, + "can't apply this %s to %s object", + what, + type->tp_name); + return 0; + } + } + return 1; +} + +static PyObject * +wrap_setattr(PyObject *self, PyObject *args, void *wrapped) +{ + setattrofunc func = (setattrofunc)wrapped; + int res; + PyObject *name, *value; + + if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value)) + return NULL; + if (!hackcheck(self, func, "__setattr__")) + return NULL; + res = (*func)(self, name, value); + if (res < 0) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +wrap_delattr(PyObject *self, PyObject *args, void *wrapped) +{ + setattrofunc func = (setattrofunc)wrapped; + int res; + PyObject *name; + + if (!check_num_args(args, 1)) + return NULL; + name = PyTuple_GET_ITEM(args, 0); + if (!hackcheck(self, func, "__delattr__")) + return NULL; + res = (*func)(self, name, NULL); + if (res < 0) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped) +{ + hashfunc func = (hashfunc)wrapped; + Py_hash_t res; + + if (!check_num_args(args, 0)) + return NULL; + res = (*func)(self); + if (res == -1 && PyErr_Occurred()) + return NULL; + return PyLong_FromSsize_t(res); +} + +static PyObject * +wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) +{ + ternaryfunc func = (ternaryfunc)wrapped; + + return (*func)(self, args, kwds); +} + +static PyObject * +wrap_del(PyObject *self, PyObject *args, void *wrapped) +{ + destructor func = (destructor)wrapped; + + if (!check_num_args(args, 0)) + return NULL; + + (*func)(self); + Py_RETURN_NONE; +} + +static PyObject * +wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op) +{ + richcmpfunc func = (richcmpfunc)wrapped; + PyObject *other; + + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + return (*func)(self, other, op); +} + +#undef RICHCMP_WRAPPER +#define RICHCMP_WRAPPER(NAME, OP) \ +static PyObject * \ +richcmp_##NAME(PyObject *self, PyObject *args, void *wrapped) \ +{ \ + return wrap_richcmpfunc(self, args, wrapped, OP); \ +} + +RICHCMP_WRAPPER(lt, Py_LT) +RICHCMP_WRAPPER(le, Py_LE) +RICHCMP_WRAPPER(eq, Py_EQ) +RICHCMP_WRAPPER(ne, Py_NE) +RICHCMP_WRAPPER(gt, Py_GT) +RICHCMP_WRAPPER(ge, Py_GE) + +static PyObject * +wrap_next(PyObject *self, PyObject *args, void *wrapped) +{ + unaryfunc func = (unaryfunc)wrapped; + PyObject *res; + + if (!check_num_args(args, 0)) + return NULL; + res = (*func)(self); + if (res == NULL && !PyErr_Occurred()) + PyErr_SetNone(PyExc_StopIteration); + return res; +} + +static PyObject * +wrap_descr_get(PyObject *self, PyObject *args, void *wrapped) +{ + descrgetfunc func = (descrgetfunc)wrapped; + PyObject *obj; + PyObject *type = NULL; + + if (!PyArg_UnpackTuple(args, "", 1, 2, &obj, &type)) + return NULL; + if (obj == Py_None) + obj = NULL; + if (type == Py_None) + type = NULL; + if (type == NULL &&obj == NULL) { + PyErr_SetString(PyExc_TypeError, + "__get__(None, None) is invalid"); + return NULL; + } + return (*func)(self, obj, type); +} + +static PyObject * +wrap_descr_set(PyObject *self, PyObject *args, void *wrapped) +{ + descrsetfunc func = (descrsetfunc)wrapped; + PyObject *obj, *value; + int ret; + + if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value)) + return NULL; + ret = (*func)(self, obj, value); + if (ret < 0) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped) +{ + descrsetfunc func = (descrsetfunc)wrapped; + PyObject *obj; + int ret; + + if (!check_num_args(args, 1)) + return NULL; + obj = PyTuple_GET_ITEM(args, 0); + ret = (*func)(self, obj, NULL); + if (ret < 0) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) +{ + initproc func = (initproc)wrapped; + + if (func(self, args, kwds) < 0) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyTypeObject *type, *subtype, *staticbase; + PyObject *arg0, *res; + + if (self == NULL || !PyType_Check(self)) + Py_FatalError("__new__() called with non-type 'self'"); + type = (PyTypeObject *)self; + if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 1) { + PyErr_Format(PyExc_TypeError, + "%s.__new__(): not enough arguments", + type->tp_name); + return NULL; + } + arg0 = PyTuple_GET_ITEM(args, 0); + if (!PyType_Check(arg0)) { + PyErr_Format(PyExc_TypeError, + "%s.__new__(X): X is not a type object (%s)", + type->tp_name, + Py_TYPE(arg0)->tp_name); + return NULL; + } + subtype = (PyTypeObject *)arg0; + if (!PyType_IsSubtype(subtype, type)) { + PyErr_Format(PyExc_TypeError, + "%s.__new__(%s): %s is not a subtype of %s", + type->tp_name, + subtype->tp_name, + subtype->tp_name, + type->tp_name); + return NULL; + } + + /* Check that the use doesn't do something silly and unsafe like + object.__new__(dict). To do this, we check that the + most derived base that's not a heap type is this type. */ + staticbase = subtype; + while (staticbase && (staticbase->tp_new == slot_tp_new)) + staticbase = staticbase->tp_base; + /* If staticbase is NULL now, it is a really weird type. + In the spirit of backwards compatibility (?), just shut up. */ + if (staticbase && staticbase->tp_new != type->tp_new) { + PyErr_Format(PyExc_TypeError, + "%s.__new__(%s) is not safe, use %s.__new__()", + type->tp_name, + subtype->tp_name, + staticbase->tp_name); + return NULL; + } + + args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + if (args == NULL) + return NULL; + res = type->tp_new(subtype, args, kwds); + Py_DECREF(args); + return res; +} + +static struct PyMethodDef tp_new_methoddef[] = { + {"__new__", (PyCFunction)(void(*)(void))tp_new_wrapper, METH_VARARGS|METH_KEYWORDS, + PyDoc_STR("__new__($type, *args, **kwargs)\n--\n\n" + "Create and return a new object. " + "See help(type) for accurate signature.")}, + {0} +}; + +static int +add_tp_new_wrapper(PyTypeObject *type) +{ + PyObject *func; + + if (_PyDict_GetItemIdWithError(type->tp_dict, &PyId___new__) != NULL) + return 0; + if (PyErr_Occurred()) + return -1; + func = PyCFunction_NewEx(tp_new_methoddef, (PyObject *)type, NULL); + if (func == NULL) + return -1; + if (_PyDict_SetItemId(type->tp_dict, &PyId___new__, func)) { + Py_DECREF(func); + return -1; + } + Py_DECREF(func); + return 0; +} + +/* Slot wrappers that call the corresponding __foo__ slot. See comments + below at override_slots() for more explanation. */ + +#define SLOT0(FUNCNAME, OPSTR) \ +static PyObject * \ +FUNCNAME(PyObject *self) \ +{ \ + _Py_static_string(id, OPSTR); \ + return call_method(self, &id, NULL, 0); \ +} + +#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE) \ +static PyObject * \ +FUNCNAME(PyObject *self, ARG1TYPE arg1) \ +{ \ + PyObject* stack[1] = {arg1}; \ + _Py_static_string(id, OPSTR); \ + return call_method(self, &id, stack, 1); \ +} + +/* Boolean helper for SLOT1BINFULL(). + right.__class__ is a nontrivial subclass of left.__class__. */ +static int +method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *name) +{ + PyObject *a, *b; + int ok; + + if (_PyObject_LookupAttrId((PyObject *)(Py_TYPE(right)), name, &b) < 0) { + return -1; + } + if (b == NULL) { + /* If right doesn't have it, it's not overloaded */ + return 0; + } + + if (_PyObject_LookupAttrId((PyObject *)(Py_TYPE(left)), name, &a) < 0) { + Py_DECREF(b); + return -1; + } + if (a == NULL) { + Py_DECREF(b); + /* If right has it but left doesn't, it's overloaded */ + return 1; + } + + ok = PyObject_RichCompareBool(a, b, Py_NE); + Py_DECREF(a); + Py_DECREF(b); + return ok; +} + + +#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \ +static PyObject * \ +FUNCNAME(PyObject *self, PyObject *other) \ +{ \ + PyObject* stack[1]; \ + _Py_static_string(op_id, OPSTR); \ + _Py_static_string(rop_id, ROPSTR); \ + int do_other = Py_TYPE(self) != Py_TYPE(other) && \ + Py_TYPE(other)->tp_as_number != NULL && \ + Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC; \ + if (Py_TYPE(self)->tp_as_number != NULL && \ + Py_TYPE(self)->tp_as_number->SLOTNAME == TESTFUNC) { \ + PyObject *r; \ + if (do_other && PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { \ + int ok = method_is_overloaded(self, other, &rop_id); \ + if (ok < 0) { \ + return NULL; \ + } \ + if (ok) { \ + stack[0] = self; \ + r = call_maybe(other, &rop_id, stack, 1); \ + if (r != Py_NotImplemented) \ + return r; \ + Py_DECREF(r); \ + do_other = 0; \ + } \ + } \ + stack[0] = other; \ + r = call_maybe(self, &op_id, stack, 1); \ + if (r != Py_NotImplemented || \ + Py_TYPE(other) == Py_TYPE(self)) \ + return r; \ + Py_DECREF(r); \ + } \ + if (do_other) { \ + stack[0] = self; \ + return call_maybe(other, &rop_id, stack, 1); \ + } \ + Py_RETURN_NOTIMPLEMENTED; \ +} + +#define SLOT1BIN(FUNCNAME, SLOTNAME, OPSTR, ROPSTR) \ + SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, OPSTR, ROPSTR) + +static Py_ssize_t +slot_sq_length(PyObject *self) +{ + PyObject *res = call_method(self, &PyId___len__, NULL, 0); + Py_ssize_t len; + + if (res == NULL) + return -1; + + Py_SETREF(res, PyNumber_Index(res)); + if (res == NULL) + return -1; + + assert(PyLong_Check(res)); + if (Py_SIZE(res) < 0) { + Py_DECREF(res); + PyErr_SetString(PyExc_ValueError, + "__len__() should return >= 0"); + return -1; + } + + len = PyNumber_AsSsize_t(res, PyExc_OverflowError); + assert(len >= 0 || PyErr_ExceptionMatches(PyExc_OverflowError)); + Py_DECREF(res); + return len; +} + +static PyObject * +slot_sq_item(PyObject *self, Py_ssize_t i) +{ + PyObject *retval; + PyObject *args[1]; + PyObject *ival = PyLong_FromSsize_t(i); + if (ival == NULL) { + return NULL; + } + args[0] = ival; + retval = call_method(self, &PyId___getitem__, args, 1); + Py_DECREF(ival); + return retval; +} + +static int +slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) +{ + PyObject *stack[2]; + PyObject *res; + PyObject *index_obj; + + index_obj = PyLong_FromSsize_t(index); + if (index_obj == NULL) { + return -1; + } + + stack[0] = index_obj; + if (value == NULL) { + res = call_method(self, &PyId___delitem__, stack, 1); + } + else { + stack[1] = value; + res = call_method(self, &PyId___setitem__, stack, 2); + } + Py_DECREF(index_obj); + + if (res == NULL) { + return -1; + } + Py_DECREF(res); + return 0; +} + +static int +slot_sq_contains(PyObject *self, PyObject *value) +{ + PyObject *func, *res; + int result = -1, unbound; + _Py_IDENTIFIER(__contains__); + + func = lookup_maybe_method(self, &PyId___contains__, &unbound); + if (func == Py_None) { + Py_DECREF(func); + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not a container", + Py_TYPE(self)->tp_name); + return -1; + } + if (func != NULL) { + PyObject *args[1] = {value}; + res = call_unbound(unbound, func, self, args, 1); + Py_DECREF(func); + if (res != NULL) { + result = PyObject_IsTrue(res); + Py_DECREF(res); + } + } + else if (! PyErr_Occurred()) { + /* Possible results: -1 and 1 */ + result = (int)_PySequence_IterSearch(self, value, + PY_ITERSEARCH_CONTAINS); + } + return result; +} + +#define slot_mp_length slot_sq_length + +SLOT1(slot_mp_subscript, "__getitem__", PyObject *) + +static int +slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) +{ + PyObject *stack[2]; + PyObject *res; + + stack[0] = key; + if (value == NULL) { + res = call_method(self, &PyId___delitem__, stack, 1); + } + else { + stack[1] = value; + res = call_method(self, &PyId___setitem__, stack, 2); + } + + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__") +SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__") +SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__") +SLOT1BIN(slot_nb_matrix_multiply, nb_matrix_multiply, "__matmul__", "__rmatmul__") +SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__") +SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__") + +static PyObject *slot_nb_power(PyObject *, PyObject *, PyObject *); + +SLOT1BINFULL(slot_nb_power_binary, slot_nb_power, + nb_power, "__pow__", "__rpow__") + +static PyObject * +slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) +{ + _Py_IDENTIFIER(__pow__); + + if (modulus == Py_None) + return slot_nb_power_binary(self, other); + /* Three-arg power doesn't use __rpow__. But ternary_op + can call this when the second argument's type uses + slot_nb_power, so check before calling self.__pow__. */ + if (Py_TYPE(self)->tp_as_number != NULL && + Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { + PyObject* stack[2] = {other, modulus}; + return call_method(self, &PyId___pow__, stack, 2); + } + Py_RETURN_NOTIMPLEMENTED; +} + +SLOT0(slot_nb_negative, "__neg__") +SLOT0(slot_nb_positive, "__pos__") +SLOT0(slot_nb_absolute, "__abs__") + +static int +slot_nb_bool(PyObject *self) +{ + PyObject *func, *value; + int result, unbound; + int using_len = 0; + _Py_IDENTIFIER(__bool__); + + func = lookup_maybe_method(self, &PyId___bool__, &unbound); + if (func == NULL) { + if (PyErr_Occurred()) { + return -1; + } + + func = lookup_maybe_method(self, &PyId___len__, &unbound); + if (func == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 1; + } + using_len = 1; + } + + value = call_unbound_noarg(unbound, func, self); + if (value == NULL) { + goto error; + } + + if (using_len) { + /* bool type enforced by slot_nb_len */ + result = PyObject_IsTrue(value); + } + else if (PyBool_Check(value)) { + result = PyObject_IsTrue(value); + } + else { + PyErr_Format(PyExc_TypeError, + "__bool__ should return " + "bool, returned %s", + Py_TYPE(value)->tp_name); + result = -1; + } + + Py_DECREF(value); + Py_DECREF(func); + return result; + +error: + Py_DECREF(func); + return -1; +} + + +static PyObject * +slot_nb_index(PyObject *self) +{ + _Py_IDENTIFIER(__index__); + return call_method(self, &PyId___index__, NULL, 0); +} + + +SLOT0(slot_nb_invert, "__invert__") +SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__") +SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__") +SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__") +SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__") +SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") + +SLOT0(slot_nb_int, "__int__") +SLOT0(slot_nb_float, "__float__") +SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *) +SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *) +SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *) +SLOT1(slot_nb_inplace_matrix_multiply, "__imatmul__", PyObject *) +SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *) +/* Can't use SLOT1 here, because nb_inplace_power is ternary */ +static PyObject * +slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) +{ + PyObject *stack[1] = {arg1}; + _Py_IDENTIFIER(__ipow__); + return call_method(self, &PyId___ipow__, stack, 1); +} +SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *) +SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *) +SLOT1(slot_nb_inplace_and, "__iand__", PyObject *) +SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *) +SLOT1(slot_nb_inplace_or, "__ior__", PyObject *) +SLOT1BIN(slot_nb_floor_divide, nb_floor_divide, + "__floordiv__", "__rfloordiv__") +SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__") +SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *) +SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *) + +static PyObject * +slot_tp_repr(PyObject *self) +{ + PyObject *func, *res; + _Py_IDENTIFIER(__repr__); + int unbound; + + func = lookup_maybe_method(self, &PyId___repr__, &unbound); + if (func != NULL) { + res = call_unbound_noarg(unbound, func, self); + Py_DECREF(func); + return res; + } + PyErr_Clear(); + return PyUnicode_FromFormat("<%s object at %p>", + Py_TYPE(self)->tp_name, self); +} + +SLOT0(slot_tp_str, "__str__") + +static Py_hash_t +slot_tp_hash(PyObject *self) +{ + PyObject *func, *res; + Py_ssize_t h; + int unbound; + + func = lookup_maybe_method(self, &PyId___hash__, &unbound); + + if (func == Py_None) { + Py_DECREF(func); + func = NULL; + } + + if (func == NULL) { + return PyObject_HashNotImplemented(self); + } + + res = call_unbound_noarg(unbound, func, self); + Py_DECREF(func); + if (res == NULL) + return -1; + + if (!PyLong_Check(res)) { + PyErr_SetString(PyExc_TypeError, + "__hash__ method should return an integer"); + return -1; + } + /* Transform the PyLong `res` to a Py_hash_t `h`. For an existing + hashable Python object x, hash(x) will always lie within the range of + Py_hash_t. Therefore our transformation must preserve values that + already lie within this range, to ensure that if x.__hash__() returns + hash(y) then hash(x) == hash(y). */ + h = PyLong_AsSsize_t(res); + if (h == -1 && PyErr_Occurred()) { + /* res was not within the range of a Py_hash_t, so we're free to + use any sufficiently bit-mixing transformation; + long.__hash__ will do nicely. */ + PyErr_Clear(); + h = PyLong_Type.tp_hash(res); + } + /* -1 is reserved for errors. */ + if (h == -1) + h = -2; + Py_DECREF(res); + return h; +} + +static PyObject * +slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) +{ + _Py_IDENTIFIER(__call__); + int unbound; + PyObject *meth = lookup_method(self, &PyId___call__, &unbound); + PyObject *res; + + if (meth == NULL) + return NULL; + + if (unbound) { + res = _PyObject_Call_Prepend(meth, self, args, kwds); + } + else { + res = PyObject_Call(meth, args, kwds); + } + + Py_DECREF(meth); + return res; +} + +/* There are two slot dispatch functions for tp_getattro. + + - slot_tp_getattro() is used when __getattribute__ is overridden + but no __getattr__ hook is present; + + - slot_tp_getattr_hook() is used when a __getattr__ hook is present. + + The code in update_one_slot() always installs slot_tp_getattr_hook(); this + detects the absence of __getattr__ and then installs the simpler slot if + necessary. */ + +static PyObject * +slot_tp_getattro(PyObject *self, PyObject *name) +{ + PyObject *stack[1] = {name}; + return call_method(self, &PyId___getattribute__, stack, 1); +} + +static PyObject * +call_attribute(PyObject *self, PyObject *attr, PyObject *name) +{ + PyObject *res, *descr = NULL; + descrgetfunc f = Py_TYPE(attr)->tp_descr_get; + + if (f != NULL) { + descr = f(attr, self, (PyObject *)(Py_TYPE(self))); + if (descr == NULL) + return NULL; + else + attr = descr; + } + res = PyObject_CallFunctionObjArgs(attr, name, NULL); + Py_XDECREF(descr); + return res; +} + +static PyObject * +slot_tp_getattr_hook(PyObject *self, PyObject *name) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject *getattr, *getattribute, *res; + _Py_IDENTIFIER(__getattr__); + + /* speed hack: we could use lookup_maybe, but that would resolve the + method fully for each attribute lookup for classes with + __getattr__, even when the attribute is present. So we use + _PyType_Lookup and create the method only when needed, with + call_attribute. */ + getattr = _PyType_LookupId(tp, &PyId___getattr__); + if (getattr == NULL) { + /* No __getattr__ hook: use a simpler dispatcher */ + tp->tp_getattro = slot_tp_getattro; + return slot_tp_getattro(self, name); + } + Py_INCREF(getattr); + /* speed hack: we could use lookup_maybe, but that would resolve the + method fully for each attribute lookup for classes with + __getattr__, even when self has the default __getattribute__ + method. So we use _PyType_Lookup and create the method only when + needed, with call_attribute. */ + getattribute = _PyType_LookupId(tp, &PyId___getattribute__); + if (getattribute == NULL || + (Py_TYPE(getattribute) == &PyWrapperDescr_Type && + ((PyWrapperDescrObject *)getattribute)->d_wrapped == + (void *)PyObject_GenericGetAttr)) + res = PyObject_GenericGetAttr(self, name); + else { + Py_INCREF(getattribute); + res = call_attribute(self, getattribute, name); + Py_DECREF(getattribute); + } + if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + res = call_attribute(self, getattr, name); + } + Py_DECREF(getattr); + return res; +} + +static int +slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) +{ + PyObject *stack[2]; + PyObject *res; + _Py_IDENTIFIER(__delattr__); + _Py_IDENTIFIER(__setattr__); + + stack[0] = name; + if (value == NULL) { + res = call_method(self, &PyId___delattr__, stack, 1); + } + else { + stack[1] = value; + res = call_method(self, &PyId___setattr__, stack, 2); + } + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +static _Py_Identifier name_op[] = { + {0, "__lt__", 0}, + {0, "__le__", 0}, + {0, "__eq__", 0}, + {0, "__ne__", 0}, + {0, "__gt__", 0}, + {0, "__ge__", 0} +}; + +static PyObject * +slot_tp_richcompare(PyObject *self, PyObject *other, int op) +{ + int unbound; + PyObject *func, *res; + + func = lookup_maybe_method(self, &name_op[op], &unbound); + if (func == NULL) { + PyErr_Clear(); + Py_RETURN_NOTIMPLEMENTED; + } + + PyObject *args[1] = {other}; + res = call_unbound(unbound, func, self, args, 1); + Py_DECREF(func); + return res; +} + +static PyObject * +slot_tp_iter(PyObject *self) +{ + int unbound; + PyObject *func, *res; + _Py_IDENTIFIER(__iter__); + + func = lookup_maybe_method(self, &PyId___iter__, &unbound); + if (func == Py_None) { + Py_DECREF(func); + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not iterable", + Py_TYPE(self)->tp_name); + return NULL; + } + + if (func != NULL) { + res = call_unbound_noarg(unbound, func, self); + Py_DECREF(func); + return res; + } + + PyErr_Clear(); + func = lookup_maybe_method(self, &PyId___getitem__, &unbound); + if (func == NULL) { + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not iterable", + Py_TYPE(self)->tp_name); + return NULL; + } + Py_DECREF(func); + return PySeqIter_New(self); +} + +static PyObject * +slot_tp_iternext(PyObject *self) +{ + _Py_IDENTIFIER(__next__); + return call_method(self, &PyId___next__, NULL, 0); +} + +static PyObject * +slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject *get; + _Py_IDENTIFIER(__get__); + + get = _PyType_LookupId(tp, &PyId___get__); + if (get == NULL) { + /* Avoid further slowdowns */ + if (tp->tp_descr_get == slot_tp_descr_get) + tp->tp_descr_get = NULL; + Py_INCREF(self); + return self; + } + if (obj == NULL) + obj = Py_None; + if (type == NULL) + type = Py_None; + return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL); +} + +static int +slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) +{ + PyObject* stack[2]; + PyObject *res; + _Py_IDENTIFIER(__delete__); + _Py_IDENTIFIER(__set__); + + stack[0] = target; + if (value == NULL) { + res = call_method(self, &PyId___delete__, stack, 1); + } + else { + stack[1] = value; + res = call_method(self, &PyId___set__, stack, 2); + } + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +static int +slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + _Py_IDENTIFIER(__init__); + int unbound; + PyObject *meth = lookup_method(self, &PyId___init__, &unbound); + PyObject *res; + + if (meth == NULL) + return -1; + if (unbound) { + res = _PyObject_Call_Prepend(meth, self, args, kwds); + } + else { + res = PyObject_Call(meth, args, kwds); + } + Py_DECREF(meth); + if (res == NULL) + return -1; + if (res != Py_None) { + PyErr_Format(PyExc_TypeError, + "__init__() should return None, not '%.200s'", + Py_TYPE(res)->tp_name); + Py_DECREF(res); + return -1; + } + Py_DECREF(res); + return 0; +} + +static PyObject * +slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *func, *result; + + func = _PyObject_GetAttrId((PyObject *)type, &PyId___new__); + if (func == NULL) { + return NULL; + } + + result = _PyObject_Call_Prepend(func, (PyObject *)type, args, kwds); + Py_DECREF(func); + return result; +} + +static void +slot_tp_finalize(PyObject *self) +{ + _Py_IDENTIFIER(__del__); + int unbound; + PyObject *del, *res; + PyObject *error_type, *error_value, *error_traceback; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + /* Execute __del__ method, if any. */ + del = lookup_maybe_method(self, &PyId___del__, &unbound); + if (del != NULL) { + res = call_unbound_noarg(unbound, del, self); + if (res == NULL) + PyErr_WriteUnraisable(del); + else + Py_DECREF(res); + Py_DECREF(del); + } + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static PyObject * +slot_am_await(PyObject *self) +{ + int unbound; + PyObject *func, *res; + _Py_IDENTIFIER(__await__); + + func = lookup_maybe_method(self, &PyId___await__, &unbound); + if (func != NULL) { + res = call_unbound_noarg(unbound, func, self); + Py_DECREF(func); + return res; + } + PyErr_Format(PyExc_AttributeError, + "object %.50s does not have __await__ method", + Py_TYPE(self)->tp_name); + return NULL; +} + +static PyObject * +slot_am_aiter(PyObject *self) +{ + int unbound; + PyObject *func, *res; + _Py_IDENTIFIER(__aiter__); + + func = lookup_maybe_method(self, &PyId___aiter__, &unbound); + if (func != NULL) { + res = call_unbound_noarg(unbound, func, self); + Py_DECREF(func); + return res; + } + PyErr_Format(PyExc_AttributeError, + "object %.50s does not have __aiter__ method", + Py_TYPE(self)->tp_name); + return NULL; +} + +static PyObject * +slot_am_anext(PyObject *self) +{ + int unbound; + PyObject *func, *res; + _Py_IDENTIFIER(__anext__); + + func = lookup_maybe_method(self, &PyId___anext__, &unbound); + if (func != NULL) { + res = call_unbound_noarg(unbound, func, self); + Py_DECREF(func); + return res; + } + PyErr_Format(PyExc_AttributeError, + "object %.50s does not have __anext__ method", + Py_TYPE(self)->tp_name); + return NULL; +} + +/* +Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper functions. + +The table is ordered by offsets relative to the 'PyHeapTypeObject' structure, +which incorporates the additional structures used for numbers, sequences and +mappings. Note that multiple names may map to the same slot (e.g. __eq__, +__ne__ etc. all map to tp_richcompare) and one name may map to multiple slots +(e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with +an all-zero entry. (This table is further initialized in init_slotdefs().) +*/ + +typedef struct wrapperbase slotdef; + +#undef TPSLOT +#undef FLSLOT +#undef AMSLOT +#undef ETSLOT +#undef SQSLOT +#undef MPSLOT +#undef NBSLOT +#undef UNSLOT +#undef IBSLOT +#undef BINSLOT +#undef RBINSLOT + +#define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC)} +#define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ + {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), FLAGS} +#define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC)} +#define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) +#define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC) +#define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC) +#define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) +#define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ + NAME "($self, /)\n--\n\n" DOC) +#define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ + NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") +#define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ + NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") +#define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ + NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") +#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ + NAME "($self, value, /)\n--\n\n" DOC) +#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ + ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ + NAME "($self, value, /)\n--\n\n" DOC) + +static slotdef slotdefs[] = { + TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), + TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), + TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), + TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), + TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, + "__repr__($self, /)\n--\n\nReturn repr(self)."), + TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, + "__hash__($self, /)\n--\n\nReturn hash(self)."), + FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, + "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", + PyWrapperFlag_KEYWORDS), + TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, + "__str__($self, /)\n--\n\nReturn str(self)."), + TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, + wrap_binaryfunc, + "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), + TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), + TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, + "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), + TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, + "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), + TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, + "__lt__($self, value, /)\n--\n\nReturn selfvalue."), + TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, + "__ge__($self, value, /)\n--\n\nReturn self>=value."), + TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, + "__iter__($self, /)\n--\n\nImplement iter(self)."), + TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, + "__next__($self, /)\n--\n\nImplement next(self)."), + TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, + "__get__($self, instance, owner, /)\n--\n\nReturn an attribute of instance, which is of type owner."), + TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, + "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), + TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, + wrap_descr_delete, + "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), + FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, + "__init__($self, /, *args, **kwargs)\n--\n\n" + "Initialize self. See help(type(self)) for accurate signature.", + PyWrapperFlag_KEYWORDS), + TPSLOT("__new__", tp_new, slot_tp_new, NULL, + "__new__(type, /, *args, **kwargs)\n--\n\n" + "Create and return new object. See help(type) for accurate signature."), + TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), + + AMSLOT("__await__", am_await, slot_am_await, wrap_unaryfunc, + "__await__($self, /)\n--\n\nReturn an iterator to be used in await expression."), + AMSLOT("__aiter__", am_aiter, slot_am_aiter, wrap_unaryfunc, + "__aiter__($self, /)\n--\n\nReturn an awaitable, that resolves in asynchronous iterator."), + AMSLOT("__anext__", am_anext, slot_am_anext, wrap_unaryfunc, + "__anext__($self, /)\n--\n\nReturn a value or raise StopAsyncIteration."), + + BINSLOT("__add__", nb_add, slot_nb_add, + "+"), + RBINSLOT("__radd__", nb_add, slot_nb_add, + "+"), + BINSLOT("__sub__", nb_subtract, slot_nb_subtract, + "-"), + RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, + "-"), + BINSLOT("__mul__", nb_multiply, slot_nb_multiply, + "*"), + RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, + "*"), + BINSLOT("__mod__", nb_remainder, slot_nb_remainder, + "%"), + RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, + "%"), + BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, + "Return divmod(self, value)."), + RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, + "Return divmod(value, self)."), + NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, + "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), + NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, + "__rpow__($self, value, mod=None, /)\n--\n\nReturn pow(value, self, mod)."), + UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), + UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), + UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, + "abs(self)"), + UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, + "self != 0"), + UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), + BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), + RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), + BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), + RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), + BINSLOT("__and__", nb_and, slot_nb_and, "&"), + RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), + BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), + RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), + BINSLOT("__or__", nb_or, slot_nb_or, "|"), + RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), + UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, + "int(self)"), + UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, + "float(self)"), + IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, + wrap_binaryfunc, "+="), + IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, + wrap_binaryfunc, "-="), + IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, + wrap_binaryfunc, "*="), + IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, + wrap_binaryfunc, "%="), + IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, + wrap_ternaryfunc, "**="), + IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, + wrap_binaryfunc, "<<="), + IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, + wrap_binaryfunc, ">>="), + IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, + wrap_binaryfunc, "&="), + IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, + wrap_binaryfunc, "^="), + IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, + wrap_binaryfunc, "|="), + BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), + RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), + BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), + RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), + IBSLOT("__ifloordiv__", nb_inplace_floor_divide, + slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), + IBSLOT("__itruediv__", nb_inplace_true_divide, + slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), + NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, + "__index__($self, /)\n--\n\n" + "Return self converted to an integer, if self is suitable " + "for use as an index into a list."), + BINSLOT("__matmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + "@"), + RBINSLOT("__rmatmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + "@"), + IBSLOT("__imatmul__", nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, + wrap_binaryfunc, "@="), + MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, + "__len__($self, /)\n--\n\nReturn len(self)."), + MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, + wrap_binaryfunc, + "__getitem__($self, key, /)\n--\n\nReturn self[key]."), + MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, + wrap_objobjargproc, + "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), + MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, + wrap_delitem, + "__delitem__($self, key, /)\n--\n\nDelete self[key]."), + + SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, + "__len__($self, /)\n--\n\nReturn len(self)."), + /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. + The logic in abstract.c always falls back to nb_add/nb_multiply in + this case. Defining both the nb_* and the sq_* slots to call the + user-defined methods has unexpected side-effects, as shown by + test_descr.notimplemented() */ + SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, + "__add__($self, value, /)\n--\n\nReturn self+value."), + SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, + "__mul__($self, value, /)\n--\n\nReturn self*value."), + SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, + "__rmul__($self, value, /)\n--\n\nReturn value*self."), + SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, + "__getitem__($self, key, /)\n--\n\nReturn self[key]."), + SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, + "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), + SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, + "__delitem__($self, key, /)\n--\n\nDelete self[key]."), + SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, + "__contains__($self, key, /)\n--\n\nReturn key in self."), + SQSLOT("__iadd__", sq_inplace_concat, NULL, + wrap_binaryfunc, + "__iadd__($self, value, /)\n--\n\nImplement self+=value."), + SQSLOT("__imul__", sq_inplace_repeat, NULL, + wrap_indexargfunc, + "__imul__($self, value, /)\n--\n\nImplement self*=value."), + + {NULL} +}; + +/* Given a type pointer and an offset gotten from a slotdef entry, return a + pointer to the actual slot. This is not quite the same as simply adding + the offset to the type pointer, since it takes care to indirect through the + proper indirection pointer (as_buffer, etc.); it returns NULL if the + indirection pointer is NULL. */ +static void ** +slotptr(PyTypeObject *type, int ioffset) +{ + char *ptr; + long offset = ioffset; + + /* Note: this depends on the order of the members of PyHeapTypeObject! */ + assert(offset >= 0); + assert((size_t)offset < offsetof(PyHeapTypeObject, as_buffer)); + if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) { + ptr = (char *)type->tp_as_sequence; + offset -= offsetof(PyHeapTypeObject, as_sequence); + } + else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_mapping)) { + ptr = (char *)type->tp_as_mapping; + offset -= offsetof(PyHeapTypeObject, as_mapping); + } + else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_number)) { + ptr = (char *)type->tp_as_number; + offset -= offsetof(PyHeapTypeObject, as_number); + } + else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_async)) { + ptr = (char *)type->tp_as_async; + offset -= offsetof(PyHeapTypeObject, as_async); + } + else { + ptr = (char *)type; + } + if (ptr != NULL) + ptr += offset; + return (void **)ptr; +} + +/* Length of array of slotdef pointers used to store slots with the + same __name__. There should be at most MAX_EQUIV-1 slotdef entries with + the same __name__, for any __name__. Since that's a static property, it is + appropriate to declare fixed-size arrays for this. */ +#define MAX_EQUIV 10 + +/* Return a slot pointer for a given name, but ONLY if the attribute has + exactly one slot function. The name must be an interned string. */ +static void ** +resolve_slotdups(PyTypeObject *type, PyObject *name) +{ + /* XXX Maybe this could be optimized more -- but is it worth it? */ + + /* pname and ptrs act as a little cache */ + static PyObject *pname; + static slotdef *ptrs[MAX_EQUIV]; + slotdef *p, **pp; + void **res, **ptr; + + if (pname != name) { + /* Collect all slotdefs that match name into ptrs. */ + pname = name; + pp = ptrs; + for (p = slotdefs; p->name_strobj; p++) { + if (p->name_strobj == name) + *pp++ = p; + } + *pp = NULL; + } + + /* Look in all matching slots of the type; if exactly one of these has + a filled-in slot, return its value. Otherwise return NULL. */ + res = NULL; + for (pp = ptrs; *pp; pp++) { + ptr = slotptr(type, (*pp)->offset); + if (ptr == NULL || *ptr == NULL) + continue; + if (res != NULL) + return NULL; + res = ptr; + } + return res; +} + +/* Common code for update_slots_callback() and fixup_slot_dispatchers(). This + does some incredibly complex thinking and then sticks something into the + slot. (It sees if the adjacent slotdefs for the same slot have conflicting + interests, and then stores a generic wrapper or a specific function into + the slot.) Return a pointer to the next slotdef with a different offset, + because that's convenient for fixup_slot_dispatchers(). */ +static slotdef * +update_one_slot(PyTypeObject *type, slotdef *p) +{ + PyObject *descr; + PyWrapperDescrObject *d; + void *generic = NULL, *specific = NULL; + int use_generic = 0; + int offset = p->offset; + int error; + void **ptr = slotptr(type, offset); + + if (ptr == NULL) { + do { + ++p; + } while (p->offset == offset); + return p; + } + /* We may end up clearing live exceptions below, so make sure it's ours. */ + assert(!PyErr_Occurred()); + do { + /* Use faster uncached lookup as we won't get any cache hits during type setup. */ + descr = find_name_in_mro(type, p->name_strobj, &error); + if (descr == NULL) { + if (error == -1) { + /* It is unlikely by not impossible that there has been an exception + during lookup. Since this function originally expected no errors, + we ignore them here in order to keep up the interface. */ + PyErr_Clear(); + } + if (ptr == (void**)&type->tp_iternext) { + specific = (void *)_PyObject_NextNotImplemented; + } + continue; + } + if (Py_TYPE(descr) == &PyWrapperDescr_Type && + ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_strobj) { + void **tptr = resolve_slotdups(type, p->name_strobj); + if (tptr == NULL || tptr == ptr) + generic = p->function; + d = (PyWrapperDescrObject *)descr; + if ((specific == NULL || specific == d->d_wrapped) && + d->d_base->wrapper == p->wrapper && + PyType_IsSubtype(type, PyDescr_TYPE(d))) + { + specific = d->d_wrapped; + } + else { + /* We cannot use the specific slot function because either + - it is not unique: there are multiple methods for this + slot and they conflict + - the signature is wrong (as checked by the ->wrapper + comparison above) + - it's wrapping the wrong class + */ + use_generic = 1; + } + } + else if (Py_TYPE(descr) == &PyCFunction_Type && + PyCFunction_GET_FUNCTION(descr) == + (PyCFunction)(void(*)(void))tp_new_wrapper && + ptr == (void**)&type->tp_new) + { + /* The __new__ wrapper is not a wrapper descriptor, + so must be special-cased differently. + If we don't do this, creating an instance will + always use slot_tp_new which will look up + __new__ in the MRO which will call tp_new_wrapper + which will look through the base classes looking + for a static base and call its tp_new (usually + PyType_GenericNew), after performing various + sanity checks and constructing a new argument + list. Cut all that nonsense short -- this speeds + up instance creation tremendously. */ + specific = (void *)type->tp_new; + /* XXX I'm not 100% sure that there isn't a hole + in this reasoning that requires additional + sanity checks. I'll buy the first person to + point out a bug in this reasoning a beer. */ + } + else if (descr == Py_None && + ptr == (void**)&type->tp_hash) { + /* We specifically allow __hash__ to be set to None + to prevent inheritance of the default + implementation from object.__hash__ */ + specific = (void *)PyObject_HashNotImplemented; + } + else { + use_generic = 1; + generic = p->function; + } + } while ((++p)->offset == offset); + if (specific && !use_generic) + *ptr = specific; + else + *ptr = generic; + return p; +} + +/* In the type, update the slots whose slotdefs are gathered in the pp array. + This is a callback for update_subclasses(). */ +static int +update_slots_callback(PyTypeObject *type, void *data) +{ + slotdef **pp = (slotdef **)data; + + for (; *pp; pp++) + update_one_slot(type, *pp); + return 0; +} + +static int slotdefs_initialized = 0; +/* Initialize the slotdefs table by adding interned string objects for the + names. */ +static void +init_slotdefs(void) +{ + slotdef *p; + + if (slotdefs_initialized) + return; + for (p = slotdefs; p->name; p++) { + /* Slots must be ordered by their offset in the PyHeapTypeObject. */ + assert(!p[1].name || p->offset <= p[1].offset); + p->name_strobj = PyUnicode_InternFromString(p->name); + if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) + Py_FatalError("Out of memory interning slotdef names"); + } + slotdefs_initialized = 1; +} + +/* Undo init_slotdefs, releasing the interned strings. */ +static void clear_slotdefs(void) +{ + slotdef *p; + for (p = slotdefs; p->name; p++) { + Py_CLEAR(p->name_strobj); + } + slotdefs_initialized = 0; +} + +/* Update the slots after assignment to a class (type) attribute. */ +static int +update_slot(PyTypeObject *type, PyObject *name) +{ + slotdef *ptrs[MAX_EQUIV]; + slotdef *p; + slotdef **pp; + int offset; + + assert(PyUnicode_CheckExact(name)); + assert(PyUnicode_CHECK_INTERNED(name)); + + init_slotdefs(); + pp = ptrs; + for (p = slotdefs; p->name; p++) { + if (p->name_strobj == name) + *pp++ = p; + } + *pp = NULL; + for (pp = ptrs; *pp; pp++) { + p = *pp; + offset = p->offset; + while (p > slotdefs && (p-1)->offset == offset) + --p; + *pp = p; + } + if (ptrs[0] == NULL) + return 0; /* Not an attribute that affects any slots */ + return update_subclasses(type, name, + update_slots_callback, (void *)ptrs); +} + +/* Store the proper functions in the slot dispatches at class (type) + definition time, based upon which operations the class overrides in its + dict. */ +static void +fixup_slot_dispatchers(PyTypeObject *type) +{ + slotdef *p; + + init_slotdefs(); + for (p = slotdefs; p->name; ) + p = update_one_slot(type, p); +} + +static void +update_all_slots(PyTypeObject* type) +{ + slotdef *p; + + /* Clear the VALID_VERSION flag of 'type' and all its subclasses. */ + PyType_Modified(type); + + init_slotdefs(); + for (p = slotdefs; p->name; p++) { + /* update_slot returns int but can't actually fail */ + update_slot(type, p->name_strobj); + } +} + +/* Call __set_name__ on all descriptors in a newly generated type */ +static int +set_names(PyTypeObject *type) +{ + PyObject *names_to_set, *key, *value, *set_name, *tmp; + Py_ssize_t i = 0; + + names_to_set = PyDict_Copy(type->tp_dict); + if (names_to_set == NULL) + return -1; + + while (PyDict_Next(names_to_set, &i, &key, &value)) { + set_name = _PyObject_LookupSpecial(value, &PyId___set_name__); + if (set_name != NULL) { + tmp = PyObject_CallFunctionObjArgs(set_name, type, key, NULL); + Py_DECREF(set_name); + if (tmp == NULL) { + _PyErr_FormatFromCause(PyExc_RuntimeError, + "Error calling __set_name__ on '%.100s' instance %R " + "in '%.100s'", + value->ob_type->tp_name, key, type->tp_name); + Py_DECREF(names_to_set); + return -1; + } + else + Py_DECREF(tmp); + } + else if (PyErr_Occurred()) { + Py_DECREF(names_to_set); + return -1; + } + } + + Py_DECREF(names_to_set); + return 0; +} + +/* Call __init_subclass__ on the parent of a newly generated type */ +static int +init_subclass(PyTypeObject *type, PyObject *kwds) +{ + PyObject *super, *func, *result; + PyObject *args[2] = {(PyObject *)type, (PyObject *)type}; + + super = _PyObject_FastCall((PyObject *)&PySuper_Type, args, 2); + if (super == NULL) { + return -1; + } + + func = _PyObject_GetAttrId(super, &PyId___init_subclass__); + Py_DECREF(super); + if (func == NULL) { + return -1; + } + + + result = _PyObject_FastCallDict(func, NULL, 0, kwds); + Py_DECREF(func); + if (result == NULL) { + return -1; + } + + Py_DECREF(result); + return 0; +} + +/* recurse_down_subclasses() and update_subclasses() are mutually + recursive functions to call a callback for all subclasses, + but refraining from recursing into subclasses that define 'name'. */ + +static int +update_subclasses(PyTypeObject *type, PyObject *name, + update_callback callback, void *data) +{ + if (callback(type, data) < 0) + return -1; + return recurse_down_subclasses(type, name, callback, data); +} + +static int +recurse_down_subclasses(PyTypeObject *type, PyObject *name, + update_callback callback, void *data) +{ + PyTypeObject *subclass; + PyObject *ref, *subclasses, *dict; + Py_ssize_t i; + + subclasses = type->tp_subclasses; + if (subclasses == NULL) + return 0; + assert(PyDict_CheckExact(subclasses)); + i = 0; + while (PyDict_Next(subclasses, &i, NULL, &ref)) { + assert(PyWeakref_CheckRef(ref)); + subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref); + assert(subclass != NULL); + if ((PyObject *)subclass == Py_None) + continue; + assert(PyType_Check(subclass)); + /* Avoid recursing down into unaffected classes */ + dict = subclass->tp_dict; + if (dict != NULL && PyDict_Check(dict)) { + if (PyDict_GetItemWithError(dict, name) != NULL) { + continue; + } + if (PyErr_Occurred()) { + return -1; + } + } + if (update_subclasses(subclass, name, callback, data) < 0) + return -1; + } + return 0; +} + +/* This function is called by PyType_Ready() to populate the type's + dictionary with method descriptors for function slots. For each + function slot (like tp_repr) that's defined in the type, one or more + corresponding descriptors are added in the type's tp_dict dictionary + under the appropriate name (like __repr__). Some function slots + cause more than one descriptor to be added (for example, the nb_add + slot adds both __add__ and __radd__ descriptors) and some function + slots compete for the same descriptor (for example both sq_item and + mp_subscript generate a __getitem__ descriptor). + + In the latter case, the first slotdef entry encountered wins. Since + slotdef entries are sorted by the offset of the slot in the + PyHeapTypeObject, this gives us some control over disambiguating + between competing slots: the members of PyHeapTypeObject are listed + from most general to least general, so the most general slot is + preferred. In particular, because as_mapping comes before as_sequence, + for a type that defines both mp_subscript and sq_item, mp_subscript + wins. + + This only adds new descriptors and doesn't overwrite entries in + tp_dict that were previously defined. The descriptors contain a + reference to the C function they must call, so that it's safe if they + are copied into a subtype's __dict__ and the subtype has a different + C function in its slot -- calling the method defined by the + descriptor will call the C function that was used to create it, + rather than the C function present in the slot when it is called. + (This is important because a subtype may have a C function in the + slot that calls the method from the dictionary, and we want to avoid + infinite recursion here.) */ + +static int +add_operators(PyTypeObject *type) +{ + PyObject *dict = type->tp_dict; + slotdef *p; + PyObject *descr; + void **ptr; + + init_slotdefs(); + for (p = slotdefs; p->name; p++) { + if (p->wrapper == NULL) + continue; + ptr = slotptr(type, p->offset); + if (!ptr || !*ptr) + continue; + if (PyDict_GetItemWithError(dict, p->name_strobj)) + continue; + if (PyErr_Occurred()) { + return -1; + } + if (*ptr == (void *)PyObject_HashNotImplemented) { + /* Classes may prevent the inheritance of the tp_hash + slot by storing PyObject_HashNotImplemented in it. Make it + visible as a None value for the __hash__ attribute. */ + if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0) + return -1; + } + else { + descr = PyDescr_NewWrapper(type, p, *ptr); + if (descr == NULL) + return -1; + if (PyDict_SetItem(dict, p->name_strobj, descr) < 0) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + } + } + if (type->tp_new != NULL) { + if (add_tp_new_wrapper(type) < 0) + return -1; + } + return 0; +} + + +/* Cooperative 'super' */ + +typedef struct { + PyObject_HEAD + PyTypeObject *type; + PyObject *obj; + PyTypeObject *obj_type; +} superobject; + +static PyMemberDef super_members[] = { + {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY, + "the class invoking super()"}, + {"__self__", T_OBJECT, offsetof(superobject, obj), READONLY, + "the instance invoking super(); may be None"}, + {"__self_class__", T_OBJECT, offsetof(superobject, obj_type), READONLY, + "the type of the instance invoking super(); may be None"}, + {0} +}; + +static void +super_dealloc(PyObject *self) +{ + superobject *su = (superobject *)self; + + _PyObject_GC_UNTRACK(self); + Py_XDECREF(su->obj); + Py_XDECREF(su->type); + Py_XDECREF(su->obj_type); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +super_repr(PyObject *self) +{ + superobject *su = (superobject *)self; + + if (su->obj_type) + return PyUnicode_FromFormat( + ", <%s object>>", + su->type ? su->type->tp_name : "NULL", + su->obj_type->tp_name); + else + return PyUnicode_FromFormat( + ", NULL>", + su->type ? su->type->tp_name : "NULL"); +} + +static PyObject * +super_getattro(PyObject *self, PyObject *name) +{ + superobject *su = (superobject *)self; + PyTypeObject *starttype; + PyObject *mro; + Py_ssize_t i, n; + + starttype = su->obj_type; + if (starttype == NULL) + goto skip; + + /* We want __class__ to return the class of the super object + (i.e. super, or a subclass), not the class of su->obj. */ + if (PyUnicode_Check(name) && + PyUnicode_GET_LENGTH(name) == 9 && + _PyUnicode_EqualToASCIIId(name, &PyId___class__)) + goto skip; + + mro = starttype->tp_mro; + if (mro == NULL) + goto skip; + + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); + + /* No need to check the last one: it's gonna be skipped anyway. */ + for (i = 0; i+1 < n; i++) { + if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i)) + break; + } + i++; /* skip su->type (if any) */ + if (i >= n) + goto skip; + + /* keep a strong reference to mro because starttype->tp_mro can be + replaced during PyDict_GetItemWithError(dict, name) */ + Py_INCREF(mro); + do { + PyObject *res, *tmp, *dict; + descrgetfunc f; + + tmp = PyTuple_GET_ITEM(mro, i); + assert(PyType_Check(tmp)); + + dict = ((PyTypeObject *)tmp)->tp_dict; + assert(dict != NULL && PyDict_Check(dict)); + + res = PyDict_GetItemWithError(dict, name); + if (res != NULL) { + Py_INCREF(res); + + f = Py_TYPE(res)->tp_descr_get; + if (f != NULL) { + tmp = f(res, + /* Only pass 'obj' param if this is instance-mode super + (See SF ID #743627) */ + (su->obj == (PyObject *)starttype) ? NULL : su->obj, + (PyObject *)starttype); + Py_DECREF(res); + res = tmp; + } + + Py_DECREF(mro); + return res; + } + else if (PyErr_Occurred()) { + Py_DECREF(mro); + return NULL; + } + + i++; + } while (i < n); + Py_DECREF(mro); + + skip: + return PyObject_GenericGetAttr(self, name); +} + +static PyTypeObject * +supercheck(PyTypeObject *type, PyObject *obj) +{ + /* Check that a super() call makes sense. Return a type object. + + obj can be a class, or an instance of one: + + - If it is a class, it must be a subclass of 'type'. This case is + used for class methods; the return value is obj. + + - If it is an instance, it must be an instance of 'type'. This is + the normal case; the return value is obj.__class__. + + But... when obj is an instance, we want to allow for the case where + Py_TYPE(obj) is not a subclass of type, but obj.__class__ is! + This will allow using super() with a proxy for obj. + */ + + /* Check for first bullet above (special case) */ + if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) { + Py_INCREF(obj); + return (PyTypeObject *)obj; + } + + /* Normal case */ + if (PyType_IsSubtype(Py_TYPE(obj), type)) { + Py_INCREF(Py_TYPE(obj)); + return Py_TYPE(obj); + } + else { + /* Try the slow way */ + PyObject *class_attr; + + if (_PyObject_LookupAttrId(obj, &PyId___class__, &class_attr) < 0) { + return NULL; + } + if (class_attr != NULL && + PyType_Check(class_attr) && + (PyTypeObject *)class_attr != Py_TYPE(obj)) + { + int ok = PyType_IsSubtype( + (PyTypeObject *)class_attr, type); + if (ok) + return (PyTypeObject *)class_attr; + } + Py_XDECREF(class_attr); + } + + PyErr_SetString(PyExc_TypeError, + "super(type, obj): " + "obj must be an instance or subtype of type"); + return NULL; +} + +static PyObject * +super_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + superobject *su = (superobject *)self; + superobject *newobj; + + if (obj == NULL || obj == Py_None || su->obj != NULL) { + /* Not binding to an object, or already bound */ + Py_INCREF(self); + return self; + } + if (Py_TYPE(su) != &PySuper_Type) + /* If su is an instance of a (strict) subclass of super, + call its type */ + return PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(su), + su->type, obj, NULL); + else { + /* Inline the common case */ + PyTypeObject *obj_type = supercheck(su->type, obj); + if (obj_type == NULL) + return NULL; + newobj = (superobject *)PySuper_Type.tp_new(&PySuper_Type, + NULL, NULL); + if (newobj == NULL) + return NULL; + Py_INCREF(su->type); + Py_INCREF(obj); + newobj->type = su->type; + newobj->obj = obj; + newobj->obj_type = obj_type; + return (PyObject *)newobj; + } +} + +static int +super_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + superobject *su = (superobject *)self; + PyTypeObject *type = NULL; + PyObject *obj = NULL; + PyTypeObject *obj_type = NULL; + + if (!_PyArg_NoKeywords("super", kwds)) + return -1; + if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj)) + return -1; + + if (type == NULL) { + /* Call super(), without args -- fill in from __class__ + and first local variable on the stack. */ + PyFrameObject *f; + PyCodeObject *co; + Py_ssize_t i, n; + f = _PyThreadState_GET()->frame; + if (f == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "super(): no current frame"); + return -1; + } + co = f->f_code; + if (co == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "super(): no code object"); + return -1; + } + if (co->co_argcount == 0) { + PyErr_SetString(PyExc_RuntimeError, + "super(): no arguments"); + return -1; + } + obj = f->f_localsplus[0]; + if (obj == NULL && co->co_cell2arg) { + /* The first argument might be a cell. */ + n = PyTuple_GET_SIZE(co->co_cellvars); + for (i = 0; i < n; i++) { + if (co->co_cell2arg[i] == 0) { + PyObject *cell = f->f_localsplus[co->co_nlocals + i]; + assert(PyCell_Check(cell)); + obj = PyCell_GET(cell); + break; + } + } + } + if (obj == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "super(): arg[0] deleted"); + return -1; + } + if (co->co_freevars == NULL) + n = 0; + else { + assert(PyTuple_Check(co->co_freevars)); + n = PyTuple_GET_SIZE(co->co_freevars); + } + for (i = 0; i < n; i++) { + PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); + assert(PyUnicode_Check(name)); + if (_PyUnicode_EqualToASCIIId(name, &PyId___class__)) { + Py_ssize_t index = co->co_nlocals + + PyTuple_GET_SIZE(co->co_cellvars) + i; + PyObject *cell = f->f_localsplus[index]; + if (cell == NULL || !PyCell_Check(cell)) { + PyErr_SetString(PyExc_RuntimeError, + "super(): bad __class__ cell"); + return -1; + } + type = (PyTypeObject *) PyCell_GET(cell); + if (type == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "super(): empty __class__ cell"); + return -1; + } + if (!PyType_Check(type)) { + PyErr_Format(PyExc_RuntimeError, + "super(): __class__ is not a type (%s)", + Py_TYPE(type)->tp_name); + return -1; + } + break; + } + } + if (type == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "super(): __class__ cell not found"); + return -1; + } + } + + if (obj == Py_None) + obj = NULL; + if (obj != NULL) { + obj_type = supercheck(type, obj); + if (obj_type == NULL) + return -1; + Py_INCREF(obj); + } + Py_INCREF(type); + Py_XSETREF(su->type, type); + Py_XSETREF(su->obj, obj); + Py_XSETREF(su->obj_type, obj_type); + return 0; +} + +PyDoc_STRVAR(super_doc, +"super() -> same as super(__class__, )\n" +"super(type) -> unbound super object\n" +"super(type, obj) -> bound super object; requires isinstance(obj, type)\n" +"super(type, type2) -> bound super object; requires issubclass(type2, type)\n" +"Typical use to call a cooperative superclass method:\n" +"class C(B):\n" +" def meth(self, arg):\n" +" super().meth(arg)\n" +"This works for class methods too:\n" +"class C(B):\n" +" @classmethod\n" +" def cmeth(cls, arg):\n" +" super().cmeth(arg)\n"); + +static int +super_traverse(PyObject *self, visitproc visit, void *arg) +{ + superobject *su = (superobject *)self; + + Py_VISIT(su->obj); + Py_VISIT(su->type); + Py_VISIT(su->obj_type); + + return 0; +} + +PyTypeObject PySuper_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "super", /* tp_name */ + sizeof(superobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + super_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + super_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + super_getattro, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + super_doc, /* tp_doc */ + super_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + super_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + super_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + super_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; diff --git a/python/Objects/typeslots.inc b/python/Objects/typeslots.inc new file mode 100755 index 0000000..dc750cc --- /dev/null +++ b/python/Objects/typeslots.inc @@ -0,0 +1,81 @@ +/* Generated by typeslots.py */ +0, +0, +offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), +offsetof(PyHeapTypeObject, as_mapping.mp_length), +offsetof(PyHeapTypeObject, as_mapping.mp_subscript), +offsetof(PyHeapTypeObject, as_number.nb_absolute), +offsetof(PyHeapTypeObject, as_number.nb_add), +offsetof(PyHeapTypeObject, as_number.nb_and), +offsetof(PyHeapTypeObject, as_number.nb_bool), +offsetof(PyHeapTypeObject, as_number.nb_divmod), +offsetof(PyHeapTypeObject, as_number.nb_float), +offsetof(PyHeapTypeObject, as_number.nb_floor_divide), +offsetof(PyHeapTypeObject, as_number.nb_index), +offsetof(PyHeapTypeObject, as_number.nb_inplace_add), +offsetof(PyHeapTypeObject, as_number.nb_inplace_and), +offsetof(PyHeapTypeObject, as_number.nb_inplace_floor_divide), +offsetof(PyHeapTypeObject, as_number.nb_inplace_lshift), +offsetof(PyHeapTypeObject, as_number.nb_inplace_multiply), +offsetof(PyHeapTypeObject, as_number.nb_inplace_or), +offsetof(PyHeapTypeObject, as_number.nb_inplace_power), +offsetof(PyHeapTypeObject, as_number.nb_inplace_remainder), +offsetof(PyHeapTypeObject, as_number.nb_inplace_rshift), +offsetof(PyHeapTypeObject, as_number.nb_inplace_subtract), +offsetof(PyHeapTypeObject, as_number.nb_inplace_true_divide), +offsetof(PyHeapTypeObject, as_number.nb_inplace_xor), +offsetof(PyHeapTypeObject, as_number.nb_int), +offsetof(PyHeapTypeObject, as_number.nb_invert), +offsetof(PyHeapTypeObject, as_number.nb_lshift), +offsetof(PyHeapTypeObject, as_number.nb_multiply), +offsetof(PyHeapTypeObject, as_number.nb_negative), +offsetof(PyHeapTypeObject, as_number.nb_or), +offsetof(PyHeapTypeObject, as_number.nb_positive), +offsetof(PyHeapTypeObject, as_number.nb_power), +offsetof(PyHeapTypeObject, as_number.nb_remainder), +offsetof(PyHeapTypeObject, as_number.nb_rshift), +offsetof(PyHeapTypeObject, as_number.nb_subtract), +offsetof(PyHeapTypeObject, as_number.nb_true_divide), +offsetof(PyHeapTypeObject, as_number.nb_xor), +offsetof(PyHeapTypeObject, as_sequence.sq_ass_item), +offsetof(PyHeapTypeObject, as_sequence.sq_concat), +offsetof(PyHeapTypeObject, as_sequence.sq_contains), +offsetof(PyHeapTypeObject, as_sequence.sq_inplace_concat), +offsetof(PyHeapTypeObject, as_sequence.sq_inplace_repeat), +offsetof(PyHeapTypeObject, as_sequence.sq_item), +offsetof(PyHeapTypeObject, as_sequence.sq_length), +offsetof(PyHeapTypeObject, as_sequence.sq_repeat), +offsetof(PyHeapTypeObject, ht_type.tp_alloc), +offsetof(PyHeapTypeObject, ht_type.tp_base), +offsetof(PyHeapTypeObject, ht_type.tp_bases), +offsetof(PyHeapTypeObject, ht_type.tp_call), +offsetof(PyHeapTypeObject, ht_type.tp_clear), +offsetof(PyHeapTypeObject, ht_type.tp_dealloc), +offsetof(PyHeapTypeObject, ht_type.tp_del), +offsetof(PyHeapTypeObject, ht_type.tp_descr_get), +offsetof(PyHeapTypeObject, ht_type.tp_descr_set), +offsetof(PyHeapTypeObject, ht_type.tp_doc), +offsetof(PyHeapTypeObject, ht_type.tp_getattr), +offsetof(PyHeapTypeObject, ht_type.tp_getattro), +offsetof(PyHeapTypeObject, ht_type.tp_hash), +offsetof(PyHeapTypeObject, ht_type.tp_init), +offsetof(PyHeapTypeObject, ht_type.tp_is_gc), +offsetof(PyHeapTypeObject, ht_type.tp_iter), +offsetof(PyHeapTypeObject, ht_type.tp_iternext), +offsetof(PyHeapTypeObject, ht_type.tp_methods), +offsetof(PyHeapTypeObject, ht_type.tp_new), +offsetof(PyHeapTypeObject, ht_type.tp_repr), +offsetof(PyHeapTypeObject, ht_type.tp_richcompare), +offsetof(PyHeapTypeObject, ht_type.tp_setattr), +offsetof(PyHeapTypeObject, ht_type.tp_setattro), +offsetof(PyHeapTypeObject, ht_type.tp_str), +offsetof(PyHeapTypeObject, ht_type.tp_traverse), +offsetof(PyHeapTypeObject, ht_type.tp_members), +offsetof(PyHeapTypeObject, ht_type.tp_getset), +offsetof(PyHeapTypeObject, ht_type.tp_free), +offsetof(PyHeapTypeObject, as_number.nb_matrix_multiply), +offsetof(PyHeapTypeObject, as_number.nb_inplace_matrix_multiply), +offsetof(PyHeapTypeObject, as_async.am_await), +offsetof(PyHeapTypeObject, as_async.am_aiter), +offsetof(PyHeapTypeObject, as_async.am_anext), +offsetof(PyHeapTypeObject, ht_type.tp_finalize), diff --git a/python/Objects/typeslots.py b/python/Objects/typeslots.py new file mode 100755 index 0000000..9b6d4ad --- /dev/null +++ b/python/Objects/typeslots.py @@ -0,0 +1,43 @@ +#!/usr/bin/python +# Usage: typeslots.py < Include/typeslots.h typeslots.inc + +import sys, re + +def generate_typeslots(out=sys.stdout): + out.write("/* Generated by typeslots.py */\n") + res = {} + for line in sys.stdin: + m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) + if not m: + continue + member = m.group(1) + if member.startswith("tp_"): + member = "ht_type."+member + elif member.startswith("am_"): + member = "as_async."+member + elif member.startswith("nb_"): + member = "as_number."+member + elif member.startswith("mp_"): + member = "as_mapping."+member + elif member.startswith("sq_"): + member = "as_sequence."+member + elif member.startswith("bf_"): + member = "as_buffer."+member + res[int(m.group(2))] = member + + M = max(res.keys())+1 + for i in range(1,M): + if i in res: + out.write("offsetof(PyHeapTypeObject, %s),\n" % res[i]) + else: + out.write("0,\n") + +def main(): + if len(sys.argv) == 2: + with open(sys.argv[1], "w") as f: + generate_typeslots(f) + else: + generate_typeslots() + +if __name__ == "__main__": + main() diff --git a/python/Objects/unicodectype.c b/python/Objects/unicodectype.c new file mode 100755 index 0000000..d8c95c8 --- /dev/null +++ b/python/Objects/unicodectype.c @@ -0,0 +1,297 @@ +/* + Unicode character type helpers. + + Written by Marc-Andre Lemburg (mal@lemburg.com). + Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com) + + Copyright (c) Corporation for National Research Initiatives. + +*/ + +#include "Python.h" + +#define ALPHA_MASK 0x01 +#define DECIMAL_MASK 0x02 +#define DIGIT_MASK 0x04 +#define LOWER_MASK 0x08 +#define LINEBREAK_MASK 0x10 +#define SPACE_MASK 0x20 +#define TITLE_MASK 0x40 +#define UPPER_MASK 0x80 +#define XID_START_MASK 0x100 +#define XID_CONTINUE_MASK 0x200 +#define PRINTABLE_MASK 0x400 +#define NUMERIC_MASK 0x800 +#define CASE_IGNORABLE_MASK 0x1000 +#define CASED_MASK 0x2000 +#define EXTENDED_CASE_MASK 0x4000 + +typedef struct { + /* + These are either deltas to the character or offsets in + _PyUnicode_ExtendedCase. + */ + const int upper; + const int lower; + const int title; + /* Note if more flag space is needed, decimal and digit could be unified. */ + const unsigned char decimal; + const unsigned char digit; + const unsigned short flags; +} _PyUnicode_TypeRecord; + +#include "unicodetype_db.h" + +static const _PyUnicode_TypeRecord * +gettyperecord(Py_UCS4 code) +{ + int index; + + if (code >= 0x110000) + index = 0; + else + { + index = index1[(code>>SHIFT)]; + index = index2[(index<flags & EXTENDED_CASE_MASK) + return _PyUnicode_ExtendedCase[ctype->title & 0xFFFF]; + return ch + ctype->title; +} + +/* Returns 1 for Unicode characters having the category 'Lt', 0 + otherwise. */ + +int _PyUnicode_IsTitlecase(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & TITLE_MASK) != 0; +} + +/* Returns 1 for Unicode characters having the XID_Start property, 0 + otherwise. */ + +int _PyUnicode_IsXidStart(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & XID_START_MASK) != 0; +} + +/* Returns 1 for Unicode characters having the XID_Continue property, + 0 otherwise. */ + +int _PyUnicode_IsXidContinue(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & XID_CONTINUE_MASK) != 0; +} + +/* Returns the integer decimal (0-9) for Unicode characters having + this property, -1 otherwise. */ + +int _PyUnicode_ToDecimalDigit(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1; +} + +int _PyUnicode_IsDecimalDigit(Py_UCS4 ch) +{ + if (_PyUnicode_ToDecimalDigit(ch) < 0) + return 0; + return 1; +} + +/* Returns the integer digit (0-9) for Unicode characters having + this property, -1 otherwise. */ + +int _PyUnicode_ToDigit(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & DIGIT_MASK) ? ctype->digit : -1; +} + +int _PyUnicode_IsDigit(Py_UCS4 ch) +{ + if (_PyUnicode_ToDigit(ch) < 0) + return 0; + return 1; +} + +/* Returns the numeric value as double for Unicode characters having + this property, -1.0 otherwise. */ + +int _PyUnicode_IsNumeric(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & NUMERIC_MASK) != 0; +} + +/* Returns 1 for Unicode characters to be hex-escaped when repr()ed, + 0 otherwise. + All characters except those characters defined in the Unicode character + database as following categories are considered printable. + * Cc (Other, Control) + * Cf (Other, Format) + * Cs (Other, Surrogate) + * Co (Other, Private Use) + * Cn (Other, Not Assigned) + * Zl Separator, Line ('\u2028', LINE SEPARATOR) + * Zp Separator, Paragraph ('\u2029', PARAGRAPH SEPARATOR) + * Zs (Separator, Space) other than ASCII space('\x20'). +*/ +int _PyUnicode_IsPrintable(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & PRINTABLE_MASK) != 0; +} + +/* Returns 1 for Unicode characters having the category 'Ll', 0 + otherwise. */ + +int _PyUnicode_IsLowercase(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & LOWER_MASK) != 0; +} + +/* Returns 1 for Unicode characters having the category 'Lu', 0 + otherwise. */ + +int _PyUnicode_IsUppercase(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & UPPER_MASK) != 0; +} + +/* Returns the uppercase Unicode characters corresponding to ch or just + ch if no uppercase mapping is known. */ + +Py_UCS4 _PyUnicode_ToUppercase(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + if (ctype->flags & EXTENDED_CASE_MASK) + return _PyUnicode_ExtendedCase[ctype->upper & 0xFFFF]; + return ch + ctype->upper; +} + +/* Returns the lowercase Unicode characters corresponding to ch or just + ch if no lowercase mapping is known. */ + +Py_UCS4 _PyUnicode_ToLowercase(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + if (ctype->flags & EXTENDED_CASE_MASK) + return _PyUnicode_ExtendedCase[ctype->lower & 0xFFFF]; + return ch + ctype->lower; +} + +int _PyUnicode_ToLowerFull(Py_UCS4 ch, Py_UCS4 *res) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + if (ctype->flags & EXTENDED_CASE_MASK) { + int index = ctype->lower & 0xFFFF; + int n = ctype->lower >> 24; + int i; + for (i = 0; i < n; i++) + res[i] = _PyUnicode_ExtendedCase[index + i]; + return n; + } + res[0] = ch + ctype->lower; + return 1; +} + +int _PyUnicode_ToTitleFull(Py_UCS4 ch, Py_UCS4 *res) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + if (ctype->flags & EXTENDED_CASE_MASK) { + int index = ctype->title & 0xFFFF; + int n = ctype->title >> 24; + int i; + for (i = 0; i < n; i++) + res[i] = _PyUnicode_ExtendedCase[index + i]; + return n; + } + res[0] = ch + ctype->title; + return 1; +} + +int _PyUnicode_ToUpperFull(Py_UCS4 ch, Py_UCS4 *res) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + if (ctype->flags & EXTENDED_CASE_MASK) { + int index = ctype->upper & 0xFFFF; + int n = ctype->upper >> 24; + int i; + for (i = 0; i < n; i++) + res[i] = _PyUnicode_ExtendedCase[index + i]; + return n; + } + res[0] = ch + ctype->upper; + return 1; +} + +int _PyUnicode_ToFoldedFull(Py_UCS4 ch, Py_UCS4 *res) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + if (ctype->flags & EXTENDED_CASE_MASK && (ctype->lower >> 20) & 7) { + int index = (ctype->lower & 0xFFFF) + (ctype->lower >> 24); + int n = (ctype->lower >> 20) & 7; + int i; + for (i = 0; i < n; i++) + res[i] = _PyUnicode_ExtendedCase[index + i]; + return n; + } + return _PyUnicode_ToLowerFull(ch, res); +} + +int _PyUnicode_IsCased(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & CASED_MASK) != 0; +} + +int _PyUnicode_IsCaseIgnorable(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & CASE_IGNORABLE_MASK) != 0; +} + +/* Returns 1 for Unicode characters having the category 'Ll', 'Lu', 'Lt', + 'Lo' or 'Lm', 0 otherwise. */ + +int _PyUnicode_IsAlpha(Py_UCS4 ch) +{ + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & ALPHA_MASK) != 0; +} + diff --git a/python/Objects/unicodeobject.c b/python/Objects/unicodeobject.c new file mode 100755 index 0000000..4554f61 --- /dev/null +++ b/python/Objects/unicodeobject.c @@ -0,0 +1,15920 @@ +/* + +Unicode implementation based on original code by Fredrik Lundh, +modified by Marc-Andre Lemburg . + +Major speed upgrades to the method implementations at the Reykjavik +NeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke. + +Copyright (c) Corporation for National Research Initiatives. + +-------------------------------------------------------------------- +The original string type implementation is: + + Copyright (c) 1999 by Secret Labs AB + Copyright (c) 1999 by Fredrik Lundh + +By obtaining, using, and/or copying this software and/or its +associated documentation, you agree that you have read, understood, +and will comply with the following terms and conditions: + +Permission to use, copy, modify, and distribute this software and its +associated documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies, and that both that copyright notice and this permission notice +appear in supporting documentation, and that the name of Secret Labs +AB or the author not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR +ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +-------------------------------------------------------------------- + +*/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "pycore_initconfig.h" +#include "pycore_fileutils.h" +#include "pycore_object.h" +#include "pycore_pylifecycle.h" +#include "pycore_pystate.h" +#include "ucnhash.h" +#include "bytes_methods.h" +#include "stringlib/eq.h" + +#ifdef MS_WINDOWS +#include +#endif + +/* Uncomment to display statistics on interned strings at exit when + using Valgrind or Insecure++. */ +/* #define INTERNED_STATS 1 */ + + +/*[clinic input] +class str "PyObject *" "&PyUnicode_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4884c934de622cf6]*/ + +/*[python input] +class Py_UCS4_converter(CConverter): + type = 'Py_UCS4' + converter = 'convert_uc' + + def converter_init(self): + if self.default is not unspecified: + self.c_default = ascii(self.default) + if len(self.c_default) > 4 or self.c_default[0] != "'": + self.c_default = hex(ord(self.default)) + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=88f5dd06cd8e7a61]*/ + +/* --- Globals ------------------------------------------------------------ + +NOTE: In the interpreter's initialization phase, some globals are currently + initialized dynamically as needed. In the process Unicode objects may + be created before the Unicode type is ready. + +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +// Maximum code point of Unicode 6.0: 0x10ffff (1,114,111). +// The value must be the same in fileutils.c. +#define MAX_UNICODE 0x10ffff + +#ifdef Py_DEBUG +# define _PyUnicode_CHECK(op) _PyUnicode_CheckConsistency(op, 0) +#else +# define _PyUnicode_CHECK(op) PyUnicode_Check(op) +#endif + +#define _PyUnicode_UTF8(op) \ + (((PyCompactUnicodeObject*)(op))->utf8) +#define PyUnicode_UTF8(op) \ + (assert(_PyUnicode_CHECK(op)), \ + assert(PyUnicode_IS_READY(op)), \ + PyUnicode_IS_COMPACT_ASCII(op) ? \ + ((char*)((PyASCIIObject*)(op) + 1)) : \ + _PyUnicode_UTF8(op)) +#define _PyUnicode_UTF8_LENGTH(op) \ + (((PyCompactUnicodeObject*)(op))->utf8_length) +#define PyUnicode_UTF8_LENGTH(op) \ + (assert(_PyUnicode_CHECK(op)), \ + assert(PyUnicode_IS_READY(op)), \ + PyUnicode_IS_COMPACT_ASCII(op) ? \ + ((PyASCIIObject*)(op))->length : \ + _PyUnicode_UTF8_LENGTH(op)) +#define _PyUnicode_WSTR(op) \ + (((PyASCIIObject*)(op))->wstr) +#define _PyUnicode_WSTR_LENGTH(op) \ + (((PyCompactUnicodeObject*)(op))->wstr_length) +#define _PyUnicode_LENGTH(op) \ + (((PyASCIIObject *)(op))->length) +#define _PyUnicode_STATE(op) \ + (((PyASCIIObject *)(op))->state) +#define _PyUnicode_HASH(op) \ + (((PyASCIIObject *)(op))->hash) +#define _PyUnicode_KIND(op) \ + (assert(_PyUnicode_CHECK(op)), \ + ((PyASCIIObject *)(op))->state.kind) +#define _PyUnicode_GET_LENGTH(op) \ + (assert(_PyUnicode_CHECK(op)), \ + ((PyASCIIObject *)(op))->length) +#define _PyUnicode_DATA_ANY(op) \ + (((PyUnicodeObject*)(op))->data.any) + +#undef PyUnicode_READY +#define PyUnicode_READY(op) \ + (assert(_PyUnicode_CHECK(op)), \ + (PyUnicode_IS_READY(op) ? \ + 0 : \ + _PyUnicode_Ready(op))) + +#define _PyUnicode_SHARE_UTF8(op) \ + (assert(_PyUnicode_CHECK(op)), \ + assert(!PyUnicode_IS_COMPACT_ASCII(op)), \ + (_PyUnicode_UTF8(op) == PyUnicode_DATA(op))) +#define _PyUnicode_SHARE_WSTR(op) \ + (assert(_PyUnicode_CHECK(op)), \ + (_PyUnicode_WSTR(unicode) == PyUnicode_DATA(op))) + +/* true if the Unicode object has an allocated UTF-8 memory block + (not shared with other data) */ +#define _PyUnicode_HAS_UTF8_MEMORY(op) \ + ((!PyUnicode_IS_COMPACT_ASCII(op) \ + && _PyUnicode_UTF8(op) \ + && _PyUnicode_UTF8(op) != PyUnicode_DATA(op))) + +/* true if the Unicode object has an allocated wstr memory block + (not shared with other data) */ +#define _PyUnicode_HAS_WSTR_MEMORY(op) \ + ((_PyUnicode_WSTR(op) && \ + (!PyUnicode_IS_READY(op) || \ + _PyUnicode_WSTR(op) != PyUnicode_DATA(op)))) + +/* Generic helper macro to convert characters of different types. + from_type and to_type have to be valid type names, begin and end + are pointers to the source characters which should be of type + "from_type *". to is a pointer of type "to_type *" and points to the + buffer where the result characters are written to. */ +#define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \ + do { \ + to_type *_to = (to_type *)(to); \ + const from_type *_iter = (const from_type *)(begin);\ + const from_type *_end = (const from_type *)(end);\ + Py_ssize_t n = (_end) - (_iter); \ + const from_type *_unrolled_end = \ + _iter + _Py_SIZE_ROUND_DOWN(n, 4); \ + while (_iter < (_unrolled_end)) { \ + _to[0] = (to_type) _iter[0]; \ + _to[1] = (to_type) _iter[1]; \ + _to[2] = (to_type) _iter[2]; \ + _to[3] = (to_type) _iter[3]; \ + _iter += 4; _to += 4; \ + } \ + while (_iter < (_end)) \ + *_to++ = (to_type) *_iter++; \ + } while (0) + +#ifdef MS_WINDOWS + /* On Windows, overallocate by 50% is the best factor */ +# define OVERALLOCATE_FACTOR 2 +#else + /* On Linux, overallocate by 25% is the best factor */ +# define OVERALLOCATE_FACTOR 4 +#endif + +/* This dictionary holds all interned unicode strings. Note that references + to strings in this dictionary are *not* counted in the string's ob_refcnt. + When the interned string reaches a refcnt of 0 the string deallocation + function will delete the reference from this dictionary. + + Another way to look at this is that to say that the actual reference + count of a string is: s->ob_refcnt + (s->state ? 2 : 0) +*/ +static PyObject *interned = NULL; + +/* The empty Unicode object is shared to improve performance. */ +static PyObject *unicode_empty = NULL; + +#define _Py_INCREF_UNICODE_EMPTY() \ + do { \ + if (unicode_empty != NULL) \ + Py_INCREF(unicode_empty); \ + else { \ + unicode_empty = PyUnicode_New(0, 0); \ + if (unicode_empty != NULL) { \ + Py_INCREF(unicode_empty); \ + assert(_PyUnicode_CheckConsistency(unicode_empty, 1)); \ + } \ + } \ + } while (0) + +#define _Py_RETURN_UNICODE_EMPTY() \ + do { \ + _Py_INCREF_UNICODE_EMPTY(); \ + return unicode_empty; \ + } while (0) + +static inline void +unicode_fill(enum PyUnicode_Kind kind, void *data, Py_UCS4 value, + Py_ssize_t start, Py_ssize_t length) +{ + assert(0 <= start); + assert(kind != PyUnicode_WCHAR_KIND); + switch (kind) { + case PyUnicode_1BYTE_KIND: { + assert(value <= 0xff); + Py_UCS1 ch = (unsigned char)value; + Py_UCS1 *to = (Py_UCS1 *)data + start; + memset(to, ch, length); + break; + } + case PyUnicode_2BYTE_KIND: { + assert(value <= 0xffff); + Py_UCS2 ch = (Py_UCS2)value; + Py_UCS2 *to = (Py_UCS2 *)data + start; + const Py_UCS2 *end = to + length; + for (; to < end; ++to) *to = ch; + break; + } + case PyUnicode_4BYTE_KIND: { + assert(value <= MAX_UNICODE); + Py_UCS4 ch = value; + Py_UCS4 * to = (Py_UCS4 *)data + start; + const Py_UCS4 *end = to + length; + for (; to < end; ++to) *to = ch; + break; + } + default: Py_UNREACHABLE(); + } +} + + +/* Forward declaration */ +static inline int +_PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch); +static PyObject * +unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, + const char *errors); +static PyObject * +unicode_decode_utf8(const char *s, Py_ssize_t size, + _Py_error_handler error_handler, const char *errors, + Py_ssize_t *consumed); + +/* List of static strings. */ +static _Py_Identifier *static_strings = NULL; + +/* Single character Unicode strings in the Latin-1 range are being + shared as well. */ +static PyObject *unicode_latin1[256] = {NULL}; + +/* Fast detection of the most frequent whitespace characters */ +const unsigned char _Py_ascii_whitespace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, +/* case 0x0009: * CHARACTER TABULATION */ +/* case 0x000A: * LINE FEED */ +/* case 0x000B: * LINE TABULATION */ +/* case 0x000C: * FORM FEED */ +/* case 0x000D: * CARRIAGE RETURN */ + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* case 0x001C: * FILE SEPARATOR */ +/* case 0x001D: * GROUP SEPARATOR */ +/* case 0x001E: * RECORD SEPARATOR */ +/* case 0x001F: * UNIT SEPARATOR */ + 0, 0, 0, 0, 1, 1, 1, 1, +/* case 0x0020: * SPACE */ + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* forward */ +static PyUnicodeObject *_PyUnicode_New(Py_ssize_t length); +static PyObject* get_latin1_char(unsigned char ch); +static int unicode_modifiable(PyObject *unicode); + + +static PyObject * +_PyUnicode_FromUCS1(const Py_UCS1 *s, Py_ssize_t size); +static PyObject * +_PyUnicode_FromUCS2(const Py_UCS2 *s, Py_ssize_t size); +static PyObject * +_PyUnicode_FromUCS4(const Py_UCS4 *s, Py_ssize_t size); + +static PyObject * +unicode_encode_call_errorhandler(const char *errors, + PyObject **errorHandler,const char *encoding, const char *reason, + PyObject *unicode, PyObject **exceptionObject, + Py_ssize_t startpos, Py_ssize_t endpos, Py_ssize_t *newpos); + +static void +raise_encode_exception(PyObject **exceptionObject, + const char *encoding, + PyObject *unicode, + Py_ssize_t startpos, Py_ssize_t endpos, + const char *reason); + +/* Same for linebreaks */ +static const unsigned char ascii_linebreak[] = { + 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x000A, * LINE FEED */ +/* 0x000B, * LINE TABULATION */ +/* 0x000C, * FORM FEED */ +/* 0x000D, * CARRIAGE RETURN */ + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x001C, * FILE SEPARATOR */ +/* 0x001D, * GROUP SEPARATOR */ +/* 0x001E, * RECORD SEPARATOR */ + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static int convert_uc(PyObject *obj, void *addr); + +#include "clinic/unicodeobject.c.h" + +_Py_error_handler +_Py_GetErrorHandler(const char *errors) +{ + if (errors == NULL || strcmp(errors, "strict") == 0) { + return _Py_ERROR_STRICT; + } + if (strcmp(errors, "surrogateescape") == 0) { + return _Py_ERROR_SURROGATEESCAPE; + } + if (strcmp(errors, "replace") == 0) { + return _Py_ERROR_REPLACE; + } + if (strcmp(errors, "ignore") == 0) { + return _Py_ERROR_IGNORE; + } + if (strcmp(errors, "backslashreplace") == 0) { + return _Py_ERROR_BACKSLASHREPLACE; + } + if (strcmp(errors, "surrogatepass") == 0) { + return _Py_ERROR_SURROGATEPASS; + } + if (strcmp(errors, "xmlcharrefreplace") == 0) { + return _Py_ERROR_XMLCHARREFREPLACE; + } + return _Py_ERROR_OTHER; +} + + +static _Py_error_handler +get_error_handler_wide(const wchar_t *errors) +{ + if (errors == NULL || wcscmp(errors, L"strict") == 0) { + return _Py_ERROR_STRICT; + } + if (wcscmp(errors, L"surrogateescape") == 0) { + return _Py_ERROR_SURROGATEESCAPE; + } + if (wcscmp(errors, L"replace") == 0) { + return _Py_ERROR_REPLACE; + } + if (wcscmp(errors, L"ignore") == 0) { + return _Py_ERROR_IGNORE; + } + if (wcscmp(errors, L"backslashreplace") == 0) { + return _Py_ERROR_BACKSLASHREPLACE; + } + if (wcscmp(errors, L"surrogatepass") == 0) { + return _Py_ERROR_SURROGATEPASS; + } + if (wcscmp(errors, L"xmlcharrefreplace") == 0) { + return _Py_ERROR_XMLCHARREFREPLACE; + } + return _Py_ERROR_OTHER; +} + + +/* The max unicode value is always 0x10FFFF while using the PEP-393 API. + This function is kept for backward compatibility with the old API. */ +Py_UNICODE +PyUnicode_GetMax(void) +{ +#ifdef Py_UNICODE_WIDE + return 0x10FFFF; +#else + /* This is actually an illegal character, so it should + not be passed to unichr. */ + return 0xFFFF; +#endif +} + +int +_PyUnicode_CheckConsistency(PyObject *op, int check_content) +{ +#define CHECK(expr) \ + do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) + + PyASCIIObject *ascii; + unsigned int kind; + + assert(op != NULL); + CHECK(PyUnicode_Check(op)); + + ascii = (PyASCIIObject *)op; + kind = ascii->state.kind; + + if (ascii->state.ascii == 1 && ascii->state.compact == 1) { + CHECK(kind == PyUnicode_1BYTE_KIND); + CHECK(ascii->state.ready == 1); + } + else { + PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; + void *data; + + if (ascii->state.compact == 1) { + data = compact + 1; + CHECK(kind == PyUnicode_1BYTE_KIND + || kind == PyUnicode_2BYTE_KIND + || kind == PyUnicode_4BYTE_KIND); + CHECK(ascii->state.ascii == 0); + CHECK(ascii->state.ready == 1); + CHECK(compact->utf8 != data); + } + else { + PyUnicodeObject *unicode = (PyUnicodeObject *)op; + + data = unicode->data.any; + if (kind == PyUnicode_WCHAR_KIND) { + CHECK(ascii->length == 0); + CHECK(ascii->hash == -1); + CHECK(ascii->state.compact == 0); + CHECK(ascii->state.ascii == 0); + CHECK(ascii->state.ready == 0); + CHECK(ascii->state.interned == SSTATE_NOT_INTERNED); + CHECK(ascii->wstr != NULL); + CHECK(data == NULL); + CHECK(compact->utf8 == NULL); + } + else { + CHECK(kind == PyUnicode_1BYTE_KIND + || kind == PyUnicode_2BYTE_KIND + || kind == PyUnicode_4BYTE_KIND); + CHECK(ascii->state.compact == 0); + CHECK(ascii->state.ready == 1); + CHECK(data != NULL); + if (ascii->state.ascii) { + CHECK(compact->utf8 == data); + CHECK(compact->utf8_length == ascii->length); + } + else + CHECK(compact->utf8 != data); + } + } + if (kind != PyUnicode_WCHAR_KIND) { + if ( +#if SIZEOF_WCHAR_T == 2 + kind == PyUnicode_2BYTE_KIND +#else + kind == PyUnicode_4BYTE_KIND +#endif + ) + { + CHECK(ascii->wstr == data); + CHECK(compact->wstr_length == ascii->length); + } else + CHECK(ascii->wstr != data); + } + + if (compact->utf8 == NULL) + CHECK(compact->utf8_length == 0); + if (ascii->wstr == NULL) + CHECK(compact->wstr_length == 0); + } + + /* check that the best kind is used: O(n) operation */ + if (check_content && kind != PyUnicode_WCHAR_KIND) { + Py_ssize_t i; + Py_UCS4 maxchar = 0; + void *data; + Py_UCS4 ch; + + data = PyUnicode_DATA(ascii); + for (i=0; i < ascii->length; i++) + { + ch = PyUnicode_READ(kind, data, i); + if (ch > maxchar) + maxchar = ch; + } + if (kind == PyUnicode_1BYTE_KIND) { + if (ascii->state.ascii == 0) { + CHECK(maxchar >= 128); + CHECK(maxchar <= 255); + } + else + CHECK(maxchar < 128); + } + else if (kind == PyUnicode_2BYTE_KIND) { + CHECK(maxchar >= 0x100); + CHECK(maxchar <= 0xFFFF); + } + else { + CHECK(maxchar >= 0x10000); + CHECK(maxchar <= MAX_UNICODE); + } + CHECK(PyUnicode_READ(kind, data, ascii->length) == 0); + } + return 1; + +#undef CHECK +} + + +static PyObject* +unicode_result_wchar(PyObject *unicode) +{ +#ifndef Py_DEBUG + Py_ssize_t len; + + len = _PyUnicode_WSTR_LENGTH(unicode); + if (len == 0) { + Py_DECREF(unicode); + _Py_RETURN_UNICODE_EMPTY(); + } + + if (len == 1) { + wchar_t ch = _PyUnicode_WSTR(unicode)[0]; + if ((Py_UCS4)ch < 256) { + PyObject *latin1_char = get_latin1_char((unsigned char)ch); + Py_DECREF(unicode); + return latin1_char; + } + } + + if (_PyUnicode_Ready(unicode) < 0) { + Py_DECREF(unicode); + return NULL; + } +#else + assert(Py_REFCNT(unicode) == 1); + + /* don't make the result ready in debug mode to ensure that the caller + makes the string ready before using it */ + assert(_PyUnicode_CheckConsistency(unicode, 1)); +#endif + return unicode; +} + +static PyObject* +unicode_result_ready(PyObject *unicode) +{ + Py_ssize_t length; + + length = PyUnicode_GET_LENGTH(unicode); + if (length == 0) { + if (unicode != unicode_empty) { + Py_DECREF(unicode); + _Py_RETURN_UNICODE_EMPTY(); + } + return unicode_empty; + } + + if (length == 1) { + void *data = PyUnicode_DATA(unicode); + int kind = PyUnicode_KIND(unicode); + Py_UCS4 ch = PyUnicode_READ(kind, data, 0); + if (ch < 256) { + PyObject *latin1_char = unicode_latin1[ch]; + if (latin1_char != NULL) { + if (unicode != latin1_char) { + Py_INCREF(latin1_char); + Py_DECREF(unicode); + } + return latin1_char; + } + else { + assert(_PyUnicode_CheckConsistency(unicode, 1)); + Py_INCREF(unicode); + unicode_latin1[ch] = unicode; + return unicode; + } + } + } + + assert(_PyUnicode_CheckConsistency(unicode, 1)); + return unicode; +} + +static PyObject* +unicode_result(PyObject *unicode) +{ + assert(_PyUnicode_CHECK(unicode)); + if (PyUnicode_IS_READY(unicode)) + return unicode_result_ready(unicode); + else + return unicode_result_wchar(unicode); +} + +static PyObject* +unicode_result_unchanged(PyObject *unicode) +{ + if (PyUnicode_CheckExact(unicode)) { + if (PyUnicode_READY(unicode) == -1) + return NULL; + Py_INCREF(unicode); + return unicode; + } + else + /* Subtype -- return genuine unicode string with the same value. */ + return _PyUnicode_Copy(unicode); +} + +/* Implementation of the "backslashreplace" error handler for 8-bit encodings: + ASCII, Latin1, UTF-8, etc. */ +static char* +backslashreplace(_PyBytesWriter *writer, char *str, + PyObject *unicode, Py_ssize_t collstart, Py_ssize_t collend) +{ + Py_ssize_t size, i; + Py_UCS4 ch; + enum PyUnicode_Kind kind; + void *data; + + assert(PyUnicode_IS_READY(unicode)); + kind = PyUnicode_KIND(unicode); + data = PyUnicode_DATA(unicode); + + size = 0; + /* determine replacement size */ + for (i = collstart; i < collend; ++i) { + Py_ssize_t incr; + + ch = PyUnicode_READ(kind, data, i); + if (ch < 0x100) + incr = 2+2; + else if (ch < 0x10000) + incr = 2+4; + else { + assert(ch <= MAX_UNICODE); + incr = 2+8; + } + if (size > PY_SSIZE_T_MAX - incr) { + PyErr_SetString(PyExc_OverflowError, + "encoded result is too long for a Python string"); + return NULL; + } + size += incr; + } + + str = _PyBytesWriter_Prepare(writer, str, size); + if (str == NULL) + return NULL; + + /* generate replacement */ + for (i = collstart; i < collend; ++i) { + ch = PyUnicode_READ(kind, data, i); + *str++ = '\\'; + if (ch >= 0x00010000) { + *str++ = 'U'; + *str++ = Py_hexdigits[(ch>>28)&0xf]; + *str++ = Py_hexdigits[(ch>>24)&0xf]; + *str++ = Py_hexdigits[(ch>>20)&0xf]; + *str++ = Py_hexdigits[(ch>>16)&0xf]; + *str++ = Py_hexdigits[(ch>>12)&0xf]; + *str++ = Py_hexdigits[(ch>>8)&0xf]; + } + else if (ch >= 0x100) { + *str++ = 'u'; + *str++ = Py_hexdigits[(ch>>12)&0xf]; + *str++ = Py_hexdigits[(ch>>8)&0xf]; + } + else + *str++ = 'x'; + *str++ = Py_hexdigits[(ch>>4)&0xf]; + *str++ = Py_hexdigits[ch&0xf]; + } + return str; +} + +/* Implementation of the "xmlcharrefreplace" error handler for 8-bit encodings: + ASCII, Latin1, UTF-8, etc. */ +static char* +xmlcharrefreplace(_PyBytesWriter *writer, char *str, + PyObject *unicode, Py_ssize_t collstart, Py_ssize_t collend) +{ + Py_ssize_t size, i; + Py_UCS4 ch; + enum PyUnicode_Kind kind; + void *data; + + assert(PyUnicode_IS_READY(unicode)); + kind = PyUnicode_KIND(unicode); + data = PyUnicode_DATA(unicode); + + size = 0; + /* determine replacement size */ + for (i = collstart; i < collend; ++i) { + Py_ssize_t incr; + + ch = PyUnicode_READ(kind, data, i); + if (ch < 10) + incr = 2+1+1; + else if (ch < 100) + incr = 2+2+1; + else if (ch < 1000) + incr = 2+3+1; + else if (ch < 10000) + incr = 2+4+1; + else if (ch < 100000) + incr = 2+5+1; + else if (ch < 1000000) + incr = 2+6+1; + else { + assert(ch <= MAX_UNICODE); + incr = 2+7+1; + } + if (size > PY_SSIZE_T_MAX - incr) { + PyErr_SetString(PyExc_OverflowError, + "encoded result is too long for a Python string"); + return NULL; + } + size += incr; + } + + str = _PyBytesWriter_Prepare(writer, str, size); + if (str == NULL) + return NULL; + + /* generate replacement */ + for (i = collstart; i < collend; ++i) { + str += sprintf(str, "&#%d;", PyUnicode_READ(kind, data, i)); + } + return str; +} + +/* --- Bloom Filters ----------------------------------------------------- */ + +/* stuff to implement simple "bloom filters" for Unicode characters. + to keep things simple, we use a single bitmask, using the least 5 + bits from each unicode characters as the bit index. */ + +/* the linebreak mask is set up by Unicode_Init below */ + +#if LONG_BIT >= 128 +#define BLOOM_WIDTH 128 +#elif LONG_BIT >= 64 +#define BLOOM_WIDTH 64 +#elif LONG_BIT >= 32 +#define BLOOM_WIDTH 32 +#else +#error "LONG_BIT is smaller than 32" +#endif + +#define BLOOM_MASK unsigned long + +static BLOOM_MASK bloom_linebreak = ~(BLOOM_MASK)0; + +#define BLOOM(mask, ch) ((mask & (1UL << ((ch) & (BLOOM_WIDTH - 1))))) + +#define BLOOM_LINEBREAK(ch) \ + ((ch) < 128U ? ascii_linebreak[(ch)] : \ + (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK(ch))) + +static inline BLOOM_MASK +make_bloom_mask(int kind, void* ptr, Py_ssize_t len) +{ +#define BLOOM_UPDATE(TYPE, MASK, PTR, LEN) \ + do { \ + TYPE *data = (TYPE *)PTR; \ + TYPE *end = data + LEN; \ + Py_UCS4 ch; \ + for (; data != end; data++) { \ + ch = *data; \ + MASK |= (1UL << (ch & (BLOOM_WIDTH - 1))); \ + } \ + break; \ + } while (0) + + /* calculate simple bloom-style bitmask for a given unicode string */ + + BLOOM_MASK mask; + + mask = 0; + switch (kind) { + case PyUnicode_1BYTE_KIND: + BLOOM_UPDATE(Py_UCS1, mask, ptr, len); + break; + case PyUnicode_2BYTE_KIND: + BLOOM_UPDATE(Py_UCS2, mask, ptr, len); + break; + case PyUnicode_4BYTE_KIND: + BLOOM_UPDATE(Py_UCS4, mask, ptr, len); + break; + default: + Py_UNREACHABLE(); + } + return mask; + +#undef BLOOM_UPDATE +} + +static int +ensure_unicode(PyObject *obj) +{ + if (!PyUnicode_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "must be str, not %.100s", + Py_TYPE(obj)->tp_name); + return -1; + } + return PyUnicode_READY(obj); +} + +/* Compilation of templated routines */ + +#include "stringlib/asciilib.h" +#include "stringlib/fastsearch.h" +#include "stringlib/partition.h" +#include "stringlib/split.h" +#include "stringlib/count.h" +#include "stringlib/find.h" +#include "stringlib/find_max_char.h" +#include "stringlib/undef.h" + +#include "stringlib/ucs1lib.h" +#include "stringlib/fastsearch.h" +#include "stringlib/partition.h" +#include "stringlib/split.h" +#include "stringlib/count.h" +#include "stringlib/find.h" +#include "stringlib/replace.h" +#include "stringlib/find_max_char.h" +#include "stringlib/undef.h" + +#include "stringlib/ucs2lib.h" +#include "stringlib/fastsearch.h" +#include "stringlib/partition.h" +#include "stringlib/split.h" +#include "stringlib/count.h" +#include "stringlib/find.h" +#include "stringlib/replace.h" +#include "stringlib/find_max_char.h" +#include "stringlib/undef.h" + +#include "stringlib/ucs4lib.h" +#include "stringlib/fastsearch.h" +#include "stringlib/partition.h" +#include "stringlib/split.h" +#include "stringlib/count.h" +#include "stringlib/find.h" +#include "stringlib/replace.h" +#include "stringlib/find_max_char.h" +#include "stringlib/undef.h" + +#include "stringlib/unicodedefs.h" +#include "stringlib/fastsearch.h" +#include "stringlib/count.h" +#include "stringlib/find.h" +#include "stringlib/undef.h" + +/* --- Unicode Object ----------------------------------------------------- */ + +static inline Py_ssize_t +findchar(const void *s, int kind, + Py_ssize_t size, Py_UCS4 ch, + int direction) +{ + switch (kind) { + case PyUnicode_1BYTE_KIND: + if ((Py_UCS1) ch != ch) + return -1; + if (direction > 0) + return ucs1lib_find_char((const Py_UCS1 *) s, size, (Py_UCS1) ch); + else + return ucs1lib_rfind_char((const Py_UCS1 *) s, size, (Py_UCS1) ch); + case PyUnicode_2BYTE_KIND: + if ((Py_UCS2) ch != ch) + return -1; + if (direction > 0) + return ucs2lib_find_char((const Py_UCS2 *) s, size, (Py_UCS2) ch); + else + return ucs2lib_rfind_char((const Py_UCS2 *) s, size, (Py_UCS2) ch); + case PyUnicode_4BYTE_KIND: + if (direction > 0) + return ucs4lib_find_char((const Py_UCS4 *) s, size, ch); + else + return ucs4lib_rfind_char((const Py_UCS4 *) s, size, ch); + default: + Py_UNREACHABLE(); + } +} + +#ifdef Py_DEBUG +/* Fill the data of a Unicode string with invalid characters to detect bugs + earlier. + + _PyUnicode_CheckConsistency(str, 1) detects invalid characters, at least for + ASCII and UCS-4 strings. U+00FF is invalid in ASCII and U+FFFFFFFF is an + invalid character in Unicode 6.0. */ +static void +unicode_fill_invalid(PyObject *unicode, Py_ssize_t old_length) +{ + int kind = PyUnicode_KIND(unicode); + Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode); + Py_ssize_t length = _PyUnicode_LENGTH(unicode); + if (length <= old_length) + return; + memset(data + old_length * kind, 0xff, (length - old_length) * kind); +} +#endif + +static PyObject* +resize_compact(PyObject *unicode, Py_ssize_t length) +{ + Py_ssize_t char_size; + Py_ssize_t struct_size; + Py_ssize_t new_size; + int share_wstr; + PyObject *new_unicode; +#ifdef Py_DEBUG + Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); +#endif + + assert(unicode_modifiable(unicode)); + assert(PyUnicode_IS_READY(unicode)); + assert(PyUnicode_IS_COMPACT(unicode)); + + char_size = PyUnicode_KIND(unicode); + if (PyUnicode_IS_ASCII(unicode)) + struct_size = sizeof(PyASCIIObject); + else + struct_size = sizeof(PyCompactUnicodeObject); + share_wstr = _PyUnicode_SHARE_WSTR(unicode); + + if (length > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) { + PyErr_NoMemory(); + return NULL; + } + new_size = (struct_size + (length + 1) * char_size); + + if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) { + PyObject_DEL(_PyUnicode_UTF8(unicode)); + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + } + _Py_DEC_REFTOTAL; + _Py_ForgetReference(unicode); + + new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size); + if (new_unicode == NULL) { + _Py_NewReference(unicode); + PyErr_NoMemory(); + return NULL; + } + unicode = new_unicode; + _Py_NewReference(unicode); + + _PyUnicode_LENGTH(unicode) = length; + if (share_wstr) { + _PyUnicode_WSTR(unicode) = PyUnicode_DATA(unicode); + if (!PyUnicode_IS_ASCII(unicode)) + _PyUnicode_WSTR_LENGTH(unicode) = length; + } + else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { + PyObject_DEL(_PyUnicode_WSTR(unicode)); + _PyUnicode_WSTR(unicode) = NULL; + if (!PyUnicode_IS_ASCII(unicode)) + _PyUnicode_WSTR_LENGTH(unicode) = 0; + } +#ifdef Py_DEBUG + unicode_fill_invalid(unicode, old_length); +#endif + PyUnicode_WRITE(PyUnicode_KIND(unicode), PyUnicode_DATA(unicode), + length, 0); + assert(_PyUnicode_CheckConsistency(unicode, 0)); + return unicode; +} + +static int +resize_inplace(PyObject *unicode, Py_ssize_t length) +{ + wchar_t *wstr; + Py_ssize_t new_size; + assert(!PyUnicode_IS_COMPACT(unicode)); + assert(Py_REFCNT(unicode) == 1); + + if (PyUnicode_IS_READY(unicode)) { + Py_ssize_t char_size; + int share_wstr, share_utf8; + void *data; +#ifdef Py_DEBUG + Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); +#endif + + data = _PyUnicode_DATA_ANY(unicode); + char_size = PyUnicode_KIND(unicode); + share_wstr = _PyUnicode_SHARE_WSTR(unicode); + share_utf8 = _PyUnicode_SHARE_UTF8(unicode); + + if (length > (PY_SSIZE_T_MAX / char_size - 1)) { + PyErr_NoMemory(); + return -1; + } + new_size = (length + 1) * char_size; + + if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) + { + PyObject_DEL(_PyUnicode_UTF8(unicode)); + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + } + + data = (PyObject *)PyObject_REALLOC(data, new_size); + if (data == NULL) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_DATA_ANY(unicode) = data; + if (share_wstr) { + _PyUnicode_WSTR(unicode) = data; + _PyUnicode_WSTR_LENGTH(unicode) = length; + } + if (share_utf8) { + _PyUnicode_UTF8(unicode) = data; + _PyUnicode_UTF8_LENGTH(unicode) = length; + } + _PyUnicode_LENGTH(unicode) = length; + PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0); +#ifdef Py_DEBUG + unicode_fill_invalid(unicode, old_length); +#endif + if (share_wstr || _PyUnicode_WSTR(unicode) == NULL) { + assert(_PyUnicode_CheckConsistency(unicode, 0)); + return 0; + } + } + assert(_PyUnicode_WSTR(unicode) != NULL); + + /* check for integer overflow */ + if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) { + PyErr_NoMemory(); + return -1; + } + new_size = sizeof(wchar_t) * (length + 1); + wstr = _PyUnicode_WSTR(unicode); + wstr = PyObject_REALLOC(wstr, new_size); + if (!wstr) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_WSTR(unicode) = wstr; + _PyUnicode_WSTR(unicode)[length] = 0; + _PyUnicode_WSTR_LENGTH(unicode) = length; + assert(_PyUnicode_CheckConsistency(unicode, 0)); + return 0; +} + +static PyObject* +resize_copy(PyObject *unicode, Py_ssize_t length) +{ + Py_ssize_t copy_length; + if (_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND) { + PyObject *copy; + + assert(PyUnicode_IS_READY(unicode)); + + copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); + if (copy == NULL) + return NULL; + + copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); + _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); + return copy; + } + else { + PyObject *w; + + w = (PyObject*)_PyUnicode_New(length); + if (w == NULL) + return NULL; + copy_length = _PyUnicode_WSTR_LENGTH(unicode); + copy_length = Py_MIN(copy_length, length); + memcpy(_PyUnicode_WSTR(w), _PyUnicode_WSTR(unicode), + copy_length * sizeof(wchar_t)); + return w; + } +} + +/* We allocate one more byte to make sure the string is + Ux0000 terminated; some code (e.g. new_identifier) + relies on that. + + XXX This allocator could further be enhanced by assuring that the + free list never reduces its size below 1. + +*/ + +static PyUnicodeObject * +_PyUnicode_New(Py_ssize_t length) +{ + PyUnicodeObject *unicode; + size_t new_size; + + /* Optimization for empty strings */ + if (length == 0 && unicode_empty != NULL) { + Py_INCREF(unicode_empty); + return (PyUnicodeObject*)unicode_empty; + } + + /* Ensure we won't overflow the size. */ + if (length > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { + return (PyUnicodeObject *)PyErr_NoMemory(); + } + if (length < 0) { + PyErr_SetString(PyExc_SystemError, + "Negative size passed to _PyUnicode_New"); + return NULL; + } + + unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type); + if (unicode == NULL) + return NULL; + new_size = sizeof(Py_UNICODE) * ((size_t)length + 1); + + _PyUnicode_WSTR_LENGTH(unicode) = length; + _PyUnicode_HASH(unicode) = -1; + _PyUnicode_STATE(unicode).interned = 0; + _PyUnicode_STATE(unicode).kind = 0; + _PyUnicode_STATE(unicode).compact = 0; + _PyUnicode_STATE(unicode).ready = 0; + _PyUnicode_STATE(unicode).ascii = 0; + _PyUnicode_DATA_ANY(unicode) = NULL; + _PyUnicode_LENGTH(unicode) = 0; + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + + _PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_MALLOC(new_size); + if (!_PyUnicode_WSTR(unicode)) { + Py_DECREF(unicode); + PyErr_NoMemory(); + return NULL; + } + + /* Initialize the first element to guard against cases where + * the caller fails before initializing str -- unicode_resize() + * reads str[0], and the Keep-Alive optimization can keep memory + * allocated for str alive across a call to unicode_dealloc(unicode). + * We don't want unicode_resize to read uninitialized memory in + * that case. + */ + _PyUnicode_WSTR(unicode)[0] = 0; + _PyUnicode_WSTR(unicode)[length] = 0; + + assert(_PyUnicode_CheckConsistency((PyObject *)unicode, 0)); + return unicode; +} + +static const char* +unicode_kind_name(PyObject *unicode) +{ + /* don't check consistency: unicode_kind_name() is called from + _PyUnicode_Dump() */ + if (!PyUnicode_IS_COMPACT(unicode)) + { + if (!PyUnicode_IS_READY(unicode)) + return "wstr"; + switch (PyUnicode_KIND(unicode)) + { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(unicode)) + return "legacy ascii"; + else + return "legacy latin1"; + case PyUnicode_2BYTE_KIND: + return "legacy UCS2"; + case PyUnicode_4BYTE_KIND: + return "legacy UCS4"; + default: + return ""; + } + } + assert(PyUnicode_IS_READY(unicode)); + switch (PyUnicode_KIND(unicode)) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(unicode)) + return "ascii"; + else + return "latin1"; + case PyUnicode_2BYTE_KIND: + return "UCS2"; + case PyUnicode_4BYTE_KIND: + return "UCS4"; + default: + return ""; + } +} + +#ifdef Py_DEBUG +/* Functions wrapping macros for use in debugger */ +char *_PyUnicode_utf8(void *unicode_raw){ + PyObject *unicode = _PyObject_CAST(unicode_raw); + return PyUnicode_UTF8(unicode); +} + +void *_PyUnicode_compact_data(void *unicode_raw) { + PyObject *unicode = _PyObject_CAST(unicode_raw); + return _PyUnicode_COMPACT_DATA(unicode); +} +void *_PyUnicode_data(void *unicode_raw) { + PyObject *unicode = _PyObject_CAST(unicode_raw); + printf("obj %p\n", (void*)unicode); + printf("compact %d\n", PyUnicode_IS_COMPACT(unicode)); + printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode)); + printf("ascii op %p\n", ((void*)((PyASCIIObject*)(unicode) + 1))); + printf("compact op %p\n", ((void*)((PyCompactUnicodeObject*)(unicode) + 1))); + printf("compact data %p\n", _PyUnicode_COMPACT_DATA(unicode)); + return PyUnicode_DATA(unicode); +} + +void +_PyUnicode_Dump(PyObject *op) +{ + PyASCIIObject *ascii = (PyASCIIObject *)op; + PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; + PyUnicodeObject *unicode = (PyUnicodeObject *)op; + void *data; + + if (ascii->state.compact) + { + if (ascii->state.ascii) + data = (ascii + 1); + else + data = (compact + 1); + } + else + data = unicode->data.any; + printf("%s: len=%" PY_FORMAT_SIZE_T "u, ", + unicode_kind_name(op), ascii->length); + + if (ascii->wstr == data) + printf("shared "); + printf("wstr=%p", (void *)ascii->wstr); + + if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) { + printf(" (%" PY_FORMAT_SIZE_T "u), ", compact->wstr_length); + if (!ascii->state.compact && compact->utf8 == unicode->data.any) + printf("shared "); + printf("utf8=%p (%" PY_FORMAT_SIZE_T "u)", + (void *)compact->utf8, compact->utf8_length); + } + printf(", data=%p\n", data); +} +#endif + +PyObject * +PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) +{ + PyObject *obj; + PyCompactUnicodeObject *unicode; + void *data; + enum PyUnicode_Kind kind; + int is_sharing, is_ascii; + Py_ssize_t char_size; + Py_ssize_t struct_size; + + /* Optimization for empty strings */ + if (size == 0 && unicode_empty != NULL) { + Py_INCREF(unicode_empty); + return unicode_empty; + } + + is_ascii = 0; + is_sharing = 0; + struct_size = sizeof(PyCompactUnicodeObject); + if (maxchar < 128) { + kind = PyUnicode_1BYTE_KIND; + char_size = 1; + is_ascii = 1; + struct_size = sizeof(PyASCIIObject); + } + else if (maxchar < 256) { + kind = PyUnicode_1BYTE_KIND; + char_size = 1; + } + else if (maxchar < 65536) { + kind = PyUnicode_2BYTE_KIND; + char_size = 2; + if (sizeof(wchar_t) == 2) + is_sharing = 1; + } + else { + if (maxchar > MAX_UNICODE) { + PyErr_SetString(PyExc_SystemError, + "invalid maximum character passed to PyUnicode_New"); + return NULL; + } + kind = PyUnicode_4BYTE_KIND; + char_size = 4; + if (sizeof(wchar_t) == 4) + is_sharing = 1; + } + + /* Ensure we won't overflow the size. */ + if (size < 0) { + PyErr_SetString(PyExc_SystemError, + "Negative size passed to PyUnicode_New"); + return NULL; + } + if (size > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) + return PyErr_NoMemory(); + + /* Duplicated allocation code from _PyObject_New() instead of a call to + * PyObject_New() so we are able to allocate space for the object and + * it's data buffer. + */ + obj = (PyObject *) PyObject_MALLOC(struct_size + (size + 1) * char_size); + if (obj == NULL) + return PyErr_NoMemory(); + obj = PyObject_INIT(obj, &PyUnicode_Type); + if (obj == NULL) + return NULL; + + unicode = (PyCompactUnicodeObject *)obj; + if (is_ascii) + data = ((PyASCIIObject*)obj) + 1; + else + data = unicode + 1; + _PyUnicode_LENGTH(unicode) = size; + _PyUnicode_HASH(unicode) = -1; + _PyUnicode_STATE(unicode).interned = 0; + _PyUnicode_STATE(unicode).kind = kind; + _PyUnicode_STATE(unicode).compact = 1; + _PyUnicode_STATE(unicode).ready = 1; + _PyUnicode_STATE(unicode).ascii = is_ascii; + if (is_ascii) { + ((char*)data)[size] = 0; + _PyUnicode_WSTR(unicode) = NULL; + } + else if (kind == PyUnicode_1BYTE_KIND) { + ((char*)data)[size] = 0; + _PyUnicode_WSTR(unicode) = NULL; + _PyUnicode_WSTR_LENGTH(unicode) = 0; + unicode->utf8 = NULL; + unicode->utf8_length = 0; + } + else { + unicode->utf8 = NULL; + unicode->utf8_length = 0; + if (kind == PyUnicode_2BYTE_KIND) + ((Py_UCS2*)data)[size] = 0; + else /* kind == PyUnicode_4BYTE_KIND */ + ((Py_UCS4*)data)[size] = 0; + if (is_sharing) { + _PyUnicode_WSTR_LENGTH(unicode) = size; + _PyUnicode_WSTR(unicode) = (wchar_t *)data; + } + else { + _PyUnicode_WSTR_LENGTH(unicode) = 0; + _PyUnicode_WSTR(unicode) = NULL; + } + } +#ifdef Py_DEBUG + unicode_fill_invalid((PyObject*)unicode, 0); +#endif + assert(_PyUnicode_CheckConsistency((PyObject*)unicode, 0)); + return obj; +} + +#if SIZEOF_WCHAR_T == 2 +/* Helper function to convert a 16-bits wchar_t representation to UCS4, this + will decode surrogate pairs, the other conversions are implemented as macros + for efficiency. + + This function assumes that unicode can hold one more code point than wstr + characters for a terminating null character. */ +static void +unicode_convert_wchar_to_ucs4(const wchar_t *begin, const wchar_t *end, + PyObject *unicode) +{ + const wchar_t *iter; + Py_UCS4 *ucs4_out; + + assert(unicode != NULL); + assert(_PyUnicode_CHECK(unicode)); + assert(_PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND); + ucs4_out = PyUnicode_4BYTE_DATA(unicode); + + for (iter = begin; iter < end; ) { + assert(ucs4_out < (PyUnicode_4BYTE_DATA(unicode) + + _PyUnicode_GET_LENGTH(unicode))); + if (Py_UNICODE_IS_HIGH_SURROGATE(iter[0]) + && (iter+1) < end + && Py_UNICODE_IS_LOW_SURROGATE(iter[1])) + { + *ucs4_out++ = Py_UNICODE_JOIN_SURROGATES(iter[0], iter[1]); + iter += 2; + } + else { + *ucs4_out++ = *iter; + iter++; + } + } + assert(ucs4_out == (PyUnicode_4BYTE_DATA(unicode) + + _PyUnicode_GET_LENGTH(unicode))); + +} +#endif + +static int +unicode_check_modifiable(PyObject *unicode) +{ + if (!unicode_modifiable(unicode)) { + PyErr_SetString(PyExc_SystemError, + "Cannot modify a string currently used"); + return -1; + } + return 0; +} + +static int +_copy_characters(PyObject *to, Py_ssize_t to_start, + PyObject *from, Py_ssize_t from_start, + Py_ssize_t how_many, int check_maxchar) +{ + unsigned int from_kind, to_kind; + void *from_data, *to_data; + + assert(0 <= how_many); + assert(0 <= from_start); + assert(0 <= to_start); + assert(PyUnicode_Check(from)); + assert(PyUnicode_IS_READY(from)); + assert(from_start + how_many <= PyUnicode_GET_LENGTH(from)); + + assert(PyUnicode_Check(to)); + assert(PyUnicode_IS_READY(to)); + assert(to_start + how_many <= PyUnicode_GET_LENGTH(to)); + + if (how_many == 0) + return 0; + + from_kind = PyUnicode_KIND(from); + from_data = PyUnicode_DATA(from); + to_kind = PyUnicode_KIND(to); + to_data = PyUnicode_DATA(to); + +#ifdef Py_DEBUG + if (!check_maxchar + && PyUnicode_MAX_CHAR_VALUE(from) > PyUnicode_MAX_CHAR_VALUE(to)) + { + const Py_UCS4 to_maxchar = PyUnicode_MAX_CHAR_VALUE(to); + Py_UCS4 ch; + Py_ssize_t i; + for (i=0; i < how_many; i++) { + ch = PyUnicode_READ(from_kind, from_data, from_start + i); + assert(ch <= to_maxchar); + } + } +#endif + + if (from_kind == to_kind) { + if (check_maxchar + && !PyUnicode_IS_ASCII(from) && PyUnicode_IS_ASCII(to)) + { + /* Writing Latin-1 characters into an ASCII string requires to + check that all written characters are pure ASCII */ + Py_UCS4 max_char; + max_char = ucs1lib_find_max_char(from_data, + (Py_UCS1*)from_data + how_many); + if (max_char >= 128) + return -1; + } + memcpy((char*)to_data + to_kind * to_start, + (char*)from_data + from_kind * from_start, + to_kind * how_many); + } + else if (from_kind == PyUnicode_1BYTE_KIND + && to_kind == PyUnicode_2BYTE_KIND) + { + _PyUnicode_CONVERT_BYTES( + Py_UCS1, Py_UCS2, + PyUnicode_1BYTE_DATA(from) + from_start, + PyUnicode_1BYTE_DATA(from) + from_start + how_many, + PyUnicode_2BYTE_DATA(to) + to_start + ); + } + else if (from_kind == PyUnicode_1BYTE_KIND + && to_kind == PyUnicode_4BYTE_KIND) + { + _PyUnicode_CONVERT_BYTES( + Py_UCS1, Py_UCS4, + PyUnicode_1BYTE_DATA(from) + from_start, + PyUnicode_1BYTE_DATA(from) + from_start + how_many, + PyUnicode_4BYTE_DATA(to) + to_start + ); + } + else if (from_kind == PyUnicode_2BYTE_KIND + && to_kind == PyUnicode_4BYTE_KIND) + { + _PyUnicode_CONVERT_BYTES( + Py_UCS2, Py_UCS4, + PyUnicode_2BYTE_DATA(from) + from_start, + PyUnicode_2BYTE_DATA(from) + from_start + how_many, + PyUnicode_4BYTE_DATA(to) + to_start + ); + } + else { + assert (PyUnicode_MAX_CHAR_VALUE(from) > PyUnicode_MAX_CHAR_VALUE(to)); + + if (!check_maxchar) { + if (from_kind == PyUnicode_2BYTE_KIND + && to_kind == PyUnicode_1BYTE_KIND) + { + _PyUnicode_CONVERT_BYTES( + Py_UCS2, Py_UCS1, + PyUnicode_2BYTE_DATA(from) + from_start, + PyUnicode_2BYTE_DATA(from) + from_start + how_many, + PyUnicode_1BYTE_DATA(to) + to_start + ); + } + else if (from_kind == PyUnicode_4BYTE_KIND + && to_kind == PyUnicode_1BYTE_KIND) + { + _PyUnicode_CONVERT_BYTES( + Py_UCS4, Py_UCS1, + PyUnicode_4BYTE_DATA(from) + from_start, + PyUnicode_4BYTE_DATA(from) + from_start + how_many, + PyUnicode_1BYTE_DATA(to) + to_start + ); + } + else if (from_kind == PyUnicode_4BYTE_KIND + && to_kind == PyUnicode_2BYTE_KIND) + { + _PyUnicode_CONVERT_BYTES( + Py_UCS4, Py_UCS2, + PyUnicode_4BYTE_DATA(from) + from_start, + PyUnicode_4BYTE_DATA(from) + from_start + how_many, + PyUnicode_2BYTE_DATA(to) + to_start + ); + } + else { + Py_UNREACHABLE(); + } + } + else { + const Py_UCS4 to_maxchar = PyUnicode_MAX_CHAR_VALUE(to); + Py_UCS4 ch; + Py_ssize_t i; + + for (i=0; i < how_many; i++) { + ch = PyUnicode_READ(from_kind, from_data, from_start + i); + if (ch > to_maxchar) + return -1; + PyUnicode_WRITE(to_kind, to_data, to_start + i, ch); + } + } + } + return 0; +} + +void +_PyUnicode_FastCopyCharacters( + PyObject *to, Py_ssize_t to_start, + PyObject *from, Py_ssize_t from_start, Py_ssize_t how_many) +{ + (void)_copy_characters(to, to_start, from, from_start, how_many, 0); +} + +Py_ssize_t +PyUnicode_CopyCharacters(PyObject *to, Py_ssize_t to_start, + PyObject *from, Py_ssize_t from_start, + Py_ssize_t how_many) +{ + int err; + + if (!PyUnicode_Check(from) || !PyUnicode_Check(to)) { + PyErr_BadInternalCall(); + return -1; + } + + if (PyUnicode_READY(from) == -1) + return -1; + if (PyUnicode_READY(to) == -1) + return -1; + + if ((size_t)from_start > (size_t)PyUnicode_GET_LENGTH(from)) { + PyErr_SetString(PyExc_IndexError, "string index out of range"); + return -1; + } + if ((size_t)to_start > (size_t)PyUnicode_GET_LENGTH(to)) { + PyErr_SetString(PyExc_IndexError, "string index out of range"); + return -1; + } + if (how_many < 0) { + PyErr_SetString(PyExc_SystemError, "how_many cannot be negative"); + return -1; + } + how_many = Py_MIN(PyUnicode_GET_LENGTH(from)-from_start, how_many); + if (to_start + how_many > PyUnicode_GET_LENGTH(to)) { + PyErr_Format(PyExc_SystemError, + "Cannot write %zi characters at %zi " + "in a string of %zi characters", + how_many, to_start, PyUnicode_GET_LENGTH(to)); + return -1; + } + + if (how_many == 0) + return 0; + + if (unicode_check_modifiable(to)) + return -1; + + err = _copy_characters(to, to_start, from, from_start, how_many, 1); + if (err) { + PyErr_Format(PyExc_SystemError, + "Cannot copy %s characters " + "into a string of %s characters", + unicode_kind_name(from), + unicode_kind_name(to)); + return -1; + } + return how_many; +} + +/* Find the maximum code point and count the number of surrogate pairs so a + correct string length can be computed before converting a string to UCS4. + This function counts single surrogates as a character and not as a pair. + + Return 0 on success, or -1 on error. */ +static int +find_maxchar_surrogates(const wchar_t *begin, const wchar_t *end, + Py_UCS4 *maxchar, Py_ssize_t *num_surrogates) +{ + const wchar_t *iter; + Py_UCS4 ch; + + assert(num_surrogates != NULL && maxchar != NULL); + *num_surrogates = 0; + *maxchar = 0; + + for (iter = begin; iter < end; ) { +#if SIZEOF_WCHAR_T == 2 + if (Py_UNICODE_IS_HIGH_SURROGATE(iter[0]) + && (iter+1) < end + && Py_UNICODE_IS_LOW_SURROGATE(iter[1])) + { + ch = Py_UNICODE_JOIN_SURROGATES(iter[0], iter[1]); + ++(*num_surrogates); + iter += 2; + } + else +#endif + { + ch = *iter; + iter++; + } + if (ch > *maxchar) { + *maxchar = ch; + if (*maxchar > MAX_UNICODE) { + PyErr_Format(PyExc_ValueError, + "character U+%x is not in range [U+0000; U+%x]", + ch, MAX_UNICODE); + return -1; + } + } + } + return 0; +} + +int +_PyUnicode_Ready(PyObject *unicode) +{ + wchar_t *end; + Py_UCS4 maxchar = 0; + Py_ssize_t num_surrogates; +#if SIZEOF_WCHAR_T == 2 + Py_ssize_t length_wo_surrogates; +#endif + + /* _PyUnicode_Ready() is only intended for old-style API usage where + strings were created using _PyObject_New() and where no canonical + representation (the str field) has been set yet aka strings + which are not yet ready. */ + assert(_PyUnicode_CHECK(unicode)); + assert(_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND); + assert(_PyUnicode_WSTR(unicode) != NULL); + assert(_PyUnicode_DATA_ANY(unicode) == NULL); + assert(_PyUnicode_UTF8(unicode) == NULL); + /* Actually, it should neither be interned nor be anything else: */ + assert(_PyUnicode_STATE(unicode).interned == SSTATE_NOT_INTERNED); + + end = _PyUnicode_WSTR(unicode) + _PyUnicode_WSTR_LENGTH(unicode); + if (find_maxchar_surrogates(_PyUnicode_WSTR(unicode), end, + &maxchar, &num_surrogates) == -1) + return -1; + + if (maxchar < 256) { + _PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(_PyUnicode_WSTR_LENGTH(unicode) + 1); + if (!_PyUnicode_DATA_ANY(unicode)) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_CONVERT_BYTES(wchar_t, unsigned char, + _PyUnicode_WSTR(unicode), end, + PyUnicode_1BYTE_DATA(unicode)); + PyUnicode_1BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; + _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); + _PyUnicode_STATE(unicode).kind = PyUnicode_1BYTE_KIND; + if (maxchar < 128) { + _PyUnicode_STATE(unicode).ascii = 1; + _PyUnicode_UTF8(unicode) = _PyUnicode_DATA_ANY(unicode); + _PyUnicode_UTF8_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); + } + else { + _PyUnicode_STATE(unicode).ascii = 0; + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + } + PyObject_FREE(_PyUnicode_WSTR(unicode)); + _PyUnicode_WSTR(unicode) = NULL; + _PyUnicode_WSTR_LENGTH(unicode) = 0; + } + /* In this case we might have to convert down from 4-byte native + wchar_t to 2-byte unicode. */ + else if (maxchar < 65536) { + assert(num_surrogates == 0 && + "FindMaxCharAndNumSurrogatePairs() messed up"); + +#if SIZEOF_WCHAR_T == 2 + /* We can share representations and are done. */ + _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); + PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; + _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); + _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; +#else + /* sizeof(wchar_t) == 4 */ + _PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC( + 2 * (_PyUnicode_WSTR_LENGTH(unicode) + 1)); + if (!_PyUnicode_DATA_ANY(unicode)) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_CONVERT_BYTES(wchar_t, Py_UCS2, + _PyUnicode_WSTR(unicode), end, + PyUnicode_2BYTE_DATA(unicode)); + PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; + _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); + _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + PyObject_FREE(_PyUnicode_WSTR(unicode)); + _PyUnicode_WSTR(unicode) = NULL; + _PyUnicode_WSTR_LENGTH(unicode) = 0; +#endif + } + /* maxchar exeeds 16 bit, wee need 4 bytes for unicode characters */ + else { +#if SIZEOF_WCHAR_T == 2 + /* in case the native representation is 2-bytes, we need to allocate a + new normalized 4-byte version. */ + length_wo_surrogates = _PyUnicode_WSTR_LENGTH(unicode) - num_surrogates; + if (length_wo_surrogates > PY_SSIZE_T_MAX / 4 - 1) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(4 * (length_wo_surrogates + 1)); + if (!_PyUnicode_DATA_ANY(unicode)) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_LENGTH(unicode) = length_wo_surrogates; + _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + /* unicode_convert_wchar_to_ucs4() requires a ready string */ + _PyUnicode_STATE(unicode).ready = 1; + unicode_convert_wchar_to_ucs4(_PyUnicode_WSTR(unicode), end, unicode); + PyObject_FREE(_PyUnicode_WSTR(unicode)); + _PyUnicode_WSTR(unicode) = NULL; + _PyUnicode_WSTR_LENGTH(unicode) = 0; +#else + assert(num_surrogates == 0); + + _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); + _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; +#endif + PyUnicode_4BYTE_DATA(unicode)[_PyUnicode_LENGTH(unicode)] = '\0'; + } + _PyUnicode_STATE(unicode).ready = 1; + assert(_PyUnicode_CheckConsistency(unicode, 1)); + return 0; +} + +static void +unicode_dealloc(PyObject *unicode) +{ + switch (PyUnicode_CHECK_INTERNED(unicode)) { + case SSTATE_NOT_INTERNED: + break; + + case SSTATE_INTERNED_MORTAL: + /* revive dead object temporarily for DelItem */ + Py_REFCNT(unicode) = 3; + if (PyDict_DelItem(interned, unicode) != 0) + Py_FatalError( + "deletion of interned string failed"); + break; + + case SSTATE_INTERNED_IMMORTAL: + Py_FatalError("Immortal interned string died."); + /* fall through */ + + default: + Py_FatalError("Inconsistent interned string state."); + } + + if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) + PyObject_DEL(_PyUnicode_WSTR(unicode)); + if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) + PyObject_DEL(_PyUnicode_UTF8(unicode)); + if (!PyUnicode_IS_COMPACT(unicode) && _PyUnicode_DATA_ANY(unicode)) + PyObject_DEL(_PyUnicode_DATA_ANY(unicode)); + + Py_TYPE(unicode)->tp_free(unicode); +} + +#ifdef Py_DEBUG +static int +unicode_is_singleton(PyObject *unicode) +{ + PyASCIIObject *ascii = (PyASCIIObject *)unicode; + if (unicode == unicode_empty) + return 1; + if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) + { + Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); + if (ch < 256 && unicode_latin1[ch] == unicode) + return 1; + } + return 0; +} +#endif + +static int +unicode_modifiable(PyObject *unicode) +{ + assert(_PyUnicode_CHECK(unicode)); + if (Py_REFCNT(unicode) != 1) + return 0; + if (_PyUnicode_HASH(unicode) != -1) + return 0; + if (PyUnicode_CHECK_INTERNED(unicode)) + return 0; + if (!PyUnicode_CheckExact(unicode)) + return 0; +#ifdef Py_DEBUG + /* singleton refcount is greater than 1 */ + assert(!unicode_is_singleton(unicode)); +#endif + return 1; +} + +static int +unicode_resize(PyObject **p_unicode, Py_ssize_t length) +{ + PyObject *unicode; + Py_ssize_t old_length; + + assert(p_unicode != NULL); + unicode = *p_unicode; + + assert(unicode != NULL); + assert(PyUnicode_Check(unicode)); + assert(0 <= length); + + if (_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND) + old_length = PyUnicode_WSTR_LENGTH(unicode); + else + old_length = PyUnicode_GET_LENGTH(unicode); + if (old_length == length) + return 0; + + if (length == 0) { + _Py_INCREF_UNICODE_EMPTY(); + if (!unicode_empty) + return -1; + Py_SETREF(*p_unicode, unicode_empty); + return 0; + } + + if (!unicode_modifiable(unicode)) { + PyObject *copy = resize_copy(unicode, length); + if (copy == NULL) + return -1; + Py_SETREF(*p_unicode, copy); + return 0; + } + + if (PyUnicode_IS_COMPACT(unicode)) { + PyObject *new_unicode = resize_compact(unicode, length); + if (new_unicode == NULL) + return -1; + *p_unicode = new_unicode; + return 0; + } + return resize_inplace(unicode, length); +} + +int +PyUnicode_Resize(PyObject **p_unicode, Py_ssize_t length) +{ + PyObject *unicode; + if (p_unicode == NULL) { + PyErr_BadInternalCall(); + return -1; + } + unicode = *p_unicode; + if (unicode == NULL || !PyUnicode_Check(unicode) || length < 0) + { + PyErr_BadInternalCall(); + return -1; + } + return unicode_resize(p_unicode, length); +} + +/* Copy an ASCII or latin1 char* string into a Python Unicode string. + + WARNING: The function doesn't copy the terminating null character and + doesn't check the maximum character (may write a latin1 character in an + ASCII string). */ +static void +unicode_write_cstr(PyObject *unicode, Py_ssize_t index, + const char *str, Py_ssize_t len) +{ + enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + void *data = PyUnicode_DATA(unicode); + const char *end = str + len; + + switch (kind) { + case PyUnicode_1BYTE_KIND: { + assert(index + len <= PyUnicode_GET_LENGTH(unicode)); +#ifdef Py_DEBUG + if (PyUnicode_IS_ASCII(unicode)) { + Py_UCS4 maxchar = ucs1lib_find_max_char( + (const Py_UCS1*)str, + (const Py_UCS1*)str + len); + assert(maxchar < 128); + } +#endif + memcpy((char *) data + index, str, len); + break; + } + case PyUnicode_2BYTE_KIND: { + Py_UCS2 *start = (Py_UCS2 *)data + index; + Py_UCS2 *ucs2 = start; + assert(index <= PyUnicode_GET_LENGTH(unicode)); + + for (; str < end; ++ucs2, ++str) + *ucs2 = (Py_UCS2)*str; + + assert((ucs2 - start) <= PyUnicode_GET_LENGTH(unicode)); + break; + } + default: { + Py_UCS4 *start = (Py_UCS4 *)data + index; + Py_UCS4 *ucs4 = start; + assert(kind == PyUnicode_4BYTE_KIND); + assert(index <= PyUnicode_GET_LENGTH(unicode)); + + for (; str < end; ++ucs4, ++str) + *ucs4 = (Py_UCS4)*str; + + assert((ucs4 - start) <= PyUnicode_GET_LENGTH(unicode)); + } + } +} + +static PyObject* +get_latin1_char(unsigned char ch) +{ + PyObject *unicode = unicode_latin1[ch]; + if (!unicode) { + unicode = PyUnicode_New(1, ch); + if (!unicode) + return NULL; + PyUnicode_1BYTE_DATA(unicode)[0] = ch; + assert(_PyUnicode_CheckConsistency(unicode, 1)); + unicode_latin1[ch] = unicode; + } + Py_INCREF(unicode); + return unicode; +} + +static PyObject* +unicode_char(Py_UCS4 ch) +{ + PyObject *unicode; + + assert(ch <= MAX_UNICODE); + + if (ch < 256) + return get_latin1_char(ch); + + unicode = PyUnicode_New(1, ch); + if (unicode == NULL) + return NULL; + + assert(PyUnicode_KIND(unicode) != PyUnicode_1BYTE_KIND); + if (PyUnicode_KIND(unicode) == PyUnicode_2BYTE_KIND) { + PyUnicode_2BYTE_DATA(unicode)[0] = (Py_UCS2)ch; + } else { + assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND); + PyUnicode_4BYTE_DATA(unicode)[0] = ch; + } + assert(_PyUnicode_CheckConsistency(unicode, 1)); + return unicode; +} + +PyObject * +PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) +{ + if (u == NULL) + return (PyObject*)_PyUnicode_New(size); + + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } + + return PyUnicode_FromWideChar(u, size); +} + +PyObject * +PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size) +{ + PyObject *unicode; + Py_UCS4 maxchar = 0; + Py_ssize_t num_surrogates; + + if (u == NULL && size != 0) { + PyErr_BadInternalCall(); + return NULL; + } + + if (size == -1) { + size = wcslen(u); + } + + /* If the Unicode data is known at construction time, we can apply + some optimizations which share commonly used objects. */ + + /* Optimization for empty strings */ + if (size == 0) + _Py_RETURN_UNICODE_EMPTY(); + + /* Single character Unicode objects in the Latin-1 range are + shared when using this constructor */ + if (size == 1 && (Py_UCS4)*u < 256) + return get_latin1_char((unsigned char)*u); + + /* If not empty and not single character, copy the Unicode data + into the new object */ + if (find_maxchar_surrogates(u, u + size, + &maxchar, &num_surrogates) == -1) + return NULL; + + unicode = PyUnicode_New(size - num_surrogates, maxchar); + if (!unicode) + return NULL; + + switch (PyUnicode_KIND(unicode)) { + case PyUnicode_1BYTE_KIND: + _PyUnicode_CONVERT_BYTES(Py_UNICODE, unsigned char, + u, u + size, PyUnicode_1BYTE_DATA(unicode)); + break; + case PyUnicode_2BYTE_KIND: +#if Py_UNICODE_SIZE == 2 + memcpy(PyUnicode_2BYTE_DATA(unicode), u, size * 2); +#else + _PyUnicode_CONVERT_BYTES(Py_UNICODE, Py_UCS2, + u, u + size, PyUnicode_2BYTE_DATA(unicode)); +#endif + break; + case PyUnicode_4BYTE_KIND: +#if SIZEOF_WCHAR_T == 2 + /* This is the only case which has to process surrogates, thus + a simple copy loop is not enough and we need a function. */ + unicode_convert_wchar_to_ucs4(u, u + size, unicode); +#else + assert(num_surrogates == 0); + memcpy(PyUnicode_4BYTE_DATA(unicode), u, size * 4); +#endif + break; + default: + Py_UNREACHABLE(); + } + + return unicode_result(unicode); +} + +PyObject * +PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) +{ + if (size < 0) { + PyErr_SetString(PyExc_SystemError, + "Negative size passed to PyUnicode_FromStringAndSize"); + return NULL; + } + if (u != NULL) + return PyUnicode_DecodeUTF8Stateful(u, size, NULL, NULL); + else + return (PyObject *)_PyUnicode_New(size); +} + +PyObject * +PyUnicode_FromString(const char *u) +{ + size_t size = strlen(u); + if (size > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, "input too long"); + return NULL; + } + return PyUnicode_DecodeUTF8Stateful(u, (Py_ssize_t)size, NULL, NULL); +} + +PyObject * +_PyUnicode_FromId(_Py_Identifier *id) +{ + if (!id->object) { + id->object = PyUnicode_DecodeUTF8Stateful(id->string, + strlen(id->string), + NULL, NULL); + if (!id->object) + return NULL; + PyUnicode_InternInPlace(&id->object); + assert(!id->next); + id->next = static_strings; + static_strings = id; + } + return id->object; +} + +void +_PyUnicode_ClearStaticStrings() +{ + _Py_Identifier *tmp, *s = static_strings; + while (s) { + Py_CLEAR(s->object); + tmp = s->next; + s->next = NULL; + s = tmp; + } + static_strings = NULL; +} + +/* Internal function, doesn't check maximum character */ + +PyObject* +_PyUnicode_FromASCII(const char *buffer, Py_ssize_t size) +{ + const unsigned char *s = (const unsigned char *)buffer; + PyObject *unicode; + if (size == 1) { +#ifdef Py_DEBUG + assert((unsigned char)s[0] < 128); +#endif + return get_latin1_char(s[0]); + } + unicode = PyUnicode_New(size, 127); + if (!unicode) + return NULL; + memcpy(PyUnicode_1BYTE_DATA(unicode), s, size); + assert(_PyUnicode_CheckConsistency(unicode, 1)); + return unicode; +} + +static Py_UCS4 +kind_maxchar_limit(unsigned int kind) +{ + switch (kind) { + case PyUnicode_1BYTE_KIND: + return 0x80; + case PyUnicode_2BYTE_KIND: + return 0x100; + case PyUnicode_4BYTE_KIND: + return 0x10000; + default: + Py_UNREACHABLE(); + } +} + +static PyObject* +_PyUnicode_FromUCS1(const Py_UCS1* u, Py_ssize_t size) +{ + PyObject *res; + unsigned char max_char; + + if (size == 0) + _Py_RETURN_UNICODE_EMPTY(); + assert(size > 0); + if (size == 1) + return get_latin1_char(u[0]); + + max_char = ucs1lib_find_max_char(u, u + size); + res = PyUnicode_New(size, max_char); + if (!res) + return NULL; + memcpy(PyUnicode_1BYTE_DATA(res), u, size); + assert(_PyUnicode_CheckConsistency(res, 1)); + return res; +} + +static PyObject* +_PyUnicode_FromUCS2(const Py_UCS2 *u, Py_ssize_t size) +{ + PyObject *res; + Py_UCS2 max_char; + + if (size == 0) + _Py_RETURN_UNICODE_EMPTY(); + assert(size > 0); + if (size == 1) + return unicode_char(u[0]); + + max_char = ucs2lib_find_max_char(u, u + size); + res = PyUnicode_New(size, max_char); + if (!res) + return NULL; + if (max_char >= 256) + memcpy(PyUnicode_2BYTE_DATA(res), u, sizeof(Py_UCS2)*size); + else { + _PyUnicode_CONVERT_BYTES( + Py_UCS2, Py_UCS1, u, u + size, PyUnicode_1BYTE_DATA(res)); + } + assert(_PyUnicode_CheckConsistency(res, 1)); + return res; +} + +static PyObject* +_PyUnicode_FromUCS4(const Py_UCS4 *u, Py_ssize_t size) +{ + PyObject *res; + Py_UCS4 max_char; + + if (size == 0) + _Py_RETURN_UNICODE_EMPTY(); + assert(size > 0); + if (size == 1) + return unicode_char(u[0]); + + max_char = ucs4lib_find_max_char(u, u + size); + res = PyUnicode_New(size, max_char); + if (!res) + return NULL; + if (max_char < 256) + _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS1, u, u + size, + PyUnicode_1BYTE_DATA(res)); + else if (max_char < 0x10000) + _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS2, u, u + size, + PyUnicode_2BYTE_DATA(res)); + else + memcpy(PyUnicode_4BYTE_DATA(res), u, sizeof(Py_UCS4)*size); + assert(_PyUnicode_CheckConsistency(res, 1)); + return res; +} + +PyObject* +PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size) +{ + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "size must be positive"); + return NULL; + } + switch (kind) { + case PyUnicode_1BYTE_KIND: + return _PyUnicode_FromUCS1(buffer, size); + case PyUnicode_2BYTE_KIND: + return _PyUnicode_FromUCS2(buffer, size); + case PyUnicode_4BYTE_KIND: + return _PyUnicode_FromUCS4(buffer, size); + default: + PyErr_SetString(PyExc_SystemError, "invalid kind"); + return NULL; + } +} + +Py_UCS4 +_PyUnicode_FindMaxChar(PyObject *unicode, Py_ssize_t start, Py_ssize_t end) +{ + enum PyUnicode_Kind kind; + void *startptr, *endptr; + + assert(PyUnicode_IS_READY(unicode)); + assert(0 <= start); + assert(end <= PyUnicode_GET_LENGTH(unicode)); + assert(start <= end); + + if (start == 0 && end == PyUnicode_GET_LENGTH(unicode)) + return PyUnicode_MAX_CHAR_VALUE(unicode); + + if (start == end) + return 127; + + if (PyUnicode_IS_ASCII(unicode)) + return 127; + + kind = PyUnicode_KIND(unicode); + startptr = PyUnicode_DATA(unicode); + endptr = (char *)startptr + end * kind; + startptr = (char *)startptr + start * kind; + switch(kind) { + case PyUnicode_1BYTE_KIND: + return ucs1lib_find_max_char(startptr, endptr); + case PyUnicode_2BYTE_KIND: + return ucs2lib_find_max_char(startptr, endptr); + case PyUnicode_4BYTE_KIND: + return ucs4lib_find_max_char(startptr, endptr); + default: + Py_UNREACHABLE(); + } +} + +/* Ensure that a string uses the most efficient storage, if it is not the + case: create a new string with of the right kind. Write NULL into *p_unicode + on error. */ +static void +unicode_adjust_maxchar(PyObject **p_unicode) +{ + PyObject *unicode, *copy; + Py_UCS4 max_char; + Py_ssize_t len; + unsigned int kind; + + assert(p_unicode != NULL); + unicode = *p_unicode; + assert(PyUnicode_IS_READY(unicode)); + if (PyUnicode_IS_ASCII(unicode)) + return; + + len = PyUnicode_GET_LENGTH(unicode); + kind = PyUnicode_KIND(unicode); + if (kind == PyUnicode_1BYTE_KIND) { + const Py_UCS1 *u = PyUnicode_1BYTE_DATA(unicode); + max_char = ucs1lib_find_max_char(u, u + len); + if (max_char >= 128) + return; + } + else if (kind == PyUnicode_2BYTE_KIND) { + const Py_UCS2 *u = PyUnicode_2BYTE_DATA(unicode); + max_char = ucs2lib_find_max_char(u, u + len); + if (max_char >= 256) + return; + } + else { + const Py_UCS4 *u = PyUnicode_4BYTE_DATA(unicode); + assert(kind == PyUnicode_4BYTE_KIND); + max_char = ucs4lib_find_max_char(u, u + len); + if (max_char >= 0x10000) + return; + } + copy = PyUnicode_New(len, max_char); + if (copy != NULL) + _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, len); + Py_DECREF(unicode); + *p_unicode = copy; +} + +PyObject* +_PyUnicode_Copy(PyObject *unicode) +{ + Py_ssize_t length; + PyObject *copy; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadInternalCall(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) + return NULL; + + length = PyUnicode_GET_LENGTH(unicode); + copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); + if (!copy) + return NULL; + assert(PyUnicode_KIND(copy) == PyUnicode_KIND(unicode)); + + memcpy(PyUnicode_DATA(copy), PyUnicode_DATA(unicode), + length * PyUnicode_KIND(unicode)); + assert(_PyUnicode_CheckConsistency(copy, 1)); + return copy; +} + + +/* Widen Unicode objects to larger buffers. Don't write terminating null + character. Return NULL on error. */ + +void* +_PyUnicode_AsKind(PyObject *s, unsigned int kind) +{ + Py_ssize_t len; + void *result; + unsigned int skind; + + if (PyUnicode_READY(s) == -1) + return NULL; + + len = PyUnicode_GET_LENGTH(s); + skind = PyUnicode_KIND(s); + if (skind >= kind) { + PyErr_SetString(PyExc_SystemError, "invalid widening attempt"); + return NULL; + } + switch (kind) { + case PyUnicode_2BYTE_KIND: + result = PyMem_New(Py_UCS2, len); + if (!result) + return PyErr_NoMemory(); + assert(skind == PyUnicode_1BYTE_KIND); + _PyUnicode_CONVERT_BYTES( + Py_UCS1, Py_UCS2, + PyUnicode_1BYTE_DATA(s), + PyUnicode_1BYTE_DATA(s) + len, + result); + return result; + case PyUnicode_4BYTE_KIND: + result = PyMem_New(Py_UCS4, len); + if (!result) + return PyErr_NoMemory(); + if (skind == PyUnicode_2BYTE_KIND) { + _PyUnicode_CONVERT_BYTES( + Py_UCS2, Py_UCS4, + PyUnicode_2BYTE_DATA(s), + PyUnicode_2BYTE_DATA(s) + len, + result); + } + else { + assert(skind == PyUnicode_1BYTE_KIND); + _PyUnicode_CONVERT_BYTES( + Py_UCS1, Py_UCS4, + PyUnicode_1BYTE_DATA(s), + PyUnicode_1BYTE_DATA(s) + len, + result); + } + return result; + default: + break; + } + PyErr_SetString(PyExc_SystemError, "invalid kind"); + return NULL; +} + +static Py_UCS4* +as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, + int copy_null) +{ + int kind; + void *data; + Py_ssize_t len, targetlen; + if (PyUnicode_READY(string) == -1) + return NULL; + kind = PyUnicode_KIND(string); + data = PyUnicode_DATA(string); + len = PyUnicode_GET_LENGTH(string); + targetlen = len; + if (copy_null) + targetlen++; + if (!target) { + target = PyMem_New(Py_UCS4, targetlen); + if (!target) { + PyErr_NoMemory(); + return NULL; + } + } + else { + if (targetsize < targetlen) { + PyErr_Format(PyExc_SystemError, + "string is longer than the buffer"); + if (copy_null && 0 < targetsize) + target[0] = 0; + return NULL; + } + } + if (kind == PyUnicode_1BYTE_KIND) { + Py_UCS1 *start = (Py_UCS1 *) data; + _PyUnicode_CONVERT_BYTES(Py_UCS1, Py_UCS4, start, start + len, target); + } + else if (kind == PyUnicode_2BYTE_KIND) { + Py_UCS2 *start = (Py_UCS2 *) data; + _PyUnicode_CONVERT_BYTES(Py_UCS2, Py_UCS4, start, start + len, target); + } + else { + assert(kind == PyUnicode_4BYTE_KIND); + memcpy(target, data, len * sizeof(Py_UCS4)); + } + if (copy_null) + target[len] = 0; + return target; +} + +Py_UCS4* +PyUnicode_AsUCS4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, + int copy_null) +{ + if (target == NULL || targetsize < 0) { + PyErr_BadInternalCall(); + return NULL; + } + return as_ucs4(string, target, targetsize, copy_null); +} + +Py_UCS4* +PyUnicode_AsUCS4Copy(PyObject *string) +{ + return as_ucs4(string, NULL, 0, 1); +} + +/* maximum number of characters required for output of %lld or %p. + We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, + plus 1 for the sign. 53/22 is an upper bound for log10(256). */ +#define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22) + +static int +unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, + Py_ssize_t width, Py_ssize_t precision) +{ + Py_ssize_t length, fill, arglen; + Py_UCS4 maxchar; + + if (PyUnicode_READY(str) == -1) + return -1; + + length = PyUnicode_GET_LENGTH(str); + if ((precision == -1 || precision >= length) + && width <= length) + return _PyUnicodeWriter_WriteStr(writer, str); + + if (precision != -1) + length = Py_MIN(precision, length); + + arglen = Py_MAX(length, width); + if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) + maxchar = _PyUnicode_FindMaxChar(str, 0, length); + else + maxchar = writer->maxchar; + + if (_PyUnicodeWriter_Prepare(writer, arglen, maxchar) == -1) + return -1; + + if (width > length) { + fill = width - length; + if (PyUnicode_Fill(writer->buffer, writer->pos, fill, ' ') == -1) + return -1; + writer->pos += fill; + } + + _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, + str, 0, length); + writer->pos += length; + return 0; +} + +static int +unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str, + Py_ssize_t width, Py_ssize_t precision) +{ + /* UTF-8 */ + Py_ssize_t length; + PyObject *unicode; + int res; + + if (precision == -1) { + length = strlen(str); + } + else { + length = 0; + while (length < precision && str[length]) { + length++; + } + } + unicode = PyUnicode_DecodeUTF8Stateful(str, length, "replace", NULL); + if (unicode == NULL) + return -1; + + res = unicode_fromformat_write_str(writer, unicode, width, -1); + Py_DECREF(unicode); + return res; +} + +static const char* +unicode_fromformat_arg(_PyUnicodeWriter *writer, + const char *f, va_list *vargs) +{ + const char *p; + Py_ssize_t len; + int zeropad; + Py_ssize_t width; + Py_ssize_t precision; + int longflag; + int longlongflag; + int size_tflag; + Py_ssize_t fill; + + p = f; + f++; + zeropad = 0; + if (*f == '0') { + zeropad = 1; + f++; + } + + /* parse the width.precision part, e.g. "%2.5s" => width=2, precision=5 */ + width = -1; + if (Py_ISDIGIT((unsigned)*f)) { + width = *f - '0'; + f++; + while (Py_ISDIGIT((unsigned)*f)) { + if (width > (PY_SSIZE_T_MAX - ((int)*f - '0')) / 10) { + PyErr_SetString(PyExc_ValueError, + "width too big"); + return NULL; + } + width = (width * 10) + (*f - '0'); + f++; + } + } + precision = -1; + if (*f == '.') { + f++; + if (Py_ISDIGIT((unsigned)*f)) { + precision = (*f - '0'); + f++; + while (Py_ISDIGIT((unsigned)*f)) { + if (precision > (PY_SSIZE_T_MAX - ((int)*f - '0')) / 10) { + PyErr_SetString(PyExc_ValueError, + "precision too big"); + return NULL; + } + precision = (precision * 10) + (*f - '0'); + f++; + } + } + if (*f == '%') { + /* "%.3%s" => f points to "3" */ + f--; + } + } + if (*f == '\0') { + /* bogus format "%.123" => go backward, f points to "3" */ + f--; + } + + /* Handle %ld, %lu, %lld and %llu. */ + longflag = 0; + longlongflag = 0; + size_tflag = 0; + if (*f == 'l') { + if (f[1] == 'd' || f[1] == 'u' || f[1] == 'i') { + longflag = 1; + ++f; + } + else if (f[1] == 'l' && + (f[2] == 'd' || f[2] == 'u' || f[2] == 'i')) { + longlongflag = 1; + f += 2; + } + } + /* handle the size_t flag. */ + else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u' || f[1] == 'i')) { + size_tflag = 1; + ++f; + } + + if (f[1] == '\0') + writer->overallocate = 0; + + switch (*f) { + case 'c': + { + int ordinal = va_arg(*vargs, int); + if (ordinal < 0 || ordinal > MAX_UNICODE) { + PyErr_SetString(PyExc_OverflowError, + "character argument not in range(0x110000)"); + return NULL; + } + if (_PyUnicodeWriter_WriteCharInline(writer, ordinal) < 0) + return NULL; + break; + } + + case 'i': + case 'd': + case 'u': + case 'x': + { + /* used by sprintf */ + char buffer[MAX_LONG_LONG_CHARS]; + Py_ssize_t arglen; + + if (*f == 'u') { + if (longflag) + len = sprintf(buffer, "%lu", + va_arg(*vargs, unsigned long)); + else if (longlongflag) + len = sprintf(buffer, "%llu", + va_arg(*vargs, unsigned long long)); + else if (size_tflag) + len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "u", + va_arg(*vargs, size_t)); + else + len = sprintf(buffer, "%u", + va_arg(*vargs, unsigned int)); + } + else if (*f == 'x') { + len = sprintf(buffer, "%x", va_arg(*vargs, int)); + } + else { + if (longflag) + len = sprintf(buffer, "%li", + va_arg(*vargs, long)); + else if (longlongflag) + len = sprintf(buffer, "%lli", + va_arg(*vargs, long long)); + else if (size_tflag) + len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "i", + va_arg(*vargs, Py_ssize_t)); + else + len = sprintf(buffer, "%i", + va_arg(*vargs, int)); + } + assert(len >= 0); + + if (precision < len) + precision = len; + + arglen = Py_MAX(precision, width); + if (_PyUnicodeWriter_Prepare(writer, arglen, 127) == -1) + return NULL; + + if (width > precision) { + Py_UCS4 fillchar; + fill = width - precision; + fillchar = zeropad?'0':' '; + if (PyUnicode_Fill(writer->buffer, writer->pos, fill, fillchar) == -1) + return NULL; + writer->pos += fill; + } + if (precision > len) { + fill = precision - len; + if (PyUnicode_Fill(writer->buffer, writer->pos, fill, '0') == -1) + return NULL; + writer->pos += fill; + } + + if (_PyUnicodeWriter_WriteASCIIString(writer, buffer, len) < 0) + return NULL; + break; + } + + case 'p': + { + char number[MAX_LONG_LONG_CHARS]; + + len = sprintf(number, "%p", va_arg(*vargs, void*)); + assert(len >= 0); + + /* %p is ill-defined: ensure leading 0x. */ + if (number[1] == 'X') + number[1] = 'x'; + else if (number[1] != 'x') { + memmove(number + 2, number, + strlen(number) + 1); + number[0] = '0'; + number[1] = 'x'; + len += 2; + } + + if (_PyUnicodeWriter_WriteASCIIString(writer, number, len) < 0) + return NULL; + break; + } + + case 's': + { + /* UTF-8 */ + const char *s = va_arg(*vargs, const char*); + if (unicode_fromformat_write_cstr(writer, s, width, precision) < 0) + return NULL; + break; + } + + case 'U': + { + PyObject *obj = va_arg(*vargs, PyObject *); + assert(obj && _PyUnicode_CHECK(obj)); + + if (unicode_fromformat_write_str(writer, obj, width, precision) == -1) + return NULL; + break; + } + + case 'V': + { + PyObject *obj = va_arg(*vargs, PyObject *); + const char *str = va_arg(*vargs, const char *); + if (obj) { + assert(_PyUnicode_CHECK(obj)); + if (unicode_fromformat_write_str(writer, obj, width, precision) == -1) + return NULL; + } + else { + assert(str != NULL); + if (unicode_fromformat_write_cstr(writer, str, width, precision) < 0) + return NULL; + } + break; + } + + case 'S': + { + PyObject *obj = va_arg(*vargs, PyObject *); + PyObject *str; + assert(obj); + str = PyObject_Str(obj); + if (!str) + return NULL; + if (unicode_fromformat_write_str(writer, str, width, precision) == -1) { + Py_DECREF(str); + return NULL; + } + Py_DECREF(str); + break; + } + + case 'R': + { + PyObject *obj = va_arg(*vargs, PyObject *); + PyObject *repr; + assert(obj); + repr = PyObject_Repr(obj); + if (!repr) + return NULL; + if (unicode_fromformat_write_str(writer, repr, width, precision) == -1) { + Py_DECREF(repr); + return NULL; + } + Py_DECREF(repr); + break; + } + + case 'A': + { + PyObject *obj = va_arg(*vargs, PyObject *); + PyObject *ascii; + assert(obj); + ascii = PyObject_ASCII(obj); + if (!ascii) + return NULL; + if (unicode_fromformat_write_str(writer, ascii, width, precision) == -1) { + Py_DECREF(ascii); + return NULL; + } + Py_DECREF(ascii); + break; + } + + case '%': + if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) + return NULL; + break; + + default: + /* if we stumble upon an unknown formatting code, copy the rest + of the format string to the output string. (we cannot just + skip the code, since there's no way to know what's in the + argument list) */ + len = strlen(p); + if (_PyUnicodeWriter_WriteLatin1String(writer, p, len) == -1) + return NULL; + f = p+len; + return f; + } + + f++; + return f; +} + +PyObject * +PyUnicode_FromFormatV(const char *format, va_list vargs) +{ + va_list vargs2; + const char *f; + _PyUnicodeWriter writer; + + _PyUnicodeWriter_Init(&writer); + writer.min_length = strlen(format) + 100; + writer.overallocate = 1; + + // Copy varags to be able to pass a reference to a subfunction. + va_copy(vargs2, vargs); + + for (f = format; *f; ) { + if (*f == '%') { + f = unicode_fromformat_arg(&writer, f, &vargs2); + if (f == NULL) + goto fail; + } + else { + const char *p; + Py_ssize_t len; + + p = f; + do + { + if ((unsigned char)*p > 127) { + PyErr_Format(PyExc_ValueError, + "PyUnicode_FromFormatV() expects an ASCII-encoded format " + "string, got a non-ASCII byte: 0x%02x", + (unsigned char)*p); + goto fail; + } + p++; + } + while (*p != '\0' && *p != '%'); + len = p - f; + + if (*p == '\0') + writer.overallocate = 0; + + if (_PyUnicodeWriter_WriteASCIIString(&writer, f, len) < 0) + goto fail; + + f = p; + } + } + va_end(vargs2); + return _PyUnicodeWriter_Finish(&writer); + + fail: + va_end(vargs2); + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + +PyObject * +PyUnicode_FromFormat(const char *format, ...) +{ + PyObject* ret; + va_list vargs; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + ret = PyUnicode_FromFormatV(format, vargs); + va_end(vargs); + return ret; +} + +static Py_ssize_t +unicode_get_widechar_size(PyObject *unicode) +{ + Py_ssize_t res; + + assert(unicode != NULL); + assert(_PyUnicode_CHECK(unicode)); + + if (_PyUnicode_WSTR(unicode) != NULL) { + return PyUnicode_WSTR_LENGTH(unicode); + } + assert(PyUnicode_IS_READY(unicode)); + + res = _PyUnicode_LENGTH(unicode); +#if SIZEOF_WCHAR_T == 2 + if (PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND) { + const Py_UCS4 *s = PyUnicode_4BYTE_DATA(unicode); + const Py_UCS4 *end = s + res; + for (; s < end; ++s) { + if (*s > 0xFFFF) { + ++res; + } + } + } +#endif + return res; +} + +static void +unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size) +{ + const wchar_t *wstr; + + assert(unicode != NULL); + assert(_PyUnicode_CHECK(unicode)); + + wstr = _PyUnicode_WSTR(unicode); + if (wstr != NULL) { + memcpy(w, wstr, size * sizeof(wchar_t)); + return; + } + assert(PyUnicode_IS_READY(unicode)); + + if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) { + const Py_UCS1 *s = PyUnicode_1BYTE_DATA(unicode); + for (; size--; ++s, ++w) { + *w = *s; + } + } + else { +#if SIZEOF_WCHAR_T == 4 + assert(PyUnicode_KIND(unicode) == PyUnicode_2BYTE_KIND); + const Py_UCS2 *s = PyUnicode_2BYTE_DATA(unicode); + for (; size--; ++s, ++w) { + *w = *s; + } +#else + assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND); + const Py_UCS4 *s = PyUnicode_4BYTE_DATA(unicode); + for (; size--; ++s, ++w) { + Py_UCS4 ch = *s; + if (ch > 0xFFFF) { + assert(ch <= MAX_UNICODE); + /* encode surrogate pair in this case */ + *w++ = Py_UNICODE_HIGH_SURROGATE(ch); + if (!size--) + break; + *w = Py_UNICODE_LOW_SURROGATE(ch); + } + else { + *w = ch; + } + } +#endif + } +} + +#ifdef HAVE_WCHAR_H + +/* Convert a Unicode object to a wide character string. + + - If w is NULL: return the number of wide characters (including the null + character) required to convert the unicode object. Ignore size argument. + + - Otherwise: return the number of wide characters (excluding the null + character) written into w. Write at most size wide characters (including + the null character). */ +Py_ssize_t +PyUnicode_AsWideChar(PyObject *unicode, + wchar_t *w, + Py_ssize_t size) +{ + Py_ssize_t res; + + if (unicode == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return -1; + } + + res = unicode_get_widechar_size(unicode); + if (w == NULL) { + return res + 1; + } + + if (size > res) { + size = res + 1; + } + else { + res = size; + } + unicode_copy_as_widechar(unicode, w, size); + return res; +} + +wchar_t* +PyUnicode_AsWideCharString(PyObject *unicode, + Py_ssize_t *size) +{ + wchar_t *buffer; + Py_ssize_t buflen; + + if (unicode == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + + buflen = unicode_get_widechar_size(unicode); + buffer = (wchar_t *) PyMem_NEW(wchar_t, (buflen + 1)); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + unicode_copy_as_widechar(unicode, buffer, buflen + 1); + if (size != NULL) { + *size = buflen; + } + else if (wcslen(buffer) != (size_t)buflen) { + PyMem_FREE(buffer); + PyErr_SetString(PyExc_ValueError, + "embedded null character"); + return NULL; + } + return buffer; +} + +#endif /* HAVE_WCHAR_H */ + +PyObject * +PyUnicode_FromOrdinal(int ordinal) +{ + if (ordinal < 0 || ordinal > MAX_UNICODE) { + PyErr_SetString(PyExc_ValueError, + "chr() arg not in range(0x110000)"); + return NULL; + } + + return unicode_char((Py_UCS4)ordinal); +} + +PyObject * +PyUnicode_FromObject(PyObject *obj) +{ + /* XXX Perhaps we should make this API an alias of + PyObject_Str() instead ?! */ + if (PyUnicode_CheckExact(obj)) { + if (PyUnicode_READY(obj) == -1) + return NULL; + Py_INCREF(obj); + return obj; + } + if (PyUnicode_Check(obj)) { + /* For a Unicode subtype that's not a Unicode object, + return a true Unicode object with the same data. */ + return _PyUnicode_Copy(obj); + } + PyErr_Format(PyExc_TypeError, + "Can't convert '%.100s' object to str implicitly", + Py_TYPE(obj)->tp_name); + return NULL; +} + +PyObject * +PyUnicode_FromEncodedObject(PyObject *obj, + const char *encoding, + const char *errors) +{ + Py_buffer buffer; + PyObject *v; + + if (obj == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + /* Decoding bytes objects is the most common case and should be fast */ + if (PyBytes_Check(obj)) { + if (PyBytes_GET_SIZE(obj) == 0) + _Py_RETURN_UNICODE_EMPTY(); + v = PyUnicode_Decode( + PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj), + encoding, errors); + return v; + } + + if (PyUnicode_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "decoding str is not supported"); + return NULL; + } + + /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */ + if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) { + PyErr_Format(PyExc_TypeError, + "decoding to str: need a bytes-like object, %.80s found", + Py_TYPE(obj)->tp_name); + return NULL; + } + + if (buffer.len == 0) { + PyBuffer_Release(&buffer); + _Py_RETURN_UNICODE_EMPTY(); + } + + v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors); + PyBuffer_Release(&buffer); + return v; +} + +/* Normalize an encoding name: similar to encodings.normalize_encoding(), but + also convert to lowercase. Return 1 on success, or 0 on error (encoding is + longer than lower_len-1). */ +int +_Py_normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) +{ + const char *e; + char *l; + char *l_end; + int punct; + + assert(encoding != NULL); + + e = encoding; + l = lower; + l_end = &lower[lower_len - 1]; + punct = 0; + while (1) { + char c = *e; + if (c == 0) { + break; + } + + if (Py_ISALNUM(c) || c == '.') { + if (punct && l != lower) { + if (l == l_end) { + return 0; + } + *l++ = '_'; + } + punct = 0; + + if (l == l_end) { + return 0; + } + *l++ = Py_TOLOWER(c); + } + else { + punct = 1; + } + + e++; + } + *l = '\0'; + return 1; +} + +PyObject * +PyUnicode_Decode(const char *s, + Py_ssize_t size, + const char *encoding, + const char *errors) +{ + PyObject *buffer = NULL, *unicode; + Py_buffer info; + char buflower[11]; /* strlen("iso-8859-1\0") == 11, longest shortcut */ + + if (encoding == NULL) { + return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL); + } + + /* Shortcuts for common default encodings */ + if (_Py_normalize_encoding(encoding, buflower, sizeof(buflower))) { + char *lower = buflower; + + /* Fast paths */ + if (lower[0] == 'u' && lower[1] == 't' && lower[2] == 'f') { + lower += 3; + if (*lower == '_') { + /* Match "utf8" and "utf_8" */ + lower++; + } + + if (lower[0] == '8' && lower[1] == 0) { + return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL); + } + else if (lower[0] == '1' && lower[1] == '6' && lower[2] == 0) { + return PyUnicode_DecodeUTF16(s, size, errors, 0); + } + else if (lower[0] == '3' && lower[1] == '2' && lower[2] == 0) { + return PyUnicode_DecodeUTF32(s, size, errors, 0); + } + } + else { + if (strcmp(lower, "ascii") == 0 + || strcmp(lower, "us_ascii") == 0) { + return PyUnicode_DecodeASCII(s, size, errors); + } + #ifdef MS_WINDOWS + else if (strcmp(lower, "mbcs") == 0) { + return PyUnicode_DecodeMBCS(s, size, errors); + } + #endif + else if (strcmp(lower, "latin1") == 0 + || strcmp(lower, "latin_1") == 0 + || strcmp(lower, "iso_8859_1") == 0 + || strcmp(lower, "iso8859_1") == 0) { + return PyUnicode_DecodeLatin1(s, size, errors); + } + } + } + + /* Decode via the codec registry */ + buffer = NULL; + if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_FULL_RO) < 0) + goto onError; + buffer = PyMemoryView_FromBuffer(&info); + if (buffer == NULL) + goto onError; + unicode = _PyCodec_DecodeText(buffer, encoding, errors); + if (unicode == NULL) + goto onError; + if (!PyUnicode_Check(unicode)) { + PyErr_Format(PyExc_TypeError, + "'%.400s' decoder returned '%.400s' instead of 'str'; " + "use codecs.decode() to decode to arbitrary types", + encoding, + Py_TYPE(unicode)->tp_name); + Py_DECREF(unicode); + goto onError; + } + Py_DECREF(buffer); + return unicode_result(unicode); + + onError: + Py_XDECREF(buffer); + return NULL; +} + +PyObject * +PyUnicode_AsDecodedObject(PyObject *unicode, + const char *encoding, + const char *errors) +{ + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyUnicode_AsDecodedObject() is deprecated; " + "use PyCodec_Decode() to decode from str", 1) < 0) + return NULL; + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + + /* Decode via the codec registry */ + return PyCodec_Decode(unicode, encoding, errors); +} + +PyObject * +PyUnicode_AsDecodedUnicode(PyObject *unicode, + const char *encoding, + const char *errors) +{ + PyObject *v; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + goto onError; + } + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyUnicode_AsDecodedUnicode() is deprecated; " + "use PyCodec_Decode() to decode from str to str", 1) < 0) + return NULL; + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + + /* Decode via the codec registry */ + v = PyCodec_Decode(unicode, encoding, errors); + if (v == NULL) + goto onError; + if (!PyUnicode_Check(v)) { + PyErr_Format(PyExc_TypeError, + "'%.400s' decoder returned '%.400s' instead of 'str'; " + "use codecs.decode() to decode to arbitrary types", + encoding, + Py_TYPE(unicode)->tp_name); + Py_DECREF(v); + goto onError; + } + return unicode_result(v); + + onError: + return NULL; +} + +PyObject * +PyUnicode_Encode(const Py_UNICODE *s, + Py_ssize_t size, + const char *encoding, + const char *errors) +{ + PyObject *v, *unicode; + + unicode = PyUnicode_FromWideChar(s, size); + if (unicode == NULL) + return NULL; + v = PyUnicode_AsEncodedString(unicode, encoding, errors); + Py_DECREF(unicode); + return v; +} + +PyObject * +PyUnicode_AsEncodedObject(PyObject *unicode, + const char *encoding, + const char *errors) +{ + PyObject *v; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + goto onError; + } + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyUnicode_AsEncodedObject() is deprecated; " + "use PyUnicode_AsEncodedString() to encode from str to bytes " + "or PyCodec_Encode() for generic encoding", 1) < 0) + return NULL; + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + + /* Encode via the codec registry */ + v = PyCodec_Encode(unicode, encoding, errors); + if (v == NULL) + goto onError; + return v; + + onError: + return NULL; +} + + +static PyObject * +unicode_encode_locale(PyObject *unicode, _Py_error_handler error_handler, + int current_locale) +{ + Py_ssize_t wlen; + wchar_t *wstr = PyUnicode_AsWideCharString(unicode, &wlen); + if (wstr == NULL) { + return NULL; + } + + if ((size_t)wlen != wcslen(wstr)) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + PyMem_Free(wstr); + return NULL; + } + + char *str; + size_t error_pos; + const char *reason; + int res = _Py_EncodeLocaleEx(wstr, &str, &error_pos, &reason, + current_locale, error_handler); + PyMem_Free(wstr); + + if (res != 0) { + if (res == -2) { + PyObject *exc; + exc = PyObject_CallFunction(PyExc_UnicodeEncodeError, "sOnns", + "locale", unicode, + (Py_ssize_t)error_pos, + (Py_ssize_t)(error_pos+1), + reason); + if (exc != NULL) { + PyCodec_StrictErrors(exc); + Py_DECREF(exc); + } + } + else if (res == -3) { + PyErr_SetString(PyExc_ValueError, "unsupported error handler"); + } + else { + PyErr_NoMemory(); + } + return NULL; + } + + PyObject *bytes = PyBytes_FromString(str); + PyMem_RawFree(str); + return bytes; +} + +PyObject * +PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) +{ + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + return unicode_encode_locale(unicode, error_handler, 1); +} + +PyObject * +PyUnicode_EncodeFSDefault(PyObject *unicode) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); +#ifdef _Py_FORCE_UTF8_FS_ENCODING + if (interp->fs_codec.encoding) { + return unicode_encode_utf8(unicode, + interp->fs_codec.error_handler, + interp->fs_codec.errors); + } + else { + const wchar_t *filesystem_errors = interp->config.filesystem_errors; + _Py_error_handler errors; + errors = get_error_handler_wide(filesystem_errors); + assert(errors != _Py_ERROR_UNKNOWN); + return unicode_encode_utf8(unicode, errors, NULL); + } +#else + /* Bootstrap check: if the filesystem codec is implemented in Python, we + cannot use it to encode and decode filenames before it is loaded. Load + the Python codec requires to encode at least its own filename. Use the C + implementation of the locale codec until the codec registry is + initialized and the Python codec is loaded. See initfsencoding(). */ + if (interp->fs_codec.encoding) { + return PyUnicode_AsEncodedString(unicode, + interp->fs_codec.encoding, + interp->fs_codec.errors); + } + else { + const wchar_t *filesystem_errors = interp->config.filesystem_errors; + _Py_error_handler errors; + errors = get_error_handler_wide(filesystem_errors); + assert(errors != _Py_ERROR_UNKNOWN); + return unicode_encode_locale(unicode, errors, 0); + } +#endif +} + +PyObject * +PyUnicode_AsEncodedString(PyObject *unicode, + const char *encoding, + const char *errors) +{ + PyObject *v; + char buflower[11]; /* strlen("iso_8859_1\0") == 11, longest shortcut */ + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + + if (encoding == NULL) { + return _PyUnicode_AsUTF8String(unicode, errors); + } + + /* Shortcuts for common default encodings */ + if (_Py_normalize_encoding(encoding, buflower, sizeof(buflower))) { + char *lower = buflower; + + /* Fast paths */ + if (lower[0] == 'u' && lower[1] == 't' && lower[2] == 'f') { + lower += 3; + if (*lower == '_') { + /* Match "utf8" and "utf_8" */ + lower++; + } + + if (lower[0] == '8' && lower[1] == 0) { + return _PyUnicode_AsUTF8String(unicode, errors); + } + else if (lower[0] == '1' && lower[1] == '6' && lower[2] == 0) { + return _PyUnicode_EncodeUTF16(unicode, errors, 0); + } + else if (lower[0] == '3' && lower[1] == '2' && lower[2] == 0) { + return _PyUnicode_EncodeUTF32(unicode, errors, 0); + } + } + else { + if (strcmp(lower, "ascii") == 0 + || strcmp(lower, "us_ascii") == 0) { + return _PyUnicode_AsASCIIString(unicode, errors); + } +#ifdef MS_WINDOWS + else if (strcmp(lower, "mbcs") == 0) { + return PyUnicode_EncodeCodePage(CP_ACP, unicode, errors); + } +#endif + else if (strcmp(lower, "latin1") == 0 || + strcmp(lower, "latin_1") == 0 || + strcmp(lower, "iso_8859_1") == 0 || + strcmp(lower, "iso8859_1") == 0) { + return _PyUnicode_AsLatin1String(unicode, errors); + } + } + } + + /* Encode via the codec registry */ + v = _PyCodec_EncodeText(unicode, encoding, errors); + if (v == NULL) + return NULL; + + /* The normal path */ + if (PyBytes_Check(v)) + return v; + + /* If the codec returns a buffer, raise a warning and convert to bytes */ + if (PyByteArray_Check(v)) { + int error; + PyObject *b; + + error = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "encoder %s returned bytearray instead of bytes; " + "use codecs.encode() to encode to arbitrary types", + encoding); + if (error) { + Py_DECREF(v); + return NULL; + } + + b = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), + PyByteArray_GET_SIZE(v)); + Py_DECREF(v); + return b; + } + + PyErr_Format(PyExc_TypeError, + "'%.400s' encoder returned '%.400s' instead of 'bytes'; " + "use codecs.encode() to encode to arbitrary types", + encoding, + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; +} + +PyObject * +PyUnicode_AsEncodedUnicode(PyObject *unicode, + const char *encoding, + const char *errors) +{ + PyObject *v; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + goto onError; + } + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyUnicode_AsEncodedUnicode() is deprecated; " + "use PyCodec_Encode() to encode from str to str", 1) < 0) + return NULL; + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + + /* Encode via the codec registry */ + v = PyCodec_Encode(unicode, encoding, errors); + if (v == NULL) + goto onError; + if (!PyUnicode_Check(v)) { + PyErr_Format(PyExc_TypeError, + "'%.400s' encoder returned '%.400s' instead of 'str'; " + "use codecs.encode() to encode to arbitrary types", + encoding, + Py_TYPE(v)->tp_name); + Py_DECREF(v); + goto onError; + } + return v; + + onError: + return NULL; +} + +static PyObject* +unicode_decode_locale(const char *str, Py_ssize_t len, + _Py_error_handler errors, int current_locale) +{ + if (str[len] != '\0' || (size_t)len != strlen(str)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); + return NULL; + } + + wchar_t *wstr; + size_t wlen; + const char *reason; + int res = _Py_DecodeLocaleEx(str, &wstr, &wlen, &reason, + current_locale, errors); + if (res != 0) { + if (res == -2) { + PyObject *exc; + exc = PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", + "locale", str, len, + (Py_ssize_t)wlen, + (Py_ssize_t)(wlen + 1), + reason); + if (exc != NULL) { + PyCodec_StrictErrors(exc); + Py_DECREF(exc); + } + } + else if (res == -3) { + PyErr_SetString(PyExc_ValueError, "unsupported error handler"); + } + else { + PyErr_NoMemory(); + } + return NULL; + } + + PyObject *unicode = PyUnicode_FromWideChar(wstr, wlen); + PyMem_RawFree(wstr); + return unicode; +} + +PyObject* +PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, + const char *errors) +{ + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + return unicode_decode_locale(str, len, error_handler, 1); +} + +PyObject* +PyUnicode_DecodeLocale(const char *str, const char *errors) +{ + Py_ssize_t size = (Py_ssize_t)strlen(str); + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + return unicode_decode_locale(str, size, error_handler, 1); +} + + +PyObject* +PyUnicode_DecodeFSDefault(const char *s) { + Py_ssize_t size = (Py_ssize_t)strlen(s); + return PyUnicode_DecodeFSDefaultAndSize(s, size); +} + +PyObject* +PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); +#ifdef _Py_FORCE_UTF8_FS_ENCODING + if (interp->fs_codec.encoding) { + return unicode_decode_utf8(s, size, + interp->fs_codec.error_handler, + interp->fs_codec.errors, + NULL); + } + else { + const wchar_t *filesystem_errors = interp->config.filesystem_errors; + _Py_error_handler errors; + errors = get_error_handler_wide(filesystem_errors); + assert(errors != _Py_ERROR_UNKNOWN); + return unicode_decode_utf8(s, size, errors, NULL, NULL); + } +#else + /* Bootstrap check: if the filesystem codec is implemented in Python, we + cannot use it to encode and decode filenames before it is loaded. Load + the Python codec requires to encode at least its own filename. Use the C + implementation of the locale codec until the codec registry is + initialized and the Python codec is loaded. See initfsencoding(). */ + if (interp->fs_codec.encoding) { + return PyUnicode_Decode(s, size, + interp->fs_codec.encoding, + interp->fs_codec.errors); + } + else { + const wchar_t *filesystem_errors = interp->config.filesystem_errors; + _Py_error_handler errors; + errors = get_error_handler_wide(filesystem_errors); + return unicode_decode_locale(s, size, errors, 0); + } +#endif +} + + +int +PyUnicode_FSConverter(PyObject* arg, void* addr) +{ + PyObject *path = NULL; + PyObject *output = NULL; + Py_ssize_t size; + void *data; + if (arg == NULL) { + Py_DECREF(*(PyObject**)addr); + *(PyObject**)addr = NULL; + return 1; + } + path = PyOS_FSPath(arg); + if (path == NULL) { + return 0; + } + if (PyBytes_Check(path)) { + output = path; + } + else { // PyOS_FSPath() guarantees its returned value is bytes or str. + output = PyUnicode_EncodeFSDefault(path); + Py_DECREF(path); + if (!output) { + return 0; + } + assert(PyBytes_Check(output)); + } + + size = PyBytes_GET_SIZE(output); + data = PyBytes_AS_STRING(output); + if ((size_t)size != strlen(data)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); + Py_DECREF(output); + return 0; + } + *(PyObject**)addr = output; + return Py_CLEANUP_SUPPORTED; +} + + +int +PyUnicode_FSDecoder(PyObject* arg, void* addr) +{ + int is_buffer = 0; + PyObject *path = NULL; + PyObject *output = NULL; + if (arg == NULL) { + Py_DECREF(*(PyObject**)addr); + *(PyObject**)addr = NULL; + return 1; + } + + is_buffer = PyObject_CheckBuffer(arg); + if (!is_buffer) { + path = PyOS_FSPath(arg); + if (path == NULL) { + return 0; + } + } + else { + path = arg; + Py_INCREF(arg); + } + + if (PyUnicode_Check(path)) { + output = path; + } + else if (PyBytes_Check(path) || is_buffer) { + PyObject *path_bytes = NULL; + + if (!PyBytes_Check(path) && + PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "path should be string, bytes, or os.PathLike, not %.200s", + Py_TYPE(arg)->tp_name)) { + Py_DECREF(path); + return 0; + } + path_bytes = PyBytes_FromObject(path); + Py_DECREF(path); + if (!path_bytes) { + return 0; + } + output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path_bytes), + PyBytes_GET_SIZE(path_bytes)); + Py_DECREF(path_bytes); + if (!output) { + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "path should be string, bytes, or os.PathLike, not %.200s", + Py_TYPE(arg)->tp_name); + Py_DECREF(path); + return 0; + } + if (PyUnicode_READY(output) == -1) { + Py_DECREF(output); + return 0; + } + if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output), + PyUnicode_GET_LENGTH(output), 0, 1) >= 0) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + Py_DECREF(output); + return 0; + } + *(PyObject**)addr = output; + return Py_CLEANUP_SUPPORTED; +} + + +const char * +PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize) +{ + PyObject *bytes; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) + return NULL; + + if (PyUnicode_UTF8(unicode) == NULL) { + assert(!PyUnicode_IS_COMPACT_ASCII(unicode)); + bytes = _PyUnicode_AsUTF8String(unicode, NULL); + if (bytes == NULL) + return NULL; + _PyUnicode_UTF8(unicode) = PyObject_MALLOC(PyBytes_GET_SIZE(bytes) + 1); + if (_PyUnicode_UTF8(unicode) == NULL) { + PyErr_NoMemory(); + Py_DECREF(bytes); + return NULL; + } + _PyUnicode_UTF8_LENGTH(unicode) = PyBytes_GET_SIZE(bytes); + memcpy(_PyUnicode_UTF8(unicode), + PyBytes_AS_STRING(bytes), + _PyUnicode_UTF8_LENGTH(unicode) + 1); + Py_DECREF(bytes); + } + + if (psize) + *psize = PyUnicode_UTF8_LENGTH(unicode); + return PyUnicode_UTF8(unicode); +} + +const char * +PyUnicode_AsUTF8(PyObject *unicode) +{ + return PyUnicode_AsUTF8AndSize(unicode, NULL); +} + +Py_UNICODE * +PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) +{ + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + Py_UNICODE *w = _PyUnicode_WSTR(unicode); + if (w == NULL) { + /* Non-ASCII compact unicode object */ + assert(_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND); + assert(PyUnicode_IS_READY(unicode)); + + Py_ssize_t wlen = unicode_get_widechar_size(unicode); + if ((size_t)wlen > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { + PyErr_NoMemory(); + return NULL; + } + w = (wchar_t *) PyObject_MALLOC(sizeof(wchar_t) * (wlen + 1)); + if (w == NULL) { + PyErr_NoMemory(); + return NULL; + } + unicode_copy_as_widechar(unicode, w, wlen + 1); + _PyUnicode_WSTR(unicode) = w; + if (!PyUnicode_IS_COMPACT_ASCII(unicode)) { + _PyUnicode_WSTR_LENGTH(unicode) = wlen; + } + } + if (size != NULL) + *size = PyUnicode_WSTR_LENGTH(unicode); + return w; +} + +Py_UNICODE * +PyUnicode_AsUnicode(PyObject *unicode) +{ + return PyUnicode_AsUnicodeAndSize(unicode, NULL); +} + +const Py_UNICODE * +_PyUnicode_AsUnicode(PyObject *unicode) +{ + Py_ssize_t size; + const Py_UNICODE *wstr; + + wstr = PyUnicode_AsUnicodeAndSize(unicode, &size); + if (wstr && wcslen(wstr) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + return NULL; + } + return wstr; +} + + +Py_ssize_t +PyUnicode_GetSize(PyObject *unicode) +{ + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + goto onError; + } + if (_PyUnicode_WSTR(unicode) == NULL) { + if (PyUnicode_AsUnicode(unicode) == NULL) + goto onError; + } + return PyUnicode_WSTR_LENGTH(unicode); + + onError: + return -1; +} + +Py_ssize_t +PyUnicode_GetLength(PyObject *unicode) +{ + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return -1; + } + if (PyUnicode_READY(unicode) == -1) + return -1; + return PyUnicode_GET_LENGTH(unicode); +} + +Py_UCS4 +PyUnicode_ReadChar(PyObject *unicode, Py_ssize_t index) +{ + void *data; + int kind; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return (Py_UCS4)-1; + } + if (PyUnicode_READY(unicode) == -1) { + return (Py_UCS4)-1; + } + if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { + PyErr_SetString(PyExc_IndexError, "string index out of range"); + return (Py_UCS4)-1; + } + data = PyUnicode_DATA(unicode); + kind = PyUnicode_KIND(unicode); + return PyUnicode_READ(kind, data, index); +} + +int +PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, Py_UCS4 ch) +{ + if (!PyUnicode_Check(unicode) || !PyUnicode_IS_COMPACT(unicode)) { + PyErr_BadArgument(); + return -1; + } + assert(PyUnicode_IS_READY(unicode)); + if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { + PyErr_SetString(PyExc_IndexError, "string index out of range"); + return -1; + } + if (unicode_check_modifiable(unicode)) + return -1; + if (ch > PyUnicode_MAX_CHAR_VALUE(unicode)) { + PyErr_SetString(PyExc_ValueError, "character out of range"); + return -1; + } + PyUnicode_WRITE(PyUnicode_KIND(unicode), PyUnicode_DATA(unicode), + index, ch); + return 0; +} + +const char * +PyUnicode_GetDefaultEncoding(void) +{ + return "utf-8"; +} + +/* create or adjust a UnicodeDecodeError */ +static void +make_decode_exception(PyObject **exceptionObject, + const char *encoding, + const char *input, Py_ssize_t length, + Py_ssize_t startpos, Py_ssize_t endpos, + const char *reason) +{ + if (*exceptionObject == NULL) { + *exceptionObject = PyUnicodeDecodeError_Create( + encoding, input, length, startpos, endpos, reason); + } + else { + if (PyUnicodeDecodeError_SetStart(*exceptionObject, startpos)) + goto onError; + if (PyUnicodeDecodeError_SetEnd(*exceptionObject, endpos)) + goto onError; + if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason)) + goto onError; + } + return; + +onError: + Py_CLEAR(*exceptionObject); +} + +#ifdef MS_WINDOWS +static int +widechar_resize(wchar_t **buf, Py_ssize_t *size, Py_ssize_t newsize) +{ + if (newsize > *size) { + wchar_t *newbuf = *buf; + if (PyMem_Resize(newbuf, wchar_t, newsize) == NULL) { + PyErr_NoMemory(); + return -1; + } + *buf = newbuf; + } + *size = newsize; + return 0; +} + +/* error handling callback helper: + build arguments, call the callback and check the arguments, + if no exception occurred, copy the replacement to the output + and adjust various state variables. + return 0 on success, -1 on error +*/ + +static int +unicode_decode_call_errorhandler_wchar( + const char *errors, PyObject **errorHandler, + const char *encoding, const char *reason, + const char **input, const char **inend, Py_ssize_t *startinpos, + Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr, + wchar_t **buf, Py_ssize_t *bufsize, Py_ssize_t *outpos) +{ + static const char *argparse = "Un;decoding error handler must return (str, int) tuple"; + + PyObject *restuple = NULL; + PyObject *repunicode = NULL; + Py_ssize_t outsize; + Py_ssize_t insize; + Py_ssize_t requiredsize; + Py_ssize_t newpos; + PyObject *inputobj = NULL; + wchar_t *repwstr; + Py_ssize_t repwlen; + + if (*errorHandler == NULL) { + *errorHandler = PyCodec_LookupError(errors); + if (*errorHandler == NULL) + goto onError; + } + + make_decode_exception(exceptionObject, + encoding, + *input, *inend - *input, + *startinpos, *endinpos, + reason); + if (*exceptionObject == NULL) + goto onError; + + restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL); + if (restuple == NULL) + goto onError; + if (!PyTuple_Check(restuple)) { + PyErr_SetString(PyExc_TypeError, &argparse[3]); + goto onError; + } + if (!PyArg_ParseTuple(restuple, argparse, &repunicode, &newpos)) + goto onError; + + /* Copy back the bytes variables, which might have been modified by the + callback */ + inputobj = PyUnicodeDecodeError_GetObject(*exceptionObject); + if (!inputobj) + goto onError; + *input = PyBytes_AS_STRING(inputobj); + insize = PyBytes_GET_SIZE(inputobj); + *inend = *input + insize; + /* we can DECREF safely, as the exception has another reference, + so the object won't go away. */ + Py_DECREF(inputobj); + + if (newpos<0) + newpos = insize+newpos; + if (newpos<0 || newpos>insize) { + PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", newpos); + goto onError; + } + + repwstr = PyUnicode_AsUnicodeAndSize(repunicode, &repwlen); + if (repwstr == NULL) + goto onError; + /* need more space? (at least enough for what we + have+the replacement+the rest of the string (starting + at the new input position), so we won't have to check space + when there are no errors in the rest of the string) */ + requiredsize = *outpos; + if (requiredsize > PY_SSIZE_T_MAX - repwlen) + goto overflow; + requiredsize += repwlen; + if (requiredsize > PY_SSIZE_T_MAX - (insize - newpos)) + goto overflow; + requiredsize += insize - newpos; + outsize = *bufsize; + if (requiredsize > outsize) { + if (outsize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*outsize) + requiredsize = 2*outsize; + if (widechar_resize(buf, bufsize, requiredsize) < 0) { + goto onError; + } + } + wcsncpy(*buf + *outpos, repwstr, repwlen); + *outpos += repwlen; + *endinpos = newpos; + *inptr = *input + newpos; + + /* we made it! */ + Py_DECREF(restuple); + return 0; + + overflow: + PyErr_SetString(PyExc_OverflowError, + "decoded result is too long for a Python string"); + + onError: + Py_XDECREF(restuple); + return -1; +} +#endif /* MS_WINDOWS */ + +static int +unicode_decode_call_errorhandler_writer( + const char *errors, PyObject **errorHandler, + const char *encoding, const char *reason, + const char **input, const char **inend, Py_ssize_t *startinpos, + Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr, + _PyUnicodeWriter *writer /* PyObject **output, Py_ssize_t *outpos */) +{ + static const char *argparse = "Un;decoding error handler must return (str, int) tuple"; + + PyObject *restuple = NULL; + PyObject *repunicode = NULL; + Py_ssize_t insize; + Py_ssize_t newpos; + Py_ssize_t replen; + Py_ssize_t remain; + PyObject *inputobj = NULL; + int need_to_grow = 0; + const char *new_inptr; + + if (*errorHandler == NULL) { + *errorHandler = PyCodec_LookupError(errors); + if (*errorHandler == NULL) + goto onError; + } + + make_decode_exception(exceptionObject, + encoding, + *input, *inend - *input, + *startinpos, *endinpos, + reason); + if (*exceptionObject == NULL) + goto onError; + + restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL); + if (restuple == NULL) + goto onError; + if (!PyTuple_Check(restuple)) { + PyErr_SetString(PyExc_TypeError, &argparse[3]); + goto onError; + } + if (!PyArg_ParseTuple(restuple, argparse, &repunicode, &newpos)) + goto onError; + + /* Copy back the bytes variables, which might have been modified by the + callback */ + inputobj = PyUnicodeDecodeError_GetObject(*exceptionObject); + if (!inputobj) + goto onError; + remain = *inend - *input - *endinpos; + *input = PyBytes_AS_STRING(inputobj); + insize = PyBytes_GET_SIZE(inputobj); + *inend = *input + insize; + /* we can DECREF safely, as the exception has another reference, + so the object won't go away. */ + Py_DECREF(inputobj); + + if (newpos<0) + newpos = insize+newpos; + if (newpos<0 || newpos>insize) { + PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", newpos); + goto onError; + } + + replen = PyUnicode_GET_LENGTH(repunicode); + if (replen > 1) { + writer->min_length += replen - 1; + need_to_grow = 1; + } + new_inptr = *input + newpos; + if (*inend - new_inptr > remain) { + /* We don't know the decoding algorithm here so we make the worst + assumption that one byte decodes to one unicode character. + If unfortunately one byte could decode to more unicode characters, + the decoder may write out-of-bound then. Is it possible for the + algorithms using this function? */ + writer->min_length += *inend - new_inptr - remain; + need_to_grow = 1; + } + if (need_to_grow) { + writer->overallocate = 1; + if (_PyUnicodeWriter_Prepare(writer, writer->min_length - writer->pos, + PyUnicode_MAX_CHAR_VALUE(repunicode)) == -1) + goto onError; + } + if (_PyUnicodeWriter_WriteStr(writer, repunicode) == -1) + goto onError; + + *endinpos = newpos; + *inptr = new_inptr; + + /* we made it! */ + Py_DECREF(restuple); + return 0; + + onError: + Py_XDECREF(restuple); + return -1; +} + +/* --- UTF-7 Codec -------------------------------------------------------- */ + +/* See RFC2152 for details. We encode conservatively and decode liberally. */ + +/* Three simple macros defining base-64. */ + +/* Is c a base-64 character? */ + +#define IS_BASE64(c) \ + (((c) >= 'A' && (c) <= 'Z') || \ + ((c) >= 'a' && (c) <= 'z') || \ + ((c) >= '0' && (c) <= '9') || \ + (c) == '+' || (c) == '/') + +/* given that c is a base-64 character, what is its base-64 value? */ + +#define FROM_BASE64(c) \ + (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' : \ + ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 26 : \ + ((c) >= '0' && (c) <= '9') ? (c) - '0' + 52 : \ + (c) == '+' ? 62 : 63) + +/* What is the base-64 character of the bottom 6 bits of n? */ + +#define TO_BASE64(n) \ + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(n) & 0x3f]) + +/* DECODE_DIRECT: this byte encountered in a UTF-7 string should be + * decoded as itself. We are permissive on decoding; the only ASCII + * byte not decoding to itself is the + which begins a base64 + * string. */ + +#define DECODE_DIRECT(c) \ + ((c) <= 127 && (c) != '+') + +/* The UTF-7 encoder treats ASCII characters differently according to + * whether they are Set D, Set O, Whitespace, or special (i.e. none of + * the above). See RFC2152. This array identifies these different + * sets: + * 0 : "Set D" + * alphanumeric and '(),-./:? + * 1 : "Set O" + * !"#$%&*;<=>@[]^_`{|} + * 2 : "whitespace" + * ht nl cr sp + * 3 : special (must be base64 encoded) + * everything else (i.e. +\~ and non-printing codes 0-8 11-12 14-31 127) + */ + +static +char utf7_category[128] = { +/* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3, +/* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* sp ! " # $ % & ' ( ) * + , - . / */ + 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 3, 0, 0, 0, 0, +/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, +/* @ A B C D E F G H I J K L M N O */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* P Q R S T U V W X Y Z [ \ ] ^ _ */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1, +/* ` a b c d e f g h i j k l m n o */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* p q r s t u v w x y z { | } ~ del */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 3, +}; + +/* ENCODE_DIRECT: this character should be encoded as itself. The + * answer depends on whether we are encoding set O as itself, and also + * on whether we are encoding whitespace as itself. RFC2152 makes it + * clear that the answers to these questions vary between + * applications, so this code needs to be flexible. */ + +#define ENCODE_DIRECT(c, directO, directWS) \ + ((c) < 128 && (c) > 0 && \ + ((utf7_category[(c)] == 0) || \ + (directWS && (utf7_category[(c)] == 2)) || \ + (directO && (utf7_category[(c)] == 1)))) + +PyObject * +PyUnicode_DecodeUTF7(const char *s, + Py_ssize_t size, + const char *errors) +{ + return PyUnicode_DecodeUTF7Stateful(s, size, errors, NULL); +} + +/* The decoder. The only state we preserve is our read position, + * i.e. how many characters we have consumed. So if we end in the + * middle of a shift sequence we have to back off the read position + * and the output to the beginning of the sequence, otherwise we lose + * all the shift state (seen bits, number of bits seen, high + * surrogate). */ + +PyObject * +PyUnicode_DecodeUTF7Stateful(const char *s, + Py_ssize_t size, + const char *errors, + Py_ssize_t *consumed) +{ + const char *starts = s; + Py_ssize_t startinpos; + Py_ssize_t endinpos; + const char *e; + _PyUnicodeWriter writer; + const char *errmsg = ""; + int inShift = 0; + Py_ssize_t shiftOutStart; + unsigned int base64bits = 0; + unsigned long base64buffer = 0; + Py_UCS4 surrogate = 0; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + + if (size == 0) { + if (consumed) + *consumed = 0; + _Py_RETURN_UNICODE_EMPTY(); + } + + /* Start off assuming it's all ASCII. Widen later as necessary. */ + _PyUnicodeWriter_Init(&writer); + writer.min_length = size; + + shiftOutStart = 0; + e = s + size; + + while (s < e) { + Py_UCS4 ch; + restart: + ch = (unsigned char) *s; + + if (inShift) { /* in a base-64 section */ + if (IS_BASE64(ch)) { /* consume a base-64 character */ + base64buffer = (base64buffer << 6) | FROM_BASE64(ch); + base64bits += 6; + s++; + if (base64bits >= 16) { + /* we have enough bits for a UTF-16 value */ + Py_UCS4 outCh = (Py_UCS4)(base64buffer >> (base64bits-16)); + base64bits -= 16; + base64buffer &= (1 << base64bits) - 1; /* clear high bits */ + assert(outCh <= 0xffff); + if (surrogate) { + /* expecting a second surrogate */ + if (Py_UNICODE_IS_LOW_SURROGATE(outCh)) { + Py_UCS4 ch2 = Py_UNICODE_JOIN_SURROGATES(surrogate, outCh); + if (_PyUnicodeWriter_WriteCharInline(&writer, ch2) < 0) + goto onError; + surrogate = 0; + continue; + } + else { + if (_PyUnicodeWriter_WriteCharInline(&writer, surrogate) < 0) + goto onError; + surrogate = 0; + } + } + if (Py_UNICODE_IS_HIGH_SURROGATE(outCh)) { + /* first surrogate */ + surrogate = outCh; + } + else { + if (_PyUnicodeWriter_WriteCharInline(&writer, outCh) < 0) + goto onError; + } + } + } + else { /* now leaving a base-64 section */ + inShift = 0; + if (base64bits > 0) { /* left-over bits */ + if (base64bits >= 6) { + /* We've seen at least one base-64 character */ + s++; + errmsg = "partial character in shift sequence"; + goto utf7Error; + } + else { + /* Some bits remain; they should be zero */ + if (base64buffer != 0) { + s++; + errmsg = "non-zero padding bits in shift sequence"; + goto utf7Error; + } + } + } + if (surrogate && DECODE_DIRECT(ch)) { + if (_PyUnicodeWriter_WriteCharInline(&writer, surrogate) < 0) + goto onError; + } + surrogate = 0; + if (ch == '-') { + /* '-' is absorbed; other terminating + characters are preserved */ + s++; + } + } + } + else if ( ch == '+' ) { + startinpos = s-starts; + s++; /* consume '+' */ + if (s < e && *s == '-') { /* '+-' encodes '+' */ + s++; + if (_PyUnicodeWriter_WriteCharInline(&writer, '+') < 0) + goto onError; + } + else if (s < e && !IS_BASE64(*s)) { + s++; + errmsg = "ill-formed sequence"; + goto utf7Error; + } + else { /* begin base64-encoded section */ + inShift = 1; + surrogate = 0; + shiftOutStart = writer.pos; + base64bits = 0; + base64buffer = 0; + } + } + else if (DECODE_DIRECT(ch)) { /* character decodes as itself */ + s++; + if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) + goto onError; + } + else { + startinpos = s-starts; + s++; + errmsg = "unexpected special character"; + goto utf7Error; + } + continue; +utf7Error: + endinpos = s-starts; + if (unicode_decode_call_errorhandler_writer( + errors, &errorHandler, + "utf7", errmsg, + &starts, &e, &startinpos, &endinpos, &exc, &s, + &writer)) + goto onError; + } + + /* end of string */ + + if (inShift && !consumed) { /* in shift sequence, no more to follow */ + /* if we're in an inconsistent state, that's an error */ + inShift = 0; + if (surrogate || + (base64bits >= 6) || + (base64bits > 0 && base64buffer != 0)) { + endinpos = size; + if (unicode_decode_call_errorhandler_writer( + errors, &errorHandler, + "utf7", "unterminated shift sequence", + &starts, &e, &startinpos, &endinpos, &exc, &s, + &writer)) + goto onError; + if (s < e) + goto restart; + } + } + + /* return state */ + if (consumed) { + if (inShift) { + *consumed = startinpos; + if (writer.pos != shiftOutStart && writer.maxchar > 127) { + PyObject *result = PyUnicode_FromKindAndData( + writer.kind, writer.data, shiftOutStart); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + _PyUnicodeWriter_Dealloc(&writer); + return result; + } + writer.pos = shiftOutStart; /* back off output */ + } + else { + *consumed = s-starts; + } + } + + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return _PyUnicodeWriter_Finish(&writer); + + onError: + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + + +PyObject * +_PyUnicode_EncodeUTF7(PyObject *str, + int base64SetO, + int base64WhiteSpace, + const char *errors) +{ + int kind; + void *data; + Py_ssize_t len; + PyObject *v; + int inShift = 0; + Py_ssize_t i; + unsigned int base64bits = 0; + unsigned long base64buffer = 0; + char * out; + char * start; + + if (PyUnicode_READY(str) == -1) + return NULL; + kind = PyUnicode_KIND(str); + data = PyUnicode_DATA(str); + len = PyUnicode_GET_LENGTH(str); + + if (len == 0) + return PyBytes_FromStringAndSize(NULL, 0); + + /* It might be possible to tighten this worst case */ + if (len > PY_SSIZE_T_MAX / 8) + return PyErr_NoMemory(); + v = PyBytes_FromStringAndSize(NULL, len * 8); + if (v == NULL) + return NULL; + + start = out = PyBytes_AS_STRING(v); + for (i = 0; i < len; ++i) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + + if (inShift) { + if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) { + /* shifting out */ + if (base64bits) { /* output remaining bits */ + *out++ = TO_BASE64(base64buffer << (6-base64bits)); + base64buffer = 0; + base64bits = 0; + } + inShift = 0; + /* Characters not in the BASE64 set implicitly unshift the sequence + so no '-' is required, except if the character is itself a '-' */ + if (IS_BASE64(ch) || ch == '-') { + *out++ = '-'; + } + *out++ = (char) ch; + } + else { + goto encode_char; + } + } + else { /* not in a shift sequence */ + if (ch == '+') { + *out++ = '+'; + *out++ = '-'; + } + else if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) { + *out++ = (char) ch; + } + else { + *out++ = '+'; + inShift = 1; + goto encode_char; + } + } + continue; +encode_char: + if (ch >= 0x10000) { + assert(ch <= MAX_UNICODE); + + /* code first surrogate */ + base64bits += 16; + base64buffer = (base64buffer << 16) | Py_UNICODE_HIGH_SURROGATE(ch); + while (base64bits >= 6) { + *out++ = TO_BASE64(base64buffer >> (base64bits-6)); + base64bits -= 6; + } + /* prepare second surrogate */ + ch = Py_UNICODE_LOW_SURROGATE(ch); + } + base64bits += 16; + base64buffer = (base64buffer << 16) | ch; + while (base64bits >= 6) { + *out++ = TO_BASE64(base64buffer >> (base64bits-6)); + base64bits -= 6; + } + } + if (base64bits) + *out++= TO_BASE64(base64buffer << (6-base64bits) ); + if (inShift) + *out++ = '-'; + if (_PyBytes_Resize(&v, out - start) < 0) + return NULL; + return v; +} +PyObject * +PyUnicode_EncodeUTF7(const Py_UNICODE *s, + Py_ssize_t size, + int base64SetO, + int base64WhiteSpace, + const char *errors) +{ + PyObject *result; + PyObject *tmp = PyUnicode_FromWideChar(s, size); + if (tmp == NULL) + return NULL; + result = _PyUnicode_EncodeUTF7(tmp, base64SetO, + base64WhiteSpace, errors); + Py_DECREF(tmp); + return result; +} + +#undef IS_BASE64 +#undef FROM_BASE64 +#undef TO_BASE64 +#undef DECODE_DIRECT +#undef ENCODE_DIRECT + +/* --- UTF-8 Codec -------------------------------------------------------- */ + +PyObject * +PyUnicode_DecodeUTF8(const char *s, + Py_ssize_t size, + const char *errors) +{ + return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL); +} + +#include "stringlib/asciilib.h" +#include "stringlib/codecs.h" +#include "stringlib/undef.h" + +#include "stringlib/ucs1lib.h" +#include "stringlib/codecs.h" +#include "stringlib/undef.h" + +#include "stringlib/ucs2lib.h" +#include "stringlib/codecs.h" +#include "stringlib/undef.h" + +#include "stringlib/ucs4lib.h" +#include "stringlib/codecs.h" +#include "stringlib/undef.h" + +/* Mask to quickly check whether a C 'long' contains a + non-ASCII, UTF8-encoded char. */ +#if (SIZEOF_LONG == 8) +# define ASCII_CHAR_MASK 0x8080808080808080UL +#elif (SIZEOF_LONG == 4) +# define ASCII_CHAR_MASK 0x80808080UL +#else +# error C 'long' size should be either 4 or 8! +#endif + +static Py_ssize_t +ascii_decode(const char *start, const char *end, Py_UCS1 *dest) +{ + const char *p = start; + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + + /* + * Issue #17237: m68k is a bit different from most architectures in + * that objects do not use "natural alignment" - for example, int and + * long are only aligned at 2-byte boundaries. Therefore the assert() + * won't work; also, tests have shown that skipping the "optimised + * version" will even speed up m68k. + */ +#if !defined(__m68k__) +#if SIZEOF_LONG <= SIZEOF_VOID_P + assert(_Py_IS_ALIGNED(dest, SIZEOF_LONG)); + if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + /* Fast path, see in STRINGLIB(utf8_decode) for + an explanation. */ + /* Help allocation */ + const char *_p = p; + Py_UCS1 * q = dest; + while (_p < aligned_end) { + unsigned long value = *(const unsigned long *) _p; + if (value & ASCII_CHAR_MASK) + break; + *((unsigned long *)q) = value; + _p += SIZEOF_LONG; + q += SIZEOF_LONG; + } + p = _p; + while (p < end) { + if ((unsigned char)*p & 0x80) + break; + *q++ = *p++; + } + return p - start; + } +#endif +#endif + while (p < end) { + /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h + for an explanation. */ + if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + /* Help allocation */ + const char *_p = p; + while (_p < aligned_end) { + unsigned long value = *(const unsigned long *) _p; + if (value & ASCII_CHAR_MASK) + break; + _p += SIZEOF_LONG; + } + p = _p; + if (_p == end) + break; + } + if ((unsigned char)*p & 0x80) + break; + ++p; + } + memcpy(dest, start, p - start); + return p - start; +} + +static PyObject * +unicode_decode_utf8(const char *s, Py_ssize_t size, + _Py_error_handler error_handler, const char *errors, + Py_ssize_t *consumed) +{ + _PyUnicodeWriter writer; + const char *starts = s; + const char *end = s + size; + + Py_ssize_t startinpos; + Py_ssize_t endinpos; + const char *errmsg = ""; + PyObject *error_handler_obj = NULL; + PyObject *exc = NULL; + + if (size == 0) { + if (consumed) + *consumed = 0; + _Py_RETURN_UNICODE_EMPTY(); + } + + /* ASCII is equivalent to the first 128 ordinals in Unicode. */ + if (size == 1 && (unsigned char)s[0] < 128) { + if (consumed) + *consumed = 1; + return get_latin1_char((unsigned char)s[0]); + } + + _PyUnicodeWriter_Init(&writer); + writer.min_length = size; + if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) == -1) + goto onError; + + writer.pos = ascii_decode(s, end, writer.data); + s += writer.pos; + while (s < end) { + Py_UCS4 ch; + int kind = writer.kind; + + if (kind == PyUnicode_1BYTE_KIND) { + if (PyUnicode_IS_ASCII(writer.buffer)) + ch = asciilib_utf8_decode(&s, end, writer.data, &writer.pos); + else + ch = ucs1lib_utf8_decode(&s, end, writer.data, &writer.pos); + } else if (kind == PyUnicode_2BYTE_KIND) { + ch = ucs2lib_utf8_decode(&s, end, writer.data, &writer.pos); + } else { + assert(kind == PyUnicode_4BYTE_KIND); + ch = ucs4lib_utf8_decode(&s, end, writer.data, &writer.pos); + } + + switch (ch) { + case 0: + if (s == end || consumed) + goto End; + errmsg = "unexpected end of data"; + startinpos = s - starts; + endinpos = end - starts; + break; + case 1: + errmsg = "invalid start byte"; + startinpos = s - starts; + endinpos = startinpos + 1; + break; + case 2: + if (consumed && (unsigned char)s[0] == 0xED && end - s == 2 + && (unsigned char)s[1] >= 0xA0 && (unsigned char)s[1] <= 0xBF) + { + /* Truncated surrogate code in range D800-DFFF */ + goto End; + } + /* fall through */ + case 3: + case 4: + errmsg = "invalid continuation byte"; + startinpos = s - starts; + endinpos = startinpos + ch - 1; + break; + default: + if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) + goto onError; + continue; + } + + if (error_handler == _Py_ERROR_UNKNOWN) + error_handler = _Py_GetErrorHandler(errors); + + switch (error_handler) { + case _Py_ERROR_IGNORE: + s += (endinpos - startinpos); + break; + + case _Py_ERROR_REPLACE: + if (_PyUnicodeWriter_WriteCharInline(&writer, 0xfffd) < 0) + goto onError; + s += (endinpos - startinpos); + break; + + case _Py_ERROR_SURROGATEESCAPE: + { + Py_ssize_t i; + + if (_PyUnicodeWriter_PrepareKind(&writer, PyUnicode_2BYTE_KIND) < 0) + goto onError; + for (i=startinpos; i 0xFF) { +#if SIZEOF_WCHAR_T == 4 + Py_UNREACHABLE(); +#else + assert(ch > 0xFFFF && ch <= MAX_UNICODE); + /* write a surrogate pair */ + unicode[outpos++] = (wchar_t)Py_UNICODE_HIGH_SURROGATE(ch); + unicode[outpos++] = (wchar_t)Py_UNICODE_LOW_SURROGATE(ch); +#endif + } + else { + if (!ch && s == e) { + break; + } + + if (surrogateescape) { + unicode[outpos++] = 0xDC00 + (unsigned char)*s++; + } + else { + /* Is it a valid three-byte code? */ + if (surrogatepass + && (e - s) >= 3 + && (s[0] & 0xf0) == 0xe0 + && (s[1] & 0xc0) == 0x80 + && (s[2] & 0xc0) == 0x80) + { + ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f); + s += 3; + unicode[outpos++] = ch; + } + else { + PyMem_RawFree(unicode ); + if (reason != NULL) { + switch (ch) { + case 0: + *reason = "unexpected end of data"; + break; + case 1: + *reason = "invalid start byte"; + break; + /* 2, 3, 4 */ + default: + *reason = "invalid continuation byte"; + break; + } + } + if (wlen != NULL) { + *wlen = s - orig_s; + } + return -2; + } + } + } + } + unicode[outpos] = L'\0'; + if (wlen) { + *wlen = outpos; + } + *wstr = unicode; + return 0; +} + + +wchar_t* +_Py_DecodeUTF8_surrogateescape(const char *arg, Py_ssize_t arglen, + size_t *wlen) +{ + wchar_t *wstr; + int res = _Py_DecodeUTF8Ex(arg, arglen, + &wstr, wlen, + NULL, _Py_ERROR_SURROGATEESCAPE); + if (res != 0) { + /* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */ + assert(res != -3); + if (wlen) { + *wlen = (size_t)res; + } + return NULL; + } + return wstr; +} + + +/* UTF-8 encoder using the surrogateescape error handler . + + On success, return 0 and write the newly allocated character string (use + PyMem_Free() to free the memory) into *str. + + On encoding failure, return -2 and write the position of the invalid + surrogate character into *error_pos (if error_pos is set) and the decoding + error message into *reason (if reason is set). + + On memory allocation failure, return -1. */ +int +_Py_EncodeUTF8Ex(const wchar_t *text, char **str, size_t *error_pos, + const char **reason, int raw_malloc, _Py_error_handler errors) +{ + const Py_ssize_t max_char_size = 4; + Py_ssize_t len = wcslen(text); + + assert(len >= 0); + + int surrogateescape = 0; + int surrogatepass = 0; + switch (errors) + { + case _Py_ERROR_STRICT: + break; + case _Py_ERROR_SURROGATEESCAPE: + surrogateescape = 1; + break; + case _Py_ERROR_SURROGATEPASS: + surrogatepass = 1; + break; + default: + return -3; + } + + if (len > PY_SSIZE_T_MAX / max_char_size - 1) { + return -1; + } + char *bytes; + if (raw_malloc) { + bytes = PyMem_RawMalloc((len + 1) * max_char_size); + } + else { + bytes = PyMem_Malloc((len + 1) * max_char_size); + } + if (bytes == NULL) { + return -1; + } + + char *p = bytes; + Py_ssize_t i; + for (i = 0; i < len; ) { + Py_ssize_t ch_pos = i; + Py_UCS4 ch = text[i]; + i++; +#if Py_UNICODE_SIZE == 2 + if (Py_UNICODE_IS_HIGH_SURROGATE(ch) + && i < len + && Py_UNICODE_IS_LOW_SURROGATE(text[i])) + { + ch = Py_UNICODE_JOIN_SURROGATES(ch, text[i]); + i++; + } +#endif + + if (ch < 0x80) { + /* Encode ASCII */ + *p++ = (char) ch; + + } + else if (ch < 0x0800) { + /* Encode Latin-1 */ + *p++ = (char)(0xc0 | (ch >> 6)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } + else if (Py_UNICODE_IS_SURROGATE(ch) && !surrogatepass) { + /* surrogateescape error handler */ + if (!surrogateescape || !(0xDC80 <= ch && ch <= 0xDCFF)) { + if (error_pos != NULL) { + *error_pos = (size_t)ch_pos; + } + if (reason != NULL) { + *reason = "encoding error"; + } + if (raw_malloc) { + PyMem_RawFree(bytes); + } + else { + PyMem_Free(bytes); + } + return -2; + } + *p++ = (char)(ch & 0xff); + } + else if (ch < 0x10000) { + *p++ = (char)(0xe0 | (ch >> 12)); + *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } + else { /* ch >= 0x10000 */ + assert(ch <= MAX_UNICODE); + /* Encode UCS4 Unicode ordinals */ + *p++ = (char)(0xf0 | (ch >> 18)); + *p++ = (char)(0x80 | ((ch >> 12) & 0x3f)); + *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } + } + *p++ = '\0'; + + size_t final_size = (p - bytes); + char *bytes2; + if (raw_malloc) { + bytes2 = PyMem_RawRealloc(bytes, final_size); + } + else { + bytes2 = PyMem_Realloc(bytes, final_size); + } + if (bytes2 == NULL) { + if (error_pos != NULL) { + *error_pos = (size_t)-1; + } + if (raw_malloc) { + PyMem_RawFree(bytes); + } + else { + PyMem_Free(bytes); + } + return -1; + } + *str = bytes2; + return 0; +} + + +/* Primary internal function which creates utf8 encoded bytes objects. + + Allocation strategy: if the string is short, convert into a stack buffer + and allocate exactly as much space needed at the end. Else allocate the + maximum possible needed (4 result bytes per Unicode character), and return + the excess memory at the end. +*/ +static PyObject * +unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, + const char *errors) +{ + enum PyUnicode_Kind kind; + void *data; + Py_ssize_t size; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + + if (PyUnicode_READY(unicode) == -1) + return NULL; + + if (PyUnicode_UTF8(unicode)) + return PyBytes_FromStringAndSize(PyUnicode_UTF8(unicode), + PyUnicode_UTF8_LENGTH(unicode)); + + kind = PyUnicode_KIND(unicode); + data = PyUnicode_DATA(unicode); + size = PyUnicode_GET_LENGTH(unicode); + + switch (kind) { + default: + Py_UNREACHABLE(); + case PyUnicode_1BYTE_KIND: + /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ + assert(!PyUnicode_IS_ASCII(unicode)); + return ucs1lib_utf8_encoder(unicode, data, size, error_handler, errors); + case PyUnicode_2BYTE_KIND: + return ucs2lib_utf8_encoder(unicode, data, size, error_handler, errors); + case PyUnicode_4BYTE_KIND: + return ucs4lib_utf8_encoder(unicode, data, size, error_handler, errors); + } +} + +PyObject * +_PyUnicode_AsUTF8String(PyObject *unicode, const char *errors) +{ + return unicode_encode_utf8(unicode, _Py_ERROR_UNKNOWN, errors); +} + + +PyObject * +PyUnicode_EncodeUTF8(const Py_UNICODE *s, + Py_ssize_t size, + const char *errors) +{ + PyObject *v, *unicode; + + unicode = PyUnicode_FromWideChar(s, size); + if (unicode == NULL) + return NULL; + v = _PyUnicode_AsUTF8String(unicode, errors); + Py_DECREF(unicode); + return v; +} + +PyObject * +PyUnicode_AsUTF8String(PyObject *unicode) +{ + return _PyUnicode_AsUTF8String(unicode, NULL); +} + +/* --- UTF-32 Codec ------------------------------------------------------- */ + +PyObject * +PyUnicode_DecodeUTF32(const char *s, + Py_ssize_t size, + const char *errors, + int *byteorder) +{ + return PyUnicode_DecodeUTF32Stateful(s, size, errors, byteorder, NULL); +} + +PyObject * +PyUnicode_DecodeUTF32Stateful(const char *s, + Py_ssize_t size, + const char *errors, + int *byteorder, + Py_ssize_t *consumed) +{ + const char *starts = s; + Py_ssize_t startinpos; + Py_ssize_t endinpos; + _PyUnicodeWriter writer; + const unsigned char *q, *e; + int le, bo = 0; /* assume native ordering by default */ + const char *encoding; + const char *errmsg = ""; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + + q = (const unsigned char *)s; + e = q + size; + + if (byteorder) + bo = *byteorder; + + /* Check for BOM marks (U+FEFF) in the input and adjust current + byte order setting accordingly. In native mode, the leading BOM + mark is skipped, in all other modes, it is copied to the output + stream as-is (giving a ZWNBSP character). */ + if (bo == 0 && size >= 4) { + Py_UCS4 bom = ((unsigned int)q[3] << 24) | (q[2] << 16) | (q[1] << 8) | q[0]; + if (bom == 0x0000FEFF) { + bo = -1; + q += 4; + } + else if (bom == 0xFFFE0000) { + bo = 1; + q += 4; + } + if (byteorder) + *byteorder = bo; + } + + if (q == e) { + if (consumed) + *consumed = size; + _Py_RETURN_UNICODE_EMPTY(); + } + +#ifdef WORDS_BIGENDIAN + le = bo < 0; +#else + le = bo <= 0; +#endif + encoding = le ? "utf-32-le" : "utf-32-be"; + + _PyUnicodeWriter_Init(&writer); + writer.min_length = (e - q + 3) / 4; + if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) == -1) + goto onError; + + while (1) { + Py_UCS4 ch = 0; + Py_UCS4 maxch = PyUnicode_MAX_CHAR_VALUE(writer.buffer); + + if (e - q >= 4) { + enum PyUnicode_Kind kind = writer.kind; + void *data = writer.data; + const unsigned char *last = e - 4; + Py_ssize_t pos = writer.pos; + if (le) { + do { + ch = ((unsigned int)q[3] << 24) | (q[2] << 16) | (q[1] << 8) | q[0]; + if (ch > maxch) + break; + if (kind != PyUnicode_1BYTE_KIND && + Py_UNICODE_IS_SURROGATE(ch)) + break; + PyUnicode_WRITE(kind, data, pos++, ch); + q += 4; + } while (q <= last); + } + else { + do { + ch = ((unsigned int)q[0] << 24) | (q[1] << 16) | (q[2] << 8) | q[3]; + if (ch > maxch) + break; + if (kind != PyUnicode_1BYTE_KIND && + Py_UNICODE_IS_SURROGATE(ch)) + break; + PyUnicode_WRITE(kind, data, pos++, ch); + q += 4; + } while (q <= last); + } + writer.pos = pos; + } + + if (Py_UNICODE_IS_SURROGATE(ch)) { + errmsg = "code point in surrogate code point range(0xd800, 0xe000)"; + startinpos = ((const char *)q) - starts; + endinpos = startinpos + 4; + } + else if (ch <= maxch) { + if (q == e || consumed) + break; + /* remaining bytes at the end? (size should be divisible by 4) */ + errmsg = "truncated data"; + startinpos = ((const char *)q) - starts; + endinpos = ((const char *)e) - starts; + } + else { + if (ch < 0x110000) { + if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) + goto onError; + q += 4; + continue; + } + errmsg = "code point not in range(0x110000)"; + startinpos = ((const char *)q) - starts; + endinpos = startinpos + 4; + } + + /* The remaining input chars are ignored if the callback + chooses to skip the input */ + if (unicode_decode_call_errorhandler_writer( + errors, &errorHandler, + encoding, errmsg, + &starts, (const char **)&e, &startinpos, &endinpos, &exc, (const char **)&q, + &writer)) + goto onError; + } + + if (consumed) + *consumed = (const char *)q-starts; + + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return _PyUnicodeWriter_Finish(&writer); + + onError: + _PyUnicodeWriter_Dealloc(&writer); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return NULL; +} + +PyObject * +_PyUnicode_EncodeUTF32(PyObject *str, + const char *errors, + int byteorder) +{ + enum PyUnicode_Kind kind; + const void *data; + Py_ssize_t len; + PyObject *v; + uint32_t *out; +#if PY_LITTLE_ENDIAN + int native_ordering = byteorder <= 0; +#else + int native_ordering = byteorder >= 0; +#endif + const char *encoding; + Py_ssize_t nsize, pos; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + PyObject *rep = NULL; + + if (!PyUnicode_Check(str)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(str) == -1) + return NULL; + kind = PyUnicode_KIND(str); + data = PyUnicode_DATA(str); + len = PyUnicode_GET_LENGTH(str); + + if (len > PY_SSIZE_T_MAX / 4 - (byteorder == 0)) + return PyErr_NoMemory(); + nsize = len + (byteorder == 0); + v = PyBytes_FromStringAndSize(NULL, nsize * 4); + if (v == NULL) + return NULL; + + /* output buffer is 4-bytes aligned */ + assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(v), 4)); + out = (uint32_t *)PyBytes_AS_STRING(v); + if (byteorder == 0) + *out++ = 0xFEFF; + if (len == 0) + goto done; + + if (byteorder == -1) + encoding = "utf-32-le"; + else if (byteorder == 1) + encoding = "utf-32-be"; + else + encoding = "utf-32"; + + if (kind == PyUnicode_1BYTE_KIND) { + ucs1lib_utf32_encode((const Py_UCS1 *)data, len, &out, native_ordering); + goto done; + } + + pos = 0; + while (pos < len) { + Py_ssize_t repsize, moreunits; + + if (kind == PyUnicode_2BYTE_KIND) { + pos += ucs2lib_utf32_encode((const Py_UCS2 *)data + pos, len - pos, + &out, native_ordering); + } + else { + assert(kind == PyUnicode_4BYTE_KIND); + pos += ucs4lib_utf32_encode((const Py_UCS4 *)data + pos, len - pos, + &out, native_ordering); + } + if (pos == len) + break; + + rep = unicode_encode_call_errorhandler( + errors, &errorHandler, + encoding, "surrogates not allowed", + str, &exc, pos, pos + 1, &pos); + if (!rep) + goto error; + + if (PyBytes_Check(rep)) { + repsize = PyBytes_GET_SIZE(rep); + if (repsize & 3) { + raise_encode_exception(&exc, encoding, + str, pos - 1, pos, + "surrogates not allowed"); + goto error; + } + moreunits = repsize / 4; + } + else { + assert(PyUnicode_Check(rep)); + if (PyUnicode_READY(rep) < 0) + goto error; + moreunits = repsize = PyUnicode_GET_LENGTH(rep); + if (!PyUnicode_IS_ASCII(rep)) { + raise_encode_exception(&exc, encoding, + str, pos - 1, pos, + "surrogates not allowed"); + goto error; + } + } + + /* four bytes are reserved for each surrogate */ + if (moreunits > 1) { + Py_ssize_t outpos = out - (uint32_t*) PyBytes_AS_STRING(v); + if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 4) { + /* integer overflow */ + PyErr_NoMemory(); + goto error; + } + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 4 * (moreunits - 1)) < 0) + goto error; + out = (uint32_t*) PyBytes_AS_STRING(v) + outpos; + } + + if (PyBytes_Check(rep)) { + memcpy(out, PyBytes_AS_STRING(rep), repsize); + out += moreunits; + } else /* rep is unicode */ { + assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); + ucs1lib_utf32_encode(PyUnicode_1BYTE_DATA(rep), repsize, + &out, native_ordering); + } + + Py_CLEAR(rep); + } + + /* Cut back to size actually needed. This is necessary for, for example, + encoding of a string containing isolated surrogates and the 'ignore' + handler is used. */ + nsize = (unsigned char*) out - (unsigned char*) PyBytes_AS_STRING(v); + if (nsize != PyBytes_GET_SIZE(v)) + _PyBytes_Resize(&v, nsize); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + done: + return v; + error: + Py_XDECREF(rep); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + Py_XDECREF(v); + return NULL; +} + +PyObject * +PyUnicode_EncodeUTF32(const Py_UNICODE *s, + Py_ssize_t size, + const char *errors, + int byteorder) +{ + PyObject *result; + PyObject *tmp = PyUnicode_FromWideChar(s, size); + if (tmp == NULL) + return NULL; + result = _PyUnicode_EncodeUTF32(tmp, errors, byteorder); + Py_DECREF(tmp); + return result; +} + +PyObject * +PyUnicode_AsUTF32String(PyObject *unicode) +{ + return _PyUnicode_EncodeUTF32(unicode, NULL, 0); +} + +/* --- UTF-16 Codec ------------------------------------------------------- */ + +PyObject * +PyUnicode_DecodeUTF16(const char *s, + Py_ssize_t size, + const char *errors, + int *byteorder) +{ + return PyUnicode_DecodeUTF16Stateful(s, size, errors, byteorder, NULL); +} + +PyObject * +PyUnicode_DecodeUTF16Stateful(const char *s, + Py_ssize_t size, + const char *errors, + int *byteorder, + Py_ssize_t *consumed) +{ + const char *starts = s; + Py_ssize_t startinpos; + Py_ssize_t endinpos; + _PyUnicodeWriter writer; + const unsigned char *q, *e; + int bo = 0; /* assume native ordering by default */ + int native_ordering; + const char *errmsg = ""; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + const char *encoding; + + q = (const unsigned char *)s; + e = q + size; + + if (byteorder) + bo = *byteorder; + + /* Check for BOM marks (U+FEFF) in the input and adjust current + byte order setting accordingly. In native mode, the leading BOM + mark is skipped, in all other modes, it is copied to the output + stream as-is (giving a ZWNBSP character). */ + if (bo == 0 && size >= 2) { + const Py_UCS4 bom = (q[1] << 8) | q[0]; + if (bom == 0xFEFF) { + q += 2; + bo = -1; + } + else if (bom == 0xFFFE) { + q += 2; + bo = 1; + } + if (byteorder) + *byteorder = bo; + } + + if (q == e) { + if (consumed) + *consumed = size; + _Py_RETURN_UNICODE_EMPTY(); + } + +#if PY_LITTLE_ENDIAN + native_ordering = bo <= 0; + encoding = bo <= 0 ? "utf-16-le" : "utf-16-be"; +#else + native_ordering = bo >= 0; + encoding = bo >= 0 ? "utf-16-be" : "utf-16-le"; +#endif + + /* Note: size will always be longer than the resulting Unicode + character count normally. Error handler will take care of + resizing when needed. */ + _PyUnicodeWriter_Init(&writer); + writer.min_length = (e - q + 1) / 2; + if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) == -1) + goto onError; + + while (1) { + Py_UCS4 ch = 0; + if (e - q >= 2) { + int kind = writer.kind; + if (kind == PyUnicode_1BYTE_KIND) { + if (PyUnicode_IS_ASCII(writer.buffer)) + ch = asciilib_utf16_decode(&q, e, + (Py_UCS1*)writer.data, &writer.pos, + native_ordering); + else + ch = ucs1lib_utf16_decode(&q, e, + (Py_UCS1*)writer.data, &writer.pos, + native_ordering); + } else if (kind == PyUnicode_2BYTE_KIND) { + ch = ucs2lib_utf16_decode(&q, e, + (Py_UCS2*)writer.data, &writer.pos, + native_ordering); + } else { + assert(kind == PyUnicode_4BYTE_KIND); + ch = ucs4lib_utf16_decode(&q, e, + (Py_UCS4*)writer.data, &writer.pos, + native_ordering); + } + } + + switch (ch) + { + case 0: + /* remaining byte at the end? (size should be even) */ + if (q == e || consumed) + goto End; + errmsg = "truncated data"; + startinpos = ((const char *)q) - starts; + endinpos = ((const char *)e) - starts; + break; + /* The remaining input chars are ignored if the callback + chooses to skip the input */ + case 1: + q -= 2; + if (consumed) + goto End; + errmsg = "unexpected end of data"; + startinpos = ((const char *)q) - starts; + endinpos = ((const char *)e) - starts; + break; + case 2: + errmsg = "illegal encoding"; + startinpos = ((const char *)q) - 2 - starts; + endinpos = startinpos + 2; + break; + case 3: + errmsg = "illegal UTF-16 surrogate"; + startinpos = ((const char *)q) - 4 - starts; + endinpos = startinpos + 2; + break; + default: + if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) + goto onError; + continue; + } + + if (unicode_decode_call_errorhandler_writer( + errors, + &errorHandler, + encoding, errmsg, + &starts, + (const char **)&e, + &startinpos, + &endinpos, + &exc, + (const char **)&q, + &writer)) + goto onError; + } + +End: + if (consumed) + *consumed = (const char *)q-starts; + + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return _PyUnicodeWriter_Finish(&writer); + + onError: + _PyUnicodeWriter_Dealloc(&writer); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return NULL; +} + +PyObject * +_PyUnicode_EncodeUTF16(PyObject *str, + const char *errors, + int byteorder) +{ + enum PyUnicode_Kind kind; + const void *data; + Py_ssize_t len; + PyObject *v; + unsigned short *out; + Py_ssize_t pairs; +#if PY_BIG_ENDIAN + int native_ordering = byteorder >= 0; +#else + int native_ordering = byteorder <= 0; +#endif + const char *encoding; + Py_ssize_t nsize, pos; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + PyObject *rep = NULL; + + if (!PyUnicode_Check(str)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(str) == -1) + return NULL; + kind = PyUnicode_KIND(str); + data = PyUnicode_DATA(str); + len = PyUnicode_GET_LENGTH(str); + + pairs = 0; + if (kind == PyUnicode_4BYTE_KIND) { + const Py_UCS4 *in = (const Py_UCS4 *)data; + const Py_UCS4 *end = in + len; + while (in < end) { + if (*in++ >= 0x10000) { + pairs++; + } + } + } + if (len > PY_SSIZE_T_MAX / 2 - pairs - (byteorder == 0)) { + return PyErr_NoMemory(); + } + nsize = len + pairs + (byteorder == 0); + v = PyBytes_FromStringAndSize(NULL, nsize * 2); + if (v == NULL) { + return NULL; + } + + /* output buffer is 2-bytes aligned */ + assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(v), 2)); + out = (unsigned short *)PyBytes_AS_STRING(v); + if (byteorder == 0) { + *out++ = 0xFEFF; + } + if (len == 0) { + goto done; + } + + if (kind == PyUnicode_1BYTE_KIND) { + ucs1lib_utf16_encode((const Py_UCS1 *)data, len, &out, native_ordering); + goto done; + } + + if (byteorder < 0) { + encoding = "utf-16-le"; + } + else if (byteorder > 0) { + encoding = "utf-16-be"; + } + else { + encoding = "utf-16"; + } + + pos = 0; + while (pos < len) { + Py_ssize_t repsize, moreunits; + + if (kind == PyUnicode_2BYTE_KIND) { + pos += ucs2lib_utf16_encode((const Py_UCS2 *)data + pos, len - pos, + &out, native_ordering); + } + else { + assert(kind == PyUnicode_4BYTE_KIND); + pos += ucs4lib_utf16_encode((const Py_UCS4 *)data + pos, len - pos, + &out, native_ordering); + } + if (pos == len) + break; + + rep = unicode_encode_call_errorhandler( + errors, &errorHandler, + encoding, "surrogates not allowed", + str, &exc, pos, pos + 1, &pos); + if (!rep) + goto error; + + if (PyBytes_Check(rep)) { + repsize = PyBytes_GET_SIZE(rep); + if (repsize & 1) { + raise_encode_exception(&exc, encoding, + str, pos - 1, pos, + "surrogates not allowed"); + goto error; + } + moreunits = repsize / 2; + } + else { + assert(PyUnicode_Check(rep)); + if (PyUnicode_READY(rep) < 0) + goto error; + moreunits = repsize = PyUnicode_GET_LENGTH(rep); + if (!PyUnicode_IS_ASCII(rep)) { + raise_encode_exception(&exc, encoding, + str, pos - 1, pos, + "surrogates not allowed"); + goto error; + } + } + + /* two bytes are reserved for each surrogate */ + if (moreunits > 1) { + Py_ssize_t outpos = out - (unsigned short*) PyBytes_AS_STRING(v); + if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 2) { + /* integer overflow */ + PyErr_NoMemory(); + goto error; + } + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 2 * (moreunits - 1)) < 0) + goto error; + out = (unsigned short*) PyBytes_AS_STRING(v) + outpos; + } + + if (PyBytes_Check(rep)) { + memcpy(out, PyBytes_AS_STRING(rep), repsize); + out += moreunits; + } else /* rep is unicode */ { + assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); + ucs1lib_utf16_encode(PyUnicode_1BYTE_DATA(rep), repsize, + &out, native_ordering); + } + + Py_CLEAR(rep); + } + + /* Cut back to size actually needed. This is necessary for, for example, + encoding of a string containing isolated surrogates and the 'ignore' handler + is used. */ + nsize = (unsigned char*) out - (unsigned char*) PyBytes_AS_STRING(v); + if (nsize != PyBytes_GET_SIZE(v)) + _PyBytes_Resize(&v, nsize); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + done: + return v; + error: + Py_XDECREF(rep); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + Py_XDECREF(v); + return NULL; +#undef STORECHAR +} + +PyObject * +PyUnicode_EncodeUTF16(const Py_UNICODE *s, + Py_ssize_t size, + const char *errors, + int byteorder) +{ + PyObject *result; + PyObject *tmp = PyUnicode_FromWideChar(s, size); + if (tmp == NULL) + return NULL; + result = _PyUnicode_EncodeUTF16(tmp, errors, byteorder); + Py_DECREF(tmp); + return result; +} + +PyObject * +PyUnicode_AsUTF16String(PyObject *unicode) +{ + return _PyUnicode_EncodeUTF16(unicode, NULL, 0); +} + +/* --- Unicode Escape Codec ----------------------------------------------- */ + +static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL; + +PyObject * +_PyUnicode_DecodeUnicodeEscape(const char *s, + Py_ssize_t size, + const char *errors, + const char **first_invalid_escape) +{ + const char *starts = s; + _PyUnicodeWriter writer; + const char *end; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + + // so we can remember if we've seen an invalid escape char or not + *first_invalid_escape = NULL; + + if (size == 0) { + _Py_RETURN_UNICODE_EMPTY(); + } + /* Escaped strings will always be longer than the resulting + Unicode string, so we start with size here and then reduce the + length after conversion to the true value. + (but if the error callback returns a long replacement string + we'll have to allocate more space) */ + _PyUnicodeWriter_Init(&writer); + writer.min_length = size; + if (_PyUnicodeWriter_Prepare(&writer, size, 127) < 0) { + goto onError; + } + + end = s + size; + while (s < end) { + unsigned char c = (unsigned char) *s++; + Py_UCS4 ch; + int count; + Py_ssize_t startinpos; + Py_ssize_t endinpos; + const char *message; + +#define WRITE_ASCII_CHAR(ch) \ + do { \ + assert(ch <= 127); \ + assert(writer.pos < writer.size); \ + PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, ch); \ + } while(0) + +#define WRITE_CHAR(ch) \ + do { \ + if (ch <= writer.maxchar) { \ + assert(writer.pos < writer.size); \ + PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, ch); \ + } \ + else if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) { \ + goto onError; \ + } \ + } while(0) + + /* Non-escape characters are interpreted as Unicode ordinals */ + if (c != '\\') { + WRITE_CHAR(c); + continue; + } + + startinpos = s - starts - 1; + /* \ - Escapes */ + if (s >= end) { + message = "\\ at end of string"; + goto error; + } + c = (unsigned char) *s++; + + assert(writer.pos < writer.size); + switch (c) { + + /* \x escapes */ + case '\n': continue; + case '\\': WRITE_ASCII_CHAR('\\'); continue; + case '\'': WRITE_ASCII_CHAR('\''); continue; + case '\"': WRITE_ASCII_CHAR('\"'); continue; + case 'b': WRITE_ASCII_CHAR('\b'); continue; + /* FF */ + case 'f': WRITE_ASCII_CHAR('\014'); continue; + case 't': WRITE_ASCII_CHAR('\t'); continue; + case 'n': WRITE_ASCII_CHAR('\n'); continue; + case 'r': WRITE_ASCII_CHAR('\r'); continue; + /* VT */ + case 'v': WRITE_ASCII_CHAR('\013'); continue; + /* BEL, not classic C */ + case 'a': WRITE_ASCII_CHAR('\007'); continue; + + /* \OOO (octal) escapes */ + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + ch = c - '0'; + if (s < end && '0' <= *s && *s <= '7') { + ch = (ch<<3) + *s++ - '0'; + if (s < end && '0' <= *s && *s <= '7') { + ch = (ch<<3) + *s++ - '0'; + } + } + WRITE_CHAR(ch); + continue; + + /* hex escapes */ + /* \xXX */ + case 'x': + count = 2; + message = "truncated \\xXX escape"; + goto hexescape; + + /* \uXXXX */ + case 'u': + count = 4; + message = "truncated \\uXXXX escape"; + goto hexescape; + + /* \UXXXXXXXX */ + case 'U': + count = 8; + message = "truncated \\UXXXXXXXX escape"; + hexescape: + for (ch = 0; count && s < end; ++s, --count) { + c = (unsigned char)*s; + ch <<= 4; + if (c >= '0' && c <= '9') { + ch += c - '0'; + } + else if (c >= 'a' && c <= 'f') { + ch += c - ('a' - 10); + } + else if (c >= 'A' && c <= 'F') { + ch += c - ('A' - 10); + } + else { + break; + } + } + if (count) { + goto error; + } + + /* when we get here, ch is a 32-bit unicode character */ + if (ch > MAX_UNICODE) { + message = "illegal Unicode character"; + goto error; + } + + WRITE_CHAR(ch); + continue; + + /* \N{name} */ + case 'N': + if (ucnhash_CAPI == NULL) { + /* load the unicode data module */ + ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import( + PyUnicodeData_CAPSULE_NAME, 1); + if (ucnhash_CAPI == NULL) { + PyErr_SetString( + PyExc_UnicodeError, + "\\N escapes not supported (can't load unicodedata module)" + ); + goto onError; + } + } + + message = "malformed \\N character escape"; + if (s < end && *s == '{') { + const char *start = ++s; + size_t namelen; + /* look for the closing brace */ + while (s < end && *s != '}') + s++; + namelen = s - start; + if (namelen && s < end) { + /* found a name. look it up in the unicode database */ + s++; + ch = 0xffffffff; /* in case 'getcode' messes up */ + if (namelen <= INT_MAX && + ucnhash_CAPI->getcode(NULL, start, (int)namelen, + &ch, 0)) { + assert(ch <= MAX_UNICODE); + WRITE_CHAR(ch); + continue; + } + message = "unknown Unicode character name"; + } + } + goto error; + + default: + if (*first_invalid_escape == NULL) { + *first_invalid_escape = s-1; /* Back up one char, since we've + already incremented s. */ + } + WRITE_ASCII_CHAR('\\'); + WRITE_CHAR(c); + continue; + } + + error: + endinpos = s-starts; + writer.min_length = end - s + writer.pos; + if (unicode_decode_call_errorhandler_writer( + errors, &errorHandler, + "unicodeescape", message, + &starts, &end, &startinpos, &endinpos, &exc, &s, + &writer)) { + goto onError; + } + assert(end - s <= writer.size - writer.pos); + +#undef WRITE_ASCII_CHAR +#undef WRITE_CHAR + } + + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return _PyUnicodeWriter_Finish(&writer); + + onError: + _PyUnicodeWriter_Dealloc(&writer); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return NULL; +} + +PyObject * +PyUnicode_DecodeUnicodeEscape(const char *s, + Py_ssize_t size, + const char *errors) +{ + const char *first_invalid_escape; + PyObject *result = _PyUnicode_DecodeUnicodeEscape(s, size, errors, + &first_invalid_escape); + if (result == NULL) + return NULL; + if (first_invalid_escape != NULL) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid escape sequence '\\%c'", + (unsigned char)*first_invalid_escape) < 0) { + Py_DECREF(result); + return NULL; + } + } + return result; +} + +/* Return a Unicode-Escape string version of the Unicode object. */ + +PyObject * +PyUnicode_AsUnicodeEscapeString(PyObject *unicode) +{ + Py_ssize_t i, len; + PyObject *repr; + char *p; + enum PyUnicode_Kind kind; + void *data; + Py_ssize_t expandsize; + + /* Initial allocation is based on the longest-possible character + escape. + + For UCS1 strings it's '\xxx', 4 bytes per source character. + For UCS2 strings it's '\uxxxx', 6 bytes per source character. + For UCS4 strings it's '\U00xxxxxx', 10 bytes per source character. + */ + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) { + return NULL; + } + + len = PyUnicode_GET_LENGTH(unicode); + if (len == 0) { + return PyBytes_FromStringAndSize(NULL, 0); + } + + kind = PyUnicode_KIND(unicode); + data = PyUnicode_DATA(unicode); + /* 4 byte characters can take up 10 bytes, 2 byte characters can take up 6 + bytes, and 1 byte characters 4. */ + expandsize = kind * 2 + 2; + if (len > PY_SSIZE_T_MAX / expandsize) { + return PyErr_NoMemory(); + } + repr = PyBytes_FromStringAndSize(NULL, expandsize * len); + if (repr == NULL) { + return NULL; + } + + p = PyBytes_AS_STRING(repr); + for (i = 0; i < len; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + + /* U+0000-U+00ff range */ + if (ch < 0x100) { + if (ch >= ' ' && ch < 127) { + if (ch != '\\') { + /* Copy printable US ASCII as-is */ + *p++ = (char) ch; + } + /* Escape backslashes */ + else { + *p++ = '\\'; + *p++ = '\\'; + } + } + + /* Map special whitespace to '\t', \n', '\r' */ + else if (ch == '\t') { + *p++ = '\\'; + *p++ = 't'; + } + else if (ch == '\n') { + *p++ = '\\'; + *p++ = 'n'; + } + else if (ch == '\r') { + *p++ = '\\'; + *p++ = 'r'; + } + + /* Map non-printable US ASCII and 8-bit characters to '\xHH' */ + else { + *p++ = '\\'; + *p++ = 'x'; + *p++ = Py_hexdigits[(ch >> 4) & 0x000F]; + *p++ = Py_hexdigits[ch & 0x000F]; + } + } + /* U+0100-U+ffff range: Map 16-bit characters to '\uHHHH' */ + else if (ch < 0x10000) { + *p++ = '\\'; + *p++ = 'u'; + *p++ = Py_hexdigits[(ch >> 12) & 0x000F]; + *p++ = Py_hexdigits[(ch >> 8) & 0x000F]; + *p++ = Py_hexdigits[(ch >> 4) & 0x000F]; + *p++ = Py_hexdigits[ch & 0x000F]; + } + /* U+010000-U+10ffff range: Map 21-bit characters to '\U00HHHHHH' */ + else { + + /* Make sure that the first two digits are zero */ + assert(ch <= MAX_UNICODE && MAX_UNICODE <= 0x10ffff); + *p++ = '\\'; + *p++ = 'U'; + *p++ = '0'; + *p++ = '0'; + *p++ = Py_hexdigits[(ch >> 20) & 0x0000000F]; + *p++ = Py_hexdigits[(ch >> 16) & 0x0000000F]; + *p++ = Py_hexdigits[(ch >> 12) & 0x0000000F]; + *p++ = Py_hexdigits[(ch >> 8) & 0x0000000F]; + *p++ = Py_hexdigits[(ch >> 4) & 0x0000000F]; + *p++ = Py_hexdigits[ch & 0x0000000F]; + } + } + + assert(p - PyBytes_AS_STRING(repr) > 0); + if (_PyBytes_Resize(&repr, p - PyBytes_AS_STRING(repr)) < 0) { + return NULL; + } + return repr; +} + +PyObject * +PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, + Py_ssize_t size) +{ + PyObject *result; + PyObject *tmp = PyUnicode_FromWideChar(s, size); + if (tmp == NULL) { + return NULL; + } + + result = PyUnicode_AsUnicodeEscapeString(tmp); + Py_DECREF(tmp); + return result; +} + +/* --- Raw Unicode Escape Codec ------------------------------------------- */ + +PyObject * +PyUnicode_DecodeRawUnicodeEscape(const char *s, + Py_ssize_t size, + const char *errors) +{ + const char *starts = s; + _PyUnicodeWriter writer; + const char *end; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + + if (size == 0) { + _Py_RETURN_UNICODE_EMPTY(); + } + + /* Escaped strings will always be longer than the resulting + Unicode string, so we start with size here and then reduce the + length after conversion to the true value. (But decoding error + handler might have to resize the string) */ + _PyUnicodeWriter_Init(&writer); + writer.min_length = size; + if (_PyUnicodeWriter_Prepare(&writer, size, 127) < 0) { + goto onError; + } + + end = s + size; + while (s < end) { + unsigned char c = (unsigned char) *s++; + Py_UCS4 ch; + int count; + Py_ssize_t startinpos; + Py_ssize_t endinpos; + const char *message; + +#define WRITE_CHAR(ch) \ + do { \ + if (ch <= writer.maxchar) { \ + assert(writer.pos < writer.size); \ + PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, ch); \ + } \ + else if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) { \ + goto onError; \ + } \ + } while(0) + + /* Non-escape characters are interpreted as Unicode ordinals */ + if (c != '\\' || s >= end) { + WRITE_CHAR(c); + continue; + } + + c = (unsigned char) *s++; + if (c == 'u') { + count = 4; + message = "truncated \\uXXXX escape"; + } + else if (c == 'U') { + count = 8; + message = "truncated \\UXXXXXXXX escape"; + } + else { + assert(writer.pos < writer.size); + PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, '\\'); + WRITE_CHAR(c); + continue; + } + startinpos = s - starts - 2; + + /* \uHHHH with 4 hex digits, \U00HHHHHH with 8 */ + for (ch = 0; count && s < end; ++s, --count) { + c = (unsigned char)*s; + ch <<= 4; + if (c >= '0' && c <= '9') { + ch += c - '0'; + } + else if (c >= 'a' && c <= 'f') { + ch += c - ('a' - 10); + } + else if (c >= 'A' && c <= 'F') { + ch += c - ('A' - 10); + } + else { + break; + } + } + if (!count) { + if (ch <= MAX_UNICODE) { + WRITE_CHAR(ch); + continue; + } + message = "\\Uxxxxxxxx out of range"; + } + + endinpos = s-starts; + writer.min_length = end - s + writer.pos; + if (unicode_decode_call_errorhandler_writer( + errors, &errorHandler, + "rawunicodeescape", message, + &starts, &end, &startinpos, &endinpos, &exc, &s, + &writer)) { + goto onError; + } + assert(end - s <= writer.size - writer.pos); + +#undef WRITE_CHAR + } + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return _PyUnicodeWriter_Finish(&writer); + + onError: + _PyUnicodeWriter_Dealloc(&writer); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return NULL; + +} + + +PyObject * +PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) +{ + PyObject *repr; + char *p; + Py_ssize_t expandsize, pos; + int kind; + void *data; + Py_ssize_t len; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) { + return NULL; + } + kind = PyUnicode_KIND(unicode); + data = PyUnicode_DATA(unicode); + len = PyUnicode_GET_LENGTH(unicode); + if (kind == PyUnicode_1BYTE_KIND) { + return PyBytes_FromStringAndSize(data, len); + } + + /* 4 byte characters can take up 10 bytes, 2 byte characters can take up 6 + bytes, and 1 byte characters 4. */ + expandsize = kind * 2 + 2; + + if (len > PY_SSIZE_T_MAX / expandsize) { + return PyErr_NoMemory(); + } + repr = PyBytes_FromStringAndSize(NULL, expandsize * len); + if (repr == NULL) { + return NULL; + } + if (len == 0) { + return repr; + } + + p = PyBytes_AS_STRING(repr); + for (pos = 0; pos < len; pos++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, pos); + + /* U+0000-U+00ff range: Copy 8-bit characters as-is */ + if (ch < 0x100) { + *p++ = (char) ch; + } + /* U+0100-U+ffff range: Map 16-bit characters to '\uHHHH' */ + else if (ch < 0x10000) { + *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]; + } + /* U+010000-U+10ffff range: Map 32-bit characters to '\U00HHHHHH' */ + else { + assert(ch <= MAX_UNICODE && MAX_UNICODE <= 0x10ffff); + *p++ = '\\'; + *p++ = 'U'; + *p++ = '0'; + *p++ = '0'; + *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]; + } + } + + assert(p > PyBytes_AS_STRING(repr)); + if (_PyBytes_Resize(&repr, p - PyBytes_AS_STRING(repr)) < 0) { + return NULL; + } + return repr; +} + +PyObject * +PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, + Py_ssize_t size) +{ + PyObject *result; + PyObject *tmp = PyUnicode_FromWideChar(s, size); + if (tmp == NULL) + return NULL; + result = PyUnicode_AsRawUnicodeEscapeString(tmp); + Py_DECREF(tmp); + return result; +} + +/* --- Latin-1 Codec ------------------------------------------------------ */ + +PyObject * +PyUnicode_DecodeLatin1(const char *s, + Py_ssize_t size, + const char *errors) +{ + /* Latin-1 is equivalent to the first 256 ordinals in Unicode. */ + return _PyUnicode_FromUCS1((const unsigned char*)s, size); +} + +/* create or adjust a UnicodeEncodeError */ +static void +make_encode_exception(PyObject **exceptionObject, + const char *encoding, + PyObject *unicode, + Py_ssize_t startpos, Py_ssize_t endpos, + const char *reason) +{ + if (*exceptionObject == NULL) { + *exceptionObject = PyObject_CallFunction( + PyExc_UnicodeEncodeError, "sOnns", + encoding, unicode, startpos, endpos, reason); + } + else { + if (PyUnicodeEncodeError_SetStart(*exceptionObject, startpos)) + goto onError; + if (PyUnicodeEncodeError_SetEnd(*exceptionObject, endpos)) + goto onError; + if (PyUnicodeEncodeError_SetReason(*exceptionObject, reason)) + goto onError; + return; + onError: + Py_CLEAR(*exceptionObject); + } +} + +/* raises a UnicodeEncodeError */ +static void +raise_encode_exception(PyObject **exceptionObject, + const char *encoding, + PyObject *unicode, + Py_ssize_t startpos, Py_ssize_t endpos, + const char *reason) +{ + make_encode_exception(exceptionObject, + encoding, unicode, startpos, endpos, reason); + if (*exceptionObject != NULL) + PyCodec_StrictErrors(*exceptionObject); +} + +/* error handling callback helper: + build arguments, call the callback and check the arguments, + put the result into newpos and return the replacement string, which + has to be freed by the caller */ +static PyObject * +unicode_encode_call_errorhandler(const char *errors, + PyObject **errorHandler, + const char *encoding, const char *reason, + PyObject *unicode, PyObject **exceptionObject, + Py_ssize_t startpos, Py_ssize_t endpos, + Py_ssize_t *newpos) +{ + static const char *argparse = "On;encoding error handler must return (str/bytes, int) tuple"; + Py_ssize_t len; + PyObject *restuple; + PyObject *resunicode; + + if (*errorHandler == NULL) { + *errorHandler = PyCodec_LookupError(errors); + if (*errorHandler == NULL) + return NULL; + } + + if (PyUnicode_READY(unicode) == -1) + return NULL; + len = PyUnicode_GET_LENGTH(unicode); + + make_encode_exception(exceptionObject, + encoding, unicode, startpos, endpos, reason); + if (*exceptionObject == NULL) + return NULL; + + restuple = PyObject_CallFunctionObjArgs( + *errorHandler, *exceptionObject, NULL); + if (restuple == NULL) + return NULL; + if (!PyTuple_Check(restuple)) { + PyErr_SetString(PyExc_TypeError, &argparse[3]); + Py_DECREF(restuple); + return NULL; + } + if (!PyArg_ParseTuple(restuple, argparse, + &resunicode, newpos)) { + Py_DECREF(restuple); + return NULL; + } + if (!PyUnicode_Check(resunicode) && !PyBytes_Check(resunicode)) { + PyErr_SetString(PyExc_TypeError, &argparse[3]); + Py_DECREF(restuple); + return NULL; + } + if (*newpos<0) + *newpos = len + *newpos; + if (*newpos<0 || *newpos>len) { + PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos); + Py_DECREF(restuple); + return NULL; + } + Py_INCREF(resunicode); + Py_DECREF(restuple); + return resunicode; +} + +static PyObject * +unicode_encode_ucs1(PyObject *unicode, + const char *errors, + const Py_UCS4 limit) +{ + /* input state */ + Py_ssize_t pos=0, size; + int kind; + void *data; + /* pointer into the output */ + char *str; + const char *encoding = (limit == 256) ? "latin-1" : "ascii"; + const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)"; + PyObject *error_handler_obj = NULL; + PyObject *exc = NULL; + _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; + PyObject *rep = NULL; + /* output object */ + _PyBytesWriter writer; + + if (PyUnicode_READY(unicode) == -1) + return NULL; + size = PyUnicode_GET_LENGTH(unicode); + kind = PyUnicode_KIND(unicode); + data = PyUnicode_DATA(unicode); + /* allocate enough for a simple encoding without + replacements, if we need more, we'll resize */ + if (size == 0) + return PyBytes_FromStringAndSize(NULL, 0); + + _PyBytesWriter_Init(&writer); + str = _PyBytesWriter_Alloc(&writer, size); + if (str == NULL) + return NULL; + + while (pos < size) { + Py_UCS4 ch = PyUnicode_READ(kind, data, pos); + + /* can we encode this? */ + if (ch < limit) { + /* no overflow check, because we know that the space is enough */ + *str++ = (char)ch; + ++pos; + } + else { + Py_ssize_t newpos, i; + /* startpos for collecting unencodable chars */ + Py_ssize_t collstart = pos; + Py_ssize_t collend = collstart + 1; + /* find all unecodable characters */ + + while ((collend < size) && (PyUnicode_READ(kind, data, collend) >= limit)) + ++collend; + + /* Only overallocate the buffer if it's not the last write */ + writer.overallocate = (collend < size); + + /* cache callback name lookup (if not done yet, i.e. it's the first error) */ + if (error_handler == _Py_ERROR_UNKNOWN) + error_handler = _Py_GetErrorHandler(errors); + + switch (error_handler) { + case _Py_ERROR_STRICT: + raise_encode_exception(&exc, encoding, unicode, collstart, collend, reason); + goto onError; + + case _Py_ERROR_REPLACE: + memset(str, '?', collend - collstart); + str += (collend - collstart); + /* fall through */ + case _Py_ERROR_IGNORE: + pos = collend; + break; + + case _Py_ERROR_BACKSLASHREPLACE: + /* subtract preallocated bytes */ + writer.min_size -= (collend - collstart); + str = backslashreplace(&writer, str, + unicode, collstart, collend); + if (str == NULL) + goto onError; + pos = collend; + break; + + case _Py_ERROR_XMLCHARREFREPLACE: + /* subtract preallocated bytes */ + writer.min_size -= (collend - collstart); + str = xmlcharrefreplace(&writer, str, + unicode, collstart, collend); + if (str == NULL) + goto onError; + pos = collend; + break; + + case _Py_ERROR_SURROGATEESCAPE: + for (i = collstart; i < collend; ++i) { + ch = PyUnicode_READ(kind, data, i); + if (ch < 0xdc80 || 0xdcff < ch) { + /* Not a UTF-8b surrogate */ + break; + } + *str++ = (char)(ch - 0xdc00); + ++pos; + } + if (i >= collend) + break; + collstart = pos; + assert(collstart != collend); + /* fall through */ + + default: + rep = unicode_encode_call_errorhandler(errors, &error_handler_obj, + encoding, reason, unicode, &exc, + collstart, collend, &newpos); + if (rep == NULL) + goto onError; + + /* subtract preallocated bytes */ + writer.min_size -= newpos - collstart; + + if (PyBytes_Check(rep)) { + /* Directly copy bytes result to output. */ + str = _PyBytesWriter_WriteBytes(&writer, str, + PyBytes_AS_STRING(rep), + PyBytes_GET_SIZE(rep)); + } + else { + assert(PyUnicode_Check(rep)); + + if (PyUnicode_READY(rep) < 0) + goto onError; + + if (limit == 256 ? + PyUnicode_KIND(rep) != PyUnicode_1BYTE_KIND : + !PyUnicode_IS_ASCII(rep)) + { + /* Not all characters are smaller than limit */ + raise_encode_exception(&exc, encoding, unicode, + collstart, collend, reason); + goto onError; + } + assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); + str = _PyBytesWriter_WriteBytes(&writer, str, + PyUnicode_DATA(rep), + PyUnicode_GET_LENGTH(rep)); + } + if (str == NULL) + goto onError; + + pos = newpos; + Py_CLEAR(rep); + } + + /* If overallocation was disabled, ensure that it was the last + write. Otherwise, we missed an optimization */ + assert(writer.overallocate || pos == size); + } + } + + Py_XDECREF(error_handler_obj); + Py_XDECREF(exc); + return _PyBytesWriter_Finish(&writer, str); + + onError: + Py_XDECREF(rep); + _PyBytesWriter_Dealloc(&writer); + Py_XDECREF(error_handler_obj); + Py_XDECREF(exc); + return NULL; +} + +/* Deprecated */ +PyObject * +PyUnicode_EncodeLatin1(const Py_UNICODE *p, + Py_ssize_t size, + const char *errors) +{ + PyObject *result; + PyObject *unicode = PyUnicode_FromWideChar(p, size); + if (unicode == NULL) + return NULL; + result = unicode_encode_ucs1(unicode, errors, 256); + Py_DECREF(unicode); + return result; +} + +PyObject * +_PyUnicode_AsLatin1String(PyObject *unicode, const char *errors) +{ + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) + return NULL; + /* Fast path: if it is a one-byte string, construct + bytes object directly. */ + if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) + return PyBytes_FromStringAndSize(PyUnicode_DATA(unicode), + PyUnicode_GET_LENGTH(unicode)); + /* Non-Latin-1 characters present. Defer to above function to + raise the exception. */ + return unicode_encode_ucs1(unicode, errors, 256); +} + +PyObject* +PyUnicode_AsLatin1String(PyObject *unicode) +{ + return _PyUnicode_AsLatin1String(unicode, NULL); +} + +/* --- 7-bit ASCII Codec -------------------------------------------------- */ + +PyObject * +PyUnicode_DecodeASCII(const char *s, + Py_ssize_t size, + const char *errors) +{ + const char *starts = s; + _PyUnicodeWriter writer; + int kind; + void *data; + Py_ssize_t startinpos; + Py_ssize_t endinpos; + Py_ssize_t outpos; + const char *e; + PyObject *error_handler_obj = NULL; + PyObject *exc = NULL; + _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; + + if (size == 0) + _Py_RETURN_UNICODE_EMPTY(); + + /* ASCII is equivalent to the first 128 ordinals in Unicode. */ + if (size == 1 && (unsigned char)s[0] < 128) + return get_latin1_char((unsigned char)s[0]); + + _PyUnicodeWriter_Init(&writer); + writer.min_length = size; + if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) < 0) + return NULL; + + e = s + size; + data = writer.data; + outpos = ascii_decode(s, e, (Py_UCS1 *)data); + writer.pos = outpos; + if (writer.pos == size) + return _PyUnicodeWriter_Finish(&writer); + + s += writer.pos; + kind = writer.kind; + while (s < e) { + unsigned char c = (unsigned char)*s; + if (c < 128) { + PyUnicode_WRITE(kind, data, writer.pos, c); + writer.pos++; + ++s; + continue; + } + + /* byte outsize range 0x00..0x7f: call the error handler */ + + if (error_handler == _Py_ERROR_UNKNOWN) + error_handler = _Py_GetErrorHandler(errors); + + switch (error_handler) + { + case _Py_ERROR_REPLACE: + case _Py_ERROR_SURROGATEESCAPE: + /* Fast-path: the error handler only writes one character, + but we may switch to UCS2 at the first write */ + if (_PyUnicodeWriter_PrepareKind(&writer, PyUnicode_2BYTE_KIND) < 0) + goto onError; + kind = writer.kind; + data = writer.data; + + if (error_handler == _Py_ERROR_REPLACE) + PyUnicode_WRITE(kind, data, writer.pos, 0xfffd); + else + PyUnicode_WRITE(kind, data, writer.pos, c + 0xdc00); + writer.pos++; + ++s; + break; + + case _Py_ERROR_IGNORE: + ++s; + break; + + default: + startinpos = s-starts; + endinpos = startinpos + 1; + if (unicode_decode_call_errorhandler_writer( + errors, &error_handler_obj, + "ascii", "ordinal not in range(128)", + &starts, &e, &startinpos, &endinpos, &exc, &s, + &writer)) + goto onError; + kind = writer.kind; + data = writer.data; + } + } + Py_XDECREF(error_handler_obj); + Py_XDECREF(exc); + return _PyUnicodeWriter_Finish(&writer); + + onError: + _PyUnicodeWriter_Dealloc(&writer); + Py_XDECREF(error_handler_obj); + Py_XDECREF(exc); + return NULL; +} + +/* Deprecated */ +PyObject * +PyUnicode_EncodeASCII(const Py_UNICODE *p, + Py_ssize_t size, + const char *errors) +{ + PyObject *result; + PyObject *unicode = PyUnicode_FromWideChar(p, size); + if (unicode == NULL) + return NULL; + result = unicode_encode_ucs1(unicode, errors, 128); + Py_DECREF(unicode); + return result; +} + +PyObject * +_PyUnicode_AsASCIIString(PyObject *unicode, const char *errors) +{ + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) + return NULL; + /* Fast path: if it is an ASCII-only string, construct bytes object + directly. Else defer to above function to raise the exception. */ + if (PyUnicode_IS_ASCII(unicode)) + return PyBytes_FromStringAndSize(PyUnicode_DATA(unicode), + PyUnicode_GET_LENGTH(unicode)); + return unicode_encode_ucs1(unicode, errors, 128); +} + +PyObject * +PyUnicode_AsASCIIString(PyObject *unicode) +{ + return _PyUnicode_AsASCIIString(unicode, NULL); +} + +#ifdef MS_WINDOWS + +/* --- MBCS codecs for Windows -------------------------------------------- */ + +#if SIZEOF_INT < SIZEOF_SIZE_T +#define NEED_RETRY +#endif + +/* INT_MAX is the theoretical largest chunk (or INT_MAX / 2 when + transcoding from UTF-16), but INT_MAX / 4 perfoms better in + both cases also and avoids partial characters overrunning the + length limit in MultiByteToWideChar on Windows */ +#define DECODING_CHUNK_SIZE (INT_MAX/4) + +#ifndef WC_ERR_INVALID_CHARS +# define WC_ERR_INVALID_CHARS 0x0080 +#endif + +static const char* +code_page_name(UINT code_page, PyObject **obj) +{ + *obj = NULL; + if (code_page == CP_ACP) + return "mbcs"; + if (code_page == CP_UTF7) + return "CP_UTF7"; + if (code_page == CP_UTF8) + return "CP_UTF8"; + + *obj = PyBytes_FromFormat("cp%u", code_page); + if (*obj == NULL) + return NULL; + return PyBytes_AS_STRING(*obj); +} + +static DWORD +decode_code_page_flags(UINT code_page) +{ + if (code_page == CP_UTF7) { + /* The CP_UTF7 decoder only supports flags=0 */ + return 0; + } + else + return MB_ERR_INVALID_CHARS; +} + +/* + * Decode a byte string from a Windows code page into unicode object in strict + * mode. + * + * Returns consumed size if succeed, returns -2 on decode error, or raise an + * OSError and returns -1 on other error. + */ +static int +decode_code_page_strict(UINT code_page, + wchar_t **buf, + Py_ssize_t *bufsize, + const char *in, + int insize) +{ + DWORD flags = MB_ERR_INVALID_CHARS; + wchar_t *out; + DWORD outsize; + + /* First get the size of the result */ + assert(insize > 0); + while ((outsize = MultiByteToWideChar(code_page, flags, + in, insize, NULL, 0)) <= 0) + { + if (!flags || GetLastError() != ERROR_INVALID_FLAGS) { + goto error; + } + /* For some code pages (e.g. UTF-7) flags must be set to 0. */ + flags = 0; + } + + /* Extend a wchar_t* buffer */ + Py_ssize_t n = *bufsize; /* Get the current length */ + if (widechar_resize(buf, bufsize, n + outsize) < 0) { + return -1; + } + out = *buf + n; + + /* Do the conversion */ + outsize = MultiByteToWideChar(code_page, flags, in, insize, out, outsize); + if (outsize <= 0) + goto error; + return insize; + +error: + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) + return -2; + PyErr_SetFromWindowsErr(0); + return -1; +} + +/* + * Decode a byte string from a code page into unicode object with an error + * handler. + * + * Returns consumed size if succeed, or raise an OSError or + * UnicodeDecodeError exception and returns -1 on error. + */ +static int +decode_code_page_errors(UINT code_page, + wchar_t **buf, + Py_ssize_t *bufsize, + const char *in, const int size, + const char *errors, int final) +{ + const char *startin = in; + const char *endin = in + size; + DWORD flags = MB_ERR_INVALID_CHARS; + /* Ideally, we should get reason from FormatMessage. This is the Windows + 2000 English version of the message. */ + const char *reason = "No mapping for the Unicode character exists " + "in the target code page."; + /* each step cannot decode more than 1 character, but a character can be + represented as a surrogate pair */ + wchar_t buffer[2], *out; + int insize; + Py_ssize_t outsize; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + PyObject *encoding_obj = NULL; + const char *encoding; + DWORD err; + int ret = -1; + + assert(size > 0); + + encoding = code_page_name(code_page, &encoding_obj); + if (encoding == NULL) + return -1; + + if ((errors == NULL || strcmp(errors, "strict") == 0) && final) { + /* The last error was ERROR_NO_UNICODE_TRANSLATION, then we raise a + UnicodeDecodeError. */ + make_decode_exception(&exc, encoding, in, size, 0, 0, reason); + if (exc != NULL) { + PyCodec_StrictErrors(exc); + Py_CLEAR(exc); + } + goto error; + } + + /* Extend a wchar_t* buffer */ + Py_ssize_t n = *bufsize; /* Get the current length */ + if (size > (PY_SSIZE_T_MAX - n) / (Py_ssize_t)Py_ARRAY_LENGTH(buffer)) { + PyErr_NoMemory(); + goto error; + } + if (widechar_resize(buf, bufsize, n + size * Py_ARRAY_LENGTH(buffer)) < 0) { + goto error; + } + out = *buf + n; + + /* Decode the byte string character per character */ + while (in < endin) + { + /* Decode a character */ + insize = 1; + do + { + outsize = MultiByteToWideChar(code_page, flags, + in, insize, + buffer, Py_ARRAY_LENGTH(buffer)); + if (outsize > 0) + break; + err = GetLastError(); + if (err == ERROR_INVALID_FLAGS && flags) { + /* For some code pages (e.g. UTF-7) flags must be set to 0. */ + flags = 0; + continue; + } + if (err != ERROR_NO_UNICODE_TRANSLATION + && err != ERROR_INSUFFICIENT_BUFFER) + { + PyErr_SetFromWindowsErr(0); + goto error; + } + insize++; + } + /* 4=maximum length of a UTF-8 sequence */ + while (insize <= 4 && (in + insize) <= endin); + + if (outsize <= 0) { + Py_ssize_t startinpos, endinpos, outpos; + + /* last character in partial decode? */ + if (in + insize >= endin && !final) + break; + + startinpos = in - startin; + endinpos = startinpos + 1; + outpos = out - *buf; + if (unicode_decode_call_errorhandler_wchar( + errors, &errorHandler, + encoding, reason, + &startin, &endin, &startinpos, &endinpos, &exc, &in, + buf, bufsize, &outpos)) + { + goto error; + } + out = *buf + outpos; + } + else { + in += insize; + memcpy(out, buffer, outsize * sizeof(wchar_t)); + out += outsize; + } + } + + /* Shrink the buffer */ + assert(out - *buf <= *bufsize); + *bufsize = out - *buf; + /* (in - startin) <= size and size is an int */ + ret = Py_SAFE_DOWNCAST(in - startin, Py_ssize_t, int); + +error: + Py_XDECREF(encoding_obj); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return ret; +} + +static PyObject * +decode_code_page_stateful(int code_page, + const char *s, Py_ssize_t size, + const char *errors, Py_ssize_t *consumed) +{ + wchar_t *buf = NULL; + Py_ssize_t bufsize = 0; + int chunk_size, final, converted, done; + + if (code_page < 0) { + PyErr_SetString(PyExc_ValueError, "invalid code page number"); + return NULL; + } + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } + + if (consumed) + *consumed = 0; + + do + { +#ifdef NEED_RETRY + if (size > DECODING_CHUNK_SIZE) { + chunk_size = DECODING_CHUNK_SIZE; + final = 0; + done = 0; + } + else +#endif + { + chunk_size = (int)size; + final = (consumed == NULL); + done = 1; + } + + if (chunk_size == 0 && done) { + if (buf != NULL) + break; + _Py_RETURN_UNICODE_EMPTY(); + } + + converted = decode_code_page_strict(code_page, &buf, &bufsize, + s, chunk_size); + if (converted == -2) + converted = decode_code_page_errors(code_page, &buf, &bufsize, + s, chunk_size, + errors, final); + assert(converted != 0 || done); + + if (converted < 0) { + PyMem_Free(buf); + return NULL; + } + + if (consumed) + *consumed += converted; + + s += converted; + size -= converted; + } while (!done); + + PyObject *v = PyUnicode_FromWideChar(buf, bufsize); + PyMem_Free(buf); + return v; +} + +PyObject * +PyUnicode_DecodeCodePageStateful(int code_page, + const char *s, + Py_ssize_t size, + const char *errors, + Py_ssize_t *consumed) +{ + return decode_code_page_stateful(code_page, s, size, errors, consumed); +} + +PyObject * +PyUnicode_DecodeMBCSStateful(const char *s, + Py_ssize_t size, + const char *errors, + Py_ssize_t *consumed) +{ + return decode_code_page_stateful(CP_ACP, s, size, errors, consumed); +} + +PyObject * +PyUnicode_DecodeMBCS(const char *s, + Py_ssize_t size, + const char *errors) +{ + return PyUnicode_DecodeMBCSStateful(s, size, errors, NULL); +} + +static DWORD +encode_code_page_flags(UINT code_page, const char *errors) +{ + if (code_page == CP_UTF8) { + return WC_ERR_INVALID_CHARS; + } + else if (code_page == CP_UTF7) { + /* CP_UTF7 only supports flags=0 */ + return 0; + } + else { + if (errors != NULL && strcmp(errors, "replace") == 0) + return 0; + else + return WC_NO_BEST_FIT_CHARS; + } +} + +/* + * Encode a Unicode string to a Windows code page into a byte string in strict + * mode. + * + * Returns consumed characters if succeed, returns -2 on encode error, or raise + * an OSError and returns -1 on other error. + */ +static int +encode_code_page_strict(UINT code_page, PyObject **outbytes, + PyObject *unicode, Py_ssize_t offset, int len, + const char* errors) +{ + BOOL usedDefaultChar = FALSE; + BOOL *pusedDefaultChar = &usedDefaultChar; + int outsize; + wchar_t *p; + Py_ssize_t size; + const DWORD flags = encode_code_page_flags(code_page, NULL); + char *out; + /* Create a substring so that we can get the UTF-16 representation + of just the slice under consideration. */ + PyObject *substring; + + assert(len > 0); + + if (code_page != CP_UTF8 && code_page != CP_UTF7) + pusedDefaultChar = &usedDefaultChar; + else + pusedDefaultChar = NULL; + + substring = PyUnicode_Substring(unicode, offset, offset+len); + if (substring == NULL) + return -1; + p = PyUnicode_AsUnicodeAndSize(substring, &size); + if (p == NULL) { + Py_DECREF(substring); + return -1; + } + assert(size <= INT_MAX); + + /* First get the size of the result */ + outsize = WideCharToMultiByte(code_page, flags, + p, (int)size, + NULL, 0, + NULL, pusedDefaultChar); + if (outsize <= 0) + goto error; + /* If we used a default char, then we failed! */ + if (pusedDefaultChar && *pusedDefaultChar) { + Py_DECREF(substring); + return -2; + } + + if (*outbytes == NULL) { + /* Create string object */ + *outbytes = PyBytes_FromStringAndSize(NULL, outsize); + if (*outbytes == NULL) { + Py_DECREF(substring); + return -1; + } + out = PyBytes_AS_STRING(*outbytes); + } + else { + /* Extend string object */ + const Py_ssize_t n = PyBytes_Size(*outbytes); + if (outsize > PY_SSIZE_T_MAX - n) { + PyErr_NoMemory(); + Py_DECREF(substring); + return -1; + } + if (_PyBytes_Resize(outbytes, n + outsize) < 0) { + Py_DECREF(substring); + return -1; + } + out = PyBytes_AS_STRING(*outbytes) + n; + } + + /* Do the conversion */ + outsize = WideCharToMultiByte(code_page, flags, + p, (int)size, + out, outsize, + NULL, pusedDefaultChar); + Py_CLEAR(substring); + if (outsize <= 0) + goto error; + if (pusedDefaultChar && *pusedDefaultChar) + return -2; + return 0; + +error: + Py_XDECREF(substring); + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) + return -2; + PyErr_SetFromWindowsErr(0); + return -1; +} + +/* + * Encode a Unicode string to a Windows code page into a byte string using an + * error handler. + * + * Returns consumed characters if succeed, or raise an OSError and returns + * -1 on other error. + */ +static int +encode_code_page_errors(UINT code_page, PyObject **outbytes, + PyObject *unicode, Py_ssize_t unicode_offset, + Py_ssize_t insize, const char* errors) +{ + const DWORD flags = encode_code_page_flags(code_page, errors); + Py_ssize_t pos = unicode_offset; + Py_ssize_t endin = unicode_offset + insize; + /* Ideally, we should get reason from FormatMessage. This is the Windows + 2000 English version of the message. */ + const char *reason = "invalid character"; + /* 4=maximum length of a UTF-8 sequence */ + char buffer[4]; + BOOL usedDefaultChar = FALSE, *pusedDefaultChar; + Py_ssize_t outsize; + char *out; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + PyObject *encoding_obj = NULL; + const char *encoding; + Py_ssize_t newpos, newoutsize; + PyObject *rep; + int ret = -1; + + assert(insize > 0); + + encoding = code_page_name(code_page, &encoding_obj); + if (encoding == NULL) + return -1; + + if (errors == NULL || strcmp(errors, "strict") == 0) { + /* The last error was ERROR_NO_UNICODE_TRANSLATION, + then we raise a UnicodeEncodeError. */ + make_encode_exception(&exc, encoding, unicode, 0, 0, reason); + if (exc != NULL) { + PyCodec_StrictErrors(exc); + Py_DECREF(exc); + } + Py_XDECREF(encoding_obj); + return -1; + } + + if (code_page != CP_UTF8 && code_page != CP_UTF7) + pusedDefaultChar = &usedDefaultChar; + else + pusedDefaultChar = NULL; + + if (Py_ARRAY_LENGTH(buffer) > PY_SSIZE_T_MAX / insize) { + PyErr_NoMemory(); + goto error; + } + outsize = insize * Py_ARRAY_LENGTH(buffer); + + if (*outbytes == NULL) { + /* Create string object */ + *outbytes = PyBytes_FromStringAndSize(NULL, outsize); + if (*outbytes == NULL) + goto error; + out = PyBytes_AS_STRING(*outbytes); + } + else { + /* Extend string object */ + Py_ssize_t n = PyBytes_Size(*outbytes); + if (n > PY_SSIZE_T_MAX - outsize) { + PyErr_NoMemory(); + goto error; + } + if (_PyBytes_Resize(outbytes, n + outsize) < 0) + goto error; + out = PyBytes_AS_STRING(*outbytes) + n; + } + + /* Encode the string character per character */ + while (pos < endin) + { + Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, pos); + wchar_t chars[2]; + int charsize; + if (ch < 0x10000) { + chars[0] = (wchar_t)ch; + charsize = 1; + } + else { + chars[0] = Py_UNICODE_HIGH_SURROGATE(ch); + chars[1] = Py_UNICODE_LOW_SURROGATE(ch); + charsize = 2; + } + + outsize = WideCharToMultiByte(code_page, flags, + chars, charsize, + buffer, Py_ARRAY_LENGTH(buffer), + NULL, pusedDefaultChar); + if (outsize > 0) { + if (pusedDefaultChar == NULL || !(*pusedDefaultChar)) + { + pos++; + memcpy(out, buffer, outsize); + out += outsize; + continue; + } + } + else if (GetLastError() != ERROR_NO_UNICODE_TRANSLATION) { + PyErr_SetFromWindowsErr(0); + goto error; + } + + rep = unicode_encode_call_errorhandler( + errors, &errorHandler, encoding, reason, + unicode, &exc, + pos, pos + 1, &newpos); + if (rep == NULL) + goto error; + pos = newpos; + + if (PyBytes_Check(rep)) { + outsize = PyBytes_GET_SIZE(rep); + if (outsize != 1) { + Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes); + newoutsize = PyBytes_GET_SIZE(*outbytes) + (outsize - 1); + if (_PyBytes_Resize(outbytes, newoutsize) < 0) { + Py_DECREF(rep); + goto error; + } + out = PyBytes_AS_STRING(*outbytes) + offset; + } + memcpy(out, PyBytes_AS_STRING(rep), outsize); + out += outsize; + } + else { + Py_ssize_t i; + enum PyUnicode_Kind kind; + void *data; + + if (PyUnicode_READY(rep) == -1) { + Py_DECREF(rep); + goto error; + } + + outsize = PyUnicode_GET_LENGTH(rep); + if (outsize != 1) { + Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes); + newoutsize = PyBytes_GET_SIZE(*outbytes) + (outsize - 1); + if (_PyBytes_Resize(outbytes, newoutsize) < 0) { + Py_DECREF(rep); + goto error; + } + out = PyBytes_AS_STRING(*outbytes) + offset; + } + kind = PyUnicode_KIND(rep); + data = PyUnicode_DATA(rep); + for (i=0; i < outsize; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (ch > 127) { + raise_encode_exception(&exc, + encoding, unicode, + pos, pos + 1, + "unable to encode error handler result to ASCII"); + Py_DECREF(rep); + goto error; + } + *out = (unsigned char)ch; + out++; + } + } + Py_DECREF(rep); + } + /* write a NUL byte */ + *out = 0; + outsize = out - PyBytes_AS_STRING(*outbytes); + assert(outsize <= PyBytes_GET_SIZE(*outbytes)); + if (_PyBytes_Resize(outbytes, outsize) < 0) + goto error; + ret = 0; + +error: + Py_XDECREF(encoding_obj); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return ret; +} + +static PyObject * +encode_code_page(int code_page, + PyObject *unicode, + const char *errors) +{ + Py_ssize_t len; + PyObject *outbytes = NULL; + Py_ssize_t offset; + int chunk_len, ret, done; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + + if (PyUnicode_READY(unicode) == -1) + return NULL; + len = PyUnicode_GET_LENGTH(unicode); + + if (code_page < 0) { + PyErr_SetString(PyExc_ValueError, "invalid code page number"); + return NULL; + } + + if (len == 0) + return PyBytes_FromStringAndSize(NULL, 0); + + offset = 0; + do + { +#ifdef NEED_RETRY + if (len > DECODING_CHUNK_SIZE) { + chunk_len = DECODING_CHUNK_SIZE; + done = 0; + } + else +#endif + { + chunk_len = (int)len; + done = 1; + } + + ret = encode_code_page_strict(code_page, &outbytes, + unicode, offset, chunk_len, + errors); + if (ret == -2) + ret = encode_code_page_errors(code_page, &outbytes, + unicode, offset, + chunk_len, errors); + if (ret < 0) { + Py_XDECREF(outbytes); + return NULL; + } + + offset += chunk_len; + len -= chunk_len; + } while (!done); + + return outbytes; +} + +PyObject * +PyUnicode_EncodeMBCS(const Py_UNICODE *p, + Py_ssize_t size, + const char *errors) +{ + PyObject *unicode, *res; + unicode = PyUnicode_FromWideChar(p, size); + if (unicode == NULL) + return NULL; + res = encode_code_page(CP_ACP, unicode, errors); + Py_DECREF(unicode); + return res; +} + +PyObject * +PyUnicode_EncodeCodePage(int code_page, + PyObject *unicode, + const char *errors) +{ + return encode_code_page(code_page, unicode, errors); +} + +PyObject * +PyUnicode_AsMBCSString(PyObject *unicode) +{ + return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); +} + +#undef NEED_RETRY + +#endif /* MS_WINDOWS */ + +/* --- Character Mapping Codec -------------------------------------------- */ + +static int +charmap_decode_string(const char *s, + Py_ssize_t size, + PyObject *mapping, + const char *errors, + _PyUnicodeWriter *writer) +{ + const char *starts = s; + const char *e; + Py_ssize_t startinpos, endinpos; + PyObject *errorHandler = NULL, *exc = NULL; + Py_ssize_t maplen; + enum PyUnicode_Kind mapkind; + void *mapdata; + Py_UCS4 x; + unsigned char ch; + + if (PyUnicode_READY(mapping) == -1) + return -1; + + maplen = PyUnicode_GET_LENGTH(mapping); + mapdata = PyUnicode_DATA(mapping); + mapkind = PyUnicode_KIND(mapping); + + e = s + size; + + if (mapkind == PyUnicode_1BYTE_KIND && maplen >= 256) { + /* fast-path for cp037, cp500 and iso8859_1 encodings. iso8859_1 + * is disabled in encoding aliases, latin1 is preferred because + * its implementation is faster. */ + Py_UCS1 *mapdata_ucs1 = (Py_UCS1 *)mapdata; + Py_UCS1 *outdata = (Py_UCS1 *)writer->data; + Py_UCS4 maxchar = writer->maxchar; + + assert (writer->kind == PyUnicode_1BYTE_KIND); + while (s < e) { + ch = *s; + x = mapdata_ucs1[ch]; + if (x > maxchar) { + if (_PyUnicodeWriter_Prepare(writer, 1, 0xff) == -1) + goto onError; + maxchar = writer->maxchar; + outdata = (Py_UCS1 *)writer->data; + } + outdata[writer->pos] = x; + writer->pos++; + ++s; + } + return 0; + } + + while (s < e) { + if (mapkind == PyUnicode_2BYTE_KIND && maplen >= 256) { + enum PyUnicode_Kind outkind = writer->kind; + Py_UCS2 *mapdata_ucs2 = (Py_UCS2 *)mapdata; + if (outkind == PyUnicode_1BYTE_KIND) { + Py_UCS1 *outdata = (Py_UCS1 *)writer->data; + Py_UCS4 maxchar = writer->maxchar; + while (s < e) { + ch = *s; + x = mapdata_ucs2[ch]; + if (x > maxchar) + goto Error; + outdata[writer->pos] = x; + writer->pos++; + ++s; + } + break; + } + else if (outkind == PyUnicode_2BYTE_KIND) { + Py_UCS2 *outdata = (Py_UCS2 *)writer->data; + while (s < e) { + ch = *s; + x = mapdata_ucs2[ch]; + if (x == 0xFFFE) + goto Error; + outdata[writer->pos] = x; + writer->pos++; + ++s; + } + break; + } + } + ch = *s; + + if (ch < maplen) + x = PyUnicode_READ(mapkind, mapdata, ch); + else + x = 0xfffe; /* invalid value */ +Error: + if (x == 0xfffe) + { + /* undefined mapping */ + startinpos = s-starts; + endinpos = startinpos+1; + if (unicode_decode_call_errorhandler_writer( + errors, &errorHandler, + "charmap", "character maps to ", + &starts, &e, &startinpos, &endinpos, &exc, &s, + writer)) { + goto onError; + } + continue; + } + + if (_PyUnicodeWriter_WriteCharInline(writer, x) < 0) + goto onError; + ++s; + } + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return 0; + +onError: + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return -1; +} + +static int +charmap_decode_mapping(const char *s, + Py_ssize_t size, + PyObject *mapping, + const char *errors, + _PyUnicodeWriter *writer) +{ + const char *starts = s; + const char *e; + Py_ssize_t startinpos, endinpos; + PyObject *errorHandler = NULL, *exc = NULL; + unsigned char ch; + PyObject *key, *item = NULL; + + e = s + size; + + while (s < e) { + ch = *s; + + /* Get mapping (char ordinal -> integer, Unicode char or None) */ + key = PyLong_FromLong((long)ch); + if (key == NULL) + goto onError; + + item = PyObject_GetItem(mapping, key); + Py_DECREF(key); + if (item == NULL) { + if (PyErr_ExceptionMatches(PyExc_LookupError)) { + /* No mapping found means: mapping is undefined. */ + PyErr_Clear(); + goto Undefined; + } else + goto onError; + } + + /* Apply mapping */ + if (item == Py_None) + goto Undefined; + if (PyLong_Check(item)) { + long value = PyLong_AS_LONG(item); + if (value == 0xFFFE) + goto Undefined; + if (value < 0 || value > MAX_UNICODE) { + PyErr_Format(PyExc_TypeError, + "character mapping must be in range(0x%x)", + (unsigned long)MAX_UNICODE + 1); + goto onError; + } + + if (_PyUnicodeWriter_WriteCharInline(writer, value) < 0) + goto onError; + } + else if (PyUnicode_Check(item)) { + if (PyUnicode_READY(item) == -1) + goto onError; + if (PyUnicode_GET_LENGTH(item) == 1) { + Py_UCS4 value = PyUnicode_READ_CHAR(item, 0); + if (value == 0xFFFE) + goto Undefined; + if (_PyUnicodeWriter_WriteCharInline(writer, value) < 0) + goto onError; + } + else { + writer->overallocate = 1; + if (_PyUnicodeWriter_WriteStr(writer, item) == -1) + goto onError; + } + } + else { + /* wrong return value */ + PyErr_SetString(PyExc_TypeError, + "character mapping must return integer, None or str"); + goto onError; + } + Py_CLEAR(item); + ++s; + continue; + +Undefined: + /* undefined mapping */ + Py_CLEAR(item); + startinpos = s-starts; + endinpos = startinpos+1; + if (unicode_decode_call_errorhandler_writer( + errors, &errorHandler, + "charmap", "character maps to ", + &starts, &e, &startinpos, &endinpos, &exc, &s, + writer)) { + goto onError; + } + } + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return 0; + +onError: + Py_XDECREF(item); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + return -1; +} + +PyObject * +PyUnicode_DecodeCharmap(const char *s, + Py_ssize_t size, + PyObject *mapping, + const char *errors) +{ + _PyUnicodeWriter writer; + + /* Default to Latin-1 */ + if (mapping == NULL) + return PyUnicode_DecodeLatin1(s, size, errors); + + if (size == 0) + _Py_RETURN_UNICODE_EMPTY(); + _PyUnicodeWriter_Init(&writer); + writer.min_length = size; + if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) == -1) + goto onError; + + if (PyUnicode_CheckExact(mapping)) { + if (charmap_decode_string(s, size, mapping, errors, &writer) < 0) + goto onError; + } + else { + if (charmap_decode_mapping(s, size, mapping, errors, &writer) < 0) + goto onError; + } + return _PyUnicodeWriter_Finish(&writer); + + onError: + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + +/* Charmap encoding: the lookup table */ + +struct encoding_map { + PyObject_HEAD + unsigned char level1[32]; + int count2, count3; + unsigned char level23[1]; +}; + +static PyObject* +encoding_map_size(PyObject *obj, PyObject* args) +{ + struct encoding_map *map = (struct encoding_map*)obj; + return PyLong_FromLong(sizeof(*map) - 1 + 16*map->count2 + + 128*map->count3); +} + +static PyMethodDef encoding_map_methods[] = { + {"size", encoding_map_size, METH_NOARGS, + PyDoc_STR("Return the size (in bytes) of this object") }, + { 0 } +}; + +static PyTypeObject EncodingMapType = { + PyVarObject_HEAD_INIT(NULL, 0) + "EncodingMap", /*tp_name*/ + sizeof(struct encoding_map), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + 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*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + encoding_map_methods, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +PyObject* +PyUnicode_BuildEncodingMap(PyObject* string) +{ + PyObject *result; + struct encoding_map *mresult; + int i; + int need_dict = 0; + unsigned char level1[32]; + unsigned char level2[512]; + unsigned char *mlevel1, *mlevel2, *mlevel3; + int count2 = 0, count3 = 0; + int kind; + void *data; + Py_ssize_t length; + Py_UCS4 ch; + + if (!PyUnicode_Check(string) || !PyUnicode_GET_LENGTH(string)) { + PyErr_BadArgument(); + return NULL; + } + kind = PyUnicode_KIND(string); + data = PyUnicode_DATA(string); + length = PyUnicode_GET_LENGTH(string); + length = Py_MIN(length, 256); + memset(level1, 0xFF, sizeof level1); + memset(level2, 0xFF, sizeof level2); + + /* If there isn't a one-to-one mapping of NULL to \0, + or if there are non-BMP characters, we need to use + a mapping dictionary. */ + if (PyUnicode_READ(kind, data, 0) != 0) + need_dict = 1; + for (i = 1; i < length; i++) { + int l1, l2; + ch = PyUnicode_READ(kind, data, i); + if (ch == 0 || ch > 0xFFFF) { + need_dict = 1; + break; + } + if (ch == 0xFFFE) + /* unmapped character */ + continue; + l1 = ch >> 11; + l2 = ch >> 7; + if (level1[l1] == 0xFF) + level1[l1] = count2++; + if (level2[l2] == 0xFF) + level2[l2] = count3++; + } + + if (count2 >= 0xFF || count3 >= 0xFF) + need_dict = 1; + + if (need_dict) { + PyObject *result = PyDict_New(); + PyObject *key, *value; + if (!result) + return NULL; + for (i = 0; i < length; i++) { + key = PyLong_FromLong(PyUnicode_READ(kind, data, i)); + value = PyLong_FromLong(i); + if (!key || !value) + goto failed1; + if (PyDict_SetItem(result, key, value) == -1) + goto failed1; + Py_DECREF(key); + Py_DECREF(value); + } + return result; + failed1: + Py_XDECREF(key); + Py_XDECREF(value); + Py_DECREF(result); + return NULL; + } + + /* Create a three-level trie */ + result = PyObject_MALLOC(sizeof(struct encoding_map) + + 16*count2 + 128*count3 - 1); + if (!result) + return PyErr_NoMemory(); + PyObject_Init(result, &EncodingMapType); + mresult = (struct encoding_map*)result; + mresult->count2 = count2; + mresult->count3 = count3; + mlevel1 = mresult->level1; + mlevel2 = mresult->level23; + mlevel3 = mresult->level23 + 16*count2; + memcpy(mlevel1, level1, 32); + memset(mlevel2, 0xFF, 16*count2); + memset(mlevel3, 0, 128*count3); + count3 = 0; + for (i = 1; i < length; i++) { + int o1, o2, o3, i2, i3; + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (ch == 0xFFFE) + /* unmapped character */ + continue; + o1 = ch>>11; + o2 = (ch>>7) & 0xF; + i2 = 16*mlevel1[o1] + o2; + if (mlevel2[i2] == 0xFF) + mlevel2[i2] = count3++; + o3 = ch & 0x7F; + i3 = 128*mlevel2[i2] + o3; + mlevel3[i3] = i; + } + return result; +} + +static int +encoding_map_lookup(Py_UCS4 c, PyObject *mapping) +{ + struct encoding_map *map = (struct encoding_map*)mapping; + int l1 = c>>11; + int l2 = (c>>7) & 0xF; + int l3 = c & 0x7F; + int i; + + if (c > 0xFFFF) + return -1; + if (c == 0) + return 0; + /* level 1*/ + i = map->level1[l1]; + if (i == 0xFF) { + return -1; + } + /* level 2*/ + i = map->level23[16*i+l2]; + if (i == 0xFF) { + return -1; + } + /* level 3 */ + i = map->level23[16*map->count2 + 128*i + l3]; + if (i == 0) { + return -1; + } + return i; +} + +/* Lookup the character ch in the mapping. If the character + can't be found, Py_None is returned (or NULL, if another + error occurred). */ +static PyObject * +charmapencode_lookup(Py_UCS4 c, PyObject *mapping) +{ + PyObject *w = PyLong_FromLong((long)c); + PyObject *x; + + if (w == NULL) + return NULL; + x = PyObject_GetItem(mapping, w); + Py_DECREF(w); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_LookupError)) { + /* No mapping found means: mapping is undefined. */ + PyErr_Clear(); + Py_RETURN_NONE; + } else + return NULL; + } + else if (x == Py_None) + return x; + else if (PyLong_Check(x)) { + long value = PyLong_AS_LONG(x); + if (value < 0 || value > 255) { + PyErr_SetString(PyExc_TypeError, + "character mapping must be in range(256)"); + Py_DECREF(x); + return NULL; + } + return x; + } + else if (PyBytes_Check(x)) + return x; + else { + /* wrong return value */ + PyErr_Format(PyExc_TypeError, + "character mapping must return integer, bytes or None, not %.400s", + x->ob_type->tp_name); + Py_DECREF(x); + return NULL; + } +} + +static int +charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize) +{ + Py_ssize_t outsize = PyBytes_GET_SIZE(*outobj); + /* exponentially overallocate to minimize reallocations */ + if (requiredsize < 2*outsize) + requiredsize = 2*outsize; + if (_PyBytes_Resize(outobj, requiredsize)) + return -1; + return 0; +} + +typedef enum charmapencode_result { + enc_SUCCESS, enc_FAILED, enc_EXCEPTION +} charmapencode_result; +/* lookup the character, put the result in the output string and adjust + various state variables. Resize the output bytes object if not enough + space is available. Return a new reference to the object that + was put in the output buffer, or Py_None, if the mapping was undefined + (in which case no character was written) or NULL, if a + reallocation error occurred. The caller must decref the result */ +static charmapencode_result +charmapencode_output(Py_UCS4 c, PyObject *mapping, + PyObject **outobj, Py_ssize_t *outpos) +{ + PyObject *rep; + char *outstart; + Py_ssize_t outsize = PyBytes_GET_SIZE(*outobj); + + if (Py_TYPE(mapping) == &EncodingMapType) { + int res = encoding_map_lookup(c, mapping); + Py_ssize_t requiredsize = *outpos+1; + if (res == -1) + return enc_FAILED; + if (outsize outsize) + /* Make room for all additional bytes. */ + if (charmapencode_resize(res, respos, requiredsize)) { + Py_DECREF(repunicode); + return -1; + } + memcpy(PyBytes_AsString(*res) + *respos, + PyBytes_AsString(repunicode), repsize); + *respos += repsize; + *inpos = newpos; + Py_DECREF(repunicode); + break; + } + /* generate replacement */ + if (PyUnicode_READY(repunicode) == -1) { + Py_DECREF(repunicode); + return -1; + } + repsize = PyUnicode_GET_LENGTH(repunicode); + data = PyUnicode_DATA(repunicode); + kind = PyUnicode_KIND(repunicode); + for (index = 0; index < repsize; index++) { + Py_UCS4 repch = PyUnicode_READ(kind, data, index); + x = charmapencode_output(repch, mapping, res, respos); + if (x==enc_EXCEPTION) { + Py_DECREF(repunicode); + return -1; + } + else if (x==enc_FAILED) { + Py_DECREF(repunicode); + raise_encode_exception(exceptionObject, encoding, unicode, collstartpos, collendpos, reason); + return -1; + } + } + *inpos = newpos; + Py_DECREF(repunicode); + } + return 0; +} + +PyObject * +_PyUnicode_EncodeCharmap(PyObject *unicode, + PyObject *mapping, + const char *errors) +{ + /* output object */ + PyObject *res = NULL; + /* current input position */ + Py_ssize_t inpos = 0; + Py_ssize_t size; + /* current output position */ + Py_ssize_t respos = 0; + PyObject *error_handler_obj = NULL; + PyObject *exc = NULL; + _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; + void *data; + int kind; + + if (PyUnicode_READY(unicode) == -1) + return NULL; + size = PyUnicode_GET_LENGTH(unicode); + data = PyUnicode_DATA(unicode); + kind = PyUnicode_KIND(unicode); + + /* Default to Latin-1 */ + if (mapping == NULL) + return unicode_encode_ucs1(unicode, errors, 256); + + /* allocate enough for a simple encoding without + replacements, if we need more, we'll resize */ + res = PyBytes_FromStringAndSize(NULL, size); + if (res == NULL) + goto onError; + if (size == 0) + return res; + + while (inpos adjust input position */ + ++inpos; + } + + /* Resize if we allocated to much */ + if (resposPyUnicode_GET_LENGTH(unicode)) { + PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos); + Py_DECREF(restuple); + return NULL; + } + Py_INCREF(resunicode); + Py_DECREF(restuple); + return resunicode; +} + +/* Lookup the character ch in the mapping and put the result in result, + which must be decrefed by the caller. + Return 0 on success, -1 on error */ +static int +charmaptranslate_lookup(Py_UCS4 c, PyObject *mapping, PyObject **result) +{ + PyObject *w = PyLong_FromLong((long)c); + PyObject *x; + + if (w == NULL) + return -1; + x = PyObject_GetItem(mapping, w); + Py_DECREF(w); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_LookupError)) { + /* No mapping found means: use 1:1 mapping. */ + PyErr_Clear(); + *result = NULL; + return 0; + } else + return -1; + } + else if (x == Py_None) { + *result = x; + return 0; + } + else if (PyLong_Check(x)) { + long value = PyLong_AS_LONG(x); + if (value < 0 || value > MAX_UNICODE) { + PyErr_Format(PyExc_ValueError, + "character mapping must be in range(0x%x)", + MAX_UNICODE+1); + Py_DECREF(x); + return -1; + } + *result = x; + return 0; + } + else if (PyUnicode_Check(x)) { + *result = x; + return 0; + } + else { + /* wrong return value */ + PyErr_SetString(PyExc_TypeError, + "character mapping must return integer, None or str"); + Py_DECREF(x); + return -1; + } +} + +/* lookup the character, write the result into the writer. + Return 1 if the result was written into the writer, return 0 if the mapping + was undefined, raise an exception return -1 on error. */ +static int +charmaptranslate_output(Py_UCS4 ch, PyObject *mapping, + _PyUnicodeWriter *writer) +{ + PyObject *item; + + if (charmaptranslate_lookup(ch, mapping, &item)) + return -1; + + if (item == NULL) { + /* not found => default to 1:1 mapping */ + if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0) { + return -1; + } + return 1; + } + + if (item == Py_None) { + Py_DECREF(item); + return 0; + } + + if (PyLong_Check(item)) { + long ch = (Py_UCS4)PyLong_AS_LONG(item); + /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already + used it */ + if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0) { + Py_DECREF(item); + return -1; + } + Py_DECREF(item); + return 1; + } + + if (!PyUnicode_Check(item)) { + Py_DECREF(item); + return -1; + } + + if (_PyUnicodeWriter_WriteStr(writer, item) < 0) { + Py_DECREF(item); + return -1; + } + + Py_DECREF(item); + return 1; +} + +static int +unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch, + Py_UCS1 *translate) +{ + PyObject *item = NULL; + int ret = 0; + + if (charmaptranslate_lookup(ch, mapping, &item)) { + return -1; + } + + if (item == Py_None) { + /* deletion */ + translate[ch] = 0xfe; + } + else if (item == NULL) { + /* not found => default to 1:1 mapping */ + translate[ch] = ch; + return 1; + } + else if (PyLong_Check(item)) { + long replace = PyLong_AS_LONG(item); + /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already + used it */ + if (127 < replace) { + /* invalid character or character outside ASCII: + skip the fast translate */ + goto exit; + } + translate[ch] = (Py_UCS1)replace; + } + else if (PyUnicode_Check(item)) { + Py_UCS4 replace; + + if (PyUnicode_READY(item) == -1) { + Py_DECREF(item); + return -1; + } + if (PyUnicode_GET_LENGTH(item) != 1) + goto exit; + + replace = PyUnicode_READ_CHAR(item, 0); + if (replace > 127) + goto exit; + translate[ch] = (Py_UCS1)replace; + } + else { + /* not None, NULL, long or unicode */ + goto exit; + } + ret = 1; + + exit: + Py_DECREF(item); + return ret; +} + +/* Fast path for ascii => ascii translation. Return 1 if the whole string + was translated into writer, return 0 if the input string was partially + translated into writer, raise an exception and return -1 on error. */ +static int +unicode_fast_translate(PyObject *input, PyObject *mapping, + _PyUnicodeWriter *writer, int ignore, + Py_ssize_t *input_pos) +{ + Py_UCS1 ascii_table[128], ch, ch2; + Py_ssize_t len; + Py_UCS1 *in, *end, *out; + int res = 0; + + len = PyUnicode_GET_LENGTH(input); + + memset(ascii_table, 0xff, 128); + + in = PyUnicode_1BYTE_DATA(input); + end = in + len; + + assert(PyUnicode_IS_ASCII(writer->buffer)); + assert(PyUnicode_GET_LENGTH(writer->buffer) == len); + out = PyUnicode_1BYTE_DATA(writer->buffer); + + for (; in < end; in++) { + ch = *in; + ch2 = ascii_table[ch]; + if (ch2 == 0xff) { + int translate = unicode_fast_translate_lookup(mapping, ch, + ascii_table); + if (translate < 0) + return -1; + if (translate == 0) + goto exit; + ch2 = ascii_table[ch]; + } + if (ch2 == 0xfe) { + if (ignore) + continue; + goto exit; + } + assert(ch2 < 128); + *out = ch2; + out++; + } + res = 1; + +exit: + writer->pos = out - PyUnicode_1BYTE_DATA(writer->buffer); + *input_pos = in - PyUnicode_1BYTE_DATA(input); + return res; +} + +static PyObject * +_PyUnicode_TranslateCharmap(PyObject *input, + PyObject *mapping, + const char *errors) +{ + /* input object */ + char *data; + Py_ssize_t size, i; + int kind; + /* output buffer */ + _PyUnicodeWriter writer; + /* error handler */ + const char *reason = "character maps to "; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + int ignore; + int res; + + if (mapping == NULL) { + PyErr_BadArgument(); + return NULL; + } + + if (PyUnicode_READY(input) == -1) + return NULL; + data = (char*)PyUnicode_DATA(input); + kind = PyUnicode_KIND(input); + size = PyUnicode_GET_LENGTH(input); + + if (size == 0) + return PyUnicode_FromObject(input); + + /* allocate enough for a simple 1:1 translation without + replacements, if we need more, we'll resize */ + _PyUnicodeWriter_Init(&writer); + if (_PyUnicodeWriter_Prepare(&writer, size, 127) == -1) + goto onError; + + ignore = (errors != NULL && strcmp(errors, "ignore") == 0); + + if (PyUnicode_READY(input) == -1) + return NULL; + if (PyUnicode_IS_ASCII(input)) { + res = unicode_fast_translate(input, mapping, &writer, ignore, &i); + if (res < 0) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + if (res == 1) + return _PyUnicodeWriter_Finish(&writer); + } + else { + i = 0; + } + + while (i adjust input pointer */ + ++i; + continue; + } + + /* untranslatable character */ + collstart = i; + collend = i+1; + + /* find all untranslatable characters */ + while (collend < size) { + PyObject *x; + ch = PyUnicode_READ(kind, data, collend); + if (charmaptranslate_lookup(ch, mapping, &x)) + goto onError; + Py_XDECREF(x); + if (x != Py_None) + break; + ++collend; + } + + if (ignore) { + i = collend; + } + else { + repunicode = unicode_translate_call_errorhandler(errors, &errorHandler, + reason, input, &exc, + collstart, collend, &newpos); + if (repunicode == NULL) + goto onError; + if (_PyUnicodeWriter_WriteStr(&writer, repunicode) < 0) { + Py_DECREF(repunicode); + goto onError; + } + Py_DECREF(repunicode); + i = newpos; + } + } + Py_XDECREF(exc); + Py_XDECREF(errorHandler); + return _PyUnicodeWriter_Finish(&writer); + + onError: + _PyUnicodeWriter_Dealloc(&writer); + Py_XDECREF(exc); + Py_XDECREF(errorHandler); + return NULL; +} + +/* Deprecated. Use PyUnicode_Translate instead. */ +PyObject * +PyUnicode_TranslateCharmap(const Py_UNICODE *p, + Py_ssize_t size, + PyObject *mapping, + const char *errors) +{ + PyObject *result; + PyObject *unicode = PyUnicode_FromWideChar(p, size); + if (!unicode) + return NULL; + result = _PyUnicode_TranslateCharmap(unicode, mapping, errors); + Py_DECREF(unicode); + return result; +} + +PyObject * +PyUnicode_Translate(PyObject *str, + PyObject *mapping, + const char *errors) +{ + if (ensure_unicode(str) < 0) + return NULL; + return _PyUnicode_TranslateCharmap(str, mapping, errors); +} + +PyObject * +_PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode) +{ + if (!PyUnicode_Check(unicode)) { + PyErr_BadInternalCall(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) + return NULL; + if (PyUnicode_IS_ASCII(unicode)) { + /* If the string is already ASCII, just return the same string */ + Py_INCREF(unicode); + return unicode; + } + + Py_ssize_t len = PyUnicode_GET_LENGTH(unicode); + PyObject *result = PyUnicode_New(len, 127); + if (result == NULL) { + return NULL; + } + + Py_UCS1 *out = PyUnicode_1BYTE_DATA(result); + int kind = PyUnicode_KIND(unicode); + const void *data = PyUnicode_DATA(unicode); + Py_ssize_t i; + for (i = 0; i < len; ++i) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (ch < 127) { + out[i] = ch; + } + else if (Py_UNICODE_ISSPACE(ch)) { + out[i] = ' '; + } + else { + int decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal < 0) { + out[i] = '?'; + out[i+1] = '\0'; + _PyUnicode_LENGTH(result) = i + 1; + break; + } + out[i] = '0' + decimal; + } + } + + assert(_PyUnicode_CheckConsistency(result, 1)); + return result; +} + +PyObject * +PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, + Py_ssize_t length) +{ + PyObject *decimal; + Py_ssize_t i; + Py_UCS4 maxchar; + enum PyUnicode_Kind kind; + void *data; + + maxchar = 127; + for (i = 0; i < length; i++) { + Py_UCS4 ch = s[i]; + if (ch > 127) { + int decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) + ch = '0' + decimal; + maxchar = Py_MAX(maxchar, ch); + } + } + + /* Copy to a new string */ + decimal = PyUnicode_New(length, maxchar); + if (decimal == NULL) + return decimal; + kind = PyUnicode_KIND(decimal); + data = PyUnicode_DATA(decimal); + /* Iterate over code points */ + for (i = 0; i < length; i++) { + Py_UCS4 ch = s[i]; + if (ch > 127) { + int decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) + ch = '0' + decimal; + } + PyUnicode_WRITE(kind, data, i, ch); + } + return unicode_result(decimal); +} +/* --- Decimal Encoder ---------------------------------------------------- */ + +int +PyUnicode_EncodeDecimal(Py_UNICODE *s, + Py_ssize_t length, + char *output, + const char *errors) +{ + PyObject *unicode; + Py_ssize_t i; + enum PyUnicode_Kind kind; + void *data; + + if (output == NULL) { + PyErr_BadArgument(); + return -1; + } + + unicode = PyUnicode_FromWideChar(s, length); + if (unicode == NULL) + return -1; + + kind = PyUnicode_KIND(unicode); + data = PyUnicode_DATA(unicode); + + for (i=0; i < length; ) { + PyObject *exc; + Py_UCS4 ch; + int decimal; + Py_ssize_t startpos; + + ch = PyUnicode_READ(kind, data, i); + + if (Py_UNICODE_ISSPACE(ch)) { + *output++ = ' '; + i++; + continue; + } + decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) { + *output++ = '0' + decimal; + i++; + continue; + } + if (0 < ch && ch < 256) { + *output++ = (char)ch; + i++; + continue; + } + + startpos = i; + exc = NULL; + raise_encode_exception(&exc, "decimal", unicode, + startpos, startpos+1, + "invalid decimal Unicode string"); + Py_XDECREF(exc); + Py_DECREF(unicode); + return -1; + } + /* 0-terminate the output string */ + *output++ = '\0'; + Py_DECREF(unicode); + return 0; +} + +/* --- Helpers ------------------------------------------------------------ */ + +/* helper macro to fixup start/end slice values */ +#define ADJUST_INDICES(start, end, len) \ + if (end > len) \ + end = len; \ + else if (end < 0) { \ + end += len; \ + if (end < 0) \ + end = 0; \ + } \ + if (start < 0) { \ + start += len; \ + if (start < 0) \ + start = 0; \ + } + +static Py_ssize_t +any_find_slice(PyObject* s1, PyObject* s2, + Py_ssize_t start, + Py_ssize_t end, + int direction) +{ + int kind1, kind2; + void *buf1, *buf2; + Py_ssize_t len1, len2, result; + + kind1 = PyUnicode_KIND(s1); + kind2 = PyUnicode_KIND(s2); + if (kind1 < kind2) + return -1; + + len1 = PyUnicode_GET_LENGTH(s1); + len2 = PyUnicode_GET_LENGTH(s2); + ADJUST_INDICES(start, end, len1); + if (end - start < len2) + return -1; + + buf1 = PyUnicode_DATA(s1); + buf2 = PyUnicode_DATA(s2); + if (len2 == 1) { + Py_UCS4 ch = PyUnicode_READ(kind2, buf2, 0); + result = findchar((const char *)buf1 + kind1*start, + kind1, end - start, ch, direction); + if (result == -1) + return -1; + else + return start + result; + } + + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(s2, kind1); + if (!buf2) + return -2; + } + + if (direction > 0) { + switch (kind1) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(s1) && PyUnicode_IS_ASCII(s2)) + result = asciilib_find_slice(buf1, len1, buf2, len2, start, end); + else + result = ucs1lib_find_slice(buf1, len1, buf2, len2, start, end); + break; + case PyUnicode_2BYTE_KIND: + result = ucs2lib_find_slice(buf1, len1, buf2, len2, start, end); + break; + case PyUnicode_4BYTE_KIND: + result = ucs4lib_find_slice(buf1, len1, buf2, len2, start, end); + break; + default: + Py_UNREACHABLE(); + } + } + else { + switch (kind1) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(s1) && PyUnicode_IS_ASCII(s2)) + result = asciilib_rfind_slice(buf1, len1, buf2, len2, start, end); + else + result = ucs1lib_rfind_slice(buf1, len1, buf2, len2, start, end); + break; + case PyUnicode_2BYTE_KIND: + result = ucs2lib_rfind_slice(buf1, len1, buf2, len2, start, end); + break; + case PyUnicode_4BYTE_KIND: + result = ucs4lib_rfind_slice(buf1, len1, buf2, len2, start, end); + break; + default: + Py_UNREACHABLE(); + } + } + + if (kind2 != kind1) + PyMem_Free(buf2); + + return result; +} + +/* _PyUnicode_InsertThousandsGrouping() helper functions */ +#include "stringlib/localeutil.h" + +/** + * InsertThousandsGrouping: + * @writer: Unicode writer. + * @n_buffer: Number of characters in @buffer. + * @digits: Digits we're reading from. If count is non-NULL, this is unused. + * @d_pos: Start of digits string. + * @n_digits: The number of digits in the string, in which we want + * to put the grouping chars. + * @min_width: The minimum width of the digits in the output string. + * Output will be zero-padded on the left to fill. + * @grouping: see definition in localeconv(). + * @thousands_sep: see definition in localeconv(). + * + * There are 2 modes: counting and filling. If @writer is NULL, + * we are in counting mode, else filling mode. + * If counting, the required buffer size is returned. + * If filling, we know the buffer will be large enough, so we don't + * need to pass in the buffer size. + * Inserts thousand grouping characters (as defined by grouping and + * thousands_sep) into @writer. + * + * Return value: -1 on error, number of characters otherwise. + **/ +Py_ssize_t +_PyUnicode_InsertThousandsGrouping( + _PyUnicodeWriter *writer, + Py_ssize_t n_buffer, + PyObject *digits, + Py_ssize_t d_pos, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + PyObject *thousands_sep, + Py_UCS4 *maxchar) +{ + min_width = Py_MAX(0, min_width); + if (writer) { + assert(digits != NULL); + assert(maxchar == NULL); + } + else { + assert(digits == NULL); + assert(maxchar != NULL); + } + assert(0 <= d_pos); + assert(0 <= n_digits); + assert(grouping != NULL); + + if (digits != NULL) { + if (PyUnicode_READY(digits) == -1) { + return -1; + } + } + if (PyUnicode_READY(thousands_sep) == -1) { + return -1; + } + + Py_ssize_t count = 0; + Py_ssize_t n_zeros; + int loop_broken = 0; + int use_separator = 0; /* First time through, don't append the + separator. They only go between + groups. */ + Py_ssize_t buffer_pos; + Py_ssize_t digits_pos; + Py_ssize_t len; + Py_ssize_t n_chars; + Py_ssize_t remaining = n_digits; /* Number of chars remaining to + be looked at */ + /* A generator that returns all of the grouping widths, until it + returns 0. */ + GroupGenerator groupgen; + GroupGenerator_init(&groupgen, grouping); + const Py_ssize_t thousands_sep_len = PyUnicode_GET_LENGTH(thousands_sep); + + /* if digits are not grouped, thousands separator + should be an empty string */ + assert(!(grouping[0] == CHAR_MAX && thousands_sep_len != 0)); + + digits_pos = d_pos + n_digits; + if (writer) { + buffer_pos = writer->pos + n_buffer; + assert(buffer_pos <= PyUnicode_GET_LENGTH(writer->buffer)); + assert(digits_pos <= PyUnicode_GET_LENGTH(digits)); + } + else { + buffer_pos = n_buffer; + } + + if (!writer) { + *maxchar = 127; + } + + while ((len = GroupGenerator_next(&groupgen)) > 0) { + len = Py_MIN(len, Py_MAX(Py_MAX(remaining, min_width), 1)); + n_zeros = Py_MAX(0, len - remaining); + n_chars = Py_MAX(0, Py_MIN(remaining, len)); + + /* Use n_zero zero's and n_chars chars */ + + /* Count only, don't do anything. */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + + /* Copy into the writer. */ + InsertThousandsGrouping_fill(writer, &buffer_pos, + digits, &digits_pos, + n_chars, n_zeros, + use_separator ? thousands_sep : NULL, + thousands_sep_len, maxchar); + + /* Use a separator next time. */ + use_separator = 1; + + remaining -= n_chars; + min_width -= len; + + if (remaining <= 0 && min_width <= 0) { + loop_broken = 1; + break; + } + min_width -= thousands_sep_len; + } + if (!loop_broken) { + /* We left the loop without using a break statement. */ + + len = Py_MAX(Py_MAX(remaining, min_width), 1); + n_zeros = Py_MAX(0, len - remaining); + n_chars = Py_MAX(0, Py_MIN(remaining, len)); + + /* Use n_zero zero's and n_chars chars */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + + /* Copy into the writer. */ + InsertThousandsGrouping_fill(writer, &buffer_pos, + digits, &digits_pos, + n_chars, n_zeros, + use_separator ? thousands_sep : NULL, + thousands_sep_len, maxchar); + } + return count; +} + + +Py_ssize_t +PyUnicode_Count(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end) +{ + Py_ssize_t result; + int kind1, kind2; + void *buf1 = NULL, *buf2 = NULL; + Py_ssize_t len1, len2; + + if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) + return -1; + + kind1 = PyUnicode_KIND(str); + kind2 = PyUnicode_KIND(substr); + if (kind1 < kind2) + return 0; + + len1 = PyUnicode_GET_LENGTH(str); + len2 = PyUnicode_GET_LENGTH(substr); + ADJUST_INDICES(start, end, len1); + if (end - start < len2) + return 0; + + buf1 = PyUnicode_DATA(str); + buf2 = PyUnicode_DATA(substr); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substr, kind1); + if (!buf2) + goto onError; + } + + switch (kind1) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(str) && PyUnicode_IS_ASCII(substr)) + result = asciilib_count( + ((Py_UCS1*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); + else + result = ucs1lib_count( + ((Py_UCS1*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); + break; + case PyUnicode_2BYTE_KIND: + result = ucs2lib_count( + ((Py_UCS2*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); + break; + case PyUnicode_4BYTE_KIND: + result = ucs4lib_count( + ((Py_UCS4*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); + break; + default: + Py_UNREACHABLE(); + } + + if (kind2 != kind1) + PyMem_Free(buf2); + + return result; + onError: + if (kind2 != kind1 && buf2) + PyMem_Free(buf2); + return -1; +} + +Py_ssize_t +PyUnicode_Find(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end, + int direction) +{ + if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) + return -2; + + return any_find_slice(str, substr, start, end, direction); +} + +Py_ssize_t +PyUnicode_FindChar(PyObject *str, Py_UCS4 ch, + Py_ssize_t start, Py_ssize_t end, + int direction) +{ + int kind; + Py_ssize_t len, result; + if (PyUnicode_READY(str) == -1) + return -2; + len = PyUnicode_GET_LENGTH(str); + ADJUST_INDICES(start, end, len); + if (end - start < 1) + return -1; + kind = PyUnicode_KIND(str); + result = findchar(PyUnicode_1BYTE_DATA(str) + kind*start, + kind, end-start, ch, direction); + if (result == -1) + return -1; + else + return start + result; +} + +static int +tailmatch(PyObject *self, + PyObject *substring, + Py_ssize_t start, + Py_ssize_t end, + int direction) +{ + int kind_self; + int kind_sub; + void *data_self; + void *data_sub; + Py_ssize_t offset; + Py_ssize_t i; + Py_ssize_t end_sub; + + if (PyUnicode_READY(self) == -1 || + PyUnicode_READY(substring) == -1) + return -1; + + ADJUST_INDICES(start, end, PyUnicode_GET_LENGTH(self)); + end -= PyUnicode_GET_LENGTH(substring); + if (end < start) + return 0; + + if (PyUnicode_GET_LENGTH(substring) == 0) + return 1; + + kind_self = PyUnicode_KIND(self); + data_self = PyUnicode_DATA(self); + kind_sub = PyUnicode_KIND(substring); + data_sub = PyUnicode_DATA(substring); + end_sub = PyUnicode_GET_LENGTH(substring) - 1; + + if (direction > 0) + offset = end; + else + offset = start; + + if (PyUnicode_READ(kind_self, data_self, offset) == + PyUnicode_READ(kind_sub, data_sub, 0) && + PyUnicode_READ(kind_self, data_self, offset + end_sub) == + PyUnicode_READ(kind_sub, data_sub, end_sub)) { + /* If both are of the same kind, memcmp is sufficient */ + if (kind_self == kind_sub) { + return ! memcmp((char *)data_self + + (offset * PyUnicode_KIND(substring)), + data_sub, + PyUnicode_GET_LENGTH(substring) * + PyUnicode_KIND(substring)); + } + /* otherwise we have to compare each character by first accessing it */ + else { + /* We do not need to compare 0 and len(substring)-1 because + the if statement above ensured already that they are equal + when we end up here. */ + for (i = 1; i < end_sub; ++i) { + if (PyUnicode_READ(kind_self, data_self, offset + i) != + PyUnicode_READ(kind_sub, data_sub, i)) + return 0; + } + return 1; + } + } + + return 0; +} + +Py_ssize_t +PyUnicode_Tailmatch(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end, + int direction) +{ + if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) + return -1; + + return tailmatch(str, substr, start, end, direction); +} + +static PyObject * +ascii_upper_or_lower(PyObject *self, int lower) +{ + Py_ssize_t len = PyUnicode_GET_LENGTH(self); + char *resdata, *data = PyUnicode_DATA(self); + PyObject *res; + + res = PyUnicode_New(len, 127); + if (res == NULL) + return NULL; + resdata = PyUnicode_DATA(res); + if (lower) + _Py_bytes_lower(resdata, data, len); + else + _Py_bytes_upper(resdata, data, len); + return res; +} + +static Py_UCS4 +handle_capital_sigma(int kind, void *data, Py_ssize_t length, Py_ssize_t i) +{ + Py_ssize_t j; + int final_sigma; + Py_UCS4 c = 0; /* initialize to prevent gcc warning */ + /* U+03A3 is in the Final_Sigma context when, it is found like this: + + \p{cased}\p{case-ignorable}*U+03A3!(\p{case-ignorable}*\p{cased}) + + where ! is a negation and \p{xxx} is a character with property xxx. + */ + for (j = i - 1; j >= 0; j--) { + c = PyUnicode_READ(kind, data, j); + if (!_PyUnicode_IsCaseIgnorable(c)) + break; + } + final_sigma = j >= 0 && _PyUnicode_IsCased(c); + if (final_sigma) { + for (j = i + 1; j < length; j++) { + c = PyUnicode_READ(kind, data, j); + if (!_PyUnicode_IsCaseIgnorable(c)) + break; + } + final_sigma = j == length || !_PyUnicode_IsCased(c); + } + return (final_sigma) ? 0x3C2 : 0x3C3; +} + +static int +lower_ucs4(int kind, void *data, Py_ssize_t length, Py_ssize_t i, + Py_UCS4 c, Py_UCS4 *mapped) +{ + /* Obscure special case. */ + if (c == 0x3A3) { + mapped[0] = handle_capital_sigma(kind, data, length, i); + return 1; + } + return _PyUnicode_ToLowerFull(c, mapped); +} + +static Py_ssize_t +do_capitalize(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar) +{ + Py_ssize_t i, k = 0; + int n_res, j; + Py_UCS4 c, mapped[3]; + + c = PyUnicode_READ(kind, data, 0); + n_res = _PyUnicode_ToTitleFull(c, mapped); + for (j = 0; j < n_res; j++) { + *maxchar = Py_MAX(*maxchar, mapped[j]); + res[k++] = mapped[j]; + } + for (i = 1; i < length; i++) { + c = PyUnicode_READ(kind, data, i); + n_res = lower_ucs4(kind, data, length, i, c, mapped); + for (j = 0; j < n_res; j++) { + *maxchar = Py_MAX(*maxchar, mapped[j]); + res[k++] = mapped[j]; + } + } + return k; +} + +static Py_ssize_t +do_swapcase(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar) { + Py_ssize_t i, k = 0; + + for (i = 0; i < length; i++) { + Py_UCS4 c = PyUnicode_READ(kind, data, i), mapped[3]; + int n_res, j; + if (Py_UNICODE_ISUPPER(c)) { + n_res = lower_ucs4(kind, data, length, i, c, mapped); + } + else if (Py_UNICODE_ISLOWER(c)) { + n_res = _PyUnicode_ToUpperFull(c, mapped); + } + else { + n_res = 1; + mapped[0] = c; + } + for (j = 0; j < n_res; j++) { + *maxchar = Py_MAX(*maxchar, mapped[j]); + res[k++] = mapped[j]; + } + } + return k; +} + +static Py_ssize_t +do_upper_or_lower(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, + Py_UCS4 *maxchar, int lower) +{ + Py_ssize_t i, k = 0; + + for (i = 0; i < length; i++) { + Py_UCS4 c = PyUnicode_READ(kind, data, i), mapped[3]; + int n_res, j; + if (lower) + n_res = lower_ucs4(kind, data, length, i, c, mapped); + else + n_res = _PyUnicode_ToUpperFull(c, mapped); + for (j = 0; j < n_res; j++) { + *maxchar = Py_MAX(*maxchar, mapped[j]); + res[k++] = mapped[j]; + } + } + return k; +} + +static Py_ssize_t +do_upper(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar) +{ + return do_upper_or_lower(kind, data, length, res, maxchar, 0); +} + +static Py_ssize_t +do_lower(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar) +{ + return do_upper_or_lower(kind, data, length, res, maxchar, 1); +} + +static Py_ssize_t +do_casefold(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar) +{ + Py_ssize_t i, k = 0; + + for (i = 0; i < length; i++) { + Py_UCS4 c = PyUnicode_READ(kind, data, i); + Py_UCS4 mapped[3]; + int j, n_res = _PyUnicode_ToFoldedFull(c, mapped); + for (j = 0; j < n_res; j++) { + *maxchar = Py_MAX(*maxchar, mapped[j]); + res[k++] = mapped[j]; + } + } + return k; +} + +static Py_ssize_t +do_title(int kind, void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar) +{ + Py_ssize_t i, k = 0; + int previous_is_cased; + + previous_is_cased = 0; + for (i = 0; i < length; i++) { + const Py_UCS4 c = PyUnicode_READ(kind, data, i); + Py_UCS4 mapped[3]; + int n_res, j; + + if (previous_is_cased) + n_res = lower_ucs4(kind, data, length, i, c, mapped); + else + n_res = _PyUnicode_ToTitleFull(c, mapped); + + for (j = 0; j < n_res; j++) { + *maxchar = Py_MAX(*maxchar, mapped[j]); + res[k++] = mapped[j]; + } + + previous_is_cased = _PyUnicode_IsCased(c); + } + return k; +} + +static PyObject * +case_operation(PyObject *self, + Py_ssize_t (*perform)(int, void *, Py_ssize_t, Py_UCS4 *, Py_UCS4 *)) +{ + PyObject *res = NULL; + Py_ssize_t length, newlength = 0; + int kind, outkind; + void *data, *outdata; + Py_UCS4 maxchar = 0, *tmp, *tmpend; + + assert(PyUnicode_IS_READY(self)); + + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + length = PyUnicode_GET_LENGTH(self); + if ((size_t) length > PY_SSIZE_T_MAX / (3 * sizeof(Py_UCS4))) { + PyErr_SetString(PyExc_OverflowError, "string is too long"); + return NULL; + } + tmp = PyMem_MALLOC(sizeof(Py_UCS4) * 3 * length); + if (tmp == NULL) + return PyErr_NoMemory(); + newlength = perform(kind, data, length, tmp, &maxchar); + res = PyUnicode_New(newlength, maxchar); + if (res == NULL) + goto leave; + tmpend = tmp + newlength; + outdata = PyUnicode_DATA(res); + outkind = PyUnicode_KIND(res); + switch (outkind) { + case PyUnicode_1BYTE_KIND: + _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS1, tmp, tmpend, outdata); + break; + case PyUnicode_2BYTE_KIND: + _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS2, tmp, tmpend, outdata); + break; + case PyUnicode_4BYTE_KIND: + memcpy(outdata, tmp, sizeof(Py_UCS4) * newlength); + break; + default: + Py_UNREACHABLE(); + } + leave: + PyMem_FREE(tmp); + return res; +} + +PyObject * +PyUnicode_Join(PyObject *separator, PyObject *seq) +{ + PyObject *res; + PyObject *fseq; + Py_ssize_t seqlen; + PyObject **items; + + fseq = PySequence_Fast(seq, "can only join an iterable"); + if (fseq == NULL) { + return NULL; + } + + /* NOTE: the following code can't call back into Python code, + * so we are sure that fseq won't be mutated. + */ + + items = PySequence_Fast_ITEMS(fseq); + seqlen = PySequence_Fast_GET_SIZE(fseq); + res = _PyUnicode_JoinArray(separator, items, seqlen); + Py_DECREF(fseq); + return res; +} + +PyObject * +_PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seqlen) +{ + PyObject *res = NULL; /* the result */ + PyObject *sep = NULL; + Py_ssize_t seplen; + PyObject *item; + Py_ssize_t sz, i, res_offset; + Py_UCS4 maxchar; + Py_UCS4 item_maxchar; + int use_memcpy; + unsigned char *res_data = NULL, *sep_data = NULL; + PyObject *last_obj; + unsigned int kind = 0; + + /* If empty sequence, return u"". */ + if (seqlen == 0) { + _Py_RETURN_UNICODE_EMPTY(); + } + + /* If singleton sequence with an exact Unicode, return that. */ + last_obj = NULL; + if (seqlen == 1) { + if (PyUnicode_CheckExact(items[0])) { + res = items[0]; + Py_INCREF(res); + return res; + } + seplen = 0; + maxchar = 0; + } + else { + /* Set up sep and seplen */ + if (separator == NULL) { + /* fall back to a blank space separator */ + sep = PyUnicode_FromOrdinal(' '); + if (!sep) + goto onError; + seplen = 1; + maxchar = 32; + } + else { + if (!PyUnicode_Check(separator)) { + PyErr_Format(PyExc_TypeError, + "separator: expected str instance," + " %.80s found", + Py_TYPE(separator)->tp_name); + goto onError; + } + if (PyUnicode_READY(separator)) + goto onError; + sep = separator; + seplen = PyUnicode_GET_LENGTH(separator); + maxchar = PyUnicode_MAX_CHAR_VALUE(separator); + /* inc refcount to keep this code path symmetric with the + above case of a blank separator */ + Py_INCREF(sep); + } + last_obj = sep; + } + + /* There are at least two things to join, or else we have a subclass + * of str in the sequence. + * Do a pre-pass to figure out the total amount of space we'll + * need (sz), and see whether all argument are strings. + */ + sz = 0; +#ifdef Py_DEBUG + use_memcpy = 0; +#else + use_memcpy = 1; +#endif + for (i = 0; i < seqlen; i++) { + size_t add_sz; + item = items[i]; + if (!PyUnicode_Check(item)) { + PyErr_Format(PyExc_TypeError, + "sequence item %zd: expected str instance," + " %.80s found", + i, Py_TYPE(item)->tp_name); + goto onError; + } + if (PyUnicode_READY(item) == -1) + goto onError; + add_sz = PyUnicode_GET_LENGTH(item); + item_maxchar = PyUnicode_MAX_CHAR_VALUE(item); + maxchar = Py_MAX(maxchar, item_maxchar); + if (i != 0) { + add_sz += seplen; + } + if (add_sz > (size_t)(PY_SSIZE_T_MAX - sz)) { + PyErr_SetString(PyExc_OverflowError, + "join() result is too long for a Python string"); + goto onError; + } + sz += add_sz; + if (use_memcpy && last_obj != NULL) { + if (PyUnicode_KIND(last_obj) != PyUnicode_KIND(item)) + use_memcpy = 0; + } + last_obj = item; + } + + res = PyUnicode_New(sz, maxchar); + if (res == NULL) + goto onError; + + /* Catenate everything. */ +#ifdef Py_DEBUG + use_memcpy = 0; +#else + if (use_memcpy) { + res_data = PyUnicode_1BYTE_DATA(res); + kind = PyUnicode_KIND(res); + if (seplen != 0) + sep_data = PyUnicode_1BYTE_DATA(sep); + } +#endif + if (use_memcpy) { + for (i = 0; i < seqlen; ++i) { + Py_ssize_t itemlen; + item = items[i]; + + /* Copy item, and maybe the separator. */ + if (i && seplen != 0) { + memcpy(res_data, + sep_data, + kind * seplen); + res_data += kind * seplen; + } + + itemlen = PyUnicode_GET_LENGTH(item); + if (itemlen != 0) { + memcpy(res_data, + PyUnicode_DATA(item), + kind * itemlen); + res_data += kind * itemlen; + } + } + assert(res_data == PyUnicode_1BYTE_DATA(res) + + kind * PyUnicode_GET_LENGTH(res)); + } + else { + for (i = 0, res_offset = 0; i < seqlen; ++i) { + Py_ssize_t itemlen; + item = items[i]; + + /* Copy item, and maybe the separator. */ + if (i && seplen != 0) { + _PyUnicode_FastCopyCharacters(res, res_offset, sep, 0, seplen); + res_offset += seplen; + } + + itemlen = PyUnicode_GET_LENGTH(item); + if (itemlen != 0) { + _PyUnicode_FastCopyCharacters(res, res_offset, item, 0, itemlen); + res_offset += itemlen; + } + } + assert(res_offset == PyUnicode_GET_LENGTH(res)); + } + + Py_XDECREF(sep); + assert(_PyUnicode_CheckConsistency(res, 1)); + return res; + + onError: + Py_XDECREF(sep); + Py_XDECREF(res); + return NULL; +} + +void +_PyUnicode_FastFill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, + Py_UCS4 fill_char) +{ + const enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + void *data = PyUnicode_DATA(unicode); + assert(PyUnicode_IS_READY(unicode)); + assert(unicode_modifiable(unicode)); + assert(fill_char <= PyUnicode_MAX_CHAR_VALUE(unicode)); + assert(start >= 0); + assert(start + length <= PyUnicode_GET_LENGTH(unicode)); + unicode_fill(kind, data, fill_char, start, length); +} + +Py_ssize_t +PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, + Py_UCS4 fill_char) +{ + Py_ssize_t maxlen; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadInternalCall(); + return -1; + } + if (PyUnicode_READY(unicode) == -1) + return -1; + if (unicode_check_modifiable(unicode)) + return -1; + + if (start < 0) { + PyErr_SetString(PyExc_IndexError, "string index out of range"); + return -1; + } + if (fill_char > PyUnicode_MAX_CHAR_VALUE(unicode)) { + PyErr_SetString(PyExc_ValueError, + "fill character is bigger than " + "the string maximum character"); + return -1; + } + + maxlen = PyUnicode_GET_LENGTH(unicode) - start; + length = Py_MIN(maxlen, length); + if (length <= 0) + return 0; + + _PyUnicode_FastFill(unicode, start, length, fill_char); + return length; +} + +static PyObject * +pad(PyObject *self, + Py_ssize_t left, + Py_ssize_t right, + Py_UCS4 fill) +{ + PyObject *u; + Py_UCS4 maxchar; + int kind; + void *data; + + if (left < 0) + left = 0; + if (right < 0) + right = 0; + + if (left == 0 && right == 0) + return unicode_result_unchanged(self); + + if (left > PY_SSIZE_T_MAX - _PyUnicode_LENGTH(self) || + right > PY_SSIZE_T_MAX - (left + _PyUnicode_LENGTH(self))) { + PyErr_SetString(PyExc_OverflowError, "padded string is too long"); + return NULL; + } + maxchar = PyUnicode_MAX_CHAR_VALUE(self); + maxchar = Py_MAX(maxchar, fill); + u = PyUnicode_New(left + _PyUnicode_LENGTH(self) + right, maxchar); + if (!u) + return NULL; + + kind = PyUnicode_KIND(u); + data = PyUnicode_DATA(u); + if (left) + unicode_fill(kind, data, fill, 0, left); + if (right) + unicode_fill(kind, data, fill, left + _PyUnicode_LENGTH(self), right); + _PyUnicode_FastCopyCharacters(u, left, self, 0, _PyUnicode_LENGTH(self)); + assert(_PyUnicode_CheckConsistency(u, 1)); + return u; +} + +PyObject * +PyUnicode_Splitlines(PyObject *string, int keepends) +{ + PyObject *list; + + if (ensure_unicode(string) < 0) + return NULL; + + switch (PyUnicode_KIND(string)) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(string)) + list = asciilib_splitlines( + string, PyUnicode_1BYTE_DATA(string), + PyUnicode_GET_LENGTH(string), keepends); + else + list = ucs1lib_splitlines( + string, PyUnicode_1BYTE_DATA(string), + PyUnicode_GET_LENGTH(string), keepends); + break; + case PyUnicode_2BYTE_KIND: + list = ucs2lib_splitlines( + string, PyUnicode_2BYTE_DATA(string), + PyUnicode_GET_LENGTH(string), keepends); + break; + case PyUnicode_4BYTE_KIND: + list = ucs4lib_splitlines( + string, PyUnicode_4BYTE_DATA(string), + PyUnicode_GET_LENGTH(string), keepends); + break; + default: + Py_UNREACHABLE(); + } + return list; +} + +static PyObject * +split(PyObject *self, + PyObject *substring, + Py_ssize_t maxcount) +{ + int kind1, kind2; + void *buf1, *buf2; + Py_ssize_t len1, len2; + PyObject* out; + + if (maxcount < 0) + maxcount = PY_SSIZE_T_MAX; + + if (PyUnicode_READY(self) == -1) + return NULL; + + if (substring == NULL) + switch (PyUnicode_KIND(self)) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(self)) + return asciilib_split_whitespace( + self, PyUnicode_1BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + else + return ucs1lib_split_whitespace( + self, PyUnicode_1BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + case PyUnicode_2BYTE_KIND: + return ucs2lib_split_whitespace( + self, PyUnicode_2BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + case PyUnicode_4BYTE_KIND: + return ucs4lib_split_whitespace( + self, PyUnicode_4BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + default: + Py_UNREACHABLE(); + } + + if (PyUnicode_READY(substring) == -1) + return NULL; + + kind1 = PyUnicode_KIND(self); + kind2 = PyUnicode_KIND(substring); + len1 = PyUnicode_GET_LENGTH(self); + len2 = PyUnicode_GET_LENGTH(substring); + if (kind1 < kind2 || len1 < len2) { + out = PyList_New(1); + if (out == NULL) + return NULL; + Py_INCREF(self); + PyList_SET_ITEM(out, 0, self); + return out; + } + buf1 = PyUnicode_DATA(self); + buf2 = PyUnicode_DATA(substring); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) + return NULL; + } + + switch (kind1) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring)) + out = asciilib_split( + self, buf1, len1, buf2, len2, maxcount); + else + out = ucs1lib_split( + self, buf1, len1, buf2, len2, maxcount); + break; + case PyUnicode_2BYTE_KIND: + out = ucs2lib_split( + self, buf1, len1, buf2, len2, maxcount); + break; + case PyUnicode_4BYTE_KIND: + out = ucs4lib_split( + self, buf1, len1, buf2, len2, maxcount); + break; + default: + out = NULL; + } + if (kind2 != kind1) + PyMem_Free(buf2); + return out; +} + +static PyObject * +rsplit(PyObject *self, + PyObject *substring, + Py_ssize_t maxcount) +{ + int kind1, kind2; + void *buf1, *buf2; + Py_ssize_t len1, len2; + PyObject* out; + + if (maxcount < 0) + maxcount = PY_SSIZE_T_MAX; + + if (PyUnicode_READY(self) == -1) + return NULL; + + if (substring == NULL) + switch (PyUnicode_KIND(self)) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(self)) + return asciilib_rsplit_whitespace( + self, PyUnicode_1BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + else + return ucs1lib_rsplit_whitespace( + self, PyUnicode_1BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + case PyUnicode_2BYTE_KIND: + return ucs2lib_rsplit_whitespace( + self, PyUnicode_2BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + case PyUnicode_4BYTE_KIND: + return ucs4lib_rsplit_whitespace( + self, PyUnicode_4BYTE_DATA(self), + PyUnicode_GET_LENGTH(self), maxcount + ); + default: + Py_UNREACHABLE(); + } + + if (PyUnicode_READY(substring) == -1) + return NULL; + + kind1 = PyUnicode_KIND(self); + kind2 = PyUnicode_KIND(substring); + len1 = PyUnicode_GET_LENGTH(self); + len2 = PyUnicode_GET_LENGTH(substring); + if (kind1 < kind2 || len1 < len2) { + out = PyList_New(1); + if (out == NULL) + return NULL; + Py_INCREF(self); + PyList_SET_ITEM(out, 0, self); + return out; + } + buf1 = PyUnicode_DATA(self); + buf2 = PyUnicode_DATA(substring); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) + return NULL; + } + + switch (kind1) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring)) + out = asciilib_rsplit( + self, buf1, len1, buf2, len2, maxcount); + else + out = ucs1lib_rsplit( + self, buf1, len1, buf2, len2, maxcount); + break; + case PyUnicode_2BYTE_KIND: + out = ucs2lib_rsplit( + self, buf1, len1, buf2, len2, maxcount); + break; + case PyUnicode_4BYTE_KIND: + out = ucs4lib_rsplit( + self, buf1, len1, buf2, len2, maxcount); + break; + default: + out = NULL; + } + if (kind2 != kind1) + PyMem_Free(buf2); + return out; +} + +static Py_ssize_t +anylib_find(int kind, PyObject *str1, void *buf1, Py_ssize_t len1, + PyObject *str2, void *buf2, Py_ssize_t len2, Py_ssize_t offset) +{ + switch (kind) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(str1) && PyUnicode_IS_ASCII(str2)) + return asciilib_find(buf1, len1, buf2, len2, offset); + else + return ucs1lib_find(buf1, len1, buf2, len2, offset); + case PyUnicode_2BYTE_KIND: + return ucs2lib_find(buf1, len1, buf2, len2, offset); + case PyUnicode_4BYTE_KIND: + return ucs4lib_find(buf1, len1, buf2, len2, offset); + } + Py_UNREACHABLE(); +} + +static Py_ssize_t +anylib_count(int kind, PyObject *sstr, void* sbuf, Py_ssize_t slen, + PyObject *str1, void *buf1, Py_ssize_t len1, Py_ssize_t maxcount) +{ + switch (kind) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(sstr) && PyUnicode_IS_ASCII(str1)) + return asciilib_count(sbuf, slen, buf1, len1, maxcount); + else + return ucs1lib_count(sbuf, slen, buf1, len1, maxcount); + case PyUnicode_2BYTE_KIND: + return ucs2lib_count(sbuf, slen, buf1, len1, maxcount); + case PyUnicode_4BYTE_KIND: + return ucs4lib_count(sbuf, slen, buf1, len1, maxcount); + } + Py_UNREACHABLE(); +} + +static void +replace_1char_inplace(PyObject *u, Py_ssize_t pos, + Py_UCS4 u1, Py_UCS4 u2, Py_ssize_t maxcount) +{ + int kind = PyUnicode_KIND(u); + void *data = PyUnicode_DATA(u); + Py_ssize_t len = PyUnicode_GET_LENGTH(u); + if (kind == PyUnicode_1BYTE_KIND) { + ucs1lib_replace_1char_inplace((Py_UCS1 *)data + pos, + (Py_UCS1 *)data + len, + u1, u2, maxcount); + } + else if (kind == PyUnicode_2BYTE_KIND) { + ucs2lib_replace_1char_inplace((Py_UCS2 *)data + pos, + (Py_UCS2 *)data + len, + u1, u2, maxcount); + } + else { + assert(kind == PyUnicode_4BYTE_KIND); + ucs4lib_replace_1char_inplace((Py_UCS4 *)data + pos, + (Py_UCS4 *)data + len, + u1, u2, maxcount); + } +} + +static PyObject * +replace(PyObject *self, PyObject *str1, + PyObject *str2, Py_ssize_t maxcount) +{ + PyObject *u; + char *sbuf = PyUnicode_DATA(self); + char *buf1 = PyUnicode_DATA(str1); + char *buf2 = PyUnicode_DATA(str2); + int srelease = 0, release1 = 0, release2 = 0; + int skind = PyUnicode_KIND(self); + int kind1 = PyUnicode_KIND(str1); + int kind2 = PyUnicode_KIND(str2); + Py_ssize_t slen = PyUnicode_GET_LENGTH(self); + Py_ssize_t len1 = PyUnicode_GET_LENGTH(str1); + Py_ssize_t len2 = PyUnicode_GET_LENGTH(str2); + int mayshrink; + Py_UCS4 maxchar, maxchar_str1, maxchar_str2; + + if (maxcount < 0) + maxcount = PY_SSIZE_T_MAX; + else if (maxcount == 0 || slen == 0) + goto nothing; + + if (str1 == str2) + goto nothing; + + maxchar = PyUnicode_MAX_CHAR_VALUE(self); + maxchar_str1 = PyUnicode_MAX_CHAR_VALUE(str1); + if (maxchar < maxchar_str1) + /* substring too wide to be present */ + goto nothing; + maxchar_str2 = PyUnicode_MAX_CHAR_VALUE(str2); + /* Replacing str1 with str2 may cause a maxchar reduction in the + result string. */ + mayshrink = (maxchar_str2 < maxchar_str1) && (maxchar == maxchar_str1); + maxchar = Py_MAX(maxchar, maxchar_str2); + + if (len1 == len2) { + /* same length */ + if (len1 == 0) + goto nothing; + if (len1 == 1) { + /* replace characters */ + Py_UCS4 u1, u2; + Py_ssize_t pos; + + u1 = PyUnicode_READ(kind1, buf1, 0); + pos = findchar(sbuf, skind, slen, u1, 1); + if (pos < 0) + goto nothing; + u2 = PyUnicode_READ(kind2, buf2, 0); + u = PyUnicode_New(slen, maxchar); + if (!u) + goto error; + + _PyUnicode_FastCopyCharacters(u, 0, self, 0, slen); + replace_1char_inplace(u, pos, u1, u2, maxcount); + } + else { + int rkind = skind; + char *res; + Py_ssize_t i; + + if (kind1 < rkind) { + /* widen substring */ + buf1 = _PyUnicode_AsKind(str1, rkind); + if (!buf1) goto error; + release1 = 1; + } + i = anylib_find(rkind, self, sbuf, slen, str1, buf1, len1, 0); + if (i < 0) + goto nothing; + if (rkind > kind2) { + /* widen replacement */ + buf2 = _PyUnicode_AsKind(str2, rkind); + if (!buf2) goto error; + release2 = 1; + } + else if (rkind < kind2) { + /* widen self and buf1 */ + rkind = kind2; + if (release1) PyMem_Free(buf1); + release1 = 0; + sbuf = _PyUnicode_AsKind(self, rkind); + if (!sbuf) goto error; + srelease = 1; + buf1 = _PyUnicode_AsKind(str1, rkind); + if (!buf1) goto error; + release1 = 1; + } + u = PyUnicode_New(slen, maxchar); + if (!u) + goto error; + assert(PyUnicode_KIND(u) == rkind); + res = PyUnicode_DATA(u); + + memcpy(res, sbuf, rkind * slen); + /* change everything in-place, starting with this one */ + memcpy(res + rkind * i, + buf2, + rkind * len2); + i += len1; + + while ( --maxcount > 0) { + i = anylib_find(rkind, self, + sbuf+rkind*i, slen-i, + str1, buf1, len1, i); + if (i == -1) + break; + memcpy(res + rkind * i, + buf2, + rkind * len2); + i += len1; + } + } + } + else { + Py_ssize_t n, i, j, ires; + Py_ssize_t new_size; + int rkind = skind; + char *res; + + if (kind1 < rkind) { + /* widen substring */ + buf1 = _PyUnicode_AsKind(str1, rkind); + if (!buf1) goto error; + release1 = 1; + } + n = anylib_count(rkind, self, sbuf, slen, str1, buf1, len1, maxcount); + if (n == 0) + goto nothing; + if (kind2 < rkind) { + /* widen replacement */ + buf2 = _PyUnicode_AsKind(str2, rkind); + if (!buf2) goto error; + release2 = 1; + } + else if (kind2 > rkind) { + /* widen self and buf1 */ + rkind = kind2; + sbuf = _PyUnicode_AsKind(self, rkind); + if (!sbuf) goto error; + srelease = 1; + if (release1) PyMem_Free(buf1); + release1 = 0; + buf1 = _PyUnicode_AsKind(str1, rkind); + if (!buf1) goto error; + release1 = 1; + } + /* new_size = PyUnicode_GET_LENGTH(self) + n * (PyUnicode_GET_LENGTH(str2) - + PyUnicode_GET_LENGTH(str1))); */ + if (len1 < len2 && len2 - len1 > (PY_SSIZE_T_MAX - slen) / n) { + PyErr_SetString(PyExc_OverflowError, + "replace string is too long"); + goto error; + } + new_size = slen + n * (len2 - len1); + if (new_size == 0) { + _Py_INCREF_UNICODE_EMPTY(); + if (!unicode_empty) + goto error; + u = unicode_empty; + goto done; + } + if (new_size > (PY_SSIZE_T_MAX / rkind)) { + PyErr_SetString(PyExc_OverflowError, + "replace string is too long"); + goto error; + } + u = PyUnicode_New(new_size, maxchar); + if (!u) + goto error; + assert(PyUnicode_KIND(u) == rkind); + res = PyUnicode_DATA(u); + ires = i = 0; + if (len1 > 0) { + while (n-- > 0) { + /* look for next match */ + j = anylib_find(rkind, self, + sbuf + rkind * i, slen-i, + str1, buf1, len1, i); + if (j == -1) + break; + else if (j > i) { + /* copy unchanged part [i:j] */ + memcpy(res + rkind * ires, + sbuf + rkind * i, + rkind * (j-i)); + ires += j - i; + } + /* copy substitution string */ + if (len2 > 0) { + memcpy(res + rkind * ires, + buf2, + rkind * len2); + ires += len2; + } + i = j + len1; + } + if (i < slen) + /* copy tail [i:] */ + memcpy(res + rkind * ires, + sbuf + rkind * i, + rkind * (slen-i)); + } + else { + /* interleave */ + while (n > 0) { + memcpy(res + rkind * ires, + buf2, + rkind * len2); + ires += len2; + if (--n <= 0) + break; + memcpy(res + rkind * ires, + sbuf + rkind * i, + rkind); + ires++; + i++; + } + memcpy(res + rkind * ires, + sbuf + rkind * i, + rkind * (slen-i)); + } + } + + if (mayshrink) { + unicode_adjust_maxchar(&u); + if (u == NULL) + goto error; + } + + done: + if (srelease) + PyMem_FREE(sbuf); + if (release1) + PyMem_FREE(buf1); + if (release2) + PyMem_FREE(buf2); + assert(_PyUnicode_CheckConsistency(u, 1)); + return u; + + nothing: + /* nothing to replace; return original string (when possible) */ + if (srelease) + PyMem_FREE(sbuf); + if (release1) + PyMem_FREE(buf1); + if (release2) + PyMem_FREE(buf2); + return unicode_result_unchanged(self); + + error: + if (srelease && sbuf) + PyMem_FREE(sbuf); + if (release1 && buf1) + PyMem_FREE(buf1); + if (release2 && buf2) + PyMem_FREE(buf2); + return NULL; +} + +/* --- Unicode Object Methods --------------------------------------------- */ + +/*[clinic input] +str.title as unicode_title + +Return a version of the string where each word is titlecased. + +More specifically, words start with uppercased characters and all remaining +cased characters have lower case. +[clinic start generated code]*/ + +static PyObject * +unicode_title_impl(PyObject *self) +/*[clinic end generated code: output=c75ae03809574902 input=fa945d669b26e683]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + return case_operation(self, do_title); +} + +/*[clinic input] +str.capitalize as unicode_capitalize + +Return a capitalized version of the string. + +More specifically, make the first character have upper case and the rest lower +case. +[clinic start generated code]*/ + +static PyObject * +unicode_capitalize_impl(PyObject *self) +/*[clinic end generated code: output=e49a4c333cdb7667 input=f4cbf1016938da6d]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + if (PyUnicode_GET_LENGTH(self) == 0) + return unicode_result_unchanged(self); + return case_operation(self, do_capitalize); +} + +/*[clinic input] +str.casefold as unicode_casefold + +Return a version of the string suitable for caseless comparisons. +[clinic start generated code]*/ + +static PyObject * +unicode_casefold_impl(PyObject *self) +/*[clinic end generated code: output=0120daf657ca40af input=384d66cc2ae30daf]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + if (PyUnicode_IS_ASCII(self)) + return ascii_upper_or_lower(self, 1); + return case_operation(self, do_casefold); +} + + +/* Argument converter. Accepts a single Unicode character. */ + +static int +convert_uc(PyObject *obj, void *addr) +{ + Py_UCS4 *fillcharloc = (Py_UCS4 *)addr; + + if (!PyUnicode_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "The fill character must be a unicode character, " + "not %.100s", Py_TYPE(obj)->tp_name); + return 0; + } + if (PyUnicode_READY(obj) < 0) + return 0; + if (PyUnicode_GET_LENGTH(obj) != 1) { + PyErr_SetString(PyExc_TypeError, + "The fill character must be exactly one character long"); + return 0; + } + *fillcharloc = PyUnicode_READ_CHAR(obj, 0); + return 1; +} + +/*[clinic input] +str.center as unicode_center + + width: Py_ssize_t + fillchar: Py_UCS4 = ' ' + / + +Return a centered string of length width. + +Padding is done using the specified fill character (default is a space). +[clinic start generated code]*/ + +static PyObject * +unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) +/*[clinic end generated code: output=420c8859effc7c0c input=b42b247eb26e6519]*/ +{ + Py_ssize_t marg, left; + + if (PyUnicode_READY(self) == -1) + return NULL; + + if (PyUnicode_GET_LENGTH(self) >= width) + return unicode_result_unchanged(self); + + marg = width - PyUnicode_GET_LENGTH(self); + left = marg / 2 + (marg & width & 1); + + return pad(self, left, marg - left, fillchar); +} + +/* This function assumes that str1 and str2 are readied by the caller. */ + +static int +unicode_compare(PyObject *str1, PyObject *str2) +{ +#define COMPARE(TYPE1, TYPE2) \ + do { \ + TYPE1* p1 = (TYPE1 *)data1; \ + TYPE2* p2 = (TYPE2 *)data2; \ + TYPE1* end = p1 + len; \ + Py_UCS4 c1, c2; \ + for (; p1 != end; p1++, p2++) { \ + c1 = *p1; \ + c2 = *p2; \ + if (c1 != c2) \ + return (c1 < c2) ? -1 : 1; \ + } \ + } \ + while (0) + + int kind1, kind2; + void *data1, *data2; + Py_ssize_t len1, len2, len; + + kind1 = PyUnicode_KIND(str1); + kind2 = PyUnicode_KIND(str2); + data1 = PyUnicode_DATA(str1); + data2 = PyUnicode_DATA(str2); + len1 = PyUnicode_GET_LENGTH(str1); + len2 = PyUnicode_GET_LENGTH(str2); + len = Py_MIN(len1, len2); + + switch(kind1) { + case PyUnicode_1BYTE_KIND: + { + switch(kind2) { + case PyUnicode_1BYTE_KIND: + { + int cmp = memcmp(data1, data2, len); + /* normalize result of memcmp() into the range [-1; 1] */ + if (cmp < 0) + return -1; + if (cmp > 0) + return 1; + break; + } + case PyUnicode_2BYTE_KIND: + COMPARE(Py_UCS1, Py_UCS2); + break; + case PyUnicode_4BYTE_KIND: + COMPARE(Py_UCS1, Py_UCS4); + break; + default: + Py_UNREACHABLE(); + } + break; + } + case PyUnicode_2BYTE_KIND: + { + switch(kind2) { + case PyUnicode_1BYTE_KIND: + COMPARE(Py_UCS2, Py_UCS1); + break; + case PyUnicode_2BYTE_KIND: + { + COMPARE(Py_UCS2, Py_UCS2); + break; + } + case PyUnicode_4BYTE_KIND: + COMPARE(Py_UCS2, Py_UCS4); + break; + default: + Py_UNREACHABLE(); + } + break; + } + case PyUnicode_4BYTE_KIND: + { + switch(kind2) { + case PyUnicode_1BYTE_KIND: + COMPARE(Py_UCS4, Py_UCS1); + break; + case PyUnicode_2BYTE_KIND: + COMPARE(Py_UCS4, Py_UCS2); + break; + case PyUnicode_4BYTE_KIND: + { +#if defined(HAVE_WMEMCMP) && SIZEOF_WCHAR_T == 4 + int cmp = wmemcmp((wchar_t *)data1, (wchar_t *)data2, len); + /* normalize result of wmemcmp() into the range [-1; 1] */ + if (cmp < 0) + return -1; + if (cmp > 0) + return 1; +#else + COMPARE(Py_UCS4, Py_UCS4); +#endif + break; + } + default: + Py_UNREACHABLE(); + } + break; + } + default: + Py_UNREACHABLE(); + } + + if (len1 == len2) + return 0; + if (len1 < len2) + return -1; + else + return 1; + +#undef COMPARE +} + +static int +unicode_compare_eq(PyObject *str1, PyObject *str2) +{ + int kind; + void *data1, *data2; + Py_ssize_t len; + int cmp; + + len = PyUnicode_GET_LENGTH(str1); + if (PyUnicode_GET_LENGTH(str2) != len) + return 0; + kind = PyUnicode_KIND(str1); + if (PyUnicode_KIND(str2) != kind) + return 0; + data1 = PyUnicode_DATA(str1); + data2 = PyUnicode_DATA(str2); + + cmp = memcmp(data1, data2, len * kind); + return (cmp == 0); +} + + +int +PyUnicode_Compare(PyObject *left, PyObject *right) +{ + if (PyUnicode_Check(left) && PyUnicode_Check(right)) { + if (PyUnicode_READY(left) == -1 || + PyUnicode_READY(right) == -1) + return -1; + + /* a string is equal to itself */ + if (left == right) + return 0; + + return unicode_compare(left, right); + } + PyErr_Format(PyExc_TypeError, + "Can't compare %.100s and %.100s", + left->ob_type->tp_name, + right->ob_type->tp_name); + return -1; +} + +int +PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) +{ + Py_ssize_t i; + int kind; + Py_UCS4 chr; + const unsigned char *ustr = (const unsigned char *)str; + + assert(_PyUnicode_CHECK(uni)); + if (!PyUnicode_IS_READY(uni)) { + const wchar_t *ws = _PyUnicode_WSTR(uni); + /* Compare Unicode string and source character set string */ + for (i = 0; (chr = ws[i]) && ustr[i]; i++) { + if (chr != ustr[i]) + return (chr < ustr[i]) ? -1 : 1; + } + /* This check keeps Python strings that end in '\0' from comparing equal + to C strings identical up to that point. */ + if (_PyUnicode_WSTR_LENGTH(uni) != i || chr) + return 1; /* uni is longer */ + if (ustr[i]) + return -1; /* str is longer */ + return 0; + } + kind = PyUnicode_KIND(uni); + if (kind == PyUnicode_1BYTE_KIND) { + const void *data = PyUnicode_1BYTE_DATA(uni); + size_t len1 = (size_t)PyUnicode_GET_LENGTH(uni); + size_t len, len2 = strlen(str); + int cmp; + + len = Py_MIN(len1, len2); + cmp = memcmp(data, str, len); + if (cmp != 0) { + if (cmp < 0) + return -1; + else + return 1; + } + if (len1 > len2) + return 1; /* uni is longer */ + if (len1 < len2) + return -1; /* str is longer */ + return 0; + } + else { + void *data = PyUnicode_DATA(uni); + /* Compare Unicode string and source character set string */ + for (i = 0; (chr = PyUnicode_READ(kind, data, i)) && str[i]; i++) + if (chr != (unsigned char)str[i]) + return (chr < (unsigned char)(str[i])) ? -1 : 1; + /* This check keeps Python strings that end in '\0' from comparing equal + to C strings identical up to that point. */ + if (PyUnicode_GET_LENGTH(uni) != i || chr) + return 1; /* uni is longer */ + if (str[i]) + return -1; /* str is longer */ + return 0; + } +} + +static int +non_ready_unicode_equal_to_ascii_string(PyObject *unicode, const char *str) +{ + size_t i, len; + const wchar_t *p; + len = (size_t)_PyUnicode_WSTR_LENGTH(unicode); + if (strlen(str) != len) + return 0; + p = _PyUnicode_WSTR(unicode); + assert(p); + for (i = 0; i < len; i++) { + unsigned char c = (unsigned char)str[i]; + if (c >= 128 || p[i] != (wchar_t)c) + return 0; + } + return 1; +} + +int +_PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) +{ + size_t len; + assert(_PyUnicode_CHECK(unicode)); + assert(str); +#ifndef NDEBUG + for (const char *p = str; *p; p++) { + assert((unsigned char)*p < 128); + } +#endif + if (PyUnicode_READY(unicode) == -1) { + /* Memory error or bad data */ + PyErr_Clear(); + return non_ready_unicode_equal_to_ascii_string(unicode, str); + } + if (!PyUnicode_IS_ASCII(unicode)) + return 0; + len = (size_t)PyUnicode_GET_LENGTH(unicode); + return strlen(str) == len && + memcmp(PyUnicode_1BYTE_DATA(unicode), str, len) == 0; +} + +int +_PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right) +{ + PyObject *right_uni; + Py_hash_t hash; + + assert(_PyUnicode_CHECK(left)); + assert(right->string); +#ifndef NDEBUG + for (const char *p = right->string; *p; p++) { + assert((unsigned char)*p < 128); + } +#endif + + if (PyUnicode_READY(left) == -1) { + /* memory error or bad data */ + PyErr_Clear(); + return non_ready_unicode_equal_to_ascii_string(left, right->string); + } + + if (!PyUnicode_IS_ASCII(left)) + return 0; + + right_uni = _PyUnicode_FromId(right); /* borrowed */ + if (right_uni == NULL) { + /* memory error or bad data */ + PyErr_Clear(); + return _PyUnicode_EqualToASCIIString(left, right->string); + } + + if (left == right_uni) + return 1; + + if (PyUnicode_CHECK_INTERNED(left)) + return 0; + + assert(_PyUnicode_HASH(right_uni) != -1); + hash = _PyUnicode_HASH(left); + if (hash != -1 && hash != _PyUnicode_HASH(right_uni)) + return 0; + + return unicode_compare_eq(left, right_uni); +} + +PyObject * +PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) +{ + int result; + + if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) + Py_RETURN_NOTIMPLEMENTED; + + if (PyUnicode_READY(left) == -1 || + PyUnicode_READY(right) == -1) + return NULL; + + if (left == right) { + switch (op) { + case Py_EQ: + case Py_LE: + case Py_GE: + /* a string is equal to itself */ + Py_RETURN_TRUE; + case Py_NE: + case Py_LT: + case Py_GT: + Py_RETURN_FALSE; + default: + PyErr_BadArgument(); + return NULL; + } + } + else if (op == Py_EQ || op == Py_NE) { + result = unicode_compare_eq(left, right); + result ^= (op == Py_NE); + return PyBool_FromLong(result); + } + else { + result = unicode_compare(left, right); + Py_RETURN_RICHCOMPARE(result, 0, op); + } +} + +int +_PyUnicode_EQ(PyObject *aa, PyObject *bb) +{ + return unicode_eq(aa, bb); +} + +int +PyUnicode_Contains(PyObject *str, PyObject *substr) +{ + int kind1, kind2; + void *buf1, *buf2; + Py_ssize_t len1, len2; + int result; + + if (!PyUnicode_Check(substr)) { + PyErr_Format(PyExc_TypeError, + "'in ' requires string as left operand, not %.100s", + Py_TYPE(substr)->tp_name); + return -1; + } + if (PyUnicode_READY(substr) == -1) + return -1; + if (ensure_unicode(str) < 0) + return -1; + + kind1 = PyUnicode_KIND(str); + kind2 = PyUnicode_KIND(substr); + if (kind1 < kind2) + return 0; + len1 = PyUnicode_GET_LENGTH(str); + len2 = PyUnicode_GET_LENGTH(substr); + if (len1 < len2) + return 0; + buf1 = PyUnicode_DATA(str); + buf2 = PyUnicode_DATA(substr); + if (len2 == 1) { + Py_UCS4 ch = PyUnicode_READ(kind2, buf2, 0); + result = findchar((const char *)buf1, kind1, len1, ch, 1) != -1; + return result; + } + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substr, kind1); + if (!buf2) + return -1; + } + + switch (kind1) { + case PyUnicode_1BYTE_KIND: + result = ucs1lib_find(buf1, len1, buf2, len2, 0) != -1; + break; + case PyUnicode_2BYTE_KIND: + result = ucs2lib_find(buf1, len1, buf2, len2, 0) != -1; + break; + case PyUnicode_4BYTE_KIND: + result = ucs4lib_find(buf1, len1, buf2, len2, 0) != -1; + break; + default: + Py_UNREACHABLE(); + } + + if (kind2 != kind1) + PyMem_Free(buf2); + + return result; +} + +/* Concat to string or Unicode object giving a new Unicode object. */ + +PyObject * +PyUnicode_Concat(PyObject *left, PyObject *right) +{ + PyObject *result; + Py_UCS4 maxchar, maxchar2; + Py_ssize_t left_len, right_len, new_len; + + if (ensure_unicode(left) < 0) + return NULL; + + if (!PyUnicode_Check(right)) { + PyErr_Format(PyExc_TypeError, + "can only concatenate str (not \"%.200s\") to str", + right->ob_type->tp_name); + return NULL; + } + if (PyUnicode_READY(right) < 0) + return NULL; + + /* Shortcuts */ + if (left == unicode_empty) + return PyUnicode_FromObject(right); + if (right == unicode_empty) + return PyUnicode_FromObject(left); + + left_len = PyUnicode_GET_LENGTH(left); + right_len = PyUnicode_GET_LENGTH(right); + if (left_len > PY_SSIZE_T_MAX - right_len) { + PyErr_SetString(PyExc_OverflowError, + "strings are too large to concat"); + return NULL; + } + new_len = left_len + right_len; + + maxchar = PyUnicode_MAX_CHAR_VALUE(left); + maxchar2 = PyUnicode_MAX_CHAR_VALUE(right); + maxchar = Py_MAX(maxchar, maxchar2); + + /* Concat the two Unicode strings */ + result = PyUnicode_New(new_len, maxchar); + if (result == NULL) + return NULL; + _PyUnicode_FastCopyCharacters(result, 0, left, 0, left_len); + _PyUnicode_FastCopyCharacters(result, left_len, right, 0, right_len); + assert(_PyUnicode_CheckConsistency(result, 1)); + return result; +} + +void +PyUnicode_Append(PyObject **p_left, PyObject *right) +{ + PyObject *left, *res; + Py_UCS4 maxchar, maxchar2; + Py_ssize_t left_len, right_len, new_len; + + if (p_left == NULL) { + if (!PyErr_Occurred()) + PyErr_BadInternalCall(); + return; + } + left = *p_left; + if (right == NULL || left == NULL + || !PyUnicode_Check(left) || !PyUnicode_Check(right)) { + if (!PyErr_Occurred()) + PyErr_BadInternalCall(); + goto error; + } + + if (PyUnicode_READY(left) == -1) + goto error; + if (PyUnicode_READY(right) == -1) + goto error; + + /* Shortcuts */ + if (left == unicode_empty) { + Py_DECREF(left); + Py_INCREF(right); + *p_left = right; + return; + } + if (right == unicode_empty) + return; + + left_len = PyUnicode_GET_LENGTH(left); + right_len = PyUnicode_GET_LENGTH(right); + if (left_len > PY_SSIZE_T_MAX - right_len) { + PyErr_SetString(PyExc_OverflowError, + "strings are too large to concat"); + goto error; + } + new_len = left_len + right_len; + + if (unicode_modifiable(left) + && PyUnicode_CheckExact(right) + && PyUnicode_KIND(right) <= PyUnicode_KIND(left) + /* Don't resize for ascii += latin1. Convert ascii to latin1 requires + to change the structure size, but characters are stored just after + the structure, and so it requires to move all characters which is + not so different than duplicating the string. */ + && !(PyUnicode_IS_ASCII(left) && !PyUnicode_IS_ASCII(right))) + { + /* append inplace */ + if (unicode_resize(p_left, new_len) != 0) + goto error; + + /* copy 'right' into the newly allocated area of 'left' */ + _PyUnicode_FastCopyCharacters(*p_left, left_len, right, 0, right_len); + } + else { + maxchar = PyUnicode_MAX_CHAR_VALUE(left); + maxchar2 = PyUnicode_MAX_CHAR_VALUE(right); + maxchar = Py_MAX(maxchar, maxchar2); + + /* Concat the two Unicode strings */ + res = PyUnicode_New(new_len, maxchar); + if (res == NULL) + goto error; + _PyUnicode_FastCopyCharacters(res, 0, left, 0, left_len); + _PyUnicode_FastCopyCharacters(res, left_len, right, 0, right_len); + Py_DECREF(left); + *p_left = res; + } + assert(_PyUnicode_CheckConsistency(*p_left, 1)); + return; + +error: + Py_CLEAR(*p_left); +} + +void +PyUnicode_AppendAndDel(PyObject **pleft, PyObject *right) +{ + PyUnicode_Append(pleft, right); + Py_XDECREF(right); +} + +/* +Wraps stringlib_parse_args_finds() and additionally ensures that the +first argument is a unicode object. +*/ + +static inline int +parse_args_finds_unicode(const char * function_name, PyObject *args, + PyObject **substring, + Py_ssize_t *start, Py_ssize_t *end) +{ + if(stringlib_parse_args_finds(function_name, args, substring, + start, end)) { + if (ensure_unicode(*substring) < 0) + return 0; + return 1; + } + return 0; +} + +PyDoc_STRVAR(count__doc__, + "S.count(sub[, start[, end]]) -> int\n\ +\n\ +Return the number of non-overlapping occurrences of substring sub in\n\ +string S[start:end]. Optional arguments start and end are\n\ +interpreted as in slice notation."); + +static PyObject * +unicode_count(PyObject *self, PyObject *args) +{ + PyObject *substring = NULL; /* initialize to fix a compiler warning */ + Py_ssize_t start = 0; + Py_ssize_t end = PY_SSIZE_T_MAX; + PyObject *result; + int kind1, kind2; + void *buf1, *buf2; + Py_ssize_t len1, len2, iresult; + + if (!parse_args_finds_unicode("count", args, &substring, &start, &end)) + return NULL; + + kind1 = PyUnicode_KIND(self); + kind2 = PyUnicode_KIND(substring); + if (kind1 < kind2) + return PyLong_FromLong(0); + + len1 = PyUnicode_GET_LENGTH(self); + len2 = PyUnicode_GET_LENGTH(substring); + ADJUST_INDICES(start, end, len1); + if (end - start < len2) + return PyLong_FromLong(0); + + buf1 = PyUnicode_DATA(self); + buf2 = PyUnicode_DATA(substring); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) + return NULL; + } + switch (kind1) { + case PyUnicode_1BYTE_KIND: + iresult = ucs1lib_count( + ((Py_UCS1*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); + break; + case PyUnicode_2BYTE_KIND: + iresult = ucs2lib_count( + ((Py_UCS2*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); + break; + case PyUnicode_4BYTE_KIND: + iresult = ucs4lib_count( + ((Py_UCS4*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); + break; + default: + Py_UNREACHABLE(); + } + + result = PyLong_FromSsize_t(iresult); + + if (kind2 != kind1) + PyMem_Free(buf2); + + return result; +} + +/*[clinic input] +str.encode as unicode_encode + + encoding: str(c_default="NULL") = 'utf-8' + The encoding in which to encode the string. + errors: str(c_default="NULL") = 'strict' + The error handling scheme to use for encoding errors. + The 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. + +Encode the string using the codec registered for encoding. +[clinic start generated code]*/ + +static PyObject * +unicode_encode_impl(PyObject *self, const char *encoding, const char *errors) +/*[clinic end generated code: output=bf78b6e2a9470e3c input=f0a9eb293d08fe02]*/ +{ + return PyUnicode_AsEncodedString(self, encoding, errors); +} + +/*[clinic input] +str.expandtabs as unicode_expandtabs + + tabsize: int = 8 + +Return a copy where all tab characters are expanded using spaces. + +If tabsize is not given, a tab size of 8 characters is assumed. +[clinic start generated code]*/ + +static PyObject * +unicode_expandtabs_impl(PyObject *self, int tabsize) +/*[clinic end generated code: output=3457c5dcee26928f input=8a01914034af4c85]*/ +{ + Py_ssize_t i, j, line_pos, src_len, incr; + Py_UCS4 ch; + PyObject *u; + void *src_data, *dest_data; + int kind; + int found; + + if (PyUnicode_READY(self) == -1) + return NULL; + + /* First pass: determine size of output string */ + src_len = PyUnicode_GET_LENGTH(self); + i = j = line_pos = 0; + kind = PyUnicode_KIND(self); + src_data = PyUnicode_DATA(self); + found = 0; + for (; i < src_len; i++) { + ch = PyUnicode_READ(kind, src_data, i); + if (ch == '\t') { + found = 1; + if (tabsize > 0) { + incr = tabsize - (line_pos % tabsize); /* cannot overflow */ + if (j > PY_SSIZE_T_MAX - incr) + goto overflow; + line_pos += incr; + j += incr; + } + } + else { + if (j > PY_SSIZE_T_MAX - 1) + goto overflow; + line_pos++; + j++; + if (ch == '\n' || ch == '\r') + line_pos = 0; + } + } + if (!found) + return unicode_result_unchanged(self); + + /* Second pass: create output string and fill it */ + u = PyUnicode_New(j, PyUnicode_MAX_CHAR_VALUE(self)); + if (!u) + return NULL; + dest_data = PyUnicode_DATA(u); + + i = j = line_pos = 0; + + for (; i < src_len; i++) { + ch = PyUnicode_READ(kind, src_data, i); + if (ch == '\t') { + if (tabsize > 0) { + incr = tabsize - (line_pos % tabsize); + line_pos += incr; + unicode_fill(kind, dest_data, ' ', j, incr); + j += incr; + } + } + else { + line_pos++; + PyUnicode_WRITE(kind, dest_data, j, ch); + j++; + if (ch == '\n' || ch == '\r') + line_pos = 0; + } + } + assert (j == PyUnicode_GET_LENGTH(u)); + return unicode_result(u); + + overflow: + PyErr_SetString(PyExc_OverflowError, "new string is too long"); + return NULL; +} + +PyDoc_STRVAR(find__doc__, + "S.find(sub[, start[, end]]) -> int\n\ +\n\ +Return the lowest index in S where substring sub is found,\n\ +such that sub is contained within S[start:end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Return -1 on failure."); + +static PyObject * +unicode_find(PyObject *self, PyObject *args) +{ + /* initialize variables to prevent gcc warning */ + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; + Py_ssize_t result; + + if (!parse_args_finds_unicode("find", args, &substring, &start, &end)) + return NULL; + + if (PyUnicode_READY(self) == -1) + return NULL; + + result = any_find_slice(self, substring, start, end, 1); + + if (result == -2) + return NULL; + + return PyLong_FromSsize_t(result); +} + +static PyObject * +unicode_getitem(PyObject *self, Py_ssize_t index) +{ + void *data; + enum PyUnicode_Kind kind; + Py_UCS4 ch; + + if (!PyUnicode_Check(self)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(self) == -1) { + return NULL; + } + if (index < 0 || index >= PyUnicode_GET_LENGTH(self)) { + PyErr_SetString(PyExc_IndexError, "string index out of range"); + return NULL; + } + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + ch = PyUnicode_READ(kind, data, index); + return unicode_char(ch); +} + +/* Believe it or not, this produces the same value for ASCII strings + as bytes_hash(). */ +static Py_hash_t +unicode_hash(PyObject *self) +{ + Py_uhash_t x; /* Unsigned for defined overflow behavior. */ + +#ifdef Py_DEBUG + assert(_Py_HashSecret_Initialized); +#endif + if (_PyUnicode_HASH(self) != -1) + return _PyUnicode_HASH(self); + if (PyUnicode_READY(self) == -1) + return -1; + + x = _Py_HashBytes(PyUnicode_DATA(self), + PyUnicode_GET_LENGTH(self) * PyUnicode_KIND(self)); + _PyUnicode_HASH(self) = x; + return x; +} + +PyDoc_STRVAR(index__doc__, + "S.index(sub[, start[, end]]) -> int\n\ +\n\ +Return the lowest index in S where substring sub is found,\n\ +such that sub is contained within S[start:end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Raises ValueError when the substring is not found."); + +static PyObject * +unicode_index(PyObject *self, PyObject *args) +{ + /* initialize variables to prevent gcc warning */ + Py_ssize_t result; + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; + + if (!parse_args_finds_unicode("index", args, &substring, &start, &end)) + return NULL; + + if (PyUnicode_READY(self) == -1) + return NULL; + + result = any_find_slice(self, substring, start, end, 1); + + if (result == -2) + return NULL; + + if (result < 0) { + PyErr_SetString(PyExc_ValueError, "substring not found"); + return NULL; + } + + return PyLong_FromSsize_t(result); +} + +/*[clinic input] +str.isascii as unicode_isascii + +Return True if all characters in the string are ASCII, False otherwise. + +ASCII characters have code points in the range U+0000-U+007F. +Empty string is ASCII too. +[clinic start generated code]*/ + +static PyObject * +unicode_isascii_impl(PyObject *self) +/*[clinic end generated code: output=c5910d64b5a8003f input=5a43cbc6399621d5]*/ +{ + if (PyUnicode_READY(self) == -1) { + return NULL; + } + return PyBool_FromLong(PyUnicode_IS_ASCII(self)); +} + +/*[clinic input] +str.islower as unicode_islower + +Return True if the string is a lowercase string, False otherwise. + +A string is lowercase if all cased characters in the string are lowercase and +there is at least one cased character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_islower_impl(PyObject *self) +/*[clinic end generated code: output=dbd41995bd005b81 input=acec65ac6821ae47]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + int cased; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) + return PyBool_FromLong( + Py_UNICODE_ISLOWER(PyUnicode_READ(kind, data, 0))); + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + cased = 0; + for (i = 0; i < length; i++) { + const Py_UCS4 ch = PyUnicode_READ(kind, data, i); + + if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) + Py_RETURN_FALSE; + else if (!cased && Py_UNICODE_ISLOWER(ch)) + cased = 1; + } + return PyBool_FromLong(cased); +} + +/*[clinic input] +str.isupper as unicode_isupper + +Return True if the string is an uppercase string, False otherwise. + +A string is uppercase if all cased characters in the string are uppercase and +there is at least one cased character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_isupper_impl(PyObject *self) +/*[clinic end generated code: output=049209c8e7f15f59 input=e9b1feda5d17f2d3]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + int cased; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) + return PyBool_FromLong( + Py_UNICODE_ISUPPER(PyUnicode_READ(kind, data, 0)) != 0); + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + cased = 0; + for (i = 0; i < length; i++) { + const Py_UCS4 ch = PyUnicode_READ(kind, data, i); + + if (Py_UNICODE_ISLOWER(ch) || Py_UNICODE_ISTITLE(ch)) + Py_RETURN_FALSE; + else if (!cased && Py_UNICODE_ISUPPER(ch)) + cased = 1; + } + return PyBool_FromLong(cased); +} + +/*[clinic input] +str.istitle as unicode_istitle + +Return True if the string is a title-cased string, False otherwise. + +In a title-cased string, upper- and title-case characters may only +follow uncased characters and lowercase characters only cased ones. +[clinic start generated code]*/ + +static PyObject * +unicode_istitle_impl(PyObject *self) +/*[clinic end generated code: output=e9bf6eb91f5d3f0e input=98d32bd2e1f06f8c]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + int cased, previous_is_cased; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) { + Py_UCS4 ch = PyUnicode_READ(kind, data, 0); + return PyBool_FromLong((Py_UNICODE_ISTITLE(ch) != 0) || + (Py_UNICODE_ISUPPER(ch) != 0)); + } + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + cased = 0; + previous_is_cased = 0; + for (i = 0; i < length; i++) { + const Py_UCS4 ch = PyUnicode_READ(kind, data, i); + + if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) { + if (previous_is_cased) + Py_RETURN_FALSE; + previous_is_cased = 1; + cased = 1; + } + else if (Py_UNICODE_ISLOWER(ch)) { + if (!previous_is_cased) + Py_RETURN_FALSE; + previous_is_cased = 1; + cased = 1; + } + else + previous_is_cased = 0; + } + return PyBool_FromLong(cased); +} + +/*[clinic input] +str.isspace as unicode_isspace + +Return True if the string is a whitespace string, False otherwise. + +A string is whitespace if all characters in the string are whitespace and there +is at least one character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_isspace_impl(PyObject *self) +/*[clinic end generated code: output=163a63bfa08ac2b9 input=fe462cb74f8437d8]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) + return PyBool_FromLong( + Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, 0))); + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + for (i = 0; i < length; i++) { + const Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (!Py_UNICODE_ISSPACE(ch)) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + +/*[clinic input] +str.isalpha as unicode_isalpha + +Return True if the string is an alphabetic string, False otherwise. + +A string is alphabetic if all characters in the string are alphabetic and there +is at least one character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_isalpha_impl(PyObject *self) +/*[clinic end generated code: output=cc81b9ac3883ec4f input=d0fd18a96cbca5eb]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) + return PyBool_FromLong( + Py_UNICODE_ISALPHA(PyUnicode_READ(kind, data, 0))); + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + for (i = 0; i < length; i++) { + if (!Py_UNICODE_ISALPHA(PyUnicode_READ(kind, data, i))) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + +/*[clinic input] +str.isalnum as unicode_isalnum + +Return True if the string is an alpha-numeric string, False otherwise. + +A string is alpha-numeric if all characters in the string are alpha-numeric and +there is at least one character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_isalnum_impl(PyObject *self) +/*[clinic end generated code: output=a5a23490ffc3660c input=5c6579bf2e04758c]*/ +{ + int kind; + void *data; + Py_ssize_t len, i; + + if (PyUnicode_READY(self) == -1) + return NULL; + + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + len = PyUnicode_GET_LENGTH(self); + + /* Shortcut for single character strings */ + if (len == 1) { + const Py_UCS4 ch = PyUnicode_READ(kind, data, 0); + return PyBool_FromLong(Py_UNICODE_ISALNUM(ch)); + } + + /* Special case for empty strings */ + if (len == 0) + Py_RETURN_FALSE; + + for (i = 0; i < len; i++) { + const Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (!Py_UNICODE_ISALNUM(ch)) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + +/*[clinic input] +str.isdecimal as unicode_isdecimal + +Return True if the string is a decimal string, False otherwise. + +A string is a decimal string if all characters in the string are decimal and +there is at least one character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_isdecimal_impl(PyObject *self) +/*[clinic end generated code: output=fb2dcdb62d3fc548 input=336bc97ab4c8268f]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) + return PyBool_FromLong( + Py_UNICODE_ISDECIMAL(PyUnicode_READ(kind, data, 0))); + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + for (i = 0; i < length; i++) { + if (!Py_UNICODE_ISDECIMAL(PyUnicode_READ(kind, data, i))) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + +/*[clinic input] +str.isdigit as unicode_isdigit + +Return True if the string is a digit string, False otherwise. + +A string is a digit string if all characters in the string are digits and there +is at least one character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_isdigit_impl(PyObject *self) +/*[clinic end generated code: output=10a6985311da6858 input=901116c31deeea4c]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) { + const Py_UCS4 ch = PyUnicode_READ(kind, data, 0); + return PyBool_FromLong(Py_UNICODE_ISDIGIT(ch)); + } + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + for (i = 0; i < length; i++) { + if (!Py_UNICODE_ISDIGIT(PyUnicode_READ(kind, data, i))) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + +/*[clinic input] +str.isnumeric as unicode_isnumeric + +Return True if the string is a numeric string, False otherwise. + +A string is numeric if all characters in the string are numeric and there is at +least one character in the string. +[clinic start generated code]*/ + +static PyObject * +unicode_isnumeric_impl(PyObject *self) +/*[clinic end generated code: output=9172a32d9013051a input=722507db976f826c]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) + return PyBool_FromLong( + Py_UNICODE_ISNUMERIC(PyUnicode_READ(kind, data, 0))); + + /* Special case for empty strings */ + if (length == 0) + Py_RETURN_FALSE; + + for (i = 0; i < length; i++) { + if (!Py_UNICODE_ISNUMERIC(PyUnicode_READ(kind, data, i))) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + +int +PyUnicode_IsIdentifier(PyObject *self) +{ + int kind; + void *data; + Py_ssize_t i; + Py_UCS4 first; + + if (PyUnicode_READY(self) == -1) { + Py_FatalError("identifier not ready"); + return 0; + } + + /* Special case for empty strings */ + if (PyUnicode_GET_LENGTH(self) == 0) + return 0; + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* PEP 3131 says that the first character must be in + XID_Start and subsequent characters in XID_Continue, + and for the ASCII range, the 2.x rules apply (i.e + start with letters and underscore, continue with + letters, digits, underscore). However, given the current + definition of XID_Start and XID_Continue, it is sufficient + to check just for these, except that _ must be allowed + as starting an identifier. */ + first = PyUnicode_READ(kind, data, 0); + if (!_PyUnicode_IsXidStart(first) && first != 0x5F /* LOW LINE */) + return 0; + + for (i = 1; i < PyUnicode_GET_LENGTH(self); i++) + if (!_PyUnicode_IsXidContinue(PyUnicode_READ(kind, data, i))) + return 0; + return 1; +} + +/*[clinic input] +str.isidentifier as unicode_isidentifier + +Return True if the string is a valid Python identifier, False otherwise. + +Call keyword.iskeyword(s) to test whether string s is a reserved identifier, +such as "def" or "class". +[clinic start generated code]*/ + +static PyObject * +unicode_isidentifier_impl(PyObject *self) +/*[clinic end generated code: output=fe585a9666572905 input=2d807a104f21c0c5]*/ +{ + return PyBool_FromLong(PyUnicode_IsIdentifier(self)); +} + +/*[clinic input] +str.isprintable as unicode_isprintable + +Return True if the string is printable, False otherwise. + +A string is printable if all of its characters are considered printable in +repr() or if it is empty. +[clinic start generated code]*/ + +static PyObject * +unicode_isprintable_impl(PyObject *self) +/*[clinic end generated code: output=3ab9626cd32dd1a0 input=98a0e1c2c1813209]*/ +{ + Py_ssize_t i, length; + int kind; + void *data; + + if (PyUnicode_READY(self) == -1) + return NULL; + length = PyUnicode_GET_LENGTH(self); + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + + /* Shortcut for single character strings */ + if (length == 1) + return PyBool_FromLong( + Py_UNICODE_ISPRINTABLE(PyUnicode_READ(kind, data, 0))); + + for (i = 0; i < length; i++) { + if (!Py_UNICODE_ISPRINTABLE(PyUnicode_READ(kind, data, i))) { + Py_RETURN_FALSE; + } + } + Py_RETURN_TRUE; +} + +/*[clinic input] +str.join as unicode_join + + iterable: object + / + +Concatenate any number of strings. + +The string whose method is called is inserted in between each given string. +The result is returned as a new string. + +Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs' +[clinic start generated code]*/ + +static PyObject * +unicode_join(PyObject *self, PyObject *iterable) +/*[clinic end generated code: output=6857e7cecfe7bf98 input=2f70422bfb8fa189]*/ +{ + return PyUnicode_Join(self, iterable); +} + +static Py_ssize_t +unicode_length(PyObject *self) +{ + if (PyUnicode_READY(self) == -1) + return -1; + return PyUnicode_GET_LENGTH(self); +} + +/*[clinic input] +str.ljust as unicode_ljust + + width: Py_ssize_t + fillchar: Py_UCS4 = ' ' + / + +Return a left-justified string of length width. + +Padding is done using the specified fill character (default is a space). +[clinic start generated code]*/ + +static PyObject * +unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) +/*[clinic end generated code: output=1cce0e0e0a0b84b3 input=3ab599e335e60a32]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + + if (PyUnicode_GET_LENGTH(self) >= width) + return unicode_result_unchanged(self); + + return pad(self, 0, width - PyUnicode_GET_LENGTH(self), fillchar); +} + +/*[clinic input] +str.lower as unicode_lower + +Return a copy of the string converted to lowercase. +[clinic start generated code]*/ + +static PyObject * +unicode_lower_impl(PyObject *self) +/*[clinic end generated code: output=84ef9ed42efad663 input=60a2984b8beff23a]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + if (PyUnicode_IS_ASCII(self)) + return ascii_upper_or_lower(self, 1); + return case_operation(self, do_lower); +} + +#define LEFTSTRIP 0 +#define RIGHTSTRIP 1 +#define BOTHSTRIP 2 + +/* Arrays indexed by above */ +static const char *stripfuncnames[] = {"lstrip", "rstrip", "strip"}; + +#define STRIPNAME(i) (stripfuncnames[i]) + +/* externally visible for str.strip(unicode) */ +PyObject * +_PyUnicode_XStrip(PyObject *self, int striptype, PyObject *sepobj) +{ + void *data; + int kind; + Py_ssize_t i, j, len; + BLOOM_MASK sepmask; + Py_ssize_t seplen; + + if (PyUnicode_READY(self) == -1 || PyUnicode_READY(sepobj) == -1) + return NULL; + + kind = PyUnicode_KIND(self); + data = PyUnicode_DATA(self); + len = PyUnicode_GET_LENGTH(self); + seplen = PyUnicode_GET_LENGTH(sepobj); + sepmask = make_bloom_mask(PyUnicode_KIND(sepobj), + PyUnicode_DATA(sepobj), + seplen); + + i = 0; + if (striptype != RIGHTSTRIP) { + while (i < len) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (!BLOOM(sepmask, ch)) + break; + if (PyUnicode_FindChar(sepobj, ch, 0, seplen, 1) < 0) + break; + i++; + } + } + + j = len; + if (striptype != LEFTSTRIP) { + j--; + while (j >= i) { + Py_UCS4 ch = PyUnicode_READ(kind, data, j); + if (!BLOOM(sepmask, ch)) + break; + if (PyUnicode_FindChar(sepobj, ch, 0, seplen, 1) < 0) + break; + j--; + } + + j++; + } + + return PyUnicode_Substring(self, i, j); +} + +PyObject* +PyUnicode_Substring(PyObject *self, Py_ssize_t start, Py_ssize_t end) +{ + unsigned char *data; + int kind; + Py_ssize_t length; + + if (PyUnicode_READY(self) == -1) + return NULL; + + length = PyUnicode_GET_LENGTH(self); + end = Py_MIN(end, length); + + if (start == 0 && end == length) + return unicode_result_unchanged(self); + + if (start < 0 || end < 0) { + PyErr_SetString(PyExc_IndexError, "string index out of range"); + return NULL; + } + if (start >= length || end < start) + _Py_RETURN_UNICODE_EMPTY(); + + length = end - start; + if (PyUnicode_IS_ASCII(self)) { + data = PyUnicode_1BYTE_DATA(self); + return _PyUnicode_FromASCII((char*)(data + start), length); + } + else { + kind = PyUnicode_KIND(self); + data = PyUnicode_1BYTE_DATA(self); + return PyUnicode_FromKindAndData(kind, + data + kind * start, + length); + } +} + +static PyObject * +do_strip(PyObject *self, int striptype) +{ + Py_ssize_t len, i, j; + + if (PyUnicode_READY(self) == -1) + return NULL; + + len = PyUnicode_GET_LENGTH(self); + + if (PyUnicode_IS_ASCII(self)) { + Py_UCS1 *data = PyUnicode_1BYTE_DATA(self); + + i = 0; + if (striptype != RIGHTSTRIP) { + while (i < len) { + Py_UCS1 ch = data[i]; + if (!_Py_ascii_whitespace[ch]) + break; + i++; + } + } + + j = len; + if (striptype != LEFTSTRIP) { + j--; + while (j >= i) { + Py_UCS1 ch = data[j]; + if (!_Py_ascii_whitespace[ch]) + break; + j--; + } + j++; + } + } + else { + int kind = PyUnicode_KIND(self); + void *data = PyUnicode_DATA(self); + + i = 0; + if (striptype != RIGHTSTRIP) { + while (i < len) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (!Py_UNICODE_ISSPACE(ch)) + break; + i++; + } + } + + j = len; + if (striptype != LEFTSTRIP) { + j--; + while (j >= i) { + Py_UCS4 ch = PyUnicode_READ(kind, data, j); + if (!Py_UNICODE_ISSPACE(ch)) + break; + j--; + } + j++; + } + } + + return PyUnicode_Substring(self, i, j); +} + + +static PyObject * +do_argstrip(PyObject *self, int striptype, PyObject *sep) +{ + if (sep != Py_None) { + if (PyUnicode_Check(sep)) + return _PyUnicode_XStrip(self, striptype, sep); + else { + PyErr_Format(PyExc_TypeError, + "%s arg must be None or str", + STRIPNAME(striptype)); + return NULL; + } + } + + return do_strip(self, striptype); +} + + +/*[clinic input] +str.strip as unicode_strip + + chars: object = None + / + +Return a copy of the string with leading and trailing whitespace removed. + +If chars is given and not None, remove characters in chars instead. +[clinic start generated code]*/ + +static PyObject * +unicode_strip_impl(PyObject *self, PyObject *chars) +/*[clinic end generated code: output=ca19018454345d57 input=385289c6f423b954]*/ +{ + return do_argstrip(self, BOTHSTRIP, chars); +} + + +/*[clinic input] +str.lstrip as unicode_lstrip + + chars: object = None + / + +Return a copy of the string with leading whitespace removed. + +If chars is given and not None, remove characters in chars instead. +[clinic start generated code]*/ + +static PyObject * +unicode_lstrip_impl(PyObject *self, PyObject *chars) +/*[clinic end generated code: output=3b43683251f79ca7 input=529f9f3834448671]*/ +{ + return do_argstrip(self, LEFTSTRIP, chars); +} + + +/*[clinic input] +str.rstrip as unicode_rstrip + + chars: object = None + / + +Return a copy of the string with trailing whitespace removed. + +If chars is given and not None, remove characters in chars instead. +[clinic start generated code]*/ + +static PyObject * +unicode_rstrip_impl(PyObject *self, PyObject *chars) +/*[clinic end generated code: output=4a59230017cc3b7a input=62566c627916557f]*/ +{ + return do_argstrip(self, RIGHTSTRIP, chars); +} + + +static PyObject* +unicode_repeat(PyObject *str, Py_ssize_t len) +{ + PyObject *u; + Py_ssize_t nchars, n; + + if (len < 1) + _Py_RETURN_UNICODE_EMPTY(); + + /* no repeat, return original string */ + if (len == 1) + return unicode_result_unchanged(str); + + if (PyUnicode_READY(str) == -1) + return NULL; + + if (PyUnicode_GET_LENGTH(str) > PY_SSIZE_T_MAX / len) { + PyErr_SetString(PyExc_OverflowError, + "repeated string is too long"); + return NULL; + } + nchars = len * PyUnicode_GET_LENGTH(str); + + u = PyUnicode_New(nchars, PyUnicode_MAX_CHAR_VALUE(str)); + if (!u) + return NULL; + assert(PyUnicode_KIND(u) == PyUnicode_KIND(str)); + + if (PyUnicode_GET_LENGTH(str) == 1) { + const int kind = PyUnicode_KIND(str); + const Py_UCS4 fill_char = PyUnicode_READ(kind, PyUnicode_DATA(str), 0); + if (kind == PyUnicode_1BYTE_KIND) { + void *to = PyUnicode_DATA(u); + memset(to, (unsigned char)fill_char, len); + } + else if (kind == PyUnicode_2BYTE_KIND) { + Py_UCS2 *ucs2 = PyUnicode_2BYTE_DATA(u); + for (n = 0; n < len; ++n) + ucs2[n] = fill_char; + } else { + Py_UCS4 *ucs4 = PyUnicode_4BYTE_DATA(u); + assert(kind == PyUnicode_4BYTE_KIND); + for (n = 0; n < len; ++n) + ucs4[n] = fill_char; + } + } + else { + /* number of characters copied this far */ + Py_ssize_t done = PyUnicode_GET_LENGTH(str); + const Py_ssize_t char_size = PyUnicode_KIND(str); + char *to = (char *) PyUnicode_DATA(u); + memcpy(to, PyUnicode_DATA(str), + PyUnicode_GET_LENGTH(str) * char_size); + while (done < nchars) { + n = (done <= nchars-done) ? done : nchars-done; + memcpy(to + (done * char_size), to, n * char_size); + done += n; + } + } + + assert(_PyUnicode_CheckConsistency(u, 1)); + return u; +} + +PyObject * +PyUnicode_Replace(PyObject *str, + PyObject *substr, + PyObject *replstr, + Py_ssize_t maxcount) +{ + if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0 || + ensure_unicode(replstr) < 0) + return NULL; + return replace(str, substr, replstr, maxcount); +} + +/*[clinic input] +str.replace as unicode_replace + + old: unicode + new: unicode + count: Py_ssize_t = -1 + Maximum number of occurrences to replace. + -1 (the default value) means replace all occurrences. + / + +Return a copy with all occurrences of substring old replaced by new. + +If the optional argument count is given, only the first count occurrences are +replaced. +[clinic start generated code]*/ + +static PyObject * +unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new, + Py_ssize_t count) +/*[clinic end generated code: output=b63f1a8b5eebf448 input=147d12206276ebeb]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + return replace(self, old, new, count); +} + +static PyObject * +unicode_repr(PyObject *unicode) +{ + PyObject *repr; + Py_ssize_t isize; + Py_ssize_t osize, squote, dquote, i, o; + Py_UCS4 max, quote; + int ikind, okind, unchanged; + void *idata, *odata; + + if (PyUnicode_READY(unicode) == -1) + return NULL; + + isize = PyUnicode_GET_LENGTH(unicode); + idata = PyUnicode_DATA(unicode); + + /* Compute length of output, quote characters, and + maximum character */ + osize = 0; + max = 127; + squote = dquote = 0; + ikind = PyUnicode_KIND(unicode); + for (i = 0; i < isize; i++) { + Py_UCS4 ch = PyUnicode_READ(ikind, idata, i); + Py_ssize_t incr = 1; + switch (ch) { + case '\'': squote++; break; + case '"': dquote++; break; + case '\\': case '\t': case '\r': case '\n': + incr = 2; + break; + default: + /* Fast-path ASCII */ + if (ch < ' ' || ch == 0x7f) + incr = 4; /* \xHH */ + else if (ch < 0x7f) + ; + else if (Py_UNICODE_ISPRINTABLE(ch)) + max = ch > max ? ch : max; + else if (ch < 0x100) + incr = 4; /* \xHH */ + else if (ch < 0x10000) + incr = 6; /* \uHHHH */ + else + incr = 10; /* \uHHHHHHHH */ + } + if (osize > PY_SSIZE_T_MAX - incr) { + PyErr_SetString(PyExc_OverflowError, + "string is too long to generate repr"); + return NULL; + } + osize += incr; + } + + quote = '\''; + unchanged = (osize == isize); + if (squote) { + unchanged = 0; + if (dquote) + /* Both squote and dquote present. Use squote, + and escape them */ + osize += squote; + else + quote = '"'; + } + osize += 2; /* quotes */ + + repr = PyUnicode_New(osize, max); + if (repr == NULL) + return NULL; + okind = PyUnicode_KIND(repr); + odata = PyUnicode_DATA(repr); + + PyUnicode_WRITE(okind, odata, 0, quote); + PyUnicode_WRITE(okind, odata, osize-1, quote); + if (unchanged) { + _PyUnicode_FastCopyCharacters(repr, 1, + unicode, 0, + isize); + } + else { + for (i = 0, o = 1; i < isize; i++) { + Py_UCS4 ch = PyUnicode_READ(ikind, idata, i); + + /* Escape quotes and backslashes */ + if ((ch == quote) || (ch == '\\')) { + PyUnicode_WRITE(okind, odata, o++, '\\'); + PyUnicode_WRITE(okind, odata, o++, ch); + continue; + } + + /* Map special whitespace to '\t', \n', '\r' */ + if (ch == '\t') { + PyUnicode_WRITE(okind, odata, o++, '\\'); + PyUnicode_WRITE(okind, odata, o++, 't'); + } + else if (ch == '\n') { + PyUnicode_WRITE(okind, odata, o++, '\\'); + PyUnicode_WRITE(okind, odata, o++, 'n'); + } + else if (ch == '\r') { + PyUnicode_WRITE(okind, odata, o++, '\\'); + PyUnicode_WRITE(okind, odata, o++, 'r'); + } + + /* Map non-printable US ASCII to '\xhh' */ + else if (ch < ' ' || ch == 0x7F) { + PyUnicode_WRITE(okind, odata, o++, '\\'); + PyUnicode_WRITE(okind, odata, o++, 'x'); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0x000F]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0x000F]); + } + + /* Copy ASCII characters as-is */ + else if (ch < 0x7F) { + PyUnicode_WRITE(okind, odata, o++, ch); + } + + /* Non-ASCII characters */ + else { + /* Map Unicode whitespace and control characters + (categories Z* and C* except ASCII space) + */ + if (!Py_UNICODE_ISPRINTABLE(ch)) { + PyUnicode_WRITE(okind, odata, o++, '\\'); + /* Map 8-bit characters to '\xhh' */ + if (ch <= 0xff) { + PyUnicode_WRITE(okind, odata, o++, 'x'); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0x000F]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0x000F]); + } + /* Map 16-bit characters to '\uxxxx' */ + else if (ch <= 0xffff) { + PyUnicode_WRITE(okind, odata, o++, 'u'); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 12) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 8) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0xF]); + } + /* Map 21-bit characters to '\U00xxxxxx' */ + else { + PyUnicode_WRITE(okind, odata, o++, 'U'); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 28) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 24) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 20) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 16) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 12) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 8) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0xF]); + PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0xF]); + } + } + /* Copy characters as-is */ + else { + PyUnicode_WRITE(okind, odata, o++, ch); + } + } + } + } + /* Closing quote already added at the beginning */ + assert(_PyUnicode_CheckConsistency(repr, 1)); + return repr; +} + +PyDoc_STRVAR(rfind__doc__, + "S.rfind(sub[, start[, end]]) -> int\n\ +\n\ +Return the highest index in S where substring sub is found,\n\ +such that sub is contained within S[start:end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Return -1 on failure."); + +static PyObject * +unicode_rfind(PyObject *self, PyObject *args) +{ + /* initialize variables to prevent gcc warning */ + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; + Py_ssize_t result; + + if (!parse_args_finds_unicode("rfind", args, &substring, &start, &end)) + return NULL; + + if (PyUnicode_READY(self) == -1) + return NULL; + + result = any_find_slice(self, substring, start, end, -1); + + if (result == -2) + return NULL; + + return PyLong_FromSsize_t(result); +} + +PyDoc_STRVAR(rindex__doc__, + "S.rindex(sub[, start[, end]]) -> int\n\ +\n\ +Return the highest index in S where substring sub is found,\n\ +such that sub is contained within S[start:end]. Optional\n\ +arguments start and end are interpreted as in slice notation.\n\ +\n\ +Raises ValueError when the substring is not found."); + +static PyObject * +unicode_rindex(PyObject *self, PyObject *args) +{ + /* initialize variables to prevent gcc warning */ + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; + Py_ssize_t result; + + if (!parse_args_finds_unicode("rindex", args, &substring, &start, &end)) + return NULL; + + if (PyUnicode_READY(self) == -1) + return NULL; + + result = any_find_slice(self, substring, start, end, -1); + + if (result == -2) + return NULL; + + if (result < 0) { + PyErr_SetString(PyExc_ValueError, "substring not found"); + return NULL; + } + + return PyLong_FromSsize_t(result); +} + +/*[clinic input] +str.rjust as unicode_rjust + + width: Py_ssize_t + fillchar: Py_UCS4 = ' ' + / + +Return a right-justified string of length width. + +Padding is done using the specified fill character (default is a space). +[clinic start generated code]*/ + +static PyObject * +unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) +/*[clinic end generated code: output=804a1a57fbe8d5cf input=d05f550b5beb1f72]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + + if (PyUnicode_GET_LENGTH(self) >= width) + return unicode_result_unchanged(self); + + return pad(self, width - PyUnicode_GET_LENGTH(self), 0, fillchar); +} + +PyObject * +PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) +{ + if (ensure_unicode(s) < 0 || (sep != NULL && ensure_unicode(sep) < 0)) + return NULL; + + return split(s, sep, maxsplit); +} + +/*[clinic input] +str.split as unicode_split + + sep: object = None + The delimiter according which to split the string. + None (the default value) means split according to any whitespace, + and discard empty strings from the result. + maxsplit: Py_ssize_t = -1 + Maximum number of splits to do. + -1 (the default value) means no limit. + +Return a list of the words in the string, using sep as the delimiter string. +[clinic start generated code]*/ + +static PyObject * +unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=3a65b1db356948dc input=606e750488a82359]*/ +{ + if (sep == Py_None) + return split(self, NULL, maxsplit); + if (PyUnicode_Check(sep)) + return split(self, sep, maxsplit); + + PyErr_Format(PyExc_TypeError, + "must be str or None, not %.100s", + Py_TYPE(sep)->tp_name); + return NULL; +} + +PyObject * +PyUnicode_Partition(PyObject *str_obj, PyObject *sep_obj) +{ + PyObject* out; + int kind1, kind2; + void *buf1, *buf2; + Py_ssize_t len1, len2; + + if (ensure_unicode(str_obj) < 0 || ensure_unicode(sep_obj) < 0) + return NULL; + + kind1 = PyUnicode_KIND(str_obj); + kind2 = PyUnicode_KIND(sep_obj); + len1 = PyUnicode_GET_LENGTH(str_obj); + len2 = PyUnicode_GET_LENGTH(sep_obj); + if (kind1 < kind2 || len1 < len2) { + _Py_INCREF_UNICODE_EMPTY(); + if (!unicode_empty) + out = NULL; + else { + out = PyTuple_Pack(3, str_obj, unicode_empty, unicode_empty); + Py_DECREF(unicode_empty); + } + return out; + } + buf1 = PyUnicode_DATA(str_obj); + buf2 = PyUnicode_DATA(sep_obj); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sep_obj, kind1); + if (!buf2) + return NULL; + } + + switch (kind1) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sep_obj)) + out = asciilib_partition(str_obj, buf1, len1, sep_obj, buf2, len2); + else + out = ucs1lib_partition(str_obj, buf1, len1, sep_obj, buf2, len2); + break; + case PyUnicode_2BYTE_KIND: + out = ucs2lib_partition(str_obj, buf1, len1, sep_obj, buf2, len2); + break; + case PyUnicode_4BYTE_KIND: + out = ucs4lib_partition(str_obj, buf1, len1, sep_obj, buf2, len2); + break; + default: + Py_UNREACHABLE(); + } + + if (kind2 != kind1) + PyMem_Free(buf2); + + return out; +} + + +PyObject * +PyUnicode_RPartition(PyObject *str_obj, PyObject *sep_obj) +{ + PyObject* out; + int kind1, kind2; + void *buf1, *buf2; + Py_ssize_t len1, len2; + + if (ensure_unicode(str_obj) < 0 || ensure_unicode(sep_obj) < 0) + return NULL; + + kind1 = PyUnicode_KIND(str_obj); + kind2 = PyUnicode_KIND(sep_obj); + len1 = PyUnicode_GET_LENGTH(str_obj); + len2 = PyUnicode_GET_LENGTH(sep_obj); + if (kind1 < kind2 || len1 < len2) { + _Py_INCREF_UNICODE_EMPTY(); + if (!unicode_empty) + out = NULL; + else { + out = PyTuple_Pack(3, unicode_empty, unicode_empty, str_obj); + Py_DECREF(unicode_empty); + } + return out; + } + buf1 = PyUnicode_DATA(str_obj); + buf2 = PyUnicode_DATA(sep_obj); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sep_obj, kind1); + if (!buf2) + return NULL; + } + + switch (kind1) { + case PyUnicode_1BYTE_KIND: + if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sep_obj)) + out = asciilib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2); + else + out = ucs1lib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2); + break; + case PyUnicode_2BYTE_KIND: + out = ucs2lib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2); + break; + case PyUnicode_4BYTE_KIND: + out = ucs4lib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2); + break; + default: + Py_UNREACHABLE(); + } + + if (kind2 != kind1) + PyMem_Free(buf2); + + return out; +} + +/*[clinic input] +str.partition as unicode_partition + + sep: object + / + +Partition the string into three parts using the given separator. + +This will search for the separator in the string. If the separator is found, +returns a 3-tuple containing the part before the separator, the separator +itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing the original string +and two empty strings. +[clinic start generated code]*/ + +static PyObject * +unicode_partition(PyObject *self, PyObject *sep) +/*[clinic end generated code: output=e4ced7bd253ca3c4 input=f29b8d06c63e50be]*/ +{ + return PyUnicode_Partition(self, sep); +} + +/*[clinic input] +str.rpartition as unicode_rpartition = str.partition + +Partition the string into three parts using the given separator. + +This will search for the separator in the string, starting at the end. If +the separator is found, returns a 3-tuple containing the part before the +separator, the separator itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing two empty strings +and the original string. +[clinic start generated code]*/ + +static PyObject * +unicode_rpartition(PyObject *self, PyObject *sep) +/*[clinic end generated code: output=1aa13cf1156572aa input=c4b7db3ef5cf336a]*/ +{ + return PyUnicode_RPartition(self, sep); +} + +PyObject * +PyUnicode_RSplit(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) +{ + if (ensure_unicode(s) < 0 || (sep != NULL && ensure_unicode(sep) < 0)) + return NULL; + + return rsplit(s, sep, maxsplit); +} + +/*[clinic input] +str.rsplit as unicode_rsplit = str.split + +Return a list of the words in the string, using sep as the delimiter string. + +Splits are done starting at the end of the string and working to the front. +[clinic start generated code]*/ + +static PyObject * +unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=c2b815c63bcabffc input=12ad4bf57dd35f15]*/ +{ + if (sep == Py_None) + return rsplit(self, NULL, maxsplit); + if (PyUnicode_Check(sep)) + return rsplit(self, sep, maxsplit); + + PyErr_Format(PyExc_TypeError, + "must be str or None, not %.100s", + Py_TYPE(sep)->tp_name); + return NULL; +} + +/*[clinic input] +str.splitlines as unicode_splitlines + + keepends: bool(accept={int}) = False + +Return a list of the lines in the string, breaking at line boundaries. + +Line breaks are not included in the resulting list unless keepends is given and +true. +[clinic start generated code]*/ + +static PyObject * +unicode_splitlines_impl(PyObject *self, int keepends) +/*[clinic end generated code: output=f664dcdad153ec40 input=b508e180459bdd8b]*/ +{ + return PyUnicode_Splitlines(self, keepends); +} + +static +PyObject *unicode_str(PyObject *self) +{ + return unicode_result_unchanged(self); +} + +/*[clinic input] +str.swapcase as unicode_swapcase + +Convert uppercase characters to lowercase and lowercase characters to uppercase. +[clinic start generated code]*/ + +static PyObject * +unicode_swapcase_impl(PyObject *self) +/*[clinic end generated code: output=5d28966bf6d7b2af input=3f3ef96d5798a7bb]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + return case_operation(self, do_swapcase); +} + +/*[clinic input] + +@staticmethod +str.maketrans as unicode_maketrans + + x: object + + y: unicode=NULL + + z: unicode=NULL + + / + +Return a translation table usable for str.translate(). + +If there is only one argument, it must be a dictionary mapping Unicode +ordinals (integers) or characters to Unicode ordinals, strings or None. +Character keys will be then converted to ordinals. +If there are two arguments, they must be strings of equal length, and +in the resulting dictionary, each character in x will be mapped to the +character at the same position in y. If there is a third argument, it +must be a string, whose characters will be mapped to None in the result. +[clinic start generated code]*/ + +static PyObject * +unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z) +/*[clinic end generated code: output=a925c89452bd5881 input=7bfbf529a293c6c5]*/ +{ + PyObject *new = NULL, *key, *value; + Py_ssize_t i = 0; + int res; + + new = PyDict_New(); + if (!new) + return NULL; + if (y != NULL) { + int x_kind, y_kind, z_kind; + void *x_data, *y_data, *z_data; + + /* x must be a string too, of equal length */ + if (!PyUnicode_Check(x)) { + PyErr_SetString(PyExc_TypeError, "first maketrans argument must " + "be a string if there is a second argument"); + goto err; + } + if (PyUnicode_GET_LENGTH(x) != PyUnicode_GET_LENGTH(y)) { + PyErr_SetString(PyExc_ValueError, "the first two maketrans " + "arguments must have equal length"); + goto err; + } + /* create entries for translating chars in x to those in y */ + x_kind = PyUnicode_KIND(x); + y_kind = PyUnicode_KIND(y); + x_data = PyUnicode_DATA(x); + y_data = PyUnicode_DATA(y); + for (i = 0; i < PyUnicode_GET_LENGTH(x); i++) { + key = PyLong_FromLong(PyUnicode_READ(x_kind, x_data, i)); + if (!key) + goto err; + value = PyLong_FromLong(PyUnicode_READ(y_kind, y_data, i)); + if (!value) { + Py_DECREF(key); + goto err; + } + res = PyDict_SetItem(new, key, value); + Py_DECREF(key); + Py_DECREF(value); + if (res < 0) + goto err; + } + /* create entries for deleting chars in z */ + if (z != NULL) { + z_kind = PyUnicode_KIND(z); + z_data = PyUnicode_DATA(z); + for (i = 0; i < PyUnicode_GET_LENGTH(z); i++) { + key = PyLong_FromLong(PyUnicode_READ(z_kind, z_data, i)); + if (!key) + goto err; + res = PyDict_SetItem(new, key, Py_None); + Py_DECREF(key); + if (res < 0) + goto err; + } + } + } else { + int kind; + void *data; + + /* x must be a dict */ + if (!PyDict_CheckExact(x)) { + PyErr_SetString(PyExc_TypeError, "if you give only one argument " + "to maketrans it must be a dict"); + goto err; + } + /* copy entries into the new dict, converting string keys to int keys */ + while (PyDict_Next(x, &i, &key, &value)) { + if (PyUnicode_Check(key)) { + /* convert string keys to integer keys */ + PyObject *newkey; + if (PyUnicode_GET_LENGTH(key) != 1) { + PyErr_SetString(PyExc_ValueError, "string keys in translate " + "table must be of length 1"); + goto err; + } + kind = PyUnicode_KIND(key); + data = PyUnicode_DATA(key); + newkey = PyLong_FromLong(PyUnicode_READ(kind, data, 0)); + if (!newkey) + goto err; + res = PyDict_SetItem(new, newkey, value); + Py_DECREF(newkey); + if (res < 0) + goto err; + } else if (PyLong_Check(key)) { + /* just keep integer keys */ + if (PyDict_SetItem(new, key, value) < 0) + goto err; + } else { + PyErr_SetString(PyExc_TypeError, "keys in translate table must " + "be strings or integers"); + goto err; + } + } + } + return new; + err: + Py_DECREF(new); + return NULL; +} + +/*[clinic input] +str.translate as unicode_translate + + table: object + Translation table, which must be a mapping of Unicode ordinals to + Unicode ordinals, strings, or None. + / + +Replace each character in the string using the given translation table. + +The table must implement lookup/indexing via __getitem__, for instance a +dictionary or list. If this operation raises LookupError, the character is +left untouched. Characters mapped to None are deleted. +[clinic start generated code]*/ + +static PyObject * +unicode_translate(PyObject *self, PyObject *table) +/*[clinic end generated code: output=3cb448ff2fd96bf3 input=6d38343db63d8eb0]*/ +{ + return _PyUnicode_TranslateCharmap(self, table, "ignore"); +} + +/*[clinic input] +str.upper as unicode_upper + +Return a copy of the string converted to uppercase. +[clinic start generated code]*/ + +static PyObject * +unicode_upper_impl(PyObject *self) +/*[clinic end generated code: output=1b7ddd16bbcdc092 input=db3d55682dfe2e6c]*/ +{ + if (PyUnicode_READY(self) == -1) + return NULL; + if (PyUnicode_IS_ASCII(self)) + return ascii_upper_or_lower(self, 0); + return case_operation(self, do_upper); +} + +/*[clinic input] +str.zfill as unicode_zfill + + width: Py_ssize_t + / + +Pad a numeric string with zeros on the left, to fill a field of the given width. + +The string is never truncated. +[clinic start generated code]*/ + +static PyObject * +unicode_zfill_impl(PyObject *self, Py_ssize_t width) +/*[clinic end generated code: output=e13fb6bdf8e3b9df input=c6b2f772c6f27799]*/ +{ + Py_ssize_t fill; + PyObject *u; + int kind; + void *data; + Py_UCS4 chr; + + if (PyUnicode_READY(self) == -1) + return NULL; + + if (PyUnicode_GET_LENGTH(self) >= width) + return unicode_result_unchanged(self); + + fill = width - PyUnicode_GET_LENGTH(self); + + u = pad(self, fill, 0, '0'); + + if (u == NULL) + return NULL; + + kind = PyUnicode_KIND(u); + data = PyUnicode_DATA(u); + chr = PyUnicode_READ(kind, data, fill); + + if (chr == '+' || chr == '-') { + /* move sign to beginning of string */ + PyUnicode_WRITE(kind, data, 0, chr); + PyUnicode_WRITE(kind, data, fill, '0'); + } + + assert(_PyUnicode_CheckConsistency(u, 1)); + return u; +} + +#if 0 +static PyObject * +unicode__decimal2ascii(PyObject *self) +{ + return PyUnicode_TransformDecimalAndSpaceToASCII(self); +} +#endif + +PyDoc_STRVAR(startswith__doc__, + "S.startswith(prefix[, start[, end]]) -> bool\n\ +\n\ +Return True if S starts with the specified prefix, False otherwise.\n\ +With optional start, test S beginning at that position.\n\ +With optional end, stop comparing S at that position.\n\ +prefix can also be a tuple of strings to try."); + +static PyObject * +unicode_startswith(PyObject *self, + PyObject *args) +{ + PyObject *subobj; + PyObject *substring; + Py_ssize_t start = 0; + Py_ssize_t end = PY_SSIZE_T_MAX; + int result; + + if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end)) + return NULL; + if (PyTuple_Check(subobj)) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { + substring = PyTuple_GET_ITEM(subobj, i); + if (!PyUnicode_Check(substring)) { + PyErr_Format(PyExc_TypeError, + "tuple for startswith must only contain str, " + "not %.100s", + Py_TYPE(substring)->tp_name); + return NULL; + } + result = tailmatch(self, substring, start, end, -1); + if (result == -1) + return NULL; + if (result) { + Py_RETURN_TRUE; + } + } + /* nothing matched */ + Py_RETURN_FALSE; + } + if (!PyUnicode_Check(subobj)) { + PyErr_Format(PyExc_TypeError, + "startswith first arg must be str or " + "a tuple of str, not %.100s", Py_TYPE(subobj)->tp_name); + return NULL; + } + result = tailmatch(self, subobj, start, end, -1); + if (result == -1) + return NULL; + return PyBool_FromLong(result); +} + + +PyDoc_STRVAR(endswith__doc__, + "S.endswith(suffix[, start[, end]]) -> bool\n\ +\n\ +Return True if S ends with the specified suffix, False otherwise.\n\ +With optional start, test S beginning at that position.\n\ +With optional end, stop comparing S at that position.\n\ +suffix can also be a tuple of strings to try."); + +static PyObject * +unicode_endswith(PyObject *self, + PyObject *args) +{ + PyObject *subobj; + PyObject *substring; + Py_ssize_t start = 0; + Py_ssize_t end = PY_SSIZE_T_MAX; + int result; + + if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end)) + return NULL; + if (PyTuple_Check(subobj)) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { + substring = PyTuple_GET_ITEM(subobj, i); + if (!PyUnicode_Check(substring)) { + PyErr_Format(PyExc_TypeError, + "tuple for endswith must only contain str, " + "not %.100s", + Py_TYPE(substring)->tp_name); + return NULL; + } + result = tailmatch(self, substring, start, end, +1); + if (result == -1) + return NULL; + if (result) { + Py_RETURN_TRUE; + } + } + Py_RETURN_FALSE; + } + if (!PyUnicode_Check(subobj)) { + PyErr_Format(PyExc_TypeError, + "endswith first arg must be str or " + "a tuple of str, not %.100s", Py_TYPE(subobj)->tp_name); + return NULL; + } + result = tailmatch(self, subobj, start, end, +1); + if (result == -1) + return NULL; + return PyBool_FromLong(result); +} + +static inline void +_PyUnicodeWriter_Update(_PyUnicodeWriter *writer) +{ + writer->maxchar = PyUnicode_MAX_CHAR_VALUE(writer->buffer); + writer->data = PyUnicode_DATA(writer->buffer); + + if (!writer->readonly) { + writer->kind = PyUnicode_KIND(writer->buffer); + writer->size = PyUnicode_GET_LENGTH(writer->buffer); + } + else { + /* use a value smaller than PyUnicode_1BYTE_KIND() so + _PyUnicodeWriter_PrepareKind() will copy the buffer. */ + writer->kind = PyUnicode_WCHAR_KIND; + assert(writer->kind <= PyUnicode_1BYTE_KIND); + + /* Copy-on-write mode: set buffer size to 0 so + * _PyUnicodeWriter_Prepare() will copy (and enlarge) the buffer on + * next write. */ + writer->size = 0; + } +} + +void +_PyUnicodeWriter_Init(_PyUnicodeWriter *writer) +{ + memset(writer, 0, sizeof(*writer)); + + /* ASCII is the bare minimum */ + writer->min_char = 127; + + /* use a value smaller than PyUnicode_1BYTE_KIND() so + _PyUnicodeWriter_PrepareKind() will copy the buffer. */ + writer->kind = PyUnicode_WCHAR_KIND; + assert(writer->kind <= PyUnicode_1BYTE_KIND); +} + +int +_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, + Py_ssize_t length, Py_UCS4 maxchar) +{ + Py_ssize_t newlen; + PyObject *newbuffer; + + assert(maxchar <= MAX_UNICODE); + + /* ensure that the _PyUnicodeWriter_Prepare macro was used */ + assert((maxchar > writer->maxchar && length >= 0) + || length > 0); + + if (length > PY_SSIZE_T_MAX - writer->pos) { + PyErr_NoMemory(); + return -1; + } + newlen = writer->pos + length; + + maxchar = Py_MAX(maxchar, writer->min_char); + + if (writer->buffer == NULL) { + assert(!writer->readonly); + if (writer->overallocate + && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) { + /* overallocate to limit the number of realloc() */ + newlen += newlen / OVERALLOCATE_FACTOR; + } + if (newlen < writer->min_length) + newlen = writer->min_length; + + writer->buffer = PyUnicode_New(newlen, maxchar); + if (writer->buffer == NULL) + return -1; + } + else if (newlen > writer->size) { + if (writer->overallocate + && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) { + /* overallocate to limit the number of realloc() */ + newlen += newlen / OVERALLOCATE_FACTOR; + } + if (newlen < writer->min_length) + newlen = writer->min_length; + + if (maxchar > writer->maxchar || writer->readonly) { + /* resize + widen */ + maxchar = Py_MAX(maxchar, writer->maxchar); + newbuffer = PyUnicode_New(newlen, maxchar); + if (newbuffer == NULL) + return -1; + _PyUnicode_FastCopyCharacters(newbuffer, 0, + writer->buffer, 0, writer->pos); + Py_DECREF(writer->buffer); + writer->readonly = 0; + } + else { + newbuffer = resize_compact(writer->buffer, newlen); + if (newbuffer == NULL) + return -1; + } + writer->buffer = newbuffer; + } + else if (maxchar > writer->maxchar) { + assert(!writer->readonly); + newbuffer = PyUnicode_New(writer->size, maxchar); + if (newbuffer == NULL) + return -1; + _PyUnicode_FastCopyCharacters(newbuffer, 0, + writer->buffer, 0, writer->pos); + Py_SETREF(writer->buffer, newbuffer); + } + _PyUnicodeWriter_Update(writer); + return 0; + +#undef OVERALLOCATE_FACTOR +} + +int +_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, + enum PyUnicode_Kind kind) +{ + Py_UCS4 maxchar; + + /* ensure that the _PyUnicodeWriter_PrepareKind macro was used */ + assert(writer->kind < kind); + + switch (kind) + { + case PyUnicode_1BYTE_KIND: maxchar = 0xff; break; + case PyUnicode_2BYTE_KIND: maxchar = 0xffff; break; + case PyUnicode_4BYTE_KIND: maxchar = MAX_UNICODE; break; + default: + Py_UNREACHABLE(); + } + + return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar); +} + +static inline int +_PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch) +{ + assert(ch <= MAX_UNICODE); + if (_PyUnicodeWriter_Prepare(writer, 1, ch) < 0) + return -1; + PyUnicode_WRITE(writer->kind, writer->data, writer->pos, ch); + writer->pos++; + return 0; +} + +int +_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, Py_UCS4 ch) +{ + return _PyUnicodeWriter_WriteCharInline(writer, ch); +} + +int +_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) +{ + Py_UCS4 maxchar; + Py_ssize_t len; + + if (PyUnicode_READY(str) == -1) + return -1; + len = PyUnicode_GET_LENGTH(str); + if (len == 0) + return 0; + maxchar = PyUnicode_MAX_CHAR_VALUE(str); + if (maxchar > writer->maxchar || len > writer->size - writer->pos) { + if (writer->buffer == NULL && !writer->overallocate) { + assert(_PyUnicode_CheckConsistency(str, 1)); + writer->readonly = 1; + Py_INCREF(str); + writer->buffer = str; + _PyUnicodeWriter_Update(writer); + writer->pos += len; + return 0; + } + if (_PyUnicodeWriter_PrepareInternal(writer, len, maxchar) == -1) + return -1; + } + _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, + str, 0, len); + writer->pos += len; + return 0; +} + +int +_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str, + Py_ssize_t start, Py_ssize_t end) +{ + Py_UCS4 maxchar; + Py_ssize_t len; + + if (PyUnicode_READY(str) == -1) + return -1; + + assert(0 <= start); + assert(end <= PyUnicode_GET_LENGTH(str)); + assert(start <= end); + + if (end == 0) + return 0; + + if (start == 0 && end == PyUnicode_GET_LENGTH(str)) + return _PyUnicodeWriter_WriteStr(writer, str); + + if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) + maxchar = _PyUnicode_FindMaxChar(str, start, end); + else + maxchar = writer->maxchar; + len = end - start; + + if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) + return -1; + + _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, + str, start, len); + writer->pos += len; + return 0; +} + +int +_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, + const char *ascii, Py_ssize_t len) +{ + if (len == -1) + len = strlen(ascii); + + assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) < 128); + + if (writer->buffer == NULL && !writer->overallocate) { + PyObject *str; + + str = _PyUnicode_FromASCII(ascii, len); + if (str == NULL) + return -1; + + writer->readonly = 1; + writer->buffer = str; + _PyUnicodeWriter_Update(writer); + writer->pos += len; + return 0; + } + + if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1) + return -1; + + switch (writer->kind) + { + case PyUnicode_1BYTE_KIND: + { + const Py_UCS1 *str = (const Py_UCS1 *)ascii; + Py_UCS1 *data = writer->data; + + memcpy(data + writer->pos, str, len); + break; + } + case PyUnicode_2BYTE_KIND: + { + _PyUnicode_CONVERT_BYTES( + Py_UCS1, Py_UCS2, + ascii, ascii + len, + (Py_UCS2 *)writer->data + writer->pos); + break; + } + case PyUnicode_4BYTE_KIND: + { + _PyUnicode_CONVERT_BYTES( + Py_UCS1, Py_UCS4, + ascii, ascii + len, + (Py_UCS4 *)writer->data + writer->pos); + break; + } + default: + Py_UNREACHABLE(); + } + + writer->pos += len; + return 0; +} + +int +_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, + const char *str, Py_ssize_t len) +{ + Py_UCS4 maxchar; + + maxchar = ucs1lib_find_max_char((const Py_UCS1*)str, (const Py_UCS1*)str + len); + if (_PyUnicodeWriter_Prepare(writer, len, maxchar) == -1) + return -1; + unicode_write_cstr(writer->buffer, writer->pos, str, len); + writer->pos += len; + return 0; +} + +PyObject * +_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer) +{ + PyObject *str; + + if (writer->pos == 0) { + Py_CLEAR(writer->buffer); + _Py_RETURN_UNICODE_EMPTY(); + } + + str = writer->buffer; + writer->buffer = NULL; + + if (writer->readonly) { + assert(PyUnicode_GET_LENGTH(str) == writer->pos); + return str; + } + + if (PyUnicode_GET_LENGTH(str) != writer->pos) { + PyObject *str2; + str2 = resize_compact(str, writer->pos); + if (str2 == NULL) { + Py_DECREF(str); + return NULL; + } + str = str2; + } + + assert(_PyUnicode_CheckConsistency(str, 1)); + return unicode_result_ready(str); +} + +void +_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer) +{ + Py_CLEAR(writer->buffer); +} + +#include "stringlib/unicode_format.h" + +PyDoc_STRVAR(format__doc__, + "S.format(*args, **kwargs) -> str\n\ +\n\ +Return a formatted version of S, using substitutions from args and kwargs.\n\ +The substitutions are identified by braces ('{' and '}')."); + +PyDoc_STRVAR(format_map__doc__, + "S.format_map(mapping) -> str\n\ +\n\ +Return a formatted version of S, using substitutions from mapping.\n\ +The substitutions are identified by braces ('{' and '}')."); + +/*[clinic input] +str.__format__ as unicode___format__ + + format_spec: unicode + / + +Return a formatted version of the string as described by format_spec. +[clinic start generated code]*/ + +static PyObject * +unicode___format___impl(PyObject *self, PyObject *format_spec) +/*[clinic end generated code: output=45fceaca6d2ba4c8 input=5e135645d167a214]*/ +{ + _PyUnicodeWriter writer; + int ret; + + if (PyUnicode_READY(self) == -1) + return NULL; + _PyUnicodeWriter_Init(&writer); + ret = _PyUnicode_FormatAdvancedWriter(&writer, + self, format_spec, 0, + PyUnicode_GET_LENGTH(format_spec)); + if (ret == -1) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + return _PyUnicodeWriter_Finish(&writer); +} + +/*[clinic input] +str.__sizeof__ as unicode_sizeof + +Return the size of the string in memory, in bytes. +[clinic start generated code]*/ + +static PyObject * +unicode_sizeof_impl(PyObject *self) +/*[clinic end generated code: output=6dbc2f5a408b6d4f input=6dd011c108e33fb0]*/ +{ + Py_ssize_t size; + + /* If it's a compact object, account for base structure + + character data. */ + if (PyUnicode_IS_COMPACT_ASCII(self)) + size = sizeof(PyASCIIObject) + PyUnicode_GET_LENGTH(self) + 1; + else if (PyUnicode_IS_COMPACT(self)) + size = sizeof(PyCompactUnicodeObject) + + (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self); + else { + /* If it is a two-block object, account for base object, and + for character block if present. */ + size = sizeof(PyUnicodeObject); + if (_PyUnicode_DATA_ANY(self)) + size += (PyUnicode_GET_LENGTH(self) + 1) * + PyUnicode_KIND(self); + } + /* If the wstr pointer is present, account for it unless it is shared + with the data pointer. Check if the data is not shared. */ + if (_PyUnicode_HAS_WSTR_MEMORY(self)) + size += (PyUnicode_WSTR_LENGTH(self) + 1) * sizeof(wchar_t); + if (_PyUnicode_HAS_UTF8_MEMORY(self)) + size += PyUnicode_UTF8_LENGTH(self) + 1; + + return PyLong_FromSsize_t(size); +} + +static PyObject * +unicode_getnewargs(PyObject *v, PyObject *Py_UNUSED(ignored)) +{ + PyObject *copy = _PyUnicode_Copy(v); + if (!copy) + return NULL; + return Py_BuildValue("(N)", copy); +} + +static PyMethodDef unicode_methods[] = { + UNICODE_ENCODE_METHODDEF + UNICODE_REPLACE_METHODDEF + UNICODE_SPLIT_METHODDEF + UNICODE_RSPLIT_METHODDEF + UNICODE_JOIN_METHODDEF + UNICODE_CAPITALIZE_METHODDEF + UNICODE_CASEFOLD_METHODDEF + UNICODE_TITLE_METHODDEF + UNICODE_CENTER_METHODDEF + {"count", (PyCFunction) unicode_count, METH_VARARGS, count__doc__}, + UNICODE_EXPANDTABS_METHODDEF + {"find", (PyCFunction) unicode_find, METH_VARARGS, find__doc__}, + UNICODE_PARTITION_METHODDEF + {"index", (PyCFunction) unicode_index, METH_VARARGS, index__doc__}, + UNICODE_LJUST_METHODDEF + UNICODE_LOWER_METHODDEF + UNICODE_LSTRIP_METHODDEF + {"rfind", (PyCFunction) unicode_rfind, METH_VARARGS, rfind__doc__}, + {"rindex", (PyCFunction) unicode_rindex, METH_VARARGS, rindex__doc__}, + UNICODE_RJUST_METHODDEF + UNICODE_RSTRIP_METHODDEF + UNICODE_RPARTITION_METHODDEF + UNICODE_SPLITLINES_METHODDEF + UNICODE_STRIP_METHODDEF + UNICODE_SWAPCASE_METHODDEF + UNICODE_TRANSLATE_METHODDEF + UNICODE_UPPER_METHODDEF + {"startswith", (PyCFunction) unicode_startswith, METH_VARARGS, startswith__doc__}, + {"endswith", (PyCFunction) unicode_endswith, METH_VARARGS, endswith__doc__}, + UNICODE_ISASCII_METHODDEF + UNICODE_ISLOWER_METHODDEF + UNICODE_ISUPPER_METHODDEF + UNICODE_ISTITLE_METHODDEF + UNICODE_ISSPACE_METHODDEF + UNICODE_ISDECIMAL_METHODDEF + UNICODE_ISDIGIT_METHODDEF + UNICODE_ISNUMERIC_METHODDEF + UNICODE_ISALPHA_METHODDEF + UNICODE_ISALNUM_METHODDEF + UNICODE_ISIDENTIFIER_METHODDEF + UNICODE_ISPRINTABLE_METHODDEF + UNICODE_ZFILL_METHODDEF + {"format", (PyCFunction)(void(*)(void)) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__}, + {"format_map", (PyCFunction) do_string_format_map, METH_O, format_map__doc__}, + UNICODE___FORMAT___METHODDEF + UNICODE_MAKETRANS_METHODDEF + UNICODE_SIZEOF_METHODDEF +#if 0 + /* These methods are just used for debugging the implementation. */ + {"_decimal2ascii", (PyCFunction) unicode__decimal2ascii, METH_NOARGS}, +#endif + + {"__getnewargs__", unicode_getnewargs, METH_NOARGS}, + {NULL, NULL} +}; + +static PyObject * +unicode_mod(PyObject *v, PyObject *w) +{ + if (!PyUnicode_Check(v)) + Py_RETURN_NOTIMPLEMENTED; + return PyUnicode_Format(v, w); +} + +static PyNumberMethods unicode_as_number = { + 0, /*nb_add*/ + 0, /*nb_subtract*/ + 0, /*nb_multiply*/ + unicode_mod, /*nb_remainder*/ +}; + +static PySequenceMethods unicode_as_sequence = { + (lenfunc) unicode_length, /* sq_length */ + PyUnicode_Concat, /* sq_concat */ + (ssizeargfunc) unicode_repeat, /* sq_repeat */ + (ssizeargfunc) unicode_getitem, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + PyUnicode_Contains, /* sq_contains */ +}; + +static PyObject* +unicode_subscript(PyObject* self, PyObject* item) +{ + if (PyUnicode_READY(self) == -1) + return NULL; + + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += PyUnicode_GET_LENGTH(self); + return unicode_getitem(self, i); + } else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength, i; + size_t cur; + PyObject *result; + void *src_data, *dest_data; + int src_kind, dest_kind; + Py_UCS4 ch, max_char, kind_limit; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelength = PySlice_AdjustIndices(PyUnicode_GET_LENGTH(self), + &start, &stop, step); + + if (slicelength <= 0) { + _Py_RETURN_UNICODE_EMPTY(); + } else if (start == 0 && step == 1 && + slicelength == PyUnicode_GET_LENGTH(self)) { + return unicode_result_unchanged(self); + } else if (step == 1) { + return PyUnicode_Substring(self, + start, start + slicelength); + } + /* General case */ + src_kind = PyUnicode_KIND(self); + src_data = PyUnicode_DATA(self); + if (!PyUnicode_IS_ASCII(self)) { + kind_limit = kind_maxchar_limit(src_kind); + max_char = 0; + for (cur = start, i = 0; i < slicelength; cur += step, i++) { + ch = PyUnicode_READ(src_kind, src_data, cur); + if (ch > max_char) { + max_char = ch; + if (max_char >= kind_limit) + break; + } + } + } + else + max_char = 127; + result = PyUnicode_New(slicelength, max_char); + if (result == NULL) + return NULL; + dest_kind = PyUnicode_KIND(result); + dest_data = PyUnicode_DATA(result); + + for (cur = start, i = 0; i < slicelength; cur += step, i++) { + Py_UCS4 ch = PyUnicode_READ(src_kind, src_data, cur); + PyUnicode_WRITE(dest_kind, dest_data, i, ch); + } + assert(_PyUnicode_CheckConsistency(result, 1)); + return result; + } else { + PyErr_SetString(PyExc_TypeError, "string indices must be integers"); + return NULL; + } +} + +static PyMappingMethods unicode_as_mapping = { + (lenfunc)unicode_length, /* mp_length */ + (binaryfunc)unicode_subscript, /* mp_subscript */ + (objobjargproc)0, /* mp_ass_subscript */ +}; + + +/* Helpers for PyUnicode_Format() */ + +struct unicode_formatter_t { + PyObject *args; + int args_owned; + Py_ssize_t arglen, argidx; + PyObject *dict; + + enum PyUnicode_Kind fmtkind; + Py_ssize_t fmtcnt, fmtpos; + void *fmtdata; + PyObject *fmtstr; + + _PyUnicodeWriter writer; +}; + +struct unicode_format_arg_t { + Py_UCS4 ch; + int flags; + Py_ssize_t width; + int prec; + int sign; +}; + +static PyObject * +unicode_format_getnextarg(struct unicode_formatter_t *ctx) +{ + Py_ssize_t argidx = ctx->argidx; + + if (argidx < ctx->arglen) { + ctx->argidx++; + if (ctx->arglen < 0) + return ctx->args; + else + return PyTuple_GetItem(ctx->args, argidx); + } + PyErr_SetString(PyExc_TypeError, + "not enough arguments for format string"); + return NULL; +} + +/* Returns a new reference to a PyUnicode object, or NULL on failure. */ + +/* Format a float into the writer if the writer is not NULL, or into *p_output + otherwise. + + Return 0 on success, raise an exception and return -1 on error. */ +static int +formatfloat(PyObject *v, struct unicode_format_arg_t *arg, + PyObject **p_output, + _PyUnicodeWriter *writer) +{ + char *p; + double x; + Py_ssize_t len; + int prec; + int dtoa_flags; + + x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) + return -1; + + prec = arg->prec; + if (prec < 0) + prec = 6; + + if (arg->flags & F_ALT) + dtoa_flags = Py_DTSF_ALT; + else + dtoa_flags = 0; + p = PyOS_double_to_string(x, arg->ch, prec, dtoa_flags, NULL); + if (p == NULL) + return -1; + len = strlen(p); + if (writer) { + if (_PyUnicodeWriter_WriteASCIIString(writer, p, len) < 0) { + PyMem_Free(p); + return -1; + } + } + else + *p_output = _PyUnicode_FromASCII(p, len); + PyMem_Free(p); + return 0; +} + +/* formatlong() emulates the format codes d, u, o, x and X, and + * the F_ALT flag, for Python's long (unbounded) ints. It's not used for + * Python's regular ints. + * Return value: a new PyUnicodeObject*, or NULL if error. + * The output string is of the form + * "-"? ("0x" | "0X")? digit+ + * "0x"/"0X" are present only for x and X conversions, with F_ALT + * set in flags. The case of hex digits will be correct, + * There will be at least prec digits, zero-filled on the left if + * necessary to get that many. + * val object to be converted + * flags bitmask of format flags; only F_ALT is looked at + * prec minimum number of digits; 0-fill on left if needed + * type a character in [duoxX]; u acts the same as d + * + * CAUTION: o, x and X conversions on regular ints can never + * produce a '-' sign, but can for Python's unbounded ints. + */ +PyObject * +_PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) +{ + PyObject *result = NULL; + char *buf; + Py_ssize_t i; + int sign; /* 1 if '-', else 0 */ + int len; /* number of characters */ + Py_ssize_t llen; + int numdigits; /* len == numnondigits + numdigits */ + int numnondigits = 0; + + /* Avoid exceeding SSIZE_T_MAX */ + if (prec > INT_MAX-3) { + PyErr_SetString(PyExc_OverflowError, + "precision too large"); + return NULL; + } + + assert(PyLong_Check(val)); + + switch (type) { + default: + Py_UNREACHABLE(); + case 'd': + case 'i': + case 'u': + /* int and int subclasses should print numerically when a numeric */ + /* format code is used (see issue18780) */ + result = PyNumber_ToBase(val, 10); + break; + case 'o': + numnondigits = 2; + result = PyNumber_ToBase(val, 8); + break; + case 'x': + case 'X': + numnondigits = 2; + result = PyNumber_ToBase(val, 16); + break; + } + if (!result) + return NULL; + + assert(unicode_modifiable(result)); + assert(PyUnicode_IS_READY(result)); + assert(PyUnicode_IS_ASCII(result)); + + /* To modify the string in-place, there can only be one reference. */ + if (Py_REFCNT(result) != 1) { + Py_DECREF(result); + PyErr_BadInternalCall(); + return NULL; + } + buf = PyUnicode_DATA(result); + llen = PyUnicode_GET_LENGTH(result); + if (llen > INT_MAX) { + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, + "string too large in _PyUnicode_FormatLong"); + return NULL; + } + len = (int)llen; + sign = buf[0] == '-'; + numnondigits += sign; + numdigits = len - numnondigits; + assert(numdigits > 0); + + /* Get rid of base marker unless F_ALT */ + if (((alt) == 0 && + (type == 'o' || type == 'x' || type == 'X'))) { + assert(buf[sign] == '0'); + assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' || + buf[sign+1] == 'o'); + numnondigits -= 2; + buf += 2; + len -= 2; + if (sign) + buf[0] = '-'; + assert(len == numnondigits + numdigits); + assert(numdigits > 0); + } + + /* Fill with leading zeroes to meet minimum width. */ + if (prec > numdigits) { + PyObject *r1 = PyBytes_FromStringAndSize(NULL, + numnondigits + prec); + char *b1; + if (!r1) { + Py_DECREF(result); + return NULL; + } + b1 = PyBytes_AS_STRING(r1); + for (i = 0; i < numnondigits; ++i) + *b1++ = *buf++; + for (i = 0; i < prec - numdigits; i++) + *b1++ = '0'; + for (i = 0; i < numdigits; i++) + *b1++ = *buf++; + *b1 = '\0'; + Py_DECREF(result); + result = r1; + buf = PyBytes_AS_STRING(result); + len = numnondigits + prec; + } + + /* Fix up case for hex conversions. */ + if (type == 'X') { + /* Need to convert all lower case letters to upper case. + and need to convert 0x to 0X (and -0x to -0X). */ + for (i = 0; i < len; i++) + if (buf[i] >= 'a' && buf[i] <= 'x') + buf[i] -= 'a'-'A'; + } + if (!PyUnicode_Check(result) + || buf != PyUnicode_DATA(result)) { + PyObject *unicode; + unicode = _PyUnicode_FromASCII(buf, len); + Py_DECREF(result); + result = unicode; + } + else if (len != PyUnicode_GET_LENGTH(result)) { + if (PyUnicode_Resize(&result, len) < 0) + Py_CLEAR(result); + } + return result; +} + +/* Format an integer or a float as an integer. + * Return 1 if the number has been formatted into the writer, + * 0 if the number has been formatted into *p_output + * -1 and raise an exception on error */ +static int +mainformatlong(PyObject *v, + struct unicode_format_arg_t *arg, + PyObject **p_output, + _PyUnicodeWriter *writer) +{ + PyObject *iobj, *res; + char type = (char)arg->ch; + + if (!PyNumber_Check(v)) + goto wrongtype; + + /* make sure number is a type of integer for o, x, and X */ + if (!PyLong_Check(v)) { + if (type == 'o' || type == 'x' || type == 'X') { + iobj = PyNumber_Index(v); + if (iobj == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + goto wrongtype; + return -1; + } + } + else { + iobj = PyNumber_Long(v); + if (iobj == NULL ) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + goto wrongtype; + return -1; + } + } + assert(PyLong_Check(iobj)); + } + else { + iobj = v; + Py_INCREF(iobj); + } + + if (PyLong_CheckExact(v) + && arg->width == -1 && arg->prec == -1 + && !(arg->flags & (F_SIGN | F_BLANK)) + && type != 'X') + { + /* Fast path */ + int alternate = arg->flags & F_ALT; + int base; + + switch(type) + { + default: + Py_UNREACHABLE(); + case 'd': + case 'i': + case 'u': + base = 10; + break; + case 'o': + base = 8; + break; + case 'x': + case 'X': + base = 16; + break; + } + + if (_PyLong_FormatWriter(writer, v, base, alternate) == -1) { + Py_DECREF(iobj); + return -1; + } + Py_DECREF(iobj); + return 1; + } + + res = _PyUnicode_FormatLong(iobj, arg->flags & F_ALT, arg->prec, type); + Py_DECREF(iobj); + if (res == NULL) + return -1; + *p_output = res; + return 0; + +wrongtype: + switch(type) + { + case 'o': + case 'x': + case 'X': + PyErr_Format(PyExc_TypeError, + "%%%c format: an integer is required, " + "not %.200s", + type, Py_TYPE(v)->tp_name); + break; + default: + PyErr_Format(PyExc_TypeError, + "%%%c format: a number is required, " + "not %.200s", + type, Py_TYPE(v)->tp_name); + break; + } + return -1; +} + +static Py_UCS4 +formatchar(PyObject *v) +{ + /* presume that the buffer is at least 3 characters long */ + if (PyUnicode_Check(v)) { + if (PyUnicode_GET_LENGTH(v) == 1) { + return PyUnicode_READ_CHAR(v, 0); + } + goto onError; + } + else { + PyObject *iobj; + long x; + /* make sure number is a type of integer */ + if (!PyLong_Check(v)) { + iobj = PyNumber_Index(v); + if (iobj == NULL) { + goto onError; + } + x = PyLong_AsLong(iobj); + Py_DECREF(iobj); + } + else { + x = PyLong_AsLong(v); + } + if (x == -1 && PyErr_Occurred()) + goto onError; + + if (x < 0 || x > MAX_UNICODE) { + PyErr_SetString(PyExc_OverflowError, + "%c arg not in range(0x110000)"); + return (Py_UCS4) -1; + } + + return (Py_UCS4) x; + } + + onError: + PyErr_SetString(PyExc_TypeError, + "%c requires int or char"); + return (Py_UCS4) -1; +} + +/* Parse options of an argument: flags, width, precision. + Handle also "%(name)" syntax. + + Return 0 if the argument has been formatted into arg->str. + Return 1 if the argument has been written into ctx->writer, + Raise an exception and return -1 on error. */ +static int +unicode_format_arg_parse(struct unicode_formatter_t *ctx, + struct unicode_format_arg_t *arg) +{ +#define FORMAT_READ(ctx) \ + PyUnicode_READ((ctx)->fmtkind, (ctx)->fmtdata, (ctx)->fmtpos) + + PyObject *v; + + if (arg->ch == '(') { + /* Get argument value from a dictionary. Example: "%(name)s". */ + Py_ssize_t keystart; + Py_ssize_t keylen; + PyObject *key; + int pcount = 1; + + if (ctx->dict == NULL) { + PyErr_SetString(PyExc_TypeError, + "format requires a mapping"); + return -1; + } + ++ctx->fmtpos; + --ctx->fmtcnt; + keystart = ctx->fmtpos; + /* Skip over balanced parentheses */ + while (pcount > 0 && --ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + if (arg->ch == ')') + --pcount; + else if (arg->ch == '(') + ++pcount; + ctx->fmtpos++; + } + keylen = ctx->fmtpos - keystart - 1; + if (ctx->fmtcnt < 0 || pcount > 0) { + PyErr_SetString(PyExc_ValueError, + "incomplete format key"); + return -1; + } + key = PyUnicode_Substring(ctx->fmtstr, + keystart, keystart + keylen); + if (key == NULL) + return -1; + if (ctx->args_owned) { + ctx->args_owned = 0; + Py_DECREF(ctx->args); + } + ctx->args = PyObject_GetItem(ctx->dict, key); + Py_DECREF(key); + if (ctx->args == NULL) + return -1; + ctx->args_owned = 1; + ctx->arglen = -1; + ctx->argidx = -2; + } + + /* Parse flags. Example: "%+i" => flags=F_SIGN. */ + while (--ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + ctx->fmtpos++; + switch (arg->ch) { + case '-': arg->flags |= F_LJUST; continue; + case '+': arg->flags |= F_SIGN; continue; + case ' ': arg->flags |= F_BLANK; continue; + case '#': arg->flags |= F_ALT; continue; + case '0': arg->flags |= F_ZERO; continue; + } + break; + } + + /* Parse width. Example: "%10s" => width=10 */ + if (arg->ch == '*') { + v = unicode_format_getnextarg(ctx); + if (v == NULL) + return -1; + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "* wants int"); + return -1; + } + arg->width = PyLong_AsSsize_t(v); + if (arg->width == -1 && PyErr_Occurred()) + return -1; + if (arg->width < 0) { + arg->flags |= F_LJUST; + arg->width = -arg->width; + } + if (--ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + ctx->fmtpos++; + } + } + else if (arg->ch >= '0' && arg->ch <= '9') { + arg->width = arg->ch - '0'; + while (--ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + ctx->fmtpos++; + if (arg->ch < '0' || arg->ch > '9') + break; + /* Since arg->ch is unsigned, the RHS would end up as unsigned, + mixing signed and unsigned comparison. Since arg->ch is between + '0' and '9', casting to int is safe. */ + if (arg->width > (PY_SSIZE_T_MAX - ((int)arg->ch - '0')) / 10) { + PyErr_SetString(PyExc_ValueError, + "width too big"); + return -1; + } + arg->width = arg->width*10 + (arg->ch - '0'); + } + } + + /* Parse precision. Example: "%.3f" => prec=3 */ + if (arg->ch == '.') { + arg->prec = 0; + if (--ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + ctx->fmtpos++; + } + if (arg->ch == '*') { + v = unicode_format_getnextarg(ctx); + if (v == NULL) + return -1; + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "* wants int"); + return -1; + } + arg->prec = _PyLong_AsInt(v); + if (arg->prec == -1 && PyErr_Occurred()) + return -1; + if (arg->prec < 0) + arg->prec = 0; + if (--ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + ctx->fmtpos++; + } + } + else if (arg->ch >= '0' && arg->ch <= '9') { + arg->prec = arg->ch - '0'; + while (--ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + ctx->fmtpos++; + if (arg->ch < '0' || arg->ch > '9') + break; + if (arg->prec > (INT_MAX - ((int)arg->ch - '0')) / 10) { + PyErr_SetString(PyExc_ValueError, + "precision too big"); + return -1; + } + arg->prec = arg->prec*10 + (arg->ch - '0'); + } + } + } + + /* Ignore "h", "l" and "L" format prefix (ex: "%hi" or "%ls") */ + if (ctx->fmtcnt >= 0) { + if (arg->ch == 'h' || arg->ch == 'l' || arg->ch == 'L') { + if (--ctx->fmtcnt >= 0) { + arg->ch = FORMAT_READ(ctx); + ctx->fmtpos++; + } + } + } + if (ctx->fmtcnt < 0) { + PyErr_SetString(PyExc_ValueError, + "incomplete format"); + return -1; + } + return 0; + +#undef FORMAT_READ +} + +/* Format one argument. Supported conversion specifiers: + + - "s", "r", "a": any type + - "i", "d", "u": int or float + - "o", "x", "X": int + - "e", "E", "f", "F", "g", "G": float + - "c": int or str (1 character) + + When possible, the output is written directly into the Unicode writer + (ctx->writer). A string is created when padding is required. + + Return 0 if the argument has been formatted into *p_str, + 1 if the argument has been written into ctx->writer, + -1 on error. */ +static int +unicode_format_arg_format(struct unicode_formatter_t *ctx, + struct unicode_format_arg_t *arg, + PyObject **p_str) +{ + PyObject *v; + _PyUnicodeWriter *writer = &ctx->writer; + + if (ctx->fmtcnt == 0) + ctx->writer.overallocate = 0; + + v = unicode_format_getnextarg(ctx); + if (v == NULL) + return -1; + + + switch (arg->ch) { + case 's': + case 'r': + case 'a': + if (PyLong_CheckExact(v) && arg->width == -1 && arg->prec == -1) { + /* Fast path */ + if (_PyLong_FormatWriter(writer, v, 10, arg->flags & F_ALT) == -1) + return -1; + return 1; + } + + if (PyUnicode_CheckExact(v) && arg->ch == 's') { + *p_str = v; + Py_INCREF(*p_str); + } + else { + if (arg->ch == 's') + *p_str = PyObject_Str(v); + else if (arg->ch == 'r') + *p_str = PyObject_Repr(v); + else + *p_str = PyObject_ASCII(v); + } + break; + + case 'i': + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': + { + int ret = mainformatlong(v, arg, p_str, writer); + if (ret != 0) + return ret; + arg->sign = 1; + break; + } + + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + if (arg->width == -1 && arg->prec == -1 + && !(arg->flags & (F_SIGN | F_BLANK))) + { + /* Fast path */ + if (formatfloat(v, arg, NULL, writer) == -1) + return -1; + return 1; + } + + arg->sign = 1; + if (formatfloat(v, arg, p_str, NULL) == -1) + return -1; + break; + + case 'c': + { + Py_UCS4 ch = formatchar(v); + if (ch == (Py_UCS4) -1) + return -1; + if (arg->width == -1 && arg->prec == -1) { + /* Fast path */ + if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0) + return -1; + return 1; + } + *p_str = PyUnicode_FromOrdinal(ch); + break; + } + + default: + PyErr_Format(PyExc_ValueError, + "unsupported format character '%c' (0x%x) " + "at index %zd", + (31<=arg->ch && arg->ch<=126) ? (char)arg->ch : '?', + (int)arg->ch, + ctx->fmtpos - 1); + return -1; + } + if (*p_str == NULL) + return -1; + assert (PyUnicode_Check(*p_str)); + return 0; +} + +static int +unicode_format_arg_output(struct unicode_formatter_t *ctx, + struct unicode_format_arg_t *arg, + PyObject *str) +{ + Py_ssize_t len; + enum PyUnicode_Kind kind; + void *pbuf; + Py_ssize_t pindex; + Py_UCS4 signchar; + Py_ssize_t buflen; + Py_UCS4 maxchar; + Py_ssize_t sublen; + _PyUnicodeWriter *writer = &ctx->writer; + Py_UCS4 fill; + + fill = ' '; + if (arg->sign && arg->flags & F_ZERO) + fill = '0'; + + if (PyUnicode_READY(str) == -1) + return -1; + + len = PyUnicode_GET_LENGTH(str); + if ((arg->width == -1 || arg->width <= len) + && (arg->prec == -1 || arg->prec >= len) + && !(arg->flags & (F_SIGN | F_BLANK))) + { + /* Fast path */ + if (_PyUnicodeWriter_WriteStr(writer, str) == -1) + return -1; + return 0; + } + + /* Truncate the string for "s", "r" and "a" formats + if the precision is set */ + if (arg->ch == 's' || arg->ch == 'r' || arg->ch == 'a') { + if (arg->prec >= 0 && len > arg->prec) + len = arg->prec; + } + + /* Adjust sign and width */ + kind = PyUnicode_KIND(str); + pbuf = PyUnicode_DATA(str); + pindex = 0; + signchar = '\0'; + if (arg->sign) { + Py_UCS4 ch = PyUnicode_READ(kind, pbuf, pindex); + if (ch == '-' || ch == '+') { + signchar = ch; + len--; + pindex++; + } + else if (arg->flags & F_SIGN) + signchar = '+'; + else if (arg->flags & F_BLANK) + signchar = ' '; + else + arg->sign = 0; + } + if (arg->width < len) + arg->width = len; + + /* Prepare the writer */ + maxchar = writer->maxchar; + if (!(arg->flags & F_LJUST)) { + if (arg->sign) { + if ((arg->width-1) > len) + maxchar = Py_MAX(maxchar, fill); + } + else { + if (arg->width > len) + maxchar = Py_MAX(maxchar, fill); + } + } + if (PyUnicode_MAX_CHAR_VALUE(str) > maxchar) { + Py_UCS4 strmaxchar = _PyUnicode_FindMaxChar(str, 0, pindex+len); + maxchar = Py_MAX(maxchar, strmaxchar); + } + + buflen = arg->width; + if (arg->sign && len == arg->width) + buflen++; + if (_PyUnicodeWriter_Prepare(writer, buflen, maxchar) == -1) + return -1; + + /* Write the sign if needed */ + if (arg->sign) { + if (fill != ' ') { + PyUnicode_WRITE(writer->kind, writer->data, writer->pos, signchar); + writer->pos += 1; + } + if (arg->width > len) + arg->width--; + } + + /* Write the numeric prefix for "x", "X" and "o" formats + if the alternate form is used. + For example, write "0x" for the "%#x" format. */ + if ((arg->flags & F_ALT) && (arg->ch == 'x' || arg->ch == 'X' || arg->ch == 'o')) { + assert(PyUnicode_READ(kind, pbuf, pindex) == '0'); + assert(PyUnicode_READ(kind, pbuf, pindex + 1) == arg->ch); + if (fill != ' ') { + PyUnicode_WRITE(writer->kind, writer->data, writer->pos, '0'); + PyUnicode_WRITE(writer->kind, writer->data, writer->pos+1, arg->ch); + writer->pos += 2; + pindex += 2; + } + arg->width -= 2; + if (arg->width < 0) + arg->width = 0; + len -= 2; + } + + /* Pad left with the fill character if needed */ + if (arg->width > len && !(arg->flags & F_LJUST)) { + sublen = arg->width - len; + unicode_fill(writer->kind, writer->data, fill, writer->pos, sublen); + writer->pos += sublen; + arg->width = len; + } + + /* If padding with spaces: write sign if needed and/or numeric prefix if + the alternate form is used */ + if (fill == ' ') { + if (arg->sign) { + PyUnicode_WRITE(writer->kind, writer->data, writer->pos, signchar); + writer->pos += 1; + } + if ((arg->flags & F_ALT) && (arg->ch == 'x' || arg->ch == 'X' || arg->ch == 'o')) { + assert(PyUnicode_READ(kind, pbuf, pindex) == '0'); + assert(PyUnicode_READ(kind, pbuf, pindex+1) == arg->ch); + PyUnicode_WRITE(writer->kind, writer->data, writer->pos, '0'); + PyUnicode_WRITE(writer->kind, writer->data, writer->pos+1, arg->ch); + writer->pos += 2; + pindex += 2; + } + } + + /* Write characters */ + if (len) { + _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, + str, pindex, len); + writer->pos += len; + } + + /* Pad right with the fill character if needed */ + if (arg->width > len) { + sublen = arg->width - len; + unicode_fill(writer->kind, writer->data, ' ', writer->pos, sublen); + writer->pos += sublen; + } + return 0; +} + +/* Helper of PyUnicode_Format(): format one arg. + Return 0 on success, raise an exception and return -1 on error. */ +static int +unicode_format_arg(struct unicode_formatter_t *ctx) +{ + struct unicode_format_arg_t arg; + PyObject *str; + int ret; + + arg.ch = PyUnicode_READ(ctx->fmtkind, ctx->fmtdata, ctx->fmtpos); + if (arg.ch == '%') { + ctx->fmtpos++; + ctx->fmtcnt--; + if (_PyUnicodeWriter_WriteCharInline(&ctx->writer, '%') < 0) + return -1; + return 0; + } + arg.flags = 0; + arg.width = -1; + arg.prec = -1; + arg.sign = 0; + str = NULL; + + ret = unicode_format_arg_parse(ctx, &arg); + if (ret == -1) + return -1; + + ret = unicode_format_arg_format(ctx, &arg, &str); + if (ret == -1) + return -1; + + if (ret != 1) { + ret = unicode_format_arg_output(ctx, &arg, str); + Py_DECREF(str); + if (ret == -1) + return -1; + } + + if (ctx->dict && (ctx->argidx < ctx->arglen)) { + PyErr_SetString(PyExc_TypeError, + "not all arguments converted during string formatting"); + return -1; + } + return 0; +} + +PyObject * +PyUnicode_Format(PyObject *format, PyObject *args) +{ + struct unicode_formatter_t ctx; + + if (format == NULL || args == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + if (ensure_unicode(format) < 0) + return NULL; + + ctx.fmtstr = format; + ctx.fmtdata = PyUnicode_DATA(ctx.fmtstr); + ctx.fmtkind = PyUnicode_KIND(ctx.fmtstr); + ctx.fmtcnt = PyUnicode_GET_LENGTH(ctx.fmtstr); + ctx.fmtpos = 0; + + _PyUnicodeWriter_Init(&ctx.writer); + ctx.writer.min_length = ctx.fmtcnt + 100; + ctx.writer.overallocate = 1; + + if (PyTuple_Check(args)) { + ctx.arglen = PyTuple_Size(args); + ctx.argidx = 0; + } + else { + ctx.arglen = -1; + ctx.argidx = -2; + } + ctx.args_owned = 0; + if (PyMapping_Check(args) && !PyTuple_Check(args) && !PyUnicode_Check(args)) + ctx.dict = args; + else + ctx.dict = NULL; + ctx.args = args; + + while (--ctx.fmtcnt >= 0) { + if (PyUnicode_READ(ctx.fmtkind, ctx.fmtdata, ctx.fmtpos) != '%') { + Py_ssize_t nonfmtpos; + + nonfmtpos = ctx.fmtpos++; + while (ctx.fmtcnt >= 0 && + PyUnicode_READ(ctx.fmtkind, ctx.fmtdata, ctx.fmtpos) != '%') { + ctx.fmtpos++; + ctx.fmtcnt--; + } + if (ctx.fmtcnt < 0) { + ctx.fmtpos--; + ctx.writer.overallocate = 0; + } + + if (_PyUnicodeWriter_WriteSubstring(&ctx.writer, ctx.fmtstr, + nonfmtpos, ctx.fmtpos) < 0) + goto onError; + } + else { + ctx.fmtpos++; + if (unicode_format_arg(&ctx) == -1) + goto onError; + } + } + + if (ctx.argidx < ctx.arglen && !ctx.dict) { + PyErr_SetString(PyExc_TypeError, + "not all arguments converted during string formatting"); + goto onError; + } + + if (ctx.args_owned) { + Py_DECREF(ctx.args); + } + return _PyUnicodeWriter_Finish(&ctx.writer); + + onError: + _PyUnicodeWriter_Dealloc(&ctx.writer); + if (ctx.args_owned) { + Py_DECREF(ctx.args); + } + return NULL; +} + +static PyObject * +unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + +static PyObject * +unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *x = NULL; + static char *kwlist[] = {"object", "encoding", "errors", 0}; + char *encoding = NULL; + char *errors = NULL; + + if (type != &PyUnicode_Type) + return unicode_subtype_new(type, args, kwds); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:str", + kwlist, &x, &encoding, &errors)) + return NULL; + if (x == NULL) + _Py_RETURN_UNICODE_EMPTY(); + if (encoding == NULL && errors == NULL) + return PyObject_Str(x); + else + return PyUnicode_FromEncodedObject(x, encoding, errors); +} + +static PyObject * +unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *unicode, *self; + Py_ssize_t length, char_size; + int share_wstr, share_utf8; + unsigned int kind; + void *data; + + assert(PyType_IsSubtype(type, &PyUnicode_Type)); + + unicode = unicode_new(&PyUnicode_Type, args, kwds); + if (unicode == NULL) + return NULL; + assert(_PyUnicode_CHECK(unicode)); + if (PyUnicode_READY(unicode) == -1) { + Py_DECREF(unicode); + return NULL; + } + + self = type->tp_alloc(type, 0); + if (self == NULL) { + Py_DECREF(unicode); + return NULL; + } + kind = PyUnicode_KIND(unicode); + length = PyUnicode_GET_LENGTH(unicode); + + _PyUnicode_LENGTH(self) = length; +#ifdef Py_DEBUG + _PyUnicode_HASH(self) = -1; +#else + _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode); +#endif + _PyUnicode_STATE(self).interned = 0; + _PyUnicode_STATE(self).kind = kind; + _PyUnicode_STATE(self).compact = 0; + _PyUnicode_STATE(self).ascii = _PyUnicode_STATE(unicode).ascii; + _PyUnicode_STATE(self).ready = 1; + _PyUnicode_WSTR(self) = NULL; + _PyUnicode_UTF8_LENGTH(self) = 0; + _PyUnicode_UTF8(self) = NULL; + _PyUnicode_WSTR_LENGTH(self) = 0; + _PyUnicode_DATA_ANY(self) = NULL; + + share_utf8 = 0; + share_wstr = 0; + if (kind == PyUnicode_1BYTE_KIND) { + char_size = 1; + if (PyUnicode_MAX_CHAR_VALUE(unicode) < 128) + share_utf8 = 1; + } + else if (kind == PyUnicode_2BYTE_KIND) { + char_size = 2; + if (sizeof(wchar_t) == 2) + share_wstr = 1; + } + else { + assert(kind == PyUnicode_4BYTE_KIND); + char_size = 4; + if (sizeof(wchar_t) == 4) + share_wstr = 1; + } + + /* Ensure we won't overflow the length. */ + if (length > (PY_SSIZE_T_MAX / char_size - 1)) { + PyErr_NoMemory(); + goto onError; + } + data = PyObject_MALLOC((length + 1) * char_size); + if (data == NULL) { + PyErr_NoMemory(); + goto onError; + } + + _PyUnicode_DATA_ANY(self) = data; + if (share_utf8) { + _PyUnicode_UTF8_LENGTH(self) = length; + _PyUnicode_UTF8(self) = data; + } + if (share_wstr) { + _PyUnicode_WSTR_LENGTH(self) = length; + _PyUnicode_WSTR(self) = (wchar_t *)data; + } + + memcpy(data, PyUnicode_DATA(unicode), + kind * (length + 1)); + assert(_PyUnicode_CheckConsistency(self, 1)); +#ifdef Py_DEBUG + _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode); +#endif + Py_DECREF(unicode); + return self; + +onError: + Py_DECREF(unicode); + Py_DECREF(self); + return NULL; +} + +PyDoc_STRVAR(unicode_doc, +"str(object='') -> str\n\ +str(bytes_or_buffer[, encoding[, errors]]) -> str\n\ +\n\ +Create a new string object from the given object. If encoding or\n\ +errors is specified, then the object must expose a data buffer\n\ +that will be decoded using the given encoding and error handler.\n\ +Otherwise, returns the result of object.__str__() (if defined)\n\ +or repr(object).\n\ +encoding defaults to sys.getdefaultencoding().\n\ +errors defaults to 'strict'."); + +static PyObject *unicode_iter(PyObject *seq); + +PyTypeObject PyUnicode_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "str", /* tp_name */ + sizeof(PyUnicodeObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* Slots */ + (destructor)unicode_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + unicode_repr, /* tp_repr */ + &unicode_as_number, /* tp_as_number */ + &unicode_as_sequence, /* tp_as_sequence */ + &unicode_as_mapping, /* tp_as_mapping */ + (hashfunc) unicode_hash, /* tp_hash*/ + 0, /* tp_call*/ + (reprfunc) unicode_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_UNICODE_SUBCLASS, /* tp_flags */ + unicode_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + PyUnicode_RichCompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + unicode_iter, /* tp_iter */ + 0, /* tp_iternext */ + unicode_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + unicode_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + +/* Initialize the Unicode implementation */ + +PyStatus +_PyUnicode_Init(void) +{ + /* XXX - move this array to unicodectype.c ? */ + Py_UCS2 linebreak[] = { + 0x000A, /* LINE FEED */ + 0x000D, /* CARRIAGE RETURN */ + 0x001C, /* FILE SEPARATOR */ + 0x001D, /* GROUP SEPARATOR */ + 0x001E, /* RECORD SEPARATOR */ + 0x0085, /* NEXT LINE */ + 0x2028, /* LINE SEPARATOR */ + 0x2029, /* PARAGRAPH SEPARATOR */ + }; + + /* Init the implementation */ + _Py_INCREF_UNICODE_EMPTY(); + if (!unicode_empty) { + return _PyStatus_ERR("Can't create empty string"); + } + Py_DECREF(unicode_empty); + + if (PyType_Ready(&PyUnicode_Type) < 0) { + return _PyStatus_ERR("Can't initialize unicode type"); + } + + /* initialize the linebreak bloom filter */ + bloom_linebreak = make_bloom_mask( + PyUnicode_2BYTE_KIND, linebreak, + Py_ARRAY_LENGTH(linebreak)); + + if (PyType_Ready(&EncodingMapType) < 0) { + return _PyStatus_ERR("Can't initialize encoding map type"); + } + if (PyType_Ready(&PyFieldNameIter_Type) < 0) { + return _PyStatus_ERR("Can't initialize field name iterator type"); + } + if (PyType_Ready(&PyFormatterIter_Type) < 0) { + return _PyStatus_ERR("Can't initialize formatter iter type"); + } + return _PyStatus_OK(); +} + +/* Finalize the Unicode implementation */ + +int +PyUnicode_ClearFreeList(void) +{ + return 0; +} + + +void +PyUnicode_InternInPlace(PyObject **p) +{ + PyObject *s = *p; + PyObject *t; +#ifdef Py_DEBUG + assert(s != NULL); + assert(_PyUnicode_CHECK(s)); +#else + if (s == NULL || !PyUnicode_Check(s)) + return; +#endif + /* If it's a subclass, we don't really know what putting + it in the interned dict might do. */ + if (!PyUnicode_CheckExact(s)) + return; + if (PyUnicode_CHECK_INTERNED(s)) + return; + if (interned == NULL) { + interned = PyDict_New(); + if (interned == NULL) { + PyErr_Clear(); /* Don't leave an exception */ + return; + } + } + t = PyDict_SetDefault(interned, s, s); + if (t == NULL) { + PyErr_Clear(); + return; + } + if (t != s) { + Py_INCREF(t); + Py_SETREF(*p, t); + return; + } + /* The two references in interned are not counted by refcnt. + The deallocator will take care of this */ + Py_REFCNT(s) -= 2; + _PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL; +} + +void +PyUnicode_InternImmortal(PyObject **p) +{ + PyUnicode_InternInPlace(p); + if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { + _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; + Py_INCREF(*p); + } +} + +PyObject * +PyUnicode_InternFromString(const char *cp) +{ + PyObject *s = PyUnicode_FromString(cp); + if (s == NULL) + return NULL; + PyUnicode_InternInPlace(&s); + return s; +} + + +#if defined(WITH_VALGRIND) || defined(__INSURE__) +static void +unicode_release_interned(void) +{ + PyObject *keys; + PyObject *s; + Py_ssize_t i, n; + Py_ssize_t immortal_size = 0, mortal_size = 0; + + if (interned == NULL || !PyDict_Check(interned)) + return; + keys = PyDict_Keys(interned); + if (keys == NULL || !PyList_Check(keys)) { + PyErr_Clear(); + return; + } + + /* Since unicode_release_interned() is intended to help a leak + detector, interned unicode strings are not forcibly deallocated; + rather, we give them their stolen references back, and then clear + and DECREF the interned dict. */ + + n = PyList_GET_SIZE(keys); +#ifdef INTERNED_STATS + fprintf(stderr, "releasing %" PY_FORMAT_SIZE_T "d interned strings\n", + n); +#endif + for (i = 0; i < n; i++) { + s = PyList_GET_ITEM(keys, i); + if (PyUnicode_READY(s) == -1) { + Py_UNREACHABLE(); + } + switch (PyUnicode_CHECK_INTERNED(s)) { + case SSTATE_NOT_INTERNED: + /* XXX Shouldn't happen */ + break; + case SSTATE_INTERNED_IMMORTAL: + Py_REFCNT(s) += 1; + immortal_size += PyUnicode_GET_LENGTH(s); + break; + case SSTATE_INTERNED_MORTAL: + Py_REFCNT(s) += 2; + mortal_size += PyUnicode_GET_LENGTH(s); + break; + default: + Py_FatalError("Inconsistent interned string state."); + } + _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + } +#ifdef INTERNED_STATS + fprintf(stderr, "total size of all interned strings: " + "%" PY_FORMAT_SIZE_T "d/%" PY_FORMAT_SIZE_T "d " + "mortal/immortal\n", mortal_size, immortal_size); +#endif + Py_DECREF(keys); + PyDict_Clear(interned); + Py_CLEAR(interned); +} +#endif + + +/********************* Unicode Iterator **************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyObject *it_seq; /* Set to NULL when iterator is exhausted */ +} unicodeiterobject; + +static void +unicodeiter_dealloc(unicodeiterobject *it) +{ + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); +} + +static int +unicodeiter_traverse(unicodeiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->it_seq); + return 0; +} + +static PyObject * +unicodeiter_next(unicodeiterobject *it) +{ + PyObject *seq, *item; + + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) + return NULL; + assert(_PyUnicode_CHECK(seq)); + + if (it->it_index < PyUnicode_GET_LENGTH(seq)) { + int kind = PyUnicode_KIND(seq); + void *data = PyUnicode_DATA(seq); + Py_UCS4 chr = PyUnicode_READ(kind, data, it->it_index); + item = PyUnicode_FromOrdinal(chr); + if (item != NULL) + ++it->it_index; + return item; + } + + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + +static PyObject * +unicodeiter_len(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t len = 0; + if (it->it_seq) + len = PyUnicode_GET_LENGTH(it->it_seq) - it->it_index; + return PyLong_FromSsize_t(len); +} + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); + +static PyObject * +unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(iter); + if (it->it_seq != NULL) { + return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + it->it_seq, it->it_index); + } else { + PyObject *u = (PyObject *)_PyUnicode_New(0); + if (u == NULL) + return NULL; + return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), u); + } +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyObject * +unicodeiter_setstate(unicodeiterobject *it, PyObject *state) +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyUnicode_GET_LENGTH(it->it_seq)) + index = PyUnicode_GET_LENGTH(it->it_seq); /* iterator truncated */ + it->it_index = index; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef unicodeiter_methods[] = { + {"__length_hint__", (PyCFunction)unicodeiter_len, METH_NOARGS, + length_hint_doc}, + {"__reduce__", (PyCFunction)unicodeiter_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)unicodeiter_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyUnicodeIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "str_iterator", /* tp_name */ + sizeof(unicodeiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)unicodeiter_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,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)unicodeiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)unicodeiter_next, /* tp_iternext */ + unicodeiter_methods, /* tp_methods */ + 0, +}; + +static PyObject * +unicode_iter(PyObject *seq) +{ + unicodeiterobject *it; + + if (!PyUnicode_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + if (PyUnicode_READY(seq) == -1) + return NULL; + it = PyObject_GC_New(unicodeiterobject, &PyUnicodeIter_Type); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; +} + + +size_t +Py_UNICODE_strlen(const Py_UNICODE *u) +{ + return wcslen(u); +} + +Py_UNICODE* +Py_UNICODE_strcpy(Py_UNICODE *s1, const Py_UNICODE *s2) +{ + Py_UNICODE *u = s1; + while ((*u++ = *s2++)); + return s1; +} + +Py_UNICODE* +Py_UNICODE_strncpy(Py_UNICODE *s1, const Py_UNICODE *s2, size_t n) +{ + Py_UNICODE *u = s1; + while ((*u++ = *s2++)) + if (n-- == 0) + break; + return s1; +} + +Py_UNICODE* +Py_UNICODE_strcat(Py_UNICODE *s1, const Py_UNICODE *s2) +{ + Py_UNICODE *u1 = s1; + u1 += wcslen(u1); + while ((*u1++ = *s2++)); + return s1; +} + +int +Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2) +{ + while (*s1 && *s2 && *s1 == *s2) + s1++, s2++; + if (*s1 && *s2) + return (*s1 < *s2) ? -1 : +1; + if (*s1) + return 1; + if (*s2) + return -1; + return 0; +} + +int +Py_UNICODE_strncmp(const Py_UNICODE *s1, const Py_UNICODE *s2, size_t n) +{ + Py_UNICODE u1, u2; + for (; n != 0; n--) { + u1 = *s1; + u2 = *s2; + if (u1 != u2) + return (u1 < u2) ? -1 : +1; + if (u1 == '\0') + return 0; + s1++; + s2++; + } + return 0; +} + +Py_UNICODE* +Py_UNICODE_strchr(const Py_UNICODE *s, Py_UNICODE c) +{ + const Py_UNICODE *p; + for (p = s; *p; p++) + if (*p == c) + return (Py_UNICODE*)p; + return NULL; +} + +Py_UNICODE* +Py_UNICODE_strrchr(const Py_UNICODE *s, Py_UNICODE c) +{ + const Py_UNICODE *p; + p = s + wcslen(s); + while (p != s) { + p--; + if (*p == c) + return (Py_UNICODE*)p; + } + return NULL; +} + +Py_UNICODE* +PyUnicode_AsUnicodeCopy(PyObject *unicode) +{ + Py_UNICODE *u, *copy; + Py_ssize_t len, size; + + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + u = PyUnicode_AsUnicodeAndSize(unicode, &len); + if (u == NULL) + return NULL; + /* Ensure we won't overflow the size. */ + if (len > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { + PyErr_NoMemory(); + return NULL; + } + size = len + 1; /* copy the null character */ + size *= sizeof(Py_UNICODE); + copy = PyMem_Malloc(size); + if (copy == NULL) { + PyErr_NoMemory(); + return NULL; + } + memcpy(copy, u, size); + return copy; +} + + +static int +encode_wstr_utf8(wchar_t *wstr, char **str, const char *name) +{ + int res; + res = _Py_EncodeUTF8Ex(wstr, str, NULL, NULL, 1, _Py_ERROR_STRICT); + if (res == -2) { + PyErr_Format(PyExc_RuntimeWarning, "cannot decode %s", name); + return -1; + } + if (res < 0) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + + +static int +config_get_codec_name(wchar_t **config_encoding) +{ + char *encoding; + if (encode_wstr_utf8(*config_encoding, &encoding, "stdio_encoding") < 0) { + return -1; + } + + PyObject *name_obj = NULL; + PyObject *codec = _PyCodec_Lookup(encoding); + PyMem_RawFree(encoding); + + if (!codec) + goto error; + + name_obj = PyObject_GetAttrString(codec, "name"); + Py_CLEAR(codec); + if (!name_obj) { + goto error; + } + + wchar_t *wname = PyUnicode_AsWideCharString(name_obj, NULL); + Py_DECREF(name_obj); + if (wname == NULL) { + goto error; + } + + wchar_t *raw_wname = _PyMem_RawWcsdup(wname); + if (raw_wname == NULL) { + PyMem_Free(wname); + PyErr_NoMemory(); + goto error; + } + + PyMem_RawFree(*config_encoding); + *config_encoding = raw_wname; + + PyMem_Free(wname); + return 0; + +error: + Py_XDECREF(codec); + Py_XDECREF(name_obj); + return -1; +} + + +static PyStatus +init_stdio_encoding(PyThreadState *tstate) +{ + /* Update the stdio encoding to the normalized Python codec name. */ + PyConfig *config = &tstate->interp->config; + if (config_get_codec_name(&config->stdio_encoding) < 0) { + return _PyStatus_ERR("failed to get the Python codec name " + "of the stdio encoding"); + } + return _PyStatus_OK(); +} + + +static int +init_fs_codec(PyInterpreterState *interp) +{ + PyConfig *config = &interp->config; + + _Py_error_handler error_handler; + error_handler = get_error_handler_wide(config->filesystem_errors); + if (error_handler == _Py_ERROR_UNKNOWN) { + PyErr_SetString(PyExc_RuntimeError, "unknow filesystem error handler"); + return -1; + } + + char *encoding, *errors; + if (encode_wstr_utf8(config->filesystem_encoding, + &encoding, + "filesystem_encoding") < 0) { + return -1; + } + + if (encode_wstr_utf8(config->filesystem_errors, + &errors, + "filesystem_errors") < 0) { + PyMem_RawFree(encoding); + return -1; + } + + PyMem_RawFree(interp->fs_codec.encoding); + interp->fs_codec.encoding = encoding; + PyMem_RawFree(interp->fs_codec.errors); + interp->fs_codec.errors = errors; + interp->fs_codec.error_handler = error_handler; + + /* At this point, PyUnicode_EncodeFSDefault() and + PyUnicode_DecodeFSDefault() can now use the Python codec rather than + the C implementation of the filesystem encoding. */ + + /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors + global configuration variables. */ + if (_Py_SetFileSystemEncoding(interp->fs_codec.encoding, + interp->fs_codec.errors) < 0) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + + +static PyStatus +init_fs_encoding(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + + /* Update the filesystem encoding to the normalized Python codec name. + For example, replace "ANSI_X3.4-1968" (locale encoding) with "ascii" + (Python codec name). */ + PyConfig *config = &interp->config; + // int i=0; + // while (config->filesystem_encoding[i]!=0) + // { + // printf("%c,",config->filesystem_encoding[i]); + // i++; + // } + + if (config_get_codec_name(&config->filesystem_encoding) < 0) { + _Py_DumpPathConfig(tstate); + return _PyStatus_ERR("failed to get the Python codec " + "of the filesystem encoding"); + } + + if (init_fs_codec(interp) < 0) { + return _PyStatus_ERR("cannot initialize filesystem codec"); + } + return _PyStatus_OK(); +} + + +PyStatus +_PyUnicode_InitEncodings(PyThreadState *tstate) +{ + PyStatus status = init_fs_encoding(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + return init_stdio_encoding(tstate); +} + + +#ifdef MS_WINDOWS +int +_PyUnicode_EnableLegacyWindowsFSEncoding(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + PyConfig *config = &interp->config; + + /* Set the filesystem encoding to mbcs/replace (PEP 529) */ + wchar_t *encoding = _PyMem_RawWcsdup(L"mbcs"); + wchar_t *errors = _PyMem_RawWcsdup(L"replace"); + if (encoding == NULL || errors == NULL) { + PyMem_RawFree(encoding); + PyMem_RawFree(errors); + PyErr_NoMemory(); + return -1; + } + + PyMem_RawFree(config->filesystem_encoding); + config->filesystem_encoding = encoding; + PyMem_RawFree(config->filesystem_errors); + config->filesystem_errors = errors; + + return init_fs_codec(interp); +} +#endif + + +void +_PyUnicode_Fini(void) +{ +#if defined(WITH_VALGRIND) || defined(__INSURE__) + /* Insure++ is a memory analysis tool that aids in discovering + * memory leaks and other memory problems. On Python exit, the + * interned string dictionaries are flagged as being in use at exit + * (which it is). Under normal circumstances, this is fine because + * the memory will be automatically reclaimed by the system. Under + * memory debugging, it's a huge source of useless noise, so we + * trade off slower shutdown for less distraction in the memory + * reports. -baw + */ + unicode_release_interned(); +#endif /* __INSURE__ */ + + Py_CLEAR(unicode_empty); + + for (Py_ssize_t i = 0; i < 256; i++) { + Py_CLEAR(unicode_latin1[i]); + } + _PyUnicode_ClearStaticStrings(); + (void)PyUnicode_ClearFreeList(); + + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + PyMem_RawFree(interp->fs_codec.encoding); + interp->fs_codec.encoding = NULL; + PyMem_RawFree(interp->fs_codec.errors); + interp->fs_codec.errors = NULL; +} + + +/* A _string module, to export formatter_parser and formatter_field_name_split + to the string.Formatter class implemented in Python. */ + +static PyMethodDef _string_methods[] = { + {"formatter_field_name_split", (PyCFunction) formatter_field_name_split, + METH_O, PyDoc_STR("split the argument as a field name")}, + {"formatter_parser", (PyCFunction) formatter_parser, + METH_O, PyDoc_STR("parse the argument as a format string")}, + {NULL, NULL} +}; + +static struct PyModuleDef _string_module = { + PyModuleDef_HEAD_INIT, + "_string", + PyDoc_STR("string helper module"), + 0, + _string_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__string(void) +{ + return PyModule_Create(&_string_module); +} + + +#ifdef __cplusplus +} +#endif diff --git a/python/Objects/unicodetype_db.h b/python/Objects/unicodetype_db.h new file mode 100755 index 0000000..693e0b3 --- /dev/null +++ b/python/Objects/unicodetype_db.h @@ -0,0 +1,6209 @@ +/* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ + +/* a list of unique character type descriptors */ +const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 32}, + {0, 0, 0, 0, 0, 48}, + {0, 0, 0, 0, 0, 1056}, + {0, 0, 0, 0, 0, 1024}, + {0, 0, 0, 0, 0, 5120}, + {0, 0, 0, 0, 0, 3590}, + {0, 0, 0, 1, 1, 3590}, + {0, 0, 0, 2, 2, 3590}, + {0, 0, 0, 3, 3, 3590}, + {0, 0, 0, 4, 4, 3590}, + {0, 0, 0, 5, 5, 3590}, + {0, 0, 0, 6, 6, 3590}, + {0, 0, 0, 7, 7, 3590}, + {0, 0, 0, 8, 8, 3590}, + {0, 0, 0, 9, 9, 3590}, + {0, 32, 0, 0, 0, 10113}, + {0, 0, 0, 0, 0, 1536}, + {-32, 0, -32, 0, 0, 9993}, + {0, 0, 0, 0, 0, 9993}, + {0, 0, 0, 0, 0, 4096}, + {0, 0, 0, 0, 2, 3076}, + {0, 0, 0, 0, 3, 3076}, + {16777218, 17825792, 16777218, 0, 0, 26377}, + {0, 0, 0, 0, 0, 5632}, + {0, 0, 0, 0, 1, 3076}, + {0, 0, 0, 0, 0, 3072}, + {33554438, 18874371, 33554440, 0, 0, 26377}, + {121, 0, 121, 0, 0, 9993}, + {0, 1, 0, 0, 0, 10113}, + {-1, 0, -1, 0, 0, 9993}, + {16777228, 33554442, 16777228, 0, 0, 26497}, + {-232, 0, -232, 0, 0, 9993}, + {33554448, 18874381, 33554448, 0, 0, 26377}, + {0, -121, 0, 0, 0, 10113}, + {16777236, 17825810, 16777236, 0, 0, 26377}, + {195, 0, 195, 0, 0, 9993}, + {0, 210, 0, 0, 0, 10113}, + {0, 206, 0, 0, 0, 10113}, + {0, 205, 0, 0, 0, 10113}, + {0, 79, 0, 0, 0, 10113}, + {0, 202, 0, 0, 0, 10113}, + {0, 203, 0, 0, 0, 10113}, + {0, 207, 0, 0, 0, 10113}, + {97, 0, 97, 0, 0, 9993}, + {0, 211, 0, 0, 0, 10113}, + {0, 209, 0, 0, 0, 10113}, + {163, 0, 163, 0, 0, 9993}, + {0, 213, 0, 0, 0, 10113}, + {130, 0, 130, 0, 0, 9993}, + {0, 214, 0, 0, 0, 10113}, + {0, 218, 0, 0, 0, 10113}, + {0, 217, 0, 0, 0, 10113}, + {0, 219, 0, 0, 0, 10113}, + {0, 0, 0, 0, 0, 1793}, + {56, 0, 56, 0, 0, 9993}, + {0, 2, 1, 0, 0, 10113}, + {-1, 1, 0, 0, 0, 10049}, + {-2, 0, -1, 0, 0, 9993}, + {-79, 0, -79, 0, 0, 9993}, + {33554456, 18874389, 33554456, 0, 0, 26377}, + {0, -97, 0, 0, 0, 10113}, + {0, -56, 0, 0, 0, 10113}, + {0, -130, 0, 0, 0, 10113}, + {0, 10795, 0, 0, 0, 10113}, + {0, -163, 0, 0, 0, 10113}, + {0, 10792, 0, 0, 0, 10113}, + {10815, 0, 10815, 0, 0, 9993}, + {0, -195, 0, 0, 0, 10113}, + {0, 69, 0, 0, 0, 10113}, + {0, 71, 0, 0, 0, 10113}, + {10783, 0, 10783, 0, 0, 9993}, + {10780, 0, 10780, 0, 0, 9993}, + {10782, 0, 10782, 0, 0, 9993}, + {-210, 0, -210, 0, 0, 9993}, + {-206, 0, -206, 0, 0, 9993}, + {-205, 0, -205, 0, 0, 9993}, + {-202, 0, -202, 0, 0, 9993}, + {-203, 0, -203, 0, 0, 9993}, + {42319, 0, 42319, 0, 0, 9993}, + {42315, 0, 42315, 0, 0, 9993}, + {-207, 0, -207, 0, 0, 9993}, + {42280, 0, 42280, 0, 0, 9993}, + {42308, 0, 42308, 0, 0, 9993}, + {-209, 0, -209, 0, 0, 9993}, + {-211, 0, -211, 0, 0, 9993}, + {10743, 0, 10743, 0, 0, 9993}, + {42305, 0, 42305, 0, 0, 9993}, + {10749, 0, 10749, 0, 0, 9993}, + {-213, 0, -213, 0, 0, 9993}, + {-214, 0, -214, 0, 0, 9993}, + {10727, 0, 10727, 0, 0, 9993}, + {-218, 0, -218, 0, 0, 9993}, + {42307, 0, 42307, 0, 0, 9993}, + {42282, 0, 42282, 0, 0, 9993}, + {-69, 0, -69, 0, 0, 9993}, + {-217, 0, -217, 0, 0, 9993}, + {-71, 0, -71, 0, 0, 9993}, + {-219, 0, -219, 0, 0, 9993}, + {42261, 0, 42261, 0, 0, 9993}, + {42258, 0, 42258, 0, 0, 9993}, + {0, 0, 0, 0, 0, 14089}, + {0, 0, 0, 0, 0, 5889}, + {16777244, 17825818, 16777244, 0, 0, 30216}, + {0, 0, 0, 0, 0, 13321}, + {0, 116, 0, 0, 0, 10113}, + {0, 38, 0, 0, 0, 10113}, + {0, 37, 0, 0, 0, 10113}, + {0, 64, 0, 0, 0, 10113}, + {0, 63, 0, 0, 0, 10113}, + {50331681, 19922973, 50331681, 0, 0, 26377}, + {-38, 0, -38, 0, 0, 9993}, + {-37, 0, -37, 0, 0, 9993}, + {50331688, 19922980, 50331688, 0, 0, 26377}, + {16777261, 17825835, 16777261, 0, 0, 26377}, + {-64, 0, -64, 0, 0, 9993}, + {-63, 0, -63, 0, 0, 9993}, + {0, 8, 0, 0, 0, 10113}, + {16777264, 17825838, 16777264, 0, 0, 26377}, + {16777267, 17825841, 16777267, 0, 0, 26377}, + {0, 0, 0, 0, 0, 10113}, + {16777270, 17825844, 16777270, 0, 0, 26377}, + {16777273, 17825847, 16777273, 0, 0, 26377}, + {-8, 0, -8, 0, 0, 9993}, + {16777276, 17825850, 16777276, 0, 0, 26377}, + {16777279, 17825853, 16777279, 0, 0, 26377}, + {7, 0, 7, 0, 0, 9993}, + {-116, 0, -116, 0, 0, 9993}, + {0, -60, 0, 0, 0, 10113}, + {16777282, 17825856, 16777282, 0, 0, 26377}, + {0, -7, 0, 0, 0, 10113}, + {0, 80, 0, 0, 0, 10113}, + {-80, 0, -80, 0, 0, 9993}, + {0, 15, 0, 0, 0, 10113}, + {-15, 0, -15, 0, 0, 9993}, + {0, 48, 0, 0, 0, 10113}, + {-48, 0, -48, 0, 0, 9993}, + {33554502, 18874435, 33554504, 0, 0, 26377}, + {0, 0, 0, 0, 0, 1537}, + {0, 7264, 0, 0, 0, 10113}, + {3008, 0, 0, 0, 0, 9993}, + {0, 0, 0, 0, 1, 3588}, + {0, 0, 0, 0, 2, 3588}, + {0, 0, 0, 0, 3, 3588}, + {0, 0, 0, 0, 4, 3588}, + {0, 0, 0, 0, 5, 3588}, + {0, 0, 0, 0, 6, 3588}, + {0, 0, 0, 0, 7, 3588}, + {0, 0, 0, 0, 8, 3588}, + {0, 0, 0, 0, 9, 3588}, + {16777292, 17825866, 16777292, 0, 0, 26497}, + {16777295, 17825869, 16777295, 0, 0, 26497}, + {16777298, 17825872, 16777298, 0, 0, 26497}, + {16777301, 17825875, 16777301, 0, 0, 26497}, + {16777304, 17825878, 16777304, 0, 0, 26497}, + {16777307, 17825881, 16777307, 0, 0, 26497}, + {16777310, 17825884, 16777310, 0, 0, 26497}, + {16777313, 17825887, 16777313, 0, 0, 26497}, + {16777316, 17825890, 16777316, 0, 0, 26497}, + {16777319, 17825893, 16777319, 0, 0, 26497}, + {16777322, 17825896, 16777322, 0, 0, 26497}, + {16777325, 17825899, 16777325, 0, 0, 26497}, + {16777328, 17825902, 16777328, 0, 0, 26497}, + {16777331, 17825905, 16777331, 0, 0, 26497}, + {16777334, 17825908, 16777334, 0, 0, 26497}, + {16777337, 17825911, 16777337, 0, 0, 26497}, + {16777340, 17825914, 16777340, 0, 0, 26497}, + {16777343, 17825917, 16777343, 0, 0, 26497}, + {16777346, 17825920, 16777346, 0, 0, 26497}, + {16777349, 17825923, 16777349, 0, 0, 26497}, + {16777352, 17825926, 16777352, 0, 0, 26497}, + {16777355, 17825929, 16777355, 0, 0, 26497}, + {16777358, 17825932, 16777358, 0, 0, 26497}, + {16777361, 17825935, 16777361, 0, 0, 26497}, + {16777364, 17825938, 16777364, 0, 0, 26497}, + {16777367, 17825941, 16777367, 0, 0, 26497}, + {16777370, 17825944, 16777370, 0, 0, 26497}, + {16777373, 17825947, 16777373, 0, 0, 26497}, + {16777376, 17825950, 16777376, 0, 0, 26497}, + {16777379, 17825953, 16777379, 0, 0, 26497}, + {16777382, 17825956, 16777382, 0, 0, 26497}, + {16777385, 17825959, 16777385, 0, 0, 26497}, + {16777388, 17825962, 16777388, 0, 0, 26497}, + {16777391, 17825965, 16777391, 0, 0, 26497}, + {16777394, 17825968, 16777394, 0, 0, 26497}, + {16777397, 17825971, 16777397, 0, 0, 26497}, + {16777400, 17825974, 16777400, 0, 0, 26497}, + {16777403, 17825977, 16777403, 0, 0, 26497}, + {16777406, 17825980, 16777406, 0, 0, 26497}, + {16777409, 17825983, 16777409, 0, 0, 26497}, + {16777412, 17825986, 16777412, 0, 0, 26497}, + {16777415, 17825989, 16777415, 0, 0, 26497}, + {16777418, 17825992, 16777418, 0, 0, 26497}, + {16777421, 17825995, 16777421, 0, 0, 26497}, + {16777424, 17825998, 16777424, 0, 0, 26497}, + {16777427, 17826001, 16777427, 0, 0, 26497}, + {16777430, 17826004, 16777430, 0, 0, 26497}, + {16777433, 17826007, 16777433, 0, 0, 26497}, + {16777436, 17826010, 16777436, 0, 0, 26497}, + {16777439, 17826013, 16777439, 0, 0, 26497}, + {16777442, 17826016, 16777442, 0, 0, 26497}, + {16777445, 17826019, 16777445, 0, 0, 26497}, + {16777448, 17826022, 16777448, 0, 0, 26497}, + {16777451, 17826025, 16777451, 0, 0, 26497}, + {16777454, 17826028, 16777454, 0, 0, 26497}, + {16777457, 17826031, 16777457, 0, 0, 26497}, + {16777460, 17826034, 16777460, 0, 0, 26497}, + {16777463, 17826037, 16777463, 0, 0, 26497}, + {16777466, 17826040, 16777466, 0, 0, 26497}, + {16777469, 17826043, 16777469, 0, 0, 26497}, + {16777472, 17826046, 16777472, 0, 0, 26497}, + {16777475, 17826049, 16777475, 0, 0, 26497}, + {16777478, 17826052, 16777478, 0, 0, 26497}, + {16777481, 17826055, 16777481, 0, 0, 26497}, + {16777484, 17826058, 16777484, 0, 0, 26497}, + {16777487, 17826061, 16777487, 0, 0, 26497}, + {16777490, 17826064, 16777490, 0, 0, 26497}, + {16777493, 17826067, 16777493, 0, 0, 26497}, + {16777496, 17826070, 16777496, 0, 0, 26497}, + {16777499, 17826073, 16777499, 0, 0, 26497}, + {16777502, 17826076, 16777502, 0, 0, 26497}, + {16777505, 17826079, 16777505, 0, 0, 26497}, + {16777508, 17826082, 16777508, 0, 0, 26497}, + {16777511, 17826085, 16777511, 0, 0, 26497}, + {16777514, 17826088, 16777514, 0, 0, 26497}, + {16777517, 17826091, 16777517, 0, 0, 26497}, + {16777520, 17826094, 16777520, 0, 0, 26497}, + {16777523, 17826097, 16777523, 0, 0, 26497}, + {16777526, 17826100, 16777526, 0, 0, 26497}, + {16777529, 17826103, 16777529, 0, 0, 26497}, + {16777532, 17826106, 16777532, 0, 0, 26497}, + {16777535, 17826109, 16777535, 0, 0, 26497}, + {16777538, 17826112, 16777538, 0, 0, 26497}, + {16777541, 17826115, 16777541, 0, 0, 26497}, + {16777544, 17826118, 16777544, 0, 0, 26497}, + {16777547, 17826121, 16777547, 0, 0, 26497}, + {16777550, 17826124, 16777550, 0, 0, 26377}, + {16777553, 17826127, 16777553, 0, 0, 26377}, + {16777556, 17826130, 16777556, 0, 0, 26377}, + {16777559, 17826133, 16777559, 0, 0, 26377}, + {16777562, 17826136, 16777562, 0, 0, 26377}, + {16777565, 17826139, 16777565, 0, 0, 26377}, + {0, 0, 0, 0, 0, 3840}, + {0, 0, 0, 0, 0, 5888}, + {16777568, 17826142, 16777568, 0, 0, 26377}, + {16777571, 17826145, 16777571, 0, 0, 26377}, + {16777574, 17826148, 16777574, 0, 0, 26377}, + {16777577, 17826151, 16777577, 0, 0, 26377}, + {16777580, 17826154, 16777580, 0, 0, 26377}, + {16777583, 17826157, 16777583, 0, 0, 26377}, + {16777586, 17826160, 16777586, 0, 0, 26377}, + {16777589, 17826163, 16777589, 0, 0, 26377}, + {16777592, 17826166, 16777592, 0, 0, 26377}, + {0, -3008, 0, 0, 0, 10113}, + {35332, 0, 35332, 0, 0, 9993}, + {3814, 0, 3814, 0, 0, 9993}, + {35384, 0, 35384, 0, 0, 9993}, + {33554812, 18874745, 33554812, 0, 0, 26377}, + {33554817, 18874750, 33554817, 0, 0, 26377}, + {33554822, 18874755, 33554822, 0, 0, 26377}, + {33554827, 18874760, 33554827, 0, 0, 26377}, + {33554832, 18874765, 33554832, 0, 0, 26377}, + {16777620, 17826194, 16777620, 0, 0, 26377}, + {16777624, 18874773, 16777624, 0, 0, 26497}, + {8, 0, 8, 0, 0, 9993}, + {0, -8, 0, 0, 0, 10113}, + {33554844, 18874777, 33554844, 0, 0, 26377}, + {50332066, 19923358, 50332066, 0, 0, 26377}, + {50332073, 19923365, 50332073, 0, 0, 26377}, + {50332080, 19923372, 50332080, 0, 0, 26377}, + {74, 0, 74, 0, 0, 9993}, + {86, 0, 86, 0, 0, 9993}, + {100, 0, 100, 0, 0, 9993}, + {128, 0, 128, 0, 0, 9993}, + {112, 0, 112, 0, 0, 9993}, + {126, 0, 126, 0, 0, 9993}, + {33554870, 18874803, 16777656, 0, 0, 26377}, + {33554876, 18874809, 16777662, 0, 0, 26377}, + {33554882, 18874815, 16777668, 0, 0, 26377}, + {33554888, 18874821, 16777674, 0, 0, 26377}, + {33554894, 18874827, 16777680, 0, 0, 26377}, + {33554900, 18874833, 16777686, 0, 0, 26377}, + {33554906, 18874839, 16777692, 0, 0, 26377}, + {33554912, 18874845, 16777698, 0, 0, 26377}, + {33554918, 18874851, 16777704, 0, 0, 26433}, + {33554924, 18874857, 16777710, 0, 0, 26433}, + {33554930, 18874863, 16777716, 0, 0, 26433}, + {33554936, 18874869, 16777722, 0, 0, 26433}, + {33554942, 18874875, 16777728, 0, 0, 26433}, + {33554948, 18874881, 16777734, 0, 0, 26433}, + {33554954, 18874887, 16777740, 0, 0, 26433}, + {33554960, 18874893, 16777746, 0, 0, 26433}, + {33554966, 18874899, 16777752, 0, 0, 26377}, + {33554972, 18874905, 16777758, 0, 0, 26377}, + {33554978, 18874911, 16777764, 0, 0, 26377}, + {33554984, 18874917, 16777770, 0, 0, 26377}, + {33554990, 18874923, 16777776, 0, 0, 26377}, + {33554996, 18874929, 16777782, 0, 0, 26377}, + {33555002, 18874935, 16777788, 0, 0, 26377}, + {33555008, 18874941, 16777794, 0, 0, 26377}, + {33555014, 18874947, 16777800, 0, 0, 26433}, + {33555020, 18874953, 16777806, 0, 0, 26433}, + {33555026, 18874959, 16777812, 0, 0, 26433}, + {33555032, 18874965, 16777818, 0, 0, 26433}, + {33555038, 18874971, 16777824, 0, 0, 26433}, + {33555044, 18874977, 16777830, 0, 0, 26433}, + {33555050, 18874983, 16777836, 0, 0, 26433}, + {33555056, 18874989, 16777842, 0, 0, 26433}, + {33555062, 18874995, 16777848, 0, 0, 26377}, + {33555068, 18875001, 16777854, 0, 0, 26377}, + {33555074, 18875007, 16777860, 0, 0, 26377}, + {33555080, 18875013, 16777866, 0, 0, 26377}, + {33555086, 18875019, 16777872, 0, 0, 26377}, + {33555092, 18875025, 16777878, 0, 0, 26377}, + {33555098, 18875031, 16777884, 0, 0, 26377}, + {33555104, 18875037, 16777890, 0, 0, 26377}, + {33555110, 18875043, 16777896, 0, 0, 26433}, + {33555116, 18875049, 16777902, 0, 0, 26433}, + {33555122, 18875055, 16777908, 0, 0, 26433}, + {33555128, 18875061, 16777914, 0, 0, 26433}, + {33555134, 18875067, 16777920, 0, 0, 26433}, + {33555140, 18875073, 16777926, 0, 0, 26433}, + {33555146, 18875079, 16777932, 0, 0, 26433}, + {33555152, 18875085, 16777938, 0, 0, 26433}, + {33555158, 18875091, 33555160, 0, 0, 26377}, + {33555165, 18875098, 16777951, 0, 0, 26377}, + {33555171, 18875104, 33555173, 0, 0, 26377}, + {33555178, 18875111, 33555178, 0, 0, 26377}, + {50332400, 19923692, 50332403, 0, 0, 26377}, + {0, -74, 0, 0, 0, 10113}, + {33555193, 18875126, 16777979, 0, 0, 26433}, + {16777982, 17826556, 16777982, 0, 0, 26377}, + {33555202, 18875135, 33555204, 0, 0, 26377}, + {33555209, 18875142, 16777995, 0, 0, 26377}, + {33555215, 18875148, 33555217, 0, 0, 26377}, + {33555222, 18875155, 33555222, 0, 0, 26377}, + {50332444, 19923736, 50332447, 0, 0, 26377}, + {0, -86, 0, 0, 0, 10113}, + {33555237, 18875170, 16778023, 0, 0, 26433}, + {50332460, 19923752, 50332460, 0, 0, 26377}, + {50332467, 19923759, 50332467, 0, 0, 26377}, + {33555257, 18875190, 33555257, 0, 0, 26377}, + {50332479, 19923771, 50332479, 0, 0, 26377}, + {0, -100, 0, 0, 0, 10113}, + {50332486, 19923778, 50332486, 0, 0, 26377}, + {50332493, 19923785, 50332493, 0, 0, 26377}, + {33555283, 18875216, 33555283, 0, 0, 26377}, + {33555288, 18875221, 33555288, 0, 0, 26377}, + {50332510, 19923802, 50332510, 0, 0, 26377}, + {0, -112, 0, 0, 0, 10113}, + {33555300, 18875233, 33555302, 0, 0, 26377}, + {33555307, 18875240, 16778093, 0, 0, 26377}, + {33555313, 18875246, 33555315, 0, 0, 26377}, + {33555320, 18875253, 33555320, 0, 0, 26377}, + {50332542, 19923834, 50332545, 0, 0, 26377}, + {0, -128, 0, 0, 0, 10113}, + {0, -126, 0, 0, 0, 10113}, + {33555335, 18875268, 16778121, 0, 0, 26433}, + {0, 0, 0, 0, 0, 3076}, + {0, 0, 0, 0, 4, 3076}, + {0, 0, 0, 0, 5, 3076}, + {0, 0, 0, 0, 6, 3076}, + {0, 0, 0, 0, 7, 3076}, + {0, 0, 0, 0, 8, 3076}, + {0, 0, 0, 0, 9, 3076}, + {0, 0, 0, 0, 0, 1792}, + {0, -7517, 0, 0, 0, 10113}, + {0, -8383, 0, 0, 0, 10113}, + {0, -8262, 0, 0, 0, 10113}, + {0, 28, 0, 0, 0, 10113}, + {-28, 0, -28, 0, 0, 9993}, + {0, 16, 0, 0, 0, 12160}, + {-16, 0, -16, 0, 0, 12040}, + {0, 26, 0, 0, 0, 9344}, + {-26, 0, -26, 0, 0, 9224}, + {0, -10743, 0, 0, 0, 10113}, + {0, -3814, 0, 0, 0, 10113}, + {0, -10727, 0, 0, 0, 10113}, + {-10795, 0, -10795, 0, 0, 9993}, + {-10792, 0, -10792, 0, 0, 9993}, + {0, -10780, 0, 0, 0, 10113}, + {0, -10749, 0, 0, 0, 10113}, + {0, -10783, 0, 0, 0, 10113}, + {0, -10782, 0, 0, 0, 10113}, + {0, -10815, 0, 0, 0, 10113}, + {-7264, 0, -7264, 0, 0, 9993}, + {0, 0, 0, 0, 0, 5121}, + {0, 0, 0, 0, 0, 3841}, + {0, -35332, 0, 0, 0, 10113}, + {0, -42280, 0, 0, 0, 10113}, + {48, 0, 48, 0, 0, 9993}, + {0, -42308, 0, 0, 0, 10113}, + {0, -42319, 0, 0, 0, 10113}, + {0, -42315, 0, 0, 0, 10113}, + {0, -42305, 0, 0, 0, 10113}, + {0, -42258, 0, 0, 0, 10113}, + {0, -42282, 0, 0, 0, 10113}, + {0, -42261, 0, 0, 0, 10113}, + {0, 928, 0, 0, 0, 10113}, + {0, -48, 0, 0, 0, 10113}, + {0, -42307, 0, 0, 0, 10113}, + {0, -35384, 0, 0, 0, 10113}, + {-928, 0, -928, 0, 0, 9993}, + {16778124, 17826698, 16778124, 0, 0, 26377}, + {16778127, 17826701, 16778127, 0, 0, 26377}, + {16778130, 17826704, 16778130, 0, 0, 26377}, + {16778133, 17826707, 16778133, 0, 0, 26377}, + {16778136, 17826710, 16778136, 0, 0, 26377}, + {16778139, 17826713, 16778139, 0, 0, 26377}, + {16778142, 17826716, 16778142, 0, 0, 26377}, + {16778145, 17826719, 16778145, 0, 0, 26377}, + {16778148, 17826722, 16778148, 0, 0, 26377}, + {16778151, 17826725, 16778151, 0, 0, 26377}, + {16778154, 17826728, 16778154, 0, 0, 26377}, + {16778157, 17826731, 16778157, 0, 0, 26377}, + {16778160, 17826734, 16778160, 0, 0, 26377}, + {16778163, 17826737, 16778163, 0, 0, 26377}, + {16778166, 17826740, 16778166, 0, 0, 26377}, + {16778169, 17826743, 16778169, 0, 0, 26377}, + {16778172, 17826746, 16778172, 0, 0, 26377}, + {16778175, 17826749, 16778175, 0, 0, 26377}, + {16778178, 17826752, 16778178, 0, 0, 26377}, + {16778181, 17826755, 16778181, 0, 0, 26377}, + {16778184, 17826758, 16778184, 0, 0, 26377}, + {16778187, 17826761, 16778187, 0, 0, 26377}, + {16778190, 17826764, 16778190, 0, 0, 26377}, + {16778193, 17826767, 16778193, 0, 0, 26377}, + {16778196, 17826770, 16778196, 0, 0, 26377}, + {16778199, 17826773, 16778199, 0, 0, 26377}, + {16778202, 17826776, 16778202, 0, 0, 26377}, + {16778205, 17826779, 16778205, 0, 0, 26377}, + {16778208, 17826782, 16778208, 0, 0, 26377}, + {16778211, 17826785, 16778211, 0, 0, 26377}, + {16778214, 17826788, 16778214, 0, 0, 26377}, + {16778217, 17826791, 16778217, 0, 0, 26377}, + {16778220, 17826794, 16778220, 0, 0, 26377}, + {16778223, 17826797, 16778223, 0, 0, 26377}, + {16778226, 17826800, 16778226, 0, 0, 26377}, + {16778229, 17826803, 16778229, 0, 0, 26377}, + {16778232, 17826806, 16778232, 0, 0, 26377}, + {16778235, 17826809, 16778235, 0, 0, 26377}, + {16778238, 17826812, 16778238, 0, 0, 26377}, + {16778241, 17826815, 16778241, 0, 0, 26377}, + {16778244, 17826818, 16778244, 0, 0, 26377}, + {16778247, 17826821, 16778247, 0, 0, 26377}, + {16778250, 17826824, 16778250, 0, 0, 26377}, + {16778253, 17826827, 16778253, 0, 0, 26377}, + {16778256, 17826830, 16778256, 0, 0, 26377}, + {16778259, 17826833, 16778259, 0, 0, 26377}, + {16778262, 17826836, 16778262, 0, 0, 26377}, + {16778265, 17826839, 16778265, 0, 0, 26377}, + {16778268, 17826842, 16778268, 0, 0, 26377}, + {16778271, 17826845, 16778271, 0, 0, 26377}, + {16778274, 17826848, 16778274, 0, 0, 26377}, + {16778277, 17826851, 16778277, 0, 0, 26377}, + {16778280, 17826854, 16778280, 0, 0, 26377}, + {16778283, 17826857, 16778283, 0, 0, 26377}, + {16778286, 17826860, 16778286, 0, 0, 26377}, + {16778289, 17826863, 16778289, 0, 0, 26377}, + {16778292, 17826866, 16778292, 0, 0, 26377}, + {16778295, 17826869, 16778295, 0, 0, 26377}, + {16778298, 17826872, 16778298, 0, 0, 26377}, + {16778301, 17826875, 16778301, 0, 0, 26377}, + {16778304, 17826878, 16778304, 0, 0, 26377}, + {16778307, 17826881, 16778307, 0, 0, 26377}, + {16778310, 17826884, 16778310, 0, 0, 26377}, + {16778313, 17826887, 16778313, 0, 0, 26377}, + {16778316, 17826890, 16778316, 0, 0, 26377}, + {16778319, 17826893, 16778319, 0, 0, 26377}, + {16778322, 17826896, 16778322, 0, 0, 26377}, + {16778325, 17826899, 16778325, 0, 0, 26377}, + {16778328, 17826902, 16778328, 0, 0, 26377}, + {16778331, 17826905, 16778331, 0, 0, 26377}, + {16778334, 17826908, 16778334, 0, 0, 26377}, + {16778337, 17826911, 16778337, 0, 0, 26377}, + {16778340, 17826914, 16778340, 0, 0, 26377}, + {16778343, 17826917, 16778343, 0, 0, 26377}, + {16778346, 17826920, 16778346, 0, 0, 26377}, + {16778349, 17826923, 16778349, 0, 0, 26377}, + {16778352, 17826926, 16778352, 0, 0, 26377}, + {16778355, 17826929, 16778355, 0, 0, 26377}, + {16778358, 17826932, 16778358, 0, 0, 26377}, + {16778361, 17826935, 16778361, 0, 0, 26377}, + {33555581, 18875514, 33555583, 0, 0, 26377}, + {33555588, 18875521, 33555590, 0, 0, 26377}, + {33555595, 18875528, 33555597, 0, 0, 26377}, + {50332819, 19924111, 50332822, 0, 0, 26377}, + {50332829, 19924121, 50332832, 0, 0, 26377}, + {33555622, 18875555, 33555624, 0, 0, 26377}, + {33555629, 18875562, 33555631, 0, 0, 26377}, + {33555636, 18875569, 33555638, 0, 0, 26377}, + {33555643, 18875576, 33555645, 0, 0, 26377}, + {33555650, 18875583, 33555652, 0, 0, 26377}, + {33555657, 18875590, 33555659, 0, 0, 26377}, + {33555664, 18875597, 33555666, 0, 0, 26377}, + {0, 0, 0, 0, 0, 1025}, + {0, 0, 0, 0, 0, 5633}, + {0, 40, 0, 0, 0, 10113}, + {-40, 0, -40, 0, 0, 9993}, + {0, 34, 0, 0, 0, 10113}, + {-34, 0, -34, 0, 0, 9993}, + {0, 0, 0, 0, 0, 9344}, +}; + +/* extended case mappings */ + +const Py_UCS4 _PyUnicode_ExtendedCase[] = { + 181, + 956, + 924, + 223, + 115, + 115, + 83, + 83, + 83, + 115, + 105, + 775, + 304, + 329, + 700, + 110, + 700, + 78, + 383, + 115, + 83, + 496, + 106, + 780, + 74, + 780, + 837, + 953, + 921, + 912, + 953, + 776, + 769, + 921, + 776, + 769, + 944, + 965, + 776, + 769, + 933, + 776, + 769, + 962, + 963, + 931, + 976, + 946, + 914, + 977, + 952, + 920, + 981, + 966, + 934, + 982, + 960, + 928, + 1008, + 954, + 922, + 1009, + 961, + 929, + 1013, + 949, + 917, + 1415, + 1381, + 1410, + 1333, + 1362, + 1333, + 1410, + 43888, + 5024, + 5024, + 43889, + 5025, + 5025, + 43890, + 5026, + 5026, + 43891, + 5027, + 5027, + 43892, + 5028, + 5028, + 43893, + 5029, + 5029, + 43894, + 5030, + 5030, + 43895, + 5031, + 5031, + 43896, + 5032, + 5032, + 43897, + 5033, + 5033, + 43898, + 5034, + 5034, + 43899, + 5035, + 5035, + 43900, + 5036, + 5036, + 43901, + 5037, + 5037, + 43902, + 5038, + 5038, + 43903, + 5039, + 5039, + 43904, + 5040, + 5040, + 43905, + 5041, + 5041, + 43906, + 5042, + 5042, + 43907, + 5043, + 5043, + 43908, + 5044, + 5044, + 43909, + 5045, + 5045, + 43910, + 5046, + 5046, + 43911, + 5047, + 5047, + 43912, + 5048, + 5048, + 43913, + 5049, + 5049, + 43914, + 5050, + 5050, + 43915, + 5051, + 5051, + 43916, + 5052, + 5052, + 43917, + 5053, + 5053, + 43918, + 5054, + 5054, + 43919, + 5055, + 5055, + 43920, + 5056, + 5056, + 43921, + 5057, + 5057, + 43922, + 5058, + 5058, + 43923, + 5059, + 5059, + 43924, + 5060, + 5060, + 43925, + 5061, + 5061, + 43926, + 5062, + 5062, + 43927, + 5063, + 5063, + 43928, + 5064, + 5064, + 43929, + 5065, + 5065, + 43930, + 5066, + 5066, + 43931, + 5067, + 5067, + 43932, + 5068, + 5068, + 43933, + 5069, + 5069, + 43934, + 5070, + 5070, + 43935, + 5071, + 5071, + 43936, + 5072, + 5072, + 43937, + 5073, + 5073, + 43938, + 5074, + 5074, + 43939, + 5075, + 5075, + 43940, + 5076, + 5076, + 43941, + 5077, + 5077, + 43942, + 5078, + 5078, + 43943, + 5079, + 5079, + 43944, + 5080, + 5080, + 43945, + 5081, + 5081, + 43946, + 5082, + 5082, + 43947, + 5083, + 5083, + 43948, + 5084, + 5084, + 43949, + 5085, + 5085, + 43950, + 5086, + 5086, + 43951, + 5087, + 5087, + 43952, + 5088, + 5088, + 43953, + 5089, + 5089, + 43954, + 5090, + 5090, + 43955, + 5091, + 5091, + 43956, + 5092, + 5092, + 43957, + 5093, + 5093, + 43958, + 5094, + 5094, + 43959, + 5095, + 5095, + 43960, + 5096, + 5096, + 43961, + 5097, + 5097, + 43962, + 5098, + 5098, + 43963, + 5099, + 5099, + 43964, + 5100, + 5100, + 43965, + 5101, + 5101, + 43966, + 5102, + 5102, + 43967, + 5103, + 5103, + 5112, + 5104, + 5104, + 5113, + 5105, + 5105, + 5114, + 5106, + 5106, + 5115, + 5107, + 5107, + 5116, + 5108, + 5108, + 5117, + 5109, + 5109, + 5112, + 5104, + 5104, + 5113, + 5105, + 5105, + 5114, + 5106, + 5106, + 5115, + 5107, + 5107, + 5116, + 5108, + 5108, + 5117, + 5109, + 5109, + 7296, + 1074, + 1042, + 7297, + 1076, + 1044, + 7298, + 1086, + 1054, + 7299, + 1089, + 1057, + 7300, + 1090, + 1058, + 7301, + 1090, + 1058, + 7302, + 1098, + 1066, + 7303, + 1123, + 1122, + 7304, + 42571, + 42570, + 7830, + 104, + 817, + 72, + 817, + 7831, + 116, + 776, + 84, + 776, + 7832, + 119, + 778, + 87, + 778, + 7833, + 121, + 778, + 89, + 778, + 7834, + 97, + 702, + 65, + 702, + 7835, + 7777, + 7776, + 223, + 115, + 115, + 7838, + 8016, + 965, + 787, + 933, + 787, + 8018, + 965, + 787, + 768, + 933, + 787, + 768, + 8020, + 965, + 787, + 769, + 933, + 787, + 769, + 8022, + 965, + 787, + 834, + 933, + 787, + 834, + 8064, + 7936, + 953, + 7944, + 921, + 8072, + 8065, + 7937, + 953, + 7945, + 921, + 8073, + 8066, + 7938, + 953, + 7946, + 921, + 8074, + 8067, + 7939, + 953, + 7947, + 921, + 8075, + 8068, + 7940, + 953, + 7948, + 921, + 8076, + 8069, + 7941, + 953, + 7949, + 921, + 8077, + 8070, + 7942, + 953, + 7950, + 921, + 8078, + 8071, + 7943, + 953, + 7951, + 921, + 8079, + 8064, + 7936, + 953, + 7944, + 921, + 8072, + 8065, + 7937, + 953, + 7945, + 921, + 8073, + 8066, + 7938, + 953, + 7946, + 921, + 8074, + 8067, + 7939, + 953, + 7947, + 921, + 8075, + 8068, + 7940, + 953, + 7948, + 921, + 8076, + 8069, + 7941, + 953, + 7949, + 921, + 8077, + 8070, + 7942, + 953, + 7950, + 921, + 8078, + 8071, + 7943, + 953, + 7951, + 921, + 8079, + 8080, + 7968, + 953, + 7976, + 921, + 8088, + 8081, + 7969, + 953, + 7977, + 921, + 8089, + 8082, + 7970, + 953, + 7978, + 921, + 8090, + 8083, + 7971, + 953, + 7979, + 921, + 8091, + 8084, + 7972, + 953, + 7980, + 921, + 8092, + 8085, + 7973, + 953, + 7981, + 921, + 8093, + 8086, + 7974, + 953, + 7982, + 921, + 8094, + 8087, + 7975, + 953, + 7983, + 921, + 8095, + 8080, + 7968, + 953, + 7976, + 921, + 8088, + 8081, + 7969, + 953, + 7977, + 921, + 8089, + 8082, + 7970, + 953, + 7978, + 921, + 8090, + 8083, + 7971, + 953, + 7979, + 921, + 8091, + 8084, + 7972, + 953, + 7980, + 921, + 8092, + 8085, + 7973, + 953, + 7981, + 921, + 8093, + 8086, + 7974, + 953, + 7982, + 921, + 8094, + 8087, + 7975, + 953, + 7983, + 921, + 8095, + 8096, + 8032, + 953, + 8040, + 921, + 8104, + 8097, + 8033, + 953, + 8041, + 921, + 8105, + 8098, + 8034, + 953, + 8042, + 921, + 8106, + 8099, + 8035, + 953, + 8043, + 921, + 8107, + 8100, + 8036, + 953, + 8044, + 921, + 8108, + 8101, + 8037, + 953, + 8045, + 921, + 8109, + 8102, + 8038, + 953, + 8046, + 921, + 8110, + 8103, + 8039, + 953, + 8047, + 921, + 8111, + 8096, + 8032, + 953, + 8040, + 921, + 8104, + 8097, + 8033, + 953, + 8041, + 921, + 8105, + 8098, + 8034, + 953, + 8042, + 921, + 8106, + 8099, + 8035, + 953, + 8043, + 921, + 8107, + 8100, + 8036, + 953, + 8044, + 921, + 8108, + 8101, + 8037, + 953, + 8045, + 921, + 8109, + 8102, + 8038, + 953, + 8046, + 921, + 8110, + 8103, + 8039, + 953, + 8047, + 921, + 8111, + 8114, + 8048, + 953, + 8122, + 921, + 8122, + 837, + 8115, + 945, + 953, + 913, + 921, + 8124, + 8116, + 940, + 953, + 902, + 921, + 902, + 837, + 8118, + 945, + 834, + 913, + 834, + 8119, + 945, + 834, + 953, + 913, + 834, + 921, + 913, + 834, + 837, + 8115, + 945, + 953, + 913, + 921, + 8124, + 8126, + 953, + 921, + 8130, + 8052, + 953, + 8138, + 921, + 8138, + 837, + 8131, + 951, + 953, + 919, + 921, + 8140, + 8132, + 942, + 953, + 905, + 921, + 905, + 837, + 8134, + 951, + 834, + 919, + 834, + 8135, + 951, + 834, + 953, + 919, + 834, + 921, + 919, + 834, + 837, + 8131, + 951, + 953, + 919, + 921, + 8140, + 8146, + 953, + 776, + 768, + 921, + 776, + 768, + 8147, + 953, + 776, + 769, + 921, + 776, + 769, + 8150, + 953, + 834, + 921, + 834, + 8151, + 953, + 776, + 834, + 921, + 776, + 834, + 8162, + 965, + 776, + 768, + 933, + 776, + 768, + 8163, + 965, + 776, + 769, + 933, + 776, + 769, + 8164, + 961, + 787, + 929, + 787, + 8166, + 965, + 834, + 933, + 834, + 8167, + 965, + 776, + 834, + 933, + 776, + 834, + 8178, + 8060, + 953, + 8186, + 921, + 8186, + 837, + 8179, + 969, + 953, + 937, + 921, + 8188, + 8180, + 974, + 953, + 911, + 921, + 911, + 837, + 8182, + 969, + 834, + 937, + 834, + 8183, + 969, + 834, + 953, + 937, + 834, + 921, + 937, + 834, + 837, + 8179, + 969, + 953, + 937, + 921, + 8188, + 43888, + 5024, + 5024, + 43889, + 5025, + 5025, + 43890, + 5026, + 5026, + 43891, + 5027, + 5027, + 43892, + 5028, + 5028, + 43893, + 5029, + 5029, + 43894, + 5030, + 5030, + 43895, + 5031, + 5031, + 43896, + 5032, + 5032, + 43897, + 5033, + 5033, + 43898, + 5034, + 5034, + 43899, + 5035, + 5035, + 43900, + 5036, + 5036, + 43901, + 5037, + 5037, + 43902, + 5038, + 5038, + 43903, + 5039, + 5039, + 43904, + 5040, + 5040, + 43905, + 5041, + 5041, + 43906, + 5042, + 5042, + 43907, + 5043, + 5043, + 43908, + 5044, + 5044, + 43909, + 5045, + 5045, + 43910, + 5046, + 5046, + 43911, + 5047, + 5047, + 43912, + 5048, + 5048, + 43913, + 5049, + 5049, + 43914, + 5050, + 5050, + 43915, + 5051, + 5051, + 43916, + 5052, + 5052, + 43917, + 5053, + 5053, + 43918, + 5054, + 5054, + 43919, + 5055, + 5055, + 43920, + 5056, + 5056, + 43921, + 5057, + 5057, + 43922, + 5058, + 5058, + 43923, + 5059, + 5059, + 43924, + 5060, + 5060, + 43925, + 5061, + 5061, + 43926, + 5062, + 5062, + 43927, + 5063, + 5063, + 43928, + 5064, + 5064, + 43929, + 5065, + 5065, + 43930, + 5066, + 5066, + 43931, + 5067, + 5067, + 43932, + 5068, + 5068, + 43933, + 5069, + 5069, + 43934, + 5070, + 5070, + 43935, + 5071, + 5071, + 43936, + 5072, + 5072, + 43937, + 5073, + 5073, + 43938, + 5074, + 5074, + 43939, + 5075, + 5075, + 43940, + 5076, + 5076, + 43941, + 5077, + 5077, + 43942, + 5078, + 5078, + 43943, + 5079, + 5079, + 43944, + 5080, + 5080, + 43945, + 5081, + 5081, + 43946, + 5082, + 5082, + 43947, + 5083, + 5083, + 43948, + 5084, + 5084, + 43949, + 5085, + 5085, + 43950, + 5086, + 5086, + 43951, + 5087, + 5087, + 43952, + 5088, + 5088, + 43953, + 5089, + 5089, + 43954, + 5090, + 5090, + 43955, + 5091, + 5091, + 43956, + 5092, + 5092, + 43957, + 5093, + 5093, + 43958, + 5094, + 5094, + 43959, + 5095, + 5095, + 43960, + 5096, + 5096, + 43961, + 5097, + 5097, + 43962, + 5098, + 5098, + 43963, + 5099, + 5099, + 43964, + 5100, + 5100, + 43965, + 5101, + 5101, + 43966, + 5102, + 5102, + 43967, + 5103, + 5103, + 64256, + 102, + 102, + 70, + 70, + 70, + 102, + 64257, + 102, + 105, + 70, + 73, + 70, + 105, + 64258, + 102, + 108, + 70, + 76, + 70, + 108, + 64259, + 102, + 102, + 105, + 70, + 70, + 73, + 70, + 102, + 105, + 64260, + 102, + 102, + 108, + 70, + 70, + 76, + 70, + 102, + 108, + 64261, + 115, + 116, + 83, + 84, + 83, + 116, + 64262, + 115, + 116, + 83, + 84, + 83, + 116, + 64275, + 1396, + 1398, + 1348, + 1350, + 1348, + 1398, + 64276, + 1396, + 1381, + 1348, + 1333, + 1348, + 1381, + 64277, + 1396, + 1387, + 1348, + 1339, + 1348, + 1387, + 64278, + 1406, + 1398, + 1358, + 1350, + 1358, + 1398, + 64279, + 1396, + 1389, + 1348, + 1341, + 1348, + 1389, +}; + +/* type indexes */ +#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, 34, 35, 36, 37, + 38, 39, 34, 34, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 65, 66, 64, + 64, 64, 64, 67, 68, 64, 64, 64, 64, 64, 64, 69, 70, 71, 72, 73, 74, 75, + 76, 64, 77, 78, 79, 80, 81, 82, 83, 64, 64, 84, 85, 34, 34, 34, 34, 34, + 34, 86, 34, 34, 34, 34, 34, 87, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 88, 89, 90, 91, 34, 34, 34, 92, 34, 34, + 34, 93, 94, 34, 34, 34, 34, 34, 95, 34, 34, 34, 96, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 97, 98, 99, 34, 34, 34, 34, 34, 34, 100, 101, 34, 34, + 34, 34, 34, 34, 34, 34, 102, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 34, 34, 104, 34, 34, 34, 34, + 100, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 105, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 106, 107, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 108, 109, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 110, 111, 34, 34, 34, 34, 34, + 34, 34, 34, 112, 34, 34, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 125, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 128, 129, + 130, 131, 132, 133, 34, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 144, 34, 34, 151, 144, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 144, 163, 144, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 144, 173, 174, 144, 175, 176, 177, 178, + 144, 179, 180, 144, 181, 182, 183, 144, 144, 184, 185, 186, 187, 144, + 188, 144, 189, 34, 34, 34, 34, 34, 34, 34, 190, 191, 34, 192, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 34, 34, 34, 34, 34, 34, 34, 34, 193, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 34, 34, 34, 34, 194, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 34, 34, 34, 34, 195, 196, 197, 198, 144, 144, 144, 144, 199, + 200, 201, 202, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 203, 34, 34, + 34, 34, 34, 204, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 34, 34, 205, 34, 34, 206, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 207, 208, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 64, + 209, 210, 211, 212, 213, 214, 144, 215, 216, 217, 218, 219, 220, 221, + 222, 64, 64, 64, 64, 223, 224, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 225, 144, 226, 144, 144, 227, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 34, 228, 229, 144, 144, 144, 144, 144, 230, 231, 232, + 144, 233, 234, 144, 144, 235, 236, 237, 238, 239, 144, 64, 240, 64, 64, + 64, 64, 64, 241, 242, 243, 244, 245, 246, 247, 248, 249, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 250, 251, 252, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 86, 253, 34, 254, 255, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 256, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 257, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 258, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 259, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 260, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 261, 34, + 262, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 263, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 264, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 34, 256, 34, 34, 265, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 266, 144, + 267, 268, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 269, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 269, +}; + +static const unsigned short index2[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 2, 4, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 6, 5, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 5, + 5, 5, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 6, 5, 20, 5, 5, + 21, 5, 6, 5, 5, 22, 23, 6, 24, 5, 25, 6, 26, 20, 5, 27, 27, 27, 5, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 28, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 5, 19, 19, 19, 19, 19, 19, 19, 29, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 32, 33, 30, 31, 30, 31, 30, 31, 20, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 34, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 35, 30, 31, 30, 31, 30, 31, 36, 37, 38, 30, 31, 30, 31, 39, + 30, 31, 40, 40, 30, 31, 20, 41, 42, 43, 30, 31, 40, 44, 45, 46, 47, 30, + 31, 48, 20, 46, 49, 50, 51, 30, 31, 30, 31, 30, 31, 52, 30, 31, 52, 20, + 20, 30, 31, 52, 30, 31, 53, 53, 30, 31, 30, 31, 54, 30, 31, 20, 55, 30, + 31, 20, 56, 55, 55, 55, 55, 57, 58, 59, 57, 58, 59, 57, 58, 59, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 60, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 61, 57, 58, + 59, 30, 31, 62, 63, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 64, 20, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 20, 20, 20, 20, 20, 65, + 30, 31, 66, 67, 68, 68, 30, 31, 69, 70, 71, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 72, 73, 74, 75, 76, 20, 77, 77, 20, 78, 20, 79, 80, 20, 20, + 20, 77, 81, 20, 82, 20, 83, 84, 20, 85, 86, 84, 87, 88, 20, 20, 86, 20, + 89, 90, 20, 20, 91, 20, 20, 20, 20, 20, 20, 20, 92, 20, 20, 93, 20, 94, + 93, 20, 20, 20, 95, 93, 96, 97, 97, 98, 20, 20, 20, 20, 20, 99, 20, 55, + 20, 20, 20, 20, 20, 20, 20, 20, 100, 101, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 103, 103, 103, 103, 103, 103, 103, 102, 102, 6, 6, 6, 6, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 102, 102, 102, 102, 102, 6, 6, 6, 6, 6, 6, 6, + 103, 6, 103, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 104, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 30, 31, 30, 31, 103, 6, 30, 31, 0, 0, 105, 50, 50, 50, 5, 106, 0, + 0, 0, 0, 6, 6, 107, 25, 108, 108, 108, 0, 109, 0, 110, 110, 111, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 112, 113, 113, 113, 114, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 115, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 116, 117, 117, 118, 119, 120, 121, 121, 121, 122, 123, + 124, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 125, 126, 127, 128, 129, 130, 5, 30, 31, 131, + 30, 31, 20, 64, 64, 64, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 133, + 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 5, + 25, 25, 25, 25, 25, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 134, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 135, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 0, 0, 103, 5, 5, 5, 5, 5, 5, 20, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 138, 20, 5, 5, 0, 0, 5, 5, 5, 0, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 5, 25, 5, 25, 25, 5, 25, 25, 5, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, + 55, 55, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, + 21, 0, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 5, 5, 5, 5, 55, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, 25, 25, 25, + 103, 103, 25, 25, 5, 25, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 55, 55, 55, 5, 5, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 21, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 103, 103, 5, 5, 5, 5, 103, 0, 0, 25, + 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 25, 25, 25, 25, 103, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 103, 25, 25, 25, 103, 25, 25, 25, 25, 25, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 0, 0, + 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 25, 18, 25, 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 18, + 18, 18, 18, 25, 18, 18, 55, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 25, 25, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 5, 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 0, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, + 55, 0, 0, 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 0, 0, 18, 18, + 25, 55, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 55, 55, 0, 55, 55, 55, + 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 5, 5, 27, 27, + 27, 27, 27, 27, 5, 5, 55, 5, 25, 0, 0, 25, 25, 18, 0, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, + 55, 0, 55, 55, 0, 55, 55, 0, 55, 55, 0, 0, 25, 0, 18, 18, 18, 25, 25, 0, + 0, 0, 0, 25, 25, 0, 0, 25, 25, 25, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 55, + 55, 55, 55, 0, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 25, 25, 55, 55, 55, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, + 25, 55, 18, 18, 18, 25, 25, 25, 25, 25, 0, 25, 25, 18, 0, 18, 18, 25, 0, + 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 25, 25, 0, 0, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 25, + 25, 25, 25, 25, 25, 0, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, + 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, + 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, 25, 25, 25, 25, 0, 0, + 18, 18, 0, 0, 18, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 25, 18, 0, 0, 0, 0, 55, + 55, 0, 55, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, + 55, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, 0, 55, + 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 0, 55, + 55, 0, 55, 0, 55, 55, 0, 0, 0, 55, 55, 0, 0, 0, 55, 55, 55, 0, 0, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 18, 18, 25, 18, + 18, 0, 0, 0, 18, 18, 18, 0, 18, 18, 18, 25, 0, 0, 55, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 25, 18, + 18, 18, 25, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 55, 25, 25, 25, 18, 18, 18, 18, 0, 25, 25, 25, 0, 25, 25, + 25, 25, 0, 0, 0, 0, 0, 0, 0, 25, 25, 0, 55, 55, 55, 0, 0, 0, 0, 0, 55, + 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, + 0, 5, 27, 27, 27, 27, 27, 27, 27, 5, 55, 25, 18, 18, 5, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, + 18, 18, 18, 18, 0, 25, 18, 18, 0, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, + 18, 18, 0, 0, 0, 0, 0, 0, 0, 55, 0, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 25, 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 18, 18, 18, 0, + 18, 18, 18, 25, 55, 5, 0, 0, 0, 0, 55, 55, 55, 18, 27, 27, 27, 27, 27, + 27, 27, 55, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 55, 55, 55, 55, 55, 55, 0, 0, 18, + 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 0, 0, 0, 0, + 18, 18, 18, 25, 25, 25, 0, 25, 0, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 18, 18, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 25, 55, 139, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, + 55, 55, 55, 103, 25, 25, 25, 25, 25, 25, 25, 25, 5, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 0, + 55, 0, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 55, 139, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 55, 0, 0, 55, 55, 55, 55, 55, 0, 103, 0, 25, 25, 25, 25, 25, 25, 0, + 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 55, 55, 55, 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, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 25, 25, 5, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 25, 5, 25, 5, 25, 5, 5, 5, + 5, 18, 18, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 5, 25, + 25, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 18, 25, + 25, 18, 18, 25, 25, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, + 5, 5, 55, 55, 55, 55, 55, 55, 18, 18, 25, 25, 55, 55, 55, 55, 25, 25, 25, + 55, 18, 18, 18, 55, 55, 18, 18, 18, 18, 18, 18, 18, 55, 55, 55, 25, 25, + 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, + 25, 25, 18, 18, 18, 18, 18, 18, 25, 55, 18, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 18, 18, 18, 25, 5, 5, 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, 140, 0, 0, 0, 0, 0, 140, 0, 0, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 5, 103, 141, 141, 141, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, + 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, + 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 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, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 0, 0, 237, 238, 239, 240, + 241, 242, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 2, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 5, 5, 5, 243, 243, 243, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 55, 55, 55, 55, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, + 25, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, + 0, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 25, 25, 25, 25, 25, + 25, 25, 18, 18, 18, 18, 18, 18, 18, 18, 25, 18, 18, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 5, 5, 5, 103, 5, 5, 5, 5, 55, 25, 0, 0, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, + 25, 21, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 0, 0, 0, 55, 55, 55, 55, 55, 244, 244, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 25, 25, 25, + 18, 18, 18, 18, 25, 25, 18, 18, 18, 0, 0, 0, 0, 18, 18, 25, 18, 18, 18, + 18, 18, 18, 25, 25, 25, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 142, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 18, 25, 0, 0, 5, 5, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 18, 25, + 25, 25, 25, 25, 25, 25, 0, 25, 18, 25, 18, 18, 25, 25, 25, 25, 25, 25, + 25, 25, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 0, 0, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 103, + 5, 5, 5, 5, 5, 5, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, + 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 25, 25, + 25, 25, 18, 25, 18, 18, 18, 18, 18, 25, 18, 18, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, 25, 25, 25, 55, + 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 25, 18, 25, 25, 18, 18, 18, 25, 18, 25, 25, 25, 18, 18, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, + 25, 25, 18, 18, 25, 25, 0, 0, 0, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 0, 0, 0, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 103, 103, 103, 103, 103, + 5, 5, 245, 246, 247, 248, 249, 250, 251, 252, 253, 0, 0, 0, 0, 0, 0, 0, + 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 254, 0, 0, 254, 254, 254, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 25, 25, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, + 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 25, 55, 55, 55, 55, 55, 55, + 25, 55, 55, 18, 25, 25, 55, 0, 0, 0, 0, 0, 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, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 102, 255, 20, 20, 20, 256, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 257, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 0, 25, 25, 25, 25, 25, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 258, 259, 260, 261, + 262, 263, 20, 20, 264, 20, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 265, 265, 265, 265, + 265, 265, 265, 265, 266, 266, 266, 266, 266, 266, 266, 266, 265, 265, + 265, 265, 265, 265, 0, 0, 266, 266, 266, 266, 266, 266, 0, 0, 265, 265, + 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, 266, 266, 266, + 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, 266, + 266, 266, 265, 265, 265, 265, 265, 265, 0, 0, 266, 266, 266, 266, 266, + 266, 0, 0, 267, 265, 268, 265, 269, 265, 270, 265, 0, 266, 0, 266, 0, + 266, 0, 266, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, + 266, 266, 266, 266, 271, 271, 272, 272, 272, 272, 273, 273, 274, 274, + 275, 275, 276, 276, 0, 0, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 265, 265, 325, + 326, 327, 0, 328, 329, 266, 266, 330, 330, 331, 6, 332, 6, 6, 6, 333, + 334, 335, 0, 336, 337, 338, 338, 338, 338, 339, 6, 6, 6, 265, 265, 340, + 341, 0, 0, 342, 343, 266, 266, 344, 344, 0, 6, 6, 6, 265, 265, 345, 346, + 347, 127, 348, 349, 266, 266, 350, 350, 131, 6, 6, 6, 0, 0, 351, 352, + 353, 0, 354, 355, 356, 356, 357, 357, 358, 6, 6, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 21, 21, 21, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 3, 3, 21, 21, 21, 21, 21, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 21, 21, 21, 21, + 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 359, 102, 0, 0, 360, 361, + 362, 363, 364, 365, 5, 5, 5, 5, 5, 102, 359, 26, 22, 23, 360, 361, 362, + 363, 364, 365, 5, 5, 5, 5, 5, 0, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 6, 6, 6, 6, 25, 6, 6, 6, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 121, 5, 5, + 5, 5, 121, 5, 5, 20, 121, 121, 121, 20, 20, 121, 121, 121, 20, 5, 121, 5, + 5, 366, 121, 121, 121, 121, 121, 5, 5, 5, 5, 5, 5, 121, 5, 367, 5, 121, + 5, 368, 369, 121, 121, 366, 20, 121, 121, 370, 121, 20, 55, 55, 55, 55, + 20, 5, 5, 20, 20, 121, 121, 5, 5, 5, 5, 5, 121, 20, 20, 20, 20, 5, 5, 5, + 5, 371, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 243, 243, 243, 30, 31, 243, 243, 243, 243, 27, 5, 5, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, 363, 364, + 365, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 359, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 359, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 22, 23, 360, 361, + 362, 363, 364, 365, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 26, + 22, 23, 360, 361, 362, 363, 364, 365, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 0, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 0, 30, 31, 376, 377, 378, 379, 380, 30, 31, + 30, 31, 30, 31, 381, 382, 383, 384, 20, 30, 31, 20, 30, 31, 20, 20, 20, + 20, 20, 102, 102, 385, 385, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, + 5, 5, 5, 5, 5, 5, 30, 31, 30, 31, 25, 25, 25, 30, 31, 0, 0, 0, 0, 0, 5, + 5, 5, 5, 27, 5, 5, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 0, 386, + 0, 0, 0, 0, 0, 386, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 103, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, + 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 0, 55, 55, 55, 55, 55, 55, 55, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 387, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 103, 55, 243, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 25, 25, 25, 25, 18, 18, 5, 103, 103, 103, 103, 103, + 5, 5, 243, 243, 243, 103, 55, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 6, 6, 103, 103, 55, 5, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 103, 103, + 103, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 5, 5, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, + 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 388, 55, 55, 388, 55, 55, 55, 388, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 388, 55, 55, 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, + 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, + 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 388, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 388, 388, 388, 55, 55, 55, 55, + 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 388, 388, 388, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, + 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 388, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 388, 388, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 388, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 388, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 103, 103, 103, 103, 103, + 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 5, 5, 5, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 55, 25, 6, 6, 6, + 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 103, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 102, 102, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 25, 25, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 20, 20, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 102, 20, 20, 20, + 20, 20, 20, 20, 20, 30, 31, 30, 31, 389, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 103, 6, 6, 30, 31, 390, 20, 55, 30, 31, 30, 31, 391, 20, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 392, 393, 394, 395, 392, 20, 396, 397, 398, 399, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 0, 0, 30, 31, 400, 401, 402, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 102, 102, 20, 55, + 55, 55, 55, 55, 55, 55, 25, 55, 55, 55, 25, 55, 55, 55, 55, 25, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 18, 18, 25, 25, 18, 5, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, + 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 55, + 55, 55, 55, 55, 55, 5, 5, 5, 55, 5, 55, 55, 25, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, + 25, 25, 25, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 25, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, 18, + 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 103, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, 55, 55, 25, 103, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 18, 25, + 25, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 25, 55, 55, + 55, 55, 55, 55, 55, 55, 25, 18, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 18, 25, 18, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 25, 25, 25, 55, + 55, 25, 25, 55, 55, 55, 55, 55, 25, 25, 55, 25, 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, 55, 55, 103, 5, 5, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, 5, 55, + 103, 103, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 0, 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, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 403, 20, 20, 20, 20, 20, 20, 20, 6, 102, 102, 102, 102, 20, 20, 20, 20, + 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 18, 18, 25, 18, 18, 25, 18, 18, 5, 18, 25, 0, 0, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, + 55, 55, 388, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 484, 485, 486, 487, 488, 489, + 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, 492, 493, 494, 495, 0, 0, + 0, 0, 0, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, + 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 496, 496, 496, 496, 496, 496, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 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, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 496, 496, 5, 5, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, + 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 18, 18, 18, 5, 5, 6, 0, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, 0, 496, 55, 496, 55, 496, 0, + 496, 55, 496, 55, 496, 55, 496, 55, 496, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 21, 0, 5, 5, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 5, 5, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, + 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 497, 497, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, + 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, + 55, 55, 55, 0, 0, 0, 5, 5, 5, 6, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 5, 5, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, + 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 27, 27, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 243, 55, 55, 55, + 55, 55, 55, 55, 55, 243, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 0, 0, + 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 5, 243, 243, 243, 243, 243, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 0, + 0, 0, 0, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 0, 0, 0, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 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, 55, 55, + 55, 55, 55, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, + 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 27, 27, 27, 27, 27, 27, 27, 27, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 5, 5, 27, 27, 27, 27, 27, 27, 27, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 27, 27, 55, 55, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 55, + 25, 25, 25, 0, 25, 25, 0, 0, 0, 0, 0, 25, 25, 25, 25, 55, 55, 55, 55, 0, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, + 25, 0, 0, 0, 0, 25, 26, 22, 23, 360, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 27, 27, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 27, 27, + 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 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, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, + 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 27, 27, 27, 27, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 25, + 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 5, 5, + 21, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 0, 0, 0, 0, 0, 0, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, + 25, 25, 25, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 55, 18, + 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 55, 55, 55, 55, 5, 5, 5, 5, 25, + 25, 25, 25, 5, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 5, 55, 5, + 5, 5, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 18, 18, 18, 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 5, 5, 5, + 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 55, 55, 55, 55, + 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 0, + 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, + 18, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 25, 25, 18, 18, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, + 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 0, 25, 25, 55, 18, 18, 25, 18, + 18, 18, 18, 0, 0, 18, 18, 0, 0, 18, 18, 18, 0, 0, 55, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 18, 18, 0, 0, 25, 25, 25, 25, 25, + 25, 25, 0, 0, 0, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, + 18, 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 25, 25, 25, 18, 25, 55, 55, + 55, 55, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 5, 0, 5, + 25, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 25, 25, + 18, 25, 25, 55, 55, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 18, + 18, 25, 25, 18, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, + 25, 25, 25, 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 55, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 18, + 18, 25, 25, 25, 25, 25, 25, 18, 25, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 25, 25, 25, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 0, + 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 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, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 25, 25, 18, 18, 18, 18, 25, + 55, 5, 55, 18, 0, 0, 0, 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, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 55, 25, 25, 25, 25, 5, 5, 5, 5, + 5, 5, 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 25, 25, 25, 18, + 18, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 5, 5, 55, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, + 25, 25, 18, 25, 55, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 5, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 18, 25, 25, 25, 25, 25, + 25, 25, 18, 25, 25, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 55, 55, 55, 55, 55, 55, 0, 55, 55, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 25, 25, 25, 25, 25, 25, 0, 0, 0, 25, 0, 25, 25, 0, 25, 25, + 25, 25, 25, 25, 25, 55, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, + 18, 0, 25, 25, 0, 18, 18, 25, 18, 25, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 25, 25, 18, 18, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 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, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, + 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 103, + 103, 103, 103, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 0, 27, 27, 27, 27, 27, 27, 27, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 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, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 55, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 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, 103, 103, 5, 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, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 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, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 5, + 25, 25, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 25, 25, 25, + 5, 5, 5, 18, 18, 18, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, 21, 25, 25, + 25, 25, 25, 25, 25, 25, 5, 5, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 0, 0, 0, 0, 0, 0, 0, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 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, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 0, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 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, 121, 0, 121, 121, 0, 0, 121, 0, 0, 121, 121, 0, 0, 121, 121, 121, + 121, 0, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 0, 20, 0, + 20, 20, 20, 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 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, 121, 121, 0, 121, 121, 121, 121, 0, 0, 121, 121, 121, + 121, 121, 121, 121, 121, 0, 121, 121, 121, 121, 121, 121, 121, 0, 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, 121, 121, 0, 121, 121, 121, 121, 0, 121, 121, + 121, 121, 121, 0, 121, 0, 0, 0, 121, 121, 121, 121, 121, 121, 121, 0, 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, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 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, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 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, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 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, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 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, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 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, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 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, 20, 20, 0, 0, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, + 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, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 5, 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, + 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 5, 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, 5, 20, 20, 20, 20, 20, 20, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, 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, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 5, 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, 5, 20, 20, 20, 20, + 20, 20, 121, 20, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, + 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, + 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, + 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 25, 25, + 0, 25, 25, 0, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, + 103, 103, 103, 103, 103, 103, 103, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 0, 0, 0, 0, 55, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 25, + 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 25, 25, 25, 25, 25, 25, 25, + 103, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 5, 27, 27, 27, 27, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, + 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, + 55, 0, 55, 0, 55, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 55, 0, 55, 0, 55, 0, + 55, 55, 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 0, 55, 0, 55, 0, 55, 0, + 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, + 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 359, 359, 26, 22, 23, 360, 361, 362, 363, 364, + 365, 27, 27, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 5, 5, 5, 5, 5, 5, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 5, 5, 5, 0, 0, 0, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, + 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 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, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 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, 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, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, +}; + +/* Returns the numeric value as double for Unicode characters + * having this property, -1.0 otherwise. + */ +double _PyUnicode_ToNumeric(Py_UCS4 ch) +{ + switch (ch) { + case 0x0F33: + return (double) -1.0/2.0; + case 0x0030: + case 0x0660: + case 0x06F0: + case 0x07C0: + case 0x0966: + case 0x09E6: + case 0x0A66: + case 0x0AE6: + case 0x0B66: + case 0x0BE6: + case 0x0C66: + case 0x0C78: + case 0x0CE6: + case 0x0D66: + case 0x0DE6: + case 0x0E50: + case 0x0ED0: + case 0x0F20: + case 0x1040: + case 0x1090: + case 0x17E0: + case 0x17F0: + case 0x1810: + case 0x1946: + case 0x19D0: + case 0x1A80: + case 0x1A90: + case 0x1B50: + case 0x1BB0: + case 0x1C40: + case 0x1C50: + case 0x2070: + case 0x2080: + case 0x2189: + case 0x24EA: + case 0x24FF: + case 0x3007: + case 0x96F6: + case 0xA620: + case 0xA6EF: + case 0xA8D0: + case 0xA900: + case 0xA9D0: + case 0xA9F0: + case 0xAA50: + case 0xABF0: + case 0xF9B2: + case 0xFF10: + case 0x1018A: + case 0x104A0: + case 0x10D30: + case 0x11066: + case 0x110F0: + case 0x11136: + case 0x111D0: + case 0x112F0: + case 0x11450: + case 0x114D0: + case 0x11650: + case 0x116C0: + case 0x11730: + case 0x118E0: + case 0x11C50: + case 0x11D50: + case 0x11DA0: + case 0x16A60: + case 0x16B50: + case 0x16E80: + case 0x1D2E0: + case 0x1D7CE: + case 0x1D7D8: + case 0x1D7E2: + case 0x1D7EC: + case 0x1D7F6: + case 0x1E140: + case 0x1E2F0: + case 0x1E950: + case 0x1F100: + case 0x1F101: + case 0x1F10B: + case 0x1F10C: + return (double) 0.0; + case 0x0031: + case 0x00B9: + case 0x0661: + case 0x06F1: + case 0x07C1: + case 0x0967: + case 0x09E7: + case 0x0A67: + case 0x0AE7: + case 0x0B67: + case 0x0BE7: + case 0x0C67: + case 0x0C79: + case 0x0C7C: + case 0x0CE7: + case 0x0D67: + case 0x0DE7: + case 0x0E51: + case 0x0ED1: + case 0x0F21: + case 0x1041: + case 0x1091: + case 0x1369: + case 0x17E1: + case 0x17F1: + case 0x1811: + case 0x1947: + case 0x19D1: + case 0x19DA: + case 0x1A81: + case 0x1A91: + case 0x1B51: + case 0x1BB1: + case 0x1C41: + case 0x1C51: + case 0x2081: + case 0x215F: + case 0x2160: + case 0x2170: + case 0x2460: + case 0x2474: + case 0x2488: + case 0x24F5: + case 0x2776: + case 0x2780: + case 0x278A: + case 0x3021: + case 0x3192: + case 0x3220: + case 0x3280: + case 0x4E00: + case 0x58F1: + case 0x58F9: + case 0x5E7A: + case 0x5F0C: + case 0xA621: + case 0xA6E6: + case 0xA8D1: + case 0xA901: + case 0xA9D1: + case 0xA9F1: + case 0xAA51: + case 0xABF1: + case 0xFF11: + case 0x10107: + case 0x10142: + case 0x10158: + case 0x10159: + case 0x1015A: + case 0x102E1: + case 0x10320: + case 0x103D1: + case 0x104A1: + case 0x10858: + case 0x10879: + case 0x108A7: + case 0x108FB: + case 0x10916: + case 0x109C0: + case 0x10A40: + case 0x10A7D: + case 0x10A9D: + case 0x10AEB: + case 0x10B58: + case 0x10B78: + case 0x10BA9: + case 0x10CFA: + case 0x10D31: + case 0x10E60: + case 0x10F1D: + case 0x10F51: + case 0x11052: + case 0x11067: + case 0x110F1: + case 0x11137: + case 0x111D1: + case 0x111E1: + case 0x112F1: + case 0x11451: + case 0x114D1: + case 0x11651: + case 0x116C1: + case 0x11731: + case 0x118E1: + case 0x11C51: + case 0x11C5A: + case 0x11D51: + case 0x11DA1: + case 0x12415: + case 0x1241E: + case 0x1242C: + case 0x12434: + case 0x1244F: + case 0x12458: + case 0x16A61: + case 0x16B51: + case 0x16E81: + case 0x16E94: + case 0x1D2E1: + case 0x1D360: + case 0x1D372: + case 0x1D377: + case 0x1D7CF: + case 0x1D7D9: + case 0x1D7E3: + case 0x1D7ED: + case 0x1D7F7: + case 0x1E141: + case 0x1E2F1: + case 0x1E8C7: + case 0x1E951: + case 0x1EC71: + case 0x1ECA3: + case 0x1ECB1: + case 0x1ED01: + case 0x1F102: + case 0x2092A: + return (double) 1.0; + case 0x0D5C: + case 0x2152: + case 0x11FCB: + return (double) 1.0/10.0; + case 0x109F6: + return (double) 1.0/12.0; + case 0x09F4: + case 0x0B75: + case 0x0D76: + case 0xA833: + case 0x11FC9: + case 0x11FCA: + return (double) 1.0/16.0; + case 0x0D58: + case 0x11FC1: + return (double) 1.0/160.0; + case 0x00BD: + case 0x0B73: + case 0x0D74: + case 0x0F2A: + case 0x2CFD: + case 0xA831: + case 0x10141: + case 0x10175: + case 0x10176: + case 0x109BD: + case 0x10A48: + case 0x10E7B: + case 0x10F26: + case 0x11FD1: + case 0x11FD2: + case 0x12464: + case 0x1ECAE: + case 0x1ED3C: + return (double) 1.0/2.0; + case 0x0D5B: + case 0x11FC8: + return (double) 1.0/20.0; + case 0x2153: + case 0x10E7D: + case 0x1245A: + case 0x1245D: + case 0x12465: + return (double) 1.0/3.0; + case 0x11FC5: + return (double) 1.0/32.0; + case 0x11FC0: + case 0x11FD4: + return (double) 1.0/320.0; + case 0x00BC: + case 0x09F7: + case 0x0B72: + case 0x0D73: + case 0xA830: + case 0x10140: + case 0x1018B: + case 0x10E7C: + case 0x11FD0: + case 0x12460: + case 0x12462: + case 0x12463: + case 0x1ECAD: + return (double) 1.0/4.0; + case 0x0D59: + case 0x11FC4: + return (double) 1.0/40.0; + case 0x0D5E: + case 0x2155: + case 0x11FCF: + return (double) 1.0/5.0; + case 0x2159: + case 0x12461: + case 0x1ED3D: + return (double) 1.0/6.0; + case 0x11FC3: + return (double) 1.0/64.0; + case 0x2150: + return (double) 1.0/7.0; + case 0x09F5: + case 0x0B76: + case 0x0D77: + case 0x215B: + case 0xA834: + case 0x11FCC: + case 0x1245F: + return (double) 1.0/8.0; + case 0x11FC2: + return (double) 1.0/80.0; + case 0x2151: + return (double) 1.0/9.0; + case 0x0BF0: + case 0x0D70: + case 0x1372: + case 0x2169: + case 0x2179: + case 0x2469: + case 0x247D: + case 0x2491: + case 0x24FE: + case 0x277F: + case 0x2789: + case 0x2793: + case 0x3038: + case 0x3229: + case 0x3248: + case 0x3289: + case 0x4EC0: + case 0x5341: + case 0x62FE: + case 0xF973: + case 0xF9FD: + case 0x10110: + case 0x10149: + case 0x10150: + case 0x10157: + case 0x10160: + case 0x10161: + case 0x10162: + case 0x10163: + case 0x10164: + case 0x102EA: + case 0x10322: + case 0x103D3: + case 0x1085B: + case 0x1087E: + case 0x108AD: + case 0x108FD: + case 0x10917: + case 0x109C9: + case 0x10A44: + case 0x10A9E: + case 0x10AED: + case 0x10B5C: + case 0x10B7C: + case 0x10BAD: + case 0x10CFC: + case 0x10E69: + case 0x10F22: + case 0x10F52: + case 0x1105B: + case 0x111EA: + case 0x1173A: + case 0x118EA: + case 0x11C63: + case 0x16B5B: + case 0x16E8A: + case 0x1D2EA: + case 0x1D369: + case 0x1EC7A: + case 0x1ED0A: + case 0x1ED37: + return (double) 10.0; + case 0x109FF: + return (double) 10.0/12.0; + case 0x0BF1: + case 0x0D71: + case 0x137B: + case 0x216D: + case 0x217D: + case 0x4F70: + case 0x767E: + case 0x964C: + case 0x10119: + case 0x1014B: + case 0x10152: + case 0x1016A: + case 0x102F3: + case 0x103D5: + case 0x1085D: + case 0x108AF: + case 0x108FF: + case 0x10919: + case 0x109D2: + case 0x10A46: + case 0x10AEF: + case 0x10B5E: + case 0x10B7E: + case 0x10BAF: + case 0x10CFE: + case 0x10E72: + case 0x10F25: + case 0x10F54: + case 0x11064: + case 0x111F3: + case 0x11C6C: + case 0x16B5C: + case 0x1EC83: + case 0x1ED13: + return (double) 100.0; + case 0x0BF2: + case 0x0D72: + case 0x216F: + case 0x217F: + case 0x2180: + case 0x4EDF: + case 0x5343: + case 0x9621: + case 0x10122: + case 0x1014D: + case 0x10154: + case 0x10171: + case 0x1085E: + case 0x109DB: + case 0x10A47: + case 0x10B5F: + case 0x10B7F: + case 0x10CFF: + case 0x11065: + case 0x111F4: + case 0x1EC8C: + case 0x1ED1C: + return (double) 1000.0; + case 0x137C: + case 0x2182: + case 0x4E07: + case 0x842C: + case 0x1012B: + case 0x10155: + case 0x1085F: + case 0x109E4: + case 0x16B5D: + case 0x1EC95: + case 0x1ECB3: + case 0x1ED25: + case 0x1ED3B: + return (double) 10000.0; + case 0x2188: + case 0x109ED: + case 0x1EC9E: + case 0x1ECA0: + case 0x1ECB4: + return (double) 100000.0; + case 0x16B5E: + return (double) 1000000.0; + case 0x1ECA1: + return (double) 10000000.0; + case 0x4EBF: + case 0x5104: + case 0x16B5F: + return (double) 100000000.0; + case 0x16B60: + return (double) 10000000000.0; + case 0x5146: + case 0x16B61: + return (double) 1000000000000.0; + case 0x216A: + case 0x217A: + case 0x246A: + case 0x247E: + case 0x2492: + case 0x24EB: + case 0x16E8B: + case 0x1D2EB: + return (double) 11.0; + case 0x109BC: + return (double) 11.0/12.0; + case 0x0F2F: + return (double) 11.0/2.0; + case 0x216B: + case 0x217B: + case 0x246B: + case 0x247F: + case 0x2493: + case 0x24EC: + case 0x16E8C: + case 0x1D2EC: + return (double) 12.0; + case 0x246C: + case 0x2480: + case 0x2494: + case 0x24ED: + case 0x16E8D: + case 0x1D2ED: + return (double) 13.0; + case 0x0F30: + return (double) 13.0/2.0; + case 0x246D: + case 0x2481: + case 0x2495: + case 0x24EE: + case 0x16E8E: + case 0x1D2EE: + return (double) 14.0; + case 0x246E: + case 0x2482: + case 0x2496: + case 0x24EF: + case 0x16E8F: + case 0x1D2EF: + return (double) 15.0; + case 0x0F31: + return (double) 15.0/2.0; + case 0x09F9: + case 0x246F: + case 0x2483: + case 0x2497: + case 0x24F0: + case 0x16E90: + case 0x1D2F0: + return (double) 16.0; + case 0x16EE: + case 0x2470: + case 0x2484: + case 0x2498: + case 0x24F1: + case 0x16E91: + case 0x1D2F1: + return (double) 17.0; + case 0x0F32: + return (double) 17.0/2.0; + case 0x16EF: + case 0x2471: + case 0x2485: + case 0x2499: + case 0x24F2: + case 0x16E92: + case 0x1D2F2: + return (double) 18.0; + case 0x16F0: + case 0x2472: + case 0x2486: + case 0x249A: + case 0x24F3: + case 0x16E93: + case 0x1D2F3: + return (double) 19.0; + case 0x0032: + case 0x00B2: + case 0x0662: + case 0x06F2: + case 0x07C2: + case 0x0968: + case 0x09E8: + case 0x0A68: + case 0x0AE8: + case 0x0B68: + case 0x0BE8: + case 0x0C68: + case 0x0C7A: + case 0x0C7D: + case 0x0CE8: + case 0x0D68: + case 0x0DE8: + case 0x0E52: + case 0x0ED2: + case 0x0F22: + case 0x1042: + case 0x1092: + case 0x136A: + case 0x17E2: + case 0x17F2: + case 0x1812: + case 0x1948: + case 0x19D2: + case 0x1A82: + case 0x1A92: + case 0x1B52: + case 0x1BB2: + case 0x1C42: + case 0x1C52: + case 0x2082: + case 0x2161: + case 0x2171: + case 0x2461: + case 0x2475: + case 0x2489: + case 0x24F6: + case 0x2777: + case 0x2781: + case 0x278B: + case 0x3022: + case 0x3193: + case 0x3221: + case 0x3281: + case 0x3483: + case 0x4E8C: + case 0x5169: + case 0x5F0D: + case 0x5F10: + case 0x8CAE: + case 0x8CB3: + case 0x8D30: + case 0xA622: + case 0xA6E7: + case 0xA8D2: + case 0xA902: + case 0xA9D2: + case 0xA9F2: + case 0xAA52: + case 0xABF2: + case 0xF978: + case 0xFF12: + case 0x10108: + case 0x1015B: + case 0x1015C: + case 0x1015D: + case 0x1015E: + case 0x102E2: + case 0x103D2: + case 0x104A2: + case 0x10859: + case 0x1087A: + case 0x108A8: + case 0x1091A: + case 0x109C1: + case 0x10A41: + case 0x10B59: + case 0x10B79: + case 0x10BAA: + case 0x10D32: + case 0x10E61: + case 0x10F1E: + case 0x11053: + case 0x11068: + case 0x110F2: + case 0x11138: + case 0x111D2: + case 0x111E2: + case 0x112F2: + case 0x11452: + case 0x114D2: + case 0x11652: + case 0x116C2: + case 0x11732: + case 0x118E2: + case 0x11C52: + case 0x11C5B: + case 0x11D52: + case 0x11DA2: + case 0x12400: + case 0x12416: + case 0x1241F: + case 0x12423: + case 0x1242D: + case 0x12435: + case 0x1244A: + case 0x12450: + case 0x12456: + case 0x12459: + case 0x16A62: + case 0x16B52: + case 0x16E82: + case 0x16E95: + case 0x1D2E2: + case 0x1D361: + case 0x1D373: + case 0x1D7D0: + case 0x1D7DA: + case 0x1D7E4: + case 0x1D7EE: + case 0x1D7F8: + case 0x1E142: + case 0x1E2F2: + case 0x1E8C8: + case 0x1E952: + case 0x1EC72: + case 0x1ECA4: + case 0x1ECB2: + case 0x1ED02: + case 0x1ED2F: + case 0x1F103: + case 0x22390: + return (double) 2.0; + case 0x109F7: + return (double) 2.0/12.0; + case 0x2154: + case 0x10177: + case 0x10E7E: + case 0x1245B: + case 0x1245E: + case 0x12466: + return (double) 2.0/3.0; + case 0x2156: + return (double) 2.0/5.0; + case 0x1373: + case 0x2473: + case 0x2487: + case 0x249B: + case 0x24F4: + case 0x3039: + case 0x3249: + case 0x5344: + case 0x5EFF: + case 0x10111: + case 0x102EB: + case 0x103D4: + case 0x1085C: + case 0x1087F: + case 0x108AE: + case 0x108FE: + case 0x10918: + case 0x109CA: + case 0x10A45: + case 0x10A9F: + case 0x10AEE: + case 0x10B5D: + case 0x10B7D: + case 0x10BAE: + case 0x10E6A: + case 0x10F23: + case 0x10F53: + case 0x1105C: + case 0x111EB: + case 0x1173B: + case 0x118EB: + case 0x11C64: + case 0x1D36A: + case 0x1EC7B: + case 0x1ED0B: + return (double) 20.0; + case 0x1011A: + case 0x102F4: + case 0x109D3: + case 0x10E73: + case 0x1EC84: + case 0x1ED14: + return (double) 200.0; + case 0x10123: + case 0x109DC: + case 0x1EC8D: + case 0x1ED1D: + case 0x1ED3A: + return (double) 2000.0; + case 0x1012C: + case 0x109E5: + case 0x1EC96: + case 0x1ED26: + return (double) 20000.0; + case 0x109EE: + case 0x1EC9F: + return (double) 200000.0; + case 0x1ECA2: + return (double) 20000000.0; + case 0x3251: + return (double) 21.0; + case 0x12432: + return (double) 216000.0; + case 0x3252: + return (double) 22.0; + case 0x3253: + return (double) 23.0; + case 0x3254: + return (double) 24.0; + case 0x3255: + return (double) 25.0; + case 0x3256: + return (double) 26.0; + case 0x3257: + return (double) 27.0; + case 0x3258: + return (double) 28.0; + case 0x3259: + return (double) 29.0; + case 0x0033: + case 0x00B3: + case 0x0663: + case 0x06F3: + case 0x07C3: + case 0x0969: + case 0x09E9: + case 0x0A69: + case 0x0AE9: + case 0x0B69: + case 0x0BE9: + case 0x0C69: + case 0x0C7B: + case 0x0C7E: + case 0x0CE9: + case 0x0D69: + case 0x0DE9: + case 0x0E53: + case 0x0ED3: + case 0x0F23: + case 0x1043: + case 0x1093: + case 0x136B: + case 0x17E3: + case 0x17F3: + case 0x1813: + case 0x1949: + case 0x19D3: + case 0x1A83: + case 0x1A93: + case 0x1B53: + case 0x1BB3: + case 0x1C43: + case 0x1C53: + case 0x2083: + case 0x2162: + case 0x2172: + case 0x2462: + case 0x2476: + case 0x248A: + case 0x24F7: + case 0x2778: + case 0x2782: + case 0x278C: + case 0x3023: + case 0x3194: + case 0x3222: + case 0x3282: + case 0x4E09: + case 0x4EE8: + case 0x53C1: + case 0x53C2: + case 0x53C3: + case 0x53C4: + case 0x5F0E: + case 0xA623: + case 0xA6E8: + case 0xA8D3: + case 0xA903: + case 0xA9D3: + case 0xA9F3: + case 0xAA53: + case 0xABF3: + case 0xF96B: + case 0xFF13: + case 0x10109: + case 0x102E3: + case 0x104A3: + case 0x1085A: + case 0x1087B: + case 0x108A9: + case 0x1091B: + case 0x109C2: + case 0x10A42: + case 0x10B5A: + case 0x10B7A: + case 0x10BAB: + case 0x10D33: + case 0x10E62: + case 0x10F1F: + case 0x11054: + case 0x11069: + case 0x110F3: + case 0x11139: + case 0x111D3: + case 0x111E3: + case 0x112F3: + case 0x11453: + case 0x114D3: + case 0x11653: + case 0x116C3: + case 0x11733: + case 0x118E3: + case 0x11C53: + case 0x11C5C: + case 0x11D53: + case 0x11DA3: + case 0x12401: + case 0x12408: + case 0x12417: + case 0x12420: + case 0x12424: + case 0x12425: + case 0x1242E: + case 0x1242F: + case 0x12436: + case 0x12437: + case 0x1243A: + case 0x1243B: + case 0x1244B: + case 0x12451: + case 0x12457: + case 0x16A63: + case 0x16B53: + case 0x16E83: + case 0x16E96: + case 0x1D2E3: + case 0x1D362: + case 0x1D374: + case 0x1D7D1: + case 0x1D7DB: + case 0x1D7E5: + case 0x1D7EF: + case 0x1D7F9: + case 0x1E143: + case 0x1E2F3: + case 0x1E8C9: + case 0x1E953: + case 0x1EC73: + case 0x1ECA5: + case 0x1ED03: + case 0x1ED30: + case 0x1F104: + case 0x20AFD: + case 0x20B19: + case 0x22998: + case 0x23B1B: + return (double) 3.0; + case 0x109F8: + return (double) 3.0/12.0; + case 0x09F6: + case 0x0B77: + case 0x0D78: + case 0xA835: + case 0x11FCE: + return (double) 3.0/16.0; + case 0x0F2B: + return (double) 3.0/2.0; + case 0x0D5D: + case 0x11FCD: + return (double) 3.0/20.0; + case 0x00BE: + case 0x09F8: + case 0x0B74: + case 0x0D75: + case 0xA832: + case 0x10178: + case 0x11FD3: + case 0x1ECAF: + return (double) 3.0/4.0; + case 0x2157: + return (double) 3.0/5.0; + case 0x11FC7: + return (double) 3.0/64.0; + case 0x215C: + return (double) 3.0/8.0; + case 0x0D5A: + case 0x11FC6: + return (double) 3.0/80.0; + case 0x1374: + case 0x303A: + case 0x324A: + case 0x325A: + case 0x5345: + case 0x10112: + case 0x10165: + case 0x102EC: + case 0x109CB: + case 0x10E6B: + case 0x10F24: + case 0x1105D: + case 0x111EC: + case 0x118EC: + case 0x11C65: + case 0x1D36B: + case 0x1EC7C: + case 0x1ED0C: + case 0x20983: + return (double) 30.0; + case 0x1011B: + case 0x1016B: + case 0x102F5: + case 0x109D4: + case 0x10E74: + case 0x1EC85: + case 0x1ED15: + return (double) 300.0; + case 0x10124: + case 0x109DD: + case 0x1EC8E: + case 0x1ED1E: + return (double) 3000.0; + case 0x1012D: + case 0x109E6: + case 0x1EC97: + case 0x1ED27: + return (double) 30000.0; + case 0x109EF: + return (double) 300000.0; + case 0x325B: + return (double) 31.0; + case 0x325C: + return (double) 32.0; + case 0x325D: + return (double) 33.0; + case 0x325E: + return (double) 34.0; + case 0x325F: + return (double) 35.0; + case 0x32B1: + return (double) 36.0; + case 0x32B2: + return (double) 37.0; + case 0x32B3: + return (double) 38.0; + case 0x32B4: + return (double) 39.0; + case 0x0034: + case 0x0664: + case 0x06F4: + case 0x07C4: + case 0x096A: + case 0x09EA: + case 0x0A6A: + case 0x0AEA: + case 0x0B6A: + case 0x0BEA: + case 0x0C6A: + case 0x0CEA: + case 0x0D6A: + case 0x0DEA: + case 0x0E54: + case 0x0ED4: + case 0x0F24: + case 0x1044: + case 0x1094: + case 0x136C: + case 0x17E4: + case 0x17F4: + case 0x1814: + case 0x194A: + case 0x19D4: + case 0x1A84: + case 0x1A94: + case 0x1B54: + case 0x1BB4: + case 0x1C44: + case 0x1C54: + case 0x2074: + case 0x2084: + case 0x2163: + case 0x2173: + case 0x2463: + case 0x2477: + case 0x248B: + case 0x24F8: + case 0x2779: + case 0x2783: + case 0x278D: + case 0x3024: + case 0x3195: + case 0x3223: + case 0x3283: + case 0x4E96: + case 0x56DB: + case 0x8086: + case 0xA624: + case 0xA6E9: + case 0xA8D4: + case 0xA904: + case 0xA9D4: + case 0xA9F4: + case 0xAA54: + case 0xABF4: + case 0xFF14: + case 0x1010A: + case 0x102E4: + case 0x104A4: + case 0x1087C: + case 0x108AA: + case 0x108AB: + case 0x109C3: + case 0x10A43: + case 0x10B5B: + case 0x10B7B: + case 0x10BAC: + case 0x10D34: + case 0x10E63: + case 0x10F20: + case 0x11055: + case 0x1106A: + case 0x110F4: + case 0x1113A: + case 0x111D4: + case 0x111E4: + case 0x112F4: + case 0x11454: + case 0x114D4: + case 0x11654: + case 0x116C4: + case 0x11734: + case 0x118E4: + case 0x11C54: + case 0x11C5D: + case 0x11D54: + case 0x11DA4: + case 0x12402: + case 0x12409: + case 0x1240F: + case 0x12418: + case 0x12421: + case 0x12426: + case 0x12430: + case 0x12438: + case 0x1243C: + case 0x1243D: + case 0x1243E: + case 0x1243F: + case 0x1244C: + case 0x12452: + case 0x12453: + case 0x12469: + case 0x16A64: + case 0x16B54: + case 0x16E84: + case 0x1D2E4: + case 0x1D363: + case 0x1D375: + case 0x1D7D2: + case 0x1D7DC: + case 0x1D7E6: + case 0x1D7F0: + case 0x1D7FA: + case 0x1E144: + case 0x1E2F4: + case 0x1E8CA: + case 0x1E954: + case 0x1EC74: + case 0x1ECA6: + case 0x1ED04: + case 0x1ED31: + case 0x1F105: + case 0x20064: + case 0x200E2: + case 0x2626D: + return (double) 4.0; + case 0x109F9: + return (double) 4.0/12.0; + case 0x2158: + return (double) 4.0/5.0; + case 0x1375: + case 0x324B: + case 0x32B5: + case 0x534C: + case 0x10113: + case 0x102ED: + case 0x109CC: + case 0x10E6C: + case 0x1105E: + case 0x111ED: + case 0x118ED: + case 0x11C66: + case 0x12467: + case 0x1D36C: + case 0x1EC7D: + case 0x1ED0D: + case 0x2098C: + case 0x2099C: + return (double) 40.0; + case 0x1011C: + case 0x102F6: + case 0x109D5: + case 0x10E75: + case 0x1EC86: + case 0x1ED16: + case 0x1ED38: + return (double) 400.0; + case 0x10125: + case 0x109DE: + case 0x1EC8F: + case 0x1ED1F: + return (double) 4000.0; + case 0x1012E: + case 0x109E7: + case 0x1EC98: + case 0x1ED28: + return (double) 40000.0; + case 0x109F0: + return (double) 400000.0; + case 0x32B6: + return (double) 41.0; + case 0x32B7: + return (double) 42.0; + case 0x32B8: + return (double) 43.0; + case 0x12433: + return (double) 432000.0; + case 0x32B9: + return (double) 44.0; + case 0x32BA: + return (double) 45.0; + case 0x32BB: + return (double) 46.0; + case 0x32BC: + return (double) 47.0; + case 0x32BD: + return (double) 48.0; + case 0x32BE: + return (double) 49.0; + case 0x0035: + case 0x0665: + case 0x06F5: + case 0x07C5: + case 0x096B: + case 0x09EB: + case 0x0A6B: + case 0x0AEB: + case 0x0B6B: + case 0x0BEB: + case 0x0C6B: + case 0x0CEB: + case 0x0D6B: + case 0x0DEB: + case 0x0E55: + case 0x0ED5: + case 0x0F25: + case 0x1045: + case 0x1095: + case 0x136D: + case 0x17E5: + case 0x17F5: + case 0x1815: + case 0x194B: + case 0x19D5: + case 0x1A85: + case 0x1A95: + case 0x1B55: + case 0x1BB5: + case 0x1C45: + case 0x1C55: + case 0x2075: + case 0x2085: + case 0x2164: + case 0x2174: + case 0x2464: + case 0x2478: + case 0x248C: + case 0x24F9: + case 0x277A: + case 0x2784: + case 0x278E: + case 0x3025: + case 0x3224: + case 0x3284: + case 0x3405: + case 0x382A: + case 0x4E94: + case 0x4F0D: + case 0xA625: + case 0xA6EA: + case 0xA8D5: + case 0xA905: + case 0xA9D5: + case 0xA9F5: + case 0xAA55: + case 0xABF5: + case 0xFF15: + case 0x1010B: + case 0x10143: + case 0x10148: + case 0x1014F: + case 0x1015F: + case 0x10173: + case 0x102E5: + case 0x10321: + case 0x104A5: + case 0x1087D: + case 0x108AC: + case 0x108FC: + case 0x109C4: + case 0x10AEC: + case 0x10CFB: + case 0x10D35: + case 0x10E64: + case 0x10F21: + case 0x11056: + case 0x1106B: + case 0x110F5: + case 0x1113B: + case 0x111D5: + case 0x111E5: + case 0x112F5: + case 0x11455: + case 0x114D5: + case 0x11655: + case 0x116C5: + case 0x11735: + case 0x118E5: + case 0x11C55: + case 0x11C5E: + case 0x11D55: + case 0x11DA5: + case 0x12403: + case 0x1240A: + case 0x12410: + case 0x12419: + case 0x12422: + case 0x12427: + case 0x12431: + case 0x12439: + case 0x1244D: + case 0x12454: + case 0x12455: + case 0x1246A: + case 0x16A65: + case 0x16B55: + case 0x16E85: + case 0x1D2E5: + case 0x1D364: + case 0x1D376: + case 0x1D378: + case 0x1D7D3: + case 0x1D7DD: + case 0x1D7E7: + case 0x1D7F1: + case 0x1D7FB: + case 0x1E145: + case 0x1E2F5: + case 0x1E8CB: + case 0x1E955: + case 0x1EC75: + case 0x1ECA7: + case 0x1ED05: + case 0x1ED32: + case 0x1F106: + case 0x20121: + return (double) 5.0; + case 0x109FA: + return (double) 5.0/12.0; + case 0x0F2C: + return (double) 5.0/2.0; + case 0x215A: + case 0x1245C: + return (double) 5.0/6.0; + case 0x215D: + return (double) 5.0/8.0; + case 0x1376: + case 0x216C: + case 0x217C: + case 0x2186: + case 0x324C: + case 0x32BF: + case 0x10114: + case 0x10144: + case 0x1014A: + case 0x10151: + case 0x10166: + case 0x10167: + case 0x10168: + case 0x10169: + case 0x10174: + case 0x102EE: + case 0x10323: + case 0x109CD: + case 0x10A7E: + case 0x10CFD: + case 0x10E6D: + case 0x1105F: + case 0x111EE: + case 0x118EE: + case 0x11C67: + case 0x12468: + case 0x1D36D: + case 0x1EC7E: + case 0x1ED0E: + return (double) 50.0; + case 0x216E: + case 0x217E: + case 0x1011D: + case 0x10145: + case 0x1014C: + case 0x10153: + case 0x1016C: + case 0x1016D: + case 0x1016E: + case 0x1016F: + case 0x10170: + case 0x102F7: + case 0x109D6: + case 0x10E76: + case 0x1EC87: + case 0x1ED17: + return (double) 500.0; + case 0x2181: + case 0x10126: + case 0x10146: + case 0x1014E: + case 0x10172: + case 0x109DF: + case 0x1EC90: + case 0x1ED20: + return (double) 5000.0; + case 0x2187: + case 0x1012F: + case 0x10147: + case 0x10156: + case 0x109E8: + case 0x1EC99: + case 0x1ED29: + return (double) 50000.0; + case 0x109F1: + return (double) 500000.0; + case 0x0036: + case 0x0666: + case 0x06F6: + case 0x07C6: + case 0x096C: + case 0x09EC: + case 0x0A6C: + case 0x0AEC: + case 0x0B6C: + case 0x0BEC: + case 0x0C6C: + case 0x0CEC: + case 0x0D6C: + case 0x0DEC: + case 0x0E56: + case 0x0ED6: + case 0x0F26: + case 0x1046: + case 0x1096: + case 0x136E: + case 0x17E6: + case 0x17F6: + case 0x1816: + case 0x194C: + case 0x19D6: + case 0x1A86: + case 0x1A96: + case 0x1B56: + case 0x1BB6: + case 0x1C46: + case 0x1C56: + case 0x2076: + case 0x2086: + case 0x2165: + case 0x2175: + case 0x2185: + case 0x2465: + case 0x2479: + case 0x248D: + case 0x24FA: + case 0x277B: + case 0x2785: + case 0x278F: + case 0x3026: + case 0x3225: + case 0x3285: + case 0x516D: + case 0x9646: + case 0x9678: + case 0xA626: + case 0xA6EB: + case 0xA8D6: + case 0xA906: + case 0xA9D6: + case 0xA9F6: + case 0xAA56: + case 0xABF6: + case 0xF9D1: + case 0xF9D3: + case 0xFF16: + case 0x1010C: + case 0x102E6: + case 0x104A6: + case 0x109C5: + case 0x10D36: + case 0x10E65: + case 0x11057: + case 0x1106C: + case 0x110F6: + case 0x1113C: + case 0x111D6: + case 0x111E6: + case 0x112F6: + case 0x11456: + case 0x114D6: + case 0x11656: + case 0x116C6: + case 0x11736: + case 0x118E6: + case 0x11C56: + case 0x11C5F: + case 0x11D56: + case 0x11DA6: + case 0x12404: + case 0x1240B: + case 0x12411: + case 0x1241A: + case 0x12428: + case 0x12440: + case 0x1244E: + case 0x1246B: + case 0x16A66: + case 0x16B56: + case 0x16E86: + case 0x1D2E6: + case 0x1D365: + case 0x1D7D4: + case 0x1D7DE: + case 0x1D7E8: + case 0x1D7F2: + case 0x1D7FC: + case 0x1E146: + case 0x1E2F6: + case 0x1E8CC: + case 0x1E956: + case 0x1EC76: + case 0x1ECA8: + case 0x1ED06: + case 0x1ED33: + case 0x1F107: + case 0x20AEA: + return (double) 6.0; + case 0x109FB: + return (double) 6.0/12.0; + case 0x1377: + case 0x324D: + case 0x10115: + case 0x102EF: + case 0x109CE: + case 0x10E6E: + case 0x11060: + case 0x111EF: + case 0x118EF: + case 0x11C68: + case 0x1D36E: + case 0x1EC7F: + case 0x1ED0F: + return (double) 60.0; + case 0x1011E: + case 0x102F8: + case 0x109D7: + case 0x10E77: + case 0x1EC88: + case 0x1ED18: + case 0x1ED39: + return (double) 600.0; + case 0x10127: + case 0x109E0: + case 0x1EC91: + case 0x1ED21: + return (double) 6000.0; + case 0x10130: + case 0x109E9: + case 0x1EC9A: + case 0x1ED2A: + return (double) 60000.0; + case 0x109F2: + return (double) 600000.0; + case 0x0037: + case 0x0667: + case 0x06F7: + case 0x07C7: + case 0x096D: + case 0x09ED: + case 0x0A6D: + case 0x0AED: + case 0x0B6D: + case 0x0BED: + case 0x0C6D: + case 0x0CED: + case 0x0D6D: + case 0x0DED: + case 0x0E57: + case 0x0ED7: + case 0x0F27: + case 0x1047: + case 0x1097: + case 0x136F: + case 0x17E7: + case 0x17F7: + case 0x1817: + case 0x194D: + case 0x19D7: + case 0x1A87: + case 0x1A97: + case 0x1B57: + case 0x1BB7: + case 0x1C47: + case 0x1C57: + case 0x2077: + case 0x2087: + case 0x2166: + case 0x2176: + case 0x2466: + case 0x247A: + case 0x248E: + case 0x24FB: + case 0x277C: + case 0x2786: + case 0x2790: + case 0x3027: + case 0x3226: + case 0x3286: + case 0x3B4D: + case 0x4E03: + case 0x67D2: + case 0x6F06: + case 0xA627: + case 0xA6EC: + case 0xA8D7: + case 0xA907: + case 0xA9D7: + case 0xA9F7: + case 0xAA57: + case 0xABF7: + case 0xFF17: + case 0x1010D: + case 0x102E7: + case 0x104A7: + case 0x109C6: + case 0x10D37: + case 0x10E66: + case 0x11058: + case 0x1106D: + case 0x110F7: + case 0x1113D: + case 0x111D7: + case 0x111E7: + case 0x112F7: + case 0x11457: + case 0x114D7: + case 0x11657: + case 0x116C7: + case 0x11737: + case 0x118E7: + case 0x11C57: + case 0x11C60: + case 0x11D57: + case 0x11DA7: + case 0x12405: + case 0x1240C: + case 0x12412: + case 0x1241B: + case 0x12429: + case 0x12441: + case 0x12442: + case 0x12443: + case 0x1246C: + case 0x16A67: + case 0x16B57: + case 0x16E87: + case 0x1D2E7: + case 0x1D366: + case 0x1D7D5: + case 0x1D7DF: + case 0x1D7E9: + case 0x1D7F3: + case 0x1D7FD: + case 0x1E147: + case 0x1E2F7: + case 0x1E8CD: + case 0x1E957: + case 0x1EC77: + case 0x1ECA9: + case 0x1ED07: + case 0x1ED34: + case 0x1F108: + case 0x20001: + return (double) 7.0; + case 0x109FC: + return (double) 7.0/12.0; + case 0x0F2D: + return (double) 7.0/2.0; + case 0x215E: + return (double) 7.0/8.0; + case 0x1378: + case 0x324E: + case 0x10116: + case 0x102F0: + case 0x109CF: + case 0x10E6F: + case 0x11061: + case 0x111F0: + case 0x118F0: + case 0x11C69: + case 0x1D36F: + case 0x1EC80: + case 0x1ED10: + return (double) 70.0; + case 0x1011F: + case 0x102F9: + case 0x109D8: + case 0x10E78: + case 0x1EC89: + case 0x1ED19: + return (double) 700.0; + case 0x10128: + case 0x109E1: + case 0x1EC92: + case 0x1ED22: + return (double) 7000.0; + case 0x10131: + case 0x109EA: + case 0x1EC9B: + case 0x1ED2B: + return (double) 70000.0; + case 0x109F3: + return (double) 700000.0; + case 0x0038: + case 0x0668: + case 0x06F8: + case 0x07C8: + case 0x096E: + case 0x09EE: + case 0x0A6E: + case 0x0AEE: + case 0x0B6E: + case 0x0BEE: + case 0x0C6E: + case 0x0CEE: + case 0x0D6E: + case 0x0DEE: + case 0x0E58: + case 0x0ED8: + case 0x0F28: + case 0x1048: + case 0x1098: + case 0x1370: + case 0x17E8: + case 0x17F8: + case 0x1818: + case 0x194E: + case 0x19D8: + case 0x1A88: + case 0x1A98: + case 0x1B58: + case 0x1BB8: + case 0x1C48: + case 0x1C58: + case 0x2078: + case 0x2088: + case 0x2167: + case 0x2177: + case 0x2467: + case 0x247B: + case 0x248F: + case 0x24FC: + case 0x277D: + case 0x2787: + case 0x2791: + case 0x3028: + case 0x3227: + case 0x3287: + case 0x516B: + case 0x634C: + case 0xA628: + case 0xA6ED: + case 0xA8D8: + case 0xA908: + case 0xA9D8: + case 0xA9F8: + case 0xAA58: + case 0xABF8: + case 0xFF18: + case 0x1010E: + case 0x102E8: + case 0x104A8: + case 0x109C7: + case 0x10D38: + case 0x10E67: + case 0x11059: + case 0x1106E: + case 0x110F8: + case 0x1113E: + case 0x111D8: + case 0x111E8: + case 0x112F8: + case 0x11458: + case 0x114D8: + case 0x11658: + case 0x116C8: + case 0x11738: + case 0x118E8: + case 0x11C58: + case 0x11C61: + case 0x11D58: + case 0x11DA8: + case 0x12406: + case 0x1240D: + case 0x12413: + case 0x1241C: + case 0x1242A: + case 0x12444: + case 0x12445: + case 0x1246D: + case 0x16A68: + case 0x16B58: + case 0x16E88: + case 0x1D2E8: + case 0x1D367: + case 0x1D7D6: + case 0x1D7E0: + case 0x1D7EA: + case 0x1D7F4: + case 0x1D7FE: + case 0x1E148: + case 0x1E2F8: + case 0x1E8CE: + case 0x1E958: + case 0x1EC78: + case 0x1ECAA: + case 0x1ED08: + case 0x1ED35: + case 0x1F109: + return (double) 8.0; + case 0x109FD: + return (double) 8.0/12.0; + case 0x1379: + case 0x324F: + case 0x10117: + case 0x102F1: + case 0x10E70: + case 0x11062: + case 0x111F1: + case 0x118F1: + case 0x11C6A: + case 0x1D370: + case 0x1EC81: + case 0x1ED11: + return (double) 80.0; + case 0x10120: + case 0x102FA: + case 0x109D9: + case 0x10E79: + case 0x1EC8A: + case 0x1ED1A: + return (double) 800.0; + case 0x10129: + case 0x109E2: + case 0x1EC93: + case 0x1ED23: + return (double) 8000.0; + case 0x10132: + case 0x109EB: + case 0x1EC9C: + case 0x1ED2C: + return (double) 80000.0; + case 0x109F4: + return (double) 800000.0; + case 0x0039: + case 0x0669: + case 0x06F9: + case 0x07C9: + case 0x096F: + case 0x09EF: + case 0x0A6F: + case 0x0AEF: + case 0x0B6F: + case 0x0BEF: + case 0x0C6F: + case 0x0CEF: + case 0x0D6F: + case 0x0DEF: + case 0x0E59: + case 0x0ED9: + case 0x0F29: + case 0x1049: + case 0x1099: + case 0x1371: + case 0x17E9: + case 0x17F9: + case 0x1819: + case 0x194F: + case 0x19D9: + case 0x1A89: + case 0x1A99: + case 0x1B59: + case 0x1BB9: + case 0x1C49: + case 0x1C59: + case 0x2079: + case 0x2089: + case 0x2168: + case 0x2178: + case 0x2468: + case 0x247C: + case 0x2490: + case 0x24FD: + case 0x277E: + case 0x2788: + case 0x2792: + case 0x3029: + case 0x3228: + case 0x3288: + case 0x4E5D: + case 0x5EFE: + case 0x7396: + case 0xA629: + case 0xA6EE: + case 0xA8D9: + case 0xA909: + case 0xA9D9: + case 0xA9F9: + case 0xAA59: + case 0xABF9: + case 0xFF19: + case 0x1010F: + case 0x102E9: + case 0x104A9: + case 0x109C8: + case 0x10D39: + case 0x10E68: + case 0x1105A: + case 0x1106F: + case 0x110F9: + case 0x1113F: + case 0x111D9: + case 0x111E9: + case 0x112F9: + case 0x11459: + case 0x114D9: + case 0x11659: + case 0x116C9: + case 0x11739: + case 0x118E9: + case 0x11C59: + case 0x11C62: + case 0x11D59: + case 0x11DA9: + case 0x12407: + case 0x1240E: + case 0x12414: + case 0x1241D: + case 0x1242B: + case 0x12446: + case 0x12447: + case 0x12448: + case 0x12449: + case 0x1246E: + case 0x16A69: + case 0x16B59: + case 0x16E89: + case 0x1D2E9: + case 0x1D368: + case 0x1D7D7: + case 0x1D7E1: + case 0x1D7EB: + case 0x1D7F5: + case 0x1D7FF: + case 0x1E149: + case 0x1E2F9: + case 0x1E8CF: + case 0x1E959: + case 0x1EC79: + case 0x1ECAB: + case 0x1ED09: + case 0x1ED36: + case 0x1F10A: + case 0x2F890: + return (double) 9.0; + case 0x109FE: + return (double) 9.0/12.0; + case 0x0F2E: + return (double) 9.0/2.0; + case 0x137A: + case 0x10118: + case 0x102F2: + case 0x10341: + case 0x10E71: + case 0x11063: + case 0x111F2: + case 0x118F2: + case 0x11C6B: + case 0x1D371: + case 0x1EC82: + case 0x1ED12: + return (double) 90.0; + case 0x10121: + case 0x102FB: + case 0x1034A: + case 0x109DA: + case 0x10E7A: + case 0x1EC8B: + case 0x1ED1B: + return (double) 900.0; + case 0x1012A: + case 0x109E3: + case 0x1EC94: + case 0x1ED24: + return (double) 9000.0; + case 0x10133: + case 0x109EC: + case 0x1EC9D: + case 0x1ED2D: + return (double) 90000.0; + case 0x109F5: + return (double) 900000.0; + } + return -1.0; +} + +/* Returns 1 for Unicode characters having the bidirectional + * type 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise. + */ +int _PyUnicode_IsWhitespace(const Py_UCS4 ch) +{ + switch (ch) { + case 0x0009: + case 0x000A: + case 0x000B: + case 0x000C: + case 0x000D: + case 0x001C: + case 0x001D: + case 0x001E: + case 0x001F: + case 0x0020: + case 0x0085: + case 0x00A0: + case 0x1680: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200A: + case 0x2028: + case 0x2029: + case 0x202F: + case 0x205F: + case 0x3000: + return 1; + } + return 0; +} + +/* Returns 1 for Unicode characters having the line break + * property 'BK', 'CR', 'LF' or 'NL' or having bidirectional + * type 'B', 0 otherwise. + */ +int _PyUnicode_IsLinebreak(const Py_UCS4 ch) +{ + switch (ch) { + case 0x000A: + case 0x000B: + case 0x000C: + case 0x000D: + case 0x001C: + case 0x001D: + case 0x001E: + case 0x0085: + case 0x2028: + case 0x2029: + return 1; + } + return 0; +} + diff --git a/python/Objects/weakrefobject.c b/python/Objects/weakrefobject.c new file mode 100755 index 0000000..58fe09f --- /dev/null +++ b/python/Objects/weakrefobject.c @@ -0,0 +1,1023 @@ +#include "Python.h" +#include "structmember.h" + + +#define GET_WEAKREFS_LISTPTR(o) \ + ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) + + +Py_ssize_t +_PyWeakref_GetWeakrefCount(PyWeakReference *head) +{ + Py_ssize_t count = 0; + + while (head != NULL) { + ++count; + head = head->wr_next; + } + return count; +} + + +static void +init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback) +{ + self->hash = -1; + self->wr_object = ob; + self->wr_prev = NULL; + self->wr_next = NULL; + Py_XINCREF(callback); + self->wr_callback = callback; +} + +static PyWeakReference * +new_weakref(PyObject *ob, PyObject *callback) +{ + PyWeakReference *result; + + result = PyObject_GC_New(PyWeakReference, &_PyWeakref_RefType); + if (result) { + init_weakref(result, ob, callback); + PyObject_GC_Track(result); + } + return result; +} + + +/* This function clears the passed-in reference and removes it from the + * list of weak references for the referent. This is the only code that + * removes an item from the doubly-linked list of weak references for an + * object; it is also responsible for clearing the callback slot. + */ +static void +clear_weakref(PyWeakReference *self) +{ + PyObject *callback = self->wr_callback; + + if (self->wr_object != Py_None) { + PyWeakReference **list = GET_WEAKREFS_LISTPTR(self->wr_object); + + if (*list == self) + /* If 'self' is the end of the list (and thus self->wr_next == NULL) + then the weakref list itself (and thus the value of *list) will + end up being set to NULL. */ + *list = self->wr_next; + self->wr_object = Py_None; + if (self->wr_prev != NULL) + self->wr_prev->wr_next = self->wr_next; + if (self->wr_next != NULL) + self->wr_next->wr_prev = self->wr_prev; + self->wr_prev = NULL; + self->wr_next = NULL; + } + if (callback != NULL) { + Py_DECREF(callback); + self->wr_callback = NULL; + } +} + +/* Cyclic gc uses this to *just* clear the passed-in reference, leaving + * the callback intact and uncalled. It must be possible to call self's + * tp_dealloc() after calling this, so self has to be left in a sane enough + * state for that to work. We expect tp_dealloc to decref the callback + * then. The reason for not letting clear_weakref() decref the callback + * right now is that if the callback goes away, that may in turn trigger + * another callback (if a weak reference to the callback exists) -- running + * arbitrary Python code in the middle of gc is a disaster. The convolution + * here allows gc to delay triggering such callbacks until the world is in + * a sane state again. + */ +void +_PyWeakref_ClearRef(PyWeakReference *self) +{ + PyObject *callback; + + assert(self != NULL); + assert(PyWeakref_Check(self)); + /* Preserve and restore the callback around clear_weakref. */ + callback = self->wr_callback; + self->wr_callback = NULL; + clear_weakref(self); + self->wr_callback = callback; +} + +static void +weakref_dealloc(PyObject *self) +{ + PyObject_GC_UnTrack(self); + clear_weakref((PyWeakReference *) self); + Py_TYPE(self)->tp_free(self); +} + + +static int +gc_traverse(PyWeakReference *self, visitproc visit, void *arg) +{ + Py_VISIT(self->wr_callback); + return 0; +} + + +static int +gc_clear(PyWeakReference *self) +{ + clear_weakref(self); + return 0; +} + + +static PyObject * +weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw) +{ + static char *kwlist[] = {NULL}; + + if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", kwlist)) { + PyObject *object = PyWeakref_GET_OBJECT(self); + Py_INCREF(object); + return (object); + } + return NULL; +} + + +static Py_hash_t +weakref_hash(PyWeakReference *self) +{ + if (self->hash != -1) + return self->hash; + PyObject* obj = PyWeakref_GET_OBJECT(self); + if (obj == Py_None) { + PyErr_SetString(PyExc_TypeError, "weak object has gone away"); + return -1; + } + Py_INCREF(obj); + self->hash = PyObject_Hash(obj); + Py_DECREF(obj); + return self->hash; +} + + +static PyObject * +weakref_repr(PyWeakReference *self) +{ + PyObject *name, *repr; + _Py_IDENTIFIER(__name__); + PyObject* obj = PyWeakref_GET_OBJECT(self); + + if (obj == Py_None) { + return PyUnicode_FromFormat("", self); + } + + Py_INCREF(obj); + if (_PyObject_LookupAttrId(obj, &PyId___name__, &name) < 0) { + Py_DECREF(obj); + return NULL; + } + if (name == NULL || !PyUnicode_Check(name)) { + repr = PyUnicode_FromFormat( + "", + self, + Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, + obj); + } + else { + repr = PyUnicode_FromFormat( + "", + self, + Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, + obj, + name); + } + Py_DECREF(obj); + Py_XDECREF(name); + return repr; +} + +/* Weak references only support equality, not ordering. Two weak references + are equal if the underlying objects are equal. If the underlying object has + gone away, they are equal if they are identical. */ + +static PyObject * +weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op) +{ + if ((op != Py_EQ && op != Py_NE) || + !PyWeakref_Check(self) || + !PyWeakref_Check(other)) { + Py_RETURN_NOTIMPLEMENTED; + } + if (PyWeakref_GET_OBJECT(self) == Py_None + || PyWeakref_GET_OBJECT(other) == Py_None) { + int res = (self == other); + if (op == Py_NE) + res = !res; + if (res) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + PyObject* obj = PyWeakref_GET_OBJECT(self); + PyObject* other_obj = PyWeakref_GET_OBJECT(other); + Py_INCREF(obj); + Py_INCREF(other_obj); + PyObject* res = PyObject_RichCompare(obj, other_obj, op); + Py_DECREF(obj); + Py_DECREF(other_obj); + return res; +} + +/* Given the head of an object's list of weak references, extract the + * two callback-less refs (ref and proxy). Used to determine if the + * shared references exist and to determine the back link for newly + * inserted references. + */ +static void +get_basic_refs(PyWeakReference *head, + PyWeakReference **refp, PyWeakReference **proxyp) +{ + *refp = NULL; + *proxyp = NULL; + + if (head != NULL && head->wr_callback == NULL) { + /* We need to be careful that the "basic refs" aren't + subclasses of the main types. That complicates this a + little. */ + if (PyWeakref_CheckRefExact(head)) { + *refp = head; + head = head->wr_next; + } + if (head != NULL + && head->wr_callback == NULL + && PyWeakref_CheckProxy(head)) { + *proxyp = head; + /* head = head->wr_next; */ + } + } +} + +/* Insert 'newref' in the list after 'prev'. Both must be non-NULL. */ +static void +insert_after(PyWeakReference *newref, PyWeakReference *prev) +{ + newref->wr_prev = prev; + newref->wr_next = prev->wr_next; + if (prev->wr_next != NULL) + prev->wr_next->wr_prev = newref; + prev->wr_next = newref; +} + +/* Insert 'newref' at the head of the list; 'list' points to the variable + * that stores the head. + */ +static void +insert_head(PyWeakReference *newref, PyWeakReference **list) +{ + PyWeakReference *next = *list; + + newref->wr_prev = NULL; + newref->wr_next = next; + if (next != NULL) + next->wr_prev = newref; + *list = newref; +} + +static int +parse_weakref_init_args(const char *funcname, PyObject *args, PyObject *kwargs, + PyObject **obp, PyObject **callbackp) +{ + return PyArg_UnpackTuple(args, funcname, 1, 2, obp, callbackp); +} + +static PyObject * +weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyWeakReference *self = NULL; + PyObject *ob, *callback = NULL; + + if (parse_weakref_init_args("__new__", args, kwargs, &ob, &callback)) { + PyWeakReference *ref, *proxy; + PyWeakReference **list; + + if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { + PyErr_Format(PyExc_TypeError, + "cannot create weak reference to '%s' object", + Py_TYPE(ob)->tp_name); + return NULL; + } + if (callback == Py_None) + callback = NULL; + list = GET_WEAKREFS_LISTPTR(ob); + get_basic_refs(*list, &ref, &proxy); + if (callback == NULL && type == &_PyWeakref_RefType) { + if (ref != NULL) { + /* We can re-use an existing reference. */ + Py_INCREF(ref); + return (PyObject *)ref; + } + } + /* We have to create a new reference. */ + /* Note: the tp_alloc() can trigger cyclic GC, so the weakref + list on ob can be mutated. This means that the ref and + proxy pointers we got back earlier may have been collected, + so we need to compute these values again before we use + them. */ + self = (PyWeakReference *) (type->tp_alloc(type, 0)); + if (self != NULL) { + init_weakref(self, ob, callback); + if (callback == NULL && type == &_PyWeakref_RefType) { + insert_head(self, list); + } + else { + PyWeakReference *prev; + + get_basic_refs(*list, &ref, &proxy); + prev = (proxy == NULL) ? ref : proxy; + if (prev == NULL) + insert_head(self, list); + else + insert_after(self, prev); + } + } + } + return (PyObject *)self; +} + +static int +weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *tmp; + + if (!_PyArg_NoKeywords("ref", kwargs)) + return -1; + + if (parse_weakref_init_args("__init__", args, kwargs, &tmp, &tmp)) + return 0; + else + return -1; +} + + +static PyMemberDef weakref_members[] = { + {"__callback__", T_OBJECT, offsetof(PyWeakReference, wr_callback), READONLY}, + {NULL} /* Sentinel */ +}; + +PyTypeObject +_PyWeakref_RefType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "weakref", + sizeof(PyWeakReference), + 0, + weakref_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + (reprfunc)weakref_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)weakref_hash, /*tp_hash*/ + (ternaryfunc)weakref_call, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ + (traverseproc)gc_traverse, /*tp_traverse*/ + (inquiry)gc_clear, /*tp_clear*/ + (richcmpfunc)weakref_richcompare, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + weakref_members, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + weakref___init__, /*tp_init*/ + PyType_GenericAlloc, /*tp_alloc*/ + weakref___new__, /*tp_new*/ + PyObject_GC_Del, /*tp_free*/ +}; + + +static int +proxy_checkref(PyWeakReference *proxy) +{ + if (PyWeakref_GET_OBJECT(proxy) == Py_None) { + PyErr_SetString(PyExc_ReferenceError, + "weakly-referenced object no longer exists"); + return 0; + } + return 1; +} + + +/* If a parameter is a proxy, check that it is still "live" and wrap it, + * replacing the original value with the raw object. Raises ReferenceError + * if the param is a dead proxy. + */ +#define UNWRAP(o) \ + if (PyWeakref_CheckProxy(o)) { \ + if (!proxy_checkref((PyWeakReference *)o)) \ + return NULL; \ + o = PyWeakref_GET_OBJECT(o); \ + } + +#define WRAP_UNARY(method, generic) \ + static PyObject * \ + method(PyObject *proxy) { \ + UNWRAP(proxy); \ + Py_INCREF(proxy); \ + PyObject* res = generic(proxy); \ + Py_DECREF(proxy); \ + return res; \ + } + +#define WRAP_BINARY(method, generic) \ + static PyObject * \ + method(PyObject *x, PyObject *y) { \ + UNWRAP(x); \ + UNWRAP(y); \ + Py_INCREF(x); \ + Py_INCREF(y); \ + PyObject* res = generic(x, y); \ + Py_DECREF(x); \ + Py_DECREF(y); \ + return res; \ + } + +/* Note that the third arg needs to be checked for NULL since the tp_call + * slot can receive NULL for this arg. + */ +#define WRAP_TERNARY(method, generic) \ + static PyObject * \ + method(PyObject *proxy, PyObject *v, PyObject *w) { \ + UNWRAP(proxy); \ + UNWRAP(v); \ + if (w != NULL) \ + UNWRAP(w); \ + Py_INCREF(proxy); \ + Py_INCREF(v); \ + Py_XINCREF(w); \ + PyObject* res = generic(proxy, v, w); \ + Py_DECREF(proxy); \ + Py_DECREF(v); \ + Py_XDECREF(w); \ + return res; \ + } + +#define WRAP_METHOD(method, special) \ + static PyObject * \ + method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \ + _Py_IDENTIFIER(special); \ + UNWRAP(proxy); \ + Py_INCREF(proxy); \ + PyObject* res = _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \ + Py_DECREF(proxy); \ + return res; \ + } + + +/* direct slots */ + +WRAP_BINARY(proxy_getattr, PyObject_GetAttr) +WRAP_UNARY(proxy_str, PyObject_Str) +WRAP_TERNARY(proxy_call, PyObject_Call) + +static PyObject * +proxy_repr(PyWeakReference *proxy) +{ + return PyUnicode_FromFormat( + "", + proxy, + Py_TYPE(PyWeakref_GET_OBJECT(proxy))->tp_name, + PyWeakref_GET_OBJECT(proxy)); +} + + +static int +proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value) +{ + if (!proxy_checkref(proxy)) + return -1; + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PyObject_SetAttr(obj, name, value); + Py_DECREF(obj); + return res; +} + +static PyObject * +proxy_richcompare(PyObject *proxy, PyObject *v, int op) +{ + UNWRAP(proxy); + UNWRAP(v); + return PyObject_RichCompare(proxy, v, op); +} + +/* number slots */ +WRAP_BINARY(proxy_add, PyNumber_Add) +WRAP_BINARY(proxy_sub, PyNumber_Subtract) +WRAP_BINARY(proxy_mul, PyNumber_Multiply) +WRAP_BINARY(proxy_floor_div, PyNumber_FloorDivide) +WRAP_BINARY(proxy_true_div, PyNumber_TrueDivide) +WRAP_BINARY(proxy_mod, PyNumber_Remainder) +WRAP_BINARY(proxy_divmod, PyNumber_Divmod) +WRAP_TERNARY(proxy_pow, PyNumber_Power) +WRAP_UNARY(proxy_neg, PyNumber_Negative) +WRAP_UNARY(proxy_pos, PyNumber_Positive) +WRAP_UNARY(proxy_abs, PyNumber_Absolute) +WRAP_UNARY(proxy_invert, PyNumber_Invert) +WRAP_BINARY(proxy_lshift, PyNumber_Lshift) +WRAP_BINARY(proxy_rshift, PyNumber_Rshift) +WRAP_BINARY(proxy_and, PyNumber_And) +WRAP_BINARY(proxy_xor, PyNumber_Xor) +WRAP_BINARY(proxy_or, PyNumber_Or) +WRAP_UNARY(proxy_int, PyNumber_Long) +WRAP_UNARY(proxy_float, PyNumber_Float) +WRAP_BINARY(proxy_iadd, PyNumber_InPlaceAdd) +WRAP_BINARY(proxy_isub, PyNumber_InPlaceSubtract) +WRAP_BINARY(proxy_imul, PyNumber_InPlaceMultiply) +WRAP_BINARY(proxy_ifloor_div, PyNumber_InPlaceFloorDivide) +WRAP_BINARY(proxy_itrue_div, PyNumber_InPlaceTrueDivide) +WRAP_BINARY(proxy_imod, PyNumber_InPlaceRemainder) +WRAP_TERNARY(proxy_ipow, PyNumber_InPlacePower) +WRAP_BINARY(proxy_ilshift, PyNumber_InPlaceLshift) +WRAP_BINARY(proxy_irshift, PyNumber_InPlaceRshift) +WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd) +WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor) +WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr) +WRAP_UNARY(proxy_index, PyNumber_Index) +WRAP_BINARY(proxy_matmul, PyNumber_MatrixMultiply) +WRAP_BINARY(proxy_imatmul, PyNumber_InPlaceMatrixMultiply) + +static int +proxy_bool(PyWeakReference *proxy) +{ + PyObject *o = PyWeakref_GET_OBJECT(proxy); + if (!proxy_checkref(proxy)) { + return -1; + } + Py_INCREF(o); + int res = PyObject_IsTrue(o); + Py_DECREF(o); + return res; +} + +static void +proxy_dealloc(PyWeakReference *self) +{ + if (self->wr_callback != NULL) + PyObject_GC_UnTrack((PyObject *)self); + clear_weakref(self); + PyObject_GC_Del(self); +} + +/* sequence slots */ + +static int +proxy_contains(PyWeakReference *proxy, PyObject *value) +{ + if (!proxy_checkref(proxy)) + return -1; + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PySequence_Contains(obj, value); + Py_DECREF(obj); + return res; +} + +/* mapping slots */ + +static Py_ssize_t +proxy_length(PyWeakReference *proxy) +{ + if (!proxy_checkref(proxy)) + return -1; + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + Py_ssize_t res = PyObject_Length(obj); + Py_DECREF(obj); + return res; +} + +WRAP_BINARY(proxy_getitem, PyObject_GetItem) + +static int +proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value) +{ + if (!proxy_checkref(proxy)) + return -1; + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res; + if (value == NULL) { + res = PyObject_DelItem(obj, key); + } else { + res = PyObject_SetItem(obj, key, value); + } + Py_DECREF(obj); + return res; +} + +/* iterator slots */ + +static PyObject * +proxy_iter(PyWeakReference *proxy) +{ + if (!proxy_checkref(proxy)) + return NULL; + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyObject_GetIter(obj); + Py_DECREF(obj); + return res; +} + +static PyObject * +proxy_iternext(PyWeakReference *proxy) +{ + if (!proxy_checkref(proxy)) + return NULL; + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyIter_Next(obj); + Py_DECREF(obj); + return res; +} + + +WRAP_METHOD(proxy_bytes, __bytes__) + + +static PyMethodDef proxy_methods[] = { + {"__bytes__", proxy_bytes, METH_NOARGS}, + {NULL, NULL} +}; + + +static PyNumberMethods proxy_as_number = { + proxy_add, /*nb_add*/ + proxy_sub, /*nb_subtract*/ + proxy_mul, /*nb_multiply*/ + proxy_mod, /*nb_remainder*/ + proxy_divmod, /*nb_divmod*/ + proxy_pow, /*nb_power*/ + proxy_neg, /*nb_negative*/ + proxy_pos, /*nb_positive*/ + proxy_abs, /*nb_absolute*/ + (inquiry)proxy_bool, /*nb_bool*/ + proxy_invert, /*nb_invert*/ + proxy_lshift, /*nb_lshift*/ + proxy_rshift, /*nb_rshift*/ + proxy_and, /*nb_and*/ + proxy_xor, /*nb_xor*/ + proxy_or, /*nb_or*/ + proxy_int, /*nb_int*/ + 0, /*nb_reserved*/ + proxy_float, /*nb_float*/ + proxy_iadd, /*nb_inplace_add*/ + proxy_isub, /*nb_inplace_subtract*/ + proxy_imul, /*nb_inplace_multiply*/ + proxy_imod, /*nb_inplace_remainder*/ + proxy_ipow, /*nb_inplace_power*/ + proxy_ilshift, /*nb_inplace_lshift*/ + proxy_irshift, /*nb_inplace_rshift*/ + proxy_iand, /*nb_inplace_and*/ + proxy_ixor, /*nb_inplace_xor*/ + proxy_ior, /*nb_inplace_or*/ + proxy_floor_div, /*nb_floor_divide*/ + proxy_true_div, /*nb_true_divide*/ + proxy_ifloor_div, /*nb_inplace_floor_divide*/ + proxy_itrue_div, /*nb_inplace_true_divide*/ + proxy_index, /*nb_index*/ + proxy_matmul, /*nb_matrix_multiply*/ + proxy_imatmul, /*nb_inplace_matrix_multiply*/ +}; + +static PySequenceMethods proxy_as_sequence = { + (lenfunc)proxy_length, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + 0, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + (objobjproc)proxy_contains, /* sq_contains */ +}; + +static PyMappingMethods proxy_as_mapping = { + (lenfunc)proxy_length, /*mp_length*/ + proxy_getitem, /*mp_subscript*/ + (objobjargproc)proxy_setitem, /*mp_ass_subscript*/ +}; + + +PyTypeObject +_PyWeakref_ProxyType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "weakproxy", + sizeof(PyWeakReference), + 0, + /* methods */ + (destructor)proxy_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)proxy_repr, /* tp_repr */ + &proxy_as_number, /* tp_as_number */ + &proxy_as_sequence, /* tp_as_sequence */ + &proxy_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + proxy_str, /* tp_str */ + proxy_getattr, /* tp_getattro */ + (setattrofunc)proxy_setattr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)gc_traverse, /* tp_traverse */ + (inquiry)gc_clear, /* tp_clear */ + proxy_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)proxy_iter, /* tp_iter */ + (iternextfunc)proxy_iternext, /* tp_iternext */ + proxy_methods, /* tp_methods */ +}; + + +PyTypeObject +_PyWeakref_CallableProxyType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "weakcallableproxy", + sizeof(PyWeakReference), + 0, + /* methods */ + (destructor)proxy_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (unaryfunc)proxy_repr, /* tp_repr */ + &proxy_as_number, /* tp_as_number */ + &proxy_as_sequence, /* tp_as_sequence */ + &proxy_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + proxy_call, /* tp_call */ + proxy_str, /* tp_str */ + proxy_getattr, /* tp_getattro */ + (setattrofunc)proxy_setattr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)gc_traverse, /* tp_traverse */ + (inquiry)gc_clear, /* tp_clear */ + proxy_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)proxy_iter, /* tp_iter */ + (iternextfunc)proxy_iternext, /* tp_iternext */ +}; + + + +PyObject * +PyWeakref_NewRef(PyObject *ob, PyObject *callback) +{ + PyWeakReference *result = NULL; + PyWeakReference **list; + PyWeakReference *ref, *proxy; + + if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { + PyErr_Format(PyExc_TypeError, + "cannot create weak reference to '%s' object", + Py_TYPE(ob)->tp_name); + return NULL; + } + list = GET_WEAKREFS_LISTPTR(ob); + get_basic_refs(*list, &ref, &proxy); + if (callback == Py_None) + callback = NULL; + if (callback == NULL) + /* return existing weak reference if it exists */ + result = ref; + if (result != NULL) + Py_INCREF(result); + else { + /* Note: new_weakref() can trigger cyclic GC, so the weakref + list on ob can be mutated. This means that the ref and + proxy pointers we got back earlier may have been collected, + so we need to compute these values again before we use + them. */ + result = new_weakref(ob, callback); + if (result != NULL) { + get_basic_refs(*list, &ref, &proxy); + if (callback == NULL) { + if (ref == NULL) + insert_head(result, list); + else { + /* Someone else added a ref without a callback + during GC. Return that one instead of this one + to avoid violating the invariants of the list + of weakrefs for ob. */ + Py_DECREF(result); + Py_INCREF(ref); + result = ref; + } + } + else { + PyWeakReference *prev; + + prev = (proxy == NULL) ? ref : proxy; + if (prev == NULL) + insert_head(result, list); + else + insert_after(result, prev); + } + } + } + return (PyObject *) result; +} + + +PyObject * +PyWeakref_NewProxy(PyObject *ob, PyObject *callback) +{ + PyWeakReference *result = NULL; + PyWeakReference **list; + PyWeakReference *ref, *proxy; + + if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { + PyErr_Format(PyExc_TypeError, + "cannot create weak reference to '%s' object", + Py_TYPE(ob)->tp_name); + return NULL; + } + list = GET_WEAKREFS_LISTPTR(ob); + get_basic_refs(*list, &ref, &proxy); + if (callback == Py_None) + callback = NULL; + if (callback == NULL) + /* attempt to return an existing weak reference if it exists */ + result = proxy; + if (result != NULL) + Py_INCREF(result); + else { + /* Note: new_weakref() can trigger cyclic GC, so the weakref + list on ob can be mutated. This means that the ref and + proxy pointers we got back earlier may have been collected, + so we need to compute these values again before we use + them. */ + result = new_weakref(ob, callback); + if (result != NULL) { + PyWeakReference *prev; + + if (PyCallable_Check(ob)) + Py_TYPE(result) = &_PyWeakref_CallableProxyType; + else + Py_TYPE(result) = &_PyWeakref_ProxyType; + get_basic_refs(*list, &ref, &proxy); + if (callback == NULL) { + if (proxy != NULL) { + /* Someone else added a proxy without a callback + during GC. Return that one instead of this one + to avoid violating the invariants of the list + of weakrefs for ob. */ + Py_DECREF(result); + result = proxy; + Py_INCREF(result); + goto skip_insert; + } + prev = ref; + } + else + prev = (proxy == NULL) ? ref : proxy; + + if (prev == NULL) + insert_head(result, list); + else + insert_after(result, prev); + skip_insert: + ; + } + } + return (PyObject *) result; +} + + +PyObject * +PyWeakref_GetObject(PyObject *ref) +{ + if (ref == NULL || !PyWeakref_Check(ref)) { + PyErr_BadInternalCall(); + return NULL; + } + return PyWeakref_GET_OBJECT(ref); +} + +/* Note that there's an inlined copy-paste of handle_callback() in gcmodule.c's + * handle_weakrefs(). + */ +static void +handle_callback(PyWeakReference *ref, PyObject *callback) +{ + PyObject *cbresult = PyObject_CallFunctionObjArgs(callback, ref, NULL); + + if (cbresult == NULL) + PyErr_WriteUnraisable(callback); + else + Py_DECREF(cbresult); +} + +/* This function is called by the tp_dealloc handler to clear weak references. + * + * This iterates through the weak references for 'object' and calls callbacks + * for those references which have one. It returns when all callbacks have + * been attempted. + */ +void +PyObject_ClearWeakRefs(PyObject *object) +{ + PyWeakReference **list; + + if (object == NULL + || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) + || object->ob_refcnt != 0) { + PyErr_BadInternalCall(); + return; + } + list = GET_WEAKREFS_LISTPTR(object); + /* Remove the callback-less basic and proxy references */ + if (*list != NULL && (*list)->wr_callback == NULL) { + clear_weakref(*list); + if (*list != NULL && (*list)->wr_callback == NULL) + clear_weakref(*list); + } + if (*list != NULL) { + PyWeakReference *current = *list; + Py_ssize_t count = _PyWeakref_GetWeakrefCount(current); + PyObject *err_type, *err_value, *err_tb; + + PyErr_Fetch(&err_type, &err_value, &err_tb); + if (count == 1) { + PyObject *callback = current->wr_callback; + + current->wr_callback = NULL; + clear_weakref(current); + if (callback != NULL) { + if (((PyObject *)current)->ob_refcnt > 0) + handle_callback(current, callback); + Py_DECREF(callback); + } + } + else { + PyObject *tuple; + Py_ssize_t i = 0; + + tuple = PyTuple_New(count * 2); + if (tuple == NULL) { + _PyErr_ChainExceptions(err_type, err_value, err_tb); + return; + } + + for (i = 0; i < count; ++i) { + PyWeakReference *next = current->wr_next; + + if (((PyObject *)current)->ob_refcnt > 0) + { + Py_INCREF(current); + PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); + PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); + } + else { + Py_DECREF(current->wr_callback); + } + current->wr_callback = NULL; + clear_weakref(current); + current = next; + } + for (i = 0; i < count; ++i) { + PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1); + + /* The tuple may have slots left to NULL */ + if (callback != NULL) { + PyObject *item = PyTuple_GET_ITEM(tuple, i * 2); + handle_callback((PyWeakReference *)item, callback); + } + } + Py_DECREF(tuple); + } + assert(!PyErr_Occurred()); + PyErr_Restore(err_type, err_value, err_tb); + } +} diff --git a/python/Parser/Python.asdl b/python/Parser/Python.asdl new file mode 100755 index 0000000..126d478 --- /dev/null +++ b/python/Parser/Python.asdl @@ -0,0 +1,129 @@ +-- ASDL's 5 builtin types are: +-- identifier, int, string, object, constant + +module Python +{ + mod = Module(stmt* body, type_ignore *type_ignores) + | Interactive(stmt* body) + | Expression(expr body) + | FunctionType(expr* argtypes, expr returns) + + -- not really an actual node but useful in Jython's typesystem. + | Suite(stmt* body) + + stmt = FunctionDef(identifier name, arguments args, + stmt* body, expr* decorator_list, expr? returns, + string? type_comment) + | AsyncFunctionDef(identifier name, arguments args, + stmt* body, expr* decorator_list, expr? returns, + string? type_comment) + + | ClassDef(identifier name, + expr* bases, + keyword* keywords, + stmt* body, + expr* decorator_list) + | Return(expr? value) + + | Delete(expr* targets) + | Assign(expr* targets, expr value, string? type_comment) + | AugAssign(expr target, operator op, expr value) + -- 'simple' indicates that we annotate simple name without parens + | AnnAssign(expr target, expr annotation, expr? value, int simple) + + -- use 'orelse' because else is a keyword in target languages + | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment) + | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment) + | While(expr test, stmt* body, stmt* orelse) + | If(expr test, stmt* body, stmt* orelse) + | With(withitem* items, stmt* body, string? type_comment) + | AsyncWith(withitem* items, stmt* body, string? type_comment) + + | Raise(expr? exc, expr? cause) + | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) + | Assert(expr test, expr? msg) + + | Import(alias* names) + | ImportFrom(identifier? module, alias* names, int? level) + + | Global(identifier* names) + | Nonlocal(identifier* names) + | Expr(expr value) + | Pass | Break | Continue + + -- XXX Jython will be different + -- col_offset is the byte offset in the utf8 string the parser uses + attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) + + -- BoolOp() can use left & right? + expr = BoolOp(boolop op, expr* values) + | NamedExpr(expr target, expr value) + | BinOp(expr left, operator op, expr right) + | UnaryOp(unaryop op, expr operand) + | Lambda(arguments args, expr body) + | IfExp(expr test, expr body, expr orelse) + | Dict(expr* keys, expr* values) + | Set(expr* elts) + | ListComp(expr elt, comprehension* generators) + | SetComp(expr elt, comprehension* generators) + | DictComp(expr key, expr value, comprehension* generators) + | GeneratorExp(expr elt, comprehension* generators) + -- the grammar constrains where yield expressions can occur + | Await(expr value) + | Yield(expr? value) + | YieldFrom(expr value) + -- need sequences for compare to distinguish between + -- x < 4 < 3 and (x < 4) < 3 + | Compare(expr left, cmpop* ops, expr* comparators) + | Call(expr func, expr* args, keyword* keywords) + | FormattedValue(expr value, int? conversion, expr? format_spec) + | JoinedStr(expr* values) + | Constant(constant value, string? kind) + + -- the following expression can appear in assignment context + | Attribute(expr value, identifier attr, expr_context ctx) + | Subscript(expr value, slice slice, expr_context ctx) + | Starred(expr value, expr_context ctx) + | Name(identifier id, expr_context ctx) + | List(expr* elts, expr_context ctx) + | Tuple(expr* elts, expr_context ctx) + + -- col_offset is the byte offset in the utf8 string the parser uses + attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) + + expr_context = Load | Store | Del | AugLoad | AugStore | Param + + slice = Slice(expr? lower, expr? upper, expr? step) + | ExtSlice(slice* dims) + | Index(expr value) + + boolop = And | Or + + operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift + | RShift | BitOr | BitXor | BitAnd | FloorDiv + + unaryop = Invert | Not | UAdd | USub + + cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn + + comprehension = (expr target, expr iter, expr* ifs, int is_async) + + excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body) + attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) + + arguments = (arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, + expr* kw_defaults, arg? kwarg, expr* defaults) + + arg = (identifier arg, expr? annotation, string? type_comment) + attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset) + + -- keyword arguments supplied to call (NULL identifier for **kwargs) + keyword = (identifier? arg, expr value) + + -- import name with optional 'as' alias. + alias = (identifier name, identifier? asname) + + withitem = (expr context_expr, expr? optional_vars) + + type_ignore = TypeIgnore(int lineno, string tag) +} diff --git a/python/Parser/acceler.c b/python/Parser/acceler.c new file mode 100755 index 0000000..e515833 --- /dev/null +++ b/python/Parser/acceler.c @@ -0,0 +1,123 @@ + +/* Parser accelerator module */ + +/* The parser as originally conceived had disappointing performance. + This module does some precomputation that speeds up the selection + of a DFA based upon a token, turning a search through an array + into a simple indexing operation. The parser now cannot work + without the accelerators installed. Note that the accelerators + are installed dynamically when the parser is initialized, they + are not part of the static data structure written on graminit.[ch] + by the parser generator. */ + +#include "Python.h" +#include "grammar.h" +#include "node.h" +#include "token.h" +#include "parser.h" + +/* Forward references */ +static void fixdfa(grammar *, const dfa *); +static void fixstate(grammar *, state *); + +void +PyGrammar_AddAccelerators(grammar *g) +{ + int i; + const dfa *d = g->g_dfa; + for (i = g->g_ndfas; --i >= 0; d++) + fixdfa(g, d); + g->g_accel = 1; +} + +void +PyGrammar_RemoveAccelerators(grammar *g) +{ + int i; + g->g_accel = 0; + const dfa *d = g->g_dfa; + for (i = g->g_ndfas; --i >= 0; d++) { + state *s; + int j; + s = d->d_state; + for (j = 0; j < d->d_nstates; j++, s++) { + if (s->s_accel) + PyObject_FREE(s->s_accel); + s->s_accel = NULL; + } + } +} + +static void +fixdfa(grammar *g, const dfa *d) +{ + state *s; + int j; + s = d->d_state; + for (j = 0; j < d->d_nstates; j++, s++) + fixstate(g, s); +} + +static void +fixstate(grammar *g, state *s) +{ + const arc *a; + int k; + int *accel; + int nl = g->g_ll.ll_nlabels; + s->s_accept = 0; + accel = (int *) PyObject_MALLOC(nl * sizeof(int)); + if (accel == NULL) { + fprintf(stderr, "no mem to build parser accelerators\n"); + exit(1); + } + for (k = 0; k < nl; k++) + accel[k] = -1; + a = s->s_arc; + for (k = s->s_narcs; --k >= 0; a++) { + int lbl = a->a_lbl; + const label *l = &g->g_ll.ll_label[lbl]; + int type = l->lb_type; + if (a->a_arrow >= (1 << 7)) { + printf("XXX too many states!\n"); + continue; + } + if (ISNONTERMINAL(type)) { + const dfa *d1 = PyGrammar_FindDFA(g, type); + int ibit; + if (type - NT_OFFSET >= (1 << 7)) { + printf("XXX too high nonterminal number!\n"); + continue; + } + for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) { + if (testbit(d1->d_first, ibit)) { + if (accel[ibit] != -1) + printf("XXX ambiguity!\n"); + accel[ibit] = a->a_arrow | (1 << 7) | + ((type - NT_OFFSET) << 8); + } + } + } + else if (lbl == EMPTY) + s->s_accept = 1; + else if (lbl >= 0 && lbl < nl) + accel[lbl] = a->a_arrow; + } + while (nl > 0 && accel[nl-1] == -1) + nl--; + for (k = 0; k < nl && accel[k] == -1;) + k++; + if (k < nl) { + int i; + s->s_accel = (int *) PyObject_MALLOC((nl-k) * sizeof(int)); + if (s->s_accel == NULL) { + fprintf(stderr, "no mem to add parser accelerators\n"); + exit(1); + } + s->s_lower = k; + s->s_upper = nl; + for (i = 0; k < nl; i++, k++) + s->s_accel[i] = accel[k]; + } + PyObject_FREE(accel); +} diff --git a/python/Parser/asdl.py b/python/Parser/asdl.py new file mode 100755 index 0000000..62f5c19 --- /dev/null +++ b/python/Parser/asdl.py @@ -0,0 +1,376 @@ +#------------------------------------------------------------------------------- +# Parser for ASDL [1] definition files. Reads in an ASDL description and parses +# it into an AST that describes it. +# +# The EBNF we're parsing here: Figure 1 of the paper [1]. Extended to support +# modules and attributes after a product. Words starting with Capital letters +# are terminals. Literal tokens are in "double quotes". Others are +# non-terminals. Id is either TokenId or ConstructorId. +# +# module ::= "module" Id "{" [definitions] "}" +# definitions ::= { TypeId "=" type } +# type ::= product | sum +# product ::= fields ["attributes" fields] +# fields ::= "(" { field, "," } field ")" +# field ::= TypeId ["?" | "*"] [Id] +# sum ::= constructor { "|" constructor } ["attributes" fields] +# constructor ::= ConstructorId [fields] +# +# [1] "The Zephyr Abstract Syntax Description Language" by Wang, et. al. See +# http://asdl.sourceforge.net/ +#------------------------------------------------------------------------------- +from collections import namedtuple +import re + +__all__ = [ + 'builtin_types', 'parse', 'AST', 'Module', 'Type', 'Constructor', + 'Field', 'Sum', 'Product', 'VisitorBase', 'Check', 'check'] + +# The following classes define nodes into which the ASDL description is parsed. +# Note: this is a "meta-AST". ASDL files (such as Python.asdl) describe the AST +# structure used by a programming language. But ASDL files themselves need to be +# parsed. This module parses ASDL files and uses a simple AST to represent them. +# See the EBNF at the top of the file to understand the logical connection +# between the various node types. + +builtin_types = {'identifier', 'string', 'bytes', 'int', 'object', 'singleton', + 'constant'} + +class AST: + def __repr__(self): + raise NotImplementedError + +class Module(AST): + def __init__(self, name, dfns): + self.name = name + self.dfns = dfns + self.types = {type.name: type.value for type in dfns} + + def __repr__(self): + return 'Module({0.name}, {0.dfns})'.format(self) + +class Type(AST): + def __init__(self, name, value): + self.name = name + self.value = value + + def __repr__(self): + return 'Type({0.name}, {0.value})'.format(self) + +class Constructor(AST): + def __init__(self, name, fields=None): + self.name = name + self.fields = fields or [] + + def __repr__(self): + return 'Constructor({0.name}, {0.fields})'.format(self) + +class Field(AST): + def __init__(self, type, name=None, seq=False, opt=False): + self.type = type + self.name = name + self.seq = seq + self.opt = opt + + def __repr__(self): + if self.seq: + extra = ", seq=True" + elif self.opt: + extra = ", opt=True" + else: + extra = "" + if self.name is None: + return 'Field({0.type}{1})'.format(self, extra) + else: + return 'Field({0.type}, {0.name}{1})'.format(self, extra) + +class Sum(AST): + def __init__(self, types, attributes=None): + self.types = types + self.attributes = attributes or [] + + def __repr__(self): + if self.attributes: + return 'Sum({0.types}, {0.attributes})'.format(self) + else: + return 'Sum({0.types})'.format(self) + +class Product(AST): + def __init__(self, fields, attributes=None): + self.fields = fields + self.attributes = attributes or [] + + def __repr__(self): + if self.attributes: + return 'Product({0.fields}, {0.attributes})'.format(self) + else: + return 'Product({0.fields})'.format(self) + +# A generic visitor for the meta-AST that describes ASDL. This can be used by +# emitters. Note that this visitor does not provide a generic visit method, so a +# subclass needs to define visit methods from visitModule to as deep as the +# interesting node. +# We also define a Check visitor that makes sure the parsed ASDL is well-formed. + +class VisitorBase(object): + """Generic tree visitor for ASTs.""" + def __init__(self): + self.cache = {} + + def visit(self, obj, *args): + klass = obj.__class__ + meth = self.cache.get(klass) + if meth is None: + methname = "visit" + klass.__name__ + meth = getattr(self, methname, None) + self.cache[klass] = meth + if meth: + try: + meth(obj, *args) + except Exception as e: + print("Error visiting %r: %s" % (obj, e)) + raise + +class Check(VisitorBase): + """A visitor that checks a parsed ASDL tree for correctness. + + Errors are printed and accumulated. + """ + def __init__(self): + super(Check, self).__init__() + self.cons = {} + self.errors = 0 + self.types = {} + + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type): + self.visit(type.value, str(type.name)) + + def visitSum(self, sum, name): + for t in sum.types: + self.visit(t, name) + + def visitConstructor(self, cons, name): + key = str(cons.name) + conflict = self.cons.get(key) + if conflict is None: + self.cons[key] = name + else: + print('Redefinition of constructor {}'.format(key)) + print('Defined in {} and {}'.format(conflict, name)) + self.errors += 1 + for f in cons.fields: + self.visit(f, key) + + def visitField(self, field, name): + key = str(field.type) + l = self.types.setdefault(key, []) + l.append(name) + + def visitProduct(self, prod, name): + for f in prod.fields: + self.visit(f, name) + +def check(mod): + """Check the parsed ASDL tree for correctness. + + Return True if success. For failure, the errors are printed out and False + is returned. + """ + v = Check() + v.visit(mod) + + for t in v.types: + if t not in mod.types and not t in builtin_types: + v.errors += 1 + uses = ", ".join(v.types[t]) + print('Undefined type {}, used in {}'.format(t, uses)) + return not v.errors + +# The ASDL parser itself comes next. The only interesting external interface +# here is the top-level parse function. + +def parse(filename): + """Parse ASDL from the given file and return a Module node describing it.""" + with open(filename) as f: + parser = ASDLParser() + return parser.parse(f.read()) + +# Types for describing tokens in an ASDL specification. +class TokenKind: + """TokenKind is provides a scope for enumerated token kinds.""" + (ConstructorId, TypeId, Equals, Comma, Question, Pipe, Asterisk, + LParen, RParen, LBrace, RBrace) = range(11) + + operator_table = { + '=': Equals, ',': Comma, '?': Question, '|': Pipe, '(': LParen, + ')': RParen, '*': Asterisk, '{': LBrace, '}': RBrace} + +Token = namedtuple('Token', 'kind value lineno') + +class ASDLSyntaxError(Exception): + def __init__(self, msg, lineno=None): + self.msg = msg + self.lineno = lineno or '' + + def __str__(self): + return 'Syntax error on line {0.lineno}: {0.msg}'.format(self) + +def tokenize_asdl(buf): + """Tokenize the given buffer. Yield Token objects.""" + for lineno, line in enumerate(buf.splitlines(), 1): + for m in re.finditer(r'\s*(\w+|--.*|.)', line.strip()): + c = m.group(1) + if c[0].isalpha(): + # Some kind of identifier + if c[0].isupper(): + yield Token(TokenKind.ConstructorId, c, lineno) + else: + yield Token(TokenKind.TypeId, c, lineno) + elif c[:2] == '--': + # Comment + break + else: + # Operators + try: + op_kind = TokenKind.operator_table[c] + except KeyError: + raise ASDLSyntaxError('Invalid operator %s' % c, lineno) + yield Token(op_kind, c, lineno) + +class ASDLParser: + """Parser for ASDL files. + + Create, then call the parse method on a buffer containing ASDL. + This is a simple recursive descent parser that uses tokenize_asdl for the + lexing. + """ + def __init__(self): + self._tokenizer = None + self.cur_token = None + + def parse(self, buf): + """Parse the ASDL in the buffer and return an AST with a Module root. + """ + self._tokenizer = tokenize_asdl(buf) + self._advance() + return self._parse_module() + + def _parse_module(self): + if self._at_keyword('module'): + self._advance() + else: + raise ASDLSyntaxError( + 'Expected "module" (found {})'.format(self.cur_token.value), + self.cur_token.lineno) + name = self._match(self._id_kinds) + self._match(TokenKind.LBrace) + defs = self._parse_definitions() + self._match(TokenKind.RBrace) + return Module(name, defs) + + def _parse_definitions(self): + defs = [] + while self.cur_token.kind == TokenKind.TypeId: + typename = self._advance() + self._match(TokenKind.Equals) + type = self._parse_type() + defs.append(Type(typename, type)) + return defs + + def _parse_type(self): + if self.cur_token.kind == TokenKind.LParen: + # If we see a (, it's a product + return self._parse_product() + else: + # Otherwise it's a sum. Look for ConstructorId + sumlist = [Constructor(self._match(TokenKind.ConstructorId), + self._parse_optional_fields())] + while self.cur_token.kind == TokenKind.Pipe: + # More constructors + self._advance() + sumlist.append(Constructor( + self._match(TokenKind.ConstructorId), + self._parse_optional_fields())) + return Sum(sumlist, self._parse_optional_attributes()) + + def _parse_product(self): + return Product(self._parse_fields(), self._parse_optional_attributes()) + + def _parse_fields(self): + fields = [] + self._match(TokenKind.LParen) + while self.cur_token.kind == TokenKind.TypeId: + typename = self._advance() + is_seq, is_opt = self._parse_optional_field_quantifier() + id = (self._advance() if self.cur_token.kind in self._id_kinds + else None) + fields.append(Field(typename, id, seq=is_seq, opt=is_opt)) + if self.cur_token.kind == TokenKind.RParen: + break + elif self.cur_token.kind == TokenKind.Comma: + self._advance() + self._match(TokenKind.RParen) + return fields + + def _parse_optional_fields(self): + if self.cur_token.kind == TokenKind.LParen: + return self._parse_fields() + else: + return None + + def _parse_optional_attributes(self): + if self._at_keyword('attributes'): + self._advance() + return self._parse_fields() + else: + return None + + def _parse_optional_field_quantifier(self): + is_seq, is_opt = False, False + if self.cur_token.kind == TokenKind.Asterisk: + is_seq = True + self._advance() + elif self.cur_token.kind == TokenKind.Question: + is_opt = True + self._advance() + return is_seq, is_opt + + def _advance(self): + """ Return the value of the current token and read the next one into + self.cur_token. + """ + cur_val = None if self.cur_token is None else self.cur_token.value + try: + self.cur_token = next(self._tokenizer) + except StopIteration: + self.cur_token = None + return cur_val + + _id_kinds = (TokenKind.ConstructorId, TokenKind.TypeId) + + def _match(self, kind): + """The 'match' primitive of RD parsers. + + * Verifies that the current token is of the given kind (kind can + be a tuple, in which the kind must match one of its members). + * Returns the value of the current token + * Reads in the next token + """ + if (isinstance(kind, tuple) and self.cur_token.kind in kind or + self.cur_token.kind == kind + ): + value = self.cur_token.value + self._advance() + return value + else: + raise ASDLSyntaxError( + 'Unmatched {} (found {})'.format(kind, self.cur_token.kind), + self.cur_token.lineno) + + def _at_keyword(self, keyword): + return (self.cur_token.kind == TokenKind.TypeId and + self.cur_token.value == keyword) diff --git a/python/Parser/asdl_c.py b/python/Parser/asdl_c.py new file mode 100755 index 0000000..a708b66 --- /dev/null +++ b/python/Parser/asdl_c.py @@ -0,0 +1,1348 @@ +#! /usr/bin/env python +"""Generate C code from an ASDL description.""" + +import os, sys + +import asdl + +TABSIZE = 4 +MAX_COL = 80 + +def get_c_type(name): + """Return a string for the C name of the type. + + This function special cases the default types provided by asdl. + """ + if name in asdl.builtin_types: + return name + else: + return "%s_ty" % name + +def reflow_lines(s, depth): + """Reflow the line s indented depth tabs. + + Return a sequence of lines where no line extends beyond MAX_COL + when properly indented. The first line is properly indented based + exclusively on depth * TABSIZE. All following lines -- these are + the reflowed lines generated by this function -- start at the same + column as the first character beyond the opening { in the first + line. + """ + size = MAX_COL - depth * TABSIZE + if len(s) < size: + return [s] + + lines = [] + cur = s + padding = "" + while len(cur) > size: + i = cur.rfind(' ', 0, size) + # XXX this should be fixed for real + if i == -1 and 'GeneratorExp' in cur: + i = size + 3 + assert i != -1, "Impossible line %d to reflow: %r" % (size, s) + lines.append(padding + cur[:i]) + if len(lines) == 1: + # find new size based on brace + j = cur.find('{', 0, i) + if j >= 0: + j += 2 # account for the brace and the space after it + size -= j + padding = " " * j + else: + j = cur.find('(', 0, i) + if j >= 0: + j += 1 # account for the paren (no space after it) + size -= j + padding = " " * j + cur = cur[i+1:] + else: + lines.append(padding + cur) + return lines + +def is_simple(sum): + """Return True if a sum is a simple. + + A sum is simple if its types have no fields, e.g. + unaryop = Invert | Not | UAdd | USub + """ + for t in sum.types: + if t.fields: + return False + return True + + +class EmitVisitor(asdl.VisitorBase): + """Visit that emits lines""" + + def __init__(self, file): + self.file = file + self.identifiers = set() + super(EmitVisitor, self).__init__() + + def emit_identifier(self, name): + name = str(name) + if name in self.identifiers: + return + self.emit("_Py_IDENTIFIER(%s);" % name, 0) + self.identifiers.add(name) + + def emit(self, s, depth, reflow=True): + # XXX reflow long lines? + if reflow: + lines = reflow_lines(s, depth) + else: + lines = [s] + for line in lines: + if line: + line = (" " * TABSIZE * depth) + line + self.file.write(line + "\n") + + +class TypeDefVisitor(EmitVisitor): + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type, depth=0): + self.visit(type.value, type.name, depth) + + def visitSum(self, sum, name, depth): + if is_simple(sum): + self.simple_sum(sum, name, depth) + else: + self.sum_with_constructors(sum, name, depth) + + def simple_sum(self, sum, name, depth): + enum = [] + for i in range(len(sum.types)): + type = sum.types[i] + enum.append("%s=%d" % (type.name, i + 1)) + enums = ", ".join(enum) + ctype = get_c_type(name) + s = "typedef enum _%s { %s } %s;" % (name, enums, ctype) + self.emit(s, depth) + self.emit("", depth) + + def sum_with_constructors(self, sum, name, depth): + ctype = get_c_type(name) + s = "typedef struct _%(name)s *%(ctype)s;" % locals() + self.emit(s, depth) + self.emit("", depth) + + def visitProduct(self, product, name, depth): + ctype = get_c_type(name) + s = "typedef struct _%(name)s *%(ctype)s;" % locals() + self.emit(s, depth) + self.emit("", depth) + + +class StructVisitor(EmitVisitor): + """Visitor to generate typedefs for AST.""" + + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type, depth=0): + self.visit(type.value, type.name, depth) + + def visitSum(self, sum, name, depth): + if not is_simple(sum): + self.sum_with_constructors(sum, name, depth) + + def sum_with_constructors(self, sum, name, depth): + def emit(s, depth=depth): + self.emit(s % sys._getframe(1).f_locals, depth) + enum = [] + for i in range(len(sum.types)): + type = sum.types[i] + enum.append("%s_kind=%d" % (type.name, i + 1)) + + emit("enum _%(name)s_kind {" + ", ".join(enum) + "};") + + emit("struct _%(name)s {") + emit("enum _%(name)s_kind kind;", depth + 1) + emit("union {", depth + 1) + for t in sum.types: + self.visit(t, depth + 2) + emit("} v;", depth + 1) + for field in sum.attributes: + # rudimentary attribute handling + type = str(field.type) + assert type in asdl.builtin_types, type + emit("%s %s;" % (type, field.name), depth + 1); + emit("};") + emit("") + + def visitConstructor(self, cons, depth): + if cons.fields: + self.emit("struct {", depth) + for f in cons.fields: + self.visit(f, depth + 1) + self.emit("} %s;" % cons.name, depth) + self.emit("", depth) + + def visitField(self, field, depth): + # XXX need to lookup field.type, because it might be something + # like a builtin... + ctype = get_c_type(field.type) + name = field.name + if field.seq: + if field.type == 'cmpop': + self.emit("asdl_int_seq *%(name)s;" % locals(), depth) + else: + self.emit("asdl_seq *%(name)s;" % locals(), depth) + else: + self.emit("%(ctype)s %(name)s;" % locals(), depth) + + def visitProduct(self, product, name, depth): + self.emit("struct _%(name)s {" % locals(), depth) + for f in product.fields: + self.visit(f, depth + 1) + for field in product.attributes: + # rudimentary attribute handling + type = str(field.type) + assert type in asdl.builtin_types, type + self.emit("%s %s;" % (type, field.name), depth + 1); + self.emit("};", depth) + self.emit("", depth) + + +class PrototypeVisitor(EmitVisitor): + """Generate function prototypes for the .h file""" + + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type): + self.visit(type.value, type.name) + + def visitSum(self, sum, name): + if is_simple(sum): + pass # XXX + else: + for t in sum.types: + self.visit(t, name, sum.attributes) + + def get_args(self, fields): + """Return list of C argument into, one for each field. + + Argument info is 3-tuple of a C type, variable name, and flag + that is true if type can be NULL. + """ + args = [] + unnamed = {} + for f in fields: + if f.name is None: + name = f.type + c = unnamed[name] = unnamed.get(name, 0) + 1 + if c > 1: + name = "name%d" % (c - 1) + else: + name = f.name + # XXX should extend get_c_type() to handle this + if f.seq: + if f.type == 'cmpop': + ctype = "asdl_int_seq *" + else: + ctype = "asdl_seq *" + else: + ctype = get_c_type(f.type) + args.append((ctype, name, f.opt or f.seq)) + return args + + def visitConstructor(self, cons, type, attrs): + args = self.get_args(cons.fields) + attrs = self.get_args(attrs) + ctype = get_c_type(type) + self.emit_function(cons.name, ctype, args, attrs) + + def emit_function(self, name, ctype, args, attrs, union=True): + args = args + attrs + if args: + argstr = ", ".join(["%s %s" % (atype, aname) + for atype, aname, opt in args]) + argstr += ", PyArena *arena" + else: + argstr = "PyArena *arena" + margs = "a0" + for i in range(1, len(args)+1): + margs += ", a%d" % i + self.emit("#define %s(%s) _Py_%s(%s)" % (name, margs, name, margs), 0, + reflow=False) + self.emit("%s _Py_%s(%s);" % (ctype, name, argstr), False) + + def visitProduct(self, prod, name): + self.emit_function(name, get_c_type(name), + self.get_args(prod.fields), + self.get_args(prod.attributes), + union=False) + + +class FunctionVisitor(PrototypeVisitor): + """Visitor to generate constructor functions for AST.""" + + def emit_function(self, name, ctype, args, attrs, union=True): + def emit(s, depth=0, reflow=True): + self.emit(s, depth, reflow) + argstr = ", ".join(["%s %s" % (atype, aname) + for atype, aname, opt in args + attrs]) + if argstr: + argstr += ", PyArena *arena" + else: + argstr = "PyArena *arena" + self.emit("%s" % ctype, 0) + emit("%s(%s)" % (name, argstr)) + emit("{") + emit("%s p;" % ctype, 1) + for argtype, argname, opt in args: + if not opt and argtype != "int": + emit("if (!%s) {" % argname, 1) + emit("PyErr_SetString(PyExc_ValueError,", 2) + msg = "field %s is required for %s" % (argname, name) + emit(' "%s");' % msg, + 2, reflow=False) + emit('return NULL;', 2) + emit('}', 1) + + emit("p = (%s)PyArena_Malloc(arena, sizeof(*p));" % ctype, 1); + emit("if (!p)", 1) + emit("return NULL;", 2) + if union: + self.emit_body_union(name, args, attrs) + else: + self.emit_body_struct(name, args, attrs) + emit("return p;", 1) + emit("}") + emit("") + + def emit_body_union(self, name, args, attrs): + def emit(s, depth=0, reflow=True): + self.emit(s, depth, reflow) + emit("p->kind = %s_kind;" % name, 1) + for argtype, argname, opt in args: + emit("p->v.%s.%s = %s;" % (name, argname, argname), 1) + for argtype, argname, opt in attrs: + emit("p->%s = %s;" % (argname, argname), 1) + + def emit_body_struct(self, name, args, attrs): + def emit(s, depth=0, reflow=True): + self.emit(s, depth, reflow) + for argtype, argname, opt in args: + emit("p->%s = %s;" % (argname, argname), 1) + for argtype, argname, opt in attrs: + emit("p->%s = %s;" % (argname, argname), 1) + + +class PickleVisitor(EmitVisitor): + + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type): + self.visit(type.value, type.name) + + def visitSum(self, sum, name): + pass + + def visitProduct(self, sum, name): + pass + + def visitConstructor(self, cons, name): + pass + + def visitField(self, sum): + pass + + +class Obj2ModPrototypeVisitor(PickleVisitor): + def visitProduct(self, prod, name): + code = "static int obj2ast_%s(PyObject* obj, %s* out, PyArena* arena);" + self.emit(code % (name, get_c_type(name)), 0) + + visitSum = visitProduct + + +class Obj2ModVisitor(PickleVisitor): + def funcHeader(self, name): + ctype = get_c_type(name) + self.emit("int", 0) + self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) + self.emit("{", 0) + self.emit("int isinstance;", 1) + self.emit("", 0) + + def sumTrailer(self, name, add_label=False): + self.emit("", 0) + # there's really nothing more we can do if this fails ... + error = "expected some sort of %s, but got %%R" % name + format = "PyErr_Format(PyExc_TypeError, \"%s\", obj);" + self.emit(format % error, 1, reflow=False) + if add_label: + self.emit("failed:", 1) + self.emit("Py_XDECREF(tmp);", 1) + self.emit("return 1;", 1) + self.emit("}", 0) + self.emit("", 0) + + def simpleSum(self, sum, name): + self.funcHeader(name) + for t in sum.types: + line = ("isinstance = PyObject_IsInstance(obj, " + "(PyObject *)%s_type);") + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) + self.emit("*out = %s;" % t.name, 2) + self.emit("return 0;", 2) + self.emit("}", 1) + self.sumTrailer(name) + + def buildArgs(self, fields): + return ", ".join(fields + ["arena"]) + + def complexSum(self, sum, name): + self.funcHeader(name) + self.emit("PyObject *tmp = NULL;", 1) + for a in sum.attributes: + self.visitAttributeDeclaration(a, name, sum=sum) + self.emit("", 0) + # XXX: should we only do this for 'expr'? + self.emit("if (obj == Py_None) {", 1) + self.emit("*out = NULL;", 2) + self.emit("return 0;", 2) + self.emit("}", 1) + for a in sum.attributes: + self.visitField(a, name, sum=sum, depth=1) + for t in sum.types: + line = "isinstance = PyObject_IsInstance(obj, (PyObject*)%s_type);" + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) + for f in t.fields: + self.visitFieldDeclaration(f, t.name, sum=sum, depth=2) + self.emit("", 0) + for f in t.fields: + self.visitField(f, t.name, sum=sum, depth=2) + args = [f.name for f in t.fields] + [a.name for a in sum.attributes] + self.emit("*out = %s(%s);" % (t.name, self.buildArgs(args)), 2) + self.emit("if (*out == NULL) goto failed;", 2) + self.emit("return 0;", 2) + self.emit("}", 1) + self.sumTrailer(name, True) + + def visitAttributeDeclaration(self, a, name, sum=sum): + ctype = get_c_type(a.type) + self.emit("%s %s;" % (ctype, a.name), 1) + + def visitSum(self, sum, name): + if is_simple(sum): + self.simpleSum(sum, name) + else: + self.complexSum(sum, name) + + def visitProduct(self, prod, name): + ctype = get_c_type(name) + self.emit("int", 0) + self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) + self.emit("{", 0) + self.emit("PyObject* tmp = NULL;", 1) + for f in prod.fields: + self.visitFieldDeclaration(f, name, prod=prod, depth=1) + for a in prod.attributes: + self.visitFieldDeclaration(a, name, prod=prod, depth=1) + self.emit("", 0) + for f in prod.fields: + self.visitField(f, name, prod=prod, depth=1) + for a in prod.attributes: + self.visitField(a, name, prod=prod, depth=1) + args = [f.name for f in prod.fields] + args.extend([a.name for a in prod.attributes]) + self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1) + self.emit("return 0;", 1) + self.emit("failed:", 0) + self.emit("Py_XDECREF(tmp);", 1) + self.emit("return 1;", 1) + self.emit("}", 0) + self.emit("", 0) + + def visitFieldDeclaration(self, field, name, sum=None, prod=None, depth=0): + ctype = get_c_type(field.type) + if field.seq: + if self.isSimpleType(field): + self.emit("asdl_int_seq* %s;" % field.name, depth) + else: + self.emit("asdl_seq* %s;" % field.name, depth) + else: + ctype = get_c_type(field.type) + self.emit("%s %s;" % (ctype, field.name), depth) + + def isSimpleSum(self, field): + # XXX can the members of this list be determined automatically? + return field.type in ('expr_context', 'boolop', 'operator', + 'unaryop', 'cmpop') + + def isNumeric(self, field): + return get_c_type(field.type) in ("int", "bool") + + def isSimpleType(self, field): + return self.isSimpleSum(field) or self.isNumeric(field) + + def visitField(self, field, name, sum=None, prod=None, depth=0): + ctype = get_c_type(field.type) + self.emit("if (_PyObject_LookupAttrId(obj, &PyId_%s, &tmp) < 0) {" % field.name, depth) + self.emit("return 1;", depth+1) + self.emit("}", depth) + if not field.opt: + self.emit("if (tmp == NULL) {", depth) + message = "required field \\\"%s\\\" missing from %s" % (field.name, name) + format = "PyErr_SetString(PyExc_TypeError, \"%s\");" + self.emit(format % message, depth+1, reflow=False) + self.emit("return 1;", depth+1) + else: + self.emit("if (tmp == NULL || tmp == Py_None) {", depth) + self.emit("Py_CLEAR(tmp);", depth+1) + if self.isNumeric(field): + self.emit("%s = 0;" % field.name, depth+1) + elif not self.isSimpleType(field): + self.emit("%s = NULL;" % field.name, depth+1) + else: + raise TypeError("could not determine the default value for %s" % field.name) + self.emit("}", depth) + self.emit("else {", depth) + + self.emit("int res;", depth+1) + if field.seq: + self.emit("Py_ssize_t len;", depth+1) + self.emit("Py_ssize_t i;", depth+1) + self.emit("if (!PyList_Check(tmp)) {", depth+1) + self.emit("PyErr_Format(PyExc_TypeError, \"%s field \\\"%s\\\" must " + "be a list, not a %%.200s\", tmp->ob_type->tp_name);" % + (name, field.name), + depth+2, reflow=False) + self.emit("goto failed;", depth+2) + self.emit("}", depth+1) + self.emit("len = PyList_GET_SIZE(tmp);", depth+1) + if self.isSimpleType(field): + self.emit("%s = _Py_asdl_int_seq_new(len, arena);" % field.name, depth+1) + else: + self.emit("%s = _Py_asdl_seq_new(len, arena);" % field.name, depth+1) + self.emit("if (%s == NULL) goto failed;" % field.name, depth+1) + self.emit("for (i = 0; i < len; i++) {", depth+1) + self.emit("%s val;" % ctype, depth+2) + self.emit("res = obj2ast_%s(PyList_GET_ITEM(tmp, i), &val, arena);" % + field.type, depth+2, reflow=False) + self.emit("if (res != 0) goto failed;", depth+2) + self.emit("if (len != PyList_GET_SIZE(tmp)) {", depth+2) + self.emit("PyErr_SetString(PyExc_RuntimeError, \"%s field \\\"%s\\\" " + "changed size during iteration\");" % + (name, field.name), + depth+3, reflow=False) + self.emit("goto failed;", depth+3) + self.emit("}", depth+2) + self.emit("asdl_seq_SET(%s, i, val);" % field.name, depth+2) + self.emit("}", depth+1) + else: + self.emit("res = obj2ast_%s(tmp, &%s, arena);" % + (field.type, field.name), depth+1) + self.emit("if (res != 0) goto failed;", depth+1) + + self.emit("Py_CLEAR(tmp);", depth+1) + self.emit("}", depth) + + +class MarshalPrototypeVisitor(PickleVisitor): + + def prototype(self, sum, name): + ctype = get_c_type(name) + self.emit("static int marshal_write_%s(PyObject **, int *, %s);" + % (name, ctype), 0) + + visitProduct = visitSum = prototype + + +class PyTypesDeclareVisitor(PickleVisitor): + + def visitProduct(self, prod, name): + self.emit("static PyTypeObject *%s_type;" % name, 0) + self.emit("static PyObject* ast2obj_%s(void*);" % name, 0) + if prod.attributes: + for a in prod.attributes: + self.emit_identifier(a.name) + self.emit("static char *%s_attributes[] = {" % name, 0) + for a in prod.attributes: + self.emit('"%s",' % a.name, 1) + self.emit("};", 0) + if prod.fields: + for f in prod.fields: + self.emit_identifier(f.name) + self.emit("static char *%s_fields[]={" % name,0) + for f in prod.fields: + self.emit('"%s",' % f.name, 1) + self.emit("};", 0) + + def visitSum(self, sum, name): + self.emit("static PyTypeObject *%s_type;" % name, 0) + if sum.attributes: + for a in sum.attributes: + self.emit_identifier(a.name) + self.emit("static char *%s_attributes[] = {" % name, 0) + for a in sum.attributes: + self.emit('"%s",' % a.name, 1) + self.emit("};", 0) + ptype = "void*" + if is_simple(sum): + ptype = get_c_type(name) + tnames = [] + for t in sum.types: + tnames.append(str(t.name)+"_singleton") + tnames = ", *".join(tnames) + self.emit("static PyObject *%s;" % tnames, 0) + self.emit("static PyObject* ast2obj_%s(%s);" % (name, ptype), 0) + for t in sum.types: + self.visitConstructor(t, name) + + def visitConstructor(self, cons, name): + self.emit("static PyTypeObject *%s_type;" % cons.name, 0) + if cons.fields: + for t in cons.fields: + self.emit_identifier(t.name) + self.emit("static char *%s_fields[]={" % cons.name, 0) + for t in cons.fields: + self.emit('"%s",' % t.name, 1) + self.emit("};",0) + +class PyTypesVisitor(PickleVisitor): + + def visitModule(self, mod): + self.emit(""" +_Py_IDENTIFIER(_fields); +_Py_IDENTIFIER(_attributes); + +typedef struct { + PyObject_HEAD + PyObject *dict; +} AST_object; + +static void +ast_dealloc(AST_object *self) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free(self); +} + +static int +ast_traverse(AST_object *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +ast_clear(AST_object *self) +{ + Py_CLEAR(self->dict); + return 0; +} + +static int +ast_type_init(PyObject *self, PyObject *args, PyObject *kw) +{ + Py_ssize_t i, numfields = 0; + int res = -1; + PyObject *key, *value, *fields; + if (_PyObject_LookupAttrId((PyObject*)Py_TYPE(self), &PyId__fields, &fields) < 0) { + goto cleanup; + } + if (fields) { + numfields = PySequence_Size(fields); + if (numfields == -1) { + goto cleanup; + } + } + + res = 0; /* if no error occurs, this stays 0 to the end */ + if (numfields < PyTuple_GET_SIZE(args)) { + PyErr_Format(PyExc_TypeError, "%.400s constructor takes at most " + "%zd positional argument%s", + Py_TYPE(self)->tp_name, + numfields, numfields == 1 ? "" : "s"); + res = -1; + goto cleanup; + } + for (i = 0; i < PyTuple_GET_SIZE(args); i++) { + /* cannot be reached when fields is NULL */ + PyObject *name = PySequence_GetItem(fields, i); + if (!name) { + res = -1; + goto cleanup; + } + res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i)); + Py_DECREF(name); + if (res < 0) { + goto cleanup; + } + } + if (kw) { + i = 0; /* needed by PyDict_Next */ + while (PyDict_Next(kw, &i, &key, &value)) { + int contains = PySequence_Contains(fields, key); + if (contains == -1) { + res = -1; + goto cleanup; + } else if (contains == 1) { + Py_ssize_t p = PySequence_Index(fields, key); + if (p == -1) { + res = -1; + goto cleanup; + } + if (p < PyTuple_GET_SIZE(args)) { + PyErr_Format(PyExc_TypeError, + "%.400s got multiple values for argument '%U'", + Py_TYPE(self)->tp_name, key); + res = -1; + goto cleanup; + } + } + res = PyObject_SetAttr(self, key, value); + if (res < 0) { + goto cleanup; + } + } + } + cleanup: + Py_XDECREF(fields); + return res; +} + +/* Pickling support */ +static PyObject * +ast_type_reduce(PyObject *self, PyObject *unused) +{ + _Py_IDENTIFIER(__dict__); + PyObject *dict; + if (_PyObject_LookupAttrId(self, &PyId___dict__, &dict) < 0) { + return NULL; + } + if (dict) { + return Py_BuildValue("O()N", Py_TYPE(self), dict); + } + return Py_BuildValue("O()", Py_TYPE(self)); +} + +static PyMethodDef ast_type_methods[] = { + {"__reduce__", ast_type_reduce, METH_NOARGS, NULL}, + {NULL} +}; + +static PyGetSetDef ast_type_getsets[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} +}; + +static PyTypeObject AST_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "_ast.AST", + sizeof(AST_object), + 0, + (destructor)ast_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 */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)ast_traverse, /* tp_traverse */ + (inquiry)ast_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ast_type_methods, /* tp_methods */ + 0, /* tp_members */ + ast_type_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(AST_object, dict),/* tp_dictoffset */ + (initproc)ast_type_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields) +{ + _Py_IDENTIFIER(__module__); + _Py_IDENTIFIER(_ast); + PyObject *fnames, *result; + int i; + fnames = PyTuple_New(num_fields); + if (!fnames) return NULL; + for (i = 0; i < num_fields; i++) { + PyObject *field = PyUnicode_FromString(fields[i]); + if (!field) { + Py_DECREF(fnames); + return NULL; + } + PyTuple_SET_ITEM(fnames, i, field); + } + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOO}", + type, base, + _PyUnicode_FromId(&PyId__fields), fnames, + _PyUnicode_FromId(&PyId___module__), + _PyUnicode_FromId(&PyId__ast)); + Py_DECREF(fnames); + return (PyTypeObject*)result; +} + +static int add_attributes(PyTypeObject* type, char**attrs, int num_fields) +{ + int i, result; + PyObject *s, *l = PyTuple_New(num_fields); + if (!l) + return 0; + for (i = 0; i < num_fields; i++) { + s = PyUnicode_FromString(attrs[i]); + if (!s) { + Py_DECREF(l); + return 0; + } + PyTuple_SET_ITEM(l, i, s); + } + result = _PyObject_SetAttrId((PyObject*)type, &PyId__attributes, l) >= 0; + Py_DECREF(l); + return result; +} + +/* Conversion AST -> Python */ + +static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*)) +{ + Py_ssize_t i, n = asdl_seq_LEN(seq); + PyObject *result = PyList_New(n); + PyObject *value; + if (!result) + return NULL; + for (i = 0; i < n; i++) { + value = func(asdl_seq_GET(seq, i)); + if (!value) { + Py_DECREF(result); + return NULL; + } + PyList_SET_ITEM(result, i, value); + } + return result; +} + +static PyObject* ast2obj_object(void *o) +{ + if (!o) + o = Py_None; + Py_INCREF((PyObject*)o); + return (PyObject*)o; +} +#define ast2obj_singleton ast2obj_object +#define ast2obj_constant ast2obj_object +#define ast2obj_identifier ast2obj_object +#define ast2obj_string ast2obj_object +#define ast2obj_bytes ast2obj_object + +static PyObject* ast2obj_int(long b) +{ + return PyLong_FromLong(b); +} + +/* Conversion Python -> AST */ + +static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (obj == Py_None) + obj = NULL; + if (obj) { + if (PyArena_AddPyObject(arena, obj) < 0) { + *out = NULL; + return -1; + } + Py_INCREF(obj); + } + *out = obj; + return 0; +} + +static int obj2ast_constant(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (PyArena_AddPyObject(arena, obj) < 0) { + *out = NULL; + return -1; + } + Py_INCREF(obj); + *out = obj; + return 0; +} + +static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (!PyUnicode_CheckExact(obj) && obj != Py_None) { + PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str"); + return 1; + } + return obj2ast_object(obj, out, arena); +} + +static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) { + PyErr_SetString(PyExc_TypeError, "AST string must be of type str"); + return 1; + } + return obj2ast_object(obj, out, arena); +} + +static int obj2ast_int(PyObject* obj, int* out, PyArena* arena) +{ + int i; + if (!PyLong_Check(obj)) { + PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj); + return 1; + } + + i = _PyLong_AsInt(obj); + if (i == -1 && PyErr_Occurred()) + return 1; + *out = i; + return 0; +} + +static int add_ast_fields(void) +{ + PyObject *empty_tuple, *d; + if (PyType_Ready(&AST_type) < 0) + return -1; + d = AST_type.tp_dict; + empty_tuple = PyTuple_New(0); + if (!empty_tuple || + _PyDict_SetItemId(d, &PyId__fields, empty_tuple) < 0 || + _PyDict_SetItemId(d, &PyId__attributes, empty_tuple) < 0) { + Py_XDECREF(empty_tuple); + return -1; + } + Py_DECREF(empty_tuple); + return 0; +} + +""", 0, reflow=False) + + self.emit("static int init_types(void)",0) + self.emit("{", 0) + self.emit("static int initialized;", 1) + self.emit("if (initialized) return 1;", 1) + self.emit("if (add_ast_fields() < 0) return 0;", 1) + for dfn in mod.dfns: + self.visit(dfn) + self.emit("initialized = 1;", 1) + self.emit("return 1;", 1); + self.emit("}", 0) + + def visitProduct(self, prod, name): + if prod.fields: + fields = name+"_fields" + else: + fields = "NULL" + self.emit('%s_type = make_type("%s", &AST_type, %s, %d);' % + (name, name, fields, len(prod.fields)), 1) + self.emit("if (!%s_type) return 0;" % name, 1) + if prod.attributes: + self.emit("if (!add_attributes(%s_type, %s_attributes, %d)) return 0;" % + (name, name, len(prod.attributes)), 1) + else: + self.emit("if (!add_attributes(%s_type, NULL, 0)) return 0;" % name, 1) + + def visitSum(self, sum, name): + self.emit('%s_type = make_type("%s", &AST_type, NULL, 0);' % + (name, name), 1) + self.emit("if (!%s_type) return 0;" % name, 1) + if sum.attributes: + self.emit("if (!add_attributes(%s_type, %s_attributes, %d)) return 0;" % + (name, name, len(sum.attributes)), 1) + else: + self.emit("if (!add_attributes(%s_type, NULL, 0)) return 0;" % name, 1) + simple = is_simple(sum) + for t in sum.types: + self.visitConstructor(t, name, simple) + + def visitConstructor(self, cons, name, simple): + if cons.fields: + fields = cons.name+"_fields" + else: + fields = "NULL" + self.emit('%s_type = make_type("%s", %s_type, %s, %d);' % + (cons.name, cons.name, name, fields, len(cons.fields)), 1) + self.emit("if (!%s_type) return 0;" % cons.name, 1) + if simple: + self.emit("%s_singleton = PyType_GenericNew(%s_type, NULL, NULL);" % + (cons.name, cons.name), 1) + self.emit("if (!%s_singleton) return 0;" % cons.name, 1) + + +class ASTModuleVisitor(PickleVisitor): + + def visitModule(self, mod): + self.emit("static struct PyModuleDef _astmodule = {", 0) + self.emit(' PyModuleDef_HEAD_INIT, "_ast"', 0) + self.emit("};", 0) + self.emit("PyMODINIT_FUNC", 0) + self.emit("PyInit__ast(void)", 0) + self.emit("{", 0) + self.emit("PyObject *m, *d;", 1) + self.emit("if (!init_types()) return NULL;", 1) + self.emit('m = PyModule_Create(&_astmodule);', 1) + self.emit("if (!m) return NULL;", 1) + self.emit("d = PyModule_GetDict(m);", 1) + self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL;', 1) + self.emit('if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0)', 1) + self.emit("return NULL;", 2) + self.emit('if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0)', 1) + self.emit("return NULL;", 2) + self.emit('if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0)', 1) + self.emit("return NULL;", 2) + for dfn in mod.dfns: + self.visit(dfn) + self.emit("return m;", 1) + self.emit("}", 0) + + def visitProduct(self, prod, name): + self.addObj(name) + + def visitSum(self, sum, name): + self.addObj(name) + for t in sum.types: + self.visitConstructor(t, name) + + def visitConstructor(self, cons, name): + self.addObj(cons.name) + + def addObj(self, name): + self.emit('if (PyDict_SetItemString(d, "%s", (PyObject*)%s_type) < 0) return NULL;' % (name, name), 1) + + +_SPECIALIZED_SEQUENCES = ('stmt', 'expr') + +def find_sequence(fields, doing_specialization): + """Return True if any field uses a sequence.""" + for f in fields: + if f.seq: + if not doing_specialization: + return True + if str(f.type) not in _SPECIALIZED_SEQUENCES: + return True + return False + +def has_sequence(types, doing_specialization): + for t in types: + if find_sequence(t.fields, doing_specialization): + return True + return False + + +class StaticVisitor(PickleVisitor): + CODE = '''Very simple, always emit this static code. Override CODE''' + + def visit(self, object): + self.emit(self.CODE, 0, reflow=False) + + +class ObjVisitor(PickleVisitor): + + def func_begin(self, name): + ctype = get_c_type(name) + self.emit("PyObject*", 0) + self.emit("ast2obj_%s(void* _o)" % (name), 0) + self.emit("{", 0) + self.emit("%s o = (%s)_o;" % (ctype, ctype), 1) + self.emit("PyObject *result = NULL, *value = NULL;", 1) + self.emit('if (!o) {', 1) + self.emit("Py_RETURN_NONE;", 2) + self.emit("}", 1) + self.emit('', 0) + + def func_end(self): + self.emit("return result;", 1) + self.emit("failed:", 0) + self.emit("Py_XDECREF(value);", 1) + self.emit("Py_XDECREF(result);", 1) + self.emit("return NULL;", 1) + self.emit("}", 0) + self.emit("", 0) + + def visitSum(self, sum, name): + if is_simple(sum): + self.simpleSum(sum, name) + return + self.func_begin(name) + self.emit("switch (o->kind) {", 1) + for i in range(len(sum.types)): + t = sum.types[i] + self.visitConstructor(t, i + 1, name) + self.emit("}", 1) + for a in sum.attributes: + self.emit("value = ast2obj_%s(o->%s);" % (a.type, a.name), 1) + self.emit("if (!value) goto failed;", 1) + self.emit('if (_PyObject_SetAttrId(result, &PyId_%s, value) < 0)' % a.name, 1) + self.emit('goto failed;', 2) + self.emit('Py_DECREF(value);', 1) + self.func_end() + + def simpleSum(self, sum, name): + self.emit("PyObject* ast2obj_%s(%s_ty o)" % (name, name), 0) + self.emit("{", 0) + self.emit("switch(o) {", 1) + for t in sum.types: + self.emit("case %s:" % t.name, 2) + self.emit("Py_INCREF(%s_singleton);" % t.name, 3) + self.emit("return %s_singleton;" % t.name, 3) + self.emit("default:", 2) + self.emit('/* should never happen, but just in case ... */', 3) + code = "PyErr_Format(PyExc_SystemError, \"unknown %s found\");" % name + self.emit(code, 3, reflow=False) + self.emit("return NULL;", 3) + self.emit("}", 1) + self.emit("}", 0) + + def visitProduct(self, prod, name): + self.func_begin(name) + self.emit("result = PyType_GenericNew(%s_type, NULL, NULL);" % name, 1); + self.emit("if (!result) return NULL;", 1) + for field in prod.fields: + self.visitField(field, name, 1, True) + for a in prod.attributes: + self.emit("value = ast2obj_%s(o->%s);" % (a.type, a.name), 1) + self.emit("if (!value) goto failed;", 1) + self.emit('if (_PyObject_SetAttrId(result, &PyId_%s, value) < 0)' % a.name, 1) + self.emit('goto failed;', 2) + self.emit('Py_DECREF(value);', 1) + self.func_end() + + def visitConstructor(self, cons, enum, name): + self.emit("case %s_kind:" % cons.name, 1) + self.emit("result = PyType_GenericNew(%s_type, NULL, NULL);" % cons.name, 2); + self.emit("if (!result) goto failed;", 2) + for f in cons.fields: + self.visitField(f, cons.name, 2, False) + self.emit("break;", 2) + + def visitField(self, field, name, depth, product): + def emit(s, d): + self.emit(s, depth + d) + if product: + value = "o->%s" % field.name + else: + value = "o->v.%s.%s" % (name, field.name) + self.set(field, value, depth) + emit("if (!value) goto failed;", 0) + emit('if (_PyObject_SetAttrId(result, &PyId_%s, value) == -1)' % field.name, 0) + emit("goto failed;", 1) + emit("Py_DECREF(value);", 0) + + def emitSeq(self, field, value, depth, emit): + emit("seq = %s;" % value, 0) + emit("n = asdl_seq_LEN(seq);", 0) + emit("value = PyList_New(n);", 0) + emit("if (!value) goto failed;", 0) + emit("for (i = 0; i < n; i++) {", 0) + self.set("value", field, "asdl_seq_GET(seq, i)", depth + 1) + emit("if (!value1) goto failed;", 1) + emit("PyList_SET_ITEM(value, i, value1);", 1) + emit("value1 = NULL;", 1) + emit("}", 0) + + def set(self, field, value, depth): + if field.seq: + # XXX should really check for is_simple, but that requires a symbol table + if field.type == "cmpop": + # While the sequence elements are stored as void*, + # ast2obj_cmpop expects an enum + self.emit("{", depth) + self.emit("Py_ssize_t i, n = asdl_seq_LEN(%s);" % value, depth+1) + self.emit("value = PyList_New(n);", depth+1) + self.emit("if (!value) goto failed;", depth+1) + self.emit("for(i = 0; i < n; i++)", depth+1) + # This cannot fail, so no need for error handling + self.emit("PyList_SET_ITEM(value, i, ast2obj_cmpop((cmpop_ty)asdl_seq_GET(%s, i)));" % value, + depth+2, reflow=False) + self.emit("}", depth) + else: + self.emit("value = ast2obj_list(%s, ast2obj_%s);" % (value, field.type), depth) + else: + ctype = get_c_type(field.type) + self.emit("value = ast2obj_%s(%s);" % (field.type, value), depth, reflow=False) + + +class PartingShots(StaticVisitor): + + CODE = """ +PyObject* PyAST_mod2obj(mod_ty t) +{ + if (!init_types()) + return NULL; + return ast2obj_mod(t); +} + +/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) +{ + PyObject *req_type[3]; + char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; + + if (PySys_Audit("compile", "OO", ast, Py_None) < 0) { + return NULL; + } + + req_type[0] = (PyObject*)Module_type; + req_type[1] = (PyObject*)Expression_type; + req_type[2] = (PyObject*)Interactive_type; + + assert(0 <= mode && mode <= 2); + + if (!init_types()) + return NULL; + + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { + PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", + req_name[mode], Py_TYPE(ast)->tp_name); + return NULL; + } + + mod_ty res = NULL; + if (obj2ast_mod(ast, &res, arena) != 0) + return NULL; + else + return res; +} + +int PyAST_Check(PyObject* obj) +{ + if (!init_types()) + return -1; + return PyObject_IsInstance(obj, (PyObject*)&AST_type); +} +""" + +class ChainOfVisitors: + def __init__(self, *visitors): + self.visitors = visitors + + def visit(self, object): + for v in self.visitors: + v.visit(object) + v.emit("", 0) + +common_msg = "/* File automatically generated by %s. */\n\n" + +def main(srcfile, dump_module=False): + argv0 = sys.argv[0] + components = argv0.split(os.sep) + argv0 = os.sep.join(components[-2:]) + auto_gen_msg = common_msg % argv0 + mod = asdl.parse(srcfile) + if dump_module: + print('Parsed Module:') + print(mod) + if not asdl.check(mod): + sys.exit(1) + if H_FILE: + with open(H_FILE, "w") as f: + f.write(auto_gen_msg) + f.write('#ifndef Py_PYTHON_AST_H\n') + f.write('#define Py_PYTHON_AST_H\n') + f.write('#ifdef __cplusplus\n') + f.write('extern "C" {\n') + f.write('#endif\n') + f.write('\n') + f.write('#include "asdl.h"\n') + f.write('\n') + f.write('#undef Yield /* undefine macro conflicting with */\n') + f.write('\n') + c = ChainOfVisitors(TypeDefVisitor(f), + StructVisitor(f)) + + c.visit(mod) + f.write("// Note: these macros affect function definitions, not only call sites.\n") + PrototypeVisitor(f).visit(mod) + f.write("\n") + f.write("PyObject* PyAST_mod2obj(mod_ty t);\n") + f.write("mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);\n") + f.write("int PyAST_Check(PyObject* obj);\n") + f.write('\n') + f.write('#ifdef __cplusplus\n') + f.write('}\n') + f.write('#endif\n') + f.write('#endif /* !Py_PYTHON_AST_H */\n') + + if C_FILE: + with open(C_FILE, "w") as f: + f.write(auto_gen_msg) + f.write('#include \n') + f.write('\n') + f.write('#include "Python.h"\n') + f.write('#include "%s-ast.h"\n' % mod.name) + f.write('\n') + f.write("static PyTypeObject AST_type;\n") + v = ChainOfVisitors( + PyTypesDeclareVisitor(f), + PyTypesVisitor(f), + Obj2ModPrototypeVisitor(f), + FunctionVisitor(f), + ObjVisitor(f), + Obj2ModVisitor(f), + ASTModuleVisitor(f), + PartingShots(f), + ) + v.visit(mod) + +if __name__ == "__main__": + import getopt + + H_FILE = '' + C_FILE = '' + dump_module = False + opts, args = getopt.getopt(sys.argv[1:], "dh:c:") + for o, v in opts: + if o == '-h': + H_FILE = v + elif o == '-c': + C_FILE = v + elif o == '-d': + dump_module = True + if H_FILE and C_FILE: + print('Must specify exactly one output file') + sys.exit(1) + elif len(args) != 1: + print('Must specify single input file') + sys.exit(1) + main(args[0], dump_module) diff --git a/python/Parser/grammar1.c b/python/Parser/grammar1.c new file mode 100755 index 0000000..e0b8fbb --- /dev/null +++ b/python/Parser/grammar1.c @@ -0,0 +1,47 @@ + +/* Grammar subroutines needed by parser */ + +#include "Python.h" +#include "grammar.h" +#include "token.h" + +/* Return the DFA for the given type */ + +const dfa * +PyGrammar_FindDFA(grammar *g, int type) +{ + /* Massive speed-up */ + const dfa *d = &g->g_dfa[type - NT_OFFSET]; + assert(d->d_type == type); + return d; +} + +const char * +PyGrammar_LabelRepr(label *lb) +{ + static char buf[100]; + + if (lb->lb_type == ENDMARKER) + return "EMPTY"; + else if (ISNONTERMINAL(lb->lb_type)) { + if (lb->lb_str == NULL) { + PyOS_snprintf(buf, sizeof(buf), "NT%d", lb->lb_type); + return buf; + } + else + return lb->lb_str; + } + else if (lb->lb_type < N_TOKENS) { + if (lb->lb_str == NULL) + return _PyParser_TokenNames[lb->lb_type]; + else { + PyOS_snprintf(buf, sizeof(buf), "%.32s(%.32s)", + _PyParser_TokenNames[lb->lb_type], lb->lb_str); + return buf; + } + } + else { + Py_FatalError("invalid label"); + return NULL; + } +} diff --git a/python/Parser/listnode.c b/python/Parser/listnode.c new file mode 100755 index 0000000..8f1a116 --- /dev/null +++ b/python/Parser/listnode.c @@ -0,0 +1,66 @@ + +/* List a node on a file */ + +#include "Python.h" +#include "token.h" +#include "node.h" + +/* Forward */ +static void list1node(FILE *, node *); +static void listnode(FILE *, node *); + +void +PyNode_ListTree(node *n) +{ + listnode(stdout, n); +} + +static int level, atbol; + +static void +listnode(FILE *fp, node *n) +{ + level = 0; + atbol = 1; + list1node(fp, n); +} + +static void +list1node(FILE *fp, node *n) +{ + if (n == NULL) + return; + if (ISNONTERMINAL(TYPE(n))) { + int i; + for (i = 0; i < NCH(n); i++) + list1node(fp, CHILD(n, i)); + } + else if (ISTERMINAL(TYPE(n))) { + switch (TYPE(n)) { + case INDENT: + ++level; + break; + case DEDENT: + --level; + break; + default: + if (atbol) { + int i; + for (i = 0; i < level; ++i) + fprintf(fp, "\t"); + atbol = 0; + } + if (TYPE(n) == NEWLINE) { + if (STR(n) != NULL) + fprintf(fp, "%s", STR(n)); + fprintf(fp, "\n"); + atbol = 1; + } + else + fprintf(fp, "%s ", STR(n)); + break; + } + } + else + fprintf(fp, "? "); +} diff --git a/python/Parser/myreadline.c b/python/Parser/myreadline.c new file mode 100755 index 0000000..e8e5773 --- /dev/null +++ b/python/Parser/myreadline.c @@ -0,0 +1,416 @@ + +/* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c. + By default, or when stdin is not a tty device, we have a super + simple my_readline function using fgets. + Optionally, we can use the GNU readline library. + my_readline() has a different return value from GNU readline(): + - NULL if an interrupt occurred or if an error occurred + - a malloc'ed empty string if EOF was read + - a malloc'ed string ending in \n normally +*/ + +#include "Python.h" +#include "pycore_pystate.h" +#ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include "windows.h" +#endif /* MS_WINDOWS */ + + +PyThreadState* _PyOS_ReadlineTState = NULL; + +#include "pythread.h" +static PyThread_type_lock _PyOS_ReadlineLock = NULL; + +int (*PyOS_InputHook)(void) = NULL; + +/* This function restarts a fgets() after an EINTR error occurred + except if _PyOS_InterruptOccurred() returns true. */ + +static int +my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) +{ +#ifdef MS_WINDOWS + HANDLE handle; + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fileno(fp)); + _Py_END_SUPPRESS_IPH + + /* bpo-40826: fgets(fp) does crash if fileno(fp) is closed */ + if (handle == INVALID_HANDLE_VALUE) { + return -1; /* EOF */ + } +#endif + + while (1) { + if (PyOS_InputHook != NULL) { + (void)(PyOS_InputHook)(); + } + + errno = 0; + clearerr(fp); + char *p = fgets(buf, len, fp); + if (p != NULL) { + return 0; /* No error */ + } + int err = errno; + +#ifdef MS_WINDOWS + /* Ctrl-C anywhere on the line or Ctrl-Z if the only character + on a line will set ERROR_OPERATION_ABORTED. Under normal + circumstances Ctrl-C will also have caused the SIGINT handler + to fire which will have set the event object returned by + _PyOS_SigintEvent. This signal fires in another thread and + is not guaranteed to have occurred before this point in the + code. + + Therefore: check whether the event is set with a small timeout. + If it is, assume this is a Ctrl-C and reset the event. If it + isn't set assume that this is a Ctrl-Z on its own and drop + through to check for EOF. + */ + if (GetLastError()==ERROR_OPERATION_ABORTED) { + HANDLE hInterruptEvent = _PyOS_SigintEvent(); + switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) { + case WAIT_OBJECT_0: + ResetEvent(hInterruptEvent); + return 1; /* Interrupt */ + case WAIT_FAILED: + return -2; /* Error */ + } + } +#endif /* MS_WINDOWS */ + + if (feof(fp)) { + clearerr(fp); + return -1; /* EOF */ + } + +#ifdef EINTR + if (err == EINTR) { + PyEval_RestoreThread(tstate); + int s = PyErr_CheckSignals(); + PyEval_SaveThread(); + + if (s < 0) { + return 1; + } + /* try again */ + continue; + } +#endif + + if (_PyOS_InterruptOccurred(tstate)) { + return 1; /* Interrupt */ + } + return -2; /* Error */ + } + /* NOTREACHED */ +} + +#ifdef MS_WINDOWS +/* Readline implementation using ReadConsoleW */ + +extern char _get_console_type(HANDLE handle); + +char * +_PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn) +{ + static wchar_t wbuf_local[1024 * 16]; + const DWORD chunk_size = 1024; + + DWORD n_read, total_read, wbuflen, u8len; + wchar_t *wbuf; + char *buf = NULL; + int err = 0; + + n_read = (DWORD)-1; + total_read = 0; + wbuf = wbuf_local; + wbuflen = sizeof(wbuf_local) / sizeof(wbuf_local[0]) - 1; + while (1) { + if (PyOS_InputHook != NULL) { + (void)(PyOS_InputHook)(); + } + if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) { + err = GetLastError(); + goto exit; + } + if (n_read == (DWORD)-1 && (err = GetLastError()) == ERROR_OPERATION_ABORTED) { + break; + } + if (n_read == 0) { + int s; + err = GetLastError(); + if (err != ERROR_OPERATION_ABORTED) + goto exit; + err = 0; + HANDLE hInterruptEvent = _PyOS_SigintEvent(); + if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) + == WAIT_OBJECT_0) { + ResetEvent(hInterruptEvent); + PyEval_RestoreThread(tstate); + s = PyErr_CheckSignals(); + PyEval_SaveThread(); + if (s < 0) { + goto exit; + } + } + break; + } + + total_read += n_read; + if (total_read == 0 || wbuf[total_read - 1] == L'\n') { + break; + } + wbuflen += chunk_size; + if (wbuf == wbuf_local) { + wbuf[total_read] = '\0'; + wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t)); + if (wbuf) { + wcscpy_s(wbuf, wbuflen, wbuf_local); + } + else { + PyEval_RestoreThread(tstate); + PyErr_NoMemory(); + PyEval_SaveThread(); + goto exit; + } + } + else { + wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t)); + if (tmp == NULL) { + PyEval_RestoreThread(tstate); + PyErr_NoMemory(); + PyEval_SaveThread(); + goto exit; + } + wbuf = tmp; + } + } + + if (wbuf[0] == '\x1a') { + buf = PyMem_RawMalloc(1); + if (buf) { + buf[0] = '\0'; + } + else { + PyEval_RestoreThread(tstate); + PyErr_NoMemory(); + PyEval_SaveThread(); + } + goto exit; + } + + u8len = WideCharToMultiByte(CP_UTF8, 0, + wbuf, total_read, + NULL, 0, + NULL, NULL); + buf = PyMem_RawMalloc(u8len + 1); + if (buf == NULL) { + PyEval_RestoreThread(tstate); + PyErr_NoMemory(); + PyEval_SaveThread(); + goto exit; + } + + u8len = WideCharToMultiByte(CP_UTF8, 0, + wbuf, total_read, + buf, u8len, + NULL, NULL); + buf[u8len] = '\0'; + +exit: + if (wbuf != wbuf_local) { + PyMem_RawFree(wbuf); + } + + if (err) { + PyEval_RestoreThread(tstate); + PyErr_SetFromWindowsErr(err); + PyEval_SaveThread(); + } + return buf; +} + +#endif + + +/* Readline implementation using fgets() */ + +char * +PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) +{ + size_t n; + char *p, *pr; + PyThreadState *tstate = _PyOS_ReadlineTState; + assert(tstate != NULL); + +#ifdef MS_WINDOWS + if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) { + HANDLE hStdIn, hStdErr; + + _Py_BEGIN_SUPPRESS_IPH + hStdIn = (HANDLE)_get_osfhandle(fileno(sys_stdin)); + hStdErr = (HANDLE)_get_osfhandle(fileno(stderr)); + _Py_END_SUPPRESS_IPH + + if (_get_console_type(hStdIn) == 'r') { + fflush(sys_stdout); + if (prompt) { + if (_get_console_type(hStdErr) == 'w') { + wchar_t *wbuf; + int wlen; + wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1, + NULL, 0); + if (wlen) { + wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t)); + if (wbuf == NULL) { + PyEval_RestoreThread(tstate); + PyErr_NoMemory(); + PyEval_SaveThread(); + return NULL; + } + wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1, + wbuf, wlen); + if (wlen) { + DWORD n; + fflush(stderr); + /* wlen includes null terminator, so subtract 1 */ + WriteConsoleW(hStdErr, wbuf, wlen - 1, &n, NULL); + } + PyMem_RawFree(wbuf); + } + } else { + fprintf(stderr, "%s", prompt); + fflush(stderr); + } + } + clearerr(sys_stdin); + return _PyOS_WindowsConsoleReadline(tstate, hStdIn); + } + } +#endif + + fflush(sys_stdout); + if (prompt) { + fprintf(stderr, "%s", prompt); + } + fflush(stderr); + + n = 0; + p = NULL; + do { + size_t incr = (n > 0) ? n + 2 : 100; + if (incr > INT_MAX) { + PyMem_RawFree(p); + PyEval_RestoreThread(tstate); + PyErr_SetString(PyExc_OverflowError, "input line too long"); + PyEval_SaveThread(); + return NULL; + } + pr = (char *)PyMem_RawRealloc(p, n + incr); + if (pr == NULL) { + PyMem_RawFree(p); + PyEval_RestoreThread(tstate); + PyErr_NoMemory(); + PyEval_SaveThread(); + return NULL; + } + p = pr; + int err = my_fgets(tstate, p + n, (int)incr, sys_stdin); + if (err == 1) { + // Interrupt + PyMem_RawFree(p); + return NULL; + } else if (err != 0) { + // EOF or error + p[n] = '\0'; + break; + } + n += strlen(p + n); + } while (p[n-1] != '\n'); + + pr = (char *)PyMem_RawRealloc(p, n+1); + if (pr == NULL) { + PyMem_RawFree(p); + PyEval_RestoreThread(tstate); + PyErr_NoMemory(); + PyEval_SaveThread(); + return NULL; + } + return pr; +} + + +/* By initializing this function pointer, systems embedding Python can + override the readline function. + + Note: Python expects in return a buffer allocated with PyMem_Malloc. */ + +char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) = NULL; + + +/* Interface used by tokenizer.c and bltinmodule.c */ + +char * +PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) +{ + char *rv, *res; + size_t len; + + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyOS_ReadlineTState == tstate) { + PyErr_SetString(PyExc_RuntimeError, + "can't re-enter readline"); + return NULL; + } + + + if (PyOS_ReadlineFunctionPointer == NULL) { + PyOS_ReadlineFunctionPointer = PyOS_StdioReadline; + } + + if (_PyOS_ReadlineLock == NULL) { + _PyOS_ReadlineLock = PyThread_allocate_lock(); + if (_PyOS_ReadlineLock == NULL) { + PyErr_SetString(PyExc_MemoryError, "can't allocate lock"); + return NULL; + } + } + + _PyOS_ReadlineTState = tstate; + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(_PyOS_ReadlineLock, 1); + + /* This is needed to handle the unlikely case that the + * interpreter is in interactive mode *and* stdin/out are not + * a tty. This can happen, for example if python is run like + * this: python -i < test1.py + */ + if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout))) + rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt); + else + rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, + prompt); + Py_END_ALLOW_THREADS + + PyThread_release_lock(_PyOS_ReadlineLock); + + _PyOS_ReadlineTState = NULL; + + if (rv == NULL) + return NULL; + + len = strlen(rv) + 1; + res = PyMem_Malloc(len); + if (res != NULL) { + memcpy(res, rv, len); + } + else { + PyErr_NoMemory(); + } + PyMem_RawFree(rv); + + return res; +} diff --git a/python/Parser/node.c b/python/Parser/node.c new file mode 100755 index 0000000..f1b70e0 --- /dev/null +++ b/python/Parser/node.c @@ -0,0 +1,188 @@ +/* Parse tree node implementation */ + +#include "Python.h" +#include "node.h" +#include "errcode.h" + +node * +PyNode_New(int type) +{ + node *n = (node *) PyObject_MALLOC(1 * sizeof(node)); + if (n == NULL) + return NULL; + n->n_type = type; + n->n_str = NULL; + n->n_lineno = 0; + n->n_end_lineno = 0; + n->n_end_col_offset = -1; + n->n_nchildren = 0; + n->n_child = NULL; + return n; +} + +/* See comments at XXXROUNDUP below. Returns -1 on overflow. */ +static int +fancy_roundup(int n) +{ + /* Round up to the closest power of 2 >= n. */ + int result = 256; + assert(n > 128); + while (result < n) { + result <<= 1; + if (result <= 0) + return -1; + } + return result; +} + +/* A gimmick to make massive numbers of reallocs quicker. The result is + * a number >= the input. In PyNode_AddChild, it's used like so, when + * we're about to add child number current_size + 1: + * + * if XXXROUNDUP(current_size) < XXXROUNDUP(current_size + 1): + * allocate space for XXXROUNDUP(current_size + 1) total children + * else: + * we already have enough space + * + * Since a node starts out empty, we must have + * + * XXXROUNDUP(0) < XXXROUNDUP(1) + * + * so that we allocate space for the first child. One-child nodes are very + * common (presumably that would change if we used a more abstract form + * of syntax tree), so to avoid wasting memory it's desirable that + * XXXROUNDUP(1) == 1. That in turn forces XXXROUNDUP(0) == 0. + * + * Else for 2 <= n <= 128, we round up to the closest multiple of 4. Why 4? + * Rounding up to a multiple of an exact power of 2 is very efficient, and + * most nodes with more than one child have <= 4 kids. + * + * Else we call fancy_roundup() to grow proportionately to n. We've got an + * extreme case then (like test_longexp.py), and on many platforms doing + * anything less than proportional growth leads to exorbitant runtime + * (e.g., MacPython), or extreme fragmentation of user address space (e.g., + * Win98). + * + * In a run of compileall across the 2.3a0 Lib directory, Andrew MacIntyre + * reported that, with this scheme, 89% of PyObject_REALLOC calls in + * PyNode_AddChild passed 1 for the size, and 9% passed 4. So this usually + * wastes very little memory, but is very effective at sidestepping + * platform-realloc disasters on vulnerable platforms. + * + * Note that this would be straightforward if a node stored its current + * capacity. The code is tricky to avoid that. + */ +#define XXXROUNDUP(n) ((n) <= 1 ? (n) : \ + (n) <= 128 ? (int)_Py_SIZE_ROUND_UP((n), 4) : \ + fancy_roundup(n)) + + +void +_PyNode_FinalizeEndPos(node *n) +{ + int nch = NCH(n); + node *last; + if (nch == 0) { + return; + } + last = CHILD(n, nch - 1); + _PyNode_FinalizeEndPos(last); + n->n_end_lineno = last->n_end_lineno; + n->n_end_col_offset = last->n_end_col_offset; +} + +int +PyNode_AddChild(node *n1, int type, char *str, int lineno, int col_offset, + int end_lineno, int end_col_offset) +{ + const int nch = n1->n_nchildren; + int current_capacity; + int required_capacity; + node *n; + + // finalize end position of previous node (if any) + if (nch > 0) { + _PyNode_FinalizeEndPos(CHILD(n1, nch - 1)); + } + + if (nch == INT_MAX || nch < 0) + return E_OVERFLOW; + + current_capacity = XXXROUNDUP(nch); + required_capacity = XXXROUNDUP(nch + 1); + if (current_capacity < 0 || required_capacity < 0) + return E_OVERFLOW; + if (current_capacity < required_capacity) { + if ((size_t)required_capacity > SIZE_MAX / sizeof(node)) { + return E_NOMEM; + } + n = n1->n_child; + n = (node *) PyObject_REALLOC(n, + required_capacity * sizeof(node)); + if (n == NULL) + return E_NOMEM; + n1->n_child = n; + } + + n = &n1->n_child[n1->n_nchildren++]; + n->n_type = type; + n->n_str = str; + n->n_lineno = lineno; + n->n_col_offset = col_offset; + n->n_end_lineno = end_lineno; // this and below will be updates after all children are added. + n->n_end_col_offset = end_col_offset; + n->n_nchildren = 0; + n->n_child = NULL; + return 0; +} + +/* Forward */ +static void freechildren(node *); +static Py_ssize_t sizeofchildren(node *n); + + +void +PyNode_Free(node *n) +{ + if (n != NULL) { + freechildren(n); + PyObject_FREE(n); + } +} + +Py_ssize_t +_PyNode_SizeOf(node *n) +{ + Py_ssize_t res = 0; + + if (n != NULL) + res = sizeof(node) + sizeofchildren(n); + return res; +} + +static void +freechildren(node *n) +{ + int i; + for (i = NCH(n); --i >= 0; ) + freechildren(CHILD(n, i)); + if (n->n_child != NULL) + PyObject_FREE(n->n_child); + if (STR(n) != NULL) + PyObject_FREE(STR(n)); +} + +static Py_ssize_t +sizeofchildren(node *n) +{ + Py_ssize_t res = 0; + int i; + for (i = NCH(n); --i >= 0; ) + res += sizeofchildren(CHILD(n, i)); + if (n->n_child != NULL) + /* allocated size of n->n_child array */ + res += XXXROUNDUP(NCH(n)) * sizeof(node); + if (STR(n) != NULL) + res += strlen(STR(n)) + 1; + return res; +} diff --git a/python/Parser/parser.c b/python/Parser/parser.c new file mode 100755 index 0000000..227b918 --- /dev/null +++ b/python/Parser/parser.c @@ -0,0 +1,462 @@ + +/* Parser implementation */ + +/* For a description, see the comments at end of this file */ + +/* XXX To do: error recovery */ + +#include "Python.h" +#include "token.h" +#include "grammar.h" +#include "node.h" +#include "parser.h" +#include "errcode.h" +#include "graminit.h" + + +#ifdef Py_DEBUG +extern int Py_DebugFlag; +#define D(x) if (!Py_DebugFlag); else x +#else +#define D(x) +#endif + + +/* STACK DATA TYPE */ + +static void s_reset(stack *); + +static void +s_reset(stack *s) +{ + s->s_top = &s->s_base[MAXSTACK]; +} + +#define s_empty(s) ((s)->s_top == &(s)->s_base[MAXSTACK]) + +static int +s_push(stack *s, const dfa *d, node *parent) +{ + stackentry *top; + if (s->s_top == s->s_base) { + fprintf(stderr, "s_push: parser stack overflow\n"); + return E_NOMEM; + } + top = --s->s_top; + top->s_dfa = d; + top->s_parent = parent; + top->s_state = 0; + return 0; +} + +#ifdef Py_DEBUG + +static void +s_pop(stack *s) +{ + if (s_empty(s)) + Py_FatalError("s_pop: parser stack underflow -- FATAL"); + s->s_top++; +} + +#else /* !Py_DEBUG */ + +#define s_pop(s) (s)->s_top++ + +#endif + + +/* PARSER CREATION */ + +parser_state * +PyParser_New(grammar *g, int start) +{ + parser_state *ps; + + if (!g->g_accel) + PyGrammar_AddAccelerators(g); + ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state)); + if (ps == NULL) + return NULL; + ps->p_grammar = g; +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD + ps->p_flags = 0; +#endif + ps->p_tree = PyNode_New(start); + if (ps->p_tree == NULL) { + PyMem_FREE(ps); + return NULL; + } + s_reset(&ps->p_stack); + (void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree); + return ps; +} + +void +PyParser_Delete(parser_state *ps) +{ + /* NB If you want to save the parse tree, + you must set p_tree to NULL before calling delparser! */ + PyNode_Free(ps->p_tree); + PyMem_FREE(ps); +} + + +/* PARSER STACK OPERATIONS */ + +static int +shift(stack *s, int type, char *str, int newstate, int lineno, int col_offset, + int end_lineno, int end_col_offset) +{ + int err; + assert(!s_empty(s)); + err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno, col_offset, + end_lineno, end_col_offset); + if (err) + return err; + s->s_top->s_state = newstate; + return 0; +} + +static int +push(stack *s, int type, const dfa *d, int newstate, int lineno, int col_offset, + int end_lineno, int end_col_offset) +{ + int err; + node *n; + n = s->s_top->s_parent; + assert(!s_empty(s)); + err = PyNode_AddChild(n, type, (char *)NULL, lineno, col_offset, + end_lineno, end_col_offset); + if (err) + return err; + s->s_top->s_state = newstate; + return s_push(s, d, CHILD(n, NCH(n)-1)); +} + + +/* PARSER PROPER */ + +static int +classify(parser_state *ps, int type, const char *str) +{ + grammar *g = ps->p_grammar; + int n = g->g_ll.ll_nlabels; + + if (type == NAME) { + const label *l = g->g_ll.ll_label; + int i; + for (i = n; i > 0; i--, l++) { + if (l->lb_type != NAME || l->lb_str == NULL || + l->lb_str[0] != str[0] || + strcmp(l->lb_str, str) != 0) + continue; +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 + /* Leaving this in as an example */ + if (!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) { + if (str[0] == 'w' && strcmp(str, "with") == 0) + break; /* not a keyword yet */ + else if (str[0] == 'a' && strcmp(str, "as") == 0) + break; /* not a keyword yet */ + } +#endif +#endif + D(printf("It's a keyword\n")); + return n - i; + } + } + + { + const label *l = g->g_ll.ll_label; + int i; + for (i = n; i > 0; i--, l++) { + if (l->lb_type == type && l->lb_str == NULL) { + D(printf("It's a token we know\n")); + return n - i; + } + } + } + + D(printf("Illegal token\n")); + return -1; +} + +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 +/* Leaving this in as an example */ +static void +future_hack(parser_state *ps) +{ + node *n = ps->p_stack.s_top->s_parent; + node *ch, *cch; + int i; + + /* from __future__ import ..., must have at least 4 children */ + n = CHILD(n, 0); + if (NCH(n) < 4) + return; + ch = CHILD(n, 0); + if (STR(ch) == NULL || strcmp(STR(ch), "from") != 0) + return; + ch = CHILD(n, 1); + if (NCH(ch) == 1 && STR(CHILD(ch, 0)) && + strcmp(STR(CHILD(ch, 0)), "__future__") != 0) + return; + ch = CHILD(n, 3); + /* ch can be a star, a parenthesis or import_as_names */ + if (TYPE(ch) == STAR) + return; + if (TYPE(ch) == LPAR) + ch = CHILD(n, 4); + + for (i = 0; i < NCH(ch); i += 2) { + cch = CHILD(ch, i); + if (NCH(cch) >= 1 && TYPE(CHILD(cch, 0)) == NAME) { + char *str_ch = STR(CHILD(cch, 0)); + if (strcmp(str_ch, FUTURE_WITH_STATEMENT) == 0) { + ps->p_flags |= CO_FUTURE_WITH_STATEMENT; + } else if (strcmp(str_ch, FUTURE_PRINT_FUNCTION) == 0) { + ps->p_flags |= CO_FUTURE_PRINT_FUNCTION; + } else if (strcmp(str_ch, FUTURE_UNICODE_LITERALS) == 0) { + ps->p_flags |= CO_FUTURE_UNICODE_LITERALS; + } + } + } +} +#endif +#endif /* future keyword */ + +int +PyParser_AddToken(parser_state *ps, int type, char *str, + int lineno, int col_offset, + int end_lineno, int end_col_offset, + int *expected_ret) +{ + int ilabel; + int err; + + D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str)); + + /* Find out which label this token is */ + ilabel = classify(ps, type, str); + if (ilabel < 0) + return E_SYNTAX; + + /* Loop until the token is shifted or an error occurred */ + for (;;) { + /* Fetch the current dfa and state */ + const dfa *d = ps->p_stack.s_top->s_dfa; + state *s = &d->d_state[ps->p_stack.s_top->s_state]; + + D(printf(" DFA '%s', state %d:", + d->d_name, ps->p_stack.s_top->s_state)); + + /* Check accelerator */ + if (s->s_lower <= ilabel && ilabel < s->s_upper) { + int x = s->s_accel[ilabel - s->s_lower]; + if (x != -1) { + if (x & (1<<7)) { + /* Push non-terminal */ + int nt = (x >> 8) + NT_OFFSET; + int arrow = x & ((1<<7)-1); + if (nt == func_body_suite && !(ps->p_flags & PyCF_TYPE_COMMENTS)) { + /* When parsing type comments is not requested, + we can provide better errors about bad indentation + by using 'suite' for the body of a funcdef */ + D(printf(" [switch func_body_suite to suite]")); + nt = suite; + } + const dfa *d1 = PyGrammar_FindDFA( + ps->p_grammar, nt); + if ((err = push(&ps->p_stack, nt, d1, + arrow, lineno, col_offset, + end_lineno, end_col_offset)) > 0) { + D(printf(" MemError: push\n")); + return err; + } + D(printf(" Push '%s'\n", d1->d_name)); + continue; + } + + /* Shift the token */ + if ((err = shift(&ps->p_stack, type, str, + x, lineno, col_offset, + end_lineno, end_col_offset)) > 0) { + D(printf(" MemError: shift.\n")); + return err; + } + D(printf(" Shift.\n")); + /* Pop while we are in an accept-only state */ + while (s = &d->d_state + [ps->p_stack.s_top->s_state], + s->s_accept && s->s_narcs == 1) { + D(printf(" DFA '%s', state %d: " + "Direct pop.\n", + d->d_name, + ps->p_stack.s_top->s_state)); +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 + if (d->d_name[0] == 'i' && + strcmp(d->d_name, + "import_stmt") == 0) + future_hack(ps); +#endif +#endif + s_pop(&ps->p_stack); + if (s_empty(&ps->p_stack)) { + D(printf(" ACCEPT.\n")); + return E_DONE; + } + d = ps->p_stack.s_top->s_dfa; + } + return E_OK; + } + } + + if (s->s_accept) { +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 + if (d->d_name[0] == 'i' && + strcmp(d->d_name, "import_stmt") == 0) + future_hack(ps); +#endif +#endif + /* Pop this dfa and try again */ + s_pop(&ps->p_stack); + D(printf(" Pop ...\n")); + if (s_empty(&ps->p_stack)) { + D(printf(" Error: bottom of stack.\n")); + return E_SYNTAX; + } + continue; + } + + /* Stuck, report syntax error */ + D(printf(" Error.\n")); + if (expected_ret) { + if (s->s_lower == s->s_upper - 1) { + /* Only one possible expected token */ + *expected_ret = ps->p_grammar-> + g_ll.ll_label[s->s_lower].lb_type; + } + else + *expected_ret = -1; + } + return E_SYNTAX; + } +} + + +#ifdef Py_DEBUG + +/* DEBUG OUTPUT */ + +void +dumptree(grammar *g, node *n) +{ + int i; + + if (n == NULL) + printf("NIL"); + else { + label l; + l.lb_type = TYPE(n); + l.lb_str = STR(n); + printf("%s", PyGrammar_LabelRepr(&l)); + if (ISNONTERMINAL(TYPE(n))) { + printf("("); + for (i = 0; i < NCH(n); i++) { + if (i > 0) + printf(","); + dumptree(g, CHILD(n, i)); + } + printf(")"); + } + } +} + +void +showtree(grammar *g, node *n) +{ + int i; + + if (n == NULL) + return; + if (ISNONTERMINAL(TYPE(n))) { + for (i = 0; i < NCH(n); i++) + showtree(g, CHILD(n, i)); + } + else if (ISTERMINAL(TYPE(n))) { + printf("%s", _PyParser_TokenNames[TYPE(n)]); + if (TYPE(n) == NUMBER || TYPE(n) == NAME) + printf("(%s)", STR(n)); + printf(" "); + } + else + printf("? "); +} + +void +printtree(parser_state *ps) +{ + if (Py_DebugFlag) { + printf("Parse tree:\n"); + dumptree(ps->p_grammar, ps->p_tree); + printf("\n"); + printf("Tokens:\n"); + showtree(ps->p_grammar, ps->p_tree); + printf("\n"); + } + printf("Listing:\n"); + PyNode_ListTree(ps->p_tree); + printf("\n"); +} + +#endif /* Py_DEBUG */ + +/* + +Description +----------- + +The parser's interface is different than usual: the function addtoken() +must be called for each token in the input. This makes it possible to +turn it into an incremental parsing system later. The parsing system +constructs a parse tree as it goes. + +A parsing rule is represented as a Deterministic Finite-state Automaton +(DFA). A node in a DFA represents a state of the parser; an arc represents +a transition. Transitions are either labeled with terminal symbols or +with non-terminals. When the parser decides to follow an arc labeled +with a non-terminal, it is invoked recursively with the DFA representing +the parsing rule for that as its initial state; when that DFA accepts, +the parser that invoked it continues. The parse tree constructed by the +recursively called parser is inserted as a child in the current parse tree. + +The DFA's can be constructed automatically from a more conventional +language description. An extended LL(1) grammar (ELL(1)) is suitable. +Certain restrictions make the parser's life easier: rules that can produce +the empty string should be outlawed (there are other ways to put loops +or optional parts in the language). To avoid the need to construct +FIRST sets, we can require that all but the last alternative of a rule +(really: arc going out of a DFA's state) must begin with a terminal +symbol. + +As an example, consider this grammar: + +expr: term (OP term)* +term: CONSTANT | '(' expr ')' + +The DFA corresponding to the rule for expr is: + +------->.---term-->.-------> + ^ | + | | + \----OP----/ + +The parse tree generated for the input a+b is: + +(expr: (term: (NAME: a)), (OP: +), (term: (NAME: b))) + +*/ diff --git a/python/Parser/parser.h b/python/Parser/parser.h new file mode 100755 index 0000000..b16075e --- /dev/null +++ b/python/Parser/parser.h @@ -0,0 +1,49 @@ +#ifndef Py_PARSER_H +#define Py_PARSER_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Parser interface */ + +#define MAXSTACK 1700 + +typedef struct { + int s_state; /* State in current DFA */ + const dfa *s_dfa; /* Current DFA */ + struct _node *s_parent; /* Where to add next node */ +} stackentry; + +typedef struct { + stackentry *s_top; /* Top entry */ + stackentry s_base[MAXSTACK];/* Array of stack entries */ + /* NB The stack grows down */ +} stack; + +typedef struct { + stack p_stack; /* Stack of parser states */ + grammar *p_grammar; /* Grammar to use */ + node *p_tree; /* Top of parse tree */ +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD + unsigned long p_flags; /* see co_flags in Include/code.h */ +#endif +} parser_state; + +parser_state *PyParser_New(grammar *g, int start); +void PyParser_Delete(parser_state *ps); +int PyParser_AddToken(parser_state *ps, int type, char *str, + int lineno, int col_offset, + int end_lineno, int end_col_offset, + int *expected_ret); +void PyGrammar_AddAccelerators(grammar *g); + + +#define showtree _Py_showtree +#define printtree _Py_printtree +#define dumptree _Py_dumptree + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PARSER_H */ diff --git a/python/Parser/parsetok.c b/python/Parser/parsetok.c new file mode 100755 index 0000000..2bb733d --- /dev/null +++ b/python/Parser/parsetok.c @@ -0,0 +1,496 @@ + +/* Parser-tokenizer link implementation */ + +#include "Python.h" +#include "tokenizer.h" +#include "node.h" +#include "grammar.h" +#include "parser.h" +#include "parsetok.h" +#include "errcode.h" +#include "graminit.h" + + +/* Forward */ +static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *); +static int initerr(perrdetail *err_ret, PyObject * filename); + +typedef struct { + struct { + int lineno; + char *comment; + } *items; + size_t size; + size_t num_items; +} growable_comment_array; + +static int +growable_comment_array_init(growable_comment_array *arr, size_t initial_size) { + assert(initial_size > 0); + arr->items = malloc(initial_size * sizeof(*arr->items)); + arr->size = initial_size; + arr->num_items = 0; + + return arr->items != NULL; +} + +static int +growable_comment_array_add(growable_comment_array *arr, int lineno, char *comment) { + if (arr->num_items >= arr->size) { + arr->size *= 2; + arr->items = realloc(arr->items, arr->size * sizeof(*arr->items)); + if (!arr->items) { + return 0; + } + } + + arr->items[arr->num_items].lineno = lineno; + arr->items[arr->num_items].comment = comment; + arr->num_items++; + return 1; +} + +static void +growable_comment_array_deallocate(growable_comment_array *arr) { + for (unsigned i = 0; i < arr->num_items; i++) { + PyObject_FREE(arr->items[i].comment); + } + free(arr->items); +} + +/* Parse input coming from a string. Return error code, print some errors. */ +node * +PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret) +{ + return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0); +} + +node * +PyParser_ParseStringFlags(const char *s, grammar *g, int start, + perrdetail *err_ret, int flags) +{ + return PyParser_ParseStringFlagsFilename(s, NULL, + g, start, err_ret, flags); +} + +node * +PyParser_ParseStringFlagsFilename(const char *s, const char *filename, + grammar *g, int start, + perrdetail *err_ret, int flags) +{ + int iflags = flags; + return PyParser_ParseStringFlagsFilenameEx(s, filename, g, start, + err_ret, &iflags); +} + +node * +PyParser_ParseStringObject(const char *s, PyObject *filename, + grammar *g, int start, + perrdetail *err_ret, int *flags) +{ + struct tok_state *tok; + int exec_input = start == file_input; + + if (initerr(err_ret, filename) < 0) + return NULL; + + if (PySys_Audit("compile", "yO", s, err_ret->filename) < 0) { + err_ret->error = E_ERROR; + return NULL; + } + + if (*flags & PyPARSE_IGNORE_COOKIE) + tok = PyTokenizer_FromUTF8(s, exec_input); + else + tok = PyTokenizer_FromString(s, exec_input); + if (tok == NULL) { + err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM; + return NULL; + } + if (*flags & PyPARSE_TYPE_COMMENTS) { + tok->type_comments = 1; + } + + Py_INCREF(err_ret->filename); + tok->filename = err_ret->filename; + if (*flags & PyPARSE_ASYNC_HACKS) + tok->async_hacks = 1; + return parsetok(tok, g, start, err_ret, flags); +} + +node * +PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str, + grammar *g, int start, + perrdetail *err_ret, int *flags) +{ + node *n; + PyObject *filename = NULL; + if (filename_str != NULL) { + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + err_ret->error = E_ERROR; + return NULL; + } + } + n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags); + Py_XDECREF(filename); + return n; +} + +/* Parse input coming from a file. Return error code, print some errors. */ + +node * +PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start, + const char *ps1, const char *ps2, + perrdetail *err_ret) +{ + return PyParser_ParseFileFlags(fp, filename, NULL, + g, start, ps1, ps2, err_ret, 0); +} + +node * +PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc, + grammar *g, int start, + const char *ps1, const char *ps2, + perrdetail *err_ret, int flags) +{ + int iflags = flags; + return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1, + ps2, err_ret, &iflags); +} + +node * +PyParser_ParseFileObject(FILE *fp, PyObject *filename, + const char *enc, grammar *g, int start, + const char *ps1, const char *ps2, + perrdetail *err_ret, int *flags) +{ + struct tok_state *tok; + + if (initerr(err_ret, filename) < 0) + return NULL; + + if (PySys_Audit("compile", "OO", Py_None, err_ret->filename) < 0) { + return NULL; + } + + if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) { + err_ret->error = E_NOMEM; + return NULL; + } + if (*flags & PyPARSE_TYPE_COMMENTS) { + tok->type_comments = 1; + } + Py_INCREF(err_ret->filename); + tok->filename = err_ret->filename; + return parsetok(tok, g, start, err_ret, flags); +} + +node * +PyParser_ParseFileFlagsEx(FILE *fp, const char *filename, + const char *enc, grammar *g, int start, + const char *ps1, const char *ps2, + perrdetail *err_ret, int *flags) +{ + node *n; + PyObject *fileobj = NULL; + if (filename != NULL) { + fileobj = PyUnicode_DecodeFSDefault(filename); + if (fileobj == NULL) { + err_ret->error = E_ERROR; + return NULL; + } + } + n = PyParser_ParseFileObject(fp, fileobj, enc, g, + start, ps1, ps2, err_ret, flags); + Py_XDECREF(fileobj); + return n; +} + +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 +static const char with_msg[] = +"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n"; + +static const char as_msg[] = +"%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n"; + +static void +warn(const char *msg, const char *filename, int lineno) +{ + if (filename == NULL) + filename = ""; + PySys_WriteStderr(msg, filename, lineno); +} +#endif +#endif + +/* Parse input coming from the given tokenizer structure. + Return error code. */ + +static node * +parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, + int *flags) +{ + parser_state *ps; + node *n; + int started = 0; + int col_offset, end_col_offset; + growable_comment_array type_ignores; + + if (!growable_comment_array_init(&type_ignores, 10)) { + err_ret->error = E_NOMEM; + PyTokenizer_Free(tok); + return NULL; + } + + if ((ps = PyParser_New(g, start)) == NULL) { + err_ret->error = E_NOMEM; + growable_comment_array_deallocate(&type_ignores); + PyTokenizer_Free(tok); + return NULL; + } +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD + if (*flags & PyPARSE_BARRY_AS_BDFL) + ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL; + if (*flags & PyPARSE_TYPE_COMMENTS) + ps->p_flags |= PyCF_TYPE_COMMENTS; +#endif + + for (;;) { + char *a, *b; + int type; + size_t len; + char *str; + col_offset = -1; + int lineno; + const char *line_start; + + type = PyTokenizer_Get(tok, &a, &b); + if (type == ERRORTOKEN) { + err_ret->error = tok->done; + break; + } + if (type == ENDMARKER && started) { + type = NEWLINE; /* Add an extra newline */ + started = 0; + /* Add the right number of dedent tokens, + except if a certain flag is given -- + codeop.py uses this. */ + if (tok->indent && + !(*flags & PyPARSE_DONT_IMPLY_DEDENT)) + { + tok->pendin = -tok->indent; + tok->indent = 0; + } + } + else + started = 1; + len = (a != NULL && b != NULL) ? b - a : 0; + str = (char *) PyObject_MALLOC(len + 1); + if (str == NULL) { + err_ret->error = E_NOMEM; + break; + } + if (len > 0) + strncpy(str, a, len); + str[len] = '\0'; + +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD + if (type == NOTEQUAL) { + if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && + strcmp(str, "!=")) { + PyObject_FREE(str); + err_ret->error = E_SYNTAX; + break; + } + else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && + strcmp(str, "<>")) { + PyObject_FREE(str); + err_ret->expected = NOTEQUAL; + err_ret->error = E_SYNTAX; + break; + } + } +#endif + + /* Nodes of type STRING, especially multi line strings + must be handled differently in order to get both + the starting line number and the column offset right. + (cf. issue 16806) */ + lineno = type == STRING ? tok->first_lineno : tok->lineno; + line_start = type == STRING ? tok->multi_line_start : tok->line_start; + if (a != NULL && a >= line_start) { + col_offset = Py_SAFE_DOWNCAST(a - line_start, + intptr_t, int); + } + else { + col_offset = -1; + } + + if (b != NULL && b >= tok->line_start) { + end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start, + intptr_t, int); + } + else { + end_col_offset = -1; + } + + if (type == TYPE_IGNORE) { + if (!growable_comment_array_add(&type_ignores, tok->lineno, str)) { + err_ret->error = E_NOMEM; + break; + } + continue; + } + + if ((err_ret->error = + PyParser_AddToken(ps, (int)type, str, + lineno, col_offset, tok->lineno, end_col_offset, + &(err_ret->expected))) != E_OK) { + if (err_ret->error != E_DONE) { + PyObject_FREE(str); + err_ret->token = type; + } + break; + } + } + + if (err_ret->error == E_DONE) { + n = ps->p_tree; + ps->p_tree = NULL; + + if (n->n_type == file_input) { + /* Put type_ignore nodes in the ENDMARKER of file_input. */ + int num; + node *ch; + size_t i; + + num = NCH(n); + ch = CHILD(n, num - 1); + REQ(ch, ENDMARKER); + + for (i = 0; i < type_ignores.num_items; i++) { + int res = PyNode_AddChild(ch, TYPE_IGNORE, type_ignores.items[i].comment, + type_ignores.items[i].lineno, 0, + type_ignores.items[i].lineno, 0); + if (res != 0) { + err_ret->error = res; + PyNode_Free(n); + n = NULL; + break; + } + type_ignores.items[i].comment = NULL; + } + } + + /* Check that the source for a single input statement really + is a single statement by looking at what is left in the + buffer after parsing. Trailing whitespace and comments + are OK. */ + if (err_ret->error == E_DONE && start == single_input) { + char *cur = tok->cur; + char c = *tok->cur; + + for (;;) { + while (c == ' ' || c == '\t' || c == '\n' || c == '\014') + c = *++cur; + + if (!c) + break; + + if (c != '#') { + err_ret->error = E_BADSINGLE; + PyNode_Free(n); + n = NULL; + break; + } + + /* Suck up comment. */ + while (c && c != '\n') + c = *++cur; + } + } + } + else + n = NULL; + + growable_comment_array_deallocate(&type_ignores); + +#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD + *flags = ps->p_flags; +#endif + PyParser_Delete(ps); + + if (n == NULL) { + if (tok->done == E_EOF) + err_ret->error = E_EOF; + err_ret->lineno = tok->lineno; + if (tok->buf != NULL) { + size_t len; + assert(tok->cur - tok->buf < INT_MAX); + /* if we've managed to parse a token, point the offset to its start, + * else use the current reading position of the tokenizer + */ + err_ret->offset = col_offset != -1 ? col_offset + 1 : ((int)(tok->cur - tok->buf)); + len = tok->inp - tok->buf; + err_ret->text = (char *) PyObject_MALLOC(len + 1); + if (err_ret->text != NULL) { + if (len > 0) + strncpy(err_ret->text, tok->buf, len); + err_ret->text[len] = '\0'; + } + } + } else if (tok->encoding != NULL) { + /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was + * allocated using PyMem_ + */ + node* r = PyNode_New(encoding_decl); + if (r) + r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1); + if (!r || !r->n_str) { + err_ret->error = E_NOMEM; + if (r) + PyObject_FREE(r); + n = NULL; + goto done; + } + strcpy(r->n_str, tok->encoding); + PyMem_FREE(tok->encoding); + tok->encoding = NULL; + r->n_nchildren = 1; + r->n_child = n; + n = r; + } + +done: + PyTokenizer_Free(tok); + + if (n != NULL) { + _PyNode_FinalizeEndPos(n); + } + return n; +} + +static int +initerr(perrdetail *err_ret, PyObject *filename) +{ + err_ret->error = E_OK; + err_ret->lineno = 0; + err_ret->offset = 0; + err_ret->text = NULL; + err_ret->token = -1; + err_ret->expected = -1; + if (filename) { + Py_INCREF(filename); + err_ret->filename = filename; + } + else { + err_ret->filename = PyUnicode_FromString(""); + if (err_ret->filename == NULL) { + err_ret->error = E_ERROR; + return -1; + } + } + return 0; +} diff --git a/python/Parser/pgen/__init__.py b/python/Parser/pgen/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/python/Parser/pgen/__main__.py b/python/Parser/pgen/__main__.py new file mode 100755 index 0000000..eea5261 --- /dev/null +++ b/python/Parser/pgen/__main__.py @@ -0,0 +1,35 @@ +import argparse + +from .pgen import ParserGenerator + + +def main(): + parser = argparse.ArgumentParser(description="Parser generator main program.") + parser.add_argument( + "grammar", type=str, help="The file with the grammar definition in EBNF format" + ) + parser.add_argument( + "tokens", type=str, help="The file with the token definitions" + ) + parser.add_argument( + "graminit_h", + type=argparse.FileType('w'), + help="The path to write the grammar's non-terminals as #defines", + ) + parser.add_argument( + "graminit_c", + type=argparse.FileType('w'), + help="The path to write the grammar as initialized data", + ) + + parser.add_argument("--verbose", "-v", action="count") + args = parser.parse_args() + + p = ParserGenerator(args.grammar, args.tokens, verbose=args.verbose) + grammar = p.make_grammar() + grammar.produce_graminit_h(args.graminit_h.write) + grammar.produce_graminit_c(args.graminit_c.write) + + +if __name__ == "__main__": + main() diff --git a/python/Parser/pgen/grammar.py b/python/Parser/pgen/grammar.py new file mode 100755 index 0000000..5cd6524 --- /dev/null +++ b/python/Parser/pgen/grammar.py @@ -0,0 +1,144 @@ +import collections + + +class Grammar: + """Pgen parsing tables class. + + The instance variables are as follows: + + symbol2number -- a dict mapping symbol names to numbers. Symbol + numbers are always 256 or higher, to distinguish + them from token numbers, which are between 0 and + 255 (inclusive). + + number2symbol -- a dict mapping numbers to symbol names; + these two are each other's inverse. + + states -- a list of DFAs, where each DFA is a list of + states, each state is a list of arcs, and each + arc is a (i, j) pair where i is a label and j is + a state number. The DFA number is the index into + this list. (This name is slightly confusing.) + Final states are represented by a special arc of + the form (0, j) where j is its own state number. + + dfas -- a dict mapping symbol numbers to (DFA, first) + pairs, where DFA is an item from the states list + above, and first is a set of tokens that can + begin this grammar rule. + + labels -- a list of (x, y) pairs where x is either a token + number or a symbol number, and y is either None + or a string; the strings are keywords. The label + number is the index in this list; label numbers + are used to mark state transitions (arcs) in the + DFAs. + + start -- the number of the grammar's start symbol. + + keywords -- a dict mapping keyword strings to arc labels. + + tokens -- a dict mapping token numbers to arc labels. + + """ + + def __init__(self): + self.symbol2number = collections.OrderedDict() + self.number2symbol = collections.OrderedDict() + self.states = [] + self.dfas = collections.OrderedDict() + self.labels = [(0, "EMPTY")] + self.keywords = collections.OrderedDict() + self.tokens = collections.OrderedDict() + self.symbol2label = collections.OrderedDict() + self.start = 256 + + def produce_graminit_h(self, writer): + writer("/* Generated by Parser/pgen */\n\n") + for number, symbol in self.number2symbol.items(): + writer("#define {} {}\n".format(symbol, number)) + + def produce_graminit_c(self, writer): + writer("/* Generated by Parser/pgen */\n\n") + + writer('#include "grammar.h"\n') + writer("grammar _PyParser_Grammar;\n") + + self.print_dfas(writer) + self.print_labels(writer) + + writer("grammar _PyParser_Grammar = {\n") + writer(" {n_dfas},\n".format(n_dfas=len(self.dfas))) + writer(" dfas,\n") + writer(" {{{n_labels}, labels}},\n".format(n_labels=len(self.labels))) + writer(" {start_number}\n".format(start_number=self.start)) + writer("};\n") + + def print_labels(self, writer): + writer( + "static const label labels[{n_labels}] = {{\n".format(n_labels=len(self.labels)) + ) + for label, name in self.labels: + label_name = '"{}"'.format(name) if name is not None else 0 + writer( + ' {{{label}, {label_name}}},\n'.format( + label=label, label_name=label_name + ) + ) + writer("};\n") + + def print_dfas(self, writer): + self.print_states(writer) + writer("static const dfa dfas[{}] = {{\n".format(len(self.dfas))) + for dfaindex, dfa_elem in enumerate(self.dfas.items()): + symbol, (dfa, first_sets) = dfa_elem + writer( + ' {{{dfa_symbol}, "{symbol_name}", '.format( + dfa_symbol=symbol, symbol_name=self.number2symbol[symbol] + ) + + "{n_states}, states_{dfa_index},\n".format( + n_states=len(dfa), dfa_index=dfaindex + ) + + ' "' + ) + + bitset = bytearray((len(self.labels) >> 3) + 1) + for token in first_sets: + bitset[token >> 3] |= 1 << (token & 7) + for byte in bitset: + writer("\\%03o" % (byte & 0xFF)) + writer('"},\n') + writer("};\n") + + def print_states(self, write): + for dfaindex, dfa in enumerate(self.states): + self.print_arcs(write, dfaindex, dfa) + write( + "static state states_{dfa_index}[{n_states}] = {{\n".format( + dfa_index=dfaindex, n_states=len(dfa) + ) + ) + for stateindex, state in enumerate(dfa): + narcs = len(state) + write( + " {{{n_arcs}, arcs_{dfa_index}_{state_index}}},\n".format( + n_arcs=narcs, dfa_index=dfaindex, state_index=stateindex + ) + ) + write("};\n") + + def print_arcs(self, write, dfaindex, states): + for stateindex, state in enumerate(states): + narcs = len(state) + write( + "static const arc arcs_{dfa_index}_{state_index}[{n_arcs}] = {{\n".format( + dfa_index=dfaindex, state_index=stateindex, n_arcs=narcs + ) + ) + for a, b in state: + write( + " {{{from_label}, {to_state}}},\n".format( + from_label=a, to_state=b + ) + ) + write("};\n") diff --git a/python/Parser/pgen/keywordgen.py b/python/Parser/pgen/keywordgen.py new file mode 100755 index 0000000..eeb3ef7 --- /dev/null +++ b/python/Parser/pgen/keywordgen.py @@ -0,0 +1,60 @@ +"""Generate Lib/keyword.py from the Grammar and Tokens files using pgen""" + +import argparse + +from .pgen import ParserGenerator + +TEMPLATE = r''' +"""Keywords (from "Grammar/Grammar") + +This file is automatically generated; please don't muck it up! + +To update the symbols in this file, 'cd' to the top directory of +the python source tree and run: + + python3 -m Parser.pgen.keywordgen Grammar/Grammar \ + Grammar/Tokens \ + Lib/keyword.py + +Alternatively, you can run 'make regen-keyword'. +""" + +__all__ = ["iskeyword", "kwlist"] + +kwlist = [ + {keywords} +] + +iskeyword = frozenset(kwlist).__contains__ +'''.lstrip() + +EXTRA_KEYWORDS = ["async", "await"] + + +def main(): + parser = argparse.ArgumentParser(description="Generate the Lib/keywords.py " + "file from the grammar.") + parser.add_argument( + "grammar", type=str, help="The file with the grammar definition in EBNF format" + ) + parser.add_argument( + "tokens", type=str, help="The file with the token definitions" + ) + parser.add_argument( + "keyword_file", + type=argparse.FileType('w'), + help="The path to write the keyword definitions", + ) + args = parser.parse_args() + p = ParserGenerator(args.grammar, args.tokens) + grammar = p.make_grammar() + + with args.keyword_file as thefile: + all_keywords = sorted(list(grammar.keywords) + EXTRA_KEYWORDS) + + keywords = ",\n ".join(map(repr, all_keywords)) + thefile.write(TEMPLATE.format(keywords=keywords)) + + +if __name__ == "__main__": + main() diff --git a/python/Parser/pgen/pgen.py b/python/Parser/pgen/pgen.py new file mode 100755 index 0000000..d52d58f --- /dev/null +++ b/python/Parser/pgen/pgen.py @@ -0,0 +1,406 @@ +import collections +import tokenize # from stdlib + +from . import grammar, token + + +class ParserGenerator(object): + + def __init__(self, grammar_file, token_file, stream=None, verbose=False): + close_stream = None + if stream is None: + stream = open(grammar_file) + close_stream = stream.close + with open(token_file) as tok_file: + token_lines = tok_file.readlines() + self.tokens = dict(token.generate_tokens(token_lines)) + self.opmap = dict(token.generate_opmap(token_lines)) + # Manually add <> so it does not collide with != + self.opmap['<>'] = "NOTEQUAL" + self.verbose = verbose + self.filename = grammar_file + self.stream = stream + self.generator = tokenize.generate_tokens(stream.readline) + self.gettoken() # Initialize lookahead + self.dfas, self.startsymbol = self.parse() + if close_stream is not None: + close_stream() + self.first = {} # map from symbol name to set of tokens + self.addfirstsets() + + def make_grammar(self): + c = grammar.Grammar() + names = list(self.dfas.keys()) + names.remove(self.startsymbol) + names.insert(0, self.startsymbol) + for name in names: + i = 256 + len(c.symbol2number) + c.symbol2number[name] = i + c.number2symbol[i] = name + for name in names: + self.make_label(c, name) + dfa = self.dfas[name] + states = [] + for state in dfa: + arcs = [] + for label, next in sorted(state.arcs.items()): + arcs.append((self.make_label(c, label), dfa.index(next))) + if state.isfinal: + arcs.append((0, dfa.index(state))) + states.append(arcs) + c.states.append(states) + c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) + c.start = c.symbol2number[self.startsymbol] + + if self.verbose: + print("") + print("Grammar summary") + print("===============") + + print("- {n_labels} labels".format(n_labels=len(c.labels))) + print("- {n_dfas} dfas".format(n_dfas=len(c.dfas))) + print("- {n_tokens} tokens".format(n_tokens=len(c.tokens))) + print("- {n_keywords} keywords".format(n_keywords=len(c.keywords))) + print( + "- Start symbol: {start_symbol}".format( + start_symbol=c.number2symbol[c.start] + ) + ) + return c + + def make_first(self, c, name): + rawfirst = self.first[name] + first = set() + for label in sorted(rawfirst): + ilabel = self.make_label(c, label) + ##assert ilabel not in first # XXX failed on <> ... != + first.add(ilabel) + return first + + def make_label(self, c, label): + # XXX Maybe this should be a method on a subclass of converter? + ilabel = len(c.labels) + if label[0].isalpha(): + # Either a symbol name or a named token + if label in c.symbol2number: + # A symbol name (a non-terminal) + if label in c.symbol2label: + return c.symbol2label[label] + else: + c.labels.append((c.symbol2number[label], None)) + c.symbol2label[label] = ilabel + return ilabel + else: + # A named token (NAME, NUMBER, STRING) + itoken = self.tokens.get(label, None) + assert isinstance(itoken, int), label + assert itoken in self.tokens.values(), label + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + else: + # Either a keyword or an operator + assert label[0] in ('"', "'"), label + value = eval(label) + if value[0].isalpha(): + # A keyword + if value in c.keywords: + return c.keywords[value] + else: + c.labels.append((self.tokens["NAME"], value)) + c.keywords[value] = ilabel + return ilabel + else: + # An operator (any non-numeric token) + tok_name = self.opmap[value] # Fails if unknown token + itoken = self.tokens[tok_name] + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + + def addfirstsets(self): + names = list(self.dfas.keys()) + for name in names: + if name not in self.first: + self.calcfirst(name) + + if self.verbose: + print("First set for {dfa_name}".format(dfa_name=name)) + for item in self.first[name]: + print(" - {terminal}".format(terminal=item)) + + def calcfirst(self, name): + dfa = self.dfas[name] + self.first[name] = None # dummy to detect left recursion + state = dfa[0] + totalset = set() + overlapcheck = {} + for label, next in state.arcs.items(): + if label in self.dfas: + if label in self.first: + fset = self.first[label] + if fset is None: + raise ValueError("recursion for rule %r" % name) + else: + self.calcfirst(label) + fset = self.first[label] + totalset.update(fset) + overlapcheck[label] = fset + else: + totalset.add(label) + overlapcheck[label] = {label} + inverse = {} + for label, itsfirst in overlapcheck.items(): + for symbol in itsfirst: + if symbol in inverse: + raise ValueError("rule %s is ambiguous; %s is in the" + " first sets of %s as well as %s" % + (name, symbol, label, inverse[symbol])) + inverse[symbol] = label + self.first[name] = totalset + + def parse(self): + dfas = collections.OrderedDict() + startsymbol = None + # MSTART: (NEWLINE | RULE)* ENDMARKER + while self.type != tokenize.ENDMARKER: + while self.type == tokenize.NEWLINE: + self.gettoken() + # RULE: NAME ':' RHS NEWLINE + name = self.expect(tokenize.NAME) + if self.verbose: + print("Processing rule {dfa_name}".format(dfa_name=name)) + self.expect(tokenize.OP, ":") + a, z = self.parse_rhs() + self.expect(tokenize.NEWLINE) + if self.verbose: + self.dump_nfa(name, a, z) + dfa = self.make_dfa(a, z) + if self.verbose: + self.dump_dfa(name, dfa) + self.simplify_dfa(dfa) + dfas[name] = dfa + if startsymbol is None: + startsymbol = name + return dfas, startsymbol + + def make_dfa(self, start, finish): + # To turn an NFA into a DFA, we define the states of the DFA + # to correspond to *sets* of states of the NFA. Then do some + # state reduction. Let's represent sets as dicts with 1 for + # values. + assert isinstance(start, NFAState) + assert isinstance(finish, NFAState) + def closure(state): + base = set() + addclosure(state, base) + return base + def addclosure(state, base): + assert isinstance(state, NFAState) + if state in base: + return + base.add(state) + for label, next in state.arcs: + if label is None: + addclosure(next, base) + states = [DFAState(closure(start), finish)] + for state in states: # NB states grows while we're iterating + arcs = {} + for nfastate in state.nfaset: + for label, next in nfastate.arcs: + if label is not None: + addclosure(next, arcs.setdefault(label, set())) + for label, nfaset in sorted(arcs.items()): + for st in states: + if st.nfaset == nfaset: + break + else: + st = DFAState(nfaset, finish) + states.append(st) + state.addarc(st, label) + return states # List of DFAState instances; first one is start + + def dump_nfa(self, name, start, finish): + print("Dump of NFA for", name) + todo = [start] + for i, state in enumerate(todo): + print(" State", i, state is finish and "(final)" or "") + for label, next in state.arcs: + if next in todo: + j = todo.index(next) + else: + j = len(todo) + todo.append(next) + if label is None: + print(" -> %d" % j) + else: + print(" %s -> %d" % (label, j)) + + def dump_dfa(self, name, dfa): + print("Dump of DFA for", name) + for i, state in enumerate(dfa): + print(" State", i, state.isfinal and "(final)" or "") + for label, next in sorted(state.arcs.items()): + print(" %s -> %d" % (label, dfa.index(next))) + + def simplify_dfa(self, dfa): + # This is not theoretically optimal, but works well enough. + # Algorithm: repeatedly look for two states that have the same + # set of arcs (same labels pointing to the same nodes) and + # unify them, until things stop changing. + + # dfa is a list of DFAState instances + changes = True + while changes: + changes = False + for i, state_i in enumerate(dfa): + for j in range(i+1, len(dfa)): + state_j = dfa[j] + if state_i == state_j: + #print " unify", i, j + del dfa[j] + for state in dfa: + state.unifystate(state_j, state_i) + changes = True + break + + def parse_rhs(self): + # RHS: ALT ('|' ALT)* + a, z = self.parse_alt() + if self.value != "|": + return a, z + else: + aa = NFAState() + zz = NFAState() + aa.addarc(a) + z.addarc(zz) + while self.value == "|": + self.gettoken() + a, z = self.parse_alt() + aa.addarc(a) + z.addarc(zz) + return aa, zz + + def parse_alt(self): + # ALT: ITEM+ + a, b = self.parse_item() + while (self.value in ("(", "[") or + self.type in (tokenize.NAME, tokenize.STRING)): + c, d = self.parse_item() + b.addarc(c) + b = d + return a, b + + def parse_item(self): + # ITEM: '[' RHS ']' | ATOM ['+' | '*'] + if self.value == "[": + self.gettoken() + a, z = self.parse_rhs() + self.expect(tokenize.OP, "]") + a.addarc(z) + return a, z + else: + a, z = self.parse_atom() + value = self.value + if value not in ("+", "*"): + return a, z + self.gettoken() + z.addarc(a) + if value == "+": + return a, z + else: + return a, a + + def parse_atom(self): + # ATOM: '(' RHS ')' | NAME | STRING + if self.value == "(": + self.gettoken() + a, z = self.parse_rhs() + self.expect(tokenize.OP, ")") + return a, z + elif self.type in (tokenize.NAME, tokenize.STRING): + a = NFAState() + z = NFAState() + a.addarc(z, self.value) + self.gettoken() + return a, z + else: + self.raise_error("expected (...) or NAME or STRING, got %s/%s", + self.type, self.value) + + def expect(self, type, value=None): + if self.type != type or (value is not None and self.value != value): + self.raise_error("expected %s/%s, got %s/%s", + type, value, self.type, self.value) + value = self.value + self.gettoken() + return value + + def gettoken(self): + tup = next(self.generator) + while tup[0] in (tokenize.COMMENT, tokenize.NL): + tup = next(self.generator) + self.type, self.value, self.begin, self.end, self.line = tup + # print(getattr(tokenize, 'tok_name')[self.type], repr(self.value)) + + def raise_error(self, msg, *args): + if args: + try: + msg = msg % args + except Exception: + msg = " ".join([msg] + list(map(str, args))) + raise SyntaxError(msg, (self.filename, self.end[0], + self.end[1], self.line)) + +class NFAState(object): + + def __init__(self): + self.arcs = [] # list of (label, NFAState) pairs + + def addarc(self, next, label=None): + assert label is None or isinstance(label, str) + assert isinstance(next, NFAState) + self.arcs.append((label, next)) + +class DFAState(object): + + def __init__(self, nfaset, final): + assert isinstance(nfaset, set) + assert isinstance(next(iter(nfaset)), NFAState) + assert isinstance(final, NFAState) + self.nfaset = nfaset + self.isfinal = final in nfaset + self.arcs = {} # map from label to DFAState + + def addarc(self, next, label): + assert isinstance(label, str) + assert label not in self.arcs + assert isinstance(next, DFAState) + self.arcs[label] = next + + def unifystate(self, old, new): + for label, next in self.arcs.items(): + if next is old: + self.arcs[label] = new + + def __eq__(self, other): + # Equality test -- ignore the nfaset instance variable + assert isinstance(other, DFAState) + if self.isfinal != other.isfinal: + return False + # Can't just return self.arcs == other.arcs, because that + # would invoke this method recursively, with cycles... + if len(self.arcs) != len(other.arcs): + return False + for label, next in self.arcs.items(): + if next is not other.arcs.get(label): + return False + return True + + __hash__ = None # For Py3 compatibility. diff --git a/python/Parser/pgen/token.py b/python/Parser/pgen/token.py new file mode 100755 index 0000000..008e241 --- /dev/null +++ b/python/Parser/pgen/token.py @@ -0,0 +1,42 @@ +import itertools + + +def generate_tokens(tokens): + numbers = itertools.count(0) + for line in tokens: + line = line.strip() + + if not line: + continue + if line.strip().startswith('#'): + continue + + name = line.split()[0] + yield (name, next(numbers)) + + yield ('N_TOKENS', next(numbers)) + yield ('NT_OFFSET', 256) + + +def generate_opmap(tokens): + for line in tokens: + line = line.strip() + + if not line: + continue + if line.strip().startswith('#'): + continue + + pieces = line.split() + + if len(pieces) != 2: + continue + + name, op = pieces + yield (op.strip("'"), name) + + # Yield independently <>. This is needed so it does not collide + # with the token generation in "generate_tokens" because if this + # symbol is included in Grammar/Tokens, it will collide with != + # as it has the same name (NOTEQUAL). + yield ('<>', 'NOTEQUAL') diff --git a/python/Parser/token.c b/python/Parser/token.c new file mode 100755 index 0000000..a489668 --- /dev/null +++ b/python/Parser/token.c @@ -0,0 +1,243 @@ +/* Auto-generated by Tools/scripts/generate_token.py */ + +#include "Python.h" +#include "token.h" + +/* Token names */ + +const char * const _PyParser_TokenNames[] = { + "ENDMARKER", + "NAME", + "NUMBER", + "STRING", + "NEWLINE", + "INDENT", + "DEDENT", + "LPAR", + "RPAR", + "LSQB", + "RSQB", + "COLON", + "COMMA", + "SEMI", + "PLUS", + "MINUS", + "STAR", + "SLASH", + "VBAR", + "AMPER", + "LESS", + "GREATER", + "EQUAL", + "DOT", + "PERCENT", + "LBRACE", + "RBRACE", + "EQEQUAL", + "NOTEQUAL", + "LESSEQUAL", + "GREATEREQUAL", + "TILDE", + "CIRCUMFLEX", + "LEFTSHIFT", + "RIGHTSHIFT", + "DOUBLESTAR", + "PLUSEQUAL", + "MINEQUAL", + "STAREQUAL", + "SLASHEQUAL", + "PERCENTEQUAL", + "AMPEREQUAL", + "VBAREQUAL", + "CIRCUMFLEXEQUAL", + "LEFTSHIFTEQUAL", + "RIGHTSHIFTEQUAL", + "DOUBLESTAREQUAL", + "DOUBLESLASH", + "DOUBLESLASHEQUAL", + "AT", + "ATEQUAL", + "RARROW", + "ELLIPSIS", + "COLONEQUAL", + "OP", + "AWAIT", + "ASYNC", + "TYPE_IGNORE", + "TYPE_COMMENT", + "", + "", + "", + "", + "", +}; + +/* Return the token corresponding to a single character */ + +int +PyToken_OneChar(int c1) +{ + switch (c1) { + case '%': return PERCENT; + case '&': return AMPER; + case '(': return LPAR; + case ')': return RPAR; + case '*': return STAR; + case '+': return PLUS; + case ',': return COMMA; + case '-': return MINUS; + case '.': return DOT; + case '/': return SLASH; + case ':': return COLON; + case ';': return SEMI; + case '<': return LESS; + case '=': return EQUAL; + case '>': return GREATER; + case '@': return AT; + case '[': return LSQB; + case ']': return RSQB; + case '^': return CIRCUMFLEX; + case '{': return LBRACE; + case '|': return VBAR; + case '}': return RBRACE; + case '~': return TILDE; + } + return OP; +} + +int +PyToken_TwoChars(int c1, int c2) +{ + switch (c1) { + case '!': + switch (c2) { + case '=': return NOTEQUAL; + } + break; + case '%': + switch (c2) { + case '=': return PERCENTEQUAL; + } + break; + case '&': + switch (c2) { + case '=': return AMPEREQUAL; + } + break; + case '*': + switch (c2) { + case '*': return DOUBLESTAR; + case '=': return STAREQUAL; + } + break; + case '+': + switch (c2) { + case '=': return PLUSEQUAL; + } + break; + case '-': + switch (c2) { + case '=': return MINEQUAL; + case '>': return RARROW; + } + break; + case '/': + switch (c2) { + case '/': return DOUBLESLASH; + case '=': return SLASHEQUAL; + } + break; + case ':': + switch (c2) { + case '=': return COLONEQUAL; + } + break; + case '<': + switch (c2) { + case '<': return LEFTSHIFT; + case '=': return LESSEQUAL; + case '>': return NOTEQUAL; + } + break; + case '=': + switch (c2) { + case '=': return EQEQUAL; + } + break; + case '>': + switch (c2) { + case '=': return GREATEREQUAL; + case '>': return RIGHTSHIFT; + } + break; + case '@': + switch (c2) { + case '=': return ATEQUAL; + } + break; + case '^': + switch (c2) { + case '=': return CIRCUMFLEXEQUAL; + } + break; + case '|': + switch (c2) { + case '=': return VBAREQUAL; + } + break; + } + return OP; +} + +int +PyToken_ThreeChars(int c1, int c2, int c3) +{ + switch (c1) { + case '*': + switch (c2) { + case '*': + switch (c3) { + case '=': return DOUBLESTAREQUAL; + } + break; + } + break; + case '.': + switch (c2) { + case '.': + switch (c3) { + case '.': return ELLIPSIS; + } + break; + } + break; + case '/': + switch (c2) { + case '/': + switch (c3) { + case '=': return DOUBLESLASHEQUAL; + } + break; + } + break; + case '<': + switch (c2) { + case '<': + switch (c3) { + case '=': return LEFTSHIFTEQUAL; + } + break; + } + break; + case '>': + switch (c2) { + case '>': + switch (c3) { + case '=': return RIGHTSHIFTEQUAL; + } + break; + } + break; + } + return OP; +} diff --git a/python/Parser/tokenizer.c b/python/Parser/tokenizer.c new file mode 100755 index 0000000..aecbceb --- /dev/null +++ b/python/Parser/tokenizer.c @@ -0,0 +1,1882 @@ + +/* Tokenizer implementation */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" + +#include +#include + +#include "tokenizer.h" +#include "errcode.h" + +#include "unicodeobject.h" +#include "bytesobject.h" +#include "fileobject.h" +#include "codecs.h" +#include "abstract.h" + +/* Alternate tab spacing */ +#define ALTTABSIZE 1 + +#define is_potential_identifier_start(c) (\ + (c >= 'a' && c <= 'z')\ + || (c >= 'A' && c <= 'Z')\ + || c == '_'\ + || (c >= 128)) + +#define is_potential_identifier_char(c) (\ + (c >= 'a' && c <= 'z')\ + || (c >= 'A' && c <= 'Z')\ + || (c >= '0' && c <= '9')\ + || c == '_'\ + || (c >= 128)) + +extern char *PyOS_Readline(FILE *, FILE *, const char *); +/* Return malloc'ed string including trailing \n; + empty malloc'ed string for EOF; + NULL if interrupted */ + +/* Don't ever change this -- it would break the portability of Python code */ +#define TABSIZE 8 + +/* Forward */ +static struct tok_state *tok_new(void); +static int tok_nextc(struct tok_state *tok); +static void tok_backup(struct tok_state *tok, int c); + + +/* Spaces in this constant are treated as "zero or more spaces or tabs" when + tokenizing. */ +static const char* type_comment_prefix = "# type: "; + +/* Create and initialize a new tok_state structure */ + +static struct tok_state * +tok_new(void) +{ + struct tok_state *tok = (struct tok_state *)PyMem_MALLOC( + sizeof(struct tok_state)); + if (tok == NULL) + return NULL; + tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->done = E_OK; + tok->fp = NULL; + tok->input = NULL; + tok->tabsize = TABSIZE; + tok->indent = 0; + tok->indstack[0] = 0; + + tok->atbol = 1; + tok->pendin = 0; + tok->prompt = tok->nextprompt = NULL; + tok->lineno = 0; + tok->level = 0; + tok->altindstack[0] = 0; + tok->decoding_state = STATE_INIT; + tok->decoding_erred = 0; + tok->read_coding_spec = 0; + tok->enc = NULL; + tok->encoding = NULL; + tok->cont_line = 0; + tok->filename = NULL; + tok->decoding_readline = NULL; + tok->decoding_buffer = NULL; + tok->type_comments = 0; + + tok->async_hacks = 0; + tok->async_def = 0; + tok->async_def_indent = 0; + tok->async_def_nl = 0; + + return tok; +} + +static char * +new_string(const char *s, Py_ssize_t len, struct tok_state *tok) +{ + char* result = (char *)PyMem_MALLOC(len + 1); + if (!result) { + tok->done = E_NOMEM; + return NULL; + } + memcpy(result, s, len); + result[len] = '\0'; + return result; +} + +static char * +error_ret(struct tok_state *tok) /* XXX */ +{ + tok->decoding_erred = 1; + if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */ + PyMem_FREE(tok->buf); + tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->done = E_DECODE; + return NULL; /* as if it were EOF */ +} + + +static const char * +get_normal_name(const char *s) /* for utf-8 and latin-1 */ +{ + char buf[13]; + int i; + for (i = 0; i < 12; i++) { + int c = s[i]; + if (c == '\0') + break; + else if (c == '_') + buf[i] = '-'; + else + buf[i] = tolower(c); + } + buf[i] = '\0'; + if (strcmp(buf, "utf-8") == 0 || + strncmp(buf, "utf-8-", 6) == 0) + return "utf-8"; + else if (strcmp(buf, "latin-1") == 0 || + strcmp(buf, "iso-8859-1") == 0 || + strcmp(buf, "iso-latin-1") == 0 || + strncmp(buf, "latin-1-", 8) == 0 || + strncmp(buf, "iso-8859-1-", 11) == 0 || + strncmp(buf, "iso-latin-1-", 12) == 0) + return "iso-8859-1"; + else + return s; +} + +/* Return the coding spec in S, or NULL if none is found. */ + +static int +get_coding_spec(const char *s, char **spec, Py_ssize_t size, struct tok_state *tok) +{ + Py_ssize_t i; + *spec = NULL; + /* Coding spec must be in a comment, and that comment must be + * the only statement on the source code line. */ + for (i = 0; i < size - 6; i++) { + if (s[i] == '#') + break; + if (s[i] != ' ' && s[i] != '\t' && s[i] != '\014') + return 1; + } + for (; i < size - 6; i++) { /* XXX inefficient search */ + const char* t = s + i; + if (strncmp(t, "coding", 6) == 0) { + const char* begin = NULL; + t += 6; + if (t[0] != ':' && t[0] != '=') + continue; + do { + t++; + } while (t[0] == '\x20' || t[0] == '\t'); + + begin = t; + while (Py_ISALNUM(t[0]) || + t[0] == '-' || t[0] == '_' || t[0] == '.') + t++; + + if (begin < t) { + char* r = new_string(begin, t - begin, tok); + const char* q; + if (!r) + return 0; + q = get_normal_name(r); + if (r != q) { + PyMem_FREE(r); + r = new_string(q, strlen(q), tok); + if (!r) + return 0; + } + *spec = r; + break; + } + } + } + return 1; +} + +/* Check whether the line contains a coding spec. If it does, + invoke the set_readline function for the new encoding. + This function receives the tok_state and the new encoding. + Return 1 on success, 0 on failure. */ + +static int +check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, + int set_readline(struct tok_state *, const char *)) +{ + char *cs; + int r = 1; + + if (tok->cont_line) { + /* It's a continuation line, so it can't be a coding spec. */ + tok->read_coding_spec = 1; + return 1; + } + if (!get_coding_spec(line, &cs, size, tok)) + return 0; + if (!cs) { + Py_ssize_t i; + for (i = 0; i < size; i++) { + if (line[i] == '#' || line[i] == '\n' || line[i] == '\r') + break; + if (line[i] != ' ' && line[i] != '\t' && line[i] != '\014') { + /* Stop checking coding spec after a line containing + * anything except a comment. */ + tok->read_coding_spec = 1; + break; + } + } + return 1; + } + tok->read_coding_spec = 1; + if (tok->encoding == NULL) { + assert(tok->decoding_state == STATE_RAW); + if (strcmp(cs, "utf-8") == 0) { + tok->encoding = cs; + } else { + r = set_readline(tok, cs); + if (r) { + tok->encoding = cs; + tok->decoding_state = STATE_NORMAL; + } + else { + PyErr_Format(PyExc_SyntaxError, + "encoding problem: %s", cs); + PyMem_FREE(cs); + } + } + } else { /* then, compare cs with BOM */ + r = (strcmp(tok->encoding, cs) == 0); + if (!r) + PyErr_Format(PyExc_SyntaxError, + "encoding problem: %s with BOM", cs); + PyMem_FREE(cs); + } + return r; +} + +/* See whether the file starts with a BOM. If it does, + invoke the set_readline function with the new encoding. + Return 1 on success, 0 on failure. */ + +static int +check_bom(int get_char(struct tok_state *), + void unget_char(int, struct tok_state *), + int set_readline(struct tok_state *, const char *), + struct tok_state *tok) +{ + int ch1, ch2, ch3; + ch1 = get_char(tok); + tok->decoding_state = STATE_RAW; + if (ch1 == EOF) { + return 1; + } else if (ch1 == 0xEF) { + ch2 = get_char(tok); + if (ch2 != 0xBB) { + unget_char(ch2, tok); + unget_char(ch1, tok); + return 1; + } + ch3 = get_char(tok); + if (ch3 != 0xBF) { + unget_char(ch3, tok); + unget_char(ch2, tok); + unget_char(ch1, tok); + return 1; + } +#if 0 + /* Disable support for UTF-16 BOMs until a decision + is made whether this needs to be supported. */ + } else if (ch1 == 0xFE) { + ch2 = get_char(tok); + if (ch2 != 0xFF) { + unget_char(ch2, tok); + unget_char(ch1, tok); + return 1; + } + if (!set_readline(tok, "utf-16-be")) + return 0; + tok->decoding_state = STATE_NORMAL; + } else if (ch1 == 0xFF) { + ch2 = get_char(tok); + if (ch2 != 0xFE) { + unget_char(ch2, tok); + unget_char(ch1, tok); + return 1; + } + if (!set_readline(tok, "utf-16-le")) + return 0; + tok->decoding_state = STATE_NORMAL; +#endif + } else { + unget_char(ch1, tok); + return 1; + } + if (tok->encoding != NULL) + PyMem_FREE(tok->encoding); + tok->encoding = new_string("utf-8", 5, tok); + if (!tok->encoding) + return 0; + /* No need to set_readline: input is already utf-8 */ + return 1; +} + +/* Read a line of text from TOK into S, using the stream in TOK. + Return NULL on failure, else S. + + On entry, tok->decoding_buffer will be one of: + 1) NULL: need to call tok->decoding_readline to get a new line + 2) PyUnicodeObject *: decoding_feof has called tok->decoding_readline and + stored the result in tok->decoding_buffer + 3) PyByteArrayObject *: previous call to fp_readl did not have enough room + (in the s buffer) to copy entire contents of the line read + by tok->decoding_readline. tok->decoding_buffer has the overflow. + In this case, fp_readl is called in a loop (with an expanded buffer) + until the buffer ends with a '\n' (or until the end of the file is + reached): see tok_nextc and its calls to decoding_fgets. +*/ + +static char * +fp_readl(char *s, int size, struct tok_state *tok) +{ + PyObject* bufobj; + const char *buf; + Py_ssize_t buflen; + + /* Ask for one less byte so we can terminate it */ + assert(size > 0); + size--; + + if (tok->decoding_buffer) { + bufobj = tok->decoding_buffer; + Py_INCREF(bufobj); + } + else + { + bufobj = _PyObject_CallNoArg(tok->decoding_readline); + if (bufobj == NULL) + goto error; + } + if (PyUnicode_CheckExact(bufobj)) + { + buf = PyUnicode_AsUTF8AndSize(bufobj, &buflen); + if (buf == NULL) { + goto error; + } + } + else + { + buf = PyByteArray_AsString(bufobj); + if (buf == NULL) { + goto error; + } + buflen = PyByteArray_GET_SIZE(bufobj); + } + + Py_XDECREF(tok->decoding_buffer); + if (buflen > size) { + /* Too many chars, the rest goes into tok->decoding_buffer */ + tok->decoding_buffer = PyByteArray_FromStringAndSize(buf+size, + buflen-size); + if (tok->decoding_buffer == NULL) + goto error; + buflen = size; + } + else + tok->decoding_buffer = NULL; + + memcpy(s, buf, buflen); + s[buflen] = '\0'; + if (buflen == 0) /* EOF */ + s = NULL; + Py_DECREF(bufobj); + return s; + +error: + Py_XDECREF(bufobj); + return error_ret(tok); +} + +/* Set the readline function for TOK to a StreamReader's + readline function. The StreamReader is named ENC. + + This function is called from check_bom and check_coding_spec. + + ENC is usually identical to the future value of tok->encoding, + except for the (currently unsupported) case of UTF-16. + + Return 1 on success, 0 on failure. */ + +static int +fp_setreadl(struct tok_state *tok, const char* enc) +{ + PyObject *readline, *io, *stream; + _Py_IDENTIFIER(open); + _Py_IDENTIFIER(readline); + int fd; + long pos; + + fd = fileno(tok->fp); + /* Due to buffering the file offset for fd can be different from the file + * position of tok->fp. If tok->fp was opened in text mode on Windows, + * its file position counts CRLF as one char and can't be directly mapped + * to the file offset for fd. Instead we step back one byte and read to + * the end of line.*/ + pos = ftell(tok->fp); + if (pos == -1 || + lseek(fd, (off_t)(pos > 0 ? pos - 1 : pos), SEEK_SET) == (off_t)-1) { + PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL); + return 0; + } + + io = PyImport_ImportModuleNoBlock("io"); + if (io == NULL) + return 0; + + stream = _PyObject_CallMethodId(io, &PyId_open, "isisOOO", + fd, "r", -1, enc, Py_None, Py_None, Py_False); + Py_DECREF(io); + if (stream == NULL) + return 0; + + readline = _PyObject_GetAttrId(stream, &PyId_readline); + Py_DECREF(stream); + if (readline == NULL) + return 0; + Py_XSETREF(tok->decoding_readline, readline); + + if (pos > 0) { + PyObject *bufobj = _PyObject_CallNoArg(readline); + if (bufobj == NULL) + return 0; + Py_DECREF(bufobj); + } + + return 1; +} + +/* Fetch the next byte from TOK. */ + +static int fp_getc(struct tok_state *tok) { + return getc(tok->fp); +} + +/* Unfetch the last byte back into TOK. */ + +static void fp_ungetc(int c, struct tok_state *tok) { + ungetc(c, tok->fp); +} + +/* Check whether the characters at s start a valid + UTF-8 sequence. Return the number of characters forming + the sequence if yes, 0 if not. */ +static int valid_utf8(const unsigned char* s) +{ + int expected = 0; + int length; + if (*s < 0x80) + /* single-byte code */ + return 1; + if (*s < 0xc0) + /* following byte */ + return 0; + if (*s < 0xE0) + expected = 1; + else if (*s < 0xF0) + expected = 2; + else if (*s < 0xF8) + expected = 3; + else + return 0; + length = expected + 1; + for (; expected; expected--) + if (s[expected] < 0x80 || s[expected] >= 0xC0) + return 0; + return length; +} + +/* Read a line of input from TOK. Determine encoding + if necessary. */ + +static char * +decoding_fgets(char *s, int size, struct tok_state *tok) +{ + char *line = NULL; + int badchar = 0; + for (;;) { + if (tok->decoding_state == STATE_NORMAL) { + /* We already have a codec associated with + this input. */ + line = fp_readl(s, size, tok); + break; + } else if (tok->decoding_state == STATE_RAW) { + /* We want a 'raw' read. */ + line = Py_UniversalNewlineFgets(s, size, + tok->fp, NULL); + break; + } else { + /* We have not yet determined the encoding. + If an encoding is found, use the file-pointer + reader functions from now on. */ + if (!check_bom(fp_getc, fp_ungetc, fp_setreadl, tok)) + return error_ret(tok); + assert(tok->decoding_state != STATE_INIT); + } + } + if (line != NULL && tok->lineno < 2 && !tok->read_coding_spec) { + if (!check_coding_spec(line, strlen(line), tok, fp_setreadl)) { + return error_ret(tok); + } + } + /* The default encoding is UTF-8, so make sure we don't have any + non-UTF-8 sequences in it. */ + if (line && !tok->encoding) { + unsigned char *c; + int length; + for (c = (unsigned char *)line; *c; c += length) + if (!(length = valid_utf8(c))) { + badchar = *c; + break; + } + } + if (badchar) { + /* Need to add 1 to the line number, since this line + has not been counted, yet. */ + PyErr_Format(PyExc_SyntaxError, + "Non-UTF-8 code starting with '\\x%.2x' " + "in file %U on line %i, " + "but no encoding declared; " + "see http://python.org/dev/peps/pep-0263/ for details", + badchar, tok->filename, tok->lineno + 1); + return error_ret(tok); + } + return line; +} + +static int +decoding_feof(struct tok_state *tok) +{ + if (tok->decoding_state != STATE_NORMAL) { + return feof(tok->fp); + } else { + PyObject* buf = tok->decoding_buffer; + if (buf == NULL) { + buf = _PyObject_CallNoArg(tok->decoding_readline); + if (buf == NULL) { + error_ret(tok); + return 1; + } else { + tok->decoding_buffer = buf; + } + } + return PyObject_Length(buf) == 0; + } +} + +/* Fetch a byte from TOK, using the string buffer. */ + +static int +buf_getc(struct tok_state *tok) { + return Py_CHARMASK(*tok->str++); +} + +/* Unfetch a byte from TOK, using the string buffer. */ + +static void +buf_ungetc(int c, struct tok_state *tok) { + tok->str--; + assert(Py_CHARMASK(*tok->str) == c); /* tok->cur may point to read-only segment */ +} + +/* Set the readline function for TOK to ENC. For the string-based + tokenizer, this means to just record the encoding. */ + +static int +buf_setreadl(struct tok_state *tok, const char* enc) { + tok->enc = enc; + return 1; +} + +/* Return a UTF-8 encoding Python string object from the + C byte string STR, which is encoded with ENC. */ + +static PyObject * +translate_into_utf8(const char* str, const char* enc) { + PyObject *utf8; + PyObject* buf = PyUnicode_Decode(str, strlen(str), enc, NULL); + if (buf == NULL) + return NULL; + utf8 = PyUnicode_AsUTF8String(buf); + Py_DECREF(buf); + return utf8; +} + + +static char * +translate_newlines(const char *s, int exec_input, struct tok_state *tok) { + int skip_next_lf = 0; + size_t needed_length = strlen(s) + 2, final_length; + char *buf, *current; + char c = '\0'; + buf = PyMem_MALLOC(needed_length); + if (buf == NULL) { + tok->done = E_NOMEM; + return NULL; + } + for (current = buf; *s; s++, current++) { + c = *s; + if (skip_next_lf) { + skip_next_lf = 0; + if (c == '\n') { + c = *++s; + if (!c) + break; + } + } + if (c == '\r') { + skip_next_lf = 1; + c = '\n'; + } + *current = c; + } + /* If this is exec input, add a newline to the end of the string if + there isn't one already. */ + if (exec_input && c != '\n') { + *current = '\n'; + current++; + } + *current = '\0'; + final_length = current - buf + 1; + if (final_length < needed_length && final_length) { + /* should never fail */ + char* result = PyMem_REALLOC(buf, final_length); + if (result == NULL) { + PyMem_FREE(buf); + } + buf = result; + } + return buf; +} + +/* Decode a byte string STR for use as the buffer of TOK. + Look for encoding declarations inside STR, and record them + inside TOK. */ + +static const char * +decode_str(const char *input, int single, struct tok_state *tok) +{ + PyObject* utf8 = NULL; + const char *str; + const char *s; + const char *newl[2] = {NULL, NULL}; + int lineno = 0; + tok->input = str = translate_newlines(input, single, tok); + if (str == NULL) + return NULL; + tok->enc = NULL; + tok->str = str; + if (!check_bom(buf_getc, buf_ungetc, buf_setreadl, tok)) + return error_ret(tok); + str = tok->str; /* string after BOM if any */ + assert(str); + if (tok->enc != NULL) { + utf8 = translate_into_utf8(str, tok->enc); + if (utf8 == NULL) + return error_ret(tok); + str = PyBytes_AsString(utf8); + } + for (s = str;; s++) { + if (*s == '\0') break; + else if (*s == '\n') { + assert(lineno < 2); + newl[lineno] = s; + lineno++; + if (lineno == 2) break; + } + } + tok->enc = NULL; + /* need to check line 1 and 2 separately since check_coding_spec + assumes a single line as input */ + if (newl[0]) { + if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) + return error_ret(tok); + if (tok->enc == NULL && !tok->read_coding_spec && newl[1]) { + if (!check_coding_spec(newl[0]+1, newl[1] - newl[0], + tok, buf_setreadl)) + return error_ret(tok); + } + } + if (tok->enc != NULL) { + assert(utf8 == NULL); + utf8 = translate_into_utf8(str, tok->enc); + if (utf8 == NULL) + return error_ret(tok); + str = PyBytes_AS_STRING(utf8); + } + assert(tok->decoding_buffer == NULL); + tok->decoding_buffer = utf8; /* CAUTION */ + return str; +} + +/* Set up tokenizer for string */ + +struct tok_state * +PyTokenizer_FromString(const char *str, int exec_input) +{ + struct tok_state *tok = tok_new(); + if (tok == NULL) + return NULL; + str = decode_str(str, exec_input, tok); + if (str == NULL) { + PyTokenizer_Free(tok); + return NULL; + } + + /* XXX: constify members. */ + tok->buf = tok->cur = tok->end = tok->inp = (char*)str; + return tok; +} + +struct tok_state * +PyTokenizer_FromUTF8(const char *str, int exec_input) +{ + struct tok_state *tok = tok_new(); + if (tok == NULL) + return NULL; + tok->input = str = translate_newlines(str, exec_input, tok); + if (str == NULL) { + PyTokenizer_Free(tok); + return NULL; + } + tok->decoding_state = STATE_RAW; + tok->read_coding_spec = 1; + tok->enc = NULL; + tok->str = str; + tok->encoding = (char *)PyMem_MALLOC(6); + if (!tok->encoding) { + PyTokenizer_Free(tok); + return NULL; + } + strcpy(tok->encoding, "utf-8"); + + /* XXX: constify members. */ + tok->buf = tok->cur = tok->end = tok->inp = (char*)str; + return tok; +} + +/* Set up tokenizer for file */ + +struct tok_state * +PyTokenizer_FromFile(FILE *fp, const char* enc, + const char *ps1, const char *ps2) +{ + struct tok_state *tok = tok_new(); + if (tok == NULL) + return NULL; + if ((tok->buf = (char *)PyMem_MALLOC(BUFSIZ)) == NULL) { + PyTokenizer_Free(tok); + return NULL; + } + tok->cur = tok->inp = tok->buf; + tok->end = tok->buf + BUFSIZ; + tok->fp = fp; + tok->prompt = ps1; + tok->nextprompt = ps2; + if (enc != NULL) { + /* Must copy encoding declaration since it + gets copied into the parse tree. */ + tok->encoding = PyMem_MALLOC(strlen(enc)+1); + if (!tok->encoding) { + PyTokenizer_Free(tok); + return NULL; + } + strcpy(tok->encoding, enc); + tok->decoding_state = STATE_NORMAL; + } + return tok; +} + + +/* Free a tok_state structure */ + +void +PyTokenizer_Free(struct tok_state *tok) +{ + if (tok->encoding != NULL) + PyMem_FREE(tok->encoding); + Py_XDECREF(tok->decoding_readline); + Py_XDECREF(tok->decoding_buffer); + Py_XDECREF(tok->filename); + if (tok->fp != NULL && tok->buf != NULL) + PyMem_FREE(tok->buf); + if (tok->input) + PyMem_FREE((char *)tok->input); + PyMem_FREE(tok); +} + +/* Get next char, updating state; error code goes into tok->done */ + +static int +tok_nextc(struct tok_state *tok) +{ + for (;;) { + if (tok->cur != tok->inp) { + return Py_CHARMASK(*tok->cur++); /* Fast path */ + } + if (tok->done != E_OK) + return EOF; + if (tok->fp == NULL) { + char *end = strchr(tok->inp, '\n'); + if (end != NULL) + end++; + else { + end = strchr(tok->inp, '\0'); + if (end == tok->inp) { + tok->done = E_EOF; + return EOF; + } + } + if (tok->start == NULL) + tok->buf = tok->cur; + tok->line_start = tok->cur; + tok->lineno++; + tok->inp = end; + return Py_CHARMASK(*tok->cur++); + } + if (tok->prompt != NULL) { + char *newtok = PyOS_Readline(stdin, stdout, tok->prompt); + if (newtok != NULL) { + char *translated = translate_newlines(newtok, 0, tok); + PyMem_FREE(newtok); + if (translated == NULL) + return EOF; + newtok = translated; + } + if (tok->encoding && newtok && *newtok) { + /* Recode to UTF-8 */ + Py_ssize_t buflen; + const char* buf; + PyObject *u = translate_into_utf8(newtok, tok->encoding); + PyMem_FREE(newtok); + if (!u) { + tok->done = E_DECODE; + return EOF; + } + buflen = PyBytes_GET_SIZE(u); + buf = PyBytes_AS_STRING(u); + newtok = PyMem_MALLOC(buflen+1); + if (newtok == NULL) { + Py_DECREF(u); + tok->done = E_NOMEM; + return EOF; + } + strcpy(newtok, buf); + Py_DECREF(u); + } + if (tok->nextprompt != NULL) + tok->prompt = tok->nextprompt; + if (newtok == NULL) + tok->done = E_INTR; + else if (*newtok == '\0') { + PyMem_FREE(newtok); + tok->done = E_EOF; + } + else if (tok->start != NULL) { + size_t start = tok->start - tok->buf; + size_t oldlen = tok->cur - tok->buf; + size_t newlen = oldlen + strlen(newtok); + Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; + char *buf = tok->buf; + buf = (char *)PyMem_REALLOC(buf, newlen+1); + tok->lineno++; + if (buf == NULL) { + PyMem_FREE(tok->buf); + tok->buf = NULL; + PyMem_FREE(newtok); + tok->done = E_NOMEM; + return EOF; + } + tok->buf = buf; + tok->cur = tok->buf + oldlen; + tok->multi_line_start = tok->buf + cur_multi_line_start; + tok->line_start = tok->cur; + strcpy(tok->buf + oldlen, newtok); + PyMem_FREE(newtok); + tok->inp = tok->buf + newlen; + tok->end = tok->inp + 1; + tok->start = tok->buf + start; + } + else { + tok->lineno++; + if (tok->buf != NULL) + PyMem_FREE(tok->buf); + tok->buf = newtok; + tok->cur = tok->buf; + tok->line_start = tok->buf; + tok->inp = strchr(tok->buf, '\0'); + tok->end = tok->inp + 1; + } + } + else { + int done = 0; + Py_ssize_t cur = 0; + char *pt; + if (tok->start == NULL) { + if (tok->buf == NULL) { + tok->buf = (char *) + PyMem_MALLOC(BUFSIZ); + if (tok->buf == NULL) { + tok->done = E_NOMEM; + return EOF; + } + tok->end = tok->buf + BUFSIZ; + } + if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf), + tok) == NULL) { + if (!tok->decoding_erred) + tok->done = E_EOF; + done = 1; + } + else { + tok->done = E_OK; + tok->inp = strchr(tok->buf, '\0'); + done = tok->inp == tok->buf || tok->inp[-1] == '\n'; + } + } + else { + cur = tok->cur - tok->buf; + if (decoding_feof(tok)) { + tok->done = E_EOF; + done = 1; + } + else + tok->done = E_OK; + } + tok->lineno++; + /* Read until '\n' or EOF */ + while (!done) { + Py_ssize_t curstart = tok->start == NULL ? -1 : + tok->start - tok->buf; + Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; + Py_ssize_t curvalid = tok->inp - tok->buf; + Py_ssize_t newsize = curvalid + BUFSIZ; + char *newbuf = tok->buf; + newbuf = (char *)PyMem_REALLOC(newbuf, + newsize); + if (newbuf == NULL) { + tok->done = E_NOMEM; + tok->cur = tok->inp; + return EOF; + } + tok->buf = newbuf; + tok->cur = tok->buf + cur; + tok->multi_line_start = tok->buf + cur_multi_line_start; + tok->line_start = tok->cur; + tok->inp = tok->buf + curvalid; + tok->end = tok->buf + newsize; + tok->start = curstart < 0 ? NULL : + tok->buf + curstart; + if (decoding_fgets(tok->inp, + (int)(tok->end - tok->inp), + tok) == NULL) { + /* Break out early on decoding + errors, as tok->buf will be NULL + */ + if (tok->decoding_erred) + return EOF; + /* Last line does not end in \n, + fake one */ + if (tok->inp[-1] != '\n') + strcpy(tok->inp, "\n"); + } + tok->inp = strchr(tok->inp, '\0'); + done = tok->inp[-1] == '\n'; + } + if (tok->buf != NULL) { + tok->cur = tok->buf + cur; + tok->line_start = tok->cur; + /* replace "\r\n" with "\n" */ + /* For Mac leave the \r, giving a syntax error */ + pt = tok->inp - 2; + if (pt >= tok->buf && *pt == '\r') { + *pt++ = '\n'; + *pt = '\0'; + tok->inp = pt; + } + } + } + if (tok->done != E_OK) { + if (tok->prompt != NULL) + PySys_WriteStderr("\n"); + tok->cur = tok->inp; + return EOF; + } + } + /*NOTREACHED*/ +} + + +/* Back-up one character */ + +static void +tok_backup(struct tok_state *tok, int c) +{ + if (c != EOF) { + if (--tok->cur < tok->buf) + Py_FatalError("tok_backup: beginning of buffer"); + if (*tok->cur != c) + *tok->cur = c; + } +} + + +static int +syntaxerror(struct tok_state *tok, const char *format, ...) +{ + PyObject *errmsg, *errtext, *args; + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + errmsg = PyUnicode_FromFormatV(format, vargs); + va_end(vargs); + if (!errmsg) { + goto error; + } + + errtext = PyUnicode_DecodeUTF8(tok->line_start, tok->cur - tok->line_start, + "replace"); + if (!errtext) { + goto error; + } + int offset = (int)PyUnicode_GET_LENGTH(errtext); + Py_ssize_t line_len = strcspn(tok->line_start, "\n"); + if (line_len != tok->cur - tok->line_start) { + Py_DECREF(errtext); + errtext = PyUnicode_DecodeUTF8(tok->line_start, line_len, + "replace"); + } + if (!errtext) { + goto error; + } + + args = Py_BuildValue("(O(OiiN))", errmsg, + tok->filename, tok->lineno, offset, errtext); + if (args) { + PyErr_SetObject(PyExc_SyntaxError, args); + Py_DECREF(args); + } + +error: + Py_XDECREF(errmsg); + tok->done = E_ERROR; + return ERRORTOKEN; +} + +static int +indenterror(struct tok_state *tok) +{ + tok->done = E_TABSPACE; + tok->cur = tok->inp; + return ERRORTOKEN; +} + +/* Verify that the identifier follows PEP 3131. + All identifier strings are guaranteed to be "ready" unicode objects. + */ +static int +verify_identifier(struct tok_state *tok) +{ + PyObject *s; + int result; + if (tok->decoding_erred) + return 0; + s = PyUnicode_DecodeUTF8(tok->start, tok->cur - tok->start, NULL); + if (s == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + PyErr_Clear(); + tok->done = E_IDENTIFIER; + } else { + tok->done = E_ERROR; + } + return 0; + } + result = PyUnicode_IsIdentifier(s); + Py_DECREF(s); + if (result == 0) + tok->done = E_IDENTIFIER; + return result; +} + +static int +tok_decimal_tail(struct tok_state *tok) +{ + int c; + + while (1) { + do { + c = tok_nextc(tok); + } while (isdigit(c)); + if (c != '_') { + break; + } + c = tok_nextc(tok); + if (!isdigit(c)) { + tok_backup(tok, c); + syntaxerror(tok, "invalid decimal literal"); + return 0; + } + } + return c; +} + +/* Get next token, after space stripping etc. */ + +static int +tok_get(struct tok_state *tok, char **p_start, char **p_end) +{ + int c; + int blankline, nonascii; + + *p_start = *p_end = NULL; + nextline: + tok->start = NULL; + blankline = 0; + + /* Get indentation level */ + if (tok->atbol) { + int col = 0; + int altcol = 0; + tok->atbol = 0; + for (;;) { + c = tok_nextc(tok); + if (c == ' ') { + col++, altcol++; + } + else if (c == '\t') { + col = (col / tok->tabsize + 1) * tok->tabsize; + altcol = (altcol / ALTTABSIZE + 1) * ALTTABSIZE; + } + else if (c == '\014') {/* Control-L (formfeed) */ + col = altcol = 0; /* For Emacs users */ + } + else { + break; + } + } + tok_backup(tok, c); + if (c == '#' || c == '\n') { + /* Lines with only whitespace and/or comments + shouldn't affect the indentation and are + not passed to the parser as NEWLINE tokens, + except *totally* empty lines in interactive + mode, which signal the end of a command group. */ + if (col == 0 && c == '\n' && tok->prompt != NULL) { + blankline = 0; /* Let it through */ + } + else if (tok->prompt != NULL && tok->lineno == 1) { + /* In interactive mode, if the first line contains + only spaces and/or a comment, let it through. */ + blankline = 0; + col = altcol = 0; + } + else { + blankline = 1; /* Ignore completely */ + } + /* We can't jump back right here since we still + may need to skip to the end of a comment */ + } + if (!blankline && tok->level == 0) { + if (col == tok->indstack[tok->indent]) { + /* No change */ + if (altcol != tok->altindstack[tok->indent]) { + return indenterror(tok); + } + } + else if (col > tok->indstack[tok->indent]) { + /* Indent -- always one */ + if (tok->indent+1 >= MAXINDENT) { + tok->done = E_TOODEEP; + tok->cur = tok->inp; + return ERRORTOKEN; + } + if (altcol <= tok->altindstack[tok->indent]) { + return indenterror(tok); + } + tok->pendin++; + tok->indstack[++tok->indent] = col; + tok->altindstack[tok->indent] = altcol; + } + else /* col < tok->indstack[tok->indent] */ { + /* Dedent -- any number, must be consistent */ + while (tok->indent > 0 && + col < tok->indstack[tok->indent]) { + tok->pendin--; + tok->indent--; + } + if (col != tok->indstack[tok->indent]) { + tok->done = E_DEDENT; + tok->cur = tok->inp; + return ERRORTOKEN; + } + if (altcol != tok->altindstack[tok->indent]) { + return indenterror(tok); + } + } + } + } + + tok->start = tok->cur; + + /* Return pending indents/dedents */ + if (tok->pendin != 0) { + if (tok->pendin < 0) { + tok->pendin++; + return DEDENT; + } + else { + tok->pendin--; + return INDENT; + } + } + + /* Peek ahead at the next character */ + c = tok_nextc(tok); + tok_backup(tok, c); + /* Check if we are closing an async function */ + if (tok->async_def + && !blankline + /* Due to some implementation artifacts of type comments, + * a TYPE_COMMENT at the start of a function won't set an + * indentation level and it will produce a NEWLINE after it. + * To avoid spuriously ending an async function due to this, + * wait until we have some non-newline char in front of us. */ + && c != '\n' + && tok->level == 0 + /* There was a NEWLINE after ASYNC DEF, + so we're past the signature. */ + && tok->async_def_nl + /* Current indentation level is less than where + the async function was defined */ + && tok->async_def_indent >= tok->indent) + { + tok->async_def = 0; + tok->async_def_indent = 0; + tok->async_def_nl = 0; + } + + again: + tok->start = NULL; + /* Skip spaces */ + do { + c = tok_nextc(tok); + } while (c == ' ' || c == '\t' || c == '\014'); + + /* Set start of current token */ + tok->start = tok->cur - 1; + + /* Skip comment, unless it's a type comment */ + if (c == '#') { + const char *prefix, *p, *type_start; + + while (c != EOF && c != '\n') { + c = tok_nextc(tok); + } + + if (tok->type_comments) { + p = tok->start; + prefix = type_comment_prefix; + while (*prefix && p < tok->cur) { + if (*prefix == ' ') { + while (*p == ' ' || *p == '\t') { + p++; + } + } else if (*prefix == *p) { + p++; + } else { + break; + } + + prefix++; + } + + /* This is a type comment if we matched all of type_comment_prefix. */ + if (!*prefix) { + int is_type_ignore = 1; + const char *ignore_end = p + 6; + tok_backup(tok, c); /* don't eat the newline or EOF */ + + type_start = p; + + /* A TYPE_IGNORE is "type: ignore" followed by the end of the token + * or anything ASCII and non-alphanumeric. */ + is_type_ignore = ( + tok->cur >= ignore_end && memcmp(p, "ignore", 6) == 0 + && !(tok->cur > ignore_end + && ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0])))); + + if (is_type_ignore) { + *p_start = (char *) ignore_end; + *p_end = tok->cur; + + /* If this type ignore is the only thing on the line, consume the newline also. */ + if (blankline) { + tok_nextc(tok); + tok->atbol = 1; + } + return TYPE_IGNORE; + } else { + *p_start = (char *) type_start; /* after type_comment_prefix */ + *p_end = tok->cur; + return TYPE_COMMENT; + } + } + } + } + + /* Check for EOF and errors now */ + if (c == EOF) { + return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN; + } + + /* Identifier (most frequent token!) */ + nonascii = 0; + if (is_potential_identifier_start(c)) { + /* Process the various legal combinations of b"", r"", u"", and f"". */ + int saw_b = 0, saw_r = 0, saw_u = 0, saw_f = 0; + while (1) { + if (!(saw_b || saw_u || saw_f) && (c == 'b' || c == 'B')) + saw_b = 1; + /* Since this is a backwards compatibility support literal we don't + want to support it in arbitrary order like byte literals. */ + else if (!(saw_b || saw_u || saw_r || saw_f) + && (c == 'u'|| c == 'U')) { + saw_u = 1; + } + /* ur"" and ru"" are not supported */ + else if (!(saw_r || saw_u) && (c == 'r' || c == 'R')) { + saw_r = 1; + } + else if (!(saw_f || saw_b || saw_u) && (c == 'f' || c == 'F')) { + saw_f = 1; + } + else { + break; + } + c = tok_nextc(tok); + if (c == '"' || c == '\'') { + goto letter_quote; + } + } + while (is_potential_identifier_char(c)) { + if (c >= 128) { + nonascii = 1; + } + c = tok_nextc(tok); + } + tok_backup(tok, c); + if (nonascii && !verify_identifier(tok)) { + return ERRORTOKEN; + } + *p_start = tok->start; + *p_end = tok->cur; + + /* async/await parsing block. */ + if (tok->cur - tok->start == 5 && tok->start[0] == 'a') { + /* May be an 'async' or 'await' token. For Python 3.7 or + later we recognize them unconditionally. For Python + 3.5 or 3.6 we recognize 'async' in front of 'def', and + either one inside of 'async def'. (Technically we + shouldn't recognize these at all for 3.4 or earlier, + but there's no *valid* Python 3.4 code that would be + rejected, and async functions will be rejected in a + later phase.) */ + if (!tok->async_hacks || tok->async_def) { + /* Always recognize the keywords. */ + if (memcmp(tok->start, "async", 5) == 0) { + return ASYNC; + } + if (memcmp(tok->start, "await", 5) == 0) { + return AWAIT; + } + } + else if (memcmp(tok->start, "async", 5) == 0) { + /* The current token is 'async'. + Look ahead one token to see if that is 'def'. */ + + struct tok_state ahead_tok; + char *ahead_tok_start = NULL, *ahead_tok_end = NULL; + int ahead_tok_kind; + + memcpy(&ahead_tok, tok, sizeof(ahead_tok)); + ahead_tok_kind = tok_get(&ahead_tok, &ahead_tok_start, + &ahead_tok_end); + + if (ahead_tok_kind == NAME + && ahead_tok.cur - ahead_tok.start == 3 + && memcmp(ahead_tok.start, "def", 3) == 0) + { + /* The next token is going to be 'def', so instead of + returning a plain NAME token, return ASYNC. */ + tok->async_def_indent = tok->indent; + tok->async_def = 1; + return ASYNC; + } + } + } + + return NAME; + } + + /* Newline */ + if (c == '\n') { + tok->atbol = 1; + if (blankline || tok->level > 0) { + goto nextline; + } + *p_start = tok->start; + *p_end = tok->cur - 1; /* Leave '\n' out of the string */ + tok->cont_line = 0; + if (tok->async_def) { + /* We're somewhere inside an 'async def' function, and + we've encountered a NEWLINE after its signature. */ + tok->async_def_nl = 1; + } + return NEWLINE; + } + + /* Period or number starting with period? */ + if (c == '.') { + c = tok_nextc(tok); + if (isdigit(c)) { + goto fraction; + } else if (c == '.') { + c = tok_nextc(tok); + if (c == '.') { + *p_start = tok->start; + *p_end = tok->cur; + return ELLIPSIS; + } + else { + tok_backup(tok, c); + } + tok_backup(tok, '.'); + } + else { + tok_backup(tok, c); + } + *p_start = tok->start; + *p_end = tok->cur; + return DOT; + } + + /* Number */ + if (isdigit(c)) { + if (c == '0') { + /* Hex, octal or binary -- maybe. */ + c = tok_nextc(tok); + if (c == 'x' || c == 'X') { + /* Hex */ + c = tok_nextc(tok); + do { + if (c == '_') { + c = tok_nextc(tok); + } + if (!isxdigit(c)) { + tok_backup(tok, c); + return syntaxerror(tok, "invalid hexadecimal literal"); + } + do { + c = tok_nextc(tok); + } while (isxdigit(c)); + } while (c == '_'); + } + else if (c == 'o' || c == 'O') { + /* Octal */ + c = tok_nextc(tok); + do { + if (c == '_') { + c = tok_nextc(tok); + } + if (c < '0' || c >= '8') { + tok_backup(tok, c); + if (isdigit(c)) { + return syntaxerror(tok, + "invalid digit '%c' in octal literal", c); + } + else { + return syntaxerror(tok, "invalid octal literal"); + } + } + do { + c = tok_nextc(tok); + } while ('0' <= c && c < '8'); + } while (c == '_'); + if (isdigit(c)) { + return syntaxerror(tok, + "invalid digit '%c' in octal literal", c); + } + } + else if (c == 'b' || c == 'B') { + /* Binary */ + c = tok_nextc(tok); + do { + if (c == '_') { + c = tok_nextc(tok); + } + if (c != '0' && c != '1') { + tok_backup(tok, c); + if (isdigit(c)) { + return syntaxerror(tok, + "invalid digit '%c' in binary literal", c); + } + else { + return syntaxerror(tok, "invalid binary literal"); + } + } + do { + c = tok_nextc(tok); + } while (c == '0' || c == '1'); + } while (c == '_'); + if (isdigit(c)) { + return syntaxerror(tok, + "invalid digit '%c' in binary literal", c); + } + } + else { + int nonzero = 0; + /* maybe old-style octal; c is first char of it */ + /* in any case, allow '0' as a literal */ + while (1) { + if (c == '_') { + c = tok_nextc(tok); + if (!isdigit(c)) { + tok_backup(tok, c); + return syntaxerror(tok, "invalid decimal literal"); + } + } + if (c != '0') { + break; + } + c = tok_nextc(tok); + } + if (isdigit(c)) { + nonzero = 1; + c = tok_decimal_tail(tok); + if (c == 0) { + return ERRORTOKEN; + } + } + if (c == '.') { + c = tok_nextc(tok); + goto fraction; + } + else if (c == 'e' || c == 'E') { + goto exponent; + } + else if (c == 'j' || c == 'J') { + goto imaginary; + } + else if (nonzero) { + /* Old-style octal: now disallowed. */ + tok_backup(tok, c); + return syntaxerror(tok, + "leading zeros in decimal integer " + "literals are not permitted; " + "use an 0o prefix for octal integers"); + } + } + } + else { + /* Decimal */ + c = tok_decimal_tail(tok); + if (c == 0) { + return ERRORTOKEN; + } + { + /* Accept floating point numbers. */ + if (c == '.') { + c = tok_nextc(tok); + fraction: + /* Fraction */ + if (isdigit(c)) { + c = tok_decimal_tail(tok); + if (c == 0) { + return ERRORTOKEN; + } + } + } + if (c == 'e' || c == 'E') { + int e; + exponent: + e = c; + /* Exponent part */ + c = tok_nextc(tok); + if (c == '+' || c == '-') { + c = tok_nextc(tok); + if (!isdigit(c)) { + tok_backup(tok, c); + return syntaxerror(tok, "invalid decimal literal"); + } + } else if (!isdigit(c)) { + tok_backup(tok, c); + tok_backup(tok, e); + *p_start = tok->start; + *p_end = tok->cur; + return NUMBER; + } + c = tok_decimal_tail(tok); + if (c == 0) { + return ERRORTOKEN; + } + } + if (c == 'j' || c == 'J') { + /* Imaginary part */ + imaginary: + c = tok_nextc(tok); + } + } + } + tok_backup(tok, c); + *p_start = tok->start; + *p_end = tok->cur; + return NUMBER; + } + + letter_quote: + /* String */ + if (c == '\'' || c == '"') { + int quote = c; + int quote_size = 1; /* 1 or 3 */ + int end_quote_size = 0; + + /* Nodes of type STRING, especially multi line strings + must be handled differently in order to get both + the starting line number and the column offset right. + (cf. issue 16806) */ + tok->first_lineno = tok->lineno; + tok->multi_line_start = tok->line_start; + + /* Find the quote size and start of string */ + c = tok_nextc(tok); + if (c == quote) { + c = tok_nextc(tok); + if (c == quote) { + quote_size = 3; + } + else { + end_quote_size = 1; /* empty string found */ + } + } + if (c != quote) { + tok_backup(tok, c); + } + + /* Get rest of string */ + while (end_quote_size != quote_size) { + c = tok_nextc(tok); + if (c == EOF) { + if (quote_size == 3) { + tok->done = E_EOFS; + } + else { + tok->done = E_EOLS; + } + tok->cur = tok->inp; + return ERRORTOKEN; + } + if (quote_size == 1 && c == '\n') { + tok->done = E_EOLS; + tok->cur = tok->inp; + return ERRORTOKEN; + } + if (c == quote) { + end_quote_size += 1; + } + else { + end_quote_size = 0; + if (c == '\\') { + tok_nextc(tok); /* skip escaped char */ + } + } + } + + *p_start = tok->start; + *p_end = tok->cur; + return STRING; + } + + /* Line continuation */ + if (c == '\\') { + c = tok_nextc(tok); + if (c != '\n') { + tok->done = E_LINECONT; + tok->cur = tok->inp; + return ERRORTOKEN; + } + c = tok_nextc(tok); + if (c == EOF) { + tok->done = E_EOF; + tok->cur = tok->inp; + return ERRORTOKEN; + } else { + tok_backup(tok, c); + } + tok->cont_line = 1; + goto again; /* Read next line */ + } + + /* Check for two-character token */ + { + int c2 = tok_nextc(tok); + int token = PyToken_TwoChars(c, c2); + if (token != OP) { + int c3 = tok_nextc(tok); + int token3 = PyToken_ThreeChars(c, c2, c3); + if (token3 != OP) { + token = token3; + } + else { + tok_backup(tok, c3); + } + *p_start = tok->start; + *p_end = tok->cur; + return token; + } + tok_backup(tok, c2); + } + + /* Keep track of parentheses nesting level */ + switch (c) { + case '(': + case '[': + case '{': + if (tok->level >= MAXLEVEL) { + return syntaxerror(tok, "too many nested parentheses"); + } + tok->parenstack[tok->level] = c; + tok->parenlinenostack[tok->level] = tok->lineno; + tok->level++; + break; + case ')': + case ']': + case '}': + if (!tok->level) { + return syntaxerror(tok, "unmatched '%c'", c); + } + tok->level--; + int opening = tok->parenstack[tok->level]; + if (!((opening == '(' && c == ')') || + (opening == '[' && c == ']') || + (opening == '{' && c == '}'))) + { + if (tok->parenlinenostack[tok->level] != tok->lineno) { + return syntaxerror(tok, + "closing parenthesis '%c' does not match " + "opening parenthesis '%c' on line %d", + c, opening, tok->parenlinenostack[tok->level]); + } + else { + return syntaxerror(tok, + "closing parenthesis '%c' does not match " + "opening parenthesis '%c'", + c, opening); + } + } + break; + } + + /* Punctuation character */ + *p_start = tok->start; + *p_end = tok->cur; + return PyToken_OneChar(c); +} + +int +PyTokenizer_Get(struct tok_state *tok, char **p_start, char **p_end) +{ + int result = tok_get(tok, p_start, p_end); + if (tok->decoding_erred) { + result = ERRORTOKEN; + tok->done = E_DECODE; + } + return result; +} + +/* Get the encoding of a Python file. Check for the coding cookie and check if + the file starts with a BOM. + + PyTokenizer_FindEncodingFilename() returns NULL when it can't find the + encoding in the first or second line of the file (in which case the encoding + should be assumed to be UTF-8). + + The char* returned is malloc'ed via PyMem_MALLOC() and thus must be freed + by the caller. */ + +char * +PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) +{ + struct tok_state *tok; + FILE *fp; + char *p_start =NULL , *p_end =NULL , *encoding = NULL; + + fd = _Py_dup(fd); + if (fd < 0) { + return NULL; + } + + fp = fdopen(fd, "r"); + if (fp == NULL) { + return NULL; + } + tok = PyTokenizer_FromFile(fp, NULL, NULL, NULL); + if (tok == NULL) { + fclose(fp); + return NULL; + } + if (filename != NULL) { + Py_INCREF(filename); + tok->filename = filename; + } + else { + tok->filename = PyUnicode_FromString(""); + if (tok->filename == NULL) { + fclose(fp); + PyTokenizer_Free(tok); + return encoding; + } + } + while (tok->lineno < 2 && tok->done == E_OK) { + PyTokenizer_Get(tok, &p_start, &p_end); + } + fclose(fp); + if (tok->encoding) { + encoding = (char *)PyMem_MALLOC(strlen(tok->encoding) + 1); + if (encoding) + strcpy(encoding, tok->encoding); + } + PyTokenizer_Free(tok); + return encoding; +} + +char * +PyTokenizer_FindEncoding(int fd) +{ + return PyTokenizer_FindEncodingFilename(fd, NULL); +} + +#ifdef Py_DEBUG + +void +tok_dump(int type, char *start, char *end) +{ + printf("%s", _PyParser_TokenNames[type]); + if (type == NAME || type == NUMBER || type == STRING || type == OP) + printf("(%.*s)", (int)(end - start), start); +} + +#endif diff --git a/python/Parser/tokenizer.h b/python/Parser/tokenizer.h new file mode 100755 index 0000000..92669bf --- /dev/null +++ b/python/Parser/tokenizer.h @@ -0,0 +1,88 @@ +#ifndef Py_TOKENIZER_H +#define Py_TOKENIZER_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "object.h" + +/* Tokenizer interface */ + +#include "token.h" /* For token types */ + +#define MAXINDENT 100 /* Max indentation level */ +#define MAXLEVEL 200 /* Max parentheses level */ + +enum decoding_state { + STATE_INIT, + STATE_RAW, + STATE_NORMAL /* have a codec associated with input */ +}; + +/* Tokenizer state */ +struct tok_state { + /* Input state; buf <= cur <= inp <= end */ + /* NB an entire line is held in the buffer */ + char *buf; /* Input buffer, or NULL; malloc'ed if fp != NULL */ + char *cur; /* Next character in buffer */ + char *inp; /* End of data in buffer */ + char *end; /* End of input buffer if buf != NULL */ + char *start; /* Start of current token if not NULL */ + int done; /* E_OK normally, E_EOF at EOF, otherwise error code */ + /* NB If done != E_OK, cur must be == inp!!! */ + FILE *fp; /* Rest of input; NULL if tokenizing a string */ + int tabsize; /* Tab spacing */ + int indent; /* Current indentation index */ + int indstack[MAXINDENT]; /* Stack of indents */ + int atbol; /* Nonzero if at begin of new line */ + int pendin; /* Pending indents (if > 0) or dedents (if < 0) */ + const char *prompt, *nextprompt; /* For interactive prompting */ + int lineno; /* Current line number */ + int first_lineno; /* First line of a single line or multi line string + expression (cf. issue 16806) */ + int level; /* () [] {} Parentheses nesting level */ + /* Used to allow free continuations inside them */ + char parenstack[MAXLEVEL]; + int parenlinenostack[MAXLEVEL]; + PyObject *filename; + /* Stuff for checking on different tab sizes */ + int altindstack[MAXINDENT]; /* Stack of alternate indents */ + /* Stuff for PEP 0263 */ + enum decoding_state decoding_state; + int decoding_erred; /* whether erred in decoding */ + int read_coding_spec; /* whether 'coding:...' has been read */ + char *encoding; /* Source encoding. */ + int cont_line; /* whether we are in a continuation line. */ + const char* line_start; /* pointer to start of current line */ + const char* multi_line_start; /* pointer to start of first line of + a single line or multi line string + expression (cf. issue 16806) */ + PyObject *decoding_readline; /* open(...).readline */ + PyObject *decoding_buffer; + const char* enc; /* Encoding for the current str. */ + const char* str; + const char* input; /* Tokenizer's newline translated copy of the string. */ + + int type_comments; /* Whether to look for type comments */ + + /* async/await related fields (still needed depending on feature_version) */ + int async_hacks; /* =1 if async/await aren't always keywords */ + int async_def; /* =1 if tokens are inside an 'async def' body. */ + int async_def_indent; /* Indentation level of the outermost 'async def'. */ + int async_def_nl; /* =1 if the outermost 'async def' had at least one + NEWLINE token after it. */ +}; + +extern struct tok_state *PyTokenizer_FromString(const char *, int); +extern struct tok_state *PyTokenizer_FromUTF8(const char *, int); +extern struct tok_state *PyTokenizer_FromFile(FILE *, const char*, + const char *, const char *); +extern void PyTokenizer_Free(struct tok_state *); +extern int PyTokenizer_Get(struct tok_state *, char **, char **); + +#define tok_dump _Py_tok_dump + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TOKENIZER_H */ diff --git a/python/Programs/README b/python/Programs/README new file mode 100755 index 0000000..c24578b --- /dev/null +++ b/python/Programs/README @@ -0,0 +1 @@ +Source files for binary executables (as opposed to shared modules) diff --git a/python/Programs/_freeze_importlib.c b/python/Programs/_freeze_importlib.c new file mode 100755 index 0000000..2e4ccbb --- /dev/null +++ b/python/Programs/_freeze_importlib.c @@ -0,0 +1,167 @@ +/* This is built as a stand-alone executable by the Makefile, and helps turn + Lib/importlib/_bootstrap.py into a frozen module in Python/importlib.h +*/ + +#include +#include + +#include +#include +#include +#ifndef MS_WINDOWS +#include +#endif + +/* To avoid a circular dependency on frozen.o, we create our own structure + of frozen modules instead, left deliberately blank so as to avoid + unintentional import of a stale version of _frozen_importlib. */ + +static const struct _frozen _PyImport_FrozenModules[] = { + {0, 0, 0} /* sentinel */ +}; + +#ifndef MS_WINDOWS +/* On Windows, this links with the regular pythonXY.dll, so this variable comes + from frozen.obj. In the Makefile, frozen.o is not linked into this executable, + so we define the variable here. */ +const struct _frozen *PyImport_FrozenModules; +#endif + +static const char header[] = + "/* Auto-generated by Programs/_freeze_importlib.c */"; + +int +main(int argc, char *argv[]) +{ + const char *name, *inpath, *outpath; + char buf[100]; + FILE *infile = NULL, *outfile = NULL; + struct _Py_stat_struct stat; + size_t text_size, data_size, i, n; + char *text = NULL; + unsigned char *data; + PyObject *code = NULL, *marshalled = NULL; + + PyImport_FrozenModules = _PyImport_FrozenModules; + + if (argc != 4) { + fprintf(stderr, "need to specify the name, input and output paths\n"); + return 2; + } + name = argv[1]; + inpath = argv[2]; + outpath = argv[3]; + infile = fopen(inpath, "rb"); + if (infile == NULL) { + fprintf(stderr, "cannot open '%s' for reading\n", inpath); + goto error; + } + if (_Py_fstat_noraise(fileno(infile), &stat)) { + fprintf(stderr, "cannot fstat '%s'\n", inpath); + goto error; + } + text_size = (size_t)stat.st_size; + text = (char *) malloc(text_size + 1); + if (text == NULL) { + fprintf(stderr, "could not allocate %ld bytes\n", (long) text_size); + goto error; + } + n = fread(text, 1, text_size, infile); + fclose(infile); + infile = NULL; + if (n < text_size) { + fprintf(stderr, "read too short: got %ld instead of %ld bytes\n", + (long) n, (long) text_size); + goto error; + } + text[text_size] = '\0'; + + PyConfig config; + PyConfig_InitIsolatedConfig(&config); + + config.site_import = 0; + + PyStatus status; + status = PyConfig_SetString(&config, &config.program_name, + L"./_freeze_importlib"); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); + } + + /* Don't install importlib, since it could execute outdated bytecode. */ + config._install_importlib = 0; + config._init_main = 0; + + status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + sprintf(buf, "", name); + code = Py_CompileStringExFlags(text, buf, Py_file_input, NULL, 0); + if (code == NULL) + goto error; + free(text); + text = NULL; + + marshalled = PyMarshal_WriteObjectToString(code, Py_MARSHAL_VERSION); + Py_CLEAR(code); + if (marshalled == NULL) + goto error; + + assert(PyBytes_CheckExact(marshalled)); + data = (unsigned char *) PyBytes_AS_STRING(marshalled); + data_size = PyBytes_GET_SIZE(marshalled); + + /* Open the file in text mode. The hg checkout should be using the eol extension, + which in turn should cause the EOL style match the C library's text mode */ + outfile = fopen(outpath, "w"); + if (outfile == NULL) { + fprintf(stderr, "cannot open '%s' for writing\n", outpath); + goto error; + } + fprintf(outfile, "%s\n", header); + for (i = n = 0; name[i] != '\0'; i++) { + if (name[i] != '.') { + buf[n++] = name[i]; + } + } + buf[n] = '\0'; + fprintf(outfile, "const unsigned char _Py_M__%s[] = {\n", buf); + for (n = 0; n < data_size; n += 16) { + size_t i, end = Py_MIN(n + 16, data_size); + fprintf(outfile, " "); + for (i = n; i < end; i++) { + fprintf(outfile, "%u,", (unsigned int) data[i]); + } + fprintf(outfile, "\n"); + } + fprintf(outfile, "};\n"); + + Py_CLEAR(marshalled); + + Py_Finalize(); + if (outfile) { + if (ferror(outfile)) { + fprintf(stderr, "error when writing to '%s'\n", outpath); + goto error; + } + fclose(outfile); + } + return 0; + +error: + PyErr_Print(); + Py_Finalize(); + if (infile) + fclose(infile); + if (outfile) + fclose(outfile); + if (text) + free(text); + if (marshalled) + Py_DECREF(marshalled); + return 1; +} diff --git a/python/Programs/_testembed b/python/Programs/_testembed new file mode 100755 index 0000000000000000000000000000000000000000..57b87fc9d8f57d9cbaf1faed83b1d2e6976c0544 GIT binary patch literal 18220556 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ℜ{tOBsKNb$0#yTRHZA`I!(JkRMY+Z|g2c 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%0AyUwBN?F<% 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%0Ax_aqpyIz>n{Ic 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

4tif)5+z5py92gZ2#cgJ4SWrKcPQc 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

    E*jOst<2McQ^@OwQzjW1ulqL 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%0D^5R}_ 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

    BrL61X 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%0AL&=I9)2FZ>|s8i&fOPZ#ivVk><9F9H2& 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℞i|gQej( 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

    Dsvy%+=j}5l=egyeV#8%zhiOn5;jXG5cfA5jb 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

    7Gp=dEuX%^EJCx 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 WkpF8oKeD?17SUqm{-q+_QI{M{cXk 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 V!n?W(VbpcuxZ?E)2ob=(HU+##v4tqy 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 z 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

    -cO;{M_OURz}*xeTiVJL1b@;PG_(V3nIl3 zZ{T6?CnH3h3~@ii ze2`L@XeFH1qbZ1>`78*1&3ys?uZJ-iL>EJpjbUd9#I<8nLP~sZqGCKToqu_h7YnX_Sh8eW~-05`zcY0mmwe$jQ-{qdlwd1_n8FTw%8J?(rdOH8ftlpc@ zITr*wk;x6%nIytzfJpmyy*T`_W)sPAf#3Nz6XAJl1U2uVvKv>Ezp4 z!Tt#KGr=2akhYnie%ld&e?dA~MmAahG!db5fb~z;;+QEy{nOnz76R*_2yH`t zfa5*jPG65C9lYQXrp6ziE*vN2DhAsS`W6I}@y&f)iPqSnO|>f!Rk?6SYcHfgEyCxf zkjtW2#YWkVgqjA+nyMo(!z)qNT$@h5sJOH{n>Z6Ta2v0K*(qWnfnW8O{&i_y@Y1i+tu$^tcc`r~AB6f+;F{h; zJE-Zs4*C-Dtm!?}RtRI`8RNloP48jWq@E9N0&q=l592L{UI<*%d${r5hJFLMruR61 znV)TX`}&h{57h_h*J2_kdH;*e{fh6x%E$q5evi3OTk_*Y&2-1jWZ25MywhAtDZO9gZu((d!AAevvMdFyxl4Ua$o*WgMJ%G-kI-yZ7X4 zGmS;ZaSSTl>(bE*>ih{KMnK!mt0$a(I!;@;>kTv6K>oeqrOd^ovO#0sGmWr59qn2i zRg>GfcPs*Nh|cYIp4f^WplcsZicVlY6zx`_MZn%;&R_&tP|V`~aTn4sM~`ss!|LPi zWo~c$T+RkW_bQI+-VLX7uZlXIdmUA)v#D)zna-9@&;BJ*FWS!O8T`)<6t($Q5~8}F zqqDBTP0Y6=H{RewI^jFX`D&EexqfjJhV7Jh)*vY{sjG@b=jj-mnB1%lDd~JPrX?nK zu%w(fYLb_@z#jNbWEP;B?i?~ zi9Aj>%q9lgl4b9Slh5-KCzv{K@Yqrm^mWsAEft?|4&+`k$Lo1}f;!nGQXJLiPj!wG z!d|BEdiL&%S0P>+@0wR()~gj&GqS-ij_NwM#(HW{`zwnZ>#;#}Q65{MH~oEOsn>G| zxfxkUpd$!mUhA@6y}IMI3a?YMUaNe|Bk%0DkLN^QSHCA3qB>O8`Dt=6WORPAzqu7x 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 +6>|}c~N8FlBM1=8hvXiAu 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

    LXV11K~Wg(T~MlNILb#x)|u7S)?=&>%kQcnmH- z%r-m&;X^QQQ{W@H+#3A;1*jWKde8=~1VBA3e_z11lpTxQ(I6?i49p@5EPD%>8$qqp zQSJ|8*PXUhy9H3lc`Jaza3MzYmabv{T_0YH$B*vZs^EjxS#>#1=^+A;RgTqC`kv18I9)=Ma zESzhIAW^9mO+?N-zSmH^>sidmR zo0|?EKYh}K1@qg_oi<^{%t?5siSrZ*?Ivgy&Cu&4;{}*#iJJgYINx76r~<#*2&#J7 z-y?#!tXyX38mV-9dgbLYx<)FENvdqS7FR`3)mQ$?E;xHgS!wB7=TY2(4H}H2ehJR7 z*eO>i_+bEN`i^FJ(Ek8liYUmT>7WoXr8N%^UXS5|9~ugN2xY<#4Fx~M4^lE#tph(a zUGPIg!4FLr{LrujerUSjhlYY5nlAXEc?SFtUVLQ3r|03*|H2RdTi}O<=<5FrerW!m z!4El`xVlfoGWTD>52@P*x(D%J;D_e_X!xP&f*+bL_@U{79~ugNX#A(}L-yPMJ@_H5 z|1bQI4{#m$;k&qB`*Zl=N62Y_AASy@0e<)mg#Z8Ghd;pDe>?oJJMQNi;D^^hXn-Gn z2H}4!{E*ZCKY|}#5bK5?M&ap01b%4Vd=ajce;s~k##qo-@I&+e0DfrxCHSHF*Wrie ze+54@|10>R`Iq2_=3j>&ntvUBX#OSmq4}5Khvr|0ADRVO7`^`herWz@@I&)2!4FLr z{LuXC@I%uDKQvwNL-W6aADTDZh4%a<_@U{7ADS-sq3MDjnlAXE>4G1ce;s~k{&&C+ zClq0u>~EGh1$UzIzR=%1le}hs-WRaI7V>lwNcu2@EP1|wU*+)-3TU#Zzooze8&Hg? zSRMWwP>igm0mVq60mVq+Pf?7fgJN7t*Bt<32+BTBR~+U2(l9XU{gQA~&fYEdS zjJq%i1i;t^dzk+R0F0&sV7w6%PXLS)>DONbFq#g4u_MZ$@NG7~Kl!TwM$-W>&ShZ& z7++^$2f&zzZfXE9j)36NOb5WoFIjvZ)&#gBy!Lt6mAJ!_BaJiw7`bKpQvhQU-_QJ~ z07haTEdm$=$w`Ua?J3k^vh#+9Pu`LP@>0fQ|B5f)l2aT!HXoEHr%Fz&f-t5@nMAnQ z19lV?G7yuO@8=C=`Z{Is^hQf*ghHlt zw%a8E6$dC}N=dS?ghHlt_w`3nfkLKK`Pcw~LZViV1x}cD$E+}NG3ksQ*-IPNtP{_0#;pMx>A^;v7C}dhm5&??>g-kDW)G-d} zMT#dBvdJ8WM|zXF%1m$c-vTk?nTCG?g=`8aB-0cWGUF`kehBiCFvAUn%s40JXJj}~ z$jn$}up9m35Co`Ry?7QSpmfp3fa=JPbg$d z)eZp*W~V6~f(5hFg%2d=*!ENKPx>P#+5tAcfZrL-iBDigtQO0s->){d!5oS0LQaBt z1CrtiHq0$hb_q7jbq0%I!(3;u2sX@Z=lF+-+bTiv1RJ(0S3JRnttu4%10EH(s#H9| zhOGuDo?ydP0~JrOVXHxkC)lu6jp7M5Y&Asjd;;HUsNxAWZ0*!buwm;&l}@l>Yroq+pCUtz=p)L z3D~e$feizJ;#7M8`cdXwahmg@J{hhRr>m{JeKkIcElyA4%!{?BbvGe2r;wKro z(VC1IDX_&*Xa6tY)onEuwZrEa|Z_;9TpkRxkej+H?V#p0!47p*8AvbI>aw1O>$MyC1D z9tB$rxnYYTH*7KFhAoENu*HxYwit557DH~>V#p0!47p*8AvbI>%>MA%|yXE`Hmv9oj4AZ)RV3$|F|th$6Pmc}VNge`V; z!4|_V*kafPTMWBki(waRG3rcEJ|IF4$t&1zQZeV2fcFY%%PDErwmN z#jp#u7rcEJ|IF4$t&1zQZe zV2fcFY%%PDErwmN#jp#u7R@p*kX@nEtwu4lMlYR@Fs8UlhaM!j|bBAID38;dgM!N z&)<)AAjCf%O1{@4n|Wx#PFKdv%n#CV$y7*37=@-_eh^XQqwDtw9H870}rn` z6G>9Rx3D8U(p2*t1D~DAqN@#^8D8@MDiFPNT%<&AfabBlXQwX(mTZloGXrSJh+aiR zZw7uiiF)U;-b)Rg8Ti>3>NUqCnHtgaXxR^629+y}K&_}`(zQ&~enmvZ)Uti-myJf? z0#P}*FQn!4#^qYS!2tAf;?p55H(h_puzy2#vW&vZhP@I)q$QvAAk+>T{;d$KWNugW zSCkZ+%q^<^s*)00Ng&?WloZgKyiUgt8RmVkDP6$t=A;WcYn~YJ*|pQ4@sXi3!)qQs z?sQd;h+b>JPpPNj=SzS;(wX5kcSQ7NMD$u|o^z>}$F5H?b!K?YHPmBQZH(xlA2!md zG&69KsH|f@3}rvGG|>2DAq_uvTji~Sl04;GQhQNeee-E|}ZRSrp zpIJ?~arqJuqxV610!^*(CzJI&hJ;;AEchIWy*$yJ z9KRspD<*EbToRL*SUVhn=s@|ObB^}%G+|;r64o*C2DY`ACyR;NS@>C9CU)Xf?d2(8 zVk;!(fb!Q;v$sdS6)HnQ38>(1R&=pP-#W{u72H7KPLIBGwofaJF2(~9be^uQU4@=l z;fZ|=V8fyik{6@oG*D3ePN8P}${&?BdAvnfXo@-`c_|d;gNk}Ucnr)g3N;Y^9n4Rlb|>KG^pUt}lppj% zoivw=MEq`D9n4+t@h*>;YjF<37l6cEe=vP0(A<15b3pC1IgREPqvNCr6UAH}&E4+t z-b!<9!bTL>08(|bzYMK{N_Tm@pGWGv2MTwBq|Sc>^9BXh$sdCG8A9<QqTm zr^@9>xR8l*sw8>jRN0S&rlI zjG>L?V3v5i8{0S|UI^t}kQU<1-UlUJj4 zyn`VsW)o$^*Mi}Q&s4gR33UR=Y92+H#JMU(>$Ghhnt8}n*#4s^*BN7W$js+T*hSX0 zH`Hp~f6ZmH&Z4XX(j@&dIE`hy|+*e@;0-GgZvNJ zc@vbk1K+|zyDMjhc^*C&Kw{eo_~~!`PE+1QO+w-bP&({~=5vNS3M@=t_JcOJF zKwUY8J5U?WPXeQnE#3NekN7tLcS6LnZ|Ic%m+`_xI=Zn#;_bIWu$4nX^7m&O_QafR(oW$wU=kr5yp%0AwnrW&_0y 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 WX$K)u8U^oKKG7(dmU$*ZXRJx(ZO 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 M1yWn9sZ|igN^$z9W`S2MB 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 z%0A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%0DVuOoa-q7@?JziL5BYjLWxwTzn{MUX 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%0AVXG>V|GWblE+S<%n`z}oj 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

    3i&h$TlIaL_PA>u`3o-je@#_eF{ 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 z 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 ^|+mtIK~gOx(?3AiZ0S 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�!o$iQu(}7aSigw-d15Lg~iG1pbDs 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

    #uK&cp&h>ogB)f&?6LUc_=o{B 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�jn0s;AMKx5>t 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%0De`rX2 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

    bZZLQ#|aSOc>7prKzIS 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

    <%yvSWq@*LwlK$+M|6n6!}Rprz)TjYkbF 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

    VI9bMGhm~+mYQ%QS3^$n4h0h& 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�mhER%YpwQU~?3Azp!R58YWbG?c869q@EU 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 z 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 z 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%0DO@*dC7`Z9U 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�` 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 +S#F=d<4 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%0AyvDmk&}X+f?)g#hog}qutVb8x$JJeR(7m?&222 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�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

    le~FGXo(7M>`3GxkVaA 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

    l&%^2I4FrBk;QcGw6d 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�(7oV8Ja9hf zaquBB8-nUvO#Ea-{fhg;m=la57ujfYi#{$R(WX$ht$4m4ZPyH8T}3|&kF6)#aaSJg z@T@5OiL$Mv;DRF}&Be7*yJzKg+gnhR-ujoL1r)KW?|&GzhY1_pN}C>(-B@QYN-}P- zT{3cTNix_a@D|hoZ%Ge|>|8H$bIHie`yvBB0+GWdfmS&M^_%Y5@SAKptfici3&f_f znfxUZ`g}t_W|rL*`>{ZmWss{?AGK6{_2qlat_h<0@mwO>D3O2FF4JggE5rY8)Sf2p z^7^V3n%9P|`^jrSA@#$NzTGw0NF2 zS)MjMo;C%-b92y1l@}g)MyRbA2R!Oi;@I;iIn$uY?i#pmOygZiM9ox zf8tHuu;-D6HE)G2Z-u4qoUn+Mj%Ac%;<069kDd-%8ugB;HKI=$OLWL&(#N0NFLTgt zK7brH=@Cim;P)^2)!AL5CzE!hq(4hj$tpO#IIHk2+$|+ z_U{vZyQFJ{1LB+zM3B8b%^t0B>^;6!L67Cz-W&P!ftGV-#k2$6Rtjh9vfuaQAtT#%8)=a1k3ZXPgL@o%@ zL4TpukNZ+z?#mTdQQqy2GL5)N@Bat7(h7)Qs4(&%=&rz1f%;49$U)0x5%* zst%|#-U0fjMjiy66}VNXbJmfAu2&sUH@yS&r$!zGJrVR)SLXvobxp7}>-_f6^luMA z6ZDJOzbJp7_2Du_!vV*Hn?yhU{c)&+679bHhj z1=ad=j)FkiFGqhzL+WrKFg4dw{FU5C;UP z2$g}aE<@aY(?e(%Q1=C94I*-C7f|04$N=b$z@#9?%k<<^)ILvdbr~WuZx>Ks7svqU zfxrwvL=o!!;ssLo^q=yc>n-dJ6RSQO|t7(gq|Ut5Ma@2Q_#UK7z6W@_PM33bggJhu#SOW<8lnFigQ zLW~OZfh^Ec@F9NF`Jg+&k4d0K|CF+Xlw*o?Kv2$>vRObbuZDXm1whhQYNcaF*$n8KT8;U$zpPukfMO1r%F`wjHKo*= zOrjRNbgRphw5;Rma#YB64rZFna%tM^MGePQBraZH)|LWUTZUi_(ZO`O;<>LaUlnmp zppm^URF+|FnKCSSP1csLi?|`sgHRC5󟸹q^Go7Hp<6Z-~7C}+y0H25sibLvj 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

    J4zL8s+ak#G2=R)#XZx(1!Ft8?y5bQ$L~ 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¨9A-qMD-duhcJ#5liWGY$Xc{}UCwT7Ct^ZZJBE3g>{2xhI#4-H$`)V&l z>iwA~icchk6~UIV%}0Wh|C>pd1RKUSHw9ZFee!rQhq>xrz;?)C9=QCG0FnyuSfueA z$cLWFzDWJODp)hNc~9`nr7r{n{{)3gz$uZgK5NUj#N0D^^WZzu7TJV=8QeEVz>vt~ zFsED&oDMn6IhO75+vVf`yT(wYz8?QW9TY?s0?Zka)?U_In8yDpzSP{<;MFz`o8l&HV<^?@AbxJZwh zM+B!${*{3o=8VZ_o(c{^4)en0&HqD*5@{9=W$U?t=*Yc78vcZ)lVUCLw z&xqi($*(EtVy>BdruKhoyhO_LtYF31){Q?AE3zSixhc{R?FjabZ9Nx^9U^UIf_Y;n zfLs3;4YlG1{%^%1vh4Ya1!HHP z2rm3T7S^2Ls>s5HS#bI8d)nee{WWzO=7~tB@#B)56=_n>3vM}kNASSdnL%AY$3#lp zoZzOh%|pR+k-33+Ve*+Jo%2rEIb!OnVAa@}O~DIer>_jKbzyD_SQObLhq>eOM}pdG z7Sg)lfwPB#7sk#2vv1H)e=i4fU8Esd7d&%zdGP z8FM)>9&(t>x*V7bIn1KVfu)ecthpSx6>^xnE(f+k4)eg}z{8Nk?7JK|2szBqTNdXD!D$f# zn!}un0!%v!FxR30vl0cE^(btJc_>l>fP;_^AMdYS5J`STaM##Nz?QKy4+SG1aRtFu zkxzax^Cq8J7d$YwdGeo8az#q{=J)Hj5k;CgBR|kzJ0-G|!<-c{6oPXhhiSVUm<>71 zg3E!$ki)FH99RoE%%;nMyCH{p=<@lGYwm~?!hztK$od3xX!4o4Va*1SZ7(pRf2E)I zaMzZPjSc6!pXjgM6Im;m`yzGpiQs9-Va7&Gp8cS#iL|c(^P>LRR|oP%F*i*ny8aVdv^lvAMjLp1)yr5t8XB>Adf$Jv3mHG@Rj0nQ69iWKEy4s+EDOZihV z`%!>7bBY!-z^F(qmU5W$E(b1z9A?(#z+A{-7F-T2h8*Um%YoI9!`yK>un}^Y9hW~9 z?1voYh0B3~AGRbe<}fEkiXRwp`9cme=5pYy%dh1ynahE;%ja{Ld6xqVF294Vr)AL@-!(@mCOSpt2WFZSnXa;$(gfz&5HOPac%X_!)ZF<@>SksBA7)MxQ zMlGvNlZeU?i>fejyVO-8y2Qd|;-MlcA{MD3HnAv+Dv_8fkutWPYe+;{#A-)4CK)1Q zzx;n|o&VYUb~n7SG*VKoG__bCXYIAtUi;&ov(G-~?6DjIkoPvY zbTY`J%R*O!oCe(vvIlxArJ$!l&Vr`?c-RF!5VXHwFpuKcG-x%*9_ZkHva3@+h{MS& zFRhArCQ#Q0o%ya%T3&)U9}FuV-z|rNIOT-cD^Lc`2%Qgd7PK5>4|GWoQ`-24G>HqO z{g%+fmf>|715^*^gbub7(QC%0hVL1dK`5mFVmO}v4Lg=C85P;-Qgq~Us0Z2anVRdXl zcI<|ce4EJamP70mNPbu7L6V?HLC$VDC~ZMoQJ9?qeHngnxL?HKU^J3?BIX2YQP9-) zLLR*@)cZ(f0OpK9$3QDV_O1wB7sPxDaXaOpEr*b+13_#Pr~&4_PcIu6h&(5BUZB)Z z4)2I~5R4*%cqot(X!oCjoCWO-vbRrYzaWa960sQa=}SU)f;_tKqZ)St6+9=jlH^UH zEr%nlnuT34`PR)&FLO7`vi*ffY5D0)c1~vyTPbt zhkroBSD>c4Ds(f*-UFe>NlyNtViL&8L7}-I`&+wmCQ!Qf2|W?yU_7FB5lDOg8~Uvk zNacpmEkT@2-WBmENI5N`?O2lOQ5 z>LOFq3R4g{*(>6(KuVzFLC%5}f;_svuS^M)DNr}a-aVmJK^tOs@JeSOh%o~3SkNAw zno)NV$O~w1kVirLQ#vQKD2SLYigO^ z6==<8=O;C(2o(6j5Mn-=#UaGWVAKiDi&*iI>mqImgin~cE=5_X%Kh8G?{K1LOf47sG}QS6MEM9NA%J#=-qiE40KWurWQmj3iuk@ zr=$mcR-i2lAnu*CF z3pqF5b_>uKIxGk|#KV+75_&A4c6`GPdb{qNsR*bmh$0X@!9?d|WC5C6bNUSc-3)RX zwC~rOA`o)|nF8gFGvyqDn`e^y9$L8IW?C=hAa1CI9D>_w()Zo9kaL^uY}`ki260O* z&bP#m%j0&?VhW3OU4?xbrg&dMF4vL@(~NOoQ@Hi{gja9yd9rL3uNS zzN8x&hvR0(G>H2eVF%)3%0YK6hgeNHh?^gw55X-E@+QQckdQ;1PdR8MaqlPeA#SG} z#Eqb|FXGmC*a30NC*%+Z1hNl0X*tCCl!Lf06#5VkQV!x~P{<)32xJGuouQCJaDRyS zg}6-=a)`4j2c4g4LJq-g z3CVqTBIMkrm`OS4?pHSY5GURj`k<472|e!nW12gm7vfMC^f1V2(6z5_N<-We$Qy{e z3E>Tb+X#~TZbHbpt*~DpIq2BeH2M(t1(Jifj}ZD0`vvF=-4ukJTMEkp$wAx~2ss3I z2PF4Rf{=5!;7-ax+%X6_#1(<`L9B0w9AZTv`DLML9_U+Ltgq8$qIP0@V$Ea(LyauDmsA%{39kQ}sPImES;gYJK8qYsg*&C{S&%OP^_Y&u19~guvID_7wd5dHokJgj zwP(qzCFs@DtU9yC97<)ed78y$mV!eL!Gf>~gKmdh&LDD;cpAhiaOgwi8t^oTCEk!j zu$(J9Ueygb%e!Y&4q}-!(g$6$9O7omL9C^QepytVW>J+T)R05u0_rq~Mbwa& z)zoPgRTuX+a)<{4`DL}US(;ou4UtQe)1X6wumf>YApP?~SCa(Y6@-eHGJ|1FlVwZk zgT}w7QG%EhNDg9YGV~!>mXsXC3SY<}#t()Zl&gE{G!VN|4q~w{^dSzU9CR?`YDb83 zDc}AlRWE^Du@1ORAQH4J2rCdQ4odDd!jQ8*I2Vh5)2t7kIn?MwTo6bfv|>5Lt&~3z zI`Dm=0%CnIOhPQD9CY1sh`T8V-3z%Y0>Rp$T!C0D3_B191(JhUFbp}XhAbHd1CgtQ z(;!v~Lk{s&pu(VL^>FocwPdJqbXeo!`#B$0(w=IX5>V`fmge(uLC}`V}#w5f+0Vai5DU8anG&uEU!$52kNC~vta)^T| z2c58dK?JLKVTm=oc0x>C&3TR3&q36rEeuUnWhd}!TQ3PTpSumW*N zz$wXT)e)K{JYDctD|tF~k&M+mSp~6{7v(4C)vX1=KpYlGX-4Q+lAv7FQ*FGcCzWay zq$SISgN8?=9 zD%Vwk7LlI_<$_nA2X{Uqkdy_lg?|XyAOFYN@+c4q`g(zu)5nI#M4S-3rnyLuy1w?d z9(RRj8EZ;cG0U4QWzp)qKo&qhBM1vDT0KrV=!=%KBmAI1`k*%jq0eI0a>_xUvz*1O zsV{^+XsaOfS4FU;d`c@)B^o5-vBcE}y;l(0EPc(T9Q4DMv;F*G%0a(nIZI+)fuaO` zQV@37n0__ot3qr;mkLW;^Rcwm2mOQ~v@eQyoN`vV_6wv9dQ%W8ta3d{Ip|+l&MMdb zSk3B#eozqlta7cS9P~NMS>@`)YE~b#QxN(Phf;oA=tPpBB|)gL5cVMDtbJXMwXZ(Q zU2h2#@Drguu@|}z`c6R<^d9LoO`yYDW1XxI`sP?C*g0KyDfsQNcGhRPY%-S1 z`mB&G#)?-T^j8GokCia?|0*OFzqZ8URG;;$)g(ciwLlfxELxq7MXNsRRJR2x_*`gr zELrtI-zo@gmaN#zE0tqHr;@xTbT>)RuL(l?p@tZTiM zBs=30&QcbSq)BDJP*+gb2%eqGI?UqM9)U>EM+IT5E8tP28>pcO$_VFBxjKyuJ4TN*jrZMy==K|g9a3tP8S z4q|aD?69!4Um$(ZVL`}Q*gBPR&}S^aE8`%`~dXTgHe zsSru7arIf&V)Lfl#M+g}aC6|BRDZ!{4ZRqPFvkQLgoqPn7DW7{nH3Q~XNK*NQ-3s! zvu1T$5XD)j+Aj!()u~GYMR4LxG~R`ywS0!DSc z7By_eOpL`BPP#6C+>&js?g<=eeF)n`G9&4!Ye?Q#9v-z8mvq-9fT1n}V=2eo)H~0;#Z+ z!v?Ol&%t!_80eHB%CMlbLl6v0I$H%Y0Ag7uS}uI}{NvBlzzv{`VuDG=$6 zTCL}@xYB1mWl0c5&x-hIGpwjwjYX6`d!bGVWQ)B}td59e4P=iXin8#rB9NT5j$g5y zg$cGKNzV46GXjxbWQd|H4_p*T&W4-gvFWDoeKwMA)kXG>xZ>6c&DHjbyI(Gv`|LXz zKNdEQ3C$(35KjebTj$acVtdL#J1mFTmvYd4%OQFx2hCUxaWdtgQrA;fq*eL4-|$yeQvT^d5{NI7Vyag9AYKqARdklzYy0`4!U7E#GRBc=;DrRJw-pI%dag0O|eTui21l4I|Aal z(N{WuVJx;0u$ACdE!ge*hF~v>oecJL=WBZKyeqZ^MDWBIx0@n=+dH)~KNrgcBut7YAsPo;WA;hVW9|bLhTwe`?xR7$tvgHt0 zQx3XjImDfmgYH@m@hIgW9z)cQ#ib!c=iS6}6f`afIRwunN`702s~c3lO6M;ERRqM7 zevt!+eJKa+w;ZCEa?p(B5GPX(I%PS;`ILh$SPpR| zA1;^%@qmFc$D;)|gFFh#rwpdcg9X#&!GdW{QSS??7+|?2xGskBsKIo3zF_*&M>Sdn za$NTKPqTghx+|(ZTu(rqTtbW;U-d}9)Y!Rf+W4WuO$javM!OX{X9V(Et?78l<^_p$g zDhA3;*8Ky`DQz{|Zv7!$4+^T;7M7bNN~2C$tES`*2dArY#ThI2IAq`FOdH=5U{~k7 zfV(I{&8wo$EtOYA{e-@l%i8y{Kw6;Ytx@NeSPaj%Mxj;S4h83Tvgm%xxg}oCl5dCN zkl%4N-huOrt&(%NJ|iSRUIn8j@*81f@%)nC2@_1^>->@}OqgI(>q|DaT5S{`{*|n! zmNSPpROhX#s`kNC5k z73aKk&Kc!BU;8uTCf3Vi>11>-k#1{|^r%Y$kv0TAqwaDoy38BpZcX)tnxeZ+S_eaO z8pH_DZHFz@NO*RdC_X3P0J!P=&rUlK^}uJRZL{rkAt=?-TPd50X)M1z^zc&IGgVjC z5h8vhh$B;~HdPPCIS2zJV@421=0y-qFeNNm^SFy6<)v&o;xQOUJOqQ;xGJL~$d#cD ztGYamY>^=jR8@I;x~j_4)2<3y)PxGi_tVo5fF9khD)qF@H3h0VJw5F@aiFTw)40!0 zFAK9TsFKAkcD2^F(et)maipr)^SWZs+lsYq#Qu1N@ceYyD1U_aS2fM`yscT3sH*n7 zty&zRZfwd6TM+qJ`Wqm|Tga^Me^Q0^*(a^J z)>>y*Gh%2fk#qw^aW=X$14Z&`yqsMs9aBohjHwdc$18IeDsvyN%w4F>U1-hauf~;c z(ajS9odP_mIZ=};4`v;RpW-#IS9J(ohNwW#FWpoHo<${&&{>}gBn7=5-SY???^?_~ zM?g1%d}C_xO6LOt{ZQIyXN+D2RMXT{dlVwN-Iw3*oJ<0$dh2fNteOd^g*v)VQ_eYo z&K}ts%G$cfQf$AD0lF?~g(6N$bUDO5)+@FNYQtlvbPQ1LN-+vt%R;Si?1}_HmASFb zEeV)7bVgG&?@0($UpwfG-IoB+n;MGd0||i2yY4khfXxZr1KL`>1G*g1%Rv9xc=gld z5>*teJ(UstrUxV)&hF!kLq7of)L&55*G2y0?|5$~a>R2m=Gk*gdGowvf^D_tUt(`& zjlJM2d%;)sf`5sFDyyjywJELO_Sma?;yeJ)sgPCP~n?TC{7QnFu4w!`2RR#Nd7MINab4Gw-PP}kcp zE3~ypTSCL8>h6*IaB%(6u=5l94hvrlJ6+H(HR3u)E0U$#_YaGM_mA{B>u9#IN;UBi ze$l8iwUHl90mVj}234U?lW>gm(awIAy!K&#ZTN)?T! zRnb`2ejIPw&W45Mey3dTiKgg+h(xVYytJ`a#r}VCgAA4ya(dBX4K zlVtA`8=fR(6B9d^M6z#*%}OHKs>J>zk?c-lOOi-7B<=V@knA>Mi;<*kFk)AcNcI%5 zkw_%lh`v7d2+i>@9ovW`Et`nu$|j;YHW9INNDAy5`a+WI8)CDNq-+&pe~?Ia2eBnc zBpZU*1tgL^Kp%>YJag>zVS|sPZ14HiBw3~YOsrJTvE+MIAcb2(&y(a0iEQtYl$Rfl zYkQ7JcIli?l84=XE6I4!?MW!GVdoYIiF9G2g=x&BPqLbek@6rng51BQg-FA6-OkS zZa$GDE6wbik(6CCY?TqoMwv@VvQdWJF_N-3h7BuzJ01#bdttAOblK_hZh^>sLLW(zO)u3`&LAvpsa#Ske`!7<)

    u51OFE1N#% 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[+l^|H0xDb$D)e+rWXWKjUl}(S|f0x-x*p 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

    Pp$QjTzBU8|qjGO}9H*y9vXtON^z1heq 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

    Py$O=0>JZ{-3=zx)>gBZ%6Xk67s75b<|v8(s! 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Μ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 IwSKYiJ(ga?61#Nh@Ov~w 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

    _wXbGegcLKV8q|>y26xyl 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%0AYMF4|l) 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®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 la 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 hEy|(oFc-wQS z=dk1KXMiy@j{5mwq3g7sp?%mo^(pGIdS1QxEMGZ0>~X*mS30g<+)=)V9}lqCmbEAT z5c`GZcW_K`{G%MFKgPa%5AO?DWXQ=PhZ1_^_A!9ItL;2rV@9agn2SHm`wW%urXTj+ z9De3`bmr1ELB8*0jv8Y_*XLN+_o2ObU*EA-!vs6*QDnZb=0XHd(D!>iqsac0P(}q+)M24%2A3TlWpIR~K%iy{3-m|}-L{!zwTI^#sV zb@|WcFFNxd$v@%d2iPw>!0l)2tTRRfO=mycaT3gx#4}PzBZI6b$2Jd(8fERL#wa`M z(eX>-87ZWZfrZLCzD1AK+wm?@Uxvk+v7UunVccOZ ztYDF#-OVe~R>ygs`dgdEu~2RUO|)V0@Dsd#JZZKiY=4sHyvysaXIUJ3>fLtzr#iQN z_)|QG7-I^HBzaZzF^5H#at?Wvq4psx)TfIctZ(3_d3{0GA?aEuUAtt_ILp^{OYZeb zdR#>fx|YdeMZYT^Yh2}Y;EucT+Ry9txQiYJct3uI*C?{cVS@h8l7qWG=RhR!e$f8t zROB?Pub>`e*j{_1v$MO4lUa!zKNnI>qq5O%L z*C4kmw7)Rj`}b1Uc?Mr zSd3{~L*K2k!vVT>$|5-AcRqv=#v>xI$WqQBkD^nrYm)BZ#{-&ZLDy4B4}DnZ+NTuK z$fFANv6xbx;{{9XaD>JD-=hr+tYD$?9-}eG5f(MdZ496`3)OYdMc=7U{QEr5XrK*? zXQ#g9)TdvmS6| zGu%yhy%7J15bG||EeJM3|QuCIDT1W)iyc^$w){dHZOT^ncpt>1Zm zpWFp1j8#VyEl->66f?~6f+cpIJzLFv=gfaaoe5G7&=z#sZ>hV3t|hzFo~2%E>0$yu zeKm$f!D}CS?N&b_XNNrwDE>9Zz|CK$KVpb`bnThN?5tn;9sAi>+PdTE+QKw4XZ5=N z&&Sw(jA79vuZ1?ISRnQ{-q3Y!vWJD+9->~?$UP#0B6J;`u76v??RU+XVLT#&GAgK| zh7+#naQqY!-q@ld+N=B^3|NU*i*Yx!>OBlC!^zbr9k1)BG~?|?dafn6tQ^Pjvm-+N=7kEgZ1t-t@Q-v{N} zSlUit5oesHr^B|3A*R@1iyig|IsGy`&LW2rls|`sa?La44Yp4IC(2R8aH(C_i~109 z=-N{Yx81E*pIi80*SlsZOCHs~%lQy3^w7ru6HGl@wiY%{%p2n~9VdR)|6S*|HEHXv z>xIV)EYIr4%rn6hy2jSxg|e=f8@vigRnzVJ-m0=%Dow7xNauFrC^>ZF;&b+s;8q5EmTQBM< zk33_xFId5%;k7B}QhS&Bp_g;1{r11$^^SY^5ym5)kwyk(PnGS>e@h-75I`OUPm}HA zmgf-`HlD`%r5G>!A=hK;ur+F{by}1uS5Q5xw__4zK39y#IyM&PdFSn?HOKeAVhrq| zFXo$|{$KO61uuB~Z#efdf8VoVdxZN1e)a#7^97pdBF9*H6i`8sF+&I=0gDm2V@z?v z6}i`FqJ<8YSYeF}eY41;hdu^qd+Xh^y+2#;N^AAPoo~y02OQzfH)Wm|EY9X@GLN** z=JPS%E$+_dT{`p5n8Tf~%h>Kb1#fH{U;FVcfJTyc)M%Ran`=+ zxLUZ+iC!n}bD`IZ`yANorsX{cdfiw=sWUmsYBMp)dd;_Bp-@GRZQXTcd7MN3tUmSMb8bKbOrR+cP8pAF75P+To?PKEq z;kiKN|9vBN^^vOr;vab<%hqDgx)0d=4{Y&Ex$ZS<-{Jm$<{17j>>JkqJNt|<>$m+W zQf@=fY5)J^7-7eL9T8%GqTYVB*lyXcJ&p*lf7-7;ELzMr(7axMs~=N0!4wPFeAeDz z-&<&-gD!@cV}T<3&_IB-KjNOX264wa{IGcBxsTzBoLkhM& zhb+gj20aG}XkYdE(lH;}oV=cH5%peQmtJQ!wze_Gw;XNV*W;0PIpKyp3-w9E=Cyjg zRwkHYh8Ks{Z?U0o_J3m^dCsmm&O`ReUL!vCOUHB#y{2N&u`NNz_5_OnV`!Z7{^}RG zkUwLdIbOW^Y@9Y@Ows4HF~JOTlo`X`w>@WGtJBu4Z}7N@)>-|MvDet*01F@cuh(vx zW0OMzO|;QPpJOn9#g=20q+aKfj#IBS3~$;2lK0vkcFwc$y1cG>n4X#Ocnyp5yz}-Ax!0fd#tqv?-$$;VP(TG$ z)L^kAe~;sb>~}iLe{K8#YY4%|7iR}xQTymet{NC%h!JL(;{_Jyc~*bkx4_sHY(9s+ z?BC&Yne*eH8s}~K2l^aw!Uy%!_-?+fM{_R_`s|PJJcbscbo!`izuDd^YF@#2ZRtt3>LSP-`1|& zI1(tLf;uc3lslMstbWbo4Ys)XEPiLf11ugXNAQFUawx(=-xpj*14E24gTNFu)KajA7BB&_oMw%bU{vf(7_>N_d+*cp`Wp3Z3^2kNQ&`L>+k5SW_sjwZ=Y6F2WDp@J&mu`Vg*38G zeU0~u-ct?e{o}vpeT@LZh@c3IHaQ)1(TCoDdhaPOiWm}3e(x+#@4riV?pRuf#&GBD z@>uW7K86@!0t>zGF4enr8*;X|<#leM_g@Wl*!!pBw7c&sx88EQh=1LB8CJ~u=hodvc(I}yS}5{&cl1kC)M#>Zk*>+=U+Y7ITW1w630}}bBO)d zb7i6DZw{R^Pq5H)dZ|81UwK9bS(H#l1y$5gM-vur%W0FR=T^_5#hCH}OW5feS>q}23y>Ij*Y??l%J788YNU=QK#HQ3vH)Z;2FQ7AygZMuKF<7D zBK~=div`vm-S5((Mt&15w9!Eq&-6`0_uS0F!p+gWKl{*p%CY-*jww$uLz6js=wpBr zbk9wTOXIyTraPW{AJ7qPV@xndi8;!spbiVoE1FL%bUajV$3k1TJ;mcRGSEFmEp#kn zJho%$)~{$=V}mVrI3W5V^KYH`j`Tm_in<%8KFqOOcs4qYpU?Z=qkD*EQ9uzxSVYN< zA&w-TQGxO*&^6ytRzjPBF(48@OwE^wtn(n?wqFZrta`*0-bY z9tWIY5&Ht3DgKK{<^KvdAG1i#}z$r|Q_Lck33^ zFR^jj!wisxejncO`-T3!x5E)r=l6*=?LF%B`-c1br1Gq8K-&mzzcP<2sKWj|*rD8o z@-345{_%_y(#RkS3;o`z-$mWuFZJ(0i+g^Khwz9T^z(QLiwEig2*UC*7xL6Uf+sw~ zB2QWWR&sxihn=6x#j|$nSEs%Q{Vt%s7R^`c`_#|iBUgPahOgAmso&y?T=lV7yi&iT z-p6q{>ex8>hga%#|L-97*2kOR?v?rw^>J*WJ{FI!)F-IVVGZ@M(C=WE>hsjspyyV7 zEQ+txKk&0s_X5}N7&DZ=h}R-4Vzk@u2_4E^OfZFhPkDiUX3HJ@<ZlH-4+UUT-+Emwrou9{)Cr;jg^3bcBv3wR$cG%+p3*8rX{H2VI z7wEpAx@Tw?Bk10pE9{{Am|DcXg4ZSzjx^=5$L^)+`$|q1@OuJmO@wj^89aQ|r#w-% zaOctZ>U-YL%~wtV%1L-*7uYK2ZFyO8lxLwas&Mzm?!|dSp7!SfnnU}bzGa-xW8+x6 zjjyqF4^kUn{i4o(2OfA&AcRLmkwy(&Sg1bkd1kBjx~I+7qV(0Q4;6>*NjZh?b*cMm znjmEhx8Hfbo2Rxe1{gtOigMnTXY+)=hW$hY&#>rG9$}1$XTf%fE%rFzh}*y$LALVb zNw9rJ3Kn_F1r(wCXIiM-z#gfu?N;w+j0Xgudv>0W zYjbPPG%Rc_s#BjH?!V4jd7T6~f8r4__`aUC!$Nf_oV+%xuYHo&3>s*ng*GhKly(2a zAVSbR6kD)}P}aQ_^QbuWk3ODDJRuH?6J>puM}VJ;VOXRnr;&kvu3D&U{|0vd-P+;j zq$%+;Pyd!Ocl->qupDgd{0U}Ie?R@y-$LIl;lmAruy|zL z2%Zo}0!f_zoYnUZB=HR0V?To&w4Nm_bYJ@Dmym-jik>pt3Tjxv;*Os$_jo`Fx)*x` zO-wMw40F#5+Z8NAlyx8UBGkVQ>))o_#{f2t^@~y$Ljp;p@R^LG`?9-Z*!X^aR#s3) z3mx=f5u%(%7I_p=g5_J@6LnFKPPx}EU*nQ^TmVZ3UwRMCUR~`|C#Yy%2p799XJN^F4Iq$&2ZL85f#01KTIC;9? zdJ$E)c{Yyj!~VARC1c(Ea*hS=aDdNmy+6H8_Ze@X?d9A#c@NYjk%60MBRzdU`--vj zJ46vB==TWSgWKX#dy{r?^V~6Xk8%Bec4axv?;ZNRWQZx;Je#lc0qqmU(mlWDI6QE^ z#R(gJ7tsB#_o(wbf$qiL#sD#Xb|;{p`zd5l#t;^tHm=5g%lHAtl+R?I6l-ZU|#gzIZe6(5n%4wg`HpdG3*}cQt z@|S11Hcy!Gx7g!|t6$4&ig~t}{rWfVBfM8JhQ+0Rcl4Ea>Ho-F`kmqlNoc+p^I7;T z`T6~i@%-Qp0fb?(rCoN|kwzOG3^BqKGb~_{qpZ9E+&pV9Q!f=% zQ9}b3m)hPoUjK>L2d0=|g$*n!6l$oWi4MBxVE_yL{ab?2-^asx)@u1 zCOL*hnDV9iIQ9B`bAlD(*PJ(Dq0d9rK6|A-M|~A*obW_njbTyn+PAN?*QoE}iavgX zp)o8PUc2v=cKvNu_IU5_v!Bgz!ael&*#`umzrTiI@wS`@c`@k!yI7ud9^yn20> ztUeZN%3^a#mm9aUDDO7%zd8Gj7RiKfKaj=HFs1jG@nE=Xk*q z`rFtDH~d@c9{Sv}h#sy#!E*)u-9>*7(%)Rd(BFjOu+TU=jmbDGtg(f~+G}6F(yqSO z{5#O7uiO8gwh&aebH-KOBO-{xBK%6do0}o$#8}ttr-jCdL7yLAYEQgUuiPp$mX4!^ zK7YPcUwEZnxjkqf^_j9o{gwLWEA<*<4vnFGv>3cnuYbp1%HL4G#SU@CNkFfcGW+Ph zK5Tq_h7g0jZmd2?-P477{k#68*U>F~aKfGUZ}hVB?{qiE@8txY_7HUv#v>v~z@kD~ zs;Hrk4lMNful`P#;otcB96g6T>S&;aHs;vCLZ1!mb74{6BJ}qT<@P-@wiZ#!G3YY| z%R8Or>3j7q3XOzv-sgHj-`-Nwu zVNs@BMGbW{pzl~4;p&%L7RQvwGQkuxtYG1OFWY;4y@nuTgb+p!d6ZB_6BY%hzT(t3 z{JhRFK#0!}9+CHS*;=%{ya(z62txS@B$0yt##4vePvfeO#*INaHhzur`$72{J}BS9 za*Q3epue42=&{`5&Z$=)eScmbQ}y*i^&y1u=+qY| z7g6(Aev`-2Mh6!98(kV%96O#h6?%^Vh#({OAU3WzDr;I9WVxsVWIjLsQ&q^ zzDIo@16ZsnZ*cTj{WX2%2KvrGizDR|uD^lfh#NdX-*uNp77es8fQ9O%fTB|$qp!XX zZ|99+`Km8?^})0JIQ0o6z4kp@eV5-678S}>v^-Yd<+1cJfW?YA*4Sc)J#Iq0Prs4( z%&+ErgBUE1)XNoh*G~N-eKP1^jsiIq<$0m@2%Zpy^1A4u4~r7zGB()arPoBOP zuZAW@SinMUQK+pAwP{~0LX_Qht4~ue8DwD*XCD)IMha=v5%?tIAdVu+(BGRaR4>m+ zIrZv0!VPu)v-$@0O|)R~LV1C$$LbF}mJ_a=aqhy*hYYfqV}l)Te$5*Zwifz3xP3+) zrEH+cHJxIq9x z#E`(VC&SiaPM;-K*r>l3i&yGH^o_#Cv-~`DMU*kZ1XIkh!4AGh&S|*!1lU^CXm6s0 z4lEk4)bFXkcE+=OjVU3-p}&#zVUePoMg}>j-mTN$AgWMb3;j)KjSY5Az18ihJE;EG z@$&)q2*5&pEayo1i$VuooN)gUULVkB^g}H5__KIE5%$>iXel0BEGew8hQ>+L zFM}-fIlhHHt9QqQiK7%6E$0G4cy*~F}U7LVGe!%ZK1M0(_UhYE%r#zS7TVHPM@(y zp*9PBj{XRJ?ydhrZBe7##uzV7z3+2)%|V}W>;L>(sLnqBj(BbQ|G@hHzXe$6vvM~t z!{bYNcRt=9xQ8DW`V4#E(P!kkerV$vew=fPV^7(_`e++;`l#=-(?|Umuk^bnSD&5V zob`YDfd1$GJ}7_58nvz)XC3-HU#3{#K)W2_bMoA|w4a(w`)5(2P(c-S=zP*f2R&Hy zDGV^g2xClP;pZG-e-{i>enJ%b+h76~Ny^Vi!Ok%`r@c>kgfSM-`D=v@^mjuGw{7jU z`8d}^5r>8Qcg9QYs?+&UeacS1JIeR)L+v_Orjdc0r?Ooe(WBglu8SCA42w%`Ixn7- z!}-Kw!egB?XSmeGj!cW1{RmvbRL{y=Hz85=a9#xcGY#DJ_lITDA%FC zGpgOrn`_E$-W}()2k2a>zfVRHLjvyKOWn4(*QWENu0yTBB1PHGv6tGrwD-`*5EgFT zocb56oc0IKhhgY^s=xhNJW)2IbFwCit_77gk;&^g*YfA^_#$JO61FO6HJUUXisqk$GIF14xMeg;e_ z&z*c5qeGp3Mx3{IU#Y+4d@py<&kR5GGr{6go7(mF)i{z!!NSJS&y-8;;aBP_)K^hM z9Su*DZA&=E`Z<60@&EC5KT*nkdwu8Y-dk!VqN1rNiKyu1-sUPQ_XfSFXozAgBPuE? zDn_EHsHIjCk|ya&ha{w%UQKt?Yq7dntLbjK7XtYwAz<@yw7%*VK zfI$uV{du1A{oUP!dVbIC)!pBvsD;ztPWKx1T=x{|OzxA}Xk&hB|aS-F0^vvxmO39XrY|*yDhs$NnvTEj9%-R;!AbkRc}0}OHJ|_qs9QtVlU!?8ovy`D zAI-DVJh-;AJqOy4IC*($ub_I7r!gYl7p}aZF)ebm5X>v)%L2dw%4NX)i*Edvy7cX9(qqKbj+rhVU7is&|JUhckp>d8x}VI zZ%q3H7MkOCEnoGT>!)i#bWMlFnewY%Gq&GbPs3SHfU?F@ox6T*Ta12^Mg~n!m!;+@ z_F>y%>(d;S9bT}<0Y{v1OTOl#xYv+mc&&LUIcRQ50Z-6%C{p61K6$mzl2g}M`l z)J>iG8_K#aWdU8sVWB#AeQLY5z999w4o26CoM53kx4+u1^-oa$pnmLw-`S5GbtMF; zi#qjB)Vbs8dY5bC4yX@v9f;=7Xx@#*kos2ysk_#`^x7}`?cb=^*rIDr9`OXt6|xvp zo?wa@7FZ&{H5EaG5Jm)=TVgTya@Q<%9n2PcRJiU$*R5En&26t!a)X_v6Jv@^CgbM81mJVeL<*cD= zQsT~aCR^(K?C+4=v6HX)KxG`LQy&XmTccyCF;Y&w`tG6YTq;hz=Jo^-LrC7A6)Ab?}rC!&oS^LhYXM{=#b>a}0?Yrj#iZICc((6uCc z9Iy+2ZTm{RF5?l(>!FVUbgjx3I|S(C_Om(LZhM=Y$wgj}*P5H%#I^RM*M8YgbGy~= zvVKq9@(UazY_LW8i~PPq51L24g@y8U%}NxyZY7QcbRA3@p9JNP$$((O!?M5{7TE~ff%TVo|6!rJ zI!e^(Iuo_&`VNaHul>!)ijdQQE@e1@&p^6S*yux(n0<`Y`9sFyZ$ z?M@d%T;>Jn8$<{(Xbg9MO4Laik9dNvWl3@@MAw|8@qjFJZH--D6QLYM3~?l2;f_^f zygHh2$I^8x*T#5o#(AcX+h5zDep;8Cr?E|oavL3V(S!P!GG+C>?Eh9j6;F~b~7tYD$*Z+g&YGVOd0`qa%(qfVbSi{TsfbLw}f zlB+%z%Qx!lU*{<=?`ifNCvUxu!&oIXt8|Zol3-{UvT?dgx z4NYiHsYTVPzoTArPu=zw?K|91f31DwwO{sIzENLeoDs%&!5#CpP`$qgWgu+#6dkDC*9 z@(Pq+ar@JZ0}Is`J=fZ+v^}GS1}s{X+vuT>IbL9)whpEqtMBq!eP&P}i#_FQ>o2pd z73^_#w!2ArhRDw_4lMfA4UwX*;MBkC%j;YCocbl@6*j2+eLf3VApZ||4T~e~C!Fz$ z8**-85vCkL6md_2Wd}XafTcx>avB+Ak#lG}Mi^s)87!=i`ni4GTy4LF$}#pMfef<9 zp^6bKly}eT0D`dmHsvlXVyXXop2n1Gc~9h4P(=+5w6Vk*?)onK-!kTh+O>_^FYQMS z78A--%u)PV+R;H5E9`OmbC%7&5#;Ugf;|p6!opAfJpu@M!YpfOcv>tiqLgEZBZ(BW z9a?`6eGD%y z;Iz+4TwsYcHaNhd@LBc~fm`15Z+LIOQl7q%&jsA?#ambM7UV|ByOw_>U*F;Ddw6TN z@5-<3`<#~J$W*dosB1TMc9w)TZ`|0er{94zXT2N*)vTv^8-;D{4${uajv_pnG%pTq;Q$l(e0y^p@f(s(_rv4zGxz#Z4dD^h>0|AhJ} zW|(7vC06*Dan=7rW7zrw>{}2agb_syN$5MGFm%q_La(zPeOIHo%KC0b_wID_^tuI| zSMS2&OztZ*XE}~C9??S|8*JhKPF4?nACo~1b=Y?*N6IJI_ZP+Q;@=F^JZ+X8SnMc= z*$$oe*S1+~DC^w)4tv;q*_*$^{~vt!dzxD+JuHz6zGvsm?cBJ|flK>)-s`gz&B+v< z@0PeH%Q6R@*S5H4e0?9F^Zf~|==Xve;YqfP60)S z_AN`k?UyaJe+kx|LK-?p-$VsQuLay>4OK?C!JnUHfg}ZqMa*eA@bLy>G40 zU5~woTGnCjotFB(MDLrQZNEnVAw;0>D|8IBE;FU9eTsVfa=9KG|6|8>$Ft+2F?!G# zb?Cd79<)xeXugqW?GyTF-!4CAdR;&fWoJCS#}&Nb2#W&cB1*W{-eC+^m)AoCzwf;e z%NQ)wrteeqeTQ-qs6yX`G+{CR$hVV%M126;D{5>u=rq3 zi1!2x z)^{{B%&|b=OS~V@cSBF8Ky#T_xc@=^{X_&&SZKcS9tZf82aVH)`dMf`vfJ){FEl1^ z0)0O;gWFGeAIi1yL*(U2+`2~9%aD?VUUw)U; zqwb7kl+O>c$iYJ21Nm`}xbmQJrcghN5M{T0#p^XT*kXql?BVuP-iLB+{0H)$q3>_{ z&i3g$9QS(@%hx)hv}s?|$3pXqV~8VxBy2A7fO7Un=z}~om$-;7CRjk*;g@-DF~b}d8QOHe?FQ6;jwRMmKZ{4oZr<*qUAZxDY|TTqNKw{& zW7P$|Vzqo`czuB8D4$`W`KT@UevE(bVbP;b-@B-;+ZiYJQ^S`2~{uO)^j3H&UnQQxwp834;CNFao1D77=OUN@1gG~#?JPs?w;eJ-{P%2edpum>DX7iIvsxde9MbaFHyu0M*>NtVDX`xk6F*lPjkF+K;~!ICg^*c0rVY9;OE%} z#1MzYEBQC%=)0VI1fcJH9-wjZ&^Y>jN8?z8c`f?hD2f>3NFWJ|59M52&x`sx>xog8 zQTja_w@;nuyCB(n4lE^{dN0CK3Z4#2*OJ#R-!E`1;P>2k@x*rw`kq4Hfrv$z?+Ya7 zsk4-cXU|gf{ee7qtpAGFa`sq#n)fJ&Jf5BRORozkUev$*BFFt7@!lbW`7iVH^D8zQ z_!#+fu{a8}J#@1{1U$pP3mjjMC;fz(Dg9@(A92R3mfm`-|MpYb&#X(wM4!DGru1LI;+{5Z@6$fS2ovSPB0`=-5knja zB$0x}hjKn*E(RE3j1|_{V2d3hj8Q-lC6w_98`s90k$bIwirh3F zkU z4?~PG!3Hnb;}yxgjl$0kuif^0+5!k7gfJqA!tJNL59Qh#=H$uncfMvx+2ZMUc~8(n z8xzbuq2FWONTY&hG(1g~Ls&f1#~sJbYdLu~wwCVr%5leY^S0z(w%?L}2R}4U6539S zE#>C|`-Bl@xcPnZQGvyd`WNhR#0ko?s8Oz?g)x%+7yg6lA z;Ox|&{*cehAMsf$vAuuHXCK8svC-eR`Dv4kmop$olxwk}&;6hA8OH|UKj-Hh1#DrV zoUD^$_2a+b-_b|FGyX) zsV|aJhBl#s8tQ1E1&alR71r2dj{}Z4!$ReEuRp_jVE3P~c0YCZ2)xm*KDu{}?pgB$ zi#X*3l2E&aa-LB`2VL|qzz7zq>w9$zmS?qn)>`?@@%mc*lKMSv$qhmGs7X2fbblPR z+x@yO+m$Q2@68i>=)=Oj-_5ml)pfi+6Q`fTI)>xS#ol)`^{YD zYb@P^M`P*UF?Np@8_!3ZAG%+U@~Y%KqxMF=a&(^_jWxlTZPS<*G1}rtczHc?`p|V} z*YY*iBh7G6oWy+7xwS#WGa((Qp>YA`PQGdqk8|{H_;xmaFF7KDqqs}7a<=OpobRQkJJ>s?7 zb5N|`Gxg@$IxH`C$G)P2E_&!g_u!epLf0ZH&)SCJRy7!EQ?t^pL)}c=KkQq98)>rqNxz?`x-(0KL{af}pK-WszeOT@(>mDo? zy1$6nvot4^XBX|4ZMxTp?nQD3i!pWTtNW5%YuEiquGQBVL-ah72AXKY;#%8?_BC|x z5)13wq3&9H_l^48xA6P+Tlsl|?vY^;rhKiwP5lJA*Te!Z(Dj-J*nK%}zRgDA^Fh6v zZ+U0x-8|i=!p*Z0cGR1z>+%v)tW(m^^`IH(UKqMh*K1nbe+T~$fFN{jrLG~2K-Uq*VG*Y-0bM(p7TO-5=fCEhJhkcC z$_%o|A+IGl*Pi8K<143t63Wmul@*ogr{}#?py#>NJav{0SaitkLf38fF~AUGOt2tV zmRMnpEi9(wxYughb(+?Gt?fh~ixXp+yL*lu^03gglDg+b61w-t&3AH~kjL$Jy?4jb z4_ye z^Nd)!+fj42Bk^}R)<_|Z2bI5@B{ISHbnT$-xu9o&Sd_@q{U&rD3Ee|N*Bk0S4ti!u z4Hk9U8fc=87Hw^GpzHoD)TaASbfJ50^f6GGoIVB^VuUd)lwZ38; zJ`cRs@wQOe=-wAixX0h_IkEa4enzo@?lobd`%zrBoz?!mY&UdWX9N~D#*Q2}FL;rs z>m}WG>#ut~*ma37l=sl}hZfh`?!J%hfUYqNApr{;L)Rv{dC`kJUEAokTmQGN|FiaM z*AMzbYzsn&AO#D%&QRAFx_NPO+`QL|cI$s4?~GU2wRgIv(BfKKnD!{*NJ7s&`6MXo z`amDtJl!+H&C~rd+;;0fq<-XapVP9XZs*yvv}k^YpIhjhht6B*p1pVan;k(|==?zi zRW#5-2Nq%euGM^`JN^z?!y-jp)>C9@(V=XAqYs^W{arqV#tEX13G}y>JMM~{H8#+C zEsEroP=@+iRQTJeiyrK6TK!FGVSk&hsng$h3C{z|0!ncI-pkT4j{-_~LIqXSV9}>A zzz`#hF~=4!*yD&#g5&Rl9}z?mgU(r{V4*sl%Tiq)_C8vB`i**>5351%_Y4*#ufBIt zubd@T(D|tYjyU7SdH+>+^6CQAhY)evZz*4^&r$yf`+V8EbpT!Iq!3UHqqzg2^Is&I=}O%T;6Mo8TIZQ=yIk!$KQhG(Zl2n-zIS!b`ux=0BY+UXP~HpnIKbV$5PkI-t)k|Pqt9?0`W#`4&ZrzUh7aX1T1m^*g-Z_E?mKIi*p)QL8o=`yz7V2X;Im&q` z*P=zC3;itZFy^zS&!&E7tzn-{n%>2M|DIK%E$ij%SX$`kK<9f!KRXsNK5I!lK<7kt z{;`NMD$qH{CM@)Ou!}zQIaN;0Y1jGBAg?9r)a!G#@GM!bpwHRPW8)Wjze_0N2^BP8 zv7x-h4muYW;5`XC?@O4neHJp5v&cd3y?&=zs7{{=)jgvQ_dHYijruk9vcVY^dM)~_ zxb^xBi2ELwocFm*`4RezG@SZZl{v3-i+h9+hVG*rht3;4z(VJU9#KQXsn@xl6*kyH z_W(Xa_sP}0aqT{~Hjd8YNDFP~oR01(Y@u^PBaAVJ#?ifYEmo9$oMVY%fLE0{=V77x z6!K8Jh3eyYMh$heVNs$iWjx{uRajJ5hvvTfY-4E^nH z_mk8;BoELz0v{}NPfGo*uJZ#^{?^mqZgc*oI>680G-=cj;_rzE%(UeH<%<}>7vgE3P@cl@obzr6#{eK0Nhl!wrHg&F41xe0AY7CC4xn#F;( zYug?7wpVkt^tY6@Q-7aaZl|`d;B40|#~_3-BG7#&<9I*@wtu$%EOj|l&_Wyfd)@w4 zA5+%$*>>3at$&>3ZF4u%lr_(92#d>htG7NG`e+WN`sjVLc+yy&CQFMcyZF2^-4t@SDbl=p$ zr~K^9`MiqGL+Ct$&M}Dg@&ApVsgtw4x`(SgK<5Cn$f1BoSh#g9>a|@**u598$xNV%E993aZe3UmMW5K&?l=vvki&3;oQlvB4HE(77?4x6>e25oiz$6XN9S;k2h|6P<_2ql`y9!JQX+t*uJVGiuP79cNs(twX!o zw6A(Eea`#u=GDEtu9tUaDQ^CNoSA3N(n9|hN*xVoKKu|P=x5x*ZEsWGLDy+lpKJXz zhS={28&7q1Zd1QU)P9eE_j|^XX<-L387@op}_|KpRsmaE5KaZMU{_hSkOP+IDJw zudIKB-%ZebBK5Jz(`NH@ZH}(y&gx!@1?boX5JVUeXztwu$L$F^W-%m?bjF=9hMqqx zdst*5^yS!OkVOu86i~$W@A0$pJg+|Q)d*+!Sf7RN1FLz!c^tmE(e4zj3e!SK1iGCI6 zK92H?%W-s%MR&fO&6#tLlZ~%?M7E&yzw75UXrDiH{H?$4(`onPe4)I@t3Jm+%=>}> zY+mdGVf!ux$hhxf7z{fyot zgRJv8(;U!-r^RxI6K=jjKJ-l3I8w-=hze?GV*)+1bq%|h=PjQ>A41UcUXw^8k0SJ3 z);jcA-SHXK&#Zo@bi8f0&#L{73A6prXd%G1>vv5K`d#zM?-=jENB;rG!=ZcR>HdAv z#{grG?vppe0v6WS`dO~Em&uh!G@X8WEtQM1(*HrsPn;(duX0(5MgM(tIe0x`UkL3o2@59S#v72z9F=}4YWRsD&;y(@Ub5j z4a!~5h^5Ru8 zy0B22+ivw6>Sc?}FSAbMQ9uz-=%R-qMi^s;6*kzzV$V1>*ZGyQJkYLjI?x>70j$6E zQ;xfS<=T3!kJfMD=GwMud*#vTt3I~P+HTwS4~_Fye{HkH{jczuL=X{==DC*egwe0^ zy8-uE+F{YAtU1A%Ut?Q5n%g_W4i?H=czLZW?E~6|7(sK5i{zA0M)gX*#?pEri6W8%>qN}ETixs)f*9b<{+ zR^CH%M8imUGAyO&sj!rWM{_V`mgKbZc zas+WC@qjD}DB%fJ)X_u-mvch3J#$!WDev%tgHvzE^5*wACa}<)&K+KG^E+%KLI@*; zG>Rypjt2S|V~q{Yctw!+DTEZ#D4~o7G^cZj5oTCo1I@|Y;RSmfaD=u~b2BZL-gX|m z?ewueZD$nP&J47jkI;6upzWMO+qr|b^Omu-oe^j|GthQw{;IZ9b62&UU+?y%*wz8^ z|Cn)LQTFP~SL)TKda)Q&r}>^5BlZVY%QhC+M%2(m7XwT%#~PZ0s=24H@clkNSBN2r z4Du*L^HyyxYLD^|Q!JqQr!P3+#@VhR4~y4$;Ul2tO7IktOXrlv*F6AEjIO5tkF=w0@>xd(PBvR<%a^27LsXP6Y)5j1q zSWL+=bIJ=WvB9e+_{Z!M^00WJP4+n8h%+qI_lEpiudmgoc>RD3a9#6DYP(=fm`5Lpzc+aSzjuzV3LhJI=PwN^$>k5?L3$hI10T#F9 zOUGmNVP3oI(Ks(q|FF}4Ox^@j%wbU?r;JBDp@J$buC=vk@1p1Asn0WNxYn-u*i}Rx zIsWK9u`RGjdhME<{Z_kj)Giho>O^zBbI79zi)(G#4h!X$P=;Ht@-v3G+~y72eM0%4 za@^2`h4s7tbAAs(`*KTe5e=;1_P2g%a!aU@-*NV@>W!0T9a(2R4}Zznc)~L}o-WG) z=2&5m6MTQgXA3cp=CG$=(W5-Z1WT;&f<0bw^Vj@83Id2ChBR_0;}JE~(Lom@jIqEH zJG|hGSLnF7$0Nr6#gRY~DQKT_$fJNFO0du|?qCGHPj;;J+0xjT@6U<6*kACw13u?C z-}72Ruy*CV!p$r2x`-0Wc*F!+?>*jHZ=5zsA_t2V`?AIc$qMh=zhJC?$$N+q<~YLQ zMBd#$`&zrztIm&m1Yr@T96=Om)w2#;&w_Qmc*XI=7HKOx?Lq1! zgcL0FS|S(qd0w}0hSsmK9&x$eXD`p%ZQMI@)$cMt=GC`YwqY@)yuuy_r(ShCuTJ$x zyu#w)Uvun{K^+!T$}`Ndz!EELu)_=Xi2N7)ydr@lEDp5Y@%kPiq)~!Jhw=~$?4A0T zXSNY1`2P(*iwMHv@G0%*H~NJcBZUUq&Un!`>T}dTdATDezwk!=&40=Mde$uW2>x5! zYW9WK_Xr^5d1P6~5ED$Xfb~C6wovX9DtLz5XU1!b9P2!4y*1Y98L%87|L^(yqlglQ zu(;N*OCRNR(Yuo0XFUTfF4mW$Umnk1|Aw=k61inO;t3U0Q9~0!`h*Zh1X0A0Knjm| zLX|Pyaa;7Y?HN&?LffT2wmn6!ueQr#LynGDle!Kp0{@QndeST8mMI0$SAcq3Vc)~O4XrY5X#+YG&HMZE}h*#XQ4nG12 zBZ>r4$iO1;ANYNUJPNRgP>3Opwr9)ofcww97h;)1!;|_fjb0R4R&b{66&5uL8t)8^ z^XT>E<-1VZ0JaVrTg$#Pj^$m}tMAn5uRaT>pS2G!>eXlE^wWM7y_~hv-}0=TF7HCe zA`TscjB^}1l+&N%eT3%P&9H>cr`uANz%B0+EYvSW{m1mvygdue;nKVqAAMu6_|Upf z*Wd5kIM(3~6Hd&T0U@;C7LgyvmY1S!X$Ib=nr zzDHSex*Ffe?8C&budIqqFQnq`!Si7FXr~9_Jd2?Pbu!OeL!k+P`IY%95eJT$z zW*?@o7*RJ@8+B^42vCmV6?e}5sxF12*Jk;uD?|4=QJY1Uat?W1Yp+uOj2d*TEp&`C z&|D+;-Y52~KFibnP^_*?`G6xVbT5=^^*!pRI3e)umd!Et>R&JFm%QG2bwMY;NLe0H z@#y(^7J80e2VLkMD;7J-dX8T3J2=j;P~9!BHJ{4wwWV05@c@h0i@XGF*Ye8LuRRBr zdj6Z{GD+v&M&oCIHr)e7?V9^!(Wb5g&EwLXEVXNnl*N)dy9bJ`=Y=|3hnA0TEHrOR^RrYRbn5loJL`YY7+z>R&Et}VQ?Gen?s_a=V>Ho1S2DeF0Z5$N79F=Ww%o<(SppqxYs*V=Q`YmP`4 zFW5tK)hsfUjpnQczx!(vlr0LhNfEl&jfLj4t+0jWnSBzJH3#hunulhgoFp{1=80Ko z&YAA>qIhjB845jvpBp_|L}SKKRwL)q34mg&m_z8+MY{Rr#yv4 znSLF#=r@DKn7SQau*U)Je6(wATEE4b@)@u2v%Y%-ob_I7i#zQqUp`yS-49!j?~DAL zd-S}rP=sTE8uaWiX?=;$40fK-4{}@`nr~p?XDqo#06~NhMg$hNPA#?G7-K(q>(Mj9 z=FqddUZH1_x$8?i>vPBHGu8l_pYm3Ikv1uz0t@w-VaWQlev1`#YizKGZI`v*u} zqV3Omv>z5>+9J@i+>$8K=C-TO`X^~id1K^RD%V2uR`d+IJN8}2!$Ng>o}7-8+AQ=w zrl4HCUlw|PToihSoV5p?cGcMeIk`wCl! z)}whhL4*)?wr4?`^;uKic>Qdyj`fMqNAq?pG+#&0gG*xoiy8HEEU<#+?&x`P7Rxv4 zEm!kMb`$dmJf;*3&^3J@jD_rEGl?l#@{3Hrze~UXNf=rfe#dtEf5c zXUe@8?-evR&qDJI(|AA@ITT=#d86KPpJ=b3=FoaJ*kXqlSZF?@^{G;RhWctwquXcC z>mw`%l+Bp(1T&{S!9HnD*X>t04zQ?ESBK_)Y2H^GU05{VsJGk^?PJUwT92M37=-4H zg`M^3IfvF~LfM{qcu$VoC&KHP({E3%(Y&;G&m?r(tCTg*O!LbIu$WOl#{w&8e%clm znzMGT-s+CDpOmjLJz9_EuoX~52^I%(tnEq5=Es>h1LS5c&-NZs36I zXZg9u9RAO7{Lw)dJ?!AS6h*m2Ua>Ujn%FOOS@<7FZ`c8DR41TK%OzFRO!%JP65 z^0++iJL<$e{ypA{CDzb=wKmW>e4Ve?IoGLU^liL3UIfY0J-Z^Xdv@vGTt500(1q@+ z)ran>rTb~g1UKJIUtEsA`BpxMaMv^ai2NJ2%LljL(&?vrY3VzIx7PPo|2<>8`wqj~ z-WW^KJ-V)qx8hiBF!uJt#??KneIAY_#_|{Ly?DDuRsk1nJJO9=|=Xr0wgWqw``CyCl-{QT#=V$S| z_+1AJyXTajwrlNa>a)lp4~rsY-G58x+d9s8Pt;XVeWU$M{q5go`{08`igFn`&p3jG z?ro)eS>@kof2MwdDQ3{Q!V0Q*cD747lA%ubnzmR{w?m)0$wmE!`mNJGqJ4akccT3j zb`I9YRlQu+-?49TZy$BfY>NP8od*sff+()#Jy4%R9tBvuQodu`?3}38>;5`+K6Fdj zLif7SIZWN>rVrigW(bRGZClzyoR@6Ey*K!Y*A_bWsdJhol<|l z;OOOb$?ZYsQngMCALl1^?lX!6EOL}}E;55>og4I`M_K0~2hcsSbZ_V>EUvZbe5FN* zbA(|;kbp&%vOJ^Z)Nd#cIDa_84!YM^4n?%^NzfMd@@6b`o-uaOenb78NB4I5P=1m2 z5_AujmdcE!bBY#fmq$;9<+Z#W^|$o1dtqtYr2y@Nh30;PDqhkfJK|K?&s5m?!{xF^PRd6^9znnz3w{{fzE>_V4-^->Aa}! zM^tm_$CM|~xzvSI|ElumIVSMKB28K6PIXV3yi?z#+(H{Yr+!U&3!VQQhxxYzN9cTJ z>lJ$I{fwGA}ULI+*+U{Ro4g>pY8e@xy4Q*2;yR{4t@ zAEfbs9CXi|0_=Qam2wSrG@$c~I=8q*=s#m0;hrx{@j8tM=sclCfc(pIt5NC_NFf8Q z{|P$JdAVMl%RJzS6V7$))6Mq`PPrw=PK*3p^heW zzPOJGEHw528hea67Es@3sBZ%ubYZcltb6nnF~b^rd=iw?cy~^drP^O$5&RPSfG{3m z5v80$8V|_8J)c|QbrsL3p^gSRSi?fEbxwMWrBfg0+@#KVPI1tAN-wfM#J)r4%F+n^ zDDNRooMZ5P*|PXdczHTEW_dbaW1;qE=)9%IQ(hd2H}aLE^N~Kk!qy9He|2}nNOrUdiIzOlLbvxL(xLd6gy5~+1y6=w8 zmpyp$ET!zJvXq9W!%_yG2}=tdQ=Nm-F|9)9V|3obLg&JCZfgjg-x_0z8T|CSM-UcP z7p5+P7<6vvt?`qzmAv+>v))pi&mo?m`$LtXa}5p5pz{VRSg2k1UK&E@8Z4%iujQYp ze^uU(^Et&C{;zV3k%i756k(xuAFq>0JM|gL*YZa{!I*eO@F)5FB8(UkNFoK@D=Ga` zyqCzMfHG=mz+%Zb8|-nw5hvWx{|;Kmht{Kea0Q@yr-h(<8$}RB3~?k-#I^N*%)aE= zh5{a;`zm$up?%Z6(E6CdqU!V=Q{K?F#SSk{-juc(=2&2bH7smqs ziaab{s6XR|x`0!!K5MT}g!(ArPP@h^polpZSYeIa&)Dei*JXKa+Pau}c|r2xaPxPx zo$!i#XB_o$*Q35+L=bcGG*%u36j4GOGerMBb$G-xI*%ZGsF@?oF}-XlKRbT!p7A- zPx6eb`Xgjq%QCK|ErhA|Gov~jj z2b{6B9~QdrNfRy9y#1~_$7k);X`l6sbnSEXH?23nFR9nP8}fIN+`o( zaFP2=TjuxZgJ{9B_-uK3?(?xVw(@(>y#of&{R7_WuX`^%c-y3YZ7iI8J!`sqv0ja3 z<7t~LDr}pcF}?nMJ~N2_0YAI2&|H7DX->Y{TIgbg4R-Jq`HUfj2UPHkDdx~Tc|RVI zMIB8{FvAWno;}OkKV(c)VWI6fK--apZAX-xhl{*1dAdJ=&X@l?2*gvG9`Pv=yu)+quKc^jX>7RyT9Ol!viv& zEKAMJtzZg^5$j(e@JIYk#uM97gGJt}bGPrzHnuOusknLc*L?^Af6V)V5aKBO2|xcR zL-zr&{k=9`#~E+!jpt*GB(h$A-8-O%Gj6p_=)oP=_Cs}6uVZYXv32hR?N8S^F0bTl z%KVJs|LgZd>$d3g{*E!h6c$^`JG|ihM*Y#L5AZn%B7`WCNWtQ=-RiUCNDi8RUxDV_ zTU@qV{e~R-+}%6-qk27ueh1Apw{YtZPQ86z^Nb-DlSe+Mf63?QpY!h-Ec8tJd+Gy7 zAdQlz&QkiGIZO4=JN-50>95|8skzW?bSv~h@Lw<iz(l|38F<>L2lh8tQ1Hg8_z^Vg}t0V2u|X zaiekI_k>uAt>=ld)I2Sg(u2jEvW~GGJF8FpGsdD`bJC-*=yL4D=2MR;Yd-Y?ORR9l zD{lTJKj*M{)qctr$~$E&j`g>GZoYCg_guL*tVg*M zC|BF8+-v!oo38x6mv8H@QLlZ`{Bdo6l>XXo+g8h~lcV|WQF1g--J{+?Hld3Us{KbmDZtS zR7DM4=-4*@J!7MdE-v>oLEjvFW9>iFvc8O z?+YxnEj>)Ia_X0iJ!dXH?s^@RK;ib_Z5CvJX5Zr4qc~Zq51J!GemZQ1$YiB&md;OHW zH0=cpF~h?xuRXe6%%bS!=-6moYHK*{ZQ48NdU==a+SUZLjT=}TDW7o0oj2yt88=Kh z0?pIcwpmOl?{LDaQ@^0Rgr0kOt$q9rw0qVpH`u}Ag|g<@pH%maR_m2{eFx2_x9F+B z`?3Bzye~Mz|97pGpK*%r=T+^R$7W&uROj~7=h_E-wtHIA9>x>uu!zu>blRUU+8eYr zq3abjj`}OdVo2QxW9YLGqb-dl^sF`ueV%r(c6*kawMW$#acCU%SB^!Nx*YP@BTHKe znro+L!D$|zo+oATL{8nwyKG<4w#Eh;&&IL-Q9e&G#G%id*0DhNyQxPOd03>#$$9il zR?*Lv^}EcU(Kg2d8sEmX@m{Fgizo42ehfG!5mGwoKen3AWT8OytD*L^EO2t(u9IMzQ!T^bM2 z&yrgvP}f8Y@o##6?53G_LkRITo6`+C>k#X6)g6 z$$_4cl|vr7j>@9*b>>gVU!untLuVY#YrXp(+NjfW2`x0gRs0Ab2)icDo%gD?549&~ z&p>0pIOA)sYy+x0I`#JaGS$6%MxwVt2Xb$`y6E@WR`NNb&eSMt-zKn7ooRb*Qd@>v()W!tY{O=sKJ(dKh7fIV^N- zk*;+TUB}dcuD!9axn$4OHKA*9=1#khKTHD9bvH%m+L|UTGzaYA%j_#|zGAf;8|w9} zxDf1laZ$<#9HIG7udsOiI`aecy*9p$cdgB~^FP@JXS-vJ8%F|`zoo1>Vb)Lcx87~L z)2~8Z3mNL933r~BwX4350frc142w@|?~(hV{@2>v?U>Tv=9IbhQR*L{x;-pnl;cR? zT6>22GT!z1d)A9%MOkyZHowO21;l=x-;J<%{&9{GG%u?S&CTkDsC@>%4X9Rd@4M*7cjL2Nogf;?Q*reoSdw;qJG14GZPyS}o=1ngr!+pd3Bt z!J8pRl<}0S_f)w$Mi!QDc~(E7?;Q7>^awd8J`U8~`~+iA zr#6c`b&p6>mv!p(yvrKuXrP5QES@QUs9o2&>DsvpW7eE;RrmapyobNSaYXl5Sugv# zC+Cc3j-Ng=77=oF&0QMSPtSv~ewX>WW^ITObp6=`y4K8MK>0)Mx)yDV^>6Sy2o^i) zjyU0ro1fx6fyLod+I4-No}s9p9sO)tG^p$SG~==^y*CzH)&0!-ZBUzquICCt?^VIc zuc!E#hU&^r{fxRb0vyw@b6oYzz&-RCi8}du&YrHzT2rU@#3D#t3=fQvbH<5Nmr1{` zD?9Z=>SjnVhCW*sbLzG~|NeKAe&#Ha|B!t`pWKm?U!_jZJWDdR)@^b81-A2nf2+yW zwp!>JS3i*knbLEEf# zTJ))#K*wBtEF!;5f9PkT>E!Da=c)6LoqPl72T;pl9CbvuTl48}zet>#V0t zU5%eD)#<&rsIt#Z=snkaW6@;n9`xDK&#Xm@-#NO*Dfv4bI~4E)iy3WZO<6g*rpiKf zM$eHs;soUwjcK9W%RIL|mFKetZNszE@0q$5RHtjMEOaea7!kys`Vr;q@4olQQtB9B zj4AY78H*G7cUS6d3@tT=g^j6Y4H|cd5j4Icw#NZySUiw-_xt2S*Nw@er_OQ!JzGZ4m5Kg=_2M|tuLsrZSu++3 z>b9`w&shDAI$O_{b?MnOcg}cvuFaiS=dQ=L$+pYJvu)JUwsS~%1Z}THlX44fbkIc~ z774Z?`-kt9Sjsc%SYi)7`$f-vIsCEp;%AM1x&}^p1L&DFcjQ>q)P@GyUY?#u(}bQ$ zV_|t3=UV%MzFTPh8E1T5SC}ZiU$?eXZAGX3jy50s2zq(C22Iz2O<-Yp+J|fHS^Acs zu^*lB%hXk%x|&n3*SbcmdQsmdcYqSd@X0xjL+Wn-$@^m$rH|U`PWzhn4Yt@r$Jhry z0b$b6**K_LaGohtE6MN`AwoskX=SADD>+0-TL6$e6ZVByE z%h|6Lbz7*e@6_vc2i=SMS91L&jv@79Slm+=_3GTur#=%atg(Z|=ude65i9fgLH7UT zvkZ$3Z3pCO)3b37{}V0$v$ei&JJGH-Ju}DR{!jTg0eS|`00H`hoqlSIL2V(YpV}Uwwu94eLERFeKjZ&nkbY!eV4-ITX&;+xe@FY^g|6{4>Z@m`7>)66 zU$uT{A1u_z@-5G8uh6dRHbboI3B&(|f5&0bqiu*0biLmU3n)K~2x72s^VP?$6a2J( zKCZEQgtkHZ{>nD^yEZECIc>V0^Z~l|FOMRWUqKZ$Sh)G>W7iCRTE8Z_gTLSycKDgV zn(f#-$KycT4aa--zw$o9;)%M(U-EAh$Nrvv9s1~4TId?T3A*$dIQ^#7RsQMw_qxaS z%O3g+WjPZcj|3*D(Xrl1H^X~w*IAQ&N@N)zUJzq%A3A+31|8%`e zZ@mfDmqZ#5_?YeZ*!2flx1MQa`(xXcr|uE9Usm6yZh*bFKUQzgJG$Jz68lw!ZI9(Y zQ`bZbZRmMNJyo=q?RxcbM}#`XK{x7YPxp*o#6J71Q+4an=dN+JcFXNz0*VSzH&)R}jEp8kH? z{sG?0X#0X|u4!G{7Wy}P^zZdF=yUD$)9;_^-`JUQtv*24XayFzKge9Lf6qq0!&-wy z>3!-isJ}*qwbZ=zw8-gqB5S->nkX=L6&Ch;k!#kv@z$IDLtN+3Yjfh|8|3smfQ13; zg~f#298+FfbMN()Y4AM_bSygFIQkvH7P5??u`H(KmVcOI^^07WxL{v&j4ht2JNhH9 z=cMk9mmrsg?geRY|8nHYsGy1(&S6oa{I>cY_2WOvIc6;r=-#J$u|@cbdlPi;d+^so zPXGQ(pS9dV=eq8l?+SJL9lFy2{b8Yh1E%%In2WaeXj3gv!ntb3`&1v&jrTZUX2&#Lp*H=<6z zXLidqvV^{8(0irDinQ>M-t$TyTBe`vxI@)fbYg+Fu7U7@bxZ`X< z9V`;$azD*E=a@fWL*21=d@Iz|k>Hr7z2ka8uJtoqd$jFBb^2b{;*Poptni36o?x-0 z{I>cR>Q6eXjbo!@WRW75hwh0xZ~qJA&VH60`+iDZ-(w8C{clj$hW5Pyiw?Qr&%J&x z(qsR%@2B4W&!}5M-=iE2tQYf;3;+D<_bl&TbFL~wu80!KsGtgq0_C^WpHqJYy;tZS zYjH#F7TRasLoBA`mR+t-@)>BKb&s-mrtat$Sj*t`+*|&bT#WbLKKpfx74?Se z3#jjq*R`W_xcxU-A9K#|{5KfkZ*rX?hUwqt_@e!9ah=0r;`P5~j9b^=>g(h#aEU|p zL-JGR9nepGZQh{ycC=6Y8~i^3(oT)-IqFWI?G1()VTDJmofz}Qk#H((t2lEyYPt?!1qAx5s<{_*N_tOvNk9W0iVAFzU6!xl+i^LmZxTF|*!a$amrIyYIA zG2z^3O^^57C;n~g&HE4iTe@%1M(r(X0r?B^muLjkkI1iK^VxW_fc%2|J(dCW&*Vew zUl>_v{Tpm?;_XM|uf4uTbZyR|Ycc~}llSOzP2QkKzcJ>}SQ*C1dE;al=MvV>)?Wdb%g4gfh}e}(;VD*^c$`E%3*>eud?*F8ta_>A>v zA0iK2FR(b_b&-SeQ7<12$S24rkqW4`5g6t`Wb82wV`Vv`R~~3xz~F6F?Av8 z{Q4+;%C2AAI}a+WeSEKdk6a&vfcgUMkC(6KAmp8gI{6#bk@NG-fP9;L2i<`BIr+1H zmo;Jyi!J$-%inqVEM>J(&@;6>SLRsyV8+rK{JRKF$v?mdBZ$1(VCct61$_ppfm`&<{$ zzC~e?3dm>4=a3JmZ;&5jf1Y+gzDK@~K|uYIeEmP*b%hsL98=D^{L;%8D6744D=%NB zTtO9w>T~S-_CJ0-Ml!woc>vF{uy;!S3jfPVnO*HOQ@ek^}paggBlvJ=unF(#P9BEsCKh$01xI^_#oqV47Tln1!M z)XSf+PTli#uhakYTO_@Fhuf9fo-}PIwwb)R8!4~Rgk@#guoQ(?WZ%e~7Qc zh#(1z4CM+m*VNDdALMcCbhcc}2>+kV1&fSpr+flQq>x4i7VlRdr|sMNAFA`$k)?kQ zdHDH(TmLm{Z^J_Q8w>;LSL7qKFQS48wy@aj)zA0pchnz|JBB~blCK}IfXYPCNF#$RtbKyENu>Asg=llAUr_r*Kzm!qp|P}X zt=AvZ+UKatqX27nO53Q{K1JE0MLX?N{{Mbu`60Ox#;)G-E56=gL;D>pVwAIJ{lDCQ zU=b&mKr*2Ig8T!jtVu5Et1&E8e}f@L7-IspyY||($sKBE;|$)X{!m}7%i@;u6f^jF zm7kUSfB64Wt?B>c{SFp>{gyWEy?W)WpXw}57%PM@4%O>gt)NEzIqJ|cvB*)EN8x?i zHK|`r$fNA-kLttJ@8^~C``LIg@^K^r>TBdj z&>VGd9_6o5-ODRy?Nw*dCEr6opkBv5jsz;uTsp@VYjRI`M##&@D94e2_SqtP^v+S? zL*6+$`-pdrE-}SDp0I;On|4#oFn6|WcQ|_IRf=r}S>$kmOEjDj+c752n(Y&woha*w zBLQ27&7UNvb?&b#MJ|nutAE*Bcb$Cm_;p_rANkHv9Zgu=QNO_!M;~~VVw*_6g5Ul=)(aJ7u<2oFT&8T8BlAoYuF$u5;yZ;p!WE>mHMT!X5dAH{M-9 z{+|324*~U|4`t0C{(5XiZp=q-+#2;A^e}Ml*)H+moP5|jM`1*8iUNu#IoE7kXggE3 zGu$~ZYpbyPu(V%>VCJxml%=|!O+zY z=;N<@MLy24JI57f)IWIRs(uHnpYPSHPW{zSbrvCVVMK7KK1u!znrnj>ls^7V|1src zgnRrau}`PG{~+cmW8c(j?@@gB!Idf<~Esn{ZAQVtvBHzKYvwvJ_u6{p% zLH-hrfchEvJIwJ23(fO_9irYkFF1DdPdt3ChP2bUdcY%|V9}-D&4GSF?Vo6W`U%X9 zxKn0ZLDgxq?V^W17P!aKIbpsK!cLBD9tEetwux)lHD~K>k<)sE*4L)4gRX10zrSnp zx^{F-bWZ$Za`Gu}j>`#c^00cFKN^rvl20KWP+uTl$41BAn`cCMgUF|`|A>ArW57c7 z3s)a=^(n7jb?UD=^|yE+x5A^VPg0jcdaqsNQ#o&#ML9pHQ$InDISRN#@$=q{tM=)= z_HEklw^JL9t2%!?TVI~K0*bC(pLPS>1hj9_Ziz?g6Q9m&@;9^3SbPbuXIQA+(6u{q z?V<eq#}-~L|e zXm^4bEN&TRiW!!$*iyc9<9F$+@t5BCY3eRqeO+U_Xi&aF6Y6KtpzRf!=)qz|n@6ni z?iyW1k~OA~M$ubune*4jglk3D%ogDd`w zUemfpZO$zHZ`0fp@q!(WId{62bgst8eHH6L_G{RG3^B&_*K(cw7T%}6jyxaC1dfOq!HJ8Nxb+@K{aPHYYV1@m4K9kda?eCB6_lEixZ1>t(eVV>?*s-vDAs}BSUqLmX zzDNEZBaZC^7NdatE%_;C0rk2s4BS{VZ@d=eHaa*|ueK{ZLC418j`AD}9ICHzPdi5) zZCLav4{!s0Phe61JdQu_!+On^uz&9>bI+@z0ljA}v4Y+Ebk7TY-RnKC#nz(3xI5Um zPkZ-Nzukg%_gLZqE2v))>h}zb5p{>!@3)%=w6k#zjiL2wF1wfM-fyv{?n(7fJ9}@i z`dEVN3U+)fpAN|9$mdZAsJ|kA@`Z1Xd)M9jZaCf}=sm_i-fP-NKA+bnVu&N@oUyH; zjtg9(fh%Xsc7iEpxWfYXct-RK7!z^ljBO3)PLFLL1LvOY16Htg+wpiNr~L}rj}7%N z*zUEn{z>}2K-XQx9g789iwo)|UcKe-$Soc9zoU=eZ$<7AYaFVNC7BO9`W<`Mc{(7U zBcDehp#GZt6dFsfAB$c<{)YSzqkwuHi%T@ohDDX~8EQCGe@}ji2W()G!FVUZZL%URiOF&_6_O| zwcl^o4QOZc9vVaIwRKv%TXIv(aH#%;d@1$1Mje;=-f;=#czwd6^hKO2w9s|tY!_HM zCtu99fiNOCMG9xA;oP}lJH*IYv3&#G>Mb5R`ufHT8 z;X2WIe}VQf?d|7~`ZcWH=H0k{$-VYF@<)t!42`>ApCPB~QghUC&b4-dDVDIfq|Mm1 zD|qWs+3#oV%j7Gl2Gn=RC)`{&-aIq%TWAf}UjCS}+AG)g@?pvmoZ?V@o%cNbKZssa z_W!O|Szdd*-|Kq`i_TuV6m2rFc%uIF%icMPA>mZmR&nNZ*!IxJ4VHMo$_cZM2u_^> z+agL%lWhxaXuTU)bjfKy_Se-T*T=xszt^7Ec$wFY?uF;jy<~{9Z)V@o!~hnzx-Wdi zn|Ay4&(tTpdh3@ar+&S?@p9zyC)#{ zsBe%TA;VlbShNE2UGhEj1M2U|pRgY@w;wj%Iv~Fx|AK8meaHPjzK)5#r^UbF_1K)T z-T_L5H|w6zeghpl)mzL1@(<)!cnqkId^Oh^j+rwAi$p*^O+JHcKz)P!827C0!CPND zAm1b3#~`47N&bY_yTZEl3^BqTEc))=7y2RQfyIn`mHVOc885#f zpK$q@m(P*QqX6}@$Z>3A-^}~&8S8^ZjeH-^d-+B{{+fIX?ST3j`7PFrr!g&-0r^L@ z#Zy3i^cy)hxWxv&JYQq;O`I3@$D&GI-?dw?wNTmbXZZ*6D?A3&N0`IrT2Y=c-vcbl zDM7YhpvsCciwIS@?-K7+y>M?laGH3=N8X+FDM_%hscK!38*iSUqEY1|1OR# z)=0AtMQ=Y^w3)khVd^bZ_WM~rNeKj8X8M$vsm!;J(f6BALANW7r92hgZmLI^5n0upRWYu zYvj*S52zoIkA54+9(5cuX9yE4V6mdzscTnYYoW5=&+=vR6;uQ2JLGMy0`pv>@69)- z{)n%&mYA1MQcfWa^|LtscGmaXUXRt7%&Ym1znf!;95ipmn|DUL9n|g_775xWkqYQnBY)(^y7tEFl3ze`)V=(g+!LOm zeij+lsB1?1Y|n1;-}$D#O8t?mUwOx+Lw*7EyYupEa!+`M`dP#&YaWepTH=0%kT=g6 z`M#^)u(jB!Oxt6qpGBVX6&~^AiKd6mo1 zn*8IHC6_}!pg#6Jyhk8`EG*6`50Ls^=7GgkK)yx3jZQ$l#u{RbIV_fxAF#rUmp^9C z6NC`=<}XvWbFT0Cbd5Ce{CjBYeZP3+wY%b+tNz%lUr--**Fu4gfi66qD%P^I)6K8?HO-8)lXdg_CUS*Jv*wmxTDV;3ut_c z9p$k*uO~mq@xr0=YwZiPEuw@PEIO1mj{4VO;pa2tv&bQj0xZ<;ZT0E*sXx@$Uq^}l zWmMqjSFHIFYwTdrrCpfoJBKTGoe#X@c~5=F)tA{?oKddf9O`GGv64tbV_HNgpCXDw z^%~;#L)ToxyH2u{bI9XRz1nushh75~SCpH$#-aKx>p0;)Bf9TcgegaG zx|c8UwcVSdzk_QR3s|(NpF{Vq7rYm=ImQXp&mu=zW2_P5d{l7ZotFmrv8&&*wK%5D z2|`dmi#7M|C*8ks#68-gNV$YE&b|DA@)UC{z5EU3Ax1bf`#=y?lf66`D{#i#TK3@BY~LE;H}@gu;RP3+g)os57&1q|~ zAs77c9^;(bCy@G|mK7W7J#@|1`UDb`@*DGgqoGf&H{NrkQ9edNIY_Xwy%sTt@ z(=o6ZaScAUsrxDJtv|!}me};T*3kK-H|i6`u|Wqg|_?#*-b4{`1NB=3=Ko;G6--1wJ_XHlWuHQMMpcWmcaI6Jn-f12Zs z5VFW2?=;w6q3Mj-PH^iyvEASWwho(rOHS+5e*5d%kv}4T4As~7>NDhYymkC+OdUs! z@qWjz#&PSSk1;-&<9Wq=Bj%gn7E>IWKj^##&8O?bKX00+@5Z08onz_Pd@Xk_wZHy+ zFYNoFdA981{yaT5kB(pM*D=nNagJG^t;3&x#=I74w}RR&pyTe>t4`xsf9v;5euI~Q z`UHKN(0-JmF_&(CBfK6?5%XRbYG20%F44dh)bAb^1#*YlS^fF@)F0~WuT$sa(E79= zIpp2`sNK#vWSOM{X7{Qh=g{s| z1IkDA(>*E!&0&$JUy*y^e!rmhUE0rZhlR6ad-T&>A5NNW7CGc`i3YBmG201lohP=> z*f=rPlRy%-AGY3}cz>cfnchUN)*^K{ASnu?LvTJ_q{d&iPCx&|^_PkB^uhB}&P!GGVnWt`d1{pxY{ z``dn;{4DE1207<~?Ijw{knI=~+~Nt(*f??KOCae~*`A^1blLVXfbEyfe?v~|4O-uj zx)H{%o$bH%Uz3k<-1d*dE+BtG+YrJ!)(83>bziSFT?0DydQI-H%|G_GjyV02TqFDa z_Rp2Izoh*DHyAl9wvSjlkze5ZNW>6F85LBW4%;qz&YbN6_s$XPIY9`vA2xrOoYot( zz6f=vh`M%mtyzCvbJE2P#u)rE*9Uga>7Qlo$iqVIVy@lHYpXtLZxP~azn$fCZ z;M~iPD33A0EoQjG0^tv_-poZg`~m(Z3vOUh{V@K<0`zaKU&F%BUwQe`hqDe;pnumq zcf$FCg>w2g&eP;nXVE1$M1q{^Ec}1({E_-6=-)lxVh4*cedbtV<@G=N2=)m#NQSI6 ze=CBoTTYv8lsdm&?K2-mU#QNaPkDgJNAoetkK>#p`|<2Ex)@^$i}%`p3~O^XY+ta& zQJC?a3|lEX7i=%lzz(sGeU)P?Rh*%QI$F*RTbVg4wvSk&zmbT(`y z#QsPENu*Fm2NwQ*-h2D0{X2Euwx36=?HDIGb)sxzPMmET8Dx=j@@&hfK*!?(P0uxD zJ1*L`(L*0Mo+0HiCYX8dD9^FL3Pp}b31yr)HMVw4>y$5WiEG#~Zd2}{3mxwXZZUK2 z*e*Q}l-GEI&VhNMyu%U4-p-4*VMK5WohO~2mZweGKVQ0jQ=F$;&dnoq{i@Fx{`GrI zI}@c`pk8e)8sx5_Yk%P7HHKMI-r_i7y%>jb14~3cfpsH>0_v~`Q}*jEKcU|o8R~Oh z`>Ri4ADq-F*9pJJo4FN|@6Ax3UI8+XUoM~rohHah5{2b)9N zXV}=pZl+DeJPhrHxFnzzuaW#I4s(`+ABEj@gfE==fP=$zMYI z=pV;2xeBVNAElR(?aP;Ynk18%;(WCzMgH+jRWm#0r?$c9DNq&0a4m$t{p6{Kbz|x zeN14{rrd$*tp3KUf290^{qby{G>7)dV$9bwH+R^}pHZ$M`MK;r(zt-d;PaRRnIy*- z7Q=x2l>ExIS09TPau*5i&E%fEeE;)#-C+0y9B+)VhQ;s;*-vQhGq2w`Ab&@G?b`e6 zt$q>LGPcNnG1nokVR1&j?do@IRbTV!hm@l!?wKgT;(`3>f&4lk|3qG1u*D8x`iqUD zIV@U~rH7@Lzo9&J=4=;^_1p0E$(Ou}uswCGzQ)&APK#~ZvHC7wKYS_Y645WSEU#U@ z?zsFjTMOl-hI7=>bgaF`vKUgHW8qjn$6OD1!7j}`^UE3QE4fGF5nFA))>?C(Xm{`0 z$7!EL6=$&iNybQ_rm>J_j4bxY&3-lK7y7r`_3ygt-(Ek#7CY3ltOM83zo%Yi9ToWN z*|L@hbL-!`ufak&t#79FBb?#5!eYPP@+tb*{?sU2WZeEdFvg=d&IS1n3aqyTiy^tW zkXw5BDaUh$J3Kh{Z{6$P zySHf2w}(8rl9%t3o8ppvZF>8gqbx;~P{z5VwiaE=I#xZ#)cLg-1mthX%NP^fV&T|0 z8q4C5x(Mex?j+bIz4PCqENyhq!=v-e)?ylvUj^iAtU)eti3Zw^zdl_H*XTMuwtZMU zay`p4Hh94a*Mmg->*DJ;_gH-cZLz@?I~;wZjmA2@p4TN-c*GN8w2?RxXrqfB2Dn%G zn>p67Xwq-u`tR7LXj8}7Yd`VYU;I|a#RM~0Gy?K3NRbhMOxuGoGA7I^h z#2UvxXshJD=f=%5UL6({@>SHZL5n(@xA(oT^RAdX&-j}64!iHCH{+LZ2F<%apFi$! zZ``~ax5Ky(jQ8Y?cg|Q%TnCKXV646yZ^T-4d`{eW=We_e<0a{zMGi&SxVGQ6KQFX> zcYj>Pjb#1D zU*Gq}KjEB*kU$bylwh%6pWmym=<6!`kH&B3K8N}5;28W)?&CN*WB;5Q+a40X>*&2u z|0>QUQ`7$}} z*Bx!&-5;wsd$SgQ|E$__+SXt(q^z}Xu!DuxT1SK2H7qItd9@v3j0rTyIWC|vEH0>P zV?W;r$gAz4acw;P`}Vot&9(Ipa=rgC%W|yA^)dS~%FQ?V4Y^W{^#>aA<}`?zNQUf!=*e++TAFYm4M57HkW?0TE5xr;TPp=0W=Kf~H{ zI-YJnel7dc+uIKv`*WQ9Ugr2wjth?2pF8%!)*t=<(fYN{=#RWPo_3yfyq1V^tV+0X z=R3hM`e2Tio$tu|jQ@8#?#7L)wTOjX7q))AMk=saa_o<}#>0pr23esIO273j1z>Q*Nuf8KfA`X)$7K>ulMtH&XKOCpx0INedMSDUQqVZ6vxo-do8+IN`-`r7i!nKwV2T;;FvkM-P(KTm>-9IU zBi)Dey4E$S*L9R*sAFdlrft+~zhAGh^t#mjK-YMU>$~gjXKHKV-w!j~2QBR0sO^oH z@4MH&#-6zQ*vs#Ky%*~qpkq+eZ>fYXHzFwoYf2Tjh`!hP|p^qC3F&6JV?rq~FXnX0}S9qmqY2o|ZI^xe)%V6*Q7--r`+_DcB9u=NLl!v{V4;6|zKt$=UVcFN z1|y6yLA1j-(7zp@LlMcJ=lH{-soc+U>~QpR98;Viga~4=K9^pdLVj0$?Nn9*j1ZkKBjqhDY?jQB%KVgF%BEQUWMidDr!&VATg{_=B4Ytxk4;$=|`LpadCVkF1D*rI|C0wJ8K5n3Y zpMH)9tnldQ-;@AGl+X;230J$D+dVkhMD|N%qgyG<9pT z5l`JXN3>P@`@Q-a_2;;-cCKU9&8P9y$HL~;_7diz($9?l8wa9$+zIti}!39nStS){5vq z&N`4m4$uDtd363s&Mk`n6xT4W{%OuRZZN@U#5n&vbN!3d|I6gDK>1&xjK(cvV2Jp? z&i#5y`7iLg`HQ@+{tELTdB?Fr13g%1Jqc*u3aV~?o455Zur^c~Q{!4#d#ktnnb$wb zy6e#TEqc`VF~ALm(Ee(^&|BJDI~ylT`x4He{uVl}dFZ%qQR2Aj_>MS!_h_&$TC+ug zwkz6M-Tv_{aXg#Q@jUtbBuMp>iP`rU7vPL zbxrA*>N>TE4`2K1I(}Qb8trZ{#spJnUJKRBIqJB;B`m_Ul?YA|LmU=5=Xusw!n^Bq z6KN*EZn4u^ zsXxXEEV8u8A&-LBUax^J?B0_3XIKYzlhfFF5+E z+%r%`4Hp<=gA?v8{=LT5wLgDtZ+;s$!x$RZ#`F7Y46R>w|I(`?uEDH#UD|%=nrgw; zonlOlZR-tM=Z0gp{8u?2Sm6=}jXg}iKc-m+Gyy-k?-z^d|j_qIOJ=Qa&yzxXh$5Bt5 zvXq@FTe*aV?(tF1sl6BFxrTHtS?F4e{y`GdCLpj}(ER@r0Oz&;BCaqns0p0WcV`IYeW_~6i|Z2&0ptrf(4dXA@eslu4utxOL?cS z|0ef9SX@w+OEhqWCa%$jMQ_1-5e67x_P4kOF~>7r9BUupYdJ*}aU_sL8o9syD$lln zB1$Nu3Jd-F@-f7bMizNk==a@=xcdIO~Ch)oH7G3;o`_#>$iH zxVnv3e?@&8Gu&f|HJ-4=4k7yMcj{w^BaO_jQ;z<56rlB4==bsKxIh#7-TW3T*0i-_ zqJ7f7=vc&%@{Y#~?MlaQ>aBn71LRRg4d-a!3T^0f0t4u?0u#)B1Kcsj90j+YBX6Bm za?*wND~S}+(EcU%_RDWS{m|ETYP;V~;|(#w6f@joi8Y?E#SS6H2_uH&Z-5kIq%ncT zBjq)ou*D8XtlOePc?@0CI+qqba(xT}>Q}TqKH)Xz7~B(L-iI-*4%SOY%S)LlOM$~_;}7A zEF$Di5kmqNWy*KZzUwmz`aD7JN^IW=l)W%|^HHJ7>j^z`4T|~*T{FJYk&YG=7;iI`f;KH%|17GiO^qU-4k>Tr- zbEY~Mb;`O%9$2fc0gJ1E{DAxzYrJ5K6Z(e`MGPsVkw*a)RDYdn^gl-(TCYWzHAirY z1d>R>BE`8cI2E=QL&^)>JC;A;yvCdqTZ{N7a?eK!1*gQ;Voq5WxW^iqPvSm`9xS%x z<(S-|dO!DcYP~pyw3iw*rp21FY!LI>XDI7;^3NP=Kj!Nt9vsVOKbhCBQ)6o}`4rk> zsa$)wbS&TF>nUcA<+prozpJm`*SE-1K1bcL{0(30GXV?7^7_5|$ft3>9n0tV zx`uP-l5HOrR^K2e&4Bt2d9j#Ke!$9kVjKQ+tL5JA>Yv%lOF;cGeZ-PN1Azh9U!B#N}-j~n_7u4^aF)?!Zi85_s)kr>x4vX13j zd_8c+Y%LxrZ=9pgv@F*uWl5rpieoKOd@UKM-l9wS7E{OaTfUBR%;Jva3w&M2g=6_1 zUr#Y}EMMUmU7_h%UY}{0W8qkS$Ja-3?tjSP3QbrjA9vDh_v`g}4CPwT=N>Hl{Dl1N zUj347&FB8G-Zr15#Bo=Q1jjghkPG0f<7O*fWl2OZf>lp0yA2-WS0sGT!^(lCr+nsWRtkwL);vOfwpPiu%jg{j*vV?{8Q~eVxEPq38;^nV-Uu&U_5iCx4KhfvmG=A9| zKcx2=moIsFy&pHxg66j9u|^%cWQ_5UM+pCy~)$;)3SInKEKBF;N3TIAX;Klk!l za~P-4+AUJ7IgKoG$fE#@I^_#wQyeQ;DAzy}`s`SQx&*42V21dYTkF>`)L!}Mm;B27 zCHV*PPq0uX@Lmqjp5Mx(~Ofr7FAfBFm4K2`uU&R3Xu!D ze9=1&4_W5;TFy26&uvBd`cOVizKb6Eu(+c<#{y4YKK@&H9ioC7EJ^`+wP~S}W4~~Q zIxK?nCtt_)jS{M`C$i?->2;WL%jQ$DmT#a zH?eNavA_~Bt-(c{uhZDz$jfK>TK!JQ`R#YCJ^wB20?M$^=avrTE97r6#S9itl%KId z=vytzoRpimM#sxv1?1Icg2y7?E8qz)un5X`zKvsn2drVC&-EP2>oZRGSVCi3biSQq z@g1!9JK0BAOvq2MzzS7?1}b4urE;M(c4l_74ibXIJial)L^W6mMQj?Mqz zt?9vA*D4?%D)GHG?Pl=Xr^x4UiEFgbLmwlIF~c2}c)$~$f1O_Fzr_w(m&Ka$Gd6hf z@~7X$`xI)YV6j6dcGMzOr_Vj@_q(Ib63?{JXOAp4yb1&r~4 z9kLa+u(%}Gz!ip2yGN*95jEUng*7%f)c@Dg?&iQaZE_uSaj5>5{1h|z>#_Zaem~a( zYPf(!hH@4;9IC%3|A^WTaGl}3pd5xib9dwAw?D}KE#>zT&ay7`WWB_7SR)~6QrQOTP6kQZ=O}5XJqH7 zqk$$`&Va2<96d9eLqDgQd?aO9WIu}Q02gS%VnkWSn0on8i2Zl6Y^Chf*~+!kVcUiN zu9<$$HO2%p$DS`e@wM!n@JI8SLEOo(l_Jj2ghiM>5(`MU27kvz!5!*2)nBoric)%LZ*y4yah7dsv3Fzl|S?K3@dVZ##`B{`dhT{l5 zv(mFBi!;i41|@#J7G}M;MjJicIy1Hw4a$DI5noRZwA+#ke=O@o6ba;=B3lbRr}Eon z_*&06)z)u!_wgJPWFo8^7Rs&gh$mR+S!D@5+`!`Qlek`?zagdPO%~58pR)hZ-=eZO zp&Z2kw_ZL+xqu?dUS5AgN#`FTbU{)7PKO^stCgPU99cFQ27cf_|3x z?By>hU!jSXmv2)ZKtEqp9}DG%7-8b&FF%Df;tFj{qRbDATXOo@;T`4(e=6%i1y$&0 zi8bsHpSLkjfrs+S=^3G(@)}Rrz+&)OoWIZJ^#}bOtt^(GOZoG-A0(_5eQEcE4PLOt4tl1wghhgK zR%6jW28#{3>o{LAegyh?>k}r-rTIp*eMW*g)84%Lxvidoss7d*uSiZm&n-jGy7WwH z1q0T`jk<@InvZ=3=8G1pmnLvLdX2b9dmzu z6ZT2Z45zSt-cYva(nmiNA7TWHHRTs6Ltgt4IsNQg^Xy-XVS^VO>i5C6*Bs|)Fvm4C zM+TbX5?5%#q8!lP>NVCiv}XMcIsKiu8qT3PG)KuFXmcHy`D$yo6b=KI(FC4--@%) zvw|z=c|;dS)am?NC^y0jEMk`g?c!8+R7U<UUi%^C5yqIOU#-~cZ_&lR zocAW^@6gF5^bDi&6*emK({6-Q@@j7}A*b=uw9R?#Z4PZ0xQFJmc%*IWE4fBd%rGCW z(8TzwtQFVp*Ki+!p0#Xok>y-t3Hy6s4_{0B-@^Gt5qdUIM~0u(w=u;6D?B5ddo#X` zH)RZ?@lv!?e~T64DW`Fkc!0*U(6}c#)&PI}312_q886V!_|I^THY}#p`Ry#f4#?NO zfiZA_OIXCdk@Ms%^V|==iTywkWn3WsTiF-SCFNT2jXGru8%taLaOM~%@cS3&Z!x8v z%y6$hF4QLqTaV>$$!VRoKFiMn@=vV)8G4?u#SVI|aEuVbh~N}@t`J88Nu-fM7C979 zL-8 z!1mEuvwd=&*}gbiwmavDb8zB>*oG0oDWb3_Q?8&2op%eJgJ;;aVfhhl#+YF0wLdN} zHtOHTYZn$pa@UBGOL+Na=!?jjPw+r#n=yzNb)K8Cz%$i#T<9K6OUE0gDzn?U(jNfB#K?n{VK~ zzVtjOd?3H`^4DJbCS&W_RSRuzo<8L;+v?)OM0Ik&``|a#I z@+hE)5-bkY^{DS-06n96fyJTrb+5imSt`)q>9g?1y!G;Ww$;M`H<)7W9DfI|4TKRz z-l?;duC^tPsnca^q32vi&#LC0wb$;6cJhoJEY81^v2lS*G;oJG7ASoe`v;3d?ez@K zqDfiwJh1EK{V`YM_1r1%jjQKcTPUYFE%dx91+C%2%Wo;~^!0bs9{Rh5`rCqiq|1yC zJ!_I%9DUCl`kQ|idY+X<4jSi_w(4(TV;mYM>Wx#Uk6fVX^*^JH)Szco`dfn+u;AN? zqa3)k{f0bO*fEYAzr%Y9YS8aTTIhMhDfG`s80uXSinNhCbGyu?Hag36NlQX zP1V&+*;))J-(Uzouen5@ciO=|i)8)QMhhJiWu}6s3GiGPUzTL@tPoS z&vUYr^C-Zc-P9;s|69ryE6N*atcW+BK7Ta&Q1%h}oKprju+Xy&lcKE85$PF-h2?VO z@+hK&GODmp-P`K*d$vvJ^JV&ck%j;7yi`A&_YllsaYnh0@CnBc7J8P_K^Jg8vY^}J;K5!Aurfn0*Gmw5E@ALWQH$l?Nb*uuiE&%633ufF(EoG0j6PY)K#=^4-^uAn-5 z{-fW2wm7Hkx4Q{wcT0YTITq0GPp@DR4so0uJ*%3-Y?^)|}NgKRCzl)s?a~x1a6?#@=p?*Wx zPM=S+=#cB87f`Q03#d;5`{PciyT#PC3)3co(}4EpEYW98LvLMbb430aA=l=C z?FwtC?FeJsdi~Vao+H{i_1w|csJ2ts+O%B+^jAN>z27cLT>(e*jd}gkF0aoZ`1vaN z3nAa|+Uws(I{kQFpNK)9S4hDkL)la*OA|wnK0hiuSg4QMs-5aA@{|iGLiH2eVhX>V z>NL;(xaZ{b?=D@qdOdGl;|V)hgd*%0qKLynW&d-HX}&gN%C`uAg0+6_yWjqUZKvnM z7ii!b`kaTxzsDn<@C<*x9AD>AKoMnBP=m(1gvQf2b6D71SLB*#V}KiIy-Pe`1_xWmKT`^fABjz2bbEy*NnSB8zlyQMB^jzK| zO*?&-_0hFgz5Y$BTj&|Sh1z9ZyC=4)pTS~APUEPr==TCbNI?I7mxZ3~>)+WDeGVwb zvvqx@N1yxA=WkAMiWt(!qJ#=Muo%&I=K9C!n?OoqxX|wa*tq&Vfc^dza_7*z{_hFs zdH)Ri?Vp+J1^Ru2BkC=>tf_}SqMyn!#}F2Ny*_iK`U3Raz2&tVQ8&f}x0pe{L$JUS zkFfq}ub+Oepzg-fvw4dtWj%MlgFbs(L=*a5fjKPvcE{vT5JDJw7O#FaTtdI6u-|{l z_zzg&5%ygF-Dmo=xAFG-*<6}K|7MpyE1X6KTJJgPxPa!i@Ym+|)f)XiTC4WgVoq5W zc*Nk-c%Q^Arm*naEoo<=K5IOoMtl8!f{ihzJi&WoeY*8}oy+aX8X(C;Sb z^UGSx+s4^4?+(Yb(`Uu>nXm|=h$8`we}_31xW@xlc*2plF11ZTYso=tX`zh{v?lGJ zh1zQEYFkDHHTZqBFBUoGl01suy!!Xu&QOCs6J3Y?-L*@{`X7A;`-UR)Z>PN%l#g+O zFd{hA?l{JAK>|snP(m3MRB?tH>bO7yiO=MiAcrz6V$_L0UYf5hRL&ra9P%ij=p4Ct z+uV1w-Fm{_{BP^mrH{oGWoe=ViymWLeHP~w!_T%X*9Cd=LV1fFEG!qM-zn^~*H*93 z03OO0nWKaQKRGwH9goP~9EXm}34J11Igf0gF`@6wTbJ6{ z@6^Oyn+@9+?4Y)HnB(5-r?v^$8nsQs)~L2i*xIyR2lQ7zzrEisPu&?#>6`KT7hOKK zm%k+667n6teS&e&LK_|QV4=^hhCZKTh76|AXEiNm)ZZgUUcaMbvGMwydU^eRkB#T& zHSRsu@W)RwR}m%npL^BkTjd;GEb#z~E6Pn=<50bF3#iXCEC!TkxPv|;YoXr5`^6M=>CGUS$cCpv*imzK}qmTVKCZTWfc&j~1dX;`IOFoA@3Mk?XV;sH1 z`x8zOLKu23V3DD4sK3=;QfT5D9dyyd03*B?jJZFLJ%jM)yQ9M#3*2Lg2Ux5qJYtO( zBp5g4t@oU=T;j@Uvb{zN7IVs?=L;+6k?k5!u!w#L#})~soD5rw3gt6ALZ4^oUZ?%y@h@bub;2ia1Q&tfz|70?fP7Uejfj}cKU3> z07K|Gz!(!)v?#aH!Q0xcsBe52=Kurf8G`F@pa|HSv&OE zh$~Dn!x9$Hw37`&Sg;r?bh_UI^h~eANt(HBi7i$LeCo{f)uVDedeMK z3)PFBGrX-``XhMFA`g2Gpr84lL4Pa6LS;Q0xP<PVjc8wOgc*YAtAH{J(7J4>dVeOSSdCCRo z*@cDGX{&k*n@4T+tU|61)RzP5Z@e|0c>Sj2@36$$(Y{z{Urf~Nmk4qEkU|D}c5w|0 zeSL-+^i0EINqL1wJbC#D&nix#&y?u%F)8S|hy6_$>#wi%858Nj!q3}t5&v^28Y_<( z^o+#fh4NNk^E~1hVJE`&6j@xL0X+w?_+a|!Z^2n;96fW9pnSn=-=-}3+cqQUdC4)) zAoSd&g*Nn@#9~SP8u}YI&)DDvYF~Bj2VVO}>JGKH@nW=1B841^&}VooG`~Gt@yER+ z-@p~FVWBoR(DN35-7CJ9M;!Ar_X_mh)Yi&v7!ydOuHBUe5{SP<@+x@9&WIKJc+k z_t*cqG8haubo36Q20>gSf*>?Bhzf$xAQ%Lpp+OKt1>vTZR#Y$u(i#;N1X0ljL9V76 znldWdASK$+R8tM2P1~qvtutrey>?#L_xF3g&wjl=_s;vQwLfQ{efBwX=KKqy8_|at zMDRL91UU*23B=m!(KCt|Lol}~1Mtrx<`9brQ#hU14jBI%eFXJJ5o3sPgelCmwtP{X zd*?a*Dg@8no5Ja_ApSRcKI#@A5{P1iDa^IDd`+0%hv-M}nt~~u-Wmv zg)oJ=)|M|EMc*Sv5Iny>k67UUICtyeylpOG6bHLJ&l%YQ%ZK2(R8yis{iXF(FM_8S zQGzH%R3fSn)rcBI9ikq=bNr?x@Of!HUUR5GX#FI3ZS|Md)jCV(sq-yCzO}WH9`)(9 zhz@9`m}?omm^O&`qJA;`{r}a!lgKg6Jctn13q!BNu>MRC|Koashv)pwyCm!Jxfx+f z89rAcsu1dH0IRP9%xeN&2%gtBWdNTUgNPx-FoMqwn!?Xxhzw#JF@cywn6ik^A&fCz zC*XC4azq89648J#C4tW+h*HE-AD=6%L8!kO%xFQhBTPx-^8kY5xmd>Y0;ZYg3&S#< z*MYb$L)b33Z7l6;leZe4aRxkm7bv$GhAGr}%_oWIN0`FvJ1s$^@IRl!RGpt01BhV+ zulw+tk13qa7(%Q~XS>b&N!k8cEGL)MlzdDx*Nb>vXQ^I+X_W}R&n=BGC5g|CLA2xl z4utAGU`8)u05OQ*wINeDozah2n_i8+G0wE+a5DdcpUi3 z2GiD-Z)yE7=4GzA6yUQd)p4vR1ka;4AePo!+Ac3BJg?4o$WLI=v$Zu1D4}r61GQHl6FV z9(~(^VBd3WnE0YGGL7~zJmyE3F~f1AW2Xnq7($rB`PCuJJpQM#`2RYeTFl4fFzq#M zt7X!7DNw%*Stcwo>Yq9 zHKsIT48iM0({UU>%Xnb@S;QP-9>F}7h$;lHb1`2pq7TuJVBRnyg5djsmtMo-d@>00 zEHURdgP29kAxtSnTgnjS2wvmjI~y~Ial|BI1~H46Lo6Uds2fH^5K%-Nk&h@q6d`KS zmvxAGL?faF(TZq8bRgCgehwmErt=!Mj$7mBJ1{2^y#73cFlFKkrt{i#8KN9fg)pV` z3#P|$jVB+GK=dIph~j)xD?7c2(-0*HKC@hgFok|zCn`W4t!JJ`j$=ACQzH1Bi-;of zWICT2?ndz4yx|?N&UZq)R-zwwL0>1(r@KN&m@)w$pD*UKw)C6AYZPM$UPs6+z3higTZ{4>KRNQ zM@%555vK5S7`ga7Zimco_6w%-`RTR!qo`XHoIGa&h?Xr zh$DEN&J<2(m}`F2c`eVBB7Ck6qIt>mVsPmf=pC5OZFlK7FnI@|4NNla@*G$C3Lyq3vp zmZo&$b1$L~F(A`>zF<19Y4SSf()pX~pG&9LVY%uNe3!upVjRJJm?=hY#PnW7AEF;I zfEY&5@4=so(0VGbypq4jk70CZCldt)Dos6fo^gJmqi_ZMOoF}kmDp^eas0uxoUN$0w)&$%eKTL?<23dc^Tm;;WG(rszQAYlOry>$Vh*u@Fr{KY^dF)M zkwlon_eD=5W)SmBruTyxYtx4?o$r|*LGWGErqH`Kf8?v!P7xJ|YJ@4Ao*Ts4^gL*M zhjl(8fiQ*MwfP$`y$8{Y7(kf9>3oMbV{Lj1rne&65FH3p=v|w?wiMebq7KoC7(xsq zOlijF7DOvzZ91n7AO;bpF5jhXN;f{I5j_a?8GQ~P7K8AXpxDBA$z9MOZAMDQ6xUY|E5F8$AYY#7~$9>iD> zbNHVTMPD&^zYL$7HP619XHpxn{Cu})GlKoWXHpqOSU&z8JuYiH2>y+{=^!F#XOwLX zg7>>Hc<)LJA{E3S{%8LVBBl_<=wC)VVgNCRSO|jmWRwO`hyNM8ZzF}^v!0BZAb8)$ zA|i_ZVU!^FY^Le6IQlCeQH(IpVwU5x-uEzp{xHw}&f@bz&_BFSs0dMxs6cT1BoVa; z_FDr&`;G5m<#WA5h!MmnVhk~kF#S1&&tdc(pY_c}#1MIiI3gdx{_a5kq!3+*UWq<@ zX8-YCnp{K_5l7?)k--0^UrX@07GdtSX~gFygt=db{T@a?L=d?M_ESL+3H-19WyV`2 zK2#%W5J|)cVhk~km_V3PhYt;iMnpSe5;23AMR*vCyvM8*VG5a%he*iuMtnB+j+uML z1~F{}F@*@BFY6H;w;_zLY6S1OGNl6^ZVzdM)-(DnrY{7+T$-Z`{bLI6IpY|i&auvU zsLpL_sopB>sD<8u;Qp*5h<^M(fM7l5Q~w~Q@qV+BFVN{{nC;B8vm7576$q}YDnwHd z^Z1|p`Y@K4eO--UpAI2Re?s<)sl)%d-pb*r4E!nlZ^{rpFh&s^2N?wYrYyqC@UR>q zgn7>2=w+DJis1cq?FjDA!&ncdupih5Wtdha(~YkGS1-#pEQbROrG5<~0ZPXj&L-+x z!y#X9KFZY3uDF_a4P%2td7lkL$?>uSqx>$zVSjp0w_)sjP{!9VHYSu1ce*G!-bVia zxobG$^BflzCCA&?|G(u+!|6j9)m-`$&KKlbA$IJCOZw+T}q?kUnIH-@C8&GD} z@Rxj^UBgkI=hpD%KARs9Io_9j?mf%oTj6tjD;$)fzL9);JlQ<__I28~gh=)4$j| z`kYy!oAtp5$C=Oc4{wAxHOR#OI6vl}l=@EyuY>i?`U|4dZ^ny<@j^D^fj4zM4>rZ* zj|Ah%_^X5QLjM-oq3l;N%ip%#{IFi`=Z}oVf|MJ3JHb!p_RRL}51s_aFht2GfQQfD z!ha_^`66&#Y74J2(78ObFWY=<|Ge;b;3sqBu|D_F;a6h*NGAUj90Ql&fATNze^n;t ze?O3!zwT9=pWMxtG5RIDJPk|qncrGJ+vB}v`M1bV=9b9()8GhrGGOMP5A%D7*~)L@vN|&Tk8F{y6F*k6FI_*KPY)zeIQk_{q8AFaDkDuMplHezNAT z_`T~-3YWo8=J$kYPwj;3ZxTKdesaF}+um^fUBXHD$$8>Wzv=o1gwKVa92fu4Tdsdx z_}lQ4wLMdluHWo$`SNdmCzH7+=kl_@7sP)nbg~&A_ku%zK>y=^(?1JuyZNKhMog?_O1f7b`DKP_AWKiRC` zgTcMRM}qso{Dw30pOX4qKhwe|!A~xb{s{9X7{6r4Pek}C_!ne^6cE-zx zu0JOHF#Kd5W104c=3IZC@H6m}%kaPPmw)2=lfo~-N7nHb`qcHugyHY52tT<<{AHqZeU%IU1AcP7w5M~;4Nckg)hE0T4hhLE(x2Xc z-1Za*^S2zC$JVC(`TmVz91z+3MZ$c?6Pe3x{PUl?`E%DiD88}(`;go#%iAkDmv>Nj zXXGcVziOE|F3Yy3R=5~`a;fA`iO&4p!Uw=lZWDiW9XEemxB`CiqWB{@u0K!s8}O4C z#2*g1{-`j|PmqVC{|DD~{Tbo2;3tnr{`U1;e@gf~_{rKoqoT8aGQ!Qw5AKxw)$6Mz*P^_L0X13$T5+MgDk%iAmb zF#Kd)zg-)-`Fn&1;U{Ng`>Nf<^*0Is27dC4_=`7n{Yl|J!cW%q)hRmL-zEGJ{N!O- z-tx_C{`K*bFh73_|F<-^SJtl)eJkkXeyKk%I{o1<*?hagPuAl%FKTuAW5QpDpWG(- zJ4L6zTQ~_nc}DzAo4fhjgwKbcY>u~UP_O69u760F&z+IgKe@v7&kO$;esaHTpQ$Ze ze~<7(@RN0W7~azLj|mUMPsVEW_opv{GvG;?Uw58czfbrz_{lvwzP54wRlqs^Zhy{I@>cRd;pGcG#YGb`Kr1R)5Q3ZvGD8o8c$7NP8AVXa4Zvw*KAlljDK^L2!Za0Js9I z>$CC*Tc7!Agjd5)P6zq8Kc5wy{srN2_{r+;sC4sp3G=yWvicK8y8aU358)@Pe@t|? zXF~W>_{m-Jd#3srH-Dq>=kSwxPTy?5J=Ly%SU4QU`9^TD_-9UV{qw@x!cQKQ?W5;J z*WV|+AN*u<{BS6^AIxhVrhUaHyYR+#v1mJ>T{7{BX8p&)3df zVA&tf!aqm81#m+0g)emd`NE^{lePawE^_@7!mq+lo+ccfwP>>XTdr{ZUBaKhPcD-F?!VIYj|zuyNr~Jp{Zn$a>#q`C0Y6!fXD6?5{qw?c z_{kHJzi*Z69~0ggesY_%zw*1Tze;!?wg;@+7V3{uD?b2a`?$J*a4aG zS($SEyuPB_Q}1n-*&qGF*C8KSw~u6(>#q~O6MnM#bMJKhG2utxC!6D^U$Xt+JXzk( zZnu7y@bBO!SIP2@q+S1v@L%937q4skXZAkVpZ62XAHz>BlkK5_S^+N`hUM_hkOnDUFM*#tAnR*n%=J$RUj;vz*M&^~)V|{S8-%ZepIn0D8sl&J zo$K!rPQg#s--GRMxc+Y8H2h@VFJkhSPrCjp;a>R3rLunO-gW&Q!UOP=`3@tKzvO+_ zUn~3z_{lsDHU7E3x&Go0Esw!Z?vVVckFCz}Gc5c%{AAwGvnKyPU4L}J@)Z1Jo`*O7 z#s65H`QwY0KY*Vc7k{y5?o-H~Unvuwhu>%QhnDz-Kc^pDF6}Sd!1cEY^W8P%DfKUR z{dK~*@RKX0J)K{2{r$pQz)#limsUPR?3e8Fb_s6}KUw!bQ5B%h5*&l{>bp83l2f|NQ|IALVKU`p$?-L@ce{5%~b3Dun9}hoS{r$VR{){kx zpA{usy;zufi!kTcDolM;nEIG7_4-0Lf2;86XfL@+`fqqQ*PjtSAAYi)Pn{`p{R_h1 zhM&y)9nJbID0cnj!fo)Awf{nUyZ!>KW0v_I@jNfFx%U9qN{faQy)6X)oV_% zOugm;mj@5B_qU9pJu~Hn{{0BcaR1Re;M5_OKL(c^R_HY&5A|gcZ2w?%kI$QehrzLc zw*^mt@w3F&cLz^_c|Qy59|)cY<3FE|;fKR*{nNoQu*rWRxIp+Ca0%GtzX@C>_3r`K zi2fM37L5P=`K`u>2C&KhD!4`TcfswVe+2FVCxZIRa7*2Y@TTB7slP3F5p4QncX0Fw zS$=SV@G;<0FlOVo?{sj5=of;MV6(i}fa}D66Sz_M9&iiT%>OZPO6so$cZ1g~Ke$i$ zUGR|jKLU>kFT*W_W5Sz)$Az~APlC<*p*uUY@#Me!d44prLaI~^PWoAzA@&J+C_ zaK7j_fs4T=|2^Oeu$lj3;A*MA8k`h<6yhw$#; zl<}|hK3}BHw709ZwoFJ-W^;HK0FxThk!f58{+$h`-9`b-A5Jr_XU#q z_hBZFF7);d{NDw~stUaW1HK!a1fLb~Q{WNsIRW$Ur4$`g=zTL_z6-4jTodqyxTSRt z{PTdf1@|6X=-m-;3Ap?lh5q$5w&z%IKe#r~8^F2Mh2FYB`&+@W;|e`I2IVi$?cgeK zL%-(>@~#|L~T zxCvYxa36RSyj9S?=fKma7kb|f^w+=*XV~@o9=Q3;Lhsx_U!Wgs+Pe{MA+Ey1<`)F| zSHQ#Is(|@Uv)r=^y$b`b0Jnin{Zqkn;AEg*46Z!8(7zvp{q=p;|E3)uKLWRaD+B*y z;8F0`0v-W}>kGXj0)8D_4gOQGynh3ioLlHE4|sj-cq+bC=zSdcw*;3q*#0jB_kvA( z%fQj|3cV8oKi@~zAY2O`0WaeB8Qb3o9&SYYgZW(pPFz&zJst2};F*gHJ>F+W|HI&k zOKtx@3!c8L(ECj=zgNHm&4u3k0lx$8zP!*s|HAqog1v7SdOr*F&%uM>9|pV}w{+KB zVf$wra1Z!r!TgKB$*T&zb%OSlforcW^ll2c3OwIxm;W?y#F#w$R%w@Lvti zUuEa_18^hwz@R?f`!fFyCR-++OJ25cJ1U;PCZ@-nGH}Pp7}5(7)d2 zuU~NV2D^P;3!VlK1^!#W=^G2Zp9J~u1y^(ydR+lO4xR!Z6Y#IV#WxjtWdToso4}_8 z{8#We*laKV1sC0HmzVE#YXO__za4lKY_^X*!Qop9y~Bch<=|?tncp|SDe(S*UI!ir z?-TH4;0Rvu@aurT2c7^Q8}MD=#I3ge!{7$6>F?*j!(g+#uYset+4VCGt^^+tymeSC3_gH8Ll0LO2)+w(5qqOL;kM}dETa0dKDz$b#+@38CR68i5f^zRSi`n(?8 z0KPTwKLiflWtVpZoDs&Yzg~BDq4%r6|8H>J4-5VKf0%CtPBlb-ROp=+=q2DL;S<5* zV6%U%2bbNA@6TZT@l<=uJ%!#~`2EFvJoOs85923bo+|9`E%fhipuQU1{Xn7j(_ntD zf~y|1+Y3+i41&Le-&^#51Ri_TZokX$Q=_xL&^tL8zng()AG5qYxZ?3b@5CVgp5Pwv z!2y?pXTX&~{c3RW6NTQN13nv^_wz#U#egrPf3T2$Cf0Ay4dBuz?RdTy+zviF(0>Y^ z1GfhCp9eQSjqm@UzsA9lXA8ai0{#jS=le(>wT`urid z`8S3B^=hu4N9cbU>nm8^XTb%p*zb3~f2|eV8sz&U*vk}pm*IR6>wf}n9xwF%5a>C1 z*q^>$=V~M4`v$9_Zf=T>Ylqe)k2Zz^?@Lj|SJhh2zh_ebKCb(SNbW#FyBN$B|j?*eWW-WS{>d?)H9wf=h+}4Xy=a_4~`e5gwVU6MYMC zyYNonKH>`PXa76W|GOI#|Asz|9-m{#<_>9AAR7$IC1Hzv~l<@8v&#%KAG%ZvvMF_4fu> zZ(`fe_oy|4&H6cs`9!Y=_X=MM9usZ@&k5fQjxOIT_v-JI8-ke9ifCu<^5ghj0#dTsMGuJVpQ3;A1Yx@m2<00{#nhjxUoh z_Dwfmp77D|Zw(ambC+f7Ujjbm9NWI{fS&}{1^Ipq z-um1e@4o>*MgCUKn&&Tn2R;Pc7U&;>UljIs@Vq1OvWFi9`X=DNfe#4yE8tzv%kka} zct7w4=jZtEQ(=Fc3ceEkb$p;-34R@%2$!k>WWW8q(h7fq{@odT zYZK-d@B!pYa-92LW0$(^$rC;X{;k2KLH)DACtjB0@sWGZ|0?hU%{g92(B7NCdtGkV z2m5CLoGsb@85F)B{wKkqp#Ey`Gs3?EuLhg-%Y0?ucJq}BPs4u*7@M8nKKjQ+XMax! z^KXp30oL)`eubOALwKW|uswlmg5}>1{9a3rf4su}I23%`l{uJqcK)Ywp`zt>I%=hdzB_n&0;Z-4N92L2wp1Ufl; zK6-_(mj>@^;P>Cv(8*k0e*fJME)!H)1>$mp~Tc7P25MBqV$lbEM<=w8oN|^2GyxY}N!qnqGcJ(r0>g~d8Pp>fb z`g`5_?ZVV2f8y%i{g$bB_F88ClrZ%sJd??-%y_QgsL6)EoL;y;+!g^JA{wCQN-wn9DycOnu=A zxBjBApZ{mB-X%;uH00_DVd`_jod2RQ_10(I`W?d5dxu?pM3}nwysJlqsdxRt)w_kM zcZ|4tr!e)zFRi|n*_1Ke?2krI;ogpAV{d2ZWd6P}+w;8WT>b^&68OoHVE=L`ICNUb zd46~VoGsb$H7a~O=Lb#%^E(?n57y)5+B7EmWx01TJ{Hu5);w?O_YXK*viT=u|9KVs z8lQFdul@Jh{9L|n$=3mi%y+4o{wP1konK0r@3SS>2L166c>dgwb3EAiEw_Hl z5^i47zS#3_dpj<0>-Pz>Kc5sZATz|bV z^Ysa{J^jMeXN9TH2~!WX*!<){SzixalI860@#S7S4jgBoo9kut*WAO=#InNs71~eE z9xtr$-T)W>xOmO)`9FgPz-hSo`=9TMt^-#E%zU+Sys)Y)%WNT!7gnGlb#lCL+i@5O zK{4A~@!RVLQ#STC*ahvKdtLLpPB!T^|OBx!iDgYyMy`%fJea?u718N zU&i+XxKhS{j1TGhWn=Gf&L87zG8nJSpC|fF$1n4_9@E*rZ@}LMJr?j;;BIhkz!!o0 zz)b-+qJA99GaNAUbAH*9J)Rq#w(X%lCcFyy$Spzp*#D*PTmLQ4>t9&ME0^V~dKxRu zFWL7URfwPU!+*B*Ilo+CzDu91_sd5A>iYA9e-1x+4gSAo+Ttmiy`GzZR>Z2Q6+T4wvpHnMyR>gSHE z7Uq_-26qtkzH{-4qlM_@u=%B z5dJG(I7jXh|A6T1&tc(Vd>@bt0{=L+ml<%S)GylHonNu=ZI~a~?BBWm(xP*Iy~3Aa z`z4353o-rMy``JKUpNo#A-8FJ_!0%bWc#;Rcysg@S=Wb`=la9KJHb!pJ9|xg+T+$= z483o39six1)cx@&JHLeZ4@P^) zdVV0aqnj@+d=KXj*71QC-$^U>cdybSA~tp3zE5Z6C1%;igd-PLP_sW%C8`CEjkPYF|>7N$OM zgquIV(lYhDBQ3LjfiU%vqg{Pen0oGUt{xMnp5RMR{E}TCWx~|!Yh1lanEISB+qWo8 zedI*9{A%z97u`d#AX19bekwmu&quVb)K7)76KCsSlpx z>Z8KcC(d>CY2lkO-pDiZ{m{q3=a+1I#)SQR7rFYhF!kmuT)kbGdgoQH-XrYSzt+{e zgzrXs$<4@PwvX^C*PkoQd`;K6dRq8lTzM}b+@~EgD~~QZdcFyp=Ii6Va~rtnEJFZ z^%-I6H9xZXs3(P~_uTF3{le4}_qckAF!k=AxcZPV^`c%^FBhiXFU*)b=Z|K=XqKPvE^yv2aXl%>&+|>CFWBXYzl8RH zw+j4!g1;SnTfn=aeQ}(0GRsrJ_Jex^9gjMA(b1LO69Hcg9s{2fFm46+N?u&K=6+4w zTI;32mj*ifKXpHUy|S$EaBHg1c_5y@+UulcUf*N({MIj^Pl9>;@1Nf~ahVr-+@24^ zt&v{nr^x3o?+OpM8hUdNTKyyNqHqi=GW?L$SAwI$hk@h5XM^Yai~aXMa{k{2w@G_` zj`oZ|&yJTB-i^?^!KS@E&>KX*5BgZ2oj?E1Rk`>(;m-%hgXMh%{{0*XW`I{PeX35`un(I#sKLtN|2tV0Of0dl!`jf(A@RR$ce-}mP`iz`u>%R{_ zc}jji4xMdv`e%ig?Vja%Ier@FLtTE!9zRV9bA8SVGvAyr^+jRo-g!13^*mwfabfE9 z!qgjusYlMY`Kad!Q*RKa-Xu)DRhW94F!d>6>T|->i!N~IUnWewOPKY$h5h`()MtgM zS2eo%lfu+nFLd<|Vd^~>x%z-G^|p&$Jta&%+T`ka!qm%z+5QS)>ea&3YlNvc2vcto zrXIS)oqtrAdP11>i-f6{3;XR8rapPCn?HY*W$JCWSZ4ipVP8+VdZ#e;-dkOLK$!Z7 zF!PTJQ=br~J}FFnR+##nFm>-Xcm5$^>QQ0Vj|o#R7p7hzOnqLM`l2xPN=-{s~nmh)fKL%(s)hjqSUnfkz+mYF~QEz8t%-?QxN!qf{s zbM-D^>NDG5=j)g3@)yS~Q%@aenfdb$vP?a3hGptwOSnjupZ*46`dfvm7v16ZSD7&N zNnzHX5vCry)7B?f%J=!^yJtCjJe0kkDfeT0JQ;@`1)JlgeZXbUL;eUWTgg4p)`)}cG!9BuzgZqWqALIYD$A5=IC!6E9 zA9(c|E9^?FyqW7RaneX8=^P7s>`t;{+Ynl0?+gYX_6Q&;D-qj0)saFfL zetVtWKB#vKQ?C)fudj6Tr-iA9cX9QIF!j!atEYsi=k4n1`NGu4gxS7~F!h$*-1_ap z)CYxGe?*viw8*WWCrrIonDy(0sfTuV>*oqnuMuYbI$`RA!hZXN{rT_V=5G|H9^KQ` z3xuh6@u7FWWcQ~%!qjv3a`k*+>O;bQ`-G|2?CsXC7p7jepR3mjQ=ckz^*Leci341{ zSeSa1FxyuxOnu^OZv8o7>b(cL`iL;~v4dTGL74jDA+DbHb<5Q2_>uv?Wc$BEn0o2q zu3jljz2!((?-r&$bCj#k3RAB++STiYsSj4U`h+m`q7z-cPMG@08LmDjOnv4|SDzK8 zK3?bQ6T;LJXSsT@Fm>;2tCL6fu-^~QVt-3E-><&`kAn||&)lEf`HB6${WEm3`M&)O z+%3G(o)|B}Uj`2dC&0ttTtEK`uN+)7Z_lTk3eJfCT=1lD8+b zjp%GopWGkL`gNl3j{1g8{dUn0gR*f5%cdSH-Asi^Swo^B#b1is`SCU)t~2pFt;^^BXUL`(McM#)I=6li;>d z`#i^o;Mj}sBPrXn4383bg7yB3iI;4CF3+Se9-Z_#5!7dU<4Fu+zbyB5fFAyJj&r>u zIp*f87v|qzCs&}p>7QQFIsbm)qv0n{$oZU>m)-pB!e_uw*7uwCXRM#?Fa4o=JT)l# z1*lKvEm5X@-M_Q-*}ehctKlc>^B=vxcl|@ccfe0>ljTXg;rh#j`{5^dh=1r!>wgA% z^v~#jOk#W4zA@2Xgifx*0kBz~$UC+^{YAp>!%sH%^L)nnPoY2IGxZz5*^-@Kqi_^M znQX?}&fpnvDyY97xaD2@e9qC}ia%QaS>R#tsLZeVPwxEMg|CL6JRtspY1dyW%)c#9 zZWsTM=S9DZ`EK2C)Y{-3DMb}DdA@L$&2D2opswYDSRvZsJf^41V&I%rE}2>n|359)5C#>>rvxas4gAuftDX2=c!NZko^W zX65&4%|G4xwZi{^pFAz|EBlx0FBjgl1m_FDxst!?Kd!%8cxU*@;lRH?IQbct4^_-~ z==OijV*!HwU61f_@RO6$zPV-m_0N(Wj~@T%onJQg&Vrw8`mY6Ckz=_N+!+e3`TH^V zfRpQ4ega&8KXTq1wD%=&W<$$wgPS+T`~v+W@^Z`T?+e}(&sPNP-5Ol_B|Hxi_=~{( zn_E5zoXjF25vJZP z%=YvNQ_qdN_2a_S+k{y^B}~0`Tep6rF!hq{T)je=dUShN&ljeim+$HcVe0e3Y+q;x z>!&^@Onp+AdgG4PPrX%``m`|hd12}`JGu4ig{hAgxOzsIdM^KHqF=JxLrj=@l`!XD zBTT(rn0lu$^_G3z{Jr~Grk*(5GV50zVVU}XF!e!U>T^fA{-hkw)nUAo&F`~|!S&!R zQIEgRt_8P&j}4gl3cks2Q3Dtq zL2xtXXZSgA^6p}`vEfGJk+lW+B*#%J>S;<9NaAa<)v63 z;JU!S4Y&$i5O5*5zR}h{09uHp6h2d zIR7%MzX4tl{tI}l+3Jhn#&27W;KrD!jE6Y568X*g+Y4NCwe=qXPPAG+1MFR6xdl8f zd=t3$TB|<@Zdqmd8E{pb<=4RTGG5;YkABzcpMtxuvmC~YCK}r1(P^aqxo2j|{s`3>;2@Eo}PCabUiHEcgOTaJT^ zZn1m-IFz!S1WyPzgZpl^`i-w&)`C;HFJvYe0U=J=>pbo$$ce+568-w(#$ zDLVZr;SBubaNz$VxEmY|nCC0=fEsiW4dW? z*)guaTzGT%$=aVaqBDO|nC+btroJdlz4JJCe*MDKM~-*(j4<`&39eozOugwuSML<2 zUURam*9lV}7iRmXg{gNX-TDK<)cfT5X>vEdPqSr(w;lSEY>p@P0QU-i9Xud>0(e;X z9PmQA*sDcCem}IZKG=M}-3;yqoBTfpn_{-Nh&*rmD0K1=OdJn0UtQ*Tx8U~-7Lhy; zo_iwXP2(0(GhXs~?D?|iP=6Hl+k@W|uYhab!tbpwTYvG@w!dD7-uaciz1rOD{)GKo zCHfR}GGu>#AAoDYRoGz6{8QK2e5~Iu{2Bb@$)G;_zv5Bb-t`Z{`PlZ5^L$AC_uPEV z!e54;9FpIgW1{=xLzwgHx!%n;BuqWr;p%Z=>czs$UnxwzL6~}r@J?tixqX@KubCU% z`GtO9c|Z8c<>F7=Xm#eV5Izik@}Ts`?9Hy9<0o6P&;JhIZkhSUgpWZ!^0dr9b%*Qk z7d{()@(e6yJhc4C^>+zh3_p2H@>ix^f1U7^@RQXa`?2dU67GPX+$iUVJMVY>Y2n-9 zC+DFbO#25#Xa5Wd-vd8c{o|t3KOy`O{N$;PZT>X2-)zbLz8e%CfS;`SGomy9xNru3 zvifI5r=R-^Ge3^k;UUX@KH*vB1M~0tnEn|0mFu4tjvS2rF}MzSjlX=<^;ZaQ4?nql zGwY8|xc(C1BKSMrgkSQHfwLvse;MHt_{r+e#r{wIQQ-sOC#%0&boLMTpQb+hZ{W|C zsgDUCj(h_jVSA9}D_DlX=$CAJn}nIKb6r>O6{bG9o~thi`}O%p;r)`$pBAP*&xb)p zk8EI>dhteo(`BwdbfD$m!%vgp51{&=l)^%`O7rANDZ zxiIybV_m&on0n`NuAUaAzIcMGM{6ukVR^~s`huVDM5}XodxU4FT+{)Z5Q<^|bH;mWRy0KVim46Tgi85{y4#=BvHT z)fRv)^|8@hdDd-@GvUJKW;xtyfv5-X+ZX3s<{(wAC{8_%)VUzgU=h z*|n~o6sBIZ%GJw-sZX}K`iwC3k?*+rgfR8!_gy_MOg(jjt9J|g^S{y67lf(j-R$bc z!qjV0uHGn2z2jC_PYY8Yx!u(#g{e1mxq728^`<*qy;+!g`TpJ&0RQ9|62I1}CCzs0iU-~iE-z&`d=Rf7@)xx_VA9+CX%{=Y;!$X#t zujLub9M9dt)HA}=$AzhfpLOd;gsDegcJ(4*>a!EBp8JO7y|FyxX4#)Kzh!l{r(Kx& zLX)l@5vJbr2Ui~wre5^6)yYHhd-XuHhaAUrUazPEPYQnvya?v+W$IUeBmI`I2j_va z=L42|cYzDQ-wpf^f&0OyVtHAA0G#{yN{_e5lV1WC{cNSTLBMZ=OP@r3tZ(Z723J0{ z(z`mymwO0~Pr+Xect>y;?>jQjcb0;Sz+VY;E^qa{_Wa24&@=bh=LgRMkNm`*pS%cM z3$F9)ukfw{=l2w^dB1!IxB_g>e{_MXh3{c~@jnV~!~F7te9wS;!P)*?;r$vs2#y6h z+gp$Gnb{Ka-h$o;F7W#!=KUSqmAAK-^8GPyy|3eZ`qq}W0uO^TfnESM#hjn1k>_vs zfljW6iQh+uus*mnV76yL{N&m;d%lC?by4)=QJ-8V+iS(o)`N>B`+Zp}d>;H{_6O(R z4sHaqf5~@%TSR{V+yO2M^vA(N;MsuLzMh}2hkseJ^XnBJhMznP)qMZf47&b$;aA}& zH;R8ubT0pd@LTYc7sNmGq?{>am=KPJ3AZWJXK%lar8 za{ZOU2f|O*`x!c)as9o*?C(ioe>@0N?|;s%KOsy#ci7d7gsIQ2cJ=7;6!dr3fW4l0E_eZY0qXJm z>t*0L^yYxuz*Er8{-+x}E6n+|?{4=WtIDz*^6O{cFW3Ry@S~`2irGK3N_!vq)bq$@ zeBKS719zg5*?y{jZTAPyB46vsdd~UL>R-D3mlS>-esV(cwTjOEY!`kPesW00bK47U z{tn?e_{sWv#2dAK_E%HJwx9FM6Fpp!<&4a4{6$-z{#oG|{A7JUas8Or-Z3@2~*E|&&^*fOg+7X+hlz2iSb6x?mw1$2ZKAoEvU!iE!H2z{w7;i zcqc(8oBhrC;1S_#z!~8#@TBk~;2GiP!Si5qJd^>)p0N3+!TG}fB>&v*AJ@Z+Fv`IN zetTDVn}a>vq;A@`GdLn#2960=gY$*!!9~K?us-sed@0r!X8&}`{#O=N zZoWEU>fQ&g9ulTrC(Qiy!qhXu)W?OXSN+w^UoA|%an{wFg{hATGyjAz^@r-iA{2vZ;Whg*MKnEJ%OTs`z}%hY@R zW10B}g#G%$)Te~0S1-Etlfu-!&s;rMnEL#Gm*}5crrsm$w@;XQ=Q``-UzXtai7@qn z99JI_rk-BU)%%30S8eF(wZhaJHgfeAVd@Jwjb^*Lec(al}GK$!ZpF#CT_n0mnqw|=QG^-#>!bA_qrZt3dz!qhudm{kdPe<}Qn>)P-0>Al?kFWKAjN$`_9 z~BsWA0)g{zMWQ=by{^9xh2Kf9(&#n0mc1>o*8fZxyEACQQ9Y zn0l`;^*Lec^TO2gk8;~rAWXefnDxtqsdoue?-r&$DNKDzn0owZcmDap)XRlgze1RL zr!e)DF!d2(>Z8KcCx!j?2~(dHramW3y{XD=f2%O{bhXu^*gi{6THmV-_8-hQFZvG9 z$WRK@KKf`QK^C^~@uT8iN`N)fyZuXDOr&>Sj=ga>7 zSomv)ii5x3p8fk{v8U|!;c3u)#{QY#XXlXNk01~Ea&SJF-#_FwaEb8s;7Z|J!M)(@ z@7wJBQu6!ve&}TL`}b*Zm+;D1VEBrCIPk56fvHuX> z0X!hQ57-p*ecdYkc^GtZ3?}w>65Iu5`^guAyTSPZv;T*rKG)x{@GAJp=KGv}eO{g1 z^uGPRz6Jhq_@^=5tna?l?D}T@LE(GgC!6oH$HDVpu5nX8UhCE`5FUY_Y`#y~o{Z?6 z-?T9Gn$z8UNnz>(!mK|kOg(&ttxs;2<^L_(L*{fI@6CWS;OheB^dXG5Y+2#`8~V^Q z#s2XV$Ll6X;rJR{fdq5|f z?Ws7^U7i~LksrTg--lTx`U$8{o`G)GPomD&XMdFle-nPP9^aIG)A~98mKk?`6{25` z`eZ#Gn>okU=lr~LEw6%~tk>sizh!m$>x6HIpPaySvpgN5)88pv4nMh7{E-GXf39#3 z{65S6G<3ldzi^U%aGsoxk2kvhgz!({C+Ca5;zHM7CHxHhWOKa!61YbAb#N`1*JIfq ze+9Q+WXH?Dz)crp|045iZF1+=A^aKqn|g`Bm87t-}9o=zbL#H{A6uU<}$ZEyHbc1V6c1+TSTU z+tVd{7X0K!$-nq*H-GpF%jdyQHvQ8Kt_9cP3&FIn|7z=}uT8eccKFFVVmkL{eBX2* zc&C8*zUgr=9%J|QTj7uVWu?~;aN);TKVaVErV))pw(RgWs=>;Q80F|B&C83$3>QxxT$?EMLj_ zfz9^%9dH?_4Lw0}5`opu9?}fht{t59%SGoD)!as$d zTom}90at;|_s@&qHn83=9R1Fce8O)sADI1b+FKwxmoFh)JD25L@t25Bf2r_$$WLwx z{GWpR!TGX(&a}Jj8y8-748}XSK>TypyZ%MtT=>a7vc0BmaQ$iFt>7m&%JPJN;QDig z^Wi7!{=eWx*Iz7L1V6c2+SA(U`rCyMhMydl_VkF({_Pb$5`J=*jPJxPZvHaiB>d!B zX-_KU`qRRjV8bHo`-|#sbN$W2b;wVS$o{V7PS@Wid?VvY_U@PL?EvTu0JY#7yM*BpHea6`fG%H;U^DB|1AE>^+!f6zW_hEMcUu^lGVAs+J%1$KiRx5 zhuc@|H?F@(_z&=t_4%Om%dWpycpiRom7IT{dCm1N2E*zfO36_{jy5ze{ws zr(c-ujZC`v@`b6l{K3^bgsB(2?dl0(>SMy3e@2*k;vKhsi7@pxVb<>yrd~Pa)~^w! z-t(@j4+>Ln{G+S43R52x=KP0*sn<=r^_zsLFTCgKx$j%1UcZEAm_XwDOA1L~fWl1D_i3y4Cpo1;&5Az8oJ)K3?fEUbC&(HNygx_b`vclU3`t%F-_uIDMkx~2m?FewwukiZ}`)8gX+Z~+x zrS%^I&PV-WB&2=zn16PCXU_)@;{0p2 z#JmTglW{nS`Z4cGuqpgK=#N({Z?dvdi`H*eR9>jyS`dPKYbG89b7K+ zADp%InSWTA`C2}7^-f{xxpS@_6{eo}$kj`Psn^WAdYv%!*?+rw_&=7HABXb?U>zTe zqG$8l{^0gqgZ|kGdAUE@8ueSj8~NMga&O})jJHqi{)+YUUM$AHEGxW?{)FRgu-Tq= zL;ZZbWVZ?`x4-?t<-fM~C$RpIY;Q+FC!6i_g*pZWSH<0`h*WV+|bb(yyOz89kTCV;&0M`hn0jUj z4@iHGVfo0L!N>9T4*Lg;=KK72@HlwWfY&)5=ObnOM8UZW_WobauMT>)tnl)oles_T z_}c^AC|m(<0p|z$@!+)R=YdTz<8M-y=L+a#-Cu>HZhypte*iz34zB+@!EtbHz`fvB za4g`b!Cl~{fL{VfHn%)UKe!^$KLC${xjf9j0GIxA$<|%^w$LeeUyo3r|f37gw zo!r^g8-%G3t#tK_@J}&6@~kZX;4ZFzNcdU!$rUo*780&Mw5#Qp;3tRi1!VenuE^@_ zugLC}+1^rN>Se;zyM?Lu3j6vVHlMEx`}$t4o))G)w~wnY3R7R)*VRM&S*G4uYMJv- z3savuz}4r3saJf>)hmUmXO?i8>~DCziLBR~>cQstgTF62!TTT&zaQSf`WXeA=V3nu z&wzP+Lw!BWaQ5H!_tO^OqW`S)Rt5F__F(^>Ei1ePCWK$MzdsHD5B^2nhrmxBkok{@&iQAAtKlaPi@)tqH-D$_ zH{mC1{*nsUUoLz({N$A69}}JJnGo)PpRE4c!`%E0!aszcToB}c6r2K=%K5~hqulx# z;iupy*Gv0~k9Pef!Y{y2u9f|JiZ8$OOLjbU3I85`a` zbMxg1e+_mL`+z)z-w%Qp?41e@cJ1@LGC z_6LE!J~p8G^TPi5HTpLP4}t4se$n&Y`Nf3`;3xNse@OIV=wmlv{RjIWpqCN-r026d zFZBm6aOXE7{52%-S^BTPafx5}DEi4VzI!hgKlIw$H&`?N*uD|b8(1Hlk@j^oNqtOD z3Aeyct``5K=*&MOd>tl`&G_W^OVuTA{-kg>{Nw@2zbHEM=U!^-KY|Hlvwq&h_#Orq z$@jr*v-Pw7obVpCSuT+IMK5>#G2sy;ASY%0)P39aHwkljQ&+fpx9~XfkxhTT4W0wn zNc$64x%DfAXW=Igi+`cj^@p#qyk3&`uVB2&{&Tj?>PY8BzGHa>{NzdLpDEGlpAp^- ze)6dJ`@U=Q(cdq8*XhfA*8Neq-Sy`SAA$U2eO`X%d#-<8_&E5<#j?KguXp`CKFXHt z{RSay&xYCFT;Vg3k359w=KE(@bo#kJ$d+ur-Wx4b&j??FeB@3{H~A_$U4O0cb?}o1 z#qZtZ`eVYk!cR_#KP5Wb(#LaI0a^Z*IC#!!%bmpHF{u%sa^(Sv}^EU~v zhM%nddC{3alCt&3;3uoULv;Fkgnth|xlG2#=&d#%{nNtJ@RRlTd(CaGzft%T_{r_E zy^Y`L`WJ+GVT-K(t-2@RQpm|I~x7Km3qouFv*9%gom!OuhGESML{o1@j~8`mTP& z^(Tdyul7+_uNU^`_qf$3k-rPS=lO$;*9Y0YA<^lt7_@%swZhcPhg`i<_%Fy$o`BDc z*Vr?zKVNtqT<9h1_j$u}uD?aN2Kx*0q^yss)vmurnC%V!!qp?f)RQl`dc839Az}8% zsPN`!fA9DP-jMuW4FAr}S1ZhXlOMWz{@*Qc$Nm88^_||2tj_uO3GWF%IZx)F{)g)y z6+Re#axwC7{hSD11nd1*kp;JYRJaX(a+maf*S}nUpKvGJ2QHT5ud)BQ{wZPhPyJ`E z-X#1Z!4y zj;96Tt>7m|<@ZvE7w7yE^q26i%n#Pzboqc`-Q9ECpU>dH|F~D zg-?f{tofU^a{V2`7r{@~{Ig$i{oXc~zYjlI^H*(Wb@peya5wy9%|E(>>z@>U2!68W zPweda%Y~nUpRD&Lmyb*^*zaidS`{HcYupDlhBeOl*l-r4rs#c!ie>->|u+Wx$F8hu*luiC@*>&1(z zalZ)b{DXVh{+M_L`gFCN|JnQ4eptLU`m}z&G+JW&6XG@K(|Ugs+t>Dc#Kq{-wX!|) z``LcR{?29S)3Ynw>uK}|m-Bo}J<|C^^izL|zRW*;tjpP-7oUkft^J8A+n*6Pqfcvp z^myB!6km-#t^Ihl?T?9XM4#6Fz)7}0EWQ_gTKl~P`vr?uZuZ~HCcozSPX zUw4-6H;GHpr?p?xVEYZ?D)edXSN+=d>%`}wPiw!T(e`V^SE5gAzwCV5uM*#ZKCS&o zlkHcCpF^M4e(^=NUnYJ7eOmiP&9)yAe~vz_{run9ezAC+lkojqSo=9GwqGRP41HSr zS(n>>zBnI!TKgGM+s_g2k3OyEfBNriKO{aJeOiA$zw=7l9}xcxeOiB>p|Z{P8^m?! z(=&_Q^|R^^wqGM|L7$%ST)*^>wqGH>7Ja%+<{xdh{YmlN=+pZ1^AUXhoLrLkSNuFW zFz;6Co|pYCy506m#G9i}=Ssio4%@F4?|?o%wvIbK`FGiV ziI|U1$$d6&5*J~<7PxLxH(%3}wjUXE-V6PiIL_}4T)%D9<$V14elxiwKR+$`moxJk zaXIFr_4lEA-n9K*@$u->P56<*;Qjmbr0wUw=X^T)G>=2j&&|#Aw{MyEYveR`AD=fY z^DcuU@U6bDfv4b6JU+~CfCqNS^B(i_JK)B=JTL0|N!ZKJ^LFw3ufySjJnvLLpMbky zzQ5&sU&3SXUcQ&%8(X2(d0vU{T(}b6-FF0Thx2{^3?76J^xXibuE|UM`#zjM3YUp* zgWKRe{r&^+FnqA@m*G%h-rC^dCm9&fBx@N^y}YtKksq% z$&2v!NL~It=YOXt@qU&481fL@=a1ju=lJ~mCHM0oo5ADa?cpi$clg2iS@CYjy%9J5 z060y2EF8o3miz0g<$RJ~0?&%ChP{{Fe7C}B;``x{_z5@%&R?259?!$&|1R>f{q>E( z^>CW+58)>992^yIa0(t@@fL7Qyc66b-XHE49|I4GYv2)a6Fe^dJv=4ufM>;Bus80u z|9&`4{5TvE{~gW|zXlhI--V0CpTec$dALHH`U`x%Ctd;9iMN6q#jD{K@g8uS_&~T* zd?eg0u7>->b?~70Ja|}q89XNb13W3d37!$(4bO`ohEv~k$9D+M5Rbsw;z>AP{0$ry zXV&8SCEgJ(7as^$iL2pSaUE5&ESHR2|? zUVItcB)$rcio4);@jY-%{1DtDeiH5%55q&^F?dA$5j-xQho{6F;)QBfoWmEcx7_jE z6HXH!0f)r3aE|x_xKMmGTrBQ_OT~}C72+4+YPi(De!d2GOa39;Ctmk7JYU6|!NcO6 z;4$$b@TB-8ct(64JP#N9>%R&Pf2{>$-j z3e4|!dP^8Twu?vM6IpU#r|zlOOb z{uIgk{T4B|zwU@UKgZ8gVtnlTCFb|9dw#Ivhs2HO(^*U1{n)?~Ah9IZHz96EpAN4| z_V0tU-dwu&?^8Yl*N!dq`fvbwfA=~(GqTicT;I*#x|yB7Q~VM7p>3CX6Y}}haFOkg zi`PFL*PA_-uKjt)EI577rT90h-TJByvEv)WzkV3!_t8teGJkt{JUfrI{g^lx^V1RZ zxPN=Yli~_E_qe5A#X4^NjmO*hn#3ogPlwZ7zw=bv?-QScK3y-{8#>eWbHtaUPlx>N z?SPBnO56_z_uozRc6__I7kyga4|V^__6NkzqEClq{;9KUe^&f5`gHaNZhO)%vi%J4 z+vw9B{{Has>Xw|(rylW_=+ilVf4wts{e|oN?OOpCH!t;S@DvG-N5>U*{W0+l=+iOT zzrx?!eu;Pw^yvnF{fEJQ@ThNYe@m+yPd6Va&u2I)`KcIBPs#X-E8TeRf4%q;^y%uw z$^E+?9=Y0%?`^Z=`^ER8Pp8ZN_FZH9aq$rPbg{oa?$7)mZ9k>m`3>}G{r#8lwJzuW zl!~X&r`tDlkJs3(wm&ZZ41HQZkLvBR{ZaAyXX1Vb?w0FM$pf|@5p(}aAG3Lln0cKz z@%V_D4?b_l$KuY+%l_fa@ipR2u)TDnTyKV7wEc1M*67n2^7xF8*gmh<$tC%DK_#x| zfw_KO-ve{|(sBI{%$%=bI3hpijqB-TBe} zxt+gTd>Hz4tMs$Jwf!RT3FyZ=GanS!VSDHq+5V1=ZNFE1KKgVa=Hd133U~sZk=K*>N;`f;d?Whwl=OR7*?zzH zKJ;nrckp7LSd#Y_G4Ye=)7o#|*7l>~m(i!o{)I5{o+OS*k5>5wkNuy?YD|IMxRcVe%sEr-!9$?{e-o@%YwdmNA_XfFZ1!<7aoE2 z`O&hs9p5270)4ts&ab&2+kX0i&gr;Opfff~uCE&7bB@};{QSYpF|N<^Ila>P67=ct zGWYx~I?m;Z=ZBcjkF*nQo-1Zv^b4DpiWASzQ*Ayjz82d<>(8U4oo@T-;x2AKE%&=) zXD{eCI6uTb-0MF++@4;^6VG??Gw2V(U4DNAt~qA|Z&F^Li_dlQb9||o^Y@9F4~vB^YbN`C3aOVD%i}NubJtX&wQ?0h|UFppEQvc}8`7*?ZVm>-e z9>1)1+s_uCjy|0u{laT)KO$~MpRSgE+jX|zC2mEZ?n`&aYwC8}PrJjJ`l=8+_9w)guj*Nw*NA&DAFcb_{haL&i4)uRyv>Wn%tL>(dA^u= zx0w6iFJ?aVf*n6EW}g0%&9lYNVSi|T%QrZGTgGfZCVm5bx=Q+!Z`=O7_)YZbQh7Zo zoV5Lj_#^b`I_Y=(*Y?T5Z~=HpZIy)z%*R&f~f(P7!YSmM(r6!Ch?{*d@k^lANh#Noww z^PgCf{b@1R-@1X#JH)49J~|@rS3;|7zexP-%0=FIcA8gufZP9!9T)V)Tz|_6Hg6N3 zhxO;2g7wS(m(|*St@s-B>A3>8{_uIWUnb`IE3dP8wfG9mM>op)2RdwjOdLZ$VOjrh z_kzBd>yJOXAQyLVK3LaZ6u13y@g3;Xu`S*HmrvM!h4?}AXWmaUe;>5_1KW>_htQ|{ z<$7QHk?l8&|A{_5CjIcowqGfpK%dt6=RUFh^iQ2XMxP$QaSX0sLz46PF)Zfs&c^d5 zxg?(th2kGDU;BC+n)yoCxBYT4=WE>1<}G68#Vc(d5i>8$w0Vh`dDEsgZxb&+8}}=4 zKYGFbcdoMiUNPsZ$+CH!nE8a5$8TE9d}MPwep1Z5atoW+h?x&=Y4dS0^LX}xT+DoG zE1Rcn?aaJqduMKcpO|^ek8Iv5WW4_ON+K%)C|1 z@oi$}&HLE#E#hr(KG1{md@J17_9J4>SGJ$c%f-wG_P6<^W1Kmmx!6?++*{6G4rAOZ9XPup8vSbi^a^FhHV}d zGoSsJ&F96;n?JO9RLs2LBbzsgnGcD1{NrNg)1TV$Gh*gVvo`M$GmrdW^Gb0k&Ih_r zo?ml`f1M5k@jAloNn3;uClX8Y^S429Vtd70U(tH5&pa$<-o3=;!(!&~4Q)OxW?r_; z=H+Va4~@4+YhOR=H@5vYaXtEUJq}UudNZmh`IekV&;uE+wsj} z=8>4q%f!rMx7oZ~%sll@n`elbkKJYS2{Ci;9-F6%KgIE+_3zcs_S$~N{mz;AMj5T| zC(0jiIgd}JnCnk@(B^4k=97=vd`4V^_0ffLy~ujp_Or#Duly;SSBRPCKV$PkaS7H( zcggd!d&Krf#Z~CjyrT}Df8&z#cua`7{)(6Fd{tuRHRCpK6EiP)*XEUC=2IWo-22d( z`Orts+`i_Iote*l?aaLB8)xRzi}B%aVo6@F=fupj*SC40n0e=Nn@@_F_hj3ARLs0E z&*nAaGw^uS!NU>vcr@%``|V=RH+!tji;r_=o>lM6;}I5Lfc4RR_+SePG4t9^oA=-7oXGETP8<(0^O7E$ zN5stg#T;LJkLxqfe!w}AiV=5u1^S z=gfTkpUzx=;VaI}Ti$YJJ|KR9k2jo;uLsYMNy*ut5_3N99XnsHn0d;(Hct~XZxnO> zCNcAw_w4vtG4qo5ZC)y7UOZ*6F-(SLMM?0@~4z9N_?@!rZ0r$WezH{I~cw^r?!=o@?&)DA|o)8}i zPm526=V089CHiN>-Z9Sn`--XXc7Fca(>QH7)Xh%_CW=PmX7M{K{?iyoKfZRGpCJr;W%RnAK{SnPHGEHCl< zK%9R|9Pp0gvA=%*d3+x4Y-6Mz0RwLcqXPlIm z_e;nN0l$ZGX0z5uv!BrRLB|aaduYfZya_8S|@BsXSfBYVyoAbPz{P|zv_)GG< zpZb0u?uUc(dC_^eAN)<8_mrPk;(zPjEy91fWO^%+=YHV+{efKAgLCme{QZz(cy`MD z{OsXyKXU&2m&{Lqizi)vCR_@S_~S2zpzk_qc8=Q~rf$`%iiS1nlmr4F3xE>C+cW<~`wxB)$o;Q}Ti`<9JiZ-Y?27+#33<)P6UGMc=ZUYTF@JJ&!f3KWA=Vv6%U& znEAYzd0J$_cro)yF~=7k;QGwR#mp;zZ1XNL^Za9N-dg3%d`!&w`+jEg=!wqEQ%`p0 z_?#MN=EY*><7e1Br{0RM;!)7LpOFZz=+^Q;bM<`FUT88P#+Kf6Bj^6QRec9#g$HiyvwJ2dc!`AkvC1-zDoQ?Tuoxk%HJAa?J0DYSO{y?xj z-J`bOFCN}|kwQwm&HzLZ8+RZ=4`C&7^0J#5-etTKkCKf6|qK0Sjp=vSoJex>+7xZk5A z^7`1ZuI+bSumpeKp-ArkxqpqaKd+%rr^@43zlqyl_M631 z=+nLUdT@T^WVk-JuWG^i3MKy%E%Np4@&oRp;N)_B+K#pikGY=jNZ< z&Gys6&c~upPssB-zK6?se5S>GeA0?-o*`ylyqC>O#msZ|wt23YxwntaQ^d@tN^M?z zkTdhzL!7z&bzJ^%=0npdUw8bG$-96&+nF-T+V(>d>{IBvpiqZZ?XMs@$=}@`t!rXx7z-w_)YZb z0l9vR-DdmKV(wq|?KUqGGq3xL&D+GEV|{c9dcpNDE;;vqMC@IXbX>0I(Yx*Z9pVuB zbWHl$_t<_|yc&JFMEX_t+J2+>SLoB7^7zgC)%G(UaOUxdin)JnV&*xIxIXhzG4sfy z3vw~@?#FE2CuTk}VDoV?^T8)XKbD?PRu`K z^L{b&{O4>Q5i{=HM!e)VNsq|-8zg7n``(RTiGI-!xWAR_b3L3~lJA$=#ap63xoG*? zf1hI;cyRG@Z^R$J8g5&6`PzSH}iLhk3ydg?zhi?OE*| z&5rjrbZ$YP&RXP-f5t{G=l*Aj|A0PSB>nI*+bD zamTA1PAKP6`F z?Q6$ph?!TF+Pp>lH|!5xFMt1J@^IUq6?49cqisGTeiQT2x$C;e&#SWikoa@->5O%f z{S902`gQ`Y58Jx&&2Vx_o?la9Zcj?J&FjQlVZPaW@%)qfm(Cj7?-hs9Px&*R-;0y$ zKNy~GS?)Fa`*RW;zG1mn;vcWG;dmdm-|usKGETGeSBRMx*V(*X%)DEixc;8*`pief z%tL3`JV(sDPR#KYXSzP~E-~}5dYjk&%9;86+0GoF-ryX?@ksmA^0j}z?Rt3N%H>|U zJYObpJd;cE@#OIhd>{Hvzr*qM&j+rr595QJ>*IWZna_1NGw0){c?}+~z={18b9}?C zHg6O^jqRbE@P;&aeV)I|_S5cm=6o&pICFjN;za&{&D+H9VtsU2uJBstQzgxWIGMryt{nYRM+vgseaOtnF8b zPeh+C!CS`Qc(zN<<25Hf2mRRMO}tY7`Sx3Q`0M4~sDHh`0dD_%xtA*E%gk$b{aLR& z{{{Wd|1I|lQ{4J1F+REY_b*~TUTx@W&hden4`O=)bNjh{ftj~s`vWuQ{sd+|g5wvM zIge*x=0h7eGmndz$2YS1xS09ia+}YHnfDa9_wSG6_|U=UIdOOpPJZ67%zFi%h4~3Q zKkxYuoU*#W|NM5D_W_&_2Yt?8hx_N`lIhJNr-RRTmRyeKmv}R{Ma=Qza=)E}oW{e4 z^@qGQ@Pv2|cv5@-JS8rNr^Uy?Gvd?WS@9+CoVXpH7nd%=i9hGI=XT^N;=jVd61*QM z%Xi0{k7w#B?(yON=KRu`d5!q7|7X6bo!xvKU%r+f`foiFVi=XCVx8h^fAxE^lb)a}oR^tnBKzjoufKlztAGoKL`VZM~B zH}PiW^`h$r+n*C3hCW@5U#SePhtq$t{mQ$XPe7j@Ti^93BJHGHmXXYI*IdgoUn0ePfZ9Xh! zUh=BVtHsRYV$MGq0x$U6hiS2}pTx&#guz8-LWaT)(R z9$XLFU$^V;5Z{YF9enPlsgwD#^J$)#8`Xr}g`vHE+22xxSXWcEEqR zEKB@5K}|oluRpcYe;@PF`uAVk|Lx{WJig*N^!wmAW)F@>-MH;HiBqF^{{ZXp$bHlH z^TnH?PisFedE$H!=c7Lk&&u}n{m0HfBHkZ;x<~qTZ`pp6_y}%4JTLvq3EOWJ{}O#V zUGCTGKeYX*_+s?w47p!#`^fe?#n+%u_sjM~rft7M%<~~8=JD$mGavfcjvo^<@B75& z17hZdpV~YuWoYGB zGcOi1pAjdu#1CLTTK~Pinf2Xx_R~_G zIbV~Qd5f5N(NfoEUM^-nl4kP>G4rWqHlGtS?^tg0A@TFrA9@VE;Ck7ziS2iaIbZ)a zHm}cdW}ces%>Bs`Gauc-=3bsN^ARz}kBgaioZ2uK-Mp;4P=iRtJx56oh z7I=6YpU8Q{NC!K30|!xQ2tJT2~o=fu5m%KzNB3^nWa(@Xv?`XyOl3bF%KNeo_d=2fwXCs&7?<==`>CUGW zn2%0F%Hxsy|ID9pxSOBHXROkh*OMlhe;16W^?tT-SGRulTf~Q=Pmkg2!S%FcH`}ig zbNzi{&etzy-oB?D9}}O1_0bdZc}&wjw%;t~e3d0OuMsn^+t=oeV&-%E+1%UTnR$Zue`RCzY$v3zP_X}{aeVf6P@Jhe`BX}MTwl55) zR~4-N_iGP?^Wk87j)o&}i9h~CxCO?ajY+KkmvGzh1>RG>e+5^ZSm5onK{7uNj@A`; zS0t|A%e+hAj57+nU-`a*`I!aYad^J-c=7nB;(D4~Lf$pV>EQa_1E-0fh122S`u!3d zEW!16Xt&k=my+|({<>hTd45FY@qPp2Y5jZAIXAoWf&CKk2k6tm-{YHs>th*fe?I;j zxcU~{Ut?Tw{TzdnOY;7HT)gCJoX>EX-(Lym-kP!Y-~ZYgZoe(Vo0IvXU3R`!@oMzx z;Qjq>aPjRK=JV@*Shr_Tyf^x^{(NEeownZ~J{WyEALm1`zs-NK{h0Vj^yzy12o3v@ zv+#I6mSKJ#sPhp!eoV~srTGb)$Hd!Si}~TAHEw&-p0xd{L1)f4Ddyu{^t8=;pK)gH zJ?os5OPjZfnU{WL^D;5>sX3cZixcbr+U7lC=GEWWyhhBtc;4of;)`*-=xjM& zHQ(8Oqqr4)dJOXhk4MS(wqGvh`g<0*_*{3rxgPV;ci@7?>)q|}wjbCpOXA! z%umna^(A;b@)z;dic9i(I=9&Q4D?$zTCw(ebRImOw!-U{$G;y=F8=jc%;VdL@tSkK zz|6bToq0TZ#g}4zG#}q!d#g6K{TlHf(5Ln91!ra0ey*77?-O(VLt^IHEA03jG4p0I z$G3=?kFB)hXT;3onKmC6Gw%zzoUWAD_gk>P!4jNb(FKoxeBt;_-F)2MYBA^U72o^+ z%)jvcQutDPzV*rY$1tAml=mZ%&F%Wj#jl}Hw_rPh$9q_EZttj=+uOE~}$AbMCT98M6Cg<}Ewe@oi$}xp_7(5;N}-bN(JN^Q?S3 zK1a;FUCi;FV&-WDc6^4Id5f6iTgA-h#mrMyyZM->7CJKziJAB9=yJMK9*?hae$cD% zbzbjNufg>a4nA+ogh%0QKi>|Xh0}fS0;jaN`*qG=CC{e_@?hcfiQ5;K?KvDd-GHz2 z{5%FO-f6|!pXWUpuHSh@;_oj8=db?z&s<;H-fsUmf18+j?~iRhAZA`#X7gb&^SVQA zUUHZ-^G-3>-y>#Tb-3#@FD!RvK7W)m^X8+SPy2t4UsQ6A9~E=_n3#FZF>XG3;q_+l zGJCzLUCbmKYyu$c3e9&7VTG4sg<9=+JU-=12KM~}Djb&5G(MUBmy#LRntZu34d z^OjR=9u+g6JJaT6_0G)e&$1qu<999|FFJTXdpSG<bXF35Y&bA9GOx-t9brJ{^_wrKiW`+@29J_rLTWo0p53*NHj4Ud+5j z%seV)-X><=E@mDRGw%{J?-eue6EhFpYqvj3%)D02@pa+T?XTux&`L=Koyv%nI9D#%T?fu~j z=^p{t!omC}!p(4S|6UJw!rWr6|6;fgUhexUI1X>-`$l*Y<|icV_rP=TmcAc@L)R5} z_*f^AzY2H5!TKiQAvoBcFW_-F*nS?L3VHop+@5ss`OwC2HS)mQ!FA$Y;70L2aEtgS zaGUs4xKn&S+%5hc+$X*k9uyzHGwyfA8^B}YThO0`_4Pj{umATWr-SboJPU`ubAA;L zmf(J_NY1CXkkkBr0^k44!o@I;@7ni6(&zbFAzt^|r1|&+{W{6nuNN;zpYD`?%8)zX zw?Li-^YP()98V{g4ZYRKLvWp+^YLzyycl`Qg7I`P{xIZiaIn7|KaKMzxh(TeK;D5| zw=e%$H=f&5B)$NBx&vPi_J2@v_J_q$^b?lX(~jrd{M??ho89&##xKa{o_Brbsc~nH z?-Mic7c+18o9i=g5i>9SyUi=a%-jEA^KLQo*{e5aWCw3zvvII;eJ+WC9M%;Tdr9}zRpe%0nVV&+jX z*WV^)9)8V^FBLQI5_5d7I5GZpJHA59JbTRMx#Gn9<2LUVKXonE2lvVSa`ij5UnAyx zRg*Ta6EklTbAOt}%sbw*HGjA0q z#!uP#OU2A9#2jBKW?my^UMpta`hlIlUCcb?Lz}0GnTN!jKTFKKSIoR$%zQ-5d{oRl z{E=OMu{e=`V)Ifl^Yl+`o+DKIkUYhEB5ay%x_iO8xxIA%u#GEg81DltLnfImHd_epYtdFjd_t)dgZ9jVxXUmEO2~o|3)B_9J4h zKWj&uhsDh2#N5AmG4rCG7K|4&9~LK$kC=J+u6BHtn0d}_HqRF`pA>WcX)*KeupQqk zX5O>A&HKd6>-MmDgP3{7o;DAOnU9LOePd$gO~rP6vzU45-ZrlgGao3id0fmqKVtJ@ zaUwrpK`v%K`(vAX2RbvaDRt)l)ry%9bh+#C)z>9mim&tfeOio$fv}AgJ;G6go7n`{Vl`e zkzA6mpY`&1{u_O|7=_?^)Fn9|{~qxd=+pZ9TLTBJ^yg2$eh!NH_}3n6^LjD!>^t1{ z(cv=NuM#t#Kg{O2hdVQm|HPTwKPzUQa)ixO#mxJ}96uyxo`0kr9~Lto6m$Hrn0f4I zJAPEmeB!4z&p6hZd7GH?cZw6^k8^$IGh*h2KeKsQ%zW$wo6m|9>p#inU1H|tKeu_E zn0e?Fo9By}4~V(_adBdNtsNg0GmncoepJjn=TtjBB4*xxn$7#f%xmgw-XvxoJ>BM= zV&>i%Hct^VuMjWl;DF>3JfBM!JYT#!-Sdb0TPfq0V>~@3_YbLO+4UESx&GR-ZQdeg z-o3ynvi>Zrk6wiyUk}*#zINCDJmhrp^TAASUpN&GCHl$lCuZaG!sHV24o6N0pC_Km z@%|DVk8D{#_rFKB?;P~$LVP{AzKu!F{Mo9)+%4@N)QxpM8#Z=V1+-ni21 z!U+(JFGrqSlCL-H2d>2bNx9XT$1h8KA?Bll<99PWecMVeAK#D&=Fjc2_uL&_#O0vh0jkO|MCI1Kc66{>*f3%c--ae z4~oA=pAJ4BPrDxHKg=si@OTZ%`CNp29(kkWwNKdj8^i~oPiM*VwPw)uE09l(tn`Nb z?dA5hN&XAubcVma^WiSIM%F(seU49k%FW+~KF#l^aDQ%vL*jlo7Y?ppakvr=_Wv!o zRr+7Top6(^KkaF^KCV9`{sDcuLi#n5vtK9P=!T?u{&0J@hU<}M%lKC5b9|dPj6SXR zn?sVbKP)}~eOmk8Gj@Mc#TDq&S+YIZl5_qX@mc88+Ao%z{St92`gFC--yu1le}j*> z>nq2{B)<*g={7n4)1S5bQz-ri`m}z3sa(Qs%W&Q!ld3=V&m!ePW^=AOro8+>g*M_|3pV&YD z`o!_P9tAniw;1xk%-Ijjyld2%d9U~u%umnA^{@4H+mDIwMxP$WJi+z1X3X~M#Qo^g z&A4C${qAwwpB8g_)84dsx|n&PnEO*CX5K7j-Xdl`B4$1+W5=+o75{tUfm`%~ig(Wm3mZ-3wRd&QrjPxs2>7yi)ptHs>E{EuuN7Be3Z^Y{#j znU_x6@#W&g{GZr7B2K*#-*1AaFi&tkWPNJ;`C`sjG-LB(G4sf0HZKz=w&!!37mJyv zePQzqG4t@O%_CywU1A=u9x?NgFYWjVabo;eHt!KLFU5Uba!KCrc8HlbEV6l2%zR=a zn@=rsW}dUL^}^p@C|Z!`X1G50w@l3Ws>RG}#LVMj=A&Zf;T3lNh?x1HnBzyp%&Ri( z_UK?Ux!EFYyJK#T>GZ``zPr!oX;??XWagLxc5Kq-j$e7Y?@P3Ajx17vM_qn{bWzL%3ed??*I=zeOH} zc?7t>>)wjTYrZJ)c@DiXJb*m;{Ll2V;ldx>?`!S|4@|`n1eYLh z_VY90S;;Sjn=yaL&;JakpdTE6K3*l??TY_$33<11K6nJ;->1C?PXB&aFWdJca3LJz z|A4(8+~)yrz$xNS;8d}98_qvC7{3ubF5UtTmf-z=`ljxByFGH6*Vo|nzfN*q&+En9 zzorEq#QB4`kkI~MMSvwgGQ7$La6bPD4wm5a<@_nPy_oGi2 z;_Jclp;L19W8xw7X}(^tKLV%zD0A)SU2nk6aM~g_U;Pet{jK8n(5Fje{r!?B&Ij={ z`onPDI&S{d)pq`{_zU#uGTEM{HMZX({vLh0aj~0!d`H`#7xVEL*vaN`G4qrnn`elb zSL|Z*N-^{7$bwwVJW^`&S~2r!F^}i0n0fRdJHAcKeC%MGPm7uN9O`mY zbw0nc;aTKA_04`*DTs)?elAQI0G(E^fSE!;c0J|wf|n`QE&&G~+>Cre{ChZ9g6H4D_ahSv_BZ7)yZ^P*_W7B?}CvHn&# z1z+InHIGkp(QbYo@;Vo6A0N+YneWa8Imf5;+wJj=wCkT);DL{AKc&L<`;T(w`bWfE zU-mIJ&lNMT7IS>4()F45{M4EGq?md0@h+!_WPAUL{il=moalDc%`o?6$<-+YQk;33>SkEkb`c|9T(ts@Y%a?w@MlUEWmrGmnd;U*`iUE#c)on<%>5spb!I*-z7zA& zb@F^F`_lF+#Sf!T56JT)srOWBm&)wtq4fcn|;Z2;+>)nC( zlkir)H--zvS#Yof_XD-{_U|do$og{8r}g)PQ@(KP-vxQ&Rw1uJ&bP^J-1a8U2k{~3 zPs82PZ{5!J+r_)Dhxcc2hnzoIxwfA#J`wZN!!rN$4z@ohJ{x^{R_33`xBY2xB@SMB zfz2z#%p1hq|3)$MsF-=Hn0fIUJAbK|`9Pt~<6`EmJK4NL%)GkD=5=D`?Yr4LCT5-* zwt1SEd0fo>8x|+V@4jHXn0d;cHqQ_<&)&=CMPlYt;>7tUWAFzFfO>i9EOui^6yKe%io{n`g^`|;}egc^k2t(qj0XQ zZ>HSM$Ns!{8hv_7`lCnK{-k(4d}D&H!3QvFxA!F551;H@$sM`WIdOc%%x5oiIo&V& zw*u> zzh8eQ9Fac%{!SGfe1GdAiS&Y^tX0>gOV3uJe`dL9-MDg ze{$owz6mks>*%m~mzeqRpKU%SW}b3`%jxdL?(>dAuswA0{YIvD92_jc{eHTPKLt6R zi&C)tg_3jo!{U1MY3)}^&VIG{0`%$N^TOZ3J)I%1QP!7rquU>j&k=W^PxJHSVEY;* zXTMS0gFda_k4T?)kKbd++mRQ_`PF}uUH_1H7=3z1*57rr?e~e_M4!%<{;=fS-cj*~ z=+oMtmYn@r@we#H{QNFB9^shXo`^W@FSuU7Vd*zY&iR|fo1#x^zgKeh`^4L!PtVKo z?7G!%Pp`NTeHtI@uigIQ+g!gAUvKbM(6sdJ>qiCpZ2KpW9ZYt-_xo@-Zd|C-Nt4 zJ}hS5HE8obG4mNQw{KR=Jp8mBUnXW=^o-3*#muvwwRxeKdHgw>kBga4#BDw&W}fvA zn-`0jrw+TEj>-A`93C$^cs+gR#$`|}PRaLSU^ z-tm6F2d;s)_WMu6(WR@spZNJ}@HkxR`x7{4gVo-TeJ{QnpGUx(;`N&ATM0)uT){C;59cKEOz(7fOnd=64;T4)3tYGk zzF(49fAaeUgDc(r`Blj2;QsttI9P($*P1hVH^gN_?>6LgKNLLQ=iYVKH*RnE0@tTA zK5%&t#?!pM^7t^X-P*n0KZ2YNw*Ogp7TcGOUhw%Kom@iRE69T-*xt$u-TL1`PV4=4 z_+poH{plaM?W0Sko%#GNk^cLbkM76z2m3$S?B-*CPCSb~9lYOI)PwW=lFiKPOZTOA z{GgcIQ`F*ex>UArBg{wN?jO%h;hB$Dul@O?)$s5qt3CYKRN{E=2iJYN+WVvLqhW7m zwReMW&fh7I$EnEa;PGgHC*YDqKhtZ5N8se+lj&UxXK&+j&XX*Z+Pq^ZDCstLrBo zKk+*E;PHdGf5GFOkNJ{I^8I>`cq{bBu5$go;3=5buV8%1)pmSD{1fzPUN6}{2`+*T+I(QNulKDFE_$QZT_}hQD-)`H?YnRV+Q?IkzTP(gG zeY($|?-*>a4%?55C(x%`{P}0#vOjNTeqKI&y&Yd7PPy0f zXx;yL$$30eZgAr_L!Zu(=X*}4%XxlRf9Z}N$LC6(hw=0vz8*aO`>X9&ig!Yvu8{d-57>T>_yF|j2HD@~ zM{Ga)QRfrTr*m|F2VBm_Ga^10eY!{blTXx~FZwMcj!#Jto(e!no~M zi62Ct?!ya2@cikQoZDaZH#eTo$H?EEnYW6Wr@r9w7Z%L_-U4%cy7a$8PS@wT?U|6A z{pJ_l{9NCRn0d}iE>FXSvUv{shYNPFf4!qFXMaM>`TAb9`Mj8U|G#ZMC}!S>^(B|& z^@8gUoER_W`pdtzdDnN&%uBy_=J?VdoSCx6^;kp`y+Qeyp3!> zCgyyTVy-W=%=LG`e3QGb@@C}tc4WAm{kWL(wXd-GxR`l-bDNKenP=~2^L{b&)UeHC zV&=ugHlGkP@7v4f^J3=lLu@`O-W|t-?w0d6R%ZJphdL+LCq54IPl-!0U&G&4dHg4I zg7dfbNH?DS4l(DesjzvEn0fWFHm?;kZ#dWHP2yv)J@m|0ZhJ~Eu>EN<=NoIXdG>|Q z%)48hkAurDb7o$5xij-VG4s(jn@@;O!uHnvd6m~A*Z-6oY(FGEAAPza&Fx>|owi>m z{w?Q+_5DxDUu?fZd?WgFSg!w#ciVoe_^;^GQ%l|U6g_174dTC{PghC5ZP4~d#P6U_ zcj1OOIKRR;-;zu6`oZ%rFpqbS_&7N7cbkX);mmwM%<*l*HXjow9`A9RH;TW(_SXMr zl{YTioBqD-mx(vNALkRSKTnnVf$e9BbJ3@#Wd8VPwx9C3b7FtKu9F^e%P)k}#aF`F;v3;Y@jY+}jMF!+UB{`ci(f@YB9`hg-g1 zo%nrxj{hm_{jl15&d(d+I2?RFc0HWyt?|zF^L{u6=ldRohv6N3e*(`*zVtyHpG7Xu zfy?3G`*p=|J$$J@z6_p)f9CsWxMJ}d|MRcp=SS7}ydk+{dM6>LM-qK}KF0Asa^F9? zh~wdypSQxX++7lX4}m{Vdp(?jyxh<4gbQ=re0^}^4!b1Y&#^xQdvMSnh0EbwfBd`5 zw{@S_eFo=mB=r;;+!B_2;Gfzq0)?@p=zqdtvQYe`EX2;uYxA ze0+k}s~*X@J-y=X(5I{A^>%9B&Y%9Ba|!x%uJqG?a5?7>i;qE{)_!;quZ~=jubJ@u%q1dOXv&xBZAX^%0zJuk zpVt1|8r#n=bS_7q*5lK+qsw`G#>KxxpVofO&bHqw{tf!H9?!_Gw%;i3K%X9y$=z9TFwWjqsRNjMz~oVh1=k#{JaaUSZ|HD7ao81 zpN8AlclU2^!ToTF-~SGtgOm3+%e+k=!|O%r8gC~*-wm#U_wrp0cfz~-z6>6NllL3= z_jBR2CC<;nC2;Wl)_34$$rlgc{kwQ;cuM;Fz`0A^_8kXTiqD0k@UH&$bijk~zP=xV zQ#M%R?dbcTa2Vd%_Y7PI2iv#l{1!pf?v-bVe z^Kc9NsDFOE372fV#(To|7qGX<8t)u``1~Ca&VhJ; zz6P!m?*%u*!TspLa39=^>lyo1aIggTqjRYR{+E*L%U$7~562-XmFLSZFrIF~*MsN( zkmT$Si_bxyuJHR;!Py7l`X}Qj;N-HQ*MofQkSwp&&pF?m3WI&X@fg!F=>%=<#^J2T#GAhvplh$jUX|nZCD$``}}JbN-^$?(sPQIUOATBjH-O zJkiheehvpq@crM=p>F#dk<-ET@Aq&soQgr*-|OKh%W9}s7wPY358k5B3mc6-vrum2C%515Z%Fn@{UoIfI7gZb&; z^?6@-=EyAbekbQ>x4y%Xm&3E`B1vz3~qv(eZK(D!;`+>geR(TzvFK|k7r|z zn~&SqF8&04TJHy=zp(vQ@we#HWB&Tmp2qXJ)_H5V_?PzaY=M(Y^8H?$csKOvnMLmL ztUb;4o5d0I>EQWw49CMQGJdYkj?XyV`E>N@n7{ozKE0Cj`1FY{MW5E=(_Zi9W4}jy zHTv|hY|r%BuFv&_<@tXr`b~xI^OgJH@J`OxUybt*{jD&L*SjZ>*TTicbYbn`X%iMC|^4V<#Y8t-i1Tz|h@57&DpX}@xNXfY z{^z0i`^0buoZpKgMJMCaycKy&vEPH`7YFwpHB7rpTW&=p=@95QoFuh@%qo={Dezn zebbUB9&d35`ZEjq`7L(-Lh)AU(>i~h-yp6*pVoe_#69F}@ybf9h}T{AuED^l9x!Bu|39|wKd#a-{~!20BZS7Bwb4N{ zj*)SY>C6bRAvA=T5Dr3CIB0Ebc0&j)EwNdlB{nv+gxIXC(8q=l4zfZBp`|5+*zkS5 z&V659uWKIP`wzR%-mmMrulx6pb83d9&it_WZ^+XH_&JZ4J~-_vw|yb(PyX^0iJwKD z*7?;*o%5>~zll6;&fk-8qxc)RS)BF^?tjIb!0oWkZv@uyjfx}4)0z)8yZKDQzl-GJgxaAsWaa!J_>nS^Mg`nen?z}Jgs@}>TG{;gZ(Q_d=B!o<_o3H{)@y7 z$kUbhxjA39OP%=+@t=^VH9seH=Dlm|_&SlNHD4ih<}1YyBTt+C@fo-co?B?g*Kn=v zpY2=4Zy`_D|`OaEzqcKZ*Dk3pUerP=-?x48MJ_;lpy ziFIs#y2H(9+-A+|`@q_k`|r!p-vGP`#>?lWR(NDto_9vzzrsa1d8zO7vi|QU@qTFA zJa0Mrr5{AS0zM?jKLK|y&+{G*JPuby^Su27|G@h8_WkOn&*FI;Hs43s0nXSV58p`e z``-sHgmVKQ4JTleuZCOU?Spy)JOD=nx5ATB?}9UTwDo?t5Z*q>C*g#60&a!<=c~ou z5AYyt-Un~?9G(|oGrl}HCpT~Y_m4{8YPcxq|0K9u>KDK>@M<$&xNxVu`M;;y4L86$ z1oi)eyJ37iFtz?)heyT#h0|8p^|#*he4l5%6QeOiPz~=q;8So5jo|i9! zbMkEaKf`6>`{8==Q*ak-*6*9}i1>5Zi`nH{cbK22<$2o$%eN(54)YB!_qUzlM)ARL zFKqV5li@LVn;>5Ydn;{!SHn@*)NhAN#Sg?#+zy-he+Uo5X8-&No`Z9P`DML; z{#V)dxp297AGkq$6x6z`~HOQ$DmFpQ}rzGVz_Bn`}g%);jVmJ@1&*v zFkH8btv>?~N&QW@1kMQh|1Vq)oAj8KpU?Jih0Jdj_9y>-YfgL>^0aB+0cYNo?PbXFh5zQZkBILI`aeK9g(Na{;)ed1oL{p`Rxx+!zE_^aKXKJ z|19gX?>=|@L*i4|A6z7PugA@&i))dmGbEq(fX#EcGIqwTbPo~r_L3?^w_OHRe z+xA@kaq-p2)9Et5kzO}HDZUALx?Ju*vLA8th2n>ir}ciQQtBK}wfF_(=`Q@-Z10SJ zy8UO0-$kAtkomxSk<_pD_B2SkE{oepL z!(+1lmp$#aPl)g0{NPE+7Yw=iGVw#m(=)O>MbEnVV(}Bm(-rAgr{h(3ex2g)kf*cdeAM%rn;#Hw z_%hDNaJ%eJC2zR-3ULJ^p%?*72ktAJt6t7uibpVnCFkFZ)}~8%Jq<+ z@8!cC_&M*7`_TUgd^Y;02jP<4?dN~5!PPLomcn{y1)eAN$irV~_x&H#t6=ka-&gP` zyk}6q^cFmi|H3}+@p-odHqRrc9f9Wqn0M&x-+Kk;KiGVq==wF-Kj8C&`id{HKNs5P zxxb*^0WS;c8=?Imd{p4Y<@o%2Py79=VT`W`Hu=qvuY>^4oI$@P2_~@Dz;2PK|GG zID0SqymAm+3iEo&@o$d#)xzd^=P1-W;6za8_9)oHK98J_I*ro++GlxJ!NYsm=aIj_ zQ?TEEmiKo!{TDX>6x_VG{k-yZcvR{i!Ci&+dE{HTSG>`yIG>2OfQQ8^;ZfL(uMnOp z+9mb<0*<#7uHVOw?*zD?<4NsL_`9uer_|4byY{rtL(OovEblGw80uzzcf*C~uPj(U z|AaGPvp%>!$K>)tCi8i0=C}5Ed6)geB?y`8bzJH^o-4#t z$kVxUd^XP7{+MqP|A0KL_Z#VZ=LJLZpI0;XvEFzD`_p&0UzPK5=1*?_MdBsM(;*pu zsnj{1GVvD`t1}B$$ws(60e`L5My7GI)9k;)3jg-!_&RRBT6{Y4bdIe5`ZPD+BCbcCp4`ZeCqLxo>%^_d)7f%8sLpirtzzzv z!)rNHwr4l`qs{x3N8m!(oKK&EYvJ{S^YMFd{l0nL<>)tcetZq@3HHnLejj)%xEa18 z@a}MCvHgD98n_YuUr;{)r!4Pg)Q4g2PdwgtI|auV zoDsMS^+|C8^%?QQsC)a`!DHf$(0)?`?=?je7GeT562$~ zb8T`8dy9~#(;@yno#kvFOy>9>mF-o4I-Nj<`|Ck)(WXo0-%lJ3$6-@H6&?_u2S+!v z^=7yQ4hQ|U!(CFp7Y=3Fd_P<#egPgAe*l++ZGIZ=5wG_;mU?qr55o=Oo#07vAzZeF z9bYM&fD3~0#^DZ_=U;RDPQm`-}f%R<=FoKOlYvdAenxT_45E+Nh{=*O(THmS4!cJX`2)5WqpquaRskBh%Wp4NQ!wr)O0yum1c9}nA8`mbK@=4-`E zkf$}@zn#r<{kD|4>vvGk76D!kmV`e$<0@Z zPeGoJO1^r9n{O7MgFJ2aw>ZW-p6BLg#FrsYCy_JTdm!fK2gNraPiIPgMCx2WqvF3I zPiuZs>da4xA3>hh{G8O8_g32R4IxkG;(yHeqf$?8FYz15=dP76mpb!t@h8aBI-Z2o znXeXqjXd2d`@`JMcD$+a=UcD$20DQ2g7JsoI=C%x4jkHL$^8A@&Tt$y=bwGxA@PxL z!LGJ`D%=GR1pS={Cw8;-E8tP_jc`eUo!^~s3vA}s2Yb6)KL^){N8xce63p*2=J#0Q zRR;bEu7oE8FMgBHS4;43klO9nRcO}_*H^!I8S-?Sj=|;&9?BnK##0li-eAz#y_jB`e;tP?dliL4kH$N=?Bl7f| zEN}n*ZhlC76UPHL1o`{nk^`1_?Q;J(bgC7f6qK@ z+An?!{lWTugTcey_T%E^$kV3%u5jfMOS~!>f7j7&`$6%($kTj6;rZhz_6M8e{Umrs zd@h_GxAz~7a0ITGK95Da-y_cFtOP@#oCLIE|*Z#}9DqH*$Z6 zpI5>D+P+D=JM#1t0^A=;;M#MSIDh|Z@V9RJA@LE& z)6+qFo^N`8=jQvwmB`cj_rNF4ck}5NSf7bJZIF0*=K9Cw?U6e3ed49a(nj3*CS8&$oQkpZa!b!fjn)F z2X5b@tKEFDxCeRK9DmGbU*qO;#g8FRSIhY8|LEr1#4jOFR|VsL6P^>#!j&!PPqyda zpWOb2#p}L<`vJHq=JkW$kW0E@nM)i>=cm@;rAm`kOk$zP~vQZiri-2lpIpeJNagkoDE@$N|>v zaGLlYI9h7!55xKUTMxpsQhx~!9cAlp!&R%TKZA>owEm7>W4*zf=sxS7gf{VpB!)4-o z;0p1ha6cW|NH4z!)YhvrOr>B|2=RoJQd{MggZ{m z^X>>d3zt;pc^3y>@*eIl;M)W53Rj<$m-_t-_IDUO3!C=UaK|t0--Egg4xgOoVKGz7 z-v%dOUJu#+KDZOE2>b%dA8Z`Oh5O0v92`{VDx@+`k=W z>)CM65!Sgd{sGJI`(^$<;4~Zw`oA3Y5Y8tie-n-Kh4J5L***`$W#S>Y z12*FwgU7{_a0KTgQ~v?36fc^r_KG%?QkKMFDGb!A6yAXq`yg79xh+@9d7?o@ndLDb92D%=WJ20j;VghPQZh0SEXpPGBR-TqwODp|g3 zk*6Di{fYBW-f7n-U4E9^enRTqXitwKXV!1$UABE6>f>-*Q0M&nrTz-)bdI#I?y~Kf zuM@wAJe@817O6AeDxO20?v;G;-`xI7#2b8s>kT{?Fi$kQ#7k9WKMSBeiro^Fu*sMOj2xEgtSR<>{7eQy7w;$I_A_b#;Cv-SZu z-z;uGo*tI*6h7$YhMH{T&%iaf3RTh3!{J|^A~dAdjXA9&o&kBj$3p4NQjfSYd-^Ze2+=KAXq zvp)Td+kRxon)T?j)@&aWvtA))y;972vzYZ3G3x_j)(6F`=RUXA{Kc$?hTVEt%zCw$ z{nv_F9~QGdB4)kl1-JiVG3#|}xk1k7spk*)AM5(ppQEt-3TpGb_tB2mqiQ(&+&u5w zz!$-pzs>W`415FJ03RCo0XPZY7I+x0{av1SZ{UyMoVq;kvA_%QB4GkH&l6!dd0yW9 zzkjq6t~fu>J2l9!fd}D|z^B0(7v!ZrPvm$nhKuX-Jp9^5YWz3BnHS~-&v*EJEqDSx z2>Ubh&%v>a^SlcKzYF&?O&4(+4{<(f<yNYdmz-ZzzAsUaI-Qo9U)Z|>&gJ(f zaQ@);CtBeAEo}W(xIla_TnHzF_K(0BTiX01t=NCXPobVEPQqp~_ZzKPKmO!@eqS&9 z-zf5Qr<~uyNq7H^h(AJ}E<%UAznFn5#S1>c`AobR9*2vA{FZRe%kJm-)v!PL_s=!r zDDre^(0&)VU%W4z{)(-a!R6xP;STW`@Ray>aKWp#J-26@tS`E9)Q*o%Z?x-^$16P) z9IwAef5|`OdA~r8`}2)(#+CN>sqTWy;MGCB4{n3^4*V=U3hx*AEjars`#k(#I1cX> z)PG`onCqAG3w?_BSMY&>m%-6y+uzP`HCz_di{XB_Jn)fl=xY1>fn45x?C<`B`(5T? zbN_obJPnT{!298gU^AKLtAaP|`nw8sn#U9OpANW0%=wjJ{{DpX1L|?qdxAXc-kY{R zo`2KD1IW`ne$D-F?prp`_T@L&{@K1j>d$d}aGJD_joJ3h7mELlJl%$$oB0h%o%s>* z7s%6Q`G15bV7*^!f7_j3k2o}i^C7JH#5-=jUc3$Rbi;afd<_$Beonj_@^qIhPuquX zzEgY%@^oC**W^cTeoh=`|L}Wzx-eh%Z5&u9Cd>A2**Sz7Bah zGsxcphsE7+F5E2r^+!$dQ$Qo-?;e!@h-^I`hAz|@7#R3nCFAUoUPMca(>ts{n0V}oafiWI3AeKyEM=L zGw|=%@qH5N^*7~t2M6_9cnCf-@D*_W&3W^GAOA+U75-IFzXwihxA!ysa232Js3+lG z*jz8(gJ()FEw|yyZ1h@PpFZDdmdKO&Vf%mt; z^5nqDzv6v(;FWOuU3uPmL4SM0on7|#^ACbUciZpRmcwoEF~R)Kf@k2Gz!$?+_t?MJ z-wF@H=K6If9O}-S|Mxu~g==85J}$uW4!{Qm{apiR+?(g!5}4aFSz)hVFQ7f0k*a5T zAH!pCTHqhyaoAknHuxO(E63yS|EHEW%i9djgn9nv^)444Ji)&I;rzn5AM>ZMSByH% z^B3>`j({iSevS8YQ{q!lH+7@{K&t5OUnLwF7k8<66X4o@q^u;d3=Y(zvXz~ zLdlm%o#XF&Fc1IbJ4a5S73iI^Q-fg`tjiXXOH+#$kTd04lQu=nc}}9Pn+}c z18@}P`sVzeh6~_GV2-z3+H-m1;t!FhdAyqO)<~WCTJeHu-$io1Y+1*ScNyxva6a}2 z_Q&?LKly)OaxBf7^-1vxw5Rzz!uET^)3AB}dkEaQ-ct8|d;_Zc^>Ag- zp5sqSo#P)9Z}^38&Brp`{tLz1B2Vk**NIKte4Tg?cc& zpB5j5JY699NS2$AicdqHo{;>k)H$Avux)=K@-$9!^T%JS)S2%PUxhqfFZs~swm;^x z#eYMdE(`Xb)cIfwH(xF8L!Q>}JJw~p`3^DrYg=mTsr^CDkFTP?G5Ft@Kd+x-aBpv( z_Xo72KZc7Qve)x(;11Y4|7CoM^8vg#&ChQM&pv|dZP0!vc<`TjspEnD6~G1kd8y-z zJ_w$HUk~OVhld}}^V);vRtOMAa?5xA9zswBy1*gzcBDzUhpIT^Q(y$t$F;6$o~8a+S7Wxm274Acjn8)A0SWH z;^*dk+AnqH2gP4;yldrS5x4&W@j{%q=wa*+rvK@!-F(_I>z^Y}56gIlq|Wgq#W~2+ zlalY;#`ed2pLjRq=^7bNXj?ZQ6(52;-6s9_N}c@=h^vvOTO?n+-0iP_&fpuQCKez+p=N;v!~z7G<(2(E{V z1FwMxU~~RD2~Hoep9fdLW$>0kp366b-ZipSPe+o9*8Xhj(`GKXR7u9CYCy&vUQa_5V2Xb;!>mVUCxI ze7n84ztxC`k*E7{0yX)8-Q0Xxfi;(}p~#y3Y*_+KX9FE4B5MNA3Ff0OLu6bCBcy^%We2(*v*b4Xz*XD}lps+8c1#&+~bH^ou<2 z$#s3R|4D3bf6DTr$kTrRS>CR2#;MlD>>oDQr=#FP@fmQ5_z--?rdAj{u zyZ+fg+#Xyd&~-G4>~uFFV@pzfN3)Je@85w@97+ zw~CKIo*t9yQ~VgW{~GZb$kQFNex{Fe^Pvjsi;$<&BtLh&t#dq?Cs=d)^om&@5MPh} zXkEThsWU$&z5{tWjGvqJH!XGMXT<+Rp4NQ&iFSOD%m!|H|%={`~ zfAXIfE5)B6Pe&0j`9`U8eof-Y&ccL(*$;Mh<0 zeQ`V70iPGtAA)jx(KmL^EeSth} zu4n1rV||F1z+>V(cv8GKJR?33_D-|?Rj@r=mKtA{cVfl@ui$iizMdLimbWBpfj5`f zCHOvYmUkB02a~z}&B*rs9p?uZA;aVGQaC?h&j){kOJQ?;`wQFxhl2d0KVp5tTwZfL z*RRjBJturW8u@P2iy%{F0EJUtlXzkvr~y}pIdw0X9Vh|~Y)oAQ{S zB2N!2wEZ{!+Re9%4?>>i{Ts(~JlqNQ$oz88cH5VW&*u1G{k~o7H*UUE{7ez{54cg5 zzgOzV;pa*5CFq|nk>yGMt=oTC{3qn;r1U=~b@o3gz8!hGTl%j(&+Wfe{2=nQ{=KgH z3*3Ca_;KXvVp*Rv^={s~(E1hR>9~xi@M2p(4&}J`Bjo8>dEV^3#LZ`3YR%(es>z!D zmHok*^&B}~zDNHw?@xKY+i(uoZq4>l?++*8KDaQbe+tjQMS<7*0q3Ki#pXZ1 z+ZwKg4-D#izyt6;!RKv9!fBhvyz7EGm%r`|dw%{E>a;mO@6w9vh4>=WTi~2j`z)^+ z?uGsF;qTMH({Nc(zZWh#bC=Zbi}LfWe%MUrd|M&g<7w3CFhV>&Ux#a9ZV!4IZjyT1 zk2t@=+&-*t0#Cq|ftSL?S1xsapD;0Nuh%=F-iA6BGu58!BXZSJ{Fjse`Ac?qt@EkW z_e1+!cuw~B@YS|G_qV7xjyzo|`RZ%je62WvJk9mV<+}hLgmt{7e{|c&#aAOw^Y>fW zp3B$K;^zCswT)VVyf;=dzL=Sx24TDSjP@zcoD`u(u3>)d=&{5tY<82hgo zPx1ygKPmn%@^q<;Cwils&lmrMJgxa!sdIT7#F;<&*8G6fnI9H!k36mUj5c>XVewwb z)0&S^V8zrBTwTrHNU+k zZgKNd;+v4CrzJmftD7Ga-;X>UmGRI1#m%R6SU-k5t=}gqy3N+PJ}bnpAWvt?^{C>n zZoWo5fjnI-`Sv^9e6RRBwFMzX=|I&G%>i0cUI-^NtScufkREvcOYt6U^%g=byfCfj11V4x9sL zE{n}S&vAWvzp~fQBGhMKe|=_oN5V-sC)Ga7JDL5Rh3|KymN(1$4V+tJKfk#gHWROp z>_3kA`IG)gL1;(L&%6ZkpvkHJlFIPhz52b>K230!lZ z`+3gLUv@y16Mi2G^(oY&kePqzes}(v;*D`5M4S9lxDf7>_7jrl_-Di`k*D?dGrR}f z`Gv$q$kW+!JY@8``CM@Y@^rnd&$fr$e3$sw$kWX-{@j1K`F!#3k*5o#|MG|3e2w@z zXhPXTQ(zDEs>-?&oFs1|DC?SBkg9 z7hUO)t>^*5{+nr``OJ_#EWv64^d!&$#)JxEXnRNb*Bc z=l(b!n z;vbQxOC{eq?B)l=;dQb9!DZ;j9Pi!>ZayU50eM>UWm4yOD#eA!)8*2Cr_`D66_+7T zbG@7K%t@X3j2G?reu+G-`EscbmxjGvqJ(~xw>(;^;5p01JOck*R7@4aIECi3*G>_3wuw$Aa) zihn?!?w0$31-V=FR^R=UH|Bd3Kkf$}D z`G%X%5ub@Xt@&Q5r?!{)GUNy0PK?uRulSp8{|WJp$kW>Ytkl_m`dhaB{m9drZ<9Ln zUE)FH>300wj3ELAGzt+ireP{3Y_Vp07sVb@P+rpWzSj(t7_tH}2*` z?^#EXPkCcI{*ljYo#PLEZoM<}a7gy&^e=3k`G~j#dAd@rzZElXzCnC6@^n~!f1>(( zH{T{c19>`K`mg`N&3A||M4m24v&-APU@MH8lm9+>RD3P+^py19y{?-d6#pH0TCdjw z>$&+6@$<;jnoq9p<|oAOBTvU<{mdI+dA_TVxE@^H@9`Vd%3-T-wplI8TdJ$FAjkF#7Dz};?v+H z%=O3omGJm>G4Juf_re|9$L2pzdI27Qe+>Gcrgw;W7X|+L1`E8R9qseZO1KJM9@Gzp zo8hekpAPqko8S>R64dX6XJGD;9N+)JnYng6Z^8L+c2NHsE`#q1oQ2PeW??hGLO6RT z+kYio2;*z`ss7J{b63Q?e+2#$JOT6lG3S3b^DATC7s2}B`Y*@xl|SL{pP){g=dtJE zs`KpcXTA?d;lfn^S>AW>Xq|nZxfl_P_Kkd|1miKT(nP(C(Anko~^b0 zp8$8kyg%am(OS6t9NYd<=6`3u|MzFOA2#FbfvaKD{%N@6H+FpdysTXOGV0yGwcj_I zgd1VrUvmCG!ZD1;-#@dw<8QUbcy8KrOxqm=Gfz%?K`FZFSMrzrG0!0d%j>kAs$1XHqUF*aNm-xQtv;^ zcyo8R^V?(**7wq_oWFtz@^pPL{tw~myshRxkDP;hVq2xYA7R#i#!9!pZ1JXxaXo@@8J*u=>8sp)j<^tc zdMubfkC#cQbN}&nw(XBbo{mcY+4;84d{lf6^7I6LZpQEJ;^s5N*C9_2Nxom|?0-bu zgFLP0!%3+#KP4VQp4Pm#t2>@F@jJ-V#WJ2Esk8qQ@wdp+m6C6lI`duPOx!5Zdi;93 zx#J0mcSN2p3HmR9OoI=tBKFJt?={l^cmz6*I;KhKOEXzT31T>J#`boctwf0>*24zqq6dAd^e z_oBmXo&8sezeb*pO8>dXxcMgWqMzaV0~g^2#vC8){{no`%iy(q`}+917~o;fy_E-ll<9!#UzAxDehfs5ippu$kYTaJ6^{ZWMn4 zw@dpCe~#@7FAMt1g-7Aczz4xouz8+Jz?r|W&o@`X1@Mv}-v!6vEdxIT*TQDJAH&V? z>p?vu6ZgM`c>Y`0UtcTWoPF)`9|IS{+yY#mSHKmpS>A`>T9}{Uu>Kz00e^_iNH5+L z$4{~Sylh)|1im21?+KT!j?Mo)k|W_}_;*453^;9nyL~T(%i;E*egixW-x#aF>_5fbzHB3t|#+DFA7!1-c+-=#>* z=b=*Z=g7y!KfoE6*ypdUHpBC1gMFSVg7Yu5<3ALR!)E*mxJu0DqZ%=vf9l12{%jJT zjrOguSw9!U6BlFsrM735cRgGU*9GhE9(d*=>jAh4Hsg5#ZWWKh9pd-lZt-VupP0{^ zgW_4#ldu`zdiefj{iSw&Z4T#(cZAJkKL709%s$`nd|M^wmtB#k%hAl7@4MUW`G@&F z@oMC09uLeP4JYA>z*TVWE%yH8H*gJH8PvId4#NKAf1jrKAa{I8ssEn+!{cZ$KfYUS zdycP1+=e_o5iHN&;MR_Py>nD(>3ngD5b>U!*IU;QK@r0Q{o+JeUHlf%f7$4 z{SS&G=%1dI{=4pW^ZnwTk*9V1+4s2lT=9X()0%IVI>+BGJ`s6(M#j_F?e^ayJ{Nhq zQ`UdvJ~y8)z5;oANb=M7yZJfsO~})6$rn7}=F7$1$kPq-d^YfRH$NhN9CccA-``&Y_rm)HbuQm9&cFVIe;*X}P@{d{ zcp*G+nLS@$4Y$MQe10=*CUd@?MgRU3d|%}WyFQz;k%zkxFz3TAsdGF9hq>*$rG7W& zM~9?+pVWDL^^2cFo-UPq+JGGo^XcMuk*Br)OsO*;7JrL;%Ci4Y|DW4`_(|)zwG>(?-HMhJgwWKWYEo*i!VW*o|W^h zH{|9^#eYSf9>Hce&7d-Fg%fxRXPse2aSG?fn8^m8CPq#_`GcUUN z@JrTfnt?#>9UU&2D;v12t<1(J{Q8zy$egt{CU&hn* zhMVsZzlJ=m_Zxk0y7@sd*I!c1^*t(Py>85H-y&vx_8nWNL&w_l(I*%WZJsyz`@K;y z^V2wg`cszIgZ+)p#1HuV!oNR}_IrE3&F7DhnD_tL;_ooOC~VrVw*=33tYd#MSSe2skG zavJ*=-`s-r4g1&2u=hLE8^xEvW-_18gx|I6zXf%=86ob!-Eb$Y=jR^Db9?uSUqGJ5 zVy4=E1kbJ2K7HKIFSWd~z1d%e)PF>Kx>xr1{`YKq<_E-?_{BZCKA1oIFL>Y07m9aA zp01XBht%1Bm$(#px>oYx58VE<#it=pW3!~z2glPTb@tyaz65z%?;mSEbo;Lr--0|{ zF8vQmo&67q|A9QM<0=2h?LRI~B2R1oT~g=r3~jOk|K;T0e{@TIlFI{EqH4~Eb5iH{ zGCsERUwe5KTxuM+QwJUuG=NBBRszhcx2;j*C4_Ow6w*NetatXXdsSE4xi?F#qaXBVFv-z{pU-vg#dDHkgm#+!V|K2{Y{sm535Sjn?A|Hmc zf3Tll4Z)fJv!5@#3s-!HYpZxiAeHpVJ#rikq{JA}hSx?9MHfEjc-+%zBfU^%gPft?NhdUrzq^>kzXZ-XOvvCcmB|PSrPzq^jok%W^AX zf&IV#nGf%dpYVCF3+uNAzA5mFaK`bm`M*c`9o!9@->=wuYrJ1OA?E!y$nOEqz_$i2 zhg(mKc?+=p+5bgwTc!Q|#9QI^lkEH3C*Udgw4go5-}?u9f5ZC;TJI+&;f_?^|9(ab zuJ`^F_TE8%bYZF<_WlD8!)bxPhLhsO%kaKHyaFB-uZG9O$HC*`v)~ChJ?Os)o|5{X z;b}M&)E|PqrFJ~e)4^o!PolE@UPqmtMaG;D!W%_`7XJQR{!6=kxj#kLs@I5FuN8BB zcV$HIUrzr1)FWoSa8ZOsOn$vs%zAq$!XhTW-YK43Yx$Uu%Xm}mPhM;MKaa38OpCnl z&^`jU%lWlw(@3gn=GQM~f0bFbPIpNE8Qb7}Gi*LjV7=)|yT2_*oi_X1E^t509(g~! zKWrwmz4~Q-hcgf7B4oDLgw(nIC&iV>)0z*3Bf%{E?HjIg*H5O@&q8~804>b?2BgmU zjfgKqp633_d<#4VC!~GR<`IZfF#l8B`4>z54z#BmkT&!0lRD==D1I1unmwBQwA7iO z5kHGO-5~kI77>V(zrWRr-$I_&{yU_899ngX|BF05fuEc4)NdJqIQjiIiR1Wb%UaHn z^)rk9Xzunr|1m!%`_~3JSl@6GKj;3G1*cza|9(;w9&fgv@9YkDUuE+Lz?I0C1?}T- z0UQl{I$V$TX8%189)Kf3{c5-e4h6miHj{b3R(H)#!H@j$H=oM2$!W27C-QVT#N~S& z?#2ACPT4;n_rU&?A&Os9fG=l|J=IP`WzE;d(DWsKIg=&d)X2G7n8rgrmy8R zoNxUp?7e~U(Ej?t_2K_BzMAJ&26=yc8Ef^IkrN5({{E38{%WoMIKED)bNp=+_W6O1 zZyUjXIr-x+kn#SA{^%-H`8=Gyt-HP0e~q+Xj5^(j829IFcxE|{@8JBo?-sM}6}$D2nDv7F-Fk_b^_~*9J}72A_h7ePBxXHc z>edtDRR4$C`Y~&*f3A-Ksh@&6-G!f<^KDCxUBB$F^cB0keuaEuO~iS=951u;WB)Va z^N^>_^WJrE{WuFW?d?dJQ$4BRarKYE&*pA^4{Jl&1~oBrz)ZoX0cF7kABrp;H>x%njPre zE3a_t)ne9*ud&yIk1;+v13%~W?_0P`ywUOnsQ8n)zp7oUzl7``n;}2-2W;PU?DFPZ z9SM5yw{Na^2juBt%*L$GnQPqqtaumXY4d*SAb6l9;{1K1rfY5c)cTU~asOcUy%2#pG}Q^xGl?Cja_0bzdZ<`TG6V zY~S>tHT!Q9vp&%4*2l%HXFu%LbH%Jj9&zh2G3z;xy7hc9>(R&DdV!erx+mOvtC;ns z|8whYV%D4g<<{H9tPecp){|n^2cL24BVyKvo^|V^V%CSBck5$f){`%|^>H!lb4j-z zdfA%w*sIpuzC~izD_?W#HDcCVUU%yqV%7)VaO+7i>(g(!b#Kg?^~gKc9A8Y#dfB*J zuN1T1@V;Ab5wqSi;noMltdD)@)~Cd*XH2^FY%%MFpSbl>G3!I0x%DwI>m{GN^|+Yz zK{40Qh?w=FX}5iunDu@!+YgIbPyff6ZUJ^%C&uOV)Mk6=K%Q z*K_L$G3(XqyY&V!>l5j2eOAnR-G*+xS)7{xMs7VJX1#uqTW=S$9^crlC&a9mE_Umc zV%8f%ZoN&+dfm_5db61I_D$S+ubB0+Ot+p8v!1)DTQ3x|J}2h>k+GT0v)&_Sy-&<~ zLzd06-YRB&YzwzOD`vfUOSj%3X1!>sTdx$e9*Ma10x|0oVvcW0%zD8#Zu_{H^|bBW zdRWYQatF6QA!fZW*R7X`SufwottZ5+7p!pWC1TdSm|M>lvtGT*t+$C;ugZ7pbz;`r zc6IALV%8G{ZoN^=df^^!JuYUwPR#97FJ^sE%=(a+^@>8b|4MPHF3%q=%klZ4Ja60q zC&d4RYsE>pLHr@yEMB-BKHm^8fjh-}z&+xl;eK%f9un8VBjPJzGnwb1*0q)|Qn4zC z`0wj7_Hx%prkLxaxyY@zh*=-l*R2nVuU%_A%ukN3bml)T=JqPs&-QmK+S3#Gxq1G| zD7JOxv&DBIPuEMnN$SkEi620ou9W<=)R~_Z{}Xvy^JS~u@x;YXB2U*z|3gw||4A{| z&+J;Bk@fRD`lH`P&b%)k$M*N9EN=w$@ zdik+#y;972T7_E=iCOPI-mMRbS+73Pt=EZJZ#c=VH;GwKKiRE^#H^2txqOpi)vdw*+r^xJhnV%jwLBolOEkIw34b!@=OM}O zfjS*Rgy*}%;ZYc`3sXKB9*6b&JiX_;dg0upGBV5d{XMnkBHwup4Ru9)%AA#T%PGYcEo=<`PaAMFWvK1 zjpV1$ADzHvG1r&D3vGX#|EQS%&?p_j&rNdeoIH$k4(eC9=N|6y?s^0emjrOy5f z#JeI-Yrb6S%*Vwg$kUpyl{)iv;$xAgHQy?A=G(;8$kUqdl{)i%;){@{H9sPC=10XX z$kV#N%u1d4IdKQ_bV2ZW7Wa?rOSZ;;Ir;DV^2PTdPiz0>QfL2h@ngu-ny-^O^Y!8+ z^7N>TC%@4hPr3L#Y{IMn61!o5JT(}=j%6LjI zcgIsD=K8AVt%wPPq))-%o%s=QBl2`@kiQ8oxoT_Y_c@wjfAaUQR&h7-^mx#o>#M5S&DV+_ zM?Pg){^D!a%8OrN9`2R?!+&)1QSp1o(|W($CUq`1ydet;Ov>BwlAne4iZV za+>W?A$9hj5QmYc$0VP7t=oUGczfhiUSRt#_|sZ>aRKwNp6}bPbMxKe66EPz>3^uz z&5w%X$kUpix!%pE-C&(Sp4NQiMqB6liHR>jp4NP6o13o?Uxhra`MN*5`6h7(@^s$< zyFPPocJoEz$C0P?`&NCoxcM*rXo*iH04mTeYe}Ft) zDWA_a-0kLD#IwlLBe(%G`)kub-F%OD1FYDpN4NGGH?jGW=iPjbcyr_@U%>e<&E{uc zcJmppSg$~yu9WAg_-nS#^;a$48+kfY^3|hmzCm1uJgvX4T0G|F>7HCW{_#)T zeEO%>+@5pk%kW=L!RKomSf7Lb(&0AUJ{#LQm#;&71@iPLE@)=^lw`U2I&nMlG*)*i ze-B&_=gRtN+QMz$C4K^Vx@MuBU*-}w9~N_Y6HDECtvHGP=n?5Jy0x1x5x<8#-MPTd ze{7kXpAvt8Jl!Dumu~CktHld;!u|r+OMYlOH$N%n@}))Hdb*hPzU|%mkoaeqAFY4? zdN|k3Pl%TxPsbM8<)2>R<}>rGW60B!vc5)Qw$A-&PP`BDbhDgKYIk$l}ZjxD9zaEaOS+=jQ9gcOy^d%kfrI z;^w=>k8u3(>_WT#n-6yLo#J8S=`K0G^4GZeQt{i!)0r~<(lVRp{*?QbeSZ5Kc{&3> z=lidp-~yQUxAfu_xE@J;E4Wmg2gk*G!&TCL4O}htrZu>~hL;EZhgRTx1oIn$oZpGa zkHQPEe&}DpV_&bF|9$J=a5EhL(JtTL;R^g~wKoRspND5)vwR=G%?nn||NGnD!-Wf1&3}J-lNiPa z|0ig_9o(_bDz7K--f&skD({@YN5g~gK;U1)jq9$OU%yT8FwEnf%hv(-uD@#j-z)Ej zn>RrFp#C~sx)H`3_%nDSW0kji;PqE7@FE+p@)iYN2FDh!3jSW^VsB5lA+*ZdE*Q@d za2LFLVD7J#E%trv8K~2I-r@I`>flE4<#5$?_I>S5aQsI5{oEe76!!P`Ebl3}820z~ zEbk3?2JQLx7}@`)aNV^w{}Y^pdQmX{O;_Q0@=vzDEnEqk@$C#ZiuZxL#B1PT@$vAq z_)Itx^W*y~j)&``Q{F$

    8Jg{;N`s_sdbI&GYJYZ~_ja5wG{1a0A>HnEhuSX3rNq zKZeB}g$q+Q@6+yIXQ3BG-T1;I7UK8&t=Zq&?~k%KwV#)q_d1SO|<$Vb2F9PQ- zwCD4JBi-?ria%Sk(4$TJ@WVL%#ZREWYIs=s3&-953dB!riuDbf{)W-M1UB23>%T(s zsq3BiZR9KAahcz=)R|8|#?GJpm5EtTh*R5JoN9lp+dh1pHS0y<&oLf4A3x{zU2kXH z-@(zqKZDz0^SLaCzc^&~gnCFb)gT_ycb z|I*E8oNUeKXIk^+RkqIY*NFN2Ol!XH6gNL2=JP+T`Rvo&e1VwH|Fq^C5^la-d=b_U z-6qSMd4`+M7xVdtp2i8%tpB-l+%cgehqoLDc7!_$v?XJ zj23Iof9PIo_LmfYfd1$>R-jqmp$FZ3R6K(`JudG9GM;qv`QionSiYyQe3`cYmRH?; zpLh}SC2wH=lKc0Tcieopcq#I9T%Ks&u$;uYwhZjkj; zGUetg#J@nE9+!Od3pZaVEd^%?s`Fw#>Qt z9x)nDsd^>uC#Yf2?WV-cMaXv2Obh+#=W1G48 zNiq8?-Q2C0iCM4P!mZbfSr28q^|1IFtUtO$##6r3%~y&$k*CunACI{CDlz9D*~YCG zi~oWC=%ID&{xrVa&1Y<9&Hfs8vgY<_6%U|4dK5o5`)9=pH(xDgf7N+zJ-X7G^??HG z)c!4Iy?uAL-X%`;{|mR?BW69cuUj7%v)*-}TMr*(&3c8Hi1jga*f!4JTl5aM z?U_##r^b7PTOSm&9y!Xb*NIc(Jgl`S{#YD_2gOl1DeVj3QK|F&&ID}U@BI5oexKDo-}8M>K5X9iL{7x>4*WdM zKO7I=?-YdX`wza~Ny7Smr(*L}&ikDySl{o|Z?S6r{Z0wSm$T(6@7jL z-e>qzme+tfos;T6%ew~d6t}}=H`(_Y-Edo*eV@?}x1i4FCBA%3dF1ric{^ytY@F-wvUQguMx9- zy*SmsnDwNX^}jtz1H^T{QIQ8Pf(}B_&K-lES!WBfj2C`{#Uil{QH7U;d+;jNzLz8yM0eV zz5Ort{Bh3E@7pdzJqCx-iCKS<=XVIYTpOB}`cn9E8xIo6&lyCRXVbmK@ zFPHsou-ff^R6K$_jgJB5*T>AS+ug0Cm}#8{a1!@7_T%`XYqjr}`nG6KPa$W{pY0dh_NnbB-ry{3PuLvaPuJjm zLc=!mzt8f^U*rDhl5M<3>8}U&C;xogC*BGD(bY2kNTZw25p#KJu5s&4;`(!NzX5mQ zgk+Xy;08AzyU}_OHwJVR8_eWmH`_XwKQ89{Gj4V3nPS%aZg=am;ytmx>0DXf%sbqC zj+p&b+~d|0V%D3xZJln~-R>`kVt#Zne$M0R@^f+hho=L-_FKHK+hdj2j@{f`uPd;> z`%{*8_<7jAf3<&~=>+uG0P}jp`~9=vTsSAypa1!2KlW#T3gdU#uz$(^eGNPyz7;l; z+27-ZcKlrb?XrCLAy0FDW_$HXo%sQAKj*hreoX4jPl$(*r?r3YUb}voPZy6OPisC$ z>dfbgKSrL`e2LV#{kr#dm%mKv-=RG{zK&h~@B{AnV&b3w0{2I72l_SZYe?!GUsAj+ z@^rrBy$9X?)5HbH(^Wx!HJpI^uvyLg(tF+Z5%J;3)1xxKDXDXOv*Ie`>0vp3x*vA? z9~9RiPnQP${~iwYZR7RJ_J*zFN%VC;K(G9uc!19d+w5@g|rbT`j-Am-x`l zw~N_d$;WQJOw9VInEUg%nDxY@+rCE3dbgPEd&I0yiCLc(vp)PE+dn-j=a;2eUfRE3 zTI{WWC*XsTS3Q@j4SenV5%S;*6wL4PaY95@vCP&i-wa(2J8913ic=e z{wN_%pgnE+=XmR+&hgZX&qtmv#?QGv{s0fa=Ka7;aP%|V-<@zFY{tvy-%|0Ts8_&x zJ!pdc$sccv_&Mb1STKK%w@>OE?|}GqONNv0=Z&^+2|7@mFqtrQ#jXp4RnWA$2ZKrMM7zTJtqhXTDav26Cs?3r@{q4;{HSC7yZd? zUno8sdD`snoL`mHxjYGR1M;*vKQP~yIy>S2;QYaSQhY7)bSHjp_MgN8p3OM<`C4%& z@+r&sD;KVn7vIl3oGJObb=-WD_(|kxUEUt4bNs#HmyxGi@N+Z%!Zf%4V)0kV)4Kh} zrOy7R#6KcWH%tFD>$?5di8m_3{T!_OU%%AZ|DZSvd0O-7>$&}h#C#t}Yrb6S?7u?1 zJ^H70|E^l!?Y~Z(f%7xnFUuQEck}t;J+zrA=HucT z_s0n_>yul!?K8HtW_>`MI$p%A*Jay0>-A#RV@uq6zL@nHG273IS#MnGwr>@)KDU-z z<@y}M`l5L~=lymO+y(P`OP9et@OJC?J_Q~;;u$y}<{IMt{K9>4yh(ji zxbQyve6Sp@hpU48Zg3_X4SX=1-zDQYV1d_gzkOeO^JeHDHu;m0A4mJTp#5*)(BJHM zE`hxso4*N;!e;$E2zQ{r%Aox-aMJ^Jey_o$uz8;0`{6mXFAMS?pgsVb`WJAc_$N4D z@;~1X;|V77ypy(--M=EJ(_v)H^(%qx?N5unRj6m9-YVz6&aG{G?!P_aUm#DH1pSr5 zvv6DBW8ju$InM827j5JAS1djgd3rQxAIJY@=D7K6@p;J8`o3s*TQ@%tcZbNf^UDzM} zDa-pG>NH2h<8K2z|8_lSkGG|8J8bs%UE#jJ+x>e#*i2@B%-q2)-x}0u^E^@kN5#K_ z3*j(2;rhA^E{79=+u?qgJ(~S_4E85~dyR`9M4mSNy$sL7roT_&${pSQ8er2O*U#J` z_ITlXY?S&!JRj0#d6;jNI`eJfpCM0czDw%NcZ<`Jr#0U%b>;`eTOv;<@pG=9e7Ggo zz5kBwWS5Wa^TmfFPtOGHxjZ>5+@GeEOpMWRosOu+RNH$N_Z6M1?H*K4ys5ANaShs7TuPtQvKJ%w(5Q2Y(@bd9W^*q&}aU%WoH z2d()IsdIgHiZ@4|HtQ!BuGrgs9!M0q^Q#jdggjlpu3i3))oy-9d=&C@C|I5ZoVLF` zJ}!d8u&G}KN8!0(eO(Xdl;k+?pVMG}@_+xQ_DJ`5XI|^G2U>G|cn4W?dsiN8&3Z!I ziTT&U1G4=x4{`JP;zy9DH9vZ&o1YQCf;?@Om*Yv6x%p`^>l25$^+_@7rR8otF8&bn zqx)t1O&{atGmo{NMxKt!{+@okt#f_-Kep~apx62S|M-Q@IicfpoX$BRbapyUhmdnZ zBNNMnObD4q$Ye5^W7^ipWNS2Hp-m$bGWiH0WI~$|%Y>-~CM z=j-}ob32dc>vg@Z-`D$k|ENIx4)x|v{@ooPW0G6_gm@wMcjgYMuRA%~e}i~CyC1|e zvOP*GqxH4oJ*hX3OMUif(fShcH>fu!$?|5N5v?y3$M&D^MDuE~h!c7$4f4bC}!ePB=I%{Svp?B0Lq!Nb_bVfk%1`-JtuS)s4Tt=P4{9}nSgg}IGy zjQgATv@-YudDbKTe&|I!{gA&On#OaukOp@DlvK?1Q1YE{x8(cc{D*z}!*LOI?JIC2 zE)DxT508p}hN~ElyB}-CwKBe&aSyHv+uwuJ`h9<;)*ie0orXIlzYx!gAID9yJb%Hh zVq0H>@_znXk_4W19`WEp#_2vwzZ~aNM zzFVAfIL9N_`ksrT^+V!S)SLDGxaZ<%eZP25>SLDi^fYWzFaE04o3;LuP3py8w|YDv z*WZ$#N9*gwM^bMdl=}2vM(Yd3Rn(hxd9$yK*5`>gQg7D!jH{yc+2RK3&03$@60Oe= zUrD{WFUjw3y{*yuQSoimo3myApSmtuKQHc~-mLYhzmC>ti65rkto8XfMC(h$gVdWF zWIR2;jn)r~pQqkDEA^cn(fR@L81?27x!;(+C0d`->HRkKW;@Q^@mndm9lurLkEl0S z$>&>|@AUmy{g8OU5gaeLd~4tT$l*81he?C(A(p}>h-~Gq4&a5 z`0&uhIPa|W!9k&Id5a$P_oJ2MS%2`KpQ*(&cpz54GPnr$V)s1x3Y>=R^|9Tb{s#9v z=ATzv|0Qeu=P`T9%}KHP^x#=sD!vn!iJ!pb;!6v8zff$SU#=97QD22e!v5dEZgS5L zlVA7S`$KYb8bx-#+U!WK2jXQo7rWo z)_=y7ufK+Ra}odU##1J_)mMr;s5fUzeWT=7-z2`9dUJkQKZpl#YUsb<5$v{??Ozkp z-ujyqk5g~13ENx!RE=N1?~<3kn-%%KNydAAd9A-J@dwnKN2R|R$*q1){0a4D9t+3T z*CM`8P%xbp6iWMzI6lRnH`j~Ps5kdWedfQS^*Q2o)SH{7zDIH!U!Qn?>djhT@b75< zMdHJ#H@oA()@Qrq)_=G7+tiy&WIQvH$JUqlyVTF&BB{@NKRTWQ@z1C?Yki&M)_;Te zchsA8{9}?^{gl|2ulPUF`B#d2>CZea_rEhAN9zmbysf{EPrYq^ed5^uDYkq@YqzEW&?i`eouvE>!>(f(`2mUoD)eV5qsn$M%{8^o6Ph^>8}*z&snMcX%v zE$D1Zv{5hO*&iddu?x)SK*p8L zo2U7AcRd&l)`VTe&u3HO-%@Y3@wobwjlTc?BhT7wO^__tyNu1F{pE-sq28Pl_BVv{ zv27pMe~HxF_)EnvQEx5_>)*niI7iwKOTD!p5r06vSwHVLniL)HwAj{v!GdUBD7Jh+ zZ1WowTi&?Pw>PKB`de7a{TM!ke|P&^E&Eq|S{W=OFZrXtzuN^DVq1T=hG?j^hIlehA_ABwc_{`-yhn<$I#w9K!Npl5Z}itPhJ!G zzI6G)e*ZX~`eE{_u-^L5+A`XIuDFl>%vR_2hkD6v{Wgg|XZ+@kQa>lT)z6DBWIW~p zsqfy(kH_ZQA=}5=_e*|0?akHldOTyXZ*TQk;#hxT%e%#vXKv%$n>%Ix_I|&47yjM$ z4|{)q7_SX&@BhzY_jTSI3smU;`3<>j%Ix?T@y@(_1oc& zZPz63Pxrt>xFXC8aMm)vzkd@Kh)>65xG}8Xh{v$oe}0Nf(!76#2XI|je>cuw?#F)< zF2pTieit6Wv!QK!^sVsQ*Vf0N_(|%`&0+l*E?v1M@%fS|+<>RT{6k!wz9w=%JvPfu z5S!xHtGWyQ@wde>+>cT}9j;#+Px(j-nsW-RLuiO6JlH2n3 zi1()6TqN}~l3V?(_)zN2#bNzPxFCb;kt|R3j?wYeiL0qMXNT=Cz#Z6aFIyj(J4M^) ziZ7<#+!VIA`fkZ>ynW(dP;VXx$9JR6KXXmw@2?E5iq3CbZ2fn9C7Sn$@1{Rp85|q!KUMrT_2vwz&p19>pCkU5dUK(yuaXm@^)=$Hc#vb( z{j0e=THht!o_e!=ztt`8^oh~>d2tT)<|L_~`&P6*ILSNT9xUN3sZX!)xvkGEaS`?A zD%oCjCr9g>#D`IDZjk^mwjjQKF2K2G;UvGl zD$a?vZxlCDZ!Qem+wsx={b>E5_*c}MC#ZAVqwV}?eW&;)>dpH7(6S#y>ubeb)SLDE zF(vTX0cpGWIQ#BWh= zcGpW=pEXU<`dYE&U1A$=x7hLlvE@Tz%jbU)?LYN$Z_5kC*1kw=`Iy-9DY4~4SNQ%c z9}`=i)Ev!I#Fpp%GMX2OEuUE8PJ`bn;Xnk;L=u2@M-Zk{~co5&nVPXAs;i`K7dvSeu2HWd9%b&$XKk>ik z@j7n8?)N_4#{)Pwtl#W7+T+5|w*F?hpN&r|gEaDvXZ-zcHqLq0zyAIz&cyD1`3O$D zWq2mm-^$=H@(F4GEnJ1O!n_(cVb{JMw~B2%`SN=H(!#ho9kRUXfju8DATNxqpY))a z_VsK1>-}r7o80UD+>8AEp6y>XvcKFyy;-jZ1Fe34v+;~w9Bn@$c|YyVL(JBlPg}3^ z?QMQ-;^(M0=Slt0_0jra@tf3}ZGE}^MwgZh}m z{{L;hljjq%y+-efwx1M#LcO^@Y`^shoImg8en7^XaZj{;mUt)X&4n_*viqX-RpRy3 zoBP7`Z_Ah38?Da}7f^3blkw!-AFa<7A4$DAMfRthzG!`c_zddJBXYkt(;ux*dDQ#I z)SLDGs#S8^{_WzQQE$$W@pu2h_h(j)xzvPH*{pE=*pBGym zJmvfQg!!2#WP6MZ`P}L!#MWO@gTMZymUH}LcR!PfQ^mPB19Lka*!@8v&XU}okL6-_ z|5Hj{j@|vow{RoQ3ftG>F8r0yKgGk?eLwD6JdatN*!=Fm!6n}PI7vK$lf{3>Dfqsy z{fBq}yYVeLk>_zzzXP7eH-`25;pU(E&j%cb^DbQ<+#lxWTRpxgw5`vgVSm4K6?y&( zdk2}Zd}VM8E*C$5>%=3)eE#BjfB!N>J|O-p9>($Yw=(z#o{{`xJn|RcKKWbRFVVld ze_Db2aCSJJ)p+>NzCI7P$#}kjyGH!{%B&u{`>Rv&nB?c;dC4!v$@J&yTW}h7Bes0zuhD#7{4(=1r&DLw!%3X>s`o6;!Kq=s@FbQGw})Pe$8e@xZ$`(X z^P3azOue~xfxrIdz80;Y7u)!o{vOS{#koxA%ab=9tuGMwP;b`yddY2k zjp9M-&00Swxz!JgN2xb!eagS0<4F@wQE%4zGRdv~3h_MkX030R-0C~U+f?v8Xp{O$ z$*q1`{1xiWEwaCEd_Ow=dT~DW<}Uhi`%}hDv_4B*M!k7N`k(qBT0bj3hkA3B)E9pk ztuGhXQ*U(6lyZV1QMigRaqKO;Q5Dk(f+dLy>Fr3toO%t|MR)6zj|>W^=4gv zNwKRVg`B^vK1KXA^=7Sa-OR40HpT1P#pBeQ^TPAP`*>uFT_W$_Wi5=h&li7Ay}6R! z-S%pc+{V`?Uh-|OUwB^X>la1)Zx!!Ey;V=*fLr_D&CiRbFtLV zZxyZ2*xLJG>dl2oetAnIx8+Sw@%6SplrHhMyh3~={h15p{5&MN)iu+$mxAoV!!rSt3vE^MWqj~lA-j-+Y;BD<|#g^x0MDxC# zy)AFe^ge^-F;6b=%hU1|pId#!YHyogdX~54lVZzjc8TV7;#%fsE?DU2SGYD>pOWou z{dJ0MezohOc~g$J<-Ov1=4US2($8;V_h^0h9^N*;<~_Zwzw%sf%Zt~0Tb{PT+wzIM zy)B;;U(R^U6EdEv{AhjdSG}#jR61vGt#PjIXzR z_&D#_`Vm`Rd_puY6Fjt;#7S7P^kJR5i8JDH!=?~lu`_MZ>`Choy`Vf!jPi3>v4&cSuqz5cowH{#@2 ze=CC)+&}6+-*gi$d1>$1`=j>xlY4MIxvT$!wa2c%XK@R5ujl@Xd!_yz>?Zg6Zb%IM~J$b7f&lQz^|FivnqxdlD z&81;~C*eU{BmHNe8f~8|{x0?AHmM(w+~zkVw(%C9=KC|Z%lI4U&wL>NZu`rXcpO^` zv(-1V{o>Qg;5PD#SN!vZK3tEpWA!V8XRw>x`xQxTetp^aN@P5*P;aizh;NT~aqCsP zBtEbB1w%WHZyTsR9`#NzI_2%?&e&^v9+!>D7)?bIzTl-P5<=K};`_B{q zl>W>U)Vbv;lHB^M5LdhU} zf5jEi`daZ6^=AEjvyop$>&M0RL1MGsucxs;$EW!E$P{N#Z+4$Yv-Q&~xvhUY9$b6N zYuNvtEw|&r+42lKUSd;xezD^xbS%GSlU%$fIy0KfY)E|6!M4 zM#kH5SG0YPxRLt0$9IYRy~bL`7oXzGXXACY@r*v=ZR4F0Uq^pteLpXa@wxU^Z{u~g z{^}U7v*k8^XUi)YpR?sQUT4eGhP*A$7vIi!%=O%$xZ|xta;qN@TYteT(f(@0mN(5s z^L}wJ^XpAo8~OdhVBuQpl_|bH)5O+akJ!f3C$>C!QM7%k*z$3)wVx7O-kcn5-zK&^ zW6NlsCAK_ot7u*zwtP}-^Pd%4-n4bJeXH2=+>~fuAhvu=Z2eD)EiYdjZC@$2d{k`h z$HkU+Es3`85nEoiG@4h4EpOd6nzxHB&srAEbH$dAiet+sw!9`S+P+R~d9Xa1r-&`@ z5nKNQV#|kCMB9&uEiYIZ&5OjAkBDRIS8RE4dbEA1*z!JcYHhcTiz|U`S*z}FWM>EzEo`a zfY{m(i7n6HIoiHZ{21pea}yt+vh(9GE;wy%&>nui*4n4-8Es#b>-{?QW9P0-{Qkl$ z&N*>yFc4mUl1}IT`vU40`Sb6@QNF#6cevDhTk407UmLk!OQFB`6hD7j|IRkP!IQkL zziIJm`ZJd<^z)xSHCk`WtNqooJkHjiEuXW^uiTa=HpRyiTfWe-ynd5hyr-=XoW%#i z-1R8y7t#7QvGtd8M>KE$y|?B4&v@H-`=0f-yy^vS%WK4zkBKdx6k9&`muUOoMQ_WC z#n!%5Yrnluy;@JGfmgl|a>n$%6TVC;L zG*AA_+w!{4qi&VgBbIma`Y}GO3<}u(W*$fLl5b^j6z&qAio3CUK5zlVX<1*~}`y5w_xBL#D{}k_x>!f`yuE%bD72-yzKN`1)Ps8m} ze;)1>{{(l7e}Q|&zsCL8jrTe{gx&JqhKI%X;Sub%?+~64zlmqC>+ipK9`pDpcD`72 zCfn<8KHnB+Vb|X(oQK`==i&nK0k}wfBrXx3g3GX*e>JWY*WnuR<+x6K9c~oghFioB z;CAsdxJ$futNmVzpa1LR1LF7au=u}tOuTtD&!feQ@r-ySo)_BAD$L3I?FyUC3)*W)_u&NsK>2Amh3uX=E= z)IWp=#LwbkvE45<@cn@Jlpg%m`jhVq{2e!nKg3PqEzain5HH6q;!NBs-V?Wpcg5}E zLfj$#Chin}3wMdn!rkKU;2!Y>xL5oO+$V0t{o-rzfcUp~Q2cv5B)%07i+k~i_%S>x z9>QbdQ9Lf5z!TybJSm>XQ{v(p&JW_P@QgSO&x&`(bK>3cym((6Wc%-nd>to=kHN{} zZ{rm4cX6ut2RKc92~HPZfiuLdI8*#PoF%>+XNw=jIpRO#T=AOar}$7!kyxD+$CO( zyTxDN9`V-aa{P;*BJUIb1^0{h!~^0pXg?@E7Y~Uq!o%VwJR&Znzftj#cuaf%9v2^u zC&W9^-=sJPPl+q2pBA5iXT;~@S#dp{6JL(!#n<6roj?9>$4TP*aI$z1r-=WIQ^jxK zH1R)ix_BOEh?7~qO!0O&OS~3mi}%Ah;zMz+_*k4L-mRA7U%U@45LZ!ODE=NU68{7j zi+_$w#Mj|caVIVl-;K+~H{%L%H?9=-<0|nWt`@(5Ys9bOTJaR#D4xM};?Hrtcp>Yf zL7avg#TmFsybd>u^Kgs!P~0j$2DgceaJ%>@+#x;%cZ$D{yTq5_ZgCs#5#Nq`#XY!B z{3z}h58(mv%Xm=y4?HCP7!QlLJdfjFyd1m9eSV}xo?pGd=MmiG^1lE1=UW-HH@8vd zo?m9iJ{@7L;?F}%#d}k4=4D-?e&lz%hqG7`978@yuD@S2C++QdT;*ojVSW7X88mDj zb=GwB{r_MKpI6%Q;zoHtv`}*Ee?lC4p0~iax4cpOUHUV(%JL^Kiq@x#H&Sn&q#w7w zW+b=%=fzi3Z+3ql_+~t{RW|SG`St_bM&~yoew2E1nT#(ZEn1%?evx|fpwv$+kJe9# z-?Q=HIa!}W>CyTL@h8-qOL!n+%YQy!bk5l^JLr}9mE-sn-+yYwwmk-SislpIZN5+c zI7dEjI=wntpOWRBMZI}A*{{!B$!&WSi`P>>mXn=$f8EA2w8r;m^|`xvA4Gk@9@+l$ z&p3b2?8xT_xIv_qP2uq(w*G6x*1yd^KE?O{Ec$o0+~((O?Q@u)v*k8_=h*t(%iHo% z@!5>mJh+u#Kk4hE_4Q)wFRdV&w}~z95!?I*#g?ZY5N)3+{t@HJ{vBtSRq^rs9M}Ic zJMsIMZ8)VeJE-5;kGJQLXn!N(Td6nC^Mcy;#|QE7G1kqswpA%=$U(?0xAN;#JpOw}{>nFsvzAAqh z&1b}x7dJ%n67e3)&pagaOSvRkpC;aqdUL&ezNVh_7oXzW)7Gc6&A*EM$=R0I_Ah74 z(^-GcmfQMtwtVm=Z_DS!Co&#$PI$ijE-rmCJMw*!O!jZrpS8FB-P!tY7F(WsOEljo zwmiKvnwN?#?-tiFo~}Q#zlP(x9M3(K9b|^!PO+4{Hj z;cR&t>%-Y{TR+a0H$U%fdAr#1@<03BTq^f3J+^<~`1@N+f`@Sxjz8aD55Q>lpcIUZjQfSksi!rH@W-23K{Rhjl4d< zwgm3@A7=jXX-SYu-e~o5eXk$!%WLbSQM}6Pak89$n_l+yHr~2%-@mnQmV7vAa{rS~`}h>! z->g693#gxFekF1}O?}tr)_=A5r_|?v7`TGn>8QJ zi&(#|-f~;t&encTYC$ohBnvH6Q_{v}JId9T>= z?v>Hp){pDY@>;R=KPI+3mF*Ru;_J`0pR?sdVr!qfb2Lw3e{}Vh+y3cn?FYn`XRnFo zN$gLq-g4W&oUMJyZr+yniY@QSjpnw$#;5rD&lX$z7O}POX8(2dmfQa9Y@|kaVTYEd6G|%RERuBI>dVaU#UGp@~ z56;$~oiChieq9`&&X(Kp>TLP^QQnr@@v3=nw72DHVryS{jL*$uGTsw7zRm7@dn%q1 zpN;3R9l>_J{sGQ>-+zCq0hfs{$4!{q^;msuesaBTB_EUP_04!(d@r6558z4hU$C3p z^}SA(Z-U%hO_5y>J6`7bh6CX`%RqAzq{*kj^tLKD_%yu*{*M{zEEqGoi^3oH0UW^B@{+@Eyx1#-Li;t$>JSO+ov)_)^2PbtcEa{n=ZiqCC%d0=b* z%d|MyCyTk z@nzJTo2CCD$!&Zi;%lilCx`XF!(+Hs)?fOW(fJjNd#E=@wtscBextabdNUu}O6*@l zXGQDB#6vb7Z1>x?{zmbncmmIer|~?_lm4^Lj`p7`o}=EZ_2o6u`YLf!9j_nE;r)

    )w>cuHmkL`SB<4?yM#aXx!XN7q#?!xZ)I|%pVnlQKdWu6zEU$(e}db8{AL|lU1 z{&yCx#dl!l{+VAz>yui&PoUo1F6+NlavM*FxQcpn zz0{{(>-)3%3~?>>=3;q$nQ>FJzDnFgy}3Zf-_#MU?+~9b&iL?%TyJV_iPqPOZ=ip3 zi}XL+8Lba)_5MBe<}vAi;C7$e@{Wn^eA0NQ&&~aEztKm3!#Iv+=mNNHUz7~@%{x@F5VEV2|bOQw%HJ*g#H4zF4+)#684|=V_rX}ZU}xGIveLM z-4J`f%KAS5H*UKj_V)qIrMPCza#k%MKfYi^KI%fm3(fkof(9@8cT0U%0-1fx9v{#QwgBwQt8Mt2V^m z?=atsC-B4J{GY+?U!i|Dew?v-LvUC)zyILstPQ~>VZPue>`(aTq0{lkH5(GYcWlQ~ zjyylyjlA%ky@SkHJ%8^92jZq520^BH-!r&BeA7Q~ytb9sXX090Zj6pzN5 z#n+LyVK=`{+%Nedn*P{A|57KOU`b7q?Sy=C&?2zPoVU6Wnjg_{IjK?PtYLQ*X|e z`sqJK>ocD6w((>QdE4^li7hX9I+~Y>EpL4$nsF1*LDbIUbe_12mvE>n4KKnv6PyUOy<@KZ9*1lD2dELv=yi;uXwAk9uh%MjvO0<2Q z*z(3PpPT39eDxvg!+bOUZucAMm)PguHUzt{e$4yhp>7vn~J zZ0O(NF??9)Cvn#98-i;>zm5Cw6QON9mE2Fnr`YN0+{rwPklNW^TZT?d{FO5&>!S&W&o}YH%Y4QDdMm&h! z7)OCeX3v!}1O?ccshf1ToYzNCG}QU3FH*1k*X zW6QsZXJvhSNPp%}X~&b=V6#i3%WLi1CimcfZHhk+F3t1fO`+c0$NPV_e9Q32*ER&X ze7-HVzu}6seS%_I+xA+8b8v3xUGd~HpKrhg*v|h}Uw~7vt3Lz}ZtLs6iR;BD;LfG{ z1Y=?QN?e31L!X7q7Vi_x#O}{m2H(fCDL${qgIhAcF#j2DHHYn6aFzHsI0?J{JMn0; zum3+>gj>S)eRz1$KC$~LTfQf7BX;X&7?)u;zn5`}S#XrCsv8!*uIpWK4?`D3yt+)}p^>-sKz^;84uII0_xbfbL`@isikGvoE{*UiJ z#g140zM$2AzIW{XW7}RMczWLd9^9+A8CQnOKZ(<@TYvw??Vowi;R5XHH@}SS_o?qM z1=nLY{uMY0yZ$n9^C#ZB;tK5Q^Kg#%Yj|>Q@5J&K<6i9QkHKZwji&;qNd0&4_{YA! z7I%w(gzLqPxI}y<&JefZ>Hqrveuq1;+dkd62)pq-fagE*`2fzs?)ZKNchCCuF^ZFL zSGYZ1$NeAr_EWeByY=}WJpUh`&*NV4!k=-y5~t#f54iq>`^WaUV#e=3SvU>5<=F%G zzVDYOA2(vR{tw2p|MuIz1b1WC{&-x1-TJ7+8Q8V|E*|}tuiuE9#TVhpX}><2a65MW zUxQO{OSrz;ane8i{(l<|zOfKYIO6qsU)#7!yM!W&niVwgWadJ4`Lvg+2 zN8<+ZNw`t!&%n)+pNm_>Kg6w4e<^O4{Fk^xd_C?I-;BGY{hhc+d_V4!`p0m;_-Q;K z^)KQf$zQ|6lK%sbO8x;J6Mu%s#S5Bv9wJ_XC$U?f+u>=+SK}G+?s!(bFP;-0gy*sA z?+Bc9sNcVi!^zm?r{Gk{&%$Zq^KrWPCpbg=bDSx@8fRhG{|z`t@>_8(cKiR`xKQ$k za1nOFUxrL=z&SBd|LtHmGT8u1snR=gz-t~X*gzh$^yyd!Ru`n9-8 zyccd37vL6Ye<*H~{21IW{xvOxek86IpMYz{r{X&7mhWs_FTMabh%d&C;$Pq< z@vm^R__w$PyZ!HW+=ktF@4=mtKZ3iZ{U33U)c+axi~ov;r2SiXMB4ugkBUFWW8%%O z;Cv?Sx5ks=<#<}WGoF?9>+l?Q%d-I|9kwCyd7%Sv4tC3bD9*!feIJeUB|ixlN`3|| z5}%8UrT&MwRPsx4nfRBuTzoyQ!0vdt8Q0+S@cMTrZj}1_aT9jS_ZV)K{At`K`HQ$y z^4D+|cFX?{+#~r1xL5MeaKGdWnz?>Sz61|Rz8xMGuf`+d-SMb+Upyv02#;eoz9aCY z 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 wz0 +#include "pycore_initconfig.h" /* _PyConfig_InitCompatConfig() */ +#include "pycore_pystate.h" /* _PyRuntime */ +#include +#include "pythread.h" +#include +#include +#include + +/********************************************************* + * Embedded interpreter tests that need a custom exe + * + * Executed via 'EmbeddingTests' in Lib/test/test_capi.py + *********************************************************/ + +/* Use path starting with "./" avoids a search along the PATH */ +#define PROGRAM_NAME L"./_testembed" + +static void _testembed_Py_Initialize(void) +{ + Py_SetProgramName(PROGRAM_NAME); + Py_Initialize(); +} + + +/***************************************************** + * Test repeated initialisation and subinterpreters + *****************************************************/ + +static void print_subinterp(void) +{ + /* Output information about the interpreter in the format + expected in Lib/test/test_capi.py (test_subinterps). */ + PyThreadState *ts = PyThreadState_Get(); + PyInterpreterState *interp = ts->interp; + int64_t id = PyInterpreterState_GetID(interp); + printf("interp %" PRId64 " <0x%" PRIXPTR ">, thread state <0x%" PRIXPTR ">: ", + id, (uintptr_t)interp, (uintptr_t)ts); + fflush(stdout); + PyRun_SimpleString( + "import sys;" + "print('id(modules) =', id(sys.modules));" + "sys.stdout.flush()" + ); +} + +static int test_repeated_init_and_subinterpreters(void) +{ + PyThreadState *mainstate, *substate; + PyGILState_STATE gilstate; + int i, j; + + for (i=0; i<15; i++) { + printf("--- Pass %d ---\n", i); + _testembed_Py_Initialize(); + mainstate = PyThreadState_Get(); + + PyEval_InitThreads(); + PyEval_ReleaseThread(mainstate); + + gilstate = PyGILState_Ensure(); + print_subinterp(); + PyThreadState_Swap(NULL); + + for (j=0; j<3; j++) { + substate = Py_NewInterpreter(); + print_subinterp(); + Py_EndInterpreter(substate); + } + + PyThreadState_Swap(mainstate); + print_subinterp(); + PyGILState_Release(gilstate); + + PyEval_RestoreThread(mainstate); + Py_Finalize(); + } + return 0; +} + +/***************************************************** + * Test forcing a particular IO encoding + *****************************************************/ + +static void check_stdio_details(const char *encoding, const char * errors) +{ + /* Output info for the test case to check */ + if (encoding) { + printf("Expected encoding: %s\n", encoding); + } else { + printf("Expected encoding: default\n"); + } + if (errors) { + printf("Expected errors: %s\n", errors); + } else { + printf("Expected errors: default\n"); + } + fflush(stdout); + /* Force the given IO encoding */ + Py_SetStandardStreamEncoding(encoding, errors); + _testembed_Py_Initialize(); + PyRun_SimpleString( + "import sys;" + "print('stdin: {0.encoding}:{0.errors}'.format(sys.stdin));" + "print('stdout: {0.encoding}:{0.errors}'.format(sys.stdout));" + "print('stderr: {0.encoding}:{0.errors}'.format(sys.stderr));" + "sys.stdout.flush()" + ); + Py_Finalize(); +} + +static int test_forced_io_encoding(void) +{ + /* Check various combinations */ + printf("--- Use defaults ---\n"); + check_stdio_details(NULL, NULL); + printf("--- Set errors only ---\n"); + check_stdio_details(NULL, "ignore"); + printf("--- Set encoding only ---\n"); + check_stdio_details("iso8859-1", NULL); + printf("--- Set encoding and errors ---\n"); + check_stdio_details("iso8859-1", "replace"); + + /* Check calling after initialization fails */ + Py_Initialize(); + + if (Py_SetStandardStreamEncoding(NULL, NULL) == 0) { + printf("Unexpected success calling Py_SetStandardStreamEncoding"); + } + Py_Finalize(); + return 0; +} + +/********************************************************* + * Test parts of the C-API that work before initialization + *********************************************************/ + +/* The pre-initialization tests tend to break by segfaulting, so explicitly + * flushed progress messages make the broken API easier to find when they fail. + */ +#define _Py_EMBED_PREINIT_CHECK(msg) \ + do {printf(msg); fflush(stdout);} while (0); + +static int test_pre_initialization_api(void) +{ + /* the test doesn't support custom memory allocators */ + putenv("PYTHONMALLOC="); + + /* Leading "./" ensures getpath.c can still find the standard library */ + _Py_EMBED_PREINIT_CHECK("Checking Py_DecodeLocale\n"); + wchar_t *program = Py_DecodeLocale("./spam", NULL); + if (program == NULL) { + fprintf(stderr, "Fatal error: cannot decode program name\n"); + return 1; + } + _Py_EMBED_PREINIT_CHECK("Checking Py_SetProgramName\n"); + Py_SetProgramName(program); + + _Py_EMBED_PREINIT_CHECK("Initializing interpreter\n"); + Py_Initialize(); + _Py_EMBED_PREINIT_CHECK("Check sys module contents\n"); + PyRun_SimpleString("import sys; " + "print('sys.executable:', sys.executable)"); + _Py_EMBED_PREINIT_CHECK("Finalizing interpreter\n"); + Py_Finalize(); + + _Py_EMBED_PREINIT_CHECK("Freeing memory allocated by Py_DecodeLocale\n"); + PyMem_RawFree(program); + return 0; +} + + +/* bpo-33042: Ensure embedding apps can predefine sys module options */ +static int test_pre_initialization_sys_options(void) +{ + /* We allocate a couple of the options dynamically, and then delete + * them before calling Py_Initialize. This ensures the interpreter isn't + * relying on the caller to keep the passed in strings alive. + */ + const wchar_t *static_warnoption = L"once"; + const wchar_t *static_xoption = L"also_not_an_option=2"; + size_t warnoption_len = wcslen(static_warnoption); + size_t xoption_len = wcslen(static_xoption); + wchar_t *dynamic_once_warnoption = \ + (wchar_t *) calloc(warnoption_len+1, sizeof(wchar_t)); + wchar_t *dynamic_xoption = \ + (wchar_t *) calloc(xoption_len+1, sizeof(wchar_t)); + wcsncpy(dynamic_once_warnoption, static_warnoption, warnoption_len+1); + wcsncpy(dynamic_xoption, static_xoption, xoption_len+1); + + _Py_EMBED_PREINIT_CHECK("Checking PySys_AddWarnOption\n"); + PySys_AddWarnOption(L"default"); + _Py_EMBED_PREINIT_CHECK("Checking PySys_ResetWarnOptions\n"); + PySys_ResetWarnOptions(); + _Py_EMBED_PREINIT_CHECK("Checking PySys_AddWarnOption linked list\n"); + PySys_AddWarnOption(dynamic_once_warnoption); + PySys_AddWarnOption(L"module"); + PySys_AddWarnOption(L"default"); + _Py_EMBED_PREINIT_CHECK("Checking PySys_AddXOption\n"); + PySys_AddXOption(L"not_an_option=1"); + PySys_AddXOption(dynamic_xoption); + + /* Delete the dynamic options early */ + free(dynamic_once_warnoption); + dynamic_once_warnoption = NULL; + free(dynamic_xoption); + dynamic_xoption = NULL; + + _Py_EMBED_PREINIT_CHECK("Initializing interpreter\n"); + _testembed_Py_Initialize(); + _Py_EMBED_PREINIT_CHECK("Check sys module contents\n"); + PyRun_SimpleString("import sys; " + "print('sys.warnoptions:', sys.warnoptions); " + "print('sys._xoptions:', sys._xoptions); " + "warnings = sys.modules['warnings']; " + "latest_filters = [f[0] for f in warnings.filters[:3]]; " + "print('warnings.filters[:3]:', latest_filters)"); + _Py_EMBED_PREINIT_CHECK("Finalizing interpreter\n"); + Py_Finalize(); + + return 0; +} + + +/* bpo-20891: Avoid race condition when initialising the GIL */ +static void bpo20891_thread(void *lockp) +{ + PyThread_type_lock lock = *((PyThread_type_lock*)lockp); + + PyGILState_STATE state = PyGILState_Ensure(); + if (!PyGILState_Check()) { + fprintf(stderr, "PyGILState_Check failed!"); + abort(); + } + + PyGILState_Release(state); + + PyThread_release_lock(lock); + + PyThread_exit_thread(); +} + +static int test_bpo20891(void) +{ + /* the test doesn't support custom memory allocators */ + putenv("PYTHONMALLOC="); + + /* bpo-20891: Calling PyGILState_Ensure in a non-Python thread before + calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must + call PyEval_InitThreads() for us in this case. */ + PyThread_type_lock lock = PyThread_allocate_lock(); + if (!lock) { + fprintf(stderr, "PyThread_allocate_lock failed!"); + return 1; + } + + _testembed_Py_Initialize(); + + unsigned long thrd = PyThread_start_new_thread(bpo20891_thread, &lock); + if (thrd == PYTHREAD_INVALID_THREAD_ID) { + fprintf(stderr, "PyThread_start_new_thread failed!"); + return 1; + } + PyThread_acquire_lock(lock, WAIT_LOCK); + + Py_BEGIN_ALLOW_THREADS + /* wait until the thread exit */ + PyThread_acquire_lock(lock, WAIT_LOCK); + Py_END_ALLOW_THREADS + + PyThread_free_lock(lock); + + return 0; +} + +static int test_initialize_twice(void) +{ + _testembed_Py_Initialize(); + + /* bpo-33932: Calling Py_Initialize() twice should do nothing + * (and not crash!). */ + Py_Initialize(); + + Py_Finalize(); + + return 0; +} + +static int test_initialize_pymain(void) +{ + wchar_t *argv[] = {L"PYTHON", L"-c", + (L"import sys; " + L"print(f'Py_Main() after Py_Initialize: " + L"sys.argv={sys.argv}')"), + L"arg2"}; + _testembed_Py_Initialize(); + + /* bpo-34008: Calling Py_Main() after Py_Initialize() must not crash */ + Py_Main(Py_ARRAY_LENGTH(argv), argv); + + Py_Finalize(); + + return 0; +} + + +static void +dump_config(void) +{ + (void) PyRun_SimpleStringFlags( + "import _testinternalcapi, json; " + "print(json.dumps(_testinternalcapi.get_configs()))", + 0); +} + + +static int test_init_initialize_config(void) +{ + _testembed_Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static void config_set_string(PyConfig *config, wchar_t **config_str, const wchar_t *str) +{ + PyStatus status = PyConfig_SetString(config, config_str, str); + if (PyStatus_Exception(status)) { + PyConfig_Clear(config); + Py_ExitStatusException(status); + } +} + + +static void config_set_argv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv) +{ + PyStatus status = PyConfig_SetArgv(config, argc, argv); + if (PyStatus_Exception(status)) { + PyConfig_Clear(config); + Py_ExitStatusException(status); + } +} + + +static void +config_set_wide_string_list(PyConfig *config, PyWideStringList *list, + Py_ssize_t length, wchar_t **items) +{ + PyStatus status = PyConfig_SetWideStringList(config, list, length, items); + if (PyStatus_Exception(status)) { + PyConfig_Clear(config); + Py_ExitStatusException(status); + } +} + + +static void config_set_program_name(PyConfig *config) +{ + const wchar_t *program_name = PROGRAM_NAME; + config_set_string(config, &config->program_name, program_name); +} + + +static void init_from_config_clear(PyConfig *config) +{ + PyStatus status = Py_InitializeFromConfig(config); + PyConfig_Clear(config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } +} + + +static int check_init_compat_config(int preinit) +{ + PyStatus status; + + if (preinit) { + PyPreConfig preconfig; + _PyPreConfig_InitCompatConfig(&preconfig); + + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + } + + PyConfig config; + _PyConfig_InitCompatConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_preinit_compat_config(void) +{ + return check_init_compat_config(1); +} + + +static int test_init_compat_config(void) +{ + return check_init_compat_config(0); +} + + +static int test_init_global_config(void) +{ + /* FIXME: test Py_IgnoreEnvironmentFlag */ + + putenv("PYTHONUTF8=0"); + Py_UTF8Mode = 1; + + /* Test initialization from global configuration variables (Py_xxx) */ + Py_SetProgramName(L"./globalvar"); + + /* Py_IsolatedFlag is not tested */ + Py_NoSiteFlag = 1; + Py_BytesWarningFlag = 1; + + putenv("PYTHONINSPECT="); + Py_InspectFlag = 1; + + putenv("PYTHONOPTIMIZE=0"); + Py_InteractiveFlag = 1; + + putenv("PYTHONDEBUG=0"); + Py_OptimizeFlag = 2; + + /* Py_DebugFlag is not tested */ + + putenv("PYTHONDONTWRITEBYTECODE="); + Py_DontWriteBytecodeFlag = 1; + + putenv("PYTHONVERBOSE=0"); + Py_VerboseFlag = 1; + + Py_QuietFlag = 1; + Py_NoUserSiteDirectory = 1; + + putenv("PYTHONUNBUFFERED="); + Py_UnbufferedStdioFlag = 1; + + Py_FrozenFlag = 1; + + /* FIXME: test Py_LegacyWindowsFSEncodingFlag */ + /* FIXME: test Py_LegacyWindowsStdioFlag */ + + Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_from_config(void) +{ + PyPreConfig preconfig; + _PyPreConfig_InitCompatConfig(&preconfig); + + putenv("PYTHONMALLOC=malloc_debug"); + preconfig.allocator = PYMEM_ALLOCATOR_MALLOC; + + putenv("PYTHONUTF8=0"); + Py_UTF8Mode = 0; + preconfig.utf8_mode = 1; + + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + PyConfig config; + _PyConfig_InitCompatConfig(&config); + + config.install_signal_handlers = 0; + + /* FIXME: test use_environment */ + + putenv("PYTHONHASHSEED=42"); + config.use_hash_seed = 1; + config.hash_seed = 123; + + /* dev_mode=1 is tested in test_init_dev_mode() */ + + putenv("PYTHONFAULTHANDLER="); + config.faulthandler = 1; + + putenv("PYTHONTRACEMALLOC=0"); + config.tracemalloc = 2; + + putenv("PYTHONPROFILEIMPORTTIME=0"); + config.import_time = 1; + + config.show_ref_count = 1; + config.show_alloc_count = 1; + /* FIXME: test dump_refs: bpo-34223 */ + + putenv("PYTHONMALLOCSTATS=0"); + config.malloc_stats = 1; + + putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix"); + config_set_string(&config, &config.pycache_prefix, L"conf_pycache_prefix"); + + Py_SetProgramName(L"./globalvar"); + config_set_string(&config, &config.program_name, L"./conf_program_name"); + + wchar_t* argv[] = { + L"python3", + L"-W", + L"cmdline_warnoption", + L"-X", + L"cmdline_xoption", + L"-c", + L"pass", + L"arg2", + }; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config.parse_argv = 1; + + wchar_t* xoptions[3] = { + L"config_xoption1=3", + L"config_xoption2=", + L"config_xoption3", + }; + config_set_wide_string_list(&config, &config.xoptions, + Py_ARRAY_LENGTH(xoptions), xoptions); + + wchar_t* warnoptions[1] = { + L"config_warnoption", + }; + config_set_wide_string_list(&config, &config.warnoptions, + Py_ARRAY_LENGTH(warnoptions), warnoptions); + + /* FIXME: test pythonpath_env */ + /* FIXME: test home */ + /* FIXME: test path config: module_search_path .. dll_path */ + + putenv("PYTHONVERBOSE=0"); + Py_VerboseFlag = 0; + config.verbose = 1; + + Py_NoSiteFlag = 0; + config.site_import = 0; + + Py_BytesWarningFlag = 0; + config.bytes_warning = 1; + + putenv("PYTHONINSPECT="); + Py_InspectFlag = 0; + config.inspect = 1; + + Py_InteractiveFlag = 0; + config.interactive = 1; + + putenv("PYTHONOPTIMIZE=0"); + Py_OptimizeFlag = 1; + config.optimization_level = 2; + + /* FIXME: test parser_debug */ + + putenv("PYTHONDONTWRITEBYTECODE="); + Py_DontWriteBytecodeFlag = 0; + config.write_bytecode = 0; + + Py_QuietFlag = 0; + config.quiet = 1; + + config.configure_c_stdio = 1; + + putenv("PYTHONUNBUFFERED="); + Py_UnbufferedStdioFlag = 0; + config.buffered_stdio = 0; + + putenv("PYTHONIOENCODING=cp424"); + Py_SetStandardStreamEncoding("ascii", "ignore"); +#ifdef MS_WINDOWS + /* Py_SetStandardStreamEncoding() sets Py_LegacyWindowsStdioFlag to 1. + Force it to 0 through the config. */ + config.legacy_windows_stdio = 0; +#endif + config_set_string(&config, &config.stdio_encoding, L"iso8859-1"); + config_set_string(&config, &config.stdio_errors, L"replace"); + + putenv("PYTHONNOUSERSITE="); + Py_NoUserSiteDirectory = 0; + config.user_site_directory = 0; + + config_set_string(&config, &config.check_hash_pycs_mode, L"always"); + + Py_FrozenFlag = 0; + config.pathconfig_warnings = 0; + + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int check_init_parse_argv(int parse_argv) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config.parse_argv = parse_argv; + + wchar_t* argv[] = { + L"./argv0", + L"-E", + L"-c", + L"pass", + L"arg1", + L"-v", + L"arg3", + }; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_parse_argv(void) +{ + return check_init_parse_argv(1); +} + + +static int test_init_dont_parse_argv(void) +{ + return check_init_parse_argv(0); +} + + +static void set_most_env_vars(void) +{ + putenv("PYTHONHASHSEED=42"); + putenv("PYTHONMALLOC=malloc"); + putenv("PYTHONTRACEMALLOC=2"); + putenv("PYTHONPROFILEIMPORTTIME=1"); + putenv("PYTHONMALLOCSTATS=1"); + putenv("PYTHONUTF8=1"); + putenv("PYTHONVERBOSE=1"); + putenv("PYTHONINSPECT=1"); + putenv("PYTHONOPTIMIZE=2"); + putenv("PYTHONDONTWRITEBYTECODE=1"); + putenv("PYTHONUNBUFFERED=1"); + putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix"); + putenv("PYTHONNOUSERSITE=1"); + putenv("PYTHONFAULTHANDLER=1"); + putenv("PYTHONIOENCODING=iso8859-1:replace"); +} + + +static void set_all_env_vars(void) +{ + set_most_env_vars(); + + putenv("PYTHONWARNINGS=EnvVar"); + putenv("PYTHONPATH=/my/path"); +} + + +static int test_init_compat_env(void) +{ + /* Test initialization from environment variables */ + Py_IgnoreEnvironmentFlag = 0; + set_all_env_vars(); + _testembed_Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_python_env(void) +{ + set_all_env_vars(); + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static void set_all_env_vars_dev_mode(void) +{ + putenv("PYTHONMALLOC="); + putenv("PYTHONFAULTHANDLER="); + putenv("PYTHONDEVMODE=1"); +} + + +static int test_init_env_dev_mode(void) +{ + /* Test initialization from environment variables */ + Py_IgnoreEnvironmentFlag = 0; + set_all_env_vars_dev_mode(); + _testembed_Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_env_dev_mode_alloc(void) +{ + /* Test initialization from environment variables */ + Py_IgnoreEnvironmentFlag = 0; + set_all_env_vars_dev_mode(); + putenv("PYTHONMALLOC=malloc"); + _testembed_Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_isolated_flag(void) +{ + /* Test PyConfig.isolated=1 */ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + Py_IsolatedFlag = 0; + config.isolated = 1; + + config_set_program_name(&config); + set_all_env_vars(); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +/* PyPreConfig.isolated=1, PyConfig.isolated=0 */ +static int test_preinit_isolated1(void) +{ + PyPreConfig preconfig; + _PyPreConfig_InitCompatConfig(&preconfig); + + preconfig.isolated = 1; + + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + PyConfig config; + _PyConfig_InitCompatConfig(&config); + + config_set_program_name(&config); + set_all_env_vars(); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +/* PyPreConfig.isolated=0, PyConfig.isolated=1 */ +static int test_preinit_isolated2(void) +{ + PyPreConfig preconfig; + _PyPreConfig_InitCompatConfig(&preconfig); + + preconfig.isolated = 0; + + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + /* Test PyConfig.isolated=1 */ + PyConfig config; + _PyConfig_InitCompatConfig(&config); + + Py_IsolatedFlag = 0; + config.isolated = 1; + + config_set_program_name(&config); + set_all_env_vars(); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_preinit_dont_parse_argv(void) +{ + PyPreConfig preconfig; + PyPreConfig_InitIsolatedConfig(&preconfig); + + preconfig.isolated = 0; + + /* -X dev must be ignored by isolated preconfiguration */ + wchar_t *argv[] = {L"python3", + L"-E", + L"-I", + L"-X", L"dev", + L"-X", L"utf8", + L"script.py"}; + PyStatus status = Py_PreInitializeFromArgs(&preconfig, + Py_ARRAY_LENGTH(argv), argv); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + PyConfig config; + PyConfig_InitIsolatedConfig(&config); + + config.isolated = 0; + + /* Pre-initialize implicitly using argv: make sure that -X dev + is used to configure the allocation in preinitialization */ + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_preinit_parse_argv(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + /* Pre-initialize implicitly using argv: make sure that -X dev + is used to configure the allocation in preinitialization */ + wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"}; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + + + +static void set_all_global_config_variables(void) +{ + Py_IsolatedFlag = 0; + Py_IgnoreEnvironmentFlag = 0; + Py_BytesWarningFlag = 2; + Py_InspectFlag = 1; + Py_InteractiveFlag = 1; + Py_OptimizeFlag = 1; + Py_DebugFlag = 1; + Py_VerboseFlag = 1; + Py_QuietFlag = 1; + Py_FrozenFlag = 0; + Py_UnbufferedStdioFlag = 1; + Py_NoSiteFlag = 1; + Py_DontWriteBytecodeFlag = 1; + Py_NoUserSiteDirectory = 1; +#ifdef MS_WINDOWS + Py_LegacyWindowsStdioFlag = 1; +#endif +} + + +static int check_preinit_isolated_config(int preinit) +{ + PyStatus status; + PyPreConfig *rt_preconfig; + + /* environment variables must be ignored */ + set_all_env_vars(); + + /* global configuration variables must be ignored */ + set_all_global_config_variables(); + + if (preinit) { + PyPreConfig preconfig; + PyPreConfig_InitIsolatedConfig(&preconfig); + + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + rt_preconfig = &_PyRuntime.preconfig; + assert(rt_preconfig->isolated == 1); + assert(rt_preconfig->use_environment == 0); + } + + PyConfig config; + PyConfig_InitIsolatedConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); + + rt_preconfig = &_PyRuntime.preconfig; + assert(rt_preconfig->isolated == 1); + assert(rt_preconfig->use_environment == 0); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_preinit_isolated_config(void) +{ + return check_preinit_isolated_config(1); +} + + +static int test_init_isolated_config(void) +{ + return check_preinit_isolated_config(0); +} + + +static int check_init_python_config(int preinit) +{ + /* global configuration variables must be ignored */ + set_all_global_config_variables(); + Py_IsolatedFlag = 1; + Py_IgnoreEnvironmentFlag = 1; + Py_FrozenFlag = 1; + Py_UnbufferedStdioFlag = 1; + Py_NoSiteFlag = 1; + Py_DontWriteBytecodeFlag = 1; + Py_NoUserSiteDirectory = 1; +#ifdef MS_WINDOWS + Py_LegacyWindowsStdioFlag = 1; +#endif + + if (preinit) { + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); + + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + } + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_preinit_python_config(void) +{ + return check_init_python_config(1); +} + + +static int test_init_python_config(void) +{ + return check_init_python_config(0); +} + + +static int test_init_dont_configure_locale(void) +{ + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); + + preconfig.configure_locale = 0; + preconfig.coerce_c_locale = 1; + preconfig.coerce_c_locale_warn = 1; + + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_dev_mode(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + putenv("PYTHONFAULTHANDLER="); + putenv("PYTHONMALLOC="); + config.dev_mode = 1; + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + +static PyObject *_open_code_hook(PyObject *path, void *data) +{ + if (PyUnicode_CompareWithASCIIString(path, "$$test-filename") == 0) { + return PyLong_FromVoidPtr(data); + } + PyObject *io = PyImport_ImportModule("_io"); + if (!io) { + return NULL; + } + return PyObject_CallMethod(io, "open", "Os", path, "rb"); +} + +static int test_open_code_hook(void) +{ + int result = 0; + + /* Provide a hook */ + result = PyFile_SetOpenCodeHook(_open_code_hook, &result); + if (result) { + printf("Failed to set hook\n"); + return 1; + } + /* A second hook should fail */ + result = PyFile_SetOpenCodeHook(_open_code_hook, &result); + if (!result) { + printf("Should have failed to set second hook\n"); + return 2; + } + + Py_IgnoreEnvironmentFlag = 0; + _testembed_Py_Initialize(); + result = 0; + + PyObject *r = PyFile_OpenCode("$$test-filename"); + if (!r) { + PyErr_Print(); + result = 3; + } else { + void *cmp = PyLong_AsVoidPtr(r); + Py_DECREF(r); + if (cmp != &result) { + printf("Did not get expected result from hook\n"); + result = 4; + } + } + + if (!result) { + PyObject *io = PyImport_ImportModule("_io"); + PyObject *r = io + ? PyObject_CallMethod(io, "open_code", "s", "$$test-filename") + : NULL; + if (!r) { + PyErr_Print(); + result = 5; + } else { + void *cmp = PyLong_AsVoidPtr(r); + Py_DECREF(r); + if (cmp != &result) { + printf("Did not get expected result from hook\n"); + result = 6; + } + } + Py_XDECREF(io); + } + + Py_Finalize(); + return result; +} + +static int _audit_hook_clear_count = 0; + +static int _audit_hook(const char *event, PyObject *args, void *userdata) +{ + assert(args && PyTuple_CheckExact(args)); + if (strcmp(event, "_testembed.raise") == 0) { + PyErr_SetString(PyExc_RuntimeError, "Intentional error"); + return -1; + } else if (strcmp(event, "_testembed.set") == 0) { + if (!PyArg_ParseTuple(args, "n", userdata)) { + return -1; + } + return 0; + } else if (strcmp(event, "cpython._PySys_ClearAuditHooks") == 0) { + _audit_hook_clear_count += 1; + } + return 0; +} + +static int _test_audit(Py_ssize_t setValue) +{ + Py_ssize_t sawSet = 0; + + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_hook, &sawSet); + _testembed_Py_Initialize(); + + if (PySys_Audit("_testembed.raise", NULL) == 0) { + printf("No error raised"); + return 1; + } + if (PySys_Audit("_testembed.nop", NULL) != 0) { + printf("Nop event failed"); + /* Exception from above may still remain */ + PyErr_Clear(); + return 2; + } + if (!PyErr_Occurred()) { + printf("Exception not preserved"); + return 3; + } + PyErr_Clear(); + + if (PySys_Audit("_testembed.set", "n", setValue) != 0) { + PyErr_Print(); + printf("Set event failed"); + return 4; + } + + if (sawSet != 42) { + printf("Failed to see *userData change\n"); + return 5; + } + return 0; +} + +static int test_audit(void) +{ + int result = _test_audit(42); + Py_Finalize(); + if (_audit_hook_clear_count != 1) { + return 0x1000 | _audit_hook_clear_count; + } + return result; +} + +static volatile int _audit_subinterpreter_interpreter_count = 0; + +static int _audit_subinterpreter_hook(const char *event, PyObject *args, void *userdata) +{ + printf("%s\n", event); + if (strcmp(event, "cpython.PyInterpreterState_New") == 0) { + _audit_subinterpreter_interpreter_count += 1; + } + return 0; +} + +static int test_audit_subinterpreter(void) +{ + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_subinterpreter_hook, NULL); + _testembed_Py_Initialize(); + + Py_NewInterpreter(); + Py_NewInterpreter(); + Py_NewInterpreter(); + + Py_Finalize(); + + switch (_audit_subinterpreter_interpreter_count) { + case 3: return 0; + case 0: return -1; + default: return _audit_subinterpreter_interpreter_count; + } +} + +typedef struct { + const char* expected; + int exit; +} AuditRunCommandTest; + +static int _audit_hook_run(const char *eventName, PyObject *args, void *userData) +{ + AuditRunCommandTest *test = (AuditRunCommandTest*)userData; + if (strcmp(eventName, test->expected)) { + return 0; + } + + if (test->exit) { + PyObject *msg = PyUnicode_FromFormat("detected %s(%R)", eventName, args); + if (msg) { + printf("%s\n", PyUnicode_AsUTF8(msg)); + Py_DECREF(msg); + } + exit(test->exit); + } + + PyErr_Format(PyExc_RuntimeError, "detected %s(%R)", eventName, args); + return -1; +} + +static int test_audit_run_command(void) +{ + AuditRunCommandTest test = {"cpython.run_command"}; + wchar_t *argv[] = {PROGRAM_NAME, L"-c", L"pass"}; + + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_hook_run, (void*)&test); + + return Py_Main(Py_ARRAY_LENGTH(argv), argv); +} + +static int test_audit_run_file(void) +{ + AuditRunCommandTest test = {"cpython.run_file"}; + wchar_t *argv[] = {PROGRAM_NAME, L"filename.py"}; + + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_hook_run, (void*)&test); + + return Py_Main(Py_ARRAY_LENGTH(argv), argv); +} + +static int run_audit_run_test(int argc, wchar_t **argv, void *test) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config.argv.length = argc; + config.argv.items = argv; + config.parse_argv = 1; + config.program_name = argv[0]; + config.interactive = 1; + config.isolated = 0; + config.use_environment = 1; + config.quiet = 1; + + PySys_AddAuditHook(_audit_hook_run, test); + + PyStatus status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + return Py_RunMain(); +} + +static int test_audit_run_interactivehook(void) +{ + AuditRunCommandTest test = {"cpython.run_interactivehook", 10}; + wchar_t *argv[] = {PROGRAM_NAME}; + return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test); +} + +static int test_audit_run_startup(void) +{ + AuditRunCommandTest test = {"cpython.run_startup", 10}; + wchar_t *argv[] = {PROGRAM_NAME}; + return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test); +} + +static int test_audit_run_stdin(void) +{ + AuditRunCommandTest test = {"cpython.run_stdin"}; + wchar_t *argv[] = {PROGRAM_NAME}; + return run_audit_run_test(Py_ARRAY_LENGTH(argv), argv, &test); +} + +static int test_init_read_set(void) +{ + PyStatus status; + PyConfig config; + PyConfig_InitPythonConfig(&config); + + status = PyConfig_SetBytesString(&config, &config.program_name, + "./init_read_set"); + if (PyStatus_Exception(status)) { + goto fail; + } + + status = PyConfig_Read(&config); + if (PyStatus_Exception(status)) { + goto fail; + } + + status = PyWideStringList_Insert(&config.module_search_paths, + 1, L"test_path_insert1"); + if (PyStatus_Exception(status)) { + goto fail; + } + + status = PyWideStringList_Append(&config.module_search_paths, + L"test_path_append"); + if (PyStatus_Exception(status)) { + goto fail; + } + + /* override executable computed by PyConfig_Read() */ + config_set_string(&config, &config.executable, L"my_executable"); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; + +fail: + Py_ExitStatusException(status); +} + + +static int test_init_sys_add(void) +{ + PySys_AddXOption(L"sysadd_xoption"); + PySys_AddXOption(L"faulthandler"); + PySys_AddWarnOption(L"ignore:::sysadd_warnoption"); + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + wchar_t* argv[] = { + L"python3", + L"-W", + L"ignore:::cmdline_warnoption", + L"-X", + L"cmdline_xoption", + }; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config.parse_argv = 1; + + PyStatus status; + status = PyWideStringList_Append(&config.xoptions, + L"config_xoption"); + if (PyStatus_Exception(status)) { + goto fail; + } + + status = PyWideStringList_Append(&config.warnoptions, + L"ignore:::config_warnoption"); + if (PyStatus_Exception(status)) { + goto fail; + } + + config_set_program_name(&config); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; + +fail: + PyConfig_Clear(&config); + Py_ExitStatusException(status); +} + + +static int test_init_setpath(void) +{ + char *env = getenv("TESTPATH"); + if (!env) { + fprintf(stderr, "missing TESTPATH env var\n"); + return 1; + } + wchar_t *path = Py_DecodeLocale(env, NULL); + if (path == NULL) { + fprintf(stderr, "failed to decode TESTPATH\n"); + return 1; + } + Py_SetPath(path); + PyMem_RawFree(path); + putenv("TESTPATH="); + + Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_setpath_config(void) +{ + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); + + /* Explicitly preinitializes with Python preconfiguration to avoid + Py_SetPath() implicit preinitialization with compat preconfiguration. */ + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + char *env = getenv("TESTPATH"); + if (!env) { + fprintf(stderr, "missing TESTPATH env var\n"); + return 1; + } + wchar_t *path = Py_DecodeLocale(env, NULL); + if (path == NULL) { + fprintf(stderr, "failed to decode TESTPATH\n"); + return 1; + } + Py_SetPath(path); + PyMem_RawFree(path); + putenv("TESTPATH="); + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config_set_string(&config, &config.program_name, L"conf_program_name"); + config_set_string(&config, &config.executable, L"conf_executable"); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_setpythonhome(void) +{ + char *env = getenv("TESTHOME"); + if (!env) { + fprintf(stderr, "missing TESTHOME env var\n"); + return 1; + } + wchar_t *home = Py_DecodeLocale(env, NULL); + if (home == NULL) { + fprintf(stderr, "failed to decode TESTHOME\n"); + return 1; + } + Py_SetPythonHome(home); + PyMem_RawFree(home); + putenv("TESTHOME="); + + Py_Initialize(); + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_init_warnoptions(void) +{ + putenv("PYTHONWARNINGS=ignore:::env1,ignore:::env2"); + + PySys_AddWarnOption(L"ignore:::PySys_AddWarnOption1"); + PySys_AddWarnOption(L"ignore:::PySys_AddWarnOption2"); + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config.dev_mode = 1; + config.bytes_warning = 1; + + config_set_program_name(&config); + + PyStatus status; + status = PyWideStringList_Append(&config.warnoptions, + L"ignore:::PyConfig_BeforeRead"); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + wchar_t* argv[] = { + L"python3", + L"-Wignore:::cmdline1", + L"-Wignore:::cmdline2"}; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config.parse_argv = 1; + + status = PyConfig_Read(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + status = PyWideStringList_Append(&config.warnoptions, + L"ignore:::PyConfig_AfterRead"); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + status = PyWideStringList_Insert(&config.warnoptions, + 0, L"ignore:::PyConfig_Insert0"); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + init_from_config_clear(&config); + dump_config(); + Py_Finalize(); + return 0; +} + + +static void configure_init_main(PyConfig *config) +{ + wchar_t* argv[] = { + L"python3", L"-c", + (L"import _testinternalcapi, json; " + L"print(json.dumps(_testinternalcapi.get_configs()))"), + L"arg2"}; + + config->parse_argv = 1; + + config_set_argv(config, Py_ARRAY_LENGTH(argv), argv); + config_set_string(config, &config->program_name, L"./python3"); +} + + +static int test_init_run_main(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + configure_init_main(&config); + init_from_config_clear(&config); + + return Py_RunMain(); +} + + +static int test_init_main(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + configure_init_main(&config); + config._init_main = 0; + init_from_config_clear(&config); + + /* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */ + int res = PyRun_SimpleString( + "import sys; " + "print('Run Python code before _Py_InitializeMain', " + "file=sys.stderr)"); + if (res < 0) { + exit(1); + } + + PyStatus status = _Py_InitializeMain(); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + return Py_RunMain(); +} + + +static int test_run_main(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + wchar_t *argv[] = {L"python3", L"-c", + (L"import sys; " + L"print(f'Py_RunMain(): sys.argv={sys.argv}')"), + L"arg2"}; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config_set_string(&config, &config.program_name, L"./python3"); + init_from_config_clear(&config); + + return Py_RunMain(); +} + + +/* ********************************************************* + * List of test cases and the function that implements it. + * + * Names are compared case-sensitively with the first + * argument. If no match is found, or no first argument was + * provided, the names of all test cases are printed and + * the exit code will be -1. + * + * The int returned from test functions is used as the exit + * code, and test_capi treats all non-zero exit codes as a + * failed test. + *********************************************************/ +struct TestCase +{ + const char *name; + int (*func)(void); +}; + +static struct TestCase TestCases[] = { + {"test_forced_io_encoding", test_forced_io_encoding}, + {"test_repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters}, + {"test_pre_initialization_api", test_pre_initialization_api}, + {"test_pre_initialization_sys_options", test_pre_initialization_sys_options}, + {"test_bpo20891", test_bpo20891}, + {"test_initialize_twice", test_initialize_twice}, + {"test_initialize_pymain", test_initialize_pymain}, + {"test_init_initialize_config", test_init_initialize_config}, + {"test_preinit_compat_config", test_preinit_compat_config}, + {"test_init_compat_config", test_init_compat_config}, + {"test_init_global_config", test_init_global_config}, + {"test_init_from_config", test_init_from_config}, + {"test_init_parse_argv", test_init_parse_argv}, + {"test_init_dont_parse_argv", test_init_dont_parse_argv}, + {"test_init_compat_env", test_init_compat_env}, + {"test_init_python_env", test_init_python_env}, + {"test_init_env_dev_mode", test_init_env_dev_mode}, + {"test_init_env_dev_mode_alloc", test_init_env_dev_mode_alloc}, + {"test_init_dont_configure_locale", test_init_dont_configure_locale}, + {"test_init_dev_mode", test_init_dev_mode}, + {"test_init_isolated_flag", test_init_isolated_flag}, + {"test_preinit_isolated_config", test_preinit_isolated_config}, + {"test_init_isolated_config", test_init_isolated_config}, + {"test_preinit_python_config", test_preinit_python_config}, + {"test_init_python_config", test_init_python_config}, + {"test_preinit_isolated1", test_preinit_isolated1}, + {"test_preinit_isolated2", test_preinit_isolated2}, + {"test_preinit_parse_argv", test_preinit_parse_argv}, + {"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv}, + {"test_init_read_set", test_init_read_set}, + {"test_init_run_main", test_init_run_main}, + {"test_init_main", test_init_main}, + {"test_init_sys_add", test_init_sys_add}, + {"test_init_setpath", test_init_setpath}, + {"test_init_setpath_config", test_init_setpath_config}, + {"test_init_setpythonhome", test_init_setpythonhome}, + {"test_init_warnoptions", test_init_warnoptions}, + {"test_run_main", test_run_main}, + + {"test_open_code_hook", test_open_code_hook}, + {"test_audit", test_audit}, + {"test_audit_subinterpreter", test_audit_subinterpreter}, + {"test_audit_run_command", test_audit_run_command}, + {"test_audit_run_file", test_audit_run_file}, + {"test_audit_run_interactivehook", test_audit_run_interactivehook}, + {"test_audit_run_startup", test_audit_run_startup}, + {"test_audit_run_stdin", test_audit_run_stdin}, + {NULL, NULL} +}; + +int main(int argc, char *argv[]) +{ + if (argc > 1) { + for (struct TestCase *tc = TestCases; tc && tc->name; tc++) { + if (strcmp(argv[1], tc->name) == 0) + return (*tc->func)(); + } + } + + /* No match found, or no test name provided, so display usage */ + printf("Python " PY_VERSION " _testembed executable for embedded interpreter tests\n" + "Normally executed via 'EmbeddingTests' in Lib/test/test_embed.py\n\n" + "Usage: %s TESTNAME\n\nAll available tests:\n", argv[0]); + for (struct TestCase *tc = TestCases; tc && tc->name; tc++) { + printf(" %s\n", tc->name); + } + + /* Non-zero exit code will cause test_embed.py tests to fail. + This is intentional. */ + return -1; +} diff --git a/python/Programs/python.c b/python/Programs/python.c new file mode 100755 index 0000000..1cc3c42 --- /dev/null +++ b/python/Programs/python.c @@ -0,0 +1,18 @@ +/* Minimal main program -- everything is loaded from the library */ + +#include "Python.h" +#include "pycore_pylifecycle.h" + +#ifdef MS_WINDOWS +int +wmain(int argc, wchar_t **argv) +{ + return Py_Main(argc, argv); +} +#else +int +main(int argc, char **argv) +{ + return Py_BytesMain(argc, argv); +} +#endif diff --git a/python/Python/Python-ast.c b/python/Python/Python-ast.c new file mode 100755 index 0000000..bcf9456 --- /dev/null +++ b/python/Python/Python-ast.c @@ -0,0 +1,9055 @@ +/* File automatically generated by Parser/asdl_c.py. */ + +#include + +#include "Python.h" +#include "Python-ast.h" + +static PyTypeObject AST_type; +static PyTypeObject *mod_type; +static PyObject* ast2obj_mod(void*); +static PyTypeObject *Module_type; +_Py_IDENTIFIER(body); +_Py_IDENTIFIER(type_ignores); +static char *Module_fields[]={ + "body", + "type_ignores", +}; +static PyTypeObject *Interactive_type; +static char *Interactive_fields[]={ + "body", +}; +static PyTypeObject *Expression_type; +static char *Expression_fields[]={ + "body", +}; +static PyTypeObject *FunctionType_type; +_Py_IDENTIFIER(argtypes); +_Py_IDENTIFIER(returns); +static char *FunctionType_fields[]={ + "argtypes", + "returns", +}; +static PyTypeObject *Suite_type; +static char *Suite_fields[]={ + "body", +}; +static PyTypeObject *stmt_type; +_Py_IDENTIFIER(lineno); +_Py_IDENTIFIER(col_offset); +_Py_IDENTIFIER(end_lineno); +_Py_IDENTIFIER(end_col_offset); +static char *stmt_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; +static PyObject* ast2obj_stmt(void*); +static PyTypeObject *FunctionDef_type; +_Py_IDENTIFIER(name); +_Py_IDENTIFIER(args); +_Py_IDENTIFIER(decorator_list); +_Py_IDENTIFIER(type_comment); +static char *FunctionDef_fields[]={ + "name", + "args", + "body", + "decorator_list", + "returns", + "type_comment", +}; +static PyTypeObject *AsyncFunctionDef_type; +static char *AsyncFunctionDef_fields[]={ + "name", + "args", + "body", + "decorator_list", + "returns", + "type_comment", +}; +static PyTypeObject *ClassDef_type; +_Py_IDENTIFIER(bases); +_Py_IDENTIFIER(keywords); +static char *ClassDef_fields[]={ + "name", + "bases", + "keywords", + "body", + "decorator_list", +}; +static PyTypeObject *Return_type; +_Py_IDENTIFIER(value); +static char *Return_fields[]={ + "value", +}; +static PyTypeObject *Delete_type; +_Py_IDENTIFIER(targets); +static char *Delete_fields[]={ + "targets", +}; +static PyTypeObject *Assign_type; +static char *Assign_fields[]={ + "targets", + "value", + "type_comment", +}; +static PyTypeObject *AugAssign_type; +_Py_IDENTIFIER(target); +_Py_IDENTIFIER(op); +static char *AugAssign_fields[]={ + "target", + "op", + "value", +}; +static PyTypeObject *AnnAssign_type; +_Py_IDENTIFIER(annotation); +_Py_IDENTIFIER(simple); +static char *AnnAssign_fields[]={ + "target", + "annotation", + "value", + "simple", +}; +static PyTypeObject *For_type; +_Py_IDENTIFIER(iter); +_Py_IDENTIFIER(orelse); +static char *For_fields[]={ + "target", + "iter", + "body", + "orelse", + "type_comment", +}; +static PyTypeObject *AsyncFor_type; +static char *AsyncFor_fields[]={ + "target", + "iter", + "body", + "orelse", + "type_comment", +}; +static PyTypeObject *While_type; +_Py_IDENTIFIER(test); +static char *While_fields[]={ + "test", + "body", + "orelse", +}; +static PyTypeObject *If_type; +static char *If_fields[]={ + "test", + "body", + "orelse", +}; +static PyTypeObject *With_type; +_Py_IDENTIFIER(items); +static char *With_fields[]={ + "items", + "body", + "type_comment", +}; +static PyTypeObject *AsyncWith_type; +static char *AsyncWith_fields[]={ + "items", + "body", + "type_comment", +}; +static PyTypeObject *Raise_type; +_Py_IDENTIFIER(exc); +_Py_IDENTIFIER(cause); +static char *Raise_fields[]={ + "exc", + "cause", +}; +static PyTypeObject *Try_type; +_Py_IDENTIFIER(handlers); +_Py_IDENTIFIER(finalbody); +static char *Try_fields[]={ + "body", + "handlers", + "orelse", + "finalbody", +}; +static PyTypeObject *Assert_type; +_Py_IDENTIFIER(msg); +static char *Assert_fields[]={ + "test", + "msg", +}; +static PyTypeObject *Import_type; +_Py_IDENTIFIER(names); +static char *Import_fields[]={ + "names", +}; +static PyTypeObject *ImportFrom_type; +_Py_IDENTIFIER(module); +_Py_IDENTIFIER(level); +static char *ImportFrom_fields[]={ + "module", + "names", + "level", +}; +static PyTypeObject *Global_type; +static char *Global_fields[]={ + "names", +}; +static PyTypeObject *Nonlocal_type; +static char *Nonlocal_fields[]={ + "names", +}; +static PyTypeObject *Expr_type; +static char *Expr_fields[]={ + "value", +}; +static PyTypeObject *Pass_type; +static PyTypeObject *Break_type; +static PyTypeObject *Continue_type; +static PyTypeObject *expr_type; +static char *expr_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; +static PyObject* ast2obj_expr(void*); +static PyTypeObject *BoolOp_type; +_Py_IDENTIFIER(values); +static char *BoolOp_fields[]={ + "op", + "values", +}; +static PyTypeObject *NamedExpr_type; +static char *NamedExpr_fields[]={ + "target", + "value", +}; +static PyTypeObject *BinOp_type; +_Py_IDENTIFIER(left); +_Py_IDENTIFIER(right); +static char *BinOp_fields[]={ + "left", + "op", + "right", +}; +static PyTypeObject *UnaryOp_type; +_Py_IDENTIFIER(operand); +static char *UnaryOp_fields[]={ + "op", + "operand", +}; +static PyTypeObject *Lambda_type; +static char *Lambda_fields[]={ + "args", + "body", +}; +static PyTypeObject *IfExp_type; +static char *IfExp_fields[]={ + "test", + "body", + "orelse", +}; +static PyTypeObject *Dict_type; +_Py_IDENTIFIER(keys); +static char *Dict_fields[]={ + "keys", + "values", +}; +static PyTypeObject *Set_type; +_Py_IDENTIFIER(elts); +static char *Set_fields[]={ + "elts", +}; +static PyTypeObject *ListComp_type; +_Py_IDENTIFIER(elt); +_Py_IDENTIFIER(generators); +static char *ListComp_fields[]={ + "elt", + "generators", +}; +static PyTypeObject *SetComp_type; +static char *SetComp_fields[]={ + "elt", + "generators", +}; +static PyTypeObject *DictComp_type; +_Py_IDENTIFIER(key); +static char *DictComp_fields[]={ + "key", + "value", + "generators", +}; +static PyTypeObject *GeneratorExp_type; +static char *GeneratorExp_fields[]={ + "elt", + "generators", +}; +static PyTypeObject *Await_type; +static char *Await_fields[]={ + "value", +}; +static PyTypeObject *Yield_type; +static char *Yield_fields[]={ + "value", +}; +static PyTypeObject *YieldFrom_type; +static char *YieldFrom_fields[]={ + "value", +}; +static PyTypeObject *Compare_type; +_Py_IDENTIFIER(ops); +_Py_IDENTIFIER(comparators); +static char *Compare_fields[]={ + "left", + "ops", + "comparators", +}; +static PyTypeObject *Call_type; +_Py_IDENTIFIER(func); +static char *Call_fields[]={ + "func", + "args", + "keywords", +}; +static PyTypeObject *FormattedValue_type; +_Py_IDENTIFIER(conversion); +_Py_IDENTIFIER(format_spec); +static char *FormattedValue_fields[]={ + "value", + "conversion", + "format_spec", +}; +static PyTypeObject *JoinedStr_type; +static char *JoinedStr_fields[]={ + "values", +}; +static PyTypeObject *Constant_type; +_Py_IDENTIFIER(kind); +static char *Constant_fields[]={ + "value", + "kind", +}; +static PyTypeObject *Attribute_type; +_Py_IDENTIFIER(attr); +_Py_IDENTIFIER(ctx); +static char *Attribute_fields[]={ + "value", + "attr", + "ctx", +}; +static PyTypeObject *Subscript_type; +_Py_IDENTIFIER(slice); +static char *Subscript_fields[]={ + "value", + "slice", + "ctx", +}; +static PyTypeObject *Starred_type; +static char *Starred_fields[]={ + "value", + "ctx", +}; +static PyTypeObject *Name_type; +_Py_IDENTIFIER(id); +static char *Name_fields[]={ + "id", + "ctx", +}; +static PyTypeObject *List_type; +static char *List_fields[]={ + "elts", + "ctx", +}; +static PyTypeObject *Tuple_type; +static char *Tuple_fields[]={ + "elts", + "ctx", +}; +static PyTypeObject *expr_context_type; +static PyObject *Load_singleton, *Store_singleton, *Del_singleton, +*AugLoad_singleton, *AugStore_singleton, *Param_singleton; +static PyObject* ast2obj_expr_context(expr_context_ty); +static PyTypeObject *Load_type; +static PyTypeObject *Store_type; +static PyTypeObject *Del_type; +static PyTypeObject *AugLoad_type; +static PyTypeObject *AugStore_type; +static PyTypeObject *Param_type; +static PyTypeObject *slice_type; +static PyObject* ast2obj_slice(void*); +static PyTypeObject *Slice_type; +_Py_IDENTIFIER(lower); +_Py_IDENTIFIER(upper); +_Py_IDENTIFIER(step); +static char *Slice_fields[]={ + "lower", + "upper", + "step", +}; +static PyTypeObject *ExtSlice_type; +_Py_IDENTIFIER(dims); +static char *ExtSlice_fields[]={ + "dims", +}; +static PyTypeObject *Index_type; +static char *Index_fields[]={ + "value", +}; +static PyTypeObject *boolop_type; +static PyObject *And_singleton, *Or_singleton; +static PyObject* ast2obj_boolop(boolop_ty); +static PyTypeObject *And_type; +static PyTypeObject *Or_type; +static PyTypeObject *operator_type; +static PyObject *Add_singleton, *Sub_singleton, *Mult_singleton, +*MatMult_singleton, *Div_singleton, *Mod_singleton, *Pow_singleton, +*LShift_singleton, *RShift_singleton, *BitOr_singleton, *BitXor_singleton, +*BitAnd_singleton, *FloorDiv_singleton; +static PyObject* ast2obj_operator(operator_ty); +static PyTypeObject *Add_type; +static PyTypeObject *Sub_type; +static PyTypeObject *Mult_type; +static PyTypeObject *MatMult_type; +static PyTypeObject *Div_type; +static PyTypeObject *Mod_type; +static PyTypeObject *Pow_type; +static PyTypeObject *LShift_type; +static PyTypeObject *RShift_type; +static PyTypeObject *BitOr_type; +static PyTypeObject *BitXor_type; +static PyTypeObject *BitAnd_type; +static PyTypeObject *FloorDiv_type; +static PyTypeObject *unaryop_type; +static PyObject *Invert_singleton, *Not_singleton, *UAdd_singleton, +*USub_singleton; +static PyObject* ast2obj_unaryop(unaryop_ty); +static PyTypeObject *Invert_type; +static PyTypeObject *Not_type; +static PyTypeObject *UAdd_type; +static PyTypeObject *USub_type; +static PyTypeObject *cmpop_type; +static PyObject *Eq_singleton, *NotEq_singleton, *Lt_singleton, *LtE_singleton, +*Gt_singleton, *GtE_singleton, *Is_singleton, *IsNot_singleton, *In_singleton, +*NotIn_singleton; +static PyObject* ast2obj_cmpop(cmpop_ty); +static PyTypeObject *Eq_type; +static PyTypeObject *NotEq_type; +static PyTypeObject *Lt_type; +static PyTypeObject *LtE_type; +static PyTypeObject *Gt_type; +static PyTypeObject *GtE_type; +static PyTypeObject *Is_type; +static PyTypeObject *IsNot_type; +static PyTypeObject *In_type; +static PyTypeObject *NotIn_type; +static PyTypeObject *comprehension_type; +static PyObject* ast2obj_comprehension(void*); +_Py_IDENTIFIER(ifs); +_Py_IDENTIFIER(is_async); +static char *comprehension_fields[]={ + "target", + "iter", + "ifs", + "is_async", +}; +static PyTypeObject *excepthandler_type; +static char *excepthandler_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; +static PyObject* ast2obj_excepthandler(void*); +static PyTypeObject *ExceptHandler_type; +_Py_IDENTIFIER(type); +static char *ExceptHandler_fields[]={ + "type", + "name", + "body", +}; +static PyTypeObject *arguments_type; +static PyObject* ast2obj_arguments(void*); +_Py_IDENTIFIER(posonlyargs); +_Py_IDENTIFIER(vararg); +_Py_IDENTIFIER(kwonlyargs); +_Py_IDENTIFIER(kw_defaults); +_Py_IDENTIFIER(kwarg); +_Py_IDENTIFIER(defaults); +static char *arguments_fields[]={ + "posonlyargs", + "args", + "vararg", + "kwonlyargs", + "kw_defaults", + "kwarg", + "defaults", +}; +static PyTypeObject *arg_type; +static PyObject* ast2obj_arg(void*); +static char *arg_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; +_Py_IDENTIFIER(arg); +static char *arg_fields[]={ + "arg", + "annotation", + "type_comment", +}; +static PyTypeObject *keyword_type; +static PyObject* ast2obj_keyword(void*); +static char *keyword_fields[]={ + "arg", + "value", +}; +static PyTypeObject *alias_type; +static PyObject* ast2obj_alias(void*); +_Py_IDENTIFIER(asname); +static char *alias_fields[]={ + "name", + "asname", +}; +static PyTypeObject *withitem_type; +static PyObject* ast2obj_withitem(void*); +_Py_IDENTIFIER(context_expr); +_Py_IDENTIFIER(optional_vars); +static char *withitem_fields[]={ + "context_expr", + "optional_vars", +}; +static PyTypeObject *type_ignore_type; +static PyObject* ast2obj_type_ignore(void*); +static PyTypeObject *TypeIgnore_type; +_Py_IDENTIFIER(tag); +static char *TypeIgnore_fields[]={ + "lineno", + "tag", +}; + + +_Py_IDENTIFIER(_fields); +_Py_IDENTIFIER(_attributes); + +typedef struct { + PyObject_HEAD + PyObject *dict; +} AST_object; + +static void +ast_dealloc(AST_object *self) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free(self); +} + +static int +ast_traverse(AST_object *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +ast_clear(AST_object *self) +{ + Py_CLEAR(self->dict); + return 0; +} + +static int +ast_type_init(PyObject *self, PyObject *args, PyObject *kw) +{ + Py_ssize_t i, numfields = 0; + int res = -1; + PyObject *key, *value, *fields; + if (_PyObject_LookupAttrId((PyObject*)Py_TYPE(self), &PyId__fields, &fields) < 0) { + goto cleanup; + } + if (fields) { + numfields = PySequence_Size(fields); + if (numfields == -1) { + goto cleanup; + } + } + + res = 0; /* if no error occurs, this stays 0 to the end */ + if (numfields < PyTuple_GET_SIZE(args)) { + PyErr_Format(PyExc_TypeError, "%.400s constructor takes at most " + "%zd positional argument%s", + Py_TYPE(self)->tp_name, + numfields, numfields == 1 ? "" : "s"); + res = -1; + goto cleanup; + } + for (i = 0; i < PyTuple_GET_SIZE(args); i++) { + /* cannot be reached when fields is NULL */ + PyObject *name = PySequence_GetItem(fields, i); + if (!name) { + res = -1; + goto cleanup; + } + res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i)); + Py_DECREF(name); + if (res < 0) { + goto cleanup; + } + } + if (kw) { + i = 0; /* needed by PyDict_Next */ + while (PyDict_Next(kw, &i, &key, &value)) { + int contains = PySequence_Contains(fields, key); + if (contains == -1) { + res = -1; + goto cleanup; + } else if (contains == 1) { + Py_ssize_t p = PySequence_Index(fields, key); + if (p == -1) { + res = -1; + goto cleanup; + } + if (p < PyTuple_GET_SIZE(args)) { + PyErr_Format(PyExc_TypeError, + "%.400s got multiple values for argument '%U'", + Py_TYPE(self)->tp_name, key); + res = -1; + goto cleanup; + } + } + res = PyObject_SetAttr(self, key, value); + if (res < 0) { + goto cleanup; + } + } + } + cleanup: + Py_XDECREF(fields); + return res; +} + +/* Pickling support */ +static PyObject * +ast_type_reduce(PyObject *self, PyObject *unused) +{ + _Py_IDENTIFIER(__dict__); + PyObject *dict; + if (_PyObject_LookupAttrId(self, &PyId___dict__, &dict) < 0) { + return NULL; + } + if (dict) { + return Py_BuildValue("O()N", Py_TYPE(self), dict); + } + return Py_BuildValue("O()", Py_TYPE(self)); +} + +static PyMethodDef ast_type_methods[] = { + {"__reduce__", ast_type_reduce, METH_NOARGS, NULL}, + {NULL} +}; + +static PyGetSetDef ast_type_getsets[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} +}; + +static PyTypeObject AST_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "_ast.AST", + sizeof(AST_object), + 0, + (destructor)ast_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 */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)ast_traverse, /* tp_traverse */ + (inquiry)ast_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ast_type_methods, /* tp_methods */ + 0, /* tp_members */ + ast_type_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(AST_object, dict),/* tp_dictoffset */ + (initproc)ast_type_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields) +{ + _Py_IDENTIFIER(__module__); + _Py_IDENTIFIER(_ast); + PyObject *fnames, *result; + int i; + fnames = PyTuple_New(num_fields); + if (!fnames) return NULL; + for (i = 0; i < num_fields; i++) { + PyObject *field = PyUnicode_FromString(fields[i]); + if (!field) { + Py_DECREF(fnames); + return NULL; + } + PyTuple_SET_ITEM(fnames, i, field); + } + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOO}", + type, base, + _PyUnicode_FromId(&PyId__fields), fnames, + _PyUnicode_FromId(&PyId___module__), + _PyUnicode_FromId(&PyId__ast)); + Py_DECREF(fnames); + return (PyTypeObject*)result; +} + +static int add_attributes(PyTypeObject* type, char**attrs, int num_fields) +{ + int i, result; + PyObject *s, *l = PyTuple_New(num_fields); + if (!l) + return 0; + for (i = 0; i < num_fields; i++) { + s = PyUnicode_FromString(attrs[i]); + if (!s) { + Py_DECREF(l); + return 0; + } + PyTuple_SET_ITEM(l, i, s); + } + result = _PyObject_SetAttrId((PyObject*)type, &PyId__attributes, l) >= 0; + Py_DECREF(l); + return result; +} + +/* Conversion AST -> Python */ + +static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*)) +{ + Py_ssize_t i, n = asdl_seq_LEN(seq); + PyObject *result = PyList_New(n); + PyObject *value; + if (!result) + return NULL; + for (i = 0; i < n; i++) { + value = func(asdl_seq_GET(seq, i)); + if (!value) { + Py_DECREF(result); + return NULL; + } + PyList_SET_ITEM(result, i, value); + } + return result; +} + +static PyObject* ast2obj_object(void *o) +{ + if (!o) + o = Py_None; + Py_INCREF((PyObject*)o); + return (PyObject*)o; +} +#define ast2obj_singleton ast2obj_object +#define ast2obj_constant ast2obj_object +#define ast2obj_identifier ast2obj_object +#define ast2obj_string ast2obj_object +#define ast2obj_bytes ast2obj_object + +static PyObject* ast2obj_int(long b) +{ + return PyLong_FromLong(b); +} + +/* Conversion Python -> AST */ + +static int obj2ast_object(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (obj == Py_None) + obj = NULL; + if (obj) { + if (PyArena_AddPyObject(arena, obj) < 0) { + *out = NULL; + return -1; + } + Py_INCREF(obj); + } + *out = obj; + return 0; +} + +static int obj2ast_constant(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (PyArena_AddPyObject(arena, obj) < 0) { + *out = NULL; + return -1; + } + Py_INCREF(obj); + *out = obj; + return 0; +} + +static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (!PyUnicode_CheckExact(obj) && obj != Py_None) { + PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str"); + return 1; + } + return obj2ast_object(obj, out, arena); +} + +static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena) +{ + if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) { + PyErr_SetString(PyExc_TypeError, "AST string must be of type str"); + return 1; + } + return obj2ast_object(obj, out, arena); +} + +static int obj2ast_int(PyObject* obj, int* out, PyArena* arena) +{ + int i; + if (!PyLong_Check(obj)) { + PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj); + return 1; + } + + i = _PyLong_AsInt(obj); + if (i == -1 && PyErr_Occurred()) + return 1; + *out = i; + return 0; +} + +static int add_ast_fields(void) +{ + PyObject *empty_tuple, *d; + if (PyType_Ready(&AST_type) < 0) + return -1; + d = AST_type.tp_dict; + empty_tuple = PyTuple_New(0); + if (!empty_tuple || + _PyDict_SetItemId(d, &PyId__fields, empty_tuple) < 0 || + _PyDict_SetItemId(d, &PyId__attributes, empty_tuple) < 0) { + Py_XDECREF(empty_tuple); + return -1; + } + Py_DECREF(empty_tuple); + return 0; +} + + +static int init_types(void) +{ + static int initialized; + if (initialized) return 1; + if (add_ast_fields() < 0) return 0; + mod_type = make_type("mod", &AST_type, NULL, 0); + if (!mod_type) return 0; + if (!add_attributes(mod_type, NULL, 0)) return 0; + Module_type = make_type("Module", mod_type, Module_fields, 2); + if (!Module_type) return 0; + Interactive_type = make_type("Interactive", mod_type, Interactive_fields, + 1); + if (!Interactive_type) return 0; + Expression_type = make_type("Expression", mod_type, Expression_fields, 1); + if (!Expression_type) return 0; + FunctionType_type = make_type("FunctionType", mod_type, + FunctionType_fields, 2); + if (!FunctionType_type) return 0; + Suite_type = make_type("Suite", mod_type, Suite_fields, 1); + if (!Suite_type) return 0; + stmt_type = make_type("stmt", &AST_type, NULL, 0); + if (!stmt_type) return 0; + if (!add_attributes(stmt_type, stmt_attributes, 4)) return 0; + FunctionDef_type = make_type("FunctionDef", stmt_type, FunctionDef_fields, + 6); + if (!FunctionDef_type) return 0; + AsyncFunctionDef_type = make_type("AsyncFunctionDef", stmt_type, + AsyncFunctionDef_fields, 6); + if (!AsyncFunctionDef_type) return 0; + ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 5); + if (!ClassDef_type) return 0; + Return_type = make_type("Return", stmt_type, Return_fields, 1); + if (!Return_type) return 0; + Delete_type = make_type("Delete", stmt_type, Delete_fields, 1); + if (!Delete_type) return 0; + Assign_type = make_type("Assign", stmt_type, Assign_fields, 3); + if (!Assign_type) return 0; + AugAssign_type = make_type("AugAssign", stmt_type, AugAssign_fields, 3); + if (!AugAssign_type) return 0; + AnnAssign_type = make_type("AnnAssign", stmt_type, AnnAssign_fields, 4); + if (!AnnAssign_type) return 0; + For_type = make_type("For", stmt_type, For_fields, 5); + if (!For_type) return 0; + AsyncFor_type = make_type("AsyncFor", stmt_type, AsyncFor_fields, 5); + if (!AsyncFor_type) return 0; + While_type = make_type("While", stmt_type, While_fields, 3); + if (!While_type) return 0; + If_type = make_type("If", stmt_type, If_fields, 3); + if (!If_type) return 0; + With_type = make_type("With", stmt_type, With_fields, 3); + if (!With_type) return 0; + AsyncWith_type = make_type("AsyncWith", stmt_type, AsyncWith_fields, 3); + if (!AsyncWith_type) return 0; + Raise_type = make_type("Raise", stmt_type, Raise_fields, 2); + if (!Raise_type) return 0; + Try_type = make_type("Try", stmt_type, Try_fields, 4); + if (!Try_type) return 0; + Assert_type = make_type("Assert", stmt_type, Assert_fields, 2); + if (!Assert_type) return 0; + Import_type = make_type("Import", stmt_type, Import_fields, 1); + if (!Import_type) return 0; + ImportFrom_type = make_type("ImportFrom", stmt_type, ImportFrom_fields, 3); + if (!ImportFrom_type) return 0; + Global_type = make_type("Global", stmt_type, Global_fields, 1); + if (!Global_type) return 0; + Nonlocal_type = make_type("Nonlocal", stmt_type, Nonlocal_fields, 1); + if (!Nonlocal_type) return 0; + Expr_type = make_type("Expr", stmt_type, Expr_fields, 1); + if (!Expr_type) return 0; + Pass_type = make_type("Pass", stmt_type, NULL, 0); + if (!Pass_type) return 0; + Break_type = make_type("Break", stmt_type, NULL, 0); + if (!Break_type) return 0; + Continue_type = make_type("Continue", stmt_type, NULL, 0); + if (!Continue_type) return 0; + expr_type = make_type("expr", &AST_type, NULL, 0); + if (!expr_type) return 0; + if (!add_attributes(expr_type, expr_attributes, 4)) return 0; + BoolOp_type = make_type("BoolOp", expr_type, BoolOp_fields, 2); + if (!BoolOp_type) return 0; + NamedExpr_type = make_type("NamedExpr", expr_type, NamedExpr_fields, 2); + if (!NamedExpr_type) return 0; + BinOp_type = make_type("BinOp", expr_type, BinOp_fields, 3); + if (!BinOp_type) return 0; + UnaryOp_type = make_type("UnaryOp", expr_type, UnaryOp_fields, 2); + if (!UnaryOp_type) return 0; + Lambda_type = make_type("Lambda", expr_type, Lambda_fields, 2); + if (!Lambda_type) return 0; + IfExp_type = make_type("IfExp", expr_type, IfExp_fields, 3); + if (!IfExp_type) return 0; + Dict_type = make_type("Dict", expr_type, Dict_fields, 2); + if (!Dict_type) return 0; + Set_type = make_type("Set", expr_type, Set_fields, 1); + if (!Set_type) return 0; + ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2); + if (!ListComp_type) return 0; + SetComp_type = make_type("SetComp", expr_type, SetComp_fields, 2); + if (!SetComp_type) return 0; + DictComp_type = make_type("DictComp", expr_type, DictComp_fields, 3); + if (!DictComp_type) return 0; + GeneratorExp_type = make_type("GeneratorExp", expr_type, + GeneratorExp_fields, 2); + if (!GeneratorExp_type) return 0; + Await_type = make_type("Await", expr_type, Await_fields, 1); + if (!Await_type) return 0; + Yield_type = make_type("Yield", expr_type, Yield_fields, 1); + if (!Yield_type) return 0; + YieldFrom_type = make_type("YieldFrom", expr_type, YieldFrom_fields, 1); + if (!YieldFrom_type) return 0; + Compare_type = make_type("Compare", expr_type, Compare_fields, 3); + if (!Compare_type) return 0; + Call_type = make_type("Call", expr_type, Call_fields, 3); + if (!Call_type) return 0; + FormattedValue_type = make_type("FormattedValue", expr_type, + FormattedValue_fields, 3); + if (!FormattedValue_type) return 0; + JoinedStr_type = make_type("JoinedStr", expr_type, JoinedStr_fields, 1); + if (!JoinedStr_type) return 0; + Constant_type = make_type("Constant", expr_type, Constant_fields, 2); + if (!Constant_type) return 0; + Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3); + if (!Attribute_type) return 0; + Subscript_type = make_type("Subscript", expr_type, Subscript_fields, 3); + if (!Subscript_type) return 0; + Starred_type = make_type("Starred", expr_type, Starred_fields, 2); + if (!Starred_type) return 0; + Name_type = make_type("Name", expr_type, Name_fields, 2); + if (!Name_type) return 0; + List_type = make_type("List", expr_type, List_fields, 2); + if (!List_type) return 0; + Tuple_type = make_type("Tuple", expr_type, Tuple_fields, 2); + if (!Tuple_type) return 0; + expr_context_type = make_type("expr_context", &AST_type, NULL, 0); + if (!expr_context_type) return 0; + if (!add_attributes(expr_context_type, NULL, 0)) return 0; + Load_type = make_type("Load", expr_context_type, NULL, 0); + if (!Load_type) return 0; + Load_singleton = PyType_GenericNew(Load_type, NULL, NULL); + if (!Load_singleton) return 0; + Store_type = make_type("Store", expr_context_type, NULL, 0); + if (!Store_type) return 0; + Store_singleton = PyType_GenericNew(Store_type, NULL, NULL); + if (!Store_singleton) return 0; + Del_type = make_type("Del", expr_context_type, NULL, 0); + if (!Del_type) return 0; + Del_singleton = PyType_GenericNew(Del_type, NULL, NULL); + if (!Del_singleton) return 0; + AugLoad_type = make_type("AugLoad", expr_context_type, NULL, 0); + if (!AugLoad_type) return 0; + AugLoad_singleton = PyType_GenericNew(AugLoad_type, NULL, NULL); + if (!AugLoad_singleton) return 0; + AugStore_type = make_type("AugStore", expr_context_type, NULL, 0); + if (!AugStore_type) return 0; + AugStore_singleton = PyType_GenericNew(AugStore_type, NULL, NULL); + if (!AugStore_singleton) return 0; + Param_type = make_type("Param", expr_context_type, NULL, 0); + if (!Param_type) return 0; + Param_singleton = PyType_GenericNew(Param_type, NULL, NULL); + if (!Param_singleton) return 0; + slice_type = make_type("slice", &AST_type, NULL, 0); + if (!slice_type) return 0; + if (!add_attributes(slice_type, NULL, 0)) return 0; + Slice_type = make_type("Slice", slice_type, Slice_fields, 3); + if (!Slice_type) return 0; + ExtSlice_type = make_type("ExtSlice", slice_type, ExtSlice_fields, 1); + if (!ExtSlice_type) return 0; + Index_type = make_type("Index", slice_type, Index_fields, 1); + if (!Index_type) return 0; + boolop_type = make_type("boolop", &AST_type, NULL, 0); + if (!boolop_type) return 0; + if (!add_attributes(boolop_type, NULL, 0)) return 0; + And_type = make_type("And", boolop_type, NULL, 0); + if (!And_type) return 0; + And_singleton = PyType_GenericNew(And_type, NULL, NULL); + if (!And_singleton) return 0; + Or_type = make_type("Or", boolop_type, NULL, 0); + if (!Or_type) return 0; + Or_singleton = PyType_GenericNew(Or_type, NULL, NULL); + if (!Or_singleton) return 0; + operator_type = make_type("operator", &AST_type, NULL, 0); + if (!operator_type) return 0; + if (!add_attributes(operator_type, NULL, 0)) return 0; + Add_type = make_type("Add", operator_type, NULL, 0); + if (!Add_type) return 0; + Add_singleton = PyType_GenericNew(Add_type, NULL, NULL); + if (!Add_singleton) return 0; + Sub_type = make_type("Sub", operator_type, NULL, 0); + if (!Sub_type) return 0; + Sub_singleton = PyType_GenericNew(Sub_type, NULL, NULL); + if (!Sub_singleton) return 0; + Mult_type = make_type("Mult", operator_type, NULL, 0); + if (!Mult_type) return 0; + Mult_singleton = PyType_GenericNew(Mult_type, NULL, NULL); + if (!Mult_singleton) return 0; + MatMult_type = make_type("MatMult", operator_type, NULL, 0); + if (!MatMult_type) return 0; + MatMult_singleton = PyType_GenericNew(MatMult_type, NULL, NULL); + if (!MatMult_singleton) return 0; + Div_type = make_type("Div", operator_type, NULL, 0); + if (!Div_type) return 0; + Div_singleton = PyType_GenericNew(Div_type, NULL, NULL); + if (!Div_singleton) return 0; + Mod_type = make_type("Mod", operator_type, NULL, 0); + if (!Mod_type) return 0; + Mod_singleton = PyType_GenericNew(Mod_type, NULL, NULL); + if (!Mod_singleton) return 0; + Pow_type = make_type("Pow", operator_type, NULL, 0); + if (!Pow_type) return 0; + Pow_singleton = PyType_GenericNew(Pow_type, NULL, NULL); + if (!Pow_singleton) return 0; + LShift_type = make_type("LShift", operator_type, NULL, 0); + if (!LShift_type) return 0; + LShift_singleton = PyType_GenericNew(LShift_type, NULL, NULL); + if (!LShift_singleton) return 0; + RShift_type = make_type("RShift", operator_type, NULL, 0); + if (!RShift_type) return 0; + RShift_singleton = PyType_GenericNew(RShift_type, NULL, NULL); + if (!RShift_singleton) return 0; + BitOr_type = make_type("BitOr", operator_type, NULL, 0); + if (!BitOr_type) return 0; + BitOr_singleton = PyType_GenericNew(BitOr_type, NULL, NULL); + if (!BitOr_singleton) return 0; + BitXor_type = make_type("BitXor", operator_type, NULL, 0); + if (!BitXor_type) return 0; + BitXor_singleton = PyType_GenericNew(BitXor_type, NULL, NULL); + if (!BitXor_singleton) return 0; + BitAnd_type = make_type("BitAnd", operator_type, NULL, 0); + if (!BitAnd_type) return 0; + BitAnd_singleton = PyType_GenericNew(BitAnd_type, NULL, NULL); + if (!BitAnd_singleton) return 0; + FloorDiv_type = make_type("FloorDiv", operator_type, NULL, 0); + if (!FloorDiv_type) return 0; + FloorDiv_singleton = PyType_GenericNew(FloorDiv_type, NULL, NULL); + if (!FloorDiv_singleton) return 0; + unaryop_type = make_type("unaryop", &AST_type, NULL, 0); + if (!unaryop_type) return 0; + if (!add_attributes(unaryop_type, NULL, 0)) return 0; + Invert_type = make_type("Invert", unaryop_type, NULL, 0); + if (!Invert_type) return 0; + Invert_singleton = PyType_GenericNew(Invert_type, NULL, NULL); + if (!Invert_singleton) return 0; + Not_type = make_type("Not", unaryop_type, NULL, 0); + if (!Not_type) return 0; + Not_singleton = PyType_GenericNew(Not_type, NULL, NULL); + if (!Not_singleton) return 0; + UAdd_type = make_type("UAdd", unaryop_type, NULL, 0); + if (!UAdd_type) return 0; + UAdd_singleton = PyType_GenericNew(UAdd_type, NULL, NULL); + if (!UAdd_singleton) return 0; + USub_type = make_type("USub", unaryop_type, NULL, 0); + if (!USub_type) return 0; + USub_singleton = PyType_GenericNew(USub_type, NULL, NULL); + if (!USub_singleton) return 0; + cmpop_type = make_type("cmpop", &AST_type, NULL, 0); + if (!cmpop_type) return 0; + if (!add_attributes(cmpop_type, NULL, 0)) return 0; + Eq_type = make_type("Eq", cmpop_type, NULL, 0); + if (!Eq_type) return 0; + Eq_singleton = PyType_GenericNew(Eq_type, NULL, NULL); + if (!Eq_singleton) return 0; + NotEq_type = make_type("NotEq", cmpop_type, NULL, 0); + if (!NotEq_type) return 0; + NotEq_singleton = PyType_GenericNew(NotEq_type, NULL, NULL); + if (!NotEq_singleton) return 0; + Lt_type = make_type("Lt", cmpop_type, NULL, 0); + if (!Lt_type) return 0; + Lt_singleton = PyType_GenericNew(Lt_type, NULL, NULL); + if (!Lt_singleton) return 0; + LtE_type = make_type("LtE", cmpop_type, NULL, 0); + if (!LtE_type) return 0; + LtE_singleton = PyType_GenericNew(LtE_type, NULL, NULL); + if (!LtE_singleton) return 0; + Gt_type = make_type("Gt", cmpop_type, NULL, 0); + if (!Gt_type) return 0; + Gt_singleton = PyType_GenericNew(Gt_type, NULL, NULL); + if (!Gt_singleton) return 0; + GtE_type = make_type("GtE", cmpop_type, NULL, 0); + if (!GtE_type) return 0; + GtE_singleton = PyType_GenericNew(GtE_type, NULL, NULL); + if (!GtE_singleton) return 0; + Is_type = make_type("Is", cmpop_type, NULL, 0); + if (!Is_type) return 0; + Is_singleton = PyType_GenericNew(Is_type, NULL, NULL); + if (!Is_singleton) return 0; + IsNot_type = make_type("IsNot", cmpop_type, NULL, 0); + if (!IsNot_type) return 0; + IsNot_singleton = PyType_GenericNew(IsNot_type, NULL, NULL); + if (!IsNot_singleton) return 0; + In_type = make_type("In", cmpop_type, NULL, 0); + if (!In_type) return 0; + In_singleton = PyType_GenericNew(In_type, NULL, NULL); + if (!In_singleton) return 0; + NotIn_type = make_type("NotIn", cmpop_type, NULL, 0); + if (!NotIn_type) return 0; + NotIn_singleton = PyType_GenericNew(NotIn_type, NULL, NULL); + if (!NotIn_singleton) return 0; + comprehension_type = make_type("comprehension", &AST_type, + comprehension_fields, 4); + if (!comprehension_type) return 0; + if (!add_attributes(comprehension_type, NULL, 0)) return 0; + excepthandler_type = make_type("excepthandler", &AST_type, NULL, 0); + if (!excepthandler_type) return 0; + if (!add_attributes(excepthandler_type, excepthandler_attributes, 4)) + return 0; + ExceptHandler_type = make_type("ExceptHandler", excepthandler_type, + ExceptHandler_fields, 3); + if (!ExceptHandler_type) return 0; + arguments_type = make_type("arguments", &AST_type, arguments_fields, 7); + if (!arguments_type) return 0; + if (!add_attributes(arguments_type, NULL, 0)) return 0; + arg_type = make_type("arg", &AST_type, arg_fields, 3); + if (!arg_type) return 0; + if (!add_attributes(arg_type, arg_attributes, 4)) return 0; + keyword_type = make_type("keyword", &AST_type, keyword_fields, 2); + if (!keyword_type) return 0; + if (!add_attributes(keyword_type, NULL, 0)) return 0; + alias_type = make_type("alias", &AST_type, alias_fields, 2); + if (!alias_type) return 0; + if (!add_attributes(alias_type, NULL, 0)) return 0; + withitem_type = make_type("withitem", &AST_type, withitem_fields, 2); + if (!withitem_type) return 0; + if (!add_attributes(withitem_type, NULL, 0)) return 0; + type_ignore_type = make_type("type_ignore", &AST_type, NULL, 0); + if (!type_ignore_type) return 0; + if (!add_attributes(type_ignore_type, NULL, 0)) return 0; + TypeIgnore_type = make_type("TypeIgnore", type_ignore_type, + TypeIgnore_fields, 2); + if (!TypeIgnore_type) return 0; + initialized = 1; + return 1; +} + +static int obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena); +static int obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena); +static int obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena); +static int obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* + arena); +static int obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena); +static int obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena); +static int obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena); +static int obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena); +static int obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena); +static int obj2ast_comprehension(PyObject* obj, comprehension_ty* out, PyArena* + arena); +static int obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* + arena); +static int obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena); +static int obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena); +static int obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena); +static int obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena); +static int obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena); +static int obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* + arena); + +mod_ty +Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena) +{ + mod_ty p; + p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Module_kind; + p->v.Module.body = body; + p->v.Module.type_ignores = type_ignores; + return p; +} + +mod_ty +Interactive(asdl_seq * body, PyArena *arena) +{ + mod_ty p; + p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Interactive_kind; + p->v.Interactive.body = body; + return p; +} + +mod_ty +Expression(expr_ty body, PyArena *arena) +{ + mod_ty p; + if (!body) { + PyErr_SetString(PyExc_ValueError, + "field body is required for Expression"); + return NULL; + } + p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Expression_kind; + p->v.Expression.body = body; + return p; +} + +mod_ty +FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena) +{ + mod_ty p; + if (!returns) { + PyErr_SetString(PyExc_ValueError, + "field returns is required for FunctionType"); + return NULL; + } + p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = FunctionType_kind; + p->v.FunctionType.argtypes = argtypes; + p->v.FunctionType.returns = returns; + return p; +} + +mod_ty +Suite(asdl_seq * body, PyArena *arena) +{ + mod_ty p; + p = (mod_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Suite_kind; + p->v.Suite.body = body; + return p; +} + +stmt_ty +FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * + decorator_list, expr_ty returns, string type_comment, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field name is required for FunctionDef"); + return NULL; + } + if (!args) { + PyErr_SetString(PyExc_ValueError, + "field args is required for FunctionDef"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = FunctionDef_kind; + p->v.FunctionDef.name = name; + p->v.FunctionDef.args = args; + p->v.FunctionDef.body = body; + p->v.FunctionDef.decorator_list = decorator_list; + p->v.FunctionDef.returns = returns; + p->v.FunctionDef.type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq + * decorator_list, expr_ty returns, string type_comment, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) +{ + stmt_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field name is required for AsyncFunctionDef"); + return NULL; + } + if (!args) { + PyErr_SetString(PyExc_ValueError, + "field args is required for AsyncFunctionDef"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = AsyncFunctionDef_kind; + p->v.AsyncFunctionDef.name = name; + p->v.AsyncFunctionDef.args = args; + p->v.AsyncFunctionDef.body = body; + p->v.AsyncFunctionDef.decorator_list = decorator_list; + p->v.AsyncFunctionDef.returns = returns; + p->v.AsyncFunctionDef.type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, asdl_seq * + body, asdl_seq * decorator_list, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field name is required for ClassDef"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = ClassDef_kind; + p->v.ClassDef.name = name; + p->v.ClassDef.bases = bases; + p->v.ClassDef.keywords = keywords; + p->v.ClassDef.body = body; + p->v.ClassDef.decorator_list = decorator_list; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Return(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Return_kind; + p->v.Return.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Delete(asdl_seq * targets, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Delete_kind; + p->v.Delete.targets = targets; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Assign"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Assign_kind; + p->v.Assign.targets = targets; + p->v.Assign.value = value; + p->v.Assign.type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for AugAssign"); + return NULL; + } + if (!op) { + PyErr_SetString(PyExc_ValueError, + "field op is required for AugAssign"); + return NULL; + } + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for AugAssign"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = AugAssign_kind; + p->v.AugAssign.target = target; + p->v.AugAssign.op = op; + p->v.AugAssign.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int + lineno, int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) +{ + stmt_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for AnnAssign"); + return NULL; + } + if (!annotation) { + PyErr_SetString(PyExc_ValueError, + "field annotation is required for AnnAssign"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = AnnAssign_kind; + p->v.AnnAssign.target = target; + p->v.AnnAssign.annotation = annotation; + p->v.AnnAssign.value = value; + p->v.AnnAssign.simple = simple; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string + type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for For"); + return NULL; + } + if (!iter) { + PyErr_SetString(PyExc_ValueError, + "field iter is required for For"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = For_kind; + p->v.For.target = target; + p->v.For.iter = iter; + p->v.For.body = body; + p->v.For.orelse = orelse; + p->v.For.type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, + string type_comment, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for AsyncFor"); + return NULL; + } + if (!iter) { + PyErr_SetString(PyExc_ValueError, + "field iter is required for AsyncFor"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = AsyncFor_kind; + p->v.AsyncFor.target = target; + p->v.AsyncFor.iter = iter; + p->v.AsyncFor.body = body; + p->v.AsyncFor.orelse = orelse; + p->v.AsyncFor.type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!test) { + PyErr_SetString(PyExc_ValueError, + "field test is required for While"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = While_kind; + p->v.While.test = test; + p->v.While.body = body; + p->v.While.orelse = orelse; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!test) { + PyErr_SetString(PyExc_ValueError, + "field test is required for If"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = If_kind; + p->v.If.test = test; + p->v.If.body = body; + p->v.If.orelse = orelse; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +With(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = With_kind; + p->v.With.items = items; + p->v.With.body = body; + p->v.With.type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = AsyncWith_kind; + p->v.AsyncWith.items = items; + p->v.AsyncWith.body = body; + p->v.AsyncWith.type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Raise_kind; + p->v.Raise.exc = exc; + p->v.Raise.cause = cause; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq * + finalbody, int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Try_kind; + p->v.Try.body = body; + p->v.Try.handlers = handlers; + p->v.Try.orelse = orelse; + p->v.Try.finalbody = finalbody; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!test) { + PyErr_SetString(PyExc_ValueError, + "field test is required for Assert"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Assert_kind; + p->v.Assert.test = test; + p->v.Assert.msg = msg; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Import(asdl_seq * names, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Import_kind; + p->v.Import.names = names; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = ImportFrom_kind; + p->v.ImportFrom.module = module; + p->v.ImportFrom.names = names; + p->v.ImportFrom.level = level; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Global(asdl_seq * names, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Global_kind; + p->v.Global.names = names; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Nonlocal(asdl_seq * names, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Nonlocal_kind; + p->v.Nonlocal.names = names; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Expr"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Expr_kind; + p->v.Expr.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Pass(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Pass_kind; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Break(int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Break_kind; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +stmt_ty +Continue(int lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena) +{ + stmt_ty p; + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Continue_kind; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!op) { + PyErr_SetString(PyExc_ValueError, + "field op is required for BoolOp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = BoolOp_kind; + p->v.BoolOp.op = op; + p->v.BoolOp.values = values; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for NamedExpr"); + return NULL; + } + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for NamedExpr"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = NamedExpr_kind; + p->v.NamedExpr.target = target; + p->v.NamedExpr.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!left) { + PyErr_SetString(PyExc_ValueError, + "field left is required for BinOp"); + return NULL; + } + if (!op) { + PyErr_SetString(PyExc_ValueError, + "field op is required for BinOp"); + return NULL; + } + if (!right) { + PyErr_SetString(PyExc_ValueError, + "field right is required for BinOp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = BinOp_kind; + p->v.BinOp.left = left; + p->v.BinOp.op = op; + p->v.BinOp.right = right; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!op) { + PyErr_SetString(PyExc_ValueError, + "field op is required for UnaryOp"); + return NULL; + } + if (!operand) { + PyErr_SetString(PyExc_ValueError, + "field operand is required for UnaryOp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = UnaryOp_kind; + p->v.UnaryOp.op = op; + p->v.UnaryOp.operand = operand; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!args) { + PyErr_SetString(PyExc_ValueError, + "field args is required for Lambda"); + return NULL; + } + if (!body) { + PyErr_SetString(PyExc_ValueError, + "field body is required for Lambda"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Lambda_kind; + p->v.Lambda.args = args; + p->v.Lambda.body = body; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!test) { + PyErr_SetString(PyExc_ValueError, + "field test is required for IfExp"); + return NULL; + } + if (!body) { + PyErr_SetString(PyExc_ValueError, + "field body is required for IfExp"); + return NULL; + } + if (!orelse) { + PyErr_SetString(PyExc_ValueError, + "field orelse is required for IfExp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = IfExp_kind; + p->v.IfExp.test = test; + p->v.IfExp.body = body; + p->v.IfExp.orelse = orelse; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Dict_kind; + p->v.Dict.keys = keys; + p->v.Dict.values = values; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + expr_ty p; + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Set_kind; + p->v.Set.elts = elts; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!elt) { + PyErr_SetString(PyExc_ValueError, + "field elt is required for ListComp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = ListComp_kind; + p->v.ListComp.elt = elt; + p->v.ListComp.generators = generators; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!elt) { + PyErr_SetString(PyExc_ValueError, + "field elt is required for SetComp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = SetComp_kind; + p->v.SetComp.elt = elt; + p->v.SetComp.generators = generators; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!key) { + PyErr_SetString(PyExc_ValueError, + "field key is required for DictComp"); + return NULL; + } + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for DictComp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = DictComp_kind; + p->v.DictComp.key = key; + p->v.DictComp.value = value; + p->v.DictComp.generators = generators; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!elt) { + PyErr_SetString(PyExc_ValueError, + "field elt is required for GeneratorExp"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = GeneratorExp_kind; + p->v.GeneratorExp.elt = elt; + p->v.GeneratorExp.generators = generators; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Await(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Await"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Await_kind; + p->v.Await.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + expr_ty p; + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Yield_kind; + p->v.Yield.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for YieldFrom"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = YieldFrom_kind; + p->v.YieldFrom.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!left) { + PyErr_SetString(PyExc_ValueError, + "field left is required for Compare"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Compare_kind; + p->v.Compare.left = left; + p->v.Compare.ops = ops; + p->v.Compare.comparators = comparators; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!func) { + PyErr_SetString(PyExc_ValueError, + "field func is required for Call"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Call_kind; + p->v.Call.func = func; + p->v.Call.args = args; + p->v.Call.keywords = keywords; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) +{ + expr_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for FormattedValue"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = FormattedValue_kind; + p->v.FormattedValue.value = value; + p->v.FormattedValue.conversion = conversion; + p->v.FormattedValue.format_spec = format_spec; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + expr_ty p; + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = JoinedStr_kind; + p->v.JoinedStr.values = values; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Constant(constant value, string kind, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Constant"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Constant_kind; + p->v.Constant.value = value; + p->v.Constant.kind = kind; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Attribute"); + return NULL; + } + if (!attr) { + PyErr_SetString(PyExc_ValueError, + "field attr is required for Attribute"); + return NULL; + } + if (!ctx) { + PyErr_SetString(PyExc_ValueError, + "field ctx is required for Attribute"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Attribute_kind; + p->v.Attribute.value = value; + p->v.Attribute.attr = attr; + p->v.Attribute.ctx = ctx; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Subscript"); + return NULL; + } + if (!slice) { + PyErr_SetString(PyExc_ValueError, + "field slice is required for Subscript"); + return NULL; + } + if (!ctx) { + PyErr_SetString(PyExc_ValueError, + "field ctx is required for Subscript"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Subscript_kind; + p->v.Subscript.value = value; + p->v.Subscript.slice = slice; + p->v.Subscript.ctx = ctx; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Starred"); + return NULL; + } + if (!ctx) { + PyErr_SetString(PyExc_ValueError, + "field ctx is required for Starred"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Starred_kind; + p->v.Starred.value = value; + p->v.Starred.ctx = ctx; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!id) { + PyErr_SetString(PyExc_ValueError, + "field id is required for Name"); + return NULL; + } + if (!ctx) { + PyErr_SetString(PyExc_ValueError, + "field ctx is required for Name"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Name_kind; + p->v.Name.id = id; + p->v.Name.ctx = ctx; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!ctx) { + PyErr_SetString(PyExc_ValueError, + "field ctx is required for List"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = List_kind; + p->v.List.elts = elts; + p->v.List.ctx = ctx; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +expr_ty +Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + expr_ty p; + if (!ctx) { + PyErr_SetString(PyExc_ValueError, + "field ctx is required for Tuple"); + return NULL; + } + p = (expr_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Tuple_kind; + p->v.Tuple.elts = elts; + p->v.Tuple.ctx = ctx; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +slice_ty +Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena) +{ + slice_ty p; + p = (slice_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Slice_kind; + p->v.Slice.lower = lower; + p->v.Slice.upper = upper; + p->v.Slice.step = step; + return p; +} + +slice_ty +ExtSlice(asdl_seq * dims, PyArena *arena) +{ + slice_ty p; + p = (slice_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = ExtSlice_kind; + p->v.ExtSlice.dims = dims; + return p; +} + +slice_ty +Index(expr_ty value, PyArena *arena) +{ + slice_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for Index"); + return NULL; + } + p = (slice_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = Index_kind; + p->v.Index.value = value; + return p; +} + +comprehension_ty +comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, int is_async, + PyArena *arena) +{ + comprehension_ty p; + if (!target) { + PyErr_SetString(PyExc_ValueError, + "field target is required for comprehension"); + return NULL; + } + if (!iter) { + PyErr_SetString(PyExc_ValueError, + "field iter is required for comprehension"); + return NULL; + } + p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->target = target; + p->iter = iter; + p->ifs = ifs; + p->is_async = is_async; + return p; +} + +excepthandler_ty +ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + excepthandler_ty p; + p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = ExceptHandler_kind; + p->v.ExceptHandler.type = type; + p->v.ExceptHandler.name = name; + p->v.ExceptHandler.body = body; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +arguments_ty +arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty vararg, asdl_seq * + kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq * + defaults, PyArena *arena) +{ + arguments_ty p; + p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->posonlyargs = posonlyargs; + p->args = args; + p->vararg = vararg; + p->kwonlyargs = kwonlyargs; + p->kw_defaults = kw_defaults; + p->kwarg = kwarg; + p->defaults = defaults; + return p; +} + +arg_ty +arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena *arena) +{ + arg_ty p; + if (!arg) { + PyErr_SetString(PyExc_ValueError, + "field arg is required for arg"); + return NULL; + } + p = (arg_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->arg = arg; + p->annotation = annotation; + p->type_comment = type_comment; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +keyword_ty +keyword(identifier arg, expr_ty value, PyArena *arena) +{ + keyword_ty p; + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field value is required for keyword"); + return NULL; + } + p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->arg = arg; + p->value = value; + return p; +} + +alias_ty +alias(identifier name, identifier asname, PyArena *arena) +{ + alias_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field name is required for alias"); + return NULL; + } + p = (alias_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->name = name; + p->asname = asname; + return p; +} + +withitem_ty +withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) +{ + withitem_ty p; + if (!context_expr) { + PyErr_SetString(PyExc_ValueError, + "field context_expr is required for withitem"); + return NULL; + } + p = (withitem_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->context_expr = context_expr; + p->optional_vars = optional_vars; + return p; +} + +type_ignore_ty +TypeIgnore(int lineno, string tag, PyArena *arena) +{ + type_ignore_ty p; + if (!tag) { + PyErr_SetString(PyExc_ValueError, + "field tag is required for TypeIgnore"); + return NULL; + } + p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = TypeIgnore_kind; + p->v.TypeIgnore.lineno = lineno; + p->v.TypeIgnore.tag = tag; + return p; +} + + +PyObject* +ast2obj_mod(void* _o) +{ + mod_ty o = (mod_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + switch (o->kind) { + case Module_kind: + result = PyType_GenericNew(Module_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Module.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Module.type_ignores, ast2obj_type_ignore); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_ignores, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Interactive_kind: + result = PyType_GenericNew(Interactive_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Interactive.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Expression_kind: + result = PyType_GenericNew(Expression_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Expression.body); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + break; + case FunctionType_kind: + result = PyType_GenericNew(FunctionType_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.FunctionType.argtypes, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_argtypes, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.FunctionType.returns); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Suite_kind: + result = PyType_GenericNew(Suite_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Suite.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + break; + } + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_stmt(void* _o) +{ + stmt_ty o = (stmt_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + switch (o->kind) { + case FunctionDef_kind: + result = PyType_GenericNew(FunctionDef_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(o->v.FunctionDef.name); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_name, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_arguments(o->v.FunctionDef.args); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.FunctionDef.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.FunctionDef.decorator_list, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_decorator_list, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.FunctionDef.returns); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.FunctionDef.type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + break; + case AsyncFunctionDef_kind: + result = PyType_GenericNew(AsyncFunctionDef_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(o->v.AsyncFunctionDef.name); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_name, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_arguments(o->v.AsyncFunctionDef.args); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.AsyncFunctionDef.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.AsyncFunctionDef.decorator_list, + ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_decorator_list, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.AsyncFunctionDef.returns); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.AsyncFunctionDef.type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + break; + case ClassDef_kind: + result = PyType_GenericNew(ClassDef_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(o->v.ClassDef.name); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_name, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.ClassDef.bases, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_bases, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.ClassDef.keywords, ast2obj_keyword); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_keywords, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.ClassDef.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.ClassDef.decorator_list, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_decorator_list, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Return_kind: + result = PyType_GenericNew(Return_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Return.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Delete_kind: + result = PyType_GenericNew(Delete_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Delete.targets, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_targets, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Assign_kind: + result = PyType_GenericNew(Assign_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Assign.targets, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_targets, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.Assign.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.Assign.type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + break; + case AugAssign_kind: + result = PyType_GenericNew(AugAssign_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.AugAssign.target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_operator(o->v.AugAssign.op); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_op, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.AugAssign.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case AnnAssign_kind: + result = PyType_GenericNew(AnnAssign_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.AnnAssign.target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.AnnAssign.annotation); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_annotation, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.AnnAssign.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->v.AnnAssign.simple); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_simple, value) == -1) + goto failed; + Py_DECREF(value); + break; + case For_kind: + result = PyType_GenericNew(For_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.For.target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.For.iter); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_iter, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.For.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.For.orelse, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.For.type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + break; + case AsyncFor_kind: + result = PyType_GenericNew(AsyncFor_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.AsyncFor.target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.AsyncFor.iter); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_iter, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.AsyncFor.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.AsyncFor.orelse, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.AsyncFor.type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + break; + case While_kind: + result = PyType_GenericNew(While_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.While.test); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_test, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.While.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.While.orelse, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1) + goto failed; + Py_DECREF(value); + break; + case If_kind: + result = PyType_GenericNew(If_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.If.test); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_test, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.If.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.If.orelse, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1) + goto failed; + Py_DECREF(value); + break; + case With_kind: + result = PyType_GenericNew(With_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.With.items, ast2obj_withitem); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_items, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.With.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.With.type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + break; + case AsyncWith_kind: + result = PyType_GenericNew(AsyncWith_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.AsyncWith.items, ast2obj_withitem); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_items, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.AsyncWith.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.AsyncWith.type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Raise_kind: + result = PyType_GenericNew(Raise_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Raise.exc); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_exc, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.Raise.cause); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_cause, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Try_kind: + result = PyType_GenericNew(Try_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Try.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Try.handlers, ast2obj_excepthandler); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_handlers, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Try.orelse, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Try.finalbody, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_finalbody, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Assert_kind: + result = PyType_GenericNew(Assert_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Assert.test); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_test, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.Assert.msg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_msg, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Import_kind: + result = PyType_GenericNew(Import_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Import.names, ast2obj_alias); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_names, value) == -1) + goto failed; + Py_DECREF(value); + break; + case ImportFrom_kind: + result = PyType_GenericNew(ImportFrom_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(o->v.ImportFrom.module); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_module, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.ImportFrom.names, ast2obj_alias); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_names, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->v.ImportFrom.level); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_level, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Global_kind: + result = PyType_GenericNew(Global_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Global.names, ast2obj_identifier); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_names, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Nonlocal_kind: + result = PyType_GenericNew(Nonlocal_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Nonlocal.names, ast2obj_identifier); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_names, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Expr_kind: + result = PyType_GenericNew(Expr_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Expr.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Pass_kind: + result = PyType_GenericNew(Pass_type, NULL, NULL); + if (!result) goto failed; + break; + case Break_kind: + result = PyType_GenericNew(Break_type, NULL, NULL); + if (!result) goto failed; + break; + case Continue_kind: + result = PyType_GenericNew(Continue_type, NULL, NULL); + if (!result) goto failed; + break; + } + value = ast2obj_int(o->lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_expr(void* _o) +{ + expr_ty o = (expr_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + switch (o->kind) { + case BoolOp_kind: + result = PyType_GenericNew(BoolOp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_boolop(o->v.BoolOp.op); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_op, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.BoolOp.values, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_values, value) == -1) + goto failed; + Py_DECREF(value); + break; + case NamedExpr_kind: + result = PyType_GenericNew(NamedExpr_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.NamedExpr.target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.NamedExpr.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case BinOp_kind: + result = PyType_GenericNew(BinOp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.BinOp.left); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_left, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_operator(o->v.BinOp.op); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_op, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.BinOp.right); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_right, value) == -1) + goto failed; + Py_DECREF(value); + break; + case UnaryOp_kind: + result = PyType_GenericNew(UnaryOp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_unaryop(o->v.UnaryOp.op); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_op, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.UnaryOp.operand); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_operand, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Lambda_kind: + result = PyType_GenericNew(Lambda_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_arguments(o->v.Lambda.args); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.Lambda.body); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + break; + case IfExp_kind: + result = PyType_GenericNew(IfExp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.IfExp.test); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_test, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.IfExp.body); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.IfExp.orelse); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Dict_kind: + result = PyType_GenericNew(Dict_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Dict.keys, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_keys, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Dict.values, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_values, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Set_kind: + result = PyType_GenericNew(Set_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Set.elts, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_elts, value) == -1) + goto failed; + Py_DECREF(value); + break; + case ListComp_kind: + result = PyType_GenericNew(ListComp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.ListComp.elt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_elt, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.ListComp.generators, ast2obj_comprehension); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_generators, value) == -1) + goto failed; + Py_DECREF(value); + break; + case SetComp_kind: + result = PyType_GenericNew(SetComp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.SetComp.elt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_elt, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.SetComp.generators, ast2obj_comprehension); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_generators, value) == -1) + goto failed; + Py_DECREF(value); + break; + case DictComp_kind: + result = PyType_GenericNew(DictComp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.DictComp.key); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_key, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.DictComp.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.DictComp.generators, ast2obj_comprehension); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_generators, value) == -1) + goto failed; + Py_DECREF(value); + break; + case GeneratorExp_kind: + result = PyType_GenericNew(GeneratorExp_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.GeneratorExp.elt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_elt, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.GeneratorExp.generators, + ast2obj_comprehension); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_generators, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Await_kind: + result = PyType_GenericNew(Await_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Await.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Yield_kind: + result = PyType_GenericNew(Yield_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Yield.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case YieldFrom_kind: + result = PyType_GenericNew(YieldFrom_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.YieldFrom.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Compare_kind: + result = PyType_GenericNew(Compare_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Compare.left); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_left, value) == -1) + goto failed; + Py_DECREF(value); + { + Py_ssize_t i, n = asdl_seq_LEN(o->v.Compare.ops); + value = PyList_New(n); + if (!value) goto failed; + for(i = 0; i < n; i++) + PyList_SET_ITEM(value, i, ast2obj_cmpop((cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i))); + } + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ops, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Compare.comparators, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_comparators, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Call_kind: + result = PyType_GenericNew(Call_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Call.func); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_func, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Call.args, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.Call.keywords, ast2obj_keyword); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_keywords, value) == -1) + goto failed; + Py_DECREF(value); + break; + case FormattedValue_kind: + result = PyType_GenericNew(FormattedValue_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.FormattedValue.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->v.FormattedValue.conversion); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_conversion, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.FormattedValue.format_spec); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_format_spec, value) == -1) + goto failed; + Py_DECREF(value); + break; + case JoinedStr_kind: + result = PyType_GenericNew(JoinedStr_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.JoinedStr.values, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_values, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Constant_kind: + result = PyType_GenericNew(Constant_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_constant(o->v.Constant.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.Constant.kind); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_kind, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Attribute_kind: + result = PyType_GenericNew(Attribute_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Attribute.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_identifier(o->v.Attribute.attr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_attr, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr_context(o->v.Attribute.ctx); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ctx, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Subscript_kind: + result = PyType_GenericNew(Subscript_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Subscript.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_slice(o->v.Subscript.slice); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_slice, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr_context(o->v.Subscript.ctx); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ctx, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Starred_kind: + result = PyType_GenericNew(Starred_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Starred.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr_context(o->v.Starred.ctx); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ctx, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Name_kind: + result = PyType_GenericNew(Name_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(o->v.Name.id); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_id, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr_context(o->v.Name.ctx); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ctx, value) == -1) + goto failed; + Py_DECREF(value); + break; + case List_kind: + result = PyType_GenericNew(List_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.List.elts, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_elts, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr_context(o->v.List.ctx); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ctx, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Tuple_kind: + result = PyType_GenericNew(Tuple_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.Tuple.elts, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_elts, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr_context(o->v.Tuple.ctx); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ctx, value) == -1) + goto failed; + Py_DECREF(value); + break; + } + value = ast2obj_int(o->lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* ast2obj_expr_context(expr_context_ty o) +{ + switch(o) { + case Load: + Py_INCREF(Load_singleton); + return Load_singleton; + case Store: + Py_INCREF(Store_singleton); + return Store_singleton; + case Del: + Py_INCREF(Del_singleton); + return Del_singleton; + case AugLoad: + Py_INCREF(AugLoad_singleton); + return AugLoad_singleton; + case AugStore: + Py_INCREF(AugStore_singleton); + return AugStore_singleton; + case Param: + Py_INCREF(Param_singleton); + return Param_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown expr_context found"); + return NULL; + } +} +PyObject* +ast2obj_slice(void* _o) +{ + slice_ty o = (slice_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + switch (o->kind) { + case Slice_kind: + result = PyType_GenericNew(Slice_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Slice.lower); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_lower, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.Slice.upper); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_upper, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.Slice.step); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_step, value) == -1) + goto failed; + Py_DECREF(value); + break; + case ExtSlice_kind: + result = PyType_GenericNew(ExtSlice_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(o->v.ExtSlice.dims, ast2obj_slice); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_dims, value) == -1) + goto failed; + Py_DECREF(value); + break; + case Index_kind: + result = PyType_GenericNew(Index_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.Index.value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + break; + } + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* ast2obj_boolop(boolop_ty o) +{ + switch(o) { + case And: + Py_INCREF(And_singleton); + return And_singleton; + case Or: + Py_INCREF(Or_singleton); + return Or_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown boolop found"); + return NULL; + } +} +PyObject* ast2obj_operator(operator_ty o) +{ + switch(o) { + case Add: + Py_INCREF(Add_singleton); + return Add_singleton; + case Sub: + Py_INCREF(Sub_singleton); + return Sub_singleton; + case Mult: + Py_INCREF(Mult_singleton); + return Mult_singleton; + case MatMult: + Py_INCREF(MatMult_singleton); + return MatMult_singleton; + case Div: + Py_INCREF(Div_singleton); + return Div_singleton; + case Mod: + Py_INCREF(Mod_singleton); + return Mod_singleton; + case Pow: + Py_INCREF(Pow_singleton); + return Pow_singleton; + case LShift: + Py_INCREF(LShift_singleton); + return LShift_singleton; + case RShift: + Py_INCREF(RShift_singleton); + return RShift_singleton; + case BitOr: + Py_INCREF(BitOr_singleton); + return BitOr_singleton; + case BitXor: + Py_INCREF(BitXor_singleton); + return BitXor_singleton; + case BitAnd: + Py_INCREF(BitAnd_singleton); + return BitAnd_singleton; + case FloorDiv: + Py_INCREF(FloorDiv_singleton); + return FloorDiv_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown operator found"); + return NULL; + } +} +PyObject* ast2obj_unaryop(unaryop_ty o) +{ + switch(o) { + case Invert: + Py_INCREF(Invert_singleton); + return Invert_singleton; + case Not: + Py_INCREF(Not_singleton); + return Not_singleton; + case UAdd: + Py_INCREF(UAdd_singleton); + return UAdd_singleton; + case USub: + Py_INCREF(USub_singleton); + return USub_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown unaryop found"); + return NULL; + } +} +PyObject* ast2obj_cmpop(cmpop_ty o) +{ + switch(o) { + case Eq: + Py_INCREF(Eq_singleton); + return Eq_singleton; + case NotEq: + Py_INCREF(NotEq_singleton); + return NotEq_singleton; + case Lt: + Py_INCREF(Lt_singleton); + return Lt_singleton; + case LtE: + Py_INCREF(LtE_singleton); + return LtE_singleton; + case Gt: + Py_INCREF(Gt_singleton); + return Gt_singleton; + case GtE: + Py_INCREF(GtE_singleton); + return GtE_singleton; + case Is: + Py_INCREF(Is_singleton); + return Is_singleton; + case IsNot: + Py_INCREF(IsNot_singleton); + return IsNot_singleton; + case In: + Py_INCREF(In_singleton); + return In_singleton; + case NotIn: + Py_INCREF(NotIn_singleton); + return NotIn_singleton; + default: + /* should never happen, but just in case ... */ + PyErr_Format(PyExc_SystemError, "unknown cmpop found"); + return NULL; + } +} +PyObject* +ast2obj_comprehension(void* _o) +{ + comprehension_ty o = (comprehension_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + result = PyType_GenericNew(comprehension_type, NULL, NULL); + if (!result) return NULL; + value = ast2obj_expr(o->target); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_target, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->iter); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_iter, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->ifs, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_ifs, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->is_async); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_is_async, value) == -1) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_excepthandler(void* _o) +{ + excepthandler_ty o = (excepthandler_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + switch (o->kind) { + case ExceptHandler_kind: + result = PyType_GenericNew(ExceptHandler_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(o->v.ExceptHandler.type); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_identifier(o->v.ExceptHandler.name); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_name, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->v.ExceptHandler.body, ast2obj_stmt); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_body, value) == -1) + goto failed; + Py_DECREF(value); + break; + } + value = ast2obj_int(o->lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_arguments(void* _o) +{ + arguments_ty o = (arguments_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + result = PyType_GenericNew(arguments_type, NULL, NULL); + if (!result) return NULL; + value = ast2obj_list(o->posonlyargs, ast2obj_arg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_posonlyargs, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->args, ast2obj_arg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_args, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_arg(o->vararg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_vararg, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->kwonlyargs, ast2obj_arg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_kwonlyargs, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->kw_defaults, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_kw_defaults, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_arg(o->kwarg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_kwarg, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(o->defaults, ast2obj_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_defaults, value) == -1) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_arg(void* _o) +{ + arg_ty o = (arg_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + result = PyType_GenericNew(arg_type, NULL, NULL); + if (!result) return NULL; + value = ast2obj_identifier(o->arg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_arg, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->annotation); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_annotation, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->type_comment); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(o->end_col_offset); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_end_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_keyword(void* _o) +{ + keyword_ty o = (keyword_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + result = PyType_GenericNew(keyword_type, NULL, NULL); + if (!result) return NULL; + value = ast2obj_identifier(o->arg); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_arg, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->value); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_value, value) == -1) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_alias(void* _o) +{ + alias_ty o = (alias_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + result = PyType_GenericNew(alias_type, NULL, NULL); + if (!result) return NULL; + value = ast2obj_identifier(o->name); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_name, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_identifier(o->asname); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_asname, value) == -1) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_withitem(void* _o) +{ + withitem_ty o = (withitem_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + result = PyType_GenericNew(withitem_type, NULL, NULL); + if (!result) return NULL; + value = ast2obj_expr(o->context_expr); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_context_expr, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->optional_vars); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_optional_vars, value) == -1) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + +PyObject* +ast2obj_type_ignore(void* _o) +{ + type_ignore_ty o = (type_ignore_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_RETURN_NONE; + } + + switch (o->kind) { + case TypeIgnore_kind: + result = PyType_GenericNew(TypeIgnore_type, NULL, NULL); + if (!result) goto failed; + value = ast2obj_int(o->v.TypeIgnore.lineno); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_lineno, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_string(o->v.TypeIgnore.tag); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_tag, value) == -1) + goto failed; + Py_DECREF(value); + break; + } + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + + +int +obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena) +{ + int isinstance; + + PyObject *tmp = NULL; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Module_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* body; + asdl_seq* type_ignores; + + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Module"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Module field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Module field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_ignores, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"type_ignores\" missing from Module"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Module field \"type_ignores\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + type_ignores = _Py_asdl_seq_new(len, arena); + if (type_ignores == NULL) goto failed; + for (i = 0; i < len; i++) { + type_ignore_ty val; + res = obj2ast_type_ignore(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Module field \"type_ignores\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(type_ignores, i, val); + } + Py_CLEAR(tmp); + } + *out = Module(body, type_ignores, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Interactive_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* body; + + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Interactive"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Interactive field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Interactive field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + *out = Interactive(body, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Expression_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty body; + + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Expression"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &body, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Expression(body, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)FunctionType_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* argtypes; + expr_ty returns; + + if (_PyObject_LookupAttrId(obj, &PyId_argtypes, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"argtypes\" missing from FunctionType"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "FunctionType field \"argtypes\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + argtypes = _Py_asdl_seq_new(len, arena); + if (argtypes == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "FunctionType field \"argtypes\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(argtypes, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_returns, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"returns\" missing from FunctionType"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &returns, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = FunctionType(argtypes, returns, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Suite_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* body; + + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Suite"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Suite field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Suite field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + *out = Suite(body, arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) +{ + int isinstance; + + PyObject *tmp = NULL; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from stmt"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_lineno = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_col_offset = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + isinstance = PyObject_IsInstance(obj, (PyObject*)FunctionDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier name; + arguments_ty args; + asdl_seq* body; + asdl_seq* decorator_list; + expr_ty returns; + string type_comment; + + if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from FunctionDef"); + return 1; + } + else { + int res; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_args, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from FunctionDef"); + return 1; + } + else { + int res; + res = obj2ast_arguments(tmp, &args, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from FunctionDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "FunctionDef field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_decorator_list, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from FunctionDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "FunctionDef field \"decorator_list\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + decorator_list = _Py_asdl_seq_new(len, arena); + if (decorator_list == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"decorator_list\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(decorator_list, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_returns, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + returns = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &returns, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = FunctionDef(name, args, body, decorator_list, returns, + type_comment, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)AsyncFunctionDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier name; + arguments_ty args; + asdl_seq* body; + asdl_seq* decorator_list; + expr_ty returns; + string type_comment; + + if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from AsyncFunctionDef"); + return 1; + } + else { + int res; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_args, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from AsyncFunctionDef"); + return 1; + } + else { + int res; + res = obj2ast_arguments(tmp, &args, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFunctionDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_decorator_list, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from AsyncFunctionDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"decorator_list\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + decorator_list = _Py_asdl_seq_new(len, arena); + if (decorator_list == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"decorator_list\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(decorator_list, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_returns, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + returns = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &returns, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = AsyncFunctionDef(name, args, body, decorator_list, returns, + type_comment, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)ClassDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier name; + asdl_seq* bases; + asdl_seq* keywords; + asdl_seq* body; + asdl_seq* decorator_list; + + if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef"); + return 1; + } + else { + int res; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_bases, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + bases = _Py_asdl_seq_new(len, arena); + if (bases == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"bases\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(bases, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_keywords, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + keywords = _Py_asdl_seq_new(len, arena); + if (keywords == NULL) goto failed; + for (i = 0; i < len; i++) { + keyword_ty val; + res = obj2ast_keyword(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"keywords\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(keywords, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ClassDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_decorator_list, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"decorator_list\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + decorator_list = _Py_asdl_seq_new(len, arena); + if (decorator_list == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"decorator_list\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(decorator_list, i, val); + } + Py_CLEAR(tmp); + } + *out = ClassDef(name, bases, keywords, body, decorator_list, lineno, + col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Return_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + value = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Return(value, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Delete_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* targets; + + if (_PyObject_LookupAttrId(obj, &PyId_targets, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Delete"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Delete field \"targets\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + targets = _Py_asdl_seq_new(len, arena); + if (targets == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Delete field \"targets\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(targets, i, val); + } + Py_CLEAR(tmp); + } + *out = Delete(targets, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Assign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* targets; + expr_ty value; + string type_comment; + + if (_PyObject_LookupAttrId(obj, &PyId_targets, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Assign"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Assign field \"targets\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + targets = _Py_asdl_seq_new(len, arena); + if (targets == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Assign field \"targets\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(targets, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Assign"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Assign(targets, value, type_comment, lineno, col_offset, + end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)AugAssign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty target; + operator_ty op; + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AugAssign"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_op, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from AugAssign"); + return 1; + } + else { + int res; + res = obj2ast_operator(tmp, &op, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from AugAssign"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = AugAssign(target, op, value, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)AnnAssign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty target; + expr_ty annotation; + expr_ty value; + int simple; + + if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AnnAssign"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_annotation, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"annotation\" missing from AnnAssign"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &annotation, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + value = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_simple, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"simple\" missing from AnnAssign"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &simple, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = AnnAssign(target, annotation, value, simple, lineno, col_offset, + end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)For_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty target; + expr_ty iter; + asdl_seq* body; + asdl_seq* orelse; + string type_comment; + + if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from For"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_iter, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from For"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &iter, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from For"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "For field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "For field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from For"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "For field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + orelse = _Py_asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "For field \"orelse\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(orelse, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = For(target, iter, body, orelse, type_comment, lineno, + col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)AsyncFor_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty target; + expr_ty iter; + asdl_seq* body; + asdl_seq* orelse; + string type_comment; + + if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AsyncFor"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_iter, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from AsyncFor"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &iter, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFor"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "AsyncFor field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from AsyncFor"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "AsyncFor field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + orelse = _Py_asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"orelse\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(orelse, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = AsyncFor(target, iter, body, orelse, type_comment, lineno, + col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)While_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty test; + asdl_seq* body; + asdl_seq* orelse; + + if (_PyObject_LookupAttrId(obj, &PyId_test, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from While"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from While"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "While field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "While field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from While"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "While field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + orelse = _Py_asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "While field \"orelse\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(orelse, i, val); + } + Py_CLEAR(tmp); + } + *out = While(test, body, orelse, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)If_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty test; + asdl_seq* body; + asdl_seq* orelse; + + if (_PyObject_LookupAttrId(obj, &PyId_test, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from If"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from If"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "If field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "If field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from If"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "If field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + orelse = _Py_asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "If field \"orelse\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(orelse, i, val); + } + Py_CLEAR(tmp); + } + *out = If(test, body, orelse, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)With_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* items; + asdl_seq* body; + string type_comment; + + if (_PyObject_LookupAttrId(obj, &PyId_items, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + items = _Py_asdl_seq_new(len, arena); + if (items == NULL) goto failed; + for (i = 0; i < len; i++) { + withitem_ty val; + res = obj2ast_withitem(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "With field \"items\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(items, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from With"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "With field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "With field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = With(items, body, type_comment, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)AsyncWith_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* items; + asdl_seq* body; + string type_comment; + + if (_PyObject_LookupAttrId(obj, &PyId_items, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from AsyncWith"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "AsyncWith field \"items\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + items = _Py_asdl_seq_new(len, arena); + if (items == NULL) goto failed; + for (i = 0; i < len; i++) { + withitem_ty val; + res = obj2ast_withitem(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"items\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(items, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncWith"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "AsyncWith field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = AsyncWith(items, body, type_comment, lineno, col_offset, + end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Raise_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty exc; + expr_ty cause; + + if (_PyObject_LookupAttrId(obj, &PyId_exc, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + exc = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &exc, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_cause, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + cause = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &cause, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Raise(exc, cause, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Try_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* body; + asdl_seq* handlers; + asdl_seq* orelse; + asdl_seq* finalbody; + + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Try field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_handlers, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + handlers = _Py_asdl_seq_new(len, arena); + if (handlers == NULL) goto failed; + for (i = 0; i < len; i++) { + excepthandler_ty val; + res = obj2ast_excepthandler(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Try field \"handlers\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(handlers, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + orelse = _Py_asdl_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Try field \"orelse\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(orelse, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_finalbody, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + finalbody = _Py_asdl_seq_new(len, arena); + if (finalbody == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Try field \"finalbody\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(finalbody, i, val); + } + Py_CLEAR(tmp); + } + *out = Try(body, handlers, orelse, finalbody, lineno, col_offset, + end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Assert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty test; + expr_ty msg; + + if (_PyObject_LookupAttrId(obj, &PyId_test, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from Assert"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_msg, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + msg = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &msg, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Assert(test, msg, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Import_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* names; + + if (_PyObject_LookupAttrId(obj, &PyId_names, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Import"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Import field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + names = _Py_asdl_seq_new(len, arena); + if (names == NULL) goto failed; + for (i = 0; i < len; i++) { + alias_ty val; + res = obj2ast_alias(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Import field \"names\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(names, i, val); + } + Py_CLEAR(tmp); + } + *out = Import(names, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)ImportFrom_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier module; + asdl_seq* names; + int level; + + if (_PyObject_LookupAttrId(obj, &PyId_module, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + module = NULL; + } + else { + int res; + res = obj2ast_identifier(tmp, &module, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_names, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from ImportFrom"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ImportFrom field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + names = _Py_asdl_seq_new(len, arena); + if (names == NULL) goto failed; + for (i = 0; i < len; i++) { + alias_ty val; + res = obj2ast_alias(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ImportFrom field \"names\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(names, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_level, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + level = 0; + } + else { + int res; + res = obj2ast_int(tmp, &level, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = ImportFrom(module, names, level, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Global_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* names; + + if (_PyObject_LookupAttrId(obj, &PyId_names, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Global"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Global field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + names = _Py_asdl_seq_new(len, arena); + if (names == NULL) goto failed; + for (i = 0; i < len; i++) { + identifier val; + res = obj2ast_identifier(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Global field \"names\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(names, i, val); + } + Py_CLEAR(tmp); + } + *out = Global(names, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Nonlocal_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* names; + + if (_PyObject_LookupAttrId(obj, &PyId_names, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Nonlocal"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Nonlocal field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + names = _Py_asdl_seq_new(len, arena); + if (names == NULL) goto failed; + for (i = 0; i < len; i++) { + identifier val; + res = obj2ast_identifier(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Nonlocal field \"names\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(names, i, val); + } + Py_CLEAR(tmp); + } + *out = Nonlocal(names, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Expr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Expr"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Expr(value, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Pass_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + + *out = Pass(lineno, col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Break_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + + *out = Break(lineno, col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Continue_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + + *out = Continue(lineno, col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) +{ + int isinstance; + + PyObject *tmp = NULL; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from expr"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_lineno = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_col_offset = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + isinstance = PyObject_IsInstance(obj, (PyObject*)BoolOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + boolop_ty op; + asdl_seq* values; + + if (_PyObject_LookupAttrId(obj, &PyId_op, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BoolOp"); + return 1; + } + else { + int res; + res = obj2ast_boolop(tmp, &op, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_values, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from BoolOp"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "BoolOp field \"values\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + values = _Py_asdl_seq_new(len, arena); + if (values == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "BoolOp field \"values\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(values, i, val); + } + Py_CLEAR(tmp); + } + *out = BoolOp(op, values, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)NamedExpr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty target; + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from NamedExpr"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NamedExpr"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = NamedExpr(target, value, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)BinOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty left; + operator_ty op; + expr_ty right; + + if (_PyObject_LookupAttrId(obj, &PyId_left, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from BinOp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &left, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_op, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BinOp"); + return 1; + } + else { + int res; + res = obj2ast_operator(tmp, &op, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_right, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"right\" missing from BinOp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &right, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = BinOp(left, op, right, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)UnaryOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + unaryop_ty op; + expr_ty operand; + + if (_PyObject_LookupAttrId(obj, &PyId_op, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from UnaryOp"); + return 1; + } + else { + int res; + res = obj2ast_unaryop(tmp, &op, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_operand, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"operand\" missing from UnaryOp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &operand, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = UnaryOp(op, operand, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Lambda_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + arguments_ty args; + expr_ty body; + + if (_PyObject_LookupAttrId(obj, &PyId_args, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Lambda"); + return 1; + } + else { + int res; + res = obj2ast_arguments(tmp, &args, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Lambda"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &body, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Lambda(args, body, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)IfExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty test; + expr_ty body; + expr_ty orelse; + + if (_PyObject_LookupAttrId(obj, &PyId_test, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from IfExp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &test, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from IfExp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &body, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from IfExp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &orelse, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = IfExp(test, body, orelse, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Dict_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* keys; + asdl_seq* values; + + if (_PyObject_LookupAttrId(obj, &PyId_keys, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from Dict"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Dict field \"keys\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + keys = _Py_asdl_seq_new(len, arena); + if (keys == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Dict field \"keys\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(keys, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_values, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from Dict"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Dict field \"values\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + values = _Py_asdl_seq_new(len, arena); + if (values == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Dict field \"values\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(values, i, val); + } + Py_CLEAR(tmp); + } + *out = Dict(keys, values, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Set_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* elts; + + if (_PyObject_LookupAttrId(obj, &PyId_elts, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Set"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Set field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + elts = _Py_asdl_seq_new(len, arena); + if (elts == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Set field \"elts\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(elts, i, val); + } + Py_CLEAR(tmp); + } + *out = Set(elts, lineno, col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)ListComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty elt; + asdl_seq* generators; + + if (_PyObject_LookupAttrId(obj, &PyId_elt, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from ListComp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &elt, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_generators, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from ListComp"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ListComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + generators = _Py_asdl_seq_new(len, arena); + if (generators == NULL) goto failed; + for (i = 0; i < len; i++) { + comprehension_ty val; + res = obj2ast_comprehension(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ListComp field \"generators\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(generators, i, val); + } + Py_CLEAR(tmp); + } + *out = ListComp(elt, generators, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)SetComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty elt; + asdl_seq* generators; + + if (_PyObject_LookupAttrId(obj, &PyId_elt, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &elt, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_generators, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from SetComp"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "SetComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + generators = _Py_asdl_seq_new(len, arena); + if (generators == NULL) goto failed; + for (i = 0; i < len; i++) { + comprehension_ty val; + res = obj2ast_comprehension(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "SetComp field \"generators\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(generators, i, val); + } + Py_CLEAR(tmp); + } + *out = SetComp(elt, generators, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)DictComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty key; + expr_ty value; + asdl_seq* generators; + + if (_PyObject_LookupAttrId(obj, &PyId_key, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &key, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_generators, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from DictComp"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "DictComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + generators = _Py_asdl_seq_new(len, arena); + if (generators == NULL) goto failed; + for (i = 0; i < len; i++) { + comprehension_ty val; + res = obj2ast_comprehension(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "DictComp field \"generators\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(generators, i, val); + } + Py_CLEAR(tmp); + } + *out = DictComp(key, value, generators, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty elt; + asdl_seq* generators; + + if (_PyObject_LookupAttrId(obj, &PyId_elt, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from GeneratorExp"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &elt, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_generators, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from GeneratorExp"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "GeneratorExp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + generators = _Py_asdl_seq_new(len, arena); + if (generators == NULL) goto failed; + for (i = 0; i < len; i++) { + comprehension_ty val; + res = obj2ast_comprehension(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "GeneratorExp field \"generators\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(generators, i, val); + } + Py_CLEAR(tmp); + } + *out = GeneratorExp(elt, generators, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Await_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Await"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Await(value, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Yield_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + value = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Yield(value, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)YieldFrom_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from YieldFrom"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = YieldFrom(value, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Compare_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty left; + asdl_int_seq* ops; + asdl_seq* comparators; + + if (_PyObject_LookupAttrId(obj, &PyId_left, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from Compare"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &left, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ops, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ops\" missing from Compare"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Compare field \"ops\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + ops = _Py_asdl_int_seq_new(len, arena); + if (ops == NULL) goto failed; + for (i = 0; i < len; i++) { + cmpop_ty val; + res = obj2ast_cmpop(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Compare field \"ops\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(ops, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_comparators, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"comparators\" missing from Compare"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Compare field \"comparators\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + comparators = _Py_asdl_seq_new(len, arena); + if (comparators == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Compare field \"comparators\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(comparators, i, val); + } + Py_CLEAR(tmp); + } + *out = Compare(left, ops, comparators, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Call_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty func; + asdl_seq* args; + asdl_seq* keywords; + + if (_PyObject_LookupAttrId(obj, &PyId_func, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"func\" missing from Call"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &func, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_args, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Call"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Call field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + args = _Py_asdl_seq_new(len, arena); + if (args == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Call field \"args\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(args, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_keywords, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Call field \"keywords\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + keywords = _Py_asdl_seq_new(len, arena); + if (keywords == NULL) goto failed; + for (i = 0; i < len; i++) { + keyword_ty val; + res = obj2ast_keyword(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Call field \"keywords\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(keywords, i, val); + } + Py_CLEAR(tmp); + } + *out = Call(func, args, keywords, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)FormattedValue_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + int conversion; + expr_ty format_spec; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from FormattedValue"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_conversion, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + conversion = 0; + } + else { + int res; + res = obj2ast_int(tmp, &conversion, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_format_spec, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + format_spec = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &format_spec, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = FormattedValue(value, conversion, format_spec, lineno, + col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)JoinedStr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* values; + + if (_PyObject_LookupAttrId(obj, &PyId_values, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from JoinedStr"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "JoinedStr field \"values\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + values = _Py_asdl_seq_new(len, arena); + if (values == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "JoinedStr field \"values\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(values, i, val); + } + Py_CLEAR(tmp); + } + *out = JoinedStr(values, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Constant_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + constant value; + string kind; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Constant"); + return 1; + } + else { + int res; + res = obj2ast_constant(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_kind, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + kind = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &kind, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Constant(value, kind, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Attribute_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + identifier attr; + expr_context_ty ctx; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Attribute"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_attr, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"attr\" missing from Attribute"); + return 1; + } + else { + int res; + res = obj2ast_identifier(tmp, &attr, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ctx, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Attribute"); + return 1; + } + else { + int res; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Attribute(value, attr, ctx, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Subscript_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + slice_ty slice; + expr_context_ty ctx; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Subscript"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_slice, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"slice\" missing from Subscript"); + return 1; + } + else { + int res; + res = obj2ast_slice(tmp, &slice, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ctx, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Subscript"); + return 1; + } + else { + int res; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Subscript(value, slice, ctx, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Starred_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + expr_context_ty ctx; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ctx, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Starred"); + return 1; + } + else { + int res; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Starred(value, ctx, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Name_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier id; + expr_context_ty ctx; + + if (_PyObject_LookupAttrId(obj, &PyId_id, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"id\" missing from Name"); + return 1; + } + else { + int res; + res = obj2ast_identifier(tmp, &id, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ctx, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Name"); + return 1; + } + else { + int res; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Name(id, ctx, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)List_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* elts; + expr_context_ty ctx; + + if (_PyObject_LookupAttrId(obj, &PyId_elts, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from List"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "List field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + elts = _Py_asdl_seq_new(len, arena); + if (elts == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "List field \"elts\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(elts, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ctx, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from List"); + return 1; + } + else { + int res; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = List(elts, ctx, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Tuple_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* elts; + expr_context_ty ctx; + + if (_PyObject_LookupAttrId(obj, &PyId_elts, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Tuple"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "Tuple field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + elts = _Py_asdl_seq_new(len, arena); + if (elts == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "Tuple field \"elts\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(elts, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ctx, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Tuple"); + return 1; + } + else { + int res; + res = obj2ast_expr_context(tmp, &ctx, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Tuple(elts, ctx, lineno, col_offset, end_lineno, end_col_offset, + arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) +{ + int isinstance; + + isinstance = PyObject_IsInstance(obj, (PyObject *)Load_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Load; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Store_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Store; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Del_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Del; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)AugLoad_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = AugLoad; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)AugStore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = AugStore; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Param_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Param; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj); + return 1; +} + +int +obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena) +{ + int isinstance; + + PyObject *tmp = NULL; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Slice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty lower; + expr_ty upper; + expr_ty step; + + if (_PyObject_LookupAttrId(obj, &PyId_lower, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + lower = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &lower, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_upper, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + upper = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &upper, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_step, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + step = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &step, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Slice(lower, upper, step, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)ExtSlice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_seq* dims; + + if (_PyObject_LookupAttrId(obj, &PyId_dims, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"dims\" missing from ExtSlice"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ExtSlice field \"dims\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + dims = _Py_asdl_seq_new(len, arena); + if (dims == NULL) goto failed; + for (i = 0; i < len; i++) { + slice_ty val; + res = obj2ast_slice(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ExtSlice field \"dims\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(dims, i, val); + } + Py_CLEAR(tmp); + } + *out = ExtSlice(dims, arena); + if (*out == NULL) goto failed; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)Index_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Index"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = Index(value, arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of slice, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena) +{ + int isinstance; + + isinstance = PyObject_IsInstance(obj, (PyObject *)And_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = And; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Or_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Or; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of boolop, but got %R", obj); + return 1; +} + +int +obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) +{ + int isinstance; + + isinstance = PyObject_IsInstance(obj, (PyObject *)Add_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Add; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Sub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Sub; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Mult_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Mult; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)MatMult_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = MatMult; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Div_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Div; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Mod_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Mod; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Pow_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Pow; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)LShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = LShift; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)RShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = RShift; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)BitOr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = BitOr; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)BitXor_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = BitXor; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)BitAnd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = BitAnd; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)FloorDiv_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = FloorDiv; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of operator, but got %R", obj); + return 1; +} + +int +obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena) +{ + int isinstance; + + isinstance = PyObject_IsInstance(obj, (PyObject *)Invert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Invert; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Not_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Not; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)UAdd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = UAdd; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)USub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = USub; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of unaryop, but got %R", obj); + return 1; +} + +int +obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena) +{ + int isinstance; + + isinstance = PyObject_IsInstance(obj, (PyObject *)Eq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Eq; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)NotEq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = NotEq; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Lt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Lt; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)LtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = LtE; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Gt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Gt; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)GtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = GtE; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)Is_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = Is; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)IsNot_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = IsNot; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)In_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = In; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject *)NotIn_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = NotIn; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of cmpop, but got %R", obj); + return 1; +} + +int +obj2ast_comprehension(PyObject* obj, comprehension_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + expr_ty target; + expr_ty iter; + asdl_seq* ifs; + int is_async; + + if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from comprehension"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_iter, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from comprehension"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &iter, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_ifs, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"ifs\" missing from comprehension"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "comprehension field \"ifs\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + ifs = _Py_asdl_seq_new(len, arena); + if (ifs == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "comprehension field \"ifs\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(ifs, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_is_async, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"is_async\" missing from comprehension"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &is_async, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = comprehension(target, iter, ifs, is_async, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena) +{ + int isinstance; + + PyObject *tmp = NULL; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from excepthandler"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_lineno = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_col_offset = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + isinstance = PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty type; + identifier name; + asdl_seq* body; + + if (_PyObject_LookupAttrId(obj, &PyId_type, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &type, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + name = NULL; + } + else { + int res; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ExceptHandler"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ExceptHandler field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ExceptHandler field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + *out = ExceptHandler(type, name, body, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of excepthandler, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + asdl_seq* posonlyargs; + asdl_seq* args; + arg_ty vararg; + asdl_seq* kwonlyargs; + asdl_seq* kw_defaults; + arg_ty kwarg; + asdl_seq* defaults; + + if (_PyObject_LookupAttrId(obj, &PyId_posonlyargs, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + posonlyargs = _Py_asdl_seq_new(len, arena); + if (posonlyargs == NULL) goto failed; + for (i = 0; i < len; i++) { + arg_ty val; + res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(posonlyargs, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_args, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + args = _Py_asdl_seq_new(len, arena); + if (args == NULL) goto failed; + for (i = 0; i < len; i++) { + arg_ty val; + res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "arguments field \"args\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(args, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_vararg, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + vararg = NULL; + } + else { + int res; + res = obj2ast_arg(tmp, &vararg, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_kwonlyargs, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"kwonlyargs\" missing from arguments"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"kwonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + kwonlyargs = _Py_asdl_seq_new(len, arena); + if (kwonlyargs == NULL) goto failed; + for (i = 0; i < len; i++) { + arg_ty val; + res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "arguments field \"kwonlyargs\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(kwonlyargs, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_kw_defaults, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"kw_defaults\" missing from arguments"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"kw_defaults\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + kw_defaults = _Py_asdl_seq_new(len, arena); + if (kw_defaults == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "arguments field \"kw_defaults\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(kw_defaults, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_kwarg, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + kwarg = NULL; + } + else { + int res; + res = obj2ast_arg(tmp, &kwarg, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_defaults, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"defaults\" missing from arguments"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "arguments field \"defaults\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + defaults = _Py_asdl_seq_new(len, arena); + if (defaults == NULL) goto failed; + for (i = 0; i < len; i++) { + expr_ty val; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "arguments field \"defaults\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(defaults, i, val); + } + Py_CLEAR(tmp); + } + *out = arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, + defaults, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + identifier arg; + expr_ty annotation; + string type_comment; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; + + if (_PyObject_LookupAttrId(obj, &PyId_arg, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg"); + return 1; + } + else { + int res; + res = obj2ast_identifier(tmp, &arg, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_annotation, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + annotation = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &annotation, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + type_comment = NULL; + } + else { + int res; + res = obj2ast_string(tmp, &type_comment, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_lineno = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_end_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + end_col_offset = 0; + } + else { + int res; + res = obj2ast_int(tmp, &end_col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = arg(arg, annotation, type_comment, lineno, col_offset, end_lineno, + end_col_offset, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + identifier arg; + expr_ty value; + + if (_PyObject_LookupAttrId(obj, &PyId_arg, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + arg = NULL; + } + else { + int res; + res = obj2ast_identifier(tmp, &arg, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from keyword"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = keyword(arg, value, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + identifier name; + identifier asname; + + if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from alias"); + return 1; + } + else { + int res; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_asname, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + asname = NULL; + } + else { + int res; + res = obj2ast_identifier(tmp, &asname, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = alias(name, asname, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + expr_ty context_expr; + expr_ty optional_vars; + + if (_PyObject_LookupAttrId(obj, &PyId_context_expr, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem"); + return 1; + } + else { + int res; + res = obj2ast_expr(tmp, &context_expr, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_optional_vars, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + optional_vars = NULL; + } + else { + int res; + res = obj2ast_expr(tmp, &optional_vars, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = withitem(context_expr, optional_vars, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + +int +obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* arena) +{ + int isinstance; + + PyObject *tmp = NULL; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + isinstance = PyObject_IsInstance(obj, (PyObject*)TypeIgnore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + int lineno; + string tag; + + if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from TypeIgnore"); + return 1; + } + else { + int res; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttrId(obj, &PyId_tag, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore"); + return 1; + } + else { + int res; + res = obj2ast_string(tmp, &tag, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = TypeIgnore(lineno, tag, arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of type_ignore, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + + +static struct PyModuleDef _astmodule = { + PyModuleDef_HEAD_INIT, "_ast" +}; +PyMODINIT_FUNC +PyInit__ast(void) +{ + PyObject *m, *d; + if (!init_types()) return NULL; + m = PyModule_Create(&_astmodule); + if (!m) return NULL; + d = PyModule_GetDict(m); + if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL; + if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) + return NULL; + if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) + return NULL; + if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) + return NULL; + if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Interactive", (PyObject*)Interactive_type) < + 0) return NULL; + if (PyDict_SetItemString(d, "Expression", (PyObject*)Expression_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "FunctionType", (PyObject*)FunctionType_type) < + 0) return NULL; + if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return NULL; + if (PyDict_SetItemString(d, "FunctionDef", (PyObject*)FunctionDef_type) < + 0) return NULL; + if (PyDict_SetItemString(d, "AsyncFunctionDef", + (PyObject*)AsyncFunctionDef_type) < 0) return NULL; + if (PyDict_SetItemString(d, "ClassDef", (PyObject*)ClassDef_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Return", (PyObject*)Return_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Delete", (PyObject*)Delete_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Assign", (PyObject*)Assign_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "AugAssign", (PyObject*)AugAssign_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "AnnAssign", (PyObject*)AnnAssign_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return NULL; + if (PyDict_SetItemString(d, "AsyncFor", (PyObject*)AsyncFor_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return NULL; + if (PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return NULL; + if (PyDict_SetItemString(d, "AsyncWith", (PyObject*)AsyncWith_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Try", (PyObject*)Try_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "ImportFrom", (PyObject*)ImportFrom_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Global", (PyObject*)Global_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Nonlocal", (PyObject*)Nonlocal_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Continue", (PyObject*)Continue_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return NULL; + if (PyDict_SetItemString(d, "BoolOp", (PyObject*)BoolOp_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "NamedExpr", (PyObject*)NamedExpr_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "UnaryOp", (PyObject*)UnaryOp_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Lambda", (PyObject*)Lambda_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return NULL; + if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "SetComp", (PyObject*)SetComp_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "DictComp", (PyObject*)DictComp_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "GeneratorExp", (PyObject*)GeneratorExp_type) < + 0) return NULL; + if (PyDict_SetItemString(d, "Await", (PyObject*)Await_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "YieldFrom", (PyObject*)YieldFrom_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Compare", (PyObject*)Compare_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return NULL; + if (PyDict_SetItemString(d, "FormattedValue", + (PyObject*)FormattedValue_type) < 0) return NULL; + if (PyDict_SetItemString(d, "JoinedStr", (PyObject*)JoinedStr_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Constant", (PyObject*)Constant_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Subscript", (PyObject*)Subscript_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Starred", (PyObject*)Starred_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Name", (PyObject*)Name_type) < 0) return NULL; + if (PyDict_SetItemString(d, "List", (PyObject*)List_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Tuple", (PyObject*)Tuple_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "expr_context", (PyObject*)expr_context_type) < + 0) return NULL; + if (PyDict_SetItemString(d, "Load", (PyObject*)Load_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Store", (PyObject*)Store_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Del", (PyObject*)Del_type) < 0) return NULL; + if (PyDict_SetItemString(d, "AugLoad", (PyObject*)AugLoad_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "AugStore", (PyObject*)AugStore_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "ExtSlice", (PyObject*)ExtSlice_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Index", (PyObject*)Index_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "boolop", (PyObject*)boolop_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "And", (PyObject*)And_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Or", (PyObject*)Or_type) < 0) return NULL; + if (PyDict_SetItemString(d, "operator", (PyObject*)operator_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return NULL; + if (PyDict_SetItemString(d, "MatMult", (PyObject*)MatMult_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return NULL; + if (PyDict_SetItemString(d, "LShift", (PyObject*)LShift_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "RShift", (PyObject*)RShift_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "BitOr", (PyObject*)BitOr_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "BitXor", (PyObject*)BitXor_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "BitAnd", (PyObject*)BitAnd_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "FloorDiv", (PyObject*)FloorDiv_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "unaryop", (PyObject*)unaryop_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Invert", (PyObject*)Invert_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Not", (PyObject*)Not_type) < 0) return NULL; + if (PyDict_SetItemString(d, "UAdd", (PyObject*)UAdd_type) < 0) return NULL; + if (PyDict_SetItemString(d, "USub", (PyObject*)USub_type) < 0) return NULL; + if (PyDict_SetItemString(d, "cmpop", (PyObject*)cmpop_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Eq", (PyObject*)Eq_type) < 0) return NULL; + if (PyDict_SetItemString(d, "NotEq", (PyObject*)NotEq_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "Lt", (PyObject*)Lt_type) < 0) return NULL; + if (PyDict_SetItemString(d, "LtE", (PyObject*)LtE_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Gt", (PyObject*)Gt_type) < 0) return NULL; + if (PyDict_SetItemString(d, "GtE", (PyObject*)GtE_type) < 0) return NULL; + if (PyDict_SetItemString(d, "Is", (PyObject*)Is_type) < 0) return NULL; + if (PyDict_SetItemString(d, "IsNot", (PyObject*)IsNot_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "In", (PyObject*)In_type) < 0) return NULL; + if (PyDict_SetItemString(d, "NotIn", (PyObject*)NotIn_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "comprehension", (PyObject*)comprehension_type) + < 0) return NULL; + if (PyDict_SetItemString(d, "excepthandler", (PyObject*)excepthandler_type) + < 0) return NULL; + if (PyDict_SetItemString(d, "ExceptHandler", (PyObject*)ExceptHandler_type) + < 0) return NULL; + if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return NULL; + if (PyDict_SetItemString(d, "keyword", (PyObject*)keyword_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return + NULL; + if (PyDict_SetItemString(d, "withitem", (PyObject*)withitem_type) < 0) + return NULL; + if (PyDict_SetItemString(d, "type_ignore", (PyObject*)type_ignore_type) < + 0) return NULL; + if (PyDict_SetItemString(d, "TypeIgnore", (PyObject*)TypeIgnore_type) < 0) + return NULL; + return m; +} + + +PyObject* PyAST_mod2obj(mod_ty t) +{ + if (!init_types()) + return NULL; + return ast2obj_mod(t); +} + +/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) +{ + PyObject *req_type[3]; + char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; + + if (PySys_Audit("compile", "OO", ast, Py_None) < 0) { + return NULL; + } + + req_type[0] = (PyObject*)Module_type; + req_type[1] = (PyObject*)Expression_type; + req_type[2] = (PyObject*)Interactive_type; + + assert(0 <= mode && mode <= 2); + + if (!init_types()) + return NULL; + + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { + PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", + req_name[mode], Py_TYPE(ast)->tp_name); + return NULL; + } + + mod_ty res = NULL; + if (obj2ast_mod(ast, &res, arena) != 0) + return NULL; + else + return res; +} + +int PyAST_Check(PyObject* obj) +{ + if (!init_types()) + return -1; + return PyObject_IsInstance(obj, (PyObject*)&AST_type); +} + + diff --git a/python/Python/README b/python/Python/README new file mode 100755 index 0000000..153b628 --- /dev/null +++ b/python/Python/README @@ -0,0 +1 @@ +Miscellaneous source files for the main Python shared library diff --git a/python/Python/_warnings.c b/python/Python/_warnings.c new file mode 100755 index 0000000..52a13df --- /dev/null +++ b/python/Python/_warnings.c @@ -0,0 +1,1382 @@ +#include "Python.h" +#include "pycore_pystate.h" +#include "frameobject.h" +#include "clinic/_warnings.c.h" + +#define MODULE_NAME "_warnings" + +PyDoc_STRVAR(warnings__doc__, +MODULE_NAME " provides basic warning filtering support.\n" +"It is a helper module to speed up interpreter start-up."); + +_Py_IDENTIFIER(stderr); +#ifndef Py_DEBUG +_Py_IDENTIFIER(default); +_Py_IDENTIFIER(ignore); +#endif + + +/*************************************************************************/ + +typedef struct _warnings_runtime_state WarningsState; + +/* Forward declaration of the _warnings module definition. */ +static struct PyModuleDef warningsmodule; + +/* Given a module object, get its per-module state. */ +static WarningsState * +_Warnings_GetState() +{ + PyThreadState *tstate = PyThreadState_GET(); + if (tstate == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "_Warnings_GetState: could not identify current interpreter"); + return NULL; + } + return &tstate->interp->warnings; +} + +/* Clear the given warnings module state. */ +static void +_Warnings_ClearState(WarningsState *st) +{ + Py_CLEAR(st->filters); + Py_CLEAR(st->once_registry); + Py_CLEAR(st->default_action); +} + +#ifndef Py_DEBUG +static PyObject * +create_filter(PyObject *category, _Py_Identifier *id, const char *modname) +{ + PyObject *modname_obj = NULL; + PyObject *action_str = _PyUnicode_FromId(id); + if (action_str == NULL) { + return NULL; + } + + /* Default to "no module name" for initial filter set */ + if (modname != NULL) { + modname_obj = PyUnicode_InternFromString(modname); + if (modname_obj == NULL) { + return NULL; + } + } else { + modname_obj = Py_None; + } + + /* This assumes the line number is zero for now. */ + return PyTuple_Pack(5, action_str, Py_None, + category, modname_obj, _PyLong_Zero); +} +#endif + +static PyObject * +init_filters(void) +{ +#ifdef Py_DEBUG + /* Py_DEBUG builds show all warnings by default */ + return PyList_New(0); +#else + /* Other builds ignore a number of warning categories by default */ + PyObject *filters = PyList_New(5); + if (filters == NULL) { + return NULL; + } + + size_t pos = 0; /* Post-incremented in each use. */ + PyList_SET_ITEM(filters, pos++, + create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__")); + PyList_SET_ITEM(filters, pos++, + create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL)); + PyList_SET_ITEM(filters, pos++, + create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL)); + PyList_SET_ITEM(filters, pos++, + create_filter(PyExc_ImportWarning, &PyId_ignore, NULL)); + PyList_SET_ITEM(filters, pos++, + create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL)); + + for (size_t x = 0; x < pos; x++) { + if (PyList_GET_ITEM(filters, x) == NULL) { + Py_DECREF(filters); + return NULL; + } + } + return filters; +#endif +} + +/* Initialize the given warnings module state. */ +static int +_Warnings_InitState(WarningsState *st) +{ + if (st->filters == NULL) { + st->filters = init_filters(); + if (st->filters == NULL) { + goto error; + } + } + + if (st->once_registry == NULL) { + st->once_registry = PyDict_New(); + if (st->once_registry == NULL) { + goto error; + } + } + + if (st->default_action == NULL) { + st->default_action = PyUnicode_FromString("default"); + if (st->default_action == NULL) { + goto error; + } + } + + st->filters_version = 0; + + return 0; + +error: + _Warnings_ClearState(st); + return -1; +} + + +/*************************************************************************/ + +static int +check_matched(PyObject *obj, PyObject *arg) +{ + PyObject *result; + _Py_IDENTIFIER(match); + int rc; + + /* A 'None' filter always matches */ + if (obj == Py_None) + return 1; + + /* An internal plain text default filter must match exactly */ + if (PyUnicode_CheckExact(obj)) { + int cmp_result = PyUnicode_Compare(obj, arg); + if (cmp_result == -1 && PyErr_Occurred()) { + return -1; + } + return !cmp_result; + } + + /* Otherwise assume a regex filter and call its match() method */ + result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL); + if (result == NULL) + return -1; + + rc = PyObject_IsTrue(result); + Py_DECREF(result); + return rc; +} + +/* + Returns a new reference. + A NULL return value can mean false or an error. +*/ +static PyObject * +get_warnings_attr(_Py_Identifier *attr_id, int try_import) +{ + PyObject *warnings_str; + PyObject *warnings_module, *obj; + _Py_IDENTIFIER(warnings); + + warnings_str = _PyUnicode_FromId(&PyId_warnings); + if (warnings_str == NULL) { + return NULL; + } + + /* don't try to import after the start of the Python finallization */ + if (try_import && !_Py_IsFinalizing()) { + warnings_module = PyImport_Import(warnings_str); + if (warnings_module == NULL) { + /* Fallback to the C implementation if we cannot get + the Python implementation */ + if (PyErr_ExceptionMatches(PyExc_ImportError)) { + PyErr_Clear(); + } + return NULL; + } + } + else { + /* if we're so late into Python finalization that the module dict is + gone, then we can't even use PyImport_GetModule without triggering + an interpreter abort. + */ + if (!_PyInterpreterState_GET_UNSAFE()->modules) { + return NULL; + } + warnings_module = PyImport_GetModule(warnings_str); + if (warnings_module == NULL) + return NULL; + } + + (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj); + Py_DECREF(warnings_module); + return obj; +} + + +static PyObject * +get_once_registry(WarningsState *st) +{ + PyObject *registry; + _Py_IDENTIFIER(onceregistry); + + registry = get_warnings_attr(&PyId_onceregistry, 0); + if (registry == NULL) { + if (PyErr_Occurred()) + return NULL; + assert(st->once_registry); + return st->once_registry; + } + if (!PyDict_Check(registry)) { + PyErr_Format(PyExc_TypeError, + MODULE_NAME ".onceregistry must be a dict, " + "not '%.200s'", + Py_TYPE(registry)->tp_name); + Py_DECREF(registry); + return NULL; + } + Py_SETREF(st->once_registry, registry); + return registry; +} + + +static PyObject * +get_default_action(WarningsState *st) +{ + PyObject *default_action; + _Py_IDENTIFIER(defaultaction); + + default_action = get_warnings_attr(&PyId_defaultaction, 0); + if (default_action == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + assert(st->default_action); + return st->default_action; + } + if (!PyUnicode_Check(default_action)) { + PyErr_Format(PyExc_TypeError, + MODULE_NAME ".defaultaction must be a string, " + "not '%.200s'", + Py_TYPE(default_action)->tp_name); + Py_DECREF(default_action); + return NULL; + } + Py_SETREF(st->default_action, default_action); + return default_action; +} + + +/* The item is a new reference. */ +static PyObject* +get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, + PyObject *module, PyObject **item) +{ + PyObject *action; + Py_ssize_t i; + PyObject *warnings_filters; + _Py_IDENTIFIER(filters); + WarningsState *st = _Warnings_GetState(); + if (st == NULL) { + return NULL; + } + + warnings_filters = get_warnings_attr(&PyId_filters, 0); + if (warnings_filters == NULL) { + if (PyErr_Occurred()) + return NULL; + } + else { + Py_SETREF(st->filters, warnings_filters); + } + + PyObject *filters = st->filters; + if (filters == NULL || !PyList_Check(filters)) { + PyErr_SetString(PyExc_ValueError, + MODULE_NAME ".filters must be a list"); + return NULL; + } + + /* WarningsState.filters could change while we are iterating over it. */ + for (i = 0; i < PyList_GET_SIZE(filters); i++) { + PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj; + Py_ssize_t ln; + int is_subclass, good_msg, good_mod; + + tmp_item = PyList_GET_ITEM(filters, i); + if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) { + PyErr_Format(PyExc_ValueError, + MODULE_NAME ".filters item %zd isn't a 5-tuple", i); + return NULL; + } + + /* Python code: action, msg, cat, mod, ln = item */ + Py_INCREF(tmp_item); + action = PyTuple_GET_ITEM(tmp_item, 0); + msg = PyTuple_GET_ITEM(tmp_item, 1); + cat = PyTuple_GET_ITEM(tmp_item, 2); + mod = PyTuple_GET_ITEM(tmp_item, 3); + ln_obj = PyTuple_GET_ITEM(tmp_item, 4); + + if (!PyUnicode_Check(action)) { + PyErr_Format(PyExc_TypeError, + "action must be a string, not '%.200s'", + Py_TYPE(action)->tp_name); + Py_DECREF(tmp_item); + return NULL; + } + + good_msg = check_matched(msg, text); + if (good_msg == -1) { + Py_DECREF(tmp_item); + return NULL; + } + + good_mod = check_matched(mod, module); + if (good_mod == -1) { + Py_DECREF(tmp_item); + return NULL; + } + + is_subclass = PyObject_IsSubclass(category, cat); + if (is_subclass == -1) { + Py_DECREF(tmp_item); + return NULL; + } + + ln = PyLong_AsSsize_t(ln_obj); + if (ln == -1 && PyErr_Occurred()) { + Py_DECREF(tmp_item); + return NULL; + } + + if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) { + *item = tmp_item; + return action; + } + + Py_DECREF(tmp_item); + } + + action = get_default_action(st); + if (action != NULL) { + Py_INCREF(Py_None); + *item = Py_None; + return action; + } + + return NULL; +} + + +static int +already_warned(PyObject *registry, PyObject *key, int should_set) +{ + PyObject *version_obj, *already_warned; + _Py_IDENTIFIER(version); + + if (key == NULL) + return -1; + + WarningsState *st = _Warnings_GetState(); + if (st == NULL) { + return -1; + } + version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version); + if (version_obj == NULL + || !PyLong_CheckExact(version_obj) + || PyLong_AsLong(version_obj) != st->filters_version) + { + if (PyErr_Occurred()) { + return -1; + } + PyDict_Clear(registry); + version_obj = PyLong_FromLong(st->filters_version); + if (version_obj == NULL) + return -1; + if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) { + Py_DECREF(version_obj); + return -1; + } + Py_DECREF(version_obj); + } + else { + already_warned = PyDict_GetItemWithError(registry, key); + if (already_warned != NULL) { + int rc = PyObject_IsTrue(already_warned); + if (rc != 0) + return rc; + } + else if (PyErr_Occurred()) { + return -1; + } + } + + /* This warning wasn't found in the registry, set it. */ + if (should_set) + return PyDict_SetItem(registry, key, Py_True); + return 0; +} + +/* New reference. */ +static PyObject * +normalize_module(PyObject *filename) +{ + PyObject *module; + int kind; + void *data; + Py_ssize_t len; + + len = PyUnicode_GetLength(filename); + if (len < 0) + return NULL; + + if (len == 0) + return PyUnicode_FromString(""); + + kind = PyUnicode_KIND(filename); + data = PyUnicode_DATA(filename); + + /* if filename.endswith(".py"): */ + if (len >= 3 && + PyUnicode_READ(kind, data, len-3) == '.' && + PyUnicode_READ(kind, data, len-2) == 'p' && + PyUnicode_READ(kind, data, len-1) == 'y') + { + module = PyUnicode_Substring(filename, 0, len-3); + } + else { + module = filename; + Py_INCREF(module); + } + return module; +} + +static int +update_registry(PyObject *registry, PyObject *text, PyObject *category, + int add_zero) +{ + PyObject *altkey; + int rc; + + if (add_zero) + altkey = PyTuple_Pack(3, text, category, _PyLong_Zero); + else + altkey = PyTuple_Pack(2, text, category); + + rc = already_warned(registry, altkey, 1); + Py_XDECREF(altkey); + return rc; +} + +static void +show_warning(PyObject *filename, int lineno, PyObject *text, + PyObject *category, PyObject *sourceline) +{ + PyObject *f_stderr; + PyObject *name; + char lineno_str[128]; + _Py_IDENTIFIER(__name__); + + PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); + + name = _PyObject_GetAttrId(category, &PyId___name__); + if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ + goto error; + + f_stderr = _PySys_GetObjectId(&PyId_stderr); + if (f_stderr == NULL) { + fprintf(stderr, "lost sys.stderr\n"); + goto error; + } + + /* Print "filename:lineno: category: text\n" */ + if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0) + goto error; + if (PyFile_WriteString(lineno_str, f_stderr) < 0) + goto error; + if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0) + goto error; + if (PyFile_WriteString(": ", f_stderr) < 0) + goto error; + if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0) + goto error; + if (PyFile_WriteString("\n", f_stderr) < 0) + goto error; + Py_CLEAR(name); + + /* Print " source_line\n" */ + if (sourceline) { + int kind; + void *data; + Py_ssize_t i, len; + Py_UCS4 ch; + PyObject *truncated; + + if (PyUnicode_READY(sourceline) < 1) + goto error; + + kind = PyUnicode_KIND(sourceline); + data = PyUnicode_DATA(sourceline); + len = PyUnicode_GET_LENGTH(sourceline); + for (i=0; iob_type; + } + else { + text = message; + message = PyObject_CallFunctionObjArgs(category, message, NULL); + if (message == NULL) + goto cleanup; + } + + lineno_obj = PyLong_FromLong(lineno); + if (lineno_obj == NULL) + goto cleanup; + + if (source == Py_None) { + source = NULL; + } + + /* Create key. */ + key = PyTuple_Pack(3, text, category, lineno_obj); + if (key == NULL) + goto cleanup; + + if ((registry != NULL) && (registry != Py_None)) { + rc = already_warned(registry, key, 0); + if (rc == -1) + goto cleanup; + else if (rc == 1) + goto return_none; + /* Else this warning hasn't been generated before. */ + } + + action = get_filter(category, text, lineno, module, &item); + if (action == NULL) + goto cleanup; + + if (_PyUnicode_EqualToASCIIString(action, "error")) { + PyErr_SetObject(category, message); + goto cleanup; + } + + if (_PyUnicode_EqualToASCIIString(action, "ignore")) { + goto return_none; + } + + /* Store in the registry that we've been here, *except* when the action + is "always". */ + rc = 0; + if (!_PyUnicode_EqualToASCIIString(action, "always")) { + if (registry != NULL && registry != Py_None && + PyDict_SetItem(registry, key, Py_True) < 0) + { + goto cleanup; + } + + if (_PyUnicode_EqualToASCIIString(action, "once")) { + if (registry == NULL || registry == Py_None) { + WarningsState *st = _Warnings_GetState(); + if (st == NULL) { + goto cleanup; + } + registry = get_once_registry(st); + if (registry == NULL) + goto cleanup; + } + /* WarningsState.once_registry[(text, category)] = 1 */ + rc = update_registry(registry, text, category, 0); + } + else if (_PyUnicode_EqualToASCIIString(action, "module")) { + /* registry[(text, category, 0)] = 1 */ + if (registry != NULL && registry != Py_None) + rc = update_registry(registry, text, category, 0); + } + else if (!_PyUnicode_EqualToASCIIString(action, "default")) { + PyErr_Format(PyExc_RuntimeError, + "Unrecognized action (%R) in warnings.filters:\n %R", + action, item); + goto cleanup; + } + } + + if (rc == 1) /* Already warned for this module. */ + goto return_none; + if (rc == 0) { + if (call_show_warning(category, text, message, filename, lineno, + lineno_obj, sourceline, source) < 0) + goto cleanup; + } + else /* if (rc == -1) */ + goto cleanup; + + return_none: + result = Py_None; + Py_INCREF(result); + + cleanup: + Py_XDECREF(item); + Py_XDECREF(key); + Py_XDECREF(text); + Py_XDECREF(lineno_obj); + Py_DECREF(module); + Py_XDECREF(message); + return result; /* Py_None or NULL. */ +} + +static int +is_internal_frame(PyFrameObject *frame) +{ + static PyObject *importlib_string = NULL; + static PyObject *bootstrap_string = NULL; + PyObject *filename; + int contains; + + if (importlib_string == NULL) { + importlib_string = PyUnicode_FromString("importlib"); + if (importlib_string == NULL) { + return 0; + } + + bootstrap_string = PyUnicode_FromString("_bootstrap"); + if (bootstrap_string == NULL) { + Py_DECREF(importlib_string); + return 0; + } + Py_INCREF(importlib_string); + Py_INCREF(bootstrap_string); + } + + if (frame == NULL || frame->f_code == NULL || + frame->f_code->co_filename == NULL) { + return 0; + } + filename = frame->f_code->co_filename; + if (!PyUnicode_Check(filename)) { + return 0; + } + contains = PyUnicode_Contains(filename, importlib_string); + if (contains < 0) { + return 0; + } + else if (contains > 0) { + contains = PyUnicode_Contains(filename, bootstrap_string); + if (contains < 0) { + return 0; + } + else if (contains > 0) { + return 1; + } + } + + return 0; +} + +static PyFrameObject * +next_external_frame(PyFrameObject *frame) +{ + do { + frame = frame->f_back; + } while (frame != NULL && is_internal_frame(frame)); + + return frame; +} + +/* filename, module, and registry are new refs, globals is borrowed */ +/* Returns 0 on error (no new refs), 1 on success */ +static int +setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, + PyObject **module, PyObject **registry) +{ + _Py_IDENTIFIER(__warningregistry__); + _Py_IDENTIFIER(__name__); + PyObject *globals; + + /* Setup globals, filename and lineno. */ + PyFrameObject *f = _PyThreadState_GET()->frame; + // Stack level comparisons to Python code is off by one as there is no + // warnings-related stack level to avoid. + if (stack_level <= 0 || is_internal_frame(f)) { + while (--stack_level > 0 && f != NULL) { + f = f->f_back; + } + } + else { + while (--stack_level > 0 && f != NULL) { + f = next_external_frame(f); + } + } + + if (f == NULL) { + globals = _PyInterpreterState_GET_UNSAFE()->sysdict; + *filename = PyUnicode_FromString("sys"); + *lineno = 1; + } + else { + globals = f->f_globals; + *filename = f->f_code->co_filename; + Py_INCREF(*filename); + *lineno = PyFrame_GetLineNumber(f); + } + + *module = NULL; + + /* Setup registry. */ + assert(globals != NULL); + assert(PyDict_Check(globals)); + *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__); + if (*registry == NULL) { + int rc; + + if (PyErr_Occurred()) { + goto handle_error; + } + *registry = PyDict_New(); + if (*registry == NULL) + goto handle_error; + + rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry); + if (rc < 0) + goto handle_error; + } + else + Py_INCREF(*registry); + + /* Setup module. */ + *module = _PyDict_GetItemIdWithError(globals, &PyId___name__); + if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) { + Py_INCREF(*module); + } + else if (PyErr_Occurred()) { + goto handle_error; + } + else { + *module = PyUnicode_FromString(""); + if (*module == NULL) + goto handle_error; + } + + return 1; + + handle_error: + Py_XDECREF(*registry); + Py_XDECREF(*module); + Py_DECREF(*filename); + return 0; +} + +static PyObject * +get_category(PyObject *message, PyObject *category) +{ + int rc; + + /* Get category. */ + rc = PyObject_IsInstance(message, PyExc_Warning); + if (rc == -1) + return NULL; + + if (rc == 1) + category = (PyObject*)message->ob_type; + else if (category == NULL || category == Py_None) + category = PyExc_UserWarning; + + /* Validate category. */ + rc = PyObject_IsSubclass(category, PyExc_Warning); + /* category is not a subclass of PyExc_Warning or + PyObject_IsSubclass raised an error */ + if (rc == -1 || rc == 0) { + PyErr_Format(PyExc_TypeError, + "category must be a Warning subclass, not '%s'", + Py_TYPE(category)->tp_name); + return NULL; + } + + return category; +} + +static PyObject * +do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, + PyObject *source) +{ + PyObject *filename, *module, *registry, *res; + int lineno; + + if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) + return NULL; + + res = warn_explicit(category, message, filename, lineno, module, registry, + NULL, source); + Py_DECREF(filename); + Py_DECREF(registry); + Py_DECREF(module); + return res; +} + +/*[clinic input] +warn as warnings_warn + + message: object + category: object = None + stacklevel: Py_ssize_t = 1 + source: object = None + +Issue a warning, or maybe ignore it or raise an exception. +[clinic start generated code]*/ + +static PyObject * +warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, + Py_ssize_t stacklevel, PyObject *source) +/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/ +{ + category = get_category(message, category); + if (category == NULL) + return NULL; + return do_warn(message, category, stacklevel, source); +} + +static PyObject * +get_source_line(PyObject *module_globals, int lineno) +{ + _Py_IDENTIFIER(get_source); + _Py_IDENTIFIER(__loader__); + _Py_IDENTIFIER(__name__); + PyObject *loader; + PyObject *module_name; + PyObject *get_source; + PyObject *source; + PyObject *source_list; + PyObject *source_line; + + /* Check/get the requisite pieces needed for the loader. */ + loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__); + if (loader == NULL) { + return NULL; + } + Py_INCREF(loader); + module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__); + if (!module_name) { + Py_DECREF(loader); + return NULL; + } + Py_INCREF(module_name); + + /* Make sure the loader implements the optional get_source() method. */ + (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source); + Py_DECREF(loader); + if (!get_source) { + Py_DECREF(module_name); + return NULL; + } + /* Call get_source() to get the source code. */ + source = PyObject_CallFunctionObjArgs(get_source, module_name, NULL); + Py_DECREF(get_source); + Py_DECREF(module_name); + if (!source) { + return NULL; + } + if (source == Py_None) { + Py_DECREF(source); + return NULL; + } + + /* Split the source into lines. */ + source_list = PyUnicode_Splitlines(source, 0); + Py_DECREF(source); + if (!source_list) { + return NULL; + } + + /* Get the source line. */ + source_line = PyList_GetItem(source_list, lineno-1); + Py_XINCREF(source_line); + Py_DECREF(source_list); + return source_line; +} + +static PyObject * +warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwd_list[] = {"message", "category", "filename", "lineno", + "module", "registry", "module_globals", + "source", 0}; + PyObject *message; + PyObject *category; + PyObject *filename; + int lineno; + PyObject *module = NULL; + PyObject *registry = NULL; + PyObject *module_globals = NULL; + PyObject *sourceobj = NULL; + PyObject *source_line = NULL; + PyObject *returned; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit", + kwd_list, &message, &category, &filename, &lineno, &module, + ®istry, &module_globals, &sourceobj)) + return NULL; + + if (module_globals && module_globals != Py_None) { + if (!PyDict_Check(module_globals)) { + PyErr_Format(PyExc_TypeError, + "module_globals must be a dict, not '%.200s'", + Py_TYPE(module_globals)->tp_name); + return NULL; + } + + source_line = get_source_line(module_globals, lineno); + if (source_line == NULL && PyErr_Occurred()) { + return NULL; + } + } + returned = warn_explicit(category, message, filename, lineno, module, + registry, source_line, sourceobj); + Py_XDECREF(source_line); + return returned; +} + +static PyObject * +warnings_filters_mutated(PyObject *self, PyObject *args) +{ + WarningsState *st = _Warnings_GetState(); + if (st == NULL) { + return NULL; + } + st->filters_version++; + Py_RETURN_NONE; +} + + +/* Function to issue a warning message; may raise an exception. */ + +static int +warn_unicode(PyObject *category, PyObject *message, + Py_ssize_t stack_level, PyObject *source) +{ + PyObject *res; + + if (category == NULL) + category = PyExc_RuntimeWarning; + + res = do_warn(message, category, stack_level, source); + if (res == NULL) + return -1; + Py_DECREF(res); + + return 0; +} + +static int +_PyErr_WarnFormatV(PyObject *source, + PyObject *category, Py_ssize_t stack_level, + const char *format, va_list vargs) +{ + PyObject *message; + int res; + + message = PyUnicode_FromFormatV(format, vargs); + if (message == NULL) + return -1; + + res = warn_unicode(category, message, stack_level, source); + Py_DECREF(message); + return res; +} + +int +PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, + const char *format, ...) +{ + int res; + va_list vargs; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs); + va_end(vargs); + return res; +} + +int +PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, + const char *format, ...) +{ + int res; + va_list vargs; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning, + stack_level, format, vargs); + va_end(vargs); + return res; +} + + +int +PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level) +{ + int ret; + PyObject *message = PyUnicode_FromString(text); + if (message == NULL) + return -1; + ret = warn_unicode(category, message, stack_level, NULL); + Py_DECREF(message); + return ret; +} + +/* PyErr_Warn is only for backwards compatibility and will be removed. + Use PyErr_WarnEx instead. */ + +#undef PyErr_Warn + +int +PyErr_Warn(PyObject *category, const char *text) +{ + return PyErr_WarnEx(category, text, 1); +} + +/* Warning with explicit origin */ +int +PyErr_WarnExplicitObject(PyObject *category, PyObject *message, + PyObject *filename, int lineno, + PyObject *module, PyObject *registry) +{ + PyObject *res; + if (category == NULL) + category = PyExc_RuntimeWarning; + res = warn_explicit(category, message, filename, lineno, + module, registry, NULL, NULL); + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +int +PyErr_WarnExplicit(PyObject *category, const char *text, + const char *filename_str, int lineno, + const char *module_str, PyObject *registry) +{ + PyObject *message = PyUnicode_FromString(text); + PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); + PyObject *module = NULL; + int ret = -1; + + if (message == NULL || filename == NULL) + goto exit; + if (module_str != NULL) { + module = PyUnicode_FromString(module_str); + if (module == NULL) + goto exit; + } + + ret = PyErr_WarnExplicitObject(category, message, filename, lineno, + module, registry); + + exit: + Py_XDECREF(message); + Py_XDECREF(module); + Py_XDECREF(filename); + return ret; +} + +int +PyErr_WarnExplicitFormat(PyObject *category, + const char *filename_str, int lineno, + const char *module_str, PyObject *registry, + const char *format, ...) +{ + PyObject *message; + PyObject *module = NULL; + PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); + int ret = -1; + va_list vargs; + + if (filename == NULL) + goto exit; + if (module_str != NULL) { + module = PyUnicode_FromString(module_str); + if (module == NULL) + goto exit; + } + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + message = PyUnicode_FromFormatV(format, vargs); + if (message != NULL) { + PyObject *res; + res = warn_explicit(category, message, filename, lineno, + module, registry, NULL, NULL); + Py_DECREF(message); + if (res != NULL) { + Py_DECREF(res); + ret = 0; + } + } + va_end(vargs); +exit: + Py_XDECREF(module); + Py_XDECREF(filename); + return ret; +} + +void +_PyErr_WarnUnawaitedCoroutine(PyObject *coro) +{ + /* First, we attempt to funnel the warning through + warnings._warn_unawaited_coroutine. + + This could raise an exception, due to: + - a bug + - some kind of shutdown-related brokenness + - succeeding, but with an "error" warning filter installed, so the + warning is converted into a RuntimeWarning exception + + In the first two cases, we want to print the error (so we know what it + is!), and then print a warning directly as a fallback. In the last + case, we want to print the error (since it's the warning!), but *not* + do a fallback. And after we print the error we can't check for what + type of error it was (because PyErr_WriteUnraisable clears it), so we + need a flag to keep track. + + Since this is called from __del__ context, it's careful to never raise + an exception. + */ + _Py_IDENTIFIER(_warn_unawaited_coroutine); + int warned = 0; + PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1); + if (fn) { + PyObject *res = PyObject_CallFunctionObjArgs(fn, coro, NULL); + Py_DECREF(fn); + if (res || PyErr_ExceptionMatches(PyExc_RuntimeWarning)) { + warned = 1; + } + Py_XDECREF(res); + } + + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(coro); + } + if (!warned) { + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "coroutine '%.50S' was never awaited", + ((PyCoroObject *)coro)->cr_qualname) < 0) + { + PyErr_WriteUnraisable(coro); + } + } +} + +PyDoc_STRVAR(warn_explicit_doc, +"Low-level interface to warnings functionality."); + +static PyMethodDef warnings_functions[] = { + WARNINGS_WARN_METHODDEF + {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit, + METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, + {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, + NULL}, + /* XXX(brett.cannon): add showwarning? */ + /* XXX(brett.cannon): Reasonable to add formatwarning? */ + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef warningsmodule = { + PyModuleDef_HEAD_INIT, + MODULE_NAME, /* m_name */ + warnings__doc__, /* m_doc */ + 0, /* m_size */ + warnings_functions, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; + + +PyMODINIT_FUNC +_PyWarnings_Init(void) +{ + PyObject *m; + + m = PyModule_Create(&warningsmodule); + if (m == NULL) { + return NULL; + } + + WarningsState *st = _Warnings_GetState(); + if (st == NULL) { + goto error; + } + if (_Warnings_InitState(st) < 0) { + goto error; + } + + Py_INCREF(st->filters); + if (PyModule_AddObject(m, "filters", st->filters) < 0) { + goto error; + } + + Py_INCREF(st->once_registry); + if (PyModule_AddObject(m, "_onceregistry", st->once_registry) < 0) { + goto error; + } + + Py_INCREF(st->default_action); + if (PyModule_AddObject(m, "_defaultaction", st->default_action) < 0) { + goto error; + } + + return m; + +error: + if (st != NULL) { + _Warnings_ClearState(st); + } + Py_DECREF(m); + return NULL; +} + +// We need this to ensure that warnings still work until late in finalization. +void +_PyWarnings_Fini(PyInterpreterState *interp) +{ + _Warnings_ClearState(&interp->warnings); +} diff --git a/python/Python/asdl.c b/python/Python/asdl.c new file mode 100755 index 0000000..c211078 --- /dev/null +++ b/python/Python/asdl.c @@ -0,0 +1,64 @@ +#include "Python.h" +#include "asdl.h" + +asdl_seq * +_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena) +{ + asdl_seq *seq = NULL; + size_t n; + + /* check size is sane */ + if (size < 0 || + (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { + PyErr_NoMemory(); + return NULL; + } + n = (size ? (sizeof(void *) * (size - 1)) : 0); + + /* check if size can be added safely */ + if (n > SIZE_MAX - sizeof(asdl_seq)) { + PyErr_NoMemory(); + return NULL; + } + n += sizeof(asdl_seq); + + seq = (asdl_seq *)PyArena_Malloc(arena, n); + if (!seq) { + PyErr_NoMemory(); + return NULL; + } + memset(seq, 0, n); + seq->size = size; + return seq; +} + +asdl_int_seq * +_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena) +{ + asdl_int_seq *seq = NULL; + size_t n; + + /* check size is sane */ + if (size < 0 || + (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { + PyErr_NoMemory(); + return NULL; + } + n = (size ? (sizeof(void *) * (size - 1)) : 0); + + /* check if size can be added safely */ + if (n > SIZE_MAX - sizeof(asdl_seq)) { + PyErr_NoMemory(); + return NULL; + } + n += sizeof(asdl_seq); + + seq = (asdl_int_seq *)PyArena_Malloc(arena, n); + if (!seq) { + PyErr_NoMemory(); + return NULL; + } + memset(seq, 0, n); + seq->size = size; + return seq; +} diff --git a/python/Python/ast.c b/python/Python/ast.c new file mode 100755 index 0000000..7c1d24d --- /dev/null +++ b/python/Python/ast.c @@ -0,0 +1,5991 @@ +/* + * This file includes functions to transform a concrete syntax tree (CST) to + * an abstract syntax tree (AST). The main function is PyAST_FromNode(). + * + */ +#include "Python.h" +#include "Python-ast.h" +#include "node.h" +#include "ast.h" +#include "token.h" +#include "pythonrun.h" + +#include +#include + +#define MAXLEVEL 200 /* Max parentheses level */ + +static int validate_stmts(asdl_seq *); +static int validate_exprs(asdl_seq *, expr_context_ty, int); +static int validate_nonempty_seq(asdl_seq *, const char *, const char *); +static int validate_stmt(stmt_ty); +static int validate_expr(expr_ty, expr_context_ty); + +static int +validate_name(PyObject *name) +{ + assert(PyUnicode_Check(name)); + static const char * const forbidden[] = { + "None", + "True", + "False", + NULL + }; + for (int i = 0; forbidden[i] != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) { + PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]); + return 0; + } + } + return 1; +} + +static int +validate_comprehension(asdl_seq *gens) +{ + Py_ssize_t i; + if (!asdl_seq_LEN(gens)) { + PyErr_SetString(PyExc_ValueError, "comprehension with no generators"); + return 0; + } + for (i = 0; i < asdl_seq_LEN(gens); i++) { + comprehension_ty comp = asdl_seq_GET(gens, i); + if (!validate_expr(comp->target, Store) || + !validate_expr(comp->iter, Load) || + !validate_exprs(comp->ifs, Load, 0)) + return 0; + } + return 1; +} + +static int +validate_slice(slice_ty slice) +{ + switch (slice->kind) { + case Slice_kind: + return (!slice->v.Slice.lower || validate_expr(slice->v.Slice.lower, Load)) && + (!slice->v.Slice.upper || validate_expr(slice->v.Slice.upper, Load)) && + (!slice->v.Slice.step || validate_expr(slice->v.Slice.step, Load)); + case ExtSlice_kind: { + Py_ssize_t i; + if (!validate_nonempty_seq(slice->v.ExtSlice.dims, "dims", "ExtSlice")) + return 0; + for (i = 0; i < asdl_seq_LEN(slice->v.ExtSlice.dims); i++) + if (!validate_slice(asdl_seq_GET(slice->v.ExtSlice.dims, i))) + return 0; + return 1; + } + case Index_kind: + return validate_expr(slice->v.Index.value, Load); + default: + PyErr_SetString(PyExc_SystemError, "unknown slice node"); + return 0; + } +} + +static int +validate_keywords(asdl_seq *keywords) +{ + Py_ssize_t i; + for (i = 0; i < asdl_seq_LEN(keywords); i++) + if (!validate_expr(((keyword_ty)asdl_seq_GET(keywords, i))->value, Load)) + return 0; + return 1; +} + +static int +validate_args(asdl_seq *args) +{ + Py_ssize_t i; + for (i = 0; i < asdl_seq_LEN(args); i++) { + arg_ty arg = asdl_seq_GET(args, i); + if (arg->annotation && !validate_expr(arg->annotation, Load)) + return 0; + } + return 1; +} + +static const char * +expr_context_name(expr_context_ty ctx) +{ + switch (ctx) { + case Load: + return "Load"; + case Store: + return "Store"; + case Del: + return "Del"; + case AugLoad: + return "AugLoad"; + case AugStore: + return "AugStore"; + case Param: + return "Param"; + default: + Py_UNREACHABLE(); + } +} + +static int +validate_arguments(arguments_ty args) +{ + if (!validate_args(args->posonlyargs) || !validate_args(args->args)) { + return 0; + } + if (args->vararg && args->vararg->annotation + && !validate_expr(args->vararg->annotation, Load)) { + return 0; + } + if (!validate_args(args->kwonlyargs)) + return 0; + if (args->kwarg && args->kwarg->annotation + && !validate_expr(args->kwarg->annotation, Load)) { + return 0; + } + if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) { + PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments"); + return 0; + } + if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) { + PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as " + "kw_defaults on arguments"); + return 0; + } + return validate_exprs(args->defaults, Load, 0) && validate_exprs(args->kw_defaults, Load, 1); +} + +static int +validate_constant(PyObject *value) +{ + if (value == Py_None || value == Py_Ellipsis) + return 1; + + if (PyLong_CheckExact(value) + || PyFloat_CheckExact(value) + || PyComplex_CheckExact(value) + || PyBool_Check(value) + || PyUnicode_CheckExact(value) + || PyBytes_CheckExact(value)) + return 1; + + if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) { + PyObject *it; + + it = PyObject_GetIter(value); + if (it == NULL) + return 0; + + while (1) { + PyObject *item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(it); + return 0; + } + break; + } + + if (!validate_constant(item)) { + Py_DECREF(it); + Py_DECREF(item); + return 0; + } + Py_DECREF(item); + } + + Py_DECREF(it); + return 1; + } + + return 0; +} + +static int +validate_expr(expr_ty exp, expr_context_ty ctx) +{ + int check_ctx = 1; + expr_context_ty actual_ctx; + + /* First check expression context. */ + switch (exp->kind) { + case Attribute_kind: + actual_ctx = exp->v.Attribute.ctx; + break; + case Subscript_kind: + actual_ctx = exp->v.Subscript.ctx; + break; + case Starred_kind: + actual_ctx = exp->v.Starred.ctx; + break; + case Name_kind: + if (!validate_name(exp->v.Name.id)) { + return 0; + } + actual_ctx = exp->v.Name.ctx; + break; + case List_kind: + actual_ctx = exp->v.List.ctx; + break; + case Tuple_kind: + actual_ctx = exp->v.Tuple.ctx; + break; + default: + if (ctx != Load) { + PyErr_Format(PyExc_ValueError, "expression which can't be " + "assigned to in %s context", expr_context_name(ctx)); + return 0; + } + check_ctx = 0; + /* set actual_ctx to prevent gcc warning */ + actual_ctx = 0; + } + if (check_ctx && actual_ctx != ctx) { + PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead", + expr_context_name(ctx), expr_context_name(actual_ctx)); + return 0; + } + + /* Now validate expression. */ + switch (exp->kind) { + case BoolOp_kind: + if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) { + PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values"); + return 0; + } + return validate_exprs(exp->v.BoolOp.values, Load, 0); + case BinOp_kind: + return validate_expr(exp->v.BinOp.left, Load) && + validate_expr(exp->v.BinOp.right, Load); + case UnaryOp_kind: + return validate_expr(exp->v.UnaryOp.operand, Load); + case Lambda_kind: + return validate_arguments(exp->v.Lambda.args) && + validate_expr(exp->v.Lambda.body, Load); + case IfExp_kind: + return validate_expr(exp->v.IfExp.test, Load) && + validate_expr(exp->v.IfExp.body, Load) && + validate_expr(exp->v.IfExp.orelse, Load); + case Dict_kind: + if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) { + PyErr_SetString(PyExc_ValueError, + "Dict doesn't have the same number of keys as values"); + return 0; + } + /* null_ok=1 for keys expressions to allow dict unpacking to work in + dict literals, i.e. ``{**{a:b}}`` */ + return validate_exprs(exp->v.Dict.keys, Load, /*null_ok=*/ 1) && + validate_exprs(exp->v.Dict.values, Load, /*null_ok=*/ 0); + case Set_kind: + return validate_exprs(exp->v.Set.elts, Load, 0); +#define COMP(NAME) \ + case NAME ## _kind: \ + return validate_comprehension(exp->v.NAME.generators) && \ + validate_expr(exp->v.NAME.elt, Load); + COMP(ListComp) + COMP(SetComp) + COMP(GeneratorExp) +#undef COMP + case DictComp_kind: + return validate_comprehension(exp->v.DictComp.generators) && + validate_expr(exp->v.DictComp.key, Load) && + validate_expr(exp->v.DictComp.value, Load); + case Yield_kind: + return !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load); + case YieldFrom_kind: + return validate_expr(exp->v.YieldFrom.value, Load); + case Await_kind: + return validate_expr(exp->v.Await.value, Load); + case Compare_kind: + if (!asdl_seq_LEN(exp->v.Compare.comparators)) { + PyErr_SetString(PyExc_ValueError, "Compare with no comparators"); + return 0; + } + if (asdl_seq_LEN(exp->v.Compare.comparators) != + asdl_seq_LEN(exp->v.Compare.ops)) { + PyErr_SetString(PyExc_ValueError, "Compare has a different number " + "of comparators and operands"); + return 0; + } + return validate_exprs(exp->v.Compare.comparators, Load, 0) && + validate_expr(exp->v.Compare.left, Load); + case Call_kind: + return validate_expr(exp->v.Call.func, Load) && + validate_exprs(exp->v.Call.args, Load, 0) && + validate_keywords(exp->v.Call.keywords); + case Constant_kind: + if (!validate_constant(exp->v.Constant.value)) { + PyErr_Format(PyExc_TypeError, + "got an invalid type in Constant: %s", + Py_TYPE(exp->v.Constant.value)->tp_name); + return 0; + } + return 1; + case JoinedStr_kind: + return validate_exprs(exp->v.JoinedStr.values, Load, 0); + case FormattedValue_kind: + if (validate_expr(exp->v.FormattedValue.value, Load) == 0) + return 0; + if (exp->v.FormattedValue.format_spec) + return validate_expr(exp->v.FormattedValue.format_spec, Load); + return 1; + case Attribute_kind: + return validate_expr(exp->v.Attribute.value, Load); + case Subscript_kind: + return validate_slice(exp->v.Subscript.slice) && + validate_expr(exp->v.Subscript.value, Load); + case Starred_kind: + return validate_expr(exp->v.Starred.value, ctx); + case List_kind: + return validate_exprs(exp->v.List.elts, ctx, 0); + case Tuple_kind: + return validate_exprs(exp->v.Tuple.elts, ctx, 0); + case NamedExpr_kind: + return validate_expr(exp->v.NamedExpr.value, Load); + /* This last case doesn't have any checking. */ + case Name_kind: + return 1; + } + PyErr_SetString(PyExc_SystemError, "unexpected expression"); + return 0; +} + +static int +validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) +{ + if (asdl_seq_LEN(seq)) + return 1; + PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner); + return 0; +} + +static int +validate_assignlist(asdl_seq *targets, expr_context_ty ctx) +{ + return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && + validate_exprs(targets, ctx, 0); +} + +static int +validate_body(asdl_seq *body, const char *owner) +{ + return validate_nonempty_seq(body, "body", owner) && validate_stmts(body); +} + +static int +validate_stmt(stmt_ty stmt) +{ + Py_ssize_t i; + switch (stmt->kind) { + case FunctionDef_kind: + return validate_body(stmt->v.FunctionDef.body, "FunctionDef") && + validate_arguments(stmt->v.FunctionDef.args) && + validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) && + (!stmt->v.FunctionDef.returns || + validate_expr(stmt->v.FunctionDef.returns, Load)); + case ClassDef_kind: + return validate_body(stmt->v.ClassDef.body, "ClassDef") && + validate_exprs(stmt->v.ClassDef.bases, Load, 0) && + validate_keywords(stmt->v.ClassDef.keywords) && + validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0); + case Return_kind: + return !stmt->v.Return.value || validate_expr(stmt->v.Return.value, Load); + case Delete_kind: + return validate_assignlist(stmt->v.Delete.targets, Del); + case Assign_kind: + return validate_assignlist(stmt->v.Assign.targets, Store) && + validate_expr(stmt->v.Assign.value, Load); + case AugAssign_kind: + return validate_expr(stmt->v.AugAssign.target, Store) && + validate_expr(stmt->v.AugAssign.value, Load); + case AnnAssign_kind: + if (stmt->v.AnnAssign.target->kind != Name_kind && + stmt->v.AnnAssign.simple) { + PyErr_SetString(PyExc_TypeError, + "AnnAssign with simple non-Name target"); + return 0; + } + return validate_expr(stmt->v.AnnAssign.target, Store) && + (!stmt->v.AnnAssign.value || + validate_expr(stmt->v.AnnAssign.value, Load)) && + validate_expr(stmt->v.AnnAssign.annotation, Load); + case For_kind: + return validate_expr(stmt->v.For.target, Store) && + validate_expr(stmt->v.For.iter, Load) && + validate_body(stmt->v.For.body, "For") && + validate_stmts(stmt->v.For.orelse); + case AsyncFor_kind: + return validate_expr(stmt->v.AsyncFor.target, Store) && + validate_expr(stmt->v.AsyncFor.iter, Load) && + validate_body(stmt->v.AsyncFor.body, "AsyncFor") && + validate_stmts(stmt->v.AsyncFor.orelse); + case While_kind: + return validate_expr(stmt->v.While.test, Load) && + validate_body(stmt->v.While.body, "While") && + validate_stmts(stmt->v.While.orelse); + case If_kind: + return validate_expr(stmt->v.If.test, Load) && + validate_body(stmt->v.If.body, "If") && + validate_stmts(stmt->v.If.orelse); + case With_kind: + if (!validate_nonempty_seq(stmt->v.With.items, "items", "With")) + return 0; + for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) { + withitem_ty item = asdl_seq_GET(stmt->v.With.items, i); + if (!validate_expr(item->context_expr, Load) || + (item->optional_vars && !validate_expr(item->optional_vars, Store))) + return 0; + } + return validate_body(stmt->v.With.body, "With"); + case AsyncWith_kind: + if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith")) + return 0; + for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) { + withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i); + if (!validate_expr(item->context_expr, Load) || + (item->optional_vars && !validate_expr(item->optional_vars, Store))) + return 0; + } + return validate_body(stmt->v.AsyncWith.body, "AsyncWith"); + case Raise_kind: + if (stmt->v.Raise.exc) { + return validate_expr(stmt->v.Raise.exc, Load) && + (!stmt->v.Raise.cause || validate_expr(stmt->v.Raise.cause, Load)); + } + if (stmt->v.Raise.cause) { + PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception"); + return 0; + } + return 1; + case Try_kind: + if (!validate_body(stmt->v.Try.body, "Try")) + return 0; + if (!asdl_seq_LEN(stmt->v.Try.handlers) && + !asdl_seq_LEN(stmt->v.Try.finalbody)) { + PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody"); + return 0; + } + if (!asdl_seq_LEN(stmt->v.Try.handlers) && + asdl_seq_LEN(stmt->v.Try.orelse)) { + PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers"); + return 0; + } + for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) { + excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); + if ((handler->v.ExceptHandler.type && + !validate_expr(handler->v.ExceptHandler.type, Load)) || + !validate_body(handler->v.ExceptHandler.body, "ExceptHandler")) + return 0; + } + return (!asdl_seq_LEN(stmt->v.Try.finalbody) || + validate_stmts(stmt->v.Try.finalbody)) && + (!asdl_seq_LEN(stmt->v.Try.orelse) || + validate_stmts(stmt->v.Try.orelse)); + case Assert_kind: + return validate_expr(stmt->v.Assert.test, Load) && + (!stmt->v.Assert.msg || validate_expr(stmt->v.Assert.msg, Load)); + case Import_kind: + return validate_nonempty_seq(stmt->v.Import.names, "names", "Import"); + case ImportFrom_kind: + if (stmt->v.ImportFrom.level < 0) { + PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level"); + return 0; + } + return validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom"); + case Global_kind: + return validate_nonempty_seq(stmt->v.Global.names, "names", "Global"); + case Nonlocal_kind: + return validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal"); + case Expr_kind: + return validate_expr(stmt->v.Expr.value, Load); + case AsyncFunctionDef_kind: + return validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && + validate_arguments(stmt->v.AsyncFunctionDef.args) && + validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && + (!stmt->v.AsyncFunctionDef.returns || + validate_expr(stmt->v.AsyncFunctionDef.returns, Load)); + case Pass_kind: + case Break_kind: + case Continue_kind: + return 1; + default: + PyErr_SetString(PyExc_SystemError, "unexpected statement"); + return 0; + } +} + +static int +validate_stmts(asdl_seq *seq) +{ + Py_ssize_t i; + for (i = 0; i < asdl_seq_LEN(seq); i++) { + stmt_ty stmt = asdl_seq_GET(seq, i); + if (stmt) { + if (!validate_stmt(stmt)) + return 0; + } + else { + PyErr_SetString(PyExc_ValueError, + "None disallowed in statement list"); + return 0; + } + } + return 1; +} + +static int +validate_exprs(asdl_seq *exprs, expr_context_ty ctx, int null_ok) +{ + Py_ssize_t i; + for (i = 0; i < asdl_seq_LEN(exprs); i++) { + expr_ty expr = asdl_seq_GET(exprs, i); + if (expr) { + if (!validate_expr(expr, ctx)) + return 0; + } + else if (!null_ok) { + PyErr_SetString(PyExc_ValueError, + "None disallowed in expression list"); + return 0; + } + + } + return 1; +} + +int +PyAST_Validate(mod_ty mod) +{ + int res = 0; + + switch (mod->kind) { + case Module_kind: + res = validate_stmts(mod->v.Module.body); + break; + case Interactive_kind: + res = validate_stmts(mod->v.Interactive.body); + break; + case Expression_kind: + res = validate_expr(mod->v.Expression.body, Load); + break; + case Suite_kind: + PyErr_SetString(PyExc_ValueError, "Suite is not valid in the CPython compiler"); + break; + default: + PyErr_SetString(PyExc_SystemError, "impossible module node"); + res = 0; + break; + } + return res; +} + +/* This is done here, so defines like "test" don't interfere with AST use above. */ +#include "grammar.h" +#include "parsetok.h" +#include "graminit.h" + +/* Data structure used internally */ +struct compiling { + PyArena *c_arena; /* Arena for allocating memory. */ + PyObject *c_filename; /* filename */ + PyObject *c_normalize; /* Normalization function from unicodedata. */ + int c_feature_version; /* Latest minor version of Python for allowed features */ +}; + +static asdl_seq *seq_for_testlist(struct compiling *, const node *); +static expr_ty ast_for_expr(struct compiling *, const node *); +static stmt_ty ast_for_stmt(struct compiling *, const node *); +static asdl_seq *ast_for_suite(struct compiling *c, const node *n); +static asdl_seq *ast_for_exprlist(struct compiling *, const node *, + expr_context_ty); +static expr_ty ast_for_testlist(struct compiling *, const node *); +static stmt_ty ast_for_classdef(struct compiling *, const node *, asdl_seq *); + +static stmt_ty ast_for_with_stmt(struct compiling *, const node *, bool); +static stmt_ty ast_for_for_stmt(struct compiling *, const node *, bool); + +/* Note different signature for ast_for_call */ +static expr_ty ast_for_call(struct compiling *, const node *, expr_ty, + const node *, const node *, const node *); + +static PyObject *parsenumber(struct compiling *, const char *); +static expr_ty parsestrplus(struct compiling *, const node *n); +static void get_last_end_pos(asdl_seq *, int *, int *); + +#define COMP_GENEXP 0 +#define COMP_LISTCOMP 1 +#define COMP_SETCOMP 2 + +static int +init_normalization(struct compiling *c) +{ + PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); + if (!m) + return 0; + c->c_normalize = PyObject_GetAttrString(m, "normalize"); + Py_DECREF(m); + if (!c->c_normalize) + return 0; + return 1; +} + +static identifier +new_identifier(const char *n, struct compiling *c) +{ + PyObject *id = PyUnicode_DecodeUTF8(n, strlen(n), NULL); + if (!id) + return NULL; + /* PyUnicode_DecodeUTF8 should always return a ready string. */ + assert(PyUnicode_IS_READY(id)); + /* Check whether there are non-ASCII characters in the + identifier; if so, normalize to NFKC. */ + if (!PyUnicode_IS_ASCII(id)) { + PyObject *id2; + _Py_IDENTIFIER(NFKC); + if (!c->c_normalize && !init_normalization(c)) { + Py_DECREF(id); + return NULL; + } + PyObject *form = _PyUnicode_FromId(&PyId_NFKC); + if (form == NULL) { + Py_DECREF(id); + return NULL; + } + PyObject *args[2] = {form, id}; + id2 = _PyObject_FastCall(c->c_normalize, args, 2); + Py_DECREF(id); + if (!id2) + return NULL; + if (!PyUnicode_Check(id2)) { + PyErr_Format(PyExc_TypeError, + "unicodedata.normalize() must return a string, not " + "%.200s", + Py_TYPE(id2)->tp_name); + Py_DECREF(id2); + return NULL; + } + id = id2; + } + PyUnicode_InternInPlace(&id); + if (PyArena_AddPyObject(c->c_arena, id) < 0) { + Py_DECREF(id); + return NULL; + } + return id; +} + +#define NEW_IDENTIFIER(n) new_identifier(STR(n), c) + +static int +ast_error(struct compiling *c, const node *n, const char *errmsg, ...) +{ + PyObject *value, *errstr, *loc, *tmp; + va_list va; + + va_start(va, errmsg); + errstr = PyUnicode_FromFormatV(errmsg, va); + va_end(va); + if (!errstr) { + return 0; + } + loc = PyErr_ProgramTextObject(c->c_filename, LINENO(n)); + if (!loc) { + Py_INCREF(Py_None); + loc = Py_None; + } + tmp = Py_BuildValue("(OiiN)", c->c_filename, LINENO(n), n->n_col_offset + 1, loc); + if (!tmp) { + Py_DECREF(errstr); + return 0; + } + value = PyTuple_Pack(2, errstr, tmp); + Py_DECREF(errstr); + Py_DECREF(tmp); + if (value) { + PyErr_SetObject(PyExc_SyntaxError, value); + Py_DECREF(value); + } + return 0; +} + +/* num_stmts() returns number of contained statements. + + Use this routine to determine how big a sequence is needed for + the statements in a parse tree. Its raison d'etre is this bit of + grammar: + + stmt: simple_stmt | compound_stmt + simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE + + A simple_stmt can contain multiple small_stmt elements joined + by semicolons. If the arg is a simple_stmt, the number of + small_stmt elements is returned. +*/ + +static string +new_type_comment(const char *s, struct compiling *c) +{ + PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL); + if (res == NULL) + return NULL; + if (PyArena_AddPyObject(c->c_arena, res) < 0) { + Py_DECREF(res); + return NULL; + } + return res; +} +#define NEW_TYPE_COMMENT(n) new_type_comment(STR(n), c) + +static int +num_stmts(const node *n) +{ + int i, l; + node *ch; + + switch (TYPE(n)) { + case single_input: + if (TYPE(CHILD(n, 0)) == NEWLINE) + return 0; + else + return num_stmts(CHILD(n, 0)); + case file_input: + l = 0; + for (i = 0; i < NCH(n); i++) { + ch = CHILD(n, i); + if (TYPE(ch) == stmt) + l += num_stmts(ch); + } + return l; + case stmt: + return num_stmts(CHILD(n, 0)); + case compound_stmt: + return 1; + case simple_stmt: + return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */ + case suite: + case func_body_suite: + /* func_body_suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */ + /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */ + if (NCH(n) == 1) + return num_stmts(CHILD(n, 0)); + else { + i = 2; + l = 0; + if (TYPE(CHILD(n, 1)) == TYPE_COMMENT) + i += 2; + for (; i < (NCH(n) - 1); i++) + l += num_stmts(CHILD(n, i)); + return l; + } + default: { + char buf[128]; + + sprintf(buf, "Non-statement found: %d %d", + TYPE(n), NCH(n)); + Py_FatalError(buf); + } + } + Py_UNREACHABLE(); +} + +/* Transform the CST rooted at node * to the appropriate AST +*/ + +mod_ty +PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags, + PyObject *filename, PyArena *arena) +{ + int i, j, k, num; + asdl_seq *stmts = NULL; + asdl_seq *type_ignores = NULL; + stmt_ty s; + node *ch; + struct compiling c; + mod_ty res = NULL; + asdl_seq *argtypes = NULL; + expr_ty ret, arg; + + c.c_arena = arena; + /* borrowed reference */ + c.c_filename = filename; + c.c_normalize = NULL; + c.c_feature_version = flags && (flags->cf_flags & PyCF_ONLY_AST) ? + flags->cf_feature_version : PY_MINOR_VERSION; + + if (TYPE(n) == encoding_decl) + n = CHILD(n, 0); + + k = 0; + switch (TYPE(n)) { + case file_input: + stmts = _Py_asdl_seq_new(num_stmts(n), arena); + if (!stmts) + goto out; + for (i = 0; i < NCH(n) - 1; i++) { + ch = CHILD(n, i); + if (TYPE(ch) == NEWLINE) + continue; + REQ(ch, stmt); + num = num_stmts(ch); + if (num == 1) { + s = ast_for_stmt(&c, ch); + if (!s) + goto out; + asdl_seq_SET(stmts, k++, s); + } + else { + ch = CHILD(ch, 0); + REQ(ch, simple_stmt); + for (j = 0; j < num; j++) { + s = ast_for_stmt(&c, CHILD(ch, j * 2)); + if (!s) + goto out; + asdl_seq_SET(stmts, k++, s); + } + } + } + + /* Type ignores are stored under the ENDMARKER in file_input. */ + ch = CHILD(n, NCH(n) - 1); + REQ(ch, ENDMARKER); + num = NCH(ch); + type_ignores = _Py_asdl_seq_new(num, arena); + if (!type_ignores) + goto out; + + for (i = 0; i < num; i++) { + string type_comment = new_type_comment(STR(CHILD(ch, i)), &c); + if (!type_comment) + goto out; + type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), type_comment, arena); + if (!ti) + goto out; + asdl_seq_SET(type_ignores, i, ti); + } + + res = Module(stmts, type_ignores, arena); + break; + case eval_input: { + expr_ty testlist_ast; + + /* XXX Why not comp_for here? */ + testlist_ast = ast_for_testlist(&c, CHILD(n, 0)); + if (!testlist_ast) + goto out; + res = Expression(testlist_ast, arena); + break; + } + case single_input: + if (TYPE(CHILD(n, 0)) == NEWLINE) { + stmts = _Py_asdl_seq_new(1, arena); + if (!stmts) + goto out; + asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + arena)); + if (!asdl_seq_GET(stmts, 0)) + goto out; + res = Interactive(stmts, arena); + } + else { + n = CHILD(n, 0); + num = num_stmts(n); + stmts = _Py_asdl_seq_new(num, arena); + if (!stmts) + goto out; + if (num == 1) { + s = ast_for_stmt(&c, n); + if (!s) + goto out; + asdl_seq_SET(stmts, 0, s); + } + else { + /* Only a simple_stmt can contain multiple statements. */ + REQ(n, simple_stmt); + for (i = 0; i < NCH(n); i += 2) { + if (TYPE(CHILD(n, i)) == NEWLINE) + break; + s = ast_for_stmt(&c, CHILD(n, i)); + if (!s) + goto out; + asdl_seq_SET(stmts, i / 2, s); + } + } + + res = Interactive(stmts, arena); + } + break; + case func_type_input: + n = CHILD(n, 0); + REQ(n, func_type); + + if (TYPE(CHILD(n, 1)) == typelist) { + ch = CHILD(n, 1); + /* this is overly permissive -- we don't pay any attention to + * stars on the args -- just parse them into an ordered list */ + num = 0; + for (i = 0; i < NCH(ch); i++) { + if (TYPE(CHILD(ch, i)) == test) { + num++; + } + } + + argtypes = _Py_asdl_seq_new(num, arena); + if (!argtypes) + goto out; + + j = 0; + for (i = 0; i < NCH(ch); i++) { + if (TYPE(CHILD(ch, i)) == test) { + arg = ast_for_expr(&c, CHILD(ch, i)); + if (!arg) + goto out; + asdl_seq_SET(argtypes, j++, arg); + } + } + } + else { + argtypes = _Py_asdl_seq_new(0, arena); + if (!argtypes) + goto out; + } + + ret = ast_for_expr(&c, CHILD(n, NCH(n) - 1)); + if (!ret) + goto out; + res = FunctionType(argtypes, ret, arena); + break; + default: + PyErr_Format(PyExc_SystemError, + "invalid node %d for PyAST_FromNode", TYPE(n)); + goto out; + } + out: + if (c.c_normalize) { + Py_DECREF(c.c_normalize); + } + return res; +} + +mod_ty +PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename_str, + PyArena *arena) +{ + mod_ty mod; + PyObject *filename; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyAST_FromNodeObject(n, flags, filename, arena); + Py_DECREF(filename); + return mod; + +} + +/* Return the AST repr. of the operator represented as syntax (|, ^, etc.) +*/ + +static operator_ty +get_operator(struct compiling *c, const node *n) +{ + switch (TYPE(n)) { + case VBAR: + return BitOr; + case CIRCUMFLEX: + return BitXor; + case AMPER: + return BitAnd; + case LEFTSHIFT: + return LShift; + case RIGHTSHIFT: + return RShift; + case PLUS: + return Add; + case MINUS: + return Sub; + case STAR: + return Mult; + case AT: + if (c->c_feature_version < 5) { + ast_error(c, n, + "The '@' operator is only supported in Python 3.5 and greater"); + return (operator_ty)0; + } + return MatMult; + case SLASH: + return Div; + case DOUBLESLASH: + return FloorDiv; + case PERCENT: + return Mod; + default: + return (operator_ty)0; + } +} + +static const char * const FORBIDDEN[] = { + "None", + "True", + "False", + "__debug__", + NULL, +}; + +static int +forbidden_name(struct compiling *c, identifier name, const node *n, + int full_checks) +{ + assert(PyUnicode_Check(name)); + const char * const *p = FORBIDDEN; + if (!full_checks) { + /* In most cases, the parser will protect True, False, and None + from being assign to. */ + p += 3; + } + for (; *p; p++) { + if (_PyUnicode_EqualToASCIIString(name, *p)) { + ast_error(c, n, "cannot assign to %U", name); + return 1; + } + } + return 0; +} + +static expr_ty +copy_location(expr_ty e, const node *n, const node *end) +{ + if (e) { + e->lineno = LINENO(n); + e->col_offset = n->n_col_offset; + e->end_lineno = end->n_end_lineno; + e->end_col_offset = end->n_end_col_offset; + } + return e; +} + +static const char * +get_expr_name(expr_ty e) +{ + switch (e->kind) { + case Attribute_kind: + return "attribute"; + case Subscript_kind: + return "subscript"; + case Starred_kind: + return "starred"; + case Name_kind: + return "name"; + case List_kind: + return "list"; + case Tuple_kind: + return "tuple"; + case Lambda_kind: + return "lambda"; + case Call_kind: + return "function call"; + case BoolOp_kind: + case BinOp_kind: + case UnaryOp_kind: + return "operator"; + case GeneratorExp_kind: + return "generator expression"; + case Yield_kind: + case YieldFrom_kind: + return "yield expression"; + case Await_kind: + return "await expression"; + case ListComp_kind: + return "list comprehension"; + case SetComp_kind: + return "set comprehension"; + case DictComp_kind: + return "dict comprehension"; + case Dict_kind: + return "dict display"; + case Set_kind: + return "set display"; + case JoinedStr_kind: + case FormattedValue_kind: + return "f-string expression"; + case Constant_kind: { + PyObject *value = e->v.Constant.value; + if (value == Py_None) { + return "None"; + } + if (value == Py_False) { + return "False"; + } + if (value == Py_True) { + return "True"; + } + if (value == Py_Ellipsis) { + return "Ellipsis"; + } + return "literal"; + } + case Compare_kind: + return "comparison"; + case IfExp_kind: + return "conditional expression"; + case NamedExpr_kind: + return "named expression"; + default: + PyErr_Format(PyExc_SystemError, + "unexpected expression in assignment %d (line %d)", + e->kind, e->lineno); + return NULL; + } +} + +/* Set the context ctx for expr_ty e, recursively traversing e. + + Only sets context for expr kinds that "can appear in assignment context" + (according to ../Parser/Python.asdl). For other expr kinds, it sets + an appropriate syntax error and returns false. +*/ + +static int +set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) +{ + asdl_seq *s = NULL; + + /* The ast defines augmented store and load contexts, but the + implementation here doesn't actually use them. The code may be + a little more complex than necessary as a result. It also means + that expressions in an augmented assignment have a Store context. + Consider restructuring so that augmented assignment uses + set_context(), too. + */ + assert(ctx != AugStore && ctx != AugLoad); + + switch (e->kind) { + case Attribute_kind: + e->v.Attribute.ctx = ctx; + if (ctx == Store && forbidden_name(c, e->v.Attribute.attr, n, 1)) + return 0; + break; + case Subscript_kind: + e->v.Subscript.ctx = ctx; + break; + case Starred_kind: + e->v.Starred.ctx = ctx; + if (!set_context(c, e->v.Starred.value, ctx, n)) + return 0; + break; + case Name_kind: + if (ctx == Store) { + if (forbidden_name(c, e->v.Name.id, n, 0)) + return 0; /* forbidden_name() calls ast_error() */ + } + e->v.Name.ctx = ctx; + break; + case List_kind: + e->v.List.ctx = ctx; + s = e->v.List.elts; + break; + case Tuple_kind: + e->v.Tuple.ctx = ctx; + s = e->v.Tuple.elts; + break; + default: { + const char *expr_name = get_expr_name(e); + if (expr_name != NULL) { + ast_error(c, n, "cannot %s %s", + ctx == Store ? "assign to" : "delete", + expr_name); + } + return 0; + } + } + + /* If the LHS is a list or tuple, we need to set the assignment + context for all the contained elements. + */ + if (s) { + Py_ssize_t i; + + for (i = 0; i < asdl_seq_LEN(s); i++) { + if (!set_context(c, (expr_ty)asdl_seq_GET(s, i), ctx, n)) + return 0; + } + } + return 1; +} + +static operator_ty +ast_for_augassign(struct compiling *c, const node *n) +{ + REQ(n, augassign); + n = CHILD(n, 0); + switch (STR(n)[0]) { + case '+': + return Add; + case '-': + return Sub; + case '/': + if (STR(n)[1] == '/') + return FloorDiv; + else + return Div; + case '%': + return Mod; + case '<': + return LShift; + case '>': + return RShift; + case '&': + return BitAnd; + case '^': + return BitXor; + case '|': + return BitOr; + case '*': + if (STR(n)[1] == '*') + return Pow; + else + return Mult; + case '@': + if (c->c_feature_version < 5) { + ast_error(c, n, + "The '@' operator is only supported in Python 3.5 and greater"); + return (operator_ty)0; + } + return MatMult; + default: + PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n)); + return (operator_ty)0; + } +} + +static cmpop_ty +ast_for_comp_op(struct compiling *c, const node *n) +{ + /* comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is' + |'is' 'not' + */ + REQ(n, comp_op); + if (NCH(n) == 1) { + n = CHILD(n, 0); + switch (TYPE(n)) { + case LESS: + return Lt; + case GREATER: + return Gt; + case EQEQUAL: /* == */ + return Eq; + case LESSEQUAL: + return LtE; + case GREATEREQUAL: + return GtE; + case NOTEQUAL: + return NotEq; + case NAME: + if (strcmp(STR(n), "in") == 0) + return In; + if (strcmp(STR(n), "is") == 0) + return Is; + /* fall through */ + default: + PyErr_Format(PyExc_SystemError, "invalid comp_op: %s", + STR(n)); + return (cmpop_ty)0; + } + } + else if (NCH(n) == 2) { + /* handle "not in" and "is not" */ + switch (TYPE(CHILD(n, 0))) { + case NAME: + if (strcmp(STR(CHILD(n, 1)), "in") == 0) + return NotIn; + if (strcmp(STR(CHILD(n, 0)), "is") == 0) + return IsNot; + /* fall through */ + default: + PyErr_Format(PyExc_SystemError, "invalid comp_op: %s %s", + STR(CHILD(n, 0)), STR(CHILD(n, 1))); + return (cmpop_ty)0; + } + } + PyErr_Format(PyExc_SystemError, "invalid comp_op: has %d children", + NCH(n)); + return (cmpop_ty)0; +} + +static asdl_seq * +seq_for_testlist(struct compiling *c, const node *n) +{ + /* testlist: test (',' test)* [','] + testlist_star_expr: test|star_expr (',' test|star_expr)* [','] + */ + asdl_seq *seq; + expr_ty expression; + int i; + assert(TYPE(n) == testlist || TYPE(n) == testlist_star_expr || TYPE(n) == testlist_comp); + + seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); + if (!seq) + return NULL; + + for (i = 0; i < NCH(n); i += 2) { + const node *ch = CHILD(n, i); + assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr || TYPE(ch) == namedexpr_test); + + expression = ast_for_expr(c, ch); + if (!expression) + return NULL; + + assert(i / 2 < seq->size); + asdl_seq_SET(seq, i / 2, expression); + } + return seq; +} + +static arg_ty +ast_for_arg(struct compiling *c, const node *n) +{ + identifier name; + expr_ty annotation = NULL; + node *ch; + arg_ty ret; + + assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef); + ch = CHILD(n, 0); + name = NEW_IDENTIFIER(ch); + if (!name) + return NULL; + if (forbidden_name(c, name, ch, 0)) + return NULL; + + if (NCH(n) == 3 && TYPE(CHILD(n, 1)) == COLON) { + annotation = ast_for_expr(c, CHILD(n, 2)); + if (!annotation) + return NULL; + } + + ret = arg(name, annotation, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + if (!ret) + return NULL; + return ret; +} + +/* returns -1 if failed to handle keyword only arguments + returns new position to keep processing if successful + (',' tfpdef ['=' test])* + ^^^ + start pointing here + */ +static int +handle_keywordonly_args(struct compiling *c, const node *n, int start, + asdl_seq *kwonlyargs, asdl_seq *kwdefaults) +{ + PyObject *argname; + node *ch; + expr_ty expression, annotation; + arg_ty arg = NULL; + int i = start; + int j = 0; /* index for kwdefaults and kwonlyargs */ + + if (kwonlyargs == NULL) { + ast_error(c, CHILD(n, start), "named arguments must follow bare *"); + return -1; + } + assert(kwdefaults != NULL); + while (i < NCH(n)) { + ch = CHILD(n, i); + switch (TYPE(ch)) { + case vfpdef: + case tfpdef: + if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { + expression = ast_for_expr(c, CHILD(n, i + 2)); + if (!expression) + goto error; + asdl_seq_SET(kwdefaults, j, expression); + i += 2; /* '=' and test */ + } + else { /* setting NULL if no default value exists */ + asdl_seq_SET(kwdefaults, j, NULL); + } + if (NCH(ch) == 3) { + /* ch is NAME ':' test */ + annotation = ast_for_expr(c, CHILD(ch, 2)); + if (!annotation) + goto error; + } + else { + annotation = NULL; + } + ch = CHILD(ch, 0); + argname = NEW_IDENTIFIER(ch); + if (!argname) + goto error; + if (forbidden_name(c, argname, ch, 0)) + goto error; + arg = arg(argname, annotation, NULL, LINENO(ch), ch->n_col_offset, + ch->n_end_lineno, ch->n_end_col_offset, + c->c_arena); + if (!arg) + goto error; + asdl_seq_SET(kwonlyargs, j++, arg); + i += 1; /* the name */ + if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) + i += 1; /* the comma, if present */ + break; + case TYPE_COMMENT: + /* arg will be equal to the last argument processed */ + arg->type_comment = NEW_TYPE_COMMENT(ch); + if (!arg->type_comment) + goto error; + i += 1; + break; + case DOUBLESTAR: + return i; + default: + ast_error(c, ch, "unexpected node"); + goto error; + } + } + return i; + error: + return -1; +} + +/* Create AST for argument list. */ + +static arguments_ty +ast_for_arguments(struct compiling *c, const node *n) +{ + /* This function handles both typedargslist (function definition) + and varargslist (lambda definition). + + parameters: '(' [typedargslist] ')' + + The following definition for typedarglist is equivalent to this set of rules: + + arguments = argument (',' [TYPE_COMMENT] argument)* + argument = tfpdef ['=' test] + kwargs = '**' tfpdef [','] [TYPE_COMMENT] + args = '*' [tfpdef] + kwonly_kwargs = (',' [TYPE_COMMENT] argument)* (TYPE_COMMENT | [',' + [TYPE_COMMENT] [kwargs]]) + args_kwonly_kwargs = args kwonly_kwargs | kwargs + poskeyword_args_kwonly_kwargs = arguments ( TYPE_COMMENT | [',' + [TYPE_COMMENT] [args_kwonly_kwargs]]) + typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs + typedarglist = (arguments ',' [TYPE_COMMENT] '/' [',' [[TYPE_COMMENT] + typedargslist_no_posonly]])|(typedargslist_no_posonly)" + + typedargslist: ( (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])* + ',' [TYPE_COMMENT] '/' [',' [ [TYPE_COMMENT] tfpdef ['=' test] ( ',' + [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*' + [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' + [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] + [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* + (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | + '**' tfpdef [','] [TYPE_COMMENT]]] ) | (tfpdef ['=' test] (',' + [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*' + [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' + [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [','] + [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* + (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | + '**' tfpdef [','] [TYPE_COMMENT])) + + tfpdef: NAME [':' test] + + The following definition for varargslist is equivalent to this set of rules: + + arguments = argument (',' argument )* + argument = vfpdef ['=' test] + kwargs = '**' vfpdef [','] + args = '*' [vfpdef] + kwonly_kwargs = (',' argument )* [',' [kwargs]] + args_kwonly_kwargs = args kwonly_kwargs | kwargs + poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]] + vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs + varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | + (vararglist_no_posonly) + + varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ (vfpdef ['=' + test] (',' vfpdef ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' + ['**' vfpdef [',']]] | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* + [',' ['**' vfpdef [',']]] | '**' vfpdef [',']) ]] | (vfpdef ['=' test] (',' vfpdef + ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef + [',']]] | '**' vfpdef [',']) + + vfpdef: NAME + + */ + int i, j, k, l, nposonlyargs=0, nposargs = 0, nkwonlyargs = 0; + int nposdefaults = 0, found_default = 0; + asdl_seq *posonlyargs, *posargs, *posdefaults, *kwonlyargs, *kwdefaults; + arg_ty vararg = NULL, kwarg = NULL; + arg_ty arg = NULL; + node *ch; + + if (TYPE(n) == parameters) { + if (NCH(n) == 2) /* () as argument list */ + return arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); + n = CHILD(n, 1); + } + assert(TYPE(n) == typedargslist || TYPE(n) == varargslist); + + /* First count the number of positional args & defaults. The + variable i is the loop index for this for loop and the next. + The next loop picks up where the first leaves off. + */ + for (i = 0; i < NCH(n); i++) { + ch = CHILD(n, i); + if (TYPE(ch) == STAR) { + /* skip star */ + i++; + if (i < NCH(n) && /* skip argument following star */ + (TYPE(CHILD(n, i)) == tfpdef || + TYPE(CHILD(n, i)) == vfpdef)) { + i++; + } + break; + } + if (TYPE(ch) == DOUBLESTAR) break; + if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++; + if (TYPE(ch) == EQUAL) nposdefaults++; + if (TYPE(ch) == SLASH ) { + nposonlyargs = nposargs; + nposargs = 0; + } + } + /* count the number of keyword only args & + defaults for keyword only args */ + for ( ; i < NCH(n); ++i) { + ch = CHILD(n, i); + if (TYPE(ch) == DOUBLESTAR) break; + if (TYPE(ch) == tfpdef || TYPE(ch) == vfpdef) nkwonlyargs++; + } + posonlyargs = (nposonlyargs ? _Py_asdl_seq_new(nposonlyargs, c->c_arena) : NULL); + if (!posonlyargs && nposonlyargs) { + return NULL; + } + posargs = (nposargs ? _Py_asdl_seq_new(nposargs, c->c_arena) : NULL); + if (!posargs && nposargs) + return NULL; + kwonlyargs = (nkwonlyargs ? + _Py_asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); + if (!kwonlyargs && nkwonlyargs) + return NULL; + posdefaults = (nposdefaults ? + _Py_asdl_seq_new(nposdefaults, c->c_arena) : NULL); + if (!posdefaults && nposdefaults) + return NULL; + /* The length of kwonlyargs and kwdefaults are same + since we set NULL as default for keyword only argument w/o default + - we have sequence data structure, but no dictionary */ + kwdefaults = (nkwonlyargs ? + _Py_asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); + if (!kwdefaults && nkwonlyargs) + return NULL; + + /* tfpdef: NAME [':' test] + vfpdef: NAME + */ + i = 0; + j = 0; /* index for defaults */ + k = 0; /* index for args */ + l = 0; /* index for posonlyargs */ + while (i < NCH(n)) { + ch = CHILD(n, i); + switch (TYPE(ch)) { + case tfpdef: + case vfpdef: + /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is + anything other than EQUAL or a comma? */ + /* XXX Should NCH(n) check be made a separate check? */ + if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { + expr_ty expression = ast_for_expr(c, CHILD(n, i + 2)); + if (!expression) + return NULL; + assert(posdefaults != NULL); + asdl_seq_SET(posdefaults, j++, expression); + i += 2; + found_default = 1; + } + else if (found_default) { + ast_error(c, n, + "non-default argument follows default argument"); + return NULL; + } + arg = ast_for_arg(c, ch); + if (!arg) + return NULL; + if (l < nposonlyargs) { + asdl_seq_SET(posonlyargs, l++, arg); + } else { + asdl_seq_SET(posargs, k++, arg); + } + i += 1; /* the name */ + if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) + i += 1; /* the comma, if present */ + break; + case SLASH: + /* Advance the slash and the comma. If there are more names + * after the slash there will be a comma so we are advancing + * the correct number of nodes. If the slash is the last item, + * we will be advancing an extra token but then * i > NCH(n) + * and the enclosing while will finish correctly. */ + i += 2; + break; + case STAR: + if (i+1 >= NCH(n) || + (i+2 == NCH(n) && (TYPE(CHILD(n, i+1)) == COMMA + || TYPE(CHILD(n, i+1)) == TYPE_COMMENT))) { + ast_error(c, CHILD(n, i), + "named arguments must follow bare *"); + return NULL; + } + ch = CHILD(n, i+1); /* tfpdef or COMMA */ + if (TYPE(ch) == COMMA) { + int res = 0; + i += 2; /* now follows keyword only arguments */ + + if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) { + ast_error(c, CHILD(n, i), + "bare * has associated type comment"); + return NULL; + } + + res = handle_keywordonly_args(c, n, i, + kwonlyargs, kwdefaults); + if (res == -1) return NULL; + i = res; /* res has new position to process */ + } + else { + vararg = ast_for_arg(c, ch); + if (!vararg) + return NULL; + + i += 2; /* the star and the name */ + if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) + i += 1; /* the comma, if present */ + + if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) { + vararg->type_comment = NEW_TYPE_COMMENT(CHILD(n, i)); + if (!vararg->type_comment) + return NULL; + i += 1; + } + + if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef + || TYPE(CHILD(n, i)) == vfpdef)) { + int res = 0; + res = handle_keywordonly_args(c, n, i, + kwonlyargs, kwdefaults); + if (res == -1) return NULL; + i = res; /* res has new position to process */ + } + } + break; + case DOUBLESTAR: + ch = CHILD(n, i+1); /* tfpdef */ + assert(TYPE(ch) == tfpdef || TYPE(ch) == vfpdef); + kwarg = ast_for_arg(c, ch); + if (!kwarg) + return NULL; + i += 2; /* the double star and the name */ + if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA) + i += 1; /* the comma, if present */ + break; + case TYPE_COMMENT: + assert(i); + + if (kwarg) + arg = kwarg; + + /* arg will be equal to the last argument processed */ + arg->type_comment = NEW_TYPE_COMMENT(ch); + if (!arg->type_comment) + return NULL; + i += 1; + break; + default: + PyErr_Format(PyExc_SystemError, + "unexpected node in varargslist: %d @ %d", + TYPE(ch), i); + return NULL; + } + } + return arguments(posonlyargs, posargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena); +} + +static expr_ty +ast_for_dotted_name(struct compiling *c, const node *n) +{ + expr_ty e; + identifier id; + int lineno, col_offset; + int i; + node *ch; + + REQ(n, dotted_name); + + lineno = LINENO(n); + col_offset = n->n_col_offset; + + ch = CHILD(n, 0); + id = NEW_IDENTIFIER(ch); + if (!id) + return NULL; + e = Name(id, Load, lineno, col_offset, + ch->n_end_lineno, ch->n_end_col_offset, c->c_arena); + if (!e) + return NULL; + + for (i = 2; i < NCH(n); i+=2) { + const node *child = CHILD(n, i); + id = NEW_IDENTIFIER(child); + if (!id) + return NULL; + e = Attribute(e, id, Load, lineno, col_offset, + child->n_end_lineno, child->n_end_col_offset, c->c_arena); + if (!e) + return NULL; + } + + return e; +} + +static expr_ty +ast_for_decorator(struct compiling *c, const node *n) +{ + /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */ + expr_ty d = NULL; + expr_ty name_expr; + + REQ(n, decorator); + REQ(CHILD(n, 0), AT); + REQ(RCHILD(n, -1), NEWLINE); + + name_expr = ast_for_dotted_name(c, CHILD(n, 1)); + if (!name_expr) + return NULL; + + if (NCH(n) == 3) { /* No arguments */ + d = name_expr; + name_expr = NULL; + } + else if (NCH(n) == 5) { /* Call with no arguments */ + d = Call(name_expr, NULL, NULL, + name_expr->lineno, name_expr->col_offset, + CHILD(n, 3)->n_end_lineno, CHILD(n, 3)->n_end_col_offset, + c->c_arena); + if (!d) + return NULL; + name_expr = NULL; + } + else { + d = ast_for_call(c, CHILD(n, 3), name_expr, + CHILD(n, 1), CHILD(n, 2), CHILD(n, 4)); + if (!d) + return NULL; + name_expr = NULL; + } + + return d; +} + +static asdl_seq* +ast_for_decorators(struct compiling *c, const node *n) +{ + asdl_seq* decorator_seq; + expr_ty d; + int i; + + REQ(n, decorators); + decorator_seq = _Py_asdl_seq_new(NCH(n), c->c_arena); + if (!decorator_seq) + return NULL; + + for (i = 0; i < NCH(n); i++) { + d = ast_for_decorator(c, CHILD(n, i)); + if (!d) + return NULL; + asdl_seq_SET(decorator_seq, i, d); + } + return decorator_seq; +} + +static stmt_ty +ast_for_funcdef_impl(struct compiling *c, const node *n0, + asdl_seq *decorator_seq, bool is_async) +{ + /* funcdef: 'def' NAME parameters ['->' test] ':' [TYPE_COMMENT] suite */ + const node * const n = is_async ? CHILD(n0, 1) : n0; + identifier name; + arguments_ty args; + asdl_seq *body; + expr_ty returns = NULL; + int name_i = 1; + int end_lineno, end_col_offset; + node *tc; + string type_comment = NULL; + + if (is_async && c->c_feature_version < 5) { + ast_error(c, n, + "Async functions are only supported in Python 3.5 and greater"); + return NULL; + } + + REQ(n, funcdef); + + name = NEW_IDENTIFIER(CHILD(n, name_i)); + if (!name) + return NULL; + if (forbidden_name(c, name, CHILD(n, name_i), 0)) + return NULL; + args = ast_for_arguments(c, CHILD(n, name_i + 1)); + if (!args) + return NULL; + if (TYPE(CHILD(n, name_i+2)) == RARROW) { + returns = ast_for_expr(c, CHILD(n, name_i + 3)); + if (!returns) + return NULL; + name_i += 2; + } + if (TYPE(CHILD(n, name_i + 3)) == TYPE_COMMENT) { + type_comment = NEW_TYPE_COMMENT(CHILD(n, name_i + 3)); + if (!type_comment) + return NULL; + name_i += 1; + } + body = ast_for_suite(c, CHILD(n, name_i + 3)); + if (!body) + return NULL; + get_last_end_pos(body, &end_lineno, &end_col_offset); + + if (NCH(CHILD(n, name_i + 3)) > 1) { + /* Check if the suite has a type comment in it. */ + tc = CHILD(CHILD(n, name_i + 3), 1); + + if (TYPE(tc) == TYPE_COMMENT) { + if (type_comment != NULL) { + ast_error(c, n, "Cannot have two type comments on def"); + return NULL; + } + type_comment = NEW_TYPE_COMMENT(tc); + if (!type_comment) + return NULL; + } + } + + if (is_async) + return AsyncFunctionDef(name, args, body, decorator_seq, returns, type_comment, + LINENO(n0), n0->n_col_offset, end_lineno, end_col_offset, c->c_arena); + else + return FunctionDef(name, args, body, decorator_seq, returns, type_comment, + LINENO(n), n->n_col_offset, end_lineno, end_col_offset, c->c_arena); +} + +static stmt_ty +ast_for_async_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) +{ + /* async_funcdef: ASYNC funcdef */ + REQ(n, async_funcdef); + REQ(CHILD(n, 0), ASYNC); + REQ(CHILD(n, 1), funcdef); + + return ast_for_funcdef_impl(c, n, decorator_seq, + true /* is_async */); +} + +static stmt_ty +ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) +{ + /* funcdef: 'def' NAME parameters ['->' test] ':' suite */ + return ast_for_funcdef_impl(c, n, decorator_seq, + false /* is_async */); +} + + +static stmt_ty +ast_for_async_stmt(struct compiling *c, const node *n) +{ + /* async_stmt: ASYNC (funcdef | with_stmt | for_stmt) */ + REQ(n, async_stmt); + REQ(CHILD(n, 0), ASYNC); + + switch (TYPE(CHILD(n, 1))) { + case funcdef: + return ast_for_funcdef_impl(c, n, NULL, + true /* is_async */); + case with_stmt: + return ast_for_with_stmt(c, n, + true /* is_async */); + + case for_stmt: + return ast_for_for_stmt(c, n, + true /* is_async */); + + default: + PyErr_Format(PyExc_SystemError, + "invalid async stament: %s", + STR(CHILD(n, 1))); + return NULL; + } +} + +static stmt_ty +ast_for_decorated(struct compiling *c, const node *n) +{ + /* decorated: decorators (classdef | funcdef | async_funcdef) */ + stmt_ty thing = NULL; + asdl_seq *decorator_seq = NULL; + + REQ(n, decorated); + + decorator_seq = ast_for_decorators(c, CHILD(n, 0)); + if (!decorator_seq) + return NULL; + + assert(TYPE(CHILD(n, 1)) == funcdef || + TYPE(CHILD(n, 1)) == async_funcdef || + TYPE(CHILD(n, 1)) == classdef); + + if (TYPE(CHILD(n, 1)) == funcdef) { + thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq); + } else if (TYPE(CHILD(n, 1)) == classdef) { + thing = ast_for_classdef(c, CHILD(n, 1), decorator_seq); + } else if (TYPE(CHILD(n, 1)) == async_funcdef) { + thing = ast_for_async_funcdef(c, CHILD(n, 1), decorator_seq); + } + return thing; +} + +static expr_ty +ast_for_namedexpr(struct compiling *c, const node *n) +{ + /* namedexpr_test: test [':=' test] + argument: ( test [comp_for] | + test ':=' test | + test '=' test | + '**' test | + '*' test ) + */ + expr_ty target, value; + + target = ast_for_expr(c, CHILD(n, 0)); + if (!target) + return NULL; + + value = ast_for_expr(c, CHILD(n, 2)); + if (!value) + return NULL; + + if (target->kind != Name_kind) { + const char *expr_name = get_expr_name(target); + if (expr_name != NULL) { + ast_error(c, n, "cannot use assignment expressions with %s", expr_name); + } + return NULL; + } + + if (!set_context(c, target, Store, n)) + return NULL; + + return NamedExpr(target, value, LINENO(n), n->n_col_offset, n->n_end_lineno, + n->n_end_col_offset, c->c_arena); +} + +static expr_ty +ast_for_lambdef(struct compiling *c, const node *n) +{ + /* lambdef: 'lambda' [varargslist] ':' test + lambdef_nocond: 'lambda' [varargslist] ':' test_nocond */ + arguments_ty args; + expr_ty expression; + + if (NCH(n) == 3) { + args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena); + if (!args) + return NULL; + expression = ast_for_expr(c, CHILD(n, 2)); + if (!expression) + return NULL; + } + else { + args = ast_for_arguments(c, CHILD(n, 1)); + if (!args) + return NULL; + expression = ast_for_expr(c, CHILD(n, 3)); + if (!expression) + return NULL; + } + + return Lambda(args, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +static expr_ty +ast_for_ifexpr(struct compiling *c, const node *n) +{ + /* test: or_test 'if' or_test 'else' test */ + expr_ty expression, body, orelse; + + assert(NCH(n) == 5); + body = ast_for_expr(c, CHILD(n, 0)); + if (!body) + return NULL; + expression = ast_for_expr(c, CHILD(n, 2)); + if (!expression) + return NULL; + orelse = ast_for_expr(c, CHILD(n, 4)); + if (!orelse) + return NULL; + return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + c->c_arena); +} + +/* + Count the number of 'for' loops in a comprehension. + + Helper for ast_for_comprehension(). +*/ + +static int +count_comp_fors(struct compiling *c, const node *n) +{ + int n_fors = 0; + + count_comp_for: + n_fors++; + REQ(n, comp_for); + if (NCH(n) == 2) { + REQ(CHILD(n, 0), ASYNC); + n = CHILD(n, 1); + } + else if (NCH(n) == 1) { + n = CHILD(n, 0); + } + else { + goto error; + } + if (NCH(n) == (5)) { + n = CHILD(n, 4); + } + else { + return n_fors; + } + count_comp_iter: + REQ(n, comp_iter); + n = CHILD(n, 0); + if (TYPE(n) == comp_for) + goto count_comp_for; + else if (TYPE(n) == comp_if) { + if (NCH(n) == 3) { + n = CHILD(n, 2); + goto count_comp_iter; + } + else + return n_fors; + } + + error: + /* Should never be reached */ + PyErr_SetString(PyExc_SystemError, + "logic error in count_comp_fors"); + return -1; +} + +/* Count the number of 'if' statements in a comprehension. + + Helper for ast_for_comprehension(). +*/ + +static int +count_comp_ifs(struct compiling *c, const node *n) +{ + int n_ifs = 0; + + while (1) { + REQ(n, comp_iter); + if (TYPE(CHILD(n, 0)) == comp_for) + return n_ifs; + n = CHILD(n, 0); + REQ(n, comp_if); + n_ifs++; + if (NCH(n) == 2) + return n_ifs; + n = CHILD(n, 2); + } +} + +static asdl_seq * +ast_for_comprehension(struct compiling *c, const node *n) +{ + int i, n_fors; + asdl_seq *comps; + + n_fors = count_comp_fors(c, n); + if (n_fors == -1) + return NULL; + + comps = _Py_asdl_seq_new(n_fors, c->c_arena); + if (!comps) + return NULL; + + for (i = 0; i < n_fors; i++) { + comprehension_ty comp; + asdl_seq *t; + expr_ty expression, first; + node *for_ch; + node *sync_n; + int is_async = 0; + + REQ(n, comp_for); + + if (NCH(n) == 2) { + is_async = 1; + REQ(CHILD(n, 0), ASYNC); + sync_n = CHILD(n, 1); + } + else { + sync_n = CHILD(n, 0); + } + REQ(sync_n, sync_comp_for); + + /* Async comprehensions only allowed in Python 3.6 and greater */ + if (is_async && c->c_feature_version < 6) { + ast_error(c, n, + "Async comprehensions are only supported in Python 3.6 and greater"); + return NULL; + } + + for_ch = CHILD(sync_n, 1); + t = ast_for_exprlist(c, for_ch, Store); + if (!t) + return NULL; + expression = ast_for_expr(c, CHILD(sync_n, 3)); + if (!expression) + return NULL; + + /* Check the # of children rather than the length of t, since + (x for x, in ...) has 1 element in t, but still requires a Tuple. */ + first = (expr_ty)asdl_seq_GET(t, 0); + if (NCH(for_ch) == 1) + comp = comprehension(first, expression, NULL, + is_async, c->c_arena); + else + comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset, + for_ch->n_end_lineno, for_ch->n_end_col_offset, + c->c_arena), + expression, NULL, is_async, c->c_arena); + if (!comp) + return NULL; + + if (NCH(sync_n) == 5) { + int j, n_ifs; + asdl_seq *ifs; + + n = CHILD(sync_n, 4); + n_ifs = count_comp_ifs(c, n); + if (n_ifs == -1) + return NULL; + + ifs = _Py_asdl_seq_new(n_ifs, c->c_arena); + if (!ifs) + return NULL; + + for (j = 0; j < n_ifs; j++) { + REQ(n, comp_iter); + n = CHILD(n, 0); + REQ(n, comp_if); + + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + asdl_seq_SET(ifs, j, expression); + if (NCH(n) == 3) + n = CHILD(n, 2); + } + /* on exit, must guarantee that n is a comp_for */ + if (TYPE(n) == comp_iter) + n = CHILD(n, 0); + comp->ifs = ifs; + } + asdl_seq_SET(comps, i, comp); + } + return comps; +} + +static expr_ty +ast_for_itercomp(struct compiling *c, const node *n, int type) +{ + /* testlist_comp: (test|star_expr) + * ( comp_for | (',' (test|star_expr))* [','] ) */ + expr_ty elt; + asdl_seq *comps; + node *ch; + + assert(NCH(n) > 1); + + ch = CHILD(n, 0); + elt = ast_for_expr(c, ch); + if (!elt) + return NULL; + if (elt->kind == Starred_kind) { + ast_error(c, ch, "iterable unpacking cannot be used in comprehension"); + return NULL; + } + + comps = ast_for_comprehension(c, CHILD(n, 1)); + if (!comps) + return NULL; + + if (type == COMP_GENEXP) + return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + else if (type == COMP_LISTCOMP) + return ListComp(elt, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + else if (type == COMP_SETCOMP) + return SetComp(elt, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + else + /* Should never happen */ + return NULL; +} + +/* Fills in the key, value pair corresponding to the dict element. In case + * of an unpacking, key is NULL. *i is advanced by the number of ast + * elements. Iff successful, nonzero is returned. + */ +static int +ast_for_dictelement(struct compiling *c, const node *n, int *i, + expr_ty *key, expr_ty *value) +{ + expr_ty expression; + if (TYPE(CHILD(n, *i)) == DOUBLESTAR) { + assert(NCH(n) - *i >= 2); + + expression = ast_for_expr(c, CHILD(n, *i + 1)); + if (!expression) + return 0; + *key = NULL; + *value = expression; + + *i += 2; + } + else { + assert(NCH(n) - *i >= 3); + + expression = ast_for_expr(c, CHILD(n, *i)); + if (!expression) + return 0; + *key = expression; + + REQ(CHILD(n, *i + 1), COLON); + + expression = ast_for_expr(c, CHILD(n, *i + 2)); + if (!expression) + return 0; + *value = expression; + + *i += 3; + } + return 1; +} + +static expr_ty +ast_for_dictcomp(struct compiling *c, const node *n) +{ + expr_ty key, value; + asdl_seq *comps; + int i = 0; + + if (!ast_for_dictelement(c, n, &i, &key, &value)) + return NULL; + assert(key); + assert(NCH(n) - i >= 1); + + comps = ast_for_comprehension(c, CHILD(n, i)); + if (!comps) + return NULL; + + return DictComp(key, value, comps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +static expr_ty +ast_for_dictdisplay(struct compiling *c, const node *n) +{ + int i; + int j; + int size; + asdl_seq *keys, *values; + + size = (NCH(n) + 1) / 3; /* +1 in case no trailing comma */ + keys = _Py_asdl_seq_new(size, c->c_arena); + if (!keys) + return NULL; + + values = _Py_asdl_seq_new(size, c->c_arena); + if (!values) + return NULL; + + j = 0; + for (i = 0; i < NCH(n); i++) { + expr_ty key, value; + + if (!ast_for_dictelement(c, n, &i, &key, &value)) + return NULL; + asdl_seq_SET(keys, j, key); + asdl_seq_SET(values, j, value); + + j++; + } + keys->size = j; + values->size = j; + return Dict(keys, values, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +static expr_ty +ast_for_genexp(struct compiling *c, const node *n) +{ + assert(TYPE(n) == (testlist_comp) || TYPE(n) == (argument)); + return ast_for_itercomp(c, n, COMP_GENEXP); +} + +static expr_ty +ast_for_listcomp(struct compiling *c, const node *n) +{ + assert(TYPE(n) == (testlist_comp)); + return ast_for_itercomp(c, n, COMP_LISTCOMP); +} + +static expr_ty +ast_for_setcomp(struct compiling *c, const node *n) +{ + assert(TYPE(n) == (dictorsetmaker)); + return ast_for_itercomp(c, n, COMP_SETCOMP); +} + +static expr_ty +ast_for_setdisplay(struct compiling *c, const node *n) +{ + int i; + int size; + asdl_seq *elts; + + assert(TYPE(n) == (dictorsetmaker)); + size = (NCH(n) + 1) / 2; /* +1 in case no trailing comma */ + elts = _Py_asdl_seq_new(size, c->c_arena); + if (!elts) + return NULL; + for (i = 0; i < NCH(n); i += 2) { + expr_ty expression; + expression = ast_for_expr(c, CHILD(n, i)); + if (!expression) + return NULL; + asdl_seq_SET(elts, i / 2, expression); + } + return Set(elts, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +static expr_ty +ast_for_atom(struct compiling *c, const node *n) +{ + /* atom: '(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' + | '{' [dictmaker|testlist_comp] '}' | NAME | NUMBER | STRING+ + | '...' | 'None' | 'True' | 'False' + */ + node *ch = CHILD(n, 0); + + switch (TYPE(ch)) { + case NAME: { + PyObject *name; + const char *s = STR(ch); + size_t len = strlen(s); + if (len >= 4 && len <= 5) { + if (!strcmp(s, "None")) + return Constant(Py_None, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + if (!strcmp(s, "True")) + return Constant(Py_True, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + if (!strcmp(s, "False")) + return Constant(Py_False, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + name = new_identifier(s, c); + if (!name) + return NULL; + /* All names start in Load context, but may later be changed. */ + return Name(name, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + case STRING: { + expr_ty str = parsestrplus(c, n); + if (!str) { + const char *errtype = NULL; + if (PyErr_ExceptionMatches(PyExc_UnicodeError)) + errtype = "unicode error"; + else if (PyErr_ExceptionMatches(PyExc_ValueError)) + errtype = "value error"; + if (errtype) { + PyObject *type, *value, *tback, *errstr; + PyErr_Fetch(&type, &value, &tback); + errstr = PyObject_Str(value); + if (errstr) { + ast_error(c, n, "(%s) %U", errtype, errstr); + Py_DECREF(errstr); + } + else { + PyErr_Clear(); + ast_error(c, n, "(%s) unknown error", errtype); + } + Py_DECREF(type); + Py_XDECREF(value); + Py_XDECREF(tback); + } + return NULL; + } + return str; + } + case NUMBER: { + PyObject *pynum; + /* Underscores in numeric literals are only allowed in Python 3.6 or greater */ + /* Check for underscores here rather than in parse_number so we can report a line number on error */ + if (c->c_feature_version < 6 && strchr(STR(ch), '_') != NULL) { + ast_error(c, ch, + "Underscores in numeric literals are only supported in Python 3.6 and greater"); + return NULL; + } + pynum = parsenumber(c, STR(ch)); + if (!pynum) + return NULL; + + if (PyArena_AddPyObject(c->c_arena, pynum) < 0) { + Py_DECREF(pynum); + return NULL; + } + return Constant(pynum, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + case ELLIPSIS: /* Ellipsis */ + return Constant(Py_Ellipsis, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + case LPAR: /* some parenthesized expressions */ + ch = CHILD(n, 1); + + if (TYPE(ch) == RPAR) + return Tuple(NULL, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + + if (TYPE(ch) == yield_expr) + return ast_for_expr(c, ch); + + /* testlist_comp: test ( comp_for | (',' test)* [','] ) */ + if (NCH(ch) == 1) { + return ast_for_testlist(c, ch); + } + + if (TYPE(CHILD(ch, 1)) == comp_for) { + return copy_location(ast_for_genexp(c, ch), n, n); + } + else { + return copy_location(ast_for_testlist(c, ch), n, n); + } + case LSQB: /* list (or list comprehension) */ + ch = CHILD(n, 1); + + if (TYPE(ch) == RSQB) + return List(NULL, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + + REQ(ch, testlist_comp); + if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { + asdl_seq *elts = seq_for_testlist(c, ch); + if (!elts) + return NULL; + + return List(elts, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else { + return copy_location(ast_for_listcomp(c, ch), n, n); + } + case LBRACE: { + /* dictorsetmaker: ( ((test ':' test | '**' test) + * (comp_for | (',' (test ':' test | '**' test))* [','])) | + * ((test | '*' test) + * (comp_for | (',' (test | '*' test))* [','])) ) */ + expr_ty res; + ch = CHILD(n, 1); + if (TYPE(ch) == RBRACE) { + /* It's an empty dict. */ + return Dict(NULL, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else { + int is_dict = (TYPE(CHILD(ch, 0)) == DOUBLESTAR); + if (NCH(ch) == 1 || + (NCH(ch) > 1 && + TYPE(CHILD(ch, 1)) == COMMA)) { + /* It's a set display. */ + res = ast_for_setdisplay(c, ch); + } + else if (NCH(ch) > 1 && + TYPE(CHILD(ch, 1)) == comp_for) { + /* It's a set comprehension. */ + res = ast_for_setcomp(c, ch); + } + else if (NCH(ch) > 3 - is_dict && + TYPE(CHILD(ch, 3 - is_dict)) == comp_for) { + /* It's a dictionary comprehension. */ + if (is_dict) { + ast_error(c, n, + "dict unpacking cannot be used in dict comprehension"); + return NULL; + } + res = ast_for_dictcomp(c, ch); + } + else { + /* It's a dictionary display. */ + res = ast_for_dictdisplay(c, ch); + } + return copy_location(res, n, n); + } + } + default: + PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch)); + return NULL; + } +} + +static slice_ty +ast_for_slice(struct compiling *c, const node *n) +{ + node *ch; + expr_ty lower = NULL, upper = NULL, step = NULL; + + REQ(n, subscript); + + /* + subscript: test | [test] ':' [test] [sliceop] + sliceop: ':' [test] + */ + ch = CHILD(n, 0); + if (NCH(n) == 1 && TYPE(ch) == test) { + /* 'step' variable hold no significance in terms of being used over + other vars */ + step = ast_for_expr(c, ch); + if (!step) + return NULL; + + return Index(step, c->c_arena); + } + + if (TYPE(ch) == test) { + lower = ast_for_expr(c, ch); + if (!lower) + return NULL; + } + + /* If there's an upper bound it's in the second or third position. */ + if (TYPE(ch) == COLON) { + if (NCH(n) > 1) { + node *n2 = CHILD(n, 1); + + if (TYPE(n2) == test) { + upper = ast_for_expr(c, n2); + if (!upper) + return NULL; + } + } + } else if (NCH(n) > 2) { + node *n2 = CHILD(n, 2); + + if (TYPE(n2) == test) { + upper = ast_for_expr(c, n2); + if (!upper) + return NULL; + } + } + + ch = CHILD(n, NCH(n) - 1); + if (TYPE(ch) == sliceop) { + if (NCH(ch) != 1) { + ch = CHILD(ch, 1); + if (TYPE(ch) == test) { + step = ast_for_expr(c, ch); + if (!step) + return NULL; + } + } + } + + return Slice(lower, upper, step, c->c_arena); +} + +static expr_ty +ast_for_binop(struct compiling *c, const node *n) +{ + /* Must account for a sequence of expressions. + How should A op B op C by represented? + BinOp(BinOp(A, op, B), op, C). + */ + + int i, nops; + expr_ty expr1, expr2, result; + operator_ty newoperator; + + expr1 = ast_for_expr(c, CHILD(n, 0)); + if (!expr1) + return NULL; + + expr2 = ast_for_expr(c, CHILD(n, 2)); + if (!expr2) + return NULL; + + newoperator = get_operator(c, CHILD(n, 1)); + if (!newoperator) + return NULL; + + result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, + CHILD(n, 2)->n_end_lineno, CHILD(n, 2)->n_end_col_offset, + c->c_arena); + if (!result) + return NULL; + + nops = (NCH(n) - 1) / 2; + for (i = 1; i < nops; i++) { + expr_ty tmp_result, tmp; + const node* next_oper = CHILD(n, i * 2 + 1); + + newoperator = get_operator(c, next_oper); + if (!newoperator) + return NULL; + + tmp = ast_for_expr(c, CHILD(n, i * 2 + 2)); + if (!tmp) + return NULL; + + tmp_result = BinOp(result, newoperator, tmp, + LINENO(n), n->n_col_offset, + CHILD(n, i * 2 + 2)->n_end_lineno, + CHILD(n, i * 2 + 2)->n_end_col_offset, + c->c_arena); + if (!tmp_result) + return NULL; + result = tmp_result; + } + return result; +} + +static expr_ty +ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr, const node *start) +{ + /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME + subscriptlist: subscript (',' subscript)* [','] + subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] + */ + const node *n_copy = n; + REQ(n, trailer); + if (TYPE(CHILD(n, 0)) == LPAR) { + if (NCH(n) == 2) + return Call(left_expr, NULL, NULL, LINENO(start), start->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + else + return ast_for_call(c, CHILD(n, 1), left_expr, + start, CHILD(n, 0), CHILD(n, 2)); + } + else if (TYPE(CHILD(n, 0)) == DOT) { + PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1)); + if (!attr_id) + return NULL; + return Attribute(left_expr, attr_id, Load, + LINENO(start), start->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else { + REQ(CHILD(n, 0), LSQB); + REQ(CHILD(n, 2), RSQB); + n = CHILD(n, 1); + if (NCH(n) == 1) { + slice_ty slc = ast_for_slice(c, CHILD(n, 0)); + if (!slc) + return NULL; + return Subscript(left_expr, slc, Load, LINENO(start), start->n_col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, + c->c_arena); + } + else { + /* The grammar is ambiguous here. The ambiguity is resolved + by treating the sequence as a tuple literal if there are + no slice features. + */ + Py_ssize_t j; + slice_ty slc; + expr_ty e; + int simple = 1; + asdl_seq *slices, *elts; + slices = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); + if (!slices) + return NULL; + for (j = 0; j < NCH(n); j += 2) { + slc = ast_for_slice(c, CHILD(n, j)); + if (!slc) + return NULL; + if (slc->kind != Index_kind) + simple = 0; + asdl_seq_SET(slices, j / 2, slc); + } + if (!simple) { + return Subscript(left_expr, ExtSlice(slices, c->c_arena), + Load, LINENO(start), start->n_col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); + } + /* extract Index values and put them in a Tuple */ + elts = _Py_asdl_seq_new(asdl_seq_LEN(slices), c->c_arena); + if (!elts) + return NULL; + for (j = 0; j < asdl_seq_LEN(slices); ++j) { + slc = (slice_ty)asdl_seq_GET(slices, j); + assert(slc->kind == Index_kind && slc->v.Index.value); + asdl_seq_SET(elts, j, slc->v.Index.value); + } + e = Tuple(elts, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + if (!e) + return NULL; + return Subscript(left_expr, Index(e, c->c_arena), + Load, LINENO(start), start->n_col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, c->c_arena); + } + } +} + +static expr_ty +ast_for_factor(struct compiling *c, const node *n) +{ + expr_ty expression; + + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + + switch (TYPE(CHILD(n, 0))) { + case PLUS: + return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + c->c_arena); + case MINUS: + return UnaryOp(USub, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + c->c_arena); + case TILDE: + return UnaryOp(Invert, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + c->c_arena); + } + PyErr_Format(PyExc_SystemError, "unhandled factor: %d", + TYPE(CHILD(n, 0))); + return NULL; +} + +static expr_ty +ast_for_atom_expr(struct compiling *c, const node *n) +{ + int i, nch, start = 0; + expr_ty e; + + REQ(n, atom_expr); + nch = NCH(n); + + if (TYPE(CHILD(n, 0)) == AWAIT) { + if (c->c_feature_version < 5) { + ast_error(c, n, + "Await expressions are only supported in Python 3.5 and greater"); + return NULL; + } + start = 1; + assert(nch > 1); + } + + e = ast_for_atom(c, CHILD(n, start)); + if (!e) + return NULL; + if (nch == 1) + return e; + if (start && nch == 2) { + return Await(e, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + + for (i = start + 1; i < nch; i++) { + node *ch = CHILD(n, i); + if (TYPE(ch) != trailer) + break; + e = ast_for_trailer(c, ch, e, CHILD(n, start)); + if (!e) + return NULL; + } + + if (start) { + /* there was an 'await' */ + return Await(e, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else { + return e; + } +} + +static expr_ty +ast_for_power(struct compiling *c, const node *n) +{ + /* power: atom trailer* ('**' factor)* + */ + expr_ty e; + REQ(n, power); + e = ast_for_atom_expr(c, CHILD(n, 0)); + if (!e) + return NULL; + if (NCH(n) == 1) + return e; + if (TYPE(CHILD(n, NCH(n) - 1)) == factor) { + expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1)); + if (!f) + return NULL; + e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + return e; +} + +static expr_ty +ast_for_starred(struct compiling *c, const node *n) +{ + expr_ty tmp; + REQ(n, star_expr); + + tmp = ast_for_expr(c, CHILD(n, 1)); + if (!tmp) + return NULL; + + /* The Load context is changed later. */ + return Starred(tmp, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + + +/* Do not name a variable 'expr'! Will cause a compile error. +*/ + +static expr_ty +ast_for_expr(struct compiling *c, const node *n) +{ + /* handle the full range of simple expressions + namedexpr_test: test [':=' test] + test: or_test ['if' or_test 'else' test] | lambdef + test_nocond: or_test | lambdef_nocond + or_test: and_test ('or' and_test)* + and_test: not_test ('and' not_test)* + not_test: 'not' not_test | comparison + comparison: expr (comp_op expr)* + expr: xor_expr ('|' xor_expr)* + xor_expr: and_expr ('^' and_expr)* + and_expr: shift_expr ('&' shift_expr)* + shift_expr: arith_expr (('<<'|'>>') arith_expr)* + arith_expr: term (('+'|'-') term)* + term: factor (('*'|'@'|'/'|'%'|'//') factor)* + factor: ('+'|'-'|'~') factor | power + power: atom_expr ['**' factor] + atom_expr: [AWAIT] atom trailer* + yield_expr: 'yield' [yield_arg] + */ + + asdl_seq *seq; + int i; + + loop: + switch (TYPE(n)) { + case namedexpr_test: + if (NCH(n) == 3) + return ast_for_namedexpr(c, n); + /* Fallthrough */ + case test: + case test_nocond: + if (TYPE(CHILD(n, 0)) == lambdef || + TYPE(CHILD(n, 0)) == lambdef_nocond) + return ast_for_lambdef(c, CHILD(n, 0)); + else if (NCH(n) > 1) + return ast_for_ifexpr(c, n); + /* Fallthrough */ + case or_test: + case and_test: + if (NCH(n) == 1) { + n = CHILD(n, 0); + goto loop; + } + seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); + if (!seq) + return NULL; + for (i = 0; i < NCH(n); i += 2) { + expr_ty e = ast_for_expr(c, CHILD(n, i)); + if (!e) + return NULL; + asdl_seq_SET(seq, i / 2, e); + } + if (!strcmp(STR(CHILD(n, 1)), "and")) + return BoolOp(And, seq, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + c->c_arena); + assert(!strcmp(STR(CHILD(n, 1)), "or")); + return BoolOp(Or, seq, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + case not_test: + if (NCH(n) == 1) { + n = CHILD(n, 0); + goto loop; + } + else { + expr_ty expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + + return UnaryOp(Not, expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, + c->c_arena); + } + case comparison: + if (NCH(n) == 1) { + n = CHILD(n, 0); + goto loop; + } + else { + expr_ty expression; + asdl_int_seq *ops; + asdl_seq *cmps; + ops = _Py_asdl_int_seq_new(NCH(n) / 2, c->c_arena); + if (!ops) + return NULL; + cmps = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena); + if (!cmps) { + return NULL; + } + for (i = 1; i < NCH(n); i += 2) { + cmpop_ty newoperator; + + newoperator = ast_for_comp_op(c, CHILD(n, i)); + if (!newoperator) { + return NULL; + } + + expression = ast_for_expr(c, CHILD(n, i + 1)); + if (!expression) { + return NULL; + } + + asdl_seq_SET(ops, i / 2, newoperator); + asdl_seq_SET(cmps, i / 2, expression); + } + expression = ast_for_expr(c, CHILD(n, 0)); + if (!expression) { + return NULL; + } + + return Compare(expression, ops, cmps, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + + case star_expr: + return ast_for_starred(c, n); + /* The next five cases all handle BinOps. The main body of code + is the same in each case, but the switch turned inside out to + reuse the code for each type of operator. + */ + case expr: + case xor_expr: + case and_expr: + case shift_expr: + case arith_expr: + case term: + if (NCH(n) == 1) { + n = CHILD(n, 0); + goto loop; + } + return ast_for_binop(c, n); + case yield_expr: { + node *an = NULL; + node *en = NULL; + int is_from = 0; + expr_ty exp = NULL; + if (NCH(n) > 1) + an = CHILD(n, 1); /* yield_arg */ + if (an) { + en = CHILD(an, NCH(an) - 1); + if (NCH(an) == 2) { + is_from = 1; + exp = ast_for_expr(c, en); + } + else + exp = ast_for_testlist(c, en); + if (!exp) + return NULL; + } + if (is_from) + return YieldFrom(exp, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + return Yield(exp, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + case factor: + if (NCH(n) == 1) { + n = CHILD(n, 0); + goto loop; + } + return ast_for_factor(c, n); + case power: + return ast_for_power(c, n); + default: + PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n)); + return NULL; + } + /* should never get here unless if error is set */ + return NULL; +} + +static expr_ty +ast_for_call(struct compiling *c, const node *n, expr_ty func, + const node *start, const node *maybegenbeg, const node *closepar) +{ + /* + arglist: argument (',' argument)* [','] + argument: ( test [comp_for] | '*' test | test '=' test | '**' test ) + */ + + int i, nargs, nkeywords; + int ndoublestars; + asdl_seq *args; + asdl_seq *keywords; + + REQ(n, arglist); + + nargs = 0; + nkeywords = 0; + for (i = 0; i < NCH(n); i++) { + node *ch = CHILD(n, i); + if (TYPE(ch) == argument) { + if (NCH(ch) == 1) + nargs++; + else if (TYPE(CHILD(ch, 1)) == comp_for) { + nargs++; + if (!maybegenbeg) { + ast_error(c, ch, "invalid syntax"); + return NULL; + } + if (NCH(n) > 1) { + ast_error(c, ch, "Generator expression must be parenthesized"); + return NULL; + } + } + else if (TYPE(CHILD(ch, 0)) == STAR) + nargs++; + else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) { + nargs++; + } + else + /* TYPE(CHILD(ch, 0)) == DOUBLESTAR or keyword argument */ + nkeywords++; + } + } + + args = _Py_asdl_seq_new(nargs, c->c_arena); + if (!args) + return NULL; + keywords = _Py_asdl_seq_new(nkeywords, c->c_arena); + if (!keywords) + return NULL; + + nargs = 0; /* positional arguments + iterable argument unpackings */ + nkeywords = 0; /* keyword arguments + keyword argument unpackings */ + ndoublestars = 0; /* just keyword argument unpackings */ + for (i = 0; i < NCH(n); i++) { + node *ch = CHILD(n, i); + if (TYPE(ch) == argument) { + expr_ty e; + node *chch = CHILD(ch, 0); + if (NCH(ch) == 1) { + /* a positional argument */ + if (nkeywords) { + if (ndoublestars) { + ast_error(c, chch, + "positional argument follows " + "keyword argument unpacking"); + } + else { + ast_error(c, chch, + "positional argument follows " + "keyword argument"); + } + return NULL; + } + e = ast_for_expr(c, chch); + if (!e) + return NULL; + asdl_seq_SET(args, nargs++, e); + } + else if (TYPE(chch) == STAR) { + /* an iterable argument unpacking */ + expr_ty starred; + if (ndoublestars) { + ast_error(c, chch, + "iterable argument unpacking follows " + "keyword argument unpacking"); + return NULL; + } + e = ast_for_expr(c, CHILD(ch, 1)); + if (!e) + return NULL; + starred = Starred(e, Load, LINENO(chch), + chch->n_col_offset, + e->end_lineno, e->end_col_offset, + c->c_arena); + if (!starred) + return NULL; + asdl_seq_SET(args, nargs++, starred); + + } + else if (TYPE(chch) == DOUBLESTAR) { + /* a keyword argument unpacking */ + keyword_ty kw; + i++; + e = ast_for_expr(c, CHILD(ch, 1)); + if (!e) + return NULL; + kw = keyword(NULL, e, c->c_arena); + asdl_seq_SET(keywords, nkeywords++, kw); + ndoublestars++; + } + else if (TYPE(CHILD(ch, 1)) == comp_for) { + /* the lone generator expression */ + e = copy_location(ast_for_genexp(c, ch), maybegenbeg, closepar); + if (!e) + return NULL; + asdl_seq_SET(args, nargs++, e); + } + else if (TYPE(CHILD(ch, 1)) == COLONEQUAL) { + /* treat colon equal as positional argument */ + if (nkeywords) { + if (ndoublestars) { + ast_error(c, chch, + "positional argument follows " + "keyword argument unpacking"); + } + else { + ast_error(c, chch, + "positional argument follows " + "keyword argument"); + } + return NULL; + } + e = ast_for_namedexpr(c, ch); + if (!e) + return NULL; + asdl_seq_SET(args, nargs++, e); + } + else { + /* a keyword argument */ + keyword_ty kw; + identifier key, tmp; + int k; + + // To remain LL(1), the grammar accepts any test (basically, any + // expression) in the keyword slot of a call site. So, we need + // to manually enforce that the keyword is a NAME here. + static const int name_tree[] = { + test, + or_test, + and_test, + not_test, + comparison, + expr, + xor_expr, + and_expr, + shift_expr, + arith_expr, + term, + factor, + power, + atom_expr, + atom, + 0, + }; + node *expr_node = chch; + for (int i = 0; name_tree[i]; i++) { + if (TYPE(expr_node) != name_tree[i]) + break; + if (NCH(expr_node) != 1) + break; + expr_node = CHILD(expr_node, 0); + } + if (TYPE(expr_node) != NAME) { + ast_error(c, chch, + "expression cannot contain assignment, " + "perhaps you meant \"==\"?"); + return NULL; + } + key = new_identifier(STR(expr_node), c); + if (key == NULL) { + return NULL; + } + if (forbidden_name(c, key, chch, 1)) { + return NULL; + } + for (k = 0; k < nkeywords; k++) { + tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg; + if (tmp && !PyUnicode_Compare(tmp, key)) { + ast_error(c, chch, + "keyword argument repeated"); + return NULL; + } + } + e = ast_for_expr(c, CHILD(ch, 2)); + if (!e) + return NULL; + kw = keyword(key, e, c->c_arena); + if (!kw) + return NULL; + asdl_seq_SET(keywords, nkeywords++, kw); + } + } + } + + return Call(func, args, keywords, LINENO(start), start->n_col_offset, + closepar->n_end_lineno, closepar->n_end_col_offset, c->c_arena); +} + +static expr_ty +ast_for_testlist(struct compiling *c, const node* n) +{ + /* testlist_comp: test (comp_for | (',' test)* [',']) */ + /* testlist: test (',' test)* [','] */ + assert(NCH(n) > 0); + if (TYPE(n) == testlist_comp) { + if (NCH(n) > 1) + assert(TYPE(CHILD(n, 1)) != comp_for); + } + else { + assert(TYPE(n) == testlist || + TYPE(n) == testlist_star_expr); + } + if (NCH(n) == 1) + return ast_for_expr(c, CHILD(n, 0)); + else { + asdl_seq *tmp = seq_for_testlist(c, n); + if (!tmp) + return NULL; + return Tuple(tmp, Load, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } +} + +static stmt_ty +ast_for_expr_stmt(struct compiling *c, const node *n) +{ + REQ(n, expr_stmt); + /* expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | + [('=' (yield_expr|testlist_star_expr))+ [TYPE_COMMENT]] ) + annassign: ':' test ['=' (yield_expr|testlist)] + testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] + augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | + '<<=' | '>>=' | '**=' | '//=') + test: ... here starts the operator precedence dance + */ + int num = NCH(n); + + if (num == 1) { + expr_ty e = ast_for_testlist(c, CHILD(n, 0)); + if (!e) + return NULL; + + return Expr(e, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else if (TYPE(CHILD(n, 1)) == augassign) { + expr_ty expr1, expr2; + operator_ty newoperator; + node *ch = CHILD(n, 0); + + expr1 = ast_for_testlist(c, ch); + if (!expr1) + return NULL; + if(!set_context(c, expr1, Store, ch)) + return NULL; + /* set_context checks that most expressions are not the left side. + Augmented assignments can only have a name, a subscript, or an + attribute on the left, though, so we have to explicitly check for + those. */ + switch (expr1->kind) { + case Name_kind: + case Attribute_kind: + case Subscript_kind: + break; + default: + ast_error(c, ch, "illegal expression for augmented assignment"); + return NULL; + } + + ch = CHILD(n, 2); + if (TYPE(ch) == testlist) + expr2 = ast_for_testlist(c, ch); + else + expr2 = ast_for_expr(c, ch); + if (!expr2) + return NULL; + + newoperator = ast_for_augassign(c, CHILD(n, 1)); + if (!newoperator) + return NULL; + + return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else if (TYPE(CHILD(n, 1)) == annassign) { + expr_ty expr1, expr2, expr3; + node *ch = CHILD(n, 0); + node *deep, *ann = CHILD(n, 1); + int simple = 1; + + /* AnnAssigns are only allowed in Python 3.6 or greater */ + if (c->c_feature_version < 6) { + ast_error(c, ch, + "Variable annotation syntax is only supported in Python 3.6 and greater"); + return NULL; + } + + /* we keep track of parens to qualify (x) as expression not name */ + deep = ch; + while (NCH(deep) == 1) { + deep = CHILD(deep, 0); + } + if (NCH(deep) > 0 && TYPE(CHILD(deep, 0)) == LPAR) { + simple = 0; + } + expr1 = ast_for_testlist(c, ch); + if (!expr1) { + return NULL; + } + switch (expr1->kind) { + case Name_kind: + if (forbidden_name(c, expr1->v.Name.id, n, 0)) { + return NULL; + } + expr1->v.Name.ctx = Store; + break; + case Attribute_kind: + if (forbidden_name(c, expr1->v.Attribute.attr, n, 1)) { + return NULL; + } + expr1->v.Attribute.ctx = Store; + break; + case Subscript_kind: + expr1->v.Subscript.ctx = Store; + break; + case List_kind: + ast_error(c, ch, + "only single target (not list) can be annotated"); + return NULL; + case Tuple_kind: + ast_error(c, ch, + "only single target (not tuple) can be annotated"); + return NULL; + default: + ast_error(c, ch, + "illegal target for annotation"); + return NULL; + } + + if (expr1->kind != Name_kind) { + simple = 0; + } + ch = CHILD(ann, 1); + expr2 = ast_for_expr(c, ch); + if (!expr2) { + return NULL; + } + if (NCH(ann) == 2) { + return AnnAssign(expr1, expr2, NULL, simple, + LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else { + ch = CHILD(ann, 3); + if (TYPE(ch) == testlist_star_expr) { + expr3 = ast_for_testlist(c, ch); + } + else { + expr3 = ast_for_expr(c, ch); + } + if (!expr3) { + return NULL; + } + return AnnAssign(expr1, expr2, expr3, simple, + LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + } + else { + int i, nch_minus_type, has_type_comment; + asdl_seq *targets; + node *value; + expr_ty expression; + string type_comment; + + /* a normal assignment */ + REQ(CHILD(n, 1), EQUAL); + + has_type_comment = TYPE(CHILD(n, num - 1)) == TYPE_COMMENT; + nch_minus_type = num - has_type_comment; + + targets = _Py_asdl_seq_new(nch_minus_type / 2, c->c_arena); + if (!targets) + return NULL; + for (i = 0; i < nch_minus_type - 2; i += 2) { + expr_ty e; + node *ch = CHILD(n, i); + if (TYPE(ch) == yield_expr) { + ast_error(c, ch, "assignment to yield expression not possible"); + return NULL; + } + e = ast_for_testlist(c, ch); + if (!e) + return NULL; + + /* set context to assign */ + if (!set_context(c, e, Store, CHILD(n, i))) + return NULL; + + asdl_seq_SET(targets, i / 2, e); + } + value = CHILD(n, nch_minus_type - 1); + if (TYPE(value) == testlist_star_expr) + expression = ast_for_testlist(c, value); + else + expression = ast_for_expr(c, value); + if (!expression) + return NULL; + if (has_type_comment) { + type_comment = NEW_TYPE_COMMENT(CHILD(n, nch_minus_type)); + if (!type_comment) + return NULL; + } + else + type_comment = NULL; + return Assign(targets, expression, type_comment, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } +} + + +static asdl_seq * +ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context) +{ + asdl_seq *seq; + int i; + expr_ty e; + + REQ(n, exprlist); + + seq = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); + if (!seq) + return NULL; + for (i = 0; i < NCH(n); i += 2) { + e = ast_for_expr(c, CHILD(n, i)); + if (!e) + return NULL; + asdl_seq_SET(seq, i / 2, e); + if (context && !set_context(c, e, context, CHILD(n, i))) + return NULL; + } + return seq; +} + +static stmt_ty +ast_for_del_stmt(struct compiling *c, const node *n) +{ + asdl_seq *expr_list; + + /* del_stmt: 'del' exprlist */ + REQ(n, del_stmt); + + expr_list = ast_for_exprlist(c, CHILD(n, 1), Del); + if (!expr_list) + return NULL; + return Delete(expr_list, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +static stmt_ty +ast_for_flow_stmt(struct compiling *c, const node *n) +{ + /* + flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt + | yield_stmt + break_stmt: 'break' + continue_stmt: 'continue' + return_stmt: 'return' [testlist] + yield_stmt: yield_expr + yield_expr: 'yield' testlist | 'yield' 'from' test + raise_stmt: 'raise' [test [',' test [',' test]]] + */ + node *ch; + + REQ(n, flow_stmt); + ch = CHILD(n, 0); + switch (TYPE(ch)) { + case break_stmt: + return Break(LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + case continue_stmt: + return Continue(LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + case yield_stmt: { /* will reduce to yield_expr */ + expr_ty exp = ast_for_expr(c, CHILD(ch, 0)); + if (!exp) + return NULL; + return Expr(exp, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + case return_stmt: + if (NCH(ch) == 1) + return Return(NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + else { + expr_ty expression = ast_for_testlist(c, CHILD(ch, 1)); + if (!expression) + return NULL; + return Return(expression, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + case raise_stmt: + if (NCH(ch) == 1) + return Raise(NULL, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + else if (NCH(ch) >= 2) { + expr_ty cause = NULL; + expr_ty expression = ast_for_expr(c, CHILD(ch, 1)); + if (!expression) + return NULL; + if (NCH(ch) == 4) { + cause = ast_for_expr(c, CHILD(ch, 3)); + if (!cause) + return NULL; + } + return Raise(expression, cause, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + /* fall through */ + default: + PyErr_Format(PyExc_SystemError, + "unexpected flow_stmt: %d", TYPE(ch)); + return NULL; + } +} + +static alias_ty +alias_for_import_name(struct compiling *c, const node *n, int store) +{ + /* + import_as_name: NAME ['as' NAME] + dotted_as_name: dotted_name ['as' NAME] + dotted_name: NAME ('.' NAME)* + */ + identifier str, name; + + loop: + switch (TYPE(n)) { + case import_as_name: { + node *name_node = CHILD(n, 0); + str = NULL; + name = NEW_IDENTIFIER(name_node); + if (!name) + return NULL; + if (NCH(n) == 3) { + node *str_node = CHILD(n, 2); + str = NEW_IDENTIFIER(str_node); + if (!str) + return NULL; + if (store && forbidden_name(c, str, str_node, 0)) + return NULL; + } + else { + if (forbidden_name(c, name, name_node, 0)) + return NULL; + } + return alias(name, str, c->c_arena); + } + case dotted_as_name: + if (NCH(n) == 1) { + n = CHILD(n, 0); + goto loop; + } + else { + node *asname_node = CHILD(n, 2); + alias_ty a = alias_for_import_name(c, CHILD(n, 0), 0); + if (!a) + return NULL; + assert(!a->asname); + a->asname = NEW_IDENTIFIER(asname_node); + if (!a->asname) + return NULL; + if (forbidden_name(c, a->asname, asname_node, 0)) + return NULL; + return a; + } + case dotted_name: + if (NCH(n) == 1) { + node *name_node = CHILD(n, 0); + name = NEW_IDENTIFIER(name_node); + if (!name) + return NULL; + if (store && forbidden_name(c, name, name_node, 0)) + return NULL; + return alias(name, NULL, c->c_arena); + } + else { + /* Create a string of the form "a.b.c" */ + int i; + size_t len; + char *s; + PyObject *uni; + + len = 0; + for (i = 0; i < NCH(n); i += 2) + /* length of string plus one for the dot */ + len += strlen(STR(CHILD(n, i))) + 1; + len--; /* the last name doesn't have a dot */ + str = PyBytes_FromStringAndSize(NULL, len); + if (!str) + return NULL; + s = PyBytes_AS_STRING(str); + if (!s) + return NULL; + for (i = 0; i < NCH(n); i += 2) { + char *sch = STR(CHILD(n, i)); + strcpy(s, STR(CHILD(n, i))); + s += strlen(sch); + *s++ = '.'; + } + --s; + *s = '\0'; + uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), + PyBytes_GET_SIZE(str), + NULL); + Py_DECREF(str); + if (!uni) + return NULL; + str = uni; + PyUnicode_InternInPlace(&str); + if (PyArena_AddPyObject(c->c_arena, str) < 0) { + Py_DECREF(str); + return NULL; + } + return alias(str, NULL, c->c_arena); + } + case STAR: + str = PyUnicode_InternFromString("*"); + if (!str) + return NULL; + if (PyArena_AddPyObject(c->c_arena, str) < 0) { + Py_DECREF(str); + return NULL; + } + return alias(str, NULL, c->c_arena); + default: + PyErr_Format(PyExc_SystemError, + "unexpected import name: %d", TYPE(n)); + return NULL; + } + + PyErr_SetString(PyExc_SystemError, "unhandled import name condition"); + return NULL; +} + +static stmt_ty +ast_for_import_stmt(struct compiling *c, const node *n) +{ + /* + import_stmt: import_name | import_from + import_name: 'import' dotted_as_names + import_from: 'from' (('.' | '...')* dotted_name | ('.' | '...')+) + 'import' ('*' | '(' import_as_names ')' | import_as_names) + */ + int lineno; + int col_offset; + int i; + asdl_seq *aliases; + + REQ(n, import_stmt); + lineno = LINENO(n); + col_offset = n->n_col_offset; + n = CHILD(n, 0); + if (TYPE(n) == import_name) { + n = CHILD(n, 1); + REQ(n, dotted_as_names); + aliases = _Py_asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); + if (!aliases) + return NULL; + for (i = 0; i < NCH(n); i += 2) { + alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); + if (!import_alias) + return NULL; + asdl_seq_SET(aliases, i / 2, import_alias); + } + // Even though n is modified above, the end position is not changed + return Import(aliases, lineno, col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else if (TYPE(n) == import_from) { + int n_children; + int idx, ndots = 0; + const node *n_copy = n; + alias_ty mod = NULL; + identifier modname = NULL; + + /* Count the number of dots (for relative imports) and check for the + optional module name */ + for (idx = 1; idx < NCH(n); idx++) { + if (TYPE(CHILD(n, idx)) == dotted_name) { + mod = alias_for_import_name(c, CHILD(n, idx), 0); + if (!mod) + return NULL; + idx++; + break; + } else if (TYPE(CHILD(n, idx)) == ELLIPSIS) { + /* three consecutive dots are tokenized as one ELLIPSIS */ + ndots += 3; + continue; + } else if (TYPE(CHILD(n, idx)) != DOT) { + break; + } + ndots++; + } + idx++; /* skip over the 'import' keyword */ + switch (TYPE(CHILD(n, idx))) { + case STAR: + /* from ... import * */ + n = CHILD(n, idx); + n_children = 1; + break; + case LPAR: + /* from ... import (x, y, z) */ + n = CHILD(n, idx + 1); + n_children = NCH(n); + break; + case import_as_names: + /* from ... import x, y, z */ + n = CHILD(n, idx); + n_children = NCH(n); + if (n_children % 2 == 0) { + ast_error(c, n, + "trailing comma not allowed without" + " surrounding parentheses"); + return NULL; + } + break; + default: + ast_error(c, n, "Unexpected node-type in from-import"); + return NULL; + } + + aliases = _Py_asdl_seq_new((n_children + 1) / 2, c->c_arena); + if (!aliases) + return NULL; + + /* handle "from ... import *" special b/c there's no children */ + if (TYPE(n) == STAR) { + alias_ty import_alias = alias_for_import_name(c, n, 1); + if (!import_alias) + return NULL; + asdl_seq_SET(aliases, 0, import_alias); + } + else { + for (i = 0; i < NCH(n); i += 2) { + alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); + if (!import_alias) + return NULL; + asdl_seq_SET(aliases, i / 2, import_alias); + } + } + if (mod != NULL) + modname = mod->name; + return ImportFrom(modname, aliases, ndots, lineno, col_offset, + n_copy->n_end_lineno, n_copy->n_end_col_offset, + c->c_arena); + } + PyErr_Format(PyExc_SystemError, + "unknown import statement: starts with command '%s'", + STR(CHILD(n, 0))); + return NULL; +} + +static stmt_ty +ast_for_global_stmt(struct compiling *c, const node *n) +{ + /* global_stmt: 'global' NAME (',' NAME)* */ + identifier name; + asdl_seq *s; + int i; + + REQ(n, global_stmt); + s = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena); + if (!s) + return NULL; + for (i = 1; i < NCH(n); i += 2) { + name = NEW_IDENTIFIER(CHILD(n, i)); + if (!name) + return NULL; + asdl_seq_SET(s, i / 2, name); + } + return Global(s, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +static stmt_ty +ast_for_nonlocal_stmt(struct compiling *c, const node *n) +{ + /* nonlocal_stmt: 'nonlocal' NAME (',' NAME)* */ + identifier name; + asdl_seq *s; + int i; + + REQ(n, nonlocal_stmt); + s = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena); + if (!s) + return NULL; + for (i = 1; i < NCH(n); i += 2) { + name = NEW_IDENTIFIER(CHILD(n, i)); + if (!name) + return NULL; + asdl_seq_SET(s, i / 2, name); + } + return Nonlocal(s, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +static stmt_ty +ast_for_assert_stmt(struct compiling *c, const node *n) +{ + /* assert_stmt: 'assert' test [',' test] */ + REQ(n, assert_stmt); + if (NCH(n) == 2) { + expr_ty expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + return Assert(expression, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + else if (NCH(n) == 4) { + expr_ty expr1, expr2; + + expr1 = ast_for_expr(c, CHILD(n, 1)); + if (!expr1) + return NULL; + expr2 = ast_for_expr(c, CHILD(n, 3)); + if (!expr2) + return NULL; + + return Assert(expr1, expr2, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + PyErr_Format(PyExc_SystemError, + "improper number of parts to 'assert' statement: %d", + NCH(n)); + return NULL; +} + +static asdl_seq * +ast_for_suite(struct compiling *c, const node *n) +{ + /* suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */ + asdl_seq *seq; + stmt_ty s; + int i, total, num, end, pos = 0; + node *ch; + + if (TYPE(n) != func_body_suite) { + REQ(n, suite); + } + + total = num_stmts(n); + seq = _Py_asdl_seq_new(total, c->c_arena); + if (!seq) + return NULL; + if (TYPE(CHILD(n, 0)) == simple_stmt) { + n = CHILD(n, 0); + /* simple_stmt always ends with a NEWLINE, + and may have a trailing SEMI + */ + end = NCH(n) - 1; + if (TYPE(CHILD(n, end - 1)) == SEMI) + end--; + /* loop by 2 to skip semi-colons */ + for (i = 0; i < end; i += 2) { + ch = CHILD(n, i); + s = ast_for_stmt(c, ch); + if (!s) + return NULL; + asdl_seq_SET(seq, pos++, s); + } + } + else { + i = 2; + if (TYPE(CHILD(n, 1)) == TYPE_COMMENT) { + i += 2; + REQ(CHILD(n, 2), NEWLINE); + } + + for (; i < (NCH(n) - 1); i++) { + ch = CHILD(n, i); + REQ(ch, stmt); + num = num_stmts(ch); + if (num == 1) { + /* small_stmt or compound_stmt with only one child */ + s = ast_for_stmt(c, ch); + if (!s) + return NULL; + asdl_seq_SET(seq, pos++, s); + } + else { + int j; + ch = CHILD(ch, 0); + REQ(ch, simple_stmt); + for (j = 0; j < NCH(ch); j += 2) { + /* statement terminates with a semi-colon ';' */ + if (NCH(CHILD(ch, j)) == 0) { + assert((j + 1) == NCH(ch)); + break; + } + s = ast_for_stmt(c, CHILD(ch, j)); + if (!s) + return NULL; + asdl_seq_SET(seq, pos++, s); + } + } + } + } + assert(pos == seq->size); + return seq; +} + +static void +get_last_end_pos(asdl_seq *s, int *end_lineno, int *end_col_offset) +{ + Py_ssize_t tot = asdl_seq_LEN(s); + // There must be no empty suites. + assert(tot > 0); + stmt_ty last = asdl_seq_GET(s, tot - 1); + *end_lineno = last->end_lineno; + *end_col_offset = last->end_col_offset; +} + +static stmt_ty +ast_for_if_stmt(struct compiling *c, const node *n) +{ + /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)* + ['else' ':' suite] + */ + char *s; + int end_lineno, end_col_offset; + + REQ(n, if_stmt); + + if (NCH(n) == 4) { + expr_ty expression; + asdl_seq *suite_seq; + + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, CHILD(n, 3)); + if (!suite_seq) + return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + + return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + + s = STR(CHILD(n, 4)); + /* s[2], the third character in the string, will be + 's' for el_s_e, or + 'i' for el_i_f + */ + if (s[2] == 's') { + expr_ty expression; + asdl_seq *seq1, *seq2; + + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + seq1 = ast_for_suite(c, CHILD(n, 3)); + if (!seq1) + return NULL; + seq2 = ast_for_suite(c, CHILD(n, 6)); + if (!seq2) + return NULL; + get_last_end_pos(seq2, &end_lineno, &end_col_offset); + + return If(expression, seq1, seq2, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + else if (s[2] == 'i') { + int i, n_elif, has_else = 0; + expr_ty expression; + asdl_seq *suite_seq; + asdl_seq *orelse = NULL; + n_elif = NCH(n) - 4; + /* must reference the child n_elif+1 since 'else' token is third, + not fourth, child from the end. */ + if (TYPE(CHILD(n, (n_elif + 1))) == NAME + && STR(CHILD(n, (n_elif + 1)))[2] == 's') { + has_else = 1; + n_elif -= 3; + } + n_elif /= 4; + + if (has_else) { + asdl_seq *suite_seq2; + + orelse = _Py_asdl_seq_new(1, c->c_arena); + if (!orelse) + return NULL; + expression = ast_for_expr(c, CHILD(n, NCH(n) - 6)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4)); + if (!suite_seq) + return NULL; + suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1)); + if (!suite_seq2) + return NULL; + get_last_end_pos(suite_seq2, &end_lineno, &end_col_offset); + + asdl_seq_SET(orelse, 0, + If(expression, suite_seq, suite_seq2, + LINENO(CHILD(n, NCH(n) - 7)), + CHILD(n, NCH(n) - 7)->n_col_offset, + end_lineno, end_col_offset, c->c_arena)); + /* the just-created orelse handled the last elif */ + n_elif--; + } + + for (i = 0; i < n_elif; i++) { + int off = 5 + (n_elif - i - 1) * 4; + asdl_seq *newobj = _Py_asdl_seq_new(1, c->c_arena); + if (!newobj) + return NULL; + expression = ast_for_expr(c, CHILD(n, off)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, CHILD(n, off + 2)); + if (!suite_seq) + return NULL; + + if (orelse != NULL) { + get_last_end_pos(orelse, &end_lineno, &end_col_offset); + } else { + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + } + asdl_seq_SET(newobj, 0, + If(expression, suite_seq, orelse, + LINENO(CHILD(n, off - 1)), + CHILD(n, off - 1)->n_col_offset, + end_lineno, end_col_offset, c->c_arena)); + orelse = newobj; + } + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, CHILD(n, 3)); + if (!suite_seq) + return NULL; + get_last_end_pos(orelse, &end_lineno, &end_col_offset); + return If(expression, suite_seq, orelse, + LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + + PyErr_Format(PyExc_SystemError, + "unexpected token in 'if' statement: %s", s); + return NULL; +} + +static stmt_ty +ast_for_while_stmt(struct compiling *c, const node *n) +{ + /* while_stmt: 'while' test ':' suite ['else' ':' suite] */ + REQ(n, while_stmt); + int end_lineno, end_col_offset; + + if (NCH(n) == 4) { + expr_ty expression; + asdl_seq *suite_seq; + + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, CHILD(n, 3)); + if (!suite_seq) + return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + else if (NCH(n) == 7) { + expr_ty expression; + asdl_seq *seq1, *seq2; + + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + seq1 = ast_for_suite(c, CHILD(n, 3)); + if (!seq1) + return NULL; + seq2 = ast_for_suite(c, CHILD(n, 6)); + if (!seq2) + return NULL; + get_last_end_pos(seq2, &end_lineno, &end_col_offset); + + return While(expression, seq1, seq2, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + + PyErr_Format(PyExc_SystemError, + "wrong number of tokens for 'while' statement: %d", + NCH(n)); + return NULL; +} + +static stmt_ty +ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async) +{ + const node * const n = is_async ? CHILD(n0, 1) : n0; + asdl_seq *_target, *seq = NULL, *suite_seq; + expr_ty expression; + expr_ty target, first; + const node *node_target; + int end_lineno, end_col_offset; + int has_type_comment; + string type_comment; + + if (is_async && c->c_feature_version < 5) { + ast_error(c, n, + "Async for loops are only supported in Python 3.5 and greater"); + return NULL; + } + + /* for_stmt: 'for' exprlist 'in' testlist ':' [TYPE_COMMENT] suite ['else' ':' suite] */ + REQ(n, for_stmt); + + has_type_comment = TYPE(CHILD(n, 5)) == TYPE_COMMENT; + + if (NCH(n) == 9 + has_type_comment) { + seq = ast_for_suite(c, CHILD(n, 8 + has_type_comment)); + if (!seq) + return NULL; + } + + node_target = CHILD(n, 1); + _target = ast_for_exprlist(c, node_target, Store); + if (!_target) + return NULL; + /* Check the # of children rather than the length of _target, since + for x, in ... has 1 element in _target, but still requires a Tuple. */ + first = (expr_ty)asdl_seq_GET(_target, 0); + if (NCH(node_target) == 1) + target = first; + else + target = Tuple(_target, Store, first->lineno, first->col_offset, + node_target->n_end_lineno, node_target->n_end_col_offset, + c->c_arena); + + expression = ast_for_testlist(c, CHILD(n, 3)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, CHILD(n, 5 + has_type_comment)); + if (!suite_seq) + return NULL; + + if (seq != NULL) { + get_last_end_pos(seq, &end_lineno, &end_col_offset); + } else { + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + } + + if (has_type_comment) { + type_comment = NEW_TYPE_COMMENT(CHILD(n, 5)); + if (!type_comment) + return NULL; + } + else + type_comment = NULL; + + if (is_async) + return AsyncFor(target, expression, suite_seq, seq, type_comment, + LINENO(n0), n0->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + else + return For(target, expression, suite_seq, seq, type_comment, + LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); +} + +static excepthandler_ty +ast_for_except_clause(struct compiling *c, const node *exc, node *body) +{ + /* except_clause: 'except' [test ['as' test]] */ + int end_lineno, end_col_offset; + REQ(exc, except_clause); + REQ(body, suite); + + if (NCH(exc) == 1) { + asdl_seq *suite_seq = ast_for_suite(c, body); + if (!suite_seq) + return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + + return ExceptHandler(NULL, NULL, suite_seq, LINENO(exc), + exc->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + else if (NCH(exc) == 2) { + expr_ty expression; + asdl_seq *suite_seq; + + expression = ast_for_expr(c, CHILD(exc, 1)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, body); + if (!suite_seq) + return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + + return ExceptHandler(expression, NULL, suite_seq, LINENO(exc), + exc->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + else if (NCH(exc) == 4) { + asdl_seq *suite_seq; + expr_ty expression; + identifier e = NEW_IDENTIFIER(CHILD(exc, 3)); + if (!e) + return NULL; + if (forbidden_name(c, e, CHILD(exc, 3), 0)) + return NULL; + expression = ast_for_expr(c, CHILD(exc, 1)); + if (!expression) + return NULL; + suite_seq = ast_for_suite(c, body); + if (!suite_seq) + return NULL; + get_last_end_pos(suite_seq, &end_lineno, &end_col_offset); + + return ExceptHandler(expression, e, suite_seq, LINENO(exc), + exc->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + + PyErr_Format(PyExc_SystemError, + "wrong number of children for 'except' clause: %d", + NCH(exc)); + return NULL; +} + +static stmt_ty +ast_for_try_stmt(struct compiling *c, const node *n) +{ + const int nch = NCH(n); + int end_lineno, end_col_offset, n_except = (nch - 3)/3; + asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL; + excepthandler_ty last_handler; + + REQ(n, try_stmt); + + body = ast_for_suite(c, CHILD(n, 2)); + if (body == NULL) + return NULL; + + if (TYPE(CHILD(n, nch - 3)) == NAME) { + if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) { + if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) { + /* we can assume it's an "else", + because nch >= 9 for try-else-finally and + it would otherwise have a type of except_clause */ + orelse = ast_for_suite(c, CHILD(n, nch - 4)); + if (orelse == NULL) + return NULL; + n_except--; + } + + finally = ast_for_suite(c, CHILD(n, nch - 1)); + if (finally == NULL) + return NULL; + n_except--; + } + else { + /* we can assume it's an "else", + otherwise it would have a type of except_clause */ + orelse = ast_for_suite(c, CHILD(n, nch - 1)); + if (orelse == NULL) + return NULL; + n_except--; + } + } + else if (TYPE(CHILD(n, nch - 3)) != except_clause) { + ast_error(c, n, "malformed 'try' statement"); + return NULL; + } + + if (n_except > 0) { + int i; + /* process except statements to create a try ... except */ + handlers = _Py_asdl_seq_new(n_except, c->c_arena); + if (handlers == NULL) + return NULL; + + for (i = 0; i < n_except; i++) { + excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3), + CHILD(n, 5 + i * 3)); + if (!e) + return NULL; + asdl_seq_SET(handlers, i, e); + } + } + + assert(finally != NULL || asdl_seq_LEN(handlers)); + if (finally != NULL) { + // finally is always last + get_last_end_pos(finally, &end_lineno, &end_col_offset); + } else if (orelse != NULL) { + // otherwise else is last + get_last_end_pos(orelse, &end_lineno, &end_col_offset); + } else { + // inline the get_last_end_pos logic due to layout mismatch + last_handler = (excepthandler_ty) asdl_seq_GET(handlers, n_except - 1); + end_lineno = last_handler->end_lineno; + end_col_offset = last_handler->end_col_offset; + } + return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); +} + +/* with_item: test ['as' expr] */ +static withitem_ty +ast_for_with_item(struct compiling *c, const node *n) +{ + expr_ty context_expr, optional_vars = NULL; + + REQ(n, with_item); + context_expr = ast_for_expr(c, CHILD(n, 0)); + if (!context_expr) + return NULL; + if (NCH(n) == 3) { + optional_vars = ast_for_expr(c, CHILD(n, 2)); + + if (!optional_vars) { + return NULL; + } + if (!set_context(c, optional_vars, Store, n)) { + return NULL; + } + } + + return withitem(context_expr, optional_vars, c->c_arena); +} + +/* with_stmt: 'with' with_item (',' with_item)* ':' [TYPE_COMMENT] suite */ +static stmt_ty +ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async) +{ + const node * const n = is_async ? CHILD(n0, 1) : n0; + int i, n_items, nch_minus_type, has_type_comment, end_lineno, end_col_offset; + asdl_seq *items, *body; + string type_comment; + + if (is_async && c->c_feature_version < 5) { + ast_error(c, n, + "Async with statements are only supported in Python 3.5 and greater"); + return NULL; + } + + REQ(n, with_stmt); + + has_type_comment = TYPE(CHILD(n, NCH(n) - 2)) == TYPE_COMMENT; + nch_minus_type = NCH(n) - has_type_comment; + + n_items = (nch_minus_type - 2) / 2; + items = _Py_asdl_seq_new(n_items, c->c_arena); + if (!items) + return NULL; + for (i = 1; i < nch_minus_type - 2; i += 2) { + withitem_ty item = ast_for_with_item(c, CHILD(n, i)); + if (!item) + return NULL; + asdl_seq_SET(items, (i - 1) / 2, item); + } + + body = ast_for_suite(c, CHILD(n, NCH(n) - 1)); + if (!body) + return NULL; + get_last_end_pos(body, &end_lineno, &end_col_offset); + + if (has_type_comment) { + type_comment = NEW_TYPE_COMMENT(CHILD(n, NCH(n) - 2)); + if (!type_comment) + return NULL; + } + else + type_comment = NULL; + + if (is_async) + return AsyncWith(items, body, type_comment, LINENO(n0), n0->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + else + return With(items, body, type_comment, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); +} + +static stmt_ty +ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) +{ + /* classdef: 'class' NAME ['(' arglist ')'] ':' suite */ + PyObject *classname; + asdl_seq *s; + expr_ty call; + int end_lineno, end_col_offset; + + REQ(n, classdef); + + if (NCH(n) == 4) { /* class NAME ':' suite */ + s = ast_for_suite(c, CHILD(n, 3)); + if (!s) + return NULL; + get_last_end_pos(s, &end_lineno, &end_col_offset); + + classname = NEW_IDENTIFIER(CHILD(n, 1)); + if (!classname) + return NULL; + if (forbidden_name(c, classname, CHILD(n, 3), 0)) + return NULL; + return ClassDef(classname, NULL, NULL, s, decorator_seq, + LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + + if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */ + s = ast_for_suite(c, CHILD(n, 5)); + if (!s) + return NULL; + get_last_end_pos(s, &end_lineno, &end_col_offset); + + classname = NEW_IDENTIFIER(CHILD(n, 1)); + if (!classname) + return NULL; + if (forbidden_name(c, classname, CHILD(n, 3), 0)) + return NULL; + return ClassDef(classname, NULL, NULL, s, decorator_seq, + LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); + } + + /* class NAME '(' arglist ')' ':' suite */ + /* build up a fake Call node so we can extract its pieces */ + { + PyObject *dummy_name; + expr_ty dummy; + dummy_name = NEW_IDENTIFIER(CHILD(n, 1)); + if (!dummy_name) + return NULL; + dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, + CHILD(n, 1)->n_end_lineno, CHILD(n, 1)->n_end_col_offset, + c->c_arena); + call = ast_for_call(c, CHILD(n, 3), dummy, + CHILD(n, 1), NULL, CHILD(n, 4)); + if (!call) + return NULL; + } + s = ast_for_suite(c, CHILD(n, 6)); + if (!s) + return NULL; + get_last_end_pos(s, &end_lineno, &end_col_offset); + + classname = NEW_IDENTIFIER(CHILD(n, 1)); + if (!classname) + return NULL; + if (forbidden_name(c, classname, CHILD(n, 1), 0)) + return NULL; + + return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s, + decorator_seq, LINENO(n), n->n_col_offset, + end_lineno, end_col_offset, c->c_arena); +} + +static stmt_ty +ast_for_stmt(struct compiling *c, const node *n) +{ + if (TYPE(n) == stmt) { + assert(NCH(n) == 1); + n = CHILD(n, 0); + } + if (TYPE(n) == simple_stmt) { + assert(num_stmts(n) == 1); + n = CHILD(n, 0); + } + if (TYPE(n) == small_stmt) { + n = CHILD(n, 0); + /* small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt + | import_stmt | global_stmt | nonlocal_stmt | assert_stmt + */ + switch (TYPE(n)) { + case expr_stmt: + return ast_for_expr_stmt(c, n); + case del_stmt: + return ast_for_del_stmt(c, n); + case pass_stmt: + return Pass(LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + case flow_stmt: + return ast_for_flow_stmt(c, n); + case import_stmt: + return ast_for_import_stmt(c, n); + case global_stmt: + return ast_for_global_stmt(c, n); + case nonlocal_stmt: + return ast_for_nonlocal_stmt(c, n); + case assert_stmt: + return ast_for_assert_stmt(c, n); + default: + PyErr_Format(PyExc_SystemError, + "unhandled small_stmt: TYPE=%d NCH=%d\n", + TYPE(n), NCH(n)); + return NULL; + } + } + else { + /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt + | funcdef | classdef | decorated | async_stmt + */ + node *ch = CHILD(n, 0); + REQ(n, compound_stmt); + switch (TYPE(ch)) { + case if_stmt: + return ast_for_if_stmt(c, ch); + case while_stmt: + return ast_for_while_stmt(c, ch); + case for_stmt: + return ast_for_for_stmt(c, ch, 0); + case try_stmt: + return ast_for_try_stmt(c, ch); + case with_stmt: + return ast_for_with_stmt(c, ch, 0); + case funcdef: + return ast_for_funcdef(c, ch, NULL); + case classdef: + return ast_for_classdef(c, ch, NULL); + case decorated: + return ast_for_decorated(c, ch); + case async_stmt: + return ast_for_async_stmt(c, ch); + default: + PyErr_Format(PyExc_SystemError, + "unhandled compound_stmt: TYPE=%d NCH=%d\n", + TYPE(n), NCH(n)); + return NULL; + } + } +} + +static PyObject * +parsenumber_raw(struct compiling *c, const char *s) +{ + const char *end; + long x; + double dx; + Py_complex compl; + int imflag; + + assert(s != NULL); + errno = 0; + end = s + strlen(s) - 1; + imflag = *end == 'j' || *end == 'J'; + if (s[0] == '0') { + x = (long) PyOS_strtoul(s, (char **)&end, 0); + if (x < 0 && errno == 0) { + return PyLong_FromString(s, (char **)0, 0); + } + } + else + x = PyOS_strtol(s, (char **)&end, 0); + if (*end == '\0') { + if (errno != 0) + return PyLong_FromString(s, (char **)0, 0); + return PyLong_FromLong(x); + } + /* XXX Huge floats may silently fail */ + if (imflag) { + compl.real = 0.; + compl.imag = PyOS_string_to_double(s, (char **)&end, NULL); + if (compl.imag == -1.0 && PyErr_Occurred()) + return NULL; + return PyComplex_FromCComplex(compl); + } + else + { + dx = PyOS_string_to_double(s, NULL, NULL); + if (dx == -1.0 && PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble(dx); + } +} + +static PyObject * +parsenumber(struct compiling *c, const char *s) +{ + char *dup, *end; + PyObject *res = NULL; + + assert(s != NULL); + + if (strchr(s, '_') == NULL) { + return parsenumber_raw(c, s); + } + /* Create a duplicate without underscores. */ + dup = PyMem_Malloc(strlen(s) + 1); + if (dup == NULL) { + return PyErr_NoMemory(); + } + end = dup; + for (; *s; s++) { + if (*s != '_') { + *end++ = *s; + } + } + *end = '\0'; + res = parsenumber_raw(c, dup); + PyMem_Free(dup); + return res; +} + +static PyObject * +decode_utf8(struct compiling *c, const char **sPtr, const char *end) +{ + const char *s, *t; + t = s = *sPtr; + /* while (s < end && *s != '\\') s++; */ /* inefficient for u".." */ + while (s < end && (*s & 0x80)) s++; + *sPtr = s; + return PyUnicode_DecodeUTF8(t, s - t, NULL); +} + +static int +warn_invalid_escape_sequence(struct compiling *c, const node *n, + unsigned char first_invalid_escape_char) +{ + PyObject *msg = PyUnicode_FromFormat("invalid escape sequence \\%c", + first_invalid_escape_char); + if (msg == NULL) { + return -1; + } + if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg, + c->c_filename, LINENO(n), + NULL, NULL) < 0) + { + if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + /* Replace the DeprecationWarning exception with a SyntaxError + to get a more accurate error report */ + PyErr_Clear(); + ast_error(c, n, "%U", msg); + } + Py_DECREF(msg); + return -1; + } + Py_DECREF(msg); + return 0; +} + +static PyObject * +decode_unicode_with_escapes(struct compiling *c, const node *n, const char *s, + size_t len) +{ + PyObject *v, *u; + char *buf; + char *p; + const char *end; + + /* check for integer overflow */ + if (len > SIZE_MAX / 6) + return NULL; + /* "ä" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5 + "\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */ + u = PyBytes_FromStringAndSize((char *)NULL, len * 6); + if (u == NULL) + return NULL; + p = buf = PyBytes_AsString(u); + end = s + len; + while (s < end) { + if (*s == '\\') { + *p++ = *s++; + if (s >= end || *s & 0x80) { + strcpy(p, "u005c"); + p += 5; + if (s >= end) + break; + } + } + if (*s & 0x80) { /* XXX inefficient */ + PyObject *w; + int kind; + void *data; + Py_ssize_t len, i; + w = decode_utf8(c, &s, end); + if (w == NULL) { + Py_DECREF(u); + return NULL; + } + kind = PyUnicode_KIND(w); + data = PyUnicode_DATA(w); + len = PyUnicode_GET_LENGTH(w); + for (i = 0; i < len; i++) { + Py_UCS4 chr = PyUnicode_READ(kind, data, i); + sprintf(p, "\\U%08x", chr); + p += 10; + } + /* Should be impossible to overflow */ + assert(p - buf <= PyBytes_GET_SIZE(u)); + Py_DECREF(w); + } else { + *p++ = *s++; + } + } + len = p - buf; + s = buf; + + const char *first_invalid_escape; + v = _PyUnicode_DecodeUnicodeEscape(s, len, NULL, &first_invalid_escape); + + if (v != NULL && first_invalid_escape != NULL) { + if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) { + /* We have not decref u before because first_invalid_escape points + inside u. */ + Py_XDECREF(u); + Py_DECREF(v); + return NULL; + } + } + Py_XDECREF(u); + return v; +} + +static PyObject * +decode_bytes_with_escapes(struct compiling *c, const node *n, const char *s, + size_t len) +{ + const char *first_invalid_escape; + PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, 0, NULL, + &first_invalid_escape); + if (result == NULL) + return NULL; + + if (first_invalid_escape != NULL) { + if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) { + Py_DECREF(result); + return NULL; + } + } + return result; +} + +/* Shift locations for the given node and all its children by adding `lineno` + and `col_offset` to existing locations. */ +static void fstring_shift_node_locations(node *n, int lineno, int col_offset) +{ + n->n_col_offset = n->n_col_offset + col_offset; + n->n_end_col_offset = n->n_end_col_offset + col_offset; + for (int i = 0; i < NCH(n); ++i) { + if (n->n_lineno && n->n_lineno < CHILD(n, i)->n_lineno) { + /* Shifting column offsets unnecessary if there's been newlines. */ + col_offset = 0; + } + fstring_shift_node_locations(CHILD(n, i), lineno, col_offset); + } + n->n_lineno = n->n_lineno + lineno; + n->n_end_lineno = n->n_end_lineno + lineno; +} + +/* Fix locations for the given node and its children. + + `parent` is the enclosing node. + `n` is the node which locations are going to be fixed relative to parent. + `expr_str` is the child node's string representation, including braces. +*/ +static void +fstring_fix_node_location(const node *parent, node *n, char *expr_str) +{ + char *substr = NULL; + char *start; + int lines = LINENO(parent) - 1; + int cols = parent->n_col_offset; + /* Find the full fstring to fix location information in `n`. */ + while (parent && parent->n_type != STRING) + parent = parent->n_child; + if (parent && parent->n_str) { + substr = strstr(parent->n_str, expr_str); + if (substr) { + start = substr; + while (start > parent->n_str) { + if (start[0] == '\n') + break; + start--; + } + cols += (int)(substr - start); + /* adjust the start based on the number of newlines encountered + before the f-string expression */ + for (char* p = parent->n_str; p < substr; p++) { + if (*p == '\n') { + lines++; + } + } + } + } + fstring_shift_node_locations(n, lines, cols); +} + +/* Compile this expression in to an expr_ty. Add parens around the + expression, in order to allow leading spaces in the expression. */ +static expr_ty +fstring_compile_expr(const char *expr_start, const char *expr_end, + struct compiling *c, const node *n) + +{ + node *mod_n; + mod_ty mod; + char *str; + Py_ssize_t len; + const char *s; + + assert(expr_end >= expr_start); + assert(*(expr_start-1) == '{'); + assert(*expr_end == '}' || *expr_end == '!' || *expr_end == ':' || + *expr_end == '='); + + /* If the substring is all whitespace, it's an error. We need to catch this + here, and not when we call PyParser_SimpleParseStringFlagsFilename, + because turning the expression '' in to '()' would go from being invalid + to valid. */ + for (s = expr_start; s != expr_end; s++) { + char c = *s; + /* The Python parser ignores only the following whitespace + characters (\r already is converted to \n). */ + if (!(c == ' ' || c == '\t' || c == '\n' || c == '\f')) { + break; + } + } + if (s == expr_end) { + ast_error(c, n, "f-string: empty expression not allowed"); + return NULL; + } + + len = expr_end - expr_start; + /* Allocate 3 extra bytes: open paren, close paren, null byte. */ + str = PyMem_Malloc(len + 3); + if (str == NULL) { + PyErr_NoMemory(); + return NULL; + } + + str[0] = '('; + memcpy(str+1, expr_start, len); + str[len+1] = ')'; + str[len+2] = 0; + + PyCompilerFlags cf = _PyCompilerFlags_INIT; + cf.cf_flags = PyCF_ONLY_AST; + mod_n = PyParser_SimpleParseStringFlagsFilename(str, "", + Py_eval_input, 0); + if (!mod_n) { + PyMem_Free(str); + return NULL; + } + /* Reuse str to find the correct column offset. */ + str[0] = '{'; + str[len+1] = '}'; + fstring_fix_node_location(n, mod_n, str); + mod = PyAST_FromNode(mod_n, &cf, "", c->c_arena); + PyMem_Free(str); + PyNode_Free(mod_n); + if (!mod) + return NULL; + return mod->v.Expression.body; +} + +/* Return -1 on error. + + Return 0 if we reached the end of the literal. + + Return 1 if we haven't reached the end of the literal, but we want + the caller to process the literal up to this point. Used for + doubled braces. +*/ +static int +fstring_find_literal(const char **str, const char *end, int raw, + PyObject **literal, int recurse_lvl, + struct compiling *c, const node *n) +{ + /* Get any literal string. It ends when we hit an un-doubled left + brace (which isn't part of a unicode name escape such as + "\N{EULER CONSTANT}"), or the end of the string. */ + + const char *s = *str; + const char *literal_start = s; + int result = 0; + + assert(*literal == NULL); + while (s < end) { + char ch = *s++; + if (!raw && ch == '\\' && s < end) { + ch = *s++; + if (ch == 'N') { + if (s < end && *s++ == '{') { + while (s < end && *s++ != '}') { + } + continue; + } + break; + } + if (ch == '{' && warn_invalid_escape_sequence(c, n, ch) < 0) { + return -1; + } + } + if (ch == '{' || ch == '}') { + /* Check for doubled braces, but only at the top level. If + we checked at every level, then f'{0:{3}}' would fail + with the two closing braces. */ + if (recurse_lvl == 0) { + if (s < end && *s == ch) { + /* We're going to tell the caller that the literal ends + here, but that they should continue scanning. But also + skip over the second brace when we resume scanning. */ + *str = s + 1; + result = 1; + goto done; + } + + /* Where a single '{' is the start of a new expression, a + single '}' is not allowed. */ + if (ch == '}') { + *str = s - 1; + ast_error(c, n, "f-string: single '}' is not allowed"); + return -1; + } + } + /* We're either at a '{', which means we're starting another + expression; or a '}', which means we're at the end of this + f-string (for a nested format_spec). */ + s--; + break; + } + } + *str = s; + assert(s <= end); + assert(s == end || *s == '{' || *s == '}'); +done: + if (literal_start != s) { + if (raw) + *literal = PyUnicode_DecodeUTF8Stateful(literal_start, + s - literal_start, + NULL, NULL); + else + *literal = decode_unicode_with_escapes(c, n, literal_start, + s - literal_start); + if (!*literal) + return -1; + } + return result; +} + +/* Forward declaration because parsing is recursive. */ +static expr_ty +fstring_parse(const char **str, const char *end, int raw, int recurse_lvl, + struct compiling *c, const node *n); + +/* Parse the f-string at *str, ending at end. We know *str starts an + expression (so it must be a '{'). Returns the FormattedValue node, which + includes the expression, conversion character, format_spec expression, and + optionally the text of the expression (if = is used). + + Note that I don't do a perfect job here: I don't make sure that a + closing brace doesn't match an opening paren, for example. It + doesn't need to error on all invalid expressions, just correctly + find the end of all valid ones. Any errors inside the expression + will be caught when we parse it later. + + *expression is set to the expression. For an '=' "debug" expression, + *expr_text is set to the debug text (the original text of the expression, + including the '=' and any whitespace around it, as a string object). If + not a debug expression, *expr_text set to NULL. */ +static int +fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, + PyObject **expr_text, expr_ty *expression, + struct compiling *c, const node *n) +{ + /* Return -1 on error, else 0. */ + + const char *expr_start; + const char *expr_end; + expr_ty simple_expression; + expr_ty format_spec = NULL; /* Optional format specifier. */ + int conversion = -1; /* The conversion char. Use default if not + specified, or !r if using = and no format + spec. */ + + /* 0 if we're not in a string, else the quote char we're trying to + match (single or double quote). */ + char quote_char = 0; + + /* If we're inside a string, 1=normal, 3=triple-quoted. */ + int string_type = 0; + + /* Keep track of nesting level for braces/parens/brackets in + expressions. */ + Py_ssize_t nested_depth = 0; + char parenstack[MAXLEVEL]; + + *expr_text = NULL; + + /* Can only nest one level deep. */ + if (recurse_lvl >= 2) { + ast_error(c, n, "f-string: expressions nested too deeply"); + goto error; + } + + /* The first char must be a left brace, or we wouldn't have gotten + here. Skip over it. */ + assert(**str == '{'); + *str += 1; + + expr_start = *str; + for (; *str < end; (*str)++) { + char ch; + + /* Loop invariants. */ + assert(nested_depth >= 0); + assert(*str >= expr_start && *str < end); + if (quote_char) + assert(string_type == 1 || string_type == 3); + else + assert(string_type == 0); + + ch = **str; + /* Nowhere inside an expression is a backslash allowed. */ + if (ch == '\\') { + /* Error: can't include a backslash character, inside + parens or strings or not. */ + ast_error(c, n, + "f-string expression part " + "cannot include a backslash"); + goto error; + } + if (quote_char) { + /* We're inside a string. See if we're at the end. */ + /* This code needs to implement the same non-error logic + as tok_get from tokenizer.c, at the letter_quote + label. To actually share that code would be a + nightmare. But, it's unlikely to change and is small, + so duplicate it here. Note we don't need to catch all + of the errors, since they'll be caught when parsing the + expression. We just need to match the non-error + cases. Thus we can ignore \n in single-quoted strings, + for example. Or non-terminated strings. */ + if (ch == quote_char) { + /* Does this match the string_type (single or triple + quoted)? */ + if (string_type == 3) { + if (*str+2 < end && *(*str+1) == ch && *(*str+2) == ch) { + /* We're at the end of a triple quoted string. */ + *str += 2; + string_type = 0; + quote_char = 0; + continue; + } + } else { + /* We're at the end of a normal string. */ + quote_char = 0; + string_type = 0; + continue; + } + } + } else if (ch == '\'' || ch == '"') { + /* Is this a triple quoted string? */ + if (*str+2 < end && *(*str+1) == ch && *(*str+2) == ch) { + string_type = 3; + *str += 2; + } else { + /* Start of a normal string. */ + string_type = 1; + } + /* Start looking for the end of the string. */ + quote_char = ch; + } else if (ch == '[' || ch == '{' || ch == '(') { + if (nested_depth >= MAXLEVEL) { + ast_error(c, n, "f-string: too many nested parenthesis"); + goto error; + } + parenstack[nested_depth] = ch; + nested_depth++; + } else if (ch == '#') { + /* Error: can't include a comment character, inside parens + or not. */ + ast_error(c, n, "f-string expression part cannot include '#'"); + goto error; + } else if (nested_depth == 0 && + (ch == '!' || ch == ':' || ch == '}' || + ch == '=' || ch == '>' || ch == '<')) { + /* See if there's a next character. */ + if (*str+1 < end) { + char next = *(*str+1); + + /* For "!=". since '=' is not an allowed conversion character, + nothing is lost in this test. */ + if ((ch == '!' && next == '=') || /* != */ + (ch == '=' && next == '=') || /* == */ + (ch == '<' && next == '=') || /* <= */ + (ch == '>' && next == '=') /* >= */ + ) { + *str += 1; + continue; + } + /* Don't get out of the loop for these, if they're single + chars (not part of 2-char tokens). If by themselves, they + don't end an expression (unlike say '!'). */ + if (ch == '>' || ch == '<') { + continue; + } + } + + /* Normal way out of this loop. */ + break; + } else if (ch == ']' || ch == '}' || ch == ')') { + if (!nested_depth) { + ast_error(c, n, "f-string: unmatched '%c'", ch); + goto error; + } + nested_depth--; + int opening = parenstack[nested_depth]; + if (!((opening == '(' && ch == ')') || + (opening == '[' && ch == ']') || + (opening == '{' && ch == '}'))) + { + ast_error(c, n, + "f-string: closing parenthesis '%c' " + "does not match opening parenthesis '%c'", + ch, opening); + goto error; + } + } else { + /* Just consume this char and loop around. */ + } + } + expr_end = *str; + /* If we leave this loop in a string or with mismatched parens, we + don't care. We'll get a syntax error when compiling the + expression. But, we can produce a better error message, so + let's just do that.*/ + if (quote_char) { + ast_error(c, n, "f-string: unterminated string"); + goto error; + } + if (nested_depth) { + int opening = parenstack[nested_depth - 1]; + ast_error(c, n, "f-string: unmatched '%c'", opening); + goto error; + } + + if (*str >= end) + goto unexpected_end_of_string; + + /* Compile the expression as soon as possible, so we show errors + related to the expression before errors related to the + conversion or format_spec. */ + simple_expression = fstring_compile_expr(expr_start, expr_end, c, n); + if (!simple_expression) + goto error; + + /* Check for =, which puts the text value of the expression in + expr_text. */ + if (**str == '=') { + if (c->c_feature_version < 8) { + ast_error(c, n, + "f-string: self documenting expressions are " + "only supported in Python 3.8 and greater"); + goto error; + } + *str += 1; + + /* Skip over ASCII whitespace. No need to test for end of string + here, since we know there's at least a trailing quote somewhere + ahead. */ + while (Py_ISSPACE(**str)) { + *str += 1; + } + + /* Set *expr_text to the text of the expression. */ + *expr_text = PyUnicode_FromStringAndSize(expr_start, *str-expr_start); + if (!*expr_text) { + goto error; + } + } + + /* Check for a conversion char, if present. */ + if (**str == '!') { + *str += 1; + if (*str >= end) + goto unexpected_end_of_string; + + conversion = **str; + *str += 1; + + /* Validate the conversion. */ + if (!(conversion == 's' || conversion == 'r' || conversion == 'a')) { + ast_error(c, n, + "f-string: invalid conversion character: " + "expected 's', 'r', or 'a'"); + goto error; + } + + } + + /* Check for the format spec, if present. */ + if (*str >= end) + goto unexpected_end_of_string; + if (**str == ':') { + *str += 1; + if (*str >= end) + goto unexpected_end_of_string; + + /* Parse the format spec. */ + format_spec = fstring_parse(str, end, raw, recurse_lvl+1, c, n); + if (!format_spec) + goto error; + } + + if (*str >= end || **str != '}') + goto unexpected_end_of_string; + + /* We're at a right brace. Consume it. */ + assert(*str < end); + assert(**str == '}'); + *str += 1; + + /* If we're in = mode (detected by non-NULL expr_text), and have no format + spec and no explict conversion, set the conversion to 'r'. */ + if (*expr_text && format_spec == NULL && conversion == -1) { + conversion = 'r'; + } + + /* And now create the FormattedValue node that represents this + entire expression with the conversion and format spec. */ + *expression = FormattedValue(simple_expression, conversion, + format_spec, LINENO(n), + n->n_col_offset, n->n_end_lineno, + n->n_end_col_offset, c->c_arena); + if (!*expression) + goto error; + + return 0; + +unexpected_end_of_string: + ast_error(c, n, "f-string: expecting '}'"); + /* Falls through to error. */ + +error: + Py_XDECREF(*expr_text); + return -1; + +} + +/* Return -1 on error. + + Return 0 if we have a literal (possible zero length) and an + expression (zero length if at the end of the string. + + Return 1 if we have a literal, but no expression, and we want the + caller to call us again. This is used to deal with doubled + braces. + + When called multiple times on the string 'a{{b{0}c', this function + will return: + + 1. the literal 'a{' with no expression, and a return value + of 1. Despite the fact that there's no expression, the return + value of 1 means we're not finished yet. + + 2. the literal 'b' and the expression '0', with a return value of + 0. The fact that there's an expression means we're not finished. + + 3. literal 'c' with no expression and a return value of 0. The + combination of the return value of 0 with no expression means + we're finished. +*/ +static int +fstring_find_literal_and_expr(const char **str, const char *end, int raw, + int recurse_lvl, PyObject **literal, + PyObject **expr_text, expr_ty *expression, + struct compiling *c, const node *n) +{ + int result; + + assert(*literal == NULL && *expression == NULL); + + /* Get any literal string. */ + result = fstring_find_literal(str, end, raw, literal, recurse_lvl, c, n); + if (result < 0) + goto error; + + assert(result == 0 || result == 1); + + if (result == 1) + /* We have a literal, but don't look at the expression. */ + return 1; + + if (*str >= end || **str == '}') + /* We're at the end of the string or the end of a nested + f-string: no expression. The top-level error case where we + expect to be at the end of the string but we're at a '}' is + handled later. */ + return 0; + + /* We must now be the start of an expression, on a '{'. */ + assert(**str == '{'); + + if (fstring_find_expr(str, end, raw, recurse_lvl, expr_text, + expression, c, n) < 0) + goto error; + + return 0; + +error: + Py_CLEAR(*literal); + return -1; +} + +#define EXPRLIST_N_CACHED 64 + +typedef struct { + /* Incrementally build an array of expr_ty, so be used in an + asdl_seq. Cache some small but reasonably sized number of + expr_ty's, and then after that start dynamically allocating, + doubling the number allocated each time. Note that the f-string + f'{0}a{1}' contains 3 expr_ty's: 2 FormattedValue's, and one + Constant for the literal 'a'. So you add expr_ty's about twice as + fast as you add expressions in an f-string. */ + + Py_ssize_t allocated; /* Number we've allocated. */ + Py_ssize_t size; /* Number we've used. */ + expr_ty *p; /* Pointer to the memory we're actually + using. Will point to 'data' until we + start dynamically allocating. */ + expr_ty data[EXPRLIST_N_CACHED]; +} ExprList; + +#ifdef NDEBUG +#define ExprList_check_invariants(l) +#else +static void +ExprList_check_invariants(ExprList *l) +{ + /* Check our invariants. Make sure this object is "live", and + hasn't been deallocated. */ + assert(l->size >= 0); + assert(l->p != NULL); + if (l->size <= EXPRLIST_N_CACHED) + assert(l->data == l->p); +} +#endif + +static void +ExprList_Init(ExprList *l) +{ + l->allocated = EXPRLIST_N_CACHED; + l->size = 0; + + /* Until we start allocating dynamically, p points to data. */ + l->p = l->data; + + ExprList_check_invariants(l); +} + +static int +ExprList_Append(ExprList *l, expr_ty exp) +{ + ExprList_check_invariants(l); + if (l->size >= l->allocated) { + /* We need to alloc (or realloc) the memory. */ + Py_ssize_t new_size = l->allocated * 2; + + /* See if we've ever allocated anything dynamically. */ + if (l->p == l->data) { + Py_ssize_t i; + /* We're still using the cached data. Switch to + alloc-ing. */ + l->p = PyMem_Malloc(sizeof(expr_ty) * new_size); + if (!l->p) + return -1; + /* Copy the cached data into the new buffer. */ + for (i = 0; i < l->size; i++) + l->p[i] = l->data[i]; + } else { + /* Just realloc. */ + expr_ty *tmp = PyMem_Realloc(l->p, sizeof(expr_ty) * new_size); + if (!tmp) { + PyMem_Free(l->p); + l->p = NULL; + return -1; + } + l->p = tmp; + } + + l->allocated = new_size; + assert(l->allocated == 2 * l->size); + } + + l->p[l->size++] = exp; + + ExprList_check_invariants(l); + return 0; +} + +static void +ExprList_Dealloc(ExprList *l) +{ + ExprList_check_invariants(l); + + /* If there's been an error, or we've never dynamically allocated, + do nothing. */ + if (!l->p || l->p == l->data) { + /* Do nothing. */ + } else { + /* We have dynamically allocated. Free the memory. */ + PyMem_Free(l->p); + } + l->p = NULL; + l->size = -1; +} + +static asdl_seq * +ExprList_Finish(ExprList *l, PyArena *arena) +{ + asdl_seq *seq; + + ExprList_check_invariants(l); + + /* Allocate the asdl_seq and copy the expressions in to it. */ + seq = _Py_asdl_seq_new(l->size, arena); + if (seq) { + Py_ssize_t i; + for (i = 0; i < l->size; i++) + asdl_seq_SET(seq, i, l->p[i]); + } + ExprList_Dealloc(l); + return seq; +} + +/* The FstringParser is designed to add a mix of strings and + f-strings, and concat them together as needed. Ultimately, it + generates an expr_ty. */ +typedef struct { + PyObject *last_str; + ExprList expr_list; + int fmode; +} FstringParser; + +#ifdef NDEBUG +#define FstringParser_check_invariants(state) +#else +static void +FstringParser_check_invariants(FstringParser *state) +{ + if (state->last_str) + assert(PyUnicode_CheckExact(state->last_str)); + ExprList_check_invariants(&state->expr_list); +} +#endif + +static void +FstringParser_Init(FstringParser *state) +{ + state->last_str = NULL; + state->fmode = 0; + ExprList_Init(&state->expr_list); + FstringParser_check_invariants(state); +} + +static void +FstringParser_Dealloc(FstringParser *state) +{ + FstringParser_check_invariants(state); + + Py_XDECREF(state->last_str); + ExprList_Dealloc(&state->expr_list); +} + +/* Constants for the following */ +static PyObject *u_kind; + +/* Compute 'kind' field for string Constant (either 'u' or None) */ +static PyObject * +make_kind(struct compiling *c, const node *n) +{ + char *s = NULL; + PyObject *kind = NULL; + + /* Find the first string literal, if any */ + while (TYPE(n) != STRING) { + if (NCH(n) == 0) + return NULL; + n = CHILD(n, 0); + } + REQ(n, STRING); + + /* If it starts with 'u', return a PyUnicode "u" string */ + s = STR(n); + if (s && *s == 'u') { + if (!u_kind) { + u_kind = PyUnicode_InternFromString("u"); + if (!u_kind) + return NULL; + } + kind = u_kind; + if (PyArena_AddPyObject(c->c_arena, kind) < 0) { + return NULL; + } + Py_INCREF(kind); + } + return kind; +} + +/* Make a Constant node, but decref the PyUnicode object being added. */ +static expr_ty +make_str_node_and_del(PyObject **str, struct compiling *c, const node* n) +{ + PyObject *s = *str; + PyObject *kind = NULL; + *str = NULL; + assert(PyUnicode_CheckExact(s)); + if (PyArena_AddPyObject(c->c_arena, s) < 0) { + Py_DECREF(s); + return NULL; + } + kind = make_kind(c, n); + if (kind == NULL && PyErr_Occurred()) + return NULL; + return Constant(s, kind, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); +} + +/* Add a non-f-string (that is, a regular literal string). str is + decref'd. */ +static int +FstringParser_ConcatAndDel(FstringParser *state, PyObject *str) +{ + FstringParser_check_invariants(state); + + assert(PyUnicode_CheckExact(str)); + + if (PyUnicode_GET_LENGTH(str) == 0) { + Py_DECREF(str); + return 0; + } + + if (!state->last_str) { + /* We didn't have a string before, so just remember this one. */ + state->last_str = str; + } else { + /* Concatenate this with the previous string. */ + PyUnicode_AppendAndDel(&state->last_str, str); + if (!state->last_str) + return -1; + } + FstringParser_check_invariants(state); + return 0; +} + +/* Parse an f-string. The f-string is in *str to end, with no + 'f' or quotes. */ +static int +FstringParser_ConcatFstring(FstringParser *state, const char **str, + const char *end, int raw, int recurse_lvl, + struct compiling *c, const node *n) +{ + FstringParser_check_invariants(state); + state->fmode = 1; + + /* Parse the f-string. */ + while (1) { + PyObject *literal = NULL; + PyObject *expr_text = NULL; + expr_ty expression = NULL; + + /* If there's a zero length literal in front of the + expression, literal will be NULL. If we're at the end of + the f-string, expression will be NULL (unless result == 1, + see below). */ + int result = fstring_find_literal_and_expr(str, end, raw, recurse_lvl, + &literal, &expr_text, + &expression, c, n); + if (result < 0) + return -1; + + /* Add the literal, if any. */ + if (literal && FstringParser_ConcatAndDel(state, literal) < 0) { + Py_XDECREF(expr_text); + return -1; + } + /* Add the expr_text, if any. */ + if (expr_text && FstringParser_ConcatAndDel(state, expr_text) < 0) { + return -1; + } + + /* We've dealt with the literal and expr_text, their ownership has + been transferred to the state object. Don't look at them again. */ + + /* See if we should just loop around to get the next literal + and expression, while ignoring the expression this + time. This is used for un-doubling braces, as an + optimization. */ + if (result == 1) + continue; + + if (!expression) + /* We're done with this f-string. */ + break; + + /* We know we have an expression. Convert any existing string + to a Constant node. */ + if (!state->last_str) { + /* Do nothing. No previous literal. */ + } else { + /* Convert the existing last_str literal to a Constant node. */ + expr_ty str = make_str_node_and_del(&state->last_str, c, n); + if (!str || ExprList_Append(&state->expr_list, str) < 0) + return -1; + } + + if (ExprList_Append(&state->expr_list, expression) < 0) + return -1; + } + + /* If recurse_lvl is zero, then we must be at the end of the + string. Otherwise, we must be at a right brace. */ + + if (recurse_lvl == 0 && *str < end-1) { + ast_error(c, n, "f-string: unexpected end of string"); + return -1; + } + if (recurse_lvl != 0 && **str != '}') { + ast_error(c, n, "f-string: expecting '}'"); + return -1; + } + + FstringParser_check_invariants(state); + return 0; +} + +/* Convert the partial state reflected in last_str and expr_list to an + expr_ty. The expr_ty can be a Constant, or a JoinedStr. */ +static expr_ty +FstringParser_Finish(FstringParser *state, struct compiling *c, + const node *n) +{ + asdl_seq *seq; + + FstringParser_check_invariants(state); + + /* If we're just a constant string with no expressions, return + that. */ + if (!state->fmode) { + assert(!state->expr_list.size); + if (!state->last_str) { + /* Create a zero length string. */ + state->last_str = PyUnicode_FromStringAndSize(NULL, 0); + if (!state->last_str) + goto error; + } + return make_str_node_and_del(&state->last_str, c, n); + } + + /* Create a Constant node out of last_str, if needed. It will be the + last node in our expression list. */ + if (state->last_str) { + expr_ty str = make_str_node_and_del(&state->last_str, c, n); + if (!str || ExprList_Append(&state->expr_list, str) < 0) + goto error; + } + /* This has already been freed. */ + assert(state->last_str == NULL); + + seq = ExprList_Finish(&state->expr_list, c->c_arena); + if (!seq) + goto error; + + return JoinedStr(seq, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + +error: + FstringParser_Dealloc(state); + return NULL; +} + +/* Given an f-string (with no 'f' or quotes) that's in *str and ends + at end, parse it into an expr_ty. Return NULL on error. Adjust + str to point past the parsed portion. */ +static expr_ty +fstring_parse(const char **str, const char *end, int raw, int recurse_lvl, + struct compiling *c, const node *n) +{ + FstringParser state; + + FstringParser_Init(&state); + if (FstringParser_ConcatFstring(&state, str, end, raw, recurse_lvl, + c, n) < 0) { + FstringParser_Dealloc(&state); + return NULL; + } + + return FstringParser_Finish(&state, c, n); +} + +/* n is a Python string literal, including the bracketing quote + characters, and r, b, u, &/or f prefixes (if any), and embedded + escape sequences (if any). parsestr parses it, and sets *result to + decoded Python string object. If the string is an f-string, set + *fstr and *fstrlen to the unparsed string object. Return 0 if no + errors occurred. +*/ +static int +parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode, + PyObject **result, const char **fstr, Py_ssize_t *fstrlen) +{ + size_t len; + const char *s = STR(n); + int quote = Py_CHARMASK(*s); + int fmode = 0; + *bytesmode = 0; + *rawmode = 0; + *result = NULL; + *fstr = NULL; + if (Py_ISALPHA(quote)) { + while (!*bytesmode || !*rawmode) { + if (quote == 'b' || quote == 'B') { + quote = *++s; + *bytesmode = 1; + } + else if (quote == 'u' || quote == 'U') { + quote = *++s; + } + else if (quote == 'r' || quote == 'R') { + quote = *++s; + *rawmode = 1; + } + else if (quote == 'f' || quote == 'F') { + quote = *++s; + fmode = 1; + } + else { + break; + } + } + } + + /* fstrings are only allowed in Python 3.6 and greater */ + if (fmode && c->c_feature_version < 6) { + ast_error(c, n, "Format strings are only supported in Python 3.6 and greater"); + return -1; + } + + if (fmode && *bytesmode) { + PyErr_BadInternalCall(); + return -1; + } + if (quote != '\'' && quote != '\"') { + PyErr_BadInternalCall(); + return -1; + } + /* Skip the leading quote char. */ + s++; + len = strlen(s); + if (len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "string to parse is too long"); + return -1; + } + if (s[--len] != quote) { + /* Last quote char must match the first. */ + PyErr_BadInternalCall(); + return -1; + } + if (len >= 4 && s[0] == quote && s[1] == quote) { + /* A triple quoted string. We've already skipped one quote at + the start and one at the end of the string. Now skip the + two at the start. */ + s += 2; + len -= 2; + /* And check that the last two match. */ + if (s[--len] != quote || s[--len] != quote) { + PyErr_BadInternalCall(); + return -1; + } + } + + if (fmode) { + /* Just return the bytes. The caller will parse the resulting + string. */ + *fstr = s; + *fstrlen = len; + return 0; + } + + /* Not an f-string. */ + /* Avoid invoking escape decoding routines if possible. */ + *rawmode = *rawmode || strchr(s, '\\') == NULL; + if (*bytesmode) { + /* Disallow non-ASCII characters. */ + const char *ch; + for (ch = s; *ch; ch++) { + if (Py_CHARMASK(*ch) >= 0x80) { + ast_error(c, n, + "bytes can only contain ASCII " + "literal characters."); + return -1; + } + } + if (*rawmode) + *result = PyBytes_FromStringAndSize(s, len); + else + *result = decode_bytes_with_escapes(c, n, s, len); + } else { + if (*rawmode) + *result = PyUnicode_DecodeUTF8Stateful(s, len, NULL, NULL); + else + *result = decode_unicode_with_escapes(c, n, s, len); + } + return *result == NULL ? -1 : 0; +} + +/* Accepts a STRING+ atom, and produces an expr_ty node. Run through + each STRING atom, and process it as needed. For bytes, just + concatenate them together, and the result will be a Constant node. For + normal strings and f-strings, concatenate them together. The result + will be a Constant node if there were no f-strings; a FormattedValue + node if there's just an f-string (with no leading or trailing + literals), or a JoinedStr node if there are multiple f-strings or + any literals involved. */ +static expr_ty +parsestrplus(struct compiling *c, const node *n) +{ + int bytesmode = 0; + PyObject *bytes_str = NULL; + int i; + + FstringParser state; + FstringParser_Init(&state); + + for (i = 0; i < NCH(n); i++) { + int this_bytesmode; + int this_rawmode; + PyObject *s; + const char *fstr; + Py_ssize_t fstrlen = -1; /* Silence a compiler warning. */ + + REQ(CHILD(n, i), STRING); + if (parsestr(c, CHILD(n, i), &this_bytesmode, &this_rawmode, &s, + &fstr, &fstrlen) != 0) + goto error; + + /* Check that we're not mixing bytes with unicode. */ + if (i != 0 && bytesmode != this_bytesmode) { + ast_error(c, n, "cannot mix bytes and nonbytes literals"); + /* s is NULL if the current string part is an f-string. */ + Py_XDECREF(s); + goto error; + } + bytesmode = this_bytesmode; + + if (fstr != NULL) { + int result; + assert(s == NULL && !bytesmode); + /* This is an f-string. Parse and concatenate it. */ + result = FstringParser_ConcatFstring(&state, &fstr, fstr+fstrlen, + this_rawmode, 0, c, n); + if (result < 0) + goto error; + } else { + /* A string or byte string. */ + assert(s != NULL && fstr == NULL); + + assert(bytesmode ? PyBytes_CheckExact(s) : + PyUnicode_CheckExact(s)); + + if (bytesmode) { + /* For bytes, concat as we go. */ + if (i == 0) { + /* First time, just remember this value. */ + bytes_str = s; + } else { + PyBytes_ConcatAndDel(&bytes_str, s); + if (!bytes_str) + goto error; + } + } else { + /* This is a regular string. Concatenate it. */ + if (FstringParser_ConcatAndDel(&state, s) < 0) + goto error; + } + } + } + if (bytesmode) { + /* Just return the bytes object and we're done. */ + if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0) + goto error; + return Constant(bytes_str, NULL, LINENO(n), n->n_col_offset, + n->n_end_lineno, n->n_end_col_offset, c->c_arena); + } + + /* We're not a bytes string, bytes_str should never have been set. */ + assert(bytes_str == NULL); + + return FstringParser_Finish(&state, c, n); + +error: + Py_XDECREF(bytes_str); + FstringParser_Dealloc(&state); + return NULL; +} + +PyObject * +_PyAST_GetDocString(asdl_seq *body) +{ + if (!asdl_seq_LEN(body)) { + return NULL; + } + stmt_ty st = (stmt_ty)asdl_seq_GET(body, 0); + if (st->kind != Expr_kind) { + return NULL; + } + expr_ty e = st->v.Expr.value; + if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) { + return e->v.Constant.value; + } + return NULL; +} diff --git a/python/Python/ast_opt.c b/python/Python/ast_opt.c new file mode 100755 index 0000000..f2a2c25 --- /dev/null +++ b/python/Python/ast_opt.c @@ -0,0 +1,766 @@ +/* AST Optimizer */ +#include "Python.h" +#include "Python-ast.h" +#include "ast.h" + + +static int +make_const(expr_ty node, PyObject *val, PyArena *arena) +{ + if (val == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) { + return 0; + } + PyErr_Clear(); + return 1; + } + if (PyArena_AddPyObject(arena, val) < 0) { + Py_DECREF(val); + return 0; + } + node->kind = Constant_kind; + node->v.Constant.value = val; + return 1; +} + +#define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr))) + +static PyObject* +unary_not(PyObject *v) +{ + int r = PyObject_IsTrue(v); + if (r < 0) + return NULL; + return PyBool_FromLong(!r); +} + +static int +fold_unaryop(expr_ty node, PyArena *arena, int optimize) +{ + expr_ty arg = node->v.UnaryOp.operand; + + if (arg->kind != Constant_kind) { + /* Fold not into comparison */ + if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind && + asdl_seq_LEN(arg->v.Compare.ops) == 1) { + /* Eq and NotEq are often implemented in terms of one another, so + folding not (self == other) into self != other breaks implementation + of !=. Detecting such cases doesn't seem worthwhile. + Python uses for 'is subset'/'is superset' operations on sets. + They don't satisfy not folding laws. */ + int op = asdl_seq_GET(arg->v.Compare.ops, 0); + switch (op) { + case Is: + op = IsNot; + break; + case IsNot: + op = Is; + break; + case In: + op = NotIn; + break; + case NotIn: + op = In; + break; + default: + op = 0; + } + if (op) { + asdl_seq_SET(arg->v.Compare.ops, 0, op); + COPY_NODE(node, arg); + return 1; + } + } + return 1; + } + + typedef PyObject *(*unary_op)(PyObject*); + static const unary_op ops[] = { + [Invert] = PyNumber_Invert, + [Not] = unary_not, + [UAdd] = PyNumber_Positive, + [USub] = PyNumber_Negative, + }; + PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value); + return make_const(node, newval, arena); +} + +/* Check whether a collection doesn't containing too much items (including + subcollections). This protects from creating a constant that needs + too much time for calculating a hash. + "limit" is the maximal number of items. + Returns the negative number if the total number of items exceeds the + limit. Otherwise returns the limit minus the total number of items. +*/ + +static Py_ssize_t +check_complexity(PyObject *obj, Py_ssize_t limit) +{ + if (PyTuple_Check(obj)) { + Py_ssize_t i; + limit -= PyTuple_GET_SIZE(obj); + for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) { + limit = check_complexity(PyTuple_GET_ITEM(obj, i), limit); + } + return limit; + } + else if (PyFrozenSet_Check(obj)) { + Py_ssize_t i = 0; + PyObject *item; + Py_hash_t hash; + limit -= PySet_GET_SIZE(obj); + while (limit >= 0 && _PySet_NextEntry(obj, &i, &item, &hash)) { + limit = check_complexity(item, limit); + } + } + return limit; +} + +#define MAX_INT_SIZE 128 /* bits */ +#define MAX_COLLECTION_SIZE 256 /* items */ +#define MAX_STR_SIZE 4096 /* characters */ +#define MAX_TOTAL_ITEMS 1024 /* including nested collections */ + +static PyObject * +safe_multiply(PyObject *v, PyObject *w) +{ + if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { + size_t vbits = _PyLong_NumBits(v); + size_t wbits = _PyLong_NumBits(w); + if (vbits == (size_t)-1 || wbits == (size_t)-1) { + return NULL; + } + if (vbits + wbits > MAX_INT_SIZE) { + return NULL; + } + } + else if (PyLong_Check(v) && (PyTuple_Check(w) || PyFrozenSet_Check(w))) { + Py_ssize_t size = PyTuple_Check(w) ? PyTuple_GET_SIZE(w) : + PySet_GET_SIZE(w); + if (size) { + long n = PyLong_AsLong(v); + if (n < 0 || n > MAX_COLLECTION_SIZE / size) { + return NULL; + } + if (n && check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) { + return NULL; + } + } + } + else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) { + Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) : + PyBytes_GET_SIZE(w); + if (size) { + long n = PyLong_AsLong(v); + if (n < 0 || n > MAX_STR_SIZE / size) { + return NULL; + } + } + } + else if (PyLong_Check(w) && + (PyTuple_Check(v) || PyFrozenSet_Check(v) || + PyUnicode_Check(v) || PyBytes_Check(v))) + { + return safe_multiply(w, v); + } + + return PyNumber_Multiply(v, w); +} + +static PyObject * +safe_power(PyObject *v, PyObject *w) +{ + if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w) > 0) { + size_t vbits = _PyLong_NumBits(v); + size_t wbits = PyLong_AsSize_t(w); + if (vbits == (size_t)-1 || wbits == (size_t)-1) { + return NULL; + } + if (vbits > MAX_INT_SIZE / wbits) { + return NULL; + } + } + + return PyNumber_Power(v, w, Py_None); +} + +static PyObject * +safe_lshift(PyObject *v, PyObject *w) +{ + if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { + size_t vbits = _PyLong_NumBits(v); + size_t wbits = PyLong_AsSize_t(w); + if (vbits == (size_t)-1 || wbits == (size_t)-1) { + return NULL; + } + if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) { + return NULL; + } + } + + return PyNumber_Lshift(v, w); +} + +static PyObject * +safe_mod(PyObject *v, PyObject *w) +{ + if (PyUnicode_Check(v) || PyBytes_Check(v)) { + return NULL; + } + + return PyNumber_Remainder(v, w); +} + +static int +fold_binop(expr_ty node, PyArena *arena, int optimize) +{ + expr_ty lhs, rhs; + lhs = node->v.BinOp.left; + rhs = node->v.BinOp.right; + if (lhs->kind != Constant_kind || rhs->kind != Constant_kind) { + return 1; + } + + PyObject *lv = lhs->v.Constant.value; + PyObject *rv = rhs->v.Constant.value; + PyObject *newval; + + switch (node->v.BinOp.op) { + case Add: + newval = PyNumber_Add(lv, rv); + break; + case Sub: + newval = PyNumber_Subtract(lv, rv); + break; + case Mult: + newval = safe_multiply(lv, rv); + break; + case Div: + newval = PyNumber_TrueDivide(lv, rv); + break; + case FloorDiv: + newval = PyNumber_FloorDivide(lv, rv); + break; + case Mod: + newval = safe_mod(lv, rv); + break; + case Pow: + newval = safe_power(lv, rv); + break; + case LShift: + newval = safe_lshift(lv, rv); + break; + case RShift: + newval = PyNumber_Rshift(lv, rv); + break; + case BitOr: + newval = PyNumber_Or(lv, rv); + break; + case BitXor: + newval = PyNumber_Xor(lv, rv); + break; + case BitAnd: + newval = PyNumber_And(lv, rv); + break; + default: // Unknown operator + return 1; + } + + return make_const(node, newval, arena); +} + +static PyObject* +make_const_tuple(asdl_seq *elts) +{ + for (int i = 0; i < asdl_seq_LEN(elts); i++) { + expr_ty e = (expr_ty)asdl_seq_GET(elts, i); + if (e->kind != Constant_kind) { + return NULL; + } + } + + PyObject *newval = PyTuple_New(asdl_seq_LEN(elts)); + if (newval == NULL) { + return NULL; + } + + for (int i = 0; i < asdl_seq_LEN(elts); i++) { + expr_ty e = (expr_ty)asdl_seq_GET(elts, i); + PyObject *v = e->v.Constant.value; + Py_INCREF(v); + PyTuple_SET_ITEM(newval, i, v); + } + return newval; +} + +static int +fold_tuple(expr_ty node, PyArena *arena, int optimize) +{ + PyObject *newval; + + if (node->v.Tuple.ctx != Load) + return 1; + + newval = make_const_tuple(node->v.Tuple.elts); + return make_const(node, newval, arena); +} + +static int +fold_subscr(expr_ty node, PyArena *arena, int optimize) +{ + PyObject *newval; + expr_ty arg, idx; + slice_ty slice; + + arg = node->v.Subscript.value; + slice = node->v.Subscript.slice; + if (node->v.Subscript.ctx != Load || + arg->kind != Constant_kind || + /* TODO: handle other types of slices */ + slice->kind != Index_kind || + slice->v.Index.value->kind != Constant_kind) + { + return 1; + } + + idx = slice->v.Index.value; + newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value); + return make_const(node, newval, arena); +} + +/* Change literal list or set of constants into constant + tuple or frozenset respectively. Change literal list of + non-constants into tuple. + Used for right operand of "in" and "not in" tests and for iterable + in "for" loop and comprehensions. +*/ +static int +fold_iter(expr_ty arg, PyArena *arena, int optimize) +{ + PyObject *newval; + if (arg->kind == List_kind) { + /* First change a list into tuple. */ + asdl_seq *elts = arg->v.List.elts; + Py_ssize_t n = asdl_seq_LEN(elts); + for (Py_ssize_t i = 0; i < n; i++) { + expr_ty e = (expr_ty)asdl_seq_GET(elts, i); + if (e->kind == Starred_kind) { + return 1; + } + } + expr_context_ty ctx = arg->v.List.ctx; + arg->kind = Tuple_kind; + arg->v.Tuple.elts = elts; + arg->v.Tuple.ctx = ctx; + /* Try to create a constant tuple. */ + newval = make_const_tuple(elts); + } + else if (arg->kind == Set_kind) { + newval = make_const_tuple(arg->v.Set.elts); + if (newval) { + Py_SETREF(newval, PyFrozenSet_New(newval)); + } + } + else { + return 1; + } + return make_const(arg, newval, arena); +} + +static int +fold_compare(expr_ty node, PyArena *arena, int optimize) +{ + asdl_int_seq *ops; + asdl_seq *args; + Py_ssize_t i; + + ops = node->v.Compare.ops; + args = node->v.Compare.comparators; + /* TODO: optimize cases with literal arguments. */ + /* Change literal list or set in 'in' or 'not in' into + tuple or frozenset respectively. */ + i = asdl_seq_LEN(ops) - 1; + int op = asdl_seq_GET(ops, i); + if (op == In || op == NotIn) { + if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, optimize)) { + return 0; + } + } + return 1; +} + +static int astfold_mod(mod_ty node_, PyArena *ctx_, int optimize_); +static int astfold_stmt(stmt_ty node_, PyArena *ctx_, int optimize_); +static int astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_); +static int astfold_arguments(arguments_ty node_, PyArena *ctx_, int optimize_); +static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, int optimize_); +static int astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_); +static int astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_); +static int astfold_arg(arg_ty node_, PyArena *ctx_, int optimize_); +static int astfold_withitem(withitem_ty node_, PyArena *ctx_, int optimize_); +static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int optimize_); +#define CALL(FUNC, TYPE, ARG) \ + if (!FUNC((ARG), ctx_, optimize_)) \ + return 0; + +#define CALL_OPT(FUNC, TYPE, ARG) \ + if ((ARG) != NULL && !FUNC((ARG), ctx_, optimize_)) \ + return 0; + +#define CALL_SEQ(FUNC, TYPE, ARG) { \ + int i; \ + asdl_seq *seq = (ARG); /* avoid variable capture */ \ + for (i = 0; i < asdl_seq_LEN(seq); i++) { \ + TYPE elt = (TYPE)asdl_seq_GET(seq, i); \ + if (elt != NULL && !FUNC(elt, ctx_, optimize_)) \ + return 0; \ + } \ +} + +#define CALL_INT_SEQ(FUNC, TYPE, ARG) { \ + int i; \ + asdl_int_seq *seq = (ARG); /* avoid variable capture */ \ + for (i = 0; i < asdl_seq_LEN(seq); i++) { \ + TYPE elt = (TYPE)asdl_seq_GET(seq, i); \ + if (!FUNC(elt, ctx_, optimize_)) \ + return 0; \ + } \ +} + +static int +astfold_body(asdl_seq *stmts, PyArena *ctx_, int optimize_) +{ + int docstring = _PyAST_GetDocString(stmts) != NULL; + CALL_SEQ(astfold_stmt, stmt_ty, stmts); + if (!docstring && _PyAST_GetDocString(stmts) != NULL) { + stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0); + asdl_seq *values = _Py_asdl_seq_new(1, ctx_); + if (!values) { + return 0; + } + asdl_seq_SET(values, 0, st->v.Expr.value); + expr_ty expr = JoinedStr(values, st->lineno, st->col_offset, + st->end_lineno, st->end_col_offset, ctx_); + if (!expr) { + return 0; + } + st->v.Expr.value = expr; + } + return 1; +} + +static int +astfold_mod(mod_ty node_, PyArena *ctx_, int optimize_) +{ + switch (node_->kind) { + case Module_kind: + CALL(astfold_body, asdl_seq, node_->v.Module.body); + break; + case Interactive_kind: + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Interactive.body); + break; + case Expression_kind: + CALL(astfold_expr, expr_ty, node_->v.Expression.body); + break; + case Suite_kind: + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Suite.body); + break; + default: + break; + } + return 1; +} + +static int +astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_) +{ + switch (node_->kind) { + case BoolOp_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.BoolOp.values); + break; + case BinOp_kind: + CALL(astfold_expr, expr_ty, node_->v.BinOp.left); + CALL(astfold_expr, expr_ty, node_->v.BinOp.right); + CALL(fold_binop, expr_ty, node_); + break; + case UnaryOp_kind: + CALL(astfold_expr, expr_ty, node_->v.UnaryOp.operand); + CALL(fold_unaryop, expr_ty, node_); + break; + case Lambda_kind: + CALL(astfold_arguments, arguments_ty, node_->v.Lambda.args); + CALL(astfold_expr, expr_ty, node_->v.Lambda.body); + break; + case IfExp_kind: + CALL(astfold_expr, expr_ty, node_->v.IfExp.test); + CALL(astfold_expr, expr_ty, node_->v.IfExp.body); + CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse); + break; + case Dict_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.keys); + CALL_SEQ(astfold_expr, expr_ty, node_->v.Dict.values); + break; + case Set_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.Set.elts); + break; + case ListComp_kind: + CALL(astfold_expr, expr_ty, node_->v.ListComp.elt); + CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.ListComp.generators); + break; + case SetComp_kind: + CALL(astfold_expr, expr_ty, node_->v.SetComp.elt); + CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.SetComp.generators); + break; + case DictComp_kind: + CALL(astfold_expr, expr_ty, node_->v.DictComp.key); + CALL(astfold_expr, expr_ty, node_->v.DictComp.value); + CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.DictComp.generators); + break; + case GeneratorExp_kind: + CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt); + CALL_SEQ(astfold_comprehension, comprehension_ty, node_->v.GeneratorExp.generators); + break; + case Await_kind: + CALL(astfold_expr, expr_ty, node_->v.Await.value); + break; + case Yield_kind: + CALL_OPT(astfold_expr, expr_ty, node_->v.Yield.value); + break; + case YieldFrom_kind: + CALL(astfold_expr, expr_ty, node_->v.YieldFrom.value); + break; + case Compare_kind: + CALL(astfold_expr, expr_ty, node_->v.Compare.left); + CALL_SEQ(astfold_expr, expr_ty, node_->v.Compare.comparators); + CALL(fold_compare, expr_ty, node_); + break; + case Call_kind: + CALL(astfold_expr, expr_ty, node_->v.Call.func); + CALL_SEQ(astfold_expr, expr_ty, node_->v.Call.args); + CALL_SEQ(astfold_keyword, keyword_ty, node_->v.Call.keywords); + break; + case FormattedValue_kind: + CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value); + CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec); + break; + case JoinedStr_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.JoinedStr.values); + break; + case Attribute_kind: + CALL(astfold_expr, expr_ty, node_->v.Attribute.value); + break; + case Subscript_kind: + CALL(astfold_expr, expr_ty, node_->v.Subscript.value); + CALL(astfold_slice, slice_ty, node_->v.Subscript.slice); + CALL(fold_subscr, expr_ty, node_); + break; + case Starred_kind: + CALL(astfold_expr, expr_ty, node_->v.Starred.value); + break; + case List_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.List.elts); + break; + case Tuple_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.Tuple.elts); + CALL(fold_tuple, expr_ty, node_); + break; + case Name_kind: + if (_PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) { + return make_const(node_, PyBool_FromLong(!optimize_), ctx_); + } + break; + default: + break; + } + return 1; +} + +static int +astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_) +{ + switch (node_->kind) { + case Slice_kind: + CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower); + CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper); + CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step); + break; + case ExtSlice_kind: + CALL_SEQ(astfold_slice, slice_ty, node_->v.ExtSlice.dims); + break; + case Index_kind: + CALL(astfold_expr, expr_ty, node_->v.Index.value); + break; + default: + break; + } + return 1; +} + +static int +astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_) +{ + CALL(astfold_expr, expr_ty, node_->value); + return 1; +} + +static int +astfold_comprehension(comprehension_ty node_, PyArena *ctx_, int optimize_) +{ + CALL(astfold_expr, expr_ty, node_->target); + CALL(astfold_expr, expr_ty, node_->iter); + CALL_SEQ(astfold_expr, expr_ty, node_->ifs); + + CALL(fold_iter, expr_ty, node_->iter); + return 1; +} + +static int +astfold_arguments(arguments_ty node_, PyArena *ctx_, int optimize_) +{ + CALL_SEQ(astfold_arg, arg_ty, node_->posonlyargs); + CALL_SEQ(astfold_arg, arg_ty, node_->args); + CALL_OPT(astfold_arg, arg_ty, node_->vararg); + CALL_SEQ(astfold_arg, arg_ty, node_->kwonlyargs); + CALL_SEQ(astfold_expr, expr_ty, node_->kw_defaults); + CALL_OPT(astfold_arg, arg_ty, node_->kwarg); + CALL_SEQ(astfold_expr, expr_ty, node_->defaults); + return 1; +} + +static int +astfold_arg(arg_ty node_, PyArena *ctx_, int optimize_) +{ + CALL_OPT(astfold_expr, expr_ty, node_->annotation); + return 1; +} + +static int +astfold_stmt(stmt_ty node_, PyArena *ctx_, int optimize_) +{ + switch (node_->kind) { + case FunctionDef_kind: + CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args); + CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body); + CALL_SEQ(astfold_expr, expr_ty, node_->v.FunctionDef.decorator_list); + CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns); + break; + case AsyncFunctionDef_kind: + CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args); + CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body); + CALL_SEQ(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.decorator_list); + CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns); + break; + case ClassDef_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.bases); + CALL_SEQ(astfold_keyword, keyword_ty, node_->v.ClassDef.keywords); + CALL(astfold_body, asdl_seq, node_->v.ClassDef.body); + CALL_SEQ(astfold_expr, expr_ty, node_->v.ClassDef.decorator_list); + break; + case Return_kind: + CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value); + break; + case Delete_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.Delete.targets); + break; + case Assign_kind: + CALL_SEQ(astfold_expr, expr_ty, node_->v.Assign.targets); + CALL(astfold_expr, expr_ty, node_->v.Assign.value); + break; + case AugAssign_kind: + CALL(astfold_expr, expr_ty, node_->v.AugAssign.target); + CALL(astfold_expr, expr_ty, node_->v.AugAssign.value); + break; + case AnnAssign_kind: + CALL(astfold_expr, expr_ty, node_->v.AnnAssign.target); + CALL(astfold_expr, expr_ty, node_->v.AnnAssign.annotation); + CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value); + break; + case For_kind: + CALL(astfold_expr, expr_ty, node_->v.For.target); + CALL(astfold_expr, expr_ty, node_->v.For.iter); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.body); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.For.orelse); + + CALL(fold_iter, expr_ty, node_->v.For.iter); + break; + case AsyncFor_kind: + CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target); + CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.body); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncFor.orelse); + break; + case While_kind: + CALL(astfold_expr, expr_ty, node_->v.While.test); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.body); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.While.orelse); + break; + case If_kind: + CALL(astfold_expr, expr_ty, node_->v.If.test); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.body); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.If.orelse); + break; + case With_kind: + CALL_SEQ(astfold_withitem, withitem_ty, node_->v.With.items); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.With.body); + break; + case AsyncWith_kind: + CALL_SEQ(astfold_withitem, withitem_ty, node_->v.AsyncWith.items); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.AsyncWith.body); + break; + case Raise_kind: + CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc); + CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause); + break; + case Try_kind: + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.body); + CALL_SEQ(astfold_excepthandler, excepthandler_ty, node_->v.Try.handlers); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.orelse); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.Try.finalbody); + break; + case Assert_kind: + CALL(astfold_expr, expr_ty, node_->v.Assert.test); + CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg); + break; + case Expr_kind: + CALL(astfold_expr, expr_ty, node_->v.Expr.value); + break; + default: + break; + } + return 1; +} + +static int +astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int optimize_) +{ + switch (node_->kind) { + case ExceptHandler_kind: + CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type); + CALL_SEQ(astfold_stmt, stmt_ty, node_->v.ExceptHandler.body); + break; + default: + break; + } + return 1; +} + +static int +astfold_withitem(withitem_ty node_, PyArena *ctx_, int optimize_) +{ + CALL(astfold_expr, expr_ty, node_->context_expr); + CALL_OPT(astfold_expr, expr_ty, node_->optional_vars); + return 1; +} + +#undef CALL +#undef CALL_OPT +#undef CALL_SEQ +#undef CALL_INT_SEQ + +int +_PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize) +{ + int ret = astfold_mod(mod, arena, optimize); + assert(ret || PyErr_Occurred()); + return ret; +} diff --git a/python/Python/ast_unparse.c b/python/Python/ast_unparse.c new file mode 100755 index 0000000..af9604e --- /dev/null +++ b/python/Python/ast_unparse.c @@ -0,0 +1,955 @@ +#include +#include "Python.h" +#include "Python-ast.h" + +static PyObject *_str_open_br; +static PyObject *_str_dbl_open_br; +static PyObject *_str_close_br; +static PyObject *_str_dbl_close_br; + +/* Forward declarations for recursion via helper functions. */ +static PyObject * +expr_as_unicode(expr_ty e, int level); +static int +append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level); +static int +append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec); +static int +append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec); +static int +append_ast_slice(_PyUnicodeWriter *writer, slice_ty slice); + +static int +append_charp(_PyUnicodeWriter *writer, const char *charp) +{ + return _PyUnicodeWriter_WriteASCIIString(writer, charp, -1); +} + +#define APPEND_STR_FINISH(str) do { \ + return append_charp(writer, (str)); \ + } while (0) + +#define APPEND_STR(str) do { \ + if (-1 == append_charp(writer, (str))) { \ + return -1; \ + } \ + } while (0) + +#define APPEND_STR_IF(cond, str) do { \ + if ((cond) && -1 == append_charp(writer, (str))) { \ + return -1; \ + } \ + } while (0) + +#define APPEND_STR_IF_NOT_FIRST(str) do { \ + APPEND_STR_IF(!first, (str)); \ + first = false; \ + } while (0) + +#define APPEND_EXPR(expr, pr) do { \ + if (-1 == append_ast_expr(writer, (expr), (pr))) { \ + return -1; \ + } \ + } while (0) + +#define APPEND(type, value) do { \ + if (-1 == append_ast_ ## type(writer, (value))) { \ + return -1; \ + } \ + } while (0) + +static int +append_repr(_PyUnicodeWriter *writer, PyObject *obj) +{ + int ret; + PyObject *repr; + repr = PyObject_Repr(obj); + if (!repr) { + return -1; + } + ret = _PyUnicodeWriter_WriteStr(writer, repr); + Py_DECREF(repr); + return ret; +} + +/* Priority levels */ + +enum { + PR_TUPLE, + PR_TEST, /* 'if'-'else', 'lambda' */ + PR_OR, /* 'or' */ + PR_AND, /* 'and' */ + PR_NOT, /* 'not' */ + PR_CMP, /* '<', '>', '==', '>=', '<=', '!=', + 'in', 'not in', 'is', 'is not' */ + PR_EXPR, + PR_BOR = PR_EXPR, /* '|' */ + PR_BXOR, /* '^' */ + PR_BAND, /* '&' */ + PR_SHIFT, /* '<<', '>>' */ + PR_ARITH, /* '+', '-' */ + PR_TERM, /* '*', '@', '/', '%', '//' */ + PR_FACTOR, /* unary '+', '-', '~' */ + PR_POWER, /* '**' */ + PR_AWAIT, /* 'await' */ + PR_ATOM, +}; + +static int +append_ast_boolop(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + Py_ssize_t i, value_count; + asdl_seq *values; + const char *op = (e->v.BoolOp.op == And) ? " and " : " or "; + int pr = (e->v.BoolOp.op == And) ? PR_AND : PR_OR; + + APPEND_STR_IF(level > pr, "("); + + values = e->v.BoolOp.values; + value_count = asdl_seq_LEN(values); + + for (i = 0; i < value_count; ++i) { + APPEND_STR_IF(i > 0, op); + APPEND_EXPR((expr_ty)asdl_seq_GET(values, i), pr + 1); + } + + APPEND_STR_IF(level > pr, ")"); + return 0; +} + +static int +append_ast_binop(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + const char *op; + int pr; + bool rassoc = false; /* is right-associative? */ + + switch (e->v.BinOp.op) { + case Add: op = " + "; pr = PR_ARITH; break; + case Sub: op = " - "; pr = PR_ARITH; break; + case Mult: op = " * "; pr = PR_TERM; break; + case MatMult: op = " @ "; pr = PR_TERM; break; + case Div: op = " / "; pr = PR_TERM; break; + case Mod: op = " % "; pr = PR_TERM; break; + case LShift: op = " << "; pr = PR_SHIFT; break; + case RShift: op = " >> "; pr = PR_SHIFT; break; + case BitOr: op = " | "; pr = PR_BOR; break; + case BitXor: op = " ^ "; pr = PR_BXOR; break; + case BitAnd: op = " & "; pr = PR_BAND; break; + case FloorDiv: op = " // "; pr = PR_TERM; break; + case Pow: op = " ** "; pr = PR_POWER; rassoc = true; break; + default: + PyErr_SetString(PyExc_SystemError, + "unknown binary operator"); + return -1; + } + + APPEND_STR_IF(level > pr, "("); + APPEND_EXPR(e->v.BinOp.left, pr + rassoc); + APPEND_STR(op); + APPEND_EXPR(e->v.BinOp.right, pr + !rassoc); + APPEND_STR_IF(level > pr, ")"); + return 0; +} + +static int +append_ast_unaryop(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + const char *op; + int pr; + + switch (e->v.UnaryOp.op) { + case Invert: op = "~"; pr = PR_FACTOR; break; + case Not: op = "not "; pr = PR_NOT; break; + case UAdd: op = "+"; pr = PR_FACTOR; break; + case USub: op = "-"; pr = PR_FACTOR; break; + default: + PyErr_SetString(PyExc_SystemError, + "unknown unary operator"); + return -1; + } + + APPEND_STR_IF(level > pr, "("); + APPEND_STR(op); + APPEND_EXPR(e->v.UnaryOp.operand, pr); + APPEND_STR_IF(level > pr, ")"); + return 0; +} + +static int +append_ast_arg(_PyUnicodeWriter *writer, arg_ty arg) +{ + if (-1 == _PyUnicodeWriter_WriteStr(writer, arg->arg)) { + return -1; + } + if (arg->annotation) { + APPEND_STR(": "); + APPEND_EXPR(arg->annotation, PR_TEST); + } + return 0; +} + +static int +append_ast_args(_PyUnicodeWriter *writer, arguments_ty args) +{ + bool first; + Py_ssize_t i, di, arg_count, posonlyarg_count, default_count; + + first = true; + + /* positional-only and positional arguments with defaults */ + posonlyarg_count = asdl_seq_LEN(args->posonlyargs); + arg_count = asdl_seq_LEN(args->args); + default_count = asdl_seq_LEN(args->defaults); + for (i = 0; i < posonlyarg_count + arg_count; i++) { + APPEND_STR_IF_NOT_FIRST(", "); + if (i < posonlyarg_count){ + APPEND(arg, (arg_ty)asdl_seq_GET(args->posonlyargs, i)); + } else { + APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i-posonlyarg_count)); + } + + di = i - posonlyarg_count - arg_count + default_count; + if (di >= 0) { + APPEND_STR("="); + APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST); + } + if (posonlyarg_count && i + 1 == posonlyarg_count) { + APPEND_STR(", /"); + } + } + + /* vararg, or bare '*' if no varargs but keyword-only arguments present */ + if (args->vararg || asdl_seq_LEN(args->kwonlyargs)) { + APPEND_STR_IF_NOT_FIRST(", "); + APPEND_STR("*"); + if (args->vararg) { + APPEND(arg, args->vararg); + } + } + + /* keyword-only arguments */ + arg_count = asdl_seq_LEN(args->kwonlyargs); + default_count = asdl_seq_LEN(args->kw_defaults); + for (i = 0; i < arg_count; i++) { + APPEND_STR_IF_NOT_FIRST(", "); + APPEND(arg, (arg_ty)asdl_seq_GET(args->kwonlyargs, i)); + + di = i - arg_count + default_count; + if (di >= 0) { + expr_ty default_ = (expr_ty)asdl_seq_GET(args->kw_defaults, di); + if (default_) { + APPEND_STR("="); + APPEND_EXPR(default_, PR_TEST); + } + } + } + + /* **kwargs */ + if (args->kwarg) { + APPEND_STR_IF_NOT_FIRST(", "); + APPEND_STR("**"); + APPEND(arg, args->kwarg); + } + + return 0; +} + +static int +append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + APPEND_STR_IF(level > PR_TEST, "("); + Py_ssize_t n_positional = (asdl_seq_LEN(e->v.Lambda.args->args) + + asdl_seq_LEN(e->v.Lambda.args->posonlyargs)); + APPEND_STR(n_positional ? "lambda " : "lambda"); + APPEND(args, e->v.Lambda.args); + APPEND_STR(": "); + APPEND_EXPR(e->v.Lambda.body, PR_TEST); + APPEND_STR_IF(level > PR_TEST, ")"); + return 0; +} + +static int +append_ast_ifexp(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + APPEND_STR_IF(level > PR_TEST, "("); + APPEND_EXPR(e->v.IfExp.body, PR_TEST + 1); + APPEND_STR(" if "); + APPEND_EXPR(e->v.IfExp.test, PR_TEST + 1); + APPEND_STR(" else "); + APPEND_EXPR(e->v.IfExp.orelse, PR_TEST); + APPEND_STR_IF(level > PR_TEST, ")"); + return 0; +} + +static int +append_ast_dict(_PyUnicodeWriter *writer, expr_ty e) +{ + Py_ssize_t i, value_count; + expr_ty key_node; + + APPEND_STR("{"); + value_count = asdl_seq_LEN(e->v.Dict.values); + + for (i = 0; i < value_count; i++) { + APPEND_STR_IF(i > 0, ", "); + key_node = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i); + if (key_node != NULL) { + APPEND_EXPR(key_node, PR_TEST); + APPEND_STR(": "); + APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_TEST); + } + else { + APPEND_STR("**"); + APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Dict.values, i), PR_EXPR); + } + } + + APPEND_STR_FINISH("}"); +} + +static int +append_ast_set(_PyUnicodeWriter *writer, expr_ty e) +{ + Py_ssize_t i, elem_count; + + APPEND_STR("{"); + elem_count = asdl_seq_LEN(e->v.Set.elts); + for (i = 0; i < elem_count; i++) { + APPEND_STR_IF(i > 0, ", "); + APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Set.elts, i), PR_TEST); + } + + APPEND_STR_FINISH("}"); +} + +static int +append_ast_list(_PyUnicodeWriter *writer, expr_ty e) +{ + Py_ssize_t i, elem_count; + + APPEND_STR("["); + elem_count = asdl_seq_LEN(e->v.List.elts); + for (i = 0; i < elem_count; i++) { + APPEND_STR_IF(i > 0, ", "); + APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.List.elts, i), PR_TEST); + } + + APPEND_STR_FINISH("]"); +} + +static int +append_ast_tuple(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + Py_ssize_t i, elem_count; + + elem_count = asdl_seq_LEN(e->v.Tuple.elts); + + if (elem_count == 0) { + APPEND_STR_FINISH("()"); + } + + APPEND_STR_IF(level > PR_TUPLE, "("); + + for (i = 0; i < elem_count; i++) { + APPEND_STR_IF(i > 0, ", "); + APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Tuple.elts, i), PR_TEST); + } + + APPEND_STR_IF(elem_count == 1, ","); + APPEND_STR_IF(level > PR_TUPLE, ")"); + return 0; +} + +static int +append_ast_comprehension(_PyUnicodeWriter *writer, comprehension_ty gen) +{ + Py_ssize_t i, if_count; + + APPEND_STR(gen->is_async ? " async for " : " for "); + APPEND_EXPR(gen->target, PR_TUPLE); + APPEND_STR(" in "); + APPEND_EXPR(gen->iter, PR_TEST + 1); + + if_count = asdl_seq_LEN(gen->ifs); + for (i = 0; i < if_count; i++) { + APPEND_STR(" if "); + APPEND_EXPR((expr_ty)asdl_seq_GET(gen->ifs, i), PR_TEST + 1); + } + return 0; +} + +static int +append_ast_comprehensions(_PyUnicodeWriter *writer, asdl_seq *comprehensions) +{ + Py_ssize_t i, gen_count; + gen_count = asdl_seq_LEN(comprehensions); + + for (i = 0; i < gen_count; i++) { + APPEND(comprehension, (comprehension_ty)asdl_seq_GET(comprehensions, i)); + } + + return 0; +} + +static int +append_ast_genexp(_PyUnicodeWriter *writer, expr_ty e) +{ + APPEND_STR("("); + APPEND_EXPR(e->v.GeneratorExp.elt, PR_TEST); + APPEND(comprehensions, e->v.GeneratorExp.generators); + APPEND_STR_FINISH(")"); +} + +static int +append_ast_listcomp(_PyUnicodeWriter *writer, expr_ty e) +{ + APPEND_STR("["); + APPEND_EXPR(e->v.ListComp.elt, PR_TEST); + APPEND(comprehensions, e->v.ListComp.generators); + APPEND_STR_FINISH("]"); +} + +static int +append_ast_setcomp(_PyUnicodeWriter *writer, expr_ty e) +{ + APPEND_STR("{"); + APPEND_EXPR(e->v.SetComp.elt, PR_TEST); + APPEND(comprehensions, e->v.SetComp.generators); + APPEND_STR_FINISH("}"); +} + +static int +append_ast_dictcomp(_PyUnicodeWriter *writer, expr_ty e) +{ + APPEND_STR("{"); + APPEND_EXPR(e->v.DictComp.key, PR_TEST); + APPEND_STR(": "); + APPEND_EXPR(e->v.DictComp.value, PR_TEST); + APPEND(comprehensions, e->v.DictComp.generators); + APPEND_STR_FINISH("}"); +} + +static int +append_ast_compare(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + const char *op; + Py_ssize_t i, comparator_count; + asdl_seq *comparators; + asdl_int_seq *ops; + + APPEND_STR_IF(level > PR_CMP, "("); + + comparators = e->v.Compare.comparators; + ops = e->v.Compare.ops; + comparator_count = asdl_seq_LEN(comparators); + assert(comparator_count > 0); + assert(comparator_count == asdl_seq_LEN(ops)); + + APPEND_EXPR(e->v.Compare.left, PR_CMP + 1); + + for (i = 0; i < comparator_count; i++) { + switch ((cmpop_ty)asdl_seq_GET(ops, i)) { + case Eq: + op = " == "; + break; + case NotEq: + op = " != "; + break; + case Lt: + op = " < "; + break; + case LtE: + op = " <= "; + break; + case Gt: + op = " > "; + break; + case GtE: + op = " >= "; + break; + case Is: + op = " is "; + break; + case IsNot: + op = " is not "; + break; + case In: + op = " in "; + break; + case NotIn: + op = " not in "; + break; + default: + PyErr_SetString(PyExc_SystemError, + "unexpected comparison kind"); + return -1; + } + + APPEND_STR(op); + APPEND_EXPR((expr_ty)asdl_seq_GET(comparators, i), PR_CMP + 1); + } + + APPEND_STR_IF(level > PR_CMP, ")"); + return 0; +} + +static int +append_ast_keyword(_PyUnicodeWriter *writer, keyword_ty kw) +{ + if (kw->arg == NULL) { + APPEND_STR("**"); + } + else { + if (-1 == _PyUnicodeWriter_WriteStr(writer, kw->arg)) { + return -1; + } + + APPEND_STR("="); + } + + APPEND_EXPR(kw->value, PR_TEST); + return 0; +} + +static int +append_ast_call(_PyUnicodeWriter *writer, expr_ty e) +{ + bool first; + Py_ssize_t i, arg_count, kw_count; + expr_ty expr; + + APPEND_EXPR(e->v.Call.func, PR_ATOM); + + arg_count = asdl_seq_LEN(e->v.Call.args); + kw_count = asdl_seq_LEN(e->v.Call.keywords); + if (arg_count == 1 && kw_count == 0) { + expr = (expr_ty)asdl_seq_GET(e->v.Call.args, 0); + if (expr->kind == GeneratorExp_kind) { + /* Special case: a single generator expression. */ + return append_ast_genexp(writer, expr); + } + } + + APPEND_STR("("); + + first = true; + for (i = 0; i < arg_count; i++) { + APPEND_STR_IF_NOT_FIRST(", "); + APPEND_EXPR((expr_ty)asdl_seq_GET(e->v.Call.args, i), PR_TEST); + } + + for (i = 0; i < kw_count; i++) { + APPEND_STR_IF_NOT_FIRST(", "); + APPEND(keyword, (keyword_ty)asdl_seq_GET(e->v.Call.keywords, i)); + } + + APPEND_STR_FINISH(")"); +} + +static PyObject * +escape_braces(PyObject *orig) +{ + PyObject *temp; + PyObject *result; + temp = PyUnicode_Replace(orig, _str_open_br, _str_dbl_open_br, -1); + if (!temp) { + return NULL; + } + result = PyUnicode_Replace(temp, _str_close_br, _str_dbl_close_br, -1); + Py_DECREF(temp); + return result; +} + +static int +append_fstring_unicode(_PyUnicodeWriter *writer, PyObject *unicode) +{ + PyObject *escaped; + int result = -1; + escaped = escape_braces(unicode); + if (escaped) { + result = _PyUnicodeWriter_WriteStr(writer, escaped); + Py_DECREF(escaped); + } + return result; +} + +static int +append_fstring_element(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) +{ + switch (e->kind) { + case Constant_kind: + return append_fstring_unicode(writer, e->v.Constant.value); + case JoinedStr_kind: + return append_joinedstr(writer, e, is_format_spec); + case FormattedValue_kind: + return append_formattedvalue(writer, e, is_format_spec); + default: + PyErr_SetString(PyExc_SystemError, + "unknown expression kind inside f-string"); + return -1; + } +} + +/* Build body separately to enable wrapping the entire stream of Strs, + Constants and FormattedValues in one opening and one closing quote. */ +static PyObject * +build_fstring_body(asdl_seq *values, bool is_format_spec) +{ + Py_ssize_t i, value_count; + _PyUnicodeWriter body_writer; + _PyUnicodeWriter_Init(&body_writer); + body_writer.min_length = 256; + body_writer.overallocate = 1; + + value_count = asdl_seq_LEN(values); + for (i = 0; i < value_count; ++i) { + if (-1 == append_fstring_element(&body_writer, + (expr_ty)asdl_seq_GET(values, i), + is_format_spec + )) { + _PyUnicodeWriter_Dealloc(&body_writer); + return NULL; + } + } + + return _PyUnicodeWriter_Finish(&body_writer); +} + +static int +append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) +{ + int result = -1; + PyObject *body = build_fstring_body(e->v.JoinedStr.values, is_format_spec); + if (!body) { + return -1; + } + + if (!is_format_spec) { + if (-1 != append_charp(writer, "f") && + -1 != append_repr(writer, body)) + { + result = 0; + } + } + else { + result = _PyUnicodeWriter_WriteStr(writer, body); + } + Py_DECREF(body); + return result; +} + +static int +append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) +{ + const char *conversion; + const char *outer_brace = "{"; + /* Grammar allows PR_TUPLE, but use >PR_TEST for adding parenthesis + around a lambda with ':' */ + PyObject *temp_fv_str = expr_as_unicode(e->v.FormattedValue.value, PR_TEST + 1); + if (!temp_fv_str) { + return -1; + } + if (PyUnicode_Find(temp_fv_str, _str_open_br, 0, 1, 1) == 0) { + /* Expression starts with a brace, split it with a space from the outer + one. */ + outer_brace = "{ "; + } + if (-1 == append_charp(writer, outer_brace)) { + Py_DECREF(temp_fv_str); + return -1; + } + if (-1 == _PyUnicodeWriter_WriteStr(writer, temp_fv_str)) { + Py_DECREF(temp_fv_str); + return -1; + } + Py_DECREF(temp_fv_str); + + if (e->v.FormattedValue.conversion > 0) { + switch (e->v.FormattedValue.conversion) { + case 'a': + conversion = "!a"; + break; + case 'r': + conversion = "!r"; + break; + case 's': + conversion = "!s"; + break; + default: + PyErr_SetString(PyExc_SystemError, + "unknown f-value conversion kind"); + return -1; + } + APPEND_STR(conversion); + } + if (e->v.FormattedValue.format_spec) { + if (-1 == _PyUnicodeWriter_WriteASCIIString(writer, ":", 1) || + -1 == append_fstring_element(writer, + e->v.FormattedValue.format_spec, + true + )) + { + return -1; + } + } + + APPEND_STR_FINISH("}"); +} + +static int +append_ast_attribute(_PyUnicodeWriter *writer, expr_ty e) +{ + const char *period; + expr_ty v = e->v.Attribute.value; + APPEND_EXPR(v, PR_ATOM); + + /* Special case: integers require a space for attribute access to be + unambiguous. */ + if (v->kind == Constant_kind && PyLong_CheckExact(v->v.Constant.value)) { + period = " ."; + } + else { + period = "."; + } + APPEND_STR(period); + + return _PyUnicodeWriter_WriteStr(writer, e->v.Attribute.attr); +} + +static int +append_ast_simple_slice(_PyUnicodeWriter *writer, slice_ty slice) +{ + if (slice->v.Slice.lower) { + APPEND_EXPR(slice->v.Slice.lower, PR_TEST); + } + + APPEND_STR(":"); + + if (slice->v.Slice.upper) { + APPEND_EXPR(slice->v.Slice.upper, PR_TEST); + } + + if (slice->v.Slice.step) { + APPEND_STR(":"); + APPEND_EXPR(slice->v.Slice.step, PR_TEST); + } + return 0; +} + +static int +append_ast_ext_slice(_PyUnicodeWriter *writer, slice_ty slice) +{ + Py_ssize_t i, dims_count; + dims_count = asdl_seq_LEN(slice->v.ExtSlice.dims); + for (i = 0; i < dims_count; i++) { + APPEND_STR_IF(i > 0, ", "); + APPEND(slice, (slice_ty)asdl_seq_GET(slice->v.ExtSlice.dims, i)); + } + APPEND_STR_IF(dims_count == 1, ","); + return 0; +} + +static int +append_ast_index_slice(_PyUnicodeWriter *writer, slice_ty slice) +{ + int level = PR_TUPLE; + expr_ty value = slice->v.Index.value; + if (value->kind == Tuple_kind) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(value->v.Tuple.elts); i++) { + expr_ty element = asdl_seq_GET(value->v.Tuple.elts, i); + if (element->kind == Starred_kind) { + ++level; + break; + } + } + } + APPEND_EXPR(value, level); + return 0; +} + +static int +append_ast_slice(_PyUnicodeWriter *writer, slice_ty slice) +{ + switch (slice->kind) { + case Slice_kind: + return append_ast_simple_slice(writer, slice); + case ExtSlice_kind: + return append_ast_ext_slice(writer, slice); + case Index_kind: + return append_ast_index_slice(writer, slice); + default: + PyErr_SetString(PyExc_SystemError, + "unexpected slice kind"); + return -1; + } +} + +static int +append_ast_subscript(_PyUnicodeWriter *writer, expr_ty e) +{ + APPEND_EXPR(e->v.Subscript.value, PR_ATOM); + APPEND_STR("["); + APPEND(slice, e->v.Subscript.slice); + APPEND_STR_FINISH("]"); +} + +static int +append_ast_starred(_PyUnicodeWriter *writer, expr_ty e) +{ + APPEND_STR("*"); + APPEND_EXPR(e->v.Starred.value, PR_EXPR); + return 0; +} + +static int +append_ast_yield(_PyUnicodeWriter *writer, expr_ty e) +{ + if (!e->v.Yield.value) { + APPEND_STR_FINISH("(yield)"); + } + + APPEND_STR("(yield "); + APPEND_EXPR(e->v.Yield.value, PR_TEST); + APPEND_STR_FINISH(")"); +} + +static int +append_ast_yield_from(_PyUnicodeWriter *writer, expr_ty e) +{ + APPEND_STR("(yield from "); + APPEND_EXPR(e->v.YieldFrom.value, PR_TEST); + APPEND_STR_FINISH(")"); +} + +static int +append_ast_await(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + APPEND_STR_IF(level > PR_AWAIT, "("); + APPEND_STR("await "); + APPEND_EXPR(e->v.Await.value, PR_ATOM); + APPEND_STR_IF(level > PR_AWAIT, ")"); + return 0; +} + +static int +append_named_expr(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + APPEND_STR_IF(level > PR_TUPLE, "("); + APPEND_EXPR(e->v.NamedExpr.target, PR_ATOM); + APPEND_STR(":="); + APPEND_EXPR(e->v.NamedExpr.value, PR_ATOM); + APPEND_STR_IF(level > PR_TUPLE, ")"); + return 0; +} + +static int +append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + switch (e->kind) { + case BoolOp_kind: + return append_ast_boolop(writer, e, level); + case BinOp_kind: + return append_ast_binop(writer, e, level); + case UnaryOp_kind: + return append_ast_unaryop(writer, e, level); + case Lambda_kind: + return append_ast_lambda(writer, e, level); + case IfExp_kind: + return append_ast_ifexp(writer, e, level); + case Dict_kind: + return append_ast_dict(writer, e); + case Set_kind: + return append_ast_set(writer, e); + case GeneratorExp_kind: + return append_ast_genexp(writer, e); + case ListComp_kind: + return append_ast_listcomp(writer, e); + case SetComp_kind: + return append_ast_setcomp(writer, e); + case DictComp_kind: + return append_ast_dictcomp(writer, e); + case Yield_kind: + return append_ast_yield(writer, e); + case YieldFrom_kind: + return append_ast_yield_from(writer, e); + case Await_kind: + return append_ast_await(writer, e, level); + case Compare_kind: + return append_ast_compare(writer, e, level); + case Call_kind: + return append_ast_call(writer, e); + case Constant_kind: + if (e->v.Constant.value == Py_Ellipsis) { + APPEND_STR_FINISH("..."); + } + return append_repr(writer, e->v.Constant.value); + case JoinedStr_kind: + return append_joinedstr(writer, e, false); + case FormattedValue_kind: + return append_formattedvalue(writer, e, false); + /* The following exprs can be assignment targets. */ + case Attribute_kind: + return append_ast_attribute(writer, e); + case Subscript_kind: + return append_ast_subscript(writer, e); + case Starred_kind: + return append_ast_starred(writer, e); + case Name_kind: + return _PyUnicodeWriter_WriteStr(writer, e->v.Name.id); + case List_kind: + return append_ast_list(writer, e); + case Tuple_kind: + return append_ast_tuple(writer, e, level); + case NamedExpr_kind: + return append_named_expr(writer, e, level); + default: + PyErr_SetString(PyExc_SystemError, + "unknown expression kind"); + return -1; + } +} + +static int +maybe_init_static_strings(void) +{ + if (!_str_open_br && + !(_str_open_br = PyUnicode_InternFromString("{"))) { + return -1; + } + if (!_str_dbl_open_br && + !(_str_dbl_open_br = PyUnicode_InternFromString("{{"))) { + return -1; + } + if (!_str_close_br && + !(_str_close_br = PyUnicode_InternFromString("}"))) { + return -1; + } + if (!_str_dbl_close_br && + !(_str_dbl_close_br = PyUnicode_InternFromString("}}"))) { + return -1; + } + return 0; +} + +static PyObject * +expr_as_unicode(expr_ty e, int level) +{ + _PyUnicodeWriter writer; + _PyUnicodeWriter_Init(&writer); + writer.min_length = 256; + writer.overallocate = 1; + if (-1 == maybe_init_static_strings() || + -1 == append_ast_expr(&writer, e, level)) + { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + return _PyUnicodeWriter_Finish(&writer); +} + +PyObject * +_PyAST_ExprAsUnicode(expr_ty e) +{ + return expr_as_unicode(e, PR_TEST); +} diff --git a/python/Python/bltinmodule.c b/python/Python/bltinmodule.c new file mode 100755 index 0000000..3767f55 --- /dev/null +++ b/python/Python/bltinmodule.c @@ -0,0 +1,2852 @@ +/* Built-in functions */ + +#include "Python.h" +#include +#include "ast.h" +#undef Yield /* undefine macro conflicting with */ +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" + +_Py_IDENTIFIER(__builtins__); +_Py_IDENTIFIER(__dict__); +_Py_IDENTIFIER(__prepare__); +_Py_IDENTIFIER(__round__); +_Py_IDENTIFIER(__mro_entries__); +_Py_IDENTIFIER(encoding); +_Py_IDENTIFIER(errors); +_Py_IDENTIFIER(fileno); +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(metaclass); +_Py_IDENTIFIER(sort); +_Py_IDENTIFIER(stdin); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); + +#include "clinic/bltinmodule.c.h" + +static PyObject* +update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) +{ + Py_ssize_t i, j; + PyObject *base, *meth, *new_base, *result, *new_bases = NULL; + PyObject *stack[1] = {bases}; + assert(PyTuple_Check(bases)); + + for (i = 0; i < nargs; i++) { + base = args[i]; + if (PyType_Check(base)) { + if (new_bases) { + /* If we already have made a replacement, then we append every normal base, + otherwise just skip it. */ + if (PyList_Append(new_bases, base) < 0) { + goto error; + } + } + continue; + } + if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, &meth) < 0) { + goto error; + } + if (!meth) { + if (new_bases) { + if (PyList_Append(new_bases, base) < 0) { + goto error; + } + } + continue; + } + new_base = _PyObject_FastCall(meth, stack, 1); + Py_DECREF(meth); + if (!new_base) { + goto error; + } + if (!PyTuple_Check(new_base)) { + PyErr_SetString(PyExc_TypeError, + "__mro_entries__ must return a tuple"); + Py_DECREF(new_base); + goto error; + } + if (!new_bases) { + /* If this is a first successful replacement, create new_bases list and + copy previously encountered bases. */ + if (!(new_bases = PyList_New(i))) { + goto error; + } + for (j = 0; j < i; j++) { + base = args[j]; + PyList_SET_ITEM(new_bases, j, base); + Py_INCREF(base); + } + } + j = PyList_GET_SIZE(new_bases); + if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { + goto error; + } + Py_DECREF(new_base); + } + if (!new_bases) { + return bases; + } + result = PyList_AsTuple(new_bases); + Py_DECREF(new_bases); + return result; + +error: + Py_XDECREF(new_bases); + return NULL; +} + +/* AC: cannot convert yet, waiting for *args support */ +static PyObject * +builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, + PyObject *kwnames) +{ + PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *orig_bases; + PyObject *cls = NULL, *cell = NULL; + int isclass = 0; /* initialize to prevent gcc warning */ + + if (nargs < 2) { + PyErr_SetString(PyExc_TypeError, + "__build_class__: not enough arguments"); + return NULL; + } + func = args[0]; /* Better be callable */ + if (!PyFunction_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "__build_class__: func must be a function"); + return NULL; + } + name = args[1]; + if (!PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, + "__build_class__: name is not a string"); + return NULL; + } + orig_bases = _PyTuple_FromArray(args + 2, nargs - 2); + if (orig_bases == NULL) + return NULL; + + bases = update_bases(orig_bases, args + 2, nargs - 2); + if (bases == NULL) { + Py_DECREF(orig_bases); + return NULL; + } + + if (kwnames == NULL) { + meta = NULL; + mkw = NULL; + } + else { + mkw = _PyStack_AsDict(args + nargs, kwnames); + if (mkw == NULL) { + Py_DECREF(bases); + return NULL; + } + + meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass); + if (meta != NULL) { + Py_INCREF(meta); + if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) { + Py_DECREF(meta); + Py_DECREF(mkw); + Py_DECREF(bases); + return NULL; + } + /* metaclass is explicitly given, check if it's indeed a class */ + isclass = PyType_Check(meta); + } + else if (PyErr_Occurred()) { + Py_DECREF(mkw); + Py_DECREF(bases); + return NULL; + } + } + if (meta == NULL) { + /* if there are no bases, use type: */ + if (PyTuple_GET_SIZE(bases) == 0) { + meta = (PyObject *) (&PyType_Type); + } + /* else get the type of the first base */ + else { + PyObject *base0 = PyTuple_GET_ITEM(bases, 0); + meta = (PyObject *) (base0->ob_type); + } + Py_INCREF(meta); + isclass = 1; /* meta is really a class */ + } + + if (isclass) { + /* meta is really a class, so check for a more derived + metaclass, or possible metaclass conflicts: */ + winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta, + bases); + if (winner == NULL) { + Py_DECREF(meta); + Py_XDECREF(mkw); + Py_DECREF(bases); + return NULL; + } + if (winner != meta) { + Py_DECREF(meta); + meta = winner; + Py_INCREF(meta); + } + } + /* else: meta is not a class, so we cannot do the metaclass + calculation, so we will use the explicitly given object as it is */ + if (_PyObject_LookupAttrId(meta, &PyId___prepare__, &prep) < 0) { + ns = NULL; + } + else if (prep == NULL) { + ns = PyDict_New(); + } + else { + PyObject *pargs[2] = {name, bases}; + ns = _PyObject_FastCallDict(prep, pargs, 2, mkw); + Py_DECREF(prep); + } + if (ns == NULL) { + Py_DECREF(meta); + Py_XDECREF(mkw); + Py_DECREF(bases); + return NULL; + } + if (!PyMapping_Check(ns)) { + PyErr_Format(PyExc_TypeError, + "%.200s.__prepare__() must return a mapping, not %.200s", + isclass ? ((PyTypeObject *)meta)->tp_name : "", + Py_TYPE(ns)->tp_name); + goto error; + } + cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns, + NULL, 0, NULL, 0, NULL, 0, NULL, + PyFunction_GET_CLOSURE(func)); + if (cell != NULL) { + if (bases != orig_bases) { + if (PyMapping_SetItemString(ns, "__orig_bases__", orig_bases) < 0) { + goto error; + } + } + PyObject *margs[3] = {name, bases, ns}; + cls = _PyObject_FastCallDict(meta, margs, 3, mkw); + if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) { + PyObject *cell_cls = PyCell_GET(cell); + if (cell_cls != cls) { + if (cell_cls == NULL) { + const char *msg = + "__class__ not set defining %.200R as %.200R. " + "Was __classcell__ propagated to type.__new__?"; + PyErr_Format(PyExc_RuntimeError, msg, name, cls); + } else { + const char *msg = + "__class__ set to %.200R defining %.200R as %.200R"; + PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls); + } + Py_DECREF(cls); + cls = NULL; + goto error; + } + } + } +error: + Py_XDECREF(cell); + Py_DECREF(ns); + Py_DECREF(meta); + Py_XDECREF(mkw); + Py_DECREF(bases); + if (bases != orig_bases) { + Py_DECREF(orig_bases); + } + return cls; +} + +PyDoc_STRVAR(build_class_doc, +"__build_class__(func, name, /, *bases, [metaclass], **kwds) -> class\n\ +\n\ +Internal helper function used by the class statement."); + +static PyObject * +builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"name", "globals", "locals", "fromlist", + "level", 0}; + PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL; + int level = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__", + kwlist, &name, &globals, &locals, &fromlist, &level)) + return NULL; + return PyImport_ImportModuleLevelObject(name, globals, locals, + fromlist, level); +} + +PyDoc_STRVAR(import_doc, +"__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module\n\ +\n\ +Import a module. Because this function is meant for use by the Python\n\ +interpreter and not for general use, it is better to use\n\ +importlib.import_module() to programmatically import a module.\n\ +\n\ +The globals argument is only used to determine the context;\n\ +they are not modified. The locals argument is unused. The fromlist\n\ +should be a list of names to emulate ``from name import ...'', or an\n\ +empty list to emulate ``import name''.\n\ +When importing a module from a package, note that __import__('A.B', ...)\n\ +returns package A when fromlist is empty, but its submodule B when\n\ +fromlist is not empty. The level argument is used to determine whether to\n\ +perform absolute or relative imports: 0 is absolute, while a positive number\n\ +is the number of parent directories to search relative to the current module."); + + +/*[clinic input] +abs as builtin_abs + + x: object + / + +Return the absolute value of the argument. +[clinic start generated code]*/ + +static PyObject * +builtin_abs(PyObject *module, PyObject *x) +/*[clinic end generated code: output=b1b433b9e51356f5 input=bed4ca14e29c20d1]*/ +{ + return PyNumber_Absolute(x); +} + +/*[clinic input] +all as builtin_all + + iterable: object + / + +Return True if bool(x) is True for all values x in the iterable. + +If the iterable is empty, return True. +[clinic start generated code]*/ + +static PyObject * +builtin_all(PyObject *module, PyObject *iterable) +/*[clinic end generated code: output=ca2a7127276f79b3 input=1a7c5d1bc3438a21]*/ +{ + PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + int cmp; + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + iternext = *Py_TYPE(it)->tp_iternext; + + for (;;) { + item = iternext(it); + if (item == NULL) + break; + cmp = PyObject_IsTrue(item); + Py_DECREF(item); + if (cmp < 0) { + Py_DECREF(it); + return NULL; + } + if (cmp == 0) { + Py_DECREF(it); + Py_RETURN_FALSE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + return NULL; + } + Py_RETURN_TRUE; +} + +/*[clinic input] +any as builtin_any + + iterable: object + / + +Return True if bool(x) is True for any x in the iterable. + +If the iterable is empty, return False. +[clinic start generated code]*/ + +static PyObject * +builtin_any(PyObject *module, PyObject *iterable) +/*[clinic end generated code: output=fa65684748caa60e input=41d7451c23384f24]*/ +{ + PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + int cmp; + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + iternext = *Py_TYPE(it)->tp_iternext; + + for (;;) { + item = iternext(it); + if (item == NULL) + break; + cmp = PyObject_IsTrue(item); + Py_DECREF(item); + if (cmp < 0) { + Py_DECREF(it); + return NULL; + } + if (cmp > 0) { + Py_DECREF(it); + Py_RETURN_TRUE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + return NULL; + } + Py_RETURN_FALSE; +} + +/*[clinic input] +ascii as builtin_ascii + + obj: object + / + +Return an ASCII-only representation of an object. + +As repr(), return a string containing a printable representation of an +object, but escape the non-ASCII characters in the string returned by +repr() using \\x, \\u or \\U escapes. This generates a string similar +to that returned by repr() in Python 2. +[clinic start generated code]*/ + +static PyObject * +builtin_ascii(PyObject *module, PyObject *obj) +/*[clinic end generated code: output=6d37b3f0984c7eb9 input=4c62732e1b3a3cc9]*/ +{ + return PyObject_ASCII(obj); +} + + +/*[clinic input] +bin as builtin_bin + + number: object + / + +Return the binary representation of an integer. + + >>> bin(2796202) + '0b1010101010101010101010' +[clinic start generated code]*/ + +static PyObject * +builtin_bin(PyObject *module, PyObject *number) +/*[clinic end generated code: output=b6fc4ad5e649f4f7 input=53f8a0264bacaf90]*/ +{ + return PyNumber_ToBase(number, 2); +} + + +/*[clinic input] +callable as builtin_callable + + obj: object + / + +Return whether the object is callable (i.e., some kind of function). + +Note that classes are callable, as are instances of classes with a +__call__() method. +[clinic start generated code]*/ + +static PyObject * +builtin_callable(PyObject *module, PyObject *obj) +/*[clinic end generated code: output=2b095d59d934cb7e input=1423bab99cc41f58]*/ +{ + return PyBool_FromLong((long)PyCallable_Check(obj)); +} + +static PyObject * +builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) +{ + PyObject *hook = PySys_GetObject("breakpointhook"); + + if (hook == NULL) { + PyErr_SetString(PyExc_RuntimeError, "lost sys.breakpointhook"); + return NULL; + } + + if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) { + return NULL; + } + + Py_INCREF(hook); + PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords); + Py_DECREF(hook); + return retval; +} + +PyDoc_STRVAR(breakpoint_doc, +"breakpoint(*args, **kws)\n\ +\n\ +Call sys.breakpointhook(*args, **kws). sys.breakpointhook() must accept\n\ +whatever arguments are passed.\n\ +\n\ +By default, this drops you into the pdb debugger."); + +typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; +} filterobject; + +static PyObject * +filter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *func, *seq; + PyObject *it; + filterobject *lz; + + if (type == &PyFilter_Type && !_PyArg_NoKeywords("filter", kwds)) + return NULL; + + if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq)) + return NULL; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create filterobject structure */ + lz = (filterobject *)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 +filter_dealloc(filterobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + Py_TYPE(lz)->tp_free(lz); +} + +static int +filter_traverse(filterobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->it); + Py_VISIT(lz->func); + return 0; +} + +static PyObject * +filter_next(filterobject *lz) +{ + PyObject *item; + PyObject *it = lz->it; + long ok; + PyObject *(*iternext)(PyObject *); + int checktrue = lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type; + + iternext = *Py_TYPE(it)->tp_iternext; + for (;;) { + item = iternext(it); + if (item == NULL) + return NULL; + + if (checktrue) { + ok = PyObject_IsTrue(item); + } else { + PyObject *good; + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); + 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 * +filter_reduce(filterobject *lz, PyObject *Py_UNUSED(ignored)) +{ + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyMethodDef filter_methods[] = { + {"__reduce__", (PyCFunction)filter_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(filter_doc, +"filter(function or None, iterable) --> filter object\n\ +\n\ +Return an iterator yielding those items of iterable for which function(item)\n\ +is true. If function is None, return the items that are true."); + +PyTypeObject PyFilter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "filter", /* tp_name */ + sizeof(filterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)filter_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 */ + filter_doc, /* tp_doc */ + (traverseproc)filter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)filter_next, /* tp_iternext */ + filter_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 */ + filter_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/*[clinic input] +format as builtin_format + + value: object + format_spec: unicode(c_default="NULL") = '' + / + +Return value.__format__(format_spec) + +format_spec defaults to the empty string. +See the Format Specification Mini-Language section of help('FORMATTING') for +details. +[clinic start generated code]*/ + +static PyObject * +builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec) +/*[clinic end generated code: output=2f40bdfa4954b077 input=88339c93ea522b33]*/ +{ + return PyObject_Format(value, format_spec); +} + +/*[clinic input] +chr as builtin_chr + + i: int + / + +Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. +[clinic start generated code]*/ + +static PyObject * +builtin_chr_impl(PyObject *module, int i) +/*[clinic end generated code: output=c733afcd200afcb7 input=3f604ef45a70750d]*/ +{ + return PyUnicode_FromOrdinal(i); +} + + +/*[clinic input] +compile as builtin_compile + + source: object + filename: object(converter="PyUnicode_FSDecoder") + mode: str + flags: int = 0 + dont_inherit: bool(accept={int}) = False + optimize: int = -1 + * + _feature_version as feature_version: int = -1 + +Compile source into a code object that can be executed by exec() or eval(). + +The source code may represent a Python module, statement or expression. +The filename will be used for run-time error messages. +The mode must be 'exec' to compile a module, 'single' to compile a +single (interactive) statement, or 'eval' to compile an expression. +The flags argument, if present, controls which future statements influence +the compilation of the code. +The dont_inherit argument, if true, stops the compilation inheriting +the effects of any future statements in effect in the code calling +compile; if absent or false these statements do influence the compilation, +in addition to any features explicitly specified. +[clinic start generated code]*/ + +static PyObject * +builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, + const char *mode, int flags, int dont_inherit, + int optimize, int feature_version) +/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/ +{ + PyObject *source_copy; + const char *str; + int compile_mode = -1; + int is_ast; + int start[] = {Py_file_input, Py_eval_input, Py_single_input, Py_func_type_input}; + PyObject *result; + + PyCompilerFlags cf = _PyCompilerFlags_INIT; + cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8; + if (feature_version >= 0 && (flags & PyCF_ONLY_AST)) { + cf.cf_feature_version = feature_version; + } + + if (flags & + ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK)) + { + PyErr_SetString(PyExc_ValueError, + "compile(): unrecognised flags"); + goto error; + } + /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ + + if (optimize < -1 || optimize > 2) { + PyErr_SetString(PyExc_ValueError, + "compile(): invalid optimize value"); + goto error; + } + + if (!dont_inherit) { + PyEval_MergeCompilerFlags(&cf); + } + + if (strcmp(mode, "exec") == 0) + compile_mode = 0; + else if (strcmp(mode, "eval") == 0) + compile_mode = 1; + else if (strcmp(mode, "single") == 0) + compile_mode = 2; + else if (strcmp(mode, "func_type") == 0) { + if (!(flags & PyCF_ONLY_AST)) { + PyErr_SetString(PyExc_ValueError, + "compile() mode 'func_type' requires flag PyCF_ONLY_AST"); + goto error; + } + compile_mode = 3; + } + else { + const char *msg; + if (flags & PyCF_ONLY_AST) + msg = "compile() mode must be 'exec', 'eval', 'single' or 'func_type'"; + else + msg = "compile() mode must be 'exec', 'eval' or 'single'"; + PyErr_SetString(PyExc_ValueError, msg); + goto error; + } + + is_ast = PyAST_Check(source); + if (is_ast == -1) + goto error; + if (is_ast) { + if (flags & PyCF_ONLY_AST) { + Py_INCREF(source); + result = source; + } + else { + PyArena *arena; + mod_ty mod; + + arena = PyArena_New(); + if (arena == NULL) + goto error; + mod = PyAST_obj2mod(source, arena, compile_mode); + if (mod == NULL) { + PyArena_Free(arena); + goto error; + } + if (!PyAST_Validate(mod)) { + PyArena_Free(arena); + goto error; + } + result = (PyObject*)PyAST_CompileObject(mod, filename, + &cf, optimize, arena); + PyArena_Free(arena); + } + goto finally; + } + + str = _Py_SourceAsString(source, "compile", "string, bytes or AST", &cf, &source_copy); + if (str == NULL) + goto error; + + result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize); + Py_XDECREF(source_copy); + goto finally; + +error: + result = NULL; +finally: + Py_DECREF(filename); + return result; +} + +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +static PyObject * +builtin_dir(PyObject *self, PyObject *args) +{ + PyObject *arg = NULL; + + if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg)) + return NULL; + return PyObject_Dir(arg); +} + +PyDoc_STRVAR(dir_doc, +"dir([object]) -> list of strings\n" +"\n" +"If called without an argument, return the names in the current scope.\n" +"Else, return an alphabetized list of names comprising (some of) the attributes\n" +"of the given object, and of attributes reachable from it.\n" +"If the object supplies a method named __dir__, it will be used; otherwise\n" +"the default dir() logic is used and returns:\n" +" for a module object: the module's attributes.\n" +" for a class object: its attributes, and recursively the attributes\n" +" of its bases.\n" +" for any other object: its attributes, its class's attributes, and\n" +" recursively the attributes of its class's base classes."); + +/*[clinic input] +divmod as builtin_divmod + + x: object + y: object + / + +Return the tuple (x//y, x%y). Invariant: div*y + mod == x. +[clinic start generated code]*/ + +static PyObject * +builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y) +/*[clinic end generated code: output=b06d8a5f6e0c745e input=175ad9c84ff41a85]*/ +{ + return PyNumber_Divmod(x, y); +} + + +/*[clinic input] +eval as builtin_eval + + source: object + globals: object = None + locals: object = None + / + +Evaluate the given source in the context of globals and locals. + +The source may be a string representing a Python expression +or a code object as returned by compile(). +The globals must be a dictionary and locals can be any mapping, +defaulting to the current globals and locals. +If only globals is given, locals defaults to it. +[clinic start generated code]*/ + +static PyObject * +builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, + PyObject *locals) +/*[clinic end generated code: output=0a0824aa70093116 input=11ee718a8640e527]*/ +{ + PyObject *result, *source_copy; + const char *str; + + if (locals != Py_None && !PyMapping_Check(locals)) { + PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); + return NULL; + } + if (globals != Py_None && !PyDict_Check(globals)) { + PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ? + "globals must be a real dict; try eval(expr, {}, mapping)" + : "globals must be a dict"); + return NULL; + } + if (globals == Py_None) { + globals = PyEval_GetGlobals(); + if (locals == Py_None) { + locals = PyEval_GetLocals(); + if (locals == NULL) + return NULL; + } + } + else if (locals == Py_None) + locals = globals; + + if (globals == NULL || locals == NULL) { + PyErr_SetString(PyExc_TypeError, + "eval must be given globals and locals " + "when called without a frame"); + return NULL; + } + + if (_PyDict_GetItemIdWithError(globals, &PyId___builtins__) == NULL) { + if (_PyDict_SetItemId(globals, &PyId___builtins__, + PyEval_GetBuiltins()) != 0) + return NULL; + } + else if (PyErr_Occurred()) { + return NULL; + } + + if (PyCode_Check(source)) { + if (PySys_Audit("exec", "O", source) < 0) { + return NULL; + } + + if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { + PyErr_SetString(PyExc_TypeError, + "code object passed to eval() may not contain free variables"); + return NULL; + } + return PyEval_EvalCode(source, globals, locals); + } + + PyCompilerFlags cf = _PyCompilerFlags_INIT; + cf.cf_flags = PyCF_SOURCE_IS_UTF8; + str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy); + if (str == NULL) + return NULL; + + while (*str == ' ' || *str == '\t') + str++; + + (void)PyEval_MergeCompilerFlags(&cf); + result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); + Py_XDECREF(source_copy); + return result; +} + +/*[clinic input] +exec as builtin_exec + + source: object + globals: object = None + locals: object = None + / + +Execute the given source in the context of globals and locals. + +The source may be a string representing one or more Python statements +or a code object as returned by compile(). +The globals must be a dictionary and locals can be any mapping, +defaulting to the current globals and locals. +If only globals is given, locals defaults to it. +[clinic start generated code]*/ + +static PyObject * +builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, + PyObject *locals) +/*[clinic end generated code: output=3c90efc6ab68ef5d input=01ca3e1c01692829]*/ +{ + PyObject *v; + + if (globals == Py_None) { + globals = PyEval_GetGlobals(); + if (locals == Py_None) { + locals = PyEval_GetLocals(); + if (locals == NULL) + return NULL; + } + if (!globals || !locals) { + PyErr_SetString(PyExc_SystemError, + "globals and locals cannot be NULL"); + return NULL; + } + } + else if (locals == Py_None) + locals = globals; + + if (!PyDict_Check(globals)) { + PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s", + globals->ob_type->tp_name); + return NULL; + } + if (!PyMapping_Check(locals)) { + PyErr_Format(PyExc_TypeError, + "locals must be a mapping or None, not %.100s", + locals->ob_type->tp_name); + return NULL; + } + if (_PyDict_GetItemIdWithError(globals, &PyId___builtins__) == NULL) { + if (_PyDict_SetItemId(globals, &PyId___builtins__, + PyEval_GetBuiltins()) != 0) + return NULL; + } + else if (PyErr_Occurred()) { + return NULL; + } + + if (PyCode_Check(source)) { + if (PySys_Audit("exec", "O", source) < 0) { + return NULL; + } + + if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { + PyErr_SetString(PyExc_TypeError, + "code object passed to exec() may not " + "contain free variables"); + return NULL; + } + v = PyEval_EvalCode(source, globals, locals); + } + else { + PyObject *source_copy; + const char *str; + PyCompilerFlags cf = _PyCompilerFlags_INIT; + cf.cf_flags = PyCF_SOURCE_IS_UTF8; + str = _Py_SourceAsString(source, "exec", + "string, bytes or code", &cf, + &source_copy); + if (str == NULL) + return NULL; + if (PyEval_MergeCompilerFlags(&cf)) + v = PyRun_StringFlags(str, Py_file_input, globals, + locals, &cf); + else + v = PyRun_String(str, Py_file_input, globals, locals); + Py_XDECREF(source_copy); + } + if (v == NULL) + return NULL; + Py_DECREF(v); + Py_RETURN_NONE; +} + + +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +static PyObject * +builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *v, *name, *result; + + if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) + return NULL; + + v = args[0]; + name = args[1]; + if (!PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, + "getattr(): attribute name must be string"); + return NULL; + } + if (nargs > 2) { + if (_PyObject_LookupAttr(v, name, &result) == 0) { + PyObject *dflt = args[2]; + Py_INCREF(dflt); + return dflt; + } + } + else { + result = PyObject_GetAttr(v, name); + } + return result; +} + +PyDoc_STRVAR(getattr_doc, +"getattr(object, name[, default]) -> value\n\ +\n\ +Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\ +When a default argument is given, it is returned when the attribute doesn't\n\ +exist; without it, an exception is raised in that case."); + + +/*[clinic input] +globals as builtin_globals + +Return the dictionary containing the current scope's global variables. + +NOTE: Updates to this dictionary *will* affect name lookups in the current +global scope and vice-versa. +[clinic start generated code]*/ + +static PyObject * +builtin_globals_impl(PyObject *module) +/*[clinic end generated code: output=e5dd1527067b94d2 input=9327576f92bb48ba]*/ +{ + PyObject *d; + + d = PyEval_GetGlobals(); + Py_XINCREF(d); + return d; +} + + +/*[clinic input] +hasattr as builtin_hasattr + + obj: object + name: object + / + +Return whether the object has an attribute with the given name. + +This is done by calling getattr(obj, name) and catching AttributeError. +[clinic start generated code]*/ + +static PyObject * +builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name) +/*[clinic end generated code: output=a7aff2090a4151e5 input=0faec9787d979542]*/ +{ + PyObject *v; + + if (!PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return NULL; + } + if (_PyObject_LookupAttr(obj, name, &v) < 0) { + return NULL; + } + if (v == NULL) { + Py_RETURN_FALSE; + } + Py_DECREF(v); + Py_RETURN_TRUE; +} + + +/* AC: gdb's integration with CPython relies on builtin_id having + * the *exact* parameter names of "self" and "v", so we ensure we + * preserve those name rather than using the AC defaults. + */ +/*[clinic input] +id as builtin_id + + self: self(type="PyModuleDef *") + obj as v: object + / + +Return the identity of an object. + +This is guaranteed to be unique among simultaneously existing objects. +(CPython uses the object's memory address.) +[clinic start generated code]*/ + +static PyObject * +builtin_id(PyModuleDef *self, PyObject *v) +/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/ +{ + PyObject *id = PyLong_FromVoidPtr(v); + + if (id && PySys_Audit("builtins.id", "O", id) < 0) { + Py_DECREF(id); + return NULL; + } + + return id; +} + + +/* map object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *iters; + PyObject *func; +} mapobject; + +static PyObject * +map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *it, *iters, *func; + mapobject *lz; + Py_ssize_t numargs, i; + + if (type == &PyMap_Type && !_PyArg_NoKeywords("map", kwds)) + return NULL; + + numargs = PyTuple_Size(args); + if (numargs < 2) { + PyErr_SetString(PyExc_TypeError, + "map() must have at least two arguments."); + return NULL; + } + + iters = PyTuple_New(numargs-1); + if (iters == NULL) + return NULL; + + for (i=1 ; itp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(iters); + return NULL; + } + lz->iters = iters; + func = PyTuple_GET_ITEM(args, 0); + Py_INCREF(func); + lz->func = func; + + return (PyObject *)lz; +} + +static void +map_dealloc(mapobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->iters); + Py_XDECREF(lz->func); + Py_TYPE(lz)->tp_free(lz); +} + +static int +map_traverse(mapobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->iters); + Py_VISIT(lz->func); + return 0; +} + +static PyObject * +map_next(mapobject *lz) +{ + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject **stack; + Py_ssize_t niters, nargs, i; + PyObject *result = NULL; + + niters = PyTuple_GET_SIZE(lz->iters); + if (niters <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { + stack = small_stack; + } + else { + stack = PyMem_Malloc(niters * sizeof(stack[0])); + if (stack == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + + nargs = 0; + for (i=0; i < niters; i++) { + PyObject *it = PyTuple_GET_ITEM(lz->iters, i); + PyObject *val = Py_TYPE(it)->tp_iternext(it); + if (val == NULL) { + goto exit; + } + stack[i] = val; + nargs++; + } + + result = _PyObject_FastCall(lz->func, stack, nargs); + +exit: + for (i=0; i < nargs; i++) { + Py_DECREF(stack[i]); + } + if (stack != small_stack) { + PyMem_Free(stack); + } + return result; +} + +static PyObject * +map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t numargs = PyTuple_GET_SIZE(lz->iters); + PyObject *args = PyTuple_New(numargs+1); + Py_ssize_t i; + if (args == NULL) + return NULL; + Py_INCREF(lz->func); + PyTuple_SET_ITEM(args, 0, lz->func); + for (i = 0; iiters, i); + Py_INCREF(it); + PyTuple_SET_ITEM(args, i+1, it); + } + + return Py_BuildValue("ON", Py_TYPE(lz), args); +} + +static PyMethodDef map_methods[] = { + {"__reduce__", (PyCFunction)map_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + + +PyDoc_STRVAR(map_doc, +"map(func, *iterables) --> map object\n\ +\n\ +Make an iterator that computes the function using arguments from\n\ +each of the iterables. Stops when the shortest iterable is exhausted."); + +PyTypeObject PyMap_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "map", /* tp_name */ + sizeof(mapobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)map_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 */ + map_doc, /* tp_doc */ + (traverseproc)map_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)map_next, /* tp_iternext */ + map_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + map_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +static PyObject * +builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *it, *res; + + if (!_PyArg_CheckPositional("next", nargs, 1, 2)) + return NULL; + + it = args[0]; + if (!PyIter_Check(it)) { + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not an iterator", + it->ob_type->tp_name); + return NULL; + } + + res = (*it->ob_type->tp_iternext)(it); + if (res != NULL) { + return res; + } else if (nargs > 1) { + PyObject *def = args[1]; + if (PyErr_Occurred()) { + if(!PyErr_ExceptionMatches(PyExc_StopIteration)) + return NULL; + PyErr_Clear(); + } + Py_INCREF(def); + return def; + } else if (PyErr_Occurred()) { + return NULL; + } else { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } +} + +PyDoc_STRVAR(next_doc, +"next(iterator[, default])\n\ +\n\ +Return the next item from the iterator. If default is given and the iterator\n\ +is exhausted, it is returned instead of raising StopIteration."); + + +/*[clinic input] +setattr as builtin_setattr + + obj: object + name: object + value: object + / + +Sets the named attribute on the given object to the specified value. + +setattr(x, 'y', v) is equivalent to ``x.y = v'' +[clinic start generated code]*/ + +static PyObject * +builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, + PyObject *value) +/*[clinic end generated code: output=dc2ce1d1add9acb4 input=bd2b7ca6875a1899]*/ +{ + if (PyObject_SetAttr(obj, name, value) != 0) + return NULL; + Py_RETURN_NONE; +} + + +/*[clinic input] +delattr as builtin_delattr + + obj: object + name: object + / + +Deletes the named attribute from the given object. + +delattr(x, 'y') is equivalent to ``del x.y'' +[clinic start generated code]*/ + +static PyObject * +builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name) +/*[clinic end generated code: output=85134bc58dff79fa input=db16685d6b4b9410]*/ +{ + if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) + return NULL; + Py_RETURN_NONE; +} + + +/*[clinic input] +hash as builtin_hash + + obj: object + / + +Return the hash value for the given object. + +Two objects that compare equal must also have the same hash value, but the +reverse is not necessarily true. +[clinic start generated code]*/ + +static PyObject * +builtin_hash(PyObject *module, PyObject *obj) +/*[clinic end generated code: output=237668e9d7688db7 input=58c48be822bf9c54]*/ +{ + Py_hash_t x; + + x = PyObject_Hash(obj); + if (x == -1) + return NULL; + return PyLong_FromSsize_t(x); +} + + +/*[clinic input] +hex as builtin_hex + + number: object + / + +Return the hexadecimal representation of an integer. + + >>> hex(12648430) + '0xc0ffee' +[clinic start generated code]*/ + +static PyObject * +builtin_hex(PyObject *module, PyObject *number) +/*[clinic end generated code: output=e46b612169099408 input=e645aff5fc7d540e]*/ +{ + return PyNumber_ToBase(number, 16); +} + + +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +static PyObject * +builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *v; + + if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) + return NULL; + v = args[0]; + if (nargs == 1) + return PyObject_GetIter(v); + if (!PyCallable_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "iter(v, w): v must be callable"); + return NULL; + } + PyObject *sentinel = args[1]; + return PyCallIter_New(v, sentinel); +} + +PyDoc_STRVAR(iter_doc, +"iter(iterable) -> iterator\n\ +iter(callable, sentinel) -> iterator\n\ +\n\ +Get an iterator from an object. In the first form, the argument must\n\ +supply its own iterator, or be a sequence.\n\ +In the second form, the callable is called until it returns the sentinel."); + + +/*[clinic input] +len as builtin_len + + obj: object + / + +Return the number of items in a container. +[clinic start generated code]*/ + +static PyObject * +builtin_len(PyObject *module, PyObject *obj) +/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/ +{ + Py_ssize_t res; + + res = PyObject_Size(obj); + if (res < 0) { + assert(PyErr_Occurred()); + return NULL; + } + return PyLong_FromSsize_t(res); +} + + +/*[clinic input] +locals as builtin_locals + +Return a dictionary containing the current scope's local variables. + +NOTE: Whether or not updates to this dictionary will affect name lookups in +the local scope and vice-versa is *implementation dependent* and not +covered by any backwards compatibility guarantees. +[clinic start generated code]*/ + +static PyObject * +builtin_locals_impl(PyObject *module) +/*[clinic end generated code: output=b46c94015ce11448 input=7874018d478d5c4b]*/ +{ + PyObject *d; + + d = PyEval_GetLocals(); + Py_XINCREF(d); + return d; +} + + +static PyObject * +min_max(PyObject *args, PyObject *kwds, int op) +{ + PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL; + PyObject *emptytuple, *defaultval = NULL; + static char *kwlist[] = {"key", "default", NULL}; + const char *name = op == Py_LT ? "min" : "max"; + const int positional = PyTuple_Size(args) > 1; + int ret; + + if (positional) + v = args; + else if (!PyArg_UnpackTuple(args, name, 1, 1, &v)) + return NULL; + + emptytuple = PyTuple_New(0); + if (emptytuple == NULL) + return NULL; + ret = PyArg_ParseTupleAndKeywords(emptytuple, kwds, + (op == Py_LT) ? "|$OO:min" : "|$OO:max", + kwlist, &keyfunc, &defaultval); + Py_DECREF(emptytuple); + if (!ret) + return NULL; + + if (positional && defaultval != NULL) { + PyErr_Format(PyExc_TypeError, + "Cannot specify a default for %s() with multiple " + "positional arguments", name); + return NULL; + } + + it = PyObject_GetIter(v); + if (it == NULL) { + return NULL; + } + + if (keyfunc == Py_None) { + keyfunc = NULL; + } + + maxitem = NULL; /* the result */ + maxval = NULL; /* the value associated with the result */ + while (( item = PyIter_Next(it) )) { + /* get the value from the key function */ + if (keyfunc != NULL) { + val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL); + if (val == NULL) + goto Fail_it_item; + } + /* no key function; the value is the item */ + else { + val = item; + Py_INCREF(val); + } + + /* maximum value and item are unset; set them */ + if (maxval == NULL) { + maxitem = item; + maxval = val; + } + /* maximum value and item are set; update them as necessary */ + else { + int cmp = PyObject_RichCompareBool(val, maxval, op); + if (cmp < 0) + goto Fail_it_item_and_val; + else if (cmp > 0) { + Py_DECREF(maxval); + Py_DECREF(maxitem); + maxval = val; + maxitem = item; + } + else { + Py_DECREF(item); + Py_DECREF(val); + } + } + } + if (PyErr_Occurred()) + goto Fail_it; + if (maxval == NULL) { + assert(maxitem == NULL); + if (defaultval != NULL) { + Py_INCREF(defaultval); + maxitem = defaultval; + } else { + PyErr_Format(PyExc_ValueError, + "%s() arg is an empty sequence", name); + } + } + else + Py_DECREF(maxval); + Py_DECREF(it); + return maxitem; + +Fail_it_item_and_val: + Py_DECREF(val); +Fail_it_item: + Py_DECREF(item); +Fail_it: + Py_XDECREF(maxval); + Py_XDECREF(maxitem); + Py_DECREF(it); + return NULL; +} + +/* AC: cannot convert yet, waiting for *args support */ +static PyObject * +builtin_min(PyObject *self, PyObject *args, PyObject *kwds) +{ + return min_max(args, kwds, Py_LT); +} + +PyDoc_STRVAR(min_doc, +"min(iterable, *[, default=obj, key=func]) -> value\n\ +min(arg1, arg2, *args, *[, key=func]) -> value\n\ +\n\ +With a single iterable argument, return its smallest item. The\n\ +default keyword-only argument specifies an object to return if\n\ +the provided iterable is empty.\n\ +With two or more arguments, return the smallest argument."); + + +/* AC: cannot convert yet, waiting for *args support */ +static PyObject * +builtin_max(PyObject *self, PyObject *args, PyObject *kwds) +{ + return min_max(args, kwds, Py_GT); +} + +PyDoc_STRVAR(max_doc, +"max(iterable, *[, default=obj, key=func]) -> value\n\ +max(arg1, arg2, *args, *[, key=func]) -> value\n\ +\n\ +With a single iterable argument, return its biggest item. The\n\ +default keyword-only argument specifies an object to return if\n\ +the provided iterable is empty.\n\ +With two or more arguments, return the largest argument."); + + +/*[clinic input] +oct as builtin_oct + + number: object + / + +Return the octal representation of an integer. + + >>> oct(342391) + '0o1234567' +[clinic start generated code]*/ + +static PyObject * +builtin_oct(PyObject *module, PyObject *number) +/*[clinic end generated code: output=40a34656b6875352 input=ad6b274af4016c72]*/ +{ + return PyNumber_ToBase(number, 8); +} + + +/*[clinic input] +ord as builtin_ord + + c: object + / + +Return the Unicode code point for a one-character string. +[clinic start generated code]*/ + +static PyObject * +builtin_ord(PyObject *module, PyObject *c) +/*[clinic end generated code: output=4fa5e87a323bae71 input=3064e5d6203ad012]*/ +{ + long ord; + Py_ssize_t size; + + if (PyBytes_Check(c)) { + size = PyBytes_GET_SIZE(c); + if (size == 1) { + ord = (long)((unsigned char)*PyBytes_AS_STRING(c)); + return PyLong_FromLong(ord); + } + } + else if (PyUnicode_Check(c)) { + if (PyUnicode_READY(c) == -1) + return NULL; + size = PyUnicode_GET_LENGTH(c); + if (size == 1) { + ord = (long)PyUnicode_READ_CHAR(c, 0); + return PyLong_FromLong(ord); + } + } + else if (PyByteArray_Check(c)) { + /* XXX Hopefully this is temporary */ + size = PyByteArray_GET_SIZE(c); + if (size == 1) { + ord = (long)((unsigned char)*PyByteArray_AS_STRING(c)); + return PyLong_FromLong(ord); + } + } + else { + PyErr_Format(PyExc_TypeError, + "ord() expected string of length 1, but " \ + "%.200s found", c->ob_type->tp_name); + return NULL; + } + + PyErr_Format(PyExc_TypeError, + "ord() expected a character, " + "but string of length %zd found", + size); + return NULL; +} + + +/*[clinic input] +pow as builtin_pow + + base: object + exp: object + mod: object = None + +Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments + +Some types, such as ints, are able to use a more efficient algorithm when +invoked using the three argument form. +[clinic start generated code]*/ + +static PyObject * +builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, + PyObject *mod) +/*[clinic end generated code: output=3ca1538221bbf15f input=435dbd48a12efb23]*/ +{ + return PyNumber_Power(base, exp, mod); +} + + +/* AC: cannot convert yet, waiting for *args support */ +static PyObject * +builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + static const char * const _keywords[] = {"sep", "end", "file", "flush", 0}; + static struct _PyArg_Parser _parser = {"|OOOO:print", _keywords, 0}; + PyObject *sep = NULL, *end = NULL, *file = NULL, *flush = NULL; + int i, err; + + if (kwnames != NULL && + !_PyArg_ParseStackAndKeywords(args + nargs, 0, kwnames, &_parser, + &sep, &end, &file, &flush)) { + return NULL; + } + + if (file == NULL || file == Py_None) { + file = _PySys_GetObjectId(&PyId_stdout); + if (file == NULL) { + PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); + return NULL; + } + + /* sys.stdout may be None when FILE* stdout isn't connected */ + if (file == Py_None) + Py_RETURN_NONE; + } + + if (sep == Py_None) { + sep = NULL; + } + else if (sep && !PyUnicode_Check(sep)) { + PyErr_Format(PyExc_TypeError, + "sep must be None or a string, not %.200s", + sep->ob_type->tp_name); + return NULL; + } + if (end == Py_None) { + end = NULL; + } + else if (end && !PyUnicode_Check(end)) { + PyErr_Format(PyExc_TypeError, + "end must be None or a string, not %.200s", + end->ob_type->tp_name); + return NULL; + } + + for (i = 0; i < nargs; i++) { + if (i > 0) { + if (sep == NULL) + err = PyFile_WriteString(" ", file); + else + err = PyFile_WriteObject(sep, file, + Py_PRINT_RAW); + if (err) + return NULL; + } + err = PyFile_WriteObject(args[i], file, Py_PRINT_RAW); + if (err) + return NULL; + } + + if (end == NULL) + err = PyFile_WriteString("\n", file); + else + err = PyFile_WriteObject(end, file, Py_PRINT_RAW); + if (err) + return NULL; + + if (flush != NULL) { + PyObject *tmp; + int do_flush = PyObject_IsTrue(flush); + if (do_flush == -1) + return NULL; + else if (do_flush) { + tmp = _PyObject_CallMethodId(file, &PyId_flush, NULL); + if (tmp == NULL) + return NULL; + else + Py_DECREF(tmp); + } + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(print_doc, +"print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n\ +\n\ +Prints the values to a stream, or to sys.stdout by default.\n\ +Optional keyword arguments:\n\ +file: a file-like object (stream); defaults to the current sys.stdout.\n\ +sep: string inserted between values, default a space.\n\ +end: string appended after the last value, default a newline.\n\ +flush: whether to forcibly flush the stream."); + + +/*[clinic input] +input as builtin_input + + prompt: object(c_default="NULL") = None + / + +Read a string from standard input. The trailing newline is stripped. + +The prompt string, if given, is printed to standard output without a +trailing newline before reading input. + +If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError. +On *nix systems, readline is used if available. +[clinic start generated code]*/ + +static PyObject * +builtin_input_impl(PyObject *module, PyObject *prompt) +/*[clinic end generated code: output=83db5a191e7a0d60 input=5e8bb70c2908fe3c]*/ +{ + PyObject *fin = _PySys_GetObjectId(&PyId_stdin); + PyObject *fout = _PySys_GetObjectId(&PyId_stdout); + PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); + PyObject *tmp; + long fd; + int tty; + + /* Check that stdin/out/err are intact */ + if (fin == NULL || fin == Py_None) { + PyErr_SetString(PyExc_RuntimeError, + "input(): lost sys.stdin"); + return NULL; + } + if (fout == NULL || fout == Py_None) { + PyErr_SetString(PyExc_RuntimeError, + "input(): lost sys.stdout"); + return NULL; + } + if (ferr == NULL || ferr == Py_None) { + PyErr_SetString(PyExc_RuntimeError, + "input(): lost sys.stderr"); + return NULL; + } + + if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) { + return NULL; + } + + /* First of all, flush stderr */ + tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); + if (tmp == NULL) + PyErr_Clear(); + else + Py_DECREF(tmp); + + /* We should only use (GNU) readline if Python's sys.stdin and + sys.stdout are the same as C's stdin and stdout, because we + need to pass it those. */ + tmp = _PyObject_CallMethodId(fin, &PyId_fileno, NULL); + if (tmp == NULL) { + PyErr_Clear(); + tty = 0; + } + else { + fd = PyLong_AsLong(tmp); + Py_DECREF(tmp); + if (fd < 0 && PyErr_Occurred()) + return NULL; + tty = fd == fileno(stdin) && isatty(fd); + } + if (tty) { + tmp = _PyObject_CallMethodId(fout, &PyId_fileno, NULL); + if (tmp == NULL) { + PyErr_Clear(); + tty = 0; + } + else { + fd = PyLong_AsLong(tmp); + Py_DECREF(tmp); + if (fd < 0 && PyErr_Occurred()) + return NULL; + tty = fd == fileno(stdout) && isatty(fd); + } + } + + /* If we're interactive, use (GNU) readline */ + if (tty) { + PyObject *po = NULL; + const char *promptstr; + char *s = NULL; + PyObject *stdin_encoding = NULL, *stdin_errors = NULL; + PyObject *stdout_encoding = NULL, *stdout_errors = NULL; + const char *stdin_encoding_str, *stdin_errors_str; + PyObject *result; + size_t len; + + /* stdin is a text stream, so it must have an encoding. */ + stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding); + stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors); + if (!stdin_encoding || !stdin_errors || + !PyUnicode_Check(stdin_encoding) || + !PyUnicode_Check(stdin_errors)) { + tty = 0; + goto _readline_errors; + } + stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding); + stdin_errors_str = PyUnicode_AsUTF8(stdin_errors); + if (!stdin_encoding_str || !stdin_errors_str) + goto _readline_errors; + tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL); + if (tmp == NULL) + PyErr_Clear(); + else + Py_DECREF(tmp); + if (prompt != NULL) { + /* We have a prompt, encode it as stdout would */ + const char *stdout_encoding_str, *stdout_errors_str; + PyObject *stringpo; + stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); + stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors); + if (!stdout_encoding || !stdout_errors || + !PyUnicode_Check(stdout_encoding) || + !PyUnicode_Check(stdout_errors)) { + tty = 0; + goto _readline_errors; + } + stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding); + stdout_errors_str = PyUnicode_AsUTF8(stdout_errors); + if (!stdout_encoding_str || !stdout_errors_str) + goto _readline_errors; + stringpo = PyObject_Str(prompt); + if (stringpo == NULL) + goto _readline_errors; + po = PyUnicode_AsEncodedString(stringpo, + stdout_encoding_str, stdout_errors_str); + Py_CLEAR(stdout_encoding); + Py_CLEAR(stdout_errors); + Py_CLEAR(stringpo); + if (po == NULL) + goto _readline_errors; + assert(PyBytes_Check(po)); + promptstr = PyBytes_AS_STRING(po); + } + else { + po = NULL; + promptstr = ""; + } + s = PyOS_Readline(stdin, stdout, promptstr); + if (s == NULL) { + PyErr_CheckSignals(); + if (!PyErr_Occurred()) + PyErr_SetNone(PyExc_KeyboardInterrupt); + goto _readline_errors; + } + + len = strlen(s); + if (len == 0) { + PyErr_SetNone(PyExc_EOFError); + result = NULL; + } + else { + if (len > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "input: input too long"); + result = NULL; + } + else { + len--; /* strip trailing '\n' */ + if (len != 0 && s[len-1] == '\r') + len--; /* strip trailing '\r' */ + result = PyUnicode_Decode(s, len, stdin_encoding_str, + stdin_errors_str); + } + } + Py_DECREF(stdin_encoding); + Py_DECREF(stdin_errors); + Py_XDECREF(po); + PyMem_FREE(s); + + if (result != NULL) { + if (PySys_Audit("builtins.input/result", "O", result) < 0) { + return NULL; + } + } + + return result; + + _readline_errors: + Py_XDECREF(stdin_encoding); + Py_XDECREF(stdout_encoding); + Py_XDECREF(stdin_errors); + Py_XDECREF(stdout_errors); + Py_XDECREF(po); + if (tty) + return NULL; + + PyErr_Clear(); + } + + /* Fallback if we're not interactive */ + if (prompt != NULL) { + if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) + return NULL; + } + tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL); + if (tmp == NULL) + PyErr_Clear(); + else + Py_DECREF(tmp); + return PyFile_GetLine(fin, -1); +} + + +/*[clinic input] +repr as builtin_repr + + obj: object + / + +Return the canonical string representation of the object. + +For many object types, including most builtins, eval(repr(obj)) == obj. +[clinic start generated code]*/ + +static PyObject * +builtin_repr(PyObject *module, PyObject *obj) +/*[clinic end generated code: output=7ed3778c44fd0194 input=1c9e6d66d3e3be04]*/ +{ + return PyObject_Repr(obj); +} + + +/*[clinic input] +round as builtin_round + + number: object + ndigits: object = None + +Round a number to a given precision in decimal digits. + +The return value is an integer if ndigits is omitted or None. Otherwise +the return value has the same type as the number. ndigits may be negative. +[clinic start generated code]*/ + +static PyObject * +builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) +/*[clinic end generated code: output=ff0d9dd176c02ede input=275678471d7aca15]*/ +{ + PyObject *round, *result; + + if (Py_TYPE(number)->tp_dict == NULL) { + if (PyType_Ready(Py_TYPE(number)) < 0) + return NULL; + } + + round = _PyObject_LookupSpecial(number, &PyId___round__); + if (round == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "type %.100s doesn't define __round__ method", + Py_TYPE(number)->tp_name); + return NULL; + } + + if (ndigits == Py_None) + result = _PyObject_CallNoArg(round); + else + result = PyObject_CallFunctionObjArgs(round, ndigits, NULL); + Py_DECREF(round); + return result; +} + + +/*AC: we need to keep the kwds dict intact to easily call into the + * list.sort method, which isn't currently supported in AC. So we just use + * the initially generated signature with a custom implementation. + */ +/* [disabled clinic input] +sorted as builtin_sorted + + iterable as seq: object + key as keyfunc: object = None + reverse: object = False + +Return a new list containing all items from the iterable in ascending order. + +A custom key function can be supplied to customize the sort order, and the +reverse flag can be set to request the result in descending order. +[end disabled clinic input]*/ + +PyDoc_STRVAR(builtin_sorted__doc__, +"sorted($module, iterable, /, *, key=None, reverse=False)\n" +"--\n" +"\n" +"Return a new list containing all items from the iterable in ascending order.\n" +"\n" +"A custom key function can be supplied to customize the sort order, and the\n" +"reverse flag can be set to request the result in descending order."); + +#define BUILTIN_SORTED_METHODDEF \ + {"sorted", (PyCFunction)(void(*)(void))builtin_sorted, METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__}, + +static PyObject * +builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *newlist, *v, *seq, *callable; + + /* Keyword arguments are passed through list.sort() which will check + them. */ + if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq)) + return NULL; + + newlist = PySequence_List(seq); + if (newlist == NULL) + return NULL; + + callable = _PyObject_GetAttrId(newlist, &PyId_sort); + if (callable == NULL) { + Py_DECREF(newlist); + return NULL; + } + + assert(nargs >= 1); + v = _PyObject_Vectorcall(callable, args + 1, nargs - 1, kwnames); + Py_DECREF(callable); + if (v == NULL) { + Py_DECREF(newlist); + return NULL; + } + Py_DECREF(v); + return newlist; +} + + +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +static PyObject * +builtin_vars(PyObject *self, PyObject *args) +{ + PyObject *v = NULL; + PyObject *d; + + if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) + return NULL; + if (v == NULL) { + d = PyEval_GetLocals(); + Py_XINCREF(d); + } + else { + if (_PyObject_LookupAttrId(v, &PyId___dict__, &d) == 0) { + PyErr_SetString(PyExc_TypeError, + "vars() argument must have __dict__ attribute"); + } + } + return d; +} + +PyDoc_STRVAR(vars_doc, +"vars([object]) -> dictionary\n\ +\n\ +Without arguments, equivalent to locals().\n\ +With an argument, equivalent to object.__dict__."); + + +/*[clinic input] +sum as builtin_sum + + iterable: object + / + start: object(c_default="NULL") = 0 + +Return the sum of a 'start' value (default: 0) plus an iterable of numbers + +When the iterable is empty, return the start value. +This function is intended specifically for use with numeric values and may +reject non-numeric types. +[clinic start generated code]*/ + +static PyObject * +builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) +/*[clinic end generated code: output=df758cec7d1d302f input=162b50765250d222]*/ +{ + PyObject *result = start; + PyObject *temp, *item, *iter; + + iter = PyObject_GetIter(iterable); + if (iter == NULL) + return NULL; + + if (result == NULL) { + result = PyLong_FromLong(0); + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } else { + /* reject string values for 'start' parameter */ + if (PyUnicode_Check(result)) { + PyErr_SetString(PyExc_TypeError, + "sum() can't sum strings [use ''.join(seq) instead]"); + Py_DECREF(iter); + return NULL; + } + if (PyBytes_Check(result)) { + PyErr_SetString(PyExc_TypeError, + "sum() can't sum bytes [use b''.join(seq) instead]"); + Py_DECREF(iter); + return NULL; + } + if (PyByteArray_Check(result)) { + PyErr_SetString(PyExc_TypeError, + "sum() can't sum bytearray [use b''.join(seq) instead]"); + Py_DECREF(iter); + return NULL; + } + Py_INCREF(result); + } + +#ifndef SLOW_SUM + /* Fast addition by keeping temporary sums in C instead of new Python objects. + Assumes all inputs are the same type. If the assumption fails, default + to the more general routine. + */ + if (PyLong_CheckExact(result)) { + int overflow; + long i_result = PyLong_AsLongAndOverflow(result, &overflow); + /* If this already overflowed, don't even enter the loop. */ + if (overflow == 0) { + Py_DECREF(result); + result = NULL; + } + while(result == NULL) { + item = PyIter_Next(iter); + if (item == NULL) { + Py_DECREF(iter); + if (PyErr_Occurred()) + return NULL; + return PyLong_FromLong(i_result); + } + if (PyLong_CheckExact(item)) { + long b = PyLong_AsLongAndOverflow(item, &overflow); + if (overflow == 0 && + (i_result >= 0 ? (b <= LONG_MAX - i_result) + : (b >= LONG_MIN - i_result))) + { + i_result += b; + Py_DECREF(item); + continue; + } + } + /* Either overflowed or is not an int. Restore real objects and process normally */ + result = PyLong_FromLong(i_result); + if (result == NULL) { + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + temp = PyNumber_Add(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } + } + + if (PyFloat_CheckExact(result)) { + double f_result = PyFloat_AS_DOUBLE(result); + Py_DECREF(result); + result = NULL; + while(result == NULL) { + item = PyIter_Next(iter); + if (item == NULL) { + Py_DECREF(iter); + if (PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble(f_result); + } + if (PyFloat_CheckExact(item)) { + PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) + f_result += PyFloat_AS_DOUBLE(item); + PyFPE_END_PROTECT(f_result) + Py_DECREF(item); + continue; + } + if (PyLong_CheckExact(item)) { + long value; + int overflow; + value = PyLong_AsLongAndOverflow(item, &overflow); + if (!overflow) { + PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) + f_result += (double)value; + PyFPE_END_PROTECT(f_result) + Py_DECREF(item); + continue; + } + } + result = PyFloat_FromDouble(f_result); + if (result == NULL) { + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + temp = PyNumber_Add(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } + } +#endif + + for(;;) { + item = PyIter_Next(iter); + if (item == NULL) { + /* error, or end-of-sequence */ + if (PyErr_Occurred()) { + Py_DECREF(result); + result = NULL; + } + break; + } + /* It's tempting to use PyNumber_InPlaceAdd instead of + PyNumber_Add here, to avoid quadratic running time + when doing 'sum(list_of_lists, [])'. However, this + would produce a change in behaviour: a snippet like + + empty = [] + sum([[x] for x in range(10)], empty) + + would change the value of empty. */ + temp = PyNumber_Add(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) + break; + } + Py_DECREF(iter); + return result; +} + + +/*[clinic input] +isinstance as builtin_isinstance + + obj: object + class_or_tuple: object + / + +Return whether an object is an instance of a class or of a subclass thereof. + +A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to +check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B) +or ...`` etc. +[clinic start generated code]*/ + +static PyObject * +builtin_isinstance_impl(PyObject *module, PyObject *obj, + PyObject *class_or_tuple) +/*[clinic end generated code: output=6faf01472c13b003 input=ffa743db1daf7549]*/ +{ + int retval; + + retval = PyObject_IsInstance(obj, class_or_tuple); + if (retval < 0) + return NULL; + return PyBool_FromLong(retval); +} + + +/*[clinic input] +issubclass as builtin_issubclass + + cls: object + class_or_tuple: object + / + +Return whether 'cls' is a derived from another class or is the same class. + +A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to +check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B) +or ...`` etc. +[clinic start generated code]*/ + +static PyObject * +builtin_issubclass_impl(PyObject *module, PyObject *cls, + PyObject *class_or_tuple) +/*[clinic end generated code: output=358412410cd7a250 input=af5f35e9ceaddaf6]*/ +{ + int retval; + + retval = PyObject_IsSubclass(cls, class_or_tuple); + if (retval < 0) + return NULL; + return PyBool_FromLong(retval); +} + + +typedef struct { + PyObject_HEAD + Py_ssize_t tuplesize; + PyObject *ittuple; /* tuple of iterators */ + PyObject *result; +} zipobject; + +static PyObject * +zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + zipobject *lz; + Py_ssize_t i; + PyObject *ittuple; /* tuple of iterators */ + PyObject *result; + Py_ssize_t tuplesize; + + if (type == &PyZip_Type && !_PyArg_NoKeywords("zip", kwds)) + 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 zipobject structure */ + lz = (zipobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(ittuple); + Py_DECREF(result); + return NULL; + } + lz->ittuple = ittuple; + lz->tuplesize = tuplesize; + lz->result = result; + + return (PyObject *)lz; +} + +static void +zip_dealloc(zipobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->ittuple); + Py_XDECREF(lz->result); + Py_TYPE(lz)->tp_free(lz); +} + +static int +zip_traverse(zipobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->ittuple); + Py_VISIT(lz->result); + return 0; +} + +static PyObject * +zip_next(zipobject *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 (Py_REFCNT(result) == 1) { + Py_INCREF(result); + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); + item = (*Py_TYPE(it)->tp_iternext)(it); + if (item == NULL) { + Py_DECREF(result); + return NULL; + } + 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); + item = (*Py_TYPE(it)->tp_iternext)(it); + if (item == NULL) { + Py_DECREF(result); + return NULL; + } + PyTuple_SET_ITEM(result, i, item); + } + } + return result; +} + +static PyObject * +zip_reduce(zipobject *lz, PyObject *Py_UNUSED(ignored)) +{ + /* Just recreate the zip with the internal iterator tuple */ + return Py_BuildValue("OO", Py_TYPE(lz), lz->ittuple); +} + +static PyMethodDef zip_methods[] = { + {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(zip_doc, +"zip(*iterables) --> A zip object yielding tuples until an input is exhausted.\n\ +\n\ + >>> list(zip('abcdefg', range(3), range(4)))\n\ + [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]\n\ +\n\ +The zip object yields n-length tuples, where n is the number of iterables\n\ +passed as positional arguments to zip(). The i-th element in every tuple\n\ +comes from the i-th iterable argument to zip(). This continues until the\n\ +shortest argument is exhausted."); + +PyTypeObject PyZip_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "zip", /* tp_name */ + sizeof(zipobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)zip_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 */ + zip_doc, /* tp_doc */ + (traverseproc)zip_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)zip_next, /* tp_iternext */ + zip_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 */ + zip_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +static PyMethodDef builtin_methods[] = { + {"__build_class__", (PyCFunction)(void(*)(void))builtin___build_class__, + METH_FASTCALL | METH_KEYWORDS, build_class_doc}, + {"__import__", (PyCFunction)(void(*)(void))builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, + BUILTIN_ABS_METHODDEF + BUILTIN_ALL_METHODDEF + BUILTIN_ANY_METHODDEF + BUILTIN_ASCII_METHODDEF + BUILTIN_BIN_METHODDEF + {"breakpoint", (PyCFunction)(void(*)(void))builtin_breakpoint, METH_FASTCALL | METH_KEYWORDS, breakpoint_doc}, + BUILTIN_CALLABLE_METHODDEF + BUILTIN_CHR_METHODDEF + BUILTIN_COMPILE_METHODDEF + BUILTIN_DELATTR_METHODDEF + {"dir", builtin_dir, METH_VARARGS, dir_doc}, + BUILTIN_DIVMOD_METHODDEF + BUILTIN_EVAL_METHODDEF + BUILTIN_EXEC_METHODDEF + BUILTIN_FORMAT_METHODDEF + {"getattr", (PyCFunction)(void(*)(void))builtin_getattr, METH_FASTCALL, getattr_doc}, + BUILTIN_GLOBALS_METHODDEF + BUILTIN_HASATTR_METHODDEF + BUILTIN_HASH_METHODDEF + BUILTIN_HEX_METHODDEF + BUILTIN_ID_METHODDEF + BUILTIN_INPUT_METHODDEF + BUILTIN_ISINSTANCE_METHODDEF + BUILTIN_ISSUBCLASS_METHODDEF + {"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc}, + BUILTIN_LEN_METHODDEF + BUILTIN_LOCALS_METHODDEF + {"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, + {"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, + {"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc}, + BUILTIN_OCT_METHODDEF + BUILTIN_ORD_METHODDEF + BUILTIN_POW_METHODDEF + {"print", (PyCFunction)(void(*)(void))builtin_print, METH_FASTCALL | METH_KEYWORDS, print_doc}, + BUILTIN_REPR_METHODDEF + BUILTIN_ROUND_METHODDEF + BUILTIN_SETATTR_METHODDEF + BUILTIN_SORTED_METHODDEF + BUILTIN_SUM_METHODDEF + {"vars", builtin_vars, METH_VARARGS, vars_doc}, + {NULL, NULL}, +}; + +PyDoc_STRVAR(builtin_doc, +"Built-in functions, exceptions, and other objects.\n\ +\n\ +Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices."); + +static struct PyModuleDef builtinsmodule = { + PyModuleDef_HEAD_INIT, + "builtins", + builtin_doc, + -1, /* multiple "initialization" just copies the module dict. */ + builtin_methods, + NULL, + NULL, + NULL, + NULL +}; + + +PyObject * +_PyBuiltin_Init(void) +{ + PyObject *mod, *dict, *debug; + + const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + + if (PyType_Ready(&PyFilter_Type) < 0 || + PyType_Ready(&PyMap_Type) < 0 || + PyType_Ready(&PyZip_Type) < 0) + return NULL; + + mod = _PyModule_CreateInitialized(&builtinsmodule, PYTHON_API_VERSION); + if (mod == NULL) + return NULL; + dict = PyModule_GetDict(mod); + +#ifdef Py_TRACE_REFS + /* "builtins" exposes a number of statically allocated objects + * that, before this code was added in 2.3, never showed up in + * the list of "all objects" maintained by Py_TRACE_REFS. As a + * result, programs leaking references to None and False (etc) + * couldn't be diagnosed by examining sys.getobjects(0). + */ +#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT), 0) +#else +#define ADD_TO_ALL(OBJECT) (void)0 +#endif + +#define SETBUILTIN(NAME, OBJECT) \ + if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0) \ + return NULL; \ + ADD_TO_ALL(OBJECT) + + SETBUILTIN("None", Py_None); + SETBUILTIN("Ellipsis", Py_Ellipsis); + SETBUILTIN("NotImplemented", Py_NotImplemented); + SETBUILTIN("False", Py_False); + SETBUILTIN("True", Py_True); + SETBUILTIN("bool", &PyBool_Type); + SETBUILTIN("memoryview", &PyMemoryView_Type); + SETBUILTIN("bytearray", &PyByteArray_Type); + SETBUILTIN("bytes", &PyBytes_Type); + SETBUILTIN("classmethod", &PyClassMethod_Type); + SETBUILTIN("complex", &PyComplex_Type); + SETBUILTIN("dict", &PyDict_Type); + SETBUILTIN("enumerate", &PyEnum_Type); + SETBUILTIN("filter", &PyFilter_Type); + SETBUILTIN("float", &PyFloat_Type); + SETBUILTIN("frozenset", &PyFrozenSet_Type); + SETBUILTIN("property", &PyProperty_Type); + SETBUILTIN("int", &PyLong_Type); + SETBUILTIN("list", &PyList_Type); + SETBUILTIN("map", &PyMap_Type); + SETBUILTIN("object", &PyBaseObject_Type); + SETBUILTIN("range", &PyRange_Type); + SETBUILTIN("reversed", &PyReversed_Type); + SETBUILTIN("set", &PySet_Type); + SETBUILTIN("slice", &PySlice_Type); + SETBUILTIN("staticmethod", &PyStaticMethod_Type); + SETBUILTIN("str", &PyUnicode_Type); + SETBUILTIN("super", &PySuper_Type); + SETBUILTIN("tuple", &PyTuple_Type); + SETBUILTIN("type", &PyType_Type); + SETBUILTIN("zip", &PyZip_Type); + debug = PyBool_FromLong(config->optimization_level == 0); + if (PyDict_SetItemString(dict, "__debug__", debug) < 0) { + Py_DECREF(debug); + return NULL; + } + Py_DECREF(debug); + + return mod; +#undef ADD_TO_ALL +#undef SETBUILTIN +} diff --git a/python/Python/bootstrap_hash.c b/python/Python/bootstrap_hash.c new file mode 100755 index 0000000..eb2b6d0 --- /dev/null +++ b/python/Python/bootstrap_hash.c @@ -0,0 +1,601 @@ +#include "Python.h" +#include "pycore_initconfig.h" +#ifdef MS_WINDOWS +# include +/* All sample MSDN wincrypt programs include the header below. It is at least + * required with Min GW. */ +# include +#else +# include +# ifdef HAVE_SYS_STAT_H +# include +# endif +# ifdef HAVE_LINUX_RANDOM_H +# include +# endif +# if defined(HAVE_SYS_RANDOM_H) && (defined(HAVE_GETRANDOM) || defined(HAVE_GETENTROPY)) +# include +# endif +# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL) +# include +# endif +#endif + +#ifdef _Py_MEMORY_SANITIZER +# include +#endif + +#ifdef Py_DEBUG +int _Py_HashSecret_Initialized = 0; +#else +static int _Py_HashSecret_Initialized = 0; +#endif + +#ifdef MS_WINDOWS +static HCRYPTPROV hCryptProv = 0; + +static int +win32_urandom_init(int raise) +{ + /* Acquire context */ + if (!CryptAcquireContextW(&hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + goto error; + + return 0; + +error: + if (raise) { + PyErr_SetFromWindowsErr(0); + } + return -1; +} + +/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen + API. Return 0 on success, or raise an exception and return -1 on error. */ +static int +win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) +{ + if (hCryptProv == 0) + { + if (win32_urandom_init(raise) == -1) { + return -1; + } + } + + while (size > 0) + { + DWORD chunk = (DWORD)Py_MIN(size, PY_DWORD_MAX); + if (!CryptGenRandom(hCryptProv, chunk, buffer)) + { + /* CryptGenRandom() failed */ + if (raise) { + PyErr_SetFromWindowsErr(0); + } + return -1; + } + buffer += chunk; + size -= chunk; + } + return 0; +} + +#else /* !MS_WINDOWS */ + +#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) +#define PY_GETRANDOM 1 + +/* Call getrandom() to get random bytes: + + - Return 1 on success + - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM), + or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not + initialized yet) and raise=0. + - Raise an exception (if raise is non-zero) and return -1 on error: + if getrandom() failed with EINTR, raise is non-zero and the Python signal + handler raised an exception, or if getrandom() failed with a different + error. + + getrandom() is retried if it failed with EINTR: interrupted by a signal. */ +static int +py_getrandom(void *buffer, Py_ssize_t size, int blocking, int raise) +{ + /* Is getrandom() supported by the running kernel? Set to 0 if getrandom() + failed with ENOSYS or EPERM. Need Linux kernel 3.17 or newer, or Solaris + 11.3 or newer */ + static int getrandom_works = 1; + int flags; + char *dest; + long n; + + if (!getrandom_works) { + return 0; + } + + flags = blocking ? 0 : GRND_NONBLOCK; + dest = buffer; + while (0 < size) { +#if defined(__sun) && defined(__SVR4) + /* Issue #26735: On Solaris, getrandom() is limited to returning up + to 1024 bytes. Call it multiple times if more bytes are + requested. */ + n = Py_MIN(size, 1024); +#else + n = Py_MIN(size, LONG_MAX); +#endif + + errno = 0; +#ifdef HAVE_GETRANDOM + if (raise) { + Py_BEGIN_ALLOW_THREADS + n = getrandom(dest, n, flags); + Py_END_ALLOW_THREADS + } + else { + n = getrandom(dest, n, flags); + } +#else + /* On Linux, use the syscall() function because the GNU libc doesn't + expose the Linux getrandom() syscall yet. See: + https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */ + if (raise) { + Py_BEGIN_ALLOW_THREADS + n = syscall(SYS_getrandom, dest, n, flags); + Py_END_ALLOW_THREADS + } + else { + n = syscall(SYS_getrandom, dest, n, flags); + } +# ifdef _Py_MEMORY_SANITIZER + if (n > 0) { + __msan_unpoison(dest, n); + } +# endif +#endif + + if (n < 0) { + /* ENOSYS: the syscall is not supported by the kernel. + EPERM: the syscall is blocked by a security policy (ex: SECCOMP) + or something else. */ + if (errno == ENOSYS || errno == EPERM) { + getrandom_works = 0; + return 0; + } + + /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system urandom + is not initialiazed yet. For _PyRandom_Init(), we ignore the + error and fall back on reading /dev/urandom which never blocks, + even if the system urandom is not initialized yet: + see the PEP 524. */ + if (errno == EAGAIN && !raise && !blocking) { + return 0; + } + + if (errno == EINTR) { + if (raise) { + if (PyErr_CheckSignals()) { + return -1; + } + } + + /* retry getrandom() if it was interrupted by a signal */ + continue; + } + + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; + } + + dest += n; + size -= n; + } + return 1; +} + +#elif defined(HAVE_GETENTROPY) +#define PY_GETENTROPY 1 + +/* Fill buffer with size pseudo-random bytes generated by getentropy(): + + - Return 1 on success + - Return 0 if getentropy() syscall is not available (failed with ENOSYS or + EPERM). + - Raise an exception (if raise is non-zero) and return -1 on error: + if getentropy() failed with EINTR, raise is non-zero and the Python signal + handler raised an exception, or if getentropy() failed with a different + error. + + getentropy() is retried if it failed with EINTR: interrupted by a signal. */ +static int +py_getentropy(char *buffer, Py_ssize_t size, int raise) +{ + /* Is getentropy() supported by the running kernel? Set to 0 if + getentropy() failed with ENOSYS or EPERM. */ + static int getentropy_works = 1; + + if (!getentropy_works) { + return 0; + } + + while (size > 0) { + /* getentropy() is limited to returning up to 256 bytes. Call it + multiple times if more bytes are requested. */ + Py_ssize_t len = Py_MIN(size, 256); + int res; + + if (raise) { + Py_BEGIN_ALLOW_THREADS + res = getentropy(buffer, len); + Py_END_ALLOW_THREADS + } + else { + res = getentropy(buffer, len); + } + + if (res < 0) { + /* ENOSYS: the syscall is not supported by the running kernel. + EPERM: the syscall is blocked by a security policy (ex: SECCOMP) + or something else. */ + if (errno == ENOSYS || errno == EPERM) { + getentropy_works = 0; + return 0; + } + + if (errno == EINTR) { + if (raise) { + if (PyErr_CheckSignals()) { + return -1; + } + } + + /* retry getentropy() if it was interrupted by a signal */ + continue; + } + + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; + } + + buffer += len; + size -= len; + } + return 1; +} +#endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */ + + +static struct { + int fd; + dev_t st_dev; + ino_t st_ino; +} urandom_cache = { -1 }; + +/* Read random bytes from the /dev/urandom device: + + - Return 0 on success + - Raise an exception (if raise is non-zero) and return -1 on error + + Possible causes of errors: + + - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device + was not found. For example, it was removed manually or not exposed in a + chroot or container. + - open() failed with a different error + - fstat() failed + - read() failed or returned 0 + + read() is retried if it failed with EINTR: interrupted by a signal. + + The file descriptor of the device is kept open between calls to avoid using + many file descriptors when run in parallel from multiple threads: + see the issue #18756. + + st_dev and st_ino fields of the file descriptor (from fstat()) are cached to + check if the file descriptor was replaced by a different file (which is + likely a bug in the application): see the issue #21207. + + If the file descriptor was closed or replaced, open a new file descriptor + but don't close the old file descriptor: it probably points to something + important for some third-party code. */ +static int +dev_urandom(char *buffer, Py_ssize_t size, int raise) +{ + int fd; + Py_ssize_t n; + + if (raise) { + struct _Py_stat_struct st; + int fstat_result; + + if (urandom_cache.fd >= 0) { + Py_BEGIN_ALLOW_THREADS + fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st); + Py_END_ALLOW_THREADS + + /* Does the fd point to the same thing as before? (issue #21207) */ + if (fstat_result + || st.st_dev != urandom_cache.st_dev + || st.st_ino != urandom_cache.st_ino) { + /* Something changed: forget the cached fd (but don't close it, + since it probably points to something important for some + third-party code). */ + urandom_cache.fd = -1; + } + } + if (urandom_cache.fd >= 0) + fd = urandom_cache.fd; + else { + fd = _Py_open("/dev/urandom", O_RDONLY); + if (fd < 0) { + if (errno == ENOENT || errno == ENXIO || + errno == ENODEV || errno == EACCES) { + PyErr_SetString(PyExc_NotImplementedError, + "/dev/urandom (or equivalent) not found"); + } + /* otherwise, keep the OSError exception raised by _Py_open() */ + return -1; + } + if (urandom_cache.fd >= 0) { + /* urandom_fd was initialized by another thread while we were + not holding the GIL, keep it. */ + close(fd); + fd = urandom_cache.fd; + } + else { + if (_Py_fstat(fd, &st)) { + close(fd); + return -1; + } + else { + urandom_cache.fd = fd; + urandom_cache.st_dev = st.st_dev; + urandom_cache.st_ino = st.st_ino; + } + } + } + + do { + n = _Py_read(fd, buffer, (size_t)size); + if (n == -1) + return -1; + if (n == 0) { + PyErr_Format(PyExc_RuntimeError, + "Failed to read %zi bytes from /dev/urandom", + size); + return -1; + } + + buffer += n; + size -= n; + } while (0 < size); + } + else { + fd = _Py_open_noraise("/dev/urandom", O_RDONLY); + if (fd < 0) { + return -1; + } + + while (0 < size) + { + do { + n = read(fd, buffer, (size_t)size); + } while (n < 0 && errno == EINTR); + + if (n <= 0) { + /* stop on error or if read(size) returned 0 */ + close(fd); + return -1; + } + + buffer += n; + size -= n; + } + close(fd); + } + return 0; +} + +static void +dev_urandom_close(void) +{ + if (urandom_cache.fd >= 0) { + close(urandom_cache.fd); + urandom_cache.fd = -1; + } +} +#endif /* !MS_WINDOWS */ + + +/* Fill buffer with pseudo-random bytes generated by a linear congruent + generator (LCG): + + x(n+1) = (x(n) * 214013 + 2531011) % 2^32 + + Use bits 23..16 of x(n) to generate a byte. */ +static void +lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) +{ + size_t index; + unsigned int x; + + x = x0; + for (index=0; index < size; index++) { + x *= 214013; + x += 2531011; + /* modulo 2 ^ (8 * sizeof(int)) */ + buffer[index] = (x >> 16) & 0xff; + } +} + +/* Read random bytes: + + - Return 0 on success + - Raise an exception (if raise is non-zero) and return -1 on error + + Used sources of entropy ordered by preference, preferred source first: + + - CryptGenRandom() on Windows + - getrandom() function (ex: Linux and Solaris): call py_getrandom() + - getentropy() function (ex: OpenBSD): call py_getentropy() + - /dev/urandom device + + Read from the /dev/urandom device if getrandom() or getentropy() function + is not available or does not work. + + Prefer getrandom() over getentropy() because getrandom() supports blocking + and non-blocking mode: see the PEP 524. Python requires non-blocking RNG at + startup to initialize its hash secret, but os.urandom() must block until the + system urandom is initialized (at least on Linux 3.17 and newer). + + Prefer getrandom() and getentropy() over reading directly /dev/urandom + because these functions don't need file descriptors and so avoid ENFILE or + EMFILE errors (too many open files): see the issue #18756. + + Only the getrandom() function supports non-blocking mode. + + Only use RNG running in the kernel. They are more secure because it is + harder to get the internal state of a RNG running in the kernel land than a + RNG running in the user land. The kernel has a direct access to the hardware + and has access to hardware RNG, they are used as entropy sources. + + Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed + its RNG on fork(), two child processes (with the same pid) generate the same + random numbers: see issue #18747. Kernel RNGs don't have this issue, + they have access to good quality entropy sources. + + If raise is zero: + + - Don't raise an exception on error + - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if + a function fails with EINTR: retry directly the interrupted function + - Don't release the GIL to call functions. +*/ +static int +pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise) +{ +#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) + int res; +#endif + + if (size < 0) { + if (raise) { + PyErr_Format(PyExc_ValueError, + "negative argument not allowed"); + } + return -1; + } + + if (size == 0) { + return 0; + } + +#ifdef MS_WINDOWS + return win32_urandom((unsigned char *)buffer, size, raise); +#else + +#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY) +#ifdef PY_GETRANDOM + res = py_getrandom(buffer, size, blocking, raise); +#else + res = py_getentropy(buffer, size, raise); +#endif + if (res < 0) { + return -1; + } + if (res == 1) { + return 0; + } + /* getrandom() or getentropy() function is not available: failed with + ENOSYS or EPERM. Fall back on reading from /dev/urandom. */ +#endif + + return dev_urandom(buffer, size, raise); +#endif +} + +/* Fill buffer with size pseudo-random bytes from the operating system random + number generator (RNG). It is suitable for most cryptographic purposes + except long living private keys for asymmetric encryption. + + On Linux 3.17 and newer, the getrandom() syscall is used in blocking mode: + block until the system urandom entropy pool is initialized (128 bits are + collected by the kernel). + + Return 0 on success. Raise an exception and return -1 on error. */ +int +_PyOS_URandom(void *buffer, Py_ssize_t size) +{ + return pyurandom(buffer, size, 1, 1); +} + +/* Fill buffer with size pseudo-random bytes from the operating system random + number generator (RNG). It is not suitable for cryptographic purpose. + + On Linux 3.17 and newer (when getrandom() syscall is used), if the system + urandom is not initialized yet, the function returns "weak" entropy read + from /dev/urandom. + + Return 0 on success. Raise an exception and return -1 on error. */ +int +_PyOS_URandomNonblock(void *buffer, Py_ssize_t size) +{ + return pyurandom(buffer, size, 0, 1); +} + + +PyStatus +_Py_HashRandomization_Init(const PyConfig *config) +{ + void *secret = &_Py_HashSecret; + Py_ssize_t secret_size = sizeof(_Py_HashSecret_t); + + if (_Py_HashSecret_Initialized) { + return _PyStatus_OK(); + } + _Py_HashSecret_Initialized = 1; + + if (config->use_hash_seed) { + if (config->hash_seed == 0) { + /* disable the randomized hash */ + memset(secret, 0, secret_size); + } + else { + /* use the specified hash seed */ + lcg_urandom(config->hash_seed, secret, secret_size); + } + } + else { + /* use a random hash seed */ + int res; + + /* _PyRandom_Init() is called very early in the Python initialization + and so exceptions cannot be used (use raise=0). + + _PyRandom_Init() must not block Python initialization: call + pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */ + res = pyurandom(secret, secret_size, 0, 0); + if (res < 0) { + return _PyStatus_ERR("failed to get random numbers " + "to initialize Python"); + } + } + return _PyStatus_OK(); +} + + +void +_Py_HashRandomization_Fini(void) +{ +#ifdef MS_WINDOWS + if (hCryptProv) { + CryptReleaseContext(hCryptProv, 0); + hCryptProv = 0; + } +#else + dev_urandom_close(); +#endif +} diff --git a/python/Python/ceval.c b/python/Python/ceval.c new file mode 100755 index 0000000..1873e37 --- /dev/null +++ b/python/Python/ceval.c @@ -0,0 +1,5619 @@ + +/* Execute compiled code */ + +/* XXX TO DO: + XXX speed up searching for keywords by using a dictionary + XXX document it! + */ + +/* enable more aggressive intra-module optimizations, where available */ +#define PY_LOCAL_AGGRESSIVE + +#include "Python.h" +#include "pycore_ceval.h" +#include "pycore_code.h" +#include "pycore_object.h" +#include "pycore_pyerrors.h" +#include "pycore_pylifecycle.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" + +#include "code.h" +#include "dictobject.h" +#include "frameobject.h" +#include "opcode.h" +#include "pydtrace.h" +#include "setobject.h" +#include "structmember.h" + +#include + +#ifdef Py_DEBUG +/* For debugging the interpreter: */ +#define LLTRACE 1 /* Low-level trace feature */ +#define CHECKEXC 1 /* Double-check exception checking */ +#endif + +#if !defined(Py_BUILD_CORE) +# error "ceval.c must be build with Py_BUILD_CORE define for best performance" +#endif + +/* Private API for the LOAD_METHOD opcode. */ +extern int _PyObject_GetMethod(PyObject *, PyObject *, PyObject **); + +typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *); + +/* Forward declarations */ +Py_LOCAL_INLINE(PyObject *) call_function( + PyThreadState *tstate, PyObject ***pp_stack, + Py_ssize_t oparg, PyObject *kwnames); +static PyObject * do_call_core( + PyThreadState *tstate, PyObject *func, + PyObject *callargs, PyObject *kwdict); + +#ifdef LLTRACE +static int lltrace; +static int prtrace(PyThreadState *, PyObject *, const char *); +#endif +static int call_trace(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *, + int, PyObject *); +static int call_trace_protected(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *, + int, PyObject *); +static void call_exc_trace(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *); +static int maybe_call_line_trace(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *, + int *, int *, int *); +static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *); +static void dtrace_function_entry(PyFrameObject *); +static void dtrace_function_return(PyFrameObject *); + +static PyObject * cmp_outcome(PyThreadState *, int, PyObject *, PyObject *); +static PyObject * import_name(PyThreadState *, PyFrameObject *, + PyObject *, PyObject *, PyObject *); +static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); +static int import_all_from(PyThreadState *, PyObject *, PyObject *); +static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); +static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); +static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *, + PyFrameObject *, const _Py_CODEUNIT *); +static PyObject * special_lookup(PyThreadState *, PyObject *, _Py_Identifier *); +static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); +static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); +static void format_awaitable_error(PyThreadState *, PyTypeObject *, int); + +#define NAME_ERROR_MSG \ + "name '%.200s' is not defined" +#define UNBOUNDLOCAL_ERROR_MSG \ + "local variable '%.200s' referenced before assignment" +#define UNBOUNDFREE_ERROR_MSG \ + "free variable '%.200s' referenced before assignment" \ + " in enclosing scope" + +/* Dynamic execution profile */ +#ifdef DYNAMIC_EXECUTION_PROFILE +#ifdef DXPAIRS +static long dxpairs[257][256]; +#define dxp dxpairs[256] +#else +static long dxp[256]; +#endif +#endif + +/* per opcode cache */ +#ifdef Py_DEBUG +// --with-pydebug is used to find memory leak. opcache makes it harder. +// So we disable opcache when Py_DEBUG is defined. +// See bpo-37146 +#define OPCACHE_MIN_RUNS 0 /* disable opcache */ +#else +#define OPCACHE_MIN_RUNS 1024 /* create opcache when code executed this time */ +#endif +#define OPCACHE_STATS 0 /* Enable stats */ + +#if OPCACHE_STATS +static size_t opcache_code_objects = 0; +static size_t opcache_code_objects_extra_mem = 0; + +static size_t opcache_global_opts = 0; +static size_t opcache_global_hits = 0; +static size_t opcache_global_misses = 0; +#endif + +#define GIL_REQUEST _Py_atomic_load_relaxed(&ceval->gil_drop_request) + +/* This can set eval_breaker to 0 even though gil_drop_request became + 1. We believe this is all right because the eval loop will release + the GIL eventually anyway. */ +#define COMPUTE_EVAL_BREAKER(ceval) \ + _Py_atomic_store_relaxed( \ + &(ceval)->eval_breaker, \ + GIL_REQUEST | \ + _Py_atomic_load_relaxed(&(ceval)->signals_pending) | \ + _Py_atomic_load_relaxed(&(ceval)->pending.calls_to_do) | \ + (ceval)->pending.async_exc) + +#define SET_GIL_DROP_REQUEST(ceval) \ + do { \ + _Py_atomic_store_relaxed(&(ceval)->gil_drop_request, 1); \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + } while (0) + +#define RESET_GIL_DROP_REQUEST(ceval) \ + do { \ + _Py_atomic_store_relaxed(&(ceval)->gil_drop_request, 0); \ + COMPUTE_EVAL_BREAKER(ceval); \ + } while (0) + +/* Pending calls are only modified under pending_lock */ +#define SIGNAL_PENDING_CALLS(ceval) \ + do { \ + _Py_atomic_store_relaxed(&(ceval)->pending.calls_to_do, 1); \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + } while (0) + +#define UNSIGNAL_PENDING_CALLS(ceval) \ + do { \ + _Py_atomic_store_relaxed(&(ceval)->pending.calls_to_do, 0); \ + COMPUTE_EVAL_BREAKER(ceval); \ + } while (0) + +#define SIGNAL_PENDING_SIGNALS(ceval) \ + do { \ + _Py_atomic_store_relaxed(&(ceval)->signals_pending, 1); \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + } while (0) + +#define UNSIGNAL_PENDING_SIGNALS(ceval) \ + do { \ + _Py_atomic_store_relaxed(&(ceval)->signals_pending, 0); \ + COMPUTE_EVAL_BREAKER(ceval); \ + } while (0) + +#define SIGNAL_ASYNC_EXC(ceval) \ + do { \ + (ceval)->pending.async_exc = 1; \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + } while (0) + +#define UNSIGNAL_ASYNC_EXC(ceval) \ + do { \ + (ceval)->pending.async_exc = 0; \ + COMPUTE_EVAL_BREAKER(ceval); \ + } while (0) + + +#ifdef HAVE_ERRNO_H +#include +#endif +#include "pythread.h" +#include "ceval_gil.h" + +int +PyEval_ThreadsInitialized(void) +{ + return gil_created(&_PyRuntime.ceval.gil); +} + +void +PyEval_InitThreads(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _gil_runtime_state *gil = &ceval->gil; + if (gil_created(gil)) { + return; + } + + PyThread_init_thread(); + create_gil(gil); + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + take_gil(ceval, tstate); + + struct _pending_calls *pending = &ceval->pending; + pending->lock = PyThread_allocate_lock(); + if (pending->lock == NULL) { + Py_FatalError("Can't initialize threads for pending calls"); + } +} + +void +_PyEval_FiniThreads(struct _ceval_runtime_state *ceval) +{ + struct _gil_runtime_state *gil = &ceval->gil; + if (!gil_created(gil)) { + return; + } + + destroy_gil(gil); + assert(!gil_created(gil)); + + struct _pending_calls *pending = &ceval->pending; + if (pending->lock != NULL) { + PyThread_free_lock(pending->lock); + pending->lock = NULL; + } +} + +static inline void +exit_thread_if_finalizing(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + /* _Py_Finalizing is protected by the GIL */ + if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { + drop_gil(&runtime->ceval, tstate); + PyThread_exit_thread(); + } +} + +void +_PyEval_Fini(void) +{ +#if OPCACHE_STATS + fprintf(stderr, "-- Opcode cache number of objects = %zd\n", + opcache_code_objects); + + fprintf(stderr, "-- Opcode cache total extra mem = %zd\n", + opcache_code_objects_extra_mem); + + fprintf(stderr, "\n"); + + fprintf(stderr, "-- Opcode cache LOAD_GLOBAL hits = %zd (%d%%)\n", + opcache_global_hits, + (int) (100.0 * opcache_global_hits / + (opcache_global_hits + opcache_global_misses))); + + fprintf(stderr, "-- Opcode cache LOAD_GLOBAL misses = %zd (%d%%)\n", + opcache_global_misses, + (int) (100.0 * opcache_global_misses / + (opcache_global_hits + opcache_global_misses))); + + fprintf(stderr, "-- Opcode cache LOAD_GLOBAL opts = %zd\n", + opcache_global_opts); + + fprintf(stderr, "\n"); +#endif +} + +void +PyEval_AcquireLock(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + if (tstate == NULL) { + Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); + } + take_gil(ceval, tstate); + exit_thread_if_finalizing(runtime, tstate); +} + +void +PyEval_ReleaseLock(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + /* This function must succeed when the current thread state is NULL. + We therefore avoid PyThreadState_Get() which dumps a fatal error + in debug mode. + */ + drop_gil(&runtime->ceval, tstate); +} + +void +PyEval_AcquireThread(PyThreadState *tstate) +{ + if (tstate == NULL) { + Py_FatalError("PyEval_AcquireThread: NULL new thread state"); + } + + _PyRuntimeState *runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + + /* Check someone has called PyEval_InitThreads() to create the lock */ + assert(gil_created(&ceval->gil)); + take_gil(ceval, tstate); + exit_thread_if_finalizing(runtime, tstate); + if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { + Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); + } +} + +void +PyEval_ReleaseThread(PyThreadState *tstate) +{ + if (tstate == NULL) { + Py_FatalError("PyEval_ReleaseThread: NULL thread state"); + } + + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); + if (new_tstate != tstate) { + Py_FatalError("PyEval_ReleaseThread: wrong thread state"); + } + drop_gil(&runtime->ceval, tstate); +} + +/* This function is called from PyOS_AfterFork_Child to destroy all threads + * which are not running in the child process, and clear internal locks + * which might be held by those threads. + */ + +void +_PyEval_ReInitThreads(_PyRuntimeState *runtime) +{ + struct _ceval_runtime_state *ceval = &runtime->ceval; + if (!gil_created(&ceval->gil)) { + return; + } + recreate_gil(&ceval->gil); + PyThreadState *current_tstate = _PyRuntimeState_GetThreadState(runtime); + take_gil(ceval, current_tstate); + + struct _pending_calls *pending = &ceval->pending; + pending->lock = PyThread_allocate_lock(); + if (pending->lock == NULL) { + Py_FatalError("Can't initialize threads for pending calls"); + } + + /* Destroy all threads except the current one */ + _PyThreadState_DeleteExcept(runtime, current_tstate); +} + +/* This function is used to signal that async exceptions are waiting to be + raised. */ + +void +_PyEval_SignalAsyncExc(struct _ceval_runtime_state *ceval) +{ + SIGNAL_ASYNC_EXC(ceval); +} + +PyThreadState * +PyEval_SaveThread(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); + if (tstate == NULL) { + Py_FatalError("PyEval_SaveThread: NULL tstate"); + } + assert(gil_created(&ceval->gil)); + drop_gil(ceval, tstate); + return tstate; +} + +void +PyEval_RestoreThread(PyThreadState *tstate) +{ + _PyRuntimeState *runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + + if (tstate == NULL) { + Py_FatalError("PyEval_RestoreThread: NULL tstate"); + } + assert(gil_created(&ceval->gil)); + + int err = errno; + take_gil(ceval, tstate); + exit_thread_if_finalizing(runtime, tstate); + errno = err; + + _PyThreadState_Swap(&runtime->gilstate, tstate); +} + + +/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX + signal handlers or Mac I/O completion routines) can schedule calls + to a function to be called synchronously. + The synchronous function is called with one void* argument. + It should return 0 for success or -1 for failure -- failure should + be accompanied by an exception. + + If registry succeeds, the registry function returns 0; if it fails + (e.g. due to too many pending calls) it returns -1 (without setting + an exception condition). + + Note that because registry may occur from within signal handlers, + or other asynchronous events, calling malloc() is unsafe! + + Any thread can schedule pending calls, but only the main thread + will execute them. + There is no facility to schedule calls to a particular thread, but + that should be easy to change, should that ever be required. In + that case, the static variables here should go into the python + threadstate. +*/ + +void +_PyEval_SignalReceived(struct _ceval_runtime_state *ceval) +{ + /* bpo-30703: Function called when the C signal handler of Python gets a + signal. We cannot queue a callback using Py_AddPendingCall() since + that function is not async-signal-safe. */ + SIGNAL_PENDING_SIGNALS(ceval); +} + +/* Push one item onto the queue while holding the lock. */ +static int +_push_pending_call(struct _pending_calls *pending, + int (*func)(void *), void *arg) +{ + int i = pending->last; + int j = (i + 1) % NPENDINGCALLS; + if (j == pending->first) { + return -1; /* Queue full */ + } + pending->calls[i].func = func; + pending->calls[i].arg = arg; + pending->last = j; + return 0; +} + +/* Pop one item off the queue while holding the lock. */ +static void +_pop_pending_call(struct _pending_calls *pending, + int (**func)(void *), void **arg) +{ + int i = pending->first; + if (i == pending->last) { + return; /* Queue empty */ + } + + *func = pending->calls[i].func; + *arg = pending->calls[i].arg; + pending->first = (i + 1) % NPENDINGCALLS; +} + +/* This implementation is thread-safe. It allows + scheduling to be made from any thread, and even from an executing + callback. + */ + +int +_PyEval_AddPendingCall(PyThreadState *tstate, + struct _ceval_runtime_state *ceval, + int (*func)(void *), void *arg) +{ + struct _pending_calls *pending = &ceval->pending; + + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + if (pending->finishing) { + PyThread_release_lock(pending->lock); + + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + _PyErr_SetString(tstate, PyExc_SystemError, + "Py_AddPendingCall: cannot add pending calls " + "(Python shutting down)"); + _PyErr_Print(tstate); + _PyErr_Restore(tstate, exc, val, tb); + return -1; + } + int result = _push_pending_call(pending, func, arg); + PyThread_release_lock(pending->lock); + + /* signal main loop */ + SIGNAL_PENDING_CALLS(ceval); + return result; +} + +int +Py_AddPendingCall(int (*func)(void *), void *arg) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + return _PyEval_AddPendingCall(tstate, &runtime->ceval, func, arg); +} + +static int +handle_signals(_PyRuntimeState *runtime) +{ + /* Only handle signals on main thread. PyEval_InitThreads must + * have been called already. + */ + if (PyThread_get_thread_ident() != runtime->main_thread) { + return 0; + } + /* + * Ensure that the thread isn't currently running some other + * interpreter. + */ + PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + if (interp != runtime->interpreters.main) { + return 0; + } + + struct _ceval_runtime_state *ceval = &runtime->ceval; + UNSIGNAL_PENDING_SIGNALS(ceval); + if (_PyErr_CheckSignals() < 0) { + SIGNAL_PENDING_SIGNALS(ceval); /* We're not done yet */ + return -1; + } + return 0; +} + +static int +make_pending_calls(_PyRuntimeState *runtime) +{ + static int busy = 0; + + /* only service pending calls on main thread */ + if (PyThread_get_thread_ident() != runtime->main_thread) { + return 0; + } + + /* don't perform recursive pending calls */ + if (busy) { + return 0; + } + busy = 1; + struct _ceval_runtime_state *ceval = &runtime->ceval; + /* unsignal before starting to call callbacks, so that any callback + added in-between re-signals */ + UNSIGNAL_PENDING_CALLS(ceval); + int res = 0; + + /* perform a bounded number of calls, in case of recursion */ + struct _pending_calls *pending = &ceval->pending; + for (int i=0; ilock, WAIT_LOCK); + _pop_pending_call(pending, &func, &arg); + PyThread_release_lock(pending->lock); + + /* having released the lock, perform the callback */ + if (func == NULL) { + break; + } + res = func(arg); + if (res) { + goto error; + } + } + + busy = 0; + return res; + +error: + busy = 0; + SIGNAL_PENDING_CALLS(ceval); + return res; +} + +void +_Py_FinishPendingCalls(_PyRuntimeState *runtime) +{ + assert(PyGILState_Check()); + + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + struct _pending_calls *pending = &runtime->ceval.pending; + + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + pending->finishing = 1; + PyThread_release_lock(pending->lock); + + if (!_Py_atomic_load_relaxed(&(pending->calls_to_do))) { + return; + } + + if (make_pending_calls(runtime) < 0) { + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + PyErr_BadInternalCall(); + _PyErr_ChainExceptions(exc, val, tb); + _PyErr_Print(tstate); + } +} + +/* Py_MakePendingCalls() is a simple wrapper for the sake + of backward-compatibility. */ +int +Py_MakePendingCalls(void) +{ + assert(PyGILState_Check()); + + /* Python signal handler doesn't really queue a callback: it only signals + that a signal was received, see _PyEval_SignalReceived(). */ + _PyRuntimeState *runtime = &_PyRuntime; + int res = handle_signals(runtime); + if (res != 0) { + return res; + } + + res = make_pending_calls(runtime); + if (res != 0) { + return res; + } + + return 0; +} + +/* The interpreter's recursion limit */ + +#ifndef Py_DEFAULT_RECURSION_LIMIT +#define Py_DEFAULT_RECURSION_LIMIT 1000 +#endif + +int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; + +void +_PyEval_Initialize(struct _ceval_runtime_state *state) +{ + state->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; + _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; + _gil_initialize(&state->gil); +} + +int +Py_GetRecursionLimit(void) +{ + return _PyRuntime.ceval.recursion_limit; +} + +void +Py_SetRecursionLimit(int new_limit) +{ + struct _ceval_runtime_state *ceval = &_PyRuntime.ceval; + ceval->recursion_limit = new_limit; + _Py_CheckRecursionLimit = ceval->recursion_limit; +} + +/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() + if the recursion_depth reaches _Py_CheckRecursionLimit. + If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit + to guarantee that _Py_CheckRecursiveCall() is regularly called. + Without USE_STACKCHECK, there is no need for this. */ +int +_Py_CheckRecursiveCall(const char *where) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + int recursion_limit = runtime->ceval.recursion_limit; + +#ifdef USE_STACKCHECK + tstate->stackcheck_counter = 0; + if (PyOS_CheckStack()) { + --tstate->recursion_depth; + _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); + return -1; + } + /* Needed for ABI backwards-compatibility (see bpo-31857) */ + _Py_CheckRecursionLimit = recursion_limit; +#endif + if (tstate->recursion_critical) + /* Somebody asked that we don't check for recursion. */ + return 0; + if (tstate->overflowed) { + if (tstate->recursion_depth > recursion_limit + 50) { + /* Overflowing while handling an overflow. Give up. */ + Py_FatalError("Cannot recover from stack overflow."); + } + return 0; + } + if (tstate->recursion_depth > recursion_limit) { + --tstate->recursion_depth; + tstate->overflowed = 1; + _PyErr_Format(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded%s", + where); + return -1; + } + return 0; +} + +static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); +static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); + +#define _Py_TracingPossible(ceval) ((ceval)->tracing_possible) + + +PyObject * +PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) +{ + return PyEval_EvalCodeEx(co, + globals, locals, + (PyObject **)NULL, 0, + (PyObject **)NULL, 0, + (PyObject **)NULL, 0, + NULL, NULL); +} + + +/* Interpreter main loop */ + +PyObject * +PyEval_EvalFrame(PyFrameObject *f) { + /* This is for backward compatibility with extension modules that + used this API; core interpreter code should call + PyEval_EvalFrameEx() */ + return PyEval_EvalFrameEx(f, 0); +} + +PyObject * +PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + return interp->eval_frame(f, throwflag); +} + +PyObject* _Py_HOT_FUNCTION +_PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) +{ +#ifdef DXPAIRS + int lastopcode = 0; +#endif + PyObject **stack_pointer; /* Next free slot in value stack */ + const _Py_CODEUNIT *next_instr; + int opcode; /* Current opcode */ + int oparg; /* Current opcode argument, if any */ + PyObject **fastlocals, **freevars; + PyObject *retval = NULL; /* Return value */ + _PyRuntimeState * const runtime = &_PyRuntime; + PyThreadState * const tstate = _PyRuntimeState_GetThreadState(runtime); + struct _ceval_runtime_state * const ceval = &runtime->ceval; + _Py_atomic_int * const eval_breaker = &ceval->eval_breaker; + PyCodeObject *co; + + /* when tracing we set things up so that + + not (instr_lb <= current_bytecode_offset < instr_ub) + + is true when the line being executed has changed. The + initial values are such as to make this false the first + time it is tested. */ + int instr_ub = -1, instr_lb = 0, instr_prev = -1; + + const _Py_CODEUNIT *first_instr; + PyObject *names; + PyObject *consts; + _PyOpcache *co_opcache; + +#ifdef LLTRACE + _Py_IDENTIFIER(__ltrace__); +#endif + +/* Computed GOTOs, or + the-optimization-commonly-but-improperly-known-as-"threaded code" + using gcc's labels-as-values extension + (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html). + + The traditional bytecode evaluation loop uses a "switch" statement, which + decent compilers will optimize as a single indirect branch instruction + combined with a lookup table of jump addresses. However, since the + indirect jump instruction is shared by all opcodes, the CPU will have a + hard time making the right prediction for where to jump next (actually, + it will be always wrong except in the uncommon case of a sequence of + several identical opcodes). + + "Threaded code" in contrast, uses an explicit jump table and an explicit + indirect jump instruction at the end of each opcode. Since the jump + instruction is at a different address for each opcode, the CPU will make a + separate prediction for each of these instructions, which is equivalent to + predicting the second opcode of each opcode pair. These predictions have + a much better chance to turn out valid, especially in small bytecode loops. + + A mispredicted branch on a modern CPU flushes the whole pipeline and + can cost several CPU cycles (depending on the pipeline depth), + and potentially many more instructions (depending on the pipeline width). + A correctly predicted branch, however, is nearly free. + + At the time of this writing, the "threaded code" version is up to 15-20% + faster than the normal "switch" version, depending on the compiler and the + CPU architecture. + + We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined, + because it would render the measurements invalid. + + + NOTE: care must be taken that the compiler doesn't try to "optimize" the + indirect jumps by sharing them between all opcodes. Such optimizations + can be disabled on gcc by using the -fno-gcse flag (or possibly + -fno-crossjumping). +*/ + +#ifdef DYNAMIC_EXECUTION_PROFILE +#undef USE_COMPUTED_GOTOS +#define USE_COMPUTED_GOTOS 0 +#endif + +#ifdef HAVE_COMPUTED_GOTOS + #ifndef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 1 + #endif +#else + #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS + #error "Computed gotos are not supported on this compiler." + #endif + #undef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 0 +#endif + +#if USE_COMPUTED_GOTOS +/* Import the static jump table */ +#include "opcode_targets.h" + +#define TARGET(op) \ + op: \ + TARGET_##op + +#ifdef LLTRACE +#define FAST_DISPATCH() \ + { \ + if (!lltrace && !_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \ + f->f_lasti = INSTR_OFFSET(); \ + NEXTOPARG(); \ + goto *opcode_targets[opcode]; \ + } \ + goto fast_next_opcode; \ + } +#else +#define FAST_DISPATCH() \ + { \ + if (!_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \ + f->f_lasti = INSTR_OFFSET(); \ + NEXTOPARG(); \ + goto *opcode_targets[opcode]; \ + } \ + goto fast_next_opcode; \ + } +#endif + +#define DISPATCH() \ + { \ + if (!_Py_atomic_load_relaxed(eval_breaker)) { \ + FAST_DISPATCH(); \ + } \ + continue; \ + } + +#else +#define TARGET(op) op +#define FAST_DISPATCH() goto fast_next_opcode +#define DISPATCH() continue +#endif + + +/* Tuple access macros */ + +#ifndef Py_DEBUG +#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i)) +#else +#define GETITEM(v, i) PyTuple_GetItem((v), (i)) +#endif + +/* Code access macros */ + +/* The integer overflow is checked by an assertion below. */ +#define INSTR_OFFSET() \ + (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr)) +#define NEXTOPARG() do { \ + _Py_CODEUNIT word = *next_instr; \ + opcode = _Py_OPCODE(word); \ + oparg = _Py_OPARG(word); \ + next_instr++; \ + } while (0) +#define JUMPTO(x) (next_instr = first_instr + (x) / sizeof(_Py_CODEUNIT)) +#define JUMPBY(x) (next_instr += (x) / sizeof(_Py_CODEUNIT)) + +/* OpCode prediction macros + Some opcodes tend to come in pairs thus making it possible to + predict the second code when the first is run. For example, + COMPARE_OP is often followed by POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE. + + Verifying the prediction costs a single high-speed test of a register + variable against a constant. If the pairing was good, then the + processor's own internal branch predication has a high likelihood of + success, resulting in a nearly zero-overhead transition to the + next opcode. A successful prediction saves a trip through the eval-loop + including its unpredictable switch-case branch. Combined with the + processor's internal branch prediction, a successful PREDICT has the + effect of making the two opcodes run as if they were a single new opcode + with the bodies combined. + + If collecting opcode statistics, your choices are to either keep the + predictions turned-on and interpret the results as if some opcodes + had been combined or turn-off predictions so that the opcode frequency + counter updates for both opcodes. + + Opcode prediction is disabled with threaded code, since the latter allows + the CPU to record separate branch prediction information for each + opcode. + +*/ + +#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS +#define PREDICT(op) if (0) goto PRED_##op +#else +#define PREDICT(op) \ + do{ \ + _Py_CODEUNIT word = *next_instr; \ + opcode = _Py_OPCODE(word); \ + if (opcode == op){ \ + oparg = _Py_OPARG(word); \ + next_instr++; \ + goto PRED_##op; \ + } \ + } while(0) +#endif +#define PREDICTED(op) PRED_##op: + + +/* Stack manipulation macros */ + +/* The stack can grow at most MAXINT deep, as co_nlocals and + co_stacksize are ints. */ +#define STACK_LEVEL() ((int)(stack_pointer - f->f_valuestack)) +#define EMPTY() (STACK_LEVEL() == 0) +#define TOP() (stack_pointer[-1]) +#define SECOND() (stack_pointer[-2]) +#define THIRD() (stack_pointer[-3]) +#define FOURTH() (stack_pointer[-4]) +#define PEEK(n) (stack_pointer[-(n)]) +#define SET_TOP(v) (stack_pointer[-1] = (v)) +#define SET_SECOND(v) (stack_pointer[-2] = (v)) +#define SET_THIRD(v) (stack_pointer[-3] = (v)) +#define SET_FOURTH(v) (stack_pointer[-4] = (v)) +#define SET_VALUE(n, v) (stack_pointer[-(n)] = (v)) +#define BASIC_STACKADJ(n) (stack_pointer += n) +#define BASIC_PUSH(v) (*stack_pointer++ = (v)) +#define BASIC_POP() (*--stack_pointer) + +#ifdef LLTRACE +#define PUSH(v) { (void)(BASIC_PUSH(v), \ + lltrace && prtrace(tstate, TOP(), "push")); \ + assert(STACK_LEVEL() <= co->co_stacksize); } +#define POP() ((void)(lltrace && prtrace(tstate, TOP(), "pop")), \ + BASIC_POP()) +#define STACK_GROW(n) do { \ + assert(n >= 0); \ + (void)(BASIC_STACKADJ(n), \ + lltrace && prtrace(tstate, TOP(), "stackadj")); \ + assert(STACK_LEVEL() <= co->co_stacksize); \ + } while (0) +#define STACK_SHRINK(n) do { \ + assert(n >= 0); \ + (void)(lltrace && prtrace(tstate, TOP(), "stackadj")); \ + (void)(BASIC_STACKADJ(-n)); \ + assert(STACK_LEVEL() <= co->co_stacksize); \ + } while (0) +#define EXT_POP(STACK_POINTER) ((void)(lltrace && \ + prtrace(tstate, (STACK_POINTER)[-1], "ext_pop")), \ + *--(STACK_POINTER)) +#else +#define PUSH(v) BASIC_PUSH(v) +#define POP() BASIC_POP() +#define STACK_GROW(n) BASIC_STACKADJ(n) +#define STACK_SHRINK(n) BASIC_STACKADJ(-n) +#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER)) +#endif + +/* Local variable macros */ + +#define GETLOCAL(i) (fastlocals[i]) + +/* The SETLOCAL() macro must not DECREF the local variable in-place and + then store the new value; it must copy the old value to a temporary + value, then store the new value, and then DECREF the temporary value. + This is because it is possible that during the DECREF the frame is + accessed by other code (e.g. a __del__ method or gc.collect()) and the + variable would be pointing to already-freed memory. */ +#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \ + GETLOCAL(i) = value; \ + Py_XDECREF(tmp); } while (0) + + +#define UNWIND_BLOCK(b) \ + while (STACK_LEVEL() > (b)->b_level) { \ + PyObject *v = POP(); \ + Py_XDECREF(v); \ + } + +#define UNWIND_EXCEPT_HANDLER(b) \ + do { \ + PyObject *type, *value, *traceback; \ + _PyErr_StackItem *exc_info; \ + assert(STACK_LEVEL() >= (b)->b_level + 3); \ + while (STACK_LEVEL() > (b)->b_level + 3) { \ + value = POP(); \ + Py_XDECREF(value); \ + } \ + exc_info = tstate->exc_info; \ + type = exc_info->exc_type; \ + value = exc_info->exc_value; \ + traceback = exc_info->exc_traceback; \ + exc_info->exc_type = POP(); \ + exc_info->exc_value = POP(); \ + exc_info->exc_traceback = POP(); \ + Py_XDECREF(type); \ + Py_XDECREF(value); \ + Py_XDECREF(traceback); \ + } while(0) + + /* macros for opcode cache */ +#define OPCACHE_CHECK() \ + do { \ + co_opcache = NULL; \ + if (co->co_opcache != NULL) { \ + unsigned char co_opt_offset = \ + co->co_opcache_map[next_instr - first_instr]; \ + if (co_opt_offset > 0) { \ + assert(co_opt_offset <= co->co_opcache_size); \ + co_opcache = &co->co_opcache[co_opt_offset - 1]; \ + assert(co_opcache != NULL); \ + } \ + } \ + } while (0) + +#if OPCACHE_STATS + +#define OPCACHE_STAT_GLOBAL_HIT() \ + do { \ + if (co->co_opcache != NULL) opcache_global_hits++; \ + } while (0) + +#define OPCACHE_STAT_GLOBAL_MISS() \ + do { \ + if (co->co_opcache != NULL) opcache_global_misses++; \ + } while (0) + +#define OPCACHE_STAT_GLOBAL_OPT() \ + do { \ + if (co->co_opcache != NULL) opcache_global_opts++; \ + } while (0) + +#else /* OPCACHE_STATS */ + +#define OPCACHE_STAT_GLOBAL_HIT() +#define OPCACHE_STAT_GLOBAL_MISS() +#define OPCACHE_STAT_GLOBAL_OPT() + +#endif + +/* Start of code */ + + /* push frame */ + if (Py_EnterRecursiveCall("")) + return NULL; + + tstate->frame = f; + + if (tstate->use_tracing) { + if (tstate->c_tracefunc != NULL) { + /* tstate->c_tracefunc, if defined, is a + function that will be called on *every* entry + to a code block. Its return value, if not + None, is a function that will be called at + the start of each executed line of code. + (Actually, the function must return itself + in order to continue tracing.) The trace + functions are called with three arguments: + a pointer to the current frame, a string + indicating why the function is called, and + an argument which depends on the situation. + The global trace function is also called + whenever an exception is detected. */ + if (call_trace_protected(tstate->c_tracefunc, + tstate->c_traceobj, + tstate, f, PyTrace_CALL, Py_None)) { + /* Trace function raised an error */ + goto exit_eval_frame; + } + } + if (tstate->c_profilefunc != NULL) { + /* Similar for c_profilefunc, except it needn't + return itself and isn't called for "line" events */ + if (call_trace_protected(tstate->c_profilefunc, + tstate->c_profileobj, + tstate, f, PyTrace_CALL, Py_None)) { + /* Profile function raised an error */ + goto exit_eval_frame; + } + } + } + + if (PyDTrace_FUNCTION_ENTRY_ENABLED()) + dtrace_function_entry(f); + + co = f->f_code; + names = co->co_names; + consts = co->co_consts; + fastlocals = f->f_localsplus; + freevars = f->f_localsplus + co->co_nlocals; + assert(PyBytes_Check(co->co_code)); + assert(PyBytes_GET_SIZE(co->co_code) <= INT_MAX); + assert(PyBytes_GET_SIZE(co->co_code) % sizeof(_Py_CODEUNIT) == 0); + assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(co->co_code), sizeof(_Py_CODEUNIT))); + first_instr = (_Py_CODEUNIT *) PyBytes_AS_STRING(co->co_code); + /* + f->f_lasti refers to the index of the last instruction, + unless it's -1 in which case next_instr should be first_instr. + + YIELD_FROM sets f_lasti to itself, in order to repeatedly yield + multiple values. + + When the PREDICT() macros are enabled, some opcode pairs follow in + direct succession without updating f->f_lasti. A successful + prediction effectively links the two codes together as if they + were a single new opcode; accordingly,f->f_lasti will point to + the first code in the pair (for instance, GET_ITER followed by + FOR_ITER is effectively a single opcode and f->f_lasti will point + to the beginning of the combined pair.) + */ + assert(f->f_lasti >= -1); + next_instr = first_instr; + if (f->f_lasti >= 0) { + assert(f->f_lasti % sizeof(_Py_CODEUNIT) == 0); + next_instr += f->f_lasti / sizeof(_Py_CODEUNIT) + 1; + } + stack_pointer = f->f_stacktop; + assert(stack_pointer != NULL); + f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */ + f->f_executing = 1; + + if (co->co_opcache_flag < OPCACHE_MIN_RUNS) { + co->co_opcache_flag++; + if (co->co_opcache_flag == OPCACHE_MIN_RUNS) { + if (_PyCode_InitOpcache(co) < 0) { + goto exit_eval_frame; + } +#if OPCACHE_STATS + opcache_code_objects_extra_mem += + PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT) + + sizeof(_PyOpcache) * co->co_opcache_size; + opcache_code_objects++; +#endif + } + } + +#ifdef LLTRACE + lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL; +#endif + + if (throwflag) /* support for generator.throw() */ + goto error; + +#ifdef Py_DEBUG + /* PyEval_EvalFrameEx() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!_PyErr_Occurred(tstate)); +#endif + +main_loop: + for (;;) { + assert(stack_pointer >= f->f_valuestack); /* else underflow */ + assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */ + assert(!_PyErr_Occurred(tstate)); + + /* Do periodic things. Doing this every time through + the loop would add too much overhead, so we do it + only every Nth instruction. We also do it if + ``pendingcalls_to_do'' is set, i.e. when an asynchronous + event needs attention (e.g. a signal handler or + async I/O handler); see Py_AddPendingCall() and + Py_MakePendingCalls() above. */ + + if (_Py_atomic_load_relaxed(eval_breaker)) { + opcode = _Py_OPCODE(*next_instr); + if (opcode == SETUP_FINALLY || + opcode == SETUP_WITH || + opcode == BEFORE_ASYNC_WITH || + opcode == YIELD_FROM) { + /* Few cases where we skip running signal handlers and other + pending calls: + - If we're about to enter the 'with:'. It will prevent + emitting a resource warning in the common idiom + 'with open(path) as file:'. + - If we're about to enter the 'async with:'. + - If we're about to enter the 'try:' of a try/finally (not + *very* useful, but might help in some cases and it's + traditional) + - If we're resuming a chain of nested 'yield from' or + 'await' calls, then each frame is parked with YIELD_FROM + as its next opcode. If the user hit control-C we want to + wait until we've reached the innermost frame before + running the signal handler and raising KeyboardInterrupt + (see bpo-30039). + */ + goto fast_next_opcode; + } + + if (_Py_atomic_load_relaxed(&ceval->signals_pending)) { + if (handle_signals(runtime) != 0) { + goto error; + } + } + if (_Py_atomic_load_relaxed(&ceval->pending.calls_to_do)) { + if (make_pending_calls(runtime) != 0) { + goto error; + } + } + + if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { + /* Give another thread a chance */ + if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { + Py_FatalError("ceval: tstate mix-up"); + } + drop_gil(ceval, tstate); + + /* Other threads may run now */ + + take_gil(ceval, tstate); + + /* Check if we should make a quick exit. */ + exit_thread_if_finalizing(runtime, tstate); + + if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { + Py_FatalError("ceval: orphan tstate"); + } + } + /* Check for asynchronous exceptions. */ + if (tstate->async_exc != NULL) { + PyObject *exc = tstate->async_exc; + tstate->async_exc = NULL; + UNSIGNAL_ASYNC_EXC(ceval); + _PyErr_SetNone(tstate, exc); + Py_DECREF(exc); + goto error; + } + } + + fast_next_opcode: + f->f_lasti = INSTR_OFFSET(); + + if (PyDTrace_LINE_ENABLED()) + maybe_dtrace_line(f, &instr_lb, &instr_ub, &instr_prev); + + /* line-by-line tracing support */ + + if (_Py_TracingPossible(ceval) && + tstate->c_tracefunc != NULL && !tstate->tracing) { + int err; + /* see maybe_call_line_trace + for expository comments */ + f->f_stacktop = stack_pointer; + + err = maybe_call_line_trace(tstate->c_tracefunc, + tstate->c_traceobj, + tstate, f, + &instr_lb, &instr_ub, &instr_prev); + /* Reload possibly changed frame fields */ + JUMPTO(f->f_lasti); + if (f->f_stacktop != NULL) { + stack_pointer = f->f_stacktop; + f->f_stacktop = NULL; + } + if (err) + /* trace function raised an exception */ + goto error; + } + + /* Extract opcode and argument */ + + NEXTOPARG(); + dispatch_opcode: +#ifdef DYNAMIC_EXECUTION_PROFILE +#ifdef DXPAIRS + dxpairs[lastopcode][opcode]++; + lastopcode = opcode; +#endif + dxp[opcode]++; +#endif + +#ifdef LLTRACE + /* Instruction tracing */ + + if (lltrace) { + if (HAS_ARG(opcode)) { + printf("%d: %d, %d\n", + f->f_lasti, opcode, oparg); + } + else { + printf("%d: %d\n", + f->f_lasti, opcode); + } + } +#endif + + switch (opcode) { + + /* BEWARE! + It is essential that any operation that fails must goto error + and that all operation that succeed call [FAST_]DISPATCH() ! */ + + case TARGET(NOP): { + FAST_DISPATCH(); + } + + case TARGET(LOAD_FAST): { + PyObject *value = GETLOCAL(oparg); + if (value == NULL) { + format_exc_check_arg(tstate, PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, + PyTuple_GetItem(co->co_varnames, oparg)); + goto error; + } + Py_INCREF(value); + PUSH(value); + FAST_DISPATCH(); + } + + case TARGET(LOAD_CONST): { + PREDICTED(LOAD_CONST); + PyObject *value = GETITEM(consts, oparg); + Py_INCREF(value); + PUSH(value); + FAST_DISPATCH(); + } + + case TARGET(STORE_FAST): { + PREDICTED(STORE_FAST); + PyObject *value = POP(); + SETLOCAL(oparg, value); + FAST_DISPATCH(); + } + + case TARGET(POP_TOP): { + PyObject *value = POP(); + Py_DECREF(value); + FAST_DISPATCH(); + } + + case TARGET(ROT_TWO): { + PyObject *top = TOP(); + PyObject *second = SECOND(); + SET_TOP(second); + SET_SECOND(top); + FAST_DISPATCH(); + } + + case TARGET(ROT_THREE): { + PyObject *top = TOP(); + PyObject *second = SECOND(); + PyObject *third = THIRD(); + SET_TOP(second); + SET_SECOND(third); + SET_THIRD(top); + FAST_DISPATCH(); + } + + case TARGET(ROT_FOUR): { + PyObject *top = TOP(); + PyObject *second = SECOND(); + PyObject *third = THIRD(); + PyObject *fourth = FOURTH(); + SET_TOP(second); + SET_SECOND(third); + SET_THIRD(fourth); + SET_FOURTH(top); + FAST_DISPATCH(); + } + + case TARGET(DUP_TOP): { + PyObject *top = TOP(); + Py_INCREF(top); + PUSH(top); + FAST_DISPATCH(); + } + + case TARGET(DUP_TOP_TWO): { + PyObject *top = TOP(); + PyObject *second = SECOND(); + Py_INCREF(top); + Py_INCREF(second); + STACK_GROW(2); + SET_TOP(top); + SET_SECOND(second); + FAST_DISPATCH(); + } + + case TARGET(UNARY_POSITIVE): { + PyObject *value = TOP(); + PyObject *res = PyNumber_Positive(value); + Py_DECREF(value); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(UNARY_NEGATIVE): { + PyObject *value = TOP(); + PyObject *res = PyNumber_Negative(value); + Py_DECREF(value); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(UNARY_NOT): { + PyObject *value = TOP(); + int err = PyObject_IsTrue(value); + Py_DECREF(value); + if (err == 0) { + Py_INCREF(Py_True); + SET_TOP(Py_True); + DISPATCH(); + } + else if (err > 0) { + Py_INCREF(Py_False); + SET_TOP(Py_False); + DISPATCH(); + } + STACK_SHRINK(1); + goto error; + } + + case TARGET(UNARY_INVERT): { + PyObject *value = TOP(); + PyObject *res = PyNumber_Invert(value); + Py_DECREF(value); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_POWER): { + PyObject *exp = POP(); + PyObject *base = TOP(); + PyObject *res = PyNumber_Power(base, exp, Py_None); + Py_DECREF(base); + Py_DECREF(exp); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_MULTIPLY): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_Multiply(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_MATRIX_MULTIPLY): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_MatrixMultiply(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_TRUE_DIVIDE): { + PyObject *divisor = POP(); + PyObject *dividend = TOP(); + PyObject *quotient = PyNumber_TrueDivide(dividend, divisor); + Py_DECREF(dividend); + Py_DECREF(divisor); + SET_TOP(quotient); + if (quotient == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_FLOOR_DIVIDE): { + PyObject *divisor = POP(); + PyObject *dividend = TOP(); + PyObject *quotient = PyNumber_FloorDivide(dividend, divisor); + Py_DECREF(dividend); + Py_DECREF(divisor); + SET_TOP(quotient); + if (quotient == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_MODULO): { + PyObject *divisor = POP(); + PyObject *dividend = TOP(); + PyObject *res; + if (PyUnicode_CheckExact(dividend) && ( + !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) { + // fast path; string formatting, but not if the RHS is a str subclass + // (see issue28598) + res = PyUnicode_Format(dividend, divisor); + } else { + res = PyNumber_Remainder(dividend, divisor); + } + Py_DECREF(divisor); + Py_DECREF(dividend); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_ADD): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *sum; + /* NOTE(haypo): Please don't try to micro-optimize int+int on + CPython using bytecode, it is simply worthless. + See http://bugs.python.org/issue21955 and + http://bugs.python.org/issue10044 for the discussion. In short, + no patch shown any impact on a realistic benchmark, only a minor + speedup on microbenchmarks. */ + if (PyUnicode_CheckExact(left) && + PyUnicode_CheckExact(right)) { + sum = unicode_concatenate(tstate, left, right, f, next_instr); + /* unicode_concatenate consumed the ref to left */ + } + else { + sum = PyNumber_Add(left, right); + Py_DECREF(left); + } + Py_DECREF(right); + SET_TOP(sum); + if (sum == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_SUBTRACT): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *diff = PyNumber_Subtract(left, right); + Py_DECREF(right); + Py_DECREF(left); + SET_TOP(diff); + if (diff == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_SUBSCR): { + PyObject *sub = POP(); + PyObject *container = TOP(); + PyObject *res = PyObject_GetItem(container, sub); + Py_DECREF(container); + Py_DECREF(sub); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_LSHIFT): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_Lshift(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_RSHIFT): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_Rshift(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_AND): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_And(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_XOR): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_Xor(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(BINARY_OR): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_Or(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(LIST_APPEND): { + PyObject *v = POP(); + PyObject *list = PEEK(oparg); + int err; + err = PyList_Append(list, v); + Py_DECREF(v); + if (err != 0) + goto error; + PREDICT(JUMP_ABSOLUTE); + DISPATCH(); + } + + case TARGET(SET_ADD): { + PyObject *v = POP(); + PyObject *set = PEEK(oparg); + int err; + err = PySet_Add(set, v); + Py_DECREF(v); + if (err != 0) + goto error; + PREDICT(JUMP_ABSOLUTE); + DISPATCH(); + } + + case TARGET(INPLACE_POWER): { + PyObject *exp = POP(); + PyObject *base = TOP(); + PyObject *res = PyNumber_InPlacePower(base, exp, Py_None); + Py_DECREF(base); + Py_DECREF(exp); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_MULTIPLY): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceMultiply(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_MATRIX_MULTIPLY): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_TRUE_DIVIDE): { + PyObject *divisor = POP(); + PyObject *dividend = TOP(); + PyObject *quotient = PyNumber_InPlaceTrueDivide(dividend, divisor); + Py_DECREF(dividend); + Py_DECREF(divisor); + SET_TOP(quotient); + if (quotient == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_FLOOR_DIVIDE): { + PyObject *divisor = POP(); + PyObject *dividend = TOP(); + PyObject *quotient = PyNumber_InPlaceFloorDivide(dividend, divisor); + Py_DECREF(dividend); + Py_DECREF(divisor); + SET_TOP(quotient); + if (quotient == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_MODULO): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *mod = PyNumber_InPlaceRemainder(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(mod); + if (mod == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_ADD): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *sum; + if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { + sum = unicode_concatenate(tstate, left, right, f, next_instr); + /* unicode_concatenate consumed the ref to left */ + } + else { + sum = PyNumber_InPlaceAdd(left, right); + Py_DECREF(left); + } + Py_DECREF(right); + SET_TOP(sum); + if (sum == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_SUBTRACT): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *diff = PyNumber_InPlaceSubtract(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(diff); + if (diff == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_LSHIFT): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceLshift(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_RSHIFT): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceRshift(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_AND): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceAnd(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_XOR): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceXor(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(INPLACE_OR): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceOr(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(STORE_SUBSCR): { + PyObject *sub = TOP(); + PyObject *container = SECOND(); + PyObject *v = THIRD(); + int err; + STACK_SHRINK(3); + /* container[sub] = v */ + err = PyObject_SetItem(container, sub, v); + Py_DECREF(v); + Py_DECREF(container); + Py_DECREF(sub); + if (err != 0) + goto error; + DISPATCH(); + } + + case TARGET(DELETE_SUBSCR): { + PyObject *sub = TOP(); + PyObject *container = SECOND(); + int err; + STACK_SHRINK(2); + /* del container[sub] */ + err = PyObject_DelItem(container, sub); + Py_DECREF(container); + Py_DECREF(sub); + if (err != 0) + goto error; + DISPATCH(); + } + + case TARGET(PRINT_EXPR): { + _Py_IDENTIFIER(displayhook); + PyObject *value = POP(); + PyObject *hook = _PySys_GetObjectId(&PyId_displayhook); + PyObject *res; + if (hook == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "lost sys.displayhook"); + Py_DECREF(value); + goto error; + } + res = PyObject_CallFunctionObjArgs(hook, value, NULL); + Py_DECREF(value); + if (res == NULL) + goto error; + Py_DECREF(res); + DISPATCH(); + } + + case TARGET(RAISE_VARARGS): { + PyObject *cause = NULL, *exc = NULL; + switch (oparg) { + case 2: + cause = POP(); /* cause */ + /* fall through */ + case 1: + exc = POP(); /* exc */ + /* fall through */ + case 0: + if (do_raise(tstate, exc, cause)) { + goto exception_unwind; + } + break; + default: + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); + break; + } + goto error; + } + + case TARGET(RETURN_VALUE): { + retval = POP(); + assert(f->f_iblock == 0); + goto exit_returning; + } + + case TARGET(GET_AITER): { + unaryfunc getter = NULL; + PyObject *iter = NULL; + PyObject *obj = TOP(); + PyTypeObject *type = Py_TYPE(obj); + + if (type->tp_as_async != NULL) { + getter = type->tp_as_async->am_aiter; + } + + if (getter != NULL) { + iter = (*getter)(obj); + Py_DECREF(obj); + if (iter == NULL) { + SET_TOP(NULL); + goto error; + } + } + else { + SET_TOP(NULL); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); + Py_DECREF(obj); + goto error; + } + + if (Py_TYPE(iter)->tp_as_async == NULL || + Py_TYPE(iter)->tp_as_async->am_anext == NULL) { + + SET_TOP(NULL); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); + Py_DECREF(iter); + goto error; + } + + SET_TOP(iter); + DISPATCH(); + } + + case TARGET(GET_ANEXT): { + unaryfunc getter = NULL; + PyObject *next_iter = NULL; + PyObject *awaitable = NULL; + PyObject *aiter = TOP(); + PyTypeObject *type = Py_TYPE(aiter); + + if (PyAsyncGen_CheckExact(aiter)) { + awaitable = type->tp_as_async->am_anext(aiter); + if (awaitable == NULL) { + goto error; + } + } else { + if (type->tp_as_async != NULL){ + getter = type->tp_as_async->am_anext; + } + + if (getter != NULL) { + next_iter = (*getter)(aiter); + if (next_iter == NULL) { + goto error; + } + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); + goto error; + } + + awaitable = _PyCoro_GetAwaitableIter(next_iter); + if (awaitable == NULL) { + _PyErr_FormatFromCause( + PyExc_TypeError, + "'async for' received an invalid object " + "from __anext__: %.100s", + Py_TYPE(next_iter)->tp_name); + + Py_DECREF(next_iter); + goto error; + } else { + Py_DECREF(next_iter); + } + } + + PUSH(awaitable); + PREDICT(LOAD_CONST); + DISPATCH(); + } + + case TARGET(GET_AWAITABLE): { + PREDICTED(GET_AWAITABLE); + PyObject *iterable = TOP(); + PyObject *iter = _PyCoro_GetAwaitableIter(iterable); + + if (iter == NULL) { + format_awaitable_error(tstate, Py_TYPE(iterable), + _Py_OPCODE(next_instr[-2])); + } + + Py_DECREF(iterable); + + if (iter != NULL && PyCoro_CheckExact(iter)) { + PyObject *yf = _PyGen_yf((PyGenObject*)iter); + if (yf != NULL) { + /* `iter` is a coroutine object that is being + awaited, `yf` is a pointer to the current awaitable + being awaited on. */ + Py_DECREF(yf); + Py_CLEAR(iter); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); + /* The code below jumps to `error` if `iter` is NULL. */ + } + } + + SET_TOP(iter); /* Even if it's NULL */ + + if (iter == NULL) { + goto error; + } + + PREDICT(LOAD_CONST); + DISPATCH(); + } + + case TARGET(YIELD_FROM): { + PyObject *v = POP(); + PyObject *receiver = TOP(); + int err; + if (PyGen_CheckExact(receiver) || PyCoro_CheckExact(receiver)) { + retval = _PyGen_Send((PyGenObject *)receiver, v); + } else { + _Py_IDENTIFIER(send); + if (v == Py_None) + retval = Py_TYPE(receiver)->tp_iternext(receiver); + else + retval = _PyObject_CallMethodIdObjArgs(receiver, &PyId_send, v, NULL); + } + Py_DECREF(v); + if (retval == NULL) { + PyObject *val; + if (tstate->c_tracefunc != NULL + && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); + err = _PyGen_FetchStopIterationValue(&val); + if (err < 0) + goto error; + Py_DECREF(receiver); + SET_TOP(val); + DISPATCH(); + } + /* receiver remains on stack, retval is value to be yielded */ + f->f_stacktop = stack_pointer; + /* and repeat... */ + assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT)); + f->f_lasti -= sizeof(_Py_CODEUNIT); + goto exit_yielding; + } + + case TARGET(YIELD_VALUE): { + retval = POP(); + + if (co->co_flags & CO_ASYNC_GENERATOR) { + PyObject *w = _PyAsyncGenValueWrapperNew(retval); + Py_DECREF(retval); + if (w == NULL) { + retval = NULL; + goto error; + } + retval = w; + } + + f->f_stacktop = stack_pointer; + goto exit_yielding; + } + + case TARGET(POP_EXCEPT): { + PyObject *type, *value, *traceback; + _PyErr_StackItem *exc_info; + PyTryBlock *b = PyFrame_BlockPop(f); + if (b->b_type != EXCEPT_HANDLER) { + _PyErr_SetString(tstate, PyExc_SystemError, + "popped block is not an except handler"); + goto error; + } + assert(STACK_LEVEL() >= (b)->b_level + 3 && + STACK_LEVEL() <= (b)->b_level + 4); + exc_info = tstate->exc_info; + type = exc_info->exc_type; + value = exc_info->exc_value; + traceback = exc_info->exc_traceback; + exc_info->exc_type = POP(); + exc_info->exc_value = POP(); + exc_info->exc_traceback = POP(); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + DISPATCH(); + } + + case TARGET(POP_BLOCK): { + PREDICTED(POP_BLOCK); + PyFrame_BlockPop(f); + DISPATCH(); + } + + case TARGET(POP_FINALLY): { + /* If oparg is 0 at the top of the stack are 1 or 6 values: + Either: + - TOP = NULL or an integer + or: + - (TOP, SECOND, THIRD) = exc_info() + - (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER + + If oparg is 1 the value for 'return' was additionally pushed + at the top of the stack. + */ + PyObject *res = NULL; + if (oparg) { + res = POP(); + } + PyObject *exc = POP(); + if (exc == NULL || PyLong_CheckExact(exc)) { + Py_XDECREF(exc); + } + else { + Py_DECREF(exc); + Py_DECREF(POP()); + Py_DECREF(POP()); + + PyObject *type, *value, *traceback; + _PyErr_StackItem *exc_info; + PyTryBlock *b = PyFrame_BlockPop(f); + if (b->b_type != EXCEPT_HANDLER) { + _PyErr_SetString(tstate, PyExc_SystemError, + "popped block is not an except handler"); + Py_XDECREF(res); + goto error; + } + assert(STACK_LEVEL() == (b)->b_level + 3); + exc_info = tstate->exc_info; + type = exc_info->exc_type; + value = exc_info->exc_value; + traceback = exc_info->exc_traceback; + exc_info->exc_type = POP(); + exc_info->exc_value = POP(); + exc_info->exc_traceback = POP(); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + } + if (oparg) { + PUSH(res); + } + DISPATCH(); + } + + case TARGET(CALL_FINALLY): { + PyObject *ret = PyLong_FromLong(INSTR_OFFSET()); + if (ret == NULL) { + goto error; + } + PUSH(ret); + JUMPBY(oparg); + FAST_DISPATCH(); + } + + case TARGET(BEGIN_FINALLY): { + /* Push NULL onto the stack for using it in END_FINALLY, + POP_FINALLY, WITH_CLEANUP_START and WITH_CLEANUP_FINISH. + */ + PUSH(NULL); + FAST_DISPATCH(); + } + + case TARGET(END_FINALLY): { + PREDICTED(END_FINALLY); + /* At the top of the stack are 1 or 6 values: + Either: + - TOP = NULL or an integer + or: + - (TOP, SECOND, THIRD) = exc_info() + - (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER + */ + PyObject *exc = POP(); + if (exc == NULL) { + FAST_DISPATCH(); + } + else if (PyLong_CheckExact(exc)) { + int ret = _PyLong_AsInt(exc); + Py_DECREF(exc); + if (ret == -1 && _PyErr_Occurred(tstate)) { + goto error; + } + JUMPTO(ret); + FAST_DISPATCH(); + } + else { + assert(PyExceptionClass_Check(exc)); + PyObject *val = POP(); + PyObject *tb = POP(); + _PyErr_Restore(tstate, exc, val, tb); + goto exception_unwind; + } + } + + case TARGET(END_ASYNC_FOR): { + PyObject *exc = POP(); + assert(PyExceptionClass_Check(exc)); + if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { + PyTryBlock *b = PyFrame_BlockPop(f); + assert(b->b_type == EXCEPT_HANDLER); + Py_DECREF(exc); + UNWIND_EXCEPT_HANDLER(b); + Py_DECREF(POP()); + JUMPBY(oparg); + FAST_DISPATCH(); + } + else { + PyObject *val = POP(); + PyObject *tb = POP(); + _PyErr_Restore(tstate, exc, val, tb); + goto exception_unwind; + } + } + + case TARGET(LOAD_BUILD_CLASS): { + _Py_IDENTIFIER(__build_class__); + + PyObject *bc; + if (PyDict_CheckExact(f->f_builtins)) { + bc = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___build_class__); + if (bc == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + } + goto error; + } + Py_INCREF(bc); + } + else { + PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__); + if (build_class_str == NULL) + goto error; + bc = PyObject_GetItem(f->f_builtins, build_class_str); + if (bc == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + goto error; + } + } + PUSH(bc); + DISPATCH(); + } + + case TARGET(STORE_NAME): { + PyObject *name = GETITEM(names, oparg); + PyObject *v = POP(); + PyObject *ns = f->f_locals; + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); + Py_DECREF(v); + goto error; + } + if (PyDict_CheckExact(ns)) + err = PyDict_SetItem(ns, name, v); + else + err = PyObject_SetItem(ns, name, v); + Py_DECREF(v); + if (err != 0) + goto error; + DISPATCH(); + } + + case TARGET(DELETE_NAME): { + PyObject *name = GETITEM(names, oparg); + PyObject *ns = f->f_locals; + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); + goto error; + } + err = PyObject_DelItem(ns, name); + if (err != 0) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); + goto error; + } + DISPATCH(); + } + + case TARGET(UNPACK_SEQUENCE): { + PREDICTED(UNPACK_SEQUENCE); + PyObject *seq = POP(), *item, **items; + if (PyTuple_CheckExact(seq) && + PyTuple_GET_SIZE(seq) == oparg) { + items = ((PyTupleObject *)seq)->ob_item; + while (oparg--) { + item = items[oparg]; + Py_INCREF(item); + PUSH(item); + } + } else if (PyList_CheckExact(seq) && + PyList_GET_SIZE(seq) == oparg) { + items = ((PyListObject *)seq)->ob_item; + while (oparg--) { + item = items[oparg]; + Py_INCREF(item); + PUSH(item); + } + } else if (unpack_iterable(tstate, seq, oparg, -1, + stack_pointer + oparg)) { + STACK_GROW(oparg); + } else { + /* unpack_iterable() raised an exception */ + Py_DECREF(seq); + goto error; + } + Py_DECREF(seq); + DISPATCH(); + } + + case TARGET(UNPACK_EX): { + int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); + PyObject *seq = POP(); + + if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, + stack_pointer + totalargs)) { + stack_pointer += totalargs; + } else { + Py_DECREF(seq); + goto error; + } + Py_DECREF(seq); + DISPATCH(); + } + + case TARGET(STORE_ATTR): { + PyObject *name = GETITEM(names, oparg); + PyObject *owner = TOP(); + PyObject *v = SECOND(); + int err; + STACK_SHRINK(2); + err = PyObject_SetAttr(owner, name, v); + Py_DECREF(v); + Py_DECREF(owner); + if (err != 0) + goto error; + DISPATCH(); + } + + case TARGET(DELETE_ATTR): { + PyObject *name = GETITEM(names, oparg); + PyObject *owner = POP(); + int err; + err = PyObject_SetAttr(owner, name, (PyObject *)NULL); + Py_DECREF(owner); + if (err != 0) + goto error; + DISPATCH(); + } + + case TARGET(STORE_GLOBAL): { + PyObject *name = GETITEM(names, oparg); + PyObject *v = POP(); + int err; + err = PyDict_SetItem(f->f_globals, name, v); + Py_DECREF(v); + if (err != 0) + goto error; + DISPATCH(); + } + + case TARGET(DELETE_GLOBAL): { + PyObject *name = GETITEM(names, oparg); + int err; + err = PyDict_DelItem(f->f_globals, name); + if (err != 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + DISPATCH(); + } + + case TARGET(LOAD_NAME): { + PyObject *name = GETITEM(names, oparg); + PyObject *locals = f->f_locals; + PyObject *v; + if (locals == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when loading %R", name); + goto error; + } + if (PyDict_CheckExact(locals)) { + v = PyDict_GetItemWithError(locals, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(locals, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + goto error; + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(f->f_globals, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(f->f_builtins)) { + v = PyDict_GetItemWithError(f->f_builtins, name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(f->f_builtins, name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + PUSH(v); + DISPATCH(); + } + + case TARGET(LOAD_GLOBAL): { + PyObject *name; + PyObject *v; + if (PyDict_CheckExact(f->f_globals) + && PyDict_CheckExact(f->f_builtins)) + { + OPCACHE_CHECK(); + if (co_opcache != NULL && co_opcache->optimized > 0) { + _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg; + + if (lg->globals_ver == + ((PyDictObject *)f->f_globals)->ma_version_tag + && lg->builtins_ver == + ((PyDictObject *)f->f_builtins)->ma_version_tag) + { + PyObject *ptr = lg->ptr; + OPCACHE_STAT_GLOBAL_HIT(); + assert(ptr != NULL); + Py_INCREF(ptr); + PUSH(ptr); + DISPATCH(); + } + } + + name = GETITEM(names, oparg); + v = _PyDict_LoadGlobal((PyDictObject *)f->f_globals, + (PyDictObject *)f->f_builtins, + name); + if (v == NULL) { + if (!_PyErr_OCCURRED()) { + /* _PyDict_LoadGlobal() returns NULL without raising + * an exception if the key doesn't exist */ + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + + if (co_opcache != NULL) { + _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg; + + if (co_opcache->optimized == 0) { + /* Wasn't optimized before. */ + OPCACHE_STAT_GLOBAL_OPT(); + } else { + OPCACHE_STAT_GLOBAL_MISS(); + } + + co_opcache->optimized = 1; + lg->globals_ver = + ((PyDictObject *)f->f_globals)->ma_version_tag; + lg->builtins_ver = + ((PyDictObject *)f->f_builtins)->ma_version_tag; + lg->ptr = v; /* borrowed */ + } + + Py_INCREF(v); + } + else { + /* Slow-path if globals or builtins is not a dict */ + + /* namespace 1: globals */ + name = GETITEM(names, oparg); + v = PyObject_GetItem(f->f_globals, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + + /* namespace 2: builtins */ + v = PyObject_GetItem(f->f_builtins, name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + PUSH(v); + DISPATCH(); + } + + case TARGET(DELETE_FAST): { + PyObject *v = GETLOCAL(oparg); + if (v != NULL) { + SETLOCAL(oparg, NULL); + DISPATCH(); + } + format_exc_check_arg( + tstate, PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, + PyTuple_GetItem(co->co_varnames, oparg) + ); + goto error; + } + + case TARGET(DELETE_DEREF): { + PyObject *cell = freevars[oparg]; + PyObject *oldobj = PyCell_GET(cell); + if (oldobj != NULL) { + PyCell_SET(cell, NULL); + Py_DECREF(oldobj); + DISPATCH(); + } + format_exc_unbound(tstate, co, oparg); + goto error; + } + + case TARGET(LOAD_CLOSURE): { + PyObject *cell = freevars[oparg]; + Py_INCREF(cell); + PUSH(cell); + DISPATCH(); + } + + case TARGET(LOAD_CLASSDEREF): { + PyObject *name, *value, *locals = f->f_locals; + Py_ssize_t idx; + assert(locals); + assert(oparg >= PyTuple_GET_SIZE(co->co_cellvars)); + idx = oparg - PyTuple_GET_SIZE(co->co_cellvars); + assert(idx >= 0 && idx < PyTuple_GET_SIZE(co->co_freevars)); + name = PyTuple_GET_ITEM(co->co_freevars, idx); + if (PyDict_CheckExact(locals)) { + value = PyDict_GetItemWithError(locals, name); + if (value != NULL) { + Py_INCREF(value); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + value = PyObject_GetItem(locals, name); + if (value == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (!value) { + PyObject *cell = freevars[oparg]; + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, co, oparg); + goto error; + } + Py_INCREF(value); + } + PUSH(value); + DISPATCH(); + } + + case TARGET(LOAD_DEREF): { + PyObject *cell = freevars[oparg]; + PyObject *value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, co, oparg); + goto error; + } + Py_INCREF(value); + PUSH(value); + DISPATCH(); + } + + case TARGET(STORE_DEREF): { + PyObject *v = POP(); + PyObject *cell = freevars[oparg]; + PyObject *oldobj = PyCell_GET(cell); + PyCell_SET(cell, v); + Py_XDECREF(oldobj); + DISPATCH(); + } + + case TARGET(BUILD_STRING): { + PyObject *str; + PyObject *empty = PyUnicode_New(0, 0); + if (empty == NULL) { + goto error; + } + str = _PyUnicode_JoinArray(empty, stack_pointer - oparg, oparg); + Py_DECREF(empty); + if (str == NULL) + goto error; + while (--oparg >= 0) { + PyObject *item = POP(); + Py_DECREF(item); + } + PUSH(str); + DISPATCH(); + } + + case TARGET(BUILD_TUPLE): { + PyObject *tup = PyTuple_New(oparg); + if (tup == NULL) + goto error; + while (--oparg >= 0) { + PyObject *item = POP(); + PyTuple_SET_ITEM(tup, oparg, item); + } + PUSH(tup); + DISPATCH(); + } + + case TARGET(BUILD_LIST): { + PyObject *list = PyList_New(oparg); + if (list == NULL) + goto error; + while (--oparg >= 0) { + PyObject *item = POP(); + PyList_SET_ITEM(list, oparg, item); + } + PUSH(list); + DISPATCH(); + } + + case TARGET(BUILD_TUPLE_UNPACK_WITH_CALL): + case TARGET(BUILD_TUPLE_UNPACK): + case TARGET(BUILD_LIST_UNPACK): { + int convert_to_tuple = opcode != BUILD_LIST_UNPACK; + Py_ssize_t i; + PyObject *sum = PyList_New(0); + PyObject *return_value; + + if (sum == NULL) + goto error; + + for (i = oparg; i > 0; i--) { + PyObject *none_val; + + none_val = _PyList_Extend((PyListObject *)sum, PEEK(i)); + if (none_val == NULL) { + if (opcode == BUILD_TUPLE_UNPACK_WITH_CALL && + _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) + { + check_args_iterable(tstate, PEEK(1 + oparg), PEEK(i)); + } + Py_DECREF(sum); + goto error; + } + Py_DECREF(none_val); + } + + if (convert_to_tuple) { + return_value = PyList_AsTuple(sum); + Py_DECREF(sum); + if (return_value == NULL) + goto error; + } + else { + return_value = sum; + } + + while (oparg--) + Py_DECREF(POP()); + PUSH(return_value); + DISPATCH(); + } + + case TARGET(BUILD_SET): { + PyObject *set = PySet_New(NULL); + int err = 0; + int i; + if (set == NULL) + goto error; + for (i = oparg; i > 0; i--) { + PyObject *item = PEEK(i); + if (err == 0) + err = PySet_Add(set, item); + Py_DECREF(item); + } + STACK_SHRINK(oparg); + if (err != 0) { + Py_DECREF(set); + goto error; + } + PUSH(set); + DISPATCH(); + } + + case TARGET(BUILD_SET_UNPACK): { + Py_ssize_t i; + PyObject *sum = PySet_New(NULL); + if (sum == NULL) + goto error; + + for (i = oparg; i > 0; i--) { + if (_PySet_Update(sum, PEEK(i)) < 0) { + Py_DECREF(sum); + goto error; + } + } + + while (oparg--) + Py_DECREF(POP()); + PUSH(sum); + DISPATCH(); + } + + case TARGET(BUILD_MAP): { + Py_ssize_t i; + PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg); + if (map == NULL) + goto error; + for (i = oparg; i > 0; i--) { + int err; + PyObject *key = PEEK(2*i); + PyObject *value = PEEK(2*i - 1); + err = PyDict_SetItem(map, key, value); + if (err != 0) { + Py_DECREF(map); + goto error; + } + } + + while (oparg--) { + Py_DECREF(POP()); + Py_DECREF(POP()); + } + PUSH(map); + DISPATCH(); + } + + case TARGET(SETUP_ANNOTATIONS): { + _Py_IDENTIFIER(__annotations__); + int err; + PyObject *ann_dict; + if (f->f_locals == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); + goto error; + } + /* check if __annotations__ in locals()... */ + if (PyDict_CheckExact(f->f_locals)) { + ann_dict = _PyDict_GetItemIdWithError(f->f_locals, + &PyId___annotations__); + if (ann_dict == NULL) { + if (_PyErr_Occurred(tstate)) { + goto error; + } + /* ...if not, create a new one */ + ann_dict = PyDict_New(); + if (ann_dict == NULL) { + goto error; + } + err = _PyDict_SetItemId(f->f_locals, + &PyId___annotations__, ann_dict); + Py_DECREF(ann_dict); + if (err != 0) { + goto error; + } + } + } + else { + /* do the same if locals() is not a dict */ + PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__); + if (ann_str == NULL) { + goto error; + } + ann_dict = PyObject_GetItem(f->f_locals, ann_str); + if (ann_dict == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + ann_dict = PyDict_New(); + if (ann_dict == NULL) { + goto error; + } + err = PyObject_SetItem(f->f_locals, ann_str, ann_dict); + Py_DECREF(ann_dict); + if (err != 0) { + goto error; + } + } + else { + Py_DECREF(ann_dict); + } + } + DISPATCH(); + } + + case TARGET(BUILD_CONST_KEY_MAP): { + Py_ssize_t i; + PyObject *map; + PyObject *keys = TOP(); + if (!PyTuple_CheckExact(keys) || + PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { + _PyErr_SetString(tstate, PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); + goto error; + } + map = _PyDict_NewPresized((Py_ssize_t)oparg); + if (map == NULL) { + goto error; + } + for (i = oparg; i > 0; i--) { + int err; + PyObject *key = PyTuple_GET_ITEM(keys, oparg - i); + PyObject *value = PEEK(i + 1); + err = PyDict_SetItem(map, key, value); + if (err != 0) { + Py_DECREF(map); + goto error; + } + } + + Py_DECREF(POP()); + while (oparg--) { + Py_DECREF(POP()); + } + PUSH(map); + DISPATCH(); + } + + case TARGET(BUILD_MAP_UNPACK): { + Py_ssize_t i; + PyObject *sum = PyDict_New(); + if (sum == NULL) + goto error; + + for (i = oparg; i > 0; i--) { + PyObject *arg = PEEK(i); + if (PyDict_Update(sum, arg) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + arg->ob_type->tp_name); + } + Py_DECREF(sum); + goto error; + } + } + + while (oparg--) + Py_DECREF(POP()); + PUSH(sum); + DISPATCH(); + } + + case TARGET(BUILD_MAP_UNPACK_WITH_CALL): { + Py_ssize_t i; + PyObject *sum = PyDict_New(); + if (sum == NULL) + goto error; + + for (i = oparg; i > 0; i--) { + PyObject *arg = PEEK(i); + if (_PyDict_MergeEx(sum, arg, 2) < 0) { + Py_DECREF(sum); + format_kwargs_error(tstate, PEEK(2 + oparg), arg); + goto error; + } + } + + while (oparg--) + Py_DECREF(POP()); + PUSH(sum); + DISPATCH(); + } + + case TARGET(MAP_ADD): { + PyObject *value = TOP(); + PyObject *key = SECOND(); + PyObject *map; + int err; + STACK_SHRINK(2); + map = PEEK(oparg); /* dict */ + assert(PyDict_CheckExact(map)); + err = PyDict_SetItem(map, key, value); /* map[key] = value */ + Py_DECREF(value); + Py_DECREF(key); + if (err != 0) + goto error; + PREDICT(JUMP_ABSOLUTE); + DISPATCH(); + } + + case TARGET(LOAD_ATTR): { + PyObject *name = GETITEM(names, oparg); + PyObject *owner = TOP(); + PyObject *res = PyObject_GetAttr(owner, name); + Py_DECREF(owner); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(COMPARE_OP): { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = cmp_outcome(tstate, oparg, left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + PREDICT(POP_JUMP_IF_FALSE); + PREDICT(POP_JUMP_IF_TRUE); + DISPATCH(); + } + + case TARGET(IMPORT_NAME): { + PyObject *name = GETITEM(names, oparg); + PyObject *fromlist = POP(); + PyObject *level = TOP(); + PyObject *res; + res = import_name(tstate, f, name, fromlist, level); + Py_DECREF(level); + Py_DECREF(fromlist); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(IMPORT_STAR): { + PyObject *from = POP(), *locals; + int err; + if (PyFrame_FastToLocalsWithError(f) < 0) { + Py_DECREF(from); + goto error; + } + + locals = f->f_locals; + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found during 'import *'"); + Py_DECREF(from); + goto error; + } + err = import_all_from(tstate, locals, from); + PyFrame_LocalsToFast(f, 0); + Py_DECREF(from); + if (err != 0) + goto error; + DISPATCH(); + } + + case TARGET(IMPORT_FROM): { + PyObject *name = GETITEM(names, oparg); + PyObject *from = TOP(); + PyObject *res; + res = import_from(tstate, from, name); + PUSH(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(JUMP_FORWARD): { + JUMPBY(oparg); + FAST_DISPATCH(); + } + + case TARGET(POP_JUMP_IF_FALSE): { + PREDICTED(POP_JUMP_IF_FALSE); + PyObject *cond = POP(); + int err; + if (cond == Py_True) { + Py_DECREF(cond); + FAST_DISPATCH(); + } + if (cond == Py_False) { + Py_DECREF(cond); + JUMPTO(oparg); + FAST_DISPATCH(); + } + err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) + ; + else if (err == 0) + JUMPTO(oparg); + else + goto error; + DISPATCH(); + } + + case TARGET(POP_JUMP_IF_TRUE): { + PREDICTED(POP_JUMP_IF_TRUE); + PyObject *cond = POP(); + int err; + if (cond == Py_False) { + Py_DECREF(cond); + FAST_DISPATCH(); + } + if (cond == Py_True) { + Py_DECREF(cond); + JUMPTO(oparg); + FAST_DISPATCH(); + } + err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) { + JUMPTO(oparg); + } + else if (err == 0) + ; + else + goto error; + DISPATCH(); + } + + case TARGET(JUMP_IF_FALSE_OR_POP): { + PyObject *cond = TOP(); + int err; + if (cond == Py_True) { + STACK_SHRINK(1); + Py_DECREF(cond); + FAST_DISPATCH(); + } + if (cond == Py_False) { + JUMPTO(oparg); + FAST_DISPATCH(); + } + err = PyObject_IsTrue(cond); + if (err > 0) { + STACK_SHRINK(1); + Py_DECREF(cond); + } + else if (err == 0) + JUMPTO(oparg); + else + goto error; + DISPATCH(); + } + + case TARGET(JUMP_IF_TRUE_OR_POP): { + PyObject *cond = TOP(); + int err; + if (cond == Py_False) { + STACK_SHRINK(1); + Py_DECREF(cond); + FAST_DISPATCH(); + } + if (cond == Py_True) { + JUMPTO(oparg); + FAST_DISPATCH(); + } + err = PyObject_IsTrue(cond); + if (err > 0) { + JUMPTO(oparg); + } + else if (err == 0) { + STACK_SHRINK(1); + Py_DECREF(cond); + } + else + goto error; + DISPATCH(); + } + + case TARGET(JUMP_ABSOLUTE): { + PREDICTED(JUMP_ABSOLUTE); + JUMPTO(oparg); +#if FAST_LOOPS + /* Enabling this path speeds-up all while and for-loops by bypassing + the per-loop checks for signals. By default, this should be turned-off + because it prevents detection of a control-break in tight loops like + "while 1: pass". Compile with this option turned-on when you need + the speed-up and do not need break checking inside tight loops (ones + that contain only instructions ending with FAST_DISPATCH). + */ + FAST_DISPATCH(); +#else + DISPATCH(); +#endif + } + + case TARGET(GET_ITER): { + /* before: [obj]; after [getiter(obj)] */ + PyObject *iterable = TOP(); + PyObject *iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + SET_TOP(iter); + if (iter == NULL) + goto error; + PREDICT(FOR_ITER); + PREDICT(CALL_FUNCTION); + DISPATCH(); + } + + case TARGET(GET_YIELD_FROM_ITER): { + /* before: [obj]; after [getiter(obj)] */ + PyObject *iterable = TOP(); + PyObject *iter; + if (PyCoro_CheckExact(iterable)) { + /* `iterable` is a coroutine */ + if (!(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { + /* and it is used in a 'yield from' expression of a + regular generator. */ + Py_DECREF(iterable); + SET_TOP(NULL); + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); + goto error; + } + } + else if (!PyGen_CheckExact(iterable)) { + /* `iterable` is not a generator. */ + iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + SET_TOP(iter); + if (iter == NULL) + goto error; + } + PREDICT(LOAD_CONST); + DISPATCH(); + } + + case TARGET(FOR_ITER): { + PREDICTED(FOR_ITER); + /* before: [iter]; after: [iter, iter()] *or* [] */ + PyObject *iter = TOP(); + PyObject *next = (*iter->ob_type->tp_iternext)(iter); + if (next != NULL) { + PUSH(next); + PREDICT(STORE_FAST); + PREDICT(UNPACK_SEQUENCE); + DISPATCH(); + } + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + goto error; + } + else if (tstate->c_tracefunc != NULL) { + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); + } + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + STACK_SHRINK(1); + Py_DECREF(iter); + JUMPBY(oparg); + PREDICT(POP_BLOCK); + DISPATCH(); + } + + case TARGET(SETUP_FINALLY): { + /* NOTE: If you add any new block-setup opcodes that + are not try/except/finally handlers, you may need + to update the PyGen_NeedsFinalizing() function. + */ + + PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, + STACK_LEVEL()); + DISPATCH(); + } + + case TARGET(BEFORE_ASYNC_WITH): { + _Py_IDENTIFIER(__aexit__); + _Py_IDENTIFIER(__aenter__); + + PyObject *mgr = TOP(); + PyObject *exit = special_lookup(tstate, mgr, &PyId___aexit__), + *enter; + PyObject *res; + if (exit == NULL) + goto error; + SET_TOP(exit); + enter = special_lookup(tstate, mgr, &PyId___aenter__); + Py_DECREF(mgr); + if (enter == NULL) + goto error; + res = _PyObject_CallNoArg(enter); + Py_DECREF(enter); + if (res == NULL) + goto error; + PUSH(res); + PREDICT(GET_AWAITABLE); + DISPATCH(); + } + + case TARGET(SETUP_ASYNC_WITH): { + PyObject *res = POP(); + /* Setup the finally block before pushing the result + of __aenter__ on the stack. */ + PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, + STACK_LEVEL()); + PUSH(res); + DISPATCH(); + } + + case TARGET(SETUP_WITH): { + _Py_IDENTIFIER(__exit__); + _Py_IDENTIFIER(__enter__); + PyObject *mgr = TOP(); + PyObject *enter = special_lookup(tstate, mgr, &PyId___enter__); + PyObject *res; + if (enter == NULL) { + goto error; + } + PyObject *exit = special_lookup(tstate, mgr, &PyId___exit__); + if (exit == NULL) { + Py_DECREF(enter); + goto error; + } + SET_TOP(exit); + Py_DECREF(mgr); + res = _PyObject_CallNoArg(enter); + Py_DECREF(enter); + if (res == NULL) + goto error; + /* Setup the finally block before pushing the result + of __enter__ on the stack. */ + PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, + STACK_LEVEL()); + + PUSH(res); + DISPATCH(); + } + + case TARGET(WITH_CLEANUP_START): { + /* At the top of the stack are 1 or 6 values indicating + how/why we entered the finally clause: + - TOP = NULL + - (TOP, SECOND, THIRD) = exc_info() + (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER + Below them is EXIT, the context.__exit__ or context.__aexit__ + bound method. + In the first case, we must call + EXIT(None, None, None) + otherwise we must call + EXIT(TOP, SECOND, THIRD) + + In the first case, we remove EXIT from the + stack, leaving TOP, and push TOP on the stack. + Otherwise we shift the bottom 3 values of the + stack down, replace the empty spot with NULL, and push + None on the stack. + + Finally we push the result of the call. + */ + PyObject *stack[3]; + PyObject *exit_func; + PyObject *exc, *val, *tb, *res; + + val = tb = Py_None; + exc = TOP(); + if (exc == NULL) { + STACK_SHRINK(1); + exit_func = TOP(); + SET_TOP(exc); + exc = Py_None; + } + else { + assert(PyExceptionClass_Check(exc)); + PyObject *tp2, *exc2, *tb2; + PyTryBlock *block; + val = SECOND(); + tb = THIRD(); + tp2 = FOURTH(); + exc2 = PEEK(5); + tb2 = PEEK(6); + exit_func = PEEK(7); + SET_VALUE(7, tb2); + SET_VALUE(6, exc2); + SET_VALUE(5, tp2); + /* UNWIND_EXCEPT_HANDLER will pop this off. */ + SET_FOURTH(NULL); + /* We just shifted the stack down, so we have + to tell the except handler block that the + values are lower than it expects. */ + assert(f->f_iblock > 0); + block = &f->f_blockstack[f->f_iblock - 1]; + assert(block->b_type == EXCEPT_HANDLER); + assert(block->b_level > 0); + block->b_level--; + } + + stack[0] = exc; + stack[1] = val; + stack[2] = tb; + res = _PyObject_FastCall(exit_func, stack, 3); + Py_DECREF(exit_func); + if (res == NULL) + goto error; + + Py_INCREF(exc); /* Duplicating the exception on the stack */ + PUSH(exc); + PUSH(res); + PREDICT(WITH_CLEANUP_FINISH); + DISPATCH(); + } + + case TARGET(WITH_CLEANUP_FINISH): { + PREDICTED(WITH_CLEANUP_FINISH); + /* TOP = the result of calling the context.__exit__ bound method + SECOND = either None or exception type + + If SECOND is None below is NULL or the return address, + otherwise below are 7 values representing an exception. + */ + PyObject *res = POP(); + PyObject *exc = POP(); + int err; + + if (exc != Py_None) + err = PyObject_IsTrue(res); + else + err = 0; + + Py_DECREF(res); + Py_DECREF(exc); + + if (err < 0) + goto error; + else if (err > 0) { + /* There was an exception and a True return. + * We must manually unwind the EXCEPT_HANDLER block + * which was created when the exception was caught, + * otherwise the stack will be in an inconsistent state. + */ + PyTryBlock *b = PyFrame_BlockPop(f); + assert(b->b_type == EXCEPT_HANDLER); + UNWIND_EXCEPT_HANDLER(b); + PUSH(NULL); + } + PREDICT(END_FINALLY); + DISPATCH(); + } + + case TARGET(LOAD_METHOD): { + /* Designed to work in tandem with CALL_METHOD. */ + PyObject *name = GETITEM(names, oparg); + PyObject *obj = TOP(); + PyObject *meth = NULL; + + int meth_found = _PyObject_GetMethod(obj, name, &meth); + + if (meth == NULL) { + /* Most likely attribute wasn't found. */ + goto error; + } + + if (meth_found) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + + meth | self | arg1 | ... | argN + */ + SET_TOP(meth); + PUSH(obj); // self + } + else { + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL_METHOD that it's not a method call. + + NULL | meth | arg1 | ... | argN + */ + SET_TOP(NULL); + Py_DECREF(obj); + PUSH(meth); + } + DISPATCH(); + } + + case TARGET(CALL_METHOD): { + /* Designed to work in tamdem with LOAD_METHOD. */ + PyObject **sp, *res, *meth; + + sp = stack_pointer; + + meth = PEEK(oparg + 2); + if (meth == NULL) { + /* `meth` is NULL when LOAD_METHOD thinks that it's not + a method call. + + Stack layout: + + ... | NULL | callable | arg1 | ... | argN + ^- TOP() + ^- (-oparg) + ^- (-oparg-1) + ^- (-oparg-2) + + `callable` will be POPed by call_function. + NULL will will be POPed manually later. + */ + res = call_function(tstate, &sp, oparg, NULL); + stack_pointer = sp; + (void)POP(); /* POP the NULL. */ + } + else { + /* This is a method call. Stack layout: + + ... | method | self | arg1 | ... | argN + ^- TOP() + ^- (-oparg) + ^- (-oparg-1) + ^- (-oparg-2) + + `self` and `method` will be POPed by call_function. + We'll be passing `oparg + 1` to call_function, to + make it accept the `self` as a first argument. + */ + res = call_function(tstate, &sp, oparg + 1, NULL); + stack_pointer = sp; + } + + PUSH(res); + if (res == NULL) + goto error; + DISPATCH(); + } + + case TARGET(CALL_FUNCTION): { + PREDICTED(CALL_FUNCTION); + PyObject **sp, *res; + sp = stack_pointer; + res = call_function(tstate, &sp, oparg, NULL); + stack_pointer = sp; + PUSH(res); + if (res == NULL) { + goto error; + } + DISPATCH(); + } + + case TARGET(CALL_FUNCTION_KW): { + PyObject **sp, *res, *names; + + names = POP(); + assert(PyTuple_CheckExact(names) && PyTuple_GET_SIZE(names) <= oparg); + sp = stack_pointer; + res = call_function(tstate, &sp, oparg, names); + stack_pointer = sp; + PUSH(res); + Py_DECREF(names); + + if (res == NULL) { + goto error; + } + DISPATCH(); + } + + case TARGET(CALL_FUNCTION_EX): { + PyObject *func, *callargs, *kwargs = NULL, *result; + if (oparg & 0x01) { + kwargs = POP(); + if (!PyDict_CheckExact(kwargs)) { + PyObject *d = PyDict_New(); + if (d == NULL) + goto error; + if (_PyDict_MergeEx(d, kwargs, 2) < 0) { + Py_DECREF(d); + format_kwargs_error(tstate, SECOND(), kwargs); + Py_DECREF(kwargs); + goto error; + } + Py_DECREF(kwargs); + kwargs = d; + } + assert(PyDict_CheckExact(kwargs)); + } + callargs = POP(); + func = TOP(); + if (!PyTuple_CheckExact(callargs)) { + if (check_args_iterable(tstate, func, callargs) < 0) { + Py_DECREF(callargs); + goto error; + } + Py_SETREF(callargs, PySequence_Tuple(callargs)); + if (callargs == NULL) { + goto error; + } + } + assert(PyTuple_CheckExact(callargs)); + + result = do_call_core(tstate, func, callargs, kwargs); + Py_DECREF(func); + Py_DECREF(callargs); + Py_XDECREF(kwargs); + + SET_TOP(result); + if (result == NULL) { + goto error; + } + DISPATCH(); + } + + case TARGET(MAKE_FUNCTION): { + PyObject *qualname = POP(); + PyObject *codeobj = POP(); + PyFunctionObject *func = (PyFunctionObject *) + PyFunction_NewWithQualName(codeobj, f->f_globals, qualname); + + Py_DECREF(codeobj); + Py_DECREF(qualname); + if (func == NULL) { + goto error; + } + + if (oparg & 0x08) { + assert(PyTuple_CheckExact(TOP())); + func ->func_closure = POP(); + } + if (oparg & 0x04) { + assert(PyDict_CheckExact(TOP())); + func->func_annotations = POP(); + } + if (oparg & 0x02) { + assert(PyDict_CheckExact(TOP())); + func->func_kwdefaults = POP(); + } + if (oparg & 0x01) { + assert(PyTuple_CheckExact(TOP())); + func->func_defaults = POP(); + } + + PUSH((PyObject *)func); + DISPATCH(); + } + + case TARGET(BUILD_SLICE): { + PyObject *start, *stop, *step, *slice; + if (oparg == 3) + step = POP(); + else + step = NULL; + stop = POP(); + start = TOP(); + slice = PySlice_New(start, stop, step); + Py_DECREF(start); + Py_DECREF(stop); + Py_XDECREF(step); + SET_TOP(slice); + if (slice == NULL) + goto error; + DISPATCH(); + } + + case TARGET(FORMAT_VALUE): { + /* Handles f-string value formatting. */ + PyObject *result; + PyObject *fmt_spec; + PyObject *value; + PyObject *(*conv_fn)(PyObject *); + int which_conversion = oparg & FVC_MASK; + int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; + + fmt_spec = have_fmt_spec ? POP() : NULL; + value = POP(); + + /* See if any conversion is specified. */ + switch (which_conversion) { + case FVC_NONE: conv_fn = NULL; break; + case FVC_STR: conv_fn = PyObject_Str; break; + case FVC_REPR: conv_fn = PyObject_Repr; break; + case FVC_ASCII: conv_fn = PyObject_ASCII; break; + default: + _PyErr_Format(tstate, PyExc_SystemError, + "unexpected conversion flag %d", + which_conversion); + goto error; + } + + /* If there's a conversion function, call it and replace + value with that result. Otherwise, just use value, + without conversion. */ + if (conv_fn != NULL) { + result = conv_fn(value); + Py_DECREF(value); + if (result == NULL) { + Py_XDECREF(fmt_spec); + goto error; + } + value = result; + } + + /* If value is a unicode object, and there's no fmt_spec, + then we know the result of format(value) is value + itself. In that case, skip calling format(). I plan to + move this optimization in to PyObject_Format() + itself. */ + if (PyUnicode_CheckExact(value) && fmt_spec == NULL) { + /* Do nothing, just transfer ownership to result. */ + result = value; + } else { + /* Actually call format(). */ + result = PyObject_Format(value, fmt_spec); + Py_DECREF(value); + Py_XDECREF(fmt_spec); + if (result == NULL) { + goto error; + } + } + + PUSH(result); + DISPATCH(); + } + + case TARGET(EXTENDED_ARG): { + int oldoparg = oparg; + NEXTOPARG(); + oparg |= oldoparg << 8; + goto dispatch_opcode; + } + + +#if USE_COMPUTED_GOTOS + _unknown_opcode: +#endif + default: + fprintf(stderr, + "XXX lineno: %d, opcode: %d\n", + PyFrame_GetLineNumber(f), + opcode); + _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode"); + goto error; + + } /* switch */ + + /* This should never be reached. Every opcode should end with DISPATCH() + or goto error. */ + Py_UNREACHABLE(); + +error: + /* Double-check exception status. */ +#ifdef NDEBUG + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_SystemError, + "error return without exception set"); + } +#else + assert(_PyErr_Occurred(tstate)); +#endif + + /* Log traceback info. */ + PyTraceBack_Here(f); + + if (tstate->c_tracefunc != NULL) + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f); + +exception_unwind: + /* Unwind stacks if an exception occurred */ + while (f->f_iblock > 0) { + /* Pop the current block. */ + PyTryBlock *b = &f->f_blockstack[--f->f_iblock]; + + if (b->b_type == EXCEPT_HANDLER) { + UNWIND_EXCEPT_HANDLER(b); + continue; + } + UNWIND_BLOCK(b); + if (b->b_type == SETUP_FINALLY) { + PyObject *exc, *val, *tb; + int handler = b->b_handler; + _PyErr_StackItem *exc_info = tstate->exc_info; + /* Beware, this invalidates all b->b_* fields */ + PyFrame_BlockSetup(f, EXCEPT_HANDLER, -1, STACK_LEVEL()); + PUSH(exc_info->exc_traceback); + PUSH(exc_info->exc_value); + if (exc_info->exc_type != NULL) { + PUSH(exc_info->exc_type); + } + else { + Py_INCREF(Py_None); + PUSH(Py_None); + } + _PyErr_Fetch(tstate, &exc, &val, &tb); + /* Make the raw exception data + available to the handler, + so a program can emulate the + Python main loop. */ + _PyErr_NormalizeException(tstate, &exc, &val, &tb); + if (tb != NULL) + PyException_SetTraceback(val, tb); + else + PyException_SetTraceback(val, Py_None); + Py_INCREF(exc); + exc_info->exc_type = exc; + Py_INCREF(val); + exc_info->exc_value = val; + exc_info->exc_traceback = tb; + if (tb == NULL) + tb = Py_None; + Py_INCREF(tb); + PUSH(tb); + PUSH(val); + PUSH(exc); + JUMPTO(handler); + /* Resume normal execution */ + goto main_loop; + } + } /* unwind stack */ + + /* End the loop as we still have an error */ + break; + } /* main loop */ + + assert(retval == NULL); + assert(_PyErr_Occurred(tstate)); + +exit_returning: + + /* Pop remaining stack entries. */ + while (!EMPTY()) { + PyObject *o = POP(); + Py_XDECREF(o); + } + +exit_yielding: + if (tstate->use_tracing) { + if (tstate->c_tracefunc) { + if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f, PyTrace_RETURN, retval)) { + Py_CLEAR(retval); + } + } + if (tstate->c_profilefunc) { + if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, + tstate, f, PyTrace_RETURN, retval)) { + Py_CLEAR(retval); + } + } + } + + /* pop frame */ +exit_eval_frame: + if (PyDTrace_FUNCTION_RETURN_ENABLED()) + dtrace_function_return(f); + Py_LeaveRecursiveCall(); + f->f_executing = 0; + tstate->frame = f->f_back; + + return _Py_CheckFunctionResult(NULL, retval, "PyEval_EvalFrameEx"); +} + +static void +format_missing(PyThreadState *tstate, const char *kind, + PyCodeObject *co, PyObject *names) +{ + int err; + Py_ssize_t len = PyList_GET_SIZE(names); + PyObject *name_str, *comma, *tail, *tmp; + + assert(PyList_CheckExact(names)); + assert(len >= 1); + /* Deal with the joys of natural language. */ + switch (len) { + case 1: + name_str = PyList_GET_ITEM(names, 0); + Py_INCREF(name_str); + break; + case 2: + name_str = PyUnicode_FromFormat("%U and %U", + PyList_GET_ITEM(names, len - 2), + PyList_GET_ITEM(names, len - 1)); + break; + default: + tail = PyUnicode_FromFormat(", %U, and %U", + PyList_GET_ITEM(names, len - 2), + PyList_GET_ITEM(names, len - 1)); + if (tail == NULL) + return; + /* Chop off the last two objects in the list. This shouldn't actually + fail, but we can't be too careful. */ + err = PyList_SetSlice(names, len - 2, len, NULL); + if (err == -1) { + Py_DECREF(tail); + return; + } + /* Stitch everything up into a nice comma-separated list. */ + comma = PyUnicode_FromString(", "); + if (comma == NULL) { + Py_DECREF(tail); + return; + } + tmp = PyUnicode_Join(comma, names); + Py_DECREF(comma); + if (tmp == NULL) { + Py_DECREF(tail); + return; + } + name_str = PyUnicode_Concat(tmp, tail); + Py_DECREF(tmp); + Py_DECREF(tail); + break; + } + if (name_str == NULL) + return; + _PyErr_Format(tstate, PyExc_TypeError, + "%U() missing %i required %s argument%s: %U", + co->co_name, + len, + kind, + len == 1 ? "" : "s", + name_str); + Py_DECREF(name_str); +} + +static void +missing_arguments(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t missing, Py_ssize_t defcount, + PyObject **fastlocals) +{ + Py_ssize_t i, j = 0; + Py_ssize_t start, end; + int positional = (defcount != -1); + const char *kind = positional ? "positional" : "keyword-only"; + PyObject *missing_names; + + /* Compute the names of the arguments that are missing. */ + missing_names = PyList_New(missing); + if (missing_names == NULL) + return; + if (positional) { + start = 0; + end = co->co_argcount - defcount; + } + else { + start = co->co_argcount; + end = start + co->co_kwonlyargcount; + } + for (i = start; i < end; i++) { + if (GETLOCAL(i) == NULL) { + PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i); + PyObject *name = PyObject_Repr(raw); + if (name == NULL) { + Py_DECREF(missing_names); + return; + } + PyList_SET_ITEM(missing_names, j++, name); + } + } + assert(j == missing); + format_missing(tstate, kind, co, missing_names); + Py_DECREF(missing_names); +} + +static void +too_many_positional(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t given, Py_ssize_t defcount, + PyObject **fastlocals) +{ + int plural; + Py_ssize_t kwonly_given = 0; + Py_ssize_t i; + PyObject *sig, *kwonly_sig; + Py_ssize_t co_argcount = co->co_argcount; + + assert((co->co_flags & CO_VARARGS) == 0); + /* Count missing keyword-only args. */ + for (i = co_argcount; i < co_argcount + co->co_kwonlyargcount; i++) { + if (GETLOCAL(i) != NULL) { + kwonly_given++; + } + } + if (defcount) { + Py_ssize_t atleast = co_argcount - defcount; + plural = 1; + sig = PyUnicode_FromFormat("from %zd to %zd", atleast, co_argcount); + } + else { + plural = (co_argcount != 1); + sig = PyUnicode_FromFormat("%zd", co_argcount); + } + if (sig == NULL) + return; + if (kwonly_given) { + const char *format = " positional argument%s (and %zd keyword-only argument%s)"; + kwonly_sig = PyUnicode_FromFormat(format, + given != 1 ? "s" : "", + kwonly_given, + kwonly_given != 1 ? "s" : ""); + if (kwonly_sig == NULL) { + Py_DECREF(sig); + return; + } + } + else { + /* This will not fail. */ + kwonly_sig = PyUnicode_FromString(""); + assert(kwonly_sig != NULL); + } + _PyErr_Format(tstate, PyExc_TypeError, + "%U() takes %U positional argument%s but %zd%U %s given", + co->co_name, + sig, + plural ? "s" : "", + given, + kwonly_sig, + given == 1 && !kwonly_given ? "was" : "were"); + Py_DECREF(sig); + Py_DECREF(kwonly_sig); +} + +static int +positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t kwcount, PyObject* const* kwnames) +{ + int posonly_conflicts = 0; + PyObject* posonly_names = PyList_New(0); + + for(int k=0; k < co->co_posonlyargcount; k++){ + PyObject* posonly_name = PyTuple_GET_ITEM(co->co_varnames, k); + + for (int k2=0; k2 0) { + if(PyList_Append(posonly_names, kwname) != 0) { + goto fail; + } + posonly_conflicts++; + } else if (cmp < 0) { + goto fail; + } + + } + } + if (posonly_conflicts) { + PyObject* comma = PyUnicode_FromString(", "); + if (comma == NULL) { + goto fail; + } + PyObject* error_names = PyUnicode_Join(comma, posonly_names); + Py_DECREF(comma); + if (error_names == NULL) { + goto fail; + } + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got some positional-only arguments passed" + " as keyword arguments: '%U'", + co->co_name, error_names); + Py_DECREF(error_names); + goto fail; + } + + Py_DECREF(posonly_names); + return 0; + +fail: + Py_XDECREF(posonly_names); + return 1; + +} + +/* This is gonna seem *real weird*, but if you put some other code between + PyEval_EvalFrame() and _PyEval_EvalFrameDefault() you will need to adjust + the test in the if statements in Misc/gdbinit (pystack and pystackv). */ + +PyObject * +_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, + PyObject *const *args, Py_ssize_t argcount, + PyObject *const *kwnames, PyObject *const *kwargs, + Py_ssize_t kwcount, int kwstep, + PyObject *const *defs, Py_ssize_t defcount, + PyObject *kwdefs, PyObject *closure, + PyObject *name, PyObject *qualname) +{ + PyCodeObject* co = (PyCodeObject*)_co; + PyFrameObject *f; + PyObject *retval = NULL; + PyObject **fastlocals, **freevars; + PyObject *x, *u; + const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; + Py_ssize_t i, j, n; + PyObject *kwdict; + + PyThreadState *tstate = _PyThreadState_GET(); + assert(tstate != NULL); + + if (globals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "PyEval_EvalCodeEx: NULL globals"); + return NULL; + } + + /* Create the frame */ + f = _PyFrame_New_NoTrack(tstate, co, globals, locals); + if (f == NULL) { + return NULL; + } + fastlocals = f->f_localsplus; + freevars = f->f_localsplus + co->co_nlocals; + + /* Create a dictionary for keyword parameters (**kwags) */ + if (co->co_flags & CO_VARKEYWORDS) { + kwdict = PyDict_New(); + if (kwdict == NULL) + goto fail; + i = total_args; + if (co->co_flags & CO_VARARGS) { + i++; + } + SETLOCAL(i, kwdict); + } + else { + kwdict = NULL; + } + + /* Copy all positional arguments into local variables */ + if (argcount > co->co_argcount) { + n = co->co_argcount; + } + else { + n = argcount; + } + for (j = 0; j < n; j++) { + x = args[j]; + Py_INCREF(x); + SETLOCAL(j, x); + } + + /* Pack other positional arguments into the *args argument */ + if (co->co_flags & CO_VARARGS) { + u = _PyTuple_FromArray(args + n, argcount - n); + if (u == NULL) { + goto fail; + } + SETLOCAL(total_args, u); + } + + /* Handle keyword arguments passed as two strided arrays */ + kwcount *= kwstep; + for (i = 0; i < kwcount; i += kwstep) { + PyObject **co_varnames; + PyObject *keyword = kwnames[i]; + PyObject *value = kwargs[i]; + Py_ssize_t j; + + if (keyword == NULL || !PyUnicode_Check(keyword)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U() keywords must be strings", + co->co_name); + goto fail; + } + + /* Speed hack: do raw pointer compares. As names are + normally interned this should almost always hit. */ + co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; + for (j = co->co_posonlyargcount; j < total_args; j++) { + PyObject *name = co_varnames[j]; + if (name == keyword) { + goto kw_found; + } + } + + /* Slow fallback, just in case */ + for (j = co->co_posonlyargcount; j < total_args; j++) { + PyObject *name = co_varnames[j]; + int cmp = PyObject_RichCompareBool( keyword, name, Py_EQ); + if (cmp > 0) { + goto kw_found; + } + else if (cmp < 0) { + goto fail; + } + } + + assert(j >= total_args); + if (kwdict == NULL) { + + if (co->co_posonlyargcount + && positional_only_passed_as_keyword(tstate, co, + kwcount, kwnames)) + { + goto fail; + } + + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got an unexpected keyword argument '%S'", + co->co_name, keyword); + goto fail; + } + + if (PyDict_SetItem(kwdict, keyword, value) == -1) { + goto fail; + } + continue; + + kw_found: + if (GETLOCAL(j) != NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got multiple values for argument '%S'", + co->co_name, keyword); + goto fail; + } + Py_INCREF(value); + SETLOCAL(j, value); + } + + /* Check the number of positional arguments */ + if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) { + too_many_positional(tstate, co, argcount, defcount, fastlocals); + goto fail; + } + + /* Add missing positional arguments (copy default values from defs) */ + if (argcount < co->co_argcount) { + Py_ssize_t m = co->co_argcount - defcount; + Py_ssize_t missing = 0; + for (i = argcount; i < m; i++) { + if (GETLOCAL(i) == NULL) { + missing++; + } + } + if (missing) { + missing_arguments(tstate, co, missing, defcount, fastlocals); + goto fail; + } + if (n > m) + i = n - m; + else + i = 0; + for (; i < defcount; i++) { + if (GETLOCAL(m+i) == NULL) { + PyObject *def = defs[i]; + Py_INCREF(def); + SETLOCAL(m+i, def); + } + } + } + + /* Add missing keyword arguments (copy default values from kwdefs) */ + if (co->co_kwonlyargcount > 0) { + Py_ssize_t missing = 0; + for (i = co->co_argcount; i < total_args; i++) { + PyObject *name; + if (GETLOCAL(i) != NULL) + continue; + name = PyTuple_GET_ITEM(co->co_varnames, i); + if (kwdefs != NULL) { + PyObject *def = PyDict_GetItemWithError(kwdefs, name); + if (def) { + Py_INCREF(def); + SETLOCAL(i, def); + continue; + } + else if (_PyErr_Occurred(tstate)) { + goto fail; + } + } + missing++; + } + if (missing) { + missing_arguments(tstate, co, missing, -1, fastlocals); + goto fail; + } + } + + /* Allocate and initialize storage for cell vars, and copy free + vars into frame. */ + for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) { + PyObject *c; + Py_ssize_t arg; + /* Possibly account for the cell variable being an argument. */ + if (co->co_cell2arg != NULL && + (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) { + c = PyCell_New(GETLOCAL(arg)); + /* Clear the local copy. */ + SETLOCAL(arg, NULL); + } + else { + c = PyCell_New(NULL); + } + if (c == NULL) + goto fail; + SETLOCAL(co->co_nlocals + i, c); + } + + /* Copy closure variables to free variables */ + for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + Py_INCREF(o); + freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; + } + + /* Handle generator/coroutine/asynchronous generator */ + if (co->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { + PyObject *gen; + int is_coro = co->co_flags & CO_COROUTINE; + + /* Don't need to keep the reference to f_back, it will be set + * when the generator is resumed. */ + Py_CLEAR(f->f_back); + + /* Create a new generator that owns the ready to run frame + * and return that as the value. */ + if (is_coro) { + gen = PyCoro_New(f, name, qualname); + } else if (co->co_flags & CO_ASYNC_GENERATOR) { + gen = PyAsyncGen_New(f, name, qualname); + } else { + gen = PyGen_NewWithQualName(f, name, qualname); + } + if (gen == NULL) { + return NULL; + } + + _PyObject_GC_TRACK(f); + + return gen; + } + + retval = PyEval_EvalFrameEx(f,0); + +fail: /* Jump here from prelude on failure */ + + /* decref'ing the frame can cause __del__ methods to get invoked, + which can call back into Python. While we're done with the + current Python frame (f), the associated C stack is still in use, + so recursion_depth must be boosted for the duration. + */ + assert(tstate != NULL); + if (Py_REFCNT(f) > 1) { + Py_DECREF(f); + _PyObject_GC_TRACK(f); + } + else { + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + } + return retval; +} + +PyObject * +PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, + PyObject *const *args, int argcount, + PyObject *const *kws, int kwcount, + PyObject *const *defs, int defcount, + PyObject *kwdefs, PyObject *closure) +{ + return _PyEval_EvalCodeWithName(_co, globals, locals, + args, argcount, + kws, kws != NULL ? kws + 1 : NULL, + kwcount, 2, + defs, defcount, + kwdefs, closure, + NULL, NULL); +} + +static PyObject * +special_lookup(PyThreadState *tstate, PyObject *o, _Py_Identifier *id) +{ + PyObject *res; + res = _PyObject_LookupSpecial(o, id); + if (res == NULL && !_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_AttributeError, id->object); + return NULL; + } + return res; +} + + +/* Logic for the raise statement (too complicated for inlining). + This *consumes* a reference count to each of its arguments. */ +static int +do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) +{ + PyObject *type = NULL, *value = NULL; + + if (exc == NULL) { + /* Reraise */ + _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); + PyObject *tb; + type = exc_info->exc_type; + value = exc_info->exc_value; + tb = exc_info->exc_traceback; + if (type == Py_None || type == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "No active exception to reraise"); + return 0; + } + Py_XINCREF(type); + Py_XINCREF(value); + Py_XINCREF(tb); + _PyErr_Restore(tstate, type, value, tb); + return 1; + } + + /* We support the following forms of raise: + raise + raise + raise */ + + if (PyExceptionClass_Check(exc)) { + type = exc; + value = _PyObject_CallNoArg(exc); + if (value == NULL) + goto raise_error; + if (!PyExceptionInstance_Check(value)) { + _PyErr_Format(tstate, PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto raise_error; + } + } + else if (PyExceptionInstance_Check(exc)) { + value = exc; + type = PyExceptionInstance_Class(exc); + Py_INCREF(type); + } + else { + /* Not something you can raise. You get an exception + anyway, just not what you specified :-) */ + Py_DECREF(exc); + _PyErr_SetString(tstate, PyExc_TypeError, + "exceptions must derive from BaseException"); + goto raise_error; + } + + assert(type != NULL); + assert(value != NULL); + + if (cause) { + PyObject *fixed_cause; + if (PyExceptionClass_Check(cause)) { + fixed_cause = _PyObject_CallNoArg(cause); + if (fixed_cause == NULL) + goto raise_error; + Py_DECREF(cause); + } + else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + } + else if (cause == Py_None) { + Py_DECREF(cause); + fixed_cause = NULL; + } + else { + _PyErr_SetString(tstate, PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto raise_error; + } + PyException_SetCause(value, fixed_cause); + } + + _PyErr_SetObject(tstate, type, value); + /* PyErr_SetObject incref's its arguments */ + Py_DECREF(value); + Py_DECREF(type); + return 0; + +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(cause); + return 0; +} + +/* Iterate v argcnt times and store the results on the stack (via decreasing + sp). Return 1 for success, 0 if error. + + If argcntafter == -1, do a simple unpack. If it is >= 0, do an unpack + with a variable target. +*/ + +static int +unpack_iterable(PyThreadState *tstate, PyObject *v, + int argcnt, int argcntafter, PyObject **sp) +{ + int i = 0, j = 0; + Py_ssize_t ll = 0; + PyObject *it; /* iter(v) */ + PyObject *w; + PyObject *l = NULL; /* variable list */ + + assert(v != NULL); + + it = PyObject_GetIter(v); + if (it == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + v->ob_type->tp_iter == NULL && !PySequence_Check(v)) + { + _PyErr_Format(tstate, PyExc_TypeError, + "cannot unpack non-iterable %.200s object", + v->ob_type->tp_name); + } + return 0; + } + + for (; i < argcnt; i++) { + w = PyIter_Next(it); + if (w == NULL) { + /* Iterator done, via error or exhaustion. */ + if (!_PyErr_Occurred(tstate)) { + if (argcntafter == -1) { + _PyErr_Format(tstate, PyExc_ValueError, + "not enough values to unpack " + "(expected %d, got %d)", + argcnt, i); + } + else { + _PyErr_Format(tstate, PyExc_ValueError, + "not enough values to unpack " + "(expected at least %d, got %d)", + argcnt + argcntafter, i); + } + } + goto Error; + } + *--sp = w; + } + + if (argcntafter == -1) { + /* We better have exhausted the iterator now. */ + w = PyIter_Next(it); + if (w == NULL) { + if (_PyErr_Occurred(tstate)) + goto Error; + Py_DECREF(it); + return 1; + } + Py_DECREF(w); + _PyErr_Format(tstate, PyExc_ValueError, + "too many values to unpack (expected %d)", + argcnt); + goto Error; + } + + l = PySequence_List(it); + if (l == NULL) + goto Error; + *--sp = l; + i++; + + ll = PyList_GET_SIZE(l); + if (ll < argcntafter) { + _PyErr_Format(tstate, PyExc_ValueError, + "not enough values to unpack (expected at least %d, got %zd)", + argcnt + argcntafter, argcnt + ll); + goto Error; + } + + /* Pop the "after-variable" args off the list. */ + for (j = argcntafter; j > 0; j--, i++) { + *--sp = PyList_GET_ITEM(l, ll - j); + } + /* Resize the list. */ + Py_SIZE(l) = ll - argcntafter; + Py_DECREF(it); + return 1; + +Error: + for (; i > 0; i--, sp++) + Py_DECREF(*sp); + Py_XDECREF(it); + return 0; +} + + +#ifdef LLTRACE +static int +prtrace(PyThreadState *tstate, PyObject *v, const char *str) +{ + printf("%s ", str); + if (PyObject_Print(v, stdout, 0) != 0) { + /* Don't know what else to do */ + _PyErr_Clear(tstate); + } + printf("\n"); + return 1; +} +#endif + +static void +call_exc_trace(Py_tracefunc func, PyObject *self, + PyThreadState *tstate, PyFrameObject *f) +{ + PyObject *type, *value, *traceback, *orig_traceback, *arg; + int err; + _PyErr_Fetch(tstate, &type, &value, &orig_traceback); + if (value == NULL) { + value = Py_None; + Py_INCREF(value); + } + _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback); + traceback = (orig_traceback != NULL) ? orig_traceback : Py_None; + arg = PyTuple_Pack(3, type, value, traceback); + if (arg == NULL) { + _PyErr_Restore(tstate, type, value, orig_traceback); + return; + } + err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); + Py_DECREF(arg); + if (err == 0) { + _PyErr_Restore(tstate, type, value, orig_traceback); + } + else { + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(orig_traceback); + } +} + +static int +call_trace_protected(Py_tracefunc func, PyObject *obj, + PyThreadState *tstate, PyFrameObject *frame, + int what, PyObject *arg) +{ + PyObject *type, *value, *traceback; + int err; + _PyErr_Fetch(tstate, &type, &value, &traceback); + err = call_trace(func, obj, tstate, frame, what, arg); + if (err == 0) + { + _PyErr_Restore(tstate, type, value, traceback); + return 0; + } + else { + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + return -1; + } +} + +static int +call_trace(Py_tracefunc func, PyObject *obj, + PyThreadState *tstate, PyFrameObject *frame, + int what, PyObject *arg) +{ + int result; + if (tstate->tracing) + return 0; + tstate->tracing++; + tstate->use_tracing = 0; + result = func(obj, frame, what, arg); + tstate->use_tracing = ((tstate->c_tracefunc != NULL) + || (tstate->c_profilefunc != NULL)); + tstate->tracing--; + return result; +} + +PyObject * +_PyEval_CallTracing(PyObject *func, PyObject *args) +{ + PyThreadState *tstate = _PyThreadState_GET(); + int save_tracing = tstate->tracing; + int save_use_tracing = tstate->use_tracing; + PyObject *result; + + tstate->tracing = 0; + tstate->use_tracing = ((tstate->c_tracefunc != NULL) + || (tstate->c_profilefunc != NULL)); + result = PyObject_Call(func, args, NULL); + tstate->tracing = save_tracing; + tstate->use_tracing = save_use_tracing; + return result; +} + +/* See Objects/lnotab_notes.txt for a description of how tracing works. */ +static int +maybe_call_line_trace(Py_tracefunc func, PyObject *obj, + PyThreadState *tstate, PyFrameObject *frame, + int *instr_lb, int *instr_ub, int *instr_prev) +{ + int result = 0; + int line = frame->f_lineno; + + /* If the last instruction executed isn't in the current + instruction window, reset the window. + */ + if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) { + PyAddrPair bounds; + line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti, + &bounds); + *instr_lb = bounds.ap_lower; + *instr_ub = bounds.ap_upper; + } + /* If the last instruction falls at the start of a line or if it + represents a jump backwards, update the frame's line number and + then call the trace function if we're tracing source lines. + */ + if ((frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev)) { + frame->f_lineno = line; + if (frame->f_trace_lines) { + result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); + } + } + /* Always emit an opcode event if we're tracing all opcodes. */ + if (frame->f_trace_opcodes) { + result = call_trace(func, obj, tstate, frame, PyTrace_OPCODE, Py_None); + } + *instr_prev = frame->f_lasti; + return result; +} + +void +PyEval_SetProfile(Py_tracefunc func, PyObject *arg) +{ + if (PySys_Audit("sys.setprofile", NULL) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetProfile", NULL); + return; + } + + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *temp = tstate->c_profileobj; + Py_XINCREF(arg); + tstate->c_profilefunc = NULL; + tstate->c_profileobj = NULL; + /* Must make sure that tracing is not ignored if 'temp' is freed */ + tstate->use_tracing = tstate->c_tracefunc != NULL; + Py_XDECREF(temp); + tstate->c_profilefunc = func; + tstate->c_profileobj = arg; + /* Flag that tracing or profiling is turned on */ + tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL); +} + +void +PyEval_SetTrace(Py_tracefunc func, PyObject *arg) +{ + if (PySys_Audit("sys.settrace", NULL) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetTrace", NULL); + return; + } + + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyObject *temp = tstate->c_traceobj; + runtime->ceval.tracing_possible += (func != NULL) - (tstate->c_tracefunc != NULL); + Py_XINCREF(arg); + tstate->c_tracefunc = NULL; + tstate->c_traceobj = NULL; + /* Must make sure that profiling is not ignored if 'temp' is freed */ + tstate->use_tracing = tstate->c_profilefunc != NULL; + Py_XDECREF(temp); + tstate->c_tracefunc = func; + tstate->c_traceobj = arg; + /* Flag that tracing or profiling is turned on */ + tstate->use_tracing = ((func != NULL) + || (tstate->c_profilefunc != NULL)); +} + +void +_PyEval_SetCoroutineOriginTrackingDepth(int new_depth) +{ + assert(new_depth >= 0); + PyThreadState *tstate = _PyThreadState_GET(); + tstate->coroutine_origin_tracking_depth = new_depth; +} + +int +_PyEval_GetCoroutineOriginTrackingDepth(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return tstate->coroutine_origin_tracking_depth; +} + +PyObject * +_PyEval_GetAsyncGenFirstiter(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return tstate->async_gen_firstiter; +} + +PyObject * +_PyEval_GetAsyncGenFinalizer(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return tstate->async_gen_finalizer; +} + +static PyFrameObject * +_PyEval_GetFrame(PyThreadState *tstate) +{ + return _PyRuntime.gilstate.getframe(tstate); +} + +PyFrameObject * +PyEval_GetFrame(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_GetFrame(tstate); +} + +PyObject * +PyEval_GetBuiltins(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); + if (current_frame == NULL) + return tstate->interp->builtins; + else + return current_frame->f_builtins; +} + +/* Convenience function to get a builtin from its name */ +PyObject * +_PyEval_GetBuiltinId(_Py_Identifier *name) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name); + if (attr) { + Py_INCREF(attr); + } + else if (!_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(name)); + } + return attr; +} + +PyObject * +PyEval_GetLocals(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); + if (current_frame == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); + return NULL; + } + + if (PyFrame_FastToLocalsWithError(current_frame) < 0) { + return NULL; + } + + assert(current_frame->f_locals != NULL); + return current_frame->f_locals; +} + +PyObject * +PyEval_GetGlobals(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); + if (current_frame == NULL) { + return NULL; + } + + assert(current_frame->f_globals != NULL); + return current_frame->f_globals; +} + +int +PyEval_MergeCompilerFlags(PyCompilerFlags *cf) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); + int result = cf->cf_flags != 0; + + if (current_frame != NULL) { + const int codeflags = current_frame->f_code->co_flags; + const int compilerflags = codeflags & PyCF_MASK; + if (compilerflags) { + result = 1; + cf->cf_flags |= compilerflags; + } +#if 0 /* future keyword */ + if (codeflags & CO_GENERATOR_ALLOWED) { + result = 1; + cf->cf_flags |= CO_GENERATOR_ALLOWED; + } +#endif + } + return result; +} + + +const char * +PyEval_GetFuncName(PyObject *func) +{ + if (PyMethod_Check(func)) + return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func)); + else if (PyFunction_Check(func)) + return PyUnicode_AsUTF8(((PyFunctionObject*)func)->func_name); + else if (PyCFunction_Check(func)) + return ((PyCFunctionObject*)func)->m_ml->ml_name; + else + return func->ob_type->tp_name; +} + +const char * +PyEval_GetFuncDesc(PyObject *func) +{ + if (PyMethod_Check(func)) + return "()"; + else if (PyFunction_Check(func)) + return "()"; + else if (PyCFunction_Check(func)) + return "()"; + else + return " object"; +} + +#define C_TRACE(x, call) \ +if (tstate->use_tracing && tstate->c_profilefunc) { \ + if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \ + tstate, tstate->frame, \ + PyTrace_C_CALL, func)) { \ + x = NULL; \ + } \ + else { \ + x = call; \ + if (tstate->c_profilefunc != NULL) { \ + if (x == NULL) { \ + call_trace_protected(tstate->c_profilefunc, \ + tstate->c_profileobj, \ + tstate, tstate->frame, \ + PyTrace_C_EXCEPTION, func); \ + /* XXX should pass (type, value, tb) */ \ + } else { \ + if (call_trace(tstate->c_profilefunc, \ + tstate->c_profileobj, \ + tstate, tstate->frame, \ + PyTrace_C_RETURN, func)) { \ + Py_DECREF(x); \ + x = NULL; \ + } \ + } \ + } \ + } \ +} else { \ + x = call; \ + } + + +static PyObject * +trace_call_function(PyThreadState *tstate, + PyObject *func, + PyObject **args, Py_ssize_t nargs, + PyObject *kwnames) +{ + PyObject *x; + if (PyCFunction_Check(func)) { + C_TRACE(x, _PyObject_Vectorcall(func, args, nargs, kwnames)); + return x; + } + else if (Py_TYPE(func) == &PyMethodDescr_Type && nargs > 0) { + /* We need to create a temporary bound method as argument + for profiling. + + If nargs == 0, then this cannot work because we have no + "self". In any case, the call itself would raise + TypeError (foo needs an argument), so we just skip + profiling. */ + PyObject *self = args[0]; + func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); + if (func == NULL) { + return NULL; + } + C_TRACE(x, _PyObject_Vectorcall(func, + args+1, nargs-1, + kwnames)); + Py_DECREF(func); + return x; + } + return _PyObject_Vectorcall(func, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); +} + +/* Issue #29227: Inline call_function() into _PyEval_EvalFrameDefault() + to reduce the stack consumption. */ +Py_LOCAL_INLINE(PyObject *) _Py_HOT_FUNCTION +call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames) +{ + PyObject **pfunc = (*pp_stack) - oparg - 1; + PyObject *func = *pfunc; + PyObject *x, *w; + Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); + Py_ssize_t nargs = oparg - nkwargs; + PyObject **stack = (*pp_stack) - nargs - nkwargs; + + if (tstate->use_tracing) { + x = trace_call_function(tstate, func, stack, nargs, kwnames); + } + else { + x = _PyObject_Vectorcall(func, stack, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); + } + + assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + /* Clear the stack of the function object. */ + while ((*pp_stack) > pfunc) { + w = EXT_POP(*pp_stack); + Py_DECREF(w); + } + + return x; +} + +static PyObject * +do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject *kwdict) +{ + PyObject *result; + + if (PyCFunction_Check(func)) { + C_TRACE(result, PyCFunction_Call(func, callargs, kwdict)); + return result; + } + else if (Py_TYPE(func) == &PyMethodDescr_Type) { + Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); + if (nargs > 0 && tstate->use_tracing) { + /* We need to create a temporary bound method as argument + for profiling. + + If nargs == 0, then this cannot work because we have no + "self". In any case, the call itself would raise + TypeError (foo needs an argument), so we just skip + profiling. */ + PyObject *self = PyTuple_GET_ITEM(callargs, 0); + func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); + if (func == NULL) { + return NULL; + } + + C_TRACE(result, _PyObject_FastCallDict(func, + &_PyTuple_ITEMS(callargs)[1], + nargs - 1, + kwdict)); + Py_DECREF(func); + return result; + } + } + return PyObject_Call(func, callargs, kwdict); +} + +/* Extract a slice index from a PyLong or an object with the + nb_index slot defined, and store in *pi. + Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, + and silently boost values less than PY_SSIZE_T_MIN to PY_SSIZE_T_MIN. + Return 0 on error, 1 on success. +*/ +int +_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (v != Py_None) { + Py_ssize_t x; + if (PyIndex_Check(v)) { + x = PyNumber_AsSsize_t(v, NULL); + if (x == -1 && _PyErr_Occurred(tstate)) + return 0; + } + else { + _PyErr_SetString(tstate, PyExc_TypeError, + "slice indices must be integers or " + "None or have an __index__ method"); + return 0; + } + *pi = x; + } + return 1; +} + +int +_PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) +{ + PyThreadState *tstate = _PyThreadState_GET(); + Py_ssize_t x; + if (PyIndex_Check(v)) { + x = PyNumber_AsSsize_t(v, NULL); + if (x == -1 && _PyErr_Occurred(tstate)) + return 0; + } + else { + _PyErr_SetString(tstate, PyExc_TypeError, + "slice indices must be integers or " + "have an __index__ method"); + return 0; + } + *pi = x; + return 1; +} + + +#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ + "BaseException is not allowed" + +static PyObject * +cmp_outcome(PyThreadState *tstate, int op, PyObject *v, PyObject *w) +{ + int res = 0; + switch (op) { + case PyCmp_IS: + res = (v == w); + break; + case PyCmp_IS_NOT: + res = (v != w); + break; + case PyCmp_IN: + res = PySequence_Contains(w, v); + if (res < 0) + return NULL; + break; + case PyCmp_NOT_IN: + res = PySequence_Contains(w, v); + if (res < 0) + return NULL; + res = !res; + break; + case PyCmp_EXC_MATCH: + if (PyTuple_Check(w)) { + Py_ssize_t i, length; + length = PyTuple_Size(w); + for (i = 0; i < length; i += 1) { + PyObject *exc = PyTuple_GET_ITEM(w, i); + if (!PyExceptionClass_Check(exc)) { + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); + return NULL; + } + } + } + else { + if (!PyExceptionClass_Check(w)) { + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); + return NULL; + } + } + res = PyErr_GivenExceptionMatches(v, w); + break; + default: + return PyObject_RichCompare(v, w, op); + } + v = res ? Py_True : Py_False; + Py_INCREF(v); + return v; +} + +static PyObject * +import_name(PyThreadState *tstate, PyFrameObject *f, + PyObject *name, PyObject *fromlist, PyObject *level) +{ + _Py_IDENTIFIER(__import__); + PyObject *import_func, *res; + PyObject* stack[5]; + + import_func = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___import__); + if (import_func == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found"); + } + return NULL; + } + + /* Fast path for not overloaded __import__. */ + if (import_func == tstate->interp->import_func) { + int ilevel = _PyLong_AsInt(level); + if (ilevel == -1 && _PyErr_Occurred(tstate)) { + return NULL; + } + res = PyImport_ImportModuleLevelObject( + name, + f->f_globals, + f->f_locals == NULL ? Py_None : f->f_locals, + fromlist, + ilevel); + return res; + } + + Py_INCREF(import_func); + + stack[0] = name; + stack[1] = f->f_globals; + stack[2] = f->f_locals == NULL ? Py_None : f->f_locals; + stack[3] = fromlist; + stack[4] = level; + res = _PyObject_FastCall(import_func, stack, 5); + Py_DECREF(import_func); + return res; +} + +static PyObject * +import_from(PyThreadState *tstate, PyObject *v, PyObject *name) +{ + PyObject *x; + _Py_IDENTIFIER(__name__); + PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg; + + if (_PyObject_LookupAttr(v, name, &x) != 0) { + return x; + } + /* Issue #17636: in case this failed because of a circular relative + import, try to fallback on reading the module directly from + sys.modules. */ + pkgname = _PyObject_GetAttrId(v, &PyId___name__); + if (pkgname == NULL) { + goto error; + } + if (!PyUnicode_Check(pkgname)) { + Py_CLEAR(pkgname); + goto error; + } + fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name); + if (fullmodname == NULL) { + Py_DECREF(pkgname); + return NULL; + } + x = PyImport_GetModule(fullmodname); + Py_DECREF(fullmodname); + if (x == NULL && !_PyErr_Occurred(tstate)) { + goto error; + } + Py_DECREF(pkgname); + return x; + error: + pkgpath = PyModule_GetFilenameObject(v); + if (pkgname == NULL) { + pkgname_or_unknown = PyUnicode_FromString(""); + if (pkgname_or_unknown == NULL) { + Py_XDECREF(pkgpath); + return NULL; + } + } else { + pkgname_or_unknown = pkgname; + } + + if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) { + _PyErr_Clear(tstate); + errmsg = PyUnicode_FromFormat( + "cannot import name %R from %R (unknown location)", + name, pkgname_or_unknown + ); + /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ + PyErr_SetImportError(errmsg, pkgname, NULL); + } + else { + _Py_IDENTIFIER(__spec__); + PyObject *spec = _PyObject_GetAttrId(v, &PyId___spec__); + const char *fmt = + _PyModuleSpec_IsInitializing(spec) ? + "cannot import name %R from partially initialized module %R " + "(most likely due to a circular import) (%S)" : + "cannot import name %R from %R (%S)"; + Py_XDECREF(spec); + + errmsg = PyUnicode_FromFormat(fmt, name, pkgname_or_unknown, pkgpath); + /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ + PyErr_SetImportError(errmsg, pkgname, pkgpath); + } + + Py_XDECREF(errmsg); + Py_XDECREF(pkgname_or_unknown); + Py_XDECREF(pkgpath); + return NULL; +} + +static int +import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) +{ + _Py_IDENTIFIER(__all__); + _Py_IDENTIFIER(__dict__); + _Py_IDENTIFIER(__name__); + PyObject *all, *dict, *name, *value; + int skip_leading_underscores = 0; + int pos, err; + + if (_PyObject_LookupAttrId(v, &PyId___all__, &all) < 0) { + return -1; /* Unexpected error */ + } + if (all == NULL) { + if (_PyObject_LookupAttrId(v, &PyId___dict__, &dict) < 0) { + return -1; + } + if (dict == NULL) { + _PyErr_SetString(tstate, PyExc_ImportError, + "from-import-* object has no __dict__ and no __all__"); + return -1; + } + all = PyMapping_Keys(dict); + Py_DECREF(dict); + if (all == NULL) + return -1; + skip_leading_underscores = 1; + } + + for (pos = 0, err = 0; ; pos++) { + name = PySequence_GetItem(all, pos); + if (name == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { + err = -1; + } + else { + _PyErr_Clear(tstate); + } + break; + } + if (!PyUnicode_Check(name)) { + PyObject *modname = _PyObject_GetAttrId(v, &PyId___name__); + if (modname == NULL) { + Py_DECREF(name); + err = -1; + break; + } + if (!PyUnicode_Check(modname)) { + _PyErr_Format(tstate, PyExc_TypeError, + "module __name__ must be a string, not %.100s", + Py_TYPE(modname)->tp_name); + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "%s in %U.%s must be str, not %.100s", + skip_leading_underscores ? "Key" : "Item", + modname, + skip_leading_underscores ? "__dict__" : "__all__", + Py_TYPE(name)->tp_name); + } + Py_DECREF(modname); + Py_DECREF(name); + err = -1; + break; + } + if (skip_leading_underscores) { + if (PyUnicode_READY(name) == -1) { + Py_DECREF(name); + err = -1; + break; + } + if (PyUnicode_READ_CHAR(name, 0) == '_') { + Py_DECREF(name); + continue; + } + } + value = PyObject_GetAttr(v, name); + if (value == NULL) + err = -1; + else if (PyDict_CheckExact(locals)) + err = PyDict_SetItem(locals, name, value); + else + err = PyObject_SetItem(locals, name, value); + Py_DECREF(name); + Py_XDECREF(value); + if (err != 0) + break; + } + Py_DECREF(all); + return err; +} + +static int +check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args) +{ + if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s argument after * " + "must be an iterable, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + args->ob_type->tp_name); + return -1; + } + return 0; +} + +static void +format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) +{ + /* _PyDict_MergeEx raises attribute + * error (percolated from an attempt + * to get 'keys' attribute) instead of + * a type error if its second argument + * is not a mapping. + */ + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + kwargs->ob_type->tp_name); + } + else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { + PyObject *key = PyTuple_GET_ITEM(val, 0); + if (!PyUnicode_Check(key)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s keywords must be strings", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func)); + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s got multiple " + "values for keyword argument '%U'", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + key); + } + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); + } + else { + _PyErr_Restore(tstate, exc, val, tb); + } + } +} + +static void +format_exc_check_arg(PyThreadState *tstate, PyObject *exc, + const char *format_str, PyObject *obj) +{ + const char *obj_str; + + if (!obj) + return; + + obj_str = PyUnicode_AsUTF8(obj); + if (!obj_str) + return; + + _PyErr_Format(tstate, exc, format_str, obj_str); +} + +static void +format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) +{ + PyObject *name; + /* Don't stomp existing exception */ + if (_PyErr_Occurred(tstate)) + return; + if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) { + name = PyTuple_GET_ITEM(co->co_cellvars, + oparg); + format_exc_check_arg(tstate, + PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, + name); + } else { + name = PyTuple_GET_ITEM(co->co_freevars, oparg - + PyTuple_GET_SIZE(co->co_cellvars)); + format_exc_check_arg(tstate, PyExc_NameError, + UNBOUNDFREE_ERROR_MSG, name); + } +} + +static void +format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevopcode) +{ + if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { + if (prevopcode == BEFORE_ASYNC_WITH) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async with' received an object from __aenter__ " + "that does not implement __await__: %.100s", + type->tp_name); + } + else if (prevopcode == WITH_CLEANUP_START) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async with' received an object from __aexit__ " + "that does not implement __await__: %.100s", + type->tp_name); + } + } +} + +static PyObject * +unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w, + PyFrameObject *f, const _Py_CODEUNIT *next_instr) +{ + PyObject *res; + if (Py_REFCNT(v) == 2) { + /* In the common case, there are 2 references to the value + * stored in 'variable' when the += is performed: one on the + * value stack (in 'v') and one still stored in the + * 'variable'. We try to delete the variable now to reduce + * the refcnt to 1. + */ + int opcode, oparg; + NEXTOPARG(); + switch (opcode) { + case STORE_FAST: + { + PyObject **fastlocals = f->f_localsplus; + if (GETLOCAL(oparg) == v) + SETLOCAL(oparg, NULL); + break; + } + case STORE_DEREF: + { + PyObject **freevars = (f->f_localsplus + + f->f_code->co_nlocals); + PyObject *c = freevars[oparg]; + if (PyCell_GET(c) == v) { + PyCell_SET(c, NULL); + Py_DECREF(v); + } + break; + } + case STORE_NAME: + { + PyObject *names = f->f_code->co_names; + PyObject *name = GETITEM(names, oparg); + PyObject *locals = f->f_locals; + if (locals && PyDict_CheckExact(locals)) { + PyObject *w = PyDict_GetItemWithError(locals, name); + if ((w == v && PyDict_DelItem(locals, name) != 0) || + (w == NULL && _PyErr_Occurred(tstate))) + { + Py_DECREF(v); + return NULL; + } + } + break; + } + } + } + res = v; + PyUnicode_Append(&res, w); + return res; +} + +#ifdef DYNAMIC_EXECUTION_PROFILE + +static PyObject * +getarray(long a[256]) +{ + int i; + PyObject *l = PyList_New(256); + if (l == NULL) return NULL; + for (i = 0; i < 256; i++) { + PyObject *x = PyLong_FromLong(a[i]); + if (x == NULL) { + Py_DECREF(l); + return NULL; + } + PyList_SET_ITEM(l, i, x); + } + for (i = 0; i < 256; i++) + a[i] = 0; + return l; +} + +PyObject * +_Py_GetDXProfile(PyObject *self, PyObject *args) +{ +#ifndef DXPAIRS + return getarray(dxp); +#else + int i; + PyObject *l = PyList_New(257); + if (l == NULL) return NULL; + for (i = 0; i < 257; i++) { + PyObject *x = getarray(dxpairs[i]); + if (x == NULL) { + Py_DECREF(l); + return NULL; + } + PyList_SET_ITEM(l, i, x); + } + return l; +#endif +} + +#endif + +Py_ssize_t +_PyEval_RequestCodeExtraIndex(freefunc free) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + Py_ssize_t new_index; + + if (interp->co_extra_user_count == MAX_CO_EXTRA_USERS - 1) { + return -1; + } + new_index = interp->co_extra_user_count++; + interp->co_extra_freefuncs[new_index] = free; + return new_index; +} + +static void +dtrace_function_entry(PyFrameObject *f) +{ + const char *filename; + const char *funcname; + int lineno; + + filename = PyUnicode_AsUTF8(f->f_code->co_filename); + funcname = PyUnicode_AsUTF8(f->f_code->co_name); + lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); + + PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); +} + +static void +dtrace_function_return(PyFrameObject *f) +{ + const char *filename; + const char *funcname; + int lineno; + + filename = PyUnicode_AsUTF8(f->f_code->co_filename); + funcname = PyUnicode_AsUTF8(f->f_code->co_name); + lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); + + PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); +} + +/* DTrace equivalent of maybe_call_line_trace. */ +static void +maybe_dtrace_line(PyFrameObject *frame, + int *instr_lb, int *instr_ub, int *instr_prev) +{ + int line = frame->f_lineno; + const char *co_filename, *co_name; + + /* If the last instruction executed isn't in the current + instruction window, reset the window. + */ + if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) { + PyAddrPair bounds; + line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti, + &bounds); + *instr_lb = bounds.ap_lower; + *instr_ub = bounds.ap_upper; + } + /* If the last instruction falls at the start of a line or if + it represents a jump backwards, update the frame's line + number and call the trace function. */ + if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) { + frame->f_lineno = line; + co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename); + if (!co_filename) + co_filename = "?"; + co_name = PyUnicode_AsUTF8(frame->f_code->co_name); + if (!co_name) + co_name = "?"; + PyDTrace_LINE(co_filename, co_name, line); + } + *instr_prev = frame->f_lasti; +} diff --git a/python/Python/ceval_gil.h b/python/Python/ceval_gil.h new file mode 100755 index 0000000..96794df --- /dev/null +++ b/python/Python/ceval_gil.h @@ -0,0 +1,254 @@ +/* + * Implementation of the Global Interpreter Lock (GIL). + */ + +#include +#include + +#include "pycore_atomic.h" + + +/* + Notes about the implementation: + + - The GIL is just a boolean variable (locked) whose access is protected + by a mutex (gil_mutex), and whose changes are signalled by a condition + variable (gil_cond). gil_mutex is taken for short periods of time, + and therefore mostly uncontended. + + - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be + able to release the GIL on demand by another thread. A volatile boolean + variable (gil_drop_request) is used for that purpose, which is checked + at every turn of the eval loop. That variable is set after a wait of + `interval` microseconds on `gil_cond` has timed out. + + [Actually, another volatile boolean variable (eval_breaker) is used + which ORs several conditions into one. Volatile booleans are + sufficient as inter-thread signalling means since Python is run + on cache-coherent architectures only.] + + - A thread wanting to take the GIL will first let pass a given amount of + time (`interval` microseconds) before setting gil_drop_request. This + encourages a defined switching period, but doesn't enforce it since + opcodes can take an arbitrary time to execute. + + The `interval` value is available for the user to read and modify + using the Python API `sys.{get,set}switchinterval()`. + + - When a thread releases the GIL and gil_drop_request is set, that thread + ensures that another GIL-awaiting thread gets scheduled. + It does so by waiting on a condition variable (switch_cond) until + the value of last_holder is changed to something else than its + own thread state pointer, indicating that another thread was able to + take the GIL. + + This is meant to prohibit the latency-adverse behaviour on multi-core + machines where one thread would speculatively release the GIL, but still + run and end up being the first to re-acquire it, making the "timeslices" + much longer than expected. + (Note: this mechanism is enabled with FORCE_SWITCHING above) +*/ + +#include "condvar.h" + +#define MUTEX_INIT(mut) \ + if (PyMUTEX_INIT(&(mut))) { \ + Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; +#define MUTEX_FINI(mut) \ + if (PyMUTEX_FINI(&(mut))) { \ + Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; +#define CX_MUTEX_LOCK(mut) \ + if (PyMUTEX_LOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; +#define MUTEX_UNLOCK(mut) \ + if (PyMUTEX_UNLOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; + +#define COND_INIT(cond) \ + if (PyCOND_INIT(&(cond))) { \ + Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; +#define COND_FINI(cond) \ + if (PyCOND_FINI(&(cond))) { \ + Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; +#define COND_SIGNAL(cond) \ + if (PyCOND_SIGNAL(&(cond))) { \ + Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; +#define COND_WAIT(cond, mut) \ + if (PyCOND_WAIT(&(cond), &(mut))) { \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ + { \ + int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ + if (r < 0) \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ + if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ + timeout_result = 1; \ + else \ + timeout_result = 0; \ + } \ + + +#define DEFAULT_INTERVAL 5000 + +static void _gil_initialize(struct _gil_runtime_state *gil) +{ + _Py_atomic_int uninitialized = {-1}; + gil->locked = uninitialized; + gil->interval = DEFAULT_INTERVAL; +} + +static int gil_created(struct _gil_runtime_state *gil) +{ + return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); +} + +static void create_gil(struct _gil_runtime_state *gil) +{ + MUTEX_INIT(gil->mutex); +#ifdef FORCE_SWITCHING + MUTEX_INIT(gil->switch_mutex); +#endif + COND_INIT(gil->cond); +#ifdef FORCE_SWITCHING + COND_INIT(gil->switch_cond); +#endif + _Py_atomic_store_relaxed(&gil->last_holder, 0); + _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); + _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); +} + +static void destroy_gil(struct _gil_runtime_state *gil) +{ + /* some pthread-like implementations tie the mutex to the cond + * and must have the cond destroyed first. + */ + COND_FINI(gil->cond); + MUTEX_FINI(gil->mutex); +#ifdef FORCE_SWITCHING + COND_FINI(gil->switch_cond); + MUTEX_FINI(gil->switch_mutex); +#endif + _Py_atomic_store_explicit(&gil->locked, -1, + _Py_memory_order_release); + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); +} + +static void recreate_gil(struct _gil_runtime_state *gil) +{ + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); + /* XXX should we destroy the old OS resources here? */ + create_gil(gil); +} + +static void +drop_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) +{ + struct _gil_runtime_state *gil = &ceval->gil; + if (!_Py_atomic_load_relaxed(&gil->locked)) { + Py_FatalError("drop_gil: GIL is not locked"); + } + + /* tstate is allowed to be NULL (early interpreter init) */ + if (tstate != NULL) { + /* Sub-interpreter support: threads might have been switched + under our feet using PyThreadState_Swap(). Fix the GIL last + holder variable so that our heuristics work. */ + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + } + + CX_MUTEX_LOCK(gil->mutex); + _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); + _Py_atomic_store_relaxed(&gil->locked, 0); + COND_SIGNAL(gil->cond); + MUTEX_UNLOCK(gil->mutex); + +#ifdef FORCE_SWITCHING + if (_Py_atomic_load_relaxed(&ceval->gil_drop_request) && tstate != NULL) { + CX_MUTEX_LOCK(gil->switch_mutex); + /* Not switched yet => wait */ + if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) + { + RESET_GIL_DROP_REQUEST(ceval); + /* NOTE: if COND_WAIT does not atomically start waiting when + releasing the mutex, another thread can run through, take + the GIL and drop it again, and reset the condition + before we even had a chance to wait for it. */ + COND_WAIT(gil->switch_cond, gil->switch_mutex); + } + MUTEX_UNLOCK(gil->switch_mutex); + } +#endif +} + +static void +take_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) +{ + if (tstate == NULL) { + Py_FatalError("take_gil: NULL tstate"); + } + + struct _gil_runtime_state *gil = &ceval->gil; + int err = errno; + CX_MUTEX_LOCK(gil->mutex); + + if (!_Py_atomic_load_relaxed(&gil->locked)) { + goto _ready; + } + + while (_Py_atomic_load_relaxed(&gil->locked)) { + int timed_out = 0; + unsigned long saved_switchnum; + + saved_switchnum = gil->switch_number; + + + unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); + COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); + /* If we timed out and no switch occurred in the meantime, it is time + to ask the GIL-holding thread to drop it. */ + if (timed_out && + _Py_atomic_load_relaxed(&gil->locked) && + gil->switch_number == saved_switchnum) + { + SET_GIL_DROP_REQUEST(ceval); + } + } +_ready: +#ifdef FORCE_SWITCHING + /* This mutex must be taken before modifying gil->last_holder: + see drop_gil(). */ + CX_MUTEX_LOCK(gil->switch_mutex); +#endif + /* We now hold the GIL */ + _Py_atomic_store_relaxed(&gil->locked, 1); + _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); + + if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + ++gil->switch_number; + } + +#ifdef FORCE_SWITCHING + COND_SIGNAL(gil->switch_cond); + MUTEX_UNLOCK(gil->switch_mutex); +#endif + if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { + RESET_GIL_DROP_REQUEST(ceval); + } + if (tstate->async_exc != NULL) { + _PyEval_SignalAsyncExc(ceval); + } + + MUTEX_UNLOCK(gil->mutex); + errno = err; +} + +void _PyEval_SetSwitchInterval(unsigned long microseconds) +{ + _PyRuntime.ceval.gil.interval = microseconds; +} + +unsigned long _PyEval_GetSwitchInterval() +{ + return _PyRuntime.ceval.gil.interval; +} diff --git a/python/Python/clinic/_warnings.c.h b/python/Python/clinic/_warnings.c.h new file mode 100755 index 0000000..67ab0e3 --- /dev/null +++ b/python/Python/clinic/_warnings.c.h @@ -0,0 +1,74 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(warnings_warn__doc__, +"warn($module, /, message, category=None, stacklevel=1, source=None)\n" +"--\n" +"\n" +"Issue a warning, or maybe ignore it or raise an exception."); + +#define WARNINGS_WARN_METHODDEF \ + {"warn", (PyCFunction)(void(*)(void))warnings_warn, METH_FASTCALL|METH_KEYWORDS, warnings_warn__doc__}, + +static PyObject * +warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, + Py_ssize_t stacklevel, PyObject *source); + +static PyObject * +warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "warn", 0}; + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *message; + PyObject *category = Py_None; + Py_ssize_t stacklevel = 1; + PyObject *source = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); + if (!args) { + goto exit; + } + message = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + category = args[1]; + 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; + } + { + 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; + } + stacklevel = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + source = args[3]; +skip_optional_pos: + return_value = warnings_warn_impl(module, message, category, stacklevel, source); + +exit: + return return_value; +} +/*[clinic end generated code: output=b7bb54c73b5433ec input=a9049054013a1b77]*/ diff --git a/python/Python/clinic/bltinmodule.c.h b/python/Python/clinic/bltinmodule.c.h new file mode 100755 index 0000000..d15af1f --- /dev/null +++ b/python/Python/clinic/bltinmodule.c.h @@ -0,0 +1,858 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_abs__doc__, +"abs($module, x, /)\n" +"--\n" +"\n" +"Return the absolute value of the argument."); + +#define BUILTIN_ABS_METHODDEF \ + {"abs", (PyCFunction)builtin_abs, METH_O, builtin_abs__doc__}, + +PyDoc_STRVAR(builtin_all__doc__, +"all($module, iterable, /)\n" +"--\n" +"\n" +"Return True if bool(x) is True for all values x in the iterable.\n" +"\n" +"If the iterable is empty, return True."); + +#define BUILTIN_ALL_METHODDEF \ + {"all", (PyCFunction)builtin_all, METH_O, builtin_all__doc__}, + +PyDoc_STRVAR(builtin_any__doc__, +"any($module, iterable, /)\n" +"--\n" +"\n" +"Return True if bool(x) is True for any x in the iterable.\n" +"\n" +"If the iterable is empty, return False."); + +#define BUILTIN_ANY_METHODDEF \ + {"any", (PyCFunction)builtin_any, METH_O, builtin_any__doc__}, + +PyDoc_STRVAR(builtin_ascii__doc__, +"ascii($module, obj, /)\n" +"--\n" +"\n" +"Return an ASCII-only representation of an object.\n" +"\n" +"As repr(), return a string containing a printable representation of an\n" +"object, but escape the non-ASCII characters in the string returned by\n" +"repr() using \\\\x, \\\\u or \\\\U escapes. This generates a string similar\n" +"to that returned by repr() in Python 2."); + +#define BUILTIN_ASCII_METHODDEF \ + {"ascii", (PyCFunction)builtin_ascii, METH_O, builtin_ascii__doc__}, + +PyDoc_STRVAR(builtin_bin__doc__, +"bin($module, number, /)\n" +"--\n" +"\n" +"Return the binary representation of an integer.\n" +"\n" +" >>> bin(2796202)\n" +" \'0b1010101010101010101010\'"); + +#define BUILTIN_BIN_METHODDEF \ + {"bin", (PyCFunction)builtin_bin, METH_O, builtin_bin__doc__}, + +PyDoc_STRVAR(builtin_callable__doc__, +"callable($module, obj, /)\n" +"--\n" +"\n" +"Return whether the object is callable (i.e., some kind of function).\n" +"\n" +"Note that classes are callable, as are instances of classes with a\n" +"__call__() method."); + +#define BUILTIN_CALLABLE_METHODDEF \ + {"callable", (PyCFunction)builtin_callable, METH_O, builtin_callable__doc__}, + +PyDoc_STRVAR(builtin_format__doc__, +"format($module, value, format_spec=\'\', /)\n" +"--\n" +"\n" +"Return value.__format__(format_spec)\n" +"\n" +"format_spec defaults to the empty string.\n" +"See the Format Specification Mini-Language section of help(\'FORMATTING\') for\n" +"details."); + +#define BUILTIN_FORMAT_METHODDEF \ + {"format", (PyCFunction)(void(*)(void))builtin_format, METH_FASTCALL, builtin_format__doc__}, + +static PyObject * +builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec); + +static PyObject * +builtin_format(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *value; + PyObject *format_spec = NULL; + + if (!_PyArg_CheckPositional("format", nargs, 1, 2)) { + goto exit; + } + value = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("format", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + format_spec = args[1]; +skip_optional: + return_value = builtin_format_impl(module, value, format_spec); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_chr__doc__, +"chr($module, i, /)\n" +"--\n" +"\n" +"Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff."); + +#define BUILTIN_CHR_METHODDEF \ + {"chr", (PyCFunction)builtin_chr, METH_O, builtin_chr__doc__}, + +static PyObject * +builtin_chr_impl(PyObject *module, int i); + +static PyObject * +builtin_chr(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int i; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + i = _PyLong_AsInt(arg); + if (i == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = builtin_chr_impl(module, i); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_compile__doc__, +"compile($module, /, source, filename, mode, flags=0,\n" +" dont_inherit=False, optimize=-1, *, _feature_version=-1)\n" +"--\n" +"\n" +"Compile source into a code object that can be executed by exec() or eval().\n" +"\n" +"The source code may represent a Python module, statement or expression.\n" +"The filename will be used for run-time error messages.\n" +"The mode must be \'exec\' to compile a module, \'single\' to compile a\n" +"single (interactive) statement, or \'eval\' to compile an expression.\n" +"The flags argument, if present, controls which future statements influence\n" +"the compilation of the code.\n" +"The dont_inherit argument, if true, stops the compilation inheriting\n" +"the effects of any future statements in effect in the code calling\n" +"compile; if absent or false these statements do influence the compilation,\n" +"in addition to any features explicitly specified."); + +#define BUILTIN_COMPILE_METHODDEF \ + {"compile", (PyCFunction)(void(*)(void))builtin_compile, METH_FASTCALL|METH_KEYWORDS, builtin_compile__doc__}, + +static PyObject * +builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, + const char *mode, int flags, int dont_inherit, + int optimize, int feature_version); + +static PyObject * +builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + PyObject *argsbuf[7]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + PyObject *source; + PyObject *filename; + const char *mode; + int flags = 0; + int dont_inherit = 0; + int optimize = -1; + int feature_version = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 6, 0, argsbuf); + if (!args) { + goto exit; + } + source = args[0]; + if (!PyUnicode_FSDecoder(args[1], &filename)) { + goto exit; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("compile", "argument 'mode'", "str", args[2]); + goto exit; + } + Py_ssize_t mode_length; + mode = PyUnicode_AsUTF8AndSize(args[2], &mode_length); + if (mode == NULL) { + goto exit; + } + if (strlen(mode) != (size_t)mode_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[3]) { + 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; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[4]) { + if (PyFloat_Check(args[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + dont_inherit = _PyLong_AsInt(args[4]); + if (dont_inherit == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[5]) { + if (PyFloat_Check(args[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + optimize = _PyLong_AsInt(args[5]); + if (optimize == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + feature_version = _PyLong_AsInt(args[6]); + if (feature_version == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_kwonly: + return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize, feature_version); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_divmod__doc__, +"divmod($module, x, y, /)\n" +"--\n" +"\n" +"Return the tuple (x//y, x%y). Invariant: div*y + mod == x."); + +#define BUILTIN_DIVMOD_METHODDEF \ + {"divmod", (PyCFunction)(void(*)(void))builtin_divmod, METH_FASTCALL, builtin_divmod__doc__}, + +static PyObject * +builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y); + +static PyObject * +builtin_divmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *x; + PyObject *y; + + if (!_PyArg_CheckPositional("divmod", nargs, 2, 2)) { + goto exit; + } + x = args[0]; + y = args[1]; + return_value = builtin_divmod_impl(module, x, y); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_eval__doc__, +"eval($module, source, globals=None, locals=None, /)\n" +"--\n" +"\n" +"Evaluate the given source in the context of globals and locals.\n" +"\n" +"The source may be a string representing a Python expression\n" +"or a code object as returned by compile().\n" +"The globals must be a dictionary and locals can be any mapping,\n" +"defaulting to the current globals and locals.\n" +"If only globals is given, locals defaults to it."); + +#define BUILTIN_EVAL_METHODDEF \ + {"eval", (PyCFunction)(void(*)(void))builtin_eval, METH_FASTCALL, builtin_eval__doc__}, + +static PyObject * +builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, + PyObject *locals); + +static PyObject * +builtin_eval(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *source; + PyObject *globals = Py_None; + PyObject *locals = Py_None; + + if (!_PyArg_CheckPositional("eval", nargs, 1, 3)) { + goto exit; + } + source = args[0]; + if (nargs < 2) { + goto skip_optional; + } + globals = args[1]; + if (nargs < 3) { + goto skip_optional; + } + locals = args[2]; +skip_optional: + return_value = builtin_eval_impl(module, source, globals, locals); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_exec__doc__, +"exec($module, source, globals=None, locals=None, /)\n" +"--\n" +"\n" +"Execute the given source in the context of globals and locals.\n" +"\n" +"The source may be a string representing one or more Python statements\n" +"or a code object as returned by compile().\n" +"The globals must be a dictionary and locals can be any mapping,\n" +"defaulting to the current globals and locals.\n" +"If only globals is given, locals defaults to it."); + +#define BUILTIN_EXEC_METHODDEF \ + {"exec", (PyCFunction)(void(*)(void))builtin_exec, METH_FASTCALL, builtin_exec__doc__}, + +static PyObject * +builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, + PyObject *locals); + +static PyObject * +builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *source; + PyObject *globals = Py_None; + PyObject *locals = Py_None; + + if (!_PyArg_CheckPositional("exec", nargs, 1, 3)) { + goto exit; + } + source = args[0]; + if (nargs < 2) { + goto skip_optional; + } + globals = args[1]; + if (nargs < 3) { + goto skip_optional; + } + locals = args[2]; +skip_optional: + return_value = builtin_exec_impl(module, source, globals, locals); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_globals__doc__, +"globals($module, /)\n" +"--\n" +"\n" +"Return the dictionary containing the current scope\'s global variables.\n" +"\n" +"NOTE: Updates to this dictionary *will* affect name lookups in the current\n" +"global scope and vice-versa."); + +#define BUILTIN_GLOBALS_METHODDEF \ + {"globals", (PyCFunction)builtin_globals, METH_NOARGS, builtin_globals__doc__}, + +static PyObject * +builtin_globals_impl(PyObject *module); + +static PyObject * +builtin_globals(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return builtin_globals_impl(module); +} + +PyDoc_STRVAR(builtin_hasattr__doc__, +"hasattr($module, obj, name, /)\n" +"--\n" +"\n" +"Return whether the object has an attribute with the given name.\n" +"\n" +"This is done by calling getattr(obj, name) and catching AttributeError."); + +#define BUILTIN_HASATTR_METHODDEF \ + {"hasattr", (PyCFunction)(void(*)(void))builtin_hasattr, METH_FASTCALL, builtin_hasattr__doc__}, + +static PyObject * +builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name); + +static PyObject * +builtin_hasattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *name; + + if (!_PyArg_CheckPositional("hasattr", nargs, 2, 2)) { + goto exit; + } + obj = args[0]; + name = args[1]; + return_value = builtin_hasattr_impl(module, obj, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_id__doc__, +"id($module, obj, /)\n" +"--\n" +"\n" +"Return the identity of an object.\n" +"\n" +"This is guaranteed to be unique among simultaneously existing objects.\n" +"(CPython uses the object\'s memory address.)"); + +#define BUILTIN_ID_METHODDEF \ + {"id", (PyCFunction)builtin_id, METH_O, builtin_id__doc__}, + +PyDoc_STRVAR(builtin_setattr__doc__, +"setattr($module, obj, name, value, /)\n" +"--\n" +"\n" +"Sets the named attribute on the given object to the specified value.\n" +"\n" +"setattr(x, \'y\', v) is equivalent to ``x.y = v\'\'"); + +#define BUILTIN_SETATTR_METHODDEF \ + {"setattr", (PyCFunction)(void(*)(void))builtin_setattr, METH_FASTCALL, builtin_setattr__doc__}, + +static PyObject * +builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, + PyObject *value); + +static PyObject * +builtin_setattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *name; + PyObject *value; + + if (!_PyArg_CheckPositional("setattr", nargs, 3, 3)) { + goto exit; + } + obj = args[0]; + name = args[1]; + value = args[2]; + return_value = builtin_setattr_impl(module, obj, name, value); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_delattr__doc__, +"delattr($module, obj, name, /)\n" +"--\n" +"\n" +"Deletes the named attribute from the given object.\n" +"\n" +"delattr(x, \'y\') is equivalent to ``del x.y\'\'"); + +#define BUILTIN_DELATTR_METHODDEF \ + {"delattr", (PyCFunction)(void(*)(void))builtin_delattr, METH_FASTCALL, builtin_delattr__doc__}, + +static PyObject * +builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name); + +static PyObject * +builtin_delattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *name; + + if (!_PyArg_CheckPositional("delattr", nargs, 2, 2)) { + goto exit; + } + obj = args[0]; + name = args[1]; + return_value = builtin_delattr_impl(module, obj, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_hash__doc__, +"hash($module, obj, /)\n" +"--\n" +"\n" +"Return the hash value for the given object.\n" +"\n" +"Two objects that compare equal must also have the same hash value, but the\n" +"reverse is not necessarily true."); + +#define BUILTIN_HASH_METHODDEF \ + {"hash", (PyCFunction)builtin_hash, METH_O, builtin_hash__doc__}, + +PyDoc_STRVAR(builtin_hex__doc__, +"hex($module, number, /)\n" +"--\n" +"\n" +"Return the hexadecimal representation of an integer.\n" +"\n" +" >>> hex(12648430)\n" +" \'0xc0ffee\'"); + +#define BUILTIN_HEX_METHODDEF \ + {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, + +PyDoc_STRVAR(builtin_len__doc__, +"len($module, obj, /)\n" +"--\n" +"\n" +"Return the number of items in a container."); + +#define BUILTIN_LEN_METHODDEF \ + {"len", (PyCFunction)builtin_len, METH_O, builtin_len__doc__}, + +PyDoc_STRVAR(builtin_locals__doc__, +"locals($module, /)\n" +"--\n" +"\n" +"Return a dictionary containing the current scope\'s local variables.\n" +"\n" +"NOTE: Whether or not updates to this dictionary will affect name lookups in\n" +"the local scope and vice-versa is *implementation dependent* and not\n" +"covered by any backwards compatibility guarantees."); + +#define BUILTIN_LOCALS_METHODDEF \ + {"locals", (PyCFunction)builtin_locals, METH_NOARGS, builtin_locals__doc__}, + +static PyObject * +builtin_locals_impl(PyObject *module); + +static PyObject * +builtin_locals(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return builtin_locals_impl(module); +} + +PyDoc_STRVAR(builtin_oct__doc__, +"oct($module, number, /)\n" +"--\n" +"\n" +"Return the octal representation of an integer.\n" +"\n" +" >>> oct(342391)\n" +" \'0o1234567\'"); + +#define BUILTIN_OCT_METHODDEF \ + {"oct", (PyCFunction)builtin_oct, METH_O, builtin_oct__doc__}, + +PyDoc_STRVAR(builtin_ord__doc__, +"ord($module, c, /)\n" +"--\n" +"\n" +"Return the Unicode code point for a one-character string."); + +#define BUILTIN_ORD_METHODDEF \ + {"ord", (PyCFunction)builtin_ord, METH_O, builtin_ord__doc__}, + +PyDoc_STRVAR(builtin_pow__doc__, +"pow($module, /, base, exp, mod=None)\n" +"--\n" +"\n" +"Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments\n" +"\n" +"Some types, such as ints, are able to use a more efficient algorithm when\n" +"invoked using the three argument form."); + +#define BUILTIN_POW_METHODDEF \ + {"pow", (PyCFunction)(void(*)(void))builtin_pow, METH_FASTCALL|METH_KEYWORDS, builtin_pow__doc__}, + +static PyObject * +builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, + PyObject *mod); + +static PyObject * +builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"base", "exp", "mod", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *base; + PyObject *exp; + PyObject *mod = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + base = args[0]; + exp = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + mod = args[2]; +skip_optional_pos: + return_value = builtin_pow_impl(module, base, exp, mod); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_input__doc__, +"input($module, prompt=None, /)\n" +"--\n" +"\n" +"Read a string from standard input. The trailing newline is stripped.\n" +"\n" +"The prompt string, if given, is printed to standard output without a\n" +"trailing newline before reading input.\n" +"\n" +"If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.\n" +"On *nix systems, readline is used if available."); + +#define BUILTIN_INPUT_METHODDEF \ + {"input", (PyCFunction)(void(*)(void))builtin_input, METH_FASTCALL, builtin_input__doc__}, + +static PyObject * +builtin_input_impl(PyObject *module, PyObject *prompt); + +static PyObject * +builtin_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *prompt = NULL; + + if (!_PyArg_CheckPositional("input", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + prompt = args[0]; +skip_optional: + return_value = builtin_input_impl(module, prompt); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_repr__doc__, +"repr($module, obj, /)\n" +"--\n" +"\n" +"Return the canonical string representation of the object.\n" +"\n" +"For many object types, including most builtins, eval(repr(obj)) == obj."); + +#define BUILTIN_REPR_METHODDEF \ + {"repr", (PyCFunction)builtin_repr, METH_O, builtin_repr__doc__}, + +PyDoc_STRVAR(builtin_round__doc__, +"round($module, /, number, ndigits=None)\n" +"--\n" +"\n" +"Round a number to a given precision in decimal digits.\n" +"\n" +"The return value is an integer if ndigits is omitted or None. Otherwise\n" +"the return value has the same type as the number. ndigits may be negative."); + +#define BUILTIN_ROUND_METHODDEF \ + {"round", (PyCFunction)(void(*)(void))builtin_round, METH_FASTCALL|METH_KEYWORDS, builtin_round__doc__}, + +static PyObject * +builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits); + +static PyObject * +builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"number", "ndigits", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "round", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *number; + PyObject *ndigits = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + number = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + ndigits = args[1]; +skip_optional_pos: + return_value = builtin_round_impl(module, number, ndigits); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_sum__doc__, +"sum($module, iterable, /, start=0)\n" +"--\n" +"\n" +"Return the sum of a \'start\' value (default: 0) plus an iterable of numbers\n" +"\n" +"When the iterable is empty, return the start value.\n" +"This function is intended specifically for use with numeric values and may\n" +"reject non-numeric types."); + +#define BUILTIN_SUM_METHODDEF \ + {"sum", (PyCFunction)(void(*)(void))builtin_sum, METH_FASTCALL|METH_KEYWORDS, builtin_sum__doc__}, + +static PyObject * +builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start); + +static PyObject * +builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "start", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sum", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *iterable; + PyObject *start = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + iterable = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + start = args[1]; +skip_optional_pos: + return_value = builtin_sum_impl(module, iterable, start); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_isinstance__doc__, +"isinstance($module, obj, class_or_tuple, /)\n" +"--\n" +"\n" +"Return whether an object is an instance of a class or of a subclass thereof.\n" +"\n" +"A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to\n" +"check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)\n" +"or ...`` etc."); + +#define BUILTIN_ISINSTANCE_METHODDEF \ + {"isinstance", (PyCFunction)(void(*)(void))builtin_isinstance, METH_FASTCALL, builtin_isinstance__doc__}, + +static PyObject * +builtin_isinstance_impl(PyObject *module, PyObject *obj, + PyObject *class_or_tuple); + +static PyObject * +builtin_isinstance(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *class_or_tuple; + + if (!_PyArg_CheckPositional("isinstance", nargs, 2, 2)) { + goto exit; + } + obj = args[0]; + class_or_tuple = args[1]; + return_value = builtin_isinstance_impl(module, obj, class_or_tuple); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_issubclass__doc__, +"issubclass($module, cls, class_or_tuple, /)\n" +"--\n" +"\n" +"Return whether \'cls\' is a derived from another class or is the same class.\n" +"\n" +"A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to\n" +"check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)\n" +"or ...`` etc."); + +#define BUILTIN_ISSUBCLASS_METHODDEF \ + {"issubclass", (PyCFunction)(void(*)(void))builtin_issubclass, METH_FASTCALL, builtin_issubclass__doc__}, + +static PyObject * +builtin_issubclass_impl(PyObject *module, PyObject *cls, + PyObject *class_or_tuple); + +static PyObject * +builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *cls; + PyObject *class_or_tuple; + + if (!_PyArg_CheckPositional("issubclass", nargs, 2, 2)) { + goto exit; + } + cls = args[0]; + class_or_tuple = args[1]; + return_value = builtin_issubclass_impl(module, cls, class_or_tuple); + +exit: + return return_value; +} +/*[clinic end generated code: output=29686a89b739d600 input=a9049054013a1b77]*/ diff --git a/python/Python/clinic/context.c.h b/python/Python/clinic/context.c.h new file mode 100755 index 0000000..2ac8bf7 --- /dev/null +++ b/python/Python/clinic/context.c.h @@ -0,0 +1,180 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_contextvars_Context_get__doc__, +"get($self, key, default=None, /)\n" +"--\n" +"\n" +"Return the value for `key` if `key` has the value in the context object.\n" +"\n" +"If `key` does not exist, return `default`. If `default` is not given,\n" +"return None."); + +#define _CONTEXTVARS_CONTEXT_GET_METHODDEF \ + {"get", (PyCFunction)(void(*)(void))_contextvars_Context_get, METH_FASTCALL, _contextvars_Context_get__doc__}, + +static PyObject * +_contextvars_Context_get_impl(PyContext *self, PyObject *key, + PyObject *default_value); + +static PyObject * +_contextvars_Context_get(PyContext *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; + } + key = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = _contextvars_Context_get_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_contextvars_Context_items__doc__, +"items($self, /)\n" +"--\n" +"\n" +"Return all variables and their values in the context object.\n" +"\n" +"The result is returned as a list of 2-tuples (variable, value)."); + +#define _CONTEXTVARS_CONTEXT_ITEMS_METHODDEF \ + {"items", (PyCFunction)_contextvars_Context_items, METH_NOARGS, _contextvars_Context_items__doc__}, + +static PyObject * +_contextvars_Context_items_impl(PyContext *self); + +static PyObject * +_contextvars_Context_items(PyContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _contextvars_Context_items_impl(self); +} + +PyDoc_STRVAR(_contextvars_Context_keys__doc__, +"keys($self, /)\n" +"--\n" +"\n" +"Return a list of all variables in the context object."); + +#define _CONTEXTVARS_CONTEXT_KEYS_METHODDEF \ + {"keys", (PyCFunction)_contextvars_Context_keys, METH_NOARGS, _contextvars_Context_keys__doc__}, + +static PyObject * +_contextvars_Context_keys_impl(PyContext *self); + +static PyObject * +_contextvars_Context_keys(PyContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _contextvars_Context_keys_impl(self); +} + +PyDoc_STRVAR(_contextvars_Context_values__doc__, +"values($self, /)\n" +"--\n" +"\n" +"Return a list of all variables\' values in the context object."); + +#define _CONTEXTVARS_CONTEXT_VALUES_METHODDEF \ + {"values", (PyCFunction)_contextvars_Context_values, METH_NOARGS, _contextvars_Context_values__doc__}, + +static PyObject * +_contextvars_Context_values_impl(PyContext *self); + +static PyObject * +_contextvars_Context_values(PyContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _contextvars_Context_values_impl(self); +} + +PyDoc_STRVAR(_contextvars_Context_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a shallow copy of the context object."); + +#define _CONTEXTVARS_CONTEXT_COPY_METHODDEF \ + {"copy", (PyCFunction)_contextvars_Context_copy, METH_NOARGS, _contextvars_Context_copy__doc__}, + +static PyObject * +_contextvars_Context_copy_impl(PyContext *self); + +static PyObject * +_contextvars_Context_copy(PyContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _contextvars_Context_copy_impl(self); +} + +PyDoc_STRVAR(_contextvars_ContextVar_get__doc__, +"get($self, default=, /)\n" +"--\n" +"\n" +"Return a value for the context variable for the current context.\n" +"\n" +"If there is no value for the variable in the current context, the method will:\n" +" * return the value of the default argument of the method, if provided; or\n" +" * return the default value for the context variable, if it was created\n" +" with one; or\n" +" * raise a LookupError."); + +#define _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF \ + {"get", (PyCFunction)(void(*)(void))_contextvars_ContextVar_get, METH_FASTCALL, _contextvars_ContextVar_get__doc__}, + +static PyObject * +_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value); + +static PyObject * +_contextvars_ContextVar_get(PyContextVar *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("get", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + default_value = args[0]; +skip_optional: + return_value = _contextvars_ContextVar_get_impl(self, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_contextvars_ContextVar_set__doc__, +"set($self, value, /)\n" +"--\n" +"\n" +"Call to set a new value for the context variable in the current context.\n" +"\n" +"The required value argument is the new value for the context variable.\n" +"\n" +"Returns a Token object that can be used to restore the variable to its previous\n" +"value via the `ContextVar.reset()` method."); + +#define _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF \ + {"set", (PyCFunction)_contextvars_ContextVar_set, METH_O, _contextvars_ContextVar_set__doc__}, + +PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__, +"reset($self, token, /)\n" +"--\n" +"\n" +"Reset the context variable.\n" +"\n" +"The variable is reset to the value it had before the `ContextVar.set()` that\n" +"created the token was used."); + +#define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \ + {"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__}, +/*[clinic end generated code: output=f2e42f34e358e179 input=a9049054013a1b77]*/ diff --git a/python/Python/clinic/import.c.h b/python/Python/clinic/import.c.h new file mode 100755 index 0000000..782fdc2 --- /dev/null +++ b/python/Python/clinic/import.c.h @@ -0,0 +1,458 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_lock_held__doc__, +"lock_held($module, /)\n" +"--\n" +"\n" +"Return True if the import lock is currently held, else False.\n" +"\n" +"On platforms without threads, return False."); + +#define _IMP_LOCK_HELD_METHODDEF \ + {"lock_held", (PyCFunction)_imp_lock_held, METH_NOARGS, _imp_lock_held__doc__}, + +static PyObject * +_imp_lock_held_impl(PyObject *module); + +static PyObject * +_imp_lock_held(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_lock_held_impl(module); +} + +PyDoc_STRVAR(_imp_acquire_lock__doc__, +"acquire_lock($module, /)\n" +"--\n" +"\n" +"Acquires the interpreter\'s import lock for the current thread.\n" +"\n" +"This lock should be used by import hooks to ensure thread-safety when importing\n" +"modules. On platforms without threads, this function does nothing."); + +#define _IMP_ACQUIRE_LOCK_METHODDEF \ + {"acquire_lock", (PyCFunction)_imp_acquire_lock, METH_NOARGS, _imp_acquire_lock__doc__}, + +static PyObject * +_imp_acquire_lock_impl(PyObject *module); + +static PyObject * +_imp_acquire_lock(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_acquire_lock_impl(module); +} + +PyDoc_STRVAR(_imp_release_lock__doc__, +"release_lock($module, /)\n" +"--\n" +"\n" +"Release the interpreter\'s import lock.\n" +"\n" +"On platforms without threads, this function does nothing."); + +#define _IMP_RELEASE_LOCK_METHODDEF \ + {"release_lock", (PyCFunction)_imp_release_lock, METH_NOARGS, _imp_release_lock__doc__}, + +static PyObject * +_imp_release_lock_impl(PyObject *module); + +static PyObject * +_imp_release_lock(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_release_lock_impl(module); +} + +PyDoc_STRVAR(_imp__fix_co_filename__doc__, +"_fix_co_filename($module, code, path, /)\n" +"--\n" +"\n" +"Changes code.co_filename to specify the passed-in file path.\n" +"\n" +" code\n" +" Code object to change.\n" +" path\n" +" File path to use."); + +#define _IMP__FIX_CO_FILENAME_METHODDEF \ + {"_fix_co_filename", (PyCFunction)(void(*)(void))_imp__fix_co_filename, METH_FASTCALL, _imp__fix_co_filename__doc__}, + +static PyObject * +_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code, + PyObject *path); + +static PyObject * +_imp__fix_co_filename(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyCodeObject *code; + PyObject *path; + + if (!_PyArg_CheckPositional("_fix_co_filename", nargs, 2, 2)) { + goto exit; + } + if (!PyObject_TypeCheck(args[0], &PyCode_Type)) { + _PyArg_BadArgument("_fix_co_filename", "argument 1", (&PyCode_Type)->tp_name, args[0]); + goto exit; + } + code = (PyCodeObject *)args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("_fix_co_filename", "argument 2", "str", args[1]); + goto exit; + } + if (PyUnicode_READY(args[1]) == -1) { + goto exit; + } + path = args[1]; + return_value = _imp__fix_co_filename_impl(module, code, path); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_create_builtin__doc__, +"create_builtin($module, spec, /)\n" +"--\n" +"\n" +"Create an extension module."); + +#define _IMP_CREATE_BUILTIN_METHODDEF \ + {"create_builtin", (PyCFunction)_imp_create_builtin, METH_O, _imp_create_builtin__doc__}, + +PyDoc_STRVAR(_imp_extension_suffixes__doc__, +"extension_suffixes($module, /)\n" +"--\n" +"\n" +"Returns the list of file suffixes used to identify extension modules."); + +#define _IMP_EXTENSION_SUFFIXES_METHODDEF \ + {"extension_suffixes", (PyCFunction)_imp_extension_suffixes, METH_NOARGS, _imp_extension_suffixes__doc__}, + +static PyObject * +_imp_extension_suffixes_impl(PyObject *module); + +static PyObject * +_imp_extension_suffixes(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_extension_suffixes_impl(module); +} + +PyDoc_STRVAR(_imp_init_frozen__doc__, +"init_frozen($module, name, /)\n" +"--\n" +"\n" +"Initializes a frozen module."); + +#define _IMP_INIT_FROZEN_METHODDEF \ + {"init_frozen", (PyCFunction)_imp_init_frozen, METH_O, _imp_init_frozen__doc__}, + +static PyObject * +_imp_init_frozen_impl(PyObject *module, PyObject *name); + +static PyObject * +_imp_init_frozen(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("init_frozen", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + name = arg; + return_value = _imp_init_frozen_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_get_frozen_object__doc__, +"get_frozen_object($module, name, /)\n" +"--\n" +"\n" +"Create a code object for a frozen module."); + +#define _IMP_GET_FROZEN_OBJECT_METHODDEF \ + {"get_frozen_object", (PyCFunction)_imp_get_frozen_object, METH_O, _imp_get_frozen_object__doc__}, + +static PyObject * +_imp_get_frozen_object_impl(PyObject *module, PyObject *name); + +static PyObject * +_imp_get_frozen_object(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("get_frozen_object", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + name = arg; + return_value = _imp_get_frozen_object_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_is_frozen_package__doc__, +"is_frozen_package($module, name, /)\n" +"--\n" +"\n" +"Returns True if the module name is of a frozen package."); + +#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ + {"is_frozen_package", (PyCFunction)_imp_is_frozen_package, METH_O, _imp_is_frozen_package__doc__}, + +static PyObject * +_imp_is_frozen_package_impl(PyObject *module, PyObject *name); + +static PyObject * +_imp_is_frozen_package(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("is_frozen_package", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + name = arg; + return_value = _imp_is_frozen_package_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_is_builtin__doc__, +"is_builtin($module, name, /)\n" +"--\n" +"\n" +"Returns True if the module name corresponds to a built-in module."); + +#define _IMP_IS_BUILTIN_METHODDEF \ + {"is_builtin", (PyCFunction)_imp_is_builtin, METH_O, _imp_is_builtin__doc__}, + +static PyObject * +_imp_is_builtin_impl(PyObject *module, PyObject *name); + +static PyObject * +_imp_is_builtin(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("is_builtin", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + name = arg; + return_value = _imp_is_builtin_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_is_frozen__doc__, +"is_frozen($module, name, /)\n" +"--\n" +"\n" +"Returns True if the module name corresponds to a frozen module."); + +#define _IMP_IS_FROZEN_METHODDEF \ + {"is_frozen", (PyCFunction)_imp_is_frozen, METH_O, _imp_is_frozen__doc__}, + +static PyObject * +_imp_is_frozen_impl(PyObject *module, PyObject *name); + +static PyObject * +_imp_is_frozen(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("is_frozen", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + name = arg; + return_value = _imp_is_frozen_impl(module, name); + +exit: + return return_value; +} + +#if defined(HAVE_DYNAMIC_LOADING) + +PyDoc_STRVAR(_imp_create_dynamic__doc__, +"create_dynamic($module, spec, file=, /)\n" +"--\n" +"\n" +"Create an extension module."); + +#define _IMP_CREATE_DYNAMIC_METHODDEF \ + {"create_dynamic", (PyCFunction)(void(*)(void))_imp_create_dynamic, METH_FASTCALL, _imp_create_dynamic__doc__}, + +static PyObject * +_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file); + +static PyObject * +_imp_create_dynamic(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + // printf("\n------------------\n"); + PyObject *return_value = NULL; + PyObject *spec; + PyObject *file = NULL; + + if (!_PyArg_CheckPositional("create_dynamic", nargs, 1, 2)) { + goto exit; + } + spec = args[0]; + if (nargs < 2) { + goto skip_optional; + } + file = args[1]; +skip_optional: + return_value = _imp_create_dynamic_impl(module, spec, file); + +exit: + return return_value; +} + +#endif /* defined(HAVE_DYNAMIC_LOADING) */ + +#if defined(HAVE_DYNAMIC_LOADING) + +PyDoc_STRVAR(_imp_exec_dynamic__doc__, +"exec_dynamic($module, mod, /)\n" +"--\n" +"\n" +"Initialize an extension module."); + +#define _IMP_EXEC_DYNAMIC_METHODDEF \ + {"exec_dynamic", (PyCFunction)_imp_exec_dynamic, METH_O, _imp_exec_dynamic__doc__}, + +static int +_imp_exec_dynamic_impl(PyObject *module, PyObject *mod); + +static PyObject * +_imp_exec_dynamic(PyObject *module, PyObject *mod) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _imp_exec_dynamic_impl(module, mod); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_DYNAMIC_LOADING) */ + +PyDoc_STRVAR(_imp_exec_builtin__doc__, +"exec_builtin($module, mod, /)\n" +"--\n" +"\n" +"Initialize a built-in module."); + +#define _IMP_EXEC_BUILTIN_METHODDEF \ + {"exec_builtin", (PyCFunction)_imp_exec_builtin, METH_O, _imp_exec_builtin__doc__}, + +static int +_imp_exec_builtin_impl(PyObject *module, PyObject *mod); + +static PyObject * +_imp_exec_builtin(PyObject *module, PyObject *mod) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _imp_exec_builtin_impl(module, mod); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_source_hash__doc__, +"source_hash($module, /, key, source)\n" +"--\n" +"\n"); + +#define _IMP_SOURCE_HASH_METHODDEF \ + {"source_hash", (PyCFunction)(void(*)(void))_imp_source_hash, METH_FASTCALL|METH_KEYWORDS, _imp_source_hash__doc__}, + +static PyObject * +_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source); + +static PyObject * +_imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"key", "source", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "source_hash", 0}; + PyObject *argsbuf[2]; + long key; + Py_buffer source = {NULL, NULL}; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + key = PyLong_AsLong(args[0]); + if (key == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &source, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&source, 'C')) { + _PyArg_BadArgument("source_hash", "argument 'source'", "contiguous buffer", args[1]); + goto exit; + } + return_value = _imp_source_hash_impl(module, key, &source); + +exit: + /* Cleanup for source */ + if (source.obj) { + PyBuffer_Release(&source); + } + + return return_value; +} + +#ifndef _IMP_CREATE_DYNAMIC_METHODDEF + #define _IMP_CREATE_DYNAMIC_METHODDEF +#endif /* !defined(_IMP_CREATE_DYNAMIC_METHODDEF) */ + +#ifndef _IMP_EXEC_DYNAMIC_METHODDEF + #define _IMP_EXEC_DYNAMIC_METHODDEF +#endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ +/*[clinic end generated code: output=3dc495e9c64d944e input=a9049054013a1b77]*/ diff --git a/python/Python/clinic/marshal.c.h b/python/Python/clinic/marshal.c.h new file mode 100755 index 0000000..05d4830 --- /dev/null +++ b/python/Python/clinic/marshal.c.h @@ -0,0 +1,168 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_dump__doc__, +"dump($module, value, file, version=version, /)\n" +"--\n" +"\n" +"Write the value on the open file.\n" +"\n" +" value\n" +" Must be a supported type.\n" +" file\n" +" Must be a writeable binary file.\n" +" version\n" +" Indicates the data format that dump should use.\n" +"\n" +"If the value has (or contains an object that has) an unsupported type, a\n" +"ValueError exception is raised - but garbage data will also be written\n" +"to the file. The object will not be properly read back by load()."); + +#define MARSHAL_DUMP_METHODDEF \ + {"dump", (PyCFunction)(void(*)(void))marshal_dump, METH_FASTCALL, marshal_dump__doc__}, + +static PyObject * +marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file, + int version); + +static PyObject * +marshal_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *value; + PyObject *file; + int version = Py_MARSHAL_VERSION; + + if (!_PyArg_CheckPositional("dump", nargs, 2, 3)) { + goto exit; + } + value = args[0]; + file = args[1]; + if (nargs < 3) { + goto skip_optional; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + version = _PyLong_AsInt(args[2]); + if (version == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = marshal_dump_impl(module, value, file, version); + +exit: + return return_value; +} + +PyDoc_STRVAR(marshal_load__doc__, +"load($module, file, /)\n" +"--\n" +"\n" +"Read one value from the open file and return it.\n" +"\n" +" file\n" +" Must be readable binary file.\n" +"\n" +"If no valid value is read (e.g. because the data has a different Python\n" +"version\'s incompatible marshal format), raise EOFError, ValueError or\n" +"TypeError.\n" +"\n" +"Note: If an object containing an unsupported type was marshalled with\n" +"dump(), load() will substitute None for the unmarshallable type."); + +#define MARSHAL_LOAD_METHODDEF \ + {"load", (PyCFunction)marshal_load, METH_O, marshal_load__doc__}, + +PyDoc_STRVAR(marshal_dumps__doc__, +"dumps($module, value, version=version, /)\n" +"--\n" +"\n" +"Return the bytes object that would be written to a file by dump(value, file).\n" +"\n" +" value\n" +" Must be a supported type.\n" +" version\n" +" Indicates the data format that dumps should use.\n" +"\n" +"Raise a ValueError exception if value has (or contains an object that has) an\n" +"unsupported type."); + +#define MARSHAL_DUMPS_METHODDEF \ + {"dumps", (PyCFunction)(void(*)(void))marshal_dumps, METH_FASTCALL, marshal_dumps__doc__}, + +static PyObject * +marshal_dumps_impl(PyObject *module, PyObject *value, int version); + +static PyObject * +marshal_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *value; + int version = Py_MARSHAL_VERSION; + + if (!_PyArg_CheckPositional("dumps", nargs, 1, 2)) { + goto exit; + } + value = args[0]; + if (nargs < 2) { + goto skip_optional; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + version = _PyLong_AsInt(args[1]); + if (version == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = marshal_dumps_impl(module, value, version); + +exit: + return return_value; +} + +PyDoc_STRVAR(marshal_loads__doc__, +"loads($module, bytes, /)\n" +"--\n" +"\n" +"Convert the bytes-like object to a value.\n" +"\n" +"If no valid value is found, raise EOFError, ValueError or TypeError. Extra\n" +"bytes in the input are ignored."); + +#define MARSHAL_LOADS_METHODDEF \ + {"loads", (PyCFunction)marshal_loads, METH_O, marshal_loads__doc__}, + +static PyObject * +marshal_loads_impl(PyObject *module, Py_buffer *bytes); + +static PyObject * +marshal_loads(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer bytes = {NULL, NULL}; + + if (PyObject_GetBuffer(arg, &bytes, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bytes, 'C')) { + _PyArg_BadArgument("loads", "argument", "contiguous buffer", arg); + goto exit; + } + return_value = marshal_loads_impl(module, &bytes); + +exit: + /* Cleanup for bytes */ + if (bytes.obj) { + PyBuffer_Release(&bytes); + } + + return return_value; +} +/*[clinic end generated code: output=a859dabe8b0afeb6 input=a9049054013a1b77]*/ diff --git a/python/Python/clinic/sysmodule.c.h b/python/Python/clinic/sysmodule.c.h new file mode 100755 index 0000000..d2d1503 --- /dev/null +++ b/python/Python/clinic/sysmodule.c.h @@ -0,0 +1,1091 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(sys_addaudithook__doc__, +"addaudithook($module, /, hook)\n" +"--\n" +"\n" +"Adds a new audit hook callback."); + +#define SYS_ADDAUDITHOOK_METHODDEF \ + {"addaudithook", (PyCFunction)(void(*)(void))sys_addaudithook, METH_FASTCALL|METH_KEYWORDS, sys_addaudithook__doc__}, + +static PyObject * +sys_addaudithook_impl(PyObject *module, PyObject *hook); + +static PyObject * +sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"hook", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0}; + PyObject *argsbuf[1]; + PyObject *hook; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + hook = args[0]; + return_value = sys_addaudithook_impl(module, hook); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_displayhook__doc__, +"displayhook($module, object, /)\n" +"--\n" +"\n" +"Print an object to sys.stdout and also save it in builtins._"); + +#define SYS_DISPLAYHOOK_METHODDEF \ + {"displayhook", (PyCFunction)sys_displayhook, METH_O, sys_displayhook__doc__}, + +PyDoc_STRVAR(sys_excepthook__doc__, +"excepthook($module, exctype, value, traceback, /)\n" +"--\n" +"\n" +"Handle an exception by displaying it with a traceback on sys.stderr."); + +#define SYS_EXCEPTHOOK_METHODDEF \ + {"excepthook", (PyCFunction)(void(*)(void))sys_excepthook, METH_FASTCALL, sys_excepthook__doc__}, + +static PyObject * +sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, + PyObject *traceback); + +static PyObject * +sys_excepthook(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exctype; + PyObject *value; + PyObject *traceback; + + if (!_PyArg_CheckPositional("excepthook", nargs, 3, 3)) { + goto exit; + } + exctype = args[0]; + value = args[1]; + traceback = args[2]; + return_value = sys_excepthook_impl(module, exctype, value, traceback); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_exc_info__doc__, +"exc_info($module, /)\n" +"--\n" +"\n" +"Return current exception information: (type, value, traceback).\n" +"\n" +"Return information about the most recent exception caught by an except\n" +"clause in the current stack frame or in an older stack frame."); + +#define SYS_EXC_INFO_METHODDEF \ + {"exc_info", (PyCFunction)sys_exc_info, METH_NOARGS, sys_exc_info__doc__}, + +static PyObject * +sys_exc_info_impl(PyObject *module); + +static PyObject * +sys_exc_info(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_exc_info_impl(module); +} + +PyDoc_STRVAR(sys_unraisablehook__doc__, +"unraisablehook($module, unraisable, /)\n" +"--\n" +"\n" +"Handle an unraisable exception.\n" +"\n" +"The unraisable argument has the following attributes:\n" +"\n" +"* exc_type: Exception type.\n" +"* exc_value: Exception value, can be None.\n" +"* exc_traceback: Exception traceback, can be None.\n" +"* err_msg: Error message, can be None.\n" +"* object: Object causing the exception, can be None."); + +#define SYS_UNRAISABLEHOOK_METHODDEF \ + {"unraisablehook", (PyCFunction)sys_unraisablehook, METH_O, sys_unraisablehook__doc__}, + +PyDoc_STRVAR(sys_exit__doc__, +"exit($module, status=None, /)\n" +"--\n" +"\n" +"Exit the interpreter by raising SystemExit(status).\n" +"\n" +"If the status is omitted or None, it defaults to zero (i.e., success).\n" +"If the status is an integer, it will be used as the system exit status.\n" +"If it is another kind of object, it will be printed and the system\n" +"exit status will be one (i.e., failure)."); + +#define SYS_EXIT_METHODDEF \ + {"exit", (PyCFunction)(void(*)(void))sys_exit, METH_FASTCALL, sys_exit__doc__}, + +static PyObject * +sys_exit_impl(PyObject *module, PyObject *status); + +static PyObject * +sys_exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *status = Py_None; + + if (!_PyArg_CheckPositional("exit", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + status = args[0]; +skip_optional: + return_value = sys_exit_impl(module, status); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_getdefaultencoding__doc__, +"getdefaultencoding($module, /)\n" +"--\n" +"\n" +"Return the current default encoding used by the Unicode implementation."); + +#define SYS_GETDEFAULTENCODING_METHODDEF \ + {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, METH_NOARGS, sys_getdefaultencoding__doc__}, + +static PyObject * +sys_getdefaultencoding_impl(PyObject *module); + +static PyObject * +sys_getdefaultencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getdefaultencoding_impl(module); +} + +PyDoc_STRVAR(sys_getfilesystemencoding__doc__, +"getfilesystemencoding($module, /)\n" +"--\n" +"\n" +"Return the encoding used to convert Unicode filenames to OS filenames."); + +#define SYS_GETFILESYSTEMENCODING_METHODDEF \ + {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding, METH_NOARGS, sys_getfilesystemencoding__doc__}, + +static PyObject * +sys_getfilesystemencoding_impl(PyObject *module); + +static PyObject * +sys_getfilesystemencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getfilesystemencoding_impl(module); +} + +PyDoc_STRVAR(sys_getfilesystemencodeerrors__doc__, +"getfilesystemencodeerrors($module, /)\n" +"--\n" +"\n" +"Return the error mode used Unicode to OS filename conversion."); + +#define SYS_GETFILESYSTEMENCODEERRORS_METHODDEF \ + {"getfilesystemencodeerrors", (PyCFunction)sys_getfilesystemencodeerrors, METH_NOARGS, sys_getfilesystemencodeerrors__doc__}, + +static PyObject * +sys_getfilesystemencodeerrors_impl(PyObject *module); + +static PyObject * +sys_getfilesystemencodeerrors(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getfilesystemencodeerrors_impl(module); +} + +PyDoc_STRVAR(sys_intern__doc__, +"intern($module, string, /)\n" +"--\n" +"\n" +"``Intern\'\' the given string.\n" +"\n" +"This enters the string in the (global) table of interned strings whose\n" +"purpose is to speed up dictionary lookups. Return the string itself or\n" +"the previously interned string object with the same value."); + +#define SYS_INTERN_METHODDEF \ + {"intern", (PyCFunction)sys_intern, METH_O, sys_intern__doc__}, + +static PyObject * +sys_intern_impl(PyObject *module, PyObject *s); + +static PyObject * +sys_intern(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *s; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("intern", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + s = arg; + return_value = sys_intern_impl(module, s); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_gettrace__doc__, +"gettrace($module, /)\n" +"--\n" +"\n" +"Return the global debug tracing function set with sys.settrace.\n" +"\n" +"See the debugger chapter in the library manual."); + +#define SYS_GETTRACE_METHODDEF \ + {"gettrace", (PyCFunction)sys_gettrace, METH_NOARGS, sys_gettrace__doc__}, + +static PyObject * +sys_gettrace_impl(PyObject *module); + +static PyObject * +sys_gettrace(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_gettrace_impl(module); +} + +PyDoc_STRVAR(sys_getprofile__doc__, +"getprofile($module, /)\n" +"--\n" +"\n" +"Return the profiling function set with sys.setprofile.\n" +"\n" +"See the profiler chapter in the library manual."); + +#define SYS_GETPROFILE_METHODDEF \ + {"getprofile", (PyCFunction)sys_getprofile, METH_NOARGS, sys_getprofile__doc__}, + +static PyObject * +sys_getprofile_impl(PyObject *module); + +static PyObject * +sys_getprofile(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getprofile_impl(module); +} + +PyDoc_STRVAR(sys_setcheckinterval__doc__, +"setcheckinterval($module, n, /)\n" +"--\n" +"\n" +"Set the async event check interval to n instructions.\n" +"\n" +"This tells the Python interpreter to check for asynchronous events\n" +"every n instructions.\n" +"\n" +"This also affects how often thread switches occur."); + +#define SYS_SETCHECKINTERVAL_METHODDEF \ + {"setcheckinterval", (PyCFunction)sys_setcheckinterval, METH_O, sys_setcheckinterval__doc__}, + +static PyObject * +sys_setcheckinterval_impl(PyObject *module, int n); + +static PyObject * +sys_setcheckinterval(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; + } + n = _PyLong_AsInt(arg); + if (n == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = sys_setcheckinterval_impl(module, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_getcheckinterval__doc__, +"getcheckinterval($module, /)\n" +"--\n" +"\n" +"Return the current check interval; see sys.setcheckinterval()."); + +#define SYS_GETCHECKINTERVAL_METHODDEF \ + {"getcheckinterval", (PyCFunction)sys_getcheckinterval, METH_NOARGS, sys_getcheckinterval__doc__}, + +static PyObject * +sys_getcheckinterval_impl(PyObject *module); + +static PyObject * +sys_getcheckinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getcheckinterval_impl(module); +} + +PyDoc_STRVAR(sys_setswitchinterval__doc__, +"setswitchinterval($module, interval, /)\n" +"--\n" +"\n" +"Set the ideal thread switching delay inside the Python interpreter.\n" +"\n" +"The actual frequency of switching threads can be lower if the\n" +"interpreter executes long sequences of uninterruptible code\n" +"(this is implementation-specific and workload-dependent).\n" +"\n" +"The parameter must represent the desired switching delay in seconds\n" +"A typical value is 0.005 (5 milliseconds)."); + +#define SYS_SETSWITCHINTERVAL_METHODDEF \ + {"setswitchinterval", (PyCFunction)sys_setswitchinterval, METH_O, sys_setswitchinterval__doc__}, + +static PyObject * +sys_setswitchinterval_impl(PyObject *module, double interval); + +static PyObject * +sys_setswitchinterval(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double interval; + + if (PyFloat_CheckExact(arg)) { + interval = PyFloat_AS_DOUBLE(arg); + } + else + { + interval = PyFloat_AsDouble(arg); + if (interval == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + return_value = sys_setswitchinterval_impl(module, interval); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_getswitchinterval__doc__, +"getswitchinterval($module, /)\n" +"--\n" +"\n" +"Return the current thread switch interval; see sys.setswitchinterval()."); + +#define SYS_GETSWITCHINTERVAL_METHODDEF \ + {"getswitchinterval", (PyCFunction)sys_getswitchinterval, METH_NOARGS, sys_getswitchinterval__doc__}, + +static double +sys_getswitchinterval_impl(PyObject *module); + +static PyObject * +sys_getswitchinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + double _return_value; + + _return_value = sys_getswitchinterval_impl(module); + if ((_return_value == -1.0) && PyErr_Occurred()) { + goto exit; + } + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_setrecursionlimit__doc__, +"setrecursionlimit($module, limit, /)\n" +"--\n" +"\n" +"Set the maximum depth of the Python interpreter stack to n.\n" +"\n" +"This limit prevents infinite recursion from causing an overflow of the C\n" +"stack and crashing Python. The highest possible limit is platform-\n" +"dependent."); + +#define SYS_SETRECURSIONLIMIT_METHODDEF \ + {"setrecursionlimit", (PyCFunction)sys_setrecursionlimit, METH_O, sys_setrecursionlimit__doc__}, + +static PyObject * +sys_setrecursionlimit_impl(PyObject *module, int new_limit); + +static PyObject * +sys_setrecursionlimit(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int new_limit; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + new_limit = _PyLong_AsInt(arg); + if (new_limit == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = sys_setrecursionlimit_impl(module, new_limit); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_set_coroutine_origin_tracking_depth__doc__, +"set_coroutine_origin_tracking_depth($module, /, depth)\n" +"--\n" +"\n" +"Enable or disable origin tracking for coroutine objects in this thread.\n" +"\n" +"Coroutine objects will track \'depth\' frames of traceback information\n" +"about where they came from, available in their cr_origin attribute.\n" +"\n" +"Set a depth of 0 to disable."); + +#define SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF \ + {"set_coroutine_origin_tracking_depth", (PyCFunction)(void(*)(void))sys_set_coroutine_origin_tracking_depth, METH_FASTCALL|METH_KEYWORDS, sys_set_coroutine_origin_tracking_depth__doc__}, + +static PyObject * +sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth); + +static PyObject * +sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"depth", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "set_coroutine_origin_tracking_depth", 0}; + PyObject *argsbuf[1]; + int depth; + + 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; + } + depth = _PyLong_AsInt(args[0]); + if (depth == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = sys_set_coroutine_origin_tracking_depth_impl(module, depth); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_get_coroutine_origin_tracking_depth__doc__, +"get_coroutine_origin_tracking_depth($module, /)\n" +"--\n" +"\n" +"Check status of origin tracking for coroutine objects in this thread."); + +#define SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF \ + {"get_coroutine_origin_tracking_depth", (PyCFunction)sys_get_coroutine_origin_tracking_depth, METH_NOARGS, sys_get_coroutine_origin_tracking_depth__doc__}, + +static int +sys_get_coroutine_origin_tracking_depth_impl(PyObject *module); + +static PyObject * +sys_get_coroutine_origin_tracking_depth(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = sys_get_coroutine_origin_tracking_depth_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_get_asyncgen_hooks__doc__, +"get_asyncgen_hooks($module, /)\n" +"--\n" +"\n" +"Return the installed asynchronous generators hooks.\n" +"\n" +"This returns a namedtuple of the form (firstiter, finalizer)."); + +#define SYS_GET_ASYNCGEN_HOOKS_METHODDEF \ + {"get_asyncgen_hooks", (PyCFunction)sys_get_asyncgen_hooks, METH_NOARGS, sys_get_asyncgen_hooks__doc__}, + +static PyObject * +sys_get_asyncgen_hooks_impl(PyObject *module); + +static PyObject * +sys_get_asyncgen_hooks(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_get_asyncgen_hooks_impl(module); +} + +PyDoc_STRVAR(sys_getrecursionlimit__doc__, +"getrecursionlimit($module, /)\n" +"--\n" +"\n" +"Return the current value of the recursion limit.\n" +"\n" +"The recursion limit is the maximum depth of the Python interpreter\n" +"stack. This limit prevents infinite recursion from causing an overflow\n" +"of the C stack and crashing Python."); + +#define SYS_GETRECURSIONLIMIT_METHODDEF \ + {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, sys_getrecursionlimit__doc__}, + +static PyObject * +sys_getrecursionlimit_impl(PyObject *module); + +static PyObject * +sys_getrecursionlimit(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getrecursionlimit_impl(module); +} + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(sys_getwindowsversion__doc__, +"getwindowsversion($module, /)\n" +"--\n" +"\n" +"Return info about the running version of Windows as a named tuple.\n" +"\n" +"The members are named: major, minor, build, platform, service_pack,\n" +"service_pack_major, service_pack_minor, suite_mask, product_type and\n" +"platform_version. For backward compatibility, only the first 5 items\n" +"are available by indexing. All elements are numbers, except\n" +"service_pack and platform_type which are strings, and platform_version\n" +"which is a 3-tuple. Platform is always 2. Product_type may be 1 for a\n" +"workstation, 2 for a domain controller, 3 for a server.\n" +"Platform_version is a 3-tuple containing a version number that is\n" +"intended for identifying the OS rather than feature detection."); + +#define SYS_GETWINDOWSVERSION_METHODDEF \ + {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS, sys_getwindowsversion__doc__}, + +static PyObject * +sys_getwindowsversion_impl(PyObject *module); + +static PyObject * +sys_getwindowsversion(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getwindowsversion_impl(module); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(sys__enablelegacywindowsfsencoding__doc__, +"_enablelegacywindowsfsencoding($module, /)\n" +"--\n" +"\n" +"Changes the default filesystem encoding to mbcs:replace.\n" +"\n" +"This is done for consistency with earlier versions of Python. See PEP\n" +"529 for more information.\n" +"\n" +"This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING\n" +"environment variable before launching Python."); + +#define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF \ + {"_enablelegacywindowsfsencoding", (PyCFunction)sys__enablelegacywindowsfsencoding, METH_NOARGS, sys__enablelegacywindowsfsencoding__doc__}, + +static PyObject * +sys__enablelegacywindowsfsencoding_impl(PyObject *module); + +static PyObject * +sys__enablelegacywindowsfsencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__enablelegacywindowsfsencoding_impl(module); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(HAVE_DLOPEN) + +PyDoc_STRVAR(sys_setdlopenflags__doc__, +"setdlopenflags($module, flags, /)\n" +"--\n" +"\n" +"Set the flags used by the interpreter for dlopen calls.\n" +"\n" +"This is used, for example, when the interpreter loads extension\n" +"modules. Among other things, this will enable a lazy resolving of\n" +"symbols when importing a module, if called as sys.setdlopenflags(0).\n" +"To share symbols across extension modules, call as\n" +"sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag\n" +"modules can be found in the os module (RTLD_xxx constants, e.g.\n" +"os.RTLD_LAZY)."); + +#define SYS_SETDLOPENFLAGS_METHODDEF \ + {"setdlopenflags", (PyCFunction)sys_setdlopenflags, METH_O, sys_setdlopenflags__doc__}, + +static PyObject * +sys_setdlopenflags_impl(PyObject *module, int new_val); + +static PyObject * +sys_setdlopenflags(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; + } + new_val = _PyLong_AsInt(arg); + if (new_val == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = sys_setdlopenflags_impl(module, new_val); + +exit: + return return_value; +} + +#endif /* defined(HAVE_DLOPEN) */ + +#if defined(HAVE_DLOPEN) + +PyDoc_STRVAR(sys_getdlopenflags__doc__, +"getdlopenflags($module, /)\n" +"--\n" +"\n" +"Return the current value of the flags that are used for dlopen calls.\n" +"\n" +"The flag constants are defined in the os module."); + +#define SYS_GETDLOPENFLAGS_METHODDEF \ + {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS, sys_getdlopenflags__doc__}, + +static PyObject * +sys_getdlopenflags_impl(PyObject *module); + +static PyObject * +sys_getdlopenflags(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getdlopenflags_impl(module); +} + +#endif /* defined(HAVE_DLOPEN) */ + +#if defined(USE_MALLOPT) + +PyDoc_STRVAR(sys_mdebug__doc__, +"mdebug($module, flag, /)\n" +"--\n" +"\n"); + +#define SYS_MDEBUG_METHODDEF \ + {"mdebug", (PyCFunction)sys_mdebug, METH_O, sys_mdebug__doc__}, + +static PyObject * +sys_mdebug_impl(PyObject *module, int flag); + +static PyObject * +sys_mdebug(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flag = _PyLong_AsInt(arg); + if (flag == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = sys_mdebug_impl(module, flag); + +exit: + return return_value; +} + +#endif /* defined(USE_MALLOPT) */ + +PyDoc_STRVAR(sys_getrefcount__doc__, +"getrefcount($module, object, /)\n" +"--\n" +"\n" +"Return the reference count of object.\n" +"\n" +"The count returned is generally one higher than you might expect,\n" +"because it includes the (temporary) reference as an argument to\n" +"getrefcount()."); + +#define SYS_GETREFCOUNT_METHODDEF \ + {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, sys_getrefcount__doc__}, + +static Py_ssize_t +sys_getrefcount_impl(PyObject *module, PyObject *object); + +static PyObject * +sys_getrefcount(PyObject *module, PyObject *object) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = sys_getrefcount_impl(module, object); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +#if defined(Py_REF_DEBUG) + +PyDoc_STRVAR(sys_gettotalrefcount__doc__, +"gettotalrefcount($module, /)\n" +"--\n" +"\n"); + +#define SYS_GETTOTALREFCOUNT_METHODDEF \ + {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS, sys_gettotalrefcount__doc__}, + +static Py_ssize_t +sys_gettotalrefcount_impl(PyObject *module); + +static PyObject * +sys_gettotalrefcount(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = sys_gettotalrefcount_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +#endif /* defined(Py_REF_DEBUG) */ + +PyDoc_STRVAR(sys_getallocatedblocks__doc__, +"getallocatedblocks($module, /)\n" +"--\n" +"\n" +"Return the number of memory blocks currently allocated."); + +#define SYS_GETALLOCATEDBLOCKS_METHODDEF \ + {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, sys_getallocatedblocks__doc__}, + +static Py_ssize_t +sys_getallocatedblocks_impl(PyObject *module); + +static PyObject * +sys_getallocatedblocks(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = sys_getallocatedblocks_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +#if defined(COUNT_ALLOCS) + +PyDoc_STRVAR(sys_getcounts__doc__, +"getcounts($module, /)\n" +"--\n" +"\n"); + +#define SYS_GETCOUNTS_METHODDEF \ + {"getcounts", (PyCFunction)sys_getcounts, METH_NOARGS, sys_getcounts__doc__}, + +static PyObject * +sys_getcounts_impl(PyObject *module); + +static PyObject * +sys_getcounts(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getcounts_impl(module); +} + +#endif /* defined(COUNT_ALLOCS) */ + +PyDoc_STRVAR(sys__getframe__doc__, +"_getframe($module, depth=0, /)\n" +"--\n" +"\n" +"Return a frame object from the call stack.\n" +"\n" +"If optional integer depth is given, return the frame object that many\n" +"calls below the top of the stack. If that is deeper than the call\n" +"stack, ValueError is raised. The default for depth is zero, returning\n" +"the frame at the top of the call stack.\n" +"\n" +"This function should be used for internal and specialized purposes\n" +"only."); + +#define SYS__GETFRAME_METHODDEF \ + {"_getframe", (PyCFunction)(void(*)(void))sys__getframe, METH_FASTCALL, sys__getframe__doc__}, + +static PyObject * +sys__getframe_impl(PyObject *module, int depth); + +static PyObject * +sys__getframe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int depth = 0; + + if (!_PyArg_CheckPositional("_getframe", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + depth = _PyLong_AsInt(args[0]); + if (depth == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = sys__getframe_impl(module, depth); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys__current_frames__doc__, +"_current_frames($module, /)\n" +"--\n" +"\n" +"Return a dict mapping each thread\'s thread id to its current stack frame.\n" +"\n" +"This function should be used for specialized purposes only."); + +#define SYS__CURRENT_FRAMES_METHODDEF \ + {"_current_frames", (PyCFunction)sys__current_frames, METH_NOARGS, sys__current_frames__doc__}, + +static PyObject * +sys__current_frames_impl(PyObject *module); + +static PyObject * +sys__current_frames(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__current_frames_impl(module); +} + +PyDoc_STRVAR(sys_call_tracing__doc__, +"call_tracing($module, func, args, /)\n" +"--\n" +"\n" +"Call func(*args), while tracing is enabled.\n" +"\n" +"The tracing state is saved, and restored afterwards. This is intended\n" +"to be called from a debugger from a checkpoint, to recursively debug\n" +"some other code."); + +#define SYS_CALL_TRACING_METHODDEF \ + {"call_tracing", (PyCFunction)(void(*)(void))sys_call_tracing, METH_FASTCALL, sys_call_tracing__doc__}, + +static PyObject * +sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs); + +static PyObject * +sys_call_tracing(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *func; + PyObject *funcargs; + + if (!_PyArg_CheckPositional("call_tracing", nargs, 2, 2)) { + goto exit; + } + func = args[0]; + if (!PyTuple_Check(args[1])) { + _PyArg_BadArgument("call_tracing", "argument 2", "tuple", args[1]); + goto exit; + } + funcargs = args[1]; + return_value = sys_call_tracing_impl(module, func, funcargs); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_callstats__doc__, +"callstats($module, /)\n" +"--\n" +"\n" +"Return a tuple of function call statistics.\n" +"\n" +"A tuple is returned only if CALL_PROFILE was defined when Python was\n" +"built. Otherwise, this returns None.\n" +"\n" +"When enabled, this function returns detailed, implementation-specific\n" +"details about the number of function calls executed. The return value\n" +"is a 11-tuple where the entries in the tuple are counts of:\n" +"0. all function calls\n" +"1. calls to PyFunction_Type objects\n" +"2. PyFunction calls that do not create an argument tuple\n" +"3. PyFunction calls that do not create an argument tuple\n" +" and bypass PyEval_EvalCodeEx()\n" +"4. PyMethod calls\n" +"5. PyMethod calls on bound methods\n" +"6. PyType calls\n" +"7. PyCFunction calls\n" +"8. generator calls\n" +"9. All other calls\n" +"10. Number of stack pops performed by call_function()"); + +#define SYS_CALLSTATS_METHODDEF \ + {"callstats", (PyCFunction)sys_callstats, METH_NOARGS, sys_callstats__doc__}, + +static PyObject * +sys_callstats_impl(PyObject *module); + +static PyObject * +sys_callstats(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_callstats_impl(module); +} + +PyDoc_STRVAR(sys__debugmallocstats__doc__, +"_debugmallocstats($module, /)\n" +"--\n" +"\n" +"Print summary info to stderr about the state of pymalloc\'s structures.\n" +"\n" +"In Py_DEBUG mode, also perform some expensive internal consistency\n" +"checks."); + +#define SYS__DEBUGMALLOCSTATS_METHODDEF \ + {"_debugmallocstats", (PyCFunction)sys__debugmallocstats, METH_NOARGS, sys__debugmallocstats__doc__}, + +static PyObject * +sys__debugmallocstats_impl(PyObject *module); + +static PyObject * +sys__debugmallocstats(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__debugmallocstats_impl(module); +} + +PyDoc_STRVAR(sys__clear_type_cache__doc__, +"_clear_type_cache($module, /)\n" +"--\n" +"\n" +"Clear the internal type lookup cache."); + +#define SYS__CLEAR_TYPE_CACHE_METHODDEF \ + {"_clear_type_cache", (PyCFunction)sys__clear_type_cache, METH_NOARGS, sys__clear_type_cache__doc__}, + +static PyObject * +sys__clear_type_cache_impl(PyObject *module); + +static PyObject * +sys__clear_type_cache(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__clear_type_cache_impl(module); +} + +PyDoc_STRVAR(sys_is_finalizing__doc__, +"is_finalizing($module, /)\n" +"--\n" +"\n" +"Return True if Python is exiting."); + +#define SYS_IS_FINALIZING_METHODDEF \ + {"is_finalizing", (PyCFunction)sys_is_finalizing, METH_NOARGS, sys_is_finalizing__doc__}, + +static PyObject * +sys_is_finalizing_impl(PyObject *module); + +static PyObject * +sys_is_finalizing(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_is_finalizing_impl(module); +} + +#if defined(ANDROID_API_LEVEL) + +PyDoc_STRVAR(sys_getandroidapilevel__doc__, +"getandroidapilevel($module, /)\n" +"--\n" +"\n" +"Return the build time API version of Android as an integer."); + +#define SYS_GETANDROIDAPILEVEL_METHODDEF \ + {"getandroidapilevel", (PyCFunction)sys_getandroidapilevel, METH_NOARGS, sys_getandroidapilevel__doc__}, + +static PyObject * +sys_getandroidapilevel_impl(PyObject *module); + +static PyObject * +sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_getandroidapilevel_impl(module); +} + +#endif /* defined(ANDROID_API_LEVEL) */ + +#ifndef SYS_GETWINDOWSVERSION_METHODDEF + #define SYS_GETWINDOWSVERSION_METHODDEF +#endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ + +#ifndef SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF + #define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF +#endif /* !defined(SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF) */ + +#ifndef SYS_SETDLOPENFLAGS_METHODDEF + #define SYS_SETDLOPENFLAGS_METHODDEF +#endif /* !defined(SYS_SETDLOPENFLAGS_METHODDEF) */ + +#ifndef SYS_GETDLOPENFLAGS_METHODDEF + #define SYS_GETDLOPENFLAGS_METHODDEF +#endif /* !defined(SYS_GETDLOPENFLAGS_METHODDEF) */ + +#ifndef SYS_MDEBUG_METHODDEF + #define SYS_MDEBUG_METHODDEF +#endif /* !defined(SYS_MDEBUG_METHODDEF) */ + +#ifndef SYS_GETTOTALREFCOUNT_METHODDEF + #define SYS_GETTOTALREFCOUNT_METHODDEF +#endif /* !defined(SYS_GETTOTALREFCOUNT_METHODDEF) */ + +#ifndef SYS_GETCOUNTS_METHODDEF + #define SYS_GETCOUNTS_METHODDEF +#endif /* !defined(SYS_GETCOUNTS_METHODDEF) */ + +#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF + #define SYS_GETANDROIDAPILEVEL_METHODDEF +#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ +/*[clinic end generated code: output=273f9cec8bfcab91 input=a9049054013a1b77]*/ diff --git a/python/Python/clinic/traceback.c.h b/python/Python/clinic/traceback.c.h new file mode 100755 index 0000000..04daf2a --- /dev/null +++ b/python/Python/clinic/traceback.c.h @@ -0,0 +1,62 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(tb_new__doc__, +"TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" +"--\n" +"\n" +"Create a new traceback object."); + +static PyObject * +tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame, + int tb_lasti, int tb_lineno); + +static PyObject * +tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "TracebackType", 0}; + PyObject *argsbuf[4]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *tb_next; + PyFrameObject *tb_frame; + int tb_lasti; + int tb_lineno; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 4, 4, 0, argsbuf); + if (!fastargs) { + goto exit; + } + tb_next = fastargs[0]; + if (!PyObject_TypeCheck(fastargs[1], &PyFrame_Type)) { + _PyArg_BadArgument("TracebackType", "argument 'tb_frame'", (&PyFrame_Type)->tp_name, fastargs[1]); + goto exit; + } + tb_frame = (PyFrameObject *)fastargs[1]; + if (PyFloat_Check(fastargs[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + tb_lasti = _PyLong_AsInt(fastargs[2]); + if (tb_lasti == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(fastargs[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + tb_lineno = _PyLong_AsInt(fastargs[3]); + if (tb_lineno == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = tb_new_impl(type, tb_next, tb_frame, tb_lasti, tb_lineno); + +exit: + return return_value; +} +/*[clinic end generated code: output=3def6c06248feed8 input=a9049054013a1b77]*/ diff --git a/python/Python/codecs.c b/python/Python/codecs.c new file mode 100755 index 0000000..4bd28ec --- /dev/null +++ b/python/Python/codecs.c @@ -0,0 +1,1539 @@ +/* ------------------------------------------------------------------------ + + Python Codec Registry and support functions + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +Copyright (c) Corporation for National Research Initiatives. + + ------------------------------------------------------------------------ */ + +#include "Python.h" +#include "pycore_pystate.h" +#include "ucnhash.h" +#include + +const char *Py_hexdigits = "0123456789abcdef"; + +/* --- Codec Registry ----------------------------------------------------- */ + +/* Import the standard encodings package which will register the first + codec search function. + + This is done in a lazy way so that the Unicode implementation does + not downgrade startup time of scripts not needing it. + + ImportErrors are silently ignored by this function. Only one try is + made. + +*/ + +static int _PyCodecRegistry_Init(void); /* Forward */ + +int PyCodec_Register(PyObject *search_function) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) + goto onError; + if (search_function == NULL) { + PyErr_BadArgument(); + goto onError; + } + if (!PyCallable_Check(search_function)) { + PyErr_SetString(PyExc_TypeError, "argument must be callable"); + goto onError; + } + return PyList_Append(interp->codec_search_path, search_function); + + onError: + return -1; +} + +/* Convert a string to a normalized Python string: all characters are + converted to lower case, spaces are replaced with underscores. */ + +static +PyObject *normalizestring(const char *string) +{ + size_t i; + size_t len = strlen(string); + char *p; + PyObject *v; + + if (len > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, "string is too large"); + return NULL; + } + + p = PyMem_Malloc(len + 1); + if (p == NULL) + return PyErr_NoMemory(); + for (i = 0; i < len; i++) { + char ch = string[i]; + if (ch == ' ') + ch = '-'; + else + ch = Py_TOLOWER(Py_CHARMASK(ch)); + p[i] = ch; + } + p[i] = '\0'; + v = PyUnicode_FromString(p); + PyMem_Free(p); + return v; +} + +/* Lookup the given encoding and return a tuple providing the codec + facilities. + + The encoding string is looked up converted to all lower-case + characters. This makes encodings looked up through this mechanism + effectively case-insensitive. + + If no codec is found, a LookupError is set and NULL returned. + + As side effect, this tries to load the encodings package, if not + yet done. This is part of the lazy load strategy for the encodings + package. + +*/ + +PyObject *_PyCodec_Lookup(const char *encoding) +{ + PyObject *result, *args = NULL, *v; + Py_ssize_t i, len; + + if (encoding == NULL) { + PyErr_BadArgument(); + goto onError; + } + + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) + goto onError; + + /* Convert the encoding to a normalized Python string: all + characters are converted to lower case, spaces and hyphens are + replaced with underscores. */ + v = normalizestring(encoding); + if (v == NULL) + goto onError; + PyUnicode_InternInPlace(&v); + + /* First, try to lookup the name in the registry dictionary */ + result = PyDict_GetItemWithError(interp->codec_search_cache, v); + if (result != NULL) { + Py_INCREF(result); + Py_DECREF(v); + return result; + } + else if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + + /* Next, scan the search functions in order of registration */ + args = PyTuple_New(1); + if (args == NULL) { + Py_DECREF(v); + return NULL; + } + PyTuple_SET_ITEM(args,0,v); + + len = PyList_Size(interp->codec_search_path); + if (len < 0) + goto onError; + if (len == 0) { + PyErr_SetString(PyExc_LookupError, + "no codec search functions registered: " + "can't find encoding"); + goto onError; + } + + for (i = 0; i < len; i++) { + PyObject *func; + + func = PyList_GetItem(interp->codec_search_path, i); + if (func == NULL) + goto onError; + result = PyEval_CallObject(func, args); + if (result == NULL) + goto onError; + if (result == Py_None) { + Py_DECREF(result); + continue; + } + if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) { + PyErr_SetString(PyExc_TypeError, + "codec search functions must return 4-tuples"); + Py_DECREF(result); + goto onError; + } + break; + } + if (i == len) { + /* XXX Perhaps we should cache misses too ? */ + PyErr_Format(PyExc_LookupError, + "unknown encoding: %s", encoding); + goto onError; + } + + /* Cache and return the result */ + if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) { + Py_DECREF(result); + goto onError; + } + Py_DECREF(args); + return result; + + onError: + Py_XDECREF(args); + return NULL; +} + +int _PyCodec_Forget(const char *encoding) +{ + PyObject *v; + int result; + + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (interp->codec_search_path == NULL) { + return -1; + } + + /* Convert the encoding to a normalized Python string: all + characters are converted to lower case, spaces and hyphens are + replaced with underscores. */ + v = normalizestring(encoding); + if (v == NULL) { + return -1; + } + + /* Drop the named codec from the internal cache */ + result = PyDict_DelItem(interp->codec_search_cache, v); + Py_DECREF(v); + + return result; +} + +/* Codec registry encoding check API. */ + +int PyCodec_KnownEncoding(const char *encoding) +{ + PyObject *codecs; + + codecs = _PyCodec_Lookup(encoding); + if (!codecs) { + PyErr_Clear(); + return 0; + } + else { + Py_DECREF(codecs); + return 1; + } +} + +static +PyObject *args_tuple(PyObject *object, + const char *errors) +{ + PyObject *args; + + args = PyTuple_New(1 + (errors != NULL)); + if (args == NULL) + return NULL; + Py_INCREF(object); + PyTuple_SET_ITEM(args,0,object); + if (errors) { + PyObject *v; + + v = PyUnicode_FromString(errors); + if (v == NULL) { + Py_DECREF(args); + return NULL; + } + PyTuple_SET_ITEM(args, 1, v); + } + return args; +} + +/* Helper function to get a codec item */ + +static +PyObject *codec_getitem(const char *encoding, int index) +{ + PyObject *codecs; + PyObject *v; + + codecs = _PyCodec_Lookup(encoding); + if (codecs == NULL) + return NULL; + v = PyTuple_GET_ITEM(codecs, index); + Py_DECREF(codecs); + Py_INCREF(v); + return v; +} + +/* Helper functions to create an incremental codec. */ +static +PyObject *codec_makeincrementalcodec(PyObject *codec_info, + const char *errors, + const char *attrname) +{ + PyObject *ret, *inccodec; + + inccodec = PyObject_GetAttrString(codec_info, attrname); + if (inccodec == NULL) + return NULL; + if (errors) + ret = PyObject_CallFunction(inccodec, "s", errors); + else + ret = _PyObject_CallNoArg(inccodec); + Py_DECREF(inccodec); + return ret; +} + +static +PyObject *codec_getincrementalcodec(const char *encoding, + const char *errors, + const char *attrname) +{ + PyObject *codec_info, *ret; + + codec_info = _PyCodec_Lookup(encoding); + if (codec_info == NULL) + return NULL; + ret = codec_makeincrementalcodec(codec_info, errors, attrname); + Py_DECREF(codec_info); + return ret; +} + +/* Helper function to create a stream codec. */ + +static +PyObject *codec_getstreamcodec(const char *encoding, + PyObject *stream, + const char *errors, + const int index) +{ + PyObject *codecs, *streamcodec, *codeccls; + + codecs = _PyCodec_Lookup(encoding); + if (codecs == NULL) + return NULL; + + codeccls = PyTuple_GET_ITEM(codecs, index); + if (errors != NULL) + streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors); + else + streamcodec = PyObject_CallFunctionObjArgs(codeccls, stream, NULL); + Py_DECREF(codecs); + return streamcodec; +} + +/* Helpers to work with the result of _PyCodec_Lookup + + */ +PyObject *_PyCodecInfo_GetIncrementalDecoder(PyObject *codec_info, + const char *errors) +{ + return codec_makeincrementalcodec(codec_info, errors, + "incrementaldecoder"); +} + +PyObject *_PyCodecInfo_GetIncrementalEncoder(PyObject *codec_info, + const char *errors) +{ + return codec_makeincrementalcodec(codec_info, errors, + "incrementalencoder"); +} + + +/* Convenience APIs to query the Codec registry. + + All APIs return a codec object with incremented refcount. + + */ + +PyObject *PyCodec_Encoder(const char *encoding) +{ + return codec_getitem(encoding, 0); +} + +PyObject *PyCodec_Decoder(const char *encoding) +{ + return codec_getitem(encoding, 1); +} + +PyObject *PyCodec_IncrementalEncoder(const char *encoding, + const char *errors) +{ + return codec_getincrementalcodec(encoding, errors, "incrementalencoder"); +} + +PyObject *PyCodec_IncrementalDecoder(const char *encoding, + const char *errors) +{ + return codec_getincrementalcodec(encoding, errors, "incrementaldecoder"); +} + +PyObject *PyCodec_StreamReader(const char *encoding, + PyObject *stream, + const char *errors) +{ + return codec_getstreamcodec(encoding, stream, errors, 2); +} + +PyObject *PyCodec_StreamWriter(const char *encoding, + PyObject *stream, + const char *errors) +{ + return codec_getstreamcodec(encoding, stream, errors, 3); +} + +/* Helper that tries to ensure the reported exception chain indicates the + * codec that was invoked to trigger the failure without changing the type + * of the exception raised. + */ +static void +wrap_codec_error(const char *operation, + const char *encoding) +{ + /* TrySetFromCause will replace the active exception with a suitably + * updated clone if it can, otherwise it will leave the original + * exception alone. + */ + _PyErr_TrySetFromCause("%s with '%s' codec failed", + operation, encoding); +} + +/* Encode an object (e.g. a Unicode object) using the given encoding + and return the resulting encoded object (usually a Python string). + + errors is passed to the encoder factory as argument if non-NULL. */ + +static PyObject * +_PyCodec_EncodeInternal(PyObject *object, + PyObject *encoder, + const char *encoding, + const char *errors) +{ + PyObject *args = NULL, *result = NULL; + PyObject *v = NULL; + + args = args_tuple(object, errors); + if (args == NULL) + goto onError; + + result = PyEval_CallObject(encoder, args); + if (result == NULL) { + wrap_codec_error("encoding", encoding); + goto onError; + } + + if (!PyTuple_Check(result) || + PyTuple_GET_SIZE(result) != 2) { + PyErr_SetString(PyExc_TypeError, + "encoder must return a tuple (object, integer)"); + goto onError; + } + v = PyTuple_GET_ITEM(result,0); + Py_INCREF(v); + /* We don't check or use the second (integer) entry. */ + + Py_DECREF(args); + Py_DECREF(encoder); + Py_DECREF(result); + return v; + + onError: + Py_XDECREF(result); + Py_XDECREF(args); + Py_XDECREF(encoder); + return NULL; +} + +/* Decode an object (usually a Python string) using the given encoding + and return an equivalent object (e.g. a Unicode object). + + errors is passed to the decoder factory as argument if non-NULL. */ + +static PyObject * +_PyCodec_DecodeInternal(PyObject *object, + PyObject *decoder, + const char *encoding, + const char *errors) +{ + PyObject *args = NULL, *result = NULL; + PyObject *v; + + args = args_tuple(object, errors); + if (args == NULL) + goto onError; + + result = PyEval_CallObject(decoder,args); + if (result == NULL) { + wrap_codec_error("decoding", encoding); + goto onError; + } + if (!PyTuple_Check(result) || + PyTuple_GET_SIZE(result) != 2) { + PyErr_SetString(PyExc_TypeError, + "decoder must return a tuple (object,integer)"); + goto onError; + } + v = PyTuple_GET_ITEM(result,0); + Py_INCREF(v); + /* We don't check or use the second (integer) entry. */ + + Py_DECREF(args); + Py_DECREF(decoder); + Py_DECREF(result); + return v; + + onError: + Py_XDECREF(args); + Py_XDECREF(decoder); + Py_XDECREF(result); + return NULL; +} + +/* Generic encoding/decoding API */ +PyObject *PyCodec_Encode(PyObject *object, + const char *encoding, + const char *errors) +{ + PyObject *encoder; + + encoder = PyCodec_Encoder(encoding); + if (encoder == NULL) + return NULL; + + return _PyCodec_EncodeInternal(object, encoder, encoding, errors); +} + +PyObject *PyCodec_Decode(PyObject *object, + const char *encoding, + const char *errors) +{ + PyObject *decoder; + + decoder = PyCodec_Decoder(encoding); + if (decoder == NULL) + return NULL; + + return _PyCodec_DecodeInternal(object, decoder, encoding, errors); +} + +/* Text encoding/decoding API */ +PyObject * _PyCodec_LookupTextEncoding(const char *encoding, + const char *alternate_command) +{ + _Py_IDENTIFIER(_is_text_encoding); + PyObject *codec; + PyObject *attr; + int is_text_codec; + + codec = _PyCodec_Lookup(encoding); + if (codec == NULL) + return NULL; + + /* Backwards compatibility: assume any raw tuple describes a text + * encoding, and the same for anything lacking the private + * attribute. + */ + if (!PyTuple_CheckExact(codec)) { + if (_PyObject_LookupAttrId(codec, &PyId__is_text_encoding, &attr) < 0) { + Py_DECREF(codec); + return NULL; + } + if (attr != NULL) { + is_text_codec = PyObject_IsTrue(attr); + Py_DECREF(attr); + if (is_text_codec <= 0) { + Py_DECREF(codec); + if (!is_text_codec) + PyErr_Format(PyExc_LookupError, + "'%.400s' is not a text encoding; " + "use %s to handle arbitrary codecs", + encoding, alternate_command); + return NULL; + } + } + } + + /* This appears to be a valid text encoding */ + return codec; +} + + +static +PyObject *codec_getitem_checked(const char *encoding, + const char *alternate_command, + int index) +{ + PyObject *codec; + PyObject *v; + + codec = _PyCodec_LookupTextEncoding(encoding, alternate_command); + if (codec == NULL) + return NULL; + + v = PyTuple_GET_ITEM(codec, index); + Py_INCREF(v); + Py_DECREF(codec); + return v; +} + +static PyObject * _PyCodec_TextEncoder(const char *encoding) +{ + return codec_getitem_checked(encoding, "codecs.encode()", 0); +} + +static PyObject * _PyCodec_TextDecoder(const char *encoding) +{ + return codec_getitem_checked(encoding, "codecs.decode()", 1); +} + +PyObject *_PyCodec_EncodeText(PyObject *object, + const char *encoding, + const char *errors) +{ + PyObject *encoder; + + encoder = _PyCodec_TextEncoder(encoding); + if (encoder == NULL) + return NULL; + + return _PyCodec_EncodeInternal(object, encoder, encoding, errors); +} + +PyObject *_PyCodec_DecodeText(PyObject *object, + const char *encoding, + const char *errors) +{ + PyObject *decoder; + + decoder = _PyCodec_TextDecoder(encoding); + if (decoder == NULL) + return NULL; + + return _PyCodec_DecodeInternal(object, decoder, encoding, errors); +} + +/* Register the error handling callback function error under the name + name. This function will be called by the codec when it encounters + an unencodable characters/undecodable bytes and doesn't know the + callback name, when name is specified as the error parameter + in the call to the encode/decode function. + Return 0 on success, -1 on error */ +int PyCodec_RegisterError(const char *name, PyObject *error) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) + return -1; + if (!PyCallable_Check(error)) { + PyErr_SetString(PyExc_TypeError, "handler must be callable"); + return -1; + } + return PyDict_SetItemString(interp->codec_error_registry, + name, error); +} + +/* Lookup the error handling callback function registered under the + name error. As a special case NULL can be passed, in which case + the error handling callback for strict encoding will be returned. */ +PyObject *PyCodec_LookupError(const char *name) +{ + PyObject *handler = NULL; + + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) + return NULL; + + if (name==NULL) + name = "strict"; + handler = _PyDict_GetItemStringWithError(interp->codec_error_registry, name); + if (handler) { + Py_INCREF(handler); + } + else if (!PyErr_Occurred()) { + PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); + } + return handler; +} + +static void wrong_exception_type(PyObject *exc) +{ + PyErr_Format(PyExc_TypeError, + "don't know how to handle %.200s in error callback", + exc->ob_type->tp_name); +} + +PyObject *PyCodec_StrictErrors(PyObject *exc) +{ + if (PyExceptionInstance_Check(exc)) + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + else + PyErr_SetString(PyExc_TypeError, "codec must pass exception instance"); + return NULL; +} + + +PyObject *PyCodec_IgnoreErrors(PyObject *exc) +{ + Py_ssize_t end; + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + } + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + } + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { + if (PyUnicodeTranslateError_GetEnd(exc, &end)) + return NULL; + } + else { + wrong_exception_type(exc); + return NULL; + } + return Py_BuildValue("(Nn)", PyUnicode_New(0, 0), end); +} + + +PyObject *PyCodec_ReplaceErrors(PyObject *exc) +{ + Py_ssize_t start, end, i, len; + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { + PyObject *res; + int kind; + void *data; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + len = end - start; + res = PyUnicode_New(len, '?'); + if (res == NULL) + return NULL; + kind = PyUnicode_KIND(res); + data = PyUnicode_DATA(res); + for (i = 0; i < len; ++i) + PyUnicode_WRITE(kind, data, i, '?'); + assert(_PyUnicode_CheckConsistency(res, 1)); + return Py_BuildValue("(Nn)", res, end); + } + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + return Py_BuildValue("(Cn)", + (int)Py_UNICODE_REPLACEMENT_CHARACTER, + end); + } + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { + PyObject *res; + int kind; + void *data; + if (PyUnicodeTranslateError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeTranslateError_GetEnd(exc, &end)) + return NULL; + len = end - start; + res = PyUnicode_New(len, Py_UNICODE_REPLACEMENT_CHARACTER); + if (res == NULL) + return NULL; + kind = PyUnicode_KIND(res); + data = PyUnicode_DATA(res); + for (i=0; i < len; i++) + PyUnicode_WRITE(kind, data, i, Py_UNICODE_REPLACEMENT_CHARACTER); + assert(_PyUnicode_CheckConsistency(res, 1)); + return Py_BuildValue("(Nn)", res, end); + } + else { + wrong_exception_type(exc); + return NULL; + } +} + +PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) +{ + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { + PyObject *restuple; + PyObject *object; + Py_ssize_t i; + Py_ssize_t start; + Py_ssize_t end; + PyObject *res; + unsigned char *outp; + Py_ssize_t ressize; + Py_UCS4 ch; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + if (end - start > PY_SSIZE_T_MAX / (2+7+1)) + end = start + PY_SSIZE_T_MAX / (2+7+1); + for (i = start, ressize = 0; i < end; ++i) { + /* object is guaranteed to be "ready" */ + ch = PyUnicode_READ_CHAR(object, i); + if (ch<10) + ressize += 2+1+1; + else if (ch<100) + ressize += 2+2+1; + else if (ch<1000) + ressize += 2+3+1; + else if (ch<10000) + ressize += 2+4+1; + else if (ch<100000) + ressize += 2+5+1; + else if (ch<1000000) + ressize += 2+6+1; + else + ressize += 2+7+1; + } + /* allocate replacement */ + res = PyUnicode_New(ressize, 127); + if (res == NULL) { + Py_DECREF(object); + return NULL; + } + outp = PyUnicode_1BYTE_DATA(res); + /* generate replacement */ + for (i = start; i < end; ++i) { + int digits; + int base; + ch = PyUnicode_READ_CHAR(object, i); + *outp++ = '&'; + *outp++ = '#'; + if (ch<10) { + digits = 1; + base = 1; + } + else if (ch<100) { + digits = 2; + base = 10; + } + else if (ch<1000) { + digits = 3; + base = 100; + } + else if (ch<10000) { + digits = 4; + base = 1000; + } + else if (ch<100000) { + digits = 5; + base = 10000; + } + else if (ch<1000000) { + digits = 6; + base = 100000; + } + else { + digits = 7; + base = 1000000; + } + while (digits-->0) { + *outp++ = '0' + ch/base; + ch %= base; + base /= 10; + } + *outp++ = ';'; + } + assert(_PyUnicode_CheckConsistency(res, 1)); + restuple = Py_BuildValue("(Nn)", res, end); + Py_DECREF(object); + return restuple; + } + else { + wrong_exception_type(exc); + return NULL; + } +} + +PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) +{ + PyObject *object; + Py_ssize_t i; + Py_ssize_t start; + Py_ssize_t end; + PyObject *res; + unsigned char *outp; + int ressize; + Py_UCS4 c; + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { + const unsigned char *p; + if (PyUnicodeDecodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeDecodeError_GetObject(exc))) + return NULL; + p = (const unsigned char*)PyBytes_AS_STRING(object); + res = PyUnicode_New(4 * (end - start), 127); + if (res == NULL) { + Py_DECREF(object); + return NULL; + } + outp = PyUnicode_1BYTE_DATA(res); + for (i = start; i < end; i++, outp += 4) { + unsigned char c = p[i]; + outp[0] = '\\'; + outp[1] = 'x'; + outp[2] = Py_hexdigits[(c>>4)&0xf]; + outp[3] = Py_hexdigits[c&0xf]; + } + + assert(_PyUnicode_CheckConsistency(res, 1)); + Py_DECREF(object); + return Py_BuildValue("(Nn)", res, end); + } + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + } + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { + if (PyUnicodeTranslateError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeTranslateError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeTranslateError_GetObject(exc))) + return NULL; + } + else { + wrong_exception_type(exc); + return NULL; + } + + if (end - start > PY_SSIZE_T_MAX / (1+1+8)) + end = start + PY_SSIZE_T_MAX / (1+1+8); + for (i = start, ressize = 0; i < end; ++i) { + /* object is guaranteed to be "ready" */ + c = PyUnicode_READ_CHAR(object, i); + if (c >= 0x10000) { + ressize += 1+1+8; + } + else if (c >= 0x100) { + ressize += 1+1+4; + } + else + ressize += 1+1+2; + } + res = PyUnicode_New(ressize, 127); + if (res == NULL) { + Py_DECREF(object); + return NULL; + } + outp = PyUnicode_1BYTE_DATA(res); + for (i = start; i < end; ++i) { + c = PyUnicode_READ_CHAR(object, i); + *outp++ = '\\'; + if (c >= 0x00010000) { + *outp++ = 'U'; + *outp++ = Py_hexdigits[(c>>28)&0xf]; + *outp++ = Py_hexdigits[(c>>24)&0xf]; + *outp++ = Py_hexdigits[(c>>20)&0xf]; + *outp++ = Py_hexdigits[(c>>16)&0xf]; + *outp++ = Py_hexdigits[(c>>12)&0xf]; + *outp++ = Py_hexdigits[(c>>8)&0xf]; + } + else if (c >= 0x100) { + *outp++ = 'u'; + *outp++ = Py_hexdigits[(c>>12)&0xf]; + *outp++ = Py_hexdigits[(c>>8)&0xf]; + } + else + *outp++ = 'x'; + *outp++ = Py_hexdigits[(c>>4)&0xf]; + *outp++ = Py_hexdigits[c&0xf]; + } + + assert(_PyUnicode_CheckConsistency(res, 1)); + Py_DECREF(object); + return Py_BuildValue("(Nn)", res, end); +} + +static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL; + +PyObject *PyCodec_NameReplaceErrors(PyObject *exc) +{ + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { + PyObject *restuple; + PyObject *object; + Py_ssize_t i; + Py_ssize_t start; + Py_ssize_t end; + PyObject *res; + unsigned char *outp; + Py_ssize_t ressize; + int replsize; + Py_UCS4 c; + char buffer[256]; /* NAME_MAXLEN */ + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + if (!ucnhash_CAPI) { + /* load the unicode data module */ + ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import( + PyUnicodeData_CAPSULE_NAME, 1); + if (!ucnhash_CAPI) + return NULL; + } + for (i = start, ressize = 0; i < end; ++i) { + /* object is guaranteed to be "ready" */ + c = PyUnicode_READ_CHAR(object, i); + if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) { + replsize = 1+1+1+(int)strlen(buffer)+1; + } + else if (c >= 0x10000) { + replsize = 1+1+8; + } + else if (c >= 0x100) { + replsize = 1+1+4; + } + else + replsize = 1+1+2; + if (ressize > PY_SSIZE_T_MAX - replsize) + break; + ressize += replsize; + } + end = i; + res = PyUnicode_New(ressize, 127); + if (res==NULL) + return NULL; + for (i = start, outp = PyUnicode_1BYTE_DATA(res); + i < end; ++i) { + c = PyUnicode_READ_CHAR(object, i); + *outp++ = '\\'; + if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) { + *outp++ = 'N'; + *outp++ = '{'; + strcpy((char *)outp, buffer); + outp += strlen(buffer); + *outp++ = '}'; + continue; + } + if (c >= 0x00010000) { + *outp++ = 'U'; + *outp++ = Py_hexdigits[(c>>28)&0xf]; + *outp++ = Py_hexdigits[(c>>24)&0xf]; + *outp++ = Py_hexdigits[(c>>20)&0xf]; + *outp++ = Py_hexdigits[(c>>16)&0xf]; + *outp++ = Py_hexdigits[(c>>12)&0xf]; + *outp++ = Py_hexdigits[(c>>8)&0xf]; + } + else if (c >= 0x100) { + *outp++ = 'u'; + *outp++ = Py_hexdigits[(c>>12)&0xf]; + *outp++ = Py_hexdigits[(c>>8)&0xf]; + } + else + *outp++ = 'x'; + *outp++ = Py_hexdigits[(c>>4)&0xf]; + *outp++ = Py_hexdigits[c&0xf]; + } + + assert(outp == PyUnicode_1BYTE_DATA(res) + ressize); + assert(_PyUnicode_CheckConsistency(res, 1)); + restuple = Py_BuildValue("(Nn)", res, end); + Py_DECREF(object); + return restuple; + } + else { + wrong_exception_type(exc); + return NULL; + } +} + +#define ENC_UNKNOWN -1 +#define ENC_UTF8 0 +#define ENC_UTF16BE 1 +#define ENC_UTF16LE 2 +#define ENC_UTF32BE 3 +#define ENC_UTF32LE 4 + +static int +get_standard_encoding(const char *encoding, int *bytelength) +{ + if (Py_TOLOWER(encoding[0]) == 'u' && + Py_TOLOWER(encoding[1]) == 't' && + Py_TOLOWER(encoding[2]) == 'f') { + encoding += 3; + if (*encoding == '-' || *encoding == '_' ) + encoding++; + if (encoding[0] == '8' && encoding[1] == '\0') { + *bytelength = 3; + return ENC_UTF8; + } + else if (encoding[0] == '1' && encoding[1] == '6') { + encoding += 2; + *bytelength = 2; + if (*encoding == '\0') { +#ifdef WORDS_BIGENDIAN + return ENC_UTF16BE; +#else + return ENC_UTF16LE; +#endif + } + if (*encoding == '-' || *encoding == '_' ) + encoding++; + if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') { + if (Py_TOLOWER(encoding[0]) == 'b') + return ENC_UTF16BE; + if (Py_TOLOWER(encoding[0]) == 'l') + return ENC_UTF16LE; + } + } + else if (encoding[0] == '3' && encoding[1] == '2') { + encoding += 2; + *bytelength = 4; + if (*encoding == '\0') { +#ifdef WORDS_BIGENDIAN + return ENC_UTF32BE; +#else + return ENC_UTF32LE; +#endif + } + if (*encoding == '-' || *encoding == '_' ) + encoding++; + if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') { + if (Py_TOLOWER(encoding[0]) == 'b') + return ENC_UTF32BE; + if (Py_TOLOWER(encoding[0]) == 'l') + return ENC_UTF32LE; + } + } + } + else if (strcmp(encoding, "CP_UTF8") == 0) { + *bytelength = 3; + return ENC_UTF8; + } + return ENC_UNKNOWN; +} + +/* This handler is declared static until someone demonstrates + a need to call it directly. */ +static PyObject * +PyCodec_SurrogatePassErrors(PyObject *exc) +{ + PyObject *restuple; + PyObject *object; + PyObject *encode; + const char *encoding; + int code; + int bytelength; + Py_ssize_t i; + Py_ssize_t start; + Py_ssize_t end; + PyObject *res; + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { + unsigned char *outp; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + if (!(encode = PyUnicodeEncodeError_GetEncoding(exc))) { + Py_DECREF(object); + return NULL; + } + if (!(encoding = PyUnicode_AsUTF8(encode))) { + Py_DECREF(object); + Py_DECREF(encode); + return NULL; + } + code = get_standard_encoding(encoding, &bytelength); + Py_DECREF(encode); + if (code == ENC_UNKNOWN) { + /* Not supported, fail with original exception */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + Py_DECREF(object); + return NULL; + } + + if (end - start > PY_SSIZE_T_MAX / bytelength) + end = start + PY_SSIZE_T_MAX / bytelength; + res = PyBytes_FromStringAndSize(NULL, bytelength*(end-start)); + if (!res) { + Py_DECREF(object); + return NULL; + } + outp = (unsigned char*)PyBytes_AsString(res); + for (i = start; i < end; i++) { + /* object is guaranteed to be "ready" */ + Py_UCS4 ch = PyUnicode_READ_CHAR(object, i); + if (!Py_UNICODE_IS_SURROGATE(ch)) { + /* Not a surrogate, fail with original exception */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + Py_DECREF(res); + Py_DECREF(object); + return NULL; + } + switch (code) { + case ENC_UTF8: + *outp++ = (unsigned char)(0xe0 | (ch >> 12)); + *outp++ = (unsigned char)(0x80 | ((ch >> 6) & 0x3f)); + *outp++ = (unsigned char)(0x80 | (ch & 0x3f)); + break; + case ENC_UTF16LE: + *outp++ = (unsigned char) ch; + *outp++ = (unsigned char)(ch >> 8); + break; + case ENC_UTF16BE: + *outp++ = (unsigned char)(ch >> 8); + *outp++ = (unsigned char) ch; + break; + case ENC_UTF32LE: + *outp++ = (unsigned char) ch; + *outp++ = (unsigned char)(ch >> 8); + *outp++ = (unsigned char)(ch >> 16); + *outp++ = (unsigned char)(ch >> 24); + break; + case ENC_UTF32BE: + *outp++ = (unsigned char)(ch >> 24); + *outp++ = (unsigned char)(ch >> 16); + *outp++ = (unsigned char)(ch >> 8); + *outp++ = (unsigned char) ch; + break; + } + } + restuple = Py_BuildValue("(On)", res, end); + Py_DECREF(res); + Py_DECREF(object); + return restuple; + } + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { + const unsigned char *p; + Py_UCS4 ch = 0; + if (PyUnicodeDecodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeDecodeError_GetObject(exc))) + return NULL; + p = (const unsigned char*)PyBytes_AS_STRING(object); + if (!(encode = PyUnicodeDecodeError_GetEncoding(exc))) { + Py_DECREF(object); + return NULL; + } + if (!(encoding = PyUnicode_AsUTF8(encode))) { + Py_DECREF(object); + Py_DECREF(encode); + return NULL; + } + code = get_standard_encoding(encoding, &bytelength); + Py_DECREF(encode); + if (code == ENC_UNKNOWN) { + /* Not supported, fail with original exception */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + Py_DECREF(object); + return NULL; + } + + /* Try decoding a single surrogate character. If + there are more, let the codec call us again. */ + p += start; + if (PyBytes_GET_SIZE(object) - start >= bytelength) { + switch (code) { + case ENC_UTF8: + if ((p[0] & 0xf0) == 0xe0 && + (p[1] & 0xc0) == 0x80 && + (p[2] & 0xc0) == 0x80) { + /* it's a three-byte code */ + ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f); + } + break; + case ENC_UTF16LE: + ch = p[1] << 8 | p[0]; + break; + case ENC_UTF16BE: + ch = p[0] << 8 | p[1]; + break; + case ENC_UTF32LE: + ch = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]; + break; + case ENC_UTF32BE: + ch = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + break; + } + } + + Py_DECREF(object); + if (!Py_UNICODE_IS_SURROGATE(ch)) { + /* it's not a surrogate - fail */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + return NULL; + } + res = PyUnicode_FromOrdinal(ch); + if (res == NULL) + return NULL; + return Py_BuildValue("(Nn)", res, start + bytelength); + } + else { + wrong_exception_type(exc); + return NULL; + } +} + +static PyObject * +PyCodec_SurrogateEscapeErrors(PyObject *exc) +{ + PyObject *restuple; + PyObject *object; + Py_ssize_t i; + Py_ssize_t start; + Py_ssize_t end; + PyObject *res; + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { + char *outp; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + res = PyBytes_FromStringAndSize(NULL, end-start); + if (!res) { + Py_DECREF(object); + return NULL; + } + outp = PyBytes_AsString(res); + for (i = start; i < end; i++) { + /* object is guaranteed to be "ready" */ + Py_UCS4 ch = PyUnicode_READ_CHAR(object, i); + if (ch < 0xdc80 || ch > 0xdcff) { + /* Not a UTF-8b surrogate, fail with original exception */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + Py_DECREF(res); + Py_DECREF(object); + return NULL; + } + *outp++ = ch - 0xdc00; + } + restuple = Py_BuildValue("(On)", res, end); + Py_DECREF(res); + Py_DECREF(object); + return restuple; + } + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { + PyObject *str; + const unsigned char *p; + Py_UCS2 ch[4]; /* decode up to 4 bad bytes. */ + int consumed = 0; + if (PyUnicodeDecodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeDecodeError_GetObject(exc))) + return NULL; + p = (const unsigned char*)PyBytes_AS_STRING(object); + while (consumed < 4 && consumed < end-start) { + /* Refuse to escape ASCII bytes. */ + if (p[start+consumed] < 128) + break; + ch[consumed] = 0xdc00 + p[start+consumed]; + consumed++; + } + Py_DECREF(object); + if (!consumed) { + /* codec complained about ASCII byte. */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + return NULL; + } + str = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, ch, consumed); + if (str == NULL) + return NULL; + return Py_BuildValue("(Nn)", str, start+consumed); + } + else { + wrong_exception_type(exc); + return NULL; + } +} + + +static PyObject *strict_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_StrictErrors(exc); +} + + +static PyObject *ignore_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_IgnoreErrors(exc); +} + + +static PyObject *replace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_ReplaceErrors(exc); +} + + +static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_XMLCharRefReplaceErrors(exc); +} + + +static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_BackslashReplaceErrors(exc); +} + +static PyObject *namereplace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_NameReplaceErrors(exc); +} + +static PyObject *surrogatepass_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_SurrogatePassErrors(exc); +} + +static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_SurrogateEscapeErrors(exc); +} + +static int _PyCodecRegistry_Init(void) +{ + static struct { + const char *name; + PyMethodDef def; + } methods[] = + { + { + "strict", + { + "strict_errors", + strict_errors, + METH_O, + PyDoc_STR("Implements the 'strict' error handling, which " + "raises a UnicodeError on coding errors.") + } + }, + { + "ignore", + { + "ignore_errors", + ignore_errors, + METH_O, + PyDoc_STR("Implements the 'ignore' error handling, which " + "ignores malformed data and continues.") + } + }, + { + "replace", + { + "replace_errors", + replace_errors, + METH_O, + PyDoc_STR("Implements the 'replace' error handling, which " + "replaces malformed data with a replacement marker.") + } + }, + { + "xmlcharrefreplace", + { + "xmlcharrefreplace_errors", + xmlcharrefreplace_errors, + METH_O, + PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, " + "which replaces an unencodable character with the " + "appropriate XML character reference.") + } + }, + { + "backslashreplace", + { + "backslashreplace_errors", + backslashreplace_errors, + METH_O, + PyDoc_STR("Implements the 'backslashreplace' error handling, " + "which replaces malformed data with a backslashed " + "escape sequence.") + } + }, + { + "namereplace", + { + "namereplace_errors", + namereplace_errors, + METH_O, + PyDoc_STR("Implements the 'namereplace' error handling, " + "which replaces an unencodable character with a " + "\\N{...} escape sequence.") + } + }, + { + "surrogatepass", + { + "surrogatepass", + surrogatepass_errors, + METH_O + } + }, + { + "surrogateescape", + { + "surrogateescape", + surrogateescape_errors, + METH_O + } + } + }; + + PyInterpreterState *interp = _PyInterpreterState_Get(); + PyObject *mod; + unsigned i; + + if (interp->codec_search_path != NULL) + return 0; + + interp->codec_search_path = PyList_New(0); + interp->codec_search_cache = PyDict_New(); + interp->codec_error_registry = PyDict_New(); + + if (interp->codec_error_registry) { + for (i = 0; i < Py_ARRAY_LENGTH(methods); ++i) { + PyObject *func = PyCFunction_NewEx(&methods[i].def, NULL, NULL); + int res; + if (!func) + Py_FatalError("can't initialize codec error registry"); + res = PyCodec_RegisterError(methods[i].name, func); + Py_DECREF(func); + if (res) + Py_FatalError("can't initialize codec error registry"); + } + } + + if (interp->codec_search_path == NULL || + interp->codec_search_cache == NULL || + interp->codec_error_registry == NULL) + Py_FatalError("can't initialize codec registry"); + + mod = PyImport_ImportModuleNoBlock("encodings"); + if (mod == NULL) { + return -1; + } + Py_DECREF(mod); + interp->codecs_initialized = 1; + return 0; +} diff --git a/python/Python/compile.c b/python/Python/compile.c new file mode 100755 index 0000000..3259e8a --- /dev/null +++ b/python/Python/compile.c @@ -0,0 +1,6052 @@ +/* + * This file compiles an abstract syntax tree (AST) into Python bytecode. + * + * The primary entry point is PyAST_Compile(), which returns a + * PyCodeObject. The compiler makes several passes to build the code + * object: + * 1. Checks for future statements. See future.c + * 2. Builds a symbol table. See symtable.c. + * 3. Generate code for basic blocks. See compiler_mod() in this file. + * 4. Assemble the basic blocks into final code. See assemble() in + * this file. + * 5. Optimize the byte code (peephole optimizations). See peephole.c + * + * Note that compiler_mod() suggests module, but the module ast type + * (mod_ty) has cases for expressions and interactive statements. + * + * CAUTION: The VISIT_* macros abort the current function when they + * encounter a problem. So don't invoke them when there is memory + * which needs to be released. Code blocks are OK, as the compiler + * structure takes care of releasing those. Use the arena to manage + * objects. + */ + +#include "Python.h" + +#include "pycore_pystate.h" /* _PyInterpreterState_GET_UNSAFE() */ +#include "Python-ast.h" +#include "ast.h" +#include "code.h" +#include "symtable.h" +#include "opcode.h" +#include "wordcode_helpers.h" + +#define DEFAULT_BLOCK_SIZE 16 +#define DEFAULT_BLOCKS 8 +#define DEFAULT_CODE_SIZE 128 +#define DEFAULT_LNOTAB_SIZE 16 + +#define COMP_GENEXP 0 +#define COMP_LISTCOMP 1 +#define COMP_SETCOMP 2 +#define COMP_DICTCOMP 3 + +#define IS_TOP_LEVEL_AWAIT(c) ( \ + (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ + && (c->u->u_ste->ste_type == ModuleBlock)) + +struct instr { + unsigned i_jabs : 1; + unsigned i_jrel : 1; + unsigned char i_opcode; + int i_oparg; + struct basicblock_ *i_target; /* target block (if jump instruction) */ + int i_lineno; +}; + +typedef struct basicblock_ { + /* Each basicblock in a compilation unit is linked via b_list in the + reverse order that the block are allocated. b_list points to the next + block, not to be confused with b_next, which is next by control flow. */ + struct basicblock_ *b_list; + /* number of instructions used */ + int b_iused; + /* length of instruction array (b_instr) */ + int b_ialloc; + /* pointer to an array of instructions, initially NULL */ + struct instr *b_instr; + /* If b_next is non-NULL, it is a pointer to the next + block reached by normal control flow. */ + struct basicblock_ *b_next; + /* b_seen is used to perform a DFS of basicblocks. */ + unsigned b_seen : 1; + /* b_return is true if a RETURN_VALUE opcode is inserted. */ + unsigned b_return : 1; + /* depth of stack upon entry of block, computed by stackdepth() */ + int b_startdepth; + /* instruction offset for block, computed by assemble_jump_offsets() */ + int b_offset; +} basicblock; + +/* fblockinfo tracks the current frame block. + +A frame block is used to handle loops, try/except, and try/finally. +It's called a frame block to distinguish it from a basic block in the +compiler IR. +*/ + +enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_TRY2, FINALLY_END, + WITH, ASYNC_WITH, HANDLER_CLEANUP }; + +struct fblockinfo { + enum fblocktype fb_type; + basicblock *fb_block; + /* (optional) type-specific exit or cleanup block */ + basicblock *fb_exit; +}; + +enum { + COMPILER_SCOPE_MODULE, + COMPILER_SCOPE_CLASS, + COMPILER_SCOPE_FUNCTION, + COMPILER_SCOPE_ASYNC_FUNCTION, + COMPILER_SCOPE_LAMBDA, + COMPILER_SCOPE_COMPREHENSION, +}; + +/* The following items change on entry and exit of code blocks. + They must be saved and restored when returning to a block. +*/ +struct compiler_unit { + PySTEntryObject *u_ste; + + PyObject *u_name; + PyObject *u_qualname; /* dot-separated qualified name (lazy) */ + int u_scope_type; + + /* The following fields are dicts that map objects to + the index of them in co_XXX. The index is used as + the argument for opcodes that refer to those collections. + */ + PyObject *u_consts; /* all constants */ + PyObject *u_names; /* all names */ + PyObject *u_varnames; /* local variables */ + PyObject *u_cellvars; /* cell variables */ + PyObject *u_freevars; /* free variables */ + + PyObject *u_private; /* for private name mangling */ + + Py_ssize_t u_argcount; /* number of arguments for block */ + Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */ + Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */ + /* Pointer to the most recently allocated block. By following b_list + members, you can reach all early allocated blocks. */ + basicblock *u_blocks; + basicblock *u_curblock; /* pointer to current block */ + + int u_nfblocks; + struct fblockinfo u_fblock[CO_MAXBLOCKS]; + + int u_firstlineno; /* the first lineno of the block */ + int u_lineno; /* the lineno for the current stmt */ + int u_col_offset; /* the offset of the current stmt */ + int u_lineno_set; /* boolean to indicate whether instr + has been generated with current lineno */ +}; + +/* This struct captures the global state of a compilation. + +The u pointer points to the current compilation unit, while units +for enclosing blocks are stored in c_stack. The u and c_stack are +managed by compiler_enter_scope() and compiler_exit_scope(). + +Note that we don't track recursion levels during compilation - the +task of detecting and rejecting excessive levels of nesting is +handled by the symbol analysis pass. + +*/ + +struct compiler { + PyObject *c_filename; + struct symtable *c_st; + PyFutureFeatures *c_future; /* pointer to module's __future__ */ + PyCompilerFlags *c_flags; + + int c_optimize; /* optimization level */ + int c_interactive; /* true if in interactive mode */ + int c_nestlevel; + int c_do_not_emit_bytecode; /* The compiler won't emit any bytecode + if this value is different from zero. + This can be used to temporarily visit + nodes without emitting bytecode to + check only errors. */ + + PyObject *c_const_cache; /* Python dict holding all constants, + including names tuple */ + struct compiler_unit *u; /* compiler state for current block */ + PyObject *c_stack; /* Python list holding compiler_unit ptrs */ + PyArena *c_arena; /* pointer to memory allocation arena */ +}; + +static int compiler_enter_scope(struct compiler *, identifier, int, void *, int); +static void compiler_free(struct compiler *); +static basicblock *compiler_new_block(struct compiler *); +static int compiler_next_instr(struct compiler *, basicblock *); +static int compiler_addop(struct compiler *, int); +static int compiler_addop_i(struct compiler *, int, Py_ssize_t); +static int compiler_addop_j(struct compiler *, int, basicblock *, int); +static int compiler_error(struct compiler *, const char *); +static int compiler_warn(struct compiler *, const char *, ...); +static int compiler_nameop(struct compiler *, identifier, expr_context_ty); + +static PyCodeObject *compiler_mod(struct compiler *, mod_ty); +static int compiler_visit_stmt(struct compiler *, stmt_ty); +static int compiler_visit_keyword(struct compiler *, keyword_ty); +static int compiler_visit_expr(struct compiler *, expr_ty); +static int compiler_augassign(struct compiler *, stmt_ty); +static int compiler_annassign(struct compiler *, stmt_ty); +static int compiler_visit_slice(struct compiler *, slice_ty, + expr_context_ty); + +static int inplace_binop(struct compiler *, operator_ty); +static int expr_constant(expr_ty); + +static int compiler_with(struct compiler *, stmt_ty, int); +static int compiler_async_with(struct compiler *, stmt_ty, int); +static int compiler_async_for(struct compiler *, stmt_ty); +static int compiler_call_helper(struct compiler *c, int n, + asdl_seq *args, + asdl_seq *keywords); +static int compiler_try_except(struct compiler *, stmt_ty); +static int compiler_set_qualname(struct compiler *); + +static int compiler_sync_comprehension_generator( + struct compiler *c, + asdl_seq *generators, int gen_index, + expr_ty elt, expr_ty val, int type); + +static int compiler_async_comprehension_generator( + struct compiler *c, + asdl_seq *generators, int gen_index, + expr_ty elt, expr_ty val, int type); + +static PyCodeObject *assemble(struct compiler *, int addNone); +static PyObject *__doc__, *__annotations__; + +#define CAPSULE_NAME "compile.c compiler unit" + +PyObject * +_Py_Mangle(PyObject *privateobj, PyObject *ident) +{ + /* Name mangling: __private becomes _classname__private. + This is independent from how the name is used. */ + PyObject *result; + size_t nlen, plen, ipriv; + Py_UCS4 maxchar; + if (privateobj == NULL || !PyUnicode_Check(privateobj) || + PyUnicode_READ_CHAR(ident, 0) != '_' || + PyUnicode_READ_CHAR(ident, 1) != '_') { + Py_INCREF(ident); + return ident; + } + nlen = PyUnicode_GET_LENGTH(ident); + plen = PyUnicode_GET_LENGTH(privateobj); + /* Don't mangle __id__ or names with dots. + + The only time a name with a dot can occur is when + we are compiling an import statement that has a + package name. + + TODO(jhylton): Decide whether we want to support + mangling of the module name, e.g. __M.X. + */ + if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' && + PyUnicode_READ_CHAR(ident, nlen-2) == '_') || + PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) { + Py_INCREF(ident); + return ident; /* Don't mangle __whatever__ */ + } + /* Strip leading underscores from class name */ + ipriv = 0; + while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') + ipriv++; + if (ipriv == plen) { + Py_INCREF(ident); + return ident; /* Don't mangle if class is just underscores */ + } + plen -= ipriv; + + if (plen + nlen >= PY_SSIZE_T_MAX - 1) { + PyErr_SetString(PyExc_OverflowError, + "private identifier too large to be mangled"); + return NULL; + } + + maxchar = PyUnicode_MAX_CHAR_VALUE(ident); + if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar) + maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj); + + result = PyUnicode_New(1 + nlen + plen, maxchar); + if (!result) + return 0; + /* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */ + PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_'); + if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) { + Py_DECREF(result); + return NULL; + } + if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) { + Py_DECREF(result); + return NULL; + } + assert(_PyUnicode_CheckConsistency(result, 1)); + return result; +} + +static int +compiler_init(struct compiler *c) +{ + memset(c, 0, sizeof(struct compiler)); + + c->c_const_cache = PyDict_New(); + if (!c->c_const_cache) { + return 0; + } + + c->c_stack = PyList_New(0); + if (!c->c_stack) { + Py_CLEAR(c->c_const_cache); + return 0; + } + + return 1; +} + +PyCodeObject * +PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, + int optimize, PyArena *arena) +{ + struct compiler c; + PyCodeObject *co = NULL; + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; + int merged; + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; + + if (!__doc__) { + __doc__ = PyUnicode_InternFromString("__doc__"); + if (!__doc__) + return NULL; + } + if (!__annotations__) { + __annotations__ = PyUnicode_InternFromString("__annotations__"); + if (!__annotations__) + return NULL; + } + if (!compiler_init(&c)) + return NULL; + Py_INCREF(filename); + c.c_filename = filename; + c.c_arena = arena; + c.c_future = PyFuture_FromASTObject(mod, filename); + if (c.c_future == NULL) + goto finally; + if (!flags) { + flags = &local_flags; + } + merged = c.c_future->ff_features | flags->cf_flags; + c.c_future->ff_features = merged; + flags->cf_flags = merged; + c.c_flags = flags; + c.c_optimize = (optimize == -1) ? config->optimization_level : optimize; + c.c_nestlevel = 0; + c.c_do_not_emit_bytecode = 0; + + if (!_PyAST_Optimize(mod, arena, c.c_optimize)) { + goto finally; + } + + c.c_st = PySymtable_BuildObject(mod, filename, c.c_future); + if (c.c_st == NULL) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_SystemError, "no symtable"); + goto finally; + } + + co = compiler_mod(&c, mod); + + finally: + compiler_free(&c); + assert(co || PyErr_Occurred()); + return co; +} + +PyCodeObject * +PyAST_CompileEx(mod_ty mod, const char *filename_str, PyCompilerFlags *flags, + int optimize, PyArena *arena) +{ + PyObject *filename; + PyCodeObject *co; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + co = PyAST_CompileObject(mod, filename, flags, optimize, arena); + Py_DECREF(filename); + return co; + +} + +PyCodeObject * +PyNode_Compile(struct _node *n, const char *filename) +{ + PyCodeObject *co = NULL; + mod_ty mod; + PyArena *arena = PyArena_New(); + if (!arena) + return NULL; + mod = PyAST_FromNode(n, NULL, filename, arena); + if (mod) + co = PyAST_Compile(mod, filename, NULL, arena); + PyArena_Free(arena); + return co; +} + +static void +compiler_free(struct compiler *c) +{ + if (c->c_st) + PySymtable_Free(c->c_st); + if (c->c_future) + PyObject_Free(c->c_future); + Py_XDECREF(c->c_filename); + Py_DECREF(c->c_const_cache); + Py_DECREF(c->c_stack); +} + +static PyObject * +list2dict(PyObject *list) +{ + Py_ssize_t i, n; + PyObject *v, *k; + PyObject *dict = PyDict_New(); + if (!dict) return NULL; + + n = PyList_Size(list); + for (i = 0; i < n; i++) { + v = PyLong_FromSsize_t(i); + if (!v) { + Py_DECREF(dict); + return NULL; + } + k = PyList_GET_ITEM(list, i); + if (PyDict_SetItem(dict, k, v) < 0) { + Py_DECREF(v); + Py_DECREF(dict); + return NULL; + } + Py_DECREF(v); + } + return dict; +} + +/* Return new dict containing names from src that match scope(s). + +src is a symbol table dictionary. If the scope of a name matches +either scope_type or flag is set, insert it into the new dict. The +values are integers, starting at offset and increasing by one for +each key. +*/ + +static PyObject * +dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) +{ + Py_ssize_t i = offset, scope, num_keys, key_i; + PyObject *k, *v, *dest = PyDict_New(); + PyObject *sorted_keys; + + assert(offset >= 0); + if (dest == NULL) + return NULL; + + /* Sort the keys so that we have a deterministic order on the indexes + saved in the returned dictionary. These indexes are used as indexes + into the free and cell var storage. Therefore if they aren't + deterministic, then the generated bytecode is not deterministic. + */ + sorted_keys = PyDict_Keys(src); + if (sorted_keys == NULL) + return NULL; + if (PyList_Sort(sorted_keys) != 0) { + Py_DECREF(sorted_keys); + return NULL; + } + num_keys = PyList_GET_SIZE(sorted_keys); + + for (key_i = 0; key_i < num_keys; key_i++) { + /* XXX this should probably be a macro in symtable.h */ + long vi; + k = PyList_GET_ITEM(sorted_keys, key_i); + v = PyDict_GetItem(src, k); + assert(PyLong_Check(v)); + vi = PyLong_AS_LONG(v); + scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK; + + if (scope == scope_type || vi & flag) { + PyObject *item = PyLong_FromSsize_t(i); + if (item == NULL) { + Py_DECREF(sorted_keys); + Py_DECREF(dest); + return NULL; + } + i++; + if (PyDict_SetItem(dest, k, item) < 0) { + Py_DECREF(sorted_keys); + Py_DECREF(item); + Py_DECREF(dest); + return NULL; + } + Py_DECREF(item); + } + } + Py_DECREF(sorted_keys); + return dest; +} + +static void +compiler_unit_check(struct compiler_unit *u) +{ + basicblock *block; + for (block = u->u_blocks; block != NULL; block = block->b_list) { + assert((uintptr_t)block != 0xcbcbcbcbU); + assert((uintptr_t)block != 0xfbfbfbfbU); + assert((uintptr_t)block != 0xdbdbdbdbU); + if (block->b_instr != NULL) { + assert(block->b_ialloc > 0); + assert(block->b_iused > 0); + assert(block->b_ialloc >= block->b_iused); + } + else { + assert (block->b_iused == 0); + assert (block->b_ialloc == 0); + } + } +} + +static void +compiler_unit_free(struct compiler_unit *u) +{ + basicblock *b, *next; + + compiler_unit_check(u); + b = u->u_blocks; + while (b != NULL) { + if (b->b_instr) + PyObject_Free((void *)b->b_instr); + next = b->b_list; + PyObject_Free((void *)b); + b = next; + } + Py_CLEAR(u->u_ste); + Py_CLEAR(u->u_name); + Py_CLEAR(u->u_qualname); + Py_CLEAR(u->u_consts); + Py_CLEAR(u->u_names); + Py_CLEAR(u->u_varnames); + Py_CLEAR(u->u_freevars); + Py_CLEAR(u->u_cellvars); + Py_CLEAR(u->u_private); + PyObject_Free(u); +} + +static int +compiler_enter_scope(struct compiler *c, identifier name, + int scope_type, void *key, int lineno) +{ + struct compiler_unit *u; + basicblock *block; + + u = (struct compiler_unit *)PyObject_Malloc(sizeof( + struct compiler_unit)); + if (!u) { + PyErr_NoMemory(); + return 0; + } + memset(u, 0, sizeof(struct compiler_unit)); + u->u_scope_type = scope_type; + u->u_argcount = 0; + u->u_posonlyargcount = 0; + u->u_kwonlyargcount = 0; + u->u_ste = PySymtable_Lookup(c->c_st, key); + if (!u->u_ste) { + compiler_unit_free(u); + return 0; + } + Py_INCREF(name); + u->u_name = name; + u->u_varnames = list2dict(u->u_ste->ste_varnames); + u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0); + if (!u->u_varnames || !u->u_cellvars) { + compiler_unit_free(u); + return 0; + } + if (u->u_ste->ste_needs_class_closure) { + /* Cook up an implicit __class__ cell. */ + _Py_IDENTIFIER(__class__); + PyObject *name; + int res; + assert(u->u_scope_type == COMPILER_SCOPE_CLASS); + assert(PyDict_GET_SIZE(u->u_cellvars) == 0); + name = _PyUnicode_FromId(&PyId___class__); + if (!name) { + compiler_unit_free(u); + return 0; + } + res = PyDict_SetItem(u->u_cellvars, name, _PyLong_Zero); + if (res < 0) { + compiler_unit_free(u); + return 0; + } + } + + u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, + PyDict_GET_SIZE(u->u_cellvars)); + if (!u->u_freevars) { + compiler_unit_free(u); + return 0; + } + + u->u_blocks = NULL; + u->u_nfblocks = 0; + u->u_firstlineno = lineno; + u->u_lineno = 0; + u->u_col_offset = 0; + u->u_lineno_set = 0; + u->u_consts = PyDict_New(); + if (!u->u_consts) { + compiler_unit_free(u); + return 0; + } + u->u_names = PyDict_New(); + if (!u->u_names) { + compiler_unit_free(u); + return 0; + } + + u->u_private = NULL; + + /* Push the old compiler_unit on the stack. */ + if (c->u) { + PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL); + if (!capsule || PyList_Append(c->c_stack, capsule) < 0) { + Py_XDECREF(capsule); + compiler_unit_free(u); + return 0; + } + Py_DECREF(capsule); + u->u_private = c->u->u_private; + Py_XINCREF(u->u_private); + } + c->u = u; + + c->c_nestlevel++; + + block = compiler_new_block(c); + if (block == NULL) + return 0; + c->u->u_curblock = block; + + if (u->u_scope_type != COMPILER_SCOPE_MODULE) { + if (!compiler_set_qualname(c)) + return 0; + } + + return 1; +} + +static void +compiler_exit_scope(struct compiler *c) +{ + Py_ssize_t n; + PyObject *capsule; + + c->c_nestlevel--; + compiler_unit_free(c->u); + /* Restore c->u to the parent unit. */ + n = PyList_GET_SIZE(c->c_stack) - 1; + if (n >= 0) { + capsule = PyList_GET_ITEM(c->c_stack, n); + c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); + assert(c->u); + /* we are deleting from a list so this really shouldn't fail */ + if (PySequence_DelItem(c->c_stack, n) < 0) + Py_FatalError("compiler_exit_scope()"); + compiler_unit_check(c->u); + } + else + c->u = NULL; + +} + +static int +compiler_set_qualname(struct compiler *c) +{ + _Py_static_string(dot, "."); + _Py_static_string(dot_locals, "."); + Py_ssize_t stack_size; + struct compiler_unit *u = c->u; + PyObject *name, *base, *dot_str, *dot_locals_str; + + base = NULL; + stack_size = PyList_GET_SIZE(c->c_stack); + assert(stack_size >= 1); + if (stack_size > 1) { + int scope, force_global = 0; + struct compiler_unit *parent; + PyObject *mangled, *capsule; + + capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1); + parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); + assert(parent); + + if (u->u_scope_type == COMPILER_SCOPE_FUNCTION + || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION + || u->u_scope_type == COMPILER_SCOPE_CLASS) { + assert(u->u_name); + mangled = _Py_Mangle(parent->u_private, u->u_name); + if (!mangled) + return 0; + scope = PyST_GetScope(parent->u_ste, mangled); + Py_DECREF(mangled); + assert(scope != GLOBAL_IMPLICIT); + if (scope == GLOBAL_EXPLICIT) + force_global = 1; + } + + if (!force_global) { + if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION + || parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION + || parent->u_scope_type == COMPILER_SCOPE_LAMBDA) { + dot_locals_str = _PyUnicode_FromId(&dot_locals); + if (dot_locals_str == NULL) + return 0; + base = PyUnicode_Concat(parent->u_qualname, dot_locals_str); + if (base == NULL) + return 0; + } + else { + Py_INCREF(parent->u_qualname); + base = parent->u_qualname; + } + } + } + + if (base != NULL) { + dot_str = _PyUnicode_FromId(&dot); + if (dot_str == NULL) { + Py_DECREF(base); + return 0; + } + name = PyUnicode_Concat(base, dot_str); + Py_DECREF(base); + if (name == NULL) + return 0; + PyUnicode_Append(&name, u->u_name); + if (name == NULL) + return 0; + } + else { + Py_INCREF(u->u_name); + name = u->u_name; + } + u->u_qualname = name; + + return 1; +} + + +/* Allocate a new block and return a pointer to it. + Returns NULL on error. +*/ + +static basicblock * +compiler_new_block(struct compiler *c) +{ + basicblock *b; + struct compiler_unit *u; + + u = c->u; + b = (basicblock *)PyObject_Malloc(sizeof(basicblock)); + if (b == NULL) { + PyErr_NoMemory(); + return NULL; + } + memset((void *)b, 0, sizeof(basicblock)); + /* Extend the singly linked list of blocks with new block. */ + b->b_list = u->u_blocks; + u->u_blocks = b; + return b; +} + +static basicblock * +compiler_next_block(struct compiler *c) +{ + basicblock *block = compiler_new_block(c); + if (block == NULL) + return NULL; + c->u->u_curblock->b_next = block; + c->u->u_curblock = block; + return block; +} + +static basicblock * +compiler_use_next_block(struct compiler *c, basicblock *block) +{ + assert(block != NULL); + c->u->u_curblock->b_next = block; + c->u->u_curblock = block; + return block; +} + +/* Returns the offset of the next instruction in the current block's + b_instr array. Resizes the b_instr as necessary. + Returns -1 on failure. +*/ + +static int +compiler_next_instr(struct compiler *c, basicblock *b) +{ + assert(b != NULL); + if (b->b_instr == NULL) { + b->b_instr = (struct instr *)PyObject_Malloc( + sizeof(struct instr) * DEFAULT_BLOCK_SIZE); + if (b->b_instr == NULL) { + PyErr_NoMemory(); + return -1; + } + b->b_ialloc = DEFAULT_BLOCK_SIZE; + memset((char *)b->b_instr, 0, + sizeof(struct instr) * DEFAULT_BLOCK_SIZE); + } + else if (b->b_iused == b->b_ialloc) { + struct instr *tmp; + size_t oldsize, newsize; + oldsize = b->b_ialloc * sizeof(struct instr); + newsize = oldsize << 1; + + if (oldsize > (SIZE_MAX >> 1)) { + PyErr_NoMemory(); + return -1; + } + + if (newsize == 0) { + PyErr_NoMemory(); + return -1; + } + b->b_ialloc <<= 1; + tmp = (struct instr *)PyObject_Realloc( + (void *)b->b_instr, newsize); + if (tmp == NULL) { + PyErr_NoMemory(); + return -1; + } + b->b_instr = tmp; + memset((char *)b->b_instr + oldsize, 0, newsize - oldsize); + } + return b->b_iused++; +} + +/* Set the i_lineno member of the instruction at offset off if the + line number for the current expression/statement has not + already been set. If it has been set, the call has no effect. + + The line number is reset in the following cases: + - when entering a new scope + - on each statement + - on each expression that start a new line + - before the "except" and "finally" clauses + - before the "for" and "while" expressions +*/ + +static void +compiler_set_lineno(struct compiler *c, int off) +{ + basicblock *b; + if (c->u->u_lineno_set) + return; + c->u->u_lineno_set = 1; + b = c->u->u_curblock; + b->b_instr[off].i_lineno = c->u->u_lineno; +} + +/* Return the stack effect of opcode with argument oparg. + + Some opcodes have different stack effect when jump to the target and + when not jump. The 'jump' parameter specifies the case: + + * 0 -- when not jump + * 1 -- when jump + * -1 -- maximal + */ +/* XXX Make the stack effect of WITH_CLEANUP_START and + WITH_CLEANUP_FINISH deterministic. */ +static int +stack_effect(int opcode, int oparg, int jump) +{ + switch (opcode) { + case NOP: + case EXTENDED_ARG: + return 0; + + /* Stack manipulation */ + case POP_TOP: + return -1; + case ROT_TWO: + case ROT_THREE: + case ROT_FOUR: + return 0; + case DUP_TOP: + return 1; + case DUP_TOP_TWO: + return 2; + + /* Unary operators */ + case UNARY_POSITIVE: + case UNARY_NEGATIVE: + case UNARY_NOT: + case UNARY_INVERT: + return 0; + + case SET_ADD: + case LIST_APPEND: + return -1; + case MAP_ADD: + return -2; + + /* Binary operators */ + case BINARY_POWER: + case BINARY_MULTIPLY: + case BINARY_MATRIX_MULTIPLY: + case BINARY_MODULO: + case BINARY_ADD: + case BINARY_SUBTRACT: + case BINARY_SUBSCR: + case BINARY_FLOOR_DIVIDE: + case BINARY_TRUE_DIVIDE: + return -1; + case INPLACE_FLOOR_DIVIDE: + case INPLACE_TRUE_DIVIDE: + return -1; + + case INPLACE_ADD: + case INPLACE_SUBTRACT: + case INPLACE_MULTIPLY: + case INPLACE_MATRIX_MULTIPLY: + case INPLACE_MODULO: + return -1; + case STORE_SUBSCR: + return -3; + case DELETE_SUBSCR: + return -2; + + case BINARY_LSHIFT: + case BINARY_RSHIFT: + case BINARY_AND: + case BINARY_XOR: + case BINARY_OR: + return -1; + case INPLACE_POWER: + return -1; + case GET_ITER: + return 0; + + case PRINT_EXPR: + return -1; + case LOAD_BUILD_CLASS: + return 1; + case INPLACE_LSHIFT: + case INPLACE_RSHIFT: + case INPLACE_AND: + case INPLACE_XOR: + case INPLACE_OR: + return -1; + + case SETUP_WITH: + /* 1 in the normal flow. + * Restore the stack position and push 6 values before jumping to + * the handler if an exception be raised. */ + return jump ? 6 : 1; + case WITH_CLEANUP_START: + return 2; /* or 1, depending on TOS */ + case WITH_CLEANUP_FINISH: + /* Pop a variable number of values pushed by WITH_CLEANUP_START + * + __exit__ or __aexit__. */ + return -3; + case RETURN_VALUE: + return -1; + case IMPORT_STAR: + return -1; + case SETUP_ANNOTATIONS: + return 0; + case YIELD_VALUE: + return 0; + case YIELD_FROM: + return -1; + case POP_BLOCK: + return 0; + case POP_EXCEPT: + return -3; + case END_FINALLY: + case POP_FINALLY: + /* Pop 6 values when an exception was raised. */ + return -6; + + case STORE_NAME: + return -1; + case DELETE_NAME: + return 0; + case UNPACK_SEQUENCE: + return oparg-1; + case UNPACK_EX: + return (oparg&0xFF) + (oparg>>8); + case FOR_ITER: + /* -1 at end of iterator, 1 if continue iterating. */ + return jump > 0 ? -1 : 1; + + case STORE_ATTR: + return -2; + case DELETE_ATTR: + return -1; + case STORE_GLOBAL: + return -1; + case DELETE_GLOBAL: + return 0; + case LOAD_CONST: + return 1; + case LOAD_NAME: + return 1; + case BUILD_TUPLE: + case BUILD_LIST: + case BUILD_SET: + case BUILD_STRING: + return 1-oparg; + case BUILD_LIST_UNPACK: + case BUILD_TUPLE_UNPACK: + case BUILD_TUPLE_UNPACK_WITH_CALL: + case BUILD_SET_UNPACK: + case BUILD_MAP_UNPACK: + case BUILD_MAP_UNPACK_WITH_CALL: + return 1 - oparg; + case BUILD_MAP: + return 1 - 2*oparg; + case BUILD_CONST_KEY_MAP: + return -oparg; + case LOAD_ATTR: + return 0; + case COMPARE_OP: + return -1; + case IMPORT_NAME: + return -1; + case IMPORT_FROM: + return 1; + + /* Jumps */ + case JUMP_FORWARD: + case JUMP_ABSOLUTE: + return 0; + + case JUMP_IF_TRUE_OR_POP: + case JUMP_IF_FALSE_OR_POP: + return jump ? 0 : -1; + + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + return -1; + + case LOAD_GLOBAL: + return 1; + + /* Exception handling */ + case SETUP_FINALLY: + /* 0 in the normal flow. + * Restore the stack position and push 6 values before jumping to + * the handler if an exception be raised. */ + return jump ? 6 : 0; + case BEGIN_FINALLY: + /* Actually pushes 1 value, but count 6 for balancing with + * END_FINALLY and POP_FINALLY. + * This is the main reason of using this opcode instead of + * "LOAD_CONST None". */ + return 6; + case CALL_FINALLY: + return jump ? 1 : 0; + + case LOAD_FAST: + return 1; + case STORE_FAST: + return -1; + case DELETE_FAST: + return 0; + + case RAISE_VARARGS: + return -oparg; + + /* Functions and calls */ + case CALL_FUNCTION: + return -oparg; + case CALL_METHOD: + return -oparg-1; + case CALL_FUNCTION_KW: + return -oparg-1; + case CALL_FUNCTION_EX: + return -1 - ((oparg & 0x01) != 0); + case MAKE_FUNCTION: + return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) - + ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0); + case BUILD_SLICE: + if (oparg == 3) + return -2; + else + return -1; + + /* Closures */ + case LOAD_CLOSURE: + return 1; + case LOAD_DEREF: + case LOAD_CLASSDEREF: + return 1; + case STORE_DEREF: + return -1; + case DELETE_DEREF: + return 0; + + /* Iterators and generators */ + case GET_AWAITABLE: + return 0; + case SETUP_ASYNC_WITH: + /* 0 in the normal flow. + * Restore the stack position to the position before the result + * of __aenter__ and push 6 values before jumping to the handler + * if an exception be raised. */ + return jump ? -1 + 6 : 0; + case BEFORE_ASYNC_WITH: + return 1; + case GET_AITER: + return 0; + case GET_ANEXT: + return 1; + case GET_YIELD_FROM_ITER: + return 0; + case END_ASYNC_FOR: + return -7; + case FORMAT_VALUE: + /* If there's a fmt_spec on the stack, we go from 2->1, + else 1->1. */ + return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0; + case LOAD_METHOD: + return 1; + default: + return PY_INVALID_STACK_EFFECT; + } + return PY_INVALID_STACK_EFFECT; /* not reachable */ +} + +int +PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump) +{ + return stack_effect(opcode, oparg, jump); +} + +int +PyCompile_OpcodeStackEffect(int opcode, int oparg) +{ + return stack_effect(opcode, oparg, -1); +} + +/* Add an opcode with no argument. + Returns 0 on failure, 1 on success. +*/ + +static int +compiler_addop(struct compiler *c, int opcode) +{ + basicblock *b; + struct instr *i; + int off; + assert(!HAS_ARG(opcode)); + if (c->c_do_not_emit_bytecode) { + return 1; + } + off = compiler_next_instr(c, c->u->u_curblock); + if (off < 0) + return 0; + b = c->u->u_curblock; + i = &b->b_instr[off]; + i->i_opcode = opcode; + i->i_oparg = 0; + if (opcode == RETURN_VALUE) + b->b_return = 1; + compiler_set_lineno(c, off); + return 1; +} + +static Py_ssize_t +compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) +{ + PyObject *v; + Py_ssize_t arg; + + v = PyDict_GetItemWithError(dict, o); + if (!v) { + if (PyErr_Occurred()) { + return -1; + } + arg = PyDict_GET_SIZE(dict); + v = PyLong_FromSsize_t(arg); + if (!v) { + return -1; + } + if (PyDict_SetItem(dict, o, v) < 0) { + Py_DECREF(v); + return -1; + } + Py_DECREF(v); + } + else + arg = PyLong_AsLong(v); + return arg; +} + +// Merge const *o* recursively and return constant key object. +static PyObject* +merge_consts_recursive(struct compiler *c, PyObject *o) +{ + // None and Ellipsis are singleton, and key is the singleton. + // No need to merge object and key. + if (o == Py_None || o == Py_Ellipsis) { + Py_INCREF(o); + return o; + } + + PyObject *key = _PyCode_ConstantKey(o); + if (key == NULL) { + return NULL; + } + + // t is borrowed reference + PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); + if (t != key) { + // o is registered in c_const_cache. Just use it. + Py_XINCREF(t); + Py_DECREF(key); + return t; + } + + // We registered o in c_const_cache. + // When o is a tuple or frozenset, we want to merge its + // items too. + if (PyTuple_CheckExact(o)) { + Py_ssize_t len = PyTuple_GET_SIZE(o); + for (Py_ssize_t i = 0; i < len; i++) { + PyObject *item = PyTuple_GET_ITEM(o, i); + PyObject *u = merge_consts_recursive(c, item); + if (u == NULL) { + Py_DECREF(key); + return NULL; + } + + // See _PyCode_ConstantKey() + PyObject *v; // borrowed + if (PyTuple_CheckExact(u)) { + v = PyTuple_GET_ITEM(u, 1); + } + else { + v = u; + } + if (v != item) { + Py_INCREF(v); + PyTuple_SET_ITEM(o, i, v); + Py_DECREF(item); + } + + Py_DECREF(u); + } + } + else if (PyFrozenSet_CheckExact(o)) { + // *key* is tuple. And its first item is frozenset of + // constant keys. + // See _PyCode_ConstantKey() for detail. + assert(PyTuple_CheckExact(key)); + assert(PyTuple_GET_SIZE(key) == 2); + + Py_ssize_t len = PySet_GET_SIZE(o); + if (len == 0) { // empty frozenset should not be re-created. + return key; + } + PyObject *tuple = PyTuple_New(len); + if (tuple == NULL) { + Py_DECREF(key); + return NULL; + } + Py_ssize_t i = 0, pos = 0; + PyObject *item; + Py_hash_t hash; + while (_PySet_NextEntry(o, &pos, &item, &hash)) { + PyObject *k = merge_consts_recursive(c, item); + if (k == NULL) { + Py_DECREF(tuple); + Py_DECREF(key); + return NULL; + } + PyObject *u; + if (PyTuple_CheckExact(k)) { + u = PyTuple_GET_ITEM(k, 1); + Py_INCREF(u); + Py_DECREF(k); + } + else { + u = k; + } + PyTuple_SET_ITEM(tuple, i, u); // Steals reference of u. + i++; + } + + // Instead of rewriting o, we create new frozenset and embed in the + // key tuple. Caller should get merged frozenset from the key tuple. + PyObject *new = PyFrozenSet_New(tuple); + Py_DECREF(tuple); + if (new == NULL) { + Py_DECREF(key); + return NULL; + } + assert(PyTuple_GET_ITEM(key, 1) == o); + Py_DECREF(o); + PyTuple_SET_ITEM(key, 1, new); + } + + return key; +} + +static Py_ssize_t +compiler_add_const(struct compiler *c, PyObject *o) +{ + if (c->c_do_not_emit_bytecode) { + return 0; + } + + PyObject *key = merge_consts_recursive(c, o); + if (key == NULL) { + return -1; + } + + Py_ssize_t arg = compiler_add_o(c, c->u->u_consts, key); + Py_DECREF(key); + return arg; +} + +static int +compiler_addop_load_const(struct compiler *c, PyObject *o) +{ + if (c->c_do_not_emit_bytecode) { + return 1; + } + + Py_ssize_t arg = compiler_add_const(c, o); + if (arg < 0) + return 0; + return compiler_addop_i(c, LOAD_CONST, arg); +} + +static int +compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, + PyObject *o) +{ + if (c->c_do_not_emit_bytecode) { + return 1; + } + + Py_ssize_t arg = compiler_add_o(c, dict, o); + if (arg < 0) + return 0; + return compiler_addop_i(c, opcode, arg); +} + +static int +compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, + PyObject *o) +{ + Py_ssize_t arg; + + if (c->c_do_not_emit_bytecode) { + return 1; + } + + PyObject *mangled = _Py_Mangle(c->u->u_private, o); + if (!mangled) + return 0; + arg = compiler_add_o(c, dict, mangled); + Py_DECREF(mangled); + if (arg < 0) + return 0; + return compiler_addop_i(c, opcode, arg); +} + +/* Add an opcode with an integer argument. + Returns 0 on failure, 1 on success. +*/ + +static int +compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) +{ + struct instr *i; + int off; + + if (c->c_do_not_emit_bytecode) { + return 1; + } + + /* oparg value is unsigned, but a signed C int is usually used to store + it in the C code (like Python/ceval.c). + + Limit to 32-bit signed C int (rather than INT_MAX) for portability. + + The argument of a concrete bytecode instruction is limited to 8-bit. + EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ + assert(HAS_ARG(opcode)); + assert(0 <= oparg && oparg <= 2147483647); + + off = compiler_next_instr(c, c->u->u_curblock); + if (off < 0) + return 0; + i = &c->u->u_curblock->b_instr[off]; + i->i_opcode = opcode; + i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); + compiler_set_lineno(c, off); + return 1; +} + +static int +compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) +{ + struct instr *i; + int off; + + if (c->c_do_not_emit_bytecode) { + return 1; + } + + assert(HAS_ARG(opcode)); + assert(b != NULL); + off = compiler_next_instr(c, c->u->u_curblock); + if (off < 0) + return 0; + i = &c->u->u_curblock->b_instr[off]; + i->i_opcode = opcode; + i->i_target = b; + if (absolute) + i->i_jabs = 1; + else + i->i_jrel = 1; + compiler_set_lineno(c, off); + return 1; +} + +/* NEXT_BLOCK() creates an implicit jump from the current block + to the new block. + + The returns inside this macro make it impossible to decref objects + created in the local function. Local objects should use the arena. +*/ +#define NEXT_BLOCK(C) { \ + if (compiler_next_block((C)) == NULL) \ + return 0; \ +} + +#define ADDOP(C, OP) { \ + if (!compiler_addop((C), (OP))) \ + return 0; \ +} + +#define ADDOP_IN_SCOPE(C, OP) { \ + if (!compiler_addop((C), (OP))) { \ + compiler_exit_scope(c); \ + return 0; \ + } \ +} + +#define ADDOP_LOAD_CONST(C, O) { \ + if (!compiler_addop_load_const((C), (O))) \ + return 0; \ +} + +/* Same as ADDOP_LOAD_CONST, but steals a reference. */ +#define ADDOP_LOAD_CONST_NEW(C, O) { \ + PyObject *__new_const = (O); \ + if (__new_const == NULL) { \ + return 0; \ + } \ + if (!compiler_addop_load_const((C), __new_const)) { \ + Py_DECREF(__new_const); \ + return 0; \ + } \ + Py_DECREF(__new_const); \ +} + +#define ADDOP_O(C, OP, O, TYPE) { \ + if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ + return 0; \ +} + +/* Same as ADDOP_O, but steals a reference. */ +#define ADDOP_N(C, OP, O, TYPE) { \ + if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \ + Py_DECREF((O)); \ + return 0; \ + } \ + Py_DECREF((O)); \ +} + +#define ADDOP_NAME(C, OP, O, TYPE) { \ + if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ + return 0; \ +} + +#define ADDOP_I(C, OP, O) { \ + if (!compiler_addop_i((C), (OP), (O))) \ + return 0; \ +} + +#define ADDOP_JABS(C, OP, O) { \ + if (!compiler_addop_j((C), (OP), (O), 1)) \ + return 0; \ +} + +#define ADDOP_JREL(C, OP, O) { \ + if (!compiler_addop_j((C), (OP), (O), 0)) \ + return 0; \ +} + +/* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use + the ASDL name to synthesize the name of the C type and the visit function. +*/ + +#define VISIT(C, TYPE, V) {\ + if (!compiler_visit_ ## TYPE((C), (V))) \ + return 0; \ +} + +#define VISIT_IN_SCOPE(C, TYPE, V) {\ + if (!compiler_visit_ ## TYPE((C), (V))) { \ + compiler_exit_scope(c); \ + return 0; \ + } \ +} + +#define VISIT_SLICE(C, V, CTX) {\ + if (!compiler_visit_slice((C), (V), (CTX))) \ + return 0; \ +} + +#define VISIT_SEQ(C, TYPE, SEQ) { \ + int _i; \ + asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ + if (!compiler_visit_ ## TYPE((C), elt)) \ + return 0; \ + } \ +} + +#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ + int _i; \ + asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ + if (!compiler_visit_ ## TYPE((C), elt)) { \ + compiler_exit_scope(c); \ + return 0; \ + } \ + } \ +} + +/* These macros allows to check only for errors and not emmit bytecode + * while visiting nodes. +*/ + +#define BEGIN_DO_NOT_EMIT_BYTECODE { \ + c->c_do_not_emit_bytecode++; + +#define END_DO_NOT_EMIT_BYTECODE \ + c->c_do_not_emit_bytecode--; \ +} + +/* Search if variable annotations are present statically in a block. */ + +static int +find_ann(asdl_seq *stmts) +{ + int i, j, res = 0; + stmt_ty st; + + for (i = 0; i < asdl_seq_LEN(stmts); i++) { + st = (stmt_ty)asdl_seq_GET(stmts, i); + switch (st->kind) { + case AnnAssign_kind: + return 1; + case For_kind: + res = find_ann(st->v.For.body) || + find_ann(st->v.For.orelse); + break; + case AsyncFor_kind: + res = find_ann(st->v.AsyncFor.body) || + find_ann(st->v.AsyncFor.orelse); + break; + case While_kind: + res = find_ann(st->v.While.body) || + find_ann(st->v.While.orelse); + break; + case If_kind: + res = find_ann(st->v.If.body) || + find_ann(st->v.If.orelse); + break; + case With_kind: + res = find_ann(st->v.With.body); + break; + case AsyncWith_kind: + res = find_ann(st->v.AsyncWith.body); + break; + case Try_kind: + for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) { + excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( + st->v.Try.handlers, j); + if (find_ann(handler->v.ExceptHandler.body)) { + return 1; + } + } + res = find_ann(st->v.Try.body) || + find_ann(st->v.Try.finalbody) || + find_ann(st->v.Try.orelse); + break; + default: + res = 0; + } + if (res) { + break; + } + } + return res; +} + +/* + * Frame block handling functions + */ + +static int +compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, + basicblock *exit) +{ + struct fblockinfo *f; + if (c->u->u_nfblocks >= CO_MAXBLOCKS) { + PyErr_SetString(PyExc_SyntaxError, + "too many statically nested blocks"); + return 0; + } + f = &c->u->u_fblock[c->u->u_nfblocks++]; + f->fb_type = t; + f->fb_block = b; + f->fb_exit = exit; + return 1; +} + +static void +compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) +{ + struct compiler_unit *u = c->u; + assert(u->u_nfblocks > 0); + u->u_nfblocks--; + assert(u->u_fblock[u->u_nfblocks].fb_type == t); + assert(u->u_fblock[u->u_nfblocks].fb_block == b); +} + +/* Unwind a frame block. If preserve_tos is true, the TOS before + * popping the blocks will be restored afterwards. + */ +static int +compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, + int preserve_tos) +{ + switch (info->fb_type) { + case WHILE_LOOP: + return 1; + + case FINALLY_END: + info->fb_exit = NULL; + ADDOP_I(c, POP_FINALLY, preserve_tos); + if (preserve_tos) { + ADDOP(c, ROT_TWO); + } + ADDOP(c, POP_TOP); + return 1; + + case FOR_LOOP: + /* Pop the iterator */ + if (preserve_tos) { + ADDOP(c, ROT_TWO); + } + ADDOP(c, POP_TOP); + return 1; + + case EXCEPT: + ADDOP(c, POP_BLOCK); + return 1; + + case FINALLY_TRY: + ADDOP(c, POP_BLOCK); + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + return 1; + + case FINALLY_TRY2: + ADDOP(c, POP_BLOCK); + if (preserve_tos) { + ADDOP(c, ROT_TWO); + ADDOP(c, POP_TOP); + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + } + else { + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + ADDOP(c, POP_TOP); + } + return 1; + + case WITH: + case ASYNC_WITH: + ADDOP(c, POP_BLOCK); + if (preserve_tos) { + ADDOP(c, ROT_TWO); + } + ADDOP(c, BEGIN_FINALLY); + ADDOP(c, WITH_CLEANUP_START); + if (info->fb_type == ASYNC_WITH) { + ADDOP(c, GET_AWAITABLE); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + } + ADDOP(c, WITH_CLEANUP_FINISH); + ADDOP_I(c, POP_FINALLY, 0); + return 1; + + case HANDLER_CLEANUP: + if (preserve_tos) { + ADDOP(c, ROT_FOUR); + } + if (info->fb_exit) { + ADDOP(c, POP_BLOCK); + ADDOP(c, POP_EXCEPT); + ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + } + else { + ADDOP(c, POP_EXCEPT); + } + return 1; + } + Py_UNREACHABLE(); +} + +/* Compile a sequence of statements, checking for a docstring + and for annotations. */ + +static int +compiler_body(struct compiler *c, asdl_seq *stmts) +{ + int i = 0; + stmt_ty st; + PyObject *docstring; + + /* Set current line number to the line number of first statement. + This way line number for SETUP_ANNOTATIONS will always + coincide with the line number of first "real" statement in module. + If body is empty, then lineno will be set later in assemble. */ + if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && + !c->u->u_lineno && asdl_seq_LEN(stmts)) { + st = (stmt_ty)asdl_seq_GET(stmts, 0); + c->u->u_lineno = st->lineno; + } + /* Every annotated class and module should have __annotations__. */ + if (find_ann(stmts)) { + ADDOP(c, SETUP_ANNOTATIONS); + } + if (!asdl_seq_LEN(stmts)) + return 1; + /* if not -OO mode, set docstring */ + if (c->c_optimize < 2) { + docstring = _PyAST_GetDocString(stmts); + if (docstring) { + i = 1; + st = (stmt_ty)asdl_seq_GET(stmts, 0); + assert(st->kind == Expr_kind); + VISIT(c, expr, st->v.Expr.value); + if (!compiler_nameop(c, __doc__, Store)) + return 0; + } + } + for (; i < asdl_seq_LEN(stmts); i++) + VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); + return 1; +} + +static PyCodeObject * +compiler_mod(struct compiler *c, mod_ty mod) +{ + PyCodeObject *co; + int addNone = 1; + static PyObject *module; + if (!module) { + module = PyUnicode_InternFromString(""); + if (!module) + return NULL; + } + /* Use 0 for firstlineno initially, will fixup in assemble(). */ + if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 0)) + return NULL; + switch (mod->kind) { + case Module_kind: + if (!compiler_body(c, mod->v.Module.body)) { + compiler_exit_scope(c); + return 0; + } + break; + case Interactive_kind: + if (find_ann(mod->v.Interactive.body)) { + ADDOP(c, SETUP_ANNOTATIONS); + } + c->c_interactive = 1; + VISIT_SEQ_IN_SCOPE(c, stmt, + mod->v.Interactive.body); + break; + case Expression_kind: + VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); + addNone = 0; + break; + case Suite_kind: + PyErr_SetString(PyExc_SystemError, + "suite should not be possible"); + return 0; + default: + PyErr_Format(PyExc_SystemError, + "module kind %d should not be possible", + mod->kind); + return 0; + } + co = assemble(c, addNone); + compiler_exit_scope(c); + return co; +} + +/* The test for LOCAL must come before the test for FREE in order to + handle classes where name is both local and free. The local var is + a method and the free var is a free var referenced within a method. +*/ + +static int +get_ref_type(struct compiler *c, PyObject *name) +{ + int scope; + if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && + _PyUnicode_EqualToASCIIString(name, "__class__")) + return CELL; + scope = PyST_GetScope(c->u->u_ste, name); + if (scope == 0) { + char buf[350]; + PyOS_snprintf(buf, sizeof(buf), + "unknown scope for %.100s in %.100s(%s)\n" + "symbols: %s\nlocals: %s\nglobals: %s", + PyUnicode_AsUTF8(name), + PyUnicode_AsUTF8(c->u->u_name), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names)) + ); + Py_FatalError(buf); + } + + return scope; +} + +static int +compiler_lookup_arg(PyObject *dict, PyObject *name) +{ + PyObject *v; + v = PyDict_GetItem(dict, name); + if (v == NULL) + return -1; + return PyLong_AS_LONG(v); +} + +static int +compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, PyObject *qualname) +{ + Py_ssize_t i, free = PyCode_GetNumFree(co); + if (qualname == NULL) + qualname = co->co_name; + + if (free) { + for (i = 0; i < free; ++i) { + /* Bypass com_addop_varname because it will generate + LOAD_DEREF but LOAD_CLOSURE is needed. + */ + PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); + int arg, reftype; + + /* Special case: If a class contains a method with a + free variable that has the same name as a method, + the name will be considered free *and* local in the + class. It should be handled by the closure, as + well as by the normal name loookup logic. + */ + reftype = get_ref_type(c, name); + if (reftype == CELL) + arg = compiler_lookup_arg(c->u->u_cellvars, name); + else /* (reftype == FREE) */ + arg = compiler_lookup_arg(c->u->u_freevars, name); + if (arg == -1) { + fprintf(stderr, + "lookup %s in %s %d %d\n" + "freevars of %s: %s\n", + PyUnicode_AsUTF8(PyObject_Repr(name)), + PyUnicode_AsUTF8(c->u->u_name), + reftype, arg, + PyUnicode_AsUTF8(co->co_name), + PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars))); + Py_FatalError("compiler_make_closure()"); + } + ADDOP_I(c, LOAD_CLOSURE, arg); + } + flags |= 0x08; + ADDOP_I(c, BUILD_TUPLE, free); + } + ADDOP_LOAD_CONST(c, (PyObject*)co); + ADDOP_LOAD_CONST(c, qualname); + ADDOP_I(c, MAKE_FUNCTION, flags); + return 1; +} + +static int +compiler_decorators(struct compiler *c, asdl_seq* decos) +{ + int i; + + if (!decos) + return 1; + + for (i = 0; i < asdl_seq_LEN(decos); i++) { + VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); + } + return 1; +} + +static int +compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs, + asdl_seq *kw_defaults) +{ + /* Push a dict of keyword-only default values. + + Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed. + */ + int i; + PyObject *keys = NULL; + + for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) { + arg_ty arg = asdl_seq_GET(kwonlyargs, i); + expr_ty default_ = asdl_seq_GET(kw_defaults, i); + if (default_) { + PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg); + if (!mangled) { + goto error; + } + if (keys == NULL) { + keys = PyList_New(1); + if (keys == NULL) { + Py_DECREF(mangled); + return 0; + } + PyList_SET_ITEM(keys, 0, mangled); + } + else { + int res = PyList_Append(keys, mangled); + Py_DECREF(mangled); + if (res == -1) { + goto error; + } + } + if (!compiler_visit_expr(c, default_)) { + goto error; + } + } + } + if (keys != NULL) { + Py_ssize_t default_count = PyList_GET_SIZE(keys); + PyObject *keys_tuple = PyList_AsTuple(keys); + Py_DECREF(keys); + ADDOP_LOAD_CONST_NEW(c, keys_tuple); + ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count); + assert(default_count > 0); + return 1; + } + else { + return -1; + } + +error: + Py_XDECREF(keys); + return 0; +} + +static int +compiler_visit_annexpr(struct compiler *c, expr_ty annotation) +{ + ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation)); + return 1; +} + +static int +compiler_visit_argannotation(struct compiler *c, identifier id, + expr_ty annotation, PyObject *names) +{ + if (annotation) { + PyObject *mangled; + if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { + VISIT(c, annexpr, annotation) + } + else { + VISIT(c, expr, annotation); + } + mangled = _Py_Mangle(c->u->u_private, id); + if (!mangled) + return 0; + if (PyList_Append(names, mangled) < 0) { + Py_DECREF(mangled); + return 0; + } + Py_DECREF(mangled); + } + return 1; +} + +static int +compiler_visit_argannotations(struct compiler *c, asdl_seq* args, + PyObject *names) +{ + int i; + for (i = 0; i < asdl_seq_LEN(args); i++) { + arg_ty arg = (arg_ty)asdl_seq_GET(args, i); + if (!compiler_visit_argannotation( + c, + arg->arg, + arg->annotation, + names)) + return 0; + } + return 1; +} + +static int +compiler_visit_annotations(struct compiler *c, arguments_ty args, + expr_ty returns) +{ + /* Push arg annotation dict. + The expressions are evaluated out-of-order wrt the source code. + + Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed. + */ + static identifier return_str; + PyObject *names; + Py_ssize_t len; + names = PyList_New(0); + if (!names) + return 0; + + if (!compiler_visit_argannotations(c, args->args, names)) + goto error; + if (!compiler_visit_argannotations(c, args->posonlyargs, names)) + goto error; + if (args->vararg && args->vararg->annotation && + !compiler_visit_argannotation(c, args->vararg->arg, + args->vararg->annotation, names)) + goto error; + if (!compiler_visit_argannotations(c, args->kwonlyargs, names)) + goto error; + if (args->kwarg && args->kwarg->annotation && + !compiler_visit_argannotation(c, args->kwarg->arg, + args->kwarg->annotation, names)) + goto error; + + if (!return_str) { + return_str = PyUnicode_InternFromString("return"); + if (!return_str) + goto error; + } + if (!compiler_visit_argannotation(c, return_str, returns, names)) { + goto error; + } + + len = PyList_GET_SIZE(names); + if (len) { + PyObject *keytuple = PyList_AsTuple(names); + Py_DECREF(names); + ADDOP_LOAD_CONST_NEW(c, keytuple); + ADDOP_I(c, BUILD_CONST_KEY_MAP, len); + return 1; + } + else { + Py_DECREF(names); + return -1; + } + +error: + Py_DECREF(names); + return 0; +} + +static int +compiler_visit_defaults(struct compiler *c, arguments_ty args) +{ + VISIT_SEQ(c, expr, args->defaults); + ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); + return 1; +} + +static Py_ssize_t +compiler_default_arguments(struct compiler *c, arguments_ty args) +{ + Py_ssize_t funcflags = 0; + if (args->defaults && asdl_seq_LEN(args->defaults) > 0) { + if (!compiler_visit_defaults(c, args)) + return -1; + funcflags |= 0x01; + } + if (args->kwonlyargs) { + int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, + args->kw_defaults); + if (res == 0) { + return -1; + } + else if (res > 0) { + funcflags |= 0x02; + } + } + return funcflags; +} + +static int +compiler_function(struct compiler *c, stmt_ty s, int is_async) +{ + PyCodeObject *co; + PyObject *qualname, *docstring = NULL; + arguments_ty args; + expr_ty returns; + identifier name; + asdl_seq* decos; + asdl_seq *body; + Py_ssize_t i, funcflags; + int annotations; + int scope_type; + int firstlineno; + + if (is_async) { + assert(s->kind == AsyncFunctionDef_kind); + + args = s->v.AsyncFunctionDef.args; + returns = s->v.AsyncFunctionDef.returns; + decos = s->v.AsyncFunctionDef.decorator_list; + name = s->v.AsyncFunctionDef.name; + body = s->v.AsyncFunctionDef.body; + + scope_type = COMPILER_SCOPE_ASYNC_FUNCTION; + } else { + assert(s->kind == FunctionDef_kind); + + args = s->v.FunctionDef.args; + returns = s->v.FunctionDef.returns; + decos = s->v.FunctionDef.decorator_list; + name = s->v.FunctionDef.name; + body = s->v.FunctionDef.body; + + scope_type = COMPILER_SCOPE_FUNCTION; + } + + if (!compiler_decorators(c, decos)) + return 0; + + firstlineno = s->lineno; + if (asdl_seq_LEN(decos)) { + firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; + } + + funcflags = compiler_default_arguments(c, args); + if (funcflags == -1) { + return 0; + } + + annotations = compiler_visit_annotations(c, args, returns); + if (annotations == 0) { + return 0; + } + else if (annotations > 0) { + funcflags |= 0x04; + } + + if (!compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)) { + return 0; + } + + /* if not -OO mode, add docstring */ + if (c->c_optimize < 2) { + docstring = _PyAST_GetDocString(body); + } + if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) { + compiler_exit_scope(c); + return 0; + } + + c->u->u_argcount = asdl_seq_LEN(args->args); + c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); + c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); + VISIT_SEQ_IN_SCOPE(c, stmt, body); + co = assemble(c, 1); + qualname = c->u->u_qualname; + Py_INCREF(qualname); + compiler_exit_scope(c); + if (co == NULL) { + Py_XDECREF(qualname); + Py_XDECREF(co); + return 0; + } + + compiler_make_closure(c, co, funcflags, qualname); + Py_DECREF(qualname); + Py_DECREF(co); + + /* decorators */ + for (i = 0; i < asdl_seq_LEN(decos); i++) { + ADDOP_I(c, CALL_FUNCTION, 1); + } + + return compiler_nameop(c, name, Store); +} + +static int +compiler_class(struct compiler *c, stmt_ty s) +{ + PyCodeObject *co; + PyObject *str; + int i, firstlineno; + asdl_seq* decos = s->v.ClassDef.decorator_list; + + if (!compiler_decorators(c, decos)) + return 0; + + firstlineno = s->lineno; + if (asdl_seq_LEN(decos)) { + firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; + } + + /* ultimately generate code for: + = __build_class__(, , *, **) + where: + is a function/closure created from the class body; + it has a single argument (__locals__) where the dict + (or MutableSequence) representing the locals is passed + is the class name + is the positional arguments and *varargs argument + is the keyword arguments and **kwds argument + This borrows from compiler_call. + */ + + /* 1. compile the class body into a code object */ + if (!compiler_enter_scope(c, s->v.ClassDef.name, + COMPILER_SCOPE_CLASS, (void *)s, firstlineno)) + return 0; + /* this block represents what we do in the new scope */ + { + /* use the class name for name mangling */ + Py_INCREF(s->v.ClassDef.name); + Py_XSETREF(c->u->u_private, s->v.ClassDef.name); + /* load (global) __name__ ... */ + str = PyUnicode_InternFromString("__name__"); + if (!str || !compiler_nameop(c, str, Load)) { + Py_XDECREF(str); + compiler_exit_scope(c); + return 0; + } + Py_DECREF(str); + /* ... and store it as __module__ */ + str = PyUnicode_InternFromString("__module__"); + if (!str || !compiler_nameop(c, str, Store)) { + Py_XDECREF(str); + compiler_exit_scope(c); + return 0; + } + Py_DECREF(str); + assert(c->u->u_qualname); + ADDOP_LOAD_CONST(c, c->u->u_qualname); + str = PyUnicode_InternFromString("__qualname__"); + if (!str || !compiler_nameop(c, str, Store)) { + Py_XDECREF(str); + compiler_exit_scope(c); + return 0; + } + Py_DECREF(str); + /* compile the body proper */ + if (!compiler_body(c, s->v.ClassDef.body)) { + compiler_exit_scope(c); + return 0; + } + /* Return __classcell__ if it is referenced, otherwise return None */ + if (c->u->u_ste->ste_needs_class_closure) { + /* Store __classcell__ into class namespace & return it */ + str = PyUnicode_InternFromString("__class__"); + if (str == NULL) { + compiler_exit_scope(c); + return 0; + } + i = compiler_lookup_arg(c->u->u_cellvars, str); + Py_DECREF(str); + if (i < 0) { + compiler_exit_scope(c); + return 0; + } + assert(i == 0); + + ADDOP_I(c, LOAD_CLOSURE, i); + ADDOP(c, DUP_TOP); + str = PyUnicode_InternFromString("__classcell__"); + if (!str || !compiler_nameop(c, str, Store)) { + Py_XDECREF(str); + compiler_exit_scope(c); + return 0; + } + Py_DECREF(str); + } + else { + /* No methods referenced __class__, so just return None */ + assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0); + ADDOP_LOAD_CONST(c, Py_None); + } + ADDOP_IN_SCOPE(c, RETURN_VALUE); + /* create the code object */ + co = assemble(c, 1); + } + /* leave the new scope */ + compiler_exit_scope(c); + if (co == NULL) + return 0; + + /* 2. load the 'build_class' function */ + ADDOP(c, LOAD_BUILD_CLASS); + + /* 3. load a function (or closure) made from the code object */ + compiler_make_closure(c, co, 0, NULL); + Py_DECREF(co); + + /* 4. load class name */ + ADDOP_LOAD_CONST(c, s->v.ClassDef.name); + + /* 5. generate the rest of the code for the call */ + if (!compiler_call_helper(c, 2, + s->v.ClassDef.bases, + s->v.ClassDef.keywords)) + return 0; + + /* 6. apply decorators */ + for (i = 0; i < asdl_seq_LEN(decos); i++) { + ADDOP_I(c, CALL_FUNCTION, 1); + } + + /* 7. store into */ + if (!compiler_nameop(c, s->v.ClassDef.name, Store)) + return 0; + return 1; +} + +/* Return 0 if the expression is a constant value except named singletons. + Return 1 otherwise. */ +static int +check_is_arg(expr_ty e) +{ + if (e->kind != Constant_kind) { + return 1; + } + PyObject *value = e->v.Constant.value; + return (value == Py_None + || value == Py_False + || value == Py_True + || value == Py_Ellipsis); +} + +/* Check operands of identity chacks ("is" and "is not"). + Emit a warning if any operand is a constant except named singletons. + Return 0 on error. + */ +static int +check_compare(struct compiler *c, expr_ty e) +{ + Py_ssize_t i, n; + int left = check_is_arg(e->v.Compare.left); + n = asdl_seq_LEN(e->v.Compare.ops); + for (i = 0; i < n; i++) { + cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i); + int right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); + if (op == Is || op == IsNot) { + if (!right || !left) { + const char *msg = (op == Is) + ? "\"is\" with a literal. Did you mean \"==\"?" + : "\"is not\" with a literal. Did you mean \"!=\"?"; + return compiler_warn(c, msg); + } + } + left = right; + } + return 1; +} + +static int +cmpop(cmpop_ty op) +{ + switch (op) { + case Eq: + return PyCmp_EQ; + case NotEq: + return PyCmp_NE; + case Lt: + return PyCmp_LT; + case LtE: + return PyCmp_LE; + case Gt: + return PyCmp_GT; + case GtE: + return PyCmp_GE; + case Is: + return PyCmp_IS; + case IsNot: + return PyCmp_IS_NOT; + case In: + return PyCmp_IN; + case NotIn: + return PyCmp_NOT_IN; + default: + return PyCmp_BAD; + } +} + +static int +compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) +{ + switch (e->kind) { + case UnaryOp_kind: + if (e->v.UnaryOp.op == Not) + return compiler_jump_if(c, e->v.UnaryOp.operand, next, !cond); + /* fallback to general implementation */ + break; + case BoolOp_kind: { + asdl_seq *s = e->v.BoolOp.values; + Py_ssize_t i, n = asdl_seq_LEN(s) - 1; + assert(n >= 0); + int cond2 = e->v.BoolOp.op == Or; + basicblock *next2 = next; + if (!cond2 != !cond) { + next2 = compiler_new_block(c); + if (next2 == NULL) + return 0; + } + for (i = 0; i < n; ++i) { + if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2)) + return 0; + } + if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond)) + return 0; + if (next2 != next) + compiler_use_next_block(c, next2); + return 1; + } + case IfExp_kind: { + basicblock *end, *next2; + end = compiler_new_block(c); + if (end == NULL) + return 0; + next2 = compiler_new_block(c); + if (next2 == NULL) + return 0; + if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0)) + return 0; + if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) + return 0; + ADDOP_JREL(c, JUMP_FORWARD, end); + compiler_use_next_block(c, next2); + if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) + return 0; + compiler_use_next_block(c, end); + return 1; + } + case Compare_kind: { + Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1; + if (n > 0) { + if (!check_compare(c, e)) { + return 0; + } + basicblock *cleanup = compiler_new_block(c); + if (cleanup == NULL) + return 0; + VISIT(c, expr, e->v.Compare.left); + for (i = 0; i < n; i++) { + VISIT(c, expr, + (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); + ADDOP(c, DUP_TOP); + ADDOP(c, ROT_THREE); + ADDOP_I(c, COMPARE_OP, + cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, i)))); + ADDOP_JABS(c, POP_JUMP_IF_FALSE, cleanup); + NEXT_BLOCK(c); + } + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); + ADDOP_I(c, COMPARE_OP, + cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n)))); + ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + basicblock *end = compiler_new_block(c); + if (end == NULL) + return 0; + ADDOP_JREL(c, JUMP_FORWARD, end); + compiler_use_next_block(c, cleanup); + ADDOP(c, POP_TOP); + if (!cond) { + ADDOP_JREL(c, JUMP_FORWARD, next); + } + compiler_use_next_block(c, end); + return 1; + } + /* fallback to general implementation */ + break; + } + default: + /* fallback to general implementation */ + break; + } + + /* general implementation */ + VISIT(c, expr, e); + ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + return 1; +} + +static int +compiler_ifexp(struct compiler *c, expr_ty e) +{ + basicblock *end, *next; + + assert(e->kind == IfExp_kind); + end = compiler_new_block(c); + if (end == NULL) + return 0; + next = compiler_new_block(c); + if (next == NULL) + return 0; + if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) + return 0; + VISIT(c, expr, e->v.IfExp.body); + ADDOP_JREL(c, JUMP_FORWARD, end); + compiler_use_next_block(c, next); + VISIT(c, expr, e->v.IfExp.orelse); + compiler_use_next_block(c, end); + return 1; +} + +static int +compiler_lambda(struct compiler *c, expr_ty e) +{ + PyCodeObject *co; + PyObject *qualname; + static identifier name; + Py_ssize_t funcflags; + arguments_ty args = e->v.Lambda.args; + assert(e->kind == Lambda_kind); + + if (!name) { + name = PyUnicode_InternFromString(""); + if (!name) + return 0; + } + + funcflags = compiler_default_arguments(c, args); + if (funcflags == -1) { + return 0; + } + + if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA, + (void *)e, e->lineno)) + return 0; + + /* Make None the first constant, so the lambda can't have a + docstring. */ + if (compiler_add_const(c, Py_None) < 0) + return 0; + + c->u->u_argcount = asdl_seq_LEN(args->args); + c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); + c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); + VISIT_IN_SCOPE(c, expr, e->v.Lambda.body); + if (c->u->u_ste->ste_generator) { + co = assemble(c, 0); + } + else { + ADDOP_IN_SCOPE(c, RETURN_VALUE); + co = assemble(c, 1); + } + qualname = c->u->u_qualname; + Py_INCREF(qualname); + compiler_exit_scope(c); + if (co == NULL) + return 0; + + compiler_make_closure(c, co, funcflags, qualname); + Py_DECREF(qualname); + Py_DECREF(co); + + return 1; +} + +static int +compiler_if(struct compiler *c, stmt_ty s) +{ + basicblock *end, *next; + int constant; + assert(s->kind == If_kind); + end = compiler_new_block(c); + if (end == NULL) + return 0; + + constant = expr_constant(s->v.If.test); + /* constant = 0: "if 0" + * constant = 1: "if 1", "if 2", ... + * constant = -1: rest */ + if (constant == 0) { + BEGIN_DO_NOT_EMIT_BYTECODE + VISIT_SEQ(c, stmt, s->v.If.body); + END_DO_NOT_EMIT_BYTECODE + if (s->v.If.orelse) { + VISIT_SEQ(c, stmt, s->v.If.orelse); + } + } else if (constant == 1) { + VISIT_SEQ(c, stmt, s->v.If.body); + if (s->v.If.orelse) { + BEGIN_DO_NOT_EMIT_BYTECODE + VISIT_SEQ(c, stmt, s->v.If.orelse); + END_DO_NOT_EMIT_BYTECODE + } + } else { + if (asdl_seq_LEN(s->v.If.orelse)) { + next = compiler_new_block(c); + if (next == NULL) + return 0; + } + else + next = end; + if (!compiler_jump_if(c, s->v.If.test, next, 0)) + return 0; + VISIT_SEQ(c, stmt, s->v.If.body); + if (asdl_seq_LEN(s->v.If.orelse)) { + ADDOP_JREL(c, JUMP_FORWARD, end); + compiler_use_next_block(c, next); + VISIT_SEQ(c, stmt, s->v.If.orelse); + } + } + compiler_use_next_block(c, end); + return 1; +} + +static int +compiler_for(struct compiler *c, stmt_ty s) +{ + basicblock *start, *cleanup, *end; + + start = compiler_new_block(c); + cleanup = compiler_new_block(c); + end = compiler_new_block(c); + if (start == NULL || end == NULL || cleanup == NULL) + return 0; + + if (!compiler_push_fblock(c, FOR_LOOP, start, end)) + return 0; + + VISIT(c, expr, s->v.For.iter); + ADDOP(c, GET_ITER); + compiler_use_next_block(c, start); + ADDOP_JREL(c, FOR_ITER, cleanup); + VISIT(c, expr, s->v.For.target); + VISIT_SEQ(c, stmt, s->v.For.body); + ADDOP_JABS(c, JUMP_ABSOLUTE, start); + compiler_use_next_block(c, cleanup); + + compiler_pop_fblock(c, FOR_LOOP, start); + + VISIT_SEQ(c, stmt, s->v.For.orelse); + compiler_use_next_block(c, end); + return 1; +} + + +static int +compiler_async_for(struct compiler *c, stmt_ty s) +{ + basicblock *start, *except, *end; + if (IS_TOP_LEVEL_AWAIT(c)){ + c->u->u_ste->ste_coroutine = 1; + } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { + return compiler_error(c, "'async for' outside async function"); + } + + start = compiler_new_block(c); + except = compiler_new_block(c); + end = compiler_new_block(c); + + if (start == NULL || except == NULL || end == NULL) + return 0; + + VISIT(c, expr, s->v.AsyncFor.iter); + ADDOP(c, GET_AITER); + + compiler_use_next_block(c, start); + if (!compiler_push_fblock(c, FOR_LOOP, start, end)) + return 0; + + /* SETUP_FINALLY to guard the __anext__ call */ + ADDOP_JREL(c, SETUP_FINALLY, except); + ADDOP(c, GET_ANEXT); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */ + + /* Success block for __anext__ */ + VISIT(c, expr, s->v.AsyncFor.target); + VISIT_SEQ(c, stmt, s->v.AsyncFor.body); + ADDOP_JABS(c, JUMP_ABSOLUTE, start); + + compiler_pop_fblock(c, FOR_LOOP, start); + + /* Except block for __anext__ */ + compiler_use_next_block(c, except); + ADDOP(c, END_ASYNC_FOR); + + /* `else` block */ + VISIT_SEQ(c, stmt, s->v.For.orelse); + + compiler_use_next_block(c, end); + + return 1; +} + +static int +compiler_while(struct compiler *c, stmt_ty s) +{ + basicblock *loop, *orelse, *end, *anchor = NULL; + int constant = expr_constant(s->v.While.test); + + if (constant == 0) { + BEGIN_DO_NOT_EMIT_BYTECODE + // Push a dummy block so the VISIT_SEQ knows that we are + // inside a while loop so it can correctly evaluate syntax + // errors. + if (!compiler_push_fblock(c, WHILE_LOOP, NULL, NULL)) { + return 0; + } + VISIT_SEQ(c, stmt, s->v.While.body); + // Remove the dummy block now that is not needed. + compiler_pop_fblock(c, WHILE_LOOP, NULL); + END_DO_NOT_EMIT_BYTECODE + if (s->v.While.orelse) { + VISIT_SEQ(c, stmt, s->v.While.orelse); + } + return 1; + } + loop = compiler_new_block(c); + end = compiler_new_block(c); + if (constant == -1) { + anchor = compiler_new_block(c); + if (anchor == NULL) + return 0; + } + if (loop == NULL || end == NULL) + return 0; + if (s->v.While.orelse) { + orelse = compiler_new_block(c); + if (orelse == NULL) + return 0; + } + else + orelse = NULL; + + compiler_use_next_block(c, loop); + if (!compiler_push_fblock(c, WHILE_LOOP, loop, end)) + return 0; + if (constant == -1) { + if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) + return 0; + } + VISIT_SEQ(c, stmt, s->v.While.body); + ADDOP_JABS(c, JUMP_ABSOLUTE, loop); + + /* XXX should the two POP instructions be in a separate block + if there is no else clause ? + */ + + if (constant == -1) + compiler_use_next_block(c, anchor); + compiler_pop_fblock(c, WHILE_LOOP, loop); + + if (orelse != NULL) /* what if orelse is just pass? */ + VISIT_SEQ(c, stmt, s->v.While.orelse); + compiler_use_next_block(c, end); + + return 1; +} + +static int +compiler_return(struct compiler *c, stmt_ty s) +{ + int preserve_tos = ((s->v.Return.value != NULL) && + (s->v.Return.value->kind != Constant_kind)); + if (c->u->u_ste->ste_type != FunctionBlock) + return compiler_error(c, "'return' outside function"); + if (s->v.Return.value != NULL && + c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator) + { + return compiler_error( + c, "'return' with value in async generator"); + } + if (preserve_tos) { + VISIT(c, expr, s->v.Return.value); + } + for (int depth = c->u->u_nfblocks; depth--;) { + struct fblockinfo *info = &c->u->u_fblock[depth]; + + if (!compiler_unwind_fblock(c, info, preserve_tos)) + return 0; + } + if (s->v.Return.value == NULL) { + ADDOP_LOAD_CONST(c, Py_None); + } + else if (!preserve_tos) { + VISIT(c, expr, s->v.Return.value); + } + ADDOP(c, RETURN_VALUE); + + return 1; +} + +static int +compiler_break(struct compiler *c) +{ + for (int depth = c->u->u_nfblocks; depth--;) { + struct fblockinfo *info = &c->u->u_fblock[depth]; + + if (!compiler_unwind_fblock(c, info, 0)) + return 0; + if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) { + ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_exit); + return 1; + } + } + return compiler_error(c, "'break' outside loop"); +} + +static int +compiler_continue(struct compiler *c) +{ + for (int depth = c->u->u_nfblocks; depth--;) { + struct fblockinfo *info = &c->u->u_fblock[depth]; + + if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) { + ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_block); + return 1; + } + if (!compiler_unwind_fblock(c, info, 0)) + return 0; + } + return compiler_error(c, "'continue' not properly in loop"); +} + + +/* Code generated for "try: finally: " is as follows: + + SETUP_FINALLY L + + POP_BLOCK + BEGIN_FINALLY + L: + + END_FINALLY + + The special instructions use the block stack. Each block + stack entry contains the instruction that created it (here + SETUP_FINALLY), the level of the value stack at the time the + block stack entry was created, and a label (here L). + + SETUP_FINALLY: + Pushes the current value stack level and the label + onto the block stack. + POP_BLOCK: + Pops en entry from the block stack. + BEGIN_FINALLY + Pushes NULL onto the value stack. + END_FINALLY: + Pops 1 (NULL or int) or 6 entries from the *value* stack and restore + the raised and the caught exceptions they specify. + + The block stack is unwound when an exception is raised: + when a SETUP_FINALLY entry is found, the raised and the caught + exceptions are pushed onto the value stack (and the exception + condition is cleared), and the interpreter jumps to the label + gotten from the block stack. +*/ + +static int +compiler_try_finally(struct compiler *c, stmt_ty s) +{ + basicblock *start, *newcurblock, *body, *end; + int break_finally = 1; + + body = compiler_new_block(c); + end = compiler_new_block(c); + if (body == NULL || end == NULL) + return 0; + + start = c->u->u_curblock; + + /* `finally` block. Compile it first to determine if any of "break", + "continue" or "return" are used in it. */ + compiler_use_next_block(c, end); + if (!compiler_push_fblock(c, FINALLY_END, end, end)) + return 0; + VISIT_SEQ(c, stmt, s->v.Try.finalbody); + ADDOP(c, END_FINALLY); + break_finally = (c->u->u_fblock[c->u->u_nfblocks - 1].fb_exit == NULL); + if (break_finally) { + /* Pops a placeholder. See below */ + ADDOP(c, POP_TOP); + } + compiler_pop_fblock(c, FINALLY_END, end); + + newcurblock = c->u->u_curblock; + c->u->u_curblock = start; + start->b_next = NULL; + + /* `try` block */ + c->u->u_lineno_set = 0; + c->u->u_lineno = s->lineno; + c->u->u_col_offset = s->col_offset; + if (break_finally) { + /* Pushes a placeholder for the value of "return" in the "try" block + to balance the stack for "break", "continue" and "return" in + the "finally" block. */ + ADDOP_LOAD_CONST(c, Py_None); + } + ADDOP_JREL(c, SETUP_FINALLY, end); + compiler_use_next_block(c, body); + if (!compiler_push_fblock(c, break_finally ? FINALLY_TRY2 : FINALLY_TRY, body, end)) + return 0; + if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { + if (!compiler_try_except(c, s)) + return 0; + } + else { + VISIT_SEQ(c, stmt, s->v.Try.body); + } + ADDOP(c, POP_BLOCK); + ADDOP(c, BEGIN_FINALLY); + compiler_pop_fblock(c, break_finally ? FINALLY_TRY2 : FINALLY_TRY, body); + + c->u->u_curblock->b_next = end; + c->u->u_curblock = newcurblock; + + return 1; +} + +/* + Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...": + (The contents of the value stack is shown in [], with the top + at the right; 'tb' is trace-back info, 'val' the exception's + associated value, and 'exc' the exception.) + + Value stack Label Instruction Argument + [] SETUP_FINALLY L1 + [] + [] POP_BLOCK + [] JUMP_FORWARD L0 + + [tb, val, exc] L1: DUP ) + [tb, val, exc, exc] ) + [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1 + [tb, val, exc, 1-or-0] POP_JUMP_IF_FALSE L2 ) + [tb, val, exc] POP + [tb, val] (or POP if no V1) + [tb] POP + [] + JUMP_FORWARD L0 + + [tb, val, exc] L2: DUP + .............................etc....................... + + [tb, val, exc] Ln+1: END_FINALLY # re-raise exception + + [] L0: + + Of course, parts are not generated if Vi or Ei is not present. +*/ +static int +compiler_try_except(struct compiler *c, stmt_ty s) +{ + basicblock *body, *orelse, *except, *end; + Py_ssize_t i, n; + + body = compiler_new_block(c); + except = compiler_new_block(c); + orelse = compiler_new_block(c); + end = compiler_new_block(c); + if (body == NULL || except == NULL || orelse == NULL || end == NULL) + return 0; + ADDOP_JREL(c, SETUP_FINALLY, except); + compiler_use_next_block(c, body); + if (!compiler_push_fblock(c, EXCEPT, body, NULL)) + return 0; + VISIT_SEQ(c, stmt, s->v.Try.body); + ADDOP(c, POP_BLOCK); + compiler_pop_fblock(c, EXCEPT, body); + ADDOP_JREL(c, JUMP_FORWARD, orelse); + n = asdl_seq_LEN(s->v.Try.handlers); + compiler_use_next_block(c, except); + for (i = 0; i < n; i++) { + excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( + s->v.Try.handlers, i); + if (!handler->v.ExceptHandler.type && i < n-1) + return compiler_error(c, "default 'except:' must be last"); + c->u->u_lineno_set = 0; + c->u->u_lineno = handler->lineno; + c->u->u_col_offset = handler->col_offset; + except = compiler_new_block(c); + if (except == NULL) + return 0; + if (handler->v.ExceptHandler.type) { + ADDOP(c, DUP_TOP); + VISIT(c, expr, handler->v.ExceptHandler.type); + ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH); + ADDOP_JABS(c, POP_JUMP_IF_FALSE, except); + } + ADDOP(c, POP_TOP); + if (handler->v.ExceptHandler.name) { + basicblock *cleanup_end, *cleanup_body; + + cleanup_end = compiler_new_block(c); + cleanup_body = compiler_new_block(c); + if (cleanup_end == NULL || cleanup_body == NULL) { + return 0; + } + + compiler_nameop(c, handler->v.ExceptHandler.name, Store); + ADDOP(c, POP_TOP); + + /* + try: + # body + except type as name: + try: + # body + finally: + name = None # in case body contains "del name" + del name + */ + + /* second try: */ + ADDOP_JREL(c, SETUP_FINALLY, cleanup_end); + compiler_use_next_block(c, cleanup_body); + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, cleanup_end)) + return 0; + + /* second # body */ + VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); + ADDOP(c, POP_BLOCK); + ADDOP(c, BEGIN_FINALLY); + compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); + + /* finally: */ + compiler_use_next_block(c, cleanup_end); + if (!compiler_push_fblock(c, FINALLY_END, cleanup_end, NULL)) + return 0; + + /* name = None; del name */ + ADDOP_LOAD_CONST(c, Py_None); + compiler_nameop(c, handler->v.ExceptHandler.name, Store); + compiler_nameop(c, handler->v.ExceptHandler.name, Del); + + ADDOP(c, END_FINALLY); + ADDOP(c, POP_EXCEPT); + compiler_pop_fblock(c, FINALLY_END, cleanup_end); + } + else { + basicblock *cleanup_body; + + cleanup_body = compiler_new_block(c); + if (!cleanup_body) + return 0; + + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + compiler_use_next_block(c, cleanup_body); + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL)) + return 0; + VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); + ADDOP(c, POP_EXCEPT); + compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); + } + ADDOP_JREL(c, JUMP_FORWARD, end); + compiler_use_next_block(c, except); + } + ADDOP(c, END_FINALLY); + compiler_use_next_block(c, orelse); + VISIT_SEQ(c, stmt, s->v.Try.orelse); + compiler_use_next_block(c, end); + return 1; +} + +static int +compiler_try(struct compiler *c, stmt_ty s) { + if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody)) + return compiler_try_finally(c, s); + else + return compiler_try_except(c, s); +} + + +static int +compiler_import_as(struct compiler *c, identifier name, identifier asname) +{ + /* The IMPORT_NAME opcode was already generated. This function + merely needs to bind the result to a name. + + If there is a dot in name, we need to split it and emit a + IMPORT_FROM for each name. + */ + Py_ssize_t len = PyUnicode_GET_LENGTH(name); + Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1); + if (dot == -2) + return 0; + if (dot != -1) { + /* Consume the base module name to get the first attribute */ + while (1) { + Py_ssize_t pos = dot + 1; + PyObject *attr; + dot = PyUnicode_FindChar(name, '.', pos, len, 1); + if (dot == -2) + return 0; + attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len); + if (!attr) + return 0; + ADDOP_N(c, IMPORT_FROM, attr, names); + if (dot == -1) { + break; + } + ADDOP(c, ROT_TWO); + ADDOP(c, POP_TOP); + } + if (!compiler_nameop(c, asname, Store)) { + return 0; + } + ADDOP(c, POP_TOP); + return 1; + } + return compiler_nameop(c, asname, Store); +} + +static int +compiler_import(struct compiler *c, stmt_ty s) +{ + /* The Import node stores a module name like a.b.c as a single + string. This is convenient for all cases except + import a.b.c as d + where we need to parse that string to extract the individual + module names. + XXX Perhaps change the representation to make this case simpler? + */ + Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names); + + for (i = 0; i < n; i++) { + alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); + int r; + + ADDOP_LOAD_CONST(c, _PyLong_Zero); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP_NAME(c, IMPORT_NAME, alias->name, names); + + if (alias->asname) { + r = compiler_import_as(c, alias->name, alias->asname); + if (!r) + return r; + } + else { + identifier tmp = alias->name; + Py_ssize_t dot = PyUnicode_FindChar( + alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1); + if (dot != -1) { + tmp = PyUnicode_Substring(alias->name, 0, dot); + if (tmp == NULL) + return 0; + } + r = compiler_nameop(c, tmp, Store); + if (dot != -1) { + Py_DECREF(tmp); + } + if (!r) + return r; + } + } + return 1; +} + +static int +compiler_from_import(struct compiler *c, stmt_ty s) +{ + Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names); + PyObject *names; + static PyObject *empty_string; + + if (!empty_string) { + empty_string = PyUnicode_FromString(""); + if (!empty_string) + return 0; + } + + ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level)); + + names = PyTuple_New(n); + if (!names) + return 0; + + /* build up the names */ + for (i = 0; i < n; i++) { + alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); + Py_INCREF(alias->name); + PyTuple_SET_ITEM(names, i, alias->name); + } + + if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module && + _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) { + Py_DECREF(names); + return compiler_error(c, "from __future__ imports must occur " + "at the beginning of the file"); + } + ADDOP_LOAD_CONST_NEW(c, names); + + if (s->v.ImportFrom.module) { + ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); + } + else { + ADDOP_NAME(c, IMPORT_NAME, empty_string, names); + } + for (i = 0; i < n; i++) { + alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); + identifier store_name; + + if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') { + assert(n == 1); + ADDOP(c, IMPORT_STAR); + return 1; + } + + ADDOP_NAME(c, IMPORT_FROM, alias->name, names); + store_name = alias->name; + if (alias->asname) + store_name = alias->asname; + + if (!compiler_nameop(c, store_name, Store)) { + return 0; + } + } + /* remove imported module */ + ADDOP(c, POP_TOP); + return 1; +} + +static int +compiler_assert(struct compiler *c, stmt_ty s) +{ + static PyObject *assertion_error = NULL; + basicblock *end; + + if (c->c_optimize) + return 1; + if (assertion_error == NULL) { + assertion_error = PyUnicode_InternFromString("AssertionError"); + if (assertion_error == NULL) + return 0; + } + if (s->v.Assert.test->kind == Tuple_kind && + asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) + { + if (!compiler_warn(c, "assertion is always true, " + "perhaps remove parentheses?")) + { + return 0; + } + } + end = compiler_new_block(c); + if (end == NULL) + return 0; + if (!compiler_jump_if(c, s->v.Assert.test, end, 1)) + return 0; + ADDOP_O(c, LOAD_GLOBAL, assertion_error, names); + if (s->v.Assert.msg) { + VISIT(c, expr, s->v.Assert.msg); + ADDOP_I(c, CALL_FUNCTION, 1); + } + ADDOP_I(c, RAISE_VARARGS, 1); + compiler_use_next_block(c, end); + return 1; +} + +static int +compiler_visit_stmt_expr(struct compiler *c, expr_ty value) +{ + if (c->c_interactive && c->c_nestlevel <= 1) { + VISIT(c, expr, value); + ADDOP(c, PRINT_EXPR); + return 1; + } + + if (value->kind == Constant_kind) { + /* ignore constant statement */ + return 1; + } + + VISIT(c, expr, value); + ADDOP(c, POP_TOP); + return 1; +} + +static int +compiler_visit_stmt(struct compiler *c, stmt_ty s) +{ + Py_ssize_t i, n; + + /* Always assign a lineno to the next instruction for a stmt. */ + c->u->u_lineno = s->lineno; + c->u->u_col_offset = s->col_offset; + c->u->u_lineno_set = 0; + + switch (s->kind) { + case FunctionDef_kind: + return compiler_function(c, s, 0); + case ClassDef_kind: + return compiler_class(c, s); + case Return_kind: + return compiler_return(c, s); + case Delete_kind: + VISIT_SEQ(c, expr, s->v.Delete.targets) + break; + case Assign_kind: + n = asdl_seq_LEN(s->v.Assign.targets); + VISIT(c, expr, s->v.Assign.value); + for (i = 0; i < n; i++) { + if (i < n - 1) + ADDOP(c, DUP_TOP); + VISIT(c, expr, + (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); + } + break; + case AugAssign_kind: + return compiler_augassign(c, s); + case AnnAssign_kind: + return compiler_annassign(c, s); + case For_kind: + return compiler_for(c, s); + case While_kind: + return compiler_while(c, s); + case If_kind: + return compiler_if(c, s); + case Raise_kind: + n = 0; + if (s->v.Raise.exc) { + VISIT(c, expr, s->v.Raise.exc); + n++; + if (s->v.Raise.cause) { + VISIT(c, expr, s->v.Raise.cause); + n++; + } + } + ADDOP_I(c, RAISE_VARARGS, (int)n); + break; + case Try_kind: + return compiler_try(c, s); + case Assert_kind: + return compiler_assert(c, s); + case Import_kind: + return compiler_import(c, s); + case ImportFrom_kind: + return compiler_from_import(c, s); + case Global_kind: + case Nonlocal_kind: + break; + case Expr_kind: + return compiler_visit_stmt_expr(c, s->v.Expr.value); + case Pass_kind: + break; + case Break_kind: + return compiler_break(c); + case Continue_kind: + return compiler_continue(c); + case With_kind: + return compiler_with(c, s, 0); + case AsyncFunctionDef_kind: + return compiler_function(c, s, 1); + case AsyncWith_kind: + return compiler_async_with(c, s, 0); + case AsyncFor_kind: + return compiler_async_for(c, s); + } + + return 1; +} + +static int +unaryop(unaryop_ty op) +{ + switch (op) { + case Invert: + return UNARY_INVERT; + case Not: + return UNARY_NOT; + case UAdd: + return UNARY_POSITIVE; + case USub: + return UNARY_NEGATIVE; + default: + PyErr_Format(PyExc_SystemError, + "unary op %d should not be possible", op); + return 0; + } +} + +static int +binop(struct compiler *c, operator_ty op) +{ + switch (op) { + case Add: + return BINARY_ADD; + case Sub: + return BINARY_SUBTRACT; + case Mult: + return BINARY_MULTIPLY; + case MatMult: + return BINARY_MATRIX_MULTIPLY; + case Div: + return BINARY_TRUE_DIVIDE; + case Mod: + return BINARY_MODULO; + case Pow: + return BINARY_POWER; + case LShift: + return BINARY_LSHIFT; + case RShift: + return BINARY_RSHIFT; + case BitOr: + return BINARY_OR; + case BitXor: + return BINARY_XOR; + case BitAnd: + return BINARY_AND; + case FloorDiv: + return BINARY_FLOOR_DIVIDE; + default: + PyErr_Format(PyExc_SystemError, + "binary op %d should not be possible", op); + return 0; + } +} + +static int +inplace_binop(struct compiler *c, operator_ty op) +{ + switch (op) { + case Add: + return INPLACE_ADD; + case Sub: + return INPLACE_SUBTRACT; + case Mult: + return INPLACE_MULTIPLY; + case MatMult: + return INPLACE_MATRIX_MULTIPLY; + case Div: + return INPLACE_TRUE_DIVIDE; + case Mod: + return INPLACE_MODULO; + case Pow: + return INPLACE_POWER; + case LShift: + return INPLACE_LSHIFT; + case RShift: + return INPLACE_RSHIFT; + case BitOr: + return INPLACE_OR; + case BitXor: + return INPLACE_XOR; + case BitAnd: + return INPLACE_AND; + case FloorDiv: + return INPLACE_FLOOR_DIVIDE; + default: + PyErr_Format(PyExc_SystemError, + "inplace binary op %d should not be possible", op); + return 0; + } +} + +static int +compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) +{ + int op, scope; + Py_ssize_t arg; + enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; + + PyObject *dict = c->u->u_names; + PyObject *mangled; + /* XXX AugStore isn't used anywhere! */ + + assert(!_PyUnicode_EqualToASCIIString(name, "None") && + !_PyUnicode_EqualToASCIIString(name, "True") && + !_PyUnicode_EqualToASCIIString(name, "False")); + + mangled = _Py_Mangle(c->u->u_private, name); + if (!mangled) + return 0; + + op = 0; + optype = OP_NAME; + scope = PyST_GetScope(c->u->u_ste, mangled); + switch (scope) { + case FREE: + dict = c->u->u_freevars; + optype = OP_DEREF; + break; + case CELL: + dict = c->u->u_cellvars; + optype = OP_DEREF; + break; + case LOCAL: + if (c->u->u_ste->ste_type == FunctionBlock) + optype = OP_FAST; + break; + case GLOBAL_IMPLICIT: + if (c->u->u_ste->ste_type == FunctionBlock) + optype = OP_GLOBAL; + break; + case GLOBAL_EXPLICIT: + optype = OP_GLOBAL; + break; + default: + /* scope can be 0 */ + break; + } + + /* XXX Leave assert here, but handle __doc__ and the like better */ + assert(scope || PyUnicode_READ_CHAR(name, 0) == '_'); + + switch (optype) { + case OP_DEREF: + switch (ctx) { + case Load: + op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF; + break; + case Store: + op = STORE_DEREF; + break; + case AugLoad: + case AugStore: + break; + case Del: op = DELETE_DEREF; break; + case Param: + default: + PyErr_SetString(PyExc_SystemError, + "param invalid for deref variable"); + return 0; + } + break; + case OP_FAST: + switch (ctx) { + case Load: op = LOAD_FAST; break; + case Store: + op = STORE_FAST; + break; + case Del: op = DELETE_FAST; break; + case AugLoad: + case AugStore: + break; + case Param: + default: + PyErr_SetString(PyExc_SystemError, + "param invalid for local variable"); + return 0; + } + ADDOP_N(c, op, mangled, varnames); + return 1; + case OP_GLOBAL: + switch (ctx) { + case Load: op = LOAD_GLOBAL; break; + case Store: + op = STORE_GLOBAL; + break; + case Del: op = DELETE_GLOBAL; break; + case AugLoad: + case AugStore: + break; + case Param: + default: + PyErr_SetString(PyExc_SystemError, + "param invalid for global variable"); + return 0; + } + break; + case OP_NAME: + switch (ctx) { + case Load: op = LOAD_NAME; break; + case Store: + op = STORE_NAME; + break; + case Del: op = DELETE_NAME; break; + case AugLoad: + case AugStore: + break; + case Param: + default: + PyErr_SetString(PyExc_SystemError, + "param invalid for name variable"); + return 0; + } + break; + } + + assert(op); + arg = compiler_add_o(c, dict, mangled); + Py_DECREF(mangled); + if (arg < 0) + return 0; + return compiler_addop_i(c, op, arg); +} + +static int +compiler_boolop(struct compiler *c, expr_ty e) +{ + basicblock *end; + int jumpi; + Py_ssize_t i, n; + asdl_seq *s; + + assert(e->kind == BoolOp_kind); + if (e->v.BoolOp.op == And) + jumpi = JUMP_IF_FALSE_OR_POP; + else + jumpi = JUMP_IF_TRUE_OR_POP; + end = compiler_new_block(c); + if (end == NULL) + return 0; + s = e->v.BoolOp.values; + n = asdl_seq_LEN(s) - 1; + assert(n >= 0); + for (i = 0; i < n; ++i) { + VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); + ADDOP_JABS(c, jumpi, end); + } + VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); + compiler_use_next_block(c, end); + return 1; +} + +static int +starunpack_helper(struct compiler *c, asdl_seq *elts, + int single_op, int inner_op, int outer_op) +{ + Py_ssize_t n = asdl_seq_LEN(elts); + Py_ssize_t i, nsubitems = 0, nseen = 0; + for (i = 0; i < n; i++) { + expr_ty elt = asdl_seq_GET(elts, i); + if (elt->kind == Starred_kind) { + if (nseen) { + ADDOP_I(c, inner_op, nseen); + nseen = 0; + nsubitems++; + } + VISIT(c, expr, elt->v.Starred.value); + nsubitems++; + } + else { + VISIT(c, expr, elt); + nseen++; + } + } + if (nsubitems) { + if (nseen) { + ADDOP_I(c, inner_op, nseen); + nsubitems++; + } + ADDOP_I(c, outer_op, nsubitems); + } + else + ADDOP_I(c, single_op, nseen); + return 1; +} + +static int +assignment_helper(struct compiler *c, asdl_seq *elts) +{ + Py_ssize_t n = asdl_seq_LEN(elts); + Py_ssize_t i; + int seen_star = 0; + for (i = 0; i < n; i++) { + expr_ty elt = asdl_seq_GET(elts, i); + if (elt->kind == Starred_kind && !seen_star) { + if ((i >= (1 << 8)) || + (n-i-1 >= (INT_MAX >> 8))) + return compiler_error(c, + "too many expressions in " + "star-unpacking assignment"); + ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); + seen_star = 1; + asdl_seq_SET(elts, i, elt->v.Starred.value); + } + else if (elt->kind == Starred_kind) { + return compiler_error(c, + "two starred expressions in assignment"); + } + } + if (!seen_star) { + ADDOP_I(c, UNPACK_SEQUENCE, n); + } + VISIT_SEQ(c, expr, elts); + return 1; +} + +static int +compiler_list(struct compiler *c, expr_ty e) +{ + asdl_seq *elts = e->v.List.elts; + if (e->v.List.ctx == Store) { + return assignment_helper(c, elts); + } + else if (e->v.List.ctx == Load) { + return starunpack_helper(c, elts, + BUILD_LIST, BUILD_TUPLE, BUILD_LIST_UNPACK); + } + else + VISIT_SEQ(c, expr, elts); + return 1; +} + +static int +compiler_tuple(struct compiler *c, expr_ty e) +{ + asdl_seq *elts = e->v.Tuple.elts; + if (e->v.Tuple.ctx == Store) { + return assignment_helper(c, elts); + } + else if (e->v.Tuple.ctx == Load) { + return starunpack_helper(c, elts, + BUILD_TUPLE, BUILD_TUPLE, BUILD_TUPLE_UNPACK); + } + else + VISIT_SEQ(c, expr, elts); + return 1; +} + +static int +compiler_set(struct compiler *c, expr_ty e) +{ + return starunpack_helper(c, e->v.Set.elts, BUILD_SET, + BUILD_SET, BUILD_SET_UNPACK); +} + +static int +are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end) +{ + Py_ssize_t i; + for (i = begin; i < end; i++) { + expr_ty key = (expr_ty)asdl_seq_GET(seq, i); + if (key == NULL || key->kind != Constant_kind) + return 0; + } + return 1; +} + +static int +compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end) +{ + Py_ssize_t i, n = end - begin; + PyObject *keys, *key; + if (n > 1 && are_all_items_const(e->v.Dict.keys, begin, end)) { + for (i = begin; i < end; i++) { + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + } + keys = PyTuple_New(n); + if (keys == NULL) { + return 0; + } + for (i = begin; i < end; i++) { + key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value; + Py_INCREF(key); + PyTuple_SET_ITEM(keys, i - begin, key); + } + ADDOP_LOAD_CONST_NEW(c, keys); + ADDOP_I(c, BUILD_CONST_KEY_MAP, n); + } + else { + for (i = begin; i < end; i++) { + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + } + ADDOP_I(c, BUILD_MAP, n); + } + return 1; +} + +static int +compiler_dict(struct compiler *c, expr_ty e) +{ + Py_ssize_t i, n, elements; + int containers; + int is_unpacking = 0; + n = asdl_seq_LEN(e->v.Dict.values); + containers = 0; + elements = 0; + for (i = 0; i < n; i++) { + is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL; + if (elements == 0xFFFF || (elements && is_unpacking)) { + if (!compiler_subdict(c, e, i - elements, i)) + return 0; + containers++; + elements = 0; + } + if (is_unpacking) { + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + containers++; + } + else { + elements++; + } + } + if (elements || containers == 0) { + if (!compiler_subdict(c, e, n - elements, n)) + return 0; + containers++; + } + /* If there is more than one dict, they need to be merged into a new + * dict. If there is one dict and it's an unpacking, then it needs + * to be copied into a new dict." */ + if (containers > 1 || is_unpacking) { + ADDOP_I(c, BUILD_MAP_UNPACK, containers); + } + return 1; +} + +static int +compiler_compare(struct compiler *c, expr_ty e) +{ + Py_ssize_t i, n; + + if (!check_compare(c, e)) { + return 0; + } + VISIT(c, expr, e->v.Compare.left); + assert(asdl_seq_LEN(e->v.Compare.ops) > 0); + n = asdl_seq_LEN(e->v.Compare.ops) - 1; + if (n == 0) { + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); + ADDOP_I(c, COMPARE_OP, + cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, 0)))); + } + else { + basicblock *cleanup = compiler_new_block(c); + if (cleanup == NULL) + return 0; + for (i = 0; i < n; i++) { + VISIT(c, expr, + (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); + ADDOP(c, DUP_TOP); + ADDOP(c, ROT_THREE); + ADDOP_I(c, COMPARE_OP, + cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, i)))); + ADDOP_JABS(c, JUMP_IF_FALSE_OR_POP, cleanup); + NEXT_BLOCK(c); + } + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); + ADDOP_I(c, COMPARE_OP, + cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n)))); + basicblock *end = compiler_new_block(c); + if (end == NULL) + return 0; + ADDOP_JREL(c, JUMP_FORWARD, end); + compiler_use_next_block(c, cleanup); + ADDOP(c, ROT_TWO); + ADDOP(c, POP_TOP); + compiler_use_next_block(c, end); + } + return 1; +} + +static PyTypeObject * +infer_type(expr_ty e) +{ + switch (e->kind) { + case Tuple_kind: + return &PyTuple_Type; + case List_kind: + case ListComp_kind: + return &PyList_Type; + case Dict_kind: + case DictComp_kind: + return &PyDict_Type; + case Set_kind: + case SetComp_kind: + return &PySet_Type; + case GeneratorExp_kind: + return &PyGen_Type; + case Lambda_kind: + return &PyFunction_Type; + case JoinedStr_kind: + case FormattedValue_kind: + return &PyUnicode_Type; + case Constant_kind: + return e->v.Constant.value->ob_type; + default: + return NULL; + } +} + +static int +check_caller(struct compiler *c, expr_ty e) +{ + switch (e->kind) { + case Constant_kind: + case Tuple_kind: + case List_kind: + case ListComp_kind: + case Dict_kind: + case DictComp_kind: + case Set_kind: + case SetComp_kind: + case GeneratorExp_kind: + case JoinedStr_kind: + case FormattedValue_kind: + return compiler_warn(c, "'%.200s' object is not callable; " + "perhaps you missed a comma?", + infer_type(e)->tp_name); + default: + return 1; + } +} + +static int +check_subscripter(struct compiler *c, expr_ty e) +{ + PyObject *v; + + switch (e->kind) { + case Constant_kind: + v = e->v.Constant.value; + if (!(v == Py_None || v == Py_Ellipsis || + PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) || + PyAnySet_Check(v))) + { + return 1; + } + /* fall through */ + case Set_kind: + case SetComp_kind: + case GeneratorExp_kind: + case Lambda_kind: + return compiler_warn(c, "'%.200s' object is not subscriptable; " + "perhaps you missed a comma?", + infer_type(e)->tp_name); + default: + return 1; + } +} + +static int +check_index(struct compiler *c, expr_ty e, slice_ty s) +{ + PyObject *v; + + if (s->kind != Index_kind) { + return 1; + } + PyTypeObject *index_type = infer_type(s->v.Index.value); + if (index_type == NULL + || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS) + || index_type == &PySlice_Type) { + return 1; + } + + switch (e->kind) { + case Constant_kind: + v = e->v.Constant.value; + if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) { + return 1; + } + /* fall through */ + case Tuple_kind: + case List_kind: + case ListComp_kind: + case JoinedStr_kind: + case FormattedValue_kind: + return compiler_warn(c, "%.200s indices must be integers or slices, " + "not %.200s; " + "perhaps you missed a comma?", + infer_type(e)->tp_name, + index_type->tp_name); + default: + return 1; + } +} + +// Return 1 if the method call was optimized, -1 if not, and 0 on error. +static int +maybe_optimize_method_call(struct compiler *c, expr_ty e) +{ + Py_ssize_t argsl, i; + expr_ty meth = e->v.Call.func; + asdl_seq *args = e->v.Call.args; + + /* Check that the call node is an attribute access, and that + the call doesn't have keyword parameters. */ + if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load || + asdl_seq_LEN(e->v.Call.keywords)) + return -1; + + /* Check that there are no *varargs types of arguments. */ + argsl = asdl_seq_LEN(args); + for (i = 0; i < argsl; i++) { + expr_ty elt = asdl_seq_GET(args, i); + if (elt->kind == Starred_kind) { + return -1; + } + } + + /* Alright, we can optimize the code. */ + VISIT(c, expr, meth->v.Attribute.value); + ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names); + VISIT_SEQ(c, expr, e->v.Call.args); + ADDOP_I(c, CALL_METHOD, asdl_seq_LEN(e->v.Call.args)); + return 1; +} + +static int +compiler_call(struct compiler *c, expr_ty e) +{ + int ret = maybe_optimize_method_call(c, e); + if (ret >= 0) { + return ret; + } + if (!check_caller(c, e->v.Call.func)) { + return 0; + } + VISIT(c, expr, e->v.Call.func); + return compiler_call_helper(c, 0, + e->v.Call.args, + e->v.Call.keywords); +} + +static int +compiler_joined_str(struct compiler *c, expr_ty e) +{ + VISIT_SEQ(c, expr, e->v.JoinedStr.values); + if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) + ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); + return 1; +} + +/* Used to implement f-strings. Format a single value. */ +static int +compiler_formatted_value(struct compiler *c, expr_ty e) +{ + /* Our oparg encodes 2 pieces of information: the conversion + character, and whether or not a format_spec was provided. + + Convert the conversion char to 3 bits: + : 000 0x0 FVC_NONE The default if nothing specified. + !s : 001 0x1 FVC_STR + !r : 010 0x2 FVC_REPR + !a : 011 0x3 FVC_ASCII + + next bit is whether or not we have a format spec: + yes : 100 0x4 + no : 000 0x0 + */ + + int conversion = e->v.FormattedValue.conversion; + int oparg; + + /* The expression to be formatted. */ + VISIT(c, expr, e->v.FormattedValue.value); + + switch (conversion) { + case 's': oparg = FVC_STR; break; + case 'r': oparg = FVC_REPR; break; + case 'a': oparg = FVC_ASCII; break; + case -1: oparg = FVC_NONE; break; + default: + PyErr_Format(PyExc_SystemError, + "Unrecognized conversion character %d", conversion); + return 0; + } + if (e->v.FormattedValue.format_spec) { + /* Evaluate the format spec, and update our opcode arg. */ + VISIT(c, expr, e->v.FormattedValue.format_spec); + oparg |= FVS_HAVE_SPEC; + } + + /* And push our opcode and oparg */ + ADDOP_I(c, FORMAT_VALUE, oparg); + + return 1; +} + +static int +compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ssize_t end) +{ + Py_ssize_t i, n = end - begin; + keyword_ty kw; + PyObject *keys, *key; + assert(n > 0); + if (n > 1) { + for (i = begin; i < end; i++) { + kw = asdl_seq_GET(keywords, i); + VISIT(c, expr, kw->value); + } + keys = PyTuple_New(n); + if (keys == NULL) { + return 0; + } + for (i = begin; i < end; i++) { + key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg; + Py_INCREF(key); + PyTuple_SET_ITEM(keys, i - begin, key); + } + ADDOP_LOAD_CONST_NEW(c, keys); + ADDOP_I(c, BUILD_CONST_KEY_MAP, n); + } + else { + /* a for loop only executes once */ + for (i = begin; i < end; i++) { + kw = asdl_seq_GET(keywords, i); + ADDOP_LOAD_CONST(c, kw->arg); + VISIT(c, expr, kw->value); + } + ADDOP_I(c, BUILD_MAP, n); + } + return 1; +} + +/* shared code between compiler_call and compiler_class */ +static int +compiler_call_helper(struct compiler *c, + int n, /* Args already pushed */ + asdl_seq *args, + asdl_seq *keywords) +{ + Py_ssize_t i, nseen, nelts, nkwelts; + int mustdictunpack = 0; + + /* the number of tuples and dictionaries on the stack */ + Py_ssize_t nsubargs = 0, nsubkwargs = 0; + + nelts = asdl_seq_LEN(args); + nkwelts = asdl_seq_LEN(keywords); + + for (i = 0; i < nkwelts; i++) { + keyword_ty kw = asdl_seq_GET(keywords, i); + if (kw->arg == NULL) { + mustdictunpack = 1; + break; + } + } + + nseen = n; /* the number of positional arguments on the stack */ + for (i = 0; i < nelts; i++) { + expr_ty elt = asdl_seq_GET(args, i); + if (elt->kind == Starred_kind) { + /* A star-arg. If we've seen positional arguments, + pack the positional arguments into a tuple. */ + if (nseen) { + ADDOP_I(c, BUILD_TUPLE, nseen); + nseen = 0; + nsubargs++; + } + VISIT(c, expr, elt->v.Starred.value); + nsubargs++; + } + else { + VISIT(c, expr, elt); + nseen++; + } + } + + /* Same dance again for keyword arguments */ + if (nsubargs || mustdictunpack) { + if (nseen) { + /* Pack up any trailing positional arguments. */ + ADDOP_I(c, BUILD_TUPLE, nseen); + nsubargs++; + } + if (nsubargs > 1) { + /* If we ended up with more than one stararg, we need + to concatenate them into a single sequence. */ + ADDOP_I(c, BUILD_TUPLE_UNPACK_WITH_CALL, nsubargs); + } + else if (nsubargs == 0) { + ADDOP_I(c, BUILD_TUPLE, 0); + } + nseen = 0; /* the number of keyword arguments on the stack following */ + for (i = 0; i < nkwelts; i++) { + keyword_ty kw = asdl_seq_GET(keywords, i); + if (kw->arg == NULL) { + /* A keyword argument unpacking. */ + if (nseen) { + if (!compiler_subkwargs(c, keywords, i - nseen, i)) + return 0; + nsubkwargs++; + nseen = 0; + } + VISIT(c, expr, kw->value); + nsubkwargs++; + } + else { + nseen++; + } + } + if (nseen) { + /* Pack up any trailing keyword arguments. */ + if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) + return 0; + nsubkwargs++; + } + if (nsubkwargs > 1) { + /* Pack it all up */ + ADDOP_I(c, BUILD_MAP_UNPACK_WITH_CALL, nsubkwargs); + } + ADDOP_I(c, CALL_FUNCTION_EX, nsubkwargs > 0); + return 1; + } + else if (nkwelts) { + PyObject *names; + VISIT_SEQ(c, keyword, keywords); + names = PyTuple_New(nkwelts); + if (names == NULL) { + return 0; + } + for (i = 0; i < nkwelts; i++) { + keyword_ty kw = asdl_seq_GET(keywords, i); + Py_INCREF(kw->arg); + PyTuple_SET_ITEM(names, i, kw->arg); + } + ADDOP_LOAD_CONST_NEW(c, names); + ADDOP_I(c, CALL_FUNCTION_KW, n + nelts + nkwelts); + return 1; + } + else { + ADDOP_I(c, CALL_FUNCTION, n + nelts); + return 1; + } +} + + +/* List and set comprehensions and generator expressions work by creating a + nested function to perform the actual iteration. This means that the + iteration variables don't leak into the current scope. + The defined function is called immediately following its definition, with the + result of that call being the result of the expression. + The LC/SC version returns the populated container, while the GE version is + flagged in symtable.c as a generator, so it returns the generator object + when the function is called. + + Possible cleanups: + - iterate over the generator sequence instead of using recursion +*/ + + +static int +compiler_comprehension_generator(struct compiler *c, + asdl_seq *generators, int gen_index, + expr_ty elt, expr_ty val, int type) +{ + comprehension_ty gen; + gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + if (gen->is_async) { + return compiler_async_comprehension_generator( + c, generators, gen_index, elt, val, type); + } else { + return compiler_sync_comprehension_generator( + c, generators, gen_index, elt, val, type); + } +} + +static int +compiler_sync_comprehension_generator(struct compiler *c, + asdl_seq *generators, int gen_index, + expr_ty elt, expr_ty val, int type) +{ + /* generate code for the iterator, then each of the ifs, + and then write to the element */ + + comprehension_ty gen; + basicblock *start, *anchor, *skip, *if_cleanup; + Py_ssize_t i, n; + + start = compiler_new_block(c); + skip = compiler_new_block(c); + if_cleanup = compiler_new_block(c); + anchor = compiler_new_block(c); + + if (start == NULL || skip == NULL || if_cleanup == NULL || + anchor == NULL) + return 0; + + gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + + if (gen_index == 0) { + /* Receive outermost iter as an implicit argument */ + c->u->u_argcount = 1; + ADDOP_I(c, LOAD_FAST, 0); + } + else { + /* Sub-iter - calculate on the fly */ + VISIT(c, expr, gen->iter); + ADDOP(c, GET_ITER); + } + compiler_use_next_block(c, start); + ADDOP_JREL(c, FOR_ITER, anchor); + NEXT_BLOCK(c); + VISIT(c, expr, gen->target); + + /* XXX this needs to be cleaned up...a lot! */ + n = asdl_seq_LEN(gen->ifs); + for (i = 0; i < n; i++) { + expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); + if (!compiler_jump_if(c, e, if_cleanup, 0)) + return 0; + NEXT_BLOCK(c); + } + + if (++gen_index < asdl_seq_LEN(generators)) + if (!compiler_comprehension_generator(c, + generators, gen_index, + elt, val, type)) + return 0; + + /* only append after the last for generator */ + if (gen_index >= asdl_seq_LEN(generators)) { + /* comprehension specific code */ + switch (type) { + case COMP_GENEXP: + VISIT(c, expr, elt); + ADDOP(c, YIELD_VALUE); + ADDOP(c, POP_TOP); + break; + case COMP_LISTCOMP: + VISIT(c, expr, elt); + ADDOP_I(c, LIST_APPEND, gen_index + 1); + break; + case COMP_SETCOMP: + VISIT(c, expr, elt); + ADDOP_I(c, SET_ADD, gen_index + 1); + break; + case COMP_DICTCOMP: + /* With '{k: v}', k is evaluated before v, so we do + the same. */ + VISIT(c, expr, elt); + VISIT(c, expr, val); + ADDOP_I(c, MAP_ADD, gen_index + 1); + break; + default: + return 0; + } + + compiler_use_next_block(c, skip); + } + compiler_use_next_block(c, if_cleanup); + ADDOP_JABS(c, JUMP_ABSOLUTE, start); + compiler_use_next_block(c, anchor); + + return 1; +} + +static int +compiler_async_comprehension_generator(struct compiler *c, + asdl_seq *generators, int gen_index, + expr_ty elt, expr_ty val, int type) +{ + comprehension_ty gen; + basicblock *start, *if_cleanup, *except; + Py_ssize_t i, n; + start = compiler_new_block(c); + except = compiler_new_block(c); + if_cleanup = compiler_new_block(c); + + if (start == NULL || if_cleanup == NULL || except == NULL) { + return 0; + } + + gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + + if (gen_index == 0) { + /* Receive outermost iter as an implicit argument */ + c->u->u_argcount = 1; + ADDOP_I(c, LOAD_FAST, 0); + } + else { + /* Sub-iter - calculate on the fly */ + VISIT(c, expr, gen->iter); + ADDOP(c, GET_AITER); + } + + compiler_use_next_block(c, start); + + ADDOP_JREL(c, SETUP_FINALLY, except); + ADDOP(c, GET_ANEXT); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + ADDOP(c, POP_BLOCK); + VISIT(c, expr, gen->target); + + n = asdl_seq_LEN(gen->ifs); + for (i = 0; i < n; i++) { + expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); + if (!compiler_jump_if(c, e, if_cleanup, 0)) + return 0; + NEXT_BLOCK(c); + } + + if (++gen_index < asdl_seq_LEN(generators)) + if (!compiler_comprehension_generator(c, + generators, gen_index, + elt, val, type)) + return 0; + + /* only append after the last for generator */ + if (gen_index >= asdl_seq_LEN(generators)) { + /* comprehension specific code */ + switch (type) { + case COMP_GENEXP: + VISIT(c, expr, elt); + ADDOP(c, YIELD_VALUE); + ADDOP(c, POP_TOP); + break; + case COMP_LISTCOMP: + VISIT(c, expr, elt); + ADDOP_I(c, LIST_APPEND, gen_index + 1); + break; + case COMP_SETCOMP: + VISIT(c, expr, elt); + ADDOP_I(c, SET_ADD, gen_index + 1); + break; + case COMP_DICTCOMP: + /* With '{k: v}', k is evaluated before v, so we do + the same. */ + VISIT(c, expr, elt); + VISIT(c, expr, val); + ADDOP_I(c, MAP_ADD, gen_index + 1); + break; + default: + return 0; + } + } + compiler_use_next_block(c, if_cleanup); + ADDOP_JABS(c, JUMP_ABSOLUTE, start); + + compiler_use_next_block(c, except); + ADDOP(c, END_ASYNC_FOR); + + return 1; +} + +static int +compiler_comprehension(struct compiler *c, expr_ty e, int type, + identifier name, asdl_seq *generators, expr_ty elt, + expr_ty val) +{ + PyCodeObject *co = NULL; + comprehension_ty outermost; + PyObject *qualname = NULL; + int is_async_generator = 0; + int top_level_await = IS_TOP_LEVEL_AWAIT(c); + + + int is_async_function = c->u->u_ste->ste_coroutine; + + outermost = (comprehension_ty) asdl_seq_GET(generators, 0); + if (!compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION, + (void *)e, e->lineno)) + { + goto error; + } + + is_async_generator = c->u->u_ste->ste_coroutine; + + if (is_async_generator && !is_async_function && type != COMP_GENEXP && !top_level_await) { + compiler_error(c, "asynchronous comprehension outside of " + "an asynchronous function"); + goto error_in_scope; + } + + if (type != COMP_GENEXP) { + int op; + switch (type) { + case COMP_LISTCOMP: + op = BUILD_LIST; + break; + case COMP_SETCOMP: + op = BUILD_SET; + break; + case COMP_DICTCOMP: + op = BUILD_MAP; + break; + default: + PyErr_Format(PyExc_SystemError, + "unknown comprehension type %d", type); + goto error_in_scope; + } + + ADDOP_I(c, op, 0); + } + + if (!compiler_comprehension_generator(c, generators, 0, elt, + val, type)) + goto error_in_scope; + + if (type != COMP_GENEXP) { + ADDOP(c, RETURN_VALUE); + } + + co = assemble(c, 1); + qualname = c->u->u_qualname; + Py_INCREF(qualname); + compiler_exit_scope(c); + if (top_level_await && is_async_generator){ + c->u->u_ste->ste_coroutine = 1; + } + if (co == NULL) + goto error; + + if (!compiler_make_closure(c, co, 0, qualname)) + goto error; + Py_DECREF(qualname); + Py_DECREF(co); + + VISIT(c, expr, outermost->iter); + + if (outermost->is_async) { + ADDOP(c, GET_AITER); + } else { + ADDOP(c, GET_ITER); + } + + ADDOP_I(c, CALL_FUNCTION, 1); + + if (is_async_generator && type != COMP_GENEXP) { + ADDOP(c, GET_AWAITABLE); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + } + + return 1; +error_in_scope: + compiler_exit_scope(c); +error: + Py_XDECREF(qualname); + Py_XDECREF(co); + return 0; +} + +static int +compiler_genexp(struct compiler *c, expr_ty e) +{ + static identifier name; + if (!name) { + name = PyUnicode_InternFromString(""); + if (!name) + return 0; + } + assert(e->kind == GeneratorExp_kind); + return compiler_comprehension(c, e, COMP_GENEXP, name, + e->v.GeneratorExp.generators, + e->v.GeneratorExp.elt, NULL); +} + +static int +compiler_listcomp(struct compiler *c, expr_ty e) +{ + static identifier name; + if (!name) { + name = PyUnicode_InternFromString(""); + if (!name) + return 0; + } + assert(e->kind == ListComp_kind); + return compiler_comprehension(c, e, COMP_LISTCOMP, name, + e->v.ListComp.generators, + e->v.ListComp.elt, NULL); +} + +static int +compiler_setcomp(struct compiler *c, expr_ty e) +{ + static identifier name; + if (!name) { + name = PyUnicode_InternFromString(""); + if (!name) + return 0; + } + assert(e->kind == SetComp_kind); + return compiler_comprehension(c, e, COMP_SETCOMP, name, + e->v.SetComp.generators, + e->v.SetComp.elt, NULL); +} + + +static int +compiler_dictcomp(struct compiler *c, expr_ty e) +{ + static identifier name; + if (!name) { + name = PyUnicode_InternFromString(""); + if (!name) + return 0; + } + assert(e->kind == DictComp_kind); + return compiler_comprehension(c, e, COMP_DICTCOMP, name, + e->v.DictComp.generators, + e->v.DictComp.key, e->v.DictComp.value); +} + + +static int +compiler_visit_keyword(struct compiler *c, keyword_ty k) +{ + VISIT(c, expr, k->value); + return 1; +} + +/* Test whether expression is constant. For constants, report + whether they are true or false. + + Return values: 1 for true, 0 for false, -1 for non-constant. + */ + +static int +expr_constant(expr_ty e) +{ + if (e->kind == Constant_kind) { + return PyObject_IsTrue(e->v.Constant.value); + } + return -1; +} + + +/* + Implements the async with statement. + + The semantics outlined in that PEP are as follows: + + async with EXPR as VAR: + BLOCK + + It is implemented roughly as: + + context = EXPR + exit = context.__aexit__ # not calling it + value = await context.__aenter__() + try: + VAR = value # if VAR present in the syntax + BLOCK + finally: + if an exception was raised: + exc = copy of (exception, instance, traceback) + else: + exc = (None, None, None) + if not (await exit(*exc)): + raise + */ +static int +compiler_async_with(struct compiler *c, stmt_ty s, int pos) +{ + basicblock *block, *finally; + withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos); + + assert(s->kind == AsyncWith_kind); + if (IS_TOP_LEVEL_AWAIT(c)){ + c->u->u_ste->ste_coroutine = 1; + } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){ + return compiler_error(c, "'async with' outside async function"); + } + + block = compiler_new_block(c); + finally = compiler_new_block(c); + if (!block || !finally) + return 0; + + /* Evaluate EXPR */ + VISIT(c, expr, item->context_expr); + + ADDOP(c, BEFORE_ASYNC_WITH); + ADDOP(c, GET_AWAITABLE); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + + ADDOP_JREL(c, SETUP_ASYNC_WITH, finally); + + /* SETUP_ASYNC_WITH pushes a finally block. */ + compiler_use_next_block(c, block); + if (!compiler_push_fblock(c, ASYNC_WITH, block, finally)) { + return 0; + } + + if (item->optional_vars) { + VISIT(c, expr, item->optional_vars); + } + else { + /* Discard result from context.__aenter__() */ + ADDOP(c, POP_TOP); + } + + pos++; + if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) + /* BLOCK code */ + VISIT_SEQ(c, stmt, s->v.AsyncWith.body) + else if (!compiler_async_with(c, s, pos)) + return 0; + + /* End of try block; start the finally block */ + ADDOP(c, POP_BLOCK); + ADDOP(c, BEGIN_FINALLY); + compiler_pop_fblock(c, ASYNC_WITH, block); + + compiler_use_next_block(c, finally); + if (!compiler_push_fblock(c, FINALLY_END, finally, NULL)) + return 0; + + /* Finally block starts; context.__exit__ is on the stack under + the exception or return information. Just issue our magic + opcode. */ + ADDOP(c, WITH_CLEANUP_START); + + ADDOP(c, GET_AWAITABLE); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + + ADDOP(c, WITH_CLEANUP_FINISH); + + /* Finally block ends. */ + ADDOP(c, END_FINALLY); + compiler_pop_fblock(c, FINALLY_END, finally); + return 1; +} + + +/* + Implements the with statement from PEP 343. + + The semantics outlined in that PEP are as follows: + + with EXPR as VAR: + BLOCK + + It is implemented roughly as: + + context = EXPR + exit = context.__exit__ # not calling it + value = context.__enter__() + try: + VAR = value # if VAR present in the syntax + BLOCK + finally: + if an exception was raised: + exc = copy of (exception, instance, traceback) + else: + exc = (None, None, None) + exit(*exc) + */ +static int +compiler_with(struct compiler *c, stmt_ty s, int pos) +{ + basicblock *block, *finally; + withitem_ty item = asdl_seq_GET(s->v.With.items, pos); + + assert(s->kind == With_kind); + + block = compiler_new_block(c); + finally = compiler_new_block(c); + if (!block || !finally) + return 0; + + /* Evaluate EXPR */ + VISIT(c, expr, item->context_expr); + ADDOP_JREL(c, SETUP_WITH, finally); + + /* SETUP_WITH pushes a finally block. */ + compiler_use_next_block(c, block); + if (!compiler_push_fblock(c, WITH, block, finally)) { + return 0; + } + + if (item->optional_vars) { + VISIT(c, expr, item->optional_vars); + } + else { + /* Discard result from context.__enter__() */ + ADDOP(c, POP_TOP); + } + + pos++; + if (pos == asdl_seq_LEN(s->v.With.items)) + /* BLOCK code */ + VISIT_SEQ(c, stmt, s->v.With.body) + else if (!compiler_with(c, s, pos)) + return 0; + + /* End of try block; start the finally block */ + ADDOP(c, POP_BLOCK); + ADDOP(c, BEGIN_FINALLY); + compiler_pop_fblock(c, WITH, block); + + compiler_use_next_block(c, finally); + if (!compiler_push_fblock(c, FINALLY_END, finally, NULL)) + return 0; + + /* Finally block starts; context.__exit__ is on the stack under + the exception or return information. Just issue our magic + opcode. */ + ADDOP(c, WITH_CLEANUP_START); + ADDOP(c, WITH_CLEANUP_FINISH); + + /* Finally block ends. */ + ADDOP(c, END_FINALLY); + compiler_pop_fblock(c, FINALLY_END, finally); + return 1; +} + +static int +compiler_visit_expr1(struct compiler *c, expr_ty e) +{ + switch (e->kind) { + case NamedExpr_kind: + VISIT(c, expr, e->v.NamedExpr.value); + ADDOP(c, DUP_TOP); + VISIT(c, expr, e->v.NamedExpr.target); + break; + case BoolOp_kind: + return compiler_boolop(c, e); + case BinOp_kind: + VISIT(c, expr, e->v.BinOp.left); + VISIT(c, expr, e->v.BinOp.right); + ADDOP(c, binop(c, e->v.BinOp.op)); + break; + case UnaryOp_kind: + VISIT(c, expr, e->v.UnaryOp.operand); + ADDOP(c, unaryop(e->v.UnaryOp.op)); + break; + case Lambda_kind: + return compiler_lambda(c, e); + case IfExp_kind: + return compiler_ifexp(c, e); + case Dict_kind: + return compiler_dict(c, e); + case Set_kind: + return compiler_set(c, e); + case GeneratorExp_kind: + return compiler_genexp(c, e); + case ListComp_kind: + return compiler_listcomp(c, e); + case SetComp_kind: + return compiler_setcomp(c, e); + case DictComp_kind: + return compiler_dictcomp(c, e); + case Yield_kind: + if (c->u->u_ste->ste_type != FunctionBlock) + return compiler_error(c, "'yield' outside function"); + if (e->v.Yield.value) { + VISIT(c, expr, e->v.Yield.value); + } + else { + ADDOP_LOAD_CONST(c, Py_None); + } + ADDOP(c, YIELD_VALUE); + break; + case YieldFrom_kind: + if (c->u->u_ste->ste_type != FunctionBlock) + return compiler_error(c, "'yield' outside function"); + + if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) + return compiler_error(c, "'yield from' inside async function"); + + VISIT(c, expr, e->v.YieldFrom.value); + ADDOP(c, GET_YIELD_FROM_ITER); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + break; + case Await_kind: + if (!IS_TOP_LEVEL_AWAIT(c)){ + if (c->u->u_ste->ste_type != FunctionBlock){ + return compiler_error(c, "'await' outside function"); + } + + if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && + c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){ + return compiler_error(c, "'await' outside async function"); + } + } + + VISIT(c, expr, e->v.Await.value); + ADDOP(c, GET_AWAITABLE); + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, YIELD_FROM); + break; + case Compare_kind: + return compiler_compare(c, e); + case Call_kind: + return compiler_call(c, e); + case Constant_kind: + ADDOP_LOAD_CONST(c, e->v.Constant.value); + break; + case JoinedStr_kind: + return compiler_joined_str(c, e); + case FormattedValue_kind: + return compiler_formatted_value(c, e); + /* The following exprs can be assignment targets. */ + case Attribute_kind: + if (e->v.Attribute.ctx != AugStore) + VISIT(c, expr, e->v.Attribute.value); + switch (e->v.Attribute.ctx) { + case AugLoad: + ADDOP(c, DUP_TOP); + /* Fall through */ + case Load: + ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); + break; + case AugStore: + ADDOP(c, ROT_TWO); + /* Fall through */ + case Store: + ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); + break; + case Del: + ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names); + break; + case Param: + default: + PyErr_SetString(PyExc_SystemError, + "param invalid in attribute expression"); + return 0; + } + break; + case Subscript_kind: + switch (e->v.Subscript.ctx) { + case AugLoad: + VISIT(c, expr, e->v.Subscript.value); + VISIT_SLICE(c, e->v.Subscript.slice, AugLoad); + break; + case Load: + if (!check_subscripter(c, e->v.Subscript.value)) { + return 0; + } + if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) { + return 0; + } + VISIT(c, expr, e->v.Subscript.value); + VISIT_SLICE(c, e->v.Subscript.slice, Load); + break; + case AugStore: + VISIT_SLICE(c, e->v.Subscript.slice, AugStore); + break; + case Store: + VISIT(c, expr, e->v.Subscript.value); + VISIT_SLICE(c, e->v.Subscript.slice, Store); + break; + case Del: + VISIT(c, expr, e->v.Subscript.value); + VISIT_SLICE(c, e->v.Subscript.slice, Del); + break; + case Param: + default: + PyErr_SetString(PyExc_SystemError, + "param invalid in subscript expression"); + return 0; + } + break; + case Starred_kind: + switch (e->v.Starred.ctx) { + case Store: + /* In all legitimate cases, the Starred node was already replaced + * by compiler_list/compiler_tuple. XXX: is that okay? */ + return compiler_error(c, + "starred assignment target must be in a list or tuple"); + default: + return compiler_error(c, + "can't use starred expression here"); + } + case Name_kind: + return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); + /* child nodes of List and Tuple will have expr_context set */ + case List_kind: + return compiler_list(c, e); + case Tuple_kind: + return compiler_tuple(c, e); + } + return 1; +} + +static int +compiler_visit_expr(struct compiler *c, expr_ty e) +{ + /* If expr e has a different line number than the last expr/stmt, + set a new line number for the next instruction. + */ + int old_lineno = c->u->u_lineno; + int old_col_offset = c->u->u_col_offset; + if (e->lineno != c->u->u_lineno) { + c->u->u_lineno = e->lineno; + c->u->u_lineno_set = 0; + } + /* Updating the column offset is always harmless. */ + c->u->u_col_offset = e->col_offset; + + int res = compiler_visit_expr1(c, e); + + if (old_lineno != c->u->u_lineno) { + c->u->u_lineno = old_lineno; + c->u->u_lineno_set = 0; + } + c->u->u_col_offset = old_col_offset; + return res; +} + +static int +compiler_augassign(struct compiler *c, stmt_ty s) +{ + expr_ty e = s->v.AugAssign.target; + expr_ty auge; + + assert(s->kind == AugAssign_kind); + + switch (e->kind) { + case Attribute_kind: + auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr, + AugLoad, e->lineno, e->col_offset, + e->end_lineno, e->end_col_offset, c->c_arena); + if (auge == NULL) + return 0; + VISIT(c, expr, auge); + VISIT(c, expr, s->v.AugAssign.value); + ADDOP(c, inplace_binop(c, s->v.AugAssign.op)); + auge->v.Attribute.ctx = AugStore; + VISIT(c, expr, auge); + break; + case Subscript_kind: + auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice, + AugLoad, e->lineno, e->col_offset, + e->end_lineno, e->end_col_offset, c->c_arena); + if (auge == NULL) + return 0; + VISIT(c, expr, auge); + VISIT(c, expr, s->v.AugAssign.value); + ADDOP(c, inplace_binop(c, s->v.AugAssign.op)); + auge->v.Subscript.ctx = AugStore; + VISIT(c, expr, auge); + break; + case Name_kind: + if (!compiler_nameop(c, e->v.Name.id, Load)) + return 0; + VISIT(c, expr, s->v.AugAssign.value); + ADDOP(c, inplace_binop(c, s->v.AugAssign.op)); + return compiler_nameop(c, e->v.Name.id, Store); + default: + PyErr_Format(PyExc_SystemError, + "invalid node type (%d) for augmented assignment", + e->kind); + return 0; + } + return 1; +} + +static int +check_ann_expr(struct compiler *c, expr_ty e) +{ + VISIT(c, expr, e); + ADDOP(c, POP_TOP); + return 1; +} + +static int +check_annotation(struct compiler *c, stmt_ty s) +{ + /* Annotations are only evaluated in a module or class. */ + if (c->u->u_scope_type == COMPILER_SCOPE_MODULE || + c->u->u_scope_type == COMPILER_SCOPE_CLASS) { + return check_ann_expr(c, s->v.AnnAssign.annotation); + } + return 1; +} + +static int +check_ann_slice(struct compiler *c, slice_ty sl) +{ + switch(sl->kind) { + case Index_kind: + return check_ann_expr(c, sl->v.Index.value); + case Slice_kind: + if (sl->v.Slice.lower && !check_ann_expr(c, sl->v.Slice.lower)) { + return 0; + } + if (sl->v.Slice.upper && !check_ann_expr(c, sl->v.Slice.upper)) { + return 0; + } + if (sl->v.Slice.step && !check_ann_expr(c, sl->v.Slice.step)) { + return 0; + } + break; + default: + PyErr_SetString(PyExc_SystemError, + "unexpected slice kind"); + return 0; + } + return 1; +} + +static int +check_ann_subscr(struct compiler *c, slice_ty sl) +{ + /* We check that everything in a subscript is defined at runtime. */ + Py_ssize_t i, n; + + switch (sl->kind) { + case Index_kind: + case Slice_kind: + if (!check_ann_slice(c, sl)) { + return 0; + } + break; + case ExtSlice_kind: + n = asdl_seq_LEN(sl->v.ExtSlice.dims); + for (i = 0; i < n; i++) { + slice_ty subsl = (slice_ty)asdl_seq_GET(sl->v.ExtSlice.dims, i); + switch (subsl->kind) { + case Index_kind: + case Slice_kind: + if (!check_ann_slice(c, subsl)) { + return 0; + } + break; + case ExtSlice_kind: + default: + PyErr_SetString(PyExc_SystemError, + "extended slice invalid in nested slice"); + return 0; + } + } + break; + default: + PyErr_Format(PyExc_SystemError, + "invalid subscript kind %d", sl->kind); + return 0; + } + return 1; +} + +static int +compiler_annassign(struct compiler *c, stmt_ty s) +{ + expr_ty targ = s->v.AnnAssign.target; + PyObject* mangled; + + assert(s->kind == AnnAssign_kind); + + /* We perform the actual assignment first. */ + if (s->v.AnnAssign.value) { + VISIT(c, expr, s->v.AnnAssign.value); + VISIT(c, expr, targ); + } + switch (targ->kind) { + case Name_kind: + /* If we have a simple name in a module or class, store annotation. */ + if (s->v.AnnAssign.simple && + (c->u->u_scope_type == COMPILER_SCOPE_MODULE || + c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { + if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { + VISIT(c, annexpr, s->v.AnnAssign.annotation) + } + else { + VISIT(c, expr, s->v.AnnAssign.annotation); + } + ADDOP_NAME(c, LOAD_NAME, __annotations__, names); + mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id); + ADDOP_LOAD_CONST_NEW(c, mangled); + ADDOP(c, STORE_SUBSCR); + } + break; + case Attribute_kind: + if (!s->v.AnnAssign.value && + !check_ann_expr(c, targ->v.Attribute.value)) { + return 0; + } + break; + case Subscript_kind: + if (!s->v.AnnAssign.value && + (!check_ann_expr(c, targ->v.Subscript.value) || + !check_ann_subscr(c, targ->v.Subscript.slice))) { + return 0; + } + break; + default: + PyErr_Format(PyExc_SystemError, + "invalid node type (%d) for annotated assignment", + targ->kind); + return 0; + } + /* Annotation is evaluated last. */ + if (!s->v.AnnAssign.simple && !check_annotation(c, s)) { + return 0; + } + return 1; +} + +/* Raises a SyntaxError and returns 0. + If something goes wrong, a different exception may be raised. +*/ + +static int +compiler_error(struct compiler *c, const char *errstr) +{ + PyObject *loc; + PyObject *u = NULL, *v = NULL; + + loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno); + if (!loc) { + Py_INCREF(Py_None); + loc = Py_None; + } + u = Py_BuildValue("(OiiO)", c->c_filename, c->u->u_lineno, + c->u->u_col_offset + 1, loc); + if (!u) + goto exit; + v = Py_BuildValue("(zO)", errstr, u); + if (!v) + goto exit; + PyErr_SetObject(PyExc_SyntaxError, v); + exit: + Py_DECREF(loc); + Py_XDECREF(u); + Py_XDECREF(v); + return 0; +} + +/* Emits a SyntaxWarning and returns 1 on success. + If a SyntaxWarning raised as error, replaces it with a SyntaxError + and returns 0. +*/ +static int +compiler_warn(struct compiler *c, const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + PyObject *msg = PyUnicode_FromFormatV(format, vargs); + va_end(vargs); + if (msg == NULL) { + return 0; + } + if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename, + c->u->u_lineno, NULL, NULL) < 0) + { + if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { + /* Replace the SyntaxWarning exception with a SyntaxError + to get a more accurate error report */ + PyErr_Clear(); + assert(PyUnicode_AsUTF8(msg) != NULL); + compiler_error(c, PyUnicode_AsUTF8(msg)); + } + Py_DECREF(msg); + return 0; + } + Py_DECREF(msg); + return 1; +} + +static int +compiler_handle_subscr(struct compiler *c, const char *kind, + expr_context_ty ctx) +{ + int op = 0; + + /* XXX this code is duplicated */ + switch (ctx) { + case AugLoad: /* fall through to Load */ + case Load: op = BINARY_SUBSCR; break; + case AugStore:/* fall through to Store */ + case Store: op = STORE_SUBSCR; break; + case Del: op = DELETE_SUBSCR; break; + case Param: + PyErr_Format(PyExc_SystemError, + "invalid %s kind %d in subscript\n", + kind, ctx); + return 0; + } + if (ctx == AugLoad) { + ADDOP(c, DUP_TOP_TWO); + } + else if (ctx == AugStore) { + ADDOP(c, ROT_THREE); + } + ADDOP(c, op); + return 1; +} + +static int +compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) +{ + int n = 2; + assert(s->kind == Slice_kind); + + /* only handles the cases where BUILD_SLICE is emitted */ + if (s->v.Slice.lower) { + VISIT(c, expr, s->v.Slice.lower); + } + else { + ADDOP_LOAD_CONST(c, Py_None); + } + + if (s->v.Slice.upper) { + VISIT(c, expr, s->v.Slice.upper); + } + else { + ADDOP_LOAD_CONST(c, Py_None); + } + + if (s->v.Slice.step) { + n++; + VISIT(c, expr, s->v.Slice.step); + } + ADDOP_I(c, BUILD_SLICE, n); + return 1; +} + +static int +compiler_visit_nested_slice(struct compiler *c, slice_ty s, + expr_context_ty ctx) +{ + switch (s->kind) { + case Slice_kind: + return compiler_slice(c, s, ctx); + case Index_kind: + VISIT(c, expr, s->v.Index.value); + break; + case ExtSlice_kind: + default: + PyErr_SetString(PyExc_SystemError, + "extended slice invalid in nested slice"); + return 0; + } + return 1; +} + +static int +compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) +{ + const char * kindname = NULL; + switch (s->kind) { + case Index_kind: + kindname = "index"; + if (ctx != AugStore) { + VISIT(c, expr, s->v.Index.value); + } + break; + case Slice_kind: + kindname = "slice"; + if (ctx != AugStore) { + if (!compiler_slice(c, s, ctx)) + return 0; + } + break; + case ExtSlice_kind: + kindname = "extended slice"; + if (ctx != AugStore) { + Py_ssize_t i, n = asdl_seq_LEN(s->v.ExtSlice.dims); + for (i = 0; i < n; i++) { + slice_ty sub = (slice_ty)asdl_seq_GET( + s->v.ExtSlice.dims, i); + if (!compiler_visit_nested_slice(c, sub, ctx)) + return 0; + } + ADDOP_I(c, BUILD_TUPLE, n); + } + break; + default: + PyErr_Format(PyExc_SystemError, + "invalid subscript kind %d", s->kind); + return 0; + } + return compiler_handle_subscr(c, kindname, ctx); +} + +/* End of the compiler section, beginning of the assembler section */ + +/* do depth-first search of basic block graph, starting with block. + post records the block indices in post-order. + + XXX must handle implicit jumps from one block to next +*/ + +struct assembler { + PyObject *a_bytecode; /* string containing bytecode */ + int a_offset; /* offset into bytecode */ + int a_nblocks; /* number of reachable blocks */ + basicblock **a_postorder; /* list of blocks in dfs postorder */ + PyObject *a_lnotab; /* string containing lnotab */ + int a_lnotab_off; /* offset into lnotab */ + int a_lineno; /* last lineno of emitted instruction */ + int a_lineno_off; /* bytecode offset of last lineno */ +}; + +static void +dfs(struct compiler *c, basicblock *b, struct assembler *a, int end) +{ + int i, j; + + /* Get rid of recursion for normal control flow. + Since the number of blocks is limited, unused space in a_postorder + (from a_nblocks to end) can be used as a stack for still not ordered + blocks. */ + for (j = end; b && !b->b_seen; b = b->b_next) { + b->b_seen = 1; + assert(a->a_nblocks < j); + a->a_postorder[--j] = b; + } + while (j < end) { + b = a->a_postorder[j++]; + for (i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + if (instr->i_jrel || instr->i_jabs) + dfs(c, instr->i_target, a, j); + } + assert(a->a_nblocks < j); + a->a_postorder[a->a_nblocks++] = b; + } +} + +Py_LOCAL_INLINE(void) +stackdepth_push(basicblock ***sp, basicblock *b, int depth) +{ + assert(b->b_startdepth < 0 || b->b_startdepth == depth); + if (b->b_startdepth < depth) { + assert(b->b_startdepth < 0); + b->b_startdepth = depth; + *(*sp)++ = b; + } +} + +/* Find the flow path that needs the largest stack. We assume that + * cycles in the flow graph have no net effect on the stack depth. + */ +static int +stackdepth(struct compiler *c) +{ + basicblock *b, *entryblock = NULL; + basicblock **stack, **sp; + int nblocks = 0, maxdepth = 0; + for (b = c->u->u_blocks; b != NULL; b = b->b_list) { + b->b_startdepth = INT_MIN; + entryblock = b; + nblocks++; + } + if (!entryblock) + return 0; + stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * nblocks); + if (!stack) { + PyErr_NoMemory(); + return -1; + } + + sp = stack; + stackdepth_push(&sp, entryblock, 0); + while (sp != stack) { + b = *--sp; + int depth = b->b_startdepth; + assert(depth >= 0); + basicblock *next = b->b_next; + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0); + if (effect == PY_INVALID_STACK_EFFECT) { + fprintf(stderr, "opcode = %d\n", instr->i_opcode); + Py_FatalError("PyCompile_OpcodeStackEffect()"); + } + int new_depth = depth + effect; + if (new_depth > maxdepth) { + maxdepth = new_depth; + } + assert(depth >= 0); /* invalid code or bug in stackdepth() */ + if (instr->i_jrel || instr->i_jabs) { + effect = stack_effect(instr->i_opcode, instr->i_oparg, 1); + assert(effect != PY_INVALID_STACK_EFFECT); + int target_depth = depth + effect; + if (target_depth > maxdepth) { + maxdepth = target_depth; + } + assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ + if (instr->i_opcode == CALL_FINALLY) { + assert(instr->i_target->b_startdepth >= 0); + assert(instr->i_target->b_startdepth >= target_depth); + depth = new_depth; + continue; + } + stackdepth_push(&sp, instr->i_target, target_depth); + } + depth = new_depth; + if (instr->i_opcode == JUMP_ABSOLUTE || + instr->i_opcode == JUMP_FORWARD || + instr->i_opcode == RETURN_VALUE || + instr->i_opcode == RAISE_VARARGS) + { + /* remaining code is dead */ + next = NULL; + break; + } + } + if (next != NULL) { + stackdepth_push(&sp, next, depth); + } + } + PyObject_Free(stack); + return maxdepth; +} + +static int +assemble_init(struct assembler *a, int nblocks, int firstlineno) +{ + memset(a, 0, sizeof(struct assembler)); + a->a_lineno = firstlineno; + a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); + if (!a->a_bytecode) + return 0; + a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); + if (!a->a_lnotab) + return 0; + if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { + PyErr_NoMemory(); + return 0; + } + a->a_postorder = (basicblock **)PyObject_Malloc( + sizeof(basicblock *) * nblocks); + if (!a->a_postorder) { + PyErr_NoMemory(); + return 0; + } + return 1; +} + +static void +assemble_free(struct assembler *a) +{ + Py_XDECREF(a->a_bytecode); + Py_XDECREF(a->a_lnotab); + if (a->a_postorder) + PyObject_Free(a->a_postorder); +} + +static int +blocksize(basicblock *b) +{ + int i; + int size = 0; + + for (i = 0; i < b->b_iused; i++) + size += instrsize(b->b_instr[i].i_oparg); + return size; +} + +/* Appends a pair to the end of the line number table, a_lnotab, representing + the instruction's bytecode offset and line number. See + Objects/lnotab_notes.txt for the description of the line number table. */ + +static int +assemble_lnotab(struct assembler *a, struct instr *i) +{ + int d_bytecode, d_lineno; + Py_ssize_t len; + unsigned char *lnotab; + + d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT); + d_lineno = i->i_lineno - a->a_lineno; + + assert(d_bytecode >= 0); + + if(d_bytecode == 0 && d_lineno == 0) + return 1; + + if (d_bytecode > 255) { + int j, nbytes, ncodes = d_bytecode / 255; + nbytes = a->a_lnotab_off + 2 * ncodes; + len = PyBytes_GET_SIZE(a->a_lnotab); + if (nbytes >= len) { + if ((len <= INT_MAX / 2) && (len * 2 < nbytes)) + len = nbytes; + else if (len <= INT_MAX / 2) + len *= 2; + else { + PyErr_NoMemory(); + return 0; + } + if (_PyBytes_Resize(&a->a_lnotab, len) < 0) + return 0; + } + lnotab = (unsigned char *) + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + for (j = 0; j < ncodes; j++) { + *lnotab++ = 255; + *lnotab++ = 0; + } + d_bytecode -= ncodes * 255; + a->a_lnotab_off += ncodes * 2; + } + assert(0 <= d_bytecode && d_bytecode <= 255); + + if (d_lineno < -128 || 127 < d_lineno) { + int j, nbytes, ncodes, k; + if (d_lineno < 0) { + k = -128; + /* use division on positive numbers */ + ncodes = (-d_lineno) / 128; + } + else { + k = 127; + ncodes = d_lineno / 127; + } + d_lineno -= ncodes * k; + assert(ncodes >= 1); + nbytes = a->a_lnotab_off + 2 * ncodes; + len = PyBytes_GET_SIZE(a->a_lnotab); + if (nbytes >= len) { + if ((len <= INT_MAX / 2) && len * 2 < nbytes) + len = nbytes; + else if (len <= INT_MAX / 2) + len *= 2; + else { + PyErr_NoMemory(); + return 0; + } + if (_PyBytes_Resize(&a->a_lnotab, len) < 0) + return 0; + } + lnotab = (unsigned char *) + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + *lnotab++ = d_bytecode; + *lnotab++ = k; + d_bytecode = 0; + for (j = 1; j < ncodes; j++) { + *lnotab++ = 0; + *lnotab++ = k; + } + a->a_lnotab_off += ncodes * 2; + } + assert(-128 <= d_lineno && d_lineno <= 127); + + len = PyBytes_GET_SIZE(a->a_lnotab); + if (a->a_lnotab_off + 2 >= len) { + if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0) + return 0; + } + lnotab = (unsigned char *) + PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; + + a->a_lnotab_off += 2; + if (d_bytecode) { + *lnotab++ = d_bytecode; + *lnotab++ = d_lineno; + } + else { /* First line of a block; def stmt, etc. */ + *lnotab++ = 0; + *lnotab++ = d_lineno; + } + a->a_lineno = i->i_lineno; + a->a_lineno_off = a->a_offset; + return 1; +} + +/* assemble_emit() + Extend the bytecode with a new instruction. + Update lnotab if necessary. +*/ + +static int +assemble_emit(struct assembler *a, struct instr *i) +{ + int size, arg = 0; + Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); + _Py_CODEUNIT *code; + + arg = i->i_oparg; + size = instrsize(arg); + if (i->i_lineno && !assemble_lnotab(a, i)) + return 0; + if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) { + if (len > PY_SSIZE_T_MAX / 2) + return 0; + if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) + return 0; + } + code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; + a->a_offset += size; + write_op_arg(code, i->i_opcode, arg, size); + return 1; +} + +static void +assemble_jump_offsets(struct assembler *a, struct compiler *c) +{ + basicblock *b; + int bsize, totsize, extended_arg_recompile; + int i; + + /* Compute the size of each block and fixup jump args. + Replace block pointer with position in bytecode. */ + do { + totsize = 0; + for (i = a->a_nblocks - 1; i >= 0; i--) { + b = a->a_postorder[i]; + bsize = blocksize(b); + b->b_offset = totsize; + totsize += bsize; + } + extended_arg_recompile = 0; + for (b = c->u->u_blocks; b != NULL; b = b->b_list) { + bsize = b->b_offset; + for (i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + int isize = instrsize(instr->i_oparg); + /* Relative jumps are computed relative to + the instruction pointer after fetching + the jump instruction. + */ + bsize += isize; + if (instr->i_jabs || instr->i_jrel) { + instr->i_oparg = instr->i_target->b_offset; + if (instr->i_jrel) { + instr->i_oparg -= bsize; + } + instr->i_oparg *= sizeof(_Py_CODEUNIT); + if (instrsize(instr->i_oparg) != isize) { + extended_arg_recompile = 1; + } + } + } + } + + /* XXX: This is an awful hack that could hurt performance, but + on the bright side it should work until we come up + with a better solution. + + The issue is that in the first loop blocksize() is called + which calls instrsize() which requires i_oparg be set + appropriately. There is a bootstrap problem because + i_oparg is calculated in the second loop above. + + So we loop until we stop seeing new EXTENDED_ARGs. + The only EXTENDED_ARGs that could be popping up are + ones in jump instructions. So this should converge + fairly quickly. + */ + } while (extended_arg_recompile); +} + +static PyObject * +dict_keys_inorder(PyObject *dict, Py_ssize_t offset) +{ + PyObject *tuple, *k, *v; + Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); + + tuple = PyTuple_New(size); + if (tuple == NULL) + return NULL; + while (PyDict_Next(dict, &pos, &k, &v)) { + i = PyLong_AS_LONG(v); + Py_INCREF(k); + assert((i - offset) < size); + assert((i - offset) >= 0); + PyTuple_SET_ITEM(tuple, i - offset, k); + } + return tuple; +} + +static PyObject * +consts_dict_keys_inorder(PyObject *dict) +{ + PyObject *consts, *k, *v; + Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); + + consts = PyList_New(size); /* PyCode_Optimize() requires a list */ + if (consts == NULL) + return NULL; + while (PyDict_Next(dict, &pos, &k, &v)) { + i = PyLong_AS_LONG(v); + /* The keys of the dictionary can be tuples wrapping a contant. + * (see compiler_add_o and _PyCode_ConstantKey). In that case + * the object we want is always second. */ + if (PyTuple_CheckExact(k)) { + k = PyTuple_GET_ITEM(k, 1); + } + Py_INCREF(k); + assert(i < size); + assert(i >= 0); + PyList_SET_ITEM(consts, i, k); + } + return consts; +} + +static int +compute_code_flags(struct compiler *c) +{ + PySTEntryObject *ste = c->u->u_ste; + int flags = 0; + if (ste->ste_type == FunctionBlock) { + flags |= CO_NEWLOCALS | CO_OPTIMIZED; + if (ste->ste_nested) + flags |= CO_NESTED; + if (ste->ste_generator && !ste->ste_coroutine) + flags |= CO_GENERATOR; + if (!ste->ste_generator && ste->ste_coroutine) + flags |= CO_COROUTINE; + if (ste->ste_generator && ste->ste_coroutine) + flags |= CO_ASYNC_GENERATOR; + if (ste->ste_varargs) + flags |= CO_VARARGS; + if (ste->ste_varkeywords) + flags |= CO_VARKEYWORDS; + } + + /* (Only) inherit compilerflags in PyCF_MASK */ + flags |= (c->c_flags->cf_flags & PyCF_MASK); + + if ((IS_TOP_LEVEL_AWAIT(c)) && + ste->ste_coroutine && + !ste->ste_generator) { + flags |= CO_COROUTINE; + } + + return flags; +} + +// Merge *tuple* with constant cache. +// Unlike merge_consts_recursive(), this function doesn't work recursively. +static int +merge_const_tuple(struct compiler *c, PyObject **tuple) +{ + assert(PyTuple_CheckExact(*tuple)); + + PyObject *key = _PyCode_ConstantKey(*tuple); + if (key == NULL) { + return 0; + } + + // t is borrowed reference + PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); + Py_DECREF(key); + if (t == NULL) { + return 0; + } + if (t == key) { // tuple is new constant. + return 1; + } + + PyObject *u = PyTuple_GET_ITEM(t, 1); + Py_INCREF(u); + Py_DECREF(*tuple); + *tuple = u; + return 1; +} + +static PyCodeObject * +makecode(struct compiler *c, struct assembler *a) +{ + PyObject *tmp; + PyCodeObject *co = NULL; + PyObject *consts = NULL; + PyObject *names = NULL; + PyObject *varnames = NULL; + PyObject *name = NULL; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + PyObject *bytecode = NULL; + Py_ssize_t nlocals; + int nlocals_int; + int flags; + int posorkeywordargcount, posonlyargcount, kwonlyargcount, maxdepth; + + consts = consts_dict_keys_inorder(c->u->u_consts); + names = dict_keys_inorder(c->u->u_names, 0); + varnames = dict_keys_inorder(c->u->u_varnames, 0); + if (!consts || !names || !varnames) + goto error; + + cellvars = dict_keys_inorder(c->u->u_cellvars, 0); + if (!cellvars) + goto error; + freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_GET_SIZE(cellvars)); + if (!freevars) + goto error; + + if (!merge_const_tuple(c, &names) || + !merge_const_tuple(c, &varnames) || + !merge_const_tuple(c, &cellvars) || + !merge_const_tuple(c, &freevars)) + { + goto error; + } + + nlocals = PyDict_GET_SIZE(c->u->u_varnames); + assert(nlocals < INT_MAX); + nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int); + + flags = compute_code_flags(c); + if (flags < 0) + goto error; + + bytecode = PyCode_Optimize(a->a_bytecode, consts, names, a->a_lnotab); + if (!bytecode) + goto error; + + tmp = PyList_AsTuple(consts); /* PyCode_New requires a tuple */ + if (!tmp) + goto error; + Py_DECREF(consts); + consts = tmp; + if (!merge_const_tuple(c, &consts)) { + goto error; + } + + posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int); + posorkeywordargcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int); + kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int); + maxdepth = stackdepth(c); + if (maxdepth < 0) { + goto error; + } + co = PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount, + posonlyargcount, kwonlyargcount, nlocals_int, + maxdepth, flags, bytecode, consts, names, + varnames, freevars, cellvars, c->c_filename, + c->u->u_name, c->u->u_firstlineno, a->a_lnotab); + error: + Py_XDECREF(consts); + Py_XDECREF(names); + Py_XDECREF(varnames); + Py_XDECREF(name); + Py_XDECREF(freevars); + Py_XDECREF(cellvars); + Py_XDECREF(bytecode); + return co; +} + + +/* For debugging purposes only */ +#if 0 +static void +dump_instr(const struct instr *i) +{ + const char *jrel = i->i_jrel ? "jrel " : ""; + const char *jabs = i->i_jabs ? "jabs " : ""; + char arg[128]; + + *arg = '\0'; + if (HAS_ARG(i->i_opcode)) { + sprintf(arg, "arg: %d ", i->i_oparg); + } + fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", + i->i_lineno, i->i_opcode, arg, jabs, jrel); +} + +static void +dump_basicblock(const basicblock *b) +{ + const char *seen = b->b_seen ? "seen " : ""; + const char *b_return = b->b_return ? "return " : ""; + fprintf(stderr, "used: %d, depth: %d, offset: %d %s%s\n", + b->b_iused, b->b_startdepth, b->b_offset, seen, b_return); + if (b->b_instr) { + int i; + for (i = 0; i < b->b_iused; i++) { + fprintf(stderr, " [%02d] ", i); + dump_instr(b->b_instr + i); + } + } +} +#endif + +static PyCodeObject * +assemble(struct compiler *c, int addNone) +{ + basicblock *b, *entryblock; + struct assembler a; + int i, j, nblocks; + PyCodeObject *co = NULL; + + /* Make sure every block that falls off the end returns None. + XXX NEXT_BLOCK() isn't quite right, because if the last + block ends with a jump or return b_next shouldn't set. + */ + if (!c->u->u_curblock->b_return) { + NEXT_BLOCK(c); + if (addNone) + ADDOP_LOAD_CONST(c, Py_None); + ADDOP(c, RETURN_VALUE); + } + + nblocks = 0; + entryblock = NULL; + for (b = c->u->u_blocks; b != NULL; b = b->b_list) { + nblocks++; + entryblock = b; + } + + /* Set firstlineno if it wasn't explicitly set. */ + if (!c->u->u_firstlineno) { + if (entryblock && entryblock->b_instr && entryblock->b_instr->i_lineno) + c->u->u_firstlineno = entryblock->b_instr->i_lineno; + else + c->u->u_firstlineno = 1; + } + if (!assemble_init(&a, nblocks, c->u->u_firstlineno)) + goto error; + dfs(c, entryblock, &a, nblocks); + + /* Can't modify the bytecode after computing jump offsets. */ + assemble_jump_offsets(&a, c); + + /* Emit code in reverse postorder from dfs. */ + for (i = a.a_nblocks - 1; i >= 0; i--) { + b = a.a_postorder[i]; + for (j = 0; j < b->b_iused; j++) + if (!assemble_emit(&a, &b->b_instr[j])) + goto error; + } + + if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) + goto error; + if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) + goto error; + + co = makecode(c, &a); + error: + assemble_free(&a); + return co; +} + +#undef PyAST_Compile +PyCodeObject * +PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, + PyArena *arena) +{ + return PyAST_CompileEx(mod, filename, flags, -1, arena); +} diff --git a/python/Python/condvar.h b/python/Python/condvar.h new file mode 100755 index 0000000..8cba19b --- /dev/null +++ b/python/Python/condvar.h @@ -0,0 +1,309 @@ +/* + * Portable condition variable support for windows and pthreads. + * Everything is inline, this header can be included where needed. + * + * APIs generally return 0 on success and non-zero on error, + * and the caller needs to use its platform's error mechanism to + * discover the error (errno, or GetLastError()) + * + * Note that some implementations cannot distinguish between a + * condition variable wait time-out and successful wait. Most often + * the difference is moot anyway since the wait condition must be + * re-checked. + * PyCOND_TIMEDWAIT, in addition to returning negative on error, + * thus returns 0 on regular success, 1 on timeout + * or 2 if it can't tell. + * + * There are at least two caveats with using these condition variables, + * due to the fact that they may be emulated with Semaphores on + * Windows: + * 1) While PyCOND_SIGNAL() will wake up at least one thread, we + * cannot currently guarantee that it will be one of the threads + * already waiting in a PyCOND_WAIT() call. It _could_ cause + * the wakeup of a subsequent thread to try a PyCOND_WAIT(), + * including the thread doing the PyCOND_SIGNAL() itself. + * The same applies to PyCOND_BROADCAST(), if N threads are waiting + * then at least N threads will be woken up, but not necessarily + * those already waiting. + * For this reason, don't make the scheduling assumption that a + * specific other thread will get the wakeup signal + * 2) The _mutex_ must be held when calling PyCOND_SIGNAL() and + * PyCOND_BROADCAST(). + * While e.g. the posix standard strongly recommends that the mutex + * associated with the condition variable is held when a + * pthread_cond_signal() call is made, this is not a hard requirement, + * although scheduling will not be "reliable" if it isn't. Here + * the mutex is used for internal synchronization of the emulated + * Condition Variable. + */ + +#ifndef _CONDVAR_IMPL_H_ +#define _CONDVAR_IMPL_H_ + +#include "Python.h" +#include "pycore_condvar.h" + +#ifdef _POSIX_THREADS +/* + * POSIX support + */ + +/* These private functions are implemented in Python/thread_pthread.h */ +int _PyThread_cond_init(PyCOND_T *cond); +void _PyThread_cond_after(long long us, struct timespec *abs); + +/* The following functions return 0 on success, nonzero on error */ +#define PyMUTEX_INIT(mut) pthread_mutex_init((mut), NULL) +#define PyMUTEX_FINI(mut) pthread_mutex_destroy(mut) +#define PyMUTEX_LOCK(mut) pthread_mutex_lock(mut) +#define PyMUTEX_UNLOCK(mut) pthread_mutex_unlock(mut) + +#define PyCOND_INIT(cond) _PyThread_cond_init(cond) +#define PyCOND_FINI(cond) pthread_cond_destroy(cond) +#define PyCOND_SIGNAL(cond) pthread_cond_signal(cond) +#define PyCOND_BROADCAST(cond) pthread_cond_broadcast(cond) +#define PyCOND_WAIT(cond, mut) pthread_cond_wait((cond), (mut)) + +/* return 0 for success, 1 on timeout, -1 on error */ +Py_LOCAL_INLINE(int) +PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) +{ + struct timespec abs; + _PyThread_cond_after(us, &abs); + int ret = pthread_cond_timedwait(cond, mut, &abs); + if (ret == ETIMEDOUT) { + return 1; + } + if (ret) { + return -1; + } + return 0; +} + +#elif defined(NT_THREADS) +/* + * Windows (XP, 2003 server and later, as well as (hopefully) CE) support + * + * Emulated condition variables ones that work with XP and later, plus + * example native support on VISTA and onwards. + */ + +#if _PY_EMULATED_WIN_CV + +/* The mutex is a CriticalSection object and + The condition variables is emulated with the help of a semaphore. + + This implementation still has the problem that the threads woken + with a "signal" aren't necessarily those that are already + waiting. It corresponds to listing 2 in: + http://birrell.org/andrew/papers/ImplementingCVs.pdf + + Generic emulations of the pthread_cond_* API using + earlier Win32 functions can be found on the Web. + The following read can be give background information to these issues, + but the implementations are all broken in some way. + http://www.cse.wustl.edu/~schmidt/win32-cv-1.html +*/ + +Py_LOCAL_INLINE(int) +PyMUTEX_INIT(PyMUTEX_T *cs) +{ + InitializeCriticalSection(cs); + return 0; +} + +Py_LOCAL_INLINE(int) +PyMUTEX_FINI(PyMUTEX_T *cs) +{ + DeleteCriticalSection(cs); + return 0; +} + +Py_LOCAL_INLINE(int) +PyMUTEX_LOCK(PyMUTEX_T *cs) +{ + EnterCriticalSection(cs); + return 0; +} + +Py_LOCAL_INLINE(int) +PyMUTEX_UNLOCK(PyMUTEX_T *cs) +{ + LeaveCriticalSection(cs); + return 0; +} + + +Py_LOCAL_INLINE(int) +PyCOND_INIT(PyCOND_T *cv) +{ + /* A semaphore with a "large" max value, The positive value + * is only needed to catch those "lost wakeup" events and + * race conditions when a timed wait elapses. + */ + cv->sem = CreateSemaphore(NULL, 0, 100000, NULL); + if (cv->sem==NULL) + return -1; + cv->waiting = 0; + return 0; +} + +Py_LOCAL_INLINE(int) +PyCOND_FINI(PyCOND_T *cv) +{ + return CloseHandle(cv->sem) ? 0 : -1; +} + +/* this implementation can detect a timeout. Returns 1 on timeout, + * 0 otherwise (and -1 on error) + */ +Py_LOCAL_INLINE(int) +_PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms) +{ + DWORD wait; + cv->waiting++; + PyMUTEX_UNLOCK(cs); + /* "lost wakeup bug" would occur if the caller were interrupted here, + * but we are safe because we are using a semaphore which has an internal + * count. + */ + wait = WaitForSingleObjectEx(cv->sem, ms, FALSE); + PyMUTEX_LOCK(cs); + if (wait != WAIT_OBJECT_0) + --cv->waiting; + /* Here we have a benign race condition with PyCOND_SIGNAL. + * When failure occurs or timeout, it is possible that + * PyCOND_SIGNAL also decrements this value + * and signals releases the mutex. This is benign because it + * just means an extra spurious wakeup for a waiting thread. + * ('waiting' corresponds to the semaphore's "negative" count and + * we may end up with e.g. (waiting == -1 && sem.count == 1). When + * a new thread comes along, it will pass right through, having + * adjusted it to (waiting == 0 && sem.count == 0). + */ + + if (wait == WAIT_FAILED) + return -1; + /* return 0 on success, 1 on timeout */ + return wait != WAIT_OBJECT_0; +} + +Py_LOCAL_INLINE(int) +PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) +{ + int result = _PyCOND_WAIT_MS(cv, cs, INFINITE); + return result >= 0 ? 0 : result; +} + +Py_LOCAL_INLINE(int) +PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us) +{ + return _PyCOND_WAIT_MS(cv, cs, (DWORD)(us/1000)); +} + +Py_LOCAL_INLINE(int) +PyCOND_SIGNAL(PyCOND_T *cv) +{ + /* this test allows PyCOND_SIGNAL to be a no-op unless required + * to wake someone up, thus preventing an unbounded increase of + * the semaphore's internal counter. + */ + if (cv->waiting > 0) { + /* notifying thread decreases the cv->waiting count so that + * a delay between notify and actual wakeup of the target thread + * doesn't cause a number of extra ReleaseSemaphore calls. + */ + cv->waiting--; + return ReleaseSemaphore(cv->sem, 1, NULL) ? 0 : -1; + } + return 0; +} + +Py_LOCAL_INLINE(int) +PyCOND_BROADCAST(PyCOND_T *cv) +{ + int waiting = cv->waiting; + if (waiting > 0) { + cv->waiting = 0; + return ReleaseSemaphore(cv->sem, waiting, NULL) ? 0 : -1; + } + return 0; +} + +#else /* !_PY_EMULATED_WIN_CV */ + +Py_LOCAL_INLINE(int) +PyMUTEX_INIT(PyMUTEX_T *cs) +{ + InitializeSRWLock(cs); + return 0; +} + +Py_LOCAL_INLINE(int) +PyMUTEX_FINI(PyMUTEX_T *cs) +{ + return 0; +} + +Py_LOCAL_INLINE(int) +PyMUTEX_LOCK(PyMUTEX_T *cs) +{ + AcquireSRWLockExclusive(cs); + return 0; +} + +Py_LOCAL_INLINE(int) +PyMUTEX_UNLOCK(PyMUTEX_T *cs) +{ + ReleaseSRWLockExclusive(cs); + return 0; +} + + +Py_LOCAL_INLINE(int) +PyCOND_INIT(PyCOND_T *cv) +{ + InitializeConditionVariable(cv); + return 0; +} +Py_LOCAL_INLINE(int) +PyCOND_FINI(PyCOND_T *cv) +{ + return 0; +} + +Py_LOCAL_INLINE(int) +PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) +{ + return SleepConditionVariableSRW(cv, cs, INFINITE, 0) ? 0 : -1; +} + +/* This implementation makes no distinction about timeouts. Signal + * 2 to indicate that we don't know. + */ +Py_LOCAL_INLINE(int) +PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long long us) +{ + return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1; +} + +Py_LOCAL_INLINE(int) +PyCOND_SIGNAL(PyCOND_T *cv) +{ + WakeConditionVariable(cv); + return 0; +} + +Py_LOCAL_INLINE(int) +PyCOND_BROADCAST(PyCOND_T *cv) +{ + WakeAllConditionVariable(cv); + return 0; +} + + +#endif /* _PY_EMULATED_WIN_CV */ + +#endif /* _POSIX_THREADS, NT_THREADS */ + +#endif /* _CONDVAR_IMPL_H_ */ diff --git a/python/Python/context.c b/python/Python/context.c new file mode 100755 index 0000000..5c30e47 --- /dev/null +++ b/python/Python/context.c @@ -0,0 +1,1307 @@ +#include "Python.h" + +#include "pycore_context.h" +#include "pycore_hamt.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "structmember.h" + + +#define CONTEXT_FREELIST_MAXLEN 255 +static PyContext *ctx_freelist = NULL; +static int ctx_freelist_len = 0; + + +#include "clinic/context.c.h" +/*[clinic input] +module _contextvars +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a0955718c8b8cea6]*/ + + +#define ENSURE_Context(o, err_ret) \ + if (!PyContext_CheckExact(o)) { \ + PyErr_SetString(PyExc_TypeError, \ + "an instance of Context was expected"); \ + return err_ret; \ + } + +#define ENSURE_ContextVar(o, err_ret) \ + if (!PyContextVar_CheckExact(o)) { \ + PyErr_SetString(PyExc_TypeError, \ + "an instance of ContextVar was expected"); \ + return err_ret; \ + } + +#define ENSURE_ContextToken(o, err_ret) \ + if (!PyContextToken_CheckExact(o)) { \ + PyErr_SetString(PyExc_TypeError, \ + "an instance of Token was expected"); \ + return err_ret; \ + } + + +/////////////////////////// Context API + + +static PyContext * +context_new_empty(void); + +static PyContext * +context_new_from_vars(PyHamtObject *vars); + +static inline PyContext * +context_get(void); + +static PyContextToken * +token_new(PyContext *ctx, PyContextVar *var, PyObject *val); + +static PyContextVar * +contextvar_new(PyObject *name, PyObject *def); + +static int +contextvar_set(PyContextVar *var, PyObject *val); + +static int +contextvar_del(PyContextVar *var); + + +PyObject * +_PyContext_NewHamtForTests(void) +{ + return (PyObject *)_PyHamt_New(); +} + + +PyObject * +PyContext_New(void) +{ + return (PyObject *)context_new_empty(); +} + + +PyObject * +PyContext_Copy(PyObject * octx) +{ + ENSURE_Context(octx, NULL) + PyContext *ctx = (PyContext *)octx; + return (PyObject *)context_new_from_vars(ctx->ctx_vars); +} + + +PyObject * +PyContext_CopyCurrent(void) +{ + PyContext *ctx = context_get(); + if (ctx == NULL) { + return NULL; + } + + return (PyObject *)context_new_from_vars(ctx->ctx_vars); +} + + +int +PyContext_Enter(PyObject *octx) +{ + ENSURE_Context(octx, -1) + PyContext *ctx = (PyContext *)octx; + + if (ctx->ctx_entered) { + PyErr_Format(PyExc_RuntimeError, + "cannot enter context: %R is already entered", ctx); + return -1; + } + + PyThreadState *ts = _PyThreadState_GET(); + assert(ts != NULL); + + ctx->ctx_prev = (PyContext *)ts->context; /* borrow */ + ctx->ctx_entered = 1; + + Py_INCREF(ctx); + ts->context = (PyObject *)ctx; + ts->context_ver++; + + return 0; +} + + +int +PyContext_Exit(PyObject *octx) +{ + ENSURE_Context(octx, -1) + PyContext *ctx = (PyContext *)octx; + + if (!ctx->ctx_entered) { + PyErr_Format(PyExc_RuntimeError, + "cannot exit context: %R has not been entered", ctx); + return -1; + } + + PyThreadState *ts = _PyThreadState_GET(); + assert(ts != NULL); + + if (ts->context != (PyObject *)ctx) { + /* Can only happen if someone misuses the C API */ + PyErr_SetString(PyExc_RuntimeError, + "cannot exit context: thread state references " + "a different context object"); + return -1; + } + + Py_SETREF(ts->context, (PyObject *)ctx->ctx_prev); + ts->context_ver++; + + ctx->ctx_prev = NULL; + ctx->ctx_entered = 0; + + return 0; +} + + +PyObject * +PyContextVar_New(const char *name, PyObject *def) +{ + PyObject *pyname = PyUnicode_FromString(name); + if (pyname == NULL) { + return NULL; + } + PyContextVar *var = contextvar_new(pyname, def); + Py_DECREF(pyname); + return (PyObject *)var; +} + + +int +PyContextVar_Get(PyObject *ovar, PyObject *def, PyObject **val) +{ + ENSURE_ContextVar(ovar, -1) + PyContextVar *var = (PyContextVar *)ovar; + + PyThreadState *ts = _PyThreadState_GET(); + assert(ts != NULL); + if (ts->context == NULL) { + goto not_found; + } + + if (var->var_cached != NULL && + var->var_cached_tsid == ts->id && + var->var_cached_tsver == ts->context_ver) + { + *val = var->var_cached; + goto found; + } + + assert(PyContext_CheckExact(ts->context)); + PyHamtObject *vars = ((PyContext *)ts->context)->ctx_vars; + + PyObject *found = NULL; + int res = _PyHamt_Find(vars, (PyObject*)var, &found); + if (res < 0) { + goto error; + } + if (res == 1) { + assert(found != NULL); + var->var_cached = found; /* borrow */ + var->var_cached_tsid = ts->id; + var->var_cached_tsver = ts->context_ver; + + *val = found; + goto found; + } + +not_found: + if (def == NULL) { + if (var->var_default != NULL) { + *val = var->var_default; + goto found; + } + + *val = NULL; + goto found; + } + else { + *val = def; + goto found; + } + +found: + Py_XINCREF(*val); + return 0; + +error: + *val = NULL; + return -1; +} + + +PyObject * +PyContextVar_Set(PyObject *ovar, PyObject *val) +{ + ENSURE_ContextVar(ovar, NULL) + PyContextVar *var = (PyContextVar *)ovar; + + if (!PyContextVar_CheckExact(var)) { + PyErr_SetString( + PyExc_TypeError, "an instance of ContextVar was expected"); + return NULL; + } + + PyContext *ctx = context_get(); + if (ctx == NULL) { + return NULL; + } + + PyObject *old_val = NULL; + int found = _PyHamt_Find(ctx->ctx_vars, (PyObject *)var, &old_val); + if (found < 0) { + return NULL; + } + + Py_XINCREF(old_val); + PyContextToken *tok = token_new(ctx, var, old_val); + Py_XDECREF(old_val); + + if (contextvar_set(var, val)) { + Py_DECREF(tok); + return NULL; + } + + return (PyObject *)tok; +} + + +int +PyContextVar_Reset(PyObject *ovar, PyObject *otok) +{ + ENSURE_ContextVar(ovar, -1) + ENSURE_ContextToken(otok, -1) + PyContextVar *var = (PyContextVar *)ovar; + PyContextToken *tok = (PyContextToken *)otok; + + if (tok->tok_used) { + PyErr_Format(PyExc_RuntimeError, + "%R has already been used once", tok); + return -1; + } + + if (var != tok->tok_var) { + PyErr_Format(PyExc_ValueError, + "%R was created by a different ContextVar", tok); + return -1; + } + + PyContext *ctx = context_get(); + if (ctx != tok->tok_ctx) { + PyErr_Format(PyExc_ValueError, + "%R was created in a different Context", tok); + return -1; + } + + tok->tok_used = 1; + + if (tok->tok_oldval == NULL) { + return contextvar_del(var); + } + else { + return contextvar_set(var, tok->tok_oldval); + } +} + + +/////////////////////////// PyContext + +/*[clinic input] +class _contextvars.Context "PyContext *" "&PyContext_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bdf87f8e0cb580e8]*/ + + +static inline PyContext * +_context_alloc(void) +{ + PyContext *ctx; + if (ctx_freelist_len) { + ctx_freelist_len--; + ctx = ctx_freelist; + ctx_freelist = (PyContext *)ctx->ctx_weakreflist; + ctx->ctx_weakreflist = NULL; + _Py_NewReference((PyObject *)ctx); + } + else { + ctx = PyObject_GC_New(PyContext, &PyContext_Type); + if (ctx == NULL) { + return NULL; + } + } + + ctx->ctx_vars = NULL; + ctx->ctx_prev = NULL; + ctx->ctx_entered = 0; + ctx->ctx_weakreflist = NULL; + + return ctx; +} + + +static PyContext * +context_new_empty(void) +{ + PyContext *ctx = _context_alloc(); + if (ctx == NULL) { + return NULL; + } + + ctx->ctx_vars = _PyHamt_New(); + if (ctx->ctx_vars == NULL) { + Py_DECREF(ctx); + return NULL; + } + + _PyObject_GC_TRACK(ctx); + return ctx; +} + + +static PyContext * +context_new_from_vars(PyHamtObject *vars) +{ + PyContext *ctx = _context_alloc(); + if (ctx == NULL) { + return NULL; + } + + Py_INCREF(vars); + ctx->ctx_vars = vars; + + _PyObject_GC_TRACK(ctx); + return ctx; +} + + +static inline PyContext * +context_get(void) +{ + PyThreadState *ts = _PyThreadState_GET(); + assert(ts != NULL); + PyContext *current_ctx = (PyContext *)ts->context; + if (current_ctx == NULL) { + current_ctx = context_new_empty(); + if (current_ctx == NULL) { + return NULL; + } + ts->context = (PyObject *)current_ctx; + } + return current_ctx; +} + +static int +context_check_key_type(PyObject *key) +{ + if (!PyContextVar_CheckExact(key)) { + // abort(); + PyErr_Format(PyExc_TypeError, + "a ContextVar key was expected, got %R", key); + return -1; + } + return 0; +} + +static PyObject * +context_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + if (PyTuple_Size(args) || (kwds != NULL && PyDict_Size(kwds))) { + PyErr_SetString( + PyExc_TypeError, "Context() does not accept any arguments"); + return NULL; + } + return PyContext_New(); +} + +static int +context_tp_clear(PyContext *self) +{ + Py_CLEAR(self->ctx_prev); + Py_CLEAR(self->ctx_vars); + return 0; +} + +static int +context_tp_traverse(PyContext *self, visitproc visit, void *arg) +{ + Py_VISIT(self->ctx_prev); + Py_VISIT(self->ctx_vars); + return 0; +} + +static void +context_tp_dealloc(PyContext *self) +{ + _PyObject_GC_UNTRACK(self); + + if (self->ctx_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } + (void)context_tp_clear(self); + + if (ctx_freelist_len < CONTEXT_FREELIST_MAXLEN) { + ctx_freelist_len++; + self->ctx_weakreflist = (PyObject *)ctx_freelist; + ctx_freelist = self; + } + else { + Py_TYPE(self)->tp_free(self); + } +} + +static PyObject * +context_tp_iter(PyContext *self) +{ + return _PyHamt_NewIterKeys(self->ctx_vars); +} + +static PyObject * +context_tp_richcompare(PyObject *v, PyObject *w, int op) +{ + if (!PyContext_CheckExact(v) || !PyContext_CheckExact(w) || + (op != Py_EQ && op != Py_NE)) + { + Py_RETURN_NOTIMPLEMENTED; + } + + int res = _PyHamt_Eq( + ((PyContext *)v)->ctx_vars, ((PyContext *)w)->ctx_vars); + if (res < 0) { + return NULL; + } + + if (op == Py_NE) { + res = !res; + } + + if (res) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +static Py_ssize_t +context_tp_len(PyContext *self) +{ + return _PyHamt_Len(self->ctx_vars); +} + +static PyObject * +context_tp_subscript(PyContext *self, PyObject *key) +{ + if (context_check_key_type(key)) { + return NULL; + } + PyObject *val = NULL; + int found = _PyHamt_Find(self->ctx_vars, key, &val); + if (found < 0) { + return NULL; + } + if (found == 0) { + PyErr_SetObject(PyExc_KeyError, key); + return NULL; + } + Py_INCREF(val); + return val; +} + +static int +context_tp_contains(PyContext *self, PyObject *key) +{ + if (context_check_key_type(key)) { + return -1; + } + PyObject *val = NULL; + return _PyHamt_Find(self->ctx_vars, key, &val); +} + + +/*[clinic input] +_contextvars.Context.get + key: object + default: object = None + / + +Return the value for `key` if `key` has the value in the context object. + +If `key` does not exist, return `default`. If `default` is not given, +return None. +[clinic start generated code]*/ + +static PyObject * +_contextvars_Context_get_impl(PyContext *self, PyObject *key, + PyObject *default_value) +/*[clinic end generated code: output=0c54aa7664268189 input=c8eeb81505023995]*/ +{ + if (context_check_key_type(key)) { + return NULL; + } + + PyObject *val = NULL; + int found = _PyHamt_Find(self->ctx_vars, key, &val); + if (found < 0) { + return NULL; + } + if (found == 0) { + Py_INCREF(default_value); + return default_value; + } + Py_INCREF(val); + return val; +} + + +/*[clinic input] +_contextvars.Context.items + +Return all variables and their values in the context object. + +The result is returned as a list of 2-tuples (variable, value). +[clinic start generated code]*/ + +static PyObject * +_contextvars_Context_items_impl(PyContext *self) +/*[clinic end generated code: output=fa1655c8a08502af input=00db64ae379f9f42]*/ +{ + return _PyHamt_NewIterItems(self->ctx_vars); +} + + +/*[clinic input] +_contextvars.Context.keys + +Return a list of all variables in the context object. +[clinic start generated code]*/ + +static PyObject * +_contextvars_Context_keys_impl(PyContext *self) +/*[clinic end generated code: output=177227c6b63ec0e2 input=114b53aebca3449c]*/ +{ + return _PyHamt_NewIterKeys(self->ctx_vars); +} + + +/*[clinic input] +_contextvars.Context.values + +Return a list of all variables' values in the context object. +[clinic start generated code]*/ + +static PyObject * +_contextvars_Context_values_impl(PyContext *self) +/*[clinic end generated code: output=d286dabfc8db6dde input=ce8075d04a6ea526]*/ +{ + return _PyHamt_NewIterValues(self->ctx_vars); +} + + +/*[clinic input] +_contextvars.Context.copy + +Return a shallow copy of the context object. +[clinic start generated code]*/ + +static PyObject * +_contextvars_Context_copy_impl(PyContext *self) +/*[clinic end generated code: output=30ba8896c4707a15 input=ebafdbdd9c72d592]*/ +{ + return (PyObject *)context_new_from_vars(self->ctx_vars); +} + + +static PyObject * +context_run(PyContext *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs < 1) { + PyErr_SetString(PyExc_TypeError, + "run() missing 1 required positional argument"); + return NULL; + } + + if (PyContext_Enter((PyObject *)self)) { + return NULL; + } + + PyObject *call_result = _PyObject_Vectorcall( + args[0], args + 1, nargs - 1, kwnames); + + if (PyContext_Exit((PyObject *)self)) { + return NULL; + } + + return call_result; +} + + +static PyMethodDef PyContext_methods[] = { + _CONTEXTVARS_CONTEXT_GET_METHODDEF + _CONTEXTVARS_CONTEXT_ITEMS_METHODDEF + _CONTEXTVARS_CONTEXT_KEYS_METHODDEF + _CONTEXTVARS_CONTEXT_VALUES_METHODDEF + _CONTEXTVARS_CONTEXT_COPY_METHODDEF + {"run", (PyCFunction)(void(*)(void))context_run, METH_FASTCALL | METH_KEYWORDS, NULL}, + {NULL, NULL} +}; + +static PySequenceMethods PyContext_as_sequence = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)context_tp_contains, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + +static PyMappingMethods PyContext_as_mapping = { + (lenfunc)context_tp_len, /* mp_length */ + (binaryfunc)context_tp_subscript, /* mp_subscript */ +}; + +PyTypeObject PyContext_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "Context", + sizeof(PyContext), + .tp_methods = PyContext_methods, + .tp_as_mapping = &PyContext_as_mapping, + .tp_as_sequence = &PyContext_as_sequence, + .tp_iter = (getiterfunc)context_tp_iter, + .tp_dealloc = (destructor)context_tp_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_richcompare = context_tp_richcompare, + .tp_traverse = (traverseproc)context_tp_traverse, + .tp_clear = (inquiry)context_tp_clear, + .tp_new = context_tp_new, + .tp_weaklistoffset = offsetof(PyContext, ctx_weakreflist), + .tp_hash = PyObject_HashNotImplemented, +}; + + +/////////////////////////// ContextVar + + +static int +contextvar_set(PyContextVar *var, PyObject *val) +{ + var->var_cached = NULL; + PyThreadState *ts = PyThreadState_Get(); + + PyContext *ctx = context_get(); + if (ctx == NULL) { + return -1; + } + + PyHamtObject *new_vars = _PyHamt_Assoc( + ctx->ctx_vars, (PyObject *)var, val); + if (new_vars == NULL) { + return -1; + } + + Py_SETREF(ctx->ctx_vars, new_vars); + + var->var_cached = val; /* borrow */ + var->var_cached_tsid = ts->id; + var->var_cached_tsver = ts->context_ver; + return 0; +} + +static int +contextvar_del(PyContextVar *var) +{ + var->var_cached = NULL; + + PyContext *ctx = context_get(); + if (ctx == NULL) { + return -1; + } + + PyHamtObject *vars = ctx->ctx_vars; + PyHamtObject *new_vars = _PyHamt_Without(vars, (PyObject *)var); + if (new_vars == NULL) { + return -1; + } + + if (vars == new_vars) { + Py_DECREF(new_vars); + PyErr_SetObject(PyExc_LookupError, (PyObject *)var); + return -1; + } + + Py_SETREF(ctx->ctx_vars, new_vars); + return 0; +} + +static Py_hash_t +contextvar_generate_hash(void *addr, PyObject *name) +{ + /* Take hash of `name` and XOR it with the object's addr. + + The structure of the tree is encoded in objects' hashes, which + means that sufficiently similar hashes would result in tall trees + with many Collision nodes. Which would, in turn, result in slower + get and set operations. + + The XORing helps to ensure that: + + (1) sequentially allocated ContextVar objects have + different hashes; + + (2) context variables with equal names have + different hashes. + */ + + Py_hash_t name_hash = PyObject_Hash(name); + if (name_hash == -1) { + return -1; + } + + Py_hash_t res = _Py_HashPointer(addr) ^ name_hash; + return res == -1 ? -2 : res; +} + +static PyContextVar * +contextvar_new(PyObject *name, PyObject *def) +{ + if (!PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, + "context variable name must be a str"); + return NULL; + } + + PyContextVar *var = PyObject_GC_New(PyContextVar, &PyContextVar_Type); + if (var == NULL) { + return NULL; + } + + var->var_hash = contextvar_generate_hash(var, name); + if (var->var_hash == -1) { + Py_DECREF(var); + return NULL; + } + + Py_INCREF(name); + var->var_name = name; + + Py_XINCREF(def); + var->var_default = def; + + var->var_cached = NULL; + var->var_cached_tsid = 0; + var->var_cached_tsver = 0; + + if (_PyObject_GC_MAY_BE_TRACKED(name) || + (def != NULL && _PyObject_GC_MAY_BE_TRACKED(def))) + { + PyObject_GC_Track(var); + } + return var; +} + + +/*[clinic input] +class _contextvars.ContextVar "PyContextVar *" "&PyContextVar_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=445da935fa8883c3]*/ + + +static PyObject * +contextvar_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"", "default", NULL}; + PyObject *name; + PyObject *def = NULL; + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, "O|$O:ContextVar", kwlist, &name, &def)) + { + return NULL; + } + + return (PyObject *)contextvar_new(name, def); +} + +static int +contextvar_tp_clear(PyContextVar *self) +{ + Py_CLEAR(self->var_name); + Py_CLEAR(self->var_default); + self->var_cached = NULL; + self->var_cached_tsid = 0; + self->var_cached_tsver = 0; + return 0; +} + +static int +contextvar_tp_traverse(PyContextVar *self, visitproc visit, void *arg) +{ + Py_VISIT(self->var_name); + Py_VISIT(self->var_default); + return 0; +} + +static void +contextvar_tp_dealloc(PyContextVar *self) +{ + PyObject_GC_UnTrack(self); + (void)contextvar_tp_clear(self); + Py_TYPE(self)->tp_free(self); +} + +static Py_hash_t +contextvar_tp_hash(PyContextVar *self) +{ + return self->var_hash; +} + +static PyObject * +contextvar_tp_repr(PyContextVar *self) +{ + _PyUnicodeWriter writer; + + _PyUnicodeWriter_Init(&writer); + + if (_PyUnicodeWriter_WriteASCIIString( + &writer, "", self); + if (addr == NULL) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(&writer, addr) < 0) { + Py_DECREF(addr); + goto error; + } + Py_DECREF(addr); + + return _PyUnicodeWriter_Finish(&writer); + +error: + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + + +/*[clinic input] +_contextvars.ContextVar.get + default: object = NULL + / + +Return a value for the context variable for the current context. + +If there is no value for the variable in the current context, the method will: + * return the value of the default argument of the method, if provided; or + * return the default value for the context variable, if it was created + with one; or + * raise a LookupError. +[clinic start generated code]*/ + +static PyObject * +_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value) +/*[clinic end generated code: output=0746bd0aa2ced7bf input=30aa2ab9e433e401]*/ +{ + if (!PyContextVar_CheckExact(self)) { + PyErr_SetString( + PyExc_TypeError, "an instance of ContextVar was expected"); + return NULL; + } + + PyObject *val; + if (PyContextVar_Get((PyObject *)self, default_value, &val) < 0) { + return NULL; + } + + if (val == NULL) { + PyErr_SetObject(PyExc_LookupError, (PyObject *)self); + return NULL; + } + + return val; +} + +/*[clinic input] +_contextvars.ContextVar.set + value: object + / + +Call to set a new value for the context variable in the current context. + +The required value argument is the new value for the context variable. + +Returns a Token object that can be used to restore the variable to its previous +value via the `ContextVar.reset()` method. +[clinic start generated code]*/ + +static PyObject * +_contextvars_ContextVar_set(PyContextVar *self, PyObject *value) +/*[clinic end generated code: output=446ed5e820d6d60b input=c0a6887154227453]*/ +{ + return PyContextVar_Set((PyObject *)self, value); +} + +/*[clinic input] +_contextvars.ContextVar.reset + token: object + / + +Reset the context variable. + +The variable is reset to the value it had before the `ContextVar.set()` that +created the token was used. +[clinic start generated code]*/ + +static PyObject * +_contextvars_ContextVar_reset(PyContextVar *self, PyObject *token) +/*[clinic end generated code: output=d4ee34d0742d62ee input=ebe2881e5af4ffda]*/ +{ + if (!PyContextToken_CheckExact(token)) { + PyErr_Format(PyExc_TypeError, + "expected an instance of Token, got %R", token); + return NULL; + } + + if (PyContextVar_Reset((PyObject *)self, token)) { + return NULL; + } + + Py_RETURN_NONE; +} + + +static PyObject * +contextvar_cls_getitem(PyObject *self, PyObject *arg) +{ + Py_INCREF(self); + return self; +} + +static PyMemberDef PyContextVar_members[] = { + {"name", T_OBJECT, offsetof(PyContextVar, var_name), READONLY}, + {NULL} +}; + +static PyMethodDef PyContextVar_methods[] = { + _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF + _CONTEXTVARS_CONTEXTVAR_SET_METHODDEF + _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF + {"__class_getitem__", contextvar_cls_getitem, + METH_O | METH_CLASS, NULL}, + {NULL, NULL} +}; + +PyTypeObject PyContextVar_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "ContextVar", + sizeof(PyContextVar), + .tp_methods = PyContextVar_methods, + .tp_members = PyContextVar_members, + .tp_dealloc = (destructor)contextvar_tp_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)contextvar_tp_traverse, + .tp_clear = (inquiry)contextvar_tp_clear, + .tp_new = contextvar_tp_new, + .tp_free = PyObject_GC_Del, + .tp_hash = (hashfunc)contextvar_tp_hash, + .tp_repr = (reprfunc)contextvar_tp_repr, +}; + + +/////////////////////////// Token + +static PyObject * get_token_missing(void); + + +/*[clinic input] +class _contextvars.Token "PyContextToken *" "&PyContextToken_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=338a5e2db13d3f5b]*/ + + +static PyObject * +token_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyErr_SetString(PyExc_RuntimeError, + "Tokens can only be created by ContextVars"); + return NULL; +} + +static int +token_tp_clear(PyContextToken *self) +{ + Py_CLEAR(self->tok_ctx); + Py_CLEAR(self->tok_var); + Py_CLEAR(self->tok_oldval); + return 0; +} + +static int +token_tp_traverse(PyContextToken *self, visitproc visit, void *arg) +{ + Py_VISIT(self->tok_ctx); + Py_VISIT(self->tok_var); + Py_VISIT(self->tok_oldval); + return 0; +} + +static void +token_tp_dealloc(PyContextToken *self) +{ + PyObject_GC_UnTrack(self); + (void)token_tp_clear(self); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +token_tp_repr(PyContextToken *self) +{ + _PyUnicodeWriter writer; + + _PyUnicodeWriter_Init(&writer); + + if (_PyUnicodeWriter_WriteASCIIString(&writer, "tok_used) { + if (_PyUnicodeWriter_WriteASCIIString(&writer, " used", 5) < 0) { + goto error; + } + } + + if (_PyUnicodeWriter_WriteASCIIString(&writer, " var=", 5) < 0) { + goto error; + } + + PyObject *var = PyObject_Repr((PyObject *)self->tok_var); + if (var == NULL) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(&writer, var) < 0) { + Py_DECREF(var); + goto error; + } + Py_DECREF(var); + + PyObject *addr = PyUnicode_FromFormat(" at %p>", self); + if (addr == NULL) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(&writer, addr) < 0) { + Py_DECREF(addr); + goto error; + } + Py_DECREF(addr); + + return _PyUnicodeWriter_Finish(&writer); + +error: + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} + +static PyObject * +token_get_var(PyContextToken *self, void *Py_UNUSED(ignored)) +{ + Py_INCREF(self->tok_var); + return (PyObject *)self->tok_var; +} + +static PyObject * +token_get_old_value(PyContextToken *self, void *Py_UNUSED(ignored)) +{ + if (self->tok_oldval == NULL) { + return get_token_missing(); + } + + Py_INCREF(self->tok_oldval); + return self->tok_oldval; +} + +static PyGetSetDef PyContextTokenType_getsetlist[] = { + {"var", (getter)token_get_var, NULL, NULL}, + {"old_value", (getter)token_get_old_value, NULL, NULL}, + {NULL} +}; + +PyTypeObject PyContextToken_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "Token", + sizeof(PyContextToken), + .tp_getset = PyContextTokenType_getsetlist, + .tp_dealloc = (destructor)token_tp_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)token_tp_traverse, + .tp_clear = (inquiry)token_tp_clear, + .tp_new = token_tp_new, + .tp_free = PyObject_GC_Del, + .tp_hash = PyObject_HashNotImplemented, + .tp_repr = (reprfunc)token_tp_repr, +}; + +static PyContextToken * +token_new(PyContext *ctx, PyContextVar *var, PyObject *val) +{ + PyContextToken *tok = PyObject_GC_New(PyContextToken, &PyContextToken_Type); + if (tok == NULL) { + return NULL; + } + + Py_INCREF(ctx); + tok->tok_ctx = ctx; + + Py_INCREF(var); + tok->tok_var = var; + + Py_XINCREF(val); + tok->tok_oldval = val; + + tok->tok_used = 0; + + PyObject_GC_Track(tok); + return tok; +} + + +/////////////////////////// Token.MISSING + + +static PyObject *_token_missing; + + +typedef struct { + PyObject_HEAD +} PyContextTokenMissing; + + +static PyObject * +context_token_missing_tp_repr(PyObject *self) +{ + return PyUnicode_FromString(""); +} + + +PyTypeObject PyContextTokenMissing_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "Token.MISSING", + sizeof(PyContextTokenMissing), + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_repr = context_token_missing_tp_repr, +}; + + +static PyObject * +get_token_missing(void) +{ + if (_token_missing != NULL) { + Py_INCREF(_token_missing); + return _token_missing; + } + + _token_missing = (PyObject *)PyObject_New( + PyContextTokenMissing, &PyContextTokenMissing_Type); + if (_token_missing == NULL) { + return NULL; + } + + Py_INCREF(_token_missing); + return _token_missing; +} + + +/////////////////////////// + + +int +PyContext_ClearFreeList(void) +{ + int size = ctx_freelist_len; + while (ctx_freelist_len) { + PyContext *ctx = ctx_freelist; + ctx_freelist = (PyContext *)ctx->ctx_weakreflist; + ctx->ctx_weakreflist = NULL; + PyObject_GC_Del(ctx); + ctx_freelist_len--; + } + return size; +} + + +void +_PyContext_Fini(void) +{ + Py_CLEAR(_token_missing); + (void)PyContext_ClearFreeList(); + (void)_PyHamt_Fini(); +} + + +int +_PyContext_Init(void) +{ + if (!_PyHamt_Init()) { + return 0; + } + + if ((PyType_Ready(&PyContext_Type) < 0) || + (PyType_Ready(&PyContextVar_Type) < 0) || + (PyType_Ready(&PyContextToken_Type) < 0) || + (PyType_Ready(&PyContextTokenMissing_Type) < 0)) + { + return 0; + } + + PyObject *missing = get_token_missing(); + if (PyDict_SetItemString( + PyContextToken_Type.tp_dict, "MISSING", missing)) + { + Py_DECREF(missing); + return 0; + } + Py_DECREF(missing); + + return 1; +} diff --git a/python/Python/dtoa.c b/python/Python/dtoa.c new file mode 100755 index 0000000..b7bb7ac --- /dev/null +++ b/python/Python/dtoa.c @@ -0,0 +1,2847 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/**************************************************************** + * This is dtoa.c by David M. Gay, downloaded from + * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for + * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. + * + * Please remember to check http://www.netlib.org/fp regularly (and especially + * before any Python release) for bugfixes and updates. + * + * The major modifications from Gay's original code are as follows: + * + * 0. The original code has been specialized to Python's needs by removing + * many of the #ifdef'd sections. In particular, code to support VAX and + * IBM floating-point formats, hex NaNs, hex floats, locale-aware + * treatment of the decimal point, and setting of the inexact flag have + * been removed. + * + * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free. + * + * 2. The public functions strtod, dtoa and freedtoa all now have + * a _Py_dg_ prefix. + * + * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread + * PyMem_Malloc failures through the code. The functions + * + * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b + * + * of return type *Bigint all return NULL to indicate a malloc failure. + * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on + * failure. bigcomp now has return type int (it used to be void) and + * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL + * on failure. _Py_dg_strtod indicates failure due to malloc failure + * by returning -1.0, setting errno=ENOMEM and *se to s00. + * + * 4. The static variable dtoa_result has been removed. Callers of + * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free + * the memory allocated by _Py_dg_dtoa. + * + * 5. The code has been reformatted to better fit with Python's + * C style guide (PEP 7). + * + * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory + * that hasn't been MALLOC'ed, private_mem should only be used when k <= + * Kmax. + * + * 7. _Py_dg_strtod has been modified so that it doesn't accept strings with + * leading whitespace. + * + ***************************************************************/ + +/* Please send bug reports for the original dtoa.c code to David M. Gay (dmg + * at acm dot org, with " at " changed at "@" and " dot " changed to "."). + * Please report bugs for this modified version using the Python issue tracker + * (http://bugs.python.org). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* Linking of Python's #defines to Gay's #defines starts here. */ + +#include "Python.h" + +/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile + the following code */ +#ifndef PY_NO_SHORT_FLOAT_REPR + +#include "float.h" + +#define MALLOC PyMem_Malloc +#define FREE PyMem_Free + +/* This code should also work for ARM mixed-endian format on little-endian + machines, where doubles have byte order 45670123 (in increasing address + order, 0 being the least significant byte). */ +#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# define IEEE_8087 +#endif +#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \ + defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +# define IEEE_MC68k +#endif +#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 +#error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." +#endif + +/* The code below assumes that the endianness of integers matches the + endianness of the two 32-bit words of a double. Check this. */ +#if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \ + defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)) +#error "doubles and ints have incompatible endianness" +#endif + +#if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) +#error "doubles and ints have incompatible endianness" +#endif + + +typedef uint32_t ULong; +typedef int32_t Long; +typedef uint64_t ULLong; + +#undef DEBUG +#ifdef Py_DEBUG +#define DEBUG +#endif + +/* End Python #define linking */ + +#ifdef DEBUG +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef IEEE_8087 +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] +#else +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] +#endif +#define dval(x) (x)->d + +#ifndef STRTOD_DIGLIM +#define STRTOD_DIGLIM 40 +#endif + +/* maximum permitted exponent value for strtod; exponents larger than + MAX_ABS_EXP in absolute value get truncated to +-MAX_ABS_EXP. MAX_ABS_EXP + should fit into an int. */ +#ifndef MAX_ABS_EXP +#define MAX_ABS_EXP 1100000000U +#endif +/* Bound on length of pieces of input strings in _Py_dg_strtod; specifically, + this is used to bound the total number of digits ignoring leading zeros and + the number of digits that follow the decimal point. Ideally, MAX_DIGITS + should satisfy MAX_DIGITS + 400 < MAX_ABS_EXP; that ensures that the + exponent clipping in _Py_dg_strtod can't affect the value of the output. */ +#ifndef MAX_DIGITS +#define MAX_DIGITS 1000000000U +#endif + +/* Guard against trying to use the above values on unusual platforms with ints + * of width less than 32 bits. */ +#if MAX_ABS_EXP > INT_MAX +#error "MAX_ABS_EXP should fit in an int" +#endif +#if MAX_DIGITS > INT_MAX +#error "MAX_DIGITS should fit in an int" +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ + ((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ + ((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Nbits 53 +#define Bias 1023 +#define Emax 1023 +#define Emin (-1022) +#define Etiny (-1074) /* smallest denormal is 2**Etiny */ +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#define Rounding Flt_Rounds + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +/* Standard NaN used by _Py_dg_stdnan. */ + +#define NAN_WORD0 0x7ff80000 +#define NAN_WORD1 0 + +/* Bits of the representation of positive infinity. */ + +#define POSINF_WORD0 0x7ff00000 +#define POSINF_WORD1 0 + +/* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */ + +typedef struct BCinfo BCinfo; +struct +BCinfo { + int e0, nd, nd0, scale; +}; + +#define FFFFFFFF 0xffffffffUL + +#define Kmax 7 + +/* struct Bigint is used to represent arbitrary-precision integers. These + integers are stored in sign-magnitude format, with the magnitude stored as + an array of base 2**32 digits. Bigints are always normalized: if x is a + Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero. + + The Bigint fields are as follows: + + - next is a header used by Balloc and Bfree to keep track of lists + of freed Bigints; it's also used for the linked list of + powers of 5 of the form 5**2**i used by pow5mult. + - k indicates which pool this Bigint was allocated from + - maxwds is the maximum number of words space was allocated for + (usually maxwds == 2**k) + - sign is 1 for negative Bigints, 0 for positive. The sign is unused + (ignored on inputs, set to 0 on outputs) in almost all operations + involving Bigints: a notable exception is the diff function, which + ignores signs on inputs but sets the sign of the output correctly. + - wds is the actual number of significant words + - x contains the vector of words (digits) for this Bigint, from least + significant (x[0]) to most significant (x[wds-1]). +*/ + +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +typedef struct Bigint Bigint; + +#ifndef Py_USING_MEMORY_DEBUGGER + +/* Memory management: memory is allocated from, and returned to, Kmax+1 pools + of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds == + 1 << k. These pools are maintained as linked lists, with freelist[k] + pointing to the head of the list for pool k. + + On allocation, if there's no free slot in the appropriate pool, MALLOC is + called to get more memory. This memory is not returned to the system until + Python quits. There's also a private memory pool that's allocated from + in preference to using MALLOC. + + For Bigints with more than (1 << Kmax) digits (which implies at least 1233 + decimal digits), memory is directly allocated using MALLOC, and freed using + FREE. + + XXX: it would be easy to bypass this memory-management system and + translate each call to Balloc into a call to PyMem_Malloc, and each + Bfree to PyMem_Free. Investigate whether this has any significant + performance on impact. */ + +static Bigint *freelist[Kmax+1]; + +/* Allocate space for a Bigint with up to 1<next; + else { + x = 1 << k; + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else { + rv = (Bigint*)MALLOC(len*sizeof(double)); + if (rv == NULL) + return NULL; + } + rv->k = k; + rv->maxwds = x; + } + rv->sign = rv->wds = 0; + return rv; +} + +/* Free a Bigint allocated with Balloc */ + +static void +Bfree(Bigint *v) +{ + if (v) { + if (v->k > Kmax) + FREE((void*)v); + else { + v->next = freelist[v->k]; + freelist[v->k] = v; + } + } +} + +#else + +/* Alternative versions of Balloc and Bfree that use PyMem_Malloc and + PyMem_Free directly in place of the custom memory allocation scheme above. + These are provided for the benefit of memory debugging tools like + Valgrind. */ + +/* Allocate space for a Bigint with up to 1<k = k; + rv->maxwds = x; + rv->sign = rv->wds = 0; + return rv; +} + +/* Free a Bigint allocated with Balloc */ + +static void +Bfree(Bigint *v) +{ + if (v) { + FREE((void*)v); + } +} + +#endif /* Py_USING_MEMORY_DEBUGGER */ + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ + y->wds*sizeof(Long) + 2*sizeof(int)) + +/* Multiply a Bigint b by m and add a. Either modifies b in place and returns + a pointer to the modified b, or Bfrees b and returns a pointer to a copy. + On failure, return NULL. In this case, b will have been already freed. */ + +static Bigint * +multadd(Bigint *b, int m, int a) /* multiply by m and add a */ +{ + int i, wds; + ULong *x; + ULLong carry, y; + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = (ULong)(y & FFFFFFFF); + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + if (b1 == NULL){ + Bfree(b); + return NULL; + } + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = (ULong)carry; + b->wds = wds; + } + return b; +} + +/* convert a string s containing nd decimal digits (possibly containing a + decimal separator at position nd0, which is ignored) to a Bigint. This + function carries on where the parsing code in _Py_dg_strtod leaves off: on + entry, y9 contains the result of converting the first 9 digits. Returns + NULL on failure. */ + +static Bigint * +s2b(const char *s, int nd0, int nd, ULong y9) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; + b = Balloc(k); + if (b == NULL) + return NULL; + b->x[0] = y9; + b->wds = 1; + + if (nd <= 9) + return b; + + s += 9; + for (i = 9; i < nd0; i++) { + b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } + s++; + for(; i < nd; i++) { + b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } + return b; +} + +/* count leading 0 bits in the 32-bit integer x. */ + +static int +hi0bits(ULong x) +{ + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +/* count trailing 0 bits in the 32-bit integer y, and shift y right by that + number of bits. */ + +static int +lo0bits(ULong *y) +{ + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; +} + +/* convert a small nonnegative integer to a Bigint */ + +static Bigint * +i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + if (b == NULL) + return NULL; + b->x[0] = i; + b->wds = 1; + return b; +} + +/* multiply two Bigints. Returns a new Bigint, or NULL on failure. Ignores + the signs of a and b. */ + +static Bigint * +mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; + ULLong carry, z; + + if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) { + c = Balloc(0); + if (c == NULL) + return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + if (c == NULL) + return NULL; + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; + for(; xb < xbe; xc0++) { + if ((y = *xb++)) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = (ULong)(z & FFFFFFFF); + } + while(x < xae); + *xc = (ULong)carry; + } + } + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +#ifndef Py_USING_MEMORY_DEBUGGER + +/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ + +static Bigint *p5s; + +/* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on + failure; if the returned pointer is distinct from b then the original + Bigint b will have been Bfree'd. Ignores the sign of b. */ + +static Bigint * +pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) { + b = multadd(b, p05[i-1], 0); + if (b == NULL) + return NULL; + } + + if (!(k >>= 2)) + return b; + p5 = p5s; + if (!p5) { + /* first time */ + p5 = i2b(625); + if (p5 == NULL) { + Bfree(b); + return NULL; + } + p5s = p5; + p5->next = 0; + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + if (b == NULL) + return NULL; + } + if (!(k >>= 1)) + break; + p51 = p5->next; + if (!p51) { + p51 = mult(p5,p5); + if (p51 == NULL) { + Bfree(b); + return NULL; + } + p51->next = 0; + p5->next = p51; + } + p5 = p51; + } + return b; +} + +#else + +/* Version of pow5mult that doesn't cache powers of 5. Provided for + the benefit of memory debugging tools like Valgrind. */ + +static Bigint * +pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) { + b = multadd(b, p05[i-1], 0); + if (b == NULL) + return NULL; + } + + if (!(k >>= 2)) + return b; + p5 = i2b(625); + if (p5 == NULL) { + Bfree(b); + return NULL; + } + + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + if (b == NULL) { + Bfree(p5); + return NULL; + } + } + if (!(k >>= 1)) + break; + p51 = mult(p5, p5); + Bfree(p5); + p5 = p51; + if (p5 == NULL) { + Bfree(b); + return NULL; + } + } + Bfree(p5); + return b; +} + +#endif /* Py_USING_MEMORY_DEBUGGER */ + +/* shift a Bigint b left by k bits. Return a pointer to the shifted result, + or NULL on failure. If the returned pointer is distinct from b then the + original b will have been Bfree'd. Ignores the sign of b. */ + +static Bigint * +lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + if (!k || (!b->x[0] && b->wds == 1)) + return b; + + n = k >> 5; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + if (b1 == NULL) { + Bfree(b); + return NULL; + } + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z)) + ++n1; + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +/* Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and + 1 if a > b. Ignores signs of a and b. */ + +static int +cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +/* Take the difference of Bigints a and b, returning a new Bigint. Returns + NULL on failure. The signs of a and b are ignored, but the sign of the + result is set appropriately. */ + +static Bigint * +diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; + ULLong borrow, y; + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + if (c == NULL) + return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + if (c == NULL) + return NULL; + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } + while(!*--xc) + wa--; + c->wds = wa; + return c; +} + +/* Given a positive normal double x, return the difference between x and the + next double up. Doesn't give correct results for subnormals. */ + +static double +ulp(U *x) +{ + Long L; + U u; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; + word0(&u) = L; + word1(&u) = 0; + return dval(&u); +} + +/* Convert a Bigint to a double plus an exponent */ + +static double +b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + U d; + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; + if (k < Ebits) { + word0(&d) = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + word0(&d) = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + word1(&d) = z << k | y >> (32 - k); + } + else { + word0(&d) = Exp_1 | y; + word1(&d) = z; + } + ret_d: + return dval(&d); +} + +/* Convert a scaled double to a Bigint plus an exponent. Similar to d2b, + except that it accepts the scale parameter used in _Py_dg_strtod (which + should be either 0 or 2*P), and the normalization for the return value is + different (see below). On input, d should be finite and nonnegative, and d + / 2**scale should be exactly representable as an IEEE 754 double. + + Returns a Bigint b and an integer e such that + + dval(d) / 2**scale = b * 2**e. + + Unlike d2b, b is not necessarily odd: b and e are normalized so + that either 2**(P-1) <= b < 2**P and e >= Etiny, or b < 2**P + and e == Etiny. This applies equally to an input of 0.0: in that + case the return values are b = 0 and e = Etiny. + + The above normalization ensures that for all possible inputs d, + 2**e gives ulp(d/2**scale). + + Returns NULL on failure. +*/ + +static Bigint * +sd2b(U *d, int scale, int *e) +{ + Bigint *b; + + b = Balloc(1); + if (b == NULL) + return NULL; + + /* First construct b and e assuming that scale == 0. */ + b->wds = 2; + b->x[0] = word1(d); + b->x[1] = word0(d) & Frac_mask; + *e = Etiny - 1 + (int)((word0(d) & Exp_mask) >> Exp_shift); + if (*e < Etiny) + *e = Etiny; + else + b->x[1] |= Exp_msk1; + + /* Now adjust for scale, provided that b != 0. */ + if (scale && (b->x[0] || b->x[1])) { + *e -= scale; + if (*e < Etiny) { + scale = Etiny - *e; + *e = Etiny; + /* We can't shift more than P-1 bits without shifting out a 1. */ + assert(0 < scale && scale <= P - 1); + if (scale >= 32) { + /* The bits shifted out should all be zero. */ + assert(b->x[0] == 0); + b->x[0] = b->x[1]; + b->x[1] = 0; + scale -= 32; + } + if (scale) { + /* The bits shifted out should all be zero. */ + assert(b->x[0] << (32 - scale) == 0); + b->x[0] = (b->x[0] >> scale) | (b->x[1] << (32 - scale)); + b->x[1] >>= scale; + } + } + } + /* Ensure b is normalized. */ + if (!b->x[1]) + b->wds = 1; + + return b; +} + +/* Convert a double to a Bigint plus an exponent. Return NULL on failure. + + Given a finite nonzero double d, return an odd Bigint b and exponent *e + such that fabs(d) = b * 2**e. On return, *bbits gives the number of + significant bits of b; that is, 2**(*bbits-1) <= b < 2**(*bbits). + + If d is zero, then b == 0, *e == -1010, *bbits = 0. + */ + +static Bigint * +d2b(U *d, int *e, int *bits) +{ + Bigint *b; + int de, k; + ULong *x, y, z; + int i; + + b = Balloc(1); + if (b == NULL) + return NULL; + x = b->x; + + z = word0(d) & Frac_mask; + word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */ + if ((de = (int)(word0(d) >> Exp_shift))) + z |= Exp_msk1; + if ((y = word1(d))) { + if ((k = lo0bits(&y))) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; + i = + b->wds = 1; + k += 32; + } + if (de) { + *e = de - Bias - (P-1) + k; + *bits = P - k; + } + else { + *e = de - Bias - (P-1) + 1 + k; + *bits = 32*i - hi0bits(x[i-1]); + } + return b; +} + +/* Compute the ratio of two Bigints, as a double. The result may have an + error of up to 2.5 ulps. */ + +static double +ratio(Bigint *a, Bigint *b) +{ + U da, db; + int k, ka, kb; + + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); + k = ka - kb + 32*(a->wds - b->wds); + if (k > 0) + word0(&da) += k*Exp_msk1; + else { + k = -k; + word0(&db) += k*Exp_msk1; + } + return dval(&da) / dval(&db); +} + +static const double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +}; + +static const double +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-256 */ +}; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 + +#define ULbits 32 +#define kshift 5 +#define kmask 31 + + +static int +dshift(Bigint *b, int p2) +{ + int rv = hi0bits(b->x[b->wds-1]) - 4; + if (p2 > 0) + rv -= p2; + return rv & kmask; +} + +/* special case of Bigint division. The quotient is always in the range 0 <= + quotient < 10, and on entry the divisor S is normalized so that its top 4 + bits (28--31) are zero and bit 27 is set. */ + +static int +quorem(Bigint *b, Bigint *S) +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; + ULLong borrow, carry, y, ys; + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +/* sulp(x) is a version of ulp(x) that takes bc.scale into account. + + Assuming that x is finite and nonnegative (positive zero is fine + here) and x / 2^bc.scale is exactly representable as a double, + sulp(x) is equivalent to 2^bc.scale * ulp(x / 2^bc.scale). */ + +static double +sulp(U *x, BCinfo *bc) +{ + U u; + + if (bc->scale && 2*P + 1 > (int)((word0(x) & Exp_mask) >> Exp_shift)) { + /* rv/2^bc->scale is subnormal */ + word0(&u) = (P+2)*Exp_msk1; + word1(&u) = 0; + return u.d; + } + else { + assert(word0(x) || word1(x)); /* x != 0.0 */ + return ulp(x); + } +} + +/* The bigcomp function handles some hard cases for strtod, for inputs + with more than STRTOD_DIGLIM digits. It's called once an initial + estimate for the double corresponding to the input string has + already been obtained by the code in _Py_dg_strtod. + + The bigcomp function is only called after _Py_dg_strtod has found a + double value rv such that either rv or rv + 1ulp represents the + correctly rounded value corresponding to the original string. It + determines which of these two values is the correct one by + computing the decimal digits of rv + 0.5ulp and comparing them with + the corresponding digits of s0. + + In the following, write dv for the absolute value of the number represented + by the input string. + + Inputs: + + s0 points to the first significant digit of the input string. + + rv is a (possibly scaled) estimate for the closest double value to the + value represented by the original input to _Py_dg_strtod. If + bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to + the input value. + + bc is a struct containing information gathered during the parsing and + estimation steps of _Py_dg_strtod. Description of fields follows: + + bc->e0 gives the exponent of the input value, such that dv = (integer + given by the bd->nd digits of s0) * 10**e0 + + bc->nd gives the total number of significant digits of s0. It will + be at least 1. + + bc->nd0 gives the number of significant digits of s0 before the + decimal separator. If there's no decimal separator, bc->nd0 == + bc->nd. + + bc->scale is the value used to scale rv to avoid doing arithmetic with + subnormal values. It's either 0 or 2*P (=106). + + Outputs: + + On successful exit, rv/2^(bc->scale) is the closest double to dv. + + Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). */ + +static int +bigcomp(U *rv, const char *s0, BCinfo *bc) +{ + Bigint *b, *d; + int b2, d2, dd, i, nd, nd0, odd, p2, p5; + + nd = bc->nd; + nd0 = bc->nd0; + p5 = nd + bc->e0; + b = sd2b(rv, bc->scale, &p2); + if (b == NULL) + return -1; + + /* record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway + case, this is used for round to even. */ + odd = b->x[0] & 1; + + /* left shift b by 1 bit and or a 1 into the least significant bit; + this gives us b * 2**p2 = rv/2^(bc->scale) + 0.5 ulp. */ + b = lshift(b, 1); + if (b == NULL) + return -1; + b->x[0] |= 1; + p2--; + + p2 -= p5; + d = i2b(1); + if (d == NULL) { + Bfree(b); + return -1; + } + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + */ + if (p5 > 0) { + d = pow5mult(d, p5); + if (d == NULL) { + Bfree(b); + return -1; + } + } + else if (p5 < 0) { + b = pow5mult(b, -p5); + if (b == NULL) { + Bfree(d); + return -1; + } + } + if (p2 > 0) { + b2 = p2; + d2 = 0; + } + else { + b2 = 0; + d2 = -p2; + } + i = dshift(d, d2); + if ((b2 += i) > 0) { + b = lshift(b, b2); + if (b == NULL) { + Bfree(d); + return -1; + } + } + if ((d2 += i) > 0) { + d = lshift(d, d2); + if (d == NULL) { + Bfree(b); + return -1; + } + } + + /* Compare s0 with b/d: set dd to -1, 0, or 1 according as s0 < b/d, s0 == + * b/d, or s0 > b/d. Here the digits of s0 are thought of as representing + * a number in the range [0.1, 1). */ + if (cmp(b, d) >= 0) + /* b/d >= 1 */ + dd = -1; + else { + i = 0; + for(;;) { + b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; + } + dd = s0[i < nd0 ? i : i+1] - '0' - quorem(b, d); + i++; + + if (dd) + break; + if (!b->x[0] && b->wds == 1) { + /* b/d == 0 */ + dd = i < nd; + break; + } + if (!(i < nd)) { + /* b/d != 0, but digits of s0 exhausted */ + dd = -1; + break; + } + } + } + Bfree(b); + Bfree(d); + if (dd > 0 || (dd == 0 && odd)) + dval(rv) += sulp(rv, bc); + return 0; +} + +/* Return a 'standard' NaN value. + + There are exactly two quiet NaNs that don't arise by 'quieting' signaling + NaNs (see IEEE 754-2008, section 6.2.1). If sign == 0, return the one whose + sign bit is cleared. Otherwise, return the one whose sign bit is set. +*/ + +double +_Py_dg_stdnan(int sign) +{ + U rv; + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; + if (sign) + word0(&rv) |= Sign_bit; + return dval(&rv); +} + +/* Return positive or negative infinity, according to the given sign (0 for + * positive infinity, 1 for negative infinity). */ + +double +_Py_dg_infinity(int sign) +{ + U rv; + word0(&rv) = POSINF_WORD0; + word1(&rv) = POSINF_WORD1; + return sign ? -dval(&rv) : dval(&rv); +} + +double +_Py_dg_strtod(const char *s00, char **se) +{ + int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error; + int esign, i, j, k, lz, nd, nd0, odd, sign; + const char *s, *s0, *s1; + double aadj, aadj1; + U aadj2, adj, rv, rv0; + ULong y, z, abs_exp; + Long L; + BCinfo bc; + Bigint *bb = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL; + size_t ndigits, fraclen; + double result; + + dval(&rv) = 0.; + + /* Start parsing. */ + c = *(s = s00); + + /* Parse optional sign, if present. */ + sign = 0; + switch (c) { + case '-': + sign = 1; + /* fall through */ + case '+': + c = *++s; + } + + /* Skip leading zeros: lz is true iff there were leading zeros. */ + s1 = s; + while (c == '0') + c = *++s; + lz = s != s1; + + /* Point s0 at the first nonzero digit (if any). fraclen will be the + number of digits between the decimal point and the end of the + digit string. ndigits will be the total number of digits ignoring + leading zeros. */ + s0 = s1 = s; + while ('0' <= c && c <= '9') + c = *++s; + ndigits = s - s1; + fraclen = 0; + + /* Parse decimal point and following digits. */ + if (c == '.') { + c = *++s; + if (!ndigits) { + s1 = s; + while (c == '0') + c = *++s; + lz = lz || s != s1; + fraclen += (s - s1); + s0 = s; + } + s1 = s; + while ('0' <= c && c <= '9') + c = *++s; + ndigits += s - s1; + fraclen += s - s1; + } + + /* Now lz is true if and only if there were leading zero digits, and + ndigits gives the total number of digits ignoring leading zeros. A + valid input must have at least one digit. */ + if (!ndigits && !lz) { + if (se) + *se = (char *)s00; + goto parse_error; + } + + /* Range check ndigits and fraclen to make sure that they, and values + computed with them, can safely fit in an int. */ + if (ndigits > MAX_DIGITS || fraclen > MAX_DIGITS) { + if (se) + *se = (char *)s00; + goto parse_error; + } + nd = (int)ndigits; + nd0 = (int)ndigits - (int)fraclen; + + /* Parse exponent. */ + e = 0; + if (c == 'e' || c == 'E') { + s00 = s; + c = *++s; + + /* Exponent sign. */ + esign = 0; + switch (c) { + case '-': + esign = 1; + /* fall through */ + case '+': + c = *++s; + } + + /* Skip zeros. lz is true iff there are leading zeros. */ + s1 = s; + while (c == '0') + c = *++s; + lz = s != s1; + + /* Get absolute value of the exponent. */ + s1 = s; + abs_exp = 0; + while ('0' <= c && c <= '9') { + abs_exp = 10*abs_exp + (c - '0'); + c = *++s; + } + + /* abs_exp will be correct modulo 2**32. But 10**9 < 2**32, so if + there are at most 9 significant exponent digits then overflow is + impossible. */ + if (s - s1 > 9 || abs_exp > MAX_ABS_EXP) + e = (int)MAX_ABS_EXP; + else + e = (int)abs_exp; + if (esign) + e = -e; + + /* A valid exponent must have at least one digit. */ + if (s == s1 && !lz) + s = s00; + } + + /* Adjust exponent to take into account position of the point. */ + e -= nd - nd0; + if (nd0 <= 0) + nd0 = nd; + + /* Finished parsing. Set se to indicate how far we parsed */ + if (se) + *se = (char *)s; + + /* If all digits were zero, exit with return value +-0.0. Otherwise, + strip trailing zeros: scan back until we hit a nonzero digit. */ + if (!nd) + goto ret; + for (i = nd; i > 0; ) { + --i; + if (s0[i < nd0 ? i : i+1] != '0') { + ++i; + break; + } + } + e += nd - i; + nd = i; + if (nd0 > nd) + nd0 = nd; + + /* Summary of parsing results. After parsing, and dealing with zero + * inputs, we have values s0, nd0, nd, e, sign, where: + * + * - s0 points to the first significant digit of the input string + * + * - nd is the total number of significant digits (here, and + * below, 'significant digits' means the set of digits of the + * significand of the input that remain after ignoring leading + * and trailing zeros). + * + * - nd0 indicates the position of the decimal point, if present; it + * satisfies 1 <= nd0 <= nd. The nd significant digits are in + * s0[0:nd0] and s0[nd0+1:nd+1] using the usual Python half-open slice + * notation. (If nd0 < nd, then s0[nd0] contains a '.' character; if + * nd0 == nd, then s0[nd0] could be any non-digit character.) + * + * - e is the adjusted exponent: the absolute value of the number + * represented by the original input string is n * 10**e, where + * n is the integer represented by the concatenation of + * s0[0:nd0] and s0[nd0+1:nd+1] + * + * - sign gives the sign of the input: 1 for negative, 0 for positive + * + * - the first and last significant digits are nonzero + */ + + /* put first DBL_DIG+1 digits into integer y and z. + * + * - y contains the value represented by the first min(9, nd) + * significant digits + * + * - if nd > 9, z contains the value represented by significant digits + * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z + * gives the value represented by the first min(16, nd) sig. digits. + */ + + bc.e0 = e1 = e; + y = z = 0; + for (i = 0; i < nd; i++) { + if (i < 9) + y = 10*y + s0[i < nd0 ? i : i+1] - '0'; + else if (i < DBL_DIG+1) + z = 10*z + s0[i < nd0 ? i : i+1] - '0'; + else + break; + } + + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(&rv) = y; + if (k > 9) { + dval(&rv) = tens[k - 9] * dval(&rv) + z; + } + if (nd <= DBL_DIG + && Flt_Rounds == 1 + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { + dval(&rv) *= tens[e]; + goto ret; + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + dval(&rv) *= tens[i]; + dval(&rv) *= tens[e]; + goto ret; + } + } + else if (e >= -Ten_pmax) { + dval(&rv) /= tens[-e]; + goto ret; + } + } + e1 += nd - k; + + bc.scale = 0; + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15)) + dval(&rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) + goto ovfl; + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(&rv) = Big0; + word1(&rv) = Big1; + } + else + word0(&rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + /* The input decimal value lies in [10**e1, 10**(e1+16)). + + If e1 <= -512, underflow immediately. + If e1 <= -256, set bc.scale to 2*P. + + So for input value < 1e-256, bc.scale is always set; + for input value >= 1e-240, bc.scale is never set. + For input values in [1e-256, 1e-240), bc.scale may or may + not be set. */ + + e1 = -e1; + if ((i = e1 & 15)) + dval(&rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; + if (e1 & Scale_Bit) + bc.scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= tinytens[j]; + if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; clear j low bits */ + if (j >= 32) { + word1(&rv) = 0; + if (j >= 53) + word0(&rv) = (P+2)*Exp_msk1; + else + word0(&rv) &= 0xffffffff << (j-32); + } + else + word1(&rv) &= 0xffffffff << j; + } + if (!dval(&rv)) + goto undfl; + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bc.nd = nd; + bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */ + /* to silence an erroneous warning about bc.nd0 */ + /* possibly not being initialized. */ + if (nd > STRTOD_DIGLIM) { + /* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */ + /* minimum number of decimal digits to distinguish double values */ + /* in IEEE arithmetic. */ + + /* Truncate input to 18 significant digits, then discard any trailing + zeros on the result by updating nd, nd0, e and y suitably. (There's + no need to update z; it's not reused beyond this point.) */ + for (i = 18; i > 0; ) { + /* scan back until we hit a nonzero digit. significant digit 'i' + is s0[i] if i < nd0, s0[i+1] if i >= nd0. */ + --i; + if (s0[i < nd0 ? i : i+1] != '0') { + ++i; + break; + } + } + e += nd - i; + nd = i; + if (nd0 > nd) + nd0 = nd; + if (nd < 9) { /* must recompute y */ + y = 0; + for(i = 0; i < nd0; ++i) + y = 10*y + s0[i] - '0'; + for(; i < nd; ++i) + y = 10*y + s0[i+1] - '0'; + } + } + bd0 = s2b(s0, nd0, nd, y); + if (bd0 == NULL) + goto failed_malloc; + + /* Notation for the comments below. Write: + + - dv for the absolute value of the number represented by the original + decimal input string. + + - if we've truncated dv, write tdv for the truncated value. + Otherwise, set tdv == dv. + + - srv for the quantity rv/2^bc.scale; so srv is the current binary + approximation to tdv (and dv). It should be exactly representable + in an IEEE 754 double. + */ + + for(;;) { + + /* This is the main correction loop for _Py_dg_strtod. + + We've got a decimal value tdv, and a floating-point approximation + srv=rv/2^bc.scale to tdv. The aim is to determine whether srv is + close enough (i.e., within 0.5 ulps) to tdv, and to compute a new + approximation if not. + + To determine whether srv is close enough to tdv, compute integers + bd, bb and bs proportional to tdv, srv and 0.5 ulp(srv) + respectively, and then use integer arithmetic to determine whether + |tdv - srv| is less than, equal to, or greater than 0.5 ulp(srv). + */ + + bd = Balloc(bd0->k); + if (bd == NULL) { + goto failed_malloc; + } + Bcopy(bd, bd0); + bb = sd2b(&rv, bc.scale, &bbe); /* srv = bb * 2^bbe */ + if (bb == NULL) { + goto failed_malloc; + } + /* Record whether lsb of bb is odd, in case we need this + for the round-to-even step later. */ + odd = bb->x[0] & 1; + + /* tdv = bd * 10**e; srv = bb * 2**bbe */ + bs = i2b(1); + if (bs == NULL) { + goto failed_malloc; + } + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; + bb2++; + bd2++; + + /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1, + and bs == 1, so: + + tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5) + srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2) + 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2) + + It follows that: + + M * tdv = bd * 2**bd2 * 5**bd5 + M * srv = bb * 2**bb2 * 5**bb5 + M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5 + + for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but + this fact is not needed below.) + */ + + /* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */ + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + + /* Scale bb, bd, bs by the appropriate powers of 2 and 5. */ + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + if (bs == NULL) { + goto failed_malloc; + } + Bigint *bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + if (bb == NULL) { + goto failed_malloc; + } + } + if (bb2 > 0) { + bb = lshift(bb, bb2); + if (bb == NULL) { + goto failed_malloc; + } + } + if (bd5 > 0) { + bd = pow5mult(bd, bd5); + if (bd == NULL) { + goto failed_malloc; + } + } + if (bd2 > 0) { + bd = lshift(bd, bd2); + if (bd == NULL) { + goto failed_malloc; + } + } + if (bs2 > 0) { + bs = lshift(bs, bs2); + if (bs == NULL) { + goto failed_malloc; + } + } + + /* Now bd, bb and bs are scaled versions of tdv, srv and 0.5 ulp(srv), + respectively. Compute the difference |tdv - srv|, and compare + with 0.5 ulp(srv). */ + + delta = diff(bb, bd); + if (delta == NULL) { + goto failed_malloc; + } + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); + if (bc.nd > nd && i <= 0) { + if (dsign) + break; /* Must use bigcomp(). */ + + /* Here rv overestimates the truncated decimal value by at most + 0.5 ulp(rv). Hence rv either overestimates the true decimal + value by <= 0.5 ulp(rv), or underestimates it by some small + amount (< 0.1 ulp(rv)); either way, rv is within 0.5 ulps of + the true decimal value, so it's possible to exit. + + Exception: if scaled rv is a normal exact power of 2, but not + DBL_MIN, then rv - 0.5 ulp(rv) takes us all the way down to the + next double, so the correctly rounded result is either rv - 0.5 + ulp(rv) or rv; in this case, use bigcomp to distinguish. */ + + if (!word1(&rv) && !(word0(&rv) & Bndry_mask)) { + /* rv can't be 0, since it's an overestimate for some + nonzero value. So rv is a normal power of 2. */ + j = (int)(word0(&rv) & Exp_mask) >> Exp_shift; + /* rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if + rv / 2^bc.scale >= 2^-1021. */ + if (j - bc.scale >= 2) { + dval(&rv) -= 0.5 * sulp(&rv, &bc); + break; /* Use bigcomp. */ + } + } + + { + bc.nd = nd; + i = -1; /* Discarded digits make delta smaller. */ + } + } + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + ) { + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ + break; + } + delta = lshift(delta,Log2P); + if (delta == NULL) { + goto failed_malloc; + } + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( + (bc.scale && + (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? + (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(&rv) = (word0(&rv) & Exp_mask) + + Exp_msk1 + ; + word1(&rv) = 0; + /* dsign = 0; */ + break; + } + } + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { + drop_down: + /* boundary case -- decrement exponent */ + if (bc.scale) { + L = word0(&rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + if (bc.nd > nd) + break; + goto undfl; + } + } + L = (word0(&rv) & Exp_mask) - Exp_msk1; + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; + break; + } + if (!odd) + break; + if (dsign) + dval(&rv) += sulp(&rv, &bc); + else { + dval(&rv) -= sulp(&rv, &bc); + if (!dval(&rv)) { + if (bc.nd >nd) + break; + goto undfl; + } + } + /* dsign = 1 - dsign; */ + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { + if (word1(&rv) == Tiny1 && !word0(&rv)) { + if (bc.nd >nd) + break; + goto undfl; + } + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; + if (Flt_Rounds == 0) + aadj1 += 0.5; + } + y = word0(&rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if ((word0(&rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) { + goto ovfl; + } + word0(&rv) = Big0; + word1(&rv) = Big1; + goto cont; + } + else + word0(&rv) += P*Exp_msk1; + } + else { + if (bc.scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = (ULong)aadj) <= 0) + z = 1; + aadj = z; + aadj1 = dsign ? aadj : -aadj; + } + dval(&aadj2) = aadj1; + word0(&aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(&aadj2); + } + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } + z = word0(&rv) & Exp_mask; + if (bc.nd == nd) { + if (!bc.scale) + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + } + cont: + Bfree(bb); bb = NULL; + Bfree(bd); bd = NULL; + Bfree(bs); bs = NULL; + Bfree(delta); delta = NULL; + } + if (bc.nd > nd) { + error = bigcomp(&rv, s0, &bc); + if (error) + goto failed_malloc; + } + + if (bc.scale) { + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); + } + + ret: + result = sign ? -dval(&rv) : dval(&rv); + goto done; + + parse_error: + result = 0.0; + goto done; + + failed_malloc: + errno = ENOMEM; + result = -1.0; + goto done; + + undfl: + result = sign ? -0.0 : 0.0; + goto done; + + ovfl: + errno = ERANGE; + /* Can't trust HUGE_VAL */ + word0(&rv) = Exp_mask; + word1(&rv) = 0; + result = sign ? -dval(&rv) : dval(&rv); + goto done; + + done: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + return result; + +} + +static char * +rv_alloc(int i) +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i; + j <<= 1) + k++; + r = (int*)Balloc(k); + if (r == NULL) + return NULL; + *r = k; + return (char *)(r+1); +} + +static char * +nrv_alloc(const char *s, char **rve, int n) +{ + char *rv, *t; + + rv = rv_alloc(n); + if (rv == NULL) + return NULL; + t = rv; + while((*t = *s++)) t++; + if (rve) + *rve = t; + return rv; +} + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + +void +_Py_dg_freedtoa(char *s) +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +} + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +/* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory + leakage, a successful call to _Py_dg_dtoa should always be matched by a + call to _Py_dg_freedtoa. */ + +char * +_Py_dg_dtoa(double dd, int mode, int ndigits, + int *decpt, int *sign, char **rve) +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; + int denorm; + ULong x; + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U d2, eps, u; + double ds; + char *s, *s0; + + /* set pointers to NULL, to silence gcc compiler warnings and make + cleanup easier on error */ + mlo = mhi = S = 0; + s0 = 0; + + u.d = dd; + if (word0(&u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(&u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + + /* quick return for Infinities, NaNs and zeros */ + if ((word0(&u) & Exp_mask) == Exp_mask) + { + /* Infinity or NaN */ + *decpt = 9999; + if (!word1(&u) && !(word0(&u) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); + return nrv_alloc("NaN", rve, 3); + } + if (!dval(&u)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + + /* compute k = floor(log10(d)). The computation may leave k + one too large, but should never leave k too small. */ + b = d2b(&u, &be, &bbits); + if (b == NULL) + goto failed_malloc; + if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { + dval(&d2) = dval(&u); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) + : word1(&u) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } + ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(&u) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + + try_quick = 1; + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ + switch(mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* fall through */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* fall through */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s0 = rv_alloc(i); + if (s0 == NULL) + goto failed_malloc; + s = s0; + + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(&d2) = dval(&u); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(&u) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(&u) /= ds; + } + else if ((j1 = -k)) { + dval(&u) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(&u) *= bigtens[i]; + } + } + if (k_check && dval(&u) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(&u) *= 10.; + ieps++; + } + dval(&eps) = ieps*dval(&u) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(&u) -= 5.; + if (dval(&u) > dval(&eps)) + goto one_digit; + if (dval(&u) < -dval(&eps)) + goto no_digits; + goto fast_failed; + } + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); + for(i = 0;;) { + L = (Long)dval(&u); + dval(&u) -= L; + *s++ = '0' + (int)L; + if (dval(&u) < dval(&eps)) + goto ret1; + if (1. - dval(&u) < dval(&eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(&eps) *= 10.; + dval(&u) *= 10.; + } + } + else { + /* Generate ilim digits, then fix them up. */ + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u)); + if (!(dval(&u) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(&u) > 0.5 + dval(&eps)) + goto bump_up; + else if (dval(&u) < 0.5 - dval(&eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } + } + fast_failed: + s = s0; + dval(&u) = dval(&d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(&u) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u) / ds); + dval(&u) -= L*ds; + *s++ = '0' + (int)L; + if (!dval(&u)) { + break; + } + if (i == ilim) { + dval(&u) += dval(&u); + if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + if (leftright) { + i = + denorm ? be + (Bias + (P-1) - 1 + 1) : + 1 + P - bbits; + b2 += i; + s2 += i; + mhi = i2b(1); + if (mhi == NULL) + goto failed_malloc; + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + if (mhi == NULL) + goto failed_malloc; + b1 = mult(mhi, b); + Bfree(b); + b = b1; + if (b == NULL) + goto failed_malloc; + } + if ((j = b5 - m5)) { + b = pow5mult(b, j); + if (b == NULL) + goto failed_malloc; + } + } + else { + b = pow5mult(b, b5); + if (b == NULL) + goto failed_malloc; + } + } + S = i2b(1); + if (S == NULL) + goto failed_malloc; + if (s5 > 0) { + S = pow5mult(S, s5); + if (S == NULL) + goto failed_malloc; + } + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) + ) { + if (!word1(&u) && !(word0(&u) & Bndry_mask) + && word0(&u) & (Exp_mask & ~Exp_msk1) + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#define iInc 28 + i = dshift(S, s2); + b2 += i; + m2 += i; + s2 += i; + if (b2 > 0) { + b = lshift(b, b2); + if (b == NULL) + goto failed_malloc; + } + if (s2 > 0) { + S = lshift(S, s2); + if (S == NULL) + goto failed_malloc; + } + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (b == NULL) + goto failed_malloc; + if (leftright) { + mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; + } + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + else { + S = multadd(S, 5, 0); + if (S == NULL) + goto failed_malloc; + if (cmp(b, S) <= 0) + goto no_digits; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) { + mhi = lshift(mhi, m2); + if (mhi == NULL) + goto failed_malloc; + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + if (mhi == NULL) + goto failed_malloc; + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + if (mhi == NULL) + goto failed_malloc; + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + if (delta == NULL) + goto failed_malloc; + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); + if (j1 == 0 && mode != 1 && !(word1(&u) & 1) + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = dig; + goto ret; + } + if (j < 0 || (j == 0 && mode != 1 + && !(word1(&u) & 1) + )) { + if (!b->x[0] && b->wds <= 1) { + goto accept_dig; + } + if (j1 > 0) { + b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && dig & 1)) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (b == NULL) + goto failed_malloc; + if (mlo == mhi) { + mlo = mhi = multadd(mhi, 10, 0); + if (mlo == NULL) + goto failed_malloc; + } + else { + mlo = multadd(mlo, 10, 0); + if (mlo == NULL) + goto failed_malloc; + mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + if (b == NULL) + goto failed_malloc; + } + + /* Round off last digit */ + + b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; + j = cmp(b, S); + if (j > 0 || (j == 0 && dig & 1)) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + failed_malloc: + if (S) + Bfree(S); + if (mlo && mlo != mhi) + Bfree(mlo); + if (mhi) + Bfree(mhi); + if (b) + Bfree(b); + if (s0) + _Py_dg_freedtoa(s0); + return NULL; +} +#ifdef __cplusplus +} +#endif + +#endif /* PY_NO_SHORT_FLOAT_REPR */ diff --git a/python/Python/dup2.c b/python/Python/dup2.c new file mode 100755 index 0000000..7c6bbfc --- /dev/null +++ b/python/Python/dup2.c @@ -0,0 +1,31 @@ +/* + * Public domain dup2() lookalike + * by Curtis Jackson @ AT&T Technologies, Burlington, NC + * electronic address: burl!rcj + * + * dup2 performs the following functions: + * + * Check to make sure that fd1 is a valid open file descriptor. + * Check to see if fd2 is already open; if so, close it. + * Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd. + * Return fd2 if all went well; return BADEXIT otherwise. + */ + +#include +#include + +#define BADEXIT -1 + +int +dup2(int fd1, int fd2) +{ + if (fd1 != fd2) { + if (fcntl(fd1, F_GETFL) < 0) + return BADEXIT; + if (fcntl(fd2, F_GETFL) >= 0) + close(fd2); + if (fcntl(fd1, F_DUPFD, fd2) < 0) + return BADEXIT; + } + return fd2; +} diff --git a/python/Python/dynamic_annotations.c b/python/Python/dynamic_annotations.c new file mode 100755 index 0000000..7febaa0 --- /dev/null +++ b/python/Python/dynamic_annotations.c @@ -0,0 +1,154 @@ +/* Copyright (c) 2008-2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Neither the name of Google Inc. 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 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. + * + * --- + * Author: Kostya Serebryany + */ + +#ifdef _MSC_VER +# include +#endif + +#ifdef __cplusplus +# error "This file should be built as pure C to avoid name mangling" +#endif + +#include +#include + +#include "dynamic_annotations.h" + +/* Each function is empty and called (via a macro) only in debug mode. + The arguments are captured by dynamic tools at runtime. */ + +#if DYNAMIC_ANNOTATIONS_ENABLED == 1 + +void AnnotateRWLockCreate(const char *file, int line, + const volatile void *lock){} +void AnnotateRWLockDestroy(const char *file, int line, + const volatile void *lock){} +void AnnotateRWLockAcquired(const char *file, int line, + const volatile void *lock, long is_w){} +void AnnotateRWLockReleased(const char *file, int line, + const volatile void *lock, long is_w){} +void AnnotateBarrierInit(const char *file, int line, + const volatile void *barrier, long count, + long reinitialization_allowed) {} +void AnnotateBarrierWaitBefore(const char *file, int line, + const volatile void *barrier) {} +void AnnotateBarrierWaitAfter(const char *file, int line, + const volatile void *barrier) {} +void AnnotateBarrierDestroy(const char *file, int line, + const volatile void *barrier) {} + +void AnnotateCondVarWait(const char *file, int line, + const volatile void *cv, + const volatile void *lock){} +void AnnotateCondVarSignal(const char *file, int line, + const volatile void *cv){} +void AnnotateCondVarSignalAll(const char *file, int line, + const volatile void *cv){} +void AnnotatePublishMemoryRange(const char *file, int line, + const volatile void *address, + long size){} +void AnnotateUnpublishMemoryRange(const char *file, int line, + const volatile void *address, + long size){} +void AnnotatePCQCreate(const char *file, int line, + const volatile void *pcq){} +void AnnotatePCQDestroy(const char *file, int line, + const volatile void *pcq){} +void AnnotatePCQPut(const char *file, int line, + const volatile void *pcq){} +void AnnotatePCQGet(const char *file, int line, + const volatile void *pcq){} +void AnnotateNewMemory(const char *file, int line, + const volatile void *mem, + long size){} +void AnnotateExpectRace(const char *file, int line, + const volatile void *mem, + const char *description){} +void AnnotateBenignRace(const char *file, int line, + const volatile void *mem, + const char *description){} +void AnnotateBenignRaceSized(const char *file, int line, + const volatile void *mem, + long size, + const char *description) {} +void AnnotateMutexIsUsedAsCondVar(const char *file, int line, + const volatile void *mu){} +void AnnotateTraceMemory(const char *file, int line, + const volatile void *arg){} +void AnnotateThreadName(const char *file, int line, + const char *name){} +void AnnotateIgnoreReadsBegin(const char *file, int line){} +void AnnotateIgnoreReadsEnd(const char *file, int line){} +void AnnotateIgnoreWritesBegin(const char *file, int line){} +void AnnotateIgnoreWritesEnd(const char *file, int line){} +void AnnotateIgnoreSyncBegin(const char *file, int line){} +void AnnotateIgnoreSyncEnd(const char *file, int line){} +void AnnotateEnableRaceDetection(const char *file, int line, int enable){} +void AnnotateNoOp(const char *file, int line, + const volatile void *arg){} +void AnnotateFlushState(const char *file, int line){} + +static int GetRunningOnValgrind(void) { +#ifdef RUNNING_ON_VALGRIND + if (RUNNING_ON_VALGRIND) return 1; +#endif + +#ifndef _MSC_VER + const char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); + if (running_on_valgrind_str) { + return strcmp(running_on_valgrind_str, "0") != 0; + } +#else + /* Visual Studio issues warnings if we use getenv, + * so we use GetEnvironmentVariableA instead. + */ + char value[100] = "1"; + int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND", + value, sizeof(value)); + /* value will remain "1" if res == 0 or res >= sizeof(value). The latter + * can happen only if the given value is long, in this case it can't be "0". + */ + if (res > 0 && !strcmp(value, "0")) + return 1; +#endif + return 0; +} + +/* See the comments in dynamic_annotations.h */ +int RunningOnValgrind(void) { + static volatile int running_on_valgrind = -1; + /* C doesn't have thread-safe initialization of statics, and we + don't want to depend on pthread_once here, so hack it. */ + int local_running_on_valgrind = running_on_valgrind; + if (local_running_on_valgrind == -1) + running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); + return local_running_on_valgrind; +} + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */ diff --git a/python/Python/dynload_aix.c b/python/Python/dynload_aix.c new file mode 100755 index 0000000..25fe19e --- /dev/null +++ b/python/Python/dynload_aix.c @@ -0,0 +1,190 @@ + +/* Support for dynamic loading of extension modules */ + +#include "Python.h" +#include "importdl.h" + +#include /* for global errno */ +#include /* for strerror() */ +#include /* for malloc(), free() */ +#include + + +#ifdef AIX_GENUINE_CPLUSPLUS +#include +#define aix_load loadAndInit +#else +#define aix_load load +#endif + + +extern char *Py_GetProgramName(void); + +typedef struct Module { + struct Module *next; + void *entry; +} Module, *ModulePtr; + +const char *_PyImport_DynLoadFiletab[] = {".so", NULL}; + +static int +aix_getoldmodules(void **modlistptr) +{ + ModulePtr modptr, prevmodptr; + struct ld_info *ldiptr; + char *ldibuf; + int errflag, bufsize = 1024; + unsigned int offset; + char *progname = Py_GetProgramName(); + + /* + -- Get the list of loaded modules into ld_info structures. + */ + if ((ldibuf = malloc(bufsize)) == NULL) { + PyErr_SetString(PyExc_ImportError, strerror(errno)); + return -1; + } + while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1 + && errno == ENOMEM) { + free(ldibuf); + bufsize += 1024; + if ((ldibuf = malloc(bufsize)) == NULL) { + PyErr_SetString(PyExc_ImportError, strerror(errno)); + return -1; + } + } + if (errflag == -1) { + PyErr_SetString(PyExc_ImportError, strerror(errno)); + return -1; + } + /* + -- Make the modules list from the ld_info structures. + */ + ldiptr = (struct ld_info *)ldibuf; + prevmodptr = NULL; + do { + if (strstr(progname, ldiptr->ldinfo_filename) == NULL && + strstr(ldiptr->ldinfo_filename, "python") == NULL) { + /* + -- Extract only the modules belonging to the main + -- executable + those containing "python" as a + -- substring (like the "python[version]" binary or + -- "libpython[version].a" in case it's a shared lib). + */ + offset = (unsigned int)ldiptr->ldinfo_next; + ldiptr = (struct ld_info *)((char*)ldiptr + offset); + continue; + } + if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) { + PyErr_SetString(PyExc_ImportError, strerror(errno)); + while (*modlistptr) { + modptr = (ModulePtr)*modlistptr; + *modlistptr = (void *)modptr->next; + free(modptr); + } + return -1; + } + modptr->entry = ldiptr->ldinfo_dataorg; + modptr->next = NULL; + if (prevmodptr == NULL) + *modlistptr = (void *)modptr; + else + prevmodptr->next = modptr; + prevmodptr = modptr; + offset = (unsigned int)ldiptr->ldinfo_next; + ldiptr = (struct ld_info *)((char*)ldiptr + offset); + } while (offset); + free(ldibuf); + return 0; +} + + +static void +aix_loaderror(const char *pathname) +{ + + char *message[1024], errbuf[1024]; + PyObject *pathname_ob = NULL; + PyObject *errbuf_ob = NULL; + int i,j; + + struct errtab { + int errNo; + char *errstr; + } load_errtab[] = { + {L_ERROR_TOOMANY, "too many errors, rest skipped."}, + {L_ERROR_NOLIB, "can't load library:"}, + {L_ERROR_UNDEF, "can't find symbol in library:"}, + {L_ERROR_RLDBAD, + "RLD index out of range or bad relocation type:"}, + {L_ERROR_FORMAT, "not a valid, executable xcoff file:"}, + {L_ERROR_MEMBER, + "file not an archive or does not contain requested member:"}, + {L_ERROR_TYPE, "symbol table mismatch:"}, + {L_ERROR_ALIGN, "text alignment in file is wrong."}, + {L_ERROR_SYSTEM, "System error:"}, + {L_ERROR_ERRNO, NULL} + }; + +#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1) + + PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname); + + if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) { + ERRBUF_APPEND(strerror(errno)); + ERRBUF_APPEND("\n"); + } + for(i = 0; message[i] && *message[i]; i++) { + int nerr = atoi(message[i]); + for (j=0; j < Py_ARRAY_LENGTH(load_errtab); j++) { + if (nerr == load_errtab[j].errNo && load_errtab[j].errstr) + ERRBUF_APPEND(load_errtab[j].errstr); + } + while (Py_ISDIGIT(Py_CHARMASK(*message[i]))) message[i]++ ; + ERRBUF_APPEND(message[i]); + ERRBUF_APPEND("\n"); + } + /* Subtract 1 from the length to trim off trailing newline */ + errbuf_ob = PyUnicode_DecodeLocaleAndSize(errbuf, strlen(errbuf)-1, "surrogateescape"); + if (errbuf_ob == NULL) + return; + pathname_ob = PyUnicode_DecodeFSDefault(pathname); + if (pathname_ob == NULL) { + Py_DECREF(errbuf_ob); + return; + } + PyErr_SetImportError(errbuf_ob, NULL, pathname_ob); + Py_DECREF(pathname_ob); + Py_DECREF(errbuf_ob); + return; +} + + +dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) +{ + dl_funcptr p; + + /* + -- Invoke load() with L_NOAUTODEFER leaving the imported symbols + -- of the shared module unresolved. Thus we have to resolve them + -- explicitly with loadbind. The new module is loaded, then we + -- resolve its symbols using the list of already loaded modules + -- (only those that belong to the python executable). Get these + -- with loadquery(L_GETINFO). + */ + + static void *staticmodlistptr = NULL; + + if (!staticmodlistptr) + if (aix_getoldmodules(&staticmodlistptr) == -1) + return NULL; + p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0); + if (p == NULL) { + aix_loaderror(pathname); + return NULL; + } + + return p; +} diff --git a/python/Python/dynload_dl.c b/python/Python/dynload_dl.c new file mode 100755 index 0000000..2bec645 --- /dev/null +++ b/python/Python/dynload_dl.c @@ -0,0 +1,23 @@ + +/* Support for dynamic loading of extension modules */ + +#include "dl.h" + +#include "Python.h" +#include "importdl.h" + + +extern char *Py_GetProgramName(void); + +const char *_PyImport_DynLoadFiletab[] = {".o", NULL}; + + +dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) +{ + char funcname[258]; + + PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname); + return dl_loadmod(Py_GetProgramName(), pathname, funcname); +} diff --git a/python/Python/dynload_hpux.c b/python/Python/dynload_hpux.c new file mode 100755 index 0000000..9fa003c --- /dev/null +++ b/python/Python/dynload_hpux.c @@ -0,0 +1,77 @@ + +/* Support for dynamic loading of extension modules */ + +#include "dl.h" +#include + +#include "Python.h" +#include "importdl.h" +#include "pycore_pystate.h" + +#if defined(__hp9000s300) +#define FUNCNAME_PATTERN "_%.20s_%.200s" +#else +#define FUNCNAME_PATTERN "%.20s_%.200s" +#endif + +const char *_PyImport_DynLoadFiletab[] = {SHLIB_EXT, NULL}; + +dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) +{ + int flags = BIND_FIRST | BIND_DEFERRED; + int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose; + if (verbose) { + flags = BIND_FIRST | BIND_IMMEDIATE | + BIND_NONFATAL | BIND_VERBOSE; + printf("shl_load %s\n",pathname); + } + + shl_t lib = shl_load(pathname, flags, 0); + /* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */ + if (lib == NULL) { + if (verbose) { + perror(pathname); + } + char buf[256]; + PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s", + pathname); + PyObject *buf_ob = PyUnicode_DecodeFSDefault(buf); + if (buf_ob == NULL) + return NULL; + PyObject *shortname_ob = PyUnicode_FromString(shortname); + if (shortname_ob == NULL) { + Py_DECREF(buf_ob); + return NULL; + } + PyObject *pathname_ob = PyUnicode_DecodeFSDefault(pathname); + if (pathname_ob == NULL) { + Py_DECREF(buf_ob); + Py_DECREF(shortname_ob); + return NULL; + } + PyErr_SetImportError(buf_ob, shortname_ob, pathname_ob); + Py_DECREF(buf_ob); + Py_DECREF(shortname_ob); + Py_DECREF(pathname_ob); + return NULL; + } + + char funcname[258]; + PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN, + prefix, shortname); + if (verbose) { + printf("shl_findsym %s\n", funcname); + } + + dl_funcptr p; + if (shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p) == -1) { + shl_unload(lib); + p = NULL; + } + if (p == NULL && verbose) { + perror(funcname); + } + return p; +} diff --git a/python/Python/dynload_shlib.c b/python/Python/dynload_shlib.c new file mode 100755 index 0000000..dd7e7d7 --- /dev/null +++ b/python/Python/dynload_shlib.c @@ -0,0 +1,133 @@ + +/* Support for dynamic loading of extension modules */ + +#include "Python.h" +#include "pycore_pystate.h" +#include "importdl.h" + +#include +#include + +#if defined(__NetBSD__) +#include +#if (NetBSD < 199712) +#include +#include +#define dlerror() "error in dynamic linking" +#endif +#endif /* NetBSD */ + +#ifdef HAVE_DLFCN_H +#include +#endif + +#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) +#define LEAD_UNDERSCORE "_" +#else +#define LEAD_UNDERSCORE "" +#endif + +/* The .so extension module ABI tag, supplied by the Makefile via + Makefile.pre.in and configure. This is used to discriminate between + incompatible .so files so that extensions for different Python builds can + live in the same directory. E.g. foomodule.cpython-32.so +*/ + +const char *_PyImport_DynLoadFiletab[] = { +#ifdef __CYGWIN__ + ".dll", +#else /* !__CYGWIN__ */ + "." SOABI ".so", +#ifdef ALT_SOABI + "." ALT_SOABI ".so", +#endif + ".abi" PYTHON_ABI_STRING ".so", + ".so", +#endif /* __CYGWIN__ */ + NULL, +}; + +static struct { + dev_t dev; + ino_t ino; + void *handle; +} handles[128]; +static int nhandles = 0; + + +dl_funcptr +_PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) +{ + // printf("\ncxunmz[%s\n%s\n%s]\n",prefix,shortname,pathname); + dl_funcptr p; + void *handle; + char funcname[258]; + char pathbuf[260]; + int dlopenflags=0; + + if (strchr(pathname, '/') == NULL) { + /* Prefix bare filename with "./" */ + PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); + pathname = pathbuf; + } + + PyOS_snprintf(funcname, sizeof(funcname), + LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname); + + if (fp != NULL) { + int i; + struct _Py_stat_struct status; + if (_Py_fstat(fileno(fp), &status) == -1) + return NULL; + for (i = 0; i < nhandles; i++) { + if (status.st_dev == handles[i].dev && + status.st_ino == handles[i].ino) { + p = (dl_funcptr) dlsym(handles[i].handle, + funcname); + return p; + } + } + if (nhandles < 128) { + handles[nhandles].dev = status.st_dev; + handles[nhandles].ino = status.st_ino; + } + } + + dlopenflags = _PyInterpreterState_Get()->dlopenflags; + + handle = dlopen(pathname, dlopenflags); + + if (handle == NULL) { + PyObject *mod_name; + PyObject *path; + PyObject *error_ob; + const char *error = dlerror(); + if (error == NULL) + error = "unknown dlopen() error"; + error_ob = PyUnicode_DecodeLocale(error, "surrogateescape"); + if (error_ob == NULL) + return NULL; + mod_name = PyUnicode_FromString(shortname); + if (mod_name == NULL) { + Py_DECREF(error_ob); + return NULL; + } + path = PyUnicode_DecodeFSDefault(pathname); + if (path == NULL) { + Py_DECREF(error_ob); + Py_DECREF(mod_name); + return NULL; + } + PyErr_SetImportError(error_ob, mod_name, path); + Py_DECREF(error_ob); + Py_DECREF(mod_name); + Py_DECREF(path); + return NULL; + } + if (fp != NULL && nhandles < 128) + handles[nhandles++].handle = handle; + p = (dl_funcptr) dlsym(handle, funcname); + return p; +} diff --git a/python/Python/dynload_stub.c b/python/Python/dynload_stub.c new file mode 100755 index 0000000..495364c --- /dev/null +++ b/python/Python/dynload_stub.c @@ -0,0 +1,9 @@ + +// /* This module provides the necessary stubs for when dynamic loading is +// not present. */ + +// #include "Python.h" +// #include "importdl.h" + + +// const char *_PyImport_DynLoadFiletab[] = {NULL}; diff --git a/python/Python/dynload_win.c b/python/Python/dynload_win.c new file mode 100755 index 0000000..4896c6d --- /dev/null +++ b/python/Python/dynload_win.c @@ -0,0 +1,297 @@ + +/* Support for dynamic loading of extension modules */ + +#include "Python.h" + +#ifdef HAVE_DIRECT_H +#include +#endif +#include + +#include "importdl.h" +#include "patchlevel.h" +#include + +// "activation context" magic - see dl_nt.c... +#if HAVE_SXS +extern ULONG_PTR _Py_ActivateActCtx(); +void _Py_DeactivateActCtx(ULONG_PTR cookie); +#endif + +#ifdef _DEBUG +#define PYD_DEBUG_SUFFIX "_d" +#else +#define PYD_DEBUG_SUFFIX "" +#endif + +#ifdef PYD_PLATFORM_TAG +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" +#else +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) ".pyd" +#endif + +#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" + +const char *_PyImport_DynLoadFiletab[] = { + PYD_TAGGED_SUFFIX, + PYD_UNTAGGED_SUFFIX, + NULL +}; + +/* Function to return the name of the "python" DLL that the supplied module + directly imports. Looks through the list of imported modules and + returns the first entry that starts with "python" (case sensitive) and + is followed by nothing but numbers until the separator (period). + + Returns a pointer to the import name, or NULL if no matching name was + located. + + This function parses through the PE header for the module as loaded in + memory by the system loader. The PE header is accessed as documented by + Microsoft in the MSDN PE and COFF specification (2/99), and handles + both PE32 and PE32+. It only worries about the direct import table and + not the delay load import table since it's unlikely an extension is + going to be delay loading Python (after all, it's already loaded). + + If any magic values are not found (e.g., the PE header or optional + header magic), then this function simply returns NULL. */ + +#define DWORD_AT(mem) (*(DWORD *)(mem)) +#define WORD_AT(mem) (*(WORD *)(mem)) + +static char *GetPythonImport (HINSTANCE hModule) +{ + unsigned char *dllbase, *import_data, *import_name; + DWORD pe_offset, opt_offset; + WORD opt_magic; + int num_dict_off, import_off; + + /* Safety check input */ + if (hModule == NULL) { + return NULL; + } + + /* Module instance is also the base load address. First portion of + memory is the MS-DOS loader, which holds the offset to the PE + header (from the load base) at 0x3C */ + dllbase = (unsigned char *)hModule; + pe_offset = DWORD_AT(dllbase + 0x3C); + + /* The PE signature must be "PE\0\0" */ + if (memcmp(dllbase+pe_offset,"PE\0\0",4)) { + return NULL; + } + + /* Following the PE signature is the standard COFF header (20 + bytes) and then the optional header. The optional header starts + with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+ + uses 64-bits for some fields). It might also be 0x107 for a ROM + image, but we don't process that here. + + The optional header ends with a data dictionary that directly + points to certain types of data, among them the import entries + (in the second table entry). Based on the header type, we + determine offsets for the data dictionary count and the entry + within the dictionary pointing to the imports. */ + + opt_offset = pe_offset + 4 + 20; + opt_magic = WORD_AT(dllbase+opt_offset); + if (opt_magic == 0x10B) { + /* PE32 */ + num_dict_off = 92; + import_off = 104; + } else if (opt_magic == 0x20B) { + /* PE32+ */ + num_dict_off = 108; + import_off = 120; + } else { + /* Unsupported */ + return NULL; + } + + /* Now if an import table exists, offset to it and walk the list of + imports. The import table is an array (ending when an entry has + empty values) of structures (20 bytes each), which contains (at + offset 12) a relative address (to the module base) at which a + string constant holding the import name is located. */ + + if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) { + /* We have at least 2 tables - the import table is the second + one. But still it may be that the table size is zero */ + if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD))) + return NULL; + import_data = dllbase + DWORD_AT(dllbase + + opt_offset + + import_off); + while (DWORD_AT(import_data)) { + import_name = dllbase + DWORD_AT(import_data+12); + if (strlen(import_name) >= 6 && + !strncmp(import_name,"python",6)) { + char *pch; + +#ifndef _DEBUG + /* In a release version, don't claim that python3.dll is + a Python DLL. */ + if (strcmp(import_name, "python3.dll") == 0) { + import_data += 20; + continue; + } +#endif + + /* Ensure python prefix is followed only + by numbers to the end of the basename */ + pch = import_name + 6; +#ifdef _DEBUG + while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') { +#else + while (*pch && *pch != '.') { +#endif + if (*pch >= '0' && *pch <= '9') { + pch++; + } else { + pch = NULL; + break; + } + } + + if (pch) { + /* Found it - return the name */ + return import_name; + } + } + import_data += 20; + } + } + + return NULL; +} + +dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, + const char *shortname, + PyObject *pathname, FILE *fp) +{ + dl_funcptr p; + char funcname[258], *import_python; + const wchar_t *wpathname; + + _Py_CheckPython3(); + + wpathname = _PyUnicode_AsUnicode(pathname); + if (wpathname == NULL) + return NULL; + + PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname); + + { + HINSTANCE hDLL = NULL; + unsigned int old_mode; +#if HAVE_SXS + ULONG_PTR cookie = 0; +#endif + + /* Don't display a message box when Python can't load a DLL */ + old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); + +#if HAVE_SXS + cookie = _Py_ActivateActCtx(); +#endif + /* bpo-36085: We use LoadLibraryEx with restricted search paths + to avoid DLL preloading attacks and enable use of the + AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to + ensure DLLs adjacent to the PYD are preferred. */ + Py_BEGIN_ALLOW_THREADS + hDLL = LoadLibraryExW(wpathname, NULL, + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); + Py_END_ALLOW_THREADS +#if HAVE_SXS + _Py_DeactivateActCtx(cookie); +#endif + + /* restore old error mode settings */ + SetErrorMode(old_mode); + + if (hDLL==NULL){ + PyObject *message; + unsigned int errorCode; + + /* Get an error string from Win32 error code */ + wchar_t theInfo[256]; /* Pointer to error text + from system */ + int theLength; /* Length of error text */ + + errorCode = GetLastError(); + + theLength = FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */ + NULL, /* message source */ + errorCode, /* the message (error) ID */ + MAKELANGID(LANG_NEUTRAL, + SUBLANG_DEFAULT), + /* Default language */ + theInfo, /* the buffer */ + sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */ + NULL); /* no additional format args. */ + + /* Problem: could not get the error message. + This should not happen if called correctly. */ + if (theLength == 0) { + message = PyUnicode_FromFormat( + "DLL load failed with error code %u while importing %s", + errorCode, shortname); + } else { + /* For some reason a \r\n + is appended to the text */ + if (theLength >= 2 && + theInfo[theLength-2] == '\r' && + theInfo[theLength-1] == '\n') { + theLength -= 2; + theInfo[theLength] = '\0'; + } + message = PyUnicode_FromFormat( + "DLL load failed while importing %s: ", shortname); + + PyUnicode_AppendAndDel(&message, + PyUnicode_FromWideChar( + theInfo, + theLength)); + } + if (message != NULL) { + PyObject *shortname_obj = PyUnicode_FromString(shortname); + PyErr_SetImportError(message, shortname_obj, pathname); + Py_XDECREF(shortname_obj); + Py_DECREF(message); + } + return NULL; + } else { + char buffer[256]; + + PyOS_snprintf(buffer, sizeof(buffer), +#ifdef _DEBUG + "python%d%d_d.dll", +#else + "python%d%d.dll", +#endif + PY_MAJOR_VERSION,PY_MINOR_VERSION); + import_python = GetPythonImport(hDLL); + + if (import_python && + _stricmp(buffer,import_python)) { + PyErr_Format(PyExc_ImportError, + "Module use of %.150s conflicts " + "with this version of Python.", + import_python); + Py_BEGIN_ALLOW_THREADS + FreeLibrary(hDLL); + Py_END_ALLOW_THREADS + return NULL; + } + } + Py_BEGIN_ALLOW_THREADS + p = GetProcAddress(hDLL, funcname); + Py_END_ALLOW_THREADS + } + + return p; +} diff --git a/python/Python/errors.c b/python/Python/errors.c new file mode 100755 index 0000000..1360c0d --- /dev/null +++ b/python/Python/errors.c @@ -0,0 +1,1613 @@ + +/* Error handling */ + +#include "Python.h" +#include "pycore_initconfig.h" +#include "pycore_pyerrors.h" +#include "pycore_pystate.h" +#include "pycore_traceback.h" + +#ifndef __STDC__ +#ifndef MS_WINDOWS +extern char *strerror(int); +#endif +#endif + +#ifdef MS_WINDOWS +#include +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +_Py_IDENTIFIER(builtins); +_Py_IDENTIFIER(stderr); +_Py_IDENTIFIER(flush); + + +/* Forward declarations */ +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs); + + +void +_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, + PyObject *traceback) +{ + PyObject *oldtype, *oldvalue, *oldtraceback; + + if (traceback != NULL && !PyTraceBack_Check(traceback)) { + /* XXX Should never happen -- fatal error instead? */ + /* Well, it could be None. */ + Py_DECREF(traceback); + traceback = NULL; + } + + /* Save these in locals to safeguard against recursive + invocation through Py_XDECREF */ + oldtype = tstate->curexc_type; + oldvalue = tstate->curexc_value; + oldtraceback = tstate->curexc_traceback; + + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = traceback; + + Py_XDECREF(oldtype); + Py_XDECREF(oldvalue); + Py_XDECREF(oldtraceback); +} + +void +PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Restore(tstate, type, value, traceback); +} + + +_PyErr_StackItem * +_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} + +static PyObject* +_PyErr_CreateException(PyObject *exception, PyObject *value) +{ + if (value == NULL || value == Py_None) { + return _PyObject_CallNoArg(exception); + } + else if (PyTuple_Check(value)) { + return PyObject_Call(exception, value, NULL); + } + else { + return PyObject_CallFunctionObjArgs(exception, value, NULL); + } +} + +void +_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) +{ + PyObject *exc_value; + PyObject *tb = NULL; + + if (exception != NULL && + !PyExceptionClass_Check(exception)) { + _PyErr_Format(tstate, PyExc_SystemError, + "exception %R not a BaseException subclass", + exception); + return; + } + + Py_XINCREF(value); + exc_value = _PyErr_GetTopmostException(tstate)->exc_value; + if (exc_value != NULL && exc_value != Py_None) { + /* Implicit exception chaining */ + Py_INCREF(exc_value); + if (value == NULL || !PyExceptionInstance_Check(value)) { + /* We must normalize the value right now */ + PyObject *fixed_value; + + /* Issue #23571: functions must not be called with an + exception set */ + _PyErr_Clear(tstate); + + fixed_value = _PyErr_CreateException(exception, value); + Py_XDECREF(value); + if (fixed_value == NULL) { + Py_DECREF(exc_value); + return; + } + + value = fixed_value; + } + + /* Avoid reference cycles through the context chain. + This is O(chain length) but context chains are + usually very short. Sensitive readers may try + to inline the call to PyException_GetContext. */ + if (exc_value != value) { + PyObject *o = exc_value, *context; + while ((context = PyException_GetContext(o))) { + Py_DECREF(context); + if (context == value) { + PyException_SetContext(o, NULL); + break; + } + o = context; + } + PyException_SetContext(value, exc_value); + } + else { + Py_DECREF(exc_value); + } + } + if (value != NULL && PyExceptionInstance_Check(value)) + tb = PyException_GetTraceback(value); + Py_XINCREF(exception); + _PyErr_Restore(tstate, exception, value, tb); +} + +void +PyErr_SetObject(PyObject *exception, PyObject *value) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetObject(tstate, exception, value); +} + +/* Set a key error with the specified argument, wrapping it in a + * tuple automatically so that tuple keys are not unpacked as the + * exception arguments. */ +void +_PyErr_SetKeyError(PyObject *arg) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *tup = PyTuple_Pack(1, arg); + if (!tup) { + /* caller will expect error to be set anyway */ + return; + } + _PyErr_SetObject(tstate, PyExc_KeyError, tup); + Py_DECREF(tup); +} + +void +_PyErr_SetNone(PyThreadState *tstate, PyObject *exception) +{ + _PyErr_SetObject(tstate, exception, (PyObject *)NULL); +} + + +void +PyErr_SetNone(PyObject *exception) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetNone(tstate, exception); +} + + +void +_PyErr_SetString(PyThreadState *tstate, PyObject *exception, + const char *string) +{ + PyObject *value = PyUnicode_FromString(string); + _PyErr_SetObject(tstate, exception, value); + Py_XDECREF(value); +} + +void +PyErr_SetString(PyObject *exception, const char *string) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, exception, string); +} + + +PyObject* _Py_HOT_FUNCTION +PyErr_Occurred(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_Occurred(tstate); +} + + +int +PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) +{ + if (err == NULL || exc == NULL) { + /* maybe caused by "import exceptions" that failed early on */ + return 0; + } + if (PyTuple_Check(exc)) { + Py_ssize_t i, n; + n = PyTuple_Size(exc); + for (i = 0; i < n; i++) { + /* Test recursively */ + if (PyErr_GivenExceptionMatches( + err, PyTuple_GET_ITEM(exc, i))) + { + return 1; + } + } + return 0; + } + /* err might be an instance, so check its class. */ + if (PyExceptionInstance_Check(err)) + err = PyExceptionInstance_Class(err); + + if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) { + return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc); + } + + return err == exc; +} + + +int +_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc) +{ + return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); +} + + +int +PyErr_ExceptionMatches(PyObject *exc) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_ExceptionMatches(tstate, exc); +} + + +#ifndef Py_NORMALIZE_RECURSION_LIMIT +#define Py_NORMALIZE_RECURSION_LIMIT 32 +#endif + +/* Used in many places to normalize a raised exception, including in + eval_code2(), do_raise(), and PyErr_Print() + + XXX: should PyErr_NormalizeException() also call + PyException_SetTraceback() with the resulting value and tb? +*/ +void +_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, + PyObject **val, PyObject **tb) +{ + int recursion_depth = 0; + PyObject *type, *value, *initial_tb; + + restart: + type = *exc; + if (type == NULL) { + /* There was no exception, so nothing to do. */ + return; + } + + value = *val; + /* If PyErr_SetNone() was used, the value will have been actually + set to NULL. + */ + if (!value) { + value = Py_None; + Py_INCREF(value); + } + + /* Normalize the exception so that if the type is a class, the + value will be an instance. + */ + if (PyExceptionClass_Check(type)) { + PyObject *inclass = NULL; + int is_subclass = 0; + + if (PyExceptionInstance_Check(value)) { + inclass = PyExceptionInstance_Class(value); + is_subclass = PyObject_IsSubclass(inclass, type); + if (is_subclass < 0) { + goto error; + } + } + + /* If the value was not an instance, or is not an instance + whose class is (or is derived from) type, then use the + value as an argument to instantiation of the type + class. + */ + if (!is_subclass) { + PyObject *fixed_value = _PyErr_CreateException(type, value); + if (fixed_value == NULL) { + goto error; + } + Py_DECREF(value); + value = fixed_value; + } + /* If the class of the instance doesn't exactly match the + class of the type, believe the instance. + */ + else if (inclass != type) { + Py_INCREF(inclass); + Py_DECREF(type); + type = inclass; + } + } + *exc = type; + *val = value; + return; + + error: + Py_DECREF(type); + Py_DECREF(value); + recursion_depth++; + if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) { + _PyErr_SetString(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded " + "while normalizing an exception"); + } + /* If the new exception doesn't set a traceback and the old + exception had a traceback, use the old traceback for the + new exception. It's better than nothing. + */ + initial_tb = *tb; + _PyErr_Fetch(tstate, exc, val, tb); + assert(*exc != NULL); + if (initial_tb != NULL) { + if (*tb == NULL) + *tb = initial_tb; + else + Py_DECREF(initial_tb); + } + /* Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded, and the + corresponding RecursionError could not be normalized, and the + MemoryError raised when normalize this RecursionError could not be + normalized. */ + if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) { + if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) { + Py_FatalError("Cannot recover from MemoryErrors " + "while normalizing exceptions."); + } + else { + Py_FatalError("Cannot recover from the recursive normalization " + "of an exception."); + } + } + goto restart; +} + + +void +PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_NormalizeException(tstate, exc, val, tb); +} + + +void +_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, + PyObject **p_traceback) +{ + *p_type = tstate->curexc_type; + *p_value = tstate->curexc_value; + *p_traceback = tstate->curexc_traceback; + + tstate->curexc_type = NULL; + tstate->curexc_value = NULL; + tstate->curexc_traceback = NULL; +} + + +void +PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Fetch(tstate, p_type, p_value, p_traceback); +} + + +void +_PyErr_Clear(PyThreadState *tstate) +{ + _PyErr_Restore(tstate, NULL, NULL, NULL); +} + + +void +PyErr_Clear(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Clear(tstate); +} + + +void +PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + + _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); + *p_type = exc_info->exc_type; + *p_value = exc_info->exc_value; + *p_traceback = exc_info->exc_traceback; + + + Py_XINCREF(*p_type); + Py_XINCREF(*p_value); + Py_XINCREF(*p_traceback); +} + +void +PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) +{ + PyObject *oldtype, *oldvalue, *oldtraceback; + PyThreadState *tstate = _PyThreadState_GET(); + + oldtype = tstate->exc_info->exc_type; + oldvalue = tstate->exc_info->exc_value; + oldtraceback = tstate->exc_info->exc_traceback; + + tstate->exc_info->exc_type = p_type; + tstate->exc_info->exc_value = p_value; + tstate->exc_info->exc_traceback = p_traceback; + + Py_XDECREF(oldtype); + Py_XDECREF(oldvalue); + Py_XDECREF(oldtraceback); +} + +/* Like PyErr_Restore(), but if an exception is already set, + set the context associated with it. + */ +void +_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) +{ + if (exc == NULL) + return; + + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyErr_Occurred(tstate)) { + PyObject *exc2, *val2, *tb2; + _PyErr_Fetch(tstate, &exc2, &val2, &tb2); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } + Py_DECREF(exc); + _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); + PyException_SetContext(val2, val); + _PyErr_Restore(tstate, exc2, val2, tb2); + } + else { + _PyErr_Restore(tstate, exc, val, tb); + } +} + +static PyObject * +_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs) +{ + PyObject *exc, *val, *val2, *tb; + + assert(_PyErr_Occurred(tstate)); + _PyErr_Fetch(tstate, &exc, &val, &tb); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } + Py_DECREF(exc); + assert(!_PyErr_Occurred(tstate)); + + _PyErr_FormatV(tstate, exception, format, vargs); + + _PyErr_Fetch(tstate, &exc, &val2, &tb); + _PyErr_NormalizeException(tstate, &exc, &val2, &tb); + Py_INCREF(val); + PyException_SetCause(val2, val); + PyException_SetContext(val2, val); + _PyErr_Restore(tstate, exc, val2, tb); + + return NULL; +} + +PyObject * +_PyErr_FormatFromCause(PyObject *exception, const char *format, ...) +{ + PyThreadState *tstate = _PyThreadState_GET(); + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatVFromCause(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + +/* Convenience functions to set a type error exception and return 0 */ + +int +PyErr_BadArgument(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, PyExc_TypeError, + "bad argument type for built-in operation"); + return 0; +} + +PyObject * +PyErr_NoMemory(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (Py_TYPE(PyExc_MemoryError) == NULL) { + /* PyErr_NoMemory() has been called before PyExc_MemoryError has been + initialized by _PyExc_Init() */ + Py_FatalError("Out of memory and PyExc_MemoryError is not " + "initialized yet"); + } + _PyErr_SetNone(tstate, PyExc_MemoryError); + return NULL; +} + +PyObject * +PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) +{ + return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL); +} + +PyObject * +PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *message; + PyObject *v, *args; + int i = errno; +#ifdef MS_WINDOWS + WCHAR *s_buf = NULL; +#endif /* Unix/Windows */ + +#ifdef EINTR + if (i == EINTR && PyErr_CheckSignals()) + return NULL; +#endif + +#ifndef MS_WINDOWS + if (i != 0) { + const char *s = strerror(i); + message = PyUnicode_DecodeLocale(s, "surrogateescape"); + } + else { + /* Sometimes errno didn't get set */ + message = PyUnicode_FromString("Error"); + } +#else + if (i == 0) + message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */ + else + { + /* Note that the Win32 errors do not lineup with the + errno error. So if the error is in the MSVC error + table, we use it, otherwise we assume it really _is_ + a Win32 error code + */ + if (i > 0 && i < _sys_nerr) { + message = PyUnicode_FromString(_sys_errlist[i]); + } + else { + int len = FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, /* no message source */ + i, + MAKELANGID(LANG_NEUTRAL, + SUBLANG_DEFAULT), + /* Default language */ + (LPWSTR) &s_buf, + 0, /* size not used */ + NULL); /* no args */ + if (len==0) { + /* Only ever seen this in out-of-mem + situations */ + s_buf = NULL; + message = PyUnicode_FromFormat("Windows Error 0x%x", i); + } else { + /* remove trailing cr/lf and dots */ + while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.')) + s_buf[--len] = L'\0'; + message = PyUnicode_FromWideChar(s_buf, len); + } + } + } +#endif /* Unix/Windows */ + + if (message == NULL) + { +#ifdef MS_WINDOWS + LocalFree(s_buf); +#endif + return NULL; + } + + if (filenameObject != NULL) { + if (filenameObject2 != NULL) + args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2); + else + args = Py_BuildValue("(iOO)", i, message, filenameObject); + } else { + assert(filenameObject2 == NULL); + args = Py_BuildValue("(iO)", i, message); + } + Py_DECREF(message); + + if (args != NULL) { + v = PyObject_Call(exc, args, NULL); + Py_DECREF(args); + if (v != NULL) { + _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); + Py_DECREF(v); + } + } +#ifdef MS_WINDOWS + LocalFree(s_buf); +#endif + return NULL; +} + +PyObject * +PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) +{ + PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); + Py_XDECREF(name); + return result; +} + +#ifdef MS_WINDOWS +PyObject * +PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) +{ + PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL; + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); + Py_XDECREF(name); + return result; +} +#endif /* MS_WINDOWS */ + +PyObject * +PyErr_SetFromErrno(PyObject *exc) +{ + return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL); +} + +#ifdef MS_WINDOWS +/* Windows specific error code handling */ +PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *exc, + int ierr, + PyObject *filenameObject) +{ + return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, + filenameObject, NULL); +} + +PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyObject *exc, + int ierr, + PyObject *filenameObject, + PyObject *filenameObject2) +{ + PyThreadState *tstate = _PyThreadState_GET(); + int len; + WCHAR *s_buf = NULL; /* Free via LocalFree */ + PyObject *message; + PyObject *args, *v; + + DWORD err = (DWORD)ierr; + if (err==0) { + err = GetLastError(); + } + + len = FormatMessageW( + /* Error API error */ + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, /* no message source */ + err, + MAKELANGID(LANG_NEUTRAL, + SUBLANG_DEFAULT), /* Default language */ + (LPWSTR) &s_buf, + 0, /* size not used */ + NULL); /* no args */ + if (len==0) { + /* Only seen this in out of mem situations */ + message = PyUnicode_FromFormat("Windows Error 0x%x", err); + s_buf = NULL; + } else { + /* remove trailing cr/lf and dots */ + while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.')) + s_buf[--len] = L'\0'; + message = PyUnicode_FromWideChar(s_buf, len); + } + + if (message == NULL) + { + LocalFree(s_buf); + return NULL; + } + + if (filenameObject == NULL) { + assert(filenameObject2 == NULL); + filenameObject = filenameObject2 = Py_None; + } + else if (filenameObject2 == NULL) + filenameObject2 = Py_None; + /* This is the constructor signature for OSError. + The POSIX translation will be figured out by the constructor. */ + args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2); + Py_DECREF(message); + + if (args != NULL) { + v = PyObject_Call(exc, args, NULL); + Py_DECREF(args); + if (v != NULL) { + _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); + Py_DECREF(v); + } + } + LocalFree(s_buf); + return NULL; +} + +PyObject *PyErr_SetExcFromWindowsErrWithFilename( + PyObject *exc, + int ierr, + const char *filename) +{ + PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, + ierr, + name, + NULL); + Py_XDECREF(name); + return ret; +} + +PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename( + PyObject *exc, + int ierr, + const Py_UNICODE *filename) +{ + PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL; + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, + ierr, + name, + NULL); + Py_XDECREF(name); + return ret; +} + +PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr) +{ + return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL); +} + +PyObject *PyErr_SetFromWindowsErr(int ierr) +{ + return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError, + ierr, NULL); +} + +PyObject *PyErr_SetFromWindowsErrWithFilename( + int ierr, + const char *filename) +{ + PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyExc_OSError, + ierr, name, NULL); + Py_XDECREF(name); + return result; +} + +PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( + int ierr, + const Py_UNICODE *filename) +{ + PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL; + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyExc_OSError, + ierr, name, NULL); + Py_XDECREF(name); + return result; +} +#endif /* MS_WINDOWS */ + +PyObject * +PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, + PyObject *name, PyObject *path) +{ + PyThreadState *tstate = _PyThreadState_GET(); + int issubclass; + PyObject *kwargs, *error; + + issubclass = PyObject_IsSubclass(exception, PyExc_ImportError); + if (issubclass < 0) { + return NULL; + } + else if (!issubclass) { + _PyErr_SetString(tstate, PyExc_TypeError, + "expected a subclass of ImportError"); + return NULL; + } + + if (msg == NULL) { + _PyErr_SetString(tstate, PyExc_TypeError, + "expected a message argument"); + return NULL; + } + + if (name == NULL) { + name = Py_None; + } + if (path == NULL) { + path = Py_None; + } + + kwargs = PyDict_New(); + if (kwargs == NULL) { + return NULL; + } + if (PyDict_SetItemString(kwargs, "name", name) < 0) { + goto done; + } + if (PyDict_SetItemString(kwargs, "path", path) < 0) { + goto done; + } + + error = _PyObject_FastCallDict(exception, &msg, 1, kwargs); + if (error != NULL) { + _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error); + Py_DECREF(error); + } + +done: + Py_DECREF(kwargs); + return NULL; +} + +PyObject * +PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) +{ + return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path); +} + +void +_PyErr_BadInternalCall(const char *filename, int lineno) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Format(tstate, PyExc_SystemError, + "%s:%d: bad argument to internal function", + filename, lineno); +} + +/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can + export the entry point for existing object code: */ +#undef PyErr_BadInternalCall +void +PyErr_BadInternalCall(void) +{ + assert(0 && "bad argument to internal function"); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad argument to internal function"); +} +#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) + + +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs) +{ + PyObject* string; + + /* Issue #23571: PyUnicode_FromFormatV() must not be called with an + exception set, it calls arbitrary Python code like PyObject_Repr() */ + _PyErr_Clear(tstate); + + string = PyUnicode_FromFormatV(format, vargs); + + _PyErr_SetObject(tstate, exception, string); + Py_XDECREF(string); + return NULL; +} + + +PyObject * +PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_FormatV(tstate, exception, format, vargs); +} + + +PyObject * +_PyErr_Format(PyThreadState *tstate, PyObject *exception, + const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatV(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + + +PyObject * +PyErr_Format(PyObject *exception, const char *format, ...) +{ + PyThreadState *tstate = _PyThreadState_GET(); + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatV(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + + +PyObject * +PyErr_NewException(const char *name, PyObject *base, PyObject *dict) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _Py_IDENTIFIER(__module__); + PyObject *modulename = NULL; + PyObject *classname = NULL; + PyObject *mydict = NULL; + PyObject *bases = NULL; + PyObject *result = NULL; + + const char *dot = strrchr(name, '.'); + if (dot == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "PyErr_NewException: name must be module.class"); + return NULL; + } + if (base == NULL) { + base = PyExc_Exception; + } + if (dict == NULL) { + dict = mydict = PyDict_New(); + if (dict == NULL) + goto failure; + } + + if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) { + if (_PyErr_Occurred(tstate)) { + goto failure; + } + modulename = PyUnicode_FromStringAndSize(name, + (Py_ssize_t)(dot-name)); + if (modulename == NULL) + goto failure; + if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0) + goto failure; + } + if (PyTuple_Check(base)) { + bases = base; + /* INCREF as we create a new ref in the else branch */ + Py_INCREF(bases); + } else { + bases = PyTuple_Pack(1, base); + if (bases == NULL) + goto failure; + } + /* Create a real class. */ + result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO", + dot+1, bases, dict); + failure: + Py_XDECREF(bases); + Py_XDECREF(mydict); + Py_XDECREF(classname); + Py_XDECREF(modulename); + return result; +} + + +/* Create an exception with docstring */ +PyObject * +PyErr_NewExceptionWithDoc(const char *name, const char *doc, + PyObject *base, PyObject *dict) +{ + int result; + PyObject *ret = NULL; + PyObject *mydict = NULL; /* points to the dict only if we create it */ + PyObject *docobj; + + if (dict == NULL) { + dict = mydict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + } + + if (doc != NULL) { + docobj = PyUnicode_FromString(doc); + if (docobj == NULL) + goto failure; + result = PyDict_SetItemString(dict, "__doc__", docobj); + Py_DECREF(docobj); + if (result < 0) + goto failure; + } + + ret = PyErr_NewException(name, base, dict); + failure: + Py_XDECREF(mydict); + return ret; +} + + +PyDoc_STRVAR(UnraisableHookArgs__doc__, +"UnraisableHookArgs\n\ +\n\ +Type used to pass arguments to sys.unraisablehook."); + +static PyTypeObject UnraisableHookArgsType; + +static PyStructSequence_Field UnraisableHookArgs_fields[] = { + {"exc_type", "Exception type"}, + {"exc_value", "Exception value"}, + {"exc_traceback", "Exception traceback"}, + {"err_msg", "Error message"}, + {"object", "Object causing the exception"}, + {0} +}; + +static PyStructSequence_Desc UnraisableHookArgs_desc = { + .name = "UnraisableHookArgs", + .doc = UnraisableHookArgs__doc__, + .fields = UnraisableHookArgs_fields, + .n_in_sequence = 5 +}; + + +PyStatus +_PyErr_Init(void) +{ + if (UnraisableHookArgsType.tp_name == NULL) { + if (PyStructSequence_InitType2(&UnraisableHookArgsType, + &UnraisableHookArgs_desc) < 0) { + return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); + } + } + return _PyStatus_OK(); +} + + +static PyObject * +make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, + PyObject *err_msg, PyObject *obj) +{ + PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); + if (args == NULL) { + return NULL; + } + + Py_ssize_t pos = 0; +#define ADD_ITEM(exc_type) \ + do { \ + if (exc_type == NULL) { \ + exc_type = Py_None; \ + } \ + Py_INCREF(exc_type); \ + PyStructSequence_SET_ITEM(args, pos++, exc_type); \ + } while (0) + + + ADD_ITEM(exc_type); + ADD_ITEM(exc_value); + ADD_ITEM(exc_tb); + ADD_ITEM(err_msg); + ADD_ITEM(obj); +#undef ADD_ITEM + + if (_PyErr_Occurred(tstate)) { + Py_DECREF(args); + return NULL; + } + return args; +} + + + +/* Default implementation of sys.unraisablehook. + + It can be called to log the exception of a custom sys.unraisablehook. + + Do nothing if sys.stderr attribute doesn't exist or is set to None. */ +static int +write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, + PyObject *err_msg, PyObject *obj, PyObject *file) +{ + if (obj != NULL && obj != Py_None) { + if (err_msg != NULL && err_msg != Py_None) { + if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { + return -1; + } + if (PyFile_WriteString(": ", file) < 0) { + return -1; + } + } + else { + if (PyFile_WriteString("Exception ignored in: ", file) < 0) { + return -1; + } + } + + if (PyFile_WriteObject(obj, file, 0) < 0) { + _PyErr_Clear(tstate); + if (PyFile_WriteString("", file) < 0) { + return -1; + } + } + if (PyFile_WriteString("\n", file) < 0) { + return -1; + } + } + else if (err_msg != NULL && err_msg != Py_None) { + if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { + return -1; + } + if (PyFile_WriteString(":\n", file) < 0) { + return -1; + } + } + + if (exc_tb != NULL && exc_tb != Py_None) { + if (PyTraceBack_Print(exc_tb, file) < 0) { + /* continue even if writing the traceback failed */ + _PyErr_Clear(tstate); + } + } + + if (exc_type == NULL || exc_type == Py_None) { + return -1; + } + + assert(PyExceptionClass_Check(exc_type)); + const char *className = PyExceptionClass_Name(exc_type); + if (className != NULL) { + const char *dot = strrchr(className, '.'); + if (dot != NULL) { + className = dot+1; + } + } + + _Py_IDENTIFIER(__module__); + PyObject *moduleName = _PyObject_GetAttrId(exc_type, &PyId___module__); + if (moduleName == NULL || !PyUnicode_Check(moduleName)) { + Py_XDECREF(moduleName); + _PyErr_Clear(tstate); + if (PyFile_WriteString("", file) < 0) { + return -1; + } + } + else { + if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { + if (PyFile_WriteObject(moduleName, file, Py_PRINT_RAW) < 0) { + Py_DECREF(moduleName); + return -1; + } + Py_DECREF(moduleName); + if (PyFile_WriteString(".", file) < 0) { + return -1; + } + } + else { + Py_DECREF(moduleName); + } + } + if (className == NULL) { + if (PyFile_WriteString("", file) < 0) { + return -1; + } + } + else { + if (PyFile_WriteString(className, file) < 0) { + return -1; + } + } + + if (exc_value && exc_value != Py_None) { + if (PyFile_WriteString(": ", file) < 0) { + return -1; + } + if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) { + _PyErr_Clear(tstate); + if (PyFile_WriteString("", file) < 0) { + return -1; + } + } + } + + if (PyFile_WriteString("\n", file) < 0) { + return -1; + } + + /* Explicitly call file.flush() */ + PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + if (!res) { + return -1; + } + Py_DECREF(res); + + return 0; +} + + +static int +write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, + PyObject *obj) +{ + PyObject *file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL || file == Py_None) { + return 0; + } + + /* Hold a strong reference to ensure that sys.stderr doesn't go away + while we use it */ + Py_INCREF(file); + int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, + err_msg, obj, file); + Py_DECREF(file); + + return res; +} + + +PyObject* +_PyErr_WriteUnraisableDefaultHook(PyObject *args) +{ + PyThreadState *tstate = _PyThreadState_GET(); + + if (Py_TYPE(args) != &UnraisableHookArgsType) { + _PyErr_SetString(tstate, PyExc_TypeError, + "sys.unraisablehook argument type " + "must be UnraisableHookArgs"); + return NULL; + } + + /* Borrowed references */ + PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); + PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); + PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); + PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3); + PyObject *obj = PyStructSequence_GET_ITEM(args, 4); + + if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/* Call sys.unraisablehook(). + + This function can be used when an exception has occurred but there is no way + for Python to handle it. For example, when a destructor raises an exception + or during garbage collection (gc.collect()). + + If err_msg_str is non-NULL, the error message is formatted as: + "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in" + error message. + + An exception must be set when calling this function. */ +void +_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) +{ + PyThreadState *tstate = _PyThreadState_GET(); + assert(tstate != NULL); + + PyObject *err_msg = NULL; + PyObject *exc_type, *exc_value, *exc_tb; + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + + assert(exc_type != NULL); + + if (exc_type == NULL) { + /* sys.unraisablehook requires that at least exc_type is set */ + goto default_hook; + } + + if (exc_tb == NULL) { + struct _frame *frame = tstate->frame; + if (frame != NULL) { + exc_tb = _PyTraceBack_FromFrame(NULL, frame); + if (exc_tb == NULL) { + _PyErr_Clear(tstate); + } + } + } + + _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb); + + if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) { + if (PyException_SetTraceback(exc_value, exc_tb) < 0) { + _PyErr_Clear(tstate); + } + } + + if (err_msg_str != NULL) { + err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str); + if (err_msg == NULL) { + PyErr_Clear(); + } + } + + PyObject *hook_args = make_unraisable_hook_args( + tstate, exc_type, exc_value, exc_tb, err_msg, obj); + if (hook_args == NULL) { + err_msg_str = ("Exception ignored on building " + "sys.unraisablehook arguments"); + goto error; + } + + _Py_IDENTIFIER(unraisablehook); + PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); + if (hook == NULL) { + Py_DECREF(hook_args); + goto default_hook; + } + + if (PySys_Audit("sys.unraisablehook", "OO", hook, hook_args) < 0) { + Py_DECREF(hook_args); + err_msg_str = "Exception ignored in audit hook"; + obj = NULL; + goto error; + } + + if (hook == Py_None) { + Py_DECREF(hook_args); + goto default_hook; + } + + PyObject *args[1] = {hook_args}; + PyObject *res = _PyObject_FastCall(hook, args, 1); + Py_DECREF(hook_args); + if (res != NULL) { + Py_DECREF(res); + goto done; + } + + /* sys.unraisablehook failed: log its error using default hook */ + obj = hook; + err_msg_str = NULL; + +error: + /* err_msg_str and obj have been updated and we have a new exception */ + Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ? + err_msg_str : "Exception ignored in sys.unraisablehook")); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + +default_hook: + /* Call the default unraisable hook (ignore failure) */ + (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, + err_msg, obj); + +done: + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + Py_XDECREF(err_msg); + _PyErr_Clear(tstate); /* Just in case */ +} + + +void +PyErr_WriteUnraisable(PyObject *obj) +{ + _PyErr_WriteUnraisableMsg(NULL, obj); +} + + +extern PyObject *PyModule_GetWarningsModule(void); + + +void +PyErr_SyntaxLocation(const char *filename, int lineno) +{ + PyErr_SyntaxLocationEx(filename, lineno, -1); +} + + +/* Set file and line information for the current exception. + If the exception is not a SyntaxError, also sets additional attributes + to make printing of exceptions believe it is a syntax error. */ + +void +PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) +{ + PyObject *exc, *v, *tb, *tmp; + _Py_IDENTIFIER(filename); + _Py_IDENTIFIER(lineno); + _Py_IDENTIFIER(msg); + _Py_IDENTIFIER(offset); + _Py_IDENTIFIER(print_file_and_line); + _Py_IDENTIFIER(text); + PyThreadState *tstate = _PyThreadState_GET(); + + /* add attributes for the line number and filename for the error */ + _PyErr_Fetch(tstate, &exc, &v, &tb); + _PyErr_NormalizeException(tstate, &exc, &v, &tb); + /* XXX check that it is, indeed, a syntax error. It might not + * be, though. */ + tmp = PyLong_FromLong(lineno); + if (tmp == NULL) + _PyErr_Clear(tstate); + else { + if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) { + _PyErr_Clear(tstate); + } + Py_DECREF(tmp); + } + tmp = NULL; + if (col_offset >= 0) { + tmp = PyLong_FromLong(col_offset); + if (tmp == NULL) { + _PyErr_Clear(tstate); + } + } + if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) { + _PyErr_Clear(tstate); + } + Py_XDECREF(tmp); + if (filename != NULL) { + if (_PyObject_SetAttrId(v, &PyId_filename, filename)) { + _PyErr_Clear(tstate); + } + + tmp = PyErr_ProgramTextObject(filename, lineno); + if (tmp) { + if (_PyObject_SetAttrId(v, &PyId_text, tmp)) { + _PyErr_Clear(tstate); + } + Py_DECREF(tmp); + } + } + if (exc != PyExc_SyntaxError) { + if (!_PyObject_HasAttrId(v, &PyId_msg)) { + tmp = PyObject_Str(v); + if (tmp) { + if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { + _PyErr_Clear(tstate); + } + Py_DECREF(tmp); + } + else { + _PyErr_Clear(tstate); + } + } + if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) { + if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, + Py_None)) { + _PyErr_Clear(tstate); + } + } + } + _PyErr_Restore(tstate, exc, v, tb); +} + +void +PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *fileobj; + if (filename != NULL) { + fileobj = PyUnicode_DecodeFSDefault(filename); + if (fileobj == NULL) { + _PyErr_Clear(tstate); + } + } + else { + fileobj = NULL; + } + PyErr_SyntaxLocationObject(fileobj, lineno, col_offset); + Py_XDECREF(fileobj); +} + +/* Attempt to load the line of text that the exception refers to. If it + fails, it will return NULL but will not set an exception. + + XXX The functionality of this function is quite similar to the + functionality in tb_displayline() in traceback.c. */ + +static PyObject * +err_programtext(PyThreadState *tstate, FILE *fp, int lineno) +{ + int i; + char linebuf[1000]; + + if (fp == NULL) + return NULL; + for (i = 0; i < lineno; i++) { + char *pLastChar = &linebuf[sizeof(linebuf) - 2]; + do { + *pLastChar = '\0'; + if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, + fp, NULL) == NULL) + break; + /* fgets read *something*; if it didn't get as + far as pLastChar, it must have found a newline + or hit the end of the file; if pLastChar is \n, + it obviously found a newline; else we haven't + yet seen a newline, so must continue */ + } while (*pLastChar != '\0' && *pLastChar != '\n'); + } + fclose(fp); + if (i == lineno) { + PyObject *res; + res = PyUnicode_FromString(linebuf); + if (res == NULL) + _PyErr_Clear(tstate); + return res; + } + return NULL; +} + +PyObject * +PyErr_ProgramText(const char *filename, int lineno) +{ + FILE *fp; + if (filename == NULL || *filename == '\0' || lineno <= 0) { + return NULL; + } + PyThreadState *tstate = _PyThreadState_GET(); + fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE); + return err_programtext(tstate, fp, lineno); +} + +PyObject * +PyErr_ProgramTextObject(PyObject *filename, int lineno) +{ + if (filename == NULL || lineno <= 0) { + return NULL; + } + + PyThreadState *tstate = _PyThreadState_GET(); + FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); + if (fp == NULL) { + _PyErr_Clear(tstate); + return NULL; + } + return err_programtext(tstate, fp, lineno); +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Python/fileutils.c b/python/Python/fileutils.c new file mode 100755 index 0000000..3e1311c --- /dev/null +++ b/python/Python/fileutils.c @@ -0,0 +1,2052 @@ +#include "Python.h" +#include "pycore_fileutils.h" +#include "osdefs.h" +#include + +#ifdef MS_WINDOWS +# include +# include +extern int winerror_to_errno(int); +#endif + +#ifdef HAVE_LANGINFO_H +#include +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif /* HAVE_FCNTL_H */ + +#ifdef O_CLOEXEC +/* Does open() support the O_CLOEXEC flag? Possible values: + + -1: unknown + 0: open() ignores O_CLOEXEC flag, ex: Linux kernel older than 2.6.23 + 1: open() supports O_CLOEXEC flag, close-on-exec is set + + The flag is used by _Py_open(), _Py_open_noraise(), io.FileIO + and os.open(). */ +int _Py_open_cloexec_works = -1; +#endif + +// The value must be the same in unicodeobject.c. +#define MAX_UNICODE 0x10ffff + +// mbstowcs() and mbrtowc() errors +static const size_t DECODE_ERROR = ((size_t)-1); +static const size_t INCOMPLETE_CHARACTER = (size_t)-2; + + +static int +get_surrogateescape(_Py_error_handler errors, int *surrogateescape) +{ + switch (errors) + { + case _Py_ERROR_STRICT: + *surrogateescape = 0; + return 0; + case _Py_ERROR_SURROGATEESCAPE: + *surrogateescape = 1; + return 0; + default: + return -1; + } +} + + +PyObject * +_Py_device_encoding(int fd) +{ +#if defined(MS_WINDOWS) + UINT cp; +#endif + int valid; + _Py_BEGIN_SUPPRESS_IPH + valid = isatty(fd); + _Py_END_SUPPRESS_IPH + if (!valid) + Py_RETURN_NONE; + +#if defined(MS_WINDOWS) + if (fd == 0) + cp = GetConsoleCP(); + else if (fd == 1 || fd == 2) + cp = GetConsoleOutputCP(); + else + cp = 0; + /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application + has no console */ + if (cp != 0) + return PyUnicode_FromFormat("cp%u", (unsigned int)cp); +#elif defined(CODESET) + { + char *codeset = nl_langinfo(CODESET); + if (codeset != NULL && codeset[0] != 0) + return PyUnicode_FromString(codeset); + } +#endif + Py_RETURN_NONE; +} + + +static size_t +is_valid_wide_char(wchar_t ch) +{ + if (Py_UNICODE_IS_SURROGATE(ch)) { + // Reject lone surrogate characters + return 0; + } + if (ch > MAX_UNICODE) { + // bpo-35883: Reject characters outside [U+0000; U+10ffff] range. + // The glibc mbstowcs() UTF-8 decoder does not respect the RFC 3629, + // it creates characters outside the [U+0000; U+10ffff] range: + // https://sourceware.org/bugzilla/show_bug.cgi?id=2373 + return 0; + } + return 1; +} + + +static size_t +_Py_mbstowcs(wchar_t *dest, const char *src, size_t n) +{ + size_t count = mbstowcs(dest, src, n); + if (dest != NULL && count != DECODE_ERROR) { + for (size_t i=0; i < count; i++) { + wchar_t ch = dest[i]; + if (!is_valid_wide_char(ch)) { + return DECODE_ERROR; + } + } + } + return count; +} + + +#ifdef HAVE_MBRTOWC +static size_t +_Py_mbrtowc(wchar_t *pwc, const char *str, size_t len, mbstate_t *pmbs) +{ + assert(pwc != NULL); + size_t count = mbrtowc(pwc, str, len, pmbs); + if (count != 0 && count != DECODE_ERROR && count != INCOMPLETE_CHARACTER) { + if (!is_valid_wide_char(*pwc)) { + return DECODE_ERROR; + } + } + return count; +} +#endif + + +#if !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS) + +#define USE_FORCE_ASCII + +extern int _Py_normalize_encoding(const char *, char *, size_t); + +/* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale + and POSIX locale. nl_langinfo(CODESET) announces an alias of the + ASCII encoding, whereas mbstowcs() and wcstombs() functions use the + ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use + locale.getpreferredencoding() codec. For example, if command line arguments + are decoded by mbstowcs() and encoded back by os.fsencode(), we get a + UnicodeEncodeError instead of retrieving the original byte string. + + The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C", + nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least + one byte in range 0x80-0xff can be decoded from the locale encoding. The + workaround is also enabled on error, for example if getting the locale + failed. + + On HP-UX with the C locale or the POSIX locale, nl_langinfo(CODESET) + announces "roman8" but mbstowcs() uses Latin1 in practice. Force also the + ASCII encoding in this case. + + Values of force_ascii: + + 1: the workaround is used: Py_EncodeLocale() uses + encode_ascii_surrogateescape() and Py_DecodeLocale() uses + decode_ascii() + 0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and + Py_DecodeLocale() uses mbstowcs() + -1: unknown, need to call check_force_ascii() to get the value +*/ +static int force_ascii = -1; + +static int +check_force_ascii(void) +{ + char *loc = setlocale(LC_CTYPE, NULL); + if (loc == NULL) { + goto error; + } + if (strcmp(loc, "C") != 0 && strcmp(loc, "POSIX") != 0) { + /* the LC_CTYPE locale is different than C and POSIX */ + return 0; + } + +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + const char *codeset = nl_langinfo(CODESET); + if (!codeset || codeset[0] == '\0') { + /* CODESET is not set or empty */ + goto error; + } + + char encoding[20]; /* longest name: "iso_646.irv_1991\0" */ + if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding))) { + goto error; + } + +#ifdef __hpux + if (strcmp(encoding, "roman8") == 0) { + unsigned char ch; + wchar_t wch; + size_t res; + + ch = (unsigned char)0xA7; + res = _Py_mbstowcs(&wch, (char*)&ch, 1); + if (res != DECODE_ERROR && wch == L'\xA7') { + /* On HP-UX withe C locale or the POSIX locale, + nl_langinfo(CODESET) announces "roman8", whereas mbstowcs() uses + Latin1 encoding in practice. Force ASCII in this case. + + Roman8 decodes 0xA7 to U+00CF. Latin1 decodes 0xA7 to U+00A7. */ + return 1; + } + } +#else + const char* ascii_aliases[] = { + "ascii", + /* Aliases from Lib/encodings/aliases.py */ + "646", + "ansi_x3.4_1968", + "ansi_x3.4_1986", + "ansi_x3_4_1968", + "cp367", + "csascii", + "ibm367", + "iso646_us", + "iso_646.irv_1991", + "iso_ir_6", + "us", + "us_ascii", + NULL + }; + + int is_ascii = 0; + for (const char **alias=ascii_aliases; *alias != NULL; alias++) { + if (strcmp(encoding, *alias) == 0) { + is_ascii = 1; + break; + } + } + if (!is_ascii) { + /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */ + return 0; + } + + for (unsigned int i=0x80; i<=0xff; i++) { + char ch[1]; + wchar_t wch[1]; + size_t res; + + unsigned uch = (unsigned char)i; + ch[0] = (char)uch; + res = _Py_mbstowcs(wch, ch, 1); + if (res != DECODE_ERROR) { + /* decoding a non-ASCII character from the locale encoding succeed: + the locale encoding is not ASCII, force ASCII */ + return 1; + } + } + /* None of the bytes in the range 0x80-0xff can be decoded from the locale + encoding: the locale encoding is really ASCII */ +#endif /* !defined(__hpux) */ + return 0; +#else + /* nl_langinfo(CODESET) is not available: always force ASCII */ + return 1; +#endif /* defined(HAVE_LANGINFO_H) && defined(CODESET) */ + +error: + /* if an error occurred, force the ASCII encoding */ + return 1; +} + + +int +_Py_GetForceASCII(void) +{ + if (force_ascii == -1) { + force_ascii = check_force_ascii(); + } + return force_ascii; +} + + +void +_Py_ResetForceASCII(void) +{ + force_ascii = -1; +} + + +static int +encode_ascii(const wchar_t *text, char **str, + size_t *error_pos, const char **reason, + int raw_malloc, _Py_error_handler errors) +{ + char *result = NULL, *out; + size_t len, i; + wchar_t ch; + + int surrogateescape; + if (get_surrogateescape(errors, &surrogateescape) < 0) { + return -3; + } + + len = wcslen(text); + + /* +1 for NULL byte */ + if (raw_malloc) { + result = PyMem_RawMalloc(len + 1); + } + else { + result = PyMem_Malloc(len + 1); + } + if (result == NULL) { + return -1; + } + + out = result; + for (i=0; i PY_SSIZE_T_MAX / sizeof(wchar_t)) { + return -1; + } + res = PyMem_RawMalloc(argsize * sizeof(wchar_t)); + if (!res) { + return -1; + } + + out = res; + for (in = (unsigned char*)arg; *in; in++) { + unsigned char ch = *in; + if (ch < 128) { + *out++ = ch; + } + else { + if (!surrogateescape) { + PyMem_RawFree(res); + if (wlen) { + *wlen = in - (unsigned char*)arg; + } + if (reason) { + *reason = "decoding error"; + } + return -2; + } + *out++ = 0xdc00 + ch; + } + } + *out = 0; + + if (wlen != NULL) { + *wlen = out - res; + } + *wstr = res; + return 0; +} +#endif /* !HAVE_MBRTOWC */ + +static int +decode_current_locale(const char* arg, wchar_t **wstr, size_t *wlen, + const char **reason, _Py_error_handler errors) +{ + wchar_t *res; + size_t argsize; + size_t count; +#ifdef HAVE_MBRTOWC + unsigned char *in; + wchar_t *out; + mbstate_t mbs; +#endif + + int surrogateescape; + if (get_surrogateescape(errors, &surrogateescape) < 0) { + return -3; + } + +#ifdef HAVE_BROKEN_MBSTOWCS + /* Some platforms have a broken implementation of + * mbstowcs which does not count the characters that + * would result from conversion. Use an upper bound. + */ + argsize = strlen(arg); +#else + argsize = _Py_mbstowcs(NULL, arg, 0); +#endif + if (argsize != DECODE_ERROR) { + if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { + return -1; + } + res = (wchar_t *)PyMem_RawMalloc((argsize + 1) * sizeof(wchar_t)); + if (!res) { + return -1; + } + + count = _Py_mbstowcs(res, arg, argsize + 1); + if (count != DECODE_ERROR) { + *wstr = res; + if (wlen != NULL) { + *wlen = count; + } + return 0; + } + PyMem_RawFree(res); + } + + /* Conversion failed. Fall back to escaping with surrogateescape. */ +#ifdef HAVE_MBRTOWC + /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */ + + /* Overallocate; as multi-byte characters are in the argument, the + actual output could use less memory. */ + argsize = strlen(arg) + 1; + if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) { + return -1; + } + res = (wchar_t*)PyMem_RawMalloc(argsize * sizeof(wchar_t)); + if (!res) { + return -1; + } + + in = (unsigned char*)arg; + out = res; + memset(&mbs, 0, sizeof mbs); + while (argsize) { + size_t converted = _Py_mbrtowc(out, (char*)in, argsize, &mbs); + if (converted == 0) { + /* Reached end of string; null char stored. */ + break; + } + + if (converted == INCOMPLETE_CHARACTER) { + /* Incomplete character. This should never happen, + since we provide everything that we have - + unless there is a bug in the C library, or I + misunderstood how mbrtowc works. */ + goto decode_error; + } + + if (converted == DECODE_ERROR) { + if (!surrogateescape) { + goto decode_error; + } + + /* Decoding error. Escape as UTF-8b, and start over in the initial + shift state. */ + *out++ = 0xdc00 + *in++; + argsize--; + memset(&mbs, 0, sizeof mbs); + continue; + } + + // _Py_mbrtowc() reject lone surrogate characters + assert(!Py_UNICODE_IS_SURROGATE(*out)); + + /* successfully converted some bytes */ + in += converted; + argsize -= converted; + out++; + } + if (wlen != NULL) { + *wlen = out - res; + } + *wstr = res; + return 0; + +decode_error: + PyMem_RawFree(res); + if (wlen) { + *wlen = in - (unsigned char*)arg; + } + if (reason) { + *reason = "decoding error"; + } + return -2; +#else /* HAVE_MBRTOWC */ + /* Cannot use C locale for escaping; manually escape as if charset + is ASCII (i.e. escape all bytes > 128. This will still roundtrip + correctly in the locale's charset, which must be an ASCII superset. */ + return decode_ascii(arg, wstr, wlen, reason, errors); +#endif /* HAVE_MBRTOWC */ +} + + +/* Decode a byte string from the locale encoding. + + Use the strict error handler if 'surrogateescape' is zero. Use the + surrogateescape error handler if 'surrogateescape' is non-zero: undecodable + bytes are decoded as characters in range U+DC80..U+DCFF. If a byte sequence + can be decoded as a surrogate character, escape the bytes using the + surrogateescape error handler instead of decoding them. + + On success, return 0 and write the newly allocated wide character string into + *wstr (use PyMem_RawFree() to free the memory). If wlen is not NULL, write + the number of wide characters excluding the null character into *wlen. + + On memory allocation failure, return -1. + + On decoding error, return -2. If wlen is not NULL, write the start of + invalid byte sequence in the input string into *wlen. If reason is not NULL, + write the decoding error message into *reason. + + Return -3 if the error handler 'errors' is not supported. + + Use the Py_EncodeLocaleEx() function to encode the character string back to + a byte string. */ +int +_Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen, + const char **reason, + int current_locale, _Py_error_handler errors) +{ + if (current_locale) { +#ifdef _Py_FORCE_UTF8_LOCALE + return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, + errors); +#else + return decode_current_locale(arg, wstr, wlen, reason, errors); +#endif + } + +#ifdef _Py_FORCE_UTF8_FS_ENCODING + return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, + errors); +#else + int use_utf8 = (Py_UTF8Mode == 1); +#ifdef MS_WINDOWS + use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; +#endif + if (use_utf8) { + return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, + errors); + } + +#ifdef USE_FORCE_ASCII + if (force_ascii == -1) { + force_ascii = check_force_ascii(); + } + + if (force_ascii) { + /* force ASCII encoding to workaround mbstowcs() issue */ + return decode_ascii(arg, wstr, wlen, reason, errors); + } +#endif + + return decode_current_locale(arg, wstr, wlen, reason, errors); +#endif /* !_Py_FORCE_UTF8_FS_ENCODING */ +} + + +/* Decode a byte string from the locale encoding with the + surrogateescape error handler: undecodable bytes are decoded as characters + in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate + character, escape the bytes using the surrogateescape error handler instead + of decoding them. + + Return a pointer to a newly allocated wide character string, use + PyMem_RawFree() to free the memory. If size is not NULL, write the number of + wide characters excluding the null character into *size + + Return NULL on decoding error or memory allocation error. If *size* is not + NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on + decoding error. + + Decoding errors should never happen, unless there is a bug in the C + library. + + Use the Py_EncodeLocale() function to encode the character string back to a + byte string. */ +wchar_t* +Py_DecodeLocale(const char* arg, size_t *wlen) +{ + wchar_t *wstr; + int res = _Py_DecodeLocaleEx(arg, &wstr, wlen, + NULL, 0, + _Py_ERROR_SURROGATEESCAPE); + if (res != 0) { + assert(res != -3); + if (wlen != NULL) { + *wlen = (size_t)res; + } + return NULL; + } + return wstr; +} + + +static int +encode_current_locale(const wchar_t *text, char **str, + size_t *error_pos, const char **reason, + int raw_malloc, _Py_error_handler errors) +{ + const size_t len = wcslen(text); + char *result = NULL, *bytes = NULL; + size_t i, size, converted; + wchar_t c, buf[2]; + + int surrogateescape; + if (get_surrogateescape(errors, &surrogateescape) < 0) { + return -3; + } + + /* The function works in two steps: + 1. compute the length of the output buffer in bytes (size) + 2. outputs the bytes */ + size = 0; + buf[1] = 0; + while (1) { + for (i=0; i < len; i++) { + c = text[i]; + if (c >= 0xdc80 && c <= 0xdcff) { + if (!surrogateescape) { + goto encode_error; + } + /* UTF-8b surrogate */ + if (bytes != NULL) { + *bytes++ = c - 0xdc00; + size--; + } + else { + size++; + } + continue; + } + else { + buf[0] = c; + if (bytes != NULL) { + converted = wcstombs(bytes, buf, size); + } + else { + converted = wcstombs(NULL, buf, 0); + } + if (converted == DECODE_ERROR) { + goto encode_error; + } + if (bytes != NULL) { + bytes += converted; + size -= converted; + } + else { + size += converted; + } + } + } + if (result != NULL) { + *bytes = '\0'; + break; + } + + size += 1; /* nul byte at the end */ + if (raw_malloc) { + result = PyMem_RawMalloc(size); + } + else { + result = PyMem_Malloc(size); + } + if (result == NULL) { + return -1; + } + bytes = result; + } + *str = result; + return 0; + +encode_error: + if (raw_malloc) { + PyMem_RawFree(result); + } + else { + PyMem_Free(result); + } + if (error_pos != NULL) { + *error_pos = i; + } + if (reason) { + *reason = "encoding error"; + } + return -2; +} + + +/* Encode a string to the locale encoding. + + Parameters: + + * raw_malloc: if non-zero, allocate memory using PyMem_RawMalloc() instead + of PyMem_Malloc(). + * current_locale: if non-zero, use the current LC_CTYPE, otherwise use + Python filesystem encoding. + * errors: error handler like "strict" or "surrogateescape". + + Return value: + + 0: success, *str is set to a newly allocated decoded string. + -1: memory allocation failure + -2: encoding error, set *error_pos and *reason (if set). + -3: the error handler 'errors' is not supported. + */ +static int +encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos, + const char **reason, + int raw_malloc, int current_locale, _Py_error_handler errors) +{ + if (current_locale) { +#ifdef _Py_FORCE_UTF8_LOCALE + return _Py_EncodeUTF8Ex(text, str, error_pos, reason, + raw_malloc, errors); +#else + return encode_current_locale(text, str, error_pos, reason, + raw_malloc, errors); +#endif + } + +#ifdef _Py_FORCE_UTF8_FS_ENCODING + return _Py_EncodeUTF8Ex(text, str, error_pos, reason, + raw_malloc, errors); +#else + int use_utf8 = (Py_UTF8Mode == 1); +#ifdef MS_WINDOWS + use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; +#endif + if (use_utf8) { + return _Py_EncodeUTF8Ex(text, str, error_pos, reason, + raw_malloc, errors); + } + +#ifdef USE_FORCE_ASCII + if (force_ascii == -1) { + force_ascii = check_force_ascii(); + } + + if (force_ascii) { + return encode_ascii(text, str, error_pos, reason, + raw_malloc, errors); + } +#endif + + return encode_current_locale(text, str, error_pos, reason, + raw_malloc, errors); +#endif /* _Py_FORCE_UTF8_FS_ENCODING */ +} + +static char* +encode_locale(const wchar_t *text, size_t *error_pos, + int raw_malloc, int current_locale) +{ + char *str; + int res = encode_locale_ex(text, &str, error_pos, NULL, + raw_malloc, current_locale, + _Py_ERROR_SURROGATEESCAPE); + if (res != -2 && error_pos) { + *error_pos = (size_t)-1; + } + if (res != 0) { + return NULL; + } + return str; +} + +/* Encode a wide character string to the locale encoding with the + surrogateescape error handler: surrogate characters in the range + U+DC80..U+DCFF are converted to bytes 0x80..0xFF. + + Return a pointer to a newly allocated byte string, use PyMem_Free() to free + the memory. Return NULL on encoding or memory allocation error. + + If error_pos is not NULL, *error_pos is set to (size_t)-1 on success, or set + to the index of the invalid character on encoding error. + + Use the Py_DecodeLocale() function to decode the bytes string back to a wide + character string. */ +char* +Py_EncodeLocale(const wchar_t *text, size_t *error_pos) +{ + return encode_locale(text, error_pos, 0, 0); +} + + +/* Similar to Py_EncodeLocale(), but result must be freed by PyMem_RawFree() + instead of PyMem_Free(). */ +char* +_Py_EncodeLocaleRaw(const wchar_t *text, size_t *error_pos) +{ + return encode_locale(text, error_pos, 1, 0); +} + + +int +_Py_EncodeLocaleEx(const wchar_t *text, char **str, + size_t *error_pos, const char **reason, + int current_locale, _Py_error_handler errors) +{ + return encode_locale_ex(text, str, error_pos, reason, 1, + current_locale, errors); +} + + +#ifdef MS_WINDOWS +static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ + +static void +FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) +{ + /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ + /* Cannot simply cast and dereference in_ptr, + since it might not be aligned properly */ + __int64 in; + memcpy(&in, in_ptr, sizeof(in)); + *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ + *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); +} + +void +_Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) +{ + /* XXX endianness */ + __int64 out; + out = time_in + secs_between_epochs; + out = out * 10000000 + nsec_in / 100; + memcpy(out_ptr, &out, sizeof(out)); +} + +/* Below, we *know* that ugo+r is 0444 */ +#if _S_IREAD != 0400 +#error Unsupported C library +#endif +static int +attributes_to_mode(DWORD attr) +{ + int m = 0; + if (attr & FILE_ATTRIBUTE_DIRECTORY) + m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */ + else + m |= _S_IFREG; + if (attr & FILE_ATTRIBUTE_READONLY) + m |= 0444; + else + m |= 0666; + return m; +} + +void +_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, + struct _Py_stat_struct *result) +{ + memset(result, 0, sizeof(*result)); + result->st_mode = attributes_to_mode(info->dwFileAttributes); + result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; + result->st_dev = info->dwVolumeSerialNumber; + result->st_rdev = result->st_dev; + FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); + FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); + FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); + result->st_nlink = info->nNumberOfLinks; + result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; + /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will + open other name surrogate reparse points without traversing them. To + detect/handle these, check st_file_attributes and st_reparse_tag. */ + result->st_reparse_tag = reparse_tag; + if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && + reparse_tag == IO_REPARSE_TAG_SYMLINK) { + /* first clear the S_IFMT bits */ + result->st_mode ^= (result->st_mode & S_IFMT); + /* now set the bits that make this a symlink */ + result->st_mode |= S_IFLNK; + } + result->st_file_attributes = info->dwFileAttributes; +} +#endif + +/* Return information about a file. + + On POSIX, use fstat(). + + On Windows, use GetFileType() and GetFileInformationByHandle() which support + files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger + than 2 GiB because the file size type is a signed 32-bit integer: see issue + #23152. + + On Windows, set the last Windows error and return nonzero on error. On + POSIX, set errno and return nonzero on error. Fill status and return 0 on + success. */ +int +_Py_fstat_noraise(int fd, struct _Py_stat_struct *status) +{ +#ifdef MS_WINDOWS + BY_HANDLE_FILE_INFORMATION info; + HANDLE h; + int type; + + _Py_BEGIN_SUPPRESS_IPH + h = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + + if (h == INVALID_HANDLE_VALUE) { + /* errno is already set by _get_osfhandle, but we also set + the Win32 error for callers who expect that */ + SetLastError(ERROR_INVALID_HANDLE); + return -1; + } + memset(status, 0, sizeof(*status)); + + type = GetFileType(h); + if (type == FILE_TYPE_UNKNOWN) { + DWORD error = GetLastError(); + if (error != 0) { + errno = winerror_to_errno(error); + return -1; + } + /* else: valid but unknown file */ + } + + if (type != FILE_TYPE_DISK) { + if (type == FILE_TYPE_CHAR) + status->st_mode = _S_IFCHR; + else if (type == FILE_TYPE_PIPE) + status->st_mode = _S_IFIFO; + return 0; + } + + if (!GetFileInformationByHandle(h, &info)) { + /* The Win32 error is already set, but we also set errno for + callers who expect it */ + errno = winerror_to_errno(GetLastError()); + return -1; + } + + _Py_attribute_data_to_stat(&info, 0, status); + /* specific to fstat() */ + status->st_ino = (((uint64_t)info.nFileIndexHigh) << 32) + info.nFileIndexLow; + return 0; +#else + return fstat(fd, status); +#endif +} + +/* Return information about a file. + + On POSIX, use fstat(). + + On Windows, use GetFileType() and GetFileInformationByHandle() which support + files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger + than 2 GiB because the file size type is a signed 32-bit integer: see issue + #23152. + + Raise an exception and return -1 on error. On Windows, set the last Windows + error on error. On POSIX, set errno on error. Fill status and return 0 on + success. + + Release the GIL to call GetFileType() and GetFileInformationByHandle(), or + to call fstat(). The caller must hold the GIL. */ +int +_Py_fstat(int fd, struct _Py_stat_struct *status) +{ + int res; + + assert(PyGILState_Check()); + + Py_BEGIN_ALLOW_THREADS + res = _Py_fstat_noraise(fd, status); + Py_END_ALLOW_THREADS + + if (res != 0) { +#ifdef MS_WINDOWS + PyErr_SetFromWindowsErr(0); +#else + PyErr_SetFromErrno(PyExc_OSError); +#endif + return -1; + } + return 0; +} + +/* Call _wstat() on Windows, or encode the path to the filesystem encoding and + call stat() otherwise. Only fill st_mode attribute on Windows. + + Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was + raised. */ + +int +_Py_stat(PyObject *path, struct stat *statbuf) +{ +#ifdef MS_WINDOWS + int err; + struct _stat wstatbuf; + const wchar_t *wpath; + + wpath = _PyUnicode_AsUnicode(path); + if (wpath == NULL) + return -2; + + err = _wstat(wpath, &wstatbuf); + if (!err) + statbuf->st_mode = wstatbuf.st_mode; + return err; +#else + int ret; + PyObject *bytes; + char *cpath; + + bytes = PyUnicode_EncodeFSDefault(path); + if (bytes == NULL) + return -2; + + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) { + Py_DECREF(bytes); + return -2; + } + + ret = stat(cpath, statbuf); + Py_DECREF(bytes); + return ret; +#endif +} + + +/* This function MUST be kept async-signal-safe on POSIX when raise=0. */ +static int +get_inheritable(int fd, int raise) +{ +#ifdef MS_WINDOWS + HANDLE handle; + DWORD flags; + + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + if (handle == INVALID_HANDLE_VALUE) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + if (!GetHandleInformation(handle, &flags)) { + if (raise) + PyErr_SetFromWindowsErr(0); + return -1; + } + + return (flags & HANDLE_FLAG_INHERIT); +#else + int flags; + + flags = fcntl(fd, F_GETFD, 0); + if (flags == -1) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return !(flags & FD_CLOEXEC); +#endif +} + +/* Get the inheritable flag of the specified file descriptor. + Return 1 if the file descriptor can be inherited, 0 if it cannot, + raise an exception and return -1 on error. */ +int +_Py_get_inheritable(int fd) +{ + return get_inheritable(fd, 1); +} + + +/* This function MUST be kept async-signal-safe on POSIX when raise=0. */ +static int +set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) +{ +#ifdef MS_WINDOWS + HANDLE handle; + DWORD flags; +#else +#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) + static int ioctl_works = -1; + int request; + int err; +#endif + int flags, new_flags; + int res; +#endif + + /* atomic_flag_works can only be used to make the file descriptor + non-inheritable */ + assert(!(atomic_flag_works != NULL && inheritable)); + + if (atomic_flag_works != NULL && !inheritable) { + if (*atomic_flag_works == -1) { + int isInheritable = get_inheritable(fd, raise); + if (isInheritable == -1) + return -1; + *atomic_flag_works = !isInheritable; + } + + if (*atomic_flag_works) + return 0; + } + +#ifdef MS_WINDOWS + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + if (handle == INVALID_HANDLE_VALUE) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + if (inheritable) + flags = HANDLE_FLAG_INHERIT; + else + flags = 0; + + /* This check can be removed once support for Windows 7 ends. */ +#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \ + GetFileType(handle) == FILE_TYPE_CHAR) + + if (!CONSOLE_PSEUDOHANDLE(handle) && + !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) { + if (raise) + PyErr_SetFromWindowsErr(0); + return -1; + } +#undef CONSOLE_PSEUDOHANDLE + return 0; + +#else + +#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) + if (ioctl_works != 0 && raise != 0) { + /* fast-path: ioctl() only requires one syscall */ + /* caveat: raise=0 is an indicator that we must be async-signal-safe + * thus avoid using ioctl() so we skip the fast-path. */ + if (inheritable) + request = FIONCLEX; + else + request = FIOCLEX; + err = ioctl(fd, request, NULL); + if (!err) { + ioctl_works = 1; + return 0; + } + +#ifdef __linux__ + if (errno == EBADF) { + // On Linux, ioctl(FIOCLEX) will fail with EBADF for O_PATH file descriptors + // Fall through to the fcntl() path + } + else +#endif + if (errno != ENOTTY && errno != EACCES) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + else { + /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for + device". The ioctl is declared but not supported by the kernel. + Remember that ioctl() doesn't work. It is the case on + Illumos-based OS for example. + + Issue #27057: When SELinux policy disallows ioctl it will fail + with EACCES. While FIOCLEX is safe operation it may be + unavailable because ioctl was denied altogether. + This can be the case on Android. */ + ioctl_works = 0; + } + /* fallback to fcntl() if ioctl() does not work */ + } +#endif + + /* slow-path: fcntl() requires two syscalls */ + flags = fcntl(fd, F_GETFD); + if (flags < 0) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + if (inheritable) { + new_flags = flags & ~FD_CLOEXEC; + } + else { + new_flags = flags | FD_CLOEXEC; + } + + if (new_flags == flags) { + /* FD_CLOEXEC flag already set/cleared: nothing to do */ + return 0; + } + + res = fcntl(fd, F_SETFD, new_flags); + if (res < 0) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return 0; +#endif +} + +/* Make the file descriptor non-inheritable. + Return 0 on success, set errno and return -1 on error. */ +static int +make_non_inheritable(int fd) +{ + return set_inheritable(fd, 0, 0, NULL); +} + +/* Set the inheritable flag of the specified file descriptor. + On success: return 0, on error: raise an exception and return -1. + + If atomic_flag_works is not NULL: + + * if *atomic_flag_works==-1, check if the inheritable is set on the file + descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and + set the inheritable flag + * if *atomic_flag_works==1: do nothing + * if *atomic_flag_works==0: set inheritable flag to False + + Set atomic_flag_works to NULL if no atomic flag was used to create the + file descriptor. + + atomic_flag_works can only be used to make a file descriptor + non-inheritable: atomic_flag_works must be NULL if inheritable=1. */ +int +_Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works) +{ + return set_inheritable(fd, inheritable, 1, atomic_flag_works); +} + +/* Same as _Py_set_inheritable() but on error, set errno and + don't raise an exception. + This function is async-signal-safe. */ +int +_Py_set_inheritable_async_safe(int fd, int inheritable, int *atomic_flag_works) +{ + return set_inheritable(fd, inheritable, 0, atomic_flag_works); +} + +static int +_Py_open_impl(const char *pathname, int flags, int gil_held) +{ + int fd; + int async_err = 0; +#ifndef MS_WINDOWS + int *atomic_flag_works; +#endif + +#ifdef MS_WINDOWS + flags |= O_NOINHERIT; +#elif defined(O_CLOEXEC) + atomic_flag_works = &_Py_open_cloexec_works; + flags |= O_CLOEXEC; +#else + atomic_flag_works = NULL; +#endif + + if (gil_held) { + PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname); + if (pathname_obj == NULL) { + return -1; + } + if (PySys_Audit("open", "OOi", pathname_obj, Py_None, flags) < 0) { + Py_DECREF(pathname_obj); + return -1; + } + + do { + Py_BEGIN_ALLOW_THREADS + fd = open(pathname, flags); + Py_END_ALLOW_THREADS + } while (fd < 0 + && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (async_err) { + Py_DECREF(pathname_obj); + return -1; + } + if (fd < 0) { + PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, pathname_obj, NULL); + Py_DECREF(pathname_obj); + return -1; + } + Py_DECREF(pathname_obj); + } + else { + fd = open(pathname, flags); + if (fd < 0) + return -1; + } + +#ifndef MS_WINDOWS + if (set_inheritable(fd, 0, gil_held, atomic_flag_works) < 0) { + close(fd); + return -1; + } +#endif + + return fd; +} + +/* Open a file with the specified flags (wrapper to open() function). + Return a file descriptor on success. Raise an exception and return -1 on + error. + + The file descriptor is created non-inheritable. + + When interrupted by a signal (open() fails with EINTR), retry the syscall, + except if the Python signal handler raises an exception. + + Release the GIL to call open(). The caller must hold the GIL. */ +int +_Py_open(const char *pathname, int flags) +{ + /* _Py_open() must be called with the GIL held. */ + assert(PyGILState_Check()); + return _Py_open_impl(pathname, flags, 1); +} + +/* Open a file with the specified flags (wrapper to open() function). + Return a file descriptor on success. Set errno and return -1 on error. + + The file descriptor is created non-inheritable. + + If interrupted by a signal, fail with EINTR. */ +int +_Py_open_noraise(const char *pathname, int flags) +{ + return _Py_open_impl(pathname, flags, 0); +} + +/* Open a file. Use _wfopen() on Windows, encode the path to the locale + encoding and use fopen() otherwise. + + The file descriptor is created non-inheritable. + + If interrupted by a signal, fail with EINTR. */ +FILE * +_Py_wfopen(const wchar_t *path, const wchar_t *mode) +{ + FILE *f; + if (PySys_Audit("open", "uui", path, mode, 0) < 0) { + return NULL; + } +#ifndef MS_WINDOWS + char *cpath; + char cmode[10]; + size_t r; + r = wcstombs(cmode, mode, 10); + if (r == DECODE_ERROR || r >= 10) { + errno = EINVAL; + return NULL; + } + cpath = _Py_EncodeLocaleRaw(path, NULL); + if (cpath == NULL) { + return NULL; + } + f = fopen(cpath, cmode); + PyMem_RawFree(cpath); +#else + f = _wfopen(path, mode); +#endif + if (f == NULL) + return NULL; + if (make_non_inheritable(fileno(f)) < 0) { + fclose(f); + return NULL; + } + return f; +} + +/* Wrapper to fopen(). + + The file descriptor is created non-inheritable. + + If interrupted by a signal, fail with EINTR. */ +FILE* +_Py_fopen(const char *pathname, const char *mode) +{ + PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname); + if (pathname_obj == NULL) { + return NULL; + } + if (PySys_Audit("open", "Osi", pathname_obj, mode, 0) < 0) { + Py_DECREF(pathname_obj); + return NULL; + } + Py_DECREF(pathname_obj); + + FILE *f = fopen(pathname, mode); + if (f == NULL) + return NULL; + if (make_non_inheritable(fileno(f)) < 0) { + fclose(f); + return NULL; + } + return f; +} + +/* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem + encoding and call fopen() otherwise. + + Return the new file object on success. Raise an exception and return NULL + on error. + + The file descriptor is created non-inheritable. + + When interrupted by a signal (open() fails with EINTR), retry the syscall, + except if the Python signal handler raises an exception. + + Release the GIL to call _wfopen() or fopen(). The caller must hold + the GIL. */ +FILE* +_Py_fopen_obj(PyObject *path, const char *mode) +{ + FILE *f; + int async_err = 0; +#ifdef MS_WINDOWS + const wchar_t *wpath; + wchar_t wmode[10]; + int usize; + + assert(PyGILState_Check()); + + if (PySys_Audit("open", "Osi", path, mode, 0) < 0) { + return NULL; + } + if (!PyUnicode_Check(path)) { + PyErr_Format(PyExc_TypeError, + "str file path expected under Windows, got %R", + Py_TYPE(path)); + return NULL; + } + wpath = _PyUnicode_AsUnicode(path); + if (wpath == NULL) + return NULL; + + usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, + wmode, Py_ARRAY_LENGTH(wmode)); + if (usize == 0) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + + do { + Py_BEGIN_ALLOW_THREADS + f = _wfopen(wpath, wmode); + Py_END_ALLOW_THREADS + } while (f == NULL + && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#else + PyObject *bytes; + char *path_bytes; + + assert(PyGILState_Check()); + + if (!PyUnicode_FSConverter(path, &bytes)) + return NULL; + path_bytes = PyBytes_AS_STRING(bytes); + + if (PySys_Audit("open", "Osi", path, mode, 0) < 0) { + Py_DECREF(bytes); + return NULL; + } + + do { + Py_BEGIN_ALLOW_THREADS + f = fopen(path_bytes, mode); + Py_END_ALLOW_THREADS + } while (f == NULL + && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + Py_DECREF(bytes); +#endif + if (async_err) + return NULL; + + if (f == NULL) { + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); + return NULL; + } + + if (set_inheritable(fileno(f), 0, 1, NULL) < 0) { + fclose(f); + return NULL; + } + return f; +} + +/* Read count bytes from fd into buf. + + On success, return the number of read bytes, it can be lower than count. + If the current file offset is at or past the end of file, no bytes are read, + and read() returns zero. + + On error, raise an exception, set errno and return -1. + + When interrupted by a signal (read() fails with EINTR), retry the syscall. + If the Python signal handler raises an exception, the function returns -1 + (the syscall is not retried). + + Release the GIL to call read(). The caller must hold the GIL. */ +Py_ssize_t +_Py_read(int fd, void *buf, size_t count) +{ + Py_ssize_t n; + int err; + int async_err = 0; + + assert(PyGILState_Check()); + + /* _Py_read() must not be called with an exception set, otherwise the + * caller may think that read() was interrupted by a signal and the signal + * handler raised an exception. */ + assert(!PyErr_Occurred()); + + if (count > _PY_READ_MAX) { + count = _PY_READ_MAX; + } + + _Py_BEGIN_SUPPRESS_IPH + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; +#ifdef MS_WINDOWS + n = read(fd, buf, (int)count); +#else + n = read(fd, buf, count); +#endif + /* save/restore errno because PyErr_CheckSignals() + * and PyErr_SetFromErrno() can modify it */ + err = errno; + Py_END_ALLOW_THREADS + } while (n < 0 && err == EINTR && + !(async_err = PyErr_CheckSignals())); + _Py_END_SUPPRESS_IPH + + if (async_err) { + /* read() was interrupted by a signal (failed with EINTR) + * and the Python signal handler raised an exception */ + errno = err; + assert(errno == EINTR && PyErr_Occurred()); + return -1; + } + if (n < 0) { + PyErr_SetFromErrno(PyExc_OSError); + errno = err; + return -1; + } + + return n; +} + +static Py_ssize_t +_Py_write_impl(int fd, const void *buf, size_t count, int gil_held) +{ + Py_ssize_t n; + int err; + int async_err = 0; + + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + if (count > 32767 && isatty(fd)) { + /* Issue #11395: the Windows console returns an error (12: not + enough space error) on writing into stdout if stdout mode is + binary and the length is greater than 66,000 bytes (or less, + depending on heap usage). */ + count = 32767; + } +#endif + if (count > _PY_WRITE_MAX) { + count = _PY_WRITE_MAX; + } + + if (gil_held) { + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; +#ifdef MS_WINDOWS + n = write(fd, buf, (int)count); +#else + n = write(fd, buf, count); +#endif + /* save/restore errno because PyErr_CheckSignals() + * and PyErr_SetFromErrno() can modify it */ + err = errno; + Py_END_ALLOW_THREADS + } while (n < 0 && err == EINTR && + !(async_err = PyErr_CheckSignals())); + } + else { + do { + errno = 0; +#ifdef MS_WINDOWS + n = write(fd, buf, (int)count); +#else + n = write(fd, buf, count); +#endif + err = errno; + } while (n < 0 && err == EINTR); + } + _Py_END_SUPPRESS_IPH + + if (async_err) { + /* write() was interrupted by a signal (failed with EINTR) + and the Python signal handler raised an exception (if gil_held is + nonzero). */ + errno = err; + assert(errno == EINTR && (!gil_held || PyErr_Occurred())); + return -1; + } + if (n < 0) { + if (gil_held) + PyErr_SetFromErrno(PyExc_OSError); + errno = err; + return -1; + } + + return n; +} + +/* Write count bytes of buf into fd. + + On success, return the number of written bytes, it can be lower than count + including 0. On error, raise an exception, set errno and return -1. + + When interrupted by a signal (write() fails with EINTR), retry the syscall. + If the Python signal handler raises an exception, the function returns -1 + (the syscall is not retried). + + Release the GIL to call write(). The caller must hold the GIL. */ +Py_ssize_t +_Py_write(int fd, const void *buf, size_t count) +{ + assert(PyGILState_Check()); + + /* _Py_write() must not be called with an exception set, otherwise the + * caller may think that write() was interrupted by a signal and the signal + * handler raised an exception. */ + assert(!PyErr_Occurred()); + + return _Py_write_impl(fd, buf, count, 1); +} + +/* Write count bytes of buf into fd. + * + * On success, return the number of written bytes, it can be lower than count + * including 0. On error, set errno and return -1. + * + * When interrupted by a signal (write() fails with EINTR), retry the syscall + * without calling the Python signal handler. */ +Py_ssize_t +_Py_write_noraise(int fd, const void *buf, size_t count) +{ + return _Py_write_impl(fd, buf, count, 0); +} + +#ifdef HAVE_READLINK + +/* Read value of symbolic link. Encode the path to the locale encoding, decode + the result from the locale encoding. + + Return -1 on encoding error, on readlink() error, if the internal buffer is + too short, on decoding error, or if 'buf' is too short. */ +int +_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t buflen) +{ + char *cpath; + char cbuf[MAXPATHLEN]; + wchar_t *wbuf; + int res; + size_t r1; + + cpath = _Py_EncodeLocaleRaw(path, NULL); + if (cpath == NULL) { + errno = EINVAL; + return -1; + } + res = (int)readlink(cpath, cbuf, Py_ARRAY_LENGTH(cbuf)); + PyMem_RawFree(cpath); + if (res == -1) + return -1; + if (res == Py_ARRAY_LENGTH(cbuf)) { + errno = EINVAL; + return -1; + } + cbuf[res] = '\0'; /* buf will be null terminated */ + wbuf = Py_DecodeLocale(cbuf, &r1); + if (wbuf == NULL) { + errno = EINVAL; + return -1; + } + /* wbuf must have space to store the trailing NUL character */ + if (buflen <= r1) { + PyMem_RawFree(wbuf); + errno = EINVAL; + return -1; + } + wcsncpy(buf, wbuf, buflen); + PyMem_RawFree(wbuf); + return (int)r1; +} +#endif + +#ifdef HAVE_REALPATH + +/* Return the canonicalized absolute pathname. Encode path to the locale + encoding, decode the result from the locale encoding. + + Return NULL on encoding error, realpath() error, decoding error + or if 'resolved_path' is too short. */ +wchar_t* +_Py_wrealpath(const wchar_t *path, + wchar_t *resolved_path, size_t resolved_path_len) +{ + char *cpath; + char cresolved_path[MAXPATHLEN]; + wchar_t *wresolved_path; + char *res; + size_t r; + cpath = _Py_EncodeLocaleRaw(path, NULL); + if (cpath == NULL) { + errno = EINVAL; + return NULL; + } + res = realpath(cpath, cresolved_path); + PyMem_RawFree(cpath); + if (res == NULL) + return NULL; + + wresolved_path = Py_DecodeLocale(cresolved_path, &r); + if (wresolved_path == NULL) { + errno = EINVAL; + return NULL; + } + /* wresolved_path must have space to store the trailing NUL character */ + if (resolved_path_len <= r) { + PyMem_RawFree(wresolved_path); + errno = EINVAL; + return NULL; + } + wcsncpy(resolved_path, wresolved_path, resolved_path_len); + PyMem_RawFree(wresolved_path); + return resolved_path; +} +#endif + +/* Get the current directory. buflen is the buffer size in wide characters + including the null character. Decode the path from the locale encoding. + + Return NULL on getcwd() error, on decoding error, or if 'buf' is + too short. */ +wchar_t* +_Py_wgetcwd(wchar_t *buf, size_t buflen) +{ +#ifdef MS_WINDOWS + int ibuflen = (int)Py_MIN(buflen, INT_MAX); + return _wgetcwd(buf, ibuflen); +#else + char fname[MAXPATHLEN]; + wchar_t *wname; + size_t len; + + if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL) + return NULL; + wname = Py_DecodeLocale(fname, &len); + if (wname == NULL) + return NULL; + /* wname must have space to store the trailing NUL character */ + if (buflen <= len) { + PyMem_RawFree(wname); + return NULL; + } + wcsncpy(buf, wname, buflen); + PyMem_RawFree(wname); + return buf; +#endif +} + +/* Duplicate a file descriptor. The new file descriptor is created as + non-inheritable. Return a new file descriptor on success, raise an OSError + exception and return -1 on error. + + The GIL is released to call dup(). The caller must hold the GIL. */ +int +_Py_dup(int fd) +{ +#ifdef MS_WINDOWS + HANDLE handle; +#endif + + assert(PyGILState_Check()); + +#ifdef MS_WINDOWS + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + if (handle == INVALID_HANDLE_VALUE) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + fd = dup(fd); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (fd < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + if (_Py_set_inheritable(fd, 0, NULL) < 0) { + _Py_BEGIN_SUPPRESS_IPH + close(fd); + _Py_END_SUPPRESS_IPH + return -1; + } +#elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC) + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (fd < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + +#else + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + fd = dup(fd); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (fd < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + if (_Py_set_inheritable(fd, 0, NULL) < 0) { + _Py_BEGIN_SUPPRESS_IPH + close(fd); + _Py_END_SUPPRESS_IPH + return -1; + } +#endif + return fd; +} + +#ifndef MS_WINDOWS +/* Get the blocking mode of the file descriptor. + Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared, + raise an exception and return -1 on error. */ +int +_Py_get_blocking(int fd) +{ + int flags; + _Py_BEGIN_SUPPRESS_IPH + flags = fcntl(fd, F_GETFL, 0); + _Py_END_SUPPRESS_IPH + if (flags < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + return !(flags & O_NONBLOCK); +} + +/* Set the blocking mode of the specified file descriptor. + + Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag + otherwise. + + Return 0 on success, raise an exception and return -1 on error. */ +int +_Py_set_blocking(int fd, int blocking) +{ +#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO) + int arg = !blocking; + if (ioctl(fd, FIONBIO, &arg) < 0) + goto error; +#else + int flags, res; + + _Py_BEGIN_SUPPRESS_IPH + flags = fcntl(fd, F_GETFL, 0); + if (flags >= 0) { + if (blocking) + flags = flags & (~O_NONBLOCK); + else + flags = flags | O_NONBLOCK; + + res = fcntl(fd, F_SETFL, flags); + } else { + res = -1; + } + _Py_END_SUPPRESS_IPH + + if (res < 0) + goto error; +#endif + return 0; + +error: + PyErr_SetFromErrno(PyExc_OSError); + return -1; +} +#endif + + +int +_Py_GetLocaleconvNumeric(struct lconv *lc, + PyObject **decimal_point, PyObject **thousands_sep) +{ + assert(decimal_point != NULL); + assert(thousands_sep != NULL); + +#ifndef MS_WINDOWS + int change_locale = 0; + if ((strlen(lc->decimal_point) > 1 || ((unsigned char)lc->decimal_point[0]) > 127)) { + change_locale = 1; + } + if ((strlen(lc->thousands_sep) > 1 || ((unsigned char)lc->thousands_sep[0]) > 127)) { + change_locale = 1; + } + + /* 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_NUMERIC, NULL); + if (loc != NULL && strcmp(loc, oldloc) == 0) { + loc = NULL; + } + + if (loc != NULL) { + /* Only set the locale temporarily the LC_CTYPE locale + if LC_NUMERIC locale is different than LC_CTYPE locale and + decimal_point and/or thousands_sep are non-ASCII or longer than + 1 byte */ + setlocale(LC_CTYPE, loc); + } + } + +#define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) +#else /* MS_WINDOWS */ +/* Use _W_* fields of Windows strcut lconv */ +#define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) +#endif /* MS_WINDOWS */ + + int res = -1; + + *decimal_point = GET_LOCALE_STRING(decimal_point); + if (*decimal_point == NULL) { + goto done; + } + + *thousands_sep = GET_LOCALE_STRING(thousands_sep); + if (*thousands_sep == NULL) { + goto done; + } + + res = 0; + +done: +#ifndef MS_WINDOWS + if (loc != NULL) { + setlocale(LC_CTYPE, oldloc); + } + PyMem_Free(oldloc); +#endif + return res; + +#undef GET_LOCALE_STRING +} diff --git a/python/Python/formatter_unicode.c b/python/Python/formatter_unicode.c new file mode 100755 index 0000000..7c4ecf0 --- /dev/null +++ b/python/Python/formatter_unicode.c @@ -0,0 +1,1593 @@ +/* implements the unicode (as opposed to string) version of the + built-in formatters for string, int, float. that is, the versions + of int.__float__, etc., that take and return unicode objects */ + +#include "Python.h" +#include "pycore_fileutils.h" +#include + +/* Raises an exception about an unknown presentation type for this + * type. */ + +static void +unknown_presentation_type(Py_UCS4 presentation_type, + const char* type_name) +{ + /* %c might be out-of-range, hence the two cases. */ + if (presentation_type > 32 && presentation_type < 128) + PyErr_Format(PyExc_ValueError, + "Unknown format code '%c' " + "for object of type '%.200s'", + (char)presentation_type, + type_name); + else + PyErr_Format(PyExc_ValueError, + "Unknown format code '\\x%x' " + "for object of type '%.200s'", + (unsigned int)presentation_type, + type_name); +} + +static void +invalid_thousands_separator_type(char specifier, Py_UCS4 presentation_type) +{ + assert(specifier == ',' || specifier == '_'); + if (presentation_type > 32 && presentation_type < 128) + PyErr_Format(PyExc_ValueError, + "Cannot specify '%c' with '%c'.", + specifier, (char)presentation_type); + else + PyErr_Format(PyExc_ValueError, + "Cannot specify '%c' with '\\x%x'.", + specifier, (unsigned int)presentation_type); +} + +static void +invalid_comma_and_underscore(void) +{ + PyErr_Format(PyExc_ValueError, "Cannot specify both ',' and '_'."); +} + +/* + get_integer consumes 0 or more decimal digit characters from an + input string, updates *result with the corresponding positive + integer, and returns the number of digits consumed. + + returns -1 on error. +*/ +static int +get_integer(PyObject *str, Py_ssize_t *ppos, Py_ssize_t end, + Py_ssize_t *result) +{ + Py_ssize_t accumulator, digitval, pos = *ppos; + int numdigits; + int kind = PyUnicode_KIND(str); + void *data = PyUnicode_DATA(str); + + accumulator = numdigits = 0; + for (; pos < end; pos++, numdigits++) { + digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ(kind, data, pos)); + if (digitval < 0) + break; + /* + Detect possible overflow before it happens: + + accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if + accumulator > (PY_SSIZE_T_MAX - digitval) / 10. + */ + if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) { + PyErr_Format(PyExc_ValueError, + "Too many decimal digits in format string"); + *ppos = pos; + return -1; + } + accumulator = accumulator * 10 + digitval; + } + *ppos = pos; + *result = accumulator; + return numdigits; +} + +/************************************************************************/ +/*********** standard format specifier parsing **************************/ +/************************************************************************/ + +/* returns true if this character is a specifier alignment token */ +Py_LOCAL_INLINE(int) +is_alignment_token(Py_UCS4 c) +{ + switch (c) { + case '<': case '>': case '=': case '^': + return 1; + default: + return 0; + } +} + +/* returns true if this character is a sign element */ +Py_LOCAL_INLINE(int) +is_sign_element(Py_UCS4 c) +{ + switch (c) { + case ' ': case '+': case '-': + return 1; + default: + return 0; + } +} + +/* Locale type codes. LT_NO_LOCALE must be zero. */ +enum LocaleType { + LT_NO_LOCALE = 0, + LT_DEFAULT_LOCALE = ',', + LT_UNDERSCORE_LOCALE = '_', + LT_UNDER_FOUR_LOCALE, + LT_CURRENT_LOCALE +}; + +typedef struct { + Py_UCS4 fill_char; + Py_UCS4 align; + int alternate; + Py_UCS4 sign; + Py_ssize_t width; + enum LocaleType thousands_separators; + Py_ssize_t precision; + Py_UCS4 type; +} InternalFormatSpec; + +#if 0 +/* Occasionally useful for debugging. Should normally be commented out. */ +static void +DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) +{ + printf("internal format spec: fill_char %d\n", format->fill_char); + printf("internal format spec: align %d\n", format->align); + printf("internal format spec: alternate %d\n", format->alternate); + printf("internal format spec: sign %d\n", format->sign); + printf("internal format spec: width %zd\n", format->width); + printf("internal format spec: thousands_separators %d\n", + format->thousands_separators); + printf("internal format spec: precision %zd\n", format->precision); + printf("internal format spec: type %c\n", format->type); + printf("\n"); +} +#endif + + +/* + ptr points to the start of the format_spec, end points just past its end. + fills in format with the parsed information. + returns 1 on success, 0 on failure. + if failure, sets the exception +*/ +static int +parse_internal_render_format_spec(PyObject *format_spec, + Py_ssize_t start, Py_ssize_t end, + InternalFormatSpec *format, + char default_type, + char default_align) +{ + Py_ssize_t pos = start; + int kind = PyUnicode_KIND(format_spec); + void *data = PyUnicode_DATA(format_spec); + /* end-pos is used throughout this code to specify the length of + the input string */ +#define READ_spec(index) PyUnicode_READ(kind, data, index) + + Py_ssize_t consumed; + int align_specified = 0; + int fill_char_specified = 0; + + format->fill_char = ' '; + format->align = default_align; + format->alternate = 0; + format->sign = '\0'; + format->width = -1; + format->thousands_separators = LT_NO_LOCALE; + format->precision = -1; + format->type = default_type; + + /* If the second char is an alignment token, + then parse the fill char */ + if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) { + format->align = READ_spec(pos+1); + format->fill_char = READ_spec(pos); + fill_char_specified = 1; + align_specified = 1; + pos += 2; + } + else if (end-pos >= 1 && is_alignment_token(READ_spec(pos))) { + format->align = READ_spec(pos); + align_specified = 1; + ++pos; + } + + /* Parse the various sign options */ + if (end-pos >= 1 && is_sign_element(READ_spec(pos))) { + format->sign = READ_spec(pos); + ++pos; + } + + /* If the next character is #, we're in alternate mode. This only + applies to integers. */ + if (end-pos >= 1 && READ_spec(pos) == '#') { + format->alternate = 1; + ++pos; + } + + /* The special case for 0-padding (backwards compat) */ + if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') { + format->fill_char = '0'; + if (!align_specified) { + format->align = '='; + } + ++pos; + } + + consumed = get_integer(format_spec, &pos, end, &format->width); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; + + /* If consumed is 0, we didn't consume any characters for the + width. In that case, reset the width to -1, because + get_integer() will have set it to zero. -1 is how we record + that the width wasn't specified. */ + if (consumed == 0) + format->width = -1; + + /* Comma signifies add thousands separators */ + if (end-pos && READ_spec(pos) == ',') { + format->thousands_separators = LT_DEFAULT_LOCALE; + ++pos; + } + /* Underscore signifies add thousands separators */ + if (end-pos && READ_spec(pos) == '_') { + if (format->thousands_separators != LT_NO_LOCALE) { + invalid_comma_and_underscore(); + return 0; + } + format->thousands_separators = LT_UNDERSCORE_LOCALE; + ++pos; + } + if (end-pos && READ_spec(pos) == ',') { + invalid_comma_and_underscore(); + return 0; + } + + /* Parse field precision */ + if (end-pos && READ_spec(pos) == '.') { + ++pos; + + consumed = get_integer(format_spec, &pos, end, &format->precision); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; + + /* Not having a precision after a dot is an error. */ + if (consumed == 0) { + PyErr_Format(PyExc_ValueError, + "Format specifier missing precision"); + return 0; + } + + } + + /* Finally, parse the type field. */ + + if (end-pos > 1) { + /* More than one char remain, invalid format specifier. */ + PyErr_Format(PyExc_ValueError, "Invalid format specifier"); + return 0; + } + + if (end-pos == 1) { + format->type = READ_spec(pos); + ++pos; + } + + /* Do as much validating as we can, just by looking at the format + specifier. Do not take into account what type of formatting + we're doing (int, float, string). */ + + if (format->thousands_separators) { + switch (format->type) { + case 'd': + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + case '%': + case 'F': + case '\0': + /* These are allowed. See PEP 378.*/ + break; + case 'b': + case 'o': + case 'x': + case 'X': + /* Underscores are allowed in bin/oct/hex. See PEP 515. */ + if (format->thousands_separators == LT_UNDERSCORE_LOCALE) { + /* Every four digits, not every three, in bin/oct/hex. */ + format->thousands_separators = LT_UNDER_FOUR_LOCALE; + break; + } + /* fall through */ + default: + invalid_thousands_separator_type(format->thousands_separators, format->type); + return 0; + } + } + + assert (format->align <= 127); + assert (format->sign <= 127); + return 1; +} + +/* Calculate the padding needed. */ +static void +calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align, + Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding, + Py_ssize_t *n_total) +{ + if (width >= 0) { + if (nchars > width) + *n_total = nchars; + else + *n_total = width; + } + else { + /* not specified, use all of the chars and no more */ + *n_total = nchars; + } + + /* Figure out how much leading space we need, based on the + aligning */ + if (align == '>') + *n_lpadding = *n_total - nchars; + else if (align == '^') + *n_lpadding = (*n_total - nchars) / 2; + else if (align == '<' || align == '=') + *n_lpadding = 0; + else { + /* We should never have an unspecified alignment. */ + Py_UNREACHABLE(); + } + + *n_rpadding = *n_total - nchars - *n_lpadding; +} + +/* Do the padding, and return a pointer to where the caller-supplied + content goes. */ +static int +fill_padding(_PyUnicodeWriter *writer, + Py_ssize_t nchars, + Py_UCS4 fill_char, Py_ssize_t n_lpadding, + Py_ssize_t n_rpadding) +{ + Py_ssize_t pos; + + /* Pad on left. */ + if (n_lpadding) { + pos = writer->pos; + _PyUnicode_FastFill(writer->buffer, pos, n_lpadding, fill_char); + } + + /* Pad on right. */ + if (n_rpadding) { + pos = writer->pos + nchars + n_lpadding; + _PyUnicode_FastFill(writer->buffer, pos, n_rpadding, fill_char); + } + + /* Pointer to the user content. */ + writer->pos += n_lpadding; + return 0; +} + +/************************************************************************/ +/*********** common routines for numeric formatting *********************/ +/************************************************************************/ + +/* Locale info needed for formatting integers and the part of floats + before and including the decimal. Note that locales only support + 8-bit chars, not unicode. */ +typedef struct { + PyObject *decimal_point; + PyObject *thousands_sep; + const char *grouping; + char *grouping_buffer; +} LocaleInfo; + +#define LocaleInfo_STATIC_INIT {0, 0, 0, 0} + +/* describes the layout for an integer, see the comment in + calc_number_widths() for details */ +typedef struct { + Py_ssize_t n_lpadding; + Py_ssize_t n_prefix; + Py_ssize_t n_spadding; + Py_ssize_t n_rpadding; + char sign; + Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */ + Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including + any grouping chars. */ + Py_ssize_t n_decimal; /* 0 if only an integer */ + Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part, + excluding the decimal itself, if + present. */ + + /* These 2 are not the widths of fields, but are needed by + STRINGLIB_GROUPING. */ + Py_ssize_t n_digits; /* The number of digits before a decimal + or exponent. */ + Py_ssize_t n_min_width; /* The min_width we used when we computed + the n_grouped_digits width. */ +} NumberFieldWidths; + + +/* Given a number of the form: + digits[remainder] + where ptr points to the start and end points to the end, find where + the integer part ends. This could be a decimal, an exponent, both, + or neither. + If a decimal point is present, set *has_decimal and increment + remainder beyond it. + Results are undefined (but shouldn't crash) for improperly + formatted strings. +*/ +static void +parse_number(PyObject *s, Py_ssize_t pos, Py_ssize_t end, + Py_ssize_t *n_remainder, int *has_decimal) +{ + Py_ssize_t remainder; + int kind = PyUnicode_KIND(s); + void *data = PyUnicode_DATA(s); + + while (posn_digits = n_end - n_start - n_remainder - (has_decimal?1:0); + spec->n_lpadding = 0; + spec->n_prefix = n_prefix; + spec->n_decimal = has_decimal ? PyUnicode_GET_LENGTH(locale->decimal_point) : 0; + spec->n_remainder = n_remainder; + spec->n_spadding = 0; + spec->n_rpadding = 0; + spec->sign = '\0'; + spec->n_sign = 0; + + /* the output will look like: + | | + | | + | | + + sign is computed from format->sign and the actual + sign of the number + + prefix is given (it's for the '0x' prefix) + + digits is already known + + the total width is either given, or computed from the + actual digits + + only one of lpadding, spadding, and rpadding can be non-zero, + and it's calculated from the width and other fields + */ + + /* compute the various parts we're going to write */ + switch (format->sign) { + case '+': + /* always put a + or - */ + spec->n_sign = 1; + spec->sign = (sign_char == '-' ? '-' : '+'); + break; + case ' ': + spec->n_sign = 1; + spec->sign = (sign_char == '-' ? '-' : ' '); + break; + default: + /* Not specified, or the default (-) */ + if (sign_char == '-') { + spec->n_sign = 1; + spec->sign = '-'; + } + } + + /* The number of chars used for non-digits and non-padding. */ + n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal + + spec->n_remainder; + + /* min_width can go negative, that's okay. format->width == -1 means + we don't care. */ + if (format->fill_char == '0' && format->align == '=') + spec->n_min_width = format->width - n_non_digit_non_padding; + else + spec->n_min_width = 0; + + if (spec->n_digits == 0) + /* This case only occurs when using 'c' formatting, we need + to special case it because the grouping code always wants + to have at least one character. */ + spec->n_grouped_digits = 0; + else { + Py_UCS4 grouping_maxchar; + spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping( + NULL, 0, + NULL, 0, spec->n_digits, + spec->n_min_width, + locale->grouping, locale->thousands_sep, &grouping_maxchar); + if (spec->n_grouped_digits == -1) { + return -1; + } + *maxchar = Py_MAX(*maxchar, grouping_maxchar); + } + + /* Given the desired width and the total of digit and non-digit + space we consume, see if we need any padding. format->width can + be negative (meaning no padding), but this code still works in + that case. */ + n_padding = format->width - + (n_non_digit_non_padding + spec->n_grouped_digits); + if (n_padding > 0) { + /* Some padding is needed. Determine if it's left, space, or right. */ + switch (format->align) { + case '<': + spec->n_rpadding = n_padding; + break; + case '^': + spec->n_lpadding = n_padding / 2; + spec->n_rpadding = n_padding - spec->n_lpadding; + break; + case '=': + spec->n_spadding = n_padding; + break; + case '>': + spec->n_lpadding = n_padding; + break; + default: + /* Shouldn't get here, but treat it as '>' */ + Py_UNREACHABLE(); + } + } + + if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding) + *maxchar = Py_MAX(*maxchar, format->fill_char); + + if (spec->n_decimal) + *maxchar = Py_MAX(*maxchar, PyUnicode_MAX_CHAR_VALUE(locale->decimal_point)); + + return spec->n_lpadding + spec->n_sign + spec->n_prefix + + spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + + spec->n_remainder + spec->n_rpadding; +} + +/* Fill in the digit parts of a number's string representation, + as determined in calc_number_widths(). + Return -1 on error, or 0 on success. */ +static int +fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec, + PyObject *digits, Py_ssize_t d_start, Py_ssize_t d_end, + PyObject *prefix, Py_ssize_t p_start, + Py_UCS4 fill_char, + LocaleInfo *locale, int toupper) +{ + /* Used to keep track of digits, decimal, and remainder. */ + Py_ssize_t d_pos = d_start; + const unsigned int kind = writer->kind; + const void *data = writer->data; + Py_ssize_t r; + + if (spec->n_lpadding) { + _PyUnicode_FastFill(writer->buffer, + writer->pos, spec->n_lpadding, fill_char); + writer->pos += spec->n_lpadding; + } + if (spec->n_sign == 1) { + PyUnicode_WRITE(kind, data, writer->pos, spec->sign); + writer->pos++; + } + if (spec->n_prefix) { + _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, + prefix, p_start, + spec->n_prefix); + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_prefix; t++) { + Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t); + c = Py_TOUPPER(c); + assert (c <= 127); + PyUnicode_WRITE(kind, data, writer->pos + t, c); + } + } + writer->pos += spec->n_prefix; + } + if (spec->n_spadding) { + _PyUnicode_FastFill(writer->buffer, + writer->pos, spec->n_spadding, fill_char); + writer->pos += spec->n_spadding; + } + + /* Only for type 'c' special case, it has no digits. */ + if (spec->n_digits != 0) { + /* Fill the digits with InsertThousandsGrouping. */ + r = _PyUnicode_InsertThousandsGrouping( + writer, spec->n_grouped_digits, + digits, d_pos, spec->n_digits, + spec->n_min_width, + locale->grouping, locale->thousands_sep, NULL); + if (r == -1) + return -1; + assert(r == spec->n_grouped_digits); + d_pos += spec->n_digits; + } + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_grouped_digits; t++) { + Py_UCS4 c = PyUnicode_READ(kind, data, writer->pos + t); + c = Py_TOUPPER(c); + if (c > 127) { + PyErr_SetString(PyExc_SystemError, "non-ascii grouped digit"); + return -1; + } + PyUnicode_WRITE(kind, data, writer->pos + t, c); + } + } + writer->pos += spec->n_grouped_digits; + + if (spec->n_decimal) { + _PyUnicode_FastCopyCharacters( + writer->buffer, writer->pos, + locale->decimal_point, 0, spec->n_decimal); + writer->pos += spec->n_decimal; + d_pos += 1; + } + + if (spec->n_remainder) { + _PyUnicode_FastCopyCharacters( + writer->buffer, writer->pos, + digits, d_pos, spec->n_remainder); + writer->pos += spec->n_remainder; + /* d_pos += spec->n_remainder; */ + } + + if (spec->n_rpadding) { + _PyUnicode_FastFill(writer->buffer, + writer->pos, spec->n_rpadding, + fill_char); + writer->pos += spec->n_rpadding; + } + return 0; +} + +static const char no_grouping[1] = {CHAR_MAX}; + +/* Find the decimal point character(s?), thousands_separator(s?), and + grouping description, either for the current locale if type is + LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE or + LT_UNDERSCORE_LOCALE/LT_UNDER_FOUR_LOCALE, or none if LT_NO_LOCALE. */ +static int +get_locale_info(enum LocaleType type, LocaleInfo *locale_info) +{ + switch (type) { + case LT_CURRENT_LOCALE: { + struct lconv *lc = localeconv(); + if (_Py_GetLocaleconvNumeric(lc, + &locale_info->decimal_point, + &locale_info->thousands_sep) < 0) { + return -1; + } + + /* localeconv() grouping can become a dangling pointer or point + to a different string if another thread calls localeconv() during + the string formatting. Copy the string to avoid this risk. */ + locale_info->grouping_buffer = _PyMem_Strdup(lc->grouping); + if (locale_info->grouping_buffer == NULL) { + PyErr_NoMemory(); + return -1; + } + locale_info->grouping = locale_info->grouping_buffer; + break; + } + case LT_DEFAULT_LOCALE: + case LT_UNDERSCORE_LOCALE: + case LT_UNDER_FOUR_LOCALE: + locale_info->decimal_point = PyUnicode_FromOrdinal('.'); + locale_info->thousands_sep = PyUnicode_FromOrdinal( + type == LT_DEFAULT_LOCALE ? ',' : '_'); + if (!locale_info->decimal_point || !locale_info->thousands_sep) + return -1; + if (type != LT_UNDER_FOUR_LOCALE) + locale_info->grouping = "\3"; /* Group every 3 characters. The + (implicit) trailing 0 means repeat + infinitely. */ + else + locale_info->grouping = "\4"; /* Bin/oct/hex group every four. */ + break; + case LT_NO_LOCALE: + locale_info->decimal_point = PyUnicode_FromOrdinal('.'); + locale_info->thousands_sep = PyUnicode_New(0, 0); + if (!locale_info->decimal_point || !locale_info->thousands_sep) + return -1; + locale_info->grouping = no_grouping; + break; + } + return 0; +} + +static void +free_locale_info(LocaleInfo *locale_info) +{ + Py_XDECREF(locale_info->decimal_point); + Py_XDECREF(locale_info->thousands_sep); + PyMem_Free(locale_info->grouping_buffer); +} + +/************************************************************************/ +/*********** string formatting ******************************************/ +/************************************************************************/ + +static int +format_string_internal(PyObject *value, const InternalFormatSpec *format, + _PyUnicodeWriter *writer) +{ + Py_ssize_t lpad; + Py_ssize_t rpad; + Py_ssize_t total; + Py_ssize_t len; + int result = -1; + Py_UCS4 maxchar; + + assert(PyUnicode_IS_READY(value)); + len = PyUnicode_GET_LENGTH(value); + + /* sign is not allowed on strings */ + if (format->sign != '\0') { + PyErr_SetString(PyExc_ValueError, + "Sign not allowed in string format specifier"); + goto done; + } + + /* alternate is not allowed on strings */ + if (format->alternate) { + PyErr_SetString(PyExc_ValueError, + "Alternate form (#) not allowed in string format " + "specifier"); + goto done; + } + + /* '=' alignment not allowed on strings */ + if (format->align == '=') { + PyErr_SetString(PyExc_ValueError, + "'=' alignment not allowed " + "in string format specifier"); + goto done; + } + + if ((format->width == -1 || format->width <= len) + && (format->precision == -1 || format->precision >= len)) { + /* Fast path */ + return _PyUnicodeWriter_WriteStr(writer, value); + } + + /* if precision is specified, output no more that format.precision + characters */ + if (format->precision >= 0 && len >= format->precision) { + len = format->precision; + } + + calc_padding(len, format->width, format->align, &lpad, &rpad, &total); + + maxchar = writer->maxchar; + if (lpad != 0 || rpad != 0) + maxchar = Py_MAX(maxchar, format->fill_char); + if (PyUnicode_MAX_CHAR_VALUE(value) > maxchar) { + Py_UCS4 valmaxchar = _PyUnicode_FindMaxChar(value, 0, len); + maxchar = Py_MAX(maxchar, valmaxchar); + } + + /* allocate the resulting string */ + if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) + goto done; + + /* Write into that space. First the padding. */ + result = fill_padding(writer, len, format->fill_char, lpad, rpad); + if (result == -1) + goto done; + + /* Then the source string. */ + if (len) { + _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, + value, 0, len); + } + writer->pos += (len + rpad); + result = 0; + +done: + return result; +} + + +/************************************************************************/ +/*********** long formatting ********************************************/ +/************************************************************************/ + +static int +format_long_internal(PyObject *value, const InternalFormatSpec *format, + _PyUnicodeWriter *writer) +{ + int result = -1; + Py_UCS4 maxchar = 127; + PyObject *tmp = NULL; + Py_ssize_t inumeric_chars; + Py_UCS4 sign_char = '\0'; + Py_ssize_t n_digits; /* count of digits need from the computed + string */ + Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which + produces non-digits */ + Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ + Py_ssize_t n_total; + Py_ssize_t prefix = 0; + NumberFieldWidths spec; + long x; + + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale = LocaleInfo_STATIC_INIT; + + /* no precision allowed on integers */ + if (format->precision != -1) { + PyErr_SetString(PyExc_ValueError, + "Precision not allowed in integer format specifier"); + goto done; + } + + /* special case for character formatting */ + if (format->type == 'c') { + /* error to specify a sign */ + if (format->sign != '\0') { + PyErr_SetString(PyExc_ValueError, + "Sign not allowed with integer" + " format specifier 'c'"); + goto done; + } + /* error to request alternate format */ + if (format->alternate) { + PyErr_SetString(PyExc_ValueError, + "Alternate form (#) not allowed with integer" + " format specifier 'c'"); + goto done; + } + + /* taken from unicodeobject.c formatchar() */ + /* Integer input truncated to a character */ + x = PyLong_AsLong(value); + if (x == -1 && PyErr_Occurred()) + goto done; + if (x < 0 || x > 0x10ffff) { + PyErr_SetString(PyExc_OverflowError, + "%c arg not in range(0x110000)"); + goto done; + } + tmp = PyUnicode_FromOrdinal(x); + inumeric_chars = 0; + n_digits = 1; + maxchar = Py_MAX(maxchar, (Py_UCS4)x); + + /* As a sort-of hack, we tell calc_number_widths that we only + have "remainder" characters. calc_number_widths thinks + these are characters that don't get formatted, only copied + into the output string. We do this for 'c' formatting, + because the characters are likely to be non-digits. */ + n_remainder = 1; + } + else { + int base; + int leading_chars_to_skip = 0; /* Number of characters added by + PyNumber_ToBase that we want to + skip over. */ + + /* Compute the base and how many characters will be added by + PyNumber_ToBase */ + switch (format->type) { + case 'b': + base = 2; + leading_chars_to_skip = 2; /* 0b */ + break; + case 'o': + base = 8; + leading_chars_to_skip = 2; /* 0o */ + break; + case 'x': + case 'X': + base = 16; + leading_chars_to_skip = 2; /* 0x */ + break; + default: /* shouldn't be needed, but stops a compiler warning */ + case 'd': + case 'n': + base = 10; + break; + } + + if (format->sign != '+' && format->sign != ' ' + && format->width == -1 + && format->type != 'X' && format->type != 'n' + && !format->thousands_separators + && PyLong_CheckExact(value)) + { + /* Fast path */ + return _PyLong_FormatWriter(writer, value, base, format->alternate); + } + + /* The number of prefix chars is the same as the leading + chars to skip */ + if (format->alternate) + n_prefix = leading_chars_to_skip; + + /* Do the hard part, converting to a string in a given base */ + tmp = _PyLong_Format(value, base); + if (tmp == NULL || PyUnicode_READY(tmp) == -1) + goto done; + + inumeric_chars = 0; + n_digits = PyUnicode_GET_LENGTH(tmp); + + prefix = inumeric_chars; + + /* Is a sign character present in the output? If so, remember it + and skip it */ + if (PyUnicode_READ_CHAR(tmp, inumeric_chars) == '-') { + sign_char = '-'; + ++prefix; + ++leading_chars_to_skip; + } + + /* Skip over the leading chars (0x, 0b, etc.) */ + n_digits -= leading_chars_to_skip; + inumeric_chars += leading_chars_to_skip; + } + + /* Determine the grouping, separator, and decimal point, if any. */ + if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + format->thousands_separators, + &locale) == -1) + goto done; + + /* Calculate how much memory we'll need. */ + n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars, + inumeric_chars + n_digits, n_remainder, 0, + &locale, format, &maxchar); + if (n_total == -1) { + goto done; + } + + /* Allocate the memory. */ + if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1) + goto done; + + /* Populate the memory. */ + result = fill_number(writer, &spec, + tmp, inumeric_chars, inumeric_chars + n_digits, + tmp, prefix, format->fill_char, + &locale, format->type == 'X'); + +done: + Py_XDECREF(tmp); + free_locale_info(&locale); + return result; +} + +/************************************************************************/ +/*********** float formatting *******************************************/ +/************************************************************************/ + +/* much of this is taken from unicodeobject.c */ +static int +format_float_internal(PyObject *value, + const InternalFormatSpec *format, + _PyUnicodeWriter *writer) +{ + char *buf = NULL; /* buffer returned from PyOS_double_to_string */ + Py_ssize_t n_digits; + Py_ssize_t n_remainder; + Py_ssize_t n_total; + int has_decimal; + double val; + int precision, default_precision = 6; + Py_UCS4 type = format->type; + int add_pct = 0; + Py_ssize_t index; + NumberFieldWidths spec; + int flags = 0; + int result = -1; + Py_UCS4 maxchar = 127; + Py_UCS4 sign_char = '\0'; + int float_type; /* Used to see if we have a nan, inf, or regular float. */ + PyObject *unicode_tmp = NULL; + + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale = LocaleInfo_STATIC_INIT; + + if (format->precision > INT_MAX) { + PyErr_SetString(PyExc_ValueError, "precision too big"); + goto done; + } + precision = (int)format->precision; + + if (format->alternate) + flags |= Py_DTSF_ALT; + + if (type == '\0') { + /* Omitted type specifier. Behaves in the same way as repr(x) + and str(x) if no precision is given, else like 'g', but with + at least one digit after the decimal point. */ + flags |= Py_DTSF_ADD_DOT_0; + type = 'r'; + default_precision = 0; + } + + if (type == 'n') + /* 'n' is the same as 'g', except for the locale used to + format the result. We take care of that later. */ + type = 'g'; + + val = PyFloat_AsDouble(value); + if (val == -1.0 && PyErr_Occurred()) + goto done; + + if (type == '%') { + type = 'f'; + val *= 100; + add_pct = 1; + } + + if (precision < 0) + precision = default_precision; + else if (type == 'r') + type = 'g'; + + /* Cast "type", because if we're in unicode we need to pass an + 8-bit char. This is safe, because we've restricted what "type" + can be. */ + buf = PyOS_double_to_string(val, (char)type, precision, flags, + &float_type); + if (buf == NULL) + goto done; + n_digits = strlen(buf); + + if (add_pct) { + /* We know that buf has a trailing zero (since we just called + strlen() on it), and we don't use that fact any more. So we + can just write over the trailing zero. */ + buf[n_digits] = '%'; + n_digits += 1; + } + + if (format->sign != '+' && format->sign != ' ' + && format->width == -1 + && format->type != 'n' + && !format->thousands_separators) + { + /* Fast path */ + result = _PyUnicodeWriter_WriteASCIIString(writer, buf, n_digits); + PyMem_Free(buf); + return result; + } + + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode. */ + unicode_tmp = _PyUnicode_FromASCII(buf, n_digits); + PyMem_Free(buf); + if (unicode_tmp == NULL) + goto done; + + /* Is a sign character present in the output? If so, remember it + and skip it */ + index = 0; + if (PyUnicode_READ_CHAR(unicode_tmp, index) == '-') { + sign_char = '-'; + ++index; + --n_digits; + } + + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal); + + /* Determine the grouping, separator, and decimal point, if any. */ + if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + format->thousands_separators, + &locale) == -1) + goto done; + + /* Calculate how much memory we'll need. */ + n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index, + index + n_digits, n_remainder, has_decimal, + &locale, format, &maxchar); + if (n_total == -1) { + goto done; + } + + /* Allocate the memory. */ + if (_PyUnicodeWriter_Prepare(writer, n_total, maxchar) == -1) + goto done; + + /* Populate the memory. */ + result = fill_number(writer, &spec, + unicode_tmp, index, index + n_digits, + NULL, 0, format->fill_char, + &locale, 0); + +done: + Py_XDECREF(unicode_tmp); + free_locale_info(&locale); + return result; +} + +/************************************************************************/ +/*********** complex formatting *****************************************/ +/************************************************************************/ + +static int +format_complex_internal(PyObject *value, + const InternalFormatSpec *format, + _PyUnicodeWriter *writer) +{ + double re; + double im; + char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */ + char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */ + + InternalFormatSpec tmp_format = *format; + Py_ssize_t n_re_digits; + Py_ssize_t n_im_digits; + Py_ssize_t n_re_remainder; + Py_ssize_t n_im_remainder; + Py_ssize_t n_re_total; + Py_ssize_t n_im_total; + int re_has_decimal; + int im_has_decimal; + int precision, default_precision = 6; + Py_UCS4 type = format->type; + Py_ssize_t i_re; + Py_ssize_t i_im; + NumberFieldWidths re_spec; + NumberFieldWidths im_spec; + int flags = 0; + int result = -1; + Py_UCS4 maxchar = 127; + enum PyUnicode_Kind rkind; + void *rdata; + Py_UCS4 re_sign_char = '\0'; + Py_UCS4 im_sign_char = '\0'; + int re_float_type; /* Used to see if we have a nan, inf, or regular float. */ + int im_float_type; + int add_parens = 0; + int skip_re = 0; + Py_ssize_t lpad; + Py_ssize_t rpad; + Py_ssize_t total; + PyObject *re_unicode_tmp = NULL; + PyObject *im_unicode_tmp = NULL; + + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale = LocaleInfo_STATIC_INIT; + + if (format->precision > INT_MAX) { + PyErr_SetString(PyExc_ValueError, "precision too big"); + goto done; + } + precision = (int)format->precision; + + /* Zero padding is not allowed. */ + if (format->fill_char == '0') { + PyErr_SetString(PyExc_ValueError, + "Zero padding is not allowed in complex format " + "specifier"); + goto done; + } + + /* Neither is '=' alignment . */ + if (format->align == '=') { + PyErr_SetString(PyExc_ValueError, + "'=' alignment flag is not allowed in complex format " + "specifier"); + goto done; + } + + re = PyComplex_RealAsDouble(value); + if (re == -1.0 && PyErr_Occurred()) + goto done; + im = PyComplex_ImagAsDouble(value); + if (im == -1.0 && PyErr_Occurred()) + goto done; + + if (format->alternate) + flags |= Py_DTSF_ALT; + + if (type == '\0') { + /* Omitted type specifier. Should be like str(self). */ + type = 'r'; + default_precision = 0; + if (re == 0.0 && copysign(1.0, re) == 1.0) + skip_re = 1; + else + add_parens = 1; + } + + if (type == 'n') + /* 'n' is the same as 'g', except for the locale used to + format the result. We take care of that later. */ + type = 'g'; + + if (precision < 0) + precision = default_precision; + else if (type == 'r') + type = 'g'; + + /* Cast "type", because if we're in unicode we need to pass an + 8-bit char. This is safe, because we've restricted what "type" + can be. */ + re_buf = PyOS_double_to_string(re, (char)type, precision, flags, + &re_float_type); + if (re_buf == NULL) + goto done; + im_buf = PyOS_double_to_string(im, (char)type, precision, flags, + &im_float_type); + if (im_buf == NULL) + goto done; + + n_re_digits = strlen(re_buf); + n_im_digits = strlen(im_buf); + + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode. */ + re_unicode_tmp = _PyUnicode_FromASCII(re_buf, n_re_digits); + if (re_unicode_tmp == NULL) + goto done; + i_re = 0; + + im_unicode_tmp = _PyUnicode_FromASCII(im_buf, n_im_digits); + if (im_unicode_tmp == NULL) + goto done; + i_im = 0; + + /* Is a sign character present in the output? If so, remember it + and skip it */ + if (PyUnicode_READ_CHAR(re_unicode_tmp, i_re) == '-') { + re_sign_char = '-'; + ++i_re; + --n_re_digits; + } + if (PyUnicode_READ_CHAR(im_unicode_tmp, i_im) == '-') { + im_sign_char = '-'; + ++i_im; + --n_im_digits; + } + + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(re_unicode_tmp, i_re, i_re + n_re_digits, + &n_re_remainder, &re_has_decimal); + parse_number(im_unicode_tmp, i_im, i_im + n_im_digits, + &n_im_remainder, &im_has_decimal); + + /* Determine the grouping, separator, and decimal point, if any. */ + if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + format->thousands_separators, + &locale) == -1) + goto done; + + /* Turn off any padding. We'll do it later after we've composed + the numbers without padding. */ + tmp_format.fill_char = '\0'; + tmp_format.align = '<'; + tmp_format.width = -1; + + /* Calculate how much memory we'll need. */ + n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, re_unicode_tmp, + i_re, i_re + n_re_digits, n_re_remainder, + re_has_decimal, &locale, &tmp_format, + &maxchar); + if (n_re_total == -1) { + goto done; + } + + /* Same formatting, but always include a sign, unless the real part is + * going to be omitted, in which case we use whatever sign convention was + * requested by the original format. */ + if (!skip_re) + tmp_format.sign = '+'; + n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, im_unicode_tmp, + i_im, i_im + n_im_digits, n_im_remainder, + im_has_decimal, &locale, &tmp_format, + &maxchar); + if (n_im_total == -1) { + goto done; + } + + if (skip_re) + n_re_total = 0; + + /* Add 1 for the 'j', and optionally 2 for parens. */ + calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, + format->width, format->align, &lpad, &rpad, &total); + + if (lpad || rpad) + maxchar = Py_MAX(maxchar, format->fill_char); + + if (_PyUnicodeWriter_Prepare(writer, total, maxchar) == -1) + goto done; + rkind = writer->kind; + rdata = writer->data; + + /* Populate the memory. First, the padding. */ + result = fill_padding(writer, + n_re_total + n_im_total + 1 + add_parens * 2, + format->fill_char, lpad, rpad); + if (result == -1) + goto done; + + if (add_parens) { + PyUnicode_WRITE(rkind, rdata, writer->pos, '('); + writer->pos++; + } + + if (!skip_re) { + result = fill_number(writer, &re_spec, + re_unicode_tmp, i_re, i_re + n_re_digits, + NULL, 0, + 0, + &locale, 0); + if (result == -1) + goto done; + } + result = fill_number(writer, &im_spec, + im_unicode_tmp, i_im, i_im + n_im_digits, + NULL, 0, + 0, + &locale, 0); + if (result == -1) + goto done; + PyUnicode_WRITE(rkind, rdata, writer->pos, 'j'); + writer->pos++; + + if (add_parens) { + PyUnicode_WRITE(rkind, rdata, writer->pos, ')'); + writer->pos++; + } + + writer->pos += rpad; + +done: + PyMem_Free(re_buf); + PyMem_Free(im_buf); + Py_XDECREF(re_unicode_tmp); + Py_XDECREF(im_unicode_tmp); + free_locale_info(&locale); + return result; +} + +/************************************************************************/ +/*********** built in formatters ****************************************/ +/************************************************************************/ +static int +format_obj(PyObject *obj, _PyUnicodeWriter *writer) +{ + PyObject *str; + int err; + + str = PyObject_Str(obj); + if (str == NULL) + return -1; + err = _PyUnicodeWriter_WriteStr(writer, str); + Py_DECREF(str); + return err; +} + +int +_PyUnicode_FormatAdvancedWriter(_PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, Py_ssize_t end) +{ + InternalFormatSpec format; + + assert(PyUnicode_Check(obj)); + + /* check for the special case of zero length format spec, make + it equivalent to str(obj) */ + if (start == end) { + if (PyUnicode_CheckExact(obj)) + return _PyUnicodeWriter_WriteStr(writer, obj); + else + return format_obj(obj, writer); + } + + /* parse the format_spec */ + if (!parse_internal_render_format_spec(format_spec, start, end, + &format, 's', '<')) + return -1; + + /* type conversion? */ + switch (format.type) { + case 's': + /* no type conversion needed, already a string. do the formatting */ + return format_string_internal(obj, &format, writer); + default: + /* unknown */ + unknown_presentation_type(format.type, obj->ob_type->tp_name); + return -1; + } +} + +int +_PyLong_FormatAdvancedWriter(_PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, Py_ssize_t end) +{ + PyObject *tmp = NULL, *str = NULL; + InternalFormatSpec format; + int result = -1; + + /* check for the special case of zero length format spec, make + it equivalent to str(obj) */ + if (start == end) { + if (PyLong_CheckExact(obj)) + return _PyLong_FormatWriter(writer, obj, 10, 0); + else + return format_obj(obj, writer); + } + + /* parse the format_spec */ + if (!parse_internal_render_format_spec(format_spec, start, end, + &format, 'd', '>')) + goto done; + + /* type conversion? */ + switch (format.type) { + case 'b': + case 'c': + case 'd': + case 'o': + case 'x': + case 'X': + case 'n': + /* no type conversion needed, already an int. do the formatting */ + result = format_long_internal(obj, &format, writer); + break; + + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case '%': + /* convert to float */ + tmp = PyNumber_Float(obj); + if (tmp == NULL) + goto done; + result = format_float_internal(tmp, &format, writer); + break; + + default: + /* unknown */ + unknown_presentation_type(format.type, obj->ob_type->tp_name); + goto done; + } + +done: + Py_XDECREF(tmp); + Py_XDECREF(str); + return result; +} + +int +_PyFloat_FormatAdvancedWriter(_PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, Py_ssize_t end) +{ + InternalFormatSpec format; + + /* check for the special case of zero length format spec, make + it equivalent to str(obj) */ + if (start == end) + return format_obj(obj, writer); + + /* parse the format_spec */ + if (!parse_internal_render_format_spec(format_spec, start, end, + &format, '\0', '>')) + return -1; + + /* type conversion? */ + switch (format.type) { + case '\0': /* No format code: like 'g', but with at least one decimal. */ + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'n': + case '%': + /* no conversion, already a float. do the formatting */ + return format_float_internal(obj, &format, writer); + + default: + /* unknown */ + unknown_presentation_type(format.type, obj->ob_type->tp_name); + return -1; + } +} + +int +_PyComplex_FormatAdvancedWriter(_PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, Py_ssize_t end) +{ + InternalFormatSpec format; + + /* check for the special case of zero length format spec, make + it equivalent to str(obj) */ + if (start == end) + return format_obj(obj, writer); + + /* parse the format_spec */ + if (!parse_internal_render_format_spec(format_spec, start, end, + &format, '\0', '>')) + return -1; + + /* type conversion? */ + switch (format.type) { + case '\0': /* No format code: like 'g', but with at least one decimal. */ + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'n': + /* no conversion, already a complex. do the formatting */ + return format_complex_internal(obj, &format, writer); + + default: + /* unknown */ + unknown_presentation_type(format.type, obj->ob_type->tp_name); + return -1; + } +} diff --git a/python/Python/frozen.c b/python/Python/frozen.c new file mode 100755 index 0000000..228a110 --- /dev/null +++ b/python/Python/frozen.c @@ -0,0 +1,50 @@ + +/* Dummy frozen modules initializer */ + +#include "Python.h" +#include "importlib.h" +#include "importlib_external.h" +#include "importlib_zipimport.h" + +/* In order to test the support for frozen modules, by default we + define a single frozen module, __hello__. Loading it will print + some famous words... */ + +/* To regenerate this data after the bytecode or marshal format has changed, + go to ../Tools/freeze/ and freeze the flag.py file; then copy and paste + the appropriate bytes from M___main__.c. */ + +static unsigned char M___hello__[] = { + 227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0, + 90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3, + 84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78, + 41,2,218,11,105,110,105,116,105,97,108,105,122,101,100,218, + 5,112,114,105,110,116,169,0,114,3,0,0,0,114,3,0, + 0,0,250,20,84,111,111,108,115,47,102,114,101,101,122,101, + 47,102,108,97,103,46,112,121,218,8,60,109,111,100,117,108, + 101,62,1,0,0,0,115,2,0,0,0,4,1, +}; + +#define SIZE (int)sizeof(M___hello__) + +static const struct _frozen _PyImport_FrozenModules[] = { + /* importlib */ + {"_frozen_importlib", _Py_M__importlib_bootstrap, + (int)sizeof(_Py_M__importlib_bootstrap)}, + {"_frozen_importlib_external", _Py_M__importlib_bootstrap_external, + (int)sizeof(_Py_M__importlib_bootstrap_external)}, + {"zipimport", _Py_M__zipimport, + (int)sizeof(_Py_M__zipimport)}, + /* Test module */ + {"__hello__", M___hello__, SIZE}, + /* Test package (negative size indicates package-ness) */ + {"__phello__", M___hello__, -SIZE}, + {"__phello__.spam", M___hello__, SIZE}, + {0, 0, 0} /* sentinel */ +}; + +/* Embedding apps may change this pointer to point to their favorite + collection of frozen modules: */ + +const struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules; diff --git a/python/Python/frozenmain.c b/python/Python/frozenmain.c new file mode 100755 index 0000000..7f9cc19 --- /dev/null +++ b/python/Python/frozenmain.c @@ -0,0 +1,129 @@ + +/* Python interpreter main program for frozen scripts */ + +#include "Python.h" +#include "pycore_pystate.h" +#include + +#ifdef MS_WINDOWS +extern void PyWinFreeze_ExeInit(void); +extern void PyWinFreeze_ExeTerm(void); +extern int PyInitFrozenExtensions(void); +#endif + +/* Main program */ + +int +Py_FrozenMain(int argc, char **argv) +{ + PyStatus status = _PyRuntime_Initialize(); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + const char *p; + int i, n, sts = 1; + int inspect = 0; + int unbuffered = 0; + char *oldloc = NULL; + wchar_t **argv_copy = NULL; + /* We need a second copies, as Python might modify the first one. */ + wchar_t **argv_copy2 = NULL; + + if (argc > 0) { + argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); + argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); + if (!argv_copy || !argv_copy2) { + fprintf(stderr, "out of memory\n"); + goto error; + } + } + + PyConfig config; + PyConfig_InitPythonConfig(&config); + config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ + + if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') + inspect = 1; + if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') + unbuffered = 1; + + if (unbuffered) { + setbuf(stdin, (char *)NULL); + setbuf(stdout, (char *)NULL); + setbuf(stderr, (char *)NULL); + } + + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); + if (!oldloc) { + fprintf(stderr, "out of memory\n"); + goto error; + } + + setlocale(LC_ALL, ""); + for (i = 0; i < argc; i++) { + argv_copy[i] = Py_DecodeLocale(argv[i], NULL); + argv_copy2[i] = argv_copy[i]; + if (!argv_copy[i]) { + fprintf(stderr, "Unable to decode the command line argument #%i\n", + i + 1); + argc = i; + goto error; + } + } + setlocale(LC_ALL, oldloc); + PyMem_RawFree(oldloc); + oldloc = NULL; + +#ifdef MS_WINDOWS + PyInitFrozenExtensions(); +#endif /* MS_WINDOWS */ + if (argc >= 1) + Py_SetProgramName(argv_copy[0]); + + status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + +#ifdef MS_WINDOWS + PyWinFreeze_ExeInit(); +#endif + + if (Py_VerboseFlag) + fprintf(stderr, "Python %s\n%s\n", + Py_GetVersion(), Py_GetCopyright()); + + PySys_SetArgv(argc, argv_copy); + + n = PyImport_ImportFrozenModule("__main__"); + if (n == 0) + Py_FatalError("__main__ not frozen"); + if (n < 0) { + PyErr_Print(); + sts = 1; + } + else + sts = 0; + + if (inspect && isatty((int)fileno(stdin))) + sts = PyRun_AnyFile(stdin, "") != 0; + +#ifdef MS_WINDOWS + PyWinFreeze_ExeTerm(); +#endif + if (Py_FinalizeEx() < 0) { + sts = 120; + } + +error: + PyMem_RawFree(argv_copy); + if (argv_copy2) { + for (i = 0; i < argc; i++) + PyMem_RawFree(argv_copy2[i]); + PyMem_RawFree(argv_copy2); + } + PyMem_RawFree(oldloc); + return sts; +} diff --git a/python/Python/future.c b/python/Python/future.c new file mode 100755 index 0000000..1663a38 --- /dev/null +++ b/python/Python/future.c @@ -0,0 +1,158 @@ +#include "Python.h" +#include "Python-ast.h" +#include "node.h" +#include "token.h" +#include "graminit.h" +#include "code.h" +#include "symtable.h" +#include "ast.h" + +#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" +#define ERR_LATE_FUTURE \ +"from __future__ imports must occur at the beginning of the file" + +static int +future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) +{ + int i; + asdl_seq *names; + + assert(s->kind == ImportFrom_kind); + + names = s->v.ImportFrom.names; + for (i = 0; i < asdl_seq_LEN(names); i++) { + alias_ty name = (alias_ty)asdl_seq_GET(names, i); + const char *feature = PyUnicode_AsUTF8(name->name); + if (!feature) + return 0; + if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) { + continue; + } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { + continue; + } else if (strcmp(feature, FUTURE_DIVISION) == 0) { + continue; + } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) { + continue; + } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) { + continue; + } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) { + continue; + } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) { + continue; + } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) { + ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL; + } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) { + continue; + } else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) { + ff->ff_features |= CO_FUTURE_ANNOTATIONS; + } else if (strcmp(feature, "braces") == 0) { + PyErr_SetString(PyExc_SyntaxError, + "not a chance"); + PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); + return 0; + } else { + PyErr_Format(PyExc_SyntaxError, + UNDEFINED_FUTURE_FEATURE, feature); + PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); + return 0; + } + } + return 1; +} + +static int +future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) +{ + int i, done = 0, prev_line = 0; + + if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) + return 1; + + if (asdl_seq_LEN(mod->v.Module.body) == 0) + return 1; + + /* A subsequent pass will detect future imports that don't + appear at the beginning of the file. There's one case, + however, that is easier to handle here: A series of imports + joined by semi-colons, where the first import is a future + statement but some subsequent import has the future form + but is preceded by a regular import. + */ + + i = 0; + if (_PyAST_GetDocString(mod->v.Module.body) != NULL) + i++; + + for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { + stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); + + if (done && s->lineno > prev_line) + return 1; + prev_line = s->lineno; + + /* The tests below will return from this function unless it is + still possible to find a future statement. The only things + that can precede a future statement are another future + statement and a doc string. + */ + + if (s->kind == ImportFrom_kind) { + identifier modname = s->v.ImportFrom.module; + if (modname && + _PyUnicode_EqualToASCIIString(modname, "__future__")) { + if (done) { + PyErr_SetString(PyExc_SyntaxError, + ERR_LATE_FUTURE); + PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); + return 0; + } + if (!future_check_features(ff, s, filename)) + return 0; + ff->ff_lineno = s->lineno; + } + else { + done = 1; + } + } + else { + done = 1; + } + } + return 1; +} + + +PyFutureFeatures * +PyFuture_FromASTObject(mod_ty mod, PyObject *filename) +{ + PyFutureFeatures *ff; + + ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); + if (ff == NULL) { + PyErr_NoMemory(); + return NULL; + } + ff->ff_features = 0; + ff->ff_lineno = -1; + + if (!future_parse(ff, mod, filename)) { + PyObject_Free(ff); + return NULL; + } + return ff; +} + + +PyFutureFeatures * +PyFuture_FromAST(mod_ty mod, const char *filename_str) +{ + PyFutureFeatures *ff; + PyObject *filename; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + ff = PyFuture_FromASTObject(mod, filename); + Py_DECREF(filename); + return ff; +} diff --git a/python/Python/getargs.c b/python/Python/getargs.c new file mode 100755 index 0000000..c1b7b1a --- /dev/null +++ b/python/Python/getargs.c @@ -0,0 +1,2859 @@ + +/* New getargs implementation */ + +#include "Python.h" +#include "pycore_tupleobject.h" + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif +int PyArg_Parse(PyObject *, const char *, ...); +int PyArg_ParseTuple(PyObject *, const char *, ...); +int PyArg_VaParse(PyObject *, const char *, va_list); + +int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, ...); +int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, va_list); + +int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, ...); +int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, va_list); + +#ifdef HAVE_DECLSPEC_DLL +/* Export functions */ +PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); +PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, + const char *format, ...); +PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, + PyObject *kwnames, + struct _PyArg_Parser *parser, ...); +PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); +PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, + const char *, char **, ...); +PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); +PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list); +PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, + const char *, char **, va_list); + +PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, + struct _PyArg_Parser *, ...); +PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *, + struct _PyArg_Parser *, va_list); +#endif + +#define FLAG_COMPAT 1 +#define FLAG_SIZE_T 2 + +typedef int (*destr_t)(PyObject *, void *); + + +/* Keep track of "objects" that have been allocated or initialized and + which will need to be deallocated or cleaned up somehow if overall + parsing fails. +*/ +typedef struct { + void *item; + destr_t destructor; +} freelistentry_t; + +typedef struct { + freelistentry_t *entries; + int first_available; + int entries_malloced; +} freelist_t; + +#define STATIC_FREELIST_ENTRIES 8 + +/* Forward */ +static int vgetargs1_impl(PyObject *args, PyObject *const *stack, Py_ssize_t nargs, + const char *format, va_list *p_va, int flags); +static int vgetargs1(PyObject *, const char *, va_list *, int); +static void seterror(Py_ssize_t, const char *, int *, const char *, const char *); +static const char *convertitem(PyObject *, const char **, va_list *, int, int *, + char *, size_t, freelist_t *); +static const char *converttuple(PyObject *, const char **, va_list *, int, + int *, char *, size_t, int, freelist_t *); +static const char *convertsimple(PyObject *, const char **, va_list *, int, + char *, size_t, freelist_t *); +static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **); +static int getbuffer(PyObject *, Py_buffer *, const char**); + +static int vgetargskeywords(PyObject *, PyObject *, + const char *, char **, va_list *, int); +static int vgetargskeywordsfast(PyObject *, PyObject *, + struct _PyArg_Parser *, va_list *, int); +static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, + PyObject *keywords, PyObject *kwnames, + struct _PyArg_Parser *parser, + va_list *p_va, int flags); +static const char *skipitem(const char **, va_list *, int); + +int +PyArg_Parse(PyObject *args, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1(args, format, &va, FLAG_COMPAT); + va_end(va); + return retval; +} + +int +_PyArg_Parse_SizeT(PyObject *args, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T); + va_end(va); + return retval; +} + + +int +PyArg_ParseTuple(PyObject *args, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1(args, format, &va, 0); + va_end(va); + return retval; +} + +int +_PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1(args, format, &va, FLAG_SIZE_T); + va_end(va); + return retval; +} + + +int +_PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0); + va_end(va); + return retval; +} + +int +_PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...) +{ + int retval; + va_list va; + + va_start(va, format); + retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T); + va_end(va); + return retval; +} + + +int +PyArg_VaParse(PyObject *args, const char *format, va_list va) +{ + va_list lva; + int retval; + + va_copy(lva, va); + + retval = vgetargs1(args, format, &lva, 0); + va_end(lva); + return retval; +} + +int +_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) +{ + va_list lva; + int retval; + + va_copy(lva, va); + + retval = vgetargs1(args, format, &lva, FLAG_SIZE_T); + va_end(lva); + return retval; +} + + +/* Handle cleanup of allocated memory in case of exception */ + +static int +cleanup_ptr(PyObject *self, void *ptr) +{ + if (ptr) { + PyMem_FREE(ptr); + } + return 0; +} + +static int +cleanup_buffer(PyObject *self, void *ptr) +{ + Py_buffer *buf = (Py_buffer *)ptr; + if (buf) { + PyBuffer_Release(buf); + } + return 0; +} + +static int +addcleanup(void *ptr, freelist_t *freelist, destr_t destructor) +{ + int index; + + index = freelist->first_available; + freelist->first_available += 1; + + freelist->entries[index].item = ptr; + freelist->entries[index].destructor = destructor; + + return 0; +} + +static int +cleanreturn(int retval, freelist_t *freelist) +{ + int index; + + if (retval == 0) { + /* A failure occurred, therefore execute all of the cleanup + functions. + */ + for (index = 0; index < freelist->first_available; ++index) { + freelist->entries[index].destructor(NULL, + freelist->entries[index].item); + } + } + if (freelist->entries_malloced) + PyMem_FREE(freelist->entries); + return retval; +} + + +static int +vgetargs1_impl(PyObject *compat_args, PyObject *const *stack, Py_ssize_t nargs, const char *format, + va_list *p_va, int flags) +{ + char msgbuf[256]; + int levels[32]; + const char *fname = NULL; + const char *message = NULL; + int min = -1; + int max = 0; + int level = 0; + int endfmt = 0; + const char *formatsave = format; + Py_ssize_t i; + const char *msg; + int compat = flags & FLAG_COMPAT; + freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; + freelist_t freelist; + + assert(nargs == 0 || stack != NULL); + + freelist.entries = static_entries; + freelist.first_available = 0; + freelist.entries_malloced = 0; + + flags = flags & ~FLAG_COMPAT; + + while (endfmt == 0) { + int c = *format++; + switch (c) { + case '(': + if (level == 0) + max++; + level++; + if (level >= 30) + Py_FatalError("too many tuple nesting levels " + "in argument format string"); + break; + case ')': + if (level == 0) + Py_FatalError("excess ')' in getargs format"); + else + level--; + break; + case '\0': + endfmt = 1; + break; + case ':': + fname = format; + endfmt = 1; + break; + case ';': + message = format; + endfmt = 1; + break; + case '|': + if (level == 0) + min = max; + break; + default: + if (level == 0) { + if (Py_ISALPHA(Py_CHARMASK(c))) + if (c != 'e') /* skip encoded */ + max++; + } + break; + } + } + + if (level != 0) + Py_FatalError(/* '(' */ "missing ')' in getargs format"); + + if (min < 0) + min = max; + + format = formatsave; + + if (max > STATIC_FREELIST_ENTRIES) { + freelist.entries = PyMem_NEW(freelistentry_t, max); + if (freelist.entries == NULL) { + PyErr_NoMemory(); + return 0; + } + freelist.entries_malloced = 1; + } + + if (compat) { + if (max == 0) { + if (compat_args == NULL) + return 1; + PyErr_Format(PyExc_TypeError, + "%.200s%s takes no arguments", + fname==NULL ? "function" : fname, + fname==NULL ? "" : "()"); + return cleanreturn(0, &freelist); + } + else if (min == 1 && max == 1) { + if (compat_args == NULL) { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes at least one argument", + fname==NULL ? "function" : fname, + fname==NULL ? "" : "()"); + return cleanreturn(0, &freelist); + } + msg = convertitem(compat_args, &format, p_va, flags, levels, + msgbuf, sizeof(msgbuf), &freelist); + if (msg == NULL) + return cleanreturn(1, &freelist); + seterror(levels[0], msg, levels+1, fname, message); + return cleanreturn(0, &freelist); + } + else { + PyErr_SetString(PyExc_SystemError, + "old style getargs format uses new features"); + return cleanreturn(0, &freelist); + } + } + + if (nargs < min || max < nargs) { + if (message == NULL) + PyErr_Format(PyExc_TypeError, + "%.150s%s takes %s %d argument%s (%zd given)", + fname==NULL ? "function" : fname, + fname==NULL ? "" : "()", + min==max ? "exactly" + : nargs < min ? "at least" : "at most", + nargs < min ? min : max, + (nargs < min ? min : max) == 1 ? "" : "s", + nargs); + else + PyErr_SetString(PyExc_TypeError, message); + return cleanreturn(0, &freelist); + } + + for (i = 0; i < nargs; i++) { + if (*format == '|') + format++; + msg = convertitem(stack[i], &format, p_va, + flags, levels, msgbuf, + sizeof(msgbuf), &freelist); + if (msg) { + seterror(i+1, msg, levels, fname, message); + return cleanreturn(0, &freelist); + } + } + + if (*format != '\0' && !Py_ISALPHA(Py_CHARMASK(*format)) && + *format != '(' && + *format != '|' && *format != ':' && *format != ';') { + PyErr_Format(PyExc_SystemError, + "bad format string: %.200s", formatsave); + return cleanreturn(0, &freelist); + } + + return cleanreturn(1, &freelist); +} + +static int +vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) +{ + PyObject **stack; + Py_ssize_t nargs; + + if (!(flags & FLAG_COMPAT)) { + assert(args != NULL); + + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, + "new style getargs format but argument is not a tuple"); + return 0; + } + + stack = _PyTuple_ITEMS(args); + nargs = PyTuple_GET_SIZE(args); + } + else { + stack = NULL; + nargs = 0; + } + + return vgetargs1_impl(args, stack, nargs, format, p_va, flags); +} + + +static void +seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, + const char *message) +{ + char buf[512]; + int i; + char *p = buf; + + if (PyErr_Occurred()) + return; + else if (message == NULL) { + if (fname != NULL) { + PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname); + p += strlen(p); + } + if (iarg != 0) { + PyOS_snprintf(p, sizeof(buf) - (p - buf), + "argument %" PY_FORMAT_SIZE_T "d", iarg); + i = 0; + p += strlen(p); + while (i < 32 && levels[i] > 0 && (int)(p-buf) < 220) { + PyOS_snprintf(p, sizeof(buf) - (p - buf), + ", item %d", levels[i]-1); + p += strlen(p); + i++; + } + } + else { + PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument"); + p += strlen(p); + } + PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg); + message = buf; + } + if (msg[0] == '(') { + PyErr_SetString(PyExc_SystemError, message); + } + else { + PyErr_SetString(PyExc_TypeError, message); + } +} + + +/* Convert a tuple argument. + On entry, *p_format points to the character _after_ the opening '('. + On successful exit, *p_format points to the closing ')'. + If successful: + *p_format and *p_va are updated, + *levels and *msgbuf are untouched, + and NULL is returned. + If the argument is invalid: + *p_format is unchanged, + *p_va is undefined, + *levels is a 0-terminated list of item numbers, + *msgbuf contains an error message, whose format is: + "must be , not ", where: + is the name of the expected type, and + is the name of the actual type, + and msgbuf is returned. +*/ + +static const char * +converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, + int *levels, char *msgbuf, size_t bufsize, int toplevel, + freelist_t *freelist) +{ + int level = 0; + int n = 0; + const char *format = *p_format; + int i; + Py_ssize_t len; + + for (;;) { + int c = *format++; + if (c == '(') { + if (level == 0) + n++; + level++; + } + else if (c == ')') { + if (level == 0) + break; + level--; + } + else if (c == ':' || c == ';' || c == '\0') + break; + else if (level == 0 && Py_ISALPHA(Py_CHARMASK(c))) + n++; + } + + if (!PySequence_Check(arg) || PyBytes_Check(arg)) { + levels[0] = 0; + PyOS_snprintf(msgbuf, bufsize, + toplevel ? "expected %d arguments, not %.50s" : + "must be %d-item sequence, not %.50s", + n, + arg == Py_None ? "None" : arg->ob_type->tp_name); + return msgbuf; + } + + len = PySequence_Size(arg); + if (len != n) { + levels[0] = 0; + if (toplevel) { + PyOS_snprintf(msgbuf, bufsize, + "expected %d argument%s, not %" PY_FORMAT_SIZE_T "d", + n, + n == 1 ? "" : "s", + len); + } + else { + PyOS_snprintf(msgbuf, bufsize, + "must be sequence of length %d, " + "not %" PY_FORMAT_SIZE_T "d", + n, len); + } + return msgbuf; + } + + format = *p_format; + for (i = 0; i < n; i++) { + const char *msg; + PyObject *item; + item = PySequence_GetItem(arg, i); + if (item == NULL) { + PyErr_Clear(); + levels[0] = i+1; + levels[1] = 0; + strncpy(msgbuf, "is not retrievable", bufsize); + return msgbuf; + } + msg = convertitem(item, &format, p_va, flags, levels+1, + msgbuf, bufsize, freelist); + /* PySequence_GetItem calls tp->sq_item, which INCREFs */ + Py_XDECREF(item); + if (msg != NULL) { + levels[0] = i+1; + return msg; + } + } + + *p_format = format; + return NULL; +} + + +/* Convert a single item. */ + +static const char * +convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, + int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist) +{ + const char *msg; + const char *format = *p_format; + + if (*format == '(' /* ')' */) { + format++; + msg = converttuple(arg, &format, p_va, flags, levels, msgbuf, + bufsize, 0, freelist); + if (msg == NULL) + format++; + } + else { + msg = convertsimple(arg, &format, p_va, flags, + msgbuf, bufsize, freelist); + if (msg != NULL) + levels[0] = 0; + } + if (msg == NULL) + *p_format = format; + return msg; +} + + + +/* Format an error message generated by convertsimple(). + displayname must be UTF-8 encoded. +*/ + +void +_PyArg_BadArgument(const char *fname, const char *displayname, + const char *expected, PyObject *arg) +{ + PyErr_Format(PyExc_TypeError, + "%.200s() %.200s must be %.50s, not %.50s", + fname, displayname, expected, + arg == Py_None ? "None" : arg->ob_type->tp_name); +} + +static const char * +converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize) +{ + assert(expected != NULL); + assert(arg != NULL); + if (expected[0] == '(') { + PyOS_snprintf(msgbuf, bufsize, + "%.100s", expected); + } + else { + PyOS_snprintf(msgbuf, bufsize, + "must be %.50s, not %.50s", expected, + arg == Py_None ? "None" : arg->ob_type->tp_name); + } + return msgbuf; +} + +#define CONV_UNICODE "(unicode conversion error)" + +/* Explicitly check for float arguments when integers are expected. + Return 1 for error, 0 if ok. + XXX Should be removed after the end of the deprecation period in + _PyLong_FromNbIndexOrNbInt. */ +static int +float_argument_error(PyObject *arg) +{ + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + return 1; + } + else + return 0; +} + +/* Convert a non-tuple argument. Return NULL if conversion went OK, + or a string with a message describing the failure. The message is + formatted as "must be , not ". + When failing, an exception may or may not have been raised. + Don't call if a tuple is expected. + + When you add new format codes, please don't forget poor skipitem() below. +*/ + +static const char * +convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, + char *msgbuf, size_t bufsize, freelist_t *freelist) +{ + /* For # codes */ +#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\ + if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \ + else { \ + if (PyErr_WarnEx(PyExc_DeprecationWarning, \ + "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { \ + return NULL; \ + } \ + q=va_arg(*p_va, int*); \ + } +#define STORE_SIZE(s) \ + if (flags & FLAG_SIZE_T) \ + *q2=s; \ + else { \ + if (INT_MAX < s) { \ + PyErr_SetString(PyExc_OverflowError, \ + "size does not fit in an int"); \ + return converterr("", arg, msgbuf, bufsize); \ + } \ + *q = (int)s; \ + } +#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q) +#define RETURN_ERR_OCCURRED return msgbuf + + const char *format = *p_format; + char c = *format++; + const char *sarg; + + switch (c) { + + case 'b': { /* unsigned byte -- very short int */ + char *p = va_arg(*p_va, char *); + long ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else if (ival < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is less than minimum"); + RETURN_ERR_OCCURRED; + } + else if (ival > UCHAR_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is greater than maximum"); + RETURN_ERR_OCCURRED; + } + else + *p = (unsigned char) ival; + break; + } + + case 'B': {/* byte sized bitfield - both signed and unsigned + values allowed */ + char *p = va_arg(*p_va, char *); + long ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = PyLong_AsUnsignedLongMask(arg); + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = (unsigned char) ival; + break; + } + + case 'h': {/* signed short int */ + short *p = va_arg(*p_va, short *); + long ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + RETURN_ERR_OCCURRED; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + RETURN_ERR_OCCURRED; + } + else + *p = (short) ival; + break; + } + + case 'H': { /* short int sized bitfield, both signed and + unsigned allowed */ + unsigned short *p = va_arg(*p_va, unsigned short *); + long ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = PyLong_AsUnsignedLongMask(arg); + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = (unsigned short) ival; + break; + } + + case 'i': {/* signed int */ + int *p = va_arg(*p_va, int *); + long ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else if (ival > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed integer is greater than maximum"); + RETURN_ERR_OCCURRED; + } + else if (ival < INT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed integer is less than minimum"); + RETURN_ERR_OCCURRED; + } + else + *p = ival; + break; + } + + case 'I': { /* int sized bitfield, both signed and + unsigned allowed */ + unsigned int *p = va_arg(*p_va, unsigned int *); + unsigned int ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = (unsigned int)PyLong_AsUnsignedLongMask(arg); + if (ival == (unsigned int)-1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = ival; + break; + } + + case 'n': /* Py_ssize_t */ + { + PyObject *iobj; + Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *); + Py_ssize_t ival = -1; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + iobj = PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + *p = ival; + break; + } + case 'l': {/* long int */ + long *p = va_arg(*p_va, long *); + long ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = PyLong_AsLong(arg); + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = ival; + break; + } + + case 'k': { /* long sized bitfield */ + unsigned long *p = va_arg(*p_va, unsigned long *); + unsigned long ival; + if (PyLong_Check(arg)) + ival = PyLong_AsUnsignedLongMask(arg); + else + return converterr("int", arg, msgbuf, bufsize); + *p = ival; + break; + } + + case 'L': {/* long long */ + long long *p = va_arg( *p_va, long long * ); + long long ival; + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + ival = PyLong_AsLongLong(arg); + if (ival == (long long)-1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = ival; + break; + } + + case 'K': { /* long long sized bitfield */ + unsigned long long *p = va_arg(*p_va, unsigned long long *); + unsigned long long ival; + if (PyLong_Check(arg)) + ival = PyLong_AsUnsignedLongLongMask(arg); + else + return converterr("int", arg, msgbuf, bufsize); + *p = ival; + break; + } + + case 'f': {/* float */ + float *p = va_arg(*p_va, float *); + double dval = PyFloat_AsDouble(arg); + if (dval == -1.0 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = (float) dval; + break; + } + + case 'd': {/* double */ + double *p = va_arg(*p_va, double *); + double dval = PyFloat_AsDouble(arg); + if (dval == -1.0 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = dval; + break; + } + + case 'D': {/* complex double */ + Py_complex *p = va_arg(*p_va, Py_complex *); + Py_complex cval; + cval = PyComplex_AsCComplex(arg); + if (PyErr_Occurred()) + RETURN_ERR_OCCURRED; + else + *p = cval; + break; + } + + case 'c': {/* char */ + char *p = va_arg(*p_va, char *); + if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) + *p = PyBytes_AS_STRING(arg)[0]; + else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1) + *p = PyByteArray_AS_STRING(arg)[0]; + else + return converterr("a byte string of length 1", arg, msgbuf, bufsize); + break; + } + + case 'C': {/* unicode char */ + int *p = va_arg(*p_va, int *); + int kind; + void *data; + + if (!PyUnicode_Check(arg)) + return converterr("a unicode character", arg, msgbuf, bufsize); + + if (PyUnicode_READY(arg)) + RETURN_ERR_OCCURRED; + + if (PyUnicode_GET_LENGTH(arg) != 1) + return converterr("a unicode character", arg, msgbuf, bufsize); + + kind = PyUnicode_KIND(arg); + data = PyUnicode_DATA(arg); + *p = PyUnicode_READ(kind, data, 0); + break; + } + + case 'p': {/* boolean *p*redicate */ + int *p = va_arg(*p_va, int *); + int val = PyObject_IsTrue(arg); + if (val > 0) + *p = 1; + else if (val == 0) + *p = 0; + else + RETURN_ERR_OCCURRED; + break; + } + + /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all + need to be cleaned up! */ + + case 'y': {/* any bytes-like object */ + void **p = (void **)va_arg(*p_va, char **); + const char *buf; + Py_ssize_t count; + if (*format == '*') { + if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) + return converterr(buf, arg, msgbuf, bufsize); + format++; + if (addcleanup(p, freelist, cleanup_buffer)) { + return converterr( + "(cleanup problem)", + arg, msgbuf, bufsize); + } + break; + } + count = convertbuffer(arg, (const void **)p, &buf); + if (count < 0) + return converterr(buf, arg, msgbuf, bufsize); + if (*format == '#') { + FETCH_SIZE; + STORE_SIZE(count); + format++; + } else { + if (strlen(*p) != (size_t)count) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); + RETURN_ERR_OCCURRED; + } + } + break; + } + + case 's': /* text string or bytes-like object */ + case 'z': /* text string, bytes-like object or None */ + { + if (*format == '*') { + /* "s*" or "z*" */ + Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *); + + if (c == 'z' && arg == Py_None) + PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0); + else if (PyUnicode_Check(arg)) { + Py_ssize_t len; + sarg = PyUnicode_AsUTF8AndSize(arg, &len); + if (sarg == NULL) + return converterr(CONV_UNICODE, + arg, msgbuf, bufsize); + PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0); + } + else { /* any bytes-like object */ + const char *buf; + if (getbuffer(arg, p, &buf) < 0) + return converterr(buf, arg, msgbuf, bufsize); + } + if (addcleanup(p, freelist, cleanup_buffer)) { + return converterr( + "(cleanup problem)", + arg, msgbuf, bufsize); + } + format++; + } else if (*format == '#') { /* a string or read-only bytes-like object */ + /* "s#" or "z#" */ + const void **p = (const void **)va_arg(*p_va, const char **); + FETCH_SIZE; + + if (c == 'z' && arg == Py_None) { + *p = NULL; + STORE_SIZE(0); + } + else if (PyUnicode_Check(arg)) { + Py_ssize_t len; + sarg = PyUnicode_AsUTF8AndSize(arg, &len); + if (sarg == NULL) + return converterr(CONV_UNICODE, + arg, msgbuf, bufsize); + *p = sarg; + STORE_SIZE(len); + } + else { /* read-only bytes-like object */ + /* XXX Really? */ + const char *buf; + Py_ssize_t count = convertbuffer(arg, p, &buf); + if (count < 0) + return converterr(buf, arg, msgbuf, bufsize); + STORE_SIZE(count); + } + format++; + } else { + /* "s" or "z" */ + const char **p = va_arg(*p_va, const char **); + Py_ssize_t len; + sarg = NULL; + + if (c == 'z' && arg == Py_None) + *p = NULL; + else if (PyUnicode_Check(arg)) { + sarg = PyUnicode_AsUTF8AndSize(arg, &len); + if (sarg == NULL) + return converterr(CONV_UNICODE, + arg, msgbuf, bufsize); + if (strlen(sarg) != (size_t)len) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + RETURN_ERR_OCCURRED; + } + *p = sarg; + } + else + return converterr(c == 'z' ? "str or None" : "str", + arg, msgbuf, bufsize); + } + break; + } + + case 'u': /* raw unicode buffer (Py_UNICODE *) */ + case 'Z': /* raw unicode buffer or None */ + { + Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); + + if (*format == '#') { + /* "u#" or "Z#" */ + FETCH_SIZE; + + if (c == 'Z' && arg == Py_None) { + *p = NULL; + STORE_SIZE(0); + } + else if (PyUnicode_Check(arg)) { + Py_ssize_t len; + *p = PyUnicode_AsUnicodeAndSize(arg, &len); + if (*p == NULL) + RETURN_ERR_OCCURRED; + STORE_SIZE(len); + } + else + return converterr(c == 'Z' ? "str or None" : "str", + arg, msgbuf, bufsize); + format++; + } else { + /* "u" or "Z" */ + if (c == 'Z' && arg == Py_None) + *p = NULL; + else if (PyUnicode_Check(arg)) { + Py_ssize_t len; + *p = PyUnicode_AsUnicodeAndSize(arg, &len); + if (*p == NULL) + RETURN_ERR_OCCURRED; + if (wcslen(*p) != (size_t)len) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + RETURN_ERR_OCCURRED; + } + } else + return converterr(c == 'Z' ? "str or None" : "str", + arg, msgbuf, bufsize); + } + break; + } + + case 'e': {/* encoded string */ + char **buffer; + const char *encoding; + PyObject *s; + int recode_strings; + Py_ssize_t size; + const char *ptr; + + /* Get 'e' parameter: the encoding name */ + encoding = (const char *)va_arg(*p_va, const char *); + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + + /* Get output buffer parameter: + 's' (recode all objects via Unicode) or + 't' (only recode non-string objects) + */ + if (*format == 's') + recode_strings = 1; + else if (*format == 't') + recode_strings = 0; + else + return converterr( + "(unknown parser marker combination)", + arg, msgbuf, bufsize); + buffer = (char **)va_arg(*p_va, char **); + format++; + if (buffer == NULL) + return converterr("(buffer is NULL)", + arg, msgbuf, bufsize); + + /* Encode object */ + if (!recode_strings && + (PyBytes_Check(arg) || PyByteArray_Check(arg))) { + s = arg; + Py_INCREF(s); + if (PyBytes_Check(arg)) { + size = PyBytes_GET_SIZE(s); + ptr = PyBytes_AS_STRING(s); + } + else { + size = PyByteArray_GET_SIZE(s); + ptr = PyByteArray_AS_STRING(s); + } + } + else if (PyUnicode_Check(arg)) { + /* Encode object; use default error handling */ + s = PyUnicode_AsEncodedString(arg, + encoding, + NULL); + if (s == NULL) + return converterr("(encoding failed)", + arg, msgbuf, bufsize); + assert(PyBytes_Check(s)); + size = PyBytes_GET_SIZE(s); + ptr = PyBytes_AS_STRING(s); + if (ptr == NULL) + ptr = ""; + } + else { + return converterr( + recode_strings ? "str" : "str, bytes or bytearray", + arg, msgbuf, bufsize); + } + + /* Write output; output is guaranteed to be 0-terminated */ + if (*format == '#') { + /* Using buffer length parameter '#': + + - if *buffer is NULL, a new buffer of the + needed size is allocated and the data + copied into it; *buffer is updated to point + to the new buffer; the caller is + responsible for PyMem_Free()ing it after + usage + + - if *buffer is not NULL, the data is + copied to *buffer; *buffer_len has to be + set to the size of the buffer on input; + buffer overflow is signalled with an error; + buffer has to provide enough room for the + encoded string plus the trailing 0-byte + + - in both cases, *buffer_len is updated to + the size of the buffer /excluding/ the + trailing 0-byte + + */ + int *q = NULL; Py_ssize_t *q2 = NULL; + if (flags & FLAG_SIZE_T) { + q2 = va_arg(*p_va, Py_ssize_t*); + } + else { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) + { + Py_DECREF(s); + return NULL; + } + q = va_arg(*p_va, int*); + } + + format++; + if (q == NULL && q2 == NULL) { + Py_DECREF(s); + return converterr( + "(buffer_len is NULL)", + arg, msgbuf, bufsize); + } + if (*buffer == NULL) { + *buffer = PyMem_NEW(char, size + 1); + if (*buffer == NULL) { + Py_DECREF(s); + PyErr_NoMemory(); + RETURN_ERR_OCCURRED; + } + if (addcleanup(*buffer, freelist, cleanup_ptr)) { + Py_DECREF(s); + return converterr( + "(cleanup problem)", + arg, msgbuf, bufsize); + } + } else { + if (size + 1 > BUFFER_LEN) { + Py_DECREF(s); + PyErr_Format(PyExc_ValueError, + "encoded string too long " + "(%zd, maximum length %zd)", + (Py_ssize_t)size, (Py_ssize_t)(BUFFER_LEN-1)); + RETURN_ERR_OCCURRED; + } + } + memcpy(*buffer, ptr, size+1); + + if (flags & FLAG_SIZE_T) { + *q2 = size; + } + else { + if (INT_MAX < size) { + Py_DECREF(s); + PyErr_SetString(PyExc_OverflowError, + "size does not fit in an int"); + return converterr("", arg, msgbuf, bufsize); + } + *q = (int)size; + } + } else { + /* Using a 0-terminated buffer: + + - the encoded string has to be 0-terminated + for this variant to work; if it is not, an + error raised + + - a new buffer of the needed size is + allocated and the data copied into it; + *buffer is updated to point to the new + buffer; the caller is responsible for + PyMem_Free()ing it after usage + + */ + if ((Py_ssize_t)strlen(ptr) != size) { + Py_DECREF(s); + return converterr( + "encoded string without null bytes", + arg, msgbuf, bufsize); + } + *buffer = PyMem_NEW(char, size + 1); + if (*buffer == NULL) { + Py_DECREF(s); + PyErr_NoMemory(); + RETURN_ERR_OCCURRED; + } + if (addcleanup(*buffer, freelist, cleanup_ptr)) { + Py_DECREF(s); + return converterr("(cleanup problem)", + arg, msgbuf, bufsize); + } + memcpy(*buffer, ptr, size+1); + } + Py_DECREF(s); + break; + } + + case 'S': { /* PyBytes object */ + PyObject **p = va_arg(*p_va, PyObject **); + if (PyBytes_Check(arg)) + *p = arg; + else + return converterr("bytes", arg, msgbuf, bufsize); + break; + } + + case 'Y': { /* PyByteArray object */ + PyObject **p = va_arg(*p_va, PyObject **); + if (PyByteArray_Check(arg)) + *p = arg; + else + return converterr("bytearray", arg, msgbuf, bufsize); + break; + } + + case 'U': { /* PyUnicode object */ + PyObject **p = va_arg(*p_va, PyObject **); + if (PyUnicode_Check(arg)) { + if (PyUnicode_READY(arg) == -1) + RETURN_ERR_OCCURRED; + *p = arg; + } + else + return converterr("str", arg, msgbuf, bufsize); + break; + } + + case 'O': { /* object */ + PyTypeObject *type; + PyObject **p; + if (*format == '!') { + type = va_arg(*p_va, PyTypeObject*); + p = va_arg(*p_va, PyObject **); + format++; + if (PyType_IsSubtype(arg->ob_type, type)) + *p = arg; + else + return converterr(type->tp_name, arg, msgbuf, bufsize); + + } + else if (*format == '&') { + typedef int (*converter)(PyObject *, void *); + converter convert = va_arg(*p_va, converter); + void *addr = va_arg(*p_va, void *); + int res; + format++; + if (! (res = (*convert)(arg, addr))) + return converterr("(unspecified)", + arg, msgbuf, bufsize); + if (res == Py_CLEANUP_SUPPORTED && + addcleanup(addr, freelist, convert) == -1) + return converterr("(cleanup problem)", + arg, msgbuf, bufsize); + } + else { + p = va_arg(*p_va, PyObject **); + *p = arg; + } + break; + } + + + case 'w': { /* "w*": memory buffer, read-write access */ + void **p = va_arg(*p_va, void **); + + if (*format != '*') + return converterr( + "(invalid use of 'w' format character)", + arg, msgbuf, bufsize); + format++; + + /* Caller is interested in Py_buffer, and the object + supports it directly. */ + if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) { + PyErr_Clear(); + return converterr("read-write bytes-like object", + arg, msgbuf, bufsize); + } + if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) { + PyBuffer_Release((Py_buffer*)p); + return converterr("contiguous buffer", arg, msgbuf, bufsize); + } + if (addcleanup(p, freelist, cleanup_buffer)) { + return converterr( + "(cleanup problem)", + arg, msgbuf, bufsize); + } + break; + } + + default: + return converterr("(impossible)", arg, msgbuf, bufsize); + + } + + *p_format = format; + return NULL; + +#undef FETCH_SIZE +#undef STORE_SIZE +#undef BUFFER_LEN +#undef RETURN_ERR_OCCURRED +} + +static Py_ssize_t +convertbuffer(PyObject *arg, const void **p, const char **errmsg) +{ + PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; + Py_ssize_t count; + Py_buffer view; + + *errmsg = NULL; + *p = NULL; + if (pb != NULL && pb->bf_releasebuffer != NULL) { + *errmsg = "read-only bytes-like object"; + return -1; + } + + if (getbuffer(arg, &view, errmsg) < 0) + return -1; + count = view.len; + *p = view.buf; + PyBuffer_Release(&view); + return count; +} + +static int +getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg) +{ + if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { + *errmsg = "bytes-like object"; + return -1; + } + if (!PyBuffer_IsContiguous(view, 'C')) { + PyBuffer_Release(view); + *errmsg = "contiguous buffer"; + return -1; + } + return 0; +} + +/* Support for keyword arguments donated by + Geoff Philbrick */ + +/* Return false (0) for error, else true. */ +int +PyArg_ParseTupleAndKeywords(PyObject *args, + PyObject *keywords, + const char *format, + char **kwlist, ...) +{ + int retval; + va_list va; + + if ((args == NULL || !PyTuple_Check(args)) || + (keywords != NULL && !PyDict_Check(keywords)) || + format == NULL || + kwlist == NULL) + { + PyErr_BadInternalCall(); + return 0; + } + + va_start(va, kwlist); + retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0); + va_end(va); + return retval; +} + +int +_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, + PyObject *keywords, + const char *format, + char **kwlist, ...) +{ + int retval; + va_list va; + + if ((args == NULL || !PyTuple_Check(args)) || + (keywords != NULL && !PyDict_Check(keywords)) || + format == NULL || + kwlist == NULL) + { + PyErr_BadInternalCall(); + return 0; + } + + va_start(va, kwlist); + retval = vgetargskeywords(args, keywords, format, + kwlist, &va, FLAG_SIZE_T); + va_end(va); + return retval; +} + + +int +PyArg_VaParseTupleAndKeywords(PyObject *args, + PyObject *keywords, + const char *format, + char **kwlist, va_list va) +{ + int retval; + va_list lva; + + if ((args == NULL || !PyTuple_Check(args)) || + (keywords != NULL && !PyDict_Check(keywords)) || + format == NULL || + kwlist == NULL) + { + PyErr_BadInternalCall(); + return 0; + } + + va_copy(lva, va); + + retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0); + va_end(lva); + return retval; +} + +int +_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, + PyObject *keywords, + const char *format, + char **kwlist, va_list va) +{ + int retval; + va_list lva; + + if ((args == NULL || !PyTuple_Check(args)) || + (keywords != NULL && !PyDict_Check(keywords)) || + format == NULL || + kwlist == NULL) + { + PyErr_BadInternalCall(); + return 0; + } + + va_copy(lva, va); + + retval = vgetargskeywords(args, keywords, format, + kwlist, &lva, FLAG_SIZE_T); + va_end(lva); + return retval; +} + +int +_PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, + struct _PyArg_Parser *parser, ...) +{ + int retval; + va_list va; + + va_start(va, parser); + retval = vgetargskeywordsfast(args, keywords, parser, &va, 0); + va_end(va); + return retval; +} + +int +_PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, + struct _PyArg_Parser *parser, ...) +{ + int retval; + va_list va; + + va_start(va, parser); + retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T); + va_end(va); + return retval; +} + +int +_PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, + struct _PyArg_Parser *parser, ...) +{ + int retval; + va_list va; + + va_start(va, parser); + retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0); + va_end(va); + return retval; +} + +int +_PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, + struct _PyArg_Parser *parser, ...) +{ + int retval; + va_list va; + + va_start(va, parser); + retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T); + va_end(va); + return retval; +} + + +int +_PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords, + struct _PyArg_Parser *parser, va_list va) +{ + int retval; + va_list lva; + + va_copy(lva, va); + + retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0); + va_end(lva); + return retval; +} + +int +_PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, + struct _PyArg_Parser *parser, va_list va) +{ + int retval; + va_list lva; + + va_copy(lva, va); + + retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T); + va_end(lva); + return retval; +} + +int +PyArg_ValidateKeywordArguments(PyObject *kwargs) +{ + if (!PyDict_Check(kwargs)) { + PyErr_BadInternalCall(); + return 0; + } + if (!_PyDict_HasOnlyStringKeys(kwargs)) { + PyErr_SetString(PyExc_TypeError, + "keywords must be strings"); + return 0; + } + return 1; +} + +#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':') + +static int +vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, + char **kwlist, va_list *p_va, int flags) +{ + char msgbuf[512]; + int levels[32]; + const char *fname, *msg, *custom_msg; + int min = INT_MAX; + int max = INT_MAX; + int i, pos, len; + int skip = 0; + Py_ssize_t nargs, nkwargs; + PyObject *current_arg; + freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; + freelist_t freelist; + + freelist.entries = static_entries; + freelist.first_available = 0; + freelist.entries_malloced = 0; + + assert(args != NULL && PyTuple_Check(args)); + assert(kwargs == NULL || PyDict_Check(kwargs)); + assert(format != NULL); + assert(kwlist != NULL); + assert(p_va != NULL); + + /* grab the function name or custom error msg first (mutually exclusive) */ + fname = strchr(format, ':'); + if (fname) { + fname++; + custom_msg = NULL; + } + else { + custom_msg = strchr(format,';'); + if (custom_msg) + custom_msg++; + } + + /* scan kwlist and count the number of positional-only parameters */ + for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) { + } + /* scan kwlist and get greatest possible nbr of args */ + for (len = pos; kwlist[len]; len++) { + if (!*kwlist[len]) { + PyErr_SetString(PyExc_SystemError, + "Empty keyword parameter name"); + return cleanreturn(0, &freelist); + } + } + + if (len > STATIC_FREELIST_ENTRIES) { + freelist.entries = PyMem_NEW(freelistentry_t, len); + if (freelist.entries == NULL) { + PyErr_NoMemory(); + return 0; + } + freelist.entries_malloced = 1; + } + + nargs = PyTuple_GET_SIZE(args); + nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); + if (nargs + nkwargs > len) { + /* Adding "keyword" (when nargs == 0) prevents producing wrong error + messages in some special cases (see bpo-31229). */ + PyErr_Format(PyExc_TypeError, + "%.200s%s takes at most %d %sargument%s (%zd given)", + (fname == NULL) ? "function" : fname, + (fname == NULL) ? "" : "()", + len, + (nargs == 0) ? "keyword " : "", + (len == 1) ? "" : "s", + nargs + nkwargs); + return cleanreturn(0, &freelist); + } + + /* convert tuple args and keyword args in same loop, using kwlist to drive process */ + for (i = 0; i < len; i++) { + if (*format == '|') { + if (min != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string (| specified twice)"); + return cleanreturn(0, &freelist); + } + + min = i; + format++; + + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ before |)"); + return cleanreturn(0, &freelist); + } + } + if (*format == '$') { + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ specified twice)"); + return cleanreturn(0, &freelist); + } + + max = i; + format++; + + if (max < pos) { + PyErr_SetString(PyExc_SystemError, + "Empty parameter name after $"); + return cleanreturn(0, &freelist); + } + if (skip) { + /* Now we know the minimal and the maximal numbers of + * positional arguments and can raise an exception with + * informative message (see below). */ + break; + } + if (max < nargs) { + if (max == 0) { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes no positional arguments", + (fname == NULL) ? "function" : fname, + (fname == NULL) ? "" : "()"); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes %s %d positional argument%s" + " (%zd given)", + (fname == NULL) ? "function" : fname, + (fname == NULL) ? "" : "()", + (min != INT_MAX) ? "at most" : "exactly", + max, + max == 1 ? "" : "s", + nargs); + } + return cleanreturn(0, &freelist); + } + } + if (IS_END_OF_FORMAT(*format)) { + PyErr_Format(PyExc_SystemError, + "More keyword list entries (%d) than " + "format specifiers (%d)", len, i); + return cleanreturn(0, &freelist); + } + if (!skip) { + if (i < nargs) { + current_arg = PyTuple_GET_ITEM(args, i); + } + else if (nkwargs && i >= pos) { + current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); + if (current_arg) { + --nkwargs; + } + else if (PyErr_Occurred()) { + return cleanreturn(0, &freelist); + } + } + else { + current_arg = NULL; + } + + if (current_arg) { + msg = convertitem(current_arg, &format, p_va, flags, + levels, msgbuf, sizeof(msgbuf), &freelist); + if (msg) { + seterror(i+1, msg, levels, fname, custom_msg); + return cleanreturn(0, &freelist); + } + continue; + } + + if (i < min) { + if (i < pos) { + assert (min == INT_MAX); + assert (max == INT_MAX); + skip = 1; + /* At that moment we still don't know the minimal and + * the maximal numbers of positional arguments. Raising + * an exception is deferred until we encounter | and $ + * or the end of the format. */ + } + else { + PyErr_Format(PyExc_TypeError, "%.200s%s missing required " + "argument '%s' (pos %d)", + (fname == NULL) ? "function" : fname, + (fname == NULL) ? "" : "()", + kwlist[i], i+1); + return cleanreturn(0, &freelist); + } + } + /* current code reports success when all required args + * fulfilled and no keyword args left, with no further + * validation. XXX Maybe skip this in debug build ? + */ + if (!nkwargs && !skip) { + return cleanreturn(1, &freelist); + } + } + + /* We are into optional args, skip through to any remaining + * keyword args */ + msg = skipitem(&format, p_va, flags); + if (msg) { + PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, + format); + return cleanreturn(0, &freelist); + } + } + + if (skip) { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes %s %d positional argument%s" + " (%zd given)", + (fname == NULL) ? "function" : fname, + (fname == NULL) ? "" : "()", + (Py_MIN(pos, min) < i) ? "at least" : "exactly", + Py_MIN(pos, min), + Py_MIN(pos, min) == 1 ? "" : "s", + nargs); + return cleanreturn(0, &freelist); + } + + if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + PyErr_Format(PyExc_SystemError, + "more argument specifiers than keyword list entries " + "(remaining format:'%s')", format); + return cleanreturn(0, &freelist); + } + + if (nkwargs > 0) { + PyObject *key; + Py_ssize_t j; + /* make sure there are no arguments given by name and position */ + for (i = pos; i < nargs; i++) { + current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]); + if (current_arg) { + /* arg present in tuple and in dict */ + PyErr_Format(PyExc_TypeError, + "argument for %.200s%s given by name ('%s') " + "and position (%d)", + (fname == NULL) ? "function" : fname, + (fname == NULL) ? "" : "()", + kwlist[i], i+1); + return cleanreturn(0, &freelist); + } + else if (PyErr_Occurred()) { + return cleanreturn(0, &freelist); + } + } + /* make sure there are no extraneous keyword arguments */ + j = 0; + while (PyDict_Next(kwargs, &j, &key, NULL)) { + int match = 0; + if (!PyUnicode_Check(key)) { + PyErr_SetString(PyExc_TypeError, + "keywords must be strings"); + return cleanreturn(0, &freelist); + } + for (i = pos; i < len; i++) { + if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) { + match = 1; + break; + } + } + if (!match) { + PyErr_Format(PyExc_TypeError, + "'%U' is an invalid keyword " + "argument for %.200s%s", + key, + (fname == NULL) ? "this function" : fname, + (fname == NULL) ? "" : "()"); + return cleanreturn(0, &freelist); + } + } + } + + return cleanreturn(1, &freelist); +} + + +/* List of static parsers. */ +static struct _PyArg_Parser *static_arg_parsers = NULL; + +static int +parser_init(struct _PyArg_Parser *parser) +{ + const char * const *keywords; + const char *format, *msg; + int i, len, min, max, nkw; + PyObject *kwtuple; + + assert(parser->keywords != NULL); + if (parser->kwtuple != NULL) { + return 1; + } + + keywords = parser->keywords; + /* scan keywords and count the number of positional-only parameters */ + for (i = 0; keywords[i] && !*keywords[i]; i++) { + } + parser->pos = i; + /* scan keywords and get greatest possible nbr of args */ + for (; keywords[i]; i++) { + if (!*keywords[i]) { + PyErr_SetString(PyExc_SystemError, + "Empty keyword parameter name"); + return 0; + } + } + len = i; + + format = parser->format; + if (format) { + /* grab the function name or custom error msg first (mutually exclusive) */ + parser->fname = strchr(parser->format, ':'); + if (parser->fname) { + parser->fname++; + parser->custom_msg = NULL; + } + else { + parser->custom_msg = strchr(parser->format,';'); + if (parser->custom_msg) + parser->custom_msg++; + } + + min = max = INT_MAX; + for (i = 0; i < len; i++) { + if (*format == '|') { + if (min != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string (| specified twice)"); + return 0; + } + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ before |)"); + return 0; + } + min = i; + format++; + } + if (*format == '$') { + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ specified twice)"); + return 0; + } + if (i < parser->pos) { + PyErr_SetString(PyExc_SystemError, + "Empty parameter name after $"); + return 0; + } + max = i; + format++; + } + if (IS_END_OF_FORMAT(*format)) { + PyErr_Format(PyExc_SystemError, + "More keyword list entries (%d) than " + "format specifiers (%d)", len, i); + return 0; + } + + msg = skipitem(&format, NULL, 0); + if (msg) { + PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, + format); + return 0; + } + } + parser->min = Py_MIN(min, len); + parser->max = Py_MIN(max, len); + + if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + PyErr_Format(PyExc_SystemError, + "more argument specifiers than keyword list entries " + "(remaining format:'%s')", format); + return 0; + } + } + + nkw = len - parser->pos; + kwtuple = PyTuple_New(nkw); + if (kwtuple == NULL) { + return 0; + } + keywords = parser->keywords + parser->pos; + for (i = 0; i < nkw; i++) { + PyObject *str = PyUnicode_FromString(keywords[i]); + if (str == NULL) { + Py_DECREF(kwtuple); + return 0; + } + PyUnicode_InternInPlace(&str); + PyTuple_SET_ITEM(kwtuple, i, str); + } + parser->kwtuple = kwtuple; + + assert(parser->next == NULL); + parser->next = static_arg_parsers; + static_arg_parsers = parser; + return 1; +} + +static void +parser_clear(struct _PyArg_Parser *parser) +{ + Py_CLEAR(parser->kwtuple); +} + +static PyObject* +find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key) +{ + Py_ssize_t i, nkwargs; + + nkwargs = PyTuple_GET_SIZE(kwnames); + for (i=0; i < nkwargs; i++) { + PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); + + /* ptr==ptr should match in most cases since keyword keys + should be interned strings */ + if (kwname == key) { + return kwstack[i]; + } + if (!PyUnicode_Check(kwname)) { + /* ignore non-string keyword keys: + an error will be raised below */ + continue; + } + if (_PyUnicode_EQ(kwname, key)) { + return kwstack[i]; + } + } + return NULL; +} + +static int +vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + va_list *p_va, int flags) +{ + PyObject *kwtuple; + char msgbuf[512]; + int levels[32]; + const char *format; + const char *msg; + PyObject *keyword; + int i, pos, len; + Py_ssize_t nkwargs; + PyObject *current_arg; + freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; + freelist_t freelist; + PyObject *const *kwstack = NULL; + + freelist.entries = static_entries; + freelist.first_available = 0; + freelist.entries_malloced = 0; + + assert(kwargs == NULL || PyDict_Check(kwargs)); + assert(kwargs == NULL || kwnames == NULL); + assert(p_va != NULL); + + if (parser == NULL) { + PyErr_BadInternalCall(); + return 0; + } + + if (kwnames != NULL && !PyTuple_Check(kwnames)) { + PyErr_BadInternalCall(); + return 0; + } + + if (!parser_init(parser)) { + return 0; + } + + kwtuple = parser->kwtuple; + pos = parser->pos; + len = pos + (int)PyTuple_GET_SIZE(kwtuple); + + if (len > STATIC_FREELIST_ENTRIES) { + freelist.entries = PyMem_NEW(freelistentry_t, len); + if (freelist.entries == NULL) { + PyErr_NoMemory(); + return 0; + } + freelist.entries_malloced = 1; + } + + if (kwargs != NULL) { + nkwargs = PyDict_GET_SIZE(kwargs); + } + else if (kwnames != NULL) { + nkwargs = PyTuple_GET_SIZE(kwnames); + kwstack = args + nargs; + } + else { + nkwargs = 0; + } + if (nargs + nkwargs > len) { + /* Adding "keyword" (when nargs == 0) prevents producing wrong error + messages in some special cases (see bpo-31229). */ + PyErr_Format(PyExc_TypeError, + "%.200s%s takes at most %d %sargument%s (%zd given)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + len, + (nargs == 0) ? "keyword " : "", + (len == 1) ? "" : "s", + nargs + nkwargs); + return cleanreturn(0, &freelist); + } + if (parser->max < nargs) { + if (parser->max == 0) { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes no positional arguments", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()"); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes %s %d positional argument%s (%zd given)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + (parser->min < parser->max) ? "at most" : "exactly", + parser->max, + parser->max == 1 ? "" : "s", + nargs); + } + return cleanreturn(0, &freelist); + } + + format = parser->format; + /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ + for (i = 0; i < len; i++) { + if (*format == '|') { + format++; + } + if (*format == '$') { + format++; + } + assert(!IS_END_OF_FORMAT(*format)); + + if (i < nargs) { + current_arg = args[i]; + } + else if (nkwargs && i >= pos) { + keyword = PyTuple_GET_ITEM(kwtuple, i - pos); + if (kwargs != NULL) { + current_arg = PyDict_GetItemWithError(kwargs, keyword); + if (!current_arg && PyErr_Occurred()) { + return cleanreturn(0, &freelist); + } + } + else { + current_arg = find_keyword(kwnames, kwstack, keyword); + } + if (current_arg) { + --nkwargs; + } + } + else { + current_arg = NULL; + } + + if (current_arg) { + msg = convertitem(current_arg, &format, p_va, flags, + levels, msgbuf, sizeof(msgbuf), &freelist); + if (msg) { + seterror(i+1, msg, levels, parser->fname, parser->custom_msg); + return cleanreturn(0, &freelist); + } + continue; + } + + if (i < parser->min) { + /* Less arguments than required */ + if (i < pos) { + Py_ssize_t min = Py_MIN(pos, parser->min); + PyErr_Format(PyExc_TypeError, + "%.200s%s takes %s %d positional argument%s" + " (%zd given)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + min < parser->max ? "at least" : "exactly", + min, + min == 1 ? "" : "s", + nargs); + } + else { + keyword = PyTuple_GET_ITEM(kwtuple, i - pos); + PyErr_Format(PyExc_TypeError, "%.200s%s missing required " + "argument '%U' (pos %d)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + keyword, i+1); + } + return cleanreturn(0, &freelist); + } + /* current code reports success when all required args + * fulfilled and no keyword args left, with no further + * validation. XXX Maybe skip this in debug build ? + */ + if (!nkwargs) { + return cleanreturn(1, &freelist); + } + + /* We are into optional args, skip through to any remaining + * keyword args */ + msg = skipitem(&format, p_va, flags); + assert(msg == NULL); + } + + assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$')); + + if (nkwargs > 0) { + Py_ssize_t j; + /* make sure there are no arguments given by name and position */ + for (i = pos; i < nargs; i++) { + keyword = PyTuple_GET_ITEM(kwtuple, i - pos); + if (kwargs != NULL) { + current_arg = PyDict_GetItemWithError(kwargs, keyword); + if (!current_arg && PyErr_Occurred()) { + return cleanreturn(0, &freelist); + } + } + else { + current_arg = find_keyword(kwnames, kwstack, keyword); + } + if (current_arg) { + /* arg present in tuple and in dict */ + PyErr_Format(PyExc_TypeError, + "argument for %.200s%s given by name ('%U') " + "and position (%d)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + keyword, i+1); + return cleanreturn(0, &freelist); + } + } + /* make sure there are no extraneous keyword arguments */ + j = 0; + while (1) { + int match; + if (kwargs != NULL) { + if (!PyDict_Next(kwargs, &j, &keyword, NULL)) + break; + } + else { + if (j >= PyTuple_GET_SIZE(kwnames)) + break; + keyword = PyTuple_GET_ITEM(kwnames, j); + j++; + } + + if (!PyUnicode_Check(keyword)) { + PyErr_SetString(PyExc_TypeError, + "keywords must be strings"); + return cleanreturn(0, &freelist); + } + match = PySequence_Contains(kwtuple, keyword); + if (match <= 0) { + if (!match) { + PyErr_Format(PyExc_TypeError, + "'%U' is an invalid keyword " + "argument for %.200s%s", + keyword, + (parser->fname == NULL) ? "this function" : parser->fname, + (parser->fname == NULL) ? "" : "()"); + } + return cleanreturn(0, &freelist); + } + } + } + + return cleanreturn(1, &freelist); +} + +static int +vgetargskeywordsfast(PyObject *args, PyObject *keywords, + struct _PyArg_Parser *parser, va_list *p_va, int flags) +{ + PyObject **stack; + Py_ssize_t nargs; + + if (args == NULL + || !PyTuple_Check(args) + || (keywords != NULL && !PyDict_Check(keywords))) + { + PyErr_BadInternalCall(); + return 0; + } + + stack = _PyTuple_ITEMS(args); + nargs = PyTuple_GET_SIZE(args); + return vgetargskeywordsfast_impl(stack, nargs, keywords, NULL, + parser, p_va, flags); +} + + +#undef _PyArg_UnpackKeywords + +PyObject * const * +_PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, int maxpos, int minkw, + PyObject **buf) +{ + PyObject *kwtuple; + PyObject *keyword; + int i, posonly, minposonly, maxargs; + int reqlimit = minkw ? maxpos + minkw : minpos; + Py_ssize_t nkwargs; + PyObject *current_arg; + PyObject * const *kwstack = NULL; + + assert(kwargs == NULL || PyDict_Check(kwargs)); + assert(kwargs == NULL || kwnames == NULL); + + if (parser == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + if (kwnames != NULL && !PyTuple_Check(kwnames)) { + PyErr_BadInternalCall(); + return NULL; + } + + if (args == NULL && nargs == 0) { + args = buf; + } + + if (!parser_init(parser)) { + return NULL; + } + + kwtuple = parser->kwtuple; + posonly = parser->pos; + minposonly = Py_MIN(posonly, minpos); + maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple); + + if (kwargs != NULL) { + nkwargs = PyDict_GET_SIZE(kwargs); + } + else if (kwnames != NULL) { + nkwargs = PyTuple_GET_SIZE(kwnames); + kwstack = args + nargs; + } + else { + nkwargs = 0; + } + if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) { + /* Fast path. */ + return args; + } + if (nargs + nkwargs > maxargs) { + /* Adding "keyword" (when nargs == 0) prevents producing wrong error + messages in some special cases (see bpo-31229). */ + PyErr_Format(PyExc_TypeError, + "%.200s%s takes at most %d %sargument%s (%zd given)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + maxargs, + (nargs == 0) ? "keyword " : "", + (maxargs == 1) ? "" : "s", + nargs + nkwargs); + return NULL; + } + if (nargs > maxpos) { + if (maxpos == 0) { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes no positional arguments", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()"); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes %s %d positional argument%s (%zd given)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + (minpos < maxpos) ? "at most" : "exactly", + maxpos, + (maxpos == 1) ? "" : "s", + nargs); + } + return NULL; + } + if (nargs < minposonly) { + PyErr_Format(PyExc_TypeError, + "%.200s%s takes %s %d positional argument%s" + " (%zd given)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + minposonly < maxpos ? "at least" : "exactly", + minposonly, + minposonly == 1 ? "" : "s", + nargs); + return NULL; + } + + /* copy tuple args */ + for (i = 0; i < nargs; i++) { + buf[i] = args[i]; + } + + /* copy keyword args using kwtuple to drive process */ + for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) { + if (nkwargs) { + keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); + if (kwargs != NULL) { + current_arg = PyDict_GetItemWithError(kwargs, keyword); + if (!current_arg && PyErr_Occurred()) { + return NULL; + } + } + else { + current_arg = find_keyword(kwnames, kwstack, keyword); + } + } + else if (i >= reqlimit) { + break; + } + else { + current_arg = NULL; + } + + buf[i] = current_arg; + + if (current_arg) { + --nkwargs; + } + else if (i < minpos || (maxpos <= i && i < reqlimit)) { + /* Less arguments than required */ + keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); + PyErr_Format(PyExc_TypeError, "%.200s%s missing required " + "argument '%U' (pos %d)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + keyword, i+1); + return NULL; + } + } + + if (nkwargs > 0) { + Py_ssize_t j; + /* make sure there are no arguments given by name and position */ + for (i = posonly; i < nargs; i++) { + keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); + if (kwargs != NULL) { + current_arg = PyDict_GetItemWithError(kwargs, keyword); + if (!current_arg && PyErr_Occurred()) { + return NULL; + } + } + else { + current_arg = find_keyword(kwnames, kwstack, keyword); + } + if (current_arg) { + /* arg present in tuple and in dict */ + PyErr_Format(PyExc_TypeError, + "argument for %.200s%s given by name ('%U') " + "and position (%d)", + (parser->fname == NULL) ? "function" : parser->fname, + (parser->fname == NULL) ? "" : "()", + keyword, i+1); + return NULL; + } + } + /* make sure there are no extraneous keyword arguments */ + j = 0; + while (1) { + int match; + if (kwargs != NULL) { + if (!PyDict_Next(kwargs, &j, &keyword, NULL)) + break; + } + else { + if (j >= PyTuple_GET_SIZE(kwnames)) + break; + keyword = PyTuple_GET_ITEM(kwnames, j); + j++; + } + + if (!PyUnicode_Check(keyword)) { + PyErr_SetString(PyExc_TypeError, + "keywords must be strings"); + return NULL; + } + match = PySequence_Contains(kwtuple, keyword); + if (match <= 0) { + if (!match) { + PyErr_Format(PyExc_TypeError, + "'%U' is an invalid keyword " + "argument for %.200s%s", + keyword, + (parser->fname == NULL) ? "this function" : parser->fname, + (parser->fname == NULL) ? "" : "()"); + } + return NULL; + } + } + } + + return buf; +} + + +static const char * +skipitem(const char **p_format, va_list *p_va, int flags) +{ + const char *format = *p_format; + char c = *format++; + + switch (c) { + + /* + * codes that take a single data pointer as an argument + * (the type of the pointer is irrelevant) + */ + + case 'b': /* byte -- very short int */ + case 'B': /* byte as bitfield */ + case 'h': /* short int */ + case 'H': /* short int as bitfield */ + case 'i': /* int */ + case 'I': /* int sized bitfield */ + case 'l': /* long int */ + case 'k': /* long int sized bitfield */ + case 'L': /* long long */ + case 'K': /* long long sized bitfield */ + case 'n': /* Py_ssize_t */ + case 'f': /* float */ + case 'd': /* double */ + case 'D': /* complex double */ + case 'c': /* char */ + case 'C': /* unicode char */ + case 'p': /* boolean predicate */ + case 'S': /* string object */ + case 'Y': /* string object */ + case 'U': /* unicode string object */ + { + if (p_va != NULL) { + (void) va_arg(*p_va, void *); + } + break; + } + + /* string codes */ + + case 'e': /* string with encoding */ + { + if (p_va != NULL) { + (void) va_arg(*p_va, const char *); + } + if (!(*format == 's' || *format == 't')) + /* after 'e', only 's' and 't' is allowed */ + goto err; + format++; + } + /* fall through */ + + case 's': /* string */ + case 'z': /* string or None */ + case 'y': /* bytes */ + case 'u': /* unicode string */ + case 'Z': /* unicode string or None */ + case 'w': /* buffer, read-write */ + { + if (p_va != NULL) { + (void) va_arg(*p_va, char **); + } + if (*format == '#') { + if (p_va != NULL) { + if (flags & FLAG_SIZE_T) + (void) va_arg(*p_va, Py_ssize_t *); + else { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { + return NULL; + } + (void) va_arg(*p_va, int *); + } + } + format++; + } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w') + && *format == '*') + { + format++; + } + break; + } + + case 'O': /* object */ + { + if (*format == '!') { + format++; + if (p_va != NULL) { + (void) va_arg(*p_va, PyTypeObject*); + (void) va_arg(*p_va, PyObject **); + } + } + else if (*format == '&') { + typedef int (*converter)(PyObject *, void *); + if (p_va != NULL) { + (void) va_arg(*p_va, converter); + (void) va_arg(*p_va, void *); + } + format++; + } + else { + if (p_va != NULL) { + (void) va_arg(*p_va, PyObject **); + } + } + break; + } + + case '(': /* bypass tuple, not handled at all previously */ + { + const char *msg; + for (;;) { + if (*format==')') + break; + if (IS_END_OF_FORMAT(*format)) + return "Unmatched left paren in format " + "string"; + msg = skipitem(&format, p_va, flags); + if (msg) + return msg; + } + format++; + break; + } + + case ')': + return "Unmatched right paren in format string"; + + default: +err: + return "impossible"; + + } + + *p_format = format; + return NULL; +} + + +#undef _PyArg_CheckPositional + +int +_PyArg_CheckPositional(const char *name, Py_ssize_t nargs, + Py_ssize_t min, Py_ssize_t max) +{ + assert(min >= 0); + assert(min <= max); + + if (nargs < min) { + if (name != NULL) + PyErr_Format( + PyExc_TypeError, + "%.200s expected %s%zd argument%s, got %zd", + name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); + else + PyErr_Format( + PyExc_TypeError, + "unpacked tuple should have %s%zd element%s," + " but has %zd", + (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); + return 0; + } + + if (nargs == 0) { + return 1; + } + + if (nargs > max) { + if (name != NULL) + PyErr_Format( + PyExc_TypeError, + "%.200s expected %s%zd argument%s, got %zd", + name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); + else + PyErr_Format( + PyExc_TypeError, + "unpacked tuple should have %s%zd element%s," + " but has %zd", + (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); + return 0; + } + + return 1; +} + +static int +unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name, + Py_ssize_t min, Py_ssize_t max, va_list vargs) +{ + Py_ssize_t i; + PyObject **o; + + if (!_PyArg_CheckPositional(name, nargs, min, max)) { + return 0; + } + + for (i = 0; i < nargs; i++) { + o = va_arg(vargs, PyObject **); + *o = args[i]; + } + return 1; +} + +int +PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) +{ + PyObject **stack; + Py_ssize_t nargs; + int retval; + va_list vargs; + + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, + "PyArg_UnpackTuple() argument list is not a tuple"); + return 0; + } + stack = _PyTuple_ITEMS(args); + nargs = PyTuple_GET_SIZE(args); + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, max); +#else + va_start(vargs); +#endif + retval = unpack_stack(stack, nargs, name, min, max, vargs); + va_end(vargs); + return retval; +} + +int +_PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name, + Py_ssize_t min, Py_ssize_t max, ...) +{ + int retval; + va_list vargs; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, max); +#else + va_start(vargs); +#endif + retval = unpack_stack(args, nargs, name, min, max, vargs); + va_end(vargs); + return retval; +} + + +#undef _PyArg_NoKeywords +#undef _PyArg_NoPositional + +/* For type constructors that don't take keyword args + * + * Sets a TypeError and returns 0 if the args/kwargs is + * not empty, returns 1 otherwise + */ +int +_PyArg_NoKeywords(const char *funcname, PyObject *kwargs) +{ + if (kwargs == NULL) { + return 1; + } + if (!PyDict_CheckExact(kwargs)) { + PyErr_BadInternalCall(); + return 0; + } + if (PyDict_GET_SIZE(kwargs) == 0) { + return 1; + } + + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + funcname); + return 0; +} + + +int +_PyArg_NoPositional(const char *funcname, PyObject *args) +{ + if (args == NULL) + return 1; + if (!PyTuple_CheckExact(args)) { + PyErr_BadInternalCall(); + return 0; + } + if (PyTuple_GET_SIZE(args) == 0) + return 1; + + PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments", + funcname); + return 0; +} + +void +_PyArg_Fini(void) +{ + struct _PyArg_Parser *tmp, *s = static_arg_parsers; + while (s) { + tmp = s->next; + s->next = NULL; + parser_clear(s); + s = tmp; + } + static_arg_parsers = NULL; +} + +#ifdef __cplusplus +}; +#endif diff --git a/python/Python/getcompiler.c b/python/Python/getcompiler.c new file mode 100755 index 0000000..59c0dbf --- /dev/null +++ b/python/Python/getcompiler.c @@ -0,0 +1,27 @@ + +/* Return the compiler identification, if possible. */ + +#include "Python.h" + +#ifndef COMPILER + +// Note the __clang__ conditional has to come before the __GNUC__ one because +// clang pretends to be GCC. +#if defined(__clang__) +#define COMPILER "\n[Clang " __clang_version__ "]" +#elif defined(__GNUC__) +#define COMPILER "\n[GCC " __VERSION__ "]" +// Generic fallbacks. +#elif defined(__cplusplus) +#define COMPILER "[C++]" +#else +#define COMPILER "[C]" +#endif + +#endif /* !COMPILER */ + +const char * +Py_GetCompiler(void) +{ + return COMPILER; +} diff --git a/python/Python/getcopyright.c b/python/Python/getcopyright.c new file mode 100755 index 0000000..7fdeb31 --- /dev/null +++ b/python/Python/getcopyright.c @@ -0,0 +1,23 @@ +/* Return the copyright string. This is updated manually. */ + +#include "Python.h" + +static const char cprt[] = +"\ +Copyright (c) 2001-2021 Python Software Foundation.\n\ +All Rights Reserved.\n\ +\n\ +Copyright (c) 2000 BeOpen.com.\n\ +All Rights Reserved.\n\ +\n\ +Copyright (c) 1995-2001 Corporation for National Research Initiatives.\n\ +All Rights Reserved.\n\ +\n\ +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\n\ +All Rights Reserved."; + +const char * +Py_GetCopyright(void) +{ + return cprt; +} diff --git a/python/Python/getopt.c b/python/Python/getopt.c new file mode 100755 index 0000000..249ad1e --- /dev/null +++ b/python/Python/getopt.c @@ -0,0 +1,179 @@ +/*---------------------------------------------------------------------------* + * + * + * C++ Library + * + * Copyright 1992-1994, David Gottner + * + * 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, this permission notice and + * the following disclaimer notice appear unmodified in all copies. + * + * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL I + * 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. + * + * Nevertheless, I would like to know about bugs in this library or + * suggestions for improvment. Send bug reports and feedback to + * davegottner@delphi.com. + *---------------------------------------------------------------------------*/ + +/* Modified to support --help and --version, as well as /? on Windows + * by Georg Brandl. */ + +#include +#include +#include +#include +#include "pycore_getopt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int _PyOS_opterr = 1; /* generate error messages */ +Py_ssize_t _PyOS_optind = 1; /* index into argv array */ +const wchar_t *_PyOS_optarg = NULL; /* optional argument */ + +static const wchar_t *opt_ptr = L""; + +/* Python command line short and long options */ + +#define SHORT_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?" + +static const _PyOS_LongOption longopts[] = { + {L"check-hash-based-pycs", 1, 0}, + {NULL, 0, 0}, +}; + + +void _PyOS_ResetGetOpt(void) +{ + _PyOS_opterr = 1; + _PyOS_optind = 1; + _PyOS_optarg = NULL; + opt_ptr = L""; +} + +int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex) +{ + wchar_t *ptr; + wchar_t option; + + if (*opt_ptr == '\0') { + + if (_PyOS_optind >= argc) + return -1; +#ifdef MS_WINDOWS + else if (wcscmp(argv[_PyOS_optind], L"/?") == 0) { + ++_PyOS_optind; + return 'h'; + } +#endif + + else if (argv[_PyOS_optind][0] != L'-' || + argv[_PyOS_optind][1] == L'\0' /* lone dash */ ) + return -1; + + else if (wcscmp(argv[_PyOS_optind], L"--") == 0) { + ++_PyOS_optind; + return -1; + } + + else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) { + ++_PyOS_optind; + return 'h'; + } + + else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) { + ++_PyOS_optind; + return 'V'; + } + + opt_ptr = &argv[_PyOS_optind++][1]; + } + + if ((option = *opt_ptr++) == L'\0') + return -1; + + if (option == L'-') { + // Parse long option. + if (*opt_ptr == L'\0') { + if (_PyOS_opterr) { + fprintf(stderr, "expected long option\n"); + } + return -1; + } + *longindex = 0; + const _PyOS_LongOption *opt; + for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) { + if (!wcscmp(opt->name, opt_ptr)) + break; + } + if (!opt->name) { + if (_PyOS_opterr) { + fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]); + } + return '_'; + } + opt_ptr = L""; + if (!opt->has_arg) { + return opt->val; + } + if (_PyOS_optind >= argc) { + if (_PyOS_opterr) { + fprintf(stderr, "Argument expected for the %ls options\n", + argv[_PyOS_optind - 1]); + } + return '_'; + } + _PyOS_optarg = argv[_PyOS_optind++]; + return opt->val; + } + + if (option == 'J') { + if (_PyOS_opterr) { + fprintf(stderr, "-J is reserved for Jython\n"); + } + return '_'; + } + + if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) { + if (_PyOS_opterr) { + fprintf(stderr, "Unknown option: -%c\n", (char)option); + } + return '_'; + } + + if (*(ptr + 1) == L':') { + if (*opt_ptr != L'\0') { + _PyOS_optarg = opt_ptr; + opt_ptr = L""; + } + + else { + if (_PyOS_optind >= argc) { + if (_PyOS_opterr) { + fprintf(stderr, + "Argument expected for the -%c option\n", (char)option); + } + return '_'; + } + + _PyOS_optarg = argv[_PyOS_optind++]; + } + } + + return option; +} + +#ifdef __cplusplus +} +#endif + diff --git a/python/Python/getplatform.c b/python/Python/getplatform.c new file mode 100755 index 0000000..81a0f7a --- /dev/null +++ b/python/Python/getplatform.c @@ -0,0 +1,12 @@ + +#include "Python.h" + +#ifndef PLATFORM +#define PLATFORM "unknown" +#endif + +const char * +Py_GetPlatform(void) +{ + return PLATFORM; +} diff --git a/python/Python/getversion.c b/python/Python/getversion.c new file mode 100755 index 0000000..c32b6f9 --- /dev/null +++ b/python/Python/getversion.c @@ -0,0 +1,15 @@ + +/* Return the full version string. */ + +#include "Python.h" + +#include "patchlevel.h" + +const char * +Py_GetVersion(void) +{ + static char version[250]; + PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s", + PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler()); + return version; +} diff --git a/python/Python/graminit.c b/python/Python/graminit.c new file mode 100755 index 0000000..7c40ce9 --- /dev/null +++ b/python/Python/graminit.c @@ -0,0 +1,2701 @@ +/* Generated by Parser/pgen */ + +#include "grammar.h" +grammar _PyParser_Grammar; +static const arc arcs_0_0[3] = { + {2, 1}, + {3, 2}, + {4, 1}, +}; +static const arc arcs_0_1[1] = { + {0, 1}, +}; +static const arc arcs_0_2[1] = { + {2, 1}, +}; +static state states_0[3] = { + {3, arcs_0_0}, + {1, arcs_0_1}, + {1, arcs_0_2}, +}; +static const arc arcs_1_0[3] = { + {44, 1}, + {2, 0}, + {45, 0}, +}; +static const arc arcs_1_1[1] = { + {0, 1}, +}; +static state states_1[2] = { + {3, arcs_1_0}, + {1, arcs_1_1}, +}; +static const arc arcs_2_0[1] = { + {47, 1}, +}; +static const arc arcs_2_1[2] = { + {44, 2}, + {2, 1}, +}; +static const arc arcs_2_2[1] = { + {0, 2}, +}; +static state states_2[3] = { + {1, arcs_2_0}, + {2, arcs_2_1}, + {1, arcs_2_2}, +}; +static const arc arcs_3_0[1] = { + {10, 1}, +}; +static const arc arcs_3_1[1] = { + {49, 2}, +}; +static const arc arcs_3_2[2] = { + {5, 3}, + {2, 4}, +}; +static const arc arcs_3_3[2] = { + {50, 5}, + {51, 6}, +}; +static const arc arcs_3_4[1] = { + {0, 4}, +}; +static const arc arcs_3_5[1] = { + {2, 4}, +}; +static const arc arcs_3_6[1] = { + {50, 5}, +}; +static state states_3[7] = { + {1, arcs_3_0}, + {1, arcs_3_1}, + {2, arcs_3_2}, + {2, arcs_3_3}, + {1, arcs_3_4}, + {1, arcs_3_5}, + {1, arcs_3_6}, +}; +static const arc arcs_4_0[1] = { + {48, 1}, +}; +static const arc arcs_4_1[2] = { + {48, 1}, + {0, 1}, +}; +static state states_4[2] = { + {1, arcs_4_0}, + {2, arcs_4_1}, +}; +static const arc arcs_5_0[1] = { + {52, 1}, +}; +static const arc arcs_5_1[3] = { + {54, 2}, + {55, 2}, + {56, 2}, +}; +static const arc arcs_5_2[1] = { + {0, 2}, +}; +static state states_5[3] = { + {1, arcs_5_0}, + {3, arcs_5_1}, + {1, arcs_5_2}, +}; +static const arc arcs_6_0[1] = { + {38, 1}, +}; +static const arc arcs_6_1[1] = { + {56, 2}, +}; +static const arc arcs_6_2[1] = { + {0, 2}, +}; +static state states_6[3] = { + {1, arcs_6_0}, + {1, arcs_6_1}, + {1, arcs_6_2}, +}; +static const arc arcs_7_0[1] = { + {19, 1}, +}; +static const arc arcs_7_1[1] = { + {40, 2}, +}; +static const arc arcs_7_2[1] = { + {57, 3}, +}; +static const arc arcs_7_3[2] = { + {58, 4}, + {59, 5}, +}; +static const arc arcs_7_4[1] = { + {60, 6}, +}; +static const arc arcs_7_5[2] = { + {61, 7}, + {62, 8}, +}; +static const arc arcs_7_6[1] = { + {59, 5}, +}; +static const arc arcs_7_7[1] = { + {62, 8}, +}; +static const arc arcs_7_8[1] = { + {0, 8}, +}; +static state states_7[9] = { + {1, arcs_7_0}, + {1, arcs_7_1}, + {1, arcs_7_2}, + {2, arcs_7_3}, + {1, arcs_7_4}, + {2, arcs_7_5}, + {1, arcs_7_6}, + {1, arcs_7_7}, + {1, arcs_7_8}, +}; +static const arc arcs_8_0[1] = { + {5, 1}, +}; +static const arc arcs_8_1[2] = { + {50, 2}, + {63, 3}, +}; +static const arc arcs_8_2[1] = { + {0, 2}, +}; +static const arc arcs_8_3[1] = { + {50, 2}, +}; +static state states_8[4] = { + {1, arcs_8_0}, + {2, arcs_8_1}, + {1, arcs_8_2}, + {1, arcs_8_3}, +}; +static const arc arcs_9_0[3] = { + {6, 1}, + {64, 2}, + {65, 3}, +}; +static const arc arcs_9_1[4] = { + {66, 4}, + {61, 5}, + {65, 6}, + {0, 1}, +}; +static const arc arcs_9_2[1] = { + {65, 7}, +}; +static const arc arcs_9_3[4] = { + {66, 8}, + {67, 9}, + {61, 5}, + {0, 3}, +}; +static const arc arcs_9_4[4] = { + {64, 2}, + {61, 10}, + {65, 11}, + {0, 4}, +}; +static const arc arcs_9_5[1] = { + {0, 5}, +}; +static const arc arcs_9_6[3] = { + {66, 4}, + {61, 5}, + {0, 6}, +}; +static const arc arcs_9_7[3] = { + {66, 12}, + {61, 5}, + {0, 7}, +}; +static const arc arcs_9_8[6] = { + {6, 13}, + {64, 2}, + {68, 14}, + {61, 15}, + {65, 3}, + {0, 8}, +}; +static const arc arcs_9_9[1] = { + {60, 16}, +}; +static const arc arcs_9_10[3] = { + {64, 2}, + {65, 11}, + {0, 10}, +}; +static const arc arcs_9_11[4] = { + {66, 4}, + {67, 17}, + {61, 5}, + {0, 11}, +}; +static const arc arcs_9_12[2] = { + {61, 5}, + {0, 12}, +}; +static const arc arcs_9_13[4] = { + {66, 18}, + {61, 5}, + {65, 19}, + {0, 13}, +}; +static const arc arcs_9_14[2] = { + {66, 20}, + {0, 14}, +}; +static const arc arcs_9_15[5] = { + {6, 13}, + {64, 2}, + {68, 14}, + {65, 3}, + {0, 15}, +}; +static const arc arcs_9_16[3] = { + {66, 8}, + {61, 5}, + {0, 16}, +}; +static const arc arcs_9_17[1] = { + {60, 6}, +}; +static const arc arcs_9_18[4] = { + {64, 2}, + {61, 21}, + {65, 22}, + {0, 18}, +}; +static const arc arcs_9_19[3] = { + {66, 18}, + {61, 5}, + {0, 19}, +}; +static const arc arcs_9_20[5] = { + {6, 23}, + {64, 2}, + {61, 24}, + {65, 25}, + {0, 20}, +}; +static const arc arcs_9_21[3] = { + {64, 2}, + {65, 22}, + {0, 21}, +}; +static const arc arcs_9_22[4] = { + {66, 18}, + {67, 26}, + {61, 5}, + {0, 22}, +}; +static const arc arcs_9_23[4] = { + {66, 27}, + {61, 5}, + {65, 28}, + {0, 23}, +}; +static const arc arcs_9_24[1] = { + {65, 25}, +}; +static const arc arcs_9_25[4] = { + {66, 29}, + {67, 30}, + {61, 5}, + {0, 25}, +}; +static const arc arcs_9_26[1] = { + {60, 19}, +}; +static const arc arcs_9_27[4] = { + {64, 2}, + {61, 31}, + {65, 32}, + {0, 27}, +}; +static const arc arcs_9_28[3] = { + {66, 27}, + {61, 5}, + {0, 28}, +}; +static const arc arcs_9_29[5] = { + {6, 33}, + {64, 2}, + {61, 34}, + {65, 25}, + {0, 29}, +}; +static const arc arcs_9_30[1] = { + {60, 35}, +}; +static const arc arcs_9_31[3] = { + {64, 2}, + {65, 32}, + {0, 31}, +}; +static const arc arcs_9_32[4] = { + {66, 27}, + {67, 36}, + {61, 5}, + {0, 32}, +}; +static const arc arcs_9_33[4] = { + {66, 37}, + {61, 5}, + {65, 38}, + {0, 33}, +}; +static const arc arcs_9_34[4] = { + {6, 33}, + {64, 2}, + {65, 25}, + {0, 34}, +}; +static const arc arcs_9_35[3] = { + {66, 29}, + {61, 5}, + {0, 35}, +}; +static const arc arcs_9_36[1] = { + {60, 28}, +}; +static const arc arcs_9_37[4] = { + {64, 2}, + {61, 39}, + {65, 40}, + {0, 37}, +}; +static const arc arcs_9_38[3] = { + {66, 37}, + {61, 5}, + {0, 38}, +}; +static const arc arcs_9_39[3] = { + {64, 2}, + {65, 40}, + {0, 39}, +}; +static const arc arcs_9_40[4] = { + {66, 37}, + {67, 41}, + {61, 5}, + {0, 40}, +}; +static const arc arcs_9_41[1] = { + {60, 38}, +}; +static state states_9[42] = { + {3, arcs_9_0}, + {4, arcs_9_1}, + {1, arcs_9_2}, + {4, arcs_9_3}, + {4, arcs_9_4}, + {1, arcs_9_5}, + {3, arcs_9_6}, + {3, arcs_9_7}, + {6, arcs_9_8}, + {1, arcs_9_9}, + {3, arcs_9_10}, + {4, arcs_9_11}, + {2, arcs_9_12}, + {4, arcs_9_13}, + {2, arcs_9_14}, + {5, arcs_9_15}, + {3, arcs_9_16}, + {1, arcs_9_17}, + {4, arcs_9_18}, + {3, arcs_9_19}, + {5, arcs_9_20}, + {3, arcs_9_21}, + {4, arcs_9_22}, + {4, arcs_9_23}, + {1, arcs_9_24}, + {4, arcs_9_25}, + {1, arcs_9_26}, + {4, arcs_9_27}, + {3, arcs_9_28}, + {5, arcs_9_29}, + {1, arcs_9_30}, + {3, arcs_9_31}, + {4, arcs_9_32}, + {4, arcs_9_33}, + {4, arcs_9_34}, + {3, arcs_9_35}, + {1, arcs_9_36}, + {4, arcs_9_37}, + {3, arcs_9_38}, + {3, arcs_9_39}, + {4, arcs_9_40}, + {1, arcs_9_41}, +}; +static const arc arcs_10_0[1] = { + {40, 1}, +}; +static const arc arcs_10_1[2] = { + {59, 2}, + {0, 1}, +}; +static const arc arcs_10_2[1] = { + {60, 3}, +}; +static const arc arcs_10_3[1] = { + {0, 3}, +}; +static state states_10[4] = { + {1, arcs_10_0}, + {2, arcs_10_1}, + {1, arcs_10_2}, + {1, arcs_10_3}, +}; +static const arc arcs_11_0[3] = { + {6, 1}, + {64, 2}, + {70, 3}, +}; +static const arc arcs_11_1[3] = { + {66, 4}, + {70, 5}, + {0, 1}, +}; +static const arc arcs_11_2[1] = { + {70, 6}, +}; +static const arc arcs_11_3[3] = { + {66, 7}, + {67, 8}, + {0, 3}, +}; +static const arc arcs_11_4[3] = { + {64, 2}, + {70, 9}, + {0, 4}, +}; +static const arc arcs_11_5[2] = { + {66, 4}, + {0, 5}, +}; +static const arc arcs_11_6[2] = { + {66, 10}, + {0, 6}, +}; +static const arc arcs_11_7[5] = { + {6, 11}, + {64, 2}, + {68, 12}, + {70, 3}, + {0, 7}, +}; +static const arc arcs_11_8[1] = { + {60, 13}, +}; +static const arc arcs_11_9[3] = { + {66, 4}, + {67, 14}, + {0, 9}, +}; +static const arc arcs_11_10[1] = { + {0, 10}, +}; +static const arc arcs_11_11[3] = { + {66, 15}, + {70, 16}, + {0, 11}, +}; +static const arc arcs_11_12[2] = { + {66, 17}, + {0, 12}, +}; +static const arc arcs_11_13[2] = { + {66, 7}, + {0, 13}, +}; +static const arc arcs_11_14[1] = { + {60, 5}, +}; +static const arc arcs_11_15[3] = { + {64, 2}, + {70, 18}, + {0, 15}, +}; +static const arc arcs_11_16[2] = { + {66, 15}, + {0, 16}, +}; +static const arc arcs_11_17[4] = { + {6, 19}, + {64, 2}, + {70, 20}, + {0, 17}, +}; +static const arc arcs_11_18[3] = { + {66, 15}, + {67, 21}, + {0, 18}, +}; +static const arc arcs_11_19[3] = { + {66, 22}, + {70, 23}, + {0, 19}, +}; +static const arc arcs_11_20[3] = { + {66, 24}, + {67, 25}, + {0, 20}, +}; +static const arc arcs_11_21[1] = { + {60, 16}, +}; +static const arc arcs_11_22[3] = { + {64, 2}, + {70, 26}, + {0, 22}, +}; +static const arc arcs_11_23[2] = { + {66, 22}, + {0, 23}, +}; +static const arc arcs_11_24[4] = { + {6, 27}, + {64, 2}, + {70, 20}, + {0, 24}, +}; +static const arc arcs_11_25[1] = { + {60, 28}, +}; +static const arc arcs_11_26[3] = { + {66, 22}, + {67, 29}, + {0, 26}, +}; +static const arc arcs_11_27[3] = { + {66, 30}, + {70, 31}, + {0, 27}, +}; +static const arc arcs_11_28[2] = { + {66, 24}, + {0, 28}, +}; +static const arc arcs_11_29[1] = { + {60, 23}, +}; +static const arc arcs_11_30[3] = { + {64, 2}, + {70, 32}, + {0, 30}, +}; +static const arc arcs_11_31[2] = { + {66, 30}, + {0, 31}, +}; +static const arc arcs_11_32[3] = { + {66, 30}, + {67, 33}, + {0, 32}, +}; +static const arc arcs_11_33[1] = { + {60, 31}, +}; +static state states_11[34] = { + {3, arcs_11_0}, + {3, arcs_11_1}, + {1, arcs_11_2}, + {3, arcs_11_3}, + {3, arcs_11_4}, + {2, arcs_11_5}, + {2, arcs_11_6}, + {5, arcs_11_7}, + {1, arcs_11_8}, + {3, arcs_11_9}, + {1, arcs_11_10}, + {3, arcs_11_11}, + {2, arcs_11_12}, + {2, arcs_11_13}, + {1, arcs_11_14}, + {3, arcs_11_15}, + {2, arcs_11_16}, + {4, arcs_11_17}, + {3, arcs_11_18}, + {3, arcs_11_19}, + {3, arcs_11_20}, + {1, arcs_11_21}, + {3, arcs_11_22}, + {2, arcs_11_23}, + {4, arcs_11_24}, + {1, arcs_11_25}, + {3, arcs_11_26}, + {3, arcs_11_27}, + {2, arcs_11_28}, + {1, arcs_11_29}, + {3, arcs_11_30}, + {2, arcs_11_31}, + {3, arcs_11_32}, + {1, arcs_11_33}, +}; +static const arc arcs_12_0[1] = { + {40, 1}, +}; +static const arc arcs_12_1[1] = { + {0, 1}, +}; +static state states_12[2] = { + {1, arcs_12_0}, + {1, arcs_12_1}, +}; +static const arc arcs_13_0[2] = { + {3, 1}, + {4, 1}, +}; +static const arc arcs_13_1[1] = { + {0, 1}, +}; +static state states_13[2] = { + {2, arcs_13_0}, + {1, arcs_13_1}, +}; +static const arc arcs_14_0[1] = { + {71, 1}, +}; +static const arc arcs_14_1[2] = { + {72, 2}, + {2, 3}, +}; +static const arc arcs_14_2[2] = { + {2, 3}, + {71, 1}, +}; +static const arc arcs_14_3[1] = { + {0, 3}, +}; +static state states_14[4] = { + {1, arcs_14_0}, + {2, arcs_14_1}, + {2, arcs_14_2}, + {1, arcs_14_3}, +}; +static const arc arcs_15_0[8] = { + {73, 1}, + {74, 1}, + {75, 1}, + {76, 1}, + {77, 1}, + {78, 1}, + {79, 1}, + {80, 1}, +}; +static const arc arcs_15_1[1] = { + {0, 1}, +}; +static state states_15[2] = { + {8, arcs_15_0}, + {1, arcs_15_1}, +}; +static const arc arcs_16_0[1] = { + {81, 1}, +}; +static const arc arcs_16_1[4] = { + {67, 2}, + {82, 3}, + {83, 4}, + {0, 1}, +}; +static const arc arcs_16_2[2] = { + {81, 5}, + {84, 5}, +}; +static const arc arcs_16_3[1] = { + {0, 3}, +}; +static const arc arcs_16_4[2] = { + {47, 3}, + {84, 3}, +}; +static const arc arcs_16_5[3] = { + {67, 2}, + {61, 3}, + {0, 5}, +}; +static state states_16[6] = { + {1, arcs_16_0}, + {4, arcs_16_1}, + {2, arcs_16_2}, + {1, arcs_16_3}, + {2, arcs_16_4}, + {3, arcs_16_5}, +}; +static const arc arcs_17_0[1] = { + {59, 1}, +}; +static const arc arcs_17_1[1] = { + {60, 2}, +}; +static const arc arcs_17_2[2] = { + {67, 3}, + {0, 2}, +}; +static const arc arcs_17_3[2] = { + {81, 4}, + {84, 4}, +}; +static const arc arcs_17_4[1] = { + {0, 4}, +}; +static state states_17[5] = { + {1, arcs_17_0}, + {1, arcs_17_1}, + {2, arcs_17_2}, + {2, arcs_17_3}, + {1, arcs_17_4}, +}; +static const arc arcs_18_0[2] = { + {85, 1}, + {60, 1}, +}; +static const arc arcs_18_1[2] = { + {66, 2}, + {0, 1}, +}; +static const arc arcs_18_2[3] = { + {85, 1}, + {60, 1}, + {0, 2}, +}; +static state states_18[3] = { + {2, arcs_18_0}, + {2, arcs_18_1}, + {3, arcs_18_2}, +}; +static const arc arcs_19_0[13] = { + {86, 1}, + {87, 1}, + {88, 1}, + {89, 1}, + {90, 1}, + {91, 1}, + {92, 1}, + {93, 1}, + {94, 1}, + {95, 1}, + {96, 1}, + {97, 1}, + {98, 1}, +}; +static const arc arcs_19_1[1] = { + {0, 1}, +}; +static state states_19[2] = { + {13, arcs_19_0}, + {1, arcs_19_1}, +}; +static const arc arcs_20_0[1] = { + {20, 1}, +}; +static const arc arcs_20_1[1] = { + {99, 2}, +}; +static const arc arcs_20_2[1] = { + {0, 2}, +}; +static state states_20[3] = { + {1, arcs_20_0}, + {1, arcs_20_1}, + {1, arcs_20_2}, +}; +static const arc arcs_21_0[1] = { + {29, 1}, +}; +static const arc arcs_21_1[1] = { + {0, 1}, +}; +static state states_21[2] = { + {1, arcs_21_0}, + {1, arcs_21_1}, +}; +static const arc arcs_22_0[5] = { + {100, 1}, + {101, 1}, + {102, 1}, + {103, 1}, + {104, 1}, +}; +static const arc arcs_22_1[1] = { + {0, 1}, +}; +static state states_22[2] = { + {5, arcs_22_0}, + {1, arcs_22_1}, +}; +static const arc arcs_23_0[1] = { + {16, 1}, +}; +static const arc arcs_23_1[1] = { + {0, 1}, +}; +static state states_23[2] = { + {1, arcs_23_0}, + {1, arcs_23_1}, +}; +static const arc arcs_24_0[1] = { + {18, 1}, +}; +static const arc arcs_24_1[1] = { + {0, 1}, +}; +static state states_24[2] = { + {1, arcs_24_0}, + {1, arcs_24_1}, +}; +static const arc arcs_25_0[1] = { + {31, 1}, +}; +static const arc arcs_25_1[2] = { + {81, 2}, + {0, 1}, +}; +static const arc arcs_25_2[1] = { + {0, 2}, +}; +static state states_25[3] = { + {1, arcs_25_0}, + {2, arcs_25_1}, + {1, arcs_25_2}, +}; +static const arc arcs_26_0[1] = { + {84, 1}, +}; +static const arc arcs_26_1[1] = { + {0, 1}, +}; +static state states_26[2] = { + {1, arcs_26_0}, + {1, arcs_26_1}, +}; +static const arc arcs_27_0[1] = { + {30, 1}, +}; +static const arc arcs_27_1[2] = { + {60, 2}, + {0, 1}, +}; +static const arc arcs_27_2[2] = { + {22, 3}, + {0, 2}, +}; +static const arc arcs_27_3[1] = { + {60, 4}, +}; +static const arc arcs_27_4[1] = { + {0, 4}, +}; +static state states_27[5] = { + {1, arcs_27_0}, + {2, arcs_27_1}, + {2, arcs_27_2}, + {1, arcs_27_3}, + {1, arcs_27_4}, +}; +static const arc arcs_28_0[2] = { + {105, 1}, + {106, 1}, +}; +static const arc arcs_28_1[1] = { + {0, 1}, +}; +static state states_28[2] = { + {2, arcs_28_0}, + {1, arcs_28_1}, +}; +static const arc arcs_29_0[1] = { + {25, 1}, +}; +static const arc arcs_29_1[1] = { + {107, 2}, +}; +static const arc arcs_29_2[1] = { + {0, 2}, +}; +static state states_29[3] = { + {1, arcs_29_0}, + {1, arcs_29_1}, + {1, arcs_29_2}, +}; +static const arc arcs_30_0[1] = { + {22, 1}, +}; +static const arc arcs_30_1[3] = { + {108, 2}, + {9, 2}, + {49, 3}, +}; +static const arc arcs_30_2[4] = { + {108, 2}, + {9, 2}, + {25, 4}, + {49, 3}, +}; +static const arc arcs_30_3[1] = { + {25, 4}, +}; +static const arc arcs_30_4[3] = { + {5, 5}, + {6, 6}, + {109, 6}, +}; +static const arc arcs_30_5[1] = { + {109, 7}, +}; +static const arc arcs_30_6[1] = { + {0, 6}, +}; +static const arc arcs_30_7[1] = { + {50, 6}, +}; +static state states_30[8] = { + {1, arcs_30_0}, + {3, arcs_30_1}, + {4, arcs_30_2}, + {1, arcs_30_3}, + {3, arcs_30_4}, + {1, arcs_30_5}, + {1, arcs_30_6}, + {1, arcs_30_7}, +}; +static const arc arcs_31_0[1] = { + {40, 1}, +}; +static const arc arcs_31_1[2] = { + {111, 2}, + {0, 1}, +}; +static const arc arcs_31_2[1] = { + {40, 3}, +}; +static const arc arcs_31_3[1] = { + {0, 3}, +}; +static state states_31[4] = { + {1, arcs_31_0}, + {2, arcs_31_1}, + {1, arcs_31_2}, + {1, arcs_31_3}, +}; +static const arc arcs_32_0[1] = { + {49, 1}, +}; +static const arc arcs_32_1[2] = { + {111, 2}, + {0, 1}, +}; +static const arc arcs_32_2[1] = { + {40, 3}, +}; +static const arc arcs_32_3[1] = { + {0, 3}, +}; +static state states_32[4] = { + {1, arcs_32_0}, + {2, arcs_32_1}, + {1, arcs_32_2}, + {1, arcs_32_3}, +}; +static const arc arcs_33_0[1] = { + {110, 1}, +}; +static const arc arcs_33_1[2] = { + {66, 2}, + {0, 1}, +}; +static const arc arcs_33_2[2] = { + {110, 1}, + {0, 2}, +}; +static state states_33[3] = { + {1, arcs_33_0}, + {2, arcs_33_1}, + {2, arcs_33_2}, +}; +static const arc arcs_34_0[1] = { + {112, 1}, +}; +static const arc arcs_34_1[2] = { + {66, 0}, + {0, 1}, +}; +static state states_34[2] = { + {1, arcs_34_0}, + {2, arcs_34_1}, +}; +static const arc arcs_35_0[1] = { + {40, 1}, +}; +static const arc arcs_35_1[2] = { + {108, 0}, + {0, 1}, +}; +static state states_35[2] = { + {1, arcs_35_0}, + {2, arcs_35_1}, +}; +static const arc arcs_36_0[1] = { + {23, 1}, +}; +static const arc arcs_36_1[1] = { + {40, 2}, +}; +static const arc arcs_36_2[2] = { + {66, 1}, + {0, 2}, +}; +static state states_36[3] = { + {1, arcs_36_0}, + {1, arcs_36_1}, + {2, arcs_36_2}, +}; +static const arc arcs_37_0[1] = { + {27, 1}, +}; +static const arc arcs_37_1[1] = { + {40, 2}, +}; +static const arc arcs_37_2[2] = { + {66, 1}, + {0, 2}, +}; +static state states_37[3] = { + {1, arcs_37_0}, + {1, arcs_37_1}, + {2, arcs_37_2}, +}; +static const arc arcs_38_0[1] = { + {15, 1}, +}; +static const arc arcs_38_1[1] = { + {60, 2}, +}; +static const arc arcs_38_2[2] = { + {66, 3}, + {0, 2}, +}; +static const arc arcs_38_3[1] = { + {60, 4}, +}; +static const arc arcs_38_4[1] = { + {0, 4}, +}; +static state states_38[5] = { + {1, arcs_38_0}, + {1, arcs_38_1}, + {2, arcs_38_2}, + {1, arcs_38_3}, + {1, arcs_38_4}, +}; +static const arc arcs_39_0[9] = { + {113, 1}, + {55, 1}, + {53, 1}, + {114, 1}, + {56, 1}, + {115, 1}, + {116, 1}, + {117, 1}, + {118, 1}, +}; +static const arc arcs_39_1[1] = { + {0, 1}, +}; +static state states_39[2] = { + {9, arcs_39_0}, + {1, arcs_39_1}, +}; +static const arc arcs_40_0[1] = { + {38, 1}, +}; +static const arc arcs_40_1[3] = { + {114, 2}, + {56, 2}, + {118, 2}, +}; +static const arc arcs_40_2[1] = { + {0, 2}, +}; +static state states_40[3] = { + {1, arcs_40_0}, + {3, arcs_40_1}, + {1, arcs_40_2}, +}; +static const arc arcs_41_0[1] = { + {24, 1}, +}; +static const arc arcs_41_1[1] = { + {119, 2}, +}; +static const arc arcs_41_2[1] = { + {59, 3}, +}; +static const arc arcs_41_3[1] = { + {120, 4}, +}; +static const arc arcs_41_4[3] = { + {121, 1}, + {122, 5}, + {0, 4}, +}; +static const arc arcs_41_5[1] = { + {59, 6}, +}; +static const arc arcs_41_6[1] = { + {120, 7}, +}; +static const arc arcs_41_7[1] = { + {0, 7}, +}; +static state states_41[8] = { + {1, arcs_41_0}, + {1, arcs_41_1}, + {1, arcs_41_2}, + {1, arcs_41_3}, + {3, arcs_41_4}, + {1, arcs_41_5}, + {1, arcs_41_6}, + {1, arcs_41_7}, +}; +static const arc arcs_42_0[1] = { + {33, 1}, +}; +static const arc arcs_42_1[1] = { + {119, 2}, +}; +static const arc arcs_42_2[1] = { + {59, 3}, +}; +static const arc arcs_42_3[1] = { + {120, 4}, +}; +static const arc arcs_42_4[2] = { + {122, 5}, + {0, 4}, +}; +static const arc arcs_42_5[1] = { + {59, 6}, +}; +static const arc arcs_42_6[1] = { + {120, 7}, +}; +static const arc arcs_42_7[1] = { + {0, 7}, +}; +static state states_42[8] = { + {1, arcs_42_0}, + {1, arcs_42_1}, + {1, arcs_42_2}, + {1, arcs_42_3}, + {2, arcs_42_4}, + {1, arcs_42_5}, + {1, arcs_42_6}, + {1, arcs_42_7}, +}; +static const arc arcs_43_0[1] = { + {21, 1}, +}; +static const arc arcs_43_1[1] = { + {99, 2}, +}; +static const arc arcs_43_2[1] = { + {123, 3}, +}; +static const arc arcs_43_3[1] = { + {47, 4}, +}; +static const arc arcs_43_4[1] = { + {59, 5}, +}; +static const arc arcs_43_5[2] = { + {61, 6}, + {120, 7}, +}; +static const arc arcs_43_6[1] = { + {120, 7}, +}; +static const arc arcs_43_7[2] = { + {122, 8}, + {0, 7}, +}; +static const arc arcs_43_8[1] = { + {59, 9}, +}; +static const arc arcs_43_9[1] = { + {120, 10}, +}; +static const arc arcs_43_10[1] = { + {0, 10}, +}; +static state states_43[11] = { + {1, arcs_43_0}, + {1, arcs_43_1}, + {1, arcs_43_2}, + {1, arcs_43_3}, + {1, arcs_43_4}, + {2, arcs_43_5}, + {1, arcs_43_6}, + {2, arcs_43_7}, + {1, arcs_43_8}, + {1, arcs_43_9}, + {1, arcs_43_10}, +}; +static const arc arcs_44_0[1] = { + {32, 1}, +}; +static const arc arcs_44_1[1] = { + {59, 2}, +}; +static const arc arcs_44_2[1] = { + {120, 3}, +}; +static const arc arcs_44_3[2] = { + {124, 4}, + {125, 5}, +}; +static const arc arcs_44_4[1] = { + {59, 6}, +}; +static const arc arcs_44_5[1] = { + {59, 7}, +}; +static const arc arcs_44_6[1] = { + {120, 8}, +}; +static const arc arcs_44_7[1] = { + {120, 9}, +}; +static const arc arcs_44_8[1] = { + {0, 8}, +}; +static const arc arcs_44_9[4] = { + {122, 10}, + {124, 4}, + {125, 5}, + {0, 9}, +}; +static const arc arcs_44_10[1] = { + {59, 11}, +}; +static const arc arcs_44_11[1] = { + {120, 12}, +}; +static const arc arcs_44_12[2] = { + {124, 4}, + {0, 12}, +}; +static state states_44[13] = { + {1, arcs_44_0}, + {1, arcs_44_1}, + {1, arcs_44_2}, + {2, arcs_44_3}, + {1, arcs_44_4}, + {1, arcs_44_5}, + {1, arcs_44_6}, + {1, arcs_44_7}, + {1, arcs_44_8}, + {4, arcs_44_9}, + {1, arcs_44_10}, + {1, arcs_44_11}, + {2, arcs_44_12}, +}; +static const arc arcs_45_0[1] = { + {34, 1}, +}; +static const arc arcs_45_1[1] = { + {126, 2}, +}; +static const arc arcs_45_2[2] = { + {66, 1}, + {59, 3}, +}; +static const arc arcs_45_3[2] = { + {61, 4}, + {120, 5}, +}; +static const arc arcs_45_4[1] = { + {120, 5}, +}; +static const arc arcs_45_5[1] = { + {0, 5}, +}; +static state states_45[6] = { + {1, arcs_45_0}, + {1, arcs_45_1}, + {2, arcs_45_2}, + {2, arcs_45_3}, + {1, arcs_45_4}, + {1, arcs_45_5}, +}; +static const arc arcs_46_0[1] = { + {60, 1}, +}; +static const arc arcs_46_1[2] = { + {111, 2}, + {0, 1}, +}; +static const arc arcs_46_2[1] = { + {127, 3}, +}; +static const arc arcs_46_3[1] = { + {0, 3}, +}; +static state states_46[4] = { + {1, arcs_46_0}, + {2, arcs_46_1}, + {1, arcs_46_2}, + {1, arcs_46_3}, +}; +static const arc arcs_47_0[1] = { + {128, 1}, +}; +static const arc arcs_47_1[2] = { + {60, 2}, + {0, 1}, +}; +static const arc arcs_47_2[2] = { + {111, 3}, + {0, 2}, +}; +static const arc arcs_47_3[1] = { + {40, 4}, +}; +static const arc arcs_47_4[1] = { + {0, 4}, +}; +static state states_47[5] = { + {1, arcs_47_0}, + {2, arcs_47_1}, + {2, arcs_47_2}, + {1, arcs_47_3}, + {1, arcs_47_4}, +}; +static const arc arcs_48_0[2] = { + {2, 1}, + {4, 2}, +}; +static const arc arcs_48_1[1] = { + {129, 3}, +}; +static const arc arcs_48_2[1] = { + {0, 2}, +}; +static const arc arcs_48_3[1] = { + {45, 4}, +}; +static const arc arcs_48_4[2] = { + {130, 2}, + {45, 4}, +}; +static state states_48[5] = { + {2, arcs_48_0}, + {1, arcs_48_1}, + {1, arcs_48_2}, + {1, arcs_48_3}, + {2, arcs_48_4}, +}; +static const arc arcs_49_0[1] = { + {60, 1}, +}; +static const arc arcs_49_1[2] = { + {131, 2}, + {0, 1}, +}; +static const arc arcs_49_2[1] = { + {60, 3}, +}; +static const arc arcs_49_3[1] = { + {0, 3}, +}; +static state states_49[4] = { + {1, arcs_49_0}, + {2, arcs_49_1}, + {1, arcs_49_2}, + {1, arcs_49_3}, +}; +static const arc arcs_50_0[2] = { + {132, 1}, + {133, 2}, +}; +static const arc arcs_50_1[1] = { + {0, 1}, +}; +static const arc arcs_50_2[2] = { + {24, 3}, + {0, 2}, +}; +static const arc arcs_50_3[1] = { + {133, 4}, +}; +static const arc arcs_50_4[1] = { + {122, 5}, +}; +static const arc arcs_50_5[1] = { + {60, 1}, +}; +static state states_50[6] = { + {2, arcs_50_0}, + {1, arcs_50_1}, + {2, arcs_50_2}, + {1, arcs_50_3}, + {1, arcs_50_4}, + {1, arcs_50_5}, +}; +static const arc arcs_51_0[2] = { + {135, 1}, + {133, 1}, +}; +static const arc arcs_51_1[1] = { + {0, 1}, +}; +static state states_51[2] = { + {2, arcs_51_0}, + {1, arcs_51_1}, +}; +static const arc arcs_52_0[1] = { + {26, 1}, +}; +static const arc arcs_52_1[2] = { + {59, 2}, + {69, 3}, +}; +static const arc arcs_52_2[1] = { + {60, 4}, +}; +static const arc arcs_52_3[1] = { + {59, 2}, +}; +static const arc arcs_52_4[1] = { + {0, 4}, +}; +static state states_52[5] = { + {1, arcs_52_0}, + {2, arcs_52_1}, + {1, arcs_52_2}, + {1, arcs_52_3}, + {1, arcs_52_4}, +}; +static const arc arcs_53_0[1] = { + {26, 1}, +}; +static const arc arcs_53_1[2] = { + {59, 2}, + {69, 3}, +}; +static const arc arcs_53_2[1] = { + {134, 4}, +}; +static const arc arcs_53_3[1] = { + {59, 2}, +}; +static const arc arcs_53_4[1] = { + {0, 4}, +}; +static state states_53[5] = { + {1, arcs_53_0}, + {2, arcs_53_1}, + {1, arcs_53_2}, + {1, arcs_53_3}, + {1, arcs_53_4}, +}; +static const arc arcs_54_0[1] = { + {136, 1}, +}; +static const arc arcs_54_1[2] = { + {137, 0}, + {0, 1}, +}; +static state states_54[2] = { + {1, arcs_54_0}, + {2, arcs_54_1}, +}; +static const arc arcs_55_0[1] = { + {138, 1}, +}; +static const arc arcs_55_1[2] = { + {139, 0}, + {0, 1}, +}; +static state states_55[2] = { + {1, arcs_55_0}, + {2, arcs_55_1}, +}; +static const arc arcs_56_0[2] = { + {28, 1}, + {140, 2}, +}; +static const arc arcs_56_1[1] = { + {138, 2}, +}; +static const arc arcs_56_2[1] = { + {0, 2}, +}; +static state states_56[3] = { + {2, arcs_56_0}, + {1, arcs_56_1}, + {1, arcs_56_2}, +}; +static const arc arcs_57_0[1] = { + {127, 1}, +}; +static const arc arcs_57_1[2] = { + {141, 0}, + {0, 1}, +}; +static state states_57[2] = { + {1, arcs_57_0}, + {2, arcs_57_1}, +}; +static const arc arcs_58_0[10] = { + {142, 1}, + {143, 1}, + {144, 1}, + {142, 1}, + {145, 1}, + {146, 1}, + {147, 1}, + {123, 1}, + {148, 2}, + {28, 3}, +}; +static const arc arcs_58_1[1] = { + {0, 1}, +}; +static const arc arcs_58_2[2] = { + {28, 1}, + {0, 2}, +}; +static const arc arcs_58_3[1] = { + {123, 1}, +}; +static state states_58[4] = { + {10, arcs_58_0}, + {1, arcs_58_1}, + {2, arcs_58_2}, + {1, arcs_58_3}, +}; +static const arc arcs_59_0[1] = { + {6, 1}, +}; +static const arc arcs_59_1[1] = { + {127, 2}, +}; +static const arc arcs_59_2[1] = { + {0, 2}, +}; +static state states_59[3] = { + {1, arcs_59_0}, + {1, arcs_59_1}, + {1, arcs_59_2}, +}; +static const arc arcs_60_0[1] = { + {149, 1}, +}; +static const arc arcs_60_1[2] = { + {150, 0}, + {0, 1}, +}; +static state states_60[2] = { + {1, arcs_60_0}, + {2, arcs_60_1}, +}; +static const arc arcs_61_0[1] = { + {151, 1}, +}; +static const arc arcs_61_1[2] = { + {152, 0}, + {0, 1}, +}; +static state states_61[2] = { + {1, arcs_61_0}, + {2, arcs_61_1}, +}; +static const arc arcs_62_0[1] = { + {153, 1}, +}; +static const arc arcs_62_1[2] = { + {154, 0}, + {0, 1}, +}; +static state states_62[2] = { + {1, arcs_62_0}, + {2, arcs_62_1}, +}; +static const arc arcs_63_0[1] = { + {155, 1}, +}; +static const arc arcs_63_1[3] = { + {156, 0}, + {157, 0}, + {0, 1}, +}; +static state states_63[2] = { + {1, arcs_63_0}, + {3, arcs_63_1}, +}; +static const arc arcs_64_0[1] = { + {158, 1}, +}; +static const arc arcs_64_1[3] = { + {7, 0}, + {8, 0}, + {0, 1}, +}; +static state states_64[2] = { + {1, arcs_64_0}, + {3, arcs_64_1}, +}; +static const arc arcs_65_0[1] = { + {159, 1}, +}; +static const arc arcs_65_1[6] = { + {160, 0}, + {6, 0}, + {68, 0}, + {161, 0}, + {10, 0}, + {0, 1}, +}; +static state states_65[2] = { + {1, arcs_65_0}, + {6, arcs_65_1}, +}; +static const arc arcs_66_0[4] = { + {7, 1}, + {8, 1}, + {37, 1}, + {162, 2}, +}; +static const arc arcs_66_1[1] = { + {159, 2}, +}; +static const arc arcs_66_2[1] = { + {0, 2}, +}; +static state states_66[3] = { + {4, arcs_66_0}, + {1, arcs_66_1}, + {1, arcs_66_2}, +}; +static const arc arcs_67_0[1] = { + {163, 1}, +}; +static const arc arcs_67_1[2] = { + {64, 2}, + {0, 1}, +}; +static const arc arcs_67_2[1] = { + {159, 3}, +}; +static const arc arcs_67_3[1] = { + {0, 3}, +}; +static state states_67[4] = { + {1, arcs_67_0}, + {2, arcs_67_1}, + {1, arcs_67_2}, + {1, arcs_67_3}, +}; +static const arc arcs_68_0[2] = { + {39, 1}, + {164, 2}, +}; +static const arc arcs_68_1[1] = { + {164, 2}, +}; +static const arc arcs_68_2[2] = { + {165, 2}, + {0, 2}, +}; +static state states_68[3] = { + {2, arcs_68_0}, + {1, arcs_68_1}, + {2, arcs_68_2}, +}; +static const arc arcs_69_0[10] = { + {5, 1}, + {9, 2}, + {11, 2}, + {12, 2}, + {13, 2}, + {14, 3}, + {36, 4}, + {40, 2}, + {41, 2}, + {42, 5}, +}; +static const arc arcs_69_1[3] = { + {50, 2}, + {166, 6}, + {84, 6}, +}; +static const arc arcs_69_2[1] = { + {0, 2}, +}; +static const arc arcs_69_3[2] = { + {167, 2}, + {166, 7}, +}; +static const arc arcs_69_4[2] = { + {168, 2}, + {169, 8}, +}; +static const arc arcs_69_5[2] = { + {42, 5}, + {0, 5}, +}; +static const arc arcs_69_6[1] = { + {50, 2}, +}; +static const arc arcs_69_7[1] = { + {167, 2}, +}; +static const arc arcs_69_8[1] = { + {168, 2}, +}; +static state states_69[9] = { + {10, arcs_69_0}, + {3, arcs_69_1}, + {1, arcs_69_2}, + {2, arcs_69_3}, + {2, arcs_69_4}, + {2, arcs_69_5}, + {1, arcs_69_6}, + {1, arcs_69_7}, + {1, arcs_69_8}, +}; +static const arc arcs_70_0[2] = { + {119, 1}, + {85, 1}, +}; +static const arc arcs_70_1[3] = { + {66, 2}, + {170, 3}, + {0, 1}, +}; +static const arc arcs_70_2[3] = { + {119, 4}, + {85, 4}, + {0, 2}, +}; +static const arc arcs_70_3[1] = { + {0, 3}, +}; +static const arc arcs_70_4[2] = { + {66, 2}, + {0, 4}, +}; +static state states_70[5] = { + {2, arcs_70_0}, + {3, arcs_70_1}, + {3, arcs_70_2}, + {1, arcs_70_3}, + {2, arcs_70_4}, +}; +static const arc arcs_71_0[3] = { + {5, 1}, + {108, 2}, + {14, 3}, +}; +static const arc arcs_71_1[2] = { + {50, 4}, + {51, 5}, +}; +static const arc arcs_71_2[1] = { + {40, 4}, +}; +static const arc arcs_71_3[1] = { + {171, 6}, +}; +static const arc arcs_71_4[1] = { + {0, 4}, +}; +static const arc arcs_71_5[1] = { + {50, 4}, +}; +static const arc arcs_71_6[1] = { + {167, 4}, +}; +static state states_71[7] = { + {3, arcs_71_0}, + {2, arcs_71_1}, + {1, arcs_71_2}, + {1, arcs_71_3}, + {1, arcs_71_4}, + {1, arcs_71_5}, + {1, arcs_71_6}, +}; +static const arc arcs_72_0[1] = { + {172, 1}, +}; +static const arc arcs_72_1[2] = { + {66, 2}, + {0, 1}, +}; +static const arc arcs_72_2[2] = { + {172, 1}, + {0, 2}, +}; +static state states_72[3] = { + {1, arcs_72_0}, + {2, arcs_72_1}, + {2, arcs_72_2}, +}; +static const arc arcs_73_0[2] = { + {59, 1}, + {60, 2}, +}; +static const arc arcs_73_1[3] = { + {173, 3}, + {60, 4}, + {0, 1}, +}; +static const arc arcs_73_2[2] = { + {59, 1}, + {0, 2}, +}; +static const arc arcs_73_3[1] = { + {0, 3}, +}; +static const arc arcs_73_4[2] = { + {173, 3}, + {0, 4}, +}; +static state states_73[5] = { + {2, arcs_73_0}, + {3, arcs_73_1}, + {2, arcs_73_2}, + {1, arcs_73_3}, + {2, arcs_73_4}, +}; +static const arc arcs_74_0[1] = { + {59, 1}, +}; +static const arc arcs_74_1[2] = { + {60, 2}, + {0, 1}, +}; +static const arc arcs_74_2[1] = { + {0, 2}, +}; +static state states_74[3] = { + {1, arcs_74_0}, + {2, arcs_74_1}, + {1, arcs_74_2}, +}; +static const arc arcs_75_0[2] = { + {127, 1}, + {85, 1}, +}; +static const arc arcs_75_1[2] = { + {66, 2}, + {0, 1}, +}; +static const arc arcs_75_2[3] = { + {127, 1}, + {85, 1}, + {0, 2}, +}; +static state states_75[3] = { + {2, arcs_75_0}, + {2, arcs_75_1}, + {3, arcs_75_2}, +}; +static const arc arcs_76_0[1] = { + {60, 1}, +}; +static const arc arcs_76_1[2] = { + {66, 2}, + {0, 1}, +}; +static const arc arcs_76_2[2] = { + {60, 1}, + {0, 2}, +}; +static state states_76[3] = { + {1, arcs_76_0}, + {2, arcs_76_1}, + {2, arcs_76_2}, +}; +static const arc arcs_77_0[3] = { + {64, 1}, + {85, 2}, + {60, 3}, +}; +static const arc arcs_77_1[1] = { + {127, 4}, +}; +static const arc arcs_77_2[3] = { + {66, 5}, + {170, 6}, + {0, 2}, +}; +static const arc arcs_77_3[4] = { + {66, 5}, + {59, 7}, + {170, 6}, + {0, 3}, +}; +static const arc arcs_77_4[3] = { + {66, 8}, + {170, 6}, + {0, 4}, +}; +static const arc arcs_77_5[3] = { + {85, 9}, + {60, 9}, + {0, 5}, +}; +static const arc arcs_77_6[1] = { + {0, 6}, +}; +static const arc arcs_77_7[1] = { + {60, 4}, +}; +static const arc arcs_77_8[3] = { + {64, 10}, + {60, 11}, + {0, 8}, +}; +static const arc arcs_77_9[2] = { + {66, 5}, + {0, 9}, +}; +static const arc arcs_77_10[1] = { + {127, 12}, +}; +static const arc arcs_77_11[1] = { + {59, 13}, +}; +static const arc arcs_77_12[2] = { + {66, 8}, + {0, 12}, +}; +static const arc arcs_77_13[1] = { + {60, 12}, +}; +static state states_77[14] = { + {3, arcs_77_0}, + {1, arcs_77_1}, + {3, arcs_77_2}, + {4, arcs_77_3}, + {3, arcs_77_4}, + {3, arcs_77_5}, + {1, arcs_77_6}, + {1, arcs_77_7}, + {3, arcs_77_8}, + {2, arcs_77_9}, + {1, arcs_77_10}, + {1, arcs_77_11}, + {2, arcs_77_12}, + {1, arcs_77_13}, +}; +static const arc arcs_78_0[1] = { + {17, 1}, +}; +static const arc arcs_78_1[1] = { + {40, 2}, +}; +static const arc arcs_78_2[2] = { + {5, 3}, + {59, 4}, +}; +static const arc arcs_78_3[2] = { + {50, 5}, + {51, 6}, +}; +static const arc arcs_78_4[1] = { + {120, 7}, +}; +static const arc arcs_78_5[1] = { + {59, 4}, +}; +static const arc arcs_78_6[1] = { + {50, 5}, +}; +static const arc arcs_78_7[1] = { + {0, 7}, +}; +static state states_78[8] = { + {1, arcs_78_0}, + {1, arcs_78_1}, + {2, arcs_78_2}, + {2, arcs_78_3}, + {1, arcs_78_4}, + {1, arcs_78_5}, + {1, arcs_78_6}, + {1, arcs_78_7}, +}; +static const arc arcs_79_0[1] = { + {174, 1}, +}; +static const arc arcs_79_1[2] = { + {66, 2}, + {0, 1}, +}; +static const arc arcs_79_2[2] = { + {174, 1}, + {0, 2}, +}; +static state states_79[3] = { + {1, arcs_79_0}, + {2, arcs_79_1}, + {2, arcs_79_2}, +}; +static const arc arcs_80_0[3] = { + {6, 1}, + {64, 1}, + {60, 2}, +}; +static const arc arcs_80_1[1] = { + {60, 3}, +}; +static const arc arcs_80_2[4] = { + {131, 1}, + {67, 1}, + {170, 3}, + {0, 2}, +}; +static const arc arcs_80_3[1] = { + {0, 3}, +}; +static state states_80[4] = { + {3, arcs_80_0}, + {1, arcs_80_1}, + {4, arcs_80_2}, + {1, arcs_80_3}, +}; +static const arc arcs_81_0[2] = { + {170, 1}, + {176, 1}, +}; +static const arc arcs_81_1[1] = { + {0, 1}, +}; +static state states_81[2] = { + {2, arcs_81_0}, + {1, arcs_81_1}, +}; +static const arc arcs_82_0[1] = { + {21, 1}, +}; +static const arc arcs_82_1[1] = { + {99, 2}, +}; +static const arc arcs_82_2[1] = { + {123, 3}, +}; +static const arc arcs_82_3[1] = { + {133, 4}, +}; +static const arc arcs_82_4[2] = { + {175, 5}, + {0, 4}, +}; +static const arc arcs_82_5[1] = { + {0, 5}, +}; +static state states_82[6] = { + {1, arcs_82_0}, + {1, arcs_82_1}, + {1, arcs_82_2}, + {1, arcs_82_3}, + {2, arcs_82_4}, + {1, arcs_82_5}, +}; +static const arc arcs_83_0[2] = { + {38, 1}, + {177, 2}, +}; +static const arc arcs_83_1[1] = { + {177, 2}, +}; +static const arc arcs_83_2[1] = { + {0, 2}, +}; +static state states_83[3] = { + {2, arcs_83_0}, + {1, arcs_83_1}, + {1, arcs_83_2}, +}; +static const arc arcs_84_0[1] = { + {24, 1}, +}; +static const arc arcs_84_1[1] = { + {134, 2}, +}; +static const arc arcs_84_2[2] = { + {175, 3}, + {0, 2}, +}; +static const arc arcs_84_3[1] = { + {0, 3}, +}; +static state states_84[4] = { + {1, arcs_84_0}, + {1, arcs_84_1}, + {2, arcs_84_2}, + {1, arcs_84_3}, +}; +static const arc arcs_85_0[1] = { + {40, 1}, +}; +static const arc arcs_85_1[1] = { + {0, 1}, +}; +static state states_85[2] = { + {1, arcs_85_0}, + {1, arcs_85_1}, +}; +static const arc arcs_86_0[1] = { + {35, 1}, +}; +static const arc arcs_86_1[2] = { + {179, 2}, + {0, 1}, +}; +static const arc arcs_86_2[1] = { + {0, 2}, +}; +static state states_86[3] = { + {1, arcs_86_0}, + {2, arcs_86_1}, + {1, arcs_86_2}, +}; +static const arc arcs_87_0[2] = { + {22, 1}, + {81, 2}, +}; +static const arc arcs_87_1[1] = { + {60, 2}, +}; +static const arc arcs_87_2[1] = { + {0, 2}, +}; +static state states_87[3] = { + {2, arcs_87_0}, + {1, arcs_87_1}, + {1, arcs_87_2}, +}; +static const arc arcs_88_0[2] = { + {2, 1}, + {4, 2}, +}; +static const arc arcs_88_1[2] = { + {129, 3}, + {61, 4}, +}; +static const arc arcs_88_2[1] = { + {0, 2}, +}; +static const arc arcs_88_3[1] = { + {45, 5}, +}; +static const arc arcs_88_4[1] = { + {2, 6}, +}; +static const arc arcs_88_5[2] = { + {130, 2}, + {45, 5}, +}; +static const arc arcs_88_6[1] = { + {129, 3}, +}; +static state states_88[7] = { + {2, arcs_88_0}, + {2, arcs_88_1}, + {1, arcs_88_2}, + {1, arcs_88_3}, + {1, arcs_88_4}, + {2, arcs_88_5}, + {1, arcs_88_6}, +}; +static const arc arcs_89_0[1] = { + {181, 1}, +}; +static const arc arcs_89_1[2] = { + {44, 2}, + {2, 1}, +}; +static const arc arcs_89_2[1] = { + {0, 2}, +}; +static state states_89[3] = { + {1, arcs_89_0}, + {2, arcs_89_1}, + {1, arcs_89_2}, +}; +static const arc arcs_90_0[1] = { + {5, 1}, +}; +static const arc arcs_90_1[2] = { + {50, 2}, + {182, 3}, +}; +static const arc arcs_90_2[1] = { + {58, 4}, +}; +static const arc arcs_90_3[1] = { + {50, 2}, +}; +static const arc arcs_90_4[1] = { + {60, 5}, +}; +static const arc arcs_90_5[1] = { + {0, 5}, +}; +static state states_90[6] = { + {1, arcs_90_0}, + {2, arcs_90_1}, + {1, arcs_90_2}, + {1, arcs_90_3}, + {1, arcs_90_4}, + {1, arcs_90_5}, +}; +static const arc arcs_91_0[3] = { + {6, 1}, + {64, 2}, + {60, 3}, +}; +static const arc arcs_91_1[3] = { + {66, 4}, + {60, 5}, + {0, 1}, +}; +static const arc arcs_91_2[1] = { + {60, 6}, +}; +static const arc arcs_91_3[2] = { + {66, 7}, + {0, 3}, +}; +static const arc arcs_91_4[2] = { + {64, 2}, + {60, 5}, +}; +static const arc arcs_91_5[2] = { + {66, 4}, + {0, 5}, +}; +static const arc arcs_91_6[1] = { + {0, 6}, +}; +static const arc arcs_91_7[4] = { + {6, 8}, + {64, 2}, + {60, 3}, + {0, 7}, +}; +static const arc arcs_91_8[3] = { + {66, 9}, + {60, 10}, + {0, 8}, +}; +static const arc arcs_91_9[2] = { + {64, 2}, + {60, 10}, +}; +static const arc arcs_91_10[2] = { + {66, 9}, + {0, 10}, +}; +static state states_91[11] = { + {3, arcs_91_0}, + {3, arcs_91_1}, + {1, arcs_91_2}, + {2, arcs_91_3}, + {2, arcs_91_4}, + {2, arcs_91_5}, + {1, arcs_91_6}, + {4, arcs_91_7}, + {3, arcs_91_8}, + {2, arcs_91_9}, + {2, arcs_91_10}, +}; +static const dfa dfas[92] = { + {256, "single_input", 3, states_0, + "\344\377\377\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {257, "file_input", 2, states_1, + "\344\377\377\377\377\027\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {258, "eval_input", 3, states_2, + "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {259, "decorator", 7, states_3, + "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {260, "decorators", 2, states_4, + "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {261, "decorated", 3, states_5, + "\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {262, "async_funcdef", 3, states_6, + "\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {263, "funcdef", 9, states_7, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {264, "parameters", 4, states_8, + "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {265, "typedargslist", 42, states_9, + "\100\000\000\000\000\001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {266, "tfpdef", 4, states_10, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {267, "varargslist", 34, states_11, + "\100\000\000\000\000\001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {268, "vfpdef", 2, states_12, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {269, "stmt", 2, states_13, + "\340\377\377\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {270, "simple_stmt", 4, states_14, + "\340\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {271, "small_stmt", 2, states_15, + "\340\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {272, "expr_stmt", 6, states_16, + "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {273, "annassign", 5, states_17, + "\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {274, "testlist_star_expr", 3, states_18, + "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {275, "augassign", 2, states_19, + "\000\000\000\000\000\000\000\000\000\000\300\377\007\000\000\000\000\000\000\000\000\000\000"}, + {276, "del_stmt", 3, states_20, + "\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {277, "pass_stmt", 2, states_21, + "\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {278, "flow_stmt", 2, states_22, + "\000\000\005\300\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {279, "break_stmt", 2, states_23, + "\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {280, "continue_stmt", 2, states_24, + "\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {281, "return_stmt", 3, states_25, + "\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {282, "yield_stmt", 2, states_26, + "\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {283, "raise_stmt", 5, states_27, + "\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {284, "import_stmt", 2, states_28, + "\000\000\100\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {285, "import_name", 3, states_29, + "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {286, "import_from", 8, states_30, + "\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {287, "import_as_name", 4, states_31, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {288, "dotted_as_name", 4, states_32, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {289, "import_as_names", 3, states_33, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {290, "dotted_as_names", 2, states_34, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {291, "dotted_name", 2, states_35, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {292, "global_stmt", 3, states_36, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {293, "nonlocal_stmt", 3, states_37, + "\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {294, "assert_stmt", 5, states_38, + "\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {295, "compound_stmt", 2, states_39, + "\000\004\052\001\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {296, "async_stmt", 3, states_40, + "\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {297, "if_stmt", 8, states_41, + "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {298, "while_stmt", 8, states_42, + "\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {299, "for_stmt", 11, states_43, + "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {300, "try_stmt", 13, states_44, + "\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {301, "with_stmt", 6, states_45, + "\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {302, "with_item", 4, states_46, + "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {303, "except_clause", 5, states_47, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000"}, + {304, "suite", 5, states_48, + "\344\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {305, "namedexpr_test", 4, states_49, + "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {306, "test", 6, states_50, + "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {307, "test_nocond", 2, states_51, + "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {308, "lambdef", 5, states_52, + "\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {309, "lambdef_nocond", 5, states_53, + "\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {310, "or_test", 2, states_54, + "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {311, "and_test", 2, states_55, + "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {312, "not_test", 3, states_56, + "\240\173\000\020\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {313, "comparison", 2, states_57, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {314, "comp_op", 4, states_58, + "\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\010\000\300\037\000\000\000\000"}, + {315, "star_expr", 3, states_59, + "\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {316, "expr", 2, states_60, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {317, "xor_expr", 2, states_61, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {318, "and_expr", 2, states_62, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {319, "shift_expr", 2, states_63, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {320, "arith_expr", 2, states_64, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {321, "term", 2, states_65, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {322, "factor", 3, states_66, + "\240\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {323, "power", 4, states_67, + "\040\172\000\000\220\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {324, "atom_expr", 3, states_68, + "\040\172\000\000\220\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {325, "atom", 9, states_69, + "\040\172\000\000\020\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {326, "testlist_comp", 5, states_70, + "\340\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {327, "trailer", 7, states_71, + "\040\100\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, + {328, "subscriptlist", 3, states_72, + "\240\173\000\024\260\007\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {329, "subscript", 5, states_73, + "\240\173\000\024\260\007\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {330, "sliceop", 3, states_74, + "\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {331, "exprlist", 3, states_75, + "\340\173\000\000\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {332, "testlist", 3, states_76, + "\240\173\000\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {333, "dictorsetmaker", 14, states_77, + "\340\173\000\024\260\007\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {334, "classdef", 8, states_78, + "\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {335, "arglist", 3, states_79, + "\340\173\000\024\260\007\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {336, "argument", 4, states_80, + "\340\173\000\024\260\007\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {337, "comp_iter", 2, states_81, + "\000\000\040\001\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {338, "sync_comp_for", 6, states_82, + "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {339, "comp_for", 3, states_83, + "\000\000\040\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {340, "comp_if", 4, states_84, + "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {341, "encoding_decl", 2, states_85, + "\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {342, "yield_expr", 3, states_86, + "\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {343, "yield_arg", 3, states_87, + "\340\173\100\024\260\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {344, "func_body_suite", 7, states_88, + "\344\373\325\376\270\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {345, "func_type_input", 3, states_89, + "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {346, "func_type", 6, states_90, + "\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {347, "typelist", 11, states_91, + "\340\173\000\024\260\007\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, +}; +static const label labels[183] = { + {0, "EMPTY"}, + {256, 0}, + {4, 0}, + {295, 0}, + {270, 0}, + {7, 0}, + {16, 0}, + {14, 0}, + {15, 0}, + {52, 0}, + {49, 0}, + {1, "False"}, + {1, "None"}, + {1, "True"}, + {9, 0}, + {1, "assert"}, + {1, "break"}, + {1, "class"}, + {1, "continue"}, + {1, "def"}, + {1, "del"}, + {1, "for"}, + {1, "from"}, + {1, "global"}, + {1, "if"}, + {1, "import"}, + {1, "lambda"}, + {1, "nonlocal"}, + {1, "not"}, + {1, "pass"}, + {1, "raise"}, + {1, "return"}, + {1, "try"}, + {1, "while"}, + {1, "with"}, + {1, "yield"}, + {25, 0}, + {31, 0}, + {56, 0}, + {55, 0}, + {1, 0}, + {2, 0}, + {3, 0}, + {257, 0}, + {0, 0}, + {269, 0}, + {258, 0}, + {332, 0}, + {259, 0}, + {291, 0}, + {8, 0}, + {335, 0}, + {260, 0}, + {261, 0}, + {262, 0}, + {334, 0}, + {263, 0}, + {264, 0}, + {51, 0}, + {11, 0}, + {306, 0}, + {58, 0}, + {344, 0}, + {265, 0}, + {35, 0}, + {266, 0}, + {12, 0}, + {22, 0}, + {17, 0}, + {267, 0}, + {268, 0}, + {271, 0}, + {13, 0}, + {294, 0}, + {276, 0}, + {272, 0}, + {278, 0}, + {292, 0}, + {284, 0}, + {293, 0}, + {277, 0}, + {274, 0}, + {273, 0}, + {275, 0}, + {342, 0}, + {315, 0}, + {40, 0}, + {41, 0}, + {46, 0}, + {38, 0}, + {36, 0}, + {37, 0}, + {48, 0}, + {39, 0}, + {44, 0}, + {45, 0}, + {50, 0}, + {43, 0}, + {42, 0}, + {331, 0}, + {279, 0}, + {280, 0}, + {283, 0}, + {281, 0}, + {282, 0}, + {286, 0}, + {285, 0}, + {290, 0}, + {23, 0}, + {289, 0}, + {287, 0}, + {1, "as"}, + {288, 0}, + {296, 0}, + {299, 0}, + {297, 0}, + {300, 0}, + {298, 0}, + {301, 0}, + {305, 0}, + {304, 0}, + {1, "elif"}, + {1, "else"}, + {1, "in"}, + {1, "finally"}, + {303, 0}, + {302, 0}, + {316, 0}, + {1, "except"}, + {5, 0}, + {6, 0}, + {53, 0}, + {308, 0}, + {310, 0}, + {307, 0}, + {309, 0}, + {311, 0}, + {1, "or"}, + {312, 0}, + {1, "and"}, + {313, 0}, + {314, 0}, + {28, 0}, + {20, 0}, + {29, 0}, + {27, 0}, + {21, 0}, + {30, 0}, + {1, "is"}, + {317, 0}, + {18, 0}, + {318, 0}, + {32, 0}, + {319, 0}, + {19, 0}, + {320, 0}, + {33, 0}, + {34, 0}, + {321, 0}, + {322, 0}, + {24, 0}, + {47, 0}, + {323, 0}, + {324, 0}, + {325, 0}, + {327, 0}, + {326, 0}, + {10, 0}, + {26, 0}, + {333, 0}, + {339, 0}, + {328, 0}, + {329, 0}, + {330, 0}, + {336, 0}, + {337, 0}, + {340, 0}, + {338, 0}, + {341, 0}, + {343, 0}, + {345, 0}, + {346, 0}, + {347, 0}, +}; +grammar _PyParser_Grammar = { + 92, + dfas, + {183, labels}, + 256 +}; diff --git a/python/Python/hamt.c b/python/Python/hamt.c new file mode 100755 index 0000000..5efc8d7 --- /dev/null +++ b/python/Python/hamt.c @@ -0,0 +1,2997 @@ +#include "Python.h" + +#include "pycore_hamt.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "structmember.h" + +/* +This file provides an implementation of an immutable mapping using the +Hash Array Mapped Trie (or HAMT) datastructure. + +This design allows to have: + +1. Efficient copy: immutable mappings can be copied by reference, + making it an O(1) operation. + +2. Efficient mutations: due to structural sharing, only a portion of + the trie needs to be copied when the collection is mutated. The + cost of set/delete operations is O(log N). + +3. Efficient lookups: O(log N). + +(where N is number of key/value items in the immutable mapping.) + + +HAMT +==== + +The core idea of HAMT is that the shape of the trie is encoded into the +hashes of keys. + +Say we want to store a K/V pair in our mapping. First, we calculate the +hash of K, let's say it's 19830128, or in binary: + + 0b1001011101001010101110000 = 19830128 + +Now let's partition this bit representation of the hash into blocks of +5 bits each: + + 0b00_00000_10010_11101_00101_01011_10000 = 19830128 + (6) (5) (4) (3) (2) (1) + +Each block of 5 bits represents a number between 0 and 31. So if we have +a tree that consists of nodes, each of which is an array of 32 pointers, +those 5-bit blocks will encode a position on a single tree level. + +For example, storing the key K with hash 19830128, results in the following +tree structure: + + (array of 32 pointers) + +---+ -- +----+----+----+ -- +----+ + root node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b10000 = 16 (1) + (level 1) +---+ -- +----+----+----+ -- +----+ + | + +---+ -- +----+----+----+ -- +----+ + a 2nd level node | 0 | .. | 10 | 11 | 12 | .. | 31 | 0b01011 = 11 (2) + +---+ -- +----+----+----+ -- +----+ + | + +---+ -- +----+----+----+ -- +----+ + a 3rd level node | 0 | .. | 04 | 05 | 06 | .. | 31 | 0b00101 = 5 (3) + +---+ -- +----+----+----+ -- +----+ + | + +---+ -- +----+----+----+----+ + a 4th level node | 0 | .. | 04 | 29 | 30 | 31 | 0b11101 = 29 (4) + +---+ -- +----+----+----+----+ + | + +---+ -- +----+----+----+ -- +----+ + a 5th level node | 0 | .. | 17 | 18 | 19 | .. | 31 | 0b10010 = 18 (5) + +---+ -- +----+----+----+ -- +----+ + | + +--------------+ + | + +---+ -- +----+----+----+ -- +----+ + a 6th level node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b00000 = 0 (6) + +---+ -- +----+----+----+ -- +----+ + | + V -- our value (or collision) + +To rehash: for a K/V pair, the hash of K encodes where in the tree V will +be stored. + +To optimize memory footprint and handle hash collisions, our implementation +uses three different types of nodes: + + * A Bitmap node; + * An Array node; + * A Collision node. + +Because we implement an immutable dictionary, our nodes are also +immutable. Therefore, when we need to modify a node, we copy it, and +do that modification to the copy. + + +Array Nodes +----------- + +These nodes are very simple. Essentially they are arrays of 32 pointers +we used to illustrate the high-level idea in the previous section. + +We use Array nodes only when we need to store more than 16 pointers +in a single node. + +Array nodes do not store key objects or value objects. They are used +only as an indirection level - their pointers point to other nodes in +the tree. + + +Bitmap Node +----------- + +Allocating a new 32-pointers array for every node of our tree would be +very expensive. Unless we store millions of keys, most of tree nodes would +be very sparse. + +When we have less than 16 elements in a node, we don't want to use the +Array node, that would mean that we waste a lot of memory. Instead, +we can use bitmap compression and can have just as many pointers +as we need! + +Bitmap nodes consist of two fields: + +1. An array of pointers. If a Bitmap node holds N elements, the + array will be of N pointers. + +2. A 32bit integer -- a bitmap field. If an N-th bit is set in the + bitmap, it means that the node has an N-th element. + +For example, say we need to store a 3 elements sparse array: + + +---+ -- +---+ -- +----+ -- +----+ + | 0 | .. | 4 | .. | 11 | .. | 17 | + +---+ -- +---+ -- +----+ -- +----+ + | | | + o1 o2 o3 + +We allocate a three-pointer Bitmap node. Its bitmap field will be +then set to: + + 0b_00100_00010_00000_10000 == (1 << 17) | (1 << 11) | (1 << 4) + +To check if our Bitmap node has an I-th element we can do: + + bitmap & (1 << I) + + +And here's a formula to calculate a position in our pointer array +which would correspond to an I-th element: + + popcount(bitmap & ((1 << I) - 1)) + + +Let's break it down: + + * `popcount` is a function that returns a number of bits set to 1; + + * `((1 << I) - 1)` is a mask to filter the bitmask to contain bits + set to the *right* of our bit. + + +So for our 17, 11, and 4 indexes: + + * bitmap & ((1 << 17) - 1) == 0b100000010000 => 2 bits are set => index is 2. + + * bitmap & ((1 << 11) - 1) == 0b10000 => 1 bit is set => index is 1. + + * bitmap & ((1 << 4) - 1) == 0b0 => 0 bits are set => index is 0. + + +To conclude: Bitmap nodes are just like Array nodes -- they can store +a number of pointers, but use bitmap compression to eliminate unused +pointers. + + +Bitmap nodes have two pointers for each item: + + +----+----+----+----+ -- +----+----+ + | k1 | v1 | k2 | v2 | .. | kN | vN | + +----+----+----+----+ -- +----+----+ + +When kI == NULL, vI points to another tree level. + +When kI != NULL, the actual key object is stored in kI, and its +value is stored in vI. + + +Collision Nodes +--------------- + +Collision nodes are simple arrays of pointers -- two pointers per +key/value. When there's a hash collision, say for k1/v1 and k2/v2 +we have `hash(k1)==hash(k2)`. Then our collision node will be: + + +----+----+----+----+ + | k1 | v1 | k2 | v2 | + +----+----+----+----+ + + +Tree Structure +-------------- + +All nodes are PyObjects. + +The `PyHamtObject` object has a pointer to the root node (h_root), +and has a length field (h_count). + +High-level functions accept a PyHamtObject object and dispatch to +lower-level functions depending on what kind of node h_root points to. + + +Operations +========== + +There are three fundamental operations on an immutable dictionary: + +1. "o.assoc(k, v)" will return a new immutable dictionary, that will be + a copy of "o", but with the "k/v" item set. + + Functions in this file: + + hamt_node_assoc, hamt_node_bitmap_assoc, + hamt_node_array_assoc, hamt_node_collision_assoc + + `hamt_node_assoc` function accepts a node object, and calls + other functions depending on its actual type. + +2. "o.find(k)" will lookup key "k" in "o". + + Functions: + + hamt_node_find, hamt_node_bitmap_find, + hamt_node_array_find, hamt_node_collision_find + +3. "o.without(k)" will return a new immutable dictionary, that will be + a copy of "o", buth without the "k" key. + + Functions: + + hamt_node_without, hamt_node_bitmap_without, + hamt_node_array_without, hamt_node_collision_without + + +Further Reading +=============== + +1. http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html + +2. http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html + +3. Clojure's PersistentHashMap implementation: + https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java + + +Debug +===== + +The HAMT datatype is accessible for testing purposes under the +`_testcapi` module: + + >>> from _testcapi import hamt + >>> h = hamt() + >>> h2 = h.set('a', 2) + >>> h3 = h2.set('b', 3) + >>> list(h3) + ['a', 'b'] + +When CPython is built in debug mode, a '__dump__()' method is available +to introspect the tree: + + >>> print(h3.__dump__()) + HAMT(len=2): + BitmapNode(size=4 count=2 bitmap=0b110 id=0x10eb9d9e8): + 'a': 2 + 'b': 3 +*/ + + +#define IS_ARRAY_NODE(node) (Py_TYPE(node) == &_PyHamt_ArrayNode_Type) +#define IS_BITMAP_NODE(node) (Py_TYPE(node) == &_PyHamt_BitmapNode_Type) +#define IS_COLLISION_NODE(node) (Py_TYPE(node) == &_PyHamt_CollisionNode_Type) + + +/* Return type for 'find' (lookup a key) functions. + + * F_ERROR - an error occurred; + * F_NOT_FOUND - the key was not found; + * F_FOUND - the key was found. +*/ +typedef enum {F_ERROR, F_NOT_FOUND, F_FOUND} hamt_find_t; + + +/* Return type for 'without' (delete a key) functions. + + * W_ERROR - an error occurred; + * W_NOT_FOUND - the key was not found: there's nothing to delete; + * W_EMPTY - the key was found: the node/tree would be empty + if the key is deleted; + * W_NEWNODE - the key was found: a new node/tree is returned + without that key. +*/ +typedef enum {W_ERROR, W_NOT_FOUND, W_EMPTY, W_NEWNODE} hamt_without_t; + + +/* Low-level iterator protocol type. + + * I_ITEM - a new item has been yielded; + * I_END - the whole tree was visited (similar to StopIteration). +*/ +typedef enum {I_ITEM, I_END} hamt_iter_t; + + +#define HAMT_ARRAY_NODE_SIZE 32 + + +typedef struct { + PyObject_HEAD + PyHamtNode *a_array[HAMT_ARRAY_NODE_SIZE]; + Py_ssize_t a_count; +} PyHamtNode_Array; + + +typedef struct { + PyObject_VAR_HEAD + uint32_t b_bitmap; + PyObject *b_array[1]; +} PyHamtNode_Bitmap; + + +typedef struct { + PyObject_VAR_HEAD + int32_t c_hash; + PyObject *c_array[1]; +} PyHamtNode_Collision; + + +static PyHamtNode_Bitmap *_empty_bitmap_node; +static PyHamtObject *_empty_hamt; + + +static PyHamtObject * +hamt_alloc(void); + +static PyHamtNode * +hamt_node_assoc(PyHamtNode *node, + uint32_t shift, int32_t hash, + PyObject *key, PyObject *val, int* added_leaf); + +static hamt_without_t +hamt_node_without(PyHamtNode *node, + uint32_t shift, int32_t hash, + PyObject *key, + PyHamtNode **new_node); + +static hamt_find_t +hamt_node_find(PyHamtNode *node, + uint32_t shift, int32_t hash, + PyObject *key, PyObject **val); + +#ifdef Py_DEBUG +static int +hamt_node_dump(PyHamtNode *node, + _PyUnicodeWriter *writer, int level); +#endif + +static PyHamtNode * +hamt_node_array_new(Py_ssize_t); + +static PyHamtNode * +hamt_node_collision_new(int32_t hash, Py_ssize_t size); + +static inline Py_ssize_t +hamt_node_collision_count(PyHamtNode_Collision *node); + + +#ifdef Py_DEBUG +static void +_hamt_node_array_validate(void *obj_raw) +{ + PyObject *obj = _PyObject_CAST(obj_raw); + assert(IS_ARRAY_NODE(obj)); + PyHamtNode_Array *node = (PyHamtNode_Array*)obj; + Py_ssize_t i = 0, count = 0; + for (; i < HAMT_ARRAY_NODE_SIZE; i++) { + if (node->a_array[i] != NULL) { + count++; + } + } + assert(count == node->a_count); +} + +#define VALIDATE_ARRAY_NODE(NODE) \ + do { _hamt_node_array_validate(NODE); } while (0); +#else +#define VALIDATE_ARRAY_NODE(NODE) +#endif + + +/* Returns -1 on error */ +static inline int32_t +hamt_hash(PyObject *o) +{ + Py_hash_t hash = PyObject_Hash(o); + +#if SIZEOF_PY_HASH_T <= 4 + return hash; +#else + if (hash == -1) { + /* exception */ + return -1; + } + + /* While it's suboptimal to reduce Python's 64 bit hash to + 32 bits via XOR, it seems that the resulting hash function + is good enough (this is also how Long type is hashed in Java.) + Storing 10, 100, 1000 Python strings results in a relatively + shallow and uniform tree structure. + + Please don't change this hashing algorithm, as there are many + tests that test some exact tree shape to cover all code paths. + */ + int32_t xored = (int32_t)(hash & 0xffffffffl) ^ (int32_t)(hash >> 32); + return xored == -1 ? -2 : xored; +#endif +} + +static inline uint32_t +hamt_mask(int32_t hash, uint32_t shift) +{ + return (((uint32_t)hash >> shift) & 0x01f); +} + +static inline uint32_t +hamt_bitpos(int32_t hash, uint32_t shift) +{ + return (uint32_t)1 << hamt_mask(hash, shift); +} + +static inline uint32_t +hamt_bitcount(uint32_t i) +{ + /* We could use native popcount instruction but that would + require to either add configure flags to enable SSE4.2 + support or to detect it dynamically. Otherwise, we have + a risk of CPython not working properly on older hardware. + + In practice, there's no observable difference in + performance between using a popcount instruction or the + following fallback code. + + The algorithm is copied from: + https://graphics.stanford.edu/~seander/bithacks.html + */ + i = i - ((i >> 1) & 0x55555555); + i = (i & 0x33333333) + ((i >> 2) & 0x33333333); + return (((i + (i >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; +} + +static inline uint32_t +hamt_bitindex(uint32_t bitmap, uint32_t bit) +{ + return hamt_bitcount(bitmap & (bit - 1)); +} + + +/////////////////////////////////// Dump Helpers +#ifdef Py_DEBUG + +static int +_hamt_dump_ident(_PyUnicodeWriter *writer, int level) +{ + /* Write `' ' * level` to the `writer` */ + PyObject *str = NULL; + PyObject *num = NULL; + PyObject *res = NULL; + int ret = -1; + + str = PyUnicode_FromString(" "); + if (str == NULL) { + goto error; + } + + num = PyLong_FromLong((long)level); + if (num == NULL) { + goto error; + } + + res = PyNumber_Multiply(str, num); + if (res == NULL) { + goto error; + } + + ret = _PyUnicodeWriter_WriteStr(writer, res); + +error: + Py_XDECREF(res); + Py_XDECREF(str); + Py_XDECREF(num); + return ret; +} + +static int +_hamt_dump_format(_PyUnicodeWriter *writer, const char *format, ...) +{ + /* A convenient helper combining _PyUnicodeWriter_WriteStr and + PyUnicode_FromFormatV. + */ + PyObject* msg; + int ret; + + 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 -1; + } + + ret = _PyUnicodeWriter_WriteStr(writer, msg); + Py_DECREF(msg); + return ret; +} + +#endif /* Py_DEBUG */ +/////////////////////////////////// Bitmap Node + + +static PyHamtNode * +hamt_node_bitmap_new(Py_ssize_t size) +{ + /* Create a new bitmap node of size 'size' */ + + PyHamtNode_Bitmap *node; + Py_ssize_t i; + + assert(size >= 0); + assert(size % 2 == 0); + + if (size == 0 && _empty_bitmap_node != NULL) { + Py_INCREF(_empty_bitmap_node); + return (PyHamtNode *)_empty_bitmap_node; + } + + /* No freelist; allocate a new bitmap node */ + node = PyObject_GC_NewVar( + PyHamtNode_Bitmap, &_PyHamt_BitmapNode_Type, size); + if (node == NULL) { + return NULL; + } + + Py_SIZE(node) = size; + + for (i = 0; i < size; i++) { + node->b_array[i] = NULL; + } + + node->b_bitmap = 0; + + _PyObject_GC_TRACK(node); + + if (size == 0 && _empty_bitmap_node == NULL) { + /* Since bitmap nodes are immutable, we can cache the instance + for size=0 and reuse it whenever we need an empty bitmap node. + */ + _empty_bitmap_node = node; + Py_INCREF(_empty_bitmap_node); + } + + return (PyHamtNode *)node; +} + +static inline Py_ssize_t +hamt_node_bitmap_count(PyHamtNode_Bitmap *node) +{ + return Py_SIZE(node) / 2; +} + +static PyHamtNode_Bitmap * +hamt_node_bitmap_clone(PyHamtNode_Bitmap *node) +{ + /* Clone a bitmap node; return a new one with the same child notes. */ + + PyHamtNode_Bitmap *clone; + Py_ssize_t i; + + clone = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(Py_SIZE(node)); + if (clone == NULL) { + return NULL; + } + + for (i = 0; i < Py_SIZE(node); i++) { + Py_XINCREF(node->b_array[i]); + clone->b_array[i] = node->b_array[i]; + } + + clone->b_bitmap = node->b_bitmap; + return clone; +} + +static PyHamtNode_Bitmap * +hamt_node_bitmap_clone_without(PyHamtNode_Bitmap *o, uint32_t bit) +{ + assert(bit & o->b_bitmap); + assert(hamt_node_bitmap_count(o) > 1); + + PyHamtNode_Bitmap *new = (PyHamtNode_Bitmap *)hamt_node_bitmap_new( + Py_SIZE(o) - 2); + if (new == NULL) { + return NULL; + } + + uint32_t idx = hamt_bitindex(o->b_bitmap, bit); + uint32_t key_idx = 2 * idx; + uint32_t val_idx = key_idx + 1; + uint32_t i; + + for (i = 0; i < key_idx; i++) { + Py_XINCREF(o->b_array[i]); + new->b_array[i] = o->b_array[i]; + } + + assert(Py_SIZE(o) >= 0 && Py_SIZE(o) <= 32); + for (i = val_idx + 1; i < (uint32_t)Py_SIZE(o); i++) { + Py_XINCREF(o->b_array[i]); + new->b_array[i - 2] = o->b_array[i]; + } + + new->b_bitmap = o->b_bitmap & ~bit; + return new; +} + +static PyHamtNode * +hamt_node_new_bitmap_or_collision(uint32_t shift, + PyObject *key1, PyObject *val1, + int32_t key2_hash, + PyObject *key2, PyObject *val2) +{ + /* Helper method. Creates a new node for key1/val and key2/val2 + pairs. + + If key1 hash is equal to the hash of key2, a Collision node + will be created. If they are not equal, a Bitmap node is + created. + */ + + int32_t key1_hash = hamt_hash(key1); + if (key1_hash == -1) { + return NULL; + } + + if (key1_hash == key2_hash) { + PyHamtNode_Collision *n; + n = (PyHamtNode_Collision *)hamt_node_collision_new(key1_hash, 4); + if (n == NULL) { + return NULL; + } + + Py_INCREF(key1); + n->c_array[0] = key1; + Py_INCREF(val1); + n->c_array[1] = val1; + + Py_INCREF(key2); + n->c_array[2] = key2; + Py_INCREF(val2); + n->c_array[3] = val2; + + return (PyHamtNode *)n; + } + else { + int added_leaf = 0; + PyHamtNode *n = hamt_node_bitmap_new(0); + if (n == NULL) { + return NULL; + } + + PyHamtNode *n2 = hamt_node_assoc( + n, shift, key1_hash, key1, val1, &added_leaf); + Py_DECREF(n); + if (n2 == NULL) { + return NULL; + } + + n = hamt_node_assoc(n2, shift, key2_hash, key2, val2, &added_leaf); + Py_DECREF(n2); + if (n == NULL) { + return NULL; + } + + return n; + } +} + +static PyHamtNode * +hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, + uint32_t shift, int32_t hash, + PyObject *key, PyObject *val, int* added_leaf) +{ + /* assoc operation for bitmap nodes. + + Return: a new node, or self if key/val already is in the + collection. + + 'added_leaf' is later used in '_PyHamt_Assoc' to determine if + `hamt.set(key, val)` increased the size of the collection. + */ + + uint32_t bit = hamt_bitpos(hash, shift); + uint32_t idx = hamt_bitindex(self->b_bitmap, bit); + + /* Bitmap node layout: + + +------+------+------+------+ --- +------+------+ + | key1 | val1 | key2 | val2 | ... | keyN | valN | + +------+------+------+------+ --- +------+------+ + where `N < Py_SIZE(node)`. + + The `node->b_bitmap` field is a bitmap. For a given + `(shift, hash)` pair we can determine: + + - If this node has the corresponding key/val slots. + - The index of key/val slots. + */ + + if (self->b_bitmap & bit) { + /* The key is set in this node */ + + uint32_t key_idx = 2 * idx; + uint32_t val_idx = key_idx + 1; + + assert(val_idx < (size_t)Py_SIZE(self)); + + PyObject *key_or_null = self->b_array[key_idx]; + PyObject *val_or_node = self->b_array[val_idx]; + + if (key_or_null == NULL) { + /* key is NULL. This means that we have a few keys + that have the same (hash, shift) pair. */ + + assert(val_or_node != NULL); + + PyHamtNode *sub_node = hamt_node_assoc( + (PyHamtNode *)val_or_node, + shift + 5, hash, key, val, added_leaf); + if (sub_node == NULL) { + return NULL; + } + + if (val_or_node == (PyObject *)sub_node) { + Py_DECREF(sub_node); + Py_INCREF(self); + return (PyHamtNode *)self; + } + + PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); + if (ret == NULL) { + return NULL; + } + Py_SETREF(ret->b_array[val_idx], (PyObject*)sub_node); + return (PyHamtNode *)ret; + } + + assert(key != NULL); + /* key is not NULL. This means that we have only one other + key in this collection that matches our hash for this shift. */ + + int comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ); + if (comp_err < 0) { /* exception in __eq__ */ + return NULL; + } + if (comp_err == 1) { /* key == key_or_null */ + if (val == val_or_node) { + /* we already have the same key/val pair; return self. */ + Py_INCREF(self); + return (PyHamtNode *)self; + } + + /* We're setting a new value for the key we had before. + Make a new bitmap node with a replaced value, and return it. */ + PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); + if (ret == NULL) { + return NULL; + } + Py_INCREF(val); + Py_SETREF(ret->b_array[val_idx], val); + return (PyHamtNode *)ret; + } + + /* It's a new key, and it has the same index as *one* another key. + We have a collision. We need to create a new node which will + combine the existing key and the key we're adding. + + `hamt_node_new_bitmap_or_collision` will either create a new + Collision node if the keys have identical hashes, or + a new Bitmap node. + */ + PyHamtNode *sub_node = hamt_node_new_bitmap_or_collision( + shift + 5, + key_or_null, val_or_node, /* existing key/val */ + hash, + key, val /* new key/val */ + ); + if (sub_node == NULL) { + return NULL; + } + + PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); + if (ret == NULL) { + Py_DECREF(sub_node); + return NULL; + } + Py_SETREF(ret->b_array[key_idx], NULL); + Py_SETREF(ret->b_array[val_idx], (PyObject *)sub_node); + + *added_leaf = 1; + return (PyHamtNode *)ret; + } + else { + /* There was no key before with the same (shift,hash). */ + + uint32_t n = hamt_bitcount(self->b_bitmap); + + if (n >= 16) { + /* When we have a situation where we want to store more + than 16 nodes at one level of the tree, we no longer + want to use the Bitmap node with bitmap encoding. + + Instead we start using an Array node, which has + simpler (faster) implementation at the expense of + having prealocated 32 pointers for its keys/values + pairs. + + Small hamt objects (<30 keys) usually don't have any + Array nodes at all. Between ~30 and ~400 keys hamt + objects usually have one Array node, and usually it's + a root node. + */ + + uint32_t jdx = hamt_mask(hash, shift); + /* 'jdx' is the index of where the new key should be added + in the new Array node we're about to create. */ + + PyHamtNode *empty = NULL; + PyHamtNode_Array *new_node = NULL; + PyHamtNode *res = NULL; + + /* Create a new Array node. */ + new_node = (PyHamtNode_Array *)hamt_node_array_new(n + 1); + if (new_node == NULL) { + goto fin; + } + + /* Create an empty bitmap node for the next + hamt_node_assoc call. */ + empty = hamt_node_bitmap_new(0); + if (empty == NULL) { + goto fin; + } + + /* Make a new bitmap node for the key/val we're adding. + Set that bitmap node to new-array-node[jdx]. */ + new_node->a_array[jdx] = hamt_node_assoc( + empty, shift + 5, hash, key, val, added_leaf); + if (new_node->a_array[jdx] == NULL) { + goto fin; + } + + /* Copy existing key/value pairs from the current Bitmap + node to the new Array node we've just created. */ + Py_ssize_t i, j; + for (i = 0, j = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + if (((self->b_bitmap >> i) & 1) != 0) { + /* Ensure we don't accidentally override `jdx` element + we set few lines above. + */ + assert(new_node->a_array[i] == NULL); + + if (self->b_array[j] == NULL) { + new_node->a_array[i] = + (PyHamtNode *)self->b_array[j + 1]; + Py_INCREF(new_node->a_array[i]); + } + else { + int32_t rehash = hamt_hash(self->b_array[j]); + if (rehash == -1) { + goto fin; + } + + new_node->a_array[i] = hamt_node_assoc( + empty, shift + 5, + rehash, + self->b_array[j], + self->b_array[j + 1], + added_leaf); + + if (new_node->a_array[i] == NULL) { + goto fin; + } + } + j += 2; + } + } + + VALIDATE_ARRAY_NODE(new_node) + + /* That's it! */ + res = (PyHamtNode *)new_node; + + fin: + Py_XDECREF(empty); + if (res == NULL) { + Py_XDECREF(new_node); + } + return res; + } + else { + /* We have less than 16 keys at this level; let's just + create a new bitmap node out of this node with the + new key/val pair added. */ + + uint32_t key_idx = 2 * idx; + uint32_t val_idx = key_idx + 1; + uint32_t i; + + *added_leaf = 1; + + /* Allocate new Bitmap node which can have one more key/val + pair in addition to what we have already. */ + PyHamtNode_Bitmap *new_node = + (PyHamtNode_Bitmap *)hamt_node_bitmap_new(2 * (n + 1)); + if (new_node == NULL) { + return NULL; + } + + /* Copy all keys/values that will be before the new key/value + we are adding. */ + for (i = 0; i < key_idx; i++) { + Py_XINCREF(self->b_array[i]); + new_node->b_array[i] = self->b_array[i]; + } + + /* Set the new key/value to the new Bitmap node. */ + Py_INCREF(key); + new_node->b_array[key_idx] = key; + Py_INCREF(val); + new_node->b_array[val_idx] = val; + + /* Copy all keys/values that will be after the new key/value + we are adding. */ + assert(Py_SIZE(self) >= 0 && Py_SIZE(self) <= 32); + for (i = key_idx; i < (uint32_t)Py_SIZE(self); i++) { + Py_XINCREF(self->b_array[i]); + new_node->b_array[i + 2] = self->b_array[i]; + } + + new_node->b_bitmap = self->b_bitmap | bit; + return (PyHamtNode *)new_node; + } + } +} + +static hamt_without_t +hamt_node_bitmap_without(PyHamtNode_Bitmap *self, + uint32_t shift, int32_t hash, + PyObject *key, + PyHamtNode **new_node) +{ + uint32_t bit = hamt_bitpos(hash, shift); + if ((self->b_bitmap & bit) == 0) { + return W_NOT_FOUND; + } + + uint32_t idx = hamt_bitindex(self->b_bitmap, bit); + + uint32_t key_idx = 2 * idx; + uint32_t val_idx = key_idx + 1; + + PyObject *key_or_null = self->b_array[key_idx]; + PyObject *val_or_node = self->b_array[val_idx]; + + if (key_or_null == NULL) { + /* key == NULL means that 'value' is another tree node. */ + + PyHamtNode *sub_node = NULL; + + hamt_without_t res = hamt_node_without( + (PyHamtNode *)val_or_node, + shift + 5, hash, key, &sub_node); + + switch (res) { + case W_EMPTY: + /* It's impossible for us to receive a W_EMPTY here: + + - Array nodes are converted to Bitmap nodes when + we delete 16th item from them; + + - Collision nodes are converted to Bitmap when + there is one item in them; + + - Bitmap node's without() inlines single-item + sub-nodes. + + So in no situation we can have a single-item + Bitmap child of another Bitmap node. + */ + Py_UNREACHABLE(); + + case W_NEWNODE: { + assert(sub_node != NULL); + + if (IS_BITMAP_NODE(sub_node)) { + PyHamtNode_Bitmap *sub_tree = (PyHamtNode_Bitmap *)sub_node; + if (hamt_node_bitmap_count(sub_tree) == 1 && + sub_tree->b_array[0] != NULL) + { + /* A bitmap node with one key/value pair. Just + merge it into this node. + + Note that we don't inline Bitmap nodes that + have a NULL key -- those nodes point to another + tree level, and we cannot simply move tree levels + up or down. + */ + + PyHamtNode_Bitmap *clone = hamt_node_bitmap_clone(self); + if (clone == NULL) { + Py_DECREF(sub_node); + return W_ERROR; + } + + PyObject *key = sub_tree->b_array[0]; + PyObject *val = sub_tree->b_array[1]; + + Py_INCREF(key); + Py_XSETREF(clone->b_array[key_idx], key); + Py_INCREF(val); + Py_SETREF(clone->b_array[val_idx], val); + + Py_DECREF(sub_tree); + + *new_node = (PyHamtNode *)clone; + return W_NEWNODE; + } + } + +#ifdef Py_DEBUG + /* Ensure that Collision.without implementation + converts to Bitmap nodes itself. + */ + if (IS_COLLISION_NODE(sub_node)) { + assert(hamt_node_collision_count( + (PyHamtNode_Collision*)sub_node) > 1); + } +#endif + + PyHamtNode_Bitmap *clone = hamt_node_bitmap_clone(self); + if (clone == NULL) { + return W_ERROR; + } + + Py_SETREF(clone->b_array[val_idx], + (PyObject *)sub_node); /* borrow */ + + *new_node = (PyHamtNode *)clone; + return W_NEWNODE; + } + + case W_ERROR: + case W_NOT_FOUND: + assert(sub_node == NULL); + return res; + + default: + Py_UNREACHABLE(); + } + } + else { + /* We have a regular key/value pair */ + + int cmp = PyObject_RichCompareBool(key_or_null, key, Py_EQ); + if (cmp < 0) { + return W_ERROR; + } + if (cmp == 0) { + return W_NOT_FOUND; + } + + if (hamt_node_bitmap_count(self) == 1) { + return W_EMPTY; + } + + *new_node = (PyHamtNode *) + hamt_node_bitmap_clone_without(self, bit); + if (*new_node == NULL) { + return W_ERROR; + } + + return W_NEWNODE; + } +} + +static hamt_find_t +hamt_node_bitmap_find(PyHamtNode_Bitmap *self, + uint32_t shift, int32_t hash, + PyObject *key, PyObject **val) +{ + /* Lookup a key in a Bitmap node. */ + + uint32_t bit = hamt_bitpos(hash, shift); + uint32_t idx; + uint32_t key_idx; + uint32_t val_idx; + PyObject *key_or_null; + PyObject *val_or_node; + int comp_err; + + if ((self->b_bitmap & bit) == 0) { + return F_NOT_FOUND; + } + + idx = hamt_bitindex(self->b_bitmap, bit); + key_idx = idx * 2; + val_idx = key_idx + 1; + + assert(val_idx < (size_t)Py_SIZE(self)); + + key_or_null = self->b_array[key_idx]; + val_or_node = self->b_array[val_idx]; + + if (key_or_null == NULL) { + /* There are a few keys that have the same hash at the current shift + that match our key. Dispatch the lookup further down the tree. */ + assert(val_or_node != NULL); + return hamt_node_find((PyHamtNode *)val_or_node, + shift + 5, hash, key, val); + } + + /* We have only one key -- a potential match. Let's compare if the + key we are looking at is equal to the key we are looking for. */ + assert(key != NULL); + comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ); + if (comp_err < 0) { /* exception in __eq__ */ + return F_ERROR; + } + if (comp_err == 1) { /* key == key_or_null */ + *val = val_or_node; + return F_FOUND; + } + + return F_NOT_FOUND; +} + +static int +hamt_node_bitmap_traverse(PyHamtNode_Bitmap *self, visitproc visit, void *arg) +{ + /* Bitmap's tp_traverse */ + + Py_ssize_t i; + + for (i = Py_SIZE(self); --i >= 0; ) { + Py_VISIT(self->b_array[i]); + } + + return 0; +} + +static void +hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self) +{ + /* Bitmap's tp_dealloc */ + + Py_ssize_t len = Py_SIZE(self); + Py_ssize_t i; + + PyObject_GC_UnTrack(self); + Py_TRASHCAN_BEGIN(self, hamt_node_bitmap_dealloc) + + if (len > 0) { + i = len; + while (--i >= 0) { + Py_XDECREF(self->b_array[i]); + } + } + + Py_TYPE(self)->tp_free((PyObject *)self); + Py_TRASHCAN_END +} + +#ifdef Py_DEBUG +static int +hamt_node_bitmap_dump(PyHamtNode_Bitmap *node, + _PyUnicodeWriter *writer, int level) +{ + /* Debug build: __dump__() method implementation for Bitmap nodes. */ + + Py_ssize_t i; + PyObject *tmp1; + PyObject *tmp2; + + if (_hamt_dump_ident(writer, level + 1)) { + goto error; + } + + if (_hamt_dump_format(writer, "BitmapNode(size=%zd count=%zd ", + Py_SIZE(node), Py_SIZE(node) / 2)) + { + goto error; + } + + tmp1 = PyLong_FromUnsignedLong(node->b_bitmap); + if (tmp1 == NULL) { + goto error; + } + tmp2 = _PyLong_Format(tmp1, 2); + Py_DECREF(tmp1); + if (tmp2 == NULL) { + goto error; + } + if (_hamt_dump_format(writer, "bitmap=%S id=%p):\n", tmp2, node)) { + Py_DECREF(tmp2); + goto error; + } + Py_DECREF(tmp2); + + for (i = 0; i < Py_SIZE(node); i += 2) { + PyObject *key_or_null = node->b_array[i]; + PyObject *val_or_node = node->b_array[i + 1]; + + if (_hamt_dump_ident(writer, level + 2)) { + goto error; + } + + if (key_or_null == NULL) { + if (_hamt_dump_format(writer, "NULL:\n")) { + goto error; + } + + if (hamt_node_dump((PyHamtNode *)val_or_node, + writer, level + 2)) + { + goto error; + } + } + else { + if (_hamt_dump_format(writer, "%R: %R", key_or_null, + val_or_node)) + { + goto error; + } + } + + if (_hamt_dump_format(writer, "\n")) { + goto error; + } + } + + return 0; +error: + return -1; +} +#endif /* Py_DEBUG */ + + +/////////////////////////////////// Collision Node + + +static PyHamtNode * +hamt_node_collision_new(int32_t hash, Py_ssize_t size) +{ + /* Create a new Collision node. */ + + PyHamtNode_Collision *node; + Py_ssize_t i; + + assert(size >= 4); + assert(size % 2 == 0); + + node = PyObject_GC_NewVar( + PyHamtNode_Collision, &_PyHamt_CollisionNode_Type, size); + if (node == NULL) { + return NULL; + } + + for (i = 0; i < size; i++) { + node->c_array[i] = NULL; + } + + Py_SIZE(node) = size; + node->c_hash = hash; + + _PyObject_GC_TRACK(node); + + return (PyHamtNode *)node; +} + +static hamt_find_t +hamt_node_collision_find_index(PyHamtNode_Collision *self, PyObject *key, + Py_ssize_t *idx) +{ + /* Lookup `key` in the Collision node `self`. Set the index of the + found key to 'idx'. */ + + Py_ssize_t i; + PyObject *el; + + for (i = 0; i < Py_SIZE(self); i += 2) { + el = self->c_array[i]; + + assert(el != NULL); + int cmp = PyObject_RichCompareBool(key, el, Py_EQ); + if (cmp < 0) { + return F_ERROR; + } + if (cmp == 1) { + *idx = i; + return F_FOUND; + } + } + + return F_NOT_FOUND; +} + +static PyHamtNode * +hamt_node_collision_assoc(PyHamtNode_Collision *self, + uint32_t shift, int32_t hash, + PyObject *key, PyObject *val, int* added_leaf) +{ + /* Set a new key to this level (currently a Collision node) + of the tree. */ + + if (hash == self->c_hash) { + /* The hash of the 'key' we are adding matches the hash of + other keys in this Collision node. */ + + Py_ssize_t key_idx = -1; + hamt_find_t found; + PyHamtNode_Collision *new_node; + Py_ssize_t i; + + /* Let's try to lookup the new 'key', maybe we already have it. */ + found = hamt_node_collision_find_index(self, key, &key_idx); + switch (found) { + case F_ERROR: + /* Exception. */ + return NULL; + + case F_NOT_FOUND: + /* This is a totally new key. Clone the current node, + add a new key/value to the cloned node. */ + + new_node = (PyHamtNode_Collision *)hamt_node_collision_new( + self->c_hash, Py_SIZE(self) + 2); + if (new_node == NULL) { + return NULL; + } + + for (i = 0; i < Py_SIZE(self); i++) { + Py_INCREF(self->c_array[i]); + new_node->c_array[i] = self->c_array[i]; + } + + Py_INCREF(key); + new_node->c_array[i] = key; + Py_INCREF(val); + new_node->c_array[i + 1] = val; + + *added_leaf = 1; + return (PyHamtNode *)new_node; + + case F_FOUND: + /* There's a key which is equal to the key we are adding. */ + + assert(key_idx >= 0); + assert(key_idx < Py_SIZE(self)); + Py_ssize_t val_idx = key_idx + 1; + + if (self->c_array[val_idx] == val) { + /* We're setting a key/value pair that's already set. */ + Py_INCREF(self); + return (PyHamtNode *)self; + } + + /* We need to replace old value for the key + with a new value. Create a new Collision node.*/ + new_node = (PyHamtNode_Collision *)hamt_node_collision_new( + self->c_hash, Py_SIZE(self)); + if (new_node == NULL) { + return NULL; + } + + /* Copy all elements of the old node to the new one. */ + for (i = 0; i < Py_SIZE(self); i++) { + Py_INCREF(self->c_array[i]); + new_node->c_array[i] = self->c_array[i]; + } + + /* Replace the old value with the new value for the our key. */ + Py_DECREF(new_node->c_array[val_idx]); + Py_INCREF(val); + new_node->c_array[val_idx] = val; + + return (PyHamtNode *)new_node; + + default: + Py_UNREACHABLE(); + } + } + else { + /* The hash of the new key is different from the hash that + all keys of this Collision node have. + + Create a Bitmap node inplace with two children: + key/value pair that we're adding, and the Collision node + we're replacing on this tree level. + */ + + PyHamtNode_Bitmap *new_node; + PyHamtNode *assoc_res; + + new_node = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(2); + if (new_node == NULL) { + return NULL; + } + new_node->b_bitmap = hamt_bitpos(self->c_hash, shift); + Py_INCREF(self); + new_node->b_array[1] = (PyObject*) self; + + assoc_res = hamt_node_bitmap_assoc( + new_node, shift, hash, key, val, added_leaf); + Py_DECREF(new_node); + return assoc_res; + } +} + +static inline Py_ssize_t +hamt_node_collision_count(PyHamtNode_Collision *node) +{ + return Py_SIZE(node) / 2; +} + +static hamt_without_t +hamt_node_collision_without(PyHamtNode_Collision *self, + uint32_t shift, int32_t hash, + PyObject *key, + PyHamtNode **new_node) +{ + if (hash != self->c_hash) { + return W_NOT_FOUND; + } + + Py_ssize_t key_idx = -1; + hamt_find_t found = hamt_node_collision_find_index(self, key, &key_idx); + + switch (found) { + case F_ERROR: + return W_ERROR; + + case F_NOT_FOUND: + return W_NOT_FOUND; + + case F_FOUND: + assert(key_idx >= 0); + assert(key_idx < Py_SIZE(self)); + + Py_ssize_t new_count = hamt_node_collision_count(self) - 1; + + if (new_count == 0) { + /* The node has only one key/value pair and it's for the + key we're trying to delete. So a new node will be empty + after the removal. + */ + return W_EMPTY; + } + + if (new_count == 1) { + /* The node has two keys, and after deletion the + new Collision node would have one. Collision nodes + with one key shouldn't exist, so convert it to a + Bitmap node. + */ + PyHamtNode_Bitmap *node = (PyHamtNode_Bitmap *) + hamt_node_bitmap_new(2); + if (node == NULL) { + return W_ERROR; + } + + if (key_idx == 0) { + Py_INCREF(self->c_array[2]); + node->b_array[0] = self->c_array[2]; + Py_INCREF(self->c_array[3]); + node->b_array[1] = self->c_array[3]; + } + else { + assert(key_idx == 2); + Py_INCREF(self->c_array[0]); + node->b_array[0] = self->c_array[0]; + Py_INCREF(self->c_array[1]); + node->b_array[1] = self->c_array[1]; + } + + node->b_bitmap = hamt_bitpos(hash, shift); + + *new_node = (PyHamtNode *)node; + return W_NEWNODE; + } + + /* Allocate a new Collision node with capacity for one + less key/value pair */ + PyHamtNode_Collision *new = (PyHamtNode_Collision *) + hamt_node_collision_new( + self->c_hash, Py_SIZE(self) - 2); + if (new == NULL) { + return W_ERROR; + } + + /* Copy all other keys from `self` to `new` */ + Py_ssize_t i; + for (i = 0; i < key_idx; i++) { + Py_INCREF(self->c_array[i]); + new->c_array[i] = self->c_array[i]; + } + for (i = key_idx + 2; i < Py_SIZE(self); i++) { + Py_INCREF(self->c_array[i]); + new->c_array[i - 2] = self->c_array[i]; + } + + *new_node = (PyHamtNode*)new; + return W_NEWNODE; + + default: + Py_UNREACHABLE(); + } +} + +static hamt_find_t +hamt_node_collision_find(PyHamtNode_Collision *self, + uint32_t shift, int32_t hash, + PyObject *key, PyObject **val) +{ + /* Lookup `key` in the Collision node `self`. Set the value + for the found key to 'val'. */ + + Py_ssize_t idx = -1; + hamt_find_t res; + + res = hamt_node_collision_find_index(self, key, &idx); + if (res == F_ERROR || res == F_NOT_FOUND) { + return res; + } + + assert(idx >= 0); + assert(idx + 1 < Py_SIZE(self)); + + *val = self->c_array[idx + 1]; + assert(*val != NULL); + + return F_FOUND; +} + + +static int +hamt_node_collision_traverse(PyHamtNode_Collision *self, + visitproc visit, void *arg) +{ + /* Collision's tp_traverse */ + + Py_ssize_t i; + + for (i = Py_SIZE(self); --i >= 0; ) { + Py_VISIT(self->c_array[i]); + } + + return 0; +} + +static void +hamt_node_collision_dealloc(PyHamtNode_Collision *self) +{ + /* Collision's tp_dealloc */ + + Py_ssize_t len = Py_SIZE(self); + + PyObject_GC_UnTrack(self); + Py_TRASHCAN_BEGIN(self, hamt_node_collision_dealloc) + + if (len > 0) { + + while (--len >= 0) { + Py_XDECREF(self->c_array[len]); + } + } + + Py_TYPE(self)->tp_free((PyObject *)self); + Py_TRASHCAN_END +} + +#ifdef Py_DEBUG +static int +hamt_node_collision_dump(PyHamtNode_Collision *node, + _PyUnicodeWriter *writer, int level) +{ + /* Debug build: __dump__() method implementation for Collision nodes. */ + + Py_ssize_t i; + + if (_hamt_dump_ident(writer, level + 1)) { + goto error; + } + + if (_hamt_dump_format(writer, "CollisionNode(size=%zd id=%p):\n", + Py_SIZE(node), node)) + { + goto error; + } + + for (i = 0; i < Py_SIZE(node); i += 2) { + PyObject *key = node->c_array[i]; + PyObject *val = node->c_array[i + 1]; + + if (_hamt_dump_ident(writer, level + 2)) { + goto error; + } + + if (_hamt_dump_format(writer, "%R: %R\n", key, val)) { + goto error; + } + } + + return 0; +error: + return -1; +} +#endif /* Py_DEBUG */ + + +/////////////////////////////////// Array Node + + +static PyHamtNode * +hamt_node_array_new(Py_ssize_t count) +{ + Py_ssize_t i; + + PyHamtNode_Array *node = PyObject_GC_New( + PyHamtNode_Array, &_PyHamt_ArrayNode_Type); + if (node == NULL) { + return NULL; + } + + for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + node->a_array[i] = NULL; + } + + node->a_count = count; + + _PyObject_GC_TRACK(node); + return (PyHamtNode *)node; +} + +static PyHamtNode_Array * +hamt_node_array_clone(PyHamtNode_Array *node) +{ + PyHamtNode_Array *clone; + Py_ssize_t i; + + VALIDATE_ARRAY_NODE(node) + + /* Create a new Array node. */ + clone = (PyHamtNode_Array *)hamt_node_array_new(node->a_count); + if (clone == NULL) { + return NULL; + } + + /* Copy all elements from the current Array node to the new one. */ + for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + Py_XINCREF(node->a_array[i]); + clone->a_array[i] = node->a_array[i]; + } + + VALIDATE_ARRAY_NODE(clone) + return clone; +} + +static PyHamtNode * +hamt_node_array_assoc(PyHamtNode_Array *self, + uint32_t shift, int32_t hash, + PyObject *key, PyObject *val, int* added_leaf) +{ + /* Set a new key to this level (currently a Collision node) + of the tree. + + Array nodes don't store values, they can only point to + other nodes. They are simple arrays of 32 BaseNode pointers/ + */ + + uint32_t idx = hamt_mask(hash, shift); + PyHamtNode *node = self->a_array[idx]; + PyHamtNode *child_node; + PyHamtNode_Array *new_node; + Py_ssize_t i; + + if (node == NULL) { + /* There's no child node for the given hash. Create a new + Bitmap node for this key. */ + + PyHamtNode_Bitmap *empty = NULL; + + /* Get an empty Bitmap node to work with. */ + empty = (PyHamtNode_Bitmap *)hamt_node_bitmap_new(0); + if (empty == NULL) { + return NULL; + } + + /* Set key/val to the newly created empty Bitmap, thus + creating a new Bitmap node with our key/value pair. */ + child_node = hamt_node_bitmap_assoc( + empty, + shift + 5, hash, key, val, added_leaf); + Py_DECREF(empty); + if (child_node == NULL) { + return NULL; + } + + /* Create a new Array node. */ + new_node = (PyHamtNode_Array *)hamt_node_array_new(self->a_count + 1); + if (new_node == NULL) { + Py_DECREF(child_node); + return NULL; + } + + /* Copy all elements from the current Array node to the + new one. */ + for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + Py_XINCREF(self->a_array[i]); + new_node->a_array[i] = self->a_array[i]; + } + + assert(new_node->a_array[idx] == NULL); + new_node->a_array[idx] = child_node; /* borrow */ + VALIDATE_ARRAY_NODE(new_node) + } + else { + /* There's a child node for the given hash. + Set the key to it./ */ + child_node = hamt_node_assoc( + node, shift + 5, hash, key, val, added_leaf); + if (child_node == NULL) { + return NULL; + } + else if (child_node == (PyHamtNode *)self) { + Py_DECREF(child_node); + return (PyHamtNode *)self; + } + + new_node = hamt_node_array_clone(self); + if (new_node == NULL) { + Py_DECREF(child_node); + return NULL; + } + + Py_SETREF(new_node->a_array[idx], child_node); /* borrow */ + VALIDATE_ARRAY_NODE(new_node) + } + + return (PyHamtNode *)new_node; +} + +static hamt_without_t +hamt_node_array_without(PyHamtNode_Array *self, + uint32_t shift, int32_t hash, + PyObject *key, + PyHamtNode **new_node) +{ + uint32_t idx = hamt_mask(hash, shift); + PyHamtNode *node = self->a_array[idx]; + + if (node == NULL) { + return W_NOT_FOUND; + } + + PyHamtNode *sub_node = NULL; + hamt_without_t res = hamt_node_without( + (PyHamtNode *)node, + shift + 5, hash, key, &sub_node); + + switch (res) { + case W_NOT_FOUND: + case W_ERROR: + assert(sub_node == NULL); + return res; + + case W_NEWNODE: { + /* We need to replace a node at the `idx` index. + Clone this node and replace. + */ + assert(sub_node != NULL); + + PyHamtNode_Array *clone = hamt_node_array_clone(self); + if (clone == NULL) { + Py_DECREF(sub_node); + return W_ERROR; + } + + Py_SETREF(clone->a_array[idx], sub_node); /* borrow */ + *new_node = (PyHamtNode*)clone; /* borrow */ + return W_NEWNODE; + } + + case W_EMPTY: { + assert(sub_node == NULL); + /* We need to remove a node at the `idx` index. + Calculate the size of the replacement Array node. + */ + Py_ssize_t new_count = self->a_count - 1; + + if (new_count == 0) { + return W_EMPTY; + } + + if (new_count >= 16) { + /* We convert Bitmap nodes to Array nodes, when a + Bitmap node needs to store more than 15 key/value + pairs. So we will create a new Array node if we + the number of key/values after deletion is still + greater than 15. + */ + + PyHamtNode_Array *new = hamt_node_array_clone(self); + if (new == NULL) { + return W_ERROR; + } + new->a_count = new_count; + Py_CLEAR(new->a_array[idx]); + + *new_node = (PyHamtNode*)new; /* borrow */ + return W_NEWNODE; + } + + /* New Array node would have less than 16 key/value + pairs. We need to create a replacement Bitmap node. */ + + Py_ssize_t bitmap_size = new_count * 2; + uint32_t bitmap = 0; + + PyHamtNode_Bitmap *new = (PyHamtNode_Bitmap *) + hamt_node_bitmap_new(bitmap_size); + if (new == NULL) { + return W_ERROR; + } + + Py_ssize_t new_i = 0; + for (uint32_t i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + if (i == idx) { + /* Skip the node we are deleting. */ + continue; + } + + PyHamtNode *node = self->a_array[i]; + if (node == NULL) { + /* Skip any missing nodes. */ + continue; + } + + bitmap |= 1U << i; + + if (IS_BITMAP_NODE(node)) { + PyHamtNode_Bitmap *child = (PyHamtNode_Bitmap *)node; + + if (hamt_node_bitmap_count(child) == 1 && + child->b_array[0] != NULL) + { + /* node is a Bitmap with one key/value pair, just + merge it into the new Bitmap node we're building. + + Note that we don't inline Bitmap nodes that + have a NULL key -- those nodes point to another + tree level, and we cannot simply move tree levels + up or down. + */ + PyObject *key = child->b_array[0]; + PyObject *val = child->b_array[1]; + + Py_INCREF(key); + new->b_array[new_i] = key; + Py_INCREF(val); + new->b_array[new_i + 1] = val; + } + else { + new->b_array[new_i] = NULL; + Py_INCREF(node); + new->b_array[new_i + 1] = (PyObject*)node; + } + } + else { + +#ifdef Py_DEBUG + if (IS_COLLISION_NODE(node)) { + Py_ssize_t child_count = hamt_node_collision_count( + (PyHamtNode_Collision*)node); + assert(child_count > 1); + } + else if (IS_ARRAY_NODE(node)) { + assert(((PyHamtNode_Array*)node)->a_count >= 16); + } +#endif + + /* Just copy the node into our new Bitmap */ + new->b_array[new_i] = NULL; + Py_INCREF(node); + new->b_array[new_i + 1] = (PyObject*)node; + } + + new_i += 2; + } + + new->b_bitmap = bitmap; + *new_node = (PyHamtNode*)new; /* borrow */ + return W_NEWNODE; + } + + default: + Py_UNREACHABLE(); + } +} + +static hamt_find_t +hamt_node_array_find(PyHamtNode_Array *self, + uint32_t shift, int32_t hash, + PyObject *key, PyObject **val) +{ + /* Lookup `key` in the Array node `self`. Set the value + for the found key to 'val'. */ + + uint32_t idx = hamt_mask(hash, shift); + PyHamtNode *node; + + node = self->a_array[idx]; + if (node == NULL) { + return F_NOT_FOUND; + } + + /* Dispatch to the generic hamt_node_find */ + return hamt_node_find(node, shift + 5, hash, key, val); +} + +static int +hamt_node_array_traverse(PyHamtNode_Array *self, + visitproc visit, void *arg) +{ + /* Array's tp_traverse */ + + Py_ssize_t i; + + for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + Py_VISIT(self->a_array[i]); + } + + return 0; +} + +static void +hamt_node_array_dealloc(PyHamtNode_Array *self) +{ + /* Array's tp_dealloc */ + + Py_ssize_t i; + + PyObject_GC_UnTrack(self); + Py_TRASHCAN_BEGIN(self, hamt_node_array_dealloc) + + for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + Py_XDECREF(self->a_array[i]); + } + + Py_TYPE(self)->tp_free((PyObject *)self); + Py_TRASHCAN_END +} + +#ifdef Py_DEBUG +static int +hamt_node_array_dump(PyHamtNode_Array *node, + _PyUnicodeWriter *writer, int level) +{ + /* Debug build: __dump__() method implementation for Array nodes. */ + + Py_ssize_t i; + + if (_hamt_dump_ident(writer, level + 1)) { + goto error; + } + + if (_hamt_dump_format(writer, "ArrayNode(id=%p):\n", node)) { + goto error; + } + + for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { + if (node->a_array[i] == NULL) { + continue; + } + + if (_hamt_dump_ident(writer, level + 2)) { + goto error; + } + + if (_hamt_dump_format(writer, "%zd::\n", i)) { + goto error; + } + + if (hamt_node_dump(node->a_array[i], writer, level + 1)) { + goto error; + } + + if (_hamt_dump_format(writer, "\n")) { + goto error; + } + } + + return 0; +error: + return -1; +} +#endif /* Py_DEBUG */ + + +/////////////////////////////////// Node Dispatch + + +static PyHamtNode * +hamt_node_assoc(PyHamtNode *node, + uint32_t shift, int32_t hash, + PyObject *key, PyObject *val, int* added_leaf) +{ + /* Set key/value to the 'node' starting with the given shift/hash. + Return a new node, or the same node if key/value already + set. + + added_leaf will be set to 1 if key/value wasn't in the + tree before. + + This method automatically dispatches to the suitable + hamt_node_{nodetype}_assoc method. + */ + + if (IS_BITMAP_NODE(node)) { + return hamt_node_bitmap_assoc( + (PyHamtNode_Bitmap *)node, + shift, hash, key, val, added_leaf); + } + else if (IS_ARRAY_NODE(node)) { + return hamt_node_array_assoc( + (PyHamtNode_Array *)node, + shift, hash, key, val, added_leaf); + } + else { + assert(IS_COLLISION_NODE(node)); + return hamt_node_collision_assoc( + (PyHamtNode_Collision *)node, + shift, hash, key, val, added_leaf); + } +} + +static hamt_without_t +hamt_node_without(PyHamtNode *node, + uint32_t shift, int32_t hash, + PyObject *key, + PyHamtNode **new_node) +{ + if (IS_BITMAP_NODE(node)) { + return hamt_node_bitmap_without( + (PyHamtNode_Bitmap *)node, + shift, hash, key, + new_node); + } + else if (IS_ARRAY_NODE(node)) { + return hamt_node_array_without( + (PyHamtNode_Array *)node, + shift, hash, key, + new_node); + } + else { + assert(IS_COLLISION_NODE(node)); + return hamt_node_collision_without( + (PyHamtNode_Collision *)node, + shift, hash, key, + new_node); + } +} + +static hamt_find_t +hamt_node_find(PyHamtNode *node, + uint32_t shift, int32_t hash, + PyObject *key, PyObject **val) +{ + /* Find the key in the node starting with the given shift/hash. + + If a value is found, the result will be set to F_FOUND, and + *val will point to the found value object. + + If a value wasn't found, the result will be set to F_NOT_FOUND. + + If an exception occurs during the call, the result will be F_ERROR. + + This method automatically dispatches to the suitable + hamt_node_{nodetype}_find method. + */ + + if (IS_BITMAP_NODE(node)) { + return hamt_node_bitmap_find( + (PyHamtNode_Bitmap *)node, + shift, hash, key, val); + + } + else if (IS_ARRAY_NODE(node)) { + return hamt_node_array_find( + (PyHamtNode_Array *)node, + shift, hash, key, val); + } + else { + assert(IS_COLLISION_NODE(node)); + return hamt_node_collision_find( + (PyHamtNode_Collision *)node, + shift, hash, key, val); + } +} + +#ifdef Py_DEBUG +static int +hamt_node_dump(PyHamtNode *node, + _PyUnicodeWriter *writer, int level) +{ + /* Debug build: __dump__() method implementation for a node. + + This method automatically dispatches to the suitable + hamt_node_{nodetype})_dump method. + */ + + if (IS_BITMAP_NODE(node)) { + return hamt_node_bitmap_dump( + (PyHamtNode_Bitmap *)node, writer, level); + } + else if (IS_ARRAY_NODE(node)) { + return hamt_node_array_dump( + (PyHamtNode_Array *)node, writer, level); + } + else { + assert(IS_COLLISION_NODE(node)); + return hamt_node_collision_dump( + (PyHamtNode_Collision *)node, writer, level); + } +} +#endif /* Py_DEBUG */ + + +/////////////////////////////////// Iterators: Machinery + + +static hamt_iter_t +hamt_iterator_next(PyHamtIteratorState *iter, PyObject **key, PyObject **val); + + +static void +hamt_iterator_init(PyHamtIteratorState *iter, PyHamtNode *root) +{ + for (uint32_t i = 0; i < _Py_HAMT_MAX_TREE_DEPTH; i++) { + iter->i_nodes[i] = NULL; + iter->i_pos[i] = 0; + } + + iter->i_level = 0; + + /* Note: we don't incref/decref nodes in i_nodes. */ + iter->i_nodes[0] = root; +} + +static hamt_iter_t +hamt_iterator_bitmap_next(PyHamtIteratorState *iter, + PyObject **key, PyObject **val) +{ + int8_t level = iter->i_level; + + PyHamtNode_Bitmap *node = (PyHamtNode_Bitmap *)(iter->i_nodes[level]); + Py_ssize_t pos = iter->i_pos[level]; + + if (pos + 1 >= Py_SIZE(node)) { +#ifdef Py_DEBUG + assert(iter->i_level >= 0); + iter->i_nodes[iter->i_level] = NULL; +#endif + iter->i_level--; + return hamt_iterator_next(iter, key, val); + } + + if (node->b_array[pos] == NULL) { + iter->i_pos[level] = pos + 2; + + int8_t next_level = level + 1; + assert(next_level < _Py_HAMT_MAX_TREE_DEPTH); + iter->i_level = next_level; + iter->i_pos[next_level] = 0; + iter->i_nodes[next_level] = (PyHamtNode *) + node->b_array[pos + 1]; + + return hamt_iterator_next(iter, key, val); + } + + *key = node->b_array[pos]; + *val = node->b_array[pos + 1]; + iter->i_pos[level] = pos + 2; + return I_ITEM; +} + +static hamt_iter_t +hamt_iterator_collision_next(PyHamtIteratorState *iter, + PyObject **key, PyObject **val) +{ + int8_t level = iter->i_level; + + PyHamtNode_Collision *node = (PyHamtNode_Collision *)(iter->i_nodes[level]); + Py_ssize_t pos = iter->i_pos[level]; + + if (pos + 1 >= Py_SIZE(node)) { +#ifdef Py_DEBUG + assert(iter->i_level >= 0); + iter->i_nodes[iter->i_level] = NULL; +#endif + iter->i_level--; + return hamt_iterator_next(iter, key, val); + } + + *key = node->c_array[pos]; + *val = node->c_array[pos + 1]; + iter->i_pos[level] = pos + 2; + return I_ITEM; +} + +static hamt_iter_t +hamt_iterator_array_next(PyHamtIteratorState *iter, + PyObject **key, PyObject **val) +{ + int8_t level = iter->i_level; + + PyHamtNode_Array *node = (PyHamtNode_Array *)(iter->i_nodes[level]); + Py_ssize_t pos = iter->i_pos[level]; + + if (pos >= HAMT_ARRAY_NODE_SIZE) { +#ifdef Py_DEBUG + assert(iter->i_level >= 0); + iter->i_nodes[iter->i_level] = NULL; +#endif + iter->i_level--; + return hamt_iterator_next(iter, key, val); + } + + for (Py_ssize_t i = pos; i < HAMT_ARRAY_NODE_SIZE; i++) { + if (node->a_array[i] != NULL) { + iter->i_pos[level] = i + 1; + + int8_t next_level = level + 1; + assert(next_level < _Py_HAMT_MAX_TREE_DEPTH); + iter->i_pos[next_level] = 0; + iter->i_nodes[next_level] = node->a_array[i]; + iter->i_level = next_level; + + return hamt_iterator_next(iter, key, val); + } + } + +#ifdef Py_DEBUG + assert(iter->i_level >= 0); + iter->i_nodes[iter->i_level] = NULL; +#endif + + iter->i_level--; + return hamt_iterator_next(iter, key, val); +} + +static hamt_iter_t +hamt_iterator_next(PyHamtIteratorState *iter, PyObject **key, PyObject **val) +{ + if (iter->i_level < 0) { + return I_END; + } + + assert(iter->i_level < _Py_HAMT_MAX_TREE_DEPTH); + + PyHamtNode *current = iter->i_nodes[iter->i_level]; + + if (IS_BITMAP_NODE(current)) { + return hamt_iterator_bitmap_next(iter, key, val); + } + else if (IS_ARRAY_NODE(current)) { + return hamt_iterator_array_next(iter, key, val); + } + else { + assert(IS_COLLISION_NODE(current)); + return hamt_iterator_collision_next(iter, key, val); + } +} + + +/////////////////////////////////// HAMT high-level functions + + +PyHamtObject * +_PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val) +{ + int32_t key_hash; + int added_leaf = 0; + PyHamtNode *new_root; + PyHamtObject *new_o; + + key_hash = hamt_hash(key); + if (key_hash == -1) { + return NULL; + } + + new_root = hamt_node_assoc( + (PyHamtNode *)(o->h_root), + 0, key_hash, key, val, &added_leaf); + if (new_root == NULL) { + return NULL; + } + + if (new_root == o->h_root) { + Py_DECREF(new_root); + Py_INCREF(o); + return o; + } + + new_o = hamt_alloc(); + if (new_o == NULL) { + Py_DECREF(new_root); + return NULL; + } + + new_o->h_root = new_root; /* borrow */ + new_o->h_count = added_leaf ? o->h_count + 1 : o->h_count; + + return new_o; +} + +PyHamtObject * +_PyHamt_Without(PyHamtObject *o, PyObject *key) +{ + int32_t key_hash = hamt_hash(key); + if (key_hash == -1) { + return NULL; + } + + PyHamtNode *new_root = NULL; + + hamt_without_t res = hamt_node_without( + (PyHamtNode *)(o->h_root), + 0, key_hash, key, + &new_root); + + switch (res) { + case W_ERROR: + return NULL; + case W_EMPTY: + return _PyHamt_New(); + case W_NOT_FOUND: + Py_INCREF(o); + return o; + case W_NEWNODE: { + assert(new_root != NULL); + + PyHamtObject *new_o = hamt_alloc(); + if (new_o == NULL) { + Py_DECREF(new_root); + return NULL; + } + + new_o->h_root = new_root; /* borrow */ + new_o->h_count = o->h_count - 1; + assert(new_o->h_count >= 0); + return new_o; + } + default: + Py_UNREACHABLE(); + } +} + +static hamt_find_t +hamt_find(PyHamtObject *o, PyObject *key, PyObject **val) +{ + if (o->h_count == 0) { + return F_NOT_FOUND; + } + + int32_t key_hash = hamt_hash(key); + if (key_hash == -1) { + return F_ERROR; + } + + return hamt_node_find(o->h_root, 0, key_hash, key, val); +} + + +int +_PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val) +{ + hamt_find_t res = hamt_find(o, key, val); + switch (res) { + case F_ERROR: + return -1; + case F_NOT_FOUND: + return 0; + case F_FOUND: + return 1; + default: + Py_UNREACHABLE(); + } +} + + +int +_PyHamt_Eq(PyHamtObject *v, PyHamtObject *w) +{ + if (v == w) { + return 1; + } + + if (v->h_count != w->h_count) { + return 0; + } + + PyHamtIteratorState iter; + hamt_iter_t iter_res; + hamt_find_t find_res; + PyObject *v_key; + PyObject *v_val; + PyObject *w_val; + + hamt_iterator_init(&iter, v->h_root); + + do { + iter_res = hamt_iterator_next(&iter, &v_key, &v_val); + if (iter_res == I_ITEM) { + find_res = hamt_find(w, v_key, &w_val); + switch (find_res) { + case F_ERROR: + return -1; + + case F_NOT_FOUND: + return 0; + + case F_FOUND: { + int cmp = PyObject_RichCompareBool(v_val, w_val, Py_EQ); + if (cmp < 0) { + return -1; + } + if (cmp == 0) { + return 0; + } + } + } + } + } while (iter_res != I_END); + + return 1; +} + +Py_ssize_t +_PyHamt_Len(PyHamtObject *o) +{ + return o->h_count; +} + +static PyHamtObject * +hamt_alloc(void) +{ + PyHamtObject *o; + o = PyObject_GC_New(PyHamtObject, &_PyHamt_Type); + if (o == NULL) { + return NULL; + } + o->h_count = 0; + o->h_root = NULL; + o->h_weakreflist = NULL; + PyObject_GC_Track(o); + return o; +} + +PyHamtObject * +_PyHamt_New(void) +{ + if (_empty_hamt != NULL) { + /* HAMT is an immutable object so we can easily cache an + empty instance. */ + Py_INCREF(_empty_hamt); + return _empty_hamt; + } + + PyHamtObject *o = hamt_alloc(); + if (o == NULL) { + return NULL; + } + + o->h_root = hamt_node_bitmap_new(0); + if (o->h_root == NULL) { + Py_DECREF(o); + return NULL; + } + + o->h_count = 0; + + if (_empty_hamt == NULL) { + Py_INCREF(o); + _empty_hamt = o; + } + + return o; +} + +#ifdef Py_DEBUG +static PyObject * +hamt_dump(PyHamtObject *self) +{ + _PyUnicodeWriter writer; + + _PyUnicodeWriter_Init(&writer); + + if (_hamt_dump_format(&writer, "HAMT(len=%zd):\n", self->h_count)) { + goto error; + } + + if (hamt_node_dump(self->h_root, &writer, 0)) { + goto error; + } + + return _PyUnicodeWriter_Finish(&writer); + +error: + _PyUnicodeWriter_Dealloc(&writer); + return NULL; +} +#endif /* Py_DEBUG */ + + +/////////////////////////////////// Iterators: Shared Iterator Implementation + + +static int +hamt_baseiter_tp_clear(PyHamtIterator *it) +{ + Py_CLEAR(it->hi_obj); + return 0; +} + +static void +hamt_baseiter_tp_dealloc(PyHamtIterator *it) +{ + PyObject_GC_UnTrack(it); + (void)hamt_baseiter_tp_clear(it); + PyObject_GC_Del(it); +} + +static int +hamt_baseiter_tp_traverse(PyHamtIterator *it, visitproc visit, void *arg) +{ + Py_VISIT(it->hi_obj); + return 0; +} + +static PyObject * +hamt_baseiter_tp_iternext(PyHamtIterator *it) +{ + PyObject *key; + PyObject *val; + hamt_iter_t res = hamt_iterator_next(&it->hi_iter, &key, &val); + + switch (res) { + case I_END: + PyErr_SetNone(PyExc_StopIteration); + return NULL; + + case I_ITEM: { + return (*(it->hi_yield))(key, val); + } + + default: { + Py_UNREACHABLE(); + } + } +} + +static Py_ssize_t +hamt_baseiter_tp_len(PyHamtIterator *it) +{ + return it->hi_obj->h_count; +} + +static PyMappingMethods PyHamtIterator_as_mapping = { + (lenfunc)hamt_baseiter_tp_len, +}; + +static PyObject * +hamt_baseiter_new(PyTypeObject *type, binaryfunc yield, PyHamtObject *o) +{ + PyHamtIterator *it = PyObject_GC_New(PyHamtIterator, type); + if (it == NULL) { + return NULL; + } + + Py_INCREF(o); + it->hi_obj = o; + it->hi_yield = yield; + + hamt_iterator_init(&it->hi_iter, o->h_root); + + return (PyObject*)it; +} + +#define ITERATOR_TYPE_SHARED_SLOTS \ + .tp_basicsize = sizeof(PyHamtIterator), \ + .tp_itemsize = 0, \ + .tp_as_mapping = &PyHamtIterator_as_mapping, \ + .tp_dealloc = (destructor)hamt_baseiter_tp_dealloc, \ + .tp_getattro = PyObject_GenericGetAttr, \ + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, \ + .tp_traverse = (traverseproc)hamt_baseiter_tp_traverse, \ + .tp_clear = (inquiry)hamt_baseiter_tp_clear, \ + .tp_iter = PyObject_SelfIter, \ + .tp_iternext = (iternextfunc)hamt_baseiter_tp_iternext, + + +/////////////////////////////////// _PyHamtItems_Type + + +PyTypeObject _PyHamtItems_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "items", + ITERATOR_TYPE_SHARED_SLOTS +}; + +static PyObject * +hamt_iter_yield_items(PyObject *key, PyObject *val) +{ + return PyTuple_Pack(2, key, val); +} + +PyObject * +_PyHamt_NewIterItems(PyHamtObject *o) +{ + return hamt_baseiter_new( + &_PyHamtItems_Type, hamt_iter_yield_items, o); +} + + +/////////////////////////////////// _PyHamtKeys_Type + + +PyTypeObject _PyHamtKeys_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "keys", + ITERATOR_TYPE_SHARED_SLOTS +}; + +static PyObject * +hamt_iter_yield_keys(PyObject *key, PyObject *val) +{ + Py_INCREF(key); + return key; +} + +PyObject * +_PyHamt_NewIterKeys(PyHamtObject *o) +{ + return hamt_baseiter_new( + &_PyHamtKeys_Type, hamt_iter_yield_keys, o); +} + + +/////////////////////////////////// _PyHamtValues_Type + + +PyTypeObject _PyHamtValues_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "values", + ITERATOR_TYPE_SHARED_SLOTS +}; + +static PyObject * +hamt_iter_yield_values(PyObject *key, PyObject *val) +{ + Py_INCREF(val); + return val; +} + +PyObject * +_PyHamt_NewIterValues(PyHamtObject *o) +{ + return hamt_baseiter_new( + &_PyHamtValues_Type, hamt_iter_yield_values, o); +} + + +/////////////////////////////////// _PyHamt_Type + + +#ifdef Py_DEBUG +static PyObject * +hamt_dump(PyHamtObject *self); +#endif + + +static PyObject * +hamt_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return (PyObject*)_PyHamt_New(); +} + +static int +hamt_tp_clear(PyHamtObject *self) +{ + Py_CLEAR(self->h_root); + return 0; +} + + +static int +hamt_tp_traverse(PyHamtObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->h_root); + return 0; +} + +static void +hamt_tp_dealloc(PyHamtObject *self) +{ + PyObject_GC_UnTrack(self); + if (self->h_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } + (void)hamt_tp_clear(self); + Py_TYPE(self)->tp_free(self); +} + + +static PyObject * +hamt_tp_richcompare(PyObject *v, PyObject *w, int op) +{ + if (!PyHamt_Check(v) || !PyHamt_Check(w) || (op != Py_EQ && op != Py_NE)) { + Py_RETURN_NOTIMPLEMENTED; + } + + int res = _PyHamt_Eq((PyHamtObject *)v, (PyHamtObject *)w); + if (res < 0) { + return NULL; + } + + if (op == Py_NE) { + res = !res; + } + + if (res) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +static int +hamt_tp_contains(PyHamtObject *self, PyObject *key) +{ + PyObject *val; + return _PyHamt_Find(self, key, &val); +} + +static PyObject * +hamt_tp_subscript(PyHamtObject *self, PyObject *key) +{ + PyObject *val; + hamt_find_t res = hamt_find(self, key, &val); + switch (res) { + case F_ERROR: + return NULL; + case F_FOUND: + Py_INCREF(val); + return val; + case F_NOT_FOUND: + PyErr_SetObject(PyExc_KeyError, key); + return NULL; + default: + Py_UNREACHABLE(); + } +} + +static Py_ssize_t +hamt_tp_len(PyHamtObject *self) +{ + return _PyHamt_Len(self); +} + +static PyObject * +hamt_tp_iter(PyHamtObject *self) +{ + return _PyHamt_NewIterKeys(self); +} + +static PyObject * +hamt_py_set(PyHamtObject *self, PyObject *args) +{ + PyObject *key; + PyObject *val; + + if (!PyArg_UnpackTuple(args, "set", 2, 2, &key, &val)) { + return NULL; + } + + return (PyObject *)_PyHamt_Assoc(self, key, val); +} + +static PyObject * +hamt_py_get(PyHamtObject *self, PyObject *args) +{ + PyObject *key; + PyObject *def = NULL; + + if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) { + return NULL; + } + + PyObject *val = NULL; + hamt_find_t res = hamt_find(self, key, &val); + switch (res) { + case F_ERROR: + return NULL; + case F_FOUND: + Py_INCREF(val); + return val; + case F_NOT_FOUND: + if (def == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(def); + return def; + default: + Py_UNREACHABLE(); + } +} + +static PyObject * +hamt_py_delete(PyHamtObject *self, PyObject *key) +{ + return (PyObject *)_PyHamt_Without(self, key); +} + +static PyObject * +hamt_py_items(PyHamtObject *self, PyObject *args) +{ + return _PyHamt_NewIterItems(self); +} + +static PyObject * +hamt_py_values(PyHamtObject *self, PyObject *args) +{ + return _PyHamt_NewIterValues(self); +} + +static PyObject * +hamt_py_keys(PyHamtObject *self, PyObject *args) +{ + return _PyHamt_NewIterKeys(self); +} + +#ifdef Py_DEBUG +static PyObject * +hamt_py_dump(PyHamtObject *self, PyObject *args) +{ + return hamt_dump(self); +} +#endif + + +static PyMethodDef PyHamt_methods[] = { + {"set", (PyCFunction)hamt_py_set, METH_VARARGS, NULL}, + {"get", (PyCFunction)hamt_py_get, METH_VARARGS, NULL}, + {"delete", (PyCFunction)hamt_py_delete, METH_O, NULL}, + {"items", (PyCFunction)hamt_py_items, METH_NOARGS, NULL}, + {"keys", (PyCFunction)hamt_py_keys, METH_NOARGS, NULL}, + {"values", (PyCFunction)hamt_py_values, METH_NOARGS, NULL}, +#ifdef Py_DEBUG + {"__dump__", (PyCFunction)hamt_py_dump, METH_NOARGS, NULL}, +#endif + {NULL, NULL} +}; + +static PySequenceMethods PyHamt_as_sequence = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)hamt_tp_contains, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + +static PyMappingMethods PyHamt_as_mapping = { + (lenfunc)hamt_tp_len, /* mp_length */ + (binaryfunc)hamt_tp_subscript, /* mp_subscript */ +}; + +PyTypeObject _PyHamt_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "hamt", + sizeof(PyHamtObject), + .tp_methods = PyHamt_methods, + .tp_as_mapping = &PyHamt_as_mapping, + .tp_as_sequence = &PyHamt_as_sequence, + .tp_iter = (getiterfunc)hamt_tp_iter, + .tp_dealloc = (destructor)hamt_tp_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_richcompare = hamt_tp_richcompare, + .tp_traverse = (traverseproc)hamt_tp_traverse, + .tp_clear = (inquiry)hamt_tp_clear, + .tp_new = hamt_tp_new, + .tp_weaklistoffset = offsetof(PyHamtObject, h_weakreflist), + .tp_hash = PyObject_HashNotImplemented, +}; + + +/////////////////////////////////// Tree Node Types + + +PyTypeObject _PyHamt_ArrayNode_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "hamt_array_node", + sizeof(PyHamtNode_Array), + 0, + .tp_dealloc = (destructor)hamt_node_array_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)hamt_node_array_traverse, + .tp_free = PyObject_GC_Del, + .tp_hash = PyObject_HashNotImplemented, +}; + +PyTypeObject _PyHamt_BitmapNode_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "hamt_bitmap_node", + sizeof(PyHamtNode_Bitmap) - sizeof(PyObject *), + sizeof(PyObject *), + .tp_dealloc = (destructor)hamt_node_bitmap_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)hamt_node_bitmap_traverse, + .tp_free = PyObject_GC_Del, + .tp_hash = PyObject_HashNotImplemented, +}; + +PyTypeObject _PyHamt_CollisionNode_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "hamt_collision_node", + sizeof(PyHamtNode_Collision) - sizeof(PyObject *), + sizeof(PyObject *), + .tp_dealloc = (destructor)hamt_node_collision_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)hamt_node_collision_traverse, + .tp_free = PyObject_GC_Del, + .tp_hash = PyObject_HashNotImplemented, +}; + + +int +_PyHamt_Init(void) +{ + if ((PyType_Ready(&_PyHamt_Type) < 0) || + (PyType_Ready(&_PyHamt_ArrayNode_Type) < 0) || + (PyType_Ready(&_PyHamt_BitmapNode_Type) < 0) || + (PyType_Ready(&_PyHamt_CollisionNode_Type) < 0) || + (PyType_Ready(&_PyHamtKeys_Type) < 0) || + (PyType_Ready(&_PyHamtValues_Type) < 0) || + (PyType_Ready(&_PyHamtItems_Type) < 0)) + { + return 0; + } + + return 1; +} + +void +_PyHamt_Fini(void) +{ + Py_CLEAR(_empty_hamt); + Py_CLEAR(_empty_bitmap_node); +} diff --git a/python/Python/import.c b/python/Python/import.c new file mode 100755 index 0000000..35c5561 --- /dev/null +++ b/python/Python/import.c @@ -0,0 +1,2468 @@ +/* Module definition and import implementation */ + +#include "Python.h" + +#include "Python-ast.h" +#undef Yield /* undefine macro conflicting with */ +#include "pycore_pyhash.h" +#include "pycore_pylifecycle.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "errcode.h" +#include "marshal.h" +#include "code.h" +#include "frameobject.h" +#include "osdefs.h" +#include "importdl.h" +#include "pydtrace.h" + +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef __cplusplus +extern "C" { +#endif + +#define CACHEDIR "__pycache__" + +/* See _PyImport_FixupExtensionObject() below */ +static PyObject *extensions = NULL; + +/* This table is defined in config.c: */ +extern struct _inittab _PyImport_Inittab[]; + +struct _inittab *PyImport_Inittab = _PyImport_Inittab; +static struct _inittab *inittab_copy = NULL; + +/*[clinic input] +module _imp +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ + +#include "clinic/import.c.h" + +/* Initialize things */ + +PyStatus +_PyImport_Init(PyInterpreterState *interp) +{ + interp->builtins_copy = PyDict_Copy(interp->builtins); + if (interp->builtins_copy == NULL) { + return _PyStatus_ERR("Can't backup builtins dict"); + } + return _PyStatus_OK(); +} + +PyStatus +_PyImportHooks_Init(void) +{ + PyObject *v, *path_hooks = NULL; + int err = 0; + + /* adding sys.path_hooks and sys.path_importer_cache */ + v = PyList_New(0); + if (v == NULL) + goto error; + err = PySys_SetObject("meta_path", v); + Py_DECREF(v); + if (err) + goto error; + v = PyDict_New(); + if (v == NULL) + goto error; + err = PySys_SetObject("path_importer_cache", v); + Py_DECREF(v); + if (err) + goto error; + path_hooks = PyList_New(0); + if (path_hooks == NULL) + goto error; + err = PySys_SetObject("path_hooks", path_hooks); + if (err) { + goto error; + } + Py_DECREF(path_hooks); + return _PyStatus_OK(); + + error: + PyErr_Print(); + return _PyStatus_ERR("initializing sys.meta_path, sys.path_hooks, " + "or path_importer_cache failed"); +} + +PyStatus +_PyImportZip_Init(PyInterpreterState *interp) +{ + PyObject *path_hooks, *zipimport; + int err = 0; + + path_hooks = PySys_GetObject("path_hooks"); + if (path_hooks == NULL) { + PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path_hooks"); + goto error; + } + + int verbose = interp->config.verbose; + if (verbose) { + PySys_WriteStderr("# installing zipimport hook\n"); + } + + zipimport = PyImport_ImportModule("zipimport"); + if (zipimport == NULL) { + PyErr_Clear(); /* No zip import module -- okay */ + if (verbose) { + PySys_WriteStderr("# can't import zipimport\n"); + } + } + else { + _Py_IDENTIFIER(zipimporter); + PyObject *zipimporter = _PyObject_GetAttrId(zipimport, + &PyId_zipimporter); + Py_DECREF(zipimport); + if (zipimporter == NULL) { + PyErr_Clear(); /* No zipimporter object -- okay */ + if (verbose) { + PySys_WriteStderr("# can't import zipimport.zipimporter\n"); + } + } + else { + /* sys.path_hooks.insert(0, zipimporter) */ + err = PyList_Insert(path_hooks, 0, zipimporter); + Py_DECREF(zipimporter); + if (err < 0) { + goto error; + } + if (verbose) { + PySys_WriteStderr("# installed zipimport hook\n"); + } + } + } + + return _PyStatus_OK(); + + error: + PyErr_Print(); + return _PyStatus_ERR("initializing zipimport failed"); +} + +/* Locking primitives to prevent parallel imports of the same module + in different threads to return with a partially loaded module. + These calls are serialized by the global interpreter lock. */ + +#include "pythread.h" + +static PyThread_type_lock import_lock = 0; +static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID; +static int import_lock_level = 0; + +void +_PyImport_AcquireLock(void) +{ + unsigned long me = PyThread_get_thread_ident(); + if (me == PYTHREAD_INVALID_THREAD_ID) + return; /* Too bad */ + if (import_lock == NULL) { + import_lock = PyThread_allocate_lock(); + if (import_lock == NULL) + return; /* Nothing much we can do. */ + } + if (import_lock_thread == me) { + import_lock_level++; + return; + } + if (import_lock_thread != PYTHREAD_INVALID_THREAD_ID || + !PyThread_acquire_lock(import_lock, 0)) + { + PyThreadState *tstate = PyEval_SaveThread(); + PyThread_acquire_lock(import_lock, 1); + PyEval_RestoreThread(tstate); + } + assert(import_lock_level == 0); + import_lock_thread = me; + import_lock_level = 1; +} + +int +_PyImport_ReleaseLock(void) +{ + unsigned long me = PyThread_get_thread_ident(); + if (me == PYTHREAD_INVALID_THREAD_ID || import_lock == NULL) + return 0; /* Too bad */ + if (import_lock_thread != me) + return -1; + import_lock_level--; + assert(import_lock_level >= 0); + if (import_lock_level == 0) { + import_lock_thread = PYTHREAD_INVALID_THREAD_ID; + PyThread_release_lock(import_lock); + } + return 1; +} + +/* This function is called from PyOS_AfterFork_Child to ensure that newly + created child processes do not share locks with the parent. + We now acquire the import lock around fork() calls but on some platforms + (Solaris 9 and earlier? see isue7242) that still left us with problems. */ + +void +_PyImport_ReInitLock(void) +{ + if (import_lock != NULL) { + import_lock = PyThread_allocate_lock(); + if (import_lock == NULL) { + Py_FatalError("PyImport_ReInitLock failed to create a new lock"); + } + } + if (import_lock_level > 1) { + /* Forked as a side effect of import */ + unsigned long me = PyThread_get_thread_ident(); + /* The following could fail if the lock is already held, but forking as + a side-effect of an import is a) rare, b) nuts, and c) difficult to + do thanks to the lock only being held when doing individual module + locks per import. */ + PyThread_acquire_lock(import_lock, NOWAIT_LOCK); + import_lock_thread = me; + import_lock_level--; + } else { + import_lock_thread = PYTHREAD_INVALID_THREAD_ID; + import_lock_level = 0; + } +} + +/*[clinic input] +_imp.lock_held + +Return True if the import lock is currently held, else False. + +On platforms without threads, return False. +[clinic start generated code]*/ + +static PyObject * +_imp_lock_held_impl(PyObject *module) +/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/ +{ + return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID); +} + +/*[clinic input] +_imp.acquire_lock + +Acquires the interpreter's import lock for the current thread. + +This lock should be used by import hooks to ensure thread-safety when importing +modules. On platforms without threads, this function does nothing. +[clinic start generated code]*/ + +static PyObject * +_imp_acquire_lock_impl(PyObject *module) +/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/ +{ + _PyImport_AcquireLock(); + Py_RETURN_NONE; +} + +/*[clinic input] +_imp.release_lock + +Release the interpreter's import lock. + +On platforms without threads, this function does nothing. +[clinic start generated code]*/ + +static PyObject * +_imp_release_lock_impl(PyObject *module) +/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/ +{ + if (_PyImport_ReleaseLock() < 0) { + PyErr_SetString(PyExc_RuntimeError, + "not holding the import lock"); + return NULL; + } + Py_RETURN_NONE; +} + +void +_PyImport_Fini(void) +{ + Py_CLEAR(extensions); + if (import_lock != NULL) { + PyThread_free_lock(import_lock); + import_lock = NULL; + } +} + +void +_PyImport_Fini2(void) +{ + /* Use the same memory allocator than PyImport_ExtendInittab(). */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Free memory allocated by PyImport_ExtendInittab() */ + PyMem_RawFree(inittab_copy); + inittab_copy = NULL; + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + +/* Helper for sys */ + +PyObject * +PyImport_GetModuleDict(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + if (interp->modules == NULL) { + Py_FatalError("PyImport_GetModuleDict: no module dictionary!"); + } + return interp->modules; +} + +/* In some corner cases it is important to be sure that the import + machinery has been initialized (or not cleaned up yet). For + example, see issue #4236 and PyModule_Create2(). */ + +int +_PyImport_IsInitialized(PyInterpreterState *interp) +{ + if (interp->modules == NULL) + return 0; + return 1; +} + +PyObject * +_PyImport_GetModuleId(struct _Py_Identifier *nameid) +{ + PyObject *name = _PyUnicode_FromId(nameid); /* borrowed */ + if (name == NULL) { + return NULL; + } + return PyImport_GetModule(name); +} + +int +_PyImport_SetModule(PyObject *name, PyObject *m) +{ + PyObject *modules = PyImport_GetModuleDict(); + return PyObject_SetItem(modules, name, m); +} + +int +_PyImport_SetModuleString(const char *name, PyObject *m) +{ + PyObject *modules = PyImport_GetModuleDict(); + return PyMapping_SetItemString(modules, name, m); +} + +PyObject * +PyImport_GetModule(PyObject *name) +{ + PyObject *m; + PyObject *modules = PyImport_GetModuleDict(); + if (modules == NULL) { + PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); + return NULL; + } + Py_INCREF(modules); + if (PyDict_CheckExact(modules)) { + m = PyDict_GetItemWithError(modules, name); /* borrowed */ + Py_XINCREF(m); + } + else { + m = PyObject_GetItem(modules, name); + if (m == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + } + } + Py_DECREF(modules); + return m; +} + + +/* List of names to clear in sys */ +static const char * const sys_deletes[] = { + "path", "argv", "ps1", "ps2", + "last_type", "last_value", "last_traceback", + "path_hooks", "path_importer_cache", "meta_path", + "__interactivehook__", + NULL +}; + +static const char * const sys_files[] = { + "stdin", "__stdin__", + "stdout", "__stdout__", + "stderr", "__stderr__", + NULL +}; + +/* Un-initialize things, as good as we can */ + +void +PyImport_Cleanup(void) +{ + Py_ssize_t pos; + PyObject *key, *value, *dict; + PyInterpreterState *interp = _PyInterpreterState_Get(); + PyObject *modules = PyImport_GetModuleDict(); + PyObject *weaklist = NULL; + const char * const *p; + + if (modules == NULL) + return; /* Already done */ + + /* Delete some special variables first. These are common + places where user values hide and people complain when their + destructors fail. Since the modules containing them are + deleted *last* of all, they would come too late in the normal + destruction order. Sigh. */ + + /* XXX Perhaps these precautions are obsolete. Who knows? */ + + int verbose = interp->config.verbose; + if (verbose) { + PySys_WriteStderr("# clear builtins._\n"); + } + if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) { + PyErr_WriteUnraisable(NULL); + } + + for (p = sys_deletes; *p != NULL; p++) { + if (verbose) { + PySys_WriteStderr("# clear sys.%s\n", *p); + } + if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) { + PyErr_WriteUnraisable(NULL); + } + } + for (p = sys_files; *p != NULL; p+=2) { + if (verbose) { + PySys_WriteStderr("# restore sys.%s\n", *p); + } + value = _PyDict_GetItemStringWithError(interp->sysdict, *(p+1)); + if (value == NULL) { + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(NULL); + } + value = Py_None; + } + if (PyDict_SetItemString(interp->sysdict, *p, value) < 0) { + PyErr_WriteUnraisable(NULL); + } + } + + /* We prepare a list which will receive (name, weakref) tuples of + modules when they are removed from sys.modules. The name is used + for diagnosis messages (in verbose mode), while the weakref helps + detect those modules which have been held alive. */ + weaklist = PyList_New(0); + if (weaklist == NULL) { + PyErr_WriteUnraisable(NULL); + } + +#define STORE_MODULE_WEAKREF(name, mod) \ + if (weaklist != NULL) { \ + PyObject *wr = PyWeakref_NewRef(mod, NULL); \ + if (wr) { \ + PyObject *tup = PyTuple_Pack(2, name, wr); \ + if (!tup || PyList_Append(weaklist, tup) < 0) { \ + PyErr_WriteUnraisable(NULL); \ + } \ + Py_XDECREF(tup); \ + Py_DECREF(wr); \ + } \ + else { \ + PyErr_WriteUnraisable(NULL); \ + } \ + } +#define CLEAR_MODULE(name, mod) \ + if (PyModule_Check(mod)) { \ + if (verbose && PyUnicode_Check(name)) { \ + PySys_FormatStderr("# cleanup[2] removing %U\n", name); \ + } \ + STORE_MODULE_WEAKREF(name, mod); \ + if (PyObject_SetItem(modules, name, Py_None) < 0) { \ + PyErr_WriteUnraisable(NULL); \ + } \ + } + + /* Remove all modules from sys.modules, hoping that garbage collection + can reclaim most of them. */ + if (PyDict_CheckExact(modules)) { + pos = 0; + while (PyDict_Next(modules, &pos, &key, &value)) { + CLEAR_MODULE(key, value); + } + } + else { + PyObject *iterator = PyObject_GetIter(modules); + if (iterator == NULL) { + PyErr_WriteUnraisable(NULL); + } + else { + while ((key = PyIter_Next(iterator))) { + value = PyObject_GetItem(modules, key); + if (value == NULL) { + PyErr_WriteUnraisable(NULL); + continue; + } + CLEAR_MODULE(key, value); + Py_DECREF(value); + Py_DECREF(key); + } + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(NULL); + } + Py_DECREF(iterator); + } + } + + /* Clear the modules dict. */ + if (PyDict_CheckExact(modules)) { + PyDict_Clear(modules); + } + else { + _Py_IDENTIFIER(clear); + if (_PyObject_CallMethodId(modules, &PyId_clear, "") == NULL) { + PyErr_WriteUnraisable(NULL); + } + } + /* Restore the original builtins dict, to ensure that any + user data gets cleared. */ + dict = PyDict_Copy(interp->builtins); + if (dict == NULL) { + PyErr_WriteUnraisable(NULL); + } + PyDict_Clear(interp->builtins); + if (PyDict_Update(interp->builtins, interp->builtins_copy)) { + PyErr_Clear(); + } + Py_XDECREF(dict); + /* Clear module dict copies stored in the interpreter state */ + _PyState_ClearModules(); + /* Collect references */ + _PyGC_CollectNoFail(); + /* Dump GC stats before it's too late, since it uses the warnings + machinery. */ + _PyGC_DumpShutdownStats(&_PyRuntime); + + /* Now, if there are any modules left alive, clear their globals to + minimize potential leaks. All C extension modules actually end + up here, since they are kept alive in the interpreter state. + + The special treatment of "builtins" here is because even + when it's not referenced as a module, its dictionary is + referenced by almost every module's __builtins__. Since + deleting a module clears its dictionary (even if there are + references left to it), we need to delete the "builtins" + module last. Likewise, we don't delete sys until the very + end because it is implicitly referenced (e.g. by print). */ + if (weaklist != NULL) { + Py_ssize_t i; + /* Since dict is ordered in CPython 3.6+, modules are saved in + importing order. First clear modules imported later. */ + for (i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) { + PyObject *tup = PyList_GET_ITEM(weaklist, i); + PyObject *name = PyTuple_GET_ITEM(tup, 0); + PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); + if (mod == Py_None) + continue; + assert(PyModule_Check(mod)); + dict = PyModule_GetDict(mod); + if (dict == interp->builtins || dict == interp->sysdict) + continue; + Py_INCREF(mod); + if (verbose && PyUnicode_Check(name)) { + PySys_FormatStderr("# cleanup[3] wiping %U\n", name); + } + _PyModule_Clear(mod); + Py_DECREF(mod); + } + Py_DECREF(weaklist); + } + + /* Next, delete sys and builtins (in that order) */ + if (verbose) { + PySys_FormatStderr("# cleanup[3] wiping sys\n"); + } + _PyModule_ClearDict(interp->sysdict); + if (verbose) { + PySys_FormatStderr("# cleanup[3] wiping builtins\n"); + } + _PyModule_ClearDict(interp->builtins); + + /* Clear and delete the modules directory. Actual modules will + still be there only if imported during the execution of some + destructor. */ + interp->modules = NULL; + Py_DECREF(modules); + + /* Once more */ + _PyGC_CollectNoFail(); + +#undef CLEAR_MODULE +#undef STORE_MODULE_WEAKREF +} + + +/* Helper for pythonrun.c -- return magic number and tag. */ + +long +PyImport_GetMagicNumber(void) +{ + long res; + PyInterpreterState *interp = _PyInterpreterState_Get(); + PyObject *external, *pyc_magic; + + external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); + if (external == NULL) + return -1; + pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER"); + Py_DECREF(external); + if (pyc_magic == NULL) + return -1; + res = PyLong_AsLong(pyc_magic); + Py_DECREF(pyc_magic); + return res; +} + + +extern const char * _PySys_ImplCacheTag; + +const char * +PyImport_GetMagicTag(void) +{ + return _PySys_ImplCacheTag; +} + + +/* Magic for extension modules (built-in as well as dynamically + loaded). To prevent initializing an extension module more than + once, we keep a static dictionary 'extensions' keyed by the tuple + (module name, module name) (for built-in modules) or by + (filename, module name) (for dynamically loaded modules), containing these + modules. A copy of the module's dictionary is stored by calling + _PyImport_FixupExtensionObject() immediately after the module initialization + function succeeds. A copy can be retrieved from there by calling + _PyImport_FindExtensionObject(). + + Modules which do support multiple initialization set their m_size + field to a non-negative number (indicating the size of the + module-specific state). They are still recorded in the extensions + dictionary, to avoid loading shared libraries twice. +*/ + +int +_PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, + PyObject *filename, PyObject *modules) +{ + PyObject *dict, *key; + struct PyModuleDef *def; + int res; + if (extensions == NULL) { + extensions = PyDict_New(); + if (extensions == NULL) + return -1; + } + if (mod == NULL || !PyModule_Check(mod)) { + PyErr_BadInternalCall(); + return -1; + } + def = PyModule_GetDef(mod); + if (!def) { + PyErr_BadInternalCall(); + return -1; + } + if (PyObject_SetItem(modules, name, mod) < 0) + return -1; + if (_PyState_AddModule(mod, def) < 0) { + PyMapping_DelItem(modules, name); + return -1; + } + if (def->m_size == -1) { + if (def->m_base.m_copy) { + /* Somebody already imported the module, + likely under a different name. + XXX this should really not happen. */ + Py_CLEAR(def->m_base.m_copy); + } + dict = PyModule_GetDict(mod); + if (dict == NULL) + return -1; + def->m_base.m_copy = PyDict_Copy(dict); + if (def->m_base.m_copy == NULL) + return -1; + } + key = PyTuple_Pack(2, filename, name); + if (key == NULL) + return -1; + res = PyDict_SetItem(extensions, key, (PyObject *)def); + Py_DECREF(key); + if (res < 0) + return -1; + return 0; +} + +int +_PyImport_FixupBuiltin(PyObject *mod, const char *name, PyObject *modules) +{ + int res; + PyObject *nameobj; + nameobj = PyUnicode_InternFromString(name); + if (nameobj == NULL) + return -1; + res = _PyImport_FixupExtensionObject(mod, nameobj, nameobj, modules); + Py_DECREF(nameobj); + return res; +} + +PyObject * +_PyImport_FindExtensionObject(PyObject *name, PyObject *filename) +{ + PyObject *modules = PyImport_GetModuleDict(); + return _PyImport_FindExtensionObjectEx(name, filename, modules); +} + +PyObject * +_PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename, + PyObject *modules) +{ + PyObject *mod, *mdict, *key; + PyModuleDef* def; + if (extensions == NULL) + return NULL; + key = PyTuple_Pack(2, filename, name); + if (key == NULL) + return NULL; + def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); + Py_DECREF(key); + if (def == NULL) + return NULL; + if (def->m_size == -1) { + /* Module does not support repeated initialization */ + if (def->m_base.m_copy == NULL) + return NULL; + mod = _PyImport_AddModuleObject(name, modules); + if (mod == NULL) + return NULL; + mdict = PyModule_GetDict(mod); + if (mdict == NULL) + return NULL; + if (PyDict_Update(mdict, def->m_base.m_copy)) + return NULL; + } + else { + if (def->m_base.m_init == NULL) + return NULL; + mod = def->m_base.m_init(); + if (mod == NULL) + return NULL; + if (PyObject_SetItem(modules, name, mod) == -1) { + Py_DECREF(mod); + return NULL; + } + Py_DECREF(mod); + } + if (_PyState_AddModule(mod, def) < 0) { + PyMapping_DelItem(modules, name); + return NULL; + } + int verbose = _PyInterpreterState_Get()->config.verbose; + if (verbose) { + PySys_FormatStderr("import %U # previously loaded (%R)\n", + name, filename); + } + return mod; + +} + +PyObject * +_PyImport_FindBuiltin(const char *name, PyObject *modules) +{ + PyObject *res, *nameobj; + nameobj = PyUnicode_InternFromString(name); + if (nameobj == NULL) + return NULL; + res = _PyImport_FindExtensionObjectEx(nameobj, nameobj, modules); + Py_DECREF(nameobj); + return res; +} + +/* Get the module object corresponding to a module name. + First check the modules dictionary if there's one there, + if not, create a new one and insert it in the modules dictionary. + Because the former action is most common, THIS DOES NOT RETURN A + 'NEW' REFERENCE! */ + +PyObject * +PyImport_AddModuleObject(PyObject *name) +{ + // printf("---PyImport_AddModuleObject in--- :"); + // PyObject_Print(name, stdout, Py_PRINT_RAW); + // printf("\n"); + PyObject *modules = PyImport_GetModuleDict(); + return _PyImport_AddModuleObject(name, modules); +} + +PyObject * +_PyImport_AddModuleObject(PyObject *name, PyObject *modules) +{ + PyObject *m; + if (PyDict_CheckExact(modules)) { + m = PyDict_GetItemWithError(modules, name); + } + else { + m = PyObject_GetItem(modules, name); + // For backward-comaptibility we copy the behavior + // of PyDict_GetItemWithError(). + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + } + } + if (PyErr_Occurred()) { + return NULL; + } + if (m != NULL && PyModule_Check(m)) { + return m; + } + m = PyModule_NewObject(name); + if (m == NULL) + return NULL; + if (PyObject_SetItem(modules, name, m) != 0) { + Py_DECREF(m); + return NULL; + } + Py_DECREF(m); /* Yes, it still exists, in modules! */ + + return m; +} + +PyObject * +PyImport_AddModule(const char *name) +{ + // printf("---PyImport_AddModule %s--- \n",name); + PyObject *nameobj, *module; + nameobj = PyUnicode_FromString(name); + if (nameobj == NULL) + return NULL; + module = PyImport_AddModuleObject(nameobj); + Py_DECREF(nameobj); + return module; +} + + +/* Remove name from sys.modules, if it's there. */ +static void +remove_module(PyObject *name) +{ + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + PyObject *modules = PyImport_GetModuleDict(); + if (!PyMapping_HasKey(modules, name)) { + goto out; + } + if (PyMapping_DelItem(modules, name) < 0) { + Py_FatalError("import: deleting existing key in " + "sys.modules failed"); + } +out: + PyErr_Restore(type, value, traceback); +} + + +/* Execute a code object in a module and return the module object + * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is + * removed from sys.modules, to avoid leaving damaged module objects + * in sys.modules. The caller may wish to restore the original + * module object (if any) in this case; PyImport_ReloadModule is an + * example. + * + * Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer + * interface. The other two exist primarily for backward compatibility. + */ +PyObject * +PyImport_ExecCodeModule(const char *name, PyObject *co) +{ + return PyImport_ExecCodeModuleWithPathnames( + name, co, (char *)NULL, (char *)NULL); +} + +PyObject * +PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname) +{ + return PyImport_ExecCodeModuleWithPathnames( + name, co, pathname, (char *)NULL); +} + +PyObject * +PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, + const char *pathname, + const char *cpathname) +{ + // printf("---PyImport_ExecCodeModuleWithPathnames---%s\n",name); + + PyObject *m = NULL; + PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL; + + nameobj = PyUnicode_FromString(name); + if (nameobj == NULL) + return NULL; + + if (cpathname != NULL) { + cpathobj = PyUnicode_DecodeFSDefault(cpathname); + if (cpathobj == NULL) + goto error; + } + else + cpathobj = NULL; + + if (pathname != NULL) { + pathobj = PyUnicode_DecodeFSDefault(pathname); + if (pathobj == NULL) + goto error; + } + else if (cpathobj != NULL) { + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + _Py_IDENTIFIER(_get_sourcefile); + + if (interp == NULL) { + Py_FatalError("PyImport_ExecCodeModuleWithPathnames: " + "no interpreter!"); + } + + external= PyObject_GetAttrString(interp->importlib, + "_bootstrap_external"); + if (external != NULL) { + pathobj = _PyObject_CallMethodIdObjArgs(external, + &PyId__get_sourcefile, cpathobj, + NULL); + Py_DECREF(external); + } + if (pathobj == NULL) + PyErr_Clear(); + } + else + pathobj = NULL; + + m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj); +error: + Py_DECREF(nameobj); + Py_XDECREF(pathobj); + Py_XDECREF(cpathobj); + return m; +} + +static PyObject * +module_dict_for_exec(PyObject *name) +{ + _Py_IDENTIFIER(__builtins__); + PyObject *m, *d = NULL; + + m = PyImport_AddModuleObject(name); + if (m == NULL) + return NULL; + /* If the module is being reloaded, we get the old module back + and re-use its dict to exec the new code. */ + d = PyModule_GetDict(m); + if (_PyDict_GetItemIdWithError(d, &PyId___builtins__) == NULL) { + if (PyErr_Occurred() || + _PyDict_SetItemId(d, &PyId___builtins__, + PyEval_GetBuiltins()) != 0) + { + remove_module(name); + return NULL; + } + } + + return d; /* Return a borrowed reference. */ +} + +static PyObject * +exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object) +{ + PyObject *v, *m; + + v = PyEval_EvalCode(code_object, module_dict, module_dict); + if (v == NULL) { + remove_module(name); + return NULL; + } + Py_DECREF(v); + + m = PyImport_GetModule(name); + if (m == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_ImportError, + "Loaded module %R not found in sys.modules", + name); + } + + return m; +} + +PyObject* +PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, + PyObject *cpathname) +{ + PyObject *d, *external, *res; + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + _Py_IDENTIFIER(_fix_up_module); + + d = module_dict_for_exec(name); + if (d == NULL) { + return NULL; + } + + if (pathname == NULL) { + pathname = ((PyCodeObject *)co)->co_filename; + } + external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); + if (external == NULL) + return NULL; + res = _PyObject_CallMethodIdObjArgs(external, + &PyId__fix_up_module, + d, name, pathname, cpathname, NULL); + Py_DECREF(external); + if (res != NULL) { + Py_DECREF(res); + res = exec_code_in_module(name, d, co); + } + return res; +} + + +static void +update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) +{ + PyObject *constants, *tmp; + Py_ssize_t i, n; + + if (PyUnicode_Compare(co->co_filename, oldname)) + return; + + Py_INCREF(newname); + Py_XSETREF(co->co_filename, newname); + + constants = co->co_consts; + n = PyTuple_GET_SIZE(constants); + for (i = 0; i < n; i++) { + tmp = PyTuple_GET_ITEM(constants, i); + if (PyCode_Check(tmp)) + update_code_filenames((PyCodeObject *)tmp, + oldname, newname); + } +} + +static void +update_compiled_module(PyCodeObject *co, PyObject *newname) +{ + PyObject *oldname; + + if (PyUnicode_Compare(co->co_filename, newname) == 0) + return; + + oldname = co->co_filename; + Py_INCREF(oldname); + update_code_filenames(co, oldname, newname); + Py_DECREF(oldname); +} + +/*[clinic input] +_imp._fix_co_filename + + code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") + Code object to change. + + path: unicode + File path to use. + / + +Changes code.co_filename to specify the passed-in file path. +[clinic start generated code]*/ + +static PyObject * +_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code, + PyObject *path) +/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/ + +{ + update_compiled_module(code, path); + + Py_RETURN_NONE; +} + + +/* Forward */ +static const struct _frozen * find_frozen(PyObject *); + + +/* Helper to test for built-in module */ + +static int +is_builtin(PyObject *name) +{ + int i; + for (i = 0; PyImport_Inittab[i].name != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(name, PyImport_Inittab[i].name)) { + if (PyImport_Inittab[i].initfunc == NULL) + return -1; + else + return 1; + } + } + return 0; +} + + +/* Return a finder object for a sys.path/pkg.__path__ item 'p', + possibly by fetching it from the path_importer_cache dict. If it + wasn't yet cached, traverse path_hooks until a hook is found + that can handle the path item. Return None if no hook could; + this tells our caller that the path based finder could not find + a finder for this path item. Cache the result in + path_importer_cache. + Returns a borrowed reference. */ + +static PyObject * +get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, + PyObject *p) +{ + PyObject *importer; + Py_ssize_t j, nhooks; + + /* These conditions are the caller's responsibility: */ + assert(PyList_Check(path_hooks)); + assert(PyDict_Check(path_importer_cache)); + + nhooks = PyList_Size(path_hooks); + if (nhooks < 0) + return NULL; /* Shouldn't happen */ + + importer = PyDict_GetItemWithError(path_importer_cache, p); + if (importer != NULL || PyErr_Occurred()) + return importer; + + /* set path_importer_cache[p] to None to avoid recursion */ + if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0) + return NULL; + + for (j = 0; j < nhooks; j++) { + PyObject *hook = PyList_GetItem(path_hooks, j); + if (hook == NULL) + return NULL; + importer = PyObject_CallFunctionObjArgs(hook, p, NULL); + if (importer != NULL) + break; + + if (!PyErr_ExceptionMatches(PyExc_ImportError)) { + return NULL; + } + PyErr_Clear(); + } + if (importer == NULL) { + return Py_None; + } + if (importer != NULL) { + int err = PyDict_SetItem(path_importer_cache, p, importer); + Py_DECREF(importer); + if (err != 0) + return NULL; + } + return importer; +} + +PyObject * +PyImport_GetImporter(PyObject *path) { + PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL; + + path_importer_cache = PySys_GetObject("path_importer_cache"); + path_hooks = PySys_GetObject("path_hooks"); + if (path_importer_cache != NULL && path_hooks != NULL) { + importer = get_path_importer(path_importer_cache, + path_hooks, path); + } + Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */ + return importer; +} + +/*[clinic input] +_imp.create_builtin + + spec: object + / + +Create an extension module. +[clinic start generated code]*/ + +static PyObject * +_imp_create_builtin(PyObject *module, PyObject *spec) +/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ +{ + struct _inittab *p; + PyObject *name; + const char *namestr; + PyObject *mod; + + name = PyObject_GetAttrString(spec, "name"); + if (name == NULL) { + return NULL; + } + + mod = _PyImport_FindExtensionObject(name, name); + if (mod || PyErr_Occurred()) { + Py_DECREF(name); + Py_XINCREF(mod); + return mod; + } + + namestr = PyUnicode_AsUTF8(name); + if (namestr == NULL) { + Py_DECREF(name); + return NULL; + } + + PyObject *modules = NULL; + for (p = PyImport_Inittab; p->name != NULL; p++) { + PyModuleDef *def; + if (_PyUnicode_EqualToASCIIString(name, p->name)) { + if (p->initfunc == NULL) { + /* Cannot re-init internal module ("sys" or "builtins") */ + mod = PyImport_AddModule(namestr); + Py_DECREF(name); + return mod; + } + mod = (*p->initfunc)(); + if (mod == NULL) { + Py_DECREF(name); + return NULL; + } + if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) { + Py_DECREF(name); + return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec); + } else { + /* Remember pointer to module init function. */ + def = PyModule_GetDef(mod); + if (def == NULL) { + Py_DECREF(name); + return NULL; + } + def->m_base.m_init = p->initfunc; + if (modules == NULL) { + modules = PyImport_GetModuleDict(); + } + if (_PyImport_FixupExtensionObject(mod, name, name, + modules) < 0) { + Py_DECREF(name); + return NULL; + } + Py_DECREF(name); + return mod; + } + } + } + Py_DECREF(name); + Py_RETURN_NONE; +} + + +/* Frozen modules */ + +static const struct _frozen * +find_frozen(PyObject *name) +{ + const struct _frozen *p; + + if (name == NULL) + return NULL; + + for (p = PyImport_FrozenModules; ; p++) { + if (p->name == NULL) + return NULL; + if (_PyUnicode_EqualToASCIIString(name, p->name)) + break; + } + return p; +} + +static PyObject * +get_frozen_object(PyObject *name) +{ + const struct _frozen *p = find_frozen(name); + int size; + + if (p == NULL) { + PyErr_Format(PyExc_ImportError, + "No such frozen object named %R", + name); + return NULL; + } + if (p->code == NULL) { + PyErr_Format(PyExc_ImportError, + "Excluded frozen object named %R", + name); + return NULL; + } + size = p->size; + if (size < 0) + size = -size; + return PyMarshal_ReadObjectFromString((const char *)p->code, size); +} + +static PyObject * +is_frozen_package(PyObject *name) +{ + const struct _frozen *p = find_frozen(name); + int size; + + if (p == NULL) { + PyErr_Format(PyExc_ImportError, + "No such frozen object named %R", + name); + return NULL; + } + + size = p->size; + + if (size < 0) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + + +/* Initialize a frozen module. + Return 1 for success, 0 if the module is not found, and -1 with + an exception set if the initialization failed. + This function is also used from frozenmain.c */ + +int +PyImport_ImportFrozenModuleObject(PyObject *name) +{ + const struct _frozen *p; + PyObject *co, *m, *d; + int ispackage; + int size; + + p = find_frozen(name); + + if (p == NULL) + return 0; + if (p->code == NULL) { + PyErr_Format(PyExc_ImportError, + "Excluded frozen object named %R", + name); + return -1; + } + size = p->size; + ispackage = (size < 0); + if (ispackage) + size = -size; + co = PyMarshal_ReadObjectFromString((const char *)p->code, size); + if (co == NULL) + return -1; + if (!PyCode_Check(co)) { + PyErr_Format(PyExc_TypeError, + "frozen object %R is not a code object", + name); + goto err_return; + } + if (ispackage) { + /* Set __path__ to the empty list */ + PyObject *l; + int err; + m = PyImport_AddModuleObject(name); + if (m == NULL) + goto err_return; + d = PyModule_GetDict(m); + l = PyList_New(0); + if (l == NULL) { + goto err_return; + } + err = PyDict_SetItemString(d, "__path__", l); + Py_DECREF(l); + if (err != 0) + goto err_return; + } + d = module_dict_for_exec(name); + if (d == NULL) { + goto err_return; + } + m = exec_code_in_module(name, d, co); + if (m == NULL) + goto err_return; + Py_DECREF(co); + Py_DECREF(m); + return 1; +err_return: + Py_DECREF(co); + return -1; +} + +int +PyImport_ImportFrozenModule(const char *name) +{ + PyObject *nameobj; + int ret; + nameobj = PyUnicode_InternFromString(name); + if (nameobj == NULL) + return -1; + ret = PyImport_ImportFrozenModuleObject(nameobj); + Py_DECREF(nameobj); + return ret; +} + + +/* Import a module, either built-in, frozen, or external, and return + its module object WITH INCREMENTED REFERENCE COUNT */ + +PyObject * +PyImport_ImportModule(const char *name) +{ + // printf("---PyImport_ImportModule %s---\n",name); + + PyObject *pname; + PyObject *result; + + pname = PyUnicode_FromString(name); + if (pname == NULL) + return NULL; + result = PyImport_Import(pname); + Py_DECREF(pname); + return result; +} + +/* Import a module without blocking + * + * At first it tries to fetch the module from sys.modules. If the module was + * never loaded before it loads it with PyImport_ImportModule() unless another + * thread holds the import lock. In the latter case the function raises an + * ImportError instead of blocking. + * + * Returns the module object with incremented ref count. + */ +PyObject * +PyImport_ImportModuleNoBlock(const char *name) +{ + return PyImport_ImportModule(name); +} + + +/* Remove importlib frames from the traceback, + * except in Verbose mode. */ +static void +remove_importlib_frames(PyInterpreterState *interp) +{ + const char *importlib_filename = ""; + const char *external_filename = ""; + const char *remove_frames = "_call_with_frames_removed"; + int always_trim = 0; + int in_importlib = 0; + PyObject *exception, *value, *base_tb, *tb; + PyObject **prev_link, **outer_link = NULL; + + /* Synopsis: if it's an ImportError, we trim all importlib chunks + from the traceback. We always trim chunks + which end with a call to "_call_with_frames_removed". */ + + PyErr_Fetch(&exception, &value, &base_tb); + if (!exception || interp->config.verbose) { + goto done; + } + + if (PyType_IsSubtype((PyTypeObject *) exception, + (PyTypeObject *) PyExc_ImportError)) + always_trim = 1; + + prev_link = &base_tb; + tb = base_tb; + while (tb != NULL) { + PyTracebackObject *traceback = (PyTracebackObject *)tb; + PyObject *next = (PyObject *) traceback->tb_next; + PyFrameObject *frame = traceback->tb_frame; + PyCodeObject *code = frame->f_code; + int now_in_importlib; + + assert(PyTraceBack_Check(tb)); + now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) || + _PyUnicode_EqualToASCIIString(code->co_filename, external_filename); + if (now_in_importlib && !in_importlib) { + /* This is the link to this chunk of importlib tracebacks */ + outer_link = prev_link; + } + in_importlib = now_in_importlib; + + if (in_importlib && + (always_trim || + _PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) { + Py_XINCREF(next); + Py_XSETREF(*outer_link, next); + prev_link = outer_link; + } + else { + prev_link = (PyObject **) &traceback->tb_next; + } + tb = next; + } +done: + PyErr_Restore(exception, value, base_tb); +} + + +static PyObject * +resolve_name(PyObject *name, PyObject *globals, int level) +{ + _Py_IDENTIFIER(__spec__); + _Py_IDENTIFIER(__package__); + _Py_IDENTIFIER(__path__); + _Py_IDENTIFIER(__name__); + _Py_IDENTIFIER(parent); + PyObject *abs_name; + PyObject *package = NULL; + PyObject *spec; + Py_ssize_t last_dot; + PyObject *base; + int level_up; + + if (globals == NULL) { + PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); + goto error; + } + if (!PyDict_Check(globals)) { + PyErr_SetString(PyExc_TypeError, "globals must be a dict"); + goto error; + } + package = _PyDict_GetItemIdWithError(globals, &PyId___package__); + if (package == Py_None) { + package = NULL; + } + else if (package == NULL && PyErr_Occurred()) { + goto error; + } + spec = _PyDict_GetItemIdWithError(globals, &PyId___spec__); + if (spec == NULL && PyErr_Occurred()) { + goto error; + } + + if (package != NULL) { + Py_INCREF(package); + if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, "package must be a string"); + goto error; + } + else if (spec != NULL && spec != Py_None) { + int equal; + PyObject *parent = _PyObject_GetAttrId(spec, &PyId_parent); + if (parent == NULL) { + goto error; + } + + equal = PyObject_RichCompareBool(package, parent, Py_EQ); + Py_DECREF(parent); + if (equal < 0) { + goto error; + } + else if (equal == 0) { + if (PyErr_WarnEx(PyExc_ImportWarning, + "__package__ != __spec__.parent", 1) < 0) { + goto error; + } + } + } + } + else if (spec != NULL && spec != Py_None) { + package = _PyObject_GetAttrId(spec, &PyId_parent); + if (package == NULL) { + goto error; + } + else if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, + "__spec__.parent must be a string"); + goto error; + } + } + else { + if (PyErr_WarnEx(PyExc_ImportWarning, + "can't resolve package from __spec__ or __package__, " + "falling back on __name__ and __path__", 1) < 0) { + goto error; + } + + package = _PyDict_GetItemIdWithError(globals, &PyId___name__); + if (package == NULL) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); + } + goto error; + } + + Py_INCREF(package); + if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, "__name__ must be a string"); + goto error; + } + + if (_PyDict_GetItemIdWithError(globals, &PyId___path__) == NULL) { + Py_ssize_t dot; + + if (PyErr_Occurred() || PyUnicode_READY(package) < 0) { + goto error; + } + + dot = PyUnicode_FindChar(package, '.', + 0, PyUnicode_GET_LENGTH(package), -1); + if (dot == -2) { + goto error; + } + else if (dot == -1) { + goto no_parent_error; + } + PyObject *substr = PyUnicode_Substring(package, 0, dot); + if (substr == NULL) { + goto error; + } + Py_SETREF(package, substr); + } + } + + last_dot = PyUnicode_GET_LENGTH(package); + if (last_dot == 0) { + goto no_parent_error; + } + + for (level_up = 1; level_up < level; level_up += 1) { + last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1); + if (last_dot == -2) { + goto error; + } + else if (last_dot == -1) { + PyErr_SetString(PyExc_ValueError, + "attempted relative import beyond top-level " + "package"); + goto error; + } + } + + base = PyUnicode_Substring(package, 0, last_dot); + Py_DECREF(package); + if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) { + return base; + } + + abs_name = PyUnicode_FromFormat("%U.%U", base, name); + Py_DECREF(base); + return abs_name; + + no_parent_error: + PyErr_SetString(PyExc_ImportError, + "attempted relative import " + "with no known parent package"); + + error: + Py_XDECREF(package); + return NULL; +} + +static PyObject * +import_find_and_load(PyObject *abs_name) +{ + // printf("---import_find_and_load 1--- :"); + // PyObject_Print(abs_name, stdout, Py_PRINT_RAW); + // printf("\n"); + + _Py_IDENTIFIER(_find_and_load); + PyObject *mod = NULL; + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + int import_time = interp->config.import_time; + static int import_level; + static _PyTime_t accumulated; + + _PyTime_t t1 = 0, accumulated_copy = accumulated; + + PyObject *sys_path = PySys_GetObject("path"); + PyObject *sys_meta_path = PySys_GetObject("meta_path"); + PyObject *sys_path_hooks = PySys_GetObject("path_hooks"); + + // printf("sys_path:"); + // PyObject_Print(sys_path, stdout, Py_PRINT_RAW); + // printf("\n"); + + // printf("sys_meta_path:"); + // PyObject_Print(sys_meta_path, stdout, Py_PRINT_RAW); + // printf("\n"); + + // printf("sys_path_hooks:"); + // PyObject_Print(sys_path_hooks, stdout, Py_PRINT_RAW); + // printf("\n"); + // printf("--- import start 1\n"); + if (PySys_Audit("import", "OOOOO", + abs_name, Py_None, sys_path ? sys_path : Py_None, + sys_meta_path ? sys_meta_path : Py_None, + sys_path_hooks ? sys_path_hooks : Py_None) < 0) { + // printf("--- import failed\n"); + return NULL; + } + // printf("--- import end 2\n"); + + /* XOptions is initialized after first some imports. + * So we can't have negative cache before completed initialization. + * Anyway, importlib._find_and_load is much slower than + * _PyDict_GetItemIdWithError(). + */ + if (import_time) { + static int header = 1; + if (header) { + fputs("import time: self [us] | cumulative | imported package\n", + stderr); + header = 0; + } + + import_level++; + t1 = _PyTime_GetPerfCounter(); + accumulated = 0; + } +// printf("--- import end 3\n"); + if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()) + PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name)); + // printf("---import_find_and_load 4--- :"); + // PyObject_Print(abs_name, stdout, Py_PRINT_RAW); + // printf("\n"); + mod = _PyObject_CallMethodIdObjArgs(interp->importlib, + &PyId__find_and_load, abs_name, + interp->import_func, NULL); +// printf("--- import end 5\n"); + if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED()) + PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name), + mod != NULL); +// printf("--- import end 6\n"); + if (import_time) { + _PyTime_t cum = _PyTime_GetPerfCounter() - t1; + + import_level--; + fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n", + (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING), + (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING), + import_level*2, "", PyUnicode_AsUTF8(abs_name)); + + accumulated = accumulated_copy + cum; + } +// printf("--- import end 7\n"); + return mod; +} + +PyObject * +PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, + PyObject *locals, PyObject *fromlist, + int level) +{ + _Py_IDENTIFIER(_handle_fromlist); + PyObject *abs_name = NULL; + PyObject *final_mod = NULL; + PyObject *mod = NULL; + PyObject *package = NULL; + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + int has_from; + + if (name == NULL) { + PyErr_SetString(PyExc_ValueError, "Empty module name"); + goto error; + } + + /* The below code is importlib.__import__() & _gcd_import(), ported to C + for added performance. */ + + if (!PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, "module name must be a string"); + goto error; + } + if (PyUnicode_READY(name) < 0) { + goto error; + } + if (level < 0) { + PyErr_SetString(PyExc_ValueError, "level must be >= 0"); + goto error; + } + + if (level > 0) { + abs_name = resolve_name(name, globals, level); + if (abs_name == NULL) + goto error; + } + else { /* level == 0 */ + if (PyUnicode_GET_LENGTH(name) == 0) { + PyErr_SetString(PyExc_ValueError, "Empty module name"); + goto error; + } + abs_name = name; + Py_INCREF(abs_name); + } + + mod = PyImport_GetModule(abs_name); + if (mod == NULL && PyErr_Occurred()) { + goto error; + } + + if (mod != NULL && mod != Py_None) { + _Py_IDENTIFIER(__spec__); + _Py_IDENTIFIER(_lock_unlock_module); + PyObject *spec; + + /* Optimization: only call _bootstrap._lock_unlock_module() if + __spec__._initializing is true. + NOTE: because of this, initializing must be set *before* + stuffing the new module in sys.modules. + */ + spec = _PyObject_GetAttrId(mod, &PyId___spec__); + if (_PyModuleSpec_IsInitializing(spec)) { + PyObject *value = _PyObject_CallMethodIdObjArgs(interp->importlib, + &PyId__lock_unlock_module, abs_name, + NULL); + if (value == NULL) { + Py_DECREF(spec); + goto error; + } + Py_DECREF(value); + } + Py_XDECREF(spec); + } + else { + Py_XDECREF(mod); + mod = import_find_and_load(abs_name); + if (mod == NULL) { + goto error; + } + } + + has_from = 0; + if (fromlist != NULL && fromlist != Py_None) { + has_from = PyObject_IsTrue(fromlist); + if (has_from < 0) + goto error; + } + if (!has_from) { + Py_ssize_t len = PyUnicode_GET_LENGTH(name); + if (level == 0 || len > 0) { + Py_ssize_t dot; + + dot = PyUnicode_FindChar(name, '.', 0, len, 1); + if (dot == -2) { + goto error; + } + + if (dot == -1) { + /* No dot in module name, simple exit */ + final_mod = mod; + Py_INCREF(mod); + goto error; + } + + if (level == 0) { + PyObject *front = PyUnicode_Substring(name, 0, dot); + if (front == NULL) { + goto error; + } + + final_mod = PyImport_ImportModuleLevelObject(front, NULL, NULL, NULL, 0); + Py_DECREF(front); + } + else { + Py_ssize_t cut_off = len - dot; + Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name); + PyObject *to_return = PyUnicode_Substring(abs_name, 0, + abs_name_len - cut_off); + if (to_return == NULL) { + goto error; + } + + final_mod = PyImport_GetModule(to_return); + Py_DECREF(to_return); + if (final_mod == NULL) { + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_KeyError, + "%R not in sys.modules as expected", + to_return); + } + goto error; + } + } + } + else { + final_mod = mod; + Py_INCREF(mod); + } + } + else { + _Py_IDENTIFIER(__path__); + PyObject *path; + if (_PyObject_LookupAttrId(mod, &PyId___path__, &path) < 0) { + goto error; + } + if (path) { + Py_DECREF(path); + final_mod = _PyObject_CallMethodIdObjArgs( + interp->importlib, &PyId__handle_fromlist, + mod, fromlist, interp->import_func, NULL); + } + else { + final_mod = mod; + Py_INCREF(mod); + } + } + + error: + Py_XDECREF(abs_name); + Py_XDECREF(mod); + Py_XDECREF(package); + if (final_mod == NULL) { + remove_importlib_frames(interp); + } + return final_mod; +} + +PyObject * +PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, + PyObject *fromlist, int level) +{ + PyObject *nameobj, *mod; + nameobj = PyUnicode_FromString(name); + if (nameobj == NULL) + return NULL; + mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals, + fromlist, level); + Py_DECREF(nameobj); + return mod; +} + + +/* Re-import a module of any kind and return its module object, WITH + INCREMENTED REFERENCE COUNT */ + +PyObject * +PyImport_ReloadModule(PyObject *m) +{ + _Py_IDENTIFIER(importlib); + _Py_IDENTIFIER(reload); + PyObject *reloaded_module = NULL; + PyObject *importlib = _PyImport_GetModuleId(&PyId_importlib); + if (importlib == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + + importlib = PyImport_ImportModule("importlib"); + if (importlib == NULL) { + return NULL; + } + } + + reloaded_module = _PyObject_CallMethodIdObjArgs(importlib, &PyId_reload, m, NULL); + Py_DECREF(importlib); + return reloaded_module; +} + + +/* Higher-level import emulator which emulates the "import" statement + more accurately -- it invokes the __import__() function from the + builtins of the current globals. This means that the import is + done using whatever import hooks are installed in the current + environment. + A dummy list ["__doc__"] is passed as the 4th argument so that + e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache")) + will return instead of . */ + +PyObject * +PyImport_Import(PyObject *module_name) +{ + static PyObject *silly_list = NULL; + static PyObject *builtins_str = NULL; + static PyObject *import_str = NULL; + PyObject *globals = NULL; + PyObject *import = NULL; + PyObject *builtins = NULL; + PyObject *r = NULL; + + /* Initialize constant string objects */ + if (silly_list == NULL) { + import_str = PyUnicode_InternFromString("__import__"); + if (import_str == NULL) + return NULL; + builtins_str = PyUnicode_InternFromString("__builtins__"); + if (builtins_str == NULL) + return NULL; + silly_list = PyList_New(0); + if (silly_list == NULL) + return NULL; + } + + /* Get the builtins from current globals */ + globals = PyEval_GetGlobals(); + if (globals != NULL) { + Py_INCREF(globals); + builtins = PyObject_GetItem(globals, builtins_str); + if (builtins == NULL) + goto err; + } + else { + /* No globals -- use standard builtins, and fake globals */ + builtins = PyImport_ImportModuleLevel("builtins", + NULL, NULL, NULL, 0); + if (builtins == NULL) + return NULL; + globals = Py_BuildValue("{OO}", builtins_str, builtins); + if (globals == NULL) + goto err; + } + + /* Get the __import__ function from the builtins */ + if (PyDict_Check(builtins)) { + import = PyObject_GetItem(builtins, import_str); + if (import == NULL) + PyErr_SetObject(PyExc_KeyError, import_str); + } + else + import = PyObject_GetAttr(builtins, import_str); + if (import == NULL) + goto err; + + /* Call the __import__ function with the proper argument list + Always use absolute import here. + Calling for side-effect of import. */ + // printf("---PyObject_CallFunction in--- :"); + // PyObject_Print(module_name, stdout, Py_PRINT_RAW); + // printf("\n"); + // printf("---PyObject_CallFunction in--- %s\n",PyBytes_AsString(module_name)); + r = PyObject_CallFunction(import, "OOOOi", module_name, globals, + globals, silly_list, 0, NULL); + // printf("---PyObject_CallFunction out---%s\n",PyBytes_AsString(module_name)); + if (r == NULL) + goto err; + Py_DECREF(r); + + r = PyImport_GetModule(module_name); + if (r == NULL && !PyErr_Occurred()) { + PyErr_SetObject(PyExc_KeyError, module_name); + } + + err: + Py_XDECREF(globals); + Py_XDECREF(builtins); + Py_XDECREF(import); + + return r; +} + +/*[clinic input] +_imp.extension_suffixes + +Returns the list of file suffixes used to identify extension modules. +[clinic start generated code]*/ + +static PyObject * +_imp_extension_suffixes_impl(PyObject *module) +/*[clinic end generated code: output=0bf346e25a8f0cd3 input=ecdeeecfcb6f839e]*/ +{ + // printf("\n--------4--------\n"); + PyObject *list; + + list = PyList_New(0); + if (list == NULL) + return NULL; +#ifdef HAVE_DYNAMIC_LOADING + const char *suffix; + unsigned int index = 0; + + while ((suffix = _PyImport_DynLoadFiletab[index])) { + PyObject *item = PyUnicode_FromString(suffix); + if (item == NULL) { + Py_DECREF(list); + return NULL; + } + if (PyList_Append(list, item) < 0) { + Py_DECREF(list); + Py_DECREF(item); + return NULL; + } + Py_DECREF(item); + index += 1; + } +#endif + return list; +} + +/*[clinic input] +_imp.init_frozen + + name: unicode + / + +Initializes a frozen module. +[clinic start generated code]*/ + +static PyObject * +_imp_init_frozen_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/ +{ + int ret; + PyObject *m; + + ret = PyImport_ImportFrozenModuleObject(name); + if (ret < 0) + return NULL; + if (ret == 0) { + Py_RETURN_NONE; + } + m = PyImport_AddModuleObject(name); + Py_XINCREF(m); + return m; +} + +/*[clinic input] +_imp.get_frozen_object + + name: unicode + / + +Create a code object for a frozen module. +[clinic start generated code]*/ + +static PyObject * +_imp_get_frozen_object_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=2568cc5b7aa0da63 input=ed689bc05358fdbd]*/ +{ + return get_frozen_object(name); +} + +/*[clinic input] +_imp.is_frozen_package + + name: unicode + / + +Returns True if the module name is of a frozen package. +[clinic start generated code]*/ + +static PyObject * +_imp_is_frozen_package_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=e70cbdb45784a1c9 input=81b6cdecd080fbb8]*/ +{ + return is_frozen_package(name); +} + +/*[clinic input] +_imp.is_builtin + + name: unicode + / + +Returns True if the module name corresponds to a built-in module. +[clinic start generated code]*/ + +static PyObject * +_imp_is_builtin_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=3bfd1162e2d3be82 input=86befdac021dd1c7]*/ +{ + return PyLong_FromLong(is_builtin(name)); +} + +/*[clinic input] +_imp.is_frozen + + name: unicode + / + +Returns True if the module name corresponds to a frozen module. +[clinic start generated code]*/ + +static PyObject * +_imp_is_frozen_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=01f408f5ec0f2577 input=7301dbca1897d66b]*/ +{ + // printf("\n-------8--------\n"); + const struct _frozen *p; + + p = find_frozen(name); + return PyBool_FromLong((long) (p == NULL ? 0 : p->size)); +} + +/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */ +static int +exec_builtin_or_dynamic(PyObject *mod) { + // printf("\n-------9--------\n"); + PyModuleDef *def; + void *state; + + if (!PyModule_Check(mod)) { + return 0; + } + + def = PyModule_GetDef(mod); + if (def == NULL) { + return 0; + } + + state = PyModule_GetState(mod); + if (state) { + /* Already initialized; skip reload */ + return 0; + } + + return PyModule_ExecDef(mod, def); +} + +#ifdef HAVE_DYNAMIC_LOADING + +/*[clinic input] +_imp.create_dynamic + + spec: object + file: object = NULL + / + +Create an extension module. +[clinic start generated code]*/ + +static PyObject * +_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) +/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/ +{ + // printf("\n-------2--------\n"); + PyObject *mod, *name, *path; + FILE *fp; + + name = PyObject_GetAttrString(spec, "name"); + if (name == NULL) { + return NULL; + } + + path = PyObject_GetAttrString(spec, "origin"); + if (path == NULL) { + Py_DECREF(name); + return NULL; + } + + mod = _PyImport_FindExtensionObject(name, path); + if (mod != NULL || PyErr_Occurred()) { + Py_DECREF(name); + Py_DECREF(path); + Py_XINCREF(mod); + return mod; + } + + if (file != NULL) { + fp = _Py_fopen_obj(path, "r"); + if (fp == NULL) { + Py_DECREF(name); + Py_DECREF(path); + return NULL; + } + } + else + fp = NULL; + + mod = _PyImport_LoadDynamicModuleWithSpec(spec, fp); + + Py_DECREF(name); + Py_DECREF(path); + if (fp) + fclose(fp); + return mod; +} + +/*[clinic input] +_imp.exec_dynamic -> int + + mod: object + / + +Initialize an extension module. +[clinic start generated code]*/ + +static int +_imp_exec_dynamic_impl(PyObject *module, PyObject *mod) +/*[clinic end generated code: output=f5720ac7b465877d input=9fdbfcb250280d3a]*/ +{ + // printf("\n--------77777--------\n"); + return exec_builtin_or_dynamic(mod); +} + + +#endif /* HAVE_DYNAMIC_LOADING */ + +/*[clinic input] +_imp.exec_builtin -> int + + mod: object + / + +Initialize a built-in module. +[clinic start generated code]*/ + +static int +_imp_exec_builtin_impl(PyObject *module, PyObject *mod) +/*[clinic end generated code: output=0262447b240c038e input=7beed5a2f12a60ca]*/ +{ + // printf("\n--------5--------\n"); + return exec_builtin_or_dynamic(mod); +} + +/*[clinic input] +_imp.source_hash + + key: long + source: Py_buffer +[clinic start generated code]*/ + +static PyObject * +_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source) +/*[clinic end generated code: output=edb292448cf399ea input=9aaad1e590089789]*/ +{ + union { + uint64_t x; + char data[sizeof(uint64_t)]; + } hash; + hash.x = _Py_KeyedHash((uint64_t)key, source->buf, source->len); +#if !PY_LITTLE_ENDIAN + // Force to little-endian. There really ought to be a succinct standard way + // to do this. + for (size_t i = 0; i < sizeof(hash.data)/2; i++) { + char tmp = hash.data[i]; + hash.data[i] = hash.data[sizeof(hash.data) - i - 1]; + hash.data[sizeof(hash.data) - i - 1] = tmp; + } +#endif + return PyBytes_FromStringAndSize(hash.data, sizeof(hash.data)); +} + + +PyDoc_STRVAR(doc_imp, +"(Extremely) low-level import machinery bits as used by importlib and imp."); + +static PyMethodDef imp_methods[] = { + _IMP_EXTENSION_SUFFIXES_METHODDEF + _IMP_LOCK_HELD_METHODDEF + _IMP_ACQUIRE_LOCK_METHODDEF + _IMP_RELEASE_LOCK_METHODDEF + _IMP_GET_FROZEN_OBJECT_METHODDEF + _IMP_IS_FROZEN_PACKAGE_METHODDEF + _IMP_CREATE_BUILTIN_METHODDEF + _IMP_INIT_FROZEN_METHODDEF + _IMP_IS_BUILTIN_METHODDEF + _IMP_IS_FROZEN_METHODDEF + _IMP_CREATE_DYNAMIC_METHODDEF + _IMP_EXEC_DYNAMIC_METHODDEF + _IMP_EXEC_BUILTIN_METHODDEF + _IMP__FIX_CO_FILENAME_METHODDEF + _IMP_SOURCE_HASH_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef impmodule = { + PyModuleDef_HEAD_INIT, + "_imp", + doc_imp, + 0, + imp_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__imp(void) +{ + PyObject *m, *d; +// printf("\n=====================\n"); + m = PyModule_Create(&impmodule); + if (m == NULL) { + goto failure; + } + d = PyModule_GetDict(m); + if (d == NULL) { + goto failure; + } + + const wchar_t *mode = _PyInterpreterState_Get()->config.check_hash_pycs_mode; + PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1); + if (pyc_mode == NULL) { + goto failure; + } + if (PyDict_SetItemString(d, "check_hash_based_pycs", pyc_mode) < 0) { + Py_DECREF(pyc_mode); + goto failure; + } + Py_DECREF(pyc_mode); + + return m; + failure: + Py_XDECREF(m); + return NULL; +} + + +/* API for embedding applications that want to add their own entries + to the table of built-in modules. This should normally be called + *before* Py_Initialize(). When the table resize fails, -1 is + returned and the existing table is unchanged. + + After a similar function by Just van Rossum. */ + +int +PyImport_ExtendInittab(struct _inittab *newtab) +{ + struct _inittab *p; + size_t i, n; + int res = 0; + + /* Count the number of entries in both tables */ + for (n = 0; newtab[n].name != NULL; n++) + ; + if (n == 0) + return 0; /* Nothing to do */ + for (i = 0; PyImport_Inittab[i].name != NULL; i++) + ; + + /* Force default raw memory allocator to get a known allocator to be able + to release the memory in _PyImport_Fini2() */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Allocate new memory for the combined table */ + p = NULL; + if (i + n <= SIZE_MAX / sizeof(struct _inittab) - 1) { + size_t size = sizeof(struct _inittab) * (i + n + 1); + p = PyMem_RawRealloc(inittab_copy, size); + } + if (p == NULL) { + res = -1; + goto done; + } + + /* Copy the tables into the new memory at the first call + to PyImport_ExtendInittab(). */ + if (inittab_copy != PyImport_Inittab) { + memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab)); + } + memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab)); + PyImport_Inittab = inittab_copy = p; + +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return res; +} + +/* Shorthand to add a single entry given a name and a function */ + +int +PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) +{ + struct _inittab newtab[2]; + + memset(newtab, '\0', sizeof newtab); + + newtab[0].name = name; + newtab[0].initfunc = initfunc; + + return PyImport_ExtendInittab(newtab); +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Python/importdl.c b/python/Python/importdl.c new file mode 100755 index 0000000..b071874 --- /dev/null +++ b/python/Python/importdl.c @@ -0,0 +1,247 @@ + +/* Support for dynamic loading of extension modules */ + +#include "Python.h" + +/* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is + supported on this platform. configure will then compile and link in one + of the dynload_*.c files, as appropriate. We will call a function in + those modules to get a function pointer to the module's init function. +*/ +#ifdef HAVE_DYNAMIC_LOADING + +#include "importdl.h" + +#ifdef MS_WINDOWS +extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, + const char *shortname, + PyObject *pathname, + FILE *fp); +#else +extern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp); +#endif + +static const char * const ascii_only_prefix = "PyInit"; +static const char * const nonascii_prefix = "PyInitU"; + +/* Get the variable part of a module's export symbol name. + * Returns a bytes instance. For non-ASCII-named modules, the name is + * encoded as per PEP 489. + * The hook_prefix pointer is set to either ascii_only_prefix or + * nonascii_prefix, as appropriate. + */ +static PyObject * +get_encoded_name(PyObject *name, const char **hook_prefix) { + PyObject *tmp; + PyObject *encoded = NULL; + PyObject *modname = NULL; + Py_ssize_t name_len, lastdot; + _Py_IDENTIFIER(replace); + + /* Get the short name (substring after last dot) */ + name_len = PyUnicode_GetLength(name); + lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1); + if (lastdot < -1) { + return NULL; + } else if (lastdot >= 0) { + tmp = PyUnicode_Substring(name, lastdot + 1, name_len); + if (tmp == NULL) + return NULL; + name = tmp; + /* "name" now holds a new reference to the substring */ + } else { + Py_INCREF(name); + } + + /* Encode to ASCII or Punycode, as needed */ + encoded = PyUnicode_AsEncodedString(name, "ascii", NULL); + if (encoded != NULL) { + *hook_prefix = ascii_only_prefix; + } else { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + PyErr_Clear(); + encoded = PyUnicode_AsEncodedString(name, "punycode", NULL); + if (encoded == NULL) { + goto error; + } + *hook_prefix = nonascii_prefix; + } else { + goto error; + } + } + + /* Replace '-' by '_' */ + modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_'); + if (modname == NULL) + goto error; + + Py_DECREF(name); + Py_DECREF(encoded); + return modname; +error: + Py_DECREF(name); + Py_XDECREF(encoded); + return NULL; +} + +PyObject * +_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) +{ + // printf("\n----------a----------\n"); +#ifndef MS_WINDOWS + PyObject *pathbytes = NULL; +#endif + PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL; + const char *name_buf, *hook_prefix; + const char *oldcontext; + dl_funcptr exportfunc; + PyModuleDef *def; + PyObject *(*p0)(void); + + name_unicode = PyObject_GetAttrString(spec, "name"); + if (name_unicode == NULL) { + return NULL; + } + if (!PyUnicode_Check(name_unicode)) { + PyErr_SetString(PyExc_TypeError, + "spec.name must be a string"); + goto error; + } + + name = get_encoded_name(name_unicode, &hook_prefix); + if (name == NULL) { + goto error; + } + name_buf = PyBytes_AS_STRING(name); + + path = PyObject_GetAttrString(spec, "origin"); + if (path == NULL) + goto error; + + if (PySys_Audit("import", "OOOOO", name_unicode, path, + Py_None, Py_None, Py_None) < 0) { + return NULL; + } + +#ifdef MS_WINDOWS + exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf, + path, fp); +#else + pathbytes = PyUnicode_EncodeFSDefault(path); + if (pathbytes == NULL) + goto error; + exportfunc = _PyImport_FindSharedFuncptr(hook_prefix, name_buf, + PyBytes_AS_STRING(pathbytes), + fp); + Py_DECREF(pathbytes); +#endif + + if (exportfunc == NULL) { + if (!PyErr_Occurred()) { + PyObject *msg; + msg = PyUnicode_FromFormat( + "dynamic module does not define " + "module export function (%s_%s)", + hook_prefix, name_buf); + if (msg == NULL) + goto error; + PyErr_SetImportError(msg, name_unicode, path); + Py_DECREF(msg); + } + goto error; + } + + p0 = (PyObject *(*)(void))exportfunc; + + /* Package context is needed for single-phase init */ + oldcontext = _Py_PackageContext; + _Py_PackageContext = PyUnicode_AsUTF8(name_unicode); + if (_Py_PackageContext == NULL) { + _Py_PackageContext = oldcontext; + goto error; + } + m = p0(); + _Py_PackageContext = oldcontext; + + if (m == NULL) { + if (!PyErr_Occurred()) { + PyErr_Format( + PyExc_SystemError, + "initialization of %s failed without raising an exception", + name_buf); + } + goto error; + } else if (PyErr_Occurred()) { + PyErr_Clear(); + PyErr_Format( + PyExc_SystemError, + "initialization of %s raised unreported exception", + name_buf); + m = NULL; + goto error; + } + if (Py_TYPE(m) == NULL) { + /* This can happen when a PyModuleDef is returned without calling + * PyModuleDef_Init on it + */ + PyErr_Format(PyExc_SystemError, + "init function of %s returned uninitialized object", + name_buf); + m = NULL; /* prevent segfault in DECREF */ + goto error; + } + if (PyObject_TypeCheck(m, &PyModuleDef_Type)) { + Py_DECREF(name_unicode); + Py_DECREF(name); + Py_DECREF(path); + return PyModule_FromDefAndSpec((PyModuleDef*)m, spec); + } + + /* Fall back to single-phase init mechanism */ + + if (hook_prefix == nonascii_prefix) { + /* don't allow legacy init for non-ASCII module names */ + PyErr_Format( + PyExc_SystemError, + "initialization of * did not return PyModuleDef", + name_buf); + goto error; + } + + /* Remember pointer to module init function. */ + def = PyModule_GetDef(m); + if (def == NULL) { + PyErr_Format(PyExc_SystemError, + "initialization of %s did not return an extension " + "module", name_buf); + goto error; + } + def->m_base.m_init = p0; + + /* Remember the filename as the __file__ attribute */ + if (PyModule_AddObject(m, "__file__", path) < 0) + PyErr_Clear(); /* Not important enough to report */ + else + Py_INCREF(path); + + PyObject *modules = PyImport_GetModuleDict(); + if (_PyImport_FixupExtensionObject(m, name_unicode, path, modules) < 0) + goto error; + + Py_DECREF(name_unicode); + Py_DECREF(name); + Py_DECREF(path); + + return m; + +error: + Py_DECREF(name_unicode); + Py_XDECREF(name); + Py_XDECREF(path); + Py_XDECREF(m); + return NULL; +} + +#endif /* HAVE_DYNAMIC_LOADING */ diff --git a/python/Python/importdl.h b/python/Python/importdl.h new file mode 100755 index 0000000..9847652 --- /dev/null +++ b/python/Python/importdl.h @@ -0,0 +1,27 @@ +#ifndef Py_IMPORTDL_H +#define Py_IMPORTDL_H + +#ifdef __cplusplus +extern "C" { +#endif + + +extern const char *_PyImport_DynLoadFiletab[]; + +extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *); + +/* Max length of module suffix searched for -- accommodates "module.slb" */ +#define MAXSUFFIXSIZE 12 + +#ifdef MS_WINDOWS +#include +typedef FARPROC dl_funcptr; +#else +typedef void (*dl_funcptr)(void); +#endif + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_IMPORTDL_H */ diff --git a/python/Python/importlib.h b/python/Python/importlib.h new file mode 100755 index 0000000..6719574 --- /dev/null +++ b/python/Python/importlib.h @@ -0,0 +1,1789 @@ +/* Auto-generated by Programs/_freeze_importlib.c */ +const unsigned char _Py_M__importlib_bootstrap[] = { + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,64,0,0,0,115,194,1,0,0,100,0, + 90,0,100,1,97,1,100,2,100,3,132,0,90,2,100,4, + 100,5,132,0,90,3,105,0,90,4,105,0,90,5,71,0, + 100,6,100,7,132,0,100,7,101,6,131,3,90,7,71,0, + 100,8,100,9,132,0,100,9,131,2,90,8,71,0,100,10, + 100,11,132,0,100,11,131,2,90,9,71,0,100,12,100,13, + 132,0,100,13,131,2,90,10,100,14,100,15,132,0,90,11, + 100,16,100,17,132,0,90,12,100,18,100,19,132,0,90,13, + 100,20,100,21,156,1,100,22,100,23,132,2,90,14,100,24, + 100,25,132,0,90,15,100,26,100,27,132,0,90,16,100,28, + 100,29,132,0,90,17,100,30,100,31,132,0,90,18,71,0, + 100,32,100,33,132,0,100,33,131,2,90,19,100,1,100,1, + 100,34,156,2,100,35,100,36,132,2,90,20,100,94,100,37, + 100,38,132,1,90,21,100,39,100,40,156,1,100,41,100,42, + 132,2,90,22,100,43,100,44,132,0,90,23,100,45,100,46, + 132,0,90,24,100,47,100,48,132,0,90,25,100,49,100,50, + 132,0,90,26,100,51,100,52,132,0,90,27,100,53,100,54, + 132,0,90,28,71,0,100,55,100,56,132,0,100,56,131,2, + 90,29,71,0,100,57,100,58,132,0,100,58,131,2,90,30, + 71,0,100,59,100,60,132,0,100,60,131,2,90,31,100,61, + 100,62,132,0,90,32,100,63,100,64,132,0,90,33,100,95, + 100,65,100,66,132,1,90,34,100,67,100,68,132,0,90,35, + 100,69,90,36,101,36,100,70,23,0,90,37,100,71,100,72, + 132,0,90,38,101,39,131,0,90,40,100,73,100,74,132,0, + 90,41,100,96,100,76,100,77,132,1,90,42,100,39,100,78, + 156,1,100,79,100,80,132,2,90,43,100,81,100,82,132,0, + 90,44,100,97,100,84,100,85,132,1,90,45,100,86,100,87, + 132,0,90,46,100,88,100,89,132,0,90,47,100,90,100,91, + 132,0,90,48,100,92,100,93,132,0,90,49,100,1,83,0, + 41,98,97,83,1,0,0,67,111,114,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,105,109, + 112,111,114,116,46,10,10,84,104,105,115,32,109,111,100,117, + 108,101,32,105,115,32,78,79,84,32,109,101,97,110,116,32, + 116,111,32,98,101,32,100,105,114,101,99,116,108,121,32,105, + 109,112,111,114,116,101,100,33,32,73,116,32,104,97,115,32, + 98,101,101,110,32,100,101,115,105,103,110,101,100,32,115,117, + 99,104,10,116,104,97,116,32,105,116,32,99,97,110,32,98, + 101,32,98,111,111,116,115,116,114,97,112,112,101,100,32,105, + 110,116,111,32,80,121,116,104,111,110,32,97,115,32,116,104, + 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,111,102,32,105,109,112,111,114,116,46,32,65,115,10,115, + 117,99,104,32,105,116,32,114,101,113,117,105,114,101,115,32, + 116,104,101,32,105,110,106,101,99,116,105,111,110,32,111,102, + 32,115,112,101,99,105,102,105,99,32,109,111,100,117,108,101, + 115,32,97,110,100,32,97,116,116,114,105,98,117,116,101,115, + 32,105,110,32,111,114,100,101,114,32,116,111,10,119,111,114, + 107,46,32,79,110,101,32,115,104,111,117,108,100,32,117,115, + 101,32,105,109,112,111,114,116,108,105,98,32,97,115,32,116, + 104,101,32,112,117,98,108,105,99,45,102,97,99,105,110,103, + 32,118,101,114,115,105,111,110,32,111,102,32,116,104,105,115, + 32,109,111,100,117,108,101,46,10,10,78,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,7,0,0,0, + 67,0,0,0,115,56,0,0,0,100,1,68,0,93,32,125, + 2,116,0,124,1,124,2,131,2,114,4,116,1,124,0,124, + 2,116,2,124,1,124,2,131,2,131,3,1,0,113,4,124, + 0,106,3,160,4,124,1,106,3,161,1,1,0,100,2,83, + 0,41,3,122,47,83,105,109,112,108,101,32,115,117,98,115, + 116,105,116,117,116,101,32,102,111,114,32,102,117,110,99,116, + 111,111,108,115,46,117,112,100,97,116,101,95,119,114,97,112, + 112,101,114,46,41,4,218,10,95,95,109,111,100,117,108,101, + 95,95,218,8,95,95,110,97,109,101,95,95,218,12,95,95, + 113,117,97,108,110,97,109,101,95,95,218,7,95,95,100,111, + 99,95,95,78,41,5,218,7,104,97,115,97,116,116,114,218, + 7,115,101,116,97,116,116,114,218,7,103,101,116,97,116,116, + 114,218,8,95,95,100,105,99,116,95,95,218,6,117,112,100, + 97,116,101,41,3,90,3,110,101,119,90,3,111,108,100,218, + 7,114,101,112,108,97,99,101,169,0,114,10,0,0,0,250, + 29,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, + 105,98,46,95,98,111,111,116,115,116,114,97,112,62,218,5, + 95,119,114,97,112,27,0,0,0,115,8,0,0,0,0,2, + 8,1,10,1,20,1,114,12,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0, + 67,0,0,0,115,12,0,0,0,116,0,116,1,131,1,124, + 0,131,1,83,0,169,1,78,41,2,218,4,116,121,112,101, + 218,3,115,121,115,169,1,218,4,110,97,109,101,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,11,95,110, + 101,119,95,109,111,100,117,108,101,35,0,0,0,115,2,0, + 0,0,0,1,114,18,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0, + 0,0,115,12,0,0,0,101,0,90,1,100,0,90,2,100, + 1,83,0,41,2,218,14,95,68,101,97,100,108,111,99,107, + 69,114,114,111,114,78,41,3,114,1,0,0,0,114,0,0, + 0,0,114,2,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,19,0,0,0, + 48,0,0,0,115,2,0,0,0,8,1,114,19,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,56,0,0,0,101,0, + 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, + 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, + 90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,0, + 90,8,100,12,83,0,41,13,218,11,95,77,111,100,117,108, + 101,76,111,99,107,122,169,65,32,114,101,99,117,114,115,105, + 118,101,32,108,111,99,107,32,105,109,112,108,101,109,101,110, + 116,97,116,105,111,110,32,119,104,105,99,104,32,105,115,32, + 97,98,108,101,32,116,111,32,100,101,116,101,99,116,32,100, + 101,97,100,108,111,99,107,115,10,32,32,32,32,40,101,46, + 103,46,32,116,104,114,101,97,100,32,49,32,116,114,121,105, + 110,103,32,116,111,32,116,97,107,101,32,108,111,99,107,115, + 32,65,32,116,104,101,110,32,66,44,32,97,110,100,32,116, + 104,114,101,97,100,32,50,32,116,114,121,105,110,103,32,116, + 111,10,32,32,32,32,116,97,107,101,32,108,111,99,107,115, + 32,66,32,116,104,101,110,32,65,41,46,10,32,32,32,32, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,2,0,0,0,67,0,0,0,115,48,0,0,0,116,0, + 160,1,161,0,124,0,95,2,116,0,160,1,161,0,124,0, + 95,3,124,1,124,0,95,4,100,0,124,0,95,5,100,1, + 124,0,95,6,100,1,124,0,95,7,100,0,83,0,169,2, + 78,233,0,0,0,0,41,8,218,7,95,116,104,114,101,97, + 100,90,13,97,108,108,111,99,97,116,101,95,108,111,99,107, + 218,4,108,111,99,107,218,6,119,97,107,101,117,112,114,17, + 0,0,0,218,5,111,119,110,101,114,218,5,99,111,117,110, + 116,218,7,119,97,105,116,101,114,115,169,2,218,4,115,101, + 108,102,114,17,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,8,95,95,105,110,105,116,95,95, + 58,0,0,0,115,12,0,0,0,0,1,10,1,10,1,6, + 1,6,1,6,1,122,20,95,77,111,100,117,108,101,76,111, + 99,107,46,95,95,105,110,105,116,95,95,99,1,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0, + 67,0,0,0,115,60,0,0,0,116,0,160,1,161,0,125, + 1,124,0,106,2,125,2,116,3,160,4,124,2,161,1,125, + 3,124,3,100,0,107,8,114,36,100,1,83,0,124,3,106, + 2,125,2,124,2,124,1,107,2,114,14,100,2,83,0,113, + 14,100,0,83,0,41,3,78,70,84,41,5,114,23,0,0, + 0,218,9,103,101,116,95,105,100,101,110,116,114,26,0,0, + 0,218,12,95,98,108,111,99,107,105,110,103,95,111,110,218, + 3,103,101,116,41,4,114,30,0,0,0,90,2,109,101,218, + 3,116,105,100,114,24,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,12,104,97,115,95,100,101, + 97,100,108,111,99,107,66,0,0,0,115,16,0,0,0,0, + 2,8,1,6,2,10,1,8,1,4,1,6,1,8,1,122, + 24,95,77,111,100,117,108,101,76,111,99,107,46,104,97,115, + 95,100,101,97,100,108,111,99,107,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,9,0,0,0,67,0, + 0,0,115,178,0,0,0,116,0,160,1,161,0,125,1,124, + 0,116,2,124,1,60,0,122,148,124,0,106,3,143,110,1, + 0,124,0,106,4,100,1,107,2,115,46,124,0,106,5,124, + 1,107,2,114,84,124,1,124,0,95,5,124,0,4,0,106, + 4,100,2,55,0,2,0,95,4,87,0,53,0,81,0,82, + 0,163,0,87,0,162,86,100,3,83,0,124,0,160,6,161, + 0,114,104,116,7,100,4,124,0,22,0,131,1,130,1,124, + 0,106,8,160,9,100,5,161,1,114,130,124,0,4,0,106, + 10,100,2,55,0,2,0,95,10,87,0,53,0,81,0,82, + 0,88,0,124,0,106,8,160,9,161,0,1,0,124,0,106, + 8,160,11,161,0,1,0,113,18,87,0,53,0,116,2,124, + 1,61,0,88,0,100,6,83,0,41,7,122,185,10,32,32, + 32,32,32,32,32,32,65,99,113,117,105,114,101,32,116,104, + 101,32,109,111,100,117,108,101,32,108,111,99,107,46,32,32, + 73,102,32,97,32,112,111,116,101,110,116,105,97,108,32,100, + 101,97,100,108,111,99,107,32,105,115,32,100,101,116,101,99, + 116,101,100,44,10,32,32,32,32,32,32,32,32,97,32,95, + 68,101,97,100,108,111,99,107,69,114,114,111,114,32,105,115, + 32,114,97,105,115,101,100,46,10,32,32,32,32,32,32,32, + 32,79,116,104,101,114,119,105,115,101,44,32,116,104,101,32, + 108,111,99,107,32,105,115,32,97,108,119,97,121,115,32,97, + 99,113,117,105,114,101,100,32,97,110,100,32,84,114,117,101, + 32,105,115,32,114,101,116,117,114,110,101,100,46,10,32,32, + 32,32,32,32,32,32,114,22,0,0,0,233,1,0,0,0, + 84,122,23,100,101,97,100,108,111,99,107,32,100,101,116,101, + 99,116,101,100,32,98,121,32,37,114,70,78,41,12,114,23, + 0,0,0,114,32,0,0,0,114,33,0,0,0,114,24,0, + 0,0,114,27,0,0,0,114,26,0,0,0,114,36,0,0, + 0,114,19,0,0,0,114,25,0,0,0,218,7,97,99,113, + 117,105,114,101,114,28,0,0,0,218,7,114,101,108,101,97, + 115,101,169,2,114,30,0,0,0,114,35,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,38,0, + 0,0,78,0,0,0,115,30,0,0,0,0,6,8,1,8, + 1,2,2,8,1,20,1,6,1,14,1,18,1,8,1,12, + 1,12,1,24,2,10,1,16,2,122,19,95,77,111,100,117, + 108,101,76,111,99,107,46,97,99,113,117,105,114,101,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,9, + 0,0,0,67,0,0,0,115,122,0,0,0,116,0,160,1, + 161,0,125,1,124,0,106,2,143,98,1,0,124,0,106,3, + 124,1,107,3,114,34,116,4,100,1,131,1,130,1,124,0, + 106,5,100,2,107,4,115,48,116,6,130,1,124,0,4,0, + 106,5,100,3,56,0,2,0,95,5,124,0,106,5,100,2, + 107,2,114,108,100,0,124,0,95,3,124,0,106,7,114,108, + 124,0,4,0,106,7,100,3,56,0,2,0,95,7,124,0, + 106,8,160,9,161,0,1,0,87,0,53,0,81,0,82,0, + 88,0,100,0,83,0,41,4,78,250,31,99,97,110,110,111, + 116,32,114,101,108,101,97,115,101,32,117,110,45,97,99,113, + 117,105,114,101,100,32,108,111,99,107,114,22,0,0,0,114, + 37,0,0,0,41,10,114,23,0,0,0,114,32,0,0,0, + 114,24,0,0,0,114,26,0,0,0,218,12,82,117,110,116, + 105,109,101,69,114,114,111,114,114,27,0,0,0,218,14,65, + 115,115,101,114,116,105,111,110,69,114,114,111,114,114,28,0, + 0,0,114,25,0,0,0,114,39,0,0,0,114,40,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,39,0,0,0,103,0,0,0,115,22,0,0,0,0,1, + 8,1,8,1,10,1,8,1,14,1,14,1,10,1,6,1, + 6,1,14,1,122,19,95,77,111,100,117,108,101,76,111,99, + 107,46,114,101,108,101,97,115,101,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,5,0,0,0,67,0, + 0,0,115,18,0,0,0,100,1,160,0,124,0,106,1,116, + 2,124,0,131,1,161,2,83,0,41,2,78,122,23,95,77, + 111,100,117,108,101,76,111,99,107,40,123,33,114,125,41,32, + 97,116,32,123,125,169,3,218,6,102,111,114,109,97,116,114, + 17,0,0,0,218,2,105,100,169,1,114,30,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, + 95,95,114,101,112,114,95,95,116,0,0,0,115,2,0,0, + 0,0,1,122,20,95,77,111,100,117,108,101,76,111,99,107, + 46,95,95,114,101,112,114,95,95,78,41,9,114,1,0,0, + 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, + 114,31,0,0,0,114,36,0,0,0,114,38,0,0,0,114, + 39,0,0,0,114,48,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,20,0, + 0,0,52,0,0,0,115,12,0,0,0,8,1,4,5,8, + 8,8,12,8,25,8,13,114,20,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,64,0,0,0,115,48,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4, + 100,5,132,0,90,5,100,6,100,7,132,0,90,6,100,8, + 100,9,132,0,90,7,100,10,83,0,41,11,218,16,95,68, + 117,109,109,121,77,111,100,117,108,101,76,111,99,107,122,86, + 65,32,115,105,109,112,108,101,32,95,77,111,100,117,108,101, + 76,111,99,107,32,101,113,117,105,118,97,108,101,110,116,32, + 102,111,114,32,80,121,116,104,111,110,32,98,117,105,108,100, + 115,32,119,105,116,104,111,117,116,10,32,32,32,32,109,117, + 108,116,105,45,116,104,114,101,97,100,105,110,103,32,115,117, + 112,112,111,114,116,46,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 16,0,0,0,124,1,124,0,95,0,100,1,124,0,95,1, + 100,0,83,0,114,21,0,0,0,41,2,114,17,0,0,0, + 114,27,0,0,0,114,29,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,31,0,0,0,124,0, + 0,0,115,4,0,0,0,0,1,6,1,122,25,95,68,117, + 109,109,121,77,111,100,117,108,101,76,111,99,107,46,95,95, + 105,110,105,116,95,95,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 18,0,0,0,124,0,4,0,106,0,100,1,55,0,2,0, + 95,0,100,2,83,0,41,3,78,114,37,0,0,0,84,41, + 1,114,27,0,0,0,114,47,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,38,0,0,0,128, + 0,0,0,115,4,0,0,0,0,1,14,1,122,24,95,68, + 117,109,109,121,77,111,100,117,108,101,76,111,99,107,46,97, + 99,113,117,105,114,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 36,0,0,0,124,0,106,0,100,1,107,2,114,18,116,1, + 100,2,131,1,130,1,124,0,4,0,106,0,100,3,56,0, + 2,0,95,0,100,0,83,0,41,4,78,114,22,0,0,0, + 114,41,0,0,0,114,37,0,0,0,41,2,114,27,0,0, + 0,114,42,0,0,0,114,47,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,39,0,0,0,132, + 0,0,0,115,6,0,0,0,0,1,10,1,8,1,122,24, + 95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107, + 46,114,101,108,101,97,115,101,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,5,0,0,0,67,0,0, + 0,115,18,0,0,0,100,1,160,0,124,0,106,1,116,2, + 124,0,131,1,161,2,83,0,41,2,78,122,28,95,68,117, + 109,109,121,77,111,100,117,108,101,76,111,99,107,40,123,33, + 114,125,41,32,97,116,32,123,125,114,44,0,0,0,114,47, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,48,0,0,0,137,0,0,0,115,2,0,0,0, + 0,1,122,25,95,68,117,109,109,121,77,111,100,117,108,101, + 76,111,99,107,46,95,95,114,101,112,114,95,95,78,41,8, + 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, + 3,0,0,0,114,31,0,0,0,114,38,0,0,0,114,39, + 0,0,0,114,48,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,49,0,0, + 0,120,0,0,0,115,10,0,0,0,8,1,4,3,8,4, + 8,4,8,5,114,49,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, + 0,0,115,36,0,0,0,101,0,90,1,100,0,90,2,100, + 1,100,2,132,0,90,3,100,3,100,4,132,0,90,4,100, + 5,100,6,132,0,90,5,100,7,83,0,41,8,218,18,95, + 77,111,100,117,108,101,76,111,99,107,77,97,110,97,103,101, + 114,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124, + 1,124,0,95,0,100,0,124,0,95,1,100,0,83,0,114, + 13,0,0,0,41,2,218,5,95,110,97,109,101,218,5,95, + 108,111,99,107,114,29,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,31,0,0,0,143,0,0, + 0,115,4,0,0,0,0,1,6,1,122,27,95,77,111,100, + 117,108,101,76,111,99,107,77,97,110,97,103,101,114,46,95, + 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0, + 115,26,0,0,0,116,0,124,0,106,1,131,1,124,0,95, + 2,124,0,106,2,160,3,161,0,1,0,100,0,83,0,114, + 13,0,0,0,41,4,218,16,95,103,101,116,95,109,111,100, + 117,108,101,95,108,111,99,107,114,51,0,0,0,114,52,0, + 0,0,114,38,0,0,0,114,47,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,9,95,95,101, + 110,116,101,114,95,95,147,0,0,0,115,4,0,0,0,0, + 1,12,1,122,28,95,77,111,100,117,108,101,76,111,99,107, + 77,97,110,97,103,101,114,46,95,95,101,110,116,101,114,95, + 95,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,2,0,0,0,79,0,0,0,115,14,0,0,0,124, + 0,106,0,160,1,161,0,1,0,100,0,83,0,114,13,0, + 0,0,41,2,114,52,0,0,0,114,39,0,0,0,41,3, + 114,30,0,0,0,218,4,97,114,103,115,90,6,107,119,97, + 114,103,115,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,8,95,95,101,120,105,116,95,95,151,0,0,0, + 115,2,0,0,0,0,1,122,27,95,77,111,100,117,108,101, + 76,111,99,107,77,97,110,97,103,101,114,46,95,95,101,120, + 105,116,95,95,78,41,6,114,1,0,0,0,114,0,0,0, + 0,114,2,0,0,0,114,31,0,0,0,114,54,0,0,0, + 114,56,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,50,0,0,0,141,0, + 0,0,115,6,0,0,0,8,2,8,4,8,4,114,50,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,8,0,0,0,67,0,0,0,115,130,0,0,0, + 116,0,160,1,161,0,1,0,122,106,122,14,116,3,124,0, + 25,0,131,0,125,1,87,0,110,24,4,0,116,4,107,10, + 114,48,1,0,1,0,1,0,100,1,125,1,89,0,110,2, + 88,0,124,1,100,1,107,8,114,112,116,5,100,1,107,8, + 114,76,116,6,124,0,131,1,125,1,110,8,116,7,124,0, + 131,1,125,1,124,0,102,1,100,2,100,3,132,1,125,2, + 116,8,160,9,124,1,124,2,161,2,116,3,124,0,60,0, + 87,0,53,0,116,0,160,2,161,0,1,0,88,0,124,1, + 83,0,41,4,122,139,71,101,116,32,111,114,32,99,114,101, + 97,116,101,32,116,104,101,32,109,111,100,117,108,101,32,108, + 111,99,107,32,102,111,114,32,97,32,103,105,118,101,110,32, + 109,111,100,117,108,101,32,110,97,109,101,46,10,10,32,32, + 32,32,65,99,113,117,105,114,101,47,114,101,108,101,97,115, + 101,32,105,110,116,101,114,110,97,108,108,121,32,116,104,101, + 32,103,108,111,98,97,108,32,105,109,112,111,114,116,32,108, + 111,99,107,32,116,111,32,112,114,111,116,101,99,116,10,32, + 32,32,32,95,109,111,100,117,108,101,95,108,111,99,107,115, + 46,78,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,8,0,0,0,83,0,0,0,115,48,0,0,0, + 116,0,160,1,161,0,1,0,122,24,116,3,160,4,124,1, + 161,1,124,0,107,8,114,30,116,3,124,1,61,0,87,0, + 53,0,116,0,160,2,161,0,1,0,88,0,100,0,83,0, + 114,13,0,0,0,41,5,218,4,95,105,109,112,218,12,97, + 99,113,117,105,114,101,95,108,111,99,107,218,12,114,101,108, + 101,97,115,101,95,108,111,99,107,218,13,95,109,111,100,117, + 108,101,95,108,111,99,107,115,114,34,0,0,0,41,2,218, + 3,114,101,102,114,17,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,2,99,98,176,0,0,0, + 115,10,0,0,0,0,1,8,1,2,4,14,1,10,2,122, + 28,95,103,101,116,95,109,111,100,117,108,101,95,108,111,99, + 107,46,60,108,111,99,97,108,115,62,46,99,98,41,10,114, + 57,0,0,0,114,58,0,0,0,114,59,0,0,0,114,60, + 0,0,0,218,8,75,101,121,69,114,114,111,114,114,23,0, + 0,0,114,49,0,0,0,114,20,0,0,0,218,8,95,119, + 101,97,107,114,101,102,114,61,0,0,0,41,3,114,17,0, + 0,0,114,24,0,0,0,114,62,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,53,0,0,0, + 157,0,0,0,115,28,0,0,0,0,6,8,1,2,1,2, + 1,14,1,14,1,10,2,8,1,8,1,10,2,8,2,12, + 11,20,2,10,2,114,53,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,8,0,0,0,67, + 0,0,0,115,54,0,0,0,116,0,124,0,131,1,125,1, + 122,12,124,1,160,1,161,0,1,0,87,0,110,20,4,0, + 116,2,107,10,114,40,1,0,1,0,1,0,89,0,110,10, + 88,0,124,1,160,3,161,0,1,0,100,1,83,0,41,2, + 122,189,65,99,113,117,105,114,101,115,32,116,104,101,110,32, + 114,101,108,101,97,115,101,115,32,116,104,101,32,109,111,100, + 117,108,101,32,108,111,99,107,32,102,111,114,32,97,32,103, + 105,118,101,110,32,109,111,100,117,108,101,32,110,97,109,101, + 46,10,10,32,32,32,32,84,104,105,115,32,105,115,32,117, + 115,101,100,32,116,111,32,101,110,115,117,114,101,32,97,32, + 109,111,100,117,108,101,32,105,115,32,99,111,109,112,108,101, + 116,101,108,121,32,105,110,105,116,105,97,108,105,122,101,100, + 44,32,105,110,32,116,104,101,10,32,32,32,32,101,118,101, + 110,116,32,105,116,32,105,115,32,98,101,105,110,103,32,105, + 109,112,111,114,116,101,100,32,98,121,32,97,110,111,116,104, + 101,114,32,116,104,114,101,97,100,46,10,32,32,32,32,78, + 41,4,114,53,0,0,0,114,38,0,0,0,114,19,0,0, + 0,114,39,0,0,0,41,2,114,17,0,0,0,114,24,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,19,95,108,111,99,107,95,117,110,108,111,99,107,95, + 109,111,100,117,108,101,194,0,0,0,115,12,0,0,0,0, + 6,8,1,2,1,12,1,14,3,6,2,114,65,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,3,0,0,0,79,0,0,0,115,10,0,0,0,124,0, + 124,1,124,2,142,1,83,0,41,1,97,46,1,0,0,114, + 101,109,111,118,101,95,105,109,112,111,114,116,108,105,98,95, + 102,114,97,109,101,115,32,105,110,32,105,109,112,111,114,116, + 46,99,32,119,105,108,108,32,97,108,119,97,121,115,32,114, + 101,109,111,118,101,32,115,101,113,117,101,110,99,101,115,10, + 32,32,32,32,111,102,32,105,109,112,111,114,116,108,105,98, + 32,102,114,97,109,101,115,32,116,104,97,116,32,101,110,100, + 32,119,105,116,104,32,97,32,99,97,108,108,32,116,111,32, + 116,104,105,115,32,102,117,110,99,116,105,111,110,10,10,32, + 32,32,32,85,115,101,32,105,116,32,105,110,115,116,101,97, + 100,32,111,102,32,97,32,110,111,114,109,97,108,32,99,97, + 108,108,32,105,110,32,112,108,97,99,101,115,32,119,104,101, + 114,101,32,105,110,99,108,117,100,105,110,103,32,116,104,101, + 32,105,109,112,111,114,116,108,105,98,10,32,32,32,32,102, + 114,97,109,101,115,32,105,110,116,114,111,100,117,99,101,115, + 32,117,110,119,97,110,116,101,100,32,110,111,105,115,101,32, + 105,110,116,111,32,116,104,101,32,116,114,97,99,101,98,97, + 99,107,32,40,101,46,103,46,32,119,104,101,110,32,101,120, + 101,99,117,116,105,110,103,10,32,32,32,32,109,111,100,117, + 108,101,32,99,111,100,101,41,10,32,32,32,32,114,10,0, + 0,0,41,3,218,1,102,114,55,0,0,0,90,4,107,119, + 100,115,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,25,95,99,97,108,108,95,119,105,116,104,95,102,114, + 97,109,101,115,95,114,101,109,111,118,101,100,211,0,0,0, + 115,2,0,0,0,0,8,114,67,0,0,0,114,37,0,0, + 0,41,1,218,9,118,101,114,98,111,115,105,116,121,99,1, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,4, + 0,0,0,71,0,0,0,115,54,0,0,0,116,0,106,1, + 106,2,124,1,107,5,114,50,124,0,160,3,100,1,161,1, + 115,30,100,2,124,0,23,0,125,0,116,4,124,0,106,5, + 124,2,142,0,116,0,106,6,100,3,141,2,1,0,100,4, + 83,0,41,5,122,61,80,114,105,110,116,32,116,104,101,32, + 109,101,115,115,97,103,101,32,116,111,32,115,116,100,101,114, + 114,32,105,102,32,45,118,47,80,89,84,72,79,78,86,69, + 82,66,79,83,69,32,105,115,32,116,117,114,110,101,100,32, + 111,110,46,41,2,250,1,35,122,7,105,109,112,111,114,116, + 32,122,2,35,32,41,1,90,4,102,105,108,101,78,41,7, + 114,15,0,0,0,218,5,102,108,97,103,115,218,7,118,101, + 114,98,111,115,101,218,10,115,116,97,114,116,115,119,105,116, + 104,218,5,112,114,105,110,116,114,45,0,0,0,218,6,115, + 116,100,101,114,114,41,3,218,7,109,101,115,115,97,103,101, + 114,68,0,0,0,114,55,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,16,95,118,101,114,98, + 111,115,101,95,109,101,115,115,97,103,101,222,0,0,0,115, + 8,0,0,0,0,2,12,1,10,1,8,1,114,76,0,0, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,3,0,0,0,115,26,0,0,0,135, + 0,102,1,100,1,100,2,132,8,125,1,116,0,124,1,136, + 0,131,2,1,0,124,1,83,0,41,3,122,49,68,101,99, + 111,114,97,116,111,114,32,116,111,32,118,101,114,105,102,121, + 32,116,104,101,32,110,97,109,101,100,32,109,111,100,117,108, + 101,32,105,115,32,98,117,105,108,116,45,105,110,46,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,19,0,0,0,115,38,0,0,0,124,1,116,0, + 106,1,107,7,114,28,116,2,100,1,160,3,124,1,161,1, + 124,1,100,2,141,2,130,1,136,0,124,0,124,1,131,2, + 83,0,41,3,78,250,29,123,33,114,125,32,105,115,32,110, + 111,116,32,97,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,114,16,0,0,0,41,4,114,15,0,0,0, + 218,20,98,117,105,108,116,105,110,95,109,111,100,117,108,101, + 95,110,97,109,101,115,218,11,73,109,112,111,114,116,69,114, + 114,111,114,114,45,0,0,0,169,2,114,30,0,0,0,218, + 8,102,117,108,108,110,97,109,101,169,1,218,3,102,120,110, + 114,10,0,0,0,114,11,0,0,0,218,25,95,114,101,113, + 117,105,114,101,115,95,98,117,105,108,116,105,110,95,119,114, + 97,112,112,101,114,232,0,0,0,115,10,0,0,0,0,1, + 10,1,10,1,2,255,6,2,122,52,95,114,101,113,117,105, + 114,101,115,95,98,117,105,108,116,105,110,46,60,108,111,99, + 97,108,115,62,46,95,114,101,113,117,105,114,101,115,95,98, + 117,105,108,116,105,110,95,119,114,97,112,112,101,114,169,1, + 114,12,0,0,0,41,2,114,83,0,0,0,114,84,0,0, + 0,114,10,0,0,0,114,82,0,0,0,114,11,0,0,0, + 218,17,95,114,101,113,117,105,114,101,115,95,98,117,105,108, + 116,105,110,230,0,0,0,115,6,0,0,0,0,2,12,5, + 10,1,114,86,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0, + 115,26,0,0,0,135,0,102,1,100,1,100,2,132,8,125, + 1,116,0,124,1,136,0,131,2,1,0,124,1,83,0,41, + 3,122,47,68,101,99,111,114,97,116,111,114,32,116,111,32, + 118,101,114,105,102,121,32,116,104,101,32,110,97,109,101,100, + 32,109,111,100,117,108,101,32,105,115,32,102,114,111,122,101, + 110,46,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,19,0,0,0,115,38,0,0,0, + 116,0,160,1,124,1,161,1,115,28,116,2,100,1,160,3, + 124,1,161,1,124,1,100,2,141,2,130,1,136,0,124,0, + 124,1,131,2,83,0,169,3,78,122,27,123,33,114,125,32, + 105,115,32,110,111,116,32,97,32,102,114,111,122,101,110,32, + 109,111,100,117,108,101,114,16,0,0,0,41,4,114,57,0, + 0,0,218,9,105,115,95,102,114,111,122,101,110,114,79,0, + 0,0,114,45,0,0,0,114,80,0,0,0,114,82,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,24,95,114,101, + 113,117,105,114,101,115,95,102,114,111,122,101,110,95,119,114, + 97,112,112,101,114,243,0,0,0,115,10,0,0,0,0,1, + 10,1,10,1,2,255,6,2,122,50,95,114,101,113,117,105, + 114,101,115,95,102,114,111,122,101,110,46,60,108,111,99,97, + 108,115,62,46,95,114,101,113,117,105,114,101,115,95,102,114, + 111,122,101,110,95,119,114,97,112,112,101,114,114,85,0,0, + 0,41,2,114,83,0,0,0,114,89,0,0,0,114,10,0, + 0,0,114,82,0,0,0,114,11,0,0,0,218,16,95,114, + 101,113,117,105,114,101,115,95,102,114,111,122,101,110,241,0, + 0,0,115,6,0,0,0,0,2,12,5,10,1,114,90,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,3,0,0,0,67,0,0,0,115,62,0,0,0, + 116,0,124,1,124,0,131,2,125,2,124,1,116,1,106,2, + 107,6,114,50,116,1,106,2,124,1,25,0,125,3,116,3, + 124,2,124,3,131,2,1,0,116,1,106,2,124,1,25,0, + 83,0,116,4,124,2,131,1,83,0,100,1,83,0,41,2, + 122,128,76,111,97,100,32,116,104,101,32,115,112,101,99,105, + 102,105,101,100,32,109,111,100,117,108,101,32,105,110,116,111, + 32,115,121,115,46,109,111,100,117,108,101,115,32,97,110,100, + 32,114,101,116,117,114,110,32,105,116,46,10,10,32,32,32, + 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, + 32,108,111,97,100,101,114,46,101,120,101,99,95,109,111,100, + 117,108,101,32,105,110,115,116,101,97,100,46,10,10,32,32, + 32,32,78,41,5,218,16,115,112,101,99,95,102,114,111,109, + 95,108,111,97,100,101,114,114,15,0,0,0,218,7,109,111, + 100,117,108,101,115,218,5,95,101,120,101,99,218,5,95,108, + 111,97,100,41,4,114,30,0,0,0,114,81,0,0,0,218, + 4,115,112,101,99,218,6,109,111,100,117,108,101,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,17,95,108, + 111,97,100,95,109,111,100,117,108,101,95,115,104,105,109,253, + 0,0,0,115,12,0,0,0,0,6,10,1,10,1,10,1, + 10,1,10,2,114,97,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,8,0,0,0,67,0, + 0,0,115,226,0,0,0,116,0,124,0,100,1,100,0,131, + 3,125,1,116,1,124,1,100,2,131,2,114,56,122,12,124, + 1,160,2,124,0,161,1,87,0,83,0,4,0,116,3,107, + 10,114,54,1,0,1,0,1,0,89,0,110,2,88,0,122, + 10,124,0,106,4,125,2,87,0,110,20,4,0,116,5,107, + 10,114,86,1,0,1,0,1,0,89,0,110,18,88,0,124, + 2,100,0,107,9,114,104,116,6,124,2,131,1,83,0,122, + 10,124,0,106,7,125,3,87,0,110,24,4,0,116,5,107, + 10,114,138,1,0,1,0,1,0,100,3,125,3,89,0,110, + 2,88,0,122,10,124,0,106,8,125,4,87,0,110,58,4, + 0,116,5,107,10,114,208,1,0,1,0,1,0,124,1,100, + 0,107,8,114,188,100,4,160,9,124,3,161,1,6,0,89, + 0,83,0,100,5,160,9,124,3,124,1,161,2,6,0,89, + 0,83,0,89,0,110,14,88,0,100,6,160,9,124,3,124, + 4,161,2,83,0,100,0,83,0,41,7,78,218,10,95,95, + 108,111,97,100,101,114,95,95,218,11,109,111,100,117,108,101, + 95,114,101,112,114,250,1,63,250,13,60,109,111,100,117,108, + 101,32,123,33,114,125,62,250,20,60,109,111,100,117,108,101, + 32,123,33,114,125,32,40,123,33,114,125,41,62,250,23,60, + 109,111,100,117,108,101,32,123,33,114,125,32,102,114,111,109, + 32,123,33,114,125,62,41,10,114,6,0,0,0,114,4,0, + 0,0,114,99,0,0,0,218,9,69,120,99,101,112,116,105, + 111,110,218,8,95,95,115,112,101,99,95,95,218,14,65,116, + 116,114,105,98,117,116,101,69,114,114,111,114,218,22,95,109, + 111,100,117,108,101,95,114,101,112,114,95,102,114,111,109,95, + 115,112,101,99,114,1,0,0,0,218,8,95,95,102,105,108, + 101,95,95,114,45,0,0,0,41,5,114,96,0,0,0,218, + 6,108,111,97,100,101,114,114,95,0,0,0,114,17,0,0, + 0,218,8,102,105,108,101,110,97,109,101,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,12,95,109,111,100, + 117,108,101,95,114,101,112,114,13,1,0,0,115,46,0,0, + 0,0,2,12,1,10,4,2,1,12,1,14,1,6,1,2, + 1,10,1,14,1,6,2,8,1,8,4,2,1,10,1,14, + 1,10,1,2,1,10,1,14,1,8,1,14,2,22,2,114, + 111,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,64,0,0,0,115,114,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,2,100,2,100,3,156,3,100,4,100,5,132,2,90,4, + 100,6,100,7,132,0,90,5,100,8,100,9,132,0,90,6, + 101,7,100,10,100,11,132,0,131,1,90,8,101,8,106,9, + 100,12,100,11,132,0,131,1,90,8,101,7,100,13,100,14, + 132,0,131,1,90,10,101,7,100,15,100,16,132,0,131,1, + 90,11,101,11,106,9,100,17,100,16,132,0,131,1,90,11, + 100,2,83,0,41,18,218,10,77,111,100,117,108,101,83,112, + 101,99,97,208,5,0,0,84,104,101,32,115,112,101,99,105, + 102,105,99,97,116,105,111,110,32,102,111,114,32,97,32,109, + 111,100,117,108,101,44,32,117,115,101,100,32,102,111,114,32, + 108,111,97,100,105,110,103,46,10,10,32,32,32,32,65,32, + 109,111,100,117,108,101,39,115,32,115,112,101,99,32,105,115, + 32,116,104,101,32,115,111,117,114,99,101,32,102,111,114,32, + 105,110,102,111,114,109,97,116,105,111,110,32,97,98,111,117, + 116,32,116,104,101,32,109,111,100,117,108,101,46,32,32,70, + 111,114,10,32,32,32,32,100,97,116,97,32,97,115,115,111, + 99,105,97,116,101,100,32,119,105,116,104,32,116,104,101,32, + 109,111,100,117,108,101,44,32,105,110,99,108,117,100,105,110, + 103,32,115,111,117,114,99,101,44,32,117,115,101,32,116,104, + 101,32,115,112,101,99,39,115,10,32,32,32,32,108,111,97, + 100,101,114,46,10,10,32,32,32,32,96,110,97,109,101,96, + 32,105,115,32,116,104,101,32,97,98,115,111,108,117,116,101, + 32,110,97,109,101,32,111,102,32,116,104,101,32,109,111,100, + 117,108,101,46,32,32,96,108,111,97,100,101,114,96,32,105, + 115,32,116,104,101,32,108,111,97,100,101,114,10,32,32,32, + 32,116,111,32,117,115,101,32,119,104,101,110,32,108,111,97, + 100,105,110,103,32,116,104,101,32,109,111,100,117,108,101,46, + 32,32,96,112,97,114,101,110,116,96,32,105,115,32,116,104, + 101,32,110,97,109,101,32,111,102,32,116,104,101,10,32,32, + 32,32,112,97,99,107,97,103,101,32,116,104,101,32,109,111, + 100,117,108,101,32,105,115,32,105,110,46,32,32,84,104,101, + 32,112,97,114,101,110,116,32,105,115,32,100,101,114,105,118, + 101,100,32,102,114,111,109,32,116,104,101,32,110,97,109,101, + 46,10,10,32,32,32,32,96,105,115,95,112,97,99,107,97, + 103,101,96,32,100,101,116,101,114,109,105,110,101,115,32,105, + 102,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, + 99,111,110,115,105,100,101,114,101,100,32,97,32,112,97,99, + 107,97,103,101,32,111,114,10,32,32,32,32,110,111,116,46, + 32,32,79,110,32,109,111,100,117,108,101,115,32,116,104,105, + 115,32,105,115,32,114,101,102,108,101,99,116,101,100,32,98, + 121,32,116,104,101,32,96,95,95,112,97,116,104,95,95,96, + 32,97,116,116,114,105,98,117,116,101,46,10,10,32,32,32, + 32,96,111,114,105,103,105,110,96,32,105,115,32,116,104,101, + 32,115,112,101,99,105,102,105,99,32,108,111,99,97,116,105, + 111,110,32,117,115,101,100,32,98,121,32,116,104,101,32,108, + 111,97,100,101,114,32,102,114,111,109,32,119,104,105,99,104, + 32,116,111,10,32,32,32,32,108,111,97,100,32,116,104,101, + 32,109,111,100,117,108,101,44,32,105,102,32,116,104,97,116, + 32,105,110,102,111,114,109,97,116,105,111,110,32,105,115,32, + 97,118,97,105,108,97,98,108,101,46,32,32,87,104,101,110, + 32,102,105,108,101,110,97,109,101,32,105,115,10,32,32,32, + 32,115,101,116,44,32,111,114,105,103,105,110,32,119,105,108, + 108,32,109,97,116,99,104,46,10,10,32,32,32,32,96,104, + 97,115,95,108,111,99,97,116,105,111,110,96,32,105,110,100, + 105,99,97,116,101,115,32,116,104,97,116,32,97,32,115,112, + 101,99,39,115,32,34,111,114,105,103,105,110,34,32,114,101, + 102,108,101,99,116,115,32,97,32,108,111,99,97,116,105,111, + 110,46,10,32,32,32,32,87,104,101,110,32,116,104,105,115, + 32,105,115,32,84,114,117,101,44,32,96,95,95,102,105,108, + 101,95,95,96,32,97,116,116,114,105,98,117,116,101,32,111, + 102,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, + 115,101,116,46,10,10,32,32,32,32,96,99,97,99,104,101, + 100,96,32,105,115,32,116,104,101,32,108,111,99,97,116,105, + 111,110,32,111,102,32,116,104,101,32,99,97,99,104,101,100, + 32,98,121,116,101,99,111,100,101,32,102,105,108,101,44,32, + 105,102,32,97,110,121,46,32,32,73,116,10,32,32,32,32, + 99,111,114,114,101,115,112,111,110,100,115,32,116,111,32,116, + 104,101,32,96,95,95,99,97,99,104,101,100,95,95,96,32, + 97,116,116,114,105,98,117,116,101,46,10,10,32,32,32,32, + 96,115,117,98,109,111,100,117,108,101,95,115,101,97,114,99, + 104,95,108,111,99,97,116,105,111,110,115,96,32,105,115,32, + 116,104,101,32,115,101,113,117,101,110,99,101,32,111,102,32, + 112,97,116,104,32,101,110,116,114,105,101,115,32,116,111,10, + 32,32,32,32,115,101,97,114,99,104,32,119,104,101,110,32, + 105,109,112,111,114,116,105,110,103,32,115,117,98,109,111,100, + 117,108,101,115,46,32,32,73,102,32,115,101,116,44,32,105, + 115,95,112,97,99,107,97,103,101,32,115,104,111,117,108,100, + 32,98,101,10,32,32,32,32,84,114,117,101,45,45,97,110, + 100,32,70,97,108,115,101,32,111,116,104,101,114,119,105,115, + 101,46,10,10,32,32,32,32,80,97,99,107,97,103,101,115, + 32,97,114,101,32,115,105,109,112,108,121,32,109,111,100,117, + 108,101,115,32,116,104,97,116,32,40,109,97,121,41,32,104, + 97,118,101,32,115,117,98,109,111,100,117,108,101,115,46,32, + 32,73,102,32,97,32,115,112,101,99,10,32,32,32,32,104, + 97,115,32,97,32,110,111,110,45,78,111,110,101,32,118,97, + 108,117,101,32,105,110,32,96,115,117,98,109,111,100,117,108, + 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, + 110,115,96,44,32,116,104,101,32,105,109,112,111,114,116,10, + 32,32,32,32,115,121,115,116,101,109,32,119,105,108,108,32, + 99,111,110,115,105,100,101,114,32,109,111,100,117,108,101,115, + 32,108,111,97,100,101,100,32,102,114,111,109,32,116,104,101, + 32,115,112,101,99,32,97,115,32,112,97,99,107,97,103,101, + 115,46,10,10,32,32,32,32,79,110,108,121,32,102,105,110, + 100,101,114,115,32,40,115,101,101,32,105,109,112,111,114,116, + 108,105,98,46,97,98,99,46,77,101,116,97,80,97,116,104, + 70,105,110,100,101,114,32,97,110,100,10,32,32,32,32,105, + 109,112,111,114,116,108,105,98,46,97,98,99,46,80,97,116, + 104,69,110,116,114,121,70,105,110,100,101,114,41,32,115,104, + 111,117,108,100,32,109,111,100,105,102,121,32,77,111,100,117, + 108,101,83,112,101,99,32,105,110,115,116,97,110,99,101,115, + 46,10,10,32,32,32,32,78,41,3,218,6,111,114,105,103, + 105,110,218,12,108,111,97,100,101,114,95,115,116,97,116,101, + 218,10,105,115,95,112,97,99,107,97,103,101,99,3,0,0, + 0,0,0,0,0,3,0,0,0,6,0,0,0,2,0,0, + 0,67,0,0,0,115,54,0,0,0,124,1,124,0,95,0, + 124,2,124,0,95,1,124,3,124,0,95,2,124,4,124,0, + 95,3,124,5,114,32,103,0,110,2,100,0,124,0,95,4, + 100,1,124,0,95,5,100,0,124,0,95,6,100,0,83,0, + 169,2,78,70,41,7,114,17,0,0,0,114,109,0,0,0, + 114,113,0,0,0,114,114,0,0,0,218,26,115,117,98,109, + 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, + 97,116,105,111,110,115,218,13,95,115,101,116,95,102,105,108, + 101,97,116,116,114,218,7,95,99,97,99,104,101,100,41,6, + 114,30,0,0,0,114,17,0,0,0,114,109,0,0,0,114, + 113,0,0,0,114,114,0,0,0,114,115,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,31,0, + 0,0,86,1,0,0,115,14,0,0,0,0,2,6,1,6, + 1,6,1,6,1,14,3,6,1,122,19,77,111,100,117,108, + 101,83,112,101,99,46,95,95,105,110,105,116,95,95,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,6, + 0,0,0,67,0,0,0,115,102,0,0,0,100,1,160,0, + 124,0,106,1,161,1,100,2,160,0,124,0,106,2,161,1, + 103,2,125,1,124,0,106,3,100,0,107,9,114,52,124,1, + 160,4,100,3,160,0,124,0,106,3,161,1,161,1,1,0, + 124,0,106,5,100,0,107,9,114,80,124,1,160,4,100,4, + 160,0,124,0,106,5,161,1,161,1,1,0,100,5,160,0, + 124,0,106,6,106,7,100,6,160,8,124,1,161,1,161,2, + 83,0,41,7,78,122,9,110,97,109,101,61,123,33,114,125, + 122,11,108,111,97,100,101,114,61,123,33,114,125,122,11,111, + 114,105,103,105,110,61,123,33,114,125,122,29,115,117,98,109, + 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, + 97,116,105,111,110,115,61,123,125,122,6,123,125,40,123,125, + 41,122,2,44,32,41,9,114,45,0,0,0,114,17,0,0, + 0,114,109,0,0,0,114,113,0,0,0,218,6,97,112,112, + 101,110,100,114,117,0,0,0,218,9,95,95,99,108,97,115, + 115,95,95,114,1,0,0,0,218,4,106,111,105,110,41,2, + 114,30,0,0,0,114,55,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,48,0,0,0,98,1, + 0,0,115,20,0,0,0,0,1,10,1,10,255,4,2,10, + 1,18,1,10,1,8,1,4,255,6,2,122,19,77,111,100, + 117,108,101,83,112,101,99,46,95,95,114,101,112,114,95,95, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,106,0,0,0,124,0, + 106,0,125,2,122,72,124,0,106,1,124,1,106,1,107,2, + 111,76,124,0,106,2,124,1,106,2,107,2,111,76,124,0, + 106,3,124,1,106,3,107,2,111,76,124,2,124,1,106,0, + 107,2,111,76,124,0,106,4,124,1,106,4,107,2,111,76, + 124,0,106,5,124,1,106,5,107,2,87,0,83,0,4,0, + 116,6,107,10,114,100,1,0,1,0,1,0,89,0,100,1, + 83,0,88,0,100,0,83,0,114,116,0,0,0,41,7,114, + 117,0,0,0,114,17,0,0,0,114,109,0,0,0,114,113, + 0,0,0,218,6,99,97,99,104,101,100,218,12,104,97,115, + 95,108,111,99,97,116,105,111,110,114,106,0,0,0,41,3, + 114,30,0,0,0,90,5,111,116,104,101,114,90,4,115,109, + 115,108,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,6,95,95,101,113,95,95,108,1,0,0,115,30,0, + 0,0,0,1,6,1,2,1,12,1,10,255,2,2,10,254, + 2,3,8,253,2,4,10,252,2,5,10,251,4,6,14,1, + 122,17,77,111,100,117,108,101,83,112,101,99,46,95,95,101, + 113,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,67,0,0,0,115,58,0,0, + 0,124,0,106,0,100,0,107,8,114,52,124,0,106,1,100, + 0,107,9,114,52,124,0,106,2,114,52,116,3,100,0,107, + 8,114,38,116,4,130,1,116,3,160,5,124,0,106,1,161, + 1,124,0,95,0,124,0,106,0,83,0,114,13,0,0,0, + 41,6,114,119,0,0,0,114,113,0,0,0,114,118,0,0, + 0,218,19,95,98,111,111,116,115,116,114,97,112,95,101,120, + 116,101,114,110,97,108,218,19,78,111,116,73,109,112,108,101, + 109,101,110,116,101,100,69,114,114,111,114,90,11,95,103,101, + 116,95,99,97,99,104,101,100,114,47,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,123,0,0, + 0,120,1,0,0,115,12,0,0,0,0,2,10,1,16,1, + 8,1,4,1,14,1,122,17,77,111,100,117,108,101,83,112, + 101,99,46,99,97,99,104,101,100,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, + 0,0,115,10,0,0,0,124,1,124,0,95,0,100,0,83, + 0,114,13,0,0,0,41,1,114,119,0,0,0,41,2,114, + 30,0,0,0,114,123,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,123,0,0,0,129,1,0, + 0,115,2,0,0,0,0,2,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, + 0,115,36,0,0,0,124,0,106,0,100,1,107,8,114,26, + 124,0,106,1,160,2,100,2,161,1,100,3,25,0,83,0, + 124,0,106,1,83,0,100,1,83,0,41,4,122,32,84,104, + 101,32,110,97,109,101,32,111,102,32,116,104,101,32,109,111, + 100,117,108,101,39,115,32,112,97,114,101,110,116,46,78,218, + 1,46,114,22,0,0,0,41,3,114,117,0,0,0,114,17, + 0,0,0,218,10,114,112,97,114,116,105,116,105,111,110,114, + 47,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,6,112,97,114,101,110,116,133,1,0,0,115, + 6,0,0,0,0,3,10,1,16,2,122,17,77,111,100,117, + 108,101,83,112,101,99,46,112,97,114,101,110,116,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0, + 0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,83, + 0,114,13,0,0,0,41,1,114,118,0,0,0,114,47,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,124,0,0,0,141,1,0,0,115,2,0,0,0,0, + 2,122,23,77,111,100,117,108,101,83,112,101,99,46,104,97, + 115,95,108,111,99,97,116,105,111,110,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, + 0,0,0,115,14,0,0,0,116,0,124,1,131,1,124,0, + 95,1,100,0,83,0,114,13,0,0,0,41,2,218,4,98, + 111,111,108,114,118,0,0,0,41,2,114,30,0,0,0,218, + 5,118,97,108,117,101,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,124,0,0,0,145,1,0,0,115,2, + 0,0,0,0,2,41,12,114,1,0,0,0,114,0,0,0, + 0,114,2,0,0,0,114,3,0,0,0,114,31,0,0,0, + 114,48,0,0,0,114,125,0,0,0,218,8,112,114,111,112, + 101,114,116,121,114,123,0,0,0,218,6,115,101,116,116,101, + 114,114,130,0,0,0,114,124,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 112,0,0,0,49,1,0,0,115,32,0,0,0,8,1,4, + 36,4,1,2,255,12,12,8,10,8,12,2,1,10,8,4, + 1,10,3,2,1,10,7,2,1,10,3,4,1,114,112,0, + 0,0,169,2,114,113,0,0,0,114,115,0,0,0,99,2, + 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,8, + 0,0,0,67,0,0,0,115,154,0,0,0,116,0,124,1, + 100,1,131,2,114,74,116,1,100,2,107,8,114,22,116,2, + 130,1,116,1,106,3,125,4,124,3,100,2,107,8,114,48, + 124,4,124,0,124,1,100,3,141,2,83,0,124,3,114,56, + 103,0,110,2,100,2,125,5,124,4,124,0,124,1,124,5, + 100,4,141,3,83,0,124,3,100,2,107,8,114,138,116,0, + 124,1,100,5,131,2,114,134,122,14,124,1,160,4,124,0, + 161,1,125,3,87,0,113,138,4,0,116,5,107,10,114,130, + 1,0,1,0,1,0,100,2,125,3,89,0,113,138,88,0, + 110,4,100,6,125,3,116,6,124,0,124,1,124,2,124,3, + 100,7,141,4,83,0,41,8,122,53,82,101,116,117,114,110, + 32,97,32,109,111,100,117,108,101,32,115,112,101,99,32,98, + 97,115,101,100,32,111,110,32,118,97,114,105,111,117,115,32, + 108,111,97,100,101,114,32,109,101,116,104,111,100,115,46,90, + 12,103,101,116,95,102,105,108,101,110,97,109,101,78,41,1, + 114,109,0,0,0,41,2,114,109,0,0,0,114,117,0,0, + 0,114,115,0,0,0,70,114,135,0,0,0,41,7,114,4, + 0,0,0,114,126,0,0,0,114,127,0,0,0,218,23,115, + 112,101,99,95,102,114,111,109,95,102,105,108,101,95,108,111, + 99,97,116,105,111,110,114,115,0,0,0,114,79,0,0,0, + 114,112,0,0,0,41,6,114,17,0,0,0,114,109,0,0, + 0,114,113,0,0,0,114,115,0,0,0,114,136,0,0,0, + 90,6,115,101,97,114,99,104,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,91,0,0,0,150,1,0,0, + 115,36,0,0,0,0,2,10,1,8,1,4,1,6,2,8, + 1,12,1,12,1,6,1,2,255,6,3,8,1,10,1,2, + 1,14,1,14,1,12,3,4,2,114,91,0,0,0,99,3, + 0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8, + 0,0,0,67,0,0,0,115,56,1,0,0,122,10,124,0, + 106,0,125,3,87,0,110,20,4,0,116,1,107,10,114,30, + 1,0,1,0,1,0,89,0,110,14,88,0,124,3,100,0, + 107,9,114,44,124,3,83,0,124,0,106,2,125,4,124,1, + 100,0,107,8,114,90,122,10,124,0,106,3,125,1,87,0, + 110,20,4,0,116,1,107,10,114,88,1,0,1,0,1,0, + 89,0,110,2,88,0,122,10,124,0,106,4,125,5,87,0, + 110,24,4,0,116,1,107,10,114,124,1,0,1,0,1,0, + 100,0,125,5,89,0,110,2,88,0,124,2,100,0,107,8, + 114,184,124,5,100,0,107,8,114,180,122,10,124,1,106,5, + 125,2,87,0,113,184,4,0,116,1,107,10,114,176,1,0, + 1,0,1,0,100,0,125,2,89,0,113,184,88,0,110,4, + 124,5,125,2,122,10,124,0,106,6,125,6,87,0,110,24, + 4,0,116,1,107,10,114,218,1,0,1,0,1,0,100,0, + 125,6,89,0,110,2,88,0,122,14,116,7,124,0,106,8, + 131,1,125,7,87,0,110,26,4,0,116,1,107,10,144,1, + 114,4,1,0,1,0,1,0,100,0,125,7,89,0,110,2, + 88,0,116,9,124,4,124,1,124,2,100,1,141,3,125,3, + 124,5,100,0,107,8,144,1,114,34,100,2,110,2,100,3, + 124,3,95,10,124,6,124,3,95,11,124,7,124,3,95,12, + 124,3,83,0,41,4,78,169,1,114,113,0,0,0,70,84, + 41,13,114,105,0,0,0,114,106,0,0,0,114,1,0,0, + 0,114,98,0,0,0,114,108,0,0,0,218,7,95,79,82, + 73,71,73,78,218,10,95,95,99,97,99,104,101,100,95,95, + 218,4,108,105,115,116,218,8,95,95,112,97,116,104,95,95, + 114,112,0,0,0,114,118,0,0,0,114,123,0,0,0,114, + 117,0,0,0,41,8,114,96,0,0,0,114,109,0,0,0, + 114,113,0,0,0,114,95,0,0,0,114,17,0,0,0,90, + 8,108,111,99,97,116,105,111,110,114,123,0,0,0,114,117, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,17,95,115,112,101,99,95,102,114,111,109,95,109, + 111,100,117,108,101,176,1,0,0,115,72,0,0,0,0,2, + 2,1,10,1,14,1,6,2,8,1,4,2,6,1,8,1, + 2,1,10,1,14,2,6,1,2,1,10,1,14,1,10,1, + 8,1,8,1,2,1,10,1,14,1,12,2,4,1,2,1, + 10,1,14,1,10,1,2,1,14,1,16,1,10,2,14,1, + 20,1,6,1,6,1,114,142,0,0,0,70,169,1,218,8, + 111,118,101,114,114,105,100,101,99,2,0,0,0,0,0,0, + 0,1,0,0,0,5,0,0,0,8,0,0,0,67,0,0, + 0,115,226,1,0,0,124,2,115,20,116,0,124,1,100,1, + 100,0,131,3,100,0,107,8,114,54,122,12,124,0,106,1, + 124,1,95,2,87,0,110,20,4,0,116,3,107,10,114,52, + 1,0,1,0,1,0,89,0,110,2,88,0,124,2,115,74, + 116,0,124,1,100,2,100,0,131,3,100,0,107,8,114,178, + 124,0,106,4,125,3,124,3,100,0,107,8,114,146,124,0, + 106,5,100,0,107,9,114,146,116,6,100,0,107,8,114,110, + 116,7,130,1,116,6,106,8,125,4,124,4,160,9,124,4, + 161,1,125,3,124,0,106,5,124,3,95,10,124,3,124,0, + 95,4,100,0,124,1,95,11,122,10,124,3,124,1,95,12, + 87,0,110,20,4,0,116,3,107,10,114,176,1,0,1,0, + 1,0,89,0,110,2,88,0,124,2,115,198,116,0,124,1, + 100,3,100,0,131,3,100,0,107,8,114,232,122,12,124,0, + 106,13,124,1,95,14,87,0,110,20,4,0,116,3,107,10, + 114,230,1,0,1,0,1,0,89,0,110,2,88,0,122,10, + 124,0,124,1,95,15,87,0,110,22,4,0,116,3,107,10, + 144,1,114,8,1,0,1,0,1,0,89,0,110,2,88,0, + 124,2,144,1,115,34,116,0,124,1,100,4,100,0,131,3, + 100,0,107,8,144,1,114,82,124,0,106,5,100,0,107,9, + 144,1,114,82,122,12,124,0,106,5,124,1,95,16,87,0, + 110,22,4,0,116,3,107,10,144,1,114,80,1,0,1,0, + 1,0,89,0,110,2,88,0,124,0,106,17,144,1,114,222, + 124,2,144,1,115,114,116,0,124,1,100,5,100,0,131,3, + 100,0,107,8,144,1,114,150,122,12,124,0,106,18,124,1, + 95,11,87,0,110,22,4,0,116,3,107,10,144,1,114,148, + 1,0,1,0,1,0,89,0,110,2,88,0,124,2,144,1, + 115,174,116,0,124,1,100,6,100,0,131,3,100,0,107,8, + 144,1,114,222,124,0,106,19,100,0,107,9,144,1,114,222, + 122,12,124,0,106,19,124,1,95,20,87,0,110,22,4,0, + 116,3,107,10,144,1,114,220,1,0,1,0,1,0,89,0, + 110,2,88,0,124,1,83,0,41,7,78,114,1,0,0,0, + 114,98,0,0,0,218,11,95,95,112,97,99,107,97,103,101, + 95,95,114,141,0,0,0,114,108,0,0,0,114,139,0,0, + 0,41,21,114,6,0,0,0,114,17,0,0,0,114,1,0, + 0,0,114,106,0,0,0,114,109,0,0,0,114,117,0,0, + 0,114,126,0,0,0,114,127,0,0,0,218,16,95,78,97, + 109,101,115,112,97,99,101,76,111,97,100,101,114,218,7,95, + 95,110,101,119,95,95,90,5,95,112,97,116,104,114,108,0, + 0,0,114,98,0,0,0,114,130,0,0,0,114,145,0,0, + 0,114,105,0,0,0,114,141,0,0,0,114,124,0,0,0, + 114,113,0,0,0,114,123,0,0,0,114,139,0,0,0,41, + 5,114,95,0,0,0,114,96,0,0,0,114,144,0,0,0, + 114,109,0,0,0,114,146,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,18,95,105,110,105,116, + 95,109,111,100,117,108,101,95,97,116,116,114,115,221,1,0, + 0,115,96,0,0,0,0,4,20,1,2,1,12,1,14,1, + 6,2,20,1,6,1,8,2,10,1,8,1,4,1,6,2, + 10,1,8,1,6,11,6,1,2,1,10,1,14,1,6,2, + 20,1,2,1,12,1,14,1,6,2,2,1,10,1,16,1, + 6,2,24,1,12,1,2,1,12,1,16,1,6,2,8,1, + 24,1,2,1,12,1,16,1,6,2,24,1,12,1,2,1, + 12,1,16,1,6,1,114,148,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 67,0,0,0,115,82,0,0,0,100,1,125,1,116,0,124, + 0,106,1,100,2,131,2,114,30,124,0,106,1,160,2,124, + 0,161,1,125,1,110,20,116,0,124,0,106,1,100,3,131, + 2,114,50,116,3,100,4,131,1,130,1,124,1,100,1,107, + 8,114,68,116,4,124,0,106,5,131,1,125,1,116,6,124, + 0,124,1,131,2,1,0,124,1,83,0,41,5,122,43,67, + 114,101,97,116,101,32,97,32,109,111,100,117,108,101,32,98, + 97,115,101,100,32,111,110,32,116,104,101,32,112,114,111,118, + 105,100,101,100,32,115,112,101,99,46,78,218,13,99,114,101, + 97,116,101,95,109,111,100,117,108,101,218,11,101,120,101,99, + 95,109,111,100,117,108,101,122,66,108,111,97,100,101,114,115, + 32,116,104,97,116,32,100,101,102,105,110,101,32,101,120,101, + 99,95,109,111,100,117,108,101,40,41,32,109,117,115,116,32, + 97,108,115,111,32,100,101,102,105,110,101,32,99,114,101,97, + 116,101,95,109,111,100,117,108,101,40,41,41,7,114,4,0, + 0,0,114,109,0,0,0,114,149,0,0,0,114,79,0,0, + 0,114,18,0,0,0,114,17,0,0,0,114,148,0,0,0, + 169,2,114,95,0,0,0,114,96,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,16,109,111,100, + 117,108,101,95,102,114,111,109,95,115,112,101,99,37,2,0, + 0,115,18,0,0,0,0,3,4,1,12,3,14,1,12,1, + 8,2,8,1,10,1,10,1,114,152,0,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,67,0,0,0,115,106,0,0,0,124,0,106,0,100, + 1,107,8,114,14,100,2,110,4,124,0,106,0,125,1,124, + 0,106,1,100,1,107,8,114,66,124,0,106,2,100,1,107, + 8,114,50,100,3,160,3,124,1,161,1,83,0,100,4,160, + 3,124,1,124,0,106,2,161,2,83,0,110,36,124,0,106, + 4,114,86,100,5,160,3,124,1,124,0,106,1,161,2,83, + 0,100,6,160,3,124,0,106,0,124,0,106,1,161,2,83, + 0,100,1,83,0,41,7,122,38,82,101,116,117,114,110,32, + 116,104,101,32,114,101,112,114,32,116,111,32,117,115,101,32, + 102,111,114,32,116,104,101,32,109,111,100,117,108,101,46,78, + 114,100,0,0,0,114,101,0,0,0,114,102,0,0,0,114, + 103,0,0,0,250,18,60,109,111,100,117,108,101,32,123,33, + 114,125,32,40,123,125,41,62,41,5,114,17,0,0,0,114, + 113,0,0,0,114,109,0,0,0,114,45,0,0,0,114,124, + 0,0,0,41,2,114,95,0,0,0,114,17,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,107, + 0,0,0,54,2,0,0,115,16,0,0,0,0,3,20,1, + 10,1,10,1,10,2,16,2,6,1,14,2,114,107,0,0, + 0,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,10,0,0,0,67,0,0,0,115,204,0,0,0,124, + 0,106,0,125,2,116,1,124,2,131,1,143,180,1,0,116, + 2,106,3,160,4,124,2,161,1,124,1,107,9,114,54,100, + 1,160,5,124,2,161,1,125,3,116,6,124,3,124,2,100, + 2,141,2,130,1,122,106,124,0,106,8,100,3,107,8,114, + 106,124,0,106,9,100,3,107,8,114,90,116,6,100,4,124, + 0,106,0,100,2,141,2,130,1,116,10,124,0,124,1,100, + 5,100,6,141,3,1,0,110,52,116,10,124,0,124,1,100, + 5,100,6,141,3,1,0,116,11,124,0,106,8,100,7,131, + 2,115,146,124,0,106,8,160,12,124,2,161,1,1,0,110, + 12,124,0,106,8,160,13,124,1,161,1,1,0,87,0,53, + 0,116,2,106,3,160,7,124,0,106,0,161,1,125,1,124, + 1,116,2,106,3,124,0,106,0,60,0,88,0,87,0,53, + 0,81,0,82,0,88,0,124,1,83,0,41,8,122,70,69, + 120,101,99,117,116,101,32,116,104,101,32,115,112,101,99,39, + 115,32,115,112,101,99,105,102,105,101,100,32,109,111,100,117, + 108,101,32,105,110,32,97,110,32,101,120,105,115,116,105,110, + 103,32,109,111,100,117,108,101,39,115,32,110,97,109,101,115, + 112,97,99,101,46,122,30,109,111,100,117,108,101,32,123,33, + 114,125,32,110,111,116,32,105,110,32,115,121,115,46,109,111, + 100,117,108,101,115,114,16,0,0,0,78,250,14,109,105,115, + 115,105,110,103,32,108,111,97,100,101,114,84,114,143,0,0, + 0,114,150,0,0,0,41,14,114,17,0,0,0,114,50,0, + 0,0,114,15,0,0,0,114,92,0,0,0,114,34,0,0, + 0,114,45,0,0,0,114,79,0,0,0,218,3,112,111,112, + 114,109,0,0,0,114,117,0,0,0,114,148,0,0,0,114, + 4,0,0,0,218,11,108,111,97,100,95,109,111,100,117,108, + 101,114,150,0,0,0,41,4,114,95,0,0,0,114,96,0, + 0,0,114,17,0,0,0,218,3,109,115,103,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,93,0,0,0, + 71,2,0,0,115,34,0,0,0,0,2,6,1,10,1,16, + 1,10,1,12,1,2,1,10,1,10,1,14,2,16,2,14, + 1,12,4,14,2,16,4,14,1,24,1,114,93,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,8,0,0,0,67,0,0,0,115,26,1,0,0,122,18, + 124,0,106,0,160,1,124,0,106,2,161,1,1,0,87,0, + 110,52,1,0,1,0,1,0,124,0,106,2,116,3,106,4, + 107,6,114,64,116,3,106,4,160,5,124,0,106,2,161,1, + 125,1,124,1,116,3,106,4,124,0,106,2,60,0,130,0, + 89,0,110,2,88,0,116,3,106,4,160,5,124,0,106,2, + 161,1,125,1,124,1,116,3,106,4,124,0,106,2,60,0, + 116,6,124,1,100,1,100,0,131,3,100,0,107,8,114,148, + 122,12,124,0,106,0,124,1,95,7,87,0,110,20,4,0, + 116,8,107,10,114,146,1,0,1,0,1,0,89,0,110,2, + 88,0,116,6,124,1,100,2,100,0,131,3,100,0,107,8, + 114,226,122,40,124,1,106,9,124,1,95,10,116,11,124,1, + 100,3,131,2,115,202,124,0,106,2,160,12,100,4,161,1, + 100,5,25,0,124,1,95,10,87,0,110,20,4,0,116,8, + 107,10,114,224,1,0,1,0,1,0,89,0,110,2,88,0, + 116,6,124,1,100,6,100,0,131,3,100,0,107,8,144,1, + 114,22,122,10,124,0,124,1,95,13,87,0,110,22,4,0, + 116,8,107,10,144,1,114,20,1,0,1,0,1,0,89,0, + 110,2,88,0,124,1,83,0,41,7,78,114,98,0,0,0, + 114,145,0,0,0,114,141,0,0,0,114,128,0,0,0,114, + 22,0,0,0,114,105,0,0,0,41,14,114,109,0,0,0, + 114,156,0,0,0,114,17,0,0,0,114,15,0,0,0,114, + 92,0,0,0,114,155,0,0,0,114,6,0,0,0,114,98, + 0,0,0,114,106,0,0,0,114,1,0,0,0,114,145,0, + 0,0,114,4,0,0,0,114,129,0,0,0,114,105,0,0, + 0,114,151,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,25,95,108,111,97,100,95,98,97,99, + 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101, + 101,2,0,0,115,54,0,0,0,0,4,2,1,18,1,6, + 1,12,1,14,1,12,1,8,3,14,1,12,1,16,1,2, + 1,12,1,14,1,6,1,16,1,2,4,8,1,10,1,22, + 1,14,1,6,1,18,1,2,1,10,1,16,1,6,1,114, + 158,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,11,0,0,0,67,0,0,0,115,220,0, + 0,0,124,0,106,0,100,0,107,9,114,30,116,1,124,0, + 106,0,100,1,131,2,115,30,116,2,124,0,131,1,83,0, + 116,3,124,0,131,1,125,1,100,2,124,0,95,4,122,162, + 124,1,116,5,106,6,124,0,106,7,60,0,122,52,124,0, + 106,0,100,0,107,8,114,96,124,0,106,8,100,0,107,8, + 114,108,116,9,100,4,124,0,106,7,100,5,141,2,130,1, + 110,12,124,0,106,0,160,10,124,1,161,1,1,0,87,0, + 110,50,1,0,1,0,1,0,122,14,116,5,106,6,124,0, + 106,7,61,0,87,0,110,20,4,0,116,11,107,10,114,152, + 1,0,1,0,1,0,89,0,110,2,88,0,130,0,89,0, + 110,2,88,0,116,5,106,6,160,12,124,0,106,7,161,1, + 125,1,124,1,116,5,106,6,124,0,106,7,60,0,116,13, + 100,6,124,0,106,7,124,0,106,0,131,3,1,0,87,0, + 53,0,100,3,124,0,95,4,88,0,124,1,83,0,41,7, + 78,114,150,0,0,0,84,70,114,154,0,0,0,114,16,0, + 0,0,122,18,105,109,112,111,114,116,32,123,33,114,125,32, + 35,32,123,33,114,125,41,14,114,109,0,0,0,114,4,0, + 0,0,114,158,0,0,0,114,152,0,0,0,90,13,95,105, + 110,105,116,105,97,108,105,122,105,110,103,114,15,0,0,0, + 114,92,0,0,0,114,17,0,0,0,114,117,0,0,0,114, + 79,0,0,0,114,150,0,0,0,114,63,0,0,0,114,155, + 0,0,0,114,76,0,0,0,114,151,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,14,95,108, + 111,97,100,95,117,110,108,111,99,107,101,100,138,2,0,0, + 115,46,0,0,0,0,2,10,2,12,1,8,2,8,5,6, + 1,2,1,12,1,2,1,10,1,10,1,16,3,16,1,6, + 1,2,1,14,1,14,1,6,1,8,5,14,1,12,1,20, + 2,8,2,114,159,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,10,0,0,0,67,0,0, + 0,115,42,0,0,0,116,0,124,0,106,1,131,1,143,22, + 1,0,116,2,124,0,131,1,87,0,2,0,53,0,81,0, + 82,0,163,0,83,0,81,0,82,0,88,0,100,1,83,0, + 41,2,122,191,82,101,116,117,114,110,32,97,32,110,101,119, + 32,109,111,100,117,108,101,32,111,98,106,101,99,116,44,32, + 108,111,97,100,101,100,32,98,121,32,116,104,101,32,115,112, + 101,99,39,115,32,108,111,97,100,101,114,46,10,10,32,32, + 32,32,84,104,101,32,109,111,100,117,108,101,32,105,115,32, + 110,111,116,32,97,100,100,101,100,32,116,111,32,105,116,115, + 32,112,97,114,101,110,116,46,10,10,32,32,32,32,73,102, + 32,97,32,109,111,100,117,108,101,32,105,115,32,97,108,114, + 101,97,100,121,32,105,110,32,115,121,115,46,109,111,100,117, + 108,101,115,44,32,116,104,97,116,32,101,120,105,115,116,105, + 110,103,32,109,111,100,117,108,101,32,103,101,116,115,10,32, + 32,32,32,99,108,111,98,98,101,114,101,100,46,10,10,32, + 32,32,32,78,41,3,114,50,0,0,0,114,17,0,0,0, + 114,159,0,0,0,41,1,114,95,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,94,0,0,0, + 180,2,0,0,115,4,0,0,0,0,9,12,1,114,94,0, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,64,0,0,0,115,136,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,101,4,100,2, + 100,3,132,0,131,1,90,5,101,6,100,19,100,5,100,6, + 132,1,131,1,90,7,101,6,100,20,100,7,100,8,132,1, + 131,1,90,8,101,6,100,9,100,10,132,0,131,1,90,9, + 101,6,100,11,100,12,132,0,131,1,90,10,101,6,101,11, + 100,13,100,14,132,0,131,1,131,1,90,12,101,6,101,11, + 100,15,100,16,132,0,131,1,131,1,90,13,101,6,101,11, + 100,17,100,18,132,0,131,1,131,1,90,14,101,6,101,15, + 131,1,90,16,100,4,83,0,41,21,218,15,66,117,105,108, + 116,105,110,73,109,112,111,114,116,101,114,122,144,77,101,116, + 97,32,112,97,116,104,32,105,109,112,111,114,116,32,102,111, + 114,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,115,46,10,10,32,32,32,32,65,108,108,32,109,101,116, + 104,111,100,115,32,97,114,101,32,101,105,116,104,101,114,32, + 99,108,97,115,115,32,111,114,32,115,116,97,116,105,99,32, + 109,101,116,104,111,100,115,32,116,111,32,97,118,111,105,100, + 32,116,104,101,32,110,101,101,100,32,116,111,10,32,32,32, + 32,105,110,115,116,97,110,116,105,97,116,101,32,116,104,101, + 32,99,108,97,115,115,46,10,10,32,32,32,32,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0, + 0,0,67,0,0,0,115,12,0,0,0,100,1,160,0,124, + 0,106,1,161,1,83,0,41,2,250,115,82,101,116,117,114, + 110,32,114,101,112,114,32,102,111,114,32,116,104,101,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,101,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,84,104,101,32,105, + 109,112,111,114,116,32,109,97,99,104,105,110,101,114,121,32, + 100,111,101,115,32,116,104,101,32,106,111,98,32,105,116,115, + 101,108,102,46,10,10,32,32,32,32,32,32,32,32,122,24, + 60,109,111,100,117,108,101,32,123,33,114,125,32,40,98,117, + 105,108,116,45,105,110,41,62,41,2,114,45,0,0,0,114, + 1,0,0,0,41,1,114,96,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,99,0,0,0,204, + 2,0,0,115,2,0,0,0,0,7,122,27,66,117,105,108, + 116,105,110,73,109,112,111,114,116,101,114,46,109,111,100,117, + 108,101,95,114,101,112,114,78,99,4,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,0, + 0,115,44,0,0,0,124,2,100,0,107,9,114,12,100,0, + 83,0,116,0,160,1,124,1,161,1,114,36,116,2,124,1, + 124,0,100,1,100,2,141,3,83,0,100,0,83,0,100,0, + 83,0,41,3,78,122,8,98,117,105,108,116,45,105,110,114, + 137,0,0,0,41,3,114,57,0,0,0,90,10,105,115,95, + 98,117,105,108,116,105,110,114,91,0,0,0,169,4,218,3, + 99,108,115,114,81,0,0,0,218,4,112,97,116,104,218,6, + 116,97,114,103,101,116,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,9,102,105,110,100,95,115,112,101,99, + 213,2,0,0,115,10,0,0,0,0,2,8,1,4,1,10, + 1,14,2,122,25,66,117,105,108,116,105,110,73,109,112,111, + 114,116,101,114,46,102,105,110,100,95,115,112,101,99,99,3, + 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4, + 0,0,0,67,0,0,0,115,30,0,0,0,124,0,160,0, + 124,1,124,2,161,2,125,3,124,3,100,1,107,9,114,26, + 124,3,106,1,83,0,100,1,83,0,41,2,122,175,70,105, + 110,100,32,116,104,101,32,98,117,105,108,116,45,105,110,32, + 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, + 32,73,102,32,39,112,97,116,104,39,32,105,115,32,101,118, + 101,114,32,115,112,101,99,105,102,105,101,100,32,116,104,101, + 110,32,116,104,101,32,115,101,97,114,99,104,32,105,115,32, + 99,111,110,115,105,100,101,114,101,100,32,97,32,102,97,105, + 108,117,114,101,46,10,10,32,32,32,32,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,102, + 105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,101, + 97,100,46,10,10,32,32,32,32,32,32,32,32,78,41,2, + 114,166,0,0,0,114,109,0,0,0,41,4,114,163,0,0, + 0,114,81,0,0,0,114,164,0,0,0,114,95,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 11,102,105,110,100,95,109,111,100,117,108,101,222,2,0,0, + 115,4,0,0,0,0,9,12,1,122,27,66,117,105,108,116, + 105,110,73,109,112,111,114,116,101,114,46,102,105,110,100,95, + 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, + 46,0,0,0,124,1,106,0,116,1,106,2,107,7,114,34, + 116,3,100,1,160,4,124,1,106,0,161,1,124,1,106,0, + 100,2,141,2,130,1,116,5,116,6,106,7,124,1,131,2, + 83,0,41,3,122,24,67,114,101,97,116,101,32,97,32,98, + 117,105,108,116,45,105,110,32,109,111,100,117,108,101,114,77, + 0,0,0,114,16,0,0,0,41,8,114,17,0,0,0,114, + 15,0,0,0,114,78,0,0,0,114,79,0,0,0,114,45, + 0,0,0,114,67,0,0,0,114,57,0,0,0,90,14,99, + 114,101,97,116,101,95,98,117,105,108,116,105,110,41,2,114, + 30,0,0,0,114,95,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,149,0,0,0,234,2,0, + 0,115,10,0,0,0,0,3,12,1,12,1,4,255,6,2, + 122,29,66,117,105,108,116,105,110,73,109,112,111,114,116,101, + 114,46,99,114,101,97,116,101,95,109,111,100,117,108,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 3,0,0,0,67,0,0,0,115,16,0,0,0,116,0,116, + 1,106,2,124,1,131,2,1,0,100,1,83,0,41,2,122, + 22,69,120,101,99,32,97,32,98,117,105,108,116,45,105,110, + 32,109,111,100,117,108,101,78,41,3,114,67,0,0,0,114, + 57,0,0,0,90,12,101,120,101,99,95,98,117,105,108,116, + 105,110,41,2,114,30,0,0,0,114,96,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,150,0, + 0,0,242,2,0,0,115,2,0,0,0,0,3,122,27,66, + 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,57, + 82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,98, + 117,105,108,116,45,105,110,32,109,111,100,117,108,101,115,32, + 100,111,32,110,111,116,32,104,97,118,101,32,99,111,100,101, + 32,111,98,106,101,99,116,115,46,78,114,10,0,0,0,169, + 2,114,163,0,0,0,114,81,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,8,103,101,116,95, + 99,111,100,101,247,2,0,0,115,2,0,0,0,0,4,122, + 24,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, + 46,103,101,116,95,99,111,100,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,122,56,82, + 101,116,117,114,110,32,78,111,110,101,32,97,115,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,100, + 111,32,110,111,116,32,104,97,118,101,32,115,111,117,114,99, + 101,32,99,111,100,101,46,78,114,10,0,0,0,114,168,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,10,103,101,116,95,115,111,117,114,99,101,253,2,0, + 0,115,2,0,0,0,0,4,122,26,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,103,101,116,95,115,111, + 117,114,99,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,83,0,41,2,122,52,82,101,116,117,114,110, + 32,70,97,108,115,101,32,97,115,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,115,32,97,114,101,32,110, + 101,118,101,114,32,112,97,99,107,97,103,101,115,46,70,114, + 10,0,0,0,114,168,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,115,0,0,0,3,3,0, + 0,115,2,0,0,0,0,4,122,26,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,105,115,95,112,97,99, + 107,97,103,101,41,2,78,78,41,1,78,41,17,114,1,0, + 0,0,114,0,0,0,0,114,2,0,0,0,114,3,0,0, + 0,218,12,115,116,97,116,105,99,109,101,116,104,111,100,114, + 99,0,0,0,218,11,99,108,97,115,115,109,101,116,104,111, + 100,114,166,0,0,0,114,167,0,0,0,114,149,0,0,0, + 114,150,0,0,0,114,86,0,0,0,114,169,0,0,0,114, + 170,0,0,0,114,115,0,0,0,114,97,0,0,0,114,156, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,160,0,0,0,195,2,0,0, + 115,42,0,0,0,8,2,4,7,2,1,10,8,2,1,12, + 8,2,1,12,11,2,1,10,7,2,1,10,4,2,1,2, + 1,12,4,2,1,2,1,12,4,2,1,2,1,12,4,114, + 160,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,64,0,0,0,115,144,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 90,4,101,5,100,3,100,4,132,0,131,1,90,6,101,7, + 100,22,100,6,100,7,132,1,131,1,90,8,101,7,100,23, + 100,8,100,9,132,1,131,1,90,9,101,7,100,10,100,11, + 132,0,131,1,90,10,101,5,100,12,100,13,132,0,131,1, + 90,11,101,7,100,14,100,15,132,0,131,1,90,12,101,7, + 101,13,100,16,100,17,132,0,131,1,131,1,90,14,101,7, + 101,13,100,18,100,19,132,0,131,1,131,1,90,15,101,7, + 101,13,100,20,100,21,132,0,131,1,131,1,90,16,100,5, + 83,0,41,24,218,14,70,114,111,122,101,110,73,109,112,111, + 114,116,101,114,122,142,77,101,116,97,32,112,97,116,104,32, + 105,109,112,111,114,116,32,102,111,114,32,102,114,111,122,101, + 110,32,109,111,100,117,108,101,115,46,10,10,32,32,32,32, + 65,108,108,32,109,101,116,104,111,100,115,32,97,114,101,32, + 101,105,116,104,101,114,32,99,108,97,115,115,32,111,114,32, + 115,116,97,116,105,99,32,109,101,116,104,111,100,115,32,116, + 111,32,97,118,111,105,100,32,116,104,101,32,110,101,101,100, + 32,116,111,10,32,32,32,32,105,110,115,116,97,110,116,105, + 97,116,101,32,116,104,101,32,99,108,97,115,115,46,10,10, + 32,32,32,32,90,6,102,114,111,122,101,110,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,67,0,0,0,115,16,0,0,0,100,1,160,0,124,0, + 106,1,116,2,106,3,161,2,83,0,41,2,114,161,0,0, + 0,114,153,0,0,0,41,4,114,45,0,0,0,114,1,0, + 0,0,114,173,0,0,0,114,138,0,0,0,41,1,218,1, + 109,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,99,0,0,0,23,3,0,0,115,2,0,0,0,0,7, + 122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,109,111,100,117,108,101,95,114,101,112,114,78,99,4,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0, + 0,0,67,0,0,0,115,34,0,0,0,116,0,160,1,124, + 1,161,1,114,26,116,2,124,1,124,0,124,0,106,3,100, + 1,141,3,83,0,100,0,83,0,100,0,83,0,41,2,78, + 114,137,0,0,0,41,4,114,57,0,0,0,114,88,0,0, + 0,114,91,0,0,0,114,138,0,0,0,114,162,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 166,0,0,0,32,3,0,0,115,6,0,0,0,0,2,10, + 1,16,2,122,24,70,114,111,122,101,110,73,109,112,111,114, + 116,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,18,0,0,0,116,0,160,1,124, + 1,161,1,114,14,124,0,83,0,100,1,83,0,41,2,122, + 93,70,105,110,100,32,97,32,102,114,111,122,101,110,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,41, + 2,114,57,0,0,0,114,88,0,0,0,41,3,114,163,0, + 0,0,114,81,0,0,0,114,164,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,167,0,0,0, + 39,3,0,0,115,2,0,0,0,0,7,122,26,70,114,111, + 122,101,110,73,109,112,111,114,116,101,114,46,102,105,110,100, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,83,0,41,2,122,42,85,115,101, + 32,100,101,102,97,117,108,116,32,115,101,109,97,110,116,105, + 99,115,32,102,111,114,32,109,111,100,117,108,101,32,99,114, + 101,97,116,105,111,110,46,78,114,10,0,0,0,41,2,114, + 163,0,0,0,114,95,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,149,0,0,0,48,3,0, + 0,115,2,0,0,0,0,2,122,28,70,114,111,122,101,110, + 73,109,112,111,114,116,101,114,46,99,114,101,97,116,101,95, + 109,111,100,117,108,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, + 64,0,0,0,124,0,106,0,106,1,125,1,116,2,160,3, + 124,1,161,1,115,36,116,4,100,1,160,5,124,1,161,1, + 124,1,100,2,141,2,130,1,116,6,116,2,106,7,124,1, + 131,2,125,2,116,8,124,2,124,0,106,9,131,2,1,0, + 100,0,83,0,114,87,0,0,0,41,10,114,105,0,0,0, + 114,17,0,0,0,114,57,0,0,0,114,88,0,0,0,114, + 79,0,0,0,114,45,0,0,0,114,67,0,0,0,218,17, + 103,101,116,95,102,114,111,122,101,110,95,111,98,106,101,99, + 116,218,4,101,120,101,99,114,7,0,0,0,41,3,114,96, + 0,0,0,114,17,0,0,0,218,4,99,111,100,101,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,150,0, + 0,0,52,3,0,0,115,14,0,0,0,0,2,8,1,10, + 1,10,1,2,255,6,2,12,1,122,26,70,114,111,122,101, + 110,73,109,112,111,114,116,101,114,46,101,120,101,99,95,109, + 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,10, + 0,0,0,116,0,124,0,124,1,131,2,83,0,41,1,122, + 95,76,111,97,100,32,97,32,102,114,111,122,101,110,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 101,120,101,99,95,109,111,100,117,108,101,40,41,32,105,110, + 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, + 41,1,114,97,0,0,0,114,168,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,156,0,0,0, + 61,3,0,0,115,2,0,0,0,0,7,122,26,70,114,111, + 122,101,110,73,109,112,111,114,116,101,114,46,108,111,97,100, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, + 115,10,0,0,0,116,0,160,1,124,1,161,1,83,0,41, + 1,122,45,82,101,116,117,114,110,32,116,104,101,32,99,111, + 100,101,32,111,98,106,101,99,116,32,102,111,114,32,116,104, + 101,32,102,114,111,122,101,110,32,109,111,100,117,108,101,46, + 41,2,114,57,0,0,0,114,175,0,0,0,114,168,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,169,0,0,0,70,3,0,0,115,2,0,0,0,0,4, + 122,23,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,103,101,116,95,99,111,100,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,122,54,82, + 101,116,117,114,110,32,78,111,110,101,32,97,115,32,102,114, + 111,122,101,110,32,109,111,100,117,108,101,115,32,100,111,32, + 110,111,116,32,104,97,118,101,32,115,111,117,114,99,101,32, + 99,111,100,101,46,78,114,10,0,0,0,114,168,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 170,0,0,0,76,3,0,0,115,2,0,0,0,0,4,122, + 25,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, + 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, + 0,0,0,115,10,0,0,0,116,0,160,1,124,1,161,1, + 83,0,41,1,122,46,82,101,116,117,114,110,32,84,114,117, + 101,32,105,102,32,116,104,101,32,102,114,111,122,101,110,32, + 109,111,100,117,108,101,32,105,115,32,97,32,112,97,99,107, + 97,103,101,46,41,2,114,57,0,0,0,90,17,105,115,95, + 102,114,111,122,101,110,95,112,97,99,107,97,103,101,114,168, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,115,0,0,0,82,3,0,0,115,2,0,0,0, + 0,4,122,25,70,114,111,122,101,110,73,109,112,111,114,116, + 101,114,46,105,115,95,112,97,99,107,97,103,101,41,2,78, + 78,41,1,78,41,17,114,1,0,0,0,114,0,0,0,0, + 114,2,0,0,0,114,3,0,0,0,114,138,0,0,0,114, + 171,0,0,0,114,99,0,0,0,114,172,0,0,0,114,166, + 0,0,0,114,167,0,0,0,114,149,0,0,0,114,150,0, + 0,0,114,156,0,0,0,114,90,0,0,0,114,169,0,0, + 0,114,170,0,0,0,114,115,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 173,0,0,0,12,3,0,0,115,46,0,0,0,8,2,4, + 7,4,2,2,1,10,8,2,1,12,6,2,1,12,8,2, + 1,10,3,2,1,10,8,2,1,10,8,2,1,2,1,12, + 4,2,1,2,1,12,4,2,1,2,1,114,173,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,32,0,0,0,101,0, + 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, + 90,4,100,4,100,5,132,0,90,5,100,6,83,0,41,7, + 218,18,95,73,109,112,111,114,116,76,111,99,107,67,111,110, + 116,101,120,116,122,36,67,111,110,116,101,120,116,32,109,97, + 110,97,103,101,114,32,102,111,114,32,116,104,101,32,105,109, + 112,111,114,116,32,108,111,99,107,46,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, + 0,0,0,115,12,0,0,0,116,0,160,1,161,0,1,0, + 100,1,83,0,41,2,122,24,65,99,113,117,105,114,101,32, + 116,104,101,32,105,109,112,111,114,116,32,108,111,99,107,46, + 78,41,2,114,57,0,0,0,114,58,0,0,0,114,47,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,54,0,0,0,95,3,0,0,115,2,0,0,0,0, + 2,122,28,95,73,109,112,111,114,116,76,111,99,107,67,111, + 110,116,101,120,116,46,95,95,101,110,116,101,114,95,95,99, + 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 2,0,0,0,67,0,0,0,115,12,0,0,0,116,0,160, + 1,161,0,1,0,100,1,83,0,41,2,122,60,82,101,108, + 101,97,115,101,32,116,104,101,32,105,109,112,111,114,116,32, + 108,111,99,107,32,114,101,103,97,114,100,108,101,115,115,32, + 111,102,32,97,110,121,32,114,97,105,115,101,100,32,101,120, + 99,101,112,116,105,111,110,115,46,78,41,2,114,57,0,0, + 0,114,59,0,0,0,41,4,114,30,0,0,0,218,8,101, + 120,99,95,116,121,112,101,218,9,101,120,99,95,118,97,108, + 117,101,218,13,101,120,99,95,116,114,97,99,101,98,97,99, + 107,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,56,0,0,0,99,3,0,0,115,2,0,0,0,0,2, + 122,27,95,73,109,112,111,114,116,76,111,99,107,67,111,110, + 116,101,120,116,46,95,95,101,120,105,116,95,95,78,41,6, + 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, + 3,0,0,0,114,54,0,0,0,114,56,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,178,0,0,0,91,3,0,0,115,6,0,0,0, + 8,2,4,2,8,4,114,178,0,0,0,99,3,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,64,0,0,0,124,1,160,0,100,1,124, + 2,100,2,24,0,161,2,125,3,116,1,124,3,131,1,124, + 2,107,0,114,36,116,2,100,3,131,1,130,1,124,3,100, + 4,25,0,125,4,124,0,114,60,100,5,160,3,124,4,124, + 0,161,2,83,0,124,4,83,0,41,6,122,50,82,101,115, + 111,108,118,101,32,97,32,114,101,108,97,116,105,118,101,32, + 109,111,100,117,108,101,32,110,97,109,101,32,116,111,32,97, + 110,32,97,98,115,111,108,117,116,101,32,111,110,101,46,114, + 128,0,0,0,114,37,0,0,0,122,50,97,116,116,101,109, + 112,116,101,100,32,114,101,108,97,116,105,118,101,32,105,109, + 112,111,114,116,32,98,101,121,111,110,100,32,116,111,112,45, + 108,101,118,101,108,32,112,97,99,107,97,103,101,114,22,0, + 0,0,250,5,123,125,46,123,125,41,4,218,6,114,115,112, + 108,105,116,218,3,108,101,110,218,10,86,97,108,117,101,69, + 114,114,111,114,114,45,0,0,0,41,5,114,17,0,0,0, + 218,7,112,97,99,107,97,103,101,218,5,108,101,118,101,108, + 90,4,98,105,116,115,90,4,98,97,115,101,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,13,95,114,101, + 115,111,108,118,101,95,110,97,109,101,104,3,0,0,115,10, + 0,0,0,0,2,16,1,12,1,8,1,8,1,114,188,0, + 0,0,99,3,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,4,0,0,0,67,0,0,0,115,34,0,0,0, + 124,0,160,0,124,1,124,2,161,2,125,3,124,3,100,0, + 107,8,114,24,100,0,83,0,116,1,124,1,124,3,131,2, + 83,0,114,13,0,0,0,41,2,114,167,0,0,0,114,91, + 0,0,0,41,4,218,6,102,105,110,100,101,114,114,17,0, + 0,0,114,164,0,0,0,114,109,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,17,95,102,105, + 110,100,95,115,112,101,99,95,108,101,103,97,99,121,113,3, + 0,0,115,8,0,0,0,0,3,12,1,8,1,4,1,114, + 190,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, + 0,10,0,0,0,10,0,0,0,67,0,0,0,115,12,1, + 0,0,116,0,106,1,125,3,124,3,100,1,107,8,114,22, + 116,2,100,2,131,1,130,1,124,3,115,38,116,3,160,4, + 100,3,116,5,161,2,1,0,124,0,116,0,106,6,107,6, + 125,4,124,3,68,0,93,210,125,5,116,7,131,0,143,84, + 1,0,122,10,124,5,106,8,125,6,87,0,110,54,4,0, + 116,9,107,10,114,128,1,0,1,0,1,0,116,10,124,5, + 124,0,124,1,131,3,125,7,124,7,100,1,107,8,114,124, + 89,0,87,0,53,0,81,0,82,0,163,0,113,52,89,0, + 110,14,88,0,124,6,124,0,124,1,124,2,131,3,125,7, + 87,0,53,0,81,0,82,0,88,0,124,7,100,1,107,9, + 114,52,124,4,144,0,115,254,124,0,116,0,106,6,107,6, + 144,0,114,254,116,0,106,6,124,0,25,0,125,8,122,10, + 124,8,106,11,125,9,87,0,110,28,4,0,116,9,107,10, + 114,226,1,0,1,0,1,0,124,7,6,0,89,0,2,0, + 1,0,83,0,88,0,124,9,100,1,107,8,114,244,124,7, + 2,0,1,0,83,0,124,9,2,0,1,0,83,0,113,52, + 124,7,2,0,1,0,83,0,113,52,100,1,83,0,41,4, + 122,21,70,105,110,100,32,97,32,109,111,100,117,108,101,39, + 115,32,115,112,101,99,46,78,122,53,115,121,115,46,109,101, + 116,97,95,112,97,116,104,32,105,115,32,78,111,110,101,44, + 32,80,121,116,104,111,110,32,105,115,32,108,105,107,101,108, + 121,32,115,104,117,116,116,105,110,103,32,100,111,119,110,122, + 22,115,121,115,46,109,101,116,97,95,112,97,116,104,32,105, + 115,32,101,109,112,116,121,41,12,114,15,0,0,0,218,9, + 109,101,116,97,95,112,97,116,104,114,79,0,0,0,218,9, + 95,119,97,114,110,105,110,103,115,218,4,119,97,114,110,218, + 13,73,109,112,111,114,116,87,97,114,110,105,110,103,114,92, + 0,0,0,114,178,0,0,0,114,166,0,0,0,114,106,0, + 0,0,114,190,0,0,0,114,105,0,0,0,41,10,114,17, + 0,0,0,114,164,0,0,0,114,165,0,0,0,114,191,0, + 0,0,90,9,105,115,95,114,101,108,111,97,100,114,189,0, + 0,0,114,166,0,0,0,114,95,0,0,0,114,96,0,0, + 0,114,105,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,10,95,102,105,110,100,95,115,112,101, + 99,122,3,0,0,115,54,0,0,0,0,2,6,1,8,2, + 8,3,4,1,12,5,10,1,8,1,8,1,2,1,10,1, + 14,1,12,1,8,1,20,2,22,1,8,2,18,1,10,1, + 2,1,10,1,14,4,14,2,8,1,8,2,10,2,10,2, + 114,195,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,5,0,0,0,67,0,0,0,115,108, + 0,0,0,116,0,124,0,116,1,131,2,115,28,116,2,100, + 1,160,3,116,4,124,0,131,1,161,1,131,1,130,1,124, + 2,100,2,107,0,114,44,116,5,100,3,131,1,130,1,124, + 2,100,2,107,4,114,84,116,0,124,1,116,1,131,2,115, + 72,116,2,100,4,131,1,130,1,110,12,124,1,115,84,116, + 6,100,5,131,1,130,1,124,0,115,104,124,2,100,2,107, + 2,114,104,116,5,100,6,131,1,130,1,100,7,83,0,41, + 8,122,28,86,101,114,105,102,121,32,97,114,103,117,109,101, + 110,116,115,32,97,114,101,32,34,115,97,110,101,34,46,122, + 31,109,111,100,117,108,101,32,110,97,109,101,32,109,117,115, + 116,32,98,101,32,115,116,114,44,32,110,111,116,32,123,125, + 114,22,0,0,0,122,18,108,101,118,101,108,32,109,117,115, + 116,32,98,101,32,62,61,32,48,122,31,95,95,112,97,99, + 107,97,103,101,95,95,32,110,111,116,32,115,101,116,32,116, + 111,32,97,32,115,116,114,105,110,103,122,54,97,116,116,101, + 109,112,116,101,100,32,114,101,108,97,116,105,118,101,32,105, + 109,112,111,114,116,32,119,105,116,104,32,110,111,32,107,110, + 111,119,110,32,112,97,114,101,110,116,32,112,97,99,107,97, + 103,101,122,17,69,109,112,116,121,32,109,111,100,117,108,101, + 32,110,97,109,101,78,41,7,218,10,105,115,105,110,115,116, + 97,110,99,101,218,3,115,116,114,218,9,84,121,112,101,69, + 114,114,111,114,114,45,0,0,0,114,14,0,0,0,114,185, + 0,0,0,114,79,0,0,0,169,3,114,17,0,0,0,114, + 186,0,0,0,114,187,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,13,95,115,97,110,105,116, + 121,95,99,104,101,99,107,169,3,0,0,115,22,0,0,0, + 0,2,10,1,18,1,8,1,8,1,8,1,10,1,10,1, + 4,1,8,2,12,1,114,200,0,0,0,122,16,78,111,32, + 109,111,100,117,108,101,32,110,97,109,101,100,32,122,4,123, + 33,114,125,99,2,0,0,0,0,0,0,0,0,0,0,0, + 8,0,0,0,8,0,0,0,67,0,0,0,115,220,0,0, + 0,100,0,125,2,124,0,160,0,100,1,161,1,100,2,25, + 0,125,3,124,3,114,134,124,3,116,1,106,2,107,7,114, + 42,116,3,124,1,124,3,131,2,1,0,124,0,116,1,106, + 2,107,6,114,62,116,1,106,2,124,0,25,0,83,0,116, + 1,106,2,124,3,25,0,125,4,122,10,124,4,106,4,125, + 2,87,0,110,50,4,0,116,5,107,10,114,132,1,0,1, + 0,1,0,116,6,100,3,23,0,160,7,124,0,124,3,161, + 2,125,5,116,8,124,5,124,0,100,4,141,2,100,0,130, + 2,89,0,110,2,88,0,116,9,124,0,124,2,131,2,125, + 6,124,6,100,0,107,8,114,172,116,8,116,6,160,7,124, + 0,161,1,124,0,100,4,141,2,130,1,110,8,116,10,124, + 6,131,1,125,7,124,3,114,216,116,1,106,2,124,3,25, + 0,125,4,116,11,124,4,124,0,160,0,100,1,161,1,100, + 5,25,0,124,7,131,3,1,0,124,7,83,0,41,6,78, + 114,128,0,0,0,114,22,0,0,0,122,23,59,32,123,33, + 114,125,32,105,115,32,110,111,116,32,97,32,112,97,99,107, + 97,103,101,114,16,0,0,0,233,2,0,0,0,41,12,114, + 129,0,0,0,114,15,0,0,0,114,92,0,0,0,114,67, + 0,0,0,114,141,0,0,0,114,106,0,0,0,218,8,95, + 69,82,82,95,77,83,71,114,45,0,0,0,218,19,77,111, + 100,117,108,101,78,111,116,70,111,117,110,100,69,114,114,111, + 114,114,195,0,0,0,114,159,0,0,0,114,5,0,0,0, + 41,8,114,17,0,0,0,218,7,105,109,112,111,114,116,95, + 114,164,0,0,0,114,130,0,0,0,90,13,112,97,114,101, + 110,116,95,109,111,100,117,108,101,114,157,0,0,0,114,95, + 0,0,0,114,96,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,23,95,102,105,110,100,95,97, + 110,100,95,108,111,97,100,95,117,110,108,111,99,107,101,100, + 188,3,0,0,115,42,0,0,0,0,1,4,1,14,1,4, + 1,10,1,10,2,10,1,10,1,10,1,2,1,10,1,14, + 1,16,1,20,1,10,1,8,1,20,2,8,1,4,2,10, + 1,22,1,114,205,0,0,0,99,2,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,10,0,0,0,67,0,0, + 0,115,106,0,0,0,116,0,124,0,131,1,143,50,1,0, + 116,1,106,2,160,3,124,0,116,4,161,2,125,2,124,2, + 116,4,107,8,114,54,116,5,124,0,124,1,131,2,87,0, + 2,0,53,0,81,0,82,0,163,0,83,0,87,0,53,0, + 81,0,82,0,88,0,124,2,100,1,107,8,114,94,100,2, + 160,6,124,0,161,1,125,3,116,7,124,3,124,0,100,3, + 141,2,130,1,116,8,124,0,131,1,1,0,124,2,83,0, + 41,4,122,25,70,105,110,100,32,97,110,100,32,108,111,97, + 100,32,116,104,101,32,109,111,100,117,108,101,46,78,122,40, + 105,109,112,111,114,116,32,111,102,32,123,125,32,104,97,108, + 116,101,100,59,32,78,111,110,101,32,105,110,32,115,121,115, + 46,109,111,100,117,108,101,115,114,16,0,0,0,41,9,114, + 50,0,0,0,114,15,0,0,0,114,92,0,0,0,114,34, + 0,0,0,218,14,95,78,69,69,68,83,95,76,79,65,68, + 73,78,71,114,205,0,0,0,114,45,0,0,0,114,203,0, + 0,0,114,65,0,0,0,41,4,114,17,0,0,0,114,204, + 0,0,0,114,96,0,0,0,114,75,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,14,95,102, + 105,110,100,95,97,110,100,95,108,111,97,100,218,3,0,0, + 115,22,0,0,0,0,2,10,1,14,1,8,1,32,2,8, + 1,4,1,2,255,4,2,12,2,8,1,114,207,0,0,0, + 114,22,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,42, + 0,0,0,116,0,124,0,124,1,124,2,131,3,1,0,124, + 2,100,1,107,4,114,32,116,1,124,0,124,1,124,2,131, + 3,125,0,116,2,124,0,116,3,131,2,83,0,41,2,97, + 50,1,0,0,73,109,112,111,114,116,32,97,110,100,32,114, + 101,116,117,114,110,32,116,104,101,32,109,111,100,117,108,101, + 32,98,97,115,101,100,32,111,110,32,105,116,115,32,110,97, + 109,101,44,32,116,104,101,32,112,97,99,107,97,103,101,32, + 116,104,101,32,99,97,108,108,32,105,115,10,32,32,32,32, + 98,101,105,110,103,32,109,97,100,101,32,102,114,111,109,44, + 32,97,110,100,32,116,104,101,32,108,101,118,101,108,32,97, + 100,106,117,115,116,109,101,110,116,46,10,10,32,32,32,32, + 84,104,105,115,32,102,117,110,99,116,105,111,110,32,114,101, + 112,114,101,115,101,110,116,115,32,116,104,101,32,103,114,101, + 97,116,101,115,116,32,99,111,109,109,111,110,32,100,101,110, + 111,109,105,110,97,116,111,114,32,111,102,32,102,117,110,99, + 116,105,111,110,97,108,105,116,121,10,32,32,32,32,98,101, + 116,119,101,101,110,32,105,109,112,111,114,116,95,109,111,100, + 117,108,101,32,97,110,100,32,95,95,105,109,112,111,114,116, + 95,95,46,32,84,104,105,115,32,105,110,99,108,117,100,101, + 115,32,115,101,116,116,105,110,103,32,95,95,112,97,99,107, + 97,103,101,95,95,32,105,102,10,32,32,32,32,116,104,101, + 32,108,111,97,100,101,114,32,100,105,100,32,110,111,116,46, + 10,10,32,32,32,32,114,22,0,0,0,41,4,114,200,0, + 0,0,114,188,0,0,0,114,207,0,0,0,218,11,95,103, + 99,100,95,105,109,112,111,114,116,114,199,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,208,0, + 0,0,234,3,0,0,115,8,0,0,0,0,9,12,1,8, + 1,12,1,114,208,0,0,0,169,1,218,9,114,101,99,117, + 114,115,105,118,101,99,3,0,0,0,0,0,0,0,1,0, + 0,0,8,0,0,0,11,0,0,0,67,0,0,0,115,226, + 0,0,0,124,1,68,0,93,216,125,4,116,0,124,4,116, + 1,131,2,115,66,124,3,114,34,124,0,106,2,100,1,23, + 0,125,5,110,4,100,2,125,5,116,3,100,3,124,5,155, + 0,100,4,116,4,124,4,131,1,106,2,155,0,157,4,131, + 1,130,1,113,4,124,4,100,5,107,2,114,108,124,3,115, + 220,116,5,124,0,100,6,131,2,114,220,116,6,124,0,124, + 0,106,7,124,2,100,7,100,8,141,4,1,0,113,4,116, + 5,124,0,124,4,131,2,115,4,100,9,160,8,124,0,106, + 2,124,4,161,2,125,6,122,14,116,9,124,2,124,6,131, + 2,1,0,87,0,113,4,4,0,116,10,107,10,114,218,1, + 0,125,7,1,0,122,42,124,7,106,11,124,6,107,2,114, + 200,116,12,106,13,160,14,124,6,116,15,161,2,100,10,107, + 9,114,200,87,0,89,0,162,8,113,4,130,0,87,0,53, + 0,100,10,125,7,126,7,88,0,89,0,113,4,88,0,113, + 4,124,0,83,0,41,11,122,238,70,105,103,117,114,101,32, + 111,117,116,32,119,104,97,116,32,95,95,105,109,112,111,114, + 116,95,95,32,115,104,111,117,108,100,32,114,101,116,117,114, + 110,46,10,10,32,32,32,32,84,104,101,32,105,109,112,111, + 114,116,95,32,112,97,114,97,109,101,116,101,114,32,105,115, + 32,97,32,99,97,108,108,97,98,108,101,32,119,104,105,99, + 104,32,116,97,107,101,115,32,116,104,101,32,110,97,109,101, + 32,111,102,32,109,111,100,117,108,101,32,116,111,10,32,32, + 32,32,105,109,112,111,114,116,46,32,73,116,32,105,115,32, + 114,101,113,117,105,114,101,100,32,116,111,32,100,101,99,111, + 117,112,108,101,32,116,104,101,32,102,117,110,99,116,105,111, + 110,32,102,114,111,109,32,97,115,115,117,109,105,110,103,32, + 105,109,112,111,114,116,108,105,98,39,115,10,32,32,32,32, + 105,109,112,111,114,116,32,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,32,105,115,32,100,101,115,105,114,101,100, + 46,10,10,32,32,32,32,122,8,46,95,95,97,108,108,95, + 95,122,13,96,96,102,114,111,109,32,108,105,115,116,39,39, + 122,8,73,116,101,109,32,105,110,32,122,18,32,109,117,115, + 116,32,98,101,32,115,116,114,44,32,110,111,116,32,250,1, + 42,218,7,95,95,97,108,108,95,95,84,114,209,0,0,0, + 114,182,0,0,0,78,41,16,114,196,0,0,0,114,197,0, + 0,0,114,1,0,0,0,114,198,0,0,0,114,14,0,0, + 0,114,4,0,0,0,218,16,95,104,97,110,100,108,101,95, + 102,114,111,109,108,105,115,116,114,212,0,0,0,114,45,0, + 0,0,114,67,0,0,0,114,203,0,0,0,114,17,0,0, + 0,114,15,0,0,0,114,92,0,0,0,114,34,0,0,0, + 114,206,0,0,0,41,8,114,96,0,0,0,218,8,102,114, + 111,109,108,105,115,116,114,204,0,0,0,114,210,0,0,0, + 218,1,120,90,5,119,104,101,114,101,90,9,102,114,111,109, + 95,110,97,109,101,90,3,101,120,99,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,213,0,0,0,249,3, + 0,0,115,44,0,0,0,0,10,8,1,10,1,4,1,12, + 2,4,1,28,2,8,1,14,1,10,1,2,255,8,2,10, + 1,14,1,2,1,14,1,16,4,10,1,16,255,2,2,8, + 1,22,1,114,213,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,6,0,0,0,67,0,0, + 0,115,146,0,0,0,124,0,160,0,100,1,161,1,125,1, + 124,0,160,0,100,2,161,1,125,2,124,1,100,3,107,9, + 114,82,124,2,100,3,107,9,114,78,124,1,124,2,106,1, + 107,3,114,78,116,2,106,3,100,4,124,1,155,2,100,5, + 124,2,106,1,155,2,100,6,157,5,116,4,100,7,100,8, + 141,3,1,0,124,1,83,0,124,2,100,3,107,9,114,96, + 124,2,106,1,83,0,116,2,106,3,100,9,116,4,100,7, + 100,8,141,3,1,0,124,0,100,10,25,0,125,1,100,11, + 124,0,107,7,114,142,124,1,160,5,100,12,161,1,100,13, + 25,0,125,1,124,1,83,0,41,14,122,167,67,97,108,99, + 117,108,97,116,101,32,119,104,97,116,32,95,95,112,97,99, + 107,97,103,101,95,95,32,115,104,111,117,108,100,32,98,101, + 46,10,10,32,32,32,32,95,95,112,97,99,107,97,103,101, + 95,95,32,105,115,32,110,111,116,32,103,117,97,114,97,110, + 116,101,101,100,32,116,111,32,98,101,32,100,101,102,105,110, + 101,100,32,111,114,32,99,111,117,108,100,32,98,101,32,115, + 101,116,32,116,111,32,78,111,110,101,10,32,32,32,32,116, + 111,32,114,101,112,114,101,115,101,110,116,32,116,104,97,116, + 32,105,116,115,32,112,114,111,112,101,114,32,118,97,108,117, + 101,32,105,115,32,117,110,107,110,111,119,110,46,10,10,32, + 32,32,32,114,145,0,0,0,114,105,0,0,0,78,122,32, + 95,95,112,97,99,107,97,103,101,95,95,32,33,61,32,95, + 95,115,112,101,99,95,95,46,112,97,114,101,110,116,32,40, + 122,4,32,33,61,32,250,1,41,233,3,0,0,0,41,1, + 90,10,115,116,97,99,107,108,101,118,101,108,122,89,99,97, + 110,39,116,32,114,101,115,111,108,118,101,32,112,97,99,107, + 97,103,101,32,102,114,111,109,32,95,95,115,112,101,99,95, + 95,32,111,114,32,95,95,112,97,99,107,97,103,101,95,95, + 44,32,102,97,108,108,105,110,103,32,98,97,99,107,32,111, + 110,32,95,95,110,97,109,101,95,95,32,97,110,100,32,95, + 95,112,97,116,104,95,95,114,1,0,0,0,114,141,0,0, + 0,114,128,0,0,0,114,22,0,0,0,41,6,114,34,0, + 0,0,114,130,0,0,0,114,192,0,0,0,114,193,0,0, + 0,114,194,0,0,0,114,129,0,0,0,41,3,218,7,103, + 108,111,98,97,108,115,114,186,0,0,0,114,95,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 17,95,99,97,108,99,95,95,95,112,97,99,107,97,103,101, + 95,95,30,4,0,0,115,38,0,0,0,0,7,10,1,10, + 1,8,1,18,1,22,2,2,0,2,254,6,3,4,1,8, + 1,6,2,6,2,2,0,2,254,6,3,8,1,8,1,14, + 1,114,219,0,0,0,114,10,0,0,0,99,5,0,0,0, + 0,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0, + 67,0,0,0,115,180,0,0,0,124,4,100,1,107,2,114, + 18,116,0,124,0,131,1,125,5,110,36,124,1,100,2,107, + 9,114,30,124,1,110,2,105,0,125,6,116,1,124,6,131, + 1,125,7,116,0,124,0,124,7,124,4,131,3,125,5,124, + 3,115,150,124,4,100,1,107,2,114,84,116,0,124,0,160, + 2,100,3,161,1,100,1,25,0,131,1,83,0,124,0,115, + 92,124,5,83,0,116,3,124,0,131,1,116,3,124,0,160, + 2,100,3,161,1,100,1,25,0,131,1,24,0,125,8,116, + 4,106,5,124,5,106,6,100,2,116,3,124,5,106,6,131, + 1,124,8,24,0,133,2,25,0,25,0,83,0,110,26,116, + 7,124,5,100,4,131,2,114,172,116,8,124,5,124,3,116, + 0,131,3,83,0,124,5,83,0,100,2,83,0,41,5,97, + 215,1,0,0,73,109,112,111,114,116,32,97,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,84,104,101,32,39,103, + 108,111,98,97,108,115,39,32,97,114,103,117,109,101,110,116, + 32,105,115,32,117,115,101,100,32,116,111,32,105,110,102,101, + 114,32,119,104,101,114,101,32,116,104,101,32,105,109,112,111, + 114,116,32,105,115,32,111,99,99,117,114,114,105,110,103,32, + 102,114,111,109,10,32,32,32,32,116,111,32,104,97,110,100, + 108,101,32,114,101,108,97,116,105,118,101,32,105,109,112,111, + 114,116,115,46,32,84,104,101,32,39,108,111,99,97,108,115, + 39,32,97,114,103,117,109,101,110,116,32,105,115,32,105,103, + 110,111,114,101,100,46,32,84,104,101,10,32,32,32,32,39, + 102,114,111,109,108,105,115,116,39,32,97,114,103,117,109,101, + 110,116,32,115,112,101,99,105,102,105,101,115,32,119,104,97, + 116,32,115,104,111,117,108,100,32,101,120,105,115,116,32,97, + 115,32,97,116,116,114,105,98,117,116,101,115,32,111,110,32, + 116,104,101,32,109,111,100,117,108,101,10,32,32,32,32,98, + 101,105,110,103,32,105,109,112,111,114,116,101,100,32,40,101, + 46,103,46,32,96,96,102,114,111,109,32,109,111,100,117,108, + 101,32,105,109,112,111,114,116,32,60,102,114,111,109,108,105, + 115,116,62,96,96,41,46,32,32,84,104,101,32,39,108,101, + 118,101,108,39,10,32,32,32,32,97,114,103,117,109,101,110, + 116,32,114,101,112,114,101,115,101,110,116,115,32,116,104,101, + 32,112,97,99,107,97,103,101,32,108,111,99,97,116,105,111, + 110,32,116,111,32,105,109,112,111,114,116,32,102,114,111,109, + 32,105,110,32,97,32,114,101,108,97,116,105,118,101,10,32, + 32,32,32,105,109,112,111,114,116,32,40,101,46,103,46,32, + 96,96,102,114,111,109,32,46,46,112,107,103,32,105,109,112, + 111,114,116,32,109,111,100,96,96,32,119,111,117,108,100,32, + 104,97,118,101,32,97,32,39,108,101,118,101,108,39,32,111, + 102,32,50,41,46,10,10,32,32,32,32,114,22,0,0,0, + 78,114,128,0,0,0,114,141,0,0,0,41,9,114,208,0, + 0,0,114,219,0,0,0,218,9,112,97,114,116,105,116,105, + 111,110,114,184,0,0,0,114,15,0,0,0,114,92,0,0, + 0,114,1,0,0,0,114,4,0,0,0,114,213,0,0,0, + 41,9,114,17,0,0,0,114,218,0,0,0,218,6,108,111, + 99,97,108,115,114,214,0,0,0,114,187,0,0,0,114,96, + 0,0,0,90,8,103,108,111,98,97,108,115,95,114,186,0, + 0,0,90,7,99,117,116,95,111,102,102,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,10,95,95,105,109, + 112,111,114,116,95,95,57,4,0,0,115,30,0,0,0,0, + 11,8,1,10,2,16,1,8,1,12,1,4,3,8,1,18, + 1,4,1,4,4,26,3,32,1,10,1,12,2,114,222,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 116,0,160,1,124,0,161,1,125,1,124,1,100,0,107,8, + 114,30,116,2,100,1,124,0,23,0,131,1,130,1,116,3, + 124,1,131,1,83,0,41,2,78,122,25,110,111,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,32,110,97, + 109,101,100,32,41,4,114,160,0,0,0,114,166,0,0,0, + 114,79,0,0,0,114,159,0,0,0,41,2,114,17,0,0, + 0,114,95,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,18,95,98,117,105,108,116,105,110,95, + 102,114,111,109,95,110,97,109,101,94,4,0,0,115,8,0, + 0,0,0,1,10,1,8,1,12,1,114,223,0,0,0,99, + 2,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0, + 5,0,0,0,67,0,0,0,115,166,0,0,0,124,1,97, + 0,124,0,97,1,116,2,116,1,131,1,125,2,116,1,106, + 3,160,4,161,0,68,0,93,72,92,2,125,3,125,4,116, + 5,124,4,124,2,131,2,114,26,124,3,116,1,106,6,107, + 6,114,60,116,7,125,5,110,18,116,0,160,8,124,3,161, + 1,114,26,116,9,125,5,110,2,113,26,116,10,124,4,124, + 5,131,2,125,6,116,11,124,6,124,4,131,2,1,0,113, + 26,116,1,106,3,116,12,25,0,125,7,100,1,68,0,93, + 46,125,8,124,8,116,1,106,3,107,7,114,138,116,13,124, + 8,131,1,125,9,110,10,116,1,106,3,124,8,25,0,125, + 9,116,14,124,7,124,8,124,9,131,3,1,0,113,114,100, + 2,83,0,41,3,122,250,83,101,116,117,112,32,105,109,112, + 111,114,116,108,105,98,32,98,121,32,105,109,112,111,114,116, + 105,110,103,32,110,101,101,100,101,100,32,98,117,105,108,116, + 45,105,110,32,109,111,100,117,108,101,115,32,97,110,100,32, + 105,110,106,101,99,116,105,110,103,32,116,104,101,109,10,32, + 32,32,32,105,110,116,111,32,116,104,101,32,103,108,111,98, + 97,108,32,110,97,109,101,115,112,97,99,101,46,10,10,32, + 32,32,32,65,115,32,115,121,115,32,105,115,32,110,101,101, + 100,101,100,32,102,111,114,32,115,121,115,46,109,111,100,117, + 108,101,115,32,97,99,99,101,115,115,32,97,110,100,32,95, + 105,109,112,32,105,115,32,110,101,101,100,101,100,32,116,111, + 32,108,111,97,100,32,98,117,105,108,116,45,105,110,10,32, + 32,32,32,109,111,100,117,108,101,115,44,32,116,104,111,115, + 101,32,116,119,111,32,109,111,100,117,108,101,115,32,109,117, + 115,116,32,98,101,32,101,120,112,108,105,99,105,116,108,121, + 32,112,97,115,115,101,100,32,105,110,46,10,10,32,32,32, + 32,41,3,114,23,0,0,0,114,192,0,0,0,114,64,0, + 0,0,78,41,15,114,57,0,0,0,114,15,0,0,0,114, + 14,0,0,0,114,92,0,0,0,218,5,105,116,101,109,115, + 114,196,0,0,0,114,78,0,0,0,114,160,0,0,0,114, + 88,0,0,0,114,173,0,0,0,114,142,0,0,0,114,148, + 0,0,0,114,1,0,0,0,114,223,0,0,0,114,5,0, + 0,0,41,10,218,10,115,121,115,95,109,111,100,117,108,101, + 218,11,95,105,109,112,95,109,111,100,117,108,101,90,11,109, + 111,100,117,108,101,95,116,121,112,101,114,17,0,0,0,114, + 96,0,0,0,114,109,0,0,0,114,95,0,0,0,90,11, + 115,101,108,102,95,109,111,100,117,108,101,90,12,98,117,105, + 108,116,105,110,95,110,97,109,101,90,14,98,117,105,108,116, + 105,110,95,109,111,100,117,108,101,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,6,95,115,101,116,117,112, + 101,4,0,0,115,36,0,0,0,0,9,4,1,4,3,8, + 1,18,1,10,1,10,1,6,1,10,1,6,2,2,1,10, + 1,12,3,10,1,8,1,10,1,10,2,10,1,114,227,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 116,0,124,0,124,1,131,2,1,0,116,1,106,2,160,3, + 116,4,161,1,1,0,116,1,106,2,160,3,116,5,161,1, + 1,0,100,1,83,0,41,2,122,48,73,110,115,116,97,108, + 108,32,105,109,112,111,114,116,101,114,115,32,102,111,114,32, + 98,117,105,108,116,105,110,32,97,110,100,32,102,114,111,122, + 101,110,32,109,111,100,117,108,101,115,78,41,6,114,227,0, + 0,0,114,15,0,0,0,114,191,0,0,0,114,120,0,0, + 0,114,160,0,0,0,114,173,0,0,0,41,2,114,225,0, + 0,0,114,226,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,8,95,105,110,115,116,97,108,108, + 136,4,0,0,115,6,0,0,0,0,2,10,2,12,1,114, + 228,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,4,0,0,0,67,0,0,0,115,32,0, + 0,0,100,1,100,2,108,0,125,0,124,0,97,1,124,0, + 160,2,116,3,106,4,116,5,25,0,161,1,1,0,100,2, + 83,0,41,3,122,57,73,110,115,116,97,108,108,32,105,109, + 112,111,114,116,101,114,115,32,116,104,97,116,32,114,101,113, + 117,105,114,101,32,101,120,116,101,114,110,97,108,32,102,105, + 108,101,115,121,115,116,101,109,32,97,99,99,101,115,115,114, + 22,0,0,0,78,41,6,218,26,95,102,114,111,122,101,110, + 95,105,109,112,111,114,116,108,105,98,95,101,120,116,101,114, + 110,97,108,114,126,0,0,0,114,228,0,0,0,114,15,0, + 0,0,114,92,0,0,0,114,1,0,0,0,41,1,114,229, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,27,95,105,110,115,116,97,108,108,95,101,120,116, + 101,114,110,97,108,95,105,109,112,111,114,116,101,114,115,144, + 4,0,0,115,6,0,0,0,0,3,8,1,4,1,114,230, + 0,0,0,41,2,78,78,41,1,78,41,2,78,114,22,0, + 0,0,41,4,78,78,114,10,0,0,0,114,22,0,0,0, + 41,50,114,3,0,0,0,114,126,0,0,0,114,12,0,0, + 0,114,18,0,0,0,114,60,0,0,0,114,33,0,0,0, + 114,42,0,0,0,114,19,0,0,0,114,20,0,0,0,114, + 49,0,0,0,114,50,0,0,0,114,53,0,0,0,114,65, + 0,0,0,114,67,0,0,0,114,76,0,0,0,114,86,0, + 0,0,114,90,0,0,0,114,97,0,0,0,114,111,0,0, + 0,114,112,0,0,0,114,91,0,0,0,114,142,0,0,0, + 114,148,0,0,0,114,152,0,0,0,114,107,0,0,0,114, + 93,0,0,0,114,158,0,0,0,114,159,0,0,0,114,94, + 0,0,0,114,160,0,0,0,114,173,0,0,0,114,178,0, + 0,0,114,188,0,0,0,114,190,0,0,0,114,195,0,0, + 0,114,200,0,0,0,90,15,95,69,82,82,95,77,83,71, + 95,80,82,69,70,73,88,114,202,0,0,0,114,205,0,0, + 0,218,6,111,98,106,101,99,116,114,206,0,0,0,114,207, + 0,0,0,114,208,0,0,0,114,213,0,0,0,114,219,0, + 0,0,114,222,0,0,0,114,223,0,0,0,114,227,0,0, + 0,114,228,0,0,0,114,230,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 8,60,109,111,100,117,108,101,62,1,0,0,0,115,94,0, + 0,0,4,24,4,2,8,8,8,8,4,2,4,3,16,4, + 14,68,14,21,14,16,8,37,8,17,8,11,14,8,8,11, + 8,12,8,16,8,36,14,101,16,26,10,45,14,72,8,17, + 8,17,8,30,8,37,8,42,8,15,14,73,14,79,14,13, + 8,9,8,9,10,47,8,16,4,1,8,2,8,27,6,3, + 8,16,10,15,14,37,8,27,10,37,8,7,8,35,8,8, +}; diff --git a/python/Python/importlib_external.h b/python/Python/importlib_external.h new file mode 100755 index 0000000..3327c33 --- /dev/null +++ b/python/Python/importlib_external.h @@ -0,0 +1,2826 @@ +/* Auto-generated by Programs/_freeze_importlib.c */ +const unsigned char _Py_M__importlib_bootstrap_external[] = { + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,64,0,0,0,115,224,2,0,0,100,0, + 90,0,100,1,100,2,108,1,97,1,100,1,100,2,108,2, + 90,2,100,1,100,2,108,3,97,3,100,1,100,2,108,4, + 90,4,100,1,100,2,108,5,90,5,116,3,106,6,100,3, + 107,2,90,7,101,7,114,76,100,1,100,2,108,8,90,9, + 100,1,100,2,108,10,90,10,110,8,100,1,100,2,108,11, + 90,9,101,7,114,98,100,4,100,5,103,2,90,12,110,6, + 100,5,103,1,90,12,101,13,100,6,100,7,132,0,101,12, + 68,0,131,1,131,1,115,126,116,14,130,1,101,12,100,1, + 25,0,90,15,101,16,101,12,131,1,90,17,100,8,160,18, + 101,12,161,1,90,12,100,9,100,10,132,0,101,12,68,0, + 131,1,90,19,100,11,90,20,100,12,90,21,101,21,101,20, + 23,0,90,22,100,13,100,14,132,0,90,23,100,15,100,16, + 132,0,90,24,100,17,100,18,132,0,90,25,100,19,100,20, + 132,0,90,26,101,7,114,228,100,21,100,22,132,0,90,27, + 110,8,100,23,100,22,132,0,90,27,100,24,100,25,132,0, + 90,28,100,26,100,27,132,0,90,29,100,28,100,29,132,0, + 90,30,100,30,100,31,132,0,90,31,100,32,100,33,132,0, + 90,32,101,7,144,1,114,36,100,34,100,35,132,0,90,33, + 110,8,100,36,100,35,132,0,90,33,100,111,100,38,100,39, + 132,1,90,34,101,35,101,34,106,36,131,1,90,37,100,40, + 160,38,100,41,100,42,161,2,100,43,23,0,90,39,101,40, + 160,41,101,39,100,42,161,2,90,42,100,44,90,43,100,45, + 90,44,100,46,103,1,90,45,100,47,103,1,90,46,101,46, + 4,0,90,47,90,48,100,112,100,2,100,48,156,1,100,49, + 100,50,132,3,90,49,100,51,100,52,132,0,90,50,100,53, + 100,54,132,0,90,51,100,55,100,56,132,0,90,52,100,57, + 100,58,132,0,90,53,100,59,100,60,132,0,90,54,100,61, + 100,62,132,0,90,55,100,63,100,64,132,0,90,56,100,65, + 100,66,132,0,90,57,100,67,100,68,132,0,90,58,100,113, + 100,69,100,70,132,1,90,59,100,114,100,71,100,72,132,1, + 90,60,100,115,100,74,100,75,132,1,90,61,100,76,100,77, + 132,0,90,62,101,63,131,0,90,64,100,116,100,2,101,64, + 100,78,156,2,100,79,100,80,132,3,90,65,71,0,100,81, + 100,82,132,0,100,82,131,2,90,66,71,0,100,83,100,84, + 132,0,100,84,131,2,90,67,71,0,100,85,100,86,132,0, + 100,86,101,67,131,3,90,68,71,0,100,87,100,88,132,0, + 100,88,131,2,90,69,71,0,100,89,100,90,132,0,100,90, + 101,69,101,68,131,4,90,70,71,0,100,91,100,92,132,0, + 100,92,101,69,101,67,131,4,90,71,103,0,90,72,71,0, + 100,93,100,94,132,0,100,94,101,69,101,67,131,4,90,73, + 71,0,100,95,100,96,132,0,100,96,131,2,90,74,71,0, + 100,97,100,98,132,0,100,98,131,2,90,75,71,0,100,99, + 100,100,132,0,100,100,131,2,90,76,71,0,100,101,100,102, + 132,0,100,102,131,2,90,77,100,117,100,103,100,104,132,1, + 90,78,100,105,100,106,132,0,90,79,100,107,100,108,132,0, + 90,80,100,109,100,110,132,0,90,81,100,2,83,0,41,118, + 97,94,1,0,0,67,111,114,101,32,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,32,111,102,32,112,97,116,104, + 45,98,97,115,101,100,32,105,109,112,111,114,116,46,10,10, + 84,104,105,115,32,109,111,100,117,108,101,32,105,115,32,78, + 79,84,32,109,101,97,110,116,32,116,111,32,98,101,32,100, + 105,114,101,99,116,108,121,32,105,109,112,111,114,116,101,100, + 33,32,73,116,32,104,97,115,32,98,101,101,110,32,100,101, + 115,105,103,110,101,100,32,115,117,99,104,10,116,104,97,116, + 32,105,116,32,99,97,110,32,98,101,32,98,111,111,116,115, + 116,114,97,112,112,101,100,32,105,110,116,111,32,80,121,116, + 104,111,110,32,97,115,32,116,104,101,32,105,109,112,108,101, + 109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,112, + 111,114,116,46,32,65,115,10,115,117,99,104,32,105,116,32, + 114,101,113,117,105,114,101,115,32,116,104,101,32,105,110,106, + 101,99,116,105,111,110,32,111,102,32,115,112,101,99,105,102, + 105,99,32,109,111,100,117,108,101,115,32,97,110,100,32,97, + 116,116,114,105,98,117,116,101,115,32,105,110,32,111,114,100, + 101,114,32,116,111,10,119,111,114,107,46,32,79,110,101,32, + 115,104,111,117,108,100,32,117,115,101,32,105,109,112,111,114, + 116,108,105,98,32,97,115,32,116,104,101,32,112,117,98,108, + 105,99,45,102,97,99,105,110,103,32,118,101,114,115,105,111, + 110,32,111,102,32,116,104,105,115,32,109,111,100,117,108,101, + 46,10,10,233,0,0,0,0,78,90,5,119,105,110,51,50, + 250,1,92,250,1,47,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,99,0,0,0,115, + 26,0,0,0,124,0,93,18,125,1,116,0,124,1,131,1, + 100,0,107,2,86,0,1,0,113,2,100,1,83,0,169,2, + 233,1,0,0,0,78,169,1,218,3,108,101,110,169,2,218, + 2,46,48,218,3,115,101,112,169,0,114,10,0,0,0,250, + 38,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, + 105,98,46,95,98,111,111,116,115,116,114,97,112,95,101,120, + 116,101,114,110,97,108,62,218,9,60,103,101,110,101,120,112, + 114,62,43,0,0,0,115,4,0,0,0,4,0,2,0,114, + 12,0,0,0,218,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, + 22,0,0,0,104,0,124,0,93,14,125,1,100,0,124,1, + 155,0,157,2,146,2,113,4,83,0,169,1,250,1,58,114, + 10,0,0,0,169,2,114,8,0,0,0,218,1,115,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,9,60, + 115,101,116,99,111,109,112,62,47,0,0,0,115,4,0,0, + 0,6,0,2,0,114,18,0,0,0,41,1,218,3,119,105, + 110,41,2,90,6,99,121,103,119,105,110,90,6,100,97,114, + 119,105,110,99,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,3,0,0,0,115,60,0,0, + 0,116,0,106,1,160,2,116,3,161,1,114,48,116,0,106, + 1,160,2,116,4,161,1,114,30,100,1,137,0,110,4,100, + 2,137,0,135,0,102,1,100,3,100,4,132,8,125,0,110, + 8,100,5,100,4,132,0,125,0,124,0,83,0,41,6,78, + 90,12,80,89,84,72,79,78,67,65,83,69,79,75,115,12, + 0,0,0,80,89,84,72,79,78,67,65,83,69,79,75,99, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,19,0,0,0,115,10,0,0,0,136,0,116, + 0,106,1,107,6,83,0,41,1,250,53,84,114,117,101,32, + 105,102,32,102,105,108,101,110,97,109,101,115,32,109,117,115, + 116,32,98,101,32,99,104,101,99,107,101,100,32,99,97,115, + 101,45,105,110,115,101,110,115,105,116,105,118,101,108,121,46, + 41,2,218,3,95,111,115,90,7,101,110,118,105,114,111,110, + 114,10,0,0,0,169,1,218,3,107,101,121,114,10,0,0, + 0,114,11,0,0,0,218,11,95,114,101,108,97,120,95,99, + 97,115,101,64,0,0,0,115,2,0,0,0,0,2,122,37, + 95,109,97,107,101,95,114,101,108,97,120,95,99,97,115,101, + 46,60,108,111,99,97,108,115,62,46,95,114,101,108,97,120, + 95,99,97,115,101,99,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,83,0,0,0,115,4, + 0,0,0,100,1,83,0,41,2,114,20,0,0,0,70,114, + 10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,24,0,0,0,68,0,0, + 0,115,2,0,0,0,0,2,41,5,218,3,115,121,115,218, + 8,112,108,97,116,102,111,114,109,218,10,115,116,97,114,116, + 115,119,105,116,104,218,27,95,67,65,83,69,95,73,78,83, + 69,78,83,73,84,73,86,69,95,80,76,65,84,70,79,82, + 77,83,218,35,95,67,65,83,69,95,73,78,83,69,78,83, + 73,84,73,86,69,95,80,76,65,84,70,79,82,77,83,95, + 83,84,82,95,75,69,89,41,1,114,24,0,0,0,114,10, + 0,0,0,114,22,0,0,0,114,11,0,0,0,218,16,95, + 109,97,107,101,95,114,101,108,97,120,95,99,97,115,101,57, + 0,0,0,115,14,0,0,0,0,1,12,1,12,1,6,2, + 4,2,14,4,8,3,114,30,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, + 67,0,0,0,115,20,0,0,0,116,0,124,0,131,1,100, + 1,64,0,160,1,100,2,100,3,161,2,83,0,41,4,122, + 42,67,111,110,118,101,114,116,32,97,32,51,50,45,98,105, + 116,32,105,110,116,101,103,101,114,32,116,111,32,108,105,116, + 116,108,101,45,101,110,100,105,97,110,46,236,3,0,0,0, + 255,127,255,127,3,0,233,4,0,0,0,218,6,108,105,116, + 116,108,101,41,2,218,3,105,110,116,218,8,116,111,95,98, + 121,116,101,115,41,1,218,1,120,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,12,95,112,97,99,107,95, + 117,105,110,116,51,50,74,0,0,0,115,2,0,0,0,0, + 2,114,37,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,4,0,0,0,67,0,0,0,115, + 28,0,0,0,116,0,124,0,131,1,100,1,107,2,115,16, + 116,1,130,1,116,2,160,3,124,0,100,2,161,2,83,0, + 41,3,122,47,67,111,110,118,101,114,116,32,52,32,98,121, + 116,101,115,32,105,110,32,108,105,116,116,108,101,45,101,110, + 100,105,97,110,32,116,111,32,97,110,32,105,110,116,101,103, + 101,114,46,114,32,0,0,0,114,33,0,0,0,169,4,114, + 6,0,0,0,218,14,65,115,115,101,114,116,105,111,110,69, + 114,114,111,114,114,34,0,0,0,218,10,102,114,111,109,95, + 98,121,116,101,115,169,1,218,4,100,97,116,97,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,14,95,117, + 110,112,97,99,107,95,117,105,110,116,51,50,79,0,0,0, + 115,4,0,0,0,0,2,16,1,114,43,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4, + 0,0,0,67,0,0,0,115,28,0,0,0,116,0,124,0, + 131,1,100,1,107,2,115,16,116,1,130,1,116,2,160,3, + 124,0,100,2,161,2,83,0,41,3,122,47,67,111,110,118, + 101,114,116,32,50,32,98,121,116,101,115,32,105,110,32,108, + 105,116,116,108,101,45,101,110,100,105,97,110,32,116,111,32, + 97,110,32,105,110,116,101,103,101,114,46,233,2,0,0,0, + 114,33,0,0,0,114,38,0,0,0,114,41,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,14, + 95,117,110,112,97,99,107,95,117,105,110,116,49,54,84,0, + 0,0,115,4,0,0,0,0,2,16,1,114,45,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,4,0,0,0,71,0,0,0,115,228,0,0,0,124,0, + 115,8,100,1,83,0,116,0,124,0,131,1,100,2,107,2, + 114,28,124,0,100,3,25,0,83,0,100,1,125,1,103,0, + 125,2,116,1,116,2,106,3,124,0,131,2,68,0,93,122, + 92,2,125,3,125,4,124,3,160,4,116,5,161,1,115,76, + 124,3,160,6,116,5,161,1,114,102,124,3,160,7,116,8, + 161,1,112,88,124,1,125,1,116,9,124,4,23,0,103,1, + 125,2,113,48,124,3,160,6,100,4,161,1,114,152,124,1, + 160,10,161,0,124,3,160,10,161,0,107,3,114,140,124,3, + 125,1,124,4,103,1,125,2,113,170,124,2,160,11,124,4, + 161,1,1,0,113,48,124,3,112,158,124,1,125,1,124,2, + 160,11,124,4,161,1,1,0,113,48,100,5,100,6,132,0, + 124,2,68,0,131,1,125,2,116,0,124,2,131,1,100,2, + 107,2,114,214,124,2,100,3,25,0,115,214,124,1,116,9, + 23,0,83,0,124,1,116,9,160,12,124,2,161,1,23,0, + 83,0,41,7,250,31,82,101,112,108,97,99,101,109,101,110, + 116,32,102,111,114,32,111,115,46,112,97,116,104,46,106,111, + 105,110,40,41,46,114,13,0,0,0,114,4,0,0,0,114, + 0,0,0,0,114,15,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,5,0,0,0,83,0, + 0,0,115,26,0,0,0,103,0,124,0,93,18,125,1,124, + 1,114,4,124,1,160,0,116,1,161,1,145,2,113,4,83, + 0,114,10,0,0,0,169,2,218,6,114,115,116,114,105,112, + 218,15,112,97,116,104,95,115,101,112,97,114,97,116,111,114, + 115,169,2,114,8,0,0,0,218,1,112,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,10,60,108,105,115, + 116,99,111,109,112,62,114,0,0,0,115,6,0,0,0,6, + 0,2,0,4,0,250,30,95,112,97,116,104,95,106,111,105, + 110,46,60,108,111,99,97,108,115,62,46,60,108,105,115,116, + 99,111,109,112,62,41,13,114,6,0,0,0,218,3,109,97, + 112,114,21,0,0,0,218,15,95,112,97,116,104,95,115,112, + 108,105,116,114,111,111,116,114,27,0,0,0,218,14,112,97, + 116,104,95,115,101,112,95,116,117,112,108,101,218,8,101,110, + 100,115,119,105,116,104,114,48,0,0,0,114,49,0,0,0, + 218,8,112,97,116,104,95,115,101,112,218,8,99,97,115,101, + 102,111,108,100,218,6,97,112,112,101,110,100,218,4,106,111, + 105,110,41,5,218,10,112,97,116,104,95,112,97,114,116,115, + 218,4,114,111,111,116,218,4,112,97,116,104,90,8,110,101, + 119,95,114,111,111,116,218,4,116,97,105,108,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,10,95,112,97, + 116,104,95,106,111,105,110,91,0,0,0,115,42,0,0,0, + 0,2,4,1,4,1,12,1,8,1,4,1,4,1,20,1, + 20,1,14,1,12,1,10,1,16,3,4,1,8,2,12,2, + 8,1,12,1,14,1,20,2,8,1,114,66,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 4,0,0,0,71,0,0,0,115,20,0,0,0,116,0,160, + 1,100,1,100,2,132,0,124,0,68,0,131,1,161,1,83, + 0,41,3,114,46,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,5,0,0,0,83,0,0, + 0,115,26,0,0,0,103,0,124,0,93,18,125,1,124,1, + 114,4,124,1,160,0,116,1,161,1,145,2,113,4,83,0, + 114,10,0,0,0,114,47,0,0,0,41,2,114,8,0,0, + 0,218,4,112,97,114,116,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,52,0,0,0,123,0,0,0,115, + 6,0,0,0,6,1,2,0,4,255,114,53,0,0,0,41, + 2,114,58,0,0,0,114,61,0,0,0,41,1,114,62,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,66,0,0,0,121,0,0,0,115,6,0,0,0,0, + 2,10,1,2,255,99,1,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,4,0,0,0,3,0,0,0,115,66, + 0,0,0,116,0,135,0,102,1,100,1,100,2,132,8,116, + 1,68,0,131,1,131,1,125,1,124,1,100,3,107,0,114, + 38,100,4,136,0,102,2,83,0,136,0,100,5,124,1,133, + 2,25,0,136,0,124,1,100,6,23,0,100,5,133,2,25, + 0,102,2,83,0,41,7,122,32,82,101,112,108,97,99,101, + 109,101,110,116,32,102,111,114,32,111,115,46,112,97,116,104, + 46,115,112,108,105,116,40,41,46,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,4,0,0,0,51,0, + 0,0,115,24,0,0,0,124,0,93,16,125,1,136,0,160, + 0,124,1,161,1,86,0,1,0,113,2,100,0,83,0,169, + 1,78,41,1,218,5,114,102,105,110,100,114,50,0,0,0, + 169,1,114,64,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,12,0,0,0,129,0,0,0,115,4,0,0,0,4, + 0,2,0,122,30,95,112,97,116,104,95,115,112,108,105,116, + 46,60,108,111,99,97,108,115,62,46,60,103,101,110,101,120, + 112,114,62,114,0,0,0,0,114,13,0,0,0,78,114,4, + 0,0,0,41,2,218,3,109,97,120,114,49,0,0,0,41, + 2,114,64,0,0,0,218,1,105,114,10,0,0,0,114,70, + 0,0,0,114,11,0,0,0,218,11,95,112,97,116,104,95, + 115,112,108,105,116,127,0,0,0,115,8,0,0,0,0,2, + 22,1,8,1,8,1,114,73,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, + 67,0,0,0,115,10,0,0,0,116,0,160,1,124,0,161, + 1,83,0,41,1,122,126,83,116,97,116,32,116,104,101,32, + 112,97,116,104,46,10,10,32,32,32,32,77,97,100,101,32, + 97,32,115,101,112,97,114,97,116,101,32,102,117,110,99,116, + 105,111,110,32,116,111,32,109,97,107,101,32,105,116,32,101, + 97,115,105,101,114,32,116,111,32,111,118,101,114,114,105,100, + 101,32,105,110,32,101,120,112,101,114,105,109,101,110,116,115, + 10,32,32,32,32,40,101,46,103,46,32,99,97,99,104,101, + 32,115,116,97,116,32,114,101,115,117,108,116,115,41,46,10, + 10,32,32,32,32,41,2,114,21,0,0,0,90,4,115,116, + 97,116,114,70,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,10,95,112,97,116,104,95,115,116, + 97,116,135,0,0,0,115,2,0,0,0,0,7,114,74,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,8,0,0,0,67,0,0,0,115,50,0,0,0, + 122,12,116,0,124,0,131,1,125,2,87,0,110,22,4,0, + 116,1,107,10,114,34,1,0,1,0,1,0,89,0,100,1, + 83,0,88,0,124,2,106,2,100,2,64,0,124,1,107,2, + 83,0,41,3,122,49,84,101,115,116,32,119,104,101,116,104, + 101,114,32,116,104,101,32,112,97,116,104,32,105,115,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 101,32,116,121,112,101,46,70,105,0,240,0,0,41,3,114, + 74,0,0,0,218,7,79,83,69,114,114,111,114,218,7,115, + 116,95,109,111,100,101,41,3,114,64,0,0,0,218,4,109, + 111,100,101,90,9,115,116,97,116,95,105,110,102,111,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, + 112,97,116,104,95,105,115,95,109,111,100,101,95,116,121,112, + 101,145,0,0,0,115,10,0,0,0,0,2,2,1,12,1, + 14,1,8,1,114,78,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,10,0,0,0,116,0,124,0,100,1,131,2,83, + 0,41,2,122,31,82,101,112,108,97,99,101,109,101,110,116, + 32,102,111,114,32,111,115,46,112,97,116,104,46,105,115,102, + 105,108,101,46,105,0,128,0,0,41,1,114,78,0,0,0, + 114,70,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,12,95,112,97,116,104,95,105,115,102,105, + 108,101,154,0,0,0,115,2,0,0,0,0,2,114,79,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,22,0,0,0, + 124,0,115,12,116,0,160,1,161,0,125,0,116,2,124,0, + 100,1,131,2,83,0,41,2,122,30,82,101,112,108,97,99, + 101,109,101,110,116,32,102,111,114,32,111,115,46,112,97,116, + 104,46,105,115,100,105,114,46,105,0,64,0,0,41,3,114, + 21,0,0,0,218,6,103,101,116,99,119,100,114,78,0,0, + 0,114,70,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,11,95,112,97,116,104,95,105,115,100, + 105,114,159,0,0,0,115,6,0,0,0,0,2,4,1,8, + 1,114,81,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, + 62,0,0,0,124,0,115,8,100,1,83,0,116,0,160,1, + 124,0,161,1,100,2,25,0,160,2,100,3,100,4,161,2, + 125,1,116,3,124,1,131,1,100,5,107,4,111,60,124,1, + 160,4,100,6,161,1,112,60,124,1,160,5,100,4,161,1, + 83,0,41,7,250,30,82,101,112,108,97,99,101,109,101,110, + 116,32,102,111,114,32,111,115,46,112,97,116,104,46,105,115, + 97,98,115,46,70,114,0,0,0,0,114,2,0,0,0,114, + 1,0,0,0,114,4,0,0,0,122,2,92,92,41,6,114, + 21,0,0,0,114,55,0,0,0,218,7,114,101,112,108,97, + 99,101,114,6,0,0,0,114,27,0,0,0,114,57,0,0, + 0,41,2,114,64,0,0,0,114,63,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,11,95,112, + 97,116,104,95,105,115,97,98,115,167,0,0,0,115,8,0, + 0,0,0,2,4,1,4,1,22,1,114,84,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,10,0,0,0,124,0,160, + 0,116,1,161,1,83,0,41,1,114,82,0,0,0,41,2, + 114,27,0,0,0,114,49,0,0,0,114,70,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,84, + 0,0,0,175,0,0,0,115,2,0,0,0,0,2,233,182, + 1,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, + 6,0,0,0,11,0,0,0,67,0,0,0,115,162,0,0, + 0,100,1,160,0,124,0,116,1,124,0,131,1,161,2,125, + 3,116,2,160,3,124,3,116,2,106,4,116,2,106,5,66, + 0,116,2,106,6,66,0,124,2,100,2,64,0,161,3,125, + 4,122,50,116,7,160,8,124,4,100,3,161,2,143,16,125, + 5,124,5,160,9,124,1,161,1,1,0,87,0,53,0,81, + 0,82,0,88,0,116,2,160,10,124,3,124,0,161,2,1, + 0,87,0,110,58,4,0,116,11,107,10,114,156,1,0,1, + 0,1,0,122,14,116,2,160,12,124,3,161,1,1,0,87, + 0,110,20,4,0,116,11,107,10,114,148,1,0,1,0,1, + 0,89,0,110,2,88,0,130,0,89,0,110,2,88,0,100, + 4,83,0,41,5,122,162,66,101,115,116,45,101,102,102,111, + 114,116,32,102,117,110,99,116,105,111,110,32,116,111,32,119, + 114,105,116,101,32,100,97,116,97,32,116,111,32,97,32,112, + 97,116,104,32,97,116,111,109,105,99,97,108,108,121,46,10, + 32,32,32,32,66,101,32,112,114,101,112,97,114,101,100,32, + 116,111,32,104,97,110,100,108,101,32,97,32,70,105,108,101, + 69,120,105,115,116,115,69,114,114,111,114,32,105,102,32,99, + 111,110,99,117,114,114,101,110,116,32,119,114,105,116,105,110, + 103,32,111,102,32,116,104,101,10,32,32,32,32,116,101,109, + 112,111,114,97,114,121,32,102,105,108,101,32,105,115,32,97, + 116,116,101,109,112,116,101,100,46,250,5,123,125,46,123,125, + 114,85,0,0,0,90,2,119,98,78,41,13,218,6,102,111, + 114,109,97,116,218,2,105,100,114,21,0,0,0,90,4,111, + 112,101,110,90,6,79,95,69,88,67,76,90,7,79,95,67, + 82,69,65,84,90,8,79,95,87,82,79,78,76,89,218,3, + 95,105,111,218,6,70,105,108,101,73,79,218,5,119,114,105, + 116,101,114,83,0,0,0,114,75,0,0,0,90,6,117,110, + 108,105,110,107,41,6,114,64,0,0,0,114,42,0,0,0, + 114,77,0,0,0,90,8,112,97,116,104,95,116,109,112,90, + 2,102,100,218,4,102,105,108,101,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,13,95,119,114,105,116,101, + 95,97,116,111,109,105,99,180,0,0,0,115,30,0,0,0, + 0,5,16,1,6,1,16,0,6,255,4,2,2,3,14,1, + 20,1,16,1,14,1,2,1,14,1,14,1,6,1,114,93, + 0,0,0,105,85,13,0,0,114,44,0,0,0,114,33,0, + 0,0,115,2,0,0,0,13,10,90,11,95,95,112,121,99, + 97,99,104,101,95,95,122,4,111,112,116,45,122,3,46,112, + 121,122,4,46,112,121,99,41,1,218,12,111,112,116,105,109, + 105,122,97,116,105,111,110,99,2,0,0,0,0,0,0,0, + 1,0,0,0,12,0,0,0,5,0,0,0,67,0,0,0, + 115,88,1,0,0,124,1,100,1,107,9,114,52,116,0,160, + 1,100,2,116,2,161,2,1,0,124,2,100,1,107,9,114, + 40,100,3,125,3,116,3,124,3,131,1,130,1,124,1,114, + 48,100,4,110,2,100,5,125,2,116,4,160,5,124,0,161, + 1,125,0,116,6,124,0,131,1,92,2,125,4,125,5,124, + 5,160,7,100,6,161,1,92,3,125,6,125,7,125,8,116, + 8,106,9,106,10,125,9,124,9,100,1,107,8,114,114,116, + 11,100,7,131,1,130,1,100,4,160,12,124,6,114,126,124, + 6,110,2,124,8,124,7,124,9,103,3,161,1,125,10,124, + 2,100,1,107,8,114,172,116,8,106,13,106,14,100,8,107, + 2,114,164,100,4,125,2,110,8,116,8,106,13,106,14,125, + 2,116,15,124,2,131,1,125,2,124,2,100,4,107,3,114, + 224,124,2,160,16,161,0,115,210,116,17,100,9,160,18,124, + 2,161,1,131,1,130,1,100,10,160,18,124,10,116,19,124, + 2,161,3,125,10,124,10,116,20,100,8,25,0,23,0,125, + 11,116,8,106,21,100,1,107,9,144,1,114,76,116,22,124, + 4,131,1,144,1,115,16,116,23,116,4,160,24,161,0,124, + 4,131,2,125,4,124,4,100,5,25,0,100,11,107,2,144, + 1,114,56,124,4,100,8,25,0,116,25,107,7,144,1,114, + 56,124,4,100,12,100,1,133,2,25,0,125,4,116,23,116, + 8,106,21,124,4,160,26,116,25,161,1,124,11,131,3,83, + 0,116,23,124,4,116,27,124,11,131,3,83,0,41,13,97, + 254,2,0,0,71,105,118,101,110,32,116,104,101,32,112,97, + 116,104,32,116,111,32,97,32,46,112,121,32,102,105,108,101, + 44,32,114,101,116,117,114,110,32,116,104,101,32,112,97,116, + 104,32,116,111,32,105,116,115,32,46,112,121,99,32,102,105, + 108,101,46,10,10,32,32,32,32,84,104,101,32,46,112,121, + 32,102,105,108,101,32,100,111,101,115,32,110,111,116,32,110, + 101,101,100,32,116,111,32,101,120,105,115,116,59,32,116,104, + 105,115,32,115,105,109,112,108,121,32,114,101,116,117,114,110, + 115,32,116,104,101,32,112,97,116,104,32,116,111,32,116,104, + 101,10,32,32,32,32,46,112,121,99,32,102,105,108,101,32, + 99,97,108,99,117,108,97,116,101,100,32,97,115,32,105,102, + 32,116,104,101,32,46,112,121,32,102,105,108,101,32,119,101, + 114,101,32,105,109,112,111,114,116,101,100,46,10,10,32,32, + 32,32,84,104,101,32,39,111,112,116,105,109,105,122,97,116, + 105,111,110,39,32,112,97,114,97,109,101,116,101,114,32,99, + 111,110,116,114,111,108,115,32,116,104,101,32,112,114,101,115, + 117,109,101,100,32,111,112,116,105,109,105,122,97,116,105,111, + 110,32,108,101,118,101,108,32,111,102,10,32,32,32,32,116, + 104,101,32,98,121,116,101,99,111,100,101,32,102,105,108,101, + 46,32,73,102,32,39,111,112,116,105,109,105,122,97,116,105, + 111,110,39,32,105,115,32,110,111,116,32,78,111,110,101,44, + 32,116,104,101,32,115,116,114,105,110,103,32,114,101,112,114, + 101,115,101,110,116,97,116,105,111,110,10,32,32,32,32,111, + 102,32,116,104,101,32,97,114,103,117,109,101,110,116,32,105, + 115,32,116,97,107,101,110,32,97,110,100,32,118,101,114,105, + 102,105,101,100,32,116,111,32,98,101,32,97,108,112,104,97, + 110,117,109,101,114,105,99,32,40,101,108,115,101,32,86,97, + 108,117,101,69,114,114,111,114,10,32,32,32,32,105,115,32, + 114,97,105,115,101,100,41,46,10,10,32,32,32,32,84,104, + 101,32,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 32,112,97,114,97,109,101,116,101,114,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,73,102,32,100,101,98, + 117,103,95,111,118,101,114,114,105,100,101,32,105,115,32,110, + 111,116,32,78,111,110,101,44,10,32,32,32,32,97,32,84, + 114,117,101,32,118,97,108,117,101,32,105,115,32,116,104,101, + 32,115,97,109,101,32,97,115,32,115,101,116,116,105,110,103, + 32,39,111,112,116,105,109,105,122,97,116,105,111,110,39,32, + 116,111,32,116,104,101,32,101,109,112,116,121,32,115,116,114, + 105,110,103,10,32,32,32,32,119,104,105,108,101,32,97,32, + 70,97,108,115,101,32,118,97,108,117,101,32,105,115,32,101, + 113,117,105,118,97,108,101,110,116,32,116,111,32,115,101,116, + 116,105,110,103,32,39,111,112,116,105,109,105,122,97,116,105, + 111,110,39,32,116,111,32,39,49,39,46,10,10,32,32,32, + 32,73,102,32,115,121,115,46,105,109,112,108,101,109,101,110, + 116,97,116,105,111,110,46,99,97,99,104,101,95,116,97,103, + 32,105,115,32,78,111,110,101,32,116,104,101,110,32,78,111, + 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111, + 114,32,105,115,32,114,97,105,115,101,100,46,10,10,32,32, + 32,32,78,122,70,116,104,101,32,100,101,98,117,103,95,111, + 118,101,114,114,105,100,101,32,112,97,114,97,109,101,116,101, + 114,32,105,115,32,100,101,112,114,101,99,97,116,101,100,59, + 32,117,115,101,32,39,111,112,116,105,109,105,122,97,116,105, + 111,110,39,32,105,110,115,116,101,97,100,122,50,100,101,98, + 117,103,95,111,118,101,114,114,105,100,101,32,111,114,32,111, + 112,116,105,109,105,122,97,116,105,111,110,32,109,117,115,116, + 32,98,101,32,115,101,116,32,116,111,32,78,111,110,101,114, + 13,0,0,0,114,4,0,0,0,218,1,46,250,36,115,121, + 115,46,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 46,99,97,99,104,101,95,116,97,103,32,105,115,32,78,111, + 110,101,114,0,0,0,0,122,24,123,33,114,125,32,105,115, + 32,110,111,116,32,97,108,112,104,97,110,117,109,101,114,105, + 99,122,7,123,125,46,123,125,123,125,114,15,0,0,0,114, + 44,0,0,0,41,28,218,9,95,119,97,114,110,105,110,103, + 115,218,4,119,97,114,110,218,18,68,101,112,114,101,99,97, + 116,105,111,110,87,97,114,110,105,110,103,218,9,84,121,112, + 101,69,114,114,111,114,114,21,0,0,0,218,6,102,115,112, + 97,116,104,114,73,0,0,0,218,10,114,112,97,114,116,105, + 116,105,111,110,114,25,0,0,0,218,14,105,109,112,108,101, + 109,101,110,116,97,116,105,111,110,218,9,99,97,99,104,101, + 95,116,97,103,218,19,78,111,116,73,109,112,108,101,109,101, + 110,116,101,100,69,114,114,111,114,114,61,0,0,0,218,5, + 102,108,97,103,115,218,8,111,112,116,105,109,105,122,101,218, + 3,115,116,114,218,7,105,115,97,108,110,117,109,218,10,86, + 97,108,117,101,69,114,114,111,114,114,87,0,0,0,218,4, + 95,79,80,84,218,17,66,89,84,69,67,79,68,69,95,83, + 85,70,70,73,88,69,83,218,14,112,121,99,97,99,104,101, + 95,112,114,101,102,105,120,114,84,0,0,0,114,66,0,0, + 0,114,80,0,0,0,114,49,0,0,0,218,6,108,115,116, + 114,105,112,218,8,95,80,89,67,65,67,72,69,41,12,114, + 64,0,0,0,90,14,100,101,98,117,103,95,111,118,101,114, + 114,105,100,101,114,94,0,0,0,218,7,109,101,115,115,97, + 103,101,218,4,104,101,97,100,114,65,0,0,0,90,4,98, + 97,115,101,114,9,0,0,0,218,4,114,101,115,116,90,3, + 116,97,103,90,15,97,108,109,111,115,116,95,102,105,108,101, + 110,97,109,101,218,8,102,105,108,101,110,97,109,101,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,17,99, + 97,99,104,101,95,102,114,111,109,95,115,111,117,114,99,101, + 98,1,0,0,115,72,0,0,0,0,18,8,1,6,1,2, + 255,4,2,8,1,4,1,8,1,12,1,10,1,12,1,16, + 1,8,1,8,1,8,1,24,1,8,1,12,1,6,2,8, + 1,8,1,8,1,8,1,14,1,14,1,12,1,12,9,10, + 1,14,5,28,1,12,4,2,1,4,1,8,1,2,253,4, + 5,114,120,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,10,0,0,0,5,0,0,0,67,0,0,0,115, + 46,1,0,0,116,0,106,1,106,2,100,1,107,8,114,20, + 116,3,100,2,131,1,130,1,116,4,160,5,124,0,161,1, + 125,0,116,6,124,0,131,1,92,2,125,1,125,2,100,3, + 125,3,116,0,106,7,100,1,107,9,114,102,116,0,106,7, + 160,8,116,9,161,1,125,4,124,1,160,10,124,4,116,11, + 23,0,161,1,114,102,124,1,116,12,124,4,131,1,100,1, + 133,2,25,0,125,1,100,4,125,3,124,3,115,144,116,6, + 124,1,131,1,92,2,125,1,125,5,124,5,116,13,107,3, + 114,144,116,14,116,13,155,0,100,5,124,0,155,2,157,3, + 131,1,130,1,124,2,160,15,100,6,161,1,125,6,124,6, + 100,7,107,7,114,178,116,14,100,8,124,2,155,2,157,2, + 131,1,130,1,110,92,124,6,100,9,107,2,144,1,114,14, + 124,2,160,16,100,6,100,10,161,2,100,11,25,0,125,7, + 124,7,160,10,116,17,161,1,115,228,116,14,100,12,116,17, + 155,2,157,2,131,1,130,1,124,7,116,12,116,17,131,1, + 100,1,133,2,25,0,125,8,124,8,160,18,161,0,144,1, + 115,14,116,14,100,13,124,7,155,2,100,14,157,3,131,1, + 130,1,124,2,160,19,100,6,161,1,100,15,25,0,125,9, + 116,20,124,1,124,9,116,21,100,15,25,0,23,0,131,2, + 83,0,41,16,97,110,1,0,0,71,105,118,101,110,32,116, + 104,101,32,112,97,116,104,32,116,111,32,97,32,46,112,121, + 99,46,32,102,105,108,101,44,32,114,101,116,117,114,110,32, + 116,104,101,32,112,97,116,104,32,116,111,32,105,116,115,32, + 46,112,121,32,102,105,108,101,46,10,10,32,32,32,32,84, + 104,101,32,46,112,121,99,32,102,105,108,101,32,100,111,101, + 115,32,110,111,116,32,110,101,101,100,32,116,111,32,101,120, + 105,115,116,59,32,116,104,105,115,32,115,105,109,112,108,121, + 32,114,101,116,117,114,110,115,32,116,104,101,32,112,97,116, + 104,32,116,111,10,32,32,32,32,116,104,101,32,46,112,121, + 32,102,105,108,101,32,99,97,108,99,117,108,97,116,101,100, + 32,116,111,32,99,111,114,114,101,115,112,111,110,100,32,116, + 111,32,116,104,101,32,46,112,121,99,32,102,105,108,101,46, + 32,32,73,102,32,112,97,116,104,32,100,111,101,115,10,32, + 32,32,32,110,111,116,32,99,111,110,102,111,114,109,32,116, + 111,32,80,69,80,32,51,49,52,55,47,52,56,56,32,102, + 111,114,109,97,116,44,32,86,97,108,117,101,69,114,114,111, + 114,32,119,105,108,108,32,98,101,32,114,97,105,115,101,100, + 46,32,73,102,10,32,32,32,32,115,121,115,46,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,46,99,97,99,104, + 101,95,116,97,103,32,105,115,32,78,111,110,101,32,116,104, + 101,110,32,78,111,116,73,109,112,108,101,109,101,110,116,101, + 100,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 46,10,10,32,32,32,32,78,114,96,0,0,0,70,84,122, + 31,32,110,111,116,32,98,111,116,116,111,109,45,108,101,118, + 101,108,32,100,105,114,101,99,116,111,114,121,32,105,110,32, + 114,95,0,0,0,62,2,0,0,0,114,44,0,0,0,233, + 3,0,0,0,122,29,101,120,112,101,99,116,101,100,32,111, + 110,108,121,32,50,32,111,114,32,51,32,100,111,116,115,32, + 105,110,32,114,121,0,0,0,114,44,0,0,0,233,254,255, + 255,255,122,53,111,112,116,105,109,105,122,97,116,105,111,110, + 32,112,111,114,116,105,111,110,32,111,102,32,102,105,108,101, + 110,97,109,101,32,100,111,101,115,32,110,111,116,32,115,116, + 97,114,116,32,119,105,116,104,32,122,19,111,112,116,105,109, + 105,122,97,116,105,111,110,32,108,101,118,101,108,32,122,29, + 32,105,115,32,110,111,116,32,97,110,32,97,108,112,104,97, + 110,117,109,101,114,105,99,32,118,97,108,117,101,114,0,0, + 0,0,41,22,114,25,0,0,0,114,103,0,0,0,114,104, + 0,0,0,114,105,0,0,0,114,21,0,0,0,114,101,0, + 0,0,114,73,0,0,0,114,113,0,0,0,114,48,0,0, + 0,114,49,0,0,0,114,27,0,0,0,114,58,0,0,0, + 114,6,0,0,0,114,115,0,0,0,114,110,0,0,0,218, + 5,99,111,117,110,116,218,6,114,115,112,108,105,116,114,111, + 0,0,0,114,109,0,0,0,218,9,112,97,114,116,105,116, + 105,111,110,114,66,0,0,0,218,15,83,79,85,82,67,69, + 95,83,85,70,70,73,88,69,83,41,10,114,64,0,0,0, + 114,117,0,0,0,90,16,112,121,99,97,99,104,101,95,102, + 105,108,101,110,97,109,101,90,23,102,111,117,110,100,95,105, + 110,95,112,121,99,97,99,104,101,95,112,114,101,102,105,120, + 90,13,115,116,114,105,112,112,101,100,95,112,97,116,104,90, + 7,112,121,99,97,99,104,101,90,9,100,111,116,95,99,111, + 117,110,116,114,94,0,0,0,90,9,111,112,116,95,108,101, + 118,101,108,90,13,98,97,115,101,95,102,105,108,101,110,97, + 109,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,17,115,111,117,114,99,101,95,102,114,111,109,95,99, + 97,99,104,101,169,1,0,0,115,52,0,0,0,0,9,12, + 1,8,1,10,1,12,1,4,1,10,1,12,1,14,1,16, + 1,4,1,4,1,12,1,8,1,18,2,10,1,8,1,16, + 1,10,1,16,1,10,1,14,2,16,1,10,1,16,2,14, + 1,114,127,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,5,0,0,0,9,0,0,0,67,0,0,0,115, + 126,0,0,0,116,0,124,0,131,1,100,1,107,2,114,16, + 100,2,83,0,124,0,160,1,100,3,161,1,92,3,125,1, + 125,2,125,3,124,1,114,56,124,3,160,2,161,0,100,4, + 100,5,133,2,25,0,100,6,107,3,114,60,124,0,83,0, + 122,12,116,3,124,0,131,1,125,4,87,0,110,36,4,0, + 116,4,116,5,102,2,107,10,114,108,1,0,1,0,1,0, + 124,0,100,2,100,5,133,2,25,0,125,4,89,0,110,2, + 88,0,116,6,124,4,131,1,114,122,124,4,83,0,124,0, + 83,0,41,7,122,188,67,111,110,118,101,114,116,32,97,32, + 98,121,116,101,99,111,100,101,32,102,105,108,101,32,112,97, + 116,104,32,116,111,32,97,32,115,111,117,114,99,101,32,112, + 97,116,104,32,40,105,102,32,112,111,115,115,105,98,108,101, + 41,46,10,10,32,32,32,32,84,104,105,115,32,102,117,110, + 99,116,105,111,110,32,101,120,105,115,116,115,32,112,117,114, + 101,108,121,32,102,111,114,32,98,97,99,107,119,97,114,100, + 115,45,99,111,109,112,97,116,105,98,105,108,105,116,121,32, + 102,111,114,10,32,32,32,32,80,121,73,109,112,111,114,116, + 95,69,120,101,99,67,111,100,101,77,111,100,117,108,101,87, + 105,116,104,70,105,108,101,110,97,109,101,115,40,41,32,105, + 110,32,116,104,101,32,67,32,65,80,73,46,10,10,32,32, + 32,32,114,0,0,0,0,78,114,95,0,0,0,233,253,255, + 255,255,233,255,255,255,255,90,2,112,121,41,7,114,6,0, + 0,0,114,102,0,0,0,218,5,108,111,119,101,114,114,127, + 0,0,0,114,105,0,0,0,114,110,0,0,0,114,79,0, + 0,0,41,5,218,13,98,121,116,101,99,111,100,101,95,112, + 97,116,104,114,118,0,0,0,218,1,95,90,9,101,120,116, + 101,110,115,105,111,110,218,11,115,111,117,114,99,101,95,112, + 97,116,104,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,15,95,103,101,116,95,115,111,117,114,99,101,102, + 105,108,101,209,1,0,0,115,20,0,0,0,0,7,12,1, + 4,1,16,1,24,1,4,1,2,1,12,1,18,1,18,1, + 114,134,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,8,0,0,0,67,0,0,0,115,74, + 0,0,0,124,0,160,0,116,1,116,2,131,1,161,1,114, + 48,122,10,116,3,124,0,131,1,87,0,83,0,4,0,116, + 4,107,10,114,44,1,0,1,0,1,0,89,0,113,70,88, + 0,110,22,124,0,160,0,116,1,116,5,131,1,161,1,114, + 66,124,0,83,0,100,0,83,0,100,0,83,0,114,68,0, + 0,0,41,6,114,57,0,0,0,218,5,116,117,112,108,101, + 114,126,0,0,0,114,120,0,0,0,114,105,0,0,0,114, + 112,0,0,0,41,1,114,119,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,11,95,103,101,116, + 95,99,97,99,104,101,100,228,1,0,0,115,16,0,0,0, + 0,1,14,1,2,1,10,1,14,1,8,1,14,1,4,2, + 114,136,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,8,0,0,0,67,0,0,0,115,52, + 0,0,0,122,14,116,0,124,0,131,1,106,1,125,1,87, + 0,110,24,4,0,116,2,107,10,114,38,1,0,1,0,1, + 0,100,1,125,1,89,0,110,2,88,0,124,1,100,2,79, + 0,125,1,124,1,83,0,41,3,122,51,67,97,108,99,117, + 108,97,116,101,32,116,104,101,32,109,111,100,101,32,112,101, + 114,109,105,115,115,105,111,110,115,32,102,111,114,32,97,32, + 98,121,116,101,99,111,100,101,32,102,105,108,101,46,114,85, + 0,0,0,233,128,0,0,0,41,3,114,74,0,0,0,114, + 76,0,0,0,114,75,0,0,0,41,2,114,64,0,0,0, + 114,77,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,10,95,99,97,108,99,95,109,111,100,101, + 240,1,0,0,115,12,0,0,0,0,2,2,1,14,1,14, + 1,10,3,8,1,114,138,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,8,0,0,0,3, + 0,0,0,115,68,0,0,0,100,6,135,0,102,1,100,2, + 100,3,132,9,125,1,122,10,116,0,106,1,125,2,87,0, + 110,28,4,0,116,2,107,10,114,52,1,0,1,0,1,0, + 100,4,100,5,132,0,125,2,89,0,110,2,88,0,124,2, + 124,1,136,0,131,2,1,0,124,1,83,0,41,7,122,252, + 68,101,99,111,114,97,116,111,114,32,116,111,32,118,101,114, + 105,102,121,32,116,104,97,116,32,116,104,101,32,109,111,100, + 117,108,101,32,98,101,105,110,103,32,114,101,113,117,101,115, + 116,101,100,32,109,97,116,99,104,101,115,32,116,104,101,32, + 111,110,101,32,116,104,101,10,32,32,32,32,108,111,97,100, + 101,114,32,99,97,110,32,104,97,110,100,108,101,46,10,10, + 32,32,32,32,84,104,101,32,102,105,114,115,116,32,97,114, + 103,117,109,101,110,116,32,40,115,101,108,102,41,32,109,117, + 115,116,32,100,101,102,105,110,101,32,95,110,97,109,101,32, + 119,104,105,99,104,32,116,104,101,32,115,101,99,111,110,100, + 32,97,114,103,117,109,101,110,116,32,105,115,10,32,32,32, + 32,99,111,109,112,97,114,101,100,32,97,103,97,105,110,115, + 116,46,32,73,102,32,116,104,101,32,99,111,109,112,97,114, + 105,115,111,110,32,102,97,105,108,115,32,116,104,101,110,32, + 73,109,112,111,114,116,69,114,114,111,114,32,105,115,32,114, + 97,105,115,101,100,46,10,10,32,32,32,32,78,99,2,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0, + 0,0,31,0,0,0,115,66,0,0,0,124,1,100,0,107, + 8,114,16,124,0,106,0,125,1,110,32,124,0,106,0,124, + 1,107,3,114,48,116,1,100,1,124,0,106,0,124,1,102, + 2,22,0,124,1,100,2,141,2,130,1,136,0,124,0,124, + 1,102,2,124,2,158,2,124,3,142,1,83,0,41,3,78, + 122,30,108,111,97,100,101,114,32,102,111,114,32,37,115,32, + 99,97,110,110,111,116,32,104,97,110,100,108,101,32,37,115, + 169,1,218,4,110,97,109,101,41,2,114,140,0,0,0,218, + 11,73,109,112,111,114,116,69,114,114,111,114,41,4,218,4, + 115,101,108,102,114,140,0,0,0,218,4,97,114,103,115,218, + 6,107,119,97,114,103,115,169,1,218,6,109,101,116,104,111, + 100,114,10,0,0,0,114,11,0,0,0,218,19,95,99,104, + 101,99,107,95,110,97,109,101,95,119,114,97,112,112,101,114, + 4,2,0,0,115,18,0,0,0,0,1,8,1,8,1,10, + 1,4,1,8,255,2,1,2,255,6,2,122,40,95,99,104, + 101,99,107,95,110,97,109,101,46,60,108,111,99,97,108,115, + 62,46,95,99,104,101,99,107,95,110,97,109,101,95,119,114, + 97,112,112,101,114,99,2,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,7,0,0,0,83,0,0,0,115,56, + 0,0,0,100,1,68,0,93,32,125,2,116,0,124,1,124, + 2,131,2,114,4,116,1,124,0,124,2,116,2,124,1,124, + 2,131,2,131,3,1,0,113,4,124,0,106,3,160,4,124, + 1,106,3,161,1,1,0,100,0,83,0,41,2,78,41,4, + 218,10,95,95,109,111,100,117,108,101,95,95,218,8,95,95, + 110,97,109,101,95,95,218,12,95,95,113,117,97,108,110,97, + 109,101,95,95,218,7,95,95,100,111,99,95,95,41,5,218, + 7,104,97,115,97,116,116,114,218,7,115,101,116,97,116,116, + 114,218,7,103,101,116,97,116,116,114,218,8,95,95,100,105, + 99,116,95,95,218,6,117,112,100,97,116,101,41,3,90,3, + 110,101,119,90,3,111,108,100,114,83,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,5,95,119, + 114,97,112,15,2,0,0,115,8,0,0,0,0,1,8,1, + 10,1,20,1,122,26,95,99,104,101,99,107,95,110,97,109, + 101,46,60,108,111,99,97,108,115,62,46,95,119,114,97,112, + 41,1,78,41,3,218,10,95,98,111,111,116,115,116,114,97, + 112,114,157,0,0,0,218,9,78,97,109,101,69,114,114,111, + 114,41,3,114,146,0,0,0,114,147,0,0,0,114,157,0, + 0,0,114,10,0,0,0,114,145,0,0,0,114,11,0,0, + 0,218,11,95,99,104,101,99,107,95,110,97,109,101,252,1, + 0,0,115,14,0,0,0,0,8,14,7,2,1,10,1,14, + 2,14,5,10,1,114,160,0,0,0,99,2,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,67, + 0,0,0,115,60,0,0,0,124,0,160,0,124,1,161,1, + 92,2,125,2,125,3,124,2,100,1,107,8,114,56,116,1, + 124,3,131,1,114,56,100,2,125,4,116,2,160,3,124,4, + 160,4,124,3,100,3,25,0,161,1,116,5,161,2,1,0, + 124,2,83,0,41,4,122,155,84,114,121,32,116,111,32,102, + 105,110,100,32,97,32,108,111,97,100,101,114,32,102,111,114, + 32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,109, + 111,100,117,108,101,32,98,121,32,100,101,108,101,103,97,116, + 105,110,103,32,116,111,10,32,32,32,32,115,101,108,102,46, + 102,105,110,100,95,108,111,97,100,101,114,40,41,46,10,10, + 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,32,105,110, + 32,102,97,118,111,114,32,111,102,32,102,105,110,100,101,114, + 46,102,105,110,100,95,115,112,101,99,40,41,46,10,10,32, + 32,32,32,78,122,44,78,111,116,32,105,109,112,111,114,116, + 105,110,103,32,100,105,114,101,99,116,111,114,121,32,123,125, + 58,32,109,105,115,115,105,110,103,32,95,95,105,110,105,116, + 95,95,114,0,0,0,0,41,6,218,11,102,105,110,100,95, + 108,111,97,100,101,114,114,6,0,0,0,114,97,0,0,0, + 114,98,0,0,0,114,87,0,0,0,218,13,73,109,112,111, + 114,116,87,97,114,110,105,110,103,41,5,114,142,0,0,0, + 218,8,102,117,108,108,110,97,109,101,218,6,108,111,97,100, + 101,114,218,8,112,111,114,116,105,111,110,115,218,3,109,115, + 103,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,17,95,102,105,110,100,95,109,111,100,117,108,101,95,115, + 104,105,109,24,2,0,0,115,10,0,0,0,0,10,14,1, + 16,1,4,1,22,1,114,167,0,0,0,99,3,0,0,0, + 0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0, + 67,0,0,0,115,158,0,0,0,124,0,100,1,100,2,133, + 2,25,0,125,3,124,3,116,0,107,3,114,60,100,3,124, + 1,155,2,100,4,124,3,155,2,157,4,125,4,116,1,160, + 2,100,5,124,4,161,2,1,0,116,3,124,4,102,1,124, + 2,142,1,130,1,116,4,124,0,131,1,100,6,107,0,114, + 102,100,7,124,1,155,2,157,2,125,4,116,1,160,2,100, + 5,124,4,161,2,1,0,116,5,124,4,131,1,130,1,116, + 6,124,0,100,2,100,8,133,2,25,0,131,1,125,5,124, + 5,100,9,64,0,114,154,100,10,124,5,155,2,100,11,124, + 1,155,2,157,4,125,4,116,3,124,4,102,1,124,2,142, + 1,130,1,124,5,83,0,41,12,97,84,2,0,0,80,101, + 114,102,111,114,109,32,98,97,115,105,99,32,118,97,108,105, + 100,105,116,121,32,99,104,101,99,107,105,110,103,32,111,102, + 32,97,32,112,121,99,32,104,101,97,100,101,114,32,97,110, + 100,32,114,101,116,117,114,110,32,116,104,101,32,102,108,97, + 103,115,32,102,105,101,108,100,44,10,32,32,32,32,119,104, + 105,99,104,32,100,101,116,101,114,109,105,110,101,115,32,104, + 111,119,32,116,104,101,32,112,121,99,32,115,104,111,117,108, + 100,32,98,101,32,102,117,114,116,104,101,114,32,118,97,108, + 105,100,97,116,101,100,32,97,103,97,105,110,115,116,32,116, + 104,101,32,115,111,117,114,99,101,46,10,10,32,32,32,32, + 42,100,97,116,97,42,32,105,115,32,116,104,101,32,99,111, + 110,116,101,110,116,115,32,111,102,32,116,104,101,32,112,121, + 99,32,102,105,108,101,46,32,40,79,110,108,121,32,116,104, + 101,32,102,105,114,115,116,32,49,54,32,98,121,116,101,115, + 32,97,114,101,10,32,32,32,32,114,101,113,117,105,114,101, + 100,44,32,116,104,111,117,103,104,46,41,10,10,32,32,32, + 32,42,110,97,109,101,42,32,105,115,32,116,104,101,32,110, + 97,109,101,32,111,102,32,116,104,101,32,109,111,100,117,108, + 101,32,98,101,105,110,103,32,105,109,112,111,114,116,101,100, + 46,32,73,116,32,105,115,32,117,115,101,100,32,102,111,114, + 32,108,111,103,103,105,110,103,46,10,10,32,32,32,32,42, + 101,120,99,95,100,101,116,97,105,108,115,42,32,105,115,32, + 97,32,100,105,99,116,105,111,110,97,114,121,32,112,97,115, + 115,101,100,32,116,111,32,73,109,112,111,114,116,69,114,114, + 111,114,32,105,102,32,105,116,32,114,97,105,115,101,100,32, + 102,111,114,10,32,32,32,32,105,109,112,114,111,118,101,100, + 32,100,101,98,117,103,103,105,110,103,46,10,10,32,32,32, + 32,73,109,112,111,114,116,69,114,114,111,114,32,105,115,32, + 114,97,105,115,101,100,32,119,104,101,110,32,116,104,101,32, + 109,97,103,105,99,32,110,117,109,98,101,114,32,105,115,32, + 105,110,99,111,114,114,101,99,116,32,111,114,32,119,104,101, + 110,32,116,104,101,32,102,108,97,103,115,10,32,32,32,32, + 102,105,101,108,100,32,105,115,32,105,110,118,97,108,105,100, + 46,32,69,79,70,69,114,114,111,114,32,105,115,32,114,97, + 105,115,101,100,32,119,104,101,110,32,116,104,101,32,100,97, + 116,97,32,105,115,32,102,111,117,110,100,32,116,111,32,98, + 101,32,116,114,117,110,99,97,116,101,100,46,10,10,32,32, + 32,32,78,114,32,0,0,0,122,20,98,97,100,32,109,97, + 103,105,99,32,110,117,109,98,101,114,32,105,110,32,122,2, + 58,32,250,2,123,125,233,16,0,0,0,122,40,114,101,97, + 99,104,101,100,32,69,79,70,32,119,104,105,108,101,32,114, + 101,97,100,105,110,103,32,112,121,99,32,104,101,97,100,101, + 114,32,111,102,32,233,8,0,0,0,233,252,255,255,255,122, + 14,105,110,118,97,108,105,100,32,102,108,97,103,115,32,122, + 4,32,105,110,32,41,7,218,12,77,65,71,73,67,95,78, + 85,77,66,69,82,114,158,0,0,0,218,16,95,118,101,114, + 98,111,115,101,95,109,101,115,115,97,103,101,114,141,0,0, + 0,114,6,0,0,0,218,8,69,79,70,69,114,114,111,114, + 114,43,0,0,0,41,6,114,42,0,0,0,114,140,0,0, + 0,218,11,101,120,99,95,100,101,116,97,105,108,115,90,5, + 109,97,103,105,99,114,116,0,0,0,114,106,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,13, + 95,99,108,97,115,115,105,102,121,95,112,121,99,41,2,0, + 0,115,28,0,0,0,0,16,12,1,8,1,16,1,12,1, + 12,1,12,1,10,1,12,1,8,1,16,2,8,1,16,1, + 12,1,114,176,0,0,0,99,5,0,0,0,0,0,0,0, + 0,0,0,0,6,0,0,0,4,0,0,0,67,0,0,0, + 115,112,0,0,0,116,0,124,0,100,1,100,2,133,2,25, + 0,131,1,124,1,100,3,64,0,107,3,114,58,100,4,124, + 3,155,2,157,2,125,5,116,1,160,2,100,5,124,5,161, + 2,1,0,116,3,124,5,102,1,124,4,142,1,130,1,124, + 2,100,6,107,9,114,108,116,0,124,0,100,2,100,7,133, + 2,25,0,131,1,124,2,100,3,64,0,107,3,114,108,116, + 3,100,4,124,3,155,2,157,2,102,1,124,4,142,1,130, + 1,100,6,83,0,41,8,97,7,2,0,0,86,97,108,105, + 100,97,116,101,32,97,32,112,121,99,32,97,103,97,105,110, + 115,116,32,116,104,101,32,115,111,117,114,99,101,32,108,97, + 115,116,45,109,111,100,105,102,105,101,100,32,116,105,109,101, + 46,10,10,32,32,32,32,42,100,97,116,97,42,32,105,115, + 32,116,104,101,32,99,111,110,116,101,110,116,115,32,111,102, + 32,116,104,101,32,112,121,99,32,102,105,108,101,46,32,40, + 79,110,108,121,32,116,104,101,32,102,105,114,115,116,32,49, + 54,32,98,121,116,101,115,32,97,114,101,10,32,32,32,32, + 114,101,113,117,105,114,101,100,46,41,10,10,32,32,32,32, + 42,115,111,117,114,99,101,95,109,116,105,109,101,42,32,105, + 115,32,116,104,101,32,108,97,115,116,32,109,111,100,105,102, + 105,101,100,32,116,105,109,101,115,116,97,109,112,32,111,102, + 32,116,104,101,32,115,111,117,114,99,101,32,102,105,108,101, + 46,10,10,32,32,32,32,42,115,111,117,114,99,101,95,115, + 105,122,101,42,32,105,115,32,78,111,110,101,32,111,114,32, + 116,104,101,32,115,105,122,101,32,111,102,32,116,104,101,32, + 115,111,117,114,99,101,32,102,105,108,101,32,105,110,32,98, + 121,116,101,115,46,10,10,32,32,32,32,42,110,97,109,101, + 42,32,105,115,32,116,104,101,32,110,97,109,101,32,111,102, + 32,116,104,101,32,109,111,100,117,108,101,32,98,101,105,110, + 103,32,105,109,112,111,114,116,101,100,46,32,73,116,32,105, + 115,32,117,115,101,100,32,102,111,114,32,108,111,103,103,105, + 110,103,46,10,10,32,32,32,32,42,101,120,99,95,100,101, + 116,97,105,108,115,42,32,105,115,32,97,32,100,105,99,116, + 105,111,110,97,114,121,32,112,97,115,115,101,100,32,116,111, + 32,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32, + 105,116,32,114,97,105,115,101,100,32,102,111,114,10,32,32, + 32,32,105,109,112,114,111,118,101,100,32,100,101,98,117,103, + 103,105,110,103,46,10,10,32,32,32,32,65,110,32,73,109, + 112,111,114,116,69,114,114,111,114,32,105,115,32,114,97,105, + 115,101,100,32,105,102,32,116,104,101,32,98,121,116,101,99, + 111,100,101,32,105,115,32,115,116,97,108,101,46,10,10,32, + 32,32,32,114,170,0,0,0,233,12,0,0,0,114,31,0, + 0,0,122,22,98,121,116,101,99,111,100,101,32,105,115,32, + 115,116,97,108,101,32,102,111,114,32,114,168,0,0,0,78, + 114,169,0,0,0,41,4,114,43,0,0,0,114,158,0,0, + 0,114,173,0,0,0,114,141,0,0,0,41,6,114,42,0, + 0,0,218,12,115,111,117,114,99,101,95,109,116,105,109,101, + 218,11,115,111,117,114,99,101,95,115,105,122,101,114,140,0, + 0,0,114,175,0,0,0,114,116,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,23,95,118,97, + 108,105,100,97,116,101,95,116,105,109,101,115,116,97,109,112, + 95,112,121,99,74,2,0,0,115,16,0,0,0,0,19,24, + 1,10,1,12,1,12,1,8,1,22,255,2,2,114,180,0, + 0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 124,0,100,1,100,2,133,2,25,0,124,1,107,3,114,34, + 116,0,100,3,124,2,155,2,157,2,102,1,124,3,142,1, + 130,1,100,4,83,0,41,5,97,243,1,0,0,86,97,108, + 105,100,97,116,101,32,97,32,104,97,115,104,45,98,97,115, + 101,100,32,112,121,99,32,98,121,32,99,104,101,99,107,105, + 110,103,32,116,104,101,32,114,101,97,108,32,115,111,117,114, + 99,101,32,104,97,115,104,32,97,103,97,105,110,115,116,32, + 116,104,101,32,111,110,101,32,105,110,10,32,32,32,32,116, + 104,101,32,112,121,99,32,104,101,97,100,101,114,46,10,10, + 32,32,32,32,42,100,97,116,97,42,32,105,115,32,116,104, + 101,32,99,111,110,116,101,110,116,115,32,111,102,32,116,104, + 101,32,112,121,99,32,102,105,108,101,46,32,40,79,110,108, + 121,32,116,104,101,32,102,105,114,115,116,32,49,54,32,98, + 121,116,101,115,32,97,114,101,10,32,32,32,32,114,101,113, + 117,105,114,101,100,46,41,10,10,32,32,32,32,42,115,111, + 117,114,99,101,95,104,97,115,104,42,32,105,115,32,116,104, + 101,32,105,109,112,111,114,116,108,105,98,46,117,116,105,108, + 46,115,111,117,114,99,101,95,104,97,115,104,40,41,32,111, + 102,32,116,104,101,32,115,111,117,114,99,101,32,102,105,108, + 101,46,10,10,32,32,32,32,42,110,97,109,101,42,32,105, + 115,32,116,104,101,32,110,97,109,101,32,111,102,32,116,104, + 101,32,109,111,100,117,108,101,32,98,101,105,110,103,32,105, + 109,112,111,114,116,101,100,46,32,73,116,32,105,115,32,117, + 115,101,100,32,102,111,114,32,108,111,103,103,105,110,103,46, + 10,10,32,32,32,32,42,101,120,99,95,100,101,116,97,105, + 108,115,42,32,105,115,32,97,32,100,105,99,116,105,111,110, + 97,114,121,32,112,97,115,115,101,100,32,116,111,32,73,109, + 112,111,114,116,69,114,114,111,114,32,105,102,32,105,116,32, + 114,97,105,115,101,100,32,102,111,114,10,32,32,32,32,105, + 109,112,114,111,118,101,100,32,100,101,98,117,103,103,105,110, + 103,46,10,10,32,32,32,32,65,110,32,73,109,112,111,114, + 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 32,105,102,32,116,104,101,32,98,121,116,101,99,111,100,101, + 32,105,115,32,115,116,97,108,101,46,10,10,32,32,32,32, + 114,170,0,0,0,114,169,0,0,0,122,46,104,97,115,104, + 32,105,110,32,98,121,116,101,99,111,100,101,32,100,111,101, + 115,110,39,116,32,109,97,116,99,104,32,104,97,115,104,32, + 111,102,32,115,111,117,114,99,101,32,78,41,1,114,141,0, + 0,0,41,4,114,42,0,0,0,218,11,115,111,117,114,99, + 101,95,104,97,115,104,114,140,0,0,0,114,175,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 18,95,118,97,108,105,100,97,116,101,95,104,97,115,104,95, + 112,121,99,102,2,0,0,115,12,0,0,0,0,17,16,1, + 2,1,8,255,2,2,2,254,114,182,0,0,0,99,4,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0, + 0,0,67,0,0,0,115,80,0,0,0,116,0,160,1,124, + 0,161,1,125,4,116,2,124,4,116,3,131,2,114,56,116, + 4,160,5,100,1,124,2,161,2,1,0,124,3,100,2,107, + 9,114,52,116,6,160,7,124,4,124,3,161,2,1,0,124, + 4,83,0,116,8,100,3,160,9,124,2,161,1,124,1,124, + 2,100,4,141,3,130,1,100,2,83,0,41,5,122,35,67, + 111,109,112,105,108,101,32,98,121,116,101,99,111,100,101,32, + 97,115,32,102,111,117,110,100,32,105,110,32,97,32,112,121, + 99,46,122,21,99,111,100,101,32,111,98,106,101,99,116,32, + 102,114,111,109,32,123,33,114,125,78,122,23,78,111,110,45, + 99,111,100,101,32,111,98,106,101,99,116,32,105,110,32,123, + 33,114,125,169,2,114,140,0,0,0,114,64,0,0,0,41, + 10,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, + 115,218,10,105,115,105,110,115,116,97,110,99,101,218,10,95, + 99,111,100,101,95,116,121,112,101,114,158,0,0,0,114,173, + 0,0,0,218,4,95,105,109,112,90,16,95,102,105,120,95, + 99,111,95,102,105,108,101,110,97,109,101,114,141,0,0,0, + 114,87,0,0,0,41,5,114,42,0,0,0,114,140,0,0, + 0,114,131,0,0,0,114,133,0,0,0,218,4,99,111,100, + 101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,17,95,99,111,109,112,105,108,101,95,98,121,116,101,99, + 111,100,101,126,2,0,0,115,20,0,0,0,0,2,10,1, + 10,1,12,1,8,1,12,1,4,2,10,1,2,0,2,255, + 114,189,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,5,0,0,0,67,0,0,0,115,70, + 0,0,0,116,0,116,1,131,1,125,3,124,3,160,2,116, + 3,100,1,131,1,161,1,1,0,124,3,160,2,116,3,124, + 1,131,1,161,1,1,0,124,3,160,2,116,3,124,2,131, + 1,161,1,1,0,124,3,160,2,116,4,160,5,124,0,161, + 1,161,1,1,0,124,3,83,0,41,2,122,43,80,114,111, + 100,117,99,101,32,116,104,101,32,100,97,116,97,32,102,111, + 114,32,97,32,116,105,109,101,115,116,97,109,112,45,98,97, + 115,101,100,32,112,121,99,46,114,0,0,0,0,41,6,218, + 9,98,121,116,101,97,114,114,97,121,114,172,0,0,0,218, + 6,101,120,116,101,110,100,114,37,0,0,0,114,184,0,0, + 0,218,5,100,117,109,112,115,41,4,114,188,0,0,0,218, + 5,109,116,105,109,101,114,179,0,0,0,114,42,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 22,95,99,111,100,101,95,116,111,95,116,105,109,101,115,116, + 97,109,112,95,112,121,99,139,2,0,0,115,12,0,0,0, + 0,2,8,1,14,1,14,1,14,1,16,1,114,194,0,0, + 0,84,99,3,0,0,0,0,0,0,0,0,0,0,0,5, + 0,0,0,5,0,0,0,67,0,0,0,115,80,0,0,0, + 116,0,116,1,131,1,125,3,100,1,124,2,100,1,62,0, + 66,0,125,4,124,3,160,2,116,3,124,4,131,1,161,1, + 1,0,116,4,124,1,131,1,100,2,107,2,115,50,116,5, + 130,1,124,3,160,2,124,1,161,1,1,0,124,3,160,2, + 116,6,160,7,124,0,161,1,161,1,1,0,124,3,83,0, + 41,3,122,38,80,114,111,100,117,99,101,32,116,104,101,32, + 100,97,116,97,32,102,111,114,32,97,32,104,97,115,104,45, + 98,97,115,101,100,32,112,121,99,46,114,4,0,0,0,114, + 170,0,0,0,41,8,114,190,0,0,0,114,172,0,0,0, + 114,191,0,0,0,114,37,0,0,0,114,6,0,0,0,114, + 39,0,0,0,114,184,0,0,0,114,192,0,0,0,41,5, + 114,188,0,0,0,114,181,0,0,0,90,7,99,104,101,99, + 107,101,100,114,42,0,0,0,114,106,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,17,95,99, + 111,100,101,95,116,111,95,104,97,115,104,95,112,121,99,149, + 2,0,0,115,14,0,0,0,0,2,8,1,12,1,14,1, + 16,1,10,1,16,1,114,195,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0, + 67,0,0,0,115,62,0,0,0,100,1,100,2,108,0,125, + 1,116,1,160,2,124,0,161,1,106,3,125,2,124,1,160, + 4,124,2,161,1,125,3,116,1,160,5,100,2,100,3,161, + 2,125,4,124,4,160,6,124,0,160,6,124,3,100,1,25, + 0,161,1,161,1,83,0,41,4,122,121,68,101,99,111,100, + 101,32,98,121,116,101,115,32,114,101,112,114,101,115,101,110, + 116,105,110,103,32,115,111,117,114,99,101,32,99,111,100,101, + 32,97,110,100,32,114,101,116,117,114,110,32,116,104,101,32, + 115,116,114,105,110,103,46,10,10,32,32,32,32,85,110,105, + 118,101,114,115,97,108,32,110,101,119,108,105,110,101,32,115, + 117,112,112,111,114,116,32,105,115,32,117,115,101,100,32,105, + 110,32,116,104,101,32,100,101,99,111,100,105,110,103,46,10, + 32,32,32,32,114,0,0,0,0,78,84,41,7,218,8,116, + 111,107,101,110,105,122,101,114,89,0,0,0,90,7,66,121, + 116,101,115,73,79,90,8,114,101,97,100,108,105,110,101,90, + 15,100,101,116,101,99,116,95,101,110,99,111,100,105,110,103, + 90,25,73,110,99,114,101,109,101,110,116,97,108,78,101,119, + 108,105,110,101,68,101,99,111,100,101,114,218,6,100,101,99, + 111,100,101,41,5,218,12,115,111,117,114,99,101,95,98,121, + 116,101,115,114,196,0,0,0,90,21,115,111,117,114,99,101, + 95,98,121,116,101,115,95,114,101,97,100,108,105,110,101,218, + 8,101,110,99,111,100,105,110,103,90,15,110,101,119,108,105, + 110,101,95,100,101,99,111,100,101,114,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,13,100,101,99,111,100, + 101,95,115,111,117,114,99,101,160,2,0,0,115,10,0,0, + 0,0,5,8,1,12,1,10,1,12,1,114,200,0,0,0, + 169,2,114,164,0,0,0,218,26,115,117,98,109,111,100,117, + 108,101,95,115,101,97,114,99,104,95,108,111,99,97,116,105, + 111,110,115,99,2,0,0,0,0,0,0,0,2,0,0,0, + 9,0,0,0,8,0,0,0,67,0,0,0,115,72,1,0, + 0,124,1,100,1,107,8,114,60,100,2,125,1,116,0,124, + 2,100,3,131,2,114,118,122,14,124,2,160,1,124,0,161, + 1,125,1,87,0,113,118,4,0,116,2,107,10,114,56,1, + 0,1,0,1,0,89,0,113,118,88,0,110,58,116,3,160, + 4,124,1,161,1,125,1,116,5,124,1,131,1,115,118,122, + 18,116,6,116,3,160,7,161,0,124,1,131,2,125,1,87, + 0,110,20,4,0,116,8,107,10,114,116,1,0,1,0,1, + 0,89,0,110,2,88,0,116,9,106,10,124,0,124,2,124, + 1,100,4,141,3,125,4,100,5,124,4,95,11,124,2,100, + 1,107,8,114,202,116,12,131,0,68,0,93,42,92,2,125, + 5,125,6,124,1,160,13,116,14,124,6,131,1,161,1,114, + 154,124,5,124,0,124,1,131,2,125,2,124,2,124,4,95, + 15,1,0,113,202,113,154,100,1,83,0,124,3,116,16,107, + 8,144,1,114,20,116,0,124,2,100,6,131,2,144,1,114, + 26,122,14,124,2,160,17,124,0,161,1,125,7,87,0,110, + 22,4,0,116,2,107,10,144,1,114,4,1,0,1,0,1, + 0,89,0,110,14,88,0,124,7,144,1,114,26,103,0,124, + 4,95,18,110,6,124,3,124,4,95,18,124,4,106,18,103, + 0,107,2,144,1,114,68,124,1,144,1,114,68,116,19,124, + 1,131,1,100,7,25,0,125,8,124,4,106,18,160,20,124, + 8,161,1,1,0,124,4,83,0,41,8,97,61,1,0,0, + 82,101,116,117,114,110,32,97,32,109,111,100,117,108,101,32, + 115,112,101,99,32,98,97,115,101,100,32,111,110,32,97,32, + 102,105,108,101,32,108,111,99,97,116,105,111,110,46,10,10, + 32,32,32,32,84,111,32,105,110,100,105,99,97,116,101,32, + 116,104,97,116,32,116,104,101,32,109,111,100,117,108,101,32, + 105,115,32,97,32,112,97,99,107,97,103,101,44,32,115,101, + 116,10,32,32,32,32,115,117,98,109,111,100,117,108,101,95, + 115,101,97,114,99,104,95,108,111,99,97,116,105,111,110,115, + 32,116,111,32,97,32,108,105,115,116,32,111,102,32,100,105, + 114,101,99,116,111,114,121,32,112,97,116,104,115,46,32,32, + 65,110,10,32,32,32,32,101,109,112,116,121,32,108,105,115, + 116,32,105,115,32,115,117,102,102,105,99,105,101,110,116,44, + 32,116,104,111,117,103,104,32,105,116,115,32,110,111,116,32, + 111,116,104,101,114,119,105,115,101,32,117,115,101,102,117,108, + 32,116,111,32,116,104,101,10,32,32,32,32,105,109,112,111, + 114,116,32,115,121,115,116,101,109,46,10,10,32,32,32,32, + 84,104,101,32,108,111,97,100,101,114,32,109,117,115,116,32, + 116,97,107,101,32,97,32,115,112,101,99,32,97,115,32,105, + 116,115,32,111,110,108,121,32,95,95,105,110,105,116,95,95, + 40,41,32,97,114,103,46,10,10,32,32,32,32,78,122,9, + 60,117,110,107,110,111,119,110,62,218,12,103,101,116,95,102, + 105,108,101,110,97,109,101,169,1,218,6,111,114,105,103,105, + 110,84,218,10,105,115,95,112,97,99,107,97,103,101,114,0, + 0,0,0,41,21,114,152,0,0,0,114,203,0,0,0,114, + 141,0,0,0,114,21,0,0,0,114,101,0,0,0,114,84, + 0,0,0,114,66,0,0,0,114,80,0,0,0,114,75,0, + 0,0,114,158,0,0,0,218,10,77,111,100,117,108,101,83, + 112,101,99,90,13,95,115,101,116,95,102,105,108,101,97,116, + 116,114,218,27,95,103,101,116,95,115,117,112,112,111,114,116, + 101,100,95,102,105,108,101,95,108,111,97,100,101,114,115,114, + 57,0,0,0,114,135,0,0,0,114,164,0,0,0,218,9, + 95,80,79,80,85,76,65,84,69,114,206,0,0,0,114,202, + 0,0,0,114,73,0,0,0,114,60,0,0,0,41,9,114, + 140,0,0,0,90,8,108,111,99,97,116,105,111,110,114,164, + 0,0,0,114,202,0,0,0,218,4,115,112,101,99,218,12, + 108,111,97,100,101,114,95,99,108,97,115,115,218,8,115,117, + 102,102,105,120,101,115,114,206,0,0,0,90,7,100,105,114, + 110,97,109,101,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,23,115,112,101,99,95,102,114,111,109,95,102, + 105,108,101,95,108,111,99,97,116,105,111,110,177,2,0,0, + 115,72,0,0,0,0,12,8,4,4,1,10,2,2,1,14, + 1,14,1,8,2,10,1,8,1,2,1,18,1,14,1,6, + 8,16,1,6,3,8,1,14,1,14,1,10,1,6,1,6, + 2,4,3,10,2,12,1,2,1,14,1,16,1,6,2,6, + 1,8,2,6,1,12,1,6,1,12,1,12,2,114,213,0, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,64,0,0,0,115,80,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,100,2,90,4, + 100,3,90,5,100,4,90,6,101,7,100,5,100,6,132,0, + 131,1,90,8,101,7,100,7,100,8,132,0,131,1,90,9, + 101,7,100,14,100,10,100,11,132,1,131,1,90,10,101,7, + 100,15,100,12,100,13,132,1,131,1,90,11,100,9,83,0, + 41,16,218,21,87,105,110,100,111,119,115,82,101,103,105,115, + 116,114,121,70,105,110,100,101,114,122,62,77,101,116,97,32, + 112,97,116,104,32,102,105,110,100,101,114,32,102,111,114,32, + 109,111,100,117,108,101,115,32,100,101,99,108,97,114,101,100, + 32,105,110,32,116,104,101,32,87,105,110,100,111,119,115,32, + 114,101,103,105,115,116,114,121,46,122,59,83,111,102,116,119, + 97,114,101,92,80,121,116,104,111,110,92,80,121,116,104,111, + 110,67,111,114,101,92,123,115,121,115,95,118,101,114,115,105, + 111,110,125,92,77,111,100,117,108,101,115,92,123,102,117,108, + 108,110,97,109,101,125,122,65,83,111,102,116,119,97,114,101, + 92,80,121,116,104,111,110,92,80,121,116,104,111,110,67,111, + 114,101,92,123,115,121,115,95,118,101,114,115,105,111,110,125, + 92,77,111,100,117,108,101,115,92,123,102,117,108,108,110,97, + 109,101,125,92,68,101,98,117,103,70,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,8,0,0,0,67, + 0,0,0,115,56,0,0,0,122,16,116,0,160,1,116,0, + 106,2,124,1,161,2,87,0,83,0,4,0,116,3,107,10, + 114,50,1,0,1,0,1,0,116,0,160,1,116,0,106,4, + 124,1,161,2,6,0,89,0,83,0,88,0,100,0,83,0, + 114,68,0,0,0,41,5,218,7,95,119,105,110,114,101,103, + 90,7,79,112,101,110,75,101,121,90,17,72,75,69,89,95, + 67,85,82,82,69,78,84,95,85,83,69,82,114,75,0,0, + 0,90,18,72,75,69,89,95,76,79,67,65,76,95,77,65, + 67,72,73,78,69,41,2,218,3,99,108,115,114,23,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,14,95,111,112,101,110,95,114,101,103,105,115,116,114,121, + 6,3,0,0,115,8,0,0,0,0,2,2,1,16,1,14, + 1,122,36,87,105,110,100,111,119,115,82,101,103,105,115,116, + 114,121,70,105,110,100,101,114,46,95,111,112,101,110,95,114, + 101,103,105,115,116,114,121,99,2,0,0,0,0,0,0,0, + 0,0,0,0,6,0,0,0,9,0,0,0,67,0,0,0, + 115,114,0,0,0,124,0,106,0,114,14,124,0,106,1,125, + 2,110,6,124,0,106,2,125,2,124,2,106,3,124,1,100, + 1,116,4,106,5,100,0,100,2,133,2,25,0,22,0,100, + 3,141,2,125,3,122,38,124,0,160,6,124,3,161,1,143, + 18,125,4,116,7,160,8,124,4,100,4,161,2,125,5,87, + 0,53,0,81,0,82,0,88,0,87,0,110,22,4,0,116, + 9,107,10,114,108,1,0,1,0,1,0,89,0,100,0,83, + 0,88,0,124,5,83,0,41,5,78,122,5,37,100,46,37, + 100,114,44,0,0,0,41,2,114,163,0,0,0,90,11,115, + 121,115,95,118,101,114,115,105,111,110,114,13,0,0,0,41, + 10,218,11,68,69,66,85,71,95,66,85,73,76,68,218,18, + 82,69,71,73,83,84,82,89,95,75,69,89,95,68,69,66, + 85,71,218,12,82,69,71,73,83,84,82,89,95,75,69,89, + 114,87,0,0,0,114,25,0,0,0,218,12,118,101,114,115, + 105,111,110,95,105,110,102,111,114,217,0,0,0,114,215,0, + 0,0,90,10,81,117,101,114,121,86,97,108,117,101,114,75, + 0,0,0,41,6,114,216,0,0,0,114,163,0,0,0,90, + 12,114,101,103,105,115,116,114,121,95,107,101,121,114,23,0, + 0,0,90,4,104,107,101,121,218,8,102,105,108,101,112,97, + 116,104,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,16,95,115,101,97,114,99,104,95,114,101,103,105,115, + 116,114,121,13,3,0,0,115,24,0,0,0,0,2,6,1, + 8,2,6,1,6,1,16,255,6,2,2,1,12,1,26,1, + 14,1,8,1,122,38,87,105,110,100,111,119,115,82,101,103, + 105,115,116,114,121,70,105,110,100,101,114,46,95,115,101,97, + 114,99,104,95,114,101,103,105,115,116,114,121,78,99,4,0, + 0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,0, + 0,0,67,0,0,0,115,122,0,0,0,124,0,160,0,124, + 1,161,1,125,4,124,4,100,0,107,8,114,22,100,0,83, + 0,122,12,116,1,124,4,131,1,1,0,87,0,110,22,4, + 0,116,2,107,10,114,56,1,0,1,0,1,0,89,0,100, + 0,83,0,88,0,116,3,131,0,68,0,93,52,92,2,125, + 5,125,6,124,4,160,4,116,5,124,6,131,1,161,1,114, + 64,116,6,106,7,124,1,124,5,124,1,124,4,131,2,124, + 4,100,1,141,3,125,7,124,7,2,0,1,0,83,0,113, + 64,100,0,83,0,41,2,78,114,204,0,0,0,41,8,114, + 223,0,0,0,114,74,0,0,0,114,75,0,0,0,114,208, + 0,0,0,114,57,0,0,0,114,135,0,0,0,114,158,0, + 0,0,218,16,115,112,101,99,95,102,114,111,109,95,108,111, + 97,100,101,114,41,8,114,216,0,0,0,114,163,0,0,0, + 114,64,0,0,0,218,6,116,97,114,103,101,116,114,222,0, + 0,0,114,164,0,0,0,114,212,0,0,0,114,210,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,9,102,105,110,100,95,115,112,101,99,28,3,0,0,115, + 28,0,0,0,0,2,10,1,8,1,4,1,2,1,12,1, + 14,1,8,1,14,1,14,1,6,1,8,1,2,254,6,3, + 122,31,87,105,110,100,111,119,115,82,101,103,105,115,116,114, + 121,70,105,110,100,101,114,46,102,105,110,100,95,115,112,101, + 99,99,3,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,4,0,0,0,67,0,0,0,115,34,0,0,0,124, + 0,160,0,124,1,124,2,161,2,125,3,124,3,100,1,107, + 9,114,26,124,3,106,1,83,0,100,1,83,0,100,1,83, + 0,41,2,122,108,70,105,110,100,32,109,111,100,117,108,101, + 32,110,97,109,101,100,32,105,110,32,116,104,101,32,114,101, + 103,105,115,116,114,121,46,10,10,32,32,32,32,32,32,32, + 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, + 32,101,120,101,99,95,109,111,100,117,108,101,40,41,32,105, + 110,115,116,101,97,100,46,10,10,32,32,32,32,32,32,32, + 32,78,169,2,114,226,0,0,0,114,164,0,0,0,169,4, + 114,216,0,0,0,114,163,0,0,0,114,64,0,0,0,114, + 210,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,11,102,105,110,100,95,109,111,100,117,108,101, + 44,3,0,0,115,8,0,0,0,0,7,12,1,8,1,6, + 2,122,33,87,105,110,100,111,119,115,82,101,103,105,115,116, + 114,121,70,105,110,100,101,114,46,102,105,110,100,95,109,111, + 100,117,108,101,41,2,78,78,41,1,78,41,12,114,149,0, + 0,0,114,148,0,0,0,114,150,0,0,0,114,151,0,0, + 0,114,220,0,0,0,114,219,0,0,0,114,218,0,0,0, + 218,11,99,108,97,115,115,109,101,116,104,111,100,114,217,0, + 0,0,114,223,0,0,0,114,226,0,0,0,114,229,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,214,0,0,0,250,2,0,0,115,28, + 0,0,0,8,2,4,3,2,255,2,4,2,255,2,3,4, + 2,2,1,10,6,2,1,10,14,2,1,12,15,2,1,114, + 214,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,64,0,0,0,115,48,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, + 100,7,132,0,90,6,100,8,100,9,132,0,90,7,100,10, + 83,0,41,11,218,13,95,76,111,97,100,101,114,66,97,115, + 105,99,115,122,83,66,97,115,101,32,99,108,97,115,115,32, + 111,102,32,99,111,109,109,111,110,32,99,111,100,101,32,110, + 101,101,100,101,100,32,98,121,32,98,111,116,104,32,83,111, + 117,114,99,101,76,111,97,100,101,114,32,97,110,100,10,32, + 32,32,32,83,111,117,114,99,101,108,101,115,115,70,105,108, + 101,76,111,97,100,101,114,46,99,2,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,4,0,0,0,67,0,0, + 0,115,64,0,0,0,116,0,124,0,160,1,124,1,161,1, + 131,1,100,1,25,0,125,2,124,2,160,2,100,2,100,1, + 161,2,100,3,25,0,125,3,124,1,160,3,100,2,161,1, + 100,4,25,0,125,4,124,3,100,5,107,2,111,62,124,4, + 100,5,107,3,83,0,41,6,122,141,67,111,110,99,114,101, + 116,101,32,105,109,112,108,101,109,101,110,116,97,116,105,111, + 110,32,111,102,32,73,110,115,112,101,99,116,76,111,97,100, + 101,114,46,105,115,95,112,97,99,107,97,103,101,32,98,121, + 32,99,104,101,99,107,105,110,103,32,105,102,10,32,32,32, + 32,32,32,32,32,116,104,101,32,112,97,116,104,32,114,101, + 116,117,114,110,101,100,32,98,121,32,103,101,116,95,102,105, + 108,101,110,97,109,101,32,104,97,115,32,97,32,102,105,108, + 101,110,97,109,101,32,111,102,32,39,95,95,105,110,105,116, + 95,95,46,112,121,39,46,114,4,0,0,0,114,95,0,0, + 0,114,0,0,0,0,114,44,0,0,0,218,8,95,95,105, + 110,105,116,95,95,41,4,114,73,0,0,0,114,203,0,0, + 0,114,124,0,0,0,114,102,0,0,0,41,5,114,142,0, + 0,0,114,163,0,0,0,114,119,0,0,0,90,13,102,105, + 108,101,110,97,109,101,95,98,97,115,101,90,9,116,97,105, + 108,95,110,97,109,101,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,206,0,0,0,63,3,0,0,115,8, + 0,0,0,0,3,18,1,16,1,14,1,122,24,95,76,111, + 97,100,101,114,66,97,115,105,99,115,46,105,115,95,112,97, + 99,107,97,103,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, + 0,0,0,100,1,83,0,169,2,122,42,85,115,101,32,100, + 101,102,97,117,108,116,32,115,101,109,97,110,116,105,99,115, + 32,102,111,114,32,109,111,100,117,108,101,32,99,114,101,97, + 116,105,111,110,46,78,114,10,0,0,0,169,2,114,142,0, + 0,0,114,210,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,13,99,114,101,97,116,101,95,109, + 111,100,117,108,101,71,3,0,0,115,2,0,0,0,0,1, + 122,27,95,76,111,97,100,101,114,66,97,115,105,99,115,46, + 99,114,101,97,116,101,95,109,111,100,117,108,101,99,2,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,5,0, + 0,0,67,0,0,0,115,56,0,0,0,124,0,160,0,124, + 1,106,1,161,1,125,2,124,2,100,1,107,8,114,36,116, + 2,100,2,160,3,124,1,106,1,161,1,131,1,130,1,116, + 4,160,5,116,6,124,2,124,1,106,7,161,3,1,0,100, + 1,83,0,41,3,122,19,69,120,101,99,117,116,101,32,116, + 104,101,32,109,111,100,117,108,101,46,78,122,52,99,97,110, + 110,111,116,32,108,111,97,100,32,109,111,100,117,108,101,32, + 123,33,114,125,32,119,104,101,110,32,103,101,116,95,99,111, + 100,101,40,41,32,114,101,116,117,114,110,115,32,78,111,110, + 101,41,8,218,8,103,101,116,95,99,111,100,101,114,149,0, + 0,0,114,141,0,0,0,114,87,0,0,0,114,158,0,0, + 0,218,25,95,99,97,108,108,95,119,105,116,104,95,102,114, + 97,109,101,115,95,114,101,109,111,118,101,100,218,4,101,120, + 101,99,114,155,0,0,0,41,3,114,142,0,0,0,218,6, + 109,111,100,117,108,101,114,188,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,11,101,120,101,99, + 95,109,111,100,117,108,101,74,3,0,0,115,12,0,0,0, + 0,2,12,1,8,1,6,1,4,255,6,2,122,25,95,76, + 111,97,100,101,114,66,97,115,105,99,115,46,101,120,101,99, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,4,0,0,0,67,0,0,0, + 115,12,0,0,0,116,0,160,1,124,0,124,1,161,2,83, + 0,41,1,122,26,84,104,105,115,32,109,111,100,117,108,101, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,41, + 2,114,158,0,0,0,218,17,95,108,111,97,100,95,109,111, + 100,117,108,101,95,115,104,105,109,169,2,114,142,0,0,0, + 114,163,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,11,108,111,97,100,95,109,111,100,117,108, + 101,82,3,0,0,115,2,0,0,0,0,2,122,25,95,76, + 111,97,100,101,114,66,97,115,105,99,115,46,108,111,97,100, + 95,109,111,100,117,108,101,78,41,8,114,149,0,0,0,114, + 148,0,0,0,114,150,0,0,0,114,151,0,0,0,114,206, + 0,0,0,114,235,0,0,0,114,240,0,0,0,114,243,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,231,0,0,0,58,3,0,0,115, + 10,0,0,0,8,2,4,3,8,8,8,3,8,8,114,231, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,64,0,0,0,115,74,0,0, + 0,101,0,90,1,100,0,90,2,100,1,100,2,132,0,90, + 3,100,3,100,4,132,0,90,4,100,5,100,6,132,0,90, + 5,100,7,100,8,132,0,90,6,100,9,100,10,132,0,90, + 7,100,11,100,12,156,1,100,13,100,14,132,2,90,8,100, + 15,100,16,132,0,90,9,100,17,83,0,41,18,218,12,83, + 111,117,114,99,101,76,111,97,100,101,114,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, + 67,0,0,0,115,8,0,0,0,116,0,130,1,100,1,83, + 0,41,2,122,165,79,112,116,105,111,110,97,108,32,109,101, + 116,104,111,100,32,116,104,97,116,32,114,101,116,117,114,110, + 115,32,116,104,101,32,109,111,100,105,102,105,99,97,116,105, + 111,110,32,116,105,109,101,32,40,97,110,32,105,110,116,41, + 32,102,111,114,32,116,104,101,10,32,32,32,32,32,32,32, + 32,115,112,101,99,105,102,105,101,100,32,112,97,116,104,32, + 40,97,32,115,116,114,41,46,10,10,32,32,32,32,32,32, + 32,32,82,97,105,115,101,115,32,79,83,69,114,114,111,114, + 32,119,104,101,110,32,116,104,101,32,112,97,116,104,32,99, + 97,110,110,111,116,32,98,101,32,104,97,110,100,108,101,100, + 46,10,32,32,32,32,32,32,32,32,78,41,1,114,75,0, + 0,0,169,2,114,142,0,0,0,114,64,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,112, + 97,116,104,95,109,116,105,109,101,89,3,0,0,115,2,0, + 0,0,0,6,122,23,83,111,117,114,99,101,76,111,97,100, + 101,114,46,112,97,116,104,95,109,116,105,109,101,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,67,0,0,0,115,14,0,0,0,100,1,124,0,160, + 0,124,1,161,1,105,1,83,0,41,2,97,158,1,0,0, + 79,112,116,105,111,110,97,108,32,109,101,116,104,111,100,32, + 114,101,116,117,114,110,105,110,103,32,97,32,109,101,116,97, + 100,97,116,97,32,100,105,99,116,32,102,111,114,32,116,104, + 101,32,115,112,101,99,105,102,105,101,100,10,32,32,32,32, + 32,32,32,32,112,97,116,104,32,40,97,32,115,116,114,41, + 46,10,10,32,32,32,32,32,32,32,32,80,111,115,115,105, + 98,108,101,32,107,101,121,115,58,10,32,32,32,32,32,32, + 32,32,45,32,39,109,116,105,109,101,39,32,40,109,97,110, + 100,97,116,111,114,121,41,32,105,115,32,116,104,101,32,110, + 117,109,101,114,105,99,32,116,105,109,101,115,116,97,109,112, + 32,111,102,32,108,97,115,116,32,115,111,117,114,99,101,10, + 32,32,32,32,32,32,32,32,32,32,99,111,100,101,32,109, + 111,100,105,102,105,99,97,116,105,111,110,59,10,32,32,32, + 32,32,32,32,32,45,32,39,115,105,122,101,39,32,40,111, + 112,116,105,111,110,97,108,41,32,105,115,32,116,104,101,32, + 115,105,122,101,32,105,110,32,98,121,116,101,115,32,111,102, + 32,116,104,101,32,115,111,117,114,99,101,32,99,111,100,101, + 46,10,10,32,32,32,32,32,32,32,32,73,109,112,108,101, + 109,101,110,116,105,110,103,32,116,104,105,115,32,109,101,116, + 104,111,100,32,97,108,108,111,119,115,32,116,104,101,32,108, + 111,97,100,101,114,32,116,111,32,114,101,97,100,32,98,121, + 116,101,99,111,100,101,32,102,105,108,101,115,46,10,32,32, + 32,32,32,32,32,32,82,97,105,115,101,115,32,79,83,69, + 114,114,111,114,32,119,104,101,110,32,116,104,101,32,112,97, + 116,104,32,99,97,110,110,111,116,32,98,101,32,104,97,110, + 100,108,101,100,46,10,32,32,32,32,32,32,32,32,114,193, + 0,0,0,41,1,114,246,0,0,0,114,245,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,10, + 112,97,116,104,95,115,116,97,116,115,97,3,0,0,115,2, + 0,0,0,0,12,122,23,83,111,117,114,99,101,76,111,97, + 100,101,114,46,112,97,116,104,95,115,116,97,116,115,99,4, + 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4, + 0,0,0,67,0,0,0,115,12,0,0,0,124,0,160,0, + 124,2,124,3,161,2,83,0,41,1,122,228,79,112,116,105, + 111,110,97,108,32,109,101,116,104,111,100,32,119,104,105,99, + 104,32,119,114,105,116,101,115,32,100,97,116,97,32,40,98, + 121,116,101,115,41,32,116,111,32,97,32,102,105,108,101,32, + 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, + 32,32,32,32,32,32,32,73,109,112,108,101,109,101,110,116, + 105,110,103,32,116,104,105,115,32,109,101,116,104,111,100,32, + 97,108,108,111,119,115,32,102,111,114,32,116,104,101,32,119, + 114,105,116,105,110,103,32,111,102,32,98,121,116,101,99,111, + 100,101,32,102,105,108,101,115,46,10,10,32,32,32,32,32, + 32,32,32,84,104,101,32,115,111,117,114,99,101,32,112,97, + 116,104,32,105,115,32,110,101,101,100,101,100,32,105,110,32, + 111,114,100,101,114,32,116,111,32,99,111,114,114,101,99,116, + 108,121,32,116,114,97,110,115,102,101,114,32,112,101,114,109, + 105,115,115,105,111,110,115,10,32,32,32,32,32,32,32,32, + 41,1,218,8,115,101,116,95,100,97,116,97,41,4,114,142, + 0,0,0,114,133,0,0,0,90,10,99,97,99,104,101,95, + 112,97,116,104,114,42,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,15,95,99,97,99,104,101, + 95,98,121,116,101,99,111,100,101,111,3,0,0,115,2,0, + 0,0,0,8,122,28,83,111,117,114,99,101,76,111,97,100, + 101,114,46,95,99,97,99,104,101,95,98,121,116,101,99,111, + 100,101,99,3,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 100,1,83,0,41,2,122,150,79,112,116,105,111,110,97,108, + 32,109,101,116,104,111,100,32,119,104,105,99,104,32,119,114, + 105,116,101,115,32,100,97,116,97,32,40,98,121,116,101,115, + 41,32,116,111,32,97,32,102,105,108,101,32,112,97,116,104, + 32,40,97,32,115,116,114,41,46,10,10,32,32,32,32,32, + 32,32,32,73,109,112,108,101,109,101,110,116,105,110,103,32, + 116,104,105,115,32,109,101,116,104,111,100,32,97,108,108,111, + 119,115,32,102,111,114,32,116,104,101,32,119,114,105,116,105, + 110,103,32,111,102,32,98,121,116,101,99,111,100,101,32,102, + 105,108,101,115,46,10,32,32,32,32,32,32,32,32,78,114, + 10,0,0,0,41,3,114,142,0,0,0,114,64,0,0,0, + 114,42,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,248,0,0,0,121,3,0,0,115,2,0, + 0,0,0,1,122,21,83,111,117,114,99,101,76,111,97,100, + 101,114,46,115,101,116,95,100,97,116,97,99,2,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,10,0,0,0, + 67,0,0,0,115,82,0,0,0,124,0,160,0,124,1,161, + 1,125,2,122,14,124,0,160,1,124,2,161,1,125,3,87, + 0,110,48,4,0,116,2,107,10,114,72,1,0,125,4,1, + 0,122,18,116,3,100,1,124,1,100,2,141,2,124,4,130, + 2,87,0,53,0,100,3,125,4,126,4,88,0,89,0,110, + 2,88,0,116,4,124,3,131,1,83,0,41,4,122,52,67, + 111,110,99,114,101,116,101,32,105,109,112,108,101,109,101,110, + 116,97,116,105,111,110,32,111,102,32,73,110,115,112,101,99, + 116,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, + 99,101,46,122,39,115,111,117,114,99,101,32,110,111,116,32, + 97,118,97,105,108,97,98,108,101,32,116,104,114,111,117,103, + 104,32,103,101,116,95,100,97,116,97,40,41,114,139,0,0, + 0,78,41,5,114,203,0,0,0,218,8,103,101,116,95,100, + 97,116,97,114,75,0,0,0,114,141,0,0,0,114,200,0, + 0,0,41,5,114,142,0,0,0,114,163,0,0,0,114,64, + 0,0,0,114,198,0,0,0,218,3,101,120,99,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,10,103,101, + 116,95,115,111,117,114,99,101,128,3,0,0,115,20,0,0, + 0,0,2,10,1,2,1,14,1,16,1,4,1,2,255,4, + 1,2,255,20,2,122,23,83,111,117,114,99,101,76,111,97, + 100,101,114,46,103,101,116,95,115,111,117,114,99,101,114,129, + 0,0,0,41,1,218,9,95,111,112,116,105,109,105,122,101, + 99,3,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,8,0,0,0,67,0,0,0,115,22,0,0,0,116,0, + 106,1,116,2,124,1,124,2,100,1,100,2,124,3,100,3, + 141,6,83,0,41,4,122,130,82,101,116,117,114,110,32,116, + 104,101,32,99,111,100,101,32,111,98,106,101,99,116,32,99, + 111,109,112,105,108,101,100,32,102,114,111,109,32,115,111,117, + 114,99,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 101,32,39,100,97,116,97,39,32,97,114,103,117,109,101,110, + 116,32,99,97,110,32,98,101,32,97,110,121,32,111,98,106, + 101,99,116,32,116,121,112,101,32,116,104,97,116,32,99,111, + 109,112,105,108,101,40,41,32,115,117,112,112,111,114,116,115, + 46,10,32,32,32,32,32,32,32,32,114,238,0,0,0,84, + 41,2,218,12,100,111,110,116,95,105,110,104,101,114,105,116, + 114,107,0,0,0,41,3,114,158,0,0,0,114,237,0,0, + 0,218,7,99,111,109,112,105,108,101,41,4,114,142,0,0, + 0,114,42,0,0,0,114,64,0,0,0,114,253,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 14,115,111,117,114,99,101,95,116,111,95,99,111,100,101,138, + 3,0,0,115,8,0,0,0,0,5,12,1,2,0,2,255, + 122,27,83,111,117,114,99,101,76,111,97,100,101,114,46,115, + 111,117,114,99,101,95,116,111,95,99,111,100,101,99,2,0, + 0,0,0,0,0,0,0,0,0,0,15,0,0,0,9,0, + 0,0,67,0,0,0,115,34,2,0,0,124,0,160,0,124, + 1,161,1,125,2,100,1,125,3,100,1,125,4,100,1,125, + 5,100,2,125,6,100,3,125,7,122,12,116,1,124,2,131, + 1,125,8,87,0,110,26,4,0,116,2,107,10,114,68,1, + 0,1,0,1,0,100,1,125,8,89,0,144,1,110,48,88, + 0,122,14,124,0,160,3,124,2,161,1,125,9,87,0,110, + 22,4,0,116,4,107,10,114,106,1,0,1,0,1,0,89, + 0,144,1,110,10,88,0,116,5,124,9,100,4,25,0,131, + 1,125,3,122,14,124,0,160,6,124,8,161,1,125,10,87, + 0,110,20,4,0,116,4,107,10,114,154,1,0,1,0,1, + 0,89,0,110,218,88,0,124,1,124,8,100,5,156,2,125, + 11,122,148,116,7,124,10,124,1,124,11,131,3,125,12,116, + 8,124,10,131,1,100,6,100,1,133,2,25,0,125,13,124, + 12,100,7,64,0,100,8,107,3,125,6,124,6,144,1,114, + 36,124,12,100,9,64,0,100,8,107,3,125,7,116,9,106, + 10,100,10,107,3,144,1,114,56,124,7,115,254,116,9,106, + 10,100,11,107,2,144,1,114,56,124,0,160,6,124,2,161, + 1,125,4,116,9,160,11,116,12,124,4,161,2,125,5,116, + 13,124,10,124,5,124,1,124,11,131,4,1,0,110,20,116, + 14,124,10,124,3,124,9,100,12,25,0,124,1,124,11,131, + 5,1,0,87,0,110,26,4,0,116,15,116,16,102,2,107, + 10,144,1,114,84,1,0,1,0,1,0,89,0,110,32,88, + 0,116,17,160,18,100,13,124,8,124,2,161,3,1,0,116, + 19,124,13,124,1,124,8,124,2,100,14,141,4,83,0,124, + 4,100,1,107,8,144,1,114,136,124,0,160,6,124,2,161, + 1,125,4,124,0,160,20,124,4,124,2,161,2,125,14,116, + 17,160,18,100,15,124,2,161,2,1,0,116,21,106,22,144, + 2,115,30,124,8,100,1,107,9,144,2,114,30,124,3,100, + 1,107,9,144,2,114,30,124,6,144,1,114,228,124,5,100, + 1,107,8,144,1,114,214,116,9,160,11,124,4,161,1,125, + 5,116,23,124,14,124,5,124,7,131,3,125,10,110,16,116, + 24,124,14,124,3,116,25,124,4,131,1,131,3,125,10,122, + 18,124,0,160,26,124,2,124,8,124,10,161,3,1,0,87, + 0,110,22,4,0,116,2,107,10,144,2,114,28,1,0,1, + 0,1,0,89,0,110,2,88,0,124,14,83,0,41,16,122, + 190,67,111,110,99,114,101,116,101,32,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,32,111,102,32,73,110,115,112, + 101,99,116,76,111,97,100,101,114,46,103,101,116,95,99,111, + 100,101,46,10,10,32,32,32,32,32,32,32,32,82,101,97, + 100,105,110,103,32,111,102,32,98,121,116,101,99,111,100,101, + 32,114,101,113,117,105,114,101,115,32,112,97,116,104,95,115, + 116,97,116,115,32,116,111,32,98,101,32,105,109,112,108,101, + 109,101,110,116,101,100,46,32,84,111,32,119,114,105,116,101, + 10,32,32,32,32,32,32,32,32,98,121,116,101,99,111,100, + 101,44,32,115,101,116,95,100,97,116,97,32,109,117,115,116, + 32,97,108,115,111,32,98,101,32,105,109,112,108,101,109,101, + 110,116,101,100,46,10,10,32,32,32,32,32,32,32,32,78, + 70,84,114,193,0,0,0,114,183,0,0,0,114,169,0,0, + 0,114,4,0,0,0,114,0,0,0,0,114,44,0,0,0, + 90,5,110,101,118,101,114,90,6,97,108,119,97,121,115,218, + 4,115,105,122,101,122,13,123,125,32,109,97,116,99,104,101, + 115,32,123,125,41,3,114,140,0,0,0,114,131,0,0,0, + 114,133,0,0,0,122,19,99,111,100,101,32,111,98,106,101, + 99,116,32,102,114,111,109,32,123,125,41,27,114,203,0,0, + 0,114,120,0,0,0,114,105,0,0,0,114,247,0,0,0, + 114,75,0,0,0,114,34,0,0,0,114,250,0,0,0,114, + 176,0,0,0,218,10,109,101,109,111,114,121,118,105,101,119, + 114,187,0,0,0,90,21,99,104,101,99,107,95,104,97,115, + 104,95,98,97,115,101,100,95,112,121,99,115,114,181,0,0, + 0,218,17,95,82,65,87,95,77,65,71,73,67,95,78,85, + 77,66,69,82,114,182,0,0,0,114,180,0,0,0,114,141, + 0,0,0,114,174,0,0,0,114,158,0,0,0,114,173,0, + 0,0,114,189,0,0,0,114,0,1,0,0,114,25,0,0, + 0,218,19,100,111,110,116,95,119,114,105,116,101,95,98,121, + 116,101,99,111,100,101,114,195,0,0,0,114,194,0,0,0, + 114,6,0,0,0,114,249,0,0,0,41,15,114,142,0,0, + 0,114,163,0,0,0,114,133,0,0,0,114,178,0,0,0, + 114,198,0,0,0,114,181,0,0,0,90,10,104,97,115,104, + 95,98,97,115,101,100,90,12,99,104,101,99,107,95,115,111, + 117,114,99,101,114,131,0,0,0,218,2,115,116,114,42,0, + 0,0,114,175,0,0,0,114,106,0,0,0,90,10,98,121, + 116,101,115,95,100,97,116,97,90,11,99,111,100,101,95,111, + 98,106,101,99,116,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,236,0,0,0,146,3,0,0,115,152,0, + 0,0,0,7,10,1,4,1,4,1,4,1,4,1,4,1, + 2,1,12,1,14,1,12,2,2,1,14,1,14,1,8,2, + 12,1,2,1,14,1,14,1,6,3,2,1,2,254,6,4, + 2,1,12,1,16,1,12,1,6,1,12,1,12,1,2,255, + 2,2,8,254,4,3,10,1,4,1,2,1,2,254,4,4, + 8,1,2,255,6,3,2,1,2,1,2,1,6,1,2,1, + 2,251,8,7,20,1,6,2,8,1,2,255,4,2,6,1, + 2,1,2,254,6,3,10,1,10,1,12,1,12,1,18,1, + 6,255,4,2,6,1,10,1,10,1,14,2,6,1,6,255, + 4,2,2,1,18,1,16,1,6,1,122,21,83,111,117,114, + 99,101,76,111,97,100,101,114,46,103,101,116,95,99,111,100, + 101,78,41,10,114,149,0,0,0,114,148,0,0,0,114,150, + 0,0,0,114,246,0,0,0,114,247,0,0,0,114,249,0, + 0,0,114,248,0,0,0,114,252,0,0,0,114,0,1,0, + 0,114,236,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,244,0,0,0,87, + 3,0,0,115,14,0,0,0,8,2,8,8,8,14,8,10, + 8,7,8,10,14,8,114,244,0,0,0,99,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 0,0,0,0,115,124,0,0,0,101,0,90,1,100,0,90, + 2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100, + 5,132,0,90,5,100,6,100,7,132,0,90,6,101,7,135, + 0,102,1,100,8,100,9,132,8,131,1,90,8,101,7,100, + 10,100,11,132,0,131,1,90,9,100,12,100,13,132,0,90, + 10,101,7,100,14,100,15,132,0,131,1,90,11,100,16,100, + 17,132,0,90,12,100,18,100,19,132,0,90,13,100,20,100, + 21,132,0,90,14,100,22,100,23,132,0,90,15,135,0,4, + 0,90,16,83,0,41,24,218,10,70,105,108,101,76,111,97, + 100,101,114,122,103,66,97,115,101,32,102,105,108,101,32,108, + 111,97,100,101,114,32,99,108,97,115,115,32,119,104,105,99, + 104,32,105,109,112,108,101,109,101,110,116,115,32,116,104,101, + 32,108,111,97,100,101,114,32,112,114,111,116,111,99,111,108, + 32,109,101,116,104,111,100,115,32,116,104,97,116,10,32,32, + 32,32,114,101,113,117,105,114,101,32,102,105,108,101,32,115, + 121,115,116,101,109,32,117,115,97,103,101,46,99,3,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0, + 0,67,0,0,0,115,16,0,0,0,124,1,124,0,95,0, + 124,2,124,0,95,1,100,1,83,0,41,2,122,75,67,97, + 99,104,101,32,116,104,101,32,109,111,100,117,108,101,32,110, + 97,109,101,32,97,110,100,32,116,104,101,32,112,97,116,104, + 32,116,111,32,116,104,101,32,102,105,108,101,32,102,111,117, + 110,100,32,98,121,32,116,104,101,10,32,32,32,32,32,32, + 32,32,102,105,110,100,101,114,46,78,114,183,0,0,0,41, + 3,114,142,0,0,0,114,163,0,0,0,114,64,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 232,0,0,0,236,3,0,0,115,4,0,0,0,0,3,6, + 1,122,19,70,105,108,101,76,111,97,100,101,114,46,95,95, + 105,110,105,116,95,95,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 24,0,0,0,124,0,106,0,124,1,106,0,107,2,111,22, + 124,0,106,1,124,1,106,1,107,2,83,0,114,68,0,0, + 0,169,2,218,9,95,95,99,108,97,115,115,95,95,114,155, + 0,0,0,169,2,114,142,0,0,0,90,5,111,116,104,101, + 114,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,6,95,95,101,113,95,95,242,3,0,0,115,6,0,0, + 0,0,1,12,1,10,255,122,17,70,105,108,101,76,111,97, + 100,101,114,46,95,95,101,113,95,95,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,20,0,0,0,116,0,124,0,106,1,131,1, + 116,0,124,0,106,2,131,1,65,0,83,0,114,68,0,0, + 0,169,3,218,4,104,97,115,104,114,140,0,0,0,114,64, + 0,0,0,169,1,114,142,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,8,95,95,104,97,115, + 104,95,95,246,3,0,0,115,2,0,0,0,0,1,122,19, + 70,105,108,101,76,111,97,100,101,114,46,95,95,104,97,115, + 104,95,95,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,3,0,0,0,3,0,0,0,115,16,0,0, + 0,116,0,116,1,124,0,131,2,160,2,124,1,161,1,83, + 0,41,1,122,100,76,111,97,100,32,97,32,109,111,100,117, + 108,101,32,102,114,111,109,32,97,32,102,105,108,101,46,10, + 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, + 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,46,32,32,85,115,101,32,101,120,101,99,95,109,111, + 100,117,108,101,40,41,32,105,110,115,116,101,97,100,46,10, + 10,32,32,32,32,32,32,32,32,41,3,218,5,115,117,112, + 101,114,114,6,1,0,0,114,243,0,0,0,114,242,0,0, + 0,169,1,114,8,1,0,0,114,10,0,0,0,114,11,0, + 0,0,114,243,0,0,0,249,3,0,0,115,2,0,0,0, + 0,10,122,22,70,105,108,101,76,111,97,100,101,114,46,108, + 111,97,100,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,6,0,0,0,124,0,106,0,83,0,169,1, + 122,58,82,101,116,117,114,110,32,116,104,101,32,112,97,116, + 104,32,116,111,32,116,104,101,32,115,111,117,114,99,101,32, + 102,105,108,101,32,97,115,32,102,111,117,110,100,32,98,121, + 32,116,104,101,32,102,105,110,100,101,114,46,114,70,0,0, + 0,114,242,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,203,0,0,0,5,4,0,0,115,2, + 0,0,0,0,3,122,23,70,105,108,101,76,111,97,100,101, + 114,46,103,101,116,95,102,105,108,101,110,97,109,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,10, + 0,0,0,67,0,0,0,115,102,0,0,0,116,0,124,0, + 116,1,116,2,102,2,131,2,114,58,116,3,160,4,116,5, + 124,1,131,1,161,1,143,22,125,2,124,2,160,6,161,0, + 87,0,2,0,53,0,81,0,82,0,163,0,83,0,81,0, + 82,0,88,0,110,40,116,3,160,7,124,1,100,1,161,2, + 143,22,125,2,124,2,160,6,161,0,87,0,2,0,53,0, + 81,0,82,0,163,0,83,0,81,0,82,0,88,0,100,2, + 83,0,41,3,122,39,82,101,116,117,114,110,32,116,104,101, + 32,100,97,116,97,32,102,114,111,109,32,112,97,116,104,32, + 97,115,32,114,97,119,32,98,121,116,101,115,46,218,1,114, + 78,41,8,114,185,0,0,0,114,244,0,0,0,218,19,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 101,114,114,89,0,0,0,90,9,111,112,101,110,95,99,111, + 100,101,114,108,0,0,0,90,4,114,101,97,100,114,90,0, + 0,0,41,3,114,142,0,0,0,114,64,0,0,0,114,92, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,250,0,0,0,10,4,0,0,115,10,0,0,0, + 0,2,14,1,16,1,28,2,14,1,122,19,70,105,108,101, + 76,111,97,100,101,114,46,103,101,116,95,100,97,116,97,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 3,0,0,0,67,0,0,0,115,18,0,0,0,124,0,160, + 0,124,1,161,1,114,14,124,0,83,0,100,0,83,0,114, + 68,0,0,0,41,1,114,206,0,0,0,169,2,114,142,0, + 0,0,114,239,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,19,103,101,116,95,114,101,115,111, + 117,114,99,101,95,114,101,97,100,101,114,21,4,0,0,115, + 6,0,0,0,0,2,10,1,4,1,122,30,70,105,108,101, + 76,111,97,100,101,114,46,103,101,116,95,114,101,115,111,117, + 114,99,101,95,114,101,97,100,101,114,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,4,0,0,0,67, + 0,0,0,115,32,0,0,0,116,0,116,1,124,0,106,2, + 131,1,100,1,25,0,124,1,131,2,125,2,116,3,160,4, + 124,2,100,2,161,2,83,0,41,3,78,114,0,0,0,0, + 114,18,1,0,0,41,5,114,66,0,0,0,114,73,0,0, + 0,114,64,0,0,0,114,89,0,0,0,114,90,0,0,0, + 169,3,114,142,0,0,0,90,8,114,101,115,111,117,114,99, + 101,114,64,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,13,111,112,101,110,95,114,101,115,111, + 117,114,99,101,27,4,0,0,115,4,0,0,0,0,1,20, + 1,122,24,70,105,108,101,76,111,97,100,101,114,46,111,112, + 101,110,95,114,101,115,111,117,114,99,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, + 67,0,0,0,115,38,0,0,0,124,0,160,0,124,1,161, + 1,115,14,116,1,130,1,116,2,116,3,124,0,106,4,131, + 1,100,1,25,0,124,1,131,2,125,2,124,2,83,0,169, + 2,78,114,0,0,0,0,41,5,218,11,105,115,95,114,101, + 115,111,117,114,99,101,218,17,70,105,108,101,78,111,116,70, + 111,117,110,100,69,114,114,111,114,114,66,0,0,0,114,73, + 0,0,0,114,64,0,0,0,114,22,1,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,13,114,101, + 115,111,117,114,99,101,95,112,97,116,104,31,4,0,0,115, + 8,0,0,0,0,1,10,1,4,1,20,1,122,24,70,105, + 108,101,76,111,97,100,101,114,46,114,101,115,111,117,114,99, + 101,95,112,97,116,104,99,2,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, + 40,0,0,0,116,0,124,1,107,6,114,12,100,1,83,0, + 116,1,116,2,124,0,106,3,131,1,100,2,25,0,124,1, + 131,2,125,2,116,4,124,2,131,1,83,0,41,3,78,70, + 114,0,0,0,0,41,5,114,58,0,0,0,114,66,0,0, + 0,114,73,0,0,0,114,64,0,0,0,114,79,0,0,0, + 169,3,114,142,0,0,0,114,140,0,0,0,114,64,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,25,1,0,0,37,4,0,0,115,8,0,0,0,0,1, + 8,1,4,1,20,1,122,22,70,105,108,101,76,111,97,100, + 101,114,46,105,115,95,114,101,115,111,117,114,99,101,99,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5, + 0,0,0,67,0,0,0,115,24,0,0,0,116,0,116,1, + 160,2,116,3,124,0,106,4,131,1,100,1,25,0,161,1, + 131,1,83,0,114,24,1,0,0,41,5,218,4,105,116,101, + 114,114,21,0,0,0,218,7,108,105,115,116,100,105,114,114, + 73,0,0,0,114,64,0,0,0,114,13,1,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,8,99, + 111,110,116,101,110,116,115,43,4,0,0,115,2,0,0,0, + 0,1,122,19,70,105,108,101,76,111,97,100,101,114,46,99, + 111,110,116,101,110,116,115,41,17,114,149,0,0,0,114,148, + 0,0,0,114,150,0,0,0,114,151,0,0,0,114,232,0, + 0,0,114,10,1,0,0,114,14,1,0,0,114,160,0,0, + 0,114,243,0,0,0,114,203,0,0,0,114,250,0,0,0, + 114,21,1,0,0,114,23,1,0,0,114,27,1,0,0,114, + 25,1,0,0,114,31,1,0,0,90,13,95,95,99,108,97, + 115,115,99,101,108,108,95,95,114,10,0,0,0,114,10,0, + 0,0,114,16,1,0,0,114,11,0,0,0,114,6,1,0, + 0,231,3,0,0,115,30,0,0,0,8,2,4,3,8,6, + 8,4,8,3,2,1,14,11,2,1,10,4,8,11,2,1, + 10,5,8,4,8,6,8,6,114,6,1,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,64,0,0,0,115,46,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, + 4,100,5,132,0,90,5,100,6,100,7,156,1,100,8,100, + 9,132,2,90,6,100,10,83,0,41,11,218,16,83,111,117, + 114,99,101,70,105,108,101,76,111,97,100,101,114,122,62,67, + 111,110,99,114,101,116,101,32,105,109,112,108,101,109,101,110, + 116,97,116,105,111,110,32,111,102,32,83,111,117,114,99,101, + 76,111,97,100,101,114,32,117,115,105,110,103,32,116,104,101, + 32,102,105,108,101,32,115,121,115,116,101,109,46,99,2,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,22,0,0,0,116,0,124,1,131, + 1,125,2,124,2,106,1,124,2,106,2,100,1,156,2,83, + 0,41,2,122,33,82,101,116,117,114,110,32,116,104,101,32, + 109,101,116,97,100,97,116,97,32,102,111,114,32,116,104,101, + 32,112,97,116,104,46,41,2,114,193,0,0,0,114,1,1, + 0,0,41,3,114,74,0,0,0,218,8,115,116,95,109,116, + 105,109,101,90,7,115,116,95,115,105,122,101,41,3,114,142, + 0,0,0,114,64,0,0,0,114,5,1,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,247,0,0, + 0,51,4,0,0,115,4,0,0,0,0,2,8,1,122,27, + 83,111,117,114,99,101,70,105,108,101,76,111,97,100,101,114, + 46,112,97,116,104,95,115,116,97,116,115,99,4,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,24,0,0,0,116,0,124,1,131,1,125, + 4,124,0,106,1,124,2,124,3,124,4,100,1,141,3,83, + 0,41,2,78,169,1,218,5,95,109,111,100,101,41,2,114, + 138,0,0,0,114,248,0,0,0,41,5,114,142,0,0,0, + 114,133,0,0,0,114,131,0,0,0,114,42,0,0,0,114, + 77,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,249,0,0,0,56,4,0,0,115,4,0,0, + 0,0,2,8,1,122,32,83,111,117,114,99,101,70,105,108, + 101,76,111,97,100,101,114,46,95,99,97,99,104,101,95,98, + 121,116,101,99,111,100,101,114,85,0,0,0,114,34,1,0, + 0,99,3,0,0,0,0,0,0,0,1,0,0,0,9,0, + 0,0,11,0,0,0,67,0,0,0,115,252,0,0,0,116, + 0,124,1,131,1,92,2,125,4,125,5,103,0,125,6,124, + 4,114,52,116,1,124,4,131,1,115,52,116,0,124,4,131, + 1,92,2,125,4,125,7,124,6,160,2,124,7,161,1,1, + 0,113,16,116,3,124,6,131,1,68,0,93,108,125,7,116, + 4,124,4,124,7,131,2,125,4,122,14,116,5,160,6,124, + 4,161,1,1,0,87,0,113,60,4,0,116,7,107,10,114, + 112,1,0,1,0,1,0,89,0,113,60,89,0,113,60,4, + 0,116,8,107,10,114,166,1,0,125,8,1,0,122,26,116, + 9,160,10,100,1,124,4,124,8,161,3,1,0,87,0,89, + 0,162,6,1,0,100,2,83,0,100,2,125,8,126,8,88, + 0,89,0,113,60,88,0,113,60,122,28,116,11,124,1,124, + 2,124,3,131,3,1,0,116,9,160,10,100,3,124,1,161, + 2,1,0,87,0,110,48,4,0,116,8,107,10,114,246,1, + 0,125,8,1,0,122,18,116,9,160,10,100,1,124,1,124, + 8,161,3,1,0,87,0,53,0,100,2,125,8,126,8,88, + 0,89,0,110,2,88,0,100,2,83,0,41,4,122,27,87, + 114,105,116,101,32,98,121,116,101,115,32,100,97,116,97,32, + 116,111,32,97,32,102,105,108,101,46,122,27,99,111,117,108, + 100,32,110,111,116,32,99,114,101,97,116,101,32,123,33,114, + 125,58,32,123,33,114,125,78,122,12,99,114,101,97,116,101, + 100,32,123,33,114,125,41,12,114,73,0,0,0,114,81,0, + 0,0,114,60,0,0,0,218,8,114,101,118,101,114,115,101, + 100,114,66,0,0,0,114,21,0,0,0,90,5,109,107,100, + 105,114,218,15,70,105,108,101,69,120,105,115,116,115,69,114, + 114,111,114,114,75,0,0,0,114,158,0,0,0,114,173,0, + 0,0,114,93,0,0,0,41,9,114,142,0,0,0,114,64, + 0,0,0,114,42,0,0,0,114,35,1,0,0,218,6,112, + 97,114,101,110,116,114,119,0,0,0,114,62,0,0,0,114, + 67,0,0,0,114,251,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,248,0,0,0,61,4,0, + 0,115,48,0,0,0,0,2,12,1,4,2,12,1,12,1, + 12,2,12,1,10,1,2,1,14,1,14,2,8,1,16,3, + 6,1,2,0,2,255,4,2,28,1,2,1,12,1,16,1, + 16,2,8,1,2,255,122,25,83,111,117,114,99,101,70,105, + 108,101,76,111,97,100,101,114,46,115,101,116,95,100,97,116, + 97,78,41,7,114,149,0,0,0,114,148,0,0,0,114,150, + 0,0,0,114,151,0,0,0,114,247,0,0,0,114,249,0, + 0,0,114,248,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,32,1,0,0, + 47,4,0,0,115,8,0,0,0,8,2,4,2,8,5,8, + 5,114,32,1,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115, + 32,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, + 100,2,100,3,132,0,90,4,100,4,100,5,132,0,90,5, + 100,6,83,0,41,7,218,20,83,111,117,114,99,101,108,101, + 115,115,70,105,108,101,76,111,97,100,101,114,122,45,76,111, + 97,100,101,114,32,119,104,105,99,104,32,104,97,110,100,108, + 101,115,32,115,111,117,114,99,101,108,101,115,115,32,102,105, + 108,101,32,105,109,112,111,114,116,115,46,99,2,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,68,0,0,0,124,0,160,0,124,1,161, + 1,125,2,124,0,160,1,124,2,161,1,125,3,124,1,124, + 2,100,1,156,2,125,4,116,2,124,3,124,1,124,4,131, + 3,1,0,116,3,116,4,124,3,131,1,100,2,100,0,133, + 2,25,0,124,1,124,2,100,3,141,3,83,0,41,4,78, + 114,183,0,0,0,114,169,0,0,0,41,2,114,140,0,0, + 0,114,131,0,0,0,41,5,114,203,0,0,0,114,250,0, + 0,0,114,176,0,0,0,114,189,0,0,0,114,2,1,0, + 0,41,5,114,142,0,0,0,114,163,0,0,0,114,64,0, + 0,0,114,42,0,0,0,114,175,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,236,0,0,0, + 96,4,0,0,115,22,0,0,0,0,1,10,1,10,4,2, + 1,2,254,6,4,12,1,2,1,14,1,2,1,2,253,122, + 29,83,111,117,114,99,101,108,101,115,115,70,105,108,101,76, + 111,97,100,101,114,46,103,101,116,95,99,111,100,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, + 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,122,39,82,101,116,117,114,110,32,78,111,110,101,32, + 97,115,32,116,104,101,114,101,32,105,115,32,110,111,32,115, + 111,117,114,99,101,32,99,111,100,101,46,78,114,10,0,0, + 0,114,242,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,252,0,0,0,112,4,0,0,115,2, + 0,0,0,0,2,122,31,83,111,117,114,99,101,108,101,115, + 115,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, + 115,111,117,114,99,101,78,41,6,114,149,0,0,0,114,148, + 0,0,0,114,150,0,0,0,114,151,0,0,0,114,236,0, + 0,0,114,252,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,39,1,0,0, + 92,4,0,0,115,6,0,0,0,8,2,4,2,8,16,114, + 39,1,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,64,0,0,0,115,92,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, + 100,7,132,0,90,6,100,8,100,9,132,0,90,7,100,10, + 100,11,132,0,90,8,100,12,100,13,132,0,90,9,100,14, + 100,15,132,0,90,10,100,16,100,17,132,0,90,11,101,12, + 100,18,100,19,132,0,131,1,90,13,100,20,83,0,41,21, + 114,19,1,0,0,122,93,76,111,97,100,101,114,32,102,111, + 114,32,101,120,116,101,110,115,105,111,110,32,109,111,100,117, + 108,101,115,46,10,10,32,32,32,32,84,104,101,32,99,111, + 110,115,116,114,117,99,116,111,114,32,105,115,32,100,101,115, + 105,103,110,101,100,32,116,111,32,119,111,114,107,32,119,105, + 116,104,32,70,105,108,101,70,105,110,100,101,114,46,10,10, + 32,32,32,32,99,3,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,2,0,0,0,67,0,0,0,115,16,0, + 0,0,124,1,124,0,95,0,124,2,124,0,95,1,100,0, + 83,0,114,68,0,0,0,114,183,0,0,0,114,28,1,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,232,0,0,0,129,4,0,0,115,4,0,0,0,0,1, + 6,1,122,28,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,95,95,105,110,105,116,95,95, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,2,0,0,0,67,0,0,0,115,24,0,0,0,124,0, + 106,0,124,1,106,0,107,2,111,22,124,0,106,1,124,1, + 106,1,107,2,83,0,114,68,0,0,0,114,7,1,0,0, + 114,9,1,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,10,1,0,0,133,4,0,0,115,6,0, + 0,0,0,1,12,1,10,255,122,26,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,95,95, + 101,113,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,67,0,0,0,115,20,0, + 0,0,116,0,124,0,106,1,131,1,116,0,124,0,106,2, + 131,1,65,0,83,0,114,68,0,0,0,114,11,1,0,0, + 114,13,1,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,14,1,0,0,137,4,0,0,115,2,0, + 0,0,0,1,122,28,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,95,95,104,97,115,104, + 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,5,0,0,0,67,0,0,0,115,36,0,0,0, + 116,0,160,1,116,2,106,3,124,1,161,2,125,2,116,0, + 160,4,100,1,124,1,106,5,124,0,106,6,161,3,1,0, + 124,2,83,0,41,2,122,38,67,114,101,97,116,101,32,97, + 110,32,117,110,105,116,105,97,108,105,122,101,100,32,101,120, + 116,101,110,115,105,111,110,32,109,111,100,117,108,101,122,38, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 32,123,33,114,125,32,108,111,97,100,101,100,32,102,114,111, + 109,32,123,33,114,125,41,7,114,158,0,0,0,114,237,0, + 0,0,114,187,0,0,0,90,14,99,114,101,97,116,101,95, + 100,121,110,97,109,105,99,114,173,0,0,0,114,140,0,0, + 0,114,64,0,0,0,41,3,114,142,0,0,0,114,210,0, + 0,0,114,239,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,235,0,0,0,140,4,0,0,115, + 18,0,0,0,0,2,4,1,4,0,2,255,4,2,6,1, + 4,0,4,255,4,2,122,33,69,120,116,101,110,115,105,111, + 110,70,105,108,101,76,111,97,100,101,114,46,99,114,101,97, + 116,101,95,109,111,100,117,108,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,5,0,0,0,67,0, + 0,0,115,36,0,0,0,116,0,160,1,116,2,106,3,124, + 1,161,2,1,0,116,0,160,4,100,1,124,0,106,5,124, + 0,106,6,161,3,1,0,100,2,83,0,41,3,122,30,73, + 110,105,116,105,97,108,105,122,101,32,97,110,32,101,120,116, + 101,110,115,105,111,110,32,109,111,100,117,108,101,122,40,101, + 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,32, + 123,33,114,125,32,101,120,101,99,117,116,101,100,32,102,114, + 111,109,32,123,33,114,125,78,41,7,114,158,0,0,0,114, + 237,0,0,0,114,187,0,0,0,90,12,101,120,101,99,95, + 100,121,110,97,109,105,99,114,173,0,0,0,114,140,0,0, + 0,114,64,0,0,0,114,20,1,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,240,0,0,0,148, + 4,0,0,115,10,0,0,0,0,2,14,1,6,1,4,0, + 4,255,122,31,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,101,120,101,99,95,109,111,100, + 117,108,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,4,0,0,0,3,0,0,0,115,36,0,0, + 0,116,0,124,0,106,1,131,1,100,1,25,0,137,0,116, + 2,135,0,102,1,100,2,100,3,132,8,116,3,68,0,131, + 1,131,1,83,0,41,4,122,49,82,101,116,117,114,110,32, + 84,114,117,101,32,105,102,32,116,104,101,32,101,120,116,101, + 110,115,105,111,110,32,109,111,100,117,108,101,32,105,115,32, + 97,32,112,97,99,107,97,103,101,46,114,4,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 4,0,0,0,51,0,0,0,115,26,0,0,0,124,0,93, + 18,125,1,136,0,100,0,124,1,23,0,107,2,86,0,1, + 0,113,2,100,1,83,0,41,2,114,232,0,0,0,78,114, + 10,0,0,0,169,2,114,8,0,0,0,218,6,115,117,102, + 102,105,120,169,1,90,9,102,105,108,101,95,110,97,109,101, + 114,10,0,0,0,114,11,0,0,0,114,12,0,0,0,157, + 4,0,0,115,4,0,0,0,4,1,2,255,122,49,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,105,115,95,112,97,99,107,97,103,101,46,60,108,111, + 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,41, + 4,114,73,0,0,0,114,64,0,0,0,218,3,97,110,121, + 218,18,69,88,84,69,78,83,73,79,78,95,83,85,70,70, + 73,88,69,83,114,242,0,0,0,114,10,0,0,0,114,42, + 1,0,0,114,11,0,0,0,114,206,0,0,0,154,4,0, + 0,115,8,0,0,0,0,2,14,1,12,1,2,255,122,30, + 69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,97, + 100,101,114,46,105,115,95,112,97,99,107,97,103,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, + 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,122,63,82,101,116,117,114,110,32,78,111,110,101,32, + 97,115,32,97,110,32,101,120,116,101,110,115,105,111,110,32, + 109,111,100,117,108,101,32,99,97,110,110,111,116,32,99,114, + 101,97,116,101,32,97,32,99,111,100,101,32,111,98,106,101, + 99,116,46,78,114,10,0,0,0,114,242,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,236,0, + 0,0,160,4,0,0,115,2,0,0,0,0,2,122,28,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, + 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122, + 53,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 115,32,104,97,118,101,32,110,111,32,115,111,117,114,99,101, + 32,99,111,100,101,46,78,114,10,0,0,0,114,242,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,252,0,0,0,164,4,0,0,115,2,0,0,0,0,2, + 122,30,69,120,116,101,110,115,105,111,110,70,105,108,101,76, + 111,97,100,101,114,46,103,101,116,95,115,111,117,114,99,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,6,0,0,0,124,0, + 106,0,83,0,114,17,1,0,0,114,70,0,0,0,114,242, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,203,0,0,0,168,4,0,0,115,2,0,0,0, + 0,3,122,32,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,102,105,108,101, + 110,97,109,101,78,41,14,114,149,0,0,0,114,148,0,0, + 0,114,150,0,0,0,114,151,0,0,0,114,232,0,0,0, + 114,10,1,0,0,114,14,1,0,0,114,235,0,0,0,114, + 240,0,0,0,114,206,0,0,0,114,236,0,0,0,114,252, + 0,0,0,114,160,0,0,0,114,203,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,19,1,0,0,121,4,0,0,115,22,0,0,0,8, + 2,4,6,8,4,8,4,8,3,8,8,8,6,8,6,8, + 4,8,4,2,1,114,19,1,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, + 0,0,0,115,104,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, + 132,0,90,5,100,6,100,7,132,0,90,6,100,8,100,9, + 132,0,90,7,100,10,100,11,132,0,90,8,100,12,100,13, + 132,0,90,9,100,14,100,15,132,0,90,10,100,16,100,17, + 132,0,90,11,100,18,100,19,132,0,90,12,100,20,100,21, + 132,0,90,13,100,22,100,23,132,0,90,14,100,24,83,0, + 41,25,218,14,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,97,38,1,0,0,82,101,112,114,101,115,101,110,116, + 115,32,97,32,110,97,109,101,115,112,97,99,101,32,112,97, + 99,107,97,103,101,39,115,32,112,97,116,104,46,32,32,73, + 116,32,117,115,101,115,32,116,104,101,32,109,111,100,117,108, + 101,32,110,97,109,101,10,32,32,32,32,116,111,32,102,105, + 110,100,32,105,116,115,32,112,97,114,101,110,116,32,109,111, + 100,117,108,101,44,32,97,110,100,32,102,114,111,109,32,116, + 104,101,114,101,32,105,116,32,108,111,111,107,115,32,117,112, + 32,116,104,101,32,112,97,114,101,110,116,39,115,10,32,32, + 32,32,95,95,112,97,116,104,95,95,46,32,32,87,104,101, + 110,32,116,104,105,115,32,99,104,97,110,103,101,115,44,32, + 116,104,101,32,109,111,100,117,108,101,39,115,32,111,119,110, + 32,112,97,116,104,32,105,115,32,114,101,99,111,109,112,117, + 116,101,100,44,10,32,32,32,32,117,115,105,110,103,32,112, + 97,116,104,95,102,105,110,100,101,114,46,32,32,70,111,114, + 32,116,111,112,45,108,101,118,101,108,32,109,111,100,117,108, + 101,115,44,32,116,104,101,32,112,97,114,101,110,116,32,109, + 111,100,117,108,101,39,115,32,112,97,116,104,10,32,32,32, + 32,105,115,32,115,121,115,46,112,97,116,104,46,99,4,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,3,0, + 0,0,67,0,0,0,115,36,0,0,0,124,1,124,0,95, + 0,124,2,124,0,95,1,116,2,124,0,160,3,161,0,131, + 1,124,0,95,4,124,3,124,0,95,5,100,0,83,0,114, + 68,0,0,0,41,6,218,5,95,110,97,109,101,218,5,95, + 112,97,116,104,114,135,0,0,0,218,16,95,103,101,116,95, + 112,97,114,101,110,116,95,112,97,116,104,218,17,95,108,97, + 115,116,95,112,97,114,101,110,116,95,112,97,116,104,218,12, + 95,112,97,116,104,95,102,105,110,100,101,114,169,4,114,142, + 0,0,0,114,140,0,0,0,114,64,0,0,0,90,11,112, + 97,116,104,95,102,105,110,100,101,114,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,232,0,0,0,181,4, + 0,0,115,8,0,0,0,0,1,6,1,6,1,14,1,122, + 23,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,95,105,110,105,116,95,95,99,1,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,3,0,0,0,67,0,0, + 0,115,38,0,0,0,124,0,106,0,160,1,100,1,161,1, + 92,3,125,1,125,2,125,3,124,2,100,2,107,2,114,30, + 100,3,83,0,124,1,100,4,102,2,83,0,41,5,122,62, + 82,101,116,117,114,110,115,32,97,32,116,117,112,108,101,32, + 111,102,32,40,112,97,114,101,110,116,45,109,111,100,117,108, + 101,45,110,97,109,101,44,32,112,97,114,101,110,116,45,112, + 97,116,104,45,97,116,116,114,45,110,97,109,101,41,114,95, + 0,0,0,114,13,0,0,0,41,2,114,25,0,0,0,114, + 64,0,0,0,90,8,95,95,112,97,116,104,95,95,41,2, + 114,46,1,0,0,114,102,0,0,0,41,4,114,142,0,0, + 0,114,38,1,0,0,218,3,100,111,116,90,2,109,101,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,23, + 95,102,105,110,100,95,112,97,114,101,110,116,95,112,97,116, + 104,95,110,97,109,101,115,187,4,0,0,115,8,0,0,0, + 0,2,18,1,8,2,4,3,122,38,95,78,97,109,101,115, + 112,97,99,101,80,97,116,104,46,95,102,105,110,100,95,112, + 97,114,101,110,116,95,112,97,116,104,95,110,97,109,101,115, + 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,3,0,0,0,67,0,0,0,115,28,0,0,0,124,0, + 160,0,161,0,92,2,125,1,125,2,116,1,116,2,106,3, + 124,1,25,0,124,2,131,2,83,0,114,68,0,0,0,41, + 4,114,53,1,0,0,114,154,0,0,0,114,25,0,0,0, + 218,7,109,111,100,117,108,101,115,41,3,114,142,0,0,0, + 90,18,112,97,114,101,110,116,95,109,111,100,117,108,101,95, + 110,97,109,101,90,14,112,97,116,104,95,97,116,116,114,95, + 110,97,109,101,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,48,1,0,0,197,4,0,0,115,4,0,0, + 0,0,1,12,1,122,31,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,95,103,101,116,95,112,97,114,101,110, + 116,95,112,97,116,104,99,1,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, + 80,0,0,0,116,0,124,0,160,1,161,0,131,1,125,1, + 124,1,124,0,106,2,107,3,114,74,124,0,160,3,124,0, + 106,4,124,1,161,2,125,2,124,2,100,0,107,9,114,68, + 124,2,106,5,100,0,107,8,114,68,124,2,106,6,114,68, + 124,2,106,6,124,0,95,7,124,1,124,0,95,2,124,0, + 106,7,83,0,114,68,0,0,0,41,8,114,135,0,0,0, + 114,48,1,0,0,114,49,1,0,0,114,50,1,0,0,114, + 46,1,0,0,114,164,0,0,0,114,202,0,0,0,114,47, + 1,0,0,41,3,114,142,0,0,0,90,11,112,97,114,101, + 110,116,95,112,97,116,104,114,210,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,12,95,114,101, + 99,97,108,99,117,108,97,116,101,201,4,0,0,115,16,0, + 0,0,0,2,12,1,10,1,14,3,18,1,6,1,8,1, + 6,1,122,27,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,46,95,114,101,99,97,108,99,117,108,97,116,101,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,12,0,0,0,116,0,124, + 0,160,1,161,0,131,1,83,0,114,68,0,0,0,41,2, + 114,29,1,0,0,114,55,1,0,0,114,13,1,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, + 95,95,105,116,101,114,95,95,214,4,0,0,115,2,0,0, + 0,0,1,122,23,95,78,97,109,101,115,112,97,99,101,80, + 97,116,104,46,95,95,105,116,101,114,95,95,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0, + 0,67,0,0,0,115,12,0,0,0,124,0,160,0,161,0, + 124,1,25,0,83,0,114,68,0,0,0,169,1,114,55,1, + 0,0,41,2,114,142,0,0,0,218,5,105,110,100,101,120, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 11,95,95,103,101,116,105,116,101,109,95,95,217,4,0,0, + 115,2,0,0,0,0,1,122,26,95,78,97,109,101,115,112, + 97,99,101,80,97,116,104,46,95,95,103,101,116,105,116,101, + 109,95,95,99,3,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,3,0,0,0,67,0,0,0,115,14,0,0, + 0,124,2,124,0,106,0,124,1,60,0,100,0,83,0,114, + 68,0,0,0,41,1,114,47,1,0,0,41,3,114,142,0, + 0,0,114,58,1,0,0,114,64,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,11,95,95,115, + 101,116,105,116,101,109,95,95,220,4,0,0,115,2,0,0, + 0,0,1,122,26,95,78,97,109,101,115,112,97,99,101,80, + 97,116,104,46,95,95,115,101,116,105,116,101,109,95,95,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,12,0,0,0,116,0,124, + 0,160,1,161,0,131,1,83,0,114,68,0,0,0,41,2, + 114,6,0,0,0,114,55,1,0,0,114,13,1,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,7, + 95,95,108,101,110,95,95,223,4,0,0,115,2,0,0,0, + 0,1,122,22,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,46,95,95,108,101,110,95,95,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,12,0,0,0,100,1,160,0,124,0,106,1, + 161,1,83,0,41,2,78,122,20,95,78,97,109,101,115,112, + 97,99,101,80,97,116,104,40,123,33,114,125,41,41,2,114, + 87,0,0,0,114,47,1,0,0,114,13,1,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,8,95, + 95,114,101,112,114,95,95,226,4,0,0,115,2,0,0,0, + 0,1,122,23,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,46,95,95,114,101,112,114,95,95,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 67,0,0,0,115,12,0,0,0,124,1,124,0,160,0,161, + 0,107,6,83,0,114,68,0,0,0,114,57,1,0,0,169, + 2,114,142,0,0,0,218,4,105,116,101,109,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,12,95,95,99, + 111,110,116,97,105,110,115,95,95,229,4,0,0,115,2,0, + 0,0,0,1,122,27,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,99,111,110,116,97,105,110,115,95, + 95,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,124, + 0,106,0,160,1,124,1,161,1,1,0,100,0,83,0,114, + 68,0,0,0,41,2,114,47,1,0,0,114,60,0,0,0, + 114,63,1,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,60,0,0,0,232,4,0,0,115,2,0, + 0,0,0,1,122,21,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,97,112,112,101,110,100,78,41,15,114,149, + 0,0,0,114,148,0,0,0,114,150,0,0,0,114,151,0, + 0,0,114,232,0,0,0,114,53,1,0,0,114,48,1,0, + 0,114,55,1,0,0,114,56,1,0,0,114,59,1,0,0, + 114,60,1,0,0,114,61,1,0,0,114,62,1,0,0,114, + 65,1,0,0,114,60,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,45,1, + 0,0,174,4,0,0,115,24,0,0,0,8,1,4,6,8, + 6,8,10,8,4,8,13,8,3,8,3,8,3,8,3,8, + 3,8,3,114,45,1,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, + 0,115,80,0,0,0,101,0,90,1,100,0,90,2,100,1, + 100,2,132,0,90,3,101,4,100,3,100,4,132,0,131,1, + 90,5,100,5,100,6,132,0,90,6,100,7,100,8,132,0, + 90,7,100,9,100,10,132,0,90,8,100,11,100,12,132,0, + 90,9,100,13,100,14,132,0,90,10,100,15,100,16,132,0, + 90,11,100,17,83,0,41,18,218,16,95,78,97,109,101,115, + 112,97,99,101,76,111,97,100,101,114,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, + 0,0,0,115,18,0,0,0,116,0,124,1,124,2,124,3, + 131,3,124,0,95,1,100,0,83,0,114,68,0,0,0,41, + 2,114,45,1,0,0,114,47,1,0,0,114,51,1,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 232,0,0,0,238,4,0,0,115,2,0,0,0,0,1,122, + 25,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, + 0,0,0,115,12,0,0,0,100,1,160,0,124,1,106,1, + 161,1,83,0,41,2,122,115,82,101,116,117,114,110,32,114, + 101,112,114,32,102,111,114,32,116,104,101,32,109,111,100,117, + 108,101,46,10,10,32,32,32,32,32,32,32,32,84,104,101, + 32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101, + 99,97,116,101,100,46,32,32,84,104,101,32,105,109,112,111, + 114,116,32,109,97,99,104,105,110,101,114,121,32,100,111,101, + 115,32,116,104,101,32,106,111,98,32,105,116,115,101,108,102, + 46,10,10,32,32,32,32,32,32,32,32,122,25,60,109,111, + 100,117,108,101,32,123,33,114,125,32,40,110,97,109,101,115, + 112,97,99,101,41,62,41,2,114,87,0,0,0,114,149,0, + 0,0,41,2,114,216,0,0,0,114,239,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,11,109, + 111,100,117,108,101,95,114,101,112,114,241,4,0,0,115,2, + 0,0,0,0,7,122,28,95,78,97,109,101,115,112,97,99, + 101,76,111,97,100,101,114,46,109,111,100,117,108,101,95,114, + 101,112,114,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,83,0,41,2,78,84,114,10,0,0,0,114,242, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,206,0,0,0,250,4,0,0,115,2,0,0,0, + 0,1,122,27,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,105,115,95,112,97,99,107,97,103,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, + 0,41,2,78,114,13,0,0,0,114,10,0,0,0,114,242, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,252,0,0,0,253,4,0,0,115,2,0,0,0, + 0,1,122,27,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 6,0,0,0,67,0,0,0,115,16,0,0,0,116,0,100, + 1,100,2,100,3,100,4,100,5,141,4,83,0,41,6,78, + 114,13,0,0,0,122,8,60,115,116,114,105,110,103,62,114, + 238,0,0,0,84,41,1,114,254,0,0,0,41,1,114,255, + 0,0,0,114,242,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,236,0,0,0,0,5,0,0, + 115,2,0,0,0,0,1,122,25,95,78,97,109,101,115,112, + 97,99,101,76,111,97,100,101,114,46,103,101,116,95,99,111, + 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 100,1,83,0,114,233,0,0,0,114,10,0,0,0,114,234, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,235,0,0,0,3,5,0,0,115,2,0,0,0, + 0,1,122,30,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,99,114,101,97,116,101,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 100,0,83,0,114,68,0,0,0,114,10,0,0,0,114,20, + 1,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,240,0,0,0,6,5,0,0,115,2,0,0,0, + 0,1,122,28,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,101,120,101,99,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,4,0,0,0,67,0,0,0,115,26,0,0,0,116,0, + 160,1,100,1,124,0,106,2,161,2,1,0,116,0,160,3, + 124,0,124,1,161,2,83,0,41,2,122,98,76,111,97,100, + 32,97,32,110,97,109,101,115,112,97,99,101,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,46,32,32,85,115,101,32,101,120, + 101,99,95,109,111,100,117,108,101,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,122,38, + 110,97,109,101,115,112,97,99,101,32,109,111,100,117,108,101, + 32,108,111,97,100,101,100,32,119,105,116,104,32,112,97,116, + 104,32,123,33,114,125,41,4,114,158,0,0,0,114,173,0, + 0,0,114,47,1,0,0,114,241,0,0,0,114,242,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,243,0,0,0,9,5,0,0,115,8,0,0,0,0,7, + 6,1,4,255,4,2,122,28,95,78,97,109,101,115,112,97, + 99,101,76,111,97,100,101,114,46,108,111,97,100,95,109,111, + 100,117,108,101,78,41,12,114,149,0,0,0,114,148,0,0, + 0,114,150,0,0,0,114,232,0,0,0,114,230,0,0,0, + 114,67,1,0,0,114,206,0,0,0,114,252,0,0,0,114, + 236,0,0,0,114,235,0,0,0,114,240,0,0,0,114,243, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,66,1,0,0,237,4,0,0, + 115,18,0,0,0,8,1,8,3,2,1,10,8,8,3,8, + 3,8,3,8,3,8,3,114,66,1,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, + 0,64,0,0,0,115,118,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,101,4,100,2,100,3,132,0,131,1, + 90,5,101,4,100,4,100,5,132,0,131,1,90,6,101,4, + 100,6,100,7,132,0,131,1,90,7,101,4,100,8,100,9, + 132,0,131,1,90,8,101,4,100,19,100,11,100,12,132,1, + 131,1,90,9,101,4,100,20,100,13,100,14,132,1,131,1, + 90,10,101,4,100,21,100,15,100,16,132,1,131,1,90,11, + 101,4,100,17,100,18,132,0,131,1,90,12,100,10,83,0, + 41,22,218,10,80,97,116,104,70,105,110,100,101,114,122,62, + 77,101,116,97,32,112,97,116,104,32,102,105,110,100,101,114, + 32,102,111,114,32,115,121,115,46,112,97,116,104,32,97,110, + 100,32,112,97,99,107,97,103,101,32,95,95,112,97,116,104, + 95,95,32,97,116,116,114,105,98,117,116,101,115,46,99,1, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, + 0,0,0,67,0,0,0,115,64,0,0,0,116,0,116,1, + 106,2,160,3,161,0,131,1,68,0,93,44,92,2,125,1, + 125,2,124,2,100,1,107,8,114,40,116,1,106,2,124,1, + 61,0,113,14,116,4,124,2,100,2,131,2,114,14,124,2, + 160,5,161,0,1,0,113,14,100,1,83,0,41,3,122,125, + 67,97,108,108,32,116,104,101,32,105,110,118,97,108,105,100, + 97,116,101,95,99,97,99,104,101,115,40,41,32,109,101,116, + 104,111,100,32,111,110,32,97,108,108,32,112,97,116,104,32, + 101,110,116,114,121,32,102,105,110,100,101,114,115,10,32,32, + 32,32,32,32,32,32,115,116,111,114,101,100,32,105,110,32, + 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, + 114,95,99,97,99,104,101,115,32,40,119,104,101,114,101,32, + 105,109,112,108,101,109,101,110,116,101,100,41,46,78,218,17, + 105,110,118,97,108,105,100,97,116,101,95,99,97,99,104,101, + 115,41,6,218,4,108,105,115,116,114,25,0,0,0,218,19, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,218,5,105,116,101,109,115,114,152,0,0,0,114, + 69,1,0,0,41,3,114,216,0,0,0,114,140,0,0,0, + 218,6,102,105,110,100,101,114,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,69,1,0,0,27,5,0,0, + 115,10,0,0,0,0,4,22,1,8,1,10,1,10,1,122, + 28,80,97,116,104,70,105,110,100,101,114,46,105,110,118,97, + 108,105,100,97,116,101,95,99,97,99,104,101,115,99,2,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,9,0, + 0,0,67,0,0,0,115,84,0,0,0,116,0,106,1,100, + 1,107,9,114,28,116,0,106,1,115,28,116,2,160,3,100, + 2,116,4,161,2,1,0,116,0,106,1,68,0,93,44,125, + 2,122,14,124,2,124,1,131,1,87,0,2,0,1,0,83, + 0,4,0,116,5,107,10,114,76,1,0,1,0,1,0,89, + 0,113,34,89,0,113,34,88,0,113,34,100,1,83,0,41, + 3,122,46,83,101,97,114,99,104,32,115,121,115,46,112,97, + 116,104,95,104,111,111,107,115,32,102,111,114,32,97,32,102, + 105,110,100,101,114,32,102,111,114,32,39,112,97,116,104,39, + 46,78,122,23,115,121,115,46,112,97,116,104,95,104,111,111, + 107,115,32,105,115,32,101,109,112,116,121,41,6,114,25,0, + 0,0,218,10,112,97,116,104,95,104,111,111,107,115,114,97, + 0,0,0,114,98,0,0,0,114,162,0,0,0,114,141,0, + 0,0,41,3,114,216,0,0,0,114,64,0,0,0,90,4, + 104,111,111,107,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,11,95,112,97,116,104,95,104,111,111,107,115, + 37,5,0,0,115,16,0,0,0,0,3,16,1,12,1,10, + 1,2,1,14,1,14,1,12,2,122,22,80,97,116,104,70, + 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, + 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,8,0,0,0,67,0,0,0,115,104,0,0,0,124, + 1,100,1,107,2,114,44,122,12,116,0,160,1,161,0,125, + 1,87,0,110,22,4,0,116,2,107,10,114,42,1,0,1, + 0,1,0,89,0,100,2,83,0,88,0,122,14,116,3,106, + 4,124,1,25,0,125,2,87,0,110,40,4,0,116,5,107, + 10,114,98,1,0,1,0,1,0,124,0,160,6,124,1,161, + 1,125,2,124,2,116,3,106,4,124,1,60,0,89,0,110, + 2,88,0,124,2,83,0,41,3,122,210,71,101,116,32,116, + 104,101,32,102,105,110,100,101,114,32,102,111,114,32,116,104, + 101,32,112,97,116,104,32,101,110,116,114,121,32,102,114,111, + 109,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,46,10,10,32,32,32,32, + 32,32,32,32,73,102,32,116,104,101,32,112,97,116,104,32, + 101,110,116,114,121,32,105,115,32,110,111,116,32,105,110,32, + 116,104,101,32,99,97,99,104,101,44,32,102,105,110,100,32, + 116,104,101,32,97,112,112,114,111,112,114,105,97,116,101,32, + 102,105,110,100,101,114,10,32,32,32,32,32,32,32,32,97, + 110,100,32,99,97,99,104,101,32,105,116,46,32,73,102,32, + 110,111,32,102,105,110,100,101,114,32,105,115,32,97,118,97, + 105,108,97,98,108,101,44,32,115,116,111,114,101,32,78,111, + 110,101,46,10,10,32,32,32,32,32,32,32,32,114,13,0, + 0,0,78,41,7,114,21,0,0,0,114,80,0,0,0,114, + 26,1,0,0,114,25,0,0,0,114,71,1,0,0,218,8, + 75,101,121,69,114,114,111,114,114,75,1,0,0,41,3,114, + 216,0,0,0,114,64,0,0,0,114,73,1,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,20,95, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,50,5,0,0,115,22,0,0,0,0,8,8,1, + 2,1,12,1,14,3,8,1,2,1,14,1,14,1,10,1, + 16,1,122,31,80,97,116,104,70,105,110,100,101,114,46,95, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,99,3,0,0,0,0,0,0,0,0,0,0,0, + 6,0,0,0,4,0,0,0,67,0,0,0,115,82,0,0, + 0,116,0,124,2,100,1,131,2,114,26,124,2,160,1,124, + 1,161,1,92,2,125,3,125,4,110,14,124,2,160,2,124, + 1,161,1,125,3,103,0,125,4,124,3,100,0,107,9,114, + 60,116,3,160,4,124,1,124,3,161,2,83,0,116,3,160, + 5,124,1,100,0,161,2,125,5,124,4,124,5,95,6,124, + 5,83,0,41,2,78,114,161,0,0,0,41,7,114,152,0, + 0,0,114,161,0,0,0,114,229,0,0,0,114,158,0,0, + 0,114,224,0,0,0,114,207,0,0,0,114,202,0,0,0, + 41,6,114,216,0,0,0,114,163,0,0,0,114,73,1,0, + 0,114,164,0,0,0,114,165,0,0,0,114,210,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 16,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, + 99,72,5,0,0,115,18,0,0,0,0,4,10,1,16,2, + 10,1,4,1,8,1,12,1,12,1,6,1,122,27,80,97, + 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, + 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, + 0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,67, + 0,0,0,115,166,0,0,0,103,0,125,4,124,2,68,0, + 93,134,125,5,116,0,124,5,116,1,116,2,102,2,131,2, + 115,28,113,8,124,0,160,3,124,5,161,1,125,6,124,6, + 100,1,107,9,114,8,116,4,124,6,100,2,131,2,114,70, + 124,6,160,5,124,1,124,3,161,2,125,7,110,12,124,0, + 160,6,124,1,124,6,161,2,125,7,124,7,100,1,107,8, + 114,92,113,8,124,7,106,7,100,1,107,9,114,110,124,7, + 2,0,1,0,83,0,124,7,106,8,125,8,124,8,100,1, + 107,8,114,132,116,9,100,3,131,1,130,1,124,4,160,10, + 124,8,161,1,1,0,113,8,116,11,160,12,124,1,100,1, + 161,2,125,7,124,4,124,7,95,8,124,7,83,0,41,4, + 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, + 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, + 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, + 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, + 46,78,114,226,0,0,0,122,19,115,112,101,99,32,109,105, + 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,185, + 0,0,0,114,108,0,0,0,218,5,98,121,116,101,115,114, + 77,1,0,0,114,152,0,0,0,114,226,0,0,0,114,78, + 1,0,0,114,164,0,0,0,114,202,0,0,0,114,141,0, + 0,0,114,191,0,0,0,114,158,0,0,0,114,207,0,0, + 0,41,9,114,216,0,0,0,114,163,0,0,0,114,64,0, + 0,0,114,225,0,0,0,218,14,110,97,109,101,115,112,97, + 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,73, + 1,0,0,114,210,0,0,0,114,165,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,9,95,103, + 101,116,95,115,112,101,99,87,5,0,0,115,40,0,0,0, + 0,5,4,1,8,1,14,1,2,1,10,1,8,1,10,1, + 14,2,12,1,8,1,2,1,10,1,8,1,6,1,8,1, + 8,5,12,2,12,1,6,1,122,20,80,97,116,104,70,105, + 110,100,101,114,46,95,103,101,116,95,115,112,101,99,99,4, + 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5, + 0,0,0,67,0,0,0,115,100,0,0,0,124,2,100,1, + 107,8,114,14,116,0,106,1,125,2,124,0,160,2,124,1, + 124,2,124,3,161,3,125,4,124,4,100,1,107,8,114,40, + 100,1,83,0,124,4,106,3,100,1,107,8,114,92,124,4, + 106,4,125,5,124,5,114,86,100,1,124,4,95,5,116,6, + 124,1,124,5,124,0,106,2,131,3,124,4,95,4,124,4, + 83,0,100,1,83,0,110,4,124,4,83,0,100,1,83,0, + 41,2,122,141,84,114,121,32,116,111,32,102,105,110,100,32, + 97,32,115,112,101,99,32,102,111,114,32,39,102,117,108,108, + 110,97,109,101,39,32,111,110,32,115,121,115,46,112,97,116, + 104,32,111,114,32,39,112,97,116,104,39,46,10,10,32,32, + 32,32,32,32,32,32,84,104,101,32,115,101,97,114,99,104, + 32,105,115,32,98,97,115,101,100,32,111,110,32,115,121,115, + 46,112,97,116,104,95,104,111,111,107,115,32,97,110,100,32, + 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, + 114,95,99,97,99,104,101,46,10,32,32,32,32,32,32,32, + 32,78,41,7,114,25,0,0,0,114,64,0,0,0,114,81, + 1,0,0,114,164,0,0,0,114,202,0,0,0,114,205,0, + 0,0,114,45,1,0,0,41,6,114,216,0,0,0,114,163, + 0,0,0,114,64,0,0,0,114,225,0,0,0,114,210,0, + 0,0,114,80,1,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,226,0,0,0,119,5,0,0,115, + 26,0,0,0,0,6,8,1,6,1,14,1,8,1,4,1, + 10,1,6,1,4,3,6,1,16,1,4,2,6,2,122,20, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 115,112,101,99,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,4,0,0,0,67,0,0,0,115,30,0, + 0,0,124,0,160,0,124,1,124,2,161,2,125,3,124,3, + 100,1,107,8,114,24,100,1,83,0,124,3,106,1,83,0, + 41,2,122,170,102,105,110,100,32,116,104,101,32,109,111,100, + 117,108,101,32,111,110,32,115,121,115,46,112,97,116,104,32, + 111,114,32,39,112,97,116,104,39,32,98,97,115,101,100,32, + 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, + 115,32,97,110,100,10,32,32,32,32,32,32,32,32,115,121, + 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,114, + 227,0,0,0,114,228,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,229,0,0,0,143,5,0, + 0,115,8,0,0,0,0,8,12,1,8,1,4,1,122,22, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 109,111,100,117,108,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,3,0,0,0,79,0,0,0,115, + 24,0,0,0,100,1,100,2,108,0,109,1,125,3,1,0, + 124,3,106,2,124,1,124,2,142,1,83,0,41,3,97,32, + 1,0,0,10,32,32,32,32,32,32,32,32,70,105,110,100, + 32,100,105,115,116,114,105,98,117,116,105,111,110,115,46,10, + 10,32,32,32,32,32,32,32,32,82,101,116,117,114,110,32, + 97,110,32,105,116,101,114,97,98,108,101,32,111,102,32,97, + 108,108,32,68,105,115,116,114,105,98,117,116,105,111,110,32, + 105,110,115,116,97,110,99,101,115,32,99,97,112,97,98,108, + 101,32,111,102,10,32,32,32,32,32,32,32,32,108,111,97, + 100,105,110,103,32,116,104,101,32,109,101,116,97,100,97,116, + 97,32,102,111,114,32,112,97,99,107,97,103,101,115,32,109, + 97,116,99,104,105,110,103,32,96,96,99,111,110,116,101,120, + 116,46,110,97,109,101,96,96,10,32,32,32,32,32,32,32, + 32,40,111,114,32,97,108,108,32,110,97,109,101,115,32,105, + 102,32,96,96,78,111,110,101,96,96,32,105,110,100,105,99, + 97,116,101,100,41,32,97,108,111,110,103,32,116,104,101,32, + 112,97,116,104,115,32,105,110,32,116,104,101,32,108,105,115, + 116,10,32,32,32,32,32,32,32,32,111,102,32,100,105,114, + 101,99,116,111,114,105,101,115,32,96,96,99,111,110,116,101, + 120,116,46,112,97,116,104,96,96,46,10,32,32,32,32,32, + 32,32,32,114,0,0,0,0,41,1,218,18,77,101,116,97, + 100,97,116,97,80,97,116,104,70,105,110,100,101,114,41,3, + 90,18,105,109,112,111,114,116,108,105,98,46,109,101,116,97, + 100,97,116,97,114,82,1,0,0,218,18,102,105,110,100,95, + 100,105,115,116,114,105,98,117,116,105,111,110,115,41,4,114, + 216,0,0,0,114,143,0,0,0,114,144,0,0,0,114,82, + 1,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,83,1,0,0,156,5,0,0,115,4,0,0,0, + 0,10,12,1,122,29,80,97,116,104,70,105,110,100,101,114, + 46,102,105,110,100,95,100,105,115,116,114,105,98,117,116,105, + 111,110,115,41,1,78,41,2,78,78,41,1,78,41,13,114, + 149,0,0,0,114,148,0,0,0,114,150,0,0,0,114,151, + 0,0,0,114,230,0,0,0,114,69,1,0,0,114,75,1, + 0,0,114,77,1,0,0,114,78,1,0,0,114,81,1,0, + 0,114,226,0,0,0,114,229,0,0,0,114,83,1,0,0, + 114,10,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,68,1,0,0,23,5,0,0,115,34,0, + 0,0,8,2,4,2,2,1,10,9,2,1,10,12,2,1, + 10,21,2,1,10,14,2,1,12,31,2,1,12,23,2,1, + 12,12,2,1,114,68,1,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0, + 0,0,115,90,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, + 0,90,5,101,6,90,7,100,6,100,7,132,0,90,8,100, + 8,100,9,132,0,90,9,100,19,100,11,100,12,132,1,90, + 10,100,13,100,14,132,0,90,11,101,12,100,15,100,16,132, + 0,131,1,90,13,100,17,100,18,132,0,90,14,100,10,83, + 0,41,20,218,10,70,105,108,101,70,105,110,100,101,114,122, + 172,70,105,108,101,45,98,97,115,101,100,32,102,105,110,100, + 101,114,46,10,10,32,32,32,32,73,110,116,101,114,97,99, + 116,105,111,110,115,32,119,105,116,104,32,116,104,101,32,102, + 105,108,101,32,115,121,115,116,101,109,32,97,114,101,32,99, + 97,99,104,101,100,32,102,111,114,32,112,101,114,102,111,114, + 109,97,110,99,101,44,32,98,101,105,110,103,10,32,32,32, + 32,114,101,102,114,101,115,104,101,100,32,119,104,101,110,32, + 116,104,101,32,100,105,114,101,99,116,111,114,121,32,116,104, + 101,32,102,105,110,100,101,114,32,105,115,32,104,97,110,100, + 108,105,110,103,32,104,97,115,32,98,101,101,110,32,109,111, + 100,105,102,105,101,100,46,10,10,32,32,32,32,99,2,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0, + 0,0,7,0,0,0,115,112,0,0,0,103,0,125,3,124, + 2,68,0,93,32,92,2,137,0,125,4,124,3,160,0,135, + 0,102,1,100,1,100,2,132,8,124,4,68,0,131,1,161, + 1,1,0,113,8,124,3,124,0,95,1,124,1,112,54,100, + 3,124,0,95,2,116,3,124,0,106,2,131,1,115,86,116, + 4,116,5,160,6,161,0,124,0,106,2,131,2,124,0,95, + 2,100,4,124,0,95,7,116,8,131,0,124,0,95,9,116, + 8,131,0,124,0,95,10,100,5,83,0,41,6,122,154,73, + 110,105,116,105,97,108,105,122,101,32,119,105,116,104,32,116, + 104,101,32,112,97,116,104,32,116,111,32,115,101,97,114,99, + 104,32,111,110,32,97,110,100,32,97,32,118,97,114,105,97, + 98,108,101,32,110,117,109,98,101,114,32,111,102,10,32,32, + 32,32,32,32,32,32,50,45,116,117,112,108,101,115,32,99, + 111,110,116,97,105,110,105,110,103,32,116,104,101,32,108,111, + 97,100,101,114,32,97,110,100,32,116,104,101,32,102,105,108, + 101,32,115,117,102,102,105,120,101,115,32,116,104,101,32,108, + 111,97,100,101,114,10,32,32,32,32,32,32,32,32,114,101, + 99,111,103,110,105,122,101,115,46,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,3,0,0,0,51,0, + 0,0,115,22,0,0,0,124,0,93,14,125,1,124,1,136, + 0,102,2,86,0,1,0,113,2,100,0,83,0,114,68,0, + 0,0,114,10,0,0,0,114,40,1,0,0,169,1,114,164, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,12,0, + 0,0,185,5,0,0,115,4,0,0,0,4,0,2,0,122, + 38,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110, + 105,116,95,95,46,60,108,111,99,97,108,115,62,46,60,103, + 101,110,101,120,112,114,62,114,95,0,0,0,114,129,0,0, + 0,78,41,11,114,191,0,0,0,218,8,95,108,111,97,100, + 101,114,115,114,64,0,0,0,114,84,0,0,0,114,66,0, + 0,0,114,21,0,0,0,114,80,0,0,0,218,11,95,112, + 97,116,104,95,109,116,105,109,101,218,3,115,101,116,218,11, + 95,112,97,116,104,95,99,97,99,104,101,218,19,95,114,101, + 108,97,120,101,100,95,112,97,116,104,95,99,97,99,104,101, + 41,5,114,142,0,0,0,114,64,0,0,0,218,14,108,111, + 97,100,101,114,95,100,101,116,97,105,108,115,90,7,108,111, + 97,100,101,114,115,114,212,0,0,0,114,10,0,0,0,114, + 85,1,0,0,114,11,0,0,0,114,232,0,0,0,179,5, + 0,0,115,20,0,0,0,0,4,4,1,12,1,26,1,6, + 2,10,1,10,1,18,1,6,1,8,1,122,19,70,105,108, + 101,70,105,110,100,101,114,46,95,95,105,110,105,116,95,95, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,2,0,0,0,67,0,0,0,115,10,0,0,0,100,1, + 124,0,95,0,100,2,83,0,41,3,122,31,73,110,118,97, + 108,105,100,97,116,101,32,116,104,101,32,100,105,114,101,99, + 116,111,114,121,32,109,116,105,109,101,46,114,129,0,0,0, + 78,41,1,114,87,1,0,0,114,13,1,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,69,1,0, + 0,195,5,0,0,115,2,0,0,0,0,2,122,28,70,105, + 108,101,70,105,110,100,101,114,46,105,110,118,97,108,105,100, + 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, + 0,0,0,115,42,0,0,0,124,0,160,0,124,1,161,1, + 125,2,124,2,100,1,107,8,114,26,100,1,103,0,102,2, + 83,0,124,2,106,1,124,2,106,2,112,38,103,0,102,2, + 83,0,41,2,122,197,84,114,121,32,116,111,32,102,105,110, + 100,32,97,32,108,111,97,100,101,114,32,102,111,114,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,44,32,111,114,32,116,104,101,32,110,97,109,101, + 115,112,97,99,101,10,32,32,32,32,32,32,32,32,112,97, + 99,107,97,103,101,32,112,111,114,116,105,111,110,115,46,32, + 82,101,116,117,114,110,115,32,40,108,111,97,100,101,114,44, + 32,108,105,115,116,45,111,102,45,112,111,114,116,105,111,110, + 115,41,46,10,10,32,32,32,32,32,32,32,32,84,104,105, + 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,46,32,32,85,115,101,32,102,105,110, + 100,95,115,112,101,99,40,41,32,105,110,115,116,101,97,100, + 46,10,10,32,32,32,32,32,32,32,32,78,41,3,114,226, + 0,0,0,114,164,0,0,0,114,202,0,0,0,41,3,114, + 142,0,0,0,114,163,0,0,0,114,210,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,161,0, + 0,0,201,5,0,0,115,8,0,0,0,0,7,10,1,8, + 1,8,1,122,22,70,105,108,101,70,105,110,100,101,114,46, + 102,105,110,100,95,108,111,97,100,101,114,99,6,0,0,0, + 0,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0, + 67,0,0,0,115,26,0,0,0,124,1,124,2,124,3,131, + 2,125,6,116,0,124,2,124,3,124,6,124,4,100,1,141, + 4,83,0,41,2,78,114,201,0,0,0,41,1,114,213,0, + 0,0,41,7,114,142,0,0,0,114,211,0,0,0,114,163, + 0,0,0,114,64,0,0,0,90,4,115,109,115,108,114,225, + 0,0,0,114,164,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,81,1,0,0,213,5,0,0, + 115,8,0,0,0,0,1,10,1,8,1,2,255,122,20,70, + 105,108,101,70,105,110,100,101,114,46,95,103,101,116,95,115, + 112,101,99,78,99,3,0,0,0,0,0,0,0,0,0,0, + 0,14,0,0,0,9,0,0,0,67,0,0,0,115,130,1, + 0,0,100,1,125,3,124,1,160,0,100,2,161,1,100,3, + 25,0,125,4,122,24,116,1,124,0,106,2,112,34,116,3, + 160,4,161,0,131,1,106,5,125,5,87,0,110,24,4,0, + 116,6,107,10,114,66,1,0,1,0,1,0,100,4,125,5, + 89,0,110,2,88,0,124,5,124,0,106,7,107,3,114,92, + 124,0,160,8,161,0,1,0,124,5,124,0,95,7,116,9, + 131,0,114,114,124,0,106,10,125,6,124,4,160,11,161,0, + 125,7,110,10,124,0,106,12,125,6,124,4,125,7,124,7, + 124,6,107,6,114,218,116,13,124,0,106,2,124,4,131,2, + 125,8,124,0,106,14,68,0,93,58,92,2,125,9,125,10, + 100,5,124,9,23,0,125,11,116,13,124,8,124,11,131,2, + 125,12,116,15,124,12,131,1,114,150,124,0,160,16,124,10, + 124,1,124,12,124,8,103,1,124,2,161,5,2,0,1,0, + 83,0,113,150,116,17,124,8,131,1,125,3,124,0,106,14, + 68,0,93,114,92,2,125,9,125,10,122,20,116,13,124,0, + 106,2,124,4,124,9,23,0,131,2,125,12,87,0,110,26, + 4,0,116,18,107,10,144,1,114,22,1,0,1,0,1,0, + 89,0,1,0,100,6,83,0,88,0,116,19,106,20,100,7, + 124,12,100,3,100,8,141,3,1,0,124,7,124,9,23,0, + 124,6,107,6,114,224,116,15,124,12,131,1,114,224,124,0, + 160,16,124,10,124,1,124,12,100,6,124,2,161,5,2,0, + 1,0,83,0,113,224,124,3,144,1,114,126,116,19,160,20, + 100,9,124,8,161,2,1,0,116,19,160,21,124,1,100,6, + 161,2,125,13,124,8,103,1,124,13,95,22,124,13,83,0, + 100,6,83,0,41,10,122,111,84,114,121,32,116,111,32,102, + 105,110,100,32,97,32,115,112,101,99,32,102,111,114,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,32,32,32,32,82,101, + 116,117,114,110,115,32,116,104,101,32,109,97,116,99,104,105, + 110,103,32,115,112,101,99,44,32,111,114,32,78,111,110,101, + 32,105,102,32,110,111,116,32,102,111,117,110,100,46,10,32, + 32,32,32,32,32,32,32,70,114,95,0,0,0,114,44,0, + 0,0,114,129,0,0,0,114,232,0,0,0,78,122,9,116, + 114,121,105,110,103,32,123,125,41,1,90,9,118,101,114,98, + 111,115,105,116,121,122,25,112,111,115,115,105,98,108,101,32, + 110,97,109,101,115,112,97,99,101,32,102,111,114,32,123,125, + 41,23,114,102,0,0,0,114,74,0,0,0,114,64,0,0, + 0,114,21,0,0,0,114,80,0,0,0,114,33,1,0,0, + 114,75,0,0,0,114,87,1,0,0,218,11,95,102,105,108, + 108,95,99,97,99,104,101,114,24,0,0,0,114,90,1,0, + 0,114,130,0,0,0,114,89,1,0,0,114,66,0,0,0, + 114,86,1,0,0,114,79,0,0,0,114,81,1,0,0,114, + 81,0,0,0,114,110,0,0,0,114,158,0,0,0,114,173, + 0,0,0,114,207,0,0,0,114,202,0,0,0,41,14,114, + 142,0,0,0,114,163,0,0,0,114,225,0,0,0,90,12, + 105,115,95,110,97,109,101,115,112,97,99,101,90,11,116,97, + 105,108,95,109,111,100,117,108,101,114,193,0,0,0,90,5, + 99,97,99,104,101,90,12,99,97,99,104,101,95,109,111,100, + 117,108,101,90,9,98,97,115,101,95,112,97,116,104,114,41, + 1,0,0,114,211,0,0,0,90,13,105,110,105,116,95,102, + 105,108,101,110,97,109,101,90,9,102,117,108,108,95,112,97, + 116,104,114,210,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,226,0,0,0,218,5,0,0,115, + 80,0,0,0,0,5,4,1,14,1,2,1,24,1,14,1, + 10,1,10,1,8,1,6,2,6,1,6,1,10,2,6,1, + 4,2,8,1,12,1,14,1,8,1,10,1,8,1,26,4, + 8,2,14,1,2,1,20,1,16,1,10,1,16,1,12,1, + 8,1,10,1,2,0,2,255,10,2,6,1,12,1,12,1, + 8,1,4,1,122,20,70,105,108,101,70,105,110,100,101,114, + 46,102,105,110,100,95,115,112,101,99,99,1,0,0,0,0, + 0,0,0,0,0,0,0,9,0,0,0,10,0,0,0,67, + 0,0,0,115,190,0,0,0,124,0,106,0,125,1,122,22, + 116,1,160,2,124,1,112,22,116,1,160,3,161,0,161,1, + 125,2,87,0,110,30,4,0,116,4,116,5,116,6,102,3, + 107,10,114,58,1,0,1,0,1,0,103,0,125,2,89,0, + 110,2,88,0,116,7,106,8,160,9,100,1,161,1,115,84, + 116,10,124,2,131,1,124,0,95,11,110,74,116,10,131,0, + 125,3,124,2,68,0,93,56,125,4,124,4,160,12,100,2, + 161,1,92,3,125,5,125,6,125,7,124,6,114,136,100,3, + 160,13,124,5,124,7,160,14,161,0,161,2,125,8,110,4, + 124,5,125,8,124,3,160,15,124,8,161,1,1,0,113,94, + 124,3,124,0,95,11,116,7,106,8,160,9,116,16,161,1, + 114,186,100,4,100,5,132,0,124,2,68,0,131,1,124,0, + 95,17,100,6,83,0,41,7,122,68,70,105,108,108,32,116, + 104,101,32,99,97,99,104,101,32,111,102,32,112,111,116,101, + 110,116,105,97,108,32,109,111,100,117,108,101,115,32,97,110, + 100,32,112,97,99,107,97,103,101,115,32,102,111,114,32,116, + 104,105,115,32,100,105,114,101,99,116,111,114,121,46,114,19, + 0,0,0,114,95,0,0,0,114,86,0,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,83,0,0,0,115,20,0,0,0,104,0,124,0,93, + 12,125,1,124,1,160,0,161,0,146,2,113,4,83,0,114, + 10,0,0,0,41,1,114,130,0,0,0,41,2,114,8,0, + 0,0,90,2,102,110,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,18,0,0,0,42,6,0,0,115,4, + 0,0,0,6,0,2,0,122,41,70,105,108,101,70,105,110, + 100,101,114,46,95,102,105,108,108,95,99,97,99,104,101,46, + 60,108,111,99,97,108,115,62,46,60,115,101,116,99,111,109, + 112,62,78,41,18,114,64,0,0,0,114,21,0,0,0,114, + 30,1,0,0,114,80,0,0,0,114,26,1,0,0,218,15, + 80,101,114,109,105,115,115,105,111,110,69,114,114,111,114,218, + 18,78,111,116,65,68,105,114,101,99,116,111,114,121,69,114, + 114,111,114,114,25,0,0,0,114,26,0,0,0,114,27,0, + 0,0,114,88,1,0,0,114,89,1,0,0,114,125,0,0, + 0,114,87,0,0,0,114,130,0,0,0,218,3,97,100,100, + 114,28,0,0,0,114,90,1,0,0,41,9,114,142,0,0, + 0,114,64,0,0,0,114,31,1,0,0,90,21,108,111,119, + 101,114,95,115,117,102,102,105,120,95,99,111,110,116,101,110, + 116,115,114,64,1,0,0,114,140,0,0,0,114,52,1,0, + 0,114,41,1,0,0,90,8,110,101,119,95,110,97,109,101, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 92,1,0,0,13,6,0,0,115,34,0,0,0,0,2,6, + 1,2,1,22,1,20,3,10,3,12,1,12,7,6,1,8, + 1,16,1,4,1,18,2,4,1,12,1,6,1,12,1,122, + 22,70,105,108,101,70,105,110,100,101,114,46,95,102,105,108, + 108,95,99,97,99,104,101,99,1,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,3,0,0,0,7,0,0,0, + 115,18,0,0,0,135,0,135,1,102,2,100,1,100,2,132, + 8,125,2,124,2,83,0,41,3,97,20,1,0,0,65,32, + 99,108,97,115,115,32,109,101,116,104,111,100,32,119,104,105, + 99,104,32,114,101,116,117,114,110,115,32,97,32,99,108,111, + 115,117,114,101,32,116,111,32,117,115,101,32,111,110,32,115, + 121,115,46,112,97,116,104,95,104,111,111,107,10,32,32,32, + 32,32,32,32,32,119,104,105,99,104,32,119,105,108,108,32, + 114,101,116,117,114,110,32,97,110,32,105,110,115,116,97,110, + 99,101,32,117,115,105,110,103,32,116,104,101,32,115,112,101, + 99,105,102,105,101,100,32,108,111,97,100,101,114,115,32,97, + 110,100,32,116,104,101,32,112,97,116,104,10,32,32,32,32, + 32,32,32,32,99,97,108,108,101,100,32,111,110,32,116,104, + 101,32,99,108,111,115,117,114,101,46,10,10,32,32,32,32, + 32,32,32,32,73,102,32,116,104,101,32,112,97,116,104,32, + 99,97,108,108,101,100,32,111,110,32,116,104,101,32,99,108, + 111,115,117,114,101,32,105,115,32,110,111,116,32,97,32,100, + 105,114,101,99,116,111,114,121,44,32,73,109,112,111,114,116, + 69,114,114,111,114,32,105,115,10,32,32,32,32,32,32,32, + 32,114,97,105,115,101,100,46,10,10,32,32,32,32,32,32, + 32,32,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,4,0,0,0,19,0,0,0,115,34,0,0,0, + 116,0,124,0,131,1,115,20,116,1,100,1,124,0,100,2, + 141,2,130,1,136,0,124,0,102,1,136,1,158,2,142,0, + 83,0,41,3,122,45,80,97,116,104,32,104,111,111,107,32, + 102,111,114,32,105,109,112,111,114,116,108,105,98,46,109,97, + 99,104,105,110,101,114,121,46,70,105,108,101,70,105,110,100, + 101,114,46,122,30,111,110,108,121,32,100,105,114,101,99,116, + 111,114,105,101,115,32,97,114,101,32,115,117,112,112,111,114, + 116,101,100,114,70,0,0,0,41,2,114,81,0,0,0,114, + 141,0,0,0,114,70,0,0,0,169,2,114,216,0,0,0, + 114,91,1,0,0,114,10,0,0,0,114,11,0,0,0,218, + 24,112,97,116,104,95,104,111,111,107,95,102,111,114,95,70, + 105,108,101,70,105,110,100,101,114,54,6,0,0,115,6,0, + 0,0,0,2,8,1,12,1,122,54,70,105,108,101,70,105, + 110,100,101,114,46,112,97,116,104,95,104,111,111,107,46,60, + 108,111,99,97,108,115,62,46,112,97,116,104,95,104,111,111, + 107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,114, + 114,10,0,0,0,41,3,114,216,0,0,0,114,91,1,0, + 0,114,97,1,0,0,114,10,0,0,0,114,96,1,0,0, + 114,11,0,0,0,218,9,112,97,116,104,95,104,111,111,107, + 44,6,0,0,115,4,0,0,0,0,10,14,6,122,20,70, + 105,108,101,70,105,110,100,101,114,46,112,97,116,104,95,104, + 111,111,107,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,67,0,0,0,115,12,0,0, + 0,100,1,160,0,124,0,106,1,161,1,83,0,41,2,78, + 122,16,70,105,108,101,70,105,110,100,101,114,40,123,33,114, + 125,41,41,2,114,87,0,0,0,114,64,0,0,0,114,13, + 1,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,62,1,0,0,62,6,0,0,115,2,0,0,0, + 0,1,122,19,70,105,108,101,70,105,110,100,101,114,46,95, + 95,114,101,112,114,95,95,41,1,78,41,15,114,149,0,0, + 0,114,148,0,0,0,114,150,0,0,0,114,151,0,0,0, + 114,232,0,0,0,114,69,1,0,0,114,167,0,0,0,114, + 229,0,0,0,114,161,0,0,0,114,81,1,0,0,114,226, + 0,0,0,114,92,1,0,0,114,230,0,0,0,114,98,1, + 0,0,114,62,1,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,84,1,0,0, + 170,5,0,0,115,22,0,0,0,8,2,4,7,8,16,8, + 4,4,2,8,12,8,5,10,51,8,31,2,1,10,17,114, + 84,1,0,0,99,4,0,0,0,0,0,0,0,0,0,0, + 0,6,0,0,0,8,0,0,0,67,0,0,0,115,146,0, + 0,0,124,0,160,0,100,1,161,1,125,4,124,0,160,0, + 100,2,161,1,125,5,124,4,115,66,124,5,114,36,124,5, + 106,1,125,4,110,30,124,2,124,3,107,2,114,56,116,2, + 124,1,124,2,131,2,125,4,110,10,116,3,124,1,124,2, + 131,2,125,4,124,5,115,84,116,4,124,1,124,2,124,4, + 100,3,141,3,125,5,122,36,124,5,124,0,100,2,60,0, + 124,4,124,0,100,1,60,0,124,2,124,0,100,4,60,0, + 124,3,124,0,100,5,60,0,87,0,110,20,4,0,116,5, + 107,10,114,140,1,0,1,0,1,0,89,0,110,2,88,0, + 100,0,83,0,41,6,78,218,10,95,95,108,111,97,100,101, + 114,95,95,218,8,95,95,115,112,101,99,95,95,114,85,1, + 0,0,90,8,95,95,102,105,108,101,95,95,90,10,95,95, + 99,97,99,104,101,100,95,95,41,6,218,3,103,101,116,114, + 164,0,0,0,114,39,1,0,0,114,32,1,0,0,114,213, + 0,0,0,218,9,69,120,99,101,112,116,105,111,110,41,6, + 90,2,110,115,114,140,0,0,0,90,8,112,97,116,104,110, + 97,109,101,90,9,99,112,97,116,104,110,97,109,101,114,164, + 0,0,0,114,210,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,14,95,102,105,120,95,117,112, + 95,109,111,100,117,108,101,68,6,0,0,115,34,0,0,0, + 0,2,10,1,10,1,4,1,4,1,8,1,8,1,12,2, + 10,1,4,1,14,1,2,1,8,1,8,1,8,1,12,1, + 14,2,114,103,1,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, + 115,38,0,0,0,116,0,116,1,160,2,161,0,102,2,125, + 0,116,3,116,4,102,2,125,1,116,5,116,6,102,2,125, + 2,124,0,124,1,124,2,103,3,83,0,41,1,122,95,82, + 101,116,117,114,110,115,32,97,32,108,105,115,116,32,111,102, + 32,102,105,108,101,45,98,97,115,101,100,32,109,111,100,117, + 108,101,32,108,111,97,100,101,114,115,46,10,10,32,32,32, + 32,69,97,99,104,32,105,116,101,109,32,105,115,32,97,32, + 116,117,112,108,101,32,40,108,111,97,100,101,114,44,32,115, + 117,102,102,105,120,101,115,41,46,10,32,32,32,32,41,7, + 114,19,1,0,0,114,187,0,0,0,218,18,101,120,116,101, + 110,115,105,111,110,95,115,117,102,102,105,120,101,115,114,32, + 1,0,0,114,126,0,0,0,114,39,1,0,0,114,112,0, + 0,0,41,3,90,10,101,120,116,101,110,115,105,111,110,115, + 90,6,115,111,117,114,99,101,90,8,98,121,116,101,99,111, + 100,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,208,0,0,0,91,6,0,0,115,8,0,0,0,0, + 5,12,1,8,1,8,1,114,208,0,0,0,99,1,0,0, + 0,0,0,0,0,0,0,0,0,12,0,0,0,9,0,0, + 0,67,0,0,0,115,178,1,0,0,124,0,97,0,116,0, + 106,1,97,1,116,0,106,2,97,2,116,1,106,3,116,4, + 25,0,125,1,100,1,68,0,93,48,125,2,124,2,116,1, + 106,3,107,7,114,56,116,0,160,5,124,2,161,1,125,3, + 110,10,116,1,106,3,124,2,25,0,125,3,116,6,124,1, + 124,2,124,3,131,3,1,0,113,30,100,2,100,3,103,1, + 102,2,100,4,100,5,100,3,103,2,102,2,102,2,125,4, + 124,4,68,0,93,110,92,2,125,5,125,6,116,7,100,6, + 100,7,132,0,124,6,68,0,131,1,131,1,115,136,116,8, + 130,1,124,6,100,8,25,0,125,7,124,5,116,1,106,3, + 107,6,114,170,116,1,106,3,124,5,25,0,125,8,1,0, + 113,226,113,106,122,20,116,0,160,5,124,5,161,1,125,8, + 87,0,1,0,113,226,87,0,113,106,4,0,116,9,107,10, + 114,214,1,0,1,0,1,0,89,0,113,106,89,0,113,106, + 88,0,113,106,116,9,100,9,131,1,130,1,116,6,124,1, + 100,10,124,8,131,3,1,0,116,6,124,1,100,11,124,7, + 131,3,1,0,116,6,124,1,100,12,100,13,160,10,124,6, + 161,1,131,3,1,0,116,6,124,1,100,14,100,15,100,16, + 132,0,124,6,68,0,131,1,131,3,1,0,116,0,160,5, + 100,17,161,1,125,9,116,6,124,1,100,17,124,9,131,3, + 1,0,116,0,160,5,100,18,161,1,125,10,116,6,124,1, + 100,18,124,10,131,3,1,0,124,5,100,4,107,2,144,1, + 114,110,116,0,160,5,100,19,161,1,125,11,116,6,124,1, + 100,20,124,11,131,3,1,0,116,6,124,1,100,21,116,11, + 131,0,131,3,1,0,116,12,160,13,116,2,160,14,161,0, + 161,1,1,0,124,5,100,4,107,2,144,1,114,174,116,15, + 160,16,100,22,161,1,1,0,100,23,116,12,107,6,144,1, + 114,174,100,24,116,17,95,18,100,25,83,0,41,26,122,205, + 83,101,116,117,112,32,116,104,101,32,112,97,116,104,45,98, + 97,115,101,100,32,105,109,112,111,114,116,101,114,115,32,102, + 111,114,32,105,109,112,111,114,116,108,105,98,32,98,121,32, + 105,109,112,111,114,116,105,110,103,32,110,101,101,100,101,100, + 10,32,32,32,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,115,32,97,110,100,32,105,110,106,101,99,116, + 105,110,103,32,116,104,101,109,32,105,110,116,111,32,116,104, + 101,32,103,108,111,98,97,108,32,110,97,109,101,115,112,97, + 99,101,46,10,10,32,32,32,32,79,116,104,101,114,32,99, + 111,109,112,111,110,101,110,116,115,32,97,114,101,32,101,120, + 116,114,97,99,116,101,100,32,102,114,111,109,32,116,104,101, + 32,99,111,114,101,32,98,111,111,116,115,116,114,97,112,32, + 109,111,100,117,108,101,46,10,10,32,32,32,32,41,4,114, + 89,0,0,0,114,97,0,0,0,218,8,98,117,105,108,116, + 105,110,115,114,184,0,0,0,218,5,112,111,115,105,120,114, + 2,0,0,0,218,2,110,116,114,1,0,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,115,0,0,0,115,26,0,0,0,124,0,93,18,125, + 1,116,0,124,1,131,1,100,0,107,2,86,0,1,0,113, + 2,100,1,83,0,114,3,0,0,0,114,5,0,0,0,114, + 7,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,12,0,0,0,127,6,0,0,115,4,0,0, + 0,4,0,2,0,122,25,95,115,101,116,117,112,46,60,108, + 111,99,97,108,115,62,46,60,103,101,110,101,120,112,114,62, + 114,0,0,0,0,122,30,105,109,112,111,114,116,108,105,98, + 32,114,101,113,117,105,114,101,115,32,112,111,115,105,120,32, + 111,114,32,110,116,114,21,0,0,0,114,58,0,0,0,114, + 49,0,0,0,114,13,0,0,0,218,20,95,112,97,116,104, + 115,101,112,115,95,119,105,116,104,95,99,111,108,111,110,99, + 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 4,0,0,0,83,0,0,0,115,22,0,0,0,104,0,124, + 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113, + 4,83,0,114,14,0,0,0,114,10,0,0,0,114,16,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,18,0,0,0,143,6,0,0,115,4,0,0,0,6, + 0,2,0,122,25,95,115,101,116,117,112,46,60,108,111,99, + 97,108,115,62,46,60,115,101,116,99,111,109,112,62,90,7, + 95,116,104,114,101,97,100,90,8,95,119,101,97,107,114,101, + 102,218,6,119,105,110,114,101,103,114,215,0,0,0,114,24, + 0,0,0,122,4,46,112,121,119,122,6,95,100,46,112,121, + 100,84,78,41,19,114,158,0,0,0,114,25,0,0,0,114, + 187,0,0,0,114,54,1,0,0,114,149,0,0,0,90,18, + 95,98,117,105,108,116,105,110,95,102,114,111,109,95,110,97, + 109,101,114,153,0,0,0,218,3,97,108,108,114,39,0,0, + 0,114,141,0,0,0,114,61,0,0,0,114,30,0,0,0, + 114,44,1,0,0,114,191,0,0,0,114,104,1,0,0,114, + 126,0,0,0,114,60,0,0,0,114,214,0,0,0,114,218, + 0,0,0,41,12,218,17,95,98,111,111,116,115,116,114,97, + 112,95,109,111,100,117,108,101,90,11,115,101,108,102,95,109, + 111,100,117,108,101,90,12,98,117,105,108,116,105,110,95,110, + 97,109,101,90,14,98,117,105,108,116,105,110,95,109,111,100, + 117,108,101,90,10,111,115,95,100,101,116,97,105,108,115,90, + 10,98,117,105,108,116,105,110,95,111,115,114,49,0,0,0, + 114,58,0,0,0,90,9,111,115,95,109,111,100,117,108,101, + 90,13,116,104,114,101,97,100,95,109,111,100,117,108,101,90, + 14,119,101,97,107,114,101,102,95,109,111,100,117,108,101,90, + 13,119,105,110,114,101,103,95,109,111,100,117,108,101,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,6,95, + 115,101,116,117,112,102,6,0,0,115,78,0,0,0,0,8, + 4,1,6,1,6,3,10,1,8,1,10,1,12,2,10,1, + 14,3,22,1,12,2,22,1,8,1,10,1,10,1,6,2, + 2,1,10,1,10,1,14,1,12,2,8,1,12,1,12,1, + 18,1,22,3,10,1,12,3,10,1,12,3,10,1,10,1, + 12,3,14,1,14,1,10,1,10,1,10,1,114,112,1,0, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,4,0,0,0,67,0,0,0,115,50,0,0,0,116, + 0,124,0,131,1,1,0,116,1,131,0,125,1,116,2,106, + 3,160,4,116,5,106,6,124,1,142,0,103,1,161,1,1, + 0,116,2,106,7,160,8,116,9,161,1,1,0,100,1,83, + 0,41,2,122,41,73,110,115,116,97,108,108,32,116,104,101, + 32,112,97,116,104,45,98,97,115,101,100,32,105,109,112,111, + 114,116,32,99,111,109,112,111,110,101,110,116,115,46,78,41, + 10,114,112,1,0,0,114,208,0,0,0,114,25,0,0,0, + 114,74,1,0,0,114,191,0,0,0,114,84,1,0,0,114, + 98,1,0,0,218,9,109,101,116,97,95,112,97,116,104,114, + 60,0,0,0,114,68,1,0,0,41,2,114,111,1,0,0, + 90,17,115,117,112,112,111,114,116,101,100,95,108,111,97,100, + 101,114,115,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,8,95,105,110,115,116,97,108,108,167,6,0,0, + 115,8,0,0,0,0,2,8,1,6,1,20,1,114,114,1, + 0,0,41,1,114,85,0,0,0,41,1,78,41,3,78,78, + 78,41,2,114,0,0,0,0,114,0,0,0,0,41,1,84, + 41,1,78,41,1,78,41,82,114,151,0,0,0,114,187,0, + 0,0,114,89,0,0,0,114,25,0,0,0,114,97,0,0, + 0,114,184,0,0,0,114,26,0,0,0,90,11,95,77,83, + 95,87,73,78,68,79,87,83,114,107,1,0,0,114,21,0, + 0,0,114,109,1,0,0,114,106,1,0,0,114,49,0,0, + 0,114,110,1,0,0,114,39,0,0,0,114,58,0,0,0, + 114,135,0,0,0,114,56,0,0,0,114,61,0,0,0,114, + 108,1,0,0,114,29,0,0,0,90,37,95,67,65,83,69, + 95,73,78,83,69,78,83,73,84,73,86,69,95,80,76,65, + 84,70,79,82,77,83,95,66,89,84,69,83,95,75,69,89, + 114,28,0,0,0,114,30,0,0,0,114,37,0,0,0,114, + 43,0,0,0,114,45,0,0,0,114,66,0,0,0,114,73, + 0,0,0,114,74,0,0,0,114,78,0,0,0,114,79,0, + 0,0,114,81,0,0,0,114,84,0,0,0,114,93,0,0, + 0,218,4,116,121,112,101,218,8,95,95,99,111,100,101,95, + 95,114,186,0,0,0,114,35,0,0,0,114,172,0,0,0, + 114,34,0,0,0,114,40,0,0,0,114,3,1,0,0,114, + 115,0,0,0,114,111,0,0,0,114,126,0,0,0,114,112, + 0,0,0,90,23,68,69,66,85,71,95,66,89,84,69,67, + 79,68,69,95,83,85,70,70,73,88,69,83,90,27,79,80, + 84,73,77,73,90,69,68,95,66,89,84,69,67,79,68,69, + 95,83,85,70,70,73,88,69,83,114,120,0,0,0,114,127, + 0,0,0,114,134,0,0,0,114,136,0,0,0,114,138,0, + 0,0,114,160,0,0,0,114,167,0,0,0,114,176,0,0, + 0,114,180,0,0,0,114,182,0,0,0,114,189,0,0,0, + 114,194,0,0,0,114,195,0,0,0,114,200,0,0,0,218, + 6,111,98,106,101,99,116,114,209,0,0,0,114,213,0,0, + 0,114,214,0,0,0,114,231,0,0,0,114,244,0,0,0, + 114,6,1,0,0,114,32,1,0,0,114,39,1,0,0,114, + 44,1,0,0,114,19,1,0,0,114,45,1,0,0,114,66, + 1,0,0,114,68,1,0,0,114,84,1,0,0,114,103,1, + 0,0,114,208,0,0,0,114,112,1,0,0,114,114,1,0, + 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,8,60,109,111,100,117,108,101,62,1, + 0,0,0,115,170,0,0,0,4,22,8,1,8,1,8,1, + 8,1,8,3,10,1,4,1,8,1,10,2,8,3,4,1, + 10,2,6,2,22,1,8,1,8,1,10,1,14,4,4,1, + 4,1,2,1,2,255,4,4,8,17,8,5,8,5,8,6, + 4,1,10,30,8,6,8,8,8,10,8,9,8,5,8,7, + 6,1,10,8,8,5,10,22,10,127,0,13,16,1,12,2, + 4,1,4,2,6,2,6,2,8,2,16,71,8,40,8,19, + 8,12,8,12,8,28,8,17,8,33,8,28,8,24,10,13, + 10,10,10,11,8,14,6,3,4,1,2,255,12,73,14,64, + 14,29,16,127,0,17,14,72,18,45,18,26,4,3,18,53, + 14,63,14,42,14,127,0,20,14,127,0,27,10,23,8,11, + 8,65, +}; diff --git a/python/Python/importlib_zipimport.h b/python/Python/importlib_zipimport.h new file mode 100755 index 0000000..f013b41 --- /dev/null +++ b/python/Python/importlib_zipimport.h @@ -0,0 +1,1081 @@ +/* Auto-generated by Programs/_freeze_importlib.c */ +const unsigned char _Py_M__zipimport[] = { + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,64,0,0,0,115,82,1,0,0,100,0, + 90,0,100,1,100,2,108,1,90,2,100,1,100,3,108,1, + 109,3,90,3,109,4,90,4,1,0,100,1,100,2,108,5, + 90,6,100,1,100,2,108,7,90,7,100,1,100,2,108,8, + 90,8,100,1,100,2,108,9,90,9,100,1,100,2,108,10, + 90,10,100,1,100,2,108,11,90,11,100,4,100,5,103,2, + 90,12,101,2,106,13,90,13,101,2,106,14,100,6,100,2, + 133,2,25,0,90,15,71,0,100,7,100,4,132,0,100,4, + 101,16,131,3,90,17,105,0,90,18,101,19,101,10,131,1, + 90,20,100,8,90,21,100,9,90,22,100,10,90,23,71,0, + 100,11,100,5,132,0,100,5,131,2,90,24,101,13,100,12, + 23,0,100,13,100,13,102,3,101,13,100,14,23,0,100,15, + 100,13,102,3,100,16,100,17,102,4,90,25,100,18,100,19, + 132,0,90,26,100,20,100,21,132,0,90,27,100,22,100,23, + 132,0,90,28,100,24,100,25,132,0,90,29,100,26,90,30, + 100,15,97,31,100,27,100,28,132,0,90,32,100,29,100,30, + 132,0,90,33,100,31,100,32,132,0,90,34,100,33,100,34, + 132,0,90,35,101,19,101,35,106,36,131,1,90,37,100,35, + 100,36,132,0,90,38,100,37,100,38,132,0,90,39,100,39, + 100,40,132,0,90,40,100,41,100,42,132,0,90,41,100,43, + 100,44,132,0,90,42,100,45,100,46,132,0,90,43,71,0, + 100,47,100,48,132,0,100,48,131,2,90,44,100,2,83,0, + 41,49,97,80,2,0,0,122,105,112,105,109,112,111,114,116, + 32,112,114,111,118,105,100,101,115,32,115,117,112,112,111,114, + 116,32,102,111,114,32,105,109,112,111,114,116,105,110,103,32, + 80,121,116,104,111,110,32,109,111,100,117,108,101,115,32,102, + 114,111,109,32,90,105,112,32,97,114,99,104,105,118,101,115, + 46,10,10,84,104,105,115,32,109,111,100,117,108,101,32,101, + 120,112,111,114,116,115,32,116,104,114,101,101,32,111,98,106, + 101,99,116,115,58,10,45,32,122,105,112,105,109,112,111,114, + 116,101,114,58,32,97,32,99,108,97,115,115,59,32,105,116, + 115,32,99,111,110,115,116,114,117,99,116,111,114,32,116,97, + 107,101,115,32,97,32,112,97,116,104,32,116,111,32,97,32, + 90,105,112,32,97,114,99,104,105,118,101,46,10,45,32,90, + 105,112,73,109,112,111,114,116,69,114,114,111,114,58,32,101, + 120,99,101,112,116,105,111,110,32,114,97,105,115,101,100,32, + 98,121,32,122,105,112,105,109,112,111,114,116,101,114,32,111, + 98,106,101,99,116,115,46,32,73,116,39,115,32,97,10,32, + 32,115,117,98,99,108,97,115,115,32,111,102,32,73,109,112, + 111,114,116,69,114,114,111,114,44,32,115,111,32,105,116,32, + 99,97,110,32,98,101,32,99,97,117,103,104,116,32,97,115, + 32,73,109,112,111,114,116,69,114,114,111,114,44,32,116,111, + 111,46,10,45,32,95,122,105,112,95,100,105,114,101,99,116, + 111,114,121,95,99,97,99,104,101,58,32,97,32,100,105,99, + 116,44,32,109,97,112,112,105,110,103,32,97,114,99,104,105, + 118,101,32,112,97,116,104,115,32,116,111,32,122,105,112,32, + 100,105,114,101,99,116,111,114,121,10,32,32,105,110,102,111, + 32,100,105,99,116,115,44,32,97,115,32,117,115,101,100,32, + 105,110,32,122,105,112,105,109,112,111,114,116,101,114,46,95, + 102,105,108,101,115,46,10,10,73,116,32,105,115,32,117,115, + 117,97,108,108,121,32,110,111,116,32,110,101,101,100,101,100, + 32,116,111,32,117,115,101,32,116,104,101,32,122,105,112,105, + 109,112,111,114,116,32,109,111,100,117,108,101,32,101,120,112, + 108,105,99,105,116,108,121,59,32,105,116,32,105,115,10,117, + 115,101,100,32,98,121,32,116,104,101,32,98,117,105,108,116, + 105,110,32,105,109,112,111,114,116,32,109,101,99,104,97,110, + 105,115,109,32,102,111,114,32,115,121,115,46,112,97,116,104, + 32,105,116,101,109,115,32,116,104,97,116,32,97,114,101,32, + 112,97,116,104,115,10,116,111,32,90,105,112,32,97,114,99, + 104,105,118,101,115,46,10,233,0,0,0,0,78,41,2,218, + 14,95,117,110,112,97,99,107,95,117,105,110,116,49,54,218, + 14,95,117,110,112,97,99,107,95,117,105,110,116,51,50,218, + 14,90,105,112,73,109,112,111,114,116,69,114,114,111,114,218, + 11,122,105,112,105,109,112,111,114,116,101,114,233,1,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,64,0,0,0,115,12,0,0,0,101, + 0,90,1,100,0,90,2,100,1,83,0,41,2,114,3,0, + 0,0,78,41,3,218,8,95,95,110,97,109,101,95,95,218, + 10,95,95,109,111,100,117,108,101,95,95,218,12,95,95,113, + 117,97,108,110,97,109,101,95,95,169,0,114,9,0,0,0, + 114,9,0,0,0,250,18,60,102,114,111,122,101,110,32,122, + 105,112,105,109,112,111,114,116,62,114,3,0,0,0,33,0, + 0,0,115,2,0,0,0,8,1,233,22,0,0,0,115,4, + 0,0,0,80,75,5,6,105,255,255,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,64,0,0,0,115,108,0,0,0,101,0,90,1,100,0, + 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,25, + 100,5,100,6,132,1,90,5,100,26,100,7,100,8,132,1, + 90,6,100,9,100,10,132,0,90,7,100,11,100,12,132,0, + 90,8,100,13,100,14,132,0,90,9,100,15,100,16,132,0, + 90,10,100,17,100,18,132,0,90,11,100,19,100,20,132,0, + 90,12,100,21,100,22,132,0,90,13,100,23,100,24,132,0, + 90,14,100,4,83,0,41,27,114,4,0,0,0,97,255,1, + 0,0,122,105,112,105,109,112,111,114,116,101,114,40,97,114, + 99,104,105,118,101,112,97,116,104,41,32,45,62,32,122,105, + 112,105,109,112,111,114,116,101,114,32,111,98,106,101,99,116, + 10,10,32,32,32,32,67,114,101,97,116,101,32,97,32,110, + 101,119,32,122,105,112,105,109,112,111,114,116,101,114,32,105, + 110,115,116,97,110,99,101,46,32,39,97,114,99,104,105,118, + 101,112,97,116,104,39,32,109,117,115,116,32,98,101,32,97, + 32,112,97,116,104,32,116,111,10,32,32,32,32,97,32,122, + 105,112,102,105,108,101,44,32,111,114,32,116,111,32,97,32, + 115,112,101,99,105,102,105,99,32,112,97,116,104,32,105,110, + 115,105,100,101,32,97,32,122,105,112,102,105,108,101,46,32, + 70,111,114,32,101,120,97,109,112,108,101,44,32,105,116,32, + 99,97,110,32,98,101,10,32,32,32,32,39,47,116,109,112, + 47,109,121,105,109,112,111,114,116,46,122,105,112,39,44,32, + 111,114,32,39,47,116,109,112,47,109,121,105,109,112,111,114, + 116,46,122,105,112,47,109,121,100,105,114,101,99,116,111,114, + 121,39,44,32,105,102,32,109,121,100,105,114,101,99,116,111, + 114,121,32,105,115,32,97,10,32,32,32,32,118,97,108,105, + 100,32,100,105,114,101,99,116,111,114,121,32,105,110,115,105, + 100,101,32,116,104,101,32,97,114,99,104,105,118,101,46,10, + 10,32,32,32,32,39,90,105,112,73,109,112,111,114,116,69, + 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105, + 102,32,39,97,114,99,104,105,118,101,112,97,116,104,39,32, + 100,111,101,115,110,39,116,32,112,111,105,110,116,32,116,111, + 32,97,32,118,97,108,105,100,32,90,105,112,10,32,32,32, + 32,97,114,99,104,105,118,101,46,10,10,32,32,32,32,84, + 104,101,32,39,97,114,99,104,105,118,101,39,32,97,116,116, + 114,105,98,117,116,101,32,111,102,32,122,105,112,105,109,112, + 111,114,116,101,114,32,111,98,106,101,99,116,115,32,99,111, + 110,116,97,105,110,115,32,116,104,101,32,110,97,109,101,32, + 111,102,32,116,104,101,10,32,32,32,32,122,105,112,102,105, + 108,101,32,116,97,114,103,101,116,101,100,46,10,32,32,32, + 32,99,2,0,0,0,0,0,0,0,0,0,0,0,8,0, + 0,0,9,0,0,0,67,0,0,0,115,36,1,0,0,116, + 0,124,1,116,1,131,2,115,28,100,1,100,0,108,2,125, + 2,124,2,160,3,124,1,161,1,125,1,124,1,115,44,116, + 4,100,2,124,1,100,3,141,2,130,1,116,5,114,60,124, + 1,160,6,116,5,116,7,161,2,125,1,103,0,125,3,122, + 14,116,8,160,9,124,1,161,1,125,4,87,0,110,72,4, + 0,116,10,116,11,102,2,107,10,114,150,1,0,1,0,1, + 0,116,8,160,12,124,1,161,1,92,2,125,5,125,6,124, + 5,124,1,107,2,114,132,116,4,100,4,124,1,100,3,141, + 2,130,1,124,5,125,1,124,3,160,13,124,6,161,1,1, + 0,89,0,113,64,88,0,124,4,106,14,100,5,64,0,100, + 6,107,3,114,182,116,4,100,4,124,1,100,3,141,2,130, + 1,113,182,113,64,122,12,116,15,124,1,25,0,125,7,87, + 0,110,36,4,0,116,16,107,10,114,230,1,0,1,0,1, + 0,116,17,124,1,131,1,125,7,124,7,116,15,124,1,60, + 0,89,0,110,2,88,0,124,7,124,0,95,18,124,1,124, + 0,95,19,116,8,106,20,124,3,100,0,100,0,100,7,133, + 3,25,0,142,0,124,0,95,21,124,0,106,21,144,1,114, + 32,124,0,4,0,106,21,116,7,55,0,2,0,95,21,100, + 0,83,0,41,8,78,114,0,0,0,0,122,21,97,114,99, + 104,105,118,101,32,112,97,116,104,32,105,115,32,101,109,112, + 116,121,169,1,218,4,112,97,116,104,122,14,110,111,116,32, + 97,32,90,105,112,32,102,105,108,101,105,0,240,0,0,105, + 0,128,0,0,233,255,255,255,255,41,22,218,10,105,115,105, + 110,115,116,97,110,99,101,218,3,115,116,114,218,2,111,115, + 90,8,102,115,100,101,99,111,100,101,114,3,0,0,0,218, + 12,97,108,116,95,112,97,116,104,95,115,101,112,218,7,114, + 101,112,108,97,99,101,218,8,112,97,116,104,95,115,101,112, + 218,19,95,98,111,111,116,115,116,114,97,112,95,101,120,116, + 101,114,110,97,108,90,10,95,112,97,116,104,95,115,116,97, + 116,218,7,79,83,69,114,114,111,114,218,10,86,97,108,117, + 101,69,114,114,111,114,90,11,95,112,97,116,104,95,115,112, + 108,105,116,218,6,97,112,112,101,110,100,90,7,115,116,95, + 109,111,100,101,218,20,95,122,105,112,95,100,105,114,101,99, + 116,111,114,121,95,99,97,99,104,101,218,8,75,101,121,69, + 114,114,111,114,218,15,95,114,101,97,100,95,100,105,114,101, + 99,116,111,114,121,218,6,95,102,105,108,101,115,218,7,97, + 114,99,104,105,118,101,218,10,95,112,97,116,104,95,106,111, + 105,110,218,6,112,114,101,102,105,120,41,8,218,4,115,101, + 108,102,114,13,0,0,0,114,17,0,0,0,114,31,0,0, + 0,90,2,115,116,90,7,100,105,114,110,97,109,101,90,8, + 98,97,115,101,110,97,109,101,218,5,102,105,108,101,115,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,8, + 95,95,105,110,105,116,95,95,63,0,0,0,115,58,0,0, + 0,0,1,10,1,8,1,10,1,4,1,12,1,4,1,12, + 2,4,2,2,1,14,1,18,3,14,1,8,1,12,1,4, + 1,16,3,14,2,12,1,4,2,2,1,12,1,14,1,8, + 1,14,1,6,1,6,2,22,1,8,1,122,20,122,105,112, + 105,109,112,111,114,116,101,114,46,95,95,105,110,105,116,95, + 95,78,99,3,0,0,0,0,0,0,0,0,0,0,0,5, + 0,0,0,4,0,0,0,67,0,0,0,115,78,0,0,0, + 116,0,124,0,124,1,131,2,125,3,124,3,100,1,107,9, + 114,26,124,0,103,0,102,2,83,0,116,1,124,0,124,1, + 131,2,125,4,116,2,124,0,124,4,131,2,114,70,100,1, + 124,0,106,3,155,0,116,4,155,0,124,4,155,0,157,3, + 103,1,102,2,83,0,100,1,103,0,102,2,83,0,41,2, + 97,239,1,0,0,102,105,110,100,95,108,111,97,100,101,114, + 40,102,117,108,108,110,97,109,101,44,32,112,97,116,104,61, + 78,111,110,101,41,32,45,62,32,115,101,108,102,44,32,115, + 116,114,32,111,114,32,78,111,110,101,46,10,10,32,32,32, + 32,32,32,32,32,83,101,97,114,99,104,32,102,111,114,32, + 97,32,109,111,100,117,108,101,32,115,112,101,99,105,102,105, + 101,100,32,98,121,32,39,102,117,108,108,110,97,109,101,39, + 46,32,39,102,117,108,108,110,97,109,101,39,32,109,117,115, + 116,32,98,101,32,116,104,101,10,32,32,32,32,32,32,32, + 32,102,117,108,108,121,32,113,117,97,108,105,102,105,101,100, + 32,40,100,111,116,116,101,100,41,32,109,111,100,117,108,101, + 32,110,97,109,101,46,32,73,116,32,114,101,116,117,114,110, + 115,32,116,104,101,32,122,105,112,105,109,112,111,114,116,101, + 114,10,32,32,32,32,32,32,32,32,105,110,115,116,97,110, + 99,101,32,105,116,115,101,108,102,32,105,102,32,116,104,101, + 32,109,111,100,117,108,101,32,119,97,115,32,102,111,117,110, + 100,44,32,97,32,115,116,114,105,110,103,32,99,111,110,116, + 97,105,110,105,110,103,32,116,104,101,10,32,32,32,32,32, + 32,32,32,102,117,108,108,32,112,97,116,104,32,110,97,109, + 101,32,105,102,32,105,116,39,115,32,112,111,115,115,105,98, + 108,121,32,97,32,112,111,114,116,105,111,110,32,111,102,32, + 97,32,110,97,109,101,115,112,97,99,101,32,112,97,99,107, + 97,103,101,44,10,32,32,32,32,32,32,32,32,111,114,32, + 78,111,110,101,32,111,116,104,101,114,119,105,115,101,46,32, + 84,104,101,32,111,112,116,105,111,110,97,108,32,39,112,97, + 116,104,39,32,97,114,103,117,109,101,110,116,32,105,115,32, + 105,103,110,111,114,101,100,32,45,45,32,105,116,39,115,10, + 32,32,32,32,32,32,32,32,116,104,101,114,101,32,102,111, + 114,32,99,111,109,112,97,116,105,98,105,108,105,116,121,32, + 119,105,116,104,32,116,104,101,32,105,109,112,111,114,116,101, + 114,32,112,114,111,116,111,99,111,108,46,10,32,32,32,32, + 32,32,32,32,78,41,5,218,16,95,103,101,116,95,109,111, + 100,117,108,101,95,105,110,102,111,218,16,95,103,101,116,95, + 109,111,100,117,108,101,95,112,97,116,104,218,7,95,105,115, + 95,100,105,114,114,29,0,0,0,114,20,0,0,0,41,5, + 114,32,0,0,0,218,8,102,117,108,108,110,97,109,101,114, + 13,0,0,0,218,2,109,105,218,7,109,111,100,112,97,116, + 104,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 218,11,102,105,110,100,95,108,111,97,100,101,114,109,0,0, + 0,115,14,0,0,0,0,10,10,1,8,2,8,7,10,1, + 10,4,24,2,122,23,122,105,112,105,109,112,111,114,116,101, + 114,46,102,105,110,100,95,108,111,97,100,101,114,99,3,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,16,0,0,0,124,0,160,0,124, + 1,124,2,161,2,100,1,25,0,83,0,41,2,97,139,1, + 0,0,102,105,110,100,95,109,111,100,117,108,101,40,102,117, + 108,108,110,97,109,101,44,32,112,97,116,104,61,78,111,110, + 101,41,32,45,62,32,115,101,108,102,32,111,114,32,78,111, + 110,101,46,10,10,32,32,32,32,32,32,32,32,83,101,97, + 114,99,104,32,102,111,114,32,97,32,109,111,100,117,108,101, + 32,115,112,101,99,105,102,105,101,100,32,98,121,32,39,102, + 117,108,108,110,97,109,101,39,46,32,39,102,117,108,108,110, + 97,109,101,39,32,109,117,115,116,32,98,101,32,116,104,101, + 10,32,32,32,32,32,32,32,32,102,117,108,108,121,32,113, + 117,97,108,105,102,105,101,100,32,40,100,111,116,116,101,100, + 41,32,109,111,100,117,108,101,32,110,97,109,101,46,32,73, + 116,32,114,101,116,117,114,110,115,32,116,104,101,32,122,105, + 112,105,109,112,111,114,116,101,114,10,32,32,32,32,32,32, + 32,32,105,110,115,116,97,110,99,101,32,105,116,115,101,108, + 102,32,105,102,32,116,104,101,32,109,111,100,117,108,101,32, + 119,97,115,32,102,111,117,110,100,44,32,111,114,32,78,111, + 110,101,32,105,102,32,105,116,32,119,97,115,110,39,116,46, + 10,32,32,32,32,32,32,32,32,84,104,101,32,111,112,116, + 105,111,110,97,108,32,39,112,97,116,104,39,32,97,114,103, + 117,109,101,110,116,32,105,115,32,105,103,110,111,114,101,100, + 32,45,45,32,105,116,39,115,32,116,104,101,114,101,32,102, + 111,114,32,99,111,109,112,97,116,105,98,105,108,105,116,121, + 10,32,32,32,32,32,32,32,32,119,105,116,104,32,116,104, + 101,32,105,109,112,111,114,116,101,114,32,112,114,111,116,111, + 99,111,108,46,10,32,32,32,32,32,32,32,32,114,0,0, + 0,0,41,1,114,41,0,0,0,41,3,114,32,0,0,0, + 114,38,0,0,0,114,13,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,11,102,105,110,100,95, + 109,111,100,117,108,101,141,0,0,0,115,2,0,0,0,0, + 9,122,23,122,105,112,105,109,112,111,114,116,101,114,46,102, + 105,110,100,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,3,0,0,0,67, + 0,0,0,115,20,0,0,0,116,0,124,0,124,1,131,2, + 92,3,125,2,125,3,125,4,124,2,83,0,41,1,122,163, + 103,101,116,95,99,111,100,101,40,102,117,108,108,110,97,109, + 101,41,32,45,62,32,99,111,100,101,32,111,98,106,101,99, + 116,46,10,10,32,32,32,32,32,32,32,32,82,101,116,117, + 114,110,32,116,104,101,32,99,111,100,101,32,111,98,106,101, + 99,116,32,102,111,114,32,116,104,101,32,115,112,101,99,105, + 102,105,101,100,32,109,111,100,117,108,101,46,32,82,97,105, + 115,101,32,90,105,112,73,109,112,111,114,116,69,114,114,111, + 114,10,32,32,32,32,32,32,32,32,105,102,32,116,104,101, + 32,109,111,100,117,108,101,32,99,111,117,108,100,110,39,116, + 32,98,101,32,102,111,117,110,100,46,10,32,32,32,32,32, + 32,32,32,169,1,218,16,95,103,101,116,95,109,111,100,117, + 108,101,95,99,111,100,101,169,5,114,32,0,0,0,114,38, + 0,0,0,218,4,99,111,100,101,218,9,105,115,112,97,99, + 107,97,103,101,114,40,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,8,103,101,116,95,99,111, + 100,101,153,0,0,0,115,4,0,0,0,0,6,16,1,122, + 20,122,105,112,105,109,112,111,114,116,101,114,46,103,101,116, + 95,99,111,100,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,118, + 0,0,0,116,0,114,16,124,1,160,1,116,0,116,2,161, + 2,125,1,124,1,125,2,124,1,160,3,124,0,106,4,116, + 2,23,0,161,1,114,58,124,1,116,5,124,0,106,4,116, + 2,23,0,131,1,100,1,133,2,25,0,125,2,122,14,124, + 0,106,6,124,2,25,0,125,3,87,0,110,32,4,0,116, + 7,107,10,114,104,1,0,1,0,1,0,116,8,100,2,100, + 3,124,2,131,3,130,1,89,0,110,2,88,0,116,9,124, + 0,106,4,124,3,131,2,83,0,41,4,122,154,103,101,116, + 95,100,97,116,97,40,112,97,116,104,110,97,109,101,41,32, + 45,62,32,115,116,114,105,110,103,32,119,105,116,104,32,102, + 105,108,101,32,100,97,116,97,46,10,10,32,32,32,32,32, + 32,32,32,82,101,116,117,114,110,32,116,104,101,32,100,97, + 116,97,32,97,115,115,111,99,105,97,116,101,100,32,119,105, + 116,104,32,39,112,97,116,104,110,97,109,101,39,46,32,82, + 97,105,115,101,32,79,83,69,114,114,111,114,32,105,102,10, + 32,32,32,32,32,32,32,32,116,104,101,32,102,105,108,101, + 32,119,97,115,110,39,116,32,102,111,117,110,100,46,10,32, + 32,32,32,32,32,32,32,78,114,0,0,0,0,218,0,41, + 10,114,18,0,0,0,114,19,0,0,0,114,20,0,0,0, + 218,10,115,116,97,114,116,115,119,105,116,104,114,29,0,0, + 0,218,3,108,101,110,114,28,0,0,0,114,26,0,0,0, + 114,22,0,0,0,218,9,95,103,101,116,95,100,97,116,97, + 41,4,114,32,0,0,0,218,8,112,97,116,104,110,97,109, + 101,90,3,107,101,121,218,9,116,111,99,95,101,110,116,114, + 121,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 218,8,103,101,116,95,100,97,116,97,163,0,0,0,115,20, + 0,0,0,0,6,4,1,12,2,4,1,16,1,22,2,2, + 1,14,1,14,1,18,1,122,20,122,105,112,105,109,112,111, + 114,116,101,114,46,103,101,116,95,100,97,116,97,99,2,0, + 0,0,0,0,0,0,0,0,0,0,5,0,0,0,3,0, + 0,0,67,0,0,0,115,20,0,0,0,116,0,124,0,124, + 1,131,2,92,3,125,2,125,3,125,4,124,4,83,0,41, + 1,122,106,103,101,116,95,102,105,108,101,110,97,109,101,40, + 102,117,108,108,110,97,109,101,41,32,45,62,32,102,105,108, + 101,110,97,109,101,32,115,116,114,105,110,103,46,10,10,32, + 32,32,32,32,32,32,32,82,101,116,117,114,110,32,116,104, + 101,32,102,105,108,101,110,97,109,101,32,102,111,114,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,46,10,32,32,32,32,32,32,32,32,114,43,0, + 0,0,114,45,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,12,103,101,116,95,102,105,108,101, + 110,97,109,101,184,0,0,0,115,4,0,0,0,0,7,16, + 1,122,24,122,105,112,105,109,112,111,114,116,101,114,46,103, + 101,116,95,102,105,108,101,110,97,109,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,6,0,0,0,8,0,0,0, + 67,0,0,0,115,128,0,0,0,116,0,124,0,124,1,131, + 2,125,2,124,2,100,1,107,8,114,36,116,1,100,2,124, + 1,155,2,157,2,124,1,100,3,141,2,130,1,116,2,124, + 0,124,1,131,2,125,3,124,2,114,64,116,3,160,4,124, + 3,100,4,161,2,125,4,110,10,124,3,155,0,100,5,157, + 2,125,4,122,14,124,0,106,5,124,4,25,0,125,5,87, + 0,110,22,4,0,116,6,107,10,114,110,1,0,1,0,1, + 0,89,0,100,1,83,0,88,0,116,7,124,0,106,8,124, + 5,131,2,160,9,161,0,83,0,41,6,122,253,103,101,116, + 95,115,111,117,114,99,101,40,102,117,108,108,110,97,109,101, + 41,32,45,62,32,115,111,117,114,99,101,32,115,116,114,105, + 110,103,46,10,10,32,32,32,32,32,32,32,32,82,101,116, + 117,114,110,32,116,104,101,32,115,111,117,114,99,101,32,99, + 111,100,101,32,102,111,114,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,109,111,100,117,108,101,46,32,82,97, + 105,115,101,32,90,105,112,73,109,112,111,114,116,69,114,114, + 111,114,10,32,32,32,32,32,32,32,32,105,102,32,116,104, + 101,32,109,111,100,117,108,101,32,99,111,117,108,100,110,39, + 116,32,98,101,32,102,111,117,110,100,44,32,114,101,116,117, + 114,110,32,78,111,110,101,32,105,102,32,116,104,101,32,97, + 114,99,104,105,118,101,32,100,111,101,115,10,32,32,32,32, + 32,32,32,32,99,111,110,116,97,105,110,32,116,104,101,32, + 109,111,100,117,108,101,44,32,98,117,116,32,104,97,115,32, + 110,111,32,115,111,117,114,99,101,32,102,111,114,32,105,116, + 46,10,32,32,32,32,32,32,32,32,78,250,18,99,97,110, + 39,116,32,102,105,110,100,32,109,111,100,117,108,101,32,169, + 1,218,4,110,97,109,101,250,11,95,95,105,110,105,116,95, + 95,46,112,121,250,3,46,112,121,41,10,114,35,0,0,0, + 114,3,0,0,0,114,36,0,0,0,114,21,0,0,0,114, + 30,0,0,0,114,28,0,0,0,114,26,0,0,0,114,52, + 0,0,0,114,29,0,0,0,218,6,100,101,99,111,100,101, + 41,6,114,32,0,0,0,114,38,0,0,0,114,39,0,0, + 0,114,13,0,0,0,218,8,102,117,108,108,112,97,116,104, + 114,54,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,218,10,103,101,116,95,115,111,117,114,99,101, + 195,0,0,0,115,24,0,0,0,0,7,10,1,8,1,18, + 2,10,1,4,1,14,2,10,2,2,1,14,1,14,2,8, + 1,122,22,122,105,112,105,109,112,111,114,116,101,114,46,103, + 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, + 0,0,115,40,0,0,0,116,0,124,0,124,1,131,2,125, + 2,124,2,100,1,107,8,114,36,116,1,100,2,124,1,155, + 2,157,2,124,1,100,3,141,2,130,1,124,2,83,0,41, + 4,122,171,105,115,95,112,97,99,107,97,103,101,40,102,117, + 108,108,110,97,109,101,41,32,45,62,32,98,111,111,108,46, + 10,10,32,32,32,32,32,32,32,32,82,101,116,117,114,110, + 32,84,114,117,101,32,105,102,32,116,104,101,32,109,111,100, + 117,108,101,32,115,112,101,99,105,102,105,101,100,32,98,121, + 32,102,117,108,108,110,97,109,101,32,105,115,32,97,32,112, + 97,99,107,97,103,101,46,10,32,32,32,32,32,32,32,32, + 82,97,105,115,101,32,90,105,112,73,109,112,111,114,116,69, + 114,114,111,114,32,105,102,32,116,104,101,32,109,111,100,117, + 108,101,32,99,111,117,108,100,110,39,116,32,98,101,32,102, + 111,117,110,100,46,10,32,32,32,32,32,32,32,32,78,114, + 57,0,0,0,114,58,0,0,0,41,2,114,35,0,0,0, + 114,3,0,0,0,41,3,114,32,0,0,0,114,38,0,0, + 0,114,39,0,0,0,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,10,105,115,95,112,97,99,107,97,103, + 101,221,0,0,0,115,8,0,0,0,0,6,10,1,8,1, + 18,1,122,22,122,105,112,105,109,112,111,114,116,101,114,46, + 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,67, + 0,0,0,115,248,0,0,0,116,0,124,0,124,1,131,2, + 92,3,125,2,125,3,125,4,116,1,106,2,160,3,124,1, + 161,1,125,5,124,5,100,1,107,8,115,46,116,4,124,5, + 116,5,131,2,115,64,116,5,124,1,131,1,125,5,124,5, + 116,1,106,2,124,1,60,0,124,0,124,5,95,6,122,84, + 124,3,114,108,116,7,124,0,124,1,131,2,125,6,116,8, + 160,9,124,0,106,10,124,6,161,2,125,7,124,7,103,1, + 124,5,95,11,116,12,124,5,100,2,131,2,115,124,116,13, + 124,5,95,13,116,8,160,14,124,5,106,15,124,1,124,4, + 161,3,1,0,116,16,124,2,124,5,106,15,131,2,1,0, + 87,0,110,22,1,0,1,0,1,0,116,1,106,2,124,1, + 61,0,130,0,89,0,110,2,88,0,122,14,116,1,106,2, + 124,1,25,0,125,5,87,0,110,36,4,0,116,17,107,10, + 114,228,1,0,1,0,1,0,116,18,100,3,124,1,155,2, + 100,4,157,3,131,1,130,1,89,0,110,2,88,0,116,19, + 160,20,100,5,124,1,124,4,161,3,1,0,124,5,83,0, + 41,6,122,245,108,111,97,100,95,109,111,100,117,108,101,40, + 102,117,108,108,110,97,109,101,41,32,45,62,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,32,32,32,32,76,111, + 97,100,32,116,104,101,32,109,111,100,117,108,101,32,115,112, + 101,99,105,102,105,101,100,32,98,121,32,39,102,117,108,108, + 110,97,109,101,39,46,32,39,102,117,108,108,110,97,109,101, + 39,32,109,117,115,116,32,98,101,32,116,104,101,10,32,32, + 32,32,32,32,32,32,102,117,108,108,121,32,113,117,97,108, + 105,102,105,101,100,32,40,100,111,116,116,101,100,41,32,109, + 111,100,117,108,101,32,110,97,109,101,46,32,73,116,32,114, + 101,116,117,114,110,115,32,116,104,101,32,105,109,112,111,114, + 116,101,100,10,32,32,32,32,32,32,32,32,109,111,100,117, + 108,101,44,32,111,114,32,114,97,105,115,101,115,32,90,105, + 112,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32, + 105,116,32,119,97,115,110,39,116,32,102,111,117,110,100,46, + 10,32,32,32,32,32,32,32,32,78,218,12,95,95,98,117, + 105,108,116,105,110,115,95,95,122,14,76,111,97,100,101,100, + 32,109,111,100,117,108,101,32,122,25,32,110,111,116,32,102, + 111,117,110,100,32,105,110,32,115,121,115,46,109,111,100,117, + 108,101,115,122,30,105,109,112,111,114,116,32,123,125,32,35, + 32,108,111,97,100,101,100,32,102,114,111,109,32,90,105,112, + 32,123,125,41,21,114,44,0,0,0,218,3,115,121,115,218, + 7,109,111,100,117,108,101,115,218,3,103,101,116,114,15,0, + 0,0,218,12,95,109,111,100,117,108,101,95,116,121,112,101, + 218,10,95,95,108,111,97,100,101,114,95,95,114,36,0,0, + 0,114,21,0,0,0,114,30,0,0,0,114,29,0,0,0, + 90,8,95,95,112,97,116,104,95,95,218,7,104,97,115,97, + 116,116,114,114,66,0,0,0,90,14,95,102,105,120,95,117, + 112,95,109,111,100,117,108,101,218,8,95,95,100,105,99,116, + 95,95,218,4,101,120,101,99,114,26,0,0,0,218,11,73, + 109,112,111,114,116,69,114,114,111,114,218,10,95,98,111,111, + 116,115,116,114,97,112,218,16,95,118,101,114,98,111,115,101, + 95,109,101,115,115,97,103,101,41,8,114,32,0,0,0,114, + 38,0,0,0,114,46,0,0,0,114,47,0,0,0,114,40, + 0,0,0,90,3,109,111,100,114,13,0,0,0,114,63,0, + 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, + 0,218,11,108,111,97,100,95,109,111,100,117,108,101,234,0, + 0,0,115,48,0,0,0,0,7,16,1,12,1,18,1,8, + 1,10,1,6,2,2,1,4,3,10,1,14,1,8,2,10, + 1,6,1,16,1,16,1,6,1,8,1,8,2,2,1,14, + 1,14,1,22,1,14,1,122,23,122,105,112,105,109,112,111, + 114,116,101,114,46,108,111,97,100,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,88,0,0,0,122,20, + 124,0,160,0,124,1,161,1,115,18,87,0,100,1,83,0, + 87,0,110,22,4,0,116,1,107,10,114,42,1,0,1,0, + 1,0,89,0,100,1,83,0,88,0,116,2,106,3,115,78, + 100,2,100,3,108,4,109,5,125,2,1,0,124,2,160,6, + 116,2,161,1,1,0,100,4,116,2,95,3,116,2,124,0, + 124,1,131,2,83,0,41,5,122,204,82,101,116,117,114,110, + 32,116,104,101,32,82,101,115,111,117,114,99,101,82,101,97, + 100,101,114,32,102,111,114,32,97,32,112,97,99,107,97,103, + 101,32,105,110,32,97,32,122,105,112,32,102,105,108,101,46, + 10,10,32,32,32,32,32,32,32,32,73,102,32,39,102,117, + 108,108,110,97,109,101,39,32,105,115,32,97,32,112,97,99, + 107,97,103,101,32,119,105,116,104,105,110,32,116,104,101,32, + 122,105,112,32,102,105,108,101,44,32,114,101,116,117,114,110, + 32,116,104,101,10,32,32,32,32,32,32,32,32,39,82,101, + 115,111,117,114,99,101,82,101,97,100,101,114,39,32,111,98, + 106,101,99,116,32,102,111,114,32,116,104,101,32,112,97,99, + 107,97,103,101,46,32,32,79,116,104,101,114,119,105,115,101, + 32,114,101,116,117,114,110,32,78,111,110,101,46,10,32,32, + 32,32,32,32,32,32,78,114,0,0,0,0,41,1,218,14, + 82,101,115,111,117,114,99,101,82,101,97,100,101,114,84,41, + 7,114,65,0,0,0,114,3,0,0,0,218,24,95,90,105, + 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, + 101,97,100,101,114,218,11,95,114,101,103,105,115,116,101,114, + 101,100,90,13,105,109,112,111,114,116,108,105,98,46,97,98, + 99,114,79,0,0,0,90,8,114,101,103,105,115,116,101,114, + 41,3,114,32,0,0,0,114,38,0,0,0,114,79,0,0, + 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 218,19,103,101,116,95,114,101,115,111,117,114,99,101,95,114, + 101,97,100,101,114,16,1,0,0,115,20,0,0,0,0,6, + 2,1,10,1,10,1,14,1,8,1,6,1,12,1,10,1, + 6,1,122,31,122,105,112,105,109,112,111,114,116,101,114,46, + 103,101,116,95,114,101,115,111,117,114,99,101,95,114,101,97, + 100,101,114,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,5,0,0,0,67,0,0,0,115,24,0,0, + 0,100,1,124,0,106,0,155,0,116,1,155,0,124,0,106, + 2,155,0,100,2,157,5,83,0,41,3,78,122,21,60,122, + 105,112,105,109,112,111,114,116,101,114,32,111,98,106,101,99, + 116,32,34,122,2,34,62,41,3,114,29,0,0,0,114,20, + 0,0,0,114,31,0,0,0,41,1,114,32,0,0,0,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,8, + 95,95,114,101,112,114,95,95,34,1,0,0,115,2,0,0, + 0,0,1,122,20,122,105,112,105,109,112,111,114,116,101,114, + 46,95,95,114,101,112,114,95,95,41,1,78,41,1,78,41, + 15,114,6,0,0,0,114,7,0,0,0,114,8,0,0,0, + 218,7,95,95,100,111,99,95,95,114,34,0,0,0,114,41, + 0,0,0,114,42,0,0,0,114,48,0,0,0,114,55,0, + 0,0,114,56,0,0,0,114,64,0,0,0,114,65,0,0, + 0,114,78,0,0,0,114,82,0,0,0,114,83,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,4,0,0,0,45,0,0,0,115,24,0, + 0,0,8,1,4,17,8,46,10,32,10,12,8,10,8,21, + 8,11,8,26,8,13,8,38,8,18,122,12,95,95,105,110, + 105,116,95,95,46,112,121,99,84,114,60,0,0,0,70,41, + 3,122,4,46,112,121,99,84,70,41,3,114,61,0,0,0, + 70,70,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,67,0,0,0,115,20,0,0,0, + 124,0,106,0,124,1,160,1,100,1,161,1,100,2,25,0, + 23,0,83,0,41,3,78,218,1,46,233,2,0,0,0,41, + 2,114,31,0,0,0,218,10,114,112,97,114,116,105,116,105, + 111,110,41,2,114,32,0,0,0,114,38,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,114,36,0, + 0,0,52,1,0,0,115,2,0,0,0,0,1,114,36,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,2,0,0,0,67,0,0,0,115,18,0,0,0, + 124,1,116,0,23,0,125,2,124,2,124,0,106,1,107,6, + 83,0,169,1,78,41,2,114,20,0,0,0,114,28,0,0, + 0,41,3,114,32,0,0,0,114,13,0,0,0,90,7,100, + 105,114,112,97,116,104,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,114,37,0,0,0,56,1,0,0,115,4, + 0,0,0,0,4,8,2,114,37,0,0,0,99,2,0,0, + 0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0, + 0,67,0,0,0,115,56,0,0,0,116,0,124,0,124,1, + 131,2,125,2,116,1,68,0,93,36,92,3,125,3,125,4, + 125,5,124,2,124,3,23,0,125,6,124,6,124,0,106,2, + 107,6,114,14,124,5,2,0,1,0,83,0,113,14,100,0, + 83,0,114,88,0,0,0,41,3,114,36,0,0,0,218,16, + 95,122,105,112,95,115,101,97,114,99,104,111,114,100,101,114, + 114,28,0,0,0,41,7,114,32,0,0,0,114,38,0,0, + 0,114,13,0,0,0,218,6,115,117,102,102,105,120,218,10, + 105,115,98,121,116,101,99,111,100,101,114,47,0,0,0,114, + 63,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,114,35,0,0,0,65,1,0,0,115,12,0,0, + 0,0,1,10,1,14,1,8,1,10,1,10,1,114,35,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,26, + 0,0,0,9,0,0,0,67,0,0,0,115,252,4,0,0, + 122,14,116,0,160,1,124,0,161,1,125,1,87,0,110,38, + 4,0,116,2,107,10,114,52,1,0,1,0,1,0,116,3, + 100,1,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 89,0,110,2,88,0,124,1,144,4,143,168,1,0,122,36, + 124,1,160,4,116,5,11,0,100,3,161,2,1,0,124,1, + 160,6,161,0,125,2,124,1,160,7,116,5,161,1,125,3, + 87,0,110,38,4,0,116,2,107,10,114,136,1,0,1,0, + 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, + 141,2,130,1,89,0,110,2,88,0,116,8,124,3,131,1, + 116,5,107,3,114,168,116,3,100,4,124,0,155,2,157,2, + 124,0,100,2,141,2,130,1,124,3,100,0,100,5,133,2, + 25,0,116,9,107,3,144,1,114,178,122,24,124,1,160,4, + 100,6,100,3,161,2,1,0,124,1,160,6,161,0,125,4, + 87,0,110,38,4,0,116,2,107,10,114,248,1,0,1,0, + 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, + 141,2,130,1,89,0,110,2,88,0,116,10,124,4,116,11, + 24,0,116,5,24,0,100,6,131,2,125,5,122,22,124,1, + 160,4,124,5,161,1,1,0,124,1,160,7,161,0,125,6, + 87,0,110,40,4,0,116,2,107,10,144,1,114,74,1,0, + 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0, + 100,2,141,2,130,1,89,0,110,2,88,0,124,6,160,12, + 116,9,161,1,125,7,124,7,100,6,107,0,144,1,114,114, + 116,3,100,7,124,0,155,2,157,2,124,0,100,2,141,2, + 130,1,124,6,124,7,124,7,116,5,23,0,133,2,25,0, + 125,3,116,8,124,3,131,1,116,5,107,3,144,1,114,162, + 116,3,100,8,124,0,155,2,157,2,124,0,100,2,141,2, + 130,1,124,4,116,8,124,6,131,1,24,0,124,7,23,0, + 125,2,116,13,124,3,100,9,100,10,133,2,25,0,131,1, + 125,8,116,13,124,3,100,10,100,11,133,2,25,0,131,1, + 125,9,124,2,124,8,107,0,144,1,114,238,116,3,100,12, + 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,2, + 124,9,107,0,144,2,114,10,116,3,100,13,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,124,2,124,8,56,0, + 125,2,124,2,124,9,24,0,125,10,124,10,100,6,107,0, + 144,2,114,54,116,3,100,14,124,0,155,2,157,2,124,0, + 100,2,141,2,130,1,105,0,125,11,100,6,125,12,122,14, + 124,1,160,4,124,2,161,1,1,0,87,0,110,40,4,0, + 116,2,107,10,144,2,114,116,1,0,1,0,1,0,116,3, + 100,4,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 89,0,110,2,88,0,124,1,160,7,100,15,161,1,125,3, + 116,8,124,3,131,1,100,5,107,0,144,2,114,150,116,14, + 100,16,131,1,130,1,124,3,100,0,100,5,133,2,25,0, + 100,17,107,3,144,2,114,172,144,4,113,224,116,8,124,3, + 131,1,100,15,107,3,144,2,114,194,116,14,100,16,131,1, + 130,1,116,15,124,3,100,18,100,19,133,2,25,0,131,1, + 125,13,116,15,124,3,100,19,100,9,133,2,25,0,131,1, + 125,14,116,15,124,3,100,9,100,20,133,2,25,0,131,1, + 125,15,116,15,124,3,100,20,100,10,133,2,25,0,131,1, + 125,16,116,13,124,3,100,10,100,11,133,2,25,0,131,1, + 125,17,116,13,124,3,100,11,100,21,133,2,25,0,131,1, + 125,18,116,13,124,3,100,21,100,22,133,2,25,0,131,1, + 125,4,116,15,124,3,100,22,100,23,133,2,25,0,131,1, + 125,19,116,15,124,3,100,23,100,24,133,2,25,0,131,1, + 125,20,116,15,124,3,100,24,100,25,133,2,25,0,131,1, + 125,21,116,13,124,3,100,26,100,15,133,2,25,0,131,1, + 125,22,124,19,124,20,23,0,124,21,23,0,125,8,124,22, + 124,9,107,4,144,3,114,154,116,3,100,27,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,124,22,124,10,55,0, + 125,22,122,14,124,1,160,7,124,19,161,1,125,23,87,0, + 110,40,4,0,116,2,107,10,144,3,114,216,1,0,1,0, + 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, + 141,2,130,1,89,0,110,2,88,0,116,8,124,23,131,1, + 124,19,107,3,144,3,114,250,116,3,100,4,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,122,50,116,8,124,1, + 160,7,124,8,124,19,24,0,161,1,131,1,124,8,124,19, + 24,0,107,3,144,4,114,42,116,3,100,4,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,87,0,110,40,4,0, + 116,2,107,10,144,4,114,84,1,0,1,0,1,0,116,3, + 100,4,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 89,0,110,2,88,0,124,13,100,28,64,0,144,4,114,106, + 124,23,160,16,161,0,125,23,110,54,122,14,124,23,160,16, + 100,29,161,1,125,23,87,0,110,38,4,0,116,17,107,10, + 144,4,114,158,1,0,1,0,1,0,124,23,160,16,100,30, + 161,1,160,18,116,19,161,1,125,23,89,0,110,2,88,0, + 124,23,160,20,100,31,116,21,161,2,125,23,116,22,160,23, + 124,0,124,23,161,2,125,24,124,24,124,14,124,18,124,4, + 124,22,124,15,124,16,124,17,102,8,125,25,124,25,124,11, + 124,23,60,0,124,12,100,32,55,0,125,12,144,2,113,118, + 87,0,53,0,81,0,82,0,88,0,116,24,160,25,100,33, + 124,12,124,0,161,3,1,0,124,11,83,0,41,34,78,122, + 21,99,97,110,39,116,32,111,112,101,110,32,90,105,112,32, + 102,105,108,101,58,32,114,12,0,0,0,114,86,0,0,0, + 250,21,99,97,110,39,116,32,114,101,97,100,32,90,105,112, + 32,102,105,108,101,58,32,233,4,0,0,0,114,0,0,0, + 0,122,16,110,111,116,32,97,32,90,105,112,32,102,105,108, + 101,58,32,122,18,99,111,114,114,117,112,116,32,90,105,112, + 32,102,105,108,101,58,32,233,12,0,0,0,233,16,0,0, + 0,233,20,0,0,0,122,28,98,97,100,32,99,101,110,116, + 114,97,108,32,100,105,114,101,99,116,111,114,121,32,115,105, + 122,101,58,32,122,30,98,97,100,32,99,101,110,116,114,97, + 108,32,100,105,114,101,99,116,111,114,121,32,111,102,102,115, + 101,116,58,32,122,38,98,97,100,32,99,101,110,116,114,97, + 108,32,100,105,114,101,99,116,111,114,121,32,115,105,122,101, + 32,111,114,32,111,102,102,115,101,116,58,32,233,46,0,0, + 0,250,27,69,79,70,32,114,101,97,100,32,119,104,101,114, + 101,32,110,111,116,32,101,120,112,101,99,116,101,100,115,4, + 0,0,0,80,75,1,2,233,8,0,0,0,233,10,0,0, + 0,233,14,0,0,0,233,24,0,0,0,233,28,0,0,0, + 233,30,0,0,0,233,32,0,0,0,233,34,0,0,0,233, + 42,0,0,0,122,25,98,97,100,32,108,111,99,97,108,32, + 104,101,97,100,101,114,32,111,102,102,115,101,116,58,32,105, + 0,8,0,0,218,5,97,115,99,105,105,90,6,108,97,116, + 105,110,49,250,1,47,114,5,0,0,0,122,33,122,105,112, + 105,109,112,111,114,116,58,32,102,111,117,110,100,32,123,125, + 32,110,97,109,101,115,32,105,110,32,123,33,114,125,41,26, + 218,3,95,105,111,218,9,111,112,101,110,95,99,111,100,101, + 114,22,0,0,0,114,3,0,0,0,218,4,115,101,101,107, + 218,20,69,78,68,95,67,69,78,84,82,65,76,95,68,73, + 82,95,83,73,90,69,90,4,116,101,108,108,218,4,114,101, + 97,100,114,51,0,0,0,218,18,83,84,82,73,78,71,95, + 69,78,68,95,65,82,67,72,73,86,69,218,3,109,97,120, + 218,15,77,65,88,95,67,79,77,77,69,78,84,95,76,69, + 78,218,5,114,102,105,110,100,114,2,0,0,0,218,8,69, + 79,70,69,114,114,111,114,114,1,0,0,0,114,62,0,0, + 0,218,18,85,110,105,99,111,100,101,68,101,99,111,100,101, + 69,114,114,111,114,218,9,116,114,97,110,115,108,97,116,101, + 218,11,99,112,52,51,55,95,116,97,98,108,101,114,19,0, + 0,0,114,20,0,0,0,114,21,0,0,0,114,30,0,0, + 0,114,76,0,0,0,114,77,0,0,0,41,26,114,29,0, + 0,0,218,2,102,112,90,15,104,101,97,100,101,114,95,112, + 111,115,105,116,105,111,110,218,6,98,117,102,102,101,114,218, + 9,102,105,108,101,95,115,105,122,101,90,17,109,97,120,95, + 99,111,109,109,101,110,116,95,115,116,97,114,116,218,4,100, + 97,116,97,90,3,112,111,115,218,11,104,101,97,100,101,114, + 95,115,105,122,101,90,13,104,101,97,100,101,114,95,111,102, + 102,115,101,116,90,10,97,114,99,95,111,102,102,115,101,116, + 114,33,0,0,0,218,5,99,111,117,110,116,218,5,102,108, + 97,103,115,218,8,99,111,109,112,114,101,115,115,218,4,116, + 105,109,101,218,4,100,97,116,101,218,3,99,114,99,218,9, + 100,97,116,97,95,115,105,122,101,218,9,110,97,109,101,95, + 115,105,122,101,218,10,101,120,116,114,97,95,115,105,122,101, + 90,12,99,111,109,109,101,110,116,95,115,105,122,101,218,11, + 102,105,108,101,95,111,102,102,115,101,116,114,59,0,0,0, + 114,13,0,0,0,218,1,116,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,114,27,0,0,0,96,1,0,0, + 115,212,0,0,0,0,1,2,1,14,1,14,1,24,2,8, + 1,2,1,14,1,8,1,14,1,14,1,24,1,12,1,18, + 1,18,3,2,1,12,1,12,1,14,1,10,1,2,255,12, + 2,8,1,2,255,2,1,2,255,4,2,2,1,10,1,12, + 1,16,1,10,1,2,255,12,2,10,1,10,1,10,1,2, + 255,6,2,16,1,14,1,10,1,2,255,6,2,16,2,16, + 1,16,1,10,1,18,1,10,1,18,1,8,1,8,1,10, + 1,18,2,4,2,4,1,2,1,14,1,16,1,24,2,10, + 1,14,1,8,2,18,1,4,1,14,1,8,1,16,1,16, + 1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16, + 1,16,1,12,1,10,1,18,1,8,2,2,1,14,1,16, + 1,24,1,14,1,18,4,2,1,28,1,22,1,16,1,24, + 2,10,2,10,3,2,1,14,1,16,1,22,2,12,1,12, + 1,20,1,8,1,22,1,14,1,114,27,0,0,0,117,190, + 1,0,0,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,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,79,80,81,82,83,84,85,86,87,88,89,90,91,92, + 93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, + 109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124, + 125,126,127,195,135,195,188,195,169,195,162,195,164,195,160,195, + 165,195,167,195,170,195,171,195,168,195,175,195,174,195,172,195, + 132,195,133,195,137,195,166,195,134,195,180,195,182,195,178,195, + 187,195,185,195,191,195,150,195,156,194,162,194,163,194,165,226, + 130,167,198,146,195,161,195,173,195,179,195,186,195,177,195,145, + 194,170,194,186,194,191,226,140,144,194,172,194,189,194,188,194, + 161,194,171,194,187,226,150,145,226,150,146,226,150,147,226,148, + 130,226,148,164,226,149,161,226,149,162,226,149,150,226,149,149, + 226,149,163,226,149,145,226,149,151,226,149,157,226,149,156,226, + 149,155,226,148,144,226,148,148,226,148,180,226,148,172,226,148, + 156,226,148,128,226,148,188,226,149,158,226,149,159,226,149,154, + 226,149,148,226,149,169,226,149,166,226,149,160,226,149,144,226, + 149,172,226,149,167,226,149,168,226,149,164,226,149,165,226,149, + 153,226,149,152,226,149,146,226,149,147,226,149,171,226,149,170, + 226,148,152,226,148,140,226,150,136,226,150,132,226,150,140,226, + 150,144,226,150,128,206,177,195,159,206,147,207,128,206,163,207, + 131,194,181,207,132,206,166,206,152,206,169,206,180,226,136,158, + 207,134,206,181,226,136,169,226,137,161,194,177,226,137,165,226, + 137,164,226,140,160,226,140,161,195,183,226,137,136,194,176,226, + 136,153,194,183,226,136,154,226,129,191,194,178,226,150,160,194, + 160,99,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,8,0,0,0,67,0,0,0,115,108,0,0,0,116, + 0,114,22,116,1,160,2,100,1,161,1,1,0,116,3,100, + 2,131,1,130,1,100,3,97,0,122,60,122,16,100,5,100, + 6,108,4,109,5,125,0,1,0,87,0,110,38,4,0,116, + 6,107,10,114,82,1,0,1,0,1,0,116,1,160,2,100, + 1,161,1,1,0,116,3,100,2,131,1,130,1,89,0,110, + 2,88,0,87,0,53,0,100,4,97,0,88,0,116,1,160, + 2,100,7,161,1,1,0,124,0,83,0,41,8,78,122,27, + 122,105,112,105,109,112,111,114,116,58,32,122,108,105,98,32, + 85,78,65,86,65,73,76,65,66,76,69,250,41,99,97,110, + 39,116,32,100,101,99,111,109,112,114,101,115,115,32,100,97, + 116,97,59,32,122,108,105,98,32,110,111,116,32,97,118,97, + 105,108,97,98,108,101,84,70,114,0,0,0,0,169,1,218, + 10,100,101,99,111,109,112,114,101,115,115,122,25,122,105,112, + 105,109,112,111,114,116,58,32,122,108,105,98,32,97,118,97, + 105,108,97,98,108,101,41,7,218,15,95,105,109,112,111,114, + 116,105,110,103,95,122,108,105,98,114,76,0,0,0,114,77, + 0,0,0,114,3,0,0,0,90,4,122,108,105,98,114,141, + 0,0,0,218,9,69,120,99,101,112,116,105,111,110,114,140, + 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, + 0,0,218,20,95,103,101,116,95,100,101,99,111,109,112,114, + 101,115,115,95,102,117,110,99,254,1,0,0,115,24,0,0, + 0,0,2,4,3,10,1,8,2,4,1,4,1,16,1,14, + 1,10,1,18,2,6,2,10,1,114,144,0,0,0,99,2, + 0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,9, + 0,0,0,67,0,0,0,115,128,1,0,0,124,1,92,8, + 125,2,125,3,125,4,125,5,125,6,125,7,125,8,125,9, + 124,4,100,1,107,0,114,36,116,0,100,2,131,1,130,1, + 116,1,160,2,124,0,161,1,144,1,143,8,125,10,122,14, + 124,10,160,3,124,6,161,1,1,0,87,0,110,38,4,0, + 116,4,107,10,114,102,1,0,1,0,1,0,116,0,100,3, + 124,0,155,2,157,2,124,0,100,4,141,2,130,1,89,0, + 110,2,88,0,124,10,160,5,100,5,161,1,125,11,116,6, + 124,11,131,1,100,5,107,3,114,134,116,7,100,6,131,1, + 130,1,124,11,100,0,100,7,133,2,25,0,100,8,107,3, + 114,168,116,0,100,9,124,0,155,2,157,2,124,0,100,4, + 141,2,130,1,116,8,124,11,100,10,100,11,133,2,25,0, + 131,1,125,12,116,8,124,11,100,11,100,5,133,2,25,0, + 131,1,125,13,100,5,124,12,23,0,124,13,23,0,125,14, + 124,6,124,14,55,0,125,6,122,14,124,10,160,3,124,6, + 161,1,1,0,87,0,110,40,4,0,116,4,107,10,144,1, + 114,18,1,0,1,0,1,0,116,0,100,3,124,0,155,2, + 157,2,124,0,100,4,141,2,130,1,89,0,110,2,88,0, + 124,10,160,5,124,4,161,1,125,15,116,6,124,15,131,1, + 124,4,107,3,144,1,114,52,116,4,100,12,131,1,130,1, + 87,0,53,0,81,0,82,0,88,0,124,3,100,1,107,2, + 144,1,114,76,124,15,83,0,122,10,116,9,131,0,125,16, + 87,0,110,30,4,0,116,10,107,10,144,1,114,116,1,0, + 1,0,1,0,116,0,100,13,131,1,130,1,89,0,110,2, + 88,0,124,16,124,15,100,14,131,2,83,0,41,15,78,114, + 0,0,0,0,122,18,110,101,103,97,116,105,118,101,32,100, + 97,116,97,32,115,105,122,101,114,92,0,0,0,114,12,0, + 0,0,114,104,0,0,0,114,98,0,0,0,114,93,0,0, + 0,115,4,0,0,0,80,75,3,4,122,23,98,97,100,32, + 108,111,99,97,108,32,102,105,108,101,32,104,101,97,100,101, + 114,58,32,233,26,0,0,0,114,103,0,0,0,122,26,122, + 105,112,105,109,112,111,114,116,58,32,99,97,110,39,116,32, + 114,101,97,100,32,100,97,116,97,114,139,0,0,0,105,241, + 255,255,255,41,11,114,3,0,0,0,114,110,0,0,0,114, + 111,0,0,0,114,112,0,0,0,114,22,0,0,0,114,114, + 0,0,0,114,51,0,0,0,114,119,0,0,0,114,1,0, + 0,0,114,144,0,0,0,114,143,0,0,0,41,17,114,29, + 0,0,0,114,54,0,0,0,90,8,100,97,116,97,112,97, + 116,104,114,130,0,0,0,114,134,0,0,0,114,125,0,0, + 0,114,137,0,0,0,114,131,0,0,0,114,132,0,0,0, + 114,133,0,0,0,114,123,0,0,0,114,124,0,0,0,114, + 135,0,0,0,114,136,0,0,0,114,127,0,0,0,90,8, + 114,97,119,95,100,97,116,97,114,141,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,52,0,0, + 0,19,2,0,0,115,62,0,0,0,0,1,20,1,8,1, + 8,2,14,2,2,1,14,1,14,1,24,1,10,1,12,1, + 8,2,16,2,18,2,16,1,16,1,12,1,8,1,2,1, + 14,1,16,1,24,1,10,1,14,1,18,2,10,2,4,3, + 2,1,10,1,16,1,14,1,114,52,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,67,0,0,0,115,16,0,0,0,116,0,124,0,124, + 1,24,0,131,1,100,1,107,1,83,0,41,2,78,114,5, + 0,0,0,41,1,218,3,97,98,115,41,2,90,2,116,49, + 90,2,116,50,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,9,95,101,113,95,109,116,105,109,101,65,2, + 0,0,115,2,0,0,0,0,2,114,147,0,0,0,99,5, + 0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,8, + 0,0,0,67,0,0,0,115,60,1,0,0,124,3,124,2, + 100,1,156,2,125,5,122,18,116,0,160,1,124,4,124,3, + 124,5,161,3,125,6,87,0,110,22,4,0,116,2,107,10, + 114,50,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 124,6,100,2,64,0,100,3,107,3,125,7,124,7,114,182, + 124,6,100,4,64,0,100,3,107,3,125,8,116,3,106,4, + 100,5,107,3,114,180,124,8,115,104,116,3,106,4,100,6, + 107,2,114,180,116,5,124,0,124,2,131,2,125,9,124,9, + 100,0,107,9,114,180,116,3,160,6,116,0,106,7,124,9, + 161,2,125,10,122,20,116,0,160,8,124,4,124,10,124,3, + 124,5,161,4,1,0,87,0,110,22,4,0,116,2,107,10, + 114,178,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 110,84,116,9,124,0,124,2,131,2,92,2,125,11,125,12, + 124,11,144,1,114,10,116,10,116,11,124,4,100,7,100,8, + 133,2,25,0,131,1,124,11,131,2,114,246,116,11,124,4, + 100,8,100,9,133,2,25,0,131,1,124,12,107,3,144,1, + 114,10,116,12,160,13,100,10,124,3,155,2,157,2,161,1, + 1,0,100,0,83,0,116,14,160,15,124,4,100,9,100,0, + 133,2,25,0,161,1,125,13,116,16,124,13,116,17,131,2, + 144,1,115,56,116,18,100,11,124,1,155,2,100,12,157,3, + 131,1,130,1,124,13,83,0,41,13,78,41,2,114,59,0, + 0,0,114,13,0,0,0,114,5,0,0,0,114,0,0,0, + 0,114,86,0,0,0,90,5,110,101,118,101,114,90,6,97, + 108,119,97,121,115,114,99,0,0,0,114,94,0,0,0,114, + 95,0,0,0,122,22,98,121,116,101,99,111,100,101,32,105, + 115,32,115,116,97,108,101,32,102,111,114,32,122,16,99,111, + 109,112,105,108,101,100,32,109,111,100,117,108,101,32,122,21, + 32,105,115,32,110,111,116,32,97,32,99,111,100,101,32,111, + 98,106,101,99,116,41,19,114,21,0,0,0,90,13,95,99, + 108,97,115,115,105,102,121,95,112,121,99,114,75,0,0,0, + 218,4,95,105,109,112,90,21,99,104,101,99,107,95,104,97, + 115,104,95,98,97,115,101,100,95,112,121,99,115,218,15,95, + 103,101,116,95,112,121,99,95,115,111,117,114,99,101,218,11, + 115,111,117,114,99,101,95,104,97,115,104,90,17,95,82,65, + 87,95,77,65,71,73,67,95,78,85,77,66,69,82,90,18, + 95,118,97,108,105,100,97,116,101,95,104,97,115,104,95,112, + 121,99,218,29,95,103,101,116,95,109,116,105,109,101,95,97, + 110,100,95,115,105,122,101,95,111,102,95,115,111,117,114,99, + 101,114,147,0,0,0,114,2,0,0,0,114,76,0,0,0, + 114,77,0,0,0,218,7,109,97,114,115,104,97,108,90,5, + 108,111,97,100,115,114,15,0,0,0,218,10,95,99,111,100, + 101,95,116,121,112,101,218,9,84,121,112,101,69,114,114,111, + 114,41,14,114,32,0,0,0,114,53,0,0,0,114,63,0, + 0,0,114,38,0,0,0,114,126,0,0,0,90,11,101,120, + 99,95,100,101,116,97,105,108,115,114,129,0,0,0,90,10, + 104,97,115,104,95,98,97,115,101,100,90,12,99,104,101,99, + 107,95,115,111,117,114,99,101,90,12,115,111,117,114,99,101, + 95,98,121,116,101,115,114,150,0,0,0,90,12,115,111,117, + 114,99,101,95,109,116,105,109,101,90,11,115,111,117,114,99, + 101,95,115,105,122,101,114,46,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,218,15,95,117,110,109, + 97,114,115,104,97,108,95,99,111,100,101,75,2,0,0,115, + 88,0,0,0,0,2,2,1,2,254,6,5,2,1,18,1, + 14,1,8,2,12,1,4,1,12,1,10,1,2,255,2,1, + 8,255,2,2,10,1,8,1,4,1,4,1,2,254,4,5, + 2,1,4,1,2,0,2,0,2,0,2,255,8,2,14,1, + 10,3,8,255,6,3,6,3,22,1,18,255,4,2,4,1, + 8,255,4,2,4,2,18,1,12,1,16,1,114,155,0,0, + 0,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,4,0,0,0,67,0,0,0,115,28,0,0,0,124, + 0,160,0,100,1,100,2,161,2,125,0,124,0,160,0,100, + 3,100,2,161,2,125,0,124,0,83,0,41,4,78,115,2, + 0,0,0,13,10,243,1,0,0,0,10,243,1,0,0,0, + 13,41,1,114,19,0,0,0,41,1,218,6,115,111,117,114, + 99,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0, + 0,218,23,95,110,111,114,109,97,108,105,122,101,95,108,105, + 110,101,95,101,110,100,105,110,103,115,126,2,0,0,115,6, + 0,0,0,0,1,12,1,12,1,114,159,0,0,0,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,6, + 0,0,0,67,0,0,0,115,24,0,0,0,116,0,124,1, + 131,1,125,1,116,1,124,1,124,0,100,1,100,2,100,3, + 141,4,83,0,41,4,78,114,74,0,0,0,84,41,1,90, + 12,100,111,110,116,95,105,110,104,101,114,105,116,41,2,114, + 159,0,0,0,218,7,99,111,109,112,105,108,101,41,2,114, + 53,0,0,0,114,158,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,15,95,99,111,109,112,105, + 108,101,95,115,111,117,114,99,101,133,2,0,0,115,4,0, + 0,0,0,1,8,1,114,161,0,0,0,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,11,0,0,0, + 67,0,0,0,115,68,0,0,0,116,0,160,1,124,0,100, + 1,63,0,100,2,23,0,124,0,100,3,63,0,100,4,64, + 0,124,0,100,5,64,0,124,1,100,6,63,0,124,1,100, + 3,63,0,100,7,64,0,124,1,100,5,64,0,100,8,20, + 0,100,9,100,9,100,9,102,9,161,1,83,0,41,10,78, + 233,9,0,0,0,105,188,7,0,0,233,5,0,0,0,233, + 15,0,0,0,233,31,0,0,0,233,11,0,0,0,233,63, + 0,0,0,114,86,0,0,0,114,14,0,0,0,41,2,114, + 131,0,0,0,90,6,109,107,116,105,109,101,41,2,218,1, + 100,114,138,0,0,0,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,14,95,112,97,114,115,101,95,100,111, + 115,116,105,109,101,139,2,0,0,115,22,0,0,0,0,1, + 4,1,10,1,10,1,6,1,6,1,10,1,10,1,2,0, + 2,0,2,249,114,169,0,0,0,99,2,0,0,0,0,0, + 0,0,0,0,0,0,6,0,0,0,10,0,0,0,67,0, + 0,0,115,116,0,0,0,122,82,124,1,100,1,100,0,133, + 2,25,0,100,2,107,6,115,22,116,0,130,1,124,1,100, + 0,100,1,133,2,25,0,125,1,124,0,106,1,124,1,25, + 0,125,2,124,2,100,3,25,0,125,3,124,2,100,4,25, + 0,125,4,124,2,100,5,25,0,125,5,116,2,124,4,124, + 3,131,2,124,5,102,2,87,0,83,0,4,0,116,3,116, + 4,116,5,102,3,107,10,114,110,1,0,1,0,1,0,89, + 0,100,6,83,0,88,0,100,0,83,0,41,7,78,114,14, + 0,0,0,169,2,218,1,99,218,1,111,114,163,0,0,0, + 233,6,0,0,0,233,3,0,0,0,41,2,114,0,0,0, + 0,114,0,0,0,0,41,6,218,14,65,115,115,101,114,116, + 105,111,110,69,114,114,111,114,114,28,0,0,0,114,169,0, + 0,0,114,26,0,0,0,218,10,73,110,100,101,120,69,114, + 114,111,114,114,154,0,0,0,41,6,114,32,0,0,0,114, + 13,0,0,0,114,54,0,0,0,114,131,0,0,0,114,132, + 0,0,0,90,17,117,110,99,111,109,112,114,101,115,115,101, + 100,95,115,105,122,101,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,114,151,0,0,0,152,2,0,0,115,20, + 0,0,0,0,1,2,2,20,1,12,1,10,3,8,1,8, + 1,8,1,16,1,20,1,114,151,0,0,0,99,2,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,8,0,0, + 0,67,0,0,0,115,86,0,0,0,124,1,100,1,100,0, + 133,2,25,0,100,2,107,6,115,20,116,0,130,1,124,1, + 100,0,100,1,133,2,25,0,125,1,122,14,124,0,106,1, + 124,1,25,0,125,2,87,0,110,22,4,0,116,2,107,10, + 114,68,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 116,3,124,0,106,4,124,2,131,2,83,0,100,0,83,0, + 41,3,78,114,14,0,0,0,114,170,0,0,0,41,5,114, + 175,0,0,0,114,28,0,0,0,114,26,0,0,0,114,52, + 0,0,0,114,29,0,0,0,41,3,114,32,0,0,0,114, + 13,0,0,0,114,54,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,114,149,0,0,0,171,2,0, + 0,115,14,0,0,0,0,2,20,1,12,2,2,1,14,1, + 14,1,8,2,114,149,0,0,0,99,2,0,0,0,0,0, + 0,0,0,0,0,0,11,0,0,0,9,0,0,0,67,0, + 0,0,115,198,0,0,0,116,0,124,0,124,1,131,2,125, + 2,116,1,68,0,93,160,92,3,125,3,125,4,125,5,124, + 2,124,3,23,0,125,6,116,2,106,3,100,1,124,0,106, + 4,116,5,124,6,100,2,100,3,141,5,1,0,122,14,124, + 0,106,6,124,6,25,0,125,7,87,0,110,20,4,0,116, + 7,107,10,114,88,1,0,1,0,1,0,89,0,113,14,88, + 0,124,7,100,4,25,0,125,8,116,8,124,0,106,4,124, + 7,131,2,125,9,124,4,114,132,116,9,124,0,124,8,124, + 6,124,1,124,9,131,5,125,10,110,10,116,10,124,8,124, + 9,131,2,125,10,124,10,100,0,107,8,114,152,113,14,124, + 7,100,4,25,0,125,8,124,10,124,5,124,8,102,3,2, + 0,1,0,83,0,113,14,116,11,100,5,124,1,155,2,157, + 2,124,1,100,6,141,2,130,1,100,0,83,0,41,7,78, + 122,13,116,114,121,105,110,103,32,123,125,123,125,123,125,114, + 86,0,0,0,41,1,90,9,118,101,114,98,111,115,105,116, + 121,114,0,0,0,0,114,57,0,0,0,114,58,0,0,0, + 41,12,114,36,0,0,0,114,89,0,0,0,114,76,0,0, + 0,114,77,0,0,0,114,29,0,0,0,114,20,0,0,0, + 114,28,0,0,0,114,26,0,0,0,114,52,0,0,0,114, + 155,0,0,0,114,161,0,0,0,114,3,0,0,0,41,11, + 114,32,0,0,0,114,38,0,0,0,114,13,0,0,0,114, + 90,0,0,0,114,91,0,0,0,114,47,0,0,0,114,63, + 0,0,0,114,54,0,0,0,114,40,0,0,0,114,126,0, + 0,0,114,46,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,114,44,0,0,0,186,2,0,0,115, + 36,0,0,0,0,1,10,1,14,1,8,1,22,1,2,1, + 14,1,14,1,6,2,8,1,12,1,4,1,18,2,10,1, + 8,3,2,1,8,1,16,2,114,44,0,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,64,0,0,0,115,60,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,90,4,100,3,100,4,132, + 0,90,5,100,5,100,6,132,0,90,6,100,7,100,8,132, + 0,90,7,100,9,100,10,132,0,90,8,100,11,100,12,132, + 0,90,9,100,13,83,0,41,14,114,80,0,0,0,122,165, + 80,114,105,118,97,116,101,32,99,108,97,115,115,32,117,115, + 101,100,32,116,111,32,115,117,112,112,111,114,116,32,90,105, + 112,73,109,112,111,114,116,46,103,101,116,95,114,101,115,111, + 117,114,99,101,95,114,101,97,100,101,114,40,41,46,10,10, + 32,32,32,32,84,104,105,115,32,99,108,97,115,115,32,105, + 115,32,97,108,108,111,119,101,100,32,116,111,32,114,101,102, + 101,114,101,110,99,101,32,97,108,108,32,116,104,101,32,105, + 110,110,97,114,100,115,32,97,110,100,32,112,114,105,118,97, + 116,101,32,112,97,114,116,115,32,111,102,10,32,32,32,32, + 116,104,101,32,122,105,112,105,109,112,111,114,116,101,114,46, + 10,32,32,32,32,70,99,3,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,2,0,0,0,67,0,0,0,115, + 16,0,0,0,124,1,124,0,95,0,124,2,124,0,95,1, + 100,0,83,0,114,88,0,0,0,41,2,114,4,0,0,0, + 114,38,0,0,0,41,3,114,32,0,0,0,114,4,0,0, + 0,114,38,0,0,0,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,114,34,0,0,0,220,2,0,0,115,4, + 0,0,0,0,1,6,1,122,33,95,90,105,112,73,109,112, + 111,114,116,82,101,115,111,117,114,99,101,82,101,97,100,101, + 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,8,0,0,0,67, + 0,0,0,115,92,0,0,0,124,0,106,0,160,1,100,1, + 100,2,161,2,125,2,124,2,155,0,100,2,124,1,155,0, + 157,3,125,3,100,3,100,4,108,2,109,3,125,4,1,0, + 122,18,124,4,124,0,106,4,160,5,124,3,161,1,131,1, + 87,0,83,0,4,0,116,6,107,10,114,86,1,0,1,0, + 1,0,116,7,124,3,131,1,130,1,89,0,110,2,88,0, + 100,0,83,0,41,5,78,114,85,0,0,0,114,109,0,0, + 0,114,0,0,0,0,41,1,218,7,66,121,116,101,115,73, + 79,41,8,114,38,0,0,0,114,19,0,0,0,90,2,105, + 111,114,177,0,0,0,114,4,0,0,0,114,55,0,0,0, + 114,22,0,0,0,218,17,70,105,108,101,78,111,116,70,111, + 117,110,100,69,114,114,111,114,41,5,114,32,0,0,0,218, + 8,114,101,115,111,117,114,99,101,218,16,102,117,108,108,110, + 97,109,101,95,97,115,95,112,97,116,104,114,13,0,0,0, + 114,177,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,218,13,111,112,101,110,95,114,101,115,111,117, + 114,99,101,224,2,0,0,115,14,0,0,0,0,1,14,1, + 14,1,12,1,2,1,18,1,14,1,122,38,95,90,105,112, + 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101, + 97,100,101,114,46,111,112,101,110,95,114,101,115,111,117,114, + 99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,8,0,0,0, + 116,0,130,1,100,0,83,0,114,88,0,0,0,41,1,114, + 178,0,0,0,41,2,114,32,0,0,0,114,179,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, + 13,114,101,115,111,117,114,99,101,95,112,97,116,104,233,2, + 0,0,115,2,0,0,0,0,4,122,38,95,90,105,112,73, + 109,112,111,114,116,82,101,115,111,117,114,99,101,82,101,97, + 100,101,114,46,114,101,115,111,117,114,99,101,95,112,97,116, + 104,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,8,0,0,0,67,0,0,0,115,72,0,0,0,124, + 0,106,0,160,1,100,1,100,2,161,2,125,2,124,2,155, + 0,100,2,124,1,155,0,157,3,125,3,122,16,124,0,106, + 2,160,3,124,3,161,1,1,0,87,0,110,22,4,0,116, + 4,107,10,114,66,1,0,1,0,1,0,89,0,100,3,83, + 0,88,0,100,4,83,0,41,5,78,114,85,0,0,0,114, + 109,0,0,0,70,84,41,5,114,38,0,0,0,114,19,0, + 0,0,114,4,0,0,0,114,55,0,0,0,114,22,0,0, + 0,41,4,114,32,0,0,0,114,59,0,0,0,114,180,0, + 0,0,114,13,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,11,105,115,95,114,101,115,111,117, + 114,99,101,239,2,0,0,115,14,0,0,0,0,3,14,1, + 14,1,2,1,16,1,14,1,8,1,122,36,95,90,105,112, + 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101, + 97,100,101,114,46,105,115,95,114,101,115,111,117,114,99,101, + 99,1,0,0,0,0,0,0,0,0,0,0,0,9,0,0, + 0,9,0,0,0,99,0,0,0,115,186,0,0,0,100,1, + 100,2,108,0,109,1,125,1,1,0,124,1,124,0,106,2, + 160,3,124,0,106,4,161,1,131,1,125,2,124,2,160,5, + 124,0,106,2,106,6,161,1,125,3,124,3,106,7,100,3, + 107,2,115,58,116,8,130,1,124,3,106,9,125,4,116,10, + 131,0,125,5,124,0,106,2,106,11,68,0,93,102,125,6, + 122,18,124,1,124,6,131,1,160,5,124,4,161,1,125,7, + 87,0,110,24,4,0,116,12,107,10,114,124,1,0,1,0, + 1,0,89,0,113,78,89,0,110,2,88,0,124,7,106,9, + 106,7,125,8,116,13,124,8,131,1,100,1,107,2,114,156, + 124,7,106,7,86,0,1,0,113,78,124,8,124,5,107,7, + 114,78,124,5,160,14,124,8,161,1,1,0,124,8,86,0, + 1,0,113,78,100,0,83,0,41,4,78,114,0,0,0,0, + 41,1,218,4,80,97,116,104,114,60,0,0,0,41,15,90, + 7,112,97,116,104,108,105,98,114,184,0,0,0,114,4,0, + 0,0,114,56,0,0,0,114,38,0,0,0,90,11,114,101, + 108,97,116,105,118,101,95,116,111,114,29,0,0,0,114,59, + 0,0,0,114,175,0,0,0,90,6,112,97,114,101,110,116, + 218,3,115,101,116,114,28,0,0,0,114,23,0,0,0,114, + 51,0,0,0,218,3,97,100,100,41,9,114,32,0,0,0, + 114,184,0,0,0,90,13,102,117,108,108,110,97,109,101,95, + 112,97,116,104,90,13,114,101,108,97,116,105,118,101,95,112, + 97,116,104,90,12,112,97,99,107,97,103,101,95,112,97,116, + 104,90,12,115,117,98,100,105,114,115,95,115,101,101,110,218, + 8,102,105,108,101,110,97,109,101,90,8,114,101,108,97,116, + 105,118,101,90,11,112,97,114,101,110,116,95,110,97,109,101, + 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, + 8,99,111,110,116,101,110,116,115,250,2,0,0,115,34,0, + 0,0,0,8,12,1,18,1,14,3,14,1,6,1,6,1, + 12,1,2,1,18,1,14,1,10,5,8,1,12,1,10,1, + 8,1,10,1,122,33,95,90,105,112,73,109,112,111,114,116, + 82,101,115,111,117,114,99,101,82,101,97,100,101,114,46,99, + 111,110,116,101,110,116,115,78,41,10,114,6,0,0,0,114, + 7,0,0,0,114,8,0,0,0,114,84,0,0,0,114,81, + 0,0,0,114,34,0,0,0,114,181,0,0,0,114,182,0, + 0,0,114,183,0,0,0,114,188,0,0,0,114,9,0,0, + 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 114,80,0,0,0,212,2,0,0,115,14,0,0,0,8,1, + 4,5,4,2,8,4,8,9,8,6,8,11,114,80,0,0, + 0,41,45,114,84,0,0,0,90,26,95,102,114,111,122,101, + 110,95,105,109,112,111,114,116,108,105,98,95,101,120,116,101, + 114,110,97,108,114,21,0,0,0,114,1,0,0,0,114,2, + 0,0,0,90,17,95,102,114,111,122,101,110,95,105,109,112, + 111,114,116,108,105,98,114,76,0,0,0,114,148,0,0,0, + 114,110,0,0,0,114,152,0,0,0,114,67,0,0,0,114, + 131,0,0,0,90,7,95,95,97,108,108,95,95,114,20,0, + 0,0,90,15,112,97,116,104,95,115,101,112,97,114,97,116, + 111,114,115,114,18,0,0,0,114,75,0,0,0,114,3,0, + 0,0,114,25,0,0,0,218,4,116,121,112,101,114,70,0, + 0,0,114,113,0,0,0,114,115,0,0,0,114,117,0,0, + 0,114,4,0,0,0,114,89,0,0,0,114,36,0,0,0, + 114,37,0,0,0,114,35,0,0,0,114,27,0,0,0,114, + 122,0,0,0,114,142,0,0,0,114,144,0,0,0,114,52, + 0,0,0,114,147,0,0,0,114,155,0,0,0,218,8,95, + 95,99,111,100,101,95,95,114,153,0,0,0,114,159,0,0, + 0,114,161,0,0,0,114,169,0,0,0,114,151,0,0,0, + 114,149,0,0,0,114,44,0,0,0,114,80,0,0,0,114, + 9,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,8,60,109,111,100,117,108,101,62,1,0,0, + 0,115,88,0,0,0,4,16,8,1,16,1,8,1,8,1, + 8,1,8,1,8,1,8,2,8,3,6,1,14,3,16,4, + 4,2,8,2,4,1,4,1,4,2,14,127,0,127,0,1, + 12,1,12,1,2,1,2,252,4,9,8,4,8,9,8,31, + 8,126,2,254,2,29,4,5,8,21,8,46,8,10,8,46, + 10,5,8,7,8,6,8,13,8,19,8,15,8,26, +}; diff --git a/python/Python/initconfig.c b/python/Python/initconfig.c new file mode 100755 index 0000000..69711d8 --- /dev/null +++ b/python/Python/initconfig.c @@ -0,0 +1,2674 @@ +#include "Python.h" +#include "osdefs.h" /* DELIM */ +#include "pycore_fileutils.h" +#include "pycore_getopt.h" +#include "pycore_initconfig.h" +#include "pycore_pathconfig.h" +#include "pycore_pyerrors.h" +#include "pycore_pylifecycle.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" /* _PyRuntime */ +#include /* setlocale() */ +#ifdef HAVE_LANGINFO_H +# include /* nl_langinfo(CODESET) */ +#endif +#if defined(MS_WINDOWS) || defined(__CYGWIN__) +# include /* GetACP() */ +# ifdef HAVE_IO_H +# include +# endif +# ifdef HAVE_FCNTL_H +# include /* O_BINARY */ +# endif +#endif + + +/* --- Command line options --------------------------------------- */ + +/* Short usage message (with %s for argv0) */ +static const char usage_line[] = +"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n"; + +/* Long usage message, split into parts < 512 bytes */ +static const char usage_1[] = "\ +Options and arguments (and corresponding environment variables):\n\ +-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\ + and comparing bytes/bytearray with str. (-bb: issue errors)\n\ +-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ +-c cmd : program passed in as string (terminates option list)\n\ +-d : debug output from parser; also PYTHONDEBUG=x\n\ +-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ +-h : print this help message and exit (also --help)\n\ +"; +static const char usage_2[] = "\ +-i : inspect interactively after running script; forces a prompt even\n\ + if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ +-I : isolate Python from the user's environment (implies -E and -s)\n\ +-m mod : run library module as a script (terminates option list)\n\ +-O : remove assert and __debug__-dependent statements; add .opt-1 before\n\ + .pyc extension; also PYTHONOPTIMIZE=x\n\ +-OO : do -O changes and also discard docstrings; add .opt-2 before\n\ + .pyc extension\n\ +-q : don't print version and copyright messages on interactive startup\n\ +-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ +-S : don't imply 'import site' on initialization\n\ +"; +static const char usage_3[] = "\ +-u : force the stdout and stderr streams to be unbuffered;\n\ + this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\ +-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\ + can be supplied multiple times to increase verbosity\n\ +-V : print the Python version number and exit (also --version)\n\ + when given twice, print more information about the build\n\ +-W arg : warning control; arg is action:message:category:module:lineno\n\ + also PYTHONWARNINGS=arg\n\ +-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ +-X opt : set implementation-specific option. The following options are available:\n\ +\n\ + -X faulthandler: enable faulthandler\n\ + -X showrefcount: output the total reference count and number of used\n\ + memory blocks when the program finishes or after each statement in the\n\ + interactive interpreter. This only works on debug builds\n\ + -X tracemalloc: start tracing Python memory allocations using the\n\ + tracemalloc module. By default, only the most recent frame is stored in a\n\ + traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ + traceback limit of NFRAME frames\n\ + -X showalloccount: output the total count of allocated objects for each\n\ + type when the program finishes. This only works when Python was built with\n\ + COUNT_ALLOCS defined\n\ + -X importtime: show how long each import takes. It shows module name,\n\ + cumulative time (including nested imports) and self time (excluding\n\ + nested imports). Note that its output may be broken in multi-threaded\n\ + application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ + -X dev: enable CPython's \"development mode\", introducing additional runtime\n\ + checks which are too expensive to be enabled by default. Effect of the\n\ + developer mode:\n\ + * Add default warning filter, as -W default\n\ + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\ + * Enable the faulthandler module to dump the Python traceback on a crash\n\ + * Enable asyncio debug mode\n\ + * Set the dev_mode attribute of sys.flags to True\n\ + * io.IOBase destructor logs close() exceptions\n\ + -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ + locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ + otherwise activate automatically)\n\ + -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ + given directory instead of to the code tree\n\ +\n\ +--check-hash-based-pycs always|default|never:\n\ + control how Python invalidates hash-based .pyc files\n\ +"; +static const char usage_4[] = "\ +file : program read from script file\n\ +- : program read from stdin (default; interactive mode if a tty)\n\ +arg ...: arguments passed to program in sys.argv[1:]\n\n\ +Other environment variables:\n\ +PYTHONSTARTUP: file executed on interactive startup (no default)\n\ +PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\ + default module search path. The result is sys.path.\n\ +"; +static const char usage_5[] = +"PYTHONHOME : alternate directory (or %lc).\n" +" The default module search path uses %s.\n" +"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n" +"PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n" +"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n" +"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"; +static const char usage_6[] = +"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n" +" to seed the hashes of str and bytes objects. It can also be set to an\n" +" integer in the range [0,4294967295] to get hash values with a\n" +" predictable seed.\n" +"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n" +" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n" +" hooks.\n" +"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n" +" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n" +" locale coercion and locale compatibility warnings on stderr.\n" +"PYTHONBREAKPOINT: if this variable is set to 0, it disables the default\n" +" debugger. It can be set to the callable of your debugger of choice.\n" +"PYTHONDEVMODE: enable the development mode.\n" +"PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.\n"; + +#if defined(MS_WINDOWS) +# define PYTHONHOMEHELP "\\python{major}{minor}" +#else +# define PYTHONHOMEHELP "/lib/pythonX.X" +#endif + + +/* --- Global configuration variables ----------------------------- */ + +/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change + stdin and stdout error handler to "surrogateescape". */ +int Py_UTF8Mode = 0; +int Py_DebugFlag = 0; /* Needed by parser.c */ +int Py_VerboseFlag = 0; /* Needed by import.c */ +int Py_QuietFlag = 0; /* Needed by sysmodule.c */ +int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */ +int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */ +int Py_OptimizeFlag = 0; /* Needed by compile.c */ +int Py_NoSiteFlag = 0; /* Suppress 'import site' */ +int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */ +int Py_FrozenFlag = 0; /* Needed by getpath.c */ +int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */ +int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */ +int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ +int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ +int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ +int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ +#ifdef MS_WINDOWS +int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */ +int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */ +#endif + + +static PyObject * +_Py_GetGlobalVariablesAsDict(void) +{ + PyObject *dict, *obj; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define SET_ITEM(KEY, EXPR) \ + do { \ + obj = (EXPR); \ + if (obj == NULL) { \ + return NULL; \ + } \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) +#define SET_ITEM_INT(VAR) \ + SET_ITEM(#VAR, PyLong_FromLong(VAR)) +#define FROM_STRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromString(STR) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_STR(VAR) \ + SET_ITEM(#VAR, FROM_STRING(VAR)) + + SET_ITEM_STR(Py_FileSystemDefaultEncoding); + SET_ITEM_INT(Py_HasFileSystemDefaultEncoding); + SET_ITEM_STR(Py_FileSystemDefaultEncodeErrors); + SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors); + + SET_ITEM_INT(Py_UTF8Mode); + SET_ITEM_INT(Py_DebugFlag); + SET_ITEM_INT(Py_VerboseFlag); + SET_ITEM_INT(Py_QuietFlag); + SET_ITEM_INT(Py_InteractiveFlag); + SET_ITEM_INT(Py_InspectFlag); + + SET_ITEM_INT(Py_OptimizeFlag); + SET_ITEM_INT(Py_NoSiteFlag); + SET_ITEM_INT(Py_BytesWarningFlag); + SET_ITEM_INT(Py_FrozenFlag); + SET_ITEM_INT(Py_IgnoreEnvironmentFlag); + SET_ITEM_INT(Py_DontWriteBytecodeFlag); + SET_ITEM_INT(Py_NoUserSiteDirectory); + SET_ITEM_INT(Py_UnbufferedStdioFlag); + SET_ITEM_INT(Py_HashRandomizationFlag); + SET_ITEM_INT(Py_IsolatedFlag); + +#ifdef MS_WINDOWS + SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag); + SET_ITEM_INT(Py_LegacyWindowsStdioFlag); +#endif + + return dict; + +fail: + Py_DECREF(dict); + return NULL; + +#undef FROM_STRING +#undef SET_ITEM +#undef SET_ITEM_INT +#undef SET_ITEM_STR +} + + +/* --- PyStatus ----------------------------------------------- */ + +PyStatus PyStatus_Ok(void) +{ return _PyStatus_OK(); } + +PyStatus PyStatus_Error(const char *err_msg) +{ + return (PyStatus){._type = _PyStatus_TYPE_ERROR, + .err_msg = err_msg}; +} + +PyStatus PyStatus_NoMemory(void) +{ return PyStatus_Error("memory allocation failed"); } + +PyStatus PyStatus_Exit(int exitcode) +{ return _PyStatus_EXIT(exitcode); } + + +int PyStatus_IsError(PyStatus status) +{ return _PyStatus_IS_ERROR(status); } + +int PyStatus_IsExit(PyStatus status) +{ return _PyStatus_IS_EXIT(status); } + +int PyStatus_Exception(PyStatus status) +{ return _PyStatus_EXCEPTION(status); } + + +/* --- PyWideStringList ------------------------------------------------ */ + +#ifndef NDEBUG +int +_PyWideStringList_CheckConsistency(const PyWideStringList *list) +{ + assert(list->length >= 0); + if (list->length != 0) { + assert(list->items != NULL); + } + for (Py_ssize_t i = 0; i < list->length; i++) { + assert(list->items[i] != NULL); + } + return 1; +} +#endif /* Py_DEBUG */ + + +void +_PyWideStringList_Clear(PyWideStringList *list) +{ + assert(_PyWideStringList_CheckConsistency(list)); + for (Py_ssize_t i=0; i < list->length; i++) { + PyMem_RawFree(list->items[i]); + } + PyMem_RawFree(list->items); + list->length = 0; + list->items = NULL; +} + + +int +_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2) +{ + assert(_PyWideStringList_CheckConsistency(list)); + assert(_PyWideStringList_CheckConsistency(list2)); + + if (list2->length == 0) { + _PyWideStringList_Clear(list); + return 0; + } + + PyWideStringList copy = _PyWideStringList_INIT; + + size_t size = list2->length * sizeof(list2->items[0]); + copy.items = PyMem_RawMalloc(size); + if (copy.items == NULL) { + return -1; + } + + for (Py_ssize_t i=0; i < list2->length; i++) { + wchar_t *item = _PyMem_RawWcsdup(list2->items[i]); + if (item == NULL) { + _PyWideStringList_Clear(©); + return -1; + } + copy.items[i] = item; + copy.length = i + 1; + } + + _PyWideStringList_Clear(list); + *list = copy; + return 0; +} + + +PyStatus +PyWideStringList_Insert(PyWideStringList *list, + Py_ssize_t index, const wchar_t *item) +{ + Py_ssize_t len = list->length; + if (len == PY_SSIZE_T_MAX) { + /* length+1 would overflow */ + return _PyStatus_NO_MEMORY(); + } + if (index < 0) { + return _PyStatus_ERR("PyWideStringList_Insert index must be >= 0"); + } + if (index > len) { + index = len; + } + + wchar_t *item2 = _PyMem_RawWcsdup(item); + if (item2 == NULL) { + return _PyStatus_NO_MEMORY(); + } + + size_t size = (len + 1) * sizeof(list->items[0]); + wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size); + if (items2 == NULL) { + PyMem_RawFree(item2); + return _PyStatus_NO_MEMORY(); + } + + if (index < len) { + memmove(&items2[index + 1], + &items2[index], + (len - index) * sizeof(items2[0])); + } + + items2[index] = item2; + list->items = items2; + list->length++; + return _PyStatus_OK(); +} + + +PyStatus +PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) +{ + return PyWideStringList_Insert(list, list->length, item); +} + + +PyStatus +_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2) +{ + for (Py_ssize_t i = 0; i < list2->length; i++) { + PyStatus status = PyWideStringList_Append(list, list2->items[i]); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +static int +_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item) +{ + for (Py_ssize_t i = 0; i < list->length; i++) { + if (wcscmp(list->items[i], item) == 0) { + return 1; + } + } + return 0; +} + + +PyObject* +_PyWideStringList_AsList(const PyWideStringList *list) +{ + assert(_PyWideStringList_CheckConsistency(list)); + + PyObject *pylist = PyList_New(list->length); + if (pylist == NULL) { + return NULL; + } + + for (Py_ssize_t i = 0; i < list->length; i++) { + PyObject *item = PyUnicode_FromWideChar(list->items[i], -1); + if (item == NULL) { + Py_DECREF(pylist); + return NULL; + } + PyList_SET_ITEM(pylist, i, item); + } + return pylist; +} + + +/* --- Py_SetStandardStreamEncoding() ----------------------------- */ + +/* Helper to allow an embedding application to override the normal + * mechanism that attempts to figure out an appropriate IO encoding + */ + +static char *_Py_StandardStreamEncoding = NULL; +static char *_Py_StandardStreamErrors = NULL; + +int +Py_SetStandardStreamEncoding(const char *encoding, const char *errors) +{ + if (Py_IsInitialized()) { + /* This is too late to have any effect */ + return -1; + } + + int res = 0; + + /* Py_SetStandardStreamEncoding() can be called before Py_Initialize(), + but Py_Initialize() can change the allocator. Use a known allocator + to be able to release the memory later. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Can't call PyErr_NoMemory() on errors, as Python hasn't been + * initialised yet. + * + * However, the raw memory allocators are initialised appropriately + * as C static variables, so _PyMem_RawStrdup is OK even though + * Py_Initialize hasn't been called yet. + */ + if (encoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); + _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); + if (!_Py_StandardStreamEncoding) { + res = -2; + goto done; + } + } + if (errors) { + PyMem_RawFree(_Py_StandardStreamErrors); + _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); + if (!_Py_StandardStreamErrors) { + PyMem_RawFree(_Py_StandardStreamEncoding); + _Py_StandardStreamEncoding = NULL; + res = -3; + goto done; + } + } +#ifdef MS_WINDOWS + if (_Py_StandardStreamEncoding) { + /* Overriding the stream encoding implies legacy streams */ + Py_LegacyWindowsStdioFlag = 1; + } +#endif + +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + return res; +} + + +void +_Py_ClearStandardStreamEncoding(void) +{ + /* Use the same allocator than Py_SetStandardStreamEncoding() */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* We won't need them anymore. */ + if (_Py_StandardStreamEncoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); + _Py_StandardStreamEncoding = NULL; + } + if (_Py_StandardStreamErrors) { + PyMem_RawFree(_Py_StandardStreamErrors); + _Py_StandardStreamErrors = NULL; + } + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + + +/* --- Py_GetArgcArgv() ------------------------------------------- */ + +/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */ +static PyWideStringList orig_argv = {.length = 0, .items = NULL}; + + +void +_Py_ClearArgcArgv(void) +{ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + _PyWideStringList_Clear(&orig_argv); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + + +static int +_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) +{ + const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv}; + int res; + + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + res = _PyWideStringList_Copy(&orig_argv, &argv_list); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return res; +} + + +/* Make the *original* argc/argv available to other modules. + This is rare, but it is needed by the secureware extension. */ +void +Py_GetArgcArgv(int *argc, wchar_t ***argv) +{ + *argc = (int)orig_argv.length; + *argv = orig_argv.items; +} + + +/* --- PyConfig ---------------------------------------------- */ + +#define DECODE_LOCALE_ERR(NAME, LEN) \ + (((LEN) == -2) \ + ? _PyStatus_ERR("cannot decode " NAME) \ + : _PyStatus_NO_MEMORY()) + + +/* Free memory allocated in config, but don't clear all attributes */ +void +PyConfig_Clear(PyConfig *config) +{ +#define CLEAR(ATTR) \ + do { \ + PyMem_RawFree(ATTR); \ + ATTR = NULL; \ + } while (0) + + CLEAR(config->pycache_prefix); + CLEAR(config->pythonpath_env); + CLEAR(config->home); + CLEAR(config->program_name); + + _PyWideStringList_Clear(&config->argv); + _PyWideStringList_Clear(&config->warnoptions); + _PyWideStringList_Clear(&config->xoptions); + _PyWideStringList_Clear(&config->module_search_paths); + config->module_search_paths_set = 0; + + CLEAR(config->executable); + CLEAR(config->base_executable); + CLEAR(config->prefix); + CLEAR(config->base_prefix); + CLEAR(config->exec_prefix); + CLEAR(config->base_exec_prefix); + + CLEAR(config->filesystem_encoding); + CLEAR(config->filesystem_errors); + CLEAR(config->stdio_encoding); + CLEAR(config->stdio_errors); + CLEAR(config->run_command); + CLEAR(config->run_module); + CLEAR(config->run_filename); + CLEAR(config->check_hash_pycs_mode); +#undef CLEAR +} + + +void +_PyConfig_InitCompatConfig(PyConfig *config) +{ + memset(config, 0, sizeof(*config)); + + config->_config_init = (int)_PyConfig_INIT_COMPAT; + config->isolated = -1; + config->use_environment = -1; + config->dev_mode = -1; + config->install_signal_handlers = 1; + config->use_hash_seed = -1; + config->faulthandler = -1; + config->tracemalloc = -1; + config->module_search_paths_set = 0; + config->parse_argv = 0; + config->site_import = -1; + config->bytes_warning = -1; + config->inspect = -1; + config->interactive = -1; + config->optimization_level = -1; + config->parser_debug= -1; + config->write_bytecode = -1; + config->verbose = -1; + config->quiet = -1; + config->user_site_directory = -1; + config->configure_c_stdio = 0; + config->buffered_stdio = -1; + config->_install_importlib = 1; + config->check_hash_pycs_mode = NULL; + config->pathconfig_warnings = -1; + config->_init_main = 1; +#ifdef MS_WINDOWS + config->legacy_windows_stdio = -1; +#endif +} + + +static void +config_init_defaults(PyConfig *config) +{ + _PyConfig_InitCompatConfig(config); + + config->isolated = 0; + config->use_environment = 1; + config->site_import = 1; + config->bytes_warning = 0; + config->inspect = 0; + config->interactive = 0; + config->optimization_level = 0; + config->parser_debug= 0; + config->write_bytecode = 1; + config->verbose = 0; + config->quiet = 0; + config->user_site_directory = 1; + config->buffered_stdio = 1; + config->pathconfig_warnings = 1; +#ifdef MS_WINDOWS + config->legacy_windows_stdio = 0; +#endif +} + + +void +PyConfig_InitPythonConfig(PyConfig *config) +{ + config_init_defaults(config); + + config->_config_init = (int)_PyConfig_INIT_PYTHON; + config->configure_c_stdio = 1; + config->parse_argv = 1; +} + + +void +PyConfig_InitIsolatedConfig(PyConfig *config) +{ + config_init_defaults(config); + + config->_config_init = (int)_PyConfig_INIT_ISOLATED; + config->isolated = 1; + config->use_environment = 0; + config->user_site_directory = 0; + config->dev_mode = 0; + config->install_signal_handlers = 0; + config->use_hash_seed = 0; + config->faulthandler = 0; + config->tracemalloc = 0; + config->pathconfig_warnings = 0; +#ifdef MS_WINDOWS + config->legacy_windows_stdio = 0; +#endif +} + + +/* Copy str into *config_str (duplicate the string) */ +PyStatus +PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str) +{ + PyStatus status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + wchar_t *str2; + if (str != NULL) { + str2 = _PyMem_RawWcsdup(str); + if (str2 == NULL) { + return _PyStatus_NO_MEMORY(); + } + } + else { + str2 = NULL; + } + PyMem_RawFree(*config_str); + *config_str = str2; + return _PyStatus_OK(); +} + + +static PyStatus +config_set_bytes_string(PyConfig *config, wchar_t **config_str, + const char *str, const char *decode_err_msg) +{ + PyStatus status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + wchar_t *str2; + if (str != NULL) { + size_t len; + str2 = Py_DecodeLocale(str, &len); + if (str2 == NULL) { + if (len == (size_t)-2) { + return _PyStatus_ERR(decode_err_msg); + } + else { + return _PyStatus_NO_MEMORY(); + } + } + } + else { + str2 = NULL; + } + PyMem_RawFree(*config_str); + *config_str = str2; + return _PyStatus_OK(); +} + + +#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \ + config_set_bytes_string(config, config_str, str, "cannot decode " NAME) + + +/* Decode str using Py_DecodeLocale() and set the result into *config_str. + Pre-initialize Python if needed to ensure that encodings are properly + configured. */ +PyStatus +PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str, + const char *str) +{ + return CONFIG_SET_BYTES_STR(config, config_str, str, "string"); +} + + +PyStatus +_PyConfig_Copy(PyConfig *config, const PyConfig *config2) +{ + PyStatus status; + + PyConfig_Clear(config); + +#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR +#define COPY_WSTR_ATTR(ATTR) \ + do { \ + status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \ + if (_PyStatus_EXCEPTION(status)) { \ + return status; \ + } \ + } while (0) +#define COPY_WSTRLIST(LIST) \ + do { \ + if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \ + return _PyStatus_NO_MEMORY(); \ + } \ + } while (0) + + COPY_ATTR(_config_init); + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + COPY_ATTR(install_signal_handlers); + COPY_ATTR(use_hash_seed); + COPY_ATTR(hash_seed); + COPY_ATTR(_install_importlib); + COPY_ATTR(faulthandler); + COPY_ATTR(tracemalloc); + COPY_ATTR(import_time); + COPY_ATTR(show_ref_count); + COPY_ATTR(show_alloc_count); + COPY_ATTR(dump_refs); + COPY_ATTR(malloc_stats); + + COPY_WSTR_ATTR(pycache_prefix); + COPY_WSTR_ATTR(pythonpath_env); + COPY_WSTR_ATTR(home); + COPY_WSTR_ATTR(program_name); + + COPY_ATTR(parse_argv); + COPY_WSTRLIST(argv); + COPY_WSTRLIST(warnoptions); + COPY_WSTRLIST(xoptions); + COPY_WSTRLIST(module_search_paths); + COPY_ATTR(module_search_paths_set); + + COPY_WSTR_ATTR(executable); + COPY_WSTR_ATTR(base_executable); + COPY_WSTR_ATTR(prefix); + COPY_WSTR_ATTR(base_prefix); + COPY_WSTR_ATTR(exec_prefix); + COPY_WSTR_ATTR(base_exec_prefix); + + COPY_ATTR(site_import); + COPY_ATTR(bytes_warning); + COPY_ATTR(inspect); + COPY_ATTR(interactive); + COPY_ATTR(optimization_level); + COPY_ATTR(parser_debug); + COPY_ATTR(write_bytecode); + COPY_ATTR(verbose); + COPY_ATTR(quiet); + COPY_ATTR(user_site_directory); + COPY_ATTR(configure_c_stdio); + COPY_ATTR(buffered_stdio); + COPY_WSTR_ATTR(filesystem_encoding); + COPY_WSTR_ATTR(filesystem_errors); + COPY_WSTR_ATTR(stdio_encoding); + COPY_WSTR_ATTR(stdio_errors); +#ifdef MS_WINDOWS + COPY_ATTR(legacy_windows_stdio); +#endif + COPY_ATTR(skip_source_first_line); + COPY_WSTR_ATTR(run_command); + COPY_WSTR_ATTR(run_module); + COPY_WSTR_ATTR(run_filename); + COPY_WSTR_ATTR(check_hash_pycs_mode); + COPY_ATTR(pathconfig_warnings); + COPY_ATTR(_init_main); + +#undef COPY_ATTR +#undef COPY_WSTR_ATTR +#undef COPY_WSTRLIST + return _PyStatus_OK(); +} + + +static PyObject * +config_as_dict(const PyConfig *config) +{ + PyObject *dict; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define SET_ITEM(KEY, EXPR) \ + do { \ + PyObject *obj = (EXPR); \ + if (obj == NULL) { \ + goto fail; \ + } \ + int res = PyDict_SetItemString(dict, (KEY), obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) +#define SET_ITEM_INT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) +#define SET_ITEM_UINT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) +#define FROM_WSTRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromWideChar(STR, -1) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_WSTR(ATTR) \ + SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) +#define SET_ITEM_WSTRLIST(LIST) \ + SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST)) + + SET_ITEM_INT(_config_init); + SET_ITEM_INT(isolated); + SET_ITEM_INT(use_environment); + SET_ITEM_INT(dev_mode); + SET_ITEM_INT(install_signal_handlers); + SET_ITEM_INT(use_hash_seed); + SET_ITEM_UINT(hash_seed); + SET_ITEM_INT(faulthandler); + SET_ITEM_INT(tracemalloc); + SET_ITEM_INT(import_time); + SET_ITEM_INT(show_ref_count); + SET_ITEM_INT(show_alloc_count); + SET_ITEM_INT(dump_refs); + SET_ITEM_INT(malloc_stats); + SET_ITEM_WSTR(filesystem_encoding); + SET_ITEM_WSTR(filesystem_errors); + SET_ITEM_WSTR(pycache_prefix); + SET_ITEM_WSTR(program_name); + SET_ITEM_INT(parse_argv); + SET_ITEM_WSTRLIST(argv); + SET_ITEM_WSTRLIST(xoptions); + SET_ITEM_WSTRLIST(warnoptions); + SET_ITEM_WSTR(pythonpath_env); + SET_ITEM_WSTR(home); + SET_ITEM_WSTRLIST(module_search_paths); + SET_ITEM_WSTR(executable); + SET_ITEM_WSTR(base_executable); + SET_ITEM_WSTR(prefix); + SET_ITEM_WSTR(base_prefix); + SET_ITEM_WSTR(exec_prefix); + SET_ITEM_WSTR(base_exec_prefix); + SET_ITEM_INT(site_import); + SET_ITEM_INT(bytes_warning); + SET_ITEM_INT(inspect); + SET_ITEM_INT(interactive); + SET_ITEM_INT(optimization_level); + SET_ITEM_INT(parser_debug); + SET_ITEM_INT(write_bytecode); + SET_ITEM_INT(verbose); + SET_ITEM_INT(quiet); + SET_ITEM_INT(user_site_directory); + SET_ITEM_INT(configure_c_stdio); + SET_ITEM_INT(buffered_stdio); + SET_ITEM_WSTR(stdio_encoding); + SET_ITEM_WSTR(stdio_errors); +#ifdef MS_WINDOWS + SET_ITEM_INT(legacy_windows_stdio); +#endif + SET_ITEM_INT(skip_source_first_line); + SET_ITEM_WSTR(run_command); + SET_ITEM_WSTR(run_module); + SET_ITEM_WSTR(run_filename); + SET_ITEM_INT(_install_importlib); + SET_ITEM_WSTR(check_hash_pycs_mode); + SET_ITEM_INT(pathconfig_warnings); + SET_ITEM_INT(_init_main); + + return dict; + +fail: + Py_DECREF(dict); + return NULL; + +#undef FROM_WSTRING +#undef SET_ITEM +#undef SET_ITEM_INT +#undef SET_ITEM_UINT +#undef SET_ITEM_WSTR +#undef SET_ITEM_WSTRLIST +} + + +static const char* +config_get_env(const PyConfig *config, const char *name) +{ + return _Py_GetEnv(config->use_environment, name); +} + + +/* Get a copy of the environment variable as wchar_t*. + Return 0 on success, but *dest can be NULL. + Return -1 on memory allocation failure. Return -2 on decoding error. */ +static PyStatus +config_get_env_dup(PyConfig *config, + wchar_t **dest, + wchar_t *wname, char *name, + const char *decode_err_msg) +{ + assert(*dest == NULL); + assert(config->use_environment >= 0); + + if (!config->use_environment) { + *dest = NULL; + return _PyStatus_OK(); + } + +#ifdef MS_WINDOWS + const wchar_t *var = _wgetenv(wname); + if (!var || var[0] == '\0') { + *dest = NULL; + return _PyStatus_OK(); + } + + return PyConfig_SetString(config, dest, var); +#else + const char *var = getenv(name); + if (!var || var[0] == '\0') { + *dest = NULL; + return _PyStatus_OK(); + } + + return config_set_bytes_string(config, dest, var, decode_err_msg); +#endif +} + + +#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \ + config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME) + + +static void +config_get_global_vars(PyConfig *config) +{ + if (config->_config_init != _PyConfig_INIT_COMPAT) { + /* Python and Isolated configuration ignore global variables */ + return; + } + +#define COPY_FLAG(ATTR, VALUE) \ + if (config->ATTR == -1) { \ + config->ATTR = VALUE; \ + } +#define COPY_NOT_FLAG(ATTR, VALUE) \ + if (config->ATTR == -1) { \ + config->ATTR = !(VALUE); \ + } + + COPY_FLAG(isolated, Py_IsolatedFlag); + COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); + COPY_FLAG(bytes_warning, Py_BytesWarningFlag); + COPY_FLAG(inspect, Py_InspectFlag); + COPY_FLAG(interactive, Py_InteractiveFlag); + COPY_FLAG(optimization_level, Py_OptimizeFlag); + COPY_FLAG(parser_debug, Py_DebugFlag); + COPY_FLAG(verbose, Py_VerboseFlag); + COPY_FLAG(quiet, Py_QuietFlag); +#ifdef MS_WINDOWS + COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag); +#endif + COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag); + + COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag); + COPY_NOT_FLAG(site_import, Py_NoSiteFlag); + COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag); + COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory); + +#undef COPY_FLAG +#undef COPY_NOT_FLAG +} + + +/* Set Py_xxx global configuration variables from 'config' configuration. */ +static void +config_set_global_vars(const PyConfig *config) +{ +#define COPY_FLAG(ATTR, VAR) \ + if (config->ATTR != -1) { \ + VAR = config->ATTR; \ + } +#define COPY_NOT_FLAG(ATTR, VAR) \ + if (config->ATTR != -1) { \ + VAR = !config->ATTR; \ + } + + COPY_FLAG(isolated, Py_IsolatedFlag); + COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); + COPY_FLAG(bytes_warning, Py_BytesWarningFlag); + COPY_FLAG(inspect, Py_InspectFlag); + COPY_FLAG(interactive, Py_InteractiveFlag); + COPY_FLAG(optimization_level, Py_OptimizeFlag); + COPY_FLAG(parser_debug, Py_DebugFlag); + COPY_FLAG(verbose, Py_VerboseFlag); + COPY_FLAG(quiet, Py_QuietFlag); +#ifdef MS_WINDOWS + COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag); +#endif + COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag); + + COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag); + COPY_NOT_FLAG(site_import, Py_NoSiteFlag); + COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag); + COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory); + + /* Random or non-zero hash seed */ + Py_HashRandomizationFlag = (config->use_hash_seed == 0 || + config->hash_seed != 0); + +#undef COPY_FLAG +#undef COPY_NOT_FLAG +} + + +/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__ + environment variables on macOS if available. */ +static PyStatus +config_init_program_name(PyConfig *config) +{ + PyStatus status; + + /* If Py_SetProgramName() was called, use its value */ + const wchar_t *program_name = _Py_path_config.program_name; + if (program_name != NULL) { + config->program_name = _PyMem_RawWcsdup(program_name); + if (config->program_name == NULL) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); + } + +#ifdef __APPLE__ + /* On MacOS X, when the Python interpreter is embedded in an + application bundle, it gets executed by a bootstrapping script + that does os.execve() with an argv[0] that's different from the + actual Python executable. This is needed to keep the Finder happy, + or rather, to work around Apple's overly strict requirements of + the process name. However, we still need a usable sys.executable, + so the actual executable path is passed in an environment variable. + See Lib/plat-mac/bundlebuiler.py for details about the bootstrap + script. */ + const char *p = config_get_env(config, "PYTHONEXECUTABLE"); + if (p != NULL) { + status = CONFIG_SET_BYTES_STR(config, &config->program_name, p, + "PYTHONEXECUTABLE environment variable"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); + } +#ifdef WITH_NEXT_FRAMEWORK + else { + const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__"); + if (pyvenv_launcher && *pyvenv_launcher) { + /* Used by Mac/Tools/pythonw.c to forward + * the argv0 of the stub executable + */ + status = CONFIG_SET_BYTES_STR(config, + &config->program_name, + pyvenv_launcher, + "__PYVENV_LAUNCHER__ environment variable"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* + * This environment variable is used to communicate between + * the stub launcher and the real interpreter and isn't needed + * beyond this point. + * + * Clean up to avoid problems when launching other programs + * later on. + */ + (void)unsetenv("__PYVENV_LAUNCHER__"); + + return _PyStatus_OK(); + } + } +#endif /* WITH_NEXT_FRAMEWORK */ +#endif /* __APPLE__ */ + + /* Use argv[0] if available and non-empty */ + const PyWideStringList *argv = &config->argv; + if (argv->length >= 1 && argv->items[0][0] != L'\0') { + config->program_name = _PyMem_RawWcsdup(argv->items[0]); + if (config->program_name == NULL) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); + } + + /* Last fall back: hardcoded name */ +#ifdef MS_WINDOWS + const wchar_t *default_program_name = L"python"; +#else + const wchar_t *default_program_name = L"python3"; +#endif + status = PyConfig_SetString(config, &config->program_name, + default_program_name); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); +} + +static PyStatus +config_init_executable(PyConfig *config) +{ + assert(config->executable == NULL); + + /* If Py_SetProgramFullPath() was called, use its value */ + const wchar_t *program_full_path = _Py_path_config.program_full_path; + if (program_full_path != NULL) { + PyStatus status = PyConfig_SetString(config, + &config->executable, + program_full_path); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); + } + return _PyStatus_OK(); +} + + +static const wchar_t* +config_get_xoption(const PyConfig *config, wchar_t *name) +{ + return _Py_get_xoption(&config->xoptions, name); +} + + +static PyStatus +config_init_home(PyConfig *config) +{ + assert(config->home == NULL); + + /* If Py_SetPythonHome() was called, use its value */ + wchar_t *home = _Py_path_config.home; + if (home) { + PyStatus status = PyConfig_SetString(config, &config->home, home); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); + } + + return CONFIG_GET_ENV_DUP(config, &config->home, + L"PYTHONHOME", "PYTHONHOME"); +} + + +static PyStatus +config_init_hash_seed(PyConfig *config) +{ + const char *seed_text = config_get_env(config, "PYTHONHASHSEED"); + + Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); + /* Convert a text seed to a numeric one */ + if (seed_text && strcmp(seed_text, "random") != 0) { + const char *endptr = seed_text; + unsigned long seed; + errno = 0; + seed = strtoul(seed_text, (char **)&endptr, 10); + if (*endptr != '\0' + || seed > 4294967295UL + || (errno == ERANGE && seed == ULONG_MAX)) + { + return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" " + "or an integer in range [0; 4294967295]"); + } + /* Use a specific hash */ + config->use_hash_seed = 1; + config->hash_seed = seed; + } + else { + /* Use a random hash */ + config->use_hash_seed = 0; + config->hash_seed = 0; + } + return _PyStatus_OK(); +} + + +static int +config_wstr_to_int(const wchar_t *wstr, int *result) +{ + const wchar_t *endptr = wstr; + errno = 0; + long value = wcstol(wstr, (wchar_t **)&endptr, 10); + if (*endptr != '\0' || errno == ERANGE) { + return -1; + } + if (value < INT_MIN || value > INT_MAX) { + return -1; + } + + *result = (int)value; + return 0; +} + + +static PyStatus +config_read_env_vars(PyConfig *config) +{ + PyStatus status; + int use_env = config->use_environment; + + /* Get environment variables */ + _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG"); + _Py_get_env_flag(use_env, &config->verbose, "PYTHONVERBOSE"); + _Py_get_env_flag(use_env, &config->optimization_level, "PYTHONOPTIMIZE"); + _Py_get_env_flag(use_env, &config->inspect, "PYTHONINSPECT"); + + int dont_write_bytecode = 0; + _Py_get_env_flag(use_env, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE"); + if (dont_write_bytecode) { + config->write_bytecode = 0; + } + + int no_user_site_directory = 0; + _Py_get_env_flag(use_env, &no_user_site_directory, "PYTHONNOUSERSITE"); + if (no_user_site_directory) { + config->user_site_directory = 0; + } + + int unbuffered_stdio = 0; + _Py_get_env_flag(use_env, &unbuffered_stdio, "PYTHONUNBUFFERED"); + if (unbuffered_stdio) { + config->buffered_stdio = 0; + } + +#ifdef MS_WINDOWS + _Py_get_env_flag(use_env, &config->legacy_windows_stdio, + "PYTHONLEGACYWINDOWSSTDIO"); +#endif + + if (config_get_env(config, "PYTHONDUMPREFS")) { + config->dump_refs = 1; + } + if (config_get_env(config, "PYTHONMALLOCSTATS")) { + config->malloc_stats = 1; + } + + if (config->pythonpath_env == NULL) { + status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env, + L"PYTHONPATH", "PYTHONPATH"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->use_hash_seed < 0) { + status = config_init_hash_seed(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + return _PyStatus_OK(); +} + + +static PyStatus +config_init_tracemalloc(PyConfig *config) +{ + int nframe; + int valid; + + const char *env = config_get_env(config, "PYTHONTRACEMALLOC"); + if (env) { + if (!_Py_str_to_int(env, &nframe)) { + valid = (nframe >= 0); + } + else { + valid = 0; + } + if (!valid) { + return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames"); + } + config->tracemalloc = nframe; + } + + const wchar_t *xoption = config_get_xoption(config, L"tracemalloc"); + if (xoption) { + const wchar_t *sep = wcschr(xoption, L'='); + if (sep) { + if (!config_wstr_to_int(sep + 1, &nframe)) { + valid = (nframe >= 0); + } + else { + valid = 0; + } + if (!valid) { + return _PyStatus_ERR("-X tracemalloc=NFRAME: " + "invalid number of frames"); + } + } + else { + /* -X tracemalloc behaves as -X tracemalloc=1 */ + nframe = 1; + } + config->tracemalloc = nframe; + } + return _PyStatus_OK(); +} + + +static PyStatus +config_init_pycache_prefix(PyConfig *config) +{ + assert(config->pycache_prefix == NULL); + + const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix"); + if (xoption) { + const wchar_t *sep = wcschr(xoption, L'='); + if (sep && wcslen(sep) > 1) { + config->pycache_prefix = _PyMem_RawWcsdup(sep + 1); + if (config->pycache_prefix == NULL) { + return _PyStatus_NO_MEMORY(); + } + } + else { + // PYTHONPYCACHEPREFIX env var ignored + // if "-X pycache_prefix=" option is used + config->pycache_prefix = NULL; + } + return _PyStatus_OK(); + } + + return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix, + L"PYTHONPYCACHEPREFIX", + "PYTHONPYCACHEPREFIX"); +} + + +static PyStatus +config_read_complex_options(PyConfig *config) +{ + /* More complex options configured by env var and -X option */ + if (config->faulthandler < 0) { + if (config_get_env(config, "PYTHONFAULTHANDLER") + || config_get_xoption(config, L"faulthandler")) { + config->faulthandler = 1; + } + } + if (config_get_env(config, "PYTHONPROFILEIMPORTTIME") + || config_get_xoption(config, L"importtime")) { + config->import_time = 1; + } + + PyStatus status; + if (config->tracemalloc < 0) { + status = config_init_tracemalloc(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->pycache_prefix == NULL) { + status = config_init_pycache_prefix(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +static const wchar_t * +config_get_stdio_errors(const PyConfig *config) +{ +#ifndef MS_WINDOWS + const char *loc = setlocale(LC_CTYPE, NULL); + if (loc != NULL) { + /* surrogateescape is the default in the legacy C and POSIX locales */ + if (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0) { + return L"surrogateescape"; + } + +#ifdef PY_COERCE_C_LOCALE + /* surrogateescape is the default in locale coercion target locales */ + if (_Py_IsLocaleCoercionTarget(loc)) { + return L"surrogateescape"; + } +#endif + } + + return L"strict"; +#else + /* On Windows, always use surrogateescape by default */ + return L"surrogateescape"; +#endif +} + + +static PyStatus +config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding) +{ +#ifdef MS_WINDOWS + char encoding[20]; + PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); + return PyConfig_SetBytesString(config, locale_encoding, encoding); +#elif defined(_Py_FORCE_UTF8_LOCALE) + return PyConfig_SetString(config, locale_encoding, L"utf-8"); +#else + const char *encoding = nl_langinfo(CODESET); + if (!encoding || encoding[0] == '\0') { + return _PyStatus_ERR("failed to get the locale encoding: " + "nl_langinfo(CODESET) failed"); + } + /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */ + return CONFIG_SET_BYTES_STR(config, + locale_encoding, encoding, + "nl_langinfo(CODESET)"); +#endif +} + + +static PyStatus +config_init_stdio_encoding(PyConfig *config, + const PyPreConfig *preconfig) +{ + PyStatus status; + + /* If Py_SetStandardStreamEncoding() have been called, use these + parameters. */ + if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { + status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding, + _Py_StandardStreamEncoding, + "_Py_StandardStreamEncoding"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) { + status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors, + _Py_StandardStreamErrors, + "_Py_StandardStreamErrors"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->stdio_encoding != NULL && config->stdio_errors != NULL) { + return _PyStatus_OK(); + } + + /* PYTHONIOENCODING environment variable */ + const char *opt = config_get_env(config, "PYTHONIOENCODING"); + if (opt) { + char *pythonioencoding = _PyMem_RawStrdup(opt); + if (pythonioencoding == NULL) { + return _PyStatus_NO_MEMORY(); + } + + char *errors = strchr(pythonioencoding, ':'); + if (errors) { + *errors = '\0'; + errors++; + if (!errors[0]) { + errors = NULL; + } + } + + /* Does PYTHONIOENCODING contain an encoding? */ + if (pythonioencoding[0]) { + if (config->stdio_encoding == NULL) { + status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding, + pythonioencoding, + "PYTHONIOENCODING environment variable"); + if (_PyStatus_EXCEPTION(status)) { + PyMem_RawFree(pythonioencoding); + return status; + } + } + + /* If the encoding is set but not the error handler, + use "strict" error handler by default. + PYTHONIOENCODING=latin1 behaves as + PYTHONIOENCODING=latin1:strict. */ + if (!errors) { + errors = "strict"; + } + } + + if (config->stdio_errors == NULL && errors != NULL) { + status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors, + errors, + "PYTHONIOENCODING environment variable"); + if (_PyStatus_EXCEPTION(status)) { + PyMem_RawFree(pythonioencoding); + return status; + } + } + + PyMem_RawFree(pythonioencoding); + } + + /* UTF-8 Mode uses UTF-8/surrogateescape */ + if (preconfig->utf8_mode) { + if (config->stdio_encoding == NULL) { + status = PyConfig_SetString(config, &config->stdio_encoding, + L"utf-8"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + if (config->stdio_errors == NULL) { + status = PyConfig_SetString(config, &config->stdio_errors, + L"surrogateescape"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + } + + /* Choose the default error handler based on the current locale. */ + if (config->stdio_encoding == NULL) { + status = config_get_locale_encoding(config, &config->stdio_encoding); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + if (config->stdio_errors == NULL) { + const wchar_t *errors = config_get_stdio_errors(config); + assert(errors != NULL); + + status = PyConfig_SetString(config, &config->stdio_errors, errors); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + return _PyStatus_OK(); +} + + +static PyStatus +config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig) +{ + PyStatus status; + + if (config->filesystem_encoding == NULL) { +#ifdef _Py_FORCE_UTF8_FS_ENCODING + status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8"); +#else + +#ifdef MS_WINDOWS + if (preconfig->legacy_windows_fs_encoding) { + /* Legacy Windows filesystem encoding: mbcs/replace */ + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"mbcs"); + } + else +#endif + if (preconfig->utf8_mode) { + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"utf-8"); + } +#ifndef MS_WINDOWS + else if (_Py_GetForceASCII()) { + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"ascii"); + } +#endif + else { +#ifdef MS_WINDOWS + /* Windows defaults to utf-8/surrogatepass (PEP 529). */ + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"utf-8"); +#else + status = config_get_locale_encoding(config, + &config->filesystem_encoding); +#endif + } +#endif /* !_Py_FORCE_UTF8_FS_ENCODING */ + + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->filesystem_errors == NULL) { + const wchar_t *errors; +#ifdef MS_WINDOWS + if (preconfig->legacy_windows_fs_encoding) { + errors = L"replace"; + } + else { + errors = L"surrogatepass"; + } +#else + errors = L"surrogateescape"; +#endif + status = PyConfig_SetString(config, &config->filesystem_errors, errors); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +static PyStatus +config_read(PyConfig *config) +{ + PyStatus status; + const PyPreConfig *preconfig = &_PyRuntime.preconfig; + + if (config->use_environment) { + status = config_read_env_vars(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + /* -X options */ + if (config_get_xoption(config, L"showrefcount")) { + config->show_ref_count = 1; + } + if (config_get_xoption(config, L"showalloccount")) { + config->show_alloc_count = 1; + } + + status = config_read_complex_options(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (config->home == NULL) { + status = config_init_home(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->executable == NULL) { + status = config_init_executable(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->_install_importlib) { + status = _PyConfig_InitPathConfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + /* default values */ + if (config->dev_mode) { + if (config->faulthandler < 0) { + config->faulthandler = 1; + } + } + if (config->faulthandler < 0) { + config->faulthandler = 0; + } + if (config->tracemalloc < 0) { + config->tracemalloc = 0; + } + if (config->use_hash_seed < 0) { + config->use_hash_seed = 0; + config->hash_seed = 0; + } + + if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) { + status = config_init_fs_encoding(config, preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + status = config_init_stdio_encoding(config, preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (config->argv.length < 1) { + /* Ensure at least one (empty) argument is seen */ + status = PyWideStringList_Append(&config->argv, L""); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->check_hash_pycs_mode == NULL) { + status = PyConfig_SetString(config, &config->check_hash_pycs_mode, + L"default"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->configure_c_stdio < 0) { + config->configure_c_stdio = 1; + } + + return _PyStatus_OK(); +} + + +static void +config_init_stdio(const PyConfig *config) +{ +#if defined(MS_WINDOWS) || defined(__CYGWIN__) + /* don't translate newlines (\r\n <=> \n) */ + _setmode(fileno(stdin), O_BINARY); + _setmode(fileno(stdout), O_BINARY); + _setmode(fileno(stderr), O_BINARY); +#endif + + if (!config->buffered_stdio) { +#ifdef HAVE_SETVBUF + setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ); + setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ); + setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ); +#else /* !HAVE_SETVBUF */ + setbuf(stdin, (char *)NULL); + setbuf(stdout, (char *)NULL); + setbuf(stderr, (char *)NULL); +#endif /* !HAVE_SETVBUF */ + } + else if (config->interactive) { +#ifdef MS_WINDOWS + /* Doesn't have to have line-buffered -- use unbuffered */ + /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */ + setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ); +#else /* !MS_WINDOWS */ +#ifdef HAVE_SETVBUF + setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ); + setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); +#endif /* HAVE_SETVBUF */ +#endif /* !MS_WINDOWS */ + /* Leave stderr alone - it should be unbuffered anyway. */ + } +} + + +/* Write the configuration: + + - set Py_xxx global configuration variables + - initialize C standard streams (stdin, stdout, stderr) */ +void +_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime) +{ + config_set_global_vars(config); + + if (config->configure_c_stdio) { + config_init_stdio(config); + } + + /* Write the new pre-configuration into _PyRuntime */ + PyPreConfig *preconfig = &runtime->preconfig; + preconfig->isolated = config->isolated; + preconfig->use_environment = config->use_environment; + preconfig->dev_mode = config->dev_mode; +} + + +/* --- PyConfig command line parser -------------------------- */ + +static void +config_usage(int error, const wchar_t* program) +{ + FILE *f = error ? stderr : stdout; + + fprintf(f, usage_line, program); + if (error) + fprintf(f, "Try `python -h' for more information.\n"); + else { + fputs(usage_1, f); + fputs(usage_2, f); + fputs(usage_3, f); + fprintf(f, usage_4, (wint_t)DELIM); + fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP); + fputs(usage_6, f); + } +} + + +/* Parse the command line arguments */ +static PyStatus +config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, + Py_ssize_t *opt_index) +{ + PyStatus status; + const PyWideStringList *argv = &config->argv; + int print_version = 0; + const wchar_t* program = config->program_name; + + _PyOS_ResetGetOpt(); + do { + int longindex = -1; + int c = _PyOS_GetOpt(argv->length, argv->items, &longindex); + if (c == EOF) { + break; + } + + if (c == 'c') { + if (config->run_command == NULL) { + /* -c is the last option; following arguments + that look like options are left for the + command to interpret. */ + size_t len = wcslen(_PyOS_optarg) + 1 + 1; + wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len); + if (command == NULL) { + return _PyStatus_NO_MEMORY(); + } + memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t)); + command[len - 2] = '\n'; + command[len - 1] = 0; + config->run_command = command; + } + break; + } + + if (c == 'm') { + /* -m is the last option; following arguments + that look like options are left for the + module to interpret. */ + if (config->run_module == NULL) { + config->run_module = _PyMem_RawWcsdup(_PyOS_optarg); + if (config->run_module == NULL) { + return _PyStatus_NO_MEMORY(); + } + } + break; + } + + switch (c) { + case 0: + // Handle long option. + assert(longindex == 0); // Only one long option now. + if (wcscmp(_PyOS_optarg, L"always") == 0 + || wcscmp(_PyOS_optarg, L"never") == 0 + || wcscmp(_PyOS_optarg, L"default") == 0) + { + status = PyConfig_SetString(config, &config->check_hash_pycs_mode, + _PyOS_optarg); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } else { + fprintf(stderr, "--check-hash-based-pycs must be one of " + "'default', 'always', or 'never'\n"); + config_usage(1, program); + return _PyStatus_EXIT(2); + } + break; + + case 'b': + config->bytes_warning++; + break; + + case 'd': + config->parser_debug++; + break; + + case 'i': + config->inspect++; + config->interactive++; + break; + + case 'E': + case 'I': + case 'X': + /* option handled by _PyPreCmdline_Read() */ + break; + + /* case 'J': reserved for Jython */ + + case 'O': + config->optimization_level++; + break; + + case 'B': + config->write_bytecode = 0; + break; + + case 's': + config->user_site_directory = 0; + break; + + case 'S': + config->site_import = 0; + break; + + case 't': + /* ignored for backwards compatibility */ + break; + + case 'u': + config->buffered_stdio = 0; + break; + + case 'v': + config->verbose++; + break; + + case 'x': + config->skip_source_first_line = 1; + break; + + case 'h': + case '?': + config_usage(0, program); + return _PyStatus_EXIT(0); + + case 'V': + print_version++; + break; + + case 'W': + status = PyWideStringList_Append(warnoptions, _PyOS_optarg); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + break; + + case 'q': + config->quiet++; + break; + + case 'R': + config->use_hash_seed = 0; + break; + + /* This space reserved for other options */ + + default: + /* unknown argument: parsing failed */ + config_usage(1, program); + return _PyStatus_EXIT(2); + } + } while (1); + + if (print_version) { + printf("Python %s\n", + (print_version >= 2) ? Py_GetVersion() : PY_VERSION); + return _PyStatus_EXIT(0); + } + + if (config->run_command == NULL && config->run_module == NULL + && _PyOS_optind < argv->length + && wcscmp(argv->items[_PyOS_optind], L"-") != 0 + && config->run_filename == NULL) + { + config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]); + if (config->run_filename == NULL) { + return _PyStatus_NO_MEMORY(); + } + } + + if (config->run_command != NULL || config->run_module != NULL) { + /* Backup _PyOS_optind */ + _PyOS_optind--; + } + + *opt_index = _PyOS_optind; + + return _PyStatus_OK(); +} + + +#ifdef MS_WINDOWS +# define WCSTOK wcstok_s +#else +# define WCSTOK wcstok +#endif + +/* Get warning options from PYTHONWARNINGS environment variable. */ +static PyStatus +config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions) +{ + PyStatus status; + /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */ + wchar_t *env = NULL; + status = CONFIG_GET_ENV_DUP(config, &env, + L"PYTHONWARNINGS", "PYTHONWARNINGS"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* env var is not set or is empty */ + if (env == NULL) { + return _PyStatus_OK(); + } + + + wchar_t *warning, *context = NULL; + for (warning = WCSTOK(env, L",", &context); + warning != NULL; + warning = WCSTOK(NULL, L",", &context)) + { + status = PyWideStringList_Append(warnoptions, warning); + if (_PyStatus_EXCEPTION(status)) { + PyMem_RawFree(env); + return status; + } + } + PyMem_RawFree(env); + return _PyStatus_OK(); +} + + +static PyStatus +warnoptions_append(PyConfig *config, PyWideStringList *options, + const wchar_t *option) +{ + /* config_init_warnoptions() add existing config warnoptions at the end: + ensure that the new option is not already present in this list to + prevent change the options order whne config_init_warnoptions() is + called twice. */ + if (_PyWideStringList_Find(&config->warnoptions, option)) { + /* Already present: do nothing */ + return _PyStatus_OK(); + } + if (_PyWideStringList_Find(options, option)) { + /* Already present: do nothing */ + return _PyStatus_OK(); + } + return PyWideStringList_Append(options, option); +} + + +static PyStatus +warnoptions_extend(PyConfig *config, PyWideStringList *options, + const PyWideStringList *options2) +{ + const Py_ssize_t len = options2->length; + wchar_t *const *items = options2->items; + + for (Py_ssize_t i = 0; i < len; i++) { + PyStatus status = warnoptions_append(config, options, items[i]); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +static PyStatus +config_init_warnoptions(PyConfig *config, + const PyWideStringList *cmdline_warnoptions, + const PyWideStringList *env_warnoptions, + const PyWideStringList *sys_warnoptions) +{ + PyStatus status; + PyWideStringList options = _PyWideStringList_INIT; + + /* Priority of warnings options, lowest to highest: + * + * - any implicit filters added by _warnings.c/warnings.py + * - PyConfig.dev_mode: "default" filter + * - PYTHONWARNINGS environment variable + * - '-W' command line options + * - PyConfig.bytes_warning ('-b' and '-bb' command line options): + * "default::BytesWarning" or "error::BytesWarning" filter + * - early PySys_AddWarnOption() calls + * - PyConfig.warnoptions + * + * PyConfig.warnoptions is copied to sys.warnoptions. Since the warnings + * module works on the basis of "the most recently added filter will be + * checked first", we add the lowest precedence entries first so that later + * entries override them. + */ + + if (config->dev_mode) { + status = warnoptions_append(config, &options, L"default"); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + } + + status = warnoptions_extend(config, &options, env_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + + status = warnoptions_extend(config, &options, cmdline_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + + /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c + * don't even try to emit a warning, so we skip setting the filter in that + * case. + */ + if (config->bytes_warning) { + const wchar_t *filter; + if (config->bytes_warning> 1) { + filter = L"error::BytesWarning"; + } + else { + filter = L"default::BytesWarning"; + } + status = warnoptions_append(config, &options, filter); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + } + + status = warnoptions_extend(config, &options, sys_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + + /* Always add all PyConfig.warnoptions options */ + status = _PyWideStringList_Extend(&options, &config->warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } + + _PyWideStringList_Clear(&config->warnoptions); + config->warnoptions = options; + return _PyStatus_OK(); + +error: + _PyWideStringList_Clear(&options); + return status; +} + + +static PyStatus +config_update_argv(PyConfig *config, Py_ssize_t opt_index) +{ + const PyWideStringList *cmdline_argv = &config->argv; + PyWideStringList config_argv = _PyWideStringList_INIT; + + /* Copy argv to be able to modify it (to force -c/-m) */ + if (cmdline_argv->length <= opt_index) { + /* Ensure at least one (empty) argument is seen */ + PyStatus status = PyWideStringList_Append(&config_argv, L""); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + else { + PyWideStringList slice; + slice.length = cmdline_argv->length - opt_index; + slice.items = &cmdline_argv->items[opt_index]; + if (_PyWideStringList_Copy(&config_argv, &slice) < 0) { + return _PyStatus_NO_MEMORY(); + } + } + assert(config_argv.length >= 1); + + wchar_t *arg0 = NULL; + if (config->run_command != NULL) { + /* Force sys.argv[0] = '-c' */ + arg0 = L"-c"; + } + else if (config->run_module != NULL) { + /* Force sys.argv[0] = '-m'*/ + arg0 = L"-m"; + } + if (arg0 != NULL) { + arg0 = _PyMem_RawWcsdup(arg0); + if (arg0 == NULL) { + _PyWideStringList_Clear(&config_argv); + return _PyStatus_NO_MEMORY(); + } + + PyMem_RawFree(config_argv.items[0]); + config_argv.items[0] = arg0; + } + + _PyWideStringList_Clear(&config->argv); + config->argv = config_argv; + return _PyStatus_OK(); +} + + +static PyStatus +core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline) +{ + PyStatus status; + + if (config->parse_argv) { + if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) { + return _PyStatus_NO_MEMORY(); + } + } + + PyPreConfig preconfig; + + status = _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + _PyPreConfig_GetConfig(&preconfig, config); + + status = _PyPreCmdline_Read(precmdline, &preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyPreCmdline_SetConfig(precmdline, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); +} + + +static PyStatus +config_read_cmdline(PyConfig *config) +{ + PyStatus status; + PyWideStringList cmdline_warnoptions = _PyWideStringList_INIT; + PyWideStringList env_warnoptions = _PyWideStringList_INIT; + PyWideStringList sys_warnoptions = _PyWideStringList_INIT; + + if (config->parse_argv < 0) { + config->parse_argv = 1; + } + + if (config->program_name == NULL) { + status = config_init_program_name(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->parse_argv) { + Py_ssize_t opt_index; + status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = config_update_argv(config, opt_index); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + } + + if (config->use_environment) { + status = config_init_env_warnoptions(config, &env_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + } + + /* Handle early PySys_AddWarnOption() calls */ + status = _PySys_ReadPreinitWarnOptions(&sys_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = config_init_warnoptions(config, + &cmdline_warnoptions, + &env_warnoptions, + &sys_warnoptions); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = _PyStatus_OK(); + +done: + _PyWideStringList_Clear(&cmdline_warnoptions); + _PyWideStringList_Clear(&env_warnoptions); + _PyWideStringList_Clear(&sys_warnoptions); + return status; +} + + +PyStatus +_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args) +{ + PyStatus status = _Py_PreInitializeFromConfig(config, args); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + return _PyArgv_AsWstrList(args, &config->argv); +} + + +/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python + if needed to ensure that encodings are properly configured. */ +PyStatus +PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv) +{ + _PyArgv args = { + .argc = argc, + .use_bytes_argv = 1, + .bytes_argv = argv, + .wchar_argv = NULL}; + return _PyConfig_SetPyArgv(config, &args); +} + + +PyStatus +PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv) +{ + _PyArgv args = { + .argc = argc, + .use_bytes_argv = 0, + .bytes_argv = NULL, + .wchar_argv = argv}; + return _PyConfig_SetPyArgv(config, &args); +} + + +PyStatus +PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, + Py_ssize_t length, wchar_t **items) +{ + PyStatus status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + PyWideStringList list2 = {.length = length, .items = items}; + if (_PyWideStringList_Copy(list, &list2) < 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} + + +/* Read the configuration into PyConfig from: + + * Command line arguments + * Environment variables + * Py_xxx global configuration variables + + The only side effects are to modify config and to call _Py_SetArgcArgv(). */ +PyStatus +PyConfig_Read(PyConfig *config) +{ + PyStatus status; + PyWideStringList orig_argv = _PyWideStringList_INIT; + + status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + config_get_global_vars(config); + + if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) { + return _PyStatus_NO_MEMORY(); + } + + _PyPreCmdline precmdline = _PyPreCmdline_INIT; + status = core_read_precmdline(config, &precmdline); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + assert(config->isolated >= 0); + if (config->isolated) { + config->use_environment = 0; + config->user_site_directory = 0; + } + + status = config_read_cmdline(config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + /* Handle early PySys_AddXOption() calls */ + status = _PySys_ReadPreinitXOptions(config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = config_read(config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) { + status = _PyStatus_NO_MEMORY(); + goto done; + } + + /* Check config consistency */ + assert(config->isolated >= 0); + assert(config->use_environment >= 0); + assert(config->dev_mode >= 0); + assert(config->install_signal_handlers >= 0); + assert(config->use_hash_seed >= 0); + assert(config->faulthandler >= 0); + assert(config->tracemalloc >= 0); + assert(config->site_import >= 0); + assert(config->bytes_warning >= 0); + assert(config->inspect >= 0); + assert(config->interactive >= 0); + assert(config->optimization_level >= 0); + assert(config->parser_debug >= 0); + assert(config->write_bytecode >= 0); + assert(config->verbose >= 0); + assert(config->quiet >= 0); + assert(config->user_site_directory >= 0); + assert(config->parse_argv >= 0); + assert(config->configure_c_stdio >= 0); + assert(config->buffered_stdio >= 0); + assert(config->program_name != NULL); + assert(_PyWideStringList_CheckConsistency(&config->argv)); + /* sys.argv must be non-empty: empty argv is replaced with [''] */ + assert(config->argv.length >= 1); + assert(_PyWideStringList_CheckConsistency(&config->xoptions)); + assert(_PyWideStringList_CheckConsistency(&config->warnoptions)); + assert(_PyWideStringList_CheckConsistency(&config->module_search_paths)); + if (config->_install_importlib) { + assert(config->module_search_paths_set != 0); + /* don't check config->module_search_paths */ + assert(config->executable != NULL); + assert(config->base_executable != NULL); + assert(config->prefix != NULL); + assert(config->base_prefix != NULL); + assert(config->exec_prefix != NULL); + assert(config->base_exec_prefix != NULL); + } + assert(config->filesystem_encoding != NULL); + assert(config->filesystem_errors != NULL); + assert(config->stdio_encoding != NULL); + assert(config->stdio_errors != NULL); +#ifdef MS_WINDOWS + assert(config->legacy_windows_stdio >= 0); +#endif + /* -c and -m options are exclusive */ + assert(!(config->run_command != NULL && config->run_module != NULL)); + assert(config->check_hash_pycs_mode != NULL); + assert(config->_install_importlib >= 0); + assert(config->pathconfig_warnings >= 0); + + status = _PyStatus_OK(); + +done: + _PyWideStringList_Clear(&orig_argv); + _PyPreCmdline_Clear(&precmdline); + return status; +} + + +PyObject* +_Py_GetConfigsAsDict(void) +{ + PyObject *result = NULL; + PyObject *dict = NULL; + + result = PyDict_New(); + if (result == NULL) { + goto error; + } + + /* global result */ + dict = _Py_GetGlobalVariablesAsDict(); + if (dict == NULL) { + goto error; + } + if (PyDict_SetItemString(result, "global_config", dict) < 0) { + goto error; + } + Py_CLEAR(dict); + + /* pre config */ + PyInterpreterState *interp = _PyInterpreterState_Get(); + const PyPreConfig *pre_config = &_PyRuntime.preconfig; + dict = _PyPreConfig_AsDict(pre_config); + if (dict == NULL) { + goto error; + } + if (PyDict_SetItemString(result, "pre_config", dict) < 0) { + goto error; + } + Py_CLEAR(dict); + + /* core config */ + const PyConfig *config = &interp->config; + dict = config_as_dict(config); + if (dict == NULL) { + goto error; + } + if (PyDict_SetItemString(result, "config", dict) < 0) { + goto error; + } + Py_CLEAR(dict); + + return result; + +error: + Py_XDECREF(result); + Py_XDECREF(dict); + return NULL; +} + + +static void +init_dump_ascii_wstr(const wchar_t *str) +{ + if (str == NULL) { + PySys_WriteStderr("(not set)"); + return; + } + + PySys_WriteStderr("'"); + for (; *str != L'\0'; str++) { + unsigned int ch = (unsigned int)*str; + if (ch == L'\'') { + PySys_WriteStderr("\\'"); + } else if (0x20 <= ch && ch < 0x7f) { + PySys_WriteStderr("%c", ch); + } + else if (ch <= 0xff) { + PySys_WriteStderr("\\x%02x", ch); + } +#if SIZEOF_WCHAR_T > 2 + else if (ch > 0xffff) { + PySys_WriteStderr("\\U%08x", ch); + } +#endif + else { + PySys_WriteStderr("\\u%04x", ch); + } + } + PySys_WriteStderr("'"); +} + + +/* Dump the Python path configuration into sys.stderr */ +void +_Py_DumpPathConfig(PyThreadState *tstate) +{ + PyObject *exc_type, *exc_value, *exc_tb; + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + + PySys_WriteStderr("Python path configuration:\n"); + +#define DUMP_CONFIG(NAME, FIELD) \ + do { \ + PySys_WriteStderr(" " NAME " = "); \ + init_dump_ascii_wstr(config->FIELD); \ + PySys_WriteStderr("\n"); \ + } while (0) + + PyConfig *config = &tstate->interp->config; + DUMP_CONFIG("PYTHONHOME", home); + DUMP_CONFIG("PYTHONPATH", pythonpath_env); + DUMP_CONFIG("program name", program_name); + PySys_WriteStderr(" isolated = %i\n", config->isolated); + PySys_WriteStderr(" environment = %i\n", config->use_environment); + PySys_WriteStderr(" user site = %i\n", config->user_site_directory); + PySys_WriteStderr(" import site = %i\n", config->site_import); +#undef DUMP_CONFIG + +#define DUMP_SYS(NAME) \ + do { \ + obj = PySys_GetObject(#NAME); \ + PySys_FormatStderr(" sys.%s = ", #NAME); \ + if (obj != NULL) { \ + PySys_FormatStderr("%A", obj); \ + } \ + else { \ + PySys_WriteStderr("(not set)"); \ + } \ + PySys_FormatStderr("\n"); \ + } while (0) + + PyObject *obj; + DUMP_SYS(_base_executable); + DUMP_SYS(base_prefix); + DUMP_SYS(base_exec_prefix); + DUMP_SYS(executable); + DUMP_SYS(prefix); + DUMP_SYS(exec_prefix); +#undef DUMP_SYS + + PyObject *sys_path = PySys_GetObject("path"); /* borrowed reference */ + if (sys_path != NULL && PyList_Check(sys_path)) { + PySys_WriteStderr(" sys.path = [\n"); + Py_ssize_t len = PyList_GET_SIZE(sys_path); + for (Py_ssize_t i=0; i < len; i++) { + PyObject *path = PyList_GET_ITEM(sys_path, i); + PySys_FormatStderr(" %A,\n", path); + } + PySys_WriteStderr(" ]\n"); + } + + _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); +} diff --git a/python/Python/makeopcodetargets.py b/python/Python/makeopcodetargets.py new file mode 100755 index 0000000..023c9e6 --- /dev/null +++ b/python/Python/makeopcodetargets.py @@ -0,0 +1,55 @@ +#! /usr/bin/env python +"""Generate C code for the jump table of the threaded code interpreter +(for compilers supporting computed gotos or "labels-as-values", such as gcc). +""" + +import os +import sys + + +try: + from importlib.machinery import SourceFileLoader +except ImportError: + import imp + + def find_module(modname): + """Finds and returns a module in the local dist/checkout. + """ + modpath = os.path.join( + os.path.dirname(os.path.dirname(__file__)), "Lib") + return imp.load_module(modname, *imp.find_module(modname, [modpath])) +else: + def find_module(modname): + """Finds and returns a module in the local dist/checkout. + """ + modpath = os.path.join( + os.path.dirname(os.path.dirname(__file__)), "Lib", modname + ".py") + return SourceFileLoader(modname, modpath).load_module() + + +def write_contents(f): + """Write C code contents to the target file object. + """ + opcode = find_module('opcode') + targets = ['_unknown_opcode'] * 256 + for opname, op in opcode.opmap.items(): + targets[op] = "TARGET_%s" % opname + f.write("static void *opcode_targets[256] = {\n") + f.write(",\n".join([" &&%s" % s for s in targets])) + f.write("\n};\n") + + +def main(): + if len(sys.argv) >= 3: + sys.exit("Too many arguments") + if len(sys.argv) == 2: + target = sys.argv[1] + else: + target = "Python/opcode_targets.h" + with open(target, "w") as f: + write_contents(f) + print("Jump table written into %s" % target) + + +if __name__ == "__main__": + main() diff --git a/python/Python/marshal.c b/python/Python/marshal.c new file mode 100755 index 0000000..a9ba7a4 --- /dev/null +++ b/python/Python/marshal.c @@ -0,0 +1,1843 @@ + +/* Write Python objects to files and read them back. + This is primarily intended for writing and reading compiled Python code, + even though dicts, lists, sets and frozensets, not commonly seen in + code objects, are supported. + Version 3 of this protocol properly supports circular links + and sharing. */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "longintrepr.h" +#include "code.h" +#include "marshal.h" +#include "../Modules/hashtable.h" + +/*[clinic input] +module marshal +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]*/ + +#include "clinic/marshal.c.h" + +/* High water mark to determine when the marshalled object is dangerously deep + * and risks coring the interpreter. When the object stack gets this deep, + * raise an exception instead of continuing. + * On Windows debug builds, reduce this value. + * + * BUG: https://bugs.python.org/issue33720 + * On Windows PGO builds, the r_object function overallocates its stack and + * can cause a stack overflow. We reduce the maximum depth for all Windows + * releases to protect against this. + * #if defined(MS_WINDOWS) && defined(_DEBUG) + */ +#if defined(MS_WINDOWS) +#define MAX_MARSHAL_STACK_DEPTH 1000 +#else +#define MAX_MARSHAL_STACK_DEPTH 2000 +#endif + +#define TYPE_NULL '0' +#define TYPE_NONE 'N' +#define TYPE_FALSE 'F' +#define TYPE_TRUE 'T' +#define TYPE_STOPITER 'S' +#define TYPE_ELLIPSIS '.' +#define TYPE_INT 'i' +/* TYPE_INT64 is not generated anymore. + Supported for backward compatibility only. */ +#define TYPE_INT64 'I' +#define TYPE_FLOAT 'f' +#define TYPE_BINARY_FLOAT 'g' +#define TYPE_COMPLEX 'x' +#define TYPE_BINARY_COMPLEX 'y' +#define TYPE_LONG 'l' +#define TYPE_STRING 's' +#define TYPE_INTERNED 't' +#define TYPE_REF 'r' +#define TYPE_TUPLE '(' +#define TYPE_LIST '[' +#define TYPE_DICT '{' +#define TYPE_CODE 'c' +#define TYPE_UNICODE 'u' +#define TYPE_UNKNOWN '?' +#define TYPE_SET '<' +#define TYPE_FROZENSET '>' +#define FLAG_REF '\x80' /* with a type, add obj to index */ + +#define TYPE_ASCII 'a' +#define TYPE_ASCII_INTERNED 'A' +#define TYPE_SMALL_TUPLE ')' +#define TYPE_SHORT_ASCII 'z' +#define TYPE_SHORT_ASCII_INTERNED 'Z' + +#define WFERR_OK 0 +#define WFERR_UNMARSHALLABLE 1 +#define WFERR_NESTEDTOODEEP 2 +#define WFERR_NOMEMORY 3 + +typedef struct { + FILE *fp; + int error; /* see WFERR_* values */ + int depth; + PyObject *str; + char *ptr; + char *end; + char *buf; + _Py_hashtable_t *hashtable; + int version; +} WFILE; + +#define w_byte(c, p) do { \ + if ((p)->ptr != (p)->end || w_reserve((p), 1)) \ + *(p)->ptr++ = (c); \ + } while(0) + +static void +w_flush(WFILE *p) +{ + assert(p->fp != NULL); + fwrite(p->buf, 1, p->ptr - p->buf, p->fp); + p->ptr = p->buf; +} + +static int +w_reserve(WFILE *p, Py_ssize_t needed) +{ + Py_ssize_t pos, size, delta; + if (p->ptr == NULL) + return 0; /* An error already occurred */ + if (p->fp != NULL) { + w_flush(p); + return needed <= p->end - p->ptr; + } + assert(p->str != NULL); + pos = p->ptr - p->buf; + size = PyBytes_Size(p->str); + if (size > 16*1024*1024) + delta = (size >> 3); /* 12.5% overallocation */ + else + delta = size + 1024; + delta = Py_MAX(delta, needed); + if (delta > PY_SSIZE_T_MAX - size) { + p->error = WFERR_NOMEMORY; + return 0; + } + size += delta; + if (_PyBytes_Resize(&p->str, size) != 0) { + p->ptr = p->buf = p->end = NULL; + return 0; + } + else { + p->buf = PyBytes_AS_STRING(p->str); + p->ptr = p->buf + pos; + p->end = p->buf + size; + return 1; + } +} + +static void +w_string(const char *s, Py_ssize_t n, WFILE *p) +{ + Py_ssize_t m; + if (!n || p->ptr == NULL) + return; + m = p->end - p->ptr; + if (p->fp != NULL) { + if (n <= m) { + memcpy(p->ptr, s, n); + p->ptr += n; + } + else { + w_flush(p); + fwrite(s, 1, n, p->fp); + } + } + else { + if (n <= m || w_reserve(p, n - m)) { + memcpy(p->ptr, s, n); + p->ptr += n; + } + } +} + +static void +w_short(int x, WFILE *p) +{ + w_byte((char)( x & 0xff), p); + w_byte((char)((x>> 8) & 0xff), p); +} + +static void +w_long(long x, WFILE *p) +{ + w_byte((char)( x & 0xff), p); + w_byte((char)((x>> 8) & 0xff), p); + w_byte((char)((x>>16) & 0xff), p); + w_byte((char)((x>>24) & 0xff), p); +} + +#define SIZE32_MAX 0x7FFFFFFF + +#if SIZEOF_SIZE_T > 4 +# define W_SIZE(n, p) do { \ + if ((n) > SIZE32_MAX) { \ + (p)->depth--; \ + (p)->error = WFERR_UNMARSHALLABLE; \ + return; \ + } \ + w_long((long)(n), p); \ + } while(0) +#else +# define W_SIZE w_long +#endif + +static void +w_pstring(const char *s, Py_ssize_t n, WFILE *p) +{ + W_SIZE(n, p); + w_string(s, n, p); +} + +static void +w_short_pstring(const char *s, Py_ssize_t n, WFILE *p) +{ + w_byte(Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char), p); + w_string(s, n, p); +} + +/* We assume that Python ints are stored internally in base some power of + 2**15; for the sake of portability we'll always read and write them in base + exactly 2**15. */ + +#define PyLong_MARSHAL_SHIFT 15 +#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT) +#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1) +#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0 +#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT" +#endif +#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT) + +#define W_TYPE(t, p) do { \ + w_byte((t) | flag, (p)); \ +} while(0) + +static void +w_PyLong(const PyLongObject *ob, char flag, WFILE *p) +{ + Py_ssize_t i, j, n, l; + digit d; + + W_TYPE(TYPE_LONG, p); + if (Py_SIZE(ob) == 0) { + w_long((long)0, p); + return; + } + + /* set l to number of base PyLong_MARSHAL_BASE digits */ + n = Py_ABS(Py_SIZE(ob)); + l = (n-1) * PyLong_MARSHAL_RATIO; + d = ob->ob_digit[n-1]; + assert(d != 0); /* a PyLong is always normalized */ + do { + d >>= PyLong_MARSHAL_SHIFT; + l++; + } while (d != 0); + if (l > SIZE32_MAX) { + p->depth--; + p->error = WFERR_UNMARSHALLABLE; + return; + } + w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p); + + for (i=0; i < n-1; i++) { + d = ob->ob_digit[i]; + for (j=0; j < PyLong_MARSHAL_RATIO; j++) { + w_short(d & PyLong_MARSHAL_MASK, p); + d >>= PyLong_MARSHAL_SHIFT; + } + assert (d == 0); + } + d = ob->ob_digit[n-1]; + do { + w_short(d & PyLong_MARSHAL_MASK, p); + d >>= PyLong_MARSHAL_SHIFT; + } while (d != 0); +} + +static void +w_float_bin(double v, WFILE *p) +{ + unsigned char buf[8]; + if (_PyFloat_Pack8(v, buf, 1) < 0) { + p->error = WFERR_UNMARSHALLABLE; + return; + } + w_string((const char *)buf, 8, p); +} + +static void +w_float_str(double v, WFILE *p) +{ + int n; + char *buf = PyOS_double_to_string(v, 'g', 17, 0, NULL); + if (!buf) { + p->error = WFERR_NOMEMORY; + return; + } + n = (int)strlen(buf); + w_byte(n, p); + w_string(buf, n, p); + PyMem_Free(buf); +} + +static int +w_ref(PyObject *v, char *flag, WFILE *p) +{ + _Py_hashtable_entry_t *entry; + int w; + + if (p->version < 3 || p->hashtable == NULL) + return 0; /* not writing object references */ + + /* if it has only one reference, it definitely isn't shared */ + if (Py_REFCNT(v) == 1) + return 0; + + entry = _Py_HASHTABLE_GET_ENTRY(p->hashtable, v); + if (entry != NULL) { + /* write the reference index to the stream */ + _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, entry, w); + /* we don't store "long" indices in the dict */ + assert(0 <= w && w <= 0x7fffffff); + w_byte(TYPE_REF, p); + w_long(w, p); + return 1; + } else { + size_t s = p->hashtable->entries; + /* we don't support long indices */ + if (s >= 0x7fffffff) { + PyErr_SetString(PyExc_ValueError, "too many objects"); + goto err; + } + w = (int)s; + Py_INCREF(v); + if (_Py_HASHTABLE_SET(p->hashtable, v, w) < 0) { + Py_DECREF(v); + goto err; + } + *flag |= FLAG_REF; + return 0; + } +err: + p->error = WFERR_UNMARSHALLABLE; + return 1; +} + +static void +w_complex_object(PyObject *v, char flag, WFILE *p); + +static void +w_object(PyObject *v, WFILE *p) +{ + char flag = '\0'; + + p->depth++; + + if (p->depth > MAX_MARSHAL_STACK_DEPTH) { + p->error = WFERR_NESTEDTOODEEP; + } + else if (v == NULL) { + w_byte(TYPE_NULL, p); + } + else if (v == Py_None) { + w_byte(TYPE_NONE, p); + } + else if (v == PyExc_StopIteration) { + w_byte(TYPE_STOPITER, p); + } + else if (v == Py_Ellipsis) { + w_byte(TYPE_ELLIPSIS, p); + } + else if (v == Py_False) { + w_byte(TYPE_FALSE, p); + } + else if (v == Py_True) { + w_byte(TYPE_TRUE, p); + } + else if (!w_ref(v, &flag, p)) + w_complex_object(v, flag, p); + + p->depth--; +} + +static void +w_complex_object(PyObject *v, char flag, WFILE *p) +{ + Py_ssize_t i, n; + + if (PyLong_CheckExact(v)) { + long x = PyLong_AsLong(v); + if ((x == -1) && PyErr_Occurred()) { + PyLongObject *ob = (PyLongObject *)v; + PyErr_Clear(); + w_PyLong(ob, flag, p); + } + else { +#if SIZEOF_LONG > 4 + long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31); + if (y && y != -1) { + /* Too large for TYPE_INT */ + w_PyLong((PyLongObject*)v, flag, p); + } + else +#endif + { + W_TYPE(TYPE_INT, p); + w_long(x, p); + } + } + } + else if (PyFloat_CheckExact(v)) { + if (p->version > 1) { + W_TYPE(TYPE_BINARY_FLOAT, p); + w_float_bin(PyFloat_AS_DOUBLE(v), p); + } + else { + W_TYPE(TYPE_FLOAT, p); + w_float_str(PyFloat_AS_DOUBLE(v), p); + } + } + else if (PyComplex_CheckExact(v)) { + if (p->version > 1) { + W_TYPE(TYPE_BINARY_COMPLEX, p); + w_float_bin(PyComplex_RealAsDouble(v), p); + w_float_bin(PyComplex_ImagAsDouble(v), p); + } + else { + W_TYPE(TYPE_COMPLEX, p); + w_float_str(PyComplex_RealAsDouble(v), p); + w_float_str(PyComplex_ImagAsDouble(v), p); + } + } + else if (PyBytes_CheckExact(v)) { + W_TYPE(TYPE_STRING, p); + w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p); + } + else if (PyUnicode_CheckExact(v)) { + if (p->version >= 4 && PyUnicode_IS_ASCII(v)) { + int is_short = PyUnicode_GET_LENGTH(v) < 256; + if (is_short) { + if (PyUnicode_CHECK_INTERNED(v)) + W_TYPE(TYPE_SHORT_ASCII_INTERNED, p); + else + W_TYPE(TYPE_SHORT_ASCII, p); + w_short_pstring((char *) PyUnicode_1BYTE_DATA(v), + PyUnicode_GET_LENGTH(v), p); + } + else { + if (PyUnicode_CHECK_INTERNED(v)) + W_TYPE(TYPE_ASCII_INTERNED, p); + else + W_TYPE(TYPE_ASCII, p); + w_pstring((char *) PyUnicode_1BYTE_DATA(v), + PyUnicode_GET_LENGTH(v), p); + } + } + else { + PyObject *utf8; + utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass"); + if (utf8 == NULL) { + p->depth--; + p->error = WFERR_UNMARSHALLABLE; + return; + } + if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v)) + W_TYPE(TYPE_INTERNED, p); + else + W_TYPE(TYPE_UNICODE, p); + w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p); + Py_DECREF(utf8); + } + } + else if (PyTuple_CheckExact(v)) { + n = PyTuple_Size(v); + if (p->version >= 4 && n < 256) { + W_TYPE(TYPE_SMALL_TUPLE, p); + w_byte((unsigned char)n, p); + } + else { + W_TYPE(TYPE_TUPLE, p); + W_SIZE(n, p); + } + for (i = 0; i < n; i++) { + w_object(PyTuple_GET_ITEM(v, i), p); + } + } + else if (PyList_CheckExact(v)) { + W_TYPE(TYPE_LIST, p); + n = PyList_GET_SIZE(v); + W_SIZE(n, p); + for (i = 0; i < n; i++) { + w_object(PyList_GET_ITEM(v, i), p); + } + } + else if (PyDict_CheckExact(v)) { + Py_ssize_t pos; + PyObject *key, *value; + W_TYPE(TYPE_DICT, p); + /* This one is NULL object terminated! */ + pos = 0; + while (PyDict_Next(v, &pos, &key, &value)) { + w_object(key, p); + w_object(value, p); + } + w_object((PyObject *)NULL, p); + } + else if (PyAnySet_CheckExact(v)) { + PyObject *value, *it; + + if (PyObject_TypeCheck(v, &PySet_Type)) + W_TYPE(TYPE_SET, p); + else + W_TYPE(TYPE_FROZENSET, p); + n = PyObject_Size(v); + if (n == -1) { + p->depth--; + p->error = WFERR_UNMARSHALLABLE; + return; + } + W_SIZE(n, p); + it = PyObject_GetIter(v); + if (it == NULL) { + p->depth--; + p->error = WFERR_UNMARSHALLABLE; + return; + } + while ((value = PyIter_Next(it)) != NULL) { + w_object(value, p); + Py_DECREF(value); + } + Py_DECREF(it); + if (PyErr_Occurred()) { + p->depth--; + p->error = WFERR_UNMARSHALLABLE; + return; + } + } + else if (PyCode_Check(v)) { + PyCodeObject *co = (PyCodeObject *)v; + W_TYPE(TYPE_CODE, p); + w_long(co->co_argcount, p); + w_long(co->co_posonlyargcount, p); + w_long(co->co_kwonlyargcount, p); + w_long(co->co_nlocals, p); + w_long(co->co_stacksize, p); + w_long(co->co_flags, p); + w_object(co->co_code, p); + w_object(co->co_consts, p); + w_object(co->co_names, p); + w_object(co->co_varnames, p); + w_object(co->co_freevars, p); + w_object(co->co_cellvars, p); + w_object(co->co_filename, p); + w_object(co->co_name, p); + w_long(co->co_firstlineno, p); + w_object(co->co_lnotab, p); + } + else if (PyObject_CheckBuffer(v)) { + /* Write unknown bytes-like objects as a bytes object */ + Py_buffer view; + if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) { + w_byte(TYPE_UNKNOWN, p); + p->depth--; + p->error = WFERR_UNMARSHALLABLE; + return; + } + W_TYPE(TYPE_STRING, p); + w_pstring(view.buf, view.len, p); + PyBuffer_Release(&view); + } + else { + W_TYPE(TYPE_UNKNOWN, p); + p->error = WFERR_UNMARSHALLABLE; + } +} + +static int +w_init_refs(WFILE *wf, int version) +{ + if (version >= 3) { + wf->hashtable = _Py_hashtable_new(sizeof(PyObject *), sizeof(int), + _Py_hashtable_hash_ptr, + _Py_hashtable_compare_direct); + if (wf->hashtable == NULL) { + PyErr_NoMemory(); + return -1; + } + } + return 0; +} + +static int +w_decref_entry(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, + void *Py_UNUSED(data)) +{ + PyObject *entry_key; + + _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, entry_key); + Py_XDECREF(entry_key); + return 0; +} + +static void +w_clear_refs(WFILE *wf) +{ + if (wf->hashtable != NULL) { + _Py_hashtable_foreach(wf->hashtable, w_decref_entry, NULL); + _Py_hashtable_destroy(wf->hashtable); + } +} + +/* version currently has no effect for writing ints. */ +void +PyMarshal_WriteLongToFile(long x, FILE *fp, int version) +{ + char buf[4]; + WFILE wf; + memset(&wf, 0, sizeof(wf)); + wf.fp = fp; + wf.ptr = wf.buf = buf; + wf.end = wf.ptr + sizeof(buf); + wf.error = WFERR_OK; + wf.version = version; + w_long(x, &wf); + w_flush(&wf); +} + +void +PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version) +{ + char buf[BUFSIZ]; + WFILE wf; + memset(&wf, 0, sizeof(wf)); + wf.fp = fp; + wf.ptr = wf.buf = buf; + wf.end = wf.ptr + sizeof(buf); + wf.error = WFERR_OK; + wf.version = version; + if (w_init_refs(&wf, version)) + return; /* caller mush check PyErr_Occurred() */ + w_object(x, &wf); + w_clear_refs(&wf); + w_flush(&wf); +} + +typedef struct { + FILE *fp; + int depth; + PyObject *readable; /* Stream-like object being read from */ + char *ptr; + char *end; + char *buf; + Py_ssize_t buf_size; + PyObject *refs; /* a list */ +} RFILE; + +static const char * +r_string(Py_ssize_t n, RFILE *p) +{ + Py_ssize_t read = -1; + + if (p->ptr != NULL) { + /* Fast path for loads() */ + char *res = p->ptr; + Py_ssize_t left = p->end - p->ptr; + if (left < n) { + PyErr_SetString(PyExc_EOFError, + "marshal data too short"); + return NULL; + } + p->ptr += n; + return res; + } + if (p->buf == NULL) { + p->buf = PyMem_MALLOC(n); + if (p->buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + p->buf_size = n; + } + else if (p->buf_size < n) { + char *tmp = PyMem_REALLOC(p->buf, n); + if (tmp == NULL) { + PyErr_NoMemory(); + return NULL; + } + p->buf = tmp; + p->buf_size = n; + } + + if (!p->readable) { + assert(p->fp != NULL); + read = fread(p->buf, 1, n, p->fp); + } + else { + _Py_IDENTIFIER(readinto); + PyObject *res, *mview; + Py_buffer buf; + + if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1) + return NULL; + mview = PyMemoryView_FromBuffer(&buf); + if (mview == NULL) + return NULL; + + res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview); + if (res != NULL) { + read = PyNumber_AsSsize_t(res, PyExc_ValueError); + Py_DECREF(res); + } + } + if (read != n) { + if (!PyErr_Occurred()) { + if (read > n) + PyErr_Format(PyExc_ValueError, + "read() returned too much data: " + "%zd bytes requested, %zd returned", + n, read); + else + PyErr_SetString(PyExc_EOFError, + "EOF read where not expected"); + } + return NULL; + } + return p->buf; +} + +static int +r_byte(RFILE *p) +{ + int c = EOF; + + if (p->ptr != NULL) { + if (p->ptr < p->end) + c = (unsigned char) *p->ptr++; + return c; + } + if (!p->readable) { + assert(p->fp); + c = getc(p->fp); + } + else { + const char *ptr = r_string(1, p); + if (ptr != NULL) + c = *(const unsigned char *) ptr; + } + return c; +} + +static int +r_short(RFILE *p) +{ + short x = -1; + const unsigned char *buffer; + + buffer = (const unsigned char *) r_string(2, p); + if (buffer != NULL) { + x = buffer[0]; + x |= buffer[1] << 8; + /* Sign-extension, in case short greater than 16 bits */ + x |= -(x & 0x8000); + } + return x; +} + +static long +r_long(RFILE *p) +{ + long x = -1; + const unsigned char *buffer; + + buffer = (const unsigned char *) r_string(4, p); + if (buffer != NULL) { + x = buffer[0]; + x |= (long)buffer[1] << 8; + x |= (long)buffer[2] << 16; + x |= (long)buffer[3] << 24; +#if SIZEOF_LONG > 4 + /* Sign extension for 64-bit machines */ + x |= -(x & 0x80000000L); +#endif + } + return x; +} + +/* r_long64 deals with the TYPE_INT64 code. */ +static PyObject * +r_long64(RFILE *p) +{ + const unsigned char *buffer = (const unsigned char *) r_string(8, p); + if (buffer == NULL) { + return NULL; + } + return _PyLong_FromByteArray(buffer, 8, + 1 /* little endian */, + 1 /* signed */); +} + +static PyObject * +r_PyLong(RFILE *p) +{ + PyLongObject *ob; + long n, size, i; + int j, md, shorts_in_top_digit; + digit d; + + n = r_long(p); + if (PyErr_Occurred()) + return NULL; + if (n == 0) + return (PyObject *)_PyLong_New(0); + if (n < -SIZE32_MAX || n > SIZE32_MAX) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (long size out of range)"); + return NULL; + } + + size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO; + shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO; + ob = _PyLong_New(size); + if (ob == NULL) + return NULL; + + Py_SIZE(ob) = n > 0 ? size : -size; + + for (i = 0; i < size-1; i++) { + d = 0; + for (j=0; j < PyLong_MARSHAL_RATIO; j++) { + md = r_short(p); + if (PyErr_Occurred()) { + Py_DECREF(ob); + return NULL; + } + if (md < 0 || md > PyLong_MARSHAL_BASE) + goto bad_digit; + d += (digit)md << j*PyLong_MARSHAL_SHIFT; + } + ob->ob_digit[i] = d; + } + + d = 0; + for (j=0; j < shorts_in_top_digit; j++) { + md = r_short(p); + if (PyErr_Occurred()) { + Py_DECREF(ob); + return NULL; + } + if (md < 0 || md > PyLong_MARSHAL_BASE) + goto bad_digit; + /* topmost marshal digit should be nonzero */ + if (md == 0 && j == shorts_in_top_digit - 1) { + Py_DECREF(ob); + PyErr_SetString(PyExc_ValueError, + "bad marshal data (unnormalized long data)"); + return NULL; + } + d += (digit)md << j*PyLong_MARSHAL_SHIFT; + } + if (PyErr_Occurred()) { + Py_DECREF(ob); + return NULL; + } + /* top digit should be nonzero, else the resulting PyLong won't be + normalized */ + ob->ob_digit[size-1] = d; + return (PyObject *)ob; + bad_digit: + Py_DECREF(ob); + PyErr_SetString(PyExc_ValueError, + "bad marshal data (digit out of range in long)"); + return NULL; +} + +static double +r_float_bin(RFILE *p) +{ + const unsigned char *buf = (const unsigned char *) r_string(8, p); + if (buf == NULL) + return -1; + return _PyFloat_Unpack8(buf, 1); +} + +/* Issue #33720: Disable inlining for reducing the C stack consumption + on PGO builds. */ +_Py_NO_INLINE static double +r_float_str(RFILE *p) +{ + int n; + char buf[256]; + const char *ptr; + n = r_byte(p); + if (n == EOF) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return -1; + } + ptr = r_string(n, p); + if (ptr == NULL) { + return -1; + } + memcpy(buf, ptr, n); + buf[n] = '\0'; + return PyOS_string_to_double(buf, NULL, NULL); +} + +/* allocate the reflist index for a new object. Return -1 on failure */ +static Py_ssize_t +r_ref_reserve(int flag, RFILE *p) +{ + if (flag) { /* currently only FLAG_REF is defined */ + Py_ssize_t idx = PyList_GET_SIZE(p->refs); + if (idx >= 0x7ffffffe) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)"); + return -1; + } + if (PyList_Append(p->refs, Py_None) < 0) + return -1; + return idx; + } else + return 0; +} + +/* insert the new object 'o' to the reflist at previously + * allocated index 'idx'. + * 'o' can be NULL, in which case nothing is done. + * if 'o' was non-NULL, and the function succeeds, 'o' is returned. + * if 'o' was non-NULL, and the function fails, 'o' is released and + * NULL returned. This simplifies error checking at the call site since + * a single test for NULL for the function result is enough. + */ +static PyObject * +r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p) +{ + if (o != NULL && flag) { /* currently only FLAG_REF is defined */ + PyObject *tmp = PyList_GET_ITEM(p->refs, idx); + Py_INCREF(o); + PyList_SET_ITEM(p->refs, idx, o); + Py_DECREF(tmp); + } + return o; +} + +/* combination of both above, used when an object can be + * created whenever it is seen in the file, as opposed to + * after having loaded its sub-objects. + */ +static PyObject * +r_ref(PyObject *o, int flag, RFILE *p) +{ + assert(flag & FLAG_REF); + if (o == NULL) + return NULL; + if (PyList_Append(p->refs, o) < 0) { + Py_DECREF(o); /* release the new object */ + return NULL; + } + return o; +} + +static PyObject * +r_object(RFILE *p) +{ + /* NULL is a valid return value, it does not necessarily means that + an exception is set. */ + PyObject *v, *v2; + Py_ssize_t idx = 0; + long i, n; + int type, code = r_byte(p); + int flag, is_interned = 0; + PyObject *retval = NULL; + + if (code == EOF) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + return NULL; + } + + p->depth++; + + if (p->depth > MAX_MARSHAL_STACK_DEPTH) { + p->depth--; + PyErr_SetString(PyExc_ValueError, "recursion limit exceeded"); + return NULL; + } + + flag = code & FLAG_REF; + type = code & ~FLAG_REF; + +#define R_REF(O) do{\ + if (flag) \ + O = r_ref(O, flag, p);\ +} while (0) + + switch (type) { + + case TYPE_NULL: + break; + + case TYPE_NONE: + Py_INCREF(Py_None); + retval = Py_None; + break; + + case TYPE_STOPITER: + Py_INCREF(PyExc_StopIteration); + retval = PyExc_StopIteration; + break; + + case TYPE_ELLIPSIS: + Py_INCREF(Py_Ellipsis); + retval = Py_Ellipsis; + break; + + case TYPE_FALSE: + Py_INCREF(Py_False); + retval = Py_False; + break; + + case TYPE_TRUE: + Py_INCREF(Py_True); + retval = Py_True; + break; + + case TYPE_INT: + n = r_long(p); + retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n); + R_REF(retval); + break; + + case TYPE_INT64: + retval = r_long64(p); + R_REF(retval); + break; + + case TYPE_LONG: + retval = r_PyLong(p); + R_REF(retval); + break; + + case TYPE_FLOAT: + { + double x = r_float_str(p); + if (x == -1.0 && PyErr_Occurred()) + break; + retval = PyFloat_FromDouble(x); + R_REF(retval); + break; + } + + case TYPE_BINARY_FLOAT: + { + double x = r_float_bin(p); + if (x == -1.0 && PyErr_Occurred()) + break; + retval = PyFloat_FromDouble(x); + R_REF(retval); + break; + } + + case TYPE_COMPLEX: + { + Py_complex c; + c.real = r_float_str(p); + if (c.real == -1.0 && PyErr_Occurred()) + break; + c.imag = r_float_str(p); + if (c.imag == -1.0 && PyErr_Occurred()) + break; + retval = PyComplex_FromCComplex(c); + R_REF(retval); + break; + } + + case TYPE_BINARY_COMPLEX: + { + Py_complex c; + c.real = r_float_bin(p); + if (c.real == -1.0 && PyErr_Occurred()) + break; + c.imag = r_float_bin(p); + if (c.imag == -1.0 && PyErr_Occurred()) + break; + retval = PyComplex_FromCComplex(c); + R_REF(retval); + break; + } + + case TYPE_STRING: + { + const char *ptr; + n = r_long(p); + if (PyErr_Occurred()) + break; + if (n < 0 || n > SIZE32_MAX) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)"); + break; + } + v = PyBytes_FromStringAndSize((char *)NULL, n); + if (v == NULL) + break; + ptr = r_string(n, p); + if (ptr == NULL) { + Py_DECREF(v); + break; + } + memcpy(PyBytes_AS_STRING(v), ptr, n); + retval = v; + R_REF(retval); + break; + } + + case TYPE_ASCII_INTERNED: + is_interned = 1; + /* fall through */ + case TYPE_ASCII: + n = r_long(p); + if (PyErr_Occurred()) + break; + if (n < 0 || n > SIZE32_MAX) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); + break; + } + goto _read_ascii; + + case TYPE_SHORT_ASCII_INTERNED: + is_interned = 1; + /* fall through */ + case TYPE_SHORT_ASCII: + n = r_byte(p); + if (n == EOF) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + break; + } + _read_ascii: + { + const char *ptr; + ptr = r_string(n, p); + if (ptr == NULL) + break; + v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n); + if (v == NULL) + break; + if (is_interned) + PyUnicode_InternInPlace(&v); + retval = v; + R_REF(retval); + break; + } + + case TYPE_INTERNED: + is_interned = 1; + /* fall through */ + case TYPE_UNICODE: + { + const char *buffer; + + n = r_long(p); + if (PyErr_Occurred()) + break; + if (n < 0 || n > SIZE32_MAX) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); + break; + } + if (n != 0) { + buffer = r_string(n, p); + if (buffer == NULL) + break; + v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass"); + } + else { + v = PyUnicode_New(0, 0); + } + if (v == NULL) + break; + if (is_interned) + PyUnicode_InternInPlace(&v); + retval = v; + R_REF(retval); + break; + } + + case TYPE_SMALL_TUPLE: + n = (unsigned char) r_byte(p); + if (PyErr_Occurred()) + break; + goto _read_tuple; + case TYPE_TUPLE: + n = r_long(p); + if (PyErr_Occurred()) + break; + if (n < 0 || n > SIZE32_MAX) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)"); + break; + } + _read_tuple: + v = PyTuple_New(n); + R_REF(v); + if (v == NULL) + break; + + for (i = 0; i < n; i++) { + v2 = r_object(p); + if ( v2 == NULL ) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "NULL object in marshal data for tuple"); + Py_DECREF(v); + v = NULL; + break; + } + PyTuple_SET_ITEM(v, i, v2); + } + retval = v; + break; + + case TYPE_LIST: + n = r_long(p); + if (PyErr_Occurred()) + break; + if (n < 0 || n > SIZE32_MAX) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)"); + break; + } + v = PyList_New(n); + R_REF(v); + if (v == NULL) + break; + for (i = 0; i < n; i++) { + v2 = r_object(p); + if ( v2 == NULL ) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "NULL object in marshal data for list"); + Py_DECREF(v); + v = NULL; + break; + } + PyList_SET_ITEM(v, i, v2); + } + retval = v; + break; + + case TYPE_DICT: + v = PyDict_New(); + R_REF(v); + if (v == NULL) + break; + for (;;) { + PyObject *key, *val; + key = r_object(p); + if (key == NULL) + break; + val = r_object(p); + if (val == NULL) { + Py_DECREF(key); + break; + } + if (PyDict_SetItem(v, key, val) < 0) { + Py_DECREF(key); + Py_DECREF(val); + break; + } + Py_DECREF(key); + Py_DECREF(val); + } + if (PyErr_Occurred()) { + Py_DECREF(v); + v = NULL; + } + retval = v; + break; + + case TYPE_SET: + case TYPE_FROZENSET: + n = r_long(p); + if (PyErr_Occurred()) + break; + if (n < 0 || n > SIZE32_MAX) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)"); + break; + } + + if (n == 0 && type == TYPE_FROZENSET) { + /* call frozenset() to get the empty frozenset singleton */ + v = _PyObject_CallNoArg((PyObject*)&PyFrozenSet_Type); + if (v == NULL) + break; + R_REF(v); + retval = v; + } + else { + v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); + if (type == TYPE_SET) { + R_REF(v); + } else { + /* must use delayed registration of frozensets because they must + * be init with a refcount of 1 + */ + idx = r_ref_reserve(flag, p); + if (idx < 0) + Py_CLEAR(v); /* signal error */ + } + if (v == NULL) + break; + + for (i = 0; i < n; i++) { + v2 = r_object(p); + if ( v2 == NULL ) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "NULL object in marshal data for set"); + Py_DECREF(v); + v = NULL; + break; + } + if (PySet_Add(v, v2) == -1) { + Py_DECREF(v); + Py_DECREF(v2); + v = NULL; + break; + } + Py_DECREF(v2); + } + if (type != TYPE_SET) + v = r_ref_insert(v, idx, flag, p); + retval = v; + } + break; + + case TYPE_CODE: + { + int argcount; + int posonlyargcount; + int kwonlyargcount; + int nlocals; + int stacksize; + int flags; + PyObject *code = NULL; + PyObject *consts = NULL; + PyObject *names = NULL; + PyObject *varnames = NULL; + PyObject *freevars = NULL; + PyObject *cellvars = NULL; + PyObject *filename = NULL; + PyObject *name = NULL; + int firstlineno; + PyObject *lnotab = NULL; + + idx = r_ref_reserve(flag, p); + if (idx < 0) + break; + + v = NULL; + + /* XXX ignore long->int overflows for now */ + argcount = (int)r_long(p); + if (PyErr_Occurred()) + goto code_error; + posonlyargcount = (int)r_long(p); + if (PyErr_Occurred()) { + goto code_error; + } + kwonlyargcount = (int)r_long(p); + if (PyErr_Occurred()) + goto code_error; + nlocals = (int)r_long(p); + if (PyErr_Occurred()) + goto code_error; + stacksize = (int)r_long(p); + if (PyErr_Occurred()) + goto code_error; + flags = (int)r_long(p); + if (PyErr_Occurred()) + goto code_error; + code = r_object(p); + if (code == NULL) + goto code_error; + consts = r_object(p); + if (consts == NULL) + goto code_error; + names = r_object(p); + if (names == NULL) + goto code_error; + varnames = r_object(p); + if (varnames == NULL) + goto code_error; + freevars = r_object(p); + if (freevars == NULL) + goto code_error; + cellvars = r_object(p); + if (cellvars == NULL) + goto code_error; + filename = r_object(p); + if (filename == NULL) + goto code_error; + name = r_object(p); + if (name == NULL) + goto code_error; + firstlineno = (int)r_long(p); + if (firstlineno == -1 && PyErr_Occurred()) + break; + lnotab = r_object(p); + if (lnotab == NULL) + goto code_error; + + if (PySys_Audit("code.__new__", "OOOiiiiii", + code, filename, name, argcount, posonlyargcount, + kwonlyargcount, nlocals, stacksize, flags) < 0) { + goto code_error; + } + + v = (PyObject *) PyCode_NewWithPosOnlyArgs( + argcount, posonlyargcount, kwonlyargcount, + nlocals, stacksize, flags, + code, consts, names, varnames, + freevars, cellvars, filename, name, + firstlineno, lnotab); + v = r_ref_insert(v, idx, flag, p); + + code_error: + Py_XDECREF(code); + Py_XDECREF(consts); + Py_XDECREF(names); + Py_XDECREF(varnames); + Py_XDECREF(freevars); + Py_XDECREF(cellvars); + Py_XDECREF(filename); + Py_XDECREF(name); + Py_XDECREF(lnotab); + } + retval = v; + break; + + case TYPE_REF: + n = r_long(p); + if (n < 0 || n >= PyList_GET_SIZE(p->refs)) { + if (n == -1 && PyErr_Occurred()) + break; + PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); + break; + } + v = PyList_GET_ITEM(p->refs, n); + if (v == Py_None) { + PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); + break; + } + Py_INCREF(v); + retval = v; + break; + + default: + /* Bogus data got written, which isn't ideal. + This will let you keep working and recover. */ + PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)"); + break; + + } + p->depth--; + return retval; +} + +static PyObject * +read_object(RFILE *p) +{ + PyObject *v; + if (PyErr_Occurred()) { + fprintf(stderr, "XXX readobject called with exception set\n"); + return NULL; + } + v = r_object(p); + if (v == NULL && !PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object"); + return v; +} + +int +PyMarshal_ReadShortFromFile(FILE *fp) +{ + RFILE rf; + int res; + assert(fp); + rf.readable = NULL; + rf.fp = fp; + rf.end = rf.ptr = NULL; + rf.buf = NULL; + res = r_short(&rf); + if (rf.buf != NULL) + PyMem_FREE(rf.buf); + return res; +} + +long +PyMarshal_ReadLongFromFile(FILE *fp) +{ + RFILE rf; + long res; + rf.fp = fp; + rf.readable = NULL; + rf.ptr = rf.end = NULL; + rf.buf = NULL; + res = r_long(&rf); + if (rf.buf != NULL) + PyMem_FREE(rf.buf); + return res; +} + +/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */ +static off_t +getfilesize(FILE *fp) +{ + struct _Py_stat_struct st; + if (_Py_fstat_noraise(fileno(fp), &st) != 0) + return -1; +#if SIZEOF_OFF_T == 4 + else if (st.st_size >= INT_MAX) + return (off_t)INT_MAX; +#endif + else + return (off_t)st.st_size; +} + +/* If we can get the size of the file up-front, and it's reasonably small, + * read it in one gulp and delegate to ...FromString() instead. Much quicker + * than reading a byte at a time from file; speeds .pyc imports. + * CAUTION: since this may read the entire remainder of the file, don't + * call it unless you know you're done with the file. + */ +PyObject * +PyMarshal_ReadLastObjectFromFile(FILE *fp) +{ +/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */ +#define REASONABLE_FILE_LIMIT (1L << 18) + off_t filesize; + filesize = getfilesize(fp); + if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) { + char* pBuf = (char *)PyMem_MALLOC(filesize); + if (pBuf != NULL) { + size_t n = fread(pBuf, 1, (size_t)filesize, fp); + PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n); + PyMem_FREE(pBuf); + return v; + } + + } + /* We don't have fstat, or we do but the file is larger than + * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time. + */ + return PyMarshal_ReadObjectFromFile(fp); + +#undef REASONABLE_FILE_LIMIT +} + +PyObject * +PyMarshal_ReadObjectFromFile(FILE *fp) +{ + RFILE rf; + PyObject *result; + rf.fp = fp; + rf.readable = NULL; + rf.depth = 0; + rf.ptr = rf.end = NULL; + rf.buf = NULL; + rf.refs = PyList_New(0); + if (rf.refs == NULL) + return NULL; + result = r_object(&rf); + Py_DECREF(rf.refs); + if (rf.buf != NULL) + PyMem_FREE(rf.buf); + return result; +} + +PyObject * +PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len) +{ + RFILE rf; + PyObject *result; + rf.fp = NULL; + rf.readable = NULL; + rf.ptr = (char *)str; + rf.end = (char *)str + len; + rf.buf = NULL; + rf.depth = 0; + rf.refs = PyList_New(0); + if (rf.refs == NULL) + return NULL; + result = r_object(&rf); + Py_DECREF(rf.refs); + if (rf.buf != NULL) + PyMem_FREE(rf.buf); + return result; +} + +PyObject * +PyMarshal_WriteObjectToString(PyObject *x, int version) +{ + WFILE wf; + + memset(&wf, 0, sizeof(wf)); + wf.str = PyBytes_FromStringAndSize((char *)NULL, 50); + if (wf.str == NULL) + return NULL; + wf.ptr = wf.buf = PyBytes_AS_STRING((PyBytesObject *)wf.str); + wf.end = wf.ptr + PyBytes_Size(wf.str); + wf.error = WFERR_OK; + wf.version = version; + if (w_init_refs(&wf, version)) { + Py_DECREF(wf.str); + return NULL; + } + w_object(x, &wf); + w_clear_refs(&wf); + if (wf.str != NULL) { + char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str); + if (wf.ptr - base > PY_SSIZE_T_MAX) { + Py_DECREF(wf.str); + PyErr_SetString(PyExc_OverflowError, + "too much marshal data for a bytes object"); + return NULL; + } + if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0) + return NULL; + } + if (wf.error != WFERR_OK) { + Py_XDECREF(wf.str); + if (wf.error == WFERR_NOMEMORY) + PyErr_NoMemory(); + else + PyErr_SetString(PyExc_ValueError, + (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object" + :"object too deeply nested to marshal"); + return NULL; + } + return wf.str; +} + +/* And an interface for Python programs... */ +/*[clinic input] +marshal.dump + + value: object + Must be a supported type. + file: object + Must be a writeable binary file. + version: int(c_default="Py_MARSHAL_VERSION") = version + Indicates the data format that dump should use. + / + +Write the value on the open file. + +If the value has (or contains an object that has) an unsupported type, a +ValueError exception is raised - but garbage data will also be written +to the file. The object will not be properly read back by load(). +[clinic start generated code]*/ + +static PyObject * +marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file, + int version) +/*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/ +{ + /* XXX Quick hack -- need to do this differently */ + PyObject *s; + PyObject *res; + _Py_IDENTIFIER(write); + + s = PyMarshal_WriteObjectToString(value, version); + if (s == NULL) + return NULL; + res = _PyObject_CallMethodIdObjArgs(file, &PyId_write, s, NULL); + Py_DECREF(s); + return res; +} + +/*[clinic input] +marshal.load + + file: object + Must be readable binary file. + / + +Read one value from the open file and return it. + +If no valid value is read (e.g. because the data has a different Python +version's incompatible marshal format), raise EOFError, ValueError or +TypeError. + +Note: If an object containing an unsupported type was marshalled with +dump(), load() will substitute None for the unmarshallable type. +[clinic start generated code]*/ + +static PyObject * +marshal_load(PyObject *module, PyObject *file) +/*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/ +{ + PyObject *data, *result; + _Py_IDENTIFIER(read); + RFILE rf; + + /* + * Make a call to the read method, but read zero bytes. + * This is to ensure that the object passed in at least + * has a read method which returns bytes. + * This can be removed if we guarantee good error handling + * for r_string() + */ + data = _PyObject_CallMethodId(file, &PyId_read, "i", 0); + if (data == NULL) + return NULL; + if (!PyBytes_Check(data)) { + PyErr_Format(PyExc_TypeError, + "file.read() returned not bytes but %.100s", + data->ob_type->tp_name); + result = NULL; + } + else { + rf.depth = 0; + rf.fp = NULL; + rf.readable = file; + rf.ptr = rf.end = NULL; + rf.buf = NULL; + if ((rf.refs = PyList_New(0)) != NULL) { + result = read_object(&rf); + Py_DECREF(rf.refs); + if (rf.buf != NULL) + PyMem_FREE(rf.buf); + } else + result = NULL; + } + Py_DECREF(data); + return result; +} + +/*[clinic input] +marshal.dumps + + value: object + Must be a supported type. + version: int(c_default="Py_MARSHAL_VERSION") = version + Indicates the data format that dumps should use. + / + +Return the bytes object that would be written to a file by dump(value, file). + +Raise a ValueError exception if value has (or contains an object that has) an +unsupported type. +[clinic start generated code]*/ + +static PyObject * +marshal_dumps_impl(PyObject *module, PyObject *value, int version) +/*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/ +{ + return PyMarshal_WriteObjectToString(value, version); +} + +/*[clinic input] +marshal.loads + + bytes: Py_buffer + / + +Convert the bytes-like object to a value. + +If no valid value is found, raise EOFError, ValueError or TypeError. Extra +bytes in the input are ignored. +[clinic start generated code]*/ + +static PyObject * +marshal_loads_impl(PyObject *module, Py_buffer *bytes) +/*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/ +{ + RFILE rf; + char *s = bytes->buf; + Py_ssize_t n = bytes->len; + PyObject* result; + rf.fp = NULL; + rf.readable = NULL; + rf.ptr = s; + rf.end = s + n; + rf.depth = 0; + if ((rf.refs = PyList_New(0)) == NULL) + return NULL; + result = read_object(&rf); + Py_DECREF(rf.refs); + return result; +} + +static PyMethodDef marshal_methods[] = { + MARSHAL_DUMP_METHODDEF + MARSHAL_LOAD_METHODDEF + MARSHAL_DUMPS_METHODDEF + MARSHAL_LOADS_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +PyDoc_STRVAR(module_doc, +"This module contains functions that can read and write Python values in\n\ +a binary format. The format is specific to Python, but independent of\n\ +machine architecture issues.\n\ +\n\ +Not all Python object types are supported; in general, only objects\n\ +whose value is independent from a particular invocation of Python can be\n\ +written and read by this module. The following types are supported:\n\ +None, integers, floating point numbers, strings, bytes, bytearrays,\n\ +tuples, lists, sets, dictionaries, and code objects, where it\n\ +should be understood that tuples, lists and dictionaries are only\n\ +supported as long as the values contained therein are themselves\n\ +supported; and recursive lists and dictionaries should not be written\n\ +(they will cause infinite loops).\n\ +\n\ +Variables:\n\ +\n\ +version -- indicates the format that the module uses. Version 0 is the\n\ + historical format, version 1 shares interned strings and version 2\n\ + uses a binary format for floating point numbers.\n\ + Version 3 shares common object references (New in version 3.4).\n\ +\n\ +Functions:\n\ +\n\ +dump() -- write value to a file\n\ +load() -- read value from a file\n\ +dumps() -- marshal value as a bytes object\n\ +loads() -- read value from a bytes-like object"); + + + +static struct PyModuleDef marshalmodule = { + PyModuleDef_HEAD_INIT, + "marshal", + module_doc, + 0, + marshal_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyMarshal_Init(void) +{ + PyObject *mod = PyModule_Create(&marshalmodule); + if (mod == NULL) + return NULL; + if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { + Py_DECREF(mod); + return NULL; + } + return mod; +} diff --git a/python/Python/modsupport.c b/python/Python/modsupport.c new file mode 100755 index 0000000..5062811 --- /dev/null +++ b/python/Python/modsupport.c @@ -0,0 +1,683 @@ + +/* Module support implementation */ + +#include "Python.h" + +#define FLAG_SIZE_T 1 +typedef double va_double; + +static PyObject *va_build_value(const char *, va_list, int); +static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); + +/* Package context -- the full module name for package imports */ +const char *_Py_PackageContext = NULL; + + +int +_Py_convert_optional_to_ssize_t(PyObject *obj, void *result) +{ + Py_ssize_t limit; + if (obj == Py_None) { + return 1; + } + else if (PyIndex_Check(obj)) { + limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); + if (limit == -1 && PyErr_Occurred()) { + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "argument should be integer or None, not '%.200s'", + Py_TYPE(obj)->tp_name); + return 0; + } + *((Py_ssize_t *)result) = limit; + return 1; +} + + +/* Helper for mkvalue() to scan the length of a format */ + +static Py_ssize_t +countformat(const char *format, char endchar) +{ + Py_ssize_t count = 0; + int level = 0; + while (level > 0 || *format != endchar) { + switch (*format) { + case '\0': + /* Premature end */ + PyErr_SetString(PyExc_SystemError, + "unmatched paren in format"); + return -1; + case '(': + case '[': + case '{': + if (level == 0) { + count++; + } + level++; + break; + case ')': + case ']': + case '}': + level--; + break; + case '#': + case '&': + case ',': + case ':': + case ' ': + case '\t': + break; + default: + if (level == 0) { + count++; + } + } + format++; + } + return count; +} + + +/* Generic function to create a value -- the inverse of getargs() */ +/* After an original idea and first implementation by Steven Miale */ + +static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t, int); +static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int); +static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int); +static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int); +static PyObject *do_mkvalue(const char**, va_list *, int); + + +static void +do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *v; + Py_ssize_t i; + assert(PyErr_Occurred()); + v = PyTuple_New(n); + for (i = 0; i < n; i++) { + PyObject *exception, *value, *tb, *w; + + PyErr_Fetch(&exception, &value, &tb); + w = do_mkvalue(p_format, p_va, flags); + PyErr_Restore(exception, value, tb); + if (w != NULL) { + if (v != NULL) { + PyTuple_SET_ITEM(v, i, w); + } + else { + Py_DECREF(w); + } + } + } + Py_XDECREF(v); + if (**p_format != endchar) { + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return; + } + if (endchar) { + ++*p_format; + } +} + +static PyObject * +do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *d; + Py_ssize_t i; + if (n < 0) + return NULL; + if (n % 2) { + PyErr_SetString(PyExc_SystemError, + "Bad dict format"); + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ + if ((d = PyDict_New()) == NULL) { + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + for (i = 0; i < n; i+= 2) { + PyObject *k, *v; + + k = do_mkvalue(p_format, p_va, flags); + if (k == NULL) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + Py_DECREF(d); + return NULL; + } + v = do_mkvalue(p_format, p_va, flags); + if (v == NULL || PyDict_SetItem(d, k, v) < 0) { + do_ignore(p_format, p_va, endchar, n - i - 2, flags); + Py_DECREF(k); + Py_XDECREF(v); + Py_DECREF(d); + return NULL; + } + Py_DECREF(k); + Py_DECREF(v); + } + if (**p_format != endchar) { + Py_DECREF(d); + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return NULL; + } + if (endchar) + ++*p_format; + return d; +} + +static PyObject * +do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *v; + Py_ssize_t i; + if (n < 0) + return NULL; + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ + v = PyList_New(n); + if (v == NULL) { + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + for (i = 0; i < n; i++) { + PyObject *w = do_mkvalue(p_format, p_va, flags); + if (w == NULL) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + Py_DECREF(v); + return NULL; + } + PyList_SET_ITEM(v, i, w); + } + if (**p_format != endchar) { + Py_DECREF(v); + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return NULL; + } + if (endchar) + ++*p_format; + return v; +} + +static int +do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, + char endchar, Py_ssize_t n, int flags) +{ + Py_ssize_t i; + + if (n < 0) { + return -1; + } + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ + for (i = 0; i < n; i++) { + PyObject *w = do_mkvalue(p_format, p_va, flags); + if (w == NULL) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + goto error; + } + stack[i] = w; + } + if (**p_format != endchar) { + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + goto error; + } + if (endchar) { + ++*p_format; + } + return 0; + +error: + n = i; + for (i=0; i < n; i++) { + Py_DECREF(stack[i]); + } + return -1; +} + +static PyObject * +do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *v; + Py_ssize_t i; + if (n < 0) + return NULL; + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ + if ((v = PyTuple_New(n)) == NULL) { + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + for (i = 0; i < n; i++) { + PyObject *w = do_mkvalue(p_format, p_va, flags); + if (w == NULL) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + Py_DECREF(v); + return NULL; + } + PyTuple_SET_ITEM(v, i, w); + } + if (**p_format != endchar) { + Py_DECREF(v); + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return NULL; + } + if (endchar) + ++*p_format; + return v; +} + +static PyObject * +do_mkvalue(const char **p_format, va_list *p_va, int flags) +{ + for (;;) { + switch (*(*p_format)++) { + case '(': + return do_mktuple(p_format, p_va, ')', + countformat(*p_format, ')'), flags); + + case '[': + return do_mklist(p_format, p_va, ']', + countformat(*p_format, ']'), flags); + + case '{': + return do_mkdict(p_format, p_va, '}', + countformat(*p_format, '}'), flags); + + case 'b': + case 'B': + case 'h': + case 'i': + return PyLong_FromLong((long)va_arg(*p_va, int)); + + case 'H': + return PyLong_FromLong((long)va_arg(*p_va, unsigned int)); + + case 'I': + { + unsigned int n; + n = va_arg(*p_va, unsigned int); + return PyLong_FromUnsignedLong(n); + } + + case 'n': +#if SIZEOF_SIZE_T!=SIZEOF_LONG + return PyLong_FromSsize_t(va_arg(*p_va, Py_ssize_t)); +#endif + /* Fall through from 'n' to 'l' if Py_ssize_t is long */ + case 'l': + return PyLong_FromLong(va_arg(*p_va, long)); + + case 'k': + { + unsigned long n; + n = va_arg(*p_va, unsigned long); + return PyLong_FromUnsignedLong(n); + } + + case 'L': + return PyLong_FromLongLong((long long)va_arg(*p_va, long long)); + + case 'K': + return PyLong_FromUnsignedLongLong((long long)va_arg(*p_va, unsigned long long)); + + case 'u': + { + PyObject *v; + Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *); + Py_ssize_t n; + if (**p_format == '#') { + ++*p_format; + if (flags & FLAG_SIZE_T) + n = va_arg(*p_va, Py_ssize_t); + else { + n = va_arg(*p_va, int); + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { + return NULL; + } + } + } + else + n = -1; + if (u == NULL) { + v = Py_None; + Py_INCREF(v); + } + else { + if (n < 0) + n = wcslen(u); + v = PyUnicode_FromWideChar(u, n); + } + return v; + } + case 'f': + case 'd': + return PyFloat_FromDouble( + (double)va_arg(*p_va, va_double)); + + case 'D': + return PyComplex_FromCComplex( + *((Py_complex *)va_arg(*p_va, Py_complex *))); + + case 'c': + { + char p[1]; + p[0] = (char)va_arg(*p_va, int); + return PyBytes_FromStringAndSize(p, 1); + } + case 'C': + { + int i = va_arg(*p_va, int); + return PyUnicode_FromOrdinal(i); + } + + case 's': + case 'z': + case 'U': /* XXX deprecated alias */ + { + PyObject *v; + const char *str = va_arg(*p_va, const char *); + Py_ssize_t n; + if (**p_format == '#') { + ++*p_format; + if (flags & FLAG_SIZE_T) + n = va_arg(*p_va, Py_ssize_t); + else { + n = va_arg(*p_va, int); + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { + return NULL; + } + } + } + else + n = -1; + if (str == NULL) { + v = Py_None; + Py_INCREF(v); + } + else { + if (n < 0) { + size_t m = strlen(str); + if (m > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "string too long for Python string"); + return NULL; + } + n = (Py_ssize_t)m; + } + v = PyUnicode_FromStringAndSize(str, n); + } + return v; + } + + case 'y': + { + PyObject *v; + const char *str = va_arg(*p_va, const char *); + Py_ssize_t n; + if (**p_format == '#') { + ++*p_format; + if (flags & FLAG_SIZE_T) + n = va_arg(*p_va, Py_ssize_t); + else { + n = va_arg(*p_va, int); + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { + return NULL; + } + } + } + else + n = -1; + if (str == NULL) { + v = Py_None; + Py_INCREF(v); + } + else { + if (n < 0) { + size_t m = strlen(str); + if (m > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "string too long for Python bytes"); + return NULL; + } + n = (Py_ssize_t)m; + } + v = PyBytes_FromStringAndSize(str, n); + } + return v; + } + + case 'N': + case 'S': + case 'O': + if (**p_format == '&') { + typedef PyObject *(*converter)(void *); + converter func = va_arg(*p_va, converter); + void *arg = va_arg(*p_va, void *); + ++*p_format; + return (*func)(arg); + } + else { + PyObject *v; + v = va_arg(*p_va, PyObject *); + if (v != NULL) { + if (*(*p_format - 1) != 'N') + Py_INCREF(v); + } + else if (!PyErr_Occurred()) + /* If a NULL was passed + * because a call that should + * have constructed a value + * failed, that's OK, and we + * pass the error on; but if + * no error occurred it's not + * clear that the caller knew + * what she was doing. */ + PyErr_SetString(PyExc_SystemError, + "NULL object passed to Py_BuildValue"); + return v; + } + + case ':': + case ',': + case ' ': + case '\t': + break; + + default: + PyErr_SetString(PyExc_SystemError, + "bad format char passed to Py_BuildValue"); + return NULL; + + } + } +} + + +PyObject * +Py_BuildValue(const char *format, ...) +{ + va_list va; + PyObject* retval; + va_start(va, format); + retval = va_build_value(format, va, 0); + va_end(va); + return retval; +} + +PyObject * +_Py_BuildValue_SizeT(const char *format, ...) +{ + va_list va; + PyObject* retval; + va_start(va, format); + retval = va_build_value(format, va, FLAG_SIZE_T); + va_end(va); + return retval; +} + +PyObject * +Py_VaBuildValue(const char *format, va_list va) +{ + return va_build_value(format, va, 0); +} + +PyObject * +_Py_VaBuildValue_SizeT(const char *format, va_list va) +{ + return va_build_value(format, va, FLAG_SIZE_T); +} + +static PyObject * +va_build_value(const char *format, va_list va, int flags) +{ + const char *f = format; + Py_ssize_t n = countformat(f, '\0'); + va_list lva; + PyObject *retval; + + if (n < 0) + return NULL; + if (n == 0) { + Py_RETURN_NONE; + } + va_copy(lva, va); + if (n == 1) { + retval = do_mkvalue(&f, &lva, flags); + } else { + retval = do_mktuple(&f, &lva, '\0', n, flags); + } + va_end(lva); + return retval; +} + +PyObject ** +_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len, + const char *format, va_list va, Py_ssize_t *p_nargs) +{ + return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs); +} + +PyObject ** +_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len, + const char *format, va_list va, Py_ssize_t *p_nargs) +{ + return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs); +} + +static PyObject ** +va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, + const char *format, va_list va, int flags, Py_ssize_t *p_nargs) +{ + const char *f; + Py_ssize_t n; + va_list lva; + PyObject **stack; + int res; + + n = countformat(format, '\0'); + if (n < 0) { + *p_nargs = 0; + return NULL; + } + + if (n == 0) { + *p_nargs = 0; + return small_stack; + } + + if (n <= small_stack_len) { + stack = small_stack; + } + else { + stack = PyMem_Malloc(n * sizeof(stack[0])); + if (stack == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + + va_copy(lva, va); + f = format; + res = do_mkstack(stack, &f, &lva, '\0', n, flags); + va_end(lva); + + if (res < 0) { + if (stack != small_stack) { + PyMem_Free(stack); + } + return NULL; + } + + *p_nargs = n; + return stack; +} + + +int +PyModule_AddObject(PyObject *m, const char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return -1; + } + if (!o) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return -1; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return -1; + } + if (PyDict_SetItemString(dict, name, o)) + return -1; + Py_DECREF(o); + return 0; +} + +int +PyModule_AddIntConstant(PyObject *m, const char *name, long value) +{ + PyObject *o = PyLong_FromLong(value); + if (!o) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; +} + +int +PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) +{ + PyObject *o = PyUnicode_FromString(value); + if (!o) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; +} diff --git a/python/Python/mysnprintf.c b/python/Python/mysnprintf.c new file mode 100755 index 0000000..a08e249 --- /dev/null +++ b/python/Python/mysnprintf.c @@ -0,0 +1,104 @@ +#include "Python.h" + +/* snprintf() wrappers. If the platform has vsnprintf, we use it, else we + emulate it in a half-hearted way. Even if the platform has it, we wrap + it because platforms differ in what vsnprintf does in case the buffer + is too small: C99 behavior is to return the number of characters that + would have been written had the buffer not been too small, and to set + the last byte of the buffer to \0. At least MS _vsnprintf returns a + negative value instead, and fills the entire buffer with non-\0 data. + + The wrappers ensure that str[size-1] is always \0 upon return. + + PyOS_snprintf and PyOS_vsnprintf never write more than size bytes + (including the trailing '\0') into str. + + If the platform doesn't have vsnprintf, and the buffer size needed to + avoid truncation exceeds size by more than 512, Python aborts with a + Py_FatalError. + + Return value (rv): + + When 0 <= rv < size, the output conversion was unexceptional, and + rv characters were written to str (excluding a trailing \0 byte at + str[rv]). + + When rv >= size, output conversion was truncated, and a buffer of + size rv+1 would have been needed to avoid truncation. str[size-1] + is \0 in this case. + + When rv < 0, "something bad happened". str[size-1] is \0 in this + case too, but the rest of str is unreliable. It could be that + an error in format codes was detected by libc, or on platforms + with a non-C99 vsnprintf simply that the buffer wasn't big enough + to avoid truncation, or on platforms without any vsnprintf that + PyMem_Malloc couldn't obtain space for a temp buffer. + + CAUTION: Unlike C99, str != NULL and size > 0 are required. +*/ + +int +PyOS_snprintf(char *str, size_t size, const char *format, ...) +{ + int rc; + va_list va; + + va_start(va, format); + rc = PyOS_vsnprintf(str, size, format, va); + va_end(va); + return rc; +} + +int +PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) +{ + int len; /* # bytes written, excluding \0 */ +#ifdef HAVE_SNPRINTF +#define _PyOS_vsnprintf_EXTRA_SPACE 1 +#else +#define _PyOS_vsnprintf_EXTRA_SPACE 512 + char *buffer; +#endif + assert(str != NULL); + assert(size > 0); + assert(format != NULL); + /* We take a size_t as input but return an int. Sanity check + * our input so that it won't cause an overflow in the + * vsnprintf return value or the buffer malloc size. */ + if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) { + len = -666; + goto Done; + } + +#ifdef HAVE_SNPRINTF + len = vsnprintf(str, size, format, va); +#else + /* Emulate it. */ + buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE); + if (buffer == NULL) { + len = -666; + goto Done; + } + + len = vsprintf(buffer, format, va); + if (len < 0) + /* ignore the error */; + + else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE) + Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf"); + + else { + const size_t to_copy = (size_t)len < size ? + (size_t)len : size - 1; + assert(to_copy < size); + memcpy(str, buffer, to_copy); + str[to_copy] = '\0'; + } + PyMem_FREE(buffer); +#endif +Done: + if (size > 0) + str[size-1] = '\0'; + return len; +#undef _PyOS_vsnprintf_EXTRA_SPACE +} diff --git a/python/Python/mystrtoul.c b/python/Python/mystrtoul.c new file mode 100755 index 0000000..7ab5814 --- /dev/null +++ b/python/Python/mystrtoul.c @@ -0,0 +1,291 @@ + +#include "Python.h" + +#if defined(__sgi) && !defined(_SGI_MP_SOURCE) +#define _SGI_MP_SOURCE +#endif + +/* strtol and strtoul, renamed to avoid conflicts */ + + +#include +#ifdef HAVE_ERRNO_H +#include +#endif + +/* Static overflow check values for bases 2 through 36. + * smallmax[base] is the largest unsigned long i such that + * i * base doesn't overflow unsigned long. + */ +static const unsigned long smallmax[] = { + 0, /* bases 0 and 1 are invalid */ + 0, + ULONG_MAX / 2, + ULONG_MAX / 3, + ULONG_MAX / 4, + ULONG_MAX / 5, + ULONG_MAX / 6, + ULONG_MAX / 7, + ULONG_MAX / 8, + ULONG_MAX / 9, + ULONG_MAX / 10, + ULONG_MAX / 11, + ULONG_MAX / 12, + ULONG_MAX / 13, + ULONG_MAX / 14, + ULONG_MAX / 15, + ULONG_MAX / 16, + ULONG_MAX / 17, + ULONG_MAX / 18, + ULONG_MAX / 19, + ULONG_MAX / 20, + ULONG_MAX / 21, + ULONG_MAX / 22, + ULONG_MAX / 23, + ULONG_MAX / 24, + ULONG_MAX / 25, + ULONG_MAX / 26, + ULONG_MAX / 27, + ULONG_MAX / 28, + ULONG_MAX / 29, + ULONG_MAX / 30, + ULONG_MAX / 31, + ULONG_MAX / 32, + ULONG_MAX / 33, + ULONG_MAX / 34, + ULONG_MAX / 35, + ULONG_MAX / 36, +}; + +/* maximum digits that can't ever overflow for bases 2 through 36, + * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)]. + * Note that this is pessimistic if sizeof(long) > 4. + */ +#if SIZEOF_LONG == 4 +static const int digitlimit[] = { + 0, 0, 32, 20, 16, 13, 12, 11, 10, 10, /* 0 - 9 */ + 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, /* 10 - 19 */ + 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */ + 6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */ +#elif SIZEOF_LONG == 8 +/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */ +static const int digitlimit[] = { + 0, 0, 64, 40, 32, 27, 24, 22, 21, 20, /* 0 - 9 */ + 19, 18, 17, 17, 16, 16, 16, 15, 15, 15, /* 10 - 19 */ + 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */ + 13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */ +#else +#error "Need table for SIZEOF_LONG" +#endif + +/* +** strtoul +** This is a general purpose routine for converting +** an ascii string to an integer in an arbitrary base. +** Leading white space is ignored. If 'base' is zero +** it looks for a leading 0b, 0o or 0x to tell which +** base. If these are absent it defaults to 10. +** Base must be 0 or between 2 and 36 (inclusive). +** If 'ptr' is non-NULL it will contain a pointer to +** the end of the scan. +** Errors due to bad pointers will probably result in +** exceptions - we don't check for them. +*/ +unsigned long +PyOS_strtoul(const char *str, char **ptr, int base) +{ + unsigned long result = 0; /* return value of the function */ + int c; /* current input character */ + int ovlimit; /* required digits to overflow */ + + /* skip leading white space */ + while (*str && Py_ISSPACE(Py_CHARMASK(*str))) + ++str; + + /* check for leading 0b, 0o or 0x for auto-base or base 16 */ + switch (base) { + case 0: /* look for leading 0b, 0o or 0x */ + if (*str == '0') { + ++str; + if (*str == 'x' || *str == 'X') { + /* there must be at least one digit after 0x */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { + if (ptr) + *ptr = (char *)str; + return 0; + } + ++str; + base = 16; + } else if (*str == 'o' || *str == 'O') { + /* there must be at least one digit after 0o */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { + if (ptr) + *ptr = (char *)str; + return 0; + } + ++str; + base = 8; + } else if (*str == 'b' || *str == 'B') { + /* there must be at least one digit after 0b */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { + if (ptr) + *ptr = (char *)str; + return 0; + } + ++str; + base = 2; + } else { + /* skip all zeroes... */ + while (*str == '0') + ++str; + while (Py_ISSPACE(Py_CHARMASK(*str))) + ++str; + if (ptr) + *ptr = (char *)str; + return 0; + } + } + else + base = 10; + break; + + /* even with explicit base, skip leading 0? prefix */ + case 16: + if (*str == '0') { + ++str; + if (*str == 'x' || *str == 'X') { + /* there must be at least one digit after 0x */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { + if (ptr) + *ptr = (char *)str; + return 0; + } + ++str; + } + } + break; + case 8: + if (*str == '0') { + ++str; + if (*str == 'o' || *str == 'O') { + /* there must be at least one digit after 0o */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { + if (ptr) + *ptr = (char *)str; + return 0; + } + ++str; + } + } + break; + case 2: + if(*str == '0') { + ++str; + if (*str == 'b' || *str == 'B') { + /* there must be at least one digit after 0b */ + if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { + if (ptr) + *ptr = (char *)str; + return 0; + } + ++str; + } + } + break; + } + + /* catch silly bases */ + if (base < 2 || base > 36) { + if (ptr) + *ptr = (char *)str; + return 0; + } + + /* skip leading zeroes */ + while (*str == '0') + ++str; + + /* base is guaranteed to be in [2, 36] at this point */ + ovlimit = digitlimit[base]; + + /* do the conversion until non-digit character encountered */ + while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) { + if (ovlimit > 0) /* no overflow check required */ + result = result * base + c; + else { /* requires overflow check */ + unsigned long temp_result; + + if (ovlimit < 0) /* guaranteed overflow */ + goto overflowed; + + /* there could be an overflow */ + /* check overflow just from shifting */ + if (result > smallmax[base]) + goto overflowed; + + result *= base; + + /* check overflow from the digit's value */ + temp_result = result + c; + if (temp_result < result) + goto overflowed; + + result = temp_result; + } + + ++str; + --ovlimit; + } + + /* set pointer to point to the last character scanned */ + if (ptr) + *ptr = (char *)str; + + return result; + +overflowed: + if (ptr) { + /* spool through remaining digit characters */ + while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base) + ++str; + *ptr = (char *)str; + } + errno = ERANGE; + return (unsigned long)-1; +} + +/* Checking for overflow in PyOS_strtol is a PITA; see comments + * about PY_ABS_LONG_MIN in longobject.c. + */ +#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) + +long +PyOS_strtol(const char *str, char **ptr, int base) +{ + long result; + unsigned long uresult; + char sign; + + while (*str && Py_ISSPACE(Py_CHARMASK(*str))) + str++; + + sign = *str; + if (sign == '+' || sign == '-') + str++; + + uresult = PyOS_strtoul(str, ptr, base); + + if (uresult <= (unsigned long)LONG_MAX) { + result = (long)uresult; + if (sign == '-') + result = -result; + } + else if (sign == '-' && uresult == PY_ABS_LONG_MIN) { + result = LONG_MIN; + } + else { + errno = ERANGE; + result = LONG_MAX; + } + return result; +} diff --git a/python/Python/opcode_targets.h b/python/Python/opcode_targets.h new file mode 100755 index 0000000..e82959b --- /dev/null +++ b/python/Python/opcode_targets.h @@ -0,0 +1,258 @@ +static void *opcode_targets[256] = { + &&_unknown_opcode, + &&TARGET_POP_TOP, + &&TARGET_ROT_TWO, + &&TARGET_ROT_THREE, + &&TARGET_DUP_TOP, + &&TARGET_DUP_TOP_TWO, + &&TARGET_ROT_FOUR, + &&_unknown_opcode, + &&_unknown_opcode, + &&TARGET_NOP, + &&TARGET_UNARY_POSITIVE, + &&TARGET_UNARY_NEGATIVE, + &&TARGET_UNARY_NOT, + &&_unknown_opcode, + &&_unknown_opcode, + &&TARGET_UNARY_INVERT, + &&TARGET_BINARY_MATRIX_MULTIPLY, + &&TARGET_INPLACE_MATRIX_MULTIPLY, + &&_unknown_opcode, + &&TARGET_BINARY_POWER, + &&TARGET_BINARY_MULTIPLY, + &&_unknown_opcode, + &&TARGET_BINARY_MODULO, + &&TARGET_BINARY_ADD, + &&TARGET_BINARY_SUBTRACT, + &&TARGET_BINARY_SUBSCR, + &&TARGET_BINARY_FLOOR_DIVIDE, + &&TARGET_BINARY_TRUE_DIVIDE, + &&TARGET_INPLACE_FLOOR_DIVIDE, + &&TARGET_INPLACE_TRUE_DIVIDE, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&TARGET_GET_AITER, + &&TARGET_GET_ANEXT, + &&TARGET_BEFORE_ASYNC_WITH, + &&TARGET_BEGIN_FINALLY, + &&TARGET_END_ASYNC_FOR, + &&TARGET_INPLACE_ADD, + &&TARGET_INPLACE_SUBTRACT, + &&TARGET_INPLACE_MULTIPLY, + &&_unknown_opcode, + &&TARGET_INPLACE_MODULO, + &&TARGET_STORE_SUBSCR, + &&TARGET_DELETE_SUBSCR, + &&TARGET_BINARY_LSHIFT, + &&TARGET_BINARY_RSHIFT, + &&TARGET_BINARY_AND, + &&TARGET_BINARY_XOR, + &&TARGET_BINARY_OR, + &&TARGET_INPLACE_POWER, + &&TARGET_GET_ITER, + &&TARGET_GET_YIELD_FROM_ITER, + &&TARGET_PRINT_EXPR, + &&TARGET_LOAD_BUILD_CLASS, + &&TARGET_YIELD_FROM, + &&TARGET_GET_AWAITABLE, + &&_unknown_opcode, + &&TARGET_INPLACE_LSHIFT, + &&TARGET_INPLACE_RSHIFT, + &&TARGET_INPLACE_AND, + &&TARGET_INPLACE_XOR, + &&TARGET_INPLACE_OR, + &&_unknown_opcode, + &&TARGET_WITH_CLEANUP_START, + &&TARGET_WITH_CLEANUP_FINISH, + &&TARGET_RETURN_VALUE, + &&TARGET_IMPORT_STAR, + &&TARGET_SETUP_ANNOTATIONS, + &&TARGET_YIELD_VALUE, + &&TARGET_POP_BLOCK, + &&TARGET_END_FINALLY, + &&TARGET_POP_EXCEPT, + &&TARGET_STORE_NAME, + &&TARGET_DELETE_NAME, + &&TARGET_UNPACK_SEQUENCE, + &&TARGET_FOR_ITER, + &&TARGET_UNPACK_EX, + &&TARGET_STORE_ATTR, + &&TARGET_DELETE_ATTR, + &&TARGET_STORE_GLOBAL, + &&TARGET_DELETE_GLOBAL, + &&_unknown_opcode, + &&TARGET_LOAD_CONST, + &&TARGET_LOAD_NAME, + &&TARGET_BUILD_TUPLE, + &&TARGET_BUILD_LIST, + &&TARGET_BUILD_SET, + &&TARGET_BUILD_MAP, + &&TARGET_LOAD_ATTR, + &&TARGET_COMPARE_OP, + &&TARGET_IMPORT_NAME, + &&TARGET_IMPORT_FROM, + &&TARGET_JUMP_FORWARD, + &&TARGET_JUMP_IF_FALSE_OR_POP, + &&TARGET_JUMP_IF_TRUE_OR_POP, + &&TARGET_JUMP_ABSOLUTE, + &&TARGET_POP_JUMP_IF_FALSE, + &&TARGET_POP_JUMP_IF_TRUE, + &&TARGET_LOAD_GLOBAL, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&TARGET_SETUP_FINALLY, + &&_unknown_opcode, + &&TARGET_LOAD_FAST, + &&TARGET_STORE_FAST, + &&TARGET_DELETE_FAST, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&TARGET_RAISE_VARARGS, + &&TARGET_CALL_FUNCTION, + &&TARGET_MAKE_FUNCTION, + &&TARGET_BUILD_SLICE, + &&_unknown_opcode, + &&TARGET_LOAD_CLOSURE, + &&TARGET_LOAD_DEREF, + &&TARGET_STORE_DEREF, + &&TARGET_DELETE_DEREF, + &&_unknown_opcode, + &&_unknown_opcode, + &&TARGET_CALL_FUNCTION_KW, + &&TARGET_CALL_FUNCTION_EX, + &&TARGET_SETUP_WITH, + &&TARGET_EXTENDED_ARG, + &&TARGET_LIST_APPEND, + &&TARGET_SET_ADD, + &&TARGET_MAP_ADD, + &&TARGET_LOAD_CLASSDEREF, + &&TARGET_BUILD_LIST_UNPACK, + &&TARGET_BUILD_MAP_UNPACK, + &&TARGET_BUILD_MAP_UNPACK_WITH_CALL, + &&TARGET_BUILD_TUPLE_UNPACK, + &&TARGET_BUILD_SET_UNPACK, + &&TARGET_SETUP_ASYNC_WITH, + &&TARGET_FORMAT_VALUE, + &&TARGET_BUILD_CONST_KEY_MAP, + &&TARGET_BUILD_STRING, + &&TARGET_BUILD_TUPLE_UNPACK_WITH_CALL, + &&_unknown_opcode, + &&TARGET_LOAD_METHOD, + &&TARGET_CALL_METHOD, + &&TARGET_CALL_FINALLY, + &&TARGET_POP_FINALLY, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode, + &&_unknown_opcode +}; diff --git a/python/Python/pathconfig.c b/python/Python/pathconfig.c new file mode 100755 index 0000000..60c1044 --- /dev/null +++ b/python/Python/pathconfig.c @@ -0,0 +1,786 @@ +/* Path configuration like module_search_path (sys.path) */ + +#include "Python.h" +#include "osdefs.h" +#include "pycore_initconfig.h" +#include "pycore_fileutils.h" +#include "pycore_pathconfig.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +_PyPathConfig _Py_path_config = _PyPathConfig_INIT; + + +static int +copy_wstr(wchar_t **dst, const wchar_t *src) +{ + assert(*dst == NULL); + if (src != NULL) { + *dst = _PyMem_RawWcsdup(src); + if (*dst == NULL) { + return -1; + } + } + else { + *dst = NULL; + } + return 0; +} + + +static void +pathconfig_clear(_PyPathConfig *config) +{ + /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator, + since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be + called before Py_Initialize() which can changes the memory allocator. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + +#define CLEAR(ATTR) \ + do { \ + PyMem_RawFree(ATTR); \ + ATTR = NULL; \ + } while (0) + + CLEAR(config->program_full_path); + CLEAR(config->prefix); + CLEAR(config->exec_prefix); + CLEAR(config->module_search_path); + CLEAR(config->program_name); + CLEAR(config->home); +#ifdef MS_WINDOWS + CLEAR(config->base_executable); +#endif + +#undef CLEAR + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + + +static PyStatus +pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2) +{ + pathconfig_clear(config); + +#define COPY_ATTR(ATTR) \ + do { \ + if (copy_wstr(&config->ATTR, config2->ATTR) < 0) { \ + return _PyStatus_NO_MEMORY(); \ + } \ + } while (0) + + COPY_ATTR(program_full_path); + COPY_ATTR(prefix); + COPY_ATTR(exec_prefix); + COPY_ATTR(module_search_path); + COPY_ATTR(program_name); + COPY_ATTR(home); +#ifdef MS_WINDOWS + config->isolated = config2->isolated; + config->site_import = config2->site_import; + COPY_ATTR(base_executable); +#endif + +#undef COPY_ATTR + + return _PyStatus_OK(); +} + + +void +_PyPathConfig_ClearGlobal(void) +{ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + pathconfig_clear(&_Py_path_config); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + + +static wchar_t* +_PyWideStringList_Join(const PyWideStringList *list, wchar_t sep) +{ + size_t len = 1; /* NUL terminator */ + for (Py_ssize_t i=0; i < list->length; i++) { + if (i != 0) { + len++; + } + len += wcslen(list->items[i]); + } + + wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t)); + if (text == NULL) { + return NULL; + } + wchar_t *str = text; + for (Py_ssize_t i=0; i < list->length; i++) { + wchar_t *path = list->items[i]; + if (i != 0) { + *str++ = sep; + } + len = wcslen(path); + memcpy(str, path, len * sizeof(wchar_t)); + str += len; + } + *str = L'\0'; + + return text; +} + + +static PyStatus +pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config) +{ + PyStatus status; + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (config->module_search_paths_set) { + PyMem_RawFree(pathconfig->module_search_path); + pathconfig->module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM); + if (pathconfig->module_search_path == NULL) { + goto no_memory; + } + } + +#define COPY_CONFIG(PATH_ATTR, CONFIG_ATTR) \ + if (config->CONFIG_ATTR) { \ + PyMem_RawFree(pathconfig->PATH_ATTR); \ + pathconfig->PATH_ATTR = NULL; \ + if (copy_wstr(&pathconfig->PATH_ATTR, config->CONFIG_ATTR) < 0) { \ + goto no_memory; \ + } \ + } + + COPY_CONFIG(program_full_path, executable); + COPY_CONFIG(prefix, prefix); + COPY_CONFIG(exec_prefix, exec_prefix); + COPY_CONFIG(program_name, program_name); + COPY_CONFIG(home, home); +#ifdef MS_WINDOWS + COPY_CONFIG(base_executable, base_executable); +#endif + +#undef COPY_CONFIG + + status = _PyStatus_OK(); + goto done; + +no_memory: + status = _PyStatus_NO_MEMORY(); + +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return status; +} + + +PyStatus +_PyConfig_WritePathConfig(const PyConfig *config) +{ + return pathconfig_set_from_config(&_Py_path_config, config); +} + + +static PyStatus +config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) +{ + assert(!config->module_search_paths_set); + + _PyWideStringList_Clear(&config->module_search_paths); + + const wchar_t *sys_path = pathconfig->module_search_path; + const wchar_t delim = DELIM; + const wchar_t *p = sys_path; + while (1) { + p = wcschr(sys_path, delim); + if (p == NULL) { + p = sys_path + wcslen(sys_path); /* End of string */ + } + + size_t path_len = (p - sys_path); + wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); + if (path == NULL) { + return _PyStatus_NO_MEMORY(); + } + memcpy(path, sys_path, path_len * sizeof(wchar_t)); + path[path_len] = L'\0'; + + PyStatus status = PyWideStringList_Append(&config->module_search_paths, path); + PyMem_RawFree(path); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (*p == '\0') { + break; + } + sys_path = p + 1; + } + config->module_search_paths_set = 1; + return _PyStatus_OK(); +} + + +/* Calculate the path configuration: + + - exec_prefix + - module_search_path + - prefix + - program_full_path + + On Windows, more fields are calculated: + + - base_executable + - isolated + - site_import + + On other platforms, isolated and site_import are left unchanged, and + _PyConfig_InitPathConfig() copies executable to base_executable (if it's not + set). + + Priority, highest to lowest: + + - PyConfig + - _Py_path_config: set by Py_SetPath(), Py_SetPythonHome() + and Py_SetProgramName() + - _PyPathConfig_Calculate() +*/ +static PyStatus +pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config) +{ + PyStatus status; + + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + status = pathconfig_copy(pathconfig, &_Py_path_config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = pathconfig_set_from_config(pathconfig, config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + if (_Py_path_config.module_search_path == NULL) { + status = _PyPathConfig_Calculate(pathconfig, config); + } + else { + /* Py_SetPath() has been called: avoid _PyPathConfig_Calculate() */ + } + +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return status; +} + + +static PyStatus +config_calculate_pathconfig(PyConfig *config) +{ + _PyPathConfig pathconfig = _PyPathConfig_INIT; + PyStatus status; + + status = pathconfig_calculate(&pathconfig, config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + if (!config->module_search_paths_set) { + status = config_init_module_search_paths(config, &pathconfig); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + } + +#define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \ + if (config->CONFIG_ATTR == NULL) { \ + if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \ + goto no_memory; \ + } \ + } + +#ifdef MS_WINDOWS + if (config->executable != NULL && config->base_executable == NULL) { + /* If executable is set explicitly in the configuration, + ignore calculated base_executable: _PyConfig_InitPathConfig() + will copy executable to base_executable */ + } + else { + COPY_ATTR(base_executable, base_executable); + } +#endif + + COPY_ATTR(program_full_path, executable); + COPY_ATTR(prefix, prefix); + COPY_ATTR(exec_prefix, exec_prefix); + +#undef COPY_ATTR + +#ifdef MS_WINDOWS + /* If a ._pth file is found: isolated and site_import are overriden */ + if (pathconfig.isolated != -1) { + config->isolated = pathconfig.isolated; + } + if (pathconfig.site_import != -1) { + config->site_import = pathconfig.site_import; + } +#endif + + status = _PyStatus_OK(); + goto done; + +no_memory: + status = _PyStatus_NO_MEMORY(); + +done: + pathconfig_clear(&pathconfig); + return status; +} + + +PyStatus +_PyConfig_InitPathConfig(PyConfig *config) +{ + /* Do we need to calculate the path? */ + if (!config->module_search_paths_set + || config->executable == NULL + || config->prefix == NULL + || config->exec_prefix == NULL) + { + PyStatus status = config_calculate_pathconfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->base_prefix == NULL) { + if (copy_wstr(&config->base_prefix, config->prefix) < 0) { + return _PyStatus_NO_MEMORY(); + } + } + + if (config->base_exec_prefix == NULL) { + if (copy_wstr(&config->base_exec_prefix, + config->exec_prefix) < 0) { + return _PyStatus_NO_MEMORY(); + } + } + + if (config->base_executable == NULL) { + if (copy_wstr(&config->base_executable, + config->executable) < 0) { + return _PyStatus_NO_MEMORY(); + } + } + + return _PyStatus_OK(); +} + + +static PyStatus +pathconfig_global_read(_PyPathConfig *pathconfig) +{ + PyConfig config; + _PyConfig_InitCompatConfig(&config); + + /* Call _PyConfig_InitPathConfig() */ + PyStatus status = PyConfig_Read(&config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = pathconfig_set_from_config(pathconfig, &config); + +done: + PyConfig_Clear(&config); + return status; +} + + +static void +pathconfig_global_init(void) +{ + PyStatus status; + + if (_Py_path_config.module_search_path == NULL) { + status = pathconfig_global_read(&_Py_path_config); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); + } + } + else { + /* Global configuration already initialized */ + } + + assert(_Py_path_config.program_full_path != NULL); + assert(_Py_path_config.prefix != NULL); + assert(_Py_path_config.exec_prefix != NULL); + assert(_Py_path_config.module_search_path != NULL); + assert(_Py_path_config.program_name != NULL); + /* home can be NULL */ +#ifdef MS_WINDOWS + assert(_Py_path_config.base_executable != NULL); +#endif +} + + +/* External interface */ + +void +Py_SetPath(const wchar_t *path) +{ + if (path == NULL) { + pathconfig_clear(&_Py_path_config); + return; + } + + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Getting the program full path calls pathconfig_global_init() */ + wchar_t *program_full_path = _PyMem_RawWcsdup(Py_GetProgramFullPath()); + + PyMem_RawFree(_Py_path_config.program_full_path); + PyMem_RawFree(_Py_path_config.prefix); + PyMem_RawFree(_Py_path_config.exec_prefix); + PyMem_RawFree(_Py_path_config.module_search_path); + + _Py_path_config.program_full_path = program_full_path; + _Py_path_config.prefix = _PyMem_RawWcsdup(L""); + _Py_path_config.exec_prefix = _PyMem_RawWcsdup(L""); + _Py_path_config.module_search_path = _PyMem_RawWcsdup(path); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (_Py_path_config.program_full_path == NULL + || _Py_path_config.prefix == NULL + || _Py_path_config.exec_prefix == NULL + || _Py_path_config.module_search_path == NULL) + { + Py_FatalError("Py_SetPath() failed: out of memory"); + } +} + + +void +Py_SetPythonHome(const wchar_t *home) +{ + if (home == NULL) { + return; + } + + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + PyMem_RawFree(_Py_path_config.home); + _Py_path_config.home = _PyMem_RawWcsdup(home); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (_Py_path_config.home == NULL) { + Py_FatalError("Py_SetPythonHome() failed: out of memory"); + } +} + + +void +Py_SetProgramName(const wchar_t *program_name) +{ + if (program_name == NULL || program_name[0] == L'\0') { + return; + } + + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + PyMem_RawFree(_Py_path_config.program_name); + _Py_path_config.program_name = _PyMem_RawWcsdup(program_name); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (_Py_path_config.program_name == NULL) { + Py_FatalError("Py_SetProgramName() failed: out of memory"); + } +} + +void +_Py_SetProgramFullPath(const wchar_t *program_full_path) +{ + if (program_full_path == NULL || program_full_path[0] == L'\0') { + return; + } + + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + PyMem_RawFree(_Py_path_config.program_full_path); + _Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (_Py_path_config.program_full_path == NULL) { + Py_FatalError("_Py_SetProgramFullPath() failed: out of memory"); + } +} + + +wchar_t * +Py_GetPath(void) +{ + pathconfig_global_init(); + return _Py_path_config.module_search_path; +} + + +wchar_t * +Py_GetPrefix(void) +{ + pathconfig_global_init(); + return _Py_path_config.prefix; +} + + +wchar_t * +Py_GetExecPrefix(void) +{ + pathconfig_global_init(); + return _Py_path_config.exec_prefix; +} + + +wchar_t * +Py_GetProgramFullPath(void) +{ + pathconfig_global_init(); + return _Py_path_config.program_full_path; +} + + +wchar_t* +Py_GetPythonHome(void) +{ + pathconfig_global_init(); + return _Py_path_config.home; +} + + +wchar_t * +Py_GetProgramName(void) +{ + pathconfig_global_init(); + return _Py_path_config.program_name; +} + +/* Compute module search path from argv[0] or the current working + directory ("-m module" case) which will be prepended to sys.argv: + sys.path[0]. + + Return 1 if the path is correctly resolved and written into *path0_p. + + Return 0 if it fails to resolve the full path. For example, return 0 if the + current working directory has been removed (bpo-36236) or if argv is empty. + + Raise an exception and return -1 on error. + */ +int +_PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) +{ + assert(_PyWideStringList_CheckConsistency(argv)); + + if (argv->length == 0) { + /* Leave sys.path unchanged if sys.argv is empty */ + return 0; + } + + wchar_t *argv0 = argv->items[0]; + int have_module_arg = (wcscmp(argv0, L"-m") == 0); + int have_script_arg = (!have_module_arg && (wcscmp(argv0, L"-c") != 0)); + + wchar_t *path0 = argv0; + Py_ssize_t n = 0; + +#ifdef HAVE_REALPATH + wchar_t fullpath[MAXPATHLEN]; +#elif defined(MS_WINDOWS) + wchar_t fullpath[MAX_PATH]; +#endif + + if (have_module_arg) { +#if defined(HAVE_REALPATH) || defined(MS_WINDOWS) + if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) { + return 0; + } + path0 = fullpath; +#else + path0 = L"."; +#endif + n = wcslen(path0); + } + +#ifdef HAVE_READLINK + wchar_t link[MAXPATHLEN + 1]; + int nr = 0; + wchar_t path0copy[2 * MAXPATHLEN + 1]; + + if (have_script_arg) { + nr = _Py_wreadlink(path0, link, Py_ARRAY_LENGTH(link)); + } + if (nr > 0) { + /* It's a symlink */ + link[nr] = '\0'; + if (link[0] == SEP) { + path0 = link; /* Link to absolute path */ + } + else if (wcschr(link, SEP) == NULL) { + /* Link without path */ + } + else { + /* Must join(dirname(path0), link) */ + wchar_t *q = wcsrchr(path0, SEP); + if (q == NULL) { + /* path0 without path */ + path0 = link; + } + else { + /* Must make a copy, path0copy has room for 2 * MAXPATHLEN */ + wcsncpy(path0copy, path0, MAXPATHLEN); + q = wcsrchr(path0copy, SEP); + wcsncpy(q+1, link, MAXPATHLEN); + q[MAXPATHLEN + 1] = L'\0'; + path0 = path0copy; + } + } + } +#endif /* HAVE_READLINK */ + + wchar_t *p = NULL; + +#if SEP == '\\' + /* Special case for Microsoft filename syntax */ + if (have_script_arg) { + wchar_t *q; +#if defined(MS_WINDOWS) + /* Replace the first element in argv with the full path. */ + wchar_t *ptemp; + if (GetFullPathNameW(path0, + Py_ARRAY_LENGTH(fullpath), + fullpath, + &ptemp)) { + path0 = fullpath; + } +#endif + p = wcsrchr(path0, SEP); + /* Test for alternate separator */ + q = wcsrchr(p ? p : path0, '/'); + if (q != NULL) + p = q; + if (p != NULL) { + n = p + 1 - path0; + if (n > 1 && p[-1] != ':') + n--; /* Drop trailing separator */ + } + } +#else + /* All other filename syntaxes */ + if (have_script_arg) { +#if defined(HAVE_REALPATH) + if (_Py_wrealpath(path0, fullpath, Py_ARRAY_LENGTH(fullpath))) { + path0 = fullpath; + } +#endif + p = wcsrchr(path0, SEP); + } + if (p != NULL) { + n = p + 1 - path0; +#if SEP == '/' /* Special case for Unix filename syntax */ + if (n > 1) { + /* Drop trailing separator */ + n--; + } +#endif /* Unix */ + } +#endif /* All others */ + + PyObject *path0_obj = PyUnicode_FromWideChar(path0, n); + if (path0_obj == NULL) { + return -1; + } + + *path0_p = path0_obj; + return 1; +} + + +#ifdef MS_WINDOWS +#define WCSTOK wcstok_s +#else +#define WCSTOK wcstok +#endif + +/* Search for a prefix value in an environment file (pyvenv.cfg). + If found, copy it into the provided buffer. */ +int +_Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key, + wchar_t *value, size_t value_size) +{ + int result = 0; /* meaning not found */ + char buffer[MAXPATHLEN * 2 + 1]; /* allow extra for key, '=', etc. */ + buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0'; + + fseek(env_file, 0, SEEK_SET); + while (!feof(env_file)) { + char * p = fgets(buffer, Py_ARRAY_LENGTH(buffer) - 1, env_file); + + if (p == NULL) { + break; + } + + size_t n = strlen(p); + if (p[n - 1] != '\n') { + /* line has overflowed - bail */ + break; + } + if (p[0] == '#') { + /* Comment - skip */ + continue; + } + + wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL); + if (tmpbuffer) { + wchar_t * state; + wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state); + if ((tok != NULL) && !wcscmp(tok, key)) { + tok = WCSTOK(NULL, L" \t", &state); + if ((tok != NULL) && !wcscmp(tok, L"=")) { + tok = WCSTOK(NULL, L"\r\n", &state); + if (tok != NULL) { + wcsncpy(value, tok, value_size - 1); + value[value_size - 1] = L'\0'; + result = 1; + PyMem_RawFree(tmpbuffer); + break; + } + } + } + PyMem_RawFree(tmpbuffer); + } + } + return result; +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Python/peephole.c b/python/Python/peephole.c new file mode 100755 index 0000000..d859648 --- /dev/null +++ b/python/Python/peephole.c @@ -0,0 +1,538 @@ +/* Peephole optimizations for bytecode compiler. */ + +#include "Python.h" + +#include "Python-ast.h" +#include "node.h" +#include "ast.h" +#include "code.h" +#include "symtable.h" +#include "opcode.h" +#include "wordcode_helpers.h" + +#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD) +#define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ + || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP) +#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE \ + || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \ + || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP) +#define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP) +#define GETJUMPTGT(arr, i) (get_arg(arr, i) / sizeof(_Py_CODEUNIT) + \ + (ABSOLUTE_JUMP(_Py_OPCODE(arr[i])) ? 0 : i+1)) +#define ISBASICBLOCK(blocks, start, end) \ + (blocks[start]==blocks[end]) + + +/* Scans back N consecutive LOAD_CONST instructions, skipping NOPs, + returns index of the Nth last's LOAD_CONST's EXTENDED_ARG prefix. + Callers are responsible to check CONST_STACK_LEN beforehand. +*/ +static Py_ssize_t +lastn_const_start(const _Py_CODEUNIT *codestr, Py_ssize_t i, Py_ssize_t n) +{ + assert(n > 0); + for (;;) { + i--; + assert(i >= 0); + if (_Py_OPCODE(codestr[i]) == LOAD_CONST) { + if (!--n) { + while (i > 0 && _Py_OPCODE(codestr[i-1]) == EXTENDED_ARG) { + i--; + } + return i; + } + } + else { + assert(_Py_OPCODE(codestr[i]) == EXTENDED_ARG); + } + } +} + +/* Scans through EXTENDED ARGs, seeking the index of the effective opcode */ +static Py_ssize_t +find_op(const _Py_CODEUNIT *codestr, Py_ssize_t codelen, Py_ssize_t i) +{ + while (i < codelen && _Py_OPCODE(codestr[i]) == EXTENDED_ARG) { + i++; + } + return i; +} + +/* Given the index of the effective opcode, + scan back to construct the oparg with EXTENDED_ARG */ +static unsigned int +get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) +{ + _Py_CODEUNIT word; + unsigned int oparg = _Py_OPARG(codestr[i]); + if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 8; + if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 16; + if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) { + oparg |= _Py_OPARG(word) << 24; + } + } + } + return oparg; +} + +/* Fill the region with NOPs. */ +static void +fill_nops(_Py_CODEUNIT *codestr, Py_ssize_t start, Py_ssize_t end) +{ + memset(codestr + start, NOP, (end - start) * sizeof(_Py_CODEUNIT)); +} + +/* Given the index of the effective opcode, + attempt to replace the argument, taking into account EXTENDED_ARG. + Returns -1 on failure, or the new op index on success */ +static Py_ssize_t +set_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned int oparg) +{ + unsigned int curarg = get_arg(codestr, i); + int curilen, newilen; + if (curarg == oparg) + return i; + curilen = instrsize(curarg); + newilen = instrsize(oparg); + if (curilen < newilen) { + return -1; + } + + write_op_arg(codestr + i + 1 - curilen, _Py_OPCODE(codestr[i]), oparg, newilen); + fill_nops(codestr, i + 1 - curilen + newilen, i + 1); + return i-curilen+newilen; +} + +/* Attempt to write op/arg at end of specified region of memory. + Preceding memory in the region is overwritten with NOPs. + Returns -1 on failure, op index on success */ +static Py_ssize_t +copy_op_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned char op, + unsigned int oparg, Py_ssize_t maxi) +{ + int ilen = instrsize(oparg); + if (i + ilen > maxi) { + return -1; + } + write_op_arg(codestr + maxi - ilen, op, oparg, ilen); + fill_nops(codestr, i, maxi - ilen); + return maxi - 1; +} + +/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n + with LOAD_CONST (c1, c2, ... cn). + The consts table must still be in list form so that the + new constant (c1, c2, ... cn) can be appended. + Called with codestr pointing to the first LOAD_CONST. +*/ +static Py_ssize_t +fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen, + Py_ssize_t c_start, Py_ssize_t opcode_end, + PyObject *consts, int n) +{ + /* Pre-conditions */ + assert(PyList_CheckExact(consts)); + + /* Buildup new tuple of constants */ + PyObject *newconst = PyTuple_New(n); + if (newconst == NULL) { + return -1; + } + + for (Py_ssize_t i = 0, pos = c_start; i < n; i++, pos++) { + assert(pos < opcode_end); + pos = find_op(codestr, codelen, pos); + assert(_Py_OPCODE(codestr[pos]) == LOAD_CONST); + + unsigned int arg = get_arg(codestr, pos); + PyObject *constant = PyList_GET_ITEM(consts, arg); + Py_INCREF(constant); + PyTuple_SET_ITEM(newconst, i, constant); + } + + Py_ssize_t index = PyList_GET_SIZE(consts); +#if SIZEOF_SIZE_T > SIZEOF_INT + if ((size_t)index >= UINT_MAX - 1) { + Py_DECREF(newconst); + PyErr_SetString(PyExc_OverflowError, "too many constants"); + return -1; + } +#endif + + /* Append folded constant onto consts */ + if (PyList_Append(consts, newconst)) { + Py_DECREF(newconst); + return -1; + } + Py_DECREF(newconst); + + return copy_op_arg(codestr, c_start, LOAD_CONST, + (unsigned int)index, opcode_end); +} + +static unsigned int * +markblocks(_Py_CODEUNIT *code, Py_ssize_t len) +{ + unsigned int *blocks = PyMem_New(unsigned int, len); + int i, j, opcode, blockcnt = 0; + + if (blocks == NULL) { + PyErr_NoMemory(); + return NULL; + } + memset(blocks, 0, len*sizeof(int)); + + /* Mark labels in the first pass */ + for (i = 0; i < len; i++) { + opcode = _Py_OPCODE(code[i]); + switch (opcode) { + case FOR_ITER: + case JUMP_FORWARD: + case JUMP_IF_FALSE_OR_POP: + case JUMP_IF_TRUE_OR_POP: + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + case JUMP_ABSOLUTE: + case SETUP_FINALLY: + case SETUP_WITH: + case SETUP_ASYNC_WITH: + case CALL_FINALLY: + j = GETJUMPTGT(code, i); + assert(j < len); + blocks[j] = 1; + break; + } + } + /* Build block numbers in the second pass */ + for (i = 0; i < len; i++) { + blockcnt += blocks[i]; /* increment blockcnt over labels */ + blocks[i] = blockcnt; + } + return blocks; +} + +/* Perform basic peephole optimizations to components of a code object. + The consts object should still be in list form to allow new constants + to be appended. + + To keep the optimizer simple, it bails when the lineno table has complex + encoding for gaps >= 255. + + Optimizations are restricted to simple transformations occurring within a + single basic block. All transformations keep the code size the same or + smaller. For those that reduce size, the gaps are initially filled with + NOPs. Later those NOPs are removed and the jump addresses retargeted in + a single pass. */ + +PyObject * +PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, + PyObject *lnotab_obj) +{ + Py_ssize_t h, i, nexti, op_start, tgt; + unsigned int j, nops; + unsigned char opcode, nextop; + _Py_CODEUNIT *codestr = NULL; + unsigned char *lnotab; + unsigned int cum_orig_offset, last_offset; + Py_ssize_t tabsiz; + // Count runs of consecutive LOAD_CONSTs + unsigned int cumlc = 0, lastlc = 0; + unsigned int *blocks = NULL; + + /* Bail out if an exception is set */ + if (PyErr_Occurred()) + goto exitError; + + /* Bypass optimization when the lnotab table is too complex */ + assert(PyBytes_Check(lnotab_obj)); + lnotab = (unsigned char*)PyBytes_AS_STRING(lnotab_obj); + tabsiz = PyBytes_GET_SIZE(lnotab_obj); + assert(tabsiz == 0 || Py_REFCNT(lnotab_obj) == 1); + + /* Don't optimize if lnotab contains instruction pointer delta larger + than +255 (encoded as multiple bytes), just to keep the peephole optimizer + simple. The optimizer leaves line number deltas unchanged. */ + + for (i = 0; i < tabsiz; i += 2) { + if (lnotab[i] == 255) { + goto exitUnchanged; + } + } + + assert(PyBytes_Check(code)); + Py_ssize_t codesize = PyBytes_GET_SIZE(code); + assert(codesize % sizeof(_Py_CODEUNIT) == 0); + Py_ssize_t codelen = codesize / sizeof(_Py_CODEUNIT); + if (codelen > INT_MAX) { + /* Python assembler is limited to INT_MAX: see assembler.a_offset in + compile.c. */ + goto exitUnchanged; + } + + /* Make a modifiable copy of the code string */ + codestr = (_Py_CODEUNIT *)PyMem_Malloc(codesize); + if (codestr == NULL) { + PyErr_NoMemory(); + goto exitError; + } + memcpy(codestr, PyBytes_AS_STRING(code), codesize); + + blocks = markblocks(codestr, codelen); + if (blocks == NULL) + goto exitError; + assert(PyList_Check(consts)); + + for (i=find_op(codestr, codelen, 0) ; i= 1 && _Py_OPCODE(codestr[op_start-1]) == EXTENDED_ARG) { + op_start--; + } + + nexti = i + 1; + while (nexti < codelen && _Py_OPCODE(codestr[nexti]) == EXTENDED_ARG) + nexti++; + nextop = nexti < codelen ? _Py_OPCODE(codestr[nexti]) : 0; + + lastlc = cumlc; + cumlc = 0; + + switch (opcode) { + /* Skip over LOAD_CONST trueconst + POP_JUMP_IF_FALSE xx. This improves + "while 1" performance. */ + case LOAD_CONST: + cumlc = lastlc + 1; + if (nextop != POP_JUMP_IF_FALSE || + !ISBASICBLOCK(blocks, op_start, i + 1)) { + break; + } + PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); + int is_true = PyObject_IsTrue(cnt); + if (is_true == -1) { + goto exitError; + } + if (is_true == 1) { + fill_nops(codestr, op_start, nexti + 1); + cumlc = 0; + } + break; + + /* Try to fold tuples of constants. + Skip over BUILD_SEQN 1 UNPACK_SEQN 1. + Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. + Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ + case BUILD_TUPLE: + j = get_arg(codestr, i); + if (j > 0 && lastlc >= j) { + h = lastn_const_start(codestr, op_start, j); + if (ISBASICBLOCK(blocks, h, op_start)) { + h = fold_tuple_on_constants(codestr, codelen, + h, i+1, consts, j); + break; + } + } + if (nextop != UNPACK_SEQUENCE || + !ISBASICBLOCK(blocks, op_start, i + 1) || + j != get_arg(codestr, nexti)) + break; + if (j < 2) { + fill_nops(codestr, op_start, nexti + 1); + } else if (j == 2) { + codestr[op_start] = PACKOPARG(ROT_TWO, 0); + fill_nops(codestr, op_start + 1, nexti + 1); + } else if (j == 3) { + codestr[op_start] = PACKOPARG(ROT_THREE, 0); + codestr[op_start + 1] = PACKOPARG(ROT_TWO, 0); + fill_nops(codestr, op_start + 2, nexti + 1); + } + break; + + /* Simplify conditional jump to conditional jump where the + result of the first test implies the success of a similar + test or the failure of the opposite test. + Arises in code like: + "a and b or c" + "(a and b) and c" + "(a or b) or c" + "(a or b) and c" + x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z + --> x:JUMP_IF_FALSE_OR_POP z + x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z + --> x:POP_JUMP_IF_FALSE y+1 + where y+1 is the instruction following the second test. + */ + case JUMP_IF_FALSE_OR_POP: + case JUMP_IF_TRUE_OR_POP: + h = get_arg(codestr, i) / sizeof(_Py_CODEUNIT); + tgt = find_op(codestr, codelen, h); + + j = _Py_OPCODE(codestr[tgt]); + if (CONDITIONAL_JUMP(j)) { + /* NOTE: all possible jumps here are absolute. */ + if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) { + /* The second jump will be taken iff the first is. + The current opcode inherits its target's + stack effect */ + h = set_arg(codestr, i, get_arg(codestr, tgt)); + } else { + /* The second jump is not taken if the first is (so + jump past it), and all conditional jumps pop their + argument when they're not taken (so change the + first jump to pop its argument when it's taken). */ + Py_ssize_t arg = (tgt + 1); + /* cannot overflow: codelen <= INT_MAX */ + assert((size_t)arg <= UINT_MAX / sizeof(_Py_CODEUNIT)); + arg *= sizeof(_Py_CODEUNIT); + h = set_arg(codestr, i, (unsigned int)arg); + j = opcode == JUMP_IF_TRUE_OR_POP ? + POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE; + } + + if (h >= 0) { + nexti = h; + codestr[nexti] = PACKOPARG(j, _Py_OPARG(codestr[nexti])); + break; + } + } + /* Intentional fallthrough */ + + /* Replace jumps to unconditional jumps */ + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + case JUMP_FORWARD: + case JUMP_ABSOLUTE: + h = GETJUMPTGT(codestr, i); + tgt = find_op(codestr, codelen, h); + /* Replace JUMP_* to a RETURN into just a RETURN */ + if (UNCONDITIONAL_JUMP(opcode) && + _Py_OPCODE(codestr[tgt]) == RETURN_VALUE) { + codestr[op_start] = PACKOPARG(RETURN_VALUE, 0); + fill_nops(codestr, op_start + 1, i + 1); + } else if (UNCONDITIONAL_JUMP(_Py_OPCODE(codestr[tgt]))) { + size_t arg = GETJUMPTGT(codestr, tgt); + if (opcode == JUMP_FORWARD) { /* JMP_ABS can go backwards */ + opcode = JUMP_ABSOLUTE; + } else if (!ABSOLUTE_JUMP(opcode)) { + if (arg < (size_t)(i + 1)) { + break; /* No backward relative jumps */ + } + arg -= i + 1; /* Calc relative jump addr */ + } + /* cannot overflow: codelen <= INT_MAX */ + assert(arg <= (UINT_MAX / sizeof(_Py_CODEUNIT))); + arg *= sizeof(_Py_CODEUNIT); + copy_op_arg(codestr, op_start, opcode, + (unsigned int)arg, i + 1); + } + break; + + /* Remove unreachable ops after RETURN */ + case RETURN_VALUE: + h = i + 1; + /* END_FINALLY should be kept since it denotes the end of + the 'finally' block in frame_setlineno() in frameobject.c. + SETUP_FINALLY should be kept for balancing. + */ + while (h < codelen && ISBASICBLOCK(blocks, i, h) && + _Py_OPCODE(codestr[h]) != END_FINALLY) + { + if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY) { + while (h > i + 1 && + _Py_OPCODE(codestr[h - 1]) == EXTENDED_ARG) + { + h--; + } + break; + } + h++; + } + if (h > i + 1) { + fill_nops(codestr, i + 1, h); + nexti = find_op(codestr, codelen, h); + } + break; + } + } + + /* Fixup lnotab */ + for (i = 0, nops = 0; i < codelen; i++) { + size_t block = (size_t)i - nops; + /* cannot overflow: codelen <= INT_MAX */ + assert(block <= UINT_MAX); + /* original code offset => new code offset */ + blocks[i] = (unsigned int)block; + if (_Py_OPCODE(codestr[i]) == NOP) { + nops++; + } + } + cum_orig_offset = 0; + last_offset = 0; + for (i=0 ; i < tabsiz ; i+=2) { + unsigned int offset_delta, new_offset; + cum_orig_offset += lnotab[i]; + assert(cum_orig_offset % sizeof(_Py_CODEUNIT) == 0); + new_offset = blocks[cum_orig_offset / sizeof(_Py_CODEUNIT)] * + sizeof(_Py_CODEUNIT); + offset_delta = new_offset - last_offset; + assert(offset_delta <= 255); + lnotab[i] = (unsigned char)offset_delta; + last_offset = new_offset; + } + + /* Remove NOPs and fixup jump targets */ + for (op_start = i = h = 0; i < codelen; i++, op_start = i) { + j = _Py_OPARG(codestr[i]); + while (_Py_OPCODE(codestr[i]) == EXTENDED_ARG) { + i++; + j = j<<8 | _Py_OPARG(codestr[i]); + } + opcode = _Py_OPCODE(codestr[i]); + switch (opcode) { + case NOP:continue; + + case JUMP_ABSOLUTE: + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + case JUMP_IF_FALSE_OR_POP: + case JUMP_IF_TRUE_OR_POP: + j = blocks[j / sizeof(_Py_CODEUNIT)] * sizeof(_Py_CODEUNIT); + break; + + case FOR_ITER: + case JUMP_FORWARD: + case SETUP_FINALLY: + case SETUP_WITH: + case SETUP_ASYNC_WITH: + case CALL_FINALLY: + j = blocks[j / sizeof(_Py_CODEUNIT) + i + 1] - blocks[i] - 1; + j *= sizeof(_Py_CODEUNIT); + break; + } + Py_ssize_t ilen = i - op_start + 1; + if (instrsize(j) > ilen) { + goto exitUnchanged; + } + assert(ilen <= INT_MAX); + /* If instrsize(j) < ilen, we'll emit EXTENDED_ARG 0 */ + write_op_arg(codestr + h, opcode, j, (int)ilen); + h += ilen; + } + assert(h + (Py_ssize_t)nops == codelen); + + PyMem_Free(blocks); + code = PyBytes_FromStringAndSize((char *)codestr, h * sizeof(_Py_CODEUNIT)); + PyMem_Free(codestr); + return code; + + exitError: + code = NULL; + + exitUnchanged: + Py_XINCREF(code); + PyMem_Free(blocks); + PyMem_Free(codestr); + return code; +} diff --git a/python/Python/preconfig.c b/python/Python/preconfig.c new file mode 100755 index 0000000..89a6227 --- /dev/null +++ b/python/Python/preconfig.c @@ -0,0 +1,967 @@ +#include "Python.h" +#include "pycore_initconfig.h" +#include "pycore_getopt.h" +#include "pycore_pystate.h" /* _PyRuntime_Initialize() */ +#include /* setlocale() */ + + +#define DECODE_LOCALE_ERR(NAME, LEN) \ + (((LEN) == -2) \ + ? _PyStatus_ERR("cannot decode " NAME) \ + : _PyStatus_NO_MEMORY()) + + +/* Forward declarations */ +static void +preconfig_copy(PyPreConfig *config, const PyPreConfig *config2); + + +/* --- File system encoding/errors -------------------------------- */ + +/* The filesystem encoding is chosen by config_init_fs_encoding(), + see also initfsencoding(). + + Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors + are encoded to UTF-8. */ +const char *Py_FileSystemDefaultEncoding = NULL; +int Py_HasFileSystemDefaultEncoding = 0; +const char *Py_FileSystemDefaultEncodeErrors = NULL; +int _Py_HasFileSystemDefaultEncodeErrors = 0; + +void +_Py_ClearFileSystemEncoding(void) +{ + if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { + PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); + Py_FileSystemDefaultEncoding = NULL; + } + if (!_Py_HasFileSystemDefaultEncodeErrors && Py_FileSystemDefaultEncodeErrors) { + PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors); + Py_FileSystemDefaultEncodeErrors = NULL; + } +} + + +/* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors + global configuration variables. */ +int +_Py_SetFileSystemEncoding(const char *encoding, const char *errors) +{ + char *encoding2 = _PyMem_RawStrdup(encoding); + if (encoding2 == NULL) { + return -1; + } + + char *errors2 = _PyMem_RawStrdup(errors); + if (errors2 == NULL) { + PyMem_RawFree(encoding2); + return -1; + } + + _Py_ClearFileSystemEncoding(); + + Py_FileSystemDefaultEncoding = encoding2; + Py_HasFileSystemDefaultEncoding = 0; + + Py_FileSystemDefaultEncodeErrors = errors2; + _Py_HasFileSystemDefaultEncodeErrors = 0; + return 0; +} + + +/* --- _PyArgv ---------------------------------------------------- */ + +/* Decode bytes_argv using Py_DecodeLocale() */ +PyStatus +_PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list) +{ + PyWideStringList wargv = _PyWideStringList_INIT; + if (args->use_bytes_argv) { + size_t size = sizeof(wchar_t*) * args->argc; + wargv.items = (wchar_t **)PyMem_RawMalloc(size); + if (wargv.items == NULL) { + return _PyStatus_NO_MEMORY(); + } + + for (Py_ssize_t i = 0; i < args->argc; i++) { + size_t len; + wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len); + if (arg == NULL) { + _PyWideStringList_Clear(&wargv); + return DECODE_LOCALE_ERR("command line arguments", + (Py_ssize_t)len); + } + wargv.items[i] = arg; + wargv.length++; + } + + _PyWideStringList_Clear(list); + *list = wargv; + } + else { + wargv.length = args->argc; + wargv.items = (wchar_t **)args->wchar_argv; + if (_PyWideStringList_Copy(list, &wargv) < 0) { + return _PyStatus_NO_MEMORY(); + } + } + return _PyStatus_OK(); +} + + +/* --- _PyPreCmdline ------------------------------------------------- */ + +void +_PyPreCmdline_Clear(_PyPreCmdline *cmdline) +{ + _PyWideStringList_Clear(&cmdline->argv); + _PyWideStringList_Clear(&cmdline->xoptions); +} + + +PyStatus +_PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) +{ + return _PyArgv_AsWstrList(args, &cmdline->argv); +} + + +static void +precmdline_get_preconfig(_PyPreCmdline *cmdline, const PyPreConfig *config) +{ +#define COPY_ATTR(ATTR) \ + if (config->ATTR != -1) { \ + cmdline->ATTR = config->ATTR; \ + } + + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + +#undef COPY_ATTR +} + + +static void +precmdline_set_preconfig(const _PyPreCmdline *cmdline, PyPreConfig *config) +{ +#define COPY_ATTR(ATTR) \ + config->ATTR = cmdline->ATTR + + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + +#undef COPY_ATTR +} + + +PyStatus +_PyPreCmdline_SetConfig(const _PyPreCmdline *cmdline, PyConfig *config) +{ +#define COPY_ATTR(ATTR) \ + config->ATTR = cmdline->ATTR + + PyStatus status = _PyWideStringList_Extend(&config->xoptions, &cmdline->xoptions); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + return _PyStatus_OK(); + +#undef COPY_ATTR +} + + +/* Parse the command line arguments */ +static PyStatus +precmdline_parse_cmdline(_PyPreCmdline *cmdline) +{ + const PyWideStringList *argv = &cmdline->argv; + + _PyOS_ResetGetOpt(); + /* Don't log parsing errors into stderr here: PyConfig_Read() + is responsible for that */ + _PyOS_opterr = 0; + do { + int longindex = -1; + int c = _PyOS_GetOpt(argv->length, argv->items, &longindex); + + if (c == EOF || c == 'c' || c == 'm') { + break; + } + + switch (c) { + case 'E': + cmdline->use_environment = 0; + break; + + case 'I': + cmdline->isolated = 1; + break; + + case 'X': + { + PyStatus status = PyWideStringList_Append(&cmdline->xoptions, + _PyOS_optarg); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + break; + } + + default: + /* ignore other argument: + handled by PyConfig_Read() */ + break; + } + } while (1); + + return _PyStatus_OK(); +} + + +PyStatus +_PyPreCmdline_Read(_PyPreCmdline *cmdline, const PyPreConfig *preconfig) +{ + precmdline_get_preconfig(cmdline, preconfig); + + if (preconfig->parse_argv) { + PyStatus status = precmdline_parse_cmdline(cmdline); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + /* isolated, use_environment */ + if (cmdline->isolated < 0) { + cmdline->isolated = 0; + } + if (cmdline->isolated > 0) { + cmdline->use_environment = 0; + } + if (cmdline->use_environment < 0) { + cmdline->use_environment = 0; + } + + /* dev_mode */ + if ((cmdline->dev_mode < 0) + && (_Py_get_xoption(&cmdline->xoptions, L"dev") + || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE"))) + { + cmdline->dev_mode = 1; + } + if (cmdline->dev_mode < 0) { + cmdline->dev_mode = 0; + } + + assert(cmdline->use_environment >= 0); + assert(cmdline->isolated >= 0); + assert(cmdline->dev_mode >= 0); + + return _PyStatus_OK(); +} + + +/* --- PyPreConfig ----------------------------------------------- */ + + +void +_PyPreConfig_InitCompatConfig(PyPreConfig *config) +{ + memset(config, 0, sizeof(*config)); + + config->_config_init = (int)_PyConfig_INIT_COMPAT; + config->parse_argv = 0; + config->isolated = -1; + config->use_environment = -1; + config->configure_locale = 1; + + /* bpo-36443: C locale coercion (PEP 538) and UTF-8 Mode (PEP 540) + are disabled by default using the Compat configuration. + + Py_UTF8Mode=1 enables the UTF-8 mode. PYTHONUTF8 environment variable + is ignored (even if use_environment=1). */ + config->utf8_mode = 0; + config->coerce_c_locale = 0; + config->coerce_c_locale_warn = 0; + + config->dev_mode = -1; + config->allocator = PYMEM_ALLOCATOR_NOT_SET; +#ifdef MS_WINDOWS + config->legacy_windows_fs_encoding = -1; +#endif +} + + +void +PyPreConfig_InitPythonConfig(PyPreConfig *config) +{ + _PyPreConfig_InitCompatConfig(config); + + config->_config_init = (int)_PyConfig_INIT_PYTHON; + config->isolated = 0; + config->parse_argv = 1; + config->use_environment = 1; + /* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540) + depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE + environment variables. */ + config->coerce_c_locale = -1; + config->coerce_c_locale_warn = -1; + config->utf8_mode = -1; +#ifdef MS_WINDOWS + config->legacy_windows_fs_encoding = 0; +#endif +} + + +void +PyPreConfig_InitIsolatedConfig(PyPreConfig *config) +{ + _PyPreConfig_InitCompatConfig(config); + + config->_config_init = (int)_PyConfig_INIT_ISOLATED; + config->configure_locale = 0; + config->isolated = 1; + config->use_environment = 0; + config->utf8_mode = 0; + config->dev_mode = 0; +#ifdef MS_WINDOWS + config->legacy_windows_fs_encoding = 0; +#endif +} + + +PyStatus +_PyPreConfig_InitFromPreConfig(PyPreConfig *config, + const PyPreConfig *config2) +{ + PyPreConfig_InitPythonConfig(config); + preconfig_copy(config, config2); + return _PyStatus_OK(); +} + + +void +_PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config) +{ + _PyConfigInitEnum config_init = (_PyConfigInitEnum)config->_config_init; + switch (config_init) { + case _PyConfig_INIT_PYTHON: + PyPreConfig_InitPythonConfig(preconfig); + break; + case _PyConfig_INIT_ISOLATED: + PyPreConfig_InitIsolatedConfig(preconfig); + break; + case _PyConfig_INIT_COMPAT: + default: + _PyPreConfig_InitCompatConfig(preconfig); + } + + _PyPreConfig_GetConfig(preconfig, config); +} + + +static void +preconfig_copy(PyPreConfig *config, const PyPreConfig *config2) +{ +#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR + + COPY_ATTR(_config_init); + COPY_ATTR(parse_argv); + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(configure_locale); + COPY_ATTR(dev_mode); + COPY_ATTR(coerce_c_locale); + COPY_ATTR(coerce_c_locale_warn); + COPY_ATTR(utf8_mode); + COPY_ATTR(allocator); +#ifdef MS_WINDOWS + COPY_ATTR(legacy_windows_fs_encoding); +#endif + +#undef COPY_ATTR +} + + +PyObject* +_PyPreConfig_AsDict(const PyPreConfig *config) +{ + PyObject *dict; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + +#define SET_ITEM_INT(ATTR) \ + do { \ + PyObject *obj = PyLong_FromLong(config->ATTR); \ + if (obj == NULL) { \ + goto fail; \ + } \ + int res = PyDict_SetItemString(dict, #ATTR, obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) + + SET_ITEM_INT(_config_init); + SET_ITEM_INT(parse_argv); + SET_ITEM_INT(isolated); + SET_ITEM_INT(use_environment); + SET_ITEM_INT(configure_locale); + SET_ITEM_INT(coerce_c_locale); + SET_ITEM_INT(coerce_c_locale_warn); + SET_ITEM_INT(utf8_mode); +#ifdef MS_WINDOWS + SET_ITEM_INT(legacy_windows_fs_encoding); +#endif + SET_ITEM_INT(dev_mode); + SET_ITEM_INT(allocator); + return dict; + +fail: + Py_DECREF(dict); + return NULL; + +#undef SET_ITEM_INT +} + + +void +_PyPreConfig_GetConfig(PyPreConfig *preconfig, const PyConfig *config) +{ +#define COPY_ATTR(ATTR) \ + if (config->ATTR != -1) { \ + preconfig->ATTR = config->ATTR; \ + } + + COPY_ATTR(parse_argv); + COPY_ATTR(isolated); + COPY_ATTR(use_environment); + COPY_ATTR(dev_mode); + +#undef COPY_ATTR +} + + +static void +preconfig_get_global_vars(PyPreConfig *config) +{ + if (config->_config_init != _PyConfig_INIT_COMPAT) { + /* Python and Isolated configuration ignore global variables */ + return; + } + +#define COPY_FLAG(ATTR, VALUE) \ + if (config->ATTR < 0) { \ + config->ATTR = VALUE; \ + } +#define COPY_NOT_FLAG(ATTR, VALUE) \ + if (config->ATTR < 0) { \ + config->ATTR = !(VALUE); \ + } + + COPY_FLAG(isolated, Py_IsolatedFlag); + COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); + if (Py_UTF8Mode > 0) { + config->utf8_mode = Py_UTF8Mode; + } +#ifdef MS_WINDOWS + COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); +#endif + +#undef COPY_FLAG +#undef COPY_NOT_FLAG +} + + +static void +preconfig_set_global_vars(const PyPreConfig *config) +{ +#define COPY_FLAG(ATTR, VAR) \ + if (config->ATTR >= 0) { \ + VAR = config->ATTR; \ + } +#define COPY_NOT_FLAG(ATTR, VAR) \ + if (config->ATTR >= 0) { \ + VAR = !config->ATTR; \ + } + + COPY_FLAG(isolated, Py_IsolatedFlag); + COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); +#ifdef MS_WINDOWS + COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); +#endif + COPY_FLAG(utf8_mode, Py_UTF8Mode); + +#undef COPY_FLAG +#undef COPY_NOT_FLAG +} + + +const char* +_Py_GetEnv(int use_environment, const char *name) +{ + assert(use_environment >= 0); + + if (!use_environment) { + return NULL; + } + + const char *var = getenv(name); + if (var && var[0] != '\0') { + return var; + } + else { + return NULL; + } +} + + +int +_Py_str_to_int(const char *str, int *result) +{ + const char *endptr = str; + errno = 0; + long value = strtol(str, (char **)&endptr, 10); + if (*endptr != '\0' || errno == ERANGE) { + return -1; + } + if (value < INT_MIN || value > INT_MAX) { + return -1; + } + + *result = (int)value; + return 0; +} + + +void +_Py_get_env_flag(int use_environment, int *flag, const char *name) +{ + const char *var = _Py_GetEnv(use_environment, name); + if (!var) { + return; + } + int value; + if (_Py_str_to_int(var, &value) < 0 || value < 0) { + /* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */ + value = 1; + } + if (*flag < value) { + *flag = value; + } +} + + +const wchar_t* +_Py_get_xoption(const PyWideStringList *xoptions, const wchar_t *name) +{ + for (Py_ssize_t i=0; i < xoptions->length; i++) { + const wchar_t *option = xoptions->items[i]; + size_t len; + wchar_t *sep = wcschr(option, L'='); + if (sep != NULL) { + len = (sep - option); + } + else { + len = wcslen(option); + } + if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') { + return option; + } + } + return NULL; +} + + +static PyStatus +preconfig_init_utf8_mode(PyPreConfig *config, const _PyPreCmdline *cmdline) +{ +#ifdef MS_WINDOWS + if (config->legacy_windows_fs_encoding) { + config->utf8_mode = 0; + } +#endif + + if (config->utf8_mode >= 0) { + return _PyStatus_OK(); + } + + const wchar_t *xopt; + xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); + if (xopt) { + wchar_t *sep = wcschr(xopt, L'='); + if (sep) { + xopt = sep + 1; + if (wcscmp(xopt, L"1") == 0) { + config->utf8_mode = 1; + } + else if (wcscmp(xopt, L"0") == 0) { + config->utf8_mode = 0; + } + else { + return _PyStatus_ERR("invalid -X utf8 option value"); + } + } + else { + config->utf8_mode = 1; + } + return _PyStatus_OK(); + } + + const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8"); + if (opt) { + if (strcmp(opt, "1") == 0) { + config->utf8_mode = 1; + } + else if (strcmp(opt, "0") == 0) { + config->utf8_mode = 0; + } + else { + return _PyStatus_ERR("invalid PYTHONUTF8 environment " + "variable value"); + } + return _PyStatus_OK(); + } + + +#ifndef MS_WINDOWS + if (config->utf8_mode < 0) { + /* The C locale and the POSIX locale enable the UTF-8 Mode (PEP 540) */ + const char *ctype_loc = setlocale(LC_CTYPE, NULL); + if (ctype_loc != NULL + && (strcmp(ctype_loc, "C") == 0 + || strcmp(ctype_loc, "POSIX") == 0)) + { + config->utf8_mode = 1; + } + } +#endif + + if (config->utf8_mode < 0) { + config->utf8_mode = 0; + } + return _PyStatus_OK(); +} + + +static void +preconfig_init_coerce_c_locale(PyPreConfig *config) +{ + if (!config->configure_locale) { + config->coerce_c_locale = 0; + config->coerce_c_locale_warn = 0; + return; + } + + const char *env = _Py_GetEnv(config->use_environment, "PYTHONCOERCECLOCALE"); + if (env) { + if (strcmp(env, "0") == 0) { + if (config->coerce_c_locale < 0) { + config->coerce_c_locale = 0; + } + } + else if (strcmp(env, "warn") == 0) { + if (config->coerce_c_locale_warn < 0) { + config->coerce_c_locale_warn = 1; + } + } + else { + if (config->coerce_c_locale < 0) { + config->coerce_c_locale = 1; + } + } + } + + /* Test if coerce_c_locale equals to -1 or equals to 1: + PYTHONCOERCECLOCALE=1 doesn't imply that the C locale is always coerced. + It is only coerced if if the LC_CTYPE locale is "C". */ + if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) { + /* The C locale enables the C locale coercion (PEP 538) */ + if (_Py_LegacyLocaleDetected(0)) { + config->coerce_c_locale = 2; + } + else { + config->coerce_c_locale = 0; + } + } + + if (config->coerce_c_locale_warn < 0) { + config->coerce_c_locale_warn = 0; + } +} + + +static PyStatus +preconfig_init_allocator(PyPreConfig *config) +{ + if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) { + /* bpo-34247. The PYTHONMALLOC environment variable has the priority + over PYTHONDEV env var and "-X dev" command line option. + For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory + allocators to "malloc" (and not to "debug"). */ + const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC"); + if (envvar) { + PyMemAllocatorName name; + if (_PyMem_GetAllocatorName(envvar, &name) < 0) { + return _PyStatus_ERR("PYTHONMALLOC: unknown allocator"); + } + config->allocator = (int)name; + } + } + + if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) { + config->allocator = PYMEM_ALLOCATOR_DEBUG; + } + return _PyStatus_OK(); +} + + +static PyStatus +preconfig_read(PyPreConfig *config, _PyPreCmdline *cmdline) +{ + PyStatus status; + + status = _PyPreCmdline_Read(cmdline, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + precmdline_set_preconfig(cmdline, config); + + /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */ +#ifdef MS_WINDOWS + _Py_get_env_flag(config->use_environment, + &config->legacy_windows_fs_encoding, + "PYTHONLEGACYWINDOWSFSENCODING"); +#endif + + preconfig_init_coerce_c_locale(config); + + status = preconfig_init_utf8_mode(config, cmdline); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* allocator */ + status = preconfig_init_allocator(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + assert(config->coerce_c_locale >= 0); + assert(config->coerce_c_locale_warn >= 0); +#ifdef MS_WINDOWS + assert(config->legacy_windows_fs_encoding >= 0); +#endif + assert(config->utf8_mode >= 0); + assert(config->isolated >= 0); + assert(config->use_environment >= 0); + assert(config->dev_mode >= 0); + + return _PyStatus_OK(); +} + + +/* Read the configuration from: + + - command line arguments + - environment variables + - Py_xxx global configuration variables + - the LC_CTYPE locale */ +PyStatus +_PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) +{ + PyStatus status; + + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + preconfig_get_global_vars(config); + + /* Copy LC_CTYPE locale, since it's modified later */ + const char *loc = setlocale(LC_CTYPE, NULL); + if (loc == NULL) { + return _PyStatus_ERR("failed to LC_CTYPE locale"); + } + char *init_ctype_locale = _PyMem_RawStrdup(loc); + if (init_ctype_locale == NULL) { + return _PyStatus_NO_MEMORY(); + } + + /* Save the config to be able to restore it if encodings change */ + PyPreConfig save_config; + + status = _PyPreConfig_InitFromPreConfig(&save_config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* Set LC_CTYPE to the user preferred locale */ + if (config->configure_locale) { + _Py_SetLocaleFromEnv(LC_CTYPE); + } + + _PyPreCmdline cmdline = _PyPreCmdline_INIT; + int init_utf8_mode = Py_UTF8Mode; +#ifdef MS_WINDOWS + int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; +#endif + + if (args) { + status = _PyPreCmdline_SetArgv(&cmdline, args); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + } + + int locale_coerced = 0; + int loops = 0; + + while (1) { + int utf8_mode = config->utf8_mode; + + /* Watchdog to prevent an infinite loop */ + loops++; + if (loops == 3) { + status = _PyStatus_ERR("Encoding changed twice while " + "reading the configuration"); + goto done; + } + + /* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend + on Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag. */ + Py_UTF8Mode = config->utf8_mode; +#ifdef MS_WINDOWS + Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; +#endif + + status = preconfig_read(config, &cmdline); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + /* The legacy C locale assumes ASCII as the default text encoding, which + * causes problems not only for the CPython runtime, but also other + * components like GNU readline. + * + * Accordingly, when the CLI detects it, it attempts to coerce it to a + * more capable UTF-8 based alternative. + * + * See the documentation of the PYTHONCOERCECLOCALE setting for more + * details. + */ + int encoding_changed = 0; + if (config->coerce_c_locale && !locale_coerced) { + locale_coerced = 1; + _Py_CoerceLegacyLocale(0); + encoding_changed = 1; + } + + if (utf8_mode == -1) { + if (config->utf8_mode == 1) { + /* UTF-8 Mode enabled */ + encoding_changed = 1; + } + } + else { + if (config->utf8_mode != utf8_mode) { + encoding_changed = 1; + } + } + + if (!encoding_changed) { + break; + } + + /* Reset the configuration before reading again the configuration, + just keep UTF-8 Mode value. */ + int new_utf8_mode = config->utf8_mode; + int new_coerce_c_locale = config->coerce_c_locale; + preconfig_copy(config, &save_config); + config->utf8_mode = new_utf8_mode; + config->coerce_c_locale = new_coerce_c_locale; + + /* The encoding changed: read again the configuration + with the new encoding */ + } + status = _PyStatus_OK(); + +done: + if (init_ctype_locale != NULL) { + setlocale(LC_CTYPE, init_ctype_locale); + PyMem_RawFree(init_ctype_locale); + } + Py_UTF8Mode = init_utf8_mode ; +#ifdef MS_WINDOWS + Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; +#endif + _PyPreCmdline_Clear(&cmdline); + return status; +} + + +/* Write the pre-configuration: + + - set the memory allocators + - set Py_xxx global configuration variables + - set the LC_CTYPE locale (coerce C locale, PEP 538) and set the UTF-8 mode + (PEP 540) + + The applied configuration is written into _PyRuntime.preconfig. + If the C locale cannot be coerced, set coerce_c_locale to 0. + + Do nothing if called after Py_Initialize(): ignore the new + pre-configuration. */ +PyStatus +_PyPreConfig_Write(const PyPreConfig *src_config) +{ + PyPreConfig config; + + PyStatus status = _PyPreConfig_InitFromPreConfig(&config, src_config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (_PyRuntime.core_initialized) { + /* bpo-34008: Calling this functions after Py_Initialize() ignores + the new configuration. */ + return _PyStatus_OK(); + } + + PyMemAllocatorName name = (PyMemAllocatorName)config.allocator; + if (name != PYMEM_ALLOCATOR_NOT_SET) { + if (_PyMem_SetupAllocators(name) < 0) { + return _PyStatus_ERR("Unknown PYTHONMALLOC allocator"); + } + } + + preconfig_set_global_vars(&config); + + if (config.configure_locale) { + if (config.coerce_c_locale) { + if (!_Py_CoerceLegacyLocale(config.coerce_c_locale_warn)) { + /* C locale not coerced */ + config.coerce_c_locale = 0; + } + } + + /* Set LC_CTYPE to the user preferred locale */ + _Py_SetLocaleFromEnv(LC_CTYPE); + } + + /* Write the new pre-configuration into _PyRuntime */ + preconfig_copy(&_PyRuntime.preconfig, &config); + + return _PyStatus_OK(); +} diff --git a/python/Python/pyarena.c b/python/Python/pyarena.c new file mode 100755 index 0000000..aefb787 --- /dev/null +++ b/python/Python/pyarena.c @@ -0,0 +1,210 @@ +#include "Python.h" + +/* A simple arena block structure. + + Measurements with standard library modules suggest the average + allocation is about 20 bytes and that most compiles use a single + block. + + TODO(jhylton): Think about a realloc API, maybe just for the last + allocation? +*/ + +#define DEFAULT_BLOCK_SIZE 8192 +#define ALIGNMENT 8 + +typedef struct _block { + /* Total number of bytes owned by this block available to pass out. + * Read-only after initialization. The first such byte starts at + * ab_mem. + */ + size_t ab_size; + + /* Total number of bytes already passed out. The next byte available + * to pass out starts at ab_mem + ab_offset. + */ + size_t ab_offset; + + /* An arena maintains a singly-linked, NULL-terminated list of + * all blocks owned by the arena. These are linked via the + * ab_next member. + */ + struct _block *ab_next; + + /* Pointer to the first allocatable byte owned by this block. Read- + * only after initialization. + */ + void *ab_mem; +} block; + +/* The arena manages two kinds of memory, blocks of raw memory + and a list of PyObject* pointers. PyObjects are decrefed + when the arena is freed. +*/ + +struct _arena { + /* Pointer to the first block allocated for the arena, never NULL. + It is used only to find the first block when the arena is + being freed. + */ + block *a_head; + + /* Pointer to the block currently used for allocation. Its + ab_next field should be NULL. If it is not-null after a + call to block_alloc(), it means a new block has been allocated + and a_cur should be reset to point it. + */ + block *a_cur; + + /* A Python list object containing references to all the PyObject + pointers associated with this arena. They will be DECREFed + when the arena is freed. + */ + PyObject *a_objects; + +#if defined(Py_DEBUG) + /* Debug output */ + size_t total_allocs; + size_t total_size; + size_t total_blocks; + size_t total_block_size; + size_t total_big_blocks; +#endif +}; + +static block * +block_new(size_t size) +{ + /* Allocate header and block as one unit. + ab_mem points just past header. */ + block *b = (block *)PyMem_Malloc(sizeof(block) + size); + if (!b) + return NULL; + b->ab_size = size; + b->ab_mem = (void *)(b + 1); + b->ab_next = NULL; + b->ab_offset = (char *)_Py_ALIGN_UP(b->ab_mem, ALIGNMENT) - + (char *)(b->ab_mem); + return b; +} + +static void +block_free(block *b) { + while (b) { + block *next = b->ab_next; + PyMem_Free(b); + b = next; + } +} + +static void * +block_alloc(block *b, size_t size) +{ + void *p; + assert(b); + size = _Py_SIZE_ROUND_UP(size, ALIGNMENT); + if (b->ab_offset + size > b->ab_size) { + /* If we need to allocate more memory than will fit in + the default block, allocate a one-off block that is + exactly the right size. */ + /* TODO(jhylton): Think about space waste at end of block */ + block *newbl = block_new( + size < DEFAULT_BLOCK_SIZE ? + DEFAULT_BLOCK_SIZE : size); + if (!newbl) + return NULL; + assert(!b->ab_next); + b->ab_next = newbl; + b = newbl; + } + + assert(b->ab_offset + size <= b->ab_size); + p = (void *)(((char *)b->ab_mem) + b->ab_offset); + b->ab_offset += size; + return p; +} + +PyArena * +PyArena_New() +{ + PyArena* arena = (PyArena *)PyMem_Malloc(sizeof(PyArena)); + if (!arena) + return (PyArena*)PyErr_NoMemory(); + + arena->a_head = block_new(DEFAULT_BLOCK_SIZE); + arena->a_cur = arena->a_head; + if (!arena->a_head) { + PyMem_Free((void *)arena); + return (PyArena*)PyErr_NoMemory(); + } + arena->a_objects = PyList_New(0); + if (!arena->a_objects) { + block_free(arena->a_head); + PyMem_Free((void *)arena); + return (PyArena*)PyErr_NoMemory(); + } +#if defined(Py_DEBUG) + arena->total_allocs = 0; + arena->total_size = 0; + arena->total_blocks = 1; + arena->total_block_size = DEFAULT_BLOCK_SIZE; + arena->total_big_blocks = 0; +#endif + return arena; +} + +void +PyArena_Free(PyArena *arena) +{ + assert(arena); +#if defined(Py_DEBUG) + /* + fprintf(stderr, + "alloc=%zu size=%zu blocks=%zu block_size=%zu big=%zu objects=%zu\n", + arena->total_allocs, arena->total_size, arena->total_blocks, + arena->total_block_size, arena->total_big_blocks, + PyList_Size(arena->a_objects)); + */ +#endif + block_free(arena->a_head); + /* This property normally holds, except when the code being compiled + is sys.getobjects(0), in which case there will be two references. + assert(arena->a_objects->ob_refcnt == 1); + */ + + Py_DECREF(arena->a_objects); + PyMem_Free(arena); +} + +void * +PyArena_Malloc(PyArena *arena, size_t size) +{ + void *p = block_alloc(arena->a_cur, size); + if (!p) + return PyErr_NoMemory(); +#if defined(Py_DEBUG) + arena->total_allocs++; + arena->total_size += size; +#endif + /* Reset cur if we allocated a new block. */ + if (arena->a_cur->ab_next) { + arena->a_cur = arena->a_cur->ab_next; +#if defined(Py_DEBUG) + arena->total_blocks++; + arena->total_block_size += arena->a_cur->ab_size; + if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE) + ++arena->total_big_blocks; +#endif + } + return p; +} + +int +PyArena_AddPyObject(PyArena *arena, PyObject *obj) +{ + int r = PyList_Append(arena->a_objects, obj); + if (r >= 0) { + Py_DECREF(obj); + } + return r; +} diff --git a/python/Python/pyctype.c b/python/Python/pyctype.c new file mode 100755 index 0000000..da117d5 --- /dev/null +++ b/python/Python/pyctype.c @@ -0,0 +1,214 @@ +#include "Python.h" + +/* Our own locale-independent ctype.h-like macros */ + +const unsigned int _Py_ctype_table[256] = { + 0, /* 0x0 '\x00' */ + 0, /* 0x1 '\x01' */ + 0, /* 0x2 '\x02' */ + 0, /* 0x3 '\x03' */ + 0, /* 0x4 '\x04' */ + 0, /* 0x5 '\x05' */ + 0, /* 0x6 '\x06' */ + 0, /* 0x7 '\x07' */ + 0, /* 0x8 '\x08' */ + PY_CTF_SPACE, /* 0x9 '\t' */ + PY_CTF_SPACE, /* 0xa '\n' */ + PY_CTF_SPACE, /* 0xb '\v' */ + PY_CTF_SPACE, /* 0xc '\f' */ + PY_CTF_SPACE, /* 0xd '\r' */ + 0, /* 0xe '\x0e' */ + 0, /* 0xf '\x0f' */ + 0, /* 0x10 '\x10' */ + 0, /* 0x11 '\x11' */ + 0, /* 0x12 '\x12' */ + 0, /* 0x13 '\x13' */ + 0, /* 0x14 '\x14' */ + 0, /* 0x15 '\x15' */ + 0, /* 0x16 '\x16' */ + 0, /* 0x17 '\x17' */ + 0, /* 0x18 '\x18' */ + 0, /* 0x19 '\x19' */ + 0, /* 0x1a '\x1a' */ + 0, /* 0x1b '\x1b' */ + 0, /* 0x1c '\x1c' */ + 0, /* 0x1d '\x1d' */ + 0, /* 0x1e '\x1e' */ + 0, /* 0x1f '\x1f' */ + PY_CTF_SPACE, /* 0x20 ' ' */ + 0, /* 0x21 '!' */ + 0, /* 0x22 '"' */ + 0, /* 0x23 '#' */ + 0, /* 0x24 '$' */ + 0, /* 0x25 '%' */ + 0, /* 0x26 '&' */ + 0, /* 0x27 "'" */ + 0, /* 0x28 '(' */ + 0, /* 0x29 ')' */ + 0, /* 0x2a '*' */ + 0, /* 0x2b '+' */ + 0, /* 0x2c ',' */ + 0, /* 0x2d '-' */ + 0, /* 0x2e '.' */ + 0, /* 0x2f '/' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x30 '0' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x31 '1' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x32 '2' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x33 '3' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x34 '4' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x35 '5' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x36 '6' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x37 '7' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x38 '8' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x39 '9' */ + 0, /* 0x3a ':' */ + 0, /* 0x3b ';' */ + 0, /* 0x3c '<' */ + 0, /* 0x3d '=' */ + 0, /* 0x3e '>' */ + 0, /* 0x3f '?' */ + 0, /* 0x40 '@' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x41 'A' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x42 'B' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x43 'C' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x44 'D' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x45 'E' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x46 'F' */ + PY_CTF_UPPER, /* 0x47 'G' */ + PY_CTF_UPPER, /* 0x48 'H' */ + PY_CTF_UPPER, /* 0x49 'I' */ + PY_CTF_UPPER, /* 0x4a 'J' */ + PY_CTF_UPPER, /* 0x4b 'K' */ + PY_CTF_UPPER, /* 0x4c 'L' */ + PY_CTF_UPPER, /* 0x4d 'M' */ + PY_CTF_UPPER, /* 0x4e 'N' */ + PY_CTF_UPPER, /* 0x4f 'O' */ + PY_CTF_UPPER, /* 0x50 'P' */ + PY_CTF_UPPER, /* 0x51 'Q' */ + PY_CTF_UPPER, /* 0x52 'R' */ + PY_CTF_UPPER, /* 0x53 'S' */ + PY_CTF_UPPER, /* 0x54 'T' */ + PY_CTF_UPPER, /* 0x55 'U' */ + PY_CTF_UPPER, /* 0x56 'V' */ + PY_CTF_UPPER, /* 0x57 'W' */ + PY_CTF_UPPER, /* 0x58 'X' */ + PY_CTF_UPPER, /* 0x59 'Y' */ + PY_CTF_UPPER, /* 0x5a 'Z' */ + 0, /* 0x5b '[' */ + 0, /* 0x5c '\\' */ + 0, /* 0x5d ']' */ + 0, /* 0x5e '^' */ + 0, /* 0x5f '_' */ + 0, /* 0x60 '`' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x61 'a' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x62 'b' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x63 'c' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x64 'd' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x65 'e' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x66 'f' */ + PY_CTF_LOWER, /* 0x67 'g' */ + PY_CTF_LOWER, /* 0x68 'h' */ + PY_CTF_LOWER, /* 0x69 'i' */ + PY_CTF_LOWER, /* 0x6a 'j' */ + PY_CTF_LOWER, /* 0x6b 'k' */ + PY_CTF_LOWER, /* 0x6c 'l' */ + PY_CTF_LOWER, /* 0x6d 'm' */ + PY_CTF_LOWER, /* 0x6e 'n' */ + PY_CTF_LOWER, /* 0x6f 'o' */ + PY_CTF_LOWER, /* 0x70 'p' */ + PY_CTF_LOWER, /* 0x71 'q' */ + PY_CTF_LOWER, /* 0x72 'r' */ + PY_CTF_LOWER, /* 0x73 's' */ + PY_CTF_LOWER, /* 0x74 't' */ + PY_CTF_LOWER, /* 0x75 'u' */ + PY_CTF_LOWER, /* 0x76 'v' */ + PY_CTF_LOWER, /* 0x77 'w' */ + PY_CTF_LOWER, /* 0x78 'x' */ + PY_CTF_LOWER, /* 0x79 'y' */ + PY_CTF_LOWER, /* 0x7a 'z' */ + 0, /* 0x7b '{' */ + 0, /* 0x7c '|' */ + 0, /* 0x7d '}' */ + 0, /* 0x7e '~' */ + 0, /* 0x7f '\x7f' */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + + +const unsigned char _Py_ctype_tolower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +const unsigned char _Py_ctype_toupper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + diff --git a/python/Python/pyfpe.c b/python/Python/pyfpe.c new file mode 100755 index 0000000..31ef5d7 --- /dev/null +++ b/python/Python/pyfpe.c @@ -0,0 +1,15 @@ +/* These variables used to be used when Python was built with --with-fpectl, + * but support for that was dropped in 3.7. We continue to define them, + * though, because they may be referenced by extensions using the stable ABI. + */ + +#include "setjmp.h" + +jmp_buf PyFPE_jbuf; +int PyFPE_counter; + +double +PyFPE_dummy(void *dummy) +{ + return 1.0; +} diff --git a/python/Python/pyhash.c b/python/Python/pyhash.c new file mode 100755 index 0000000..c0355ae --- /dev/null +++ b/python/Python/pyhash.c @@ -0,0 +1,435 @@ +/* Set of hash utility functions to help maintaining the invariant that + if a==b then hash(a)==hash(b) + + All the utility functions (_Py_Hash*()) return "-1" to signify an error. +*/ +#include "Python.h" + +#ifdef __APPLE__ +# include +#elif defined(HAVE_LE64TOH) && defined(HAVE_ENDIAN_H) +# include +#elif defined(HAVE_LE64TOH) && defined(HAVE_SYS_ENDIAN_H) +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_Py_HashSecret_t _Py_HashSecret = {{0}}; + +#if Py_HASH_ALGORITHM == Py_HASH_EXTERNAL +extern PyHash_FuncDef PyHash_Func; +#else +static PyHash_FuncDef PyHash_Func; +#endif + +/* Count _Py_HashBytes() calls */ +#ifdef Py_HASH_STATS +#define Py_HASH_STATS_MAX 32 +static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0}; +#endif + +/* For numeric types, the hash of a number x is based on the reduction + of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that + hash(x) == hash(y) whenever x and y are numerically equal, even if + x and y have different types. + + A quick summary of the hashing strategy: + + (1) First define the 'reduction of x modulo P' for any rational + number x; this is a standard extension of the usual notion of + reduction modulo P for integers. If x == p/q (written in lowest + terms), the reduction is interpreted as the reduction of p times + the inverse of the reduction of q, all modulo P; if q is exactly + divisible by P then define the reduction to be infinity. So we've + got a well-defined map + + reduce : { rational numbers } -> { 0, 1, 2, ..., P-1, infinity }. + + (2) Now for a rational number x, define hash(x) by: + + reduce(x) if x >= 0 + -reduce(-x) if x < 0 + + If the result of the reduction is infinity (this is impossible for + integers, floats and Decimals) then use the predefined hash value + _PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead. + _PyHASH_INF, -_PyHASH_INF and _PyHASH_NAN are also used for the + hashes of float and Decimal infinities and nans. + + A selling point for the above strategy is that it makes it possible + to compute hashes of decimal and binary floating-point numbers + efficiently, even if the exponent of the binary or decimal number + is large. The key point is that + + reduce(x * y) == reduce(x) * reduce(y) (modulo _PyHASH_MODULUS) + + provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a + binary or decimal float is never infinity, since the denominator is a power + of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have, + for nonnegative x, + + reduce(x * 2**e) == reduce(x) * reduce(2**e) % _PyHASH_MODULUS + + reduce(x * 10**e) == reduce(x) * reduce(10**e) % _PyHASH_MODULUS + + and reduce(10**e) can be computed efficiently by the usual modular + exponentiation algorithm. For reduce(2**e) it's even better: since + P is of the form 2**n-1, reduce(2**e) is 2**(e mod n), and multiplication + by 2**(e mod n) modulo 2**n-1 just amounts to a rotation of bits. + + */ + +Py_hash_t +_Py_HashDouble(double v) +{ + int e, sign; + double m; + Py_uhash_t x, y; + + if (!Py_IS_FINITE(v)) { + if (Py_IS_INFINITY(v)) + return v > 0 ? _PyHASH_INF : -_PyHASH_INF; + else + return _PyHASH_NAN; + } + + m = frexp(v, &e); + + sign = 1; + if (m < 0) { + sign = -1; + m = -m; + } + + /* process 28 bits at a time; this should work well both for binary + and hexadecimal floating point. */ + x = 0; + while (m) { + x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28); + m *= 268435456.0; /* 2**28 */ + e -= 28; + y = (Py_uhash_t)m; /* pull out integer part */ + m -= y; + x += y; + if (x >= _PyHASH_MODULUS) + x -= _PyHASH_MODULUS; + } + + /* adjust for the exponent; first reduce it modulo _PyHASH_BITS */ + e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS); + x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e); + + x = x * sign; + if (x == (Py_uhash_t)-1) + x = (Py_uhash_t)-2; + return (Py_hash_t)x; +} + +Py_hash_t +_Py_HashPointer(void *p) +{ + Py_hash_t x; + size_t y = (size_t)p; + /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid + excessive hash collisions for dicts and sets */ + y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4)); + x = (Py_hash_t)y; + if (x == -1) + x = -2; + return x; +} + +Py_hash_t +_Py_HashBytes(const void *src, Py_ssize_t len) +{ + Py_hash_t x; + /* + We make the hash of the empty string be 0, rather than using + (prefix ^ suffix), since this slightly obfuscates the hash secret + */ + if (len == 0) { + return 0; + } + +#ifdef Py_HASH_STATS + hashstats[(len <= Py_HASH_STATS_MAX) ? len : 0]++; +#endif + +#if Py_HASH_CUTOFF > 0 + if (len < Py_HASH_CUTOFF) { + /* Optimize hashing of very small strings with inline DJBX33A. */ + Py_uhash_t hash; + const unsigned char *p = src; + hash = 5381; /* DJBX33A starts with 5381 */ + + switch(len) { + /* ((hash << 5) + hash) + *p == hash * 33 + *p */ + case 7: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ + case 6: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ + case 5: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ + case 4: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ + case 3: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ + case 2: hash = ((hash << 5) + hash) + *p++; /* fallthrough */ + case 1: hash = ((hash << 5) + hash) + *p++; break; + default: + Py_UNREACHABLE(); + } + hash ^= len; + hash ^= (Py_uhash_t) _Py_HashSecret.djbx33a.suffix; + x = (Py_hash_t)hash; + } + else +#endif /* Py_HASH_CUTOFF */ + x = PyHash_Func.hash(src, len); + + if (x == -1) + return -2; + return x; +} + +void +_PyHash_Fini(void) +{ +#ifdef Py_HASH_STATS + int i; + Py_ssize_t total = 0; + const char *fmt = "%2i %8" PY_FORMAT_SIZE_T "d %8" PY_FORMAT_SIZE_T "d\n"; + + fprintf(stderr, "len calls total\n"); + for (i = 1; i <= Py_HASH_STATS_MAX; i++) { + total += hashstats[i]; + fprintf(stderr, fmt, i, hashstats[i], total); + } + total += hashstats[0]; + fprintf(stderr, "> %8" PY_FORMAT_SIZE_T "d %8" PY_FORMAT_SIZE_T "d\n", + hashstats[0], total); +#endif +} + +PyHash_FuncDef * +PyHash_GetFuncDef(void) +{ + return &PyHash_Func; +} + +/* Optimized memcpy() for Windows */ +#ifdef _MSC_VER +# if SIZEOF_PY_UHASH_T == 4 +# define PY_UHASH_CPY(dst, src) do { \ + dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; \ + } while(0) +# elif SIZEOF_PY_UHASH_T == 8 +# define PY_UHASH_CPY(dst, src) do { \ + dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; \ + dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]; \ + } while(0) +# else +# error SIZEOF_PY_UHASH_T must be 4 or 8 +# endif /* SIZEOF_PY_UHASH_T */ +#else /* not Windows */ +# define PY_UHASH_CPY(dst, src) memcpy(dst, src, SIZEOF_PY_UHASH_T) +#endif /* _MSC_VER */ + + +#if Py_HASH_ALGORITHM == Py_HASH_FNV +/* ************************************************************************** + * Modified Fowler-Noll-Vo (FNV) hash function + */ +static Py_hash_t +fnv(const void *src, Py_ssize_t len) +{ + const unsigned char *p = src; + Py_uhash_t x; + Py_ssize_t remainder, blocks; + union { + Py_uhash_t value; + unsigned char bytes[SIZEOF_PY_UHASH_T]; + } block; + +#ifdef Py_DEBUG + assert(_Py_HashSecret_Initialized); +#endif + remainder = len % SIZEOF_PY_UHASH_T; + if (remainder == 0) { + /* Process at least one block byte by byte to reduce hash collisions + * for strings with common prefixes. */ + remainder = SIZEOF_PY_UHASH_T; + } + blocks = (len - remainder) / SIZEOF_PY_UHASH_T; + + x = (Py_uhash_t) _Py_HashSecret.fnv.prefix; + x ^= (Py_uhash_t) *p << 7; + while (blocks--) { + PY_UHASH_CPY(block.bytes, p); + x = (_PyHASH_MULTIPLIER * x) ^ block.value; + p += SIZEOF_PY_UHASH_T; + } + /* add remainder */ + for (; remainder > 0; remainder--) + x = (_PyHASH_MULTIPLIER * x) ^ (Py_uhash_t) *p++; + x ^= (Py_uhash_t) len; + x ^= (Py_uhash_t) _Py_HashSecret.fnv.suffix; + if (x == (Py_uhash_t) -1) { + x = (Py_uhash_t) -2; + } + return x; +} + +static PyHash_FuncDef PyHash_Func = {fnv, "fnv", 8 * SIZEOF_PY_HASH_T, + 16 * SIZEOF_PY_HASH_T}; + +#endif /* Py_HASH_ALGORITHM == Py_HASH_FNV */ + + +/* ************************************************************************** + + Copyright (c) 2013 Marek Majkowski + + 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. + + + Original location: + https://github.com/majek/csiphash/ + + Solution inspired by code from: + Samuel Neves (supercop/crypto_auth/siphash24/little) + djb (supercop/crypto_auth/siphash24/little2) + Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c) + + Modified for Python by Christian Heimes: + - C89 / MSVC compatibility + - _rotl64() on Windows + - letoh64() fallback +*/ + +/* byte swap little endian to host endian + * Endian conversion not only ensures that the hash function returns the same + * value on all platforms. It is also required to for a good dispersion of + * the hash values' least significant bits. + */ +#if PY_LITTLE_ENDIAN +# define _le64toh(x) ((uint64_t)(x)) +#elif defined(__APPLE__) +# define _le64toh(x) OSSwapLittleToHostInt64(x) +#elif defined(HAVE_LETOH64) +# define _le64toh(x) le64toh(x) +#else +# define _le64toh(x) (((uint64_t)(x) << 56) | \ + (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \ + (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \ + (((uint64_t)(x) << 8) & 0xff00000000ULL) | \ + (((uint64_t)(x) >> 8) & 0xff000000ULL) | \ + (((uint64_t)(x) >> 24) & 0xff0000ULL) | \ + (((uint64_t)(x) >> 40) & 0xff00ULL) | \ + ((uint64_t)(x) >> 56)) +#endif + + +#ifdef _MSC_VER +# define ROTATE(x, b) _rotl64(x, b) +#else +# define ROTATE(x, b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) ) +#endif + +#define HALF_ROUND(a,b,c,d,s,t) \ + a += b; c += d; \ + b = ROTATE(b, s) ^ a; \ + d = ROTATE(d, t) ^ c; \ + a = ROTATE(a, 32); + +#define DOUBLE_ROUND(v0,v1,v2,v3) \ + HALF_ROUND(v0,v1,v2,v3,13,16); \ + HALF_ROUND(v2,v1,v0,v3,17,21); \ + HALF_ROUND(v0,v1,v2,v3,13,16); \ + HALF_ROUND(v2,v1,v0,v3,17,21); + + +static uint64_t +siphash24(uint64_t k0, uint64_t k1, const void *src, Py_ssize_t src_sz) { + uint64_t b = (uint64_t)src_sz << 56; + const uint8_t *in = (const uint8_t*)src; + + uint64_t v0 = k0 ^ 0x736f6d6570736575ULL; + uint64_t v1 = k1 ^ 0x646f72616e646f6dULL; + uint64_t v2 = k0 ^ 0x6c7967656e657261ULL; + uint64_t v3 = k1 ^ 0x7465646279746573ULL; + + uint64_t t; + uint8_t *pt; + + while (src_sz >= 8) { + uint64_t mi; + memcpy(&mi, in, sizeof(mi)); + mi = _le64toh(mi); + in += sizeof(mi); + src_sz -= sizeof(mi); + v3 ^= mi; + DOUBLE_ROUND(v0,v1,v2,v3); + v0 ^= mi; + } + + t = 0; + pt = (uint8_t *)&t; + switch (src_sz) { + case 7: pt[6] = in[6]; /* fall through */ + case 6: pt[5] = in[5]; /* fall through */ + case 5: pt[4] = in[4]; /* fall through */ + case 4: memcpy(pt, in, sizeof(uint32_t)); break; + case 3: pt[2] = in[2]; /* fall through */ + case 2: pt[1] = in[1]; /* fall through */ + case 1: pt[0] = in[0]; /* fall through */ + } + b |= _le64toh(t); + + v3 ^= b; + DOUBLE_ROUND(v0,v1,v2,v3); + v0 ^= b; + v2 ^= 0xff; + DOUBLE_ROUND(v0,v1,v2,v3); + DOUBLE_ROUND(v0,v1,v2,v3); + + /* modified */ + t = (v0 ^ v1) ^ (v2 ^ v3); + return t; +} + +uint64_t +_Py_KeyedHash(uint64_t key, const void *src, Py_ssize_t src_sz) +{ + return siphash24(key, 0, src, src_sz); +} + + +#if Py_HASH_ALGORITHM == Py_HASH_SIPHASH24 +static Py_hash_t +pysiphash(const void *src, Py_ssize_t src_sz) { + return (Py_hash_t)siphash24( + _le64toh(_Py_HashSecret.siphash.k0), _le64toh(_Py_HashSecret.siphash.k1), + src, src_sz); +} + +static PyHash_FuncDef PyHash_Func = {pysiphash, "siphash24", 64, 128}; +#endif + +#ifdef __cplusplus +} +#endif diff --git a/python/Python/pylifecycle.c b/python/Python/pylifecycle.c new file mode 100755 index 0000000..8732d81 --- /dev/null +++ b/python/Python/pylifecycle.c @@ -0,0 +1,2407 @@ +/* Python interpreter top-level routines, including init/exit */ + +#include "Python.h" + +#include "Python-ast.h" +#undef Yield /* undefine macro conflicting with */ +#include "pycore_ceval.h" +#include "pycore_context.h" +#include "pycore_initconfig.h" +#include "pycore_fileutils.h" +#include "pycore_hamt.h" +#include "pycore_pathconfig.h" +#include "pycore_pylifecycle.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "pycore_traceback.h" +#include "grammar.h" +#include "node.h" +#include "token.h" +#include "parsetok.h" +#include "errcode.h" +#include "code.h" +#include "symtable.h" +#include "ast.h" +#include "marshal.h" +#include "osdefs.h" +#include + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef MS_WINDOWS +#include "malloc.h" /* for alloca */ +#endif + +#ifdef HAVE_LANGINFO_H +#include +#endif + +#ifdef MS_WINDOWS +#undef BYTE +#include "windows.h" + +extern PyTypeObject PyWindowsConsoleIO_Type; +#define PyWindowsConsoleIO_Check(op) (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type)) +#endif + +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(name); +_Py_IDENTIFIER(stdin); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); +_Py_IDENTIFIER(threading); + +#ifdef __cplusplus +extern "C" { +#endif + +extern grammar _PyParser_Grammar; /* From graminit.c */ + +/* Forward */ +static PyStatus add_main_module(PyInterpreterState *interp); +static PyStatus init_import_size(void); +static PyStatus init_sys_streams(PyInterpreterState *interp); +static void call_py_exitfuncs(PyInterpreterState *); +static void wait_for_thread_shutdown(void); +static void call_ll_exitfuncs(_PyRuntimeState *runtime); + +int _Py_UnhandledKeyboardInterrupt = 0; +_PyRuntimeState _PyRuntime = _PyRuntimeState_INIT; +static int runtime_initialized = 0; + +PyStatus +_PyRuntime_Initialize(void) +{ + /* XXX We only initialize once in the process, which aligns with + the static initialization of the former globals now found in + _PyRuntime. However, _PyRuntime *should* be initialized with + every Py_Initialize() call, but doing so breaks the runtime. + This is because the runtime state is not properly finalized + currently. */ + if (runtime_initialized) { + return _PyStatus_OK(); + } + runtime_initialized = 1; + + return _PyRuntimeState_Init(&_PyRuntime); +} + +void +_PyRuntime_Finalize(void) +{ + _PyRuntimeState_Fini(&_PyRuntime); + runtime_initialized = 0; +} + +int +_Py_IsFinalizing(void) +{ + return _PyRuntime.finalizing != NULL; +} + +/* Hack to force loading of object files */ +int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \ + PyOS_mystrnicmp; /* Python/pystrcmp.o */ + +/* PyModule_GetWarningsModule is no longer necessary as of 2.6 +since _warnings is builtin. This API should not be used. */ +PyObject * +PyModule_GetWarningsModule(void) +{ + return PyImport_ImportModule("warnings"); +} + + +/* APIs to access the initialization flags + * + * Can be called prior to Py_Initialize. + */ + +int +_Py_IsCoreInitialized(void) +{ + return _PyRuntime.core_initialized; +} + +int +Py_IsInitialized(void) +{ + return _PyRuntime.initialized; +} + + +/* Global initializations. Can be undone by Py_FinalizeEx(). Don't + call this twice without an intervening Py_FinalizeEx() call. When + initializations fail, a fatal error is issued and the function does + not return. On return, the first thread and interpreter state have + been created. + + Locking: you must hold the interpreter lock while calling this. + (If the lock has not yet been initialized, that's equivalent to + having the lock, but you cannot use multiple threads.) + +*/ + +static PyStatus +init_importlib(PyInterpreterState *interp, PyObject *sysmod) +{ + PyObject *importlib; + PyObject *impmod; + PyObject *value; + int verbose = interp->config.verbose; + + /* Import _importlib through its frozen version, _frozen_importlib. */ + if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { + return _PyStatus_ERR("can't import _frozen_importlib"); + } + else if (verbose) { + PySys_FormatStderr("import _frozen_importlib # frozen\n"); + } + importlib = PyImport_AddModule("_frozen_importlib"); + if (importlib == NULL) { + return _PyStatus_ERR("couldn't get _frozen_importlib from sys.modules"); + } + interp->importlib = importlib; + Py_INCREF(interp->importlib); + + interp->import_func = PyDict_GetItemString(interp->builtins, "__import__"); + if (interp->import_func == NULL) + return _PyStatus_ERR("__import__ not found"); + Py_INCREF(interp->import_func); + + /* Import the _imp module */ + impmod = PyInit__imp(); + if (impmod == NULL) { + return _PyStatus_ERR("can't import _imp"); + } + else if (verbose) { + PySys_FormatStderr("import _imp # builtin\n"); + } + if (_PyImport_SetModuleString("_imp", impmod) < 0) { + return _PyStatus_ERR("can't save _imp to sys.modules"); + } + + /* Install importlib as the implementation of import */ + value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); + if (value == NULL) { + PyErr_Print(); + return _PyStatus_ERR("importlib install failed"); + } + Py_DECREF(value); + Py_DECREF(impmod); + + return _PyStatus_OK(); +} + +static PyStatus +init_importlib_external(PyInterpreterState *interp) +{ + PyObject *value; + value = PyObject_CallMethod(interp->importlib, + "_install_external_importers", ""); + if (value == NULL) { + PyErr_Print(); + return _PyStatus_ERR("external importer setup failed"); + } + Py_DECREF(value); + return _PyImportZip_Init(interp); +} + +/* Helper functions to better handle the legacy C locale + * + * The legacy C locale assumes ASCII as the default text encoding, which + * causes problems not only for the CPython runtime, but also other + * components like GNU readline. + * + * Accordingly, when the CLI detects it, it attempts to coerce it to a + * more capable UTF-8 based alternative as follows: + * + * if (_Py_LegacyLocaleDetected()) { + * _Py_CoerceLegacyLocale(); + * } + * + * See the documentation of the PYTHONCOERCECLOCALE setting for more details. + * + * Locale coercion also impacts the default error handler for the standard + * streams: while the usual default is "strict", the default for the legacy + * C locale and for any of the coercion target locales is "surrogateescape". + */ + +int +_Py_LegacyLocaleDetected(int warn) +{ +#ifndef MS_WINDOWS + if (!warn) { + const char *locale_override = getenv("LC_ALL"); + if (locale_override != NULL && *locale_override != '\0') { + /* Don't coerce C locale if the LC_ALL environment variable + is set */ + return 0; + } + } + + /* On non-Windows systems, the C locale is considered a legacy locale */ + /* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat + * the POSIX locale as a simple alias for the C locale, so + * we may also want to check for that explicitly. + */ + const char *ctype_loc = setlocale(LC_CTYPE, NULL); + return ctype_loc != NULL && strcmp(ctype_loc, "C") == 0; +#else + /* Windows uses code pages instead of locales, so no locale is legacy */ + return 0; +#endif +} + +static const char *_C_LOCALE_WARNING = + "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " + "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " + "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible " + "locales is recommended.\n"; + +static void +emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) +{ + const PyPreConfig *preconfig = &runtime->preconfig; + if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) { + PySys_FormatStderr("%s", _C_LOCALE_WARNING); + } +} + +typedef struct _CandidateLocale { + const char *locale_name; /* The locale to try as a coercion target */ +} _LocaleCoercionTarget; + +static _LocaleCoercionTarget _TARGET_LOCALES[] = { + {"C.UTF-8"}, + {"C.utf8"}, + {"UTF-8"}, + {NULL} +}; + + +int +_Py_IsLocaleCoercionTarget(const char *ctype_loc) +{ + const _LocaleCoercionTarget *target = NULL; + for (target = _TARGET_LOCALES; target->locale_name; target++) { + if (strcmp(ctype_loc, target->locale_name) == 0) { + return 1; + } + } + return 0; +} + + +#ifdef PY_COERCE_C_LOCALE +static const char C_LOCALE_COERCION_WARNING[] = + "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale " + "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n"; + +static int +_coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target) +{ + const char *newloc = target->locale_name; + + /* Reset locale back to currently configured defaults */ + _Py_SetLocaleFromEnv(LC_ALL); + + /* Set the relevant locale environment variable */ + if (setenv("LC_CTYPE", newloc, 1)) { + fprintf(stderr, + "Error setting LC_CTYPE, skipping C locale coercion\n"); + return 0; + } + if (warn) { + fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc); + } + + /* Reconfigure with the overridden environment variables */ + _Py_SetLocaleFromEnv(LC_ALL); + return 1; +} +#endif + +int +_Py_CoerceLegacyLocale(int warn) +{ + int coerced = 0; +#ifdef PY_COERCE_C_LOCALE + char *oldloc = NULL; + + oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL)); + if (oldloc == NULL) { + return coerced; + } + + const char *locale_override = getenv("LC_ALL"); + if (locale_override == NULL || *locale_override == '\0') { + /* LC_ALL is also not set (or is set to an empty string) */ + const _LocaleCoercionTarget *target = NULL; + for (target = _TARGET_LOCALES; target->locale_name; target++) { + const char *new_locale = setlocale(LC_CTYPE, + target->locale_name); + if (new_locale != NULL) { +#if !defined(_Py_FORCE_UTF8_LOCALE) && defined(HAVE_LANGINFO_H) && defined(CODESET) + /* Also ensure that nl_langinfo works in this locale */ + char *codeset = nl_langinfo(CODESET); + if (!codeset || *codeset == '\0') { + /* CODESET is not set or empty, so skip coercion */ + new_locale = NULL; + _Py_SetLocaleFromEnv(LC_CTYPE); + continue; + } +#endif + /* Successfully configured locale, so make it the default */ + coerced = _coerce_default_locale_settings(warn, target); + goto done; + } + } + } + /* No C locale warning here, as Py_Initialize will emit one later */ + + setlocale(LC_CTYPE, oldloc); + +done: + PyMem_RawFree(oldloc); +#endif + return coerced; +} + +/* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to + * isolate the idiosyncrasies of different libc implementations. It reads the + * appropriate environment variable and uses its value to select the locale for + * 'category'. */ +char * +_Py_SetLocaleFromEnv(int category) +{ + char *res; +#ifdef __ANDROID__ + const char *locale; + const char **pvar; +#ifdef PY_COERCE_C_LOCALE + const char *coerce_c_locale; +#endif + const char *utf8_locale = "C.UTF-8"; + const char *env_var_set[] = { + "LC_ALL", + "LC_CTYPE", + "LANG", + NULL, + }; + + /* Android setlocale(category, "") doesn't check the environment variables + * and incorrectly sets the "C" locale at API 24 and older APIs. We only + * check the environment variables listed in env_var_set. */ + for (pvar=env_var_set; *pvar; pvar++) { + locale = getenv(*pvar); + if (locale != NULL && *locale != '\0') { + if (strcmp(locale, utf8_locale) == 0 || + strcmp(locale, "en_US.UTF-8") == 0) { + return setlocale(category, utf8_locale); + } + return setlocale(category, "C"); + } + } + + /* Android uses UTF-8, so explicitly set the locale to C.UTF-8 if none of + * LC_ALL, LC_CTYPE, or LANG is set to a non-empty string. + * Quote from POSIX section "8.2 Internationalization Variables": + * "4. If the LANG environment variable is not set or is set to the empty + * string, the implementation-defined default locale shall be used." */ + +#ifdef PY_COERCE_C_LOCALE + coerce_c_locale = getenv("PYTHONCOERCECLOCALE"); + if (coerce_c_locale == NULL || strcmp(coerce_c_locale, "0") != 0) { + /* Some other ported code may check the environment variables (e.g. in + * extension modules), so we make sure that they match the locale + * configuration */ + if (setenv("LC_CTYPE", utf8_locale, 1)) { + fprintf(stderr, "Warning: failed setting the LC_CTYPE " + "environment variable to %s\n", utf8_locale); + } + } +#endif + res = setlocale(category, utf8_locale); +#else /* !defined(__ANDROID__) */ + res = setlocale(category, ""); +#endif + _Py_ResetForceASCII(); + return res; +} + + +/* Global initializations. Can be undone by Py_Finalize(). Don't + call this twice without an intervening Py_Finalize() call. + + Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx + must have a corresponding call to Py_Finalize. + + Locking: you must hold the interpreter lock while calling these APIs. + (If the lock has not yet been initialized, that's equivalent to + having the lock, but you cannot use multiple threads.) + +*/ + +static PyStatus +pyinit_core_reconfigure(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, + const PyConfig *config) +{ + PyStatus status; + PyThreadState *tstate = _PyThreadState_GET(); + if (!tstate) { + return _PyStatus_ERR("failed to read thread state"); + } + + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + return _PyStatus_ERR("can't make main interpreter"); + } + *interp_p = interp; + + _PyConfig_Write(config, runtime); + + status = _PyConfig_Copy(&interp->config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + config = &interp->config; + + if (config->_install_importlib) { + status = _PyConfig_WritePathConfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +static PyStatus +pycore_init_runtime(_PyRuntimeState *runtime, + const PyConfig *config) +{ + if (runtime->initialized) { + return _PyStatus_ERR("main interpreter already initialized"); + } + + _PyConfig_Write(config, runtime); + + /* Py_Finalize leaves _Py_Finalizing set in order to help daemon + * threads behave a little more gracefully at interpreter shutdown. + * We clobber it here so the new interpreter can start with a clean + * slate. + * + * However, this may still lead to misbehaviour if there are daemon + * threads still hanging around from a previous Py_Initialize/Finalize + * pair :( + */ + runtime->finalizing = NULL; + + PyStatus status = _Py_HashRandomization_Init(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyInterpreterState_Enable(runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); +} + + +static PyStatus +pycore_create_interpreter(_PyRuntimeState *runtime, + const PyConfig *config, + PyInterpreterState **interp_p) +{ + PyInterpreterState *interp = PyInterpreterState_New(); + if (interp == NULL) { + return _PyStatus_ERR("can't make main interpreter"); + } + *interp_p = interp; + + PyStatus status = _PyConfig_Copy(&interp->config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + config = &interp->config; + + PyThreadState *tstate = PyThreadState_New(interp); + if (tstate == NULL) + return _PyStatus_ERR("can't make first thread"); + (void) PyThreadState_Swap(tstate); + + /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because + destroying the GIL might fail when it is being referenced from + another running thread (see issue #9901). + Instead we destroy the previously created GIL here, which ensures + that we can call Py_Initialize / Py_FinalizeEx multiple times. */ + _PyEval_FiniThreads(&runtime->ceval); + + /* Auto-thread-state API */ + _PyGILState_Init(runtime, interp, tstate); + + /* Create the GIL */ + PyEval_InitThreads(); + + return _PyStatus_OK(); +} + + +static PyStatus +pycore_init_types(void) +{ + PyStatus status = _PyTypes_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyUnicode_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (_PyStructSequence_Init() < 0) { + return _PyStatus_ERR("can't initialize structseq"); + } + + if (!_PyLong_Init()) { + return _PyStatus_ERR("can't init longs"); + } + + status = _PyExc_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (!_PyFloat_Init()) { + return _PyStatus_ERR("can't init float"); + } + + if (!_PyContext_Init()) { + return _PyStatus_ERR("can't init context"); + } + + status = _PyErr_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + return _PyStatus_OK(); +} + + +static PyStatus +pycore_init_builtins(PyInterpreterState *interp) +{ + PyObject *bimod = _PyBuiltin_Init(); + if (bimod == NULL) { + return _PyStatus_ERR("can't initialize builtins modules"); + } + _PyImport_FixupBuiltin(bimod, "builtins", interp->modules); + + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) { + return _PyStatus_ERR("can't initialize builtins dict"); + } + Py_INCREF(interp->builtins); + + PyStatus status = _PyBuiltins_AddExceptions(bimod); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); +} + + +static PyStatus +pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) +{ + const PyConfig *config = &interp->config; + + PyStatus status = _PyImport_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyImportHooks_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* Initialize _warnings. */ + if (_PyWarnings_Init() == NULL) { + return _PyStatus_ERR("can't initialize warnings"); + } + + if (config->_install_importlib) { + status = _PyConfig_WritePathConfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + /* This call sets up builtin and frozen import support */ + if (config->_install_importlib) { + status = init_importlib(interp, sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + return _PyStatus_OK(); +} + + +static PyStatus +pyinit_config(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, + const PyConfig *config) +{ + PyInterpreterState *interp; + + _PyConfig_Write(config, runtime); + + PyStatus status = pycore_init_runtime(runtime, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = pycore_create_interpreter(runtime, config, &interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + config = &interp->config; + *interp_p = interp; + + status = pycore_init_types(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + PyObject *sysmod; + status = _PySys_Create(runtime, interp, &sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = pycore_init_builtins(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = pycore_init_import_warnings(interp, sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* Only when we get here is the runtime core fully initialized */ + runtime->core_initialized = 1; + return _PyStatus_OK(); +} + + +PyStatus +_Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args) +{ + PyStatus status; + + if (src_config == NULL) { + return _PyStatus_ERR("preinitialization config is NULL"); + } + + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + _PyRuntimeState *runtime = &_PyRuntime; + + if (runtime->preinitialized) { + /* If it's already configured: ignored the new configuration */ + return _PyStatus_OK(); + } + + /* Note: preinitialized remains 1 on error, it is only set to 0 + at exit on success. */ + runtime->preinitializing = 1; + + PyPreConfig config; + + status = _PyPreConfig_InitFromPreConfig(&config, src_config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyPreConfig_Read(&config, args); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyPreConfig_Write(&config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + runtime->preinitializing = 0; + runtime->preinitialized = 1; + return _PyStatus_OK(); +} + + +PyStatus +Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv) +{ + _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; + return _Py_PreInitializeFromPyArgv(src_config, &args); +} + + +PyStatus +Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv) +{ + _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; + return _Py_PreInitializeFromPyArgv(src_config, &args); +} + + +PyStatus +Py_PreInitialize(const PyPreConfig *src_config) +{ + return _Py_PreInitializeFromPyArgv(src_config, NULL); +} + + +PyStatus +_Py_PreInitializeFromConfig(const PyConfig *config, + const _PyArgv *args) +{ + assert(config != NULL); + + PyStatus status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + _PyRuntimeState *runtime = &_PyRuntime; + + if (runtime->preinitialized) { + /* Already initialized: do nothing */ + return _PyStatus_OK(); + } + + PyPreConfig preconfig; + + _PyPreConfig_InitFromConfig(&preconfig, config); + + if (!config->parse_argv) { + return Py_PreInitialize(&preconfig); + } + else if (args == NULL) { + _PyArgv config_args = { + .use_bytes_argv = 0, + .argc = config->argv.length, + .wchar_argv = config->argv.items}; + return _Py_PreInitializeFromPyArgv(&preconfig, &config_args); + } + else { + return _Py_PreInitializeFromPyArgv(&preconfig, args); + } +} + + +/* Begin interpreter initialization + * + * On return, the first thread and interpreter state have been created, + * but the compiler, signal handling, multithreading and + * multiple interpreter support, and codec infrastructure are not yet + * available. + * + * The import system will support builtin and frozen modules only. + * The only supported io is writing to sys.stderr + * + * If any operation invoked by this function fails, a fatal error is + * issued and the function does not return. + * + * Any code invoked from this function should *not* assume it has access + * to the Python C API (unless the API is explicitly listed as being + * safe to call without calling Py_Initialize first) + */ +static PyStatus +pyinit_core(_PyRuntimeState *runtime, + const PyConfig *src_config, + PyInterpreterState **interp_p) +{ + PyStatus status; + + status = _Py_PreInitializeFromConfig(src_config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + PyConfig config; + _PyConfig_InitCompatConfig(&config); + + status = _PyConfig_Copy(&config, src_config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + status = PyConfig_Read(&config); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + + if (!runtime->core_initialized) { + status = pyinit_config(runtime, interp_p, &config); + } + else { + status = pyinit_core_reconfigure(runtime, interp_p, &config); + } + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + +done: + PyConfig_Clear(&config); + return status; +} + + +/* Py_Initialize() has already been called: update the main interpreter + configuration. Example of bpo-34008: Py_Main() called after + Py_Initialize(). */ +static PyStatus +_Py_ReconfigureMainInterpreter(PyInterpreterState *interp) +{ + PyConfig *config = &interp->config; + + PyObject *argv = _PyWideStringList_AsList(&config->argv); + if (argv == NULL) { + return _PyStatus_NO_MEMORY(); \ + } + + int res = PyDict_SetItemString(interp->sysdict, "argv", argv); + Py_DECREF(argv); + if (res < 0) { + return _PyStatus_ERR("fail to set sys.argv"); + } + return _PyStatus_OK(); +} + +/* Update interpreter state based on supplied configuration settings + * + * After calling this function, most of the restrictions on the interpreter + * are lifted. The only remaining incomplete settings are those related + * to the main module (sys.argv[0], __main__ metadata) + * + * Calling this when the interpreter is not initializing, is already + * initialized or without a valid current thread state is a fatal error. + * Other errors should be reported as normal Python exceptions with a + * non-zero return code. + */ +static PyStatus +pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) +{ + if (!runtime->core_initialized) { + return _PyStatus_ERR("runtime core not initialized"); + } + + /* Configure the main interpreter */ + PyConfig *config = &interp->config; + + if (runtime->initialized) { + return _Py_ReconfigureMainInterpreter(interp); + } + + if (!config->_install_importlib) { + /* Special mode for freeze_importlib: run with no import system + * + * This means anything which needs support from extension modules + * or pure Python code in the standard library won't work. + */ + runtime->initialized = 1; + return _PyStatus_OK(); + } + + if (_PyTime_Init() < 0) { + return _PyStatus_ERR("can't initialize time"); + } + + if (_PySys_InitMain(runtime, interp) < 0) { + return _PyStatus_ERR("can't finish initializing sys"); + } + + PyStatus status = init_importlib_external(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* initialize the faulthandler module */ + status = _PyFaulthandler_Init(config->faulthandler); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + status = _PyUnicode_InitEncodings(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (_PySignal_Init(config->install_signal_handlers) < 0) { + return _PyStatus_ERR("can't initialize signals"); + } + + if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { + return _PyStatus_ERR("can't initialize tracemalloc"); + } + + status = add_main_module(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = init_sys_streams(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* Initialize warnings. */ + PyObject *warnoptions = PySys_GetObject("warnoptions"); + if (warnoptions != NULL && PyList_Size(warnoptions) > 0) + { + PyObject *warnings_module = PyImport_ImportModule("warnings"); + if (warnings_module == NULL) { + fprintf(stderr, "'import warnings' failed; traceback:\n"); + PyErr_Print(); + } + Py_XDECREF(warnings_module); + } + + runtime->initialized = 1; + + if (config->site_import) { + status = init_import_size(); /* Module site */ + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + +#ifndef MS_WINDOWS + emit_stderr_warning_for_legacy_locale(runtime); +#endif + + return _PyStatus_OK(); +} + + +PyStatus +_Py_InitializeMain(void) +{ + PyStatus status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + _PyRuntimeState *runtime = &_PyRuntime; + PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + + return pyinit_main(runtime, interp); +} + + +PyStatus +Py_InitializeFromConfig(const PyConfig *config) +{ + if (config == NULL) { + return _PyStatus_ERR("initialization config is NULL"); + } + + PyStatus status; + + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + _PyRuntimeState *runtime = &_PyRuntime; + + PyInterpreterState *interp = NULL; + status = pyinit_core(runtime, config, &interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + config = &interp->config; + + if (config->_init_main) { + status = pyinit_main(runtime, interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + return _PyStatus_OK(); +} + + +void +Py_InitializeEx(int install_sigs) +{ + PyStatus status; + + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); + } + _PyRuntimeState *runtime = &_PyRuntime; + + if (runtime->initialized) { + /* bpo-33932: Calling Py_Initialize() twice does nothing. */ + return; + } + + PyConfig config; + _PyConfig_InitCompatConfig(&config); + + config.install_signal_handlers = install_sigs; + + status = Py_InitializeFromConfig(&config); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); + } +} + +void +Py_Initialize(void) +{ + Py_InitializeEx(1); +} + + +#ifdef COUNT_ALLOCS +extern void _Py_dump_counts(FILE*); +#endif + +/* Flush stdout and stderr */ + +static int +file_is_closed(PyObject *fobj) +{ + int r; + PyObject *tmp = PyObject_GetAttrString(fobj, "closed"); + if (tmp == NULL) { + PyErr_Clear(); + return 0; + } + r = PyObject_IsTrue(tmp); + Py_DECREF(tmp); + if (r < 0) + PyErr_Clear(); + return r > 0; +} + +static int +flush_std_files(void) +{ + PyObject *fout = _PySys_GetObjectId(&PyId_stdout); + PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); + PyObject *tmp; + int status = 0; + + if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { + tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL); + if (tmp == NULL) { + PyErr_WriteUnraisable(fout); + status = -1; + } + else + Py_DECREF(tmp); + } + + if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { + tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); + if (tmp == NULL) { + PyErr_Clear(); + status = -1; + } + else + Py_DECREF(tmp); + } + + return status; +} + +/* Undo the effect of Py_Initialize(). + + Beware: if multiple interpreter and/or thread states exist, these + are not wiped out; only the current thread and interpreter state + are deleted. But since everything else is deleted, those other + interpreter and thread states should no longer be used. + + (XXX We should do better, e.g. wipe out all interpreters and + threads.) + + Locking: as above. + +*/ + +int +Py_FinalizeEx(void) +{ + int status = 0; + + _PyRuntimeState *runtime = &_PyRuntime; + if (!runtime->initialized) { + return status; + } + + // Wrap up existing "threading"-module-created, non-daemon threads. + wait_for_thread_shutdown(); + + // Make any remaining pending calls. + _Py_FinishPendingCalls(runtime); + + /* Get current thread state and interpreter pointer */ + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = tstate->interp; + + /* The interpreter is still entirely intact at this point, and the + * exit funcs may be relying on that. In particular, if some thread + * or exit func is still waiting to do an import, the import machinery + * expects Py_IsInitialized() to return true. So don't say the + * runtime is uninitialized until after the exit funcs have run. + * Note that Threading.py uses an exit func to do a join on all the + * threads created thru it, so this also protects pending imports in + * the threads created via Threading. + */ + + call_py_exitfuncs(interp); + + /* Copy the core config, PyInterpreterState_Delete() free + the core config memory */ +#ifdef Py_REF_DEBUG + int show_ref_count = interp->config.show_ref_count; +#endif +#ifdef Py_TRACE_REFS + int dump_refs = interp->config.dump_refs; +#endif +#ifdef WITH_PYMALLOC + int malloc_stats = interp->config.malloc_stats; +#endif + + /* Remaining threads (e.g. daemon threads) will automatically exit + after taking the GIL (in PyEval_RestoreThread()). */ + runtime->finalizing = tstate; + runtime->initialized = 0; + runtime->core_initialized = 0; + + /* Flush sys.stdout and sys.stderr */ + if (flush_std_files() < 0) { + status = -1; + } + + /* Disable signal handling */ + PyOS_FiniInterrupts(); + + /* Collect garbage. This may call finalizers; it's nice to call these + * before all modules are destroyed. + * XXX If a __del__ or weakref callback is triggered here, and tries to + * XXX import a module, bad things can happen, because Python no + * XXX longer believes it's initialized. + * XXX Fatal Python error: Interpreter not initialized (version mismatch?) + * XXX is easy to provoke that way. I've also seen, e.g., + * XXX Exception exceptions.ImportError: 'No module named sha' + * XXX in ignored + * XXX but I'm unclear on exactly how that one happens. In any case, + * XXX I haven't seen a real-life report of either of these. + */ + _PyGC_CollectIfEnabled(); +#ifdef COUNT_ALLOCS + /* With COUNT_ALLOCS, it helps to run GC multiple times: + each collection might release some types from the type + list, so they become garbage. */ + while (_PyGC_CollectIfEnabled() > 0) + /* nothing */; +#endif + + /* Destroy all modules */ + PyImport_Cleanup(); + + /* Print debug stats if any */ + _PyEval_Fini(); + + /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ + if (flush_std_files() < 0) { + status = -1; + } + + /* Collect final garbage. This disposes of cycles created by + * class definitions, for example. + * XXX This is disabled because it caused too many problems. If + * XXX a __del__ or weakref callback triggers here, Python code has + * XXX a hard time running, because even the sys module has been + * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). + * XXX One symptom is a sequence of information-free messages + * XXX coming from threads (if a __del__ or callback is invoked, + * XXX other threads can execute too, and any exception they encounter + * XXX triggers a comedy of errors as subsystem after subsystem + * XXX fails to find what it *expects* to find in sys to help report + * XXX the exception and consequent unexpected failures). I've also + * XXX seen segfaults then, after adding print statements to the + * XXX Python code getting called. + */ +#if 0 + _PyGC_CollectIfEnabled(); +#endif + + /* Disable tracemalloc after all Python objects have been destroyed, + so it is possible to use tracemalloc in objects destructor. */ + _PyTraceMalloc_Fini(); + + /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ + _PyImport_Fini(); + + /* Cleanup typeobject.c's internal caches. */ + _PyType_Fini(); + + /* unload faulthandler module */ + _PyFaulthandler_Fini(); + + /* Debugging stuff */ +#ifdef COUNT_ALLOCS + _Py_dump_counts(stderr); +#endif + /* dump hash stats */ + _PyHash_Fini(); + +#ifdef Py_REF_DEBUG + if (show_ref_count) { + _PyDebug_PrintTotalRefs(); + } +#endif + +#ifdef Py_TRACE_REFS + /* Display all objects still alive -- this can invoke arbitrary + * __repr__ overrides, so requires a mostly-intact interpreter. + * Alas, a lot of stuff may still be alive now that will be cleaned + * up later. + */ + if (dump_refs) { + _Py_PrintReferences(stderr); + } +#endif /* Py_TRACE_REFS */ + + /* Clear interpreter state and all thread states. */ + PyInterpreterState_Clear(interp); + + /* Clear all loghooks */ + /* We want minimal exposure of this function, so define the extern + * here. The linker should discover the correct function without + * exporting a symbol. */ + extern void _PySys_ClearAuditHooks(void); + _PySys_ClearAuditHooks(); + + /* Now we decref the exception classes. After this point nothing + can raise an exception. That's okay, because each Fini() method + below has been checked to make sure no exceptions are ever + raised. + */ + + _PyExc_Fini(); + + /* Sundry finalizers */ + PyMethod_Fini(); + PyFrame_Fini(); + PyCFunction_Fini(); + PyTuple_Fini(); + PyList_Fini(); + PySet_Fini(); + PyBytes_Fini(); + PyLong_Fini(); + PyFloat_Fini(); + PyDict_Fini(); + PySlice_Fini(); + _PyGC_Fini(runtime); + _PyWarnings_Fini(interp); + _Py_HashRandomization_Fini(); + _PyArg_Fini(); + PyAsyncGen_Fini(); + _PyContext_Fini(); + + /* Cleanup Unicode implementation */ + _PyUnicode_Fini(); + + _Py_ClearFileSystemEncoding(); + + /* XXX Still allocated: + - various static ad-hoc pointers to interned strings + - int and float free list blocks + - whatever various modules and libraries allocate + */ + + PyGrammar_RemoveAccelerators(&_PyParser_Grammar); + + /* Cleanup auto-thread-state */ + _PyGILState_Fini(runtime); + + /* Delete current thread. After this, many C API calls become crashy. */ + PyThreadState_Swap(NULL); + + PyInterpreterState_Delete(interp); + +#ifdef Py_TRACE_REFS + /* Display addresses (& refcnts) of all objects still alive. + * An address can be used to find the repr of the object, printed + * above by _Py_PrintReferences. + */ + if (dump_refs) { + _Py_PrintReferenceAddresses(stderr); + } +#endif /* Py_TRACE_REFS */ +#ifdef WITH_PYMALLOC + if (malloc_stats) { + _PyObject_DebugMallocStats(stderr); + } +#endif + + call_ll_exitfuncs(runtime); + + _PyRuntime_Finalize(); + return status; +} + +void +Py_Finalize(void) +{ + Py_FinalizeEx(); +} + +/* Create and initialize a new interpreter and thread, and return the + new thread. This requires that Py_Initialize() has been called + first. + + Unsuccessful initialization yields a NULL pointer. Note that *no* + exception information is available even in this case -- the + exception information is held in the thread, and there is no + thread. + + Locking: as above. + +*/ + +static PyStatus +new_interpreter(PyThreadState **tstate_p) +{ + PyStatus status; + + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + _PyRuntimeState *runtime = &_PyRuntime; + + if (!runtime->initialized) { + return _PyStatus_ERR("Py_Initialize must be called first"); + } + + /* Issue #10915, #15751: The GIL API doesn't work with multiple + interpreters: disable PyGILState_Check(). */ + _PyGILState_check_enabled = 0; + + PyInterpreterState *interp = PyInterpreterState_New(); + if (interp == NULL) { + *tstate_p = NULL; + return _PyStatus_OK(); + } + + PyThreadState *tstate = PyThreadState_New(interp); + if (tstate == NULL) { + PyInterpreterState_Delete(interp); + *tstate_p = NULL; + return _PyStatus_OK(); + } + + PyThreadState *save_tstate = PyThreadState_Swap(tstate); + + /* Copy the current interpreter config into the new interpreter */ + PyConfig *config; + if (save_tstate != NULL) { + config = &save_tstate->interp->config; + } else { + /* No current thread state, copy from the main interpreter */ + PyInterpreterState *main_interp = PyInterpreterState_Main(); + config = &main_interp->config; + } + + status = _PyConfig_Copy(&interp->config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + config = &interp->config; + + status = _PyExc_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyErr_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + + /* XXX The following is lax in error checking */ + PyObject *modules = PyDict_New(); + if (modules == NULL) { + return _PyStatus_ERR("can't make modules dictionary"); + } + interp->modules = modules; + + PyObject *sysmod = _PyImport_FindBuiltin("sys", modules); + if (sysmod != NULL) { + interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) { + goto handle_error; + } + Py_INCREF(interp->sysdict); + PyDict_SetItemString(interp->sysdict, "modules", modules); + if (_PySys_InitMain(runtime, interp) < 0) { + return _PyStatus_ERR("can't finish initializing sys"); + } + } + else if (PyErr_Occurred()) { + goto handle_error; + } + + PyObject *bimod = _PyImport_FindBuiltin("builtins", modules); + if (bimod != NULL) { + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + goto handle_error; + Py_INCREF(interp->builtins); + } + else if (PyErr_Occurred()) { + goto handle_error; + } + + if (bimod != NULL && sysmod != NULL) { + status = _PyBuiltins_AddExceptions(bimod); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PySys_SetPreliminaryStderr(interp->sysdict); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyImportHooks_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = init_importlib(interp, sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = init_importlib_external(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyUnicode_InitEncodings(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = init_sys_streams(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = add_main_module(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (config->site_import) { + status = init_import_size(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + } + + if (PyErr_Occurred()) { + goto handle_error; + } + + *tstate_p = tstate; + return _PyStatus_OK(); + +handle_error: + /* Oops, it didn't work. Undo it all. */ + + PyErr_PrintEx(0); + PyThreadState_Clear(tstate); + PyThreadState_Swap(save_tstate); + PyThreadState_Delete(tstate); + PyInterpreterState_Delete(interp); + + *tstate_p = NULL; + return _PyStatus_OK(); +} + +PyThreadState * +Py_NewInterpreter(void) +{ + PyThreadState *tstate = NULL; + PyStatus status = new_interpreter(&tstate); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); + } + return tstate; + +} + +/* Delete an interpreter and its last thread. This requires that the + given thread state is current, that the thread has no remaining + frames, and that it is its interpreter's only remaining thread. + It is a fatal error to violate these constraints. + + (Py_FinalizeEx() doesn't have these constraints -- it zaps + everything, regardless.) + + Locking: as above. + +*/ + +void +Py_EndInterpreter(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + + if (tstate != _PyThreadState_GET()) + Py_FatalError("Py_EndInterpreter: thread is not current"); + if (tstate->frame != NULL) + Py_FatalError("Py_EndInterpreter: thread still has a frame"); + interp->finalizing = 1; + + // Wrap up existing "threading"-module-created, non-daemon threads. + wait_for_thread_shutdown(); + + call_py_exitfuncs(interp); + + if (tstate != interp->tstate_head || tstate->next != NULL) + Py_FatalError("Py_EndInterpreter: not the last thread"); + + PyImport_Cleanup(); + PyInterpreterState_Clear(interp); + PyThreadState_Swap(NULL); + PyInterpreterState_Delete(interp); +} + +/* Add the __main__ module */ + +static PyStatus +add_main_module(PyInterpreterState *interp) +{ + PyObject *m, *d, *loader, *ann_dict; + m = PyImport_AddModule("__main__"); + if (m == NULL) + return _PyStatus_ERR("can't create __main__ module"); + + d = PyModule_GetDict(m); + ann_dict = PyDict_New(); + if ((ann_dict == NULL) || + (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) { + return _PyStatus_ERR("Failed to initialize __main__.__annotations__"); + } + Py_DECREF(ann_dict); + + if (PyDict_GetItemString(d, "__builtins__") == NULL) { + PyObject *bimod = PyImport_ImportModule("builtins"); + if (bimod == NULL) { + return _PyStatus_ERR("Failed to retrieve builtins module"); + } + if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { + return _PyStatus_ERR("Failed to initialize __main__.__builtins__"); + } + Py_DECREF(bimod); + } + + /* Main is a little special - imp.is_builtin("__main__") will return + * False, but BuiltinImporter is still the most appropriate initial + * setting for its __loader__ attribute. A more suitable value will + * be set if __main__ gets further initialized later in the startup + * process. + */ + loader = PyDict_GetItemString(d, "__loader__"); + if (loader == NULL || loader == Py_None) { + PyObject *loader = PyObject_GetAttrString(interp->importlib, + "BuiltinImporter"); + if (loader == NULL) { + return _PyStatus_ERR("Failed to retrieve BuiltinImporter"); + } + if (PyDict_SetItemString(d, "__loader__", loader) < 0) { + return _PyStatus_ERR("Failed to initialize __main__.__loader__"); + } + Py_DECREF(loader); + } + return _PyStatus_OK(); +} + +/* Import the site module (not into __main__ though) */ + +static PyStatus +init_import_size(void) +{ + PyObject *m; + m = PyImport_ImportModule("site"); + if (m == NULL) { + return _PyStatus_ERR("Failed to import the site module"); + } + Py_DECREF(m); + return _PyStatus_OK(); +} + +/* Check if a file descriptor is valid or not. + Return 0 if the file descriptor is invalid, return non-zero otherwise. */ +static int +is_valid_fd(int fd) +{ +/* dup() is faster than fstat(): fstat() can require input/output operations, + whereas dup() doesn't. There is a low risk of EMFILE/ENFILE at Python + startup. Problem: dup() doesn't check if the file descriptor is valid on + some platforms. + + bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other + side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with + EBADF. FreeBSD has similar issue (bpo-32849). + + Only use dup() on platforms where dup() is enough to detect invalid FD in + corner cases: on Linux and Windows (bpo-32849). */ +#if defined(__linux__) || defined(MS_WINDOWS) + if (fd < 0) { + return 0; + } + int fd2; + + _Py_BEGIN_SUPPRESS_IPH + fd2 = dup(fd); + if (fd2 >= 0) { + close(fd2); + } + _Py_END_SUPPRESS_IPH + + return (fd2 >= 0); +#else + struct stat st; + return (fstat(fd, &st) == 0); +#endif +} + +/* returns Py_None if the fd is not valid */ +static PyObject* +create_stdio(const PyConfig *config, PyObject* io, + int fd, int write_mode, const char* name, + const wchar_t* encoding, const wchar_t* errors) +{ + PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; + const char* mode; + const char* newline; + PyObject *line_buffering, *write_through; + int buffering, isatty; + _Py_IDENTIFIER(open); + _Py_IDENTIFIER(isatty); + _Py_IDENTIFIER(TextIOWrapper); + _Py_IDENTIFIER(mode); + const int buffered_stdio = config->buffered_stdio; + + if (!is_valid_fd(fd)) + Py_RETURN_NONE; + + /* stdin is always opened in buffered mode, first because it shouldn't + make a difference in common use cases, second because TextIOWrapper + depends on the presence of a read1() method which only exists on + buffered streams. + */ + if (!buffered_stdio && write_mode) + buffering = 0; + else + buffering = -1; + if (write_mode) + mode = "wb"; + else + mode = "rb"; + buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", + fd, mode, buffering, + Py_None, Py_None, /* encoding, errors */ + Py_None, 0); /* newline, closefd */ + if (buf == NULL) + goto error; + + if (buffering) { + _Py_IDENTIFIER(raw); + raw = _PyObject_GetAttrId(buf, &PyId_raw); + if (raw == NULL) + goto error; + } + else { + raw = buf; + Py_INCREF(raw); + } + +#ifdef MS_WINDOWS + /* Windows console IO is always UTF-8 encoded */ + if (PyWindowsConsoleIO_Check(raw)) + encoding = L"utf-8"; +#endif + + text = PyUnicode_FromString(name); + if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) + goto error; + res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL); + if (res == NULL) + goto error; + isatty = PyObject_IsTrue(res); + Py_DECREF(res); + if (isatty == -1) + goto error; + if (!buffered_stdio) + write_through = Py_True; + else + write_through = Py_False; + if (isatty && buffered_stdio) + line_buffering = Py_True; + else + line_buffering = Py_False; + + Py_CLEAR(raw); + Py_CLEAR(text); + +#ifdef MS_WINDOWS + /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r" + newlines to "\n". + sys.stdout and sys.stderr: translate "\n" to "\r\n". */ + newline = NULL; +#else + /* sys.stdin: split lines at "\n". + sys.stdout and sys.stderr: don't translate newlines (use "\n"). */ + newline = "\n"; +#endif + + PyObject *encoding_str = PyUnicode_FromWideChar(encoding, -1); + if (encoding_str == NULL) { + Py_CLEAR(buf); + goto error; + } + + PyObject *errors_str = PyUnicode_FromWideChar(errors, -1); + if (errors_str == NULL) { + Py_CLEAR(buf); + Py_CLEAR(encoding_str); + goto error; + } + + stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OOOsOO", + buf, encoding_str, errors_str, + newline, line_buffering, write_through); + Py_CLEAR(buf); + Py_CLEAR(encoding_str); + Py_CLEAR(errors_str); + if (stream == NULL) + goto error; + + if (write_mode) + mode = "w"; + else + mode = "r"; + text = PyUnicode_FromString(mode); + if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0) + goto error; + Py_CLEAR(text); + return stream; + +error: + Py_XDECREF(buf); + Py_XDECREF(stream); + Py_XDECREF(text); + Py_XDECREF(raw); + + if (PyErr_ExceptionMatches(PyExc_OSError) && !is_valid_fd(fd)) { + /* Issue #24891: the file descriptor was closed after the first + is_valid_fd() check was called. Ignore the OSError and set the + stream to None. */ + PyErr_Clear(); + Py_RETURN_NONE; + } + return NULL; +} + +/* Initialize sys.stdin, stdout, stderr and builtins.open */ +static PyStatus +init_sys_streams(PyInterpreterState *interp) +{ + PyObject *iomod = NULL, *wrapper; + PyObject *bimod = NULL; + PyObject *m; + PyObject *std = NULL; + int fd; + PyObject * encoding_attr; + PyStatus res = _PyStatus_OK(); + PyConfig *config = &interp->config; + + /* Check that stdin is not a directory + Using shell redirection, you can redirect stdin to a directory, + crashing the Python interpreter. Catch this common mistake here + and output a useful error message. Note that under MS Windows, + the shell already prevents that. */ +#ifndef MS_WINDOWS + struct _Py_stat_struct sb; + if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && + S_ISDIR(sb.st_mode)) { + return _PyStatus_ERR(" is a directory, cannot continue"); + } +#endif + + /* Hack to avoid a nasty recursion issue when Python is invoked + in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ + if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { + goto error; + } + Py_DECREF(m); + + if (!(m = PyImport_ImportModule("encodings.latin_1"))) { + goto error; + } + Py_DECREF(m); + + if (!(bimod = PyImport_ImportModule("builtins"))) { + goto error; + } + + if (!(iomod = PyImport_ImportModule("io"))) { + goto error; + } + if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { + goto error; + } + + /* Set builtins.open */ + if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { + Py_DECREF(wrapper); + goto error; + } + Py_DECREF(wrapper); + + /* Set sys.stdin */ + fd = fileno(stdin); + /* Under some conditions stdin, stdout and stderr may not be connected + * and fileno() may point to an invalid file descriptor. For example + * GUI apps don't have valid standard streams by default. + */ + std = create_stdio(config, iomod, fd, 0, "", + config->stdio_encoding, + config->stdio_errors); + if (std == NULL) + goto error; + PySys_SetObject("__stdin__", std); + _PySys_SetObjectId(&PyId_stdin, std); + Py_DECREF(std); + + /* Set sys.stdout */ + fd = fileno(stdout); + std = create_stdio(config, iomod, fd, 1, "", + config->stdio_encoding, + config->stdio_errors); + if (std == NULL) + goto error; + PySys_SetObject("__stdout__", std); + _PySys_SetObjectId(&PyId_stdout, std); + Py_DECREF(std); + +#if 1 /* Disable this if you have trouble debugging bootstrap stuff */ + /* Set sys.stderr, replaces the preliminary stderr */ + fd = fileno(stderr); + std = create_stdio(config, iomod, fd, 1, "", + config->stdio_encoding, + L"backslashreplace"); + if (std == NULL) + goto error; + + /* Same as hack above, pre-import stderr's codec to avoid recursion + when import.c tries to write to stderr in verbose mode. */ + encoding_attr = PyObject_GetAttrString(std, "encoding"); + if (encoding_attr != NULL) { + const char *std_encoding = PyUnicode_AsUTF8(encoding_attr); + if (std_encoding != NULL) { + PyObject *codec_info = _PyCodec_Lookup(std_encoding); + Py_XDECREF(codec_info); + } + Py_DECREF(encoding_attr); + } + PyErr_Clear(); /* Not a fatal error if codec isn't available */ + + if (PySys_SetObject("__stderr__", std) < 0) { + Py_DECREF(std); + goto error; + } + if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { + Py_DECREF(std); + goto error; + } + Py_DECREF(std); +#endif + + goto done; + +error: + res = _PyStatus_ERR("can't initialize sys standard streams"); + +done: + _Py_ClearStandardStreamEncoding(); + + Py_XDECREF(bimod); + Py_XDECREF(iomod); + return res; +} + + +static void +_Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, + PyThreadState *tstate) +{ + fputc('\n', stderr); + fflush(stderr); + + /* display the current Python stack */ + _Py_DumpTracebackThreads(fd, interp, tstate); +} + +/* Print the current exception (if an exception is set) with its traceback, + or display the current Python stack. + + Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is + called on catastrophic cases. + + Return 1 if the traceback was displayed, 0 otherwise. */ + +static int +_Py_FatalError_PrintExc(int fd) +{ + PyObject *ferr, *res; + PyObject *exception, *v, *tb; + int has_tb; + + PyErr_Fetch(&exception, &v, &tb); + if (exception == NULL) { + /* No current exception */ + return 0; + } + + ferr = _PySys_GetObjectId(&PyId_stderr); + if (ferr == NULL || ferr == Py_None) { + /* sys.stderr is not set yet or set to None, + no need to try to display the exception */ + return 0; + } + + PyErr_NormalizeException(&exception, &v, &tb); + if (tb == NULL) { + tb = Py_None; + Py_INCREF(tb); + } + PyException_SetTraceback(v, tb); + if (exception == NULL) { + /* PyErr_NormalizeException() failed */ + return 0; + } + + has_tb = (tb != Py_None); + PyErr_Display(exception, v, tb); + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); + + /* sys.stderr may be buffered: call sys.stderr.flush() */ + res = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); + if (res == NULL) + PyErr_Clear(); + else + Py_DECREF(res); + + return has_tb; +} + +/* Print fatal error message and abort */ + +#ifdef MS_WINDOWS +static void +fatal_output_debug(const char *msg) +{ + /* buffer of 256 bytes allocated on the stack */ + WCHAR buffer[256 / sizeof(WCHAR)]; + size_t buflen = Py_ARRAY_LENGTH(buffer) - 1; + size_t msglen; + + OutputDebugStringW(L"Fatal Python error: "); + + msglen = strlen(msg); + while (msglen) { + size_t i; + + if (buflen > msglen) { + buflen = msglen; + } + + /* Convert the message to wchar_t. This uses a simple one-to-one + conversion, assuming that the this error message actually uses + ASCII only. If this ceases to be true, we will have to convert. */ + for (i=0; i < buflen; ++i) { + buffer[i] = msg[i]; + } + buffer[i] = L'\0'; + OutputDebugStringW(buffer); + + msg += buflen; + msglen -= buflen; + } + OutputDebugStringW(L"\n"); +} +#endif + + +static void +fatal_error_dump_runtime(FILE *stream, _PyRuntimeState *runtime) +{ + fprintf(stream, "Python runtime state: "); + if (runtime->finalizing) { + fprintf(stream, "finalizing (tstate=%p)", runtime->finalizing); + } + else if (runtime->initialized) { + fprintf(stream, "initialized"); + } + else if (runtime->core_initialized) { + fprintf(stream, "core initialized"); + } + else if (runtime->preinitialized) { + fprintf(stream, "preinitialized"); + } + else if (runtime->preinitializing) { + fprintf(stream, "preinitializing"); + } + else { + fprintf(stream, "unknown"); + } + fprintf(stream, "\n"); + fflush(stream); +} + + +static void _Py_NO_RETURN +fatal_error(const char *prefix, const char *msg, int status) +{ + FILE *stream = stderr; + const int fd = fileno(stream); + static int reentrant = 0; + + if (reentrant) { + /* Py_FatalError() caused a second fatal error. + Example: flush_std_files() raises a recursion error. */ + goto exit; + } + reentrant = 1; + + fprintf(stream, "Fatal Python error: "); + if (prefix) { + fputs(prefix, stream); + fputs(": ", stream); + } + if (msg) { + fputs(msg, stream); + } + else { + fprintf(stream, ""); + } + fputs("\n", stream); + fflush(stream); /* it helps in Windows debug build */ + + _PyRuntimeState *runtime = &_PyRuntime; + fatal_error_dump_runtime(stream, runtime); + + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = NULL; + if (tstate != NULL) { + interp = tstate->interp; + } + + /* Check if the current thread has a Python thread state + and holds the GIL. + + tss_tstate is NULL if Py_FatalError() is called from a C thread which + has no Python thread state. + + tss_tstate != tstate if the current Python thread does not hold the GIL. + */ + PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); + int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate); + if (has_tstate_and_gil) { + /* If an exception is set, print the exception with its traceback */ + if (!_Py_FatalError_PrintExc(fd)) { + /* No exception is set, or an exception is set without traceback */ + _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); + } + } + else { + _Py_FatalError_DumpTracebacks(fd, interp, tss_tstate); + } + + /* The main purpose of faulthandler is to display the traceback. + This function already did its best to display a traceback. + Disable faulthandler to prevent writing a second traceback + on abort(). */ + _PyFaulthandler_Fini(); + + /* Check if the current Python thread hold the GIL */ + if (has_tstate_and_gil) { + /* Flush sys.stdout and sys.stderr */ + flush_std_files(); + } + +#ifdef MS_WINDOWS + fatal_output_debug(msg); +#endif /* MS_WINDOWS */ + +exit: + if (status < 0) { +#if defined(MS_WINDOWS) && defined(_DEBUG) + DebugBreak(); +#endif + abort(); + } + else { + exit(status); + } +} + +void _Py_NO_RETURN +Py_FatalError(const char *msg) +{ + fatal_error(NULL, msg, -1); +} + +void _Py_NO_RETURN +Py_ExitStatusException(PyStatus status) +{ + if (_PyStatus_IS_EXIT(status)) { + exit(status.exitcode); + } + else if (_PyStatus_IS_ERROR(status)) { + fatal_error(status.func, status.err_msg, 1); + } + else { + Py_FatalError("Py_ExitStatusException() must not be called on success"); + } +} + +/* Clean up and exit */ + +# include "pythread.h" + +/* For the atexit module. */ +void _Py_PyAtExit(void (*func)(PyObject *), PyObject *module) +{ + PyInterpreterState *is = _PyInterpreterState_Get(); + + /* Guard against API misuse (see bpo-17852) */ + assert(is->pyexitfunc == NULL || is->pyexitfunc == func); + + is->pyexitfunc = func; + is->pyexitmodule = module; +} + +static void +call_py_exitfuncs(PyInterpreterState *istate) +{ + if (istate->pyexitfunc == NULL) + return; + + (*istate->pyexitfunc)(istate->pyexitmodule); + PyErr_Clear(); +} + +/* Wait until threading._shutdown completes, provided + the threading module was imported in the first place. + The shutdown routine will wait until all non-daemon + "threading" threads have completed. */ +static void +wait_for_thread_shutdown(void) +{ + _Py_IDENTIFIER(_shutdown); + PyObject *result; + PyObject *threading = _PyImport_GetModuleId(&PyId_threading); + if (threading == NULL) { + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(NULL); + } + /* else: threading not imported */ + return; + } + result = _PyObject_CallMethodId(threading, &PyId__shutdown, NULL); + if (result == NULL) { + PyErr_WriteUnraisable(threading); + } + else { + Py_DECREF(result); + } + Py_DECREF(threading); +} + +#define NEXITFUNCS 32 +int Py_AtExit(void (*func)(void)) +{ + if (_PyRuntime.nexitfuncs >= NEXITFUNCS) + return -1; + _PyRuntime.exitfuncs[_PyRuntime.nexitfuncs++] = func; + return 0; +} + +static void +call_ll_exitfuncs(_PyRuntimeState *runtime) +{ + while (runtime->nexitfuncs > 0) { + /* pop last function from the list */ + runtime->nexitfuncs--; + void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs]; + runtime->exitfuncs[runtime->nexitfuncs] = NULL; + + exitfunc(); + } + + fflush(stdout); + fflush(stderr); +} + +void _Py_NO_RETURN +Py_Exit(int sts) +{ + if (Py_FinalizeEx() < 0) { + sts = 120; + } + + exit(sts); +} + + +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. + * + * 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. + */ +void +_Py_RestoreSignals(void) +{ +#ifdef SIGPIPE + PyOS_setsig(SIGPIPE, SIG_DFL); +#endif +#ifdef SIGXFZ + PyOS_setsig(SIGXFZ, SIG_DFL); +#endif +#ifdef SIGXFSZ + PyOS_setsig(SIGXFSZ, SIG_DFL); +#endif +} + + +/* + * The file descriptor fd is considered ``interactive'' if either + * a) isatty(fd) is TRUE, or + * b) the -i flag was given, and the filename associated with + * the descriptor is NULL or "" or "???". + */ +int +Py_FdIsInteractive(FILE *fp, const char *filename) +{ + if (isatty((int)fileno(fp))) + return 1; + if (!Py_InteractiveFlag) + return 0; + return (filename == NULL) || + (strcmp(filename, "") == 0) || + (strcmp(filename, "???") == 0); +} + + +/* Wrappers around sigaction() or signal(). */ + +PyOS_sighandler_t +PyOS_getsig(int sig) +{ +#ifdef HAVE_SIGACTION + struct sigaction context; + if (sigaction(sig, NULL, &context) == -1) + return SIG_ERR; + return context.sa_handler; +#else + PyOS_sighandler_t handler; +/* Special signal handling for the secure CRT in Visual Studio 2005 */ +#if defined(_MSC_VER) && _MSC_VER >= 1400 + switch (sig) { + /* Only these signals are valid */ + case SIGINT: + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGTERM: + case SIGBREAK: + case SIGABRT: + break; + /* Don't call signal() with other values or it will assert */ + default: + return SIG_ERR; + } +#endif /* _MSC_VER && _MSC_VER >= 1400 */ + handler = signal(sig, SIG_IGN); + if (handler != SIG_ERR) + signal(sig, handler); + return handler; +#endif +} + +/* + * 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. + */ +PyOS_sighandler_t +PyOS_setsig(int sig, PyOS_sighandler_t handler) +{ +#ifdef HAVE_SIGACTION + /* Some code in Modules/signalmodule.c depends on sigaction() being + * used here if HAVE_SIGACTION is defined. Fix that if this code + * changes to invalidate that assumption. + */ + struct sigaction context, ocontext; + context.sa_handler = handler; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + if (sigaction(sig, &context, &ocontext) == -1) + return SIG_ERR; + return ocontext.sa_handler; +#else + PyOS_sighandler_t oldhandler; + oldhandler = signal(sig, handler); +#ifdef HAVE_SIGINTERRUPT + siginterrupt(sig, 1); +#endif + return oldhandler; +#endif +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Python/pymath.c b/python/Python/pymath.c new file mode 100755 index 0000000..24b8042 --- /dev/null +++ b/python/Python/pymath.c @@ -0,0 +1,81 @@ +#include "Python.h" + +#ifdef X87_DOUBLE_ROUNDING +/* On x86 platforms using an x87 FPU, this function is called from the + Py_FORCE_DOUBLE macro (defined in pymath.h) to force a floating-point + number out of an 80-bit x87 FPU register and into a 64-bit memory location, + thus rounding from extended precision to double precision. */ +double _Py_force_double(double x) +{ + volatile double y; + y = x; + return y; +} +#endif + +#ifdef HAVE_GCC_ASM_FOR_X87 + +/* inline assembly for getting and setting the 387 FPU control word on + gcc/x86 */ +#ifdef _Py_MEMORY_SANITIZER +__attribute__((no_sanitize_memory)) +#endif +unsigned short _Py_get_387controlword(void) { + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + return cw; +} + +void _Py_set_387controlword(unsigned short cw) { + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); +} + +#endif + + +#ifndef HAVE_HYPOT +double hypot(double x, double y) +{ + double yx; + + x = fabs(x); + y = fabs(y); + if (x < y) { + double temp = x; + x = y; + y = temp; + } + if (x == 0.) + return 0.; + else { + yx = y/x; + return x*sqrt(1.+yx*yx); + } +} +#endif /* HAVE_HYPOT */ + +#ifndef HAVE_COPYSIGN +double +copysign(double x, double y) +{ + /* use atan2 to distinguish -0. from 0. */ + if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) { + return fabs(x); + } else { + return -fabs(x); + } +} +#endif /* HAVE_COPYSIGN */ + +#ifndef HAVE_ROUND +double +round(double x) +{ + double absx, y; + absx = fabs(x); + y = floor(absx); + if (absx - y >= 0.5) + y += 1.0; + return copysign(y, x); +} +#endif /* HAVE_ROUND */ diff --git a/python/Python/pystate.c b/python/Python/pystate.c new file mode 100755 index 0000000..56c184e --- /dev/null +++ b/python/Python/pystate.c @@ -0,0 +1,1724 @@ + +/* Thread and interpreter state structures and their interfaces */ + +#include "Python.h" +#include "pycore_ceval.h" +#include "pycore_initconfig.h" +#include "pycore_pymem.h" +#include "pycore_pystate.h" +#include "pycore_pylifecycle.h" + +/* -------------------------------------------------------------------------- +CAUTION + +Always use PyMem_RawMalloc() and PyMem_RawFree() directly in this file. A +number of these functions are advertised as safe to call when the GIL isn't +held, and in a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's +debugging obmalloc functions. Those aren't thread-safe (they rely on the GIL +to avoid the expense of doing their own locking). +-------------------------------------------------------------------------- */ + +#ifdef HAVE_DLOPEN +#ifdef HAVE_DLFCN_H +#include +#endif +#if !HAVE_DECL_RTLD_LAZY +#define RTLD_LAZY 1 +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define _PyRuntimeGILState_GetThreadState(gilstate) \ + ((PyThreadState*)_Py_atomic_load_relaxed(&(gilstate)->tstate_current)) +#define _PyRuntimeGILState_SetThreadState(gilstate, value) \ + _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \ + (uintptr_t)(value)) + +/* Forward declarations */ +static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); +static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate); + + +static PyStatus +_PyRuntimeState_Init_impl(_PyRuntimeState *runtime) +{ + /* We preserve the hook across init, because there is + currently no public API to set it between runtime + initialization and interpreter initialization. */ + void *open_code_hook = runtime->open_code_hook; + void *open_code_userdata = runtime->open_code_userdata; + _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head; + + memset(runtime, 0, sizeof(*runtime)); + + runtime->open_code_hook = open_code_hook; + runtime->open_code_userdata = open_code_userdata; + runtime->audit_hook_head = audit_hook_head; + + _PyGC_Initialize(&runtime->gc); + _PyEval_Initialize(&runtime->ceval); + + PyPreConfig_InitPythonConfig(&runtime->preconfig); + + runtime->gilstate.check_enabled = 1; + + /* A TSS key must be initialized with Py_tss_NEEDS_INIT + in accordance with the specification. */ + Py_tss_t initial = Py_tss_NEEDS_INIT; + runtime->gilstate.autoTSSkey = initial; + + runtime->interpreters.mutex = PyThread_allocate_lock(); + if (runtime->interpreters.mutex == NULL) { + return _PyStatus_ERR("Can't initialize threads for interpreter"); + } + runtime->interpreters.next_id = -1; + + runtime->xidregistry.mutex = PyThread_allocate_lock(); + if (runtime->xidregistry.mutex == NULL) { + return _PyStatus_ERR("Can't initialize threads for cross-interpreter data registry"); + } + + // Set it to the ID of the main thread of the main interpreter. + runtime->main_thread = PyThread_get_thread_ident(); + + return _PyStatus_OK(); +} + +PyStatus +_PyRuntimeState_Init(_PyRuntimeState *runtime) +{ + /* Force default allocator, since _PyRuntimeState_Fini() must + use the same allocator than this function. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + PyStatus status = _PyRuntimeState_Init_impl(runtime); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return status; +} + +void +_PyRuntimeState_Fini(_PyRuntimeState *runtime) +{ + /* Force the allocator used by _PyRuntimeState_Init(). */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (runtime->interpreters.mutex != NULL) { + PyThread_free_lock(runtime->interpreters.mutex); + runtime->interpreters.mutex = NULL; + } + + if (runtime->xidregistry.mutex != NULL) { + PyThread_free_lock(runtime->xidregistry.mutex); + runtime->xidregistry.mutex = NULL; + } + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + +/* This function is called from PyOS_AfterFork_Child to ensure that + * newly created child processes do not share locks with the parent. + */ + +void +_PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) +{ + // This was initially set in _PyRuntimeState_Init(). + runtime->main_thread = PyThread_get_thread_ident(); + + /* Force default allocator, since _PyRuntimeState_Fini() must + use the same allocator than this function. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + runtime->interpreters.mutex = PyThread_allocate_lock(); + runtime->interpreters.main->id_mutex = PyThread_allocate_lock(); + runtime->xidregistry.mutex = PyThread_allocate_lock(); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (runtime->interpreters.mutex == NULL) { + Py_FatalError("Can't initialize lock for runtime interpreters"); + } + + if (runtime->interpreters.main->id_mutex == NULL) { + Py_FatalError("Can't initialize ID lock for main interpreter"); + } + + if (runtime->xidregistry.mutex == NULL) { + Py_FatalError("Can't initialize lock for cross-interpreter data registry"); + } +} + +#define HEAD_LOCK(runtime) \ + PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) +#define HEAD_UNLOCK(runtime) \ + PyThread_release_lock((runtime)->interpreters.mutex) + +/* Forward declaration */ +static void _PyGILState_NoteThreadState( + struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); + +PyStatus +_PyInterpreterState_Enable(_PyRuntimeState *runtime) +{ + struct pyinterpreters *interpreters = &runtime->interpreters; + interpreters->next_id = 0; + + /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex. + Create a new mutex if needed. */ + if (interpreters->mutex == NULL) { + /* Force default allocator, since _PyRuntimeState_Fini() must + use the same allocator than this function. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + interpreters->mutex = PyThread_allocate_lock(); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (interpreters->mutex == NULL) { + return _PyStatus_ERR("Can't initialize threads for interpreter"); + } + } + + return _PyStatus_OK(); +} + +PyInterpreterState * +PyInterpreterState_New(void) +{ + if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) { + return NULL; + } + + PyInterpreterState *interp = PyMem_RawMalloc(sizeof(PyInterpreterState)); + if (interp == NULL) { + return NULL; + } + + memset(interp, 0, sizeof(*interp)); + interp->id_refcount = -1; + interp->check_interval = 100; + + PyConfig_InitPythonConfig(&interp->config); + + interp->eval_frame = _PyEval_EvalFrameDefault; +#ifdef HAVE_DLOPEN +#if HAVE_DECL_RTLD_NOW + interp->dlopenflags = RTLD_NOW; +#else + interp->dlopenflags = RTLD_LAZY; +#endif +#endif + + _PyRuntimeState *runtime = &_PyRuntime; + struct pyinterpreters *interpreters = &runtime->interpreters; + + HEAD_LOCK(runtime); + if (interpreters->next_id < 0) { + /* overflow or Py_Initialize() not called! */ + PyErr_SetString(PyExc_RuntimeError, + "failed to get an interpreter ID"); + PyMem_RawFree(interp); + interp = NULL; + } + else { + interp->id = interpreters->next_id; + interpreters->next_id += 1; + interp->next = interpreters->head; + if (interpreters->main == NULL) { + interpreters->main = interp; + } + interpreters->head = interp; + } + HEAD_UNLOCK(runtime); + + if (interp == NULL) { + return NULL; + } + + interp->tstate_next_unique_id = 0; + + interp->audit_hooks = NULL; + + return interp; +} + + +static void +_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) +{ + if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) { + PyErr_Clear(); + } + + HEAD_LOCK(runtime); + for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) { + PyThreadState_Clear(p); + } + HEAD_UNLOCK(runtime); + + Py_CLEAR(interp->audit_hooks); + + PyConfig_Clear(&interp->config); + Py_CLEAR(interp->codec_search_path); + Py_CLEAR(interp->codec_search_cache); + Py_CLEAR(interp->codec_error_registry); + Py_CLEAR(interp->modules); + Py_CLEAR(interp->modules_by_index); + Py_CLEAR(interp->sysdict); + Py_CLEAR(interp->builtins); + Py_CLEAR(interp->builtins_copy); + Py_CLEAR(interp->importlib); + Py_CLEAR(interp->import_func); + Py_CLEAR(interp->dict); +#ifdef HAVE_FORK + Py_CLEAR(interp->before_forkers); + Py_CLEAR(interp->after_forkers_parent); + Py_CLEAR(interp->after_forkers_child); +#endif + if (runtime->finalizing == NULL) { + _PyWarnings_Fini(interp); + } + // XXX Once we have one allocator per interpreter (i.e. + // per-interpreter GC) we must ensure that all of the interpreter's + // objects have been cleaned up at the point. +} + +void +PyInterpreterState_Clear(PyInterpreterState *interp) +{ + _PyInterpreterState_Clear(&_PyRuntime, interp); +} + + +static void +zapthreads(_PyRuntimeState *runtime, PyInterpreterState *interp) +{ + PyThreadState *p; + /* No need to lock the mutex here because this should only happen + when the threads are all really dead (XXX famous last words). */ + while ((p = interp->tstate_head) != NULL) { + _PyThreadState_Delete(runtime, p); + } +} + + +static void +_PyInterpreterState_Delete(_PyRuntimeState *runtime, + PyInterpreterState *interp) +{ + struct pyinterpreters *interpreters = &runtime->interpreters; + zapthreads(runtime, interp); + HEAD_LOCK(runtime); + PyInterpreterState **p; + for (p = &interpreters->head; ; p = &(*p)->next) { + if (*p == NULL) { + Py_FatalError("PyInterpreterState_Delete: invalid interp"); + } + if (*p == interp) { + break; + } + } + if (interp->tstate_head != NULL) { + Py_FatalError("PyInterpreterState_Delete: remaining threads"); + } + *p = interp->next; + if (interpreters->main == interp) { + interpreters->main = NULL; + if (interpreters->head != NULL) { + Py_FatalError("PyInterpreterState_Delete: remaining subinterpreters"); + } + } + HEAD_UNLOCK(runtime); + if (interp->id_mutex != NULL) { + PyThread_free_lock(interp->id_mutex); + } + PyMem_RawFree(interp); +} + + +void +PyInterpreterState_Delete(PyInterpreterState *interp) +{ + _PyInterpreterState_Delete(&_PyRuntime, interp); +} + + +/* + * Delete all interpreter states except the main interpreter. If there + * is a current interpreter state, it *must* be the main interpreter. + */ +void +_PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) +{ + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct pyinterpreters *interpreters = &runtime->interpreters; + + PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL); + if (tstate != NULL && tstate->interp != interpreters->main) { + Py_FatalError("PyInterpreterState_DeleteExceptMain: not main interpreter"); + } + + HEAD_LOCK(runtime); + PyInterpreterState *interp = interpreters->head; + interpreters->head = NULL; + while (interp != NULL) { + if (interp == interpreters->main) { + interpreters->main->next = NULL; + interpreters->head = interp; + interp = interp->next; + continue; + } + + _PyInterpreterState_Clear(runtime, interp); // XXX must activate? + zapthreads(runtime, interp); + if (interp->id_mutex != NULL) { + PyThread_free_lock(interp->id_mutex); + } + PyInterpreterState *prev_interp = interp; + interp = interp->next; + PyMem_RawFree(prev_interp); + } + HEAD_UNLOCK(runtime); + + if (interpreters->head == NULL) { + Py_FatalError("PyInterpreterState_DeleteExceptMain: missing main"); + } + _PyThreadState_Swap(gilstate, tstate); +} + + +PyInterpreterState * +_PyInterpreterState_Get(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) { + Py_FatalError("_PyInterpreterState_Get(): no current thread state"); + } + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("_PyInterpreterState_Get(): no current interpreter"); + } + return interp; +} + + +int64_t +PyInterpreterState_GetID(PyInterpreterState *interp) +{ + if (interp == NULL) { + PyErr_SetString(PyExc_RuntimeError, "no interpreter provided"); + return -1; + } + return interp->id; +} + + +static PyInterpreterState * +interp_look_up_id(_PyRuntimeState *runtime, PY_INT64_T requested_id) +{ + PyInterpreterState *interp = runtime->interpreters.head; + while (interp != NULL) { + PY_INT64_T id = PyInterpreterState_GetID(interp); + if (id < 0) { + return NULL; + } + if (requested_id == id) { + return interp; + } + interp = PyInterpreterState_Next(interp); + } + return NULL; +} + +PyInterpreterState * +_PyInterpreterState_LookUpID(PY_INT64_T requested_id) +{ + PyInterpreterState *interp = NULL; + if (requested_id >= 0) { + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + interp = interp_look_up_id(runtime, requested_id); + HEAD_UNLOCK(runtime); + } + if (interp == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_RuntimeError, + "unrecognized interpreter ID %lld", requested_id); + } + return interp; +} + + +int +_PyInterpreterState_IDInitref(PyInterpreterState *interp) +{ + if (interp->id_mutex != NULL) { + return 0; + } + interp->id_mutex = PyThread_allocate_lock(); + if (interp->id_mutex == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "failed to create init interpreter ID mutex"); + return -1; + } + interp->id_refcount = 0; + return 0; +} + + +int +_PyInterpreterState_IDIncref(PyInterpreterState *interp) +{ + if (_PyInterpreterState_IDInitref(interp) < 0) { + return -1; + } + + PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); + interp->id_refcount += 1; + PyThread_release_lock(interp->id_mutex); + return 0; +} + + +void +_PyInterpreterState_IDDecref(PyInterpreterState *interp) +{ + assert(interp->id_mutex != NULL); + + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); + assert(interp->id_refcount != 0); + interp->id_refcount -= 1; + int64_t refcount = interp->id_refcount; + PyThread_release_lock(interp->id_mutex); + + if (refcount == 0 && interp->requires_idref) { + // XXX Using the "head" thread isn't strictly correct. + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + // XXX Possible GILState issues? + PyThreadState *save_tstate = _PyThreadState_Swap(gilstate, tstate); + Py_EndInterpreter(tstate); + _PyThreadState_Swap(gilstate, save_tstate); + } +} + +int +_PyInterpreterState_RequiresIDRef(PyInterpreterState *interp) +{ + return interp->requires_idref; +} + +void +_PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required) +{ + interp->requires_idref = required ? 1 : 0; +} + +PyObject * +_PyInterpreterState_GetMainModule(PyInterpreterState *interp) +{ + if (interp->modules == NULL) { + PyErr_SetString(PyExc_RuntimeError, "interpreter not initialized"); + return NULL; + } + return PyMapping_GetItemString(interp->modules, "__main__"); +} + +PyObject * +PyInterpreterState_GetDict(PyInterpreterState *interp) +{ + if (interp->dict == NULL) { + interp->dict = PyDict_New(); + if (interp->dict == NULL) { + PyErr_Clear(); + } + } + /* Returning NULL means no per-interpreter dict is available. */ + return interp->dict; +} + +/* Default implementation for _PyThreadState_GetFrame */ +static struct _frame * +threadstate_getframe(PyThreadState *self) +{ + return self->frame; +} + +static PyThreadState * +new_threadstate(PyInterpreterState *interp, int init) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); + if (tstate == NULL) { + return NULL; + } + + if (_PyThreadState_GetFrame == NULL) { + _PyThreadState_GetFrame = threadstate_getframe; + } + + tstate->interp = interp; + + tstate->frame = NULL; + tstate->recursion_depth = 0; + tstate->overflowed = 0; + tstate->recursion_critical = 0; + tstate->stackcheck_counter = 0; + tstate->tracing = 0; + tstate->use_tracing = 0; + tstate->gilstate_counter = 0; + tstate->async_exc = NULL; + tstate->thread_id = PyThread_get_thread_ident(); + + tstate->dict = NULL; + + tstate->curexc_type = NULL; + tstate->curexc_value = NULL; + tstate->curexc_traceback = NULL; + + tstate->exc_state.exc_type = NULL; + tstate->exc_state.exc_value = NULL; + tstate->exc_state.exc_traceback = NULL; + tstate->exc_state.previous_item = NULL; + tstate->exc_info = &tstate->exc_state; + + tstate->c_profilefunc = NULL; + tstate->c_tracefunc = NULL; + tstate->c_profileobj = NULL; + tstate->c_traceobj = NULL; + + tstate->trash_delete_nesting = 0; + tstate->trash_delete_later = NULL; + tstate->on_delete = NULL; + tstate->on_delete_data = NULL; + + tstate->coroutine_origin_tracking_depth = 0; + + tstate->async_gen_firstiter = NULL; + tstate->async_gen_finalizer = NULL; + + tstate->context = NULL; + tstate->context_ver = 1; + + if (init) { + _PyThreadState_Init(runtime, tstate); + } + + HEAD_LOCK(runtime); + tstate->id = ++interp->tstate_next_unique_id; + tstate->prev = NULL; + tstate->next = interp->tstate_head; + if (tstate->next) + tstate->next->prev = tstate; + interp->tstate_head = tstate; + HEAD_UNLOCK(runtime); + + return tstate; +} + +PyThreadState * +PyThreadState_New(PyInterpreterState *interp) +{ + return new_threadstate(interp, 1); +} + +PyThreadState * +_PyThreadState_Prealloc(PyInterpreterState *interp) +{ + return new_threadstate(interp, 0); +} + +void +_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + _PyGILState_NoteThreadState(&runtime->gilstate, tstate); +} + +PyObject* +PyState_FindModule(struct PyModuleDef* module) +{ + Py_ssize_t index = module->m_base.m_index; + PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE(); + PyObject *res; + if (module->m_slots) { + return NULL; + } + if (index == 0) + return NULL; + if (state->modules_by_index == NULL) + return NULL; + if (index >= PyList_GET_SIZE(state->modules_by_index)) + return NULL; + res = PyList_GET_ITEM(state->modules_by_index, index); + return res==Py_None ? NULL : res; +} + +int +_PyState_AddModule(PyObject* module, struct PyModuleDef* def) +{ + PyInterpreterState *state; + if (!def) { + assert(PyErr_Occurred()); + return -1; + } + if (def->m_slots) { + PyErr_SetString(PyExc_SystemError, + "PyState_AddModule called on module with slots"); + return -1; + } + state = _PyInterpreterState_GET_UNSAFE(); + if (!state->modules_by_index) { + state->modules_by_index = PyList_New(0); + if (!state->modules_by_index) + return -1; + } + while (PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index) + if (PyList_Append(state->modules_by_index, Py_None) < 0) + return -1; + Py_INCREF(module); + return PyList_SetItem(state->modules_by_index, + def->m_base.m_index, module); +} + +int +PyState_AddModule(PyObject* module, struct PyModuleDef* def) +{ + Py_ssize_t index; + PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE(); + if (!def) { + Py_FatalError("PyState_AddModule: Module Definition is NULL"); + return -1; + } + index = def->m_base.m_index; + if (state->modules_by_index && + index < PyList_GET_SIZE(state->modules_by_index) && + module == PyList_GET_ITEM(state->modules_by_index, index)) { + Py_FatalError("PyState_AddModule: Module already added!"); + return -1; + } + return _PyState_AddModule(module, def); +} + +int +PyState_RemoveModule(struct PyModuleDef* def) +{ + PyInterpreterState *state; + Py_ssize_t index = def->m_base.m_index; + if (def->m_slots) { + PyErr_SetString(PyExc_SystemError, + "PyState_RemoveModule called on module with slots"); + return -1; + } + state = _PyInterpreterState_GET_UNSAFE(); + if (index == 0) { + Py_FatalError("PyState_RemoveModule: Module index invalid."); + return -1; + } + if (state->modules_by_index == NULL) { + Py_FatalError("PyState_RemoveModule: Interpreters module-list not accessible."); + return -1; + } + if (index > PyList_GET_SIZE(state->modules_by_index)) { + Py_FatalError("PyState_RemoveModule: Module index out of bounds."); + return -1; + } + Py_INCREF(Py_None); + return PyList_SetItem(state->modules_by_index, index, Py_None); +} + +/* used by import.c:PyImport_Cleanup */ +void +_PyState_ClearModules(void) +{ + PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE(); + if (state->modules_by_index) { + Py_ssize_t i; + for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) { + PyObject *m = PyList_GET_ITEM(state->modules_by_index, i); + if (PyModule_Check(m)) { + /* cleanup the saved copy of module dicts */ + PyModuleDef *md = PyModule_GetDef(m); + if (md) + Py_CLEAR(md->m_base.m_copy); + } + } + /* Setting modules_by_index to NULL could be dangerous, so we + clear the list instead. */ + if (PyList_SetSlice(state->modules_by_index, + 0, PyList_GET_SIZE(state->modules_by_index), + NULL)) + PyErr_WriteUnraisable(state->modules_by_index); + } +} + +void +PyThreadState_Clear(PyThreadState *tstate) +{ + int verbose = tstate->interp->config.verbose; + + if (verbose && tstate->frame != NULL) { + /* bpo-20526: After the main thread calls + _PyRuntimeState_SetFinalizing() in Py_FinalizeEx(), threads must + exit when trying to take the GIL. If a thread exit in the middle of + _PyEval_EvalFrameDefault(), tstate->frame is not reset to its + previous value. It is more likely with daemon threads, but it can + happen with regular threads if threading._shutdown() fails + (ex: interrupted by CTRL+C). */ + fprintf(stderr, + "PyThreadState_Clear: warning: thread still has a frame\n"); + } + + /* Don't clear tstate->frame: it is a borrowed reference */ + + Py_CLEAR(tstate->dict); + Py_CLEAR(tstate->async_exc); + + Py_CLEAR(tstate->curexc_type); + Py_CLEAR(tstate->curexc_value); + Py_CLEAR(tstate->curexc_traceback); + + Py_CLEAR(tstate->exc_state.exc_type); + Py_CLEAR(tstate->exc_state.exc_value); + Py_CLEAR(tstate->exc_state.exc_traceback); + + /* The stack of exception states should contain just this thread. */ + if (verbose && tstate->exc_info != &tstate->exc_state) { + fprintf(stderr, + "PyThreadState_Clear: warning: thread still has a generator\n"); + } + + tstate->c_profilefunc = NULL; + tstate->c_tracefunc = NULL; + Py_CLEAR(tstate->c_profileobj); + Py_CLEAR(tstate->c_traceobj); + + Py_CLEAR(tstate->async_gen_firstiter); + Py_CLEAR(tstate->async_gen_finalizer); + + Py_CLEAR(tstate->context); +} + + +/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ +static void +tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + if (tstate == NULL) { + Py_FatalError("PyThreadState_Delete: NULL tstate"); + } + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("PyThreadState_Delete: NULL interp"); + } + HEAD_LOCK(runtime); + if (tstate->prev) + tstate->prev->next = tstate->next; + else + interp->tstate_head = tstate->next; + if (tstate->next) + tstate->next->prev = tstate->prev; + HEAD_UNLOCK(runtime); + if (tstate->on_delete != NULL) { + tstate->on_delete(tstate->on_delete_data); + } + PyMem_RawFree(tstate); +} + + +static void +_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { + Py_FatalError("PyThreadState_Delete: tstate is still current"); + } + if (gilstate->autoInterpreterState && + PyThread_tss_get(&gilstate->autoTSSkey) == tstate) + { + PyThread_tss_set(&gilstate->autoTSSkey, NULL); + } + tstate_delete_common(runtime, tstate); +} + + +void +PyThreadState_Delete(PyThreadState *tstate) +{ + _PyThreadState_Delete(&_PyRuntime, tstate); +} + + +static void +_PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) +{ + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); + if (tstate == NULL) + Py_FatalError( + "PyThreadState_DeleteCurrent: no current tstate"); + tstate_delete_common(runtime, tstate); + if (gilstate->autoInterpreterState && + PyThread_tss_get(&gilstate->autoTSSkey) == tstate) + { + PyThread_tss_set(&gilstate->autoTSSkey, NULL); + } + _PyRuntimeGILState_SetThreadState(gilstate, NULL); + PyEval_ReleaseLock(); +} + +void +PyThreadState_DeleteCurrent() +{ + _PyThreadState_DeleteCurrent(&_PyRuntime); +} + + +/* + * Delete all thread states except the one passed as argument. + * Note that, if there is a current thread state, it *must* be the one + * passed as argument. Also, this won't touch any other interpreters + * than the current one, since we don't know which thread state should + * be kept in those other interpreters. + */ +void +_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + PyThreadState *p, *next, *garbage; + HEAD_LOCK(runtime); + /* Remove all thread states, except tstate, from the linked list of + thread states. This will allow calling PyThreadState_Clear() + without holding the lock. */ + garbage = interp->tstate_head; + if (garbage == tstate) + garbage = tstate->next; + if (tstate->prev) + tstate->prev->next = tstate->next; + if (tstate->next) + tstate->next->prev = tstate->prev; + tstate->prev = tstate->next = NULL; + interp->tstate_head = tstate; + HEAD_UNLOCK(runtime); + /* Clear and deallocate all stale thread states. Even if this + executes Python code, we should be safe since it executes + in the current thread, not one of the stale threads. */ + for (p = garbage; p; p = next) { + next = p->next; + PyThreadState_Clear(p); + PyMem_RawFree(p); + } +} + + +PyThreadState * +_PyThreadState_UncheckedGet(void) +{ + return _PyThreadState_GET(); +} + + +PyThreadState * +PyThreadState_Get(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) + Py_FatalError("PyThreadState_Get: no current thread"); + + return tstate; +} + + +PyThreadState * +_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts) +{ + PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate); + + _PyRuntimeGILState_SetThreadState(gilstate, newts); + /* It should not be possible for more than one thread state + to be used for a thread. Check this the best we can in debug + builds. + */ +#if defined(Py_DEBUG) + if (newts) { + /* This can be called from PyEval_RestoreThread(). Similar + to it, we need to ensure errno doesn't change. + */ + int err = errno; + PyThreadState *check = _PyGILState_GetThisThreadState(gilstate); + if (check && check->interp == newts->interp && check != newts) + Py_FatalError("Invalid thread state for this thread"); + errno = err; + } +#endif + return oldts; +} + +PyThreadState * +PyThreadState_Swap(PyThreadState *newts) +{ + return _PyThreadState_Swap(&_PyRuntime.gilstate, newts); +} + +/* An extension mechanism to store arbitrary additional per-thread state. + PyThreadState_GetDict() returns a dictionary that can be used to hold such + state; the caller should pick a unique key and store its state there. If + PyThreadState_GetDict() returns NULL, an exception has *not* been raised + and the caller should assume no per-thread state is available. */ + +PyObject * +PyThreadState_GetDict(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) + return NULL; + + if (tstate->dict == NULL) { + PyObject *d; + tstate->dict = d = PyDict_New(); + if (d == NULL) + PyErr_Clear(); + } + return tstate->dict; +} + + +/* Asynchronously raise an exception in a thread. + Requested by Just van Rossum and Alex Martelli. + To prevent naive misuse, you must write your own extension + to call this, or use ctypes. Must be called with the GIL held. + Returns the number of tstates modified (normally 1, but 0 if `id` didn't + match any known thread id). Can be called with exc=NULL to clear an + existing async exception. This raises no exceptions. */ + +int +PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + + /* Although the GIL is held, a few C API functions can be called + * without the GIL held, and in particular some that create and + * destroy thread and interpreter states. Those can mutate the + * list of thread states we're traversing, so to prevent that we lock + * head_mutex for the duration. + */ + HEAD_LOCK(runtime); + for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) { + if (p->thread_id == id) { + /* Tricky: we need to decref the current value + * (if any) in p->async_exc, but that can in turn + * allow arbitrary Python code to run, including + * perhaps calls to this function. To prevent + * deadlock, we need to release head_mutex before + * the decref. + */ + PyObject *old_exc = p->async_exc; + Py_XINCREF(exc); + p->async_exc = exc; + HEAD_UNLOCK(runtime); + Py_XDECREF(old_exc); + _PyEval_SignalAsyncExc(&runtime->ceval); + return 1; + } + } + HEAD_UNLOCK(runtime); + return 0; +} + + +/* Routines for advanced debuggers, requested by David Beazley. + Don't use unless you know what you are doing! */ + +PyInterpreterState * +PyInterpreterState_Head(void) +{ + return _PyRuntime.interpreters.head; +} + +PyInterpreterState * +PyInterpreterState_Main(void) +{ + return _PyRuntime.interpreters.main; +} + +PyInterpreterState * +PyInterpreterState_Next(PyInterpreterState *interp) { + return interp->next; +} + +PyThreadState * +PyInterpreterState_ThreadHead(PyInterpreterState *interp) { + return interp->tstate_head; +} + +PyThreadState * +PyThreadState_Next(PyThreadState *tstate) { + return tstate->next; +} + +/* The implementation of sys._current_frames(). This is intended to be + called with the GIL held, as it will be when called via + sys._current_frames(). It's possible it would work fine even without + the GIL held, but haven't thought enough about that. +*/ +PyObject * +_PyThread_CurrentFrames(void) +{ + PyObject *result; + PyInterpreterState *i; + + if (PySys_Audit("sys._current_frames", NULL) < 0) { + return NULL; + } + + result = PyDict_New(); + if (result == NULL) + return NULL; + + /* for i in all interpreters: + * for t in all of i's thread states: + * if t's frame isn't NULL, map t's id to its frame + * Because these lists can mutate even when the GIL is held, we + * need to grab head_mutex for the duration. + */ + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + for (i = runtime->interpreters.head; i != NULL; i = i->next) { + PyThreadState *t; + for (t = i->tstate_head; t != NULL; t = t->next) { + PyObject *id; + int stat; + struct _frame *frame = t->frame; + if (frame == NULL) + continue; + id = PyLong_FromUnsignedLong(t->thread_id); + if (id == NULL) + goto Fail; + stat = PyDict_SetItem(result, id, (PyObject *)frame); + Py_DECREF(id); + if (stat < 0) + goto Fail; + } + } + HEAD_UNLOCK(runtime); + return result; + + Fail: + HEAD_UNLOCK(runtime); + Py_DECREF(result); + return NULL; +} + +/* Python "auto thread state" API. */ + +/* Keep this as a static, as it is not reliable! It can only + ever be compared to the state for the *current* thread. + * If not equal, then it doesn't matter that the actual + value may change immediately after comparison, as it can't + possibly change to the current thread's state. + * If equal, then the current thread holds the lock, so the value can't + change until we yield the lock. +*/ +static int +PyThreadState_IsCurrent(PyThreadState *tstate) +{ + /* Must be the tstate for this thread */ + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + assert(_PyGILState_GetThisThreadState(gilstate) == tstate); + return tstate == _PyRuntimeGILState_GetThreadState(gilstate); +} + +/* Internal initialization/finalization functions called by + Py_Initialize/Py_FinalizeEx +*/ +void +_PyGILState_Init(_PyRuntimeState *runtime, + PyInterpreterState *interp, PyThreadState *tstate) +{ + /* must init with valid states */ + assert(interp != NULL); + assert(tstate != NULL); + + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + + if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { + Py_FatalError("Could not allocate TSS entry"); + } + gilstate->autoInterpreterState = interp; + assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); + assert(tstate->gilstate_counter == 0); + + _PyGILState_NoteThreadState(gilstate, tstate); +} + +PyInterpreterState * +_PyGILState_GetInterpreterStateUnsafe(void) +{ + return _PyRuntime.gilstate.autoInterpreterState; +} + +void +_PyGILState_Fini(_PyRuntimeState *runtime) +{ + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + PyThread_tss_delete(&gilstate->autoTSSkey); + gilstate->autoInterpreterState = NULL; +} + +/* Reset the TSS key - called by PyOS_AfterFork_Child(). + * This should not be necessary, but some - buggy - pthread implementations + * don't reset TSS upon fork(), see issue #10517. + */ +void +_PyGILState_Reinit(_PyRuntimeState *runtime) +{ + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + PyThreadState *tstate = _PyGILState_GetThisThreadState(gilstate); + + PyThread_tss_delete(&gilstate->autoTSSkey); + if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { + Py_FatalError("Could not allocate TSS entry"); + } + + /* If the thread had an associated auto thread state, reassociate it with + * the new key. */ + if (tstate && + PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0) + { + Py_FatalError("Couldn't create autoTSSkey mapping"); + } +} + +/* When a thread state is created for a thread by some mechanism other than + PyGILState_Ensure, it's important that the GILState machinery knows about + it so it doesn't try to create another thread state for the thread (this is + a better fix for SF bug #1010677 than the first one attempted). +*/ +static void +_PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate) +{ + /* If autoTSSkey isn't initialized, this must be the very first + threadstate created in Py_Initialize(). Don't do anything for now + (we'll be back here when _PyGILState_Init is called). */ + if (!gilstate->autoInterpreterState) { + return; + } + + /* Stick the thread state for this thread in thread specific storage. + + The only situation where you can legitimately have more than one + thread state for an OS level thread is when there are multiple + interpreters. + + You shouldn't really be using the PyGILState_ APIs anyway (see issues + #10915 and #15751). + + The first thread state created for that given OS level thread will + "win", which seems reasonable behaviour. + */ + if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) { + if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) { + Py_FatalError("Couldn't create autoTSSkey mapping"); + } + } + + /* PyGILState_Release must not try to delete this thread state. */ + tstate->gilstate_counter = 1; +} + +/* The public functions */ +static PyThreadState * +_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate) +{ + if (gilstate->autoInterpreterState == NULL) + return NULL; + return (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); +} + +PyThreadState * +PyGILState_GetThisThreadState(void) +{ + return _PyGILState_GetThisThreadState(&_PyRuntime.gilstate); +} + +int +PyGILState_Check(void) +{ + + if (!_PyGILState_check_enabled) { + return 1; + } + + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { + return 1; + } + + PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); + if (tstate == NULL) { + return 0; + } + + return (tstate == _PyGILState_GetThisThreadState(gilstate)); +} + +PyGILState_STATE +PyGILState_Ensure(void) +{ + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + int current; + PyThreadState *tcur; + int need_init_threads = 0; + + /* Note that we do not auto-init Python here - apart from + potential races with 2 threads auto-initializing, pep-311 + spells out other issues. Embedders are expected to have + called Py_Initialize() and usually PyEval_InitThreads(). + */ + /* Py_Initialize() hasn't been called! */ + assert(gilstate->autoInterpreterState); + + tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); + if (tcur == NULL) { + need_init_threads = 1; + + /* Create a new thread state for this thread */ + tcur = PyThreadState_New(gilstate->autoInterpreterState); + if (tcur == NULL) + Py_FatalError("Couldn't create thread-state for new thread"); + /* This is our thread state! We'll need to delete it in the + matching call to PyGILState_Release(). */ + tcur->gilstate_counter = 0; + current = 0; /* new thread state is never current */ + } + else { + current = PyThreadState_IsCurrent(tcur); + } + + if (current == 0) { + PyEval_RestoreThread(tcur); + } + + /* Update our counter in the thread-state - no need for locks: + - tcur will remain valid as we hold the GIL. + - the counter is safe as we are the only thread "allowed" + to modify this value + */ + ++tcur->gilstate_counter; + + if (need_init_threads) { + /* At startup, Python has no concrete GIL. If PyGILState_Ensure() is + called from a new thread for the first time, we need the create the + GIL. */ + PyEval_InitThreads(); + } + + return current ? PyGILState_LOCKED : PyGILState_UNLOCKED; +} + +void +PyGILState_Release(PyGILState_STATE oldstate) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tcur = PyThread_tss_get(&runtime->gilstate.autoTSSkey); + if (tcur == NULL) { + Py_FatalError("auto-releasing thread-state, " + "but no thread-state for this thread"); + } + + /* We must hold the GIL and have our thread state current */ + /* XXX - remove the check - the assert should be fine, + but while this is very new (April 2003), the extra check + by release-only users can't hurt. + */ + if (!PyThreadState_IsCurrent(tcur)) { + Py_FatalError("This thread state must be current when releasing"); + } + assert(PyThreadState_IsCurrent(tcur)); + --tcur->gilstate_counter; + assert(tcur->gilstate_counter >= 0); /* illegal counter value */ + + /* If we're going to destroy this thread-state, we must + * clear it while the GIL is held, as destructors may run. + */ + if (tcur->gilstate_counter == 0) { + /* can't have been locked when we created it */ + assert(oldstate == PyGILState_UNLOCKED); + PyThreadState_Clear(tcur); + /* Delete the thread-state. Note this releases the GIL too! + * It's vital that the GIL be held here, to avoid shutdown + * races; see bugs 225673 and 1061968 (that nasty bug has a + * habit of coming back). + */ + _PyThreadState_DeleteCurrent(runtime); + } + /* Release the lock if necessary */ + else if (oldstate == PyGILState_UNLOCKED) + PyEval_SaveThread(); +} + + +/**************************/ +/* cross-interpreter data */ +/**************************/ + +/* cross-interpreter data */ + +crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); + +/* This is a separate func from _PyCrossInterpreterData_Lookup in order + to keep the registry code separate. */ +static crossinterpdatafunc +_lookup_getdata(PyObject *obj) +{ + crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj); + if (getdata == NULL && PyErr_Occurred() == 0) + PyErr_Format(PyExc_ValueError, + "%S does not support cross-interpreter data", obj); + return getdata; +} + +int +_PyObject_CheckCrossInterpreterData(PyObject *obj) +{ + crossinterpdatafunc getdata = _lookup_getdata(obj); + if (getdata == NULL) { + return -1; + } + return 0; +} + +static int +_check_xidata(_PyCrossInterpreterData *data) +{ + // data->data can be anything, including NULL, so we don't check it. + + // data->obj may be NULL, so we don't check it. + + if (data->interp < 0) { + PyErr_SetString(PyExc_SystemError, "missing interp"); + return -1; + } + + if (data->new_object == NULL) { + PyErr_SetString(PyExc_SystemError, "missing new_object func"); + return -1; + } + + // data->free may be NULL, so we don't check it. + + return 0; +} + +int +_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) +{ + // _PyInterpreterState_Get() aborts if lookup fails, so we don't need + // to check the result for NULL. + PyInterpreterState *interp = _PyInterpreterState_Get(); + + // Reset data before re-populating. + *data = (_PyCrossInterpreterData){0}; + data->free = PyMem_RawFree; // Set a default that may be overridden. + + // Call the "getdata" func for the object. + Py_INCREF(obj); + crossinterpdatafunc getdata = _lookup_getdata(obj); + if (getdata == NULL) { + Py_DECREF(obj); + return -1; + } + int res = getdata(obj, data); + Py_DECREF(obj); + if (res != 0) { + return -1; + } + + // Fill in the blanks and validate the result. + data->interp = interp->id; + if (_check_xidata(data) != 0) { + _PyCrossInterpreterData_Release(data); + return -1; + } + + return 0; +} + +static void +_release_xidata(void *arg) +{ + _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; + if (data->free != NULL) { + data->free(data->data); + } + Py_XDECREF(data->obj); +} + +static void +_call_in_interpreter(struct _gilstate_runtime_state *gilstate, + PyInterpreterState *interp, + void (*func)(void *), void *arg) +{ + /* We would use Py_AddPendingCall() if it weren't specific to the + * main interpreter (see bpo-33608). In the meantime we take a + * naive approach. + */ + PyThreadState *save_tstate = NULL; + if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) { + // XXX Using the "head" thread isn't strictly correct. + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + // XXX Possible GILState issues? + save_tstate = _PyThreadState_Swap(gilstate, tstate); + } + + func(arg); + + // Switch back. + if (save_tstate != NULL) { + _PyThreadState_Swap(gilstate, save_tstate); + } +} + +void +_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) +{ + if (data->data == NULL && data->obj == NULL) { + // Nothing to release! + return; + } + + // Switch to the original interpreter. + PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); + if (interp == NULL) { + // The intepreter was already destroyed. + if (data->free != NULL) { + // XXX Someone leaked some memory... + } + return; + } + + // "Release" the data and/or the object. + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + _call_in_interpreter(gilstate, interp, _release_xidata, data); +} + +PyObject * +_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) +{ + return data->new_object(data); +} + +/* registry of {type -> crossinterpdatafunc} */ + +/* For now we use a global registry of shareable classes. An + alternative would be to add a tp_* slot for a class's + crossinterpdatafunc. It would be simpler and more efficient. */ + +static int +_register_xidata(struct _xidregistry *xidregistry, PyTypeObject *cls, + crossinterpdatafunc getdata) +{ + // Note that we effectively replace already registered classes + // rather than failing. + struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); + if (newhead == NULL) + return -1; + newhead->cls = cls; + newhead->getdata = getdata; + newhead->next = xidregistry->head; + xidregistry->head = newhead; + return 0; +} + +static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry); + +int +_PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, + crossinterpdatafunc getdata) +{ + if (!PyType_Check(cls)) { + PyErr_Format(PyExc_ValueError, "only classes may be registered"); + return -1; + } + if (getdata == NULL) { + PyErr_Format(PyExc_ValueError, "missing 'getdata' func"); + return -1; + } + + // Make sure the class isn't ever deallocated. + Py_INCREF((PyObject *)cls); + + struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; + PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + if (xidregistry->head == NULL) { + _register_builtins_for_crossinterpreter_data(xidregistry); + } + int res = _register_xidata(xidregistry, cls, getdata); + PyThread_release_lock(xidregistry->mutex); + return res; +} + +/* Cross-interpreter objects are looked up by exact match on the class. + We can reassess this policy when we move from a global registry to a + tp_* slot. */ + +crossinterpdatafunc +_PyCrossInterpreterData_Lookup(PyObject *obj) +{ + struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; + PyObject *cls = PyObject_Type(obj); + crossinterpdatafunc getdata = NULL; + PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + struct _xidregitem *cur = xidregistry->head; + if (cur == NULL) { + _register_builtins_for_crossinterpreter_data(xidregistry); + cur = xidregistry->head; + } + for(; cur != NULL; cur = cur->next) { + if (cur->cls == (PyTypeObject *)cls) { + getdata = cur->getdata; + break; + } + } + Py_DECREF(cls); + PyThread_release_lock(xidregistry->mutex); + return getdata; +} + +/* cross-interpreter data for builtin types */ + +struct _shared_bytes_data { + char *bytes; + Py_ssize_t len; +}; + +static PyObject * +_new_bytes_object(_PyCrossInterpreterData *data) +{ + struct _shared_bytes_data *shared = (struct _shared_bytes_data *)(data->data); + return PyBytes_FromStringAndSize(shared->bytes, shared->len); +} + +static int +_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + struct _shared_bytes_data *shared = PyMem_NEW(struct _shared_bytes_data, 1); + if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { + return -1; + } + data->data = (void *)shared; + Py_INCREF(obj); + data->obj = obj; // Will be "released" (decref'ed) when data released. + data->new_object = _new_bytes_object; + data->free = PyMem_Free; + return 0; +} + +struct _shared_str_data { + int kind; + const void *buffer; + Py_ssize_t len; +}; + +static PyObject * +_new_str_object(_PyCrossInterpreterData *data) +{ + struct _shared_str_data *shared = (struct _shared_str_data *)(data->data); + return PyUnicode_FromKindAndData(shared->kind, shared->buffer, shared->len); +} + +static int +_str_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + struct _shared_str_data *shared = PyMem_NEW(struct _shared_str_data, 1); + shared->kind = PyUnicode_KIND(obj); + shared->buffer = PyUnicode_DATA(obj); + shared->len = PyUnicode_GET_LENGTH(obj); + data->data = (void *)shared; + Py_INCREF(obj); + data->obj = obj; // Will be "released" (decref'ed) when data released. + data->new_object = _new_str_object; + data->free = PyMem_Free; + return 0; +} + +static PyObject * +_new_long_object(_PyCrossInterpreterData *data) +{ + return PyLong_FromSsize_t((Py_ssize_t)(data->data)); +} + +static int +_long_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + /* Note that this means the size of shareable ints is bounded by + * sys.maxsize. Hence on 32-bit architectures that is half the + * size of maximum shareable ints on 64-bit. + */ + Py_ssize_t value = PyLong_AsSsize_t(obj); + if (value == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, "try sending as bytes"); + } + return -1; + } + data->data = (void *)value; + data->obj = NULL; + data->new_object = _new_long_object; + data->free = NULL; + return 0; +} + +static PyObject * +_new_none_object(_PyCrossInterpreterData *data) +{ + // XXX Singleton refcounts are problematic across interpreters... + Py_INCREF(Py_None); + return Py_None; +} + +static int +_none_shared(PyObject *obj, _PyCrossInterpreterData *data) +{ + data->data = NULL; + // data->obj remains NULL + data->new_object = _new_none_object; + data->free = NULL; // There is nothing to free. + return 0; +} + +static void +_register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) +{ + // None + if (_register_xidata(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { + Py_FatalError("could not register None for cross-interpreter sharing"); + } + + // int + if (_register_xidata(xidregistry, &PyLong_Type, _long_shared) != 0) { + Py_FatalError("could not register int for cross-interpreter sharing"); + } + + // bytes + if (_register_xidata(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { + Py_FatalError("could not register bytes for cross-interpreter sharing"); + } + + // str + if (_register_xidata(xidregistry, &PyUnicode_Type, _str_shared) != 0) { + Py_FatalError("could not register str for cross-interpreter sharing"); + } +} + + +#ifdef __cplusplus +} +#endif diff --git a/python/Python/pystrcmp.c b/python/Python/pystrcmp.c new file mode 100755 index 0000000..9224ce4 --- /dev/null +++ b/python/Python/pystrcmp.c @@ -0,0 +1,30 @@ +/* Cross platform case insensitive string compare functions + */ + +#include "Python.h" + +int +PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size) +{ + const unsigned char *p1, *p2; + if (size == 0) + return 0; + p1 = (const unsigned char *)s1; + p2 = (const unsigned char *)s2; + for (; (--size > 0) && *p1 && *p2 && (tolower(*p1) == tolower(*p2)); + p1++, p2++) { + ; + } + return tolower(*p1) - tolower(*p2); +} + +int +PyOS_mystricmp(const char *s1, const char *s2) +{ + const unsigned char *p1 = (const unsigned char *)s1; + const unsigned char *p2 = (const unsigned char *)s2; + for (; *p1 && *p2 && (tolower(*p1) == tolower(*p2)); p1++, p2++) { + ; + } + return (tolower(*p1) - tolower(*p2)); +} diff --git a/python/Python/pystrhex.c b/python/Python/pystrhex.c new file mode 100755 index 0000000..9d34f71 --- /dev/null +++ b/python/Python/pystrhex.c @@ -0,0 +1,133 @@ +/* bytes to hex implementation */ + +#include "Python.h" + +#include "pystrhex.h" + +static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, + const PyObject* sep, int bytes_per_sep_group, + const int return_bytes) +{ + PyObject *retval; + Py_UCS1* retbuf; + Py_ssize_t i, j, resultlen = 0; + Py_UCS1 sep_char = 0; + unsigned int abs_bytes_per_sep; + + if (sep) { + Py_ssize_t seplen = PyObject_Length((PyObject*)sep); + if (seplen < 0) { + return NULL; + } + if (seplen != 1) { + PyErr_SetString(PyExc_ValueError, "sep must be length 1."); + return NULL; + } + if (PyUnicode_Check(sep)) { + if (PyUnicode_READY(sep)) + return NULL; + if (PyUnicode_KIND(sep) != PyUnicode_1BYTE_KIND) { + PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); + return NULL; + } + sep_char = PyUnicode_READ_CHAR(sep, 0); + } else if (PyBytes_Check(sep)) { + sep_char = PyBytes_AS_STRING(sep)[0]; + } else { + PyErr_SetString(PyExc_TypeError, "sep must be str or bytes."); + return NULL; + } + if (sep_char > 127 && !return_bytes) { + PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); + return NULL; + } + } else { + bytes_per_sep_group = 0; + } + + assert(arglen >= 0); + abs_bytes_per_sep = abs(bytes_per_sep_group); + if (bytes_per_sep_group && arglen > 0) { + /* How many sep characters we'll be inserting. */ + resultlen = (arglen - 1) / abs_bytes_per_sep; + } + /* Bounds checking for our Py_ssize_t indices. */ + if (arglen >= PY_SSIZE_T_MAX / 2 - resultlen) { + return PyErr_NoMemory(); + } + resultlen += arglen * 2; + + if ((size_t)abs_bytes_per_sep >= (size_t)arglen) { + bytes_per_sep_group = 0; + abs_bytes_per_sep = 0; + } + + if (return_bytes) { + /* If _PyBytes_FromSize() were public we could avoid malloc+copy. */ + retbuf = (Py_UCS1*) PyMem_Malloc(resultlen); + if (!retbuf) + return PyErr_NoMemory(); + retval = NULL; /* silence a compiler warning, assigned later. */ + } else { + retval = PyUnicode_New(resultlen, 127); + if (!retval) + return NULL; + retbuf = PyUnicode_1BYTE_DATA(retval); + } + + /* Hexlify */ + for (i=j=0; i < arglen; ++i) { + assert(j < resultlen); + unsigned char c; + c = (argbuf[i] >> 4) & 0xf; + retbuf[j++] = Py_hexdigits[c]; + c = argbuf[i] & 0xf; + retbuf[j++] = Py_hexdigits[c]; + if (bytes_per_sep_group && i < arglen - 1) { + Py_ssize_t anchor; + anchor = (bytes_per_sep_group > 0) ? (arglen - 1 - i) : (i + 1); + if (anchor % abs_bytes_per_sep == 0) { + retbuf[j++] = sep_char; + } + } + } + assert(j == resultlen); + + if (return_bytes) { + retval = PyBytes_FromStringAndSize((const char *)retbuf, resultlen); + PyMem_Free(retbuf); + } +#ifdef Py_DEBUG + else { + assert(_PyUnicode_CheckConsistency(retval, 1)); + } +#endif + + return retval; +} + +PyObject * _Py_strhex(const char* argbuf, const Py_ssize_t arglen) +{ + return _Py_strhex_impl(argbuf, arglen, NULL, 0, 0); +} + +/* Same as above but returns a bytes() instead of str() to avoid the + * need to decode the str() when bytes are needed. */ +PyObject * _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) +{ + return _Py_strhex_impl(argbuf, arglen, NULL, 0, 1); +} + +/* These variants include support for a separator between every N bytes: */ + +PyObject * _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +{ + return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 0); +} + +/* Same as above but returns a bytes() instead of str() to avoid the + * need to decode the str() when bytes are needed. */ +PyObject * _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +{ + return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 1); +} diff --git a/python/Python/pystrtod.c b/python/Python/pystrtod.c new file mode 100755 index 0000000..4aa99d5 --- /dev/null +++ b/python/Python/pystrtod.c @@ -0,0 +1,1308 @@ +/* -*- Mode: C; c-file-style: "python" -*- */ + +#include +#include + +/* Case-insensitive string match used for nan and inf detection; t should be + lower-case. Returns 1 for a successful match, 0 otherwise. */ + +static int +case_insensitive_match(const char *s, const char *t) +{ + while(*t && Py_TOLOWER(*s) == *t) { + s++; + t++; + } + return *t ? 0 : 1; +} + +/* _Py_parse_inf_or_nan: Attempt to parse a string of the form "nan", "inf" or + "infinity", with an optional leading sign of "+" or "-". On success, + return the NaN or Infinity as a double and set *endptr to point just beyond + the successfully parsed portion of the string. On failure, return -1.0 and + set *endptr to point to the start of the string. */ + +#ifndef PY_NO_SHORT_FLOAT_REPR + +double +_Py_parse_inf_or_nan(const char *p, char **endptr) +{ + double retval; + const char *s; + int negate = 0; + + s = p; + if (*s == '-') { + negate = 1; + s++; + } + else if (*s == '+') { + s++; + } + if (case_insensitive_match(s, "inf")) { + s += 3; + if (case_insensitive_match(s, "inity")) + s += 5; + retval = _Py_dg_infinity(negate); + } + else if (case_insensitive_match(s, "nan")) { + s += 3; + retval = _Py_dg_stdnan(negate); + } + else { + s = p; + retval = -1.0; + } + *endptr = (char *)s; + return retval; +} + +#else + +double +_Py_parse_inf_or_nan(const char *p, char **endptr) +{ + double retval; + const char *s; + int negate = 0; + + s = p; + if (*s == '-') { + negate = 1; + s++; + } + else if (*s == '+') { + s++; + } + if (case_insensitive_match(s, "inf")) { + s += 3; + if (case_insensitive_match(s, "inity")) + s += 5; + retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL; + } +#ifdef Py_NAN + else if (case_insensitive_match(s, "nan")) { + s += 3; + retval = negate ? -Py_NAN : Py_NAN; + } +#endif + else { + s = p; + retval = -1.0; + } + *endptr = (char *)s; + return retval; +} + +#endif + +/** + * _PyOS_ascii_strtod: + * @nptr: the string to convert to a numeric value. + * @endptr: if non-%NULL, it returns the character after + * the last character used in the conversion. + * + * Converts a string to a #gdouble value. + * This function behaves like the standard strtod() function + * does in the C locale. It does this without actually + * changing the current locale, since that would not be + * thread-safe. + * + * This function is typically used when reading configuration + * files or other non-user input that should be locale independent. + * To handle input from the user you should normally use the + * locale-sensitive system strtod() function. + * + * If the correct value would cause overflow, plus or minus %HUGE_VAL + * is returned (according to the sign of the value), and %ERANGE is + * stored in %errno. If the correct value would cause underflow, + * zero is returned and %ERANGE is stored in %errno. + * If memory allocation fails, %ENOMEM is stored in %errno. + * + * This function resets %errno before calling strtod() so that + * you can reliably detect overflow and underflow. + * + * Return value: the #gdouble value. + **/ + +#ifndef PY_NO_SHORT_FLOAT_REPR + +static double +_PyOS_ascii_strtod(const char *nptr, char **endptr) +{ + double result; + _Py_SET_53BIT_PRECISION_HEADER; + + assert(nptr != NULL); + /* Set errno to zero, so that we can distinguish zero results + and underflows */ + errno = 0; + + _Py_SET_53BIT_PRECISION_START; + result = _Py_dg_strtod(nptr, endptr); + _Py_SET_53BIT_PRECISION_END; + + if (*endptr == nptr) + /* string might represent an inf or nan */ + result = _Py_parse_inf_or_nan(nptr, endptr); + + return result; + +} + +#else + +/* + Use system strtod; since strtod is locale aware, we may + have to first fix the decimal separator. + + Note that unlike _Py_dg_strtod, the system strtod may not always give + correctly rounded results. +*/ + +static double +_PyOS_ascii_strtod(const char *nptr, char **endptr) +{ + char *fail_pos; + double val; + struct lconv *locale_data; + const char *decimal_point; + size_t decimal_point_len; + const char *p, *decimal_point_pos; + const char *end = NULL; /* Silence gcc */ + const char *digits_pos = NULL; + int negate = 0; + + assert(nptr != NULL); + + fail_pos = NULL; + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + assert(decimal_point_len != 0); + + decimal_point_pos = NULL; + + /* Parse infinities and nans */ + val = _Py_parse_inf_or_nan(nptr, endptr); + if (*endptr != nptr) + return val; + + /* Set errno to zero, so that we can distinguish zero results + and underflows */ + errno = 0; + + /* We process the optional sign manually, then pass the remainder to + the system strtod. This ensures that the result of an underflow + has the correct sign. (bug #1725) */ + p = nptr; + /* Process leading sign, if present */ + if (*p == '-') { + negate = 1; + p++; + } + else if (*p == '+') { + p++; + } + + /* Some platform strtods accept hex floats; Python shouldn't (at the + moment), so we check explicitly for strings starting with '0x'. */ + if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) + goto invalid_string; + + /* Check that what's left begins with a digit or decimal point */ + if (!Py_ISDIGIT(*p) && *p != '.') + goto invalid_string; + + digits_pos = p; + if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + /* Look for a '.' in the input; if present, it'll need to be + swapped for the current locale's decimal point before we + call strtod. On the other hand, if we find the current + locale's decimal point then the input is invalid. */ + while (Py_ISDIGIT(*p)) + p++; + + if (*p == '.') + { + decimal_point_pos = p++; + + /* locate end of number */ + while (Py_ISDIGIT(*p)) + p++; + + if (*p == 'e' || *p == 'E') + p++; + if (*p == '+' || *p == '-') + p++; + while (Py_ISDIGIT(*p)) + p++; + end = p; + } + else if (strncmp(p, decimal_point, decimal_point_len) == 0) + /* Python bug #1417699 */ + goto invalid_string; + /* For the other cases, we need not convert the decimal + point */ + } + + if (decimal_point_pos) { + char *copy, *c; + /* Create a copy of the input, with the '.' converted to the + locale-specific decimal point */ + copy = (char *)PyMem_MALLOC(end - digits_pos + + 1 + decimal_point_len); + if (copy == NULL) { + *endptr = (char *)nptr; + errno = ENOMEM; + return val; + } + + c = copy; + memcpy(c, digits_pos, decimal_point_pos - digits_pos); + c += decimal_point_pos - digits_pos; + memcpy(c, decimal_point, decimal_point_len); + c += decimal_point_len; + memcpy(c, decimal_point_pos + 1, + end - (decimal_point_pos + 1)); + c += end - (decimal_point_pos + 1); + *c = 0; + + val = strtod(copy, &fail_pos); + + if (fail_pos) + { + if (fail_pos > decimal_point_pos) + fail_pos = (char *)digits_pos + + (fail_pos - copy) - + (decimal_point_len - 1); + else + fail_pos = (char *)digits_pos + + (fail_pos - copy); + } + + PyMem_FREE(copy); + + } + else { + val = strtod(digits_pos, &fail_pos); + } + + if (fail_pos == digits_pos) + goto invalid_string; + + if (negate && fail_pos != nptr) + val = -val; + *endptr = fail_pos; + + return val; + + invalid_string: + *endptr = (char*)nptr; + errno = EINVAL; + return -1.0; +} + +#endif + +/* PyOS_string_to_double converts a null-terminated byte string s (interpreted + as a string of ASCII characters) to a float. The string should not have + leading or trailing whitespace. The conversion is independent of the + current locale. + + If endptr is NULL, try to convert the whole string. Raise ValueError and + return -1.0 if the string is not a valid representation of a floating-point + number. + + If endptr is non-NULL, try to convert as much of the string as possible. + If no initial segment of the string is the valid representation of a + floating-point number then *endptr is set to point to the beginning of the + string, -1.0 is returned and again ValueError is raised. + + On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine), + if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python + exception is raised. Otherwise, overflow_exception should point to + a Python exception, this exception will be raised, -1.0 will be returned, + and *endptr will point just past the end of the converted value. + + If any other failure occurs (for example lack of memory), -1.0 is returned + and the appropriate Python exception will have been set. +*/ + +double +PyOS_string_to_double(const char *s, + char **endptr, + PyObject *overflow_exception) +{ + double x, result=-1.0; + char *fail_pos; + + errno = 0; + PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0) + x = _PyOS_ascii_strtod(s, &fail_pos); + PyFPE_END_PROTECT(x) + + if (errno == ENOMEM) { + PyErr_NoMemory(); + fail_pos = (char *)s; + } + else if (!endptr && (fail_pos == s || *fail_pos != '\0')) + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "'%.200s'", s); + else if (fail_pos == s) + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "'%.200s'", s); + else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception) + PyErr_Format(overflow_exception, + "value too large to convert to float: " + "'%.200s'", s); + else + result = x; + + if (endptr != NULL) + *endptr = fail_pos; + return result; +} + +/* Remove underscores that follow the underscore placement rule from + the string and then call the `innerfunc` function on the result. + It should return a new object or NULL on exception. + + `what` is used for the error message emitted when underscores are detected + that don't follow the rule. `arg` is an opaque pointer passed to the inner + function. + + This is used to implement underscore-agnostic conversion for floats + and complex numbers. +*/ +PyObject * +_Py_string_to_number_with_underscores( + const char *s, Py_ssize_t orig_len, const char *what, PyObject *obj, void *arg, + PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)) +{ + char prev; + const char *p, *last; + char *dup, *end; + PyObject *result; + + assert(s[orig_len] == '\0'); + + if (strchr(s, '_') == NULL) { + return innerfunc(s, orig_len, arg); + } + + dup = PyMem_Malloc(orig_len + 1); + if (dup == NULL) { + return PyErr_NoMemory(); + } + end = dup; + prev = '\0'; + last = s + orig_len; + for (p = s; *p; p++) { + if (*p == '_') { + /* Underscores are only allowed after digits. */ + if (!(prev >= '0' && prev <= '9')) { + goto error; + } + } + else { + *end++ = *p; + /* Underscores are only allowed before digits. */ + if (prev == '_' && !(*p >= '0' && *p <= '9')) { + goto error; + } + } + prev = *p; + } + /* Underscores are not allowed at the end. */ + if (prev == '_') { + goto error; + } + /* No embedded NULs allowed. */ + if (p != last) { + goto error; + } + *end = '\0'; + result = innerfunc(dup, end - dup, arg); + PyMem_Free(dup); + return result; + + error: + PyMem_Free(dup); + PyErr_Format(PyExc_ValueError, + "could not convert string to %s: " + "%R", what, obj); + return NULL; +} + +#ifdef PY_NO_SHORT_FLOAT_REPR + +/* Given a string that may have a decimal point in the current + locale, change it back to a dot. Since the string cannot get + longer, no need for a maximum buffer size parameter. */ +Py_LOCAL_INLINE(void) +change_decimal_from_locale_to_dot(char* buffer) +{ + struct lconv *locale_data = localeconv(); + const char *decimal_point = locale_data->decimal_point; + + if (decimal_point[0] != '.' || decimal_point[1] != 0) { + size_t decimal_point_len = strlen(decimal_point); + + if (*buffer == '+' || *buffer == '-') + buffer++; + while (Py_ISDIGIT(*buffer)) + buffer++; + if (strncmp(buffer, decimal_point, decimal_point_len) == 0) { + *buffer = '.'; + buffer++; + if (decimal_point_len > 1) { + /* buffer needs to get smaller */ + size_t rest_len = strlen(buffer + + (decimal_point_len - 1)); + memmove(buffer, + buffer + (decimal_point_len - 1), + rest_len); + buffer[rest_len] = 0; + } + } + } +} + + +/* From the C99 standard, section 7.19.6: +The exponent always contains at least two digits, and only as many more digits +as necessary to represent the exponent. +*/ +#define MIN_EXPONENT_DIGITS 2 + +/* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS + in length. */ +Py_LOCAL_INLINE(void) +ensure_minimum_exponent_length(char* buffer, size_t buf_size) +{ + char *p = strpbrk(buffer, "eE"); + if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { + char *start = p + 2; + int exponent_digit_cnt = 0; + int leading_zero_cnt = 0; + int in_leading_zeros = 1; + int significant_digit_cnt; + + /* Skip over the exponent and the sign. */ + p += 2; + + /* Find the end of the exponent, keeping track of leading + zeros. */ + while (*p && Py_ISDIGIT(*p)) { + if (in_leading_zeros && *p == '0') + ++leading_zero_cnt; + if (*p != '0') + in_leading_zeros = 0; + ++p; + ++exponent_digit_cnt; + } + + significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt; + if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) { + /* If there are 2 exactly digits, we're done, + regardless of what they contain */ + } + else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) { + int extra_zeros_cnt; + + /* There are more than 2 digits in the exponent. See + if we can delete some of the leading zeros */ + if (significant_digit_cnt < MIN_EXPONENT_DIGITS) + significant_digit_cnt = MIN_EXPONENT_DIGITS; + extra_zeros_cnt = exponent_digit_cnt - + significant_digit_cnt; + + /* Delete extra_zeros_cnt worth of characters from the + front of the exponent */ + assert(extra_zeros_cnt >= 0); + + /* Add one to significant_digit_cnt to copy the + trailing 0 byte, thus setting the length */ + memmove(start, + start + extra_zeros_cnt, + significant_digit_cnt + 1); + } + else { + /* If there are fewer than 2 digits, add zeros + until there are 2, if there's enough room */ + int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt; + if (start + zeros + exponent_digit_cnt + 1 + < buffer + buf_size) { + memmove(start + zeros, start, + exponent_digit_cnt + 1); + memset(start, '0', zeros); + } + } + } +} + +/* Remove trailing zeros after the decimal point from a numeric string; also + remove the decimal point if all digits following it are zero. The numeric + string must end in '\0', and should not have any leading or trailing + whitespace. Assumes that the decimal point is '.'. */ +Py_LOCAL_INLINE(void) +remove_trailing_zeros(char *buffer) +{ + char *old_fraction_end, *new_fraction_end, *end, *p; + + p = buffer; + if (*p == '-' || *p == '+') + /* Skip leading sign, if present */ + ++p; + while (Py_ISDIGIT(*p)) + ++p; + + /* if there's no decimal point there's nothing to do */ + if (*p++ != '.') + return; + + /* scan any digits after the point */ + while (Py_ISDIGIT(*p)) + ++p; + old_fraction_end = p; + + /* scan up to ending '\0' */ + while (*p != '\0') + p++; + /* +1 to make sure that we move the null byte as well */ + end = p+1; + + /* scan back from fraction_end, looking for removable zeros */ + p = old_fraction_end; + while (*(p-1) == '0') + --p; + /* and remove point if we've got that far */ + if (*(p-1) == '.') + --p; + new_fraction_end = p; + + memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); +} + +/* Ensure that buffer has a decimal point in it. The decimal point will not + be in the current locale, it will always be '.'. Don't add a decimal point + if an exponent is present. Also, convert to exponential notation where + adding a '.0' would produce too many significant digits (see issue 5864). + + Returns a pointer to the fixed buffer, or NULL on failure. +*/ +Py_LOCAL_INLINE(char *) +ensure_decimal_point(char* buffer, size_t buf_size, int precision) +{ + int digit_count, insert_count = 0, convert_to_exp = 0; + const char *chars_to_insert; + char *digits_start; + + /* search for the first non-digit character */ + char *p = buffer; + if (*p == '-' || *p == '+') + /* Skip leading sign, if present. I think this could only + ever be '-', but it can't hurt to check for both. */ + ++p; + digits_start = p; + while (*p && Py_ISDIGIT(*p)) + ++p; + digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int); + + if (*p == '.') { + if (Py_ISDIGIT(*(p+1))) { + /* Nothing to do, we already have a decimal + point and a digit after it */ + } + else { + /* We have a decimal point, but no following + digit. Insert a zero after the decimal. */ + /* can't ever get here via PyOS_double_to_string */ + assert(precision == -1); + ++p; + chars_to_insert = "0"; + insert_count = 1; + } + } + else if (!(*p == 'e' || *p == 'E')) { + /* Don't add ".0" if we have an exponent. */ + if (digit_count == precision) { + /* issue 5864: don't add a trailing .0 in the case + where the '%g'-formatted result already has as many + significant digits as were requested. Switch to + exponential notation instead. */ + convert_to_exp = 1; + /* no exponent, no point, and we shouldn't land here + for infs and nans, so we must be at the end of the + string. */ + assert(*p == '\0'); + } + else { + assert(precision == -1 || digit_count < precision); + chars_to_insert = ".0"; + insert_count = 2; + } + } + if (insert_count) { + size_t buf_len = strlen(buffer); + if (buf_len + insert_count + 1 >= buf_size) { + /* If there is not enough room in the buffer + for the additional text, just skip it. It's + not worth generating an error over. */ + } + else { + memmove(p + insert_count, p, + buffer + strlen(buffer) - p + 1); + memcpy(p, chars_to_insert, insert_count); + } + } + if (convert_to_exp) { + int written; + size_t buf_avail; + p = digits_start; + /* insert decimal point */ + assert(digit_count >= 1); + memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */ + p[1] = '.'; + p += digit_count+1; + assert(p <= buf_size+buffer); + buf_avail = buf_size+buffer-p; + if (buf_avail == 0) + return NULL; + /* Add exponent. It's okay to use lower case 'e': we only + arrive here as a result of using the empty format code or + repr/str builtins and those never want an upper case 'E' */ + written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1); + if (!(0 <= written && + written < Py_SAFE_DOWNCAST(buf_avail, size_t, int))) + /* output truncated, or something else bad happened */ + return NULL; + remove_trailing_zeros(buffer); + } + return buffer; +} + +/* see FORMATBUFLEN in unicodeobject.c */ +#define FLOAT_FORMATBUFLEN 120 + +/** + * _PyOS_ascii_formatd: + * @buffer: A buffer to place the resulting string in + * @buf_size: The length of the buffer. + * @format: The printf()-style format to use for the + * code to use for converting. + * @d: The #gdouble to convert + * @precision: The precision to use when formatting. + * + * Converts a #gdouble to a string, using the '.' as + * decimal point. To format the number you pass in + * a printf()-style format string. Allowed conversion + * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'. + * + * 'Z' is the same as 'g', except it always has a decimal and + * at least one digit after the decimal. + * + * Return value: The pointer to the buffer with the converted string. + * On failure returns NULL but does not set any Python exception. + **/ +static char * +_PyOS_ascii_formatd(char *buffer, + size_t buf_size, + const char *format, + double d, + int precision) +{ + char format_char; + size_t format_len = strlen(format); + + /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but + also with at least one character past the decimal. */ + char tmp_format[FLOAT_FORMATBUFLEN]; + + /* The last character in the format string must be the format char */ + format_char = format[format_len - 1]; + + if (format[0] != '%') + return NULL; + + /* I'm not sure why this test is here. It's ensuring that the format + string after the first character doesn't have a single quote, a + lowercase l, or a percent. This is the reverse of the commented-out + test about 10 lines ago. */ + if (strpbrk(format + 1, "'l%")) + return NULL; + + /* Also curious about this function is that it accepts format strings + like "%xg", which are invalid for floats. In general, the + interface to this function is not very good, but changing it is + difficult because it's a public API. */ + + if (!(format_char == 'e' || format_char == 'E' || + format_char == 'f' || format_char == 'F' || + format_char == 'g' || format_char == 'G' || + format_char == 'Z')) + return NULL; + + /* Map 'Z' format_char to 'g', by copying the format string and + replacing the final char with a 'g' */ + if (format_char == 'Z') { + if (format_len + 1 >= sizeof(tmp_format)) { + /* The format won't fit in our copy. Error out. In + practice, this will never happen and will be + detected by returning NULL */ + return NULL; + } + strcpy(tmp_format, format); + tmp_format[format_len - 1] = 'g'; + format = tmp_format; + } + + + /* Have PyOS_snprintf do the hard work */ + PyOS_snprintf(buffer, buf_size, format, d); + + /* Do various fixups on the return string */ + + /* Get the current locale, and find the decimal point string. + Convert that string back to a dot. */ + change_decimal_from_locale_to_dot(buffer); + + /* If an exponent exists, ensure that the exponent is at least + MIN_EXPONENT_DIGITS digits, providing the buffer is large enough + for the extra zeros. Also, if there are more than + MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get + back to MIN_EXPONENT_DIGITS */ + ensure_minimum_exponent_length(buffer, buf_size); + + /* If format_char is 'Z', make sure we have at least one character + after the decimal point (and make sure we have a decimal point); + also switch to exponential notation in some edge cases where the + extra character would produce more significant digits that we + really want. */ + if (format_char == 'Z') + buffer = ensure_decimal_point(buffer, buf_size, precision); + + return buffer; +} + +/* The fallback code to use if _Py_dg_dtoa is not available. */ + +char * PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type) +{ + char format[32]; + Py_ssize_t bufsize; + char *buf; + int t, exp; + int upper = 0; + + /* Validate format_code, and map upper and lower case */ + switch (format_code) { + case 'e': /* exponent */ + case 'f': /* fixed */ + case 'g': /* general */ + break; + case 'E': + upper = 1; + format_code = 'e'; + break; + case 'F': + upper = 1; + format_code = 'f'; + break; + case 'G': + upper = 1; + format_code = 'g'; + break; + case 'r': /* repr format */ + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + /* The repr() precision (17 significant decimal digits) is the + minimal number that is guaranteed to have enough precision + so that if the number is read back in the exact same binary + value is recreated. This is true for IEEE floating point + by design, and also happens to work for all other modern + hardware. */ + precision = 17; + format_code = 'g'; + break; + default: + PyErr_BadInternalCall(); + return NULL; + } + + /* Here's a quick-and-dirty calculation to figure out how big a buffer + we need. In general, for a finite float we need: + + 1 byte for each digit of the decimal significand, and + + 1 for a possible sign + 1 for a possible decimal point + 2 for a possible [eE][+-] + 1 for each digit of the exponent; if we allow 19 digits + total then we're safe up to exponents of 2**63. + 1 for the trailing nul byte + + This gives a total of 24 + the number of digits in the significand, + and the number of digits in the significand is: + + for 'g' format: at most precision, except possibly + when precision == 0, when it's 1. + for 'e' format: precision+1 + for 'f' format: precision digits after the point, at least 1 + before. To figure out how many digits appear before the point + we have to examine the size of the number. If fabs(val) < 1.0 + then there will be only one digit before the point. If + fabs(val) >= 1.0, then there are at most + + 1+floor(log10(ceiling(fabs(val)))) + + digits before the point (where the 'ceiling' allows for the + possibility that the rounding rounds the integer part of val + up). A safe upper bound for the above quantity is + 1+floor(exp/3), where exp is the unique integer such that 0.5 + <= fabs(val)/2**exp < 1.0. This exp can be obtained from + frexp. + + So we allow room for precision+1 digits for all formats, plus an + extra floor(exp/3) digits for 'f' format. + + */ + + if (Py_IS_NAN(val) || Py_IS_INFINITY(val)) + /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */ + bufsize = 5; + else { + bufsize = 25 + precision; + if (format_code == 'f' && fabs(val) >= 1.0) { + frexp(val, &exp); + bufsize += exp/3; + } + } + + buf = PyMem_Malloc(bufsize); + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + + /* Handle nan and inf. */ + if (Py_IS_NAN(val)) { + strcpy(buf, "nan"); + t = Py_DTST_NAN; + } else if (Py_IS_INFINITY(val)) { + if (copysign(1., val) == 1.) + strcpy(buf, "inf"); + else + strcpy(buf, "-inf"); + t = Py_DTST_INFINITE; + } else { + t = Py_DTST_FINITE; + if (flags & Py_DTSF_ADD_DOT_0) + format_code = 'Z'; + + PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", + (flags & Py_DTSF_ALT ? "#" : ""), precision, + format_code); + _PyOS_ascii_formatd(buf, bufsize, format, val, precision); + } + + /* Add sign when requested. It's convenient (esp. when formatting + complex numbers) to include a sign even for inf and nan. */ + if (flags & Py_DTSF_SIGN && buf[0] != '-') { + size_t len = strlen(buf); + /* the bufsize calculations above should ensure that we've got + space to add a sign */ + assert((size_t)bufsize >= len+2); + memmove(buf+1, buf, len+1); + buf[0] = '+'; + } + if (upper) { + /* Convert to upper case. */ + char *p1; + for (p1 = buf; *p1; p1++) + *p1 = Py_TOUPPER(*p1); + } + + if (type) + *type = t; + return buf; +} + +#else + +/* _Py_dg_dtoa is available. */ + +/* I'm using a lookup table here so that I don't have to invent a non-locale + specific way to convert to uppercase */ +#define OFS_INF 0 +#define OFS_NAN 1 +#define OFS_E 2 + +/* The lengths of these are known to the code below, so don't change them */ +static const char * const lc_float_strings[] = { + "inf", + "nan", + "e", +}; +static const char * const uc_float_strings[] = { + "INF", + "NAN", + "E", +}; + + +/* Convert a double d to a string, and return a PyMem_Malloc'd block of + memory contain the resulting string. + + Arguments: + d is the double to be converted + format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g' + correspond to '%e', '%f' and '%g'; 'r' corresponds to repr. + mode is one of '0', '2' or '3', and is completely determined by + format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0. + precision is the desired precision + always_add_sign is nonzero if a '+' sign should be included for positive + numbers + add_dot_0_if_integer is nonzero if integers in non-exponential form + should have ".0" added. Only applies to format codes 'r' and 'g'. + use_alt_formatting is nonzero if alternative formatting should be + used. Only applies to format codes 'e', 'f' and 'g'. For code 'g', + at most one of use_alt_formatting and add_dot_0_if_integer should + be nonzero. + type, if non-NULL, will be set to one of these constants to identify + the type of the 'd' argument: + Py_DTST_FINITE + Py_DTST_INFINITE + Py_DTST_NAN + + Returns a PyMem_Malloc'd block of memory containing the resulting string, + or NULL on error. If NULL is returned, the Python error has been set. + */ + +static char * +format_float_short(double d, char format_code, + int mode, int precision, + int always_add_sign, int add_dot_0_if_integer, + int use_alt_formatting, const char * const *float_strings, + int *type) +{ + char *buf = NULL; + char *p = NULL; + Py_ssize_t bufsize = 0; + char *digits, *digits_end; + int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; + Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end; + _Py_SET_53BIT_PRECISION_HEADER; + + /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). + Must be matched by a call to _Py_dg_freedtoa. */ + _Py_SET_53BIT_PRECISION_START; + digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign, + &digits_end); + _Py_SET_53BIT_PRECISION_END; + + decpt = (Py_ssize_t)decpt_as_int; + if (digits == NULL) { + /* The only failure mode is no memory. */ + PyErr_NoMemory(); + goto exit; + } + assert(digits_end != NULL && digits_end >= digits); + digits_len = digits_end - digits; + + if (digits_len && !Py_ISDIGIT(digits[0])) { + /* Infinities and nans here; adapt Gay's output, + so convert Infinity to inf and NaN to nan, and + ignore sign of nan. Then return. */ + + /* ignore the actual sign of a nan */ + if (digits[0] == 'n' || digits[0] == 'N') + sign = 0; + + /* We only need 5 bytes to hold the result "+inf\0" . */ + bufsize = 5; /* Used later in an assert. */ + buf = (char *)PyMem_Malloc(bufsize); + if (buf == NULL) { + PyErr_NoMemory(); + goto exit; + } + p = buf; + + if (sign == 1) { + *p++ = '-'; + } + else if (always_add_sign) { + *p++ = '+'; + } + if (digits[0] == 'i' || digits[0] == 'I') { + strncpy(p, float_strings[OFS_INF], 3); + p += 3; + + if (type) + *type = Py_DTST_INFINITE; + } + else if (digits[0] == 'n' || digits[0] == 'N') { + strncpy(p, float_strings[OFS_NAN], 3); + p += 3; + + if (type) + *type = Py_DTST_NAN; + } + else { + /* shouldn't get here: Gay's code should always return + something starting with a digit, an 'I', or 'N' */ + Py_UNREACHABLE(); + } + goto exit; + } + + /* The result must be finite (not inf or nan). */ + if (type) + *type = Py_DTST_FINITE; + + + /* We got digits back, format them. We may need to pad 'digits' + either on the left or right (or both) with extra zeros, so in + general the resulting string has the form + + [][] + + where either of the pieces could be empty, and there's a + decimal point that could appear either in or in the + leading or trailing . + + Imagine an infinite 'virtual' string vdigits, consisting of the + string 'digits' (starting at index 0) padded on both the left and + right with infinite strings of zeros. We want to output a slice + + vdigits[vdigits_start : vdigits_end] + + of this virtual string. Thus if vdigits_start < 0 then we'll end + up producing some leading zeros; if vdigits_end > digits_len there + will be trailing zeros in the output. The next section of code + determines whether to use an exponent or not, figures out the + position 'decpt' of the decimal point, and computes 'vdigits_start' + and 'vdigits_end'. */ + vdigits_end = digits_len; + switch (format_code) { + case 'e': + use_exp = 1; + vdigits_end = precision; + break; + case 'f': + vdigits_end = decpt + precision; + break; + case 'g': + if (decpt <= -4 || decpt > + (add_dot_0_if_integer ? precision-1 : precision)) + use_exp = 1; + if (use_alt_formatting) + vdigits_end = precision; + break; + case 'r': + /* convert to exponential format at 1e16. We used to convert + at 1e17, but that gives odd-looking results for some values + when a 16-digit 'shortest' repr is padded with bogus zeros. + For example, repr(2e16+8) would give 20000000000000010.0; + the true value is 20000000000000008.0. */ + if (decpt <= -4 || decpt > 16) + use_exp = 1; + break; + default: + PyErr_BadInternalCall(); + goto exit; + } + + /* if using an exponent, reset decimal point position to 1 and adjust + exponent accordingly.*/ + if (use_exp) { + exp = (int)decpt - 1; + decpt = 1; + } + /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start < + decpt < vdigits_end if add_dot_0_if_integer and no exponent */ + vdigits_start = decpt <= 0 ? decpt-1 : 0; + if (!use_exp && add_dot_0_if_integer) + vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1; + else + vdigits_end = vdigits_end > decpt ? vdigits_end : decpt; + + /* double check inequalities */ + assert(vdigits_start <= 0 && + 0 <= digits_len && + digits_len <= vdigits_end); + /* decimal point should be in (vdigits_start, vdigits_end] */ + assert(vdigits_start < decpt && decpt <= vdigits_end); + + /* Compute an upper bound how much memory we need. This might be a few + chars too long, but no big deal. */ + bufsize = + /* sign, decimal point and trailing 0 byte */ + 3 + + + /* total digit count (including zero padding on both sides) */ + (vdigits_end - vdigits_start) + + + /* exponent "e+100", max 3 numerical digits */ + (use_exp ? 5 : 0); + + /* Now allocate the memory and initialize p to point to the start of + it. */ + buf = (char *)PyMem_Malloc(bufsize); + if (buf == NULL) { + PyErr_NoMemory(); + goto exit; + } + p = buf; + + /* Add a negative sign if negative, and a plus sign if non-negative + and always_add_sign is true. */ + if (sign == 1) + *p++ = '-'; + else if (always_add_sign) + *p++ = '+'; + + /* note that exactly one of the three 'if' conditions is true, + so we include exactly one decimal point */ + /* Zero padding on left of digit string */ + if (decpt <= 0) { + memset(p, '0', decpt-vdigits_start); + p += decpt - vdigits_start; + *p++ = '.'; + memset(p, '0', 0-decpt); + p += 0-decpt; + } + else { + memset(p, '0', 0-vdigits_start); + p += 0 - vdigits_start; + } + + /* Digits, with included decimal point */ + if (0 < decpt && decpt <= digits_len) { + strncpy(p, digits, decpt-0); + p += decpt-0; + *p++ = '.'; + strncpy(p, digits+decpt, digits_len-decpt); + p += digits_len-decpt; + } + else { + strncpy(p, digits, digits_len); + p += digits_len; + } + + /* And zeros on the right */ + if (digits_len < decpt) { + memset(p, '0', decpt-digits_len); + p += decpt-digits_len; + *p++ = '.'; + memset(p, '0', vdigits_end-decpt); + p += vdigits_end-decpt; + } + else { + memset(p, '0', vdigits_end-digits_len); + p += vdigits_end-digits_len; + } + + /* Delete a trailing decimal pt unless using alternative formatting. */ + if (p[-1] == '.' && !use_alt_formatting) + p--; + + /* Now that we've done zero padding, add an exponent if needed. */ + if (use_exp) { + *p++ = float_strings[OFS_E][0]; + exp_len = sprintf(p, "%+.02d", exp); + p += exp_len; + } + exit: + if (buf) { + *p = '\0'; + /* It's too late if this fails, as we've already stepped on + memory that isn't ours. But it's an okay debugging test. */ + assert(p-buf < bufsize); + } + if (digits) + _Py_dg_freedtoa(digits); + + return buf; +} + + +char * PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type) +{ + const char * const *float_strings = lc_float_strings; + int mode; + + /* Validate format_code, and map upper and lower case. Compute the + mode and make any adjustments as needed. */ + switch (format_code) { + /* exponent */ + case 'E': + float_strings = uc_float_strings; + format_code = 'e'; + /* Fall through. */ + case 'e': + mode = 2; + precision++; + break; + + /* fixed */ + case 'F': + float_strings = uc_float_strings; + format_code = 'f'; + /* Fall through. */ + case 'f': + mode = 3; + break; + + /* general */ + case 'G': + float_strings = uc_float_strings; + format_code = 'g'; + /* Fall through. */ + case 'g': + mode = 2; + /* precision 0 makes no sense for 'g' format; interpret as 1 */ + if (precision == 0) + precision = 1; + break; + + /* repr format */ + case 'r': + mode = 0; + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + break; + + default: + PyErr_BadInternalCall(); + return NULL; + } + + return format_float_short(val, format_code, mode, precision, + flags & Py_DTSF_SIGN, + flags & Py_DTSF_ADD_DOT_0, + flags & Py_DTSF_ALT, + float_strings, type); +} +#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */ diff --git a/python/Python/pythonrun.c b/python/Python/pythonrun.c new file mode 100755 index 0000000..c55e767 --- /dev/null +++ b/python/Python/pythonrun.c @@ -0,0 +1,1816 @@ + +/* Top level execution of Python code (including in __main__) */ + +/* To help control the interfaces between the startup, execution and + * shutdown code, the phases are split across separate modules (boostrap, + * pythonrun, shutdown) + */ + +/* TODO: Cull includes following phase split */ + +#include "Python.h" + +#include "Python-ast.h" +#undef Yield /* undefine macro conflicting with */ +#include "pycore_pyerrors.h" +#include "pycore_pylifecycle.h" +#include "pycore_pystate.h" +#include "grammar.h" +#include "node.h" +#include "token.h" +#include "parsetok.h" +#include "errcode.h" +#include "code.h" +#include "symtable.h" +#include "ast.h" +#include "marshal.h" +#include "osdefs.h" +#include + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef MS_WINDOWS +#include "malloc.h" /* for alloca */ +#endif + +#ifdef MS_WINDOWS +#undef BYTE +#include "windows.h" +#endif + +_Py_IDENTIFIER(builtins); +_Py_IDENTIFIER(excepthook); +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(last_traceback); +_Py_IDENTIFIER(last_type); +_Py_IDENTIFIER(last_value); +_Py_IDENTIFIER(ps1); +_Py_IDENTIFIER(ps2); +_Py_IDENTIFIER(stdin); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); +_Py_static_string(PyId_string, ""); + +#ifdef __cplusplus +extern "C" { +#endif + +extern grammar _PyParser_Grammar; /* From graminit.c */ + +/* Forward */ +static void flush_io(void); +static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, + PyCompilerFlags *, PyArena *); +static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *, + PyCompilerFlags *); +static void err_input(perrdetail *); +static void err_free(perrdetail *); +static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *); +static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start, + PyObject *globals, PyObject *locals, int closeit, + PyCompilerFlags *flags); + + +/* Parse input from a file and execute it */ +int +PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, + PyCompilerFlags *flags) +{ + if (filename == NULL) + filename = "???"; + if (Py_FdIsInteractive(fp, filename)) { + int err = PyRun_InteractiveLoopFlags(fp, filename, flags); + if (closeit) + fclose(fp); + return err; + } + else + return PyRun_SimpleFileExFlags(fp, filename, closeit, flags); +} + +int +PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) +{ + PyObject *filename, *v; + int ret, err; + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; + int nomem_count = 0; +#ifdef Py_REF_DEBUG + int show_ref_count = _PyInterpreterState_Get()->config.show_ref_count; +#endif + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + + if (flags == NULL) { + flags = &local_flags; + } + v = _PySys_GetObjectId(&PyId_ps1); + if (v == NULL) { + _PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> ")); + Py_XDECREF(v); + } + v = _PySys_GetObjectId(&PyId_ps2); + if (v == NULL) { + _PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... ")); + Py_XDECREF(v); + } + err = 0; + do { + ret = PyRun_InteractiveOneObjectEx(fp, filename, flags); + if (ret == -1 && PyErr_Occurred()) { + /* Prevent an endless loop after multiple consecutive MemoryErrors + * while still allowing an interactive command to fail with a + * MemoryError. */ + if (PyErr_ExceptionMatches(PyExc_MemoryError)) { + if (++nomem_count > 16) { + PyErr_Clear(); + err = -1; + break; + } + } else { + nomem_count = 0; + } + PyErr_Print(); + flush_io(); + } else { + nomem_count = 0; + } +#ifdef Py_REF_DEBUG + if (show_ref_count) { + _PyDebug_PrintTotalRefs(); + } +#endif + } while (ret != E_EOF); + Py_DECREF(filename); + return err; +} + +/* compute parser flags based on compiler flags */ +static int PARSER_FLAGS(PyCompilerFlags *flags) +{ + int parser_flags = 0; + if (!flags) + return 0; + if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT) + parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; + if (flags->cf_flags & PyCF_IGNORE_COOKIE) + parser_flags |= PyPARSE_IGNORE_COOKIE; + if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) + parser_flags |= PyPARSE_BARRY_AS_BDFL; + if (flags->cf_flags & PyCF_TYPE_COMMENTS) + parser_flags |= PyPARSE_TYPE_COMMENTS; + return parser_flags; +} + +#if 0 +/* Keep an example of flags with future keyword support. */ +#define PARSER_FLAGS(flags) \ + ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \ + PyPARSE_DONT_IMPLY_DEDENT : 0) \ + | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \ + PyPARSE_WITH_IS_KEYWORD : 0)) : 0) +#endif + +/* A PyRun_InteractiveOneObject() auxiliary function that does not print the + * error on failure. */ +static int +PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, + PyCompilerFlags *flags) +{ + PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name; + mod_ty mod; + PyArena *arena; + const char *ps1 = "", *ps2 = "", *enc = NULL; + int errcode = 0; + _Py_IDENTIFIER(encoding); + _Py_IDENTIFIER(__main__); + + mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */ + if (mod_name == NULL) { + return -1; + } + + if (fp == stdin) { + /* Fetch encoding from sys.stdin if possible. */ + v = _PySys_GetObjectId(&PyId_stdin); + if (v && v != Py_None) { + oenc = _PyObject_GetAttrId(v, &PyId_encoding); + if (oenc) + enc = PyUnicode_AsUTF8(oenc); + if (!enc) + PyErr_Clear(); + } + } + v = _PySys_GetObjectId(&PyId_ps1); + if (v != NULL) { + v = PyObject_Str(v); + if (v == NULL) + PyErr_Clear(); + else if (PyUnicode_Check(v)) { + ps1 = PyUnicode_AsUTF8(v); + if (ps1 == NULL) { + PyErr_Clear(); + ps1 = ""; + } + } + } + w = _PySys_GetObjectId(&PyId_ps2); + if (w != NULL) { + w = PyObject_Str(w); + if (w == NULL) + PyErr_Clear(); + else if (PyUnicode_Check(w)) { + ps2 = PyUnicode_AsUTF8(w); + if (ps2 == NULL) { + PyErr_Clear(); + ps2 = ""; + } + } + } + arena = PyArena_New(); + if (arena == NULL) { + Py_XDECREF(v); + Py_XDECREF(w); + Py_XDECREF(oenc); + return -1; + } + mod = PyParser_ASTFromFileObject(fp, filename, enc, + Py_single_input, ps1, ps2, + flags, &errcode, arena); + Py_XDECREF(v); + Py_XDECREF(w); + Py_XDECREF(oenc); + if (mod == NULL) { + PyArena_Free(arena); + if (errcode == E_EOF) { + PyErr_Clear(); + return E_EOF; + } + return -1; + } + m = PyImport_AddModuleObject(mod_name); + if (m == NULL) { + PyArena_Free(arena); + return -1; + } + d = PyModule_GetDict(m); + v = run_mod(mod, filename, d, d, flags, arena); + PyArena_Free(arena); + if (v == NULL) { + return -1; + } + Py_DECREF(v); + flush_io(); + return 0; +} + +int +PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) +{ + int res; + + res = PyRun_InteractiveOneObjectEx(fp, filename, flags); + if (res == -1) { + PyErr_Print(); + flush_io(); + } + return res; +} + +int +PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags) +{ + PyObject *filename; + int res; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + PyErr_Print(); + return -1; + } + res = PyRun_InteractiveOneObject(fp, filename, flags); + Py_DECREF(filename); + return res; +} + + +/* Check whether a file maybe a pyc file: Look at the extension, + the file type, and, if we may close it, at the first few bytes. */ + +static int +maybe_pyc_file(FILE *fp, PyObject *filename, int closeit) +{ + PyObject *ext = PyUnicode_FromString(".pyc"); + if (ext == NULL) { + return -1; + } + Py_ssize_t endswith = PyUnicode_Tailmatch(filename, ext, 0, PY_SSIZE_T_MAX, +1); + Py_DECREF(ext); + if (endswith) { + return 1; + } + + /* Only look into the file if we are allowed to close it, since + it then should also be seekable. */ + if (!closeit) { + return 0; + } + + /* Read only two bytes of the magic. If the file was opened in + text mode, the bytes 3 and 4 of the magic (\r\n) might not + be read as they are on disk. */ + unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; + unsigned char buf[2]; + /* Mess: In case of -x, the stream is NOT at its start now, + and ungetc() was used to push back the first newline, + which makes the current stream position formally undefined, + and a x-platform nightmare. + Unfortunately, we have no direct way to know whether -x + was specified. So we use a terrible hack: if the current + stream position is not 0, we assume -x was specified, and + give up. Bug 132850 on SourceForge spells out the + hopelessness of trying anything else (fseek and ftell + don't work predictably x-platform for text-mode files). + */ + int ispyc = 0; + if (ftell(fp) == 0) { + if (fread(buf, 1, 2, fp) == 2 && + ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic) + ispyc = 1; + rewind(fp); + } + return ispyc; +} + + +static int +set_main_loader(PyObject *d, PyObject *filename, const char *loader_name) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + PyObject *bootstrap = PyObject_GetAttrString(interp->importlib, + "_bootstrap_external"); + if (bootstrap == NULL) { + return -1; + } + + PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name); + Py_DECREF(bootstrap); + if (loader_type == NULL) { + return -1; + } + + PyObject *loader = PyObject_CallFunction(loader_type, + "sO", "__main__", filename); + Py_DECREF(loader_type); + if (loader == NULL) { + return -1; + } + + if (PyDict_SetItemString(d, "__loader__", loader) < 0) { + Py_DECREF(loader); + return -1; + } + Py_DECREF(loader); + return 0; +} + + +static int +pyrun_simple_file(FILE *fp, PyObject *filename, int closeit, + PyCompilerFlags *flags) +{ + PyObject *m, *d, *v; + int set_file_name = 0, ret = -1; + + m = PyImport_AddModule("__main__"); + if (m == NULL) + return -1; + Py_INCREF(m); + d = PyModule_GetDict(m); + if (PyDict_GetItemString(d, "__file__") == NULL) { + if (PyDict_SetItemString(d, "__file__", filename) < 0) { + goto done; + } + if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) { + goto done; + } + set_file_name = 1; + } + + int pyc = maybe_pyc_file(fp, filename, closeit); + if (pyc < 0) { + goto done; + } + + if (pyc) { + FILE *pyc_fp; + /* Try to run a pyc file. First, re-open in binary */ + if (closeit) { + fclose(fp); + } + + pyc_fp = _Py_fopen_obj(filename, "rb"); + if (pyc_fp == NULL) { + fprintf(stderr, "python: Can't reopen .pyc file\n"); + goto done; + } + + if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { + fprintf(stderr, "python: failed to set __main__.__loader__\n"); + ret = -1; + fclose(pyc_fp); + goto done; + } + v = run_pyc_file(pyc_fp, d, d, flags); + } else { + /* When running from stdin, leave __main__.__loader__ alone */ + if (PyUnicode_CompareWithASCIIString(filename, "") != 0 && + set_main_loader(d, filename, "SourceFileLoader") < 0) { + fprintf(stderr, "python: failed to set __main__.__loader__\n"); + ret = -1; + goto done; + } + v = pyrun_file(fp, filename, Py_file_input, d, d, + closeit, flags); + } + flush_io(); + if (v == NULL) { + Py_CLEAR(m); + PyErr_Print(); + goto done; + } + Py_DECREF(v); + ret = 0; + done: + if (set_file_name) { + if (PyDict_DelItemString(d, "__file__")) { + PyErr_Clear(); + } + if (PyDict_DelItemString(d, "__cached__")) { + PyErr_Clear(); + } + } + Py_XDECREF(m); + return ret; +} + + +int +PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, + PyCompilerFlags *flags) +{ + PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); + if (filename_obj == NULL) { + return -1; + } + int res = pyrun_simple_file(fp, filename_obj, closeit, flags); + Py_DECREF(filename_obj); + return res; +} + + +int +PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) +{ + PyObject *m, *d, *v; + m = PyImport_AddModule("__main__"); + if (m == NULL) + return -1; + d = PyModule_GetDict(m); + v = PyRun_StringFlags(command, Py_file_input, d, d, flags); + if (v == NULL) { + PyErr_Print(); + return -1; + } + Py_DECREF(v); + return 0; +} + +static int +parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, + int *lineno, int *offset, PyObject **text) +{ + int hold; + PyObject *v; + _Py_IDENTIFIER(msg); + _Py_IDENTIFIER(filename); + _Py_IDENTIFIER(lineno); + _Py_IDENTIFIER(offset); + _Py_IDENTIFIER(text); + + *message = NULL; + *filename = NULL; + + /* new style errors. `err' is an instance */ + *message = _PyObject_GetAttrId(err, &PyId_msg); + if (!*message) + goto finally; + + v = _PyObject_GetAttrId(err, &PyId_filename); + if (!v) + goto finally; + if (v == Py_None) { + Py_DECREF(v); + *filename = _PyUnicode_FromId(&PyId_string); + if (*filename == NULL) + goto finally; + Py_INCREF(*filename); + } + else { + *filename = v; + } + + v = _PyObject_GetAttrId(err, &PyId_lineno); + if (!v) + goto finally; + hold = _PyLong_AsInt(v); + Py_DECREF(v); + if (hold < 0 && PyErr_Occurred()) + goto finally; + *lineno = hold; + + v = _PyObject_GetAttrId(err, &PyId_offset); + if (!v) + goto finally; + if (v == Py_None) { + *offset = -1; + Py_DECREF(v); + } else { + hold = _PyLong_AsInt(v); + Py_DECREF(v); + if (hold < 0 && PyErr_Occurred()) + goto finally; + *offset = hold; + } + + v = _PyObject_GetAttrId(err, &PyId_text); + if (!v) + goto finally; + if (v == Py_None) { + Py_DECREF(v); + *text = NULL; + } + else { + *text = v; + } + return 1; + +finally: + Py_XDECREF(*message); + Py_XDECREF(*filename); + return 0; +} + +static void +print_error_text(PyObject *f, int offset, PyObject *text_obj) +{ + const char *text; + const char *nl; + + text = PyUnicode_AsUTF8(text_obj); + if (text == NULL) + return; + + if (offset >= 0) { + if (offset > 0 && (size_t)offset == strlen(text) && text[offset - 1] == '\n') + offset--; + for (;;) { + nl = strchr(text, '\n'); + if (nl == NULL || nl-text >= offset) + break; + offset -= (int)(nl+1-text); + text = nl+1; + } + while (*text == ' ' || *text == '\t' || *text == '\f') { + text++; + offset--; + } + } + PyFile_WriteString(" ", f); + PyFile_WriteString(text, f); + if (*text == '\0' || text[strlen(text)-1] != '\n') + PyFile_WriteString("\n", f); + if (offset == -1) + return; + PyFile_WriteString(" ", f); + while (--offset > 0) + PyFile_WriteString(" ", f); + PyFile_WriteString("^\n", f); +} + + +int +_Py_HandleSystemExit(int *exitcode_p) +{ + int inspect = _PyInterpreterState_GET_UNSAFE()->config.inspect; + if (inspect) { + /* Don't exit if -i flag was given. This flag is set to 0 + * when entering interactive mode for inspecting. */ + return 0; + } + + if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { + return 0; + } + + PyObject *exception, *value, *tb; + PyErr_Fetch(&exception, &value, &tb); + + fflush(stdout); + + int exitcode = 0; + if (value == NULL || value == Py_None) { + goto done; + } + + if (PyExceptionInstance_Check(value)) { + /* The error code should be in the `code' attribute. */ + _Py_IDENTIFIER(code); + PyObject *code = _PyObject_GetAttrId(value, &PyId_code); + if (code) { + Py_DECREF(value); + value = code; + if (value == Py_None) + goto done; + } + /* If we failed to dig out the 'code' attribute, + just let the else clause below print the error. */ + } + + if (PyLong_Check(value)) { + exitcode = (int)PyLong_AsLong(value); + } + else { + PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr); + /* We clear the exception here to avoid triggering the assertion + * in PyObject_Str that ensures it won't silently lose exception + * details. + */ + PyErr_Clear(); + if (sys_stderr != NULL && sys_stderr != Py_None) { + PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); + } else { + PyObject_Print(value, stderr, Py_PRINT_RAW); + fflush(stderr); + } + PySys_WriteStderr("\n"); + exitcode = 1; + } + + done: + /* Restore and clear the exception info, in order to properly decref + * the exception, value, and traceback. If we just exit instead, + * these leak, which confuses PYTHONDUMPREFS output, and may prevent + * some finalizers from running. + */ + PyErr_Restore(exception, value, tb); + PyErr_Clear(); + *exitcode_p = exitcode; + return 1; +} + + +static void +handle_system_exit(void) +{ + int exitcode; + if (_Py_HandleSystemExit(&exitcode)) { + Py_Exit(exitcode); + } +} + + +static void +_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) +{ + PyObject *exception, *v, *tb, *hook; + + handle_system_exit(); + + _PyErr_Fetch(tstate, &exception, &v, &tb); + if (exception == NULL) { + goto done; + } + + _PyErr_NormalizeException(tstate, &exception, &v, &tb); + if (tb == NULL) { + tb = Py_None; + Py_INCREF(tb); + } + PyException_SetTraceback(v, tb); + if (exception == NULL) { + goto done; + } + + /* Now we know v != NULL too */ + if (set_sys_last_vars) { + if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) { + _PyErr_Clear(tstate); + } + if (_PySys_SetObjectId(&PyId_last_value, v) < 0) { + _PyErr_Clear(tstate); + } + if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) { + _PyErr_Clear(tstate); + } + } + hook = _PySys_GetObjectId(&PyId_excepthook); + if (PySys_Audit("sys.excepthook", "OOOO", hook ? hook : Py_None, + exception, v, tb) < 0) { + if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { + PyErr_Clear(); + goto done; + } + _PyErr_WriteUnraisableMsg("in audit hook", NULL); + } + if (hook) { + PyObject* stack[3]; + PyObject *result; + + stack[0] = exception; + stack[1] = v; + stack[2] = tb; + result = _PyObject_FastCall(hook, stack, 3); + if (result == NULL) { + handle_system_exit(); + + PyObject *exception2, *v2, *tb2; + _PyErr_Fetch(tstate, &exception2, &v2, &tb2); + _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2); + /* It should not be possible for exception2 or v2 + to be NULL. However PyErr_Display() can't + tolerate NULLs, so just be safe. */ + if (exception2 == NULL) { + exception2 = Py_None; + Py_INCREF(exception2); + } + if (v2 == NULL) { + v2 = Py_None; + Py_INCREF(v2); + } + fflush(stdout); + PySys_WriteStderr("Error in sys.excepthook:\n"); + PyErr_Display(exception2, v2, tb2); + PySys_WriteStderr("\nOriginal exception was:\n"); + PyErr_Display(exception, v, tb); + Py_DECREF(exception2); + Py_DECREF(v2); + Py_XDECREF(tb2); + } + Py_XDECREF(result); + } + else { + PySys_WriteStderr("sys.excepthook is missing\n"); + PyErr_Display(exception, v, tb); + } + +done: + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); +} + +void +_PyErr_Print(PyThreadState *tstate) +{ + _PyErr_PrintEx(tstate, 1); +} + +void +PyErr_PrintEx(int set_sys_last_vars) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_PrintEx(tstate, set_sys_last_vars); +} + +void +PyErr_Print(void) +{ + PyErr_PrintEx(1); +} + +static void +print_exception(PyObject *f, PyObject *value) +{ + int err = 0; + PyObject *type, *tb; + _Py_IDENTIFIER(print_file_and_line); + + if (!PyExceptionInstance_Check(value)) { + err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); + err += PyFile_WriteString(Py_TYPE(value)->tp_name, f); + err += PyFile_WriteString(" found\n", f); + if (err) + PyErr_Clear(); + return; + } + + Py_INCREF(value); + fflush(stdout); + type = (PyObject *) Py_TYPE(value); + tb = PyException_GetTraceback(value); + if (tb && tb != Py_None) + err = PyTraceBack_Print(tb, f); + if (err == 0 && + _PyObject_HasAttrId(value, &PyId_print_file_and_line)) + { + PyObject *message, *filename, *text; + int lineno, offset; + if (!parse_syntax_error(value, &message, &filename, + &lineno, &offset, &text)) + PyErr_Clear(); + else { + PyObject *line; + + Py_DECREF(value); + value = message; + + line = PyUnicode_FromFormat(" File \"%S\", line %d\n", + filename, lineno); + Py_DECREF(filename); + if (line != NULL) { + PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); + } + + if (text != NULL) { + print_error_text(f, offset, text); + Py_DECREF(text); + } + + /* Can't be bothered to check all those + PyFile_WriteString() calls */ + if (PyErr_Occurred()) + err = -1; + } + } + if (err) { + /* Don't do anything else */ + } + else { + PyObject* moduleName; + const char *className; + _Py_IDENTIFIER(__module__); + assert(PyExceptionClass_Check(type)); + className = PyExceptionClass_Name(type); + if (className != NULL) { + const char *dot = strrchr(className, '.'); + if (dot != NULL) + className = dot+1; + } + + moduleName = _PyObject_GetAttrId(type, &PyId___module__); + if (moduleName == NULL || !PyUnicode_Check(moduleName)) + { + Py_XDECREF(moduleName); + err = PyFile_WriteString("", f); + } + else { + if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) + { + err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); + err += PyFile_WriteString(".", f); + } + Py_DECREF(moduleName); + } + if (err == 0) { + if (className == NULL) + err = PyFile_WriteString("", f); + else + err = PyFile_WriteString(className, f); + } + } + if (err == 0 && (value != Py_None)) { + PyObject *s = PyObject_Str(value); + /* only print colon if the str() of the + object is not the empty string + */ + if (s == NULL) { + PyErr_Clear(); + err = -1; + PyFile_WriteString(": ", f); + } + else if (!PyUnicode_Check(s) || + PyUnicode_GetLength(s) != 0) + err = PyFile_WriteString(": ", f); + if (err == 0) + err = PyFile_WriteObject(s, f, Py_PRINT_RAW); + Py_XDECREF(s); + } + /* try to write a newline in any case */ + if (err < 0) { + PyErr_Clear(); + } + err += PyFile_WriteString("\n", f); + Py_XDECREF(tb); + Py_DECREF(value); + /* If an error happened here, don't show it. + XXX This is wrong, but too many callers rely on this behavior. */ + if (err != 0) + PyErr_Clear(); +} + +static const char cause_message[] = + "\nThe above exception was the direct cause " + "of the following exception:\n\n"; + +static const char context_message[] = + "\nDuring handling of the above exception, " + "another exception occurred:\n\n"; + +static void +print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) +{ + int err = 0, res; + PyObject *cause, *context; + + if (seen != NULL) { + /* Exception chaining */ + PyObject *value_id = PyLong_FromVoidPtr(value); + if (value_id == NULL || PySet_Add(seen, value_id) == -1) + PyErr_Clear(); + else if (PyExceptionInstance_Check(value)) { + PyObject *check_id = NULL; + cause = PyException_GetCause(value); + context = PyException_GetContext(value); + if (cause) { + check_id = PyLong_FromVoidPtr(cause); + if (check_id == NULL) { + res = -1; + } else { + res = PySet_Contains(seen, check_id); + Py_DECREF(check_id); + } + if (res == -1) + PyErr_Clear(); + if (res == 0) { + print_exception_recursive( + f, cause, seen); + err |= PyFile_WriteString( + cause_message, f); + } + } + else if (context && + !((PyBaseExceptionObject *)value)->suppress_context) { + check_id = PyLong_FromVoidPtr(context); + if (check_id == NULL) { + res = -1; + } else { + res = PySet_Contains(seen, check_id); + Py_DECREF(check_id); + } + if (res == -1) + PyErr_Clear(); + if (res == 0) { + print_exception_recursive( + f, context, seen); + err |= PyFile_WriteString( + context_message, f); + } + } + Py_XDECREF(context); + Py_XDECREF(cause); + } + Py_XDECREF(value_id); + } + print_exception(f, value); + if (err != 0) + PyErr_Clear(); +} + +void +_PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb) +{ + assert(file != NULL && file != Py_None); + + PyObject *seen; + if (PyExceptionInstance_Check(value) + && tb != NULL && PyTraceBack_Check(tb)) { + /* Put the traceback on the exception, otherwise it won't get + displayed. See issue #18776. */ + PyObject *cur_tb = PyException_GetTraceback(value); + if (cur_tb == NULL) + PyException_SetTraceback(value, tb); + else + Py_DECREF(cur_tb); + } + + /* We choose to ignore seen being possibly NULL, and report + at least the main exception (it could be a MemoryError). + */ + seen = PySet_New(NULL); + if (seen == NULL) { + PyErr_Clear(); + } + print_exception_recursive(file, value, seen); + Py_XDECREF(seen); + + /* Call file.flush() */ + PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + if (!res) { + /* Silently ignore file.flush() error */ + PyErr_Clear(); + } + else { + Py_DECREF(res); + } +} + +void +PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) +{ + PyObject *file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL) { + _PyObject_Dump(value); + fprintf(stderr, "lost sys.stderr\n"); + return; + } + if (file == Py_None) { + return; + } + Py_INCREF(file); + _PyErr_Display(file, exception, value, tb); + Py_DECREF(file); +} + +PyObject * +PyRun_StringFlags(const char *str, int start, PyObject *globals, + PyObject *locals, PyCompilerFlags *flags) +{ + PyObject *ret = NULL; + mod_ty mod; + PyArena *arena; + PyObject *filename; + + filename = _PyUnicode_FromId(&PyId_string); /* borrowed */ + if (filename == NULL) + return NULL; + + arena = PyArena_New(); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + if (mod != NULL) + ret = run_mod(mod, filename, globals, locals, flags, arena); + PyArena_Free(arena); + return ret; +} + + +static PyObject * +pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, + PyObject *locals, int closeit, PyCompilerFlags *flags) +{ + PyArena *arena = PyArena_New(); + if (arena == NULL) { + return NULL; + } + + mod_ty mod; + mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, 0, 0, + flags, NULL, arena); + if (closeit) { + fclose(fp); + } + + PyObject *ret; + if (mod != NULL) { + ret = run_mod(mod, filename, globals, locals, flags, arena); + } + else { + ret = NULL; + } + PyArena_Free(arena); + + return ret; +} + + +PyObject * +PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, + PyObject *locals, int closeit, PyCompilerFlags *flags) +{ + PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename); + if (filename_obj == NULL) { + return NULL; + } + + PyObject *res = pyrun_file(fp, filename_obj, start, globals, + locals, closeit, flags); + Py_DECREF(filename_obj); + return res; + +} + + +static void +flush_io(void) +{ + PyObject *f, *r; + PyObject *type, *value, *traceback; + + /* Save the current exception */ + PyErr_Fetch(&type, &value, &traceback); + + f = _PySys_GetObjectId(&PyId_stderr); + if (f != NULL) { + r = _PyObject_CallMethodId(f, &PyId_flush, NULL); + if (r) + Py_DECREF(r); + else + PyErr_Clear(); + } + f = _PySys_GetObjectId(&PyId_stdout); + if (f != NULL) { + r = _PyObject_CallMethodId(f, &PyId_flush, NULL); + if (r) + Py_DECREF(r); + else + PyErr_Clear(); + } + + PyErr_Restore(type, value, traceback); +} + +static PyObject * +run_eval_code_obj(PyCodeObject *co, PyObject *globals, PyObject *locals) +{ + PyObject *v; + /* + * We explicitly re-initialize _Py_UnhandledKeyboardInterrupt every eval + * _just in case_ someone is calling into an embedded Python where they + * don't care about an uncaught KeyboardInterrupt exception (why didn't they + * leave config.install_signal_handlers set to 0?!?) but then later call + * Py_Main() itself (which _checks_ this flag and dies with a signal after + * its interpreter exits). We don't want a previous embedded interpreter's + * uncaught exception to trigger an unexplained signal exit from a future + * Py_Main() based one. + */ + _Py_UnhandledKeyboardInterrupt = 0; + + /* Set globals['__builtins__'] if it doesn't exist */ + if (globals != NULL && PyDict_GetItemString(globals, "__builtins__") == NULL) { + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (PyDict_SetItemString(globals, "__builtins__", interp->builtins) < 0) { + return NULL; + } + } + + v = PyEval_EvalCode((PyObject*)co, globals, locals); + if (!v && PyErr_Occurred() == PyExc_KeyboardInterrupt) { + _Py_UnhandledKeyboardInterrupt = 1; + } + return v; +} + +static PyObject * +run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, + PyCompilerFlags *flags, PyArena *arena) +{ + PyCodeObject *co; + PyObject *v; + co = PyAST_CompileObject(mod, filename, flags, -1, arena); + if (co == NULL) + return NULL; + + if (PySys_Audit("exec", "O", co) < 0) { + Py_DECREF(co); + return NULL; + } + + v = run_eval_code_obj(co, globals, locals); + Py_DECREF(co); + return v; +} + +static PyObject * +run_pyc_file(FILE *fp, PyObject *globals, PyObject *locals, + PyCompilerFlags *flags) +{ + PyCodeObject *co; + PyObject *v; + long magic; + long PyImport_GetMagicNumber(void); + + magic = PyMarshal_ReadLongFromFile(fp); + if (magic != PyImport_GetMagicNumber()) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, + "Bad magic number in .pyc file"); + goto error; + } + /* Skip the rest of the header. */ + (void) PyMarshal_ReadLongFromFile(fp); + (void) PyMarshal_ReadLongFromFile(fp); + (void) PyMarshal_ReadLongFromFile(fp); + if (PyErr_Occurred()) { + goto error; + } + v = PyMarshal_ReadLastObjectFromFile(fp); + if (v == NULL || !PyCode_Check(v)) { + Py_XDECREF(v); + PyErr_SetString(PyExc_RuntimeError, + "Bad code object in .pyc file"); + goto error; + } + fclose(fp); + co = (PyCodeObject *)v; + v = run_eval_code_obj(co, globals, locals); + if (v && flags) + flags->cf_flags |= (co->co_flags & PyCF_MASK); + Py_DECREF(co); + return v; +error: + fclose(fp); + return NULL; +} + +PyObject * +Py_CompileStringObject(const char *str, PyObject *filename, int start, + PyCompilerFlags *flags, int optimize) +{ + PyCodeObject *co; + mod_ty mod; + PyArena *arena = PyArena_New(); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + if (mod == NULL) { + PyArena_Free(arena); + return NULL; + } + if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { + PyObject *result = PyAST_mod2obj(mod); + PyArena_Free(arena); + return result; + } + co = PyAST_CompileObject(mod, filename, flags, optimize, arena); + PyArena_Free(arena); + return (PyObject *)co; +} + +PyObject * +Py_CompileStringExFlags(const char *str, const char *filename_str, int start, + PyCompilerFlags *flags, int optimize) +{ + PyObject *filename, *co; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + co = Py_CompileStringObject(str, filename, start, flags, optimize); + Py_DECREF(filename); + return co; +} + +/* For use in Py_LIMITED_API */ +#undef Py_CompileString +PyObject * +PyCompileString(const char *str, const char *filename, int start) +{ + return Py_CompileStringFlags(str, filename, start, NULL); +} + +const char * +_Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) +{ + const char *str; + Py_ssize_t size; + Py_buffer view; + + *cmd_copy = NULL; + if (PyUnicode_Check(cmd)) { + cf->cf_flags |= PyCF_IGNORE_COOKIE; + str = PyUnicode_AsUTF8AndSize(cmd, &size); + if (str == NULL) + return NULL; + } + else if (PyBytes_Check(cmd)) { + str = PyBytes_AS_STRING(cmd); + size = PyBytes_GET_SIZE(cmd); + } + else if (PyByteArray_Check(cmd)) { + str = PyByteArray_AS_STRING(cmd); + size = PyByteArray_GET_SIZE(cmd); + } + else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) { + /* Copy to NUL-terminated buffer. */ + *cmd_copy = PyBytes_FromStringAndSize( + (const char *)view.buf, view.len); + PyBuffer_Release(&view); + if (*cmd_copy == NULL) { + return NULL; + } + str = PyBytes_AS_STRING(*cmd_copy); + size = PyBytes_GET_SIZE(*cmd_copy); + } + else { + PyErr_Format(PyExc_TypeError, + "%s() arg 1 must be a %s object", + funcname, what); + return NULL; + } + + if (strlen(str) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, + "source code string cannot contain null bytes"); + Py_CLEAR(*cmd_copy); + return NULL; + } + return str; +} + +struct symtable * +Py_SymtableStringObject(const char *str, PyObject *filename, int start) +{ + PyCompilerFlags flags = _PyCompilerFlags_INIT; + return _Py_SymtableStringObjectFlags(str, filename, start, &flags); +} + +struct symtable * +_Py_SymtableStringObjectFlags(const char *str, PyObject *filename, int start, PyCompilerFlags *flags) +{ + struct symtable *st; + mod_ty mod; + PyArena *arena; + + arena = PyArena_New(); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + if (mod == NULL) { + PyArena_Free(arena); + return NULL; + } + st = PySymtable_BuildObject(mod, filename, 0); + PyArena_Free(arena); + return st; +} + +struct symtable * +Py_SymtableString(const char *str, const char *filename_str, int start) +{ + PyObject *filename; + struct symtable *st; + + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + st = Py_SymtableStringObject(str, filename, start); + Py_DECREF(filename); + return st; +} + +/* Preferred access to parser is through AST. */ +mod_ty +PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start, + PyCompilerFlags *flags, PyArena *arena) +{ + mod_ty mod; + PyCompilerFlags localflags = _PyCompilerFlags_INIT; + perrdetail err; + int iflags = PARSER_FLAGS(flags); + if (flags && (flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7) + iflags |= PyPARSE_ASYNC_HACKS; + + node *n = PyParser_ParseStringObject(s, filename, + &_PyParser_Grammar, start, &err, + &iflags); + if (flags == NULL) { + flags = &localflags; + } + if (n) { + flags->cf_flags |= iflags & PyCF_MASK; + mod = PyAST_FromNodeObject(n, flags, filename, arena); + PyNode_Free(n); + } + else { + err_input(&err); + mod = NULL; + } + err_free(&err); + return mod; +} + +mod_ty +PyParser_ASTFromString(const char *s, const char *filename_str, int start, + PyCompilerFlags *flags, PyArena *arena) +{ + PyObject *filename; + mod_ty mod; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyParser_ASTFromStringObject(s, filename, start, flags, arena); + Py_DECREF(filename); + return mod; +} + +mod_ty +PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc, + int start, const char *ps1, + const char *ps2, PyCompilerFlags *flags, int *errcode, + PyArena *arena) +{ + mod_ty mod; + PyCompilerFlags localflags = _PyCompilerFlags_INIT; + perrdetail err; + int iflags = PARSER_FLAGS(flags); + + node *n = PyParser_ParseFileObject(fp, filename, enc, + &_PyParser_Grammar, + start, ps1, ps2, &err, &iflags); + if (flags == NULL) { + flags = &localflags; + } + if (n) { + flags->cf_flags |= iflags & PyCF_MASK; + mod = PyAST_FromNodeObject(n, flags, filename, arena); + PyNode_Free(n); + } + else { + err_input(&err); + if (errcode) + *errcode = err.error; + mod = NULL; + } + err_free(&err); + return mod; +} + +mod_ty +PyParser_ASTFromFile(FILE *fp, const char *filename_str, const char* enc, + int start, const char *ps1, + const char *ps2, PyCompilerFlags *flags, int *errcode, + PyArena *arena) +{ + mod_ty mod; + PyObject *filename; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + mod = PyParser_ASTFromFileObject(fp, filename, enc, start, ps1, ps2, + flags, errcode, arena); + Py_DECREF(filename); + return mod; +} + +/* Simplified interface to parsefile -- return node or set exception */ + +node * +PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags) +{ + perrdetail err; + node *n = PyParser_ParseFileFlags(fp, filename, NULL, + &_PyParser_Grammar, + start, NULL, NULL, &err, flags); + if (n == NULL) + err_input(&err); + err_free(&err); + + return n; +} + +/* Simplified interface to parsestring -- return node or set exception */ + +node * +PyParser_SimpleParseStringFlags(const char *str, int start, int flags) +{ + perrdetail err; + node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, + start, &err, flags); + if (n == NULL) + err_input(&err); + err_free(&err); + return n; +} + +node * +PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, + int start, int flags) +{ + perrdetail err; + node *n = PyParser_ParseStringFlagsFilename(str, filename, + &_PyParser_Grammar, start, &err, flags); + if (n == NULL) + err_input(&err); + err_free(&err); + return n; +} + +/* May want to move a more generalized form of this to parsetok.c or + even parser modules. */ + +void +PyParser_ClearError(perrdetail *err) +{ + err_free(err); +} + +void +PyParser_SetError(perrdetail *err) +{ + err_input(err); +} + +static void +err_free(perrdetail *err) +{ + Py_CLEAR(err->filename); +} + +/* Set the error appropriate to the given input error code (see errcode.h) */ + +static void +err_input(perrdetail *err) +{ + PyObject *v, *w, *errtype, *errtext; + PyObject *msg_obj = NULL; + const char *msg = NULL; + int offset = err->offset; + + errtype = PyExc_SyntaxError; + switch (err->error) { + case E_ERROR: + goto cleanup; + case E_SYNTAX: + errtype = PyExc_IndentationError; + if (err->expected == INDENT) + msg = "expected an indented block"; + else if (err->token == INDENT) + msg = "unexpected indent"; + else if (err->token == DEDENT) + msg = "unexpected unindent"; + else if (err->expected == NOTEQUAL) { + errtype = PyExc_SyntaxError; + msg = "with Barry as BDFL, use '<>' instead of '!='"; + } + else { + errtype = PyExc_SyntaxError; + msg = "invalid syntax"; + } + break; + case E_TOKEN: + msg = "invalid token"; + break; + case E_EOFS: + msg = "EOF while scanning triple-quoted string literal"; + break; + case E_EOLS: + msg = "EOL while scanning string literal"; + break; + case E_INTR: + if (!PyErr_Occurred()) + PyErr_SetNone(PyExc_KeyboardInterrupt); + goto cleanup; + case E_NOMEM: + PyErr_NoMemory(); + goto cleanup; + case E_EOF: + msg = "unexpected EOF while parsing"; + break; + case E_TABSPACE: + errtype = PyExc_TabError; + msg = "inconsistent use of tabs and spaces in indentation"; + break; + case E_OVERFLOW: + msg = "expression too long"; + break; + case E_DEDENT: + errtype = PyExc_IndentationError; + msg = "unindent does not match any outer indentation level"; + break; + case E_TOODEEP: + errtype = PyExc_IndentationError; + msg = "too many levels of indentation"; + break; + case E_DECODE: { + PyObject *type, *value, *tb; + PyErr_Fetch(&type, &value, &tb); + msg = "unknown decode error"; + if (value != NULL) + msg_obj = PyObject_Str(value); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(tb); + break; + } + case E_LINECONT: + msg = "unexpected character after line continuation character"; + break; + + case E_IDENTIFIER: + msg = "invalid character in identifier"; + break; + case E_BADSINGLE: + msg = "multiple statements found while compiling a single statement"; + break; + default: + fprintf(stderr, "error=%d\n", err->error); + msg = "unknown parsing error"; + break; + } + /* err->text may not be UTF-8 in case of decoding errors. + Explicitly convert to an object. */ + if (!err->text) { + errtext = Py_None; + Py_INCREF(Py_None); + } else { + errtext = PyUnicode_DecodeUTF8(err->text, err->offset, + "replace"); + if (errtext != NULL) { + Py_ssize_t len = strlen(err->text); + offset = (int)PyUnicode_GET_LENGTH(errtext); + if (len != err->offset) { + Py_DECREF(errtext); + errtext = PyUnicode_DecodeUTF8(err->text, len, + "replace"); + } + } + } + v = Py_BuildValue("(OiiN)", err->filename, + err->lineno, offset, errtext); + if (v != NULL) { + if (msg_obj) + w = Py_BuildValue("(OO)", msg_obj, v); + else + w = Py_BuildValue("(sO)", msg, v); + } else + w = NULL; + Py_XDECREF(v); + PyErr_SetObject(errtype, w); + Py_XDECREF(w); +cleanup: + Py_XDECREF(msg_obj); + if (err->text != NULL) { + PyObject_FREE(err->text); + err->text = NULL; + } +} + + +#if defined(USE_STACKCHECK) +#if defined(WIN32) && defined(_MSC_VER) + +/* Stack checking for Microsoft C */ + +#include +#include + +/* + * Return non-zero when we run out of memory on the stack; zero otherwise. + */ +int +PyOS_CheckStack(void) +{ + __try { + /* alloca throws a stack overflow exception if there's + not enough space left on the stack */ + alloca(PYOS_STACK_MARGIN * sizeof(void*)); + return 0; + } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) { + int errcode = _resetstkoflw(); + if (errcode == 0) + { + Py_FatalError("Could not reset the stack!"); + } + } + return 1; +} + +#endif /* WIN32 && _MSC_VER */ + +/* Alternate implementations can be added here... */ + +#endif /* USE_STACKCHECK */ + +/* Deprecated C API functions still provided for binary compatibility */ + +#undef PyParser_SimpleParseFile +PyAPI_FUNC(node *) +PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) +{ + return PyParser_SimpleParseFileFlags(fp, filename, start, 0); +} + +#undef PyParser_SimpleParseString +PyAPI_FUNC(node *) +PyParser_SimpleParseString(const char *str, int start) +{ + return PyParser_SimpleParseStringFlags(str, start, 0); +} + +#undef PyRun_AnyFile +PyAPI_FUNC(int) +PyRun_AnyFile(FILE *fp, const char *name) +{ + return PyRun_AnyFileExFlags(fp, name, 0, NULL); +} + +#undef PyRun_AnyFileEx +PyAPI_FUNC(int) +PyRun_AnyFileEx(FILE *fp, const char *name, int closeit) +{ + return PyRun_AnyFileExFlags(fp, name, closeit, NULL); +} + +#undef PyRun_AnyFileFlags +PyAPI_FUNC(int) +PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags) +{ + return PyRun_AnyFileExFlags(fp, name, 0, flags); +} + +#undef PyRun_File +PyAPI_FUNC(PyObject *) +PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l) +{ + return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL); +} + +#undef PyRun_FileEx +PyAPI_FUNC(PyObject *) +PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c) +{ + return PyRun_FileExFlags(fp, p, s, g, l, c, NULL); +} + +#undef PyRun_FileFlags +PyAPI_FUNC(PyObject *) +PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, + PyCompilerFlags *flags) +{ + return PyRun_FileExFlags(fp, p, s, g, l, 0, flags); +} + +#undef PyRun_SimpleFile +PyAPI_FUNC(int) +PyRun_SimpleFile(FILE *f, const char *p) +{ + return PyRun_SimpleFileExFlags(f, p, 0, NULL); +} + +#undef PyRun_SimpleFileEx +PyAPI_FUNC(int) +PyRun_SimpleFileEx(FILE *f, const char *p, int c) +{ + return PyRun_SimpleFileExFlags(f, p, c, NULL); +} + + +#undef PyRun_String +PyAPI_FUNC(PyObject *) +PyRun_String(const char *str, int s, PyObject *g, PyObject *l) +{ + return PyRun_StringFlags(str, s, g, l, NULL); +} + +#undef PyRun_SimpleString +PyAPI_FUNC(int) +PyRun_SimpleString(const char *s) +{ + return PyRun_SimpleStringFlags(s, NULL); +} + +#undef Py_CompileString +PyAPI_FUNC(PyObject *) +Py_CompileString(const char *str, const char *p, int s) +{ + return Py_CompileStringExFlags(str, p, s, NULL, -1); +} + +#undef Py_CompileStringFlags +PyAPI_FUNC(PyObject *) +Py_CompileStringFlags(const char *str, const char *p, int s, + PyCompilerFlags *flags) +{ + return Py_CompileStringExFlags(str, p, s, flags, -1); +} + +#undef PyRun_InteractiveOne +PyAPI_FUNC(int) +PyRun_InteractiveOne(FILE *f, const char *p) +{ + return PyRun_InteractiveOneFlags(f, p, NULL); +} + +#undef PyRun_InteractiveLoop +PyAPI_FUNC(int) +PyRun_InteractiveLoop(FILE *f, const char *p) +{ + return PyRun_InteractiveLoopFlags(f, p, NULL); +} + +#ifdef __cplusplus +} +#endif diff --git a/python/Python/pytime.c b/python/Python/pytime.c new file mode 100755 index 0000000..109d526 --- /dev/null +++ b/python/Python/pytime.c @@ -0,0 +1,1114 @@ +#include "Python.h" +#ifdef MS_WINDOWS +#include /* struct timeval */ +#endif + +#if defined(__APPLE__) +#include /* mach_absolute_time(), mach_timebase_info() */ +#endif + +#define _PyTime_check_mul_overflow(a, b) \ + (assert(b > 0), \ + (_PyTime_t)(a) < _PyTime_MIN / (_PyTime_t)(b) \ + || _PyTime_MAX / (_PyTime_t)(b) < (_PyTime_t)(a)) + +/* To millisecond (10^-3) */ +#define SEC_TO_MS 1000 + +/* To microseconds (10^-6) */ +#define MS_TO_US 1000 +#define SEC_TO_US (SEC_TO_MS * MS_TO_US) + +/* To nanoseconds (10^-9) */ +#define US_TO_NS 1000 +#define MS_TO_NS (MS_TO_US * US_TO_NS) +#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS) + +/* Conversion from nanoseconds */ +#define NS_TO_MS (1000 * 1000) +#define NS_TO_US (1000) + +static void +error_time_t_overflow(void) +{ + PyErr_SetString(PyExc_OverflowError, + "timestamp out of range for platform time_t"); +} + +static void +_PyTime_overflow(void) +{ + PyErr_SetString(PyExc_OverflowError, + "timestamp too large to convert to C _PyTime_t"); +} + + +_PyTime_t +_PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div) +{ + _PyTime_t intpart, remaining; + /* Compute (ticks * mul / div) in two parts to prevent integer overflow: + compute integer part, and then the remaining part. + + (ticks * mul) / div == (ticks / div) * mul + (ticks % div) * mul / div + + The caller must ensure that "(div - 1) * mul" cannot overflow. */ + intpart = ticks / div; + ticks %= div; + remaining = ticks * mul; + remaining /= div; + return intpart * mul + remaining; +} + + +time_t +_PyLong_AsTime_t(PyObject *obj) +{ +#if SIZEOF_TIME_T == SIZEOF_LONG_LONG + long long val; + val = PyLong_AsLongLong(obj); +#else + long val; + Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); + val = PyLong_AsLong(obj); +#endif + if (val == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + error_time_t_overflow(); + } + return -1; + } + return (time_t)val; +} + +PyObject * +_PyLong_FromTime_t(time_t t) +{ +#if SIZEOF_TIME_T == SIZEOF_LONG_LONG + return PyLong_FromLongLong((long long)t); +#else + Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); + return PyLong_FromLong((long)t); +#endif +} + +/* Round to nearest with ties going to nearest even integer + (_PyTime_ROUND_HALF_EVEN) */ +static double +_PyTime_RoundHalfEven(double x) +{ + double rounded = round(x); + if (fabs(x-rounded) == 0.5) { + /* halfway case: round to even */ + rounded = 2.0*round(x/2.0); + } + return rounded; +} + +static double +_PyTime_Round(double x, _PyTime_round_t round) +{ + /* volatile avoids optimization changing how numbers are rounded */ + volatile double d; + + d = x; + if (round == _PyTime_ROUND_HALF_EVEN) { + d = _PyTime_RoundHalfEven(d); + } + else if (round == _PyTime_ROUND_CEILING) { + d = ceil(d); + } + else if (round == _PyTime_ROUND_FLOOR) { + d = floor(d); + } + else { + assert(round == _PyTime_ROUND_UP); + d = (d >= 0.0) ? ceil(d) : floor(d); + } + return d; +} + +static int +_PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator, + long idenominator, _PyTime_round_t round) +{ + double denominator = (double)idenominator; + double intpart; + /* volatile avoids optimization changing how numbers are rounded */ + volatile double floatpart; + + floatpart = modf(d, &intpart); + + floatpart *= denominator; + floatpart = _PyTime_Round(floatpart, round); + if (floatpart >= denominator) { + floatpart -= denominator; + intpart += 1.0; + } + else if (floatpart < 0) { + floatpart += denominator; + intpart -= 1.0; + } + assert(0.0 <= floatpart && floatpart < denominator); + + if (!_Py_InIntegralTypeRange(time_t, intpart)) { + error_time_t_overflow(); + return -1; + } + *sec = (time_t)intpart; + *numerator = (long)floatpart; + assert(0 <= *numerator && *numerator < idenominator); + return 0; +} + +static int +_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, + long denominator, _PyTime_round_t round) +{ + assert(denominator >= 1); + + if (PyFloat_Check(obj)) { + double d = PyFloat_AsDouble(obj); + if (Py_IS_NAN(d)) { + *numerator = 0; + PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)"); + return -1; + } + return _PyTime_DoubleToDenominator(d, sec, numerator, + denominator, round); + } + else { + *sec = _PyLong_AsTime_t(obj); + *numerator = 0; + if (*sec == (time_t)-1 && PyErr_Occurred()) { + return -1; + } + return 0; + } +} + +int +_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round) +{ + if (PyFloat_Check(obj)) { + double intpart; + /* volatile avoids optimization changing how numbers are rounded */ + volatile double d; + + d = PyFloat_AsDouble(obj); + if (Py_IS_NAN(d)) { + PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)"); + return -1; + } + + d = _PyTime_Round(d, round); + (void)modf(d, &intpart); + + if (!_Py_InIntegralTypeRange(time_t, intpart)) { + error_time_t_overflow(); + return -1; + } + *sec = (time_t)intpart; + return 0; + } + else { + *sec = _PyLong_AsTime_t(obj); + if (*sec == (time_t)-1 && PyErr_Occurred()) { + return -1; + } + return 0; + } +} + +int +_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec, + _PyTime_round_t round) +{ + return _PyTime_ObjectToDenominator(obj, sec, nsec, SEC_TO_NS, round); +} + +int +_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec, + _PyTime_round_t round) +{ + return _PyTime_ObjectToDenominator(obj, sec, usec, SEC_TO_US, round); +} + +_PyTime_t +_PyTime_FromSeconds(int seconds) +{ + _PyTime_t t; + /* ensure that integer overflow cannot happen, int type should have 32 + bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30 + bits). */ + Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS); + Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS); + + t = (_PyTime_t)seconds; + assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS) + || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS)); + t *= SEC_TO_NS; + return t; +} + +_PyTime_t +_PyTime_FromNanoseconds(_PyTime_t ns) +{ + /* _PyTime_t already uses nanosecond resolution, no conversion needed */ + return ns; +} + +int +_PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) +{ + long long nsec; + _PyTime_t t; + + if (!PyLong_Check(obj)) { + PyErr_Format(PyExc_TypeError, "expect int, got %s", + Py_TYPE(obj)->tp_name); + return -1; + } + + Py_BUILD_ASSERT(sizeof(long long) == sizeof(_PyTime_t)); + nsec = PyLong_AsLongLong(obj); + if (nsec == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + _PyTime_overflow(); + } + return -1; + } + + /* _PyTime_t already uses nanosecond resolution, no conversion needed */ + t = (_PyTime_t)nsec; + *tp = t; + return 0; +} + +#ifdef HAVE_CLOCK_GETTIME +static int +pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise) +{ + _PyTime_t t, nsec; + int res = 0; + + Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); + t = (_PyTime_t)ts->tv_sec; + + if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { + if (raise) { + _PyTime_overflow(); + } + res = -1; + t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; + } + else { + t = t * SEC_TO_NS; + } + + nsec = ts->tv_nsec; + /* The following test is written for positive only nsec */ + assert(nsec >= 0); + if (t > _PyTime_MAX - nsec) { + if (raise) { + _PyTime_overflow(); + } + res = -1; + t = _PyTime_MAX; + } + else { + t += nsec; + } + + *tp = t; + return res; +} + +int +_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts) +{ + return pytime_fromtimespec(tp, ts, 1); +} +#endif + +#if !defined(MS_WINDOWS) +static int +pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise) +{ + _PyTime_t t, usec; + int res = 0; + + Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); + t = (_PyTime_t)tv->tv_sec; + + if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { + if (raise) { + _PyTime_overflow(); + } + res = -1; + t = (t > 0) ? _PyTime_MAX : _PyTime_MIN; + } + else { + t = t * SEC_TO_NS; + } + + usec = (_PyTime_t)tv->tv_usec * US_TO_NS; + /* The following test is written for positive only usec */ + assert(usec >= 0); + if (t > _PyTime_MAX - usec) { + if (raise) { + _PyTime_overflow(); + } + res = -1; + t = _PyTime_MAX; + } + else { + t += usec; + } + + *tp = t; + return res; +} + +int +_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv) +{ + return pytime_fromtimeval(tp, tv, 1); +} +#endif + +static int +_PyTime_FromDouble(_PyTime_t *t, double value, _PyTime_round_t round, + long unit_to_ns) +{ + /* volatile avoids optimization changing how numbers are rounded */ + volatile double d; + + /* convert to a number of nanoseconds */ + d = value; + d *= (double)unit_to_ns; + d = _PyTime_Round(d, round); + + if (!_Py_InIntegralTypeRange(_PyTime_t, d)) { + _PyTime_overflow(); + return -1; + } + *t = (_PyTime_t)d; + return 0; +} + +static int +_PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round, + long unit_to_ns) +{ + if (PyFloat_Check(obj)) { + double d; + d = PyFloat_AsDouble(obj); + if (Py_IS_NAN(d)) { + PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)"); + return -1; + } + return _PyTime_FromDouble(t, d, round, unit_to_ns); + } + else { + long long sec; + Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t)); + + sec = PyLong_AsLongLong(obj); + if (sec == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + _PyTime_overflow(); + } + return -1; + } + + if (_PyTime_check_mul_overflow(sec, unit_to_ns)) { + _PyTime_overflow(); + return -1; + } + *t = sec * unit_to_ns; + return 0; + } +} + +int +_PyTime_FromSecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round) +{ + return _PyTime_FromObject(t, obj, round, SEC_TO_NS); +} + +int +_PyTime_FromMillisecondsObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round) +{ + return _PyTime_FromObject(t, obj, round, MS_TO_NS); +} + +double +_PyTime_AsSecondsDouble(_PyTime_t t) +{ + /* volatile avoids optimization changing how numbers are rounded */ + volatile double d; + + if (t % SEC_TO_NS == 0) { + _PyTime_t secs; + /* Divide using integers to avoid rounding issues on the integer part. + 1e-9 cannot be stored exactly in IEEE 64-bit. */ + secs = t / SEC_TO_NS; + d = (double)secs; + } + else { + d = (double)t; + d /= 1e9; + } + return d; +} + +PyObject * +_PyTime_AsNanosecondsObject(_PyTime_t t) +{ + Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t)); + return PyLong_FromLongLong((long long)t); +} + +static _PyTime_t +_PyTime_Divide(const _PyTime_t t, const _PyTime_t k, + const _PyTime_round_t round) +{ + assert(k > 1); + if (round == _PyTime_ROUND_HALF_EVEN) { + _PyTime_t x, r, abs_r; + x = t / k; + r = t % k; + abs_r = Py_ABS(r); + if (abs_r > k / 2 || (abs_r == k / 2 && (Py_ABS(x) & 1))) { + if (t >= 0) { + x++; + } + else { + x--; + } + } + return x; + } + else if (round == _PyTime_ROUND_CEILING) { + if (t >= 0) { + return (t + k - 1) / k; + } + else { + return t / k; + } + } + else if (round == _PyTime_ROUND_FLOOR){ + if (t >= 0) { + return t / k; + } + else { + return (t - (k - 1)) / k; + } + } + else { + assert(round == _PyTime_ROUND_UP); + if (t >= 0) { + return (t + k - 1) / k; + } + else { + return (t - (k - 1)) / k; + } + } +} + +_PyTime_t +_PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round) +{ + return _PyTime_Divide(t, NS_TO_MS, round); +} + +_PyTime_t +_PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round) +{ + return _PyTime_Divide(t, NS_TO_US, round); +} + +static int +_PyTime_AsTimeval_impl(_PyTime_t t, _PyTime_t *p_secs, int *p_us, + _PyTime_round_t round) +{ + _PyTime_t secs, ns; + int usec; + int res = 0; + + secs = t / SEC_TO_NS; + ns = t % SEC_TO_NS; + + usec = (int)_PyTime_Divide(ns, US_TO_NS, round); + if (usec < 0) { + usec += SEC_TO_US; + if (secs != _PyTime_MIN) { + secs -= 1; + } + else { + res = -1; + } + } + else if (usec >= SEC_TO_US) { + usec -= SEC_TO_US; + if (secs != _PyTime_MAX) { + secs += 1; + } + else { + res = -1; + } + } + assert(0 <= usec && usec < SEC_TO_US); + + *p_secs = secs; + *p_us = usec; + + return res; +} + +static int +_PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv, + _PyTime_round_t round, int raise) +{ + _PyTime_t secs, secs2; + int us; + int res; + + res = _PyTime_AsTimeval_impl(t, &secs, &us, round); + +#ifdef MS_WINDOWS + tv->tv_sec = (long)secs; +#else + tv->tv_sec = secs; +#endif + tv->tv_usec = us; + + secs2 = (_PyTime_t)tv->tv_sec; + if (res < 0 || secs2 != secs) { + if (raise) { + error_time_t_overflow(); + } + return -1; + } + return 0; +} + +int +_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round) +{ + return _PyTime_AsTimevalStruct_impl(t, tv, round, 1); +} + +int +_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round) +{ + return _PyTime_AsTimevalStruct_impl(t, tv, round, 0); +} + +int +_PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us, + _PyTime_round_t round) +{ + _PyTime_t secs; + int res; + + res = _PyTime_AsTimeval_impl(t, &secs, us, round); + + *p_secs = secs; + + if (res < 0 || (_PyTime_t)*p_secs != secs) { + error_time_t_overflow(); + return -1; + } + return 0; +} + + +#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) +int +_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts) +{ + _PyTime_t secs, nsec; + + secs = t / SEC_TO_NS; + nsec = t % SEC_TO_NS; + if (nsec < 0) { + nsec += SEC_TO_NS; + secs -= 1; + } + ts->tv_sec = (time_t)secs; + assert(0 <= nsec && nsec < SEC_TO_NS); + ts->tv_nsec = nsec; + + if ((_PyTime_t)ts->tv_sec != secs) { + error_time_t_overflow(); + return -1; + } + return 0; +} +#endif + +static int +pygettimeofday(_PyTime_t *tp, _Py_clock_info_t *info, int raise) +{ +#ifdef MS_WINDOWS + FILETIME system_time; + ULARGE_INTEGER large; + + assert(info == NULL || raise); + + GetSystemTimeAsFileTime(&system_time); + large.u.LowPart = system_time.dwLowDateTime; + large.u.HighPart = system_time.dwHighDateTime; + /* 11,644,473,600,000,000,000: number of nanoseconds between + the 1st january 1601 and the 1st january 1970 (369 years + 89 leap + days). */ + *tp = large.QuadPart * 100 - 11644473600000000000; + if (info) { + DWORD timeAdjustment, timeIncrement; + BOOL isTimeAdjustmentDisabled, ok; + + info->implementation = "GetSystemTimeAsFileTime()"; + info->monotonic = 0; + ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, + &isTimeAdjustmentDisabled); + if (!ok) { + PyErr_SetFromWindowsErr(0); + return -1; + } + info->resolution = timeIncrement * 1e-7; + info->adjustable = 1; + } + +#else /* MS_WINDOWS */ + int err; +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; +#else + struct timeval tv; +#endif + + assert(info == NULL || raise); + +#ifdef HAVE_CLOCK_GETTIME + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err) { + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; + } + if (pytime_fromtimespec(tp, &ts, raise) < 0) { + return -1; + } + + if (info) { + struct timespec res; + info->implementation = "clock_gettime(CLOCK_REALTIME)"; + info->monotonic = 0; + info->adjustable = 1; + if (clock_getres(CLOCK_REALTIME, &res) == 0) { + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + } + else { + info->resolution = 1e-9; + } + } +#else /* HAVE_CLOCK_GETTIME */ + + /* test gettimeofday() */ +#ifdef GETTIMEOFDAY_NO_TZ + err = gettimeofday(&tv); +#else + err = gettimeofday(&tv, (struct timezone *)NULL); +#endif + if (err) { + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; + } + if (pytime_fromtimeval(tp, &tv, raise) < 0) { + return -1; + } + + if (info) { + info->implementation = "gettimeofday()"; + info->resolution = 1e-6; + info->monotonic = 0; + info->adjustable = 1; + } +#endif /* !HAVE_CLOCK_GETTIME */ +#endif /* !MS_WINDOWS */ + return 0; +} + +_PyTime_t +_PyTime_GetSystemClock(void) +{ + _PyTime_t t; + if (pygettimeofday(&t, NULL, 0) < 0) { + /* should not happen, _PyTime_Init() checked the clock at startup */ + Py_UNREACHABLE(); + } + return t; +} + +int +_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) +{ + return pygettimeofday(t, info, 1); +} + +static int +pymonotonic(_PyTime_t *tp, _Py_clock_info_t *info, int raise) +{ +#if defined(MS_WINDOWS) + ULONGLONG ticks; + _PyTime_t t; + + assert(info == NULL || raise); + + ticks = GetTickCount64(); + Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); + t = (_PyTime_t)ticks; + + if (_PyTime_check_mul_overflow(t, MS_TO_NS)) { + if (raise) { + _PyTime_overflow(); + return -1; + } + /* Hello, time traveler! */ + Py_UNREACHABLE(); + } + *tp = t * MS_TO_NS; + + if (info) { + DWORD timeAdjustment, timeIncrement; + BOOL isTimeAdjustmentDisabled, ok; + info->implementation = "GetTickCount64()"; + info->monotonic = 1; + ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, + &isTimeAdjustmentDisabled); + if (!ok) { + PyErr_SetFromWindowsErr(0); + return -1; + } + info->resolution = timeIncrement * 1e-7; + info->adjustable = 0; + } + +#elif defined(__APPLE__) + static mach_timebase_info_data_t timebase; + static uint64_t t0 = 0; + uint64_t ticks; + + if (timebase.denom == 0) { + /* According to the Technical Q&A QA1398, mach_timebase_info() cannot + fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ + (void)mach_timebase_info(&timebase); + + /* Sanity check: should never occur in practice */ + if (timebase.numer < 1 || timebase.denom < 1) { + PyErr_SetString(PyExc_RuntimeError, + "invalid mach_timebase_info"); + return -1; + } + + /* Check that timebase.numer and timebase.denom can be casted to + _PyTime_t. In practice, timebase uses uint32_t, so casting cannot + overflow. At the end, only make sure that the type is uint32_t + (_PyTime_t is 64-bit long). */ + assert(sizeof(timebase.numer) < sizeof(_PyTime_t)); + assert(sizeof(timebase.denom) < sizeof(_PyTime_t)); + + /* Make sure that (ticks * timebase.numer) cannot overflow in + _PyTime_MulDiv(), with ticks < timebase.denom. + + Known time bases: + + * always (1, 1) on Intel + * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC + + None of these time bases can overflow with 64-bit _PyTime_t, but + check for overflow, just in case. */ + if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) { + PyErr_SetString(PyExc_OverflowError, + "mach_timebase_info is too large"); + return -1; + } + + t0 = mach_absolute_time(); + } + + if (info) { + info->implementation = "mach_absolute_time()"; + info->resolution = (double)timebase.numer / (double)timebase.denom * 1e-9; + info->monotonic = 1; + info->adjustable = 0; + } + + ticks = mach_absolute_time(); + /* Use a "time zero" to reduce precision loss when converting time + to floatting point number, as in time.monotonic(). */ + ticks -= t0; + *tp = _PyTime_MulDiv(ticks, + (_PyTime_t)timebase.numer, + (_PyTime_t)timebase.denom); + +#elif defined(__hpux) + hrtime_t time; + + time = gethrtime(); + if (time == -1) { + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + } + return -1; + } + + *tp = time; + + if (info) { + info->implementation = "gethrtime()"; + info->resolution = 1e-9; + info->monotonic = 1; + info->adjustable = 0; + } + +#else + struct timespec ts; +#ifdef CLOCK_HIGHRES + const clockid_t clk_id = CLOCK_HIGHRES; + const char *implementation = "clock_gettime(CLOCK_HIGHRES)"; +#else + const clockid_t clk_id = CLOCK_MONOTONIC; + const char *implementation = "clock_gettime(CLOCK_MONOTONIC)"; +#endif + + assert(info == NULL || raise); + + if (clock_gettime(clk_id, &ts) != 0) { + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return -1; + } + + if (info) { + struct timespec res; + info->monotonic = 1; + info->implementation = implementation; + info->adjustable = 0; + if (clock_getres(clk_id, &res) != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + } + if (pytime_fromtimespec(tp, &ts, raise) < 0) { + return -1; + } +#endif + return 0; +} + +_PyTime_t +_PyTime_GetMonotonicClock(void) +{ + _PyTime_t t; + if (pymonotonic(&t, NULL, 0) < 0) { + /* should not happen, _PyTime_Init() checked that monotonic clock at + startup */ + Py_UNREACHABLE(); + } + return t; +} + +int +_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +{ + return pymonotonic(tp, info, 1); +} + + +#ifdef MS_WINDOWS +static int +win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info) +{ + static LONGLONG frequency = 0; + static LONGLONG t0 = 0; + LARGE_INTEGER now; + LONGLONG ticksll; + _PyTime_t ticks; + + if (frequency == 0) { + LARGE_INTEGER freq; + if (!QueryPerformanceFrequency(&freq)) { + PyErr_SetFromWindowsErr(0); + return -1; + } + frequency = freq.QuadPart; + + /* Sanity check: should never occur in practice */ + if (frequency < 1) { + PyErr_SetString(PyExc_RuntimeError, + "invalid QueryPerformanceFrequency"); + return -1; + } + + /* Check that frequency can be casted to _PyTime_t. + + Make also sure that (ticks * SEC_TO_NS) cannot overflow in + _PyTime_MulDiv(), with ticks < frequency. + + Known QueryPerformanceFrequency() values: + + * 10,000,000 (10 MHz): 100 ns resolution + * 3,579,545 Hz (3.6 MHz): 279 ns resolution + + None of these frequencies can overflow with 64-bit _PyTime_t, but + check for overflow, just in case. */ + if (frequency > _PyTime_MAX + || frequency > (LONGLONG)_PyTime_MAX / (LONGLONG)SEC_TO_NS) { + PyErr_SetString(PyExc_OverflowError, + "QueryPerformanceFrequency is too large"); + return -1; + } + + QueryPerformanceCounter(&now); + t0 = now.QuadPart; + } + + if (info) { + info->implementation = "QueryPerformanceCounter()"; + info->resolution = 1.0 / (double)frequency; + info->monotonic = 1; + info->adjustable = 0; + } + + QueryPerformanceCounter(&now); + ticksll = now.QuadPart; + + /* Use a "time zero" to reduce precision loss when converting time + to floatting point number, as in time.perf_counter(). */ + ticksll -= t0; + + /* Make sure that casting LONGLONG to _PyTime_t cannot overflow, + both types are signed */ + Py_BUILD_ASSERT(sizeof(ticksll) <= sizeof(ticks)); + ticks = (_PyTime_t)ticksll; + + *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency); + return 0; +} +#endif + + +int +_PyTime_GetPerfCounterWithInfo(_PyTime_t *t, _Py_clock_info_t *info) +{ +#ifdef MS_WINDOWS + return win_perf_counter(t, info); +#else + return _PyTime_GetMonotonicClockWithInfo(t, info); +#endif +} + + +_PyTime_t +_PyTime_GetPerfCounter(void) +{ + _PyTime_t t; + if (_PyTime_GetPerfCounterWithInfo(&t, NULL)) { + Py_UNREACHABLE(); + } + return t; +} + + +int +_PyTime_Init(void) +{ + /* check that time.time(), time.monotonic() and time.perf_counter() clocks + are working properly to not have to check for exceptions at runtime. If + a clock works once, it cannot fail in next calls. */ + _PyTime_t t; + if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0) { + return -1; + } + if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) { + return -1; + } + if (_PyTime_GetPerfCounterWithInfo(&t, NULL) < 0) { + return -1; + } + return 0; +} + +int +_PyTime_localtime(time_t t, struct tm *tm) +{ +#ifdef MS_WINDOWS + int error; + + error = localtime_s(tm, &t); + if (error != 0) { + errno = error; + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return 0; +#else /* !MS_WINDOWS */ + +#ifdef _AIX + /* bpo-34373: AIX does not return NULL if t is too small or too large */ + if (t < -2145916800 /* 1902-01-01 */ + || t > 2145916800 /* 2038-01-01 */) { + errno = EINVAL; + PyErr_SetString(PyExc_OverflowError, + "localtime argument out of range"); + return -1; + } +#endif + + errno = 0; + if (localtime_r(&t, tm) == NULL) { + if (errno == 0) { + errno = EINVAL; + } + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return 0; +#endif /* MS_WINDOWS */ +} + +int +_PyTime_gmtime(time_t t, struct tm *tm) +{ +#ifdef MS_WINDOWS + int error; + + error = gmtime_s(tm, &t); + if (error != 0) { + errno = error; + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return 0; +#else /* !MS_WINDOWS */ + if (gmtime_r(&t, tm) == NULL) { +#ifdef EINVAL + if (errno == 0) { + errno = EINVAL; + } +#endif + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return 0; +#endif /* MS_WINDOWS */ +} diff --git a/python/Python/strdup.c b/python/Python/strdup.c new file mode 100755 index 0000000..af39a1e --- /dev/null +++ b/python/Python/strdup.c @@ -0,0 +1,14 @@ +/* strdup() replacement (from stdwin, if you must know) */ +#include +#include + +char * +strdup(const char *str) +{ + if (str != NULL) { + char *copy = (char *)malloc((int)(strlen(str) + 1)); + if (copy != NULL) + return strcpy(copy, str); + } + return NULL; +} diff --git a/python/Python/structmember.c b/python/Python/structmember.c new file mode 100755 index 0000000..e653d02 --- /dev/null +++ b/python/Python/structmember.c @@ -0,0 +1,292 @@ + +/* Map C struct members to Python object attributes */ + +#include "Python.h" + +#include "structmember.h" + +PyObject * +PyMember_GetOne(const char *addr, PyMemberDef *l) +{ + PyObject *v; + + addr += l->offset; + switch (l->type) { + case T_BOOL: + v = PyBool_FromLong(*(char*)addr); + break; + case T_BYTE: + v = PyLong_FromLong(*(char*)addr); + break; + case T_UBYTE: + v = PyLong_FromUnsignedLong(*(unsigned char*)addr); + break; + case T_SHORT: + v = PyLong_FromLong(*(short*)addr); + break; + case T_USHORT: + v = PyLong_FromUnsignedLong(*(unsigned short*)addr); + break; + case T_INT: + v = PyLong_FromLong(*(int*)addr); + break; + case T_UINT: + v = PyLong_FromUnsignedLong(*(unsigned int*)addr); + break; + case T_LONG: + v = PyLong_FromLong(*(long*)addr); + break; + case T_ULONG: + v = PyLong_FromUnsignedLong(*(unsigned long*)addr); + break; + case T_PYSSIZET: + v = PyLong_FromSsize_t(*(Py_ssize_t*)addr); + break; + case T_FLOAT: + v = PyFloat_FromDouble((double)*(float*)addr); + break; + case T_DOUBLE: + v = PyFloat_FromDouble(*(double*)addr); + break; + case T_STRING: + if (*(char**)addr == NULL) { + Py_INCREF(Py_None); + v = Py_None; + } + else + v = PyUnicode_FromString(*(char**)addr); + break; + case T_STRING_INPLACE: + v = PyUnicode_FromString((char*)addr); + break; + case T_CHAR: + v = PyUnicode_FromStringAndSize((char*)addr, 1); + break; + case T_OBJECT: + v = *(PyObject **)addr; + if (v == NULL) + v = Py_None; + Py_INCREF(v); + break; + case T_OBJECT_EX: + v = *(PyObject **)addr; + if (v == NULL) + PyErr_SetString(PyExc_AttributeError, l->name); + Py_XINCREF(v); + break; + case T_LONGLONG: + v = PyLong_FromLongLong(*(long long *)addr); + break; + case T_ULONGLONG: + v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr); + break; + case T_NONE: + v = Py_None; + Py_INCREF(v); + break; + default: + PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); + v = NULL; + } + return v; +} + +#define WARN(msg) \ + do { \ + if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) \ + return -1; \ + } while (0) + +int +PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) +{ + PyObject *oldv; + + addr += l->offset; + + if ((l->flags & READONLY)) + { + PyErr_SetString(PyExc_AttributeError, "readonly attribute"); + return -1; + } + if (v == NULL) { + if (l->type == T_OBJECT_EX) { + /* Check if the attribute is set. */ + if (*(PyObject **)addr == NULL) { + PyErr_SetString(PyExc_AttributeError, l->name); + return -1; + } + } + else if (l->type != T_OBJECT) { + PyErr_SetString(PyExc_TypeError, + "can't delete numeric/char attribute"); + return -1; + } + } + switch (l->type) { + case T_BOOL:{ + if (!PyBool_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "attribute value type must be bool"); + return -1; + } + if (v == Py_True) + *(char*)addr = (char) 1; + else + *(char*)addr = (char) 0; + break; + } + case T_BYTE:{ + long long_val = PyLong_AsLong(v); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + *(char*)addr = (char)long_val; + /* XXX: For compatibility, only warn about truncations + for now. */ + if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN)) + WARN("Truncation of value to char"); + break; + } + case T_UBYTE:{ + long long_val = PyLong_AsLong(v); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + *(unsigned char*)addr = (unsigned char)long_val; + if ((long_val > UCHAR_MAX) || (long_val < 0)) + WARN("Truncation of value to unsigned char"); + break; + } + case T_SHORT:{ + long long_val = PyLong_AsLong(v); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + *(short*)addr = (short)long_val; + if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN)) + WARN("Truncation of value to short"); + break; + } + case T_USHORT:{ + long long_val = PyLong_AsLong(v); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + *(unsigned short*)addr = (unsigned short)long_val; + if ((long_val > USHRT_MAX) || (long_val < 0)) + WARN("Truncation of value to unsigned short"); + break; + } + case T_INT:{ + long long_val = PyLong_AsLong(v); + if ((long_val == -1) && PyErr_Occurred()) + return -1; + *(int *)addr = (int)long_val; + if ((long_val > INT_MAX) || (long_val < INT_MIN)) + WARN("Truncation of value to int"); + break; + } + case T_UINT:{ + unsigned long ulong_val = PyLong_AsUnsignedLong(v); + if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) { + /* XXX: For compatibility, accept negative int values + as well. */ + PyErr_Clear(); + ulong_val = PyLong_AsLong(v); + if ((ulong_val == (unsigned long)-1) && + PyErr_Occurred()) + return -1; + *(unsigned int *)addr = (unsigned int)ulong_val; + WARN("Writing negative value into unsigned field"); + } else + *(unsigned int *)addr = (unsigned int)ulong_val; + if (ulong_val > UINT_MAX) + WARN("Truncation of value to unsigned int"); + break; + } + case T_LONG:{ + *(long*)addr = PyLong_AsLong(v); + if ((*(long*)addr == -1) && PyErr_Occurred()) + return -1; + break; + } + case T_ULONG:{ + *(unsigned long*)addr = PyLong_AsUnsignedLong(v); + if ((*(unsigned long*)addr == (unsigned long)-1) + && PyErr_Occurred()) { + /* XXX: For compatibility, accept negative int values + as well. */ + PyErr_Clear(); + *(unsigned long*)addr = PyLong_AsLong(v); + if ((*(unsigned long*)addr == (unsigned long)-1) + && PyErr_Occurred()) + return -1; + WARN("Writing negative value into unsigned field"); + } + break; + } + case T_PYSSIZET:{ + *(Py_ssize_t*)addr = PyLong_AsSsize_t(v); + if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) + && PyErr_Occurred()) + return -1; + break; + } + case T_FLOAT:{ + double double_val = PyFloat_AsDouble(v); + if ((double_val == -1) && PyErr_Occurred()) + return -1; + *(float*)addr = (float)double_val; + break; + } + case T_DOUBLE: + *(double*)addr = PyFloat_AsDouble(v); + if ((*(double*)addr == -1) && PyErr_Occurred()) + return -1; + break; + case T_OBJECT: + case T_OBJECT_EX: + Py_XINCREF(v); + oldv = *(PyObject **)addr; + *(PyObject **)addr = v; + Py_XDECREF(oldv); + break; + case T_CHAR: { + const char *string; + Py_ssize_t len; + + string = PyUnicode_AsUTF8AndSize(v, &len); + if (string == NULL || len != 1) { + PyErr_BadArgument(); + return -1; + } + *(char*)addr = string[0]; + break; + } + case T_STRING: + case T_STRING_INPLACE: + PyErr_SetString(PyExc_TypeError, "readonly attribute"); + return -1; + case T_LONGLONG:{ + long long value; + *(long long*)addr = value = PyLong_AsLongLong(v); + if ((value == -1) && PyErr_Occurred()) + return -1; + break; + } + case T_ULONGLONG:{ + unsigned long long value; + /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong + doesn't ??? */ + if (PyLong_Check(v)) + *(unsigned long long*)addr = value = PyLong_AsUnsignedLongLong(v); + else + *(unsigned long long*)addr = value = PyLong_AsLong(v); + if ((value == (unsigned long long)-1) && PyErr_Occurred()) + return -1; + break; + } + default: + PyErr_Format(PyExc_SystemError, + "bad memberdescr type for %s", l->name); + return -1; + } + return 0; +} diff --git a/python/Python/symtable.c b/python/Python/symtable.c new file mode 100755 index 0000000..30482d9 --- /dev/null +++ b/python/Python/symtable.c @@ -0,0 +1,1956 @@ +#include "Python.h" +#include "pycore_pystate.h" +#include "symtable.h" +#undef Yield /* undefine macro conflicting with */ +#include "structmember.h" + +/* error strings used for warnings */ +#define GLOBAL_PARAM \ +"name '%U' is parameter and global" + +#define NONLOCAL_PARAM \ +"name '%U' is parameter and nonlocal" + +#define GLOBAL_AFTER_ASSIGN \ +"name '%U' is assigned to before global declaration" + +#define NONLOCAL_AFTER_ASSIGN \ +"name '%U' is assigned to before nonlocal declaration" + +#define GLOBAL_AFTER_USE \ +"name '%U' is used prior to global declaration" + +#define NONLOCAL_AFTER_USE \ +"name '%U' is used prior to nonlocal declaration" + +#define GLOBAL_ANNOT \ +"annotated name '%U' can't be global" + +#define NONLOCAL_ANNOT \ +"annotated name '%U' can't be nonlocal" + +#define IMPORT_STAR_WARNING "import * only allowed at module level" + +#define NAMED_EXPR_COMP_IN_CLASS \ +"assignment expression within a comprehension cannot be used in a class body" + +#define NAMED_EXPR_COMP_CONFLICT \ +"assignment expression cannot rebind comprehension iteration variable '%U'" + +#define NAMED_EXPR_COMP_INNER_LOOP_CONFLICT \ +"comprehension inner loop cannot rebind assignment expression target '%U'" + +#define NAMED_EXPR_COMP_ITER_EXPR \ +"assignment expression cannot be used in a comprehension iterable expression" + +static PySTEntryObject * +ste_new(struct symtable *st, identifier name, _Py_block_ty block, + void *key, int lineno, int col_offset) +{ + PySTEntryObject *ste = NULL; + PyObject *k = NULL; + + k = PyLong_FromVoidPtr(key); + if (k == NULL) + goto fail; + ste = PyObject_New(PySTEntryObject, &PySTEntry_Type); + if (ste == NULL) { + Py_DECREF(k); + goto fail; + } + ste->ste_table = st; + ste->ste_id = k; /* ste owns reference to k */ + + Py_INCREF(name); + ste->ste_name = name; + + ste->ste_symbols = NULL; + ste->ste_varnames = NULL; + ste->ste_children = NULL; + + ste->ste_directives = NULL; + + ste->ste_type = block; + ste->ste_nested = 0; + ste->ste_free = 0; + ste->ste_varargs = 0; + ste->ste_varkeywords = 0; + ste->ste_opt_lineno = 0; + ste->ste_opt_col_offset = 0; + ste->ste_lineno = lineno; + ste->ste_col_offset = col_offset; + + if (st->st_cur != NULL && + (st->st_cur->ste_nested || + st->st_cur->ste_type == FunctionBlock)) + ste->ste_nested = 1; + ste->ste_child_free = 0; + ste->ste_generator = 0; + ste->ste_coroutine = 0; + ste->ste_comprehension = 0; + ste->ste_returns_value = 0; + ste->ste_needs_class_closure = 0; + ste->ste_comp_iter_target = 0; + ste->ste_comp_iter_expr = 0; + + ste->ste_symbols = PyDict_New(); + ste->ste_varnames = PyList_New(0); + ste->ste_children = PyList_New(0); + if (ste->ste_symbols == NULL + || ste->ste_varnames == NULL + || ste->ste_children == NULL) + goto fail; + + if (PyDict_SetItem(st->st_blocks, ste->ste_id, (PyObject *)ste) < 0) + goto fail; + + return ste; + fail: + Py_XDECREF(ste); + return NULL; +} + +static PyObject * +ste_repr(PySTEntryObject *ste) +{ + return PyUnicode_FromFormat("", + ste->ste_name, + PyLong_AS_LONG(ste->ste_id), ste->ste_lineno); +} + +static void +ste_dealloc(PySTEntryObject *ste) +{ + ste->ste_table = NULL; + Py_XDECREF(ste->ste_id); + Py_XDECREF(ste->ste_name); + Py_XDECREF(ste->ste_symbols); + Py_XDECREF(ste->ste_varnames); + Py_XDECREF(ste->ste_children); + Py_XDECREF(ste->ste_directives); + PyObject_Del(ste); +} + +#define OFF(x) offsetof(PySTEntryObject, x) + +static PyMemberDef ste_memberlist[] = { + {"id", T_OBJECT, OFF(ste_id), READONLY}, + {"name", T_OBJECT, OFF(ste_name), READONLY}, + {"symbols", T_OBJECT, OFF(ste_symbols), READONLY}, + {"varnames", T_OBJECT, OFF(ste_varnames), READONLY}, + {"children", T_OBJECT, OFF(ste_children), READONLY}, + {"nested", T_INT, OFF(ste_nested), READONLY}, + {"type", T_INT, OFF(ste_type), READONLY}, + {"lineno", T_INT, OFF(ste_lineno), READONLY}, + {NULL} +}; + +PyTypeObject PySTEntry_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "symtable entry", + sizeof(PySTEntryObject), + 0, + (destructor)ste_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)ste_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + ste_memberlist, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +static int symtable_analyze(struct symtable *st); +static int symtable_enter_block(struct symtable *st, identifier name, + _Py_block_ty block, void *ast, int lineno, + int col_offset); +static int symtable_exit_block(struct symtable *st, void *ast); +static int symtable_visit_stmt(struct symtable *st, stmt_ty s); +static int symtable_visit_expr(struct symtable *st, expr_ty s); +static int symtable_visit_genexp(struct symtable *st, expr_ty s); +static int symtable_visit_listcomp(struct symtable *st, expr_ty s); +static int symtable_visit_setcomp(struct symtable *st, expr_ty s); +static int symtable_visit_dictcomp(struct symtable *st, expr_ty s); +static int symtable_visit_arguments(struct symtable *st, arguments_ty); +static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty); +static int symtable_visit_alias(struct symtable *st, alias_ty); +static int symtable_visit_comprehension(struct symtable *st, comprehension_ty); +static int symtable_visit_keyword(struct symtable *st, keyword_ty); +static int symtable_visit_slice(struct symtable *st, slice_ty); +static int symtable_visit_params(struct symtable *st, asdl_seq *args); +static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args); +static int symtable_implicit_arg(struct symtable *st, int pos); +static int symtable_visit_annotations(struct symtable *st, stmt_ty s, arguments_ty, expr_ty); +static int symtable_visit_withitem(struct symtable *st, withitem_ty item); + + +static identifier top = NULL, lambda = NULL, genexpr = NULL, + listcomp = NULL, setcomp = NULL, dictcomp = NULL, + __class__ = NULL; + +#define GET_IDENTIFIER(VAR) \ + ((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR))) + +#define DUPLICATE_ARGUMENT \ +"duplicate argument '%U' in function definition" + +static struct symtable * +symtable_new(void) +{ + struct symtable *st; + + st = (struct symtable *)PyMem_Malloc(sizeof(struct symtable)); + if (st == NULL) { + PyErr_NoMemory(); + return NULL; + } + + st->st_filename = NULL; + st->st_blocks = NULL; + + if ((st->st_stack = PyList_New(0)) == NULL) + goto fail; + if ((st->st_blocks = PyDict_New()) == NULL) + goto fail; + st->st_cur = NULL; + st->st_private = NULL; + return st; + fail: + PySymtable_Free(st); + return NULL; +} + +/* When compiling the use of C stack is probably going to be a lot + lighter than when executing Python code but still can overflow + and causing a Python crash if not checked (e.g. eval("()"*300000)). + Using the current recursion limit for the compiler seems too + restrictive (it caused at least one test to fail) so a factor is + used to allow deeper recursion when compiling an expression. + + Using a scaling factor means this should automatically adjust when + the recursion limit is adjusted for small or large C stack allocations. +*/ +#define COMPILER_STACK_FRAME_SCALE 3 + +struct symtable * +PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) +{ + struct symtable *st = symtable_new(); + asdl_seq *seq; + int i; + PyThreadState *tstate; + int recursion_limit = Py_GetRecursionLimit(); + int starting_recursion_depth; + + if (st == NULL) + return NULL; + if (filename == NULL) { + PySymtable_Free(st); + return NULL; + } + Py_INCREF(filename); + st->st_filename = filename; + st->st_future = future; + + /* Setup recursion depth check counters */ + tstate = _PyThreadState_GET(); + if (!tstate) { + PySymtable_Free(st); + return NULL; + } + /* Be careful here to prevent overflow. */ + starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? + tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth; + st->recursion_depth = starting_recursion_depth; + st->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? + recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; + + /* Make the initial symbol information gathering pass */ + if (!GET_IDENTIFIER(top) || + !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0)) { + PySymtable_Free(st); + return NULL; + } + + st->st_top = st->st_cur; + switch (mod->kind) { + case Module_kind: + seq = mod->v.Module.body; + for (i = 0; i < asdl_seq_LEN(seq); i++) + if (!symtable_visit_stmt(st, + (stmt_ty)asdl_seq_GET(seq, i))) + goto error; + break; + case Expression_kind: + if (!symtable_visit_expr(st, mod->v.Expression.body)) + goto error; + break; + case Interactive_kind: + seq = mod->v.Interactive.body; + for (i = 0; i < asdl_seq_LEN(seq); i++) + if (!symtable_visit_stmt(st, + (stmt_ty)asdl_seq_GET(seq, i))) + goto error; + break; + case Suite_kind: + PyErr_SetString(PyExc_RuntimeError, + "this compiler does not handle Suites"); + goto error; + case FunctionType_kind: + PyErr_SetString(PyExc_RuntimeError, + "this compiler does not handle FunctionTypes"); + goto error; + } + if (!symtable_exit_block(st, (void *)mod)) { + PySymtable_Free(st); + return NULL; + } + /* Check that the recursion depth counting balanced correctly */ + if (st->recursion_depth != starting_recursion_depth) { + PyErr_Format(PyExc_SystemError, + "symtable analysis recursion depth mismatch (before=%d, after=%d)", + starting_recursion_depth, st->recursion_depth); + PySymtable_Free(st); + return NULL; + } + /* Make the second symbol analysis pass */ + if (symtable_analyze(st)) + return st; + PySymtable_Free(st); + return NULL; + error: + (void) symtable_exit_block(st, (void *)mod); + PySymtable_Free(st); + return NULL; +} + +struct symtable * +PySymtable_Build(mod_ty mod, const char *filename_str, PyFutureFeatures *future) +{ + PyObject *filename; + struct symtable *st; + filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) + return NULL; + st = PySymtable_BuildObject(mod, filename, future); + Py_DECREF(filename); + return st; +} + +void +PySymtable_Free(struct symtable *st) +{ + Py_XDECREF(st->st_filename); + Py_XDECREF(st->st_blocks); + Py_XDECREF(st->st_stack); + PyMem_Free((void *)st); +} + +PySTEntryObject * +PySymtable_Lookup(struct symtable *st, void *key) +{ + PyObject *k, *v; + + k = PyLong_FromVoidPtr(key); + if (k == NULL) + return NULL; + v = PyDict_GetItemWithError(st->st_blocks, k); + if (v) { + assert(PySTEntry_Check(v)); + Py_INCREF(v); + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_KeyError, + "unknown symbol table entry"); + } + + Py_DECREF(k); + return (PySTEntryObject *)v; +} + +static long +_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name) +{ + PyObject *v = PyDict_GetItem(ste->ste_symbols, name); + if (!v) + return 0; + assert(PyLong_Check(v)); + return PyLong_AS_LONG(v); +} + +int +PyST_GetScope(PySTEntryObject *ste, PyObject *name) +{ + long symbol = _PyST_GetSymbol(ste, name); + return (symbol >> SCOPE_OFFSET) & SCOPE_MASK; +} + +static int +error_at_directive(PySTEntryObject *ste, PyObject *name) +{ + Py_ssize_t i; + PyObject *data; + assert(ste->ste_directives); + for (i = 0; i < PyList_GET_SIZE(ste->ste_directives); i++) { + data = PyList_GET_ITEM(ste->ste_directives, i); + assert(PyTuple_CheckExact(data)); + assert(PyUnicode_CheckExact(PyTuple_GET_ITEM(data, 0))); + if (PyUnicode_Compare(PyTuple_GET_ITEM(data, 0), name) == 0) { + PyErr_SyntaxLocationObject(ste->ste_table->st_filename, + PyLong_AsLong(PyTuple_GET_ITEM(data, 1)), + PyLong_AsLong(PyTuple_GET_ITEM(data, 2)) + 1); + + return 0; + } + } + PyErr_SetString(PyExc_RuntimeError, + "BUG: internal directive bookkeeping broken"); + return 0; +} + + +/* Analyze raw symbol information to determine scope of each name. + + The next several functions are helpers for symtable_analyze(), + which determines whether a name is local, global, or free. In addition, + it determines which local variables are cell variables; they provide + bindings that are used for free variables in enclosed blocks. + + There are also two kinds of global variables, implicit and explicit. An + explicit global is declared with the global statement. An implicit + global is a free variable for which the compiler has found no binding + in an enclosing function scope. The implicit global is either a global + or a builtin. Python's module and class blocks use the xxx_NAME opcodes + to handle these names to implement slightly odd semantics. In such a + block, the name is treated as global until it is assigned to; then it + is treated as a local. + + The symbol table requires two passes to determine the scope of each name. + The first pass collects raw facts from the AST via the symtable_visit_* + functions: the name is a parameter here, the name is used but not defined + here, etc. The second pass analyzes these facts during a pass over the + PySTEntryObjects created during pass 1. + + When a function is entered during the second pass, the parent passes + the set of all name bindings visible to its children. These bindings + are used to determine if non-local variables are free or implicit globals. + Names which are explicitly declared nonlocal must exist in this set of + visible names - if they do not, a syntax error is raised. After doing + the local analysis, it analyzes each of its child blocks using an + updated set of name bindings. + + The children update the free variable set. If a local variable is added to + the free variable set by the child, the variable is marked as a cell. The + function object being defined must provide runtime storage for the variable + that may outlive the function's frame. Cell variables are removed from the + free set before the analyze function returns to its parent. + + During analysis, the names are: + symbols: dict mapping from symbol names to flag values (including offset scope values) + scopes: dict mapping from symbol names to scope values (no offset) + local: set of all symbol names local to the current scope + bound: set of all symbol names local to a containing function scope + free: set of all symbol names referenced but not bound in child scopes + global: set of all symbol names explicitly declared as global +*/ + +#define SET_SCOPE(DICT, NAME, I) { \ + PyObject *o = PyLong_FromLong(I); \ + if (!o) \ + return 0; \ + if (PyDict_SetItem((DICT), (NAME), o) < 0) { \ + Py_DECREF(o); \ + return 0; \ + } \ + Py_DECREF(o); \ +} + +/* Decide on scope of name, given flags. + + The namespace dictionaries may be modified to record information + about the new name. For example, a new global will add an entry to + global. A name that was global can be changed to local. +*/ + +static int +analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, + PyObject *bound, PyObject *local, PyObject *free, + PyObject *global) +{ + if (flags & DEF_GLOBAL) { + if (flags & DEF_NONLOCAL) { + PyErr_Format(PyExc_SyntaxError, + "name '%U' is nonlocal and global", + name); + return error_at_directive(ste, name); + } + SET_SCOPE(scopes, name, GLOBAL_EXPLICIT); + if (PySet_Add(global, name) < 0) + return 0; + if (bound && (PySet_Discard(bound, name) < 0)) + return 0; + return 1; + } + if (flags & DEF_NONLOCAL) { + if (!bound) { + PyErr_Format(PyExc_SyntaxError, + "nonlocal declaration not allowed at module level"); + return error_at_directive(ste, name); + } + if (!PySet_Contains(bound, name)) { + PyErr_Format(PyExc_SyntaxError, + "no binding for nonlocal '%U' found", + name); + + return error_at_directive(ste, name); + } + SET_SCOPE(scopes, name, FREE); + ste->ste_free = 1; + return PySet_Add(free, name) >= 0; + } + if (flags & DEF_BOUND) { + SET_SCOPE(scopes, name, LOCAL); + if (PySet_Add(local, name) < 0) + return 0; + if (PySet_Discard(global, name) < 0) + return 0; + return 1; + } + /* If an enclosing block has a binding for this name, it + is a free variable rather than a global variable. + Note that having a non-NULL bound implies that the block + is nested. + */ + if (bound && PySet_Contains(bound, name)) { + SET_SCOPE(scopes, name, FREE); + ste->ste_free = 1; + return PySet_Add(free, name) >= 0; + } + /* If a parent has a global statement, then call it global + explicit? It could also be global implicit. + */ + if (global && PySet_Contains(global, name)) { + SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); + return 1; + } + if (ste->ste_nested) + ste->ste_free = 1; + SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); + return 1; +} + +#undef SET_SCOPE + +/* If a name is defined in free and also in locals, then this block + provides the binding for the free variable. The name should be + marked CELL in this block and removed from the free list. + + Note that the current block's free variables are included in free. + That's safe because no name can be free and local in the same scope. +*/ + +static int +analyze_cells(PyObject *scopes, PyObject *free) +{ + PyObject *name, *v, *v_cell; + int success = 0; + Py_ssize_t pos = 0; + + v_cell = PyLong_FromLong(CELL); + if (!v_cell) + return 0; + while (PyDict_Next(scopes, &pos, &name, &v)) { + long scope; + assert(PyLong_Check(v)); + scope = PyLong_AS_LONG(v); + if (scope != LOCAL) + continue; + if (!PySet_Contains(free, name)) + continue; + /* Replace LOCAL with CELL for this name, and remove + from free. It is safe to replace the value of name + in the dict, because it will not cause a resize. + */ + if (PyDict_SetItem(scopes, name, v_cell) < 0) + goto error; + if (PySet_Discard(free, name) < 0) + goto error; + } + success = 1; + error: + Py_DECREF(v_cell); + return success; +} + +static int +drop_class_free(PySTEntryObject *ste, PyObject *free) +{ + int res; + if (!GET_IDENTIFIER(__class__)) + return 0; + res = PySet_Discard(free, __class__); + if (res < 0) + return 0; + if (res) + ste->ste_needs_class_closure = 1; + return 1; +} + +/* Enter the final scope information into the ste_symbols dict. + * + * All arguments are dicts. Modifies symbols, others are read-only. +*/ +static int +update_symbols(PyObject *symbols, PyObject *scopes, + PyObject *bound, PyObject *free, int classflag) +{ + PyObject *name = NULL, *itr = NULL; + PyObject *v = NULL, *v_scope = NULL, *v_new = NULL, *v_free = NULL; + Py_ssize_t pos = 0; + + /* Update scope information for all symbols in this scope */ + while (PyDict_Next(symbols, &pos, &name, &v)) { + long scope, flags; + assert(PyLong_Check(v)); + flags = PyLong_AS_LONG(v); + v_scope = PyDict_GetItem(scopes, name); + assert(v_scope && PyLong_Check(v_scope)); + scope = PyLong_AS_LONG(v_scope); + flags |= (scope << SCOPE_OFFSET); + v_new = PyLong_FromLong(flags); + if (!v_new) + return 0; + if (PyDict_SetItem(symbols, name, v_new) < 0) { + Py_DECREF(v_new); + return 0; + } + Py_DECREF(v_new); + } + + /* Record not yet resolved free variables from children (if any) */ + v_free = PyLong_FromLong(FREE << SCOPE_OFFSET); + if (!v_free) + return 0; + + itr = PyObject_GetIter(free); + if (itr == NULL) { + Py_DECREF(v_free); + return 0; + } + + while ((name = PyIter_Next(itr))) { + v = PyDict_GetItemWithError(symbols, name); + + /* Handle symbol that already exists in this scope */ + if (v) { + /* Handle a free variable in a method of + the class that has the same name as a local + or global in the class scope. + */ + if (classflag && + PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) { + long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS; + v_new = PyLong_FromLong(flags); + if (!v_new) { + goto error; + } + if (PyDict_SetItem(symbols, name, v_new) < 0) { + Py_DECREF(v_new); + goto error; + } + Py_DECREF(v_new); + } + /* It's a cell, or already free in this scope */ + Py_DECREF(name); + continue; + } + else if (PyErr_Occurred()) { + goto error; + } + /* Handle global symbol */ + if (bound && !PySet_Contains(bound, name)) { + Py_DECREF(name); + continue; /* it's a global */ + } + /* Propagate new free symbol up the lexical stack */ + if (PyDict_SetItem(symbols, name, v_free) < 0) { + goto error; + } + Py_DECREF(name); + } + Py_DECREF(itr); + Py_DECREF(v_free); + return 1; +error: + Py_XDECREF(v_free); + Py_XDECREF(itr); + Py_XDECREF(name); + return 0; +} + +/* Make final symbol table decisions for block of ste. + + Arguments: + ste -- current symtable entry (input/output) + bound -- set of variables bound in enclosing scopes (input). bound + is NULL for module blocks. + free -- set of free variables in enclosed scopes (output) + globals -- set of declared global variables in enclosing scopes (input) + + The implementation uses two mutually recursive functions, + analyze_block() and analyze_child_block(). analyze_block() is + responsible for analyzing the individual names defined in a block. + analyze_child_block() prepares temporary namespace dictionaries + used to evaluated nested blocks. + + The two functions exist because a child block should see the name + bindings of its enclosing blocks, but those bindings should not + propagate back to a parent block. +*/ + +static int +analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, + PyObject *global, PyObject* child_free); + +static int +analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, + PyObject *global) +{ + PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL; + PyObject *newglobal = NULL, *newfree = NULL, *allfree = NULL; + PyObject *temp; + int i, success = 0; + Py_ssize_t pos = 0; + + local = PySet_New(NULL); /* collect new names bound in block */ + if (!local) + goto error; + scopes = PyDict_New(); /* collect scopes defined for each name */ + if (!scopes) + goto error; + + /* Allocate new global and bound variable dictionaries. These + dictionaries hold the names visible in nested blocks. For + ClassBlocks, the bound and global names are initialized + before analyzing names, because class bindings aren't + visible in methods. For other blocks, they are initialized + after names are analyzed. + */ + + /* TODO(jhylton): Package these dicts in a struct so that we + can write reasonable helper functions? + */ + newglobal = PySet_New(NULL); + if (!newglobal) + goto error; + newfree = PySet_New(NULL); + if (!newfree) + goto error; + newbound = PySet_New(NULL); + if (!newbound) + goto error; + + /* Class namespace has no effect on names visible in + nested functions, so populate the global and bound + sets to be passed to child blocks before analyzing + this one. + */ + if (ste->ste_type == ClassBlock) { + /* Pass down known globals */ + temp = PyNumber_InPlaceOr(newglobal, global); + if (!temp) + goto error; + Py_DECREF(temp); + /* Pass down previously bound symbols */ + if (bound) { + temp = PyNumber_InPlaceOr(newbound, bound); + if (!temp) + goto error; + Py_DECREF(temp); + } + } + + while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) { + long flags = PyLong_AS_LONG(v); + if (!analyze_name(ste, scopes, name, flags, + bound, local, free, global)) + goto error; + } + + /* Populate global and bound sets to be passed to children. */ + if (ste->ste_type != ClassBlock) { + /* Add function locals to bound set */ + if (ste->ste_type == FunctionBlock) { + temp = PyNumber_InPlaceOr(newbound, local); + if (!temp) + goto error; + Py_DECREF(temp); + } + /* Pass down previously bound symbols */ + if (bound) { + temp = PyNumber_InPlaceOr(newbound, bound); + if (!temp) + goto error; + Py_DECREF(temp); + } + /* Pass down known globals */ + temp = PyNumber_InPlaceOr(newglobal, global); + if (!temp) + goto error; + Py_DECREF(temp); + } + else { + /* Special-case __class__ */ + if (!GET_IDENTIFIER(__class__)) + goto error; + if (PySet_Add(newbound, __class__) < 0) + goto error; + } + + /* Recursively call analyze_child_block() on each child block. + + newbound, newglobal now contain the names visible in + nested blocks. The free variables in the children will + be collected in allfree. + */ + allfree = PySet_New(NULL); + if (!allfree) + goto error; + for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) { + PyObject *c = PyList_GET_ITEM(ste->ste_children, i); + PySTEntryObject* entry; + assert(c && PySTEntry_Check(c)); + entry = (PySTEntryObject*)c; + if (!analyze_child_block(entry, newbound, newfree, newglobal, + allfree)) + goto error; + /* Check if any children have free variables */ + if (entry->ste_free || entry->ste_child_free) + ste->ste_child_free = 1; + } + + temp = PyNumber_InPlaceOr(newfree, allfree); + if (!temp) + goto error; + Py_DECREF(temp); + + /* Check if any local variables must be converted to cell variables */ + if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree)) + goto error; + else if (ste->ste_type == ClassBlock && !drop_class_free(ste, newfree)) + goto error; + /* Records the results of the analysis in the symbol table entry */ + if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, + ste->ste_type == ClassBlock)) + goto error; + + temp = PyNumber_InPlaceOr(free, newfree); + if (!temp) + goto error; + Py_DECREF(temp); + success = 1; + error: + Py_XDECREF(scopes); + Py_XDECREF(local); + Py_XDECREF(newbound); + Py_XDECREF(newglobal); + Py_XDECREF(newfree); + Py_XDECREF(allfree); + if (!success) + assert(PyErr_Occurred()); + return success; +} + +static int +analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, + PyObject *global, PyObject* child_free) +{ + PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; + PyObject *temp; + + /* Copy the bound and global dictionaries. + + These dictionaries are used by all blocks enclosed by the + current block. The analyze_block() call modifies these + dictionaries. + + */ + temp_bound = PySet_New(bound); + if (!temp_bound) + goto error; + temp_free = PySet_New(free); + if (!temp_free) + goto error; + temp_global = PySet_New(global); + if (!temp_global) + goto error; + + if (!analyze_block(entry, temp_bound, temp_free, temp_global)) + goto error; + temp = PyNumber_InPlaceOr(child_free, temp_free); + if (!temp) + goto error; + Py_DECREF(temp); + Py_DECREF(temp_bound); + Py_DECREF(temp_free); + Py_DECREF(temp_global); + return 1; + error: + Py_XDECREF(temp_bound); + Py_XDECREF(temp_free); + Py_XDECREF(temp_global); + return 0; +} + +static int +symtable_analyze(struct symtable *st) +{ + PyObject *free, *global; + int r; + + free = PySet_New(NULL); + if (!free) + return 0; + global = PySet_New(NULL); + if (!global) { + Py_DECREF(free); + return 0; + } + r = analyze_block(st->st_top, NULL, free, global); + Py_DECREF(free); + Py_DECREF(global); + return r; +} + +/* symtable_enter_block() gets a reference via ste_new. + This reference is released when the block is exited, via the DECREF + in symtable_exit_block(). +*/ + +static int +symtable_exit_block(struct symtable *st, void *ast) +{ + Py_ssize_t size; + + st->st_cur = NULL; + size = PyList_GET_SIZE(st->st_stack); + if (size) { + if (PyList_SetSlice(st->st_stack, size - 1, size, NULL) < 0) + return 0; + if (--size) + st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, size - 1); + } + return 1; +} + +static int +symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, + void *ast, int lineno, int col_offset) +{ + PySTEntryObject *prev = NULL, *ste; + + ste = ste_new(st, name, block, ast, lineno, col_offset); + if (ste == NULL) + return 0; + if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) { + Py_DECREF(ste); + return 0; + } + prev = st->st_cur; + /* bpo-37757: For now, disallow *all* assignment expressions in the + * outermost iterator expression of a comprehension, even those inside + * a nested comprehension or a lambda expression. + */ + if (prev) { + ste->ste_comp_iter_expr = prev->ste_comp_iter_expr; + } + /* The entry is owned by the stack. Borrow it for st_cur. */ + Py_DECREF(ste); + st->st_cur = ste; + if (block == ModuleBlock) + st->st_global = st->st_cur->ste_symbols; + if (prev) { + if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) { + return 0; + } + } + return 1; +} + +static long +symtable_lookup(struct symtable *st, PyObject *name) +{ + PyObject *mangled = _Py_Mangle(st->st_private, name); + if (!mangled) + return 0; + long ret = _PyST_GetSymbol(st->st_cur, mangled); + Py_DECREF(mangled); + return ret; +} + +static int +symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste) +{ + PyObject *o; + PyObject *dict; + long val; + PyObject *mangled = _Py_Mangle(st->st_private, name); + + + if (!mangled) + return 0; + dict = ste->ste_symbols; + if ((o = PyDict_GetItemWithError(dict, mangled))) { + val = PyLong_AS_LONG(o); + if ((flag & DEF_PARAM) && (val & DEF_PARAM)) { + /* Is it better to use 'mangled' or 'name' here? */ + PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name); + PyErr_SyntaxLocationObject(st->st_filename, + ste->ste_lineno, + ste->ste_col_offset + 1); + goto error; + } + val |= flag; + } + else if (PyErr_Occurred()) { + goto error; + } + else { + val = flag; + } + if (ste->ste_comp_iter_target) { + /* This name is an iteration variable in a comprehension, + * so check for a binding conflict with any named expressions. + * Otherwise, mark it as an iteration variable so subsequent + * named expressions can check for conflicts. + */ + if (val & (DEF_GLOBAL | DEF_NONLOCAL)) { + PyErr_Format(PyExc_SyntaxError, + NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name); + PyErr_SyntaxLocationObject(st->st_filename, + ste->ste_lineno, + ste->ste_col_offset + 1); + goto error; + } + val |= DEF_COMP_ITER; + } + o = PyLong_FromLong(val); + if (o == NULL) + goto error; + if (PyDict_SetItem(dict, mangled, o) < 0) { + Py_DECREF(o); + goto error; + } + Py_DECREF(o); + + if (flag & DEF_PARAM) { + if (PyList_Append(ste->ste_varnames, mangled) < 0) + goto error; + } else if (flag & DEF_GLOBAL) { + /* XXX need to update DEF_GLOBAL for other flags too; + perhaps only DEF_FREE_GLOBAL */ + val = flag; + if ((o = PyDict_GetItem(st->st_global, mangled))) { + val |= PyLong_AS_LONG(o); + } + o = PyLong_FromLong(val); + if (o == NULL) + goto error; + if (PyDict_SetItem(st->st_global, mangled, o) < 0) { + Py_DECREF(o); + goto error; + } + Py_DECREF(o); + } + Py_DECREF(mangled); + return 1; + +error: + Py_DECREF(mangled); + return 0; +} + +static int +symtable_add_def(struct symtable *st, PyObject *name, int flag) { + return symtable_add_def_helper(st, name, flag, st->st_cur); +} + +/* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument. + They use the ASDL name to synthesize the name of the C type and the visit + function. + + VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is + useful if the first node in the sequence requires special treatment. + + VISIT_QUIT macro returns the specified value exiting from the function but + first adjusts current recursion counter depth. +*/ + +#define VISIT_QUIT(ST, X) \ + return --(ST)->recursion_depth,(X) + +#define VISIT(ST, TYPE, V) \ + if (!symtable_visit_ ## TYPE((ST), (V))) \ + VISIT_QUIT((ST), 0); + +#define VISIT_SEQ(ST, TYPE, SEQ) { \ + int i; \ + asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + for (i = 0; i < asdl_seq_LEN(seq); i++) { \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ + if (!symtable_visit_ ## TYPE((ST), elt)) \ + VISIT_QUIT((ST), 0); \ + } \ +} + +#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \ + int i; \ + asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + for (i = (START); i < asdl_seq_LEN(seq); i++) { \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ + if (!symtable_visit_ ## TYPE((ST), elt)) \ + VISIT_QUIT((ST), 0); \ + } \ +} + +#define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) { \ + int i = 0; \ + asdl_seq *seq = (SEQ); /* avoid variable capture */ \ + for (i = 0; i < asdl_seq_LEN(seq); i++) { \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ + if (!elt) continue; /* can be NULL */ \ + if (!symtable_visit_ ## TYPE((ST), elt)) \ + VISIT_QUIT((ST), 0); \ + } \ +} + +static int +symtable_record_directive(struct symtable *st, identifier name, int lineno, int col_offset) +{ + PyObject *data, *mangled; + int res; + if (!st->st_cur->ste_directives) { + st->st_cur->ste_directives = PyList_New(0); + if (!st->st_cur->ste_directives) + return 0; + } + mangled = _Py_Mangle(st->st_private, name); + if (!mangled) + return 0; + data = Py_BuildValue("(Nii)", mangled, lineno, col_offset); + if (!data) + return 0; + res = PyList_Append(st->st_cur->ste_directives, data); + Py_DECREF(data); + return res == 0; +} + + +static int +symtable_visit_stmt(struct symtable *st, stmt_ty s) +{ + if (++st->recursion_depth > st->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + VISIT_QUIT(st, 0); + } + switch (s->kind) { + case FunctionDef_kind: + if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL)) + VISIT_QUIT(st, 0); + if (s->v.FunctionDef.args->defaults) + VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); + if (s->v.FunctionDef.args->kw_defaults) + VISIT_SEQ_WITH_NULL(st, expr, s->v.FunctionDef.args->kw_defaults); + if (!symtable_visit_annotations(st, s, s->v.FunctionDef.args, + s->v.FunctionDef.returns)) + VISIT_QUIT(st, 0); + if (s->v.FunctionDef.decorator_list) + VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list); + if (!symtable_enter_block(st, s->v.FunctionDef.name, + FunctionBlock, (void *)s, s->lineno, + s->col_offset)) + VISIT_QUIT(st, 0); + VISIT(st, arguments, s->v.FunctionDef.args); + VISIT_SEQ(st, stmt, s->v.FunctionDef.body); + if (!symtable_exit_block(st, s)) + VISIT_QUIT(st, 0); + break; + case ClassDef_kind: { + PyObject *tmp; + if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL)) + VISIT_QUIT(st, 0); + VISIT_SEQ(st, expr, s->v.ClassDef.bases); + VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); + if (s->v.ClassDef.decorator_list) + VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list); + if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, + (void *)s, s->lineno, s->col_offset)) + VISIT_QUIT(st, 0); + tmp = st->st_private; + st->st_private = s->v.ClassDef.name; + VISIT_SEQ(st, stmt, s->v.ClassDef.body); + st->st_private = tmp; + if (!symtable_exit_block(st, s)) + VISIT_QUIT(st, 0); + break; + } + case Return_kind: + if (s->v.Return.value) { + VISIT(st, expr, s->v.Return.value); + st->st_cur->ste_returns_value = 1; + } + break; + case Delete_kind: + VISIT_SEQ(st, expr, s->v.Delete.targets); + break; + case Assign_kind: + VISIT_SEQ(st, expr, s->v.Assign.targets); + VISIT(st, expr, s->v.Assign.value); + break; + case AnnAssign_kind: + if (s->v.AnnAssign.target->kind == Name_kind) { + expr_ty e_name = s->v.AnnAssign.target; + long cur = symtable_lookup(st, e_name->v.Name.id); + if (cur < 0) { + VISIT_QUIT(st, 0); + } + if ((cur & (DEF_GLOBAL | DEF_NONLOCAL)) + && (st->st_cur->ste_symbols != st->st_global) + && s->v.AnnAssign.simple) { + PyErr_Format(PyExc_SyntaxError, + cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT, + e_name->v.Name.id); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset + 1); + VISIT_QUIT(st, 0); + } + if (s->v.AnnAssign.simple && + !symtable_add_def(st, e_name->v.Name.id, + DEF_ANNOT | DEF_LOCAL)) { + VISIT_QUIT(st, 0); + } + else { + if (s->v.AnnAssign.value + && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL)) { + VISIT_QUIT(st, 0); + } + } + } + else { + VISIT(st, expr, s->v.AnnAssign.target); + } + VISIT(st, expr, s->v.AnnAssign.annotation); + if (s->v.AnnAssign.value) { + VISIT(st, expr, s->v.AnnAssign.value); + } + break; + case AugAssign_kind: + VISIT(st, expr, s->v.AugAssign.target); + VISIT(st, expr, s->v.AugAssign.value); + break; + case For_kind: + VISIT(st, expr, s->v.For.target); + VISIT(st, expr, s->v.For.iter); + VISIT_SEQ(st, stmt, s->v.For.body); + if (s->v.For.orelse) + VISIT_SEQ(st, stmt, s->v.For.orelse); + break; + case While_kind: + VISIT(st, expr, s->v.While.test); + VISIT_SEQ(st, stmt, s->v.While.body); + if (s->v.While.orelse) + VISIT_SEQ(st, stmt, s->v.While.orelse); + break; + case If_kind: + /* XXX if 0: and lookup_yield() hacks */ + VISIT(st, expr, s->v.If.test); + VISIT_SEQ(st, stmt, s->v.If.body); + if (s->v.If.orelse) + VISIT_SEQ(st, stmt, s->v.If.orelse); + break; + case Raise_kind: + if (s->v.Raise.exc) { + VISIT(st, expr, s->v.Raise.exc); + if (s->v.Raise.cause) { + VISIT(st, expr, s->v.Raise.cause); + } + } + break; + case Try_kind: + VISIT_SEQ(st, stmt, s->v.Try.body); + VISIT_SEQ(st, stmt, s->v.Try.orelse); + VISIT_SEQ(st, excepthandler, s->v.Try.handlers); + VISIT_SEQ(st, stmt, s->v.Try.finalbody); + break; + case Assert_kind: + VISIT(st, expr, s->v.Assert.test); + if (s->v.Assert.msg) + VISIT(st, expr, s->v.Assert.msg); + break; + case Import_kind: + VISIT_SEQ(st, alias, s->v.Import.names); + break; + case ImportFrom_kind: + VISIT_SEQ(st, alias, s->v.ImportFrom.names); + break; + case Global_kind: { + int i; + asdl_seq *seq = s->v.Global.names; + for (i = 0; i < asdl_seq_LEN(seq); i++) { + identifier name = (identifier)asdl_seq_GET(seq, i); + long cur = symtable_lookup(st, name); + if (cur < 0) + VISIT_QUIT(st, 0); + if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) { + const char* msg; + if (cur & DEF_PARAM) { + msg = GLOBAL_PARAM; + } else if (cur & USE) { + msg = GLOBAL_AFTER_USE; + } else if (cur & DEF_ANNOT) { + msg = GLOBAL_ANNOT; + } else { /* DEF_LOCAL */ + msg = GLOBAL_AFTER_ASSIGN; + } + PyErr_Format(PyExc_SyntaxError, + msg, name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset + 1); + VISIT_QUIT(st, 0); + } + if (!symtable_add_def(st, name, DEF_GLOBAL)) + VISIT_QUIT(st, 0); + if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) + VISIT_QUIT(st, 0); + } + break; + } + case Nonlocal_kind: { + int i; + asdl_seq *seq = s->v.Nonlocal.names; + for (i = 0; i < asdl_seq_LEN(seq); i++) { + identifier name = (identifier)asdl_seq_GET(seq, i); + long cur = symtable_lookup(st, name); + if (cur < 0) + VISIT_QUIT(st, 0); + if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) { + const char* msg; + if (cur & DEF_PARAM) { + msg = NONLOCAL_PARAM; + } else if (cur & USE) { + msg = NONLOCAL_AFTER_USE; + } else if (cur & DEF_ANNOT) { + msg = NONLOCAL_ANNOT; + } else { /* DEF_LOCAL */ + msg = NONLOCAL_AFTER_ASSIGN; + } + PyErr_Format(PyExc_SyntaxError, msg, name); + PyErr_SyntaxLocationObject(st->st_filename, + s->lineno, + s->col_offset + 1); + VISIT_QUIT(st, 0); + } + if (!symtable_add_def(st, name, DEF_NONLOCAL)) + VISIT_QUIT(st, 0); + if (!symtable_record_directive(st, name, s->lineno, s->col_offset)) + VISIT_QUIT(st, 0); + } + break; + } + case Expr_kind: + VISIT(st, expr, s->v.Expr.value); + break; + case Pass_kind: + case Break_kind: + case Continue_kind: + /* nothing to do here */ + break; + case With_kind: + VISIT_SEQ(st, withitem, s->v.With.items); + VISIT_SEQ(st, stmt, s->v.With.body); + break; + case AsyncFunctionDef_kind: + if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL)) + VISIT_QUIT(st, 0); + if (s->v.AsyncFunctionDef.args->defaults) + VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults); + if (s->v.AsyncFunctionDef.args->kw_defaults) + VISIT_SEQ_WITH_NULL(st, expr, + s->v.AsyncFunctionDef.args->kw_defaults); + if (!symtable_visit_annotations(st, s, s->v.AsyncFunctionDef.args, + s->v.AsyncFunctionDef.returns)) + VISIT_QUIT(st, 0); + if (s->v.AsyncFunctionDef.decorator_list) + VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list); + if (!symtable_enter_block(st, s->v.AsyncFunctionDef.name, + FunctionBlock, (void *)s, s->lineno, + s->col_offset)) + VISIT_QUIT(st, 0); + st->st_cur->ste_coroutine = 1; + VISIT(st, arguments, s->v.AsyncFunctionDef.args); + VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body); + if (!symtable_exit_block(st, s)) + VISIT_QUIT(st, 0); + break; + case AsyncWith_kind: + VISIT_SEQ(st, withitem, s->v.AsyncWith.items); + VISIT_SEQ(st, stmt, s->v.AsyncWith.body); + break; + case AsyncFor_kind: + VISIT(st, expr, s->v.AsyncFor.target); + VISIT(st, expr, s->v.AsyncFor.iter); + VISIT_SEQ(st, stmt, s->v.AsyncFor.body); + if (s->v.AsyncFor.orelse) + VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse); + break; + } + VISIT_QUIT(st, 1); +} + +static int +symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) +{ + assert(st->st_stack); + assert(e->kind == Name_kind); + + PyObject *target_name = e->v.Name.id; + Py_ssize_t i, size; + struct _symtable_entry *ste; + size = PyList_GET_SIZE(st->st_stack); + assert(size); + + /* Iterate over the stack in reverse and add to the nearest adequate scope */ + for (i = size - 1; i >= 0; i--) { + ste = (struct _symtable_entry *) PyList_GET_ITEM(st->st_stack, i); + + /* If we find a comprehension scope, check for a target + * binding conflict with iteration variables, otherwise skip it + */ + if (ste->ste_comprehension) { + long target_in_scope = _PyST_GetSymbol(ste, target_name); + if (target_in_scope & DEF_COMP_ITER) { + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + VISIT_QUIT(st, 0); + } + continue; + } + + /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */ + if (ste->ste_type == FunctionBlock) { + long target_in_scope = _PyST_GetSymbol(ste, target_name); + if (target_in_scope & DEF_GLOBAL) { + if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + VISIT_QUIT(st, 0); + } else { + if (!symtable_add_def(st, target_name, DEF_NONLOCAL)) + VISIT_QUIT(st, 0); + } + if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) + VISIT_QUIT(st, 0); + + return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste); + } + /* If we find a ModuleBlock entry, add as GLOBAL */ + if (ste->ste_type == ModuleBlock) { + if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + VISIT_QUIT(st, 0); + if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset)) + VISIT_QUIT(st, 0); + + return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste); + } + /* Disallow usage in ClassBlock */ + if (ste->ste_type == ClassBlock) { + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + VISIT_QUIT(st, 0); + } + } + + /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock + and should never fall to this case + */ + assert(0); + return 0; +} + +static int +symtable_handle_namedexpr(struct symtable *st, expr_ty e) +{ + if (st->st_cur->ste_comp_iter_expr > 0) { + /* Assignment isn't allowed in a comprehension iterable expression */ + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_ITER_EXPR); + PyErr_SyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset); + return 0; + } + if (st->st_cur->ste_comprehension) { + /* Inside a comprehension body, so find the right target scope */ + if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target)) + return 0; + } + VISIT(st, expr, e->v.NamedExpr.value); + VISIT(st, expr, e->v.NamedExpr.target); + return 1; +} + +static int +symtable_visit_expr(struct symtable *st, expr_ty e) +{ + if (++st->recursion_depth > st->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + VISIT_QUIT(st, 0); + } + switch (e->kind) { + case NamedExpr_kind: + if(!symtable_handle_namedexpr(st, e)) + VISIT_QUIT(st, 0); + break; + case BoolOp_kind: + VISIT_SEQ(st, expr, e->v.BoolOp.values); + break; + case BinOp_kind: + VISIT(st, expr, e->v.BinOp.left); + VISIT(st, expr, e->v.BinOp.right); + break; + case UnaryOp_kind: + VISIT(st, expr, e->v.UnaryOp.operand); + break; + case Lambda_kind: { + if (!GET_IDENTIFIER(lambda)) + VISIT_QUIT(st, 0); + if (e->v.Lambda.args->defaults) + VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); + if (e->v.Lambda.args->kw_defaults) + VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults); + if (!symtable_enter_block(st, lambda, + FunctionBlock, (void *)e, e->lineno, + e->col_offset)) + VISIT_QUIT(st, 0); + VISIT(st, arguments, e->v.Lambda.args); + VISIT(st, expr, e->v.Lambda.body); + if (!symtable_exit_block(st, (void *)e)) + VISIT_QUIT(st, 0); + break; + } + case IfExp_kind: + VISIT(st, expr, e->v.IfExp.test); + VISIT(st, expr, e->v.IfExp.body); + VISIT(st, expr, e->v.IfExp.orelse); + break; + case Dict_kind: + VISIT_SEQ_WITH_NULL(st, expr, e->v.Dict.keys); + VISIT_SEQ(st, expr, e->v.Dict.values); + break; + case Set_kind: + VISIT_SEQ(st, expr, e->v.Set.elts); + break; + case GeneratorExp_kind: + if (!symtable_visit_genexp(st, e)) + VISIT_QUIT(st, 0); + break; + case ListComp_kind: + if (!symtable_visit_listcomp(st, e)) + VISIT_QUIT(st, 0); + break; + case SetComp_kind: + if (!symtable_visit_setcomp(st, e)) + VISIT_QUIT(st, 0); + break; + case DictComp_kind: + if (!symtable_visit_dictcomp(st, e)) + VISIT_QUIT(st, 0); + break; + case Yield_kind: + if (e->v.Yield.value) + VISIT(st, expr, e->v.Yield.value); + st->st_cur->ste_generator = 1; + break; + case YieldFrom_kind: + VISIT(st, expr, e->v.YieldFrom.value); + st->st_cur->ste_generator = 1; + break; + case Await_kind: + VISIT(st, expr, e->v.Await.value); + st->st_cur->ste_coroutine = 1; + break; + case Compare_kind: + VISIT(st, expr, e->v.Compare.left); + VISIT_SEQ(st, expr, e->v.Compare.comparators); + break; + case Call_kind: + VISIT(st, expr, e->v.Call.func); + VISIT_SEQ(st, expr, e->v.Call.args); + VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords); + break; + case FormattedValue_kind: + VISIT(st, expr, e->v.FormattedValue.value); + if (e->v.FormattedValue.format_spec) + VISIT(st, expr, e->v.FormattedValue.format_spec); + break; + case JoinedStr_kind: + VISIT_SEQ(st, expr, e->v.JoinedStr.values); + break; + case Constant_kind: + /* Nothing to do here. */ + break; + /* The following exprs can be assignment targets. */ + case Attribute_kind: + VISIT(st, expr, e->v.Attribute.value); + break; + case Subscript_kind: + VISIT(st, expr, e->v.Subscript.value); + VISIT(st, slice, e->v.Subscript.slice); + break; + case Starred_kind: + VISIT(st, expr, e->v.Starred.value); + break; + case Name_kind: + if (!symtable_add_def(st, e->v.Name.id, + e->v.Name.ctx == Load ? USE : DEF_LOCAL)) + VISIT_QUIT(st, 0); + /* Special-case super: it counts as a use of __class__ */ + if (e->v.Name.ctx == Load && + st->st_cur->ste_type == FunctionBlock && + _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) { + if (!GET_IDENTIFIER(__class__) || + !symtable_add_def(st, __class__, USE)) + VISIT_QUIT(st, 0); + } + break; + /* child nodes of List and Tuple will have expr_context set */ + case List_kind: + VISIT_SEQ(st, expr, e->v.List.elts); + break; + case Tuple_kind: + VISIT_SEQ(st, expr, e->v.Tuple.elts); + break; + } + VISIT_QUIT(st, 1); +} + +static int +symtable_implicit_arg(struct symtable *st, int pos) +{ + PyObject *id = PyUnicode_FromFormat(".%d", pos); + if (id == NULL) + return 0; + if (!symtable_add_def(st, id, DEF_PARAM)) { + Py_DECREF(id); + return 0; + } + Py_DECREF(id); + return 1; +} + +static int +symtable_visit_params(struct symtable *st, asdl_seq *args) +{ + int i; + + if (!args) + return -1; + + for (i = 0; i < asdl_seq_LEN(args); i++) { + arg_ty arg = (arg_ty)asdl_seq_GET(args, i); + if (!symtable_add_def(st, arg->arg, DEF_PARAM)) + return 0; + } + + return 1; +} + +static int +symtable_visit_argannotations(struct symtable *st, asdl_seq *args) +{ + int i; + + if (!args) + return -1; + + for (i = 0; i < asdl_seq_LEN(args); i++) { + arg_ty arg = (arg_ty)asdl_seq_GET(args, i); + if (arg->annotation) + VISIT(st, expr, arg->annotation); + } + + return 1; +} + +static int +symtable_visit_annotations(struct symtable *st, stmt_ty s, + arguments_ty a, expr_ty returns) +{ + if (a->posonlyargs && !symtable_visit_argannotations(st, a->posonlyargs)) + return 0; + if (a->args && !symtable_visit_argannotations(st, a->args)) + return 0; + if (a->vararg && a->vararg->annotation) + VISIT(st, expr, a->vararg->annotation); + if (a->kwarg && a->kwarg->annotation) + VISIT(st, expr, a->kwarg->annotation); + if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs)) + return 0; + if (returns) + VISIT(st, expr, returns); + return 1; +} + +static int +symtable_visit_arguments(struct symtable *st, arguments_ty a) +{ + /* skip default arguments inside function block + XXX should ast be different? + */ + if (a->posonlyargs && !symtable_visit_params(st, a->posonlyargs)) + return 0; + if (a->args && !symtable_visit_params(st, a->args)) + return 0; + if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs)) + return 0; + if (a->vararg) { + if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM)) + return 0; + st->st_cur->ste_varargs = 1; + } + if (a->kwarg) { + if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM)) + return 0; + st->st_cur->ste_varkeywords = 1; + } + return 1; +} + + +static int +symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh) +{ + if (eh->v.ExceptHandler.type) + VISIT(st, expr, eh->v.ExceptHandler.type); + if (eh->v.ExceptHandler.name) + if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL)) + return 0; + VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body); + return 1; +} + +static int +symtable_visit_withitem(struct symtable *st, withitem_ty item) +{ + VISIT(st, expr, item->context_expr); + if (item->optional_vars) { + VISIT(st, expr, item->optional_vars); + } + return 1; +} + + +static int +symtable_visit_alias(struct symtable *st, alias_ty a) +{ + /* Compute store_name, the name actually bound by the import + operation. It is different than a->name when a->name is a + dotted package name (e.g. spam.eggs) + */ + PyObject *store_name; + PyObject *name = (a->asname == NULL) ? a->name : a->asname; + Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, + PyUnicode_GET_LENGTH(name), 1); + if (dot != -1) { + store_name = PyUnicode_Substring(name, 0, dot); + if (!store_name) + return 0; + } + else { + store_name = name; + Py_INCREF(store_name); + } + if (!_PyUnicode_EqualToASCIIString(name, "*")) { + int r = symtable_add_def(st, store_name, DEF_IMPORT); + Py_DECREF(store_name); + return r; + } + else { + if (st->st_cur->ste_type != ModuleBlock) { + int lineno = st->st_cur->ste_lineno; + int col_offset = st->st_cur->ste_col_offset; + PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); + PyErr_SyntaxLocationObject(st->st_filename, lineno, col_offset + 1); + Py_DECREF(store_name); + return 0; + } + Py_DECREF(store_name); + return 1; + } +} + + +static int +symtable_visit_comprehension(struct symtable *st, comprehension_ty lc) +{ + st->st_cur->ste_comp_iter_target = 1; + VISIT(st, expr, lc->target); + st->st_cur->ste_comp_iter_target = 0; + st->st_cur->ste_comp_iter_expr++; + VISIT(st, expr, lc->iter); + st->st_cur->ste_comp_iter_expr--; + VISIT_SEQ(st, expr, lc->ifs); + if (lc->is_async) { + st->st_cur->ste_coroutine = 1; + } + return 1; +} + + +static int +symtable_visit_keyword(struct symtable *st, keyword_ty k) +{ + VISIT(st, expr, k->value); + return 1; +} + + +static int +symtable_visit_slice(struct symtable *st, slice_ty s) +{ + switch (s->kind) { + case Slice_kind: + if (s->v.Slice.lower) + VISIT(st, expr, s->v.Slice.lower) + if (s->v.Slice.upper) + VISIT(st, expr, s->v.Slice.upper) + if (s->v.Slice.step) + VISIT(st, expr, s->v.Slice.step) + break; + case ExtSlice_kind: + VISIT_SEQ(st, slice, s->v.ExtSlice.dims) + break; + case Index_kind: + VISIT(st, expr, s->v.Index.value) + break; + } + return 1; +} + +static int +symtable_handle_comprehension(struct symtable *st, expr_ty e, + identifier scope_name, asdl_seq *generators, + expr_ty elt, expr_ty value) +{ + int is_generator = (e->kind == GeneratorExp_kind); + comprehension_ty outermost = ((comprehension_ty) + asdl_seq_GET(generators, 0)); + /* Outermost iterator is evaluated in current scope */ + st->st_cur->ste_comp_iter_expr++; + VISIT(st, expr, outermost->iter); + st->st_cur->ste_comp_iter_expr--; + /* Create comprehension scope for the rest */ + if (!scope_name || + !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, + e->lineno, e->col_offset)) { + return 0; + } + if (outermost->is_async) { + st->st_cur->ste_coroutine = 1; + } + st->st_cur->ste_comprehension = 1; + + /* Outermost iter is received as an argument */ + if (!symtable_implicit_arg(st, 0)) { + symtable_exit_block(st, (void *)e); + return 0; + } + /* Visit iteration variable target, and mark them as such */ + st->st_cur->ste_comp_iter_target = 1; + VISIT(st, expr, outermost->target); + st->st_cur->ste_comp_iter_target = 0; + /* Visit the rest of the comprehension body */ + VISIT_SEQ(st, expr, outermost->ifs); + VISIT_SEQ_TAIL(st, comprehension, generators, 1); + if (value) + VISIT(st, expr, value); + VISIT(st, expr, elt); + if (st->st_cur->ste_generator) { + PyErr_SetString(PyExc_SyntaxError, + (e->kind == ListComp_kind) ? "'yield' inside list comprehension" : + (e->kind == SetComp_kind) ? "'yield' inside set comprehension" : + (e->kind == DictComp_kind) ? "'yield' inside dict comprehension" : + "'yield' inside generator expression"); + PyErr_SyntaxLocationObject(st->st_filename, + st->st_cur->ste_lineno, + st->st_cur->ste_col_offset + 1); + symtable_exit_block(st, (void *)e); + return 0; + } + st->st_cur->ste_generator = is_generator; + return symtable_exit_block(st, (void *)e); +} + +static int +symtable_visit_genexp(struct symtable *st, expr_ty e) +{ + return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr), + e->v.GeneratorExp.generators, + e->v.GeneratorExp.elt, NULL); +} + +static int +symtable_visit_listcomp(struct symtable *st, expr_ty e) +{ + return symtable_handle_comprehension(st, e, GET_IDENTIFIER(listcomp), + e->v.ListComp.generators, + e->v.ListComp.elt, NULL); +} + +static int +symtable_visit_setcomp(struct symtable *st, expr_ty e) +{ + return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp), + e->v.SetComp.generators, + e->v.SetComp.elt, NULL); +} + +static int +symtable_visit_dictcomp(struct symtable *st, expr_ty e) +{ + return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp), + e->v.DictComp.generators, + e->v.DictComp.key, + e->v.DictComp.value); +} diff --git a/python/Python/sysmodule.c b/python/Python/sysmodule.c new file mode 100755 index 0000000..b544f2b --- /dev/null +++ b/python/Python/sysmodule.c @@ -0,0 +1,3337 @@ + +/* System module */ + +/* +Various bits of information used by the interpreter are collected in +module 'sys'. +Function member: +- exit(sts): raise SystemExit +Data members: +- stdin, stdout, stderr: standard file objects +- modules: the table of modules (dictionary) +- path: module search path (list of strings) +- argv: script arguments (list of strings) +- ps1, ps2: optional primary and secondary prompts (strings) +*/ + +#include "Python.h" +#include "code.h" +#include "frameobject.h" +#include "pycore_initconfig.h" +#include "pycore_pylifecycle.h" +#include "pycore_pymem.h" +#include "pycore_pathconfig.h" +#include "pycore_pystate.h" +#include "pycore_tupleobject.h" +#include "pythread.h" +#include "pydtrace.h" + +#include "osdefs.h" +#include + +#ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#endif /* MS_WINDOWS */ + +#ifdef MS_COREDLL +extern void *PyWin_DLLhModule; +/* A string loaded from the DLL at startup: */ +extern const char *PyWin_DLLVersionString; +#endif + +/*[clinic input] +module sys +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3726b388feee8cea]*/ + +#include "clinic/sysmodule.c.h" + +_Py_IDENTIFIER(_); +_Py_IDENTIFIER(__sizeof__); +_Py_IDENTIFIER(_xoptions); +_Py_IDENTIFIER(buffer); +_Py_IDENTIFIER(builtins); +_Py_IDENTIFIER(encoding); +_Py_IDENTIFIER(path); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); +_Py_IDENTIFIER(warnoptions); +_Py_IDENTIFIER(write); + +PyObject * +_PySys_GetObjectId(_Py_Identifier *key) +{ + PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + if (sd == NULL) { + return NULL; + } + return _PyDict_GetItemId(sd, key); +} + +PyObject * +PySys_GetObject(const char *name) +{ + PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + if (sd == NULL) { + return NULL; + } + return PyDict_GetItemString(sd, name); +} + +int +_PySys_SetObjectId(_Py_Identifier *key, PyObject *v) +{ + PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + if (v == NULL) { + if (_PyDict_GetItemId(sd, key) == NULL) { + return 0; + } + else { + return _PyDict_DelItemId(sd, key); + } + } + else { + return _PyDict_SetItemId(sd, key, v); + } +} + +int +PySys_SetObject(const char *name, PyObject *v) +{ + PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + if (v == NULL) { + if (PyDict_GetItemString(sd, name) == NULL) { + return 0; + } + else { + return PyDict_DelItemString(sd, name); + } + } + else { + return PyDict_SetItemString(sd, name, v); + } +} + +static int +should_audit(void) +{ + PyThreadState *ts = _PyThreadState_GET(); + if (!ts) { + return 0; + } + PyInterpreterState *is = ts ? ts->interp : NULL; + return _PyRuntime.audit_hook_head + || (is && is->audit_hooks) + || PyDTrace_AUDIT_ENABLED(); +} + +int +PySys_Audit(const char *event, const char *argFormat, ...) +{ + PyObject *eventName = NULL; + PyObject *eventArgs = NULL; + PyObject *hooks = NULL; + PyObject *hook = NULL; + int res = -1; + + /* N format is inappropriate, because you do not know + whether the reference is consumed by the call. + Assert rather than exception for perf reasons */ + assert(!argFormat || !strchr(argFormat, 'N')); + + /* Early exit when no hooks are registered */ + if (!should_audit()) { + return 0; + } + + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; + PyThreadState *ts = _PyThreadState_GET(); + PyInterpreterState *is = ts ? ts->interp : NULL; + int dtrace = PyDTrace_AUDIT_ENABLED(); + + PyObject *exc_type, *exc_value, *exc_tb; + if (ts) { + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + } + + /* Initialize event args now */ + if (argFormat && argFormat[0]) { + va_list args; + va_start(args, argFormat); + eventArgs = _Py_VaBuildValue_SizeT(argFormat, args); + va_end(args); + if (eventArgs && !PyTuple_Check(eventArgs)) { + PyObject *argTuple = PyTuple_Pack(1, eventArgs); + Py_DECREF(eventArgs); + eventArgs = argTuple; + } + } else { + eventArgs = PyTuple_New(0); + } + if (!eventArgs) { + goto exit; + } + + /* Call global hooks */ + for (; e; e = e->next) { + if (e->hookCFunction(event, eventArgs, e->userData) < 0) { + goto exit; + } + } + + /* Dtrace USDT point */ + if (dtrace) { + PyDTrace_AUDIT(event, (void *)eventArgs); + } + + /* Call interpreter hooks */ + if (is && is->audit_hooks) { + eventName = PyUnicode_FromString(event); + if (!eventName) { + goto exit; + } + + hooks = PyObject_GetIter(is->audit_hooks); + if (!hooks) { + goto exit; + } + + /* Disallow tracing in hooks unless explicitly enabled */ + ts->tracing++; + ts->use_tracing = 0; + while ((hook = PyIter_Next(hooks)) != NULL) { + _Py_IDENTIFIER(__cantrace__); + PyObject *o; + int canTrace = _PyObject_LookupAttrId(hook, &PyId___cantrace__, &o); + if (o) { + canTrace = PyObject_IsTrue(o); + Py_DECREF(o); + } + if (canTrace < 0) { + break; + } + if (canTrace) { + ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); + ts->tracing--; + } + o = PyObject_CallFunctionObjArgs(hook, eventName, + eventArgs, NULL); + if (canTrace) { + ts->tracing++; + ts->use_tracing = 0; + } + if (!o) { + break; + } + Py_DECREF(o); + Py_CLEAR(hook); + } + ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); + ts->tracing--; + if (PyErr_Occurred()) { + goto exit; + } + } + + res = 0; + +exit: + Py_XDECREF(hook); + Py_XDECREF(hooks); + Py_XDECREF(eventName); + Py_XDECREF(eventArgs); + + if (ts) { + if (!res) { + PyErr_Restore(exc_type, exc_value, exc_tb); + } else { + assert(PyErr_Occurred()); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + } + } + + return res; +} + +/* We expose this function primarily for our own cleanup during + * finalization. In general, it should not need to be called, + * and as such it is not defined in any header files. + */ +void _PySys_ClearAuditHooks(void) { + /* Must be finalizing to clear hooks */ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *ts = _PyRuntimeState_GetThreadState(runtime); + assert(!ts || _Py_CURRENTLY_FINALIZING(runtime, ts)); + if (!ts || !_Py_CURRENTLY_FINALIZING(runtime, ts)) + return; + + if (Py_VerboseFlag) { + PySys_WriteStderr("# clear sys.audit hooks\n"); + } + + /* Hooks can abort later hooks for this event, but cannot + abort the clear operation itself. */ + PySys_Audit("cpython._PySys_ClearAuditHooks", NULL); + PyErr_Clear(); + + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n; + _PyRuntime.audit_hook_head = NULL; + while (e) { + n = e->next; + PyMem_RawFree(e); + e = n; + } +} + +int +PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) +{ + /* Invoke existing audit hooks to allow them an opportunity to abort. */ + /* Cannot invoke hooks until we are initialized */ + if (Py_IsInitialized()) { + if (PySys_Audit("sys.addaudithook", NULL) < 0) { + if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { + /* We do not report errors derived from RuntimeError */ + PyErr_Clear(); + return 0; + } + return -1; + } + } + + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; + if (!e) { + e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); + _PyRuntime.audit_hook_head = e; + } else { + while (e->next) + e = e->next; + e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc( + sizeof(_Py_AuditHookEntry)); + } + + if (!e) { + if (Py_IsInitialized()) + PyErr_NoMemory(); + return -1; + } + + e->next = NULL; + e->hookCFunction = (Py_AuditHookFunction)hook; + e->userData = userData; + + return 0; +} + +/*[clinic input] +sys.addaudithook + + hook: object + +Adds a new audit hook callback. +[clinic start generated code]*/ + +static PyObject * +sys_addaudithook_impl(PyObject *module, PyObject *hook) +/*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/ +{ + /* Invoke existing audit hooks to allow them an opportunity to abort. */ + if (PySys_Audit("sys.addaudithook", NULL) < 0) { + if (PyErr_ExceptionMatches(PyExc_Exception)) { + /* We do not report errors derived from Exception */ + PyErr_Clear(); + Py_RETURN_NONE; + } + return NULL; + } + + PyInterpreterState *is = _PyInterpreterState_Get(); + + if (is->audit_hooks == NULL) { + is->audit_hooks = PyList_New(0); + if (is->audit_hooks == NULL) { + return NULL; + } + } + + if (PyList_Append(is->audit_hooks, hook) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(audit_doc, +"audit(event, *args)\n\ +\n\ +Passes the event to any audit hooks that are attached."); + +static PyObject * +sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc) +{ + if (argc == 0) { + PyErr_SetString(PyExc_TypeError, "audit() missing 1 required positional argument: 'event'"); + return NULL; + } + + if (!should_audit()) { + Py_RETURN_NONE; + } + + PyObject *auditEvent = args[0]; + if (!auditEvent) { + PyErr_SetString(PyExc_TypeError, "expected str for argument 'event'"); + return NULL; + } + if (!PyUnicode_Check(auditEvent)) { + PyErr_Format(PyExc_TypeError, "expected str for argument 'event', not %.200s", + Py_TYPE(auditEvent)->tp_name); + return NULL; + } + const char *event = PyUnicode_AsUTF8(auditEvent); + if (!event) { + return NULL; + } + + PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1); + if (!auditArgs) { + return NULL; + } + + int res = PySys_Audit(event, "O", auditArgs); + Py_DECREF(auditArgs); + + if (res < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + + +static PyObject * +sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) +{ + assert(!PyErr_Occurred()); + char *envar = Py_GETENV("PYTHONBREAKPOINT"); + + if (envar == NULL || strlen(envar) == 0) { + envar = "pdb.set_trace"; + } + else if (!strcmp(envar, "0")) { + /* The breakpoint is explicitly no-op'd. */ + Py_RETURN_NONE; + } + /* According to POSIX the string returned by getenv() might be invalidated + * or the string content might be overwritten by a subsequent call to + * getenv(). Since importing a module can performs the getenv() calls, + * we need to save a copy of envar. */ + envar = _PyMem_RawStrdup(envar); + if (envar == NULL) { + PyErr_NoMemory(); + return NULL; + } + const char *last_dot = strrchr(envar, '.'); + const char *attrname = NULL; + PyObject *modulepath = NULL; + + if (last_dot == NULL) { + /* The breakpoint is a built-in, e.g. PYTHONBREAKPOINT=int */ + modulepath = PyUnicode_FromString("builtins"); + attrname = envar; + } + else if (last_dot != envar) { + /* Split on the last dot; */ + modulepath = PyUnicode_FromStringAndSize(envar, last_dot - envar); + attrname = last_dot + 1; + } + else { + goto warn; + } + if (modulepath == NULL) { + PyMem_RawFree(envar); + return NULL; + } + + PyObject *module = PyImport_Import(modulepath); + Py_DECREF(modulepath); + + if (module == NULL) { + if (PyErr_ExceptionMatches(PyExc_ImportError)) { + goto warn; + } + PyMem_RawFree(envar); + return NULL; + } + + PyObject *hook = PyObject_GetAttrString(module, attrname); + Py_DECREF(module); + + if (hook == NULL) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + goto warn; + } + PyMem_RawFree(envar); + return NULL; + } + PyMem_RawFree(envar); + PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords); + Py_DECREF(hook); + return retval; + + warn: + /* If any of the imports went wrong, then warn and ignore. */ + PyErr_Clear(); + int status = PyErr_WarnFormat( + PyExc_RuntimeWarning, 0, + "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar); + PyMem_RawFree(envar); + if (status < 0) { + /* Printing the warning raised an exception. */ + return NULL; + } + /* The warning was (probably) issued. */ + Py_RETURN_NONE; +} + +PyDoc_STRVAR(breakpointhook_doc, +"breakpointhook(*args, **kws)\n" +"\n" +"This hook function is called by built-in breakpoint().\n" +); + +/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace' + error handler. If sys.stdout has a buffer attribute, use + sys.stdout.buffer.write(encoded), otherwise redecode the string and use + sys.stdout.write(redecoded). + + Helper function for sys_displayhook(). */ +static int +sys_displayhook_unencodable(PyObject *outf, PyObject *o) +{ + PyObject *stdout_encoding = NULL; + PyObject *encoded, *escaped_str, *repr_str, *buffer, *result; + const char *stdout_encoding_str; + int ret; + + stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding); + if (stdout_encoding == NULL) + goto error; + stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding); + if (stdout_encoding_str == NULL) + goto error; + + repr_str = PyObject_Repr(o); + if (repr_str == NULL) + goto error; + encoded = PyUnicode_AsEncodedString(repr_str, + stdout_encoding_str, + "backslashreplace"); + Py_DECREF(repr_str); + if (encoded == NULL) + goto error; + + if (_PyObject_LookupAttrId(outf, &PyId_buffer, &buffer) < 0) { + Py_DECREF(encoded); + goto error; + } + if (buffer) { + result = _PyObject_CallMethodIdObjArgs(buffer, &PyId_write, encoded, NULL); + Py_DECREF(buffer); + Py_DECREF(encoded); + if (result == NULL) + goto error; + Py_DECREF(result); + } + else { + escaped_str = PyUnicode_FromEncodedObject(encoded, + stdout_encoding_str, + "strict"); + Py_DECREF(encoded); + if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) { + Py_DECREF(escaped_str); + goto error; + } + Py_DECREF(escaped_str); + } + ret = 0; + goto finally; + +error: + ret = -1; +finally: + Py_XDECREF(stdout_encoding); + return ret; +} + +/*[clinic input] +sys.displayhook + + object as o: object + / + +Print an object to sys.stdout and also save it in builtins._ +[clinic start generated code]*/ + +static PyObject * +sys_displayhook(PyObject *module, PyObject *o) +/*[clinic end generated code: output=347477d006df92ed input=08ba730166d7ef72]*/ +{ + PyObject *outf; + PyObject *builtins; + static PyObject *newline = NULL; + int err; + + builtins = _PyImport_GetModuleId(&PyId_builtins); + if (builtins == NULL) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); + } + return NULL; + } + Py_DECREF(builtins); + + /* Print value except if None */ + /* After printing, also assign to '_' */ + /* Before, set '_' to None to avoid recursion */ + if (o == Py_None) { + Py_RETURN_NONE; + } + if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0) + return NULL; + outf = _PySys_GetObjectId(&PyId_stdout); + if (outf == NULL || outf == Py_None) { + PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); + return NULL; + } + if (PyFile_WriteObject(o, outf, 0) != 0) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + /* repr(o) is not encodable to sys.stdout.encoding with + * sys.stdout.errors error handler (which is probably 'strict') */ + PyErr_Clear(); + err = sys_displayhook_unencodable(outf, o); + if (err) + return NULL; + } + else { + return NULL; + } + } + if (newline == NULL) { + newline = PyUnicode_FromString("\n"); + if (newline == NULL) + return NULL; + } + if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0) + return NULL; + if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0) + return NULL; + Py_RETURN_NONE; +} + + +/*[clinic input] +sys.excepthook + + exctype: object + value: object + traceback: object + / + +Handle an exception by displaying it with a traceback on sys.stderr. +[clinic start generated code]*/ + +static PyObject * +sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, + PyObject *traceback) +/*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/ +{ + PyErr_Display(exctype, value, traceback); + Py_RETURN_NONE; +} + + +/*[clinic input] +sys.exc_info + +Return current exception information: (type, value, traceback). + +Return information about the most recent exception caught by an except +clause in the current stack frame or in an older stack frame. +[clinic start generated code]*/ + +static PyObject * +sys_exc_info_impl(PyObject *module) +/*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/ +{ + _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET()); + return Py_BuildValue( + "(OOO)", + err_info->exc_type != NULL ? err_info->exc_type : Py_None, + err_info->exc_value != NULL ? err_info->exc_value : Py_None, + err_info->exc_traceback != NULL ? + err_info->exc_traceback : Py_None); +} + + +/*[clinic input] +sys.unraisablehook + + unraisable: object + / + +Handle an unraisable exception. + +The unraisable argument has the following attributes: + +* exc_type: Exception type. +* exc_value: Exception value, can be None. +* exc_traceback: Exception traceback, can be None. +* err_msg: Error message, can be None. +* object: Object causing the exception, can be None. +[clinic start generated code]*/ + +static PyObject * +sys_unraisablehook(PyObject *module, PyObject *unraisable) +/*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/ +{ + return _PyErr_WriteUnraisableDefaultHook(unraisable); +} + + +/*[clinic input] +sys.exit + + status: object = None + / + +Exit the interpreter by raising SystemExit(status). + +If the status is omitted or None, it defaults to zero (i.e., success). +If the status is an integer, it will be used as the system exit status. +If it is another kind of object, it will be printed and the system +exit status will be one (i.e., failure). +[clinic start generated code]*/ + +static PyObject * +sys_exit_impl(PyObject *module, PyObject *status) +/*[clinic end generated code: output=13870986c1ab2ec0 input=b86ca9497baa94f2]*/ +{ + /* Raise SystemExit so callers may catch it or clean up. */ + PyErr_SetObject(PyExc_SystemExit, status); + return NULL; +} + + + +/*[clinic input] +sys.getdefaultencoding + +Return the current default encoding used by the Unicode implementation. +[clinic start generated code]*/ + +static PyObject * +sys_getdefaultencoding_impl(PyObject *module) +/*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/ +{ + return PyUnicode_FromString(PyUnicode_GetDefaultEncoding()); +} + +/*[clinic input] +sys.getfilesystemencoding + +Return the encoding used to convert Unicode filenames to OS filenames. +[clinic start generated code]*/ + +static PyObject * +sys_getfilesystemencoding_impl(PyObject *module) +/*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + const PyConfig *config = &interp->config; + return PyUnicode_FromWideChar(config->filesystem_encoding, -1); +} + +/*[clinic input] +sys.getfilesystemencodeerrors + +Return the error mode used Unicode to OS filename conversion. +[clinic start generated code]*/ + +static PyObject * +sys_getfilesystemencodeerrors_impl(PyObject *module) +/*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + const PyConfig *config = &interp->config; + return PyUnicode_FromWideChar(config->filesystem_errors, -1); +} + +/*[clinic input] +sys.intern + + string as s: unicode + / + +``Intern'' the given string. + +This enters the string in the (global) table of interned strings whose +purpose is to speed up dictionary lookups. Return the string itself or +the previously interned string object with the same value. +[clinic start generated code]*/ + +static PyObject * +sys_intern_impl(PyObject *module, PyObject *s) +/*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/ +{ + if (PyUnicode_CheckExact(s)) { + Py_INCREF(s); + PyUnicode_InternInPlace(&s); + return s; + } + else { + PyErr_Format(PyExc_TypeError, + "can't intern %.400s", s->ob_type->tp_name); + return NULL; + } +} + + +/* + * Cached interned string objects used for calling the profile and + * trace functions. Initialized by trace_init(). + */ +static PyObject *whatstrings[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + +static int +trace_init(void) +{ + static const char * const whatnames[8] = { + "call", "exception", "line", "return", + "c_call", "c_exception", "c_return", + "opcode" + }; + PyObject *name; + int i; + for (i = 0; i < 8; ++i) { + if (whatstrings[i] == NULL) { + name = PyUnicode_InternFromString(whatnames[i]); + if (name == NULL) + return -1; + whatstrings[i] = name; + } + } + return 0; +} + + +static PyObject * +call_trampoline(PyObject* callback, + PyFrameObject *frame, int what, PyObject *arg) +{ + PyObject *result; + PyObject *stack[3]; + + if (PyFrame_FastToLocalsWithError(frame) < 0) { + return NULL; + } + + stack[0] = (PyObject *)frame; + stack[1] = whatstrings[what]; + stack[2] = (arg != NULL) ? arg : Py_None; + + /* call the Python-level function */ + result = _PyObject_FastCall(callback, stack, 3); + + PyFrame_LocalsToFast(frame, 1); + if (result == NULL) { + PyTraceBack_Here(frame); + } + + return result; +} + +static int +profile_trampoline(PyObject *self, PyFrameObject *frame, + int what, PyObject *arg) +{ + PyObject *result; + + if (arg == NULL) + arg = Py_None; + result = call_trampoline(self, frame, what, arg); + if (result == NULL) { + PyEval_SetProfile(NULL, NULL); + return -1; + } + Py_DECREF(result); + return 0; +} + +static int +trace_trampoline(PyObject *self, PyFrameObject *frame, + int what, PyObject *arg) +{ + PyObject *callback; + PyObject *result; + + if (what == PyTrace_CALL) + callback = self; + else + callback = frame->f_trace; + if (callback == NULL) + return 0; + result = call_trampoline(callback, frame, what, arg); + if (result == NULL) { + PyEval_SetTrace(NULL, NULL); + Py_CLEAR(frame->f_trace); + return -1; + } + if (result != Py_None) { + Py_XSETREF(frame->f_trace, result); + } + else { + Py_DECREF(result); + } + return 0; +} + +static PyObject * +sys_settrace(PyObject *self, PyObject *args) +{ + if (trace_init() == -1) + return NULL; + if (args == Py_None) + PyEval_SetTrace(NULL, NULL); + else + PyEval_SetTrace(trace_trampoline, args); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(settrace_doc, +"settrace(function)\n\ +\n\ +Set the global debug tracing function. It will be called on each\n\ +function call. See the debugger chapter in the library manual." +); + +/*[clinic input] +sys.gettrace + +Return the global debug tracing function set with sys.settrace. + +See the debugger chapter in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys_gettrace_impl(PyObject *module) +/*[clinic end generated code: output=e97e3a4d8c971b6e input=373b51bb2147f4d8]*/ +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *temp = tstate->c_traceobj; + + if (temp == NULL) + temp = Py_None; + Py_INCREF(temp); + return temp; +} + +static PyObject * +sys_setprofile(PyObject *self, PyObject *args) +{ + if (trace_init() == -1) + return NULL; + if (args == Py_None) + PyEval_SetProfile(NULL, NULL); + else + PyEval_SetProfile(profile_trampoline, args); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setprofile_doc, +"setprofile(function)\n\ +\n\ +Set the profiling function. It will be called on each function call\n\ +and return. See the profiler chapter in the library manual." +); + +/*[clinic input] +sys.getprofile + +Return the profiling function set with sys.setprofile. + +See the profiler chapter in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys_getprofile_impl(PyObject *module) +/*[clinic end generated code: output=579b96b373448188 input=1b3209d89a32965d]*/ +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *temp = tstate->c_profileobj; + + if (temp == NULL) + temp = Py_None; + Py_INCREF(temp); + return temp; +} + +/*[clinic input] +sys.setcheckinterval + + n: int + / + +Set the async event check interval to n instructions. + +This tells the Python interpreter to check for asynchronous events +every n instructions. + +This also affects how often thread switches occur. +[clinic start generated code]*/ + +static PyObject * +sys_setcheckinterval_impl(PyObject *module, int n) +/*[clinic end generated code: output=3f686cef07e6e178 input=7a35b17bf22a6227]*/ +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "sys.getcheckinterval() and sys.setcheckinterval() " + "are deprecated. Use sys.setswitchinterval() " + "instead.", 1) < 0) + return NULL; + + PyInterpreterState *interp = _PyInterpreterState_Get(); + interp->check_interval = n; + Py_RETURN_NONE; +} + +/*[clinic input] +sys.getcheckinterval + +Return the current check interval; see sys.setcheckinterval(). +[clinic start generated code]*/ + +static PyObject * +sys_getcheckinterval_impl(PyObject *module) +/*[clinic end generated code: output=1b5060bf2b23a47c input=4b6589cbcca1db4e]*/ +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "sys.getcheckinterval() and sys.setcheckinterval() " + "are deprecated. Use sys.getswitchinterval() " + "instead.", 1) < 0) + return NULL; + PyInterpreterState *interp = _PyInterpreterState_Get(); + return PyLong_FromLong(interp->check_interval); +} + +/*[clinic input] +sys.setswitchinterval + + interval: double + / + +Set the ideal thread switching delay inside the Python interpreter. + +The actual frequency of switching threads can be lower if the +interpreter executes long sequences of uninterruptible code +(this is implementation-specific and workload-dependent). + +The parameter must represent the desired switching delay in seconds +A typical value is 0.005 (5 milliseconds). +[clinic start generated code]*/ + +static PyObject * +sys_setswitchinterval_impl(PyObject *module, double interval) +/*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/ +{ + if (interval <= 0.0) { + PyErr_SetString(PyExc_ValueError, + "switch interval must be strictly positive"); + return NULL; + } + _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval)); + Py_RETURN_NONE; +} + + +/*[clinic input] +sys.getswitchinterval -> double + +Return the current thread switch interval; see sys.setswitchinterval(). +[clinic start generated code]*/ + +static double +sys_getswitchinterval_impl(PyObject *module) +/*[clinic end generated code: output=a38c277c85b5096d input=bdf9d39c0ebbbb6f]*/ +{ + return 1e-6 * _PyEval_GetSwitchInterval(); +} + +/*[clinic input] +sys.setrecursionlimit + + limit as new_limit: int + / + +Set the maximum depth of the Python interpreter stack to n. + +This limit prevents infinite recursion from causing an overflow of the C +stack and crashing Python. The highest possible limit is platform- +dependent. +[clinic start generated code]*/ + +static PyObject * +sys_setrecursionlimit_impl(PyObject *module, int new_limit) +/*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/ +{ + int mark; + PyThreadState *tstate; + + if (new_limit < 1) { + PyErr_SetString(PyExc_ValueError, + "recursion limit must be greater or equal than 1"); + return NULL; + } + + /* Issue #25274: When the recursion depth hits the recursion limit in + _Py_CheckRecursiveCall(), the overflowed flag of the thread state is + set to 1 and a RecursionError is raised. The overflowed flag is reset + to 0 when the recursion depth goes below the low-water mark: see + Py_LeaveRecursiveCall(). + + Reject too low new limit if the current recursion depth is higher than + the new low-water mark. Otherwise it may not be possible anymore to + reset the overflowed flag to 0. */ + mark = _Py_RecursionLimitLowerWaterMark(new_limit); + tstate = _PyThreadState_GET(); + if (tstate->recursion_depth >= mark) { + PyErr_Format(PyExc_RecursionError, + "cannot set the recursion limit to %i at " + "the recursion depth %i: the limit is too low", + new_limit, tstate->recursion_depth); + return NULL; + } + + Py_SetRecursionLimit(new_limit); + Py_RETURN_NONE; +} + +/*[clinic input] +sys.set_coroutine_origin_tracking_depth + + depth: int + +Enable or disable origin tracking for coroutine objects in this thread. + +Coroutine objects will track 'depth' frames of traceback information +about where they came from, available in their cr_origin attribute. + +Set a depth of 0 to disable. +[clinic start generated code]*/ + +static PyObject * +sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth) +/*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/ +{ + if (depth < 0) { + PyErr_SetString(PyExc_ValueError, "depth must be >= 0"); + return NULL; + } + _PyEval_SetCoroutineOriginTrackingDepth(depth); + Py_RETURN_NONE; +} + +/*[clinic input] +sys.get_coroutine_origin_tracking_depth -> int + +Check status of origin tracking for coroutine objects in this thread. +[clinic start generated code]*/ + +static int +sys_get_coroutine_origin_tracking_depth_impl(PyObject *module) +/*[clinic end generated code: output=3699f7be95a3afb8 input=335266a71205b61a]*/ +{ + return _PyEval_GetCoroutineOriginTrackingDepth(); +} + +static PyTypeObject AsyncGenHooksType; + +PyDoc_STRVAR(asyncgen_hooks_doc, +"asyncgen_hooks\n\ +\n\ +A named tuple providing information about asynchronous\n\ +generators hooks. The attributes are read only."); + +static PyStructSequence_Field asyncgen_hooks_fields[] = { + {"firstiter", "Hook to intercept first iteration"}, + {"finalizer", "Hook to intercept finalization"}, + {0} +}; + +static PyStructSequence_Desc asyncgen_hooks_desc = { + "asyncgen_hooks", /* name */ + asyncgen_hooks_doc, /* doc */ + asyncgen_hooks_fields , /* fields */ + 2 +}; + +static int +set_async_gen_firstiter(PyObject *firstiter) +{ + PyThreadState *tstate = _PyThreadState_GET(); + + if (PySys_Audit("sys.set_asyncgen_hook_firstiter", NULL) < 0) { + return -1; + } + + Py_XINCREF(firstiter); + Py_XSETREF(tstate->async_gen_firstiter, firstiter); + return 0; +} + +void +_PyEval_SetAsyncGenFirstiter(PyObject *firstiter) +{ + if (set_async_gen_firstiter(firstiter) < 0) { + PyErr_WriteUnraisable(NULL); + } +} + +static int +set_async_gen_finalizer(PyObject *finalizer) +{ + PyThreadState *tstate = _PyThreadState_GET(); + + if (PySys_Audit("sys.set_asyncgen_hook_finalizer", NULL) < 0) { + return -1; + } + + Py_XINCREF(finalizer); + Py_XSETREF(tstate->async_gen_finalizer, finalizer); + return 0; +} + +void +_PyEval_SetAsyncGenFinalizer(PyObject *finalizer) +{ + if (set_async_gen_finalizer(finalizer) < 0) { + PyErr_WriteUnraisable(NULL); + } +} + + +static PyObject * +sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) +{ + static char *keywords[] = {"firstiter", "finalizer", NULL}; + PyObject *firstiter = NULL; + PyObject *finalizer = NULL; + + if (!PyArg_ParseTupleAndKeywords( + args, kw, "|OO", keywords, + &firstiter, &finalizer)) { + return NULL; + } + + if (finalizer && finalizer != Py_None) { + if (!PyCallable_Check(finalizer)) { + PyErr_Format(PyExc_TypeError, + "callable finalizer expected, got %.50s", + Py_TYPE(finalizer)->tp_name); + return NULL; + } + if (set_async_gen_finalizer(finalizer) < 0) { + return NULL; + } + } + else if (finalizer == Py_None && set_async_gen_finalizer(NULL) < 0) { + return NULL; + } + + if (firstiter && firstiter != Py_None) { + if (!PyCallable_Check(firstiter)) { + PyErr_Format(PyExc_TypeError, + "callable firstiter expected, got %.50s", + Py_TYPE(firstiter)->tp_name); + return NULL; + } + if (set_async_gen_firstiter(firstiter) < 0) { + return NULL; + } + } + else if (firstiter == Py_None && set_async_gen_firstiter(NULL) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(set_asyncgen_hooks_doc, +"set_asyncgen_hooks(* [, firstiter] [, finalizer])\n\ +\n\ +Set a finalizer for async generators objects." +); + +/*[clinic input] +sys.get_asyncgen_hooks + +Return the installed asynchronous generators hooks. + +This returns a namedtuple of the form (firstiter, finalizer). +[clinic start generated code]*/ + +static PyObject * +sys_get_asyncgen_hooks_impl(PyObject *module) +/*[clinic end generated code: output=53a253707146f6cf input=3676b9ea62b14625]*/ +{ + PyObject *res; + PyObject *firstiter = _PyEval_GetAsyncGenFirstiter(); + PyObject *finalizer = _PyEval_GetAsyncGenFinalizer(); + + res = PyStructSequence_New(&AsyncGenHooksType); + if (res == NULL) { + return NULL; + } + + if (firstiter == NULL) { + firstiter = Py_None; + } + + if (finalizer == NULL) { + finalizer = Py_None; + } + + Py_INCREF(firstiter); + PyStructSequence_SET_ITEM(res, 0, firstiter); + + Py_INCREF(finalizer); + PyStructSequence_SET_ITEM(res, 1, finalizer); + + return res; +} + + +static PyTypeObject Hash_InfoType; + +PyDoc_STRVAR(hash_info_doc, +"hash_info\n\ +\n\ +A named tuple providing parameters used for computing\n\ +hashes. The attributes are read only."); + +static PyStructSequence_Field hash_info_fields[] = { + {"width", "width of the type used for hashing, in bits"}, + {"modulus", "prime number giving the modulus on which the hash " + "function is based"}, + {"inf", "value to be used for hash of a positive infinity"}, + {"nan", "value to be used for hash of a nan"}, + {"imag", "multiplier used for the imaginary part of a complex number"}, + {"algorithm", "name of the algorithm for hashing of str, bytes and " + "memoryviews"}, + {"hash_bits", "internal output size of hash algorithm"}, + {"seed_bits", "seed size of hash algorithm"}, + {"cutoff", "small string optimization cutoff"}, + {NULL, NULL} +}; + +static PyStructSequence_Desc hash_info_desc = { + "sys.hash_info", + hash_info_doc, + hash_info_fields, + 9, +}; + +static PyObject * +get_hash_info(void) +{ + PyObject *hash_info; + int field = 0; + PyHash_FuncDef *hashfunc; + hash_info = PyStructSequence_New(&Hash_InfoType); + if (hash_info == NULL) + return NULL; + hashfunc = PyHash_GetFuncDef(); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(8*sizeof(Py_hash_t))); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromSsize_t(_PyHASH_MODULUS)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(_PyHASH_INF)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(_PyHASH_NAN)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(_PyHASH_IMAG)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyUnicode_FromString(hashfunc->name)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(hashfunc->hash_bits)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(hashfunc->seed_bits)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(Py_HASH_CUTOFF)); + if (PyErr_Occurred()) { + Py_CLEAR(hash_info); + return NULL; + } + return hash_info; +} +/*[clinic input] +sys.getrecursionlimit + +Return the current value of the recursion limit. + +The recursion limit is the maximum depth of the Python interpreter +stack. This limit prevents infinite recursion from causing an overflow +of the C stack and crashing Python. +[clinic start generated code]*/ + +static PyObject * +sys_getrecursionlimit_impl(PyObject *module) +/*[clinic end generated code: output=d571fb6b4549ef2e input=1c6129fd2efaeea8]*/ +{ + return PyLong_FromLong(Py_GetRecursionLimit()); +} + +#ifdef MS_WINDOWS + +static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0}; + +static PyStructSequence_Field windows_version_fields[] = { + {"major", "Major version number"}, + {"minor", "Minor version number"}, + {"build", "Build number"}, + {"platform", "Operating system platform"}, + {"service_pack", "Latest Service Pack installed on the system"}, + {"service_pack_major", "Service Pack major version number"}, + {"service_pack_minor", "Service Pack minor version number"}, + {"suite_mask", "Bit mask identifying available product suites"}, + {"product_type", "System product type"}, + {"platform_version", "Diagnostic version number"}, + {0} +}; + +static PyStructSequence_Desc windows_version_desc = { + "sys.getwindowsversion", /* name */ + sys_getwindowsversion__doc__, /* doc */ + windows_version_fields, /* fields */ + 5 /* For backward compatibility, + only the first 5 items are accessible + via indexing, the rest are name only */ +}; + +/* 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) + +/*[clinic input] +sys.getwindowsversion + +Return info about the running version of Windows as a named tuple. + +The members are named: major, minor, build, platform, service_pack, +service_pack_major, service_pack_minor, suite_mask, product_type and +platform_version. For backward compatibility, only the first 5 items +are available by indexing. All elements are numbers, except +service_pack and platform_type which are strings, and platform_version +which is a 3-tuple. Platform is always 2. Product_type may be 1 for a +workstation, 2 for a domain controller, 3 for a server. +Platform_version is a 3-tuple containing a version number that is +intended for identifying the OS rather than feature detection. +[clinic start generated code]*/ + +static PyObject * +sys_getwindowsversion_impl(PyObject *module) +/*[clinic end generated code: output=1ec063280b932857 input=73a228a328fee63a]*/ +{ + PyObject *version; + int pos = 0; + OSVERSIONINFOEXW ver; + DWORD realMajor, realMinor, realBuild; + HANDLE hKernel32; + wchar_t kernel32_path[MAX_PATH]; + LPVOID verblock; + DWORD verblock_size; + + ver.dwOSVersionInfoSize = sizeof(ver); + if (!GetVersionExW((OSVERSIONINFOW*) &ver)) + return PyErr_SetFromWindowsErr(0); + + version = PyStructSequence_New(&WindowsVersionType); + if (version == NULL) + return NULL; + + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion)); + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion)); + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber)); + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId)); + PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromWideChar(ver.szCSDVersion, -1)); + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor)); + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor)); + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); + PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); + + realMajor = ver.dwMajorVersion; + realMinor = ver.dwMinorVersion; + realBuild = ver.dwBuildNumber; + + // GetVersion will lie if we are running in a compatibility mode. + // We need to read the version info from a system file resource + // to accurately identify the OS version. If we fail for any reason, + // just return whatever GetVersion said. + Py_BEGIN_ALLOW_THREADS + hKernel32 = GetModuleHandleW(L"kernel32.dll"); + Py_END_ALLOW_THREADS + if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) && + (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) && + (verblock = PyMem_RawMalloc(verblock_size))) { + VS_FIXEDFILEINFO *ffi; + UINT ffi_len; + + if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) && + VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { + realMajor = HIWORD(ffi->dwProductVersionMS); + realMinor = LOWORD(ffi->dwProductVersionMS); + realBuild = HIWORD(ffi->dwProductVersionLS); + } + PyMem_RawFree(verblock); + } + PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)", + realMajor, + realMinor, + realBuild + )); + + if (PyErr_Occurred()) { + Py_DECREF(version); + return NULL; + } + + return version; +} + +#pragma warning(pop) + +/*[clinic input] +sys._enablelegacywindowsfsencoding + +Changes the default filesystem encoding to mbcs:replace. + +This is done for consistency with earlier versions of Python. See PEP +529 for more information. + +This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING +environment variable before launching Python. +[clinic start generated code]*/ + +static PyObject * +sys__enablelegacywindowsfsencoding_impl(PyObject *module) +/*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/ +{ + if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +#endif /* MS_WINDOWS */ + +#ifdef HAVE_DLOPEN + +/*[clinic input] +sys.setdlopenflags + + flags as new_val: int + / + +Set the flags used by the interpreter for dlopen calls. + +This is used, for example, when the interpreter loads extension +modules. Among other things, this will enable a lazy resolving of +symbols when importing a module, if called as sys.setdlopenflags(0). +To share symbols across extension modules, call as +sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag +modules can be found in the os module (RTLD_xxx constants, e.g. +os.RTLD_LAZY). +[clinic start generated code]*/ + +static PyObject * +sys_setdlopenflags_impl(PyObject *module, int new_val) +/*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + interp->dlopenflags = new_val; + Py_RETURN_NONE; +} + + +/*[clinic input] +sys.getdlopenflags + +Return the current value of the flags that are used for dlopen calls. + +The flag constants are defined in the os module. +[clinic start generated code]*/ + +static PyObject * +sys_getdlopenflags_impl(PyObject *module) +/*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + return PyLong_FromLong(interp->dlopenflags); +} + +#endif /* HAVE_DLOPEN */ + +#ifdef USE_MALLOPT +/* Link with -lmalloc (or -lmpc) on an SGI */ +#include + +/*[clinic input] +sys.mdebug + + flag: int + / +[clinic start generated code]*/ + +static PyObject * +sys_mdebug_impl(PyObject *module, int flag) +/*[clinic end generated code: output=5431d545847c3637 input=151d150ae1636f8a]*/ +{ + int flag; + mallopt(M_DEBUG, flag); + Py_RETURN_NONE; +} +#endif /* USE_MALLOPT */ + +size_t +_PySys_GetSizeOf(PyObject *o) +{ + PyObject *res = NULL; + PyObject *method; + Py_ssize_t size; + + /* Make sure the type is initialized. float gets initialized late */ + if (PyType_Ready(Py_TYPE(o)) < 0) + return (size_t)-1; + + method = _PyObject_LookupSpecial(o, &PyId___sizeof__); + if (method == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __sizeof__", + Py_TYPE(o)->tp_name); + } + else { + res = _PyObject_CallNoArg(method); + Py_DECREF(method); + } + + if (res == NULL) + return (size_t)-1; + + size = PyLong_AsSsize_t(res); + Py_DECREF(res); + if (size == -1 && PyErr_Occurred()) + return (size_t)-1; + + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0"); + return (size_t)-1; + } + + /* add gc_head size */ + if (PyObject_IS_GC(o)) + return ((size_t)size) + sizeof(PyGC_Head); + return (size_t)size; +} + +static PyObject * +sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"object", "default", 0}; + size_t size; + PyObject *o, *dflt = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", + kwlist, &o, &dflt)) + return NULL; + + size = _PySys_GetSizeOf(o); + + if (size == (size_t)-1 && PyErr_Occurred()) { + /* Has a default value been given */ + if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + Py_INCREF(dflt); + return dflt; + } + else + return NULL; + } + + return PyLong_FromSize_t(size); +} + +PyDoc_STRVAR(getsizeof_doc, +"getsizeof(object [, default]) -> int\n\ +\n\ +Return the size of object in bytes."); + +/*[clinic input] +sys.getrefcount -> Py_ssize_t + + object: object + / + +Return the reference count of object. + +The count returned is generally one higher than you might expect, +because it includes the (temporary) reference as an argument to +getrefcount(). +[clinic start generated code]*/ + +static Py_ssize_t +sys_getrefcount_impl(PyObject *module, PyObject *object) +/*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/ +{ + return object->ob_refcnt; +} + +#ifdef Py_REF_DEBUG +/*[clinic input] +sys.gettotalrefcount -> Py_ssize_t +[clinic start generated code]*/ + +static Py_ssize_t +sys_gettotalrefcount_impl(PyObject *module) +/*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/ +{ + return _Py_GetRefTotal(); +} +#endif /* Py_REF_DEBUG */ + +/*[clinic input] +sys.getallocatedblocks -> Py_ssize_t + +Return the number of memory blocks currently allocated. +[clinic start generated code]*/ + +static Py_ssize_t +sys_getallocatedblocks_impl(PyObject *module) +/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/ +{ + return _Py_GetAllocatedBlocks(); +} + +#ifdef COUNT_ALLOCS +/*[clinic input] +sys.getcounts +[clinic start generated code]*/ + +static PyObject * +sys_getcounts_impl(PyObject *module) +/*[clinic end generated code: output=20df00bc164f43cb input=ad2ec7bda5424953]*/ +{ + extern PyObject *_Py_get_counts(void); + + return _Py_get_counts(); +} +#endif + +/*[clinic input] +sys._getframe + + depth: int = 0 + / + +Return a frame object from the call stack. + +If optional integer depth is given, return the frame object that many +calls below the top of the stack. If that is deeper than the call +stack, ValueError is raised. The default for depth is zero, returning +the frame at the top of the call stack. + +This function should be used for internal and specialized purposes +only. +[clinic start generated code]*/ + +static PyObject * +sys__getframe_impl(PyObject *module, int depth) +/*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/ +{ + PyFrameObject *f = _PyThreadState_GET()->frame; + + if (PySys_Audit("sys._getframe", "O", f) < 0) { + return NULL; + } + + while (depth > 0 && f != NULL) { + f = f->f_back; + --depth; + } + if (f == NULL) { + PyErr_SetString(PyExc_ValueError, + "call stack is not deep enough"); + return NULL; + } + Py_INCREF(f); + return (PyObject*)f; +} + +/*[clinic input] +sys._current_frames + +Return a dict mapping each thread's thread id to its current stack frame. + +This function should be used for specialized purposes only. +[clinic start generated code]*/ + +static PyObject * +sys__current_frames_impl(PyObject *module) +/*[clinic end generated code: output=d2a41ac0a0a3809a input=2a9049c5f5033691]*/ +{ + return _PyThread_CurrentFrames(); +} + +/*[clinic input] +sys.call_tracing + + func: object + args as funcargs: object(subclass_of='&PyTuple_Type') + / + +Call func(*args), while tracing is enabled. + +The tracing state is saved, and restored afterwards. This is intended +to be called from a debugger from a checkpoint, to recursively debug +some other code. +[clinic start generated code]*/ + +static PyObject * +sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs) +/*[clinic end generated code: output=7e4999853cd4e5a6 input=5102e8b11049f92f]*/ +{ + return _PyEval_CallTracing(func, funcargs); +} + +/*[clinic input] +sys.callstats + +Return a tuple of function call statistics. + +A tuple is returned only if CALL_PROFILE was defined when Python was +built. Otherwise, this returns None. + +When enabled, this function returns detailed, implementation-specific +details about the number of function calls executed. The return value +is a 11-tuple where the entries in the tuple are counts of: +0. all function calls +1. calls to PyFunction_Type objects +2. PyFunction calls that do not create an argument tuple +3. PyFunction calls that do not create an argument tuple + and bypass PyEval_EvalCodeEx() +4. PyMethod calls +5. PyMethod calls on bound methods +6. PyType calls +7. PyCFunction calls +8. generator calls +9. All other calls +10. Number of stack pops performed by call_function() +[clinic start generated code]*/ + +static PyObject * +sys_callstats_impl(PyObject *module) +/*[clinic end generated code: output=edc4a74957fa8def input=d447d8d224d5d175]*/ +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "sys.callstats() has been deprecated in Python 3.7 " + "and will be removed in the future", 1) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + + +#ifdef __cplusplus +extern "C" { +#endif + +/*[clinic input] +sys._debugmallocstats + +Print summary info to stderr about the state of pymalloc's structures. + +In Py_DEBUG mode, also perform some expensive internal consistency +checks. +[clinic start generated code]*/ + +static PyObject * +sys__debugmallocstats_impl(PyObject *module) +/*[clinic end generated code: output=ec3565f8c7cee46a input=33c0c9c416f98424]*/ +{ +#ifdef WITH_PYMALLOC + if (_PyObject_DebugMallocStats(stderr)) { + fputc('\n', stderr); + } +#endif + _PyObject_DebugTypeStats(stderr); + + Py_RETURN_NONE; +} + +#ifdef Py_TRACE_REFS +/* Defined in objects.c because it uses static globals if that file */ +extern PyObject *_Py_GetObjects(PyObject *, PyObject *); +#endif + +#ifdef DYNAMIC_EXECUTION_PROFILE +/* Defined in ceval.c because it uses static globals if that file */ +extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); +#endif + +#ifdef __cplusplus +} +#endif + + +/*[clinic input] +sys._clear_type_cache + +Clear the internal type lookup cache. +[clinic start generated code]*/ + +static PyObject * +sys__clear_type_cache_impl(PyObject *module) +/*[clinic end generated code: output=20e48ca54a6f6971 input=127f3e04a8d9b555]*/ +{ + PyType_ClearCache(); + Py_RETURN_NONE; +} + +/*[clinic input] +sys.is_finalizing + +Return True if Python is exiting. +[clinic start generated code]*/ + +static PyObject * +sys_is_finalizing_impl(PyObject *module) +/*[clinic end generated code: output=735b5ff7962ab281 input=f0df747a039948a5]*/ +{ + return PyBool_FromLong(_Py_IsFinalizing()); +} + +#ifdef ANDROID_API_LEVEL +/*[clinic input] +sys.getandroidapilevel + +Return the build time API version of Android as an integer. +[clinic start generated code]*/ + +static PyObject * +sys_getandroidapilevel_impl(PyObject *module) +/*[clinic end generated code: output=214abf183a1c70c1 input=3e6d6c9fcdd24ac6]*/ +{ + return PyLong_FromLong(ANDROID_API_LEVEL); +} +#endif /* ANDROID_API_LEVEL */ + + + +static PyMethodDef sys_methods[] = { + /* Might as well keep this in alphabetic order */ + SYS_ADDAUDITHOOK_METHODDEF + {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc }, + {"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook, + METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc}, + SYS_CALLSTATS_METHODDEF + SYS__CLEAR_TYPE_CACHE_METHODDEF + SYS__CURRENT_FRAMES_METHODDEF + SYS_DISPLAYHOOK_METHODDEF + SYS_EXC_INFO_METHODDEF + SYS_EXCEPTHOOK_METHODDEF + SYS_EXIT_METHODDEF + SYS_GETDEFAULTENCODING_METHODDEF + SYS_GETDLOPENFLAGS_METHODDEF + SYS_GETALLOCATEDBLOCKS_METHODDEF + SYS_GETCOUNTS_METHODDEF +#ifdef DYNAMIC_EXECUTION_PROFILE + {"getdxp", _Py_GetDXProfile, METH_VARARGS}, +#endif + SYS_GETFILESYSTEMENCODING_METHODDEF + SYS_GETFILESYSTEMENCODEERRORS_METHODDEF +#ifdef Py_TRACE_REFS + {"getobjects", _Py_GetObjects, METH_VARARGS}, +#endif + SYS_GETTOTALREFCOUNT_METHODDEF + SYS_GETREFCOUNT_METHODDEF + SYS_GETRECURSIONLIMIT_METHODDEF + {"getsizeof", (PyCFunction)(void(*)(void))sys_getsizeof, + METH_VARARGS | METH_KEYWORDS, getsizeof_doc}, + SYS__GETFRAME_METHODDEF + SYS_GETWINDOWSVERSION_METHODDEF + SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF + SYS_INTERN_METHODDEF + SYS_IS_FINALIZING_METHODDEF + SYS_MDEBUG_METHODDEF + SYS_SETCHECKINTERVAL_METHODDEF + SYS_GETCHECKINTERVAL_METHODDEF + SYS_SETSWITCHINTERVAL_METHODDEF + SYS_GETSWITCHINTERVAL_METHODDEF + SYS_SETDLOPENFLAGS_METHODDEF + {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + SYS_GETPROFILE_METHODDEF + SYS_SETRECURSIONLIMIT_METHODDEF + {"settrace", sys_settrace, METH_O, settrace_doc}, + SYS_GETTRACE_METHODDEF + SYS_CALL_TRACING_METHODDEF + SYS__DEBUGMALLOCSTATS_METHODDEF + SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF + SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF + {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks, + METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, + SYS_GET_ASYNCGEN_HOOKS_METHODDEF + SYS_GETANDROIDAPILEVEL_METHODDEF + SYS_UNRAISABLEHOOK_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +list_builtin_module_names(void) +{ + PyObject *list = PyList_New(0); + int i; + if (list == NULL) + return NULL; + for (i = 0; PyImport_Inittab[i].name != NULL; i++) { + PyObject *name = PyUnicode_FromString( + PyImport_Inittab[i].name); + if (name == NULL) + break; + PyList_Append(list, name); + Py_DECREF(name); + } + if (PyList_Sort(list) != 0) { + Py_DECREF(list); + list = NULL; + } + if (list) { + PyObject *v = PyList_AsTuple(list); + Py_DECREF(list); + list = v; + } + return list; +} + +/* Pre-initialization support for sys.warnoptions and sys._xoptions + * + * Modern internal code paths: + * These APIs get called after _Py_InitializeCore and get to use the + * regular CPython list, dict, and unicode APIs. + * + * Legacy embedding code paths: + * The multi-phase initialization API isn't public yet, so embedding + * apps still need to be able configure sys.warnoptions and sys._xoptions + * before they call Py_Initialize. To support this, we stash copies of + * the supplied wchar * sequences in linked lists, and then migrate the + * contents of those lists to the sys module in _PyInitializeCore. + * + */ + +struct _preinit_entry { + wchar_t *value; + struct _preinit_entry *next; +}; + +typedef struct _preinit_entry *_Py_PreInitEntry; + +static _Py_PreInitEntry _preinit_warnoptions = NULL; +static _Py_PreInitEntry _preinit_xoptions = NULL; + +static _Py_PreInitEntry +_alloc_preinit_entry(const wchar_t *value) +{ + /* To get this to work, we have to initialize the runtime implicitly */ + _PyRuntime_Initialize(); + + /* Force default allocator, so we can ensure that it also gets used to + * destroy the linked list in _clear_preinit_entries. + */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + _Py_PreInitEntry node = PyMem_RawCalloc(1, sizeof(*node)); + if (node != NULL) { + node->value = _PyMem_RawWcsdup(value); + if (node->value == NULL) { + PyMem_RawFree(node); + node = NULL; + }; + }; + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return node; +} + +static int +_append_preinit_entry(_Py_PreInitEntry *optionlist, const wchar_t *value) +{ + _Py_PreInitEntry new_entry = _alloc_preinit_entry(value); + if (new_entry == NULL) { + return -1; + } + /* We maintain the linked list in this order so it's easy to play back + * the add commands in the same order later on in _Py_InitializeCore + */ + _Py_PreInitEntry last_entry = *optionlist; + if (last_entry == NULL) { + *optionlist = new_entry; + } else { + while (last_entry->next != NULL) { + last_entry = last_entry->next; + } + last_entry->next = new_entry; + } + return 0; +} + +static void +_clear_preinit_entries(_Py_PreInitEntry *optionlist) +{ + _Py_PreInitEntry current = *optionlist; + *optionlist = NULL; + /* Deallocate the nodes and their contents using the default allocator */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + while (current != NULL) { + _Py_PreInitEntry next = current->next; + PyMem_RawFree(current->value); + PyMem_RawFree(current); + current = next; + } + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} + + +PyStatus +_PySys_ReadPreinitWarnOptions(PyWideStringList *options) +{ + PyStatus status; + _Py_PreInitEntry entry; + + for (entry = _preinit_warnoptions; entry != NULL; entry = entry->next) { + status = PyWideStringList_Append(options, entry->value); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + _clear_preinit_entries(&_preinit_warnoptions); + return _PyStatus_OK(); +} + + +PyStatus +_PySys_ReadPreinitXOptions(PyConfig *config) +{ + PyStatus status; + _Py_PreInitEntry entry; + + for (entry = _preinit_xoptions; entry != NULL; entry = entry->next) { + status = PyWideStringList_Append(&config->xoptions, entry->value); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + _clear_preinit_entries(&_preinit_xoptions); + return _PyStatus_OK(); +} + + +static PyObject * +get_warnoptions(void) +{ + PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); + if (warnoptions == NULL || !PyList_Check(warnoptions)) { + /* PEP432 TODO: we can reach this if warnoptions is NULL in the main + * interpreter config. When that happens, we need to properly set + * the `warnoptions` reference in the main interpreter config as well. + * + * For Python 3.7, we shouldn't be able to get here due to the + * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit + * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig + * call optional for embedding applications, thus making this + * reachable again. + */ + warnoptions = PyList_New(0); + if (warnoptions == NULL) + return NULL; + if (_PySys_SetObjectId(&PyId_warnoptions, warnoptions)) { + Py_DECREF(warnoptions); + return NULL; + } + Py_DECREF(warnoptions); + } + return warnoptions; +} + +void +PySys_ResetWarnOptions(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) { + _clear_preinit_entries(&_preinit_warnoptions); + return; + } + + PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); + if (warnoptions == NULL || !PyList_Check(warnoptions)) + return; + PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL); +} + +static int +_PySys_AddWarnOptionWithError(PyObject *option) +{ + PyObject *warnoptions = get_warnoptions(); + if (warnoptions == NULL) { + return -1; + } + if (PyList_Append(warnoptions, option)) { + return -1; + } + return 0; +} + +void +PySys_AddWarnOptionUnicode(PyObject *option) +{ + if (_PySys_AddWarnOptionWithError(option) < 0) { + /* No return value, therefore clear error state if possible */ + if (_PyThreadState_UncheckedGet()) { + PyErr_Clear(); + } + } +} + +void +PySys_AddWarnOption(const wchar_t *s) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) { + _append_preinit_entry(&_preinit_warnoptions, s); + return; + } + PyObject *unicode; + unicode = PyUnicode_FromWideChar(s, -1); + if (unicode == NULL) + return; + PySys_AddWarnOptionUnicode(unicode); + Py_DECREF(unicode); +} + +int +PySys_HasWarnOptions(void) +{ + PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); + return (warnoptions != NULL && PyList_Check(warnoptions) + && PyList_GET_SIZE(warnoptions) > 0); +} + +static PyObject * +get_xoptions(void) +{ + PyObject *xoptions = _PySys_GetObjectId(&PyId__xoptions); + if (xoptions == NULL || !PyDict_Check(xoptions)) { + /* PEP432 TODO: we can reach this if xoptions is NULL in the main + * interpreter config. When that happens, we need to properly set + * the `xoptions` reference in the main interpreter config as well. + * + * For Python 3.7, we shouldn't be able to get here due to the + * combination of how _PyMainInterpreter_ReadConfig and _PySys_EndInit + * work, but we expect 3.8+ to make the _PyMainInterpreter_ReadConfig + * call optional for embedding applications, thus making this + * reachable again. + */ + xoptions = PyDict_New(); + if (xoptions == NULL) + return NULL; + if (_PySys_SetObjectId(&PyId__xoptions, xoptions)) { + Py_DECREF(xoptions); + return NULL; + } + Py_DECREF(xoptions); + } + return xoptions; +} + +static int +_PySys_AddXOptionWithError(const wchar_t *s) +{ + PyObject *name = NULL, *value = NULL; + + PyObject *opts = get_xoptions(); + if (opts == NULL) { + goto error; + } + + const wchar_t *name_end = wcschr(s, L'='); + if (!name_end) { + name = PyUnicode_FromWideChar(s, -1); + value = Py_True; + Py_INCREF(value); + } + else { + name = PyUnicode_FromWideChar(s, name_end - s); + value = PyUnicode_FromWideChar(name_end + 1, -1); + } + if (name == NULL || value == NULL) { + goto error; + } + if (PyDict_SetItem(opts, name, value) < 0) { + goto error; + } + Py_DECREF(name); + Py_DECREF(value); + return 0; + +error: + Py_XDECREF(name); + Py_XDECREF(value); + return -1; +} + +void +PySys_AddXOption(const wchar_t *s) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) { + _append_preinit_entry(&_preinit_xoptions, s); + return; + } + if (_PySys_AddXOptionWithError(s) < 0) { + /* No return value, therefore clear error state if possible */ + PyErr_Clear(); + } +} + +PyObject * +PySys_GetXOptions(void) +{ + return get_xoptions(); +} + +/* XXX This doc string is too long to be a single string literal in VC++ 5.0. + Two literals concatenated works just fine. If you have a K&R compiler + or other abomination that however *does* understand longer strings, + get rid of the !!! comment in the middle and the quotes that surround it. */ +PyDoc_VAR(sys_doc) = +PyDoc_STR( +"This module provides access to some objects used or maintained by the\n\ +interpreter and to functions that interact strongly with the interpreter.\n\ +\n\ +Dynamic objects:\n\ +\n\ +argv -- command line arguments; argv[0] is the script pathname if known\n\ +path -- module search path; path[0] is the script directory, else ''\n\ +modules -- dictionary of loaded modules\n\ +\n\ +displayhook -- called to show results in an interactive session\n\ +excepthook -- called to handle any uncaught exception other than SystemExit\n\ + To customize printing in an interactive session or to install a custom\n\ + top-level exception handler, assign other functions to replace these.\n\ +\n\ +stdin -- standard input file object; used by input()\n\ +stdout -- standard output file object; used by print()\n\ +stderr -- standard error object; used for error messages\n\ + By assigning other file objects (or objects that behave like files)\n\ + to these, it is possible to redirect all of the interpreter's I/O.\n\ +\n\ +last_type -- type of last uncaught exception\n\ +last_value -- value of last uncaught exception\n\ +last_traceback -- traceback of last uncaught exception\n\ + These three are only available in an interactive session after a\n\ + traceback has been printed.\n\ +" +) +/* concatenating string here */ +PyDoc_STR( +"\n\ +Static objects:\n\ +\n\ +builtin_module_names -- tuple of module names built into this interpreter\n\ +copyright -- copyright notice pertaining to this interpreter\n\ +exec_prefix -- prefix used to find the machine-specific Python library\n\ +executable -- absolute path of the executable binary of the Python interpreter\n\ +float_info -- a named tuple with information about the float implementation.\n\ +float_repr_style -- string indicating the style of repr() output for floats\n\ +hash_info -- a named tuple with information about the hash algorithm.\n\ +hexversion -- version information encoded as a single integer\n\ +implementation -- Python implementation information.\n\ +int_info -- a named tuple with information about the int implementation.\n\ +maxsize -- the largest supported length of containers.\n\ +maxunicode -- the value of the largest Unicode code point\n\ +platform -- platform identifier\n\ +prefix -- prefix used to find the Python library\n\ +thread_info -- a named tuple with information about the thread implementation.\n\ +version -- the version of this interpreter as a string\n\ +version_info -- version information as a named tuple\n\ +" +) +#ifdef MS_COREDLL +/* concatenating string here */ +PyDoc_STR( +"dllhandle -- [Windows only] integer handle of the Python DLL\n\ +winver -- [Windows only] version number of the Python DLL\n\ +" +) +#endif /* MS_COREDLL */ +#ifdef MS_WINDOWS +/* concatenating string here */ +PyDoc_STR( +"_enablelegacywindowsfsencoding -- [Windows only]\n\ +" +) +#endif +PyDoc_STR( +"__stdin__ -- the original stdin; don't touch!\n\ +__stdout__ -- the original stdout; don't touch!\n\ +__stderr__ -- the original stderr; don't touch!\n\ +__displayhook__ -- the original displayhook; don't touch!\n\ +__excepthook__ -- the original excepthook; don't touch!\n\ +\n\ +Functions:\n\ +\n\ +displayhook() -- print an object to the screen, and save it in builtins._\n\ +excepthook() -- print an exception and its traceback to sys.stderr\n\ +exc_info() -- return thread-safe information about the current exception\n\ +exit() -- exit the interpreter by raising SystemExit\n\ +getdlopenflags() -- returns flags to be used for dlopen() calls\n\ +getprofile() -- get the global profiling function\n\ +getrefcount() -- return the reference count for an object (plus one :-)\n\ +getrecursionlimit() -- return the max recursion depth for the interpreter\n\ +getsizeof() -- return the size of an object in bytes\n\ +gettrace() -- get the global debug tracing function\n\ +setcheckinterval() -- control how often the interpreter checks for events\n\ +setdlopenflags() -- set the flags to be used for dlopen() calls\n\ +setprofile() -- set the global profiling function\n\ +setrecursionlimit() -- set the max recursion depth for the interpreter\n\ +settrace() -- set the global debug tracing function\n\ +" +) +/* end of sys_doc */ ; + + +PyDoc_STRVAR(flags__doc__, +"sys.flags\n\ +\n\ +Flags provided through command line arguments or environment vars."); + +static PyTypeObject FlagsType; + +static PyStructSequence_Field flags_fields[] = { + {"debug", "-d"}, + {"inspect", "-i"}, + {"interactive", "-i"}, + {"optimize", "-O or -OO"}, + {"dont_write_bytecode", "-B"}, + {"no_user_site", "-s"}, + {"no_site", "-S"}, + {"ignore_environment", "-E"}, + {"verbose", "-v"}, + /* {"unbuffered", "-u"}, */ + /* {"skip_first", "-x"}, */ + {"bytes_warning", "-b"}, + {"quiet", "-q"}, + {"hash_randomization", "-R"}, + {"isolated", "-I"}, + {"dev_mode", "-X dev"}, + {"utf8_mode", "-X utf8"}, + {0} +}; + +static PyStructSequence_Desc flags_desc = { + "sys.flags", /* name */ + flags__doc__, /* doc */ + flags_fields, /* fields */ + 15 +}; + +static PyObject* +make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) +{ + int pos = 0; + PyObject *seq; + const PyPreConfig *preconfig = &runtime->preconfig; + const PyConfig *config = &interp->config; + + seq = PyStructSequence_New(&FlagsType); + if (seq == NULL) + return NULL; + +#define SetFlag(flag) \ + PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag)) + + SetFlag(config->parser_debug); + SetFlag(config->inspect); + SetFlag(config->interactive); + SetFlag(config->optimization_level); + SetFlag(!config->write_bytecode); + SetFlag(!config->user_site_directory); + SetFlag(!config->site_import); + SetFlag(!config->use_environment); + SetFlag(config->verbose); + /* SetFlag(saw_unbuffered_flag); */ + /* SetFlag(skipfirstline); */ + SetFlag(config->bytes_warning); + SetFlag(config->quiet); + SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0); + SetFlag(config->isolated); + PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode)); + SetFlag(preconfig->utf8_mode); +#undef SetFlag + + if (PyErr_Occurred()) { + Py_DECREF(seq); + return NULL; + } + return seq; +} + +PyDoc_STRVAR(version_info__doc__, +"sys.version_info\n\ +\n\ +Version information as a named tuple."); + +static PyTypeObject VersionInfoType; + +static PyStructSequence_Field version_info_fields[] = { + {"major", "Major release number"}, + {"minor", "Minor release number"}, + {"micro", "Patch release number"}, + {"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"}, + {"serial", "Serial release number"}, + {0} +}; + +static PyStructSequence_Desc version_info_desc = { + "sys.version_info", /* name */ + version_info__doc__, /* doc */ + version_info_fields, /* fields */ + 5 +}; + +static PyObject * +make_version_info(void) +{ + PyObject *version_info; + char *s; + int pos = 0; + + version_info = PyStructSequence_New(&VersionInfoType); + if (version_info == NULL) { + return NULL; + } + + /* + * These release level checks are mutually exclusive and cover + * the field, so don't get too fancy with the pre-processor! + */ +#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA + s = "alpha"; +#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA + s = "beta"; +#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA + s = "candidate"; +#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL + s = "final"; +#endif + +#define SetIntItem(flag) \ + PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag)) +#define SetStrItem(flag) \ + PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag)) + + SetIntItem(PY_MAJOR_VERSION); + SetIntItem(PY_MINOR_VERSION); + SetIntItem(PY_MICRO_VERSION); + SetStrItem(s); + SetIntItem(PY_RELEASE_SERIAL); +#undef SetIntItem +#undef SetStrItem + + if (PyErr_Occurred()) { + Py_CLEAR(version_info); + return NULL; + } + return version_info; +} + +/* sys.implementation values */ +#define NAME "cpython" +const char *_PySys_ImplName = NAME; +#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION) +#define MINOR Py_STRINGIFY(PY_MINOR_VERSION) +#define TAG NAME "-" MAJOR MINOR +const char *_PySys_ImplCacheTag = TAG; +#undef NAME +#undef MAJOR +#undef MINOR +#undef TAG + +static PyObject * +make_impl_info(PyObject *version_info) +{ + int res; + PyObject *impl_info, *value, *ns; + + impl_info = PyDict_New(); + if (impl_info == NULL) + return NULL; + + /* populate the dict */ + + value = PyUnicode_FromString(_PySys_ImplName); + if (value == NULL) + goto error; + res = PyDict_SetItemString(impl_info, "name", value); + Py_DECREF(value); + if (res < 0) + goto error; + + value = PyUnicode_FromString(_PySys_ImplCacheTag); + if (value == NULL) + goto error; + res = PyDict_SetItemString(impl_info, "cache_tag", value); + Py_DECREF(value); + if (res < 0) + goto error; + + res = PyDict_SetItemString(impl_info, "version", version_info); + if (res < 0) + goto error; + + value = PyLong_FromLong(PY_VERSION_HEX); + if (value == NULL) + goto error; + res = PyDict_SetItemString(impl_info, "hexversion", value); + Py_DECREF(value); + if (res < 0) + goto error; + +#ifdef MULTIARCH + value = PyUnicode_FromString(MULTIARCH); + if (value == NULL) + goto error; + res = PyDict_SetItemString(impl_info, "_multiarch", value); + Py_DECREF(value); + if (res < 0) + goto error; +#endif + + /* dict ready */ + + ns = _PyNamespace_New(impl_info); + Py_DECREF(impl_info); + return ns; + +error: + Py_CLEAR(impl_info); + return NULL; +} + +static struct PyModuleDef sysmodule = { + PyModuleDef_HEAD_INIT, + "sys", + sys_doc, + -1, /* multiple "initialization" just copies the module dict. */ + sys_methods, + NULL, + NULL, + NULL, + NULL +}; + +/* Updating the sys namespace, returning NULL pointer on error */ +#define SET_SYS_FROM_STRING_BORROW(key, value) \ + do { \ + PyObject *v = (value); \ + if (v == NULL) { \ + goto err_occurred; \ + } \ + res = PyDict_SetItemString(sysdict, key, v); \ + if (res < 0) { \ + goto err_occurred; \ + } \ + } while (0) +#define SET_SYS_FROM_STRING(key, value) \ + do { \ + PyObject *v = (value); \ + if (v == NULL) { \ + goto err_occurred; \ + } \ + res = PyDict_SetItemString(sysdict, key, v); \ + Py_DECREF(v); \ + if (res < 0) { \ + goto err_occurred; \ + } \ + } while (0) + +static PyStatus +_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject *sysdict) +{ + PyObject *version_info; + int res; + + /* stdin/stdout/stderr are set in pylifecycle.c */ + + SET_SYS_FROM_STRING_BORROW("__displayhook__", + PyDict_GetItemString(sysdict, "displayhook")); + SET_SYS_FROM_STRING_BORROW("__excepthook__", + PyDict_GetItemString(sysdict, "excepthook")); + SET_SYS_FROM_STRING_BORROW( + "__breakpointhook__", + PyDict_GetItemString(sysdict, "breakpointhook")); + SET_SYS_FROM_STRING_BORROW("__unraisablehook__", + PyDict_GetItemString(sysdict, "unraisablehook")); + + SET_SYS_FROM_STRING("version", + PyUnicode_FromString(Py_GetVersion())); + SET_SYS_FROM_STRING("hexversion", + PyLong_FromLong(PY_VERSION_HEX)); + SET_SYS_FROM_STRING("_git", + Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), + _Py_gitversion())); + SET_SYS_FROM_STRING("_framework", PyUnicode_FromString(_PYTHONFRAMEWORK)); + SET_SYS_FROM_STRING("api_version", + PyLong_FromLong(PYTHON_API_VERSION)); + SET_SYS_FROM_STRING("copyright", + PyUnicode_FromString(Py_GetCopyright())); + SET_SYS_FROM_STRING("platform", + PyUnicode_FromString(Py_GetPlatform())); + SET_SYS_FROM_STRING("maxsize", + PyLong_FromSsize_t(PY_SSIZE_T_MAX)); + SET_SYS_FROM_STRING("float_info", + PyFloat_GetInfo()); + SET_SYS_FROM_STRING("int_info", + PyLong_GetInfo()); + /* initialize hash_info */ + if (Hash_InfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) { + goto type_init_failed; + } + } + SET_SYS_FROM_STRING("hash_info", + get_hash_info()); + SET_SYS_FROM_STRING("maxunicode", + PyLong_FromLong(0x10FFFF)); + SET_SYS_FROM_STRING("builtin_module_names", + list_builtin_module_names()); +#if PY_BIG_ENDIAN + SET_SYS_FROM_STRING("byteorder", + PyUnicode_FromString("big")); +#else + SET_SYS_FROM_STRING("byteorder", + PyUnicode_FromString("little")); +#endif + +#ifdef MS_COREDLL + SET_SYS_FROM_STRING("dllhandle", + PyLong_FromVoidPtr(PyWin_DLLhModule)); + SET_SYS_FROM_STRING("winver", + PyUnicode_FromString(PyWin_DLLVersionString)); +#endif +#ifdef ABIFLAGS + SET_SYS_FROM_STRING("abiflags", + PyUnicode_FromString(ABIFLAGS)); +#endif + + /* version_info */ + if (VersionInfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&VersionInfoType, + &version_info_desc) < 0) { + goto type_init_failed; + } + } + version_info = make_version_info(); + SET_SYS_FROM_STRING("version_info", version_info); + /* prevent user from creating new instances */ + VersionInfoType.tp_init = NULL; + VersionInfoType.tp_new = NULL; + res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__"); + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); + + /* implementation */ + SET_SYS_FROM_STRING("implementation", make_impl_info(version_info)); + + /* flags */ + if (FlagsType.tp_name == 0) { + if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) { + goto type_init_failed; + } + } + /* Set flags to their default values (updated by _PySys_InitMain()) */ + SET_SYS_FROM_STRING("flags", make_flags(runtime, interp)); + +#if defined(MS_WINDOWS) + /* getwindowsversion */ + if (WindowsVersionType.tp_name == 0) + if (PyStructSequence_InitType2(&WindowsVersionType, + &windows_version_desc) < 0) { + goto type_init_failed; + } + /* prevent user from creating new instances */ + WindowsVersionType.tp_init = NULL; + WindowsVersionType.tp_new = NULL; + assert(!PyErr_Occurred()); + res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__"); + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + } +#endif + + /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ +#ifndef PY_NO_SHORT_FLOAT_REPR + SET_SYS_FROM_STRING("float_repr_style", + PyUnicode_FromString("short")); +#else + SET_SYS_FROM_STRING("float_repr_style", + PyUnicode_FromString("legacy")); +#endif + + SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo()); + + /* initialize asyncgen_hooks */ + if (AsyncGenHooksType.tp_name == NULL) { + if (PyStructSequence_InitType2( + &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) { + goto type_init_failed; + } + } + + if (PyErr_Occurred()) { + goto err_occurred; + } + return _PyStatus_OK(); + +type_init_failed: + return _PyStatus_ERR("failed to initialize a type"); + +err_occurred: + return _PyStatus_ERR("can't initialize sys module"); +} + +#undef SET_SYS_FROM_STRING + +/* Updating the sys namespace, returning integer error codes */ +#define SET_SYS_FROM_STRING_INT_RESULT(key, value) \ + do { \ + PyObject *v = (value); \ + if (v == NULL) \ + return -1; \ + res = PyDict_SetItemString(sysdict, key, v); \ + Py_DECREF(v); \ + if (res < 0) { \ + return res; \ + } \ + } while (0) + + +static int +sys_add_xoption(PyObject *opts, const wchar_t *s) +{ + PyObject *name, *value; + + const wchar_t *name_end = wcschr(s, L'='); + if (!name_end) { + name = PyUnicode_FromWideChar(s, -1); + value = Py_True; + Py_INCREF(value); + } + else { + name = PyUnicode_FromWideChar(s, name_end - s); + value = PyUnicode_FromWideChar(name_end + 1, -1); + } + if (name == NULL || value == NULL) { + goto error; + } + if (PyDict_SetItem(opts, name, value) < 0) { + goto error; + } + Py_DECREF(name); + Py_DECREF(value); + return 0; + +error: + Py_XDECREF(name); + Py_XDECREF(value); + return -1; +} + + +static PyObject* +sys_create_xoptions_dict(const PyConfig *config) +{ + Py_ssize_t nxoption = config->xoptions.length; + wchar_t * const * xoptions = config->xoptions.items; + PyObject *dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + + for (Py_ssize_t i=0; i < nxoption; i++) { + const wchar_t *option = xoptions[i]; + if (sys_add_xoption(dict, option) < 0) { + Py_DECREF(dict); + return NULL; + } + } + + return dict; +} + + +int +_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) +{ + PyObject *sysdict = interp->sysdict; + const PyConfig *config = &interp->config; + int res; + +#define COPY_LIST(KEY, VALUE) \ + do { \ + PyObject *list = _PyWideStringList_AsList(&(VALUE)); \ + if (list == NULL) { \ + return -1; \ + } \ + SET_SYS_FROM_STRING_BORROW(KEY, list); \ + Py_DECREF(list); \ + } while (0) + +#define SET_SYS_FROM_WSTR(KEY, VALUE) \ + do { \ + PyObject *str = PyUnicode_FromWideChar(VALUE, -1); \ + if (str == NULL) { \ + return -1; \ + } \ + SET_SYS_FROM_STRING_BORROW(KEY, str); \ + Py_DECREF(str); \ + } while (0) + + COPY_LIST("path", config->module_search_paths); + + SET_SYS_FROM_WSTR("executable", config->executable); + SET_SYS_FROM_WSTR("_base_executable", config->base_executable); + SET_SYS_FROM_WSTR("prefix", config->prefix); + SET_SYS_FROM_WSTR("base_prefix", config->base_prefix); + SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix); + SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix); + + if (config->pycache_prefix != NULL) { + SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); + } else { + PyDict_SetItemString(sysdict, "pycache_prefix", Py_None); + } + + COPY_LIST("argv", config->argv); + COPY_LIST("warnoptions", config->warnoptions); + + PyObject *xoptions = sys_create_xoptions_dict(config); + if (xoptions == NULL) { + return -1; + } + SET_SYS_FROM_STRING_BORROW("_xoptions", xoptions); + Py_DECREF(xoptions); + +#undef COPY_LIST +#undef SET_SYS_FROM_WSTR + + /* Set flags to their final values */ + SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp)); + /* prevent user from creating new instances */ + FlagsType.tp_init = NULL; + FlagsType.tp_new = NULL; + res = PyDict_DelItemString(FlagsType.tp_dict, "__new__"); + if (res < 0) { + if (!PyErr_ExceptionMatches(PyExc_KeyError)) { + return res; + } + PyErr_Clear(); + } + + SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode", + PyBool_FromLong(!config->write_bytecode)); + + if (get_warnoptions() == NULL) + return -1; + + if (get_xoptions() == NULL) + return -1; + + if (PyErr_Occurred()) + return -1; + + return 0; + +err_occurred: + return -1; +} + +#undef SET_SYS_FROM_STRING_BORROW +#undef SET_SYS_FROM_STRING_INT_RESULT + + +/* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. + + Use UTF-8/surrogateescape and ignore EAGAIN errors. */ +PyStatus +_PySys_SetPreliminaryStderr(PyObject *sysdict) +{ + PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) { + goto error; + } + if (_PyDict_SetItemId(sysdict, &PyId_stderr, pstderr) < 0) { + goto error; + } + if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) { + goto error; + } + Py_DECREF(pstderr); + return _PyStatus_OK(); + +error: + Py_XDECREF(pstderr); + return _PyStatus_ERR("can't set preliminary stderr"); +} + + +/* Create sys module without all attributes: _PySys_InitMain() should be called + later to add remaining attributes. */ +PyStatus +_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject **sysmod_p) +{ + PyObject *modules = PyDict_New(); + if (modules == NULL) { + return _PyStatus_ERR("can't make modules dictionary"); + } + interp->modules = modules; + + PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION); + if (sysmod == NULL) { + return _PyStatus_ERR("failed to create a module object"); + } + + PyObject *sysdict = PyModule_GetDict(sysmod); + if (sysdict == NULL) { + return _PyStatus_ERR("can't initialize sys dict"); + } + Py_INCREF(sysdict); + interp->sysdict = sysdict; + + if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) { + return _PyStatus_ERR("can't initialize sys module"); + } + + PyStatus status = _PySys_SetPreliminaryStderr(sysdict); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PySys_InitCore(runtime, interp, sysdict); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + _PyImport_FixupBuiltin(sysmod, "sys", interp->modules); + + *sysmod_p = sysmod; + return _PyStatus_OK(); +} + + +static PyObject * +makepathobject(const wchar_t *path, wchar_t delim) +{ + int i, n; + const wchar_t *p; + PyObject *v, *w; + + n = 1; + p = path; + while ((p = wcschr(p, delim)) != NULL) { + n++; + p++; + } + v = PyList_New(n); + if (v == NULL) + return NULL; + for (i = 0; ; i++) { + p = wcschr(path, delim); + if (p == NULL) + p = path + wcslen(path); /* End of string */ + w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path)); + if (w == NULL) { + Py_DECREF(v); + return NULL; + } + PyList_SET_ITEM(v, i, w); + if (*p == '\0') + break; + path = p+1; + } + return v; +} + +void +PySys_SetPath(const wchar_t *path) +{ + PyObject *v; + if ((v = makepathobject(path, DELIM)) == NULL) + Py_FatalError("can't create sys.path"); + if (_PySys_SetObjectId(&PyId_path, v) != 0) + Py_FatalError("can't assign sys.path"); + Py_DECREF(v); +} + +static PyObject * +make_sys_argv(int argc, wchar_t * const * argv) +{ + PyObject *list = PyList_New(argc); + if (list == NULL) { + return NULL; + } + + for (Py_ssize_t i = 0; i < argc; i++) { + PyObject *v = PyUnicode_FromWideChar(argv[i], -1); + if (v == NULL) { + Py_DECREF(list); + return NULL; + } + PyList_SET_ITEM(list, i, v); + } + return list; +} + +void +PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) +{ + wchar_t* empty_argv[1] = {L""}; + + if (argc < 1 || argv == NULL) { + /* Ensure at least one (empty) argument is seen */ + argv = empty_argv; + argc = 1; + } + + PyObject *av = make_sys_argv(argc, argv); + if (av == NULL) { + Py_FatalError("no mem for sys.argv"); + } + if (PySys_SetObject("argv", av) != 0) { + Py_DECREF(av); + Py_FatalError("can't assign sys.argv"); + } + Py_DECREF(av); + + if (updatepath) { + /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path. + If argv[0] is a symlink, use the real path. */ + const PyWideStringList argv_list = {.length = argc, .items = argv}; + PyObject *path0 = NULL; + if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) { + if (path0 == NULL) { + Py_FatalError("can't compute path0 from argv"); + } + + PyObject *sys_path = _PySys_GetObjectId(&PyId_path); + if (sys_path != NULL) { + if (PyList_Insert(sys_path, 0, path0) < 0) { + Py_DECREF(path0); + Py_FatalError("can't prepend path0 to sys.path"); + } + } + Py_DECREF(path0); + } + } +} + +void +PySys_SetArgv(int argc, wchar_t **argv) +{ + PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0); +} + +/* Reimplementation of PyFile_WriteString() no calling indirectly + PyErr_CheckSignals(): avoid the call to PyObject_Str(). */ + +static int +sys_pyfile_write_unicode(PyObject *unicode, PyObject *file) +{ + PyObject *writer = NULL, *result = NULL; + int err; + + if (file == NULL) + return -1; + + writer = _PyObject_GetAttrId(file, &PyId_write); + if (writer == NULL) + goto error; + + result = PyObject_CallFunctionObjArgs(writer, unicode, NULL); + if (result == NULL) { + goto error; + } else { + err = 0; + goto finally; + } + +error: + err = -1; +finally: + Py_XDECREF(writer); + Py_XDECREF(result); + return err; +} + +static int +sys_pyfile_write(const char *text, PyObject *file) +{ + PyObject *unicode = NULL; + int err; + + if (file == NULL) + return -1; + + unicode = PyUnicode_FromString(text); + if (unicode == NULL) + return -1; + + err = sys_pyfile_write_unicode(unicode, file); + Py_DECREF(unicode); + return err; +} + +/* APIs to write to sys.stdout or sys.stderr using a printf-like interface. + Adapted from code submitted by Just van Rossum. + + PySys_WriteStdout(format, ...) + PySys_WriteStderr(format, ...) + + The first function writes to sys.stdout; the second to sys.stderr. When + there is a problem, they write to the real (C level) stdout or stderr; + no exceptions are raised. + + PyErr_CheckSignals() is not called to avoid the execution of the Python + signal handlers: they may raise a new exception whereas sys_write() + ignores all exceptions. + + Both take a printf-style format string as their first argument followed + by a variable length argument list determined by the format string. + + *** WARNING *** + + The format should limit the total size of the formatted output string to + 1000 bytes. In particular, this means that no unrestricted "%s" formats + should occur; these should be limited using "%.s where is a + decimal number calculated so that plus the maximum size of other + formatted text does not exceed 1000 bytes. Also watch out for "%f", + which can print hundreds of digits for very large numbers. + + */ + +static void +sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va) +{ + PyObject *file; + PyObject *error_type, *error_value, *error_traceback; + char buffer[1001]; + int written; + + PyErr_Fetch(&error_type, &error_value, &error_traceback); + file = _PySys_GetObjectId(key); + written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); + if (sys_pyfile_write(buffer, file) != 0) { + PyErr_Clear(); + fputs(buffer, fp); + } + if (written < 0 || (size_t)written >= sizeof(buffer)) { + const char *truncated = "... truncated"; + if (sys_pyfile_write(truncated, file) != 0) + fputs(truncated, fp); + } + PyErr_Restore(error_type, error_value, error_traceback); +} + +void +PySys_WriteStdout(const char *format, ...) +{ + va_list va; + + va_start(va, format); + sys_write(&PyId_stdout, stdout, format, va); + va_end(va); +} + +void +PySys_WriteStderr(const char *format, ...) +{ + va_list va; + + va_start(va, format); + sys_write(&PyId_stderr, stderr, format, va); + va_end(va); +} + +static void +sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va) +{ + PyObject *file, *message; + PyObject *error_type, *error_value, *error_traceback; + const char *utf8; + + PyErr_Fetch(&error_type, &error_value, &error_traceback); + file = _PySys_GetObjectId(key); + message = PyUnicode_FromFormatV(format, va); + if (message != NULL) { + if (sys_pyfile_write_unicode(message, file) != 0) { + PyErr_Clear(); + utf8 = PyUnicode_AsUTF8(message); + if (utf8 != NULL) + fputs(utf8, fp); + } + Py_DECREF(message); + } + PyErr_Restore(error_type, error_value, error_traceback); +} + +void +PySys_FormatStdout(const char *format, ...) +{ + va_list va; + + va_start(va, format); + sys_format(&PyId_stdout, stdout, format, va); + va_end(va); +} + +void +PySys_FormatStderr(const char *format, ...) +{ + va_list va; + + va_start(va, format); + sys_format(&PyId_stderr, stderr, format, va); + va_end(va); +} diff --git a/python/Python/thread.c b/python/Python/thread.c new file mode 100755 index 0000000..c36ce6f --- /dev/null +++ b/python/Python/thread.c @@ -0,0 +1,228 @@ + +/* Thread package. + This is intended to be usable independently from Python. + The implementation for system foobar is in a file thread_foobar.h + which is included by this file dependent on config settings. + Stuff shared by all thread_*.h files is collected here. */ + +#include "Python.h" +#include "pycore_pystate.h" + +#ifndef _POSIX_THREADS +/* This means pthreads are not implemented in libc headers, hence the macro + not present in unistd.h. But they still can be implemented as an external + library (e.g. gnu pth in pthread emulation) */ +# ifdef HAVE_PTHREAD_H +# include /* _POSIX_THREADS */ +# endif +#endif + +#ifndef DONT_HAVE_STDIO_H +#include +#endif + +#include + +#include "pythread.h" + +#ifndef _POSIX_THREADS + +/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then + enough of the Posix threads package is implemented to support python + threads. + + This is valid for HP-UX 11.23 running on an ia64 system. If needed, add + a check of __ia64 to verify that we're running on an ia64 system instead + of a pa-risc system. +*/ +#ifdef __hpux +#ifdef _SC_THREADS +#define _POSIX_THREADS +#endif +#endif + +#endif /* _POSIX_THREADS */ + + +#ifdef Py_DEBUG +static int thread_debug = 0; +#define dprintf(args) (void)((thread_debug & 1) && printf args) +#define d2printf(args) ((thread_debug & 8) && printf args) +#else +#define dprintf(args) +#define d2printf(args) +#endif + +static int initialized; + +static void PyThread__init_thread(void); /* Forward */ + +void +PyThread_init_thread(void) +{ +#ifdef Py_DEBUG + const char *p = Py_GETENV("PYTHONTHREADDEBUG"); + + if (p) { + if (*p) + thread_debug = atoi(p); + else + thread_debug = 1; + } +#endif /* Py_DEBUG */ + if (initialized) + return; + initialized = 1; + dprintf(("PyThread_init_thread called\n")); + PyThread__init_thread(); +} + +#if defined(_POSIX_THREADS) +# define PYTHREAD_NAME "pthread" +# include "thread_pthread.h" +#elif defined(NT_THREADS) +# define PYTHREAD_NAME "nt" +# include "thread_nt.h" +#else +# error "Require native threads. See https://bugs.python.org/issue31370" +#endif + + +/* return the current thread stack size */ +size_t +PyThread_get_stacksize(void) +{ + return _PyInterpreterState_Get()->pythread_stacksize; +} + +/* Only platforms defining a THREAD_SET_STACKSIZE() macro + in thread_.h support changing the stack size. + Return 0 if stack size is valid, + -1 if stack size value is invalid, + -2 if setting stack size is not supported. */ +int +PyThread_set_stacksize(size_t size) +{ +#if defined(THREAD_SET_STACKSIZE) + return THREAD_SET_STACKSIZE(size); +#else + return -2; +#endif +} + + +/* Thread Specific Storage (TSS) API + + Cross-platform components of TSS API implementation. +*/ + +Py_tss_t * +PyThread_tss_alloc(void) +{ + Py_tss_t *new_key = (Py_tss_t *)PyMem_RawMalloc(sizeof(Py_tss_t)); + if (new_key == NULL) { + return NULL; + } + new_key->_is_initialized = 0; + return new_key; +} + +void +PyThread_tss_free(Py_tss_t *key) +{ + if (key != NULL) { + PyThread_tss_delete(key); + PyMem_RawFree((void *)key); + } +} + +int +PyThread_tss_is_created(Py_tss_t *key) +{ + assert(key != NULL); + return key->_is_initialized; +} + + +PyDoc_STRVAR(threadinfo__doc__, +"sys.thread_info\n\ +\n\ +A named tuple holding information about the thread implementation."); + +static PyStructSequence_Field threadinfo_fields[] = { + {"name", "name of the thread implementation"}, + {"lock", "name of the lock implementation"}, + {"version", "name and version of the thread library"}, + {0} +}; + +static PyStructSequence_Desc threadinfo_desc = { + "sys.thread_info", /* name */ + threadinfo__doc__, /* doc */ + threadinfo_fields, /* fields */ + 3 +}; + +static PyTypeObject ThreadInfoType; + +PyObject* +PyThread_GetInfo(void) +{ + PyObject *threadinfo, *value; + int pos = 0; +#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \ + && defined(_CS_GNU_LIBPTHREAD_VERSION)) + char buffer[255]; + int len; +#endif + + if (ThreadInfoType.tp_name == 0) { + if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0) + return NULL; + } + + threadinfo = PyStructSequence_New(&ThreadInfoType); + if (threadinfo == NULL) + return NULL; + + value = PyUnicode_FromString(PYTHREAD_NAME); + if (value == NULL) { + Py_DECREF(threadinfo); + return NULL; + } + PyStructSequence_SET_ITEM(threadinfo, pos++, value); + +#ifdef _POSIX_THREADS +#ifdef USE_SEMAPHORES + value = PyUnicode_FromString("semaphore"); +#else + value = PyUnicode_FromString("mutex+cond"); +#endif + if (value == NULL) { + Py_DECREF(threadinfo); + return NULL; + } +#else + Py_INCREF(Py_None); + value = Py_None; +#endif + PyStructSequence_SET_ITEM(threadinfo, pos++, value); + +#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \ + && defined(_CS_GNU_LIBPTHREAD_VERSION)) + value = NULL; + len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer)); + if (1 < len && (size_t)len < sizeof(buffer)) { + value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); + if (value == NULL) + PyErr_Clear(); + } + if (value == NULL) +#endif + { + Py_INCREF(Py_None); + value = Py_None; + } + PyStructSequence_SET_ITEM(threadinfo, pos++, value); + return threadinfo; +} diff --git a/python/Python/thread_nt.h b/python/Python/thread_nt.h new file mode 100755 index 0000000..23d585c --- /dev/null +++ b/python/Python/thread_nt.h @@ -0,0 +1,498 @@ + +/* This code implemented by Dag.Gruneau@elsa.preseco.comm.se */ +/* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch@iso.ru */ +/* Eliminated some memory leaks, gsw@agere.com */ + +#include +#include +#ifdef HAVE_PROCESS_H +#include +#endif + +/* options */ +#ifndef _PY_USE_CV_LOCKS +#define _PY_USE_CV_LOCKS 1 /* use locks based on cond vars */ +#endif + +/* Now, define a non-recursive mutex using either condition variables + * and critical sections (fast) or using operating system mutexes + * (slow) + */ + +#if _PY_USE_CV_LOCKS + +#include "condvar.h" + +typedef struct _NRMUTEX +{ + PyMUTEX_T cs; + PyCOND_T cv; + int locked; +} NRMUTEX; +typedef NRMUTEX *PNRMUTEX; + +PNRMUTEX +AllocNonRecursiveMutex() +{ + PNRMUTEX m = (PNRMUTEX)PyMem_RawMalloc(sizeof(NRMUTEX)); + if (!m) + return NULL; + if (PyCOND_INIT(&m->cv)) + goto fail; + if (PyMUTEX_INIT(&m->cs)) { + PyCOND_FINI(&m->cv); + goto fail; + } + m->locked = 0; + return m; +fail: + PyMem_RawFree(m); + return NULL; +} + +VOID +FreeNonRecursiveMutex(PNRMUTEX mutex) +{ + if (mutex) { + PyCOND_FINI(&mutex->cv); + PyMUTEX_FINI(&mutex->cs); + PyMem_RawFree(mutex); + } +} + +DWORD +EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) +{ + DWORD result = WAIT_OBJECT_0; + if (PyMUTEX_LOCK(&mutex->cs)) + return WAIT_FAILED; + if (milliseconds == INFINITE) { + while (mutex->locked) { + if (PyCOND_WAIT(&mutex->cv, &mutex->cs)) { + result = WAIT_FAILED; + break; + } + } + } else if (milliseconds != 0) { + /* wait at least until the target */ + ULONGLONG now, target = GetTickCount64() + milliseconds; + while (mutex->locked) { + if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, (long long)milliseconds*1000) < 0) { + result = WAIT_FAILED; + break; + } + now = GetTickCount64(); + if (target <= now) + break; + milliseconds = (DWORD)(target-now); + } + } + if (!mutex->locked) { + mutex->locked = 1; + result = WAIT_OBJECT_0; + } else if (result == WAIT_OBJECT_0) + result = WAIT_TIMEOUT; + /* else, it is WAIT_FAILED */ + PyMUTEX_UNLOCK(&mutex->cs); /* must ignore result here */ + return result; +} + +BOOL +LeaveNonRecursiveMutex(PNRMUTEX mutex) +{ + BOOL result; + if (PyMUTEX_LOCK(&mutex->cs)) + return FALSE; + mutex->locked = 0; + /* condvar APIs return 0 on success. We need to return TRUE on success. */ + result = !PyCOND_SIGNAL(&mutex->cv); + PyMUTEX_UNLOCK(&mutex->cs); + return result; +} + +#else /* if ! _PY_USE_CV_LOCKS */ + +/* NR-locks based on a kernel mutex */ +#define PNRMUTEX HANDLE + +PNRMUTEX +AllocNonRecursiveMutex() +{ + return CreateSemaphore(NULL, 1, 1, NULL); +} + +VOID +FreeNonRecursiveMutex(PNRMUTEX mutex) +{ + /* No in-use check */ + CloseHandle(mutex); +} + +DWORD +EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) +{ + return WaitForSingleObjectEx(mutex, milliseconds, FALSE); +} + +BOOL +LeaveNonRecursiveMutex(PNRMUTEX mutex) +{ + return ReleaseSemaphore(mutex, 1, NULL); +} +#endif /* _PY_USE_CV_LOCKS */ + +unsigned long PyThread_get_thread_ident(void); + +#ifdef PY_HAVE_THREAD_NATIVE_ID +unsigned long PyThread_get_thread_native_id(void); +#endif + +/* + * Initialization of the C package, should not be needed. + */ +static void +PyThread__init_thread(void) +{ +} + +/* + * Thread support. + */ + +typedef struct { + void (*func)(void*); + void *arg; +} callobj; + +/* thunker to call adapt between the function type used by the system's +thread start function and the internally used one. */ +static unsigned __stdcall +bootstrap(void *call) +{ + callobj *obj = (callobj*)call; + void (*func)(void*) = obj->func; + void *arg = obj->arg; + HeapFree(GetProcessHeap(), 0, obj); + func(arg); + return 0; +} + +unsigned long +PyThread_start_new_thread(void (*func)(void *), void *arg) +{ + HANDLE hThread; + unsigned threadID; + callobj *obj; + + dprintf(("%lu: PyThread_start_new_thread called\n", + PyThread_get_thread_ident())); + if (!initialized) + PyThread_init_thread(); + + obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); + if (!obj) + return PYTHREAD_INVALID_THREAD_ID; + obj->func = func; + obj->arg = arg; + PyThreadState *tstate = _PyThreadState_GET(); + size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0; + hThread = (HANDLE)_beginthreadex(0, + Py_SAFE_DOWNCAST(stacksize, Py_ssize_t, unsigned int), + bootstrap, obj, + 0, &threadID); + if (hThread == 0) { + /* I've seen errno == EAGAIN here, which means "there are + * too many threads". + */ + int e = errno; + dprintf(("%lu: PyThread_start_new_thread failed, errno %d\n", + PyThread_get_thread_ident(), e)); + threadID = (unsigned)-1; + HeapFree(GetProcessHeap(), 0, obj); + } + else { + dprintf(("%lu: PyThread_start_new_thread succeeded: %p\n", + PyThread_get_thread_ident(), (void*)hThread)); + CloseHandle(hThread); + } + return threadID; +} + +/* + * Return the thread Id instead of a handle. The Id is said to uniquely identify the + * thread in the system + */ +unsigned long +PyThread_get_thread_ident(void) +{ + if (!initialized) + PyThread_init_thread(); + + return GetCurrentThreadId(); +} + +#ifdef PY_HAVE_THREAD_NATIVE_ID +/* + * Return the native Thread ID (TID) of the calling thread. + * The native ID of a thread is valid and guaranteed to be unique system-wide + * from the time the thread is created until the thread has been terminated. + */ +unsigned long +PyThread_get_thread_native_id(void) +{ + if (!initialized) { + PyThread_init_thread(); + } + + DWORD native_id; + native_id = GetCurrentThreadId(); + return (unsigned long) native_id; +} +#endif + +void _Py_NO_RETURN +PyThread_exit_thread(void) +{ + dprintf(("%lu: PyThread_exit_thread called\n", PyThread_get_thread_ident())); + if (!initialized) + exit(0); + _endthreadex(0); +} + +/* + * Lock support. It has to be implemented as semaphores. + * I [Dag] tried to implement it with mutex but I could find a way to + * tell whether a thread already own the lock or not. + */ +PyThread_type_lock +PyThread_allocate_lock(void) +{ + PNRMUTEX aLock; + + dprintf(("PyThread_allocate_lock called\n")); + if (!initialized) + PyThread_init_thread(); + + aLock = AllocNonRecursiveMutex() ; + + dprintf(("%lu: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock)); + + return (PyThread_type_lock) aLock; +} + +void +PyThread_free_lock(PyThread_type_lock aLock) +{ + dprintf(("%lu: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); + + FreeNonRecursiveMutex(aLock) ; +} + +/* + * Return 1 on success if the lock was acquired + * + * and 0 if the lock was not acquired. This means a 0 is returned + * if the lock has already been acquired by this thread! + */ +PyLockStatus +PyThread_acquire_lock_timed(PyThread_type_lock aLock, + PY_TIMEOUT_T microseconds, int intr_flag) +{ + /* Fow now, intr_flag does nothing on Windows, and lock acquires are + * uninterruptible. */ + PyLockStatus success; + PY_TIMEOUT_T milliseconds; + + if (microseconds >= 0) { + milliseconds = microseconds / 1000; + if (microseconds % 1000 > 0) + ++milliseconds; + if (milliseconds > PY_DWORD_MAX) { + Py_FatalError("Timeout larger than PY_TIMEOUT_MAX"); + } + } + else { + milliseconds = INFINITE; + } + + dprintf(("%lu: PyThread_acquire_lock_timed(%p, %lld) called\n", + PyThread_get_thread_ident(), aLock, microseconds)); + + if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock, + (DWORD)milliseconds) == WAIT_OBJECT_0) { + success = PY_LOCK_ACQUIRED; + } + else { + success = PY_LOCK_FAILURE; + } + + dprintf(("%lu: PyThread_acquire_lock(%p, %lld) -> %d\n", + PyThread_get_thread_ident(), aLock, microseconds, success)); + + return success; +} +int +PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) +{ + return PyThread_acquire_lock_timed(aLock, waitflag ? -1 : 0, 0); +} + +void +PyThread_release_lock(PyThread_type_lock aLock) +{ + dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); + + if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) + dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError())); +} + +/* minimum/maximum thread stack sizes supported */ +#define THREAD_MIN_STACKSIZE 0x8000 /* 32 KiB */ +#define THREAD_MAX_STACKSIZE 0x10000000 /* 256 MiB */ + +/* set the thread stack size. + * Return 0 if size is valid, -1 otherwise. + */ +static int +_pythread_nt_set_stacksize(size_t size) +{ + /* set to default */ + if (size == 0) { + _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0; + return 0; + } + + /* valid range? */ + if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) { + _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size; + return 0; + } + + return -1; +} + +#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x) + + +/* Thread Local Storage (TLS) API + + This API is DEPRECATED since Python 3.7. See PEP 539 for details. +*/ + +int +PyThread_create_key(void) +{ + DWORD result = TlsAlloc(); + if (result == TLS_OUT_OF_INDEXES) + return -1; + return (int)result; +} + +void +PyThread_delete_key(int key) +{ + TlsFree(key); +} + +int +PyThread_set_key_value(int key, void *value) +{ + BOOL ok = TlsSetValue(key, value); + return ok ? 0 : -1; +} + +void * +PyThread_get_key_value(int key) +{ + /* because TLS is used in the Py_END_ALLOW_THREAD macro, + * it is necessary to preserve the windows error state, because + * it is assumed to be preserved across the call to the macro. + * Ideally, the macro should be fixed, but it is simpler to + * do it here. + */ + DWORD error = GetLastError(); + void *result = TlsGetValue(key); + SetLastError(error); + return result; +} + +void +PyThread_delete_key_value(int key) +{ + /* NULL is used as "key missing", and it is also the default + * given by TlsGetValue() if nothing has been set yet. + */ + TlsSetValue(key, NULL); +} + + +/* reinitialization of TLS is not necessary after fork when using + * the native TLS functions. And forking isn't supported on Windows either. + */ +void +PyThread_ReInitTLS(void) +{ +} + + +/* Thread Specific Storage (TSS) API + + Platform-specific components of TSS API implementation. +*/ + +int +PyThread_tss_create(Py_tss_t *key) +{ + assert(key != NULL); + /* If the key has been created, function is silently skipped. */ + if (key->_is_initialized) { + return 0; + } + + DWORD result = TlsAlloc(); + if (result == TLS_OUT_OF_INDEXES) { + return -1; + } + /* In Windows, platform-specific key type is DWORD. */ + key->_key = result; + key->_is_initialized = 1; + return 0; +} + +void +PyThread_tss_delete(Py_tss_t *key) +{ + assert(key != NULL); + /* If the key has not been created, function is silently skipped. */ + if (!key->_is_initialized) { + return; + } + + TlsFree(key->_key); + key->_key = TLS_OUT_OF_INDEXES; + key->_is_initialized = 0; +} + +int +PyThread_tss_set(Py_tss_t *key, void *value) +{ + assert(key != NULL); + BOOL ok = TlsSetValue(key->_key, value); + return ok ? 0 : -1; +} + +void * +PyThread_tss_get(Py_tss_t *key) +{ + assert(key != NULL); + /* because TSS is used in the Py_END_ALLOW_THREAD macro, + * it is necessary to preserve the windows error state, because + * it is assumed to be preserved across the call to the macro. + * Ideally, the macro should be fixed, but it is simpler to + * do it here. + */ + DWORD error = GetLastError(); + void *result = TlsGetValue(key->_key); + SetLastError(error); + return result; +} diff --git a/python/Python/thread_pthread.h b/python/Python/thread_pthread.h new file mode 100755 index 0000000..78b99a7 --- /dev/null +++ b/python/Python/thread_pthread.h @@ -0,0 +1,874 @@ + +/* Posix threads interface */ + +#include +#include +#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) +#define destructor xxdestructor +#endif +#include +#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) +#undef destructor +#endif +#include + +#if defined(__linux__) +# include /* syscall(SYS_gettid) */ +#elif defined(__FreeBSD__) +# include /* pthread_getthreadid_np() */ +#elif defined(__OpenBSD__) +# include /* getthrid() */ +#elif defined(_AIX) +# include /* thread_self() */ +#elif defined(__NetBSD__) +# include /* _lwp_self() */ +#endif + +/* The POSIX spec requires that use of pthread_attr_setstacksize + be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */ +#ifdef _POSIX_THREAD_ATTR_STACKSIZE +#ifndef THREAD_STACK_SIZE +#define THREAD_STACK_SIZE 0 /* use default stack size */ +#endif + +/* The default stack size for new threads on OSX and BSD is small enough that + * we'll get hard crashes instead of 'maximum recursion depth exceeded' + * exceptions. + * + * The default stack sizes below are the empirically determined minimal stack + * sizes where a simple recursive function doesn't cause a hard crash. + */ +#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#undef THREAD_STACK_SIZE +/* Note: This matches the value of -Wl,-stack_size in configure.ac */ +#define THREAD_STACK_SIZE 0x1000000 +#endif +#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#undef THREAD_STACK_SIZE +#define THREAD_STACK_SIZE 0x400000 +#endif +#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 +#undef THREAD_STACK_SIZE +#define THREAD_STACK_SIZE 0x200000 +#endif +/* for safety, ensure a viable minimum stacksize */ +#define THREAD_STACK_MIN 0x8000 /* 32 KiB */ +#else /* !_POSIX_THREAD_ATTR_STACKSIZE */ +#ifdef THREAD_STACK_SIZE +#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined" +#endif +#endif + +/* The POSIX spec says that implementations supporting the sem_* + family of functions must indicate this by defining + _POSIX_SEMAPHORES. */ +#ifdef _POSIX_SEMAPHORES +/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so + we need to add 0 to make it work there as well. */ +#if (_POSIX_SEMAPHORES+0) == -1 +#define HAVE_BROKEN_POSIX_SEMAPHORES +#else +#include +#include +#endif +#endif + + +/* Whether or not to use semaphores directly rather than emulating them with + * mutexes and condition variables: + */ +#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \ + defined(HAVE_SEM_TIMEDWAIT)) +# define USE_SEMAPHORES +#else +# undef USE_SEMAPHORES +#endif + + +/* On platforms that don't use standard POSIX threads pthread_sigmask() + * isn't present. DEC threads uses sigprocmask() instead as do most + * other UNIX International compliant systems that don't have the full + * pthread implementation. + */ +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +# define SET_THREAD_SIGMASK pthread_sigmask +#else +# define SET_THREAD_SIGMASK sigprocmask +#endif + + +/* We assume all modern POSIX systems have gettimeofday() */ +#ifdef GETTIMEOFDAY_NO_TZ +#define GETTIMEOFDAY(ptv) gettimeofday(ptv) +#else +#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL) +#endif + +#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \ +do { \ + struct timeval tv; \ + GETTIMEOFDAY(&tv); \ + tv.tv_usec += microseconds % 1000000; \ + tv.tv_sec += microseconds / 1000000; \ + tv.tv_sec += tv.tv_usec / 1000000; \ + tv.tv_usec %= 1000000; \ + ts.tv_sec = tv.tv_sec; \ + ts.tv_nsec = tv.tv_usec * 1000; \ +} while(0) + + +/* + * pthread_cond support + */ + +#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) +// monotonic is supported statically. It doesn't mean it works on runtime. +#define CONDATTR_MONOTONIC +#endif + +// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported. +static pthread_condattr_t *condattr_monotonic = NULL; + +static void +init_condattr(void) +{ +#ifdef CONDATTR_MONOTONIC + static pthread_condattr_t ca; + pthread_condattr_init(&ca); + if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) { + condattr_monotonic = &ca; // Use monotonic clock + } +#endif +} + +int +_PyThread_cond_init(PyCOND_T *cond) +{ + return pthread_cond_init(cond, condattr_monotonic); +} + +void +_PyThread_cond_after(long long us, struct timespec *abs) +{ +#ifdef CONDATTR_MONOTONIC + if (condattr_monotonic) { + clock_gettime(CLOCK_MONOTONIC, abs); + abs->tv_sec += us / 1000000; + abs->tv_nsec += (us % 1000000) * 1000; + abs->tv_sec += abs->tv_nsec / 1000000000; + abs->tv_nsec %= 1000000000; + return; + } +#endif + + struct timespec ts; + MICROSECONDS_TO_TIMESPEC(us, ts); + *abs = ts; +} + + +/* A pthread mutex isn't sufficient to model the Python lock type + * because, according to Draft 5 of the docs (P1003.4a/D5), both of the + * following are undefined: + * -> a thread tries to lock a mutex it already has locked + * -> a thread tries to unlock a mutex locked by a different thread + * pthread mutexes are designed for serializing threads over short pieces + * of code anyway, so wouldn't be an appropriate implementation of + * Python's locks regardless. + * + * The pthread_lock struct implements a Python lock as a "locked?" bit + * and a pair. In general, if the bit can be acquired + * instantly, it is, else the pair is used to block the thread until the + * bit is cleared. 9 May 1994 tim@ksr.com + */ + +typedef struct { + char locked; /* 0=unlocked, 1=locked */ + /* a pair to handle an acquire of a locked lock */ + pthread_cond_t lock_released; + pthread_mutex_t mut; +} pthread_lock; + +#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; } +#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \ + "%s: %s\n", name, strerror(status)); error = 1; } + +/* + * Initialization. + */ +static void +PyThread__init_thread(void) +{ +#if defined(_AIX) && defined(__GNUC__) + extern void pthread_init(void); + pthread_init(); +#endif + init_condattr(); +} + +/* + * Thread support. + */ + +/* bpo-33015: pythread_callback struct and pythread_wrapper() cast + "void func(void *)" to "void* func(void *)": always return NULL. + + PyThread_start_new_thread() uses "void func(void *)" type, whereas + pthread_create() requires a void* return value. */ +typedef struct { + void (*func) (void *); + void *arg; +} pythread_callback; + +static void * +pythread_wrapper(void *arg) +{ + /* copy func and func_arg and free the temporary structure */ + pythread_callback *callback = arg; + void (*func)(void *) = callback->func; + void *func_arg = callback->arg; + PyMem_RawFree(arg); + + func(func_arg); + return NULL; +} + +unsigned long +PyThread_start_new_thread(void (*func)(void *), void *arg) +{ + pthread_t th; + int status; +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + pthread_attr_t attrs; +#endif +#if defined(THREAD_STACK_SIZE) + size_t tss; +#endif + + dprintf(("PyThread_start_new_thread called\n")); + if (!initialized) + PyThread_init_thread(); + +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + if (pthread_attr_init(&attrs) != 0) + return PYTHREAD_INVALID_THREAD_ID; +#endif +#if defined(THREAD_STACK_SIZE) + PyThreadState *tstate = _PyThreadState_GET(); + size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0; + tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE; + if (tss != 0) { + if (pthread_attr_setstacksize(&attrs, tss) != 0) { + pthread_attr_destroy(&attrs); + return PYTHREAD_INVALID_THREAD_ID; + } + } +#endif +#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); +#endif + + pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback)); + + if (callback == NULL) { + return PYTHREAD_INVALID_THREAD_ID; + } + + callback->func = func; + callback->arg = arg; + + status = pthread_create(&th, +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + &attrs, +#else + (pthread_attr_t*)NULL, +#endif + pythread_wrapper, callback); + +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + pthread_attr_destroy(&attrs); +#endif + + if (status != 0) { + PyMem_RawFree(callback); + return PYTHREAD_INVALID_THREAD_ID; + } + + pthread_detach(th); + +#if SIZEOF_PTHREAD_T <= SIZEOF_LONG + return (unsigned long) th; +#else + return (unsigned long) *(unsigned long *) &th; +#endif +} + +/* XXX This implementation is considered (to quote Tim Peters) "inherently + hosed" because: + - It does not guarantee the promise that a non-zero integer is returned. + - The cast to unsigned long is inherently unsafe. + - It is not clear that the 'volatile' (for AIX?) are any longer necessary. +*/ +unsigned long +PyThread_get_thread_ident(void) +{ + volatile pthread_t threadid; + if (!initialized) + PyThread_init_thread(); + threadid = pthread_self(); + return (unsigned long) threadid; +} + +#ifdef PY_HAVE_THREAD_NATIVE_ID +unsigned long +PyThread_get_thread_native_id(void) +{ + if (!initialized) + PyThread_init_thread(); +#ifdef __APPLE__ + uint64_t native_id; + (void) pthread_threadid_np(NULL, &native_id); +#elif defined(__linux__) + pid_t native_id; + native_id = syscall(SYS_gettid); +#elif defined(__FreeBSD__) + int native_id; + native_id = pthread_getthreadid_np(); +#elif defined(__OpenBSD__) + pid_t native_id; + native_id = getthrid(); +#elif defined(_AIX) + tid_t native_id; + native_id = thread_self(); +#elif defined(__NetBSD__) + lwpid_t native_id; + native_id = _lwp_self(); +#endif + return (unsigned long) native_id; +} +#endif + +void _Py_NO_RETURN +PyThread_exit_thread(void) +{ + dprintf(("PyThread_exit_thread called\n")); + if (!initialized) + exit(0); + pthread_exit(0); +} + +#ifdef USE_SEMAPHORES + +/* + * Lock support. + */ + +PyThread_type_lock +PyThread_allocate_lock(void) +{ + sem_t *lock; + int status, error = 0; + + dprintf(("PyThread_allocate_lock called\n")); + if (!initialized) + PyThread_init_thread(); + + lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t)); + + if (lock) { + status = sem_init(lock,0,1); + CHECK_STATUS("sem_init"); + + if (error) { + PyMem_RawFree((void *)lock); + lock = NULL; + } + } + + dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); + return (PyThread_type_lock)lock; +} + +void +PyThread_free_lock(PyThread_type_lock lock) +{ + sem_t *thelock = (sem_t *)lock; + int status, error = 0; + + (void) error; /* silence unused-but-set-variable warning */ + dprintf(("PyThread_free_lock(%p) called\n", lock)); + + if (!thelock) + return; + + status = sem_destroy(thelock); + CHECK_STATUS("sem_destroy"); + + PyMem_RawFree((void *)thelock); +} + +/* + * As of February 2002, Cygwin thread implementations mistakenly report error + * codes in the return value of the sem_ calls (like the pthread_ functions). + * Correct implementations return -1 and put the code in errno. This supports + * either. + */ +static int +fix_status(int status) +{ + return (status == -1) ? errno : status; +} + +PyLockStatus +PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, + int intr_flag) +{ + PyLockStatus success; + sem_t *thelock = (sem_t *)lock; + int status, error = 0; + struct timespec ts; + _PyTime_t deadline = 0; + + (void) error; /* silence unused-but-set-variable warning */ + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", + lock, microseconds, intr_flag)); + + if (microseconds > PY_TIMEOUT_MAX) { + Py_FatalError("Timeout larger than PY_TIMEOUT_MAX"); + } + + if (microseconds > 0) { + MICROSECONDS_TO_TIMESPEC(microseconds, ts); + + if (!intr_flag) { + /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX) + check done above */ + _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000); + deadline = _PyTime_GetMonotonicClock() + timeout; + } + } + + while (1) { + if (microseconds > 0) { + status = fix_status(sem_timedwait(thelock, &ts)); + } + else if (microseconds == 0) { + status = fix_status(sem_trywait(thelock)); + } + else { + status = fix_status(sem_wait(thelock)); + } + + /* Retry if interrupted by a signal, unless the caller wants to be + notified. */ + if (intr_flag || status != EINTR) { + break; + } + + if (microseconds > 0) { + /* wait interrupted by a signal (EINTR): recompute the timeout */ + _PyTime_t dt = deadline - _PyTime_GetMonotonicClock(); + if (dt < 0) { + status = ETIMEDOUT; + break; + } + else if (dt > 0) { + _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt; + if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) { + /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX) + check done above */ + Py_UNREACHABLE(); + } + /* no need to update microseconds value, the code only care + if (microseconds > 0 or (microseconds == 0). */ + } + else { + microseconds = 0; + } + } + } + + /* Don't check the status if we're stopping because of an interrupt. */ + if (!(intr_flag && status == EINTR)) { + if (microseconds > 0) { + if (status != ETIMEDOUT) + CHECK_STATUS("sem_timedwait"); + } + else if (microseconds == 0) { + if (status != EAGAIN) + CHECK_STATUS("sem_trywait"); + } + else { + CHECK_STATUS("sem_wait"); + } + } + + if (status == 0) { + success = PY_LOCK_ACQUIRED; + } else if (intr_flag && status == EINTR) { + success = PY_LOCK_INTR; + } else { + success = PY_LOCK_FAILURE; + } + + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", + lock, microseconds, intr_flag, success)); + return success; +} + +void +PyThread_release_lock(PyThread_type_lock lock) +{ + sem_t *thelock = (sem_t *)lock; + int status, error = 0; + + (void) error; /* silence unused-but-set-variable warning */ + dprintf(("PyThread_release_lock(%p) called\n", lock)); + + status = sem_post(thelock); + CHECK_STATUS("sem_post"); +} + +#else /* USE_SEMAPHORES */ + +/* + * Lock support. + */ +PyThread_type_lock +PyThread_allocate_lock(void) +{ + pthread_lock *lock; + int status, error = 0; + + dprintf(("PyThread_allocate_lock called\n")); + if (!initialized) + PyThread_init_thread(); + + lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock)); + if (lock) { + memset((void *)lock, '\0', sizeof(pthread_lock)); + lock->locked = 0; + + status = pthread_mutex_init(&lock->mut, NULL); + CHECK_STATUS_PTHREAD("pthread_mutex_init"); + /* Mark the pthread mutex underlying a Python mutex as + pure happens-before. We can't simply mark the + Python-level mutex as a mutex because it can be + acquired and released in different threads, which + will cause errors. */ + _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut); + + status = _PyThread_cond_init(&lock->lock_released); + CHECK_STATUS_PTHREAD("pthread_cond_init"); + + if (error) { + PyMem_RawFree((void *)lock); + lock = 0; + } + } + + dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); + return (PyThread_type_lock) lock; +} + +void +PyThread_free_lock(PyThread_type_lock lock) +{ + pthread_lock *thelock = (pthread_lock *)lock; + int status, error = 0; + + (void) error; /* silence unused-but-set-variable warning */ + dprintf(("PyThread_free_lock(%p) called\n", lock)); + + /* some pthread-like implementations tie the mutex to the cond + * and must have the cond destroyed first. + */ + status = pthread_cond_destroy( &thelock->lock_released ); + CHECK_STATUS_PTHREAD("pthread_cond_destroy"); + + status = pthread_mutex_destroy( &thelock->mut ); + CHECK_STATUS_PTHREAD("pthread_mutex_destroy"); + + PyMem_RawFree((void *)thelock); +} + +PyLockStatus +PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, + int intr_flag) +{ + PyLockStatus success = PY_LOCK_FAILURE; + pthread_lock *thelock = (pthread_lock *)lock; + int status, error = 0; + + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", + lock, microseconds, intr_flag)); + + if (microseconds == 0) { + status = pthread_mutex_trylock( &thelock->mut ); + if (status != EBUSY) + CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]"); + } + else { + status = pthread_mutex_lock( &thelock->mut ); + CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]"); + } + if (status == 0) { + if (thelock->locked == 0) { + success = PY_LOCK_ACQUIRED; + } + else if (microseconds != 0) { + struct timespec abs; + if (microseconds > 0) { + _PyThread_cond_after(microseconds, &abs); + } + /* continue trying until we get the lock */ + + /* mut must be locked by me -- part of the condition + * protocol */ + while (success == PY_LOCK_FAILURE) { + if (microseconds > 0) { + status = pthread_cond_timedwait( + &thelock->lock_released, + &thelock->mut, &abs); + if (status == 1) { + break; + } + if (status == ETIMEDOUT) + break; + CHECK_STATUS_PTHREAD("pthread_cond_timedwait"); + } + else { + status = pthread_cond_wait( + &thelock->lock_released, + &thelock->mut); + CHECK_STATUS_PTHREAD("pthread_cond_wait"); + } + + if (intr_flag && status == 0 && thelock->locked) { + /* We were woken up, but didn't get the lock. We probably received + * a signal. Return PY_LOCK_INTR to allow the caller to handle + * it and retry. */ + success = PY_LOCK_INTR; + break; + } + else if (status == 0 && !thelock->locked) { + success = PY_LOCK_ACQUIRED; + } + } + } + if (success == PY_LOCK_ACQUIRED) thelock->locked = 1; + status = pthread_mutex_unlock( &thelock->mut ); + CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]"); + } + + if (error) success = PY_LOCK_FAILURE; + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", + lock, microseconds, intr_flag, success)); + return success; +} + +void +PyThread_release_lock(PyThread_type_lock lock) +{ + pthread_lock *thelock = (pthread_lock *)lock; + int status, error = 0; + + (void) error; /* silence unused-but-set-variable warning */ + dprintf(("PyThread_release_lock(%p) called\n", lock)); + + status = pthread_mutex_lock( &thelock->mut ); + CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]"); + + thelock->locked = 0; + + /* wake up someone (anyone, if any) waiting on the lock */ + status = pthread_cond_signal( &thelock->lock_released ); + CHECK_STATUS_PTHREAD("pthread_cond_signal"); + + status = pthread_mutex_unlock( &thelock->mut ); + CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]"); +} + +#endif /* USE_SEMAPHORES */ + +int +PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) +{ + return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0); +} + +/* set the thread stack size. + * Return 0 if size is valid, -1 if size is invalid, + * -2 if setting stack size is not supported. + */ +static int +_pythread_pthread_set_stacksize(size_t size) +{ +#if defined(THREAD_STACK_SIZE) + pthread_attr_t attrs; + size_t tss_min; + int rc = 0; +#endif + + /* set to default */ + if (size == 0) { + _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0; + return 0; + } + +#if defined(THREAD_STACK_SIZE) +#if defined(PTHREAD_STACK_MIN) + tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN + : THREAD_STACK_MIN; +#else + tss_min = THREAD_STACK_MIN; +#endif + if (size >= tss_min) { + /* validate stack size by setting thread attribute */ + if (pthread_attr_init(&attrs) == 0) { + rc = pthread_attr_setstacksize(&attrs, size); + pthread_attr_destroy(&attrs); + if (rc == 0) { + _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size; + return 0; + } + } + } + return -1; +#else + return -2; +#endif +} + +#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x) + + +/* Thread Local Storage (TLS) API + + This API is DEPRECATED since Python 3.7. See PEP 539 for details. +*/ + +/* Issue #25658: On platforms where native TLS key is defined in a way that + cannot be safely cast to int, PyThread_create_key returns immediately a + failure status and other TLS functions all are no-ops. This indicates + clearly that the old API is not supported on platforms where it cannot be + used reliably, and that no effort will be made to add such support. + + Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after + removing this API. +*/ + +int +PyThread_create_key(void) +{ +#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT + pthread_key_t key; + int fail = pthread_key_create(&key, NULL); + if (fail) + return -1; + if (key > INT_MAX) { + /* Issue #22206: handle integer overflow */ + pthread_key_delete(key); + errno = ENOMEM; + return -1; + } + return (int)key; +#else + return -1; /* never return valid key value. */ +#endif +} + +void +PyThread_delete_key(int key) +{ +#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT + pthread_key_delete(key); +#endif +} + +void +PyThread_delete_key_value(int key) +{ +#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT + pthread_setspecific(key, NULL); +#endif +} + +int +PyThread_set_key_value(int key, void *value) +{ +#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT + int fail = pthread_setspecific(key, value); + return fail ? -1 : 0; +#else + return -1; +#endif +} + +void * +PyThread_get_key_value(int key) +{ +#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT + return pthread_getspecific(key); +#else + return NULL; +#endif +} + + +void +PyThread_ReInitTLS(void) +{ +} + + +/* Thread Specific Storage (TSS) API + + Platform-specific components of TSS API implementation. +*/ + +int +PyThread_tss_create(Py_tss_t *key) +{ + assert(key != NULL); + /* If the key has been created, function is silently skipped. */ + if (key->_is_initialized) { + return 0; + } + + int fail = pthread_key_create(&(key->_key), NULL); + if (fail) { + return -1; + } + key->_is_initialized = 1; + return 0; +} + +void +PyThread_tss_delete(Py_tss_t *key) +{ + assert(key != NULL); + /* If the key has not been created, function is silently skipped. */ + if (!key->_is_initialized) { + return; + } + + pthread_key_delete(key->_key); + /* pthread has not provided the defined invalid value for the key. */ + key->_is_initialized = 0; +} + +int +PyThread_tss_set(Py_tss_t *key, void *value) +{ + assert(key != NULL); + int fail = pthread_setspecific(key->_key, value); + return fail ? -1 : 0; +} + +void * +PyThread_tss_get(Py_tss_t *key) +{ + assert(key != NULL); + return pthread_getspecific(key->_key); +} diff --git a/python/Python/traceback.c b/python/Python/traceback.c new file mode 100755 index 0000000..0aa51ad --- /dev/null +++ b/python/Python/traceback.c @@ -0,0 +1,923 @@ + +/* Traceback implementation */ + +#include "Python.h" +#include "pycore_pystate.h" + +#include "code.h" +#include "frameobject.h" +#include "structmember.h" +#include "osdefs.h" +#ifdef HAVE_FCNTL_H +#include +#endif + +#define OFF(x) offsetof(PyTracebackObject, x) + +#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) +#define MAX_STRING_LENGTH 500 +#define MAX_FRAME_DEPTH 100 +#define MAX_NTHREADS 100 + +/* Function from Parser/tokenizer.c */ +extern char * PyTokenizer_FindEncodingFilename(int, PyObject *); + +_Py_IDENTIFIER(TextIOWrapper); +_Py_IDENTIFIER(close); +_Py_IDENTIFIER(open); +_Py_IDENTIFIER(path); + +/*[clinic input] +class TracebackType "PyTracebackObject *" "&PyTraceback_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=928fa06c10151120]*/ + +#include "clinic/traceback.c.h" + +static PyObject * +tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti, + int lineno) +{ + PyTracebackObject *tb; + if ((next != NULL && !PyTraceBack_Check(next)) || + frame == NULL || !PyFrame_Check(frame)) { + PyErr_BadInternalCall(); + return NULL; + } + tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); + if (tb != NULL) { + Py_XINCREF(next); + tb->tb_next = next; + Py_XINCREF(frame); + tb->tb_frame = frame; + tb->tb_lasti = lasti; + tb->tb_lineno = lineno; + PyObject_GC_Track(tb); + } + return (PyObject *)tb; +} + +/*[clinic input] +@classmethod +TracebackType.__new__ as tb_new + + tb_next: object + tb_frame: object(type='PyFrameObject *', subclass_of='&PyFrame_Type') + tb_lasti: int + tb_lineno: int + +Create a new traceback object. +[clinic start generated code]*/ + +static PyObject * +tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame, + int tb_lasti, int tb_lineno) +/*[clinic end generated code: output=fa077debd72d861a input=01cbe8ec8783fca7]*/ +{ + if (tb_next == Py_None) { + tb_next = NULL; + } else if (!PyTraceBack_Check(tb_next)) { + return PyErr_Format(PyExc_TypeError, + "expected traceback object or None, got '%s'", + Py_TYPE(tb_next)->tp_name); + } + + return tb_create_raw((PyTracebackObject *)tb_next, tb_frame, tb_lasti, + tb_lineno); +} + +static PyObject * +tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored)) +{ + return Py_BuildValue("[ssss]", "tb_frame", "tb_next", + "tb_lasti", "tb_lineno"); +} + +static PyObject * +tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_)) +{ + PyObject* ret = (PyObject*)self->tb_next; + if (!ret) { + ret = Py_None; + } + Py_INCREF(ret); + return ret; +} + +static int +tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_)) +{ + if (!new_next) { + PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute"); + return -1; + } + + /* We accept None or a traceback object, and map None -> NULL (inverse of + tb_next_get) */ + if (new_next == Py_None) { + new_next = NULL; + } else if (!PyTraceBack_Check(new_next)) { + PyErr_Format(PyExc_TypeError, + "expected traceback object, got '%s'", + Py_TYPE(new_next)->tp_name); + return -1; + } + + /* Check for loops */ + PyTracebackObject *cursor = (PyTracebackObject *)new_next; + while (cursor) { + if (cursor == self) { + PyErr_Format(PyExc_ValueError, "traceback loop detected"); + return -1; + } + cursor = cursor->tb_next; + } + + PyObject *old_next = (PyObject*)self->tb_next; + Py_XINCREF(new_next); + self->tb_next = (PyTracebackObject *)new_next; + Py_XDECREF(old_next); + + return 0; +} + + +static PyMethodDef tb_methods[] = { + {"__dir__", (PyCFunction)tb_dir, METH_NOARGS}, + {NULL, NULL, 0, NULL}, +}; + +static PyMemberDef tb_memberlist[] = { + {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY}, + {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, + {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyGetSetDef tb_getsetters[] = { + {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL}, + {NULL} /* Sentinel */ +}; + +static void +tb_dealloc(PyTracebackObject *tb) +{ + PyObject_GC_UnTrack(tb); + Py_TRASHCAN_BEGIN(tb, tb_dealloc) + Py_XDECREF(tb->tb_next); + Py_XDECREF(tb->tb_frame); + PyObject_GC_Del(tb); + Py_TRASHCAN_END +} + +static int +tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg) +{ + Py_VISIT(tb->tb_next); + Py_VISIT(tb->tb_frame); + return 0; +} + +static int +tb_clear(PyTracebackObject *tb) +{ + Py_CLEAR(tb->tb_next); + Py_CLEAR(tb->tb_frame); + return 0; +} + +PyTypeObject PyTraceBack_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "traceback", + sizeof(PyTracebackObject), + 0, + (destructor)tb_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,/* tp_flags */ + tb_new__doc__, /* tp_doc */ + (traverseproc)tb_traverse, /* tp_traverse */ + (inquiry)tb_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + tb_methods, /* tp_methods */ + tb_memberlist, /* tp_members */ + tb_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 */ + tb_new, /* tp_new */ +}; + + +PyObject* +_PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) +{ + assert(tb_next == NULL || PyTraceBack_Check(tb_next)); + assert(frame != NULL); + + return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti, + PyFrame_GetLineNumber(frame)); +} + + +int +PyTraceBack_Here(PyFrameObject *frame) +{ + PyObject *exc, *val, *tb, *newtb; + PyErr_Fetch(&exc, &val, &tb); + newtb = _PyTraceBack_FromFrame(tb, frame); + if (newtb == NULL) { + _PyErr_ChainExceptions(exc, val, tb); + return -1; + } + PyErr_Restore(exc, val, newtb); + Py_XDECREF(tb); + return 0; +} + +/* Insert a frame into the traceback for (funcname, filename, lineno). */ +void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) +{ + PyObject *globals; + PyCodeObject *code; + PyFrameObject *frame; + PyObject *exc, *val, *tb; + + /* Save and clear the current exception. Python functions must not be + called with an exception set. Calling Python functions happens when + the codec of the filesystem encoding is implemented in pure Python. */ + PyErr_Fetch(&exc, &val, &tb); + + globals = PyDict_New(); + if (!globals) + goto error; + code = PyCode_NewEmpty(filename, funcname, lineno); + if (!code) { + Py_DECREF(globals); + goto error; + } + frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL); + Py_DECREF(globals); + Py_DECREF(code); + if (!frame) + goto error; + frame->f_lineno = lineno; + + PyErr_Restore(exc, val, tb); + PyTraceBack_Here(frame); + Py_DECREF(frame); + return; + +error: + _PyErr_ChainExceptions(exc, val, tb); +} + +static PyObject * +_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) +{ + Py_ssize_t i; + PyObject *binary; + PyObject *v; + Py_ssize_t npath; + size_t taillen; + PyObject *syspath; + PyObject *path; + const char* tail; + PyObject *filebytes; + const char* filepath; + Py_ssize_t len; + PyObject* result; + + filebytes = PyUnicode_EncodeFSDefault(filename); + if (filebytes == NULL) { + PyErr_Clear(); + return NULL; + } + filepath = PyBytes_AS_STRING(filebytes); + + /* Search tail of filename in sys.path before giving up */ + tail = strrchr(filepath, SEP); + if (tail == NULL) + tail = filepath; + else + tail++; + taillen = strlen(tail); + + syspath = _PySys_GetObjectId(&PyId_path); + if (syspath == NULL || !PyList_Check(syspath)) + goto error; + npath = PyList_Size(syspath); + + for (i = 0; i < npath; i++) { + v = PyList_GetItem(syspath, i); + if (v == NULL) { + PyErr_Clear(); + break; + } + if (!PyUnicode_Check(v)) + continue; + path = PyUnicode_EncodeFSDefault(v); + if (path == NULL) { + PyErr_Clear(); + continue; + } + len = PyBytes_GET_SIZE(path); + if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) { + Py_DECREF(path); + continue; /* Too long */ + } + strcpy(namebuf, PyBytes_AS_STRING(path)); + Py_DECREF(path); + if (strlen(namebuf) != (size_t)len) + continue; /* v contains '\0' */ + if (len > 0 && namebuf[len-1] != SEP) + namebuf[len++] = SEP; + strcpy(namebuf+len, tail); + + binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb"); + if (binary != NULL) { + result = binary; + goto finally; + } + PyErr_Clear(); + } + goto error; + +error: + result = NULL; +finally: + Py_DECREF(filebytes); + return result; +} + +int +_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) +{ + int err = 0; + int fd; + int i; + char *found_encoding; + char *encoding; + PyObject *io; + PyObject *binary; + PyObject *fob = NULL; + PyObject *lineobj = NULL; + PyObject *res; + char buf[MAXPATHLEN+1]; + int kind; + void *data; + + /* open the file */ + if (filename == NULL) + return 0; + + io = PyImport_ImportModuleNoBlock("io"); + if (io == NULL) + return -1; + binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb"); + + if (binary == NULL) { + PyErr_Clear(); + + binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); + if (binary == NULL) { + Py_DECREF(io); + return -1; + } + } + + /* use the right encoding to decode the file as unicode */ + fd = PyObject_AsFileDescriptor(binary); + if (fd < 0) { + Py_DECREF(io); + Py_DECREF(binary); + return 0; + } + found_encoding = PyTokenizer_FindEncodingFilename(fd, filename); + if (found_encoding == NULL) + PyErr_Clear(); + encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; + /* Reset position */ + if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { + Py_DECREF(io); + Py_DECREF(binary); + PyMem_FREE(found_encoding); + return 0; + } + fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); + Py_DECREF(io); + PyMem_FREE(found_encoding); + + if (fob == NULL) { + PyErr_Clear(); + + res = _PyObject_CallMethodId(binary, &PyId_close, NULL); + Py_DECREF(binary); + if (res) + Py_DECREF(res); + else + PyErr_Clear(); + return 0; + } + Py_DECREF(binary); + + /* get the line number lineno */ + for (i = 0; i < lineno; i++) { + Py_XDECREF(lineobj); + lineobj = PyFile_GetLine(fob, -1); + if (!lineobj) { + PyErr_Clear(); + err = -1; + break; + } + } + res = _PyObject_CallMethodId(fob, &PyId_close, NULL); + if (res) + Py_DECREF(res); + else + PyErr_Clear(); + Py_DECREF(fob); + if (!lineobj || !PyUnicode_Check(lineobj)) { + Py_XDECREF(lineobj); + return err; + } + + /* remove the indentation of the line */ + kind = PyUnicode_KIND(lineobj); + data = PyUnicode_DATA(lineobj); + for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (ch != ' ' && ch != '\t' && ch != '\014') + break; + } + if (i) { + PyObject *truncated; + truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj)); + if (truncated) { + Py_DECREF(lineobj); + lineobj = truncated; + } else { + PyErr_Clear(); + } + } + + /* Write some spaces before the line */ + strcpy(buf, " "); + assert (strlen(buf) == 10); + while (indent > 0) { + if (indent < 10) + buf[indent] = '\0'; + err = PyFile_WriteString(buf, f); + if (err != 0) + break; + indent -= 10; + } + + /* finally display the line */ + if (err == 0) + err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW); + Py_DECREF(lineobj); + if (err == 0) + err = PyFile_WriteString("\n", f); + return err; +} + +static int +tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name) +{ + int err; + PyObject *line; + + if (filename == NULL || name == NULL) + return -1; + line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", + filename, lineno, name); + if (line == NULL) + return -1; + err = PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); + if (err != 0) + return err; + /* ignore errors since we can't report them, can we? */ + if (_Py_DisplaySourceLine(f, filename, lineno, 4)) + PyErr_Clear(); + return err; +} + +static const int TB_RECURSIVE_CUTOFF = 3; // Also hardcoded in traceback.py. + +static int +tb_print_line_repeated(PyObject *f, long cnt) +{ + cnt -= TB_RECURSIVE_CUTOFF; + PyObject *line = PyUnicode_FromFormat( + (cnt > 1) + ? " [Previous line repeated %ld more times]\n" + : " [Previous line repeated %ld more time]\n", + cnt); + if (line == NULL) { + return -1; + } + int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); + return err; +} + +static int +tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit) +{ + int err = 0; + Py_ssize_t depth = 0; + PyObject *last_file = NULL; + int last_line = -1; + PyObject *last_name = NULL; + long cnt = 0; + PyTracebackObject *tb1 = tb; + while (tb1 != NULL) { + depth++; + tb1 = tb1->tb_next; + } + while (tb != NULL && depth > limit) { + depth--; + tb = tb->tb_next; + } + while (tb != NULL && err == 0) { + if (last_file == NULL || + tb->tb_frame->f_code->co_filename != last_file || + last_line == -1 || tb->tb_lineno != last_line || + last_name == NULL || tb->tb_frame->f_code->co_name != last_name) { + if (cnt > TB_RECURSIVE_CUTOFF) { + err = tb_print_line_repeated(f, cnt); + } + last_file = tb->tb_frame->f_code->co_filename; + last_line = tb->tb_lineno; + last_name = tb->tb_frame->f_code->co_name; + cnt = 0; + } + cnt++; + if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) { + err = tb_displayline(f, + tb->tb_frame->f_code->co_filename, + tb->tb_lineno, + tb->tb_frame->f_code->co_name); + if (err == 0) { + err = PyErr_CheckSignals(); + } + } + tb = tb->tb_next; + } + if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) { + err = tb_print_line_repeated(f, cnt); + } + return err; +} + +#define PyTraceBack_LIMIT 1000 + +int +PyTraceBack_Print(PyObject *v, PyObject *f) +{ + int err; + PyObject *limitv; + long limit = PyTraceBack_LIMIT; + + if (v == NULL) + return 0; + if (!PyTraceBack_Check(v)) { + PyErr_BadInternalCall(); + return -1; + } + limitv = PySys_GetObject("tracebacklimit"); + if (limitv && PyLong_Check(limitv)) { + int overflow; + limit = PyLong_AsLongAndOverflow(limitv, &overflow); + if (overflow > 0) { + limit = LONG_MAX; + } + else if (limit <= 0) { + return 0; + } + } + err = PyFile_WriteString("Traceback (most recent call last):\n", f); + if (!err) + err = tb_printinternal((PyTracebackObject *)v, f, limit); + return err; +} + +/* Format an integer in range [0; 0xffffffff] to decimal and write it + into the file fd. + + This function is signal safe. */ + +void +_Py_DumpDecimal(int fd, unsigned long value) +{ + /* maximum number of characters required for output of %lld or %p. + We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, + plus 1 for the null byte. 53/22 is an upper bound for log10(256). */ + char buffer[1 + (sizeof(unsigned long)*53-1) / 22 + 1]; + char *ptr, *end; + + end = &buffer[Py_ARRAY_LENGTH(buffer) - 1]; + ptr = end; + *ptr = '\0'; + do { + --ptr; + assert(ptr >= buffer); + *ptr = '0' + (value % 10); + value /= 10; + } while (value); + + _Py_write_noraise(fd, ptr, end - ptr); +} + +/* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits, + and write it into the file fd. + + This function is signal safe. */ + +void +_Py_DumpHexadecimal(int fd, unsigned long value, Py_ssize_t width) +{ + char buffer[sizeof(unsigned long) * 2 + 1], *ptr, *end; + const Py_ssize_t size = Py_ARRAY_LENGTH(buffer) - 1; + + if (width > size) + width = size; + /* it's ok if width is negative */ + + end = &buffer[size]; + ptr = end; + *ptr = '\0'; + do { + --ptr; + assert(ptr >= buffer); + *ptr = Py_hexdigits[value & 15]; + value >>= 4; + } while ((end - ptr) < width || value); + + _Py_write_noraise(fd, ptr, end - ptr); +} + +void +_Py_DumpASCII(int fd, PyObject *text) +{ + PyASCIIObject *ascii = (PyASCIIObject *)text; + Py_ssize_t i, size; + int truncated; + int kind; + void *data = NULL; + wchar_t *wstr = NULL; + Py_UCS4 ch; + + if (!PyUnicode_Check(text)) + return; + + size = ascii->length; + kind = ascii->state.kind; + if (kind == PyUnicode_WCHAR_KIND) { + wstr = ((PyASCIIObject *)text)->wstr; + if (wstr == NULL) + return; + size = ((PyCompactUnicodeObject *)text)->wstr_length; + } + else if (ascii->state.compact) { + if (ascii->state.ascii) + data = ((PyASCIIObject*)text) + 1; + else + data = ((PyCompactUnicodeObject*)text) + 1; + } + else { + data = ((PyUnicodeObject *)text)->data.any; + if (data == NULL) + return; + } + + if (MAX_STRING_LENGTH < size) { + size = MAX_STRING_LENGTH; + truncated = 1; + } + else { + truncated = 0; + } + + for (i=0; i < size; i++) { + if (kind != PyUnicode_WCHAR_KIND) + ch = PyUnicode_READ(kind, data, i); + else + ch = wstr[i]; + if (' ' <= ch && ch <= 126) { + /* printable ASCII character */ + char c = (char)ch; + _Py_write_noraise(fd, &c, 1); + } + else if (ch <= 0xff) { + PUTS(fd, "\\x"); + _Py_DumpHexadecimal(fd, ch, 2); + } + else if (ch <= 0xffff) { + PUTS(fd, "\\u"); + _Py_DumpHexadecimal(fd, ch, 4); + } + else { + PUTS(fd, "\\U"); + _Py_DumpHexadecimal(fd, ch, 8); + } + } + if (truncated) { + PUTS(fd, "..."); + } +} + +/* Write a frame into the file fd: "File "xxx", line xxx in xxx". + + This function is signal safe. */ + +static void +dump_frame(int fd, PyFrameObject *frame) +{ + PyCodeObject *code; + int lineno; + + code = frame->f_code; + PUTS(fd, " File "); + if (code != NULL && code->co_filename != NULL + && PyUnicode_Check(code->co_filename)) + { + PUTS(fd, "\""); + _Py_DumpASCII(fd, code->co_filename); + PUTS(fd, "\""); + } else { + PUTS(fd, "???"); + } + + /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */ + lineno = PyCode_Addr2Line(code, frame->f_lasti); + PUTS(fd, ", line "); + if (lineno >= 0) { + _Py_DumpDecimal(fd, (unsigned long)lineno); + } + else { + PUTS(fd, "???"); + } + PUTS(fd, " in "); + + if (code != NULL && code->co_name != NULL + && PyUnicode_Check(code->co_name)) { + _Py_DumpASCII(fd, code->co_name); + } + else { + PUTS(fd, "???"); + } + + PUTS(fd, "\n"); +} + +static void +dump_traceback(int fd, PyThreadState *tstate, int write_header) +{ + PyFrameObject *frame; + unsigned int depth; + + if (write_header) { + PUTS(fd, "Stack (most recent call first):\n"); + } + + frame = _PyThreadState_GetFrame(tstate); + if (frame == NULL) { + PUTS(fd, "\n"); + return; + } + + depth = 0; + while (frame != NULL) { + if (MAX_FRAME_DEPTH <= depth) { + PUTS(fd, " ...\n"); + break; + } + if (!PyFrame_Check(frame)) + break; + dump_frame(fd, frame); + frame = frame->f_back; + depth++; + } +} + +/* Dump the traceback of a Python thread into fd. Use write() to write the + traceback and retry if write() is interrupted by a signal (failed with + EINTR), but don't call the Python signal handler. + + The caller is responsible to call PyErr_CheckSignals() to call Python signal + handlers if signals were received. */ +void +_Py_DumpTraceback(int fd, PyThreadState *tstate) +{ + dump_traceback(fd, tstate, 1); +} + +/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if + is_current is true, "Thread 0xHHHH:\n" otherwise. + + This function is signal safe. */ + +static void +write_thread_id(int fd, PyThreadState *tstate, int is_current) +{ + if (is_current) + PUTS(fd, "Current thread 0x"); + else + PUTS(fd, "Thread 0x"); + _Py_DumpHexadecimal(fd, + tstate->thread_id, + sizeof(unsigned long) * 2); + PUTS(fd, " (most recent call first):\n"); +} + +/* Dump the traceback of all Python threads into fd. Use write() to write the + traceback and retry if write() is interrupted by a signal (failed with + EINTR), but don't call the Python signal handler. + + The caller is responsible to call PyErr_CheckSignals() to call Python signal + handlers if signals were received. */ +const char* +_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, + PyThreadState *current_tstate) +{ + PyThreadState *tstate; + unsigned int nthreads; + + if (current_tstate == NULL) { + /* _Py_DumpTracebackThreads() is called from signal handlers by + faulthandler. + + 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 + _PyThreadState_GET() cannot be used. Read the thread specific + storage (TSS) instead: call PyGILState_GetThisThreadState(). */ + current_tstate = PyGILState_GetThisThreadState(); + } + + if (interp == NULL) { + if (current_tstate == NULL) { + interp = _PyGILState_GetInterpreterStateUnsafe(); + if (interp == NULL) { + /* We need the interpreter state to get Python threads */ + return "unable to get the interpreter state"; + } + } + else { + interp = current_tstate->interp; + } + } + assert(interp != NULL); + + /* Get the current interpreter from the current thread */ + tstate = PyInterpreterState_ThreadHead(interp); + if (tstate == NULL) + return "unable to get the thread head state"; + + /* Dump the traceback of each thread */ + tstate = PyInterpreterState_ThreadHead(interp); + nthreads = 0; + _Py_BEGIN_SUPPRESS_IPH + do + { + if (nthreads != 0) + PUTS(fd, "\n"); + if (nthreads >= MAX_NTHREADS) { + PUTS(fd, "...\n"); + break; + } + write_thread_id(fd, tstate, tstate == current_tstate); + dump_traceback(fd, tstate, 0); + tstate = PyThreadState_Next(tstate); + nthreads++; + } while (tstate != NULL); + _Py_END_SUPPRESS_IPH + + return NULL; +} + diff --git a/python/Python/wordcode_helpers.h b/python/Python/wordcode_helpers.h new file mode 100755 index 0000000..c8f7a0f --- /dev/null +++ b/python/Python/wordcode_helpers.h @@ -0,0 +1,44 @@ +/* This file contains code shared by the compiler and the peephole + optimizer. + */ + +#ifdef WORDS_BIGENDIAN +# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((opcode) << 8) | (oparg))) +#else +# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((oparg) << 8) | (opcode))) +#endif + +/* Minimum number of code units necessary to encode instruction with + EXTENDED_ARGs */ +static int +instrsize(unsigned int oparg) +{ + return oparg <= 0xff ? 1 : + oparg <= 0xffff ? 2 : + oparg <= 0xffffff ? 3 : + 4; +} + +/* Spits out op/oparg pair using ilen bytes. codestr should be pointed at the + desired location of the first EXTENDED_ARG */ +static void +write_op_arg(_Py_CODEUNIT *codestr, unsigned char opcode, + unsigned int oparg, int ilen) +{ + switch (ilen) { + case 4: + *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 24) & 0xff); + /* fall through */ + case 3: + *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 16) & 0xff); + /* fall through */ + case 2: + *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 8) & 0xff); + /* fall through */ + case 1: + *codestr++ = PACKOPARG(opcode, oparg & 0xff); + break; + default: + Py_UNREACHABLE(); + } +} diff --git a/python/include/Python-ast.h b/python/include/Python-ast.h new file mode 100755 index 0000000..5fe4f2b --- /dev/null +++ b/python/include/Python-ast.h @@ -0,0 +1,715 @@ +/* File automatically generated by Parser/asdl_c.py. */ + +#ifndef Py_PYTHON_AST_H +#define Py_PYTHON_AST_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "asdl.h" + +#undef Yield /* undefine macro conflicting with */ + +typedef struct _mod *mod_ty; + +typedef struct _stmt *stmt_ty; + +typedef struct _expr *expr_ty; + +typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5, + Param=6 } expr_context_ty; + +typedef struct _slice *slice_ty; + +typedef enum _boolop { And=1, Or=2 } boolop_ty; + +typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, + LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, + FloorDiv=13 } operator_ty; + +typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; + +typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, + In=9, NotIn=10 } cmpop_ty; + +typedef struct _comprehension *comprehension_ty; + +typedef struct _excepthandler *excepthandler_ty; + +typedef struct _arguments *arguments_ty; + +typedef struct _arg *arg_ty; + +typedef struct _keyword *keyword_ty; + +typedef struct _alias *alias_ty; + +typedef struct _withitem *withitem_ty; + +typedef struct _type_ignore *type_ignore_ty; + + +enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, + FunctionType_kind=4, Suite_kind=5}; +struct _mod { + enum _mod_kind kind; + union { + struct { + asdl_seq *body; + asdl_seq *type_ignores; + } Module; + + struct { + asdl_seq *body; + } Interactive; + + struct { + expr_ty body; + } Expression; + + struct { + asdl_seq *argtypes; + expr_ty returns; + } FunctionType; + + struct { + asdl_seq *body; + } Suite; + + } v; +}; + +enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, + Return_kind=4, Delete_kind=5, Assign_kind=6, + AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, + AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, + AsyncWith_kind=14, Raise_kind=15, Try_kind=16, + Assert_kind=17, Import_kind=18, ImportFrom_kind=19, + Global_kind=20, Nonlocal_kind=21, Expr_kind=22, Pass_kind=23, + Break_kind=24, Continue_kind=25}; +struct _stmt { + enum _stmt_kind kind; + union { + struct { + identifier name; + arguments_ty args; + asdl_seq *body; + asdl_seq *decorator_list; + expr_ty returns; + string type_comment; + } FunctionDef; + + struct { + identifier name; + arguments_ty args; + asdl_seq *body; + asdl_seq *decorator_list; + expr_ty returns; + string type_comment; + } AsyncFunctionDef; + + struct { + identifier name; + asdl_seq *bases; + asdl_seq *keywords; + asdl_seq *body; + asdl_seq *decorator_list; + } ClassDef; + + struct { + expr_ty value; + } Return; + + struct { + asdl_seq *targets; + } Delete; + + struct { + asdl_seq *targets; + expr_ty value; + string type_comment; + } Assign; + + struct { + expr_ty target; + operator_ty op; + expr_ty value; + } AugAssign; + + struct { + expr_ty target; + expr_ty annotation; + expr_ty value; + int simple; + } AnnAssign; + + struct { + expr_ty target; + expr_ty iter; + asdl_seq *body; + asdl_seq *orelse; + string type_comment; + } For; + + struct { + expr_ty target; + expr_ty iter; + asdl_seq *body; + asdl_seq *orelse; + string type_comment; + } AsyncFor; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } While; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } If; + + struct { + asdl_seq *items; + asdl_seq *body; + string type_comment; + } With; + + struct { + asdl_seq *items; + asdl_seq *body; + string type_comment; + } AsyncWith; + + struct { + expr_ty exc; + expr_ty cause; + } Raise; + + struct { + asdl_seq *body; + asdl_seq *handlers; + asdl_seq *orelse; + asdl_seq *finalbody; + } Try; + + struct { + expr_ty test; + expr_ty msg; + } Assert; + + struct { + asdl_seq *names; + } Import; + + struct { + identifier module; + asdl_seq *names; + int level; + } ImportFrom; + + struct { + asdl_seq *names; + } Global; + + struct { + asdl_seq *names; + } Nonlocal; + + struct { + expr_ty value; + } Expr; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4, + Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8, + ListComp_kind=9, SetComp_kind=10, DictComp_kind=11, + GeneratorExp_kind=12, Await_kind=13, Yield_kind=14, + YieldFrom_kind=15, Compare_kind=16, Call_kind=17, + FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20, + Attribute_kind=21, Subscript_kind=22, Starred_kind=23, + Name_kind=24, List_kind=25, Tuple_kind=26}; +struct _expr { + enum _expr_kind kind; + union { + struct { + boolop_ty op; + asdl_seq *values; + } BoolOp; + + struct { + expr_ty target; + expr_ty value; + } NamedExpr; + + struct { + expr_ty left; + operator_ty op; + expr_ty right; + } BinOp; + + struct { + unaryop_ty op; + expr_ty operand; + } UnaryOp; + + struct { + arguments_ty args; + expr_ty body; + } Lambda; + + struct { + expr_ty test; + expr_ty body; + expr_ty orelse; + } IfExp; + + struct { + asdl_seq *keys; + asdl_seq *values; + } Dict; + + struct { + asdl_seq *elts; + } Set; + + struct { + expr_ty elt; + asdl_seq *generators; + } ListComp; + + struct { + expr_ty elt; + asdl_seq *generators; + } SetComp; + + struct { + expr_ty key; + expr_ty value; + asdl_seq *generators; + } DictComp; + + struct { + expr_ty elt; + asdl_seq *generators; + } GeneratorExp; + + struct { + expr_ty value; + } Await; + + struct { + expr_ty value; + } Yield; + + struct { + expr_ty value; + } YieldFrom; + + struct { + expr_ty left; + asdl_int_seq *ops; + asdl_seq *comparators; + } Compare; + + struct { + expr_ty func; + asdl_seq *args; + asdl_seq *keywords; + } Call; + + struct { + expr_ty value; + int conversion; + expr_ty format_spec; + } FormattedValue; + + struct { + asdl_seq *values; + } JoinedStr; + + struct { + constant value; + string kind; + } Constant; + + struct { + expr_ty value; + identifier attr; + expr_context_ty ctx; + } Attribute; + + struct { + expr_ty value; + slice_ty slice; + expr_context_ty ctx; + } Subscript; + + struct { + expr_ty value; + expr_context_ty ctx; + } Starred; + + struct { + identifier id; + expr_context_ty ctx; + } Name; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } List; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } Tuple; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +enum _slice_kind {Slice_kind=1, ExtSlice_kind=2, Index_kind=3}; +struct _slice { + enum _slice_kind kind; + union { + struct { + expr_ty lower; + expr_ty upper; + expr_ty step; + } Slice; + + struct { + asdl_seq *dims; + } ExtSlice; + + struct { + expr_ty value; + } Index; + + } v; +}; + +struct _comprehension { + expr_ty target; + expr_ty iter; + asdl_seq *ifs; + int is_async; +}; + +enum _excepthandler_kind {ExceptHandler_kind=1}; +struct _excepthandler { + enum _excepthandler_kind kind; + union { + struct { + expr_ty type; + identifier name; + asdl_seq *body; + } ExceptHandler; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _arguments { + asdl_seq *posonlyargs; + asdl_seq *args; + arg_ty vararg; + asdl_seq *kwonlyargs; + asdl_seq *kw_defaults; + arg_ty kwarg; + asdl_seq *defaults; +}; + +struct _arg { + identifier arg; + expr_ty annotation; + string type_comment; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + +struct _keyword { + identifier arg; + expr_ty value; +}; + +struct _alias { + identifier name; + identifier asname; +}; + +struct _withitem { + expr_ty context_expr; + expr_ty optional_vars; +}; + +enum _type_ignore_kind {TypeIgnore_kind=1}; +struct _type_ignore { + enum _type_ignore_kind kind; + union { + struct { + int lineno; + string tag; + } TypeIgnore; + + } v; +}; + + +// Note: these macros affect function definitions, not only call sites. +#define Module(a0, a1, a2) _Py_Module(a0, a1, a2) +mod_ty _Py_Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena); +#define Interactive(a0, a1) _Py_Interactive(a0, a1) +mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena); +#define Expression(a0, a1) _Py_Expression(a0, a1) +mod_ty _Py_Expression(expr_ty body, PyArena *arena); +#define FunctionType(a0, a1, a2) _Py_FunctionType(a0, a1, a2) +mod_ty _Py_FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena); +#define Suite(a0, a1) _Py_Suite(a0, a1) +mod_ty _Py_Suite(asdl_seq * body, PyArena *arena); +#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) +stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, + asdl_seq * decorator_list, expr_ty returns, string + type_comment, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) +stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * + body, asdl_seq * decorator_list, expr_ty returns, + string type_comment, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena + *arena); +#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, + asdl_seq * body, asdl_seq * decorator_list, int lineno, + int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define Return(a0, a1, a2, a3, a4, a5) _Py_Return(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define Delete(a0, a1, a2, a3, a4, a5) _Py_Delete(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Assign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Assign(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, string type_comment, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_AnnAssign(a0, a1, a2, a3, a4, a5, a6, a7, a8) +stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int + simple, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, string type_comment, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, string type_comment, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define While(a0, a1, a2, a3, a4, a5, a6, a7) _Py_While(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define If(a0, a1, a2, a3, a4, a5, a6, a7) _Py_If(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define With(a0, a1, a2, a3, a4, a5, a6, a7) _Py_With(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, string type_comment, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Raise(a0, a1, a2, a3, a4, a5, a6) _Py_Raise(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_Try(a0, a1, a2, a3, a4, a5, a6, a7, a8) +stmt_ty _Py_Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, + asdl_seq * finalbody, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Assert(a0, a1, a2, a3, a4, a5, a6) _Py_Assert(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Import(a0, a1, a2, a3, a4, a5) _Py_Import(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ImportFrom(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Global(a0, a1, a2, a3, a4, a5) _Py_Global(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Nonlocal(a0, a1, a2, a3, a4, a5) _Py_Nonlocal(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Nonlocal(asdl_seq * names, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Expr(a0, a1, a2, a3, a4, a5) _Py_Expr(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Pass(a0, a1, a2, a3, a4) _Py_Pass(a0, a1, a2, a3, a4) +stmt_ty _Py_Pass(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Break(a0, a1, a2, a3, a4) _Py_Break(a0, a1, a2, a3, a4) +stmt_ty _Py_Break(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Continue(a0, a1, a2, a3, a4) _Py_Continue(a0, a1, a2, a3, a4) +stmt_ty _Py_Continue(int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define BoolOp(a0, a1, a2, a3, a4, a5, a6) _Py_BoolOp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define NamedExpr(a0, a1, a2, a3, a4, a5, a6) _Py_NamedExpr(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_NamedExpr(expr_ty target, expr_ty value, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define BinOp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_BinOp(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define UnaryOp(a0, a1, a2, a3, a4, a5, a6) _Py_UnaryOp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define Lambda(a0, a1, a2, a3, a4, a5, a6) _Py_Lambda(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define IfExp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_IfExp(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Dict(a0, a1, a2, a3, a4, a5, a6) _Py_Dict(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Set(a0, a1, a2, a3, a4, a5) _Py_Set(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Set(asdl_seq * elts, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define ListComp(a0, a1, a2, a3, a4, a5, a6) _Py_ListComp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define SetComp(a0, a1, a2, a3, a4, a5, a6) _Py_SetComp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_SetComp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define DictComp(a0, a1, a2, a3, a4, a5, a6, a7) _Py_DictComp(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define GeneratorExp(a0, a1, a2, a3, a4, a5, a6) _Py_GeneratorExp(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define Await(a0, a1, a2, a3, a4, a5) _Py_Await(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Await(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define Yield(a0, a1, a2, a3, a4, a5) _Py_Yield(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena); +#define YieldFrom(a0, a1, a2, a3, a4, a5) _Py_YieldFrom(a0, a1, a2, a3, a4, a5) +expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Compare(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Compare(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5) +expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +#define Constant(a0, a1, a2, a3, a4, a5, a6) _Py_Constant(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Constant(constant value, string kind, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena); +#define Attribute(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Attribute(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Subscript(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Subscript(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); +#define Starred(a0, a1, a2, a3, a4, a5, a6) _Py_Starred(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Starred(expr_ty value, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Name(a0, a1, a2, a3, a4, a5, a6) _Py_Name(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define List(a0, a1, a2, a3, a4, a5, a6) _Py_List(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Tuple(a0, a1, a2, a3, a4, a5, a6) _Py_Tuple(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define Slice(a0, a1, a2, a3) _Py_Slice(a0, a1, a2, a3) +slice_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena); +#define ExtSlice(a0, a1) _Py_ExtSlice(a0, a1) +slice_ty _Py_ExtSlice(asdl_seq * dims, PyArena *arena); +#define Index(a0, a1) _Py_Index(a0, a1) +slice_ty _Py_Index(expr_ty value, PyArena *arena); +#define comprehension(a0, a1, a2, a3, a4) _Py_comprehension(a0, a1, a2, a3, a4) +comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq * + ifs, int is_async, PyArena *arena); +#define ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5, a6, a7) +excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq * + body, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena + *arena); +#define arguments(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7) +arguments_ty _Py_arguments(asdl_seq * posonlyargs, asdl_seq * args, arg_ty + vararg, asdl_seq * kwonlyargs, asdl_seq * + kw_defaults, arg_ty kwarg, asdl_seq * defaults, + PyArena *arena); +#define arg(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arg(a0, a1, a2, a3, a4, a5, a6, a7) +arg_ty _Py_arg(identifier arg, expr_ty annotation, string type_comment, int + lineno, int col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) +keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); +#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) +alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); +#define withitem(a0, a1, a2) _Py_withitem(a0, a1, a2) +withitem_ty _Py_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena + *arena); +#define TypeIgnore(a0, a1, a2) _Py_TypeIgnore(a0, a1, a2) +type_ignore_ty _Py_TypeIgnore(int lineno, string tag, PyArena *arena); + +PyObject* PyAST_mod2obj(mod_ty t); +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); +int PyAST_Check(PyObject* obj); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYTHON_AST_H */ diff --git a/python/include/Python.h b/python/include/Python.h new file mode 100755 index 0000000..d6e5b13 --- /dev/null +++ b/python/include/Python.h @@ -0,0 +1,160 @@ +#ifndef Py_PYTHON_H +#define Py_PYTHON_H +/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ + +/* Include nearly all Python header files */ + +#include "patchlevel.h" +#include "pyconfig.h" +#include "pymacconfig.h" + +#include + +#ifndef UCHAR_MAX +#error "Something's broken. UCHAR_MAX should be defined in limits.h." +#endif + +#if UCHAR_MAX != 255 +#error "Python's source code assumes C's unsigned char is an 8-bit type." +#endif + +#if defined(__sgi) && !defined(_SGI_MP_SOURCE) +#define _SGI_MP_SOURCE +#endif + +#include +#ifndef NULL +# error "Python.h requires that stdio.h define NULL." +#endif + +#include +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#ifndef MS_WINDOWS +#include +#endif +#ifdef HAVE_CRYPT_H +#if defined(HAVE_CRYPT_R) && !defined(_GNU_SOURCE) +/* Required for glibc to expose the crypt_r() function prototype. */ +# define _GNU_SOURCE +# define _Py_GNU_SOURCE_FOR_CRYPT +#endif +#include +#ifdef _Py_GNU_SOURCE_FOR_CRYPT +/* Don't leak the _GNU_SOURCE define to other headers. */ +# undef _GNU_SOURCE +# undef _Py_GNU_SOURCE_FOR_CRYPT +#endif +#endif + +/* For size_t? */ +#ifdef HAVE_STDDEF_H +#include +#endif + +/* CAUTION: Build setups should ensure that NDEBUG is defined on the + * compiler command line when building Python in release mode; else + * assert() calls won't be removed. + */ +#include + +#include "pyport.h" +#include "pymacro.h" + +/* A convenient way for code to know if clang's memory sanitizer is enabled. */ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# if !defined(_Py_MEMORY_SANITIZER) +# define _Py_MEMORY_SANITIZER +# endif +# endif +#endif + +/* Debug-mode build with pymalloc implies PYMALLOC_DEBUG. + * PYMALLOC_DEBUG is in error if pymalloc is not in use. + */ +#if defined(Py_DEBUG) && defined(WITH_PYMALLOC) && !defined(PYMALLOC_DEBUG) +#define PYMALLOC_DEBUG +#endif +#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC) +#error "PYMALLOC_DEBUG requires WITH_PYMALLOC" +#endif +#include "pymath.h" +#include "pytime.h" +#include "pymem.h" + +#include "object.h" +#include "objimpl.h" +#include "typeslots.h" +#include "pyhash.h" + +#include "pydebug.h" + +#include "bytearrayobject.h" +#include "bytesobject.h" +#include "unicodeobject.h" +#include "longobject.h" +#include "longintrepr.h" +#include "boolobject.h" +#include "floatobject.h" +#include "complexobject.h" +#include "rangeobject.h" +#include "memoryobject.h" +#include "tupleobject.h" +#include "listobject.h" +#include "dictobject.h" +#include "odictobject.h" +#include "enumobject.h" +#include "setobject.h" +#include "methodobject.h" +#include "moduleobject.h" +#include "funcobject.h" +#include "classobject.h" +#include "fileobject.h" +#include "pycapsule.h" +#include "traceback.h" +#include "sliceobject.h" +#include "cellobject.h" +#include "iterobject.h" +#include "genobject.h" +#include "descrobject.h" +#include "warnings.h" +#include "weakrefobject.h" +#include "structseq.h" +#include "namespaceobject.h" +#include "picklebufobject.h" + +#include "codecs.h" +#include "pyerrors.h" + +#include "cpython/initconfig.h" +#include "pystate.h" +#include "context.h" + +#include "pyarena.h" +#include "modsupport.h" +#include "compile.h" +#include "pythonrun.h" +#include "pylifecycle.h" +#include "ceval.h" +#include "sysmodule.h" +#include "osmodule.h" +#include "intrcheck.h" +#include "import.h" + +#include "abstract.h" +#include "bltinmodule.h" + +#include "eval.h" + +#include "pyctype.h" +#include "pystrtod.h" +#include "pystrcmp.h" +#include "dtoa.h" +#include "fileutils.h" +#include "pyfpe.h" +#include "tracemalloc.h" + +#endif /* !Py_PYTHON_H */ diff --git a/python/include/abstract.h b/python/include/abstract.h new file mode 100755 index 0000000..777fd70 --- /dev/null +++ b/python/include/abstract.h @@ -0,0 +1,844 @@ +/* Abstract Object Interface (many thanks to Jim Fulton) */ + +#ifndef Py_ABSTRACTOBJECT_H +#define Py_ABSTRACTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* === Object Protocol ================================================== */ + +/* Implemented elsewhere: + + int PyObject_Print(PyObject *o, FILE *fp, int flags); + + Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument + is used to enable certain printing options. The only option currently + supported is Py_Print_RAW. + + (What should be said about Py_Print_RAW?). */ + + +/* Implemented elsewhere: + + int PyObject_HasAttrString(PyObject *o, const char *attr_name); + + Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise. + + This is equivalent to the Python expression: hasattr(o,attr_name). + + This function always succeeds. */ + + +/* Implemented elsewhere: + + PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name); + + Retrieve an attributed named attr_name form object o. + Returns the attribute value on success, or NULL on failure. + + This is the equivalent of the Python expression: o.attr_name. */ + + +/* Implemented elsewhere: + + int PyObject_HasAttr(PyObject *o, PyObject *attr_name); + + Returns 1 if o has the attribute attr_name, and 0 otherwise. + + This is equivalent to the Python expression: hasattr(o,attr_name). + + This function always succeeds. */ + +/* Implemented elsewhere: + + PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name); + + Retrieve an attributed named 'attr_name' form object 'o'. + Returns the attribute value on success, or NULL on failure. + + This is the equivalent of the Python expression: o.attr_name. */ + + +/* Implemented elsewhere: + + int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object 'o', + to the value 'v'. Raise an exception and return -1 on failure; return 0 on + success. + + This is the equivalent of the Python statement o.attr_name=v. */ + + +/* Implemented elsewhere: + + int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object 'o', to the value + 'v'. an exception and return -1 on failure; return 0 on success. + + This is the equivalent of the Python statement o.attr_name=v. */ + +/* Implemented as a macro: + + int PyObject_DelAttrString(PyObject *o, const char *attr_name); + + Delete attribute named attr_name, for object o. Returns + -1 on failure. + + This is the equivalent of the Python statement: del o.attr_name. */ +#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A), NULL) + + +/* Implemented as a macro: + + int PyObject_DelAttr(PyObject *o, PyObject *attr_name); + + Delete attribute named attr_name, for object o. Returns -1 + on failure. This is the equivalent of the Python + statement: del o.attr_name. */ +#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A), NULL) + + +/* Implemented elsewhere: + + PyObject *PyObject_Repr(PyObject *o); + + Compute the string representation of object 'o'. Returns the + string representation on success, NULL on failure. + + This is the equivalent of the Python expression: repr(o). + + Called by the repr() built-in function. */ + + +/* Implemented elsewhere: + + PyObject *PyObject_Str(PyObject *o); + + Compute the string representation of object, o. Returns the + string representation on success, NULL on failure. + + This is the equivalent of the Python expression: str(o). + + Called by the str() and print() built-in functions. */ + + +/* Declared elsewhere + + PyAPI_FUNC(int) PyCallable_Check(PyObject *o); + + Determine if the object, o, is callable. Return 1 if the object is callable + and 0 otherwise. + + This function always succeeds. */ + + +#ifdef PY_SSIZE_T_CLEAN +# define PyObject_CallFunction _PyObject_CallFunction_SizeT +# define PyObject_CallMethod _PyObject_CallMethod_SizeT +#endif + + +/* Call a callable Python object 'callable' with arguments given by the + tuple 'args' and keywords arguments given by the dictionary 'kwargs'. + + 'args' must not be NULL, use an empty tuple if no arguments are + needed. If no named arguments are needed, 'kwargs' can be NULL. + + This is the equivalent of the Python expression: + callable(*args, **kwargs). */ +PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable, + PyObject *args, PyObject *kwargs); + + +/* Call a callable Python object 'callable', with arguments given by the + tuple 'args'. If no arguments are needed, then 'args' can be NULL. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: + callable(*args). */ +PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable, + PyObject *args); + +/* Call a callable Python object, callable, with a variable number of C + arguments. The C arguments are described using a mkvalue-style format + string. + + The format may be NULL, indicating that no arguments are provided. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: + callable(arg1, arg2, ...). */ +PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable, + const char *format, ...); + +/* Call the method named 'name' of object 'obj' with a variable number of + C arguments. The C arguments are described by a mkvalue format string. + + The format can be NULL, indicating that no arguments are provided. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: + obj.name(arg1, arg2, ...). */ +PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj, + const char *name, + const char *format, ...); + +PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable, + const char *format, + ...); + +PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj, + const char *name, + const char *format, + ...); + +/* Call a callable Python object 'callable' with a variable number of C + arguments. The C arguments are provided as PyObject* values, terminated + by a NULL. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: + callable(arg1, arg2, ...). */ +PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, + ...); + +/* Call the method named 'name' of object 'obj' with a variable number of + C arguments. The C arguments are provided as PyObject* values, terminated + by NULL. + + Returns the result of the call on success, or NULL on failure. + + This is the equivalent of the Python expression: obj.name(*args). */ + +PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs( + PyObject *obj, + PyObject *name, + ...); + + +/* Implemented elsewhere: + + Py_hash_t PyObject_Hash(PyObject *o); + + Compute and return the hash, hash_value, of an object, o. On + failure, return -1. + + This is the equivalent of the Python expression: hash(o). */ + + +/* Implemented elsewhere: + + int PyObject_IsTrue(PyObject *o); + + Returns 1 if the object, o, is considered to be true, 0 if o is + considered to be false and -1 on failure. + + This is equivalent to the Python expression: not not o. */ + + +/* Implemented elsewhere: + + int PyObject_Not(PyObject *o); + + Returns 0 if the object, o, is considered to be true, 1 if o is + considered to be false and -1 on failure. + + This is equivalent to the Python expression: not o. */ + + +/* Get the type of an object. + + On success, returns a type object corresponding to the object type of object + 'o'. On failure, returns NULL. + + This is equivalent to the Python expression: type(o) */ +PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o); + + +/* Return the size of object 'o'. If the object 'o' provides both sequence and + mapping protocols, the sequence size is returned. + + On error, -1 is returned. + + This is the equivalent to the Python expression: len(o) */ +PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o); + + +/* For DLL compatibility */ +#undef PyObject_Length +PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); +#define PyObject_Length PyObject_Size + +/* Return element of 'o' corresponding to the object 'key'. Return NULL + on failure. + + This is the equivalent of the Python expression: o[key] */ +PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key); + + +/* Map the object 'key' to the value 'v' into 'o'. + + Raise an exception and return -1 on failure; return 0 on success. + + This is the equivalent of the Python statement: o[key]=v. */ +PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v); + +/* Remove the mapping for the string 'key' from the object 'o'. + Returns -1 on failure. + + This is equivalent to the Python statement: del o[key]. */ +PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key); + +/* Delete the mapping for the object 'key' from the object 'o'. + Returns -1 on failure. + + This is the equivalent of the Python statement: del o[key]. */ +PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key); + + +/* === Old Buffer API ============================================ */ + +/* FIXME: usage of these should all be replaced in Python itself + but for backwards compatibility we will implement them. + Their usage without a corresponding "unlock" mechanism + may create issues (but they would already be there). */ + +/* Takes an arbitrary object which must support the (character, single segment) + buffer interface and returns a pointer to a read-only memory location + useable as character based input for subsequent processing. + + Return 0 on success. buffer and buffer_len are only set in case no error + occurs. Otherwise, -1 is returned and an exception set. */ +Py_DEPRECATED(3.0) +PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj, + const char **buffer, + Py_ssize_t *buffer_len); + +/* Checks whether an arbitrary object supports the (character, single segment) + buffer interface. + + Returns 1 on success, 0 on failure. */ +Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj); + +/* Same as PyObject_AsCharBuffer() except that this API expects (readable, + single segment) buffer interface and returns a pointer to a read-only memory + location which can contain arbitrary data. + + 0 is returned on success. buffer and buffer_len are only set in case no + error occurs. Otherwise, -1 is returned and an exception set. */ +Py_DEPRECATED(3.0) +PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj, + const void **buffer, + Py_ssize_t *buffer_len); + +/* Takes an arbitrary object which must support the (writable, single segment) + buffer interface and returns a pointer to a writable memory location in + buffer of size 'buffer_len'. + + Return 0 on success. buffer and buffer_len are only set in case no error + occurs. Otherwise, -1 is returned and an exception set. */ +Py_DEPRECATED(3.0) +PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj, + void **buffer, + Py_ssize_t *buffer_len); + + +/* === New Buffer API ============================================ */ + +/* Takes an arbitrary object and returns the result of calling + obj.__format__(format_spec). */ +PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj, + PyObject *format_spec); + + +/* ==== Iterators ================================================ */ + +/* Takes an object and returns an iterator for it. + This is typically a new iterator but if the argument is an iterator, this + returns itself. */ +PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); + +/* Returns 1 if the object 'obj' provides iterator protocols, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyIter_Check(PyObject *); + +/* Takes an iterator object and calls its tp_iternext slot, + returning the next value. + + If the iterator is exhausted, this returns NULL without setting an + exception. + + NULL with an exception means an error occurred. */ +PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); + + +/* === Number Protocol ================================================== */ + +/* Returns 1 if the object 'o' provides numeric protocols, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyNumber_Check(PyObject *o); + +/* Returns the result of adding o1 and o2, or NULL on failure. + + This is the equivalent of the Python expression: o1 + o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2); + +/* Returns the result of subtracting o2 from o1, or NULL on failure. + + This is the equivalent of the Python expression: o1 - o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2); + +/* Returns the result of multiplying o1 and o2, or NULL on failure. + + This is the equivalent of the Python expression: o1 * o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* This is the equivalent of the Python expression: o1 @ o2. */ +PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2); +#endif + +/* Returns the result of dividing o1 by o2 giving an integral result, + or NULL on failure. + + This is the equivalent of the Python expression: o1 // o2. */ +PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); + +/* Returns the result of dividing o1 by o2 giving a float result, or NULL on + failure. + + This is the equivalent of the Python expression: o1 / o2. */ +PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2); + +/* Returns the remainder of dividing o1 by o2, or NULL on failure. + + This is the equivalent of the Python expression: o1 % o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2); + +/* See the built-in function divmod. + + Returns NULL on failure. + + This is the equivalent of the Python expression: divmod(o1, o2). */ +PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2); + +/* See the built-in function pow. Returns NULL on failure. + + This is the equivalent of the Python expression: pow(o1, o2, o3), + where o3 is optional. */ +PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2, + PyObject *o3); + +/* Returns the negation of o on success, or NULL on failure. + + This is the equivalent of the Python expression: -o. */ +PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o); + +/* Returns the positive of o on success, or NULL on failure. + + This is the equivalent of the Python expression: +o. */ +PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o); + +/* Returns the absolute value of 'o', or NULL on failure. + + This is the equivalent of the Python expression: abs(o). */ +PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o); + +/* Returns the bitwise negation of 'o' on success, or NULL on failure. + + This is the equivalent of the Python expression: ~o. */ +PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o); + +/* Returns the result of left shifting o1 by o2 on success, or NULL on failure. + + This is the equivalent of the Python expression: o1 << o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2); + +/* Returns the result of right shifting o1 by o2 on success, or NULL on + failure. + + This is the equivalent of the Python expression: o1 >> o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise and of o1 and o2 on success, or NULL on + failure. + + This is the equivalent of the Python expression: o1 & o2. */ +PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2); + +/* Returns the bitwise exclusive or of o1 by o2 on success, or NULL on failure. + + This is the equivalent of the Python expression: o1 ^ o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise or on o1 and o2 on success, or NULL on + failure. + + This is the equivalent of the Python expression: o1 | o2. */ +PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2); + +/* Returns 1 if obj is an index integer (has the nb_index slot of the + tp_as_number structure filled in), and 0 otherwise. */ +PyAPI_FUNC(int) PyIndex_Check(PyObject *); + +/* Returns the object 'o' converted to a Python int, or NULL with an exception + raised on failure. */ +PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o); + +/* Returns the object 'o' converted to Py_ssize_t by going through + PyNumber_Index() first. + + If an overflow error occurs while converting the int to Py_ssize_t, then the + second argument 'exc' is the error-type to return. If it is NULL, then the + overflow error is cleared and the value is clipped. */ +PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc); + +/* Returns the object 'o' converted to an integer object on success, or NULL + on failure. + + This is the equivalent of the Python expression: int(o). */ +PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o); + +/* Returns the object 'o' converted to a float object on success, or NULL + on failure. + + This is the equivalent of the Python expression: float(o). */ +PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o); + + +/* --- In-place variants of (some of) the above number protocol functions -- */ + +/* Returns the result of adding o2 to o1, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 += o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2); + +/* Returns the result of subtracting o2 from o1, possibly in-place or + NULL on failure. + + This is the equivalent of the Python expression: o1 -= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2); + +/* Returns the result of multiplying o1 by o2, possibly in-place, or NULL on + failure. + + This is the equivalent of the Python expression: o1 *= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* This is the equivalent of the Python expression: o1 @= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2); +#endif + +/* Returns the result of dividing o1 by o2 giving an integral result, possibly + in-place, or NULL on failure. + + This is the equivalent of the Python expression: o1 /= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, + PyObject *o2); + +/* Returns the result of dividing o1 by o2 giving a float result, possibly + in-place, or null on failure. + + This is the equivalent of the Python expression: o1 /= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1, + PyObject *o2); + +/* Returns the remainder of dividing o1 by o2, possibly in-place, or NULL on + failure. + + This is the equivalent of the Python expression: o1 %= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2); + +/* Returns the result of raising o1 to the power of o2, possibly in-place, + or NULL on failure. + + This is the equivalent of the Python expression: o1 **= o2, + or o1 = pow(o1, o2, o3) if o3 is present. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2, + PyObject *o3); + +/* Returns the result of left shifting o1 by o2, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 <<= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2); + +/* Returns the result of right shifting o1 by o2, possibly in-place or NULL + on failure. + + This is the equivalent of the Python expression: o1 >>= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise and of o1 and o2, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 &= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2); + +/* Returns the bitwise exclusive or of o1 by o2, possibly in-place, or NULL + on failure. + + This is the equivalent of the Python expression: o1 ^= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2); + +/* Returns the result of bitwise or of o1 and o2, possibly in-place, + or NULL on failure. + + This is the equivalent of the Python expression: o1 |= o2. */ +PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2); + +/* Returns the integer n converted to a string with a base, with a base + marker of 0b, 0o or 0x prefixed if applicable. + + If n is not an int object, it is converted with PyNumber_Index first. */ +PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base); + + +/* === Sequence protocol ================================================ */ + +/* Return 1 if the object provides sequence protocol, and zero + otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PySequence_Check(PyObject *o); + +/* Return the size of sequence object o, or -1 on failure. */ +PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o); + +/* For DLL compatibility */ +#undef PySequence_Length +PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o); +#define PySequence_Length PySequence_Size + + +/* Return the concatenation of o1 and o2 on success, and NULL on failure. + + This is the equivalent of the Python expression: o1 + o2. */ +PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2); + +/* Return the result of repeating sequence object 'o' 'count' times, + or NULL on failure. + + This is the equivalent of the Python expression: o * count. */ +PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count); + +/* Return the ith element of o, or NULL on failure. + + This is the equivalent of the Python expression: o[i]. */ +PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i); + +/* Return the slice of sequence object o between i1 and i2, or NULL on failure. + + This is the equivalent of the Python expression: o[i1:i2]. */ +PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + +/* Assign object 'v' to the ith element of the sequence 'o'. Raise an exception + and return -1 on failure; return 0 on success. + + This is the equivalent of the Python statement o[i] = v. */ +PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v); + +/* Delete the 'i'-th element of the sequence 'v'. Returns -1 on failure. + + This is the equivalent of the Python statement: del o[i]. */ +PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i); + +/* Assign the sequence object 'v' to the slice in sequence object 'o', + from 'i1' to 'i2'. Returns -1 on failure. + + This is the equivalent of the Python statement: o[i1:i2] = v. */ +PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, + PyObject *v); + +/* Delete the slice in sequence object 'o' from 'i1' to 'i2'. + Returns -1 on failure. + + This is the equivalent of the Python statement: del o[i1:i2]. */ +PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + +/* Returns the sequence 'o' as a tuple on success, and NULL on failure. + + This is equivalent to the Python expression: tuple(o). */ +PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o); + +/* Returns the sequence 'o' as a list on success, and NULL on failure. + This is equivalent to the Python expression: list(o) */ +PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o); + +/* Return the sequence 'o' as a list, unless it's already a tuple or list. + + Use PySequence_Fast_GET_ITEM to access the members of this list, and + PySequence_Fast_GET_SIZE to get its length. + + Returns NULL on failure. If the object does not support iteration, raises a + TypeError exception with 'm' as the message text. */ +PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); + +/* Return the size of the sequence 'o', assuming that 'o' was returned by + PySequence_Fast and is not NULL. */ +#define PySequence_Fast_GET_SIZE(o) \ + (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o)) + +/* Return the 'i'-th element of the sequence 'o', assuming that o was returned + by PySequence_Fast, and that i is within bounds. */ +#define PySequence_Fast_GET_ITEM(o, i)\ + (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) + +/* Return a pointer to the underlying item array for + an object retured by PySequence_Fast */ +#define PySequence_Fast_ITEMS(sf) \ + (PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \ + : ((PyTupleObject *)(sf))->ob_item) + +/* Return the number of occurrences on value on 'o', that is, return + the number of keys for which o[key] == value. + + On failure, return -1. This is equivalent to the Python expression: + o.count(value). */ +PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value); + +/* Return 1 if 'ob' is in the sequence 'seq'; 0 if 'ob' is not in the sequence + 'seq'; -1 on error. + + Use __contains__ if possible, else _PySequence_IterSearch(). */ +PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob); + +/* For DLL-level backwards compatibility */ +#undef PySequence_In +/* Determine if the sequence 'o' contains 'value'. If an item in 'o' is equal + to 'value', return 1, otherwise return 0. On error, return -1. + + This is equivalent to the Python expression: value in o. */ +PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value); + +/* For source-level backwards compatibility */ +#define PySequence_In PySequence_Contains + + +/* Return the first index for which o[i] == value. + On error, return -1. + + This is equivalent to the Python expression: o.index(value). */ +PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value); + + +/* --- In-place versions of some of the above Sequence functions --- */ + +/* Append sequence 'o2' to sequence 'o1', in-place when possible. Return the + resulting object, which could be 'o1', or NULL on failure. + + This is the equivalent of the Python expression: o1 += o2. */ +PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2); + +/* Repeat sequence 'o' by 'count', in-place when possible. Return the resulting + object, which could be 'o', or NULL on failure. + + This is the equivalent of the Python expression: o1 *= count. */ +PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count); + + +/* === Mapping protocol ================================================= */ + +/* Return 1 if the object provides mapping protocol, and 0 otherwise. + + This function always succeeds. */ +PyAPI_FUNC(int) PyMapping_Check(PyObject *o); + +/* Returns the number of keys in mapping object 'o' on success, and -1 on + failure. This is equivalent to the Python expression: len(o). */ +PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o); + +/* For DLL compatibility */ +#undef PyMapping_Length +PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); +#define PyMapping_Length PyMapping_Size + + +/* Implemented as a macro: + + int PyMapping_DelItemString(PyObject *o, const char *key); + + Remove the mapping for the string 'key' from the mapping 'o'. Returns -1 on + failure. + + This is equivalent to the Python statement: del o[key]. */ +#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) + +/* Implemented as a macro: + + int PyMapping_DelItem(PyObject *o, PyObject *key); + + Remove the mapping for the object 'key' from the mapping object 'o'. + Returns -1 on failure. + + This is equivalent to the Python statement: del o[key]. */ +#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) + +/* On success, return 1 if the mapping object 'o' has the key 'key', + and 0 otherwise. + + This is equivalent to the Python expression: key in o. + + This function always succeeds. */ +PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, const char *key); + +/* Return 1 if the mapping object has the key 'key', and 0 otherwise. + + This is equivalent to the Python expression: key in o. + + This function always succeeds. */ +PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key); + +/* On success, return a list or tuple of the keys in mapping object 'o'. + On failure, return NULL. */ +PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o); + +/* On success, return a list or tuple of the values in mapping object 'o'. + On failure, return NULL. */ +PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o); + +/* On success, return a list or tuple of the items in mapping object 'o', + where each item is a tuple containing a key-value pair. On failure, return + NULL. */ +PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o); + +/* Return element of 'o' corresponding to the string 'key' or NULL on failure. + + This is the equivalent of the Python expression: o[key]. */ +PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o, + const char *key); + +/* Map the string 'key' to the value 'v' in the mapping 'o'. + Returns -1 on failure. + + This is the equivalent of the Python statement: o[key]=v. */ +PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, const char *key, + PyObject *value); + +/* isinstance(object, typeorclass) */ +PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass); + +/* issubclass(object, typeorclass) */ +PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass); + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_ABSTRACTOBJECT_H +# include "cpython/abstract.h" +# undef Py_CPYTHON_ABSTRACTOBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* Py_ABSTRACTOBJECT_H */ diff --git a/python/include/asdl.h b/python/include/asdl.h new file mode 100755 index 0000000..fc6d223 --- /dev/null +++ b/python/include/asdl.h @@ -0,0 +1,46 @@ +#ifndef Py_ASDL_H +#define Py_ASDL_H + +typedef PyObject * identifier; +typedef PyObject * string; +typedef PyObject * bytes; +typedef PyObject * object; +typedef PyObject * singleton; +typedef PyObject * constant; + +/* It would be nice if the code generated by asdl_c.py was completely + independent of Python, but it is a goal the requires too much work + at this stage. So, for example, I'll represent identifiers as + interned Python strings. +*/ + +/* XXX A sequence should be typed so that its use can be typechecked. */ + +typedef struct { + Py_ssize_t size; + void *elements[1]; +} asdl_seq; + +typedef struct { + Py_ssize_t size; + int elements[1]; +} asdl_int_seq; + +asdl_seq *_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena); +asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena); + +#define asdl_seq_GET(S, I) (S)->elements[(I)] +#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) +#ifdef Py_DEBUG +#define asdl_seq_SET(S, I, V) \ + do { \ + Py_ssize_t _asdl_i = (I); \ + assert((S) != NULL); \ + assert(0 <= _asdl_i && _asdl_i < (S)->size); \ + (S)->elements[_asdl_i] = (V); \ + } while (0) +#else +#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V) +#endif + +#endif /* !Py_ASDL_H */ diff --git a/python/include/ast.h b/python/include/ast.h new file mode 100755 index 0000000..f1d7348 --- /dev/null +++ b/python/include/ast.h @@ -0,0 +1,37 @@ +#ifndef Py_AST_H +#define Py_AST_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "Python-ast.h" /* mod_ty */ +#include "node.h" /* node */ + +PyAPI_FUNC(int) PyAST_Validate(mod_ty); +PyAPI_FUNC(mod_ty) PyAST_FromNode( + const node *n, + PyCompilerFlags *flags, + const char *filename, /* decoded from the filesystem encoding */ + PyArena *arena); +PyAPI_FUNC(mod_ty) PyAST_FromNodeObject( + const node *n, + PyCompilerFlags *flags, + PyObject *filename, + PyArena *arena); + +#ifndef Py_LIMITED_API + +/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */ +PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(expr_ty); + +/* Return the borrowed reference to the first literal string in the + sequence of statemnts or NULL if it doesn't start from a literal string. + Doesn't set exception. */ +PyAPI_FUNC(PyObject *) _PyAST_GetDocString(asdl_seq *); + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_AST_H */ diff --git a/python/include/bitset.h b/python/include/bitset.h new file mode 100755 index 0000000..6a2ac97 --- /dev/null +++ b/python/include/bitset.h @@ -0,0 +1,23 @@ + +#ifndef Py_BITSET_H +#define Py_BITSET_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Bitset interface */ + +#define BYTE char +typedef BYTE *bitset; + +#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0) + +#define BITSPERBYTE (8*sizeof(BYTE)) +#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE) +#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE) +#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BITSET_H */ diff --git a/python/include/bltinmodule.h b/python/include/bltinmodule.h new file mode 100755 index 0000000..868c9e6 --- /dev/null +++ b/python/include/bltinmodule.h @@ -0,0 +1,14 @@ +#ifndef Py_BLTINMODULE_H +#define Py_BLTINMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyFilter_Type; +PyAPI_DATA(PyTypeObject) PyMap_Type; +PyAPI_DATA(PyTypeObject) PyZip_Type; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BLTINMODULE_H */ diff --git a/python/include/boolobject.h b/python/include/boolobject.h new file mode 100755 index 0000000..7cc2f1f --- /dev/null +++ b/python/include/boolobject.h @@ -0,0 +1,34 @@ +/* Boolean object interface */ + +#ifndef Py_BOOLOBJECT_H +#define Py_BOOLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_DATA(PyTypeObject) PyBool_Type; + +#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) + +/* Py_False and Py_True are the only two bools in existence. +Don't forget to apply Py_INCREF() when returning either!!! */ + +/* Don't use these directly */ +PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct; + +/* Use these macros */ +#define Py_False ((PyObject *) &_Py_FalseStruct) +#define Py_True ((PyObject *) &_Py_TrueStruct) + +/* Macros for returning Py_True or Py_False, respectively */ +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False + +/* Function to return a bool from a C long */ +PyAPI_FUNC(PyObject *) PyBool_FromLong(long); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BOOLOBJECT_H */ diff --git a/python/include/bytearrayobject.h b/python/include/bytearrayobject.h new file mode 100755 index 0000000..a757b88 --- /dev/null +++ b/python/include/bytearrayobject.h @@ -0,0 +1,62 @@ +/* ByteArray object interface */ + +#ifndef Py_BYTEARRAYOBJECT_H +#define Py_BYTEARRAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Type PyByteArrayObject represents a mutable array of bytes. + * The Python API is that of a sequence; + * the bytes are mapped to ints in [0, 256). + * Bytes are not characters; they may be used to encode characters. + * The only way to go between bytes and str/unicode is via encoding + * and decoding. + * For the convenience of C programmers, the bytes type is considered + * to contain a char pointer, not an unsigned char pointer. + */ + +/* Object layout */ +#ifndef Py_LIMITED_API +typedef struct { + PyObject_VAR_HEAD + Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */ + char *ob_bytes; /* Physical backing buffer */ + char *ob_start; /* Logical start inside ob_bytes */ + /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */ + int ob_exports; /* How many buffer exports */ +} PyByteArrayObject; +#endif + +/* Type object */ +PyAPI_DATA(PyTypeObject) PyByteArray_Type; +PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; + +/* Type check macros */ +#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) +#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) + +/* Direct API functions */ +PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *); +PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); +PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); + +/* Macros, trading safety for speed */ +#ifndef Py_LIMITED_API +#define PyByteArray_AS_STRING(self) \ + (assert(PyByteArray_Check(self)), \ + Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string) +#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self)) + +PyAPI_DATA(char) _PyByteArray_empty_string[]; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BYTEARRAYOBJECT_H */ diff --git a/python/include/bytes_methods.h b/python/include/bytes_methods.h new file mode 100755 index 0000000..8434a50 --- /dev/null +++ b/python/include/bytes_methods.h @@ -0,0 +1,69 @@ +#ifndef Py_LIMITED_API +#ifndef Py_BYTES_CTYPE_H +#define Py_BYTES_CTYPE_H + +/* + * The internal implementation behind PyBytes (bytes) and PyByteArray (bytearray) + * methods of the given names, they operate on ASCII byte strings. + */ +extern PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isascii(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len); + +/* These store their len sized answer in the given preallocated *result arg. */ +extern void _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len); +extern void _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len); +extern void _Py_bytes_title(char *result, const char *s, Py_ssize_t len); +extern void _Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len); +extern void _Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len); + +extern PyObject *_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args); +extern int _Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg); +extern PyObject *_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args); +extern PyObject *_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args); + +/* The maketrans() static method. */ +extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to); + +/* Shared __doc__ strings. */ +extern const char _Py_isspace__doc__[]; +extern const char _Py_isalpha__doc__[]; +extern const char _Py_isalnum__doc__[]; +extern const char _Py_isascii__doc__[]; +extern const char _Py_isdigit__doc__[]; +extern const char _Py_islower__doc__[]; +extern const char _Py_isupper__doc__[]; +extern const char _Py_istitle__doc__[]; +extern const char _Py_lower__doc__[]; +extern const char _Py_upper__doc__[]; +extern const char _Py_title__doc__[]; +extern const char _Py_capitalize__doc__[]; +extern const char _Py_swapcase__doc__[]; +extern const char _Py_count__doc__[]; +extern const char _Py_find__doc__[]; +extern const char _Py_index__doc__[]; +extern const char _Py_rfind__doc__[]; +extern const char _Py_rindex__doc__[]; +extern const char _Py_startswith__doc__[]; +extern const char _Py_endswith__doc__[]; +extern const char _Py_maketrans__doc__[]; +extern const char _Py_expandtabs__doc__[]; +extern const char _Py_ljust__doc__[]; +extern const char _Py_rjust__doc__[]; +extern const char _Py_center__doc__[]; +extern const char _Py_zfill__doc__[]; + +/* this is needed because some docs are shared from the .o, not static */ +#define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str) + +#endif /* !Py_BYTES_CTYPE_H */ +#endif /* !Py_LIMITED_API */ diff --git a/python/include/bytesobject.h b/python/include/bytesobject.h new file mode 100755 index 0000000..3fde4a2 --- /dev/null +++ b/python/include/bytesobject.h @@ -0,0 +1,224 @@ + +/* Bytes (String) object interface */ + +#ifndef Py_BYTESOBJECT_H +#define Py_BYTESOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* +Type PyBytesObject represents a character string. An extra zero byte is +reserved at the end to ensure it is zero-terminated, but a size is +present so strings with null bytes in them can be represented. This +is an immutable object type. + +There are functions to create new string objects, to test +an object for string-ness, and to get the +string value. The latter function returns a null pointer +if the object is not of the proper type. +There is a variant that takes an explicit size as well as a +variant that assumes a zero-terminated string. Note that none of the +functions should be applied to nil objects. +*/ + +/* Caching the hash (ob_shash) saves recalculation of a string's hash value. + This significantly speeds up dict lookups. */ + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_VAR_HEAD + Py_hash_t ob_shash; + char ob_sval[1]; + + /* Invariants: + * ob_sval contains space for 'ob_size+1' elements. + * ob_sval[ob_size] == 0. + * ob_shash is the hash of the string or -1 if not computed yet. + */ +} PyBytesObject; +#endif + +PyAPI_DATA(PyTypeObject) PyBytes_Type; +PyAPI_DATA(PyTypeObject) PyBytesIter_Type; + +#define PyBytes_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) +#define PyBytes_CheckExact(op) (Py_TYPE(op) == &PyBytes_Type) + +PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); +PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *); +PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list) + Py_GCC_ATTRIBUTE((format(printf, 1, 0))); +PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *); +PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); +PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); +PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *); +PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject*) _PyBytes_FormatEx( + const char *format, + Py_ssize_t format_len, + PyObject *args, + int use_bytearray); +PyAPI_FUNC(PyObject*) _PyBytes_FromHex( + PyObject *string, + int use_bytearray); +#endif +PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, Py_ssize_t, + const char *); +#ifndef Py_LIMITED_API +/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ +PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, Py_ssize_t, + const char *, + const char **); +#endif + +/* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API +#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \ + (((PyBytesObject *)(op))->ob_sval)) +#define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op)) +#endif + +/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, + x must be an iterable object. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); +#endif + +/* Provides access to the internal data buffer and size of a string + object or the default encoded version of a Unicode object. Passing + NULL as *len parameter will force the string buffer to be + 0-terminated (passing a string with embedded NULL characters will + cause an exception). */ +PyAPI_FUNC(int) PyBytes_AsStringAndSize( + PyObject *obj, /* string or Unicode object */ + char **s, /* pointer to buffer variable */ + Py_ssize_t *len /* pointer to length variable or NULL + (only possible for 0-terminated + strings) */ + ); + +/* Using the current locale, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGroupingLocale(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width); + +/* Using explicit passed-in values, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); +#endif + +/* Flags used by string formatting */ +#define F_LJUST (1<<0) +#define F_SIGN (1<<1) +#define F_BLANK (1<<2) +#define F_ALT (1<<3) +#define F_ZERO (1<<4) + +#ifndef Py_LIMITED_API +/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer". + A _PyBytesWriter variable must be declared at the end of variables in a + function to optimize the memory allocation on the stack. */ +typedef struct { + /* bytes, bytearray or NULL (when the small buffer is used) */ + PyObject *buffer; + + /* Number of allocated size. */ + Py_ssize_t allocated; + + /* Minimum number of allocated bytes, + incremented by _PyBytesWriter_Prepare() */ + Py_ssize_t min_size; + + /* If non-zero, use a bytearray instead of a bytes object for buffer. */ + int use_bytearray; + + /* If non-zero, overallocate the buffer (default: 0). + This flag must be zero if use_bytearray is non-zero. */ + int overallocate; + + /* Stack buffer */ + int use_small_buffer; + char small_buffer[512]; +} _PyBytesWriter; + +/* Initialize a bytes writer + + By default, the overallocation is disabled. Set the overallocate attribute + to control the allocation of the buffer. */ +PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer); + +/* Get the buffer content and reset the writer. + Return a bytes object, or a bytearray object if use_bytearray is non-zero. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer, + void *str); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer); + +/* Allocate the buffer to write size bytes. + Return the pointer to the beginning of buffer data. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer, + Py_ssize_t size); + +/* Ensure that the buffer is large enough to write *size* bytes. + Add size to the writer minimum size (min_size attribute). + + str is the current pointer inside the buffer. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Resize the buffer to make it larger. + The new buffer may be larger than size bytes because of overallocation. + Return the updated current pointer inside the buffer. + Raise an exception and return NULL on error. + + Note: size must be greater than the number of allocated bytes in the writer. + + This function doesn't use the writer minimum size (min_size attribute). + + See also _PyBytesWriter_Prepare(). + */ +PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer, + void *str, + Py_ssize_t size); + +/* Write bytes. + Raise an exception and return NULL on error. */ +PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, + void *str, + const void *bytes, + Py_ssize_t size); +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BYTESOBJECT_H */ diff --git a/python/include/cellobject.h b/python/include/cellobject.h new file mode 100755 index 0000000..2f9b5b7 --- /dev/null +++ b/python/include/cellobject.h @@ -0,0 +1,29 @@ +/* Cell object interface */ +#ifndef Py_LIMITED_API +#ifndef Py_CELLOBJECT_H +#define Py_CELLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *ob_ref; /* Content of the cell or NULL when empty */ +} PyCellObject; + +PyAPI_DATA(PyTypeObject) PyCell_Type; + +#define PyCell_Check(op) (Py_TYPE(op) == &PyCell_Type) + +PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); +PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); +PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); + +#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref) +#define PyCell_SET(op, v) (((PyCellObject *)(op))->ob_ref = v) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/ceval.h b/python/include/ceval.h new file mode 100755 index 0000000..36fd014 --- /dev/null +++ b/python/include/ceval.h @@ -0,0 +1,231 @@ +#ifndef Py_CEVAL_H +#define Py_CEVAL_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to random parts in ceval.c */ + +/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction + * and PyEval_CallMethod are kept for backward compatibility: PyObject_Call(), + * PyObject_CallFunction() and PyObject_CallMethod() are recommended to call + * a callable object. + */ + +PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( + PyObject *callable, + PyObject *args, + PyObject *kwargs); + +/* Inline this */ +#define PyEval_CallObject(callable, arg) \ + PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL) + +PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *callable, + const char *format, ...); +PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, + const char *name, + const char *format, ...); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth(int new_depth); +PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); +PyAPI_FUNC(void) _PyEval_SetAsyncGenFirstiter(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); +PyAPI_FUNC(void) _PyEval_SetAsyncGenFinalizer(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void); +#endif + +struct _frame; /* Avoid including frameobject.h */ + +PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); +PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); +PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); +PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); + +#ifndef Py_LIMITED_API +/* Helper to look up a builtin object */ +PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *); +/* Look at the current frame's (if any) code's co_flags, and turn on + the corresponding compiler flags in cf->cf_flags. Return 1 if any + flag was set, else return 0. */ +PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); +#endif + +PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); +PyAPI_FUNC(int) Py_MakePendingCalls(void); + +/* Protection against deeply nested recursive calls + + In Python 3.0, this protection has two levels: + * normal anti-recursion protection is triggered when the recursion level + exceeds the current recursion limit. It raises a RecursionError, and sets + the "overflowed" flag in the thread state structure. This flag + temporarily *disables* the normal protection; this allows cleanup code + to potentially outgrow the recursion limit while processing the + RecursionError. + * "last chance" anti-recursion protection is triggered when the recursion + level exceeds "current recursion limit + 50". By construction, this + protection can only be triggered when the "overflowed" flag is set. It + means the cleanup code has itself gone into an infinite loop, or the + RecursionError has been mistakingly ignored. When this protection is + triggered, the interpreter aborts with a Fatal Error. + + In addition, the "overflowed" flag is automatically reset when the + recursion level drops below "current recursion limit - 50". This heuristic + is meant to ensure that the normal anti-recursion protection doesn't get + disabled too long. + + Please note: this scheme has its own limitations. See: + http://mail.python.org/pipermail/python-dev/2008-August/082106.html + for some observations. +*/ +PyAPI_FUNC(void) Py_SetRecursionLimit(int); +PyAPI_FUNC(int) Py_GetRecursionLimit(void); + +#define Py_EnterRecursiveCall(where) \ + (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ + _Py_CheckRecursiveCall(where)) +#define Py_LeaveRecursiveCall() \ + do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ + PyThreadState_GET()->overflowed = 0; \ + } while(0) +PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); + +/* Due to the macros in which it's used, _Py_CheckRecursionLimit is in + the stable ABI. It should be removed therefrom when possible. +*/ +PyAPI_DATA(int) _Py_CheckRecursionLimit; + +#ifdef USE_STACKCHECK +/* With USE_STACKCHECK, trigger stack checks in _Py_CheckRecursiveCall() + on every 64th call to Py_EnterRecursiveCall. +*/ +# define _Py_MakeRecCheck(x) \ + (++(x) > _Py_CheckRecursionLimit || \ + ++(PyThreadState_GET()->stackcheck_counter) > 64) +#else +# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) +#endif + +/* Compute the "lower-water mark" for a recursion limit. When + * Py_LeaveRecursiveCall() is called with a recursion depth below this mark, + * the overflowed flag is reset to 0. */ +#define _Py_RecursionLimitLowerWaterMark(limit) \ + (((limit) > 200) \ + ? ((limit) - 50) \ + : (3 * ((limit) >> 2))) + +#define _Py_MakeEndRecCheck(x) \ + (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) + +#define Py_ALLOW_RECURSION \ + do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ + PyThreadState_GET()->recursion_critical = 1; + +#define Py_END_ALLOW_RECURSION \ + PyThreadState_GET()->recursion_critical = _old; \ + } while(0); + +PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); +PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); +PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(struct _frame *f, int exc); +#endif + +/* Interface for threads. + + A module that plans to do a blocking system call (or something else + that lasts a long time and doesn't touch Python data) can allow other + threads to run as follows: + + ...preparations here... + Py_BEGIN_ALLOW_THREADS + ...blocking system call here... + Py_END_ALLOW_THREADS + ...interpret result here... + + The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a + {}-surrounded block. + To leave the block in the middle (e.g., with return), you must insert + a line containing Py_BLOCK_THREADS before the return, e.g. + + if (...premature_exit...) { + Py_BLOCK_THREADS + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + An alternative is: + + Py_BLOCK_THREADS + if (...premature_exit...) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_UNBLOCK_THREADS + + For convenience, that the value of 'errno' is restored across + Py_END_ALLOW_THREADS and Py_BLOCK_THREADS. + + WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND + Py_END_ALLOW_THREADS!!! + + The function PyEval_InitThreads() should be called only from + init_thread() in "_threadmodule.c". + + Note that not yet all candidates have been converted to use this + mechanism! +*/ + +PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); +PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); + +PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); +PyAPI_FUNC(void) PyEval_InitThreads(void); +Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void); +/* Py_DEPRECATED(3.2) */ PyAPI_FUNC(void) PyEval_ReleaseLock(void); +PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); +PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); +PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); +#endif + +#define Py_BEGIN_ALLOW_THREADS { \ + PyThreadState *_save; \ + _save = PyEval_SaveThread(); +#define Py_BLOCK_THREADS PyEval_RestoreThread(_save); +#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); +#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ + } + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); +#endif + +/* Masks and values used by FORMAT_VALUE opcode. */ +#define FVC_MASK 0x3 +#define FVC_NONE 0x0 +#define FVC_STR 0x1 +#define FVC_REPR 0x2 +#define FVC_ASCII 0x3 +#define FVS_MASK 0x4 +#define FVS_HAVE_SPEC 0x4 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CEVAL_H */ diff --git a/python/include/classobject.h b/python/include/classobject.h new file mode 100755 index 0000000..c83303c --- /dev/null +++ b/python/include/classobject.h @@ -0,0 +1,59 @@ +/* Former class object interface -- now only bound methods are here */ + +/* Revealing some structures (not for general use) */ + +#ifndef Py_LIMITED_API +#ifndef Py_CLASSOBJECT_H +#define Py_CLASSOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *im_func; /* The callable object implementing the method */ + PyObject *im_self; /* The instance it is bound to */ + PyObject *im_weakreflist; /* List of weak references */ + vectorcallfunc vectorcall; +} PyMethodObject; + +PyAPI_DATA(PyTypeObject) PyMethod_Type; + +#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type) + +PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyMethod_GET_FUNCTION(meth) \ + (((PyMethodObject *)meth) -> im_func) +#define PyMethod_GET_SELF(meth) \ + (((PyMethodObject *)meth) -> im_self) + +PyAPI_FUNC(int) PyMethod_ClearFreeList(void); + +typedef struct { + PyObject_HEAD + PyObject *func; +} PyInstanceMethodObject; + +PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; + +#define PyInstanceMethod_Check(op) ((op)->ob_type == &PyInstanceMethod_Type) + +PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyInstanceMethod_GET_FUNCTION(meth) \ + (((PyInstanceMethodObject *)meth) -> func) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CLASSOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/code.h b/python/include/code.h new file mode 100755 index 0000000..a1cd58f --- /dev/null +++ b/python/include/code.h @@ -0,0 +1,180 @@ +/* Definitions for bytecode */ + +#ifndef Py_LIMITED_API +#ifndef Py_CODE_H +#define Py_CODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint16_t _Py_CODEUNIT; + +#ifdef WORDS_BIGENDIAN +# define _Py_OPCODE(word) ((word) >> 8) +# define _Py_OPARG(word) ((word) & 255) +#else +# define _Py_OPCODE(word) ((word) & 255) +# define _Py_OPARG(word) ((word) >> 8) +#endif + +typedef struct _PyOpcache _PyOpcache; + +/* Bytecode object */ +typedef struct { + PyObject_HEAD + int co_argcount; /* #arguments, except *args */ + int co_posonlyargcount; /* #positional only arguments */ + int co_kwonlyargcount; /* #keyword only arguments */ + int co_nlocals; /* #local variables */ + int co_stacksize; /* #entries needed for evaluation stack */ + int co_flags; /* CO_..., see below */ + int co_firstlineno; /* first source line number */ + PyObject *co_code; /* instruction opcodes */ + PyObject *co_consts; /* list (constants used) */ + PyObject *co_names; /* list of strings (names used) */ + PyObject *co_varnames; /* tuple of strings (local variable names) */ + PyObject *co_freevars; /* tuple of strings (free variable names) */ + PyObject *co_cellvars; /* tuple of strings (cell variable names) */ + /* The rest aren't used in either hash or comparisons, except for co_name, + used in both. This is done to preserve the name and line number + for tracebacks and debuggers; otherwise, constant de-duplication + would collapse identical functions/lambdas defined on different lines. + */ + Py_ssize_t *co_cell2arg; /* Maps cell vars which are arguments. */ + PyObject *co_filename; /* unicode (where it was loaded from) */ + PyObject *co_name; /* unicode (name, for reference) */ + PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See + Objects/lnotab_notes.txt for details. */ + void *co_zombieframe; /* for optimization only (see frameobject.c) */ + PyObject *co_weakreflist; /* to support weakrefs to code objects */ + /* Scratch space for extra data relating to the code object. + Type is a void* to keep the format private in codeobject.c to force + people to go through the proper APIs. */ + void *co_extra; + + /* Per opcodes just-in-time cache + * + * To reduce cache size, we use indirect mapping from opcode index to + * cache object: + * cache = co_opcache[co_opcache_map[next_instr - first_instr] - 1] + */ + + // co_opcache_map is indexed by (next_instr - first_instr). + // * 0 means there is no cache for this opcode. + // * n > 0 means there is cache in co_opcache[n-1]. + unsigned char *co_opcache_map; + _PyOpcache *co_opcache; + int co_opcache_flag; // used to determine when create a cache. + unsigned char co_opcache_size; // length of co_opcache. +} PyCodeObject; + +/* Masks for co_flags above */ +#define CO_OPTIMIZED 0x0001 +#define CO_NEWLOCALS 0x0002 +#define CO_VARARGS 0x0004 +#define CO_VARKEYWORDS 0x0008 +#define CO_NESTED 0x0010 +#define CO_GENERATOR 0x0020 +/* The CO_NOFREE flag is set if there are no free or cell variables. + This information is redundant, but it allows a single flag test + to determine whether there is any extra work to be done when the + call frame it setup. +*/ +#define CO_NOFREE 0x0040 + +/* The CO_COROUTINE flag is set for coroutine functions (defined with + ``async def`` keywords) */ +#define CO_COROUTINE 0x0080 +#define CO_ITERABLE_COROUTINE 0x0100 +#define CO_ASYNC_GENERATOR 0x0200 + +/* bpo-39562: These constant values are changed in Python 3.9 + to prevent collision with compiler flags. CO_FUTURE_ and PyCF_ + constants must be kept unique. PyCF_ constants can use bits from + 0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */ +#define CO_FUTURE_DIVISION 0x20000 +#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */ +#define CO_FUTURE_WITH_STATEMENT 0x80000 +#define CO_FUTURE_PRINT_FUNCTION 0x100000 +#define CO_FUTURE_UNICODE_LITERALS 0x200000 + +#define CO_FUTURE_BARRY_AS_BDFL 0x400000 +#define CO_FUTURE_GENERATOR_STOP 0x800000 +#define CO_FUTURE_ANNOTATIONS 0x1000000 + +/* This value is found in the co_cell2arg array when the associated cell + variable does not correspond to an argument. */ +#define CO_CELL_NOT_AN_ARG (-1) + +/* This should be defined if a future statement modifies the syntax. + For example, when a keyword is added. +*/ +#define PY_PARSER_REQUIRES_FUTURE_KEYWORD + +#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ + +PyAPI_DATA(PyTypeObject) PyCode_Type; + +#define PyCode_Check(op) (Py_TYPE(op) == &PyCode_Type) +#define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars)) + +/* Public interface */ +PyAPI_FUNC(PyCodeObject *) PyCode_New( + int, int, int, int, int, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, PyObject *, + PyObject *, PyObject *, int, PyObject *); + +PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs( + int, int, int, int, int, int, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, PyObject *, + PyObject *, PyObject *, int, PyObject *); + /* same as struct above */ + +/* Creates a new empty code object with the specified source location. */ +PyAPI_FUNC(PyCodeObject *) +PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno); + +/* Return the line number associated with the specified bytecode index + in this code object. If you just need the line number of a frame, + use PyFrame_GetLineNumber() instead. */ +PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); + +/* for internal use only */ +typedef struct _addr_pair { + int ap_lower; + int ap_upper; +} PyAddrPair; + +#ifndef Py_LIMITED_API +/* Update *bounds to describe the first and one-past-the-last instructions in the + same line as lasti. Return the number of that line. +*/ +PyAPI_FUNC(int) _PyCode_CheckLineNumber(PyCodeObject* co, + int lasti, PyAddrPair *bounds); + +/* Create a comparable key used to compare constants taking in account the + * object type. It is used to make sure types are not coerced (e.g., float and + * complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms + * + * Return (type(obj), obj, ...): a tuple with variable size (at least 2 items) + * depending on the type and the value. The type is the first item to not + * compare bytes and str which can raise a BytesWarning exception. */ +PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj); +#endif + +PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, + PyObject *names, PyObject *lnotab); + + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index, + void **extra); +PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, + void *extra); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODE_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/codecs.h b/python/include/codecs.h new file mode 100755 index 0000000..3ad0f2b --- /dev/null +++ b/python/include/codecs.h @@ -0,0 +1,240 @@ +#ifndef Py_CODECREGISTRY_H +#define Py_CODECREGISTRY_H +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------------ + + Python Codec Registry and support functions + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +Copyright (c) Corporation for National Research Initiatives. + + ------------------------------------------------------------------------ */ + +/* Register a new codec search function. + + As side effect, this tries to load the encodings package, if not + yet done, to make sure that it is always first in the list of + search functions. + + The search_function's refcount is incremented by this function. */ + +PyAPI_FUNC(int) PyCodec_Register( + PyObject *search_function + ); + +/* Codec registry lookup API. + + Looks up the given encoding and returns a CodecInfo object with + function attributes which implement the different aspects of + processing the encoding. + + The encoding string is looked up converted to all lower-case + characters. This makes encodings looked up through this mechanism + effectively case-insensitive. + + If no codec is found, a KeyError is set and NULL returned. + + As side effect, this tries to load the encodings package, if not + yet done. This is part of the lazy load strategy for the encodings + package. + + */ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyCodec_Lookup( + const char *encoding + ); + +PyAPI_FUNC(int) _PyCodec_Forget( + const char *encoding + ); +#endif + +/* Codec registry encoding check API. + + Returns 1/0 depending on whether there is a registered codec for + the given encoding. + +*/ + +PyAPI_FUNC(int) PyCodec_KnownEncoding( + const char *encoding + ); + +/* Generic codec based encoding API. + + object is passed through the encoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Encode( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* Generic codec based decoding API. + + object is passed through the decoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Decode( + PyObject *object, + const char *encoding, + const char *errors + ); + +#ifndef Py_LIMITED_API +/* Text codec specific encoding and decoding API. + + Checks the encoding against a list of codecs which do not + implement a str<->bytes encoding before attempting the + operation. + + Please note that these APIs are internal and should not + be used in Python C extensions. + + XXX (ncoghlan): should we make these, or something like them, public + in Python 3.5+? + + */ +PyAPI_FUNC(PyObject *) _PyCodec_LookupTextEncoding( + const char *encoding, + const char *alternate_command + ); + +PyAPI_FUNC(PyObject *) _PyCodec_EncodeText( + PyObject *object, + const char *encoding, + const char *errors + ); + +PyAPI_FUNC(PyObject *) _PyCodec_DecodeText( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* These two aren't actually text encoding specific, but _io.TextIOWrapper + * is the only current API consumer. + */ +PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalDecoder( + PyObject *codec_info, + const char *errors + ); + +PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalEncoder( + PyObject *codec_info, + const char *errors + ); +#endif + + + +/* --- Codec Lookup APIs -------------------------------------------------- + + All APIs return a codec object with incremented refcount and are + based on _PyCodec_Lookup(). The same comments w/r to the encoding + name also apply to these APIs. + +*/ + +/* Get an encoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Encoder( + const char *encoding + ); + +/* Get a decoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Decoder( + const char *encoding + ); + +/* Get an IncrementalEncoder object for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( + const char *encoding, + const char *errors + ); + +/* Get an IncrementalDecoder object function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( + const char *encoding, + const char *errors + ); + +/* Get a StreamReader factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamReader( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Get a StreamWriter factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamWriter( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Unicode encoding error handling callback registry API */ + +/* Register the error handling callback function error under the given + name. This function will be called by the codec when it encounters + unencodable characters/undecodable bytes and doesn't know the + callback name, when name is specified as the error parameter + in the call to the encode/decode function. + Return 0 on success, -1 on error */ +PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error); + +/* Lookup the error handling callback function registered under the given + name. As a special case NULL can be passed, in which case + the error handling callback for "strict" will be returned. */ +PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name); + +/* raise exc as an exception */ +PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc); + +/* ignore the unicode error, skipping the faulty input */ +PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc); + +/* replace the unicode encode error with ? or U+FFFD */ +PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with XML character references */ +PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with backslash escapes (\x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc); +#endif + +#ifndef Py_LIMITED_API +PyAPI_DATA(const char *) Py_hexdigits; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODECREGISTRY_H */ diff --git a/python/include/compile.h b/python/include/compile.h new file mode 100755 index 0000000..015584d --- /dev/null +++ b/python/include/compile.h @@ -0,0 +1,106 @@ +#ifndef Py_COMPILE_H +#define Py_COMPILE_H + +#ifndef Py_LIMITED_API +#include "code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public interface */ +struct _node; /* Declare the existence of this type */ +PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); +/* XXX (ncoghlan): Unprefixed type name in a public API! */ + +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ + CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ + CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) +#define PyCF_MASK_OBSOLETE (CO_NESTED) + +/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. + PyCF_ constants can use bits from 0x0100 to 0x10000. + CO_FUTURE_ constants use bits starting at 0x20000. */ +#define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 +#define PyCF_IGNORE_COOKIE 0x0800 +#define PyCF_TYPE_COMMENTS 0x1000 +#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 +#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ + PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT) + +#ifndef Py_LIMITED_API +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ + int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ +} PyCompilerFlags; + +#define _PyCompilerFlags_INIT \ + (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} +#endif + +/* Future feature support */ + +typedef struct { + int ff_features; /* flags set by future statements */ + int ff_lineno; /* line number of last future statement */ +} PyFutureFeatures; + +#define FUTURE_NESTED_SCOPES "nested_scopes" +#define FUTURE_GENERATORS "generators" +#define FUTURE_DIVISION "division" +#define FUTURE_ABSOLUTE_IMPORT "absolute_import" +#define FUTURE_WITH_STATEMENT "with_statement" +#define FUTURE_PRINT_FUNCTION "print_function" +#define FUTURE_UNICODE_LITERALS "unicode_literals" +#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" +#define FUTURE_GENERATOR_STOP "generator_stop" +#define FUTURE_ANNOTATIONS "annotations" + +struct _mod; /* Declare the existence of this type */ +#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar) +PyAPI_FUNC(PyCodeObject *) PyAST_CompileEx( + struct _mod *mod, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags, + int optimize, + PyArena *arena); +PyAPI_FUNC(PyCodeObject *) PyAST_CompileObject( + struct _mod *mod, + PyObject *filename, + PyCompilerFlags *flags, + int optimize, + PyArena *arena); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST( + struct _mod * mod, + const char *filename /* decoded from the filesystem encoding */ + ); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromASTObject( + struct _mod * mod, + PyObject *filename + ); + +/* _Py_Mangle is defined in compile.c */ +PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); + +#define PY_INVALID_STACK_EFFECT INT_MAX +PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); +PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); + +PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, int optimize); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_LIMITED_API */ + +/* These definitions must match corresponding definitions in graminit.h. */ +#define Py_single_input 256 +#define Py_file_input 257 +#define Py_eval_input 258 +#define Py_func_type_input 345 + +#endif /* !Py_COMPILE_H */ diff --git a/python/include/complexobject.h b/python/include/complexobject.h new file mode 100755 index 0000000..cb8c52c --- /dev/null +++ b/python/include/complexobject.h @@ -0,0 +1,69 @@ +/* Complex number structure */ + +#ifndef Py_COMPLEXOBJECT_H +#define Py_COMPLEXOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +typedef struct { + double real; + double imag; +} Py_complex; + +/* Operations on complex numbers from complexmodule.c */ + +PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); +PyAPI_FUNC(double) _Py_c_abs(Py_complex); +#endif + +/* Complex object interface */ + +/* +PyComplexObject represents a complex number with double-precision +real and imaginary parts. +*/ +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + Py_complex cval; +} PyComplexObject; +#endif + +PyAPI_DATA(PyTypeObject) PyComplex_Type; + +#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) +#define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type) + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); +#endif +PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); + +PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); +PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); +#endif + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyComplex_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COMPLEXOBJECT_H */ diff --git a/python/include/context.h b/python/include/context.h new file mode 100755 index 0000000..9581285 --- /dev/null +++ b/python/include/context.h @@ -0,0 +1,84 @@ +#ifndef Py_CONTEXT_H +#define Py_CONTEXT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + + +PyAPI_DATA(PyTypeObject) PyContext_Type; +typedef struct _pycontextobject PyContext; + +PyAPI_DATA(PyTypeObject) PyContextVar_Type; +typedef struct _pycontextvarobject PyContextVar; + +PyAPI_DATA(PyTypeObject) PyContextToken_Type; +typedef struct _pycontexttokenobject PyContextToken; + + +#define PyContext_CheckExact(o) (Py_TYPE(o) == &PyContext_Type) +#define PyContextVar_CheckExact(o) (Py_TYPE(o) == &PyContextVar_Type) +#define PyContextToken_CheckExact(o) (Py_TYPE(o) == &PyContextToken_Type) + + +PyAPI_FUNC(PyObject *) PyContext_New(void); +PyAPI_FUNC(PyObject *) PyContext_Copy(PyObject *); +PyAPI_FUNC(PyObject *) PyContext_CopyCurrent(void); + +PyAPI_FUNC(int) PyContext_Enter(PyObject *); +PyAPI_FUNC(int) PyContext_Exit(PyObject *); + + +/* Create a new context variable. + + default_value can be NULL. +*/ +PyAPI_FUNC(PyObject *) PyContextVar_New( + const char *name, PyObject *default_value); + + +/* Get a value for the variable. + + Returns -1 if an error occurred during lookup. + + Returns 0 if value either was or was not found. + + If value was found, *value will point to it. + If not, it will point to: + + - default_value, if not NULL; + - the default value of "var", if not NULL; + - NULL. + + '*value' will be a new ref, if not NULL. +*/ +PyAPI_FUNC(int) PyContextVar_Get( + PyObject *var, PyObject *default_value, PyObject **value); + + +/* Set a new value for the variable. + Returns NULL if an error occurs. +*/ +PyAPI_FUNC(PyObject *) PyContextVar_Set(PyObject *var, PyObject *value); + + +/* Reset a variable to its previous value. + Returns 0 on success, -1 on error. +*/ +PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token); + + +/* This method is exposed only for CPython tests. Don not use it. */ +PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void); + + +PyAPI_FUNC(int) PyContext_ClearFreeList(void); + + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CONTEXT_H */ diff --git a/python/include/cpython/abstract.h b/python/include/cpython/abstract.h new file mode 100755 index 0000000..dbfce2d --- /dev/null +++ b/python/include/cpython/abstract.h @@ -0,0 +1,319 @@ +#ifndef Py_CPYTHON_ABSTRACTOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* === Object Protocol ================================================== */ + +#ifdef PY_SSIZE_T_CLEAN +# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT +#endif + +/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) + format to a Python dictionary ("kwargs" dict). + + The type of kwnames keys is not checked. The final function getting + arguments is responsible to check if all keys are strings, for example using + PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). + + Duplicate keys are merged using the last value. If duplicate keys must raise + an exception, the caller is responsible to implement an explicit keys on + kwnames. */ +PyAPI_FUNC(PyObject *) _PyStack_AsDict( + PyObject *const *values, + PyObject *kwnames); + +/* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple). + + Return 0 on success, raise an exception and return -1 on error. + + Write the new stack into *p_stack. If *p_stack is differen than args, it + must be released by PyMem_Free(). + + The stack uses borrowed references. + + The type of keyword keys is not checked, these checks should be done + later (ex: _PyArg_ParseStackAndKeywords). */ +PyAPI_FUNC(int) _PyStack_UnpackDict( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs, + PyObject *const **p_stack, + PyObject **p_kwnames); + +/* Suggested size (number of positional arguments) for arrays of PyObject* + allocated on a C stack to avoid allocating memory on the heap memory. Such + array is used to pass positional arguments to call functions of the + _PyObject_Vectorcall() family. + + The size is chosen to not abuse the C stack and so limit the risk of stack + overflow. The size is also chosen to allow using the small stack for most + function calls of the Python standard library. On 64-bit CPU, it allocates + 40 bytes on the stack. */ +#define _PY_FASTCALL_SMALL_STACK 5 + +PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable, + PyObject *result, + const char *where); + +/* === Vectorcall protocol (PEP 590) ============================= */ + +/* Call callable using tp_call. Arguments are like _PyObject_Vectorcall() + or _PyObject_FastCallDict() (both forms are supported), + except that nargs is plainly the number of arguments without flags. */ +PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( + PyObject *callable, + PyObject *const *args, Py_ssize_t nargs, + PyObject *keywords); + +#define PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + +static inline Py_ssize_t +PyVectorcall_NARGS(size_t n) +{ + return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; +} + +static inline vectorcallfunc +_PyVectorcall_Function(PyObject *callable) +{ + PyTypeObject *tp = Py_TYPE(callable); + Py_ssize_t offset = tp->tp_vectorcall_offset; + vectorcallfunc ptr; + if (!PyType_HasFeature(tp, _Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + assert(offset > 0); + memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); + return ptr; +} + +/* Call the callable object 'callable' with the "vectorcall" calling + convention. + + args is a C array for positional arguments. + + nargsf is the number of positional arguments plus optionally the flag + PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to + modify args[-1]. + + kwnames is a tuple of keyword names. The values of the keyword arguments + are stored in "args" after the positional arguments (note that the number + of keyword arguments does not change nargsf). kwnames can also be NULL if + there are no keyword arguments. + + keywords must only contains str strings (no subclass), and all keys must + be unique. + + Return the result on success. Raise an exception and return NULL on + error. */ +static inline PyObject * +_PyObject_Vectorcall(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + PyObject *res; + vectorcallfunc func; + assert(kwnames == NULL || PyTuple_Check(kwnames)); + assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); + func = _PyVectorcall_Function(callable); + if (func == NULL) { + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + return _PyObject_MakeTpCall(callable, args, nargs, kwnames); + } + res = func(callable, args, nargsf, kwnames); + return _Py_CheckFunctionResult(callable, res, NULL); +} + +/* Same as _PyObject_Vectorcall except that keyword arguments are passed as + dict, which may be NULL if there are no keyword arguments. */ +PyAPI_FUNC(PyObject *) _PyObject_FastCallDict( + PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwargs); + +/* Call "callable" (which must support vectorcall) with positional arguments + "tuple" and keyword arguments "dict". "dict" may also be NULL */ +PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); + +/* Same as _PyObject_Vectorcall except without keyword arguments */ +static inline PyObject * +_PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) +{ + return _PyObject_Vectorcall(func, args, (size_t)nargs, NULL); +} + +/* Call a callable without any arguments */ +static inline PyObject * +_PyObject_CallNoArg(PyObject *func) { + return _PyObject_Vectorcall(func, NULL, 0, NULL); +} + +PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( + PyObject *callable, + PyObject *obj, + PyObject *args, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyObject_FastCall_Prepend( + PyObject *callable, + PyObject *obj, + PyObject *const *args, + Py_ssize_t nargs); + +/* Like PyObject_CallMethod(), but expect a _Py_Identifier* + as the method name. */ +PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, + _Py_Identifier *name, + const char *format, ...); + +PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, + _Py_Identifier *name, + const char *format, + ...); + +PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( + PyObject *obj, + struct _Py_Identifier *name, + ...); + +PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); + +/* Guess the size of object 'o' using len(o) or o.__length_hint__(). + If neither of those return a non-negative value, then return the default + value. If one of the calls fails, this function returns -1. */ +PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); + +/* === New Buffer API ============================================ */ + +/* Return 1 if the getbuffer function is available, otherwise return 0. */ +#define PyObject_CheckBuffer(obj) \ + (((obj)->ob_type->tp_as_buffer != NULL) && \ + ((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL)) + +/* This is a C-API version of the getbuffer function call. It checks + to make sure object has the required function pointer and issues the + call. + + Returns -1 and raises an error on failure and returns 0 on success. */ +PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, + int flags); + +/* Get the memory area pointed to by the indices for the buffer given. + Note that view->ndim is the assumed size of indices. */ +PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); + +/* Return the implied itemsize of the data-format area from a + struct-style description. */ +PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *); + +/* Implementation in memoryobject.c */ +PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view, + Py_ssize_t len, char order); + +PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf, + Py_ssize_t len, char order); + +/* Copy len bytes of data from the contiguous chunk of memory + pointed to by buf into the buffer exported by obj. Return + 0 on success and return -1 and raise a PyBuffer_Error on + error (i.e. the object does not have a buffer interface or + it is not working). + + If fort is 'F', then if the object is multi-dimensional, + then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If + fort is 'C', then the data will be copied into the array + in C-style (last dimension varies the fastest). If fort + is 'A', then it does not matter and the copy will be made + in whatever way is more efficient. */ +PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); + +/* Copy the data from the src buffer to the buffer of destination. */ +PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort); + +/*Fill the strides array with byte-strides of a contiguous + (Fortran-style if fort is 'F' or C-style otherwise) + array of the given shape with the given number of bytes + per element. */ +PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, + Py_ssize_t *shape, + Py_ssize_t *strides, + int itemsize, + char fort); + +/* Fills in a buffer-info structure correctly for an exporter + that can only share a contiguous chunk of memory of + "unsigned bytes" of the given length. + + Returns 0 on success and -1 (with raising an error) on error. */ +PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, + Py_ssize_t len, int readonly, + int flags); + +/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ +PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); + +/* ==== Iterators ================================================ */ + +#define PyIter_Check(obj) \ + ((obj)->ob_type->tp_iternext != NULL && \ + (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented) + +/* === Number Protocol ================================================== */ + +#define PyIndex_Check(obj) \ + ((obj)->ob_type->tp_as_number != NULL && \ + (obj)->ob_type->tp_as_number->nb_index != NULL) + +/* === Sequence protocol ================================================ */ + +/* Assume tp_as_sequence and sq_item exist and that 'i' does not + need to be corrected for a negative index. */ +#define PySequence_ITEM(o, i)\ + ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) + +#define PY_ITERSEARCH_COUNT 1 +#define PY_ITERSEARCH_INDEX 2 +#define PY_ITERSEARCH_CONTAINS 3 + +/* Iterate over seq. + + Result depends on the operation: + + PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if + error. + PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of + obj in seq; set ValueError and return -1 if none found; + also return -1 on error. + PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on + error. */ +PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, + PyObject *obj, int operation); + +/* === Mapping protocol ================================================= */ + +PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); + +PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); + +PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self); + +PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]); + +/* For internal use by buffer API functions */ +PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); +PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); + +/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ +PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/dictobject.h b/python/include/cpython/dictobject.h new file mode 100755 index 0000000..64c012a --- /dev/null +++ b/python/include/cpython/dictobject.h @@ -0,0 +1,94 @@ +#ifndef Py_CPYTHON_DICTOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _dictkeysobject PyDictKeysObject; + +/* The ma_values pointer is NULL for a combined table + * or points to an array of PyObject* for a split table + */ +typedef struct { + PyObject_HEAD + + /* Number of items in the dictionary */ + Py_ssize_t ma_used; + + /* Dictionary version: globally unique, value change each time + the dictionary is modified */ + uint64_t ma_version_tag; + + PyDictKeysObject *ma_keys; + + /* If ma_values is NULL, the table is "combined": keys and values + are stored in ma_keys. + + If ma_values is not NULL, the table is splitted: + keys are stored in ma_keys and values are stored in ma_values */ + PyObject **ma_values; +} PyDictObject; + +PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, + struct _Py_Identifier *key); +PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyDict_SetDefault( + PyObject *mp, PyObject *key, PyObject *defaultobj); +PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, + PyObject *item, Py_hash_t hash); +PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, + int (*predicate)(PyObject *value)); +PyDictKeysObject *_PyDict_NewKeysForClass(void); +PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *); +PyAPI_FUNC(int) _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); + +/* Get the number of items of a dictionary. */ +#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used) +PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash); +PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); +PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); +PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); +Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); +PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); +PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *); +PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); +PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); +#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) + +PyAPI_FUNC(int) PyDict_ClearFreeList(void); + +/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0, + the first occurrence of a key wins, if override is 1, the last occurrence + of a key wins, if override is 2, a KeyError with conflicting key as + argument is raised. +*/ +PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); +PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key); +PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item); + +PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key); +PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); + +int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); +PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); + +/* _PyDictView */ + +typedef struct { + PyObject_HEAD + PyDictObject *dv_dict; +} _PyDictViewObject; + +PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); +PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/fileobject.h b/python/include/cpython/fileobject.h new file mode 100755 index 0000000..3005ce1 --- /dev/null +++ b/python/include/cpython/fileobject.h @@ -0,0 +1,24 @@ +#ifndef Py_CPYTHON_FILEOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); + +/* The std printer acts as a preliminary sys.stderr until the new io + infrastructure is in place. */ +PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); +PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; + +typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *); + +PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); +PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); +PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/initconfig.h b/python/include/cpython/initconfig.h new file mode 100755 index 0000000..4b5ceaf --- /dev/null +++ b/python/include/cpython/initconfig.h @@ -0,0 +1,434 @@ +#ifndef Py_PYCORECONFIG_H +#define Py_PYCORECONFIG_H +#ifndef Py_LIMITED_API +#ifdef __cplusplus +extern "C" { +#endif + +/* --- PyStatus ----------------------------------------------- */ + +typedef struct { + enum { + _PyStatus_TYPE_OK=0, + _PyStatus_TYPE_ERROR=1, + _PyStatus_TYPE_EXIT=2 + } _type; + const char *func; + const char *err_msg; + int exitcode; +} PyStatus; + +PyAPI_FUNC(PyStatus) PyStatus_Ok(void); +PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg); +PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void); +PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode); +PyAPI_FUNC(int) PyStatus_IsError(PyStatus err); +PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err); +PyAPI_FUNC(int) PyStatus_Exception(PyStatus err); + +/* --- PyWideStringList ------------------------------------------------ */ + +typedef struct { + /* If length is greater than zero, items must be non-NULL + and all items strings must be non-NULL */ + Py_ssize_t length; + wchar_t **items; +} PyWideStringList; + +PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list, + const wchar_t *item); +PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list, + Py_ssize_t index, + const wchar_t *item); + + +/* --- PyPreConfig ----------------------------------------------- */ + +typedef struct { + int _config_init; /* _PyConfigInitEnum value */ + + /* Parse Py_PreInitializeFromBytesArgs() arguments? + See PyConfig.parse_argv */ + int parse_argv; + + /* If greater than 0, enable isolated mode: sys.path contains + neither the script's directory nor the user's site-packages directory. + + Set to 1 by the -I command line option. If set to -1 (default), inherit + Py_IsolatedFlag value. */ + int isolated; + + /* If greater than 0: use environment variables. + Set to 0 by -E command line option. If set to -1 (default), it is + set to !Py_IgnoreEnvironmentFlag. */ + int use_environment; + + /* Set the LC_CTYPE locale to the user preferred locale? If equals to 0, + set coerce_c_locale and coerce_c_locale_warn to 0. */ + int configure_locale; + + /* Coerce the LC_CTYPE locale if it's equal to "C"? (PEP 538) + + Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1. + Set to 2 if the user preferred LC_CTYPE locale is "C". + + If it is equal to 1, LC_CTYPE locale is read to decide if it should be + coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2 + if the LC_CTYPE locale must be coerced. + + Disable by default (set to 0). Set it to -1 to let Python decide if it + should be enabled or not. */ + int coerce_c_locale; + + /* Emit a warning if the LC_CTYPE locale is coerced? + + Set to 1 by PYTHONCOERCECLOCALE=warn. + + Disable by default (set to 0). Set it to -1 to let Python decide if it + should be enabled or not. */ + int coerce_c_locale_warn; + +#ifdef MS_WINDOWS + /* If greater than 1, use the "mbcs" encoding instead of the UTF-8 + encoding for the filesystem encoding. + + Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is + set to a non-empty string. If set to -1 (default), inherit + Py_LegacyWindowsFSEncodingFlag value. + + See PEP 529 for more details. */ + int legacy_windows_fs_encoding; +#endif + + /* Enable UTF-8 mode? (PEP 540) + + Disabled by default (equals to 0). + + Set to 1 by "-X utf8" and "-X utf8=1" command line options. + Set to 1 by PYTHONUTF8=1 environment variable. + + Set to 0 by "-X utf8=0" and PYTHONUTF8=0. + + If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or + "POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */ + int utf8_mode; + + int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */ + + /* Memory allocator: PYTHONMALLOC env var. + See PyMemAllocatorName for valid values. */ + int allocator; +} PyPreConfig; + +PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config); +PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config); + + +/* --- PyConfig ---------------------------------------------- */ + +typedef struct { + int _config_init; /* _PyConfigInitEnum value */ + + int isolated; /* Isolated mode? see PyPreConfig.isolated */ + int use_environment; /* Use environment variables? see PyPreConfig.use_environment */ + int dev_mode; /* Development mode? See PyPreConfig.dev_mode */ + + /* Install signal handlers? Yes by default. */ + int install_signal_handlers; + + int use_hash_seed; /* PYTHONHASHSEED=x */ + unsigned long hash_seed; + + /* Enable faulthandler? + Set to 1 by -X faulthandler and PYTHONFAULTHANDLER. -1 means unset. */ + int faulthandler; + + /* Enable tracemalloc? + Set by -X tracemalloc=N and PYTHONTRACEMALLOC. -1 means unset */ + int tracemalloc; + + int import_time; /* PYTHONPROFILEIMPORTTIME, -X importtime */ + int show_ref_count; /* -X showrefcount */ + int show_alloc_count; /* -X showalloccount */ + int dump_refs; /* PYTHONDUMPREFS */ + int malloc_stats; /* PYTHONMALLOCSTATS */ + + /* Python filesystem encoding and error handler: + sys.getfilesystemencoding() and sys.getfilesystemencodeerrors(). + + Default encoding and error handler: + + * if Py_SetStandardStreamEncoding() has been called: they have the + highest priority; + * PYTHONIOENCODING environment variable; + * The UTF-8 Mode uses UTF-8/surrogateescape; + * If Python forces the usage of the ASCII encoding (ex: C locale + or POSIX locale on FreeBSD or HP-UX), use ASCII/surrogateescape; + * locale encoding: ANSI code page on Windows, UTF-8 on Android and + VxWorks, LC_CTYPE locale encoding on other platforms; + * On Windows, "surrogateescape" error handler; + * "surrogateescape" error handler if the LC_CTYPE locale is "C" or "POSIX"; + * "surrogateescape" error handler if the LC_CTYPE locale has been coerced + (PEP 538); + * "strict" error handler. + + Supported error handlers: "strict", "surrogateescape" and + "surrogatepass". The surrogatepass error handler is only supported + if Py_DecodeLocale() and Py_EncodeLocale() use directly the UTF-8 codec; + it's only used on Windows. + + initfsencoding() updates the encoding to the Python codec name. + For example, "ANSI_X3.4-1968" is replaced with "ascii". + + On Windows, sys._enablelegacywindowsfsencoding() sets the + encoding/errors to mbcs/replace at runtime. + + + See Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors. + */ + wchar_t *filesystem_encoding; + wchar_t *filesystem_errors; + + wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ + int parse_argv; /* Parse argv command line arguments? */ + + /* Command line arguments (sys.argv). + + Set parse_argv to 1 to parse argv as Python command line arguments + and then strip Python arguments from argv. + + If argv is empty, an empty string is added to ensure that sys.argv + always exists and is never empty. */ + PyWideStringList argv; + + /* Program name: + + - If Py_SetProgramName() was called, use its value. + - On macOS, use PYTHONEXECUTABLE environment variable if set. + - If WITH_NEXT_FRAMEWORK macro is defined, use __PYVENV_LAUNCHER__ + environment variable is set. + - Use argv[0] if available and non-empty. + - Use "python" on Windows, or "python3 on other platforms. */ + wchar_t *program_name; + + PyWideStringList xoptions; /* Command line -X options */ + + /* Warnings options: lowest to highest priority. warnings.filters + is built in the reverse order (highest to lowest priority). */ + PyWideStringList warnoptions; + + /* If equal to zero, disable the import of the module site and the + site-dependent manipulations of sys.path that it entails. Also disable + these manipulations if site is explicitly imported later (call + site.main() if you want them to be triggered). + + Set to 0 by the -S command line option. If set to -1 (default), it is + set to !Py_NoSiteFlag. */ + int site_import; + + /* Bytes warnings: + + * If equal to 1, issue a warning when comparing bytes or bytearray with + str or bytes with int. + * If equal or greater to 2, issue an error. + + Incremented by the -b command line option. If set to -1 (default), inherit + Py_BytesWarningFlag value. */ + int bytes_warning; + + /* If greater than 0, enable inspect: when a script is passed as first + argument or the -c option is used, enter interactive mode after + executing the script or the command, even when sys.stdin does not appear + to be a terminal. + + Incremented by the -i command line option. Set to 1 if the PYTHONINSPECT + environment variable is non-empty. If set to -1 (default), inherit + Py_InspectFlag value. */ + int inspect; + + /* If greater than 0: enable the interactive mode (REPL). + + Incremented by the -i command line option. If set to -1 (default), + inherit Py_InteractiveFlag value. */ + int interactive; + + /* Optimization level. + + Incremented by the -O command line option. Set by the PYTHONOPTIMIZE + environment variable. If set to -1 (default), inherit Py_OptimizeFlag + value. */ + int optimization_level; + + /* If greater than 0, enable the debug mode: turn on parser debugging + output (for expert only, depending on compilation options). + + Incremented by the -d command line option. Set by the PYTHONDEBUG + environment variable. If set to -1 (default), inherit Py_DebugFlag + value. */ + int parser_debug; + + /* If equal to 0, Python won't try to write ``.pyc`` files on the + import of source modules. + + Set to 0 by the -B command line option and the PYTHONDONTWRITEBYTECODE + environment variable. If set to -1 (default), it is set to + !Py_DontWriteBytecodeFlag. */ + int write_bytecode; + + /* If greater than 0, enable the verbose mode: print a message each time a + module is initialized, showing the place (filename or built-in module) + from which it is loaded. + + If greater or equal to 2, print a message for each file that is checked + for when searching for a module. Also provides information on module + cleanup at exit. + + Incremented by the -v option. Set by the PYTHONVERBOSE environment + variable. If set to -1 (default), inherit Py_VerboseFlag value. */ + int verbose; + + /* If greater than 0, enable the quiet mode: Don't display the copyright + and version messages even in interactive mode. + + Incremented by the -q option. If set to -1 (default), inherit + Py_QuietFlag value. */ + int quiet; + + /* If greater than 0, don't add the user site-packages directory to + sys.path. + + Set to 0 by the -s and -I command line options , and the PYTHONNOUSERSITE + environment variable. If set to -1 (default), it is set to + !Py_NoUserSiteDirectory. */ + int user_site_directory; + + /* If non-zero, configure C standard steams (stdio, stdout, + stderr): + + - Set O_BINARY mode on Windows. + - If buffered_stdio is equal to zero, make streams unbuffered. + Otherwise, enable streams buffering if interactive is non-zero. */ + int configure_c_stdio; + + /* If equal to 0, enable unbuffered mode: force the stdout and stderr + streams to be unbuffered. + + Set to 0 by the -u option. Set by the PYTHONUNBUFFERED environment + variable. + If set to -1 (default), it is set to !Py_UnbufferedStdioFlag. */ + int buffered_stdio; + + /* Encoding of sys.stdin, sys.stdout and sys.stderr. + Value set from PYTHONIOENCODING environment variable and + Py_SetStandardStreamEncoding() function. + See also 'stdio_errors' attribute. */ + wchar_t *stdio_encoding; + + /* Error handler of sys.stdin and sys.stdout. + Value set from PYTHONIOENCODING environment variable and + Py_SetStandardStreamEncoding() function. + See also 'stdio_encoding' attribute. */ + wchar_t *stdio_errors; + +#ifdef MS_WINDOWS + /* If greater than zero, use io.FileIO instead of WindowsConsoleIO for sys + standard streams. + + Set to 1 if the PYTHONLEGACYWINDOWSSTDIO environment variable is set to + a non-empty string. If set to -1 (default), inherit + Py_LegacyWindowsStdioFlag value. + + See PEP 528 for more details. */ + int legacy_windows_stdio; +#endif + + /* Value of the --check-hash-based-pycs command line option: + + - "default" means the 'check_source' flag in hash-based pycs + determines invalidation + - "always" causes the interpreter to hash the source file for + invalidation regardless of value of 'check_source' bit + - "never" causes the interpreter to always assume hash-based pycs are + valid + + The default value is "default". + + See PEP 552 "Deterministic pycs" for more details. */ + wchar_t *check_hash_pycs_mode; + + /* --- Path configuration inputs ------------ */ + + /* If greater than 0, suppress _PyPathConfig_Calculate() warnings on Unix. + The parameter has no effect on Windows. + + If set to -1 (default), inherit !Py_FrozenFlag value. */ + int pathconfig_warnings; + + wchar_t *pythonpath_env; /* PYTHONPATH environment variable */ + wchar_t *home; /* PYTHONHOME environment variable, + see also Py_SetPythonHome(). */ + + /* --- Path configuration outputs ----------- */ + + int module_search_paths_set; /* If non-zero, use module_search_paths */ + PyWideStringList module_search_paths; /* sys.path paths. Computed if + module_search_paths_set is equal + to zero. */ + + wchar_t *executable; /* sys.executable */ + wchar_t *base_executable; /* sys._base_executable */ + wchar_t *prefix; /* sys.prefix */ + wchar_t *base_prefix; /* sys.base_prefix */ + wchar_t *exec_prefix; /* sys.exec_prefix */ + wchar_t *base_exec_prefix; /* sys.base_exec_prefix */ + + /* --- Parameter only used by Py_Main() ---------- */ + + /* Skip the first line of the source ('run_filename' parameter), allowing use of non-Unix forms of + "#!cmd". This is intended for a DOS specific hack only. + + Set by the -x command line option. */ + int skip_source_first_line; + + wchar_t *run_command; /* -c command line argument */ + wchar_t *run_module; /* -m command line argument */ + wchar_t *run_filename; /* Trailing command line argument without -c or -m */ + + /* --- Private fields ---------------------------- */ + + /* Install importlib? If set to 0, importlib is not initialized at all. + Needed by freeze_importlib. */ + int _install_importlib; + + /* If equal to 0, stop Python initialization before the "main" phase */ + int _init_main; +} PyConfig; + +PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); +PyAPI_FUNC(void) PyConfig_InitIsolatedConfig(PyConfig *config); +PyAPI_FUNC(void) PyConfig_Clear(PyConfig *); +PyAPI_FUNC(PyStatus) PyConfig_SetString( + PyConfig *config, + wchar_t **config_str, + const wchar_t *str); +PyAPI_FUNC(PyStatus) PyConfig_SetBytesString( + PyConfig *config, + wchar_t **config_str, + const char *str); +PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config); +PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv( + PyConfig *config, + Py_ssize_t argc, + char * const *argv); +PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config, + Py_ssize_t argc, + wchar_t * const *argv); +PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, + PyWideStringList *list, + Py_ssize_t length, wchar_t **items); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LIMITED_API */ +#endif /* !Py_PYCORECONFIG_H */ diff --git a/python/include/cpython/interpreteridobject.h b/python/include/cpython/interpreteridobject.h new file mode 100755 index 0000000..67ec587 --- /dev/null +++ b/python/include/cpython/interpreteridobject.h @@ -0,0 +1,19 @@ +#ifndef Py_CPYTHON_INTERPRETERIDOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Interpreter ID Object */ + +PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; + +PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t); +PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *); +PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/object.h b/python/include/cpython/object.h new file mode 100755 index 0000000..5a0ac4a --- /dev/null +++ b/python/include/cpython/object.h @@ -0,0 +1,470 @@ +#ifndef Py_CPYTHON_OBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* String Literals ****************************************/ +/* This structure helps managing static strings. The basic usage goes like this: + Instead of doing + + r = PyObject_CallMethod(o, "foo", "args", ...); + + do + + _Py_IDENTIFIER(foo); + ... + r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); + + PyId_foo is a static variable, either on block level or file level. On first + usage, the string "foo" is interned, and the structures are linked. On interpreter + shutdown, all strings are released (through _PyUnicode_ClearStaticStrings). + + Alternatively, _Py_static_string allows choosing the variable name. + _PyUnicode_FromId returns a borrowed reference to the interned string. + _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. +*/ +typedef struct _Py_Identifier { + struct _Py_Identifier *next; + const char* string; + PyObject *object; +} _Py_Identifier; + +#define _Py_static_string_init(value) { .next = NULL, .string = value, .object = NULL } +#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) +#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) + +/* buffer interface */ +typedef struct bufferinfo { + void *buf; + PyObject *obj; /* owned reference */ + Py_ssize_t len; + Py_ssize_t itemsize; /* This is Py_ssize_t so it can be + pointed to by strides in simple case.*/ + int readonly; + int ndim; + char *format; + Py_ssize_t *shape; + Py_ssize_t *strides; + Py_ssize_t *suboffsets; + void *internal; +} Py_buffer; + +typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); +typedef void (*releasebufferproc)(PyObject *, Py_buffer *); + +typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + +/* Maximum number of dimensions */ +#define PyBUF_MAX_NDIM 64 + +/* Flags for getting buffers */ +#define PyBUF_SIMPLE 0 +#define PyBUF_WRITABLE 0x0001 +/* we used to include an E, backwards compatible alias */ +#define PyBUF_WRITEABLE PyBUF_WRITABLE +#define PyBUF_FORMAT 0x0004 +#define PyBUF_ND 0x0008 +#define PyBUF_STRIDES (0x0010 | PyBUF_ND) +#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) +#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) +#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) +#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) + +#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) +#define PyBUF_CONTIG_RO (PyBUF_ND) + +#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) +#define PyBUF_STRIDED_RO (PyBUF_STRIDES) + +#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) + +#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) + + +#define PyBUF_READ 0x100 +#define PyBUF_WRITE 0x200 +/* End buffer interface */ + + +typedef struct { + /* Number implementations must check *both* + arguments for proper type and implement the necessary conversions + in the slot functions themselves. */ + + binaryfunc nb_add; + binaryfunc nb_subtract; + binaryfunc nb_multiply; + binaryfunc nb_remainder; + binaryfunc nb_divmod; + ternaryfunc nb_power; + unaryfunc nb_negative; + unaryfunc nb_positive; + unaryfunc nb_absolute; + inquiry nb_bool; + unaryfunc nb_invert; + binaryfunc nb_lshift; + binaryfunc nb_rshift; + binaryfunc nb_and; + binaryfunc nb_xor; + binaryfunc nb_or; + unaryfunc nb_int; + void *nb_reserved; /* the slot formerly known as nb_long */ + unaryfunc nb_float; + + binaryfunc nb_inplace_add; + binaryfunc nb_inplace_subtract; + binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_remainder; + ternaryfunc nb_inplace_power; + binaryfunc nb_inplace_lshift; + binaryfunc nb_inplace_rshift; + binaryfunc nb_inplace_and; + binaryfunc nb_inplace_xor; + binaryfunc nb_inplace_or; + + binaryfunc nb_floor_divide; + binaryfunc nb_true_divide; + binaryfunc nb_inplace_floor_divide; + binaryfunc nb_inplace_true_divide; + + unaryfunc nb_index; + + binaryfunc nb_matrix_multiply; + binaryfunc nb_inplace_matrix_multiply; +} PyNumberMethods; + +typedef struct { + lenfunc sq_length; + binaryfunc sq_concat; + ssizeargfunc sq_repeat; + ssizeargfunc sq_item; + void *was_sq_slice; + ssizeobjargproc sq_ass_item; + void *was_sq_ass_slice; + objobjproc sq_contains; + + binaryfunc sq_inplace_concat; + ssizeargfunc sq_inplace_repeat; +} PySequenceMethods; + +typedef struct { + lenfunc mp_length; + binaryfunc mp_subscript; + objobjargproc mp_ass_subscript; +} PyMappingMethods; + +typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; +} PyAsyncMethods; + +typedef struct { + getbufferproc bf_getbuffer; + releasebufferproc bf_releasebuffer; +} PyBufferProcs; + +/* Allow printfunc in the tp_vectorcall_offset slot for + * backwards-compatibility */ +typedef Py_ssize_t printfunc; + +typedef struct _typeobject { + PyObject_VAR_HEAD + const char *tp_name; /* For printing, in format "." */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ + + /* Methods to implement standard operations */ + + destructor tp_dealloc; + Py_ssize_t tp_vectorcall_offset; + getattrfunc tp_getattr; + setattrfunc tp_setattr; + PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) + or tp_reserved (Python 3) */ + reprfunc tp_repr; + + /* Method suites for standard classes */ + + PyNumberMethods *tp_as_number; + PySequenceMethods *tp_as_sequence; + PyMappingMethods *tp_as_mapping; + + /* More standard operations (here for binary compatibility) */ + + hashfunc tp_hash; + ternaryfunc tp_call; + reprfunc tp_str; + getattrofunc tp_getattro; + setattrofunc tp_setattro; + + /* Functions to access object as input/output buffer */ + PyBufferProcs *tp_as_buffer; + + /* Flags to define presence of optional/expanded features */ + unsigned long tp_flags; + + const char *tp_doc; /* Documentation string */ + + /* Assigned meaning in release 2.0 */ + /* call function for all accessible objects */ + traverseproc tp_traverse; + + /* delete references to contained objects */ + inquiry tp_clear; + + /* Assigned meaning in release 2.1 */ + /* rich comparisons */ + richcmpfunc tp_richcompare; + + /* weak reference enabler */ + Py_ssize_t tp_weaklistoffset; + + /* Iterators */ + getiterfunc tp_iter; + iternextfunc tp_iternext; + + /* Attribute descriptor and subclassing stuff */ + struct PyMethodDef *tp_methods; + struct PyMemberDef *tp_members; + struct PyGetSetDef *tp_getset; + struct _typeobject *tp_base; + PyObject *tp_dict; + descrgetfunc tp_descr_get; + descrsetfunc tp_descr_set; + Py_ssize_t tp_dictoffset; + initproc tp_init; + allocfunc tp_alloc; + newfunc tp_new; + freefunc tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ + PyObject *tp_bases; + PyObject *tp_mro; /* method resolution order */ + PyObject *tp_cache; + PyObject *tp_subclasses; + PyObject *tp_weaklist; + destructor tp_del; + + /* Type attribute cache version tag. Added in version 2.6 */ + unsigned int tp_version_tag; + + destructor tp_finalize; + vectorcallfunc tp_vectorcall; + + /* bpo-37250: kept for backwards compatibility in CPython 3.8 only */ + Py_DEPRECATED(3.8) int (*tp_print)(PyObject *, FILE *, int); + +#ifdef COUNT_ALLOCS + /* these must be last and never explicitly initialized */ + Py_ssize_t tp_allocs; + Py_ssize_t tp_frees; + Py_ssize_t tp_maxalloc; + struct _typeobject *tp_prev; + struct _typeobject *tp_next; +#endif +} PyTypeObject; + +/* The *real* layout of a type object when allocated on the heap */ +typedef struct _heaptypeobject { + /* Note: there's a dependency on the order of these members + in slotptr() in typeobject.c . */ + PyTypeObject ht_type; + PyAsyncMethods as_async; + PyNumberMethods as_number; + PyMappingMethods as_mapping; + PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, + so that the mapping wins when both + the mapping and the sequence define + a given operator (e.g. __getitem__). + see add_operators() in typeobject.c . */ + PyBufferProcs as_buffer; + PyObject *ht_name, *ht_slots, *ht_qualname; + struct _dictkeysobject *ht_cached_keys; + /* here are optional user slots, followed by the members. */ +} PyHeapTypeObject; + +/* access macro to the members which are floating "behind" the object */ +#define PyHeapType_GET_MEMBERS(etype) \ + ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) + +PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); +PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); +PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *); +PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); +PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); + +struct _Py_Identifier; +PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); +PyAPI_FUNC(void) _Py_BreakPoint(void); +PyAPI_FUNC(void) _PyObject_Dump(PyObject *); +PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); + +PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); +PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *); +PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *); +/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which + don't raise AttributeError. + + Return 1 and set *result != NULL if an attribute is found. + Return 0 and set *result == NULL if an attribute is not found; + an AttributeError is silenced. + Return -1 and set *result == NULL if an error other than AttributeError + is raised. +*/ +PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **); +PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, struct _Py_Identifier *, PyObject **); +PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); +PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); +PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); + +/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes + dict as the last parameter. */ +PyAPI_FUNC(PyObject *) +_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int); +PyAPI_FUNC(int) +_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, + PyObject *, PyObject *); + +#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) + +static inline void _Py_Dealloc_inline(PyObject *op) +{ + destructor dealloc = Py_TYPE(op)->tp_dealloc; +#ifdef Py_TRACE_REFS + _Py_ForgetReference(op); +#else + _Py_INC_TPFREES(op); +#endif + (*dealloc)(op); +} +#define _Py_Dealloc(op) _Py_Dealloc_inline(op) + + +/* Safely decref `op` and set `op` to `op2`. + * + * As in case of Py_CLEAR "the obvious" code can be deadly: + * + * Py_DECREF(op); + * op = op2; + * + * The safe way is: + * + * Py_SETREF(op, op2); + * + * That arranges to set `op` to `op2` _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of + * Py_DECREF. + */ + +#define Py_SETREF(op, op2) \ + do { \ + PyObject *_py_tmp = _PyObject_CAST(op); \ + (op) = (op2); \ + Py_DECREF(_py_tmp); \ + } while (0) + +#define Py_XSETREF(op, op2) \ + do { \ + PyObject *_py_tmp = _PyObject_CAST(op); \ + (op) = (op2); \ + Py_XDECREF(_py_tmp); \ + } while (0) + + +PyAPI_DATA(PyTypeObject) _PyNone_Type; +PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type; + +/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. + * Defined in object.c. + */ +PyAPI_DATA(int) _Py_SwappedOp[]; + +/* This is the old private API, invoked by the macros before 3.2.4. + Kept for binary compatibility of extensions using the stable ABI. */ +PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*); +PyAPI_FUNC(void) _PyTrash_destroy_chain(void); + +PyAPI_FUNC(void) +_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, + size_t sizeof_block); +PyAPI_FUNC(void) +_PyObject_DebugTypeStats(FILE *out); + +/* Define a pair of assertion macros: + _PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT(). + + These work like the regular C assert(), in that they will abort the + process with a message on stderr if the given condition fails to hold, + but compile away to nothing if NDEBUG is defined. + + However, before aborting, Python will also try to call _PyObject_Dump() on + the given object. This may be of use when investigating bugs in which a + particular object is corrupt (e.g. buggy a tp_visit method in an extension + module breaking the garbage collector), to help locate the broken objects. + + The WITH_MSG variant allows you to supply an additional message that Python + will attempt to print to stderr, after the object dump. */ +#ifdef NDEBUG + /* No debugging: compile away the assertions: */ +# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ + ((void)0) +#else + /* With debugging: generate checks: */ +# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ + ((expr) \ + ? (void)(0) \ + : _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \ + (msg), (filename), (lineno), (func))) +#endif + +#define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ + _PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__) +#define _PyObject_ASSERT(obj, expr) \ + _PyObject_ASSERT_WITH_MSG(obj, expr, NULL) + +#define _PyObject_ASSERT_FAILED_MSG(obj, msg) \ + _PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__) + +/* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined, + to avoid causing compiler/linker errors when building extensions without + NDEBUG against a Python built with NDEBUG defined. + + msg, expr and function can be NULL. */ +PyAPI_FUNC(void) _PyObject_AssertFailed( + PyObject *obj, + const char *expr, + const char *msg, + const char *file, + int line, + const char *function); + +/* Check if an object is consistent. For example, ensure that the reference + counter is greater than or equal to 1, and ensure that ob_type is not NULL. + + Call _PyObject_AssertFailed() if the object is inconsistent. + + If check_content is zero, only check header fields: reduce the overhead. + + The function always return 1. The return value is just here to be able to + write: + + assert(_PyObject_CheckConsistency(obj, 1)); */ +PyAPI_FUNC(int) _PyObject_CheckConsistency( + PyObject *op, + int check_content); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/objimpl.h b/python/include/cpython/objimpl.h new file mode 100755 index 0000000..f121922 --- /dev/null +++ b/python/include/cpython/objimpl.h @@ -0,0 +1,113 @@ +#ifndef Py_CPYTHON_OBJIMPL_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* This function returns the number of allocated memory blocks, regardless of size */ +PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); + +/* Macros */ +#ifdef WITH_PYMALLOC +PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); +#endif + + +typedef struct { + /* user context passed as the first argument to the 2 functions */ + void *ctx; + + /* allocate an arena of size bytes */ + void* (*alloc) (void *ctx, size_t size); + + /* free an arena */ + void (*free) (void *ctx, void *ptr, size_t size); +} PyObjectArenaAllocator; + +/* Get the arena allocator. */ +PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator); + +/* Set the arena allocator. */ +PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator); + + +PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(void); +PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void); + + +/* Test if an object has a GC head */ +#define PyObject_IS_GC(o) \ + (PyType_IS_GC(Py_TYPE(o)) \ + && (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o))) + +/* GC information is stored BEFORE the object structure. */ +typedef struct { + // Pointer to next object in the list. + // 0 means the object is not tracked + uintptr_t _gc_next; + + // Pointer to previous object in the list. + // Lowest two bits are used for flags documented later. + uintptr_t _gc_prev; +} PyGC_Head; + +#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1) + +/* True if the object is currently tracked by the GC. */ +#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0) + +/* True if the object may be tracked by the GC in the future, or already is. + This can be useful to implement some optimizations. */ +#define _PyObject_GC_MAY_BE_TRACKED(obj) \ + (PyObject_IS_GC(obj) && \ + (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) + + +/* Bit flags for _gc_prev */ +/* Bit 0 is set when tp_finalize is called */ +#define _PyGC_PREV_MASK_FINALIZED (1) +/* Bit 1 is set when the object is in generation which is GCed currently. */ +#define _PyGC_PREV_MASK_COLLECTING (2) +/* The (N-2) most significant bits contain the real address. */ +#define _PyGC_PREV_SHIFT (2) +#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT) + +// Lowest bit of _gc_next is used for flags only in GC. +// But it is always 0 for normal code. +#define _PyGCHead_NEXT(g) ((PyGC_Head*)(g)->_gc_next) +#define _PyGCHead_SET_NEXT(g, p) ((g)->_gc_next = (uintptr_t)(p)) + +// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags. +#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK)) +#define _PyGCHead_SET_PREV(g, p) do { \ + assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \ + (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \ + | ((uintptr_t)(p)); \ + } while (0) + +#define _PyGCHead_FINALIZED(g) \ + (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0) +#define _PyGCHead_SET_FINALIZED(g) \ + ((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED) + +#define _PyGC_FINALIZED(o) \ + _PyGCHead_FINALIZED(_Py_AS_GC(o)) +#define _PyGC_SET_FINALIZED(o) \ + _PyGCHead_SET_FINALIZED(_Py_AS_GC(o)) + + +PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size); +PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); + + +/* Test if a type supports weak references */ +#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) + +#define PyObject_GET_WEAKREFS_LISTPTR(o) \ + ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset)) + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/pyerrors.h b/python/include/cpython/pyerrors.h new file mode 100755 index 0000000..418f48a --- /dev/null +++ b/python/include/cpython/pyerrors.h @@ -0,0 +1,188 @@ +#ifndef Py_CPYTHON_ERRORS_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error objects */ + +/* PyException_HEAD defines the initial segment of every exception class. */ +#define PyException_HEAD PyObject_HEAD PyObject *dict;\ + PyObject *args; PyObject *traceback;\ + PyObject *context; PyObject *cause;\ + char suppress_context; + +typedef struct { + PyException_HEAD +} PyBaseExceptionObject; + +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *filename; + PyObject *lineno; + PyObject *offset; + PyObject *text; + PyObject *print_file_and_line; +} PySyntaxErrorObject; + +typedef struct { + PyException_HEAD + PyObject *msg; + PyObject *name; + PyObject *path; +} PyImportErrorObject; + +typedef struct { + PyException_HEAD + PyObject *encoding; + PyObject *object; + Py_ssize_t start; + Py_ssize_t end; + PyObject *reason; +} PyUnicodeErrorObject; + +typedef struct { + PyException_HEAD + PyObject *code; +} PySystemExitObject; + +typedef struct { + PyException_HEAD + PyObject *myerrno; + PyObject *strerror; + PyObject *filename; + PyObject *filename2; +#ifdef MS_WINDOWS + PyObject *winerror; +#endif + Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */ +} PyOSErrorObject; + +typedef struct { + PyException_HEAD + PyObject *value; +} PyStopIterationObject; + +/* Compatibility typedefs */ +typedef PyOSErrorObject PyEnvironmentErrorObject; +#ifdef MS_WINDOWS +typedef PyOSErrorObject PyWindowsErrorObject; +#endif + +/* Error handling definitions */ + +PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); +_PyErr_StackItem *_PyErr_GetTopmostException(PyThreadState *tstate); + +/* Context manipulation (PEP 3134) */ + +PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); + +/* */ + +#define PyExceptionClass_Name(x) (((PyTypeObject*)(x))->tp_name) + +/* Convenience functions */ + +#ifdef MS_WINDOWS +Py_DEPRECATED(3.3) +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename( + PyObject *, const Py_UNICODE *); +#endif /* MS_WINDOWS */ + +/* Like PyErr_Format(), but saves current exception as __context__ and + __cause__. + */ +PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause( + PyObject *exception, + const char *format, /* ASCII-encoded string */ + ... + ); + +#ifdef MS_WINDOWS +/* XXX redeclare to use WSTRING */ +Py_DEPRECATED(3.3) +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( + int, const Py_UNICODE *); +Py_DEPRECATED(3.3) +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename( + PyObject *,int, const Py_UNICODE *); +#endif + +/* In exceptions.c */ + +/* Helper that attempts to replace the current exception with one of the + * same type but with a prefix added to the exception text. The resulting + * exception description looks like: + * + * prefix (exc_type: original_exc_str) + * + * Only some exceptions can be safely replaced. If the function determines + * it isn't safe to perform the replacement, it will leave the original + * unmodified exception in place. + * + * Returns a borrowed reference to the new exception (if any), NULL if the + * existing exception was left in place. + */ +PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause( + const char *prefix_format, /* ASCII-encoded string */ + ... + ); + +/* In signalmodule.c */ + +int PySignal_SetWakeupFd(int fd); +PyAPI_FUNC(int) _PyErr_CheckSignals(void); + +/* Support for adding program text to SyntaxErrors */ + +PyAPI_FUNC(void) PyErr_SyntaxLocationObject( + PyObject *filename, + int lineno, + int col_offset); + +PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( + PyObject *filename, + int lineno); + +/* Create a UnicodeEncodeError object. + * + * TODO: This API will be removed in Python 3.11. + */ +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( + const char *encoding, /* UTF-8 encoded string */ + const Py_UNICODE *object, + Py_ssize_t length, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ); + +/* Create a UnicodeTranslateError object. + * + * TODO: This API will be removed in Python 3.11. + */ +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( + const Py_UNICODE *object, + Py_ssize_t length, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( + PyObject *object, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ); + +PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg( + const char *err_msg, + PyObject *obj); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/pylifecycle.h b/python/include/cpython/pylifecycle.h new file mode 100755 index 0000000..2f3a0db --- /dev/null +++ b/python/include/cpython/pylifecycle.h @@ -0,0 +1,78 @@ +#ifndef Py_CPYTHON_PYLIFECYCLE_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Only used by applications that embed the interpreter and need to + * override the standard encoding determination mechanism + */ +PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, + const char *errors); + +/* PEP 432 Multi-phase initialization API (Private while provisional!) */ + +PyAPI_FUNC(PyStatus) Py_PreInitialize( + const PyPreConfig *src_config); +PyAPI_FUNC(PyStatus) Py_PreInitializeFromBytesArgs( + const PyPreConfig *src_config, + Py_ssize_t argc, + char **argv); +PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs( + const PyPreConfig *src_config, + Py_ssize_t argc, + wchar_t **argv); + +PyAPI_FUNC(int) _Py_IsCoreInitialized(void); + + +/* Initialization and finalization */ + +PyAPI_FUNC(PyStatus) Py_InitializeFromConfig( + const PyConfig *config); +PyAPI_FUNC(PyStatus) _Py_InitializeFromArgs( + const PyConfig *config, + Py_ssize_t argc, + char * const *argv); +PyAPI_FUNC(PyStatus) _Py_InitializeFromWideArgs( + const PyConfig *config, + Py_ssize_t argc, + wchar_t * const *argv); +PyAPI_FUNC(PyStatus) _Py_InitializeMain(void); + +PyAPI_FUNC(int) Py_RunMain(void); + + +PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err); + +/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level + * exit functions. + */ +PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(PyObject *), PyObject *); + +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ +PyAPI_FUNC(void) _Py_RestoreSignals(void); + +PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); + +PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *); + +PyAPI_FUNC(const char *) _Py_gitidentifier(void); +PyAPI_FUNC(const char *) _Py_gitversion(void); + +PyAPI_FUNC(int) _Py_IsFinalizing(void); + +/* Random */ +PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size); +PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size); + +/* Legacy locale support */ +PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn); +PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); +PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/pymem.h b/python/include/cpython/pymem.h new file mode 100755 index 0000000..79f063b --- /dev/null +++ b/python/include/cpython/pymem.h @@ -0,0 +1,108 @@ +#ifndef Py_CPYTHON_PYMEM_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); +PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyMem_RawFree(void *ptr); + +/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ +PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void); + +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); + +/* strdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); + +/* strdup() using PyMem_Malloc() */ +PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); + +/* wcsdup() using PyMem_RawMalloc() */ +PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); + + +typedef enum { + /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ + PYMEM_DOMAIN_RAW, + + /* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */ + PYMEM_DOMAIN_MEM, + + /* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */ + PYMEM_DOMAIN_OBJ +} PyMemAllocatorDomain; + +typedef enum { + PYMEM_ALLOCATOR_NOT_SET = 0, + PYMEM_ALLOCATOR_DEFAULT = 1, + PYMEM_ALLOCATOR_DEBUG = 2, + PYMEM_ALLOCATOR_MALLOC = 3, + PYMEM_ALLOCATOR_MALLOC_DEBUG = 4, +#ifdef WITH_PYMALLOC + PYMEM_ALLOCATOR_PYMALLOC = 5, + PYMEM_ALLOCATOR_PYMALLOC_DEBUG = 6, +#endif +} PyMemAllocatorName; + + +typedef struct { + /* user context passed as the first argument to the 4 functions */ + void *ctx; + + /* allocate a memory block */ + void* (*malloc) (void *ctx, size_t size); + + /* allocate a memory block initialized by zeros */ + void* (*calloc) (void *ctx, size_t nelem, size_t elsize); + + /* allocate or resize a memory block */ + void* (*realloc) (void *ctx, void *ptr, size_t new_size); + + /* release a memory block */ + void (*free) (void *ctx, void *ptr); +} PyMemAllocatorEx; + +/* Get the memory block allocator of the specified domain. */ +PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Set the memory block allocator of the specified domain. + + The new allocator must return a distinct non-NULL pointer when requesting + zero bytes. + + For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL + is not held when the allocator is called. + + If the new allocator is not a hook (don't call the previous allocator), the + PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks + on top on the new allocator. */ +PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, + PyMemAllocatorEx *allocator); + +/* Setup hooks to detect bugs in the following Python memory allocator + functions: + + - PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree() + - PyMem_Malloc(), PyMem_Realloc(), PyMem_Free() + - PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() + + Newly allocated memory is filled with the byte 0xCB, freed memory is filled + with the byte 0xDB. Additional checks: + + - detect API violations, ex: PyObject_Free() called on a buffer allocated + by PyMem_Malloc() + - detect write before the start of the buffer (buffer underflow) + - detect write after the end of the buffer (buffer overflow) + + The function does nothing if Python is not compiled is debug mode. */ +PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/pystate.h b/python/include/cpython/pystate.h new file mode 100755 index 0000000..e22b053 --- /dev/null +++ b/python/include/cpython/pystate.h @@ -0,0 +1,252 @@ +#ifndef Py_CPYTHON_PYSTATE_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cpython/initconfig.h" + +PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); +PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); + +PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); + +/* State unique per thread */ + +/* Py_tracefunc return -1 when raising an exception, or 0 for success. */ +typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); + +/* The following values are used for 'what' for tracefunc functions + * + * To add a new kind of trace event, also update "trace_init" in + * Python/sysmodule.c to define the Python level event name + */ +#define PyTrace_CALL 0 +#define PyTrace_EXCEPTION 1 +#define PyTrace_LINE 2 +#define PyTrace_RETURN 3 +#define PyTrace_C_CALL 4 +#define PyTrace_C_EXCEPTION 5 +#define PyTrace_C_RETURN 6 +#define PyTrace_OPCODE 7 + + +typedef struct _err_stackitem { + /* This struct represents an entry on the exception stack, which is a + * per-coroutine state. (Coroutine in the computer science sense, + * including the thread and generators). + * This ensures that the exception state is not impacted by "yields" + * from an except handler. + */ + PyObject *exc_type, *exc_value, *exc_traceback; + + struct _err_stackitem *previous_item; + +} _PyErr_StackItem; + + +// The PyThreadState typedef is in Include/pystate.h. +struct _ts { + /* See Python/ceval.c for comments explaining most fields */ + + struct _ts *prev; + struct _ts *next; + PyInterpreterState *interp; + + /* Borrowed reference to the current frame (it can be NULL) */ + struct _frame *frame; + int recursion_depth; + char overflowed; /* The stack has overflowed. Allow 50 more calls + to handle the runtime error. */ + char recursion_critical; /* The current calls must not cause + a stack overflow. */ + int stackcheck_counter; + + /* 'tracing' keeps track of the execution depth when tracing/profiling. + This is to prevent the actual trace/profile code from being recorded in + the trace/profile. */ + int tracing; + int use_tracing; + + Py_tracefunc c_profilefunc; + Py_tracefunc c_tracefunc; + PyObject *c_profileobj; + PyObject *c_traceobj; + + /* The exception currently being raised */ + PyObject *curexc_type; + PyObject *curexc_value; + PyObject *curexc_traceback; + + /* The exception currently being handled, if no coroutines/generators + * are present. Always last element on the stack referred to be exc_info. + */ + _PyErr_StackItem exc_state; + + /* Pointer to the top of the stack of the exceptions currently + * being handled */ + _PyErr_StackItem *exc_info; + + PyObject *dict; /* Stores per-thread state */ + + int gilstate_counter; + + PyObject *async_exc; /* Asynchronous exception to raise */ + unsigned long thread_id; /* Thread id where this tstate was created */ + + int trash_delete_nesting; + PyObject *trash_delete_later; + + /* Called when a thread state is deleted normally, but not when it + * is destroyed after fork(). + * Pain: to prevent rare but fatal shutdown errors (issue 18808), + * Thread.join() must wait for the join'ed thread's tstate to be unlinked + * from the tstate chain. That happens at the end of a thread's life, + * in pystate.c. + * The obvious way doesn't quite work: create a lock which the tstate + * unlinking code releases, and have Thread.join() wait to acquire that + * lock. The problem is that we _are_ at the end of the thread's life: + * if the thread holds the last reference to the lock, decref'ing the + * lock will delete the lock, and that may trigger arbitrary Python code + * if there's a weakref, with a callback, to the lock. But by this time + * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest + * of C code can be allowed to run (in particular it must not be possible to + * release the GIL). + * So instead of holding the lock directly, the tstate holds a weakref to + * the lock: that's the value of on_delete_data below. Decref'ing a + * weakref is harmless. + * on_delete points to _threadmodule.c's static release_sentinel() function. + * After the tstate is unlinked, release_sentinel is called with the + * weakref-to-lock (on_delete_data) argument, and release_sentinel releases + * the indirectly held lock. + */ + void (*on_delete)(void *); + void *on_delete_data; + + int coroutine_origin_tracking_depth; + + PyObject *async_gen_firstiter; + PyObject *async_gen_finalizer; + + PyObject *context; + uint64_t context_ver; + + /* Unique thread state id. */ + uint64_t id; + + /* XXX signal handlers should also be here */ + +}; + +/* Get the current interpreter state. + + Issue a fatal error if there no current Python thread state or no current + interpreter. It cannot return NULL. + + The caller must hold the GIL.*/ +PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); + +PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); +PyAPI_FUNC(void) _PyState_ClearModules(void); +PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); + +/* Similar to PyThreadState_Get(), but don't issue a fatal error + * if it is NULL. */ +PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); + +/* PyGILState */ + +/* Helper/diagnostic function - return 1 if the current thread + currently holds the GIL, 0 otherwise. + + The function returns 1 if _PyGILState_check_enabled is non-zero. */ +PyAPI_FUNC(int) PyGILState_Check(void); + +/* Get the single PyInterpreterState used by this process' GILState + implementation. + + This function doesn't check for error. Return NULL before _PyGILState_Init() + is called and after _PyGILState_Fini() is called. + + See also _PyInterpreterState_Get() and _PyInterpreterState_GET_UNSAFE(). */ +PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); + +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); + +/* Routines for advanced debuggers, requested by David Beazley. + Don't use unless you know what you are doing! */ +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); + +typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); + +/* cross-interpreter data */ + +struct _xid; + +// _PyCrossInterpreterData is similar to Py_buffer as an effectively +// opaque struct that holds data outside the object machinery. This +// is necessary to pass safely between interpreters in the same process. +typedef struct _xid { + // data is the cross-interpreter-safe derivation of a Python object + // (see _PyObject_GetCrossInterpreterData). It will be NULL if the + // new_object func (below) encodes the data. + void *data; + // obj is the Python object from which the data was derived. This + // is non-NULL only if the data remains bound to the object in some + // way, such that the object must be "released" (via a decref) when + // the data is released. In that case the code that sets the field, + // likely a registered "crossinterpdatafunc", is responsible for + // ensuring it owns the reference (i.e. incref). + PyObject *obj; + // interp is the ID of the owning interpreter of the original + // object. It corresponds to the active interpreter when + // _PyObject_GetCrossInterpreterData() was called. This should only + // be set by the cross-interpreter machinery. + // + // We use the ID rather than the PyInterpreterState to avoid issues + // with deleted interpreters. Note that IDs are never re-used, so + // each one will always correspond to a specific interpreter + // (whether still alive or not). + int64_t interp; + // new_object is a function that returns a new object in the current + // interpreter given the data. The resulting object (a new + // reference) will be equivalent to the original object. This field + // is required. + PyObject *(*new_object)(struct _xid *); + // free is called when the data is released. If it is NULL then + // nothing will be done to free the data. For some types this is + // okay (e.g. bytes) and for those types this field should be set + // to NULL. However, for most the data was allocated just for + // cross-interpreter use, so it must be freed when + // _PyCrossInterpreterData_Release is called or the memory will + // leak. In that case, at the very least this field should be set + // to PyMem_RawFree (the default if not explicitly set to NULL). + // The call will happen with the original interpreter activated. + void (*free)(void *); +} _PyCrossInterpreterData; + +PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); +PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); +PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); + +PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); + +/* cross-interpreter data registry */ + +typedef int (*crossinterpdatafunc)(PyObject *, struct _xid *); + +PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); +PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/sysmodule.h b/python/include/cpython/sysmodule.h new file mode 100755 index 0000000..72d8ffe --- /dev/null +++ b/python/include/cpython/sysmodule.h @@ -0,0 +1,21 @@ +#ifndef Py_CPYTHON_SYSMODULE_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); +PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); + +PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); + +typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); + +PyAPI_FUNC(int) PySys_Audit(const char*, const char *, ...); +PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/traceback.h b/python/include/cpython/traceback.h new file mode 100755 index 0000000..746097d --- /dev/null +++ b/python/include/cpython/traceback.h @@ -0,0 +1,22 @@ +#ifndef Py_CPYTHON_TRACEBACK_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _traceback { + PyObject_HEAD + struct _traceback *tb_next; + struct _frame *tb_frame; + int tb_lasti; + int tb_lineno; +} PyTracebackObject; + +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); +PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/tupleobject.h b/python/include/cpython/tupleobject.h new file mode 100755 index 0000000..1565f2a --- /dev/null +++ b/python/include/cpython/tupleobject.h @@ -0,0 +1,36 @@ +#ifndef Py_CPYTHON_TUPLEOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_VAR_HEAD + /* ob_item contains space for 'ob_size' elements. + Items must normally not be NULL, except during construction when + the tuple is not yet visible outside the function that builds it. */ + PyObject *ob_item[1]; +} PyTupleObject; + +PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); + +/* Macros trading safety for speed */ + +/* Cast argument to PyTupleObject* type. */ +#define _PyTuple_CAST(op) (assert(PyTuple_Check(op)), (PyTupleObject *)(op)) + +#define PyTuple_GET_SIZE(op) Py_SIZE(_PyTuple_CAST(op)) + +#define PyTuple_GET_ITEM(op, i) (_PyTuple_CAST(op)->ob_item[i]) + +/* Macro, *only* to be used to fill in brand new tuples */ +#define PyTuple_SET_ITEM(op, i, v) (_PyTuple_CAST(op)->ob_item[i] = v) + +PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/cpython/unicodeobject.h b/python/include/cpython/unicodeobject.h new file mode 100755 index 0000000..87ff31d --- /dev/null +++ b/python/include/cpython/unicodeobject.h @@ -0,0 +1,1239 @@ +#ifndef Py_CPYTHON_UNICODEOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Py_UNICODE was the native Unicode storage format (code unit) used by + Python and represents a single Unicode element in the Unicode type. + With PEP 393, Py_UNICODE is deprecated and replaced with a + typedef to wchar_t. */ +#define PY_UNICODE_TYPE wchar_t +/* Py_DEPRECATED(3.3) */ typedef wchar_t Py_UNICODE; + +/* --- Internal Unicode Operations ---------------------------------------- */ + +/* Since splitting on whitespace is an important use case, and + whitespace in most situations is solely ASCII whitespace, we + optimize for the common case by using a quick look-up table + _Py_ascii_whitespace (see below) with an inlined check. + + */ +#define Py_UNICODE_ISSPACE(ch) \ + ((Py_UCS4)(ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) +#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +#define Py_UNICODE_ISALNUM(ch) \ + (Py_UNICODE_ISALPHA(ch) || \ + Py_UNICODE_ISDECIMAL(ch) || \ + Py_UNICODE_ISDIGIT(ch) || \ + Py_UNICODE_ISNUMERIC(ch)) + +#define Py_UNICODE_COPY(target, source, length) \ + memcpy((target), (source), (length)*sizeof(Py_UNICODE)) + +#define Py_UNICODE_FILL(target, value, length) \ + do {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\ + for (i_ = 0; i_ < (length); i_++) t_[i_] = v_;\ + } while (0) + +/* macros to work with surrogates */ +#define Py_UNICODE_IS_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDFFF) +#define Py_UNICODE_IS_HIGH_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDBFF) +#define Py_UNICODE_IS_LOW_SURROGATE(ch) (0xDC00 <= (ch) && (ch) <= 0xDFFF) +/* Join two surrogate characters and return a single Py_UCS4 value. */ +#define Py_UNICODE_JOIN_SURROGATES(high, low) \ + (((((Py_UCS4)(high) & 0x03FF) << 10) | \ + ((Py_UCS4)(low) & 0x03FF)) + 0x10000) +/* high surrogate = top 10 bits added to D800 */ +#define Py_UNICODE_HIGH_SURROGATE(ch) (0xD800 - (0x10000 >> 10) + ((ch) >> 10)) +/* low surrogate = bottom 10 bits added to DC00 */ +#define Py_UNICODE_LOW_SURROGATE(ch) (0xDC00 + ((ch) & 0x3FF)) + +/* Check if substring matches at given offset. The offset must be + valid, and the substring must not be empty. */ + +#define Py_UNICODE_MATCH(string, offset, substring) \ + ((*((string)->wstr + (offset)) == *((substring)->wstr)) && \ + ((*((string)->wstr + (offset) + (substring)->wstr_length-1) == *((substring)->wstr + (substring)->wstr_length-1))) && \ + !memcmp((string)->wstr + (offset), (substring)->wstr, (substring)->wstr_length*sizeof(Py_UNICODE))) + +/* --- Unicode Type ------------------------------------------------------- */ + +/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject + structure. state.ascii and state.compact are set, and the data + immediately follow the structure. utf8_length and wstr_length can be found + in the length field; the utf8 pointer is equal to the data pointer. */ +typedef struct { + /* There are 4 forms of Unicode strings: + + - compact ascii: + + * structure = PyASCIIObject + * test: PyUnicode_IS_COMPACT_ASCII(op) + * kind = PyUnicode_1BYTE_KIND + * compact = 1 + * ascii = 1 + * ready = 1 + * (length is the length of the utf8 and wstr strings) + * (data starts just after the structure) + * (since ASCII is decoded from UTF-8, the utf8 string are the data) + + - compact: + + * structure = PyCompactUnicodeObject + * test: PyUnicode_IS_COMPACT(op) && !PyUnicode_IS_ASCII(op) + * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or + PyUnicode_4BYTE_KIND + * compact = 1 + * ready = 1 + * ascii = 0 + * utf8 is not shared with data + * utf8_length = 0 if utf8 is NULL + * wstr is shared with data and wstr_length=length + if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 + or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_t)=4 + * wstr_length = 0 if wstr is NULL + * (data starts just after the structure) + + - legacy string, not ready: + + * structure = PyUnicodeObject + * test: kind == PyUnicode_WCHAR_KIND + * length = 0 (use wstr_length) + * hash = -1 + * kind = PyUnicode_WCHAR_KIND + * compact = 0 + * ascii = 0 + * ready = 0 + * interned = SSTATE_NOT_INTERNED + * wstr is not NULL + * data.any is NULL + * utf8 is NULL + * utf8_length = 0 + + - legacy string, ready: + + * structure = PyUnicodeObject structure + * test: !PyUnicode_IS_COMPACT(op) && kind != PyUnicode_WCHAR_KIND + * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or + PyUnicode_4BYTE_KIND + * compact = 0 + * ready = 1 + * data.any is not NULL + * utf8 is shared and utf8_length = length with data.any if ascii = 1 + * utf8_length = 0 if utf8 is NULL + * wstr is shared with data.any and wstr_length = length + if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 + or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_4)=4 + * wstr_length = 0 if wstr is NULL + + Compact strings use only one memory block (structure + characters), + whereas legacy strings use one block for the structure and one block + for characters. + + Legacy strings are created by PyUnicode_FromUnicode() and + PyUnicode_FromStringAndSize(NULL, size) functions. They become ready + when PyUnicode_READY() is called. + + See also _PyUnicode_CheckConsistency(). + */ + PyObject_HEAD + Py_ssize_t length; /* Number of code points in the string */ + Py_hash_t hash; /* Hash value; -1 if not set */ + struct { + /* + SSTATE_NOT_INTERNED (0) + SSTATE_INTERNED_MORTAL (1) + SSTATE_INTERNED_IMMORTAL (2) + + If interned != SSTATE_NOT_INTERNED, the two references from the + dictionary to this object are *not* counted in ob_refcnt. + */ + unsigned int interned:2; + /* Character size: + + - PyUnicode_WCHAR_KIND (0): + + * character type = wchar_t (16 or 32 bits, depending on the + platform) + + - PyUnicode_1BYTE_KIND (1): + + * character type = Py_UCS1 (8 bits, unsigned) + * all characters are in the range U+0000-U+00FF (latin1) + * if ascii is set, all characters are in the range U+0000-U+007F + (ASCII), otherwise at least one character is in the range + U+0080-U+00FF + + - PyUnicode_2BYTE_KIND (2): + + * character type = Py_UCS2 (16 bits, unsigned) + * all characters are in the range U+0000-U+FFFF (BMP) + * at least one character is in the range U+0100-U+FFFF + + - PyUnicode_4BYTE_KIND (4): + + * character type = Py_UCS4 (32 bits, unsigned) + * all characters are in the range U+0000-U+10FFFF + * at least one character is in the range U+10000-U+10FFFF + */ + unsigned int kind:3; + /* Compact is with respect to the allocation scheme. Compact unicode + objects only require one memory block while non-compact objects use + one block for the PyUnicodeObject struct and another for its data + buffer. */ + unsigned int compact:1; + /* The string only contains characters in the range U+0000-U+007F (ASCII) + and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is + set, use the PyASCIIObject structure. */ + unsigned int ascii:1; + /* The ready flag indicates whether the object layout is initialized + completely. This means that this is either a compact object, or + the data pointer is filled out. The bit is redundant, and helps + to minimize the test in PyUnicode_IS_READY(). */ + unsigned int ready:1; + /* Padding to ensure that PyUnicode_DATA() is always aligned to + 4 bytes (see issue #19537 on m68k). */ + unsigned int :24; + } state; + wchar_t *wstr; /* wchar_t representation (null-terminated) */ +} PyASCIIObject; + +/* Non-ASCII strings allocated through PyUnicode_New use the + PyCompactUnicodeObject structure. state.compact is set, and the data + immediately follow the structure. */ +typedef struct { + PyASCIIObject _base; + Py_ssize_t utf8_length; /* Number of bytes in utf8, excluding the + * terminating \0. */ + char *utf8; /* UTF-8 representation (null-terminated) */ + Py_ssize_t wstr_length; /* Number of code points in wstr, possible + * surrogates count as two code points. */ +} PyCompactUnicodeObject; + +/* Strings allocated through PyUnicode_FromUnicode(NULL, len) use the + PyUnicodeObject structure. The actual string data is initially in the wstr + block, and copied into the data block using _PyUnicode_Ready. */ +typedef struct { + PyCompactUnicodeObject _base; + union { + void *any; + Py_UCS1 *latin1; + Py_UCS2 *ucs2; + Py_UCS4 *ucs4; + } data; /* Canonical, smallest-form Unicode buffer */ +} PyUnicodeObject; + +PyAPI_FUNC(int) _PyUnicode_CheckConsistency( + PyObject *op, + int check_content); + +/* Fast access macros */ +#define PyUnicode_WSTR_LENGTH(op) \ + (PyUnicode_IS_COMPACT_ASCII(op) ? \ + ((PyASCIIObject*)op)->length : \ + ((PyCompactUnicodeObject*)op)->wstr_length) + +/* Returns the deprecated Py_UNICODE representation's size in code units + (this includes surrogate pairs as 2 units). + If the Py_UNICODE representation is not available, it will be computed + on request. Use PyUnicode_GET_LENGTH() for the length in code points. */ + +/* Py_DEPRECATED(3.3) */ +#define PyUnicode_GET_SIZE(op) \ + (assert(PyUnicode_Check(op)), \ + (((PyASCIIObject *)(op))->wstr) ? \ + PyUnicode_WSTR_LENGTH(op) : \ + ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\ + assert(((PyASCIIObject *)(op))->wstr), \ + PyUnicode_WSTR_LENGTH(op))) + +/* Py_DEPRECATED(3.3) */ +#define PyUnicode_GET_DATA_SIZE(op) \ + (PyUnicode_GET_SIZE(op) * Py_UNICODE_SIZE) + +/* Alias for PyUnicode_AsUnicode(). This will create a wchar_t/Py_UNICODE + representation on demand. Using this macro is very inefficient now, + try to port your code to use the new PyUnicode_*BYTE_DATA() macros or + use PyUnicode_WRITE() and PyUnicode_READ(). */ + +/* Py_DEPRECATED(3.3) */ +#define PyUnicode_AS_UNICODE(op) \ + (assert(PyUnicode_Check(op)), \ + (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ + PyUnicode_AsUnicode(_PyObject_CAST(op))) + +/* Py_DEPRECATED(3.3) */ +#define PyUnicode_AS_DATA(op) \ + ((const char *)(PyUnicode_AS_UNICODE(op))) + + +/* --- Flexible String Representation Helper Macros (PEP 393) -------------- */ + +/* Values for PyASCIIObject.state: */ + +/* Interning state. */ +#define SSTATE_NOT_INTERNED 0 +#define SSTATE_INTERNED_MORTAL 1 +#define SSTATE_INTERNED_IMMORTAL 2 + +/* Return true if the string contains only ASCII characters, or 0 if not. The + string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be + ready. */ +#define PyUnicode_IS_ASCII(op) \ + (assert(PyUnicode_Check(op)), \ + assert(PyUnicode_IS_READY(op)), \ + ((PyASCIIObject*)op)->state.ascii) + +/* Return true if the string is compact or 0 if not. + No type checks or Ready calls are performed. */ +#define PyUnicode_IS_COMPACT(op) \ + (((PyASCIIObject*)(op))->state.compact) + +/* Return true if the string is a compact ASCII string (use PyASCIIObject + structure), or 0 if not. No type checks or Ready calls are performed. */ +#define PyUnicode_IS_COMPACT_ASCII(op) \ + (((PyASCIIObject*)op)->state.ascii && PyUnicode_IS_COMPACT(op)) + +enum PyUnicode_Kind { +/* String contains only wstr byte characters. This is only possible + when the string was created with a legacy API and _PyUnicode_Ready() + has not been called yet. */ + PyUnicode_WCHAR_KIND = 0, +/* Return values of the PyUnicode_KIND() macro: */ + PyUnicode_1BYTE_KIND = 1, + PyUnicode_2BYTE_KIND = 2, + PyUnicode_4BYTE_KIND = 4 +}; + +/* Return pointers to the canonical representation cast to unsigned char, + Py_UCS2, or Py_UCS4 for direct character access. + No checks are performed, use PyUnicode_KIND() before to ensure + these will work correctly. */ + +#define PyUnicode_1BYTE_DATA(op) ((Py_UCS1*)PyUnicode_DATA(op)) +#define PyUnicode_2BYTE_DATA(op) ((Py_UCS2*)PyUnicode_DATA(op)) +#define PyUnicode_4BYTE_DATA(op) ((Py_UCS4*)PyUnicode_DATA(op)) + +/* Return one of the PyUnicode_*_KIND values defined above. */ +#define PyUnicode_KIND(op) \ + (assert(PyUnicode_Check(op)), \ + assert(PyUnicode_IS_READY(op)), \ + ((PyASCIIObject *)(op))->state.kind) + +/* Return a void pointer to the raw unicode buffer. */ +#define _PyUnicode_COMPACT_DATA(op) \ + (PyUnicode_IS_ASCII(op) ? \ + ((void*)((PyASCIIObject*)(op) + 1)) : \ + ((void*)((PyCompactUnicodeObject*)(op) + 1))) + +#define _PyUnicode_NONCOMPACT_DATA(op) \ + (assert(((PyUnicodeObject*)(op))->data.any), \ + ((((PyUnicodeObject *)(op))->data.any))) + +#define PyUnicode_DATA(op) \ + (assert(PyUnicode_Check(op)), \ + PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \ + _PyUnicode_NONCOMPACT_DATA(op)) + +/* In the access macros below, "kind" may be evaluated more than once. + All other macro parameters are evaluated exactly once, so it is safe + to put side effects into them (such as increasing the index). */ + +/* Write into the canonical representation, this macro does not do any sanity + checks and is intended for usage in loops. The caller should cache the + kind and data pointers obtained from other macro calls. + index is the index in the string (starts at 0) and value is the new + code point value which should be written to that location. */ +#define PyUnicode_WRITE(kind, data, index, value) \ + do { \ + switch ((kind)) { \ + case PyUnicode_1BYTE_KIND: { \ + ((Py_UCS1 *)(data))[(index)] = (Py_UCS1)(value); \ + break; \ + } \ + case PyUnicode_2BYTE_KIND: { \ + ((Py_UCS2 *)(data))[(index)] = (Py_UCS2)(value); \ + break; \ + } \ + default: { \ + assert((kind) == PyUnicode_4BYTE_KIND); \ + ((Py_UCS4 *)(data))[(index)] = (Py_UCS4)(value); \ + } \ + } \ + } while (0) + +/* Read a code point from the string's canonical representation. No checks + or ready calls are performed. */ +#define PyUnicode_READ(kind, data, index) \ + ((Py_UCS4) \ + ((kind) == PyUnicode_1BYTE_KIND ? \ + ((const Py_UCS1 *)(data))[(index)] : \ + ((kind) == PyUnicode_2BYTE_KIND ? \ + ((const Py_UCS2 *)(data))[(index)] : \ + ((const Py_UCS4 *)(data))[(index)] \ + ) \ + )) + +/* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it + calls PyUnicode_KIND() and might call it twice. For single reads, use + PyUnicode_READ_CHAR, for multiple consecutive reads callers should + cache kind and use PyUnicode_READ instead. */ +#define PyUnicode_READ_CHAR(unicode, index) \ + (assert(PyUnicode_Check(unicode)), \ + assert(PyUnicode_IS_READY(unicode)), \ + (Py_UCS4) \ + (PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \ + ((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \ + (PyUnicode_KIND((unicode)) == PyUnicode_2BYTE_KIND ? \ + ((const Py_UCS2 *)(PyUnicode_DATA((unicode))))[(index)] : \ + ((const Py_UCS4 *)(PyUnicode_DATA((unicode))))[(index)] \ + ) \ + )) + +/* Returns the length of the unicode string. The caller has to make sure that + the string has it's canonical representation set before calling + this macro. Call PyUnicode_(FAST_)Ready to ensure that. */ +#define PyUnicode_GET_LENGTH(op) \ + (assert(PyUnicode_Check(op)), \ + assert(PyUnicode_IS_READY(op)), \ + ((PyASCIIObject *)(op))->length) + + +/* Fast check to determine whether an object is ready. Equivalent to + PyUnicode_IS_COMPACT(op) || ((PyUnicodeObject*)(op))->data.any) */ + +#define PyUnicode_IS_READY(op) (((PyASCIIObject*)op)->state.ready) + +/* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best + case. If the canonical representation is not yet set, it will still call + _PyUnicode_Ready(). + Returns 0 on success and -1 on errors. */ +#define PyUnicode_READY(op) \ + (assert(PyUnicode_Check(op)), \ + (PyUnicode_IS_READY(op) ? \ + 0 : _PyUnicode_Ready(_PyObject_CAST(op)))) + +/* Return a maximum character value which is suitable for creating another + string based on op. This is always an approximation but more efficient + than iterating over the string. */ +#define PyUnicode_MAX_CHAR_VALUE(op) \ + (assert(PyUnicode_IS_READY(op)), \ + (PyUnicode_IS_ASCII(op) ? \ + (0x7f) : \ + (PyUnicode_KIND(op) == PyUnicode_1BYTE_KIND ? \ + (0xffU) : \ + (PyUnicode_KIND(op) == PyUnicode_2BYTE_KIND ? \ + (0xffffU) : \ + (0x10ffffU))))) + +/* === Public API ========================================================= */ + +/* --- Plain Py_UNICODE --------------------------------------------------- */ + +/* With PEP 393, this is the recommended way to allocate a new unicode object. + This function will allocate the object and its buffer in a single memory + block. Objects created using this function are not resizable. */ +PyAPI_FUNC(PyObject*) PyUnicode_New( + Py_ssize_t size, /* Number of code points in the new string */ + Py_UCS4 maxchar /* maximum code point value in the string */ + ); + +/* Initializes the canonical string representation from the deprecated + wstr/Py_UNICODE representation. This function is used to convert Unicode + objects which were created using the old API to the new flexible format + introduced with PEP 393. + + Don't call this function directly, use the public PyUnicode_READY() macro + instead. */ +PyAPI_FUNC(int) _PyUnicode_Ready( + PyObject *unicode /* Unicode object */ + ); + +/* Get a copy of a Unicode string. */ +PyAPI_FUNC(PyObject*) _PyUnicode_Copy( + PyObject *unicode + ); + +/* Copy character from one unicode object into another, this function performs + character conversion when necessary and falls back to memcpy() if possible. + + Fail if to is too small (smaller than *how_many* or smaller than + len(from)-from_start), or if kind(from[from_start:from_start+how_many]) > + kind(to), or if *to* has more than 1 reference. + + Return the number of written character, or return -1 and raise an exception + on error. + + Pseudo-code: + + how_many = min(how_many, len(from) - from_start) + to[to_start:to_start+how_many] = from[from_start:from_start+how_many] + return how_many + + Note: The function doesn't write a terminating null character. + */ +PyAPI_FUNC(Py_ssize_t) PyUnicode_CopyCharacters( + PyObject *to, + Py_ssize_t to_start, + PyObject *from, + Py_ssize_t from_start, + Py_ssize_t how_many + ); + +/* Unsafe version of PyUnicode_CopyCharacters(): don't check arguments and so + may crash if parameters are invalid (e.g. if the output string + is too short). */ +PyAPI_FUNC(void) _PyUnicode_FastCopyCharacters( + PyObject *to, + Py_ssize_t to_start, + PyObject *from, + Py_ssize_t from_start, + Py_ssize_t how_many + ); + +/* Fill a string with a character: write fill_char into + unicode[start:start+length]. + + Fail if fill_char is bigger than the string maximum character, or if the + string has more than 1 reference. + + Return the number of written character, or return -1 and raise an exception + on error. */ +PyAPI_FUNC(Py_ssize_t) PyUnicode_Fill( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t length, + Py_UCS4 fill_char + ); + +/* Unsafe version of PyUnicode_Fill(): don't check arguments and so may crash + if parameters are invalid (e.g. if length is longer than the string). */ +PyAPI_FUNC(void) _PyUnicode_FastFill( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t length, + Py_UCS4 fill_char + ); + +/* Create a Unicode Object from the Py_UNICODE buffer u of the given + size. + + u may be NULL which causes the contents to be undefined. It is the + user's responsibility to fill in the needed data afterwards. Note + that modifying the Unicode object contents after construction is + only allowed if u was set to NULL. + + The buffer is copied into the new object. */ +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( + const Py_UNICODE *u, /* Unicode buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Create a new string from a buffer of Py_UCS1, Py_UCS2 or Py_UCS4 characters. + Scan the string to find the maximum character. */ +PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData( + int kind, + const void *buffer, + Py_ssize_t size); + +/* Create a new string from a buffer of ASCII characters. + WARNING: Don't check if the string contains any non-ASCII character. */ +PyAPI_FUNC(PyObject*) _PyUnicode_FromASCII( + const char *buffer, + Py_ssize_t size); + +/* Compute the maximum character of the substring unicode[start:end]. + Return 127 for an empty string. */ +PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( + PyObject *unicode, + Py_ssize_t start, + Py_ssize_t end); + +/* Return a read-only pointer to the Unicode object's internal + Py_UNICODE buffer. + If the wchar_t/Py_UNICODE representation is not yet available, this + function will calculate it. */ +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( + PyObject *unicode /* Unicode object */ + ); + +/* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string + contains null characters. */ +PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( + PyObject *unicode /* Unicode object */ + ); + +/* Return a read-only pointer to the Unicode object's internal + Py_UNICODE buffer and save the length at size. + If the wchar_t/Py_UNICODE representation is not yet available, this + function will calculate it. */ + +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( + PyObject *unicode, /* Unicode object */ + Py_ssize_t *size /* location where to save the length */ + ); + +/* Get the maximum ordinal for a Unicode character. */ +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); + + +/* --- _PyUnicodeWriter API ----------------------------------------------- */ + +typedef struct { + PyObject *buffer; + void *data; + enum PyUnicode_Kind kind; + Py_UCS4 maxchar; + Py_ssize_t size; + Py_ssize_t pos; + + /* minimum number of allocated characters (default: 0) */ + Py_ssize_t min_length; + + /* minimum character (default: 127, ASCII) */ + Py_UCS4 min_char; + + /* If non-zero, overallocate the buffer (default: 0). */ + unsigned char overallocate; + + /* If readonly is 1, buffer is a shared string (cannot be modified) + and size is set to 0. */ + unsigned char readonly; +} _PyUnicodeWriter ; + +/* Initialize a Unicode writer. + * + * By default, the minimum buffer size is 0 character and overallocation is + * disabled. Set min_length, min_char and overallocate attributes to control + * the allocation of the buffer. */ +PyAPI_FUNC(void) +_PyUnicodeWriter_Init(_PyUnicodeWriter *writer); + +/* Prepare the buffer to write 'length' characters + with the specified maximum character. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \ + (((MAXCHAR) <= (WRITER)->maxchar \ + && (LENGTH) <= (WRITER)->size - (WRITER)->pos) \ + ? 0 \ + : (((LENGTH) == 0) \ + ? 0 \ + : _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR)))) + +/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro + instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, + Py_ssize_t length, Py_UCS4 maxchar); + +/* Prepare the buffer to have at least the kind KIND. + For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will + support characters in range U+000-U+FFFF. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ + (assert((KIND) != PyUnicode_WCHAR_KIND), \ + (KIND) <= (WRITER)->kind \ + ? 0 \ + : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) + +/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind() + macro instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, + enum PyUnicode_Kind kind); + +/* Append a Unicode character. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, + Py_UCS4 ch + ); + +/* Append a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, + PyObject *str /* Unicode string */ + ); + +/* Append a substring of a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, + PyObject *str, /* Unicode string */ + Py_ssize_t start, + Py_ssize_t end + ); + +/* Append an ASCII-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, + const char *str, /* ASCII-encoded byte string */ + Py_ssize_t len /* number of bytes, or -1 if unknown */ + ); + +/* Append a latin1-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, + const char *str, /* latin1-encoded byte string */ + Py_ssize_t len /* length in bytes */ + ); + +/* Get the value of the writer as a Unicode string. Clear the + buffer of the writer. Raise an exception and return NULL + on error. */ +PyAPI_FUNC(PyObject *) +_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) +_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer); + + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(int) _PyUnicode_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); + +/* --- wchar_t support for platforms which support it --------------------- */ + +#ifdef HAVE_WCHAR_H +PyAPI_FUNC(void*) _PyUnicode_AsKind(PyObject *s, unsigned int kind); +#endif + +/* --- Manage the default encoding ---------------------------------------- */ + +/* Returns a pointer to the default encoding (UTF-8) of the + Unicode object unicode and the size of the encoded representation + in bytes stored in *size. + + In case of an error, no *size is set. + + This function caches the UTF-8 encoded string in the unicodeobject + and subsequent calls will return the same string. The memory is released + when the unicodeobject is deallocated. + + _PyUnicode_AsStringAndSize is a #define for PyUnicode_AsUTF8AndSize to + support the previous internal function with the same behaviour. + + *** This API is for interpreter INTERNAL USE ONLY and will likely + *** be removed or changed in the future. + + *** If you need to access the Unicode object as UTF-8 bytes string, + *** please use PyUnicode_AsUTF8String() instead. +*/ + +PyAPI_FUNC(const char *) PyUnicode_AsUTF8AndSize( + PyObject *unicode, + Py_ssize_t *size); + +#define _PyUnicode_AsStringAndSize PyUnicode_AsUTF8AndSize + +/* Returns a pointer to the default encoding (UTF-8) of the + Unicode object unicode. + + Like PyUnicode_AsUTF8AndSize(), this also caches the UTF-8 representation + in the unicodeobject. + + _PyUnicode_AsString is a #define for PyUnicode_AsUTF8 to + support the previous internal function with the same behaviour. + + Use of this API is DEPRECATED since no size information can be + extracted from the returned data. + + *** This API is for interpreter INTERNAL USE ONLY and will likely + *** be removed or changed for Python 3.1. + + *** If you need to access the Unicode object as UTF-8 bytes string, + *** please use PyUnicode_AsUTF8String() instead. + +*/ + +PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode); + +#define _PyUnicode_AsString PyUnicode_AsUTF8 + +/* --- Generic Codecs ----------------------------------------------------- */ + +/* Encodes a Py_UNICODE buffer of the given size and returns a + Python string object. */ +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_Encode( + const Py_UNICODE *s, /* Unicode char buffer */ + Py_ssize_t size, /* number of Py_UNICODE chars to encode */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* --- UTF-7 Codecs ------------------------------------------------------- */ + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + int base64SetO, /* Encode RFC2152 Set O characters in base64 */ + int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF7( + PyObject *unicode, /* Unicode object */ + int base64SetO, /* Encode RFC2152 Set O characters in base64 */ + int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ + const char *errors /* error handling */ + ); + +/* --- UTF-8 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) _PyUnicode_AsUTF8String( + PyObject *unicode, + const char *errors); + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- UTF-32 Codecs ------------------------------------------------------ */ + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( + PyObject *object, /* Unicode object */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +/* --- UTF-16 Codecs ------------------------------------------------------ */ + +/* Returns a Python string object holding the UTF-16 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. + + Note that Py_UNICODE data is being interpreted as UTF-16 reduced to + UCS-2. This trick makes it possible to add full UTF-16 capabilities + at a later point without compromising the APIs. + +*/ +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF16( + PyObject* unicode, /* Unicode object */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +/* --- Unicode-Escape Codecs ---------------------------------------------- */ + +/* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape + chars. */ +PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscape( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + const char **first_invalid_escape /* on return, points to first + invalid escaped char in + string. */ +); + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ); + +/* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ); + +/* --- Latin-1 Codecs ----------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) _PyUnicode_AsLatin1String( + PyObject* unicode, + const char* errors); + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- ASCII Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) _PyUnicode_AsASCIIString( + PyObject* unicode, + const char* errors); + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- Character Map Codecs ----------------------------------------------- */ + +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *mapping, /* encoding mapping */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( + PyObject *unicode, /* Unicode object */ + PyObject *mapping, /* encoding mapping */ + const char *errors /* error handling */ + ); + +/* Translate a Py_UNICODE buffer of the given length by applying a + character mapping table to it and return the resulting Unicode + object. + + The mapping table must map Unicode ordinal integers to Unicode strings, + Unicode ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ); + +/* --- MBCS codecs for Windows -------------------------------------------- */ + +#ifdef MS_WINDOWS +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); +#endif + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters except + \0 as-is. Characters outside this range (Unicode ordinals 1-256) + are treated as errors. This includes embedded NULL bytes. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ); + +/* Transforms code points that have decimal digit property to the + corresponding ASCII digit code points. + + Returns a new Unicode string on success, NULL on failure. +*/ + +/* Py_DEPRECATED(3.3) */ +PyAPI_FUNC(PyObject*) PyUnicode_TransformDecimalToASCII( + Py_UNICODE *s, /* Unicode buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to transform */ + ); + +/* Coverts a Unicode object holding a decimal value to an ASCII string + for using in int, float and complex parsers. + Transforms code points that have decimal digit property to the + corresponding ASCII digit code points. Transforms spaces to ASCII. + Transforms code points starting from the first non-ASCII code point that + is neither a decimal digit nor a space to the end into '?'. */ + +PyAPI_FUNC(PyObject*) _PyUnicode_TransformDecimalAndSpaceToASCII( + PyObject *unicode /* Unicode object */ + ); + +/* --- Methods & Slots ---------------------------------------------------- */ + +PyAPI_FUNC(PyObject *) _PyUnicode_JoinArray( + PyObject *separator, + PyObject *const *items, + Py_ssize_t seqlen + ); + +/* Test whether a unicode is equal to ASCII identifier. Return 1 if true, + 0 otherwise. The right argument must be ASCII identifier. + Any error occurs inside will be cleared before return. */ +PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId( + PyObject *left, /* Left string */ + _Py_Identifier *right /* Right identifier */ + ); + +/* Test whether a unicode is equal to ASCII string. Return 1 if true, + 0 otherwise. The right argument must be ASCII-encoded string. + Any error occurs inside will be cleared before return. */ +PyAPI_FUNC(int) _PyUnicode_EqualToASCIIString( + PyObject *left, + const char *right /* ASCII-encoded string */ + ); + +/* Externally visible for str.strip(unicode) */ +PyAPI_FUNC(PyObject *) _PyUnicode_XStrip( + PyObject *self, + int striptype, + PyObject *sepobj + ); + +/* Using explicit passed-in values, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping( + _PyUnicodeWriter *writer, + Py_ssize_t n_buffer, + PyObject *digits, + Py_ssize_t d_pos, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + PyObject *thousands_sep, + Py_UCS4 *maxchar); + +/* === Characters Type APIs =============================================== */ + +/* Helper array used by Py_UNICODE_ISSPACE(). */ + +PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; + +/* These should not be used directly. Use the Py_UNICODE_IS* and + Py_UNICODE_TO* macros instead. + + These APIs are implemented in Objects/unicodectype.c. + +*/ + +PyAPI_FUNC(int) _PyUnicode_IsLowercase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsUppercase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsTitlecase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsXidStart( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsXidContinue( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsWhitespace( + const Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsLinebreak( + const Py_UCS4 ch /* Unicode character */ + ); + +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToLowercase( + Py_UCS4 ch /* Unicode character */ + ); + +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToUppercase( + Py_UCS4 ch /* Unicode character */ + ); + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToLowerFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToTitleFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToUpperFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_ToFoldedFull( + Py_UCS4 ch, /* Unicode character */ + Py_UCS4 *res + ); + +PyAPI_FUNC(int) _PyUnicode_IsCaseIgnorable( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsCased( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(double) _PyUnicode_ToNumeric( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDigit( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsNumeric( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsPrintable( + Py_UCS4 ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsAlpha( + Py_UCS4 ch /* Unicode character */ + ); + +Py_DEPRECATED(3.3) PyAPI_FUNC(size_t) Py_UNICODE_strlen( + const Py_UNICODE *u + ); + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcpy( + Py_UNICODE *s1, + const Py_UNICODE *s2); + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcat( + Py_UNICODE *s1, const Py_UNICODE *s2); + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy( + Py_UNICODE *s1, + const Py_UNICODE *s2, + size_t n); + +Py_DEPRECATED(3.3) PyAPI_FUNC(int) Py_UNICODE_strcmp( + const Py_UNICODE *s1, + const Py_UNICODE *s2 + ); + +Py_DEPRECATED(3.3) PyAPI_FUNC(int) Py_UNICODE_strncmp( + const Py_UNICODE *s1, + const Py_UNICODE *s2, + size_t n + ); + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( + const Py_UNICODE *s, + Py_UNICODE c + ); + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( + const Py_UNICODE *s, + Py_UNICODE c + ); + +PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); + +/* Create a copy of a unicode string ending with a nul character. Return NULL + and raise a MemoryError exception on memory allocation failure, otherwise + return a new allocated buffer (use PyMem_Free() to free the buffer). */ + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( + PyObject *unicode + ); + +/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ +PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); +/* Clear all static strings. */ +PyAPI_FUNC(void) _PyUnicode_ClearStaticStrings(void); + +/* Fast equality check when the inputs are known to be exact unicode types + and where the hash values are equal (i.e. a very probable match) */ +PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); + +#ifdef __cplusplus +} +#endif diff --git a/python/include/datetime.h b/python/include/datetime.h new file mode 100755 index 0000000..00507cb --- /dev/null +++ b/python/include/datetime.h @@ -0,0 +1,259 @@ +/* datetime.h + */ +#ifndef Py_LIMITED_API +#ifndef DATETIME_H +#define DATETIME_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Fields are packed into successive bytes, each viewed as unsigned and + * big-endian, unless otherwise noted: + * + * byte offset + * 0 year 2 bytes, 1-9999 + * 2 month 1 byte, 1-12 + * 3 day 1 byte, 1-31 + * 4 hour 1 byte, 0-23 + * 5 minute 1 byte, 0-59 + * 6 second 1 byte, 0-59 + * 7 usecond 3 bytes, 0-999999 + * 10 + */ + +/* # of bytes for year, month, and day. */ +#define _PyDateTime_DATE_DATASIZE 4 + +/* # of bytes for hour, minute, second, and usecond. */ +#define _PyDateTime_TIME_DATASIZE 6 + +/* # of bytes for year, month, day, hour, minute, second, and usecond. */ +#define _PyDateTime_DATETIME_DATASIZE 10 + + +typedef struct +{ + PyObject_HEAD + Py_hash_t hashcode; /* -1 when unknown */ + int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ + int seconds; /* 0 <= seconds < 24*3600 is invariant */ + int microseconds; /* 0 <= microseconds < 1000000 is invariant */ +} PyDateTime_Delta; + +typedef struct +{ + PyObject_HEAD /* a pure abstract base class */ +} PyDateTime_TZInfo; + + +/* The datetime and time types have hashcodes, and an optional tzinfo member, + * present if and only if hastzinfo is true. + */ +#define _PyTZINFO_HEAD \ + PyObject_HEAD \ + Py_hash_t hashcode; \ + char hastzinfo; /* boolean flag */ + +/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something + * convenient to cast to, when getting at the hastzinfo member of objects + * starting with _PyTZINFO_HEAD. + */ +typedef struct +{ + _PyTZINFO_HEAD +} _PyDateTime_BaseTZInfo; + +/* All time objects are of PyDateTime_TimeType, but that can be allocated + * in two ways, with or without a tzinfo member. Without is the same as + * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an + * internal struct used to allocate the right amount of space for the + * "without" case. + */ +#define _PyDateTime_TIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_TIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_TIMEHEAD +} _PyDateTime_BaseTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_TIMEHEAD + unsigned char fold; + PyObject *tzinfo; +} PyDateTime_Time; /* hastzinfo true */ + + +/* All datetime objects are of PyDateTime_DateTimeType, but that can be + * allocated in two ways too, just like for time objects above. In addition, + * the plain date type is a base class for datetime, so it must also have + * a hastzinfo member (although it's unused there). + */ +typedef struct +{ + _PyTZINFO_HEAD + unsigned char data[_PyDateTime_DATE_DATASIZE]; +} PyDateTime_Date; + +#define _PyDateTime_DATETIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_DATETIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_DATETIMEHEAD +} _PyDateTime_BaseDateTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_DATETIMEHEAD + unsigned char fold; + PyObject *tzinfo; +} PyDateTime_DateTime; /* hastzinfo true */ + + +/* Apply for date and datetime instances. */ +#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ + ((PyDateTime_Date*)o)->data[1]) +#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) +#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3]) + +#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4]) +#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) +#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6]) +#define PyDateTime_DATE_GET_MICROSECOND(o) \ + ((((PyDateTime_DateTime*)o)->data[7] << 16) | \ + (((PyDateTime_DateTime*)o)->data[8] << 8) | \ + ((PyDateTime_DateTime*)o)->data[9]) +#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold) + +/* Apply for time instances. */ +#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) +#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) +#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) +#define PyDateTime_TIME_GET_MICROSECOND(o) \ + ((((PyDateTime_Time*)o)->data[3] << 16) | \ + (((PyDateTime_Time*)o)->data[4] << 8) | \ + ((PyDateTime_Time*)o)->data[5]) +#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold) + +/* Apply for time delta instances */ +#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) +#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) +#define PyDateTime_DELTA_GET_MICROSECONDS(o) \ + (((PyDateTime_Delta*)o)->microseconds) + + +/* Define structure for C API. */ +typedef struct { + /* type objects */ + PyTypeObject *DateType; + PyTypeObject *DateTimeType; + PyTypeObject *TimeType; + PyTypeObject *DeltaType; + PyTypeObject *TZInfoType; + + /* singletons */ + PyObject *TimeZone_UTC; + + /* constructors */ + PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*); + PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, + PyObject*, PyTypeObject*); + PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); + PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + PyObject *(*TimeZone_FromTimeZone)(PyObject *offset, PyObject *name); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); + + /* PEP 495 constructors */ + PyObject *(*DateTime_FromDateAndTimeAndFold)(int, int, int, int, int, int, int, + PyObject*, int, PyTypeObject*); + PyObject *(*Time_FromTimeAndFold)(int, int, int, int, PyObject*, int, PyTypeObject*); + +} PyDateTime_CAPI; + +#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI" + + +/* This block is only used as part of the public API and should not be + * included in _datetimemodule.c, which does not use the C API capsule. + * See bpo-35081 for more details. + * */ +#ifndef _PY_DATETIME_IMPL +/* Define global variable for the C API and a macro for setting it. */ +static PyDateTime_CAPI *PyDateTimeAPI = NULL; + +#define PyDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) + +/* Macro for access to the UTC singleton */ +#define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC + +/* Macros for type checking when not building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType) + + +/* Macros for accessing constructors in a simplified fashion. */ +#define PyDate_FromDate(year, month, day) \ + PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) + +#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ + PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ + min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) + +#define PyDateTime_FromDateAndTimeAndFold(year, month, day, hour, min, sec, usec, fold) \ + PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, \ + min, sec, usec, Py_None, fold, PyDateTimeAPI->DateTimeType) + +#define PyTime_FromTime(hour, minute, second, usecond) \ + PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ + Py_None, PyDateTimeAPI->TimeType) + +#define PyTime_FromTimeAndFold(hour, minute, second, usecond, fold) \ + PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, usecond, \ + Py_None, fold, PyDateTimeAPI->TimeType) + +#define PyDelta_FromDSU(days, seconds, useconds) \ + PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ + PyDateTimeAPI->DeltaType) + +#define PyTimeZone_FromOffset(offset) \ + PyDateTimeAPI->TimeZone_FromTimeZone(offset, NULL) + +#define PyTimeZone_FromOffsetAndName(offset, name) \ + PyDateTimeAPI->TimeZone_FromTimeZone(offset, name) + +/* Macros supporting the DB API. */ +#define PyDateTime_FromTimestamp(args) \ + PyDateTimeAPI->DateTime_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) + +#define PyDate_FromTimestamp(args) \ + PyDateTimeAPI->Date_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateType), args) + +#endif /* !defined(_PY_DATETIME_IMPL) */ + +#ifdef __cplusplus +} +#endif +#endif +#endif /* !Py_LIMITED_API */ diff --git a/python/include/descrobject.h b/python/include/descrobject.h new file mode 100755 index 0000000..ead269d --- /dev/null +++ b/python/include/descrobject.h @@ -0,0 +1,108 @@ +/* Descriptors */ +#ifndef Py_DESCROBJECT_H +#define Py_DESCROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef PyObject *(*getter)(PyObject *, void *); +typedef int (*setter)(PyObject *, PyObject *, void *); + +typedef struct PyGetSetDef { + const char *name; + getter get; + setter set; + const char *doc; + void *closure; +} PyGetSetDef; + +#ifndef Py_LIMITED_API +typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, + void *wrapped); + +typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, + void *wrapped, PyObject *kwds); + +struct wrapperbase { + const char *name; + int offset; + void *function; + wrapperfunc wrapper; + const char *doc; + int flags; + PyObject *name_strobj; +}; + +/* Flags for above struct */ +#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ + +/* Various kinds of descriptor objects */ + +typedef struct { + PyObject_HEAD + PyTypeObject *d_type; + PyObject *d_name; + PyObject *d_qualname; +} PyDescrObject; + +#define PyDescr_COMMON PyDescrObject d_common + +#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) +#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) + +typedef struct { + PyDescr_COMMON; + PyMethodDef *d_method; + vectorcallfunc vectorcall; +} PyMethodDescrObject; + +typedef struct { + PyDescr_COMMON; + struct PyMemberDef *d_member; +} PyMemberDescrObject; + +typedef struct { + PyDescr_COMMON; + PyGetSetDef *d_getset; +} PyGetSetDescrObject; + +typedef struct { + PyDescr_COMMON; + struct wrapperbase *d_base; + void *d_wrapped; /* This can be any function pointer */ +} PyWrapperDescrObject; +#endif /* Py_LIMITED_API */ + +PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type; +PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; +PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; +PyAPI_DATA(PyTypeObject) PyMethodDescr_Type; +PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; +PyAPI_DATA(PyTypeObject) PyDictProxy_Type; +#ifndef Py_LIMITED_API +PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type; +#endif /* Py_LIMITED_API */ + +PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); +struct PyMemberDef; /* forward declaration for following prototype */ +PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, + struct PyMemberDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, + struct PyGetSetDef *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, + struct wrapperbase *, void *); +#define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL) +#endif + +PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); +PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); + + +PyAPI_DATA(PyTypeObject) PyProperty_Type; +#ifdef __cplusplus +} +#endif +#endif /* !Py_DESCROBJECT_H */ + diff --git a/python/include/dictobject.h b/python/include/dictobject.h new file mode 100755 index 0000000..b37573a --- /dev/null +++ b/python/include/dictobject.h @@ -0,0 +1,94 @@ +#ifndef Py_DICTOBJECT_H +#define Py_DICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Dictionary object type -- mapping from hashable object to object */ + +/* The distribution includes a separate file, Objects/dictnotes.txt, + describing explorations into dictionary design and optimization. + It covers typical dictionary use patterns, the parameters for + tuning dictionaries, and several ideas for possible optimizations. +*/ + +PyAPI_DATA(PyTypeObject) PyDict_Type; + +#define PyDict_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) +#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) + +PyAPI_FUNC(PyObject *) PyDict_New(void); +PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key); +PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); +PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); +PyAPI_FUNC(int) PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); +PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); +PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); +PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); + +/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ +PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); + +/* PyDict_Merge updates/merges from a mapping object (an object that + supports PyMapping_Keys() and PyObject_GetItem()). If override is true, + the last occurrence of a key wins, else the first. The Python + dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). +*/ +PyAPI_FUNC(int) PyDict_Merge(PyObject *mp, + PyObject *other, + int override); + +/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing + iterable objects of length 2. If override is true, the last occurrence + of a key wins, else the first. The Python dict constructor dict(seq2) + is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). +*/ +PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, + PyObject *seq2, + int override); + +PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); +PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); +PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); + +/* Dictionary (keys, values, items) views */ + +PyAPI_DATA(PyTypeObject) PyDictKeys_Type; +PyAPI_DATA(PyTypeObject) PyDictValues_Type; +PyAPI_DATA(PyTypeObject) PyDictItems_Type; + +#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type) +#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type) +#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type) +/* This excludes Values, since they are not sets. */ +# define PyDictViewSet_Check(op) \ + (PyDictKeys_Check(op) || PyDictItems_Check(op)) + +/* Dictionary (key, value, items) iterators */ + +PyAPI_DATA(PyTypeObject) PyDictIterKey_Type; +PyAPI_DATA(PyTypeObject) PyDictIterValue_Type; +PyAPI_DATA(PyTypeObject) PyDictIterItem_Type; + +PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type; +PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type; +PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type; + + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_DICTOBJECT_H +# include "cpython/dictobject.h" +# undef Py_CPYTHON_DICTOBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_DICTOBJECT_H */ diff --git a/python/include/dtoa.h b/python/include/dtoa.h new file mode 100755 index 0000000..9bfb625 --- /dev/null +++ b/python/include/dtoa.h @@ -0,0 +1,19 @@ +#ifndef Py_LIMITED_API +#ifndef PY_NO_SHORT_FLOAT_REPR +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); +PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); +PyAPI_FUNC(double) _Py_dg_stdnan(int sign); +PyAPI_FUNC(double) _Py_dg_infinity(int sign); + + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/python/include/dynamic_annotations.h b/python/include/dynamic_annotations.h new file mode 100755 index 0000000..0bd1a83 --- /dev/null +++ b/python/include/dynamic_annotations.h @@ -0,0 +1,499 @@ +/* Copyright (c) 2008-2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Neither the name of Google Inc. 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 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. + * + * --- + * Author: Kostya Serebryany + * Copied to CPython by Jeffrey Yasskin, with all macros renamed to + * start with _Py_ to avoid colliding with users embedding Python, and + * with deprecated macros removed. + */ + +/* This file defines dynamic annotations for use with dynamic analysis + tool such as valgrind, PIN, etc. + + Dynamic annotation is a source code annotation that affects + the generated code (that is, the annotation is not a comment). + Each such annotation is attached to a particular + instruction and/or to a particular object (address) in the program. + + The annotations that should be used by users are macros in all upper-case + (e.g., _Py_ANNOTATE_NEW_MEMORY). + + Actual implementation of these macros may differ depending on the + dynamic analysis tool being used. + + See http://code.google.com/p/data-race-test/ for more information. + + This file supports the following dynamic analysis tools: + - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). + Macros are defined empty. + - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). + Macros are defined as calls to non-inlinable empty functions + that are intercepted by Valgrind. */ + +#ifndef __DYNAMIC_ANNOTATIONS_H__ +#define __DYNAMIC_ANNOTATIONS_H__ + +#ifndef DYNAMIC_ANNOTATIONS_ENABLED +# define DYNAMIC_ANNOTATIONS_ENABLED 0 +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 + + /* ------------------------------------------------------------- + Annotations useful when implementing condition variables such as CondVar, + using conditional critical sections (Await/LockWhen) and when constructing + user-defined synchronization mechanisms. + + The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and + _Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in + user-defined synchronization mechanisms: the race detector will infer an + arc from the former to the latter when they share the same argument + pointer. + + Example 1 (reference counting): + + void Unref() { + _Py_ANNOTATE_HAPPENS_BEFORE(&refcount_); + if (AtomicDecrementByOne(&refcount_) == 0) { + _Py_ANNOTATE_HAPPENS_AFTER(&refcount_); + delete this; + } + } + + Example 2 (message queue): + + void MyQueue::Put(Type *e) { + MutexLock lock(&mu_); + _Py_ANNOTATE_HAPPENS_BEFORE(e); + PutElementIntoMyQueue(e); + } + + Type *MyQueue::Get() { + MutexLock lock(&mu_); + Type *e = GetElementFromMyQueue(); + _Py_ANNOTATE_HAPPENS_AFTER(e); + return e; + } + + Note: when possible, please use the existing reference counting and message + queue implementations instead of inventing new ones. */ + + /* Report that wait on the condition variable at address "cv" has succeeded + and the lock at address "lock" is held. */ +#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ + AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) + + /* Report that wait on the condition variable at "cv" has succeeded. Variant + w/o lock. */ +#define _Py_ANNOTATE_CONDVAR_WAIT(cv) \ + AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) + + /* Report that we are about to signal on the condition variable at address + "cv". */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \ + AnnotateCondVarSignal(__FILE__, __LINE__, cv) + + /* Report that we are about to signal_all on the condition variable at "cv". */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ + AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) + + /* Annotations for user-defined synchronization mechanisms. */ +#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj) +#define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj) + + /* Report that the bytes in the range [pointer, pointer+size) are about + to be published safely. The race checker will create a happens-before + arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to + subsequent accesses to this memory. + Note: this annotation may not work properly if the race detector uses + sampling, i.e. does not observe all memory accesses. + */ +#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ + AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) + + /* Instruct the tool to create a happens-before arc between mu->Unlock() and + mu->Lock(). This annotation may slow down the race detector and hide real + races. Normally it is used only when it would be difficult to annotate each + of the mutex's critical sections individually using the annotations above. + This annotation makes sense only for hybrid race detectors. For pure + happens-before detectors this is a no-op. For more details see + http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ +#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ + AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) + + /* ------------------------------------------------------------- + Annotations useful when defining memory allocators, or when memory that + was protected in one way starts to be protected in another. */ + + /* Report that a new memory at "address" of size "size" has been allocated. + This might be used when the memory has been retrieved from a free list and + is about to be reused, or when the locking discipline for a variable + changes. */ +#define _Py_ANNOTATE_NEW_MEMORY(address, size) \ + AnnotateNewMemory(__FILE__, __LINE__, address, size) + + /* ------------------------------------------------------------- + Annotations useful when defining FIFO queues that transfer data between + threads. */ + + /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at + address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should + be used only for FIFO queues. For non-FIFO queues use + _Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for + get). */ +#define _Py_ANNOTATE_PCQ_CREATE(pcq) \ + AnnotatePCQCreate(__FILE__, __LINE__, pcq) + + /* Report that the queue at address "pcq" is about to be destroyed. */ +#define _Py_ANNOTATE_PCQ_DESTROY(pcq) \ + AnnotatePCQDestroy(__FILE__, __LINE__, pcq) + + /* Report that we are about to put an element into a FIFO queue at address + "pcq". */ +#define _Py_ANNOTATE_PCQ_PUT(pcq) \ + AnnotatePCQPut(__FILE__, __LINE__, pcq) + + /* Report that we've just got an element from a FIFO queue at address "pcq". */ +#define _Py_ANNOTATE_PCQ_GET(pcq) \ + AnnotatePCQGet(__FILE__, __LINE__, pcq) + + /* ------------------------------------------------------------- + Annotations that suppress errors. It is usually better to express the + program's synchronization using the other annotations, but these can + be used when all else fails. */ + + /* Report that we may have a benign race at "pointer", with size + "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the + point where "pointer" has been allocated, preferably close to the point + where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */ +#define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ + sizeof(*(pointer)), description) + + /* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to + the memory range [address, address+size). */ +#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) + + /* Request the analysis tool to ignore all reads in the current thread + until _Py_ANNOTATE_IGNORE_READS_END is called. + Useful to ignore intentional racey reads, while still checking + other reads and all writes. + See also _Py_ANNOTATE_UNPROTECTED_READ. */ +#define _Py_ANNOTATE_IGNORE_READS_BEGIN() \ + AnnotateIgnoreReadsBegin(__FILE__, __LINE__) + + /* Stop ignoring reads. */ +#define _Py_ANNOTATE_IGNORE_READS_END() \ + AnnotateIgnoreReadsEnd(__FILE__, __LINE__) + + /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ +#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \ + AnnotateIgnoreWritesBegin(__FILE__, __LINE__) + + /* Stop ignoring writes. */ +#define _Py_ANNOTATE_IGNORE_WRITES_END() \ + AnnotateIgnoreWritesEnd(__FILE__, __LINE__) + + /* Start ignoring all memory accesses (reads and writes). */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ + do {\ + _Py_ANNOTATE_IGNORE_READS_BEGIN();\ + _Py_ANNOTATE_IGNORE_WRITES_BEGIN();\ + }while(0)\ + + /* Stop ignoring all memory accesses. */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ + do {\ + _Py_ANNOTATE_IGNORE_WRITES_END();\ + _Py_ANNOTATE_IGNORE_READS_END();\ + }while(0)\ + + /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: + RWLOCK* and CONDVAR*. */ +#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \ + AnnotateIgnoreSyncBegin(__FILE__, __LINE__) + + /* Stop ignoring sync events. */ +#define _Py_ANNOTATE_IGNORE_SYNC_END() \ + AnnotateIgnoreSyncEnd(__FILE__, __LINE__) + + + /* Enable (enable!=0) or disable (enable==0) race detection for all threads. + This annotation could be useful if you want to skip expensive race analysis + during some period of program execution, e.g. during initialization. */ +#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ + AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) + + /* ------------------------------------------------------------- + Annotations useful for debugging. */ + + /* Request to trace every access to "address". */ +#define _Py_ANNOTATE_TRACE_MEMORY(address) \ + AnnotateTraceMemory(__FILE__, __LINE__, address) + + /* Report the current thread name to a race detector. */ +#define _Py_ANNOTATE_THREAD_NAME(name) \ + AnnotateThreadName(__FILE__, __LINE__, name) + + /* ------------------------------------------------------------- + Annotations useful when implementing locks. They are not + normally needed by modules that merely use locks. + The "lock" argument is a pointer to the lock object. */ + + /* Report that a lock has been created at address "lock". */ +#define _Py_ANNOTATE_RWLOCK_CREATE(lock) \ + AnnotateRWLockCreate(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" is about to be destroyed. */ +#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \ + AnnotateRWLockDestroy(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" has been acquired. + is_w=1 for writer lock, is_w=0 for reader lock. */ +#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ + AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) + + /* Report that the lock at address "lock" is about to be released. */ +#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ + AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) + + /* ------------------------------------------------------------- + Annotations useful when implementing barriers. They are not + normally needed by modules that merely use barriers. + The "barrier" argument is a pointer to the barrier object. */ + + /* Report that the "barrier" has been initialized with initial "count". + If 'reinitialization_allowed' is true, initialization is allowed to happen + multiple times w/o calling barrier_destroy() */ +#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ + AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \ + reinitialization_allowed) + + /* Report that we are about to enter barrier_wait("barrier"). */ +#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ + AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) + + /* Report that we just exited barrier_wait("barrier"). */ +#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ + AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) + + /* Report that the "barrier" has been destroyed. */ +#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \ + AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) + + /* ------------------------------------------------------------- + Annotations useful for testing race detectors. */ + + /* Report that we expect a race on the variable at "address". + Use only in unit tests for a race detector. */ +#define _Py_ANNOTATE_EXPECT_RACE(address, description) \ + AnnotateExpectRace(__FILE__, __LINE__, address, description) + + /* A no-op. Insert where you like to test the interceptors. */ +#define _Py_ANNOTATE_NO_OP(arg) \ + AnnotateNoOp(__FILE__, __LINE__, arg) + + /* Force the race detector to flush its state. The actual effect depends on + * the implementation of the detector. */ +#define _Py_ANNOTATE_FLUSH_STATE() \ + AnnotateFlushState(__FILE__, __LINE__) + + +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + +#define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */ +#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ +#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ +#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ +#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ +#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ +#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ +#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ +#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ +#define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ +#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ +#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ +#define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */ +#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ +#define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ +#define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ +#define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */ +#define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */ +#define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */ +#define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */ +#define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */ +#define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */ +#define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */ +#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ +#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ +#define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ +#define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */ +#define _Py_ANNOTATE_THREAD_NAME(name) /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_END() /* empty */ +#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ +#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ +#define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */ +#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ +#define _Py_ANNOTATE_NO_OP(arg) /* empty */ +#define _Py_ANNOTATE_FLUSH_STATE() /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +/* Use the macros above rather than using these functions directly. */ +#ifdef __cplusplus +extern "C" { +#endif +void AnnotateRWLockCreate(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockDestroy(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockAcquired(const char *file, int line, + const volatile void *lock, long is_w); +void AnnotateRWLockReleased(const char *file, int line, + const volatile void *lock, long is_w); +void AnnotateBarrierInit(const char *file, int line, + const volatile void *barrier, long count, + long reinitialization_allowed); +void AnnotateBarrierWaitBefore(const char *file, int line, + const volatile void *barrier); +void AnnotateBarrierWaitAfter(const char *file, int line, + const volatile void *barrier); +void AnnotateBarrierDestroy(const char *file, int line, + const volatile void *barrier); +void AnnotateCondVarWait(const char *file, int line, + const volatile void *cv, + const volatile void *lock); +void AnnotateCondVarSignal(const char *file, int line, + const volatile void *cv); +void AnnotateCondVarSignalAll(const char *file, int line, + const volatile void *cv); +void AnnotatePublishMemoryRange(const char *file, int line, + const volatile void *address, + long size); +void AnnotateUnpublishMemoryRange(const char *file, int line, + const volatile void *address, + long size); +void AnnotatePCQCreate(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQDestroy(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQPut(const char *file, int line, + const volatile void *pcq); +void AnnotatePCQGet(const char *file, int line, + const volatile void *pcq); +void AnnotateNewMemory(const char *file, int line, + const volatile void *address, + long size); +void AnnotateExpectRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRaceSized(const char *file, int line, + const volatile void *address, + long size, + const char *description); +void AnnotateMutexIsUsedAsCondVar(const char *file, int line, + const volatile void *mu); +void AnnotateTraceMemory(const char *file, int line, + const volatile void *arg); +void AnnotateThreadName(const char *file, int line, + const char *name); +void AnnotateIgnoreReadsBegin(const char *file, int line); +void AnnotateIgnoreReadsEnd(const char *file, int line); +void AnnotateIgnoreWritesBegin(const char *file, int line); +void AnnotateIgnoreWritesEnd(const char *file, int line); +void AnnotateEnableRaceDetection(const char *file, int line, int enable); +void AnnotateNoOp(const char *file, int line, + const volatile void *arg); +void AnnotateFlushState(const char *file, int line); + +/* Return non-zero value if running under valgrind. + + If "valgrind.h" is included into dynamic_annotations.c, + the regular valgrind mechanism will be used. + See http://valgrind.org/docs/manual/manual-core-adv.html about + RUNNING_ON_VALGRIND and other valgrind "client requests". + The file "valgrind.h" may be obtained by doing + svn co svn://svn.valgrind.org/valgrind/trunk/include + + If for some reason you can't use "valgrind.h" or want to fake valgrind, + there are two ways to make this function return non-zero: + - Use environment variable: export RUNNING_ON_VALGRIND=1 + - Make your tool intercept the function RunningOnValgrind() and + change its return value. + */ +int RunningOnValgrind(void); + +#ifdef __cplusplus +} +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) + + /* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. + + Instead of doing + _Py_ANNOTATE_IGNORE_READS_BEGIN(); + ... = x; + _Py_ANNOTATE_IGNORE_READS_END(); + one can use + ... = _Py_ANNOTATE_UNPROTECTED_READ(x); */ + template + inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) { + _Py_ANNOTATE_IGNORE_READS_BEGIN(); + T res = x; + _Py_ANNOTATE_IGNORE_READS_END(); + return res; + } + /* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ +#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ + namespace { \ + class static_var ## _annotator { \ + public: \ + static_var ## _annotator() { \ + _Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ + sizeof(static_var), \ + # static_var ": " description); \ + } \ + }; \ + static static_var ## _annotator the ## static_var ## _annotator;\ + } +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + +#define _Py_ANNOTATE_UNPROTECTED_READ(x) (x) +#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +#endif /* __DYNAMIC_ANNOTATIONS_H__ */ diff --git a/python/include/enumobject.h b/python/include/enumobject.h new file mode 100755 index 0000000..c14dbfc --- /dev/null +++ b/python/include/enumobject.h @@ -0,0 +1,17 @@ +#ifndef Py_ENUMOBJECT_H +#define Py_ENUMOBJECT_H + +/* Enumerate Object */ + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyEnum_Type; +PyAPI_DATA(PyTypeObject) PyReversed_Type; + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_ENUMOBJECT_H */ diff --git a/python/include/errcode.h b/python/include/errcode.h new file mode 100755 index 0000000..b37cd26 --- /dev/null +++ b/python/include/errcode.h @@ -0,0 +1,38 @@ +#ifndef Py_ERRCODE_H +#define Py_ERRCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Error codes passed around between file input, tokenizer, parser and + interpreter. This is necessary so we can turn them into Python + exceptions at a higher level. Note that some errors have a + slightly different meaning when passed from the tokenizer to the + parser than when passed from the parser to the interpreter; e.g. + the parser only returns E_EOF when it hits EOF immediately, and it + never returns E_OK. */ + +#define E_OK 10 /* No error */ +#define E_EOF 11 /* End Of File */ +#define E_INTR 12 /* Interrupted */ +#define E_TOKEN 13 /* Bad token */ +#define E_SYNTAX 14 /* Syntax error */ +#define E_NOMEM 15 /* Ran out of memory */ +#define E_DONE 16 /* Parsing complete */ +#define E_ERROR 17 /* Execution error */ +#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ +#define E_OVERFLOW 19 /* Node had too many children */ +#define E_TOODEEP 20 /* Too many indentation levels */ +#define E_DEDENT 21 /* No matching outer block for dedent */ +#define E_DECODE 22 /* Error in decoding into Unicode */ +#define E_EOFS 23 /* EOF in triple-quoted string */ +#define E_EOLS 24 /* EOL in single-quoted string */ +#define E_LINECONT 25 /* Unexpected characters after a line continuation */ +#define E_IDENTIFIER 26 /* Invalid characters in identifier */ +#define E_BADSINGLE 27 /* Ill-formed single statement input */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRCODE_H */ diff --git a/python/include/eval.h b/python/include/eval.h new file mode 100755 index 0000000..2c1c2d0 --- /dev/null +++ b/python/include/eval.h @@ -0,0 +1,37 @@ + +/* Interface to execute compiled code */ + +#ifndef Py_EVAL_H +#define Py_EVAL_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co, + PyObject *globals, + PyObject *locals, + PyObject *const *args, int argc, + PyObject *const *kwds, int kwdc, + PyObject *const *defs, int defc, + PyObject *kwdefs, PyObject *closure); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyEval_EvalCodeWithName( + PyObject *co, + PyObject *globals, PyObject *locals, + PyObject *const *args, Py_ssize_t argcount, + PyObject *const *kwnames, PyObject *const *kwargs, + Py_ssize_t kwcount, int kwstep, + PyObject *const *defs, Py_ssize_t defcount, + PyObject *kwdefs, PyObject *closure, + PyObject *name, PyObject *qualname); + +PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_EVAL_H */ diff --git a/python/include/fileobject.h b/python/include/fileobject.h new file mode 100755 index 0000000..6ec2994 --- /dev/null +++ b/python/include/fileobject.h @@ -0,0 +1,49 @@ +/* File object interface (what's left of it -- see io.py) */ + +#ifndef Py_FILEOBJECT_H +#define Py_FILEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#define PY_STDIOTEXTMODE "b" + +PyAPI_FUNC(PyObject *) PyFile_FromFd(int, const char *, const char *, int, + const char *, const char *, + const char *, int); +PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); +PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); + +/* The default encoding used by the platform file system APIs + If non-NULL, this is different than the default encoding for strings +*/ +PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; +#endif +PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_DATA(int) Py_UTF8Mode; +#endif + +/* A routine to check if a file descriptor can be select()-ed. */ +#ifdef _MSC_VER + /* On Windows, any socket fd can be select()-ed, no matter how high */ + #define _PyIsSelectable_fd(FD) (1) +#else + #define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE) +#endif + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_FILEOBJECT_H +# include "cpython/fileobject.h" +# undef Py_CPYTHON_FILEOBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FILEOBJECT_H */ diff --git a/python/include/fileutils.h b/python/include/fileutils.h new file mode 100755 index 0000000..359dd0a --- /dev/null +++ b/python/include/fileutils.h @@ -0,0 +1,185 @@ +#ifndef Py_FILEUTILS_H +#define Py_FILEUTILS_H +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(wchar_t *) Py_DecodeLocale( + const char *arg, + size_t *size); + +PyAPI_FUNC(char*) Py_EncodeLocale( + const wchar_t *text, + size_t *error_pos); + +PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( + const wchar_t *text, + size_t *error_pos); +#endif + + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03080000 +typedef enum { + _Py_ERROR_UNKNOWN=0, + _Py_ERROR_STRICT, + _Py_ERROR_SURROGATEESCAPE, + _Py_ERROR_REPLACE, + _Py_ERROR_IGNORE, + _Py_ERROR_BACKSLASHREPLACE, + _Py_ERROR_SURROGATEPASS, + _Py_ERROR_XMLCHARREFREPLACE, + _Py_ERROR_OTHER +} _Py_error_handler; + +PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors); + +PyAPI_FUNC(int) _Py_DecodeLocaleEx( + const char *arg, + wchar_t **wstr, + size_t *wlen, + const char **reason, + int current_locale, + _Py_error_handler errors); + +PyAPI_FUNC(int) _Py_EncodeLocaleEx( + const wchar_t *text, + char **str, + size_t *error_pos, + const char **reason, + int current_locale, + _Py_error_handler errors); +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _Py_device_encoding(int); + +#if defined(MS_WINDOWS) || defined(__APPLE__) + /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611). + On macOS 10.13, read() and write() with more than INT_MAX bytes + fail with EINVAL (bpo-24658). */ +# define _PY_READ_MAX INT_MAX +# define _PY_WRITE_MAX INT_MAX +#else + /* write() should truncate the input to PY_SSIZE_T_MAX bytes, + but it's safer to do it ourself to have a portable behaviour */ +# define _PY_READ_MAX PY_SSIZE_T_MAX +# define _PY_WRITE_MAX PY_SSIZE_T_MAX +#endif + +#ifdef MS_WINDOWS +struct _Py_stat_struct { + unsigned long st_dev; + uint64_t st_ino; + unsigned short st_mode; + int st_nlink; + int st_uid; + int st_gid; + unsigned long st_rdev; + __int64 st_size; + time_t st_atime; + int st_atime_nsec; + time_t st_mtime; + int st_mtime_nsec; + time_t st_ctime; + int st_ctime_nsec; + unsigned long st_file_attributes; + unsigned long st_reparse_tag; +}; +#else +# define _Py_stat_struct stat +#endif + +PyAPI_FUNC(int) _Py_fstat( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_fstat_noraise( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_stat( + PyObject *path, + struct stat *status); + +PyAPI_FUNC(int) _Py_open( + const char *pathname, + int flags); + +PyAPI_FUNC(int) _Py_open_noraise( + const char *pathname, + int flags); + +PyAPI_FUNC(FILE *) _Py_wfopen( + const wchar_t *path, + const wchar_t *mode); + +PyAPI_FUNC(FILE*) _Py_fopen( + const char *pathname, + const char *mode); + +PyAPI_FUNC(FILE*) _Py_fopen_obj( + PyObject *path, + const char *mode); + +PyAPI_FUNC(Py_ssize_t) _Py_read( + int fd, + void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write( + int fd, + const void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( + int fd, + const void *buf, + size_t count); + +#ifdef HAVE_READLINK +PyAPI_FUNC(int) _Py_wreadlink( + const wchar_t *path, + wchar_t *buf, + /* Number of characters of 'buf' buffer + including the trailing NUL character */ + size_t buflen); +#endif + +#ifdef HAVE_REALPATH +PyAPI_FUNC(wchar_t*) _Py_wrealpath( + const wchar_t *path, + wchar_t *resolved_path, + /* Number of characters of 'resolved_path' buffer + including the trailing NUL character */ + size_t resolved_path_len); +#endif + +PyAPI_FUNC(wchar_t*) _Py_wgetcwd( + wchar_t *buf, + /* Number of characters of 'buf' buffer + including the trailing NUL character */ + size_t buflen); + +PyAPI_FUNC(int) _Py_get_inheritable(int fd); + +PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_dup(int fd); + +#ifndef MS_WINDOWS +PyAPI_FUNC(int) _Py_get_blocking(int fd); + +PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); +#endif /* !MS_WINDOWS */ + +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FILEUTILS_H */ diff --git a/python/include/floatobject.h b/python/include/floatobject.h new file mode 100755 index 0000000..f1044d6 --- /dev/null +++ b/python/include/floatobject.h @@ -0,0 +1,130 @@ + +/* Float object interface */ + +/* +PyFloatObject represents a (double precision) floating point number. +*/ + +#ifndef Py_FLOATOBJECT_H +#define Py_FLOATOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + double ob_fval; +} PyFloatObject; +#endif + +PyAPI_DATA(PyTypeObject) PyFloat_Type; + +#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) +#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type) + +#ifdef Py_NAN +#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) +#endif + +#define Py_RETURN_INF(sign) do \ + if (copysign(1., sign) == 1.) { \ + return PyFloat_FromDouble(Py_HUGE_VAL); \ + } else { \ + return PyFloat_FromDouble(-Py_HUGE_VAL); \ + } while(0) + +PyAPI_FUNC(double) PyFloat_GetMax(void); +PyAPI_FUNC(double) PyFloat_GetMin(void); +PyAPI_FUNC(PyObject *) PyFloat_GetInfo(void); + +/* Return Python float from string PyObject. */ +PyAPI_FUNC(PyObject *) PyFloat_FromString(PyObject*); + +/* Return Python float from C double. */ +PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double); + +/* Extract C double from Python float. The macro version trades safety for + speed. */ +PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *); +#ifndef Py_LIMITED_API +#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) +#endif + +#ifndef Py_LIMITED_API +/* _PyFloat_{Pack,Unpack}{4,8} + * + * The struct and pickle (at least) modules need an efficient platform- + * independent way to store floating-point values as byte strings. + * The Pack routines produce a string from a C double, and the Unpack + * routines produce a C double from such a string. The suffix (4 or 8) + * specifies the number of bytes in the string. + * + * On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats + * these functions work by copying bits. On other platforms, the formats the + * 4- byte format is identical to the IEEE-754 single precision format, and + * the 8-byte format to the IEEE-754 double precision format, although the + * packing of INFs and NaNs (if such things exist on the platform) isn't + * handled correctly, and attempting to unpack a string containing an IEEE + * INF or NaN will raise an exception. + * + * On non-IEEE platforms with more precision, or larger dynamic range, than + * 754 supports, not all values can be packed; on non-IEEE platforms with less + * precision, or smaller dynamic range, not all values can be unpacked. What + * happens in such cases is partly accidental (alas). + */ + +/* The pack routines write 2, 4 or 8 bytes, starting at p. le is a bool + * argument, true if you want the string in little-endian format (exponent + * last, at p+1, p+3 or p+7), false if you want big-endian format (exponent + * first, at p). + * Return value: 0 if all is OK, -1 if error (and an exception is + * set, most likely OverflowError). + * There are two problems on non-IEEE platforms: + * 1): What this does is undefined if x is a NaN or infinity. + * 2): -0.0 and +0.0 produce the same string. + */ +PyAPI_FUNC(int) _PyFloat_Pack2(double x, unsigned char *p, int le); +PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le); +PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le); + +/* Needed for the old way for marshal to store a floating point number. + Returns the string length copied into p, -1 on error. + */ +PyAPI_FUNC(int) _PyFloat_Repr(double x, char *p, size_t len); + +/* Used to get the important decimal digits of a double */ +PyAPI_FUNC(int) _PyFloat_Digits(char *buf, double v, int *signum); +PyAPI_FUNC(void) _PyFloat_DigitsInit(void); + +/* The unpack routines read 2, 4 or 8 bytes, starting at p. le is a bool + * argument, true if the string is in little-endian format (exponent + * last, at p+1, p+3 or p+7), false if big-endian (exponent first, at p). + * Return value: The unpacked double. On error, this is -1.0 and + * PyErr_Occurred() is true (and an exception is set, most likely + * OverflowError). Note that on a non-IEEE platform this will refuse + * to unpack a string that represents a NaN or infinity. + */ +PyAPI_FUNC(double) _PyFloat_Unpack2(const unsigned char *p, int le); +PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); +PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); + +/* free list api */ +PyAPI_FUNC(int) PyFloat_ClearFreeList(void); + +PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(int) _PyFloat_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif /* Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FLOATOBJECT_H */ diff --git a/python/include/frameobject.h b/python/include/frameobject.h new file mode 100755 index 0000000..3bad86a --- /dev/null +++ b/python/include/frameobject.h @@ -0,0 +1,92 @@ +/* Frame object interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_FRAMEOBJECT_H +#define Py_FRAMEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int b_type; /* what kind of block this is */ + int b_handler; /* where to jump to find handler */ + int b_level; /* value stack level to pop to */ +} PyTryBlock; + +typedef struct _frame { + PyObject_VAR_HEAD + struct _frame *f_back; /* previous frame, or NULL */ + PyCodeObject *f_code; /* code segment */ + PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ + PyObject *f_globals; /* global symbol table (PyDictObject) */ + PyObject *f_locals; /* local symbol table (any mapping) */ + PyObject **f_valuestack; /* points after the last local */ + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; + PyObject *f_trace; /* Trace function */ + char f_trace_lines; /* Emit per-line trace events? */ + char f_trace_opcodes; /* Emit per-opcode trace events? */ + + /* Borrowed reference to a generator, or NULL */ + PyObject *f_gen; + + int f_lasti; /* Last instruction if called */ + /* Call PyFrame_GetLineNumber() instead of reading this field + directly. As of 2.3 f_lineno is only valid when tracing is + active (i.e. when f_trace is set). At other times we use + PyCode_Addr2Line to calculate the line from the current + bytecode index. */ + int f_lineno; /* Current line number */ + int f_iblock; /* index in f_blockstack */ + char f_executing; /* whether the frame is still executing */ + PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ + PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ +} PyFrameObject; + + +/* Standard object interface */ + +PyAPI_DATA(PyTypeObject) PyFrame_Type; + +#define PyFrame_Check(op) (Py_TYPE(op) == &PyFrame_Type) + +PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, + PyObject *, PyObject *); + +/* only internal use */ +PyFrameObject* _PyFrame_New_NoTrack(PyThreadState *, PyCodeObject *, + PyObject *, PyObject *); + + +/* The rest of the interface is specific for frame objects */ + +/* Block management functions */ + +PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int); +PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *); + +/* Extend the value stack */ + +PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int); + +/* Conversions between "fast locals" and locals in dictionary */ + +PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); + +PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); +PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); + +PyAPI_FUNC(int) PyFrame_ClearFreeList(void); + +PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); + +/* Return the line of code the frame is currently executing. */ +PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FRAMEOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/funcobject.h b/python/include/funcobject.h new file mode 100755 index 0000000..e563a74 --- /dev/null +++ b/python/include/funcobject.h @@ -0,0 +1,104 @@ + +/* Function object interface */ +#ifndef Py_LIMITED_API +#ifndef Py_FUNCOBJECT_H +#define Py_FUNCOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Function objects and code objects should not be confused with each other: + * + * Function objects are created by the execution of the 'def' statement. + * They reference a code object in their __code__ attribute, which is a + * purely syntactic object, i.e. nothing more than a compiled version of some + * source code lines. There is one code object per source code "fragment", + * but each code object can be referenced by zero or many function objects + * depending only on how many times the 'def' statement in the source was + * executed so far. + */ + +typedef struct { + PyObject_HEAD + PyObject *func_code; /* A code object, the __code__ attribute */ + PyObject *func_globals; /* A dictionary (other mappings won't do) */ + PyObject *func_defaults; /* NULL or a tuple */ + PyObject *func_kwdefaults; /* NULL or a dict */ + PyObject *func_closure; /* NULL or a tuple of cell objects */ + PyObject *func_doc; /* The __doc__ attribute, can be anything */ + PyObject *func_name; /* The __name__ attribute, a string object */ + PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */ + PyObject *func_weakreflist; /* List of weak references */ + PyObject *func_module; /* The __module__ attribute, can be anything */ + PyObject *func_annotations; /* Annotations, a dict or NULL */ + PyObject *func_qualname; /* The qualified name */ + vectorcallfunc vectorcall; + + /* Invariant: + * func_closure contains the bindings for func_code->co_freevars, so + * PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code) + * (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0). + */ +} PyFunctionObject; + +PyAPI_DATA(PyTypeObject) PyFunction_Type; + +#define PyFunction_Check(op) (Py_TYPE(op) == &PyFunction_Type) + +PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); +PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *); +PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyFunction_FastCallDict( + PyObject *func, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( + PyObject *func, + PyObject *const *stack, + size_t nargsf, + PyObject *kwnames); +#endif + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyFunction_GET_CODE(func) \ + (((PyFunctionObject *)func) -> func_code) +#define PyFunction_GET_GLOBALS(func) \ + (((PyFunctionObject *)func) -> func_globals) +#define PyFunction_GET_MODULE(func) \ + (((PyFunctionObject *)func) -> func_module) +#define PyFunction_GET_DEFAULTS(func) \ + (((PyFunctionObject *)func) -> func_defaults) +#define PyFunction_GET_KW_DEFAULTS(func) \ + (((PyFunctionObject *)func) -> func_kwdefaults) +#define PyFunction_GET_CLOSURE(func) \ + (((PyFunctionObject *)func) -> func_closure) +#define PyFunction_GET_ANNOTATIONS(func) \ + (((PyFunctionObject *)func) -> func_annotations) + +/* The classmethod and staticmethod types lives here, too */ +PyAPI_DATA(PyTypeObject) PyClassMethod_Type; +PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; + +PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FUNCOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/genobject.h b/python/include/genobject.h new file mode 100755 index 0000000..59ede28 --- /dev/null +++ b/python/include/genobject.h @@ -0,0 +1,109 @@ + +/* Generator object interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_GENOBJECT_H +#define Py_GENOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "pystate.h" /* _PyErr_StackItem */ + +struct _frame; /* Avoid including frameobject.h */ + +/* _PyGenObject_HEAD defines the initial segment of generator + and coroutine objects. */ +#define _PyGenObject_HEAD(prefix) \ + PyObject_HEAD \ + /* Note: gi_frame can be NULL if the generator is "finished" */ \ + struct _frame *prefix##_frame; \ + /* True if generator is being executed. */ \ + char prefix##_running; \ + /* The code object backing the generator */ \ + PyObject *prefix##_code; \ + /* List of weak reference. */ \ + PyObject *prefix##_weakreflist; \ + /* Name of the generator. */ \ + PyObject *prefix##_name; \ + /* Qualified name of the generator. */ \ + PyObject *prefix##_qualname; \ + _PyErr_StackItem prefix##_exc_state; + +typedef struct { + /* The gi_ prefix is intended to remind of generator-iterator. */ + _PyGenObject_HEAD(gi) +} PyGenObject; + +PyAPI_DATA(PyTypeObject) PyGen_Type; + +#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) +#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type) + +PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); +PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *, + PyObject *name, PyObject *qualname); +PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *); +PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); +PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); +PyAPI_FUNC(PyObject *) _PyGen_Send(PyGenObject *, PyObject *); +PyObject *_PyGen_yf(PyGenObject *); +PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); + +#ifndef Py_LIMITED_API +typedef struct { + _PyGenObject_HEAD(cr) + PyObject *cr_origin; +} PyCoroObject; + +PyAPI_DATA(PyTypeObject) PyCoro_Type; +PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; + +PyAPI_DATA(PyTypeObject) _PyAIterWrapper_Type; + +#define PyCoro_CheckExact(op) (Py_TYPE(op) == &PyCoro_Type) +PyObject *_PyCoro_GetAwaitableIter(PyObject *o); +PyAPI_FUNC(PyObject *) PyCoro_New(struct _frame *, + PyObject *name, PyObject *qualname); + +/* Asynchronous Generators */ + +typedef struct { + _PyGenObject_HEAD(ag) + PyObject *ag_finalizer; + + /* Flag is set to 1 when hooks set up by sys.set_asyncgen_hooks + were called on the generator, to avoid calling them more + than once. */ + int ag_hooks_inited; + + /* Flag is set to 1 when aclose() is called for the first time, or + when a StopAsyncIteration exception is raised. */ + int ag_closed; + + int ag_running_async; +} PyAsyncGenObject; + +PyAPI_DATA(PyTypeObject) PyAsyncGen_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type; +PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; + +PyAPI_FUNC(PyObject *) PyAsyncGen_New(struct _frame *, + PyObject *name, PyObject *qualname); + +#define PyAsyncGen_CheckExact(op) (Py_TYPE(op) == &PyAsyncGen_Type) + +PyObject *_PyAsyncGenValueWrapperNew(PyObject *); + +int PyAsyncGen_ClearFreeLists(void); + +#endif + +#undef _PyGenObject_HEAD + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GENOBJECT_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/graminit.h b/python/include/graminit.h new file mode 100755 index 0000000..d1027b7 --- /dev/null +++ b/python/include/graminit.h @@ -0,0 +1,94 @@ +/* Generated by Parser/pgen */ + +#define single_input 256 +#define file_input 257 +#define eval_input 258 +#define decorator 259 +#define decorators 260 +#define decorated 261 +#define async_funcdef 262 +#define funcdef 263 +#define parameters 264 +#define typedargslist 265 +#define tfpdef 266 +#define varargslist 267 +#define vfpdef 268 +#define stmt 269 +#define simple_stmt 270 +#define small_stmt 271 +#define expr_stmt 272 +#define annassign 273 +#define testlist_star_expr 274 +#define augassign 275 +#define del_stmt 276 +#define pass_stmt 277 +#define flow_stmt 278 +#define break_stmt 279 +#define continue_stmt 280 +#define return_stmt 281 +#define yield_stmt 282 +#define raise_stmt 283 +#define import_stmt 284 +#define import_name 285 +#define import_from 286 +#define import_as_name 287 +#define dotted_as_name 288 +#define import_as_names 289 +#define dotted_as_names 290 +#define dotted_name 291 +#define global_stmt 292 +#define nonlocal_stmt 293 +#define assert_stmt 294 +#define compound_stmt 295 +#define async_stmt 296 +#define if_stmt 297 +#define while_stmt 298 +#define for_stmt 299 +#define try_stmt 300 +#define with_stmt 301 +#define with_item 302 +#define except_clause 303 +#define suite 304 +#define namedexpr_test 305 +#define test 306 +#define test_nocond 307 +#define lambdef 308 +#define lambdef_nocond 309 +#define or_test 310 +#define and_test 311 +#define not_test 312 +#define comparison 313 +#define comp_op 314 +#define star_expr 315 +#define expr 316 +#define xor_expr 317 +#define and_expr 318 +#define shift_expr 319 +#define arith_expr 320 +#define term 321 +#define factor 322 +#define power 323 +#define atom_expr 324 +#define atom 325 +#define testlist_comp 326 +#define trailer 327 +#define subscriptlist 328 +#define subscript 329 +#define sliceop 330 +#define exprlist 331 +#define testlist 332 +#define dictorsetmaker 333 +#define classdef 334 +#define arglist 335 +#define argument 336 +#define comp_iter 337 +#define sync_comp_for 338 +#define comp_for 339 +#define comp_if 340 +#define encoding_decl 341 +#define yield_expr 342 +#define yield_arg 343 +#define func_body_suite 344 +#define func_type_input 345 +#define func_type 346 +#define typelist 347 diff --git a/python/include/grammar.h b/python/include/grammar.h new file mode 100755 index 0000000..4b66b1e --- /dev/null +++ b/python/include/grammar.h @@ -0,0 +1,77 @@ + +/* Grammar interface */ + +#ifndef Py_GRAMMAR_H +#define Py_GRAMMAR_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "bitset.h" /* Sigh... */ + +/* A label of an arc */ + +typedef struct { + int lb_type; + const char *lb_str; +} label; + +#define EMPTY 0 /* Label number 0 is by definition the empty label */ + +/* A list of labels */ + +typedef struct { + int ll_nlabels; + const label *ll_label; +} labellist; + +/* An arc from one state to another */ + +typedef struct { + short a_lbl; /* Label of this arc */ + short a_arrow; /* State where this arc goes to */ +} arc; + +/* A state in a DFA */ + +typedef struct { + int s_narcs; + const arc *s_arc; /* Array of arcs */ + + /* Optional accelerators */ + int s_lower; /* Lowest label index */ + int s_upper; /* Highest label index */ + int *s_accel; /* Accelerator */ + int s_accept; /* Nonzero for accepting state */ +} state; + +/* A DFA */ + +typedef struct { + int d_type; /* Non-terminal this represents */ + char *d_name; /* For printing */ + int d_nstates; + state *d_state; /* Array of states */ + bitset d_first; +} dfa; + +/* A grammar */ + +typedef struct { + int g_ndfas; + const dfa *g_dfa; /* Array of DFAs */ + const labellist g_ll; + int g_start; /* Start symbol of the grammar */ + int g_accel; /* Set if accelerators present */ +} grammar; + +/* FUNCTIONS */ +const dfa *PyGrammar_FindDFA(grammar *g, int type); +const char *PyGrammar_LabelRepr(label *lb); +void PyGrammar_AddAccelerators(grammar *g); +void PyGrammar_RemoveAccelerators(grammar *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GRAMMAR_H */ diff --git a/python/include/import.h b/python/include/import.h new file mode 100755 index 0000000..13c6149 --- /dev/null +++ b/python/include/import.h @@ -0,0 +1,149 @@ + +/* Module definition and import interface */ + +#ifndef Py_IMPORT_H +#define Py_IMPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyMODINIT_FUNC PyInit__imp(void); +#endif /* !Py_LIMITED_API */ +PyAPI_FUNC(long) PyImport_GetMagicNumber(void); +PyAPI_FUNC(const char *) PyImport_GetMagicTag(void); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule( + const char *name, /* UTF-8 encoded string */ + PyObject *co + ); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx( + const char *name, /* UTF-8 encoded string */ + PyObject *co, + const char *pathname /* decoded from the filesystem encoding */ + ); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleWithPathnames( + const char *name, /* UTF-8 encoded string */ + PyObject *co, + const char *pathname, /* decoded from the filesystem encoding */ + const char *cpathname /* decoded from the filesystem encoding */ + ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject( + PyObject *name, + PyObject *co, + PyObject *pathname, + PyObject *cpathname + ); +#endif +PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_FUNC(PyObject *) PyImport_GetModule(PyObject *name); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); +PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(struct _Py_Identifier *name); +PyAPI_FUNC(PyObject *) _PyImport_AddModuleObject(PyObject *name, + PyObject *modules); +PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); +PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyImport_AddModuleObject( + PyObject *name + ); +#endif +PyAPI_FUNC(PyObject *) PyImport_AddModule( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyImport_ImportModule( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel( + const char *name, /* UTF-8 encoded string */ + PyObject *globals, + PyObject *locals, + PyObject *fromlist, + int level + ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject( + PyObject *name, + PyObject *globals, + PyObject *locals, + PyObject *fromlist, + int level + ); +#endif + +#define PyImport_ImportModuleEx(n, g, l, f) \ + PyImport_ImportModuleLevel(n, g, l, f, 0) + +PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); +PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); +PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); +PyAPI_FUNC(void) PyImport_Cleanup(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(int) PyImport_ImportFrozenModuleObject( + PyObject *name + ); +#endif +PyAPI_FUNC(int) PyImport_ImportFrozenModule( + const char *name /* UTF-8 encoded string */ + ); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyImport_AcquireLock(void); +PyAPI_FUNC(int) _PyImport_ReleaseLock(void); + +PyAPI_FUNC(void) _PyImport_ReInitLock(void); + +PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( + const char *name, /* UTF-8 encoded string */ + PyObject *modules + ); +PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObjectEx(PyObject *, PyObject *, + PyObject *); +PyAPI_FUNC(int) _PyImport_FixupBuiltin( + PyObject *mod, + const char *name, /* UTF-8 encoded string */ + PyObject *modules + ); +PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *, + PyObject *, PyObject *); + +struct _inittab { + const char *name; /* ASCII encoded string */ + PyObject* (*initfunc)(void); +}; +PyAPI_DATA(struct _inittab *) PyImport_Inittab; +PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); +#endif /* Py_LIMITED_API */ + +PyAPI_DATA(PyTypeObject) PyNullImporter_Type; + +PyAPI_FUNC(int) PyImport_AppendInittab( + const char *name, /* ASCII encoded string */ + PyObject* (*initfunc)(void) + ); + +#ifndef Py_LIMITED_API +struct _frozen { + const char *name; /* ASCII encoded string */ + const unsigned char *code; + int size; +}; + +/* Embedding apps may change this pointer to point to their favorite + collection of frozen modules: */ + +PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_IMPORT_H */ diff --git a/python/include/internal/pycore_accu.h b/python/include/internal/pycore_accu.h new file mode 100755 index 0000000..d346222 --- /dev/null +++ b/python/include/internal/pycore_accu.h @@ -0,0 +1,39 @@ +#ifndef Py_LIMITED_API +#ifndef Py_INTERNAL_ACCU_H +#define Py_INTERNAL_ACCU_H +#ifdef __cplusplus +extern "C" { +#endif + +/*** This is a private API for use by the interpreter and the stdlib. + *** Its definition may be changed or removed at any moment. + ***/ + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* + * A two-level accumulator of unicode objects that avoids both the overhead + * of keeping a huge number of small separate objects, and the quadratic + * behaviour of using a naive repeated concatenation scheme. + */ + +#undef small /* defined by some Windows headers */ + +typedef struct { + PyObject *large; /* A list of previously accumulated large strings */ + PyObject *small; /* Pending small strings */ +} _PyAccu; + +PyAPI_FUNC(int) _PyAccu_Init(_PyAccu *acc); +PyAPI_FUNC(int) _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode); +PyAPI_FUNC(PyObject *) _PyAccu_FinishAsList(_PyAccu *acc); +PyAPI_FUNC(PyObject *) _PyAccu_Finish(_PyAccu *acc); +PyAPI_FUNC(void) _PyAccu_Destroy(_PyAccu *acc); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_ACCU_H */ +#endif /* !Py_LIMITED_API */ diff --git a/python/include/internal/pycore_atomic.h b/python/include/internal/pycore_atomic.h new file mode 100755 index 0000000..336bc3f --- /dev/null +++ b/python/include/internal/pycore_atomic.h @@ -0,0 +1,558 @@ +#ifndef Py_ATOMIC_H +#define Py_ATOMIC_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "dynamic_annotations.h" + +#include "pyconfig.h" + +#if defined(HAVE_STD_ATOMIC) +#include +#endif + + +#if defined(_MSC_VER) +#include +#if defined(_M_IX86) || defined(_M_X64) +# include +#endif +#endif + +/* This is modeled after the atomics interface from C1x, according to + * the draft at + * http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf. + * Operations and types are named the same except with a _Py_ prefix + * and have the same semantics. + * + * Beware, the implementations here are deep magic. + */ + +#if defined(HAVE_STD_ATOMIC) + +typedef enum _Py_memory_order { + _Py_memory_order_relaxed = memory_order_relaxed, + _Py_memory_order_acquire = memory_order_acquire, + _Py_memory_order_release = memory_order_release, + _Py_memory_order_acq_rel = memory_order_acq_rel, + _Py_memory_order_seq_cst = memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + atomic_uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + atomic_int _value; +} _Py_atomic_int; + +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ + atomic_signal_fence(ORDER) + +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ + atomic_thread_fence(ORDER) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + atomic_store_explicit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER) + +/* Use builtin atomic operations in GCC >= 4.7 */ +#elif defined(HAVE_BUILTIN_ATOMIC) + +typedef enum _Py_memory_order { + _Py_memory_order_relaxed = __ATOMIC_RELAXED, + _Py_memory_order_acquire = __ATOMIC_ACQUIRE, + _Py_memory_order_release = __ATOMIC_RELEASE, + _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL, + _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST +} _Py_memory_order; + +typedef struct _Py_atomic_address { + uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + int _value; +} _Py_atomic_int; + +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ + __atomic_signal_fence(ORDER) + +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ + __atomic_thread_fence(ORDER) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + (assert((ORDER) == __ATOMIC_RELAXED \ + || (ORDER) == __ATOMIC_SEQ_CST \ + || (ORDER) == __ATOMIC_RELEASE), \ + __atomic_store_n(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER)) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + (assert((ORDER) == __ATOMIC_RELAXED \ + || (ORDER) == __ATOMIC_SEQ_CST \ + || (ORDER) == __ATOMIC_ACQUIRE \ + || (ORDER) == __ATOMIC_CONSUME), \ + __atomic_load_n(&((ATOMIC_VAL)->_value), ORDER)) + +/* Only support GCC (for expression statements) and x86 (for simple + * atomic semantics) and MSVC x86/x64/ARM */ +#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64)) +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + int _value; +} _Py_atomic_int; + + +static __inline__ void +_Py_atomic_signal_fence(_Py_memory_order order) +{ + if (order != _Py_memory_order_relaxed) + __asm__ volatile("":::"memory"); +} + +static __inline__ void +_Py_atomic_thread_fence(_Py_memory_order order) +{ + if (order != _Py_memory_order_relaxed) + __asm__ volatile("mfence":::"memory"); +} + +/* Tell the race checker about this operation's effects. */ +static __inline__ void +_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) +{ + (void)address; /* shut up -Wunused-parameter */ + switch(order) { + case _Py_memory_order_release: + case _Py_memory_order_acq_rel: + case _Py_memory_order_seq_cst: + _Py_ANNOTATE_HAPPENS_BEFORE(address); + break; + case _Py_memory_order_relaxed: + case _Py_memory_order_acquire: + break; + } + switch(order) { + case _Py_memory_order_acquire: + case _Py_memory_order_acq_rel: + case _Py_memory_order_seq_cst: + _Py_ANNOTATE_HAPPENS_AFTER(address); + break; + case _Py_memory_order_relaxed: + case _Py_memory_order_release: + break; + } +} + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + __extension__ ({ \ + __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ + __typeof__(atomic_val->_value) new_val = NEW_VAL;\ + volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \ + _Py_memory_order order = ORDER; \ + _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ + \ + /* Perform the operation. */ \ + _Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \ + switch(order) { \ + case _Py_memory_order_release: \ + _Py_atomic_signal_fence(_Py_memory_order_release); \ + /* fallthrough */ \ + case _Py_memory_order_relaxed: \ + *volatile_data = new_val; \ + break; \ + \ + case _Py_memory_order_acquire: \ + case _Py_memory_order_acq_rel: \ + case _Py_memory_order_seq_cst: \ + __asm__ volatile("xchg %0, %1" \ + : "+r"(new_val) \ + : "m"(atomic_val->_value) \ + : "memory"); \ + break; \ + } \ + _Py_ANNOTATE_IGNORE_WRITES_END(); \ + }) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + __extension__ ({ \ + __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ + __typeof__(atomic_val->_value) result; \ + volatile __typeof__(result) *volatile_data = &atomic_val->_value; \ + _Py_memory_order order = ORDER; \ + _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ + \ + /* Perform the operation. */ \ + _Py_ANNOTATE_IGNORE_READS_BEGIN(); \ + switch(order) { \ + case _Py_memory_order_release: \ + case _Py_memory_order_acq_rel: \ + case _Py_memory_order_seq_cst: \ + /* Loads on x86 are not releases by default, so need a */ \ + /* thread fence. */ \ + _Py_atomic_thread_fence(_Py_memory_order_release); \ + break; \ + default: \ + /* No fence */ \ + break; \ + } \ + result = *volatile_data; \ + switch(order) { \ + case _Py_memory_order_acquire: \ + case _Py_memory_order_acq_rel: \ + case _Py_memory_order_seq_cst: \ + /* Loads on x86 are automatically acquire operations so */ \ + /* can get by with just a compiler fence. */ \ + _Py_atomic_signal_fence(_Py_memory_order_acquire); \ + break; \ + default: \ + /* No fence */ \ + break; \ + } \ + _Py_ANNOTATE_IGNORE_READS_END(); \ + result; \ + }) + +#elif defined(_MSC_VER) +/* _Interlocked* functions provide a full memory barrier and are therefore + enough for acq_rel and seq_cst. If the HLE variants aren't available + in hardware they will fall back to a full memory barrier as well. + + This might affect performance but likely only in some very specific and + hard to meassure scenario. +*/ +#if defined(_M_IX86) || defined(_M_X64) +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + volatile uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + volatile int _value; +} _Py_atomic_int; + + +#if defined(_M_X64) +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ + break; \ + default: \ + _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ + break; \ + } +#else +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); +#endif + +#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ + break; \ + default: \ + _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ + break; \ + } + +#if defined(_M_X64) +/* This has to be an intptr_t for now. + gil_created() uses -1 as a sentinel value, if this returns + a uintptr_t it will do an unsigned compare and crash +*/ +inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { + __int64 old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old); + break; + } + } + return old; +} + +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) + +#else +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) +#endif + +inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { + long old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange((volatile long*)value, old, old) != old); + break; + } + } + return old; +} + +#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + if (sizeof((ATOMIC_VAL)->_value) == 8) { \ + _Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \ + _Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) } + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + ( \ + sizeof((ATOMIC_VAL)->_value) == 8 ? \ + _Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \ + _Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \ + ) +#elif defined(_M_ARM) || defined(_M_ARM64) +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + volatile uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + volatile int _value; +} _Py_atomic_int; + + +#if defined(_M_ARM64) +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange64_acq((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange64_rel((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ + break; \ + default: \ + _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ + break; \ + } +#else +#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); +#endif + +#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ + switch (ORDER) { \ + case _Py_memory_order_acquire: \ + _InterlockedExchange_acq((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ + break; \ + case _Py_memory_order_release: \ + _InterlockedExchange_rel((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ + break; \ + default: \ + _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ + break; \ + } + +#if defined(_M_ARM64) +/* This has to be an intptr_t for now. + gil_created() uses -1 as a sentinel value, if this returns + a uintptr_t it will do an unsigned compare and crash +*/ +inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { + uintptr_t old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_acq(value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange64_rel(value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange64(value, old, old) != old); + break; + } + } + return old; +} + +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) + +#else +#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) +#endif + +inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { + int old; + switch (order) { + case _Py_memory_order_acquire: + { + do { + old = *value; + } while(_InterlockedCompareExchange_acq(value, old, old) != old); + break; + } + case _Py_memory_order_release: + { + do { + old = *value; + } while(_InterlockedCompareExchange_rel(value, old, old) != old); + break; + } + case _Py_memory_order_relaxed: + old = *value; + break; + default: + { + do { + old = *value; + } while(_InterlockedCompareExchange(value, old, old) != old); + break; + } + } + return old; +} + +#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ + _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + if (sizeof((ATOMIC_VAL)->_value) == 8) { \ + _Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \ + _Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + ( \ + sizeof((ATOMIC_VAL)->_value) == 8 ? \ + _Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \ + _Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \ + ) +#endif +#else /* !gcc x86 !_msc_ver */ +typedef enum _Py_memory_order { + _Py_memory_order_relaxed, + _Py_memory_order_acquire, + _Py_memory_order_release, + _Py_memory_order_acq_rel, + _Py_memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + uintptr_t _value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + int _value; +} _Py_atomic_int; +/* Fall back to other compilers and processors by assuming that simple + volatile accesses are atomic. This is false, so people should port + this. */ +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0) +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0) +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + ((ATOMIC_VAL)->_value = NEW_VAL) +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + ((ATOMIC_VAL)->_value) +#endif + +/* Standardized shortcuts. */ +#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ + _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst) +#define _Py_atomic_load(ATOMIC_VAL) \ + _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst) + +/* Python-local extensions */ + +#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \ + _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed) +#define _Py_atomic_load_relaxed(ATOMIC_VAL) \ + _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed) + +#ifdef __cplusplus +} +#endif +#endif /* Py_ATOMIC_H */ diff --git a/python/include/internal/pycore_ceval.h b/python/include/internal/pycore_ceval.h new file mode 100755 index 0000000..4c1c0e2 --- /dev/null +++ b/python/include/internal/pycore_ceval.h @@ -0,0 +1,37 @@ +#ifndef Py_INTERNAL_CEVAL_H +#define Py_INTERNAL_CEVAL_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_atomic.h" +#include "pycore_pystate.h" +#include "pythread.h" + +PyAPI_FUNC(void) _Py_FinishPendingCalls(_PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *); +PyAPI_FUNC(void) _PyEval_FiniThreads( + struct _ceval_runtime_state *ceval); +PyAPI_FUNC(void) _PyEval_SignalReceived( + struct _ceval_runtime_state *ceval); +PyAPI_FUNC(int) _PyEval_AddPendingCall( + PyThreadState *tstate, + struct _ceval_runtime_state *ceval, + int (*func)(void *), + void *arg); +PyAPI_FUNC(void) _PyEval_SignalAsyncExc( + struct _ceval_runtime_state *ceval); +PyAPI_FUNC(void) _PyEval_ReInitThreads( + _PyRuntimeState *runtime); + +/* Private function */ +void _PyEval_Fini(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CEVAL_H */ diff --git a/python/include/internal/pycore_code.h b/python/include/internal/pycore_code.h new file mode 100755 index 0000000..88956f1 --- /dev/null +++ b/python/include/internal/pycore_code.h @@ -0,0 +1,27 @@ +#ifndef Py_INTERNAL_CODE_H +#define Py_INTERNAL_CODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject *ptr; /* Cached pointer (borrowed reference) */ + uint64_t globals_ver; /* ma_version of global dict */ + uint64_t builtins_ver; /* ma_version of builtin dict */ +} _PyOpcache_LoadGlobal; + +struct _PyOpcache { + union { + _PyOpcache_LoadGlobal lg; + } u; + char optimized; +}; + +/* Private API */ +int _PyCode_InitOpcache(PyCodeObject *co); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CODE_H */ diff --git a/python/include/internal/pycore_condvar.h b/python/include/internal/pycore_condvar.h new file mode 100755 index 0000000..8b89d70 --- /dev/null +++ b/python/include/internal/pycore_condvar.h @@ -0,0 +1,95 @@ +#ifndef Py_INTERNAL_CONDVAR_H +#define Py_INTERNAL_CONDVAR_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#ifndef _POSIX_THREADS +/* This means pthreads are not implemented in libc headers, hence the macro + not present in unistd.h. But they still can be implemented as an external + library (e.g. gnu pth in pthread emulation) */ +# ifdef HAVE_PTHREAD_H +# include /* _POSIX_THREADS */ +# endif +#endif + +#ifdef _POSIX_THREADS +/* + * POSIX support + */ +#define Py_HAVE_CONDVAR + +#include + +#define PyMUTEX_T pthread_mutex_t +#define PyCOND_T pthread_cond_t + +#elif defined(NT_THREADS) +/* + * Windows (XP, 2003 server and later, as well as (hopefully) CE) support + * + * Emulated condition variables ones that work with XP and later, plus + * example native support on VISTA and onwards. + */ +#define Py_HAVE_CONDVAR + +/* include windows if it hasn't been done before */ +#define WIN32_LEAN_AND_MEAN +#include + +/* options */ +/* non-emulated condition variables are provided for those that want + * to target Windows Vista. Modify this macro to enable them. + */ +#ifndef _PY_EMULATED_WIN_CV +#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */ +#endif + +/* fall back to emulation if not targeting Vista */ +#if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA +#undef _PY_EMULATED_WIN_CV +#define _PY_EMULATED_WIN_CV 1 +#endif + +#if _PY_EMULATED_WIN_CV + +typedef CRITICAL_SECTION PyMUTEX_T; + +/* The ConditionVariable object. From XP onwards it is easily emulated + with a Semaphore. + Semaphores are available on Windows XP (2003 server) and later. + We use a Semaphore rather than an auto-reset event, because although + an auto-resent event might appear to solve the lost-wakeup bug (race + condition between releasing the outer lock and waiting) because it + maintains state even though a wait hasn't happened, there is still + a lost wakeup problem if more than one thread are interrupted in the + critical place. A semaphore solves that, because its state is + counted, not Boolean. + Because it is ok to signal a condition variable with no one + waiting, we need to keep track of the number of + waiting threads. Otherwise, the semaphore's state could rise + without bound. This also helps reduce the number of "spurious wakeups" + that would otherwise happen. + */ + +typedef struct _PyCOND_T +{ + HANDLE sem; + int waiting; /* to allow PyCOND_SIGNAL to be a no-op */ +} PyCOND_T; + +#else /* !_PY_EMULATED_WIN_CV */ + +/* Use native Win7 primitives if build target is Win7 or higher */ + +/* SRWLOCK is faster and better than CriticalSection */ +typedef SRWLOCK PyMUTEX_T; + +typedef CONDITION_VARIABLE PyCOND_T; + +#endif /* _PY_EMULATED_WIN_CV */ + +#endif /* _POSIX_THREADS, NT_THREADS */ + +#endif /* Py_INTERNAL_CONDVAR_H */ diff --git a/python/include/internal/pycore_context.h b/python/include/internal/pycore_context.h new file mode 100755 index 0000000..5e1ba0d --- /dev/null +++ b/python/include/internal/pycore_context.h @@ -0,0 +1,42 @@ +#ifndef Py_INTERNAL_CONTEXT_H +#define Py_INTERNAL_CONTEXT_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_hamt.h" + +struct _pycontextobject { + PyObject_HEAD + PyContext *ctx_prev; + PyHamtObject *ctx_vars; + PyObject *ctx_weakreflist; + int ctx_entered; +}; + + +struct _pycontextvarobject { + PyObject_HEAD + PyObject *var_name; + PyObject *var_default; + PyObject *var_cached; + uint64_t var_cached_tsid; + uint64_t var_cached_tsver; + Py_hash_t var_hash; +}; + + +struct _pycontexttokenobject { + PyObject_HEAD + PyContext *tok_ctx; + PyContextVar *tok_var; + PyObject *tok_oldval; + int tok_used; +}; + + +int _PyContext_Init(void); +void _PyContext_Fini(void); + +#endif /* !Py_INTERNAL_CONTEXT_H */ diff --git a/python/include/internal/pycore_fileutils.h b/python/include/internal/pycore_fileutils.h new file mode 100755 index 0000000..bbee586 --- /dev/null +++ b/python/include/internal/pycore_fileutils.h @@ -0,0 +1,54 @@ +#ifndef Py_INTERNAL_FILEUTILS_H +#define Py_INTERNAL_FILEUTILS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "Py_BUILD_CORE must be defined to include this header" +#endif + +#include /* struct lconv */ + +PyAPI_DATA(int) _Py_HasFileSystemDefaultEncodeErrors; + +PyAPI_FUNC(int) _Py_DecodeUTF8Ex( + const char *arg, + Py_ssize_t arglen, + wchar_t **wstr, + size_t *wlen, + const char **reason, + _Py_error_handler errors); + +PyAPI_FUNC(int) _Py_EncodeUTF8Ex( + const wchar_t *text, + char **str, + size_t *error_pos, + const char **reason, + int raw_malloc, + _Py_error_handler errors); + +PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape( + const char *arg, + Py_ssize_t arglen, + size_t *wlen); + +PyAPI_FUNC(int) _Py_GetForceASCII(void); + +/* Reset "force ASCII" mode (if it was initialized). + + This function should be called when Python changes the LC_CTYPE locale, + so the "force ASCII" mode can be detected again on the new locale + encoding. */ +PyAPI_FUNC(void) _Py_ResetForceASCII(void); + + +PyAPI_FUNC(int) _Py_GetLocaleconvNumeric( + struct lconv *lc, + PyObject **decimal_point, + PyObject **thousands_sep); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_FILEUTILS_H */ diff --git a/python/include/internal/pycore_getopt.h b/python/include/internal/pycore_getopt.h new file mode 100755 index 0000000..7f0dd13 --- /dev/null +++ b/python/include/internal/pycore_getopt.h @@ -0,0 +1,22 @@ +#ifndef Py_INTERNAL_PYGETOPT_H +#define Py_INTERNAL_PYGETOPT_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +extern int _PyOS_opterr; +extern Py_ssize_t _PyOS_optind; +extern const wchar_t *_PyOS_optarg; + +extern void _PyOS_ResetGetOpt(void); + +typedef struct { + const wchar_t *name; + int has_arg; + int val; +} _PyOS_LongOption; + +extern int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex); + +#endif /* !Py_INTERNAL_PYGETOPT_H */ diff --git a/python/include/internal/pycore_gil.h b/python/include/internal/pycore_gil.h new file mode 100755 index 0000000..7de3163 --- /dev/null +++ b/python/include/internal/pycore_gil.h @@ -0,0 +1,50 @@ +#ifndef Py_INTERNAL_GIL_H +#define Py_INTERNAL_GIL_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_condvar.h" +#include "pycore_atomic.h" + +#ifndef Py_HAVE_CONDVAR +# error You need either a POSIX-compatible or a Windows system! +#endif + +/* Enable if you want to force the switching of threads at least + every `interval`. */ +#undef FORCE_SWITCHING +#define FORCE_SWITCHING + +struct _gil_runtime_state { + /* microseconds (the Python API uses seconds, though) */ + unsigned long interval; + /* Last PyThreadState holding / having held the GIL. This helps us + know whether anyone else was scheduled after we dropped the GIL. */ + _Py_atomic_address last_holder; + /* Whether the GIL is already taken (-1 if uninitialized). This is + atomic because it can be read without any lock taken in ceval.c. */ + _Py_atomic_int locked; + /* Number of GIL switches since the beginning. */ + unsigned long switch_number; + /* This condition variable allows one or several threads to wait + until the GIL is released. In addition, the mutex also protects + the above variables. */ + PyCOND_T cond; + PyMUTEX_T mutex; +#ifdef FORCE_SWITCHING + /* This condition variable helps the GIL-releasing thread wait for + a GIL-awaiting thread to be scheduled and take the GIL. */ + PyCOND_T switch_cond; + PyMUTEX_T switch_mutex; +#endif +}; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_GIL_H */ diff --git a/python/include/internal/pycore_hamt.h b/python/include/internal/pycore_hamt.h new file mode 100755 index 0000000..e65aef5 --- /dev/null +++ b/python/include/internal/pycore_hamt.h @@ -0,0 +1,116 @@ +#ifndef Py_INTERNAL_HAMT_H +#define Py_INTERNAL_HAMT_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#define _Py_HAMT_MAX_TREE_DEPTH 7 + + +#define PyHamt_Check(o) (Py_TYPE(o) == &_PyHamt_Type) + + +/* Abstract tree node. */ +typedef struct { + PyObject_HEAD +} PyHamtNode; + + +/* An HAMT immutable mapping collection. */ +typedef struct { + PyObject_HEAD + PyHamtNode *h_root; + PyObject *h_weakreflist; + Py_ssize_t h_count; +} PyHamtObject; + + +/* A struct to hold the state of depth-first traverse of the tree. + + HAMT is an immutable collection. Iterators will hold a strong reference + to it, and every node in the HAMT has strong references to its children. + + So for iterators, we can implement zero allocations and zero reference + inc/dec depth-first iteration. + + - i_nodes: an array of seven pointers to tree nodes + - i_level: the current node in i_nodes + - i_pos: an array of positions within nodes in i_nodes. +*/ +typedef struct { + PyHamtNode *i_nodes[_Py_HAMT_MAX_TREE_DEPTH]; + Py_ssize_t i_pos[_Py_HAMT_MAX_TREE_DEPTH]; + int8_t i_level; +} PyHamtIteratorState; + + +/* Base iterator object. + + Contains the iteration state, a pointer to the HAMT tree, + and a pointer to the 'yield function'. The latter is a simple + function that returns a key/value tuple for the 'Items' iterator, + just a key for the 'Keys' iterator, and a value for the 'Values' + iterator. +*/ +typedef struct { + PyObject_HEAD + PyHamtObject *hi_obj; + PyHamtIteratorState hi_iter; + binaryfunc hi_yield; +} PyHamtIterator; + + +PyAPI_DATA(PyTypeObject) _PyHamt_Type; +PyAPI_DATA(PyTypeObject) _PyHamt_ArrayNode_Type; +PyAPI_DATA(PyTypeObject) _PyHamt_BitmapNode_Type; +PyAPI_DATA(PyTypeObject) _PyHamt_CollisionNode_Type; +PyAPI_DATA(PyTypeObject) _PyHamtKeys_Type; +PyAPI_DATA(PyTypeObject) _PyHamtValues_Type; +PyAPI_DATA(PyTypeObject) _PyHamtItems_Type; + + +/* Create a new HAMT immutable mapping. */ +PyHamtObject * _PyHamt_New(void); + +/* Return a new collection based on "o", but with an additional + key/val pair. */ +PyHamtObject * _PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val); + +/* Return a new collection based on "o", but without "key". */ +PyHamtObject * _PyHamt_Without(PyHamtObject *o, PyObject *key); + +/* Find "key" in the "o" collection. + + Return: + - -1: An error occurred. + - 0: "key" wasn't found in "o". + - 1: "key" is in "o"; "*val" is set to its value (a borrowed ref). +*/ +int _PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val); + +/* Check if "v" is equal to "w". + + Return: + - 0: v != w + - 1: v == w + - -1: An error occurred. +*/ +int _PyHamt_Eq(PyHamtObject *v, PyHamtObject *w); + +/* Return the size of "o"; equivalent of "len(o)". */ +Py_ssize_t _PyHamt_Len(PyHamtObject *o); + +/* Return a Keys iterator over "o". */ +PyObject * _PyHamt_NewIterKeys(PyHamtObject *o); + +/* Return a Values iterator over "o". */ +PyObject * _PyHamt_NewIterValues(PyHamtObject *o); + +/* Return a Items iterator over "o". */ +PyObject * _PyHamt_NewIterItems(PyHamtObject *o); + +int _PyHamt_Init(void); +void _PyHamt_Fini(void); + +#endif /* !Py_INTERNAL_HAMT_H */ diff --git a/python/include/internal/pycore_initconfig.h b/python/include/internal/pycore_initconfig.h new file mode 100755 index 0000000..40831c4 --- /dev/null +++ b/python/include/internal/pycore_initconfig.h @@ -0,0 +1,166 @@ +#ifndef Py_INTERNAL_CORECONFIG_H +#define Py_INTERNAL_CORECONFIG_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pystate.h" /* _PyRuntimeState */ + +/* --- PyStatus ----------------------------------------------- */ + +/* Almost all errors causing Python initialization to fail */ +#ifdef _MSC_VER + /* Visual Studio 2015 doesn't implement C99 __func__ in C */ +# define _PyStatus_GET_FUNC() __FUNCTION__ +#else +# define _PyStatus_GET_FUNC() __func__ +#endif + +#define _PyStatus_OK() \ + (PyStatus){._type = _PyStatus_TYPE_OK,} + /* other fields are set to 0 */ +#define _PyStatus_ERR(ERR_MSG) \ + (PyStatus){ \ + ._type = _PyStatus_TYPE_ERROR, \ + .func = _PyStatus_GET_FUNC(), \ + .err_msg = (ERR_MSG)} + /* other fields are set to 0 */ +#define _PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed") +#define _PyStatus_EXIT(EXITCODE) \ + (PyStatus){ \ + ._type = _PyStatus_TYPE_EXIT, \ + .exitcode = (EXITCODE)} +#define _PyStatus_IS_ERROR(err) \ + (err._type == _PyStatus_TYPE_ERROR) +#define _PyStatus_IS_EXIT(err) \ + (err._type == _PyStatus_TYPE_EXIT) +#define _PyStatus_EXCEPTION(err) \ + (err._type != _PyStatus_TYPE_OK) +#define _PyStatus_UPDATE_FUNC(err) \ + do { err.func = _PyStatus_GET_FUNC(); } while (0) + +/* --- PyWideStringList ------------------------------------------------ */ + +#define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL} + +#ifndef NDEBUG +PyAPI_FUNC(int) _PyWideStringList_CheckConsistency(const PyWideStringList *list); +#endif +PyAPI_FUNC(void) _PyWideStringList_Clear(PyWideStringList *list); +PyAPI_FUNC(int) _PyWideStringList_Copy(PyWideStringList *list, + const PyWideStringList *list2); +PyAPI_FUNC(PyStatus) _PyWideStringList_Extend(PyWideStringList *list, + const PyWideStringList *list2); +PyAPI_FUNC(PyObject*) _PyWideStringList_AsList(const PyWideStringList *list); + + +/* --- _PyArgv ---------------------------------------------------- */ + +typedef struct { + Py_ssize_t argc; + int use_bytes_argv; + char * const *bytes_argv; + wchar_t * const *wchar_argv; +} _PyArgv; + +PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args, + PyWideStringList *list); + + +/* --- Helper functions ------------------------------------------- */ + +PyAPI_FUNC(int) _Py_str_to_int( + const char *str, + int *result); +PyAPI_FUNC(const wchar_t*) _Py_get_xoption( + const PyWideStringList *xoptions, + const wchar_t *name); +PyAPI_FUNC(const char*) _Py_GetEnv( + int use_environment, + const char *name); +PyAPI_FUNC(void) _Py_get_env_flag( + int use_environment, + int *flag, + const char *name); + +/* Py_GetArgcArgv() helper */ +PyAPI_FUNC(void) _Py_ClearArgcArgv(void); + + +/* --- _PyPreCmdline ------------------------------------------------- */ + +typedef struct { + PyWideStringList argv; + PyWideStringList xoptions; /* "-X value" option */ + int isolated; /* -I option */ + int use_environment; /* -E option */ + int dev_mode; /* -X dev and PYTHONDEVMODE */ +} _PyPreCmdline; + +#define _PyPreCmdline_INIT \ + (_PyPreCmdline){ \ + .use_environment = -1, \ + .isolated = -1, \ + .dev_mode = -1} +/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */ + +extern void _PyPreCmdline_Clear(_PyPreCmdline *cmdline); +extern PyStatus _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, + const _PyArgv *args); +extern PyStatus _PyPreCmdline_SetConfig( + const _PyPreCmdline *cmdline, + PyConfig *config); +extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline, + const PyPreConfig *preconfig); + + +/* --- PyPreConfig ----------------------------------------------- */ + +PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig); +extern void _PyPreConfig_InitFromConfig( + PyPreConfig *preconfig, + const PyConfig *config); +extern PyStatus _PyPreConfig_InitFromPreConfig( + PyPreConfig *preconfig, + const PyPreConfig *config2); +extern PyObject* _PyPreConfig_AsDict(const PyPreConfig *preconfig); +extern void _PyPreConfig_GetConfig(PyPreConfig *preconfig, + const PyConfig *config); +extern PyStatus _PyPreConfig_Read(PyPreConfig *preconfig, + const _PyArgv *args); +extern PyStatus _PyPreConfig_Write(const PyPreConfig *preconfig); + + +/* --- PyConfig ---------------------------------------------- */ + +typedef enum { + /* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */ + _PyConfig_INIT_COMPAT = 1, + _PyConfig_INIT_PYTHON = 2, + _PyConfig_INIT_ISOLATED = 3 +} _PyConfigInitEnum; + +PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config); +extern PyStatus _PyConfig_Copy( + PyConfig *config, + const PyConfig *config2); +extern PyStatus _PyConfig_InitPathConfig(PyConfig *config); +extern void _PyConfig_Write(const PyConfig *config, + _PyRuntimeState *runtime); +extern PyStatus _PyConfig_SetPyArgv( + PyConfig *config, + const _PyArgv *args); + + +/* --- Function used for testing ---------------------------------- */ + +PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CORECONFIG_H */ diff --git a/python/include/internal/pycore_object.h b/python/include/internal/pycore_object.h new file mode 100755 index 0000000..7418c69 --- /dev/null +++ b/python/include/internal/pycore_object.h @@ -0,0 +1,81 @@ +#ifndef Py_INTERNAL_OBJECT_H +#define Py_INTERNAL_OBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pystate.h" /* _PyRuntime */ + +PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); +PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); + +/* Tell the GC to track this object. + * + * NB: While the object is tracked by the collector, it must be safe to call the + * ob_traverse method. + * + * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags + * because it's not object header. So we don't use _PyGCHead_PREV() and + * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. + * + * The PyObject_GC_Track() function is the public version of this macro. + */ +static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, + PyObject *op) +{ + _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op), + "object already tracked by the garbage collector", + filename, lineno, "_PyObject_GC_TRACK"); + + PyGC_Head *gc = _Py_AS_GC(op); + _PyObject_ASSERT_FROM(op, + (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0, + "object is in generation which is garbage collected", + filename, lineno, "_PyObject_GC_TRACK"); + + PyGC_Head *last = (PyGC_Head*)(_PyRuntime.gc.generation0->_gc_prev); + _PyGCHead_SET_NEXT(last, gc); + _PyGCHead_SET_PREV(gc, last); + _PyGCHead_SET_NEXT(gc, _PyRuntime.gc.generation0); + _PyRuntime.gc.generation0->_gc_prev = (uintptr_t)gc; +} + +#define _PyObject_GC_TRACK(op) \ + _PyObject_GC_TRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) + +/* Tell the GC to stop tracking this object. + * + * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING + * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept. + * + * The object must be tracked by the GC. + * + * The PyObject_GC_UnTrack() function is the public version of this macro. + */ +static inline void _PyObject_GC_UNTRACK_impl(const char *filename, int lineno, + PyObject *op) +{ + _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op), + "object not tracked by the garbage collector", + filename, lineno, "_PyObject_GC_UNTRACK"); + + PyGC_Head *gc = _Py_AS_GC(op); + PyGC_Head *prev = _PyGCHead_PREV(gc); + PyGC_Head *next = _PyGCHead_NEXT(gc); + _PyGCHead_SET_NEXT(prev, next); + _PyGCHead_SET_PREV(next, prev); + gc->_gc_next = 0; + gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; +} + +#define _PyObject_GC_UNTRACK(op) \ + _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_OBJECT_H */ diff --git a/python/include/internal/pycore_pathconfig.h b/python/include/internal/pycore_pathconfig.h new file mode 100755 index 0000000..ce75cce --- /dev/null +++ b/python/include/internal/pycore_pathconfig.h @@ -0,0 +1,75 @@ +#ifndef Py_INTERNAL_PATHCONFIG_H +#define Py_INTERNAL_PATHCONFIG_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct _PyPathConfig { + /* Full path to the Python program */ + wchar_t *program_full_path; + wchar_t *prefix; + wchar_t *exec_prefix; + /* Set by Py_SetPath(), or computed by _PyConfig_InitPathConfig() */ + wchar_t *module_search_path; + /* Python program name */ + wchar_t *program_name; + /* Set by Py_SetPythonHome() or PYTHONHOME environment variable */ + wchar_t *home; +#ifdef MS_WINDOWS + /* isolated and site_import are used to set Py_IsolatedFlag and + Py_NoSiteFlag flags on Windows in read_pth_file(). These fields + are ignored when their value are equal to -1 (unset). */ + int isolated; + int site_import; + /* Set when a venv is detected */ + wchar_t *base_executable; +#endif +} _PyPathConfig; + +#ifdef MS_WINDOWS +# define _PyPathConfig_INIT \ + {.module_search_path = NULL, \ + .isolated = -1, \ + .site_import = -1} +#else +# define _PyPathConfig_INIT \ + {.module_search_path = NULL} +#endif +/* Note: _PyPathConfig_INIT sets other fields to 0/NULL */ + +PyAPI_DATA(_PyPathConfig) _Py_path_config; +#ifdef MS_WINDOWS +PyAPI_DATA(wchar_t*) _Py_dll_path; +#endif + +extern void _PyPathConfig_ClearGlobal(void); +extern PyStatus _PyPathConfig_SetGlobal( + const struct _PyPathConfig *pathconfig); + +extern PyStatus _PyPathConfig_Calculate( + _PyPathConfig *pathconfig, + const PyConfig *config); +extern int _PyPathConfig_ComputeSysPath0( + const PyWideStringList *argv, + PyObject **path0); +extern int _Py_FindEnvConfigValue( + FILE *env_file, + const wchar_t *key, + wchar_t *value, + size_t value_size); + +#ifdef MS_WINDOWS +extern wchar_t* _Py_GetDLLPath(void); +#endif + +extern PyStatus _PyConfig_WritePathConfig(const PyConfig *config); +extern void _Py_DumpPathConfig(PyThreadState *tstate); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PATHCONFIG_H */ diff --git a/python/include/internal/pycore_pyerrors.h b/python/include/internal/pycore_pyerrors.h new file mode 100755 index 0000000..23327ef --- /dev/null +++ b/python/include/internal/pycore_pyerrors.h @@ -0,0 +1,62 @@ +#ifndef Py_INTERNAL_PYERRORS_H +#define Py_INTERNAL_PYERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) +{ + return tstate == NULL ? NULL : tstate->curexc_type; +} + + +PyAPI_FUNC(void) _PyErr_Fetch( + PyThreadState *tstate, + PyObject **type, + PyObject **value, + PyObject **traceback); + +PyAPI_FUNC(int) _PyErr_ExceptionMatches( + PyThreadState *tstate, + PyObject *exc); + +PyAPI_FUNC(void) _PyErr_Restore( + PyThreadState *tstate, + PyObject *type, + PyObject *value, + PyObject *traceback); + +PyAPI_FUNC(void) _PyErr_SetObject( + PyThreadState *tstate, + PyObject *type, + PyObject *value); + +PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate); + +PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); + +PyAPI_FUNC(void) _PyErr_SetString( + PyThreadState *tstate, + PyObject *exception, + const char *string); + +PyAPI_FUNC(PyObject *) _PyErr_Format( + PyThreadState *tstate, + PyObject *exception, + const char *format, + ...); + +PyAPI_FUNC(void) _PyErr_NormalizeException( + PyThreadState *tstate, + PyObject **exc, + PyObject **val, + PyObject **tb); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYERRORS_H */ diff --git a/python/include/internal/pycore_pyhash.h b/python/include/internal/pycore_pyhash.h new file mode 100755 index 0000000..a229f8d --- /dev/null +++ b/python/include/internal/pycore_pyhash.h @@ -0,0 +1,10 @@ +#ifndef Py_INTERNAL_HASH_H +#define Py_INTERNAL_HASH_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); + +#endif diff --git a/python/include/internal/pycore_pylifecycle.h b/python/include/internal/pycore_pylifecycle.h new file mode 100755 index 0000000..c237b1d --- /dev/null +++ b/python/include/internal/pycore_pylifecycle.h @@ -0,0 +1,118 @@ +#ifndef Py_INTERNAL_LIFECYCLE_H +#define Py_INTERNAL_LIFECYCLE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_initconfig.h" /* _PyArgv */ +#include "pycore_pystate.h" /* _PyRuntimeState */ + +/* True if the main interpreter thread exited due to an unhandled + * KeyboardInterrupt exception, suggesting the user pressed ^C. */ +PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt; + +extern int _Py_SetFileSystemEncoding( + const char *encoding, + const char *errors); +extern void _Py_ClearFileSystemEncoding(void); +extern PyStatus _PyUnicode_InitEncodings(PyThreadState *tstate); +#ifdef MS_WINDOWS +extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void); +#endif + +PyAPI_FUNC(void) _Py_ClearStandardStreamEncoding(void); + +PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); + +/* Various one-time initializers */ + +extern PyStatus _PyUnicode_Init(void); +extern int _PyStructSequence_Init(void); +extern int _PyLong_Init(void); +extern PyStatus _PyFaulthandler_Init(int enable); +extern int _PyTraceMalloc_Init(int enable); +extern PyObject * _PyBuiltin_Init(void); +extern PyStatus _PySys_Create( + _PyRuntimeState *runtime, + PyInterpreterState *interp, + PyObject **sysmod_p); +extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); +extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); +extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); +extern int _PySys_InitMain( + _PyRuntimeState *runtime, + PyInterpreterState *interp); +extern PyStatus _PyImport_Init(PyInterpreterState *interp); +extern PyStatus _PyExc_Init(void); +extern PyStatus _PyErr_Init(void); +extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod); +extern PyStatus _PyImportHooks_Init(void); +extern int _PyFloat_Init(void); +extern PyStatus _Py_HashRandomization_Init(const PyConfig *); + +extern PyStatus _PyTypes_Init(void); +extern PyStatus _PyImportZip_Init(PyInterpreterState *interp); + + +/* Various internal finalizers */ + +extern void PyMethod_Fini(void); +extern void PyFrame_Fini(void); +extern void PyCFunction_Fini(void); +extern void PyDict_Fini(void); +extern void PyTuple_Fini(void); +extern void PyList_Fini(void); +extern void PySet_Fini(void); +extern void PyBytes_Fini(void); +extern void PyFloat_Fini(void); + +extern int _PySignal_Init(int install_signal_handlers); +extern void PyOS_FiniInterrupts(void); +extern void PySlice_Fini(void); +extern void PyAsyncGen_Fini(void); + +extern void _PyExc_Fini(void); +extern void _PyImport_Fini(void); +extern void _PyImport_Fini2(void); +extern void _PyGC_Fini(_PyRuntimeState *runtime); +extern void _PyType_Fini(void); +extern void _Py_HashRandomization_Fini(void); +extern void _PyUnicode_Fini(void); +extern void PyLong_Fini(void); +extern void _PyFaulthandler_Fini(void); +extern void _PyHash_Fini(void); +extern void _PyTraceMalloc_Fini(void); +extern void _PyWarnings_Fini(PyInterpreterState *interp); + +extern void _PyGILState_Init( + _PyRuntimeState *runtime, + PyInterpreterState *interp, + PyThreadState *tstate); +extern void _PyGILState_Fini(_PyRuntimeState *runtime); + +PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime); + +PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv( + const PyPreConfig *src_config, + const _PyArgv *args); +PyAPI_FUNC(PyStatus) _Py_PreInitializeFromConfig( + const PyConfig *config, + const _PyArgv *args); + + +PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p); + +PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); + +PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); +PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, + PyObject *value, PyObject *tb); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_LIFECYCLE_H */ diff --git a/python/include/internal/pycore_pymem.h b/python/include/internal/pycore_pymem.h new file mode 100755 index 0000000..47d092f --- /dev/null +++ b/python/include/internal/pycore_pymem.h @@ -0,0 +1,212 @@ +#ifndef Py_INTERNAL_PYMEM_H +#define Py_INTERNAL_PYMEM_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "objimpl.h" +#include "pymem.h" + + +/* GC runtime state */ + +/* If we change this, we need to change the default value in the + signature of gc.collect. */ +#define NUM_GENERATIONS 3 + +/* + NOTE: about the counting of long-lived objects. + + To limit the cost of garbage collection, there are two strategies; + - make each collection faster, e.g. by scanning fewer objects + - do less collections + This heuristic is about the latter strategy. + + In addition to the various configurable thresholds, we only trigger a + full collection if the ratio + long_lived_pending / long_lived_total + is above a given value (hardwired to 25%). + + The reason is that, while "non-full" collections (i.e., collections of + the young and middle generations) will always examine roughly the same + number of objects -- determined by the aforementioned thresholds --, + the cost of a full collection is proportional to the total number of + long-lived objects, which is virtually unbounded. + + Indeed, it has been remarked that doing a full collection every + of object creations entails a dramatic performance + degradation in workloads which consist in creating and storing lots of + long-lived objects (e.g. building a large list of GC-tracked objects would + show quadratic performance, instead of linear as expected: see issue #4074). + + Using the above ratio, instead, yields amortized linear performance in + the total number of objects (the effect of which can be summarized + thusly: "each full garbage collection is more and more costly as the + number of objects grows, but we do fewer and fewer of them"). + + 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 +*/ + +/* + NOTE: about untracking of mutable objects. + + Certain types of container cannot participate in a reference cycle, and + so do not need to be tracked by the garbage collector. Untracking these + objects reduces the cost of garbage collections. However, determining + which objects may be untracked is not free, and the costs must be + weighed against the benefits for garbage collection. + + There are two possible strategies for when to untrack a container: + + i) When the container is created. + ii) When the container is examined by the garbage collector. + + Tuples containing only immutable objects (integers, strings etc, and + recursively, tuples of immutable objects) do not need to be tracked. + The interpreter creates a large number of tuples, many of which will + not survive until garbage collection. It is therefore not worthwhile + to untrack eligible tuples at creation time. + + Instead, all tuples except the empty tuple are tracked when created. + During garbage collection it is determined whether any surviving tuples + can be untracked. A tuple can be untracked if all of its contents are + already not tracked. Tuples are examined for untracking in all garbage + collection cycles. It may take more than one cycle to untrack a tuple. + + Dictionaries containing only immutable objects also do not need to be + tracked. Dictionaries are untracked when created. If a tracked item is + inserted into a dictionary (either as a key or value), the dictionary + becomes tracked. During a full garbage collection (all generations), + the collector will untrack any dictionaries whose contents are not + tracked. + + The module provides the python function is_tracked(obj), which returns + the CURRENT tracking status of the object. Subsequent garbage + collections may change the tracking status of the object. + + Untracking of certain containers was introduced in issue #4688, and + the algorithm was refined in response to issue #14775. +*/ + +struct gc_generation { + PyGC_Head head; + int threshold; /* collection threshold */ + int count; /* count of allocations or collections of younger + generations */ +}; + +/* Running stats per generation */ +struct gc_generation_stats { + /* total number of collections */ + Py_ssize_t collections; + /* total number of collected objects */ + Py_ssize_t collected; + /* total number of uncollectable objects (put into gc.garbage) */ + Py_ssize_t uncollectable; +}; + +struct _gc_runtime_state { + /* List of objects that still need to be cleaned up, singly linked + * via their gc headers' gc_prev pointers. */ + PyObject *trash_delete_later; + /* Current call-stack depth of tp_dealloc calls. */ + int trash_delete_nesting; + + int enabled; + int debug; + /* linked lists of container objects */ + struct gc_generation generations[NUM_GENERATIONS]; + PyGC_Head *generation0; + /* a permanent generation which won't be collected */ + struct gc_generation permanent_generation; + struct gc_generation_stats generation_stats[NUM_GENERATIONS]; + /* true if we are currently running the collector */ + int collecting; + /* list of uncollectable objects */ + PyObject *garbage; + /* a list of callbacks to be invoked when collection is performed */ + PyObject *callbacks; + /* This is the number of objects that survived the last full + collection. It approximates the number of long lived objects + tracked by the GC. + + (by "full collection", we mean a collection of the oldest + generation). */ + Py_ssize_t long_lived_total; + /* This is the number of objects that survived all "non-full" + collections, and are awaiting to undergo a full collection for + the first time. */ + Py_ssize_t long_lived_pending; +}; + +PyAPI_FUNC(void) _PyGC_Initialize(struct _gc_runtime_state *); + + +/* Set the memory allocator of the specified domain to the default. + Save the old allocator into *old_alloc if it's non-NULL. + Return on success, or return -1 if the domain is unknown. */ +PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( + PyMemAllocatorDomain domain, + PyMemAllocatorEx *old_alloc); + +/* Special bytes broadcast into debug memory blocks at appropriate times. + Strings of these are unlikely to be valid addresses, floats, ints or + 7-bit ASCII. + + - PYMEM_CLEANBYTE: clean (newly allocated) memory + - PYMEM_DEADBYTE dead (newly freed) memory + - PYMEM_FORBIDDENBYTE: untouchable bytes at each end of a block + + Byte patterns 0xCB, 0xDB and 0xFB have been replaced with 0xCD, 0xDD and + 0xFD to use the same values than Windows CRT debug malloc() and free(). + If modified, _PyMem_IsPtrFreed() should be updated as well. */ +#define PYMEM_CLEANBYTE 0xCD +#define PYMEM_DEADBYTE 0xDD +#define PYMEM_FORBIDDENBYTE 0xFD + +/* Heuristic checking if a pointer value is newly allocated + (uninitialized), newly freed or NULL (is equal to zero). + + The pointer is not dereferenced, only the pointer value is checked. + + The heuristic relies on the debug hooks on Python memory allocators which + fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory + with DEADBYTE (0xDD). Detect also "untouchable bytes" marked + with FORBIDDENBYTE (0xFD). */ +static inline int _PyMem_IsPtrFreed(void *ptr) +{ + uintptr_t value = (uintptr_t)ptr; +#if SIZEOF_VOID_P == 8 + return (value == 0 + || value == (uintptr_t)0xCDCDCDCDCDCDCDCD + || value == (uintptr_t)0xDDDDDDDDDDDDDDDD + || value == (uintptr_t)0xFDFDFDFDFDFDFDFD); +#elif SIZEOF_VOID_P == 4 + return (value == 0 + || value == (uintptr_t)0xCDCDCDCD + || value == (uintptr_t)0xDDDDDDDD + || value == (uintptr_t)0xFDFDFDFD); +#else +# error "unknown pointer size" +#endif +} + +PyAPI_FUNC(int) _PyMem_GetAllocatorName( + const char *name, + PyMemAllocatorName *allocator); + +/* Configure the Python memory allocators. + Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators. + PYMEM_ALLOCATOR_NOT_SET does nothing. */ +PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYMEM_H */ diff --git a/python/include/internal/pycore_pystate.h b/python/include/internal/pycore_pystate.h new file mode 100755 index 0000000..1810533 --- /dev/null +++ b/python/include/internal/pycore_pystate.h @@ -0,0 +1,326 @@ +#ifndef Py_INTERNAL_PYSTATE_H +#define Py_INTERNAL_PYSTATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "cpython/initconfig.h" +#include "fileobject.h" +#include "pystate.h" +#include "pythread.h" +#include "sysmodule.h" + +#include "pycore_gil.h" /* _gil_runtime_state */ +#include "pycore_pathconfig.h" +#include "pycore_pymem.h" +#include "pycore_warnings.h" + + +/* ceval state */ + +struct _pending_calls { + int finishing; + PyThread_type_lock lock; + /* Request for running pending calls. */ + _Py_atomic_int calls_to_do; + /* Request for looking at the `async_exc` field of the current + thread state. + Guarded by the GIL. */ + int async_exc; +#define NPENDINGCALLS 32 + struct { + int (*func)(void *); + void *arg; + } calls[NPENDINGCALLS]; + int first; + int last; +}; + +struct _ceval_runtime_state { + int recursion_limit; + /* Records whether tracing is on for any thread. Counts the number + of threads for which tstate->c_tracefunc is non-NULL, so if the + value is 0, we know we don't have to check this thread's + c_tracefunc. This speeds up the if statement in + PyEval_EvalFrameEx() after fast_next_opcode. */ + int tracing_possible; + /* This single variable consolidates all requests to break out of + the fast path in the eval loop. */ + _Py_atomic_int eval_breaker; + /* Request for dropping the GIL */ + _Py_atomic_int gil_drop_request; + struct _pending_calls pending; + /* Request for checking signals. */ + _Py_atomic_int signals_pending; + struct _gil_runtime_state gil; +}; + +/* interpreter state */ + +typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); + +// The PyInterpreterState typedef is in Include/pystate.h. +struct _is { + + struct _is *next; + struct _ts *tstate_head; + + int64_t id; + int64_t id_refcount; + int requires_idref; + PyThread_type_lock id_mutex; + + int finalizing; + + PyObject *modules; + PyObject *modules_by_index; + PyObject *sysdict; + PyObject *builtins; + PyObject *importlib; + + /* Used in Python/sysmodule.c. */ + int check_interval; + + /* Used in Modules/_threadmodule.c. */ + long num_threads; + /* Support for runtime thread stack size tuning. + A value of 0 means using the platform's default stack size + or the size specified by the THREAD_STACK_SIZE macro. */ + /* Used in Python/thread.c. */ + size_t pythread_stacksize; + + PyObject *codec_search_path; + PyObject *codec_search_cache; + PyObject *codec_error_registry; + int codecs_initialized; + + /* fs_codec.encoding is initialized to NULL. + Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ + struct { + char *encoding; /* Filesystem encoding (encoded to UTF-8) */ + char *errors; /* Filesystem errors (encoded to UTF-8) */ + _Py_error_handler error_handler; + } fs_codec; + + PyConfig config; +#ifdef HAVE_DLOPEN + int dlopenflags; +#endif + + PyObject *dict; /* Stores per-interpreter state */ + + PyObject *builtins_copy; + PyObject *import_func; + /* Initialized to PyEval_EvalFrameDefault(). */ + _PyFrameEvalFunction eval_frame; + + Py_ssize_t co_extra_user_count; + freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; + +#ifdef HAVE_FORK + PyObject *before_forkers; + PyObject *after_forkers_parent; + PyObject *after_forkers_child; +#endif + /* AtExit module */ + void (*pyexitfunc)(PyObject *); + PyObject *pyexitmodule; + + uint64_t tstate_next_unique_id; + + struct _warnings_runtime_state warnings; + + PyObject *audit_hooks; +}; + +PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T); + +PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *); +PyAPI_FUNC(int) _PyInterpreterState_IDIncref(struct _is *); +PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *); + + +/* cross-interpreter data registry */ + +/* For now we use a global registry of shareable classes. An + alternative would be to add a tp_* slot for a class's + crossinterpdatafunc. It would be simpler and more efficient. */ + +struct _xidregitem; + +struct _xidregitem { + PyTypeObject *cls; + crossinterpdatafunc getdata; + struct _xidregitem *next; +}; + +/* runtime audit hook state */ + +typedef struct _Py_AuditHookEntry { + struct _Py_AuditHookEntry *next; + Py_AuditHookFunction hookCFunction; + void *userData; +} _Py_AuditHookEntry; + +/* GIL state */ + +struct _gilstate_runtime_state { + int check_enabled; + /* Assuming the current thread holds the GIL, this is the + PyThreadState for the current thread. */ + _Py_atomic_address tstate_current; + PyThreadFrameGetter getframe; + /* The single PyInterpreterState used by this process' + GILState implementation + */ + /* TODO: Given interp_main, it may be possible to kill this ref */ + PyInterpreterState *autoInterpreterState; + Py_tss_t autoTSSkey; +}; + +/* hook for PyEval_GetFrame(), requested for Psyco */ +#define _PyThreadState_GetFrame _PyRuntime.gilstate.getframe + +/* Issue #26558: Flag to disable PyGILState_Check(). + If set to non-zero, PyGILState_Check() always return 1. */ +#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled + + +/* Full Python runtime state */ + +typedef struct pyruntimestate { + /* Is running Py_PreInitialize()? */ + int preinitializing; + + /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */ + int preinitialized; + + /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */ + int core_initialized; + + /* Is Python fully initialized? Set to 1 by Py_Initialize() */ + int initialized; + + /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize() + is called again. */ + PyThreadState *finalizing; + + struct pyinterpreters { + PyThread_type_lock mutex; + PyInterpreterState *head; + PyInterpreterState *main; + /* _next_interp_id is an auto-numbered sequence of small + integers. It gets initialized in _PyInterpreterState_Init(), + which is called in Py_Initialize(), and used in + PyInterpreterState_New(). A negative interpreter ID + indicates an error occurred. The main interpreter will + always have an ID of 0. Overflow results in a RuntimeError. + If that becomes a problem later then we can adjust, e.g. by + using a Python int. */ + int64_t next_id; + } interpreters; + // XXX Remove this field once we have a tp_* slot. + struct _xidregistry { + PyThread_type_lock mutex; + struct _xidregitem *head; + } xidregistry; + + unsigned long main_thread; + +#define NEXITFUNCS 32 + void (*exitfuncs[NEXITFUNCS])(void); + int nexitfuncs; + + struct _gc_runtime_state gc; + struct _ceval_runtime_state ceval; + struct _gilstate_runtime_state gilstate; + + PyPreConfig preconfig; + + Py_OpenCodeHookFunction open_code_hook; + void *open_code_userdata; + _Py_AuditHookEntry *audit_hook_head; + + // XXX Consolidate globals found via the check-c-globals script. +} _PyRuntimeState; + +#define _PyRuntimeState_INIT \ + {.preinitialized = 0, .core_initialized = 0, .initialized = 0} +/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */ + +PyAPI_DATA(_PyRuntimeState) _PyRuntime; +PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); + +/* Initialize _PyRuntimeState. + Return NULL on success, or return an error message on failure. */ +PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void); + +PyAPI_FUNC(void) _PyRuntime_Finalize(void); + +#define _Py_CURRENTLY_FINALIZING(runtime, tstate) \ + (runtime->finalizing == tstate) + + +/* Variable and macro for in-line access to current thread + and interpreter state */ + +#define _PyRuntimeState_GetThreadState(runtime) \ + ((PyThreadState*)_Py_atomic_load_relaxed(&(runtime)->gilstate.tstate_current)) + +/* Get the current Python thread state. + + Efficient macro reading directly the 'gilstate.tstate_current' atomic + variable. The macro is unsafe: it does not check for error and it can + return NULL. + + The caller must hold the GIL. + + See also PyThreadState_Get() and PyThreadState_GET(). */ +#define _PyThreadState_GET() _PyRuntimeState_GetThreadState(&_PyRuntime) + +/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */ +#undef PyThreadState_GET +#define PyThreadState_GET() _PyThreadState_GET() + +/* Get the current interpreter state. + + The macro is unsafe: it does not check for error and it can return NULL. + + The caller must hold the GIL. + + See also _PyInterpreterState_Get() + and _PyGILState_GetInterpreterStateUnsafe(). */ +#define _PyInterpreterState_GET_UNSAFE() (_PyThreadState_GET()->interp) + + +/* Other */ + +PyAPI_FUNC(void) _PyThreadState_Init( + _PyRuntimeState *runtime, + PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_DeleteExcept( + _PyRuntimeState *runtime, + PyThreadState *tstate); + +PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( + struct _gilstate_runtime_state *gilstate, + PyThreadState *newts); + +PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); + +PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); + + +PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYSTATE_H */ diff --git a/python/include/internal/pycore_traceback.h b/python/include/internal/pycore_traceback.h new file mode 100755 index 0000000..bf4d7fe --- /dev/null +++ b/python/include/internal/pycore_traceback.h @@ -0,0 +1,96 @@ +#ifndef Py_INTERNAL_TRACEBACK_H +#define Py_INTERNAL_TRACEBACK_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pystate.h" /* PyInterpreterState */ + +/* Write the Python traceback into the file 'fd'. For example: + + Traceback (most recent call first): + File "xxx", line xxx in + File "xxx", line xxx in + ... + File "xxx", line xxx in + + This function is written for debug purpose only, to dump the traceback in + the worst case: after a segmentation fault, at fatal error, etc. That's why, + it is very limited. Strings are truncated to 100 characters and encoded to + ASCII with backslashreplace. It doesn't write the source code, only the + function name, filename and line number of each frame. Write only the first + 100 frames: if the traceback is truncated, write the line " ...". + + This function is signal safe. */ + +PyAPI_FUNC(void) _Py_DumpTraceback( + int fd, + PyThreadState *tstate); + +/* Write the traceback of all threads into the file 'fd'. current_thread can be + NULL. + + Return NULL on success, or an error message on error. + + This function is written for debug purpose only. It calls + _Py_DumpTraceback() for each thread, and so has the same limitations. It + only write the traceback of the first 100 threads: write "..." if there are + more threads. + + If current_tstate is NULL, the function tries to get the Python thread state + of the current thread. It is not an error if the function is unable to get + the current Python thread state. + + If interp is NULL, the function tries to get the interpreter state from + the current Python thread state, or from + _PyGILState_GetInterpreterStateUnsafe() in last resort. + + It is better to pass NULL to interp and current_tstate, the function tries + different options to retrieve these informations. + + This function is signal safe. */ + +PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( + int fd, + PyInterpreterState *interp, + PyThreadState *current_tstate); + +/* Write a Unicode object into the file descriptor fd. Encode the string to + ASCII using the backslashreplace error handler. + + Do nothing if text is not a Unicode object. The function accepts Unicode + string which is not ready (PyUnicode_WCHAR_KIND). + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text); + +/* Format an integer as decimal into the file descriptor fd. + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpDecimal( + int fd, + unsigned long value); + +/* Format an integer as hexadecimal into the file descriptor fd with at least + width digits. + + The maximum width is sizeof(unsigned long)*2 digits. + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpHexadecimal( + int fd, + unsigned long value, + Py_ssize_t width); + +PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame( + PyObject *tb_next, + struct _frame *frame); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TRACEBACK_H */ diff --git a/python/include/internal/pycore_tupleobject.h b/python/include/internal/pycore_tupleobject.h new file mode 100755 index 0000000..9fcfc5c --- /dev/null +++ b/python/include/internal/pycore_tupleobject.h @@ -0,0 +1,19 @@ +#ifndef Py_INTERNAL_TUPLEOBJECT_H +#define Py_INTERNAL_TUPLEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "tupleobject.h" + +#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item) +PyAPI_FUNC(PyObject *) _PyTuple_FromArray(PyObject *const *, Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TUPLEOBJECT_H */ diff --git a/python/include/internal/pycore_warnings.h b/python/include/internal/pycore_warnings.h new file mode 100755 index 0000000..73e5350 --- /dev/null +++ b/python/include/internal/pycore_warnings.h @@ -0,0 +1,25 @@ +#ifndef Py_INTERNAL_WARNINGS_H +#define Py_INTERNAL_WARNINGS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "object.h" + +struct _warnings_runtime_state { + /* Both 'filters' and 'onceregistry' can be set in warnings.py; + get_warnings_attr() will reset these variables accordingly. */ + PyObject *filters; /* List */ + PyObject *once_registry; /* Dict */ + PyObject *default_action; /* String */ + long filters_version; +}; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_WARNINGS_H */ diff --git a/python/include/interpreteridobject.h b/python/include/interpreteridobject.h new file mode 100755 index 0000000..e744fcd --- /dev/null +++ b/python/include/interpreteridobject.h @@ -0,0 +1,17 @@ +#ifndef Py_INTERPRETERIDOBJECT_H +#define Py_INTERPRETERIDOBJECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_INTERPRETERIDOBJECT_H +# include "cpython/interpreteridobject.h" +# undef Py_CPYTHON_INTERPRETERIDOBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERPRETERIDOBJECT_H */ diff --git a/python/include/intrcheck.h b/python/include/intrcheck.h new file mode 100755 index 0000000..e5bf5a8 --- /dev/null +++ b/python/include/intrcheck.h @@ -0,0 +1,33 @@ + +#ifndef Py_INTRCHECK_H +#define Py_INTRCHECK_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyOS_InterruptOccurred(void); +PyAPI_FUNC(void) PyOS_InitInterrupts(void); +#ifdef HAVE_FORK +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_FUNC(void) PyOS_BeforeFork(void); +PyAPI_FUNC(void) PyOS_AfterFork_Parent(void); +PyAPI_FUNC(void) PyOS_AfterFork_Child(void); +#endif +#endif +/* Deprecated, please use PyOS_AfterFork_Child() instead */ +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyOS_AfterFork(void); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyOS_IsMainThread(void); +PyAPI_FUNC(void) _PySignal_AfterFork(void); + +#ifdef MS_WINDOWS +/* windows.h is not included by Python.h so use void* instead of HANDLE */ +PyAPI_FUNC(void*) _PyOS_SigintEvent(void); +#endif +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTRCHECK_H */ diff --git a/python/include/iterobject.h b/python/include/iterobject.h new file mode 100755 index 0000000..f61726f --- /dev/null +++ b/python/include/iterobject.h @@ -0,0 +1,25 @@ +#ifndef Py_ITEROBJECT_H +#define Py_ITEROBJECT_H +/* Iterators (the basic kind, over a sequence) */ +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PySeqIter_Type; +PyAPI_DATA(PyTypeObject) PyCallIter_Type; +PyAPI_DATA(PyTypeObject) PyCmpWrapper_Type; + +#define PySeqIter_Check(op) (Py_TYPE(op) == &PySeqIter_Type) + +PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); + + +#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type) + +PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ITEROBJECT_H */ + diff --git a/python/include/listobject.h b/python/include/listobject.h new file mode 100755 index 0000000..6057279 --- /dev/null +++ b/python/include/listobject.h @@ -0,0 +1,81 @@ + +/* List object interface */ + +/* +Another generally useful object type is a list of object pointers. +This is a mutable type: the list items can be changed, and items can be +added or removed. Out-of-range indices or non-list objects are ignored. + +*** WARNING *** PyList_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the list. Similarly, PyList_GetItem does not increment the +returned item's reference count. +*/ + +#ifndef Py_LISTOBJECT_H +#define Py_LISTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_VAR_HEAD + /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ + PyObject **ob_item; + + /* ob_item contains space for 'allocated' elements. The number + * currently in use is ob_size. + * Invariants: + * 0 <= ob_size <= allocated + * len(list) == ob_size + * ob_item == NULL implies ob_size == allocated == 0 + * list.sort() temporarily sets allocated to -1 to detect mutations. + * + * Items must normally not be NULL, except during construction when + * the list is not yet visible outside the function that builds it. + */ + Py_ssize_t allocated; +} PyListObject; +#endif + +PyAPI_DATA(PyTypeObject) PyList_Type; +PyAPI_DATA(PyTypeObject) PyListIter_Type; +PyAPI_DATA(PyTypeObject) PyListRevIter_Type; +PyAPI_DATA(PyTypeObject) PySortWrapper_Type; + +#define PyList_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) +#define PyList_CheckExact(op) (Py_TYPE(op) == &PyList_Type) + +PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Sort(PyObject *); +PyAPI_FUNC(int) PyList_Reverse(PyObject *); +PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); + +PyAPI_FUNC(int) PyList_ClearFreeList(void); +PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); +#endif + +/* Macro, trading safety for speed */ +#ifndef Py_LIMITED_API +#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) +#define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) +#define PyList_GET_SIZE(op) (assert(PyList_Check(op)),Py_SIZE(op)) +#define _PyList_ITEMS(op) (((PyListObject *)(op))->ob_item) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LISTOBJECT_H */ diff --git a/python/include/longintrepr.h b/python/include/longintrepr.h new file mode 100755 index 0000000..ff4155f --- /dev/null +++ b/python/include/longintrepr.h @@ -0,0 +1,99 @@ +#ifndef Py_LIMITED_API +#ifndef Py_LONGINTREPR_H +#define Py_LONGINTREPR_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is published for the benefit of "friends" marshal.c and _decimal.c. */ + +/* Parameters of the integer representation. There are two different + sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit + integer type, and one set for 15-bit digits with each digit stored in an + unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at + configure time or in pyport.h, is used to decide which digit size to use. + + Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits' + should be an unsigned integer type able to hold all integers up to + PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type, + and that overflow is handled by taking the result modulo 2**N for some N > + PyLong_SHIFT. The majority of the code doesn't care about the precise + value of PyLong_SHIFT, but there are some notable exceptions: + + - long_pow() requires that PyLong_SHIFT be divisible by 5 + + - PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8 + + - long_hash() requires that PyLong_SHIFT is *strictly* less than the number + of bits in an unsigned long, as do the PyLong <-> long (or unsigned long) + conversion functions + + - the Python int <-> size_t/Py_ssize_t conversion functions expect that + PyLong_SHIFT is strictly less than the number of bits in a size_t + + - the marshal code currently expects that PyLong_SHIFT is a multiple of 15 + + - NSMALLNEGINTS and NSMALLPOSINTS should be small enough to fit in a single + digit; with the current values this forces PyLong_SHIFT >= 9 + + The values 15 and 30 should fit all of the above requirements, on any + platform. +*/ + +#if PYLONG_BITS_IN_DIGIT == 30 +typedef uint32_t digit; +typedef int32_t sdigit; /* signed variant of digit */ +typedef uint64_t twodigits; +typedef int64_t stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 30 +#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */ +#elif PYLONG_BITS_IN_DIGIT == 15 +typedef unsigned short digit; +typedef short sdigit; /* signed variant of digit */ +typedef unsigned long twodigits; +typedef long stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 15 +#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */ +#else +#error "PYLONG_BITS_IN_DIGIT should be 15 or 30" +#endif +#define PyLong_BASE ((digit)1 << PyLong_SHIFT) +#define PyLong_MASK ((digit)(PyLong_BASE - 1)) + +#if PyLong_SHIFT % 5 != 0 +#error "longobject.c requires that PyLong_SHIFT be divisible by 5" +#endif + +/* Long integer representation. + The absolute value of a number is equal to + SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) + Negative numbers are represented with ob_size < 0; + zero is represented by ob_size == 0. + In a normalized number, ob_digit[abs(ob_size)-1] (the most significant + digit) is never zero. Also, in all cases, for all valid i, + 0 <= ob_digit[i] <= MASK. + The allocation function takes care of allocating extra memory + so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. + + CAUTION: Generic code manipulating subtypes of PyVarObject has to + aware that ints abuse ob_size's sign bit. +*/ + +struct _longobject { + PyObject_VAR_HEAD + digit ob_digit[1]; +}; + +PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); + +/* Return a copy of src. */ +PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGINTREPR_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/longobject.h b/python/include/longobject.h new file mode 100755 index 0000000..1e7a58d --- /dev/null +++ b/python/include/longobject.h @@ -0,0 +1,242 @@ +#ifndef Py_LONGOBJECT_H +#define Py_LONGOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Long (arbitrary precision) integer object interface */ + +typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ + +PyAPI_DATA(PyTypeObject) PyLong_Type; + +#define PyLong_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) +#define PyLong_CheckExact(op) (Py_TYPE(op) == &PyLong_Type) + +PyAPI_FUNC(PyObject *) PyLong_FromLong(long); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); +PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); +PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); +PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); +PyAPI_FUNC(long) PyLong_AsLong(PyObject *); +PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); +PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); +PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); + +/* It may be useful in the future. I've added it in the PyInt -> PyLong + cleanup to keep the extra information. [CH] */ +#define PyLong_AS_LONG(op) PyLong_AsLong(op) + +/* Issue #1983: pid_t can be longer than a C long on some systems */ +#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT +#define _Py_PARSE_PID "i" +#define PyLong_FromPid PyLong_FromLong +#define PyLong_AsPid PyLong_AsLong +#elif SIZEOF_PID_T == SIZEOF_LONG +#define _Py_PARSE_PID "l" +#define PyLong_FromPid PyLong_FromLong +#define PyLong_AsPid PyLong_AsLong +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG +#define _Py_PARSE_PID "L" +#define PyLong_FromPid PyLong_FromLongLong +#define PyLong_AsPid PyLong_AsLongLong +#else +#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" +#endif /* SIZEOF_PID_T */ + +#if SIZEOF_VOID_P == SIZEOF_INT +# define _Py_PARSE_INTPTR "i" +# define _Py_PARSE_UINTPTR "I" +#elif SIZEOF_VOID_P == SIZEOF_LONG +# define _Py_PARSE_INTPTR "l" +# define _Py_PARSE_UINTPTR "k" +#elif defined(SIZEOF_LONG_LONG) && SIZEOF_VOID_P == SIZEOF_LONG_LONG +# define _Py_PARSE_INTPTR "L" +# define _Py_PARSE_UINTPTR "K" +#else +# error "void* different in size from int, long and long long" +#endif /* SIZEOF_VOID_P */ + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *); +#endif + +/* Used by Python/mystrtoul.c, _PyBytes_FromHex(), + _PyBytes_DecodeEscapeRecode(), etc. */ +#ifndef Py_LIMITED_API +PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; +#endif + +/* _PyLong_Frexp returns a double x and an exponent e such that the + true value is approximately equal to x * 2**e. e is >= 0. x is + 0.0 if and only if the input is 0 (in which case, e and x are both + zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is + possible if the number of bits doesn't fit into a Py_ssize_t, sets + OverflowError and returns -1.0 for x, 0 for e. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); +#endif + +PyAPI_FUNC(double) PyLong_AsDouble(PyObject *); +PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *); +PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *); + +PyAPI_FUNC(PyObject *) PyLong_FromLongLong(long long); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned long long); +PyAPI_FUNC(long long) PyLong_AsLongLong(PyObject *); +PyAPI_FUNC(unsigned long long) PyLong_AsUnsignedLongLong(PyObject *); +PyAPI_FUNC(unsigned long long) PyLong_AsUnsignedLongLongMask(PyObject *); +PyAPI_FUNC(long long) PyLong_AsLongLongAndOverflow(PyObject *, int *); + +PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int); +#ifndef Py_LIMITED_API +Py_DEPRECATED(3.3) +PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int); +PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base); +PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int); +#endif + +#ifndef Py_LIMITED_API +/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. + v must not be NULL, and must be a normalized long. + There are no error cases. +*/ +PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); + + +/* _PyLong_NumBits. Return the number of bits needed to represent the + absolute value of a long. For example, this returns 1 for 1 and -1, 2 + for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. + v must not be NULL, and must be a normalized long. + (size_t)-1 is returned and OverflowError set if the true result doesn't + fit in a size_t. +*/ +PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); + +/* _PyLong_DivmodNear. Given integers a and b, compute the nearest + integer q to the exact quotient a / b, rounding to the nearest even integer + in the case of a tie. Return (q, r), where r = a - q*b. The remainder r + will satisfy abs(r) <= abs(b)/2, with equality possible only if q is + even. +*/ +PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); + +/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in + base 256, and return a Python int with the same numeric value. + If n is 0, the integer is 0. Else: + If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; + else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the + LSB. + If is_signed is 0/false, view the bytes as a non-negative integer. + If is_signed is 1/true, view the bytes as a 2's-complement integer, + non-negative if bit 0x80 of the MSB is clear, negative if set. + Error returns: + + Return NULL with the appropriate exception set if there's not + enough memory to create the Python int. +*/ +PyAPI_FUNC(PyObject *) _PyLong_FromByteArray( + const unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long + v to a base-256 integer, stored in array bytes. Normally return 0, + return -1 on error. + If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at + bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and + the LSB at bytes[n-1]. + If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes + are filled and there's nothing special about bit 0x80 of the MSB. + If is_signed is 1/true, bytes is filled with the 2's-complement + representation of v's value. Bit 0x80 of the MSB is the sign bit. + Error returns (-1): + + is_signed is 0 and v < 0. TypeError is set in this case, and bytes + isn't altered. + + n isn't big enough to hold the full mathematical value of v. For + example, if is_signed is 0 and there are more digits in the v than + fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of + being large enough to hold a sign bit. OverflowError is set in this + case, but bytes holds the least-significant n bytes of the true value. +*/ +PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_FromNbInt: Convert the given object to a PyLongObject + using the nb_int slot, if available. Raise TypeError if either the + nb_int slot is not available or the result of the call to nb_int + returns something not of type int. +*/ +PyAPI_FUNC(PyObject *) _PyLong_FromNbInt(PyObject *); + +/* Convert the given object to a PyLongObject using the nb_index or + nb_int slots, if available (the latter is deprecated). + Raise TypeError if either nb_index and nb_int slots are not + available or the result of the call to nb_index or nb_int + returns something not of type int. + Should be replaced with PyNumber_Index after the end of the + deprecation period. +*/ +PyAPI_FUNC(PyObject *) _PyLong_FromNbIndexOrNbInt(PyObject *); + +/* _PyLong_Format: Convert the long to a string object with given base, + appending a base prefix of 0[box] if base is 2, 8 or 16. */ +PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base); + +PyAPI_FUNC(int) _PyLong_FormatWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + int base, + int alternate); + +PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( + _PyBytesWriter *writer, + char *str, + PyObject *obj, + int base, + int alternate); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif /* Py_LIMITED_API */ + +/* These aren't really part of the int object, but they're handy. The + functions are in Python/mystrtoul.c. + */ +PyAPI_FUNC(unsigned long) PyOS_strtoul(const char *, char **, int); +PyAPI_FUNC(long) PyOS_strtol(const char *, char **, int); + +#ifndef Py_LIMITED_API +/* For use by the gcd function in mathmodule.c */ +PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); +#endif /* !Py_LIMITED_API */ + +#ifndef Py_LIMITED_API +PyAPI_DATA(PyObject *) _PyLong_Zero; +PyAPI_DATA(PyObject *) _PyLong_One; + +PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t); +PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGOBJECT_H */ diff --git a/python/include/marshal.h b/python/include/marshal.h new file mode 100755 index 0000000..09d9337 --- /dev/null +++ b/python/include/marshal.h @@ -0,0 +1,28 @@ + +/* Interface for marshal.c */ + +#ifndef Py_MARSHAL_H +#define Py_MARSHAL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define Py_MARSHAL_VERSION 4 + +PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int); +PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int); +PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *); +PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *); +#endif +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(const char *, + Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MARSHAL_H */ diff --git a/python/include/memoryobject.h b/python/include/memoryobject.h new file mode 100755 index 0000000..990a716 --- /dev/null +++ b/python/include/memoryobject.h @@ -0,0 +1,72 @@ +/* Memory view object. In Python this is available as "memoryview". */ + +#ifndef Py_MEMORYOBJECT_H +#define Py_MEMORYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; +#endif +PyAPI_DATA(PyTypeObject) PyMemoryView_Type; + +#define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type) + +#ifndef Py_LIMITED_API +/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ +#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view) +/* Get a pointer to the exporting object (this may be NULL!). */ +#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj) +#endif + +PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyMemoryView_FromMemory(char *mem, Py_ssize_t size, + int flags); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info); +#endif +PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, + int buffertype, + char order); + + +/* The structs are declared here so that macros can work, but they shouldn't + be considered public. Don't access their fields directly, use the macros + and functions instead! */ +#ifndef Py_LIMITED_API +#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ +#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ +typedef struct { + PyObject_HEAD + int flags; /* state flags */ + Py_ssize_t exports; /* number of direct memoryview exports */ + Py_buffer master; /* snapshot buffer obtained from the original exporter */ +} _PyManagedBufferObject; + + +/* memoryview state flags */ +#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ +#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ +#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ +#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ +#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ + +typedef struct { + PyObject_VAR_HEAD + _PyManagedBufferObject *mbuf; /* managed buffer */ + Py_hash_t hash; /* hash value for read-only views */ + int flags; /* state flags */ + Py_ssize_t exports; /* number of buffer re-exports */ + Py_buffer view; /* private copy of the exporter's view */ + PyObject *weakreflist; + Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ +} PyMemoryViewObject; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MEMORYOBJECT_H */ diff --git a/python/include/methodobject.h b/python/include/methodobject.h new file mode 100755 index 0000000..ba3b887 --- /dev/null +++ b/python/include/methodobject.h @@ -0,0 +1,131 @@ + +/* Method object interface */ + +#ifndef Py_METHODOBJECT_H +#define Py_METHODOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* This is about the type 'builtin_function_or_method', + not Python methods in user-defined classes. See classobject.h + for the latter. */ + +PyAPI_DATA(PyTypeObject) PyCFunction_Type; + +#define PyCFunction_Check(op) (Py_TYPE(op) == &PyCFunction_Type) + +typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); +typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); +typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, + PyObject *); +typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *, + PyObject *const *, Py_ssize_t, + PyObject *); +typedef PyObject *(*PyNoArgsFunction)(PyObject *); + +PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *); +PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *); +PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#ifndef Py_LIMITED_API +#define PyCFunction_GET_FUNCTION(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_meth) +#define PyCFunction_GET_SELF(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_STATIC ? \ + NULL : ((PyCFunctionObject *)func) -> m_self) +#define PyCFunction_GET_FLAGS(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_flags) +#endif +PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyCFunction_FastCallDict(PyObject *func, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs); +#endif + +struct PyMethodDef { + const char *ml_name; /* The name of the built-in function/method */ + PyCFunction ml_meth; /* The C function that implements it */ + int ml_flags; /* Combination of METH_xxx flags, which mostly + describe the args expected by the C func */ + const char *ml_doc; /* The __doc__ attribute, or NULL */ +}; +typedef struct PyMethodDef PyMethodDef; + +#define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) +PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, + PyObject *); + +/* Flag passed to newmethodobject */ +/* #define METH_OLDARGS 0x0000 -- unsupported now */ +#define METH_VARARGS 0x0001 +#define METH_KEYWORDS 0x0002 +/* METH_NOARGS and METH_O must not be combined with the flags above. */ +#define METH_NOARGS 0x0004 +#define METH_O 0x0008 + +/* METH_CLASS and METH_STATIC are a little different; these control + the construction of methods for a class. These cannot be used for + functions in modules. */ +#define METH_CLASS 0x0010 +#define METH_STATIC 0x0020 + +/* METH_COEXIST allows a method to be entered even though a slot has + already filled the entry. When defined, the flag allows a separate + method, "__contains__" for example, to coexist with a defined + slot like sq_contains. */ + +#define METH_COEXIST 0x0040 + +#ifndef Py_LIMITED_API +#define METH_FASTCALL 0x0080 +#endif + +/* This bit is preserved for Stackless Python */ +#ifdef STACKLESS +#define METH_STACKLESS 0x0100 +#else +#define METH_STACKLESS 0x0000 +#endif + +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + PyMethodDef *m_ml; /* Description of the C function to call */ + PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ + PyObject *m_module; /* The __module__ attribute, can be anything */ + PyObject *m_weakreflist; /* List of weak references */ + vectorcallfunc vectorcall; +} PyCFunctionObject; + +PyAPI_FUNC(PyObject *) _PyMethodDef_RawFastCallDict( + PyMethodDef *method, + PyObject *self, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyMethodDef_RawFastCallKeywords( + PyMethodDef *method, + PyObject *self, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames); +#endif + +PyAPI_FUNC(int) PyCFunction_ClearFreeList(void); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyCFunction_DebugMallocStats(FILE *out); +PyAPI_FUNC(void) _PyMethod_DebugMallocStats(FILE *out); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METHODOBJECT_H */ diff --git a/python/include/modsupport.h b/python/include/modsupport.h new file mode 100755 index 0000000..f90ede4 --- /dev/null +++ b/python/include/modsupport.h @@ -0,0 +1,248 @@ + +#ifndef Py_MODSUPPORT_H +#define Py_MODSUPPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Module support interface */ + +#include + +/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier + to mean Py_ssize_t */ +#ifdef PY_SSIZE_T_CLEAN +#define PyArg_Parse _PyArg_Parse_SizeT +#define PyArg_ParseTuple _PyArg_ParseTuple_SizeT +#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT +#define PyArg_VaParse _PyArg_VaParse_SizeT +#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT +#define Py_BuildValue _Py_BuildValue_SizeT +#define Py_VaBuildValue _Py_VaBuildValue_SizeT +#ifndef Py_LIMITED_API +#define _Py_VaBuildStack _Py_VaBuildStack_SizeT +#endif +#else +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); +PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); +#endif /* !Py_LIMITED_API */ +#endif + +/* Due to a glitch in 3.2, the _SizeT versions weren't exported from the DLL. */ +#if !defined(PY_SSIZE_T_CLEAN) || !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); +PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); +PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, ...); +PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); +PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, va_list); +#endif +PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *); +PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); +PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); +PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); + + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyArg_UnpackStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *name, + Py_ssize_t min, + Py_ssize_t max, + ...); + +PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); +PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); +#define _PyArg_NoKeywords(funcname, kwargs) \ + ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) +#define _PyArg_NoPositional(funcname, args) \ + ((args) == NULL || _PyArg_NoPositional((funcname), (args))) + +PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *); +PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, + Py_ssize_t, Py_ssize_t); +#define _PyArg_CheckPositional(funcname, nargs, min, max) \ + (((min) <= (nargs) && (nargs) <= (max)) \ + || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) + +#endif + +PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject **) _Py_VaBuildStack( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); +#endif + +#ifndef Py_LIMITED_API +typedef struct _PyArg_Parser { + const char *format; + const char * const *keywords; + const char *fname; + const char *custom_msg; + int pos; /* number of positional-only arguments */ + int min; /* minimal number of arguments */ + int max; /* maximal number of positional arguments */ + PyObject *kwtuple; /* tuple of keyword parameter names */ + struct _PyArg_Parser *next; +} _PyArg_Parser; +#ifdef PY_SSIZE_T_CLEAN +#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT +#define _PyArg_ParseStack _PyArg_ParseStack_SizeT +#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT +#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT +#endif +PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, ...); +PyAPI_FUNC(int) _PyArg_ParseStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *format, + ...); +PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames, + struct _PyArg_Parser *, + ...); +PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, va_list); +PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, int maxpos, int minkw, + PyObject **buf); +#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ + (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ + (minpos) <= (nargs) && (nargs) <= (maxpos) && args != NULL) ? (args) : \ + _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ + (minpos), (maxpos), (minkw), (buf))) + +void _PyArg_Fini(void); +#endif /* Py_LIMITED_API */ + +PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); +PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +PyAPI_FUNC(int) PyModule_SetDocString(PyObject *, const char *); +PyAPI_FUNC(int) PyModule_AddFunctions(PyObject *, PyMethodDef *); +PyAPI_FUNC(int) PyModule_ExecDef(PyObject *module, PyModuleDef *def); +#endif + +#define Py_CLEANUP_SUPPORTED 0x20000 + +#define PYTHON_API_VERSION 1013 +#define PYTHON_API_STRING "1013" +/* The API version is maintained (independently from the Python version) + so we can detect mismatches between the interpreter and dynamically + loaded modules. These are diagnosed by an error message but + the module is still loaded (because the mismatch can only be tested + after loading the module). The error message is intended to + explain the core dump a few seconds later. + + The symbol PYTHON_API_STRING defines the same value as a string + literal. *** PLEASE MAKE SURE THE DEFINITIONS MATCH. *** + + Please add a line or two to the top of this log for each API + version change: + + 22-Feb-2006 MvL 1013 PEP 353 - long indices for sequence lengths + + 19-Aug-2002 GvR 1012 Changes to string object struct for + interning changes, saving 3 bytes. + + 17-Jul-2001 GvR 1011 Descr-branch, just to be on the safe side + + 25-Jan-2001 FLD 1010 Parameters added to PyCode_New() and + PyFrame_New(); Python 2.1a2 + + 14-Mar-2000 GvR 1009 Unicode API added + + 3-Jan-1999 GvR 1007 Decided to change back! (Don't reuse 1008!) + + 3-Dec-1998 GvR 1008 Python 1.5.2b1 + + 18-Jan-1997 GvR 1007 string interning and other speedups + + 11-Oct-1996 GvR renamed Py_Ellipses to Py_Ellipsis :-( + + 30-Jul-1996 GvR Slice and ellipses syntax added + + 23-Jul-1996 GvR For 1.4 -- better safe than sorry this time :-) + + 7-Nov-1995 GvR Keyword arguments (should've been done at 1.3 :-( ) + + 10-Jan-1995 GvR Renamed globals to new naming scheme + + 9-Jan-1995 GvR Initial version (incompatible with older API) +*/ + +/* The PYTHON_ABI_VERSION is introduced in PEP 384. For the lifetime of + Python 3, it will stay at the value of 3; changes to the limited API + must be performed in a strictly backwards-compatible manner. */ +#define PYTHON_ABI_VERSION 3 +#define PYTHON_ABI_STRING "3" + +#ifdef Py_TRACE_REFS + /* When we are tracing reference counts, rename module creation functions so + modules compiled with incompatible settings will generate a + link-time error. */ + #define PyModule_Create2 PyModule_Create2TraceRefs + #define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs +#endif + +PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*, + int apiver); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(struct PyModuleDef*, + int apiver); +#endif + +#ifdef Py_LIMITED_API +#define PyModule_Create(module) \ + PyModule_Create2(module, PYTHON_ABI_VERSION) +#else +#define PyModule_Create(module) \ + PyModule_Create2(module, PYTHON_API_VERSION) +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +PyAPI_FUNC(PyObject *) PyModule_FromDefAndSpec2(PyModuleDef *def, + PyObject *spec, + int module_api_version); + +#ifdef Py_LIMITED_API +#define PyModule_FromDefAndSpec(module, spec) \ + PyModule_FromDefAndSpec2(module, spec, PYTHON_ABI_VERSION) +#else +#define PyModule_FromDefAndSpec(module, spec) \ + PyModule_FromDefAndSpec2(module, spec, PYTHON_API_VERSION) +#endif /* Py_LIMITED_API */ +#endif /* New in 3.5 */ + +#ifndef Py_LIMITED_API +PyAPI_DATA(const char *) _Py_PackageContext; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODSUPPORT_H */ diff --git a/python/include/moduleobject.h b/python/include/moduleobject.h new file mode 100755 index 0000000..e246fd2 --- /dev/null +++ b/python/include/moduleobject.h @@ -0,0 +1,90 @@ + +/* Module object interface */ + +#ifndef Py_MODULEOBJECT_H +#define Py_MODULEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyModule_Type; + +#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) +#define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type) + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyModule_NewObject( + PyObject *name + ); +#endif +PyAPI_FUNC(PyObject *) PyModule_New( + const char *name /* UTF-8 encoded string */ + ); +PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyModule_GetNameObject(PyObject *); +#endif +PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); +Py_DEPRECATED(3.2) PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); +PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyModule_Clear(PyObject *); +PyAPI_FUNC(void) _PyModule_ClearDict(PyObject *); +PyAPI_FUNC(int) _PyModuleSpec_IsInitializing(PyObject *); +#endif +PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*); +PyAPI_FUNC(void*) PyModule_GetState(PyObject*); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +PyAPI_FUNC(PyObject *) PyModuleDef_Init(struct PyModuleDef*); +PyAPI_DATA(PyTypeObject) PyModuleDef_Type; +#endif + +typedef struct PyModuleDef_Base { + PyObject_HEAD + PyObject* (*m_init)(void); + Py_ssize_t m_index; + PyObject* m_copy; +} PyModuleDef_Base; + +#define PyModuleDef_HEAD_INIT { \ + PyObject_HEAD_INIT(NULL) \ + NULL, /* m_init */ \ + 0, /* m_index */ \ + NULL, /* m_copy */ \ + } + +struct PyModuleDef_Slot; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +typedef struct PyModuleDef_Slot{ + int slot; + void *value; +} PyModuleDef_Slot; + +#define Py_mod_create 1 +#define Py_mod_exec 2 + +#ifndef Py_LIMITED_API +#define _Py_mod_LAST_SLOT 2 +#endif + +#endif /* New in 3.5 */ + +typedef struct PyModuleDef{ + PyModuleDef_Base m_base; + const char* m_name; + const char* m_doc; + Py_ssize_t m_size; + PyMethodDef *m_methods; + struct PyModuleDef_Slot* m_slots; + traverseproc m_traverse; + inquiry m_clear; + freefunc m_free; +} PyModuleDef; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODULEOBJECT_H */ diff --git a/python/include/namespaceobject.h b/python/include/namespaceobject.h new file mode 100755 index 0000000..0c8d95c --- /dev/null +++ b/python/include/namespaceobject.h @@ -0,0 +1,19 @@ + +/* simple namespace object interface */ + +#ifndef NAMESPACEOBJECT_H +#define NAMESPACEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_DATA(PyTypeObject) _PyNamespace_Type; + +PyAPI_FUNC(PyObject *) _PyNamespace_New(PyObject *kwds); +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !NAMESPACEOBJECT_H */ diff --git a/python/include/node.h b/python/include/node.h new file mode 100755 index 0000000..2b39074 --- /dev/null +++ b/python/include/node.h @@ -0,0 +1,48 @@ + +/* Parse tree node interface */ + +#ifndef Py_NODE_H +#define Py_NODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _node { + short n_type; + char *n_str; + int n_lineno; + int n_col_offset; + int n_nchildren; + struct _node *n_child; + int n_end_lineno; + int n_end_col_offset; +} node; + +PyAPI_FUNC(node *) PyNode_New(int type); +PyAPI_FUNC(int) PyNode_AddChild(node *n, int type, + char *str, int lineno, int col_offset, + int end_lineno, int end_col_offset); +PyAPI_FUNC(void) PyNode_Free(node *n); +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyNode_SizeOf(node *n); +#endif + +/* Node access functions */ +#define NCH(n) ((n)->n_nchildren) + +#define CHILD(n, i) (&(n)->n_child[i]) +#define RCHILD(n, i) (CHILD(n, NCH(n) + i)) +#define TYPE(n) ((n)->n_type) +#define STR(n) ((n)->n_str) +#define LINENO(n) ((n)->n_lineno) + +/* Assert that the type of a node is what we expect */ +#define REQ(n, type) assert(TYPE(n) == (type)) + +PyAPI_FUNC(void) PyNode_ListTree(node *); +void _PyNode_FinalizeEndPos(node *n); // helper also used in parsetok.c + +#ifdef __cplusplus +} +#endif +#endif /* !Py_NODE_H */ diff --git a/python/include/object.h b/python/include/object.h new file mode 100755 index 0000000..5558f65 --- /dev/null +++ b/python/include/object.h @@ -0,0 +1,753 @@ +#ifndef Py_OBJECT_H +#define Py_OBJECT_H + +#include "pymem.h" /* _Py_tracemalloc_config */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Object and type object interface */ + +/* +Objects are structures allocated on the heap. Special rules apply to +the use of objects to ensure they are properly garbage-collected. +Objects are never allocated statically or on the stack; they must be +accessed through special macros and functions only. (Type objects are +exceptions to the first rule; the standard types are represented by +statically initialized type objects, although work on type/class unification +for Python 2.2 made it possible to have heap-allocated type objects too). + +An object has a 'reference count' that is increased or decreased when a +pointer to the object is copied or deleted; when the reference count +reaches zero there are no references to the object left and it can be +removed from the heap. + +An object has a 'type' that determines what it represents and what kind +of data it contains. An object's type is fixed when it is created. +Types themselves are represented as objects; an object contains a +pointer to the corresponding type object. The type itself has a type +pointer pointing to the object representing the type 'type', which +contains a pointer to itself!. + +Objects do not float around in memory; once allocated an object keeps +the same size and address. Objects that must hold variable-size data +can contain pointers to variable-size parts of the object. Not all +objects of the same type have the same size; but the size cannot change +after allocation. (These restrictions are made so a reference to an +object can be simply a pointer -- moving an object would require +updating all the pointers, and changing an object's size would require +moving it if there was another object right next to it.) + +Objects are always accessed through pointers of the type 'PyObject *'. +The type 'PyObject' is a structure that only contains the reference count +and the type pointer. The actual memory allocated for an object +contains other data that can only be accessed after casting the pointer +to a pointer to a longer structure type. This longer type must start +with the reference count and type fields; the macro PyObject_HEAD should be +used for this (to accommodate for future changes). The implementation +of a particular object type can cast the object pointer to the proper +type and back. + +A standard interface exists for objects that contain an array of items +whose size is determined when the object is allocated. +*/ + +/* Py_DEBUG implies Py_REF_DEBUG. */ +#if defined(Py_DEBUG) && !defined(Py_REF_DEBUG) +#define Py_REF_DEBUG +#endif + +#if defined(Py_LIMITED_API) && defined(Py_REF_DEBUG) +#error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG +#endif + + +#ifdef Py_TRACE_REFS +/* Define pointers to support a doubly-linked list of all live heap objects. */ +#define _PyObject_HEAD_EXTRA \ + struct _object *_ob_next; \ + struct _object *_ob_prev; + +#define _PyObject_EXTRA_INIT 0, 0, + +#else +#define _PyObject_HEAD_EXTRA +#define _PyObject_EXTRA_INIT +#endif + +/* PyObject_HEAD defines the initial segment of every PyObject. */ +#define PyObject_HEAD PyObject ob_base; + +#define PyObject_HEAD_INIT(type) \ + { _PyObject_EXTRA_INIT \ + 1, type }, + +#define PyVarObject_HEAD_INIT(type, size) \ + { PyObject_HEAD_INIT(type) size }, + +/* PyObject_VAR_HEAD defines the initial segment of all variable-size + * container objects. These end with a declaration of an array with 1 + * element, but enough space is malloc'ed so that the array actually + * has room for ob_size elements. Note that ob_size is an element count, + * not necessarily a byte count. + */ +#define PyObject_VAR_HEAD PyVarObject ob_base; +#define Py_INVALID_SIZE (Py_ssize_t)-1 + +/* Nothing is actually declared to be a PyObject, but every pointer to + * a Python object can be cast to a PyObject*. This is inheritance built + * by hand. Similarly every pointer to a variable-size Python object can, + * in addition, be cast to PyVarObject*. + */ +typedef struct _object { + _PyObject_HEAD_EXTRA + Py_ssize_t ob_refcnt; + struct _typeobject *ob_type; +} PyObject; + +/* Cast argument to PyObject* type. */ +#define _PyObject_CAST(op) ((PyObject*)(op)) + +typedef struct { + PyObject ob_base; + Py_ssize_t ob_size; /* Number of items in variable part */ +} PyVarObject; + +/* Cast argument to PyVarObject* type. */ +#define _PyVarObject_CAST(op) ((PyVarObject*)(op)) + +#define Py_REFCNT(ob) (_PyObject_CAST(ob)->ob_refcnt) +#define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type) +#define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size) + +/* +Type objects contain a string containing the type name (to help somewhat +in debugging), the allocation parameters (see PyObject_New() and +PyObject_NewVar()), +and methods for accessing objects of the type. Methods are optional, a +nil pointer meaning that particular kind of access is not available for +this type. The Py_DECREF() macro uses the tp_dealloc method without +checking for a nil pointer; it should always be implemented except if +the implementation can guarantee that the reference count will never +reach zero (e.g., for statically allocated type objects). + +NB: the methods for certain type groups are now contained in separate +method blocks. +*/ + +typedef PyObject * (*unaryfunc)(PyObject *); +typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); +typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); +typedef int (*inquiry)(PyObject *); +typedef Py_ssize_t (*lenfunc)(PyObject *); +typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); +typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); +typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *); +typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *); + +typedef int (*objobjproc)(PyObject *, PyObject *); +typedef int (*visitproc)(PyObject *, void *); +typedef int (*traverseproc)(PyObject *, visitproc, void *); + + +typedef void (*freefunc)(void *); +typedef void (*destructor)(PyObject *); +typedef PyObject *(*getattrfunc)(PyObject *, char *); +typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); +typedef int (*setattrfunc)(PyObject *, char *, PyObject *); +typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *); +typedef PyObject *(*reprfunc)(PyObject *); +typedef Py_hash_t (*hashfunc)(PyObject *); +typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); +typedef PyObject *(*getiterfunc) (PyObject *); +typedef PyObject *(*iternextfunc) (PyObject *); +typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*initproc)(PyObject *, PyObject *, PyObject *); +typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); +typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); + +#ifdef Py_LIMITED_API +/* In Py_LIMITED_API, PyTypeObject is an opaque structure. */ +typedef struct _typeobject PyTypeObject; +#else +/* PyTypeObject is defined in cpython/object.h */ +#endif + +typedef struct{ + int slot; /* slot id, see below */ + void *pfunc; /* function pointer */ +} PyType_Slot; + +typedef struct{ + const char* name; + int basicsize; + int itemsize; + unsigned int flags; + PyType_Slot *slots; /* terminated by slot==0. */ +} PyType_Spec; + +PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 +PyAPI_FUNC(void*) PyType_GetSlot(struct _typeobject*, int); +#endif + +/* Generic type check */ +PyAPI_FUNC(int) PyType_IsSubtype(struct _typeobject *, struct _typeobject *); +#define PyObject_TypeCheck(ob, tp) \ + (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) + +PyAPI_DATA(struct _typeobject) PyType_Type; /* built-in 'type' */ +PyAPI_DATA(struct _typeobject) PyBaseObject_Type; /* built-in 'object' */ +PyAPI_DATA(struct _typeobject) PySuper_Type; /* built-in 'super' */ + +PyAPI_FUNC(unsigned long) PyType_GetFlags(struct _typeobject*); + +#define PyType_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) +#define PyType_CheckExact(op) (Py_TYPE(op) == &PyType_Type) + +PyAPI_FUNC(int) PyType_Ready(struct _typeobject *); +PyAPI_FUNC(PyObject *) PyType_GenericAlloc(struct _typeobject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyType_GenericNew(struct _typeobject *, + PyObject *, PyObject *); +PyAPI_FUNC(unsigned int) PyType_ClearCache(void); +PyAPI_FUNC(void) PyType_Modified(struct _typeobject *); + +/* Generic operations on objects */ +PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_ASCII(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Bytes(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int); +PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *); +PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, + PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(int) PyObject_GenericSetDict(PyObject *, PyObject *, void *); +#endif +PyAPI_FUNC(Py_hash_t) PyObject_Hash(PyObject *); +PyAPI_FUNC(Py_hash_t) PyObject_HashNotImplemented(PyObject *); +PyAPI_FUNC(int) PyObject_IsTrue(PyObject *); +PyAPI_FUNC(int) PyObject_Not(PyObject *); +PyAPI_FUNC(int) PyCallable_Check(PyObject *); +PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); + +/* PyObject_Dir(obj) acts like Python builtins.dir(obj), returning a + list of strings. PyObject_Dir(NULL) is like builtins.dir(), + returning the names of the current locals. In this case, if there are + no current locals, NULL is returned, and PyErr_Occurred() is false. +*/ +PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); + + +/* Helpers for printing recursive container types */ +PyAPI_FUNC(int) Py_ReprEnter(PyObject *); +PyAPI_FUNC(void) Py_ReprLeave(PyObject *); + +/* Flag bits for printing: */ +#define Py_PRINT_RAW 1 /* No string quotes etc. */ + +/* +Type flags (tp_flags) + +These flags are used to change expected features and behavior for a +particular type. + +Arbitration of the flag bit positions will need to be coordinated among +all extension writers who publicly release their extensions (this will +be fewer than you might expect!). + +Most flags were removed as of Python 3.0 to make room for new flags. (Some +flags are not for backwards compatibility but to indicate the presence of an +optional feature; these flags remain of course.) + +Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value. + +Code can use PyType_HasFeature(type_ob, flag_value) to test whether the +given type object has a specified feature. +*/ + +/* Set if the type object is dynamically allocated */ +#define Py_TPFLAGS_HEAPTYPE (1UL << 9) + +/* Set if the type allows subclassing */ +#define Py_TPFLAGS_BASETYPE (1UL << 10) + +/* Set if the type implements the vectorcall protocol (PEP 590) */ +#ifndef Py_LIMITED_API +#define _Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) +#endif + +/* Set if the type is 'ready' -- fully initialized */ +#define Py_TPFLAGS_READY (1UL << 12) + +/* Set while the type is being 'readied', to prevent recursive ready calls */ +#define Py_TPFLAGS_READYING (1UL << 13) + +/* Objects support garbage collection (see objimpl.h) */ +#define Py_TPFLAGS_HAVE_GC (1UL << 14) + +/* These two bits are preserved for Stackless Python, next after this is 17 */ +#ifdef STACKLESS +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3UL << 15) +#else +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 +#endif + +/* Objects behave like an unbound method */ +#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17) + +/* Objects support type attribute cache */ +#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) +#define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19) + +/* Type is abstract and cannot be instantiated */ +#define Py_TPFLAGS_IS_ABSTRACT (1UL << 20) + +/* These flags are used to determine if a type is a subclass. */ +#define Py_TPFLAGS_LONG_SUBCLASS (1UL << 24) +#define Py_TPFLAGS_LIST_SUBCLASS (1UL << 25) +#define Py_TPFLAGS_TUPLE_SUBCLASS (1UL << 26) +#define Py_TPFLAGS_BYTES_SUBCLASS (1UL << 27) +#define Py_TPFLAGS_UNICODE_SUBCLASS (1UL << 28) +#define Py_TPFLAGS_DICT_SUBCLASS (1UL << 29) +#define Py_TPFLAGS_BASE_EXC_SUBCLASS (1UL << 30) +#define Py_TPFLAGS_TYPE_SUBCLASS (1UL << 31) + +#define Py_TPFLAGS_DEFAULT ( \ + Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ + Py_TPFLAGS_HAVE_VERSION_TAG | \ + 0) + +/* NOTE: The following flags reuse lower bits (removed as part of the + * Python 3.0 transition). */ + +/* The following flag is kept for compatibility. Starting with 3.8, + * binary compatibility of C extensions accross feature releases of + * Python is not supported anymore, except when using the stable ABI. + */ + +/* Type structure has tp_finalize member (3.4) */ +#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) + +#ifdef Py_LIMITED_API +# define PyType_HasFeature(t,f) ((PyType_GetFlags(t) & (f)) != 0) +#endif +#define PyType_FastSubclass(t,f) PyType_HasFeature(t,f) + + +/* +The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement +reference counts. Py_DECREF calls the object's deallocator function when +the refcount falls to 0; for +objects that don't contain references to other objects or heap memory +this can be the standard function free(). Both macros can be used +wherever a void expression is allowed. The argument must not be a +NULL pointer. If it may be NULL, use Py_XINCREF/Py_XDECREF instead. +The macro _Py_NewReference(op) initialize reference counts to 1, and +in special builds (Py_REF_DEBUG, Py_TRACE_REFS) performs additional +bookkeeping appropriate to the special build. + +We assume that the reference count field can never overflow; this can +be proven when the size of the field is the same as the pointer size, so +we ignore the possibility. Provided a C int is at least 32 bits (which +is implicitly assumed in many parts of this code), that's enough for +about 2**31 references to an object. + +XXX The following became out of date in Python 2.2, but I'm not sure +XXX what the full truth is now. Certainly, heap-allocated type objects +XXX can and should be deallocated. +Type objects should never be deallocated; the type pointer in an object +is not considered to be a reference to the type object, to save +complications in the deallocation function. (This is actually a +decision that's up to the implementer of each new type so if you want, +you can count such references to the type object.) +*/ + +/* First define a pile of simple helper macros, one set per special + * build symbol. These either expand to the obvious things, or to + * nothing at all when the special mode isn't in effect. The main + * macros can later be defined just once then, yet expand to different + * things depending on which special build options are and aren't in effect. + * Trust me : while painful, this is 20x easier to understand than, + * e.g, defining _Py_NewReference five different times in a maze of nested + * #ifdefs (we used to do that -- it was impenetrable). + */ +#ifdef Py_REF_DEBUG +PyAPI_DATA(Py_ssize_t) _Py_RefTotal; +PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, + PyObject *op); +PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); +#define _Py_INC_REFTOTAL _Py_RefTotal++ +#define _Py_DEC_REFTOTAL _Py_RefTotal-- + +/* Py_REF_DEBUG also controls the display of refcounts and memory block + * allocations at the interactive prompt and at interpreter shutdown + */ +PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void); +#else +#define _Py_INC_REFTOTAL +#define _Py_DEC_REFTOTAL +#endif /* Py_REF_DEBUG */ + +#ifdef COUNT_ALLOCS +PyAPI_FUNC(void) _Py_inc_count(struct _typeobject *); +PyAPI_FUNC(void) _Py_dec_count(struct _typeobject *); +#define _Py_INC_TPALLOCS(OP) _Py_inc_count(Py_TYPE(OP)) +#define _Py_INC_TPFREES(OP) _Py_dec_count(Py_TYPE(OP)) +#define _Py_DEC_TPFREES(OP) Py_TYPE(OP)->tp_frees-- +#define _Py_COUNT_ALLOCS_COMMA , +#else +#define _Py_INC_TPALLOCS(OP) +#define _Py_INC_TPFREES(OP) +#define _Py_DEC_TPFREES(OP) +#define _Py_COUNT_ALLOCS_COMMA +#endif /* COUNT_ALLOCS */ + +/* Update the Python traceback of an object. This function must be called + when a memory block is reused from a free list. */ +PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op); + +#ifdef Py_TRACE_REFS +/* Py_TRACE_REFS is such major surgery that we call external routines. */ +PyAPI_FUNC(void) _Py_NewReference(PyObject *); +PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); +PyAPI_FUNC(void) _Py_PrintReferences(FILE *); +PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *); +PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); +#else +/* Without Py_TRACE_REFS, there's little enough to do that we expand code + inline. */ +static inline void _Py_NewReference(PyObject *op) +{ + if (_Py_tracemalloc_config.tracing) { + _PyTraceMalloc_NewReference(op); + } + _Py_INC_TPALLOCS(op); + _Py_INC_REFTOTAL; + Py_REFCNT(op) = 1; +} + +static inline void _Py_ForgetReference(PyObject *op) +{ + (void)op; /* may be unused, shut up -Wunused-parameter */ + _Py_INC_TPFREES(op); +} +#endif /* !Py_TRACE_REFS */ + + +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); + +static inline void _Py_INCREF(PyObject *op) +{ + _Py_INC_REFTOTAL; + op->ob_refcnt++; +} + +#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op)) + +static inline void _Py_DECREF(const char *filename, int lineno, + PyObject *op) +{ + (void)filename; /* may be unused, shut up -Wunused-parameter */ + (void)lineno; /* may be unused, shut up -Wunused-parameter */ + _Py_DEC_REFTOTAL; + if (--op->ob_refcnt != 0) { +#ifdef Py_REF_DEBUG + if (op->ob_refcnt < 0) { + _Py_NegativeRefcount(filename, lineno, op); + } +#endif + } + else { + _Py_Dealloc(op); + } +} + +#define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) + + +/* Safely decref `op` and set `op` to NULL, especially useful in tp_clear + * and tp_dealloc implementations. + * + * Note that "the obvious" code can be deadly: + * + * Py_XDECREF(op); + * op = NULL; + * + * Typically, `op` is something like self->containee, and `self` is done + * using its `containee` member. In the code sequence above, suppose + * `containee` is non-NULL with a refcount of 1. Its refcount falls to + * 0 on the first line, which can trigger an arbitrary amount of code, + * possibly including finalizers (like __del__ methods or weakref callbacks) + * coded in Python, which in turn can release the GIL and allow other threads + * to run, etc. Such code may even invoke methods of `self` again, or cause + * cyclic gc to trigger, but-- oops! --self->containee still points to the + * object being torn down, and it may be in an insane state while being torn + * down. This has in fact been a rich historic source of miserable (rare & + * hard-to-diagnose) segfaulting (and other) bugs. + * + * The safe way is: + * + * Py_CLEAR(op); + * + * That arranges to set `op` to NULL _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * There are cases where it's safe to use the naive code, but they're brittle. + * For example, if `op` points to a Python integer, you know that destroying + * one of those can't cause problems -- but in part that relies on that + * Python integers aren't currently weakly referencable. Best practice is + * to use Py_CLEAR() even if you can't think of a reason for why you need to. + */ +#define Py_CLEAR(op) \ + do { \ + PyObject *_py_tmp = _PyObject_CAST(op); \ + if (_py_tmp != NULL) { \ + (op) = NULL; \ + Py_DECREF(_py_tmp); \ + } \ + } while (0) + +/* Function to use in case the object pointer can be NULL: */ +static inline void _Py_XINCREF(PyObject *op) +{ + if (op != NULL) { + Py_INCREF(op); + } +} + +#define Py_XINCREF(op) _Py_XINCREF(_PyObject_CAST(op)) + +static inline void _Py_XDECREF(PyObject *op) +{ + if (op != NULL) { + Py_DECREF(op); + } +} + +#define Py_XDECREF(op) _Py_XDECREF(_PyObject_CAST(op)) + +/* +These are provided as conveniences to Python runtime embedders, so that +they can have object code that is not dependent on Python compilation flags. +*/ +PyAPI_FUNC(void) Py_IncRef(PyObject *); +PyAPI_FUNC(void) Py_DecRef(PyObject *); + +/* +_Py_NoneStruct is an object of undefined type which can be used in contexts +where NULL (nil) is not suitable (since NULL often means 'error'). + +Don't forget to apply Py_INCREF() when returning this value!!! +*/ +PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ +#define Py_None (&_Py_NoneStruct) + +/* Macro for returning Py_None from a function */ +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None + +/* +Py_NotImplemented is a singleton used to signal that an operation is +not implemented for a given type combination. +*/ +PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ +#define Py_NotImplemented (&_Py_NotImplementedStruct) + +/* Macro for returning Py_NotImplemented from a function */ +#define Py_RETURN_NOTIMPLEMENTED \ + return Py_INCREF(Py_NotImplemented), Py_NotImplemented + +/* Rich comparison opcodes */ +#define Py_LT 0 +#define Py_LE 1 +#define Py_EQ 2 +#define Py_NE 3 +#define Py_GT 4 +#define Py_GE 5 + +/* + * Macro for implementing rich comparisons + * + * Needs to be a macro because any C-comparable type can be used. + */ +#define Py_RETURN_RICHCOMPARE(val1, val2, op) \ + do { \ + switch (op) { \ + case Py_EQ: if ((val1) == (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_NE: if ((val1) != (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_LT: if ((val1) < (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_GT: if ((val1) > (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_LE: if ((val1) <= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + case Py_GE: if ((val1) >= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ + default: \ + Py_UNREACHABLE(); \ + } \ + } while (0) + + +/* +More conventions +================ + +Argument Checking +----------------- + +Functions that take objects as arguments normally don't check for nil +arguments, but they do check the type of the argument, and return an +error if the function doesn't apply to the type. + +Failure Modes +------------- + +Functions may fail for a variety of reasons, including running out of +memory. This is communicated to the caller in two ways: an error string +is set (see errors.h), and the function result differs: functions that +normally return a pointer return NULL for failure, functions returning +an integer return -1 (which could be a legal return value too!), and +other functions return 0 for success and -1 for failure. +Callers should always check for errors before using the result. If +an error was set, the caller must either explicitly clear it, or pass +the error on to its caller. + +Reference Counts +---------------- + +It takes a while to get used to the proper usage of reference counts. + +Functions that create an object set the reference count to 1; such new +objects must be stored somewhere or destroyed again with Py_DECREF(). +Some functions that 'store' objects, such as PyTuple_SetItem() and +PyList_SetItem(), +don't increment the reference count of the object, since the most +frequent use is to store a fresh object. Functions that 'retrieve' +objects, such as PyTuple_GetItem() and PyDict_GetItemString(), also +don't increment +the reference count, since most frequently the object is only looked at +quickly. Thus, to retrieve an object and store it again, the caller +must call Py_INCREF() explicitly. + +NOTE: functions that 'consume' a reference count, like +PyList_SetItem(), consume the reference even if the object wasn't +successfully stored, to simplify error handling. + +It seems attractive to make other functions that take an object as +argument consume a reference count; however, this may quickly get +confusing (even the current practice is already confusing). Consider +it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at +times. +*/ + + +/* Trashcan mechanism, thanks to Christian Tismer. + +When deallocating a container object, it's possible to trigger an unbounded +chain of deallocations, as each Py_DECREF in turn drops the refcount on "the +next" object in the chain to 0. This can easily lead to stack overflows, +especially in threads (which typically have less stack space to work with). + +A container object can avoid this by bracketing the body of its tp_dealloc +function with a pair of macros: + +static void +mytype_dealloc(mytype *p) +{ + ... declarations go here ... + + PyObject_GC_UnTrack(p); // must untrack first + Py_TRASHCAN_BEGIN(p, mytype_dealloc) + ... The body of the deallocator goes here, including all calls ... + ... to Py_DECREF on contained objects. ... + Py_TRASHCAN_END // there should be no code after this +} + +CAUTION: Never return from the middle of the body! If the body needs to +"get out early", put a label immediately before the Py_TRASHCAN_END +call, and goto it. Else the call-depth counter (see below) will stay +above 0 forever, and the trashcan will never get emptied. + +How it works: The BEGIN macro increments a call-depth counter. So long +as this counter is small, the body of the deallocator is run directly without +further ado. But if the counter gets large, it instead adds p to a list of +objects to be deallocated later, skips the body of the deallocator, and +resumes execution after the END macro. The tp_dealloc routine then returns +without deallocating anything (and so unbounded call-stack depth is avoided). + +When the call stack finishes unwinding again, code generated by the END macro +notices this, and calls another routine to deallocate all the objects that +may have been added to the list of deferred deallocations. In effect, a +chain of N deallocations is broken into (N-1)/(PyTrash_UNWIND_LEVEL-1) pieces, +with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL. + +Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base +class, we need to ensure that the trashcan is only triggered on the tp_dealloc +of the actual class being deallocated. Otherwise we might end up with a +partially-deallocated object. To check this, the tp_dealloc function must be +passed as second argument to Py_TRASHCAN_BEGIN(). +*/ + +/* The new thread-safe private API, invoked by the macros below. */ +PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyObject*); +PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void); + +#define PyTrash_UNWIND_LEVEL 50 + +#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \ + do { \ + PyThreadState *_tstate = NULL; \ + /* If "cond" is false, then _tstate remains NULL and the deallocator \ + * is run normally without involving the trashcan */ \ + if (cond) { \ + _tstate = PyThreadState_GET(); \ + if (_tstate->trash_delete_nesting >= PyTrash_UNWIND_LEVEL) { \ + /* Store the object (to be deallocated later) and jump past \ + * Py_TRASHCAN_END, skipping the body of the deallocator */ \ + _PyTrash_thread_deposit_object(_PyObject_CAST(op)); \ + break; \ + } \ + ++_tstate->trash_delete_nesting; \ + } + /* The body of the deallocator is here. */ +#define Py_TRASHCAN_END \ + if (_tstate) { \ + --_tstate->trash_delete_nesting; \ + if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \ + _PyTrash_thread_destroy_chain(); \ + } \ + } while (0); + +#define Py_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN_CONDITION(op, \ + Py_TYPE(op)->tp_dealloc == (destructor)(dealloc)) + +/* For backwards compatibility, these macros enable the trashcan + * unconditionally */ +#define Py_TRASHCAN_SAFE_BEGIN(op) Py_TRASHCAN_BEGIN_CONDITION(op, 1) +#define Py_TRASHCAN_SAFE_END(op) Py_TRASHCAN_END + + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_OBJECT_H +# include "cpython/object.h" +# undef Py_CPYTHON_OBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJECT_H */ diff --git a/python/include/objimpl.h b/python/include/objimpl.h new file mode 100755 index 0000000..2337d8a --- /dev/null +++ b/python/include/objimpl.h @@ -0,0 +1,284 @@ +/* The PyObject_ memory family: high-level object memory interfaces. + See pymem.h for the low-level PyMem_ family. +*/ + +#ifndef Py_OBJIMPL_H +#define Py_OBJIMPL_H + +#include "pymem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyObject_ memory functions with calls to the platform + malloc/realloc/ calloc/free, or with calls to PyMem_. +*/ + +/* +Functions and macros for modules that implement new object types. + + - PyObject_New(type, typeobj) allocates memory for a new object of the given + type, and initializes part of it. 'type' must be the C structure type used + to represent the object, and 'typeobj' the address of the corresponding + type object. Reference count and type pointer are filled in; the rest of + the bytes of the object are *undefined*! The resulting expression type is + 'type *'. The size of the object is determined by the tp_basicsize field + of the type object. + + - PyObject_NewVar(type, typeobj, n) is similar but allocates a variable-size + object with room for n items. In addition to the refcount and type pointer + fields, this also fills in the ob_size field. + + - PyObject_Del(op) releases the memory allocated for an object. It does not + run a destructor -- it only frees the memory. PyObject_Free is identical. + + - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't + allocate memory. Instead of a 'type' parameter, they take a pointer to a + new object (allocated by an arbitrary allocator), and initialize its object + header fields. + +Note that objects created with PyObject_{New, NewVar} are allocated using the +specialized Python allocator (implemented in obmalloc.c), if WITH_PYMALLOC is +enabled. In addition, a special debugging allocator is used if PYMALLOC_DEBUG +is also #defined. + +In case a specific form of memory management is needed (for example, if you +must use the platform malloc heap(s), or shared memory, or C++ local storage or +operator new), you must first allocate the object with your custom allocator, +then pass its pointer to PyObject_{Init, InitVar} for filling in its Python- +specific fields: reference count, type pointer, possibly others. You should +be aware that Python has no control over these objects because they don't +cooperate with the Python memory manager. Such objects may not be eligible +for automatic garbage collection and you have to make sure that they are +released accordingly whenever their destructor gets called (cf. the specific +form of memory management you're using). + +Unless you have specific memory management requirements, use +PyObject_{New, NewVar, Del}. +*/ + +/* + * Raw object memory interface + * =========================== + */ + +/* Functions to call the same malloc/realloc/free as used by Python's + object allocator. If WITH_PYMALLOC is enabled, these may differ from + the platform malloc/realloc/free. The Python object allocator is + designed for fast, cache-conscious allocation of many "small" objects, + and with low hidden memory overhead. + + PyObject_Malloc(0) returns a unique non-NULL pointer if possible. + + PyObject_Realloc(NULL, n) acts like PyObject_Malloc(n). + PyObject_Realloc(p != NULL, 0) does not return NULL, or free the memory + at p. + + Returned pointers must be checked for NULL explicitly; no action is + performed on failure other than to return NULL (no warning it printed, no + exception is set, etc). + + For allocating objects, use PyObject_{New, NewVar} instead whenever + possible. The PyObject_{Malloc, Realloc, Free} family is exposed + so that you can exploit Python's small-block allocator for non-object + uses. If you must use these routines to allocate object memory, make sure + the object gets initialized via PyObject_{Init, InitVar} after obtaining + the raw memory. +*/ +PyAPI_FUNC(void *) PyObject_Malloc(size_t size); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(void *) PyObject_Calloc(size_t nelem, size_t elsize); +#endif +PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyObject_Free(void *ptr); + + +/* Macros */ +#define PyObject_MALLOC PyObject_Malloc +#define PyObject_REALLOC PyObject_Realloc +#define PyObject_FREE PyObject_Free +#define PyObject_Del PyObject_Free +#define PyObject_DEL PyObject_Free + + +/* + * Generic object allocator interface + * ================================== + */ + +/* Functions */ +PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *); +PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *, + PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); + +#define PyObject_New(type, typeobj) \ + ( (type *) _PyObject_New(typeobj) ) +#define PyObject_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_NewVar((typeobj), (n)) ) + +/* Inline functions trading binary compatibility for speed: + PyObject_INIT() is the fast version of PyObject_Init(), and + PyObject_INIT_VAR() is the fast version of PyObject_InitVar. + See also pymem.h. + + These inline functions expect non-NULL object pointers. */ +static inline PyObject* +_PyObject_INIT(PyObject *op, PyTypeObject *typeobj) +{ + assert(op != NULL); + Py_TYPE(op) = typeobj; + if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(typeobj); + } + _Py_NewReference(op); + return op; +} + +#define PyObject_INIT(op, typeobj) \ + _PyObject_INIT(_PyObject_CAST(op), (typeobj)) + +static inline PyVarObject* +_PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) +{ + assert(op != NULL); + Py_SIZE(op) = size; + PyObject_INIT((PyObject *)op, typeobj); + return op; +} + +#define PyObject_INIT_VAR(op, typeobj, size) \ + _PyObject_INIT_VAR(_PyVarObject_CAST(op), (typeobj), (size)) + +#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) + +/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a + vrbl-size object with nitems items, exclusive of gc overhead (if any). The + value is rounded up to the closest multiple of sizeof(void *), in order to + ensure that pointer fields at the end of the object are correctly aligned + for the platform (this is of special importance for subclasses of, e.g., + str or int, so that pointers can be stored after the embedded data). + + Note that there's no memory wastage in doing this, as malloc has to + return (at worst) pointer-aligned memory anyway. +*/ +#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 +# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" +#endif + +#define _PyObject_VAR_SIZE(typeobj, nitems) \ + _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \ + (nitems)*(typeobj)->tp_itemsize, \ + SIZEOF_VOID_P) + +#define PyObject_NEW(type, typeobj) \ +( (type *) PyObject_Init( \ + (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) + +#define PyObject_NEW_VAR(type, typeobj, n) \ +( (type *) PyObject_InitVar( \ + (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\ + (typeobj), (n)) ) + +/* This example code implements an object constructor with a custom + allocator, where PyObject_New is inlined, and shows the important + distinction between two steps (at least): + 1) the actual allocation of the object storage; + 2) the initialization of the Python specific fields + in this storage with PyObject_{Init, InitVar}. + + PyObject * + YourObject_New(...) + { + PyObject *op; + + op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); + if (op == NULL) + return PyErr_NoMemory(); + + PyObject_Init(op, &YourTypeStruct); + + op->ob_field = value; + ... + return op; + } + + Note that in C++, the use of the new operator usually implies that + the 1st step is performed automatically for you, so in a C++ class + constructor you would start directly with PyObject_Init/InitVar +*/ + + + +/* + * Garbage Collection Support + * ========================== + */ + +/* C equivalent of gc.collect() which ignores the state of gc.enabled. */ +PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void); + +/* Test if a type has a GC head */ +#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) + +PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); +#define PyObject_GC_Resize(type, op, n) \ + ( (type *) _PyObject_GC_Resize(_PyVarObject_CAST(op), (n)) ) + + + +PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); + +/* Tell the GC to track this object. + * + * See also private _PyObject_GC_TRACK() macro. */ +PyAPI_FUNC(void) PyObject_GC_Track(void *); + +/* Tell the GC to stop tracking this object. + * + * See also private _PyObject_GC_UNTRACK() macro. */ +PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); + +PyAPI_FUNC(void) PyObject_GC_Del(void *); + +#define PyObject_GC_New(type, typeobj) \ + ( (type *) _PyObject_GC_New(typeobj) ) +#define PyObject_GC_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_GC_NewVar((typeobj), (n)) ) + + +/* Utility macro to help write tp_traverse functions. + * To use this macro, the tp_traverse function must name its arguments + * "visit" and "arg". This is intended to keep tp_traverse functions + * looking as much alike as possible. + */ +#define Py_VISIT(op) \ + do { \ + if (op) { \ + int vret = visit(_PyObject_CAST(op), arg); \ + if (vret) \ + return vret; \ + } \ + } while (0) + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_OBJIMPL_H +# include "cpython/objimpl.h" +# undef Py_CPYTHON_OBJIMPL_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJIMPL_H */ diff --git a/python/include/odictobject.h b/python/include/odictobject.h new file mode 100755 index 0000000..35aff8a --- /dev/null +++ b/python/include/odictobject.h @@ -0,0 +1,43 @@ +#ifndef Py_ODICTOBJECT_H +#define Py_ODICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* OrderedDict */ +/* This API is optional and mostly redundant. */ + +#ifndef Py_LIMITED_API + +typedef struct _odictobject PyODictObject; + +PyAPI_DATA(PyTypeObject) PyODict_Type; +PyAPI_DATA(PyTypeObject) PyODictIter_Type; +PyAPI_DATA(PyTypeObject) PyODictKeys_Type; +PyAPI_DATA(PyTypeObject) PyODictItems_Type; +PyAPI_DATA(PyTypeObject) PyODictValues_Type; + +#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) +#define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type) +#define PyODict_SIZE(op) PyDict_GET_SIZE((op)) + +PyAPI_FUNC(PyObject *) PyODict_New(void); +PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); +PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); + +/* wrappers around PyDict* functions */ +#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), key) +#define PyODict_GetItemWithError(od, key) \ + PyDict_GetItemWithError(_PyObject_CAST(od), key) +#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key) +#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od)) +#define PyODict_GetItemString(od, key) \ + PyDict_GetItemString(_PyObject_CAST(od), key) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ODICTOBJECT_H */ diff --git a/python/include/opcode.h b/python/include/opcode.h new file mode 100755 index 0000000..2a29e97 --- /dev/null +++ b/python/include/opcode.h @@ -0,0 +1,148 @@ +/* Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py */ +#ifndef Py_OPCODE_H +#define Py_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + + /* Instruction opcodes for compiled code */ +#define POP_TOP 1 +#define ROT_TWO 2 +#define ROT_THREE 3 +#define DUP_TOP 4 +#define DUP_TOP_TWO 5 +#define ROT_FOUR 6 +#define NOP 9 +#define UNARY_POSITIVE 10 +#define UNARY_NEGATIVE 11 +#define UNARY_NOT 12 +#define UNARY_INVERT 15 +#define BINARY_MATRIX_MULTIPLY 16 +#define INPLACE_MATRIX_MULTIPLY 17 +#define BINARY_POWER 19 +#define BINARY_MULTIPLY 20 +#define BINARY_MODULO 22 +#define BINARY_ADD 23 +#define BINARY_SUBTRACT 24 +#define BINARY_SUBSCR 25 +#define BINARY_FLOOR_DIVIDE 26 +#define BINARY_TRUE_DIVIDE 27 +#define INPLACE_FLOOR_DIVIDE 28 +#define INPLACE_TRUE_DIVIDE 29 +#define GET_AITER 50 +#define GET_ANEXT 51 +#define BEFORE_ASYNC_WITH 52 +#define BEGIN_FINALLY 53 +#define END_ASYNC_FOR 54 +#define INPLACE_ADD 55 +#define INPLACE_SUBTRACT 56 +#define INPLACE_MULTIPLY 57 +#define INPLACE_MODULO 59 +#define STORE_SUBSCR 60 +#define DELETE_SUBSCR 61 +#define BINARY_LSHIFT 62 +#define BINARY_RSHIFT 63 +#define BINARY_AND 64 +#define BINARY_XOR 65 +#define BINARY_OR 66 +#define INPLACE_POWER 67 +#define GET_ITER 68 +#define GET_YIELD_FROM_ITER 69 +#define PRINT_EXPR 70 +#define LOAD_BUILD_CLASS 71 +#define YIELD_FROM 72 +#define GET_AWAITABLE 73 +#define INPLACE_LSHIFT 75 +#define INPLACE_RSHIFT 76 +#define INPLACE_AND 77 +#define INPLACE_XOR 78 +#define INPLACE_OR 79 +#define WITH_CLEANUP_START 81 +#define WITH_CLEANUP_FINISH 82 +#define RETURN_VALUE 83 +#define IMPORT_STAR 84 +#define SETUP_ANNOTATIONS 85 +#define YIELD_VALUE 86 +#define POP_BLOCK 87 +#define END_FINALLY 88 +#define POP_EXCEPT 89 +#define HAVE_ARGUMENT 90 +#define STORE_NAME 90 +#define DELETE_NAME 91 +#define UNPACK_SEQUENCE 92 +#define FOR_ITER 93 +#define UNPACK_EX 94 +#define STORE_ATTR 95 +#define DELETE_ATTR 96 +#define STORE_GLOBAL 97 +#define DELETE_GLOBAL 98 +#define LOAD_CONST 100 +#define LOAD_NAME 101 +#define BUILD_TUPLE 102 +#define BUILD_LIST 103 +#define BUILD_SET 104 +#define BUILD_MAP 105 +#define LOAD_ATTR 106 +#define COMPARE_OP 107 +#define IMPORT_NAME 108 +#define IMPORT_FROM 109 +#define JUMP_FORWARD 110 +#define JUMP_IF_FALSE_OR_POP 111 +#define JUMP_IF_TRUE_OR_POP 112 +#define JUMP_ABSOLUTE 113 +#define POP_JUMP_IF_FALSE 114 +#define POP_JUMP_IF_TRUE 115 +#define LOAD_GLOBAL 116 +#define SETUP_FINALLY 122 +#define LOAD_FAST 124 +#define STORE_FAST 125 +#define DELETE_FAST 126 +#define RAISE_VARARGS 130 +#define CALL_FUNCTION 131 +#define MAKE_FUNCTION 132 +#define BUILD_SLICE 133 +#define LOAD_CLOSURE 135 +#define LOAD_DEREF 136 +#define STORE_DEREF 137 +#define DELETE_DEREF 138 +#define CALL_FUNCTION_KW 141 +#define CALL_FUNCTION_EX 142 +#define SETUP_WITH 143 +#define EXTENDED_ARG 144 +#define LIST_APPEND 145 +#define SET_ADD 146 +#define MAP_ADD 147 +#define LOAD_CLASSDEREF 148 +#define BUILD_LIST_UNPACK 149 +#define BUILD_MAP_UNPACK 150 +#define BUILD_MAP_UNPACK_WITH_CALL 151 +#define BUILD_TUPLE_UNPACK 152 +#define BUILD_SET_UNPACK 153 +#define SETUP_ASYNC_WITH 154 +#define FORMAT_VALUE 155 +#define BUILD_CONST_KEY_MAP 156 +#define BUILD_STRING 157 +#define BUILD_TUPLE_UNPACK_WITH_CALL 158 +#define LOAD_METHOD 160 +#define CALL_METHOD 161 +#define CALL_FINALLY 162 +#define POP_FINALLY 163 + +/* EXCEPT_HANDLER is a special, implicit block type which is created when + entering an except handler. It is not an opcode but we define it here + as we want it to be available to both frameobject.c and ceval.c, while + remaining private.*/ +#define EXCEPT_HANDLER 257 + + +enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, + PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, PyCmp_IN, PyCmp_NOT_IN, + PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; + +#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_H */ diff --git a/python/include/osdefs.h b/python/include/osdefs.h new file mode 100755 index 0000000..3243944 --- /dev/null +++ b/python/include/osdefs.h @@ -0,0 +1,51 @@ +#ifndef Py_OSDEFS_H +#define Py_OSDEFS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Operating system dependencies */ + +#ifdef MS_WINDOWS +#define SEP L'\\' +#define ALTSEP L'/' +#define MAXPATHLEN 256 +#define DELIM L';' +#endif + +#ifdef __VXWORKS__ +#define DELIM L';' +#endif + +/* Filename separator */ +#ifndef SEP +#define SEP L'/' +#endif + +/* Max pathname length */ +#ifdef __hpux +#include +#include +#ifndef PATH_MAX +#define PATH_MAX MAXPATHLEN +#endif +#endif + +#ifndef MAXPATHLEN +#if defined(PATH_MAX) && PATH_MAX > 1024 +#define MAXPATHLEN PATH_MAX +#else +#define MAXPATHLEN 1024 +#endif +#endif + +/* Search path entry delimiter */ +#ifndef DELIM +#define DELIM L':' +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OSDEFS_H */ diff --git a/python/include/osmodule.h b/python/include/osmodule.h new file mode 100755 index 0000000..9095c2f --- /dev/null +++ b/python/include/osmodule.h @@ -0,0 +1,17 @@ + +/* os module interface */ + +#ifndef Py_OSMODULE_H +#define Py_OSMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_FUNC(PyObject *) PyOS_FSPath(PyObject *path); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OSMODULE_H */ diff --git a/python/include/parsetok.h b/python/include/parsetok.h new file mode 100755 index 0000000..935d733 --- /dev/null +++ b/python/include/parsetok.h @@ -0,0 +1,110 @@ +/* Parser-tokenizer link interface */ + +#ifndef Py_LIMITED_API +#ifndef Py_PARSETOK_H +#define Py_PARSETOK_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "grammar.h" /* grammar */ +#include "node.h" /* node */ + +typedef struct { + int error; + PyObject *filename; + int lineno; + int offset; + char *text; /* UTF-8-encoded string */ + int token; + int expected; +} perrdetail; + +#if 0 +#define PyPARSE_YIELD_IS_KEYWORD 0x0001 +#endif + +#define PyPARSE_DONT_IMPLY_DEDENT 0x0002 + +#if 0 +#define PyPARSE_WITH_IS_KEYWORD 0x0003 +#define PyPARSE_PRINT_IS_FUNCTION 0x0004 +#define PyPARSE_UNICODE_LITERALS 0x0008 +#endif + +#define PyPARSE_IGNORE_COOKIE 0x0010 +#define PyPARSE_BARRY_AS_BDFL 0x0020 +#define PyPARSE_TYPE_COMMENTS 0x0040 +#define PyPARSE_ASYNC_HACKS 0x0080 + +PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, + perrdetail *); +PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int, + const char *, const char *, + perrdetail *); + +PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int, + perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseFileFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + const char *enc, + grammar *g, + int start, + const char *ps1, + const char *ps2, + perrdetail *err_ret, + int flags); +PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + const char *enc, + grammar *g, + int start, + const char *ps1, + const char *ps2, + perrdetail *err_ret, + int *flags); +PyAPI_FUNC(node *) PyParser_ParseFileObject( + FILE *fp, + PyObject *filename, + const char *enc, + grammar *g, + int start, + const char *ps1, + const char *ps2, + perrdetail *err_ret, + int *flags); + +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename( + const char *s, + const char *filename, /* decoded from the filesystem encoding */ + grammar *g, + int start, + perrdetail *err_ret, + int flags); +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx( + const char *s, + const char *filename, /* decoded from the filesystem encoding */ + grammar *g, + int start, + perrdetail *err_ret, + int *flags); +PyAPI_FUNC(node *) PyParser_ParseStringObject( + const char *s, + PyObject *filename, + grammar *g, + int start, + perrdetail *err_ret, + int *flags); + +/* Note that the following functions are defined in pythonrun.c, + not in parsetok.c */ +PyAPI_FUNC(void) PyParser_SetError(perrdetail *); +PyAPI_FUNC(void) PyParser_ClearError(perrdetail *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PARSETOK_H */ +#endif /* !Py_LIMITED_API */ diff --git a/python/include/patchlevel.h b/python/include/patchlevel.h new file mode 100755 index 0000000..d23d5af --- /dev/null +++ b/python/include/patchlevel.h @@ -0,0 +1,35 @@ + +/* Python version identification scheme. + + When the major or minor version changes, the VERSION variable in + configure.ac must also be changed. + + There is also (independent) API version information in modsupport.h. +*/ + +/* Values for PY_RELEASE_LEVEL */ +#define PY_RELEASE_LEVEL_ALPHA 0xA +#define PY_RELEASE_LEVEL_BETA 0xB +#define PY_RELEASE_LEVEL_GAMMA 0xC /* For release candidates */ +#define PY_RELEASE_LEVEL_FINAL 0xF /* Serial should be 0 here */ + /* Higher for patch releases */ + +/* Version parsed out into numeric values */ +/*--start constants--*/ +#define PY_MAJOR_VERSION 3 +#define PY_MINOR_VERSION 8 +#define PY_MICRO_VERSION 10 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 + +/* Version as a string */ +#define PY_VERSION "3.8.10" +/*--end constants--*/ + +/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. + Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */ +#define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \ + (PY_MINOR_VERSION << 16) | \ + (PY_MICRO_VERSION << 8) | \ + (PY_RELEASE_LEVEL << 4) | \ + (PY_RELEASE_SERIAL << 0)) diff --git a/python/include/picklebufobject.h b/python/include/picklebufobject.h new file mode 100755 index 0000000..f07e900 --- /dev/null +++ b/python/include/picklebufobject.h @@ -0,0 +1,31 @@ +/* PickleBuffer object. This is built-in for ease of use from third-party + * C extensions. + */ + +#ifndef Py_PICKLEBUFOBJECT_H +#define Py_PICKLEBUFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + +PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type; + +#define PyPickleBuffer_Check(op) (Py_TYPE(op) == &PyPickleBuffer_Type) + +/* Create a PickleBuffer redirecting to the given buffer-enabled object */ +PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *); +/* Get the PickleBuffer's underlying view to the original object + * (NULL if released) + */ +PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *); +/* Release the PickleBuffer. Returns 0 on success, -1 on error. */ +PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *); + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PICKLEBUFOBJECT_H */ diff --git a/python/include/py_curses.h b/python/include/py_curses.h new file mode 100755 index 0000000..2702b37 --- /dev/null +++ b/python/include/py_curses.h @@ -0,0 +1,100 @@ + +#ifndef Py_CURSES_H +#define Py_CURSES_H + +#ifdef __APPLE__ +/* +** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards +** against multiple definition of wchar_t. +*/ +#ifdef _BSD_WCHAR_T_DEFINED_ +#define _WCHAR_T +#endif +#endif /* __APPLE__ */ + +/* On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards + against multiple definition of wchar_t and wint_t. */ +#if defined(__FreeBSD__) && defined(_XOPEN_SOURCE_EXTENDED) +# ifndef __wchar_t +# define __wchar_t +# endif +# ifndef __wint_t +# define __wint_t +# endif +#endif + +#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS) +/* The following definition is necessary for ncurses 5.7; without it, + some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python + can't get at the WINDOW flags field. */ +#define NCURSES_OPAQUE 0 +#endif + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#endif + +#ifdef HAVE_NCURSES_H +/* configure was checking , but we will + use , which has some or all these features. */ +#if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0) +#define WINDOW_HAS_FLAGS 1 +#endif +#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906 +#define HAVE_CURSES_IS_PAD 1 +#endif +#ifndef MVWDELCH_IS_EXPRESSION +#define MVWDELCH_IS_EXPRESSION 1 +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define PyCurses_API_pointers 4 + +/* Type declarations */ + +typedef struct { + PyObject_HEAD + WINDOW *win; + char *encoding; +} PyCursesWindowObject; + +#define PyCursesWindow_Check(v) (Py_TYPE(v) == &PyCursesWindow_Type) + +#define PyCurses_CAPSULE_NAME "_curses._C_API" + + +#ifdef CURSES_MODULE +/* This section is used when compiling _cursesmodule.c */ + +#else +/* This section is used in modules that use the _cursesmodule API */ + +static void **PyCurses_API; + +#define PyCursesWindow_Type (*(PyTypeObject *) PyCurses_API[0]) +#define PyCursesSetupTermCalled {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;} +#define PyCursesInitialised {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;} +#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;} + +#define import_curses() \ + PyCurses_API = (void **)PyCapsule_Import(PyCurses_CAPSULE_NAME, 1); + +#endif + +/* general error messages */ +static const char catchall_ERR[] = "curses function returned ERR"; +static const char catchall_NULL[] = "curses function returned NULL"; + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(Py_CURSES_H) */ + + diff --git a/python/include/pyarena.h b/python/include/pyarena.h new file mode 100755 index 0000000..db3ad01 --- /dev/null +++ b/python/include/pyarena.h @@ -0,0 +1,64 @@ +/* An arena-like memory interface for the compiler. + */ + +#ifndef Py_LIMITED_API +#ifndef Py_PYARENA_H +#define Py_PYARENA_H + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _arena PyArena; + + /* PyArena_New() and PyArena_Free() create a new arena and free it, + respectively. Once an arena has been created, it can be used + to allocate memory via PyArena_Malloc(). Pointers to PyObject can + also be registered with the arena via PyArena_AddPyObject(), and the + arena will ensure that the PyObjects stay alive at least until + PyArena_Free() is called. When an arena is freed, all the memory it + allocated is freed, the arena releases internal references to registered + PyObject*, and none of its pointers are valid. + XXX (tim) What does "none of its pointers are valid" mean? Does it + XXX mean that pointers previously obtained via PyArena_Malloc() are + XXX no longer valid? (That's clearly true, but not sure that's what + XXX the text is trying to say.) + + PyArena_New() returns an arena pointer. On error, it + returns a negative number and sets an exception. + XXX (tim): Not true. On error, PyArena_New() actually returns NULL, + XXX and looks like it may or may not set an exception (e.g., if the + XXX internal PyList_New(0) returns NULL, PyArena_New() passes that on + XXX and an exception is set; OTOH, if the internal + XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but + XXX an exception is not set in that case). + */ + PyAPI_FUNC(PyArena *) PyArena_New(void); + PyAPI_FUNC(void) PyArena_Free(PyArena *); + + /* Mostly like malloc(), return the address of a block of memory spanning + * `size` bytes, or return NULL (without setting an exception) if enough + * new memory can't be obtained. Unlike malloc(0), PyArena_Malloc() with + * size=0 does not guarantee to return a unique pointer (the pointer + * returned may equal one or more other pointers obtained from + * PyArena_Malloc()). + * Note that pointers obtained via PyArena_Malloc() must never be passed to + * the system free() or realloc(), or to any of Python's similar memory- + * management functions. PyArena_Malloc()-obtained pointers remain valid + * until PyArena_Free(ar) is called, at which point all pointers obtained + * from the arena `ar` become invalid simultaneously. + */ + PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t size); + + /* This routine isn't a proper arena allocation routine. It takes + * a PyObject* and records it so that it can be DECREFed when the + * arena is freed. + */ + PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYARENA_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/pycapsule.h b/python/include/pycapsule.h new file mode 100755 index 0000000..d9ecda7 --- /dev/null +++ b/python/include/pycapsule.h @@ -0,0 +1,59 @@ + +/* Capsule objects let you wrap a C "void *" pointer in a Python + object. They're a way of passing data through the Python interpreter + without creating your own custom type. + + Capsules are used for communication between extension modules. + They provide a way for an extension module to export a C interface + to other extension modules, so that extension modules can use the + Python import mechanism to link to one another. + + For more information, please see "c-api/capsule.html" in the + documentation. +*/ + +#ifndef Py_CAPSULE_H +#define Py_CAPSULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyCapsule_Type; + +typedef void (*PyCapsule_Destructor)(PyObject *); + +#define PyCapsule_CheckExact(op) (Py_TYPE(op) == &PyCapsule_Type) + + +PyAPI_FUNC(PyObject *) PyCapsule_New( + void *pointer, + const char *name, + PyCapsule_Destructor destructor); + +PyAPI_FUNC(void *) PyCapsule_GetPointer(PyObject *capsule, const char *name); + +PyAPI_FUNC(PyCapsule_Destructor) PyCapsule_GetDestructor(PyObject *capsule); + +PyAPI_FUNC(const char *) PyCapsule_GetName(PyObject *capsule); + +PyAPI_FUNC(void *) PyCapsule_GetContext(PyObject *capsule); + +PyAPI_FUNC(int) PyCapsule_IsValid(PyObject *capsule, const char *name); + +PyAPI_FUNC(int) PyCapsule_SetPointer(PyObject *capsule, void *pointer); + +PyAPI_FUNC(int) PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor); + +PyAPI_FUNC(int) PyCapsule_SetName(PyObject *capsule, const char *name); + +PyAPI_FUNC(int) PyCapsule_SetContext(PyObject *capsule, void *context); + +PyAPI_FUNC(void *) PyCapsule_Import( + const char *name, /* UTF-8 encoded string */ + int no_block); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CAPSULE_H */ diff --git a/python/include/pyctype.h b/python/include/pyctype.h new file mode 100755 index 0000000..729d932 --- /dev/null +++ b/python/include/pyctype.h @@ -0,0 +1,39 @@ +#ifndef Py_LIMITED_API +#ifndef PYCTYPE_H +#define PYCTYPE_H +#ifdef __cplusplus +extern "C" { +#endif + +#define PY_CTF_LOWER 0x01 +#define PY_CTF_UPPER 0x02 +#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) +#define PY_CTF_DIGIT 0x04 +#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) +#define PY_CTF_SPACE 0x08 +#define PY_CTF_XDIGIT 0x10 + +PyAPI_DATA(const unsigned int) _Py_ctype_table[256]; + +/* Unlike their C counterparts, the following macros are not meant to + * handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument + * must be a signed/unsigned char. */ +#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) +#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) +#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) +#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) +#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) +#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) +#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) + +PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256]; +PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256]; + +#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) +#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) + +#ifdef __cplusplus +} +#endif +#endif /* !PYCTYPE_H */ +#endif /* !Py_LIMITED_API */ diff --git a/python/include/pydebug.h b/python/include/pydebug.h new file mode 100755 index 0000000..bd4aafe --- /dev/null +++ b/python/include/pydebug.h @@ -0,0 +1,40 @@ +#ifndef Py_LIMITED_API +#ifndef Py_PYDEBUG_H +#define Py_PYDEBUG_H +#ifdef __cplusplus +extern "C" { +#endif + +/* These global variable are defined in pylifecycle.c */ +/* XXX (ncoghlan): move these declarations to pylifecycle.h? */ +PyAPI_DATA(int) Py_DebugFlag; +PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_QuietFlag; +PyAPI_DATA(int) Py_InteractiveFlag; +PyAPI_DATA(int) Py_InspectFlag; +PyAPI_DATA(int) Py_OptimizeFlag; +PyAPI_DATA(int) Py_NoSiteFlag; +PyAPI_DATA(int) Py_BytesWarningFlag; +PyAPI_DATA(int) Py_FrozenFlag; +PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +PyAPI_DATA(int) Py_NoUserSiteDirectory; +PyAPI_DATA(int) Py_UnbufferedStdioFlag; +PyAPI_DATA(int) Py_HashRandomizationFlag; +PyAPI_DATA(int) Py_IsolatedFlag; + +#ifdef MS_WINDOWS +PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; +PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; +#endif + +/* this is a wrapper around getenv() that pays attention to + Py_IgnoreEnvironmentFlag. It should be used for getting variables like + PYTHONPATH and PYTHONHOME from the environment */ +#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYDEBUG_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/pydtrace.d b/python/include/pydtrace.d new file mode 100755 index 0000000..5e6a626 --- /dev/null +++ b/python/include/pydtrace.d @@ -0,0 +1,22 @@ +/* Python DTrace provider */ + +provider python { + probe function__entry(const char *, const char *, int); + probe function__return(const char *, const char *, int); + probe instance__new__start(const char *, const char *); + probe instance__new__done(const char *, const char *); + probe instance__delete__start(const char *, const char *); + probe instance__delete__done(const char *, const char *); + probe line(const char *, const char *, int); + probe gc__start(int); + probe gc__done(long); + probe import__find__load__start(const char *); + probe import__find__load__done(const char *, int); + probe audit(const char *, void *); +}; + +#pragma D attributes Evolving/Evolving/Common provider python provider +#pragma D attributes Evolving/Evolving/Common provider python module +#pragma D attributes Evolving/Evolving/Common provider python function +#pragma D attributes Evolving/Evolving/Common provider python name +#pragma D attributes Evolving/Evolving/Common provider python args diff --git a/python/include/pydtrace.h b/python/include/pydtrace.h new file mode 100755 index 0000000..75f8e7f --- /dev/null +++ b/python/include/pydtrace.h @@ -0,0 +1,59 @@ +/* Static DTrace probes interface */ + +#ifndef Py_DTRACE_H +#define Py_DTRACE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WITH_DTRACE + +#include "pydtrace_probes.h" + +/* pydtrace_probes.h, on systems with DTrace, is auto-generated to include + `PyDTrace_{PROBE}` and `PyDTrace_{PROBE}_ENABLED()` macros for every probe + defined in pydtrace_provider.d. + + Calling these functions must be guarded by a `PyDTrace_{PROBE}_ENABLED()` + check to minimize performance impact when probing is off. For example: + + if (PyDTrace_FUNCTION_ENTRY_ENABLED()) + PyDTrace_FUNCTION_ENTRY(f); +*/ + +#else + +/* Without DTrace, compile to nothing. */ + +static inline void PyDTrace_LINE(const char *arg0, const char *arg1, int arg2) {} +static inline void PyDTrace_FUNCTION_ENTRY(const char *arg0, const char *arg1, int arg2) {} +static inline void PyDTrace_FUNCTION_RETURN(const char *arg0, const char *arg1, int arg2) {} +static inline void PyDTrace_GC_START(int arg0) {} +static inline void PyDTrace_GC_DONE(Py_ssize_t arg0) {} +static inline void PyDTrace_INSTANCE_NEW_START(int arg0) {} +static inline void PyDTrace_INSTANCE_NEW_DONE(int arg0) {} +static inline void PyDTrace_INSTANCE_DELETE_START(int arg0) {} +static inline void PyDTrace_INSTANCE_DELETE_DONE(int arg0) {} +static inline void PyDTrace_IMPORT_FIND_LOAD_START(const char *arg0) {} +static inline void PyDTrace_IMPORT_FIND_LOAD_DONE(const char *arg0, int arg1) {} +static inline void PyDTrace_AUDIT(const char *arg0, void *arg1) {} + +static inline int PyDTrace_LINE_ENABLED(void) { return 0; } +static inline int PyDTrace_FUNCTION_ENTRY_ENABLED(void) { return 0; } +static inline int PyDTrace_FUNCTION_RETURN_ENABLED(void) { return 0; } +static inline int PyDTrace_GC_START_ENABLED(void) { return 0; } +static inline int PyDTrace_GC_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_NEW_START_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_NEW_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) { return 0; } +static inline int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_IMPORT_FIND_LOAD_START_ENABLED(void) { return 0; } +static inline int PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_AUDIT_ENABLED(void) { return 0; } + +#endif /* !WITH_DTRACE */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_DTRACE_H */ diff --git a/python/include/pyerrors.h b/python/include/pyerrors.h new file mode 100755 index 0000000..5125a51 --- /dev/null +++ b/python/include/pyerrors.h @@ -0,0 +1,335 @@ +#ifndef Py_ERRORS_H +#define Py_ERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Error handling definitions */ + +PyAPI_FUNC(void) PyErr_SetNone(PyObject *); +PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); +PyAPI_FUNC(void) PyErr_SetString( + PyObject *exception, + const char *string /* decoded from utf-8 */ + ); +PyAPI_FUNC(PyObject *) PyErr_Occurred(void); +PyAPI_FUNC(void) PyErr_Clear(void); +PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); +PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(void) PyErr_GetExcInfo(PyObject **, PyObject **, PyObject **); +PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); +#endif + +/* Defined in Python/pylifecycle.c */ +PyAPI_FUNC(void) _Py_NO_RETURN Py_FatalError(const char *message); + +#if defined(Py_DEBUG) || defined(Py_LIMITED_API) +#define _PyErr_OCCURRED() PyErr_Occurred() +#else +#define _PyErr_OCCURRED() (PyThreadState_GET()->curexc_type) +#endif + +/* Error testing and normalization */ +PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *); +PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); +PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**); + +/* Traceback manipulation (PEP 3134) */ +PyAPI_FUNC(int) PyException_SetTraceback(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyException_GetTraceback(PyObject *); + +/* Cause manipulation (PEP 3134) */ +PyAPI_FUNC(PyObject *) PyException_GetCause(PyObject *); +PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *); + +/* Context manipulation (PEP 3134) */ +PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *); +PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); + +/* */ + +#define PyExceptionClass_Check(x) \ + (PyType_Check((x)) && \ + PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS)) + +#define PyExceptionInstance_Check(x) \ + PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS) + +PyAPI_FUNC(const char *) PyExceptionClass_Name(PyObject *); + +#define PyExceptionInstance_Class(x) ((PyObject*)((x)->ob_type)) + + +/* Predefined exceptions */ + +PyAPI_DATA(PyObject *) PyExc_BaseException; +PyAPI_DATA(PyObject *) PyExc_Exception; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_DATA(PyObject *) PyExc_StopAsyncIteration; +#endif +PyAPI_DATA(PyObject *) PyExc_StopIteration; +PyAPI_DATA(PyObject *) PyExc_GeneratorExit; +PyAPI_DATA(PyObject *) PyExc_ArithmeticError; +PyAPI_DATA(PyObject *) PyExc_LookupError; + +PyAPI_DATA(PyObject *) PyExc_AssertionError; +PyAPI_DATA(PyObject *) PyExc_AttributeError; +PyAPI_DATA(PyObject *) PyExc_BufferError; +PyAPI_DATA(PyObject *) PyExc_EOFError; +PyAPI_DATA(PyObject *) PyExc_FloatingPointError; +PyAPI_DATA(PyObject *) PyExc_OSError; +PyAPI_DATA(PyObject *) PyExc_ImportError; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_DATA(PyObject *) PyExc_ModuleNotFoundError; +#endif +PyAPI_DATA(PyObject *) PyExc_IndexError; +PyAPI_DATA(PyObject *) PyExc_KeyError; +PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt; +PyAPI_DATA(PyObject *) PyExc_MemoryError; +PyAPI_DATA(PyObject *) PyExc_NameError; +PyAPI_DATA(PyObject *) PyExc_OverflowError; +PyAPI_DATA(PyObject *) PyExc_RuntimeError; +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_DATA(PyObject *) PyExc_RecursionError; +#endif +PyAPI_DATA(PyObject *) PyExc_NotImplementedError; +PyAPI_DATA(PyObject *) PyExc_SyntaxError; +PyAPI_DATA(PyObject *) PyExc_IndentationError; +PyAPI_DATA(PyObject *) PyExc_TabError; +PyAPI_DATA(PyObject *) PyExc_ReferenceError; +PyAPI_DATA(PyObject *) PyExc_SystemError; +PyAPI_DATA(PyObject *) PyExc_SystemExit; +PyAPI_DATA(PyObject *) PyExc_TypeError; +PyAPI_DATA(PyObject *) PyExc_UnboundLocalError; +PyAPI_DATA(PyObject *) PyExc_UnicodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeEncodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError; +PyAPI_DATA(PyObject *) PyExc_ValueError; +PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError; + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_DATA(PyObject *) PyExc_BlockingIOError; +PyAPI_DATA(PyObject *) PyExc_BrokenPipeError; +PyAPI_DATA(PyObject *) PyExc_ChildProcessError; +PyAPI_DATA(PyObject *) PyExc_ConnectionError; +PyAPI_DATA(PyObject *) PyExc_ConnectionAbortedError; +PyAPI_DATA(PyObject *) PyExc_ConnectionRefusedError; +PyAPI_DATA(PyObject *) PyExc_ConnectionResetError; +PyAPI_DATA(PyObject *) PyExc_FileExistsError; +PyAPI_DATA(PyObject *) PyExc_FileNotFoundError; +PyAPI_DATA(PyObject *) PyExc_InterruptedError; +PyAPI_DATA(PyObject *) PyExc_IsADirectoryError; +PyAPI_DATA(PyObject *) PyExc_NotADirectoryError; +PyAPI_DATA(PyObject *) PyExc_PermissionError; +PyAPI_DATA(PyObject *) PyExc_ProcessLookupError; +PyAPI_DATA(PyObject *) PyExc_TimeoutError; +#endif + + +/* Compatibility aliases */ +PyAPI_DATA(PyObject *) PyExc_EnvironmentError; +PyAPI_DATA(PyObject *) PyExc_IOError; +#ifdef MS_WINDOWS +PyAPI_DATA(PyObject *) PyExc_WindowsError; +#endif + +/* Predefined warning categories */ +PyAPI_DATA(PyObject *) PyExc_Warning; +PyAPI_DATA(PyObject *) PyExc_UserWarning; +PyAPI_DATA(PyObject *) PyExc_DeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_SyntaxWarning; +PyAPI_DATA(PyObject *) PyExc_RuntimeWarning; +PyAPI_DATA(PyObject *) PyExc_FutureWarning; +PyAPI_DATA(PyObject *) PyExc_ImportWarning; +PyAPI_DATA(PyObject *) PyExc_UnicodeWarning; +PyAPI_DATA(PyObject *) PyExc_BytesWarning; +PyAPI_DATA(PyObject *) PyExc_ResourceWarning; + + +/* Convenience functions */ + +PyAPI_FUNC(int) PyErr_BadArgument(void); +PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( + PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObjects( + PyObject *, PyObject *, PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( + PyObject *exc, + const char *filename /* decoded from the filesystem encoding */ + ); + +PyAPI_FUNC(PyObject *) PyErr_Format( + PyObject *exception, + const char *format, /* ASCII-encoded string */ + ... + ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(PyObject *) PyErr_FormatV( + PyObject *exception, + const char *format, + va_list vargs); +#endif + +#ifdef MS_WINDOWS +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename( + int ierr, + const char *filename /* decoded from the filesystem encoding */ + ); +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *,int, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyObject *,int, PyObject *, PyObject *); +#endif +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( + PyObject *exc, + int ierr, + const char *filename /* decoded from the filesystem encoding */ + ); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); +#endif /* MS_WINDOWS */ + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_FUNC(PyObject *) PyErr_SetImportErrorSubclass(PyObject *, PyObject *, + PyObject *, PyObject *); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject *) PyErr_SetImportError(PyObject *, PyObject *, + PyObject *); +#endif + +/* Export the old function so that the existing API remains available: */ +PyAPI_FUNC(void) PyErr_BadInternalCall(void); +PyAPI_FUNC(void) _PyErr_BadInternalCall(const char *filename, int lineno); +/* Mask the old API with a call to the new API for code compiled under + Python 2.0: */ +#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) + +/* Function to create a new exception */ +PyAPI_FUNC(PyObject *) PyErr_NewException( + const char *name, PyObject *base, PyObject *dict); +PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc( + const char *name, const char *doc, PyObject *base, PyObject *dict); +PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); + + +/* In signalmodule.c */ +PyAPI_FUNC(int) PyErr_CheckSignals(void); +PyAPI_FUNC(void) PyErr_SetInterrupt(void); + +/* Support for adding program text to SyntaxErrors */ +PyAPI_FUNC(void) PyErr_SyntaxLocation( + const char *filename, /* decoded from the filesystem encoding */ + int lineno); +PyAPI_FUNC(void) PyErr_SyntaxLocationEx( + const char *filename, /* decoded from the filesystem encoding */ + int lineno, + int col_offset); +PyAPI_FUNC(PyObject *) PyErr_ProgramText( + const char *filename, /* decoded from the filesystem encoding */ + int lineno); + +/* The following functions are used to create and modify unicode + exceptions from C */ + +/* create a UnicodeDecodeError object */ +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_Create( + const char *encoding, /* UTF-8 encoded string */ + const char *object, + Py_ssize_t length, + Py_ssize_t start, + Py_ssize_t end, + const char *reason /* UTF-8 encoded string */ + ); + +/* get the encoding attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetEncoding(PyObject *); + +/* get the object attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetObject(PyObject *); + +/* get the value of the start attribute (the int * may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetStart(PyObject *, Py_ssize_t *); + +/* assign a new value to the start attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetStart(PyObject *, Py_ssize_t); + +/* get the value of the end attribute (the int *may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetEnd(PyObject *, Py_ssize_t *); + +/* assign a new value to the end attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetEnd(PyObject *, Py_ssize_t); + +/* get the value of the reason attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetReason(PyObject *); + +/* assign a new value to the reason attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetReason( + PyObject *exc, + const char *reason /* UTF-8 encoded string */ + ); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetReason( + PyObject *exc, + const char *reason /* UTF-8 encoded string */ + ); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason( + PyObject *exc, + const char *reason /* UTF-8 encoded string */ + ); + +/* These APIs aren't really part of the error implementation, but + often needed to format error messages; the native C lib APIs are + not available on all platforms, which is why we provide emulations + for those platforms in Python/mysnprintf.c, + WARNING: The return value of snprintf varies across platforms; do + not rely on any particular behavior; eventually the C99 defn may + be reliable. +*/ +#if defined(MS_WIN32) && !defined(HAVE_SNPRINTF) +# define HAVE_SNPRINTF +# define snprintf _snprintf +# define vsnprintf _vsnprintf +#endif + +#include +PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 3, 4))); +PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) + Py_GCC_ATTRIBUTE((format(printf, 3, 0))); + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_ERRORS_H +# include "cpython/pyerrors.h" +# undef Py_CPYTHON_ERRORS_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRORS_H */ diff --git a/python/include/pyexpat.h b/python/include/pyexpat.h new file mode 100755 index 0000000..07020b5 --- /dev/null +++ b/python/include/pyexpat.h @@ -0,0 +1,55 @@ +/* Stuff to export relevant 'expat' entry points from pyexpat to other + * parser modules, such as cElementTree. */ + +/* note: you must import expat.h before importing this module! */ + +#define PyExpat_CAPI_MAGIC "pyexpat.expat_CAPI 1.1" +#define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI" + +struct PyExpat_CAPI +{ + char* magic; /* set to PyExpat_CAPI_MAGIC */ + int size; /* set to sizeof(struct PyExpat_CAPI) */ + int MAJOR_VERSION; + int MINOR_VERSION; + int MICRO_VERSION; + /* pointers to selected expat functions. add new functions at + the end, if needed */ + const XML_LChar * (*ErrorString)(enum XML_Error code); + enum XML_Error (*GetErrorCode)(XML_Parser parser); + XML_Size (*GetErrorColumnNumber)(XML_Parser parser); + XML_Size (*GetErrorLineNumber)(XML_Parser parser); + enum XML_Status (*Parse)( + XML_Parser parser, const char *s, int len, int isFinal); + XML_Parser (*ParserCreate_MM)( + const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + void (*ParserFree)(XML_Parser parser); + void (*SetCharacterDataHandler)( + XML_Parser parser, XML_CharacterDataHandler handler); + void (*SetCommentHandler)( + XML_Parser parser, XML_CommentHandler handler); + void (*SetDefaultHandlerExpand)( + XML_Parser parser, XML_DefaultHandler handler); + void (*SetElementHandler)( + XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end); + void (*SetNamespaceDeclHandler)( + XML_Parser parser, XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + void (*SetProcessingInstructionHandler)( + XML_Parser parser, XML_ProcessingInstructionHandler handler); + void (*SetUnknownEncodingHandler)( + XML_Parser parser, XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + void (*SetUserData)(XML_Parser parser, void *userData); + void (*SetStartDoctypeDeclHandler)(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding); + int (*DefaultUnknownEncodingHandler)( + void *encodingHandlerData, const XML_Char *name, XML_Encoding *info); + /* might be none for expat < 2.1.0 */ + int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt); + /* always add new stuff to the end! */ +}; + diff --git a/python/include/pyfpe.h b/python/include/pyfpe.h new file mode 100755 index 0000000..5a99e39 --- /dev/null +++ b/python/include/pyfpe.h @@ -0,0 +1,12 @@ +#ifndef Py_PYFPE_H +#define Py_PYFPE_H + +/* These macros used to do something when Python was built with --with-fpectl, + * but support for that was dropped in 3.7. We continue to define them though, + * to avoid breaking API users. + */ + +#define PyFPE_START_PROTECT(err_string, leave_stmt) +#define PyFPE_END_PROTECT(v) + +#endif /* !Py_PYFPE_H */ diff --git a/python/include/pyhash.h b/python/include/pyhash.h new file mode 100755 index 0000000..dbcc974 --- /dev/null +++ b/python/include/pyhash.h @@ -0,0 +1,145 @@ +#ifndef Py_HASH_H + +#define Py_HASH_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Helpers for hash functions */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double); +PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*); +PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); +#endif + +/* Prime multiplier used in string and various other hashes. */ +#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */ + +/* Parameters used for the numeric hash implementation. See notes for + _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on + reduction modulo the prime 2**_PyHASH_BITS - 1. */ + +#if SIZEOF_VOID_P >= 8 +# define _PyHASH_BITS 61 +#else +# define _PyHASH_BITS 31 +#endif + +#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1) +#define _PyHASH_INF 314159 +#define _PyHASH_NAN 0 +#define _PyHASH_IMAG _PyHASH_MULTIPLIER + + +/* hash secret + * + * memory layout on 64 bit systems + * cccccccc cccccccc cccccccc uc -- unsigned char[24] + * pppppppp ssssssss ........ fnv -- two Py_hash_t + * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t + * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t + * ........ ........ eeeeeeee pyexpat XML hash salt + * + * memory layout on 32 bit systems + * cccccccc cccccccc cccccccc uc + * ppppssss ........ ........ fnv -- two Py_hash_t + * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*) + * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t + * ........ ........ eeee.... pyexpat XML hash salt + * + * (*) The siphash member may not be available on 32 bit platforms without + * an unsigned int64 data type. + */ +#ifndef Py_LIMITED_API +typedef union { + /* ensure 24 bytes */ + unsigned char uc[24]; + /* two Py_hash_t for FNV */ + struct { + Py_hash_t prefix; + Py_hash_t suffix; + } fnv; + /* two uint64 for SipHash24 */ + struct { + uint64_t k0; + uint64_t k1; + } siphash; + /* a different (!) Py_hash_t for small string optimization */ + struct { + unsigned char padding[16]; + Py_hash_t suffix; + } djbx33a; + struct { + unsigned char padding[16]; + Py_hash_t hashsalt; + } expat; +} _Py_HashSecret_t; +PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; +#endif + +#ifdef Py_DEBUG +PyAPI_DATA(int) _Py_HashSecret_Initialized; +#endif + + +/* hash function definition */ +#ifndef Py_LIMITED_API +typedef struct { + Py_hash_t (*const hash)(const void *, Py_ssize_t); + const char *name; + const int hash_bits; + const int seed_bits; +} PyHash_FuncDef; + +PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); +#endif + + +/* cutoff for small string DJBX33A optimization in range [1, cutoff). + * + * About 50% of the strings in a typical Python application are smaller than + * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks. + * NEVER use DJBX33A for long strings! + * + * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms + * should use a smaller cutoff because it is easier to create colliding + * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should + * provide a decent safety margin. + */ +#ifndef Py_HASH_CUTOFF +# define Py_HASH_CUTOFF 0 +#elif (Py_HASH_CUTOFF > 7 || Py_HASH_CUTOFF < 0) +# error Py_HASH_CUTOFF must in range 0...7. +#endif /* Py_HASH_CUTOFF */ + + +/* hash algorithm selection + * + * The values for Py_HASH_SIPHASH24 and Py_HASH_FNV are hard-coded in the + * configure script. + * + * - FNV is available on all platforms and architectures. + * - SIPHASH24 only works on platforms that don't require aligned memory for integers. + * - With EXTERNAL embedders can provide an alternative implementation with:: + * + * PyHash_FuncDef PyHash_Func = {...}; + * + * XXX: Figure out __declspec() for extern PyHash_FuncDef. + */ +#define Py_HASH_EXTERNAL 0 +#define Py_HASH_SIPHASH24 1 +#define Py_HASH_FNV 2 + +#ifndef Py_HASH_ALGORITHM +# ifndef HAVE_ALIGNED_REQUIRED +# define Py_HASH_ALGORITHM Py_HASH_SIPHASH24 +# else +# define Py_HASH_ALGORITHM Py_HASH_FNV +# endif /* uint64_t && uint32_t && aligned */ +#endif /* Py_HASH_ALGORITHM */ + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_HASH_H */ diff --git a/python/include/pylifecycle.h b/python/include/pylifecycle.h new file mode 100755 index 0000000..c5368b3 --- /dev/null +++ b/python/include/pylifecycle.h @@ -0,0 +1,75 @@ + +/* Interfaces to configure, query, create & destroy the Python runtime */ + +#ifndef Py_PYLIFECYCLE_H +#define Py_PYLIFECYCLE_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Initialization and finalization */ +PyAPI_FUNC(void) Py_Initialize(void); +PyAPI_FUNC(void) Py_InitializeEx(int); +PyAPI_FUNC(void) Py_Finalize(void); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_FUNC(int) Py_FinalizeEx(void); +#endif +PyAPI_FUNC(int) Py_IsInitialized(void); + +/* Subinterpreter support */ +PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); +PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); + + +/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level + * exit functions. + */ +PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); + +PyAPI_FUNC(void) _Py_NO_RETURN Py_Exit(int); + +/* Bootstrap __main__ (defined in Modules/main.c) */ +PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); + +PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv); + +/* In pathconfig.c */ +PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); + +PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); + +PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); + +PyAPI_FUNC(wchar_t *) Py_GetPrefix(void); +PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); +PyAPI_FUNC(wchar_t *) Py_GetPath(void); +PyAPI_FUNC(void) Py_SetPath(const wchar_t *); +#ifdef MS_WINDOWS +int _Py_CheckPython3(void); +#endif + +/* In their own files */ +PyAPI_FUNC(const char *) Py_GetVersion(void); +PyAPI_FUNC(const char *) Py_GetPlatform(void); +PyAPI_FUNC(const char *) Py_GetCopyright(void); +PyAPI_FUNC(const char *) Py_GetCompiler(void); +PyAPI_FUNC(const char *) Py_GetBuildInfo(void); + +/* Signals */ +typedef void (*PyOS_sighandler_t)(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_PYLIFECYCLE_H +# include "cpython/pylifecycle.h" +# undef Py_CPYTHON_PYLIFECYCLE_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYLIFECYCLE_H */ diff --git a/python/include/pymacconfig.h b/python/include/pymacconfig.h new file mode 100755 index 0000000..9dde11b --- /dev/null +++ b/python/include/pymacconfig.h @@ -0,0 +1,102 @@ +#ifndef PYMACCONFIG_H +#define PYMACCONFIG_H + /* + * This file moves some of the autoconf magic to compile-time + * when building on MacOSX. This is needed for building 4-way + * universal binaries and for 64-bit universal binaries because + * the values redefined below aren't configure-time constant but + * only compile-time constant in these scenarios. + */ + +#if defined(__APPLE__) + +# undef SIZEOF_LONG +# undef SIZEOF_PTHREAD_T +# undef SIZEOF_SIZE_T +# undef SIZEOF_TIME_T +# undef SIZEOF_VOID_P +# undef SIZEOF__BOOL +# undef SIZEOF_UINTPTR_T +# undef SIZEOF_PTHREAD_T +# undef WORDS_BIGENDIAN +# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 +# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 +# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# undef HAVE_GCC_ASM_FOR_X87 + +# undef VA_LIST_IS_ARRAY +# if defined(__LP64__) && defined(__x86_64__) +# define VA_LIST_IS_ARRAY 1 +# endif + +# undef HAVE_LARGEFILE_SUPPORT +# ifndef __LP64__ +# define HAVE_LARGEFILE_SUPPORT 1 +# endif + +# undef SIZEOF_LONG +# ifdef __LP64__ +# define SIZEOF__BOOL 1 +# define SIZEOF__BOOL 1 +# define SIZEOF_LONG 8 +# define SIZEOF_PTHREAD_T 8 +# define SIZEOF_SIZE_T 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_VOID_P 8 +# define SIZEOF_UINTPTR_T 8 +# define SIZEOF_PTHREAD_T 8 +# else +# ifdef __ppc__ +# define SIZEOF__BOOL 4 +# else +# define SIZEOF__BOOL 1 +# endif +# define SIZEOF_LONG 4 +# define SIZEOF_PTHREAD_T 4 +# define SIZEOF_SIZE_T 4 +# define SIZEOF_TIME_T 4 +# define SIZEOF_VOID_P 4 +# define SIZEOF_UINTPTR_T 4 +# define SIZEOF_PTHREAD_T 4 +# endif + +# if defined(__LP64__) + /* MacOSX 10.4 (the first release to support 64-bit code + * at all) only supports 64-bit in the UNIX layer. + * Therefore suppress the toolbox-glue in 64-bit mode. + */ + + /* In 64-bit mode setpgrp always has no arguments, in 32-bit + * mode that depends on the compilation environment + */ +# undef SETPGRP_HAVE_ARG + +# endif + +#ifdef __BIG_ENDIAN__ +#define WORDS_BIGENDIAN 1 +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 +#else +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +#endif /* __BIG_ENDIAN */ + +#ifdef __i386__ +# define HAVE_GCC_ASM_FOR_X87 +#endif + + /* + * The definition in pyconfig.h is only valid on the OS release + * where configure ran on and not necessarily for all systems where + * the executable can be used on. + * + * Specifically: OSX 10.4 has limited supported for '%zd', while + * 10.5 has full support for '%zd'. A binary built on 10.5 won't + * work properly on 10.4 unless we suppress the definition + * of PY_FORMAT_SIZE_T + */ +#undef PY_FORMAT_SIZE_T + + +#endif /* defined(_APPLE__) */ + +#endif /* PYMACCONFIG_H */ diff --git a/python/include/pymacro.h b/python/include/pymacro.h new file mode 100755 index 0000000..495c2c2 --- /dev/null +++ b/python/include/pymacro.h @@ -0,0 +1,106 @@ +#ifndef Py_PYMACRO_H +#define Py_PYMACRO_H + +/* Minimum value between x and y */ +#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x)) + +/* Maximum value between x and y */ +#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y)) + +/* Absolute value of the number x */ +#define Py_ABS(x) ((x) < 0 ? -(x) : (x)) + +#define _Py_XSTRINGIFY(x) #x + +/* Convert the argument to a string. For example, Py_STRINGIFY(123) is replaced + with "123" by the preprocessor. Defines are also replaced by their value. + For example Py_STRINGIFY(__LINE__) is replaced by the line number, not + by "__LINE__". */ +#define Py_STRINGIFY(x) _Py_XSTRINGIFY(x) + +/* Get the size of a structure member in bytes */ +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) + +/* Argument must be a char or an int in [-128, 127] or [0, 255]. */ +#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff)) + +/* Assert a build-time dependency, as an expression. + + Your compile will fail if the condition isn't true, or can't be evaluated + by the compiler. This can be used in an expression: its value is 0. + + Example: + + #define foo_to_char(foo) \ + ((char *)(foo) \ + + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0)) + + Written by Rusty Russell, public domain, http://ccodearchive.net/ */ +#define Py_BUILD_ASSERT_EXPR(cond) \ + (sizeof(char [1 - 2*!(cond)]) - 1) + +#define Py_BUILD_ASSERT(cond) do { \ + (void)Py_BUILD_ASSERT_EXPR(cond); \ + } while(0) + +/* Get the number of elements in a visible array + + This does not work on pointers, or arrays declared as [], or function + parameters. With correct compiler support, such usage will cause a build + error (see Py_BUILD_ASSERT_EXPR). + + Written by Rusty Russell, public domain, http://ccodearchive.net/ + + Requires at GCC 3.1+ */ +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__) && \ + (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ >= 4))) +/* Two gcc extensions. + &a[0] degrades to a pointer: a different type from an array */ +#define Py_ARRAY_LENGTH(array) \ + (sizeof(array) / sizeof((array)[0]) \ + + Py_BUILD_ASSERT_EXPR(!__builtin_types_compatible_p(typeof(array), \ + typeof(&(array)[0])))) +#else +#define Py_ARRAY_LENGTH(array) \ + (sizeof(array) / sizeof((array)[0])) +#endif + + +/* Define macros for inline documentation. */ +#define PyDoc_VAR(name) static const char name[] +#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) +#ifdef WITH_DOC_STRINGS +#define PyDoc_STR(str) str +#else +#define PyDoc_STR(str) "" +#endif + +/* Below "a" is a power of 2. */ +/* Round down size "n" to be a multiple of "a". */ +#define _Py_SIZE_ROUND_DOWN(n, a) ((size_t)(n) & ~(size_t)((a) - 1)) +/* Round up size "n" to be a multiple of "a". */ +#define _Py_SIZE_ROUND_UP(n, a) (((size_t)(n) + \ + (size_t)((a) - 1)) & ~(size_t)((a) - 1)) +/* Round pointer "p" down to the closest "a"-aligned address <= "p". */ +#define _Py_ALIGN_DOWN(p, a) ((void *)((uintptr_t)(p) & ~(uintptr_t)((a) - 1))) +/* Round pointer "p" up to the closest "a"-aligned address >= "p". */ +#define _Py_ALIGN_UP(p, a) ((void *)(((uintptr_t)(p) + \ + (uintptr_t)((a) - 1)) & ~(uintptr_t)((a) - 1))) +/* Check if pointer "p" is aligned to "a"-bytes boundary. */ +#define _Py_IS_ALIGNED(p, a) (!((uintptr_t)(p) & (uintptr_t)((a) - 1))) + +/* Use this for unused arguments in a function definition to silence compiler + * warnings. Example: + * + * int func(int a, int Py_UNUSED(b)) { return a; } + */ +#if defined(__GNUC__) || defined(__clang__) +# define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) +#else +# define Py_UNUSED(name) _unused_ ## name +#endif + +#define Py_UNREACHABLE() \ + Py_FatalError("Unreachable C code path reached") + +#endif /* Py_PYMACRO_H */ diff --git a/python/include/pymath.h b/python/include/pymath.h new file mode 100755 index 0000000..6cf69f9 --- /dev/null +++ b/python/include/pymath.h @@ -0,0 +1,230 @@ +#ifndef Py_PYMATH_H +#define Py_PYMATH_H + +#include "pyconfig.h" /* include for defines */ + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to mathematical +functions and constants +**************************************************************************/ + +/* Python provides implementations for copysign, round and hypot in + * Python/pymath.c just in case your math library doesn't provide the + * functions. + * + *Note: PC/pyconfig.h defines copysign as _copysign + */ +#ifndef HAVE_COPYSIGN +extern double copysign(double, double); +#endif + +#ifndef HAVE_ROUND +extern double round(double); +#endif + +#ifndef HAVE_HYPOT +extern double hypot(double, double); +#endif + +/* extra declarations */ +#ifndef _MSC_VER +#ifndef __STDC__ +extern double fmod (double, double); +extern double frexp (double, int *); +extern double ldexp (double, int); +extern double modf (double, double *); +extern double pow(double, double); +#endif /* __STDC__ */ +#endif /* _MSC_VER */ + +/* High precision definition of pi and e (Euler) + * The values are taken from libc6's math.h. + */ +#ifndef Py_MATH_PIl +#define Py_MATH_PIl 3.1415926535897932384626433832795029L +#endif +#ifndef Py_MATH_PI +#define Py_MATH_PI 3.14159265358979323846 +#endif + +#ifndef Py_MATH_El +#define Py_MATH_El 2.7182818284590452353602874713526625L +#endif + +#ifndef Py_MATH_E +#define Py_MATH_E 2.7182818284590452354 +#endif + +/* Tau (2pi) to 40 digits, taken from tauday.com/tau-digits. */ +#ifndef Py_MATH_TAU +#define Py_MATH_TAU 6.2831853071795864769252867665590057683943L +#endif + + +/* On x86, Py_FORCE_DOUBLE forces a floating-point number out of an x87 FPU + register and into a 64-bit memory location, rounding from extended + precision to double precision in the process. On other platforms it does + nothing. */ + +/* we take double rounding as evidence of x87 usage */ +#ifndef Py_LIMITED_API +#ifndef Py_FORCE_DOUBLE +# ifdef X87_DOUBLE_ROUNDING +PyAPI_FUNC(double) _Py_force_double(double); +# define Py_FORCE_DOUBLE(X) (_Py_force_double(X)) +# else +# define Py_FORCE_DOUBLE(X) (X) +# endif +#endif +#endif + +#ifndef Py_LIMITED_API +#ifdef HAVE_GCC_ASM_FOR_X87 +PyAPI_FUNC(unsigned short) _Py_get_387controlword(void); +PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); +#endif +#endif + +/* Py_IS_NAN(X) + * Return 1 if float or double arg is a NaN, else 0. + * Caution: + * X is evaluated more than once. + * This may not work on all platforms. Each platform has *some* + * way to spell this, though -- override in pyconfig.h if you have + * a platform where it doesn't work. + * Note: PC/pyconfig.h defines Py_IS_NAN as _isnan + */ +#ifndef Py_IS_NAN +#if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1 +#define Py_IS_NAN(X) isnan(X) +#else +#define Py_IS_NAN(X) ((X) != (X)) +#endif +#endif + +/* Py_IS_INFINITY(X) + * Return 1 if float or double arg is an infinity, else 0. + * Caution: + * X is evaluated more than once. + * This implementation may set the underflow flag if |X| is very small; + * it really can't be implemented correctly (& easily) before C99. + * Override in pyconfig.h if you have a better spelling on your platform. + * Py_FORCE_DOUBLE is used to avoid getting false negatives from a + * non-infinite value v sitting in an 80-bit x87 register such that + * v becomes infinite when spilled from the register to 64-bit memory. + * Note: PC/pyconfig.h defines Py_IS_INFINITY as _isinf + */ +#ifndef Py_IS_INFINITY +# if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1 +# define Py_IS_INFINITY(X) isinf(X) +# else +# define Py_IS_INFINITY(X) ((X) && \ + (Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X))) +# endif +#endif + +/* Py_IS_FINITE(X) + * Return 1 if float or double arg is neither infinite nor NAN, else 0. + * Some compilers (e.g. VisualStudio) have intrisics for this, so a special + * macro for this particular test is useful + * Note: PC/pyconfig.h defines Py_IS_FINITE as _finite + */ +#ifndef Py_IS_FINITE +#if defined HAVE_DECL_ISFINITE && HAVE_DECL_ISFINITE == 1 +#define Py_IS_FINITE(X) isfinite(X) +#elif defined HAVE_FINITE +#define Py_IS_FINITE(X) finite(X) +#else +#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) +#endif +#endif + +/* HUGE_VAL is supposed to expand to a positive double infinity. Python + * uses Py_HUGE_VAL instead because some platforms are broken in this + * respect. We used to embed code in pyport.h to try to worm around that, + * but different platforms are broken in conflicting ways. If you're on + * a platform where HUGE_VAL is defined incorrectly, fiddle your Python + * config to #define Py_HUGE_VAL to something that works on your platform. + */ +#ifndef Py_HUGE_VAL +#define Py_HUGE_VAL HUGE_VAL +#endif + +/* Py_NAN + * A value that evaluates to a NaN. On IEEE 754 platforms INF*0 or + * INF/INF works. Define Py_NO_NAN in pyconfig.h if your platform + * doesn't support NaNs. + */ +#if !defined(Py_NAN) && !defined(Py_NO_NAN) +#if !defined(__INTEL_COMPILER) + #define Py_NAN (Py_HUGE_VAL * 0.) +#else /* __INTEL_COMPILER */ + #if defined(ICC_NAN_STRICT) + #pragma float_control(push) + #pragma float_control(precise, on) + #pragma float_control(except, on) + #if defined(_MSC_VER) + __declspec(noinline) + #else /* Linux */ + __attribute__((noinline)) + #endif /* _MSC_VER */ + static double __icc_nan() + { + return sqrt(-1.0); + } + #pragma float_control (pop) + #define Py_NAN __icc_nan() + #else /* ICC_NAN_RELAXED as default for Intel Compiler */ + static const union { unsigned char buf[8]; double __icc_nan; } __nan_store = {0,0,0,0,0,0,0xf8,0x7f}; + #define Py_NAN (__nan_store.__icc_nan) + #endif /* ICC_NAN_STRICT */ +#endif /* __INTEL_COMPILER */ +#endif + +/* Py_OVERFLOWED(X) + * Return 1 iff a libm function overflowed. Set errno to 0 before calling + * a libm function, and invoke this macro after, passing the function + * result. + * Caution: + * This isn't reliable. C99 no longer requires libm to set errno under + * any exceptional condition, but does require +- HUGE_VAL return + * values on overflow. A 754 box *probably* maps HUGE_VAL to a + * double infinity, and we're cool if that's so, unless the input + * was an infinity and an infinity is the expected result. A C89 + * system sets errno to ERANGE, so we check for that too. We're + * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or + * if the returned result is a NaN, or if a C89 box returns HUGE_VAL + * in non-overflow cases. + * X is evaluated more than once. + * Some platforms have better way to spell this, so expect some #ifdef'ery. + * + * OpenBSD uses 'isinf()' because a compiler bug on that platform causes + * the longer macro version to be mis-compiled. This isn't optimal, and + * should be removed once a newer compiler is available on that platform. + * The system that had the failure was running OpenBSD 3.2 on Intel, with + * gcc 2.95.3. + * + * According to Tim's checkin, the FreeBSD systems use isinf() to work + * around a FPE bug on that platform. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#define Py_OVERFLOWED(X) isinf(X) +#else +#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \ + (X) == Py_HUGE_VAL || \ + (X) == -Py_HUGE_VAL)) +#endif + +/* Return whether integral type *type* is signed or not. */ +#define _Py_IntegralTypeSigned(type) ((type)(-1) < 0) +/* Return the maximum value of integral type *type*. */ +#define _Py_IntegralTypeMax(type) ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) +/* Return the minimum value of integral type *type*. */ +#define _Py_IntegralTypeMin(type) ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0) +/* Check whether *v* is in the range of integral type *type*. This is most + * useful if *v* is floating-point, since demoting a floating-point *v* to an + * integral type that cannot represent *v*'s integral part is undefined + * behavior. */ +#define _Py_InIntegralTypeRange(type, v) (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) + +#endif /* Py_PYMATH_H */ diff --git a/python/include/pymem.h b/python/include/pymem.h new file mode 100755 index 0000000..07b380a --- /dev/null +++ b/python/include/pymem.h @@ -0,0 +1,150 @@ +/* The PyMem_ family: low-level memory allocation interfaces. + See objimpl.h for the PyObject_ memory family. +*/ + +#ifndef Py_PYMEM_H +#define Py_PYMEM_H + +#include "pyport.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyMem_ with calls to the platform malloc/realloc/ + calloc/free. For example, on Windows different DLLs may end up using + different heaps, and if you use PyMem_Malloc you'll get the memory from the + heap used by the Python DLL; it could be a disaster if you free()'ed that + directly in your own extension. Using PyMem_Free instead ensures Python + can return the memory to the proper heap. As another example, in + PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_ + memory functions in special debugging wrappers that add additional + debugging info to dynamic memory blocks. The system routines have no idea + what to do with that stuff, and the Python wrappers have no idea what to do + with raw blocks obtained directly by the system routines then. + + The GIL must be held when using these APIs. +*/ + +/* + * Raw memory interface + * ==================== + */ + +/* Functions + + Functions supplying platform-independent semantics for malloc/realloc/ + free. These functions make sure that allocating 0 bytes returns a distinct + non-NULL pointer (whenever possible -- if we're flat out of memory, NULL + may be returned), even if the platform malloc and realloc don't. + Returned pointers must be checked for NULL explicitly. No action is + performed on failure (no exception is set, no warning is printed, etc). +*/ + +PyAPI_FUNC(void *) PyMem_Malloc(size_t size); +PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); +PyAPI_FUNC(void) PyMem_Free(void *ptr); + +/* Macros. */ + +/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL + for malloc(0), which would be treated as an error. Some platforms + would return a pointer with no memory behind it, which would break + pymalloc. To solve these problems, allocate an extra byte. */ +/* Returns NULL to indicate error if a negative size or size larger than + Py_ssize_t can represent is supplied. Helps prevents security holes. */ +#define PyMem_MALLOC(n) PyMem_Malloc(n) +#define PyMem_REALLOC(p, n) PyMem_Realloc(p, n) +#define PyMem_FREE(p) PyMem_Free(p) + +/* + * Type-oriented memory interface + * ============================== + * + * Allocate memory for n objects of the given type. Returns a new pointer + * or NULL if the request was too large or memory allocation failed. Use + * these macros rather than doing the multiplication yourself so that proper + * overflow checking is always done. + */ + +#define PyMem_New(type, n) \ + ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + ( (type *) PyMem_Malloc((n) * sizeof(type)) ) ) +#define PyMem_NEW(type, n) \ + ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) ) + +/* + * The value of (p) is always clobbered by this macro regardless of success. + * The caller MUST check if (p) is NULL afterwards and deal with the memory + * error if so. This means the original value of (p) MUST be saved for the + * caller's memory error handler to not lose track of it. + */ +#define PyMem_Resize(p, type, n) \ + ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) +#define PyMem_RESIZE(p, type, n) \ + ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) + +/* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used + * anymore. They're just confusing aliases for PyMem_{Free,FREE} now. + */ +#define PyMem_Del PyMem_Free +#define PyMem_DEL PyMem_FREE + +/* bpo-35053: expose _Py_tracemalloc_config for performance: + _Py_NewReference() needs an efficient check to test if tracemalloc is + tracing. + + It has to be defined in pymem.h, before object.h is included. */ +struct _PyTraceMalloc_Config { + /* Module initialized? + Variable protected by the GIL */ + enum { + TRACEMALLOC_NOT_INITIALIZED, + TRACEMALLOC_INITIALIZED, + TRACEMALLOC_FINALIZED + } initialized; + + /* Is tracemalloc tracing memory allocations? + Variable protected by the GIL */ + int tracing; + + /* limit of the number of frames in a traceback, 1 by default. + Variable protected by the GIL. */ + int max_nframe; + + /* use domain in trace key? + Variable protected by the GIL. */ + int use_domain; +}; + +PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; + +#define _PyTraceMalloc_Config_INIT \ + {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ + .tracing = 0, \ + .max_nframe = 1, \ + .use_domain = 0} + + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_PYMEM_H +# include "cpython/pymem.h" +# undef Py_CPYTHON_PYMEM_H +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYMEM_H */ diff --git a/python/include/pyport.h b/python/include/pyport.h new file mode 100755 index 0000000..71f5794 --- /dev/null +++ b/python/include/pyport.h @@ -0,0 +1,850 @@ +#ifndef Py_PYPORT_H +#define Py_PYPORT_H + +#include "pyconfig.h" /* include for defines */ + +#include + + +/* Defines to build Python and its standard library: + * + * - Py_BUILD_CORE: Build Python core. Give access to Python internals, but + * should not be used by third-party modules. + * - Py_BUILD_CORE_BUILTIN: Build a Python stdlib module as a built-in module. + * - Py_BUILD_CORE_MODULE: Build a Python stdlib module as a dynamic library. + * + * Py_BUILD_CORE_BUILTIN and Py_BUILD_CORE_MODULE imply Py_BUILD_CORE. + * + * On Windows, Py_BUILD_CORE_MODULE exports "PyInit_xxx" symbol, whereas + * Py_BUILD_CORE_BUILTIN does not. + */ +#if defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE) +# define Py_BUILD_CORE +#endif +#if defined(Py_BUILD_CORE_MODULE) && !defined(Py_BUILD_CORE) +# define Py_BUILD_CORE +#endif + + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to basic +C language & library operations whose spellings vary across platforms. + +Please try to make documentation here as clear as possible: by definition, +the stuff here is trying to illuminate C's darkest corners. + +Config #defines referenced here: + +SIGNED_RIGHT_SHIFT_ZERO_FILLS +Meaning: To be defined iff i>>j does not extend the sign bit when i is a + signed integral type and i < 0. +Used in: Py_ARITHMETIC_RIGHT_SHIFT + +Py_DEBUG +Meaning: Extra checks compiled in for debug mode. +Used in: Py_SAFE_DOWNCAST + +**************************************************************************/ + +/* typedefs for some C9X-defined synonyms for integral types. + * + * The names in Python are exactly the same as the C9X names, except with a + * Py_ prefix. Until C9X is universally implemented, this is the only way + * to ensure that Python gets reliable names that don't conflict with names + * in non-Python code that are playing their own tricks to define the C9X + * names. + * + * NOTE: don't go nuts here! Python has no use for *most* of the C9X + * integral synonyms. Only define the ones we actually need. + */ + +/* long long is required. Ensure HAVE_LONG_LONG is defined for compatibility. */ +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 +#endif +#ifndef PY_LONG_LONG +#define PY_LONG_LONG long long +/* If LLONG_MAX is defined in limits.h, use that. */ +#define PY_LLONG_MIN LLONG_MIN +#define PY_LLONG_MAX LLONG_MAX +#define PY_ULLONG_MAX ULLONG_MAX +#endif + +#define PY_UINT32_T uint32_t +#define PY_UINT64_T uint64_t + +/* Signed variants of the above */ +#define PY_INT32_T int32_t +#define PY_INT64_T int64_t + +/* If PYLONG_BITS_IN_DIGIT is not defined then we'll use 30-bit digits if all + the necessary integer types are available, and we're on a 64-bit platform + (as determined by SIZEOF_VOID_P); otherwise we use 15-bit digits. */ + +#ifndef PYLONG_BITS_IN_DIGIT +#if SIZEOF_VOID_P >= 8 +#define PYLONG_BITS_IN_DIGIT 30 +#else +#define PYLONG_BITS_IN_DIGIT 15 +#endif +#endif + +/* uintptr_t is the C9X name for an unsigned integral type such that a + * legitimate void* can be cast to uintptr_t and then back to void* again + * without loss of information. Similarly for intptr_t, wrt a signed + * integral type. + */ +typedef uintptr_t Py_uintptr_t; +typedef intptr_t Py_intptr_t; + +/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) == + * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an + * unsigned integral type). See PEP 353 for details. + */ +#ifdef HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef Py_intptr_t Py_ssize_t; +#else +# error "Python needs a typedef for Py_ssize_t in pyport.h." +#endif + +/* Py_hash_t is the same size as a pointer. */ +#define SIZEOF_PY_HASH_T SIZEOF_SIZE_T +typedef Py_ssize_t Py_hash_t; +/* Py_uhash_t is the unsigned equivalent needed to calculate numeric hash. */ +#define SIZEOF_PY_UHASH_T SIZEOF_SIZE_T +typedef size_t Py_uhash_t; + +/* Only used for compatibility with code that may not be PY_SSIZE_T_CLEAN. */ +#ifdef PY_SSIZE_T_CLEAN +typedef Py_ssize_t Py_ssize_clean_t; +#else +typedef int Py_ssize_clean_t; +#endif + +/* Largest possible value of size_t. */ +#define PY_SIZE_MAX SIZE_MAX + +/* Largest positive value of type Py_ssize_t. */ +#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1)) +/* Smallest negative value of type Py_ssize_t. */ +#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) + +/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf + * format to convert an argument with the width of a size_t or Py_ssize_t. + * C99 introduced "z" for this purpose, but not all platforms support that; + * e.g., MS compilers use "I" instead. + * + * These "high level" Python format functions interpret "z" correctly on + * all platforms (Python interprets the format string itself, and does whatever + * the platform C requires to convert a size_t/Py_ssize_t argument): + * + * PyBytes_FromFormat + * PyErr_Format + * PyBytes_FromFormatV + * PyUnicode_FromFormatV + * + * Lower-level uses require that you interpolate the correct format modifier + * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for + * example, + * + * Py_ssize_t index; + * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index); + * + * That will expand to %ld, or %Id, or to something else correct for a + * Py_ssize_t on the platform. + */ +#ifndef PY_FORMAT_SIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__) +# define PY_FORMAT_SIZE_T "" +# elif SIZEOF_SIZE_T == SIZEOF_LONG +# define PY_FORMAT_SIZE_T "l" +# elif defined(MS_WINDOWS) +# define PY_FORMAT_SIZE_T "I" +# else +# error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T" +# endif +#endif + +/* Py_LOCAL can be used instead of static to get the fastest possible calling + * convention for functions that are local to a given module. + * + * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining, + * for platforms that support that. + * + * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more + * "aggressive" inlining/optimization is enabled for the entire module. This + * may lead to code bloat, and may slow things down for those reasons. It may + * also lead to errors, if the code relies on pointer aliasing. Use with + * care. + * + * NOTE: You can only use this for functions that are entirely local to a + * module; functions that are exported via method tables, callbacks, etc, + * should keep using static. + */ + +#if defined(_MSC_VER) +# if defined(PY_LOCAL_AGGRESSIVE) + /* enable more aggressive optimization for visual studio */ +# pragma optimize("agtw", on) +#endif + /* ignore warnings if the compiler decides not to inline a function */ +# pragma warning(disable: 4710) + /* fastest possible local call under MSVC */ +# define Py_LOCAL(type) static type __fastcall +# define Py_LOCAL_INLINE(type) static __inline type __fastcall +#else +# define Py_LOCAL(type) static type +# define Py_LOCAL_INLINE(type) static inline type +#endif + +/* Py_MEMCPY is kept for backwards compatibility, + * see https://bugs.python.org/issue28126 */ +#define Py_MEMCPY memcpy + +#include + +#ifdef HAVE_IEEEFP_H +#include /* needed for 'finite' declaration on some platforms */ +#endif + +#include /* Moved here from the math section, before extern "C" */ + +/******************************************** + * WRAPPER FOR and/or * + ********************************************/ + +#ifdef TIME_WITH_SYS_TIME +#include +#include +#else /* !TIME_WITH_SYS_TIME */ +#ifdef HAVE_SYS_TIME_H +#include +#else /* !HAVE_SYS_TIME_H */ +#include +#endif /* !HAVE_SYS_TIME_H */ +#endif /* !TIME_WITH_SYS_TIME */ + + +/****************************** + * WRAPPER FOR * + ******************************/ + +/* NB caller must include */ + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* !HAVE_SYS_SELECT_H */ + +/******************************* + * stat() and fstat() fiddling * + *******************************/ + +#ifdef HAVE_SYS_STAT_H +#include +#elif defined(HAVE_STAT_H) +#include +#endif + +#ifndef S_IFMT +/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */ +#define S_IFMT 0170000 +#endif + +#ifndef S_IFLNK +/* Windows doesn't define S_IFLNK but posixmodule.c maps + * IO_REPARSE_TAG_SYMLINK to S_IFLNK */ +# define S_IFLNK 0120000 +#endif + +#ifndef S_ISREG +#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISDIR +#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif + +#ifndef S_ISCHR +#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) +#endif + +#ifdef __cplusplus +/* Move this down here since some C++ #include's don't like to be included + inside an extern "C" */ +extern "C" { +#endif + + +/* Py_ARITHMETIC_RIGHT_SHIFT + * C doesn't define whether a right-shift of a signed integer sign-extends + * or zero-fills. Here a macro to force sign extension: + * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) + * Return I >> J, forcing sign extension. Arithmetically, return the + * floor of I/2**J. + * Requirements: + * I should have signed integer type. In the terminology of C99, this can + * be either one of the five standard signed integer types (signed char, + * short, int, long, long long) or an extended signed integer type. + * J is an integer >= 0 and strictly less than the number of bits in the + * type of I (because C doesn't define what happens for J outside that + * range either). + * TYPE used to specify the type of I, but is now ignored. It's been left + * in for backwards compatibility with versions <= 2.6 or 3.0. + * Caution: + * I may be evaluated more than once. + */ +#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \ + ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J)) +#else +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J)) +#endif + +/* Py_FORCE_EXPANSION(X) + * "Simply" returns its argument. However, macro expansions within the + * argument are evaluated. This unfortunate trickery is needed to get + * token-pasting to work as desired in some cases. + */ +#define Py_FORCE_EXPANSION(X) X + +/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) + * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this + * assert-fails if any information is lost. + * Caution: + * VALUE may be evaluated more than once. + */ +#ifdef Py_DEBUG +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \ + (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE)) +#else +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE) +#endif + +/* Py_SET_ERRNO_ON_MATH_ERROR(x) + * If a libm function did not set errno, but it looks like the result + * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno + * to 0 before calling a libm function, and invoke this macro after, + * passing the function result. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X is evaluated more than once. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64)) +#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM; +#else +#define _Py_SET_EDOM_FOR_NAN(X) ; +#endif +#define Py_SET_ERRNO_ON_MATH_ERROR(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + else _Py_SET_EDOM_FOR_NAN(X) \ + } \ + } while(0) + +/* Py_SET_ERANGE_IF_OVERFLOW(x) + * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility. + */ +#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X) + +/* Py_ADJUST_ERANGE1(x) + * Py_ADJUST_ERANGE2(x, y) + * Set errno to 0 before calling a libm function, and invoke one of these + * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful + * for functions returning complex results). This makes two kinds of + * adjustments to errno: (A) If it looks like the platform libm set + * errno=ERANGE due to underflow, clear errno. (B) If it looks like the + * platform libm overflowed but didn't set errno, force errno to ERANGE. In + * effect, we're trying to force a useful implementation of C89 errno + * behavior. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X and Y may be evaluated more than once. + */ +#define Py_ADJUST_ERANGE1(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE && (X) == 0.0) \ + errno = 0; \ + } while(0) + +#define Py_ADJUST_ERANGE2(X, Y) \ + do { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \ + (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \ + if (errno == 0) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE) \ + errno = 0; \ + } while(0) + +/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are + * required to support the short float repr introduced in Python 3.1) require + * that the floating-point unit that's being used for arithmetic operations + * on C doubles is set to use 53-bit precision. It also requires that the + * FPU rounding mode is round-half-to-even, but that's less often an issue. + * + * If your FPU isn't already set to 53-bit precision/round-half-to-even, and + * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should + * + * #define HAVE_PY_SET_53BIT_PRECISION 1 + * + * and also give appropriate definitions for the following three macros: + * + * _PY_SET_53BIT_PRECISION_START : store original FPU settings, and + * set FPU to 53-bit precision/round-half-to-even + * _PY_SET_53BIT_PRECISION_END : restore original FPU settings + * _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to + * use the two macros above. + * + * The macros are designed to be used within a single C function: see + * Python/pystrtod.c for an example of their use. + */ + +/* get and set x87 control word for gcc/x86 */ +#ifdef HAVE_GCC_ASM_FOR_X87 +#define HAVE_PY_SET_53BIT_PRECISION 1 +/* _Py_get/set_387controlword functions are defined in Python/pymath.c */ +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned short old_387controlword, new_387controlword +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + old_387controlword = _Py_get_387controlword(); \ + new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(new_387controlword); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(old_387controlword) +#endif + +/* get and set x87 control word for VisualStudio/x86 */ +#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) /* x87 not supported in 64-bit or ARM */ +#define HAVE_PY_SET_53BIT_PRECISION 1 +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned int old_387controlword, new_387controlword, out_387controlword +/* We use the __control87_2 function to set only the x87 control word. + The SSE control word is unaffected. */ +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + __control87_2(0, 0, &old_387controlword, NULL); \ + new_387controlword = \ + (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \ + if (new_387controlword != old_387controlword) \ + __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \ + &out_387controlword, NULL); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + do { \ + if (new_387controlword != old_387controlword) \ + __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \ + &out_387controlword, NULL); \ + } while (0) +#endif + +#ifdef HAVE_GCC_ASM_FOR_MC68881 +#define HAVE_PY_SET_53BIT_PRECISION 1 +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned int old_fpcr, new_fpcr +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \ + /* Set double precision / round to nearest. */ \ + new_fpcr = (old_fpcr & ~0xf0) | 0x80; \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + do { \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \ + } while (0) +#endif + +/* default definitions are empty */ +#ifndef HAVE_PY_SET_53BIT_PRECISION +#define _Py_SET_53BIT_PRECISION_HEADER +#define _Py_SET_53BIT_PRECISION_START +#define _Py_SET_53BIT_PRECISION_END +#endif + +/* If we can't guarantee 53-bit precision, don't use the code + in Python/dtoa.c, but fall back to standard code. This + means that repr of a float will be long (17 sig digits). + + Realistically, there are two things that could go wrong: + + (1) doubles aren't IEEE 754 doubles, or + (2) we're on x86 with the rounding precision set to 64-bits + (extended precision), and we don't know how to change + the rounding precision. + */ + +#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +#define PY_NO_SHORT_FLOAT_REPR +#endif + +/* double rounding is symptomatic of use of extended precision on x86. If + we're seeing double rounding, and we don't have any mechanism available for + changing the FPU rounding precision, then don't use Python/dtoa.c. */ +#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) +#define PY_NO_SHORT_FLOAT_REPR +#endif + + +/* Py_DEPRECATED(version) + * Declare a variable, type, or function deprecated. + * The macro must be placed before the declaration. + * Usage: + * Py_DEPRECATED(3.3) extern int old_var; + * Py_DEPRECATED(3.4) typedef int T1; + * Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); + */ +#if defined(__GNUC__) \ + && ((__GNUC__ >= 4) || (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) +#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +#elif defined(_MSC_VER) +#define Py_DEPRECATED(VERSION) __declspec(deprecated( \ + "deprecated in " #VERSION)) +#else +#define Py_DEPRECATED(VERSION_UNUSED) +#endif + + +/* _Py_HOT_FUNCTION + * The hot attribute on a function is used to inform the compiler that the + * function is a hot spot of the compiled program. The function is optimized + * more aggressively and on many target it is placed into special subsection of + * the text section so all hot functions appears close together improving + * locality. + * + * Usage: + * int _Py_HOT_FUNCTION x(void) { return 3; } + * + * Issue #28618: This attribute must not be abused, otherwise it can have a + * negative effect on performance. Only the functions were Python spend most of + * its time must use it. Use a profiler when running performance benchmark + * suite to find these functions. + */ +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) +#define _Py_HOT_FUNCTION __attribute__((hot)) +#else +#define _Py_HOT_FUNCTION +#endif + +/* _Py_NO_INLINE + * Disable inlining on a function. For example, it helps to reduce the C stack + * consumption. + * + * Usage: + * int _Py_NO_INLINE x(void) { return 3; } + */ +#if defined(_MSC_VER) +# define _Py_NO_INLINE __declspec(noinline) +#elif defined(__GNUC__) || defined(__clang__) +# define _Py_NO_INLINE __attribute__ ((noinline)) +#else +# define _Py_NO_INLINE +#endif + +/************************************************************************** +Prototypes that are missing from the standard include files on some systems +(and possibly only some versions of such systems.) + +Please be conservative with adding new ones, document them and enclose them +in platform-specific #ifdefs. +**************************************************************************/ + +#ifdef SOLARIS +/* Unchecked */ +extern int gethostname(char *, int); +#endif + +#ifdef HAVE__GETPTY +#include /* we need to import mode_t */ +extern char * _getpty(int *, int, mode_t, int); +#endif + +/* On QNX 6, struct termio must be declared by including sys/termio.h + if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must + be included before termios.h or it will generate an error. */ +#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux) +#include +#endif + + +/* On 4.4BSD-descendants, ctype functions serves the whole range of + * wchar_t character set rather than single byte code points only. + * This characteristic can break some operations of string object + * including str.upper() and str.split() on UTF-8 locales. This + * workaround was provided by Tim Robbins of FreeBSD project. + */ + +#if defined(__APPLE__) +# define _PY_PORT_CTYPE_UTF8_ISSUE +#endif + +#ifdef _PY_PORT_CTYPE_UTF8_ISSUE +#ifndef __cplusplus + /* The workaround below is unsafe in C++ because + * the defines these symbols as real functions, + * with a slightly different signature. + * See issue #10910 + */ +#include +#include +#undef isalnum +#define isalnum(c) iswalnum(btowc(c)) +#undef isalpha +#define isalpha(c) iswalpha(btowc(c)) +#undef islower +#define islower(c) iswlower(btowc(c)) +#undef isspace +#define isspace(c) iswspace(btowc(c)) +#undef isupper +#define isupper(c) iswupper(btowc(c)) +#undef tolower +#define tolower(c) towlower(btowc(c)) +#undef toupper +#define toupper(c) towupper(btowc(c)) +#endif +#endif + + +/* Declarations for symbol visibility. + + PyAPI_FUNC(type): Declares a public Python API function and return type + PyAPI_DATA(type): Declares public Python data and its type + PyMODINIT_FUNC: A Python module init function. If these functions are + inside the Python core, they are private to the core. + If in an extension module, it may be declared with + external linkage depending on the platform. + + As a number of platforms support/require "__declspec(dllimport/dllexport)", + we support a HAVE_DECLSPEC_DLL macro to save duplication. +*/ + +/* + All windows ports, except cygwin, are handled in PC/pyconfig.h. + + Cygwin is the only other autoconf platform requiring special + linkage handling and it uses __declspec(). +*/ +#if defined(__CYGWIN__) +# define HAVE_DECLSPEC_DLL +#endif + +/* only get special linkage if built as shared or platform is Cygwin */ +#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) +# if defined(HAVE_DECLSPEC_DLL) +# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE +# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE + /* module init functions inside the core need no external linkage */ + /* except for Cygwin to handle embedding */ +# if defined(__CYGWIN__) +# define PyMODINIT_FUNC __declspec(dllexport) PyObject* +# else /* __CYGWIN__ */ +# define PyMODINIT_FUNC PyObject* +# endif /* __CYGWIN__ */ +# else /* Py_BUILD_CORE */ + /* Building an extension module, or an embedded situation */ + /* public Python functions and data are imported */ + /* Under Cygwin, auto-import functions to prevent compilation */ + /* failures similar to those described at the bottom of 4.1: */ + /* http://docs.python.org/extending/windows.html#a-cookbook-approach */ +# if !defined(__CYGWIN__) +# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE +# endif /* !__CYGWIN__ */ +# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE + /* module init functions outside the core must be exported */ +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" __declspec(dllexport) PyObject* +# else /* __cplusplus */ +# define PyMODINIT_FUNC __declspec(dllexport) PyObject* +# endif /* __cplusplus */ +# endif /* Py_BUILD_CORE */ +# endif /* HAVE_DECLSPEC_DLL */ +#endif /* Py_ENABLE_SHARED */ + +/* If no external linkage macros defined by now, create defaults */ +#ifndef PyAPI_FUNC +# define PyAPI_FUNC(RTYPE) RTYPE +#endif +#ifndef PyAPI_DATA +# define PyAPI_DATA(RTYPE) extern RTYPE +#endif +#ifndef PyMODINIT_FUNC +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" PyObject* +# else /* __cplusplus */ +# define PyMODINIT_FUNC PyObject* +# endif /* __cplusplus */ +#endif + +/* limits.h constants that may be missing */ + +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif + +#ifndef LONG_MAX +#if SIZEOF_LONG == 4 +#define LONG_MAX 0X7FFFFFFFL +#elif SIZEOF_LONG == 8 +#define LONG_MAX 0X7FFFFFFFFFFFFFFFL +#else +#error "could not set LONG_MAX in pyport.h" +#endif +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * SIZEOF_LONG) +#endif + +#if LONG_BIT != 8 * SIZEOF_LONG +/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent + * 32-bit platforms using gcc. We try to catch that here at compile-time + * rather than waiting for integer multiplication to trigger bogus + * overflows. + */ +#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." +#endif + +#ifdef __cplusplus +} +#endif + +/* + * Hide GCC attributes from compilers that don't support them. + */ +#if (!defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) +#define Py_GCC_ATTRIBUTE(x) +#else +#define Py_GCC_ATTRIBUTE(x) __attribute__(x) +#endif + +/* + * Specify alignment on compilers that support it. + */ +#if defined(__GNUC__) && __GNUC__ >= 3 +#define Py_ALIGNED(x) __attribute__((aligned(x))) +#else +#define Py_ALIGNED(x) +#endif + +/* Eliminate end-of-loop code not reached warnings from SunPro C + * when using do{...}while(0) macros + */ +#ifdef __SUNPRO_C +#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED) +#endif + +#ifndef Py_LL +#define Py_LL(x) x##LL +#endif + +#ifndef Py_ULL +#define Py_ULL(x) Py_LL(x##U) +#endif + +#define Py_VA_COPY va_copy + +/* + * Convenient macros to deal with endianness of the platform. WORDS_BIGENDIAN is + * detected by configure and defined in pyconfig.h. The code in pyconfig.h + * also takes care of Apple's universal builds. + */ + +#ifdef WORDS_BIGENDIAN +#define PY_BIG_ENDIAN 1 +#define PY_LITTLE_ENDIAN 0 +#else +#define PY_BIG_ENDIAN 0 +#define PY_LITTLE_ENDIAN 1 +#endif + +#ifdef Py_BUILD_CORE +/* + * Macros to protect CRT calls against instant termination when passed an + * invalid parameter (issue23524). + */ +#if defined _MSC_VER && _MSC_VER >= 1900 + +extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; +#define _Py_BEGIN_SUPPRESS_IPH { _invalid_parameter_handler _Py_old_handler = \ + _set_thread_local_invalid_parameter_handler(_Py_silent_invalid_parameter_handler); +#define _Py_END_SUPPRESS_IPH _set_thread_local_invalid_parameter_handler(_Py_old_handler); } + +#else + +#define _Py_BEGIN_SUPPRESS_IPH +#define _Py_END_SUPPRESS_IPH + +#endif /* _MSC_VER >= 1900 */ +#endif /* Py_BUILD_CORE */ + +#ifdef __ANDROID__ + /* The Android langinfo.h header is not used. */ +# undef HAVE_LANGINFO_H +# undef CODESET +#endif + +/* Maximum value of the Windows DWORD type */ +#define PY_DWORD_MAX 4294967295U + +/* This macro used to tell whether Python was built with multithreading + * enabled. Now multithreading is always enabled, but keep the macro + * for compatibility. + */ +#ifndef WITH_THREAD +# define WITH_THREAD +#endif + +/* Check that ALT_SOABI is consistent with Py_TRACE_REFS: + ./configure --with-trace-refs should must be used to define Py_TRACE_REFS */ +#if defined(ALT_SOABI) && defined(Py_TRACE_REFS) +# error "Py_TRACE_REFS ABI is not compatible with release and debug ABI" +#endif + +#if defined(__ANDROID__) || defined(__VXWORKS__) + /* Ignore the locale encoding: force UTF-8 */ +# define _Py_FORCE_UTF8_LOCALE +#endif + +#if defined(_Py_FORCE_UTF8_LOCALE) || defined(__APPLE__) + /* Use UTF-8 as filesystem encoding */ +# define _Py_FORCE_UTF8_FS_ENCODING +#endif + +/* Mark a function which cannot return. Example: + + PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); */ +#if defined(__clang__) || \ + (defined(__GNUC__) && \ + ((__GNUC__ >= 3) || \ + (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))) +# define _Py_NO_RETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +# define _Py_NO_RETURN __declspec(noreturn) +#else +# define _Py_NO_RETURN +#endif + +#endif /* Py_PYPORT_H */ diff --git a/python/include/pystate.h b/python/include/pystate.h new file mode 100755 index 0000000..4c25e3f --- /dev/null +++ b/python/include/pystate.h @@ -0,0 +1,136 @@ +/* Thread and interpreter state structures and their interfaces */ + + +#ifndef Py_PYSTATE_H +#define Py_PYSTATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "pythread.h" + +/* This limitation is for performance and simplicity. If needed it can be +removed (with effort). */ +#define MAX_CO_EXTRA_USERS 255 + +/* Forward declarations for PyFrameObject, PyThreadState + and PyInterpreterState */ +struct _frame; +struct _ts; +struct _is; + +/* struct _ts is defined in cpython/pystate.h */ +typedef struct _ts PyThreadState; +/* struct _is is defined in internal/pycore_pystate.h */ +typedef struct _is PyInterpreterState; + +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); +PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); +PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03080000 +/* New in 3.8 */ +PyAPI_FUNC(PyObject *) PyInterpreterState_GetDict(PyInterpreterState *); +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +/* New in 3.7 */ +PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 + +/* State unique per thread */ + +/* New in 3.3 */ +PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*); +PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*); +#endif +PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*); + +PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); +PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); + +/* Get the current thread state. + + When the current thread state is NULL, this issues a fatal error (so that + the caller needn't check for NULL). + + The caller must hold the GIL. + + See also PyThreadState_GET() and _PyThreadState_GET(). */ +PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); + +/* Get the current Python thread state. + + Macro using PyThreadState_Get() or _PyThreadState_GET() depending if + pycore_pystate.h is included or not (this header redefines the macro). + + If PyThreadState_Get() is used, issue a fatal error if the current thread + state is NULL. + + See also PyThreadState_Get() and _PyThreadState_GET(). */ +#define PyThreadState_GET() PyThreadState_Get() + +PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); +PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); +PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *); + +typedef + enum {PyGILState_LOCKED, PyGILState_UNLOCKED} + PyGILState_STATE; + + +/* Ensure that the current thread is ready to call the Python + C API, regardless of the current state of Python, or of its + thread lock. This may be called as many times as desired + by a thread so long as each call is matched with a call to + PyGILState_Release(). In general, other thread-state APIs may + be used between _Ensure() and _Release() calls, so long as the + thread-state is restored to its previous state before the Release(). + For example, normal use of the Py_BEGIN_ALLOW_THREADS/ + Py_END_ALLOW_THREADS macros are acceptable. + + The return value is an opaque "handle" to the thread state when + PyGILState_Ensure() was called, and must be passed to + PyGILState_Release() to ensure Python is left in the same state. Even + though recursive calls are allowed, these handles can *not* be shared - + each unique call to PyGILState_Ensure must save the handle for its + call to PyGILState_Release. + + When the function returns, the current thread will hold the GIL. + + Failure is a fatal error. +*/ +PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure(void); + +/* Release any resources previously acquired. After this call, Python's + state will be the same as it was prior to the corresponding + PyGILState_Ensure() call (but generally this state will be unknown to + the caller, hence the use of the GILState API.) + + Every call to PyGILState_Ensure must be matched by a call to + PyGILState_Release on the same thread. +*/ +PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE); + +/* Helper/diagnostic function - get the current thread state for + this thread. May return NULL if no GILState API has been used + on the current thread. Note that the main thread always has such a + thread-state, even if no auto-thread-state call has been made + on the main thread. +*/ +PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); + + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_PYSTATE_H +# include "cpython/pystate.h" +# undef Py_CPYTHON_PYSTATE_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYSTATE_H */ diff --git a/python/include/pystrcmp.h b/python/include/pystrcmp.h new file mode 100755 index 0000000..edb1239 --- /dev/null +++ b/python/include/pystrcmp.h @@ -0,0 +1,23 @@ +#ifndef Py_STRCMP_H +#define Py_STRCMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyOS_mystrnicmp(const char *, const char *, Py_ssize_t); +PyAPI_FUNC(int) PyOS_mystricmp(const char *, const char *); + +#ifdef MS_WINDOWS +#define PyOS_strnicmp strnicmp +#define PyOS_stricmp stricmp +#else +#define PyOS_strnicmp PyOS_mystrnicmp +#define PyOS_stricmp PyOS_mystricmp +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRCMP_H */ diff --git a/python/include/pystrhex.h b/python/include/pystrhex.h new file mode 100755 index 0000000..a4f3630 --- /dev/null +++ b/python/include/pystrhex.h @@ -0,0 +1,22 @@ +#ifndef Py_STRHEX_H +#define Py_STRHEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +/* Returns a str() containing the hex representation of argbuf. */ +PyAPI_FUNC(PyObject*) _Py_strhex(const char* argbuf, const Py_ssize_t arglen); +/* Returns a bytes() containing the ASCII hex representation of argbuf. */ +PyAPI_FUNC(PyObject*) _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen); +/* These variants include support for a separator between every N bytes: */ +PyAPI_FUNC(PyObject*) _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group); +PyAPI_FUNC(PyObject*) _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group); +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRHEX_H */ diff --git a/python/include/pystrtod.h b/python/include/pystrtod.h new file mode 100755 index 0000000..c1e84de --- /dev/null +++ b/python/include/pystrtod.h @@ -0,0 +1,45 @@ +#ifndef Py_STRTOD_H +#define Py_STRTOD_H + +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_FUNC(double) PyOS_string_to_double(const char *str, + char **endptr, + PyObject *overflow_exception); + +/* The caller is responsible for calling PyMem_Free to free the buffer + that's is returned. */ +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _Py_string_to_number_with_underscores( + const char *str, Py_ssize_t len, const char *what, PyObject *obj, void *arg, + PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)); + +PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr); +#endif + + +/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ +#define Py_DTSF_SIGN 0x01 /* always add the sign */ +#define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ +#define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code + specific */ + +/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ +#define Py_DTST_FINITE 0 +#define Py_DTST_INFINITE 1 +#define Py_DTST_NAN 2 + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRTOD_H */ diff --git a/python/include/pythonrun.h b/python/include/pythonrun.h new file mode 100755 index 0000000..46091e0 --- /dev/null +++ b/python/include/pythonrun.h @@ -0,0 +1,210 @@ + +/* Interfaces to parse and execute pieces of python code */ + +#ifndef Py_PYTHONRUN_H +#define Py_PYTHONRUN_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_AnyFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_SimpleFileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int closeit, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveOneObject( + FILE *fp, + PyObject *filename, + PyCompilerFlags *flags); +PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + PyCompilerFlags *flags); + +PyAPI_FUNC(struct _mod *) PyParser_ASTFromString( + const char *s, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyCompilerFlags *flags, + PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromStringObject( + const char *s, + PyObject *filename, + int start, + PyCompilerFlags *flags, + PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + const char* enc, + int start, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromFileObject( + FILE *fp, + PyObject *filename, + const char* enc, + int start, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); +#endif + +#ifndef PyParser_SimpleParseString +#define PyParser_SimpleParseString(S, B) \ + PyParser_SimpleParseStringFlags(S, B, 0) +#define PyParser_SimpleParseFile(FP, S, B) \ + PyParser_SimpleParseFileFlags(FP, S, B, 0) +#endif +PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, + int); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlagsFilename(const char *, + const char *, + int, int); +#endif +PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, + int, int); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, + PyObject *, PyCompilerFlags *); + +PyAPI_FUNC(PyObject *) PyRun_FileExFlags( + FILE *fp, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyObject *globals, + PyObject *locals, + int closeit, + PyCompilerFlags *flags); +#endif + +#ifdef Py_LIMITED_API +PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int); +#else +#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1) +#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1) +PyAPI_FUNC(PyObject *) Py_CompileStringExFlags( + const char *str, + const char *filename, /* decoded from the filesystem encoding */ + int start, + PyCompilerFlags *flags, + int optimize); +PyAPI_FUNC(PyObject *) Py_CompileStringObject( + const char *str, + PyObject *filename, int start, + PyCompilerFlags *flags, + int optimize); +#endif +PyAPI_FUNC(struct symtable *) Py_SymtableString( + const char *str, + const char *filename, /* decoded from the filesystem encoding */ + int start); +#ifndef Py_LIMITED_API +PyAPI_FUNC(const char *) _Py_SourceAsString( + PyObject *cmd, + const char *funcname, + const char *what, + PyCompilerFlags *cf, + PyObject **cmd_copy); + +PyAPI_FUNC(struct symtable *) Py_SymtableStringObject( + const char *str, + PyObject *filename, + int start); + +PyAPI_FUNC(struct symtable *) _Py_SymtableStringObjectFlags( + const char *str, + PyObject *filename, + int start, + PyCompilerFlags *flags); +#endif + +PyAPI_FUNC(void) PyErr_Print(void); +PyAPI_FUNC(void) PyErr_PrintEx(int); +PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); + +#ifndef Py_LIMITED_API +/* A function flavor is also exported by libpython. It is required when + libpython is accessed directly rather than using header files which defines + macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to + export functions in pythonXX.dll. */ +PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l); +PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name); +PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit); +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_SimpleString(const char *s); +PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p); +PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c); +PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p); +PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p); +PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l); +PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c); +PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags); + +/* Use macros for a bunch of old variants */ +#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) +#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) +#define PyRun_AnyFileEx(fp, name, closeit) \ + PyRun_AnyFileExFlags(fp, name, closeit, NULL) +#define PyRun_AnyFileFlags(fp, name, flags) \ + PyRun_AnyFileExFlags(fp, name, 0, flags) +#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL) +#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL) +#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL) +#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL) +#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL) +#define PyRun_File(fp, p, s, g, l) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, NULL) +#define PyRun_FileEx(fp, p, s, g, l, c) \ + PyRun_FileExFlags(fp, p, s, g, l, c, NULL) +#define PyRun_FileFlags(fp, p, s, g, l, flags) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, flags) +#endif + +/* Stuff with no proper home (yet) */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); +#endif +PyAPI_DATA(int) (*PyOS_InputHook)(void); +PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *); +#ifndef Py_LIMITED_API +PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; +#endif + +/* Stack size, in "pointers" (so we get extra safety margins + on 64-bit platforms). On a 32-bit platform, this translates + to an 8k margin. */ +#define PYOS_STACK_MARGIN 2048 + +#if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 +/* Enable stack checking under Microsoft C */ +#define USE_STACKCHECK +#endif + +#ifdef USE_STACKCHECK +/* Check that we aren't overflowing our stack */ +PyAPI_FUNC(int) PyOS_CheckStack(void); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYTHONRUN_H */ diff --git a/python/include/pythread.h b/python/include/pythread.h new file mode 100755 index 0000000..f22e8c4 --- /dev/null +++ b/python/include/pythread.h @@ -0,0 +1,161 @@ + +#ifndef Py_PYTHREAD_H +#define Py_PYTHREAD_H + +typedef void *PyThread_type_lock; +typedef void *PyThread_type_sema; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return status codes for Python lock acquisition. Chosen for maximum + * backwards compatibility, ie failure -> 0, success -> 1. */ +typedef enum PyLockStatus { + PY_LOCK_FAILURE = 0, + PY_LOCK_ACQUIRED = 1, + PY_LOCK_INTR +} PyLockStatus; + +#ifndef Py_LIMITED_API +#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) +#endif + +PyAPI_FUNC(void) PyThread_init_thread(void); +PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); +PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); +PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); + +#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX) +#define PY_HAVE_THREAD_NATIVE_ID +PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); +#endif + +PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); +PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); +PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); +#define WAIT_LOCK 1 +#define NOWAIT_LOCK 0 + +/* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting + on a lock (see PyThread_acquire_lock_timed() below). + PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that + type, and depends on the system threading API. + + NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread + module exposes a higher-level API, with timeouts expressed in seconds + and floating-point numbers allowed. +*/ +#define PY_TIMEOUT_T long long + +#if defined(_POSIX_THREADS) + /* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000), + convert microseconds to nanoseconds. */ +# define PY_TIMEOUT_MAX (PY_LLONG_MAX / 1000) +#elif defined (NT_THREADS) + /* In the NT API, the timeout is a DWORD and is expressed in milliseconds */ +# if 0xFFFFFFFFLL * 1000 < PY_LLONG_MAX +# define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000) +# else +# define PY_TIMEOUT_MAX PY_LLONG_MAX +# endif +#else +# define PY_TIMEOUT_MAX PY_LLONG_MAX +#endif + + +/* If microseconds == 0, the call is non-blocking: it returns immediately + even when the lock can't be acquired. + If microseconds > 0, the call waits up to the specified duration. + If microseconds < 0, the call waits until success (or abnormal failure) + + microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is + undefined. + + If intr_flag is true and the acquire is interrupted by a signal, then the + call will return PY_LOCK_INTR. The caller may reattempt to acquire the + lock. +*/ +PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed(PyThread_type_lock, + PY_TIMEOUT_T microseconds, + int intr_flag); + +PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock); + +PyAPI_FUNC(size_t) PyThread_get_stacksize(void); +PyAPI_FUNC(int) PyThread_set_stacksize(size_t); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyThread_GetInfo(void); +#endif + + +/* Thread Local Storage (TLS) API + TLS API is DEPRECATED. Use Thread Specific Storage (TSS) API. + + The existing TLS API has used int to represent TLS keys across all + platforms, but it is not POSIX-compliant. Therefore, the new TSS API uses + opaque data type to represent TSS keys to be compatible (see PEP 539). +*/ +Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_create_key(void); +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key(int key); +Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_set_key_value(int key, + void *value); +Py_DEPRECATED(3.7) PyAPI_FUNC(void *) PyThread_get_key_value(int key); +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key_value(int key); + +/* Cleanup after a fork */ +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_ReInitTLS(void); + + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +/* New in 3.7 */ +/* Thread Specific Storage (TSS) API */ + +typedef struct _Py_tss_t Py_tss_t; /* opaque */ + +#ifndef Py_LIMITED_API +#if defined(_POSIX_THREADS) + /* Darwin needs pthread.h to know type name the pthread_key_t. */ +# include +# define NATIVE_TSS_KEY_T pthread_key_t +#elif defined(NT_THREADS) + /* In Windows, native TSS key type is DWORD, + but hardcode the unsigned long to avoid errors for include directive. + */ +# define NATIVE_TSS_KEY_T unsigned long +#else +# error "Require native threads. See https://bugs.python.org/issue31370" +#endif + +/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is + exposed to allow static allocation in the API clients. Even in this case, + you must handle TSS keys through API functions due to compatibility. +*/ +struct _Py_tss_t { + int _is_initialized; + NATIVE_TSS_KEY_T _key; +}; + +#undef NATIVE_TSS_KEY_T + +/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */ +#define Py_tss_NEEDS_INIT {0} +#endif /* !Py_LIMITED_API */ + +PyAPI_FUNC(Py_tss_t *) PyThread_tss_alloc(void); +PyAPI_FUNC(void) PyThread_tss_free(Py_tss_t *key); + +/* The parameter key must not be NULL. */ +PyAPI_FUNC(int) PyThread_tss_is_created(Py_tss_t *key); +PyAPI_FUNC(int) PyThread_tss_create(Py_tss_t *key); +PyAPI_FUNC(void) PyThread_tss_delete(Py_tss_t *key); +PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t *key, void *value); +PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t *key); +#endif /* New in 3.7 */ + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYTHREAD_H */ diff --git a/python/include/pytime.h b/python/include/pytime.h new file mode 100755 index 0000000..bdda1da --- /dev/null +++ b/python/include/pytime.h @@ -0,0 +1,246 @@ +#ifndef Py_LIMITED_API +#ifndef Py_PYTIME_H +#define Py_PYTIME_H + +#include "pyconfig.h" /* include for defines */ +#include "object.h" + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to time related +functions and constants +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +/* _PyTime_t: Python timestamp with subsecond precision. It can be used to + store a duration, and so indirectly a date (related to another date, like + UNIX epoch). */ +typedef int64_t _PyTime_t; +#define _PyTime_MIN INT64_MIN +#define _PyTime_MAX INT64_MAX + +typedef enum { + /* Round towards minus infinity (-inf). + For example, used to read a clock. */ + _PyTime_ROUND_FLOOR=0, + /* Round towards infinity (+inf). + For example, used for timeout to wait "at least" N seconds. */ + _PyTime_ROUND_CEILING=1, + /* Round to nearest with ties going to nearest even integer. + For example, used to round from a Python float. */ + _PyTime_ROUND_HALF_EVEN=2, + /* Round away from zero + For example, used for timeout. _PyTime_ROUND_CEILING rounds + -1e-9 to 0 milliseconds which causes bpo-31786 issue. + _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps + the timeout sign as expected. select.poll(timeout) must block + for negative values." */ + _PyTime_ROUND_UP=3, + /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be + used for timeouts. */ + _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP +} _PyTime_round_t; + + +/* Convert a time_t to a PyLong. */ +PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( + time_t sec); + +/* Convert a PyLong to a time_t. */ +PyAPI_FUNC(time_t) _PyLong_AsTime_t( + PyObject *obj); + +/* Convert a number of seconds, int or float, to time_t. */ +PyAPI_FUNC(int) _PyTime_ObjectToTime_t( + PyObject *obj, + time_t *sec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timeval structure. + usec is in the range [0; 999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimeval( + PyObject *obj, + time_t *sec, + long *usec, + _PyTime_round_t); + +/* Convert a number of seconds, int or float, to a timespec structure. + nsec is in the range [0; 999999999] and rounded towards zero. + For example, -1.2 is converted to (-2, 800000000). */ +PyAPI_FUNC(int) _PyTime_ObjectToTimespec( + PyObject *obj, + time_t *sec, + long *nsec, + _PyTime_round_t); + + +/* Create a timestamp from a number of seconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); + +/* Macro to create a timestamp from a number of seconds, no integer overflow. + Only use the macro for small values, prefer _PyTime_FromSeconds(). */ +#define _PYTIME_FROMSECONDS(seconds) \ + ((_PyTime_t)(seconds) * (1000 * 1000 * 1000)) + +/* Create a timestamp from a number of nanoseconds. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); + +/* Create a timestamp from nanoseconds (Python int). */ +PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, + PyObject *obj); + +/* Convert a number of seconds (Python float or int) to a timetamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a number of milliseconds (Python float or int, 10^-3) to a timetamp. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, + PyObject *obj, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds as a C double. */ +PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); + +/* Convert timestamp to a number of milliseconds (10^-3 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of microseconds (10^-6 seconds). */ +PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t, + _PyTime_round_t round); + +/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int + object. */ +PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t); + +/* Create a timestamp from a timeval structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); + +/* Convert a timestamp to a timeval structure (microsecond resolution). + tv_usec is always positive. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Similar to _PyTime_AsTimeval(), but don't raise an exception on error. */ +PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t, + struct timeval *tv, + _PyTime_round_t round); + +/* Convert a timestamp to a number of seconds (secs) and microseconds (us). + us is always positive. This function is similar to _PyTime_AsTimeval() + except that secs is always a time_t type, whereas the timeval structure + uses a C long for tv_sec on Windows. + Raise an exception and return -1 if the conversion overflowed, + return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( + _PyTime_t t, + time_t *secs, + int *us, + _PyTime_round_t round); + +#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) +/* Create a timestamp from a timespec structure. + Raise an exception and return -1 on overflow, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts); + +/* Convert a timestamp to a timespec structure (nanosecond resolution). + tv_nsec is always positive. + Raise an exception and return -1 on error, return 0 on success. */ +PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts); +#endif + +/* Compute ticks * mul / div. + The caller must ensure that ((div - 1) * mul) cannot overflow. */ +PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks, + _PyTime_t mul, + _PyTime_t div); + +/* Get the current time from the system clock. + + The function cannot fail. _PyTime_Init() ensures that the system clock + works. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + The function cannot fail. _PyTime_Init() ensures that a monotonic clock + is available and works. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); + + +/* Structure used by time.get_clock_info() */ +typedef struct { + const char *implementation; + int monotonic; + int adjustable; + double resolution; +} _Py_clock_info_t; + +/* Get the current time from the system clock. + * Fill clock information if info is not NULL. + * Raise an exception and return -1 on error, return 0 on success. + */ +PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + + +/* Initialize time. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_Init(void); + +/* Converts a timestamp to the Gregorian time, using the local time zone. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); + +/* Converts a timestamp to the Gregorian time, assuming UTC. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + The function cannot fail. _PyTime_Init() ensures that the system clock + works. */ +PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); + +/* Get the performance counter: clock with the highest available resolution to + measure a short duration. + + Fill info (if set) with information of the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo( + _PyTime_t *t, + _Py_clock_info_t *info); + +#ifdef __cplusplus +} +#endif + +#endif /* Py_PYTIME_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/rangeobject.h b/python/include/rangeobject.h new file mode 100755 index 0000000..7e4dc28 --- /dev/null +++ b/python/include/rangeobject.h @@ -0,0 +1,27 @@ + +/* Range object interface */ + +#ifndef Py_RANGEOBJECT_H +#define Py_RANGEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* +A range object represents an integer range. This is an immutable object; +a range cannot change its value after creation. + +Range objects behave like the corresponding tuple objects except that +they are represented by a start, stop, and step datamembers. +*/ + +PyAPI_DATA(PyTypeObject) PyRange_Type; +PyAPI_DATA(PyTypeObject) PyRangeIter_Type; +PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type; + +#define PyRange_Check(op) (Py_TYPE(op) == &PyRange_Type) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_RANGEOBJECT_H */ diff --git a/python/include/setobject.h b/python/include/setobject.h new file mode 100755 index 0000000..fc0ea83 --- /dev/null +++ b/python/include/setobject.h @@ -0,0 +1,108 @@ +/* Set object interface */ + +#ifndef Py_SETOBJECT_H +#define Py_SETOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + +/* There are three kinds of entries in the table: + +1. Unused: key == NULL and hash == 0 +2. Dummy: key == dummy and hash == -1 +3. Active: key != NULL and key != dummy and hash != -1 + +The hash field of Unused slots is always zero. + +The hash field of Dummy slots are set to -1 +meaning that dummy entries can be detected by +either entry->key==dummy or by entry->hash==-1. +*/ + +#define PySet_MINSIZE 8 + +typedef struct { + PyObject *key; + Py_hash_t hash; /* Cached hash code of the key */ +} setentry; + +/* The SetObject data structure is shared by set and frozenset objects. + +Invariant for sets: + - hash is -1 + +Invariants for frozensets: + - data is immutable. + - hash is the hash of the frozenset or -1 if not computed yet. + +*/ + +typedef struct { + PyObject_HEAD + + Py_ssize_t fill; /* Number active and dummy entries*/ + Py_ssize_t used; /* Number active entries */ + + /* The table contains mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t mask; + + /* The table points to a fixed-size smalltable for small tables + * or to additional malloc'ed memory for bigger tables. + * The table pointer is never NULL which saves us from repeated + * runtime null-tests. + */ + setentry *table; + Py_hash_t hash; /* Only used by frozenset objects */ + Py_ssize_t finger; /* Search finger for pop() */ + + setentry smalltable[PySet_MINSIZE]; + PyObject *weakreflist; /* List of weak references */ +} PySetObject; + +#define PySet_GET_SIZE(so) (assert(PyAnySet_Check(so)),(((PySetObject *)(so))->used)) + +PyAPI_DATA(PyObject *) _PySet_Dummy; + +PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); +PyAPI_FUNC(int) PySet_ClearFreeList(void); + +#endif /* Section excluded by Py_LIMITED_API */ + +PyAPI_DATA(PyTypeObject) PySet_Type; +PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; +PyAPI_DATA(PyTypeObject) PySetIter_Type; + +PyAPI_FUNC(PyObject *) PySet_New(PyObject *); +PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); + +PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); +PyAPI_FUNC(int) PySet_Clear(PyObject *set); +PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); +PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); +PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); +PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); + +#define PyFrozenSet_CheckExact(ob) (Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyAnySet_CheckExact(ob) \ + (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyAnySet_Check(ob) \ + (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ + PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) +#define PySet_Check(ob) \ + (Py_TYPE(ob) == &PySet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) +#define PyFrozenSet_Check(ob) \ + (Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SETOBJECT_H */ diff --git a/python/include/sliceobject.h b/python/include/sliceobject.h new file mode 100755 index 0000000..aae6f3c --- /dev/null +++ b/python/include/sliceobject.h @@ -0,0 +1,65 @@ +#ifndef Py_SLICEOBJECT_H +#define Py_SLICEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* The unique ellipsis object "..." */ + +PyAPI_DATA(PyObject) _Py_EllipsisObject; /* Don't use this directly */ + +#define Py_Ellipsis (&_Py_EllipsisObject) + +/* Slice object interface */ + +/* + +A slice object containing start, stop, and step data members (the +names are from range). After much talk with Guido, it was decided to +let these be any arbitrary python type. Py_None stands for omitted values. +*/ +#ifndef Py_LIMITED_API +typedef struct { + PyObject_HEAD + PyObject *start, *stop, *step; /* not NULL */ +} PySliceObject; +#endif + +PyAPI_DATA(PyTypeObject) PySlice_Type; +PyAPI_DATA(PyTypeObject) PyEllipsis_Type; + +#define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) + +PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, + PyObject* step); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop); +PyAPI_FUNC(int) _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, + PyObject **start_ptr, PyObject **stop_ptr, + PyObject **step_ptr); +#endif +PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +Py_DEPRECATED(3.7) +PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t *step, + Py_ssize_t *slicelength); + +#if !defined(Py_LIMITED_API) || (Py_LIMITED_API+0 >= 0x03050400 && Py_LIMITED_API+0 < 0x03060000) || Py_LIMITED_API+0 >= 0x03060100 +#define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \ + PySlice_Unpack((slice), (start), (stop), (step)) < 0 ? \ + ((*(slicelen) = 0), -1) : \ + ((*(slicelen) = PySlice_AdjustIndices((length), (start), (stop), *(step))), \ + 0)) +PyAPI_FUNC(int) PySlice_Unpack(PyObject *slice, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +PyAPI_FUNC(Py_ssize_t) PySlice_AdjustIndices(Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t step); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SLICEOBJECT_H */ diff --git a/python/include/structmember.h b/python/include/structmember.h new file mode 100755 index 0000000..b54f708 --- /dev/null +++ b/python/include/structmember.h @@ -0,0 +1,74 @@ +#ifndef Py_STRUCTMEMBER_H +#define Py_STRUCTMEMBER_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to map C struct members to Python object attributes */ + +#include /* For offsetof */ + +/* An array of PyMemberDef structures defines the name, type and offset + of selected members of a C structure. These can be read by + PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY + flag is set). The array must be terminated with an entry whose name + pointer is NULL. */ + +typedef struct PyMemberDef { + const char *name; + int type; + Py_ssize_t offset; + int flags; + const char *doc; +} PyMemberDef; + +/* Types */ +#define T_SHORT 0 +#define T_INT 1 +#define T_LONG 2 +#define T_FLOAT 3 +#define T_DOUBLE 4 +#define T_STRING 5 +#define T_OBJECT 6 +/* XXX the ordering here is weird for binary compatibility */ +#define T_CHAR 7 /* 1-character string */ +#define T_BYTE 8 /* 8-bit signed int */ +/* unsigned variants: */ +#define T_UBYTE 9 +#define T_USHORT 10 +#define T_UINT 11 +#define T_ULONG 12 + +/* Added by Jack: strings contained in the structure */ +#define T_STRING_INPLACE 13 + +/* Added by Lillo: bools contained in the structure (assumed char) */ +#define T_BOOL 14 + +#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError + when the value is NULL, instead of + converting to None. */ +#define T_LONGLONG 17 +#define T_ULONGLONG 18 + +#define T_PYSSIZET 19 /* Py_ssize_t */ +#define T_NONE 20 /* Value is always None */ + + +/* Flags */ +#define READONLY 1 +#define READ_RESTRICTED 2 +#define PY_WRITE_RESTRICTED 4 +#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED) + + +/* Current API, use this */ +PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *); +PyAPI_FUNC(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTMEMBER_H */ diff --git a/python/include/structseq.h b/python/include/structseq.h new file mode 100755 index 0000000..e5e5d5c --- /dev/null +++ b/python/include/structseq.h @@ -0,0 +1,49 @@ + +/* Named tuple object interface */ + +#ifndef Py_STRUCTSEQ_H +#define Py_STRUCTSEQ_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PyStructSequence_Field { + const char *name; + const char *doc; +} PyStructSequence_Field; + +typedef struct PyStructSequence_Desc { + const char *name; + const char *doc; + struct PyStructSequence_Field *fields; + int n_in_sequence; +} PyStructSequence_Desc; + +extern char* PyStructSequence_UnnamedField; + +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, + PyStructSequence_Desc *desc); +PyAPI_FUNC(int) PyStructSequence_InitType2(PyTypeObject *type, + PyStructSequence_Desc *desc); +#endif +PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc); + +PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); + +#ifndef Py_LIMITED_API +typedef PyTupleObject PyStructSequence; + +/* Macro, *only* to be used to fill in brand new objects */ +#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) + +#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) +#endif + +PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*); +PyAPI_FUNC(PyObject*) PyStructSequence_GetItem(PyObject*, Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTSEQ_H */ diff --git a/python/include/symtable.h b/python/include/symtable.h new file mode 100755 index 0000000..5dcfa7e --- /dev/null +++ b/python/include/symtable.h @@ -0,0 +1,123 @@ +#ifndef Py_LIMITED_API +#ifndef Py_SYMTABLE_H +#define Py_SYMTABLE_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "Python-ast.h" /* mod_ty */ + +/* XXX(ncoghlan): This is a weird mix of public names and interpreter internal + * names. + */ + +typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock } + _Py_block_ty; + +struct _symtable_entry; + +struct symtable { + PyObject *st_filename; /* name of file being compiled, + decoded from the filesystem encoding */ + struct _symtable_entry *st_cur; /* current symbol table entry */ + struct _symtable_entry *st_top; /* symbol table entry for module */ + PyObject *st_blocks; /* dict: map AST node addresses + * to symbol table entries */ + PyObject *st_stack; /* list: stack of namespace info */ + PyObject *st_global; /* borrowed ref to st_top->ste_symbols */ + int st_nblocks; /* number of blocks used. kept for + consistency with the corresponding + compiler structure */ + PyObject *st_private; /* name of current class or NULL */ + PyFutureFeatures *st_future; /* module's future features that affect + the symbol table */ + int recursion_depth; /* current recursion depth */ + int recursion_limit; /* recursion limit */ +}; + +typedef struct _symtable_entry { + PyObject_HEAD + PyObject *ste_id; /* int: key in ste_table->st_blocks */ + PyObject *ste_symbols; /* dict: variable names to flags */ + PyObject *ste_name; /* string: name of current block */ + PyObject *ste_varnames; /* list of function parameters */ + PyObject *ste_children; /* list of child blocks */ + PyObject *ste_directives;/* locations of global and nonlocal statements */ + _Py_block_ty ste_type; /* module, class, or function */ + int ste_nested; /* true if block is nested */ + unsigned ste_free : 1; /* true if block has free variables */ + unsigned ste_child_free : 1; /* true if a child block has free vars, + including free refs to globals */ + unsigned ste_generator : 1; /* true if namespace is a generator */ + unsigned ste_coroutine : 1; /* true if namespace is a coroutine */ + unsigned ste_comprehension : 1; /* true if namespace is a list comprehension */ + unsigned ste_varargs : 1; /* true if block has varargs */ + unsigned ste_varkeywords : 1; /* true if block has varkeywords */ + unsigned ste_returns_value : 1; /* true if namespace uses return with + an argument */ + unsigned ste_needs_class_closure : 1; /* for class scopes, true if a + closure over __class__ + should be created */ + unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */ + int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */ + int ste_lineno; /* first line of block */ + int ste_col_offset; /* offset of first line of block */ + int ste_opt_lineno; /* lineno of last exec or import * */ + int ste_opt_col_offset; /* offset of last exec or import * */ + struct symtable *ste_table; +} PySTEntryObject; + +PyAPI_DATA(PyTypeObject) PySTEntry_Type; + +#define PySTEntry_Check(op) (Py_TYPE(op) == &PySTEntry_Type) + +PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *); + +PyAPI_FUNC(struct symtable *) PySymtable_Build( + mod_ty mod, + const char *filename, /* decoded from the filesystem encoding */ + PyFutureFeatures *future); +PyAPI_FUNC(struct symtable *) PySymtable_BuildObject( + mod_ty mod, + PyObject *filename, + PyFutureFeatures *future); +PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); + +PyAPI_FUNC(void) PySymtable_Free(struct symtable *); + +/* Flags for def-use information */ + +#define DEF_GLOBAL 1 /* global stmt */ +#define DEF_LOCAL 2 /* assignment in code block */ +#define DEF_PARAM 2<<1 /* formal parameter */ +#define DEF_NONLOCAL 2<<2 /* nonlocal stmt */ +#define USE 2<<3 /* name is used */ +#define DEF_FREE 2<<4 /* name used but not defined in nested block */ +#define DEF_FREE_CLASS 2<<5 /* free variable from class's method */ +#define DEF_IMPORT 2<<6 /* assignment occurred via import */ +#define DEF_ANNOT 2<<7 /* this name is annotated */ +#define DEF_COMP_ITER 2<<8 /* this name is a comprehension iteration variable */ + +#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) + +/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol + table. GLOBAL is returned from PyST_GetScope() for either of them. + It is stored in ste_symbols at bits 12-15. +*/ +#define SCOPE_OFFSET 11 +#define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL) + +#define LOCAL 1 +#define GLOBAL_EXPLICIT 2 +#define GLOBAL_IMPLICIT 3 +#define FREE 4 +#define CELL 5 + +#define GENERATOR 1 +#define GENERATOR_EXPRESSION 2 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYMTABLE_H */ +#endif /* !Py_LIMITED_API */ diff --git a/python/include/sysmodule.h b/python/include/sysmodule.h new file mode 100755 index 0000000..670e5d2 --- /dev/null +++ b/python/include/sysmodule.h @@ -0,0 +1,41 @@ + +/* System module interface */ + +#ifndef Py_SYSMODULE_H +#define Py_SYSMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); +PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); + +PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); +PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); +PyAPI_FUNC(void) PySys_SetPath(const wchar_t *); + +PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...); +PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...); + +PyAPI_FUNC(void) PySys_ResetWarnOptions(void); +PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *); +PyAPI_FUNC(void) PySys_AddWarnOptionUnicode(PyObject *); +PyAPI_FUNC(int) PySys_HasWarnOptions(void); + +PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *); +PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_SYSMODULE_H +# include "cpython/sysmodule.h" +# undef Py_CPYTHON_SYSMODULE_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYSMODULE_H */ diff --git a/python/include/token.h b/python/include/token.h new file mode 100755 index 0000000..e08708b --- /dev/null +++ b/python/include/token.h @@ -0,0 +1,92 @@ +/* Auto-generated by Tools/scripts/generate_token.py */ + +/* Token types */ +#ifndef Py_LIMITED_API +#ifndef Py_TOKEN_H +#define Py_TOKEN_H +#ifdef __cplusplus +extern "C" { +#endif + +#undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ + +#define ENDMARKER 0 +#define NAME 1 +#define NUMBER 2 +#define STRING 3 +#define NEWLINE 4 +#define INDENT 5 +#define DEDENT 6 +#define LPAR 7 +#define RPAR 8 +#define LSQB 9 +#define RSQB 10 +#define COLON 11 +#define COMMA 12 +#define SEMI 13 +#define PLUS 14 +#define MINUS 15 +#define STAR 16 +#define SLASH 17 +#define VBAR 18 +#define AMPER 19 +#define LESS 20 +#define GREATER 21 +#define EQUAL 22 +#define DOT 23 +#define PERCENT 24 +#define LBRACE 25 +#define RBRACE 26 +#define EQEQUAL 27 +#define NOTEQUAL 28 +#define LESSEQUAL 29 +#define GREATEREQUAL 30 +#define TILDE 31 +#define CIRCUMFLEX 32 +#define LEFTSHIFT 33 +#define RIGHTSHIFT 34 +#define DOUBLESTAR 35 +#define PLUSEQUAL 36 +#define MINEQUAL 37 +#define STAREQUAL 38 +#define SLASHEQUAL 39 +#define PERCENTEQUAL 40 +#define AMPEREQUAL 41 +#define VBAREQUAL 42 +#define CIRCUMFLEXEQUAL 43 +#define LEFTSHIFTEQUAL 44 +#define RIGHTSHIFTEQUAL 45 +#define DOUBLESTAREQUAL 46 +#define DOUBLESLASH 47 +#define DOUBLESLASHEQUAL 48 +#define AT 49 +#define ATEQUAL 50 +#define RARROW 51 +#define ELLIPSIS 52 +#define COLONEQUAL 53 +#define OP 54 +#define AWAIT 55 +#define ASYNC 56 +#define TYPE_IGNORE 57 +#define TYPE_COMMENT 58 +#define ERRORTOKEN 59 +#define N_TOKENS 63 +#define NT_OFFSET 256 + +/* Special definitions for cooperation with parser */ + +#define ISTERMINAL(x) ((x) < NT_OFFSET) +#define ISNONTERMINAL(x) ((x) >= NT_OFFSET) +#define ISEOF(x) ((x) == ENDMARKER) + + +PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ +PyAPI_FUNC(int) PyToken_OneChar(int); +PyAPI_FUNC(int) PyToken_TwoChars(int, int); +PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TOKEN_H */ +#endif /* Py_LIMITED_API */ diff --git a/python/include/traceback.h b/python/include/traceback.h new file mode 100755 index 0000000..b451927 --- /dev/null +++ b/python/include/traceback.h @@ -0,0 +1,28 @@ +#ifndef Py_TRACEBACK_H +#define Py_TRACEBACK_H +#ifdef __cplusplus +extern "C" { +#endif + +struct _frame; + +/* Traceback interface */ + +PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); +PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); + +/* Reveal traceback type so we can typecheck traceback objects */ +PyAPI_DATA(PyTypeObject) PyTraceBack_Type; +#define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type) + + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_TRACEBACK_H +# include "cpython/traceback.h" +# undef Py_CPYTHON_TRACEBACK_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TRACEBACK_H */ diff --git a/python/include/tracemalloc.h b/python/include/tracemalloc.h new file mode 100755 index 0000000..bd14217 --- /dev/null +++ b/python/include/tracemalloc.h @@ -0,0 +1,38 @@ +#ifndef Py_TRACEMALLOC_H +#define Py_TRACEMALLOC_H + +#ifndef Py_LIMITED_API +/* Track an allocated memory block in the tracemalloc module. + Return 0 on success, return -1 on error (failed to allocate memory to store + the trace). + + Return -2 if tracemalloc is disabled. + + If memory block is already tracked, update the existing trace. */ +PyAPI_FUNC(int) PyTraceMalloc_Track( + unsigned int domain, + uintptr_t ptr, + size_t size); + +/* Untrack an allocated memory block in the tracemalloc module. + Do nothing if the block was not tracked. + + Return -2 if tracemalloc is disabled, otherwise return 0. */ +PyAPI_FUNC(int) PyTraceMalloc_Untrack( + unsigned int domain, + uintptr_t ptr); + +/* Get the traceback where a memory block was allocated. + + Return a tuple of (filename: str, lineno: int) tuples. + + Return None if the tracemalloc module is disabled or if the memory block + is not tracked by tracemalloc. + + Raise an exception and return NULL on error. */ +PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback( + unsigned int domain, + uintptr_t ptr); +#endif + +#endif /* !Py_TRACEMALLOC_H */ diff --git a/python/include/tupleobject.h b/python/include/tupleobject.h new file mode 100755 index 0000000..590902d --- /dev/null +++ b/python/include/tupleobject.h @@ -0,0 +1,48 @@ +/* Tuple object interface */ + +#ifndef Py_TUPLEOBJECT_H +#define Py_TUPLEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* +Another generally useful object type is a tuple of object pointers. +For Python, this is an immutable type. C code can change the tuple items +(but not their number), and even use tuples as general-purpose arrays of +object references, but in general only brand new tuples should be mutated, +not ones that might already have been exposed to Python code. + +*** WARNING *** PyTuple_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the tuple. Similarly, PyTuple_GetItem does not increment the +returned item's reference count. +*/ + +PyAPI_DATA(PyTypeObject) PyTuple_Type; +PyAPI_DATA(PyTypeObject) PyTupleIter_Type; + +#define PyTuple_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) +#define PyTuple_CheckExact(op) (Py_TYPE(op) == &PyTuple_Type) + +PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); + +PyAPI_FUNC(int) PyTuple_ClearFreeList(void); + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_TUPLEOBJECT_H +# include "cpython/tupleobject.h" +# undef Py_CPYTHON_TUPLEOBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ diff --git a/python/include/typeslots.h b/python/include/typeslots.h new file mode 100755 index 0000000..0ce6a37 --- /dev/null +++ b/python/include/typeslots.h @@ -0,0 +1,85 @@ +/* Do not renumber the file; these numbers are part of the stable ABI. */ +/* Disabled, see #10181 */ +#undef Py_bf_getbuffer +#undef Py_bf_releasebuffer +#define Py_mp_ass_subscript 3 +#define Py_mp_length 4 +#define Py_mp_subscript 5 +#define Py_nb_absolute 6 +#define Py_nb_add 7 +#define Py_nb_and 8 +#define Py_nb_bool 9 +#define Py_nb_divmod 10 +#define Py_nb_float 11 +#define Py_nb_floor_divide 12 +#define Py_nb_index 13 +#define Py_nb_inplace_add 14 +#define Py_nb_inplace_and 15 +#define Py_nb_inplace_floor_divide 16 +#define Py_nb_inplace_lshift 17 +#define Py_nb_inplace_multiply 18 +#define Py_nb_inplace_or 19 +#define Py_nb_inplace_power 20 +#define Py_nb_inplace_remainder 21 +#define Py_nb_inplace_rshift 22 +#define Py_nb_inplace_subtract 23 +#define Py_nb_inplace_true_divide 24 +#define Py_nb_inplace_xor 25 +#define Py_nb_int 26 +#define Py_nb_invert 27 +#define Py_nb_lshift 28 +#define Py_nb_multiply 29 +#define Py_nb_negative 30 +#define Py_nb_or 31 +#define Py_nb_positive 32 +#define Py_nb_power 33 +#define Py_nb_remainder 34 +#define Py_nb_rshift 35 +#define Py_nb_subtract 36 +#define Py_nb_true_divide 37 +#define Py_nb_xor 38 +#define Py_sq_ass_item 39 +#define Py_sq_concat 40 +#define Py_sq_contains 41 +#define Py_sq_inplace_concat 42 +#define Py_sq_inplace_repeat 43 +#define Py_sq_item 44 +#define Py_sq_length 45 +#define Py_sq_repeat 46 +#define Py_tp_alloc 47 +#define Py_tp_base 48 +#define Py_tp_bases 49 +#define Py_tp_call 50 +#define Py_tp_clear 51 +#define Py_tp_dealloc 52 +#define Py_tp_del 53 +#define Py_tp_descr_get 54 +#define Py_tp_descr_set 55 +#define Py_tp_doc 56 +#define Py_tp_getattr 57 +#define Py_tp_getattro 58 +#define Py_tp_hash 59 +#define Py_tp_init 60 +#define Py_tp_is_gc 61 +#define Py_tp_iter 62 +#define Py_tp_iternext 63 +#define Py_tp_methods 64 +#define Py_tp_new 65 +#define Py_tp_repr 66 +#define Py_tp_richcompare 67 +#define Py_tp_setattr 68 +#define Py_tp_setattro 69 +#define Py_tp_str 70 +#define Py_tp_traverse 71 +#define Py_tp_members 72 +#define Py_tp_getset 73 +#define Py_tp_free 74 +#define Py_nb_matrix_multiply 75 +#define Py_nb_inplace_matrix_multiply 76 +#define Py_am_await 77 +#define Py_am_aiter 78 +#define Py_am_anext 79 +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +/* New in 3.5 */ +#define Py_tp_finalize 80 +#endif diff --git a/python/include/ucnhash.h b/python/include/ucnhash.h new file mode 100755 index 0000000..45362e9 --- /dev/null +++ b/python/include/ucnhash.h @@ -0,0 +1,36 @@ +/* Unicode name database interface */ +#ifndef Py_LIMITED_API +#ifndef Py_UCNHASH_H +#define Py_UCNHASH_H +#ifdef __cplusplus +extern "C" { +#endif + +/* revised ucnhash CAPI interface (exported through a "wrapper") */ + +#define PyUnicodeData_CAPSULE_NAME "unicodedata.ucnhash_CAPI" + +typedef struct { + + /* Size of this struct */ + int size; + + /* Get name for a given character code. Returns non-zero if + success, zero if not. Does not set Python exceptions. + If self is NULL, data come from the default version of the database. + If it is not NULL, it should be a unicodedata.ucd_X_Y_Z object */ + int (*getname)(PyObject *self, Py_UCS4 code, char* buffer, int buflen, + int with_alias_and_seq); + + /* Get character code for a given name. Same error handling + as for getname. */ + int (*getcode)(PyObject *self, const char* name, int namelen, Py_UCS4* code, + int with_named_seq); + +} _PyUnicode_Name_CAPI; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_UCNHASH_H */ +#endif /* !Py_LIMITED_API */ diff --git a/python/include/unicodeobject.h b/python/include/unicodeobject.h new file mode 100755 index 0000000..97d8cd1 --- /dev/null +++ b/python/include/unicodeobject.h @@ -0,0 +1,1044 @@ +#ifndef Py_UNICODEOBJECT_H +#define Py_UNICODEOBJECT_H + +#include + +/* + +Unicode implementation based on original code by Fredrik Lundh, +modified by Marc-Andre Lemburg (mal@lemburg.com) according to the +Unicode Integration Proposal. (See +http://www.egenix.com/files/python/unicode-proposal.txt). + +Copyright (c) Corporation for National Research Initiatives. + + + Original header: + -------------------------------------------------------------------- + + * Yet another Unicode string type for Python. This type supports the + * 16-bit Basic Multilingual Plane (BMP) only. + * + * Written by Fredrik Lundh, January 1999. + * + * Copyright (c) 1999 by Secret Labs AB. + * Copyright (c) 1999 by Fredrik Lundh. + * + * fredrik@pythonware.com + * http://www.pythonware.com + * + * -------------------------------------------------------------------- + * This Unicode String Type is + * + * Copyright (c) 1999 by Secret Labs AB + * Copyright (c) 1999 by Fredrik Lundh + * + * By obtaining, using, and/or copying this software and/or its + * associated documentation, you agree that you have read, understood, + * and will comply with the following terms and conditions: + * + * Permission to use, copy, modify, and distribute this software and its + * associated documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appears in all + * copies, and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of Secret Labs + * AB or the author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. + * + * SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * -------------------------------------------------------------------- */ + +#include + +/* === Internal API ======================================================= */ + +/* --- Internal Unicode Format -------------------------------------------- */ + +/* Python 3.x requires unicode */ +#define Py_USING_UNICODE + +#ifndef SIZEOF_WCHAR_T +#error Must define SIZEOF_WCHAR_T +#endif + +#define Py_UNICODE_SIZE SIZEOF_WCHAR_T + +/* If wchar_t can be used for UCS-4 storage, set Py_UNICODE_WIDE. + Otherwise, Unicode strings are stored as UCS-2 (with limited support + for UTF-16) */ + +#if Py_UNICODE_SIZE >= 4 +#define Py_UNICODE_WIDE +#endif + +/* Set these flags if the platform has "wchar.h" and the + wchar_t type is a 16-bit unsigned type */ +/* #define HAVE_WCHAR_H */ +/* #define HAVE_USABLE_WCHAR_T */ + +/* If the compiler provides a wchar_t type we try to support it + through the interface functions PyUnicode_FromWideChar(), + PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(). */ + +#ifdef HAVE_USABLE_WCHAR_T +# ifndef HAVE_WCHAR_H +# define HAVE_WCHAR_H +# endif +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +/* Py_UCS4 and Py_UCS2 are typedefs for the respective + unicode representations. */ +typedef uint32_t Py_UCS4; +typedef uint16_t Py_UCS2; +typedef uint8_t Py_UCS1; + +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_DATA(PyTypeObject) PyUnicode_Type; +PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; + +#define PyUnicode_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) +#define PyUnicode_CheckExact(op) (Py_TYPE(op) == &PyUnicode_Type) + +/* --- Constants ---------------------------------------------------------- */ + +/* This Unicode character will be used as replacement character during + decoding if the errors argument is set to "replace". Note: the + Unicode character U+FFFD is the official REPLACEMENT CHARACTER in + Unicode 3.0. */ + +#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UCS4) 0xFFFD) + +/* === Public API ========================================================= */ + +/* Similar to PyUnicode_FromUnicode(), but u points to UTF-8 encoded bytes */ +PyAPI_FUNC(PyObject*) PyUnicode_FromStringAndSize( + const char *u, /* UTF-8 encoded string */ + Py_ssize_t size /* size of buffer */ + ); + +/* Similar to PyUnicode_FromUnicode(), but u points to null-terminated + UTF-8 encoded bytes. The size is determined with strlen(). */ +PyAPI_FUNC(PyObject*) PyUnicode_FromString( + const char *u /* UTF-8 encoded string */ + ); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyUnicode_Substring( + PyObject *str, + Py_ssize_t start, + Py_ssize_t end); +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Copy the string into a UCS4 buffer including the null character if copy_null + is set. Return NULL and raise an exception on error. Raise a SystemError if + the buffer is smaller than the string. Return buffer on success. + + buflen is the length of the buffer in (Py_UCS4) characters. */ +PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4( + PyObject *unicode, + Py_UCS4* buffer, + Py_ssize_t buflen, + int copy_null); + +/* Copy the string into a UCS4 buffer. A new buffer is allocated using + * PyMem_Malloc; if this fails, NULL is returned with a memory error + exception set. */ +PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4Copy(PyObject *unicode); +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Get the length of the Unicode object. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetLength( + PyObject *unicode +); +#endif + +/* Get the number of Py_UNICODE units in the + string representation. */ + +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( + PyObject *unicode /* Unicode object */ + ); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Read a character from the string. */ + +PyAPI_FUNC(Py_UCS4) PyUnicode_ReadChar( + PyObject *unicode, + Py_ssize_t index + ); + +/* Write a character to the string. The string must have been created through + PyUnicode_New, must not be shared, and must not have been hashed yet. + + Return 0 on success, -1 on error. */ + +PyAPI_FUNC(int) PyUnicode_WriteChar( + PyObject *unicode, + Py_ssize_t index, + Py_UCS4 character + ); +#endif + +/* Resize a Unicode object. The length is the number of characters, except + if the kind of the string is PyUnicode_WCHAR_KIND: in this case, the length + is the number of Py_UNICODE characters. + + *unicode is modified to point to the new (resized) object and 0 + returned on success. + + Try to resize the string in place (which is usually faster than allocating + a new string and copy characters), or create a new string. + + Error handling is implemented as follows: an exception is set, -1 + is returned and *unicode left untouched. + + WARNING: The function doesn't check string content, the result may not be a + string in canonical representation. */ + +PyAPI_FUNC(int) PyUnicode_Resize( + PyObject **unicode, /* Pointer to the Unicode object */ + Py_ssize_t length /* New length */ + ); + +/* Decode obj to a Unicode object. + + bytes, bytearray and other bytes-like objects are decoded according to the + given encoding and error handler. The encoding and error handler can be + NULL to have the interface use UTF-8 and "strict". + + All other objects (including Unicode objects) raise an exception. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromEncodedObject( + PyObject *obj, /* Object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Copy an instance of a Unicode subtype to a new true Unicode object if + necessary. If obj is already a true Unicode object (not a subtype), return + the reference with *incremented* refcount. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromObject( + PyObject *obj /* Object */ + ); + +PyAPI_FUNC(PyObject *) PyUnicode_FromFormatV( + const char *format, /* ASCII-encoded string */ + va_list vargs + ); +PyAPI_FUNC(PyObject *) PyUnicode_FromFormat( + const char *format, /* ASCII-encoded string */ + ... + ); + +PyAPI_FUNC(void) PyUnicode_InternInPlace(PyObject **); +PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); +PyAPI_FUNC(PyObject *) PyUnicode_InternFromString( + const char *u /* UTF-8 encoded string */ + ); + +/* Use only if you know it's a string */ +#define PyUnicode_CHECK_INTERNED(op) \ + (((PyASCIIObject *)(op))->state.interned) + +/* --- wchar_t support for platforms which support it --------------------- */ + +#ifdef HAVE_WCHAR_H + +/* Create a Unicode Object from the wchar_t buffer w of the given + size. + + The buffer is copied into the new object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_FromWideChar( + const wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Copies the Unicode Object contents into the wchar_t buffer w. At + most size wchar_t characters are copied. + + Note that the resulting wchar_t string may or may not be + 0-terminated. It is the responsibility of the caller to make sure + that the wchar_t string is 0-terminated in case this is required by + the application. + + Returns the number of wchar_t characters copied (excluding a + possibly trailing 0-termination character) or -1 in case of an + error. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( + PyObject *unicode, /* Unicode object */ + wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Convert the Unicode object to a wide character string. The output string + always ends with a nul character. If size is not NULL, write the number of + wide characters (excluding the null character) into *size. + + Returns a buffer allocated by PyMem_Malloc() (use PyMem_Free() to free it) + on success. On error, returns NULL, *size is undefined and raises a + MemoryError. */ + +PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString( + PyObject *unicode, /* Unicode object */ + Py_ssize_t *size /* number of characters of the result */ + ); + +#endif + +/* --- Unicode ordinals --------------------------------------------------- */ + +/* Create a Unicode Object from the given Unicode code point ordinal. + + The ordinal must be in range(0x110000). A ValueError is + raised in case it is not. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal); + +/* --- Free-list management ----------------------------------------------- */ + +/* Clear the free list used by the Unicode implementation. + + This can be used to release memory used for objects on the free + list back to the Python memory allocator. + +*/ + +PyAPI_FUNC(int) PyUnicode_ClearFreeList(void); + +/* === Builtin Codecs ===================================================== + + Many of these APIs take two arguments encoding and errors. These + parameters encoding and errors have the same semantics as the ones + of the builtin str() API. + + Setting encoding to NULL causes the default encoding (UTF-8) to be used. + + Error handling is set by errors which may also be set to NULL + meaning to use the default handling defined for the codec. Default + error handling for all builtin codecs is "strict" (ValueErrors are + raised). + + The codecs all use a similar interface. Only deviation from the + generic ones are documented. + +*/ + +/* --- Manage the default encoding ---------------------------------------- */ + +/* Returns "utf-8". */ +PyAPI_FUNC(const char*) PyUnicode_GetDefaultEncoding(void); + +/* --- Generic Codecs ----------------------------------------------------- */ + +/* Create a Unicode object by decoding the encoded string s of the + given size. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Decode( + const char *s, /* encoded string */ + Py_ssize_t size, /* size of buffer */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Decode a Unicode object unicode and return the result as Python + object. + + This API is DEPRECATED. The only supported standard encoding is rot13. + Use PyCodec_Decode() to decode with rot13 and non-standard codecs + that decode from str. */ + +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedObject( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Decode a Unicode object unicode and return the result as Unicode + object. + + This API is DEPRECATED. The only supported standard encoding is rot13. + Use PyCodec_Decode() to decode with rot13 and non-standard codecs + that decode from str to str. */ + +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedUnicode( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Python + object. + + This API is DEPRECATED. It is superseded by PyUnicode_AsEncodedString() + since all standard encodings (except rot13) encode str to bytes. + Use PyCodec_Encode() for encoding with rot13 and non-standard codecs + that encode form str to non-bytes. */ + +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Python string + object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedString( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Unicode + object. + + This API is DEPRECATED. The only supported standard encodings is rot13. + Use PyCodec_Encode() to encode with rot13 and non-standard codecs + that encode from str to str. */ + +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedUnicode( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Build an encoding map. */ + +PyAPI_FUNC(PyObject*) PyUnicode_BuildEncodingMap( + PyObject* string /* 256 character map */ + ); + +/* --- UTF-7 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7( + const char *string, /* UTF-7 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7Stateful( + const char *string, /* UTF-7 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* --- UTF-8 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8Stateful( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String( + PyObject *unicode /* Unicode object */ + ); + +/* --- UTF-32 Codecs ------------------------------------------------------ */ + +/* Decodes length bytes from a UTF-32 encoded buffer string and returns + the corresponding Unicode object. + + errors (if non-NULL) defines the error handling. It defaults + to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the + given byte order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + In native mode, the first four bytes of the stream are checked for a + BOM mark. If found, the BOM mark is analysed, the byte order + adjusted and the BOM skipped. In the other modes, no BOM mark + interpretation is done. After completion, *byteorder is set to the + current byte order at the end of input data. + + If byteorder is NULL, the codec starts in native order mode. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32( + const char *string, /* UTF-32 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32Stateful( + const char *string, /* UTF-32 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* Returns a Python string using the UTF-32 encoding in native byte + order. The string always starts with a BOM mark. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF32String( + PyObject *unicode /* Unicode object */ + ); + +/* Returns a Python string object holding the UTF-32 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. + +*/ + +/* --- UTF-16 Codecs ------------------------------------------------------ */ + +/* Decodes length bytes from a UTF-16 encoded buffer string and returns + the corresponding Unicode object. + + errors (if non-NULL) defines the error handling. It defaults + to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the + given byte order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + In native mode, the first two bytes of the stream are checked for a + BOM mark. If found, the BOM mark is analysed, the byte order + adjusted and the BOM skipped. In the other modes, no BOM mark + interpretation is done. After completion, *byteorder is set to the + current byte order at the end of input data. + + If byteorder is NULL, the codec starts in native order mode. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16Stateful( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* Returns a Python string using the UTF-16 encoding in native byte + order. The string always starts with a BOM mark. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF16String( + PyObject *unicode /* Unicode object */ + ); + +/* --- Unicode-Escape Codecs ---------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUnicodeEscape( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +/* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeRawUnicodeEscape( + const char *string, /* Raw-Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsRawUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +/* --- Latin-1 Codecs ----------------------------------------------------- + + Note: Latin-1 corresponds to the first 256 Unicode ordinals. */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLatin1( + const char *string, /* Latin-1 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsLatin1String( + PyObject *unicode /* Unicode object */ + ); + +/* --- ASCII Codecs ------------------------------------------------------- + + Only 7-bit ASCII data is excepted. All other codes generate errors. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeASCII( + const char *string, /* ASCII encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsASCIIString( + PyObject *unicode /* Unicode object */ + ); + +/* --- Character Map Codecs ----------------------------------------------- + + This codec uses mappings to encode and decode characters. + + Decoding mappings must map byte ordinals (integers in the range from 0 to + 255) to Unicode strings, integers (which are then interpreted as Unicode + ordinals) or None. Unmapped data bytes (ones which cause a LookupError) + as well as mapped to None, 0xFFFE or '\ufffe' are treated as "undefined + mapping" and cause an error. + + Encoding mappings must map Unicode ordinal integers to bytes objects, + integers in the range from 0 to 255 or None. Unmapped character + ordinals (ones which cause a LookupError) as well as mapped to + None are treated as "undefined mapping" and cause an error. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeCharmap( + const char *string, /* Encoded string */ + Py_ssize_t length, /* size of string */ + PyObject *mapping, /* decoding mapping */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsCharmapString( + PyObject *unicode, /* Unicode object */ + PyObject *mapping /* encoding mapping */ + ); + +/* --- MBCS codecs for Windows -------------------------------------------- */ + +#ifdef MS_WINDOWS +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCS( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCSStateful( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyUnicode_DecodeCodePageStateful( + int code_page, /* code page number */ + const char *string, /* encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); +#endif + +PyAPI_FUNC(PyObject*) PyUnicode_AsMBCSString( + PyObject *unicode /* Unicode object */ + ); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +PyAPI_FUNC(PyObject*) PyUnicode_EncodeCodePage( + int code_page, /* code page number */ + PyObject *unicode, /* Unicode object */ + const char *errors /* error handling */ + ); +#endif + +#endif /* MS_WINDOWS */ + +/* --- Locale encoding --------------------------------------------------- */ + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Decode a string from the current locale encoding. The decoder is strict if + *surrogateescape* is equal to zero, otherwise it uses the 'surrogateescape' + error handler (PEP 383) to escape undecodable bytes. If a byte sequence can + be decoded as a surrogate character and *surrogateescape* is not equal to + zero, the byte sequence is escaped using the 'surrogateescape' error handler + instead of being decoded. *str* must end with a null character but cannot + contain embedded null characters. */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLocaleAndSize( + const char *str, + Py_ssize_t len, + const char *errors); + +/* Similar to PyUnicode_DecodeLocaleAndSize(), but compute the string + length using strlen(). */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLocale( + const char *str, + const char *errors); + +/* Encode a Unicode object to the current locale encoding. The encoder is + strict is *surrogateescape* is equal to zero, otherwise the + "surrogateescape" error handler is used. Return a bytes object. The string + cannot contain embedded null characters. */ + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeLocale( + PyObject *unicode, + const char *errors + ); +#endif + +/* --- File system encoding ---------------------------------------------- */ + +/* ParseTuple converter: encode str objects to bytes using + PyUnicode_EncodeFSDefault(); bytes objects are output as-is. */ + +PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); + +/* ParseTuple converter: decode bytes objects to unicode using + PyUnicode_DecodeFSDefaultAndSize(); str objects are output as-is. */ + +PyAPI_FUNC(int) PyUnicode_FSDecoder(PyObject*, void*); + +/* Decode a null-terminated string using Py_FileSystemDefaultEncoding + and the "surrogateescape" error handler. + + If Py_FileSystemDefaultEncoding is not set, fall back to the locale + encoding. + + Use PyUnicode_DecodeFSDefaultAndSize() if the string length is known. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefault( + const char *s /* encoded string */ + ); + +/* Decode a string using Py_FileSystemDefaultEncoding + and the "surrogateescape" error handler. + + If Py_FileSystemDefaultEncoding is not set, fall back to the locale + encoding. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize( + const char *s, /* encoded string */ + Py_ssize_t size /* size */ + ); + +/* Encode a Unicode object to Py_FileSystemDefaultEncoding with the + "surrogateescape" error handler, and return bytes. + + If Py_FileSystemDefaultEncoding is not set, fall back to the locale + encoding. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeFSDefault( + PyObject *unicode + ); + +/* --- Methods & Slots ---------------------------------------------------- + + These are capable of handling Unicode objects and strings on input + (we refer to them as strings in the descriptions) and return + Unicode objects or integers as appropriate. */ + +/* Concat two strings giving a new Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Concat( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +/* Concat two strings and put the result in *pleft + (sets *pleft to NULL on error) */ + +PyAPI_FUNC(void) PyUnicode_Append( + PyObject **pleft, /* Pointer to left string */ + PyObject *right /* Right string */ + ); + +/* Concat two strings, put the result in *pleft and drop the right object + (sets *pleft to NULL on error) */ + +PyAPI_FUNC(void) PyUnicode_AppendAndDel( + PyObject **pleft, /* Pointer to left string */ + PyObject *right /* Right string */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. If negative, no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_Split( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Dito, but split at line breaks. + + CRLF is considered to be one line break. Line breaks are not + included in the resulting list. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Splitlines( + PyObject *s, /* String to split */ + int keepends /* If true, line end markers are included */ + ); + +/* Partition a string using a given separator. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Partition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Partition a string using a given separator, searching from the end of the + string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_RPartition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. But unlike PyUnicode_Split + PyUnicode_RSplit splits from the end of the string. If negative, + no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_RSplit( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Translate a string by applying a character mapping table to it and + return the resulting Unicode object. + + The mapping table must map Unicode ordinal integers to Unicode strings, + Unicode ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_Translate( + PyObject *str, /* String */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ); + +/* Join a sequence of strings using the given separator and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Join( + PyObject *separator, /* Separator string */ + PyObject *seq /* Sequence object */ + ); + +/* Return 1 if substr matches str[start:end] at the given tail end, 0 + otherwise. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Tailmatch( + PyObject *str, /* String */ + PyObject *substr, /* Prefix or Suffix string */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Tail end: -1 prefix, +1 suffix */ + ); + +/* Return the first position of substr in str[start:end] using the + given search direction or -1 if not found. -2 is returned in case + an error occurred and an exception is set. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Find( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Find direction: +1 forward, -1 backward */ + ); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 +/* Like PyUnicode_Find, but search for single character only. */ +PyAPI_FUNC(Py_ssize_t) PyUnicode_FindChar( + PyObject *str, + Py_UCS4 ch, + Py_ssize_t start, + Py_ssize_t end, + int direction + ); +#endif + +/* Count the number of occurrences of substr in str[start:end]. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Count( + PyObject *str, /* String */ + PyObject *substr, /* Substring to count */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end /* Stop index */ + ); + +/* Replace at most maxcount occurrences of substr in str with replstr + and return the resulting Unicode object. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Replace( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + PyObject *replstr, /* Substring to replace */ + Py_ssize_t maxcount /* Max. number of replacements to apply; + -1 = all */ + ); + +/* Compare two strings and return -1, 0, 1 for less than, equal, + greater than resp. + Raise an exception and return -1 on error. */ + +PyAPI_FUNC(int) PyUnicode_Compare( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +/* Compare a Unicode object with C string and return -1, 0, 1 for less than, + equal, and greater than, respectively. It is best to pass only + ASCII-encoded strings, but the function interprets the input string as + ISO-8859-1 if it contains non-ASCII characters. + This function does not raise exceptions. */ + +PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( + PyObject *left, + const char *right /* ASCII-encoded string */ + ); + +/* Rich compare two strings and return one of the following: + + - NULL in case an exception was raised + - Py_True or Py_False for successful comparisons + - Py_NotImplemented in case the type combination is unknown + + Possible values for op: + + Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_RichCompare( + PyObject *left, /* Left string */ + PyObject *right, /* Right string */ + int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ + ); + +/* Apply an argument tuple or dictionary to a format string and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Format( + PyObject *format, /* Format string */ + PyObject *args /* Argument tuple or dictionary */ + ); + +/* Checks whether element is contained in container and return 1/0 + accordingly. + + element has to coerce to a one element Unicode string. -1 is + returned in case of an error. */ + +PyAPI_FUNC(int) PyUnicode_Contains( + PyObject *container, /* Container string */ + PyObject *element /* Element string */ + ); + +/* Checks whether argument is a valid identifier. */ + +PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s); + +/* === Characters Type APIs =============================================== */ + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_UNICODEOBJECT_H +# include "cpython/unicodeobject.h" +# undef Py_CPYTHON_UNICODEOBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_UNICODEOBJECT_H */ diff --git a/python/include/warnings.h b/python/include/warnings.h new file mode 100755 index 0000000..a675bb5 --- /dev/null +++ b/python/include/warnings.h @@ -0,0 +1,67 @@ +#ifndef Py_WARNINGS_H +#define Py_WARNINGS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject*) _PyWarnings_Init(void); +#endif + +PyAPI_FUNC(int) PyErr_WarnEx( + PyObject *category, + const char *message, /* UTF-8 encoded string */ + Py_ssize_t stack_level); +PyAPI_FUNC(int) PyErr_WarnFormat( + PyObject *category, + Py_ssize_t stack_level, + const char *format, /* ASCII-encoded string */ + ...); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +/* Emit a ResourceWarning warning */ +PyAPI_FUNC(int) PyErr_ResourceWarning( + PyObject *source, + Py_ssize_t stack_level, + const char *format, /* ASCII-encoded string */ + ...); +#endif +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) PyErr_WarnExplicitObject( + PyObject *category, + PyObject *message, + PyObject *filename, + int lineno, + PyObject *module, + PyObject *registry); +#endif +PyAPI_FUNC(int) PyErr_WarnExplicit( + PyObject *category, + const char *message, /* UTF-8 encoded string */ + const char *filename, /* decoded from the filesystem encoding */ + int lineno, + const char *module, /* UTF-8 encoded string */ + PyObject *registry); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) +PyErr_WarnExplicitFormat(PyObject *category, + const char *filename, int lineno, + const char *module, PyObject *registry, + const char *format, ...); +#endif + +/* DEPRECATED: Use PyErr_WarnEx() instead. */ +#ifndef Py_LIMITED_API +#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) +#endif + +#ifndef Py_LIMITED_API +void _PyErr_WarnUnawaitedCoroutine(PyObject *coro); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_WARNINGS_H */ + diff --git a/python/include/weakrefobject.h b/python/include/weakrefobject.h new file mode 100755 index 0000000..1705156 --- /dev/null +++ b/python/include/weakrefobject.h @@ -0,0 +1,86 @@ +/* Weak references objects for Python. */ + +#ifndef Py_WEAKREFOBJECT_H +#define Py_WEAKREFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct _PyWeakReference PyWeakReference; + +/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType, + * and CallableProxyType. + */ +#ifndef Py_LIMITED_API +struct _PyWeakReference { + PyObject_HEAD + + /* The object to which this is a weak reference, or Py_None if none. + * Note that this is a stealth reference: wr_object's refcount is + * not incremented to reflect this pointer. + */ + PyObject *wr_object; + + /* A callable to invoke when wr_object dies, or NULL if none. */ + PyObject *wr_callback; + + /* A cache for wr_object's hash code. As usual for hashes, this is -1 + * if the hash code isn't known yet. + */ + Py_hash_t hash; + + /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL- + * terminated list of weak references to it. These are the list pointers. + * If wr_object goes away, wr_object is set to Py_None, and these pointers + * have no meaning then. + */ + PyWeakReference *wr_prev; + PyWeakReference *wr_next; +}; +#endif + +PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; +PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; +PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; + +#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) +#define PyWeakref_CheckRefExact(op) \ + (Py_TYPE(op) == &_PyWeakref_RefType) +#define PyWeakref_CheckProxy(op) \ + ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \ + (Py_TYPE(op) == &_PyWeakref_CallableProxyType)) + +#define PyWeakref_Check(op) \ + (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) + + +PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); + +#ifndef Py_LIMITED_API +PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); + +PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); +#endif + +/* Explanation for the Py_REFCNT() check: when a weakref's target is part + of a long chain of deallocations which triggers the trashcan mechanism, + clearing the weakrefs can be delayed long after the target's refcount + has dropped to zero. In the meantime, code accessing the weakref will + be able to "see" the target object even though it is supposed to be + unreachable. See issue #16602. */ + +#define PyWeakref_GET_OBJECT(ref) \ + (Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \ + ? ((PyWeakReference *)(ref))->wr_object \ + : Py_None) + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_WEAKREFOBJECT_H */ diff --git a/python/pyconfig.h b/python/pyconfig.h new file mode 100755 index 0000000..9d53ac6 --- /dev/null +++ b/python/pyconfig.h @@ -0,0 +1,1665 @@ +/* pyconfig.h. Generated from pyconfig.h.in by configure. */ +/* pyconfig.h.in. Generated from configure.ac by autoheader. */ + + +#ifndef Py_PYCONFIG_H +#define Py_PYCONFIG_H + + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want + support for AIX C++ shared extension modules. */ +/* #undef AIX_GENUINE_CPLUSPLUS */ + +/* Alternative SOABI used in debug build to load C extensions built in release + mode */ +/* #undef ALT_SOABI */ + +/* The Android API level. */ +/* #undef ANDROID_API_LEVEL */ + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM + mixed-endian order (byte order 45670123) */ +/* #undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 */ + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most + significant byte first */ +/* #undef DOUBLE_IS_BIG_ENDIAN_IEEE754 */ + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 + +/* Define if --enable-ipv6 is specified */ +/* #undef ENABLE_IPV6 */ + +/* Define to 1 if your system stores words within floats with the most + significant word first */ +/* #undef FLOAT_WORDS_BIGENDIAN */ + +/* Define if flock needs to be linked with bsd library. */ +/* #undef FLOCK_NEEDS_LIBBSD */ + +/* Define if getpgrp() must be called as getpgrp(0). */ +/* #undef GETPGRP_HAVE_ARG */ + +/* Define if gettimeofday() does not have second (timezone) argument This is + the case on Motorola V4 (R40V4.2) */ +/* #undef GETTIMEOFDAY_NO_TZ */ + +/* Define to 1 if you have the `accept4' function. */ +#define HAVE_ACCEPT4 1 + +/* Define to 1 if you have the `acosh' function. */ +#define HAVE_ACOSH 1 + +/* struct addrinfo (netdb.h) */ +#define HAVE_ADDRINFO 1 + +/* Define to 1 if you have the `alarm' function. */ +#define HAVE_ALARM 1 + +/* Define if aligned memory access is required */ +#define HAVE_ALIGNED_REQUIRED 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define this if your time.h defines altzone. */ +/* #undef HAVE_ALTZONE */ + +/* Define to 1 if you have the `asinh' function. */ +#define HAVE_ASINH 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ASM_TYPES_H 1 + +/* Define to 1 if you have the `atanh' function. */ +#define HAVE_ATANH 1 + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +#define HAVE_BIND_TEXTDOMAIN_CODESET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BLUETOOTH_BLUETOOTH_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BLUETOOTH_H */ + +/* Define if mbstowcs(NULL, "text", 0) does not return the number of wide + chars that would be converted. */ +/* #undef HAVE_BROKEN_MBSTOWCS */ + +/* Define if nice() returns success/failure instead of the new priority. */ +/* #undef HAVE_BROKEN_NICE */ + +/* Define if the system reports an invalid PIPE_BUF value. */ +/* #undef HAVE_BROKEN_PIPE_BUF */ + +/* Define if poll() sets errno on invalid file descriptors. */ +/* #undef HAVE_BROKEN_POLL */ + +/* Define if the Posix semaphores do not work on your system */ +/* #undef HAVE_BROKEN_POSIX_SEMAPHORES */ + +/* Define if pthread_sigmask() does not work on your system. */ +/* #undef HAVE_BROKEN_PTHREAD_SIGMASK */ + +/* define to 1 if your sem_getvalue is broken. */ +#define HAVE_BROKEN_SEM_GETVALUE 1 + +/* Define if `unsetenv` does not return an int. */ +/* #undef HAVE_BROKEN_UNSETENV */ + +/* Has builtin atomics */ +#define HAVE_BUILTIN_ATOMIC 1 + +/* Define to 1 if you have the 'chflags' function. */ +/* #undef HAVE_CHFLAGS */ + +/* Define to 1 if you have the `chown' function. */ +#define HAVE_CHOWN 1 + +/* Define if you have the 'chroot' function. */ +#define HAVE_CHROOT 1 + +/* Define to 1 if you have the `clock' function. */ +#define HAVE_CLOCK 1 + +/* Define to 1 if you have the `clock_getres' function. */ +#define HAVE_CLOCK_GETRES 1 + +/* Define to 1 if you have the `clock_gettime' function. */ +#define HAVE_CLOCK_GETTIME 1 + +/* Define to 1 if you have the `clock_settime' function. */ +#define HAVE_CLOCK_SETTIME 1 + +/* Define if the C compiler supports computed gotos. */ +/* #undef HAVE_COMPUTED_GOTOS */ + +/* Define to 1 if you have the `confstr' function. */ +#define HAVE_CONFSTR 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CONIO_H */ + +/* Define to 1 if you have the `copysign' function. */ +#define HAVE_COPYSIGN 1 + +/* Define to 1 if you have the `copy_file_range' function. */ +/* #undef HAVE_COPY_FILE_RANGE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_CRYPT_H 1 + +/* Define if you have the crypt_r() function. */ +#define HAVE_CRYPT_R 1 + +/* Define to 1 if you have the `ctermid' function. */ +#define HAVE_CTERMID 1 + +/* Define if you have the 'ctermid_r' function. */ +/* #undef HAVE_CTERMID_R */ + +/* Define if you have the 'filter' function. */ +/* #undef HAVE_CURSES_FILTER */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CURSES_H */ + +/* Define if you have the 'has_key' function. */ +/* #undef HAVE_CURSES_HAS_KEY */ + +/* Define if you have the 'immedok' function. */ +/* #undef HAVE_CURSES_IMMEDOK */ + +/* Define if you have the 'is_pad' function or macro. */ +/* #undef HAVE_CURSES_IS_PAD */ + +/* Define if you have the 'is_term_resized' function. */ +/* #undef HAVE_CURSES_IS_TERM_RESIZED */ + +/* Define if you have the 'resizeterm' function. */ +/* #undef HAVE_CURSES_RESIZETERM */ + +/* Define if you have the 'resize_term' function. */ +/* #undef HAVE_CURSES_RESIZE_TERM */ + +/* Define if you have the 'syncok' function. */ +/* #undef HAVE_CURSES_SYNCOK */ + +/* Define if you have the 'typeahead' function. */ +/* #undef HAVE_CURSES_TYPEAHEAD */ + +/* Define if you have the 'use_env' function. */ +/* #undef HAVE_CURSES_USE_ENV */ + +/* Define if you have the 'wchgat' function. */ +/* #undef HAVE_CURSES_WCHGAT */ + +/* Define to 1 if you have the declaration of `isfinite', and to 0 if you + don't. */ +#define HAVE_DECL_ISFINITE 1 + +/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. + */ +#define HAVE_DECL_ISINF 1 + +/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. + */ +#define HAVE_DECL_ISNAN 1 + +/* Define to 1 if you have the declaration of `RTLD_DEEPBIND', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_DEEPBIND 0 + +/* Define to 1 if you have the declaration of `RTLD_GLOBAL', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_GLOBAL 1 + +/* Define to 1 if you have the declaration of `RTLD_LAZY', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_LAZY 1 + +/* Define to 1 if you have the declaration of `RTLD_LOCAL', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_LOCAL 1 + +/* Define to 1 if you have the declaration of `RTLD_MEMBER', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_MEMBER 0 + +/* Define to 1 if you have the declaration of `RTLD_NODELETE', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_NODELETE 1 + +/* Define to 1 if you have the declaration of `RTLD_NOLOAD', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_NOLOAD 1 + +/* Define to 1 if you have the declaration of `RTLD_NOW', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_NOW 1 + +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. + */ +/* #undef HAVE_DECL_TZNAME */ + +/* Define to 1 if you have the device macros. */ +#define HAVE_DEVICE_MACROS 1 + +/* Define to 1 if you have the /dev/ptc device file. */ +/* #undef HAVE_DEV_PTC */ + +/* Define to 1 if you have the /dev/ptmx device file. */ +/* #undef HAVE_DEV_PTMX */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DIRECT_H */ + +/* Define to 1 if the dirent structure has a d_type field */ +#define HAVE_DIRENT_D_TYPE 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the 'dirfd' function or macro. */ +#define HAVE_DIRFD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dlopen' function. */ +#define HAVE_DLOPEN 1 + +/* Define to 1 if you have the `dup2' function. */ +#define HAVE_DUP2 1 + +/* Define to 1 if you have the `dup3' function. */ +#define HAVE_DUP3 1 + +/* Defined when any dynamic module loading is enabled. */ + #define HAVE_DYNAMIC_LOADING 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ENDIAN_H 1 + +/* Define if you have the 'epoll' functions. */ +#define HAVE_EPOLL 1 + +/* Define if you have the 'epoll_create1' function. */ +#define HAVE_EPOLL_CREATE1 1 + +/* Define to 1 if you have the `erf' function. */ +#define HAVE_ERF 1 + +/* Define to 1 if you have the `erfc' function. */ +#define HAVE_ERFC 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `execv' function. */ +#define HAVE_EXECV 1 + +/* Define to 1 if you have the `explicit_bzero' function. */ +#define HAVE_EXPLICIT_BZERO 1 + +/* Define to 1 if you have the `explicit_memset' function. */ +/* #undef HAVE_EXPLICIT_MEMSET */ + +/* Define to 1 if you have the `expm1' function. */ +#define HAVE_EXPM1 1 + +/* Define to 1 if you have the `faccessat' function. */ +#define HAVE_FACCESSAT 1 + +/* Define if you have the 'fchdir' function. */ +#define HAVE_FCHDIR 1 + +/* Define to 1 if you have the `fchmod' function. */ +#define HAVE_FCHMOD 1 + +/* Define to 1 if you have the `fchmodat' function. */ +#define HAVE_FCHMODAT 1 + +/* Define to 1 if you have the `fchown' function. */ +#define HAVE_FCHOWN 1 + +/* Define to 1 if you have the `fchownat' function. */ +#define HAVE_FCHOWNAT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the 'fdatasync' function. */ +#define HAVE_FDATASYNC 1 + +/* Define to 1 if you have the `fdopendir' function. */ +#define HAVE_FDOPENDIR 1 + +/* Define to 1 if you have the `fdwalk' function. */ +/* #undef HAVE_FDWALK */ + +/* Define to 1 if you have the `fexecve' function. */ +#define HAVE_FEXECVE 1 + +/* Define to 1 if you have the `finite' function. */ +#define HAVE_FINITE 1 + +/* Define to 1 if you have the `flock' function. */ +#define HAVE_FLOCK 1 + +/* Define to 1 if you have the `fork' function. */ +#define HAVE_FORK 1 + +/* Define to 1 if you have the `forkpty' function. */ +#define HAVE_FORKPTY 1 + +/* Define to 1 if you have the `fpathconf' function. */ +#define HAVE_FPATHCONF 1 + +/* Define to 1 if you have the `fseek64' function. */ +/* #undef HAVE_FSEEK64 */ + +/* Define to 1 if you have the `fseeko' function. */ +#define HAVE_FSEEKO 1 + +/* Define to 1 if you have the `fstatat' function. */ +#define HAVE_FSTATAT 1 + +/* Define to 1 if you have the `fstatvfs' function. */ +#define HAVE_FSTATVFS 1 + +/* Define if you have the 'fsync' function. */ +#define HAVE_FSYNC 1 + +/* Define to 1 if you have the `ftell64' function. */ +/* #undef HAVE_FTELL64 */ + +/* Define to 1 if you have the `ftello' function. */ +#define HAVE_FTELLO 1 + +/* Define to 1 if you have the `ftime' function. */ +#define HAVE_FTIME 1 + +/* Define to 1 if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE 1 + +/* Define to 1 if you have the `futimens' function. */ +#define HAVE_FUTIMENS 1 + +/* Define to 1 if you have the `futimes' function. */ +#define HAVE_FUTIMES 1 + +/* Define to 1 if you have the `futimesat' function. */ +#define HAVE_FUTIMESAT 1 + +/* Define to 1 if you have the `gai_strerror' function. */ +#define HAVE_GAI_STRERROR 1 + +/* Define to 1 if you have the `gamma' function. */ +#define HAVE_GAMMA 1 + +/* Define if we can use gcc inline assembler to get and set mc68881 fpcr */ +/* #undef HAVE_GCC_ASM_FOR_MC68881 */ + +/* Define if we can use x64 gcc inline assembler */ +/* #undef HAVE_GCC_ASM_FOR_X64 */ + +/* Define if we can use gcc inline assembler to get and set x87 control word + */ +/* #undef HAVE_GCC_ASM_FOR_X87 */ + +/* Define if your compiler provides __uint128_t */ +/* #undef HAVE_GCC_UINT128_T */ + +/* Define if you have the getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ +#define HAVE_GETC_UNLOCKED 1 + +/* Define to 1 if you have the `getentropy' function. */ +#define HAVE_GETENTROPY 1 + +/* Define to 1 if you have the `getgrgid_r' function. */ +#define HAVE_GETGRGID_R 1 + +/* Define to 1 if you have the `getgrnam_r' function. */ +#define HAVE_GETGRNAM_R 1 + +/* Define to 1 if you have the `getgrouplist' function. */ +#define HAVE_GETGROUPLIST 1 + +/* Define to 1 if you have the `getgroups' function. */ +#define HAVE_GETGROUPS 1 + +/* Define to 1 if you have the `gethostbyname' function. */ +/* #undef HAVE_GETHOSTBYNAME */ + +/* Define this if you have some version of gethostbyname_r() */ +#define HAVE_GETHOSTBYNAME_R 1 + +/* Define this if you have the 3-arg version of gethostbyname_r(). */ +/* #undef HAVE_GETHOSTBYNAME_R_3_ARG */ + +/* Define this if you have the 5-arg version of gethostbyname_r(). */ +/* #undef HAVE_GETHOSTBYNAME_R_5_ARG */ + +/* Define this if you have the 6-arg version of gethostbyname_r(). */ +#define HAVE_GETHOSTBYNAME_R_6_ARG 1 + +/* Define to 1 if you have the `getitimer' function. */ +#define HAVE_GETITIMER 1 + +/* Define to 1 if you have the `getloadavg' function. */ +#define HAVE_GETLOADAVG 1 + +/* Define to 1 if you have the `getlogin' function. */ +#define HAVE_GETLOGIN 1 + +/* Define to 1 if you have the `getnameinfo' function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define if you have the 'getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the `getpeername' function. */ +#define HAVE_GETPEERNAME 1 + +/* Define to 1 if you have the `getpgid' function. */ +#define HAVE_GETPGID 1 + +/* Define to 1 if you have the `getpgrp' function. */ +#define HAVE_GETPGRP 1 + +/* Define to 1 if you have the `getpid' function. */ +#define HAVE_GETPID 1 + +/* Define to 1 if you have the `getpriority' function. */ +#define HAVE_GETPRIORITY 1 + +/* Define to 1 if you have the `getpwent' function. */ +#define HAVE_GETPWENT 1 + +/* Define to 1 if you have the `getpwnam_r' function. */ +#define HAVE_GETPWNAM_R 1 + +/* Define to 1 if you have the `getpwuid_r' function. */ +#define HAVE_GETPWUID_R 1 + +/* Define to 1 if the getrandom() function is available */ +#define HAVE_GETRANDOM 1 + +/* Define to 1 if the Linux getrandom() syscall is available */ +#define HAVE_GETRANDOM_SYSCALL 1 + +/* Define to 1 if you have the `getresgid' function. */ +#define HAVE_GETRESGID 1 + +/* Define to 1 if you have the `getresuid' function. */ +#define HAVE_GETRESUID 1 + +/* Define to 1 if you have the `getsid' function. */ +#define HAVE_GETSID 1 + +/* Define to 1 if you have the `getspent' function. */ +#define HAVE_GETSPENT 1 + +/* Define to 1 if you have the `getspnam' function. */ +#define HAVE_GETSPNAM 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `getwd' function. */ +#define HAVE_GETWD 1 + +/* Define if glibc has incorrect _FORTIFY_SOURCE wrappers for memmove and + bcopy. */ +/* #undef HAVE_GLIBC_MEMMOVE_BUG */ + +/* Define to 1 if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the 'hstrerror' function. */ +#define HAVE_HSTRERROR 1 + +/* Define this if you have le64toh() */ +#define HAVE_HTOLE64 1 + +/* Define to 1 if you have the `hypot' function. */ +#define HAVE_HYPOT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IEEEFP_H */ + +/* Define to 1 if you have the `if_nameindex' function. */ +#define HAVE_IF_NAMEINDEX 1 + +/* Define if you have the 'inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the 'inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if you have the `initgroups' function. */ +#define HAVE_INITGROUPS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* Define if gcc has the ipa-pure-const bug. */ +/* #undef HAVE_IPA_PURE_CONST_BUG */ + +/* Define to 1 if you have the `kill' function. */ +#define HAVE_KILL 1 + +/* Define to 1 if you have the `killpg' function. */ +#define HAVE_KILLPG 1 + +/* Define if you have the 'kqueue' functions. */ +/* #undef HAVE_KQUEUE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LANGINFO_H 1 + +/* Defined to enable large file support when an off_t is bigger than a long + and long long is at least as big as an off_t. You may need to add some + flags for configuration and compilation to enable this mode. (For Solaris + and Linux, the necessary defines are already defined.) */ +#define HAVE_LARGEFILE_SUPPORT 1 + +/* Define to 1 if you have the 'lchflags' function. */ +/* #undef HAVE_LCHFLAGS */ + +/* Define to 1 if you have the `lchmod' function. */ +/* #undef HAVE_LCHMOD */ + +/* Define to 1 if you have the `lchown' function. */ +#define HAVE_LCHOWN 1 + +/* Define to 1 if you have the `lgamma' function. */ +#define HAVE_LGAMMA 1 + +/* Define to 1 if you have the `dl' library (-ldl). */ +#define HAVE_LIBDL 1 + +/* Define to 1 if you have the `dld' library (-ldld). */ +/* #undef HAVE_LIBDLD */ + +/* Define to 1 if you have the `ieee' library (-lieee). */ +/* #undef HAVE_LIBIEEE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIBINTL_H 1 + +/* Define if you have the readline library (-lreadline). */ +/* #undef HAVE_LIBREADLINE */ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define to 1 if you have the `sendfile' library (-lsendfile). */ +/* #undef HAVE_LIBSENDFILE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBUTIL_H */ + +/* Define if you have the 'link' function. */ +#define HAVE_LINK 1 + +/* Define to 1 if you have the `linkat' function. */ +#define HAVE_LINKAT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_CAN_BCM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_CAN_H 1 + +/* Define if compiling using Linux 3.6 or later. */ +#define HAVE_LINUX_CAN_RAW_FD_FRAMES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_CAN_RAW_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_MEMFD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_NETLINK_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_QRTR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_RANDOM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_TIPC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LINUX_VM_SOCKETS_H 1 + +/* Define to 1 if you have the `lockf' function. */ +#define HAVE_LOCKF 1 + +/* Define to 1 if you have the `log1p' function. */ +#define HAVE_LOG1P 1 + +/* Define to 1 if you have the `log2' function. */ +#define HAVE_LOG2 1 + +/* Define to 1 if the system has the type `long double'. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define to 1 if you have the `lstat' function. */ +#define HAVE_LSTAT 1 + +/* Define to 1 if you have the `lutimes' function. */ +#define HAVE_LUTIMES 1 + +/* Define to 1 if you have the `madvise' function. */ +#define HAVE_MADVISE 1 + +/* Define this if you have the makedev macro. */ +#define HAVE_MAKEDEV 1 + +/* Define to 1 if you have the `mbrtowc' function. */ +#define HAVE_MBRTOWC 1 + +/* Define if you have the 'memfd_create' function. */ +/* #undef HAVE_MEMFD_CREATE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memrchr' function. */ +#define HAVE_MEMRCHR 1 + +/* Define to 1 if you have the `mkdirat' function. */ +#define HAVE_MKDIRAT 1 + +/* Define to 1 if you have the `mkfifo' function. */ +#define HAVE_MKFIFO 1 + +/* Define to 1 if you have the `mkfifoat' function. */ +#define HAVE_MKFIFOAT 1 + +/* Define to 1 if you have the `mknod' function. */ +#define HAVE_MKNOD 1 + +/* Define to 1 if you have the `mknodat' function. */ +#define HAVE_MKNODAT 1 + +/* Define to 1 if you have the `mktime' function. */ +#define HAVE_MKTIME 1 + +/* Define to 1 if you have the `mmap' function. */ +#define HAVE_MMAP 1 + +/* Define to 1 if you have the `mremap' function. */ +#define HAVE_MREMAP 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSES_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETPACKET_PACKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define to 1 if you have the `nice' function. */ +#define HAVE_NICE 1 + +/* Define to 1 if you have the `openat' function. */ +#define HAVE_OPENAT 1 + +/* Define to 1 if you have the `openpty' function. */ +#define HAVE_OPENPTY 1 + +/* Define to 1 if you have the `pathconf' function. */ +#define HAVE_PATHCONF 1 + +/* Define to 1 if you have the `pause' function. */ +#define HAVE_PAUSE 1 + +/* Define to 1 if you have the `pipe2' function. */ +#define HAVE_PIPE2 1 + +/* Define to 1 if you have the `plock' function. */ +/* #undef HAVE_PLOCK */ + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define to 1 if you have the `posix_fadvise' function. */ +#define HAVE_POSIX_FADVISE 1 + +/* Define to 1 if you have the `posix_fallocate' function. */ +#define HAVE_POSIX_FALLOCATE 1 + +/* Define to 1 if you have the `posix_spawn' function. */ +#define HAVE_POSIX_SPAWN 1 + +/* Define to 1 if you have the `posix_spawnp' function. */ +#define HAVE_POSIX_SPAWNP 1 + +/* Define to 1 if you have the `pread' function. */ +#define HAVE_PREAD 1 + +/* Define to 1 if you have the `preadv' function. */ +#define HAVE_PREADV 1 + +/* Define to 1 if you have the `preadv2' function. */ +/* #undef HAVE_PREADV2 */ + +/* Define if you have the 'prlimit' functions. */ +#define HAVE_PRLIMIT 1 + +/* Define if you have the '_dyld_shared_cache_contains_path' function. */ +/* #undef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PROCESS_H */ + +/* Define if your compiler supports function prototype */ +#define HAVE_PROTOTYPES 1 + +/* Define to 1 if you have the `pthread_condattr_setclock' function. */ +#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1 + +/* Defined for Solaris 2.6 bug in pthread header. */ +/* #undef HAVE_PTHREAD_DESTRUCTOR */ + +/* Define to 1 if you have the `pthread_getcpuclockid' function. */ +#define HAVE_PTHREAD_GETCPUCLOCKID 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the `pthread_init' function. */ +/* #undef HAVE_PTHREAD_INIT */ + +/* Define to 1 if you have the `pthread_kill' function. */ +#define HAVE_PTHREAD_KILL 1 + +/* Define to 1 if you have the `pthread_sigmask' function. */ +#define HAVE_PTHREAD_SIGMASK 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PTY_H 1 + +/* Define to 1 if you have the `putenv' function. */ +#define HAVE_PUTENV 1 + +/* Define to 1 if you have the `pwrite' function. */ +#define HAVE_PWRITE 1 + +/* Define to 1 if you have the `pwritev' function. */ +#define HAVE_PWRITEV 1 + +/* Define to 1 if you have the `pwritev2' function. */ +/* #undef HAVE_PWRITEV2 */ + +/* Define to 1 if you have the `readlink' function. */ +#define HAVE_READLINK 1 + +/* Define to 1 if you have the `readlinkat' function. */ +#define HAVE_READLINKAT 1 + +/* Define to 1 if you have the `readv' function. */ +#define HAVE_READV 1 + +/* Define to 1 if you have the `realpath' function. */ +#define HAVE_REALPATH 1 + +/* Define to 1 if you have the `renameat' function. */ +#define HAVE_RENAMEAT 1 + +/* Define if readline supports append_history */ +/* #undef HAVE_RL_APPEND_HISTORY */ + +/* Define if you can turn off readline's signal handling. */ +/* #undef HAVE_RL_CATCH_SIGNAL */ + +/* Define if you have readline 2.2 */ +/* #undef HAVE_RL_COMPLETION_APPEND_CHARACTER */ + +/* Define if you have readline 4.0 */ +/* #undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK */ + +/* Define if you have readline 4.2 */ +/* #undef HAVE_RL_COMPLETION_MATCHES */ + +/* Define if you have rl_completion_suppress_append */ +/* #undef HAVE_RL_COMPLETION_SUPPRESS_APPEND */ + +/* Define if you have readline 4.0 */ +/* #undef HAVE_RL_PRE_INPUT_HOOK */ + +/* Define if you have readline 4.0 */ +/* #undef HAVE_RL_RESIZE_TERMINAL */ + +/* Define to 1 if you have the `round' function. */ +#define HAVE_ROUND 1 + +/* Define to 1 if you have the `rtpSpawn' function. */ +/* #undef HAVE_RTPSPAWN */ + +/* Define to 1 if you have the `sched_get_priority_max' function. */ +#define HAVE_SCHED_GET_PRIORITY_MAX 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SCHED_H 1 + +/* Define to 1 if you have the `sched_rr_get_interval' function. */ +#define HAVE_SCHED_RR_GET_INTERVAL 1 + +/* Define to 1 if you have the `sched_setaffinity' function. */ +#define HAVE_SCHED_SETAFFINITY 1 + +/* Define to 1 if you have the `sched_setparam' function. */ +#define HAVE_SCHED_SETPARAM 1 + +/* Define to 1 if you have the `sched_setscheduler' function. */ +#define HAVE_SCHED_SETSCHEDULER 1 + +/* Define to 1 if you have the `sem_getvalue' function. */ +#define HAVE_SEM_GETVALUE 1 + +/* Define to 1 if you have the `sem_open' function. */ +#define HAVE_SEM_OPEN 1 + +/* Define to 1 if you have the `sem_timedwait' function. */ +#define HAVE_SEM_TIMEDWAIT 1 + +/* Define to 1 if you have the `sem_unlink' function. */ +#define HAVE_SEM_UNLINK 1 + +/* Define to 1 if you have the `sendfile' function. */ +#define HAVE_SENDFILE 1 + +/* Define to 1 if you have the `setegid' function. */ +#define HAVE_SETEGID 1 + +/* Define to 1 if you have the `seteuid' function. */ +#define HAVE_SETEUID 1 + +/* Define to 1 if you have the `setgid' function. */ +#define HAVE_SETGID 1 + +/* Define if you have the 'setgroups' function. */ +#define HAVE_SETGROUPS 1 + +/* Define to 1 if you have the `sethostname' function. */ +#define HAVE_SETHOSTNAME 1 + +/* Define to 1 if you have the `setitimer' function. */ +#define HAVE_SETITIMER 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setpgid' function. */ +#define HAVE_SETPGID 1 + +/* Define to 1 if you have the `setpgrp' function. */ +#define HAVE_SETPGRP 1 + +/* Define to 1 if you have the `setpriority' function. */ +#define HAVE_SETPRIORITY 1 + +/* Define to 1 if you have the `setregid' function. */ +#define HAVE_SETREGID 1 + +/* Define to 1 if you have the `setresgid' function. */ +#define HAVE_SETRESGID 1 + +/* Define to 1 if you have the `setresuid' function. */ +#define HAVE_SETRESUID 1 + +/* Define to 1 if you have the `setreuid' function. */ +#define HAVE_SETREUID 1 + +/* Define to 1 if you have the `setsid' function. */ +#define HAVE_SETSID 1 + +/* Define to 1 if you have the `setuid' function. */ +#define HAVE_SETUID 1 + +/* Define to 1 if you have the `setvbuf' function. */ +#define HAVE_SETVBUF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SHADOW_H 1 + +/* Define to 1 if you have the `shm_open' function. */ +#define HAVE_SHM_OPEN 1 + +/* Define to 1 if you have the `shm_unlink' function. */ +#define HAVE_SHM_UNLINK 1 + +/* Define to 1 if you have the `sigaction' function. */ +#define HAVE_SIGACTION 1 + +/* Define to 1 if you have the `sigaltstack' function. */ +#define HAVE_SIGALTSTACK 1 + +/* Define to 1 if you have the `sigfillset' function. */ +#define HAVE_SIGFILLSET 1 + +/* Define to 1 if `si_band' is a member of `siginfo_t'. */ +#define HAVE_SIGINFO_T_SI_BAND 1 + +/* Define to 1 if you have the `siginterrupt' function. */ +#define HAVE_SIGINTERRUPT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the `sigpending' function. */ +#define HAVE_SIGPENDING 1 + +/* Define to 1 if you have the `sigrelse' function. */ +#define HAVE_SIGRELSE 1 + +/* Define to 1 if you have the `sigtimedwait' function. */ +#define HAVE_SIGTIMEDWAIT 1 + +/* Define to 1 if you have the `sigwait' function. */ +#define HAVE_SIGWAIT 1 + +/* Define to 1 if you have the `sigwaitinfo' function. */ +#define HAVE_SIGWAITINFO 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* struct sockaddr_alg (linux/if_alg.h) */ +#define HAVE_SOCKADDR_ALG 1 + +/* Define if sockaddr has sa_len member */ +/* #undef HAVE_SOCKADDR_SA_LEN */ + +/* struct sockaddr_storage (sys/socket.h) */ +#define HAVE_SOCKADDR_STORAGE 1 + +/* Define if you have the 'socketpair' function. */ +#define HAVE_SOCKETPAIR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SPAWN_H 1 + +/* Define if your compiler provides ssize_t */ +#define HAVE_SSIZE_T 1 + +/* Define to 1 if you have the `statvfs' function. */ +#define HAVE_STATVFS 1 + +/* Define if you have struct stat.st_mtim.tv_nsec */ +#define HAVE_STAT_TV_NSEC 1 + +/* Define if you have struct stat.st_mtimensec */ +/* #undef HAVE_STAT_TV_NSEC2 */ + +/* Define if your compiler supports variable length function prototypes (e.g. + void fprintf(FILE *, char *, ...);) *and* */ +#define HAVE_STDARG_PROTOTYPES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Has stdatomic.h with atomic_int and atomic_uintptr_t */ +#define HAVE_STD_ATOMIC 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STROPTS_H 1 + +/* Define to 1 if you have the `strsignal' function. */ +#define HAVE_STRSIGNAL 1 + +/* Define to 1 if `pw_gecos' is a member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_GECOS 1 + +/* Define to 1 if `pw_passwd' is a member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_PASSWD 1 + +/* Define to 1 if `st_birthtime' is a member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIME */ + +/* Define to 1 if `st_blksize' is a member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 + +/* Define to 1 if `st_blocks' is a member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 + +/* Define to 1 if `st_flags' is a member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_FLAGS */ + +/* Define to 1 if `st_gen' is a member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_GEN */ + +/* Define to 1 if `st_rdev' is a member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_RDEV 1 + +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +#define HAVE_STRUCT_TM_TM_ZONE 1 + +/* Define if you have the 'symlink' function. */ +#define HAVE_SYMLINK 1 + +/* Define to 1 if you have the `symlinkat' function. */ +#define HAVE_SYMLINKAT 1 + +/* Define to 1 if you have the `sync' function. */ +#define HAVE_SYNC 1 + +/* Define to 1 if you have the `sysconf' function. */ +#define HAVE_SYSCONF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSEXITS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_AUDIOIO_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BSDTTY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_DEVPOLL_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_ENDIAN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_EPOLL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_EVENT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_KERN_CONTROL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_LOADAVG_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_LOCK_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MEMFD_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MKDEV_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_MODEM_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RANDOM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SENDFILE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STATVFS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSCALL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSMACROS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYS_DOMAIN_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TERMIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIMES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_XATTR_H 1 + +/* Define to 1 if you have the `tcgetpgrp' function. */ +#define HAVE_TCGETPGRP 1 + +/* Define to 1 if you have the `tcsetpgrp' function. */ +#define HAVE_TCSETPGRP 1 + +/* Define to 1 if you have the `tempnam' function. */ +#define HAVE_TEMPNAM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERM_H */ + +/* Define to 1 if you have the `tgamma' function. */ +#define HAVE_TGAMMA 1 + +/* Define to 1 if you have the `timegm' function. */ +#define HAVE_TIMEGM 1 + +/* Define to 1 if you have the `times' function. */ +#define HAVE_TIMES 1 + +/* Define to 1 if you have the `tmpfile' function. */ +#define HAVE_TMPFILE 1 + +/* Define to 1 if you have the `tmpnam' function. */ +#define HAVE_TMPNAM 1 + +/* Define to 1 if you have the `tmpnam_r' function. */ +#define HAVE_TMPNAM_R 1 + +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use + `HAVE_STRUCT_TM_TM_ZONE' instead. */ +#define HAVE_TM_ZONE 1 + +/* Define to 1 if you have the `truncate' function. */ +#define HAVE_TRUNCATE 1 + +/* Define to 1 if you don't have `tm_zone' but do have the external array + `tzname'. */ +/* #undef HAVE_TZNAME */ + +/* Define this if you have tcl and TCL_UTF_MAX==6 */ +/* #undef HAVE_UCS4_TCL */ + +/* Define to 1 if you have the `uname' function. */ +#define HAVE_UNAME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `unlinkat' function. */ +#define HAVE_UNLINKAT 1 + +/* Define to 1 if you have the `unsetenv' function. */ +#define HAVE_UNSETENV 1 + +/* Define if you have a useable wchar_t type defined in wchar.h; useable means + wchar_t must be an unsigned type with at least 16 bits. (see + Include/unicodeobject.h). */ +/* #undef HAVE_USABLE_WCHAR_T */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UTIL_H */ + +/* Define to 1 if you have the `utimensat' function. */ +#define HAVE_UTIMENSAT 1 + +/* Define to 1 if you have the `utimes' function. */ +#define HAVE_UTIMES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define if uuid_create() exists. */ +/* #undef HAVE_UUID_CREATE */ + +/* Define if uuid_enc_be() exists. */ +/* #undef HAVE_UUID_ENC_BE */ + +/* Define if uuid_generate_time_safe() exists. */ +/* #undef HAVE_UUID_GENERATE_TIME_SAFE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UUID_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UUID_UUID_H */ + +/* Define to 1 if you have the `wait3' function. */ +#define HAVE_WAIT3 1 + +/* Define to 1 if you have the `wait4' function. */ +#define HAVE_WAIT4 1 + +/* Define to 1 if you have the `waitid' function. */ +#define HAVE_WAITID 1 + +/* Define to 1 if you have the `waitpid' function. */ +#define HAVE_WAITPID 1 + +/* Define if the compiler provides a wchar.h header file. */ +#define HAVE_WCHAR_H 1 + +/* Define to 1 if you have the `wcscoll' function. */ +#define HAVE_WCSCOLL 1 + +/* Define to 1 if you have the `wcsftime' function. */ +#define HAVE_WCSFTIME 1 + +/* Define to 1 if you have the `wcsxfrm' function. */ +#define HAVE_WCSXFRM 1 + +/* Define to 1 if you have the `wmemcmp' function. */ +#define HAVE_WMEMCMP 1 + +/* Define if tzset() actually switches the local timezone in a meaningful way. + */ +/* #undef HAVE_WORKING_TZSET */ + +/* Define to 1 if you have the `writev' function. */ +#define HAVE_WRITEV 1 + +/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ +/* #undef HAVE_X509_VERIFY_PARAM_SET1_HOST */ + +/* Define if the zlib library has inflateCopy */ +/* #undef HAVE_ZLIB_COPY */ + +/* Define to 1 if you have the `_getpty' function. */ +/* #undef HAVE__GETPTY */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in . + */ +/* #undef MAJOR_IN_MKDEV */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in + . */ +/* #undef MAJOR_IN_SYSMACROS */ + +/* Define if mvwdelch in curses.h is an expression. */ +/* #undef MVWDELCH_IS_EXPRESSION */ + +/* Define to the address where bug reports for this package should be sent. */ +/* #undef PACKAGE_BUGREPORT */ + +/* Define to the full name of this package. */ +/* #undef PACKAGE_NAME */ + +/* Define to the full name and version of this package. */ +/* #undef PACKAGE_STRING */ + +/* Define to the one symbol short name of this package. */ +/* #undef PACKAGE_TARNAME */ + +/* Define to the home page for this package. */ +/* #undef PACKAGE_URL */ + +/* Define to the version of this package. */ +/* #undef PACKAGE_VERSION */ + +/* Define if POSIX semaphores aren't enabled on your system */ +/* #undef POSIX_SEMAPHORES_NOT_ENABLED */ + +/* Define if pthread_key_t is compatible with int. */ +#define PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT 1 + +/* Defined if PTHREAD_SCOPE_SYSTEM supported. */ +/* #undef PTHREAD_SYSTEM_SCHED_SUPPORTED */ + +/* Define as the preferred size in bits of long digits */ +/* #undef PYLONG_BITS_IN_DIGIT */ + +/* Define if you want to coerce the C locale to a UTF-8 based locale */ +#define PY_COERCE_C_LOCALE 1 + +/* Define to printf format modifier for Py_ssize_t */ +#define PY_FORMAT_SIZE_T "z" + +/* Default cipher suites list for ssl module. 1: Python's preferred selection, + 2: leave OpenSSL defaults untouched, 0: custom string */ +#define PY_SSL_DEFAULT_CIPHERS 1 + +/* Cipher suite string for PY_SSL_DEFAULT_CIPHERS=0 */ +/* #undef PY_SSL_DEFAULT_CIPHER_STRING */ + +/* Define if you want to build an interpreter with many run-time checks. */ +/* #undef Py_DEBUG */ + +/* Defined if Python is built as a shared library. */ +/* #undef Py_ENABLE_SHARED */ + +/* Define hash algorithm for str, bytes and memoryview. SipHash24: 1, FNV: 2, + externally defined: 0 */ +/* #undef Py_HASH_ALGORITHM */ + +/* Define if you want to enable tracing references for debugging purpose */ +/* #undef Py_TRACE_REFS */ + +/* assume C89 semantics that RETSIGTYPE is always void */ +#define RETSIGTYPE void + +/* Define if setpgrp() must be called as setpgrp(0, 0). */ +/* #undef SETPGRP_HAVE_ARG */ + +/* Define to 1 if you must link with -lrt for shm_open(). */ +#define SHM_NEEDS_LIBRT 1 + +/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */ +/* #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS */ + +/* The size of `double', as computed by sizeof. */ +#define SIZEOF_DOUBLE 8 + +/* The size of `float', as computed by sizeof. */ +#define SIZEOF_FLOAT 4 + +/* The size of `fpos_t', as computed by sizeof. */ +#define SIZEOF_FPOS_T 16 + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* The size of `long double', as computed by sizeof. */ +#define SIZEOF_LONG_DOUBLE 8 + +/* The size of `long long', as computed by sizeof. */ +#define SIZEOF_LONG_LONG 8 + +/* The size of `off_t', as computed by sizeof. */ +#define SIZEOF_OFF_T 8 + +/* The size of `pid_t', as computed by sizeof. */ +#define SIZEOF_PID_T 4 + +/* The size of `pthread_key_t', as computed by sizeof. */ +#define SIZEOF_PTHREAD_KEY_T 4 + +/* The size of `pthread_t', as computed by sizeof. */ +#define SIZEOF_PTHREAD_T 4 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 4 + +/* The size of `time_t', as computed by sizeof. */ +#define SIZEOF_TIME_T 4 + +/* The size of `uintptr_t', as computed by sizeof. */ +#define SIZEOF_UINTPTR_T 4 + +/* The size of `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 4 + +/* The size of `wchar_t', as computed by sizeof. */ +#define SIZEOF_WCHAR_T 4 + +/* The size of `_Bool', as computed by sizeof. */ +#define SIZEOF__BOOL 1 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and + (which you can't on SCO ODT 3.0). */ +#define SYS_SELECT_WITH_SYS_TIME 1 + +/* Library needed by timemodule.c: librt may be needed for clock_gettime() */ +/* #undef TIMEMODULE_LIB */ + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define if you want to use computed gotos in ceval.c. */ +/* #undef USE_COMPUTED_GOTOS */ + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Define if WINDOW in curses.h offers a field _flags. */ +/* #undef WINDOW_HAS_FLAGS */ + +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#define WITH_DECIMAL_CONTEXTVAR 1 + +/* Define if you want documentation strings in extension modules */ +#define WITH_DOC_STRINGS 1 + +/* Define if you want to compile in DTrace support */ +/* #undef WITH_DTRACE */ + +/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic + linker (dyld) instead of the old-style (NextStep) dynamic linker (rld). + Dyld is necessary to support frameworks. */ +/* #undef WITH_DYLD */ + +/* Define to 1 if libintl is needed for locale functions. */ +/* #undef WITH_LIBINTL */ + +/* Define if you want to produce an OpenStep/Rhapsody framework (shared + library plus accessory files). */ +/* #undef WITH_NEXT_FRAMEWORK */ + +/* Define if you want to compile in Python-specific mallocs */ +#define WITH_PYMALLOC 1 + +/* Define if you want pymalloc to be disabled when running under valgrind */ +/* #undef WITH_VALGRIND */ + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define if arithmetic is subject to x87-style double rounding issue */ +/* #undef X87_DOUBLE_ROUNDING */ + +/* Define on OpenBSD to activate all library features */ +/* #undef _BSD_SOURCE */ + +/* Define on Darwin to activate all library features */ +#define _DARWIN_C_SOURCE 1 + +/* This must be set to 64 on some systems to enable large file support. */ +#define _FILE_OFFSET_BITS 64 + +/* Define on Linux to activate all library features */ +#define _GNU_SOURCE 1 + +/* Define to include mbstate_t for mbrtowc */ +/* #undef _INCLUDE__STDC_A1_SOURCE */ + +/* This must be defined on some systems to enable large file support. */ +#define _LARGEFILE_SOURCE 1 + +/* This must be defined on AIX systems to enable large file support. */ +/* #undef _LARGE_FILES */ + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* Define on NetBSD to activate all library features */ +#define _NETBSD_SOURCE 1 + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to activate features from IEEE Stds 1003.1-2008 */ +#define _POSIX_C_SOURCE 200809L + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define if you have POSIX threads, and your system does not define that. */ +/* #undef _POSIX_THREADS */ + +/* framework name */ +#define _PYTHONFRAMEWORK "" + +/* Define to force use of thread-safe errno, h_errno, and other functions */ +#define _REENTRANT 1 + +/* Define to the level of X/Open that your system supports */ +#define _XOPEN_SOURCE 700 + +/* Define to activate Unix95-and-earlier features */ +#define _XOPEN_SOURCE_EXTENDED 1 + +/* Define on FreeBSD to activate all library features */ +#define __BSD_VISIBLE 1 + +/* Define to 1 if type `char' is unsigned and you are not using gcc. */ +#ifndef __CHAR_UNSIGNED__ +/* # undef __CHAR_UNSIGNED__ */ +#endif + +/* Define to 'long' if doesn't define. */ +/* #undef clock_t */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define to `int' if does not define. */ +/* #undef mode_t */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to empty if the keyword does not work. */ +/* #undef signed */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +/* #undef socklen_t */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + + +/* Define the macros needed if on a UnixWare 7.x system. */ +#if defined(__USLC__) && defined(__SCO_VERSION__) +#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ +#endif + +#endif /*Py_PYCONFIG_H*/ + -- Gitee

    LI5sUdHBF4g_h5(_4MIB630zS2jisp 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%0ABC6!xaDcbA!TcR{DtVjN&cuj$md zA<&ZE7Ru{!w{&{U+r4mUO9+Ka*F$Ipl=4fUJJ}0LRZBSWG?I0tQ#C?7{Cm3I3bb!Q z=l>_jWzZ8rUf!X4zZ(Of!-5=uI+g>VbKSs*iQYEJFA8J>bUVlaT2F`YV3hr=1}+Cr zvq$6mgQqzt^ovQFU8~u?c8DD@xjyDB8m2mn>Cw9vt3z4kZt4wpQKlOc!XERymi;r5 z=dmAn5KgV&R0^*!Q7PQ52*UfsF-6b;f?;Wc#DlePW_dbC_?R5s>|*9XtAmTMl|WmI zZd>@wjeBKS<2Zr$`IPjnwiU7*aA zQ{9zM&+a=Gea?T;Jezx`7F4a_4X;hTgA#58^SyoDniCEEhXs7u{R4eW0~#aM8JklI zBigmDYeSpS#)cWi(I3Y2pZ+@J?`9gXmhR0HgoUp&FGt@for1Y2|)h~ffE241rrGX<4Zv-G(>VWAQX=!0P&v^)YI6D zi^lBUD!$FZ%6VBUnAZ%Rm#xbJ-4Vw#-GkyGd)#K0dDXmnT=PGEdT7pUB^QAfomv%` z#x6JdO26#gs%%=ej7aD2lutY84}G>0RY)oHQtzz&WPV`_v?Iu6&@sX2g$W7x7lNq| zf~mR>F-K}#0wu?LX)XWXrtZ&$U;|2yZUZFGJ`LG;F$D9o1mSOe?Sj9J~p0?}2P$L<4Wm znhoOD1hN6b%V4ro#Z3pTbl>$o9cy@jHMechZQFDkv#57_(n9uNCzpCW_nCl++_%{r zuu*La?41|n02J1%tyetV1T9rYURMBuq(eP|;?&J~jTzgvFwy4{k^o0Fb z160XvYY}M$)pVxkI*MC|6(It@lEH$QC(RAA7m~DHeYaK}m!q@0^p?(%2z8&)@{W6- zbp_5c;p3art3$u-c9n=bVyb6tK(xx0wMhNlav~ZK(>5UXW^FSf2w~f`BRGFapm_yh zaU$a#NDho^n8;*wXx0}yH|tEct}10~SAIjXI<*Jj)U$$~y#i%z5$+xgkbUoq`ECf7 zEirkH!c|3zKn7&3qu~)|QJhCAvskaDr^39m))8AV`M${!$TTa(1jY?ymEozM71({by#dPFrzv8Q-IUmsao$y1*@GfeLKD39!*NR84+Z)(bI~#Kq(#?KjsJG=G?;smB=sshK2j~zIEPYs+Pa=@mUEM7Zh?_w1? zQ^{j%@Ub>@rfz&1kY*}!Iu45akU$FwA_#4Pr$V`2jn|8fA#K|P;sxQedTnED=Uncz zHAgz;ZY#WlukwI7#07nf?yG-6?^&`M75Cq*AgWFhIR#&+q#(D~LEs3}+NM zOE&58S<)MugHh>R6Rd9}V#^wDk=)ORYy(O)1N*N)?Rpin-aJseNRIEhGBTE2FD0;$ zWc8`w00oW<>`UKjAiTuCIK_{ zWh);&Z))}FBnO4o4}<~DTG9TR^P-($Td5|yo&g_esLUDAJIw3M07n`-2agE5jUH8P zEb9fyPjjcd?XPDuC5jB;$jW3!O^J7tzQSH4H?qblQDol4+B-dc$t&h&qp@x7@uo1d z`DPMD=1u&Qsd!zGy$@sc8qjY9**~aBJtQFEgnlW=k*&^(mRPmJ0{EwbF7KZHs}lVKg0zSvRfaWCWk_I4 z2z{^!-Y(EZ1ca`M_gpvi8Ywv*iuMf`#Ii#$UYWS=(EI4(#N4}jGd^k*8pi~@Im-`g zK@*LPq75J3)z7khKs`f)sNSK2A7K!UXMSVXUP?A%)PI}w&mQXS7dt4@9P@ETUYDBs z(9-8Q)ib-dT9VDddSgrhhA%4)?pSo9My4c#2 z#Tq9uA7J`Tf$|h|_%7rMh@X$oV+iW~901+w2B2Q#0BFbmYze3X0;vKGx&f&7a{zRq z8-Tiz1E71|z@*EwdTz=8R~ZTjuQdgr6G1j0TvjjWcd{3BKYKw>vlo=1EfdVogli3G zXOPRFec21zALM}e2t_79-wLt;UCdt4rR)V|$mO;xV%sm<2ht5t2C{rbWP0DRa{J!XcyH5Rm zqU!Tv&&Af0+3|}N{VxSvW%Of0L+Di5xwoljVXf_2_f$hWW6JX6u{fS(%t4N9ICYAm zY6~ueO}1B^!&yAD|2PXZ$Dno}`%I{mY{r$AgUm8Zon;Ff z*SZ0y-->|-bgvtLdKd!((2H&WYKxvcYq~*;g0^Oy>K@+R3h(+LJme!3V0)pTTb9o2 z0;MVFh5#loUhz2#ux(BIoCS6+3HZi|P)^9v+Km3la;r~gajkCJ=PVA3^@KpTES@lt zx72exdYijK_mYA6`AAT2oN`BVSKgqFH~G#BqYfH9D1k;1TABhVCruo(TAyyynR-ws_O!TdQMWtk3Hz}IsM5q)i%2V|rZYWPwbeST2od-P z87zo-(%c~XGD+LjPbjNnY<)`SNQAlsw7lcqFN8XrWy0BP=Y=n~v{$FzgehS!z({YG zgiNjtA*v0C*62s=MK>U(Z9weJ+GZ~-Y}0lG^BnV2y9-JkwVJ9>0G4L8bN$2ZbZMwMKhlof^>RgRJiU$--R6?%tlyS&Z4pTpc;s z$%9t{ophkwETf;ZFbhvW%`@^ji)Rw-$${|#k^Yy0?sFD2urPAlPk3;mS{c1MEH)aL z(H#9S^2)oK+&J|&ik!fc+vyGWh!s^kVIl6M#y2b3$&qqcpo2V~UEUUbuWE4tFXb9s%lAzSPjNXUQyG%Gu z#5v)f&I##Duik6Kz8WHpCrTeZLD9YFeb0*OGj&ssi6BgEgBSnX$Ol+FQe`l)?HBVQ zfxH6!Qjpz=rW|j7e#P_9h@qOp3&B4CO`n&HVeoP0MQ^l7EmN*&&ezeDk+Eowi}`(l zq5*w9$T}K_(VOn^$8!^N*FemBSllzP96 z-fzX?H=s7Riis~7hBZWj+?id^${FIwPp+ zIz7fw$F1lb*${O9R&+O@VS1sa)N$P7TA3bFw)C%U#3 z+3v(I)?S52DNbFz9iR%b=Hn zoI$7^e*vCl&;daXKpn~f(D7~n>irx5eb^1u#xebC0^QYuVA29l=U6Hn-BAX6@15%s zy)TGG5ynH_slbI(L6@b7J@?Kw_5OZ=LI!1I19$=T)-EK?d^{0o5cE9An2bFs0%A5a zMQ4RFmQIn*AU)(JUOd$b{?1>~dkjn~zPOD%9=L5c#-%r1;}Kku&UTT`b|sDVe1#9y za^sF%wl0wyT~ZvKxW818ciSK}Q^W>{oHDtToO<_2?1(sKd*ZfN(d`U_NARQ4)90i} zkIqR-TSGM;xH38)W0^cP?C|BHM1MEL8&GN*I3CS`oe>!V@!wgoBB>)hR&{cuI*l1T zC*}_Y(gOO8AiEnTIBuvb9a$?TtB*|U9VIQwH*#S>nXKJ$%4vt&lUoGsymWDr7+OX% zp!AO~mwxx6l^73{H-Fe&Y$;#Ie8{++R$~u!ygKau)=v-3nJx1%JJzY`Gt<~inmaL{ z6ZwHa^9s81_aRq64+I$})UzA_9siC8pw0^<0eaRAKyA4f1E9l#(J32s;-xHa4Fe76 zVvqyO9trIO41FWW26QHSuM6Eu5`%lfV7H#d#AzwYz#0dpWM7m>6Vl5lLW6pDNl7Z2 zQugR4t)%KkxYvMiQNiQH?}U5|RL#gj971fX zT08eJWdjZv-X*ByHdh>Elv(QRA_J{uBRo=XHI*eP>1|W)Zjas2fPN~-YW<&Se)F*C zHu3KZ(+pI)wnpdo)j9g<5xk^#Vv!%I^J%b;eprP5#{w@hGzvx**}@}>JRfH&XIMQ| zdD71Atzy_53RsR>0UrS2by`jkjj!j-3Rg0>uZt$j+(r-A9=Ah@{@bKSTSemyY1DQ9 z>pwk&LcdxUetKx_IcDA2vgT}AFZUqn<#}mQSg6=55Q%(yZ7u9JIPTzlToa2cme7Ni z)Nt(y_=`KAF7U&cLo&6(m0}Fa8$ZI3i%Nzi0`lIml zL0bgL19dzG^hXNkdgr@j)Yguca-K)rciDiI4dr znx)*fq}!v?Zh_HM1&$jZJ8=9?;jzF8A_r`mS>&}}_O1&YI#bEP1wI}0-XT*rJ`G4S z6*(QN(y%7bLV^f_4JNr&>Zg$$5;~jH%B)x;L@_;$S z1>L!yKd<7H)xfyhTSQ~lZO@L|HaMxTtZwSdcF~vZqA%N(K4z%$P+JJ+$YhZq^eUmP zQoYtzZ8vd9O(S-~)XX83k_~|Y^tP`pfteLV9OZhmGD~`6b1*8MYl8KSL~L2(os#=A zA=`jb&A|Svqs&$pv+kJ1isbm7D60x1N2Cdld{sM{KKrS+9!vP(Y>54v~f z?1M zM;a<~2EMTF3~;2ebMUB&9#t93xbyf0H(8o$`^Ci`1T&X zc`Hzcf>!@6$YszSK^{O*_j3UBPlD`&9t)BO>cF1}VbGc&2cXX70O)2nFz&_o!;3!1 zOy%aswhG zUIOiunP7tWS%HK>xDx&Na?uTlzabD42p@yVPNkC$ODn&PPXIVHw;i6_qtb4H(NrxV z5q<0>B%-NHNEA6>(*($Co9vwvuvZA;anN5Ff*VQEPZFS^-cLxEyZXK2-Y1X@h#-{2 z4~23a8fTt*pR2bgZQ=#tvwCe~EcY*T+L{9$b9YBmt(ca_Z~ zX=Mct+@9P8Xy>KRzqQF&EqCc0UmHD(?Q(ZC*L+V)g0O2iWLa$-geFDs4%(XyI^E!@ z5-;xQ{eO^=aGbhv2triHFLt6IL$i)w90(>n*eMU90a2aBcozM*w&An5E)|HoI!AFW zPdt3f`5(Lfc}6txo{-TqvR1DrWzw@xplktQKr3Cezvhfk8!4{`#4cdGT(d_#f$6IfB+tX!%_d*?G+?;ZAPHDHERsjwLs; zLGr@SmnQvsOJTb zH6QnYm&5b&;VFIgL_OJCu8t|g$gGPK5^>I1eNj}c)z-XOO`3DEwzN(;08@LbZB5hg<$WsU1X>=@{(l>C8FWREmlUY$IRN^dAp4*@ zg5-f({F5OJIv~gasN*>Ry4VfW-r&V|!izr0OyjlX9gUrlAx>|c+An3$*f`tLR-31{ zTgGTOEXi0nh@%1}5(v%FkLp`)KxD*Apq|X+s*8A6AYl-$L_fZqas%Qo3&aG%#}sb; zNhckaR{kKhr9*Su;koT#CPPG1wS+|Uv6qmDrY<2-l`V*LsV%pOd%Hj>2_gvP^G%^#hsK$w-UsS^91INzpVey{BEzrtzmwuf zZOx(>lexROcP+>q;)3qPSO2=M{#Qg}+--uvtlO*(2Hm#BNquE?Q(v}=zHAqL*{<}p zwWU4OM#Z^mYob@VW|d;FHj!2&4%L=h#7dZKe4&(V2nvI0PZ8;}<*8kD*z|FAf9~9?Uw6@hq5d zZNq1AUHsu^b&ld%o_P3{^FMa|^NeWXJt3oKWUXFL;iPA~K-mJqfL6L_f6W=!W`(U( z2~w|`k6~0!uG;KlnA#GLs_0Rbv8)?p7HG(){q-{?Gp4RBk)D+!X#Iqi-?gQk*Sr$$ zV}TY4G<)K+K(pjVHb`E&>)P@yh3(qX&c8|6SzB6?i@OtK)`dO`v?8&7eoWSuZ)u`j zTiW?InJ6ENYs#WynNXlVA7p=MxS^>4CHK?{k!ABwV!6NvHK=&jdbWN!( zcdC1zfHxf<3O{XWo6OCU|Mz-uW3H<$Y3voawuB}c8ATgDbhRZ7qH=8sjc2Yc?WJUk z^-Wvl#!?z>l?2kd&w)iFmInRRhOPn>g;imH{|9NP0{x@f0f zJSkt#L|9o{k}(Gax|@kw(`swptR~GlSzB7C9Du34)wZTleChwuCl>`uX;AN<$7c>f z+XZUby^U-dGgRX$ukhe-)`P4@8JGIrE$o2+?L zi#aEC_U2zn`SrOX zy;7vRTkhBY8T74EbWFhNf{zESzr!MYO0cQ-{`?T4ZOjeNs&URE5N%^__@NpXJp$1- z=7v|)xatvzwlO!np~g**K(vjy;T<*ZdIaKrHs*$V6*$3b-+4y$5jTxy=UVCP&98|s z7osV1Q;Ai)ybv>e%>YFBcZ2(|M!BwIV|3<3P#p!hdTC;cFy-2b(|DT?nRGi z@BOLK{k&iH@ZB8*{^* zYV7g|MBC5~RAZkXlQA--IQ zrp(QZ{hX_Q=71ix3ZxyhswD|9P0P2uH zT0y6}0cRZ;FaDeGq7O1t*|Jp5+WZ<@lXkWhPVJB~Xlxv7>0s1W|guLm-JNH*DC1aT#3J*OAmCMo(!f?TU| zi#+=5_qnvZ5GW-<1feOtD3t5aIP=tdL%nx`p#kBudTm3bT?8KyM`~+cbin!&G43|OVAgHVj@!04sjsYV>dSV~m+hi2+m${JE*;YLP+JP;s;!A$ z<(gHB!P-PxkvOF0X&WXRUs5UA5ExJ$Hu>xqn}|3{3}+NMOE&3o8ylD2*c^;XXT(_F zNW_*kz9qTuhin5%H3R#vK<#=Jvu?q}isbm7Dn$j zF8$cdbl=I@2a%+e6*$hSYjPJjR29YA0PSfz**U&8`X*Y-J|3l?BC-$IH5{_6HV#6Q zB6tVw%?53od0bC^t_Xdzj$iD=;fSGG$1e^96CONv1EM;M@hq5dZNq1A{csjPt8*0B z^2Ecpod2=wpJzlF>IoS=BWv}#36TK~H)RV519G)!f6W=!W`(U(2~w|`kKyU7Hv1Un z*)JYd(W5G3SvSahfQo$DUq4eaW9nzWNYBaU^8u=zo({Os3WO14;+WwGF) z&YnT%Vl>P(AD7)VU2w>K_o~2CPxh9pV~)P=;)Fz;bCZgymE0WKCkvlV-JPzk>+!7j zm3-$;&~2;b+3yjJtqD})>pLsv%$E7M?KGbpfT_LJHpeu4Qy)LNFVIB})O;Rt8FWjK zmlUYGIRN@cLH0q91jz%nZ*K^L27(-bI+FvS>)k-@4PJaNyy%0>G+tXi(%3~A;`GL; zM#`YEajB)Pwo65K1V+O#NyfrK{Hj2S1VVH4qxyjx5E=0jXot)M6U1i(5(eQ)^yA9~ zHz2+x5EBR=gULRnlMYKOzesKA(A;)-ZjVa41x8b~ghceQmyn32E+J9mfK3x1uPw57 zM!@zWh(|$xVF*4fDf&qQG}K#gw6@$W?mYs90wM?{)P12`hsK$w-lyt)84L{wpVey{ zBJCphoH$Zjvrml4+}+%}7Gw@_L3iT+?7!C4|CVTsyG<~db(__}pxd@MsjsYV>dSV~ zm+hi2+m*hywzP-Zs5n<`P4p_)tWpftCen(;p|fJASP4_}fK*C01O}+r>{%UR6A?#= z;fx|@$tFEMOL}8-Fe;sSjrEO0Y+2*y^87Oy5-8OS?7srF>s8Epcq}O-$M;+r8B4Cm zVtyu&7SIoZ>@H9^v$eCnQcQN~$5BA{%XAe)l2%sWxTWsNU4V98diS|a#%j4s=lI&_ zy^=0>M{~_p3JJol;gDsuaS)mm!8>SgHt2MN_YHVW)|TiyCWu22qB?%D6a5&Pb^PK$ zFyR45a5NyQvl!2!AJ;Z~7T3ieepcrwuH}h`Z#n;C*FVpQCf*Y=dPdgj^}F!WvqvB^ zAPi`wi}u%?acx%EN|hk>s`(g3<>ac(K8C3+@u-R(RT;~=L1ux5eA-_>QzB7x?^j+( z&&m$ zWkI8vh-0-Se&wbe&s#*QQ^K_+0*69r1NzefYD*_QwIx~qqqg5Ml-kk?s4cBQwIvE( zgwO|z;8z0OlYr1QrMBF!?jr(f%V)wpIXwG^4dBLHS6k9JEO2cJO*Ar!Hhk!6OBzJw z+7cSiTwB^p$vR-_FMFu7XVAGA4Rg)MJ>bRgysj-drn9$P9aH9Y7bhg*oU?kp{njd~ zR&sN6=FN1`j=$#=(!~fXYfCa_Akf{+#OI34o7JQ_Cu>XdNfS)%t#)y6lDepmA6*xS z8MOE3A(ugy1bIn;x|#!^-wLu1x+O>+sO|eh7_?8215j%@0J_i()V|=wx5JA*$V}t4 ze!k|9oSoZ2g8(AYTL(pH9Dl&N2o0wn%fS~Z3i<9t!dMfj4vdN`|AZ`V%=K#XHB}G3;kZV=8;Am~RMci8jN=XnwD4(wjVHWz#@!|u%(~6$V9;$_ zoYYrVH}z$^=*xD|m+eYlTU**gZB(4AwkCR&YgQ=+YZGZj;@~-ySP7GjFO-rEfdT3@ zd)AiNM8r{IIHSl}vPqB6lHS-Hj7qDdYOQZ1V#^voknE2H3JF9I$_x9iUb|k!tj{iq z70K~ES4PH?>yDW33#0|~-5|RQ6wW+TS6W{wCcE@wGt>Pj{EKWRNh>RGT+-;|Es`(g3<>ac(K8C3+@u-R(RT;~=L1ux5eA-_>Q!-=f z+7jtmIfB+tX!%`R+Ih_@;XV>*kwCL2J_|HUZe)YxrMs>z-%{AFE$#f9gq^jeCAqje zL1ta(vp_2n>*vR0ZTXfa%C)7Pf0K#wu{cl`t!6@jemThg7M)UC1)K#!KN;l6m4nSl z>g#ZMB9w_ZR$Jm%Zrbs@MWi|+HT7zm! z6g&)}4;H~633N{aLf4eqa)-M22&gCT3qNjYo6OCU|LaX$jbg5=Eotl)xVD5Q8W}|! zK6JGu4We>w35{p2E$yXbi}g)m6AyLv3_2I1VXpbO2Rx;;sT=_PT9AFvc|r0(J&A#3(83`PK47sJ+39 zZ-p0qkeSA7%kvsLB<-BuIMtIfXlxvAX{&WAx}6ve+awta2k|okB@zhD(U0o0Za`$j zOQ3u1hxo2Q!XR7;VSG8@2E;E2#00{}k(5a%9hO%9BDJMMbKBv$?T{uzL{qhdMD($j zkcd)vYzc`X2kZy|^13DSdt{UCMG)tM{=yLavh61ca;?f1M4Aue1A6yHT0RmeB|!wC zd_E(T>(Ds!)O$(2*Mgw|;j?;eLu6=d|Jx^y)Yd%dn7f;M*MiI;F6d7DtG}hI{|T{T z+--uvtlOR)w{3A!Us>JMm+hi2+eKftD}8NkX%DrfaIV^#=vA&+r5LP@P3;#8H2~{qU2}BUe z3;VBLyI#etul$G&$?-i`M#hrsLor_t-3@3MWOsqWncM10>np`%mws$!y07KzgGkcK z3LGcYHMtAW&P%r)+5qion_YG1_}b_T9xeNLl&(_P2kaUSSymedp-BZW&`KBWuQ}t|tgw|TLF!fWF+6?M_ExJldJI!ra_Uymqbg%rH^?l| zkWc&TXG$cB?)}OO=~+2~)=y~pU0d3D%`4$vie*&uo8u4~J;6t-(i zJO3tOXKiUoF8WRoXeVfWubl;2kyt-JCTq*LG*PZC?fjcel#_dxl4*A)6zFq7_8$p- zl)a$uWv^udtBcgv;c`8UMA{@)bP zZ+}W{X$91l)}Y!F1y@7pgGKOlf$m8_=$cYnK9%WLVSeB6vRG~iX1{LN-F1zNLAynl$HRZD~F^ z08@LbT^yXG27gMAb_L2X(DNXdL94&yOA6F+fl?dv^&tD8(}KM0Ks}6sWzdUm0BZ4Y z2!oCYMlZVfgcsio(|wSc#%s&d8rvs*oZdL~yrr?RUyAG7o5{ipLulxUI~PvGrvyqQ z5SpVO)$h9jkr6L}Zn+=g+X4xLa3zHCWsiJ`2E^wDVglh~TE-W>(n*JCoJE zcy6bxrQHIfsairJ%E?CM8!jOcr7-rZB_xW`B_u#z*JOTC%xo_#o(}p8L-5nKA4R!V zqc=6Bw!9}T_XSEx5J4!PPYUHaG|oKro>%XsU}!-2tX|s?8Gg0@?b2v!YaVvY-Oc^G z_$@D(LtN0E_}}`wy85q*72|Fb3})T-?6_@R z6Rd9}V#^wTD7kNkYy(O)1N*N)?RpinK7t}vB**t$85v8ivtqs=kQUIlg6u9(ICEWH zX?>-b?9z{;fbL5<`yi6EvI57dx+Zr4+IeYTYIn6;HM{E0@wL(Wi!J+jl&(_P2kaUS zR#qDap-BIoS=BWv~g0Rjs$x8uDp>{Y=R$t!qo9XXOZ5KcVG!ZE5EtS#Tt zM7g%K^KUXyK8m+1nRaACfqo{){ym}l*$et^_F4waW+e4>xLg&=L>#Lv@hdm&c-|sX zof57s5qKid5d``@0X3wPp4yV+9}1?|mR3M*X$`6^QE)MYK3D`_7U-S?gsv&I&dJ)+d~yJ$_Ey`Prs3=Q=TZlLxCFaB|O(Fd8S)Rr(8rlp!`Y3ynF11Y#5Z#d%d z{ID!SuL{Hj!pC5;JL#mu(rw^w3Q&jUw!?FKRN5^tnyPgsqL01KL^O4si6RGVngHV^ zd#42KL4tS?w0_Z5_@JcdCsWW+?^C2p0lHJ%y9CNx5J4#E?+WEQG)_Bmt(_w#fWM3Pok;JBgg$z6bUUiw%_n~c?R zm(KCE(Z_na+#Ss|mog*>yM{xS)y6?+QUvdyz1g7CjoBZZMc=9*4nc_O_{C22V`$d# zivz)g2OPoCfT+%5Jd1u@+wfUjSBUsooujyxCmz1#{EuBEJtLZUPsr#QS*!2G&f6tj z$`%j?w9-ZUYtFbfD{Q4okb2d845M;#)n*^V6rgxiMUSeCW!)gNibFo_ub(NIF?9io z^sF2~>nF7QEXdK+iok&wYCyjzpwM*EQ-G57KWzIQLwR%43MfFWK?NuZ zo`ui{i{KXm-IIXOHKhREtL{Sriq0p(FI(CsbF<|C`o^Y4G1nEKG!6<}fI<_EjG_%6 zx&o92QMmwx#xob7_ENIN`lhgnhdO%(or}>hm!?kZc0o|z*y@*{yWVnjOc_RIU7XMp z=bY6SMb%1bD#e#K(?vT)UA;QW6l#Dqd(A~_$o15m%lGB`%1*rMt08H(zc5!f$ zy8FlVuDw8s4LbHY$YszyL0(dz9_9e(e-E+`dMZdBs6+9GS(ib_1vvn9AqPPGQS2P3 zeZh+#gcp5~nMwi5m04f<)7VuR;`GL;V^RiUm%v|DC^3F7kt34?GY`tjwm8xTW*m_Ya#Om-@rbXZ#X1!_x&=C;FgdsNyj zFq*0*B%+VKghVuT35jBK2?>zb4%xdPV0#h7)1dXOe&JO~(N7Yfq27X{wdHgJ^_oaHbNSk;;_^e*r5E*{8|6S~~HHSLp?&jXLAajTdx)c8se_vOB z0>QZ31cO<(Sse_zZHtro%Ic=RY!`jmF8Z=v>1%6Cd#H_ybJf;FuX4>Q#b9kBtw*;W7pyLKM{~_p3JJol;gDsuaS)mm!8>SgHt2L?c5R8i z_XTkXLR7~ucA_6cvyNXJ2qrw(Ef1mrQJuwj7X7%k;j_3d{_wLpM{zArJbcUfAG`i} zMl|uBkkK=;RI1eNj}cI;_;#T)?rS3&kc*96HElz#eH!V5yX1UUe8 zBnLqJNs=6>y}^s$3@`d1GmY1l*EDuqCON%vYNwPzW8*|iTWy}+ZW*ItuOwsPAig9} zB7x8x{iwd;21G`@1bXUzh#v?f48oNV#+NlWAbv$4CJ;W3q)a;Lu(a~WsVyCv+YZld z2QwKWnyMuvqL00VL^O2?iDGmK36R$#nLi?%Y%hYi7W5Z};2n~ppCrh&8vVppdEfG- zw7e21B|!wCe7-D{>(Ds!)O$<4_ky7T;j?;eL!{>lJP=1}YZk0sUXJzvhfqA0R2Xgeb6OA@<6?a zfo0J4gC2l7AdptjNx|qv7q9SQ7+&;2W*V<8FKKKb?VR2?wN1*Pv9a3H4$`UUc49Q_ zlw>R%#ODM`BoLaTAJrea0g(|efgZUZ;(G!KgK#B;@#Tmc5PwD>CJ;W3q)a;Lu(a}L zs4X3u+YZldhcp=?nyMuvqL00VM3ll~OGp%>OGtpc?#cWC+2qnf5SN11xB7**NQ!=v zAlIsF!O{0EpGwO!fl?Ag5c>auP_9Gc%v0|*_1+4G287S*wGEM;EASz4q_*Zo$K2iA zyB1^)aY1+DSN~UC{ZES(<8BiSX5IGexNVD*`pW92zHAqL*)ICBUFmCUOM9p-g>%)` zM6YtqD#c)JBCSXqsx2S4VY2Zhm68pC0qQk-)|S{r#8F~6qsUpZNsrHx-q;+BO6xaN zTk9K%*s{hqB>O#qLIM$l(!l5_>MX{yV8XQxpT%|Y zho99sifeh|;akrC*!9mdq73zfjGmFTdc8v}0~~J3IS>Z4(nb4g&bT%!Y^6$&dewXk zPhYj!$1t@e9#zq!Dq~qU$Sly1Py6dvj0@*S@wc{kiC`xvl&T!9WHl;G7-mWOZ>`BJD#_QRHuY%O9U2T zr~!RSKyB%yr?w>dzuorRpHf>|0kx$ysJ2AG%@F!v5qw*qdlC@3rqq@%<;hkJQCnUY zzSGh+nVTj5*JHWX@2aSF+nT1~3;NC3s{&o*K)e4P$Ys!ng1n?aUCsf} z-wv`5x*%A0--tjQGLw~h>Um%^xXXrKNLt9gexJ8FUQ@0_^Lom zAbcE2nRL=&Y2{a`EghQM4$p0eG#MhAswE_%kG+IMG<6AyVsr@!kk@0GAIK)#iy&?U zt?$MP@01k%BtfoK*@C0BWl!7-0;ME~Af)!HP_9Gc%v0|j^*#uO287S*wGEM;EAW~) zQd_fCjLF>H+`ATJ4sk(u;@^9utN(|hG43|OVAgF`2ZL_g;-tQ^x~VVQMPIgyzHC?e z+S<|{YOmp3wKdVJT(e3sSer;I5{GKbmu;AAd`YEbLtub<&7QR-HW6`@7|tkimTc1F zv!pjR2cy#Znqg~wBN1EH_?~2cC{Rcsg3yB5fA!k+D&}7Arr3}i-*aVTEV*up`EKZL zK;H?nyFlU06LqEam143>KQ=Sn4|4WFBxz*@jt|v6xeL(FOLrh`GFHo7I>*;W7pyLK zM{~_p3j2Uv!y(IR;~+FCf_Ko~Y|!b(?Ds9vH|zMtP8^OHnsxl*KrrFKb2lKWvl!2U z3D-7!7LOEvQdpg%xRxg#zUBOnUH?2Ins`sh=ovYpJ`R`#=~B*tFrbw#+Fx_VwOL^+ zRf5#3=3^L@ldCrS7^b$wqbhn-Wi0CknFSj1X@C7p$&9IMOQdJz2wFd(<#%mq=M@6s zJ`iY;K(i-43p7h^WP{|TyRI$YQrNC7?fjdBowcPUxwtz)W?ksBKr0gK=f`Ai`IaWi zwWXbZlZo=Nctly$WI}P|8d)I@lsn_0kx$ysJ2AG{Sf+K5&Te~dlC@3rqq_( z)V)hUZFyJtQA^uoZkGICg|X@UiyEq{c=iH>CY9%*^_Q}F$Q+KDU zyO*df$(TI?x2=}ia!qla6l67N&dJ)+d~yJ$_Ey`Prs1plTIOwm5*u{z=OC9s*93V< zfx4Lkpx+I$54tBv9;jXWLKt*NkONRBa{zR?8>qd(i|>XPeUO>PYs-5YJ10Y&-Z*to z%Am1vzNM|!spxiMG&GWog@gEIff5OX=IBTD9XB8{;w8`)nF%I{pA<+Kge%dHFK66< z_@+QiAbboaJC#m4EUo-LYDgJ^_mO&^215hFXZ6~K zNV^C=C63hA>=I)#cQ^O01(`!!(4F|Fzo)DJHPIM%n_w{OHmid{w{3A!Us>JMm+hi2 z+eKftD}8NkX%Dqgajx2$=vA&+r5LPDq!o!nwdFRk5+)m8C?y*L1JrBwtSzyLh@-@C zMv=2*lOCTXy|FnMmCn4z`bHwQtnp)c{*xIJDAf$?zXG-ERm^&mQBp{b@3}HEmRt|S z{EKaK*rpQfuIlC-h{$2E0N?gF&)5_6l3)pD24@wL&F zugl%hTyvE|g0O2iWLa$-geFDs4%(XyI^CFETcWQK#32Y#9lzL#ehkezesLg}@PH#Y z8W7c4jAzl0Ya2d`>*5bTt8*0B^2Ecpod2=wpJzl9?+F<_BWv~gX1eq&3N#%c3}~H- z_Sc+oZC2Pyl_2%1`4~p!e*&uo0uWQS<6t-(iJO3tOXKiUoF6d5>Sr_^&(2B(R z`7v2rzNLwBZE5Gr=!tXA>WiXkB{zrm zyqPZAsTWVl*K-k8)|O<C$N^CA-?W6i$(-3Ei%$it4EC-H zpb>x8(w5+>dHSm`t%T<5_CHlcW+}HV>Gr6!Th>$sjvE;iD&H`0{7&JqzzHG;Y?=w> zwI+KHs?hg{lj{@sa?pE+OdT5P#2u~3&Pc;qfff=(5M+U5a=jX_mwFGV_lQ8eAbeJ@ zZHTms;76Ud=6uK8-4efpPg)RG0~d7vy7&LkHFK+2G4A#r(U^7Hv*WfcPUI*1rbMy z;fx|@$tFEMOL}8-Fe+WFZzN*N8XuC^Ul%AO5J4y}?En8q-1`7ox!(7E=PY}#R=z8l zL}awG*EaDbF;mlqd%daFV`fBaoG>F2zvt{Z%igPvMIt(8YFcycwME9X-j10FS2!j$ zjkgu;yRLUeG@=O|)0#H4VrphYV`7n-HngG~S%$SM#{rrCK?|q*4J!fHY z?v3}(?|y&J^Zfolf8OVuvwKi)gr4QB?{JeCn(aN8Mp}z&PQv@mb^-jLvGuV|Fh|to z-WQY0diim9(0xdxNB|aT<^_pqb&c)*`6EyTd$RPJIlD+vk%xc zY*uEQ0O468Ly zTC)C}^P;M7c*%;LS0IkGQ~~||tb%`D1vt{!IYg9Yk15Y33~ZXDzeGSk{D;bBRgV`H zp`&zA8C_9h^7Wf}Xl`YW<1QaMFXPSc@}apEZ+;?H^uFx^XT%noj z1rhy`L%KqT0j|(tL04!D95AJKX2C+FhX{bJF<0oba=mWu=gR#O8Hl(}hfBW*`TzCZ z9g@UdeTAlRK@?YLc(RdGtPw+fg{DDPafOB_vbaJ=l&vdtMA+^8r3g@L#5ZAQj%O#MYsv?GLE)^EQdIeHfkn+gD-4N(?L zSj_RsckBJC*AXj#v&IgACn7(9jN66Ga8mHC#`b_6BA0J_%j(7X#Dm4#y>O(Z}Pn)+$!`Fs^IU+UeZ-Z_zE z0b*8f_-L(|>$SDwL@iujM&j;D4GBRvhd=jwx(hQKIFB~T;5OP(ooGi>C07d?yE+xZq@ z5?Q{eDw}C)hGlPg*dGcLHC?jA7GJYUXUQ{(OnR!>Io&4>WmugjJb=EPA%Tf zGH!zG19lA?niWET@GKFcgOAMyAC~jWDmJn+33GmWV9;}EoxovTvmM5p=S^Uih2e=T?!pme>nH-`AHtxb#W#YCdKeY7Lz;k=E zDS5?2@3ahXzrC(JxUuL&wYxA=e@+zbSXsHO-+n`K^e!AW6#znKMOiFi(ec{X^^g#0 zZ34TV*k{(jyvUCpxFsI|&eQ{NQ{ONRV3(+Q@Q(VrWxjgAZZkOq!dI_^JK_UC`0AC( z*D&{$ej%ypOK$^7eW!>i!|I^oF|=0k7laQ*`osOn|5xwm|9^<<19ahv@%krLgr`Ij z0q~7T)7w?qxNmj}bTMDoao$B$5T;z*3*b)dGAMRue=VpRmC1U z5ool-WiIPhLUPn*XJV(yux#NiknVYBi4D@L-P~+0-b>=WB;GjXq&l%n_RosCokajw z+dA)D>L%^Qq`erl zUQy#}jKEZlZh1qEn=t}YHM->;HSWd;Ox5U?57c-VBQTG>(Jco`oaD9dB1uogJC{>u zXJS=yJ`qK#O{SK~b`C!7bXG;O3tTpK0NfDy?u2{b1Hg`d5(97>wm}B~XT$UMGrpG0 zP7k<|cFy%O$`4*=n-S0-P>+}Gy&c}?nA3AU0@ZKPT~C67MDPUPMvh z#1+}!WA+yTT-kn3+KWkhi~ISyZ0?XDW)z$;{>^fiaJR_zGfdU!mUC*%#|TW-=#~f6 zI2a=^RYN;ajinfYsT$q#s2ay&1g2_q%M~?F#t6)+H?-5mJQ6kbGl_Wd8~b^to`@pV zrf5~RYTkdO{Qt4p1r8cJ0G36*JK;|G0C1@ufZL;OqNhK=etq74#@Az!?nb~NGdTpp zSFeOS?E^sg>XpgYF!#0je%>qf10rS_t0yZSL)R+)x^VjcCZeU?f^)y`n-yF$es2k` zizEWzdvrhFlbuPkQy~92lP{hMK5XSFQt@x9^P!JNr*@pAW<_K6Vl|?@_b)Z~^W!S^ z(1}2!omuaMtXm1mQJbBK1Il96!doEStIiS|G_s$QcrS_flK9AeJ}CQ_tx}5su53Ri z?Zu?M#r-^xp^GAB8oXruo8?vEHIeOSn5xk&Z>n)CMqsK&x4f&yy%>S18r|}t8joTG zrfPJ{r)oTl5typcEvJ;;w56yU0?ZC?bjy=sNWQV3NyIxF`*}lhJ`qK#O%e0k#N+>` zo;f1f1@0I-03M2bcfw8mU&suAd65sm-Lwrl0NAh3+t2tqCDMKd?ixD;!dI_^+it#w zK={%{y!JKBeQmyKq(JjxY zaW+O^sz$e5Q{zI6z-)L!J6(xyw~A&PlSHV9-e-;36He??mrq2IYLlsDvYpA_QT`(B zXW+Q817KC;yAy8R2Y}o409>Ihqm2%*U!S+1@wG#w{S2Hib_j&8UI};62Y~R^E0eEb z?rZb?JdpY^5wncd3l)!{`xXB{xc7I7Xz7sP%0u6*;5Fm-mf#JML;!q`?&pq_cblC8 z`7fG$F)P_05H-%=M;e=Mc20D5sbjxrbT7t;_THZ6e%>K}#2z{kXtZON+0P;CRzh;r zW@qANCGlPoAKA~xW&e&y`x(HM?dPPun6$UJpHIrrEfF&f z-ZuWt@}BU%$o4Z#)##Rw)OZ{tFjb>lK2xJ(LFtJKQ#HEfv>MxE1g2_q%ULyc#t2N+ z=$3ob*c&4-^WNx|7sQZ!V{MR#cQ*F(P09I06sb0w>}Q|#neWisiXvGDE*m=pX1+7t zkcZnX(i`%?_Ziy*=0(*5TikgY7y?)70l0fU08H!C@aE3<&xYsa@rj6;!QW*OJnBy? z-XmuA_z4ZI;>&zC99q#1&1g5ZqZO92#0kSg#N+G>EcJOy z_l**~X#C!i(qVy;n3Dd7Hl^@#oRNjIB26Sf5;|=6O2_A`i1||QLG><)BnuF;dc%j< zZ~;E3trh2M;d;NtXSvJ%{-RXMa=vmh}@y&*nj3_ekbEOG2v zc$LCsjBlpBwHh?FJ!8CYCF9TyETs3drdt4RW)Sf!(Fi@uS@#2pqS@YaX{5Ed_DlGX zNNT_j8{2pk99NfnUra9R<;USc_mWp1V3B5CkeE@|=q`v<^}Q?_ug<8^&i35sAzz8N zvy4wh*$3ADfbc94qJxjkmT&0%!&_`*XA9UBmaISLyr?Q1Ub1566^J7(Rp5;mR)8aookK)f_L%ZqUYMkR(u;oh50%ZT z9-j?|j?zJ8bVZHH*FWhE&8^IFd^Q|9FXPQW8xGB_c=OMOUtYs!fC|1$e6e@#Nbj!c z7Qk1G?VV9k&x%-Zf?qVYvDKMz_c=VOQD0_eCd$TEd#YCUB4B+^I^5Djz6V*N&X6mnqqMZjBvU*MOTd$NM>8+6C zfgf@T0HMpGES8YWaqma;>!ud>~v?P<~eB{)s43r;%h0?Fugk)QNRtAP zgr@$Wz~`%o`BLu@^`0<+0w8AfhL6^Yc~)C1F4e;IWhCyd)Q}K#b2v2lnqJpQ6z9<< z8QexYsuS%f%Ba0GyKc|h$)2~9J#T0Bs=IJRs8vjG*}P&`r$U&NKv)wSh9sdKwpOL7 zDx>9^1&KlG4ROB<;}ez0633o}S1DY^_-5K$t3gxS*EQa^l5yw;9+TcLn{ENPnL)&_ zL?iSpXZ;q2MA2;Txir#RTuTx@Dv}l8M~$t|XM#DcF898eT-M8v!-MVz*a2Vh&92RsJ#=tRCdS@0~5$PcU zU~9}>__AEzF!yuiQHh)sZGIO<8h7fs#picnrv6sej+K?m`t3I) zNAJR6Qvo1!Qgk2JW&*D-^i(_hJC0PRQkH^Iib>RN%mZu?2A4dx7)b3mmWz21f-%BsJj6#umVgh0=Jh z)7?Ihr>E`|m^Yil`+_;s9%A#Fvo{28zP=q%+xVFw5Ye{I`@dQ4knD`e8ZdiA`gmhS zaN5}7f?(a*ux!#{&tD+uJ!8eSCgR|u8Y?1rkmR{D6BZLdf9T^cepaPVs+uR%n8a!> zN!4fOxf4hMM<>u7U_6^R_cMs_w62H}KbjYujF}9*?qza$^ zAX6ojEw%9ygCtR}03u(nY*4@u$v?$Q<#X9vlGnFo94TRbTcl$IAP(!t$g~P&4VZ7W zW!D4P1=b%i<`Jkc5rEi`;Np^E+?&OiCYeQ&WX9(a3kkc(zPowk5sc3RzxU+#zDTP9 z_?ofVQ}C)fyrlJqT<^DF8OUn#nsxf>NPp=%UH6VWe>S9lMbv)c(0@_Hqv0ny-(A9E zw()2PWlh|2y{{(hm}5ShyDergUqYnr$KsaPg^Oc8OZye`$;Qd8vxHiEiy$&RmQY9# zZS3(pawhO)WMn?fWS(TCb4MHXuI=*z_=>UFBy;TeIZz*EMX1N_OtOxkscc!ACw)!r?)!Z~I6YPoQe7 z^5$dV%g4f#x6FzDH=&ZT+QNq(9$}J4N)@fxP!}7zTwWrYh@Yonp6@tWk1iy=6>?-8 zHdXWx%Id$(o~_ri8isBfkyU((M6v>W!r1I7t6w@- zmwR7KF6-sT;X(INuRg#c&AcG7OI@S8AX3$z_i4P^s-vClxzTT5RpRX|TaqktP^j_%4pg;d z{W<4FRpIcG6+5p$9BHWn`ZrZxPyvoKb`B9`*<;Fc2?LuZ>F)%hAO1sSv#Q5?hoPf% zP#IlOWAgQP0z-2va~$s-hR(})^Y;!zb1UBby~CH+@EM?jFB4zvo%_;zV7dkHyTK_x0fA261@ZMoq(0hj%ST?11X2D}3JwyO(ja=)ubvESss=1#lmn3pr)V}2Ny4rt` z#$Em1A&o1dc<&INY~&Pc#8AI?NQ126y+e2+i}wyA%EoJl6rtWQi~t+&9X^zaPU{w; zciEoXn@!0pCfdHnaHW2%JUSMizl31wuV?L8S-Gq(y!sqHB)t`KJn+M&0zl}RD2pW| zbG-MbbqRKIIK$}j5p7l z+`Rq@N_IFX^nU;cs#>!Cob#fpaCpgzomU`^G)#I0-gsdJIMUcTL`2$E_L%ZqUYMlc zY|#(@p|V-k<1QRJN(YtE6*VSbzuAW7R^~YF!lCmr-ux~cnp^Sacj1@U@EM?jFB4y^ z<2C7BFx>(ujqM#$Q40|ZPOxBXW2-ac?sK?XqrS{qcVTkzmC>FhRI;TQcVQHcSp)^} z<09_7F~!`4nd;X?4r)pzfpT>cHN%0 zlRa-IdzE};Q1+_3a73t8OmM8^YC&U{V@yDZ>J4ki#t+4xI98>p%Aw_&1zN7zx(nkI zl{(8xC)(jM+TqJ@(n))3HE3#gI-$Rnj6*kYUQz$3NQnX@!MaE}N9Ym=9lZf7F*MtI zE{(Jn*KP^Vne77jsIiR)Twqi9i@ZH=!zPXuitD#b1QQkcj3@^8E<|U4$ZB2^SkiNYxoRM!Iz0I z_RclwT{qnV_zh!wCsfoG5erW6X=58(of&tZ!$TVNW!Ab2lZ&s6_AH^2EycJCqj1(D zD1cuQap#RG<}S=s|9R2)yKorbE*utg7skN6DZMib9uVmv0$^**U3gWl&zt+Xa!w)# zMVsG+k;Ywp7p8Ge6n9~GvXN7)5kq|!ra@M57ltRYxC=*=t-EkUs0(le*tiSdkcoSu z{Ls>$n?AQUo03;d^nS|#_uE^_gBy!ZRJ#i^^%q3Zj+K?m`t3I)NAJR6Qvo2fCdy(7 zi;n01cYVK&NNW>#YU}`*{#yJFA>1C3i~!5^0NkVh!v+Ap8>D&gj`~_R2R-1Ku|pty z^-8!ok{J)RE=(VN{!VRfvFnZ z@~j%?Vg#mY=-WQjSdS5ys?jYksc|_*V5&y9yr#zW7=gLz4SlPK5}&h*W|v43p(6UM zD`tS-9bbzzrdHWe( z^CF$4zS3Bld} zjc)yOlEVAO>vt-J4@D9I@IAVpcS-q>*(s3!n#mXYCHqN{YTK!QwyR@rvvZ^!fkrz#PKXIvw-S=0HudW~vUtMxU&76v=@{17WeZ78G0;Yroku1zgc!$Xx@y^D6 zek3`ch$7V{TT&XWf3AE*&m58L0<-sE2f$uY_0m9G;RC>GJpi};tEK_4U!S+1@pZ#| z^?;pbatMU4UJ1A413>uFmwu_`zJ|H4&G+-96lO%sGFA^&JciC!{F?BANDtr6|EfPH z`A5E4!IQ@8BV*yJNFo5fNB8p;*|=wR3gmyrP#7Fk? zPT5}*@rNCiE8EXWdogKmaX;^op;Zwx4W2gs&GMY^yvUxluB)*TBQRB?TV7V< zN{ql%4edZRZo~*o)##SD)wmNQFjb>l-dE#6jKDndhIYEDxnvd1HYSNITjz4jo^ax{ zx_lyvRGUmKlkFV3tNcaU&%hO92f$5{?@qXfJ^;-8&oKbEW*c+>uwS3IpYgS9c6z{7 zV~0Ta>XmSheEvtc7 zlS&2=a9Si00NzsjqQGosPG7$e$yf4{k( zm*tPxLni`_cDQ6ehpbx($x)k~iOaJ1Na<_mlI|{xbb;8Qk^P*+dr7>P#7Fk?71^IP z`-=dsY(FRM#iYH({d`?EcgPUa1H^Ks-YdI z#={tasT$q#i5gF11g2_q%Soj-Whv^$53}7H+Ua6Wi5mB967k|U_VY!_`9u_{HrbMj zDuE~df$|s0E^yb_0q{uVyAy8ue?Vpc>=XF_+%?;v1AzVdy#0)?Rgv~HaL?Ew5WadP z+z#_K1j1LZOumM>ug&-Kby>P2VwSNwC3El?I#lt6@PbGW->ZV1N`TD@?lyjJ3GNk1 z1i<&`em*Yc^Jb?&{(DWnI3xJHv#I1u>Nwf#oamfW$0gC|UW^g#z29u^=T-S5_Rxty zqa7}JK8LJZ3CU5LorycLxZT2AAl-w`5*swKpObhmiT9FtFQTY$;;!uP|7|QS0=TmM zoU|8{_F`y1e?LEv&3PGPcENqd>$|aqheWoYVXB6{8(WR#7=fu8`fhABj>ia0)zEii zt8pquV5)|`8(WRDF#=OH^xfEMT!;~v4R7eXv6VQZFqDZybWIsp6 zPA%wn$wjgcJTZ0voE*eQY;b2q+SkBZJplKsHc$Xp>jAhMHZTAl)B|u&eE^sqhL4D+ zi9~nFLh1oTIH5mc2G=T^y%O$%+3W%9B7{Jqn$RCcgW+r3Nr0cTqHd=TctI9&H+^&C z$u8vP`eid@meIW2Es3;vqhMk$s^^mR7FPsUU4Z)B60s=5Qa6~+6-9%!iO!qlNg?Lo zv4atK3}FQxOHV64j3jH(17dknlJ@t)FyAWDi3{M-`f+(W8Ze&`sYn2!m{7!GjR?jX zL~}31V7@An4}d65D1u61M$$T=9{wZ!9uHCAE!yEQ+TkM85RH$s5VKrE|b1xQDaYSyq=%b z*~n0@)hpR{^plnb!BX({=8V~)Kk{{rXn|-?N?R_MOPFi}V%7Rjia8w(m~k5rf17Qy z2caCUBM{s_5vi^K9!FMuB+|UBg@uuoj15(tm`7J~*vgh{7$TJ47wOa-0 zVp6UbFstvDgm+3J-x8zeC{kIbD0o6)wV57;N{0PNrHc7%MlnNnQsd+15ntAit1VBF zTPKF>n81{37cpmL)RFSSfRTwG48OYpyY(#x{Hh{J6;7vFK6N^uGMVwSfK2?n`$@U= zEhj}FGn%7Wo2LT!E@QK+EvwMyu|9hE#mJTqU#sKPA;yzq_P?2R*3q&5utol9<+tUMiE10%0s$zbkOM z$5PFwRmrL-L{$T80$*SuSX#5i0&pkK2RY4HG0 zjU56H)Z2f6kPFfoSwdC5q3O>mCq7={D}G zc~xWkWRKU*1ogDy@v&cq^VihAD%&YzVM@}r8eu*p(pmDHF?_VzCCyM@13>h|&5ZEDti$()wHHN*k#~JJO4GQ#)E9ma-`%BQG{4Uvdh` z$d&P*O(9t{r;r5sxh(g)B+RD9{N+EJZohsRNSX?ES7x05|@Cwtz`>`|dCLhVO_%jOlkT5Dla0%1*T7?Om{+^o`M z<4emm3lf9W8{+RbhN_?vS>o8U@G6DN7~f2LYc*(U`<&o?D;bAw;F|QlWV!|5W(E|MA2;Txir#RTxTSFUL-5PFB@AwBMIh;y4?F>a#=4wjsm*Zz4`!)H1mSQ z5p|930<80+_c64)s;%l>d1rfW^oDFD-p(?9F`IqBuHj&1wh0iPB|>!YvDxy&*N}_`Z;>Qk09C7Me1I81!n66Go7qI=ZvdXMR>^;NIq+E43D2ReVNuK$1uN6 Yb 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 z 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≶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 dq3$(;@`ISbD3;*1ylQ9Yqa@KPVM_keFRhc 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

    @RWa>oZWH@8Gj&)rD^Z857{bBdml}4O4Huw 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

V z4#+2K3C81ZZ9D&r?|iRZzr4&{H+&w%{U!ZzcM19<-U;A7ft%ir&Zrn9^V|ES|2v5} z*4@J+oOuV$Wd6U%@21J#b#A77-Iw7B%?|ykt_*g4Hk30Z1LbH}GxA0=vIc3R|G0s=bURv zFCAB7{ZamN?fA{*`#A@>ze*XiC}T5apeues?MUAebXSq>^4Iv%1Mi_ed@}SLNWT;G zc`jkc|2o_&a9`oz1E}u-!lF9Pv~|2h8$S*0nO~-kQPgpp+PN@zinQQt{fcb3ZWATR z@0_U>ShJpF&ogVSm8(7MV{2~LulHHI@6p=zw00NNN3wP~i^f)=)zM$x{x$xN!v3@0 zuQik(m9>U2tzGsToh?3Vm;P{n*+;J3)XKVzvu=(3Zo|4A#aJbCXL{`ie8y+Z*2`0& zRnFp?>}?|alx?{1)6JHzYx2G8ID;F)&$Alvv#kL?Nn0mv9X;(p^jo;Ovk?YA&^HYn zNV){+^=@lZS@!$o`jz0?-OinUZ+?q^Dd7gU(hv8yqlWUMvK}Q&xYP_T#psLhNw|a_ zYm@vMv)3`W^!M=B2v3;D>)5Ma_X_x7=ov6$blpo0`0`Je?WJdb#T*RLGs@R^ayNZI zc%$FK7unbh!Qcyij6xi#mg}F6@T3Z!I9q(?D2&UO>z^gR!J#~H=`H?`73Y9kUPz;h z-{bDEaLhyR0F6eU$b4?^U!Sh}qR|`jRsV7Fe3p8Ik8uawt3KS%8yW*DBkn!ie|ffC zKRH+zv}7OdcgnXy<9GJAfunk_CYk?9zXPt`M|$Z5Wam({eb-+1B1=PMZ+w84tj)4` z$(_>{;qV@CHU$k#A#+HtaXEe3`Ve&^Bs4Fyx3Fg z&2IHamY?WfU*76pOr4r9Gk(n3r<6Y(=3nt3b5-D0(!*^G98+VU32TmEgv;5Bf zSblRbi~I*T*zk3;cJc4UUG3n2YKrq-&Z3mZ>8ZIXd@mJO^1kiLAd_Cn`6vF6PUKvS z_}aHjSm6lL;R; zQaYrb+6lyuApY+yZu}|V^BA9pbay&`UC;ubb(|gjEzrC1k}bi5I6mRWI>XACXps>)3lMMoiuIL9sM2XP?UBw=|<*v^k?!t!2xz0TxnWpmV1(_AFf2HK^0$WVU=?P#ZMqiI7l z54TYN=d;kQ?8E)5Zqps#Tabm;2IJ;#>u;xS7yNayYdIree5%`7v%vUn?Whu`vB+!O z2rI8e_qVe@2`+7+O*6Qgr+zt{kDmvQt6!V)xBCujaeSFRIS=|R`6tXAtfznKSC+EW zwQiGn;lnAz(y2`vkCTaW8Iu;)j>f=YeTW`7 z)oX$i(()ho6J+U!`xn#3&x4a$&am~?uyAtR-0cP@MWa-f##nkf-jrhAMXR>=r@^%^ zkoS^ZCz$=%z0vu0aa-`{(D^p+9&}NE!}&IQBlc#gT25~wWZm9uLh7 z&$sa{SafUHO7>jE*-DFB_752q>V@%@4nMyDyN2+5`)JA)%}N$n#})h)HQKU#I<^zDfuETYarYedR6zeT~k#Pepew-M?h^bdmFB z=DBg+7d4zWYhMwaH-FrY51aI%^JZi|bKX1xd}#)skGnoO$Q|T?<=OB&U2{5`^qSMR z*?zYFJN*QC!Z}S3pVNh`JL=A$o42+L+{*%&?AbQDWz8*TE1g%-2I-Wec1fo^`d_3| z#zsIoW!VB0megcBta&wO;LL4w4yid_N;wCVAK;#N!x^~e`6Danl4Wx#{c#DK%f>VC zFC)7apzEG&9}n5DE_sS{$L9DC8bL^_vrk#uF!k$xXta&g}? z^WV}XS2zQwT%*?^e{^Q9^QxwzJp-qnjg|i)XW*P0@(!DS9P+Hrj+)Az|GUn>*$1rs zW1oSisPn(-4E&eK1C3|kobeAV9}zQW;Lj5$TG{HO6istFhWA;dS!IH8!^@ zxRiML+n6goDR%T*fMriFooKUnaLp;;eEa9vVwtgy{sPv0-0t2z$VW-O&(spAB2r5Vp~VK{$uXyW57Xwqe){ zne*ZVs4U2~kP=X9=qUj16i(_A^uQ^^?lG+!0xDNtk8!ClndmAmiR%U2`^78l_6dHmsI zPxo#|rjebNe8tBK(`pmQ=W>1?&S&2EH;eYZwYYs zy@d5TuleWNF!Y=TKF7l7ISqW4h2Lr6=@vfL!lzkyoP|%d@EBl?-#;)0z0TAAdu_OI zZ$0pPEPN>N2H?pSJ_vXt@H;Jh0PrT@V=deYd@t}g3yUY+4?M=glFcgaYyLYdj6SJz z#b)NuyE$mn{26=Q6=wdVw{i2Q*P6X_Et%&X7RFZn&{}y1-$tL2qky$mRKI*iCi!Zu zoMzVJYk_O)<4zp;Uki3$8m=Ag#2NTE7Dm5q;8!h-y@G*%X<_+ZQvMe#`~zT(w%krAGa`f z+gNk21zRlqO_M)d6YoVn5IuO%#(jl27kcv&v=`hC?z7>-HS9w=*{>5`HulgjUHu-% z<8L^<6FnPF@46c3oz8DW?;hjJnU0}(U*Naa&{n>UG%pLRc|69%FQ{kuiss1{RP%Ts zU(KWDQ}d`bqW=7~ZFeuQ`lGPV*|2Y!u#gUZ#)f^ZA?%Yj?DmGRkK3?Y8^Q`U?8b($ zi)`2`8`ek%=h!&WLF6Gr2hXu#%Ya1(&$4hgu;}1)3rlYsEIN3Sg&BW?f1-o(^SM7dxb>GIFRPMve{>L=o8O{?D}E0h?4WMZ!4sD!2llr{ zCs0o#Khxe$a~smX1(yCTu=FpSTj6BP_DMMTK2rwk^e@77dZLAYW8rsO_*DxZXW?I3 zIBWy!)WXs)Xx%<%VbNyIA!liXKONLf!A4>J8%ZR$-+-r_y!Aav+#8m-fH15S(tU*`3ST{Jf_EnVM}j#%n}Qu z3otxpk%jL87LWO&g})0d9`iRAz8hFP<_i`U4-=31tcAY;EFSY|3x5?@b1h!;p8q9u z?pWLQMmjgvhBeZ;BWzeBo$It=jdbo{8`enY(l)G-&b8XG{n5FEjccTHdp;Si&xp?b zn}s7f_bUrWbZ(c0BRcn@g(EsQXyJ&?^;`JO(79`0dTZ(2qtq=r_xe?DEuHJNeQKn0 z-?Cv5o%_0lBRcmL3rBSBHVa2|?iLG2bnZqA52th2+3-d>ceM?R=vD>ElSVZSev~Wb{-fiKC&K+mrh|W#0a75>hws1t}jD(_b3D-~~oqOJf(H2AJp0#j9=lU!h(K*k;5uN*q zg(EumBMUdux$QPAqH{m6a75=Gvv5S`9uuG44r!k ze?vx3hm5OpuV~*Y-?`vUX9{1qV{`ZuW4}6{cXDI7_3tq+g; zBL6Pt%q*7YO%8OAD7FUV!&-We-oh)sY;@XeS-+-E!57%}zhdD<7JkXXt1SFH@I$&o z%^5XqK$o+EyVnZ?^+|1rYA1L-qpx6m)mrWJadT++aJ%o!p1f7%)hZ=5zqXBg(IH%Sqn!z^V1fNc;+W9 z9P!LgSUBRDAF=S8;hD={cx!p)Y1A#A`RbClmS?`x_DQrn(t(V(VG++9YvG7zW-J`> z%+VH(cxH!%Bc9oA;o&@Uqz!N6nImji#50o?j(DbP;fQDMw(BY4nZL1c#4}&DaKtks z-u1`knGx^OI7d2=$8Fmpp1H-s5zl z%x_sZ;+bE!aKtmeV&RBq-e%#5XWnArh-cnt;r|fN%$0rNO2jkG*;YEHa}9V*ApR#G1tW-;9|r02rN6yGe670F z!!PIB*e60+MrnaN=S==>ou=sX4bO+``Ao_fl7X==GG{w!r=~d?ezqe%qjtWHJZk4j zd}W`n`oY(=^^d!Q;+qa@+RIXJ+MX$Kw&PUs$4l#zOM6%?e`MzHTwM!b;~~pzsDPam?~E4~@ObXZPrLpk6CK1rW4@!P56;RgPucW$KP7oU@!U%vf~ zyu{pVEgv;29LrRJb4~7Au-+NFx#nE+U^8xW>%!|5yy4>DZ!kQ&;p{ED!uYL!mz^K+ z4>Lan&fcQ=$vd?{+OGLIhIp0Rfo(B%?FPU0$~fokBjfzk_D%AEXr10kSq8oFYCpD9$%AHr=K%OS%>Of%E<^y*I zB>yZ6(;9gP+!#>1zGC|rj`8_*?f`e1e0l1#?bF>K>D|@;^XR|w-C*;LwDqo0zOFKN zwXu_-e%g)9OCDR#xwf5Ji|Rji-<`{C+)Nt>&Y3<)Ug{=}eoKcsAe%tuYCz+&M6zTd zlqGw+UhySU&9?cQY}ubDe*&3T<0@LId>R9#{d3#yC@pWr4E0xegcHz8llEv^Zp@Y| zIZtoJs9h>g=T~~0Av(Jn+5_amJI+J&OgPP1J###S)8kEm~e=E^yd|`=XucfmHR(zeV`-OMxTzf30R1uieLa~B?V z@9TX3V(xY>!;f++`}%S`lw*Eu?se_;Tl!A;kmPZ5uM1gTce~^t;(WsOt{-=R+`GHh zx~-S3Ma7t}f1dElBYG2Vo-e(x_Z~mG1uNU(E=q{JeMVkE3ujz-$qx-#0 zRo%x4eV6JSCxJcHT;kHoo6gmg*OcwyCxJUb@_!mHEc9-p9^KVPw=#6+D=R-!$gt9j z4EJxkfUsk3vv-3^Ee&^rE|3qk7QH#d9?#tUx^rhJ_k5ADdI;ZLPNu}YN%;`VdXhQ6 zG3@TwQQSE)`@zzP+B)Q8jejZf1y;spxh$LI^L=bL*B0ll3yQ`U*y`Z5e+y|KdwOJ9 zbX#3J`;VY4(O9nkNH~`58cW7Xa#S={W-P~qW7$HUwkl)k$@gUFL)MIC^=fRb84Jl^ zgtM=loJwEK@9>V5>d}~JbKacpt-jASA-(tiT(HAe50gsIzWZkcV<`^HN+8aT8j1NL+PjtU( zAKzZ|MZUdGcxLzDvWELrk&jW`v)Z5L7RsAtr{0v_(JX$Z`y@*; zWw$rI+HD%O`cUygC(~eWk-^>~v+7{Zj{H&7@3h=iUG2J? z!!ly&r)>H8`Xa@pSGloKt0;fI-m-OS83w@Ryuj$;Ao#o$+A1cn81~i_!cdfCE6_$7pf97F78q=S_ zgEgji!Z%&p4l`DH-T}xjj)`yUE*o|i1H8}csjRI>Z1t}P*4rFv_ekz<-$T3fz83nx zof?yZf%Ely`ATLOX?#E}sDG3%Z>n-vY7}>;z=HI`@rds(%ccv26?*xhT-Qdl9|68;_Mp-7zxtsZ&FJHKwF1~de!_W)=R@klk36nj@ z@Vu+`6ZRz=rgz)Fjf|G4uEr0@b@>0_%#b!LB|b%1iZH=f0=EI{ePY2^0H=Y|7XDk{ zcHnjk{}pftaEFEe5_mN5XbXP^IKwz(Y@h!ESZ&dHdJl7?vEQvR=XY2i}BSxh&W%JMd3$G@1`>c(fRFc;U?){wR4d7XR7WD zuxZO|e?|nGIhyTHGi@V2b9X?yd}IRJx;OtRQF@#IZyl$?hhsHP@-}x4g z=UY6UZ}E7(#pC(b4q?8*p{agf_`1$@R zf|b5{x9R`M5p46H5T&>Ivk`3bPXg9{bfy{C9h7sODF>fgo$H+)>@majekAaQ>JI!V zg*5nZ;Elj(6F=YY1l~mYcANhY;Cq2PZ2kj*?s|fee!$5;GX~wt$S~K&`TfN@HzK1 z;j!xWV0~tXsrN~x1Kwca$AJ^T8!e2Vrp_erCJR3d+ys2Dg&zQJ2EO0I_XDTsS7l7t zFOAWowrk0BfM@HeA6(PcZT*!f88+nOT*yh zg4v50+Ue~GT>7ao#7`4rxC33!c0<<|0>^V2$A=jNz5o5hWPMgmaq5TLiUlBERX5ypg~7t#J*R+*GMDUS_&#;@re8*vH{U;-y2ZzPt1p8udH>7^Ht~7?48cn8yo^jc z-=7-6Hvb2r^fv$dBG~3X5je(}&fN{)r_a64lct=k!hzSPpET{51RQsE@TT#TrXAyf z6TllyeBK`mtTEkW^JjoHruW+Xqk)@Af4|M&0i2>=l~L+v-i+x%jA?Tw^X`Kt&vYd-Jqiqbo;nlX4Wf=&E>7ht{F9n!_T{|xX(;BZan{T;yKHKL1}!zX~nYoay%&%pPS zUUX6I{yuQU-Q|aCIvl%)Uf(kyJ2UMA<%=#}#>Wu8^g8seD)xA>(!RdNPA-K0(Pk8H z(HmOqiJqqJa8D%r@9WXay4-_dFUB4U8N2Ix_-J1KHd=D%CO>-o8^%UKdk4iUu1UYW za$PX`-!`X!Y#Tqs_)3-^;NmFWxXG-nox@vY>Q|cj(hfcd@k27Fv^r>tzrD_Wn0oad z{p|Yb>`U zwf~$%J6rf-r!z2({d2C0PdOL+&J6m}GJ4wT%HVZu|K*!+L`Gv#3cl1Hj)h~!W^wS< zhW@Rx{X<{dlJMwX8vmW~QT3x}lloVtEcNeD+dtVunf{gOAO7^3;=G5^&_8TCP5-uN zKU+kX(8W9PUB$pD(4YJn^hfr9-GTOF>d&uVePdANu^(eSFY=tsvS0(h@3|?|jXO?v zfNrGoZwMQYZ@uxfM}0ctHFxkkguV9E?!gu4J-m}AItAXZ%e;4@b1C1_@e`dHeCveE zek9ga_S?_F7t;^02W`VQ@Qd{8U5uMocH7W3I9Ys1|Lj9Gy(>2s|B1go9AAm(y(f7q zgYlV_fq7$&wKC^G#+d!Bd{)XY<&R_d0m$D%THc~9t`4~4(kVN>vE|jlshU@3W$iP+ zNDihLd;OmHQgZOvi`Cy7tmK24!dV_auIZ|!xI z(N~lg$JD2PqAlvT?B6PnCI>r6vpff_$*x5Q74~JT-Z7;wtdTnt*%@B5cTjD4w#U-* z1(p}?^~DqJffra_xWMim78qU_?i=Rmo>7l{Zuh2lF)s7u!zF~F=jdtt_e5}2w11w@ z_=fS`F5VTN=W|vT!Wr#D=1JDsr@V0%*1Lg6GH=>Ds9er=dPK`rx5@>#e2}3>dk2N7 zEbO#KGy1_3-~_fw`>lVOCJc19cy$K7t~v;)4XqjH_emJsx?SJ0Q3;yfEyA?~oVD07M_^WPXJ zx6)ANM9Qov-$nIT6c?4LwhYpi>e;5u7Zew@MP*K;%(U{&s{h=UsWURQb*lQ}T^F46 z7;UP|G-dw_X&jIDK?&E|Gwmh6(yNRl>%1vb_P47n+TNyg#F;W!k4m%E#68A)VAln) z{PKO`VueMuhlr1PkMWi;cJjmGxmQJL40CZe1iD(#3zU!O?+}#e3E$PxhF|{ zhVgD17T-kt9mF>iu5oAvcD>VezpXQtgP!G91~-CV@(C-Rl*!x@OoDGG%HSn&CqNUI zY~3>`+Bp7&w+3@+ zI@A4t=XmA%=`pAChM%phz4WE~o^2Wh&Y}xi2%TxGL^wO!;_PgTv!VV?`nC{fL%mxQ zuyD2)T5(dVa4*Lk&98ryF^F(abf*!YIe#9)A<2{{J(dH9!nr+9aZZSrrcB|pBmBzO z(UN_l2`Zt1NJKgVG6S8^%Ml(DgP48;OhM7w!`$oW;lh zoZTF3B0fGWUO3BM2b|p;+)I37SiEqynfL_p_Y`N`7#54mgEhL$ArZ z(u>6ptWWb+23N^HXy(U3k#mie&_>A?N7l=uT<^F8U2o)pG30^K+;vTO*nN9tu5T=; zUrHXGi7X(!(eY=N^WMbrn8r1gy(!RI_{kedV`t?QZi0TFS9fz~)Gjfy!koI~aVNJt zc#yJNowEPcU2hClb-#uF=qyAy8iTG^k&hy}J_$Ph>yNfNpR;uRCw#?sKl{d>I}>T~ z-BGnxXgItL`u*npdcBLjgnFWRK02%(@wrgXG|%V#z7U3{ir3AHVCabW?70!_=$v4l z-oy#hSEYBF=bsh9@U$6k?AaOWndkYZ6K-_O)TMI8XVGExNROoYRTes|o^%y@Y56ER ztRCr^#b?Dw(P8yS&n!NxGSFf5NRK2wtNiG&dNQ;_d{%8458TLS$D&s<{9oBt(J#7{Uw7)Zk3Dn7FQF#aZ)Yr5zW;o{?w%+-ee`!?!P zf3*id_TRx>xh?OduZPoyYZ=GUe3$Wcco*2seXzEjxN%SLKIso8JNfrcbS~+d;9SbL z#GYC<12M)c!F!}BbVGA;*9LB^y`IV40>6W16^YBDPswYoKzn29`rn9ubm^UV>4;|4 zGqNw(Y;;xiv9d4V4Ke(6`=1BLQ{HMr!#>MzjoBB>x%pHtfsPTJyQ`VACY@<>4!=e5 zEtKtKc}t!>XpFVlhMq@yC(+XtN3IK2@Vd6tAPx+5M}qJ?M}IWG@lNRzi2E`tUoEKhz3srAlcHO}~W8-;xd-dS@Pq-^L5?fXFx&uc|QC}0LuhNaHui}~N z>o+s&4u;lrevP}kImYLX3_3CNJm@3_Zl(g-6uFJ-iIEFzf0@rq*zyL z_*)Nr5u1oAIx6X`(!i7WdzQEqU#-Dq{C4<#FW(A(KjQCE{>&ZW$fruK?7xFK%%oX^ zthF}NcOx%!wxh3c3fBgEut%8+9o1TxWPIx9We>Y4kq>o3S{u^+Y@4FKNdFV+ceHM8LhQN#4iqnm&zwwA=QfxqqD@EJ9DllF7H1Jp6U$@H;s)0@zN)qqB1D! zdFI4{&$yIv3c3iN#o*bB!F0{vW)5BAK8( z&R+2e{DkW`*Brcu-`|%mX*2DZb#uS!5?#>!Y=+w0UHzAr-WVj!KwlTQFzW`BhCNJ+ z^uBHeJCV#{`h%X5Jzc09?iL;xJ>}!%?Imy2_P6cR_HOAcJMSc3xYm&_@_t`2Cca)J zpTWr{uciIai2>Q*{wv=#yG}Iv&wH_Rmj13CIC5OXvJL z`dVy5p9qeF&dTPkxzt=!e2(88>4nVu!kA2D((z3CIw!5lt99g+nS$fRob zwf7JX4muU)Br}CRGY8<}7u9Fz#=_^9G*GfmUdK7gJv}zaJ5=9yYIJhHr-R z`WekD^`zig6YV&IuV#%i-ofqsp3^0~IaF_Rggg}*BAdOxXZ+K}r-O85M=;*kICj)0 z!UIxO)_7OE)?6G}gGaNk-Vu!D?NRNOXPGg^cF@|xscxO8ss2gG2cKg9t9L;Dlyq@- zZGTQ<&Dc2LHnv#QFB^H@?sIlD$4SFpq`pu#fDZP7?&?ENh|*^mTk>2*8jZ7XVS>iF zitNYy$TzI^*x?+l2y!MJah~Yi*@TDm?qtF>ci3VfFK|Xv!N(PTm|Br-)aEISpYSQ} z>}=LO;P$9~>Sn$>KfpYS&Q@N0WAN|o?|Xk7$}gwTAFVyjAN;e^DV6KuuWIidq;JWU zeQdM_G=Ani(K7z4%1dGzN7?7eHWOSh{tCWo%REM7#C%^x_^OYr3(7{8x<2^ci|*iI zge9|Ozl4lcBD{#4lN%Kq>?C{{^}%NcxH2-EvRDe6xbo(Yb=P58h&@WqxIG9v5h5ayisQ1e&C48C>U$Q!1-*TP=$ z-`G!U3{#YOB55`MDewllhcYj$zo0kzJjR|p@@K9*%1ijpxVyUlyHWdCC&Ck-{Yq;_ z^I!JAwaLzT+0J=UbAEo^DXs|m>5KaNLHgTg+Ryx#nE(6-Nh8``40toIa|-cWk>fQ# zsnW{e;tiAu{S!Spi88d$h*8c-q?6s~=BT~Zu)S>-R|vn8^Ys4Z!`l0uhW0L0d!Y$V zL483^$3`o}#YLvQYNyU&Mw`0k)&HM)zmT!vtw$HzqG&Ac9waW2~LXdkN9glWul`!ir$NuBfG+>qiV=ZE!)Oy;|xw?g{};FDA*aU zt#;xrp-p$pi5vRS#k&(umHFeG*zs1IwuZj(7YEKL_+us=h*!kDSgkF4wV%r5YI@gJ zexo4(&n0;Ch%%lv{FQGz{c5ND@BRYZXFe47EL!ld{pLjH8wg2~3ELz)Ie%&7s&slA z_u}OfW)yqM&?iiW-)d)y^V%_+(R~3or`u|`x~|vZU|a2U$BtjfSTp`@oS(+2NB8LU zJ$%o*{5x%575^)(yYy4g*irQX<}H<>Ocy$g@1AQZZ!GdqW;$qfNTG@|^^o;H;i~917Z<>Fkc7_bK8T#sWVeI~W_aO>)%_`Q4P; z*1t8+{*8Vnpe2be;ZolC8j+1b`2I!F)b};!`)dZDOTlH#yKq767|R$sg~*@LY;5HB zZEvNp)yUaDx42^RR7(MRl7T#RH&JI3b??bFvG($HPwh(UEVx|%xE&wXAvXHknBT+e zNmD*@ipO|(j7RSApxIsA&t7z3Ec`2y7o$DN(7LHgP8)6Xl!+`nJ(*&}~r|2q6z&+k?I z{hjuUtS|b+dG`ur<8VFw=9zH4YLB~Zlw?w~@7W}t`Ld0hPMmx^vT<*TRaLh+yI6?a zxA3RhE9gCQ=94!2$Pk@r{6}ejon$Juv!aqQ+;%=^w(?2!NTGyYewLuQNyG(XJmrb?Fnux7Lt8{bG#JZo{wsw(mO z@joBMqt7yBy@Jd)Xnso$;%#0h6O$jj1ah7P#P20Z6e5(KCLzZG+z&xg_ zPbHrNw{P~=1vi_ub!)Kpg>Y@D&E1S+TjpBk_U52S{LQ;u@GYdbV@(-lWbB)nizSvm zhyKV6y%=i8Q+jid@t$SwJ2b}0pBFTNxM=*;F3QZ}8!Q`^srwqt(|~x^-@%7+{J9z0 z06qVS+RQqN(WcR#Mh}Qwpz)B6k!Y~=X|Y7QKGKZQ?0Q>z6?YGW&&Uh6F&^Y~Nb5S1 zOC;xZqf66!L}mY|7v31^tJWhnulTtL^Nv?u%2Ix}s=bD6pt^&X7|UpUrWI%#dsfLZ zN!1T+bTgcbuqQzmGoZccF235sD9@SO!}&37Vjur9bO;(bu%7;!{U`ku-T2s1$bPx& zf)m(-x>MWb2g!Gsqe+>S%tN`pfx5Ph;x1A_bYxcjFPLwY|HhBPwf;@TTidfw5~uy! zuWZ~`)Xp^fp02WgMUJ=UDUW-rwQnIe$VOgtu{le7Gdd$!S(BaA*xbrs&XIAW6I@RI z(a8F#+%19b^k5Uxax8cEQ(frfki)R$!Ee{9AW59)w8r_{-wpeH1F-SUhc5OL{MI^< zf4+B%rWC|m52-Ka_gLojXwen=DXi`-`P7|@!YQ;@ZtS=aV!4#>;g z%<&Ib+4Lo(gNxxE%zyd}=1_Z%?jV^fk2=`mz?Yu~2WSWD5FDK&xwr*cjkyND=#z9k z>X&p4RBZ5OHF+MIMZMER6X%#WKf^kfa95=}xWgxoGtf!M)X};6M{V8{wD)G+ZMzIU zz}_mx{FLn6!2iwMXihXg8vp6c%N14TC=}X3QD4z-v>fY& zb0ZxCHfck1QzlMxGu_S&XW3?MG>&UX*OwpapRaNZul6LnE~q(o9cRdL{>d;q%O-zAxK z!6mGH$(S#`EjIXd!p$BhgWQ(sj(q|6c;sd zjM0p_-k6>FZhe`nV%Zj9u8vJhl6-&Nevy~ zP@9ptLLY|gQ)z!^2W`z{RtBGb99%1x&H0kX?Fz;$=}h;UE9u(D@cGbPTJ{IoSoM0p z@mn6_Ec;~mLrU~1?_VN)ANC!+72*c*z3?bHV&Y{te{mG&5O+_p*7__m5%KU|^A5Yo zmnE+C%9^v0`5_+J&ObNGS0(QKD{Ao+eIXv3FrBA__3fuEr$=%7X$$njy1Ed2#CUe5;ds_nz$#}T(t<>s&atvKi|HhRza z@%_Xh>-OABTw*_Q;7HH?#3lC=2S4tqxWDn6_7fK)u9wRi#FBAIF4NsPU8^Nb@rYnJ3OW49pr zEdeZ<5B_L)jqDcALRZ?Gea(;MmU|~1b{h6cvc;P(J#vqmeXLLK9hta6Y?rdKPdc~$ zn&KSds!=}dk{spB*I!gzl{nAFyfwRA$tc$7qWq`>VY4 z*rqLdi}-H%L9h3;Z7*eKmH*uO6Qpsle_LOD8ajsk-C1hWG?Ty8Lx!V&kE$Hnwjpiv zzaN_`+qTV$OFz#22jVJMV+%!GR(503!!P&#k@y(#np${(=gP(yP`_N?e5qtGU#o!s@MURiJi>H+9-2XGUi4JwAa4}YyQCsXS_u|=Q zUc7p?7c0%IeVsPB&ca$8`k3)n23No{j_|xX_7OG74YEZ=CIVkCGG~Lbm2=jLUOTm8 z?_20+ny&WSN(-5nskC)!5O<~qP2}yZ?DFH8MYUFwwzYQbEepB-x6q$R`XuSFy+B_u zl{+xI{7eNt6qRYysa)xLW2EJ-fhkwzO{6W7J7YQcUunBPViRp~M${($^FsgF>#z2m z%0h6A^yG_?Pxi!ap$2vr5)kW=IXS-b*2Rya+FhDR7;q$619o6VeAIV z$}RL0r3Zp|woUFIE_tK)4~i`2NNaFa8Bx=;h#(=!@dAg_X5QrIqX_Rt9O(l_sNC z9>e_;2Rl6QOJ_xi683qV%go{JP{|jUNUp11A7nksri?l1n>h!b7PhOp2z$Iy^;4?I z^zc%hk?Txc`W>CeP3Eh!#8z-+Z07o8inFJV%#s6zYq3|swGw!p(|+fIx|^S7Wf{p? zO9JS7OE!N?@J;$XYLNY9q3m=2Z(z%FZwyAbj9pZx>_omt*mHcJ+(DaJTgM;+t1a9C z8&KVu0iM?Ig8E(PDnwhpK^s2Sg^a=&C9yO!@!e4Vn=pIKwiHgNl+ zy9aMZZoKo(J16XEcARbO-(G)muiO|bYMjb-$&IqBT=QPe>=<+PXCJwd@r>lgY%Mu> zctDfTI2k4paVP> zUeGseQn7o@tPGxfY|r3WaHzx4eSq`*0%P6eVGmk8yq1`JmGuX)S0{_^4xT^X`h%En z{XxuEyIXXhK;xFcPCk;8k@+UbHdr=RC&H5@J5P_ounRr$Fnm@MHZ=;%E9`U=_9s!8 zr?9h4*vU~CwwWiwCzTglg|Lo>dXKYV>eEEEDUYqEb7d_m`)J}5p7_s_+KG>;?D=)^ zH~KfBt%AN&;TK8PKTmqk3GxdOD=e&?h^!K8HE(E6(7j}QmDNt-07({cX|PuqiY53+hv43!J$- zXhxcksNO*_hRpbjd^H`s7z{E*5%Sg7GUH^sR9O9T`6UP`uvRS|4JmR7<52H*g z(|J*uRhv)rlCu|;i5y|*uAf^{0;s6N5y3}L+inrifrH2?vR!%?_I>lh&TA7c-h`Nq0PVICC|mH zo5TAWir1Ln2S9yOyyQ9Az8kzU<*R?8yr=jZiI?r5?!h-HUTw4X|BAnc_-4X225u&l z_xi=xp#x3cH1GjBo5fD@vPICdm6T&;J$TH+cf(__VfZmTeIHpb$6BgPtLe_e9bI2+In`N`#>X{MYWNgWq%BDiTne>apXDG z8(ABf?qN@gY?pojpDNhQ(-)UIPxai|IMR-x&m%q3sEw*OoeNwq7hprwnaG{tb!WR7 z+oc}JI~*DTK1zXe-N&wzAv}$Z|Iz%Plps+?QSkm-5IcnHvnBa|=_gET?nnrJ*cW;LZpA zz4cjSxh`;=-}CzS%5pA!OAD_KtT_B8TJ zmeaimt+$gzn>dfxU9Mg$%dMyELJ`@4@zGjKl27A3L$X|vJ=H%kPS|6(1<4;_`{gf3 zyj$ESG(F_h1=WPV$@NxP8uSVh5S`6VrVF9$YTmn+91Bi&>YQ0;#LWfvA*9RkJ34EQ(LSA7v=Gi3*1Im9(zn3BSO+@q zxbIo~A`B><&XbiEx$U>oJpHe-cbjYOKjhJmuDdEWxCh;aI$s3@1qgP1BMSXvc`i zR1_Rk)XGB$l8Ke133;@!P{zl|9g0y0y~Ajw6Y_4X@CXdcC=NzU zBm@Sy|$Pbc_{85JO=vnePO0} zBV~XvTtmP_c2#)qCKbSJH|%3NaV@R zvc%a_XhSVkU!P6*lmU#i&$>Ol`RB)AawD?gBS$R$j`i75kqyFh=5SO0E1wU-5jc(R zJ+md>zoe01KHL(wT{_WJf$?T+ZMR&vTyzl{_ws#*`rwD`IVaZNrv8Cz!n29I3x5RP z*HLB0taoE4gI;XXm7H<^{O#z(&?f-Xq;_TVgv(C3of?jj( zq<&fHN8!YDf^!aq;IHYw)^q%dP$&Ck^35y@M+!RIXx8#(8t3Ed?}^j;N$V*iyJj6o zRc;A;Sx5TtVPGen#$wVkHTga0Z&cV<^yaTc-*9bRd!$TdW!=dShMmy)GmVaFk$lr_ z7k}_Ua7#2Ik-ONJ%@+Hnho#4q{LyjnwUT2kv}1aN9OuKt3!gguO()`4xJ~1DG~Kf5 z#W=k={?Z@+mN?m%B&XbV^0T}n4{!Vr69<3otvm5oyr=L-@o}CRW8btK-h56#pZ2Hn z-wso>uTOSXcR2N@$kVhz0Pi^OAfJK#jW_ZxAAyp6e;>Za2L9?F^3$k)wJGMT81_=8 zf7pd~pYwjL2{(npH@mc)HT7D?O?N|j!H&HVEtGwgWq}{>)ZX)k@bcU-Ti6?uR`(Tq z28|u8+V&W2vwUzLYY z+IB& zbtkKwC6puoDP_{Lp7Jkj+-%0MzcEalzJELIGvAsr`WveW+unQY=~{Q)c4;4Dl!Tvo z6TT9_hhS2iZz50ap+(0yN75M26MuTfeqVcN(V|rTUiu^ZvL&qleZl)_PlEDN9`VkQ z+7rxIUoFnY!DpoML*(xd<~HM6^37_-wdA{~8P}3;dNZyi-@A#6`d_Yh0FQZ$v+PUd z(<|j%AEx}Jf^~2%`7$2<7HijIPrfjiY`()zn>=dkn+WSXrsG}D*!Bl+AgujQr%CS* z;A6VG_`WOt9-T#Z58XLrQ!%ID)r!Udk_lE9HU<_wh1_iCLS zqF<@n{m{uJj7@*Ak2XmjopSD{J+p&73cG|o@-PP2qQ?I8?q`e&!4I10}( zr%aVsQ&{D>DsN7(gD|#6!M|V!I)o34l*f5!%Ed3B@nMv)ZZqW$5jOtv@Fk;i|B3K6 z4}W>J+f2E45th%3PHYKOE;gs#J4o*$e+T*T$A@1x{N=^v-A35>%ZvK~58i<->WJ-4 zt!F*W@zuV@S##0S9OU^W%}sY|J((ZyQ{HucGRNO~ub;+0q2^`;@BSFx{V}}zV|Zg< zWZ>N&!#k2|>C9~^AI(YRAI2}B%{kg=J{E#c(oXq>YtF@z!Y%1n9GA|%>qY68AD3Pv zoCLm~0p2!eWK*m+*eL`HiI*R^OgwkyDPR6kV6XJPU=CrO!FA&FS%lk2?~K#mOIUv3 zy5jT;2&YN!iPNVN))`#a(3!}G**k%^a5n+W(cg8Xtq6BJ!0}`FTZrLVh~Zg?;Ticw zlI#jX*wOSGYl~**@5dHJ_}drsQm@T9W#OM_imR|k*b+V#f*ytQguz$%#h^=J+9~`N z&FO5WlV5bfQMjeNEMewU@H)ZMdz89`Z>%%KCpeQV`~`Oc&Qy2HuU^&@J}=anYWB;5 z=WV85&Qy2HuU==2pPZ@gZl}DixIE5Occ&?@r>64o3raXcKis$q}$&Od!L$1KMQQmSLaM(}Jt74z@#i=B=QV@9nl6~bboR14dSK4%H*{!^aWodycOCZTotUpOn4jV zPMj{kfZItIt}0!A0p$;;D^8bR!23xTt}0!A0joQoMz1ww$`@>}2eyXxTF~BF-cRIb z*6;Lysk@rBd0ai|x6<5KNdxjPgrd6<&Fu@WrheNY4mvAZ_X&k-gav=#e5Jx3VPG#> z`SE7D$=@G*L}63r(}8gDLkg?BntT(@4n9CQNk2a=pL_WO)bl9y^aTruPk0CLxrgr! z%DqJSY6pxiQ1#9x%(@oJPpN4CUlML}4xnQe>}LlT5pJhE(OuR19>QtTy^Wz((sm=j08p2{syY&frJsCVwHoFQCC)Lt`ngrm)Jhdvz5hfwMS9BQ?+flC+~yq!+kmag z{YS#>wF6;$9-2&fcMwjKE*h$S+(tMvN2Ujc1Ty5gsCz|Q{hIw?Q z!XD{0;Q;erVT-WA-9qq@X1dA0F!&H*@mSXYWBKJ7igD}x#A~icxH>ynKzJ+ZTipZH z(;r+y*!YQzadkG~?H+z2YrSudRXdtPf^i-g zYp;}K-uLW${;+&TN*6C*00&sdBb|9)<3`>kOH7s66C;m3V+^#`aap_U`j_5)eXtf8 zk5kzf_LNVlzn%ADZB)GoFM%z0n_Ii_MBQm~fyzU!q&>dn%dUBG<6`n=b9(lF4H-uSb|bCy*$Q6U{U!TJ!7oZ~XJncc*^Hr|rn*b2c(hYzwJ(SMb8&vFzJ3p5&sJ1lr%KeFe3Uc52TsyYV{3 zn==*I(G`|Z9(!yD+jmE{ijiF}as<9bW}WlQ?4a!2dJOZqPM;}r@ z;j2@tLgcy~(wS@AZI`ncZaLIgS;kg>7T=Q(JM>5SUUGybzyP_x$OCoBk^H0WcfkY6 zkOfoa>%Tjy1Dz!OTuxg(*}aYQ*~mLN|8YeSeSbf3^1~(AE<-+n|3%q=CTzcP-<|2h zHZpqot?n%XGvL<4SRey=So;4CYu;Gfy|#Y+s8Q@AtPbr9=TTQrd0E)SU*)tDH$ASO z@i21XG;#~cfoVemm#f)99sr8QO(?EPFqrGp2ZCj+@sW)c5FG zIyz~S^Z+$rt3B&^$VksemixLGHdhme9ZTa{+Hp^1t+`*?DpN*z_d)C)Vi}}kc|!Xo2kzFn z_9Ni-U7YL5&c@F%Fw9_G?vmwMj_$;6um1zeIo$z<3~z(* zZ?Y+Oe&b97i}{AHND|*oSaVr0YU4>G*hkD){T(Wsy>rl>Krb4<6Te|>W=`WX=+&hQ zI6nRpuMm$6@MZIVCB?>>K6^CK%7_P+ZL z&HN?yRE!Ta(zM|pz|p5zV>EZM_3FN2IW#gQ*>R!qN%r!_z8ig;XpSj^bN=uKjr*u~ zI=&4$mnIJ9xqB`DR=z_He?GnhZjW^w&HT~@bXn24E$K}%AHF?ov)3O~9g?Yv9@)^@ z_39^aztkM&T$A)XpP~&$$J0DZSlG?C%MYp?_4gu^PWd&;uPslUP<^N|+Kui$)0n65 z5jG~r-Djl-8m_ghZdF$JP7c3P&PBdco>HH52X$9h*Hg%4lm4mrBv@Mqmdvrm#RjAXZUU#dAIUSinuXlWM+IbMBKJ&&1d}$ z9PgIlZ1uEoYc(HOGfsPQ3(rioD;)Ck@Eu)z|B#<5cZDvpye-uWgB{C zW6L5rh2(4P=6OpedX3>BYqv90+3lxX-d&zKo;jWlPlsooXP#&2mSNR9RNC!NrOpg+ z&3d#AxMq-BXVE1%xm&_c0>8f)#V~lh7cQx=?(72U(>{P%ZYzs1#sqo(sE~T-J z=yJvz`-o2Pq^&eH6wV3HQst>(Py9`qZ@TzKwz8e%myDpznHoZS;PZs*l8J&xl##3O zE#(OJgda)DnZY-*m6%StzO_kr%C`-t%C%wPqi`_moW|Y)zRdZz@QCavuye??#HE}c znfL_pDgU(4#sIwhCP&jLsFASa1Da-@f^`Q5{}QfEf6bHPoEyU@Tr+uFq%eKY$kcsp!Lx`0Q!KQrvC zbcJo$13S#?RCOkFr7KK&Gx5XF1wYLik((K&^1v%UGZbzvLsnRWKUsR3*LePbcsH-H zj=0|1`Vjqrc_K3&fd>fQ@x6%FTB(&Ge$cvC5buC52H(J$EaNYnN`nJk;6OWL(FuOE zfg9*QMua!Q$qaF#QQM$TTP^4tG)r`T`e%{i*>by_u;$XkLYS;PxumDZ4q5Z1ANzM&{f|8)LEvKYup%DB61ouM1x% zue%|<+>;LW?Y`xCjV~XkgZ(*m*uYc$8qIt=s)H>Kh9`4Ryvmaf_Q4NDI#|&}+0mVR z6i(9&oc6`KR`CV0KRIixV1%xfcF9MXAvtZ(RTiI4TRy3fEidRyg< z^tSJB#b$(dlzA& z>xk3ePFT7+$>f#(R>GZpAL(ir25%uWBz=c{g!H$!<<4O5?gg`UL^@oEeD?*UZ!|hw=_1#K zxA49${x(h8Kpq_~XT9tkdIWb`{SGhI;pSJ@`_bX*j_Y)uv+T5MOfcY|2@c4|*69Xk z{%i8^4%_hE&RIX3mU-&Z(K z*abh>v7mo1(&I|M8|iAK_v#DaOJ1bM#b)tEdR*4j?(O+VkE?R;CfusW{R&~D z$IVCO-AVX(J?`zSyPEH9z*_V2%gjg7YRSm)wbn7l#Ya1MAowQG^J32mjlxb9J#GZ+ zS0~T4-51~!(2Jpa=%CG?qfL^LNB37E-&MFq*u586_Xk%i>=Cx^1wR%BpJ=9IZwp-s zu2k5Rc`y9woZ#aMt2}HKM29{?SiCr}>9E}c)N=#h%?U0eUizEpKFWo``w2^bBYSey zyMVCtH_=^*=ywRWSqF^GxXPVPxZOPv%4S0K{w3iw={=@=E1V!PJVE}-1}zqzLY6Dgp-=(xhii?FpjWfT=<4>IOTI6 z<^48OZi;Zqdz3p7rT6U*EW&N*7@BgC=g{{UJudk>XvedJ(>3(C=zUe5?tL?NBF6oY zjQp4Ik)khStO37VQxKYM5eAm>y@t+}xl9;X3Lie%OgFll zxj{+c8tGP~Gr2-xl?N-nM{!f3^lM zz&(j$&^c(mieUTdY`P*_fMfOrkJE-$`+`Rm23Ae`f*&jF9kVa^VKW_mLF>pv3g=0O zACPYL0fk%a3%*NOFa|aqt@Z`qCSL1P)4t%F%2zvPUvLlMR{Mgl6K=IH_$uL6`+_eK zZnZDiO!#>Ff{iUY-LIh2y#oEMf8Du8uPdGIrwLd2i{7SdorcaHqXn;y4-n5~^t#Xj z;nqLUo+0O%SWi1U_>96i!e;Kz4L;ROcO$*-RSMTgH*=kP9~Jfp8``ii_*gUD+N=)OCKa{DM(de^zZ2Z-O|>^hmEeH@KAWHg8`L*&r+o<`Ujs z+ZRN%pg(vY;T@z$dfkP=#f0yty!+$wE+kx?{7g{YEE*Qkf~mmyE8mWI;0*N9=o#5- zUh_NTDfnt?+OJ=?Ka$-z*zs%a`s%$$MkexsbVpB-Pq4S0JqMFT?AJN((~G{yl$FD7 z6L|r;B<+#V55c>Yyx@uLs*7D|LX2^HX)ex_soGaUS_SJT6D)5N>YYns4NYUr>_rGu$-Q>s&;D0wb zE?Lu4;B+a+pZAaQoV4~#OFqIrN`0B>=xEtbNG7O$s{h768u~)XT!3YV#W-Xv=?9Gu zIrPc$Lxf+a7XRD7qW;%Xck8!L5ofvRNPCxuI;$c1m*kJ~>u3XWi*bFo$|nvzP4_l* zvDWl;rad}uXZiFohu@*xGI%PTyXa}WiFoNr+FbOZj)!bN@<;ijZMs(?@*9pmWcy#+ zSE(=i&(|0LxBsoSMr*Y)8QCguZ&@hcj2<{7UP=1R(P{&*RU53F z-#C@_v^mRsjf?8f8kjvuJ2(eQ8~%xYtGsWW&~}({8R0tvzo&H$3^;rXI5?JI>=>R# za-Jq^E&2VPvf|)R`OeL8Cg0%k4dG)ywT*u%^+#~k`06am-8;^)bN(d8 zg!#&vF;{IyFC+QbT%F~D$DV6s&ok(s&Zk*cCHyXBOa3L=kYJph{C$VEKfwMXejk4D z*!yEUHJ8xQnQyNTt9+|Dr#AGwE1Cl-p29QcC2Owu!@0p8>K32)DW1~939tT^blIVt z6?jJWm9CAc%irQg+s5~VbdLI#J&unYCs$S+{pfELN#pFNe}YqMaGwow0QP>g|8tDX zIO(2CH-xF;4dBNOVK#q5xbX&j1}F#>jzEn%t4HdB!DqtVP{(KMiCVK{6+84?0?Cdp0 zm#@B{>*;u|8@t&E)e+M)fUZp>PCTvK$z}rEmlDmG`cGmh6k%d~; zc+T6|_0t(^@jeOg`C?;NFuQRsb&9ri@dT%g>`uBB(NF1Cgzv4omCGmtdD*bVm}|XK zJt}{6OFT>A(fGEOc;Rp}e<$T0p^qBJ6zihO_&xp5xd@g0Ti%_V-p3nwNyesl(d(`_ zUbIoNH5c8K(pY1T_K)>d_nd*BH<-4{c1LnP<*P$8{+)T|SeiRd16eD6A1rwGf}zvf zYOJHsiwt38$ad25#%e6afXAE2tFckLr9%;J&yWuFxOswXa3m9_e}eSmaqlwHb(T}* z%#WXf#}Vcoa>SA5J2KIu?{8~)m#nY}%MJABYjK*|sWWvtwJ4oUnV)nvDQJh*PWhRX zkI8oce{;68=mll;rJ~)^m&#w`sl4lKr+ASs;Ez^xmbJs!?dU9}&S1!Yi#bmjuVXHF z*v^rxRO z5d7yu8+Fc+vn(U3)A(JcF8GFyGbVaLp7%69rf)Lm7_l*MmM5OwdaO<>FWw+JbLmi) z1FTPb!al4uL2wbQnrAzu&vNp6!oD|fMjM{3Y;|&fBJ;<+p0x=6#`PLk(DzJPYuS85 z>w4FDflI!0WmNqt`rq?0_`TB2q5M@~OS5{Vx6<#hf$_gb>$Zz*G`a`j@iyiIb58dl zJZ@Xo%_r)C^XPj9ZH4n2@^r`3-M;E-wIy0QA%7?Yq0M3&W zpCvw1liy12*(KhtdX36gWD~fcF)yx*b)sXmee*%>+ePP8=M(SJnq_4F`{ftj&Mk+| zVw*>Kk~y{q%MP{!>(7!uD?YNe%$GeFyb$fcCcs%6UQHTj3`6;aIQDHG-_whNB!025 zH@bnQK$Sbp~}~N2kn!W`Pe>nPXey#l5A)$r7t&ypCez2_mkyI zgEBrBkMUgKdgsloy__}btcb^b8-Cin28*@frF+EVViR-k0}<}ArZIjx2aivDK<#(o2Dymb?F8AK7!2*;N!pz-cx5= zM_Z2{6fCceVF_K`pMg&nEEB*g(S+qhV0js5)oF)d+5R%H)Y!cQmYjcxU^!r52@UJk zoL>WtyVtte$YC@u)rQOCHb7(lXd7T)U$G4auNcqfSZe%iD__@GYK+wu*(0r1-)Td} zWxN;{t&^Yl8e>bJ@n;$WpULg^GJF#)uZw@nVuzH17t!AOUg{VB`uGdN1us}jy2d>Z z9%$^FXP1Qo*!p#!;O%O3xRLG9$82mkSm*2_wnNqLH(a0l6|r>~Q(1%k2KOJ9u^%eU zsJ~ve2Q_RDiam9F)yH-m^I|)Wd5!nVcE}qWW~*bvOmS?O^2cJEgKbF_+mhnUV91|| zFMuU{yB6Ca@|DO({uKEYKMFo&`I!LCt)Kr3*KcGPV&t1l$CLV1 zuj+(oZx{`nEa02+Z^nM;R@Mma1I53E_pPwvR!0s@T~!EkDO55)o9wheYsx##V-K``Sh$=jJu+-?I0xQRRtjIyN4Uc*nVW@O%(1vs4%;K$ZAQHC+b+(+ z$2@jGKDI~L&t$>dWDeV-BDP2LGf_O=_J}s+usu?_MQo4wKC(TU71}nYmg-l%s+04F8|)Umc7eC;e}7p1PNXNcD&J>c%(%Jvu(Qhe zRMG6*#j`rpoAse%sKzj1b-Zv*=gxt1tn=O--2o?FRs7e^Z|n?qeQsBf0GHD4hCu6r z?5!^bH@vWj`dEWCpWoyz^S+4ho4Zq;t6n-t>L3&3?{#crJz0bkJq`V5e=)&N) z(2Q0enB;b?j>`=i0DYM%2FLb!<)dYp?wq+9bIFwmaP&_pI{e z8?__wf+G7Z+nrT^1F$@qJ?bbQe||fedpW!Q9@6lg>Dz9(en*XUo;(@+xOzNAN9CuK z`-VG{_|;20PJQjprT#?f(Y{pUp?&FzJhd;?x}trlV55C$J5Tx4wem|(Oz~&WHIDa? zcj(R1`hVwLYoPeWqh(NLmcPTllYbZg9{w)>UjCE#pT$4N{~Z43@jsuxY&KQaFIYRU zC2X*V53JxipFJvieDEeeFpMA8fb$z0GLG!c7ZG<|NFO(3Yr1E7QIH{=ChQ zVW!ZAP766BVTW*M{<>?MczUrN`3Cu)jPLPys<9TXE;C*u5nc9W*yTJ{!Rw8q< zX>0PTRembJvNK(A>I1=wc$^o+6Cf8$;ED@WrTmq%Gy{to|6{$2cg_`Cdj`A_117XKXobNHXf|9t*=+M%+{IM;T< z`^*lqV^{hI7-#vb&=_Z@tUS11<6MTPB#doA_?X5y$J$CbL-;2eXXb>)HB0yrjdMl3 zrp9?m2r=5w$y0X(NFKBtyn-hhF>{tP1WEK5k|)7ybUX(SGyZD4FA)9%`O=Kd5hq32 ztNgRR$sG`J8J{BUm(b|d4&#HbbMduj%h$gf$m4 zHO=eU$Pynw#%XQnu$BT>_5*~s=O0+ooQpk%cCPlz{wjY(`8uEbn1U50?!VDoaxSd@ zQ%-Q5-Pla~ZSL0jG-YM07c-aE)HjnaJy|fFR@YsC(wk&!noCRTYb&e#q5LC`eBh@w zul^*st^%&Bfa^>DT2BR6*+ZskONZUcD&RT_xI+JUI{dTzGbU~n^l3o^S8FFUZgx<{ z_PgwO!O!4}6QwovG&JO%{B^+-@HvbPu$vETe<=SP8`{Ai&NBhqAId++hD>D*_&y)l z{!soofbAM!J0IBoQ2seK2)DNL{t&h*Q^4CJ`4sy7JRU{>tT?r+CE67+WhZ`MeiA_80I(_#f;>Qyl0~9o98r;d)%eFh_al|`v~%fY!P3pF7TvG>AiCBOv|2^ ze4rqiBg;FoRCGkD^Bs@A0G;|f?W?*!^uk#ds%+hFb)(S(Z4A$TRPwk8F4FCEx!gYr9N4mlyGy?OY$sK!*Ls+7#~JOG4A;9_>@r*#*x&5UAcRpLXYD>pVAjg0`ux zPffY+(BI;7aQc1c8vK!s!Lqx~#4N5mNyO*jW0oMG@_eb_0S0|#f2_6~z{$mzn&xswg?*TYct3V;0{x?@~_y z8{0+ROnc7bjPBXL*LTr*ISU`>os=j4r|SRDf%Wg+8nsvQZ|TnWO^y05S;-$3G3StH znEqQ+<2kn?JjL|;(`Js`{qOM{Df>yua%5kdV$L<;u^$_H)&FDa+H)Ca5ez(x?90GI zce%rJ-j&M5zRzg8?ac78H#z(O^hvUfc|UpKFtWxG!RLd>Yz6!8P@dqa@1c*|^WbjE z*Exj6S{J*UcjbPCG=0|>e|INsygM#yKlTfE@jmmO=MQg@zW+E}n*r^5Ib6Hqm2j;T z;TrqD)mC|3IK$u?KGJ~o>w(#AF|66Q0qdK?&j{A#Lj5ArJi(gtW`@2U#kG~;Vgu_^ zBX6F44dsnsdvmxnhOP8it+>`FTmzqweFYz7ERya8exlg!-*Li#Z8cw}!?isn==Z8#MW)_;z#nu2y^tn)tR@=hE-e z8Y@46%+0$JC1`dr?b}v+{mVaI;qP|JEik#zf9?-Q4u2QikT1KfdtW%L^;3AX>%Iv8 zr1Ni<$9lZ|iZb{Y<0Ew;pQCQtPn!+?ZHd48D&OhOHkD=P**E2{4ZlR$XXW|6d=qnX zzI3SYonG)}@bfm(?yNq4cw3C0O*&YJ*VUK9&p(wG{^r~l)55(|j?uzr7YaXL9WDIV z#{W08aK+v~jTRn$wgop|h8Av(``@I6>*D?kH@B(({|PPp*nvMz3vZ6$@t@H`+nsR~ z7cIwYEC3gqv~WDQ*rbIMVw`%lv~X3^NC4s+&**B&SXA079T@vhMt&go7a9Co^cuTf;A*vY_Gd+vhLy^b_#j4hO&l3H|I2Z%U=lJPMq|vT@Jc2XGLOt zs)IdE#Cw0?8}cFBM>*DZ_^c77>3${I`=(rPbB47skzeL_SS$VYiG)8G=f}QdyY`aO zhyP$lG|z9M9+RJbo!Zi`HT28LKOU-I>faAoS9-+%({|~PzsDT@3anu;pi`kH)U9qVXaEAp4MIVZIV^l$h&{V-Y!|2;ot3h!F6MikvLQ8 zn|X>}*~ndyaoUz!J~27Dj4W(y{kq^!kcGL(!uT6mn2RiozmbLgH{Qh`8W~Bm44zs3 z4*yR6UHp6ayZn3kPvUt}Dd#D~^)*!i`L;rt*w zv3xL#{NM{ZqlR82YiYkbAN(nYH)=1P!#@Dw4B-mlBtGG^m&_7gOE{HB7f9G4-07CT zw}P=NVe3L_9o%8LQ12i<5eGm zgZ??(;cHb3^_%q_G;f8Txm&|$(G4{B8_=nae|t-WQ>zRuM^8Fm`|T3;C0=l+Y#}_| zDbU^cd-9$MO-j3V-6fo<=q`c5@OI+!gmte#ue&0FuWaVig2o2h+TT^)6l%TH+H@QF z7=y-#C^K=7->~z{nKJ((_gvMuBg?wjcP(^-$O%)q??8L!HjsIBwA-IF_H)={V_!LU zyv;oRIPtO_Xh*hWa~7X@$T~E;@eh=(wn)FDJx7n}1jpwk{z%F5I z3fO)4oAlo+XbtUf^7})VwSzu&_f|KA+RL>w4(+rRAdW~DE*js19x=7#2F~ryZ+wZo z@>TUM)*rPkMVq9L=%P=OugW$}cRQrYdrW?hwAb)mhc$nEd-;b4ZREr13wtKc9z@@Z zrF6Pmb?@=Ho6Yt4?Q2@gyb68 z8t~+wDKaKLxRD>k55-{k^nS$3S1H+|+wbvWLKbG)8^I7Tt z04~@5?)I>T&lu6Z%#X#xd5v4PYF~0|cve;Wl6Ux46+0vBD9l~A=%uVOco2`-4b0W% z7#le?ePI6YZ(|OKXZZT{>BG9;!M2bKvrn;|_xKs<@X9MW&xD;3I0cVCqUV!5dud0H zH5e9oKkFay2XET8Aq*ag+J>HLr2hj#jKjrt%Q$gQOh=yK@;?byz@NBf|% zFwEgLr1g=e_F}iNUt=t|7ih0t2F{e_0@rrVxuZkzC&7zl zX!C`9)6DxG@^)!_$PW+KP`;BG>-LF!vvUADkvW0xFJtXG)Apy-PiD^Pj`-6j(@r1# zHS5mBtUFp`Tzu4}tbxv?HOu#C#}d{a(SZzi@OZo%{ZMYXpPak~U9MAKa+LRp{L{$R zOyh#>P^=${#;=WVq#r7nI_T5*r1ixv>T9TfydV1SyeE-ss9xO*rt(}@Wg4C7A@MWk zIZ1dN)+~J7i3gcPxRdK3A8ufLPIJv$gPalqfi zxFslGb)}s0FtV@U7RjM=_+!x;=nRMt+K~0R|AugeFnka?qk+2eW(mUwZRm{iJA^x( zfosJFC6>hWxXRopiWblCSGmg#Jx-LlOR{)DU3cw`f}Sx?4NdN)J)8@LCifqm8?uL! z9oVhN_M7>SpBq}QzPXOM0S%RHx%L2>8?3G9=~)SNNQgB1MzM4s)~r;EQ|ngh4t>&JlG5EAIhf8DRmjIp<$m~xhO<|Ws0 zmJXj6KXdVOQv7t|XIK0bu4&zH!QUkF&YH+s2=Er2 zq7oi9`im(4Hp1K8+LC`~OlI8u{Nc;3+rytn!I6;~d+2RHKgY-vn>M~p*^T(IYnt*K%Qd=@r>4E>N%8-(GwH*&+@3nV{(a!( z=tJ&rC!EG72=BRSZy-OL=Ofp8ZWrs~vW?KQdBNvNlYI1g zo{6#8tRP>?l-7rt$`okZf&d<5yLk9C``{_$(cb(>-fQfrW21}@6Y=rTwC*16H-*oT zOxYHHo#A~W`xWd*>^JMqv3#NaF5=aO>3UY6=isOGP1;N7?kU|FTKu0!4olCZwOwg# z?OYb{$PgXo*Dne}ge;~{96=`(#d{RS=;IMjVyzh}m`ktIH)Y{lR~^`Oh?g+%pLXA&anBqX`GKpl`$Xe_qo*?wBU{kv=*$7@ zZMOwJwF@pe>>qN=!|O=jbCqPDmx>;4*EgSHY{b)jll~ijHOgOx9+s~S2gu*gT+`hS zMMv#e!#hPi}(?;iF{n~}TFrc1tf zp@GM`V1Z@5S9a*wSMOzR-X$Drd|8~eQzs7Gy8J*rQ24Qnjoy3Ux0ewX^vwFGPN z?8e46*QbBmwVybb@?=*dS)KL^Z&7#(v>g1<`NP~%T((A@(Ks_!mV>^?$f%ZvYPZf& z{H#F!>9YOkqkqhK+HYIfZE=3CnP&&zrzjI%$;h-#JpI4sY32`Omh$z@;sE}$yQ#ZH zCbM1n4j~^D&Ky#|zTSg5>_LEa7d*@=AE}EV7n8lab>I@7R0TMR-HO zvapABnETai)&bo=$r`-_{!KF7uLCdHs<-i+pW%$6v8}9x?^PcxukkE<+tU(PH@<|9 zG0pdD(2Z)1+)RGmH3uDPxY$Kqh-^Y~!Cx2|1$VIJIqREWmPpnfYGmE${6f04%>Nx{ z7_t@o0!yA*yvYBvCD3MUOOo6-YZsA?U~l7;%XNbnjJIf_{GE}eKM;Tel7)Ski%9ug^vE-RfdaAZ}SZlab!``um-HA6l%zD^k@yzhFo!RiU*loE7 zh8=h9aMD?fU4J%AxQpRQv!pL3J&QbydTMQ^omscd^f}|Sg>A&EjVaQkpZqiJL0xRN zrU3IdqhrK2k1@O@=~29i!V~@vb0O&>+J2HJoonS(Gxz9!2;(4SXK+a`@~DpJy3-&VbLSP>yUxM)TC2PQAzzgr^zsrMh!Qkn|&b zzTcn0+CMkk;mm+vof~dNBM;a zPq!9k1j1AK_}o&T5eQF*?x2ps&xW@ZcKV#BGdyR~>ks7{IKguZPrKHSFC2XTI{z}f z&3VL6)-J(E%`D`)m*5v<7U`Fe&eUL8w2Yja7TYWlLpnHmUB)y5&>j>pph^gjPL z@N~$1z!5$UIS(NF;#uPfo)XVK^ri8tQ)w@Ur$e<}zVK9YTed^O(;eMxJs+zxFauDt?|dVEKmQ(ZcoEMxajoyQrapZeKqlCxj) zf}!F(&VoS`ipg+m5xKLs5%W%zAbx0iCDv$+g1CE7;WZt=QsdogNT z4tv3DB^l;vTc#Y9CH%t&gnu_O3Ok2eQkx8?T+TMK)G9X0ml=#+FGWvdSyz}+F2yRm>@X8~DU zKGrkUprz`MYiQ|e(Nf{)c;pEGRhsl;@|v^IF6+FzEb(50-x0rHG4>q_^IS|mJ-AvwEyR9wi(c?i{OB%27I8U#bT9v0eCKIdcA7UFnqduwJ34<9%(4dSZH$eD z-tZdjWlLV;{2I1)g~2eN9}K7S-}2SSk8Ur1bpMk4I|xsA2kSbsqCMRV&Wh%9gY|QW z`%K|S;qa68VPvVnYYpFW%vbJtslu_#+f#s+~_K=M0dY3;c~8=G}bHm zwvTl2^82dt+nAT5=)d5H?=oWxkwr%G?`Azhw$FFS790Oz_5%2-OyUCszVHa??S7x{ z`1q&g(!7p|=qQNS+3*vS*t*t`bLKCochdj#k_+mI+y(WNH4`7=o%Kwx+P7SM%4|kQ zaMi|xb{Rjyd2}?nL8H$YNU<+qO^}>UXTmj4@IAo(Z)2FGoC)aSx=v>ut5i9UfX{bu zHi^D=0(ZuAshqP0n7`AofhJw;P7mhcFp4s z=yZJ&_?Q9bt7{exPgfxa-Z?5KbuD^|$>%^rfd^0ed4e zW!{Rvs4)h~du}_J6c2;#wRCNr7I=m(C+(eBAB_!}^d{od9qNqs*b5t?!T7OiOyv2W z`lu~$q`Z6JQ#n^j9k=4I*rvRcM_hFWxU(==Z{oOLQ*q@T$odur>zZ-;*4q(w@a@{x zIFoNtu%a2)QrFqbc|ANXyX93~{zqHthu7L5cV*aar;y zUTyd|aSm|~aS3asiTf~doy2t#myF{sBd&|MF5*&gTt9I=#Ptx@7ROymoJ${F`q&=F z%^?mMCbEZ1f_;pMgDyks;0L(dHQ_R@wd)zzZ2fK9G_I#MR>4npd7HuxC5&En)Cce=?6T3bWQ0(JM<%I=m&h|QTidB zBIjC|zkLlWzpVP;`yRXp+4Kl>Fz~9v+bOmFf9oYOPxl>Lwl&S?I9nhTvPx|CBkNs&_GWhAK}5e~f+%Ii%B$ zKSn>W+s8ldo?uI54`&hfFs?79A=@bDPoW`_IlU4Msh0M0{^^xz$dI!?_+vEW8;r+N z7Z_A;dl3yu{9mLYL*<`Q{;!~$5e*qM_XMFQ@qR`8bJ)Ht3|5-Ba^1w0pF;ow)79HEGCP;&u?XgSaLQnMK_F#NAI^lZISG zT=kw`;dk%3ph-if6DJy?wl-;q#eZKB~ zKig)Fu0?arsSSo};3KkSXbNj|hW)CYo59+mGm970bso_!KXFiNDR%>eHuEa$Y5nEQ zG&p1D{f6#jm&{TARFDaqby_lF_HvCk@RXkBG@d%IhzVL{ zid7$XN}Pu>Ri4T+<(Rtw$wT?$emDCy3ONgX z`s!-aC-Go{#kf;e2hwvf4u)rE9|QlCsdtWB5~Oop;6mSez+JZh9>Od2RwEuMS>vuo z>u2Ev&#F(}ptbarm+(l~;A~G;x!W7sA-%1``f0oP?=PKLZ>xxZ_8MAa67Cv5;*Tzk z`J+o?{^(M(kAv?s_}j))`?q$UZ9MJL<a7!yB&UT-w550dgDhM|PDs?>WPt^qDyH zyoxJ57m8PVUo%eMR-ZF`)O%awOumJ|dzx`A<>g!B;_}`R$BABuw%OiKDEDWk+;d1v z(9VS7;Dgjo_C^7;pgURpNtpELL(Ct&fw&ZLDdG~=3d0{s7S%>v8*#}vZUS-b#I+Nb zisR^bcbd2~acyzjiNs}Sdj?pv$8qdIplvIT(l%&AFqZvA61rwreiCZFPrgRud2(Zo zcq7JaG`taf(uf6a4CAZeImS{nF2EP9=uy^Ze^JEmGj~2%C3KF^C(SYO6ykFw%RZH- z{I5u6ESa`=1NmQ(>{$L+l05mYk*eIw7%d3c=iBnlo?yo3 z_*^q=DO?CX-V7HNo)=u&4EqW%*7%$9q|2lu-TzBEk(%^c1B_34GUVU$EC6PWvpa4P(^~o|;Qq8`3U~~7B<<1r;vlJa?yA+<V01D0PpR--WLZy;9WFNv`+Qu zyoPKU#TTO|>^={87Gjv4OB+LN6%g`V@zp8Hh>pPwGD(kx7mS7!@U^hF4 z-Ru~4#=k0Uitc)n4SfVV;}5fAsI0r7p~JvVew=lm>n~`Z?va)4&QJAT)cd^PVZE31 zeyQotP(|+xf~w-Vw^rx41v}ZMr)jsjPntf;zHOTFlpiI}{Gh=57EkZoO~CtBOYenX zG4I=odY>13ocHbcnp9n~Yu!=N`+{Hz@48!dj4Ah}uzQko`?9NXSR3#gef0f1z|;bE z+J9($n8dmu+sl6=Pmd>FeKqhenf-uE9c|E$&nT}&no~CT&Rs~*$0+R$e0O|WDo%R~ zb@dbn>$%MOL*FAGunn5^?To|t#wI=*^KFdvcUr>O9Cm+;Fyk7yw6m9X-mCO@-la%) zp>56YvCruKTFdwI34ggIKR%VZJ6rP4CH?l6{G1!;zO^N+`FeB9_u9Wv=h6BuApP?# z`QJl$O-r~!cty+i0pCBP{bJmHpD?ygN6W)5ted-!kA`JSdv#0rErdVOQr@F{PZ>w^ z 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 u*W!45Rdwf@BEiym)b9QCD zWo)0Ci7=yxQ@N@=^U`8sAa)=&9v%6HSQ+C